[libvigraimpex] 01/10: Imported Upstream version 1.10.0+dfsg

Andreas Tille tille at debian.org
Wed Feb 12 21:50:59 UTC 2014


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository libvigraimpex.

commit f58879d1104393cd416c2c13a8b576ecb7f828e0
Author: Andreas Tille <tille at debian.org>
Date:   Wed Feb 12 11:48:58 2014 +0100

    Imported Upstream version 1.10.0+dfsg
---
 CMakeLists.txt                                     |   397 +
 LICENSE.txt                                        |    25 +
 README.md                                          |    58 +
 config/CPackConfig.cmake                           |    21 +
 config/CTestConfig.cmake.template                  |    12 +
 config/FindFFTW3.cmake                             |    28 +
 config/FindFFTW3F.cmake                            |    28 +
 config/FindHDF5.cmake                              |    81 +
 config/FindOpenEXR.cmake                           |    44 +
 config/FindVIGRANUMPY_DEPENDENCIES.cmake           |   174 +
 config/VIGRA_ADD_NUMPY_MODULE.cmake                |   107 +
 config/VigraAddTest.cmake                          |   141 +
 config/VigraCMakeUtils.cmake                       |    12 +
 config/VigraConfig.cmake.in                        |    14 +
 config/VigraConfigBuild.cmake.in                   |     6 +
 config/VigraConfigVersion.cmake.in                 |    12 +
 config/VigraFindPackage.cmake                      |    81 +
 config/VigraSetDefaults.cmake                      |   129 +
 config/VigranumpyConfig.cmake.in                   |    64 +
 config/checkHDF5usesCompression.c                  |     8 +
 config/checkHDF5version.c                          |     9 +
 config/package-src.cmake.in                        |    53 +
 config/run_test.bat.in                             |    18 +
 config/run_test.sh.in                              |     1 +
 config/update-gh-pages.sh.in                       |    21 +
 config/vigra-config.in                             |    94 +
 config/winsetup.iss                                |   146 +
 docsrc/CMakeLists.txt                              |    67 +
 docsrc/Doxyfile.in                                 |  1446 +
 docsrc/credits_changelog.dxx                       |   678 +
 docsrc/doxygen.css                                 |   389 +
 docsrc/examples.dxx                                |   163 +
 docsrc/footer.html                                 |    24 +
 docsrc/header.html                                 |    32 +
 docsrc/image_processing.dxx                        |   354 +
 docsrc/index.dxx                                   |   601 +
 docsrc/index_fallback.html                         |    13 +
 docsrc/installation.dxx                            |    66 +
 docsrc/makeFunctionIndex.py                        |   166 +
 docsrc/post.py                                     |   184 +
 docsrc/tutorial.dxx                                |   933 +
 docsrc/vigra-icon.ico                              |   Bin 0 -> 15086 bytes
 docsrc/vigra-icon.xcf                              |   Bin 0 -> 66223 bytes
 docsrc/vigra-wiki.html                             |  9978 +++
 docsrc/vigra.css                                   |   457 +
 docsrc/vigra_1_8_2.css                             |  1622 +
 include/vigra/accessor.hxx                         |  1023 +
 include/vigra/accumulator-grammar.hxx              |   749 +
 include/vigra/accumulator.hxx                      |  5847 ++
 include/vigra/affine_registration.hxx              |   806 +
 include/vigra/affinegeometry.hxx                   |   421 +
 include/vigra/algorithm.hxx                        |   730 +
 include/vigra/array_vector.hxx                     |   918 +
 include/vigra/autodiff.hxx                         |   636 +
 include/vigra/axistags.hxx                         |  1097 +
 include/vigra/basicgeometry.hxx                    |   973 +
 include/vigra/basicimage.hxx                       |  1512 +
 include/vigra/basicimageview.hxx                   |   707 +
 include/vigra/bessel.hxx                           |   337 +
 include/vigra/bit_array.hxx                        |   318 +
 include/vigra/bordertreatment.hxx                  |    90 +
 include/vigra/boundarytensor.hxx                   |   897 +
 include/vigra/box.hxx                              |   545 +
 include/vigra/bucket_queue.hxx                     |   404 +
 include/vigra/cellconfigurations.hxx               |  1331 +
 include/vigra/cellimage.hxx                        |   272 +
 include/vigra/clebsch-gordan.hxx                   |   423 +
 include/vigra/codec.hxx                            |   303 +
 include/vigra/colorconversions.hxx                 |  3420 ++
 include/vigra/combineimages.hxx                    |   814 +
 include/vigra/config.hxx                           |   273 +
 include/vigra/configVersion.hxx                    |    45 +
 include/vigra/contourcirculator.hxx                |   239 +
 include/vigra/convolution.hxx                      |  1883 +
 include/vigra/coordinate_iterator.hxx              |   762 +
 include/vigra/copyimage.hxx                        |   421 +
 include/vigra/cornerdetection.hxx                  |   893 +
 include/vigra/diff2d.hxx                           |  1425 +
 include/vigra/distancetransform.hxx                |   464 +
 include/vigra/edgedetection.hxx                    |  2994 +
 include/vigra/eigensystem.hxx                      |  1231 +
 include/vigra/error.hxx                            |   337 +
 include/vigra/fftw.hxx                             |  1209 +
 include/vigra/fftw3.hxx                            |  2772 +
 include/vigra/fixedpoint.hxx                       |  1795 +
 include/vigra/flatmorphology.hxx                   |  1416 +
 include/vigra/functorexpression.hxx                |  2072 +
 include/vigra/functortraits.hxx                    |   266 +
 include/vigra/gaborfilter.hxx                      |   458 +
 include/vigra/gaussians.hxx                        |   234 +
 include/vigra/gradient_energy_tensor.hxx           |   231 +
 include/vigra/graphs.hxx                           |   286 +
 include/vigra/hdf5impex.hxx                        |  3109 +
 include/vigra/histogram.hxx                        |   368 +
 include/vigra/imagecontainer.hxx                   |   775 +
 include/vigra/imageinfo.hxx                        |   568 +
 include/vigra/imageiterator.hxx                    |  1564 +
 include/vigra/imageiteratoradapter.hxx             |   605 +
 include/vigra/impex.hxx                            |  1026 +
 include/vigra/impexalpha.hxx                       |  1105 +
 include/vigra/impexbase.hxx                        |   236 +
 include/vigra/initimage.hxx                        |   723 +
 include/vigra/inspectimage.hxx                     |  2256 +
 include/vigra/inspector_passes.hxx                 |    79 +
 include/vigra/interpolating_accessor.hxx           |   170 +
 include/vigra/invariant_features3D.hxx             |    71 +
 include/vigra/iteratoradapter.hxx                  |   302 +
 include/vigra/iteratortags.hxx                     |    52 +
 include/vigra/iteratortraits.hxx                   |   701 +
 include/vigra/labelimage.hxx                       |  1167 +
 include/vigra/labelvolume.hxx                      |   740 +
 include/vigra/linear_algebra.hxx                   |    44 +
 include/vigra/linear_solve.hxx                     |  1279 +
 include/vigra/localminmax.hxx                      |  2014 +
 include/vigra/mathutil.hxx                         |  1625 +
 include/vigra/matlab.hxx                           |  1304 +
 include/vigra/matlab_FLEXTYPE.hxx                  |   232 +
 include/vigra/matrix.hxx                           |  3026 +
 include/vigra/memory.hxx                           |   119 +
 include/vigra/meshgrid.hxx                         |   133 +
 include/vigra/metaprogramming.hxx                  |   848 +
 include/vigra/multi_array.hxx                      |  3383 +
 include/vigra/multi_convolution.hxx                |  2714 +
 include/vigra/multi_distance.hxx                   |   665 +
 include/vigra/multi_fft.hxx                        |  2249 +
 include/vigra/multi_gridgraph.hxx                  |  3002 +
 include/vigra/multi_impex.hxx                      |   903 +
 include/vigra/multi_iterator.hxx                   |  2255 +
 include/vigra/multi_iterator_coupled.hxx           |  1185 +
 include/vigra/multi_labeling.hxx                   |   344 +
 include/vigra/multi_localminmax.hxx                |   308 +
 include/vigra/multi_math.hxx                       |   882 +
 include/vigra/multi_morphology.hxx                 |   680 +
 include/vigra/multi_opencl.hxx                     |   443 +
 include/vigra/multi_pointoperators.hxx             |  2030 +
 include/vigra/multi_resize.hxx                     |   328 +
 include/vigra/multi_shape.hxx                      |   675 +
 include/vigra/multi_tensorutilities.hxx            |   641 +
 include/vigra/multi_watersheds.hxx                 |   508 +
 include/vigra/navigator.hxx                        |   435 +
 include/vigra/noise_normalization.hxx              |  1752 +
 include/vigra/nonlineardiffusion.hxx               |   777 +
 include/vigra/numerictraits.hxx                    |  1350 +
 include/vigra/numpy_array.hxx                      |  1232 +
 include/vigra/numpy_array_converters.hxx           |   304 +
 include/vigra/numpy_array_taggedshape.hxx          |   838 +
 include/vigra/numpy_array_traits.hxx               |   840 +
 include/vigra/orientedtensorfilters.hxx            |   640 +
 include/vigra/pixelneighborhood.hxx                |  1531 +
 include/vigra/polygon.hxx                          |   130 +
 include/vigra/polynomial.hxx                       |  1112 +
 include/vigra/project2ellipse.hxx                  |   177 +
 include/vigra/promote_traits.hxx                   |  1520 +
 include/vigra/promote_traits.hxx.py                |    74 +
 include/vigra/python_utility.hxx                   |   415 +
 include/vigra/quadprog.hxx                         |   354 +
 include/vigra/quaternion.hxx                       |   559 +
 include/vigra/random.hxx                           |   911 +
 include/vigra/random_forest.hxx                    |  1383 +
 include/vigra/random_forest/features.hxx           |   114 +
 include/vigra/random_forest/rf_algorithm.hxx       |  1339 +
 include/vigra/random_forest/rf_common.hxx          |   908 +
 include/vigra/random_forest/rf_decisionTree.hxx    |   478 +
 include/vigra/random_forest/rf_earlystopping.hxx   |   418 +
 include/vigra/random_forest/rf_nodeproxy.hxx       |   672 +
 .../random_forest/rf_online_prediction_set.hxx     |    77 +
 include/vigra/random_forest/rf_preprocessing.hxx   |   335 +
 include/vigra/random_forest/rf_region.hxx          |   197 +
 include/vigra/random_forest/rf_ridge_split.hxx     |   446 +
 include/vigra/random_forest/rf_split.hxx           |  1380 +
 include/vigra/random_forest/rf_visitors.hxx        |  1722 +
 include/vigra/random_forest/splices.hxx            |   140 +
 include/vigra/random_forest_deprec.hxx             |  1142 +
 include/vigra/random_forest_hdf5_impex.hxx         |   305 +
 include/vigra/rational.hxx                         |  1312 +
 include/vigra/recursiveconvolution.hxx             |  2229 +
 include/vigra/regression.hxx                       |  1276 +
 include/vigra/resampling_convolution.hxx           |  1202 +
 include/vigra/resizeimage.hxx                      |  1115 +
 include/vigra/rfftw.hxx                            |   248 +
 include/vigra/rgbvalue.hxx                         |  1331 +
 include/vigra/sampling.hxx                         |   567 +
 include/vigra/seededregiongrowing.hxx              |  1000 +
 include/vigra/seededregiongrowing3d.hxx            |   668 +
 include/vigra/separableconvolution.hxx             |  2584 +
 include/vigra/sifImport.hxx                        |   248 +
 include/vigra/singular_value_decomposition.hxx     |   565 +
 include/vigra/sized_int.hxx                        |   212 +
 include/vigra/slanted_edge_mtf.hxx                 |   735 +
 include/vigra/slic.hxx                             |   489 +
 include/vigra/splineimageview.hxx                  |  1882 +
 include/vigra/splines.hxx                          |  1385 +
 include/vigra/static_assert.hxx                    |   133 +
 include/vigra/stdconvolution.hxx                   |  1347 +
 include/vigra/stdimage.hxx                         |   333 +
 include/vigra/stdimagefunctions.hxx                |    76 +
 include/vigra/symmetry.hxx                         |   312 +
 include/vigra/tensorutilities.hxx                  |   616 +
 include/vigra/tiff.hxx                             |  2028 +
 include/vigra/timing.hxx                           |   374 +
 include/vigra/tinyvector.hxx                       |  2051 +
 include/vigra/transformimage.hxx                   |  1664 +
 include/vigra/tuple.hxx                            |   181 +
 include/vigra/tv_filter.hxx                        |   767 +
 include/vigra/type_lists.hxx                       |  1929 +
 include/vigra/union_find.hxx                       |   152 +
 include/vigra/unittest.hxx                         |  1170 +
 include/vigra/unsupervised_decomposition.hxx       |   384 +
 include/vigra/utilities.hxx                        |   163 +
 include/vigra/voxelneighborhood.hxx                |  1652 +
 include/vigra/watersheds.hxx                       |  1498 +
 include/vigra/watersheds3d.hxx                     |   460 +
 include/vigra/wigner-matrix.hxx                    |   321 +
 include/vigra/windows.h                            |    59 +
 src/CMakeLists.txt                                 |     2 +
 src/examples/CMakeLists.txt                        |    24 +
 src/examples/aniso_tv.par                          |    14 +
 src/examples/block.tif                             |   Bin 0 -> 60312 bytes
 src/examples/boundarytensor.cxx                    |   115 +
 src/examples/cameraman.png                         |   Bin 0 -> 48912 bytes
 src/examples/cameraman_noise.png                   |   Bin 0 -> 64585 bytes
 src/examples/convert.cxx                           |    93 +
 src/examples/edge.cxx                              |   108 +
 src/examples/house.tif                             |   Bin 0 -> 49426 bytes
 src/examples/invert.cxx                            |   124 +
 src/examples/invert_explicitly.cxx                 |   149 +
 src/examples/lenna.bmp                             |   Bin 0 -> 984118 bytes
 src/examples/lenna_color.gif                       |   Bin 0 -> 197227 bytes
 src/examples/lenna_color_small.gif                 |   Bin 0 -> 26116 bytes
 src/examples/lenna_gray.gif                        |   Bin 0 -> 234921 bytes
 src/examples/lenna_small.gif                       |   Bin 0 -> 26116 bytes
 src/examples/lenna_stripes.gif                     |   Bin 0 -> 26116 bytes
 src/examples/lenna_sub.gif                         |   Bin 0 -> 70462 bytes
 src/examples/lenna_transposed.gif                  |   Bin 0 -> 26116 bytes
 src/examples/oi.JPG                                |   Bin 0 -> 648023 bytes
 src/examples/oi.png                                |   Bin 0 -> 5522017 bytes
 src/examples/oi_small.jpg                          |   Bin 0 -> 8596 bytes
 src/examples/palette.cxx                           |   294 +
 src/examples/profile.cxx                           |   106 +
 src/examples/pyramid.cxx                           |   134 +
 src/examples/resize.cxx                            |   164 +
 src/examples/second_order_tv.par                   |    15 +
 src/examples/smooth.cxx                            |   150 +
 src/examples/subimage.cxx                          |    95 +
 src/examples/total_variation.cxx                   |   285 +
 src/examples/tutorial/cameraman.png                |   Bin 0 -> 48912 bytes
 src/examples/tutorial/chess_smoothed.gif           |   Bin 0 -> 29823 bytes
 src/examples/tutorial/composite.cxx                |    68 +
 src/examples/tutorial/conv1.gif                    |   Bin 0 -> 29823 bytes
 src/examples/tutorial/conv2.gif                    |   Bin 0 -> 29823 bytes
 src/examples/tutorial/conv3.gif                    |   Bin 0 -> 29823 bytes
 src/examples/tutorial/conv4.gif                    |   Bin 0 -> 29823 bytes
 src/examples/tutorial/dissolve.cxx                 |    62 +
 src/examples/tutorial/dissolved.gif                |   Bin 0 -> 75107 bytes
 src/examples/tutorial/dissolved_color.gif          |   Bin 0 -> 26116 bytes
 src/examples/tutorial/imageExportInfo_tutorial.cxx |    34 +
 src/examples/tutorial/imageIO_tutorial.cxx         |    53 +
 src/examples/tutorial/imageImportInfo_tutorial.cxx |    37 +
 src/examples/tutorial/invert_tutorial.cxx          |    66 +
 src/examples/tutorial/lenna_color.gif              |   Bin 0 -> 197227 bytes
 src/examples/tutorial/lenna_color_small.gif        |   Bin 0 -> 26116 bytes
 src/examples/tutorial/lenna_composite_color.gif    |   Bin 0 -> 102075 bytes
 src/examples/tutorial/lenna_gray.gif               |   Bin 0 -> 234921 bytes
 src/examples/tutorial/lenna_inverted_color.gif     |   Bin 0 -> 279458 bytes
 src/examples/tutorial/lenna_small.gif              |   Bin 0 -> 26116 bytes
 src/examples/tutorial/lenna_smoothed.gif           |   Bin 0 -> 26116 bytes
 src/examples/tutorial/mirror_tutorial.cxx          |    60 +
 src/examples/tutorial/oi.JPG                       |   Bin 0 -> 648023 bytes
 src/examples/tutorial/oi_small.jpg                 |   Bin 0 -> 8596 bytes
 src/examples/tutorial/smooth_convolve.cxx          |   116 +
 src/examples/tutorial/smooth_explicitly.cxx        |    92 +
 src/examples/tutorial/subimage_tutorial.cxx        |    70 +
 src/examples/tutorial/testimage.gif                |   Bin 0 -> 29823 bytes
 src/examples/tutorial/transpose.cxx                |    76 +
 src/examples/tutorial/transpose_image_tutorial.cxx |    53 +
 src/examples/tv.par                                |     8 +
 src/examples/voronoi.cxx                           |   107 +
 src/examples/watershed.cxx                         |   143 +
 src/examples/weightedWatersheds.cxx                |   204 +
 src/images/conv1.gif                               |   Bin 0 -> 29823 bytes
 src/images/conv2.gif                               |   Bin 0 -> 29823 bytes
 src/images/conv3.gif                               |   Bin 0 -> 29823 bytes
 src/images/conv4.gif                               |   Bin 0 -> 29823 bytes
 src/images/dissolved.gif                           |   Bin 0 -> 75107 bytes
 src/images/dissolved_color.gif                     |   Bin 0 -> 26116 bytes
 src/images/lenna_color.gif                         |   Bin 0 -> 197227 bytes
 src/images/lenna_color_small.gif                   |   Bin 0 -> 26116 bytes
 src/images/lenna_composite_color.gif               |   Bin 0 -> 102075 bytes
 src/images/lenna_gray.gif                          |   Bin 0 -> 234921 bytes
 src/images/lenna_inverted.gif                      |   Bin 0 -> 26116 bytes
 src/images/lenna_mirror_horizontal.gif             |   Bin 0 -> 26116 bytes
 src/images/lenna_mirror_vertical.gif               |   Bin 0 -> 26116 bytes
 src/images/lenna_small.gif                         |   Bin 0 -> 26116 bytes
 src/images/lenna_smoothed.gif                      |   Bin 0 -> 26116 bytes
 src/images/lenna_stripes.gif                       |   Bin 0 -> 26116 bytes
 src/images/lenna_sub.gif                           |   Bin 0 -> 7253 bytes
 src/images/lenna_transposed_major.gif              |   Bin 0 -> 26116 bytes
 src/images/lenna_transposed_minor.gif              |   Bin 0 -> 26116 bytes
 src/images/oi.JPG                                  |   Bin 0 -> 648023 bytes
 src/images/oi_small.jpg                            |   Bin 0 -> 8596 bytes
 src/images/testimage.gif                           |   Bin 0 -> 29823 bytes
 src/images/testimage.jpg                           |   Bin 0 -> 8522 bytes
 src/impex/CMakeLists.txt                           |    89 +
 src/impex/auto_file.hxx                            |    84 +
 src/impex/bmp.cxx                                  |  1120 +
 src/impex/bmp.hxx                                  |   107 +
 src/impex/byteorder.cxx                            |    87 +
 src/impex/byteorder.hxx                            |   181 +
 src/impex/codecmanager.cxx                         |   393 +
 src/impex/codecmanager.hxx                         |   116 +
 src/impex/error.hxx                                |    44 +
 src/impex/exr.cxx                                  |   509 +
 src/impex/exr.hxx                                  |   123 +
 src/impex/gif.cxx                                  |  1076 +
 src/impex/gif.hxx                                  |   108 +
 src/impex/hdf5_rf_impex.cxx                        |   120 +
 src/impex/hdf5impex.cxx                            |   219 +
 src/impex/hdr.cxx                                  |   390 +
 src/impex/hdr.hxx                                  |   117 +
 src/impex/iccjpeg.c                                |   289 +
 src/impex/iccjpeg.h                                |    84 +
 src/impex/imageinfo.cxx                            |  1220 +
 src/impex/jpeg.cxx                                 |   527 +
 src/impex/jpeg.hxx                                 |   113 +
 src/impex/png.cxx                                  |   780 +
 src/impex/png.hxx                                  |   131 +
 src/impex/pnm.cxx                                  |   827 +
 src/impex/pnm.hxx                                  |   110 +
 src/impex/rgbe.c                                   |   547 +
 src/impex/rgbe.h                                   |    78 +
 src/impex/sifImport.cxx                            |   304 +
 src/impex/sun.cxx                                  |   520 +
 src/impex/sun.hxx                                  |   108 +
 src/impex/tiff.cxx                                 |  1075 +
 src/impex/tiff.hxx                                 |   151 +
 src/impex/viff.cxx                                 |  1090 +
 src/impex/viff.hxx                                 |   108 +
 src/impex/void_vector.cxx                          |    46 +
 src/impex/void_vector.hxx                          |   266 +
 src/matlab/RandomForestProgressVisitor.hxx         |    40 +
 src/matlab/buildVigraExtensions.m                  |   227 +
 src/matlab/cellimage.hxx                           |   272 +
 src/matlab/doc/tutorial_reference.pdf              |   Bin 0 -> 107966 bytes
 src/matlab/doc/tutorial_reference.tex              |   366 +
 src/matlab/random_forest_impex.hxx                 |   113 +
 src/matlab/test-routines/vigraTestConstrScalar.cpp |    78 +
 src/matlab/test-routines/vigraTestCopy.cpp         |   100 +
 src/matlab/test-routines/vigraTestCopyMixed.cpp    |    97 +
 src/matlab/test-routines/vigraTestCopyOpt.cpp      |    97 +
 src/matlab/test-routines/vigraTestDefault.cpp      |    83 +
 src/matlab/test-routines/vigraTestEnum.cpp         |    74 +
 src/matlab/test-routines/vigraTestOptional.cpp     |    94 +
 src/matlab/test-routines/vigraTestString.cpp       |    80 +
 src/matlab/testVigraExtensions.m                   |   740 +
 src/matlab/vigraAdjacency.cpp                      |   328 +
 src/matlab/vigraBoundaryTensor.cpp                 |   106 +
 src/matlab/vigraConnectedComponents.cpp            |   206 +
 src/matlab/vigraCorner.cpp                         |   122 +
 src/matlab/vigraDistance.cpp                       |   224 +
 src/matlab/vigraExporthdf5RF.cpp                   |   100 +
 src/matlab/vigraImporthdf5RF.cpp                   |   100 +
 src/matlab/vigraIndex.m                            |    55 +
 src/matlab/vigraLearnRF.cpp                        |   190 +
 src/matlab/vigraLeastAngleRegression.cpp           |   137 +
 src/matlab/vigraPredictIndividually.cpp            |    97 +
 src/matlab/vigraPredictLabelsRF.cpp                |    89 +
 src/matlab/vigraPredictProbabilitiesRF.cpp         |    89 +
 src/matlab/vigraRadialSymmetry.cpp                 |    95 +
 src/matlab/vigraResize2.cpp                        |   187 +
 src/matlab/vigraResize3.cpp                        |   163 +
 src/matlab/vigraWatershed.cpp                      |   242 +
 src/regression.cpp                                 |    30 +
 test/CMakeLists.txt                                |    37 +
 test/checkUnitTests.py                             |    24 +
 test/classifier/CMakeLists.txt                     |    14 +
 test/classifier/data/CMakeLists.txt                |     7 +
 test/classifier/data/RF_common.hxx                 |   171 +
 test/classifier/data/RF_data.hxx                   |   142 +
 test/classifier/data/SPECTF_features.hxx           |    85 +
 test/classifier/data/SPECTF_labels.hxx             |    89 +
 test/classifier/data/ecoli_features.hxx            |   341 +
 test/classifier/data/ecoli_labels.hxx              |   344 +
 test/classifier/data/glass_features.hxx            |   219 +
 test/classifier/data/glass_labels.hxx              |   222 +
 test/classifier/data/ionosphere_features.hxx       |   356 +
 test/classifier/data/ionosphere_labels.hxx         |   359 +
 test/classifier/data/iris_features.hxx             |   156 +
 test/classifier/data/iris_labels.hxx               |   160 +
 test/classifier/data/oldClassifier.log             | 61218 +++++++++++++++++++
 test/classifier/data/oldsetTest.log                |   618 +
 .../data/pina_indians_diabetes_features.hxx        |   774 +
 .../data/pina_indians_diabetes_labels.hxx          |   777 +
 test/classifier/data/segmentation_features.hxx     |   215 +
 test/classifier/data/segmentation_labels.hxx       |   218 +
 test/classifier/data/wine_features.hxx             |   183 +
 test/classifier/data/wine_labels.hxx               |   186 +
 test/classifier/data/wpbc_features.hxx             |   198 +
 test/classifier/data/wpbc_labels.hxx               |   202 +
 test/classifier/speed_comparison.cxx               |    48 +
 test/classifier/test.cxx                           |  1085 +
 test/classifier/test_visitors.hxx                  |   241 +
 test/colorspaces/CMakeLists.txt                    |     1 +
 test/colorspaces/test.cxx                          |   480 +
 test/convolution/CMakeLists.txt                    |     3 +
 test/convolution/coscot.xv                         |   Bin 0 -> 972196 bytes
 test/convolution/lenna128.xv                       |   Bin 0 -> 62464 bytes
 test/convolution/lenna128nonlinear.xv              |   Bin 0 -> 62464 bytes
 test/convolution/lenna128recgrad.xv                |   Bin 0 -> 123904 bytes
 test/convolution/lenna128rgb.xv                    |   Bin 0 -> 185344 bytes
 test/convolution/lenna128rgbsepgrad.xv             |   Bin 0 -> 123904 bytes
 test/convolution/lenna128sepgrad.xv                |   Bin 0 -> 123904 bytes
 test/convolution/lenna_gaussian_sharpening_orig.xv |   Bin 0 -> 123904 bytes
 test/convolution/lenna_level-1.xv                  |   Bin 0 -> 488584 bytes
 test/convolution/lenna_level-2.xv                  |   Bin 0 -> 1943368 bytes
 test/convolution/lenna_level1.xv                   |   Bin 0 -> 31744 bytes
 test/convolution/lenna_level2.xv                   |   Bin 0 -> 8704 bytes
 test/convolution/lenna_levellap0.xv                |   Bin 0 -> 123904 bytes
 test/convolution/lenna_levellap1.xv                |   Bin 0 -> 31744 bytes
 test/convolution/lenna_levellap2.xv                |   Bin 0 -> 8704 bytes
 test/convolution/lenna_simple_sharpening_orig.xv   |   Bin 0 -> 123904 bytes
 test/convolution/lennahessxx.xv                    |   Bin 0 -> 123904 bytes
 test/convolution/lennahessxy.xv                    |   Bin 0 -> 123904 bytes
 test/convolution/lennahessyy.xv                    |   Bin 0 -> 123904 bytes
 test/convolution/lennargbst.xv                     |   Bin 0 -> 369664 bytes
 test/convolution/lennastxx.xv                      |   Bin 0 -> 123904 bytes
 test/convolution/lennastxy.xv                      |   Bin 0 -> 123904 bytes
 test/convolution/lennastyy.xv                      |   Bin 0 -> 123904 bytes
 test/convolution/resampling.xv                     |   Bin 0 -> 242832 bytes
 test/convolution/test.cxx                          |  2521 +
 test/convolution/tv_test_data.hxx                  |   260 +
 test/coordinateiterator/CMakeLists.txt             |     1 +
 test/coordinateiterator/test.cxx                   |   367 +
 test/error/CMakeLists.txt                          |     3 +
 test/error/test.cxx                                |   125 +
 test/features/CMakeLists.txt                       |    10 +
 test/features/test.cxx                             |   171 +
 test/features/wigner-matrix-reference.hxx          |   324 +
 test/fourier/CMakeLists.txt                        |     9 +
 test/fourier/filter.xv                             |   Bin 0 -> 66560 bytes
 test/fourier/gaborresult.xv                        |   Bin 0 -> 66560 bytes
 test/fourier/ghouse.gif                            |   Bin 0 -> 9470 bytes
 test/fourier/test.cxx                              |   886 +
 test/fourier/test.hxx                              |   771 +
 test/functorexpression/CMakeLists.txt              |     1 +
 test/functorexpression/test.cxx                    |   472 +
 test/gridgraph/CMakeLists.txt                      |    13 +
 test/gridgraph/test.cxx                            |  1276 +
 test/hdf5impex/CMakeLists.txt                      |     9 +
 test/hdf5impex/test.cxx                            |  1378 +
 test/image/CMakeLists.txt                          |     3 +
 test/image/lenna.gif                               |   Bin 0 -> 13253 bytes
 test/image/lenna.xv                                |   Bin 0 -> 17137 bytes
 test/image/test.cxx                                |   914 +
 test/imagehierarchy/NewImHier.hxx                  |  2205 +
 test/imagehierarchy/basic_image_test.hxx           |   105 +
 test/imagehierarchy/g++_relops_workaround.hxx      |    13 +
 test/imagehierarchy/gray_image_test_suite.cxx      |    19 +
 test/imagehierarchy/imagehierarchy_test.hxx        |   375 +
 .../one_band_basic_image_test_suite.cxx            |    31 +
 test/imagehierarchy/one_band_image_policy.hxx      |    54 +
 test/imagehierarchy/parent_test_class.hxx          |   619 +
 test/imagehierarchy/rgb_basic_image_test.hxx       |    56 +
 test/imagehierarchy/rgb_basic_image_test_suite.cxx |    22 +
 test/imagehierarchy/rgb_imagehierarchy_test.hxx    |    54 +
 .../rgb_imagehierarchy_test_suite.cxx              |    20 +
 test/imagehierarchy/rgb_images_policy.hxx          |    58 +
 test/imagehierarchy/select_band_image_policy.hxx   |    84 +
 .../select_band_image_test_suite.cxx               |    41 +
 test/imagehierarchy/select_image_test.hxx          |   209 +
 test/imagehierarchy/single_band_image_policy.hxx   |    76 +
 test/imagehierarchy/single_band_image_test.hxx     |   133 +
 .../single_band_image_test_suite.cxx               |    26 +
 test/imagehierarchy/test_policy_parent.hxx         |    69 +
 test/imagehierarchy/tests_start_suite.cxx          |    45 +
 .../imagehierarchy/variable_bands_image_policy.hxx |    81 +
 test/imagehierarchy/variable_bands_image_test.hxx  |   133 +
 .../variable_bands_image_test_suite.cxx            |    33 +
 .../vector_2_basic_image_test_suite.cxx            |    19 +
 test/imagehierarchy/vector_2_image_policy.hxx      |    52 +
 .../vector_2_imagehierarchy_test_suite.cxx         |    18 +
 .../vector_3_basic_image_test_suite.cxx            |    19 +
 test/imagehierarchy/vector_3_image_policy.hxx      |    55 +
 .../vector_3_imagehierarchy_test_suite.cxx         |    18 +
 .../vector_4_basic_image_test_suite.cxx            |    19 +
 test/imagehierarchy/vector_4_image_policy.hxx      |    55 +
 .../vector_4_imagehierarchy_test_suite.cxx         |    18 +
 test/imgproc/CMakeLists.txt                        |     3 +
 test/imgproc/lenna128.xv                           |   Bin 0 -> 62464 bytes
 test/imgproc/lenna128rgb.xv                        |   Bin 0 -> 185344 bytes
 test/imgproc/lenna288.xv                           |   Bin 0 -> 307616 bytes
 test/imgproc/lenna288neu.xv                        |   Bin 0 -> 307616 bytes
 test/imgproc/lenna288rgb.xv                        |   Bin 0 -> 920800 bytes
 test/imgproc/lenna288rgbneu.xv                     |   Bin 0 -> 920800 bytes
 test/imgproc/lenna367FIR.xv                        |   Bin 0 -> 1013944 bytes
 test/imgproc/lenna367IIR.xv                        |   Bin 0 -> 507484 bytes
 test/imgproc/lenna42.xv                            |   Bin 0 -> 7744 bytes
 test/imgproc/lenna42FIR.xv                         |   Bin 0 -> 7744 bytes
 test/imgproc/lenna42IIR.xv                         |   Bin 0 -> 7744 bytes
 test/imgproc/lenna42lin.xv                         |   Bin 0 -> 14464 bytes
 test/imgproc/lenna42linrgb.xv                      |   Bin 0 -> 21184 bytes
 test/imgproc/lenna42neu.xv                         |   Bin 0 -> 7744 bytes
 test/imgproc/lenna42rgb.xv                         |   Bin 0 -> 21184 bytes
 test/imgproc/lenna42rgbneu.xv                      |   Bin 0 -> 21184 bytes
 test/imgproc/lenna_rotate.xv                       |   Bin 0 -> 123904 bytes
 test/imgproc/lennargb42FIR.xv                      |   Bin 0 -> 21184 bytes
 test/imgproc/lennargb42IIR.xv                      |   Bin 0 -> 21184 bytes
 test/imgproc/splineimageview2.xv                   |   Bin 0 -> 307616 bytes
 test/imgproc/splineimageview3.xv                   |   Bin 0 -> 307616 bytes
 test/imgproc/splineimageview5.xv                   |   Bin 0 -> 307616 bytes
 test/imgproc/test.cxx                              |  1841 +
 test/impex/CMakeLists.txt                          |    21 +
 test/impex/lenna.xv                                |   Bin 0 -> 16384 bytes
 test/impex/lenna_0.tif                             |   Bin 0 -> 16554 bytes
 test/impex/lenna_1.tif                             |   Bin 0 -> 16554 bytes
 test/impex/lenna_2.tif                             |   Bin 0 -> 16554 bytes
 test/impex/lenna_gifref.xv                         |   Bin 0 -> 47104 bytes
 test/impex/lenna_masked_color.tif                  |   Bin 0 -> 43220 bytes
 test/impex/lenna_masked_gray.tif                   |   Bin 0 -> 15588 bytes
 test/impex/lennafloat.xv                           |   Bin 0 -> 62464 bytes
 test/impex/lennafloatrgb.xv                        |   Bin 0 -> 185344 bytes
 test/impex/lennargb.xv                             |   Bin 0 -> 17137 bytes
 test/impex/no-image.txt                            |     1 +
 test/impex/test.cxx                                |  1860 +
 test/math/CMakeLists.txt                           |     1 +
 test/math/convex_hull_test.hxx                     |   460 +
 test/math/test.cxx                                 |  3103 +
 test/morphology/CMakeLists.txt                     |     1 +
 test/morphology/test.cxx                           |   296 +
 test/multiarray/CMakeLists.txt                     |    15 +
 test/multiarray/test.cxx                           |  2991 +
 test/multiconvolution/CMakeLists.txt               |     5 +
 test/multiconvolution/oi_single.gif                |   Bin 0 -> 436826 bytes
 test/multiconvolution/speedtest.cxx                |   387 +
 test/multiconvolution/test.cxx                     |  1313 +
 test/multidistance/CMakeLists.txt                  |     9 +
 test/multidistance/test.cxx                        |  1175 +
 test/multimorphology/CMakeLists.txt                |     1 +
 test/multimorphology/test.cxx                      |   324 +
 test/objectfeatures/CMakeLists.txt                 |     4 +
 test/objectfeatures/of.gif                         |   Bin 0 -> 3385 bytes
 test/objectfeatures/test.cxx                       |  1460 +
 test/optimization/CMakeLists.txt                   |     1 +
 test/optimization/larsdata.hxx                     |  9065 +++
 test/optimization/test.cxx                         |   689 +
 test/pixeltypes/CMakeLists.txt                     |     1 +
 test/pixeltypes/test.cxx                           |  1038 +
 test/sampler/CMakeLists.txt                        |     1 +
 test/sampler/test.cxx                              |   433 +
 test/seededRegionGrowing3d/CMakeLists.txt          |     1 +
 test/seededRegionGrowing3d/test.cxx                |   320 +
 test/sifImport/CMakeLists.txt                      |     8 +
 test/sifImport/test.cxx                            |   209 +
 test/sifImport/testSif_4_13_30000.sif              |   Bin 0 -> 2636 bytes
 test/sifImport/testSif_4_16_30001.sif              |   Bin 0 -> 68266 bytes
 test/sifImport/testSif_4_6_30000.sif               |   Bin 0 -> 554 bytes
 test/sifImport/testSif_forBlocks_4_16_30001.sif    |   Bin 0 -> 2936 bytes
 test/sifImport/testSif_ref_4_16_30001.hxx          |   130 +
 test/simpleanalysis/CMakeLists.txt                 |    10 +
 test/simpleanalysis/lenna128.xv                    |   Bin 0 -> 62464 bytes
 test/simpleanalysis/noiseNormalizationTest.xv      |   Bin 0 -> 33024 bytes
 test/simpleanalysis/slantedEdgeMTF.xv              |   Bin 0 -> 37368 bytes
 test/simpleanalysis/test.cxx                       |  2487 +
 test/simpleanalysis/test_freaky.cxx                |    24 +
 test/slic2d/CMakeLists.txt                         |     3 +
 test/slic2d/lenna.xv                               |   Bin 0 -> 17137 bytes
 test/slic2d/slic.xv                                |   Bin 0 -> 62464 bytes
 test/slic2d/test.cxx                               |   144 +
 test/tensorimaging/CMakeLists.txt                  |     3 +
 test/tensorimaging/boundaryTensor.xv               |   Bin 0 -> 7960 bytes
 test/tensorimaging/l2.xv                           |   Bin 0 -> 60525 bytes
 test/tensorimaging/l2_boundary.xv                  |   Bin 0 -> 477032 bytes
 test/tensorimaging/l2_boundary1.xv                 |   Bin 0 -> 477032 bytes
 test/tensorimaging/l2_get.xv                       |   Bin 0 -> 477032 bytes
 test/tensorimaging/l2_hourglass.xv                 |   Bin 0 -> 477032 bytes
 test/tensorimaging/riesz00.xv                      |   Bin 0 -> 3336 bytes
 test/tensorimaging/riesz01.xv                      |   Bin 0 -> 3336 bytes
 test/tensorimaging/riesz02.xv                      |   Bin 0 -> 3336 bytes
 test/tensorimaging/riesz10.xv                      |   Bin 0 -> 3336 bytes
 test/tensorimaging/riesz11.xv                      |   Bin 0 -> 3336 bytes
 test/tensorimaging/riesz20.xv                      |   Bin 0 -> 3336 bytes
 test/tensorimaging/test.cxx                        |   335 +
 test/unsupervised/CMakeLists.txt                   |    15 +
 test/unsupervised/example_data.h5                  |   Bin 0 -> 655360 bytes
 test/unsupervised/test.cxx                         |   184 +
 test/unsupervised/test_data.hxx                    |  2090 +
 test/utilities/CMakeLists.txt                      |     1 +
 test/utilities/test.cxx                            |   508 +
 test/volumelabeling/CMakeLists.txt                 |     1 +
 test/volumelabeling/test.cxx                       |   484 +
 test/voxelneighborhood/CMakeLists.txt              |     1 +
 test/voxelneighborhood/test.cxx                    |  2335 +
 test/watersheds3d/CMakeLists.txt                   |     1 +
 test/watersheds3d/test.cxx                         |   503 +
 vigranumpy/CMakeLists.txt                          |    83 +
 vigranumpy/docsrc/CMakeLists.txt                   |    64 +
 vigranumpy/docsrc/_static/basic.css                |   413 +
 vigranumpy/docsrc/_static/default.css              |   210 +
 vigranumpy/docsrc/_static/doctools.js              |   232 +
 vigranumpy/docsrc/_static/file.png                 |   Bin 0 -> 392 bytes
 vigranumpy/docsrc/_static/jquery.js                |    32 +
 vigranumpy/docsrc/_static/minus.png                |   Bin 0 -> 199 bytes
 vigranumpy/docsrc/_static/plus.png                 |   Bin 0 -> 199 bytes
 vigranumpy/docsrc/_static/pygments.css             |    61 +
 vigranumpy/docsrc/_static/searchtools.js           |   467 +
 vigranumpy/docsrc/_static/vigra-icon.ico           |   Bin 0 -> 15086 bytes
 vigranumpy/docsrc/conf.py.in                       |   276 +
 vigranumpy/docsrc/index.rst                        |   673 +
 vigranumpy/docsrc/make.bat                         |   116 +
 vigranumpy/lib/CMakeLists.txt                      |    32 +
 vigranumpy/lib/__init__.py                         |   440 +
 vigranumpy/lib/arraytypes.py                       |  1979 +
 vigranumpy/lib/axistags.py                         |   250 +
 vigranumpy/lib/pyqt/CMakeLists.txt                 |     9 +
 vigranumpy/lib/pyqt/__init__.py                    |    41 +
 vigranumpy/lib/pyqt/imagewindow.py                 |   617 +
 vigranumpy/lib/pyqt/overlays.py                    |   205 +
 vigranumpy/lib/pyqt/quickdialog.py                 |   450 +
 vigranumpy/lib/pyqt/viewer2svg.py                  |   108 +
 vigranumpy/lib/tagged_array.py                     |   377 +
 vigranumpy/lib/ufunc.py                            |   368 +
 vigranumpy/setup.py.in                             |    37 +
 vigranumpy/src/CMakeLists.txt                      |     7 +
 vigranumpy/src/core/CMakeLists.txt                 |    65 +
 .../src/core/accumulator-region-multiband.cxx      |    69 +
 .../src/core/accumulator-region-singleband.cxx     |    65 +
 vigranumpy/src/core/accumulator.cxx                |   165 +
 vigranumpy/src/core/axistags.cxx                   |   748 +
 vigranumpy/src/core/colors.cxx                     |   639 +
 vigranumpy/src/core/converters.cxx                 |   425 +
 vigranumpy/src/core/convolution.cxx                |   761 +
 vigranumpy/src/core/edgedetection.cxx              |   473 +
 vigranumpy/src/core/filters.cxx                    |   132 +
 vigranumpy/src/core/geometry.cxx                   |    94 +
 vigranumpy/src/core/impex.cxx                      |   583 +
 vigranumpy/src/core/interestpoints.cxx             |   197 +
 vigranumpy/src/core/kernel.cxx                     |   491 +
 vigranumpy/src/core/learning.cxx                   |   150 +
 vigranumpy/src/core/morphology.cxx                 |   778 +
 vigranumpy/src/core/noise.cxx                      |   357 +
 vigranumpy/src/core/optimization.cxx               |   234 +
 vigranumpy/src/core/pythonaccumulator.hxx          |   955 +
 vigranumpy/src/core/random_forest.cxx              |   415 +
 vigranumpy/src/core/random_forest_old.cxx          |   178 +
 vigranumpy/src/core/sampling.cxx                   |   933 +
 vigranumpy/src/core/segmentation.cxx               |  1297 +
 vigranumpy/src/core/tensors.cxx                    |   772 +
 vigranumpy/src/core/tws.hxx                        |   374 +
 vigranumpy/src/core/vigranumpycore.cxx             |    74 +
 vigranumpy/src/core/vigranumpykernel.hxx           |    16 +
 vigranumpy/src/core/vigranumpyscaleparam.hxx       |   107 +
 vigranumpy/src/fourier/CMakeLists.txt              |     9 +
 vigranumpy/src/fourier/fourier.cxx                 |   259 +
 vigranumpy/test/CMakeLists.txt                     |   146 +
 vigranumpy/test/set_paths.py.in                    |    45 +
 vigranumpy/test/test1.py                           |   279 +
 vigranumpy/test/test2.py                           |   173 +
 vigranumpy/test/test3.py                           |   124 +
 vigranumpy/test/test_arraytypes.py                 |  1579 +
 vigranumpy/test/test_color.py                      |   106 +
 vigranumpy/test/test_impex.py                      |   160 +
 vigranumpy/test/vigranumpytest.cxx                 |   178 +
 661 files changed, 340765 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..6e01dd6
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,397 @@
+cmake_minimum_required(VERSION 2.6)
+
+##################################################
+#
+#     basic initializations
+#
+##################################################
+
+PROJECT(vigra)
+
+# read the current version from configVersion.hxx
+file(READ ${vigra_SOURCE_DIR}/include/vigra/configVersion.hxx VIGRA_VERSION_FILE)
+string(REGEX MATCH "VIGRA_VERSION_MAJOR[ \t\n]+[^ \t\n]+" VIGRA_VERSION_MAJOR ${VIGRA_VERSION_FILE})
+string(REGEX REPLACE "VIGRA_VERSION_MAJOR[ \t\n]" "" VIGRA_VERSION_MAJOR ${VIGRA_VERSION_MAJOR})
+string(REGEX MATCH "VIGRA_VERSION_MINOR[ \t\n]+[^ \t\n]+" VIGRA_VERSION_MINOR ${VIGRA_VERSION_FILE})
+string(REGEX REPLACE "VIGRA_VERSION_MINOR[ \t\n]" "" VIGRA_VERSION_MINOR ${VIGRA_VERSION_MINOR})
+string(REGEX MATCH "VIGRA_VERSION_PATCH[ \t\n]+[^ \t\n]+" VIGRA_VERSION_PATCH ${VIGRA_VERSION_FILE})
+string(REGEX REPLACE "VIGRA_VERSION_PATCH[ \t\n]" "" VIGRA_VERSION_PATCH ${VIGRA_VERSION_PATCH})
+
+SET(vigra_version_short ${VIGRA_VERSION_MAJOR}.${VIGRA_VERSION_MINOR})
+SET(vigra_version ${VIGRA_VERSION_MAJOR}.${VIGRA_VERSION_MINOR}.${VIGRA_VERSION_PATCH})
+message(STATUS "Configuring VIGRA version ${vigra_version}")
+
+SET(CMAKE_MODULE_PATH  ${CMAKE_MODULE_PATH}  ${vigra_SOURCE_DIR}/config)
+
+include(VigraSetDefaults)
+include(VigraCMakeUtils)
+
+INCLUDE_DIRECTORIES(${vigra_SOURCE_DIR}/include)
+
+IF(VIGRA_STATIC_LIB)
+    SET(LIBTYPE STATIC)
+    ADD_DEFINITIONS(-DVIGRA_STATIC_LIB)
+ELSE(VIGRA_STATIC_LIB)
+    SET(LIBTYPE SHARED)
+ENDIF(VIGRA_STATIC_LIB)
+
+IF (MSVC)
+    ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_DEPRECATE)
+ENDIF ()
+
+# if(CMAKE_COMPILER_IS_GNUCXX)
+  # exec_program(
+      # ${CMAKE_CXX_COMPILER}
+      # ARGS                    --version
+      # OUTPUT_VARIABLE _compiler_output)
+  # string(REGEX REPLACE ".*([0-9]\\.[0-9]\\.[0-9]).*" "\\1"  gcc_compiler_version ${_compiler_output})
+  # if(gcc_compiler_version VERSION_LESS "4.4.0")
+      # message(FATAL_ERROR "VIGRA requires at least gcc 4.4")
+  # else()
+      # message(STATUS "Using gcc ${gcc_compiler_version} [${CMAKE_CXX_COMPILER}]")
+  # endif()
+# endif()
+
+##################################################
+#
+#     search for dependencies
+#
+##################################################
+
+INCLUDE(VigraFindPackage)
+VIGRA_FIND_PACKAGE(TIFF NAMES libtiff)
+VIGRA_FIND_PACKAGE(JPEG NAMES libjpeg)
+VIGRA_FIND_PACKAGE(PNG)
+VIGRA_FIND_PACKAGE(FFTW3 NAMES libfftw3-3 libfftw-3.3)
+VIGRA_FIND_PACKAGE(FFTW3F NAMES libfftw3f-3 libfftwf-3.3)
+
+IF(WITH_OPENEXR)
+    VIGRA_FIND_PACKAGE(OpenEXR)
+ENDIF()
+
+IF(WITH_HDF5)
+    VIGRA_FIND_PACKAGE(HDF5)
+ENDIF()
+
+IF(WITH_BOOST_GRAPH)
+    IF(WITH_VIGRANUMPY)
+        VIGRA_FIND_PACKAGE( Boost 1.40.0 COMPONENTS python )
+    else()
+        VIGRA_FIND_PACKAGE( Boost 1.40.0 )
+    endif()
+ENDIF()
+
+IF(WITH_LEMON)
+    VIGRA_FIND_PACKAGE(LEMON)
+ENDIF()
+
+SET(DOXYGEN_SKIP_DOT TRUE)
+FIND_PACKAGE(Doxygen)
+FIND_PACKAGE(PythonInterp)
+
+IF(WITH_VIGRANUMPY)
+    FIND_PACKAGE( VIGRANUMPY_DEPENDENCIES )
+ENDIF()
+
+IF(WITH_VALGRIND)
+    FIND_PROGRAM(VALGRIND_EXECUTABLE valgrind)
+ENDIF()
+
+##################################################
+#
+#     setup testing environment
+#
+##################################################
+
+ADD_CUSTOM_TARGET(check)
+ADD_CUSTOM_TARGET(ctest COMMAND ${CMAKE_CTEST_COMMAND})
+
+ADD_CUSTOM_TARGET(check_cpp)
+ADD_DEPENDENCIES(check check_cpp)
+
+
+OPTION(CREATE_CTEST_TARGETS "Create special targets for CTest" OFF)
+IF(CREATE_CTEST_TARGETS)
+  INCLUDE(CTest)
+ENDIF()
+
+IF(WITH_VIGRANUMPY)
+    ADD_CUSTOM_TARGET(check_python)
+    ADD_DEPENDENCIES(check check_python)
+ENDIF()
+
+ENABLE_TESTING()
+
+##################################################
+#
+#     setup documentation generator
+#
+##################################################
+
+ADD_CUSTOM_TARGET(doc)
+
+# Automatically push the latest documentation to github's gh-pages.
+# This only works when ${DOCDIR} refers to a VIGRA repository that is 
+# checked out in branch 'gh-pages', and the present repository is 
+# in branch 'master' (these conditions are checked in the script).
+if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+
+    configure_file(${PROJECT_SOURCE_DIR}/config/update-gh-pages.sh.in 
+                   ${PROJECT_BINARY_DIR}/update-gh-pages.sh @ONLY)
+    EXECUTE_PROCESS(COMMAND chmod u+x ${PROJECT_BINARY_DIR}/update-gh-pages.sh OUTPUT_QUIET ERROR_QUIET)
+       
+    ADD_CUSTOM_TARGET(gh-pages 
+          ${PROJECT_BINARY_DIR}/update-gh-pages.sh
+          DEPENDS doc
+          WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+          COMMENT "Pushing documentation to github pages.")
+endif()
+
+##################################################
+#
+#     setup private experimentation target
+#
+##################################################
+
+ADD_CUSTOM_TARGET(experiments)
+
+##################################################
+#
+#     subdirectories
+#
+##################################################
+
+ADD_SUBDIRECTORY(src)
+ADD_SUBDIRECTORY(test)
+ADD_SUBDIRECTORY(docsrc)
+
+IF(WITH_VIGRANUMPY)
+    ADD_SUBDIRECTORY(vigranumpy)
+ENDIF()
+
+IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/private/CMakeLists.txt)
+    ADD_SUBDIRECTORY(private EXCLUDE_FROM_ALL)
+ENDIF()
+
+
+set(LIB_SUFFIX "" CACHE STRING "Define suffix of lib directory name (32/64)" )
+
+##################################################
+#
+#     global installation commands
+#
+##################################################
+
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/include/vigra
+        DESTINATION include)
+
+##################################################
+#
+#     enable CPack package generation
+#
+##################################################
+INCLUDE(CPackConfig)
+
+##################################################
+#
+#     add target vigra-$version-src.tar.gz
+#
+##################################################
+
+find_program(GIT_EXECUTABLE 
+              NAMES git git.exe git.cmd
+              HINTS $ENV{ProgramFiles}/Git/bin
+              DOC "git command line client")
+
+CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/config/package-src.cmake.in
+                ${PROJECT_BINARY_DIR}/package-src.cmake
+                @ONLY IMMEDIATE)
+
+add_custom_target(PACKAGE_SRC_TAR
+                   COMMAND ${CMAKE_COMMAND} -P package-src.cmake
+                   WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
+                   COMMENT "Creating ${PROJECT_BINARY_DIR}/vigra-${vigra_version}-src.tar.gz")        
+
+ADD_DEPENDENCIES(PACKAGE_SRC_TAR check)
+ADD_DEPENDENCIES(PACKAGE_SRC_TAR doc_cpp)
+IF(WITH_VIGRANUMPY AND PYTHON_SPHINX)
+    ADD_DEPENDENCIES(PACKAGE_SRC_TAR doc_python)
+ENDIF()
+
+##################################################
+#
+#  enable other non-CMake projects to find Vigra
+#
+##################################################
+
+IF(NOT WIN32)
+# vigra-config script for (non-CMake-based) third party packages
+CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/config/vigra-config.in
+        ${PROJECT_BINARY_DIR}/bin/vigra-config
+        @ONLY IMMEDIATE)
+INSTALL(FILES ${PROJECT_BINARY_DIR}/bin/vigra-config
+        DESTINATION bin
+        PERMISSIONS
+            OWNER_READ OWNER_WRITE OWNER_EXECUTE
+            GROUP_READ GROUP_EXECUTE
+            WORLD_READ WORLD_EXECUTE)
+ENDIF(NOT WIN32)
+
+##################################################
+#
+#     enable other CMake projects to find Vigra
+#
+##################################################
+
+# config file for CMake FIND_PACKAGE command (for using the build tree)
+CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/config/VigraConfigBuild.cmake.in
+        ${PROJECT_BINARY_DIR}/VigraConfig.cmake
+        @ONLY IMMEDIATE)
+CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/config/VigraConfigVersion.cmake.in
+        ${PROJECT_BINARY_DIR}/VigraConfigVersion.cmake
+        @ONLY IMMEDIATE)
+
+# config file for CMake FIND_PACKAGE command
+CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/config/VigraConfig.cmake.in
+        ${PROJECT_BINARY_DIR}/lib/vigra/CMake/VigraConfig.cmake
+        @ONLY IMMEDIATE)
+CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/config/VigraConfigVersion.cmake.in
+        ${PROJECT_BINARY_DIR}/lib/vigra/CMake/VigraConfigVersion.cmake
+        @ONLY IMMEDIATE)
+
+# export targets:
+INSTALL(EXPORT vigra-targets
+        DESTINATION lib${LIB_SUFFIX}/vigra)
+INSTALL(FILES ${PROJECT_BINARY_DIR}/lib/vigra/CMake/VigraConfig.cmake
+            ${PROJECT_BINARY_DIR}/lib/vigra/CMake/VigraConfigVersion.cmake
+        DESTINATION lib${LIB_SUFFIX}/vigra)
+EXPORT(TARGETS vigraimpex FILE vigra-targets.cmake)
+
+##################################################
+#
+#     status output
+#
+##################################################
+
+MESSAGE( STATUS "---------------------------------------------------------" )
+MESSAGE( STATUS "VIGRA configuration information:" )
+MESSAGE( STATUS "---------------------------------------------------------" )
+
+IF(TIFF_FOUND)
+    MESSAGE( STATUS "  Using TIFF libraries: ${TIFF_LIBRARIES}" )
+ELSE()
+    MESSAGE( STATUS "  TIFF libraries not found (TIFF support disabled)" )
+ENDIF()
+
+IF(JPEG_FOUND)
+    MESSAGE( STATUS "  Using JPEG libraries: ${JPEG_LIBRARIES}" )
+ELSE()
+    MESSAGE( STATUS "  JPEG libraries not found (JPEG support disabled)" )
+ENDIF()
+
+IF(PNG_FOUND)
+    MESSAGE( STATUS "  Using PNG  libraries: ${PNG_LIBRARIES}" )
+ELSE()
+    MESSAGE( STATUS "  PNG libraries not found (PNG support disabled)" )
+ENDIF()
+
+IF(OPENEXR_FOUND)
+    MESSAGE( STATUS "  Using OpenEXR  libraries: ${OPENEXR_LIBRARIES}" )
+ELSEIF(NOT WITH_OPENEXR)
+    MESSAGE( STATUS "  OpenEXR disabled by user (WITH_OPENEXR=0)" )
+ELSE()
+    MESSAGE( STATUS "  OpenEXR libraries not found (OpenEXR support disabled)" )
+ENDIF()
+
+IF(FFTW3_FOUND)
+    MESSAGE( STATUS "  Using FFTW libraries: ${FFTW3_LIBRARIES}" )
+ELSE()
+    MESSAGE( STATUS "  FFTW libraries not found (FFTW support disabled)" )
+ENDIF()
+
+IF(HDF5_FOUND)
+    MESSAGE( STATUS "  Using HDF5 libraries: ${HDF5_LIBRARIES}" )
+ELSEIF(NOT WITH_HDF5)
+    MESSAGE( STATUS "  HDF5 disabled by user (WITH_HDF5=0)" )
+ELSE()
+    MESSAGE( STATUS "  HDF5 libraries not found (HDF5 support disabled)" )
+ENDIF()
+
+IF(Boost_FOUND)
+    MESSAGE( STATUS "  Using Boost Graph Library: ${Boost_INCLUDE_DIR}/boost/graph" )
+ELSEIF(NOT WITH_BOOST_GRAPH)
+    MESSAGE( STATUS "  Boost Graph Library disabled by user (WITH_BOOST_GRAPH=0)" )
+ELSE()
+    MESSAGE( STATUS "  Boost Graph Library not found (support disabled)" )
+ENDIF()
+
+IF(LEMON_FOUND)
+    MESSAGE( STATUS "  Using LEMON graph library: ${LEMON_LIBRARY}" )
+ELSEIF(NOT WITH_LEMON)
+    MESSAGE( STATUS "  LEMON graph library disabled by user (WITH_LEMON=0)" )
+ELSE()
+    MESSAGE( STATUS "  LEMON graph library not found (support disabled)" )
+ENDIF()
+
+IF(WITH_VIGRANUMPY)
+    IF(VIGRANUMPY_DEPENDENCIES_FOUND)
+        MESSAGE( STATUS "  Using Python libraries: ${VIGRANUMPY_LIBRARIES}" )
+        MESSAGE( STATUS "  Using Numpy includes:   ${PYTHON_NUMPY_INCLUDE_DIR}" )
+    ELSE()
+        MESSAGE( STATUS "  Vigranumpy dependencies not found (vigranumpy disabled)" )
+    ENDIF()
+ELSE()
+  MESSAGE( STATUS "  Vigranumpy disabled by user (WITH_VIGRANUMPY=0)" )
+ENDIF()
+
+MESSAGE( STATUS "---------------------------------------------------------" )
+
+IF(VIGRA_STATIC_LIB)
+    MESSAGE( STATUS "  building static lib" )
+ELSE()
+    MESSAGE( STATUS "  building shared lib" )
+ENDIF()
+
+MESSAGE( STATUS "  binaries will be generated in: ${CMAKE_CURRENT_BINARY_DIR}")
+IF(DOXYGEN_FOUND AND PYTHONINTERP_FOUND)
+    MESSAGE( STATUS "  manuals will be generated in: ${DOCDIR}")
+ENDIF()
+
+MESSAGE( STATUS "---------------------------------------------------------" )
+
+MESSAGE( STATUS "  includes will be installed at: ${CMAKE_INSTALL_PREFIX}/include")
+MESSAGE( STATUS "  libraries will be installed at: ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
+
+IF (MSVC)
+  MESSAGE( STATUS "  binaries and DLLs will be installed at: ${CMAKE_INSTALL_PREFIX}/bin")
+else()
+  MESSAGE( STATUS "  binaries will be installed at: ${CMAKE_INSTALL_PREFIX}/bin")
+endif()
+
+IF(DOXYGEN_FOUND AND PYTHONINTERP_FOUND)
+  MESSAGE( STATUS "  vigra manuals will be installed at: "
+    "${CMAKE_INSTALL_PREFIX}/${DOCINSTALL}/vigra/index.html")
+ELSE()
+  MESSAGE( STATUS "  vigra manuals cannot be generated (Doxygen or Python not found)")
+ENDIF()
+
+IF(WITH_VIGRANUMPY AND VIGRANUMPY_DEPENDENCIES_FOUND)
+  MESSAGE( STATUS "  vigranumpy will be installed at ${CMAKE_INSTALL_PREFIX}/${VIGRANUMPY_INSTALL_DIR}" )
+  IF(PYTHON_SPHINX)
+    MESSAGE( STATUS "  vigranumpy manuals will be installed at: "
+      "${CMAKE_INSTALL_PREFIX}/${DOCINSTALL}/vigranumpy/html/index.html")
+  ELSE(PYTHON_SPHINX)
+    MESSAGE( STATUS "  vigranumpy manuals cannot be generated "
+      "(Sphinx missing)")
+  ENDIF(PYTHON_SPHINX)
+ELSE()
+  MESSAGE( STATUS "  vigranumpy will NOT be installed" )
+ENDIF()
+
+IF(NOT TIFF_FOUND OR NOT JPEG_FOUND OR NOT PNG_FOUND OR NOT FFTW3_FOUND OR
+   NOT HDF5_FOUND OR NOT VIGRANUMPY_DEPENDENCIES_FOUND)
+  MESSAGE( STATUS "" )
+  MESSAGE( STATUS "Consider setting DEPENDENCY_SEARCH_PREFIX to find missing libraries" )
+ENDIF()
+
+MESSAGE( STATUS "---------------------------------------------------------" )
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..10c26ab
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,25 @@
+The VIGRA License
+=================
+(identical to the MIT X11 License)
+
+Permission is hereby granted, free of charge, to any person    
+obtaining a copy of this software and associated documentation 
+files (the "Software"), to deal in the Software without        
+restriction, including without limitation the rights to use,   
+copy, modify, merge, publish, distribute, sublicense, and/or   
+sell copies of the Software, and to permit persons to whom the 
+Software is furnished to do so, subject to the following       
+conditions:                                                    
+                                                               
+The above copyright notice and this permission notice shall be 
+included in all copies or substantial portions of the          
+Software.                                                      
+                                                               
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND 
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND       
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,   
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING   
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR  
+OTHER DEALINGS IN THE SOFTWARE.                               
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5bcff8b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,58 @@
+VIGRA Computer Vision Library
+=============================
+
+[![Build Status](https://travis-ci.org/ukoethe/vigra.png?branch=master)](https://travis-ci.org/ukoethe/vigra)
+
+                Copyright 1998-2013 by Ullrich Koethe
+
+    This file is part of the VIGRA computer vision library.
+    You may use, modify, and distribute this software according
+    to the terms stated in the LICENSE.txt file included in
+    the VIGRA distribution.
+
+    The VIGRA Website is
+        http://hci.iwr.uni-heidelberg.de/vigra/                       
+    Please direct questions, bug reports, and contributions to        
+        ullrich.koethe at iwr.uni-heidelberg.de    or                    
+        vigra at informatik.uni-hamburg.de                               
+
+
+    THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR
+    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+    WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+Installation
+------------
+
+Installation instructions can be found in the file 
+  $VIGRA_PATH/doc/vigra/Installation.html
+If the documentation has not yet been generated (e.g. when you build from a development 
+snapshot), you find these instructions in
+  $VIGRA_PATH/docsrc/installation.dxx
+or online at
+  http://hci.iwr.uni-heidelberg.de/vigra/doc/vigra/Installation.html
+
+Documentation
+-------------
+
+If you downloaded an official release, the documentation can be found in $VIGRA_PATH/doc/vigra/, the start file 
+is $VIGRA_PATH/doc/vigra/index.html. Online documentation for the latest release is at 
+http://hci.iwr.uni-heidelberg.de/vigra/doc/vigra/index.html
+
+When you use the development version from github, you can generate documentation by `make doc`. Up-to-date 
+online documentation for the 'master' branch is at http://ukoethe.github.io/vigra/doc/vigra/index.html
+
+Download
+--------
+
+VIGRA can be downloaded at http://hci.iwr.uni-heidelberg.de/vigra/#download The official development 
+repository is at https://github.com/ukoethe/vigra
+
+What is VIGRA
+-------------
+
+VIGRA is a computer vision library that puts its main emphasis on flexible algorithms, because algorithms represent the principle know-how of this field. The library was consequently built using generic programming as introduced by Stepanov and Musser and exemplified in the C++ Standard Template Library. By writing a few adapters (image iterators and accessors) you can use VIGRA's algorithms on top of your data structures, within your environment. Alternatively, you can also use the data [...]
+
+
+
diff --git a/config/CPackConfig.cmake b/config/CPackConfig.cmake
new file mode 100644
index 0000000..e96c234
--- /dev/null
+++ b/config/CPackConfig.cmake
@@ -0,0 +1,21 @@
+# general information
+SET(CPACK_PACKAGE_VENDOR "Heidelberg Collaboratory for Image Processing")
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
+    "C++ computer vision library with emphasis on customizable algorithms and data structures"
+)
+
+# package version setup
+SET(CPACK_PACKAGE_VERSION_MAJOR "${VIGRA_VERSION_MAJOR}")
+SET(CPACK_PACKAGE_VERSION_MINOR "${VIGRA_VERSION_MINOR}")
+SET(CPACK_PACKAGE_VERSION_PATCH "${VIGRA_VERSION_PATCH}")
+
+SET(CPACK_PACKAGE_INSTALL_DIRECTORY     "${PROJECT_NAME}")
+SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY  "${PROJECT_NAME}")
+SET(CPACK_RESOURCE_FILE_LICENSE         "${PROJECT_SOURCE_DIR}/LICENSE.txt")
+SET(CPACK_RESOURCE_FILE_README          "${PROJECT_SOURCE_DIR}/README.md")
+SET(CPACK_STRIP_FILES TRUE)
+SET(CPACK_SOURCE_IGNORE_FILES "${PROJECT_SOURCE_DIR}/.hg" ".#" "#.*~")
+SET(CPACK_PACKAGE_CONTACT "Ullrich Koethe <ullrich.koethe at iwr.uni-heidelberg.de>")
+SET(CPACK_DEBIAN_PACKAGE_DEPENDS "")
+
+INCLUDE (CPack)
diff --git a/config/CTestConfig.cmake.template b/config/CTestConfig.cmake.template
new file mode 100644
index 0000000..91e5b8f
--- /dev/null
+++ b/config/CTestConfig.cmake.template
@@ -0,0 +1,12 @@
+set(CTEST_PROJECT_NAME "Vigra")
+set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
+
+
+set(CTEST_DROP_METHOD "http")
+
+set(CTEST_DROP_SITE "hci.iwr.uni-heidelberg.de")
+set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Vigra")
+set(CTEST_DROP_SITE_CDASH TRUE)
+
+
+SET(MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes")
diff --git a/config/FindFFTW3.cmake b/config/FindFFTW3.cmake
new file mode 100644
index 0000000..2dd64b7
--- /dev/null
+++ b/config/FindFFTW3.cmake
@@ -0,0 +1,28 @@
+# - Find FFTW3
+# Find the native FFTW3 includes and library
+# This module defines
+#  FFTW3_INCLUDE_DIR, where to find FFTW3lib.h, etc.
+#  FFTW3_LIBRARIES, the libraries needed to use FFTW3.
+#  JFFTW3_FOUND, If false, do not try to use FFTW3.
+# also defined, but not for general use are
+#  FFTW3_LIBRARY, where to find the FFTW3 library.
+
+FIND_PATH(FFTW3_INCLUDE_DIR fftw3.h)
+
+SET(FFTW3_NAMES ${FFTW3_NAMES} fftw3)
+FIND_LIBRARY(FFTW3_LIBRARY NAMES ${FFTW3_NAMES} )
+
+# handle the QUIETLY and REQUIRED arguments and set FFTW3_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(FFTW3 DEFAULT_MSG FFTW3_LIBRARY FFTW3_INCLUDE_DIR)
+
+IF(FFTW3_FOUND)
+  SET(FFTW3_LIBRARIES ${FFTW3_LIBRARY})
+ENDIF(FFTW3_FOUND)
+
+# Deprecated declarations.
+SET (NATIVE_FFTW3_INCLUDE_PATH ${FFTW3_INCLUDE_DIR} )
+IF(FFTW3_LIBRARY)
+  GET_FILENAME_COMPONENT (NATIVE_FFTW3_LIB_PATH ${FFTW3_LIBRARY} PATH)
+ENDIF(FFTW3_LIBRARY)
diff --git a/config/FindFFTW3F.cmake b/config/FindFFTW3F.cmake
new file mode 100644
index 0000000..040d71d
--- /dev/null
+++ b/config/FindFFTW3F.cmake
@@ -0,0 +1,28 @@
+# - Find FFTW3F
+# Find the single-precision FFTW3 includes and library
+# This module defines
+#  FFTW3F_INCLUDE_DIR, where to find fftw3.h, etc.
+#  FFTW3F_LIBRARIES, the libraries needed to use single-precision FFTW3.
+#  JFFTW3_FOUND, If false, do not try to use FFTW3.
+# also defined, but not for general use are
+#  FFTW3F_LIBRARY, where to find the single-precision FFTW3 library.
+
+FIND_PATH(FFTW3F_INCLUDE_DIR fftw3.h)
+
+SET(FFTW3F_NAMES ${FFTW3F_NAMES} fftw3f)
+FIND_LIBRARY(FFTW3F_LIBRARY NAMES ${FFTW3F_NAMES} )
+
+# handle the QUIETLY and REQUIRED arguments and set FFTW3F_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(FFTW3F DEFAULT_MSG FFTW3F_LIBRARY FFTW3F_INCLUDE_DIR)
+
+IF(FFTW3F_FOUND)
+  SET(FFTW3F_LIBRARIES ${FFTW3F_LIBRARY})
+ENDIF(FFTW3F_FOUND)
+
+# Deprecated declarations.
+SET (NATIVE_FFTW3F_INCLUDE_PATH ${FFTW3F_INCLUDE_DIR} )
+IF(FFTW3F_LIBRARY)
+  GET_FILENAME_COMPONENT (NATIVE_FFTW3F_LIB_PATH ${FFTW3F_LIBRARY} PATH)
+ENDIF(FFTW3F_LIBRARY)
diff --git a/config/FindHDF5.cmake b/config/FindHDF5.cmake
new file mode 100644
index 0000000..e6b06e2
--- /dev/null
+++ b/config/FindHDF5.cmake
@@ -0,0 +1,81 @@
+# - Find HDF5, a library for reading and writing self describing array data.
+#
+FIND_PATH(HDF5_INCLUDE_DIR hdf5.h)
+
+if(HDF5_INCLUDE_DIR)
+    SET(HDF5_TRY_COMPILE_INCLUDE_DIR "-DINCLUDE_DIRECTORIES:STRING=${HDF5_INCLUDE_DIR}")
+
+    FIND_LIBRARY(HDF5_CORE_LIBRARY NAMES hdf5dll hdf5  )
+    FIND_LIBRARY(HDF5_HL_LIBRARY NAMES hdf5_hldll hdf5_hl  )
+
+    # FIXME: as of version 1.8.9 and 1.8.10-patch1 (but NOT 1.8.10), these flags are
+    #        already set correctly => remove or set conditionally according to version
+    IF(WIN32 AND HDF5_CORE_LIBRARY MATCHES "dll.lib$")
+        SET(HDF5_CFLAGS "-D_HDF5USEDLL_")
+        SET(HDF5_CPPFLAGS "-D_HDF5USEDLL_ -DHDF5CPP_USEDLL")
+    ELSE()
+        SET(HDF5_CFLAGS)
+        SET(HDF5_CPPFLAGS)
+    ENDIF()
+
+    SET(HDF5_VERSION_MAJOR 1)
+    SET(HDF5_VERSION_MINOR 8)
+
+    set(HDF5_SUFFICIENT_VERSION FALSE)
+    TRY_COMPILE(HDF5_SUFFICIENT_VERSION 
+                ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/config/checkHDF5version.c
+                COMPILE_DEFINITIONS "-DMIN_MAJOR=${HDF5_VERSION_MAJOR} -DMIN_MINOR=${HDF5_VERSION_MINOR}"
+                CMAKE_FLAGS "${HDF5_TRY_COMPILE_INCLUDE_DIR}") 
+            
+    if(HDF5_SUFFICIENT_VERSION)
+        MESSAGE(STATUS 
+               "Checking HDF5 version (at least ${HDF5_VERSION_MAJOR}.${HDF5_VERSION_MINOR}): ok")
+    else()
+        MESSAGE( STATUS "HDF5: need at least version ${HDF5_VERSION_MAJOR}.${HDF5_VERSION_MINOR}" )
+    endif()
+
+    set(HDF5_USES_ZLIB FALSE)
+    TRY_COMPILE(HDF5_USES_ZLIB
+               ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/config/checkHDF5usesCompression.c
+               COMPILE_DEFINITIONS "-DH5_SOMETHING=H5_HAVE_FILTER_DEFLATE"
+               CMAKE_FLAGS "${HDF5_TRY_COMPILE_INCLUDE_DIR}") 
+
+    if(HDF5_USES_ZLIB)
+        FIND_LIBRARY(HDF5_Z_LIBRARY NAMES zlib1 zlib z )
+        set(HDF5_ZLIB_OK ${HDF5_Z_LIBRARY})
+    else()
+        set(HDF5_ZLIB_OK TRUE)
+        set(HDF5_Z_LIBRARY "")
+    endif()
+
+    set(HDF5_USES_SZLIB FALSE)
+    TRY_COMPILE(HDF5_USES_SZLIB 
+                ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/config/checkHDF5usesCompression.c
+                COMPILE_DEFINITIONS "-DH5_SOMETHING=H5_HAVE_FILTER_SZIP"
+                CMAKE_FLAGS "${HDF5_TRY_COMPILE_INCLUDE_DIR}") 
+            
+    if(HDF5_USES_SZLIB)
+        FIND_LIBRARY(HDF5_SZ_LIBRARY NAMES szlibdll sz szip)
+        set(HDF5_SZLIB_OK ${HDF5_SZ_LIBRARY})
+    else()
+        set(HDF5_SZLIB_OK TRUE)
+        set(HDF5_SZ_LIBRARY "")
+    endif()
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set HDF5_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(HDF5 DEFAULT_MSG HDF5_CORE_LIBRARY 
+        HDF5_HL_LIBRARY HDF5_ZLIB_OK HDF5_SZLIB_OK HDF5_INCLUDE_DIR HDF5_SUFFICIENT_VERSION)
+        
+IF(HDF5_FOUND)
+    SET(HDF5_LIBRARIES ${HDF5_CORE_LIBRARY} ${HDF5_HL_LIBRARY} ${HDF5_Z_LIBRARY} ${HDF5_SZ_LIBRARY})
+ELSE()
+    SET(HDF5_CORE_LIBRARY HDF5_CORE_LIBRARY-NOTFOUND)
+    SET(HDF5_HL_LIBRARY   HDF5_HL_LIBRARY-NOTFOUND)
+    SET(HDF5_Z_LIBRARY    HDF5_Z_LIBRARY-NOTFOUND)
+    SET(HDF5_SZ_LIBRARY   HDF5_SZ_LIBRARY-NOTFOUND)
+ENDIF(HDF5_FOUND)
+    
diff --git a/config/FindOpenEXR.cmake b/config/FindOpenEXR.cmake
new file mode 100644
index 0000000..1e405b5
--- /dev/null
+++ b/config/FindOpenEXR.cmake
@@ -0,0 +1,44 @@
+# Copyright (c) 2011, Lukas Jirkovsky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the <organization> nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+FIND_PATH(OPENEXR_INCLUDE_DIR ImfRgbaFile.h PATH_SUFFIXES OpenEXR)
+
+FIND_LIBRARY(OPENEXR_ILMIMF_LIBRARY NAMES IlmImf)
+FIND_LIBRARY(OPENEXR_IMATH_LIBRARY NAMES Imath)
+FIND_LIBRARY(OPENEXR_HALF_LIBRARY NAMES Half)
+FIND_LIBRARY(OPENEXR_IEX_LIBRARY NAMES Iex)
+FIND_LIBRARY(OPENEXR_ILMTHREAD_LIBRARY NAMES IlmThread)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENEXR DEFAULT_MSG
+    OPENEXR_HALF_LIBRARY OPENEXR_IEX_LIBRARY OPENEXR_IMATH_LIBRARY
+    OPENEXR_ILMIMF_LIBRARY OPENEXR_INCLUDE_DIR
+)
+
+IF(OPENEXR_FOUND)
+    SET(OPENEXR_LIBRARIES ${OPENEXR_ILMIMF_LIBRARY}
+        ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_HALF_LIBRARY}
+        ${OPENEXR_IEX_LIBRARY} ${OPENEXR_ILMTHREAD_LIBRARY} )
+ENDIF(OPENEXR_FOUND)
diff --git a/config/FindVIGRANUMPY_DEPENDENCIES.cmake b/config/FindVIGRANUMPY_DEPENDENCIES.cmake
new file mode 100644
index 0000000..9e52a38
--- /dev/null
+++ b/config/FindVIGRANUMPY_DEPENDENCIES.cmake
@@ -0,0 +1,174 @@
+# - Find VIGRANUMPY_DEPENDENCIES
+#
+MESSAGE(STATUS "Checking VIGRANUMPY_DEPENDENCIES")
+
+FIND_PACKAGE(PythonInterp)
+
+IF(PYTHONINTERP_FOUND)
+    # check that Python version 2.x is used
+    execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
+                         "import sys; print sys.version[0]"
+                          OUTPUT_VARIABLE PYTHON_MAJOR_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
+    IF(${PYTHON_MAJOR_VERSION} EQUAL 2)
+        SET(PYTHONINTERP_V2_FOUND 1)
+    ELSE()
+        MESSAGE(STATUS "vigranumpy currently requires Python 2.x.")
+        MESSAGE(STATUS "Make sure that Python 2 is in your PATH or use 'cmake_gui' to set the PYTHON_EXECUTABLE variable manually.")
+        SET(PYTHONINTERP_V2_FOUND 0)
+    ENDIF()
+ELSE()
+    SET(PYTHONINTERP_V2_FOUND 0)
+ENDIF()
+
+IF(PYTHONINTERP_V2_FOUND)
+
+#    this command cannot be used because its results are often inconsistent
+#    with the Python interpreter found previously (e.g. libraries or includes
+#    from incompatible installations)
+#    FIND_PACKAGE(PythonLibs)
+
+    # find Python library
+    execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
+                     "import sys; print sys.exec_prefix"
+                      OUTPUT_VARIABLE PYTHON_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+    IF(APPLE AND ${PYTHON_PREFIX} MATCHES ".*framework.*")
+        SET(PYTHON_LIBRARIES "${PYTHON_PREFIX}/Python"
+            CACHE FILEPATH "Python libraries"
+            FORCE)
+    ELSE()
+        execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
+                         "import sys; skip = 2 if sys.platform.startswith('win') else 1; print 'python' + sys.version[0:3:skip]"
+                          OUTPUT_VARIABLE PYTHON_LIBRARY_NAME OUTPUT_STRIP_TRAILING_WHITESPACE)
+        FIND_LIBRARY(PYTHON_LIBRARIES ${PYTHON_LIBRARY_NAME} HINTS "${PYTHON_PREFIX}" 
+                     PATH_SUFFIXES lib lib64 libs DOC "Python libraries")
+    ENDIF()
+
+    # find Python includes
+    execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
+                    "from distutils.sysconfig import *; print get_python_inc()"
+                    OUTPUT_VARIABLE PYTHON_INCLUDE OUTPUT_STRIP_TRAILING_WHITESPACE)
+    SET(PYTHON_INCLUDE_PATH ${PYTHON_INCLUDE}
+        CACHE PATH "Path to Python include files"
+        FORCE)
+
+    IF(PYTHON_LIBRARIES AND PYTHON_INCLUDE_PATH)
+        MESSAGE(STATUS "Found Python libraries: ${PYTHON_LIBRARIES}")
+        MESSAGE(STATUS "Found Python includes:  ${PYTHON_INCLUDE_PATH}")
+        SET(PYTHONLIBS_FOUND TRUE)
+    ELSE()
+        MESSAGE(STATUS "Could NOT find Python libraries and/or includes")
+    ENDIF()
+
+    VIGRA_FIND_PACKAGE( Boost 1.40.0 COMPONENTS python )
+
+    ######################################################################
+    #
+    #      find default install directory for Python modules
+    #      (usually PYTHONDIR/Lib/site-packages)
+    #
+    ######################################################################
+    IF(NOT DEFINED VIGRANUMPY_INSTALL_DIR OR VIGRANUMPY_INSTALL_DIR MATCHES "^$")
+        execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
+                         "from distutils.sysconfig import *; print get_python_lib(1)"
+                          OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
+        FILE(TO_CMAKE_PATH ${PYTHON_SITE_PACKAGES} VIGRANUMPY_INSTALL_DIR)
+    ENDIF()
+    SET(VIGRANUMPY_INSTALL_DIR ${VIGRANUMPY_INSTALL_DIR}
+        CACHE PATH "where to install the VIGRA Python package" FORCE)
+    # this is the install path relative to CMAKE_INSTALL_PREFIX,
+    # use this in INSTALL() commands to get packaging right
+    FILE(RELATIVE_PATH VIGRANUMPY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX} ${VIGRANUMPY_INSTALL_DIR})
+
+    ######################################################################
+    #
+    #      find numpy include directory
+    #      (usually below PYTHONDIR/Lib/site-packages/numpy)
+    #
+    ######################################################################
+    IF(NOT PYTHON_NUMPY_INCLUDE_DIR)
+        # Note: we must suppress possible output of the 'from numpy... import *' command,
+        #       because the output cannot be interpreted correctly otherwise
+        execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
+                         "import sys, os; sys.stdout = open(os.devnull, 'w'); from numpy.distutils.misc_util import *; sys.__stdout__.write(' '.join(get_numpy_include_dirs()))"
+                          RESULT_VARIABLE PYTHON_NUMPY_NOT_FOUND
+                          OUTPUT_VARIABLE PYTHON_NUMPY_INCLUDE_DIR
+                          OUTPUT_STRIP_TRAILING_WHITESPACE)
+        IF(NOT PYTHON_NUMPY_NOT_FOUND)
+            FILE(TO_CMAKE_PATH ${PYTHON_NUMPY_INCLUDE_DIR} PYTHON_NUMPY_INCLUDE_DIR)
+        ELSE()
+            SET(PYTHON_NUMPY_INCLUDE_DIR "PYTHON_NUMPY_INCLUDE_DIR-NOTFOUND")
+        ENDIF()
+    ENDIF()
+
+    SET(PYTHON_NUMPY_INCLUDE_DIR ${PYTHON_NUMPY_INCLUDE_DIR}
+        CACHE PATH "Path to numpy include files" FORCE)
+    IF(PYTHON_NUMPY_INCLUDE_DIR)
+        MESSAGE(STATUS "Searching for Python numpy: ok")
+    ELSE()
+        MESSAGE(STATUS "Could NOT find Python numpy ('import numpy.distutils.misc_util' failed)")
+    ENDIF()
+
+    ######################################################################
+    #
+    #      check if nosetests are installed
+    #
+    ######################################################################
+    execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
+                     "import nose"
+                      RESULT_VARIABLE PYTHON_NOSETESTS_NOT_FOUND)
+
+    IF(NOT PYTHON_NOSETESTS_NOT_FOUND)
+        MESSAGE(STATUS "Searching for Python nosetests: ok")
+    ELSE()
+        MESSAGE(STATUS "Could NOT find Python nosetests ('import nose' failed)")
+    ENDIF()
+
+    ######################################################################
+    #
+    #      check if sphinx documentation generator is installed
+    #
+    ######################################################################
+    find_program(PYTHON_SPHINX sphinx-build "${PYTHON_PREFIX}/Scripts")
+
+    IF(NOT PYTHON_SPHINX)
+        MESSAGE(STATUS "Could NOT find sphinx documentation generator")
+    ELSE()
+        MESSAGE(STATUS "Searching for sphinx documentation generator: ok")
+    ENDIF()
+
+    ######################################################################
+    #
+    #      find Python platform
+    #
+    ######################################################################
+    execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
+                     "import sys; p = sys.platform; print 'windows' if p.startswith('win') else p"
+                      OUTPUT_VARIABLE PYTHON_PLATFORM OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+    ######################################################################
+    #
+    #      set outputs
+    #
+    ######################################################################
+    INCLUDE(FindPackageHandleStandardArgs)
+    FIND_PACKAGE_HANDLE_STANDARD_ARGS(VIGRANUMPY_DEPENDENCIES DEFAULT_MSG
+                         PYTHONINTERP_V2_FOUND PYTHONLIBS_FOUND
+                         Boost_PYTHON_FOUND PYTHON_NUMPY_INCLUDE_DIR VIGRANUMPY_INSTALL_DIR)
+
+    IF(NOT VIGRANUMPY_INCLUDE_DIRS OR VIGRANUMPY_INCLUDE_DIRS MATCHES "-NOTFOUND")
+        #note that the numpy include dir is set _before_ the python include dir, such that
+        #installing a more recent version of numpy on top of an existing python installation
+        #works (otherwise, numpy includes are picked up from ${PYTHON_INCLUDE_PATH}/numpy )
+        SET(VIGRANUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_INCLUDE_DIR} ${PYTHON_INCLUDE_PATH} ${Boost_INCLUDE_DIR})
+    ENDIF()
+    SET(VIGRANUMPY_INCLUDE_DIRS ${VIGRANUMPY_INCLUDE_DIRS}
+        CACHE PATH "include directories needed by VIGRA Python bindings"
+        FORCE)
+    IF(NOT VIGRANUMPY_LIBRARIES OR VIGRANUMPY_LIBRARIES MATCHES "-NOTFOUND")
+        SET(VIGRANUMPY_LIBRARIES ${PYTHON_LIBRARIES} ${Boost_PYTHON_LIBRARY})
+    ENDIF()
+    SET(VIGRANUMPY_LIBRARIES ${VIGRANUMPY_LIBRARIES}
+        CACHE FILEPATH "libraries needed by VIGRA Python bindings"
+        FORCE)
+ENDIF()
diff --git a/config/VIGRA_ADD_NUMPY_MODULE.cmake b/config/VIGRA_ADD_NUMPY_MODULE.cmake
new file mode 100644
index 0000000..d56f74b
--- /dev/null
+++ b/config/VIGRA_ADD_NUMPY_MODULE.cmake
@@ -0,0 +1,107 @@
+###################################################################
+#
+# VIGRA_ADD_NUMPY_MODULE: setup a module dependening on vigranumpy
+#
+# VIGRA_ADD_NUMPY_MODULE(modulename [SOURCES] source1.cpp, source2.cpp ...
+#                                   [LIBRARIES dependency1 dependency2 ...]
+#                                   [VIGANUMPY])
+#
+#        'modulename' is the module name to be used within Python (e.g. 'import modulename'). 
+#        Unless 'VIGRANUMPY' is specified (see below), it is also the cmake target name.
+#
+#        SOURCE are the C++ sources of the module, LIBRARIES the necessary libraries. 
+#        Dependency syntax must conform to the requirements of the cmake command
+#        TARGET_LINK_LIBRARIES. Modules are automatically linked against vigranumpycore
+#        and its dependencies (libpython, boost_python), so it is not necessary to state 
+#        this dependency explicitly.
+#   
+#        If VIGRANUMPY is given, the module is considered part of 'vigranumpy' and will
+#        be compiled and installed along with the other vigranumpy modules (otherwise,
+#        no installation target will be defined). The cmake target name becomes 
+#        'vigranumpy_modulename' in order to get useful alphabetic sorting of 
+#        targets in project files.
+FUNCTION(VIGRA_ADD_NUMPY_MODULE target)
+    
+    # parse the args
+    set(v SOURCES)
+    set(PART_OF_VIGRANUMPY 0)
+    foreach(i ${ARGN})
+        if(${i} MATCHES "^SOURCES$")
+            set(v SOURCES)
+        elseif(${i} MATCHES "^LIBRARIES$")
+            set(v LIBRARIES)
+        elseif(${i} MATCHES "^VIGRANUMPY$")
+            set(PART_OF_VIGRANUMPY 1)
+        else()
+            set(${v} ${${v}} ${i})
+        endif()
+    endforeach(i)
+    
+    IF(PART_OF_VIGRANUMPY)
+        set(TARGET_NAME vigranumpy_${target})
+        if(target MATCHES "^core$")
+            set(LIBRARY_NAME vigranumpycore)
+        else()
+            set(LIBRARY_NAME ${target})
+        endif()
+    ELSE()
+        set(TARGET_NAME ${target})
+        set(LIBRARY_NAME ${target})
+    ENDIF()
+
+    ADD_LIBRARY(${TARGET_NAME} SHARED ${SOURCES})    
+    
+    IF(PART_OF_VIGRANUMPY)
+        ADD_DEPENDENCIES(vigranumpy ${TARGET_NAME})
+        
+        # Store dependencies as a custom target property, so that we can 
+        # later query them.
+        # TODO: Does cmake provide a standard way to query the dependencies? 
+        GET_TARGET_PROPERTY(VIGRANUMPY_DEPENDS vigranumpy VIGRA_DEPENDS)
+        IF(NOT VIGRANUMPY_DEPENDS)
+            set(VIGRANUMPY_DEPENDS "")
+        ENDIF()
+        SET_TARGET_PROPERTIES(vigranumpy PROPERTIES VIGRA_DEPENDS "${VIGRANUMPY_DEPENDS} ${TARGET_NAME}")
+    ENDIF()
+    
+    if(DEFINED LIBRARIES)
+        TARGET_LINK_LIBRARIES(${TARGET_NAME} ${LIBRARIES})
+    endif()
+    
+    # if(LIBRARY_NAME MATCHES "^vigranumpycore$")
+        # TARGET_LINK_LIBRARIES(${TARGET_NAME} ${VIGRANUMPY_LIBRARIES})
+    # else()
+        # TARGET_LINK_LIBRARIES(${TARGET_NAME} ${VIGRANUMPY_LIBRARIES} vigranumpy_core)
+    # endif()
+    
+    TARGET_LINK_LIBRARIES(${TARGET_NAME} ${VIGRANUMPY_LIBRARIES})
+    
+    IF(PYTHON_PLATFORM MATCHES "^windows$")
+        SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${LIBRARY_NAME}" 
+                                                           PREFIX "" SUFFIX  ".pyd")
+    ELSEIF(MACOSX)
+        SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${LIBRARY_NAME}" PREFIX "" 
+                              SUFFIX ".so" INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${VIGRANUMPY_INSTALL_DIR}/vigra") 
+    ELSE()
+        SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${LIBRARY_NAME}" 
+                                                           PREFIX "")
+    ENDIF()
+    
+    IF(PART_OF_VIGRANUMPY)
+        IF(PYTHON_PLATFORM MATCHES "^windows$")
+            INSTALL(TARGETS ${TARGET_NAME} RUNTIME DESTINATION ${VIGRANUMPY_INSTALL_DIR}/vigra)
+        ELSE()
+            INSTALL(TARGETS ${TARGET_NAME}
+                    LIBRARY DESTINATION ${VIGRANUMPY_INSTALL_DIR}/vigra)
+        ENDIF()
+        
+        # create a temporary vigranumpy installation in ${vigranumpy_tmp_dir}
+        # (required for testing and documentation generation)
+        GET_TARGET_PROPERTY(loc ${TARGET_NAME} LOCATION)
+        ADD_CUSTOM_COMMAND(
+            TARGET ${TARGET_NAME}
+            POST_BUILD
+            COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${loc} ${vigranumpy_tmp_dir}/
+            COMMENT "Copying module to temporary module directory")
+    ENDIF()
+ENDFUNCTION(VIGRA_ADD_NUMPY_MODULE)
diff --git a/config/VigraAddTest.cmake b/config/VigraAddTest.cmake
new file mode 100644
index 0000000..eedbe35
--- /dev/null
+++ b/config/VigraAddTest.cmake
@@ -0,0 +1,141 @@
+# Enhanced version of ADD_TEST
+#
+# Usage of this module:
+#
+#     VIGRA_ADD_TEST(target [[SOURCES] source1 source2 ...] [LIBRARIES lib1 lib2 ...])
+#     VIGRA_COPY_TEST_DATA(datafile1 datafile2 ...)
+#
+# The function VIGRA_ADD_TEST
+# * creates a new executable for 'target', using the given sources and libraries
+# * makes the global target 'test' depend on the new 'target' (target 'test' must already exist)
+# * installs a post-build event that runs the test automatically after linking
+#
+# The function VIGRA_COPY_TEST_DATA copies the given files from the current source directory
+# to the corresponding binary directory.
+#
+MACRO(VIGRA_NATIVE_PATH out in)
+    file(TO_CMAKE_PATH "${in}" ${out})
+    IF(NOT CMAKE_CFG_INTDIR STREQUAL ".")
+        STRING(REGEX REPLACE "\\$\\([^\\)]*\\)" "%CONFIGURATION%" ${out} "${${out}}")
+    ENDIF()
+    IF(MINGW)
+        STRING(REGEX REPLACE "/" "\\\\" ${out} "${${out}}")
+    ELSE()
+        file(TO_NATIVE_PATH "${${out}}" ${out})
+    ENDIF()
+ENDMACRO(VIGRA_NATIVE_PATH)
+
+FUNCTION(VIGRA_ADD_TEST target)
+    # parse the args
+    set(v SOURCES)
+    foreach(i ${ARGN})
+        if(${i} MATCHES "^SOURCES$")
+            set(v SOURCES)
+        elseif(${i} MATCHES "^LIBRARIES$")
+            set(v LIBRARIES)
+        else()
+            set(${v} ${${v}} ${i})
+        endif()
+    endforeach(i)
+    
+    FILE(GLOB TESTSUCCESS_FOUND ${CMAKE_CURRENT_BINARY_DIR}/testsuccess.cxx)
+    IF(NOT TESTSUCCESS_FOUND)
+        FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/testsuccess.cxx 
+         "// auto-generated dummy file to force re-execution of failed tests
+")
+    ENDIF()
+    SET(SOURCES ${SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/testsuccess.cxx)
+    
+    # configure the target 
+    IF(AUTOBUILD_TESTS)
+        ADD_EXECUTABLE(${target} ${SOURCES})
+    ELSE()
+        ADD_EXECUTABLE(${target} EXCLUDE_FROM_ALL ${SOURCES})
+    ENDIF()
+    
+    ADD_DEPENDENCIES(check_cpp ${target})
+    ADD_DEPENDENCIES(ctest ${target})
+    if(DEFINED LIBRARIES)
+        TARGET_LINK_LIBRARIES(${target} ${LIBRARIES})
+    endif()
+    
+    # find the test executable
+    GET_TARGET_PROPERTY(${target}_executable ${target} LOCATION)
+    VIGRA_NATIVE_PATH(VIGRA_TEST_EXECUTABLE ${${target}_executable})
+    
+    # Windows: set the DLL path
+    set(VIGRA_PATH "")
+    if(WIN32)
+        IF(CYGWIN)
+            SET(PATHSEP ":")
+        ELSE()
+            SET(PATHSEP ";")
+        ENDIF()
+        FOREACH(lib ${LIBRARIES})
+            GET_TARGET_PROPERTY(p ${lib} LOCATION)
+            if(p)
+                GET_FILENAME_COMPONENT(p ${p} PATH)
+                VIGRA_NATIVE_PATH(p ${p})
+                SET(VIGRA_PATH  "${p}${PATHSEP}${VIGRA_PATH}")
+           endif()
+        ENDFOREACH(lib)
+    endif()
+    
+    VIGRA_NATIVE_PATH(VIGRA_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+    IF(MSVC OR MINGW)
+        SET(VIGRA_RUN_TEST "${CMAKE_CURRENT_BINARY_DIR}/run_${target}.bat")
+        SET(VIGRA_TEST_EXECUTABLE "\"${VIGRA_TEST_EXECUTABLE}\"")  # take care of paths with spaces
+        CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config/run_test.bat.in
+                       ${VIGRA_RUN_TEST}
+                       @ONLY)
+    ELSE()
+        IF(VIGRA_RUN_TESTS_DIRECTLY)
+          SET(VIGRA_RUN_TEST "${CMAKE_CURRENT_BINARY_DIR}/${target}")
+        ELSE()
+          SET(VIGRA_RUN_TEST "${CMAKE_CURRENT_BINARY_DIR}/run_${target}.sh")
+          CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config/run_test.sh.in
+                         ${VIGRA_RUN_TEST}
+                         @ONLY)
+          EXECUTE_PROCESS(COMMAND chmod u+x ${VIGRA_RUN_TEST} OUTPUT_QUIET ERROR_QUIET)
+        ENDIF()
+    ENDIF()
+    
+    # register the test execution command
+    IF(NOT CMAKE_CFG_INTDIR STREQUAL ".")
+        SET(VIGRA_CONFIGURATION ${CMAKE_CFG_INTDIR})
+    ELSE()
+        SET(VIGRA_CONFIGURATION)
+    ENDIF()
+    
+    IF(AUTOEXEC_TESTS)
+        add_custom_command(
+            TARGET ${target}
+            POST_BUILD
+            COMMAND ${VIGRA_RUN_TEST} ARGS ${VIGRA_CONFIGURATION}
+            COMMENT "Running ${target}")
+    ENDIF()
+    
+    ADD_TEST(${target} ${VIGRA_RUN_TEST} ${VIGRA_CONFIGURATION})
+    
+    IF(WITH_VALGRIND AND VALGRIND_EXECUTABLE)
+        IF(VALGRIND_SUPPRESSION_FILE)
+            SET(VALGRIND_SUPPRESSION "--suppressions=${VALGRIND_SUPPRESSION_FILE}")
+        ELSE()
+            SET(VALGRIND_SUPPRESSION)
+        ENDIF()
+        ADD_TEST(${target}_valgrind 
+                ${VALGRIND_EXECUTABLE} 
+                ${VALGRIND_SUPPRESSION} 
+                --error-exitcode=1 
+                ${${target}_executable})
+    ENDIF()
+
+ENDFUNCTION(VIGRA_ADD_TEST)
+
+MACRO(VIGRA_COPY_TEST_DATA)
+    FOREACH(test_data ${ARGN})
+        configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${test_data} 
+                       ${CMAKE_CURRENT_BINARY_DIR}/${test_data}
+                       COPYONLY)
+    ENDFOREACH(test_data)
+ENDMACRO(VIGRA_COPY_TEST_DATA)
diff --git a/config/VigraCMakeUtils.cmake b/config/VigraCMakeUtils.cmake
new file mode 100644
index 0000000..fd88a38
--- /dev/null
+++ b/config/VigraCMakeUtils.cmake
@@ -0,0 +1,12 @@
+# - find the path of a module's compilation output (usually a DLL)
+#
+#  DEPENDENCY_PATH(TARGET_VAR dependency)
+#
+# e.g. DEPENDENCY_PATH(VIGRAIMPEX_PATH vigraimpex)
+#
+MACRO(DEPENDENCY_PATH variable target)
+    GET_TARGET_PROPERTY(${variable} ${target} LOCATION)
+    STRING(REGEX REPLACE "(/\\$\\([^\\)]*\\)/[^/]*|/[^/]*)$" "" ${variable} ${${variable}}) # get path prefix
+    FILE(TO_NATIVE_PATH ${${variable}} ${variable})
+ENDMACRO(DEPENDENCY_PATH)
+
diff --git a/config/VigraConfig.cmake.in b/config/VigraConfig.cmake.in
new file mode 100644
index 0000000..5b998e3
--- /dev/null
+++ b/config/VigraConfig.cmake.in
@@ -0,0 +1,14 @@
+get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+get_filename_component(Vigra_TOP_DIR  "${SELF_DIR}/../../" ABSOLUTE)
+
+include(${SELF_DIR}/vigra-targets.cmake)
+get_target_property(VIGRA_TYPE vigraimpex TYPE)
+if(${VIGRA_TYPE} STREQUAL "STATIC_LIBRARY")
+    SET(VIGRA_STATIC_LIB True)
+    ADD_DEFINITIONS(-DVIGRA_STATIC_LIB)
+endif(${VIGRA_TYPE} STREQUAL "STATIC_LIBRARY")
+get_filename_component(Vigra_INCLUDE_DIRS "${Vigra_TOP_DIR}/include/" ABSOLUTE)
+
+IF(EXISTS ${SELF_DIR}/../vigranumpy/VigranumpyConfig.cmake)
+    INCLUDE(${SELF_DIR}/../vigranumpy/VigranumpyConfig.cmake)
+ENDIF()
diff --git a/config/VigraConfigBuild.cmake.in b/config/VigraConfigBuild.cmake.in
new file mode 100644
index 0000000..451f983
--- /dev/null
+++ b/config/VigraConfigBuild.cmake.in
@@ -0,0 +1,6 @@
+get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+set(Vigra_TOP_DIR ${SELF_DIR})
+include(${Vigra_TOP_DIR}/vigra-targets.cmake)
+get_filename_component(Vigra_INCLUDE_DIRS "${Vigra_TOP_DIR}/include/" ABSOLUTE)
+set(Vigra_INCLUDE_DIRS ${Vigra_INCLUDE_DIRS};@PROJECT_SOURCE_DIR@/include)
+
diff --git a/config/VigraConfigVersion.cmake.in b/config/VigraConfigVersion.cmake.in
new file mode 100644
index 0000000..08a9cd0
--- /dev/null
+++ b/config/VigraConfigVersion.cmake.in
@@ -0,0 +1,12 @@
+SET(PACKAGE_VERSION @vigra_version@)
+SET(PACKAGE_VERSION_EXACT False)
+SET(PACKAGE_VERSION_COMPATIBLE True)
+
+IF(PACKAGE_FIND_VERSION)
+    IF(${PACKAGE_FIND_VERSION} VERSION_EQUAL @vigra_version@)
+        SET(PACKAGE_VERSION_EXACT True)
+    ENDIF()
+    IF(${PACKAGE_FIND_VERSION} VERSION_GREATER @vigra_version@)
+        SET(PACKAGE_VERSION_COMPATIBLE False)
+    ENDIF()
+ENDIF(PACKAGE_FIND_VERSION)
diff --git a/config/VigraFindPackage.cmake b/config/VigraFindPackage.cmake
new file mode 100644
index 0000000..e7c1288
--- /dev/null
+++ b/config/VigraFindPackage.cmake
@@ -0,0 +1,81 @@
+# - improved version of the reduced FIND_PACKAGE syntax
+#
+#  VIGRA_FIND_PACKAGE(package [VERSION_SPEC] [COMPONENTS component1 ... ] [NAMES name1 ...])
+#
+# FIND_PACKAGE is dangerous when custom search prefixes are added, because these 
+# prefixes are tried for includes and libraries independently. Thus, it may happen
+# that a library is found under one prefix, whereas the corresponding include is 
+# found under another. Subsequent crashes of the compiled programs are likely. 
+#
+# VIGRA_FIND_PACKAGE improves upon this by trying custom prefixes one at a time,
+# so that either both includes and libraries are found under the same prefix,
+# or the search is marked as unsuccessful for this prefix.
+#
+MACRO(VIGRA_FIND_PACKAGE package)
+    # parse the args
+    set(COMPONENTS)
+    set(NAMES)
+    set(VERSION_SPEC)
+    set(v VERSION_SPEC)
+    foreach(i ${ARGN})
+        if(${i} MATCHES "^COMPONENTS$")
+            set(v COMPONENTS)
+        elseif(${i} MATCHES "^NAMES$")
+            set(v NAMES)
+        else()
+            set(${v} ${${v}} ${i})
+        endif()
+    endforeach(i)
+
+    foreach(name ${NAMES})
+        SET(${package}_NAMES ${package}_NAMES ${name})
+    endforeach(name)
+
+    IF(DEFINED COMPONENTS)
+        SET(COMPONENTS COMPONENTS ${COMPONENTS})
+    ENDIF()
+    
+    if(VERSION_SPEC)
+        set(VERSION_MESSAGE " (at least version ${VERSION_SPEC})")
+    else()
+        set(VERSION_MESSAGE)
+    endif()
+    
+    MESSAGE(STATUS "Searching for ${package}${VERSION_MESSAGE}")
+    
+    foreach(path ${DEPENDENCY_SEARCH_PREFIX})
+        if(NOT ${package}_FOUND)
+            IF(${package} STREQUAL "Boost")
+                IF(EXISTS "${path}/boost/config.hpp")
+                    SET(BOOST_INCLUDEDIR ${path}) # boost's default include path
+                ELSE()
+                    SET(BOOST_INCLUDEDIR ${path}/include) # standard include path
+                ENDIF()
+                SET(BOOST_LIBRARYDIR ${path}/lib)
+            ELSE()
+                SET(CMAKE_INCLUDE_PATH ${path}/include)
+                SET(CMAKE_LIBRARY_PATH ${path}/lib)
+            ENDIF()
+            # SET(${package}_INCLUDE_DIR ${package}_INCLUDE_DIR-NOTFOUND)
+            # SET(${package}_LIBRARIES ${package}_LIBRARIES-NOTFOUND)
+            # SET(${package}_LIBRARY ${package}_LIBRARY-NOTFOUND)
+            MESSAGE(STATUS "   in prefix ${path}")
+            FIND_PACKAGE(${package} ${VERSION_SPEC} ${COMPONENTS})
+            IF(${package} STREQUAL "Boost")
+                SET(BOOST_INCLUDEDIR)
+                SET(BOOST_LIBRARYDIR)
+            ELSE()
+                SET(CMAKE_INCLUDE_PATH)
+                SET(CMAKE_LIBRARY_PATH)
+            ENDIF()
+        endif()
+    endforeach(path)
+   
+    # search the package in the default locations if not found 
+    # in the DEPENDENCY_SEARCH_PREFIX 
+    if(NOT ${package}_FOUND)
+        MESSAGE(STATUS "   in default locations")
+        FIND_PACKAGE(${package} ${VERSION_SPEC} ${COMPONENTS})
+    endif()
+    
+ENDMACRO(VIGRA_FIND_PACKAGE)    
diff --git a/config/VigraSetDefaults.cmake b/config/VigraSetDefaults.cmake
new file mode 100644
index 0000000..3a3f7dd
--- /dev/null
+++ b/config/VigraSetDefaults.cmake
@@ -0,0 +1,129 @@
+# Set default values for various cmake configuration variables
+
+# Output of doxygen and sphinx-build will be written
+# to ${DOCDIR}.
+# Vigra html files generated by doxygen will be stored
+# in ${DOCDIR}/vigra.
+# Vigranumpy sphinx output will be stored in
+# ${DOCDIR}/vigranumpy.
+# This should keep relative links between
+# vigranumpy and vigra working.
+IF(NOT DEFINED DOCDIR)
+    SET(DOCDIR ${vigra_SOURCE_DIR}/doc)
+ENDIF()
+SET(DOCDIR ${DOCDIR}
+    CACHE PATH "Output path of created documentation files."
+    FORCE)
+
+# running make install, the content of ${DOCDIR}
+# is copied/installed at ${DOCINSTALL}.
+IF(NOT DEFINED DOCINSTALL)
+    SET(DOCINSTALL "doc")
+ENDIF()
+SET(DOCINSTALL ${DOCINSTALL}
+    CACHE STRING "where to install the documentation (relative to install prefix)"
+    FORCE)
+
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+    set(MACOSX TRUE)
+ENDIF()
+
+IF(NOT DEFINED WITH_HDF5)
+    SET(WITH_HDF5 "ON")
+ENDIF()
+SET(WITH_HDF5 ${WITH_HDF5}
+    CACHE BOOL "Build HDF5 import/export ?"
+    FORCE)
+    
+OPTION(WITH_OPENEXR "Support for the OpenEXR graphics format" OFF)
+
+IF(NOT DEFINED WITH_VIGRANUMPY)
+    SET(WITH_VIGRANUMPY "ON")
+ENDIF()
+SET(WITH_VIGRANUMPY ${WITH_VIGRANUMPY}
+    CACHE BOOL "Build VIGRA Python bindings ?"
+    FORCE)
+    
+IF(NOT DEFINED WITH_VALGRIND)
+    SET(WITH_VALGRIND "OFF")
+ENDIF()
+SET(WITH_VALGRIND ${WITH_VALGRIND}
+    CACHE BOOL "Perform valgrind memory testing upon 'make ctest' ?"
+    FORCE)
+    
+IF(NOT DEFINED LIBDIR_SUFFIX)
+    SET(LIBDIR_SUFFIX "")
+ENDIF()
+SET(LIBDIR_SUFFIX ${LIBDIR_SUFFIX}
+    CACHE STRING "Define suffix of lib directory name (empty string or 32 or 64)." 
+    FORCE)
+    
+IF(NOT DEFINED DEPENDENCY_SEARCH_PREFIX)
+    SET(DEPENDENCY_SEARCH_PREFIX "")
+ENDIF()    
+SET(DEPENDENCY_SEARCH_PREFIX ${DEPENDENCY_SEARCH_PREFIX}
+    CACHE PATH "Additional search prefixes (used by Find... macros)."
+    FORCE)
+
+IF(NOT DEFINED AUTOEXEC_TESTS)
+    SET(AUTOEXEC_TESTS "ON")
+ENDIF()    
+SET(AUTOEXEC_TESTS ${AUTOEXEC_TESTS}
+    CACHE BOOL "Automatically execute each test after compilation ?"
+    FORCE)
+
+IF(NOT DEFINED AUTOBUILD_TESTS)
+    SET(AUTOBUILD_TESTS "OFF")
+ENDIF()    
+SET(AUTOBUILD_TESTS ${AUTOBUILD_TESTS}
+    CACHE BOOL "Compile tests as part of target 'all' (resp. 'ALL_BUILD') ?"
+    FORCE)
+
+IF(NOT DEFINED VIGRA_STATIC_LIB)
+    SET(VIGRA_STATIC_LIB "OFF")
+ENDIF()    
+SET(VIGRA_STATIC_LIB ${VIGRA_STATIC_LIB}
+    CACHE BOOL "Whether to build vigra as a static library ?"
+    FORCE)
+
+# This is only executed once on the first cmake run.
+IF(NOT VIGRA_DEFAULTS_INIT)
+    SET(VIGRA_DEFAULTS_INIT TRUE CACHE INTERNAL "initial flags set")
+
+    IF (NOT MSVC AND NOT CMAKE_BUILD_TYPE)
+        SET(CMAKE_BUILD_TYPE "Release"
+            CACHE STRING "Choose the type of build, options are None Release Debug RelWithDebInfo MinSizeRel."
+            FORCE)
+    ENDIF ()
+    
+    IF(NOT DEFINED VALGRIND_SUPPRESSION_FILE)
+        SET(VALGRIND_SUPPRESSION_FILE ""
+            CACHE FILEPATH "File containing valgrind error suppression rules."
+            FORCE)
+    ENDIF()
+    
+    # initial compiler flags can be set here, this is only
+    # executed once in the first configure run.
+    IF(CMAKE_COMPILER_IS_GNUCXX)
+        IF(NOT CMAKE_CXX_FLAGS)
+            if(NOT MINGW AND NOT MACOSX)
+                SET(CMAKE_CXX_FLAGS "-W -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-unused-variable -Wno-type-limits")
+            elseif(MACOSX)
+                SET(CMAKE_CXX_FLAGS "-W -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-unused-variable")
+            endif()
+        ENDIF()
+        IF(NOT CMAKE_C_FLAGS)
+            SET(CMAKE_C_FLAGS "-W -Wall -Wextra -pedantic -std=c99 -Wno-sign-compare")
+        ENDIF()
+    ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+
+    SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} CACHE STRING
+        "Flags used by the compiler during all build types."
+        FORCE
+    )
+    SET(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} CACHE STRING
+        "Flags used by the compiler during all build types."
+        FORCE
+    )
+ENDIF(NOT VIGRA_DEFAULTS_INIT)
+
diff --git a/config/VigranumpyConfig.cmake.in b/config/VigranumpyConfig.cmake.in
new file mode 100644
index 0000000..ea44edc
--- /dev/null
+++ b/config/VigranumpyConfig.cmake.in
@@ -0,0 +1,64 @@
+#        Configuration file for 3rd party vigranumpy modules
+#        
+#        Usage:
+#            find_package(Vigranumpy REQUIRED PATHS ${Vigranumpy_DIR}) # set Vigranumpy_DIR default paths fail
+#            add_vigranumpy_module(myModule SOURCES myModule.cxx ... [LIBRARIES extralib.lib ...])
+#
+get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+# turn relative paths to includes and libraries back into absolute paths
+set(VIGRANUMPY_INCLUDE_DIRS "")
+foreach(PATH @VIGRANUMPY_INCLUDE_RELATIVE@)
+    get_filename_component(ABSPATH ${SELF_DIR}/${PATH} ABSOLUTE)
+    set(VIGRANUMPY_INCLUDE_DIRS ${VIGRANUMPY_INCLUDE_DIRS} ${ABSPATH})
+endforeach(PATH)
+
+set(VIGRANUMPY_LIBRARIES "")
+foreach(PATH @VIGRANUMPY_LIBRARIES_RELATIVE@)
+    get_filename_component(ABSPATH ${SELF_DIR}/${PATH} ABSOLUTE)
+    set(VIGRANUMPY_LIBRARIES ${VIGRANUMPY_LIBRARIES} ${ABSPATH})
+endforeach(PATH)
+
+FUNCTION(add_vigranumpy_module target)
+    
+    # parse the args
+    set(v SOURCES)
+    foreach(i ${ARGN})
+        if(${i} MATCHES "^SOURCES$")
+            set(v SOURCES)
+        elseif(${i} MATCHES "^LIBRARIES$")
+            set(v LIBRARIES)
+        else()
+            set(${v} ${${v}} ${i})
+        endif()
+    endforeach(i)
+    
+    set(TARGET_NAME ${target})
+    set(LIBRARY_NAME ${target})
+
+    include_directories(${VIGRANUMPY_INCLUDE_DIRS})
+    
+    ADD_LIBRARY(${TARGET_NAME} SHARED ${SOURCES})    
+    
+    if(DEFINED LIBRARIES)
+        TARGET_LINK_LIBRARIES(${TARGET_NAME} ${LIBRARIES})
+    endif()
+    
+    TARGET_LINK_LIBRARIES(${TARGET_NAME} ${VIGRANUMPY_LIBRARIES})
+    
+    # configure boost's autolink magic to use the right library name
+    # (default on Windows is a mangled name like 'boost_python-vc110-mt-1_51.lib')
+    if("${VIGRANUMPY_LIBRARIES}" MATCHES "boost_python\\.lib")
+        ADD_DEFINITIONS(-DBOOST_AUTO_LINK_NOMANGLE)
+    endif()
+    
+    IF(WIN32 AND NOT MINGW)
+        SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${LIBRARY_NAME}" 
+                                                           PREFIX "" SUFFIX  ".pyd")
+    ELSEIF(APPLE)
+        SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${LIBRARY_NAME}" PREFIX "" SUFFIX ".so")
+    ELSE()
+        SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${LIBRARY_NAME}" 
+                                                           PREFIX "")
+    ENDIF()
+ENDFUNCTION(add_vigranumpy_module)
diff --git a/config/checkHDF5usesCompression.c b/config/checkHDF5usesCompression.c
new file mode 100644
index 0000000..7b3edb7
--- /dev/null
+++ b/config/checkHDF5usesCompression.c
@@ -0,0 +1,8 @@
+#include <H5pubconf.h>
+
+#if !defined(H5_SOMETHING) || !H5_SOMETHING
+#error "flag is not defined"
+#endif
+
+int main()
+{}
diff --git a/config/checkHDF5version.c b/config/checkHDF5version.c
new file mode 100644
index 0000000..7906980
--- /dev/null
+++ b/config/checkHDF5version.c
@@ -0,0 +1,9 @@
+#include <hdf5.h>
+
+#if (H5_VERS_MAJOR < MIN_MAJOR) || \
+   ((H5_VERS_MAJOR == MIN_MAJOR) && (H5_VERS_MINOR < MIN_MINOR))
+#error "insufficient HDF5 version"
+#endif
+
+int main()
+{}
diff --git a/config/package-src.cmake.in b/config/package-src.cmake.in
new file mode 100644
index 0000000..f74e81a
--- /dev/null
+++ b/config/package-src.cmake.in
@@ -0,0 +1,53 @@
+SET(versionname "vigra- at VIGRA_VERSION_MAJOR@. at VIGRA_VERSION_MINOR@. at VIGRA_VERSION_PATCH@")
+SET(versiontag "Version- at VIGRA_VERSION_MAJOR@- at VIGRA_VERSION_MINOR@- at VIGRA_VERSION_PATCH@")
+SET(GITREFS_PATH "@PROJECT_SOURCE_DIR@/.git/refs")
+
+IF (NOT EXISTS "${GITREFS_PATH}/tags/${versiontag}")
+    MESSAGE(FATAL_ERROR "Version tag '${versiontag}' missing.")
+endif()
+
+execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files "${GITREFS_PATH}/heads/master" "${GITREFS_PATH}/tags/${versiontag}"
+                 RESULT_VARIABLE VERSION_OUT_OF_SYNC ERROR_QUIET)
+
+IF (${VERSION_OUT_OF_SYNC})
+    MESSAGE(FATAL_ERROR "Version tag '${versiontag}' and branch 'master' are out of sync.")
+endif()
+
+execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${versionname}
+                WORKING_DIRECTORY "@PROJECT_BINARY_DIR@")
+
+execute_process(COMMAND @GIT_EXECUTABLE@ archive --format=tar --prefix=${versionname}/ -o "@PROJECT_BINARY_DIR@/${versionname}-src.tar" ${versiontag}
+                 WORKING_DIRECTORY "@PROJECT_SOURCE_DIR@")
+MESSAGE(STATUS "Created tar file")
+
+IF(${CMAKE_VERSION} VERSION_GREATER 2.8.2)
+    SET(CMAKE_HAS_WORKING_TAR 1)
+ELSE()
+    SET(CMAKE_HAS_WORKING_TAR 0)
+ENDIF()
+
+IF(${CMAKE_HAS_WORKING_TAR})
+    execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${versionname}-src.tar
+                    WORKING_DIRECTORY "@PROJECT_BINARY_DIR@")
+    MESSAGE(STATUS "Unpacked tar file")
+    execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory @DOCDIR@ ${versionname}/doc
+                    WORKING_DIRECTORY "@PROJECT_BINARY_DIR@")
+    MESSAGE(STATUS "Copied docu")
+    execute_process(COMMAND ${CMAKE_COMMAND} -E tar czf ${versionname}-src.tar.gz ${versionname}
+                    WORKING_DIRECTORY "@PROJECT_BINARY_DIR@")
+    MESSAGE(STATUS "Finished  ${versionname}-src.tar.gz")
+    execute_process(COMMAND ${CMAKE_COMMAND} -E remove -f ${versionname}-src.tar
+                    WORKING_DIRECTORY "@PROJECT_BINARY_DIR@")
+ELSE()
+    execute_process(COMMAND tar -xf ${versionname}-src.tar
+                    WORKING_DIRECTORY "@PROJECT_BINARY_DIR@")
+    MESSAGE(STATUS "Unpacked tar file")
+    execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory @DOCDIR@ ${versionname}/doc
+                    WORKING_DIRECTORY "@PROJECT_BINARY_DIR@")
+    MESSAGE(STATUS "Copied docu")
+    execute_process(COMMAND tar -czf ${versionname}-src.tar.gz ${versionname}
+                    WORKING_DIRECTORY "@PROJECT_BINARY_DIR@")
+    MESSAGE(STATUS "Finished  ${versionname}-src.tar.gz")
+    execute_process(COMMAND ${CMAKE_COMMAND} -E remove -f ${versionname}-src.tar
+                    WORKING_DIRECTORY "@PROJECT_BINARY_DIR@")
+ENDIF()
\ No newline at end of file
diff --git a/config/run_test.bat.in b/config/run_test.bat.in
new file mode 100644
index 0000000..1626353
--- /dev/null
+++ b/config/run_test.bat.in
@@ -0,0 +1,18 @@
+ at echo off
+if [%1] NEQ [] (
+    set CONFIGURATION=%1
+) else (
+    set CONFIGURATION=Release
+)
+
+echo Testing configuration '%CONFIGURATION%'
+
+set PATH=@VIGRA_PATH@%PATH%
+cd @VIGRA_CURRENT_BINARY_DIR@
+
+cmd /c @VIGRA_TEST_EXECUTABLE@
+IF %ERRORLEVEL% NEQ 0 (
+    rem this is the Windows version of 'touch'
+    copy /b testsuccess.cxx+,, > NUL
+    exit %ERRORLEVEL% 
+)
diff --git a/config/run_test.sh.in b/config/run_test.sh.in
new file mode 100644
index 0000000..086fa1c
--- /dev/null
+++ b/config/run_test.sh.in
@@ -0,0 +1 @@
+PATH=@VIGRA_PATH@$PATH && cd @VIGRA_CURRENT_BINARY_DIR@ && (@VIGRA_TEST_EXECUTABLE@ || { touch testsuccess.cxx; exit 1; } )
diff --git a/config/update-gh-pages.sh.in b/config/update-gh-pages.sh.in
new file mode 100644
index 0000000..93334f0
--- /dev/null
+++ b/config/update-gh-pages.sh.in
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+branch=`git rev-parse --abbrev-ref HEAD`
+if [ "$branch" == "master" ]; then
+    current=`git rev-parse --short HEAD`
+    cd @DOCDIR@
+    branch=`git rev-parse --abbrev-ref HEAD`
+    if [ "$branch" == "gh-pages" ]; then
+        if [ -n "$(git status --porcelain)" ]; then 
+            git add -A
+            git commit -m "documentation for commit $current"
+        else
+            echo "Nothing to commit"
+        fi
+        git push origin gh-pages
+    else
+        echo "WARNING: cannot upload documentation: '@DOCDIR@' is not a git repo or not in branch 'gh-pages'"
+    fi
+else
+    echo "WARNING: cannot upload documentation: repository is not in branch 'master'" 
+fi
diff --git a/config/vigra-config.in b/config/vigra-config.in
new file mode 100644
index 0000000..b403f0d
--- /dev/null
+++ b/config/vigra-config.in
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+
+from optparse import OptionParser
+import sys
+
+hasFFTW = bool('@FFTW3_LIBRARY@')
+
+parser = OptionParser()
+
+parser.add_option("--version", action = 'store_true',
+                  help = "output version (@vigra_version@)")
+#parser.add_option("--target", action = 'store_true',
+#                 help = "output platform this VIGRA library was configured for")
+parser.add_option("--impex-lib", "--libs", action = 'store_true',
+                  help = "output flags for linking libvigraimpex")
+parser.add_option("--fftw-lib", action = 'store_true',
+                  help = "output flags for linking libfftw"
+                  + " (unavailable)" if not hasFFTW else "")
+#parser.add_option("--rfftw-lib", action = 'store_true',
+#                 help = "output flags for linking librfftw and libfftw")
+parser.add_option("--cppflags", action = 'store_true',
+                  help = "output include flags for vigra"
+                  + " and fftw" if hasFFTW else "")
+parser.add_option("--include-path", "--includepath", action = 'store_true',
+                  help = "output path to VIGRA includes")
+parser.add_option("--docdir", action = 'store_true',
+                  help = "output path to VIGRA documentation")
+
+(op, args) = parser.parse_args()
+
+if len(sys.argv) < 2:
+    sys.stderr.write("ERROR: no parameters given.\n")
+    parser.print_help()
+    sys.exit(1)
+
+# --------------------------------------------------------------------
+
+import os.path
+
+# don't output -L flags for the following dirs (assumed to be compiler
+# built-in):
+standardLibDirs = ["/lib", "/usr/lib", "/lib64", "/usr/lib64"]
+
+libExt = ".so" if not sys.platform == "darwin" else ".dylib"
+
+def filename2ldflags(libFilename):
+    dir, fn = os.path.split(libFilename)
+    if not (fn.startswith("lib") and fn.endswith(libExt)):
+        if libFilename:
+            sys.stderr.write("ERROR: don't know how to handle %r!\n" % libFilename)
+        return []
+    lib = fn[3:-len(libExt)]
+
+    result = []
+    if dir not in standardLibDirs:
+        result.append("-L" + dir)
+    result.append("-l" + lib)
+    return result
+
+if op.version:
+    print "@vigra_version@"
+
+if op.cppflags: # was: --cppflags|--cxxincludes|--cxxflags|--cincludes|--cflags
+    print '-I at CMAKE_INSTALL_PREFIX@/include'
+
+if op.impex_lib: # was: --impex_lib|--impex-lib|--libs
+    ldflags = []
+
+    libDir = '@CMAKE_INSTALL_PREFIX@/lib at LIBDIR_SUFFIX@'
+    if libDir not in standardLibDirs:
+        ldflags.append('-L' + libDir)
+
+    ldflags.append('-lvigraimpex')
+
+    for flag in '@vigraimpex_LIB_DEPENDS@'.split(';'):
+        if flag == 'general':
+            continue
+        for fl in filename2ldflags(flag):
+            if fl not in ldflags:
+                ldflags.append(fl)
+
+    print " ".join(ldflags)
+
+if op.fftw_lib:
+    if not hasFFTW:
+        sys.stderr.write("VIGRA was configured without FFTW switches, libpath unknown!\n")
+        sys.exit(1)
+    print " ".join(filename2ldflags('@FFTW3_LIBRARY@'))
+
+if op.include_path: # was: --include_path|--include-path|--includepath
+    print '@CMAKE_INSTALL_PREFIX@/include'
+
+if op.docdir:
+    print '@DOCDIR@'
diff --git a/config/winsetup.iss b/config/winsetup.iss
new file mode 100644
index 0000000..17171a8
--- /dev/null
+++ b/config/winsetup.iss
@@ -0,0 +1,146 @@
+#define MyAppName "Vigra 1.6"
+#define MyAppVersion "1.6.0"
+#define MyAppPublisher "Ullrich K�the, University of Heidelberg"
+#define MyAppURL "http://kogs.informatik.uni-hamburg.de/~koethe/vigra/"
+#define MySourcePath "C:\ukoethe\tmp\vigra1.6.0"
+#define MyExternalPath "C:\ukoethe\vigra\current"
+#define RequiredVCVersion "8.0"
+
+[Setup]
+AppCopyright=Ullrich K�the
+AppName={#MyAppName}
+AppVerName=Vigra {#MyAppVersion}
+LicenseFile={#MySourcePath}\LICENSE.txt
+ShowLanguageDialog=yes
+AppSupportURL={#MyAppUrl}
+AppVersion={#MyAppVersion}
+DefaultDirName={reg:HKCU\Software\Microsoft\VisualStudio\8.0,VisualStudioProjectsLocation|{pf}}\{#MyAppName}
+OutputBaseFilename=Setup-Vigra-{#MyAppVersion}
+Compression=lzma
+SolidCompression=true
+AppID={#MyAppName}
+OutputDir=C:\ukoethe\vigra\current\WinSetup
+InfoBeforeFile=
+
+[Files]
+Source: {#MySourcePath}\LICENSE.txt; DestDir: {app}
+Source: {#MySourcePath}\README.txt; DestDir: {app}
+Source: {#MySourcePath}\include\vigra\*.hxx; DestDir: {app}\include\vigra
+Source: {#MySourcePath}\include\vigra\*.h; DestDir: {app}\include\vigra
+Source: {#MySourcePath}\src\*.cxx; DestDir: {app}\src; Flags: recursesubdirs
+Source: {#MySourcePath}\src\*.hxx; DestDir: {app}\src; Flags: recursesubdirs
+Source: {#MySourcePath}\src\*.c; DestDir: {app}\src; Flags: recursesubdirs
+Source: {#MySourcePath}\src\*.h; DestDir: {app}\src; Flags: recursesubdirs
+Source: {#MySourcePath}\src\*.vcproj; Excludes: *-vc71.vcproj; DestDir: {app}\src; Flags: recursesubdirs
+Source: {#MySourcePath}\src\*.sln; Excludes: *-vc71.sln; DestDir: {app}\src
+Source: {#MySourcePath}\src\examples\*.gif; DestDir: {app}\src\examples
+Source: {#MySourcePath}\test\*.cxx; DestDir: {app}\test; Flags: recursesubdirs
+Source: {#MySourcePath}\test\*.hxx; DestDir: {app}\test; Flags: recursesubdirs
+Source: {#MySourcePath}\test\*.gif; DestDir: {app}\test; Flags: recursesubdirs
+Source: {#MySourcePath}\test\*.xv; DestDir: {app}\test; Flags: recursesubdirs
+Source: {#MySourcePath}\test\*.vcproj; Excludes: *-vc71.vcproj; DestDir: {app}\test; Flags: recursesubdirs
+Source: {#MySourcePath}\test\*.sln; Excludes: *-vc71.sln; DestDir: {app}\test
+Source: {#MySourcePath}\test\testOrDelete.bat; DestDir: {app}\test
+Source: {#MySourcePath}\doc\vigra\*; Excludes: CVS; DestDir: {app}\doc\vigra; Flags: recursesubdirs
+Source: {#MySourcePath}\include\external\fftw3.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\include\external\jconfig.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\include\external\jmorecfg.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\include\external\jpeglib.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\include\external\png.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\include\external\pngconf.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\include\external\tiff.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\include\external\tiffconf.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\include\external\tiffio.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\include\external\tiffvers.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\include\external\zconf.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\include\external\zlib.h; DestDir: {app}\include\external
+Source: {#MySourcePath}\lib\libfftw3-3.lib; DestDir: {app}\lib
+Source: {#MySourcePath}\lib\libjpeg.lib; DestDir: {app}\lib
+Source: {#MySourcePath}\lib\libpng.lib; DestDir: {app}\lib
+Source: {#MySourcePath}\lib\libtiff_i.lib; DestDir: {app}\lib
+Source: {#MySourcePath}\lib\zlib.lib; DestDir: {app}\lib
+Source: {#MySourcePath}\bin\libfftw3-3.dll; DestDir: {app}\bin
+Source: {#MySourcePath}\bin\libtiff.dll; DestDir: {app}\bin
+Source: {#MySourcePath}\src\impex\vigraimpex.dll.lib; DestDir: {app}\lib
+Source: {#MySourcePath}\src\impex\vigraimpex.dll; DestDir: {app}\bin
+Source: {#MySourcePath}\src\examples\*.exe; DestDir: {app}\bin
+
+[UninstallDelete]
+Type: filesandordirs; Name: {app}\src\impex\Release
+Type: filesandordirs; Name: {app}\src\impex\Debug
+Type: files; Name: {app}\src\impex\*.exp
+Type: files; Name: {app}\src\impex\*.pdb
+Type: files; Name: {app}\src\impex\*.dll
+Type: files; Name: {app}\src\impex\*.lib
+Type: files; Name: {app}\src\impex\*.ilk
+Type: dirifempty; Name: {app}\src\impex
+
+Type: filesandordirs; Name: {app}\src\examples\Release
+Type: filesandordirs; Name: {app}\src\examples\Debug
+Type: files; Name: {app}\src\examples\*.exe
+Type: files; Name: {app}\src\examples\*.pdb
+Type: files; Name: {app}\src\examples\*.ilk
+Type: dirifempty; Name: {app}\src\examples
+
+Type: files; Name: {app}\src\*.ncb
+Type: files; Name: {app}\src\*.suo
+Type: dirifempty; Name: {app}\src
+
+Type: files; Name: {app}\lib\*.lib
+Type: dirifempty; Name: {app}\lib
+
+Type: filesandordirs; Name: {app}\test
+Type: dirifempty; Name: {app}
+
+[Code]
+var
+    VCPath: String;
+    VCUserPath: String;
+
+procedure CurStepChanged(CurStep: TSetupStep);
+var
+    Path: String;
+begin
+    if CurStep = ssPostInstall then
+    begin
+        RegQueryStringValue(HKCU, 'Environment', 'PATH', Path);
+        Path := Path + ';' + ExpandConstant('{app}\bin');
+        RegWriteStringValue(HKCU, 'Environment', 'PATH', Path);
+    end;
+end;
+
+procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
+var
+    Path: String;
+begin
+    if CurUninstallStep = usPostUninstall then
+    begin
+        RegQueryStringValue(HKCU, 'Environment', 'PATH', Path);
+        StringChange(Path,  ';' + ExpandConstant('{app}\bin'), '');
+        RegWriteStringValue(HKCU, 'Environment', 'PATH', Path);
+    end;
+end;
+
+procedure InitializeWizard();
+begin
+    if VCPath = '' then
+        CreateOutputMsgPage(wpWelcome, 'Visual C++ {#RequiredVCVersion} not found.', '',
+         'Visual C++ {#RequiredVCVersion} could not be found on your computer. ' +
+         'You may need to re-compile {#MyAppName}, because the provided binaries ' +
+         'may be incompatible with your compiler.');
+
+    if VCUserPath <> '' then
+        WizardForm.DirEdit.Text := VCUserPath + '\{#MyAppName}'
+    else
+        WizardForm.DirEdit.Text := ExpandConstant('{pf}\{#MyAppName}');
+end;
+
+function InitializeSetup(): Boolean;
+begin
+    // Look for Visual Studio
+    VCPath := '';
+    VCUserPath := '';
+    if RegQueryStringValue(HKLM, 'Software\Microsoft\VisualStudio\{#RequiredVCVersion}\Setup\VC', 'ProductDir', VCPath) then
+        RegQueryStringValue(HKCU, 'Software\Microsoft\VisualStudio\{#RequiredVCVersion}','VisualStudioProjectsLocation', VCUserPath);
+    Result := True;
+end;
diff --git a/docsrc/CMakeLists.txt b/docsrc/CMakeLists.txt
new file mode 100644
index 0000000..41c7fde
--- /dev/null
+++ b/docsrc/CMakeLists.txt
@@ -0,0 +1,67 @@
+IF(DOXYGEN_FOUND AND PYTHONINTERP_FOUND)
+    execute_process(COMMAND ${DOXYGEN_EXECUTABLE} --version
+                  OUTPUT_VARIABLE DOXYGEN_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+    if(DOXYGEN_VERSION VERSION_LESS 1.8)
+        set(DOXYGEN_BEFORE_1_8 "")
+        set(DOXYGEN_FROM_1_8_2 "#")
+    elseif(DOXYGEN_VERSION VERSION_LESS 1.8.2)
+        set(DOXYGEN_BEFORE_1_8 "#")
+        set(DOXYGEN_FROM_1_8_2 "#")
+    else()
+        set(DOXYGEN_BEFORE_1_8 "#")
+        set(DOXYGEN_FROM_1_8_2 "")
+    endif()
+    
+    CONFIGURE_FILE(
+        ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in
+        ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
+        @ONLY)
+
+    ADD_CUSTOM_TARGET (doc_cpp
+        COMMAND ${CMAKE_COMMAND} -E make_directory ${DOCDIR}
+        COMMAND ${CMAKE_COMMAND} -E make_directory ${DOCDIR}/vigra
+        COMMAND ${DOXYGEN_EXECUTABLE}  
+        COMMENT "Generating documentation with doxygen ${DOXYGEN_VERSION}")
+
+    ADD_CUSTOM_COMMAND(
+        TARGET doc_cpp
+        POST_BUILD
+        COMMAND ${PYTHON_EXECUTABLE}
+            ${CMAKE_CURRENT_SOURCE_DIR}/makeFunctionIndex.py
+            ${DOCDIR}/vigra
+        COMMAND ${PYTHON_EXECUTABLE}
+            ${CMAKE_CURRENT_SOURCE_DIR}/post.py
+            ${DOCDIR}/vigra
+            ${vigra_version}
+        COMMAND ${CMAKE_COMMAND} -E copy_directory
+            ${CMAKE_CURRENT_SOURCE_DIR}/documents
+            ${DOCDIR}/vigra/documents
+        COMMAND ${CMAKE_COMMAND} -E copy_if_different
+            ${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE.txt
+            ${DOCDIR}/vigra/LICENSE.txt
+        COMMAND ${CMAKE_COMMAND} -E copy_if_different
+            ${CMAKE_CURRENT_SOURCE_DIR}/../src/matlab/doc/tutorial_reference.pdf
+            ${DOCDIR}/vigra/documents/tutorial_reference.pdf
+        COMMENT "Postprocessing html files")
+
+ELSE()
+    ADD_CUSTOM_TARGET (doc_cpp 
+        COMMAND ${CMAKE_COMMAND} -E echo
+            \"Cannot generate C++ documentation -- doxygen or Python not found.\")
+
+ENDIF()
+
+# create fallback index.html that simply refers to the online documentation
+file(MAKE_DIRECTORY ${DOCDIR}/vigra)
+file(GLOB INDEX_HTML_EXISTS ${DOCDIR}/vigra/index.html)
+configure_file(vigra-icon.ico ${DOCDIR}/vigra/vigra-icon.ico COPYONLY)
+if(NOT INDEX_HTML_EXISTS)
+    configure_file(index_fallback.html ${DOCDIR}/vigra/index.html COPYONLY)
+    configure_file(vigra.css ${DOCDIR}/vigra/vigra.css COPYONLY)
+endif()
+
+INSTALL(DIRECTORY ${DOCDIR}/
+         DESTINATION ${DOCINSTALL}/)
+
+ADD_DEPENDENCIES(doc doc_cpp)
diff --git a/docsrc/Doxyfile.in b/docsrc/Doxyfile.in
new file mode 100644
index 0000000..03093aa
--- /dev/null
+++ b/docsrc/Doxyfile.in
@@ -0,0 +1,1446 @@
+# Doxyfile 1.5.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = @PROJECT_NAME@
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = @vigra_version@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = @DOCDIR@
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, 
+# and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = @PROJECT_SOURCE_DIR@/include
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = @PROJECT_SOURCE_DIR@/include
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = configured_docdir="\@docdir\@"
+ALIASES                += stl_link="\"http://www.sgi.com/tech/stl/\""
+ALIASES                += vigra_version=@vigra_version@
+ALIASES                += deprecatedAPI{1}="<a href=\"#\" id=\"\1_OldAPIToggle\" onclick=\"return toggleHiddenDocumentation('\1_OldAPI', '\1_OldAPIToggle', 'deprecated declarations');\">show deprecated declarations</a><div id=\"\1_OldAPI\" style=\"display:none\">"
+ALIASES                += deprecatedUsage{1}="<a href=\"#\" id=\"\1_OldUsageToggle\" onclick=\"return toggleHiddenDocumentation('\1_OldUsage', '\1_OldUsageToggle', 'deprecated examples');\">show deprecated examples</a><div id=\"\1_OldUsage\" style=\"display:none\">"
+ALIASES                += deprecatedEnd="</div>"
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = NO
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+ at DOXYGEN_BEFORE_1_8@ SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = NO
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = 
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = @PROJECT_SOURCE_DIR@/include \
+                         @PROJECT_SOURCE_DIR@/docsrc
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          = index.dxx \
+                         examples.dxx \
+                         credits_changelog.dxx \
+                         installation.dxx \
+                         tutorial.dxx \
+                         image_processing.dxx \
+                         *.hxx \
+                         viff.h
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = @PROJECT_SOURCE_DIR@/include/vigra/fftw.hxx
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = vigra::detail
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = @PROJECT_SOURCE_DIR@/src/examples
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = *.cxx
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = @PROJECT_SOURCE_DIR@/src/images
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 4
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = @DOCDIR@/vigra
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = @PROJECT_SOURCE_DIR@/docsrc/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = @PROJECT_SOURCE_DIR@/docsrc/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = @PROJECT_SOURCE_DIR@/docsrc/vigra.css
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+ at DOXYGEN_FROM_1_8_2@ HTML_EXTRA_STYLESHEET  = @PROJECT_SOURCE_DIR@/docsrc/vigra_1_8_2.css
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES       = @PROJECT_SOURCE_DIR@/src/examples/lenna_color.gif \
+                         @PROJECT_SOURCE_DIR@/src/examples/lenna_gray.gif
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+ at DOXYGEN_BEFORE_1_8@ HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = YES
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, a side panel will be generated
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature. Other possible values 
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hiererachy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 16
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = 
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = 
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = 
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = *.h \
+                         *.hxx
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = DOXYGEN \
+                         __cplusplus \
+                         VIGRA_EXPORT=
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = doxygen_overloaded_function
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = tagfile.tag
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is enabled by default, which results in a transparent 
+# background. Warning: Depending on the platform used, enabling this option 
+# may lead to badly anti-aliased labels on the edges of a graph (i.e. they 
+# become hard to read).
+
+DOT_TRANSPARENT        = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/docsrc/credits_changelog.dxx b/docsrc/credits_changelog.dxx
new file mode 100644
index 0000000..7c41f62
--- /dev/null
+++ b/docsrc/credits_changelog.dxx
@@ -0,0 +1,678 @@
+/** 
+\page CreditsChangelog Credits and Changelog
+
+<b> Credits</b>
+
+<ul>
+      <li> <a href="http://hci.iwr.uni-heidelberg.de/people/ukoethe/">Ullrich Köthe</a>
+             originated and wrote the library.
+
+      <li> Mikhail Amchislavsky 
+      (<a href="mailto:mamchisl at ucdavis.edu">mamchisl at ucdavis.edu</a>)
+      contributed code to read and write PNM files.
+
+      <li> Hans Meine 
+      (<a href="mailto:hans_meine at gmx.net">hans_meine at gmx.net</a>)
+      contributed interface code for the FFTW Fourier transform library,
+      the ImageArray class and the Gabor filter code. He also
+      collaborated in the implementation of many other modules and contributed various improvements.
+
+      <li> Gunnar Kedenburg 
+      (<a href="mailto:gunnar at haquebright.de">gunnar at haquebright.de</a>)
+      completely rewrote the image import/export library and implemented
+      much of the \ref vigra::MultiArray functionality.
+
+      <li> Yevgen Reznichenko
+      (<a href="mailto:rezniche at kogs.informatik.uni-hamburg.de">rezniche at kogs.informatik.uni-hamburg.de</a>)
+      added a number of image processing algorithms.
+
+      <li> Christian Dennis Rahn
+      (<a href="mailto:rahn at informatik.uni-hamburg.de">rahn at informatik.uni-hamburg.de</a>)
+      implemented much of the \ref MultiArrayConvolutionFilters.
+
+      <li> Kasim Terzic, Florian Heinrich and Benjamin Seppke
+      implemented image analysis functionality for 3- and higher-dimensional data.
+
+      <li> Pablo d'Angelo, Douglas Wilkins, Lukas Jirkovsky and other members of the  
+      <a href="http://hugin.sourceforge.net">Hugin team</a> contributed various extensions of the impex
+      library (UINT16/UINT32 support, ICC profile support, HDR and OpenEXR file types).
+
+      <li> Rahul Nair implemented the \ref vigra::RandomForest classifier and VIGRA Matlab bindings.
+      
+      <li> Michael Hanselmann and Martin Lindner implemented much of the HDF5 support. Michael Hanselmann
+           also contributed his pLSA (probabilistic latent semantic analysis) implementation.
+      
+      <li> Nathan Huesken and Christoph Sommer helped a lot in developing 
+           <a href="../vigranumpy/index.html">vigranumpy</a>, the VIGRA Python bindings.
+           
+      <li> Jens-Malte Gottfried contributed to the cmake-based build system.
+
+      <li> Joachim Schleicher implemented a reader for the SIF file format.
+
+      <li> Oliver Gathmann and Michael Held implemented support for the multi-page TIFF format.
+
+      <li> Christoph Spiel contributed I/O functions for images with transparency (alpha channel) and other improvements to the impex library.
+
+      <li> Frank Lenzen contributed his implementations of total variation filters.
+
+      <li> Patrick Fahner helped writing the tutorial.
+      
+      <li> Stefan Schmidt made major contributions to \ref vigra::GridGraph.
+
+      <li> Numerous people reported bugs and made suggestions.
+</ul>
+
+Many thanks to all!
+<p>
+
+<b> Changes from Version 1.9.0 to 1.10.0</b>
+
+<ul>  
+      <li> VIGRA got a \ref Tutorial !
+      
+      <li> Significant simplification of the API: <tt>MultiArrayView</tt> arguments can now be passed to functions directly:
+      
+      \code
+      MultiArray<float> src(Shape2(200,100)), dest(src.shape());
+      gaussianSmoothing(src, dest, 2.0);
+      \endcode
+      
+      The old syntax with \ref ArgumentObjectFactories (<tt>srcImageRange()</tt>, <tt>srcMultiArray()</tt> and relatives) remains valid, but is only required when the arguments are old-style <tt>BasicImage</tt>s.
+      
+      <li> Made <tt>StridedArrayTag</tt> the default for \ref vigra::MultiArrayView .
+      
+      <li> Added an efficient multi-dimensional \ref vigra::GridGraph class which support both the LEMON and boost::graph APIs.
+      
+      <li> Generalized various algorithms to arbitrary dimensions (\ref gaussianGradientMultiArray(), \ref hessianOfGaussianMultiArray(), \ref gaussianDivergenceMultiArray(), \ref localMinima(), \ref localMaxima(), \ref labelMultiArray(), \ref watershedsMultiArray()).
+      
+      <li> Added \ref slicSuperpixels() for arbitrary dimensions.
+      
+      <li> Added automatic differentiation (see \ref vigra::autodiff::DualVector).
+      
+      <li> Added \ref nonlinearLeastSquares() using the Levenberg-Marquardt algorithm and automatic differentiation.
+      
+      <li> Added a function <tt>setCoordinateOffset()</tt> to the feature accumulator classes to enable block-wise computation of coordinate-based features.
+      
+      <li> Added \ref vigra::MultiCoordinateIterator to enumerate the grid coordinates of a multi-dimensional array.
+      
+      <li> Fixed thread-safety of <tt>RandomForest::learn()</tt> (random seeding) and <tt>RandomForest::predictLebels()</tt>.
+      
+      <li> Improved HDF5 I/O for strided <tt>MultiArrayView</tt>s and HDF5 on-the-fly compression.
+      
+      <li> Added support for multi-page TIFF to \ref importVolume() and \ref exportVolume(). Added support for Andor SIF to \ref importVolume().
+      
+      <li> Added <tt>VigranumpyConfig.cmake</tt> to simplify cmake-based compilation of custom vigranumpy modules.
+      
+      <li> Minor improvements and bug fixes in the code and documentation. 
+ </ul>
+
+<b> Changes from Version 1.8.0 to 1.9.0</b>
+
+<ul>  
+      <li> Flexible incremental computation of image and region statistics via \ref FeatureAccumulators and corresponding Python bindings (see <a href="../vigranumpy/index.html#vigra.analysis.extractFeatures">vigra.analysis.extractFeatures()</a> and <a href="../vigranumpy/index.html#vigra.analysis.extractRegionFeatures">vigra.analysis.extractRegionFeatures()</a>).
+      
+      <li> Simultaneous iteration over several arrays via \ref vigra::CoupledScanOrderIterator.
+      
+      <li> Import and export of images with transparency: importImageAlpha() and exportImageAlpha().
+      
+      <li> Image denoising by total variation filtering, see \ref NonLinearDiffusion and example <a href="total_variation_8cxx-example.html">total_variation.cxx</a>.
+      
+      <li> Fixed Python bindings of \ref Unsupervised_Decomposition.
+      
+      <li> Extended \ref vigra::SplineImageView to handle \ref vigra::TinyVector pixels.
+      
+      <li> Various convenience functions for vigranumpy's <a href="../vigranumpy/index.html#vigra.VigraArray">VigraArray</a>.
+      
+      <li> Minor improvements and bug fixes in the code and documentation. 
+ </ul>
+
+<b> Changes from Version 1.7.1 to 1.8.0</b>
+
+<ul>  
+      <li> Various extensions to \ref LocalMinMax (3D algorithms, on-the-fly thresholding).
+      
+      <li> Added \ref vigra::BucketQueue, \ref vigra::MappedBucketQueue.
+      
+      <li> Refactored and extended 2D watershed algorithms (especially watershedsRegionGrowing()).
+      
+      <li> Added the \ref vigra::Quaternion class.
+      
+      <li> Added \ref Unsupervised_Decomposition.
+      
+      <li> Added mathematical functions (even(), odd(), gamma(), loggamma(), legendre(), besselJ(), besselY(), 
+           linearSequence(), indexSort(), inversePermutation(), applyPermutation(), checksum())
+      
+      <li> Implemented wrapper of the <a href="http://www.fftw.org/">FFTW library</a> to support 
+           arbitrary dimensional Fourier transforms (see \ref fourierTransform() and \ref vigra::FFTWPlan)
+           and FFT-based convolution (see \ref convolveFFT() and \ref vigra::FFTWConvolvePlan) and 
+           refactored \ref vigra::FFTWComplex.
+     
+      <li> Added cannyEdgelListThreshold(), cannyEdgelList3x3Threshold().
+      
+      <li> Added capability to handle subarrays and anisotropic resolution to separableConvolveMultiArray()
+           and related Gaussian filters. Added <tt>windowRatio</tt> parameters to \ref vigra::Kernel1D::initGaussian()
+           and \ref vigra::Kernel1D::initGaussianDerivative()
+      
+      <li> Added \ref vigra::StridedScanOrderIterator and corresponding \ref vigra::MultiArrayView::begin().
+      
+      <li> Extended \ref vigra::MultiArrayView. Added \ref vigra::Shape1 ... \ref vigra::Shape5 convenience typedefs.
+      
+      <li> Implemented \ref MultiMathModule (arithmetic and algebraic functions for multi-dimensional arrays).
+      
+      <li> Extended the \ref vigra::HDF5File class.
+      
+      <li> Improved and documented the \ref TimingMacros.
+      
+      <li> Added support for the <a href="http://www.openexr.com/">OpenEXR image format</a> and multi-page TIFF. Improved 
+           support for the SIF format.
+      
+      <li> <b>vigranumpy</b>: added <a href="../vigranumpy/index.html#axistags-and-the-vigraarray-data-structure">axistags </a> 
+           and completly re-implemented VigraArray and the conversion between
+           Python and C++ arrays in terms of axistags.
+      
+      <li> Minor improvements and bug fixes in the code and documentation. 
+ </ul>
+
+<b> Changes from Version 1.7.0 to 1.7.1</b>
+
+<ul>  
+      <li> Fixed the build process for MacOS X.
+      
+      <li> Re-activated <tt>vigra-config</tt> (script to query VIGRA installation information) 
+           and added <tt>VigraConfig.cmake</tt> (query VIGRA installation information from
+           within cmake).
+      
+      <li> Added CDash support (nightly builds and tests).
+      
+      <li> Added \ref convexHull().
+      
+      <li> Added \ref vigra::Box.
+      
+      <li> Added \ref vigra::Sampler class to sample given data in various ways.
+      
+      <li> Added much new functionality to the \ref vigra::RandomForest class 
+           (e.g. more split strategies, variable importance measures, feature selection)
+      
+      <li> Added readSIF() (reader for the Andor SIF file format).
+      
+      <li> Added \ref vigra::HDF5File for easier navigation in HDF5 files.
+      
+      <li> Added recursive approximation of the Gaussian filter (\ref recursiveGaussianFilterX(), 
+           \ref recursiveGaussianFilterY())
+           
+      <li> vigranumpy: added Gabor filtering.
+      
+      <li> Fixed multi-threading bugs at various places.
+     
+      <li> Minor improvements and bug fixes in the code and documentation. 
+ </ul>
+
+<b> Changes from Version 1.6.0 to 1.7.0</b>
+
+<ul>  
+      <li> Incompatible changes: 
+      <ul>
+           <li> Modified angle convention from counter-clockwise to clockwise
+                (see e.g. \ref vigra::Edgel). This fits better with the left-handed coordinate system 
+                 we use.
+            
+            <li> \ref symmetricEigensystem(): sort eigenvalues by decreasing value
+                 (was: decreasing abs value)
+      </ul>
+      
+      <li> Implemented a new build system on the basis of <a href="http://www.cmake.org/">cmake</a>.
+      
+      <li> Added \ref vigra::NumpyAnyArray and \ref vigra::NumpyArray, improved \ref vigra::MultiArrayView.
+      
+      <li> Added <b><a href="../vigranumpy/index.html">vigranumpy</a></b> (VIGRA Python bindings).
+      
+      <li> Added \ref VigraMatlab.
+      
+      <li> Added support for <a href="http://www.hdfgroup.org/HDF5/">HDF5</a> import/export of arrays
+           (see \ref VigraHDF5Impex).
+      
+      <li> Added \ref vigra::RandomForest classifier.
+          
+      <li> Added constrained optimization functions: \ref nonnegativeLeastSquares(), 
+           \ref quadraticProgramming(), \ref leastAngleRegression() (LASSO and non-negative LASSO).
+          
+      <li> Added \ref choleskySolve() and improved \ref choleskyDecomposition() (in-place capability).
+      
+      <li> Added \ref symmetric2x2Eigenvalues() and \ref symmetric3x3Eigenvalues() for
+           fast eigenvalue computation on small matrices.
+      
+      <li> Added \ref meshGrid().
+      
+      <li> Added \ref vigra::FixedPoint16.
+      
+      <li> Minor improvements and bug fixes in the code and documentation. 
+</ul>
+
+<b> Changes from Version 1.5.0 to 1.6.0</b>
+
+<ul>  
+      <li> Added functions for arrays of arbitrary dimensions: 
+      <ul>
+          <li> \ref MultiArrayDistanceTransform "Euclidean distance transform"
+          <li> \ref MultiArrayMorphology "separable morphology"
+          <li> \ref resizeMultiArraySplineInterpolation()
+      </ul>    
+      
+      <li> Added functionality for 3D image analysis: \ref labelVolume(), \ref seededRegionGrowing3D(), 
+           \ref watersheds3D(), \ref VoxelNeighborhood
+          
+      <li> Added \ref RandomNumberGeneration
+          
+      <li> Added \ref affineWarpImage() and  and factory functions for 
+           affine transformation matrices
+          
+      <li> Added linear algebra functionality: \ref choleskyDecomposition(), \ref singularValueDecomposition(), 
+           \ref determinant(), \ref logDeterminant(), 
+           \ref leastSquares(), \ref weightedLeastSquares(), \ref ridgeRegression()
+          
+      <li> Extended \ref linearSolve(), \ref qrDecomposition(), and \ref inverse() to handle 
+           rectangular matrices (complete reimplementation of these functions).
+          
+      <li> Added matrix functionality: \ref joinVertically(), \ref joinHorizontally(), 
+           \ref columnStatistics(), \ref rowStatistics(), \ref prepareColumns(), \ref prepareRows()
+          
+      <li> Added/fixed \ref vigra::MultiArray and \ref vigra::linalg::Matrix computed assignments
+      
+      <li> Extended MultiArrayView::norm() to compute L1, L2 and Linfinity, added MultiArrayView::swapData(), 
+           MultiArrayView::permuteDimensions(), MultiArrayView::transpose(), and other minor improvements
+           to MultiArrayView
+          
+      <li> Added typedef \ref vigra::MultiArrayIndex to fix signed/unsigned mismatch problems
+          
+      <li> Added \ref vigra::ImagePyramid
+          
+      <li> Minor improvements in \ref VigraImpex
+          
+      <li> Added sRGB to \ref ColorConversions
+          
+      <li> Added weighted operator()s to FindAverage[AndVariance] functors.
+          
+      <li> Added \ref log2i() (integer base-2 logarithm), \ref floorPower2(), and \ref ceilPower2()
+          
+      <li> Added \ref argMin(), \ref argMax(), \ref argMinIf(), \ref argMaxIf()
+          
+      <li> Changed default border treatment of Gaussian filters and derivatives to BORDER_TREATMENT_REFLECT
+          
+      <li> Promoted documentation to Doxygen 1.5.6
+          
+      <li> Minor improvements and bug fixes in the code and documentation. 
+</ul>
+
+<b> Changes from Version 1.4.0 to 1.5.0</b>
+
+<ul>      
+      <li> Added \ref NoiseNormalization
+      
+      <li> Added \ref SlantedEdgeMTF
+      
+      <li> Added \ref gaussianGradientMagnitude()
+      
+      <li> Added \ref fourierTransform() and \ref fourierTransformInverse()
+      
+      <li> Added \ref cannyEdgelList3x3()
+      
+      <li> Added srcImage(), srcImageRange() etc. with ROI (see \ref ArgumentObjectFactories)
+      
+      <li> Improved the \ref VigraImpex (thanks to Pablo d'Angelo, Douglas Wilkins and others):
+      <ul>
+         <li> Added UINT16 and UINT32 pixel types.
+         <li> Added support for obtaining extra bands beyond RGB.
+         <li> Added support for a position field that indicates the start of this
+                image relative to some global origin  (PNG + TIFF).
+         <li> Added support for x and y resolution fields.
+         <li> Added support for ICC profiles (TIFF, PNG, and JPEG).
+         <li> Added support for deflate compression (PNG + TIFF).
+         <li> Added support for .hdr file format (high dynamic range).
+      </ul>
+      
+      <li> Improved support of 64-bit compilers. 
+      
+      <li> Added mathematical functions:  elliptic integrals (\ref ellipticIntegralF(), \ref ellipticIntegralE()),
+             chi-squared distribution (\ref chi2(), \ref chi2CDF(), \ref noncentralChi2(), \ref noncentralChi2CDF())
+      
+      <li> Dropped "vigra/" from \#includes in headers (so compiler will first look in the same directory).
+      
+      <li> Switched to relative paths in the MSVC project files. Compile vigraimpex into a DLL.
+      
+      <li> Bug fixes in the code and documentation. 
+</ul>
+
+<b> Changes from Version 1.3.3 to 1.4.0</b>
+
+<ul>      
+      <li> Switched to the MIT X11 License.
+      
+      <li> Introduced \ref FixedSizeInt (UInt8, Int16 etc.) and made VIGRA compile on 
+           64-bit compilers. Thanks to Hans Ekkehard Plesser 
+           <a href="mailto:hans.ekkehard.plesser at umb.no">hans.ekkehard.plesser at umb.no</a>)
+           for bug reports and other help. Added corresponding typedefs UInt8Image, 
+           Int16RGBImage etc.
+      
+      <li> Added NumericTraits::isSigned. Thanks to Pablo D'Angelo 
+           <a href="mailto:pablo.dangelo at web.de">pablo.dangelo at web.de</a>)
+           for a patch.
+      
+      <li> Added watersheds().
+      
+      <li> Added \ref cross() (cross product).
+      
+      <li> Added \ref cannyEdgeImageWithThinning().
+      
+      <li> Added the possibility to choose between 4- and 
+           8-neighborhood in \ref localMinima() and \ref localMaxima().
+      
+      <li> Added \ref vigra::FixedPoint.
+      
+      <li> Added \ref SquareRootTraits and sqrti().
+      
+      <li> Added \ref vigra::RestrictedNeighborhoodCirculator.
+      
+      <li> Extended \ref vigra::SplineImageView to support access outside the image
+           border according to reflective boundary conditions. Added partial
+           specializations for orders 0 and 1 to speed up computations.
+      
+      <li> Extended \ref vigra::RGBValue to have arbitrarily ordered color channels
+           (e.g. BGR). Thanks to Paul Furgale 
+           (<a href="mailto:umfurga1 at cc.umanitoba.ca">umfurga1 at cc.umanitoba.ca</a>) for the
+           suggestion and a first implementation.
+      
+      <li> Bug fixes in the code and documentation. Thanks to Holger Friedrich
+           (<a href="mailto:holger.friedrich at vsi.cs.uni-frankfurt.de">holger.friedrich at vsi.cs.uni-frankfurt.de</a>)
+           for patches.
+</ul>
+
+<b> Changes from Version 1.3.2 to 1.3.3</b>
+
+<ul>      
+      <li> Added \ref NormTraits, norm(), squaredNorm().
+      
+      <li> Added \ref gradientEnergyTensor()
+      
+      <li> Added the test suite to the distribution 
+          (see <a href="Installation.html">installation</a> section)
+      
+      <li> Bug fixes in the code and documentation.
+</ul>
+
+<b> Changes from Version 1.3.1 to 1.3.2</b>
+
+<ul>      
+      <li> Added \ref vigra::linalg::Matrix "Matrix class".
+      
+      <li> Added \ref LinearAlgebraFunctions "Matrix algebra,
+           solution of linear systems, eigenvalue computation".
+      
+      <li> Bug fixes in the code and documentation.
+</ul>
+
+<b> Changes from Version 1.3.0 to 1.3.1</b>
+
+<ul>      
+      <li> Fixed syntax for dependent types in templates to make VIGRA
+           compile with g++ 3.4 (which is very strict in enforcing
+           dependent type rules).
+      
+      <li> Added \ref vigra::FunctorTraits.
+      
+      <li> Added \ref vigra::ReduceFunctor.
+      
+      <li> Added reduce and expand modes to the 
+           \link MultiPointoperators multi-dimensional point operators\endlink.
+      
+      <li> Bug fixes in the code and documentation.       
+</ul>
+
+<b> Changes from Version 1.2.0 to 1.3.0</b>
+
+<ul>
+      <li> Added algorithms for \ref MultiDimensionalArrays :
+           \ref MultiPointoperators and \ref MultiArrayConvolutionFilters
+           and the \link vigra::MultiArrayNavigator navigator utility\endlink.
+      
+      <li> Extended \ref convolveImage() (non-separable convolution)
+           to support all \link BorderTreatmentMode border treatment modes\endlink.
+           
+      <li> Added \ref vigra::Rational
+           
+      <li> Added \ref vigra::Polynomial and \ref polynomialRoots().
+           
+      <li> Added more \link MathFunctions mathematical functions and functors\endlink.
+           
+      <li> Added \ref vigra::SplineImageView.
+      
+      <li> Added \link TensorImaging tensor image processing and analysis\endlink
+      
+      <li> Added 2nd order \ref recursiveFilterX() and \ref recursiveFilterY()
+      
+      <li> Added \ref ResamplingConvolutionFilters and reimplemented 
+           \ref resizeImageSplineInterpolation() in terms of them.
+      
+      <li> Added \link MultiArrayToImage multiarray to image wrappers\endlink.
+      
+      <li> Added \link GeometricTransformations image mirroring and rotation\endlink.
+      
+      <li> Added \link FourierTransform fftw3.hxx to support FFTW version 3\endlink
+           (unfortunately, this is incompatible to FFTW 2, which is still supported in
+           <tt>fftw.hxx</tt> but should no longer be used within VIGRA).
+           
+      <li> Added \ref vigra::ArrayVector as a <tt>std::vector</tt> alternative
+           whose memory is guaranteed to be one contiguous piece and whose
+           iterator is guaranteed to be a <tt>value_type *</tt>.
+      
+      <li> Added an <tt>allocator</tt> template parameters to all classes
+           that allocate dynamic memory.
+      
+      <li> Bug fixes in the code and documentation.       
+</ul>
+
+<b> Changes from Version 1.1.6 to 1.2.0</b>
+
+<ul>
+      <li> Complete redesign of the image import/export library. 
+      
+      <li> Added support for Microsoft Visual C++ 7.1 (.net 2003). 
+           This is the first Microsoft compiler that compiles VIGRA without
+           special configurations and work-arounds. Work-arounds for older
+           MS compilers will probably no longer be maintained.
+           
+      <li> Added support for PNG image format.
+           
+      <li> Added cygwin support to the build system.
+           
+      <li> Added \link PixelNeighborhood pixel neighborhood utilities \endlink 
+           and \ref vigra::NeighborhoodCirculator.
+      
+      <li> Added \ref vigra::CrackContourCirculator
+      
+      <li> Added \ref recursiveFilterX() and \ref recursiveFilterY() that
+           support negative filter coefficients and all
+           \link BorderTreatmentMode BorderTreatmenModes \endlink
+      
+      <li> Changed \ref gaussianSmoothing() to use BORDER_TREATMENT_REFLECT
+      
+      <li> Added \ref simpleSharpening() and \ref gaussianSharpening()
+      
+      <li> Added \ref vigra::Size2D, \ref vigra::Point2D, \ref vigra::Rect2D
+      
+      <li> Added \ref vigra::BasicImageView
+      
+      <li> Split "utilities.hxx" into "diff2d.hxx", 
+          "interpolating_accessor.hxx", "iteratortags.hxx", "mathutil.hxx", 
+          "metaprogramming.hxx", "tuple.hxx". "utilities.hxx" now includes 
+          these other files.
+      
+      <li> Added \ref MultiDimensionalArrays and \ref VolumeImpex
+      
+      <li> Redesigned \ref vigra::TinyVector, added \ref vigra::TinyVectorView       
+</ul>
+
+<b> Changes from Version 1.1.5 to 1.1.6</b>
+
+<ul>
+      <li> Restored VIGRA compatibility with Microsoft Visual C++ 6.0
+           (in addition to C++.net)       
+</ul>
+
+<b> Changes from Version 1.1.4 to 1.1.5</b>
+
+<ul>
+      <li> Added \ref vigra::ImageArray.
+           
+      <li> Added more corner detectors (see \ref CornerDetection).
+           
+      <li> Added local symmetry detector (see \ref SymmetryDetection).
+           
+      <li> Added Gabor filter code (see \ref GaborFilter).
+           
+      <li> Extended \link FunctorExpressions functor expression library \endlink.
+           
+      <li> Added \ref initImageWithFunctor().
+           
+      <li> Improved Gaussian derivative filters (higher accuracy, correct sign,
+           see \ref vigra#Kernel1D#initGaussianDerivative()).
+           
+      <li> Ported VIGRA to Microsoft VisualC++.net (however, this compiler
+           still doesn't support all VIGRA features, because it still
+           doesn't implement partial template specialization and
+           partial function ordering).
+           
+      <li> Finished the new build system.
+           
+      <li> Improved the documentation.       
+</ul>
+
+<b> Changes from Version 1.1.3 to 1.1.4</b>
+
+<ul>
+      <li> Added \ref FourierTransform "Fourier transform" support, 
+           and \ref vigra::FFTWComplex "FFTWComplex" complex number type.
+
+      <li> Added convolution convenience functions (see \ref CommonConvolutionFilters).
+
+      <li> Added \ref vigra::IteratorAdaptor template for quick and
+           easy generation of iterator adaptors.
+
+      <li> Used  \ref vigra::IteratorAdaptor to implement improved
+           row and column iterators for images.
+
+      <li> Added rowIterator() and columnIterator() functions
+           returning optimized iterator adapters to all 2D iterators 
+           (e.g. vigra::ImageIterator). Changed algorithms to make use 
+           of these new members.
+           
+      <li> Added rounding and clipping to accessor functions when
+           floating point values are converted to intergral numbers.
+           
+      <li> Added STL-compatible typedefs to all functors, iterators and 
+           vigra::BasicImage.
+           
+      <li> Removed ConstRowIterator and ConstColumnsIterator. Thanks
+           to the new typedefs, RowIterator and ColumnIterator are
+           automatically const when the underlying iterator was const. Thus,
+           separate const iterators are not necessary.
+
+      <li> Major performance tuning. Many algorithms now actually perform
+           as fast as their inflexible C counterparts. Thanks to
+           <a href="mailto:viola at merl.com">Paul Viola</a> for doing benchmarks.       
+</ul>
+
+<b> Changes from Version 1.1.2 to 1.1.3</b>
+
+<ul>
+      <li> Switched from obsolete 
+           <a href="http://www.zib.de/Visual/software/doc++/index.html">doc++</a>
+           documentation generator to
+           <a href="http://www.doxygen.org">doxygen</a>. 
+      
+      <li> Improved documentation.
+      
+      <li> Minor changes to the code to quiet compiler warnings if compiling with
+           "<TT>g++ -Wall -pedantic</TT>".
+           
+      <li> Dropped support for rint() as this was not portable enough.
+      
+      <li> In error.hxx: replaced snprintf() with sprintf() for portability.
+      
+      <li> Renamed CellGridImage into CrackEdgeImage in \ref EdgeDetection.
+      
+      <li> Added \ref vigra::TinyVector and made vigra::RGBValue derive from it.
+      
+      <li> Added typedefs for TinyVector images.
+     
+      <li> Added \ref ColorConversions.
+     
+      <li> Added \ref vigra::VectorComponentAccessor.
+     
+      <li> Extended \ref vigra::FindMinMax to work with RGB images.
+      
+      <li> Minor improvements and bug fixes.
+</ul>
+
+<b> Changes from Version 1.1.1 to 1.1.2</b>
+
+<ul>
+      <li> Made VIGRA compile under MS Visual C++ 6.0.
+      
+      <li> Added \ref vigra::BrightnessContrastFunctor.
+      
+      <li> Added \ref gradientBasedTransform() and related 
+            \ref vigra::MagnitudeFunctor and \ref vigra::RGBGradientMagnitudeFunctor.
+      
+      <li> Added \ref nonlinearDiffusion().
+      
+      <li> Added more smoothing methods to <a href="ExampleList.html">smooth</a> example.
+      
+      <li> Added <a href="ExampleList.html">resize</a> example.
+      
+      <li> Minor corrections and bug fixes.  
+</ul>
+
+<b> Changes from Version 1.1.0 to 1.1.1</b>
+
+<ul>
+      <li> Fixed bug with PNM import code.
+      
+      <li> added Canny edge detection algorithm (code adapted from 
+      C implementation by <a href="mailto:utcke at informatik.uni-hamburg.de">Sven Utcke</a>)
+</ul>
+
+<b> Changes from Version 1.0 to 1.1.0</b>
+
+<ul>
+      <li> Put everything in namespace "vigra".
+      
+      <li> Renamed <br>
+            VigraStdException => StdException.<br>
+            vigraImpexListFormats() => impexListFormats()
+      
+      
+      <li> Added expression templates for \ref FunctorExpressions "automated functor creation".
+
+      <li> Added support for input/output of the PNM image file format
+       (contributed by  
+        <a href="mailto:mamchisl at ucdavis.edu">Mikhail Amchislavsky</a>).
+
+      <li> Improved support for the \ref TIFFImpex "TIFF image format".
+            VIGRA can now read and create TIFF with various pixel types 
+            (unsigned byte, short and long int, float, double).
+            
+      <li> Renamed Dist2D into \ref vigra::Diff2D, since it represents a difference vector 
+            rather than a distance. Extended Diff2D so that it can also act as a 
+            \ref vigra::CoordinateIterator. Note that this 
+            required renaming <TT>Dist2D::width</TT> and <TT>Dist2D::height</TT> into <TT>Diff2D::x</TT> 
+            and <TT>Diff2D::y</TT> respectively.
+            
+      <li> Changed the documentation layout.
+      
+      <li> Improved \ref labelImage() according to ideas of Prof. 
+            Vladimir Kovalevsky.
+      
+      <li> Several minor changes and bug fixes.
+</ul>
+
+*/
diff --git a/docsrc/doxygen.css b/docsrc/doxygen.css
new file mode 100644
index 0000000..8496356
--- /dev/null
+++ b/docsrc/doxygen.css
@@ -0,0 +1,389 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+    font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+BODY,TD {
+       font-size: 90%;
+}
+H1 {
+    background-color: #e0d0a0;
+    padding: 0.5em;
+    text-align: center;
+       font-size: 160%;
+}
+H2 {
+       font-size: 200%;
+}
+H3 {
+       font-size: 100%;
+}
+CAPTION { font-weight: bold }
+DIV.qindex {
+    width: 100%;
+    background-color: #e8eef2;
+    border: 1px solid #84b0c7;
+    text-align: center;
+    margin: 2px;
+    padding: 2px;
+    line-height: 140%;
+}
+DIV.nav {
+    width: 100%;
+    background-color: #e8eef2;
+    border: 1px solid #84b0c7;
+    text-align: center;
+    margin: 2px;
+    padding: 2px;
+    line-height: 140%;
+}
+DIV.navtab {
+       background-color: #e8eef2;
+       border: 1px solid #84b0c7;
+       text-align: center;
+       margin: 2px;
+       margin-right: 15px;
+       padding: 2px;
+}
+TD.navtab {
+       font-size: 70%;
+}
+A.qindex {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D;
+}
+A.qindex:visited {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D
+}
+A.qindex:hover {
+    text-decoration: none;
+    background-color: #ddddff;
+}
+A.qindexHL {
+    text-decoration: none;
+    font-weight: bold;
+    background-color: #6666cc;
+    color: #ffffff;
+    border: 1px double #9295C2;
+}
+A.qindexHL:hover {
+    text-decoration: none;
+    background-color: #6666cc;
+    color: #ffffff;
+}
+A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.el { text-decoration: none; font-weight: bold }
+A:link { color: #0040b0; }
+A:visited { color: #a00040; }
+A.elRef { font-weight: bold }
+A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
+A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
+A.codeRef:link { font-weight: normal; color: #0000FF}
+A.codeRef:visited { font-weight: normal; color: #0000FF}
+A:hover { text-decoration: none; background-color: #f2f2ff }
+DL.el { margin-left: -1cm }
+.fragment {
+       font-family: monospace, fixed;
+       font-size: 95%;
+}
+PRE.fragment {
+    border: 1px solid #CCCCCC;
+    background-color: #f5f5f5;
+    margin-top: 4px;
+    margin-bottom: 4px;
+    margin-left: 2px;
+    margin-right: 8px;
+    padding-left: 6px;
+    padding-right: 6px;
+    padding-top: 4px;
+    padding-bottom: 4px;
+}
+DIV.line {
+	font-family: monospace, fixed;
+        font-size: 30px;
+	min-height: 13px;
+	line-height: 1.0;
+	text-wrap: unrestricted;
+	white-space: -moz-pre-wrap; /* Moz */
+	white-space: -pre-wrap;     /* Opera 4-6 */
+	white-space: -o-pre-wrap;   /* Opera 7 */
+	white-space: pre-wrap;      /* CSS3  */
+	word-wrap: break-word;      /* IE 5.5+ */
+	text-indent: -53px;
+	padding-left: 53px;
+	padding-bottom: 0px;
+	margin: 0px;
+	-webkit-transition-property: background-color, box-shadow;
+	-webkit-transition-duration: 0.5s;
+	-moz-transition-property: background-color, box-shadow;
+	-moz-transition-duration: 0.5s;
+	-ms-transition-property: background-color, box-shadow;
+	-ms-transition-duration: 0.5s;
+	-o-transition-property: background-color, box-shadow;
+	-o-transition-duration: 0.5s;
+	transition-property: background-color, box-shadow;
+	transition-duration: 0.5s;
+}
+DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
+
+DIV.groupHeader {
+       margin-left: 16px;
+       margin-top: 12px;
+       margin-bottom: 6px;
+       font-weight: bold;
+}
+DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
+BODY {
+    background: #f8f0e0;
+    color: black;
+    margin-right: 20px;
+    margin-left: 20px;
+}
+TD.indexkey {
+    background-color: #e8eef2;
+    font-weight: bold;
+    padding-right  : 10px;
+    padding-top    : 2px;
+    padding-left   : 10px;
+    padding-bottom : 2px;
+    margin-left    : 0px;
+    margin-right   : 0px;
+    margin-top     : 2px;
+    margin-bottom  : 2px;
+    border: 1px solid #CCCCCC;
+}
+TD.indexvalue {
+    background-color: #e8eef2;
+    font-style: italic;
+    padding-right  : 10px;
+    padding-top    : 2px;
+    padding-left   : 10px;
+    padding-bottom : 2px;
+    margin-left    : 0px;
+    margin-right   : 0px;
+    margin-top     : 2px;
+    margin-bottom  : 2px;
+    border: 1px solid #CCCCCC;
+}
+TR.memlist {
+   background-color: #f0f0f0;
+}
+P.formulaDsp { text-align: center; }
+IMG.formulaDsp { }
+IMG.formulaInl { vertical-align: middle; }
+SPAN.keyword       { color: #008000 }
+SPAN.keywordtype   { color: #604020 }
+SPAN.keywordflow   { color: #e08000 }
+SPAN.comment       { color: #800000 }
+SPAN.preprocessor  { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral   { color: #008080 }
+.mdescLeft {
+       padding: 0px 8px 4px 8px;
+    font-size: 80%;
+    font-style: italic;
+    background-color: #FAFAFA;
+    border-top: 1px none #E0E0E0;
+    border-right: 1px none #E0E0E0;
+    border-bottom: 1px none #E0E0E0;
+    border-left: 1px none #E0E0E0;
+    margin: 0px;
+}
+.mdescRight {
+       padding: 0px 8px 4px 8px;
+    font-size: 80%;
+    font-style: italic;
+    background-color: #FAFAFA;
+    border-top: 1px none #E0E0E0;
+    border-right: 1px none #E0E0E0;
+    border-bottom: 1px none #E0E0E0;
+    border-left: 1px none #E0E0E0;
+    margin: 0px;
+}
+.memItemLeft {
+    padding: 1px 0px 0px 8px;
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #E0E0E0;
+    border-right-color: #E0E0E0;
+    border-bottom-color: #E0E0E0;
+    border-left-color: #E0E0E0;
+    border-top-style: solid;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #FAFAFA;
+    font-size: 80%;
+}
+.memItemRight {
+    padding: 1px 8px 0px 8px;
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #E0E0E0;
+    border-right-color: #E0E0E0;
+    border-bottom-color: #E0E0E0;
+    border-left-color: #E0E0E0;
+    border-top-style: solid;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #FAFAFA;
+    font-size: 80%;
+}
+.memTemplItemLeft {
+    padding: 1px 0px 0px 8px;
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #E0E0E0;
+    border-right-color: #E0E0E0;
+    border-bottom-color: #E0E0E0;
+    border-left-color: #E0E0E0;
+    border-top-style: none;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #FAFAFA;
+    font-size: 80%;
+}
+.memTemplItemRight {
+    padding: 1px 8px 0px 8px;
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #E0E0E0;
+    border-right-color: #E0E0E0;
+    border-bottom-color: #E0E0E0;
+    border-left-color: #E0E0E0;
+    border-top-style: none;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #FAFAFA;
+    font-size: 80%;
+}
+.memTemplParams {
+    padding: 1px 0px 0px 8px;
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #E0E0E0;
+    border-right-color: #E0E0E0;
+    border-bottom-color: #E0E0E0;
+    border-left-color: #E0E0E0;
+    border-top-style: solid;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+       color: #606060;
+    background-color: #FAFAFA;
+    font-size: 80%;
+}
+.search     { color: #003399;
+              font-weight: bold;
+}
+FORM.search {
+              margin-bottom: 0px;
+              margin-top: 0px;
+}
+INPUT.search { font-size: 75%;
+               color: #000080;
+               font-weight: normal;
+               background-color: #e8eef2;
+}
+TD.tiny      { font-size: 75%;
+}
+a {
+    color: #1A41A8;
+}
+a:visited {
+    color: #2A3798;
+}
+.dirtab { padding: 4px;
+          border-collapse: collapse;
+          border: 1px solid #84b0c7;
+}
+TH.dirtab { background: #e8eef2;
+            font-weight: bold;
+}
+HR { height: 1px;
+     border: none;
+     border-top: 1px solid black;
+}
+
+/* Style for detailed member documentation */
+.memtemplate {
+  font-size: 80%;
+  color: #606060;
+  font-weight: normal;
+  margin-left: 3px;
+}
+.memnav {
+  background-color: #e8eef2;
+  border: 1px solid #84b0c7;
+  text-align: center;
+  margin: 2px;
+  margin-right: 15px;
+  padding: 2px;
+}
+.memitem {
+  padding: 4px;
+  background-color: #eef3f5;
+  border-width: 1px;
+  border-style: solid;
+  border-color: #dedeee;
+  -moz-border-radius: 8px 8px 8px 8px;
+}
+.memname {
+  white-space: nowrap;
+  font-weight: bold;
+}
+.memdoc{
+  padding-left: 10px;
+}
+.memproto {
+  background-color: #d5e1e8;
+  width: 100%;
+  border-width: 1px;
+  border-style: solid;
+  border-color: #84b0c7;
+  font-weight: bold;
+  -moz-border-radius: 8px 8px 8px 8px;
+}
+.paramkey {
+  text-align: right;
+}
+.paramtype {
+  white-space: nowrap;
+}
+.paramname {
+  color: #602020;
+  font-style: italic;
+  white-space: nowrap;
+}
+/* End Styling for detailed member documentation */
+
+/* for the tree view */
+.ftvtree {
+    font-family: sans-serif;
+    margin:0.5em;
+}
+.directory { font-size: 9pt; font-weight: bold; }
+.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; }
+.directory > h3 { margin-top: 0; }
+.directory p { margin: 0px; white-space: nowrap; }
+.directory div { display: none; margin: 0px; }
+.directory img { vertical-align: -30%; }
diff --git a/docsrc/examples.dxx b/docsrc/examples.dxx
new file mode 100644
index 0000000..8b25671
--- /dev/null
+++ b/docsrc/examples.dxx
@@ -0,0 +1,163 @@
+/** \page ExampleList Examples
+    
+    Demonstration programs for VIGRA's usage.
+    
+    Click on the hyperlinks to view the commented source code for the demos.
+    Most examples can be applied to both gray-scale and RGB images. 
+    See <a href="Installation.html">Installation</a> for instructions on how these
+    programs can be compiled. For convenience, the directory contains the test images 
+    <a href="lenna_gray.gif">lenna_gray.gif</a> and 
+    <a href="lenna_color.gif">lenna_color.gif</a>.
+    
+    <ul>
+    
+    <li> Convert an image file into another file type:
+    <a href="convert_8cxx-example.html">convert.cxx</a> <br>
+    Usage: <TT>convert infile outfile</TT>
+    
+    <li> Read an image file and write out a subimage:
+    <a href="subimage_8cxx-example.html">subimage.cxx</a> <br>
+    Usage: <TT>subimage infile outfile</TT>
+    
+    <li> Invert an image file (create a negative) using the function 
+    \ref transformImage():
+    <a href="invert_8cxx-example.html">invert.cxx</a> <br>
+    Usage: <TT>invert infile outfile</TT>
+    
+    <li> Invert an image file (create a negative) by coding the loop
+    explicitly:
+    <a href="invert_explicitly_8cxx-example.html">invert_explicitly.cxx</a> <br>
+    Usage: <TT>invert_explicitly infile outfile</TT>
+    
+    <li> Resize an image using \ref resizeImageSplineInterpolation():
+    <a href="resize_8cxx-example.html">resize.cxx</a> <br>
+    Usage: <TT>resize infile outfile</TT>
+    
+    <li> Smooth an image using \ref RecursiveConvolution functions:
+    <a href="smooth_8cxx-example.html">smooth.cxx</a> <br>
+    Usage: <TT>smooth infile outfile</TT>
+    
+    <li> Find the gray value profile along the image diagonal 
+    by means of a \ref vigra::LineIterator :
+    <a href="profile_8cxx-example.html">profile.cxx</a> <br>
+    Usage: <TT>profile infile</TT>, generates <TT>profile.gif</TT>
+
+    <li> Create series of slices through different color spaces.:
+    <a href="palette_8cxx-example.html">palette.cxx</a> <br>
+    Usage: <TT>palette lab</TT>, generates <TT>lab_*.gif</TT> (44 images)
+
+    <li> Reduce image size by mean of a Gaussian pyramid:
+    <a href="pyramid_8cxx-example.html">pyramid.cxx</a> <br>
+    Usage: <TT>pyramid infile outfile</TT>
+    
+    <li> Find edges by means of a 
+    \ref differenceOfExponentialEdgeImage():
+    <a href="edge_8cxx-example.html">edge.cxx</a> <br>
+    Usage: <TT>edge infile outfile</TT>
+    <li> Segment image by means of the watershed algorithm, using 
+    \ref seededRegionGrowing():
+    <a href="watershed_8cxx-example.html">watershed.cxx</a> <br>
+    Usage: <TT>watershed infile outfile</TT>
+    
+    <li> Generate a Voronoi diagram, using \ref distanceTransform() and
+    \ref seededRegionGrowing():
+    <a href="voronoi_8cxx-example.html">voronoi.cxx</a> <br>
+    Usage: <TT>voronoi</TT>, generates: <TT>distances.gif</TT> (Euclidean distance transform) and <TT>voronoi.gif</TT>
+    (Voronoi diagram)
+        
+    <li> Measure boundary and corner strengths with the 
+    \ref boundaryTensor():
+    <a href="boundarytensor_8cxx-example.html">boundarytensor.cxx</a> <br>
+    Usage: <TT>boundarytensor infile</TT>, creates <tt>boundarystrength.tif</tt> and <tt>cornerstrength.tif</tt>
+    
+    <li> Total Variation (TV) Regularization
+    <a href="total_variation_8cxx-example.html">total_variation.cxx</a> <br>
+    Usage: <TT>total_variation parameterfile</TT>
+    (cf. example parameter files *.par for standard TV regularization, anisotropic and second order TV)
+    
+    </ul>
+*/
+
+/** \example convert.cxx
+    Convert an image file into another file type
+    <br>
+    Usage: <TT>convert infile outfile</TT>
+*/
+
+/** \example subimage.cxx
+    Read an image file and write out a subimage
+    <br>
+    Usage: <TT>subimage infile outfile</TT>
+*/
+    
+/** \example invert.cxx
+    Invert an image file (create a negative) using the function 
+    \ref transformImage()
+    <br>
+    Usage: <TT>invert infile outfile</TT>
+*/
+    
+/** \example invert_explicitly.cxx
+    Invert an image file (create a negative) by coding the loop
+    explicitly
+    <br>
+    Usage: <TT>invert_explicitly infile outfile</TT>
+*/
+    
+/** \example resize.cxx
+    Resize an image using \ref resizeImageSplineInterpolation()<br>
+    Usage: <TT>resize infile outfile</TT>
+*/
+    
+/** \example smooth.cxx
+    Smooth an image using \ref RecursiveConvolution functions:
+    <a href="smooth.cxx-example.html">smooth.cxx</a> <br>
+    Usage: <TT>smooth infile outfile</TT>
+*/
+    
+/** \example profile.cxx
+    Find the gray value profile along the image diagonal 
+    by means of a \ref vigra::LineIterator<br>
+    Usage: <TT>profile infile</TT>, generates <TT>profile.gif</TT>
+*/
+
+/** \example palette.cxx
+    Create series of slices through different color spaces.
+    Usage: <TT>palette luv</TT>, generates <TT>luv_*.gif</TT> (44 images)
+*/
+
+/** \example pyramid.cxx
+    Reduce image size by mean of a Gaussian pyramid<br>
+    Usage: <TT>pyramid infile outfile</TT>
+*/
+    
+/** \example edge.cxx
+    Find edges by means of a 
+    \ref differenceOfExponentialEdgeImage()<br>
+    Usage: <TT>edge infile outfile</TT>
+*/
+    
+/** \example watershed.cxx
+    Segment image by means of the watershed algorithm, using 
+    \ref seededRegionGrowing()<br>
+    Usage: <TT>watershed infile outfile</TT>
+*/
+    
+/** \example voronoi.cxx
+    Generate a Voronoi diagram, using \ref distanceTransform() and
+    \ref seededRegionGrowing()<br>
+    Usage: <TT>voronoi</TT>, generates: <TT>distances.gif</TT> (Euclidean distance transform) and <TT>voronoi.gif</TT> (Voronoi diagram)
+*/
+
+/** \example boundarytensor.cxx        
+    Measure boundary and corner strengths with the 
+    \ref boundaryTensor():
+    <a href="boundarytensor.cxx-example.html">boundarytensor.cxx</a> <br>
+    Usage: <TT>boundarytensor infile</TT>, creates <tt>boundarystrength.tif</tt> and <tt>cornerstrength.tif</tt>
+*/
+
+/** \example total_variation.cxx
+       Smooth an image with Total Variation (TV) regularization (standard ROF model, anisotropic, second order)<br>
+       Usage: <TT>example_total_variation</TT> reads a given parameter file (see tv.par, aniso_tv.par, secondo_oder_tv.par 
+       in the examples subfolder) and performes a smoothing with TV regularization with the parameters given in this file.
+*/
diff --git a/docsrc/footer.html b/docsrc/footer.html
new file mode 100644
index 0000000..21d4ba0
--- /dev/null
+++ b/docsrc/footer.html
@@ -0,0 +1,24 @@
+<!-- footer.html -->
+<p>
+<table border=0 cellspacing=0 width="100%"  bgcolor="#e0d0a0" cellpadding=5>
+<tr>
+<td>
+<p>
+<i>© <A HREF="http://hci.iwr.uni-heidelberg.de/people/ukoethe/">Ullrich Köthe</A>     (<A
+HREF="mailto:ullrich.koethe at iwr.uni-heidelberg.de">ullrich.koethe at iwr.uni-heidelberg.de</A>)</i> <br>
+<i><A HREF="http://hci.iwr.uni-heidelberg.de/">
+Heidelberg Collaboratory for Image Processing</a>,
+University of Heidelberg, Germany</i>
+<td>
+<p align=right>
+<I>html generated using <A HREF="http://www.doxygen.org">doxygen</A> and <A HREF="http://www.python.org">Python</A></I>
+<br>
+<i>
+$projectname $projectnumber ($date)
+</i>
+</tr>
+</table>
+
+
+</BODY>
+</HTML>
diff --git a/docsrc/header.html b/docsrc/header.html
new file mode 100644
index 0000000..9072e1f
--- /dev/null
+++ b/docsrc/header.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head><TITLE>$projectname - $title</TITLE>
+<link rel=stylesheet type="text/css" href="vigra.css">
+<link rel=stylesheet type="text/css" href="vigra_1_8_2.css">
+<link rel="shortcut icon" href="vigra-icon.ico" />
+<script type="text/javascript">
+function toggleHiddenDocumentation( textID, toggleID, toggleMessage )
+{ 
+	if( document.getElementById(textID).style.display == 'none' )
+    {
+		document.getElementById(textID).style.display = 'block';
+        document.getElementById(toggleID).innerHTML = "hide " + toggleMessage;
+    }
+    else
+    {
+		document.getElementById(textID).style.display = 'none';
+        document.getElementById(toggleID).innerHTML = "show " + toggleMessage;
+	}
+    return false;
+}
+</script>
+</head>
+<body  bgcolor="#f8f0e0" link="#0040b0" vlink="#a00040">
+<basefont face="Helvetica,Arial,sans-serif" size=3>
+<p align=right>
+[ <a href="http://hci.iwr.uni-heidelberg.de/vigra/">VIGRA Homepage</a> |
+ <a href="functionindex.html">Function Index</a> |
+ <a href="classes.html">Class Index</a> |
+ <a href="namespaces.html">Namespaces</a> |
+ <a href="files.html">File List</a> |
+ <a href="index.html">Main Page</a> ]
+</p>
diff --git a/docsrc/image_processing.dxx b/docsrc/image_processing.dxx
new file mode 100644
index 0000000..f5d7cd9
--- /dev/null
+++ b/docsrc/image_processing.dxx
@@ -0,0 +1,354 @@
+/** \page ImageProcessingTutorial Image Processing
+
+    <h2>Section Contents</h2>
+    
+    In this chapter we'll use VIGRA's methods for some applications of Image Processing.
+
+    <ul style="list-style-image:url(documents/bullet.gif)">
+    <li> \ref CallingConventions
+    <li> \ref ImageInversion
+    <li> \ref ImageBlending
+    <li> \ref CompositeImage
+    <li> \ref SmoothingTutorial
+       <ul type="disc">
+        <li> \ref Convolve2DTutorial
+        <li> \ref SeparableConvolveTutorial
+        </ul>
+    </ul>
+
+    \section CallingConventions Calling Conventions
+    
+    VIGRA's image processing functions follow a uniform calling convention: The argument list start with the input images or arrays, followed by the output images or arrays, followed by the function's parameters (if any). Some functions additionally accept an option object that allows more fine-grained control of the function's actions and must be passed as the last argument. Most functions assume that the output arrays already have the appropriate shape.
+    
+    All functions working on arrays expect their arguments to be passed as \ref vigra::MultiArrayView instances. Functions that only support 2-dimensional images usually contain the term "Image" in their name, whereas functions that act on arbitrary many dimensions usually contain the term "Multi" in their name. <br/>
+    Examples: 
+    \code
+    // determine the connected components in a binary image, using the 8-neighborhood
+    MultiArray<2, UInt8>   image(width, height);
+    MultiArray<2, UInt32>  labels(width, height);
+    ... // fill image
+    labelImage(image, labels, true);
+    
+    // smooth a 3D array with a gaussian filter with sigma=2.0
+    MultiArray<3, float> volume(Shape3(300, 200, 100)),
+                         smoothed(Shape3(300, 200, 100));
+    ... // fill volume
+    gaussianSmoothMultiArray(volume, smoothed, 2.0);
+    
+     // compute the determinant of a 5x5 matrix
+    MultiArray<2, float> matrix(Shape2(5, 5));
+    ... // fill matrix with data
+    float det = linalg::determinant(matrix);
+    \endcode
+    
+    For historical reasons, VIGRA also supports two alternative APIs in terms of iterators. These APIs used to considerably faster, but meanwhile compilers and processors have improved to the point where the much simpler MultiArrayView API no longer imposes a significant abstraction penalty. While there are no plans to remove support for the old APIs, they should not be used in new code.
+    
+    <ul>
+    <li> Functions on 2-dimensional images may support an \ref ImageIterators API. These iterators are best passed to the functions via the convenience functions <tt>srcImageRange(array)</tt>, <tt>srcImage(array)</tt>, and <tt>destImage(array)</tt>. A detailed description of the convenience functions can be found in section \ref ArgumentObjectFactories. Example:
+    \code
+    // compute the pixel-wise square root of an image
+    MultiArray<2, float> input(Shape2(200, 100)),
+                         result(imput.shape());
+    ... // fill input with data
+    transformImage(srcImageRange(input), destImage(result), &sqrt);  // deprecated API
+    \endcode
+    
+    <li> Functions for arbitrary-dimensional arrays may support hierarchical \ref MultiIteratorPage. These iterators are best passed to the functions via the convenience functions <tt>srcMultiArrayRange(array)</tt>, <tt>srcMultiArray(array)</tt>, and <tt>destMultiArray(array)</tt>. A detailed description of these convenience functions can also be found in section \ref ArgumentObjectFactories. Example:
+    \code
+    // compute the element-wise square root of a 4-dimensional array
+    MultiArray<4, float> input(Shape4(200, 100, 50, 30)),
+                         result(imput.shape());
+    ... // fill input with data
+    transformMultiArray(srcMultiArrayRange(input), destMultiArray(result), &sqrt);  // deprecated API
+    \endcode
+    
+    \section ImageInversion Inverting an Image
+    
+    Inverting an (gray scale) image is quite easy. We just need to subtract every pixel's 
+    value from white (255). This simple task doesn't need an explicit function call at all, but is best solved with a arithmetic expression implemented in namespace \ref MultiMathModule. To avoid possible overload ambiguities, 
+    you must explicitly activate array arithmetic via the command <tt>using namespace vigra::multi_math</tt> before use. To invert <tt>imageArray</tt> and overwrite its original contents, you write:
+
+    \code
+    using namespace vigra::multi_math;
+    imageArray = 255-imageArray;
+    \endcode
+
+    See here for a complete example:
+    <a href="invert_tutorial_8cxx-example.html">invert_tutorial.cxx</a>
+
+    This is the result:
+    <Table cellspacing = "10">
+    <TR valign = "bottom">
+    <TD> \image html lenna_small.gif "input file" </TD>
+    <TD> \image html lenna_inverted.gif "inverted output file" </TD>
+    </TR>
+    </Table>
+
+    \section ImageBlending Image Blending
+    
+    In this example, we have two input images and want to blend them into one another. 
+    In the combined output image every pixel value is the mean of the two appropriate original pixels. This is also best solved with array arithmetic:
+
+    \code
+    using namespace vigra::multi_math;
+    exportArray = 0.5*imageArray1 + 0.5*imageArray2;
+    \endcode
+
+    Since it is not guaranteed that the two input images have the same shape, we first
+    determine the maximum possible shape of the blended image, which equals the minimum 
+    size along each axis. With the help of subarray-method we just blend the appropriate 
+    parts of the two images. These parts (subimages) are aligned around the centers 
+    of the original images.
+
+    Here's the code:
+    <a href="dissolve_8cxx-example.html">dissolve.cxx</a>
+
+    And here are the results:
+    <table cellspacing = "10">
+    <TR valign = "bottom">
+    <TD> \image html lenna_color_small.gif "input file 1" </TD>
+    <TD> \image html oi_small.jpg "input file 2" </TD>
+    <TD> \image html dissolved_color.gif "dissolved output file" </TD>
+    </TR>
+    </table>
+
+    \section CompositeImage Creating a Composite Image
+    
+    Let's come to a little gimmick. Given one input image we want to create a composite image 
+    of 4 images reflected with respect to each other. The result resembles the effect of a
+    kaleidoscope. Two of VIGRA's functions are sufficient for this purpose: \ref MultiArray_subarray 
+    and \ref reflectImage(). Input and output images of reflectImage() are specified by MultiArrayViews. 
+    The third parameter specifies the desired reflection axis. The axis can either
+    be horizontal, vertical or both (as in this example):
+
+    \code
+    reflectImage(inputArray, outputArray, horizontal | vertical);
+    \endcode
+
+    Here's the code:
+    <a href="composite_8cxx-example.html">composite.cxx</a>
+
+    And here are the results:
+    <Table cellspacing = "10">
+    <TR valign = "bottom">
+    <TD> \image html lenna_color_small.gif "input file" </TD>
+    <TD> \image html lenna_composite_color.gif "composite output file" </TD>
+    </TR>
+    </Table>
+
+    \section SmoothingTutorial Smoothing
+    
+    \subsection Convolve2DTutorial 2-dimensional Convolution
+    
+    There are many different ways to smooth an image. Before we use VIGRA's methods, we 
+    want to write a smoothing code of our own. The idea is to choose each pixel in turn and 
+    replace it with the mean of itself and the pixels in 5x5 window around it.
+    To calculate the mean in a window, we can just devide the sum of the pixel values 
+    within the corresponding subarray by their number. MultiArrayView provides two useful 
+    methods for doing this: <tt>sum</tt> and <tt>size</tt>. 
+    In our code we iterate over every pixel, construct the surrounding 5x5 window via 
+    <tt>subarray</tt>, and write the average of the window into the corresponding output pixel.
+    Near the borders of the image we truncate the window appropriately so that it remains
+    inside the image, and only take the average over the actually existing neighbours of the pixel.
+
+    See the code:
+    <a href="smooth_explicitly_8cxx-example.html">smooth_explicitly.cxx</a>
+
+    The results:
+    <Table cellspacing = "10">
+    <TR valign = "bottom">
+    <TD> \image html lenna_small.gif "input file" </TD>
+    <TD> \image html lenna_smoothed.gif "smoothed output file" </TD>
+    </TR>
+    </Table>
+
+    The technical term for this kind of operation is <i>convolution</i>. VIGRA provides 
+    <dfn>convolveImage</dfn> as a comfortable way to perform 2-dimensional convolutions 
+    with arbitrary filters. You may use it as follows:
+
+    \code
+    convolveImage(inputImage, resultImage, filter);
+    \endcode
+
+    The filter of <i>convolution kernel</i> is given as argument object by <dfn>kernel2d()</dfn>.
+    To implement the above smoothing by taking averages in 3x3 windows, you need an averaging 
+    kernel with radius 1. Kernel truncation near the image borders is performed when the 
+    filter's border treatment mode is set to <tt>BORDER_TREATMENT_CLIP</tt>:
+    
+    \code
+    Kernel2D<double> filter;
+    filter.initAveraging(1);
+    filter.setBorderTreatment(BORDER_TREATMENT_CLIP);
+    \endcode
+    
+    By default, VIGRA's convolution functions use <tt>BORDER_TREATMENT_REFLECT</tt> (i.e. the
+    image is virtually enlarged by reflecting the pixel values about the border), which usually
+    leads to superior results. The strength of smoothing can be controlled by increasing the filter 
+    radius.
+    
+    Another improvement over simple averaging can be achieved when one takes a <i>weighted 
+    average</i> such that pixels near the center have more influence on the result.
+    A popular choice here is the 5x5 binomial filter. VIGRA allows to specify arbitrary filter
+    shapes and coefficients via the <tt>Kernel2D::initExplicitly()</tt>:
+    
+    \code
+    Kernel2D<float> filter;
+    
+    // specify filter shape (lower right corner is inclusive here!)
+    filter.initExplicitly(Shape2(-2,-2), Shape2(2,2));
+    
+    // specify filter coefficients
+    filter =  1.0/256.0,  4.0/256.0,  6.0/256.0,  4.0/256.0,  1.0/256.0,
+              4.0/256.0, 16.0/256.0, 24.0/256.0, 16.0/256.0,  4.0/256.0,
+              6.0/256.0, 24.0/256.0, 36.0/256.0, 24.0/256.0,  6.0/256.0,
+              4.0/256.0, 16.0/256.0, 24.0/256.0, 16.0/256.0,  4.0/256.0,
+              1.0/256.0,  4.0/256.0,  6.0/256.0,  4.0/256.0,  1.0/256.0;
+              
+    // apply filter
+    convolveImage(inputImage, resultImage, filter);
+    \endcode
+   
+    <tt>initExplicitly()</tt> receives the upper left and lower right corners of the 
+    filter window. Note that the lower right corner here is <i>included</i> in the window,
+    in contrast to <tt>MultiArray::subarray()</tt> where the end point is not included. 
+
+    The filter weights are provided in a comma separated list. Normally, the sum of the 
+    coefficients should to be 1 in order to preserve the average intensity of the image. 
+    You must provide either as many coefficients as needed for the given filter size, 
+    or exactly one value which will be used for all filter coefficients. Thus, the 3x3 
+    averaging filter can also be created like this:
+    
+    \code
+    Kernel2D<double> filter;
+    filter.initExplicitly(Shape2(-1,-1), Shape2(1,1)) = 1.0/9.0;
+    \endcode
+
+    For various theoretical and practical reasons, the Gaussian filter is the best choice
+    in most situations. Its coefficients are chosen according to a Gaussian (i.e. 
+    bell-shaped) function with given standard deviation. The kernel class has a 
+    convenient <dfn>initGaussian(std_dev)</dfn> method that creates the appropriate 
+    coefficients:
+
+    \code
+    vigra::Kernel2D<float> filter; 
+    filter.initGaussian(1.5);
+    convolveImage(inputImage, resultImage, filter);
+    \endcode
+    
+    A complete example using these possibilities can be found in <a href="smooth_convolve_8cxx-example.html">smooth_convolve.cxx</a>.
+
+    <hr>
+
+    \subsection SeparableConvolveTutorial Separable Convolution in 2D and nD Images
+    
+    When filtering is implemented with 2-dimensional windows as in the previous section, 
+    we need as many multiplications per pixel as there are coefficients in the filter. 
+    Fortunately, many important filters (including averaging and Gaussian smoothing) 
+    have the property of beeing <i>separable</i>, which allows a much more efficient 
+    implementation in terms  of 1-dimensional windows. A 2-dimensional filter is 
+    separable if its coefficients \f$f_{ij}\f$ can be expressend as an outer product 
+    of two 1-dimensional filters \f$h_i\f$ and \f$c_j\f$:
+
+    \f[
+        f_{ij} = h_i \cdot c_j
+    \f]
+    
+    For example, the 3x3 averaging filter (with coefficients 1/9) is obtained as the outer 
+    product of two 3x1 filters (with coefficients 1/3):
+    
+    \f[ \left( \begin{array}{ccc} \frac{1}{9} & \frac{1}{9} & \frac{1}{9} \\[1ex] 
+                                  \frac{1}{9} & \frac{1}{9} & \frac{1}{9} \\[1ex] 
+                                  \frac{1}{9} & \frac{1}{9} & \frac{1}{9} \end{array} \right) = 
+    \left( \begin{array}{c} \frac{1}{3} \\[1ex]  \frac{1}{3} \\[1ex]  \frac{1}{3} \end{array} \right)  \cdot
+    \left( \begin{array}{ccc} \frac{1}{3} & \frac{1}{3} & \frac{1}{3} \end{array} \right)
+    \f]
+    
+    The convolution with separable filters can be implemented by two consecutive 1-dimensional
+    convolutions: first, one filters all rows of the image with the horizontal filter, and then
+    all columns of the result with the vertical filter. Instead of the (n x m) operations required
+    for a 2-dimensional window, we now only need (n + m) operations for the two 1-dimensional ones.
+    Already for a 5x5 window, this reduces the number of operations from 25 to 10, and the difference
+    becomes even bigger with increasing window size.
+    
+    To construct and apply 1-dimensional filters, VIGRA provides the class \ref vigra::Kernel1D and
+    the functions separableConvolveX() resp. separableConvolveY(). To compute a 2D Gaussian filter
+    we use the following code:
+
+    \code
+    Kernel1D<double> filter; 
+    filter.initGaussian(1.5);
+    
+    MultiArray<2, float> tmpImage(inputImage.shape());
+    separateConvolveX(inputImage, tmpImage, filter);
+    separateConvolveY(tmpImage, resultImage, filter);
+    \endcode
+
+    Note that we need an intermediate image to hold the result of the horizontal filtering.
+    The same result is more conveniently achieved by the functions \ref convolveImage() and
+    \ref gaussianSmoothing() (see <a href="smooth_convolve_8cxx-example.html">smooth_convolve.cxx</a>
+    for a working example):
+    
+    \code
+    // apply 'filter' to both the x- and y-axis 
+    // (calls separateConvolveX() and separateConvolveY() internally)
+    convolveImage(inputImage, resultImage, filter, filter);
+    
+    // smooth image with Gaussian filter with sigma=1.5
+    // (calls convolveImage() with Gaussian filter internally)
+    gaussianSmoothing(inputImage, resultImage, 1.5);
+    \endcode
+
+    It is, of course, also possible to apply different filters in the x- and y-directions. 
+    This is especially useful for derivative filters which are commonly used to compute
+    image features, for example \ref gaussianGradient() and \ref gaussianGradientMagnitude().
+    For more information see \ref CommonConvolutionFilters and \ref Convolution.
+    
+    Separable filters are also the key for efficient convolution of higher-dimensional images
+    and arrays: An n-dimensional filter is simply implemented by n consecutive 1-dimensional 
+    filter applications, regardsless of the size of n. This is the basis for VIGRA's 
+    multi-dimensional filter functions. For example, Gaussian smoothing in arbitrary many
+    dimensions is implemented in \ref gaussianSmoothMultiArray():
+    
+    \code
+    MultiArray<3, UInt8> inputArray(Shape3(100, 100, 100));
+    ... // fill inputArray with data
+    
+    MultiArray<3, float> resultArray(inputArray.shape());
+    
+    // perform isotropic Gaussian smoothing at scale 1.5
+    gaussianSmoothMultiArray(inputArray, resultArray, 1.5);
+    \endcode
+    
+    More information about VIGRA's multi-dimensional convolution funcions can be found in
+    the reference manual under \ref MultiArrayConvolutionFilters .
+*/
+
+/** \example invert_tutorial.cxx
+    Invert an image file (gray scale or color)
+    <br>
+    Usage: <TT>invert infile outfile</TT>
+*/
+
+/** \example dissolve.cxx
+    Dissolve two image files (gray scale or color)
+    <br>
+    Usage: <TT>dissolve infile1 infile2 outfile</TT>
+*/
+
+/** \example composite.cxx
+    Create a composite image (gray scale or color)
+    <br>
+    Usage: <TT>composite infile outfile</TT>
+*/
+
+/** \example smooth_explicitly.cxx
+    Smooth an image by averaging a 5x5-box (gray scale or color)
+    <br>
+    Usage: <TT>smooth_explicitly infile outfile</TT>
+*/
+
+/** \example smooth_convolve.cxx
+    Convolve an image in different ways (gray scale or color)
+    <br>
+    Usage: <TT>smooth_convolve infile outfile</TT>
+*/
diff --git a/docsrc/index.dxx b/docsrc/index.dxx
new file mode 100644
index 0000000..109aea1
--- /dev/null
+++ b/docsrc/index.dxx
@@ -0,0 +1,601 @@
+/** \mainpage VIGRA Reference Manual
+
+    <UL style="list-style-image:url(documents/bullet.gif)">
+    <LI> \ref Installation
+        <BR>   <em>how to get started</em>
+	<LI> \ref Tutorial
+		<BR>   <em>first steps with VIGRA</em>
+    <LI> \ref Concepts
+        <BR>   <em>generic interface definitions</em>
+    <LI> \ref Utilities
+        <BR>   <em>Basic helper functionality needed throughout</em>
+    <LI> \ref ErrorReporting
+        <BR>   <em>Exceptions and assertions</em>
+    <LI> \ref MathFunctionality
+        <BR>   <em>Number types, mathematical constants and functions, linear algebra etc.</em>
+    <LI> \ref PixelTypes
+        <BR>   <em>Non-scalar types such as RGBValue and TinyVector</em>
+    <LI> \ref ImageDataStructures
+        <BR>   <em>Images, image iterators, and supporting types and functions</em>
+    <LI> \ref MultiDimensionalArrays
+        <BR>   <em>Arrays, iterators, and supporting types and functions
+             for arbitrary dimensions</em>
+    <LI> \ref GraphDataStructures
+        <BR>   <em>Grid graphs and supporting types and functions
+             for arbitrary dimensions</em>
+    <LI> \ref ImportExport
+        <BR>   <em>Conversion from and to other image data types</em>
+    <LI> \ref ColorConversions
+        <BR>   <em>Convert between RGB and other color spaces, such as L*u*v*, Y'PbPr</em>
+    <LI> \ref ImageProcessing
+        <BR>   <em>Point operators, image arithmetic, convolution, morphology</em>
+    <LI> \ref ImageAnalysis
+        <BR>   <em>Segmentation and feature extraction algorithms</em>
+    <LI> \ref MachineLearning
+        <BR>   <em>Classification algorithms</em>
+    <LI> \ref ExampleList
+        <BR>   <em>Demonstration programs for VIGRA's usage </em>
+    <LI> \ref VigraMatlab
+        <BR>   <em>VIGRA Matlab bindings</em>
+    <LI> <b><a href="../vigranumpy/index.html">vigranumpy</a></b>
+        <BR>   <em>VIGRA Python bindings</em>
+    <LI> \ref CreditsChangelog
+        <BR>   <em>Who contributed what?</em>
+    </UL>
+
+    \anchor _details
+    <CENTER>
+    \section Main VIGRA - Vision with Generic Algorithms
+    Version  \vigra_version
+    by <a href="http://hci.iwr.uni-heidelberg.de/people/ukoethe/">Ullrich Köthe</a>
+    </CENTER>
+
+    VIGRA  is a computer vision library that puts its main emphasis on
+    <em>flexible algorithms</em>, because
+    algorithms represent the principle know-how of this field.
+    The library was consequently built
+    using <em>generic programming</em> as introduced by Stepanov
+    and Musser  and exemplified in the C++
+    <a href=\stl_link>Standard Template Library</a>.
+    By writing a few adapters (image iterators and accessors)
+    you can use VIGRA's algorithms on top of
+    <em>your</em> data structures, within <em>your</em> environment. Alternatively,
+    you can also use the data structures provided within VIGRA, which can
+    be easily adapted to a wide range of applications. VIGRA's flexibility
+    comes almost for free: Since the design uses compile-time polymorphism
+    (templates), performance of the compiled program approaches that
+    of a traditional, hand tuned, inflexible, solution.
+
+    VIGRA's design is documented in the chapter <em>"Reusable Software in
+    Computer Vision"</em> by
+    <a href="http://hci.iwr.uni-heidelberg.de/people/ukoethe/">Ullrich Köthe</a>,
+    in: B. Jähne, H. Haußecker, P. Geißler: "Handbook on
+    Computer Vision and  Applications", volume 3, Academic Press, 1999.
+    If you don't have the book,  you may read a
+    <a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/GenericProg2D.ps">draft of this article</a>. A shorter
+    article <em><a href="http://hci.iwr.uni-heidelberg.de/people/ukoethe/papers/index.php#cite_GenericProg2DCppReport">STL Style Generic Programming with Images</a></em>
+    describing some of the
+    ideas has appeared in the January 2000 issue of
+    <a href="http://www.creport.com/">C++ Report Magazine</a>. The most comprehensive source of information is
+    U. Köthe's PhD thesis <em><a href="http://hci.iwr.uni-heidelberg.de/people/ukoethe/papers/index.php#cite_PhD">Generische Programmierung für die Bildverarbeitung</a></em>, but this is written in German.
+
+    VIGRA is subject to this <a href="LICENSE.txt">LICENSE</a>.
+
+    You can also subscribe to the <a href="https://mailhost.informatik.uni-hamburg.de/mailman/listinfo/vigra">VIGRA Mailing List</a> to get instant information about new releases, discuss VIGRA's features and development, and ask the experts for help.
+
+
+
+*/
+
+/** \page Concepts Concepts
+
+    <DL>
+    <DT>
+    Description of the generic interface concepts used within VIGRA.
+    <DD>
+        <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref AlgebraicConcepts
+             <BR>   <em>Requirements for types that implement arithmetic operations</em>
+        <LI> \ref ImageIterators
+             <BR>   <em>Requirements for 2D iterators</em>
+        <LI> \ref MultiIteratorPage
+             <BR>   <em>Iterators for multi-dimensional arrays</em>
+        <LI> \ref DataAccessors
+             <BR>   <em>Requirements for data accessors</em>
+        <LI> \ref vigra::FunctorTraits
+             <BR>   <em>Requirements for functor traits</em>
+        <LI> \ref CrackEdgeImage
+        </UL>
+    </DL>
+*/
+
+/** \page MathFunctionality Mathematical tools
+
+    <b>Number types, mathematical constants, special functions, linear algebra</b>
+    <p>
+    <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref AlgebraicConcepts
+             <BR>   <em>Requirements for types that implement arithmetic operations</em>
+        <LI> \ref NumericPromotionTraits
+             <BR>   <em>Meta-information about arithmetic types</em>
+        <LI> \ref MathConstants
+             <BR>   <em>M_PI, M_SQRT2</em>
+        <LI> <b>Grid Neighborhood Specification</b>
+             <UL style="list-style-image:url(documents/bullet.gif)">
+             <LI> \ref PixelNeighborhood "2-dimensional" (4- and 8-neighborhood)
+             <LI> \ref VoxelNeighborhood "3-dimensional" (6- and 26-neighborhood)
+             </UL>
+        <LI> <b>Number Types</b>
+            <UL style="list-style-image:url(documents/bullet.gif)">
+            <LI> \ref vigra::Rational
+            <LI> \ref vigra::TinyVector
+            <LI> \ref vigra::autodiff::DualVector
+            <LI> \ref vigra::FFTWComplex
+            <LI> \ref vigra::FixedPoint16
+            <LI> \ref vigra::Quaternion
+            </UL>
+        <LI> \ref RandomNumberGeneration
+             <BR>   <em>Mersenne twister class and random number functors</em>
+        <LI> \ref Polynomials
+             <BR>   <em>Polynomials and root determination</em>
+        <LI> \ref MathFunctions
+             <BR>   <em>and functors</em>
+        <LI> \ref vigra::linalg::Matrix "Matrix class"
+             <BR>   <em>the matrix class</em>
+        <LI> \ref LinearAlgebraModule "Linear Algebra"
+             <BR>   <em>matrix algebra, solution of linear systems, eigenvalue calculation etc.</em>
+        <LI> \ref Unsupervised_Decomposition "Unsupervised Decomposition"
+             <BR>   <em>Unsupervised matrix decomposition methods (pLSA)</em>
+        <LI> \ref Optimization "Optimization and Regression"
+             <BR>   <em>ordinary and non-negative least squares, ridge regression, least angle regression (LARS and LASSO)</em>
+    </UL>
+
+*/
+
+/** \page PixelTypes Pixel Types
+
+    <DL>
+    <DT>
+    <b>Scalar types</b>
+    <DD>
+        <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref FixedSizeInt
+        <LI> \ref vigra::Rational
+        <LI> \ref vigra::FixedPoint
+        <LI> \ref vigra::FixedPoint16
+        </UL>
+        <p>
+    <DT>
+    <b>RGB colors and related functionality</b>
+    <DD>
+        <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref vigra::RGBValue
+        <LI> \ref RGBValueTraits
+        <LI> \ref RGBValueOperators
+        <LI> \ref RGBValueAccessors
+        </UL>
+        <p>
+    <DT>
+    <b>Fixed-size vectors and related functionality</b>
+    <DD>
+        <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref vigra::TinyVector
+        <LI> \ref vigra::TinyVectorView
+        <LI> \ref TinyVectorTraits
+        <LI> \ref TinyVectorOperators
+        </UL>
+        <p>
+    <DT>
+    <b>Complex Numbers</b>
+    <DD>
+        <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref vigra::FFTWComplex
+        <LI> \ref FFTWComplexTraits
+        <LI> \ref FFTWComplexOperators
+        <LI> \ref FFTWComplexAccessors
+        </UL>
+    </DL>
+*/
+
+/** \page ImageDataStructures Image Data Structures and Iterators
+
+    <UL style="list-style-image:url(documents/bullet.gif)">
+    <LI> \ref vigra::BasicImage
+         <BR>   <em>Fundamental class template for images </em>
+    <LI> \ref vigra::BasicImageView
+         <BR>   <em>Class template for images that use external memory</em>
+    <LI> \ref StandardImageTypes
+         <BR>   <em>The most common instantiations of \ref vigra::BasicImage</em>
+    <LI> \ref vigra::SplineImageView
+         <BR>   <em>Wrap a discrete image as a continous function</em>
+    <LI> \ref VigraImpex
+         <BR>   <em>Image import/export</em>
+    <LI> \ref ImageContainers
+         <BR>   <em>Classes to manage multiple images (ImageArray..)</em>
+    <LI> \ref PixelNeighborhood
+         <BR>   <em>Easy access to the 4- and 8-neighbors of a pixel</em>
+    <LI> \ref ImageIterators
+         <BR>   <em>Basic image iterator implementations </em>
+    <LI> \ref ImageIteratorAdapters
+         <BR>   <em>Iterate over rows, columns, and other image subsets </em>
+    <LI> \ref DataAccessors
+         <BR>   <em>Basic templates to encapsulate access to the data of an iterator</em>
+    <LI> \ref ArgumentObjectFactories
+         <BR>   <em>Factory functions to create argument objects which simplify long argument lists </em>
+    </UL>
+*/
+
+/** \page MultiDimensionalArrays Multi-Dimensional Arrays and Iterators
+
+    <UL style="list-style-image:url(documents/bullet.gif)">
+    <LI> \ref vigra::MultiArrayView
+         <BR>   <em>Interface for multi-dimensional arrays </em>
+    <LI> \ref vigra::MultiArray
+         <BR>   <em>Array class that holds the actual memory</em>
+    <LI> \ref MultiMathModule
+         <BR>   <em>Arithmetic and algebraic expressions for multi-dimensional arrays</em>
+    <LI> \ref MultiArrayTags
+         <BR>   <em>Meta-programming tags to mark array's as strided or unstrided</em>
+    <LI> \ref MultiIteratorPage
+         <BR>   <em>Iterators for multi-dimensional arrays</em>
+    <LI> \ref vigra::MultiArrayNavigator
+         <BR>   <em>Navigator utility for multi-dimensional arrays</em>
+    <LI> \ref VolumeImpex
+         <BR>   <em>Import/export of volume data.</em>
+    <LI> \ref MultiPointoperators
+         <BR>   <em>Point operators on multi-dimensional arrays</em>
+    <LI> \ref MultiArrayConvolutionFilters
+         <BR>   <em>Convolution filters in arbitrary dimensions</em>
+    <LI> \ref FourierTransform
+         <BR>   <em>Fast Fourier transform for arrays of arbitrary dimension</em>
+    <LI> \ref resizeMultiArraySplineInterpolation()
+         <BR>   <em>Interpolation of arrays in arbitrary dimensions</em>
+    <LI> \ref MultiArrayDistanceTransform 
+         <BR>   <em>Separable distance transform for arrays of arbitrary dimension</em>
+    <LI> \ref MultiArrayMorphology 
+         <BR>   <em>Separable morphology with parabola structuring function for arrays of arbitrary dimension</em>
+    <LI> \ref labelVolume(), \ref seededRegionGrowing3D(), \ref watersheds3D(), \ref localMinima3D(), \ref localMaxima3D(),
+         <BR>   <em>3-dimensional image (i.e. volume) analysis</em>
+    <LI> \ref VoxelNeighborhood
+         <BR>   <em>Easy access to the 6- and 26-neighbors of a voxel</em>
+    <LI> \ref vigra::NumpyArray and \ref vigra::NumpyAnyArray
+         <BR>   <em>Provide the VIGRA multi array interface Python arrays</em>
+    </UL>
+*/
+
+/** \page ImportExport Image Import and Export
+
+    Conversion from and to other image data types
+
+    <UL style="list-style-image:url(documents/bullet.gif)">
+    <LI> \ref VigraImpex
+         <BR>   <em>VIGRA's highlevel image import/export interface</em>
+    <LI> \ref VolumeImpex
+         <BR>   <em>Import/export interface for volume data</em>
+    <LI> \ref VigraHDF5Impex 
+         <BR>   <em>Import/export of images and arrays in 
+         <a href="http://www.hdfgroup.org/HDF5/">HDF5</a> format</em>
+    <LI> \ref TIFFImpex
+         <BR>   <em>image import/export interface if you want to call libtiff functions directly</em>
+    </UL>
+
+    There are two fundamentally different approaches to interfacing between VIGRA and the rest of the world.
+
+    <b>If you already have an image data type in your system:</b>
+
+    Then I recommend using VIGRA's algorithms directly on top of your data type.
+    To do this, you simply wrap your data in an \ref vigra::ImageIterator and/or 
+    \ref vigra::MultiArrayView (depending on the functions you want to call). If 
+    your data have some exotic properties, that prevent this solution from working,
+    you can still implement your own versions or subclasses of the interface classe,
+    which isn't very difficult.
+
+    Alternatively, you may use the data structures provided within VIGRA
+    and convert your data type into one of them. Take a look at \ref tiffToScalarImage() and
+    \ref createScalarTiffImage() to see how this might be done.
+
+    <b>If you don't have an image data type in your system:</b>
+
+    Use the data structures provided within VIGRA and use one of the import/export facilities above.
+
+*/
+
+/** \page ImageProcessing Image Processing
+
+    <UL style="list-style-image:url(documents/bullet.gif)">
+    <LI> \ref PointOperators
+         <BR>   <em>algorithms and functors for image arithmetic, inspection, transformations etc.</em>
+    <LI> \ref MultiMathModule
+         <BR>   <em>Arithmetic and algebraic expressions for multi-dimensional arrays</em>
+    <LI> \ref FunctorExpressions
+         <BR>   <em>Expression templates for automated functor creation</em>
+    <LI> \ref GeometricTransformations "Resize and Other Geometric Image Transformations"
+         <BR>   <em>resize and interpolation, image mirroring, rotation, arbitrary affine transformations</em>
+    <LI> \ref vigra::SplineImageView
+         <BR>   <em>Wrap a discrete image as a continous function</em>
+    <LI> \ref Convolution
+         <BR>   <em>1D, 2D, and nD filters, including separable and recursive convolution</em>
+    <LI> \ref NonLinearDiffusion
+         <BR>   <em>Edge-preserving smoothing and denoising</em>
+    <LI> \ref FourierTransform
+         <BR>   <em>forward and backward FFT, cosine transform, and related
+                 functionality</em>
+    <LI> \ref GaborFilter
+         <BR>   <em>Gabor filter generation and related
+                 functionality</em>
+    <LI> \ref TensorImaging
+         <BR>   <em>Tensor image processing</em>
+    <LI> \ref Morphology
+         <BR>   <em>erosion, dilation, and median with disc structuring functions</em>
+    <LI> \ref NoiseNormalization
+         <BR>   <em>transform intensity-dependent noise into additive Gaussian noise</em>
+    <LI> \ref SlantedEdgeMTF
+         <BR>   <em>determine the magnitude transfer function (MTF) of a camera using the slanted edge method</em>
+    </UL>
+*/
+
+/** \page ImageAnalysis Image Analysis
+
+    <UL style="list-style-image:url(documents/bullet.gif)">
+    <LI> \ref InspectAlgo and \ref InspectFunctor
+         <BR>   <em>Statistical analysis of images and regions</em>
+     <LI> \ref FeatureAccumulators
+         <BR>   <em>Computation of global and per-region statistics of multi arrays via accumulators framework</em>
+   <LI> \ref vigra::Threshold
+         <BR>   <em>Good old thresholding</em>
+    <LI> \ref Labeling
+         <BR>   <em>Connected components labeling using 4 or 8 connectivity </em>
+    <LI> \ref LocalMinMax
+         <BR>   <em>Including extremal plateaus larger than 1 pixel</em>
+    <LI> \ref DistanceTransform
+         <BR>   <em>Distance transform using Euclidean, Manhattan, or chessboard metrics </em>
+    <LI> \ref TensorImaging
+         <BR>   <em>Tensor image analysis</em>
+    <LI> \ref EdgeDetection
+         <BR>   <em>Edge detectors based on first and second derivatives</em>
+    <LI> \ref CornerDetection
+         <BR>   <em>Measure the 'cornerness' at each pixel </em>
+    <LI> \ref SymmetryDetection
+         <BR>   <em>Measure the local symmetry at each pixel </em>
+    <LI> \ref SeededRegionGrowing
+         <BR>   <em>Region growing, watersheds, and voronoi tesselation</em>
+    </UL>
+*/
+
+/** \page AlgebraicConcepts Algebraic Concepts
+
+The algebraic concepts describe requirements for algebraic types, that is
+for types that support arithmetic operations. The built-in types are concepts
+of \ref AlgebraicField and \ref DivisionAlgebra.
+
+\anchor AlgebraicRing
+
+<h3>Algebraic Ring</h3>
+
+<ul>
+    <li>A model of Algebraic Ring implements <tt>Assignable</TT>, <tt>Default Constructible</TT>,
+        <tt>Equality Comparable</TT> and <tt>Strict Weakly Comparable</TT>
+        as defined in the C++ standard (cf. the
+        <a href=\stl_link>Standard Template Library documentation</a>).
+
+    <li>A model of Algebraic Ring implements addition, subtraction and unary negation. The associated
+    \link NumericTraits NumericTraits \endlink define a 'zero' element, the type of the
+    result of addition and subtraction, and a type conversion function.
+    Addition must be commutative.
+
+    \code
+    ModelOfAlgebraicRing a, b;
+    NumericTraits<ModelOfAlgebraicRing>::Promote c;
+
+    ModelOfAlgebraicRing zero = NumericTraits<ModelOfAlgebraicRing>::zero();
+
+    b += a;
+    b -= a;
+    b = -a;
+    c = a + b;
+    c = a - b;
+    c = a;
+    a = NumericTraits<ModelOfAlgebraicRing>::fromPromote(c);
+
+    assert(a + zero == a);
+    assert(a + b == b + a);
+    assert(a - b == a + (-b));
+    \endcode
+
+    <li>If mixed-type addition and subtraction are supported,
+    \link PromoteTraits PromoteTraits \endlink define the result type:
+
+    \code
+    ModelOfAlgebraicRing1 a;
+    ModelOfAlgebraicRing2 b;
+
+    PromoteTraits<ModelOfAlgebraicRing1, ModelOfAlgebraicRing2>::Promote c;
+
+    c = a + b;
+    \endcode
+
+    <li>A model of Algebraic Ring implements multiplication. The associated
+    \link NumericTraits NumericTraits \endlink define a 'one' element, the type of the
+    result of multiplication, and a type conversion function.
+
+    \code
+    ModelOfAlgebraicRing a, b;
+    NumericTraits<ModelOfAlgebraicRing>::RealPromote c;
+
+    ModelOfAlgebraicRing one = NumericTraits<ModelOfAlgebraicRing>::one();
+
+    b *= a;
+    c = a * b;
+    c = a;
+    a = NumericTraits<ModelOfAlgebraicRing>::fromRealPromote(c);
+
+    assert(a * one == a);
+    \endcode
+</ul>
+
+\anchor AlgebraicField
+<h3>Algebraic Field</h3>
+
+<ul>
+    <li>A model of Algebraic Field implements \ref AlgebraicRing as defined above.
+
+    <li>A model of Algebraic Field implements division. Division is undefined if
+    and only if the right operand is 'zero'.
+
+    \code
+    ModelOfAlgebraicField a, b;
+    typename NumericTraits<ModelOfAlgebraicField>::RealPromote c;
+
+    ModelOfAlgebraicField zero = NumericTraits<ModelOfAlgebraicField>::zero();
+
+    if(a != zero) b /= a;
+    if(a != zero) c = b / a;
+    \endcode
+
+</ul>
+
+
+\anchor LinearSpace
+
+<h3>Linear Space</h3>
+
+<ul>
+    <li>A model of Linear Space implements <tt>Assignable</TT>, <tt>Default Constructible</TT>
+        and <tt>Equality Comparable</TT>
+        as defined in the C++ standard (cf. the
+        <a href=\stl_link>Standard Template Library documentation</a>).
+
+    <li>A model of Algebraic Ring implements addition, subtraction and unary negation. The associated
+    \link NumericTraits NumericTraits \endlink define a 'zero' element, the type of the
+    result of addition and subtraction, and a type conversion function.
+    Addition must be commutative. (This part of the requirements is identical to
+    \ref AlgebraicRing above.)
+
+    \code
+    ModelOfAlgebraicRing a, b;
+    NumericTraits<ModelOfAlgebraicRing>::Promote c;
+
+    ModelOfAlgebraicRing zero = NumericTraits<ModelOfAlgebraicRing>::zero();
+
+    b += a;
+    b -= a;
+    b = -a;
+    c = a + b;
+    c = a - b;
+    c = a;
+    a = NumericTraits<ModelOfAlgebraicRing>::fromPromote(c);
+
+    assert(a + zero == a);
+    assert(a + b == b + a);
+    assert(a - b == a + (-b));
+    \endcode
+
+    <li>If mixed-type addition and subtraction are supported,
+    \link PromoteTraits PromoteTraits \endlink define the result type:
+
+    \code
+    ModelOfAlgebraicRing1 a;
+    ModelOfAlgebraicRing2 b;
+
+    PromoteTraits<ModelOfAlgebraicRing1, ModelOfAlgebraicRing2>::Promote c;
+
+    c = a + b;
+    \endcode
+
+    <li>A model of Algebraic Ring implements multiplication and division with 'double'.
+      (Note that the outer product could be defined with an arbitrary model of
+      \ref AlgebraicField. For simplicity, VIGRA restricts this to only 'double'.)
+      The associated \link NumericTraits NumericTraits \endlink define the type of the
+      results, and a type conversion function.
+
+    \code
+    ModelOfAlgebraicRing a;
+    double f;
+    NumericTraits<ModelOfAlgebraicRing>::RealPromote c;
+
+
+    a *= f;
+    c = a * f;
+    c = f * a;
+
+    if(f != 0.0) a /= f;
+    if(f != 0.0) c = a / f;
+
+    c = a;
+    a = NumericTraits<ModelOfAlgebraicRing>::fromRealPromote(c);
+    \endcode
+</ul>
+
+\anchor LinearAlgebraConcept
+<h3>Linear Algebra</h3>
+
+<ul>
+    <li>A model of Linear Algebra implements \ref LinearSpace and
+        \ref AlgebraicRing as defined above.
+
+</ul>
+
+\anchor DivisionAlgebra
+<h3>Division Algebra</h3>
+
+<ul>
+    <li>A model of Division Algebra implements \ref LinearSpace and
+        \ref AlgebraicField as defined above.
+
+</ul>
+
+*/
+
+/** \page VigraMatlab Vigra Matlab
+
+    Matlab bindings (mex-files) for the most important VIGRA functions are located 
+    <tt>[vigra_src_dir]/src/matlab</tt>. To compile and install them, start Matlab, 
+    go into that directory and call the function buildVigraExtensions:
+    
+    \code
+    buildVigraExtensions('install_path')
+    \endcode
+    
+    If the compilation fails because includes or libraries are not found, you can 
+    provide additional search directories like this:
+    
+    \code
+    buildVigraExtensions('install_path', 'all', struct('flags', '-I/path/to/includes -L/path/to/libs'))
+    \endcode
+    
+    Additional compiler flags are specified in the same way. Suggestions about typical settings on Linux and
+    Windows can be found in the individual .cpp files. For example, on Windows we usually need
+    
+    \code
+    buildVigraExtensions('install_path', 'all', ...
+     struct('flags', '-I[HDF5PATH]/include -L[HDF5PATH]/lib -lhdf5dll -lhdf5_hldll -D_HDF5USEDLL_ -DHDF5CPP_USEDLL'))
+    \endcode
+   
+    After successful compilation, you can obtain a list of the available VIGRA functions by calling
+
+    \code
+    help vigraIndex
+    \endcode
+    
+    In the same way, you get documentation for the individual functions. More 
+    information about the glue code behind the bindings is available in 
+    <a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/tutorial_reference.pdf">this report</a>.
+    
+*/
+
+/** \namespace vigra
+    all VIGRA functionality is located in namespace vigra
+*/
+
+
+#if 0
+//@{
+
+
+//Include: ../include/vigra/morphological_appropriate_scale.hxx
+//Include: ../include/vigra/feature_adjacency_graph.hxx
+
+//@}
+
+#endif
+
diff --git a/docsrc/index_fallback.html b/docsrc/index_fallback.html
new file mode 100644
index 0000000..8505e84
--- /dev/null
+++ b/docsrc/index_fallback.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head><TITLE>vigra - vigra: VIGRA Reference Manual</TITLE>
+<link rel=stylesheet type="text/css" href="vigra.css">
+</head>
+<body  bgcolor="#f8f0e0" link="#0040b0" vlink="#a00040">
+<basefont face="Helvetica,Arial,sans-serif" size=3>
+
+<h2>VIGRA Reference Manual</h2>
+
+You did not yet generate documentation (use 'make doc' or equivalent to do so). 
+Online documentation can be found on the <a href="http://hci.iwr.uni-heidelberg.de/vigra/">VIGRA Homepage</a>.
+</BODY>
+</HTML>
diff --git a/docsrc/installation.dxx b/docsrc/installation.dxx
new file mode 100755
index 0000000..2e26b63
--- /dev/null
+++ b/docsrc/installation.dxx
@@ -0,0 +1,66 @@
+/** \page Installation Installation
+
+    VIGRA can be downloaded from <a href="http://hci.iwr.uni-heidelberg.de/vigra/">http://hci.iwr.uni-heidelberg.de/vigra/</a>. It should work with any standard conforming C++ compiler on both 32-bit and 64-bit machines.
+    
+    VIGRA is mainly a header library, i.e. much of its functionality can be accessed by simply copying the include files to a convenient location. A more involved build process is necessary for image file import and export, for the VIGRA Python bindings, and for the test suite and examples. VIGRA can take advantage of the following external software packages:
+    
+    <ul>
+    <li> <a href="http://www.ijg.org/">libjpeg</a>, <a href="http://www.libtiff.org/">libtiff</a>,
+         <a href="http://www.libpng.org/">libpng</a>, <a href="http://www.openexr.com/">OpenEXR</a> 
+         for reading and writing JPEG, TIFF, PNG, and EXR images respectively.
+    <li> <a href="http://www.hdfgroup.org/HDF5/">HDF5</a> for reading and writing HDF5 files (storage of MultiArray and RandomForest).
+    <li> <a href="http://www.fftw.org/">libfftw</a> for fast Fourier transforms.
+    <li> <a href="http://www.doxygen.org/">doxygen</a> and <a href="http://www.python.org/">Python</a> to generate C++ documentation.
+    <li> <a href="http://www.python.org/">Python</a>, <a href="http://www.boost.org/">boost_python</a>, and <a href="http://numpy.scipy.org/">numpy</a> to compile and run vigranumpy (the VIGRA Python bindings).
+    <li> <a href="http://sphinx.pocoo.org/">sphinx</a> to generate vigranumpy documentation.
+    <li> <a href="http://readthedocs.org/docs/nose/en/latest/">nosetests</a> to execute the vigranumpy test suite.
+    </ul>
+
+    These dependencies are optional - the functionality will simply be unavailable if the libraries cannot be found.
+    
+    VIGRA installation is based on <a href="http://www.cmake.org/">cmake</a> which has to be installed on your machine. In order to configure the build and installation process, execute the following on the command line:
+
+    
+    \code
+    > mkdir \<vigra_build_path\>       
+    > cd \<vigra_build_path\>       
+    > cmake [options] \<vigra_source_path\>
+    > make          # build (Linux/Unix and MinGW only)
+    > make check    # compile and run tests (optional, Linux/Unix and MinGW only)
+    > make doc      # generate documentation (Linux/Unix and MinGW only)
+    > make install  # install (Linux/Unix and MinGW only)
+    > make examples # build examples (optional, Linux/Unix and MinGW only)
+    \endcode
+    
+    When you use gcc 4.8.1, make sure to change the optimization level to <tt>-O2</tt> in the cmake configuration (this is best done in the cmake GUI that you get by calling <tt>ccmake .</tt> before invoking <tt>make</tt>). The <tt>-O3</tt> level in that compiler is buggy and leads to crashes.
+    
+    If you use Microsoft Visual C++, you just execute <tt>cmake</tt> (not <tt>make</tt>) or <tt>cmake-gui</tt> with the appropriate generator which creates a solution file '<vigra_build_path>/vigra.sln'. This file must be opened in Visual Studio, and the projects 'ALL_BUILD', 'check', 'doc', 'INSTALL', and 'examples' should be generated. <b>Important note</b>: If you include <b>"windows.h"</b> in your projects: there are some name clashes with VIGRA -- always include <b>"vigra/wind [...]
+    
+    cmake [options] customize installation directories and guide cmake in its search for the VIGRA dependencies. On a Linux system, it is often possible to configure without any options. The most commonly used options are:
+    
+    <DL>
+    <DT> -DCMAKE_INSTALL_PREFIX=<path>
+         <DD> where to install VIGRA (binaries will be installed in <path>/bin, libraries in 
+         <path>/lib, headers in <path>/include/vigra, and documentation in 
+         <path>/doc/vigra and <path>/doc/vigranumpy, default is platform dependent)
+    <DT> -DDEPENDENCY_SEARCH_PREFIX=<path1>[;<path2>...]
+         <DD> where to look for VIGRA dependencies (for every given path, cmake will search for 
+         libraries in <path>/lib and for headers in <path>/include)
+    <DT> -DDOCDIR=<path>
+         <DD> where to generate VIGRA documentation (default: <vigra_source_path>/doc).
+         Note that this is not the documentation install directory (the latter can be changed
+         by -DDOCINSTALL=... and defaults to $CMAKE_INSTALL_PREFIX/doc).
+    <DT> -DWITH_VIGRANUMPY=1
+         <DD> build VIGRA Python bindings (default: 1). Pass -DWITH_VIGRANUMPY=0 to suppress 
+         vigranumpy.
+    <DT> -DWITH_HDF5=1
+         <DD> build VIGRA with HDF5 support (default: 1). Pass -DDWITH_HDF5=0 to compile without HDF5.
+    <DT> -DLIB_SUFFIX=64
+         <DD> define suffix of lib directory name (default: empty string, i.e. no suffix). Use 
+         -DLIB_SUFFIX=64 when you want to install libraries in $CMAKE_INSTALL_PREFIX/lib64.
+    </DL>
+
+    More fine-grained customization (e.g. specification of explicit paths for all dependencies, customization of compiler flags) is possible by editing the file <vigra_build_path>/CMakeCache.txt. This is best done by means of the interactive programs <b>ccmake</b> or <b>cmake-gui</b>. Consult the <a href="http://www.cmake.org/cmake/help/documentation.html">cmake documentation</a> for more detailed help.
+
+    For using VIGRA in another CMake-built project, you can use the CMake command FIND_PACKAGE(Vigra), which will set the CMake variables ${Vigra_INCLUDE_DIRS} with the correct include path, and import the binary targets (currently vigraimpex) to link against (e.g., TARGET_LINK_LIBRARIES(targetname vigraimpex)). For this mechanism to work, CMake reads a config file VigraConfig.cmake, which is installed along with the library in CMAKE_INSTALL_PREFIX/lib/vigra. Alternatively, you can point [...]
+*/
diff --git a/docsrc/makeFunctionIndex.py b/docsrc/makeFunctionIndex.py
new file mode 100644
index 0000000..81c0cc0
--- /dev/null
+++ b/docsrc/makeFunctionIndex.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python
+
+import re
+import glob
+import sys
+import xml.etree.ElementTree as ET
+from itertools import chain
+
+if len(sys.argv) != 2:
+    print 'usage: python makeFunctionIndex.py directory'
+    sys.exit(1)
+
+path = str(sys.argv[1])
+
+
+def getClassList():
+    tree = ET.parse("tagfile.tag")
+    root = tree.getroot()
+
+    class_list = []
+    for classes in root.findall("*[@kind='class']"):
+        long_name = classes.find('name').text
+        # only classes from vigra namespace
+        if long_name[0:5] == 'vigra':
+            html = classes.find('filename').text
+            short_name = long_name[long_name.rfind('::')+2:]
+            namespace = long_name[:long_name.rfind('::')]
+            class_list.append([html, short_name, namespace])
+
+    class_list.sort(lambda a,b: cmp(a[1], b[1]))
+    return class_list
+
+
+
+def getFunctionList():
+    tree = ET.parse("tagfile.tag")
+    root = tree.getroot()
+
+    function_list = []
+    for function in chain(root.findall("*[@kind='group']/*[@kind='function']"),root.findall("*[@kind='namespace']/*[@kind='function']")):
+        name = function.find('name').text
+        anchorfile = function.find('anchorfile').text
+        anchor = function.find('anchor').text
+        html = anchorfile + '#' + anchor
+        function_list.append((html, name))
+
+    # add special documentation for argument object factories
+    for k in ['srcImageRange', 'srcImage', 'destImageRange', 'destImage', 'maskImage']:
+        function_list.append(('group__ImageIterators.html#ImageBasedArgumentObjectFactories', k))
+    for k in ['srcMultiArrayRange', 'srcMultiArray', 'destMultiArrayRange', 'destMultiArray']:
+        function_list.append(('group__ImageIterators.html#MultiArrayBasedArgumentObjectFactories', k))
+    for k in ['srcIterRange', 'srcIter', 'destIterRange', 'destIter', 'maskIter']:
+        function_list.append(('group__ImageIterators.html#IteratorBasedArgumentObjectFactories', k))
+
+    unique = set()
+    set_add = unique.add
+    function_list = [ x for x in function_list if x not in unique and not set_add(x)]    
+    function_list.sort(lambda a,b: cmp(a[1], b[1]))
+    function_list = disambiguateOverloadedFunctions(function_list)
+    return function_list
+
+def addHeading(index, initial):    
+    index = index + '<p><a name="index_' + initial + \
+    '"><table class="function_index"><tr><th> ' + initial.upper() + \
+    ' </th><td align="right" width="100%">VIGRA_NAVIGATOR_PLACEHOLDER</td></tr></table><p>\n'
+    return index
+
+def disambiguateOverloadedFunctions(functionList):
+    for i in xrange(len(functionList)):
+        overloaded = False
+        functionName = functionList[i][1]
+        if i > 0:
+            lastFunctionName = functionList[i-1][1]
+            if functionName == lastFunctionName:
+                overloaded = True
+        if i < len(functionList) - 1:
+            nextFunctionName = functionList[i+1][1]
+            if functionName == nextFunctionName:
+                overloaded = True
+        if overloaded:
+            # disambiguate overloaded functions by their group or namespace
+            link = functionList[i][0]
+            group = re.sub(r'(group__|namespacevigra_1_1)([^\.]+)\.html.*', r'\2', link)
+        else:
+            group = ""
+        functionList[i] = functionList[i] + (group,)
+    
+    return functionList
+
+
+def generateFunctionIndex(functionList):
+    index = ""
+    initials = []
+    for i in range(len(functionList)):
+        functionName = functionList[i][1]
+        link = functionList[i][0]
+        initial = functionName[0]
+        if i > 0:
+            lastInitial = functionList[i-1][1][0]
+            if initial != lastInitial:
+                initials.append(initial)
+                index = addHeading(index, initial)
+        else:
+            initials.append(initial)
+            index = addHeading(index, initial)
+            
+        index = index + '<a href="'+ link + '">' + functionName + '</a>()'
+        overloadDisambiguation = functionList[i][2]
+        if overloadDisambiguation != "":
+            index = index + ' [' + overloadDisambiguation + ']'
+        index = index + '<br>\n'
+
+    navigator = '['
+    for i in range(len(initials)):
+        initial = initials[i]
+        if i != 0:
+            navigator = navigator + '|'
+        navigator = navigator + ' <a href="#index_' + initial + '">' + initial.upper() + '</a> '
+    navigator = navigator + ']'
+    index = re.sub('VIGRA_NAVIGATOR_PLACEHOLDER', navigator, index)
+
+    # use file "/namespaces.html" as boiler plate for "/functionindex.html"
+    text = open(path + "/namespaces.html").read()
+    if text.find('</h1>') > -1: # up to doxygen 1.7.1
+        header = text[:text.find('</h1>')+5]
+    else: # for doxygen 1.7.4 to 1.7.6.1
+        header = text[:re.search(r'<div class="title">[^<]*</div>\s*</div>\s*</div>(?:<!--header-->)?\n<div class="contents">',text).end()]
+    footer = re.search(r'(?s)(<!-- footer.html -->.*)', text).group(1)
+
+    text = re.sub(r'Namespace List', r'Function Index', header)
+    text = text + '\n<p><hr>\n'
+    text = text + index
+    text = text + footer
+
+    open(path + "/functionindex.html", 'w+').write(text)
+
+
+classList = getClassList()
+functionList = getFunctionList()
+generateFunctionIndex(functionList)
+
+# Export class and function list to c_api_replaces.txt for 
+# crosslinking of vigranumpy documentation.
+# Note that '::' are not allowed in reStructuedText link names, 
+# so we have to use '.' instead.
+replaces=open("../vigranumpy/docsrc/c_api_replaces.txt","w")
+for i in range(len(functionList)):
+    functionName = functionList[i][1]
+    overloadDisambiguation = functionList[i][2]
+    if i > 0 and functionName == functionList[i-1][1] and \
+                   overloadDisambiguation == functionList[i-1][2]:
+        continue
+    if overloadDisambiguation != "":
+        functionName = overloadDisambiguation +'.' + functionName
+    link = functionList[i][0]
+    replaces.write(functionName+":"+link+"\n")
+for i in range(len(classList)):
+    className = classList[i][1]
+    namespace = classList[i][2]
+    if (i > 0 and className == classList[i-1][1]) or \
+       (i < len(classList)-1 and className == classList[i+1][1]):
+        namespace = namespace.replace('::', '.')
+        className = namespace +'.' + className
+    link = classList[i][0]
+    replaces.write(className+":"+link+"\n")
+replaces.close()
diff --git a/docsrc/post.py b/docsrc/post.py
new file mode 100644
index 0000000..de3d39f
--- /dev/null
+++ b/docsrc/post.py
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+
+import re
+import glob
+import sys
+
+if len(sys.argv) != 3:
+    print 'usage: python post.py directory versionNumber'
+    sys.exit(1)
+
+path = str(sys.argv[1])
+
+insertVersion = re.compile(r'VERSION_VERSION_VERSION')
+insertSTLLink = re.compile(r'WWW_STL_DOCU')
+
+# tested with doxygen 1.7.5.1
+hasAnchorDetails = re.compile(r'<a (class="anchor" |)name="_?details"( id="details"|)>')
+
+detailsHeading1 = re.compile(r'''<a name="_details"></a><h2>Detailed Description</h2>
+<h3>''')
+
+detailsHeading2 = re.compile(r'<a name="_details"></a><h2>Detailed Description</h2>')
+
+# tested with doxygen 1.7.5.1 and 1.8.2
+detailsHeading3 = re.compile(r'<a name="details" id="details"></a><h2( class="groupheader"|)>Detailed Description</h2>')
+
+mainHeading1 = re.compile(r'''(<!-- Generated by Doxygen \d+\.\d+\.\d+ -->)
+(  <div class="navpath">.*
+  </div>
+|)<div class="contents">
+<h1>(.*)( Class Template Reference| Struct Template Reference| Class Reference| Struct Reference)(<br>
+<small>
+.*</small>
+|)</h1>''')
+
+mainHeading2 = re.compile(r'''(<!-- Generated by Doxygen \d+\.\d+\.\d+ -->)
+(  <div class="navpath">.*
+  </div>
+<div class="contents">
+|<div class="contents">
+|)<h1>(.*)()(<br>
+<small>
+.*</small>
+|)</h1>''')
+
+# tested with doxygen 1.5.6
+mainHeading3 = re.compile(r'''(<!-- Generated by Doxygen \d+\.\d+\.\d+ -->)
+(<div class="header">
+  <div class="headertitle">
+)<h1>(.*)</h1>(.*)()
+</div>
+<div class="contents">''')
+
+# tested with doxygen 1.7.5.1 and 1.7.6.1
+mainHeading4 = re.compile(r'''(<!-- Generated by Doxygen .+ -->
+</div>)
+(<div class="header">
+  <div class="headertitle">
+)<div class="title">(.*)</div>  </div>(.*)()
+</div>(?:<!--header-->)?
+<div class="contents">''')
+
+# tested with doxygen 1.8.2
+mainHeading5 = re.compile(r'''(<!-- Generated by Doxygen .+ -->
+</div><!-- top -->)
+(<div class="header">
+  <div class="headertitle">
+)<div class="title">(.*)</div>  </div>(.*)()
+</div>(?:<!--header-->)?
+<div class="contents">''')
+
+
+mainHeadingReplacement = '''\\1
+<div class="contents">
+<table class="main_heading">
+<tr>
+%s<td width="100%%">\\3\\5
+</td>
+<td align=right><a href="http://hci.iwr.uni-heidelberg.de/vigra/"><IMG border=0 ALT="VIGRA" SRC="documents/vigra.gif" title="VIGRA Homepage"></a></td></tr>
+</table><p>
+'''
+
+# tested with doxygen 1.7.5.1
+headingSummary = re.compile(r'''(<!-- Generated by Doxygen .+ -->
+</div>
+<div class="header">)
+  <div class="summary">
+(?s).*?</div>''')
+
+# tested with doxygen 1.8.2
+headingSummary2 = re.compile(r'''(<!-- Generated by Doxygen .+ -->
+</div><!-- top -->
+<div class="header">)
+  <div class="summary">
+(?s).*?</div>''')
+
+# tested with doxygen 1.7.5.1
+headingNavpath = re.compile(r'''(<!-- Generated by Doxygen .+ -->)
+  <div id="nav-path" class="navpath">(?s).*?</div>''')
+
+# tested with doxygen 1.8.2
+headingNavpath2 = re.compile(r'''(<!-- Generated by Doxygen .+ -->)
+<div id="nav-path" class="navpath">
+  <ul>
+.*  </ul>
+</div>''')
+
+detailsLink = '''<td align=left>
+<A HREF ="#_details" ><IMG BORDER=0 ALT="details" title="Detailed Description" SRC="documents/pfeilGross.gif"></A>
+</td>
+'''
+
+indexPageHeading = re.compile(r'''((?:<p>)?<a class="anchor" (?:name|id)="_details"></a> (?:</p>\n)?<center> </center>)<h2>(<a class="anchor" (?:name|id)="Main">(?:</a>)?)
+(.*)
+<center> Version''')
+
+indexPageHeadingReplacement = '''\\1 <h2 class="details_section">\\2
+\\3
+<center> Version'''
+
+templateDeclaration = re.compile('''<tr><td class="memTemplParams" nowrap colspan="2">([^<]*)</td></tr>\s*
+<tr><td class="memTemplItemLeft" nowrap align="right" valign="top">[^<]*</td><td class="memTemplItemRight" valign="bottom"><a class="el" href=".*#([^"]+)">''')
+
+templateDocumentation = '''(<a class="anchor" name="%s"></a>.*
+<div class="memitem">
+<div class="memproto">\s*
+      <table class="memname">
+        <tr>)'''
+
+templateDocumentationReplacement = '''\\1
+          <td colspan="4" class="memtemplate">%s</td></tr><tr>'''
+
+def convertHeadings(text):
+    if hasAnchorDetails.search(text):
+        text = detailsHeading1.sub('<a name="_details"></a><h2 class="details_section">Detailed Description</h2>\n<h3 class="details_section">', \
+                      text, 1)
+        text = detailsHeading2.sub(r'<a name="_details"></a><h2 class="details_section">Detailed Description</h2>', text, 1)
+        text = detailsHeading3.sub(r'<a name="_details" id="details"></a><h2 class="details_section">Detailed Description</h2>', text, 1)
+        mhr = mainHeadingReplacement % detailsLink
+    else:
+        mhr = mainHeadingReplacement % ''
+    text = headingNavpath.sub("\\1", text, 1)
+    text = headingNavpath2.sub("\\1", text, 1)
+    text = headingSummary.sub("\\1", text, 1)
+    text = headingSummary2.sub("\\1", text, 1)
+    text = mainHeading1.sub(mhr, text, 1)
+    text = mainHeading2.sub(mhr, text, 1)
+    text = mainHeading3.sub(mhr, text, 1)
+    text = mainHeading4.sub(mhr, text, 1)
+    text = mainHeading5.sub(mhr, text, 1)
+    return text
+
+def insertMissingTemplateDeclarations(text):
+    matches = templateDeclaration.findall(text)
+    for k in matches:
+        text = re.sub(templateDocumentation % k[1], templateDocumentationReplacement % k[0], text)
+    return text
+
+def processFile(fileName):
+    print fileName          # log message
+    f = open(fileName)
+    text = f.read()
+    f.close()
+    
+    text = insertVersion.sub(sys.argv[2], text)
+    text = insertSTLLink.sub(r'http://www.sgi.com/tech/stl/', text)
+    if re.search('.*/index.html', fileName) or re.search('.*\\index.html', fileName):
+        text = re.sub(r'<h3 (align="center"|class="version")>\d+\.\d+\.\d+ </h3>', '', text)
+        text = indexPageHeading.sub(indexPageHeadingReplacement, text)
+        
+    text = convertHeadings(text)
+    
+    text = insertMissingTemplateDeclarations(text)
+
+    f = open(fileName, 'w+')
+    f.write(text)
+    f.close()
+
+files = glob.glob(path + '/*.html')  # use given path to files
+#files = glob.glob(path + '/index.html')
+
+for file in files:
+   processFile(file)
+
diff --git a/docsrc/tutorial.dxx b/docsrc/tutorial.dxx
new file mode 100644
index 0000000..02a73be
--- /dev/null
+++ b/docsrc/tutorial.dxx
@@ -0,0 +1,933 @@
+/** \page Tutorial Tutorial
+    
+    This tutorial will help you to learn VIGRA's most important concepts by means of simple examples. The tutorial consists of the following parts:
+    
+    <ul style="list-style-image:url(documents/bullet.gif)">
+    <li> \ref MultiDimensionalArrayTutorial
+        <BR>   <em>VIGRA's most important data structure</em>
+        <ul style="list-style-image:url(documents/bullet.gif)">
+        <li> \ref MultiArrayBasics
+        <li> \ref MultiArrayIndexing
+        <li> \ref MultiArrayScanOrder
+        <li> \ref MultiArrayMethods
+            <ul type="disc">
+            <li> \ref MultiArrayViewBasics
+            <li> \ref MultiArray_subarray
+            <li> \ref MultiArray_bind
+            <li> \ref MultiArray_vector_elements
+            <li> \ref MultiArray_transpose
+            <li> \ref MultiArray_unstrided
+            </ul>
+        </ul>
+        
+    <li> \ref MultiArrayArithmeticTutorial
+        <BR>   <em>mathematical operations on MultiArrays</em>
+        <ul style="list-style-image:url(documents/bullet.gif)">
+        <li> \ref MultiMathModule "Array Experessions"
+        <li> \ref LinearAlgebraModule "Linear Algebra"
+        <li> \ref MultiPointoperators "STL-style transformation algorithms"
+        <li> \ref FeatureAccumulators
+        </ul>
+        
+    <li> \ref ImageInputOutputTutorial
+        <BR>   <em>importing and exporting images and arbitrary-dimensional arrays</em>
+        <ul style="list-style-image:url(documents/bullet.gif)">
+        <li> \ref Impex2D
+        <li> \ref ImpexND
+        </ul>
+
+    <li> \ref ImageProcessingTutorial
+        <BR>   <em>basic applications of VIGRA's functions</em>
+        <ul style="list-style-image:url(documents/bullet.gif)">
+        <li> \ref CallingConventions
+        <li> \ref ImageInversion
+        <li> \ref ImageBlending
+        <li> \ref CompositeImage
+        <li> \ref SmoothingTutorial
+           <ul type="disc">
+            <li> \ref Convolve2DTutorial
+            <li> \ref SeparableConvolveTutorial
+            </ul>
+        </ul>
+
+    <li> \ref OwnFunctionsTutorial
+        <BR>   <em>... without getting confused by templates</em>
+
+    <li> \ref PythonBindingsTutorial
+        <BR>   <em>scripting with VIGRA made easy</em>
+        
+    </ul>
+*/
+
+/** \page MultiDimensionalArrayTutorial Multi-Dimensional Arrays
+
+    <h2>Section Contents</h2>
+    
+    <ul style="list-style-image:url(documents/bullet.gif)">
+    <li> \ref MultiArrayBasics
+    <li> \ref MultiArrayIndexing
+    <li> \ref MultiArrayScanOrder
+    <li> \ref MultiArrayMethods
+        <ul type="disc">
+        <li> \ref MultiArrayViewBasics
+        <li> \ref MultiArray_subarray
+        <li> \ref MultiArray_bind
+        <li> \ref MultiArray_vector_elements
+        <li> \ref MultiArray_transpose
+        <li> \ref MultiArray_unstrided
+        </ul>
+    </ul>
+    
+    \section MultiArrayBasics Basic MultiArray Usage
+    
+    \ref vigra::MultiArray is the most fundamental data structure in VIGRA. It holds a rectangular block of values in arbitrary many dimensions. Most VIGRA functions operate on top of MultiArray or the associated class MultiArrayView (see \ref MultiArrayViewBasics). 
+    
+    A 2D image can be interpreted as a matrix, i.e. a 2-dimensional array, where each element holds the information of a specific pixel. Internally, the data are stored in a single 1-dimensional piece of memory, and MultiArray encapsulates the entire mapping between our familiar 2-dimensional notation and the raw memory. Pixels in an image are identified by a coordinate pair (x,y), where indexing starts at 0. That is, the pixels in a 800x600 image are indexed by <tt>x = 0,...,799 and y = [...]
+    
+    The structure of a multidimensional array is given by its <tt>shape</tt> vector, and the length of the shape vector is the array's <i>dimension</i>. The dimension must be fixed as a template parameter at compule time, while the shape is passed to the array's constructor. The second important template parameter is the pixel's <tt>value_type</tt>, as you know it form <tt>std::vector</tt>. 
+    
+    To represent the data of a gray scale image, we just need to store one value per pixel, so we 
+    choose a 2-dimensional array, where each element has the <tt> unsigned char </tt> type 
+    (in VIGRA, this type is also available as \ref vigra::UInt8). We instantiate a gray scale image object like this:
+
+    \code
+    #include <vigra/multi_array.hxx>
+    
+    using namespace vigra; // for brevity in the examples - don't do this in header files!
+    
+    int width = ...,  height = ...;
+    MultiArray<2, UInt8> image(Shape2(width, height));
+    \endcode
+    
+    By default, VIGRA arrays are <b>always zero-initialized</b>. Another initial value can be provided in the constructor, or later via the <tt>init()</tt> function or the assignment operator:
+    
+    \code
+    MultiArray<2, UInt8> image(Shape2(width, height), 255); // init with value 255
+    
+    image.init(128);  // same effect, different initial value
+    image = 100;      // yet another way
+    \endcode
+     
+    The <tt>Shape2</tt> typedef also exists for higher dimensions up to five as <tt>Shape3</tt> etc. If you need even more dimensions, use <tt>MultiArrayShape<N>::type</tt> instead, were N is the number of dimensions: 
+
+    \code
+    // dimension 0 runs from 0, 1, ..., 299
+    // dimension 1 runs from 0, 1, ..., 199
+    // dimension 2 runs from 0, 1, ...,  99
+    MultiArray<3, double> volume(Shape3(300, 200, 100));
+    
+    MultiArray<7, float> array7D(MultiArrayShape<7>::type(20, 10, ...));
+    \endcode     
+
+    When storing RGB images we obviously can't simply use the unsigned char type because every pixel contains 3 numbers: values for red, green and blue. Mathematically, you want to store a data vector for each pixel. To this end, VIGRA
+    provides the <tt>vigra::RGBValue<ValueType></tt> class. So for RGB-images just use: </p>
+
+    \code
+    MultiArray<2, RGBValue<UInt8> > rgb_image(Shape2(256, 128));
+    \endcode
+
+    vigra::RGBValue<ValueType> is a specialised 3-dimensional vector containing ValueType elements. Arbitrary short vectors can be stored in the <tt>TinyVector<ValueType, SIZE></tt> class, which is the base class of RGBValue. It's length must be specified at compile time in the template parameter <tt>SIZE</tt>. Vectors whose length is known at compile time are very useful for the compiler to produce highly optimized code. Therefore, <tt>Shape2</tt> and it's higher-dimensional coursins ar [...]
+
+    Alternatively you can use a 3-dimensional array <tt>vigra::MultiArray<3, unsigned
+    char></tt> to represent a color image. The third dimension has size 3 and contains the
+    information for the red, green and blue channel. 
+    
+    \code
+    MultiArray<3, UInt8> rgb_array(Shape3(256, 128, 3));
+    \endcode
+
+    However, we are not going to use this form in the tutorial because <tt>vigra::RGBValue<ValueType></tt> provides many helpful methods that are not available when color is just another array dimension.
+
+    \section MultiArrayIndexing Array Indexing via Coordinates
+
+    The easiest way to access the values of an array is via the coordinates. A tuple of coordinates can again be specified by the appropriate shape object, which must be passed to the array's indexing operator:
+
+    \code
+    int width = 300, height = 200;
+    MultiArray<2, int> image(Shape2(width, height));
+
+    // set all elements to 3
+    image.init(3);
+
+    // print pixel at x=1 and y=2
+    int x=1, y=2;
+    std::cout << image[Shape2(x,y)] << std::endl;  // output: 3
+    \endcode
+
+    <B>Important Remark:</B> Notice that VIGRA follows the mathematical convention of the index order: dimension 0 corresponds to the x (horizontal) coordinate, dimension 1 to the y (vertical) coordinate, and so on. Accordingly,  dimension 0 is changing fastest in memory: when we increase x by one, we get to the next memory location. In matrix jargon, this is also known as <i>Fortran order</i>. Many image processing libraries (e.g. <a href="http://www.imagemagick.org/">Image Magick</a>,  [...]
+    
+    Internally, shape objects are implemented in terms of the powerful \ref vigra::TinyVector class. This means that shape objects support the usual mathematical operations like addition, multiplication and scalar products. Coordinate computations can thus be performed on entire coordinate objects at once - there is no need to manipulate the individual coordinates separately.
+    
+    Nonetheless, in some circumstances it is more convenient to provide coordinates individually rather than in a shape object. This is possible with round brackets (x,y):
+
+    \code
+    // access via individual coordinates
+    image(1,2) = 22;
+    \endcode
+	
+    This kind of indexing is supported for dimensions up to five, and only if the array's dimension is known (this is not always the case: in a generic function where the dimension is a template parameter, you must use shape objects).
+	In combination with the method <tt>shape(n)</tt>, that returns the length of the n-th dimension, 
+    we can use the coordinates to set the element of an entire row or column:
+
+    \code
+    // set all elements of first row to 13
+    for (int i = 0; i < image.shape(1); i++)
+        image(1,i) = 13;
+    \endcode
+
+    On first sight, individual coordinates may be necessary to iterator of the image or parts of it. But the following example shows that the same effect can be achieved with a shape object that is allocated outside the loop:
+    3rd column of a 8x4-matrix (initialized with 5) to 7.
+
+    \code
+    // instantiate shape object (zero intialized by default)
+    Shape2 p;
+    // bind x=2
+    p[0] = 2;
+    // iterator over row 2
+    for(p[1]=0; p[1]<image.shape(1); ++p[1])   
+        image[p] = 7;
+    \endcode
+
+    We will discuss more powerful methods to access certain parts of an array in section \ref MultiArrayMethods.
+
+    \section MultiArrayScanOrder One-dimensional Indexing and Scan-Order Iterator
+	
+    Regardless of the array's dimension, it is always possible to access elements with 1-dimensional index, its <i>scan-order index</i>, via the normal indexing operator. For example, <tt>array[1]</tt> refers to the index of the second array element. Defining a scan order is often called <i>flattening</i> of an array, because a high-dimensional data structure is accessed like a 1-dimensional vector. Notive that scan-order access in VIGRA does not require the data to be copied. 
+    
+	VIGRA defines scan-order by considering the dimensions from front to back. Thus, items are accessed such that only the x coordinate is incremented, while y (and possibly further coordinates) are held fixed at 0. When x is exhausted, y is incremented by one and the iteration starts again at x=0. To control iteration, the function <tt>array.size()</tt> returns the total number of elements: 
+
+    \code
+    MultiArray<2, int> intArray(Shape2(3,2));
+
+    for(int k=0; k<intArray.size(); ++k=
+        intArray[k] = k+1;
+    
+    // the array now contains the values
+    //
+    //   1 2 3
+    //   4 5 6
+    \endcode
+	
+    Alternatively, scan-order access can be achieved with an STL-compatible iterator pair obtained by calling <tt>array.begin()</tt> and <tt>array.end()</tt>. Continuing with the example above, we can write:
+
+	\code
+    // declare an alias for the iterator type
+    typedef MultiArray<2, int>::iterator Iter;
+
+    // iterate over intArray and print the elements in scan order
+    for (Iter i = intArray.begin(); i != intArray.end(); ++i)
+        std::cout << *i << " ";
+    std::cout << std::endl;
+    
+    // output: 1 2 3 4 5 6
+	\endcode
+
+    The iterator is implemented by class <tt>StridedScanOrderIterator</tt> which encapsulates all the bookkeeping necessary to get the elements in the correct order, even when the array was transposed (see below). 
+
+	Scan-order access is useful to implement pointwise operations, e.g. the addition of two matrices. The following code adds two matrices and stores the result in the first one: 
+
+	\code
+    MultiArray<2, int> matrix1(Shape2(3,3)),
+                       matrix2(Shape2(3,3));
+    ... // fill in data
+
+    // use indexing
+    for (int i=0; i < matrix1.size(); ++i)
+        matrix1[i] += matrix2[i];
+    
+    // use iterators
+    for (Iter i = matrix1.begin(), j = matrix2.begin(); i != matrix1.end(); ++i, ++j)
+        *i += *j;
+	\endcode
+
+	This is convenient because the actual high-dimensional shapes of the arrays are of no significance for point-wise operations as long as the shapes match. Be careful: the arrays themselves have no way of checking this condition. So thefollowing code using two transposed shapes is perfectly valid C++, but has probably not the intended effect:
+
+	\code
+    MultiArray<2, int> matrix3(Shape2(3,2)),
+                       matrix4(Shape2(2,3));  // transposed shape of matrix3
+    ... // fill in data
+
+    for (int i=0; i < matrix3.size(); ++i)
+        matrix3[i] += matrix4[i];  // works, but may not have the intended effect
+	\endcode
+
+    By the way: VIGRA provides the += operator (and is cousins) to write this more concisely, and this operator throws an exception if the shapes don't match:
+
+    \code
+    matrix1 += matrix2;          // works fine!
+    matrix3 += matrix4;          // error: shape mismatch!
+    \endcode
+
+    For more information on mathematical operations on arrays see the \ref MultiMathModule "multi_math" module.
+
+    As mentioned, VIGRA's scan order is similar to the NumPy-method <tt>array.flatten()</tt>. You use it, 
+    to copy a multi-dimensional array into an one-dimensional array, or to access elements in flattened order. The only
+    difference is that NumPy uses "C-order" , i.e. the rightmost dimension takes priority, whereas
+    VIGRA uses Fortran-order, i.e. the leftmost dimension takes priority. A method like flatten can be implemented in VIGRA as:
+
+    \code
+    MultiArray<2, int> intArray(Shape2(3,2));
+
+    for(int k=0; k<intArray.size(); ++k=
+        intArray[k] = k+1;
+    
+    // create 1D-array of appropriate size
+    std::vector<int> flatArray(intArray.size());
+    
+    // copy 2D-array into 1D-array using the STL
+    std::copy(intArray.begin(), intArray.end(), flatArray.begin());
+    
+    // print 1D-array on console
+    // (same output as printing from the StridedScanOrderIterator directly) 
+    for (std::vector<int>::iterator i = flatArray.begin(); i != flatArray.end(); ++i)
+         std::cout << *iter << " ";
+    std::cout << std::endl;
+    \endcode
+
+    To show the difference between VIGRA and NumPy we'll add the NumPy output, i.e. the result when we had
+    used C-order in the code above:
+
+    \verbatim
+    flatArray - index     0       1       2       3       4       5 
+    -----------------------------------------------------------------
+    VIGRA-output:         1       2       3       4       5       6
+    intArray - index    [0,0]   [1,0]   [2,0]   [0,1]   [1,1]   [2,1]
+    -----------------------------------------------------------------
+    NumPy-output:         1       4       2       5       3       6
+    intArray - index    [0,0]   [0,1]   [1,0]   [1,1]   [2,0]   [2,1]
+    \endverbatim
+
+    To change the axis priorities of the StridedScanOrderIterator, look at the transpose-function
+    in the next section.
+    
+    \section MultiArrayMethods Important MultiArray Methods
+
+    This part of the tutorial explains important methods of MultiArray. However, before we proceed, we need to introduce the class \ref vigra::MultiArrayView.
+    
+    \subsection MultiArrayViewBasics The MultiArrayView Interface
+    
+    A \ref vigra::MultiArrayView has the same interface as a MultiArray (with the exception of <tt>reshape()</tt> and <tt>swap()</tt>), but it doesn't own its data. Instead, it provides a <i>view</i> onto the data of some other array. In contrast, a MultiArray owns its data and is responsible for freeing it in the destructor. MultiArrays are automatically converted into MultiArrayViews when needed.
+    
+    The point of this distinction is that MultiArrayViews can be used to access and manipulate the same data in many different ways <i>without any need for creating copies</i>. For example, we can work with a 2-dimensional slice of a volume dataset (i.e. a lower dimensional part of a 3D array) without first copying the slice into a 2D image. This is possible whenever the desired view can be realized by just manipulating the internal <i>mapping</i> from indices and shapes to memory locati [...]
+    
+    This possibility -- which is similarly implemented in other packages like Matlab and numpy -- is a key ingredient for efficient computations with multi-dimensional arrays. Thus, most VIGRA functions actually receive MultiArrayViews to maximize flexibility. This section describes the most important ways to create new MultiArrayViews from an existing array or view. The complete documentation is available in the \ref vigra::MultiArrayView reference.
+
+    <hr>
+
+    \subsection MultiArray_subarray subarray(p,q)
+    
+    This method creates a rectangular subarray of your array between the points p and q, where p (the starting point of the subregion) is included, q (the ending point) is not. <tt>subarray</tt> does not change the dimension of the array (this is the task of the various <tt>bind</tt>-methods).
+    
+    To give an example, we create a 4x4 array that consitst of a checkerboard with 2x2 squares:
+
+    \code
+    MultiArray<2, float> array_4x4(Shape2(4,4));  // zero (black) initialized
+    
+    // paint the upper left 2x2 square white
+    array_4x4.subarray(Shape2(0,0), Shape2(2,2)) = 1.0;
+    
+    // likewise for the lower right 2x2 square, but this time we 
+    // store the array view explicitly for illustration
+    MultiArrayView<2, int> lower_right_square = array_4x4.subarray(Shape2(2,2), Shape2(4,4));
+    lower_right_square = 1.0;
+    
+    // contents of array_4x4 now:
+    //    1 1 0 0
+    //    1 1 0 0
+    //    0 0 1 1
+    //    0 0 1 1
+    \endcode
+
+    The positions p and q are specified with the familiar <tt>Shape</tt> objects. In this example we simply overwrite parts of the array. The following larger example uses <tt>subarray</tt> to output a half-sized subimage around the center of the original image: <a href="subimage_tutorial_8cxx-example.html">subimage_tutorial.cxx</a> <br />
+    The relevant part of this code is shown here (the functions <tt>importImage</tt> and <tt>exportImage</tt> are described in section \ref ImageInputOutputTutorial):
+
+    \dontinclude subimage_tutorial.cxx
+    \skip // read image
+    \until exportImage
+
+    After reading the (here: gray scale) image data to an array we need to calculate the 
+    coordinates of our subimage. In this case we want to cut out the middle part of the image. 
+    Afterwards we write the subimage into a new array. Look at the result:
+
+    <Table cellspacing = "10">
+    <TR valign="bottom">
+    <TD> \image html lenna_small.gif "input file" </TD>
+    <TD> \image html lenna_sub.gif "subimage output file" </TD>
+    </TR>
+    </Table>
+
+    <hr>
+
+    \subsection MultiArray_bind bind<M>(i) and bindAt(M, i)
+    
+    These methods bind axis M to the index i and thus reduce the dimension of the array by one. The only difference between the two forms is that the axis to be bound must be known at compile time in the first form, whereas it can be specified at runtime in the second. 
+    
+    Binding is useful when we want to access and/or manipulate a particular row or column of an image, or a single slice of a volume. In principle, the same can also be achieved by explicit loops, but use of <tt>bind</tt> often leads to more elegant and more generic code. Consider the following code to initialize the third column of an image with the constant 5:
+
+    \code
+    // initialize 200x100 image
+    MultiArray<2, int> array2d(Shape2(200,100)); // zero initialized
+
+    // initialize column 2 with value 5 using a loop
+    for(int y=0; y<array2d.shape(1); ++y)
+        array2d(2, y) = 5;
+        
+    // the same using bind
+    array2d.bind<0>(2) = 5;
+    \endcode
+
+    NumPy-Users are familiar with the bind mechanism as "slicing". The example above written in numpy syntax becomes:
+    \verbatim
+    array2d[2, :] = 5      // NumPy-equivalent of array2d.bind<0>(2) = 5
+    \endverbatim
+
+    You can also initialize a lower-dimensional array with the bind-method:
+
+    \code
+    // initialize new 1D array with 3rd column of a 2D array
+    MultiArray<1, int> array1d = array2d.bind<0>(2);
+    \endcode
+
+    The array <tt>array1d</tt> contains the elements the 3rd column of <tt>array2d</tt>. This bahavior nicely illustrates the difference between a copy and a view: <tt>array1d</tt> contains a copy of the 3rd column, whereas the <tt>bind</tt> function only creates a new view to the existing data in <tt>array2d</tt>. 
+    
+    At this point we have to distinguish between the classes <tt> MultiArray </tt> and 
+    <tt> MultiArrayView </tt>. MultiArray inherits from MultiArrayView and contains the
+    memory management of the array. With MultiArrayView we can view the data stored in a 
+    MultiArray. The code above produces a copy of the 3rd column of intArray. If we change the
+    elements of <tt>lowArray</tt> nothing happens to <tt> intArray </tt>.
+
+    \code
+         // initialize 200x100 image
+    MultiArray<2, int> array2d(Shape2(200,100)); // zero initialized
+
+    // initialize new 1D array with 3rd column of a 2D array
+    MultiArray<1, int> array1d = array2d.bind<0>(2);
+    
+    // overwrite element [0] of array1d
+    array1d[0] = 1;
+    
+    // this has no effect on the original array2d
+    // output: 0 1
+    std::cout << array2d(2, 0) << " " << array1d[0] << std::endl;
+    
+    // initialize a view and overwrite element [0]
+    MultiArrayView<1, int> array_view = array2d.bind<0>(2);
+    array_view[0] = 2;
+    
+    // now, the original array2d has changed as well
+    // output: 2 2
+    std::cout << array2d(2, 0) << " " << array_view[0] << std::endl;
+    \endcode
+
+    Moving on to image processing we'll give an example how you can flip an image by using 
+    bind. We read a gray scale image into a 2-dimensional array called <tt> imageArray </tt>. 
+    Then we initalize a new array <tt> newImageArray </tt> of the same dimension and size
+    and set the first row of <tt> newImageArray </tt> to the values of the last row of 
+    <tt> imageArray </tt>, the second row to the values of the second last row and so on.
+    Hence, we flip the image top to bottom.
+
+    \dontinclude mirror_tutorial.cxx
+    \skip // mirror the image horizontally 
+    \until }
+    
+    However, you don't need to implement a method like this yourself because VIGRA already provides the 
+    function \ref reflectImage(). We use this function to flip the image left-to-right:
+    
+    \dontinclude mirror_tutorial.cxx
+    \skip // mirror the image vertically
+    \until reflectImage
+   
+    The complete example can be found in <a href="mirror_tutorial_8cxx-example.html">mirror_tutorial.cxx</a>.
+    (This program needs an infile and an outfile as command-line arguments and contains additional I/O code 
+    which will be explained in section \ref ImageInputOutputTutorial.) Here you can see what happens to an input file:
+
+    <Table cellspacing = "10">
+    <TR valign="bottom">
+    <TD> \image html lenna_small.gif "input file" </TD>
+    <TD> \image html lenna_mirror_horizontal.gif "mirrored top to bottom" <TD>
+    <TD> \image html lenna_mirror_vertical.gif "mirrored left to right" <TD>
+    </TR>
+    </Table>
+
+    For completeness, there are five additional versions of the bind()-method:
+    
+    <DL>
+    <DT><b> bindInner(i) </b> with scalar or multi-dimensional index i:</DT>
+        <DD> if i is an <tt> integer </tt>, the innermost dimension (axis 0) is fixed to i, <br>
+             if i is <tt>MultiArrayShape<M>::type</tt> (a shape of size M), then the M innermost 
+             dimensions (axes 0...M-1) are fixed to the values in the shape vector </DD>
+    <DT><b> bindOuter(i) </b> with scalar or multi-dimensional index i:</DT>
+        <DD> if i is an <tt> integer </tt>, the outmost dimension (axis N-1) is fixed to i, <br>
+        if i is <tt>MultiArrayShape<M>::type</tt> (a shape of size M), then the M outmost dimensions 
+        (axes N-M ... N-1) are fixed to the values in the shape vector </DD>
+    <DT><b> diagonal() </b>:</DT>
+        <DD> Create a 1-dimensional view to the diagonal elements of the original array 
+        (i.e. <tt>view[i] == array(i,i,i)</tt> for a 3D original array). </DD>
+    </DL>
+    
+    The opposite of binding - inserting a new axis - is also possible. However, since we cannot alter the internal memory layout and thus cannot insert additional data elements, a new axis must be singleton axis, i.e. an axis with length 1. The argument of <tt>insertSingletonDimension(k)</tt> determines the position of the new axis, with <tt>0 <= k <= N</tt> when the original array has <tt>N</tt> dimensions:
+    
+    \code
+    MultiArray<2, int> array(20,10);
+    std::cout << array.insertSingletonDimension(1).shape() << "\n"; // prints "(20, 1, 10)"
+    \endcode
+    
+    <hr>
+
+    \subsection MultiArray_vector_elements expandElements(k) and bindElementChannel(i)
+    
+    When the array elements are vectors (i.e. \ref vigra::TinyVector or \ref vigra::RGBValue), we can expand these elements into an addtional array dimension:
+    \code
+    MultiArray<2, TinyVector<int, 3> > vector_array(20, 10);
+    std::cout << vector_array.shape() << "\n";  // prints "(20, 10)"
+    
+    MultiArrayView<3, int> expanded(vector_array.expandElements(2));
+    std::cout << expanded.shape() << "\n";  // prints "(20, 10, 3)"
+    \endcode
+    
+    The argument <tt>k</tt> of <tt>expandElements(k)</tt> determines the desired position of the channel axis, i.e. the index that refers to the vector elements. When the original vector array has <tt>N</tt> dimensions (not counting the channel axis), it is required that <tt>0 <= k <= N</tt>. 
+    
+    Often, we are only interested in a single channel of a vector-valued array. This can be achieved with the function <tt>bindElementChannel(i)</tt>. For example, we can extract the green channel (i.e. channel 1) from an RGB image like this:
+    \code
+    MultiArray<2, RGBValue<UInt8> > rgb_array(20, 10);
+    MultiArrayView<2, UInt8> green_channel(rgb_array.bindElementChannel(1));
+    \endcode
+    This is simply an abbreviation for <tt>rgb_array.expandElements(0).bindInner(1)</tt>.
+
+    <hr>
+
+    \subsection MultiArray_transpose transpose()
+    Everyone is familiar with the <tt>transpose()</tt> function of a matrix (i.e. a 2-dimensional array). Once again, this operation is possible without copying the data by just manipulating the internal access functions. The following example demonstrates the difference between a transposed copy and view:
+
+    \dontinclude transpose.cxx
+    \skip  create array
+    \until set transarrayView to 5
+    \until print
+
+    The output is:
+
+    \verbatim
+    base_array:
+    0  1  2  3
+    0  1  2  3
+    0  1  2  3
+    0  1  2  3
+    transarray:
+    0  0  0  0
+    1  1  1  1
+    2  2  2  2
+    3  3  3  3
+    transArrayView:
+    0  0  0  0
+    1  1  1  1
+    2  2  2  2
+    3  3  3  3
+    base_array after setting transarray to 5
+    (no change, since transarray is a copy):
+    0  1  2  3
+    0  1  2  3
+    0  1  2  3
+    0  1  2  3
+    base_array after setting transarrayView to 5
+    (base_array changes because transarrayView is a view):
+    5  5  5  5
+    5  5  5  5
+    5  5  5  5
+    5  5  5  5
+    \endverbatim
+
+    The function <tt>MultiArrayView::transpose()</tt> generalizes transposition to arrays of arbitrary dimensions. Here, it just reverses the order of the axes: axis 0 becomes axis N-1, axis 1 becomes axis N-2 and so on. In the following example we transpose a 5D array and print out its shape.
+
+    \dontinclude transpose.cxx
+    \skip transposing a 5D array
+    \until arrayview5D.shape
+
+    The output is:
+
+    \verbatim
+    Shape of array5D: (1, 2, 3, 4, 5)
+    Shape of array5D view after default transpose(): (5, 4, 3, 2, 1)
+    \endverbatim
+    
+    Finally, <tt>MultiArrayView::transpose()</tt> can also be called with a shape object that specifies the desired permutation of the axes: When <tt>permutation[k] = j</tt>, axis <tt>j</tt> of the original array becomes axis <tt>k</tt> of the transposed array (remember, that VIGRA counts the axes from 0):
+    
+    \dontinclude transpose.cxx
+    \skip transpose to an explicitly specified axis permutation
+    \until applied permutation
+    
+    The permutation in the example is 2,1,3,4,0. Thus, original dimension 0 appears in the last position of the new view, original dimension 2 appears in the first position, and so on as demonstrated by the output of the example:
+    
+    \verbatim
+    Shape of array5D view after user-defined transpose(): (3, 2, 4, 5, 1)
+        (applied permutation 2 => 0, 1 => 1, 3 => 2, 4 => 3, 0 => 4 to the axes)
+    \endverbatim
+
+    When we transpose an image about the major diagonal, we can simply use the view created by <tt>MultiArrayView::transpose()</tt>. However, transposition about the minor diagonal requires a new image, which can be filled by \ref transposeImage() like this:
+
+    \include transpose_image_tutorial.cxx
+
+    The result is:
+
+    <table cellspacing = "10">
+    <TR valign="bottom">
+    <TD> \image html lenna_small.gif "input file" </TD>
+    <TD>\image html lenna_transposed_major.gif "transpose about major diagonal" </TD>
+    <TD>\image html lenna_transposed_minor.gif "transpose about minor diagonal" </TD>
+    </TR>
+    </table>
+
+    In VIGRA, image transposition is also implemented in function <tt>vigra::transposeImage(...)</tt>. The difference
+    is that transposeImage() copies the image data, whereas MultiArrayView::transpose() just changes the internal mapping from indices to memory locations.
+
+    <b>Important note:</b> Transposing an array also changes the direction of the StridedScanOrderIterator. Imagine a 3x4-
+    matrix. Scan-order means that we iterate from left to right, row by row. Now, let's transpose the matrix to a 4x3 view. Than, scan-order in the new view is again left to right, row by row. However, in the original matrix this now corresponds to a transposed scan: from top to bottom, column by column. The same applies to the array's index operator with integer argument.
+    
+    <hr>
+
+    \subsection MultiArray_unstrided isUnstrided(k)
+    
+    A MultiArray always accesses its elements in consecutive memory order, i.e. <tt>&array[i] == &array.data()[i]</tt> for all <tt>i</tt> in the range <tt>[0, array.size())</tt>. However, this does in general not hold for MultiArrayViews, because changing array access is the whole point of view creation. Sometimes, it is necessary to find out if a view still has consecutive, unstrided memory access, for example when you want to pass on the view's data to an external library that only acc [...]
+    \code 
+    MultiArray<2, int> array(20,10);
+    std::cout << array.isUnstrided() << " " << array.transpose().isUnstrided() << "\n";  // prints "true false"
+    \endcode
+*/
+
+
+/** \example mirror_tutorial.cxx
+    Mirror an image file (horizontal or vertical)
+    <br>
+    Usage: <TT>mirror_tutorial infile outfile</TT>
+*/
+
+/** \example transpose.cxx
+    Demonstrate MultiArrayView::transpose()
+    <br>
+    Usage: <TT>transpose</TT>
+*/
+
+/** \example transpose_image_tutorial.cxx
+    Transpose an image file about major or minor axis
+    <br>
+    Usage: <TT>transpose_image_tutorial infile outfile</TT>
+*/
+
+/** \example subimage_tutorial.cxx
+    Create a half-sized subimage
+    <br>
+    Usage: <TT>subimage_tutorial infile outfile</TT>
+*/
+
+
+/** \page ImageInputOutputTutorial Image Input and Output 
+
+    <h2>Section Contents</h2>
+    <ul style="list-style-image:url(documents/bullet.gif)">
+    <li> \ref Impex2D
+    <li> \ref ImpexND
+    </ul>
+
+    \section Impex2D Two-Dimensional Images
+    
+    In this section we'll show you how to import and export an image with VIGRA. If you
+    want to import an image from disk and enquire about its properties, you must use an 
+    object of <tt>vigra::ImageImportInfo</tt> class. It reads the header of the image file. 
+    The constructor expects the file name, the file type will be determined automatically. 
+    
+    The <tt>vigra::ImageImportInfo</tt> class currently recognizes the following file formats:
+
+    <DL>
+    <DT><b>BMP:</b></dt>
+              <DD> Microsoft Windows bitmap image file.</DD>
+    <DT><b>EXR:</b></dt>
+              <DD> OpenEXR high dynamic range image format. (only available if libopenexr is installed)</DD>
+    <DT><b>GIF:</b></dt>
+              <DD> CompuServe graphics interchange format; 8-bit color.</DD>
+    <DT><b>HDR:</b></dt>
+              <DD> Radiance RGBE high dynamic range image format.</DD>
+    <DT><b>JPEG:</b></dt>
+              <DD> Joint Photographic Experts Group JFIF format - compressed 24-bit color (only available if libjpeg is installed).</DD>
+    <DT><b>PNG:</b></dt>
+              <DD> Portable Network Graphic (only available if libpng is installed).</DD>
+    <DT><b>PBM:</b></dt>
+              <DD> Portable bitmap format (black and white).</DD>
+    <DT><b>PGM:</b></dt>
+              <DD> Portable graymap format (gray scale).</DD>
+    <DT><b>PNM:</b></dt>
+              <DD> Portable anymap.</DD>
+    <DT><b>PPM:</b></dt>
+              <DD> Portable pixmap format (color).</DD>
+    <DT><b>SUN:</b></dt>
+              <DD> SUN Rasterfile.</DD>
+    <DT><b>TIFF:</b></dt>
+              <DD> Tagged Image File Format. (only available if libtiff is installed.)</DD>
+    <DT><b>VIFF:</b></dt>
+              <DD> Khoros Visualization image file.</DD>
+    </DL>
+
+    In the following example, the image file name is given in the first command line argument, and the most important image metadata are printed:
+
+    \dontinclude imageImportInfo_tutorial.cxx
+    \skip read image
+    \until numBands
+    
+
+    As you can see, the <tt> ImageImportInfo </tt> object contains a lot of information,
+    some of it is printed in the example. Using this image
+
+    \image html lenna_small.gif "input file"
+
+    we get the following output:
+
+    \verbatim
+    Image information:
+      file format: GIF
+      width:       154
+      height:      145
+      pixel type:  UINT8
+      color image: no  (number of channels: 1)
+    \endverbatim
+
+    To process the image, we must load the actual image data into an array such as the one described in \ref MultiArrayBasics. To do so, we create a <tt>vigra::MultiArray</tt> with the appropriate shape and then call \ref vigra::importImage(). This function needs an <tt> ImageImportInfo </tt> object specifying the image to be loaded and a MultiArrayView object of apropriate size to copy the image data in. The code looks like this:
+
+    \dontinclude imageIO_tutorial.cxx
+    \skip read image
+    \until importImage(imageInfo
+    
+    If you already know the type of data in the file, you can also just pass the filename and a MultiArray, which will automatically be resized as appropariate:
+
+    \dontinclude imageIO_tutorial.cxx
+    \skip if you don't need
+    \until importImage(in_filename
+    
+    Writing the image data from an array to a file is quite similar. For this purpose, you use the function \ref vigra::exportImage(), which takes an 2D MultiArrayView and an \ref vigra::ImageExportInfo object or a string (the filename). The ImageExportInfo object also needs a file name, but gives you more control over how the image is written. The desired file format is guessed from the file name's extension (but can be overridden with the method <tt>ImageExportInfo::setFileType</tt>. R [...]
+
+    \include imageExportInfo_tutorial.cxx
+
+    The resulting images are the following:
+
+    <Table cellspacing = "10">
+    <TR valign="bottom">
+    <TD> \image html testimage.jpg "testimage.jpg" </TD>
+    <TD> \image html testimage.gif "testimage.gif" </TD>
+    </TR>
+    </Table>
+
+    Finally, we give a complete example of importing, editing and exporting an image.
+    After importing, we set every other horizontal line to black. This can be done
+    with the <tt>bind<M>(i)</tt> method explained in \ref MultiArray_bind.
+    Input and output file names are specified via command line arguments.
+
+    \include imageIO_tutorial.cxx
+
+    The input image and the resulting output image are:
+    
+    <Table cellspacing = "10">
+    <TR valign="bottom">
+    <TD> \image html lenna_small.gif "input image" </TD>
+    <TD> \image html lenna_stripes.gif "output image" </TD>
+    </TR>
+    </Table>
+
+    The handling of <b>color images</b> is exactly the same, but instead of instantiating
+    a <tt>vigra::MultiArray<2, UInt8></tt> you need a
+    <tt> vigra::MultiArray<2, vigra::RGBValue<UInt8> > </tt> array as described in
+    \ref MultiArrayBasics. Images with alpha channel are supported by \ref importImageAlpha() and \ref exportImageAlpha().
+
+    Note that image processing often requires more complicated calculations than in these examples.
+    In this case, it is better to import and convert the data into a <tt>float</tt> array (i.e. <tt>vigra::MultiArray<2, float></tt>) instead of the simple <tt>unsigned char</tt> type in order to minimize rounding errors. When a file is imported into such an array, the conversion is automatically performed by the importImage() function. When an array is to be exported, the handling of <tt>float</tt> depends on the file format: If the file format supports float (currently: TIFF and VIFF), [...]
+
+    The <tt>ImageExportInfo</tt> class provides a number of additional methods to <b>customize data export</b>, including:
+    
+    <DL>
+    <DT><b>setCompression():</b></dt>
+              <DD>Request compressed storage if the file format supports it.</DD>
+    <DT><b>setFileType():</b></dt>
+              <DD>Provide the file format explicitly instead of guessing from the filename extension.</DD>
+    <DT><b>setPixelType():</b></dt>
+              <DD>Request pixels to be stored as the given type (results in an exception if the type is unsupported by the file format).</DD>
+    <DT><b> setXResolution(),  setYResolution:</b></dt>
+              <DD>Store resolution information for the two axes (ignored if unsupported by the file format).</DD>
+    </DL>
+    
+    See \ref vigra::ImageExportInfo for a complete list and more details.
+
+    \section ImpexND Higher Dimensional Arrays
+    
+    The recommended file format for arrays of arbitrary dimension is <a href="http://www.hdfgroup.org/HDF5/">HDF5</a>. It supports all possible pixel types, arbitrary dimensions, on-the-fly compression, arbitrary many arrays per file, and flexible metadata storage along with arrays. See \ref VigraHDF5Impex for more information.
+
+    The functions \ref importVolume() and \ref exportVolume() support three additional methods to read and write 3D volume data:
+    <ul>
+    <li> Multipage TIFF (read/write) and Andor SIF (read only) file formats.
+    <li> Image stacks (consisting of one 2D image per slice - read/write).
+    <li> Raw data if accompanied with an additional text file providing the necessary metadata (shape, pixel type etc.) - read only.
+    </ul>
+*/
+
+/** \example imageImportInfo_tutorial.cxx
+    Read an image and print its header information
+    <br>
+    Usage: <TT>imageImportInfo_tutorial infile</TT>
+*/
+
+/** \example imageExportInfo_tutorial.cxx
+    Create an image and export it to a file
+    <br>
+    Usage: <TT>imageExportInfo_tutorial</TT>
+*/
+
+/** \example imageIO_tutorial.cxx
+    A complete image I/O example
+    <br>
+    Usage: <TT>imageIO_tutorial infile outfile</TT>
+*/
+
+/** \page MultiArrayArithmeticTutorial Mathematics with Multi-Dimensional Arrays
+    
+    VIGRA supports various way to perform mathematical operations (arithmetic and algebraic functions, linear alebra) on arrays. Most of these functions operate element-wise.
+    
+    <ul style="list-style-image:url(documents/bullet.gif)">
+    <li> \ref MultiMathModule "Array Expressions"
+        <BR>The \ref MultiMathModule "vigra::multi_math" module overloads the usual arithmetic operators and algebraic functions for array arguments, similar to Matlab and numpy. This leads to very efficient and readable code.
+    <li> \ref LinearAlgebraModule "Linear Algebra"
+        <BR>The \ref LinearAlgebraModule "vigra::linalg" module implements linear algebra for 2-dimensional arrays. The main difference to multi_math (besides a different internal implementation) is that the multiplication operator realizes matrix multiplication here. In addition, this modul implements linear system solvers, eigenvalue decomposition, and other standard matrix algorithms.
+    <li> \ref MultiPointoperators "STL-style transformation algorithms"
+        <BR>VIGRA also provides functions like <tt>transformMultiArray()</tt> that generalize the corresponding STL functions to multiple dimensions. The functors needed for these functions are most easily created with the \ref FunctorExpressions module, VIGRA's "lambda library". This approach offers more flexibility than the array expressions above.
+    <li> \ref FeatureAccumulators
+        <BR>The \ref FeatureAccumulators "vigra::acc" module provides powerful and efficient methods to compute statistics accross entire arrays or arbitrary subparts of them.
+    </ul>    
+*/
+
+/** \page OwnFunctionsTutorial Writing your own Functions
+    
+    Sooner or later, you will want to implement your own functions on the basis of VIGRA's functionality. Some people believe that this is very difficult because one needs to provide a lot of template magic and full genericity. However, this is <i>not</i> true: Your VIGRA functions need not be templated at all -- function arguments can simply be hard-wired. In other cases, it makes sense to template on the pixel type, but leave averything else fixed. Full genericity should only be implem [...]
+    
+    As an example, consider again the image smoothing example program <a href="smooth_explicitly_8cxx-example.html">smooth_explicitly.cxx</a>. It makes sense to encapsulate the smoothing algorithm into a function of its own. When we only need to support <tt>float</tt> images, the function is simply a verbatim copy of the algorithm. In contrast to the original version, we now allow an arbitrary window radius to be passed to the algorithm, so that the amount of smoothing can be controlled  [...]
+    
+    \code
+    void smooth(MultiArrayView<2, float> input, MultiArrayView<2, float> result, int radius)
+    {
+        vigra_precondition(radius >= 0, "smooth(): window radius must not be negative.");
+        
+        Shape2 current;
+        for(current[1] = 0; current[1] < input.shape(1); ++current[1])
+        {
+            for (current[0] = 0; current[0] < input.shape(0); ++current[0])
+            {
+                Shape2 windowStart = max(Shape2(0),     current - Shape2(radius));
+                Shape2 windowStop  = min(input.shape(), current + Shape2(radius+1));
+                MultiArrayView<2, float> window = input.subarray(windowStart, windowStop);
+                result[current] = window.sum<float>() / window.size();
+            }
+        }
+    }
+    \endcode
+    
+    If we don't need to support any higher dimension or other pixel type, we can just leave it at this -- no templates are required then. 
+    
+    But suppose now that we want to generalize this code for arbitrary dimensional arrays. To do so, we specify the dimension <tt>N</tt> as a template parameter. Then we can no longer use <tt>Shape2</tt> because this class only works for 2-dimensional arrays. Instead, we use the <tt>MultiArrayShape</tt> traits class to ask for the appropriate shape object. Moreover, we cannot iterate over the array with two explicitly nested loops because the number of loops must correspond to the (unkno [...]
+    
+    \code
+    #include <vigra/multi_iterator_coupled.hxx>
+    
+    template <unsigned int N>
+    void smooth(MultiArrayView<N, float> input, MultiArrayView<N, float> result, int radius)
+    {
+        vigra_precondition(radius >= 0, "smooth(): window radius must not be negative.");
+        
+        typedef typename MultiArrayShape<N>::type  Shape;
+        
+        typename MultiCoordinateIterator<N> current(input.shape()),
+                                            end = current.getEndIterator();
+             
+        for(; current != end; ++current)
+        {
+            Shape windowStart = max(Shape(0),      *current - Shape(radius));
+            Shape windowStop  = min(input.shape(), *current + Shape(radius+1));
+            MultiArrayView<N, float> window = input.subarray(windowStart, windowStop);
+            result[*current] = window.sum<float>() / window.size();
+        }
+    }
+    \endcode
+    
+    Another useful generalization is in terms of the array's value_type. For one, we want to be able to smooth color images as well. Furthermore, most images are stored with pixel type <tt>unsigned char</tt>, and we don't want to force the user to convert them into <tt>float</tt> images before smoothing. We therefore specify the value_types as template parameters as well (notice that we allow input and result to have different types). In addition, we have to make the type of the sum in < [...]
+   
+    \code
+    template <unsigned int N, class InputValue, class ResultValue>
+    void smooth(MultiArrayView<N, InputValue>  input, 
+                MultiArrayView<N, ResultValue> result, 
+                int radius)
+    {
+        vigra_precondition(radius >= 0, "smooth(): window radius must not be negative.");
+        
+        typedef typename MultiArrayShape<N>::type                Shape;
+        typedef typename NumericTraits<InputValue>::RealPromote  SumType;
+        
+        typename MultiCoordinateIterator<N> current(input.shape()),
+                                            end = current.getEndIterator();
+             
+        for(; current != end; ++current)
+        {
+            Shape windowStart = max(Shape(0),      *current - Shape(radius));
+            Shape windowStop  = min(input.shape(), *current + Shape(radius+1));
+            MultiArrayView<N, InputValue> window = input.subarray(windowStart, windowStop);
+            result[*current] = window.template sum<SumType>() / window.size();
+        }
+    }
+    \endcode
+    
+    These simple tricks already get you a long way in the advanced use of VIGRA. You will notice, that many existing VIGRA functions are not implemented in temrs of \ref vigra::MultiArrayView, but in terms of \ref ImageIterators "image iterators" and \ref MultiIteratorGroup "hierarchical iterators". However, these iterators are quite difficult to use, so the MultiArrayView approach is recommended for new code.
+*/
+
+/** \page PythonBindingsTutorial VIGRA Python Bindings
+    
+    When you configure VIGRA with the option <tt>-DWITH_VIGRANUMPY=1</tt> while running cmake, a Python module <tt>vigra</tt> will be compiled and installed. It exposes most of VIGRA's functionality for easy scripting and prototyping in Python. Most importantly, VIGRA's Python bindings are fully integrated with the popular 'numpy' package so that you can call vigra functions directly with numpy <tt>ndarrays</tt>. No explicit or implicit conversion of data formats is required.
+    
+    The syntax of the Python version is usually very similar to the C++ syntax, with one important difference: You do not have to pass pre-allocated result images to the functions. That is, while in C++ you write
+    
+    \code
+    MultiArray<2, float> inputImage(Shape2(width, height)), 
+                         resultImage(inputImage.shape());  // pre-allocate result with correct shape
+    ... // fill inputImage
+    
+    // smooth image with Gaussian filter with sigma=1.5
+    // (pre-allocated resultImage must be passed to the function)
+    gaussianSmoothing(inputImage, resultImage, 1.5);
+    \endcode
+    
+    the corresponding Python call is
+    
+    \code
+    >>> import numpy, vigra
+    
+    >>> inputImage = numpy.zeros((width, height), dtype=numpy.float32)
+    ...  # fill inputImage
+    
+    # smooth image with Gaussian filter with sigma=1.5
+    # (resultImage is automatically allocated and returned) 
+    >>> resultImage = vigra.filters.gaussianSmoothing(inputImage, 1.5);
+    \endcode
+    
+    However, it is still possible to pass a result array of appropriate shape explicitly by means of the <tt>out</tt> parameter:
+    
+    \code
+    >>> resultImage = numpy.zeros(inputImage.shape, dtype=numpy.float32)
+    >>> vigra.filters.gaussianSmoothing(inputImage, 1.5, out=resultImage)
+    \endcode
+    
+    If the C++ function provides options, they are exposed on the Python side as keyword arguments:
+    
+    \code
+    >>> labeling, max_label = vigra.analysis.watersheds(inputImage, seeds=seedImage, method='UnionFind')
+    \endcode
+    
+    In general, the correspondence between a Python function and its C++ counterpart is straightforward, and the Python documentation frequently refers to the C++ documentation for details. However, there is an important caveat: the default axis interpretation is different in VIGRA's <tt>MultiArray</tt> (which uses 'Fortran order') and in numpy's <tt>ndarray</tt> (which uses 'C-order). To help you deal with this difficulty, vigranumpy provides a subclass <a href="../vigranumpy/index.html [...]
+    
+    The full Python documentation is available via <a href="../vigranumpy/index.html">HTML</a> or can be obtained directly from the Python prompt by the <tt>help()</tt> command:
+    
+    \code
+    >>> help(vigra.filters.gaussianSmoothing)
+    \endcode
+    
+    An important
+*/
diff --git a/docsrc/vigra-icon.ico b/docsrc/vigra-icon.ico
new file mode 100644
index 0000000..8d7dd85
Binary files /dev/null and b/docsrc/vigra-icon.ico differ
diff --git a/docsrc/vigra-icon.xcf b/docsrc/vigra-icon.xcf
new file mode 100644
index 0000000..f774827
Binary files /dev/null and b/docsrc/vigra-icon.xcf differ
diff --git a/docsrc/vigra-wiki.html b/docsrc/vigra-wiki.html
new file mode 100644
index 0000000..7eb9382
--- /dev/null
+++ b/docsrc/vigra-wiki.html
@@ -0,0 +1,9978 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<script id="versionArea" type="text/javascript">
+//<![CDATA[
+var version = {title: "TiddlyWiki", major: 2, minor: 6, revision: 0, date: new Date("Mar 18, 2010"), extensions: {}};
+//]]>
+</script>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<meta name="copyright" content="
+TiddlyWiki created by Jeremy Ruston, (jeremy [at] osmosoft [dot] com)
+
+Copyright (c) UnaMesa Association 2004-2009
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+Neither the name of the UnaMesa Association nor the names of its contributors may be
+used to endorse or promote products derived from this software without specific
+prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+" />
+<!--PRE-HEAD-START-->
+<!--{{{-->
+<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
+<!--}}}-->
+
+<!--PRE-HEAD-END-->
+<title> VIGRA Wiki Pages - powered by TiddlyWiki </title>
+<style id="styleArea" type="text/css">
+#saveTest {display:none;}
+#messageArea {display:none;}
+#copyright {display:none;}
+#storeArea {display:none;}
+#storeArea div {padding:0.5em; margin:1em 0em 0em 0em; border-color:#fff #666 #444 #ddd; border-style:solid; border-width:2px; overflow:auto;}
+#shadowArea {display:none;}
+#javascriptWarning {width:100%; text-align:center; font-weight:bold; background-color:#dd1100; color:#fff; padding:1em 0em;}
+</style>
+<!--POST-HEAD-START-->
+
+<!--POST-HEAD-END-->
+</head>
+<body onload="main();" onunload="if(window.unload) unload();">
+<!--PRE-BODY-START-->
+
+<!--PRE-BODY-END-->
+<div id="copyright">
+Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
+</div>
+<noscript>
+<div id="javascriptWarning">
+This page requires JavaScript to function properly.<br /><br />If you are using Microsoft Internet Explorer you may need to click on the yellow bar above and select 'Allow Blocked Content'. You must then click 'Yes' on the following security warning.
+</div>
+</noscript>
+<div id="saveTest"></div>
+<div id="backstageCloak"></div>
+<div id="backstageButton"></div>
+<div id="backstageArea"><div id="backstageToolbar"></div></div>
+<div id="backstage">
+	<div id="backstagePanel"></div>
+</div>
+<div id="contentWrapper"></div>
+<div id="contentStash"></div>
+<div id="shadowArea">
+<div title="MarkupPreHead">
+<pre><!--{{{-->
+<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
+<!--}}}-->
+</pre>
+</div>
+<div title="ColorPalette">
+<pre>Background: #fff
+Foreground: #000
+PrimaryPale: #8cf
+PrimaryLight: #18f
+PrimaryMid: #04b
+PrimaryDark: #014
+SecondaryPale: #ffc
+SecondaryLight: #fe8
+SecondaryMid: #db4
+SecondaryDark: #841
+TertiaryPale: #eee
+TertiaryLight: #ccc
+TertiaryMid: #999
+TertiaryDark: #666
+Error: #f88
+</pre>
+</div>
+<div title="StyleSheetColors">
+<pre>/*{{{*/
+body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
+
+a {color:[[ColorPalette::PrimaryMid]];}
+a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
+a img {border:0;}
+
+h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
+h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
+h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}
+
+.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
+.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
+.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}
+
+.header {background:[[ColorPalette::PrimaryMid]];}
+.headerShadow {color:[[ColorPalette::Foreground]];}
+.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
+.headerForeground {color:[[ColorPalette::Background]];}
+.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}
+
+.tabSelected{color:[[ColorPalette::PrimaryDark]];
+	background:[[ColorPalette::TertiaryPale]];
+	border-left:1px solid [[ColorPalette::TertiaryLight]];
+	border-top:1px solid [[ColorPalette::TertiaryLight]];
+	border-right:1px solid [[ColorPalette::TertiaryLight]];
+}
+.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
+.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
+.tabContents .button {border:0;}
+
+#sidebar {}
+#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
+#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
+#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
+#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
+#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}
+
+.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
+.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
+.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
+.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
+	border:1px solid [[ColorPalette::PrimaryMid]];}
+.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
+.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
+.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
+.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
+	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
+.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
+.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
+	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}
+
+.wizard .notChanged {background:transparent;}
+.wizard .changedLocally {background:#80ff80;}
+.wizard .changedServer {background:#8080ff;}
+.wizard .changedBoth {background:#ff8080;}
+.wizard .notFound {background:#ffff80;}
+.wizard .putToServer {background:#ff80ff;}
+.wizard .gotFromServer {background:#80ffff;}
+
+#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
+#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}
+
+.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}
+
+.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
+.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
+.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
+.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
+.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
+.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
+.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
+.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}
+
+.tiddler .defaultCommand {font-weight:bold;}
+
+.shadow .title {color:[[ColorPalette::TertiaryDark]];}
+
+.title {color:[[ColorPalette::SecondaryDark]];}
+.subtitle {color:[[ColorPalette::TertiaryDark]];}
+
+.toolbar {color:[[ColorPalette::PrimaryMid]];}
+.toolbar a {color:[[ColorPalette::TertiaryLight]];}
+.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
+.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}
+
+.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
+.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
+.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
+.tagging .button, .tagged .button {border:none;}
+
+.footer {color:[[ColorPalette::TertiaryLight]];}
+.selected .footer {color:[[ColorPalette::TertiaryMid]];}
+
+.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
+.sparktick {background:[[ColorPalette::PrimaryDark]];}
+
+.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
+.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
+.lowlight {background:[[ColorPalette::TertiaryLight]];}
+
+.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}
+
+.imageLink, #displayArea .imageLink {background:transparent;}
+
+.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}
+
+.viewer .listTitle {list-style-type:none; margin-left:-2em;}
+.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
+.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}
+
+.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
+.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
+.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}
+
+.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
+.viewer code {color:[[ColorPalette::SecondaryDark]];}
+.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}
+
+.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}
+
+.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
+.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
+.editorFooter {color:[[ColorPalette::TertiaryMid]];}
+.readOnly {background:[[ColorPalette::TertiaryPale]];}
+
+#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
+#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
+#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
+#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
+#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
+#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
+#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
+.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
+.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
+#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity=60)';}
+/*}}}*/</pre>
+</div>
+<div title="StyleSheetLayout">
+<pre>/*{{{*/
+* html .tiddler {height:1%;}
+
+body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}
+
+h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
+h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
+h4,h5,h6 {margin-top:1em;}
+h1 {font-size:1.35em;}
+h2 {font-size:1.25em;}
+h3 {font-size:1.1em;}
+h4 {font-size:1em;}
+h5 {font-size:.9em;}
+
+hr {height:1px;}
+
+a {text-decoration:none;}
+
+dt {font-weight:bold;}
+
+ol {list-style-type:decimal;}
+ol ol {list-style-type:lower-alpha;}
+ol ol ol {list-style-type:lower-roman;}
+ol ol ol ol {list-style-type:decimal;}
+ol ol ol ol ol {list-style-type:lower-alpha;}
+ol ol ol ol ol ol {list-style-type:lower-roman;}
+ol ol ol ol ol ol ol {list-style-type:decimal;}
+
+.txtOptionInput {width:11em;}
+
+#contentWrapper .chkOptionInput {border:0;}
+
+.externalLink {text-decoration:underline;}
+
+.indent {margin-left:3em;}
+.outdent {margin-left:3em; text-indent:-3em;}
+code.escaped {white-space:nowrap;}
+
+.tiddlyLinkExisting {font-weight:bold;}
+.tiddlyLinkNonExisting {font-style:italic;}
+
+/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
+a.tiddlyLinkNonExisting.shadow {font-weight:bold;}
+
+#mainMenu .tiddlyLinkExisting,
+	#mainMenu .tiddlyLinkNonExisting,
+	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
+#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}
+
+.header {position:relative;}
+.header a:hover {background:transparent;}
+.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
+.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0px; top:0px;}
+
+.siteTitle {font-size:3em;}
+.siteSubtitle {font-size:1.2em;}
+
+#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}
+
+#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
+#sidebarOptions {padding-top:0.3em;}
+#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
+#sidebarOptions input {margin:0.4em 0.5em;}
+#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
+#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
+#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
+#sidebarTabs .tabContents {width:15em; overflow:hidden;}
+
+.wizard {padding:0.1em 1em 0 2em;}
+.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
+.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
+.wizardStep {padding:1em 1em 1em 1em;}
+.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
+.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
+.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
+.wizard .button {padding:0.1em 0.2em;}
+
+#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
+.messageToolbar {display:block; text-align:right; padding:0.2em;}
+#messageArea a {text-decoration:underline;}
+
+.tiddlerPopupButton {padding:0.2em;}
+.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}
+
+.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
+.popup .popupMessage {padding:0.4em;}
+.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
+.popup li.disabled {padding:0.4em;}
+.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
+.listBreak {font-size:1px; line-height:1px;}
+.listBreak div {margin:2px 0;}
+
+.tabset {padding:1em 0 0 0.5em;}
+.tab {margin:0 0 0 0.25em; padding:2px;}
+.tabContents {padding:0.5em;}
+.tabContents ul, .tabContents ol {margin:0; padding:0;}
+.txtMainTab .tabContents li {list-style:none;}
+.tabContents li.listLink { margin-left:.75em;}
+
+#contentWrapper {display:block;}
+#splashScreen {display:none;}
+
+#displayArea {margin:1em 17em 0 14em;}
+
+.toolbar {text-align:right; font-size:.9em;}
+
+.tiddler {padding:1em 1em 0;}
+
+.missing .viewer,.missing .title {font-style:italic;}
+
+.title {font-size:1.6em; font-weight:bold;}
+
+.missing .subtitle {display:none;}
+.subtitle {font-size:1.1em;}
+
+.tiddler .button {padding:0.2em 0.4em;}
+
+.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
+.isTag .tagging {display:block;}
+.tagged {margin:0.5em; float:right;}
+.tagging, .tagged {font-size:0.9em; padding:0.25em;}
+.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
+.tagClear {clear:both;}
+
+.footer {font-size:.9em;}
+.footer li {display:inline;}
+
+.annotation {padding:0.5em; margin:0.5em;}
+
+* html .viewer pre {width:99%; padding:0 0 1em 0;}
+.viewer {line-height:1.4em; padding-top:0.5em;}
+.viewer .button {margin:0 0.25em; padding:0 0.25em;}
+.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
+.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}
+
+.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
+.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
+table.listView {font-size:0.85em; margin:0.8em 1.0em;}
+table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}
+
+.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
+.viewer code {font-size:1.2em; line-height:1.4em;}
+
+.editor {font-size:1.1em;}
+.editor input, .editor textarea {display:block; width:100%; font:inherit;}
+.editorFooter {padding:0.25em 0; font-size:.9em;}
+.editorFooter .button {padding-top:0px; padding-bottom:0px;}
+
+.fieldsetFix {border:0; padding:0; margin:1px 0px;}
+
+.sparkline {line-height:1em;}
+.sparktick {outline:0;}
+
+.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
+.zoomer div {padding:1em;}
+
+* html #backstage {width:99%;}
+* html #backstageArea {width:99%;}
+#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
+#backstageToolbar {position:relative;}
+#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
+#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
+#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
+#backstage {position:relative; width:100%; z-index:50;}
+#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
+.backstagePanelFooter {padding-top:0.2em; float:right;}
+.backstagePanelFooter a {padding:0.2em 0.4em;}
+#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}
+
+.whenBackstage {display:none;}
+.backstageVisible .whenBackstage {display:block;}
+/*}}}*/
+</pre>
+</div>
+<div title="StyleSheetLocale">
+<pre>/***
+StyleSheet for use when a translation requires any css style changes.
+This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
+***/
+/*{{{*/
+body {font-size:0.8em;}
+#sidebarOptions {font-size:1.05em;}
+#sidebarOptions a {font-style:normal;}
+#sidebarOptions .sliderPanel {font-size:0.95em;}
+.subtitle {font-size:0.8em;}
+.viewer table.listView {font-size:0.95em;}
+/*}}}*/</pre>
+</div>
+<div title="StyleSheetPrint">
+<pre>/*{{{*/
+ at media print {
+#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
+#displayArea {margin: 1em 1em 0em;}
+noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
+}
+/*}}}*/</pre>
+</div>
+<div title="PageTemplate">
+<pre><!--{{{-->
+<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
+<div class='headerShadow'>
+<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
+<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
+</div>
+<div class='headerForeground'>
+<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
+<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
+</div>
+</div>
+<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
+<div id='sidebar'>
+<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
+<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
+</div>
+<div id='displayArea'>
+<div id='messageArea'></div>
+<div id='tiddlerDisplay'></div>
+</div>
+<!--}}}--></pre>
+</div>
+<div title="ViewTemplate">
+<pre><!--{{{-->
+<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
+<div class='title' macro='view title'></div>
+<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
+<div class='tagging' macro='tagging'></div>
+<div class='tagged' macro='tags'></div>
+<div class='viewer' macro='view text wikified'></div>
+<div class='tagClear'></div>
+<!--}}}--></pre>
+</div>
+<div title="EditTemplate">
+<pre><!--{{{-->
+<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
+<div class='title' macro='view title'></div>
+<div class='editor' macro='edit title'></div>
+<div macro='annotations'></div>
+<div class='editor' macro='edit text'></div>
+<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
+<!--}}}--></pre>
+</div>
+<div title="GettingStarted">
+<pre>To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
+* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
+* [[MainMenu]]: The menu (usually on the left)
+* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
+You'll also need to enter your username for signing your edits: <<option txtUserName>></pre>
+</div>
+<div title="OptionsPanel">
+<pre>These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser
+
+Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])
+
+<<option txtUserName>>
+<<option chkSaveBackups>> [[SaveBackups]]
+<<option chkAutoSave>> [[AutoSave]]
+<<option chkRegExpSearch>> [[RegExpSearch]]
+<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
+<<option chkAnimate>> [[EnableAnimations]]
+
+----
+Also see [[AdvancedOptions]]</pre>
+</div>
+<div title="ImportTiddlers">
+<pre><<importTiddlers>></pre>
+</div>
+</div>
+<!--POST-SHADOWAREA-->
+<div id="storeArea">
+<div title="AliasPlugin" modifier="ELSDesignStudios" created="200509280700" modified="200909091131" tags="systemConfig" server.type="file" server.host="www.tiddlytools.com/#AliasPlugin" server.page.revision="200909091131">
+<pre>/***
+|Name|AliasPlugin|
+|Source|http://www.TiddlyTools.com/#AliasPlugin|
+|Documentation|http://www.TiddlyTools.com/#AliasPluginInfo|
+|Version|1.1.1|
+|Author|Eric Shulman|
+|License|http://www.TiddlyTools.com/#LegalStatements|
+|~CoreVersion|2.1|
+|Type|plugin|
+|Description|Create text-substitution macros|
+Define macros for abbreviations and other "aliases", and then embed them in the rest of your tiddler content to quickly insert common terms, phrases and links without a lot of repetitive typing.
+!!!!!Documentation
+> see [[AliasPluginInfo]]
+!!!!!Revisions
+<<<
+2009.09.09 [1.1.1] 'tiddler' arg passed to wikify() so aliases containing macros render with correct context
+| Please see [[AliasPluginInfo]] for previous revision details |
+2005.08.12 [1.0.0] initial release
+<<<
+!!!!!Code
+***/
+//{{{
+version.extensions.AliasPlugin= {major: 1, minor: 1, revision: 1, date: new Date(2009,9,9)};
+config.macros.alias= { };
+config.macros.alias.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
+	var alias=params.shift(); if (!alias) return; alias=alias.replace(/ /g,"_"); // don't allow spaces in alias
+	if (config.macros[alias]==undefined) { // create new macro (as needed)
+		config.macros[alias] = { };
+		config.macros[alias].handler =
+			function (place,macroName,params,wikifier,paramString,tiddler)
+				{ wikify(config.macros[macroName].text.format(params),place,null,tiddler); }
+	}
+	config.macros[alias].text = params[0]?params.join(' '):alias;	// set alias text
+}
+//}}}</pre>
+</div>
+<div title="AliasPluginInfo" modifier="UllrichKoethe" created="200509280700" modified="201005021126" tags="pluginInfo" server.type="file" server.host="www.tiddlytools.com/#AliasPlugin" server.page.revision="200909091131" changecount="1">
+<pre>/***
+|Name|AliasPlugin|
+|Source|http://www.TiddlyTools.com/#AliasPlugin|
+|Documentation|http://www.TiddlyTools.com/#AliasPluginInfo|
+|Version|1.1.1|
+|Author|Eric Shulman|
+|License|http://www.TiddlyTools.com/#LegalStatements|
+|~CoreVersion|2.1|
+|Type|documentation|
+|Description|documentation for AliasPlugin|
+Define macros for abbreviations and other "aliases", and then embed them in the rest of your tiddler content to quickly insert common terms, phrases and links without a lot of repetitive typing.
+!!!!!Usage
+<<<
+{{{
+<<alias keyword "content to display">>
+}}}
+Select a short keyword or other abbreviated term that is easily input with just a few keystrokes.  When the {{{<<alias>>}}} macro is processed, it creates a new macro for you to embed in tiddler content, using the specified alias keyword as the name for that new macro.  You can choose any keyword you like, but don't include any spaces, as macro names must not contain spaces.
+
+In order to ensure that your aliases are always defined and available for use, you should add your definitions to a tiddler that you are certain will be displayed when your TW is first loaded (e.g., [[MainMenu]]).  The {{{<<alias>>}}} macro itself won't actually produce any visible output, so it can be safely added to practically any tiddler without producing a change in that tiddler's appearance.
+
+To use the aliases you have defined, simply invoke them as you would any other TiddlyWiki macro, e.g.,
+{{{<<keyword>>}}}.  If you include parameters when you invoke the macro -- {{{<<keyword param param param...>>}}} -- they can be inserted direclty into the output by replacing corresponding substitution markers, indicated by using "%0" through "%9" in the "text to display" parameter used when the alias was defined.  For example, to define a quick alias for inserting a link to any given subject on www.wikipedia.com, you can write:
+{{{
+<<alias wikipedia "[[Wikipedia:%0|http://www.wikipedia.com/wiki/%0]]">>
+}}}
+which allows you to then write:
+{{{
+<<wikipedia TiddlyWiki>>
+}}}
+which is processed as if you wrote:
+{{{
+[[Wikipedia:TiddlyWiki|http://www.wikipedia.com/wiki/TiddlyWiki]]
+}}}
+and is displayed this way:
+><<alias wikipedia "[[Wikipedia:%0|http://www.wikipedia.com/wiki/%0]]">><<wikipedia TiddlyWiki>>
+
+Another interesting example uses the substitution markers to automatically display a reference to a TiddlerSlice value:
+{{{
+<<alias describe {{"|\<\<tiddler [[%0::Description]]\>\>|\n"}}>>
+}}}
+which allows you to then write:
+{{{
+<<describe AliasPlugin>>
+}}}
+which is processed as if you wrote:
+{{{
+|<<tiddler [[AliasPlugin::Description]]>>|
+}}}
+and is displayed this way:
+<<alias describe {{"|\<\<tiddler [[%0::Description]]\>\>|\n"}}>><<describe AliasPlugin>>
+<<<
+!!!!!Revisions
+<<<
+2009.09.09 1.1.1 'tiddler' arg passed to wikify() so aliases containing macros render with correct context
+2008.03.11 [*.*.*] plugin size reduction - documentation moved to [[AliasPluginInfo]]
+2007.03.21 1.1.0 added support for parameter substitution into alias macros, using format() method and%0..%9 markers
+2005.10.09 1.0.3 combined documentation and code into a single tiddler
+2005.08.12 1.0.0 initial release
+<<<</pre>
+</div>
+<div title="ConfigTweaks" creator="UllrichKoethe" modifier="UllrichKoethe" created="201005020842" modified="201005021145" tags="systemConfig" changecount="10">
+<pre>//{{{
+config.options.chkHttpReadOnly = true;
+config.options.chkSaveBackups = false;  
+readOnly = false;
+showBackstage = true;
+//}}}
+</pre>
+</div>
+<div title="Download MathSVGPlugin" modifier="UllrichKoethe" created="201005020840" modified="201005021052" tags="systemServer" changecount="5">
+<pre>|''Type:''|file|
+|''URL:''|http://www.math.ist.utl.pt/~psoares/MathSVG.html|
+|''Workspace:''|(default)|
+
+This plugin for ~TiddlyWiki >=2.5 provides an easy way to:
+
+# translate ~LaTeX math equations to ~MathML;
+# produce mathematical SVG graphics.
+
+If you use MS Internet Explorer, you may need the [[MathPlayer|http://www.dessci.com/en/products/mathplayer/download.htm]] plugin to render ~MathML.</pre>
+</div>
+<div title="GettingStarted" creator="UllrichKoethe" modifier="UllrichKoethe" created="201005020846" changecount="1">
+<pre>To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
+* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
+* [[MainMenu]]: The menu (usually on the left)
+* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
+You'll also need to enter your username for signing your edits: <<option txtUserName>></pre>
+</div>
+<div title="MathSVGPlugin" modifier="PauloSoares" created="200710081238" modified="201004071427" tags="systemConfig" server.type="file" server.host="www.math.ist.utl.pt/~psoares/MathSVG.html" server.page.revision="201004071427">
+<pre>/***
+|''Name:''|MathSVGPlugin|
+|''Description:''|This plugin translates a subset of the LaTeX math notation to MathML with a customisable  image fallback when MathML is not supported. It also provides an easy way to produce mathematical SVG graphics with dynamical features and animation.|
+|''Version:''|1.4.1|
+|''Date:''|2010-04-01|
+|''Source:''|http://www.math.ist.utl.pt/~psoares/MathSVG.html|
+|''Author:''|Paulo Soares|
+|''License:''|[[GNU Lesser General Public License|http://www.gnu.org/licences/lgpl.html]]|
+|''~CoreVersion:''|2.5.0|
+!Original copyright notice
+{{{
+ASCIIMathML.js
+==============
+Version 2.1 Oct 8, 2008, (c) Peter Jipsen http://www.chapman.edu/~jipsen
+This version extends ASCIIMathML.js with LaTeXMathML.js and ASCIIsvg.js.
+Latest version at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML.js
+If you use it on a webpage, please send the URL to jipsen at chapman.edu
+
+The LaTeXMathML modifications were made by Douglas Woodall, June 2006.
+(for details see header on the LaTeXMathML part in middle of file)
+Extensive clean-up and improvements by Paulo Soares, Oct 2007.
+
+This program 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 program 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 
+(at http://www.gnu.org/licences/lgpl.html) for more details.
+}}}
+!~MathSVG code (minified)
+***/
+//{{{
+Math.sec=function(a){return 1/Math.cos(a)};Math.csc=function(a){return 1/Math.sin(a)};Math.cot=function(a){return 1/Math.tan(a)};Math.asec=function(a){return Math.acos(1/a)};Math.acsc=function(a){return Math.asin(1/a)};Math.acot=function(a){return Math.atan(1/a)};Math.sinh=function(a){return(Math.exp(a)-Math.exp(-a))/2};Math.cosh=function(a){return(Math.exp(a)+Math.exp(-a))/2};Math.tanh=function(a){return(Math.exp(a)-Math.exp(-a))/(Math.exp(a)+Math.exp(-a))};Math.sech=function(a){return  [...]
+//}}}
+/***
+!~TiddlyWiki formatters
+***/
+//{{{
+if(!version.extensions.MathSVGPlugin) { //# ensure that the plugin is only installed once
+version.extensions.MathSVGPlugin = {installed: true};
+MSVG.generic();
+
+config.formatterHelpers.MathSVGHelper = function(w) {
+  if(MSVG.noMathTag && jQuery.inArray(MSVG.noMathTag,w.tiddler.tags)>-1) return;
+  this.lookaheadRegExp.lastIndex = w.matchStart;
+  var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+  if(lookaheadMatch){
+    var eq = MSVG.parseMath(lookaheadMatch[1],this.displaystyle);
+    if(this.displaystyle){
+      var node = createTiddlyElement(w.output,"div");
+      node.style.textAlign='center';
+      node.appendChild(eq);
+      w.output.appendChild(node);
+    } else {w.output.appendChild(eq);}
+    w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
+  }
+}
+
+config.formatters.push( {
+  name: "clatex",
+  match: "\\$\\$",
+  lookaheadRegExp: /\$\$((?:.|\n)*?)\$\$/mg,
+  displaystyle: true,
+  handler: config.formatterHelpers.MathSVGHelper
+})
+
+config.formatters.push( {
+  name: "clatex2",
+  match: "\\\\\\\[",
+  lookaheadRegExp: /\\\[((?:.|\n)*?)\\\]/mg,
+  displaystyle: true,
+  handler: config.formatterHelpers.MathSVGHelper
+})
+
+config.formatters.push( {
+  name: "latex",
+  match: "\\$",
+  lookaheadRegExp: /\$((?:.|\n)*?)\$/mg,
+  displaystyle: false,
+  handler: config.formatterHelpers.MathSVGHelper
+})
+
+config.formatters.push( {
+  name: "latex2",
+  match: "\\\\\\\(",
+  lookaheadRegExp: /\\\(((?:.|\n)*?)\\\)/mg,
+  displaystyle: false,
+  handler: config.formatterHelpers.MathSVGHelper
+})
+
+config.formatters.push( {
+  name: "graph",
+  match: "<div",
+  lookaheadRegExp: /<div.+SVGgraph.+?>((?:.|\n)*?)<\/div>/mg,
+  handler: function(w){
+    if(MSVG.noSvgTag && jQuery.inArray(MSVG.noSvgTag,w.tiddler.tags)>-1) return;
+    this.lookaheadRegExp.lastIndex = w.matchStart;
+    var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+    if(lookaheadMatch){
+      var text = lookaheadMatch[0].replace('<div','<div id="currentGraph"');
+      jQuery(w.output).append(text);
+      MSVG.initPictures("#currentGraph");
+      w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
+    }
+  }
+})
+
+config.formatters.push( {
+  name: "inlineGraph",
+  match: "<span",
+  lookaheadRegExp: /<span.+SVGgraph.+?>((?:.|\n)*?)<\/span>/mg,
+  handler: function(w){
+    if(MSVG.noSvgTag && jQuery.inArray(MSVG.noSvgTag,w.tiddler.tags)>-1) return;
+    this.lookaheadRegExp.lastIndex = w.matchStart;
+    var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+    if(lookaheadMatch){
+      var text = lookaheadMatch[0].replace('<span','<span id="currentGraph"');
+      jQuery(w.output).append(text);
+      MSVG.initPictures("#currentGraph");
+      w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
+    }
+  }
+})
+
+}
+//}}}</pre>
+</div>
+<div title="MathSVGPluginComp" modifier="PauloSoares" created="200710092057" modified="201001091828" tags="systemConfig" server.type="file" server.host="www.math.ist.utl.pt/~psoares/MathSVG.html" server.page.revision="201001091828">
+<pre>/***
+The script should not be edited. All available options can be set by the following variables:
+***/
+//{{{
+//MSVG.showFormulaOnMouseOver = false; //show LaTeX code on mouse over the equation
+//MSVG.latexImages = false; //set to true to force the use of an external converter
+//MSVG.latexConverter = "http://www.yourequations.com/eq.latex?"; //link to external converter
+//MSVG.mathColor = "green"; //font color
+//MSVG.mathFontSize = ""; //font size
+//MSVG.mathFontFamily = ""; //font family
+MSVG.noMathTag = null;
+MSVG.noSvgTag = 'noSVG';
+//}}}
+/***
+New symbols or commands can be defined here:
+***/
+//{{{
+ var commands = ["nle","R","diagup","varnothing","ind","DD"];
+ var symbols = ["\u2270","\u211D","\u2571","\u2205","\u2AEB","\\frac{d}{dr}"];
+ MSVG.define(commands,symbols);
+//}}}
+/***
+External javascript code can be loaded here:
+***/
+//{{{
+ jQuery.getScript("demo.js");
+//}}}
+</pre>
+</div>
+<div title="SiteSubtitle" creator="UllrichKoethe" modifier="UllrichKoethe" created="201005020843" modified="201005021058" changecount="3">
+<pre>powered by ~TiddlyWiki</pre>
+</div>
+<div title="SiteTitle" creator="UllrichKoethe" modifier="UllrichKoethe" created="201005020843" changecount="1">
+<pre>VIGRA Wiki Pages</pre>
+</div>
+<div title="Test Tiddler" creator="UllrichKoethe" modifier="UllrichKoethe" created="201005021129" modified="201005021131" changecount="3">
+<pre><<VigraReference>></pre>
+</div>
+<div title="VigraReference" creator="UllrichKoethe" modifier="UllrichKoethe" created="201005021143" changecount="1">
+<pre>See <<VigraReference>></pre>
+</div>
+<div title="VigraUrlMapping" creator="UllrichKoethe" modifier="UllrichKoethe" created="201005021128" modified="201005021131" changecount="5">
+<pre><<alias VigraReference "[[VigraReference|file:///c:/ukoethe/vigra-hg/vigra/doc/vigra/index.html]]">>
+</pre>
+</div>
+</div>
+<!--POST-STOREAREA-->
+<!--POST-BODY-START-->
+<!--POST-BODY-END-->
+<script id="jsArea" type="text/javascript">
+//<![CDATA[
+//
+// Please note:
+//
+// * This code is designed to be readable but for compactness it only includes brief comments. You can see fuller comments
+//   in the project Subversion repository at http://svn.tiddlywiki.org/Trunk/core/
+//
+// * You should never need to modify this source code directly. TiddlyWiki is carefully designed to allow deep customisation
+//   without changing the core code. Please consult the development group at http://groups.google.com/group/TiddlyWikiDev
+//
+
+//--
+//-- Configuration repository
+//--
+
+// Miscellaneous options
+var config = {
+	numRssItems: 20, // Number of items in the RSS feed
+	animDuration: 400, // Duration of UI animations in milliseconds
+	cascadeFast: 20, // Speed for cascade animations (higher == slower)
+	cascadeSlow: 60, // Speed for EasterEgg cascade animations
+	cascadeDepth: 5, // Depth of cascade animation
+	locale: "en" // W3C language tag
+};
+
+// Hashmap of alternative parsers for the wikifier
+config.parsers = {};
+
+// Adaptors
+config.adaptors = {};
+config.defaultAdaptor = null;
+
+// Backstage tasks
+config.tasks = {};
+
+// Annotations
+config.annotations = {};
+
+// Custom fields to be automatically added to new tiddlers
+config.defaultCustomFields = {};
+
+// Messages
+config.messages = {
+	messageClose: {},
+	dates: {},
+	tiddlerPopup: {}
+};
+
+// Options that can be set in the options panel and/or cookies
+config.options = {
+	chkRegExpSearch: false,
+	chkCaseSensitiveSearch: false,
+	chkIncrementalSearch: true,
+	chkAnimate: true,
+	chkSaveBackups: true,
+	chkAutoSave: false,
+	chkGenerateAnRssFeed: false,
+	chkSaveEmptyTemplate: false,
+	chkOpenInNewWindow: true,
+	chkToggleLinks: false,
+	chkHttpReadOnly: true,
+	chkForceMinorUpdate: false,
+	chkConfirmDelete: true,
+	chkInsertTabs: false,
+	chkUsePreForStorage: true, // Whether to use <pre> format for storage
+	chkDisplayInstrumentation: false,
+	txtBackupFolder: "",
+	txtEditorFocus: "text",
+	txtMainTab: "tabTimeline",
+	txtMoreTab: "moreTabAll",
+	txtMaxEditRows: "30",
+	txtFileSystemCharSet: "UTF-8",
+	txtTheme: ""
+	};
+config.optionsDesc = {};
+
+// Default tiddler templates
+var DEFAULT_VIEW_TEMPLATE = 1;
+var DEFAULT_EDIT_TEMPLATE = 2;
+config.tiddlerTemplates = {
+	1: "ViewTemplate",
+	2: "EditTemplate"
+};
+
+// More messages (rather a legacy layout that should not really be like this)
+config.views = {
+	wikified: {
+		tag: {}
+	},
+	editor: {
+		tagChooser: {}
+	}
+};
+
+// Backstage tasks
+config.backstageTasks = ["save","sync","importTask","tweak","upgrade","plugins"];
+
+// Extensions
+config.extensions = {};
+
+// Macros; each has a 'handler' member that is inserted later
+config.macros = {
+	today: {},
+	version: {},
+	search: {sizeTextbox: 15},
+	tiddler: {},
+	tag: {},
+	tags: {},
+	tagging: {},
+	timeline: {},
+	allTags: {},
+	list: {
+		all: {},
+		missing: {},
+		orphans: {},
+		shadowed: {},
+		touched: {},
+		filter: {}
+	},
+	closeAll: {},
+	permaview: {},
+	saveChanges: {},
+	slider: {},
+	option: {},
+	options: {},
+	newTiddler: {},
+	newJournal: {},
+	tabs: {},
+	gradient: {},
+	message: {},
+	view: {defaultView: "text"},
+	edit: {},
+	tagChooser: {},
+	toolbar: {},
+	plugins: {},
+	refreshDisplay: {},
+	importTiddlers: {},
+	upgrade: {
+		source: "http://www.tiddlywiki.com/upgrade/",
+		backupExtension: "pre.core.upgrade"
+	},
+	sync: {},
+	annotations: {}
+};
+
+// Commands supported by the toolbar macro
+config.commands = {
+	closeTiddler: {},
+	closeOthers: {},
+	editTiddler: {},
+	saveTiddler: {hideReadOnly: true},
+	cancelTiddler: {},
+	deleteTiddler: {hideReadOnly: true},
+	permalink: {},
+	references: {type: "popup"},
+	jump: {type: "popup"},
+	syncing: {type: "popup"},
+	fields: {type: "popup"}
+};
+
+// Browser detection... In a very few places, there's nothing else for it but to know what browser we're using.
+config.userAgent = navigator.userAgent.toLowerCase();
+config.browser = {
+	isIE: config.userAgent.indexOf("msie") != -1 && config.userAgent.indexOf("opera") == -1,
+	isGecko: navigator.product == "Gecko" && config.userAgent.indexOf("WebKit") == -1,
+	ieVersion: /MSIE (\d.\d)/i.exec(config.userAgent), // config.browser.ieVersion[1], if it exists, will be the IE version string, eg "6.0"
+	isSafari: config.userAgent.indexOf("applewebkit") != -1,
+	isBadSafari: !((new RegExp("[\u0150\u0170]","g")).test("\u0150")),
+	firefoxDate: /gecko\/(\d{8})/i.exec(config.userAgent), // config.browser.firefoxDate[1], if it exists, will be Firefox release date as "YYYYMMDD"
+	isOpera: config.userAgent.indexOf("opera") != -1,
+	isLinux: config.userAgent.indexOf("linux") != -1,
+	isUnix: config.userAgent.indexOf("x11") != -1,
+	isMac: config.userAgent.indexOf("mac") != -1,
+	isWindows: config.userAgent.indexOf("win") != -1
+};
+
+// Basic regular expressions
+config.textPrimitives = {
+	upperLetter: "[A-Z\u00c0-\u00de\u0150\u0170]",
+	lowerLetter: "[a-z0-9_\\-\u00df-\u00ff\u0151\u0171]",
+	anyLetter:   "[A-Za-z0-9_\\-\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]",
+	anyLetterStrict: "[A-Za-z0-9\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]"
+};
+if(config.browser.isBadSafari) {
+	config.textPrimitives = {
+		upperLetter: "[A-Z\u00c0-\u00de]",
+		lowerLetter: "[a-z0-9_\\-\u00df-\u00ff]",
+		anyLetter:   "[A-Za-z0-9_\\-\u00c0-\u00de\u00df-\u00ff]",
+		anyLetterStrict: "[A-Za-z0-9\u00c0-\u00de\u00df-\u00ff]"
+	};
+}
+config.textPrimitives.sliceSeparator = "::";
+config.textPrimitives.sectionSeparator = "##";
+config.textPrimitives.urlPattern = "(?:file|http|https|mailto|ftp|irc|news|data):[^\\s'\"]+(?:/|\\b)";
+config.textPrimitives.unWikiLink = "~";
+config.textPrimitives.wikiLink = "(?:(?:" + config.textPrimitives.upperLetter + "+" +
+	config.textPrimitives.lowerLetter + "+" +
+	config.textPrimitives.upperLetter +
+	config.textPrimitives.anyLetter + "*)|(?:" +
+	config.textPrimitives.upperLetter + "{2,}" +
+	config.textPrimitives.lowerLetter + "+))";
+
+config.textPrimitives.cssLookahead = "(?:(" + config.textPrimitives.anyLetter + "+)\\(([^\\)\\|\\n]+)(?:\\):))|(?:(" + config.textPrimitives.anyLetter + "+):([^;\\|\\n]+);)";
+config.textPrimitives.cssLookaheadRegExp = new RegExp(config.textPrimitives.cssLookahead,"mg");
+
+config.textPrimitives.brackettedLink = "\\[\\[([^\\]]+)\\]\\]";
+config.textPrimitives.titledBrackettedLink = "\\[\\[([^\\[\\]\\|]+)\\|([^\\[\\]\\|]+)\\]\\]";
+config.textPrimitives.tiddlerForcedLinkRegExp = new RegExp("(?:" + config.textPrimitives.titledBrackettedLink + ")|(?:" +
+	config.textPrimitives.brackettedLink + ")|(?:" +
+	config.textPrimitives.urlPattern + ")","mg");
+config.textPrimitives.tiddlerAnyLinkRegExp = new RegExp("("+ config.textPrimitives.wikiLink + ")|(?:" +
+	config.textPrimitives.titledBrackettedLink + ")|(?:" +
+	config.textPrimitives.brackettedLink + ")|(?:" +
+	config.textPrimitives.urlPattern + ")","mg");
+
+config.glyphs = {
+	browsers: [
+		function() {return config.browser.isIE;},
+		function() {return true;}
+	],
+	currBrowser: null,
+	codes: {
+		downTriangle: ["\u25BC","\u25BE"],
+		downArrow: ["\u2193","\u2193"],
+		bentArrowLeft: ["\u2190","\u21A9"],
+		bentArrowRight: ["\u2192","\u21AA"]
+	}
+};
+
+//--
+//-- Shadow tiddlers
+//--
+
+config.shadowTiddlers = {
+	StyleSheet: "",
+	MarkupPreHead: "",
+	MarkupPostHead: "",
+	MarkupPreBody: "",
+	MarkupPostBody: "",
+	TabTimeline: '<<timeline>>',
+	TabAll: '<<list all>>',
+	TabTags: '<<allTags excludeLists>>',
+	TabMoreMissing: '<<list missing>>',
+	TabMoreOrphans: '<<list orphans>>',
+	TabMoreShadowed: '<<list shadowed>>',
+	AdvancedOptions: '<<options>>',
+	PluginManager: '<<plugins>>',
+	ToolbarCommands: '|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|\n|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|',
+	WindowTitle: '<<tiddler SiteTitle>> - <<tiddler SiteSubtitle>>'
+};
+
+//--
+//-- Translateable strings
+//--
+
+// Strings in "double quotes" should be translated; strings in 'single quotes' should be left alone
+
+merge(config.options,{
+	txtUserName: "YourName"});
+
+merge(config.tasks,{
+	save: {text: "save", tooltip: "Save your changes to this TiddlyWiki", action: saveChanges},
+	sync: {text: "sync", tooltip: "Synchronise changes with other TiddlyWiki files and servers", content: '<<sync>>'},
+	importTask: {text: "import", tooltip: "Import tiddlers and plugins from other TiddlyWiki files and servers", content: '<<importTiddlers>>'},
+	tweak: {text: "tweak", tooltip: "Tweak the appearance and behaviour of TiddlyWiki", content: '<<options>>'},
+	upgrade: {text: "upgrade", tooltip: "Upgrade TiddlyWiki core code", content: '<<upgrade>>'},
+	plugins: {text: "plugins", tooltip: "Manage installed plugins", content: '<<plugins>>'}
+});
+
+// Options that can be set in the options panel and/or cookies
+merge(config.optionsDesc,{
+	txtUserName: "Username for signing your edits",
+	chkRegExpSearch: "Enable regular expressions for searches",
+	chkCaseSensitiveSearch: "Case-sensitive searching",
+	chkIncrementalSearch: "Incremental key-by-key searching",
+	chkAnimate: "Enable animations",
+	chkSaveBackups: "Keep backup file when saving changes",
+	chkAutoSave: "Automatically save changes",
+	chkGenerateAnRssFeed: "Generate an RSS feed when saving changes",
+	chkSaveEmptyTemplate: "Generate an empty template when saving changes",
+	chkOpenInNewWindow: "Open external links in a new window",
+	chkToggleLinks: "Clicking on links to open tiddlers causes them to close",
+	chkHttpReadOnly: "Hide editing features when viewed over HTTP",
+	chkForceMinorUpdate: "Don't update modifier username and date when editing tiddlers",
+	chkConfirmDelete: "Require confirmation before deleting tiddlers",
+	chkInsertTabs: "Use the tab key to insert tab characters instead of moving between fields",
+	txtBackupFolder: "Name of folder to use for backups",
+	txtMaxEditRows: "Maximum number of rows in edit boxes",
+	txtTheme: "Name of the theme to use",
+	txtFileSystemCharSet: "Default character set for saving changes (Firefox/Mozilla only)"});
+
+merge(config.messages,{
+	customConfigError: "Problems were encountered loading plugins. See PluginManager for details",
+	pluginError: "Error: %0",
+	pluginDisabled: "Not executed because disabled via 'systemConfigDisable' tag",
+	pluginForced: "Executed because forced via 'systemConfigForce' tag",
+	pluginVersionError: "Not executed because this plugin needs a newer version of TiddlyWiki",
+	nothingSelected: "Nothing is selected. You must select one or more items first",
+	savedSnapshotError: "It appears that this TiddlyWiki has been incorrectly saved. Please see http://www.tiddlywiki.com/#Download for details",
+	subtitleUnknown: "(unknown)",
+	undefinedTiddlerToolTip: "The tiddler '%0' doesn't yet exist",
+	shadowedTiddlerToolTip: "The tiddler '%0' doesn't yet exist, but has a pre-defined shadow value",
+	tiddlerLinkTooltip: "%0 - %1, %2",
+	externalLinkTooltip: "External link to %0",
+	noTags: "There are no tagged tiddlers",
+	notFileUrlError: "You need to save this TiddlyWiki to a file before you can save changes",
+	cantSaveError: "It's not possible to save changes. Possible reasons include:\n- your browser doesn't support saving (Firefox, Internet Explorer, Safari and Opera all work if properly configured)\n- the pathname to your TiddlyWiki file contains illegal characters\n- the TiddlyWiki HTML file has been moved or renamed",
+	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
+	backupSaved: "Backup saved",
+	backupFailed: "Failed to save backup file",
+	rssSaved: "RSS feed saved",
+	rssFailed: "Failed to save RSS feed file",
+	emptySaved: "Empty template saved",
+	emptyFailed: "Failed to save empty template file",
+	mainSaved: "Main TiddlyWiki file saved",
+	mainFailed: "Failed to save main TiddlyWiki file. Your changes have not been saved",
+	macroError: "Error in macro <<\%0>>",
+	macroErrorDetails: "Error while executing macro <<\%0>>:\n%1",
+	missingMacro: "No such macro",
+	overwriteWarning: "A tiddler named '%0' already exists. Choose OK to overwrite it",
+	unsavedChangesWarning: "WARNING! There are unsaved changes in TiddlyWiki\n\nChoose OK to save\nChoose CANCEL to discard",
+	confirmExit: "--------------------------------\n\nThere are unsaved changes in TiddlyWiki. If you continue you will lose those changes\n\n--------------------------------",
+	saveInstructions: "SaveChanges",
+	unsupportedTWFormat: "Unsupported TiddlyWiki format '%0'",
+	tiddlerSaveError: "Error when saving tiddler '%0'",
+	tiddlerLoadError: "Error when loading tiddler '%0'",
+	wrongSaveFormat: "Cannot save with storage format '%0'. Using standard format for save.",
+	invalidFieldName: "Invalid field name %0",
+	fieldCannotBeChanged: "Field '%0' cannot be changed",
+	loadingMissingTiddler: "Attempting to retrieve the tiddler '%0' from the '%1' server at:\n\n'%2' in the workspace '%3'",
+	upgradeDone: "The upgrade to version %0 is now complete\n\nClick 'OK' to reload the newly upgraded TiddlyWiki"});
+
+merge(config.messages.messageClose,{
+	text: "close",
+	tooltip: "close this message area"});
+
+config.messages.backstage = {
+	open: {text: "backstage", tooltip: "Open the backstage area to perform authoring and editing tasks"},
+	close: {text: "close", tooltip: "Close the backstage area"},
+	prompt: "backstage: ",
+	decal: {
+		edit: {text: "edit", tooltip: "Edit the tiddler '%0'"}
+	}
+};
+
+config.messages.listView = {
+	tiddlerTooltip: "Click for the full text of this tiddler",
+	previewUnavailable: "(preview not available)"
+};
+
+config.messages.dates.months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November","December"];
+config.messages.dates.days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
+config.messages.dates.shortMonths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+config.messages.dates.shortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+// suffixes for dates, eg "1st","2nd","3rd"..."30th","31st"
+config.messages.dates.daySuffixes = ["st","nd","rd","th","th","th","th","th","th","th",
+		"th","th","th","th","th","th","th","th","th","th",
+		"st","nd","rd","th","th","th","th","th","th","th",
+		"st"];
+config.messages.dates.am = "am";
+config.messages.dates.pm = "pm";
+
+merge(config.messages.tiddlerPopup,{
+	});
+
+merge(config.views.wikified.tag,{
+	labelNoTags: "no tags",
+	labelTags: "tags: ",
+	openTag: "Open tag '%0'",
+	tooltip: "Show tiddlers tagged with '%0'",
+	openAllText: "Open all",
+	openAllTooltip: "Open all of these tiddlers",
+	popupNone: "No other tiddlers tagged with '%0'"});
+
+merge(config.views.wikified,{
+	defaultText: "The tiddler '%0' doesn't yet exist. Double-click to create it",
+	defaultModifier: "(missing)",
+	shadowModifier: "(built-in shadow tiddler)",
+	dateFormat: "DD MMM YYYY",
+	createdPrompt: "created"});
+
+merge(config.views.editor,{
+	tagPrompt: "Type tags separated with spaces, [[use double square brackets]] if necessary, or add existing",
+	defaultText: "Type the text for '%0'"});
+
+merge(config.views.editor.tagChooser,{
+	text: "tags",
+	tooltip: "Choose existing tags to add to this tiddler",
+	popupNone: "There are no tags defined",
+	tagTooltip: "Add the tag '%0'"});
+
+merge(config.messages,{
+	sizeTemplates:
+		[
+		{unit: 1024*1024*1024, template: "%0\u00a0GB"},
+		{unit: 1024*1024, template: "%0\u00a0MB"},
+		{unit: 1024, template: "%0\u00a0KB"},
+		{unit: 1, template: "%0\u00a0B"}
+		]});
+
+merge(config.macros.search,{
+	label: "search",
+	prompt: "Search this TiddlyWiki",
+	accessKey: "F",
+	successMsg: "%0 tiddlers found matching %1",
+	failureMsg: "No tiddlers found matching %0"});
+
+merge(config.macros.tagging,{
+	label: "tagging: ",
+	labelNotTag: "not tagging",
+	tooltip: "List of tiddlers tagged with '%0'"});
+
+merge(config.macros.timeline,{
+	dateFormat: "DD MMM YYYY"});
+
+merge(config.macros.allTags,{
+	tooltip: "Show tiddlers tagged with '%0'",
+	noTags: "There are no tagged tiddlers"});
+
+config.macros.list.all.prompt = "All tiddlers in alphabetical order";
+config.macros.list.missing.prompt = "Tiddlers that have links to them but are not defined";
+config.macros.list.orphans.prompt = "Tiddlers that are not linked to from any other tiddlers";
+config.macros.list.shadowed.prompt = "Tiddlers shadowed with default contents";
+config.macros.list.touched.prompt = "Tiddlers that have been modified locally";
+
+merge(config.macros.closeAll,{
+	label: "close all",
+	prompt: "Close all displayed tiddlers (except any that are being edited)"});
+
+merge(config.macros.permaview,{
+	label: "permaview",
+	prompt: "Link to an URL that retrieves all the currently displayed tiddlers"});
+
+merge(config.macros.saveChanges,{
+	label: "save changes",
+	prompt: "Save all tiddlers to create a new TiddlyWiki",
+	accessKey: "S"});
+
+merge(config.macros.newTiddler,{
+	label: "new tiddler",
+	prompt: "Create a new tiddler",
+	title: "New Tiddler",
+	accessKey: "N"});
+
+merge(config.macros.newJournal,{
+	label: "new journal",
+	prompt: "Create a new tiddler from the current date and time",
+	accessKey: "J"});
+
+merge(config.macros.options,{
+	wizardTitle: "Tweak advanced options",
+	step1Title: "These options are saved in cookies in your browser",
+	step1Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='false' name='chkUnknown'>Show unknown options</input>",
+	unknownDescription: "//(unknown)//",
+	listViewTemplate: {
+		columns: [
+			{name: 'Option', field: 'option', title: "Option", type: 'String'},
+			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
+			{name: 'Name', field: 'name', title: "Name", type: 'String'}
+			],
+		rowClasses: [
+			{className: 'lowlight', field: 'lowlight'}
+			]}
+	});
+
+merge(config.macros.plugins,{
+	wizardTitle: "Manage plugins",
+	step1Title: "Currently loaded plugins",
+	step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
+	skippedText: "(This plugin has not been executed because it was added since startup)",
+	noPluginText: "There are no plugins installed",
+	confirmDeleteText: "Are you sure you want to delete these plugins:\n\n%0",
+	removeLabel: "remove systemConfig tag",
+	removePrompt: "Remove systemConfig tag",
+	deleteLabel: "delete",
+	deletePrompt: "Delete these tiddlers forever",
+	listViewTemplate: {
+		columns: [
+			{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
+			{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
+			{name: 'Description', field: 'Description', title: "Description", type: 'String'},
+			{name: 'Version', field: 'Version', title: "Version", type: 'String'},
+			{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'},
+			{name: 'Forced', field: 'forced', title: "Forced", tag: 'systemConfigForce', type: 'TagCheckbox'},
+			{name: 'Disabled', field: 'disabled', title: "Disabled", tag: 'systemConfigDisable', type: 'TagCheckbox'},
+			{name: 'Executed', field: 'executed', title: "Loaded", type: 'Boolean', trueText: "Yes", falseText: "No"},
+			{name: 'Startup Time', field: 'startupTime', title: "Startup Time", type: 'String'},
+			{name: 'Error', field: 'error', title: "Status", type: 'Boolean', trueText: "Error", falseText: "OK"},
+			{name: 'Log', field: 'log', title: "Log", type: 'StringList'}
+			],
+		rowClasses: [
+			{className: 'error', field: 'error'},
+			{className: 'warning', field: 'warning'}
+			]}
+	});
+
+merge(config.macros.toolbar,{
+	moreLabel: "more",
+	morePrompt: "Show additional commands",
+	lessLabel: "less",
+	lessPrompt: "Hide additional commands",
+	separator: "|"
+	});
+
+merge(config.macros.refreshDisplay,{
+	label: "refresh",
+	prompt: "Redraw the entire TiddlyWiki display"
+	});
+
+merge(config.macros.importTiddlers,{
+	readOnlyWarning: "You cannot import into a read-only TiddlyWiki file. Try opening it from a file:// URL",
+	wizardTitle: "Import tiddlers from another file or server",
+	step1Title: "Step 1: Locate the server or TiddlyWiki file",
+	step1Html: "Specify the type of the server: <select name='selTypes'><option value=''>Choose...</option></select><br>Enter the URL or pathname here: <input type='text' size=50 name='txtPath'><br>...or browse for a file: <input type='file' size=50 name='txtBrowse'><br><hr>...or select a pre-defined feed: <select name='selFeeds'><option value=''>Choose...</option></select>",
+	openLabel: "open",
+	openPrompt: "Open the connection to this file or server",
+	openError: "There were problems fetching the tiddlywiki file",
+	statusOpenHost: "Opening the host",
+	statusGetWorkspaceList: "Getting the list of available workspaces",
+	step2Title: "Step 2: Choose the workspace",
+	step2Html: "Enter a workspace name: <input type='text' size=50 name='txtWorkspace'><br>...or select a workspace: <select name='selWorkspace'><option value=''>Choose...</option></select>",
+	cancelLabel: "cancel",
+	cancelPrompt: "Cancel this import",
+	statusOpenWorkspace: "Opening the workspace",
+	statusGetTiddlerList: "Getting the list of available tiddlers",
+	errorGettingTiddlerList: "Error getting list of tiddlers, click Cancel to try again",
+	step3Title: "Step 3: Choose the tiddlers to import",
+	step3Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='true' name='chkSync'>Keep these tiddlers linked to this server so that you can synchronise subsequent changes</input><br><input type='checkbox' name='chkSave'>Save the details of this server in a 'systemServer' tiddler called:</input> <input type='text' size=25 name='txtSaveTiddler'>",
+	importLabel: "import",
+	importPrompt: "Import these tiddlers",
+	confirmOverwriteText: "Are you sure you want to overwrite these tiddlers:\n\n%0",
+	step4Title: "Step 4: Importing %0 tiddler(s)",
+	step4Html: "<input type='hidden' name='markReport'></input>", // DO NOT TRANSLATE
+	doneLabel: "done",
+	donePrompt: "Close this wizard",
+	statusDoingImport: "Importing tiddlers",
+	statusDoneImport: "All tiddlers imported",
+	systemServerNamePattern: "%2 on %1",
+	systemServerNamePatternNoWorkspace: "%1",
+	confirmOverwriteSaveTiddler: "The tiddler '%0' already exists. Click 'OK' to overwrite it with the details of this server, or 'Cancel' to leave it unchanged",
+	serverSaveTemplate: "|''Type:''|%0|\n|''URL:''|%1|\n|''Workspace:''|%2|\n\nThis tiddler was automatically created to record the details of this server",
+	serverSaveModifier: "(System)",
+	listViewTemplate: {
+		columns: [
+			{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
+			{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
+			{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'},
+			{name: 'Tags', field: 'tags', title: "Tags", type: 'Tags'}
+			],
+		rowClasses: [
+			]}
+	});
+
+merge(config.macros.upgrade,{
+	wizardTitle: "Upgrade TiddlyWiki core code",
+	step1Title: "Update or repair this TiddlyWiki to the latest release",
+	step1Html: "You are about to upgrade to the latest release of the TiddlyWiki core code (from <a href='%0' class='externalLink' target='_blank'>%1</a>). Your content will be preserved across the upgrade.<br><br>Note that core upgrades have been known to interfere with older plugins. If you run into problems with the upgraded file, see <a href='http://www.tiddlywiki.org/wiki/CoreUpgrades' class='externalLink' target='_blank'>http://www.tiddlywiki.org/wiki/CoreUpgrades</a>",
+	errorCantUpgrade: "Unable to upgrade this TiddlyWiki. You can only perform upgrades on TiddlyWiki files stored locally",
+	errorNotSaved: "You must save changes before you can perform an upgrade",
+	step2Title: "Confirm the upgrade details",
+	step2Html_downgrade: "You are about to downgrade to TiddlyWiki version %0 from %1.<br><br>Downgrading to an earlier version of the core code is not recommended",
+	step2Html_restore: "This TiddlyWiki appears to be already using the latest version of the core code (%0).<br><br>You can continue to upgrade anyway to ensure that the core code hasn't been corrupted or damaged",
+	step2Html_upgrade: "You are about to upgrade to TiddlyWiki version %0 from %1",
+	upgradeLabel: "upgrade",
+	upgradePrompt: "Prepare for the upgrade process",
+	statusPreparingBackup: "Preparing backup",
+	statusSavingBackup: "Saving backup file",
+	errorSavingBackup: "There was a problem saving the backup file",
+	statusLoadingCore: "Loading core code",
+	errorLoadingCore: "Error loading the core code",
+	errorCoreFormat: "Error with the new core code",
+	statusSavingCore: "Saving the new core code",
+	statusReloadingCore: "Reloading the new core code",
+	startLabel: "start",
+	startPrompt: "Start the upgrade process",
+	cancelLabel: "cancel",
+	cancelPrompt: "Cancel the upgrade process",
+	step3Title: "Upgrade cancelled",
+	step3Html: "You have cancelled the upgrade process"
+	});
+
+merge(config.macros.sync,{
+	listViewTemplate: {
+		columns: [
+			{name: 'Selected', field: 'selected', rowName: 'title', type: 'Selector'},
+			{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
+			{name: 'Server Type', field: 'serverType', title: "Server type", type: 'String'},
+			{name: 'Server Host', field: 'serverHost', title: "Server host", type: 'String'},
+			{name: 'Server Workspace', field: 'serverWorkspace', title: "Server workspace", type: 'String'},
+			{name: 'Status', field: 'status', title: "Synchronisation status", type: 'String'},
+			{name: 'Server URL', field: 'serverUrl', title: "Server URL", text: "View", type: 'Link'}
+			],
+		rowClasses: [
+			],
+		buttons: [
+			{caption: "Sync these tiddlers", name: 'sync'}
+			]},
+	wizardTitle: "Synchronize with external servers and files",
+	step1Title: "Choose the tiddlers you want to synchronize",
+	step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
+	syncLabel: "sync",
+	syncPrompt: "Sync these tiddlers",
+	hasChanged: "Changed while unplugged",
+	hasNotChanged: "Unchanged while unplugged",
+	syncStatusList: {
+		none: {text: "...", display:null, className:'notChanged'},
+		changedServer: {text: "Changed on server", display:null, className:'changedServer'},
+		changedLocally: {text: "Changed while unplugged", display:null, className:'changedLocally'},
+		changedBoth: {text: "Changed while unplugged and on server", display:null, className:'changedBoth'},
+		notFound: {text: "Not found on server", display:null, className:'notFound'},
+		putToServer: {text: "Saved update on server", display:null, className:'putToServer'},
+		gotFromServer: {text: "Retrieved update from server", display:null, className:'gotFromServer'}
+		}
+	});
+
+merge(config.macros.annotations,{
+	});
+
+merge(config.commands.closeTiddler,{
+	text: "close",
+	tooltip: "Close this tiddler"});
+
+merge(config.commands.closeOthers,{
+	text: "close others",
+	tooltip: "Close all other tiddlers"});
+
+merge(config.commands.editTiddler,{
+	text: "edit",
+	tooltip: "Edit this tiddler",
+	readOnlyText: "view",
+	readOnlyTooltip: "View the source of this tiddler"});
+
+merge(config.commands.saveTiddler,{
+	text: "done",
+	tooltip: "Save changes to this tiddler"});
+
+merge(config.commands.cancelTiddler,{
+	text: "cancel",
+	tooltip: "Undo changes to this tiddler",
+	warning: "Are you sure you want to abandon your changes to '%0'?",
+	readOnlyText: "done",
+	readOnlyTooltip: "View this tiddler normally"});
+
+merge(config.commands.deleteTiddler,{
+	text: "delete",
+	tooltip: "Delete this tiddler",
+	warning: "Are you sure you want to delete '%0'?"});
+
+merge(config.commands.permalink,{
+	text: "permalink",
+	tooltip: "Permalink for this tiddler"});
+
+merge(config.commands.references,{
+	text: "references",
+	tooltip: "Show tiddlers that link to this one",
+	popupNone: "No references"});
+
+merge(config.commands.jump,{
+	text: "jump",
+	tooltip: "Jump to another open tiddler"});
+
+merge(config.commands.syncing,{
+	text: "syncing",
+	tooltip: "Control synchronisation of this tiddler with a server or external file",
+	currentlySyncing: "<div>Currently syncing via <span class='popupHighlight'>'%0'</span> to:</"+"div><div>host: <span class='popupHighlight'>%1</span></"+"div><div>workspace: <span class='popupHighlight'>%2</span></"+"div>", // Note escaping of closing <div> tag
+	notCurrentlySyncing: "Not currently syncing",
+	captionUnSync: "Stop synchronising this tiddler",
+	chooseServer: "Synchronise this tiddler with another server:",
+	currServerMarker: "\u25cf ",
+	notCurrServerMarker: "  "});
+
+merge(config.commands.fields,{
+	text: "fields",
+	tooltip: "Show the extended fields of this tiddler",
+	emptyText: "There are no extended fields for this tiddler",
+	listViewTemplate: {
+		columns: [
+			{name: 'Field', field: 'field', title: "Field", type: 'String'},
+			{name: 'Value', field: 'value', title: "Value", type: 'String'}
+			],
+		rowClasses: [
+			],
+		buttons: [
+			]}});
+
+merge(config.shadowTiddlers,{
+	DefaultTiddlers: "[[GettingStarted]]",
+	MainMenu: "[[GettingStarted]]",
+	SiteTitle: "My TiddlyWiki",
+	SiteSubtitle: "a reusable non-linear personal web notebook",
+	SiteUrl: "",
+	SideBarOptions: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options \u00bb" "Change TiddlyWiki advanced options">>',
+	SideBarTabs: '<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>',
+	TabMore: '<<tabs txtMoreTab "Missing" "Missing tiddlers" TabMoreMissing "Orphans" "Orphaned tiddlers" TabMoreOrphans "Shadowed" "Shadowed tiddlers" TabMoreShadowed>>'
+	});
+
+merge(config.annotations,{
+	AdvancedOptions: "This shadow tiddler provides access to several advanced options",
+	ColorPalette: "These values in this shadow tiddler determine the colour scheme of the ~TiddlyWiki user interface",
+	DefaultTiddlers: "The tiddlers listed in this shadow tiddler will be automatically displayed when ~TiddlyWiki starts up",
+	EditTemplate: "The HTML template in this shadow tiddler determines how tiddlers look while they are being edited",
+	GettingStarted: "This shadow tiddler provides basic usage instructions",
+	ImportTiddlers: "This shadow tiddler provides access to importing tiddlers",
+	MainMenu: "This shadow tiddler is used as the contents of the main menu in the left-hand column of the screen",
+	MarkupPreHead: "This tiddler is inserted at the top of the <head> section of the TiddlyWiki HTML file",
+	MarkupPostHead: "This tiddler is inserted at the bottom of the <head> section of the TiddlyWiki HTML file",
+	MarkupPreBody: "This tiddler is inserted at the top of the <body> section of the TiddlyWiki HTML file",
+	MarkupPostBody: "This tiddler is inserted at the end of the <body> section of the TiddlyWiki HTML file immediately after the script block",
+	OptionsPanel: "This shadow tiddler is used as the contents of the options panel slider in the right-hand sidebar",
+	PageTemplate: "The HTML template in this shadow tiddler determines the overall ~TiddlyWiki layout",
+	PluginManager: "This shadow tiddler provides access to the plugin manager",
+	SideBarOptions: "This shadow tiddler is used as the contents of the option panel in the right-hand sidebar",
+	SideBarTabs: "This shadow tiddler is used as the contents of the tabs panel in the right-hand sidebar",
+	SiteSubtitle: "This shadow tiddler is used as the second part of the page title",
+	SiteTitle: "This shadow tiddler is used as the first part of the page title",
+	SiteUrl: "This shadow tiddler should be set to the full target URL for publication",
+	StyleSheetColors: "This shadow tiddler contains CSS definitions related to the color of page elements. ''DO NOT EDIT THIS TIDDLER'', instead make your changes in the StyleSheet shadow tiddler",
+	StyleSheet: "This tiddler can contain custom CSS definitions",
+	StyleSheetLayout: "This shadow tiddler contains CSS definitions related to the layout of page elements. ''DO NOT EDIT THIS TIDDLER'', instead make your changes in the StyleSheet shadow tiddler",
+	StyleSheetLocale: "This shadow tiddler contains CSS definitions related to the translation locale",
+	StyleSheetPrint: "This shadow tiddler contains CSS definitions for printing",
+	TabAll: "This shadow tiddler contains the contents of the 'All' tab in the right-hand sidebar",
+	TabMore: "This shadow tiddler contains the contents of the 'More' tab in the right-hand sidebar",
+	TabMoreMissing: "This shadow tiddler contains the contents of the 'Missing' tab in the right-hand sidebar",
+	TabMoreOrphans: "This shadow tiddler contains the contents of the 'Orphans' tab in the right-hand sidebar",
+	TabMoreShadowed: "This shadow tiddler contains the contents of the 'Shadowed' tab in the right-hand sidebar",
+	TabTags: "This shadow tiddler contains the contents of the 'Tags' tab in the right-hand sidebar",
+	TabTimeline: "This shadow tiddler contains the contents of the 'Timeline' tab in the right-hand sidebar",
+	ToolbarCommands: "This shadow tiddler determines which commands are shown in tiddler toolbars",
+	ViewTemplate: "The HTML template in this shadow tiddler determines how tiddlers look"
+	});
+
+//--
+//-- Main
+//--
+
+var params = null; // Command line parameters
+var store = null; // TiddlyWiki storage
+var story = null; // Main story
+var formatter = null; // Default formatters for the wikifier
+var anim = typeof Animator == "function" ? new Animator() : null; // Animation engine
+var readOnly = false; // Whether we're in readonly mode
+var highlightHack = null; // Embarrassing hack department...
+var hadConfirmExit = false; // Don't warn more than once
+var safeMode = false; // Disable all plugins and cookies
+var showBackstage; // Whether to include the backstage area
+var installedPlugins = []; // Information filled in when plugins are executed
+var startingUp = false; // Whether we're in the process of starting up
+var pluginInfo,tiddler; // Used to pass information to plugins in loadPlugins()
+
+// Whether to use the JavaSaver applet
+var useJavaSaver = (config.browser.isSafari || config.browser.isOpera) && (document.location.toString().substr(0,4) != "http");
+
+// Starting up
+function main()
+{
+	var t10,t9,t8,t7,t6,t5,t4,t3,t2,t1,t0 = new Date();
+	startingUp = true;
+	jQuery.noConflict();
+	window.onbeforeunload = function(e) {if(window.confirmExit) return confirmExit();};
+	params = getParameters();
+	if(params)
+		params = params.parseParams("open",null,false);
+	store = new TiddlyWiki();
+	invokeParamifier(params,"oninit");
+	story = new Story("tiddlerDisplay","tiddler");
+	addEvent(document,"click",Popup.onDocumentClick);
+	saveTest();
+	loadOptionsCookie();
+	for(var s=0; s<config.notifyTiddlers.length; s++)
+		store.addNotification(config.notifyTiddlers[s].name,config.notifyTiddlers[s].notify);
+	t1 = new Date();
+	loadShadowTiddlers();
+	jQuery().trigger("loadShadows");
+	t2 = new Date();
+	store.loadFromDiv("storeArea","store",true);
+	jQuery().trigger("loadTiddlers");
+	t3 = new Date();
+	invokeParamifier(params,"onload");
+	t4 = new Date();
+	readOnly = (window.location.protocol == "file:") ? false : config.options.chkHttpReadOnly;
+	var pluginProblem = loadPlugins();
+	jQuery().trigger("loadPlugins");
+	t5 = new Date();
+	formatter = new Formatter(config.formatters);
+	invokeParamifier(params,"onconfig");
+	story.switchTheme(config.options.txtTheme);
+	showBackstage = !readOnly;
+	t6 = new Date();
+	for(var m in config.macros) {
+		if(config.macros[m].init)
+			config.macros[m].init();
+	}
+	t7 = new Date();
+	store.notifyAll();
+	t8 = new Date();
+	restart();
+	refreshDisplay();
+	t9 = new Date();
+	if(pluginProblem) {
+		story.displayTiddler(null,"PluginManager");
+		displayMessage(config.messages.customConfigError);
+	}
+	if(showBackstage)
+		backstage.init();
+	t10 = new Date();
+	if(config.options.chkDisplayInstrumentation) {
+		displayMessage("LoadShadows " + (t2-t1) + " ms");
+		displayMessage("LoadFromDiv " + (t3-t2) + " ms");
+		displayMessage("LoadPlugins " + (t5-t4) + " ms");
+		displayMessage("Macro init " + (t7-t6) + " ms");
+		displayMessage("Notify " + (t8-t7) + " ms");
+		displayMessage("Restart " + (t9-t8) + " ms");
+		displayMessage("Total: " + (t10-t0) + " ms");
+	}
+	startingUp = false;
+	jQuery().trigger("startup");
+}
+
+// Called on unload. All functions called conditionally since they themselves may have been unloaded.
+function unload()
+{
+	if(window.checkUnsavedChanges)
+		checkUnsavedChanges();
+	if(window.scrubNodes)
+		scrubNodes(document.body);
+}
+
+// Restarting
+function restart()
+{
+	invokeParamifier(params,"onstart");
+	if(story.isEmpty()) {
+		story.displayDefaultTiddlers();
+	}
+	window.scrollTo(0,0);
+}
+
+function saveTest()
+{
+	var s = document.getElementById("saveTest");
+	if(s.hasChildNodes())
+		alert(config.messages.savedSnapshotError);
+	s.appendChild(document.createTextNode("savetest"));
+}
+
+function loadShadowTiddlers()
+{
+	var shadows = new TiddlyWiki();
+	shadows.loadFromDiv("shadowArea","shadows",true);
+	shadows.forEachTiddler(function(title,tiddler){config.shadowTiddlers[title] = tiddler.text;});
+	delete shadows;
+}
+
+function loadPlugins()
+{
+	if(safeMode)
+		return false;
+	var tiddlers = store.getTaggedTiddlers("systemConfig");
+	var toLoad = [];
+	var nLoaded = 0;
+	var map = {};
+	var nPlugins = tiddlers.length;
+	installedPlugins = [];
+	for(var i=0; i<nPlugins; i++) {
+		var p = getPluginInfo(tiddlers[i]);
+		installedPlugins[i] = p;
+		var n = p.Name;
+		if(n)
+			map[n] = p;
+		n = p.Source;
+		if(n)
+			map[n] = p;
+	}
+	var visit = function(p) {
+		if(!p || p.done)
+			return;
+		p.done = 1;
+		var reqs = p.Requires;
+		if(reqs) {
+			reqs = reqs.readBracketedList();
+			for(var i=0; i<reqs.length; i++)
+				visit(map[reqs[i]]);
+		}
+		toLoad.push(p);
+	};
+	for(i=0; i<nPlugins; i++)
+		visit(installedPlugins[i]);
+	for(i=0; i<toLoad.length; i++) {
+		p = toLoad[i];
+		pluginInfo = p;
+		tiddler = p.tiddler;
+		if(isPluginExecutable(p)) {
+			if(isPluginEnabled(p)) {
+				p.executed = true;
+				var startTime = new Date();
+				try {
+					if(tiddler.text)
+						window.eval(tiddler.text);
+					nLoaded++;
+				} catch(ex) {
+					p.log.push(config.messages.pluginError.format([exceptionText(ex)]));
+					p.error = true;
+				}
+				pluginInfo.startupTime = String((new Date()) - startTime) + "ms";
+			} else {
+				nPlugins--;
+			}
+		} else {
+			p.warning = true;
+		}
+	}
+	return nLoaded != nPlugins;
+}
+
+function getPluginInfo(tiddler)
+{
+	var p = store.getTiddlerSlices(tiddler.title,["Name","Description","Version","Requires","CoreVersion","Date","Source","Author","License","Browsers"]);
+	p.tiddler = tiddler;
+	p.title = tiddler.title;
+	p.log = [];
+	return p;
+}
+
+// Check that a particular plugin is valid for execution
+function isPluginExecutable(plugin)
+{
+	if(plugin.tiddler.isTagged("systemConfigForce")) {
+		plugin.log.push(config.messages.pluginForced);
+		return true;
+	}
+	if(plugin["CoreVersion"]) {
+		var coreVersion = plugin["CoreVersion"].split(".");
+		var w = parseInt(coreVersion[0],10) - version.major;
+		if(w == 0 && coreVersion[1])
+			w = parseInt(coreVersion[1],10) - version.minor;
+		if(w == 0 && coreVersion[2])
+			w = parseInt(coreVersion[2],10) - version.revision;
+		if(w > 0) {
+			plugin.log.push(config.messages.pluginVersionError);
+			return false;
+		}
+	}
+	return true;
+}
+
+function isPluginEnabled(plugin)
+{
+	if(plugin.tiddler.isTagged("systemConfigDisable")) {
+		plugin.log.push(config.messages.pluginDisabled);
+		return false;
+	}
+	return true;
+}
+
+function invokeMacro(place,macro,params,wikifier,tiddler)
+{
+	try {
+		var m = config.macros[macro];
+		if(m && m.handler) {
+			var tiddlerElem = story.findContainingTiddler(place);
+			window.tiddler = tiddlerElem ? store.getTiddler(tiddlerElem.getAttribute("tiddler")) : null;
+			window.place = place;
+			m.handler(place,macro,m.noPreParse?null:params.readMacroParams(),wikifier,params,tiddler);
+		} else {
+			createTiddlyError(place,config.messages.macroError.format([macro]),config.messages.macroErrorDetails.format([macro,config.messages.missingMacro]));
+		}
+	} catch(ex) {
+		createTiddlyError(place,config.messages.macroError.format([macro]),config.messages.macroErrorDetails.format([macro,ex.toString()]));
+	}
+}
+
+//--
+//-- Paramifiers
+//--
+
+function getParameters()
+{
+	var p = null;
+	if(window.location.hash) {
+		p = decodeURIComponent(window.location.hash.substr(1));
+		if(config.browser.firefoxDate != null && config.browser.firefoxDate[1] < "20051111")
+			p = convertUTF8ToUnicode(p);
+	}
+	return p;
+}
+
+function invokeParamifier(params,handler)
+{
+	if(!params || params.length == undefined || params.length <= 1)
+		return;
+	for(var i=1; i<params.length; i++) {
+		var p = config.paramifiers[params[i].name];
+		if(p && p[handler] instanceof Function)
+			p[handler](params[i].value);
+		else {
+			var h = config.optionHandlers[params[i].name.substr(0,3)];
+			if(h && h.set instanceof Function)
+				h.set(params[i].name,params[i].value);
+		}
+	}
+}
+
+config.paramifiers = {};
+
+config.paramifiers.start = {
+	oninit: function(v) {
+		safeMode = v.toLowerCase() == "safe";
+	}
+};
+
+config.paramifiers.open = {
+	onstart: function(v) {
+		if(!readOnly || store.tiddlerExists(v) || store.isShadowTiddler(v))
+			story.displayTiddler("bottom",v,null,false,null);
+	}
+};
+
+config.paramifiers.story = {
+	onstart: function(v) {
+		var list = store.getTiddlerText(v,"").parseParams("open",null,false);
+		invokeParamifier(list,"onstart");
+	}
+};
+
+config.paramifiers.search = {
+	onstart: function(v) {
+		story.search(v,false,false);
+	}
+};
+
+config.paramifiers.searchRegExp = {
+	onstart: function(v) {
+		story.prototype.search(v,false,true);
+	}
+};
+
+config.paramifiers.tag = {
+	onstart: function(v) {
+		story.displayTiddlers(null,store.filterTiddlers("[tag["+v+"]]"),null,false,null);
+	}
+};
+
+config.paramifiers.newTiddler = {
+	onstart: function(v) {
+		if(!readOnly) {
+			story.displayTiddler(null,v,DEFAULT_EDIT_TEMPLATE);
+			story.focusTiddler(v,"text");
+		}
+	}
+};
+
+config.paramifiers.newJournal = {
+	onstart: function(v) {
+		if(!readOnly) {
+			var now = new Date();
+			var title = now.formatString(v.trim());
+			story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE);
+			story.focusTiddler(title,"text");
+		}
+	}
+};
+
+config.paramifiers.readOnly = {
+	onconfig: function(v) {
+		var p = v.toLowerCase();
+		readOnly = p == "yes" ? true : (p == "no" ? false : readOnly);
+	}
+};
+
+config.paramifiers.theme = {
+	onconfig: function(v) {
+		story.switchTheme(v);
+	}
+};
+
+config.paramifiers.upgrade = {
+	onstart: function(v) {
+		upgradeFrom(v);
+	}
+};
+
+config.paramifiers.recent= {
+	onstart: function(v) {
+		var titles=[];
+		var tiddlers=store.getTiddlers("modified","excludeLists").reverse();
+		for(var i=0; i<v && i<tiddlers.length; i++)
+			titles.push(tiddlers[i].title);
+		story.displayTiddlers(null,titles);
+	}
+};
+
+config.paramifiers.filter = {
+	onstart: function(v) {
+		story.displayTiddlers(null,store.filterTiddlers(v),null,false);
+	}
+};
+
+//--
+//-- Formatter helpers
+//--
+
+function Formatter(formatters)
+{
+	this.formatters = [];
+	var pattern = [];
+	for(var n=0; n<formatters.length; n++) {
+		pattern.push("(" + formatters[n].match + ")");
+		this.formatters.push(formatters[n]);
+	}
+	this.formatterRegExp = new RegExp(pattern.join("|"),"mg");
+}
+
+config.formatterHelpers = {
+
+	createElementAndWikify: function(w)
+	{
+		w.subWikifyTerm(createTiddlyElement(w.output,this.element),this.termRegExp);
+	},
+
+	inlineCssHelper: function(w)
+	{
+		var styles = [];
+		config.textPrimitives.cssLookaheadRegExp.lastIndex = w.nextMatch;
+		var lookaheadMatch = config.textPrimitives.cssLookaheadRegExp.exec(w.source);
+		while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
+			var s,v;
+			if(lookaheadMatch[1]) {
+				s = lookaheadMatch[1].unDash();
+				v = lookaheadMatch[2];
+			} else {
+				s = lookaheadMatch[3].unDash();
+				v = lookaheadMatch[4];
+			}
+			if(s=="bgcolor")
+				s = "backgroundColor";
+			styles.push({style: s, value: v});
+			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
+			config.textPrimitives.cssLookaheadRegExp.lastIndex = w.nextMatch;
+			lookaheadMatch = config.textPrimitives.cssLookaheadRegExp.exec(w.source);
+		}
+		return styles;
+	},
+
+	applyCssHelper: function(e,styles)
+	{
+		for(var t=0; t< styles.length; t++) {
+			try {
+				e.style[styles[t].style] = styles[t].value;
+			} catch (ex) {
+			}
+		}
+	},
+
+	enclosedTextHelper: function(w)
+	{
+		this.lookaheadRegExp.lastIndex = w.matchStart;
+		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
+			var text = lookaheadMatch[1];
+			if(config.browser.isIE)
+				text = text.replace(/\n/g,"\r");
+			createTiddlyElement(w.output,this.element,null,null,text);
+			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
+		}
+	},
+
+	isExternalLink: function(link)
+	{
+		if(store.tiddlerExists(link) || store.isShadowTiddler(link)) {
+			return false;
+		}
+		var urlRegExp = new RegExp(config.textPrimitives.urlPattern,"mg");
+		if(urlRegExp.exec(link)) {
+			return true;
+		}
+		if(link.indexOf(".")!=-1 || link.indexOf("\\")!=-1 || link.indexOf("/")!=-1 || link.indexOf("#")!=-1) {
+			return true;
+		}
+		return false;
+	}
+
+};
+
+//--
+//-- Standard formatters
+//--
+
+config.formatters = [
+{
+	name: "table",
+	match: "^\\|(?:[^\\n]*)\\|(?:[fhck]?)$",
+	lookaheadRegExp: /^\|([^\n]*)\|([fhck]?)$/mg,
+	rowTermRegExp: /(\|(?:[fhck]?)$\n?)/mg,
+	cellRegExp: /(?:\|([^\n\|]*)\|)|(\|[fhck]?$\n?)/mg,
+	cellTermRegExp: /((?:\x20*)\|)/mg,
+	rowTypes: {"c":"caption", "h":"thead", "":"tbody", "f":"tfoot"},
+	handler: function(w)
+	{
+		var table = createTiddlyElement(w.output,"table",null,"twtable");
+		var prevColumns = [];
+		var currRowType = null;
+		var rowContainer;
+		var rowCount = 0;
+		w.nextMatch = w.matchStart;
+		this.lookaheadRegExp.lastIndex = w.nextMatch;
+		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+		while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
+			var nextRowType = lookaheadMatch[2];
+			if(nextRowType == "k") {
+				table.className = lookaheadMatch[1];
+				w.nextMatch += lookaheadMatch[0].length+1;
+			} else {
+				if(nextRowType != currRowType) {
+					rowContainer = createTiddlyElement(table,this.rowTypes[nextRowType]);
+					currRowType = nextRowType;
+				}
+				if(currRowType == "c") {
+					// Caption
+					w.nextMatch++;
+					if(rowContainer != table.firstChild)
+						table.insertBefore(rowContainer,table.firstChild);
+					rowContainer.setAttribute("align",rowCount == 0?"top":"bottom");
+					w.subWikifyTerm(rowContainer,this.rowTermRegExp);
+				} else {
+					var theRow = createTiddlyElement(rowContainer,"tr",null,(rowCount&1)?"oddRow":"evenRow");
+					theRow.onmouseover = function() {addClass(this,"hoverRow");};
+					theRow.onmouseout = function() {removeClass(this,"hoverRow");};
+					this.rowHandler(w,theRow,prevColumns);
+					rowCount++;
+				}
+			}
+			this.lookaheadRegExp.lastIndex = w.nextMatch;
+			lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+		}
+	},
+	rowHandler: function(w,e,prevColumns)
+	{
+		var col = 0;
+		var colSpanCount = 1;
+		var prevCell = null;
+		this.cellRegExp.lastIndex = w.nextMatch;
+		var cellMatch = this.cellRegExp.exec(w.source);
+		while(cellMatch && cellMatch.index == w.nextMatch) {
+			if(cellMatch[1] == "~") {
+				// Rowspan
+				var last = prevColumns[col];
+				if(last) {
+					last.rowSpanCount++;
+					last.element.setAttribute("rowspan",last.rowSpanCount);
+					last.element.setAttribute("rowSpan",last.rowSpanCount); // Needed for IE
+					last.element.valign = "center";
+					if(colSpanCount > 1) {
+						last.element.setAttribute("colspan",colSpanCount);
+						last.element.setAttribute("colSpan",colSpanCount); // Needed for IE
+						colSpanCount = 1;
+					}
+				}
+				w.nextMatch = this.cellRegExp.lastIndex-1;
+			} else if(cellMatch[1] == ">") {
+				// Colspan
+				colSpanCount++;
+				w.nextMatch = this.cellRegExp.lastIndex-1;
+			} else if(cellMatch[2]) {
+				// End of row
+				if(prevCell && colSpanCount > 1) {
+					prevCell.setAttribute("colspan",colSpanCount);
+					prevCell.setAttribute("colSpan",colSpanCount); // Needed for IE
+				}
+				w.nextMatch = this.cellRegExp.lastIndex;
+				break;
+			} else {
+				// Cell
+				w.nextMatch++;
+				var styles = config.formatterHelpers.inlineCssHelper(w);
+				var spaceLeft = false;
+				var chr = w.source.substr(w.nextMatch,1);
+				while(chr == " ") {
+					spaceLeft = true;
+					w.nextMatch++;
+					chr = w.source.substr(w.nextMatch,1);
+				}
+				var cell;
+				if(chr == "!") {
+					cell = createTiddlyElement(e,"th");
+					w.nextMatch++;
+				} else {
+					cell = createTiddlyElement(e,"td");
+				}
+				prevCell = cell;
+				prevColumns[col] = {rowSpanCount:1,element:cell};
+				if(colSpanCount > 1) {
+					cell.setAttribute("colspan",colSpanCount);
+					cell.setAttribute("colSpan",colSpanCount); // Needed for IE
+					colSpanCount = 1;
+				}
+				config.formatterHelpers.applyCssHelper(cell,styles);
+				w.subWikifyTerm(cell,this.cellTermRegExp);
+				if(w.matchText.substr(w.matchText.length-2,1) == " ") // spaceRight
+					cell.align = spaceLeft ? "center" : "left";
+				else if(spaceLeft)
+					cell.align = "right";
+				w.nextMatch--;
+			}
+			col++;
+			this.cellRegExp.lastIndex = w.nextMatch;
+			cellMatch = this.cellRegExp.exec(w.source);
+		}
+	}
+},
+
+{
+	name: "heading",
+	match: "^!{1,6}",
+	termRegExp: /(\n)/mg,
+	handler: function(w)
+	{
+		w.subWikifyTerm(createTiddlyElement(w.output,"h" + w.matchLength),this.termRegExp);
+	}
+},
+
+{
+	name: "list",
+	match: "^(?:[\\*#;:]+)",
+	lookaheadRegExp: /^(?:(?:(\*)|(#)|(;)|(:))+)/mg,
+	termRegExp: /(\n)/mg,
+	handler: function(w)
+	{
+		var stack = [w.output];
+		var currLevel = 0, currType = null;
+		var listLevel, listType, itemType, baseType;
+		w.nextMatch = w.matchStart;
+		this.lookaheadRegExp.lastIndex = w.nextMatch;
+		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+		while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
+			if(lookaheadMatch[1]) {
+				listType = "ul";
+				itemType = "li";
+			} else if(lookaheadMatch[2]) {
+				listType = "ol";
+				itemType = "li";
+			} else if(lookaheadMatch[3]) {
+				listType = "dl";
+				itemType = "dt";
+			} else if(lookaheadMatch[4]) {
+				listType = "dl";
+				itemType = "dd";
+			}
+			if(!baseType)
+				baseType = listType;
+			listLevel = lookaheadMatch[0].length;
+			w.nextMatch += lookaheadMatch[0].length;
+			var t;
+			if(listLevel > currLevel) {
+				for(t=currLevel; t<listLevel; t++) {
+					var target = (currLevel == 0) ? stack[stack.length-1] : stack[stack.length-1].lastChild;
+					stack.push(createTiddlyElement(target,listType));
+				}
+			} else if(listType!=baseType && listLevel==1) {
+				w.nextMatch -= lookaheadMatch[0].length;
+				return;
+			} else if(listLevel < currLevel) {
+				for(t=currLevel; t>listLevel; t--)
+					stack.pop();
+			} else if(listLevel == currLevel && listType != currType) {
+				stack.pop();
+				stack.push(createTiddlyElement(stack[stack.length-1].lastChild,listType));
+			}
+			currLevel = listLevel;
+			currType = listType;
+			var e = createTiddlyElement(stack[stack.length-1],itemType);
+			w.subWikifyTerm(e,this.termRegExp);
+			this.lookaheadRegExp.lastIndex = w.nextMatch;
+			lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+		}
+	}
+},
+
+{
+	name: "quoteByBlock",
+	match: "^<<<\\n",
+	termRegExp: /(^<<<(\n|$))/mg,
+	element: "blockquote",
+	handler: config.formatterHelpers.createElementAndWikify
+},
+
+{
+	name: "quoteByLine",
+	match: "^>+",
+	lookaheadRegExp: /^>+/mg,
+	termRegExp: /(\n)/mg,
+	element: "blockquote",
+	handler: function(w)
+	{
+		var stack = [w.output];
+		var currLevel = 0;
+		var newLevel = w.matchLength;
+		var t;
+		do {
+			if(newLevel > currLevel) {
+				for(t=currLevel; t<newLevel; t++)
+					stack.push(createTiddlyElement(stack[stack.length-1],this.element));
+			} else if(newLevel < currLevel) {
+				for(t=currLevel; t>newLevel; t--)
+					stack.pop();
+			}
+			currLevel = newLevel;
+			w.subWikifyTerm(stack[stack.length-1],this.termRegExp);
+			createTiddlyElement(stack[stack.length-1],"br");
+			this.lookaheadRegExp.lastIndex = w.nextMatch;
+			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+			var matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
+			if(matched) {
+				newLevel = lookaheadMatch[0].length;
+				w.nextMatch += lookaheadMatch[0].length;
+			}
+		} while(matched);
+	}
+},
+
+{
+	name: "rule",
+	match: "^----+$\\n?|<hr ?/?>\\n?",
+	handler: function(w)
+	{
+		createTiddlyElement(w.output,"hr");
+	}
+},
+
+{
+	name: "monospacedByLine",
+	match: "^(?:/\\*\\{\\{\\{\\*/|\\{\\{\\{|//\\{\\{\\{|<!--\\{\\{\\{-->)\\n",
+	element: "pre",
+	handler: function(w)
+	{
+		switch(w.matchText) {
+		case "/*{{{*/\n": // CSS
+			this.lookaheadRegExp = /\/\*\{\{\{\*\/\n*((?:^[^\n]*\n)+?)(\n*^\f*\/\*\}\}\}\*\/$\n?)/mg;
+			break;
+		case "{{{\n": // monospaced block
+			this.lookaheadRegExp = /^\{\{\{\n((?:^[^\n]*\n)+?)(^\f*\}\}\}$\n?)/mg;
+			break;
+		case "//{{{\n": // plugin
+			this.lookaheadRegExp = /^\/\/\{\{\{\n\n*((?:^[^\n]*\n)+?)(\n*^\f*\/\/\}\}\}$\n?)/mg;
+			break;
+		case "<!--{{{-->\n": //template
+			this.lookaheadRegExp = /<!--\{\{\{-->\n*((?:^[^\n]*\n)+?)(\n*^\f*<!--\}\}\}-->$\n?)/mg;
+			break;
+		default:
+			break;
+		}
+		config.formatterHelpers.enclosedTextHelper.call(this,w);
+	}
+},
+
+{
+	name: "wikifyComment",
+	match: "^(?:/\\*\\*\\*|<!---)\\n",
+	handler: function(w)
+	{
+		var termRegExp = (w.matchText == "/***\n") ? (/(^\*\*\*\/\n)/mg) : (/(^--->\n)/mg);
+		w.subWikifyTerm(w.output,termRegExp);
+	}
+},
+
+{
+	name: "macro",
+	match: "<<",
+	lookaheadRegExp: /<<([^>\s]+)(?:\s*)((?:[^>]|(?:>(?!>)))*)>>/mg,
+	handler: function(w)
+	{
+		this.lookaheadRegExp.lastIndex = w.matchStart;
+		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+		if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1]) {
+			w.nextMatch = this.lookaheadRegExp.lastIndex;
+			invokeMacro(w.output,lookaheadMatch[1],lookaheadMatch[2],w,w.tiddler);
+		}
+	}
+},
+
+{
+	name: "prettyLink",
+	match: "\\[\\[",
+	lookaheadRegExp: /\[\[(.*?)(?:\|(~)?(.*?))?\]\]/mg,
+	handler: function(w)
+	{
+		this.lookaheadRegExp.lastIndex = w.matchStart;
+		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
+			var e;
+			var text = lookaheadMatch[1];
+			if(lookaheadMatch[3]) {
+				// Pretty bracketted link
+				var link = lookaheadMatch[3];
+				e = (!lookaheadMatch[2] && config.formatterHelpers.isExternalLink(link)) ?
+						createExternalLink(w.output,link) : createTiddlyLink(w.output,decodeURIComponent(link),false,null,w.isStatic,w.tiddler);
+			} else {
+				// Simple bracketted link
+				e = createTiddlyLink(w.output,decodeURIComponent(text),false,null,w.isStatic,w.tiddler);
+			}
+			createTiddlyText(e,text);
+			w.nextMatch = this.lookaheadRegExp.lastIndex;
+		}
+	}
+},
+
+{
+	name: "wikiLink",
+	match: config.textPrimitives.unWikiLink+"?"+config.textPrimitives.wikiLink,
+	handler: function(w)
+	{
+		if(w.matchText.substr(0,1) == config.textPrimitives.unWikiLink) {
+			w.outputText(w.output,w.matchStart+1,w.nextMatch);
+			return;
+		}
+		if(w.matchStart > 0) {
+			var preRegExp = new RegExp(config.textPrimitives.anyLetterStrict,"mg");
+			preRegExp.lastIndex = w.matchStart-1;
+			var preMatch = preRegExp.exec(w.source);
+			if(preMatch.index == w.matchStart-1) {
+				w.outputText(w.output,w.matchStart,w.nextMatch);
+				return;
+			}
+		}
+		if(w.autoLinkWikiWords || store.isShadowTiddler(w.matchText)) {
+			var link = createTiddlyLink(w.output,w.matchText,false,null,w.isStatic,w.tiddler);
+			w.outputText(link,w.matchStart,w.nextMatch);
+		} else {
+			w.outputText(w.output,w.matchStart,w.nextMatch);
+		}
+	}
+},
+
+{
+	name: "urlLink",
+	match: config.textPrimitives.urlPattern,
+	handler: function(w)
+	{
+		w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
+	}
+},
+
+{
+	name: "image",
+	match: "\\[[<>]?[Ii][Mm][Gg]\\[",
+	lookaheadRegExp: /\[([<]?)(>?)[Ii][Mm][Gg]\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg,
+	handler: function(w)
+	{
+		this.lookaheadRegExp.lastIndex = w.matchStart;
+		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
+			var e = w.output;
+			if(lookaheadMatch[5]) {
+				var link = lookaheadMatch[5];
+				e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler);
+				addClass(e,"imageLink");
+			}
+			var img = createTiddlyElement(e,"img");
+			if(lookaheadMatch[1])
+				img.align = "left";
+			else if(lookaheadMatch[2])
+				img.align = "right";
+			if(lookaheadMatch[3]) {
+				img.title = lookaheadMatch[3];
+				img.setAttribute("alt",lookaheadMatch[3]);
+			}
+			img.src = lookaheadMatch[4];
+			w.nextMatch = this.lookaheadRegExp.lastIndex;
+		}
+	}
+},
+
+{
+	name: "html",
+	match: "<[Hh][Tt][Mm][Ll]>",
+	lookaheadRegExp: /<[Hh][Tt][Mm][Ll]>((?:.|\n)*?)<\/[Hh][Tt][Mm][Ll]>/mg,
+	handler: function(w)
+	{
+		this.lookaheadRegExp.lastIndex = w.matchStart;
+		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
+			createTiddlyElement(w.output,"span").innerHTML = lookaheadMatch[1];
+			w.nextMatch = this.lookaheadRegExp.lastIndex;
+		}
+	}
+},
+
+{
+	name: "commentByBlock",
+	match: "/%",
+	lookaheadRegExp: /\/%((?:.|\n)*?)%\//mg,
+	handler: function(w)
+	{
+		this.lookaheadRegExp.lastIndex = w.matchStart;
+		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+		if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
+			w.nextMatch = this.lookaheadRegExp.lastIndex;
+	}
+},
+
+{
+	name: "characterFormat",
+	match: "''|//|__|\\^\\^|~~|--(?!\\s|$)|\\{\\{\\{",
+	handler: function(w)
+	{
+		switch(w.matchText) {
+		case "''":
+			w.subWikifyTerm(w.output.appendChild(document.createElement("strong")),/('')/mg);
+			break;
+		case "//":
+			w.subWikifyTerm(createTiddlyElement(w.output,"em"),/(\/\/)/mg);
+			break;
+		case "__":
+			w.subWikifyTerm(createTiddlyElement(w.output,"u"),/(__)/mg);
+			break;
+		case "^^":
+			w.subWikifyTerm(createTiddlyElement(w.output,"sup"),/(\^\^)/mg);
+			break;
+		case "~~":
+			w.subWikifyTerm(createTiddlyElement(w.output,"sub"),/(~~)/mg);
+			break;
+		case "--":
+			w.subWikifyTerm(createTiddlyElement(w.output,"strike"),/(--)/mg);
+			break;
+		case "{{{":
+			var lookaheadRegExp = /\{\{\{((?:.|\n)*?)\}\}\}/mg;
+			lookaheadRegExp.lastIndex = w.matchStart;
+			var lookaheadMatch = lookaheadRegExp.exec(w.source);
+			if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
+				createTiddlyElement(w.output,"code",null,null,lookaheadMatch[1]);
+				w.nextMatch = lookaheadRegExp.lastIndex;
+			}
+			break;
+		}
+	}
+},
+
+{
+	name: "customFormat",
+	match: "@@|\\{\\{",
+	handler: function(w)
+	{
+		switch(w.matchText) {
+		case "@@":
+			var e = createTiddlyElement(w.output,"span");
+			var styles = config.formatterHelpers.inlineCssHelper(w);
+			if(styles.length == 0)
+				e.className = "marked";
+			else
+				config.formatterHelpers.applyCssHelper(e,styles);
+			w.subWikifyTerm(e,/(@@)/mg);
+			break;
+		case "{{":
+			var lookaheadRegExp = /\{\{[\s]*([\w]+[\s\w]*)[\s]*\{(\n?)/mg;
+			lookaheadRegExp.lastIndex = w.matchStart;
+			var lookaheadMatch = lookaheadRegExp.exec(w.source);
+			if(lookaheadMatch) {
+				w.nextMatch = lookaheadRegExp.lastIndex;
+				e = createTiddlyElement(w.output,lookaheadMatch[2] == "\n" ? "div" : "span",null,lookaheadMatch[1]);
+				w.subWikifyTerm(e,/(\}\}\})/mg);
+			}
+			break;
+		}
+	}
+},
+
+{
+	name: "mdash",
+	match: "--",
+	handler: function(w)
+	{
+		createTiddlyElement(w.output,"span").innerHTML = "—";
+	}
+},
+
+{
+	name: "lineBreak",
+	match: "\\n|<br ?/?>",
+	handler: function(w)
+	{
+		createTiddlyElement(w.output,"br");
+	}
+},
+
+{
+	name: "rawText",
+	match: "\"{3}|<nowiki>",
+	lookaheadRegExp: /(?:\"{3}|<nowiki>)((?:.|\n)*?)(?:\"{3}|<\/nowiki>)/mg,
+	handler: function(w)
+	{
+		this.lookaheadRegExp.lastIndex = w.matchStart;
+		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
+		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
+			createTiddlyElement(w.output,"span",null,null,lookaheadMatch[1]);
+			w.nextMatch = this.lookaheadRegExp.lastIndex;
+		}
+	}
+},
+
+{
+	name: "htmlEntitiesEncoding",
+	match: "(?:(?:&#?[a-zA-Z0-9]{2,8};|.)(?:&#?(?:x0*(?:3[0-6][0-9a-fA-F]|1D[c-fC-F][0-9a-fA-F]|20[d-fD-F][0-9a-fA-F]|FE2[0-9a-fA-F])|0*(?:76[89]|7[7-9][0-9]|8[0-7][0-9]|761[6-9]|76[2-7][0-9]|84[0-3][0-9]|844[0-7]|6505[6-9]|6506[0-9]|6507[0-1]));)+|&#?[a-zA-Z0-9]{2,8};)",
+	handler: function(w)
+	{
+		createTiddlyElement(w.output,"span").innerHTML = w.matchText;
+	}
+}
+
+];
+
+//--
+//-- Wikifier
+//--
+
+function getParser(tiddler,format)
+{
+	if(tiddler) {
+		if(!format)
+			format = tiddler.fields["wikiformat"];
+		var i;
+		if(format) {
+			for(i in config.parsers) {
+				if(format == config.parsers[i].format)
+					return config.parsers[i];
+			}
+		} else {
+			for(i in config.parsers) {
+				if(tiddler.isTagged(config.parsers[i].formatTag))
+					return config.parsers[i];
+			}
+		}
+	}
+	return formatter;
+}
+
+function wikify(source,output,highlightRegExp,tiddler)
+{
+	if(source) {
+		var wikifier = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler);
+		var t0 = new Date();
+		wikifier.subWikify(output);
+		if(tiddler && config.options.chkDisplayInstrumentation)
+			displayMessage("wikify:" +tiddler.title+ " in " + (new Date()-t0) + " ms");
+	}
+}
+
+function wikifyStatic(source,highlightRegExp,tiddler,format)
+{
+	var e = createTiddlyElement(document.body,"pre");
+	e.style.display = "none";
+	var html = "";
+	if(source && source != "") {
+		if(!tiddler)
+			tiddler = new Tiddler("temp");
+		var wikifier = new Wikifier(source,getParser(tiddler,format),highlightRegExp,tiddler);
+		wikifier.isStatic = true;
+		wikifier.subWikify(e);
+		html = e.innerHTML;
+		removeNode(e);
+	}
+	return html;
+}
+
+function wikifyPlain(title,theStore,limit)
+{
+	if(!theStore)
+		theStore = store;
+	if(theStore.tiddlerExists(title) || theStore.isShadowTiddler(title)) {
+		return wikifyPlainText(theStore.getTiddlerText(title),limit,tiddler);
+	} else {
+		return "";
+	}
+}
+
+function wikifyPlainText(text,limit,tiddler)
+{
+	if(limit > 0)
+		text = text.substr(0,limit);
+	var wikifier = new Wikifier(text,formatter,null,tiddler);
+	return wikifier.wikifyPlain();
+}
+
+function highlightify(source,output,highlightRegExp,tiddler)
+{
+	if(source) {
+		var wikifier = new Wikifier(source,formatter,highlightRegExp,tiddler);
+		wikifier.outputText(output,0,source.length);
+	}
+}
+
+function Wikifier(source,formatter,highlightRegExp,tiddler)
+{
+	this.source = source;
+	this.output = null;
+	this.formatter = formatter;
+	this.nextMatch = 0;
+	this.autoLinkWikiWords = tiddler && tiddler.autoLinkWikiWords() == false ? false : true;
+	this.highlightRegExp = highlightRegExp;
+	this.highlightMatch = null;
+	this.isStatic = false;
+	if(highlightRegExp) {
+		highlightRegExp.lastIndex = 0;
+		this.highlightMatch = highlightRegExp.exec(source);
+	}
+	this.tiddler = tiddler;
+}
+
+Wikifier.prototype.wikifyPlain = function()
+{
+	var e = createTiddlyElement(document.body,"div");
+	e.style.display = "none";
+	this.subWikify(e);
+	var text = getPlainText(e);
+	removeNode(e);
+	return text;
+};
+
+Wikifier.prototype.subWikify = function(output,terminator)
+{
+	try {
+		if(terminator)
+			this.subWikifyTerm(output,new RegExp("(" + terminator + ")","mg"));
+		else
+			this.subWikifyUnterm(output);
+	} catch(ex) {
+		showException(ex);
+	}
+};
+
+Wikifier.prototype.subWikifyUnterm = function(output)
+{
+	var oldOutput = this.output;
+	this.output = output;
+	this.formatter.formatterRegExp.lastIndex = this.nextMatch;
+	var formatterMatch = this.formatter.formatterRegExp.exec(this.source);
+	while(formatterMatch) {
+		// Output any text before the match
+		if(formatterMatch.index > this.nextMatch)
+			this.outputText(this.output,this.nextMatch,formatterMatch.index);
+		// Set the match parameters for the handler
+		this.matchStart = formatterMatch.index;
+		this.matchLength = formatterMatch[0].length;
+		this.matchText = formatterMatch[0];
+		this.nextMatch = this.formatter.formatterRegExp.lastIndex;
+		for(var t=1; t<formatterMatch.length; t++) {
+			if(formatterMatch[t]) {
+				this.formatter.formatters[t-1].handler(this);
+				this.formatter.formatterRegExp.lastIndex = this.nextMatch;
+				break;
+			}
+		}
+		formatterMatch = this.formatter.formatterRegExp.exec(this.source);
+	}
+	if(this.nextMatch < this.source.length) {
+		this.outputText(this.output,this.nextMatch,this.source.length);
+		this.nextMatch = this.source.length;
+	}
+	this.output = oldOutput;
+};
+
+Wikifier.prototype.subWikifyTerm = function(output,terminatorRegExp)
+{
+	var oldOutput = this.output;
+	this.output = output;
+	terminatorRegExp.lastIndex = this.nextMatch;
+	var terminatorMatch = terminatorRegExp.exec(this.source);
+	this.formatter.formatterRegExp.lastIndex = this.nextMatch;
+	var formatterMatch = this.formatter.formatterRegExp.exec(terminatorMatch ? this.source.substr(0,terminatorMatch.index) : this.source);
+	while(terminatorMatch || formatterMatch) {
+		if(terminatorMatch && (!formatterMatch || terminatorMatch.index <= formatterMatch.index)) {
+			if(terminatorMatch.index > this.nextMatch)
+				this.outputText(this.output,this.nextMatch,terminatorMatch.index);
+			this.matchText = terminatorMatch[1];
+			this.matchLength = terminatorMatch[1].length;
+			this.matchStart = terminatorMatch.index;
+			this.nextMatch = this.matchStart + this.matchLength;
+			this.output = oldOutput;
+			return;
+		}
+		if(formatterMatch.index > this.nextMatch)
+			this.outputText(this.output,this.nextMatch,formatterMatch.index);
+		this.matchStart = formatterMatch.index;
+		this.matchLength = formatterMatch[0].length;
+		this.matchText = formatterMatch[0];
+		this.nextMatch = this.formatter.formatterRegExp.lastIndex;
+		for(var t=1; t<formatterMatch.length; t++) {
+			if(formatterMatch[t]) {
+				this.formatter.formatters[t-1].handler(this);
+				this.formatter.formatterRegExp.lastIndex = this.nextMatch;
+				break;
+			}
+		}
+		terminatorRegExp.lastIndex = this.nextMatch;
+		terminatorMatch = terminatorRegExp.exec(this.source);
+		formatterMatch = this.formatter.formatterRegExp.exec(terminatorMatch ? this.source.substr(0,terminatorMatch.index) : this.source);
+	}
+	if(this.nextMatch < this.source.length) {
+		this.outputText(this.output,this.nextMatch,this.source.length);
+		this.nextMatch = this.source.length;
+	}
+	this.output = oldOutput;
+};
+
+Wikifier.prototype.outputText = function(place,startPos,endPos)
+{
+	while(this.highlightMatch && (this.highlightRegExp.lastIndex > startPos) && (this.highlightMatch.index < endPos) && (startPos < endPos)) {
+		if(this.highlightMatch.index > startPos) {
+			createTiddlyText(place,this.source.substring(startPos,this.highlightMatch.index));
+			startPos = this.highlightMatch.index;
+		}
+		var highlightEnd = Math.min(this.highlightRegExp.lastIndex,endPos);
+		var theHighlight = createTiddlyElement(place,"span",null,"highlight",this.source.substring(startPos,highlightEnd));
+		startPos = highlightEnd;
+		if(startPos >= this.highlightRegExp.lastIndex)
+			this.highlightMatch = this.highlightRegExp.exec(this.source);
+	}
+	if(startPos < endPos) {
+		createTiddlyText(place,this.source.substring(startPos,endPos));
+	}
+};
+
+//--
+//-- Macro definitions
+//--
+
+config.macros.today.handler = function(place,macroName,params)
+{
+	var now = new Date();
+	var text = params[0] ? now.formatString(params[0].trim()) : now.toLocaleString();
+	jQuery("<span/>").text(text).appendTo(place);
+};
+
+config.macros.version.handler = function(place)
+{
+	jQuery("<span/>").text(formatVersion()).appendTo(place);
+};
+
+config.macros.list.handler = function(place,macroName,params)
+{
+	var type = params[0] || "all";
+	var list = document.createElement("ul");
+	place.appendChild(list);
+	if(this[type].prompt)
+		createTiddlyElement(list,"li",null,"listTitle",this[type].prompt);
+	var results;
+	if(this[type].handler)
+		results = this[type].handler(params);
+	for(var t = 0; t < results.length; t++) {
+		var li = document.createElement("li");
+		list.appendChild(li);
+		createTiddlyLink(li,typeof results[t] == "string" ? results[t] : results[t].title,true);
+	}
+};
+
+config.macros.list.all.handler = function(params)
+{
+	return store.reverseLookup("tags","excludeLists",false,"title");
+};
+
+config.macros.list.missing.handler = function(params)
+{
+	return store.getMissingLinks();
+};
+
+config.macros.list.orphans.handler = function(params)
+{
+	return store.getOrphans();
+};
+
+config.macros.list.shadowed.handler = function(params)
+{
+	return store.getShadowed();
+};
+
+config.macros.list.touched.handler = function(params)
+{
+	return store.getTouched();
+};
+
+config.macros.list.filter.handler = function(params)
+{
+	var filter = params[1];
+	var results = [];
+	if(filter) {
+		var tiddlers = store.filterTiddlers(filter);
+		for(var t=0; t<tiddlers.length; t++)
+			results.push(tiddlers[t].title);
+	}
+	return results;
+};
+
+config.macros.allTags.handler = function(place,macroName,params)
+{
+	var tags = store.getTags(params[0]);
+	var ul = createTiddlyElement(place,"ul");
+	if(tags.length == 0)
+		createTiddlyElement(ul,"li",null,"listTitle",this.noTags);
+	for(var t=0; t<tags.length; t++) {
+		var title = tags[t][0];
+		var info = getTiddlyLinkInfo(title);
+		var li = createTiddlyElement(ul,"li");
+		var btn = createTiddlyButton(li,title + " (" + tags[t][1] + ")",this.tooltip.format([title]),onClickTag,info.classes);
+		btn.setAttribute("tag",title);
+		btn.setAttribute("refresh","link");
+		btn.setAttribute("tiddlyLink",title);
+		if(params[1]) {
+			btn.setAttribute("sortby",params[1]);
+		}
+	}
+};
+
+config.macros.timeline.handler = function(place,macroName,params)
+{
+	var field = params[0] || "modified";
+	var tiddlers = store.reverseLookup("tags","excludeLists",false,field);
+	var lastDay = "";
+	var last = params[1] ? tiddlers.length-Math.min(tiddlers.length,parseInt(params[1])) : 0;
+	var dateFormat = params[2] || this.dateFormat;
+	for(var t=tiddlers.length-1; t>=last; t--) {
+		var tiddler = tiddlers[t];
+		var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);
+		if(theDay != lastDay) {
+			var ul = document.createElement("ul");
+			addClass(ul,"timeline");
+			place.appendChild(ul);
+			createTiddlyElement(ul,"li",null,"listTitle",tiddler[field].formatString(dateFormat));
+			lastDay = theDay;
+		}
+		createTiddlyElement(ul,"li",null,"listLink").appendChild(createTiddlyLink(place,tiddler.title,true));
+	}
+};
+
+config.macros.tiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler)
+{
+	params = paramString.parseParams("name",null,true,false,true);
+	var names = params[0]["name"];
+	var tiddlerName = names[0];
+	var className = names[1] || null;
+	var args = params[0]["with"];
+	var wrapper = createTiddlyElement(place,"span",null,className);
+	wrapper.setAttribute("refresh","content");
+	wrapper.setAttribute("tiddler",tiddlerName);
+	if(args!==undefined)
+		wrapper.setAttribute("args","[["+args.join("]] [[")+"]]");
+	this.transclude(wrapper,tiddlerName,args);
+};
+
+config.macros.tiddler.transclude = function(wrapper,tiddlerName,args)
+{
+	var text = store.getTiddlerText(tiddlerName);
+	if(!text)
+		return;
+	var stack = config.macros.tiddler.tiddlerStack;
+	if(stack.indexOf(tiddlerName) !== -1)
+		return;
+	stack.push(tiddlerName);
+	try {
+		if(typeof args == "string")
+			args = args.readBracketedList();
+		var n = args ? Math.min(args.length,9) : 0;
+		for(var i=0; i<n; i++) {
+			var placeholderRE = new RegExp("\\$" + (i + 1),"mg");
+			text = text.replace(placeholderRE,args[i]);
+		}
+		config.macros.tiddler.renderText(wrapper,text,tiddlerName,params);
+	} finally {
+		stack.pop();
+	}
+};
+
+config.macros.tiddler.renderText = function(place,text,tiddlerName,params)
+{
+	wikify(text,place,null,store.getTiddler(tiddlerName));
+};
+
+config.macros.tiddler.tiddlerStack = [];
+
+config.macros.tag.handler = function(place,macroName,params)
+{
+	createTagButton(place,params[0],null,params[1],params[2]);
+	if(params[3]) {
+		btn.setAttribute('sortby',params[3]);
+	}
+};
+
+config.macros.tags.handler = function(place,macroName,params,wikifier,paramString,tiddler)
+{
+	params = paramString.parseParams("anon",null,true,false,false);
+	var ul = createTiddlyElement(place,"ul");
+	var title = getParam(params,"anon","");
+	if(title && store.tiddlerExists(title))
+		tiddler = store.getTiddler(title);
+	var sep = getParam(params,"sep"," ");
+	var lingo = config.views.wikified.tag;
+	var prompt = tiddler.tags.length == 0 ? lingo.labelNoTags : lingo.labelTags;
+	createTiddlyElement(ul,"li",null,"listTitle",prompt.format([tiddler.title]));
+	for(var t=0; t<tiddler.tags.length; t++) {
+		var tag = store.getTiddler(tiddler.tags[t]);
+		if(!tag || !tag.tags.contains("excludeLists")) {
+			createTagButton(createTiddlyElement(ul,"li"),tiddler.tags[t],tiddler.title);
+			if(t<tiddler.tags.length-1)
+				createTiddlyText(ul,sep);
+		}
+	}
+};
+
+config.macros.tagging.handler = function(place,macroName,params,wikifier,paramString,tiddler)
+{
+	params = paramString.parseParams("anon",null,true,false,false);
+	var ul = createTiddlyElement(place,"ul");
+	var title = getParam(params,"anon","");
+	if(title == "" && tiddler instanceof Tiddler)
+		title = tiddler.title;
+	var sep = getParam(params,"sep"," ");
+	ul.setAttribute("title",this.tooltip.format([title]));
+	var tagged = store.getTaggedTiddlers(title);
+	var prompt = tagged.length == 0 ? this.labelNotTag : this.label;
+	createTiddlyElement(ul,"li",null,"listTitle",prompt.format([title,tagged.length]));
+	for(var t=0; t<tagged.length; t++) {
+		createTiddlyLink(createTiddlyElement(ul,"li"),tagged[t].title,true);
+		if(t<tagged.length-1)
+			createTiddlyText(ul,sep);
+	}
+};
+
+config.macros.closeAll.handler = function(place)
+{
+	createTiddlyButton(place,this.label,this.prompt,this.onClick);
+};
+
+config.macros.closeAll.onClick = function(e)
+{
+	story.closeAllTiddlers();
+	return false;
+};
+
+config.macros.permaview.handler = function(place)
+{
+	createTiddlyButton(place,this.label,this.prompt,this.onClick);
+};
+
+config.macros.permaview.onClick = function(e)
+{
+	story.permaView();
+	return false;
+};
+
+config.macros.saveChanges.handler = function(place,macroName,params)
+{
+	if(!readOnly)
+		createTiddlyButton(place,params[0] || this.label,params[1] || this.prompt,this.onClick,null,null,this.accessKey);
+};
+
+config.macros.saveChanges.onClick = function(e)
+{
+	saveChanges();
+	return false;
+};
+
+config.macros.slider.onClickSlider = function(ev)
+{
+	var e = ev || window.event;
+	var n = this.nextSibling;
+	var cookie = n.getAttribute("cookie");
+	var isOpen = n.style.display != "none";
+	if(config.options.chkAnimate && anim && typeof Slider == "function")
+		anim.startAnimating(new Slider(n,!isOpen,null,"none"));
+	else
+		n.style.display = isOpen ? "none" : "block";
+	config.options[cookie] = !isOpen;
+	saveOptionCookie(cookie);
+	return false;
+};
+
+config.macros.slider.createSlider = function(place,cookie,title,tooltip)
+{
+	var c = cookie || "";
+	var btn = createTiddlyButton(place,title,tooltip,this.onClickSlider);
+	var panel = createTiddlyElement(null,"div",null,"sliderPanel");
+	panel.setAttribute("cookie",c);
+	panel.style.display = config.options[c] ? "block" : "none";
+	place.appendChild(panel);
+	return panel;
+};
+
+config.macros.slider.handler = function(place,macroName,params)
+{
+	var panel = this.createSlider(place,params[0],params[2],params[3]);
+	var text = store.getTiddlerText(params[1]);
+	panel.setAttribute("refresh","content");
+	panel.setAttribute("tiddler",params[1]);
+	if(text)
+		wikify(text,panel,null,store.getTiddler(params[1]));
+};
+
+// <<gradient [[tiddler name]] vert|horiz rgb rgb rgb rgb... >>
+config.macros.gradient.handler = function(place,macroName,params,wikifier,paramString,tiddler)
+{
+	var panel = wikifier ? createTiddlyElement(place,"div",null,"gradient") : place;
+	panel.style.position = "relative";
+	panel.style.overflow = "hidden";
+	panel.style.zIndex = "0";
+	if(wikifier) {
+		var styles = config.formatterHelpers.inlineCssHelper(wikifier);
+		config.formatterHelpers.applyCssHelper(panel,styles);
+	}
+	params = paramString.parseParams("color");
+	var locolors = [], hicolors = [];
+	for(var t=2; t<params.length; t++) {
+		var c = params[t].value;
+		if(params[t].name == "snap") {
+			hicolors[hicolors.length-1] = c;
+		} else {
+			locolors.push(c);
+			hicolors.push(c);
+		}
+	}
+	drawGradient(panel,params[1].value != "vert",locolors,hicolors);
+	if(wikifier)
+		wikifier.subWikify(panel,">>");
+	if(document.all) {
+		panel.style.height = "100%";
+		panel.style.width = "100%";
+	}
+};
+
+config.macros.message.handler = function(place,macroName,params)
+{
+	if(params[0]) {
+		var names = params[0].split(".");
+		var lookupMessage = function(root,nameIndex) {
+				if(names[nameIndex] in root) {
+					if(nameIndex < names.length-1)
+						return (lookupMessage(root[names[nameIndex]],nameIndex+1));
+					else
+						return root[names[nameIndex]];
+				} else
+					return null;
+			};
+		var m = lookupMessage(config,0);
+		if(m == null)
+			m = lookupMessage(window,0);
+		createTiddlyText(place,m.toString().format(params.splice(1)));
+	}
+};
+
+
+config.macros.view.views = {
+	text: function(value,place,params,wikifier,paramString,tiddler) {
+		highlightify(value,place,highlightHack,tiddler);
+	},
+	link: function(value,place,params,wikifier,paramString,tiddler) {
+		createTiddlyLink(place,value,true);
+	},
+	wikified: function(value,place,params,wikifier,paramString,tiddler) {
+		if(params[2])
+			value=params[2].unescapeLineBreaks().format([value]);
+		wikify(value,place,highlightHack,tiddler);
+	},
+	date: function(value,place,params,wikifier,paramString,tiddler) {
+		value = Date.convertFromYYYYMMDDHHMM(value);
+		createTiddlyText(place,value.formatString(params[2] ? params[2] : config.views.wikified.dateFormat));
+	}
+};
+
+config.macros.view.handler = function(place,macroName,params,wikifier,paramString,tiddler)
+{
+	if((tiddler instanceof Tiddler) && params[0]) {
+		var value = store.getValue(tiddler,params[0]);
+		if(value) {
+			var type = params[1] || config.macros.view.defaultView;
+			var handler = config.macros.view.views[type];
+			if(handler)
+				handler(value,place,params,wikifier,paramString,tiddler);
+		}
+	}
+};
+
+config.macros.edit.handler = function(place,macroName,params,wikifier,paramString,tiddler)
+{
+	var field = params[0];
+	var rows = params[1] || 0;
+	var defVal = params[2] || '';
+	if((tiddler instanceof Tiddler) && field) {
+		story.setDirty(tiddler.title,true);
+		var e,v;
+		if(field != "text" && !rows) {
+			e = createTiddlyElement(null,"input");
+			e.setAttribute("edit",field);
+			e.setAttribute("type","text");
+			e.value = store.getValue(tiddler,field) || defVal;
+			e.setAttribute("size","40");
+			e.setAttribute("autocomplete","off");
+			place.appendChild(e);
+		} else {
+			var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
+			var wrapper2 = createTiddlyElement(wrapper1,"div");
+			e = createTiddlyElement(wrapper2,"textarea");
+			e.value = v = store.getValue(tiddler,field) || defVal;
+			rows = rows || 10;
+			var lines = v.match(/\n/mg);
+			var maxLines = Math.max(parseInt(config.options.txtMaxEditRows),5);
+			if(lines != null && lines.length > rows)
+				rows = lines.length + 5;
+			rows = Math.min(rows,maxLines);
+			e.setAttribute("rows",rows);
+			e.setAttribute("edit",field);
+			place.appendChild(wrapper1);
+		}
+		if(tiddler.isReadOnly()) {
+			e.setAttribute("readOnly","readOnly");
+			addClass(e,"readOnly");
+		}
+		return e;
+	}
+};
+
+config.macros.tagChooser.onClick = function(ev)
+{
+	var e = ev || window.event;
+	var lingo = config.views.editor.tagChooser;
+	var popup = Popup.create(this);
+	var tags = store.getTags(this.getAttribute("tags"));
+	if(tags.length == 0)
+		jQuery("<li/>").text(lingo.popupNone).appendTo(jQuery(popup));
+	for(var t=0; t<tags.length; t++) {
+		var tag = createTiddlyButton(createTiddlyElement(popup,"li"),tags[t][0],lingo.tagTooltip.format([tags[t][0]]),config.macros.tagChooser.onTagClick);
+		tag.setAttribute("tag",tags[t][0]);
+		tag.setAttribute("tiddler",this.getAttribute("tiddler"));
+	}
+	Popup.show();
+	e.cancelBubble = true;
+	if(e.stopPropagation) e.stopPropagation();
+	return false;
+};
+
+config.macros.tagChooser.onTagClick = function(ev)
+{
+	var e = ev || window.event;
+	if(e.metaKey || e.ctrlKey) stopEvent(e); //# keep popup open on CTRL-click
+	var tag = this.getAttribute("tag");
+	var title = this.getAttribute("tiddler");
+	if(!readOnly)
+		story.setTiddlerTag(title,tag,0);
+	return false;
+};
+
+config.macros.tagChooser.handler = function(place,macroName,params,wikifier,paramString,tiddler)
+{
+	if(tiddler instanceof Tiddler) {
+		var lingo = config.views.editor.tagChooser;
+		var btn = createTiddlyButton(place,lingo.text,lingo.tooltip,this.onClick);
+		btn.setAttribute("tiddler",tiddler.title);
+		btn.setAttribute("tags",params[0]);
+	}
+};
+
+config.macros.refreshDisplay.handler = function(place)
+{
+	createTiddlyButton(place,this.label,this.prompt,this.onClick);
+};
+
+config.macros.refreshDisplay.onClick = function(e)
+{
+	refreshAll();
+	return false;
+};
+
+config.macros.annotations.handler = function(place,macroName,params,wikifier,paramString,tiddler)
+{
+	var title = tiddler ? tiddler.title : null;
+	var a = title ? config.annotations[title] : null;
+	if(!tiddler || !title || !a)
+		return;
+	var text = a.format([title]);
+	wikify(text,createTiddlyElement(place,"div",null,"annotation"),null,tiddler);
+};
+
+//--
+//-- NewTiddler and NewJournal macros
+//--
+
+config.macros.newTiddler.createNewTiddlerButton = function(place,title,params,label,prompt,accessKey,newFocus,isJournal)
+{
+	var tags = [];
+	for(var t=1; t<params.length; t++) {
+		if((params[t].name == "anon" && t != 1) || (params[t].name == "tag"))
+			tags.push(params[t].value);
+	}
+	label = getParam(params,"label",label);
+	prompt = getParam(params,"prompt",prompt);
+	accessKey = getParam(params,"accessKey",accessKey);
+	newFocus = getParam(params,"focus",newFocus);
+	var customFields = getParam(params,"fields","");
+	if(!customFields && !store.isShadowTiddler(title))
+		customFields = String.encodeHashMap(config.defaultCustomFields);
+	var btn = createTiddlyButton(place,label,prompt,this.onClickNewTiddler,null,null,accessKey);
+	btn.setAttribute("newTitle",title);
+	btn.setAttribute("isJournal",isJournal ? "true" : "false");
+	if(tags.length > 0)
+		btn.setAttribute("params",tags.join("|"));
+	btn.setAttribute("newFocus",newFocus);
+	btn.setAttribute("newTemplate",getParam(params,"template",DEFAULT_EDIT_TEMPLATE));
+	if(customFields !== "")
+		btn.setAttribute("customFields",customFields);
+	var text = getParam(params,"text");
+	if(text !== undefined)
+		btn.setAttribute("newText",text);
+	return btn;
+};
+
+config.macros.newTiddler.onClickNewTiddler = function()
+{
+	var title = this.getAttribute("newTitle");
+	if(this.getAttribute("isJournal") == "true") {
+		title = new Date().formatString(title.trim());
+	}
+	var params = this.getAttribute("params");
+	var tags = params ? params.split("|") : [];
+	var focus = this.getAttribute("newFocus");
+	var template = this.getAttribute("newTemplate");
+	var customFields = this.getAttribute("customFields");
+	if(!customFields && !store.isShadowTiddler(title))
+		customFields = String.encodeHashMap(config.defaultCustomFields);
+	story.displayTiddler(null,title,template,false,null,null);
+	var tiddlerElem = story.getTiddler(title);
+	if(customFields)
+		story.addCustomFields(tiddlerElem,customFields);
+	var text = this.getAttribute("newText");
+	if(typeof text == "string" && story.getTiddlerField(title,"text"))
+		story.getTiddlerField(title,"text").value = text.format([title]);
+	for(var t=0;t<tags.length;t++)
+		story.setTiddlerTag(title,tags[t],+1);
+	story.focusTiddler(title,focus);
+	return false;
+};
+
+config.macros.newTiddler.handler = function(place,macroName,params,wikifier,paramString)
+{
+	if(!readOnly) {
+		params = paramString.parseParams("anon",null,true,false,false);
+		var title = params[1] && params[1].name == "anon" ? params[1].value : this.title;
+		title = getParam(params,"title",title);
+		this.createNewTiddlerButton(place,title,params,this.label,this.prompt,this.accessKey,"title",false);
+	}
+};
+
+config.macros.newJournal.handler = function(place,macroName,params,wikifier,paramString)
+{
+	if(!readOnly) {
+		params = paramString.parseParams("anon",null,true,false,false);
+		var title = params[1] && params[1].name == "anon" ? params[1].value : config.macros.timeline.dateFormat;
+		title = getParam(params,"title",title);
+		config.macros.newTiddler.createNewTiddlerButton(place,title,params,this.label,this.prompt,this.accessKey,"text",true);
+	}
+};
+
+//--
+//-- Search macro
+//--
+
+config.macros.search.handler = function(place,macroName,params)
+{
+	var searchTimeout = null;
+	var btn = createTiddlyButton(place,this.label,this.prompt,this.onClick,"searchButton");
+	var txt = createTiddlyElement(null,"input",null,"txtOptionInput searchField");
+	if(params[0])
+		txt.value = params[0];
+	if(config.browser.isSafari) {
+		txt.setAttribute("type","search");
+		txt.setAttribute("results","5");
+	} else {
+		txt.setAttribute("type","text");
+	}
+	place.appendChild(txt);
+	txt.onkeyup = this.onKeyPress;
+	txt.onfocus = this.onFocus;
+	txt.setAttribute("size",this.sizeTextbox);
+	txt.setAttribute("accessKey",params[1] || this.accessKey);
+	txt.setAttribute("autocomplete","off");
+	txt.setAttribute("lastSearchText","");
+};
+
+// Global because there's only ever one outstanding incremental search timer
+config.macros.search.timeout = null;
+
+config.macros.search.doSearch = function(txt)
+{
+	if(txt.value.length > 0) {
+		story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);
+		txt.setAttribute("lastSearchText",txt.value);
+	}
+};
+
+config.macros.search.onClick = function(e)
+{
+	config.macros.search.doSearch(this.nextSibling);
+	return false;
+};
+
+config.macros.search.onKeyPress = function(ev)
+{
+	var e = ev || window.event;
+	switch(e.keyCode) {
+		case 13: // Ctrl-Enter
+		case 10: // Ctrl-Enter on IE PC
+			config.macros.search.doSearch(this);
+			break;
+		case 27: // Escape
+			this.value = "";
+			clearMessage();
+			break;
+	}
+	if(config.options.chkIncrementalSearch) {
+		if(this.value.length > 2) {
+			if(this.value != this.getAttribute("lastSearchText")) {
+				if(config.macros.search.timeout)
+					clearTimeout(config.macros.search.timeout);
+				var txt = this;
+				config.macros.search.timeout = setTimeout(function() {config.macros.search.doSearch(txt);},500);
+			}
+		} else {
+			if(config.macros.search.timeout)
+				clearTimeout(config.macros.search.timeout);
+		}
+	}
+};
+
+config.macros.search.onFocus = function(e)
+{
+	this.select();
+};
+
+//--
+//-- Tabs macro
+//--
+
+config.macros.tabs.handler = function(place,macroName,params)
+{
+	var cookie = params[0];
+	var numTabs = (params.length-1)/3;
+	var wrapper = createTiddlyElement(null,"div",null,"tabsetWrapper " + cookie);
+	var tabset = createTiddlyElement(wrapper,"div",null,"tabset");
+	tabset.setAttribute("cookie",cookie);
+	var validTab = false;
+	for(var t=0; t<numTabs; t++) {
+		var label = params[t*3+1];
+		var prompt = params[t*3+2];
+		var content = params[t*3+3];
+		var tab = createTiddlyButton(tabset,label,prompt,this.onClickTab,"tab tabUnselected");
+		createTiddlyElement(tab,"span",null,null," ",{style:"font-size:0pt;line-height:0px"});
+		tab.setAttribute("tab",label);
+		tab.setAttribute("content",content);
+		tab.title = prompt;
+		if(config.options[cookie] == label)
+			validTab = true;
+	}
+	if(!validTab)
+		config.options[cookie] = params[1];
+	place.appendChild(wrapper);
+	this.switchTab(tabset,config.options[cookie]);
+};
+
+config.macros.tabs.onClickTab = function(e)
+{
+	config.macros.tabs.switchTab(this.parentNode,this.getAttribute("tab"));
+	return false;
+};
+
+config.macros.tabs.switchTab = function(tabset,tab)
+{
+	var cookie = tabset.getAttribute("cookie");
+	var theTab = null;
+	var nodes = tabset.childNodes;
+	for(var t=0; t<nodes.length; t++) {
+		if(nodes[t].getAttribute && nodes[t].getAttribute("tab") == tab) {
+			theTab = nodes[t];
+			theTab.className = "tab tabSelected";
+		} else {
+			nodes[t].className = "tab tabUnselected";
+		}
+	}
+	if(theTab) {
+		if(tabset.nextSibling && tabset.nextSibling.className == "tabContents")
+			removeNode(tabset.nextSibling);
+		var tabContent = createTiddlyElement(null,"div",null,"tabContents");
+		tabset.parentNode.insertBefore(tabContent,tabset.nextSibling);
+		var contentTitle = theTab.getAttribute("content");
+		wikify(store.getTiddlerText(contentTitle),tabContent,null,store.getTiddler(contentTitle));
+		if(cookie) {
+			config.options[cookie] = tab;
+			saveOptionCookie(cookie);
+		}
+	}
+};
+
+//--
+//-- Tiddler toolbar
+//--
+
+// Create a toolbar command button
+config.macros.toolbar.createCommand = function(place,commandName,tiddler,className)
+{
+	if(typeof commandName != "string") {
+		var c = null;
+		for(var t in config.commands) {
+			if(config.commands[t] == commandName)
+				c = t;
+		}
+		commandName = c;
+	}
+	if((tiddler instanceof Tiddler) && (typeof commandName == "string")) {
+		var command = config.commands[commandName];
+		if(command.isEnabled ? command.isEnabled(tiddler) : this.isCommandEnabled(command,tiddler)) {
+			var text = command.getText ? command.getText(tiddler) : this.getCommandText(command,tiddler);
+			var tooltip = command.getTooltip ? command.getTooltip(tiddler) : this.getCommandTooltip(command,tiddler);
+			var cmd;
+			switch(command.type) {
+			case "popup":
+				cmd = this.onClickPopup;
+				break;
+			case "command":
+			default:
+				cmd = this.onClickCommand;
+				break;
+			}
+			var btn = createTiddlyButton(null,text,tooltip,cmd);
+			btn.setAttribute("commandName",commandName);
+			btn.setAttribute("tiddler",tiddler.title);
+			addClass(btn,"command_" + commandName);
+			if(className)
+				addClass(btn,className);
+			place.appendChild(btn);
+		}
+	}
+};
+
+config.macros.toolbar.isCommandEnabled = function(command,tiddler)
+{
+	var title = tiddler.title;
+	var ro = tiddler.isReadOnly();
+	var shadow = store.isShadowTiddler(title) && !store.tiddlerExists(title);
+	return (!ro || (ro && !command.hideReadOnly)) && !(shadow && command.hideShadow);
+};
+
+config.macros.toolbar.getCommandText = function(command,tiddler)
+{
+	return tiddler.isReadOnly() && command.readOnlyText || command.text;
+};
+
+config.macros.toolbar.getCommandTooltip = function(command,tiddler)
+{
+	return tiddler.isReadOnly() && command.readOnlyTooltip || command.tooltip;
+};
+
+config.macros.toolbar.onClickCommand = function(ev)
+{
+	var e = ev || window.event;
+	e.cancelBubble = true;
+	if(e.stopPropagation) e.stopPropagation();
+	var command = config.commands[this.getAttribute("commandName")];
+	return command.handler(e,this,this.getAttribute("tiddler"));
+};
+
+config.macros.toolbar.onClickPopup = function(ev)
+{
+	var e = ev || window.event;
+	e.cancelBubble = true;
+	if(e.stopPropagation) e.stopPropagation();
+	var popup = Popup.create(this);
+	var command = config.commands[this.getAttribute("commandName")];
+	var title = this.getAttribute("tiddler");
+	var tiddler = store.fetchTiddler(title);
+	popup.setAttribute("tiddler",title);
+	command.handlePopup(popup,title);
+	Popup.show();
+	return false;
+};
+
+// Invoke the first command encountered from a given place that is tagged with a specified class
+config.macros.toolbar.invokeCommand = function(place,className,event)
+{
+	var children = place.getElementsByTagName("a");
+	for(var t=0; t<children.length; t++) {
+		var c = children[t];
+		if(hasClass(c,className) && c.getAttribute && c.getAttribute("commandName")) {
+			if(c.onclick instanceof Function)
+				c.onclick.call(c,event);
+			break;
+		}
+	}
+};
+
+config.macros.toolbar.onClickMore = function(ev)
+{
+	var e = this.nextSibling;
+	e.style.display = "inline";
+	this.style.display = "none";
+	return false;
+};
+
+config.macros.toolbar.onClickLess = function(ev)
+{
+	var e = this.parentNode;
+	var m = e.previousSibling;
+	e.style.display = "none";
+	m.style.display = "inline";
+	return false;
+};
+
+config.macros.toolbar.handler = function(place,macroName,params,wikifier,paramString,tiddler)
+{
+	for(var t=0; t<params.length; t++) {
+		var c = params[t];
+		switch(c) {
+		case "!":
+			createTiddlyText(place,this.separator);
+			break;
+		case "*":
+			createTiddlyElement(place,"br");
+			break;
+		case "<":
+			var btn = createTiddlyButton(place,this.lessLabel,this.lessPrompt,config.macros.toolbar.onClickLess);
+			addClass(btn,"lessCommand");
+			break;
+		case ">":
+			var btn = createTiddlyButton(place,this.moreLabel,this.morePrompt,config.macros.toolbar.onClickMore);
+			addClass(btn,"moreCommand");
+			var e = createTiddlyElement(place,"span",null,"moreCommand");
+			e.style.display = "none";
+			place = e;
+			break;
+		default:
+			var className = "";
+			switch(c.substr(0,1)) {
+			case "+":
+				className = "defaultCommand";
+				c = c.substr(1);
+				break;
+			case "-":
+				className = "cancelCommand";
+				c = c.substr(1);
+				break;
+			}
+			if(c in config.commands)
+				this.createCommand(place,c,tiddler,className);
+			break;
+		}
+	}
+};
+
+//--
+//-- Menu and toolbar commands
+//--
+
+config.commands.closeTiddler.handler = function(event,src,title)
+{
+	if(story.isDirty(title) && !readOnly) {
+		if(!confirm(config.commands.cancelTiddler.warning.format([title])))
+			return false;
+	}
+	story.setDirty(title,false);
+	story.closeTiddler(title,true);
+	return false;
+};
+
+config.commands.closeOthers.handler = function(event,src,title)
+{
+	story.closeAllTiddlers(title);
+	return false;
+};
+
+config.commands.editTiddler.handler = function(event,src,title)
+{
+	clearMessage();
+	var tiddlerElem = story.getTiddler(title);
+	var fields = tiddlerElem.getAttribute("tiddlyFields");
+	story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE,false,null,fields);
+	story.focusTiddler(title,config.options.txtEditorFocus||"text");
+	return false;
+};
+
+config.commands.saveTiddler.handler = function(event,src,title)
+{
+	var newTitle = story.saveTiddler(title,event.shiftKey);
+	if(newTitle)
+		story.displayTiddler(null,newTitle);
+	return false;
+};
+
+config.commands.cancelTiddler.handler = function(event,src,title)
+{
+	if(story.hasChanges(title) && !readOnly) {
+		if(!confirm(this.warning.format([title])))
+			return false;
+	}
+	story.setDirty(title,false);
+	story.displayTiddler(null,title);
+	return false;
+};
+
+config.commands.deleteTiddler.handler = function(event,src,title)
+{
+	var deleteIt = true;
+	if(config.options.chkConfirmDelete)
+		deleteIt = confirm(this.warning.format([title]));
+	if(deleteIt) {
+		store.removeTiddler(title);
+		story.closeTiddler(title,true);
+		autoSaveChanges();
+	}
+	return false;
+};
+
+config.commands.permalink.handler = function(event,src,title)
+{
+	var t = encodeURIComponent(String.encodeTiddlyLink(title));
+	if(window.location.hash != t)
+		window.location.hash = t;
+	return false;
+};
+
+config.commands.references.handlePopup = function(popup,title)
+{
+	var references = store.getReferringTiddlers(title);
+	var c = false;
+	for(var r=0; r<references.length; r++) {
+		if(references[r].title != title && !references[r].isTagged("excludeLists")) {
+			createTiddlyLink(createTiddlyElement(popup,"li"),references[r].title,true);
+			c = true;
+		}
+	}
+	if(!c)
+		createTiddlyElement(popup,"li",null,"disabled",this.popupNone);
+};
+
+config.commands.jump.handlePopup = function(popup,title)
+{
+	story.forEachTiddler(function(title,element) {
+		createTiddlyLink(createTiddlyElement(popup,"li"),title,true,null,false,null,true);
+		});
+};
+
+config.commands.syncing.handlePopup = function(popup,title)
+{
+	var tiddler = store.fetchTiddler(title);
+	if(!tiddler)
+		return;
+	var serverType = tiddler.getServerType();
+	var serverHost = tiddler.fields["server.host"];
+	var serverWorkspace = tiddler.fields["server.workspace"];
+	if(!serverWorkspace)
+		serverWorkspace = "";
+	if(serverType) {
+		var e = createTiddlyElement(popup,"li",null,"popupMessage");
+		e.innerHTML = config.commands.syncing.currentlySyncing.format([serverType,serverHost,serverWorkspace]);
+	} else {
+		createTiddlyElement(popup,"li",null,"popupMessage",config.commands.syncing.notCurrentlySyncing);
+	}
+	if(serverType) {
+		createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
+		var btn = createTiddlyButton(createTiddlyElement(popup,"li"),this.captionUnSync,null,config.commands.syncing.onChooseServer);
+		btn.setAttribute("tiddler",title);
+		btn.setAttribute("server.type","");
+	}
+	createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
+	createTiddlyElement(popup,"li",null,"popupMessage",config.commands.syncing.chooseServer);
+	var feeds = store.getTaggedTiddlers("systemServer","title");
+	for(var t=0; t<feeds.length; t++) {
+		var f = feeds[t];
+		var feedServerType = store.getTiddlerSlice(f.title,"Type");
+		if(!feedServerType)
+			feedServerType = "file";
+		var feedServerHost = store.getTiddlerSlice(f.title,"URL");
+		if(!feedServerHost)
+			feedServerHost = "";
+		var feedServerWorkspace = store.getTiddlerSlice(f.title,"Workspace");
+		if(!feedServerWorkspace)
+			feedServerWorkspace = "";
+		var caption = f.title;
+		if(serverType == feedServerType && serverHost == feedServerHost && serverWorkspace == feedServerWorkspace) {
+			caption = config.commands.syncing.currServerMarker + caption;
+		} else {
+			caption = config.commands.syncing.notCurrServerMarker + caption;
+		}
+		btn = createTiddlyButton(createTiddlyElement(popup,"li"),caption,null,config.commands.syncing.onChooseServer);
+		btn.setAttribute("tiddler",title);
+		btn.setAttribute("server.type",feedServerType);
+		btn.setAttribute("server.host",feedServerHost);
+		btn.setAttribute("server.workspace",feedServerWorkspace);
+	}
+};
+
+config.commands.syncing.onChooseServer = function(e)
+{
+	var tiddler = this.getAttribute("tiddler");
+	var serverType = this.getAttribute("server.type");
+	if(serverType) {
+		store.addTiddlerFields(tiddler,{
+			"server.type": serverType,
+			"server.host": this.getAttribute("server.host"),
+			"server.workspace": this.getAttribute("server.workspace")
+			});
+	} else {
+		store.setValue(tiddler,"server",null);
+	}
+	return false;
+};
+
+config.commands.fields.handlePopup = function(popup,title)
+{
+	var tiddler = store.fetchTiddler(title);
+	if(!tiddler)
+		return;
+	var items = [];
+	store.forEachField(tiddler,function(tiddler,fieldName,value){items.push({field:fieldName,value:value});},true);
+	items.sort(function(a,b) {return a.field < b.field ? -1 : (a.field == b.field ? 0 : +1);});
+	if(items.length > 0)
+		ListView.create(popup,items,this.listViewTemplate);
+	else
+		createTiddlyElement(popup,"div",null,null,this.emptyText);
+};
+
+//--
+//-- Tiddler() object
+//--
+
+function Tiddler(title)
+{
+	this.title = title;
+	this.text = "";
+	this.creator = null;
+	this.modifier = null;
+	this.created = new Date();
+	this.modified = this.created;
+	this.links = [];
+	this.linksUpdated = false;
+	this.tags = [];
+	this.fields = {};
+	return this;
+}
+
+Tiddler.prototype.getLinks = function()
+{
+	if(this.linksUpdated==false)
+		this.changed();
+	return this.links;
+};
+
+// Returns the fields that are inherited in string field:"value" field2:"value2" format
+Tiddler.prototype.getInheritedFields = function()
+{
+	var f = {};
+	for(var i in this.fields) {
+		if(i=="server.host" || i=="server.workspace" || i=="wikiformat"|| i=="server.type") {
+			f[i] = this.fields[i];
+		}
+	}
+	return String.encodeHashMap(f);
+};
+
+// Increment the changeCount of a tiddler
+Tiddler.prototype.incChangeCount = function()
+{
+	var c = this.fields['changecount'];
+	c = c ? parseInt(c,10) : 0;
+	this.fields['changecount'] = String(c+1);
+};
+
+// Clear the changeCount of a tiddler
+Tiddler.prototype.clearChangeCount = function()
+{
+	if(this.fields['changecount']) {
+		delete this.fields['changecount'];
+	}
+};
+
+Tiddler.prototype.doNotSave = function()
+{
+	return this.fields['doNotSave'];
+};
+
+// Returns true if the tiddler has been updated since the tiddler was created or downloaded
+Tiddler.prototype.isTouched = function()
+{
+	var changeCount = this.fields['changecount'];
+	if(changeCount === undefined)
+		changeCount = 0;
+	return changeCount > 0;
+};
+
+// Change the text and other attributes of a tiddler
+Tiddler.prototype.set = function(title,text,modifier,modified,tags,created,fields,creator)
+{
+	this.assign(title,text,modifier,modified,tags,created,fields,creator);
+	this.changed();
+	return this;
+};
+
+// Change the text and other attributes of a tiddler without triggered a tiddler.changed() call
+Tiddler.prototype.assign = function(title,text,modifier,modified,tags,created,fields,creator)
+{
+	if(title != undefined)
+		this.title = title;
+	if(text != undefined)
+		this.text = text;
+	if(modifier != undefined)
+		this.modifier = modifier;
+	if(modified != undefined)
+		this.modified = modified;
+	if(creator != undefined)
+		this.creator = creator;
+	if(created != undefined)
+		this.created = created;
+	if(fields != undefined)
+		this.fields = fields;
+	if(tags != undefined)
+		this.tags = (typeof tags == "string") ? tags.readBracketedList() : tags;
+	else if(this.tags == undefined)
+		this.tags = [];
+	return this;
+};
+
+// Get the tags for a tiddler as a string (space delimited, using [[brackets]] for tags containing spaces)
+Tiddler.prototype.getTags = function()
+{
+	return String.encodeTiddlyLinkList(this.tags);
+};
+
+// Test if a tiddler carries a tag
+Tiddler.prototype.isTagged = function(tag)
+{
+	return this.tags.indexOf(tag) != -1;
+};
+
+// Static method to convert "\n" to newlines, "\s" to "\"
+Tiddler.unescapeLineBreaks = function(text)
+{
+	return text ? text.unescapeLineBreaks() : "";
+};
+
+// Convert newlines to "\n", "\" to "\s"
+Tiddler.prototype.escapeLineBreaks = function()
+{
+	return this.text.escapeLineBreaks();
+};
+
+// Updates the secondary information (like links[] array) after a change to a tiddler
+Tiddler.prototype.changed = function()
+{
+	this.links = [];
+	var text = this.text;
+	// remove 'quoted' text before scanning tiddler source
+	text = text.replace(/\/%((?:.|\n)*?)%\//g,"").
+		replace(/\{{3}((?:.|\n)*?)\}{3}/g,"").
+		replace(/"""((?:.|\n)*?)"""/g,"").
+		replace(/\<nowiki\>((?:.|\n)*?)\<\/nowiki\>/g,"").
+		replace(/\<html\>((?:.|\n)*?)\<\/html\>/g,"").
+		replace(/\<script((?:.|\n)*?)\<\/script\>/g,"");
+	var t = this.autoLinkWikiWords() ? 0 : 1;
+	var tiddlerLinkRegExp = t==0 ? config.textPrimitives.tiddlerAnyLinkRegExp : config.textPrimitives.tiddlerForcedLinkRegExp;
+	tiddlerLinkRegExp.lastIndex = 0;
+	var formatMatch = tiddlerLinkRegExp.exec(text);
+	while(formatMatch) {
+		var lastIndex = tiddlerLinkRegExp.lastIndex;
+		if(t==0 && formatMatch[1] && formatMatch[1] != this.title) {
+			// wikiWordLink
+			if(formatMatch.index > 0) {
+				var preRegExp = new RegExp(config.textPrimitives.unWikiLink+"|"+config.textPrimitives.anyLetter,"mg");
+				preRegExp.lastIndex = formatMatch.index-1;
+				var preMatch = preRegExp.exec(text);
+				if(preMatch.index != formatMatch.index-1)
+					this.links.pushUnique(formatMatch[1]);
+			} else {
+				this.links.pushUnique(formatMatch[1]);
+			}
+		}
+		else if(formatMatch[2-t] && !config.formatterHelpers.isExternalLink(formatMatch[3-t])) // titledBrackettedLink
+			this.links.pushUnique(formatMatch[3-t]);
+		else if(formatMatch[4-t] && formatMatch[4-t] != this.title) // brackettedLink
+			this.links.pushUnique(formatMatch[4-t]);
+		tiddlerLinkRegExp.lastIndex = lastIndex;
+		formatMatch = tiddlerLinkRegExp.exec(text);
+	}
+	this.linksUpdated = true;
+};
+
+Tiddler.prototype.getSubtitle = function()
+{
+	var modifier = this.modifier;
+	if(!modifier)
+		modifier = config.messages.subtitleUnknown;
+	var modified = this.modified;
+	if(modified)
+		modified = modified.toLocaleString();
+	else
+		modified = config.messages.subtitleUnknown;
+	return config.messages.tiddlerLinkTooltip.format([this.title,modifier,modified]);
+};
+
+Tiddler.prototype.isReadOnly = function()
+{
+	return readOnly;
+};
+
+Tiddler.prototype.autoLinkWikiWords = function()
+{
+	return !(this.isTagged("systemConfig") || this.isTagged("excludeMissing"));
+};
+
+Tiddler.prototype.getServerType = function()
+{
+	var serverType = null;
+	if(this.fields['server.type'])
+		serverType = this.fields['server.type'];
+	if(!serverType)
+		serverType = this.fields['wikiformat'];
+	if(serverType && !config.adaptors[serverType])
+		serverType = null;
+	return serverType;
+};
+
+Tiddler.prototype.getAdaptor = function()
+{
+	var serverType = this.getServerType();
+	return serverType ? new config.adaptors[serverType]() : null;
+};
+
+//--
+//-- TiddlyWiki() object contains Tiddler()s
+//--
+
+function TiddlyWiki()
+{
+	var tiddlers = {}; // Hashmap by name of tiddlers
+	this.tiddlersUpdated = false;
+	this.namedNotifications = []; // Array of {name:,notify:} of notification functions
+	this.notificationLevel = 0;
+	this.slices = {}; // map tiddlerName->(map sliceName->sliceValue). Lazy.
+	this.clear = function() {
+		tiddlers = {};
+		this.setDirty(false);
+	};
+	this.fetchTiddler = function(title) {
+		var t = tiddlers[title];
+		return t instanceof Tiddler ? t : null;
+	};
+	this.deleteTiddler = function(title) {
+		delete this.slices[title];
+		delete tiddlers[title];
+	};
+	this.addTiddler = function(tiddler) {
+		delete this.slices[tiddler.title];
+		tiddlers[tiddler.title] = tiddler;
+	};
+	this.forEachTiddler = function(callback) {
+		for(var t in tiddlers) {
+			var tiddler = tiddlers[t];
+			if(tiddler instanceof Tiddler)
+				callback.call(this,t,tiddler);
+		}
+	};
+}
+
+TiddlyWiki.prototype.setDirty = function(dirty)
+{
+	this.dirty = dirty;
+};
+
+TiddlyWiki.prototype.isDirty = function()
+{
+	return this.dirty;
+};
+
+TiddlyWiki.prototype.tiddlerExists = function(title)
+{
+	var t = this.fetchTiddler(title);
+	return t != undefined;
+};
+
+TiddlyWiki.prototype.isShadowTiddler = function(title)
+{
+	return config.shadowTiddlers[title] === undefined ? false : true;
+};
+
+TiddlyWiki.prototype.createTiddler = function(title)
+{
+	var tiddler = this.fetchTiddler(title);
+	if(!tiddler) {
+		tiddler = new Tiddler(title);
+		this.addTiddler(tiddler);
+		this.setDirty(true);
+	}
+	return tiddler;
+};
+
+TiddlyWiki.prototype.getTiddler = function(title)
+{
+	var t = this.fetchTiddler(title);
+	if(t != undefined)
+		return t;
+	else
+		return null;
+};
+
+TiddlyWiki.prototype.getShadowTiddlerText = function(title)
+{
+	if(typeof config.shadowTiddlers[title] == "string")
+		return config.shadowTiddlers[title];
+	else
+		return "";
+};
+
+// Retrieve tiddler contents
+TiddlyWiki.prototype.getTiddlerText = function(title,defaultText)
+{
+	if(!title)
+		return defaultText;
+	var pos = title.indexOf(config.textPrimitives.sectionSeparator);
+	var section = null;
+	if(pos != -1) {
+		section = title.substr(pos + config.textPrimitives.sectionSeparator.length);
+		title = title.substr(0,pos);
+	}
+	pos = title.indexOf(config.textPrimitives.sliceSeparator);
+	if(pos != -1) {
+		var slice = this.getTiddlerSlice(title.substr(0,pos),title.substr(pos + config.textPrimitives.sliceSeparator.length));
+		if(slice)
+			return slice;
+	}
+	var tiddler = this.fetchTiddler(title);
+	if(tiddler) {
+		if(!section)
+			return tiddler.text;
+		var re = new RegExp("(^!{1,6}[ \t]*" + section.escapeRegExp() + "[ \t]*\n)","mg");
+		re.lastIndex = 0;
+		var match = re.exec(tiddler.text);
+		if(match) {
+			var t = tiddler.text.substr(match.index+match[1].length);
+			var re2 = /^!/mg;
+			re2.lastIndex = 0;
+			match = re2.exec(t); //# search for the next heading
+			if(match)
+				t = t.substr(0,match.index-1);//# don't include final \n
+			return t;
+		}
+		return defaultText;
+	}
+	if(this.isShadowTiddler(title))
+		return this.getShadowTiddlerText(title);
+	if(defaultText != undefined)
+		return defaultText;
+	return null;
+};
+
+TiddlyWiki.prototype.getRecursiveTiddlerText = function(title,defaultText,depth)
+{
+	var bracketRegExp = new RegExp("(?:\\[\\[([^\\]]+)\\]\\])","mg");
+	var text = this.getTiddlerText(title,null);
+	if(text == null)
+		return defaultText;
+	var textOut = [];
+	var lastPos = 0;
+	do {
+		var match = bracketRegExp.exec(text);
+		if(match) {
+			textOut.push(text.substr(lastPos,match.index-lastPos));
+			if(match[1]) {
+				if(depth <= 0)
+					textOut.push(match[1]);
+				else
+					textOut.push(this.getRecursiveTiddlerText(match[1],"",depth-1));
+			}
+			lastPos = match.index + match[0].length;
+		} else {
+			textOut.push(text.substr(lastPos));
+		}
+	} while(match);
+	return textOut.join("");
+};
+
+TiddlyWiki.prototype.slicesRE = /(?:^([\'\/]{0,2})~?([\.\w]+)\:\1[\t\x20]*([^\n]+)[\t\x20]*$)|(?:^\|([\'\/]{0,2})~?([\.\w]+)\:?\4\|[\t\x20]*([^\n]+)[\t\x20]*\|$)/gm;
+
+// @internal
+TiddlyWiki.prototype.calcAllSlices = function(title)
+{
+	var slices = {};
+	var text = this.getTiddlerText(title,"");
+	this.slicesRE.lastIndex = 0;
+	var m = this.slicesRE.exec(text);
+	while(m) {
+		if(m[2])
+			slices[m[2]] = m[3];
+		else
+			slices[m[5]] = m[6];
+		m = this.slicesRE.exec(text);
+	}
+	return slices;
+};
+
+// Returns the slice of text of the given name
+TiddlyWiki.prototype.getTiddlerSlice = function(title,sliceName)
+{
+	var slices = this.slices[title];
+	if(!slices) {
+		slices = this.calcAllSlices(title);
+		this.slices[title] = slices;
+	}
+	return slices[sliceName];
+};
+
+// Build an hashmap of the specified named slices of a tiddler
+TiddlyWiki.prototype.getTiddlerSlices = function(title,sliceNames)
+{
+	var r = {};
+	for(var t=0; t<sliceNames.length; t++) {
+		var slice = this.getTiddlerSlice(title,sliceNames[t]);
+		if(slice)
+			r[sliceNames[t]] = slice;
+	}
+	return r;
+};
+
+TiddlyWiki.prototype.suspendNotifications = function()
+{
+	this.notificationLevel--;
+};
+
+TiddlyWiki.prototype.resumeNotifications = function()
+{
+	this.notificationLevel++;
+};
+
+// Invoke the notification handlers for a particular tiddler
+TiddlyWiki.prototype.notify = function(title,doBlanket)
+{
+	if(!this.notificationLevel) {
+		for(var t=0; t<this.namedNotifications.length; t++) {
+			var n = this.namedNotifications[t];
+			if((n.name == null && doBlanket) || (n.name == title))
+				n.notify(title);
+		}
+	}
+};
+
+// Invoke the notification handlers for all tiddlers
+TiddlyWiki.prototype.notifyAll = function()
+{
+	if(!this.notificationLevel) {
+		for(var t=0; t<this.namedNotifications.length; t++) {
+			var n = this.namedNotifications[t];
+			if(n.name)
+				n.notify(n.name);
+		}
+	}
+};
+
+// Add a notification handler to a tiddler
+TiddlyWiki.prototype.addNotification = function(title,fn)
+{
+	for(var i=0; i<this.namedNotifications.length; i++) {
+		if((this.namedNotifications[i].name == title) && (this.namedNotifications[i].notify == fn))
+			return this;
+	}
+	this.namedNotifications.push({name: title, notify: fn});
+	return this;
+};
+
+TiddlyWiki.prototype.removeTiddler = function(title)
+{
+	var tiddler = this.fetchTiddler(title);
+	if(tiddler) {
+		this.deleteTiddler(title);
+		this.notify(title,true);
+		this.setDirty(true);
+	}
+};
+
+// Reset the sync status of a freshly synced tiddler
+TiddlyWiki.prototype.resetTiddler = function(title)
+{
+	var tiddler = this.fetchTiddler(title);
+	if(tiddler) {
+		tiddler.clearChangeCount();
+		this.notify(title,true);
+		this.setDirty(true);
+	}
+};
+
+TiddlyWiki.prototype.setTiddlerTag = function(title,status,tag)
+{
+	var tiddler = this.fetchTiddler(title);
+	if(tiddler) {
+		var t = tiddler.tags.indexOf(tag);
+		if(t != -1)
+			tiddler.tags.splice(t,1);
+		if(status)
+			tiddler.tags.push(tag);
+		tiddler.changed();
+		tiddler.incChangeCount();
+		this.notify(title,true);
+		this.setDirty(true);
+	}
+};
+
+TiddlyWiki.prototype.addTiddlerFields = function(title,fields)
+{
+	var tiddler = this.fetchTiddler(title);
+	if(!tiddler)
+		return;
+	merge(tiddler.fields,fields);
+	tiddler.changed();
+	tiddler.incChangeCount();
+	this.notify(title,true);
+	this.setDirty(true);
+};
+
+// Store tiddler in TiddlyWiki instance
+TiddlyWiki.prototype.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created,creator)
+{
+	var tiddler = this.fetchTiddler(title);
+	if(tiddler) {
+		created = created || tiddler.created; // Preserve created date
+		creator = creator || tiddler.creator;
+		this.deleteTiddler(title);
+	} else {
+		created = created || modified;
+		tiddler = new Tiddler();
+	}
+	fields = merge({},fields);
+	tiddler.set(newTitle,newBody,modifier,modified,tags,created,fields,creator);
+	this.addTiddler(tiddler);
+	if(clearChangeCount)
+		tiddler.clearChangeCount();
+	else
+		tiddler.incChangeCount();
+	if(title != newTitle)
+		this.notify(title,true);
+	this.notify(newTitle,true);
+	this.setDirty(true);
+	return tiddler;
+};
+
+TiddlyWiki.prototype.incChangeCount = function(title)
+{
+	var tiddler = this.fetchTiddler(title);
+	if(tiddler)
+		tiddler.incChangeCount();
+};
+
+TiddlyWiki.prototype.getLoader = function()
+{
+	if(!this.loader)
+		this.loader = new TW21Loader();
+	return this.loader;
+};
+
+TiddlyWiki.prototype.getSaver = function()
+{
+	if(!this.saver)
+		this.saver = new TW21Saver();
+	return this.saver;
+};
+
+// Return all tiddlers formatted as an HTML string
+TiddlyWiki.prototype.allTiddlersAsHtml = function()
+{
+	return this.getSaver().externalize(store);
+};
+
+// Load contents of a TiddlyWiki from an HTML DIV
+TiddlyWiki.prototype.loadFromDiv = function(src,idPrefix,noUpdate)
+{
+	this.idPrefix = idPrefix;
+	var storeElem = (typeof src == "string") ? document.getElementById(src) : src;
+	if(!storeElem)
+		return;
+	var tiddlers = this.getLoader().loadTiddlers(this,storeElem.childNodes);
+	this.setDirty(false);
+	if(!noUpdate) {
+		for(var i = 0;i<tiddlers.length; i++)
+			tiddlers[i].changed();
+	}
+	jQuery().trigger("loadTiddlers");
+};
+
+// Load contents of a TiddlyWiki from a string
+// Returns null if there's an error
+TiddlyWiki.prototype.importTiddlyWiki = function(text)
+{
+	var posDiv = locateStoreArea(text);
+	if(!posDiv)
+		return null;
+	var content = "<" + "html><" + "body>" + text.substring(posDiv[0],posDiv[1] + endSaveArea.length) + "<" + "/body><" + "/html>";
+	// Create the iframe
+	var iframe = document.createElement("iframe");
+	iframe.style.display = "none";
+	document.body.appendChild(iframe);
+	var doc = iframe.document;
+	if(iframe.contentDocument)
+		doc = iframe.contentDocument; // For NS6
+	else if(iframe.contentWindow)
+		doc = iframe.contentWindow.document; // For IE5.5 and IE6
+	// Put the content in the iframe
+	doc.open();
+	doc.writeln(content);
+	doc.close();
+	// Load the content into a TiddlyWiki() object
+	var storeArea = doc.getElementById("storeArea");
+	this.loadFromDiv(storeArea,"store");
+	// Get rid of the iframe
+	iframe.parentNode.removeChild(iframe);
+	return this;
+};
+
+TiddlyWiki.prototype.updateTiddlers = function()
+{
+	this.tiddlersUpdated = true;
+	this.forEachTiddler(function(title,tiddler) {
+		tiddler.changed();
+	});
+};
+
+// Return an array of tiddlers matching a search regular expression
+TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag,match)
+{
+	var candidates = this.reverseLookup("tags",excludeTag,!!match);
+	var results = [];
+	for(var t=0; t<candidates.length; t++) {
+		if((candidates[t].title.search(searchRegExp) != -1) || (candidates[t].text.search(searchRegExp) != -1))
+			results.push(candidates[t]);
+	}
+	if(!sortField)
+		sortField = "title";
+	results.sort(function(a,b) {return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);});
+	return results;
+};
+
+// Returns a list of all tags in use
+//   excludeTag - if present, excludes tags that are themselves tagged with excludeTag
+// Returns an array of arrays where [tag][0] is the name of the tag and [tag][1] is the number of occurances
+TiddlyWiki.prototype.getTags = function(excludeTag)
+{
+	var results = [];
+	this.forEachTiddler(function(title,tiddler) {
+		for(var g=0; g<tiddler.tags.length; g++) {
+			var tag = tiddler.tags[g];
+			var n = true;
+			for(var c=0; c<results.length; c++) {
+				if(results[c][0] == tag) {
+					n = false;
+					results[c][1]++;
+				}
+			}
+			if(n && excludeTag) {
+				var t = this.fetchTiddler(tag);
+				if(t && t.isTagged(excludeTag))
+					n = false;
+			}
+			if(n)
+				results.push([tag,1]);
+		}
+	});
+	results.sort(function(a,b) {return a[0].toLowerCase() < b[0].toLowerCase() ? -1 : (a[0].toLowerCase() == b[0].toLowerCase() ? 0 : +1);});
+	return results;
+};
+
+// Return an array of the tiddlers that are tagged with a given tag
+TiddlyWiki.prototype.getTaggedTiddlers = function(tag,sortField)
+{
+	return this.reverseLookup("tags",tag,true,sortField);
+};
+
+// Return an array of the tiddlers that link to a given tiddler
+TiddlyWiki.prototype.getReferringTiddlers = function(title,unusedParameter,sortField)
+{
+	if(!this.tiddlersUpdated)
+		this.updateTiddlers();
+	return this.reverseLookup("links",title,true,sortField);
+};
+
+// Return an array of the tiddlers that do or do not have a specified entry in the specified storage array (ie, "links" or "tags")
+// lookupMatch == true to match tiddlers, false to exclude tiddlers
+TiddlyWiki.prototype.reverseLookup = function(lookupField,lookupValue,lookupMatch,sortField)
+{
+	var results = [];
+	this.forEachTiddler(function(title,tiddler) {
+		var f = !lookupMatch;
+		for(var lookup=0; lookup<tiddler[lookupField].length; lookup++) {
+			if(tiddler[lookupField][lookup] == lookupValue)
+				f = lookupMatch;
+		}
+		if(f)
+			results.push(tiddler);
+	});
+	if(!sortField)
+		sortField = "title";
+	results.sort(function(a,b) {return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);});
+	return results;
+};
+
+// Return the tiddlers as a sorted array
+TiddlyWiki.prototype.getTiddlers = function(field,excludeTag)
+{
+	var results = [];
+	this.forEachTiddler(function(title,tiddler) {
+		if(excludeTag == undefined || !tiddler.isTagged(excludeTag))
+			results.push(tiddler);
+	});
+	if(field)
+		results.sort(function(a,b) {return a[field] < b[field] ? -1 : (a[field] == b[field] ? 0 : +1);});
+	return results;
+};
+
+// Return array of names of tiddlers that are referred to but not defined
+TiddlyWiki.prototype.getMissingLinks = function(sortField)
+{
+	if(!this.tiddlersUpdated)
+		this.updateTiddlers();
+	var results = [];
+	this.forEachTiddler(function (title,tiddler) {
+		if(tiddler.isTagged("excludeMissing") || tiddler.isTagged("systemConfig"))
+			return;
+		for(var n=0; n<tiddler.links.length;n++) {
+			var link = tiddler.links[n];
+			if(this.fetchTiddler(link) == null && !this.isShadowTiddler(link))
+				results.pushUnique(link);
+		}
+	});
+	results.sort();
+	return results;
+};
+
+// Return an array of names of tiddlers that are defined but not referred to
+TiddlyWiki.prototype.getOrphans = function()
+{
+	var results = [];
+	this.forEachTiddler(function (title,tiddler) {
+		if(this.getReferringTiddlers(title).length == 0 && !tiddler.isTagged("excludeLists"))
+			results.push(title);
+	});
+	results.sort();
+	return results;
+};
+
+// Return an array of names of all the shadow tiddlers
+TiddlyWiki.prototype.getShadowed = function()
+{
+	var results = [];
+	for(var t in config.shadowTiddlers) {
+		if(this.isShadowTiddler(t))
+			results.push(t);
+	}
+	results.sort();
+	return results;
+};
+
+// Return an array of tiddlers that have been touched since they were downloaded or created
+TiddlyWiki.prototype.getTouched = function()
+{
+	var results = [];
+	this.forEachTiddler(function(title,tiddler) {
+		if(tiddler.isTouched())
+			results.push(tiddler);
+		});
+	results.sort();
+	return results;
+};
+
+// Resolves a Tiddler reference or tiddler title into a Tiddler object, or null if it doesn't exist
+TiddlyWiki.prototype.resolveTiddler = function(tiddler)
+{
+	var t = (typeof tiddler == "string") ? this.getTiddler(tiddler) : tiddler;
+	return t instanceof Tiddler ? t : null;
+};
+
+// Filter a list of tiddlers
+TiddlyWiki.prototype.filterTiddlers = function(filter)
+{
+	var results = [];
+	if(filter) {
+		var tiddler;
+		var re = /([^\s\[\]]+)|(?:\[([ \w]+)\[([^\]]+)\]\])|(?:\[\[([^\]]+)\]\])/mg;
+		var match = re.exec(filter);
+		while(match) {
+			if(match[1] || match[4]) {
+				var title = match[1] || match[4];
+				tiddler = this.fetchTiddler(title);
+				if(tiddler) {
+					results.pushUnique(tiddler);
+				} else if(this.isShadowTiddler(title)) {
+					tiddler = new Tiddler();
+					tiddler.set(title,this.getTiddlerText(title));
+					results.pushUnique(tiddler);
+				} else {
+					results.pushUnique(new Tiddler(title));
+				}
+			} else if(match[2]) {
+				switch(match[2]) {
+					case "tag":
+						var matched = this.getTaggedTiddlers(match[3]);
+						for(var m = 0; m < matched.length; m++)
+							results.pushUnique(matched[m]);
+						break;
+					case "sort":
+						results = this.sortTiddlers(results,match[3]);
+						break;
+				}
+			}
+			match = re.exec(filter);
+		}
+	}
+	return results;
+};
+
+// Sort a list of tiddlers
+TiddlyWiki.prototype.sortTiddlers = function(tiddlers,field)
+{
+	var asc = +1;
+	switch(field.substr(0,1)) {
+	case "-":
+		asc = -1;
+		// Note: this fall-through is intentional
+		/*jsl:fallthru*/
+	case "+":
+		field = field.substr(1);
+		break;
+	}
+	if(TiddlyWiki.standardFieldAccess[field])
+		tiddlers.sort(function(a,b) {return a[field] < b[field] ? -asc : (a[field] == b[field] ? 0 : asc);});
+	else
+		tiddlers.sort(function(a,b) {return a.fields[field] < b.fields[field] ? -asc : (a.fields[field] == b.fields[field] ? 0 : +asc);});
+	return tiddlers;
+};
+
+// Returns true if path is a valid field name (path),
+// i.e. a sequence of identifiers, separated by "."
+TiddlyWiki.isValidFieldName = function(name)
+{
+	var match = /[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)*/.exec(name);
+	return match && (match[0] == name);
+};
+
+// Throws an exception when name is not a valid field name.
+TiddlyWiki.checkFieldName = function(name)
+{
+	if(!TiddlyWiki.isValidFieldName(name))
+		throw config.messages.invalidFieldName.format([name]);
+};
+
+function StringFieldAccess(n,readOnly)
+{
+	this.set = readOnly ?
+			function(t,v) {if(v != t[n]) throw config.messages.fieldCannotBeChanged.format([n]);} :
+			function(t,v) {if(v != t[n]) {t[n] = v; return true;}};
+	this.get = function(t) {return t[n];};
+}
+
+function DateFieldAccess(n)
+{
+	this.set = function(t,v) {
+		var d = v instanceof Date ? v : Date.convertFromYYYYMMDDHHMM(v);
+		if(d != t[n]) {
+			t[n] = d; return true;
+		}
+	};
+	this.get = function(t) {return t[n].convertToYYYYMMDDHHMM();};
+}
+
+function LinksFieldAccess(n)
+{
+	this.set = function(t,v) {
+		var s = (typeof v == "string") ? v.readBracketedList() : v;
+		if(s.toString() != t[n].toString()) {
+			t[n] = s; return true;
+		}
+	};
+	this.get = function(t) {return String.encodeTiddlyLinkList(t[n]);};
+}
+
+TiddlyWiki.standardFieldAccess = {
+	// The set functions return true when setting the data has changed the value.
+	"title":    new StringFieldAccess("title",true),
+	// Handle the "tiddler" field name as the title
+	"tiddler":  new StringFieldAccess("title",true),
+	"text":     new StringFieldAccess("text"),
+	"modifier": new StringFieldAccess("modifier"),
+	"modified": new DateFieldAccess("modified"),
+	"creator":  new StringFieldAccess("creator"),
+	"created":  new DateFieldAccess("created"),
+	"tags":     new LinksFieldAccess("tags")
+};
+
+TiddlyWiki.isStandardField = function(name)
+{
+	return TiddlyWiki.standardFieldAccess[name] != undefined;
+};
+
+// Sets the value of the given field of the tiddler to the value.
+// Setting an ExtendedField's value to null or undefined removes the field.
+// Setting a namespace to undefined removes all fields of that namespace.
+// The fieldName is case-insensitive.
+// All values will be converted to a string value.
+TiddlyWiki.prototype.setValue = function(tiddler,fieldName,value)
+{
+	TiddlyWiki.checkFieldName(fieldName);
+	var t = this.resolveTiddler(tiddler);
+	if(!t)
+		return;
+	fieldName = fieldName.toLowerCase();
+	var isRemove = (value === undefined) || (value === null);
+	var accessor = TiddlyWiki.standardFieldAccess[fieldName];
+	if(accessor) {
+		if(isRemove)
+			// don't remove StandardFields
+			return;
+		var h = TiddlyWiki.standardFieldAccess[fieldName];
+		if(!h.set(t,value))
+			return;
+	} else {
+		var oldValue = t.fields[fieldName];
+		if(isRemove) {
+			if(oldValue !== undefined) {
+				// deletes a single field
+				delete t.fields[fieldName];
+			} else {
+				// no concrete value is defined for the fieldName
+				// so we guess this is a namespace path.
+				// delete all fields in a namespace
+				var re = new RegExp("^"+fieldName+"\\.");
+				var dirty = false;
+				for(var n in t.fields) {
+					if(n.match(re)) {
+						delete t.fields[n];
+						dirty = true;
+					}
+				}
+				if(!dirty)
+					return;
+			}
+		} else {
+			// the "normal" set case. value is defined (not null/undefined)
+			// For convenience provide a nicer conversion Date->String
+			value = value instanceof Date ? value.convertToYYYYMMDDHHMMSSMMM() : String(value);
+			if(oldValue == value)
+				return;
+			t.fields[fieldName] = value;
+		}
+	}
+	// When we are here the tiddler/store really was changed.
+	this.notify(t.title,true);
+	if(!fieldName.match(/^temp\./))
+		this.setDirty(true);
+};
+
+// Returns the value of the given field of the tiddler.
+// The fieldName is case-insensitive.
+// Will only return String values (or undefined).
+TiddlyWiki.prototype.getValue = function(tiddler,fieldName)
+{
+	var t = this.resolveTiddler(tiddler);
+	if(!t)
+		return undefined;
+	fieldName = fieldName.toLowerCase();
+	var accessor = TiddlyWiki.standardFieldAccess[fieldName];
+	if(accessor) {
+		return accessor.get(t);
+	}
+	return t.fields[fieldName];
+};
+
+// Calls the callback function for every field in the tiddler.
+// When callback function returns a non-false value the iteration stops
+// and that value is returned.
+// The order of the fields is not defined.
+// @param callback a function(tiddler,fieldName,value).
+TiddlyWiki.prototype.forEachField = function(tiddler,callback,onlyExtendedFields)
+{
+	var t = this.resolveTiddler(tiddler);
+	if(!t)
+		return undefined;
+	var n,result;
+	for(n in t.fields) {
+		result = callback(t,n,t.fields[n]);
+		if(result)
+			return result;
+		}
+	if(onlyExtendedFields)
+		return undefined;
+	for(n in TiddlyWiki.standardFieldAccess) {
+		if(n == "tiddler")
+			// even though the "title" field can also be referenced through the name "tiddler"
+			// we only visit this field once.
+			continue;
+		result = callback(t,n,TiddlyWiki.standardFieldAccess[n].get(t));
+		if(result)
+			return result;
+	}
+	return undefined;
+};
+
+//--
+//-- Story functions
+//--
+
+function Story(containerId,idPrefix)
+{
+	this.container = containerId;
+	this.idPrefix = idPrefix;
+	this.highlightRegExp = null;
+	this.tiddlerId = function(title) {
+		var id = this.idPrefix + title;
+		return id==this.container ? this.idPrefix + "_" + title : id;
+	};
+	this.containerId = function() {
+		return this.container;
+	};
+}
+
+Story.prototype.getTiddler = function(title)
+{
+	return document.getElementById(this.tiddlerId(title));
+};
+
+Story.prototype.getContainer = function()
+{
+	return document.getElementById(this.containerId());
+};
+
+Story.prototype.forEachTiddler = function(fn)
+{
+	var place = this.getContainer();
+	if(!place)
+		return;
+	var e = place.firstChild;
+	while(e) {
+		var n = e.nextSibling;
+		var title = e.getAttribute("tiddler");
+		fn.call(this,title,e);
+		e = n;
+	}
+};
+
+Story.prototype.displayDefaultTiddlers = function()
+{
+	this.displayTiddlers(null,store.filterTiddlers(store.getTiddlerText("DefaultTiddlers")));
+};
+
+Story.prototype.displayTiddlers = function(srcElement,titles,template,animate,unused,customFields,toggle)
+{
+	for(var t = titles.length-1;t>=0;t--)
+		this.displayTiddler(srcElement,titles[t],template,animate,unused,customFields);
+};
+
+Story.prototype.displayTiddler = function(srcElement,tiddler,template,animate,unused,customFields,toggle,animationSrc)
+{
+	var title = (tiddler instanceof Tiddler) ? tiddler.title : tiddler;
+	var tiddlerElem = this.getTiddler(title);
+	if(tiddlerElem) {
+		if(toggle)
+			this.closeTiddler(title,true);
+		else
+			this.refreshTiddler(title,template,false,customFields);
+	} else {
+		var place = this.getContainer();
+		var before = this.positionTiddler(srcElement);
+		tiddlerElem = this.createTiddler(place,before,title,template,customFields);
+	}
+	if(animationSrc && typeof animationSrc !== "string") {
+		srcElement = animationSrc;
+	}
+	if(srcElement && typeof srcElement !== "string") {
+		if(config.options.chkAnimate && (animate == undefined || animate == true) && anim && typeof Zoomer == "function" && typeof Scroller == "function")
+			anim.startAnimating(new Zoomer(title,srcElement,tiddlerElem),new Scroller(tiddlerElem));
+		else
+			window.scrollTo(0,ensureVisible(tiddlerElem));
+	}
+	return tiddlerElem;
+};
+
+Story.prototype.positionTiddler = function(srcElement)
+{
+	var place = this.getContainer();
+	var before = null;
+	if(typeof srcElement == "string") {
+		switch(srcElement) {
+		case "top":
+			before = place.firstChild;
+			break;
+		case "bottom":
+			before = null;
+			break;
+		}
+	} else {
+		var after = this.findContainingTiddler(srcElement);
+		if(after == null) {
+			before = place.firstChild;
+		} else if(after.nextSibling) {
+			before = after.nextSibling;
+			if(before.nodeType != 1)
+				before = null;
+		}
+	}
+	return before;
+};
+
+Story.prototype.createTiddler = function(place,before,title,template,customFields)
+{
+	var tiddlerElem = createTiddlyElement(null,"div",this.tiddlerId(title),"tiddler");
+	tiddlerElem.setAttribute("refresh","tiddler");
+	if(customFields)
+		tiddlerElem.setAttribute("tiddlyFields",customFields);
+	place.insertBefore(tiddlerElem,before);
+	var defaultText = null;
+	if(!store.tiddlerExists(title) && !store.isShadowTiddler(title))
+		defaultText = this.loadMissingTiddler(title,customFields,tiddlerElem);
+	this.refreshTiddler(title,template,false,customFields,defaultText);
+	return tiddlerElem;
+};
+
+Story.prototype.loadMissingTiddler = function(title,fields,tiddlerElem)
+{
+	var getTiddlerCallback = function(context)
+	{
+		if(context.status) {
+			var t = context.tiddler;
+			if(!t.created)
+				t.created = new Date();
+			if(!t.modified)
+				t.modified = t.created;
+			store.saveTiddler(t.title,t.title,t.text,t.modifier,t.modified,t.tags,t.fields,true,t.created,t.creator);
+			autoSaveChanges();
+		} else {
+			story.refreshTiddler(context.title,null,true);
+		}
+		context.adaptor.close();
+		delete context.adaptor;
+	};
+	var tiddler = new Tiddler(title);
+	tiddler.fields = typeof fields == "string" ? fields.decodeHashMap() : fields||{};
+	var context = {serverType:tiddler.getServerType()};
+	if(!context.serverType)
+		return;
+	context.host = tiddler.fields['server.host'];
+	context.workspace = tiddler.fields['server.workspace'];
+	var adaptor = new config.adaptors[context.serverType];
+	adaptor.getTiddler(title,context,null,getTiddlerCallback);
+	return config.messages.loadingMissingTiddler.format([title,context.serverType,context.host,context.workspace]);
+};
+
+Story.prototype.chooseTemplateForTiddler = function(title,template)
+{
+	if(!template)
+		template = DEFAULT_VIEW_TEMPLATE;
+	if(template == DEFAULT_VIEW_TEMPLATE || template == DEFAULT_EDIT_TEMPLATE)
+		template = config.tiddlerTemplates[template];
+	return template;
+};
+
+Story.prototype.getTemplateForTiddler = function(title,template,tiddler)
+{
+	return store.getRecursiveTiddlerText(template,null,10);
+};
+
+Story.prototype.refreshTiddler = function(title,template,force,customFields,defaultText)
+{
+	var tiddlerElem = this.getTiddler(title);
+	if(tiddlerElem) {
+		if(tiddlerElem.getAttribute("dirty") == "true" && !force)
+			return tiddlerElem;
+		template = this.chooseTemplateForTiddler(title,template);
+		var currTemplate = tiddlerElem.getAttribute("template");
+		if((template != currTemplate) || force) {
+			var tiddler = store.getTiddler(title);
+			if(!tiddler) {
+				tiddler = new Tiddler();
+				if(store.isShadowTiddler(title)) {
+					var tags = [];
+					tiddler.set(title,store.getTiddlerText(title),config.views.wikified.shadowModifier,version.date,tags,version.date);
+				} else {
+					var text = template=="EditTemplate" ?
+								config.views.editor.defaultText.format([title]) :
+								config.views.wikified.defaultText.format([title]);
+					text = defaultText || text;
+					var fields = customFields ? customFields.decodeHashMap() : null;
+					tiddler.set(title,text,config.views.wikified.defaultModifier,version.date,[],version.date,fields);
+				}
+			}
+			tiddlerElem.setAttribute("tags",tiddler.tags.join(" "));
+			tiddlerElem.setAttribute("tiddler",title);
+			tiddlerElem.setAttribute("template",template);
+			tiddlerElem.onmouseover = this.onTiddlerMouseOver;
+			tiddlerElem.onmouseout = this.onTiddlerMouseOut;
+			tiddlerElem.ondblclick = this.onTiddlerDblClick;
+			tiddlerElem[window.event?"onkeydown":"onkeypress"] = this.onTiddlerKeyPress;
+			tiddlerElem.innerHTML = this.getTemplateForTiddler(title,template,tiddler);
+			applyHtmlMacros(tiddlerElem,tiddler);
+			if(store.getTaggedTiddlers(title).length > 0)
+				addClass(tiddlerElem,"isTag");
+			else
+				removeClass(tiddlerElem,"isTag");
+			if(store.tiddlerExists(title)) {
+				removeClass(tiddlerElem,"shadow");
+				removeClass(tiddlerElem,"missing");
+			} else {
+				addClass(tiddlerElem, store.isShadowTiddler(title) ? "shadow" : "missing");
+			}
+			if(customFields)
+				this.addCustomFields(tiddlerElem,customFields);
+			forceReflow();
+		}
+	}
+	return tiddlerElem;
+};
+
+Story.prototype.addCustomFields = function(place,customFields)
+{
+	var fields = customFields.decodeHashMap();
+	var w = createTiddlyElement(place,"div",null,"customFields");
+	w.style.display = "none";
+	for(var t in fields) {
+		var e = document.createElement("input");
+		e.setAttribute("type","text");
+		e.setAttribute("value",fields[t]);
+		w.appendChild(e);
+		e.setAttribute("edit",t);
+	}
+};
+
+Story.prototype.refreshAllTiddlers = function(force)
+{
+	var e = this.getContainer().firstChild;
+	while(e) {
+		var template = e.getAttribute("template");
+		if(template && e.getAttribute("dirty") != "true") {
+			this.refreshTiddler(e.getAttribute("tiddler"),force ? null : template,true);
+		}
+		e = e.nextSibling;
+	}
+};
+
+Story.prototype.onTiddlerMouseOver = function(e)
+{
+	addClass(this, "selected");
+};
+
+Story.prototype.onTiddlerMouseOut = function(e)
+{
+	removeClass(this,"selected");
+};
+
+Story.prototype.onTiddlerDblClick = function(ev)
+{
+	var e = ev || window.event;
+	var target = resolveTarget(e);
+	if(target && target.nodeName.toLowerCase() != "input" && target.nodeName.toLowerCase() != "textarea") {
+		if(document.selection && document.selection.empty)
+			document.selection.empty();
+		config.macros.toolbar.invokeCommand(this,"defaultCommand",e);
+		e.cancelBubble = true;
+		if(e.stopPropagation) e.stopPropagation();
+		return true;
+	}
+	return false;
+};
+
+Story.prototype.onTiddlerKeyPress = function(ev)
+{
+	var e = ev || window.event;
+	clearMessage();
+	var consume = false;
+	var title = this.getAttribute("tiddler");
+	var target = resolveTarget(e);
+	switch(e.keyCode) {
+	case 9: // Tab
+		if(config.options.chkInsertTabs && target.tagName.toLowerCase() == "textarea") {
+			replaceSelection(target,String.fromCharCode(9));
+			consume = true;
+		}
+		if(config.isOpera) {
+			target.onblur = function() {
+				this.focus();
+				this.onblur = null;
+			};
+		}
+		break;
+	case 13: // Ctrl-Enter
+	case 10: // Ctrl-Enter on IE PC
+	case 77: // Ctrl-Enter is "M" on some platforms
+		if(e.ctrlKey) {
+			blurElement(this);
+			config.macros.toolbar.invokeCommand(this,"defaultCommand",e);
+			consume = true;
+		}
+		break;
+	case 27: // Escape
+		blurElement(this);
+		config.macros.toolbar.invokeCommand(this,"cancelCommand",e);
+		consume = true;
+		break;
+	}
+	e.cancelBubble = consume;
+	if(consume) {
+		if(e.stopPropagation) e.stopPropagation(); // Stop Propagation
+		e.returnValue = true; // Cancel The Event in IE
+		if(e.preventDefault ) e.preventDefault(); // Cancel The Event in Moz
+	}
+	return !consume;
+};
+
+Story.prototype.getTiddlerField = function(title,field)
+{
+	var tiddlerElem = this.getTiddler(title);
+	var e = null;
+	if(tiddlerElem ) {
+		var children = tiddlerElem.getElementsByTagName("*");
+		for(var t=0; t<children.length; t++) {
+			var c = children[t];
+			if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea") {
+				if(!e)
+					e = c;
+				if(c.getAttribute("edit") == field)
+					e = c;
+			}
+		}
+	}
+	return e;
+};
+
+Story.prototype.focusTiddler = function(title,field)
+{
+	var e = this.getTiddlerField(title,field);
+	if(e) {
+		e.focus();
+		e.select();
+	}
+};
+
+Story.prototype.blurTiddler = function(title)
+{
+	var tiddlerElem = this.getTiddler(title);
+	if(tiddlerElem && tiddlerElem.focus && tiddlerElem.blur) {
+		tiddlerElem.focus();
+		tiddlerElem.blur();
+	}
+};
+
+Story.prototype.setTiddlerField = function(title,tag,mode,field)
+{
+	var c = this.getTiddlerField(title,field);
+	var tags = c.value.readBracketedList();
+	tags.setItem(tag,mode);
+	c.value = String.encodeTiddlyLinkList(tags);
+};
+
+Story.prototype.setTiddlerTag = function(title,tag,mode)
+{
+	this.setTiddlerField(title,tag,mode,"tags");
+};
+
+Story.prototype.closeTiddler = function(title,animate,unused)
+{
+	var tiddlerElem = this.getTiddler(title);
+	if(tiddlerElem) {
+		clearMessage();
+		this.scrubTiddler(tiddlerElem);
+		if(config.options.chkAnimate && animate && anim && typeof Slider == "function")
+			anim.startAnimating(new Slider(tiddlerElem,false,null,"all"));
+		else {
+			removeNode(tiddlerElem);
+			forceReflow();
+		}
+	}
+};
+
+Story.prototype.scrubTiddler = function(tiddlerElem)
+{
+	tiddlerElem.id = null;
+};
+
+Story.prototype.setDirty = function(title,dirty)
+{
+	var tiddlerElem = this.getTiddler(title);
+	if(tiddlerElem)
+		tiddlerElem.setAttribute("dirty",dirty ? "true" : "false");
+};
+
+Story.prototype.isDirty = function(title)
+{
+	var tiddlerElem = this.getTiddler(title);
+	if(tiddlerElem)
+		return tiddlerElem.getAttribute("dirty") == "true";
+	return null;
+};
+
+Story.prototype.areAnyDirty = function()
+{
+	var r = false;
+	this.forEachTiddler(function(title,element) {
+		if(this.isDirty(title))
+			r = true;
+	});
+	return r;
+};
+
+Story.prototype.closeAllTiddlers = function(exclude)
+{
+	clearMessage();
+	this.forEachTiddler(function(title,element) {
+		if((title != exclude) && element.getAttribute("dirty") != "true")
+			this.closeTiddler(title);
+	});
+	window.scrollTo(0,ensureVisible(this.container));
+};
+
+Story.prototype.isEmpty = function()
+{
+	var place = this.getContainer();
+	return place && place.firstChild == null;
+};
+
+Story.prototype.search = function(text,useCaseSensitive,useRegExp)
+{
+	this.closeAllTiddlers();
+	highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(),useCaseSensitive ? "mg" : "img");
+	var matches = store.search(highlightHack,"title","excludeSearch");
+	this.displayTiddlers(null,matches);
+	highlightHack = null;
+	var q = useRegExp ? "/" : "'";
+	if(matches.length > 0)
+		displayMessage(config.macros.search.successMsg.format([matches.length.toString(),q + text + q]));
+	else
+		displayMessage(config.macros.search.failureMsg.format([q + text + q]));
+};
+
+Story.prototype.findContainingTiddler = function(e)
+{
+	while(e && !hasClass(e,"tiddler"))
+		e = hasClass(e,"popup") ? Popup.stack[0].root : e.parentNode;
+	return e;
+};
+
+Story.prototype.gatherSaveFields = function(e,fields)
+{
+	if(e && e.getAttribute) {
+		var f = e.getAttribute("edit");
+		if(f)
+			fields[f] = e.value.replace(/\r/mg,"");
+		if(e.hasChildNodes()) {
+			var c = e.childNodes;
+			for(var t=0; t<c.length; t++)
+				this.gatherSaveFields(c[t],fields);
+		}
+	}
+};
+
+Story.prototype.hasChanges = function(title)
+{
+	var e = this.getTiddler(title);
+	if(e) {
+		var fields = {};
+		this.gatherSaveFields(e,fields);
+		if(store.fetchTiddler(title)) {
+			for(var n in fields) {
+				if(store.getValue(title,n) != fields[n]) //# tiddler changed
+					return true;
+			}
+		} else {
+			if(store.isShadowTiddler(title) && store.getShadowTiddlerText(title) == fields.text) { //# not checking for title or tags
+				return false;
+			} else { //# changed shadow or new tiddler
+				return true;
+			}
+		}
+	}
+	return false;
+};
+
+Story.prototype.saveTiddler = function(title,minorUpdate)
+{
+	var tiddlerElem = this.getTiddler(title);
+	if(tiddlerElem) {
+		var fields = {};
+		this.gatherSaveFields(tiddlerElem,fields);
+		var newTitle = fields.title || title;
+		if(!store.tiddlerExists(newTitle)) {
+			newTitle = newTitle.trim();
+			var creator = config.options.txtUserName;
+		}
+		if(store.tiddlerExists(newTitle) && newTitle != title) {
+			if(!confirm(config.messages.overwriteWarning.format([newTitle.toString()])))
+				return null;
+		}
+		if(newTitle != title)
+			this.closeTiddler(newTitle,false);
+		tiddlerElem.id = this.tiddlerId(newTitle);
+		tiddlerElem.setAttribute("tiddler",newTitle);
+		tiddlerElem.setAttribute("template",DEFAULT_VIEW_TEMPLATE);
+		tiddlerElem.setAttribute("dirty","false");
+		if(config.options.chkForceMinorUpdate)
+			minorUpdate = !minorUpdate;
+		if(!store.tiddlerExists(newTitle))
+			minorUpdate = false;
+		var newDate = new Date();
+		if(store.tiddlerExists(title)) {
+			var t = store.fetchTiddler(title);
+			var extendedFields = t.fields;
+			creator = t.creator;
+		} else {
+			extendedFields = merge({},config.defaultCustomFields);
+		}
+		for(var n in fields) {
+			if(!TiddlyWiki.isStandardField(n))
+				extendedFields[n] = fields[n];
+		}
+		var tiddler = store.saveTiddler(title,newTitle,fields.text,minorUpdate ? undefined : config.options.txtUserName,minorUpdate ? undefined : newDate,fields.tags,extendedFields,null,null,creator);
+		autoSaveChanges(null,[tiddler]);
+		return newTitle;
+	}
+	return null;
+};
+
+Story.prototype.permaView = function()
+{
+	var links = [];
+	this.forEachTiddler(function(title,element) {
+		links.push(String.encodeTiddlyLink(title));
+	});
+	var t = encodeURIComponent(links.join(" "));
+	if(t == "")
+		t = "#";
+	if(window.location.hash != t)
+		window.location.hash = t;
+};
+
+Story.prototype.switchTheme = function(theme)
+{
+	if(safeMode)
+		return;
+
+	var isAvailable = function(title) {
+		var s = title ? title.indexOf(config.textPrimitives.sectionSeparator) : -1;
+		if(s!=-1)
+			title = title.substr(0,s);
+		return store.tiddlerExists(title) || store.isShadowTiddler(title);
+	};
+
+	var getSlice = function(theme,slice) {
+		var r;
+		if(readOnly)
+			r = store.getTiddlerSlice(theme,slice+"ReadOnly") || store.getTiddlerSlice(theme,"Web"+slice);
+		r = r || store.getTiddlerSlice(theme,slice);
+		if(r && r.indexOf(config.textPrimitives.sectionSeparator)==0)
+			r = theme + r;
+		return isAvailable(r) ? r : slice;
+	};
+
+	var replaceNotification = function(i,name,theme,slice) {
+		var newName = getSlice(theme,slice);
+		if(name!=newName && store.namedNotifications[i].name==name) {
+			store.namedNotifications[i].name = newName;
+			return newName;
+		}
+		return name;
+	};
+
+	var pt = config.refresherData.pageTemplate;
+	var vi = DEFAULT_VIEW_TEMPLATE;
+	var vt = config.tiddlerTemplates[vi];
+	var ei = DEFAULT_EDIT_TEMPLATE;
+	var et = config.tiddlerTemplates[ei];
+
+	for(var i=0; i<config.notifyTiddlers.length; i++) {
+		var name = config.notifyTiddlers[i].name;
+		switch(name) {
+		case "PageTemplate":
+			config.refresherData.pageTemplate = replaceNotification(i,config.refresherData.pageTemplate,theme,name);
+			break;
+		case "StyleSheet":
+			removeStyleSheet(config.refresherData.styleSheet);
+			config.refresherData.styleSheet = replaceNotification(i,config.refresherData.styleSheet,theme,name);
+			break;
+		case "ColorPalette":
+			config.refresherData.colorPalette = replaceNotification(i,config.refresherData.colorPalette,theme,name);
+			break;
+		default:
+			break;
+		}
+	}
+	config.tiddlerTemplates[vi] = getSlice(theme,"ViewTemplate");
+	config.tiddlerTemplates[ei] = getSlice(theme,"EditTemplate");
+	if(!startingUp) {
+		if(config.refresherData.pageTemplate!=pt || config.tiddlerTemplates[vi]!=vt || config.tiddlerTemplates[ei]!=et) {
+			refreshAll();
+			this.refreshAllTiddlers(true);
+		} else {
+			setStylesheet(store.getRecursiveTiddlerText(config.refresherData.styleSheet,"",10),config.refreshers.styleSheet);
+		}
+		config.options.txtTheme = theme;
+		saveOptionCookie("txtTheme");
+	}
+};
+
+//--
+//-- Backstage
+//--
+
+var backstage = {
+	area: null,
+	toolbar: null,
+	button: null,
+	showButton: null,
+	hideButton: null,
+	cloak: null,
+	panel: null,
+	panelBody: null,
+	panelFooter: null,
+	currTabName: null,
+	currTabElem: null,
+	content: null,
+
+	init: function() {
+		var cmb = config.messages.backstage;
+		this.area = document.getElementById("backstageArea");
+		this.toolbar = document.getElementById("backstageToolbar");
+		this.button = document.getElementById("backstageButton");
+		this.button.style.display = "block";
+		var t = cmb.open.text + " " + glyph("bentArrowLeft");
+		this.showButton = createTiddlyButton(this.button,t,cmb.open.tooltip,
+						function(e) {backstage.show(); return false;},null,"backstageShow");
+		t = glyph("bentArrowRight") + " " + cmb.close.text;
+		this.hideButton = createTiddlyButton(this.button,t,cmb.close.tooltip,
+						function(e) {backstage.hide(); return false;},null,"backstageHide");
+		this.cloak = document.getElementById("backstageCloak");
+		this.panel = document.getElementById("backstagePanel");
+		this.panelFooter = createTiddlyElement(this.panel,"div",null,"backstagePanelFooter");
+		this.panelBody = createTiddlyElement(this.panel,"div",null,"backstagePanelBody");
+		this.cloak.onmousedown = function(e) {backstage.switchTab(null);};
+		createTiddlyText(this.toolbar,cmb.prompt);
+		for(t=0; t<config.backstageTasks.length; t++) {
+			var taskName = config.backstageTasks[t];
+			var task = config.tasks[taskName];
+			var handler = task.action ? this.onClickCommand : this.onClickTab;
+			var text = task.text + (task.action ? "" : glyph("downTriangle"));
+			var btn = createTiddlyButton(this.toolbar,text,task.tooltip,handler,"backstageTab");
+			addClass(btn,task.action ? "backstageAction" : "backstageTask");
+			btn.setAttribute("task", taskName);
+			}
+		this.content = document.getElementById("contentWrapper");
+		if(config.options.chkBackstage)
+			this.show();
+		else
+			this.hide();
+	},
+
+	isVisible: function() {
+		return this.area ? this.area.style.display == "block" : false;
+	},
+
+	show: function() {
+		this.area.style.display = "block";
+		if(anim && config.options.chkAnimate) {
+			backstage.toolbar.style.left = findWindowWidth() + "px";
+			var p = [{style: "left", start: findWindowWidth(), end: 0, template: "%0px"}];
+			anim.startAnimating(new Morpher(backstage.toolbar,config.animDuration,p));
+		} else {
+			backstage.area.style.left = "0px";
+		}
+		jQuery(this.showButton).hide();
+		jQuery(this.hideButton).show();
+		config.options.chkBackstage = true;
+		saveOptionCookie("chkBackstage");
+		addClass(this.content,"backstageVisible");
+	},
+
+	hide: function() {
+		if(this.currTabElem) {
+			this.switchTab(null);
+		} else {
+			backstage.toolbar.style.left = "0px";
+			if(anim && config.options.chkAnimate) {
+				var p = [{style: "left", start: 0, end: findWindowWidth(), template: "%0px"}];
+				var c = function(element,properties) {backstage.area.style.display = "none";};
+				anim.startAnimating(new Morpher(backstage.toolbar,config.animDuration,p,c));
+			} else {
+				this.area.style.display = "none";
+			}
+			this.showButton.style.display = "block";
+			this.hideButton.style.display = "none";
+			config.options.chkBackstage = false;
+			saveOptionCookie("chkBackstage");
+			removeClass(this.content, "backstageVisible");
+		}
+	},
+
+	onClickCommand: function(e) {
+		var task = config.tasks[this.getAttribute("task")];
+		if(task.action) {
+			backstage.switchTab(null);
+			task.action();
+		}
+		return false;
+	},
+
+	onClickTab: function(e) {
+		backstage.switchTab(this.getAttribute("task"));
+		return false;
+	},
+
+	// Switch to a given tab, or none if null is passed
+	switchTab: function(tabName) {
+		var tabElem = null;
+		var e = this.toolbar.firstChild;
+		while(e)
+			{
+			if(e.getAttribute && e.getAttribute("task") == tabName)
+				tabElem = e;
+			e = e.nextSibling;
+			}
+		if(tabName == backstage.currTabName) {
+			backstage.hidePanel();
+			return;
+		}
+		if(backstage.currTabElem) {
+			removeClass(this.currTabElem, "backstageSelTab");
+		}
+		if(tabElem && tabName) {
+			backstage.preparePanel();
+			addClass(tabElem,"backstageSelTab");
+			var task = config.tasks[tabName];
+			wikify(task.content,backstage.panelBody,null,null);
+			backstage.showPanel();
+		} else if(backstage.currTabElem) {
+			backstage.hidePanel();
+		}
+		backstage.currTabName = tabName;
+		backstage.currTabElem = tabElem;
+	},
+
+	isPanelVisible: function() {
+		return backstage.panel ? backstage.panel.style.display == "block" : false;
+	},
+
+	preparePanel: function() {
+		backstage.cloak.style.height = findWindowHeight() + "px";
+		backstage.cloak.style.display = "block";
+		removeChildren(backstage.panelBody);
+		return backstage.panelBody;
+	},
+
+	showPanel: function() {
+		backstage.panel.style.display = "block";
+		if(anim && config.options.chkAnimate) {
+			backstage.panel.style.top = (-backstage.panel.offsetHeight) + "px";
+			var p = [{style: "top", start: -backstage.panel.offsetHeight, end: 0, template: "%0px"}];
+			anim.startAnimating(new Morpher(backstage.panel,config.animDuration,p),new Scroller(backstage.panel,false));
+		} else {
+			backstage.panel.style.top = "0px";
+		}
+		return backstage.panelBody;
+	},
+
+	hidePanel: function() {
+		if(backstage.currTabElem)
+			removeClass(backstage.currTabElem, "backstageSelTab");
+		backstage.currTabElem = null;
+		backstage.currTabName = null;
+		if(anim && config.options.chkAnimate) {
+			var p = [
+				{style: "top", start: 0, end: -(backstage.panel.offsetHeight), template: "%0px"},
+				{style: "display", atEnd: "none"}
+			];
+			var c = function(element,properties) {backstage.cloak.style.display = "none";};
+			anim.startAnimating(new Morpher(backstage.panel,config.animDuration,p,c));
+		} else {
+			jQuery([backstage.panel,backstage.cloak]).hide();
+		}
+	}
+};
+
+config.macros.backstage = {};
+
+config.macros.backstage.handler = function(place,macroName,params)
+{
+	var backstageTask = config.tasks[params[0]];
+	if(backstageTask)
+		createTiddlyButton(place,backstageTask.text,backstageTask.tooltip,function(e) {backstage.switchTab(params[0]); return false;});
+};
+
+//--
+//-- ImportTiddlers macro
+//--
+
+config.macros.importTiddlers.handler = function(place,macroName,params,wikifier,paramString,tiddler)
+{
+	if(readOnly) {
+		createTiddlyElement(place,"div",null,"marked",this.readOnlyWarning);
+		return;
+	}
+	var w = new Wizard();
+	w.createWizard(place,this.wizardTitle);
+	this.restart(w);
+};
+
+config.macros.importTiddlers.onCancel = function(e)
+{
+	var wizard = new Wizard(this);
+	var place = wizard.clear();
+	config.macros.importTiddlers.restart(wizard);
+	return false;
+};
+
+config.macros.importTiddlers.onClose = function(e)
+{
+	backstage.hidePanel();
+	return false;
+};
+
+config.macros.importTiddlers.restart = function(wizard)
+{
+	wizard.addStep(this.step1Title,this.step1Html);
+	var s = wizard.getElement("selTypes");
+	for(var t in config.adaptors) {
+		var e = createTiddlyElement(s,"option",null,null,config.adaptors[t].serverLabel ? config.adaptors[t].serverLabel : t);
+		e.value = t;
+	}
+	if(config.defaultAdaptor)
+		s.value = config.defaultAdaptor;
+	s = wizard.getElement("selFeeds");
+	var feeds = this.getFeeds();
+	for(t in feeds) {
+		e = createTiddlyElement(s,"option",null,null,t);
+		e.value = t;
+	}
+	wizard.setValue("feeds",feeds);
+	s.onchange = config.macros.importTiddlers.onFeedChange;
+	var fileInput = wizard.getElement("txtBrowse");
+	fileInput.onchange = config.macros.importTiddlers.onBrowseChange;
+	fileInput.onkeyup = config.macros.importTiddlers.onBrowseChange;
+	wizard.setButtons([{caption: this.openLabel, tooltip: this.openPrompt, onClick: config.macros.importTiddlers.onOpen}]);
+	wizard.formElem.action = "javascript:;";
+	wizard.formElem.onsubmit = function() {
+		if(!this.txtPath || this.txtPath.value.length) //# check for manually entered path in first step
+			this.lastChild.firstChild.onclick();
+	};
+};
+
+config.macros.importTiddlers.getFeeds = function()
+{
+	var feeds = {};
+	var tagged = store.getTaggedTiddlers("systemServer","title");
+	for(var t=0; t<tagged.length; t++) {
+		var title = tagged[t].title;
+		var serverType = store.getTiddlerSlice(title,"Type");
+		if(!serverType)
+			serverType = "file";
+		feeds[title] = {title: title,
+						url: store.getTiddlerSlice(title,"URL"),
+						workspace: store.getTiddlerSlice(title,"Workspace"),
+						workspaceList: store.getTiddlerSlice(title,"WorkspaceList"),
+						tiddlerFilter: store.getTiddlerSlice(title,"TiddlerFilter"),
+						serverType: serverType,
+						description: store.getTiddlerSlice(title,"Description")};
+	}
+	return feeds;
+};
+
+config.macros.importTiddlers.onFeedChange = function(e)
+{
+	var wizard = new Wizard(this);
+	var selTypes = wizard.getElement("selTypes");
+	var fileInput = wizard.getElement("txtPath");
+	var feeds = wizard.getValue("feeds");
+	var f = feeds[this.value];
+	if(f) {
+		selTypes.value = f.serverType;
+		fileInput.value = f.url;
+		wizard.setValue("feedName",f.serverType);
+		wizard.setValue("feedHost",f.url);
+		wizard.setValue("feedWorkspace",f.workspace);
+		wizard.setValue("feedWorkspaceList",f.workspaceList);
+		wizard.setValue("feedTiddlerFilter",f.tiddlerFilter);
+	}
+	return false;
+};
+
+config.macros.importTiddlers.onBrowseChange = function(e)
+{
+	var wizard = new Wizard(this);
+	var fileInput = wizard.getElement("txtPath");
+	fileInput.value = config.macros.importTiddlers.getURLFromLocalPath(this.value);
+	var serverType = wizard.getElement("selTypes");
+	serverType.value = "file";
+	return true;
+};
+
+config.macros.importTiddlers.getURLFromLocalPath = function(v)
+{
+	if(!v||!v.length)
+		return v;
+	v = v.replace(/\\/g,"/"); // use "/" for cross-platform consistency
+	var u;
+	var t = v.split(":");
+	var p = t[1]||t[0]; // remove drive letter (if any)
+	if (t[1] && (t[0]=="http"||t[0]=="https"||t[0]=="file")) {
+		u = v;
+	} else if(p.substr(0,1)=="/") {
+		u = document.location.protocol + "//" + document.location.hostname + (t[1] ? "/" : "") + v;
+	} else {
+		var c = document.location.href.replace(/\\/g,"/");
+		var pos = c.lastIndexOf("/");
+		if (pos!=-1)
+			c = c.substr(0,pos); // remove filename
+		u = c + "/" + p;
+	}
+	return u;
+};
+
+config.macros.importTiddlers.onOpen = function(e)
+{
+	var wizard = new Wizard(this);
+	var fileInput = wizard.getElement("txtPath");
+	var url = fileInput.value;
+	var serverType = wizard.getElement("selTypes").value || config.defaultAdaptor;
+	var adaptor = new config.adaptors[serverType]();
+	wizard.setValue("adaptor",adaptor);
+	wizard.setValue("serverType",serverType);
+	wizard.setValue("host",url);
+	var ret = adaptor.openHost(url,null,wizard,config.macros.importTiddlers.onOpenHost);
+	if(ret !== true)
+		displayMessage(ret);
+	wizard.setButtons([{caption: config.macros.importTiddlers.cancelLabel, tooltip: config.macros.importTiddlers.cancelPrompt, onClick: config.macros.importTiddlers.onCancel}],config.macros.importTiddlers.statusOpenHost);
+	return false;
+};
+
+config.macros.importTiddlers.onOpenHost = function(context,wizard)
+{
+	var adaptor = wizard.getValue("adaptor");
+	if(context.status !== true)
+		displayMessage("Error in importTiddlers.onOpenHost: " + context.statusText);
+	var ret = adaptor.getWorkspaceList(context,wizard,config.macros.importTiddlers.onGetWorkspaceList);
+	if(ret !== true)
+		displayMessage(ret);
+	wizard.setButtons([{caption: config.macros.importTiddlers.cancelLabel, tooltip: config.macros.importTiddlers.cancelPrompt, onClick: config.macros.importTiddlers.onCancel}],config.macros.importTiddlers.statusGetWorkspaceList);
+};
+
+config.macros.importTiddlers.onGetWorkspaceList = function(context,wizard)
+{
+	if(context.status !== true)
+		displayMessage("Error in importTiddlers.onGetWorkspaceList: " + context.statusText);
+	wizard.setValue("context",context);
+	var workspace = wizard.getValue("feedWorkspace");
+	if(!workspace && context.workspaces.length==1)
+		workspace = context.workspaces[0].title;
+	if(workspace) {
+		var ret = context.adaptor.openWorkspace(workspace,context,wizard,config.macros.importTiddlers.onOpenWorkspace);
+		if(ret !== true)
+			displayMessage(ret);
+		wizard.setValue("workspace",workspace);
+		wizard.setButtons([{caption: config.macros.importTiddlers.cancelLabel, tooltip: config.macros.importTiddlers.cancelPrompt, onClick: config.macros.importTiddlers.onCancel}],config.macros.importTiddlers.statusOpenWorkspace);
+		return;
+	}
+	wizard.addStep(config.macros.importTiddlers.step2Title,config.macros.importTiddlers.step2Html);
+	var s = wizard.getElement("selWorkspace");
+	s.onchange = config.macros.importTiddlers.onWorkspaceChange;
+	for(var t=0; t<context.workspaces.length; t++) {
+		var e = createTiddlyElement(s,"option",null,null,context.workspaces[t].title);
+		e.value = context.workspaces[t].title;
+	}
+	var workspaceList = wizard.getValue("feedWorkspaceList");
+	if(workspaceList) {
+		var list = workspaceList.parseParams("workspace",null,false,true);
+		for(var n=1; n<list.length; n++) {
+			if(context.workspaces.findByField("title",list[n].value) == null) {
+				e = createTiddlyElement(s,"option",null,null,list[n].value);
+				e.value = list[n].value;
+			}
+		}
+	}
+	if(workspace) {
+		t = wizard.getElement("txtWorkspace");
+		t.value = workspace;
+	}
+	wizard.setButtons([{caption: config.macros.importTiddlers.openLabel, tooltip: config.macros.importTiddlers.openPrompt, onClick: config.macros.importTiddlers.onChooseWorkspace}]);
+};
+
+config.macros.importTiddlers.onWorkspaceChange = function(e)
+{
+	var wizard = new Wizard(this);
+	var t = wizard.getElement("txtWorkspace");
+	t.value = this.value;
+	this.selectedIndex = 0;
+	return false;
+};
+
+config.macros.importTiddlers.onChooseWorkspace = function(e)
+{
+	var wizard = new Wizard(this);
+	var adaptor = wizard.getValue("adaptor");
+	var workspace = wizard.getElement("txtWorkspace").value;
+	wizard.setValue("workspace",workspace);
+	var context = wizard.getValue("context");
+	var ret = adaptor.openWorkspace(workspace,context,wizard,config.macros.importTiddlers.onOpenWorkspace);
+	if(ret !== true)
+		displayMessage(ret);
+	wizard.setButtons([{caption: config.macros.importTiddlers.cancelLabel, tooltip: config.macros.importTiddlers.cancelPrompt, onClick: config.macros.importTiddlers.onCancel}],config.macros.importTiddlers.statusOpenWorkspace);
+	return false;
+};
+
+config.macros.importTiddlers.onOpenWorkspace = function(context,wizard)
+{
+	if(context.status !== true)
+		displayMessage("Error in importTiddlers.onOpenWorkspace: " + context.statusText);
+	var adaptor = wizard.getValue("adaptor");
+	var ret = adaptor.getTiddlerList(context,wizard,config.macros.importTiddlers.onGetTiddlerList,wizard.getValue("feedTiddlerFilter"));
+	if(ret !== true)
+		displayMessage(ret);
+	wizard.setButtons([{caption: config.macros.importTiddlers.cancelLabel, tooltip: config.macros.importTiddlers.cancelPrompt, onClick: config.macros.importTiddlers.onCancel}],config.macros.importTiddlers.statusGetTiddlerList);
+};
+
+config.macros.importTiddlers.onGetTiddlerList = function(context,wizard)
+{
+	if(context.status !== true) {
+		wizard.setButtons([{caption: config.macros.importTiddlers.cancelLabel, tooltip: config.macros.importTiddlers.cancelPrompt, onClick: config.macros.importTiddlers.onCancel}],config.macros.importTiddlers.errorGettingTiddlerList);
+		return;
+	}
+	// Extract data for the listview
+	var listedTiddlers = [];
+	if(context.tiddlers) {
+		for(var n=0; n<context.tiddlers.length; n++) {
+			var tiddler = context.tiddlers[n];
+			listedTiddlers.push({
+				title: tiddler.title,
+				modified: tiddler.modified,
+				modifier: tiddler.modifier,
+				text: tiddler.text ? wikifyPlainText(tiddler.text,100) : "",
+				tags: tiddler.tags,
+				size: tiddler.text ? tiddler.text.length : 0,
+				tiddler: tiddler
+			});
+		}
+	}
+	listedTiddlers.sort(function(a,b) {return a.title < b.title ? -1 : (a.title == b.title ? 0 : +1);});
+	// Display the listview
+	wizard.addStep(config.macros.importTiddlers.step3Title,config.macros.importTiddlers.step3Html);
+	var markList = wizard.getElement("markList");
+	var listWrapper = document.createElement("div");
+	markList.parentNode.insertBefore(listWrapper,markList);
+	var listView = ListView.create(listWrapper,listedTiddlers,config.macros.importTiddlers.listViewTemplate);
+	wizard.setValue("listView",listView);
+	wizard.setValue("context",context);
+	var txtSaveTiddler = wizard.getElement("txtSaveTiddler");
+	txtSaveTiddler.value = config.macros.importTiddlers.generateSystemServerName(wizard);
+	wizard.setButtons([
+			{caption: config.macros.importTiddlers.cancelLabel, tooltip: config.macros.importTiddlers.cancelPrompt, onClick: config.macros.importTiddlers.onCancel},
+			{caption: config.macros.importTiddlers.importLabel, tooltip: config.macros.importTiddlers.importPrompt, onClick: config.macros.importTiddlers.doImport}
+		]);
+};
+
+config.macros.importTiddlers.generateSystemServerName = function(wizard)
+{
+	var serverType = wizard.getValue("serverType");
+	var host = wizard.getValue("host");
+	var workspace = wizard.getValue("workspace");
+	var pattern = config.macros.importTiddlers[workspace ? "systemServerNamePattern" : "systemServerNamePatternNoWorkspace"];
+	return pattern.format([serverType,host,workspace]);
+};
+
+config.macros.importTiddlers.saveServerTiddler = function(wizard)
+{
+	var txtSaveTiddler = wizard.getElement("txtSaveTiddler").value;
+	if(store.tiddlerExists(txtSaveTiddler)) {
+		if(!confirm(config.macros.importTiddlers.confirmOverwriteSaveTiddler.format([txtSaveTiddler])))
+			return;
+		store.suspendNotifications();
+		store.removeTiddler(txtSaveTiddler);
+		store.resumeNotifications();
+	}
+	var serverType = wizard.getValue("serverType");
+	var host = wizard.getValue("host");
+	var workspace = wizard.getValue("workspace");
+	var text = config.macros.importTiddlers.serverSaveTemplate.format([serverType,host,workspace]);
+	store.saveTiddler(txtSaveTiddler,txtSaveTiddler,text,config.macros.importTiddlers.serverSaveModifier,new Date(),["systemServer"]);
+};
+
+config.macros.importTiddlers.doImport = function(e)
+{
+	var wizard = new Wizard(this);
+	if(wizard.getElement("chkSave").checked)
+		config.macros.importTiddlers.saveServerTiddler(wizard);
+	var chkSync = wizard.getElement("chkSync").checked;
+	wizard.setValue("sync",chkSync);
+	var listView = wizard.getValue("listView");
+	var rowNames = ListView.getSelectedRows(listView);
+	var adaptor = wizard.getValue("adaptor");
+	var overwrite = [];
+	var t;
+	for(t=0; t<rowNames.length; t++) {
+		if(store.tiddlerExists(rowNames[t]))
+			overwrite.push(rowNames[t]);
+	}
+	if(overwrite.length > 0) {
+		if(!confirm(config.macros.importTiddlers.confirmOverwriteText.format([overwrite.join(", ")])))
+			return false;
+	}
+	wizard.addStep(config.macros.importTiddlers.step4Title.format([rowNames.length]),config.macros.importTiddlers.step4Html);
+	for(t=0; t<rowNames.length; t++) {
+		var link = document.createElement("div");
+		createTiddlyLink(link,rowNames[t],true);
+		var place = wizard.getElement("markReport");
+		place.parentNode.insertBefore(link,place);
+	}
+	wizard.setValue("remainingImports",rowNames.length);
+	wizard.setButtons([
+			{caption: config.macros.importTiddlers.cancelLabel, tooltip: config.macros.importTiddlers.cancelPrompt, onClick: config.macros.importTiddlers.onCancel}
+		],config.macros.importTiddlers.statusDoingImport);
+	var wizardContext = wizard.getValue("context");
+	var tiddlers = wizardContext ? wizardContext.tiddlers : [];
+	for(t=0; t<rowNames.length; t++) {
+		var context = {
+			allowSynchronous:true,
+			tiddler:tiddlers[tiddlers.findByField("title",rowNames[t])]
+		};
+		adaptor.getTiddler(rowNames[t],context,wizard,config.macros.importTiddlers.onGetTiddler);
+	}
+	return false;
+};
+
+config.macros.importTiddlers.onGetTiddler = function(context,wizard)
+{
+	if(!context.status)
+		displayMessage("Error in importTiddlers.onGetTiddler: " + context.statusText);
+	var tiddler = context.tiddler;
+	store.suspendNotifications();
+	store.saveTiddler(tiddler.title, tiddler.title, tiddler.text, tiddler.modifier, tiddler.modified, tiddler.tags, tiddler.fields, true, tiddler.created);
+	if(!wizard.getValue("sync")) {
+		store.setValue(tiddler.title,'server',null);
+	}
+	store.resumeNotifications();
+	if(!context.isSynchronous)
+		store.notify(tiddler.title,true);
+	var remainingImports = wizard.getValue("remainingImports")-1;
+	wizard.setValue("remainingImports",remainingImports);
+	if(remainingImports == 0) {
+		if(context.isSynchronous) {
+			store.notifyAll();
+			refreshDisplay();
+		}
+		wizard.setButtons([
+				{caption: config.macros.importTiddlers.doneLabel, tooltip: config.macros.importTiddlers.donePrompt, onClick: config.macros.importTiddlers.onClose}
+			],config.macros.importTiddlers.statusDoneImport);
+		autoSaveChanges();
+	}
+};
+
+//--
+//-- Upgrade macro
+//--
+
+config.macros.upgrade.handler = function(place)
+{
+	var w = new Wizard();
+	w.createWizard(place,this.wizardTitle);
+	w.addStep(this.step1Title,this.step1Html.format([this.source,this.source]));
+	w.setButtons([{caption: this.upgradeLabel, tooltip: this.upgradePrompt, onClick: this.onClickUpgrade}]);
+};
+
+config.macros.upgrade.onClickUpgrade = function(e)
+{
+	var me = config.macros.upgrade;
+	var w = new Wizard(this);
+	if(window.location.protocol != "file:") {
+		alert(me.errorCantUpgrade);
+		return false;
+	}
+	if(story.areAnyDirty() || store.isDirty()) {
+		alert(me.errorNotSaved);
+		return false;
+	}
+	var localPath = getLocalPath(document.location.toString());
+	var backupPath = getBackupPath(localPath,me.backupExtension);
+	w.setValue("backupPath",backupPath);
+	w.setButtons([],me.statusPreparingBackup);
+	var original = loadOriginal(localPath);
+	w.setButtons([],me.statusSavingBackup);
+	var backup = copyFile(backupPath,localPath);
+	if(!backup)
+		backup = saveFile(backupPath,original);
+	if(!backup) {
+		w.setButtons([],me.errorSavingBackup);
+		alert(me.errorSavingBackup);
+		return false;
+	}
+	w.setButtons([],me.statusLoadingCore);
+	var load = loadRemoteFile(me.source,me.onLoadCore,w);
+	if(typeof load == "string") {
+		w.setButtons([],me.errorLoadingCore);
+		alert(me.errorLoadingCore);
+		return false;
+	}
+	return false;
+};
+
+config.macros.upgrade.onLoadCore = function(status,params,responseText,url,xhr)
+{
+	var me = config.macros.upgrade;
+	var w = params;
+	var errMsg;
+	if(!status)
+		errMsg = me.errorLoadingCore;
+	var newVer = me.extractVersion(responseText);
+	if(!newVer)
+		errMsg = me.errorCoreFormat;
+	if(errMsg) {
+		w.setButtons([],errMsg);
+		alert(errMsg);
+		return;
+	}
+	var onStartUpgrade = function(e) {
+		w.setButtons([],me.statusSavingCore);
+		var localPath = getLocalPath(document.location.toString());
+		saveFile(localPath,responseText);
+		w.setButtons([],me.statusReloadingCore);
+		var backupPath = w.getValue("backupPath");
+		var newLoc = document.location.toString() + "?time=" + new Date().convertToYYYYMMDDHHMM() + "#upgrade:[[" + encodeURI(backupPath) + "]]";
+		window.setTimeout(function () {window.location = newLoc;},10);
+	};
+	var step2 = [me.step2Html_downgrade,me.step2Html_restore,me.step2Html_upgrade][compareVersions(version,newVer) + 1];
+	w.addStep(me.step2Title,step2.format([formatVersion(newVer),formatVersion(version)]));
+	w.setButtons([{caption: me.startLabel, tooltip: me.startPrompt, onClick: onStartUpgrade},{caption: me.cancelLabel, tooltip: me.cancelPrompt, onClick: me.onCancel}]);
+};
+
+config.macros.upgrade.onCancel = function(e)
+{
+	var me = config.macros.upgrade;
+	var w = new Wizard(this);
+	w.addStep(me.step3Title,me.step3Html);
+	w.setButtons([]);
+	return false;
+};
+
+config.macros.upgrade.extractVersion = function(upgradeFile)
+{
+	var re = /^var version = \{title: "([^"]+)", major: (\d+), minor: (\d+), revision: (\d+)(, beta: (\d+)){0,1}, date: new Date\("([^"]+)"\)/mg;
+	var m = re.exec(upgradeFile);
+	return  m ? {title: m[1], major: m[2], minor: m[3], revision: m[4], beta: m[6], date: new Date(m[7])} : null;
+};
+
+function upgradeFrom(path)
+{
+	var importStore = new TiddlyWiki();
+	var tw = loadFile(path);
+	if(window.netscape !== undefined)
+		tw = convertUTF8ToUnicode(tw);
+	importStore.importTiddlyWiki(tw);
+	importStore.forEachTiddler(function(title,tiddler) {
+		if(!store.getTiddler(title)) {
+			store.addTiddler(tiddler);
+		}
+	});
+	refreshDisplay();
+	saveChanges(); //# To create appropriate Markup* sections
+	alert(config.messages.upgradeDone.format([formatVersion()]));
+	window.location = window.location.toString().substr(0,window.location.toString().lastIndexOf("?"));
+}
+
+//--
+//-- Sync macro
+//--
+
+// Synchronisation handlers
+config.syncers = {};
+
+// Sync state.
+var currSync = null;
+
+// sync macro
+config.macros.sync.handler = function(place,macroName,params,wikifier,paramString,tiddler)
+{
+	if(!wikifier.isStatic)
+		this.startSync(place);
+};
+
+config.macros.sync.cancelSync = function()
+{
+	currSync = null;
+};
+
+config.macros.sync.startSync = function(place)
+{
+	if(currSync)
+		config.macros.sync.cancelSync();
+	currSync = {};
+	currSync.syncList = this.getSyncableTiddlers();
+	currSync.syncTasks = this.createSyncTasks(currSync.syncList);
+	this.preProcessSyncableTiddlers(currSync.syncList);
+	var wizard = new Wizard();
+	currSync.wizard = wizard;
+	wizard.createWizard(place,this.wizardTitle);
+	wizard.addStep(this.step1Title,this.step1Html);
+	var markList = wizard.getElement("markList");
+	var listWrapper = document.createElement("div");
+	markList.parentNode.insertBefore(listWrapper,markList);
+	currSync.listView = ListView.create(listWrapper,currSync.syncList,this.listViewTemplate);
+	this.processSyncableTiddlers(currSync.syncList);
+	wizard.setButtons([{caption: this.syncLabel, tooltip: this.syncPrompt, onClick: this.doSync}]);
+};
+
+config.macros.sync.getSyncableTiddlers = function()
+{
+	var list = [];
+	store.forEachTiddler(function(title,tiddler) {
+		var syncItem = {};
+		syncItem.serverType = tiddler.getServerType();
+		syncItem.serverHost = tiddler.fields['server.host'];
+		if(syncItem.serverType && syncItem.serverHost) {
+			syncItem.adaptor = new config.adaptors[syncItem.serverType];
+			syncItem.serverWorkspace = tiddler.fields['server.workspace'];
+			syncItem.tiddler = tiddler;
+			syncItem.title = tiddler.title;
+			syncItem.isTouched = tiddler.isTouched();
+			syncItem.selected = syncItem.isTouched;
+			syncItem.syncStatus = config.macros.sync.syncStatusList[syncItem.isTouched ? "changedLocally" : "none"];
+			syncItem.status = syncItem.syncStatus.text;
+			list.push(syncItem);
+		}
+		});
+	list.sort(function(a,b) {return a.title < b.title ? -1 : (a.title == b.title ? 0 : +1);});
+	return list;
+};
+
+config.macros.sync.preProcessSyncableTiddlers = function(syncList)
+{
+	for(var i=0; i<syncList.length; i++) {
+		var si = syncList[i];
+		si.serverUrl = si.adaptor.generateTiddlerInfo(si.tiddler).uri;
+	}
+};
+
+config.macros.sync.processSyncableTiddlers = function(syncList)
+{
+	for(var i=0; i<syncList.length; i++) {
+		var si = syncList[i];
+		if(si.syncStatus.display)
+			si.rowElement.style.display = si.syncStatus.display;
+		if(si.syncStatus.className)
+			si.rowElement.className = si.syncStatus.className;
+	}
+};
+
+config.macros.sync.createSyncTasks = function(syncList)
+{
+	var syncTasks = [];
+	for(var i=0; i<syncList.length; i++) {
+		var si = syncList[i];
+		var r = null;
+		for(var j=0; j<syncTasks.length; j++) {
+			var cst = syncTasks[j];
+			if(si.serverType == cst.serverType && si.serverHost == cst.serverHost && si.serverWorkspace == cst.serverWorkspace)
+				r = cst;
+		}
+		if(r) {
+			si.syncTask = r;
+			r.syncItems.push(si);
+		} else {
+			si.syncTask = this.createSyncTask(si);
+			syncTasks.push(si.syncTask);
+		}
+	}
+	return syncTasks;
+};
+
+config.macros.sync.createSyncTask = function(syncItem)
+{
+	var st = {};
+	st.serverType = syncItem.serverType;
+	st.serverHost = syncItem.serverHost;
+	st.serverWorkspace = syncItem.serverWorkspace;
+	st.syncItems = [syncItem];
+
+	var openWorkspaceCallback = function(context,syncItems) {
+		if(context.status) {
+			context.adaptor.getTiddlerList(context,syncItems,getTiddlerListCallback);
+			return true;
+		}
+		displayMessage(context.statusText);
+		return false;
+	};
+
+	var getTiddlerListCallback = function(context,sycnItems) {
+		if(!context.status) {
+			displayMessage(context.statusText);
+			return false;
+		}
+		syncItems = context.userParams;
+		var tiddlers = context.tiddlers;
+		for(var i=0; i<syncItems.length; i++) {
+			var si = syncItems[i];
+			var f = tiddlers.findByField("title",si.title);
+			if(f !== null) {
+				if(tiddlers[f].fields['server.page.revision'] > si.tiddler.fields['server.page.revision']) {
+					si.syncStatus = config.macros.sync.syncStatusList[si.isTouched ? 'changedBoth' : 'changedServer'];
+				}
+			} else {
+				si.syncStatus = config.macros.sync.syncStatusList.notFound;
+			}
+			config.macros.sync.updateSyncStatus(si);
+		}
+		return true;
+	};
+	var context = {host:st.serverHost,workspace:st.serverWorkspace};
+	syncItem.adaptor.openHost(st.serverHost);
+	syncItem.adaptor.openWorkspace(st.serverWorkspace,context,st.syncItems,openWorkspaceCallback);
+	return st;
+};
+
+config.macros.sync.updateSyncStatus = function(syncItem)
+{
+	var e = syncItem.colElements["status"];
+	removeChildren(e);
+	createTiddlyText(e,syncItem.syncStatus.text);
+	if(syncItem.syncStatus.display)
+		syncItem.rowElement.style.display = syncItem.syncStatus.display;
+	if(syncItem.syncStatus.className)
+		syncItem.rowElement.className = syncItem.syncStatus.className;
+};
+
+config.macros.sync.doSync = function(e)
+{
+	var getTiddlerCallback = function(context,syncItem) {
+		if(syncItem) {
+			var tiddler = context.tiddler;
+			store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields,true,tiddler.created);
+			syncItem.syncStatus = config.macros.sync.syncStatusList.gotFromServer;
+			config.macros.sync.updateSyncStatus(syncItem);
+		}
+	};
+	var putTiddlerCallback = function(context,syncItem) {
+		if(syncItem) {
+			store.resetTiddler(context.title);
+			syncItem.syncStatus = config.macros.sync.syncStatusList.putToServer;
+			config.macros.sync.updateSyncStatus(syncItem);
+		}
+	};
+
+	var rowNames = ListView.getSelectedRows(currSync.listView);
+	var sl = config.macros.sync.syncStatusList;
+	for(var i=0; i<currSync.syncList.length; i++) {
+		var si = currSync.syncList[i];
+		if(rowNames.indexOf(si.title) != -1) {
+			var errorMsg = "Error in doSync: ";
+			try {
+				var r = true;
+				switch(si.syncStatus) {
+				case sl.changedServer:
+					r = si.adaptor.getTiddler(si.title,null,si,getTiddlerCallback);
+					break;
+				case sl.notFound:
+				case sl.changedLocally:
+				case sl.changedBoth:
+					r = si.adaptor.putTiddler(si.tiddler,null,si,putTiddlerCallback);
+					break;
+				default:
+					break;
+				}
+				if(!r)
+					displayMessage(errorMsg + r);
+			} catch(ex) {
+				if(ex.name == "TypeError")
+					displayMessage("sync operation unsupported: " + ex.message);
+				else
+					displayMessage(errorMsg + ex.message);
+			}
+		}
+	}
+	return false;
+};
+
+//--
+//-- Manager UI for groups of tiddlers
+//--
+
+config.macros.plugins.handler = function(place,macroName,params,wikifier,paramString)
+{
+	var wizard = new Wizard();
+	wizard.createWizard(place,this.wizardTitle);
+	wizard.addStep(this.step1Title,this.step1Html);
+	var markList = wizard.getElement("markList");
+	var listWrapper = document.createElement("div");
+	markList.parentNode.insertBefore(listWrapper,markList);
+	listWrapper.setAttribute("refresh","macro");
+	listWrapper.setAttribute("macroName","plugins");
+	listWrapper.setAttribute("params",paramString);
+	this.refresh(listWrapper,paramString);
+};
+
+config.macros.plugins.refresh = function(listWrapper,params)
+{
+	var wizard = new Wizard(listWrapper);
+	var selectedRows = [];
+	ListView.forEachSelector(listWrapper,function(e,rowName) {
+			if(e.checked)
+				selectedRows.push(e.getAttribute("rowName"));
+		});
+	removeChildren(listWrapper);
+	params = params.parseParams("anon");
+	var plugins = installedPlugins.slice(0);
+	var t,tiddler,p;
+	var configTiddlers = store.getTaggedTiddlers("systemConfig");
+	for(t=0; t<configTiddlers.length; t++) {
+		tiddler = configTiddlers[t];
+		if(plugins.findByField("title",tiddler.title) == null) {
+			p = getPluginInfo(tiddler);
+			p.executed = false;
+			p.log.splice(0,0,this.skippedText);
+			plugins.push(p);
+		}
+	}
+	for(t=0; t<plugins.length; t++) {
+		p = plugins[t];
+		p.size = p.tiddler.text ? p.tiddler.text.length : 0;
+		p.forced = p.tiddler.isTagged("systemConfigForce");
+		p.disabled = p.tiddler.isTagged("systemConfigDisable");
+		p.Selected = selectedRows.indexOf(plugins[t].title) != -1;
+	}
+	if(plugins.length == 0) {
+		createTiddlyElement(listWrapper,"em",null,null,this.noPluginText);
+		wizard.setButtons([]);
+	} else {
+		var listView = ListView.create(listWrapper,plugins,this.listViewTemplate,this.onSelectCommand);
+		wizard.setValue("listView",listView);
+		wizard.setButtons([
+				{caption: config.macros.plugins.removeLabel, tooltip: config.macros.plugins.removePrompt, onClick: config.macros.plugins.doRemoveTag},
+				{caption: config.macros.plugins.deleteLabel, tooltip: config.macros.plugins.deletePrompt, onClick: config.macros.plugins.doDelete}
+			]);
+	}
+};
+
+config.macros.plugins.doRemoveTag = function(e)
+{
+	var wizard = new Wizard(this);
+	var listView = wizard.getValue("listView");
+	var rowNames = ListView.getSelectedRows(listView);
+	if(rowNames.length == 0) {
+		alert(config.messages.nothingSelected);
+	} else {
+		for(var t=0; t<rowNames.length; t++)
+			store.setTiddlerTag(rowNames[t],false,"systemConfig");
+	}
+};
+
+config.macros.plugins.doDelete = function(e)
+{
+	var wizard = new Wizard(this);
+	var listView = wizard.getValue("listView");
+	var rowNames = ListView.getSelectedRows(listView);
+	if(rowNames.length == 0) {
+		alert(config.messages.nothingSelected);
+	} else {
+		if(confirm(config.macros.plugins.confirmDeleteText.format([rowNames.join(", ")]))) {
+			for(var t=0; t<rowNames.length; t++) {
+				store.removeTiddler(rowNames[t]);
+				story.closeTiddler(rowNames[t],true);
+			}
+		}
+	}
+};
+
+//--
+//-- Message area
+//--
+
+function getMessageDiv()
+{
+	var msgArea = document.getElementById("messageArea");
+	if(!msgArea)
+		return null;
+	if(!msgArea.hasChildNodes())
+		createTiddlyButton(createTiddlyElement(msgArea,"div",null,"messageToolbar"),
+			config.messages.messageClose.text,
+			config.messages.messageClose.tooltip,
+			clearMessage);
+	msgArea.style.display = "block";
+	return createTiddlyElement(msgArea,"div");
+}
+
+function displayMessage(text,linkText)
+{
+	var e = getMessageDiv();
+	if(!e) {
+		alert(text);
+		return;
+	}
+	if(linkText) {
+		var link = createTiddlyElement(e,"a",null,null,text);
+		link.href = linkText;
+		link.target = "_blank";
+	} else {
+		e.appendChild(document.createTextNode(text));
+	}
+}
+
+function clearMessage()
+{
+	var msgArea = document.getElementById("messageArea");
+	if(msgArea) {
+		removeChildren(msgArea);
+		msgArea.style.display = "none";
+	}
+	return false;
+}
+
+//--
+//-- Refresh mechanism
+//--
+
+config.notifyTiddlers = [
+	{name: "StyleSheetLayout", notify: refreshStyles},
+	{name: "StyleSheetColors", notify: refreshStyles},
+	{name: "StyleSheet", notify: refreshStyles},
+	{name: "StyleSheetPrint", notify: refreshStyles},
+	{name: "PageTemplate", notify: refreshPageTemplate},
+	{name: "SiteTitle", notify: refreshPageTitle},
+	{name: "SiteSubtitle", notify: refreshPageTitle},
+	{name: "WindowTitle", notify: refreshPageTitle},
+	{name: "ColorPalette", notify: refreshColorPalette},
+	{name: null, notify: refreshDisplay}
+];
+
+config.refreshers = {
+	link: function(e,changeList)
+		{
+		var title = e.getAttribute("tiddlyLink");
+		refreshTiddlyLink(e,title);
+		return true;
+		},
+
+	tiddler: function(e,changeList)
+		{
+		var title = e.getAttribute("tiddler");
+		var template = e.getAttribute("template");
+		if(changeList && changeList.indexOf(title) != -1 && !story.isDirty(title))
+			story.refreshTiddler(title,template,true);
+		else
+			refreshElements(e,changeList);
+		return true;
+		},
+
+	content: function(e,changeList)
+		{
+		var title = e.getAttribute("tiddler");
+		var force = e.getAttribute("force");
+		var args = e.getAttribute("args");
+		if(force != null || changeList == null || changeList.indexOf(title) != -1) {
+			removeChildren(e);
+			config.macros.tiddler.transclude(e,title,args);
+			return true;
+		} else
+			return false;
+		},
+
+	macro: function(e,changeList)
+		{
+		var macro = e.getAttribute("macroName");
+		var params = e.getAttribute("params");
+		if(macro)
+			macro = config.macros[macro];
+		if(macro && macro.refresh)
+			macro.refresh(e,params);
+		return true;
+		}
+};
+
+config.refresherData = {
+	styleSheet: "StyleSheet",
+	defaultStyleSheet: "StyleSheet",
+	pageTemplate: "PageTemplate",
+	defaultPageTemplate: "PageTemplate",
+	colorPalette: "ColorPalette",
+	defaultColorPalette: "ColorPalette"
+};
+
+function refreshElements(root,changeList)
+{
+	var nodes = root.childNodes;
+	for(var c=0; c<nodes.length; c++) {
+		var e = nodes[c], type = null;
+		if(e.getAttribute && (e.tagName ? e.tagName != "IFRAME" : true))
+			type = e.getAttribute("refresh");
+		var refresher = config.refreshers[type];
+		var refreshed = false;
+		if(refresher != undefined)
+			refreshed = refresher(e,changeList);
+		if(e.hasChildNodes() && !refreshed)
+			refreshElements(e,changeList);
+	}
+}
+
+function applyHtmlMacros(root,tiddler)
+{
+	var e = root.firstChild;
+	while(e) {
+		var nextChild = e.nextSibling;
+		if(e.getAttribute) {
+			var macro = e.getAttribute("macro");
+			if(macro) {
+				e.removeAttribute("macro");
+				var params = "";
+				var p = macro.indexOf(" ");
+				if(p != -1) {
+					params = macro.substr(p+1);
+					macro = macro.substr(0,p);
+				}
+				invokeMacro(e,macro,params,null,tiddler);
+			}
+		}
+		if(e.hasChildNodes())
+			applyHtmlMacros(e,tiddler);
+		e = nextChild;
+	}
+}
+
+function refreshPageTemplate(title)
+{
+	var stash = jQuery("<div/>").appendTo("body").hide()[0];
+	var display = story.getContainer();
+	var nodes,t;
+	if(display) {
+		nodes = display.childNodes;
+		for(t=nodes.length-1; t>=0; t--)
+			stash.appendChild(nodes[t]);
+	}
+	var wrapper = document.getElementById("contentWrapper");
+
+	var isAvailable = function(title) {
+		var s = title ? title.indexOf(config.textPrimitives.sectionSeparator) : -1;
+		if(s!=-1)
+			title = title.substr(0,s);
+		return store.tiddlerExists(title) || store.isShadowTiddler(title);
+	};
+	if(!title || !isAvailable(title))
+		title = config.refresherData.pageTemplate;
+	if(!isAvailable(title))
+		title = config.refresherData.defaultPageTemplate; //# this one is always avaialable
+	wrapper.innerHTML = store.getRecursiveTiddlerText(title,null,10);
+	applyHtmlMacros(wrapper);
+	refreshElements(wrapper);
+	display = story.getContainer();
+	removeChildren(display);
+	if(!display)
+		display = createTiddlyElement(wrapper,"div",story.containerId());
+	nodes = stash.childNodes;
+	for(t=nodes.length-1; t>=0; t--)
+		display.appendChild(nodes[t]);
+	removeNode(stash);
+}
+
+function refreshDisplay(hint)
+{
+	if(typeof hint == "string")
+		hint = [hint];
+	var e = document.getElementById("contentWrapper");
+	refreshElements(e,hint);
+	if(backstage.isPanelVisible()) {
+		e = document.getElementById("backstage");
+		refreshElements(e,hint);
+	}
+}
+
+function refreshPageTitle()
+{
+	document.title = getPageTitle();
+}
+
+function getPageTitle()
+{
+	return wikifyPlain("WindowTitle");
+}
+
+function refreshStyles(title,doc)
+{
+	setStylesheet(title == null ? "" : store.getRecursiveTiddlerText(title,"",10),title,doc || document);
+}
+
+function refreshColorPalette(title)
+{
+	if(!startingUp)
+		refreshAll();
+}
+
+function refreshAll()
+{
+	refreshPageTemplate();
+	refreshDisplay();
+	refreshStyles("StyleSheetLayout");
+	refreshStyles("StyleSheetColors");
+	refreshStyles(config.refresherData.styleSheet);
+	refreshStyles("StyleSheetPrint");
+}
+
+//--
+//-- Options stuff
+//--
+
+config.optionHandlers = {
+	'txt': {
+		get: function(name) {return encodeCookie(config.options[name].toString());},
+		set: function(name,value) {config.options[name] = decodeCookie(value);}
+	},
+	'chk': {
+		get: function(name) {return config.options[name] ? "true" : "false";},
+		set: function(name,value) {config.options[name] = value == "true";}
+	}
+};
+
+function loadOptionsCookie()
+{
+	if(safeMode)
+		return;
+	var cookies = document.cookie.split(";");
+	for(var c=0; c<cookies.length; c++) {
+		var p = cookies[c].indexOf("=");
+		if(p != -1) {
+			var name = cookies[c].substr(0,p).trim();
+			var value = cookies[c].substr(p+1).trim();
+			var optType = name.substr(0,3);
+			if(config.optionHandlers[optType] && config.optionHandlers[optType].set)
+				config.optionHandlers[optType].set(name,value);
+		}
+	}
+}
+
+function saveOptionCookie(name)
+{
+	if(safeMode)
+		return;
+	var c = name + "=";
+	var optType = name.substr(0,3);
+	if(config.optionHandlers[optType] && config.optionHandlers[optType].get)
+		c += config.optionHandlers[optType].get(name);
+	c += "; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";
+	document.cookie = c;
+}
+
+function removeCookie(name)
+{
+	document.cookie = name + "=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;";
+}
+
+function encodeCookie(s)
+{
+	return escape(convertUnicodeToHtmlEntities(s));
+}
+
+function decodeCookie(s)
+{
+	s = unescape(s);
+	var re = /&#[0-9]{1,5};/g;
+	return s.replace(re,function($0) {return String.fromCharCode(eval($0.replace(/[&#;]/g,"")));});
+}
+
+
+config.macros.option.genericCreate = function(place,type,opt,className,desc)
+{
+	var typeInfo = config.macros.option.types[type];
+	var c = document.createElement(typeInfo.elementType);
+	if(typeInfo.typeValue)
+		c.setAttribute("type",typeInfo.typeValue);
+	c[typeInfo.eventName] = typeInfo.onChange;
+	c.setAttribute("option",opt);
+	c.className = className || typeInfo.className;
+	if(config.optionsDesc[opt])
+		c.setAttribute("title",config.optionsDesc[opt]);
+	place.appendChild(c);
+	if(desc != "no")
+		createTiddlyText(place,config.optionsDesc[opt] || opt);
+	c[typeInfo.valueField] = config.options[opt];
+	return c;
+};
+
+config.macros.option.genericOnChange = function(e)
+{
+	var opt = this.getAttribute("option");
+	if(opt) {
+		var optType = opt.substr(0,3);
+		var handler = config.macros.option.types[optType];
+		if(handler.elementType && handler.valueField)
+			config.macros.option.propagateOption(opt,handler.valueField,this[handler.valueField],handler.elementType,this);
+	}
+	return true;
+};
+
+config.macros.option.types = {
+	'txt': {
+		elementType: "input",
+		valueField: "value",
+		eventName: "onchange",
+		className: "txtOptionInput",
+		create: config.macros.option.genericCreate,
+		onChange: config.macros.option.genericOnChange
+	},
+	'chk': {
+		elementType: "input",
+		valueField: "checked",
+		eventName: "onclick",
+		className: "chkOptionInput",
+		typeValue: "checkbox",
+		create: config.macros.option.genericCreate,
+		onChange: config.macros.option.genericOnChange
+	}
+};
+
+config.macros.option.propagateOption = function(opt,valueField,value,elementType,elem)
+{
+	config.options[opt] = value;
+	saveOptionCookie(opt);
+	var nodes = document.getElementsByTagName(elementType);
+	for(var t=0; t<nodes.length; t++) {
+		var optNode = nodes[t].getAttribute("option");
+		if(opt == optNode && nodes[t]!=elem)
+			nodes[t][valueField] = value;
+	}
+};
+
+config.macros.option.handler = function(place,macroName,params,wikifier,paramString)
+{
+	params = paramString.parseParams("anon",null,true,false,false);
+	var opt = (params[1] && params[1].name == "anon") ? params[1].value : getParam(params,"name",null);
+	var className = (params[2] && params[2].name == "anon") ? params[2].value : getParam(params,"class",null);
+	var desc = getParam(params,"desc","no");
+	var type = opt.substr(0,3);
+	var h = config.macros.option.types[type];
+	if(h && h.create)
+		h.create(place,type,opt,className,desc);
+};
+
+config.macros.options.handler = function(place,macroName,params,wikifier,paramString)
+{
+	params = paramString.parseParams("anon",null,true,false,false);
+	var showUnknown = getParam(params,"showUnknown","no");
+	var wizard = new Wizard();
+	wizard.createWizard(place,this.wizardTitle);
+	wizard.addStep(this.step1Title,this.step1Html);
+	var markList = wizard.getElement("markList");
+	var chkUnknown = wizard.getElement("chkUnknown");
+	chkUnknown.checked = showUnknown == "yes";
+	chkUnknown.onchange = this.onChangeUnknown;
+	var listWrapper = document.createElement("div");
+	markList.parentNode.insertBefore(listWrapper,markList);
+	wizard.setValue("listWrapper",listWrapper);
+	this.refreshOptions(listWrapper,showUnknown == "yes");
+};
+
+config.macros.options.refreshOptions = function(listWrapper,showUnknown)
+{
+	var opts = [];
+	for(var n in config.options) {
+		var opt = {};
+		opt.option = "";
+		opt.name = n;
+		opt.lowlight = !config.optionsDesc[n];
+		opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
+		if(!opt.lowlight || showUnknown)
+			opts.push(opt);
+	}
+	opts.sort(function(a,b) {return a.name.substr(3) < b.name.substr(3) ? -1 : (a.name.substr(3) == b.name.substr(3) ? 0 : +1);});
+	var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
+	for(n=0; n<opts.length; n++) {
+		var type = opts[n].name.substr(0,3);
+		var h = config.macros.option.types[type];
+		if(h && h.create) {
+			h.create(opts[n].colElements['option'],type,opts[n].name,null,"no");
+		}
+	}
+};
+
+config.macros.options.onChangeUnknown = function(e)
+{
+	var wizard = new Wizard(this);
+	var listWrapper = wizard.getValue("listWrapper");
+	removeChildren(listWrapper);
+	config.macros.options.refreshOptions(listWrapper,this.checked);
+	return false;
+};
+
+//--
+//-- Saving
+//--
+
+var saveUsingSafari = false;
+
+var startSaveArea = '<div id="' + 'storeArea">'; // Split up into two so that indexOf() of this source doesn't find it
+var endSaveArea = '</d' + 'iv>';
+
+// If there are unsaved changes, force the user to confirm before exitting
+function confirmExit()
+{
+	hadConfirmExit = true;
+	if((store && store.isDirty && store.isDirty()) || (story && story.areAnyDirty && story.areAnyDirty()))
+		return config.messages.confirmExit;
+}
+
+// Give the user a chance to save changes before exitting
+function checkUnsavedChanges()
+{
+	if(store && store.isDirty && store.isDirty() && window.hadConfirmExit === false) {
+		if(confirm(config.messages.unsavedChangesWarning))
+			saveChanges();
+	}
+}
+
+function updateLanguageAttribute(s)
+{
+	if(config.locale) {
+		var mRE = /(<html(?:.*?)?)(?: xml:lang\="([a-z]+)")?(?: lang\="([a-z]+)")?>/;
+		var m = mRE.exec(s);
+		if(m) {
+			var t = m[1];
+			if(m[2])
+				t += ' xml:lang="' + config.locale + '"';
+			if(m[3])
+				t += ' lang="' + config.locale + '"';
+			t += ">";
+			s = s.substr(0,m.index) + t + s.substr(m.index+m[0].length);
+		}
+	}
+	return s;
+}
+
+function updateMarkupBlock(s,blockName,tiddlerName)
+{
+	return s.replaceChunk(
+			"<!--%0-START-->".format([blockName]),
+			"<!--%0-END-->".format([blockName]),
+			"\n" + convertUnicodeToFileFormat(store.getRecursiveTiddlerText(tiddlerName,"")) + "\n");
+}
+
+function updateOriginal(original,posDiv,localPath)
+{
+	if(!posDiv)
+		posDiv = locateStoreArea(original);
+	if(!posDiv) {
+		alert(config.messages.invalidFileError.format([localPath]));
+		return null;
+	}
+	var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
+				convertUnicodeToFileFormat(store.allTiddlersAsHtml()) + "\n" +
+				original.substr(posDiv[1]);
+	var newSiteTitle = convertUnicodeToFileFormat(getPageTitle()).htmlEncode();
+	revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
+	revised = updateLanguageAttribute(revised);
+	revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
+	revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
+	revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
+	revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
+	return revised;
+}
+
+function locateStoreArea(original)
+{
+	// Locate the storeArea div's
+	var posOpeningDiv = original.indexOf(startSaveArea);
+	var limitClosingDiv = original.indexOf("<"+"!--POST-STOREAREA--"+">");
+	if(limitClosingDiv == -1)
+		limitClosingDiv = original.indexOf("<"+"!--POST-BODY-START--"+">");
+	var posClosingDiv = original.lastIndexOf(endSaveArea,limitClosingDiv == -1 ? original.length : limitClosingDiv);
+	return (posOpeningDiv != -1 && posClosingDiv != -1) ? [posOpeningDiv,posClosingDiv] : null;
+}
+
+function autoSaveChanges(onlyIfDirty,tiddlers)
+{
+	if(config.options.chkAutoSave)
+		saveChanges(onlyIfDirty,tiddlers);
+}
+
+function loadOriginal(localPath)
+{
+	return loadFile(localPath);
+}
+
+// Save this tiddlywiki with the pending changes
+function saveChanges(onlyIfDirty,tiddlers)
+{
+	if(onlyIfDirty && !store.isDirty())
+		return;
+	clearMessage();
+	var t0 = new Date();
+	var originalPath = document.location.toString();
+	if(originalPath.substr(0,5) != "file:") {
+		alert(config.messages.notFileUrlError);
+		if(store.tiddlerExists(config.messages.saveInstructions))
+			story.displayTiddler(null,config.messages.saveInstructions);
+		return;
+	}
+	var localPath = getLocalPath(originalPath);
+	var original = loadOriginal(localPath);
+	if(original == null) {
+		alert(config.messages.cantSaveError);
+		if(store.tiddlerExists(config.messages.saveInstructions))
+			story.displayTiddler(null,config.messages.saveInstructions);
+		return;
+	}
+	var posDiv = locateStoreArea(original);
+	if(!posDiv) {
+		alert(config.messages.invalidFileError.format([localPath]));
+		return;
+	}
+	saveMain(localPath,original,posDiv);
+	if(config.options.chkSaveBackups)
+		saveBackup(localPath,original);
+	if(config.options.chkSaveEmptyTemplate)
+		saveEmpty(localPath,original,posDiv);
+	if(config.options.chkGenerateAnRssFeed && saveRss instanceof Function)
+		saveRss(localPath);
+	if(config.options.chkDisplayInstrumentation)
+		displayMessage("saveChanges " + (new Date()-t0) + " ms");
+}
+
+function saveMain(localPath,original,posDiv)
+{
+	var save;
+	try {
+		var revised = updateOriginal(original,posDiv,localPath);
+		save = saveFile(localPath,revised);
+	} catch (ex) {
+		showException(ex);
+	}
+	if(save) {
+		displayMessage(config.messages.mainSaved,"file://" + localPath);
+		store.setDirty(false);
+	} else {
+		alert(config.messages.mainFailed);
+	}
+}
+
+function saveBackup(localPath,original)
+{
+	var backupPath = getBackupPath(localPath);
+	var backup = copyFile(backupPath,localPath);
+	if(!backup)
+		backup = saveFile(backupPath,original);
+	if(backup)
+		displayMessage(config.messages.backupSaved,"file://" + backupPath);
+	else
+		alert(config.messages.backupFailed);
+}
+
+function saveEmpty(localPath,original,posDiv)
+{
+	var emptyPath,p;
+	if((p = localPath.lastIndexOf("/")) != -1)
+		emptyPath = localPath.substr(0,p) + "/";
+	else if((p = localPath.lastIndexOf("\\")) != -1)
+		emptyPath = localPath.substr(0,p) + "\\";
+	else
+		emptyPath = localPath + ".";
+	emptyPath += "empty.html";
+	var empty = original.substr(0,posDiv[0] + startSaveArea.length) + original.substr(posDiv[1]);
+	var emptySave = saveFile(emptyPath,empty);
+	if(emptySave)
+		displayMessage(config.messages.emptySaved,"file://" + emptyPath);
+	else
+		alert(config.messages.emptyFailed);
+}
+
+function getLocalPath(origPath)
+{
+	var originalPath = convertUriToUTF8(origPath,config.options.txtFileSystemCharSet);
+	// Remove any location or query part of the URL
+	var argPos = originalPath.indexOf("?");
+	if(argPos != -1)
+		originalPath = originalPath.substr(0,argPos);
+	var hashPos = originalPath.indexOf("#");
+	if(hashPos != -1)
+		originalPath = originalPath.substr(0,hashPos);
+	// Convert file://localhost/ to file:///
+	if(originalPath.indexOf("file://localhost/") == 0)
+		originalPath = "file://" + originalPath.substr(16);
+	// Convert to a native file format
+	var localPath;
+	if(originalPath.charAt(9) == ":") // pc local file
+		localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
+	else if(originalPath.indexOf("file://///") == 0) // FireFox pc network file
+		localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
+	else if(originalPath.indexOf("file:///") == 0) // mac/unix local file
+		localPath = unescape(originalPath.substr(7));
+	else if(originalPath.indexOf("file:/") == 0) // mac/unix local file
+		localPath = unescape(originalPath.substr(5));
+	else // pc network file
+		localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");
+	return localPath;
+}
+
+function getBackupPath(localPath,title,extension)
+{
+	var slash = "\\";
+	var dirPathPos = localPath.lastIndexOf("\\");
+	if(dirPathPos == -1) {
+		dirPathPos = localPath.lastIndexOf("/");
+		slash = "/";
+	}
+	var backupFolder = config.options.txtBackupFolder;
+	if(!backupFolder || backupFolder == "")
+		backupFolder = ".";
+	var backupPath = localPath.substr(0,dirPathPos) + slash + backupFolder + localPath.substr(dirPathPos);
+	backupPath = backupPath.substr(0,backupPath.lastIndexOf(".")) + ".";
+	if(title)
+		backupPath += title.replace(/[\\\/\*\?\":<> ]/g,"_") + ".";
+	backupPath += (new Date()).convertToYYYYMMDDHHMMSSMMM() + "." + (extension || "html");
+	return backupPath;
+}
+
+//--
+//-- RSS Saving
+//--
+
+function saveRss(localPath)
+{
+	var rssPath = localPath.substr(0,localPath.lastIndexOf(".")) + ".xml";
+	if(saveFile(rssPath,convertUnicodeToFileFormat(generateRss())))
+		displayMessage(config.messages.rssSaved,"file://" + rssPath);
+	else
+		alert(config.messages.rssFailed);
+}
+
+tiddlerToRssItem = function(tiddler,uri)
+{
+	var s = "<title" + ">" + tiddler.title.htmlEncode() + "</title" + ">\n";
+	s += "<description>" + wikifyStatic(tiddler.text,null,tiddler).htmlEncode() + "</description>\n";
+	for(var i=0; i<tiddler.tags.length; i++)
+		s += "<category>" + tiddler.tags[i] + "</category>\n";
+	s += "<link>" + uri + "#" + encodeURIComponent(String.encodeTiddlyLink(tiddler.title)) + "</link>\n";
+	s +="<pubDate>" + tiddler.modified.toGMTString() + "</pubDate>\n";
+	return s;
+};
+
+function generateRss()
+{
+	var s = [];
+	var d = new Date();
+	var u = store.getTiddlerText("SiteUrl");
+	// Assemble the header
+	s.push("<" + "?xml version=\"1.0\"?" + ">");
+	s.push("<rss version=\"2.0\">");
+	s.push("<channel>");
+	s.push("<title" + ">" + wikifyPlain("SiteTitle").htmlEncode() + "</title" + ">");
+	if(u)
+		s.push("<link>" + u.htmlEncode() + "</link>");
+	s.push("<description>" + wikifyPlain("SiteSubtitle").htmlEncode() + "</description>");
+	s.push("<language>" + config.locale + "</language>");
+	s.push("<copyright>Copyright " + d.getFullYear() + " " + config.options.txtUserName.htmlEncode() + "</copyright>");
+	s.push("<pubDate>" + d.toGMTString() + "</pubDate>");
+	s.push("<lastBuildDate>" + d.toGMTString() + "</lastBuildDate>");
+	s.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");
+	s.push("<generator>TiddlyWiki " + formatVersion() + "</generator>");
+	// The body
+	var tiddlers = store.getTiddlers("modified","excludeLists");
+	var n = config.numRssItems > tiddlers.length ? 0 : tiddlers.length-config.numRssItems;
+	for(var i=tiddlers.length-1; i>=n; i--) {
+		s.push("<item>\n" + tiddlerToRssItem(tiddlers[i],u) + "\n</item>");
+	}
+	// And footer
+	s.push("</channel>");
+	s.push("</rss>");
+	// Save it all
+	return s.join("\n");
+}
+
+//--
+//-- Filesystem code
+//--
+
+function convertUTF8ToUnicode(u)
+{
+	return config.browser.isOpera || !window.netscape ? manualConvertUTF8ToUnicode(u) : mozConvertUTF8ToUnicode(u);
+}
+
+function manualConvertUTF8ToUnicode(utf)
+{
+	var uni = utf;
+	var src = 0;
+	var dst = 0;
+	var b1, b2, b3;
+	var c;
+	while(src < utf.length) {
+		b1 = utf.charCodeAt(src++);
+		if(b1 < 0x80) {
+			dst++;
+		} else if(b1 < 0xE0) {
+			b2 = utf.charCodeAt(src++);
+			c = String.fromCharCode(((b1 & 0x1F) << 6) | (b2 & 0x3F));
+			uni = uni.substring(0,dst++).concat(c,utf.substr(src));
+		} else {
+			b2 = utf.charCodeAt(src++);
+			b3 = utf.charCodeAt(src++);
+			c = String.fromCharCode(((b1 & 0xF) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F));
+			uni = uni.substring(0,dst++).concat(c,utf.substr(src));
+		}
+	}
+	return uni;
+}
+
+function mozConvertUTF8ToUnicode(u)
+{
+	try {
+		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+		var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
+		converter.charset = "UTF-8";
+	} catch(ex) {
+		return manualConvertUTF8ToUnicode(u);
+	} // fallback
+	var s = converter.ConvertToUnicode(u);
+	var fin = converter.Finish();
+	return fin.length > 0 ? s+fin : s;
+}
+
+function convertUnicodeToFileFormat(s)
+{
+	return config.browser.isOpera || !window.netscape ? convertUnicodeToHtmlEntities(s) : mozConvertUnicodeToUTF8(s);
+}
+
+function convertUnicodeToHtmlEntities(s)
+{
+	var re = /[^\u0000-\u007F]/g;
+	return s.replace(re,function($0) {return "&#" + $0.charCodeAt(0).toString() + ";";});
+}
+
+function convertUnicodeToUTF8(s)
+{
+// return convertUnicodeToFileFormat to allow plugin migration
+	return convertUnicodeToFileFormat(s);
+}
+
+function manualConvertUnicodeToUTF8(s)
+{
+	return unescape(encodeURIComponent(s));
+}
+
+function mozConvertUnicodeToUTF8(s)
+{
+	try {
+		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+		var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
+		converter.charset = "UTF-8";
+	} catch(ex) {
+		return manualConvertUnicodeToUTF8(s);
+	} // fallback
+	var u = converter.ConvertFromUnicode(s);
+	var fin = converter.Finish();
+	return fin.length > 0 ? u + fin : u;
+}
+
+function convertUriToUTF8(uri,charSet)
+{
+	if(window.netscape == undefined || charSet == undefined || charSet == "")
+		return uri;
+	try {
+		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+		var converter = Components.classes["@mozilla.org/intl/utf8converterservice;1"].getService(Components.interfaces.nsIUTF8ConverterService);
+	} catch(ex) {
+		return uri;
+	}
+	return converter.convertURISpecToUTF8(uri,charSet);
+}
+
+function copyFile(dest,source)
+{
+	return config.browser.isIE ? ieCopyFile(dest,source) : false;
+}
+
+function saveFile(fileUrl,content)
+{
+	var r = mozillaSaveFile(fileUrl,content);
+	if(!r)
+		r = ieSaveFile(fileUrl,content);
+	if(!r)
+		r = javaSaveFile(fileUrl,content);
+	return r;
+}
+
+function loadFile(fileUrl)
+{
+	var r = mozillaLoadFile(fileUrl);
+	if((r == null) || (r == false))
+		r = ieLoadFile(fileUrl);
+	if((r == null) || (r == false))
+		r = javaLoadFile(fileUrl);
+	return r;
+}
+
+function ieCreatePath(path)
+{
+	try {
+		var fso = new ActiveXObject("Scripting.FileSystemObject");
+	} catch(ex) {
+		return null;
+	}
+
+	var pos = path.lastIndexOf("\\");
+	if(pos==-1)
+		pos = path.lastIndexOf("/");
+	if(pos!=-1)
+		path = path.substring(0,pos+1);
+
+	var scan = [path];
+	var parent = fso.GetParentFolderName(path);
+	while(parent && !fso.FolderExists(parent)) {
+		scan.push(parent);
+		parent = fso.GetParentFolderName(parent);
+	}
+
+	for(i=scan.length-1;i>=0;i--) {
+		if(!fso.FolderExists(scan[i])) {
+			fso.CreateFolder(scan[i]);
+		}
+	}
+	return true;
+}
+
+// Returns null if it can't do it, false if there's an error, true if it saved OK
+function ieSaveFile(filePath,content)
+{
+	ieCreatePath(filePath);
+	try {
+		var fso = new ActiveXObject("Scripting.FileSystemObject");
+	} catch(ex) {
+		return null;
+	}
+	var file = fso.OpenTextFile(filePath,2,-1,0);
+	file.Write(content);
+	file.Close();
+	return true;
+}
+
+// Returns null if it can't do it, false if there's an error, or a string of the content if successful
+function ieLoadFile(filePath)
+{
+	try {
+		var fso = new ActiveXObject("Scripting.FileSystemObject");
+		var file = fso.OpenTextFile(filePath,1);
+		var content = file.ReadAll();
+		file.Close();
+	} catch(ex) {
+		return null;
+	}
+	return content;
+}
+
+function ieCopyFile(dest,source)
+{
+	ieCreatePath(dest);
+	try {
+		var fso = new ActiveXObject("Scripting.FileSystemObject");
+		fso.GetFile(source).Copy(dest);
+	} catch(ex) {
+		return false;
+	}
+	return true;
+}
+
+// Returns null if it can't do it, false if there's an error, true if it saved OK
+function mozillaSaveFile(filePath,content)
+{
+	if(window.Components) {
+		try {
+			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+			var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+			file.initWithPath(filePath);
+			if(!file.exists())
+				file.create(0,0664);
+			var out = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
+			out.init(file,0x20|0x02,00004,null);
+			out.write(content,content.length);
+			out.flush();
+			out.close();
+			return true;
+		} catch(ex) {
+			return false;
+		}
+	}
+	return null;
+}
+
+// Returns null if it can't do it, false if there's an error, or a string of the content if successful
+function mozillaLoadFile(filePath)
+{
+	if(window.Components) {
+		try {
+			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+			var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+			file.initWithPath(filePath);
+			if(!file.exists())
+				return null;
+			var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
+			inputStream.init(file,0x01,00004,null);
+			var sInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
+			sInputStream.init(inputStream);
+			var contents = sInputStream.read(sInputStream.available());
+			sInputStream.close();
+			inputStream.close();
+			return contents;
+		} catch(ex) {
+			return false;
+		}
+	}
+	return null;
+}
+
+function javaUrlToFilename(url)
+{
+	var f = "//localhost";
+	if(url.indexOf(f) == 0)
+		return url.substring(f.length);
+	var i = url.indexOf(":");
+	return i > 0 ? url.substring(i-1) : url;
+}
+
+function javaSaveFile(filePath,content)
+{
+	try {
+		if(document.applets["TiddlySaver"])
+			return document.applets["TiddlySaver"].saveFile(javaUrlToFilename(filePath),"UTF-8",content);
+	} catch(ex) {
+	}
+	try {
+		var s = new java.io.PrintStream(new java.io.FileOutputStream(javaUrlToFilename(filePath)));
+		s.print(content);
+		s.close();
+	} catch(ex) {
+		return null;
+	}
+	return true;
+}
+
+function javaLoadFile(filePath)
+{
+	try {
+		if(document.applets["TiddlySaver"])
+			return String(document.applets["TiddlySaver"].loadFile(javaUrlToFilename(filePath),"UTF-8"));
+	} catch(ex) {
+	}
+	var content = [];
+	try {
+		var r = new java.io.BufferedReader(new java.io.FileReader(javaUrlToFilename(filePath)));
+		var line;
+		while((line = r.readLine()) != null)
+			content.push(new String(line));
+		r.close();
+	} catch(ex) {
+		return null;
+	}
+	return content.join("\n");
+}
+
+//--
+//-- Server adaptor base class
+//--
+
+function AdaptorBase()
+{
+	this.host = null;
+	this.store = null;
+	return this;
+}
+
+AdaptorBase.prototype.close = function()
+{
+	return true;
+};
+
+AdaptorBase.prototype.fullHostName = function(host)
+{
+	if(!host)
+		return '';
+	host = host.trim();
+	if(!host.match(/:\/\//))
+		host = 'http://' + host;
+	if(host.substr(host.length-1) == '/')
+		host = host.substr(0,host.length-1);
+	return host;
+};
+
+AdaptorBase.minHostName = function(host)
+{
+	return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : '';
+};
+
+AdaptorBase.prototype.setContext = function(context,userParams,callback)
+{
+	if(!context) context = {};
+	context.userParams = userParams;
+	if(callback) context.callback = callback;
+	context.adaptor = this;
+	if(!context.host)
+		context.host = this.host;
+	context.host = this.fullHostName(context.host);
+	if(!context.workspace)
+		context.workspace = this.workspace;
+	return context;
+};
+
+// Open the specified host
+AdaptorBase.prototype.openHost = function(host,context,userParams,callback)
+{
+	this.host = host;
+	context = this.setContext(context,userParams,callback);
+	context.status = true;
+	if(callback)
+		window.setTimeout(function() {context.callback(context,userParams);},10);
+	return true;
+};
+
+// Open the specified workspace
+AdaptorBase.prototype.openWorkspace = function(workspace,context,userParams,callback)
+{
+	this.workspace = workspace;
+	context = this.setContext(context,userParams,callback);
+	context.status = true;
+	if(callback)
+		window.setTimeout(function() {callback(context,userParams);},10);
+	return true;
+};
+
+//--
+//-- Server adaptor for talking to static TiddlyWiki files
+//--
+
+function FileAdaptor()
+{
+}
+
+FileAdaptor.prototype = new AdaptorBase();
+
+FileAdaptor.serverType = 'file';
+FileAdaptor.serverLabel = 'TiddlyWiki';
+
+FileAdaptor.loadTiddlyWikiCallback = function(status,context,responseText,url,xhr)
+{
+	context.status = status;
+	if(!status) {
+		context.statusText = "Error reading file";
+	} else {
+		context.adaptor.store = new TiddlyWiki();
+		if(!context.adaptor.store.importTiddlyWiki(responseText)) {
+			context.statusText = config.messages.invalidFileError.format([url]);
+			context.status = false;
+		}
+	}
+	context.complete(context,context.userParams);
+};
+
+// Get the list of workspaces on a given server
+FileAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
+{
+	context = this.setContext(context,userParams,callback);
+	context.workspaces = [{title:"(default)"}];
+	context.status = true;
+	if(callback)
+		window.setTimeout(function() {callback(context,userParams);},10);
+	return true;
+};
+
+// Gets the list of tiddlers within a given workspace
+FileAdaptor.prototype.getTiddlerList = function(context,userParams,callback,filter)
+{
+	context = this.setContext(context,userParams,callback);
+	if(!context.filter)
+		context.filter = filter;
+	context.complete = FileAdaptor.getTiddlerListComplete;
+	if(this.store) {
+		var ret = context.complete(context,context.userParams);
+	} else {
+		ret = loadRemoteFile(context.host,FileAdaptor.loadTiddlyWikiCallback,context);
+		if(typeof ret != "string")
+			ret = true;
+	}
+	return ret;
+};
+
+FileAdaptor.getTiddlerListComplete = function(context,userParams)
+{
+	if(context.status) {
+		if(context.filter) {
+			context.tiddlers = context.adaptor.store.filterTiddlers(context.filter);
+		} else {
+			context.tiddlers = [];
+			context.adaptor.store.forEachTiddler(function(title,tiddler) {context.tiddlers.push(tiddler);});
+		}
+		for(var i=0; i<context.tiddlers.length; i++) {
+			context.tiddlers[i].fields['server.type'] = FileAdaptor.serverType;
+			context.tiddlers[i].fields['server.host'] = AdaptorBase.minHostName(context.host);
+			context.tiddlers[i].fields['server.page.revision'] = context.tiddlers[i].modified.convertToYYYYMMDDHHMM();
+		}
+		context.status = true;
+	}
+	if(context.callback) {
+		window.setTimeout(function() {context.callback(context,userParams);},10);
+	}
+	return true;
+};
+
+FileAdaptor.prototype.generateTiddlerInfo = function(tiddler)
+{
+	var info = {};
+	info.uri = tiddler.fields['server.host'] + "#" + tiddler.title;
+	return info;
+};
+
+// Retrieve a tiddler from a given workspace on a given server
+FileAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
+{
+	context = this.setContext(context,userParams,callback);
+	context.title = title;
+	context.complete = FileAdaptor.getTiddlerComplete;
+	return context.adaptor.store ?
+		context.complete(context,context.userParams) :
+		loadRemoteFile(context.host,FileAdaptor.loadTiddlyWikiCallback,context);
+};
+
+FileAdaptor.getTiddlerComplete = function(context,userParams)
+{
+	var t = context.adaptor.store.fetchTiddler(context.title);
+	if(t) {
+		t.fields['server.type'] = FileAdaptor.serverType;
+		t.fields['server.host'] = AdaptorBase.minHostName(context.host);
+		t.fields['server.page.revision'] = t.modified.convertToYYYYMMDDHHMM();
+		context.tiddler = t;
+		context.status = true;
+	} else { //# tiddler does not exist in document
+		context.status = false;
+	}
+	if(context.allowSynchronous) {
+		context.isSynchronous = true;
+		context.callback(context,userParams);
+	} else {
+		window.setTimeout(function() {context.callback(context,userParams);},10);
+	}
+	return true;
+};
+
+FileAdaptor.prototype.close = function()
+{
+	delete this.store;
+	this.store = null;
+};
+
+config.adaptors[FileAdaptor.serverType] = FileAdaptor;
+
+config.defaultAdaptor = FileAdaptor.serverType;
+
+//--
+//-- HTTP request code
+//--
+
+function ajaxReq(args)
+{
+	if(window.Components && window.netscape && window.netscape.security && document.location.protocol.indexOf("http") == -1)
+		window.netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+	return jQuery.ajax(args);
+}
+
+//--
+//-- TiddlyWiki-specific utility functions
+//--
+
+// Returns TiddlyWiki version string
+function formatVersion(v)
+{
+	v = v || version;
+	return v.major + "." + v.minor + "." + v.revision +
+		(v.alpha ? " (alpha " + v.alpha + ")" : "") +
+		(v.beta ? " (beta " + v.beta + ")" : "");
+}
+
+function compareVersions(v1,v2)
+{
+	var a = ["major","minor","revision"];
+	for(var i = 0; i<a.length; i++) {
+		var x1 = v1[a[i]] || 0;
+		var x2 = v2[a[i]] || 0;
+		if(x1<x2)
+			return 1;
+		if(x1>x2)
+			return -1;
+	}
+	x1 = v1.beta || 9999;
+	x2 = v2.beta || 9999;
+	if(x1<x2)
+		return 1;
+	return x1 > x2 ? -1 : 0;
+}
+
+function createTiddlyButton(parent,text,tooltip,action,className,id,accessKey,attribs)
+{
+	var btn = document.createElement("a");
+	if(action) {
+		btn.onclick = action;
+		btn.setAttribute("href","javascript:;");
+	}
+	if(tooltip)
+		btn.setAttribute("title",tooltip);
+	if(text)
+		btn.appendChild(document.createTextNode(text));
+	btn.className = className || "button";
+	if(id)
+		btn.id = id;
+	if(attribs) {
+		for(var i in attribs) {
+			btn.setAttribute(i,attribs[i]);
+		}
+	}
+	if(parent)
+		parent.appendChild(btn);
+	if(accessKey)
+		btn.setAttribute("accessKey",accessKey);
+	return btn;
+}
+
+function createTiddlyLink(place,title,includeText,className,isStatic,linkedFromTiddler,noToggle)
+{
+	var text = includeText ? title : null;
+	var i = getTiddlyLinkInfo(title,className);
+	var btn = isStatic ? createExternalLink(place,store.getTiddlerText("SiteUrl",null) + "#" + title) : createTiddlyButton(place,text,i.subTitle,onClickTiddlerLink,i.classes);
+	if(isStatic)
+		btn.className += ' ' + className;
+	btn.setAttribute("refresh","link");
+	btn.setAttribute("tiddlyLink",title);
+	if(noToggle)
+		btn.setAttribute("noToggle","true");
+	if(linkedFromTiddler) {
+		var fields = linkedFromTiddler.getInheritedFields();
+		if(fields)
+			btn.setAttribute("tiddlyFields",fields);
+	}
+	return btn;
+}
+
+function refreshTiddlyLink(e,title)
+{
+	var i = getTiddlyLinkInfo(title,e.className);
+	e.className = i.classes;
+	e.title = i.subTitle;
+}
+
+function getTiddlyLinkInfo(title,currClasses)
+{
+	var classes = currClasses ? currClasses.split(" ") : [];
+	classes.pushUnique("tiddlyLink");
+	var tiddler = store.fetchTiddler(title);
+	var subTitle;
+	if(tiddler) {
+		subTitle = tiddler.getSubtitle();
+		classes.pushUnique("tiddlyLinkExisting");
+		classes.remove("tiddlyLinkNonExisting");
+		classes.remove("shadow");
+	} else {
+		classes.remove("tiddlyLinkExisting");
+		classes.pushUnique("tiddlyLinkNonExisting");
+		if(store.isShadowTiddler(title)) {
+			subTitle = config.messages.shadowedTiddlerToolTip.format([title]);
+			classes.pushUnique("shadow");
+		} else {
+			subTitle = config.messages.undefinedTiddlerToolTip.format([title]);
+			classes.remove("shadow");
+		}
+	}
+	if(typeof config.annotations[title]=="string")
+		subTitle = config.annotations[title];
+	return {classes: classes.join(" "),subTitle: subTitle};
+}
+
+function createExternalLink(place,url,label)
+{
+	var link = document.createElement("a");
+	link.className = "externalLink";
+	link.href = url;
+	link.title = config.messages.externalLinkTooltip.format([url]);
+	if(config.options.chkOpenInNewWindow)
+		link.target = "_blank";
+	place.appendChild(link);
+	if(label)
+		createTiddlyText(link, label);
+	return link;
+}
+
+// Event handler for clicking on a tiddly link
+function onClickTiddlerLink(ev)
+{
+	var e = ev || window.event;
+	var target = resolveTarget(e);
+	var link = target;
+	var title = null;
+	var fields = null;
+	var noToggle = null;
+	do {
+		title = link.getAttribute("tiddlyLink");
+		fields = link.getAttribute("tiddlyFields");
+		noToggle = link.getAttribute("noToggle");
+		link = link.parentNode;
+	} while(title == null && link != null);
+	if(!store.isShadowTiddler(title)) {
+		var f = fields ? fields.decodeHashMap() : {};
+		fields = String.encodeHashMap(merge(f,config.defaultCustomFields,true));
+	}
+	if(title) {
+		var toggling = e.metaKey || e.ctrlKey;
+		if(config.options.chkToggleLinks)
+			toggling = !toggling;
+		if(noToggle)
+			toggling = false;
+		if(store.getTiddler(title))
+			fields = null;
+		story.displayTiddler(target,title,null,true,null,fields,toggling);
+	}
+	clearMessage();
+	return false;
+}
+
+// Create a button for a tag with a popup listing all the tiddlers that it tags
+function createTagButton(place,tag,excludeTiddler,title,tooltip)
+{
+	var btn = createTiddlyButton(place,title||tag,(tooltip||config.views.wikified.tag.tooltip).format([tag]),onClickTag);
+	btn.setAttribute("tag",tag);
+	if(excludeTiddler)
+		btn.setAttribute("tiddler",excludeTiddler);
+	return btn;
+}
+
+// Event handler for clicking on a tiddler tag
+function onClickTag(ev)
+{
+	var e = ev || window.event;
+	var popup = Popup.create(this);
+	addClass(popup,"taggedTiddlerList");
+	var tag = this.getAttribute("tag");
+	var title = this.getAttribute("tiddler");
+	if(popup && tag) {
+		var tagged = tag.indexOf("[")==-1 ? store.getTaggedTiddlers(tag) : store.filterTiddlers(tag);
+		var sortby = this.getAttribute("sortby");
+		if(sortby&&sortby.length) {
+			store.sortTiddlers(tagged,sortby);
+		}
+		var titles = [];
+		var li,r;
+		for(r=0;r<tagged.length;r++) {
+			if(tagged[r].title != title)
+				titles.push(tagged[r].title);
+		}
+		var lingo = config.views.wikified.tag;
+		if(titles.length > 0) {
+			var openAll = createTiddlyButton(createTiddlyElement(popup,"li"),lingo.openAllText.format([tag]),lingo.openAllTooltip,onClickTagOpenAll);
+			openAll.setAttribute("tag",tag);
+			openAll.setAttribute("sortby",sortby);
+			createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
+			for(r=0; r<titles.length; r++) {
+				createTiddlyLink(createTiddlyElement(popup,"li"),titles[r],true);
+			}
+		} else {
+			createTiddlyElement(popup,"li",null,"disabled",lingo.popupNone.format([tag]));
+		}
+		createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
+		var h = createTiddlyLink(createTiddlyElement(popup,"li"),tag,false);
+		createTiddlyText(h,lingo.openTag.format([tag]));
+	}
+	Popup.show();
+	e.cancelBubble = true;
+	if(e.stopPropagation) e.stopPropagation();
+	return false;
+}
+
+// Event handler for 'open all' on a tiddler popup
+function onClickTagOpenAll(ev)
+{
+	var tiddlers = store.getTaggedTiddlers(this.getAttribute("tag"));
+	var sortby = this.getAttribute("sortby");
+	if(sortby&&sortby.length) {
+		store.sortTiddlers(tiddlers,sortby);
+	}
+	story.displayTiddlers(this,tiddlers);
+	return false;
+}
+
+function onClickError(ev)
+{
+	var e = ev || window.event;
+	var popup = Popup.create(this);
+	var lines = this.getAttribute("errorText").split("\n");
+	for(var t=0; t<lines.length; t++)
+		createTiddlyElement(popup,"li",null,null,lines[t]);
+	Popup.show();
+	e.cancelBubble = true;
+	if(e.stopPropagation) e.stopPropagation();
+	return false;
+}
+
+function createTiddlyDropDown(place,onchange,options,defaultValue)
+{
+	var sel = createTiddlyElement(place,"select");
+	sel.onchange = onchange;
+	for(var t=0; t<options.length; t++) {
+		var e = createTiddlyElement(sel,"option",null,null,options[t].caption);
+		e.value = options[t].name;
+		if(options[t].name == defaultValue)
+			e.selected = true;
+	}
+	return sel;
+}
+
+function createTiddlyPopup(place,caption,tooltip,tiddler)
+{
+	if(tiddler.text) {
+		createTiddlyLink(place,caption,true);
+		var btn = createTiddlyButton(place,glyph("downArrow"),tooltip,onClickTiddlyPopup,"tiddlerPopupButton");
+		btn.tiddler = tiddler;
+	} else {
+		createTiddlyText(place,caption);
+	}
+}
+
+function onClickTiddlyPopup(ev)
+{
+	var e = ev || window.event;
+	var tiddler = this.tiddler;
+	if(tiddler.text) {
+		var popup = Popup.create(this,"div","popupTiddler");
+		wikify(tiddler.text,popup,null,tiddler);
+		Popup.show();
+	}
+	if(e) e.cancelBubble = true;
+	if(e && e.stopPropagation) e.stopPropagation();
+	return false;
+}
+
+function createTiddlyError(place,title,text)
+{
+	var btn = createTiddlyButton(place,title,null,onClickError,"errorButton");
+	if(text) btn.setAttribute("errorText",text);
+}
+
+function merge(dst,src,preserveExisting)
+{
+	for(var i in src) {
+		if(!preserveExisting || dst[i] === undefined)
+			dst[i] = src[i];
+	}
+	return dst;
+}
+
+// Returns a string containing the description of an exception, optionally prepended by a message
+function exceptionText(e,message)
+{
+	var s = e.description || e.toString();
+	return message ? "%0:\n%1".format([message,s]) : s;
+}
+
+// Displays an alert of an exception description with optional message
+function showException(e,message)
+{
+	alert(exceptionText(e,message));
+}
+
+function alertAndThrow(m)
+{
+	alert(m);
+	throw(m);
+}
+
+function glyph(name)
+{
+	var g = config.glyphs;
+	var b = g.currBrowser;
+	if(b == null) {
+		b = 0;
+		while(!g.browsers[b]() && b < g.browsers.length-1)
+			b++;
+		g.currBrowser = b;
+	}
+	if(!g.codes[name])
+		return "";
+	return g.codes[name][b];
+}
+
+if(!window.console) {
+	console = {tiddlywiki:true,log:function(message) {displayMessage(message);}};
+}
+
+//-
+//- Animation engine
+//-
+
+function Animator()
+{
+	this.running = 0; // Incremented at start of each animation, decremented afterwards. If zero, the interval timer is disabled
+	this.timerID = 0; // ID of the timer used for animating
+	this.animations = []; // List of animations in progress
+	return this;
+}
+
+// Start animation engine
+Animator.prototype.startAnimating = function() //# Variable number of arguments
+{
+	for(var t=0; t<arguments.length; t++)
+		this.animations.push(arguments[t]);
+	if(this.running == 0) {
+		var me = this;
+		this.timerID = window.setInterval(function() {me.doAnimate(me);},10);
+	}
+	this.running += arguments.length;
+};
+
+// Perform an animation engine tick, calling each of the known animation modules
+Animator.prototype.doAnimate = function(me)
+{
+	var a = 0;
+	while(a < me.animations.length) {
+		var animation = me.animations[a];
+		if(animation.tick()) {
+			a++;
+		} else {
+			me.animations.splice(a,1);
+			if(--me.running == 0)
+				window.clearInterval(me.timerID);
+		}
+	}
+};
+
+Animator.slowInSlowOut = function(progress)
+{
+	return(1-((Math.cos(progress * Math.PI)+1)/2));
+};
+
+//--
+//-- Morpher animation
+//--
+
+// Animate a set of properties of an element
+function Morpher(element,duration,properties,callback)
+{
+	this.element = element;
+	this.duration = duration;
+	this.properties = properties;
+	this.startTime = new Date();
+	this.endTime = Number(this.startTime) + duration;
+	this.callback = callback;
+	this.tick();
+	return this;
+}
+
+Morpher.prototype.assignStyle = function(element,style,value)
+{
+	switch(style) {
+	case "-tw-vertScroll":
+		window.scrollTo(findScrollX(),value);
+		break;
+	case "-tw-horizScroll":
+		window.scrollTo(value,findScrollY());
+		break;
+	default:
+		element.style[style] = value;
+		break;
+	}
+};
+
+Morpher.prototype.stop = function()
+{
+	for(var t=0; t<this.properties.length; t++) {
+		var p = this.properties[t];
+		if(p.atEnd !== undefined) {
+			this.assignStyle(this.element,p.style,p.atEnd);
+		}
+	}
+	if(this.callback)
+		this.callback(this.element,this.properties);
+};
+
+Morpher.prototype.tick = function()
+{
+	var currTime = Number(new Date());
+	var progress = Animator.slowInSlowOut(Math.min(1,(currTime-this.startTime)/this.duration));
+	for(var t=0; t<this.properties.length; t++) {
+		var p = this.properties[t];
+		if(p.start !== undefined && p.end !== undefined) {
+			var template = p.template || "%0";
+			switch(p.format) {
+			case undefined:
+			case "style":
+				var v = p.start + (p.end-p.start) * progress;
+				this.assignStyle(this.element,p.style,template.format([v]));
+				break;
+			case "color":
+				break;
+			}
+		}
+	}
+	if(currTime >= this.endTime) {
+		this.stop();
+		return false;
+	}
+	return true;
+};
+
+//--
+//-- Zoomer animation
+//--
+
+function Zoomer(text,startElement,targetElement,unused)
+{
+	var e = createTiddlyElement(document.body,"div",null,"zoomer");
+	createTiddlyElement(e,"div",null,null,text);
+	var winWidth = findWindowWidth();
+	var winHeight = findWindowHeight();
+	var p = [
+		{style: 'left', start: findPosX(startElement), end: findPosX(targetElement), template: '%0px'},
+		{style: 'top', start: findPosY(startElement), end: findPosY(targetElement), template: '%0px'},
+		{style: 'width', start: Math.min(startElement.scrollWidth,winWidth), end: Math.min(targetElement.scrollWidth,winWidth), template: '%0px', atEnd: 'auto'},
+		{style: 'height', start: Math.min(startElement.scrollHeight,winHeight), end: Math.min(targetElement.scrollHeight,winHeight), template: '%0px', atEnd: 'auto'},
+		{style: 'fontSize', start: 8, end: 24, template: '%0pt'}
+	];
+	var c = function(element,properties) {removeNode(element);};
+	return new Morpher(e,config.animDuration,p,c);
+}
+
+//--
+//-- Scroller animation
+//--
+
+function Scroller(targetElement)
+{
+	var p = [{style: '-tw-vertScroll', start: findScrollY(), end: ensureVisible(targetElement)}];
+	return new Morpher(targetElement,config.animDuration,p);
+}
+
+//--
+//-- Slider animation
+//--
+
+// deleteMode - "none", "all" [delete target element and it's children], [only] "children" [but not the target element]
+function Slider(element,opening,unused,deleteMode)
+{
+	element.style.overflow = 'hidden';
+	if(opening)
+		element.style.height = '0px'; // Resolves a Firefox flashing bug
+	element.style.display = 'block';
+	var left = findPosX(element);
+	var width = element.scrollWidth;
+	var height = element.scrollHeight;
+	var winWidth = findWindowWidth();
+	var p = [];
+	var c = null;
+	if(opening) {
+		p.push({style: 'height', start: 0, end: height, template: '%0px', atEnd: 'auto'});
+		p.push({style: 'opacity', start: 0, end: 1, template: '%0'});
+		p.push({style: 'filter', start: 0, end: 100, template: 'alpha(opacity:%0)'});
+	} else {
+		p.push({style: 'height', start: height, end: 0, template: '%0px'});
+		p.push({style: 'display', atEnd: 'none'});
+		p.push({style: 'opacity', start: 1, end: 0, template: '%0'});
+		p.push({style: 'filter', start: 100, end: 0, template: 'alpha(opacity:%0)'});
+		switch(deleteMode) {
+		case "all":
+			c = function(element,properties) {removeNode(element);};
+			break;
+		case "children":
+			c = function(element,properties) {removeChildren(element);};
+			break;
+		}
+	}
+	return new Morpher(element,config.animDuration,p,c);
+}
+
+//--
+//-- Popup menu
+//--
+
+var Popup = {
+	stack: [] // Array of objects with members root: and popup:
+	};
+
+Popup.create = function(root,elem,className)
+{
+	var stackPosition = this.find(root,"popup");
+	Popup.remove(stackPosition+1);
+	var popup = createTiddlyElement(document.body,elem || "ol","popup",className || "popup");
+	popup.stackPosition = stackPosition;
+	Popup.stack.push({root: root, popup: popup});
+	return popup;
+};
+
+Popup.onDocumentClick = function(ev)
+{
+	var e = ev || window.event;
+	if(e.eventPhase == undefined)
+		Popup.remove();
+	else if(e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET)
+		Popup.remove();
+	return true;
+};
+
+Popup.show = function(valign,halign,offset)
+{
+	var curr = Popup.stack[Popup.stack.length-1];
+	this.place(curr.root,curr.popup,valign,halign,offset);
+	addClass(curr.root,"highlight");
+	if(config.options.chkAnimate && anim && typeof Scroller == "function")
+		anim.startAnimating(new Scroller(curr.popup));
+	else
+		window.scrollTo(0,ensureVisible(curr.popup));
+};
+
+Popup.place = function(root,popup,valign,halign,offset)
+{
+	if(!offset)
+		var offset = {x:0,y:0};
+	if(popup.stackPosition >= 0 && !valign && !halign) {
+		offset.x = offset.x + root.offsetWidth;
+	} else {
+		offset.x = (halign == "right") ? offset.x + root.offsetWidth : offset.x;
+		offset.y = (valign == "top") ? offset.y : offset.y + root.offsetHeight;
+	}
+	var rootLeft = findPosX(root);
+	var rootTop = findPosY(root);
+	var popupLeft = rootLeft + offset.x;
+	var popupTop = rootTop + offset.y;
+	var winWidth = findWindowWidth();
+	if(popup.offsetWidth > winWidth*0.75)
+		popup.style.width = winWidth*0.75 + "px";
+	var popupWidth = popup.offsetWidth;
+	var scrollWidth = winWidth - document.body.offsetWidth;
+	if(popupLeft + popupWidth > winWidth - scrollWidth - 1) {
+		if(halign == "right")
+			popupLeft = popupLeft - root.offsetWidth - popupWidth;
+		else
+			popupLeft = winWidth - popupWidth - scrollWidth - 1;
+	}
+	popup.style.left = popupLeft + "px";
+	popup.style.top = popupTop + "px";
+	popup.style.display = "block";
+};
+
+Popup.find = function(e)
+{
+	var pos = -1;
+	for (var t=this.stack.length-1; t>=0; t--) {
+		if(isDescendant(e,this.stack[t].popup))
+			pos = t;
+	}
+	return pos;
+};
+
+Popup.remove = function(pos)
+{
+	if(!pos) var pos = 0;
+	if(Popup.stack.length > pos) {
+		Popup.removeFrom(pos);
+	}
+};
+
+Popup.removeFrom = function(from)
+{
+	for(var t=Popup.stack.length-1; t>=from; t--) {
+		var p = Popup.stack[t];
+		removeClass(p.root,"highlight");
+		removeNode(p.popup);
+	}
+	Popup.stack = Popup.stack.slice(0,from);
+};
+
+//--
+//-- Wizard support
+//--
+
+function Wizard(elem)
+{
+	if(elem) {
+		this.formElem = findRelated(elem,"wizard","className");
+		this.bodyElem = findRelated(this.formElem.firstChild,"wizardBody","className","nextSibling");
+		this.footElem = findRelated(this.formElem.firstChild,"wizardFooter","className","nextSibling");
+	} else {
+		this.formElem = null;
+		this.bodyElem = null;
+		this.footElem = null;
+	}
+}
+
+Wizard.prototype.setValue = function(name,value)
+{
+	if(this.formElem)
+		this.formElem[name] = value;
+};
+
+Wizard.prototype.getValue = function(name)
+{
+	return this.formElem ? this.formElem[name] : null;
+};
+
+Wizard.prototype.createWizard = function(place,title)
+{
+	this.formElem = createTiddlyElement(place,"form",null,"wizard");
+	createTiddlyElement(this.formElem,"h1",null,null,title);
+	this.bodyElem = createTiddlyElement(this.formElem,"div",null,"wizardBody");
+	this.footElem = createTiddlyElement(this.formElem,"div",null,"wizardFooter");
+};
+
+Wizard.prototype.clear = function()
+{
+	removeChildren(this.bodyElem);
+};
+
+Wizard.prototype.setButtons = function(buttonInfo,status)
+{
+	removeChildren(this.footElem);
+	for(var t=0; t<buttonInfo.length; t++) {
+		createTiddlyButton(this.footElem,buttonInfo[t].caption,buttonInfo[t].tooltip,buttonInfo[t].onClick);
+		insertSpacer(this.footElem);
+		}
+	if(typeof status == "string") {
+		createTiddlyElement(this.footElem,"span",null,"status",status);
+	}
+};
+
+Wizard.prototype.addStep = function(stepTitle,html)
+{
+	removeChildren(this.bodyElem);
+	var w = createTiddlyElement(this.bodyElem,"div");
+	createTiddlyElement(w,"h2",null,null,stepTitle);
+	var step = createTiddlyElement(w,"div",null,"wizardStep");
+	step.innerHTML = html;
+	applyHtmlMacros(step,tiddler);
+};
+
+Wizard.prototype.getElement = function(name)
+{
+	return this.formElem.elements[name];
+};
+
+//--
+//-- ListView gadget
+//--
+
+var ListView = {};
+
+// Create a listview
+ListView.create = function(place,listObject,listTemplate,callback,className)
+{
+	var table = createTiddlyElement(place,"table",null,className || "listView twtable");
+	var thead = createTiddlyElement(table,"thead");
+	var r = createTiddlyElement(thead,"tr");
+	for(var t=0; t<listTemplate.columns.length; t++) {
+		var columnTemplate = listTemplate.columns[t];
+		var c = createTiddlyElement(r,"th");
+		var colType = ListView.columnTypes[columnTemplate.type];
+		if(colType && colType.createHeader) {
+			colType.createHeader(c,columnTemplate,t);
+			if(columnTemplate.className)
+				addClass(c,columnTemplate.className);
+		}
+	}
+	var tbody = createTiddlyElement(table,"tbody");
+	for(var rc=0; rc<listObject.length; rc++) {
+		var rowObject = listObject[rc];
+		r = createTiddlyElement(tbody,"tr");
+		for(c=0; c<listTemplate.rowClasses.length; c++) {
+			if(rowObject[listTemplate.rowClasses[c].field])
+				addClass(r,listTemplate.rowClasses[c].className);
+		}
+		rowObject.rowElement = r;
+		rowObject.colElements = {};
+		for(var cc=0; cc<listTemplate.columns.length; cc++) {
+			c = createTiddlyElement(r,"td");
+			columnTemplate = listTemplate.columns[cc];
+			var field = columnTemplate.field;
+			colType = ListView.columnTypes[columnTemplate.type];
+			if(colType && colType.createItem) {
+				colType.createItem(c,rowObject,field,columnTemplate,cc,rc);
+				if(columnTemplate.className)
+					addClass(c,columnTemplate.className);
+			}
+			rowObject.colElements[field] = c;
+		}
+	}
+	if(callback && listTemplate.actions)
+		createTiddlyDropDown(place,ListView.getCommandHandler(callback),listTemplate.actions);
+	if(callback && listTemplate.buttons) {
+		for(t=0; t<listTemplate.buttons.length; t++) {
+			var a = listTemplate.buttons[t];
+			if(a && a.name != "")
+				createTiddlyButton(place,a.caption,null,ListView.getCommandHandler(callback,a.name,a.allowEmptySelection));
+		}
+	}
+	return table;
+};
+
+ListView.getCommandHandler = function(callback,name,allowEmptySelection)
+{
+	return function(e) {
+		var view = findRelated(this,"TABLE",null,"previousSibling");
+		var tiddlers = [];
+		ListView.forEachSelector(view,function(e,rowName) {
+					if(e.checked)
+						tiddlers.push(rowName);
+					});
+		if(tiddlers.length == 0 && !allowEmptySelection) {
+			alert(config.messages.nothingSelected);
+		} else {
+			if(this.nodeName.toLowerCase() == "select") {
+				callback(view,this.value,tiddlers);
+				this.selectedIndex = 0;
+			} else {
+				callback(view,name,tiddlers);
+			}
+		}
+	};
+};
+
+// Invoke a callback for each selector checkbox in the listview
+ListView.forEachSelector = function(view,callback)
+{
+	var checkboxes = view.getElementsByTagName("input");
+	var hadOne = false;
+	for(var t=0; t<checkboxes.length; t++) {
+		var cb = checkboxes[t];
+		if(cb.getAttribute("type") == "checkbox") {
+			var rn = cb.getAttribute("rowName");
+			if(rn) {
+				callback(cb,rn);
+				hadOne = true;
+			}
+		}
+	}
+	return hadOne;
+};
+
+ListView.getSelectedRows = function(view)
+{
+	var rowNames = [];
+	ListView.forEachSelector(view,function(e,rowName) {
+				if(e.checked)
+					rowNames.push(rowName);
+				});
+	return rowNames;
+};
+
+ListView.columnTypes = {};
+
+ListView.columnTypes.String = {
+	createHeader: function(place,columnTemplate,col)
+		{
+			createTiddlyText(place,columnTemplate.title);
+		},
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			var v = listObject[field];
+			if(v != undefined)
+				createTiddlyText(place,v);
+		}
+};
+
+ListView.columnTypes.WikiText = {
+	createHeader: ListView.columnTypes.String.createHeader,
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			var v = listObject[field];
+			if(v != undefined)
+				wikify(v,place,null,null);
+		}
+};
+
+ListView.columnTypes.Tiddler = {
+	createHeader: ListView.columnTypes.String.createHeader,
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			var v = listObject[field];
+			if(v != undefined && v.title)
+				createTiddlyPopup(place,v.title,config.messages.listView.tiddlerTooltip,v);
+		}
+};
+
+ListView.columnTypes.Size = {
+	createHeader: ListView.columnTypes.String.createHeader,
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			var v = listObject[field];
+			if(v != undefined) {
+				var t = 0;
+				while(t<config.messages.sizeTemplates.length-1 && v<config.messages.sizeTemplates[t].unit)
+					t++;
+				createTiddlyText(place,config.messages.sizeTemplates[t].template.format([Math.round(v/config.messages.sizeTemplates[t].unit)]));
+			}
+		}
+};
+
+ListView.columnTypes.Link = {
+	createHeader: ListView.columnTypes.String.createHeader,
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			var v = listObject[field];
+			var c = columnTemplate.text;
+			if(v != undefined)
+				createExternalLink(place,v,c || v);
+		}
+};
+
+ListView.columnTypes.Date = {
+	createHeader: ListView.columnTypes.String.createHeader,
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			var v = listObject[field];
+			if(v != undefined)
+				createTiddlyText(place,v.formatString(columnTemplate.dateFormat));
+		}
+};
+
+ListView.columnTypes.StringList = {
+	createHeader: ListView.columnTypes.String.createHeader,
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			var v = listObject[field];
+			if(v != undefined) {
+				for(var t=0; t<v.length; t++) {
+					createTiddlyText(place,v[t]);
+					createTiddlyElement(place,"br");
+				}
+			}
+		}
+};
+
+ListView.columnTypes.Selector = {
+	createHeader: function(place,columnTemplate,col)
+		{
+			createTiddlyCheckbox(place,null,false,this.onHeaderChange);
+		},
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			var e = createTiddlyCheckbox(place,null,listObject[field],null);
+			e.setAttribute("rowName",listObject[columnTemplate.rowName]);
+		},
+	onHeaderChange: function(e)
+		{
+			var state = this.checked;
+			var view = findRelated(this,"TABLE");
+			if(!view)
+				return;
+			ListView.forEachSelector(view,function(e,rowName) {
+								e.checked = state;
+							});
+		}
+};
+
+ListView.columnTypes.Tags = {
+	createHeader: ListView.columnTypes.String.createHeader,
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			var tags = listObject[field];
+			createTiddlyText(place,String.encodeTiddlyLinkList(tags));
+		}
+};
+
+ListView.columnTypes.Boolean = {
+	createHeader: ListView.columnTypes.String.createHeader,
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			if(listObject[field] == true)
+				createTiddlyText(place,columnTemplate.trueText);
+			if(listObject[field] == false)
+				createTiddlyText(place,columnTemplate.falseText);
+		}
+};
+
+ListView.columnTypes.TagCheckbox = {
+	createHeader: ListView.columnTypes.String.createHeader,
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			var e = createTiddlyCheckbox(place,null,listObject[field],this.onChange);
+			e.setAttribute("tiddler",listObject.title);
+			e.setAttribute("tag",columnTemplate.tag);
+		},
+	onChange : function(e)
+		{
+			var tag = this.getAttribute("tag");
+			var tiddler = this.getAttribute("tiddler");
+			store.setTiddlerTag(tiddler,this.checked,tag);
+		}
+};
+
+ListView.columnTypes.TiddlerLink = {
+	createHeader: ListView.columnTypes.String.createHeader,
+	createItem: function(place,listObject,field,columnTemplate,col,row)
+		{
+			var v = listObject[field];
+			if(v != undefined) {
+				var link = createTiddlyLink(place,listObject[columnTemplate.tiddlerLink],false,null);
+				createTiddlyText(link,listObject[field]);
+			}
+		}
+};
+
+//--
+//-- Augmented methods for the JavaScript Number(), Array(), String() and Date() objects
+//--
+
+// Clamp a number to a range
+Number.prototype.clamp = function(min,max)
+{
+	var c = this;
+	if(c < min)
+		c = min;
+	if(c > max)
+		c = max;
+	return Number(c);
+};
+
+// Add indexOf function if browser does not support it
+if(!Array.indexOf) {
+Array.prototype.indexOf = function(item,from)
+{
+	if(!from)
+		from = 0;
+	for(var i=from; i<this.length; i++) {
+		if(this[i] === item)
+			return i;
+	}
+	return -1;
+};}
+
+// Find an entry in a given field of the members of an array
+Array.prototype.findByField = function(field,value)
+{
+	for(var t=0; t<this.length; t++) {
+		if(this[t][field] === value)
+			return t;
+	}
+	return null;
+};
+
+// Return whether an entry exists in an array
+Array.prototype.contains = function(item)
+{
+	return this.indexOf(item) != -1;
+};
+
+// Adds, removes or toggles a particular value within an array
+//  value - value to add
+//  mode - +1 to add value, -1 to remove value, 0 to toggle it
+Array.prototype.setItem = function(value,mode)
+{
+	var p = this.indexOf(value);
+	if(mode == 0)
+		mode = (p == -1) ? +1 : -1;
+	if(mode == +1) {
+		if(p == -1)
+			this.push(value);
+	} else if(mode == -1) {
+		if(p != -1)
+			this.splice(p,1);
+	}
+};
+
+// Return whether one of a list of values exists in an array
+Array.prototype.containsAny = function(items)
+{
+	for(var i=0; i<items.length; i++) {
+		if(this.indexOf(items[i]) != -1)
+			return true;
+	}
+	return false;
+};
+
+// Return whether all of a list of values exists in an array
+Array.prototype.containsAll = function(items)
+{
+	for(var i = 0; i<items.length; i++) {
+		if(this.indexOf(items[i]) == -1)
+			return false;
+	}
+	return true;
+};
+
+// Push a new value into an array only if it is not already present in the array. If the optional unique parameter is false, it reverts to a normal push
+Array.prototype.pushUnique = function(item,unique)
+{
+	if(unique === false) {
+		this.push(item);
+	} else {
+		if(this.indexOf(item) == -1)
+			this.push(item);
+	}
+};
+
+Array.prototype.remove = function(item)
+{
+	var p = this.indexOf(item);
+	if(p != -1)
+		this.splice(p,1);
+};
+
+if(!Array.prototype.map) {
+Array.prototype.map = function(fn,thisObj)
+{
+	var scope = thisObj || window;
+	var a = [];
+	for(var i=0, j=this.length; i < j; ++i) {
+		a.push(fn.call(scope,this[i],i,this));
+	}
+	return a;
+};}
+
+// Get characters from the right end of a string
+String.prototype.right = function(n)
+{
+	return n < this.length ? this.slice(this.length-n) : this;
+};
+
+// Trim whitespace from both ends of a string
+String.prototype.trim = function()
+{
+	return this.replace(/^\s*|\s*$/g,"");
+};
+
+// Convert a string from a CSS style property name to a JavaScript style name ("background-color" -> "backgroundColor")
+String.prototype.unDash = function()
+{
+	var s = this.split("-");
+	if(s.length > 1) {
+		for(var t=1; t<s.length; t++)
+			s[t] = s[t].substr(0,1).toUpperCase() + s[t].substr(1);
+	}
+	return s.join("");
+};
+
+// Substitute substrings from an array into a format string that includes '%1'-type specifiers
+String.prototype.format = function(substrings)
+{
+	var subRegExp = /(?:%(\d+))/mg;
+	var currPos = 0;
+	var r = [];
+	do {
+		var match = subRegExp.exec(this);
+		if(match && match[1]) {
+			if(match.index > currPos)
+				r.push(this.substring(currPos,match.index));
+			r.push(substrings[parseInt(match[1])]);
+			currPos = subRegExp.lastIndex;
+		}
+	} while(match);
+	if(currPos < this.length)
+		r.push(this.substring(currPos,this.length));
+	return r.join("");
+};
+
+// Escape any special RegExp characters with that character preceded by a backslash
+String.prototype.escapeRegExp = function()
+{
+	var s = "\\^$*+?()=!|,{}[].";
+	var c = this;
+	for(var t=0; t<s.length; t++)
+		c = c.replace(new RegExp("\\" + s.substr(t,1),"g"),"\\" + s.substr(t,1));
+	return c;
+};
+
+// Convert "\" to "\s", newlines to "\n" (and remove carriage returns)
+String.prototype.escapeLineBreaks = function()
+{
+	return this.replace(/\\/mg,"\\s").replace(/\n/mg,"\\n").replace(/\r/mg,"");
+};
+
+// Convert "\n" to newlines, "\b" to " ", "\s" to "\" (and remove carriage returns)
+String.prototype.unescapeLineBreaks = function()
+{
+	return this.replace(/\\n/mg,"\n").replace(/\\b/mg," ").replace(/\\s/mg,"\\").replace(/\r/mg,"");
+};
+
+// Convert & to "&", < to "<", > to ">" and " to """
+String.prototype.htmlEncode = function()
+{
+	return this.replace(/&/mg,"&").replace(/</mg,"<").replace(/>/mg,">").replace(/\"/mg,""");
+};
+
+// Convert "&" to &, "<" to <, ">" to > and """ to "
+String.prototype.htmlDecode = function()
+{
+	return this.replace(/</mg,"<").replace(/>/mg,">").replace(/"/mg,"\"").replace(/&/mg,"&");
+};
+
+// Parse a space-separated string of name:value parameters
+// The result is an array of objects:
+//   result[0] = object with a member for each parameter name, value of that member being an array of values
+//   result[1..n] = one object for each parameter, with 'name' and 'value' members
+String.prototype.parseParams = function(defaultName,defaultValue,allowEval,noNames,cascadeDefaults)
+{
+	var parseToken = function(match,p) {
+		var n;
+		if(match[p]) // Double quoted
+			n = match[p];
+		else if(match[p+1]) // Single quoted
+			n = match[p+1];
+		else if(match[p+2]) // Double-square-bracket quoted
+			n = match[p+2];
+		else if(match[p+3]) // Double-brace quoted
+			try {
+				n = match[p+3];
+				if(allowEval)
+					n = window.eval(n);
+			} catch(ex) {
+				throw "Unable to evaluate {{" + match[p+3] + "}}: " + exceptionText(ex);
+			}
+		else if(match[p+4]) // Unquoted
+			n = match[p+4];
+		else if(match[p+5]) // empty quote
+			n = "";
+		return n;
+	};
+	var r = [{}];
+	var dblQuote = "(?:\"((?:(?:\\\\\")|[^\"])+)\")";
+	var sngQuote = "(?:'((?:(?:\\\\\')|[^'])+)')";
+	var dblSquare = "(?:\\[\\[((?:\\s|\\S)*?)\\]\\])";
+	var dblBrace = "(?:\\{\\{((?:\\s|\\S)*?)\\}\\})";
+	var unQuoted = noNames ? "([^\"'\\s]\\S*)" : "([^\"':\\s][^\\s:]*)";
+	var emptyQuote = "((?:\"\")|(?:''))";
+	var skipSpace = "(?:\\s*)";
+	var token = "(?:" + dblQuote + "|" + sngQuote + "|" + dblSquare + "|" + dblBrace + "|" + unQuoted + "|" + emptyQuote + ")";
+	var re = noNames ? new RegExp(token,"mg") : new RegExp(skipSpace + token + skipSpace + "(?:(\\:)" + skipSpace + token + ")?","mg");
+	var params = [];
+	do {
+		var match = re.exec(this);
+		if(match) {
+			var n = parseToken(match,1);
+			if(noNames) {
+				r.push({name:"",value:n});
+			} else {
+				var v = parseToken(match,8);
+				if(v == null && defaultName) {
+					v = n;
+					n = defaultName;
+				} else if(v == null && defaultValue) {
+					v = defaultValue;
+				}
+				r.push({name:n,value:v});
+				if(cascadeDefaults) {
+					defaultName = n;
+					defaultValue = v;
+				}
+			}
+		}
+	} while(match);
+	// Summarise parameters into first element
+	for(var t=1; t<r.length; t++) {
+		if(r[0][r[t].name])
+			r[0][r[t].name].push(r[t].value);
+		else
+			r[0][r[t].name] = [r[t].value];
+	}
+	return r;
+};
+
+// Process a string list of macro parameters into an array. Parameters can be quoted with "", '',
+// [[]], {{ }} or left unquoted (and therefore space-separated). Double-braces {{}} results in
+// an *evaluated* parameter: e.g. {{config.options.txtUserName}} results in the current user's name.
+String.prototype.readMacroParams = function()
+{
+	var p = this.parseParams("list",null,true,true);
+	var n = [];
+	for(var t=1; t<p.length; t++)
+		n.push(p[t].value);
+	return n;
+};
+
+// Process a string list of unique tiddler names into an array. Tiddler names that have spaces in them must be [[bracketed]]
+String.prototype.readBracketedList = function(unique)
+{
+	var p = this.parseParams("list",null,false,true);
+	var n = [];
+	for(var t=1; t<p.length; t++) {
+		if(p[t].value)
+			n.pushUnique(p[t].value,unique);
+	}
+	return n;
+};
+
+// Returns array with start and end index of chunk between given start and end marker, or undefined.
+String.prototype.getChunkRange = function(start,end)
+{
+	var s = this.indexOf(start);
+	if(s != -1) {
+		s += start.length;
+		var e = this.indexOf(end,s);
+		if(e != -1)
+			return [s,e];
+	}
+};
+
+// Replace a chunk of a string given start and end markers
+String.prototype.replaceChunk = function(start,end,sub)
+{
+	var r = this.getChunkRange(start,end);
+	return r ? this.substring(0,r[0]) + sub + this.substring(r[1]) : this;
+};
+
+// Returns a chunk of a string between start and end markers, or undefined
+String.prototype.getChunk = function(start,end)
+{
+	var r = this.getChunkRange(start,end);
+	if(r)
+		return this.substring(r[0],r[1]);
+};
+
+
+// Static method to bracket a string with double square brackets if it contains a space
+String.encodeTiddlyLink = function(title)
+{
+	return title.indexOf(" ") == -1 ? title : "[[" + title + "]]";
+};
+
+// Static method to encodeTiddlyLink for every item in an array and join them with spaces
+String.encodeTiddlyLinkList = function(list)
+{
+	if(list) {
+		var results = [];
+		for(var t=0; t<list.length; t++)
+			results.push(String.encodeTiddlyLink(list[t]));
+		return results.join(" ");
+	} else {
+		return "";
+	}
+};
+
+// Convert a string as a sequence of name:"value" pairs into a hashmap
+String.prototype.decodeHashMap = function()
+{
+	var fields = this.parseParams("anon","",false);
+	var r = {};
+	for(var t=1; t<fields.length; t++)
+		r[fields[t].name] = fields[t].value;
+	return r;
+};
+
+// Static method to encode a hashmap into a name:"value"... string
+String.encodeHashMap = function(hashmap)
+{
+	var r = [];
+	for(var t in hashmap)
+		r.push(t + ':"' + hashmap[t] + '"');
+	return r.join(" ");
+};
+
+// Static method to left-pad a string with 0s to a certain width
+String.zeroPad = function(n,d)
+{
+	var s = n.toString();
+	if(s.length < d)
+		s = "000000000000000000000000000".substr(0,d-s.length) + s;
+	return s;
+};
+
+String.prototype.startsWith = function(prefix)
+{
+	return !prefix || this.substring(0,prefix.length) == prefix;
+};
+
+// Returns the first value of the given named parameter.
+function getParam(params,name,defaultValue)
+{
+	if(!params)
+		return defaultValue;
+	var p = params[0][name];
+	return p ? p[0] : defaultValue;
+}
+
+// Returns the first value of the given boolean named parameter.
+function getFlag(params,name,defaultValue)
+{
+	return !!getParam(params,name,defaultValue);
+}
+
+// Substitute date components into a string
+Date.prototype.formatString = function(template)
+{
+	var t = template.replace(/0hh12/g,String.zeroPad(this.getHours12(),2));
+	t = t.replace(/hh12/g,this.getHours12());
+	t = t.replace(/0hh/g,String.zeroPad(this.getHours(),2));
+	t = t.replace(/hh/g,this.getHours());
+	t = t.replace(/mmm/g,config.messages.dates.shortMonths[this.getMonth()]);
+	t = t.replace(/0mm/g,String.zeroPad(this.getMinutes(),2));
+	t = t.replace(/mm/g,this.getMinutes());
+	t = t.replace(/0ss/g,String.zeroPad(this.getSeconds(),2));
+	t = t.replace(/ss/g,this.getSeconds());
+	t = t.replace(/[ap]m/g,this.getAmPm().toLowerCase());
+	t = t.replace(/[AP]M/g,this.getAmPm().toUpperCase());
+	t = t.replace(/wYYYY/g,this.getYearForWeekNo());
+	t = t.replace(/wYY/g,String.zeroPad(this.getYearForWeekNo()-2000,2));
+	t = t.replace(/YYYY/g,this.getFullYear());
+	t = t.replace(/YY/g,String.zeroPad(this.getFullYear()-2000,2));
+	t = t.replace(/MMM/g,config.messages.dates.months[this.getMonth()]);
+	t = t.replace(/0MM/g,String.zeroPad(this.getMonth()+1,2));
+	t = t.replace(/MM/g,this.getMonth()+1);
+	t = t.replace(/0WW/g,String.zeroPad(this.getWeek(),2));
+	t = t.replace(/WW/g,this.getWeek());
+	t = t.replace(/DDD/g,config.messages.dates.days[this.getDay()]);
+	t = t.replace(/ddd/g,config.messages.dates.shortDays[this.getDay()]);
+	t = t.replace(/0DD/g,String.zeroPad(this.getDate(),2));
+	t = t.replace(/DDth/g,this.getDate()+this.daySuffix());
+	t = t.replace(/DD/g,this.getDate());
+	var tz = this.getTimezoneOffset();
+	var atz = Math.abs(tz);
+	t = t.replace(/TZD/g,(tz < 0 ? '+' : '-') + String.zeroPad(Math.floor(atz / 60),2) + ':' + String.zeroPad(atz % 60,2));
+	t = t.replace(/\\/g,"");
+	return t;
+};
+
+Date.prototype.getWeek = function()
+{
+	var dt = new Date(this.getTime());
+	var d = dt.getDay();
+	if(d==0) d=7;// JavaScript Sun=0, ISO Sun=7
+	dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same week to calculate weekNo
+	var n = Math.floor((dt.getTime()-new Date(dt.getFullYear(),0,1)+3600000)/86400000);
+	return Math.floor(n/7)+1;
+};
+
+Date.prototype.getYearForWeekNo = function()
+{
+	var dt = new Date(this.getTime());
+	var d = dt.getDay();
+	if(d==0) d=7;// JavaScript Sun=0, ISO Sun=7
+	dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same week
+	return dt.getFullYear();
+};
+
+Date.prototype.getHours12 = function()
+{
+	var h = this.getHours();
+	return h > 12 ? h-12 : ( h > 0 ? h : 12 );
+};
+
+Date.prototype.getAmPm = function()
+{
+	return this.getHours() >= 12 ? config.messages.dates.pm : config.messages.dates.am;
+};
+
+Date.prototype.daySuffix = function()
+{
+	return config.messages.dates.daySuffixes[this.getDate()-1];
+};
+
+// Convert a date to local YYYYMMDDHHMM string format
+Date.prototype.convertToLocalYYYYMMDDHHMM = function()
+{
+	return this.getFullYear() + String.zeroPad(this.getMonth()+1,2) + String.zeroPad(this.getDate(),2) + String.zeroPad(this.getHours(),2) + String.zeroPad(this.getMinutes(),2);
+};
+
+// Convert a date to UTC YYYYMMDDHHMM string format
+Date.prototype.convertToYYYYMMDDHHMM = function()
+{
+	return this.getUTCFullYear() + String.zeroPad(this.getUTCMonth()+1,2) + String.zeroPad(this.getUTCDate(),2) + String.zeroPad(this.getUTCHours(),2) + String.zeroPad(this.getUTCMinutes(),2);
+};
+
+// Convert a date to UTC YYYYMMDD.HHMMSSMMM string format
+Date.prototype.convertToYYYYMMDDHHMMSSMMM = function()
+{
+	return this.getUTCFullYear() + String.zeroPad(this.getUTCMonth()+1,2) + String.zeroPad(this.getUTCDate(),2) + "." + String.zeroPad(this.getUTCHours(),2) + String.zeroPad(this.getUTCMinutes(),2) + String.zeroPad(this.getUTCSeconds(),2) + String.zeroPad(this.getUTCMilliseconds(),3) +"0";
+};
+
+// Static method to create a date from a UTC YYYYMMDDHHMM format string
+Date.convertFromYYYYMMDDHHMM = function(d)
+{
+	d = d?d.replace(/[^0-9]/g, ""):""; 
+	return Date.convertFromYYYYMMDDHHMMSSMMM(d.substr(0,12));
+};
+
+// Static method to create a date from a UTC YYYYMMDDHHMMSSMMM format string
+Date.convertFromYYYYMMDDHHMMSSMMM = function(d)
+{
+	d = d ? d.replace(/[^0-9]/g, "") : "";
+	return new Date(Date.UTC(parseInt(d.substr(0,4),10),
+			parseInt(d.substr(4,2),10)-1,
+			parseInt(d.substr(6,2),10),
+			parseInt(d.substr(8,2)||"00",10),
+			parseInt(d.substr(10,2)||"00",10),
+			parseInt(d.substr(12,2)||"00",10),
+			parseInt(d.substr(14,3)||"000",10)));
+};
+
+//--
+//-- RGB colour object
+//--
+
+// Construct an RGB colour object from a '#rrggbb', '#rgb' or 'rgb(n,n,n)' string or from separate r,g,b values
+function RGB(r,g,b)
+{
+	this.r = 0;
+	this.g = 0;
+	this.b = 0;
+	if(typeof r == "string") {
+		if(r.substr(0,1) == "#") {
+			if(r.length == 7) {
+				this.r = parseInt(r.substr(1,2),16)/255;
+				this.g = parseInt(r.substr(3,2),16)/255;
+				this.b = parseInt(r.substr(5,2),16)/255;
+			} else {
+				this.r = parseInt(r.substr(1,1),16)/15;
+				this.g = parseInt(r.substr(2,1),16)/15;
+				this.b = parseInt(r.substr(3,1),16)/15;
+			}
+		} else {
+			var rgbPattern = /rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/;
+			var c = r.match(rgbPattern);
+			if(c) {
+				this.r = parseInt(c[1],10)/255;
+				this.g = parseInt(c[2],10)/255;
+				this.b = parseInt(c[3],10)/255;
+			}
+		}
+	} else {
+		this.r = r;
+		this.g = g;
+		this.b = b;
+	}
+	return this;
+}
+
+// Mixes this colour with another in a specified proportion
+// c = other colour to mix
+// f = 0..1 where 0 is this colour and 1 is the new colour
+// Returns an RGB object
+RGB.prototype.mix = function(c,f)
+{
+	return new RGB(this.r + (c.r-this.r) * f,this.g + (c.g-this.g) * f,this.b + (c.b-this.b) * f);
+};
+
+// Return an rgb colour as a #rrggbb format hex string
+RGB.prototype.toString = function()
+{
+	return "#" + ("0" + Math.floor(this.r.clamp(0,1) * 255).toString(16)).right(2) +
+				 ("0" + Math.floor(this.g.clamp(0,1) * 255).toString(16)).right(2) +
+				 ("0" + Math.floor(this.b.clamp(0,1) * 255).toString(16)).right(2);
+};
+
+//--
+//-- DOM utilities - many derived from www.quirksmode.org
+//--
+
+// Resolve the target object of an event
+function resolveTarget(e)
+{
+	var obj;
+	if(e.target)
+		obj = e.target;
+	else if(e.srcElement)
+		obj = e.srcElement;
+	if(obj.nodeType == 3) // defeat Safari bug
+		obj = obj.parentNode;
+	return obj;
+}
+
+function drawGradient(place,horiz,locolors,hicolors)
+{
+	if(!hicolors)
+		hicolors = locolors;
+	for(var t=0; t<= 100; t+=2) {
+		var bar = document.createElement("div");
+		place.appendChild(bar);
+		bar.style.position = "absolute";
+		bar.style.left = horiz ? t + "%" : 0;
+		bar.style.top = horiz ? 0 : t + "%";
+		bar.style.width = horiz ? (101-t) + "%" : "100%";
+		bar.style.height = horiz ? "100%" : (101-t) + "%";
+		bar.style.zIndex = -1;
+		var p = t/100*(locolors.length-1);
+		var hc = hicolors[Math.floor(p)];
+		if(typeof hc == "string")
+			hc = new RGB(hc);
+		var lc = locolors[Math.ceil(p)];
+		if(typeof lc == "string")
+			lc = new RGB(lc);
+		bar.style.backgroundColor = hc.mix(lc,p-Math.floor(p)).toString();
+	}
+}
+
+function createTiddlyText(parent,text)
+{
+	return parent.appendChild(document.createTextNode(text));
+}
+
+function createTiddlyCheckbox(parent,caption,checked,onChange)
+{
+	var cb = document.createElement("input");
+	cb.setAttribute("type","checkbox");
+	cb.onclick = onChange;
+	parent.appendChild(cb);
+	cb.checked = checked;
+	cb.className = "chkOptionInput";
+	if(caption)
+		wikify(caption,parent);
+	return cb;
+}
+
+function createTiddlyElement(parent,element,id,className,text,attribs)
+{
+	var e = document.createElement(element);
+	if(className != null)
+		e.className = className;
+	if(id != null)
+		e.setAttribute("id",id);
+	if(text != null)
+		e.appendChild(document.createTextNode(text));
+	if(attribs) {
+		for(var n in attribs) {
+			e.setAttribute(n,attribs[n]);
+		}
+	}
+	if(parent != null)
+		parent.appendChild(e);
+	return e;
+}
+
+function addEvent(obj,type,fn)
+{
+	if(obj.attachEvent) {
+		obj["e"+type+fn] = fn;
+		obj[type+fn] = function(){obj["e"+type+fn](window.event);};
+		obj.attachEvent("on"+type,obj[type+fn]);
+	} else {
+		obj.addEventListener(type,fn,false);
+	}
+}
+
+function removeEvent(obj,type,fn)
+{
+	if(obj.detachEvent) {
+		obj.detachEvent("on"+type,obj[type+fn]);
+		obj[type+fn] = null;
+	} else {
+		obj.removeEventListener(type,fn,false);
+	}
+}
+
+
+// Find the closest relative with a given property value (property defaults to tagName, relative defaults to parentNode)
+function findRelated(e,value,name,relative)
+{
+	name = name || "tagName";
+	relative = relative || "parentNode";
+	if(name == "className") {
+		while(e && !hasClass(e,value)) {
+			e = e[relative];
+		}
+	} else {
+		while(e && e[name] != value) {
+			e = e[relative];
+		}
+	}
+	return e;
+}
+
+// Get the scroll position for window.scrollTo necessary to scroll a given element into view
+function ensureVisible(e)
+{
+	var posTop = findPosY(e);
+	var posBot = posTop + e.offsetHeight;
+	var winTop = findScrollY();
+	var winHeight = findWindowHeight();
+	var winBot = winTop + winHeight;
+	if(posTop < winTop) {
+		return posTop;
+	} else if(posBot > winBot) {
+		if(e.offsetHeight < winHeight)
+			return posTop - (winHeight - e.offsetHeight);
+		else
+			return posTop;
+	} else {
+		return winTop;
+	}
+}
+
+// Get the current width of the display window
+function findWindowWidth()
+{
+	return window.innerWidth || document.documentElement.clientWidth;
+}
+
+// Get the current height of the display window
+function findWindowHeight()
+{
+	return window.innerHeight || document.documentElement.clientHeight;
+}
+
+// Get the current horizontal page scroll position
+function findScrollX()
+{
+	return window.scrollX || document.documentElement.scrollLeft;
+}
+
+// Get the current vertical page scroll position
+function findScrollY()
+{
+	return window.scrollY || document.documentElement.scrollTop;
+}
+
+function findPosX(obj)
+{
+	var curleft = 0;
+	while(obj.offsetParent) {
+		curleft += obj.offsetLeft;
+		obj = obj.offsetParent;
+	}
+	return curleft;
+}
+
+function findPosY(obj)
+{
+	var curtop = 0;
+	while(obj.offsetParent) {
+		curtop += obj.offsetTop;
+		obj = obj.offsetParent;
+	}
+	return curtop;
+}
+
+// Blur a particular element
+function blurElement(e)
+{
+	if(e && e.focus && e.blur) {
+		e.focus();
+		e.blur();
+	}
+}
+
+// Create a non-breaking space
+function insertSpacer(place)
+{
+	var e = document.createTextNode(String.fromCharCode(160));
+	if(place)
+		place.appendChild(e);
+	return e;
+}
+
+// Force the browser to do a document reflow when needed to workaround browser bugs
+function forceReflow()
+{
+	if(config.browser.isGecko) {
+		setStylesheet("body {top:0px;margin-top:0px;}","forceReflow");
+		setTimeout(function() {setStylesheet("","forceReflow");},1);
+	}
+}
+
+// Replace the current selection of a textarea or text input and scroll it into view
+function replaceSelection(e,text)
+{
+	if(e.setSelectionRange) {
+		var oldpos = e.selectionStart;
+		var isRange = e.selectionEnd > e.selectionStart;
+		e.value = e.value.substr(0,e.selectionStart) + text + e.value.substr(e.selectionEnd);
+		e.setSelectionRange(isRange ? oldpos : oldpos + text.length,oldpos + text.length);
+		var linecount = e.value.split("\n").length;
+		var thisline = e.value.substr(0,e.selectionStart).split("\n").length-1;
+		e.scrollTop = Math.floor((thisline - e.rows / 2) * e.scrollHeight / linecount);
+	} else if(document.selection) {
+		var range = document.selection.createRange();
+		if(range.parentElement() == e) {
+			var isCollapsed = range.text == "";
+			range.text = text;
+			if(!isCollapsed) {
+				range.moveStart("character", -text.length);
+				range.select();
+			}
+		}
+	}
+}
+
+// Returns the text of the given (text) node, possibly merging subsequent text nodes
+function getNodeText(e)
+{
+	var t = "";
+	while(e && e.nodeName == "#text") {
+		t += e.nodeValue;
+		e = e.nextSibling;
+	}
+	return t;
+}
+
+// Returns true if the element e has a given ancestor element
+function isDescendant(e,ancestor)
+{
+	while(e) {
+		if(e === ancestor)
+			return true;
+		e = e.parentNode;
+	}
+	return false;
+}
+
+
+// deprecate the following...
+
+// Prevent an event from bubbling
+function stopEvent(e)
+{
+	var ev = e || window.event;
+	ev.cancelBubble = true;
+	if(ev.stopPropagation) ev.stopPropagation();
+	return false;
+}
+
+// Remove any event handlers or non-primitve custom attributes
+function scrubNode(e)
+{
+	if(!config.browser.isIE)
+		return;
+	var att = e.attributes;
+	if(att) {
+		for(var t=0; t<att.length; t++) {
+			var n = att[t].name;
+			if(n !== "style" && (typeof e[n] === "function" || (typeof e[n] === "object" && e[n] != null))) {
+				try {
+					e[n] = null;
+				} catch(ex) {
+				}
+			}
+		}
+	}
+	var c = e.firstChild;
+	while(c) {
+		scrubNode(c);
+		c = c.nextSibling;
+	}
+}
+
+function addClass(e,className)
+{
+	jQuery(e).addClass(className);
+}
+
+function removeClass(e,className)
+{
+	jQuery(e).removeClass(className);
+}
+
+function hasClass(e,className)
+{
+	return jQuery(e).hasClass(className);
+}
+
+// Remove all children of a node
+function removeChildren(e)
+{
+	jQuery(e).empty();
+}
+
+// Return the content of an element as plain text with no formatting
+function getPlainText(e)
+{
+	return jQuery(e).text();
+}
+
+// Remove a node and all it's children
+function removeNode(e)
+{
+	jQuery(e).remove();
+}
+
+//--
+//-- LoaderBase and SaverBase
+//--
+
+function LoaderBase() {}
+
+LoaderBase.prototype.loadTiddler = function(store,node,tiddlers)
+{
+	var title = this.getTitle(store,node);
+	if(safeMode && store.isShadowTiddler(title))
+		return;
+	if(title) {
+		var tiddler = store.createTiddler(title);
+		this.internalizeTiddler(store,tiddler,title,node);
+		tiddlers.push(tiddler);
+	}
+};
+
+LoaderBase.prototype.loadTiddlers = function(store,nodes)
+{
+	var tiddlers = [];
+	for(var t = 0; t < nodes.length; t++) {
+		try {
+			this.loadTiddler(store,nodes[t],tiddlers);
+		} catch(ex) {
+			showException(ex,config.messages.tiddlerLoadError.format([this.getTitle(store,nodes[t])]));
+		}
+	}
+	return tiddlers;
+};
+
+function SaverBase() {}
+
+SaverBase.prototype.externalize = function(store)
+{
+	var results = [];
+	var tiddlers = store.getTiddlers("title");
+	for(var t = 0; t < tiddlers.length; t++) {
+		if(!tiddlers[t].doNotSave())
+			results.push(this.externalizeTiddler(store, tiddlers[t]));
+	}
+	return results.join("\n");
+};
+
+//--
+//-- TW21Loader (inherits from LoaderBase)
+//--
+
+function TW21Loader() {}
+
+TW21Loader.prototype = new LoaderBase();
+
+TW21Loader.prototype.getTitle = function(store,node)
+{
+	var title = null;
+	if(node.getAttribute) {
+		title = node.getAttribute("title");
+		if(!title)
+			title = node.getAttribute("tiddler");
+	}
+	if(!title && node.id) {
+		var lenPrefix = store.idPrefix.length;
+		if(node.id.substr(0,lenPrefix) == store.idPrefix)
+			title = node.id.substr(lenPrefix);
+	}
+	return title;
+};
+
+TW21Loader.prototype.internalizeTiddler = function(store,tiddler,title,node)
+{
+	var e = node.firstChild;
+	var text = null;
+	if(node.getAttribute("tiddler")) {
+		text = getNodeText(e).unescapeLineBreaks();
+	} else {
+		while(e.nodeName!="PRE" && e.nodeName!="pre") {
+			e = e.nextSibling;
+		}
+		text = e.innerHTML.replace(/\r/mg,"").htmlDecode();
+	}
+	var creator = node.getAttribute("creator");
+	var modifier = node.getAttribute("modifier");
+	var c = node.getAttribute("created");
+	var m = node.getAttribute("modified");
+	var created = c ? Date.convertFromYYYYMMDDHHMM(c) : version.date;
+	var modified = m ? Date.convertFromYYYYMMDDHHMM(m) : created;
+	var tags = node.getAttribute("tags");
+	var fields = {};
+	var attrs = node.attributes;
+	for(var i = attrs.length-1; i >= 0; i--) {
+		var name = attrs[i].name;
+		if(attrs[i].specified && !TiddlyWiki.isStandardField(name)) {
+			fields[name] = attrs[i].value.unescapeLineBreaks();
+		}
+	}
+	tiddler.assign(title,text,modifier,modified,tags,created,fields,creator);
+	return tiddler;
+};
+
+//--
+//-- TW21Saver (inherits from SaverBase)
+//--
+
+function TW21Saver() {}
+
+TW21Saver.prototype = new SaverBase();
+
+TW21Saver.prototype.externalizeTiddler = function(store,tiddler)
+{
+	try {
+		var extendedAttributes = "";
+		var usePre = config.options.chkUsePreForStorage;
+		store.forEachField(tiddler,
+			function(tiddler,fieldName,value) {
+				// don't store stuff from the temp namespace
+				if(typeof value != "string")
+					value = "";
+				if(!fieldName.match(/^temp\./))
+					extendedAttributes += ' %0="%1"'.format([fieldName,value.escapeLineBreaks().htmlEncode()]);
+			},true);
+		var created = tiddler.created;
+		var modified = tiddler.modified;
+		var attributes = tiddler.creator ? ' creator="' + tiddler.creator.htmlEncode() + '"' : "";
+		attributes += tiddler.modifier ? ' modifier="' + tiddler.modifier.htmlEncode() + '"' : "";
+		attributes += (usePre && created == version.date) ? "" :' created="' + created.convertToYYYYMMDDHHMM() + '"';
+		attributes += (usePre && modified == created) ? "" : ' modified="' + modified.convertToYYYYMMDDHHMM() +'"';
+		var tags = tiddler.getTags();
+		if(!usePre || tags)
+			attributes += ' tags="' + tags.htmlEncode() + '"';
+		return ('<div %0="%1"%2%3>%4</'+'div>').format([
+				usePre ? "title" : "tiddler",
+				tiddler.title.htmlEncode(),
+				attributes,
+				extendedAttributes,
+				usePre ? "\n<pre>" + tiddler.text.htmlEncode() + "</pre>\n" : tiddler.text.escapeLineBreaks().htmlEncode()
+			]);
+	} catch (ex) {
+		throw exceptionText(ex,config.messages.tiddlerSaveError.format([tiddler.title]));
+	}
+};
+
+//]]>
+</script>
+<script id="jsdeprecatedArea" type="text/javascript">
+//<![CDATA[
+//--
+//-- Deprecated Crypto functions and associated conversion routines.
+//-- Use the jQuery.encoding functions directly instead.
+//--
+
+// Crypto 'namespace'
+function Crypto() {}
+
+// Convert a string to an array of big-endian 32-bit words
+Crypto.strToBe32s = function(str)
+{
+	return jQuery.encoding.strToBe32s(str);
+};
+
+// Convert an array of big-endian 32-bit words to a string
+Crypto.be32sToStr = function(be)
+{
+	return jQuery.encoding.be32sToStr(be);
+};
+
+// Convert an array of big-endian 32-bit words to a hex string
+Crypto.be32sToHex = function(be)
+{
+	return jQuery.encoding.be32sToHex(be);
+};
+
+// Return, in hex, the SHA-1 hash of a string
+Crypto.hexSha1Str = function(str)
+{
+	return jQuery.encoding.digests.hexSha1Str(str);
+};
+
+// Return the SHA-1 hash of a string
+Crypto.sha1Str = function(str)
+{
+	return jQuery.encoding.digests.sha1Str(str);
+};
+
+// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
+Crypto.sha1 = function(x,blen)
+{
+	return jQuery.encoding.digests.sha1(x,blen);
+};
+
+//--
+//-- Deprecated DOM utilities
+//--
+
+// @Deprecated: Use jQuery.stylesheet instead
+function setStylesheet(s,id,doc)
+{
+	jQuery.twStylesheet(s,{ id: id, doc: doc });
+}
+
+// @Deprecated: Use jQuery.stylesheet.remove instead
+function removeStyleSheet(id)
+{
+	jQuery.twStylesheet.remove({ id: id });
+}
+//--
+//-- Deprecated HTTP request code
+//-- Use the jQuery ajax functions directly instead
+//--
+
+function loadRemoteFile(url,callback,params)
+{
+	return httpReq("GET",url,callback,params);
+}
+
+function doHttp(type,url,data,contentType,username,password,callback,params,headers,allowCache)
+{
+	return httpReq(type,url,callback,params,headers,data,contentType,username,password,allowCache);
+}
+
+function httpReq(type,url,callback,params,headers,data,contentType,username,password,allowCache)
+{
+	var options = {
+		type:type,
+		url:url,
+		processData:false,
+		data:data,
+		cache:!!allowCache,
+		beforeSend: function(xhr) {
+			for(var i in headers)
+				xhr.setRequestHeader(i,headers[i]);
+			xhr.setRequestHeader("X-Requested-With", "TiddlyWiki " + formatVersion());
+		}
+	};
+
+	if(callback) {
+		options.complete = function(xhr,textStatus) {
+			if(jQuery.httpSuccess(xhr))
+				callback(true,params,xhr.responseText,url,xhr);
+			else
+				callback(false,params,null,url,xhr);
+		};
+	}
+	if(contentType)
+		options.contentType = contentType;
+	if(username)
+		options.username = username;
+	if(password)
+		options.password = password;
+	if(window.Components && window.netscape && window.netscape.security && document.location.protocol.indexOf("http") == -1)
+		window.netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+	return jQuery.ajax(options);
+}
+
+//--
+//-- Deprecated String functions
+//--
+
+// @Deprecated: no direct replacement, since not used in core code
+String.prototype.toJSONString = function()
+{
+	// Convert a string to it's JSON representation by encoding control characters, double quotes and backslash. See json.org
+	var m = {
+		'\b': '\\b',
+		'\f': '\\f',
+		'\n': '\\n',
+		'\r': '\\r',
+		'\t': '\\t',
+		'"' : '\\"',
+		'\\': '\\\\'
+		};
+	var replaceFn = function(a,b) {
+		var c = m[b];
+		if(c)
+			return c;
+		c = b.charCodeAt();
+		return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
+		};
+	if(/["\\\x00-\x1f]/.test(this))
+		return '"' + this.replace(/([\x00-\x1f\\"])/g,replaceFn) + '"';
+	return '"' + this + '"';
+};
+
+//--
+//-- Deprecated Tiddler code
+//--
+
+// @Deprecated: Use tiddlerToRssItem(tiddler,uri) instead
+Tiddler.prototype.toRssItem = function(uri)
+{
+	return tiddlerToRssItem(this,uri);
+};
+
+// @Deprecated: Use "<item>\n" + tiddlerToRssItem(tiddler,uri)  + "\n</item>" instead
+Tiddler.prototype.saveToRss = function(uri)
+{
+	return "<item>\n" + tiddlerToRssItem(this,uri) + "\n</item>";
+};
+
+// @Deprecated: Use jQuery.encoding.digests.hexSha1Str instead
+Tiddler.prototype.generateFingerprint = function()
+{
+	return "0x" + Crypto.hexSha1Str(this.text);
+};
+
+//]]>
+</script>
+<script id="jslibArea" type="text/javascript">
+//<![CDATA[
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j); [...]
+e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget) [...]
+j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g," [...]
+"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua [...]
+true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]* [...]
+Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if(( [...]
+(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagNam [...]
+a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.c [...]
+"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:fu [...]
+function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.i [...]
+c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMConten [...]
+L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"construc [...]
+"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Functi [...]
+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d) [...]
+d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++ [...]
+a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d [...]
+!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if [...]
+true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML="   <link/><table></table><a href='/a' style='color:red;float:left [...]
+var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select [...]
+parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCl [...]
+false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="non [...]
+s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embe [...]
+applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.rem [...]
+else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c. [...]
+a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a; [...]
+w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|inpu [...]
+cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.cla [...]
+i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+ [...]
+" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);thi [...]
+this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j< [...]
+e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",t [...]
+c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type proper [...]
+a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=functi [...]
+function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1) [...]
+k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n [...]
+C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove [...]
+null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf(" [...]
+e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(! [...]
+f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.e [...]
+if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange at [...]
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b. [...]
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.e [...]
+"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type) [...]
+a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented [...]
+isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submit [...]
+{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialS [...]
+if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_ [...]
+e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.t [...]
+"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventLi [...]
+d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a=== [...]
+!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return  [...]
+toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j| [...]
+u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unl [...]
+function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++ [...]
+if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?: [...]
+e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g]) [...]
+t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||( [...]
+g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q [...]
+for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.spli [...]
+1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG" [...]
+CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attr [...]
+relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m+ [...]
+l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){ [...]
+h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG: [...]
+CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m [...]
+g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:functio [...]
+text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.no [...]
+setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q=== [...]
+h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0; [...]
+m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m [...]
+"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+) [...]
+h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocume [...]
+!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createR [...]
+h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!= [...]
+q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTM [...]
+if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l]; [...]
+(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPositi [...]
+function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Unti [...]
+gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f+ [...]
+c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=thi [...]
+{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||t [...]
+"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"par [...]
+d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeNam [...]
+a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeTy [...]
+1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b, [...]
+a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn. [...]
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(th [...]
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChi [...]
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.pa [...]
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChi [...]
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].i [...]
+""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith [...]
+this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagNam [...]
+u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childN [...]
+1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length=== [...]
+return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec [...]
+""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.pu [...]
+c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b [...]
+c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styl [...]
+function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")| [...]
+Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c [...]
+"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedSty [...]
+a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters. [...]
+a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:funct [...]
+"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}}) [...]
+serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess [...]
+function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url: [...]
+global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{} [...]
+e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka [...]
+"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;i [...]
+false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if [...]
+false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.se [...]
+c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q== [...]
+d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h [...]
+g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status== [...]
+1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="st [...]
+"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w) [...]
+if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a], [...]
+this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!==" [...]
+"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacit [...]
+animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){ [...]
+j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a [...]
+this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.f [...]
+"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this [...]
+c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.n [...]
+this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.st [...]
+this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this. [...]
+e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a [...]
+c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClien [...]
+function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:fun [...]
+this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.cu [...]
+k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o. [...]
+f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></d [...]
+a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j [...]
+c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b= [...]
+d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{ [...]
+f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pag [...]
+"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return" [...]
+e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
+
+//]]>
+</script>
+<script id="jqueryArea" type="text/javascript">
+//<![CDATA[
+/*
+jQuery.encoding.digests.sha1.js
+
+SHA-1 digest and associated utility functions
+
+Copyright (c) UnaMesa Association 2009
+
+Dual licensed under the MIT and GPL licenses:
+  http://www.opensource.org/licenses/mit-license.php
+  http://www.gnu.org/licenses/gpl.html
+*/
+
+(function($) {
+
+if(!$.encoding)
+	$.encoding = {};
+	$.extend($.encoding,{
+		strToBe32s: function(str) {
+			// Convert a string to an array of big-endian 32-bit words
+			var be=[];
+			var len=Math.floor(str.length/4);
+			var i, j;
+			for(i=0, j=0; i<len; i++, j+=4) {
+				be[i]=((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
+			}
+			while(j<str.length) {
+				be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
+				j++;
+			}
+			return be;
+		},
+		be32sToStr: function(be) {
+			// Convert an array of big-endian 32-bit words to a string
+			var str='';
+			for(var i=0;i<be.length*32;i+=8) {
+				str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
+			}
+			return str;
+		},
+		be32sToHex: function(be) {
+			// Convert an array of big-endian 32-bit words to a hex string
+			var hex='0123456789ABCDEF';
+			var str='';
+			for(var i=0;i<be.length*4;i++) {
+				str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
+			}
+			return str;
+		}
+	});
+})(jQuery);
+
+
+(function($) {
+
+if(!$.encoding.digests)
+	$.encoding.digests = {};
+	$.extend($.encoding.digests,{
+		hexSha1Str: function(str) {
+			// Return, in hex, the SHA-1 hash of a string
+			return $.encoding.be32sToHex($.encoding.digests.sha1Str(str));
+		},
+		sha1Str: function(str) {
+			// Return the SHA-1 hash of a string
+			return sha1($.encoding.strToBe32s(str),str.length);
+		},
+		sha1: function(x,blen) {
+			// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
+			return sha1($.encoding.strToBe32s(str),str.length);
+		}
+	});
+
+	// Private functions.
+	function sha1(x,blen) {
+		// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
+		function add32(a,b) {
+			// Add 32-bit integers, wrapping at 32 bits
+			// Uses 16-bit operations internally to work around bugs in some JavaScript interpreters.
+			var lsw=(a&0xFFFF)+(b&0xFFFF);
+			var msw=(a>>16)+(b>>16)+(lsw>>16);
+			return (msw<<16)|(lsw&0xFFFF);
+		}
+		function AA(a,b,c,d,e) {
+			// Cryptographic round helper function. Add five 32-bit integers, wrapping at 32 bits, second parameter is rotated left 5 bits before the addition
+			// Uses 16-bit operations internally to work around bugs in some JavaScript interpreters.
+			b=(b>>>27)|(b<<5);
+			var lsw=(a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
+			var msw=(a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
+			return (msw<<16)|(lsw&0xFFFF);
+		}
+		function RR(w,j) {
+			// Cryptographic round helper function.
+			var n=w[j-3]^w[j-8]^w[j-14]^w[j-16];
+			return (n>>>31)|(n<<1);
+		}
+
+		var len=blen*8;
+		x[len>>5] |= 0x80 << (24-len%32);
+		x[((len+64>>9)<<4)+15]=len;
+		var w=new Array(80);
+
+		var k1=0x5A827999;
+		var k2=0x6ED9EBA1;
+		var k3=0x8F1BBCDC;
+		var k4=0xCA62C1D6;
+
+		var h0=0x67452301;
+		var h1=0xEFCDAB89;
+		var h2=0x98BADCFE;
+		var h3=0x10325476;
+		var h4=0xC3D2E1F0;
+
+		for(var i=0;i<x.length;i+=16) {
+			var j=0;
+			var t;
+			var a=h0;
+			var b=h1;
+			var c=h2;
+			var d=h3;
+			var e=h4;
+			while(j<16) {
+				w[j]=x[i+j];
+				t=AA(e,a,d^(b&(c^d)),w[j],k1);
+				e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
+			}
+			while(j<20) {
+				w[j]=RR(w,j);
+				t=AA(e,a,d^(b&(c^d)),w[j],k1);
+				e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
+			}
+			while(j<40) {
+				w[j]=RR(w,j);
+				t=AA(e,a,b^c^d,w[j],k2);
+				e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
+			}
+			while(j<60) {
+				w[j]=RR(w,j);
+				t=AA(e,a,(b&c)|(d&(b|c)),w[j],k3);
+				e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
+			}
+			while(j<80) {
+				w[j]=RR(w,j);
+				t=AA(e,a,b^c^d,w[j],k4);
+				e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
+			}
+			h0=add32(h0,a);
+			h1=add32(h1,b);
+			h2=add32(h2,c);
+			h3=add32(h3,d);
+			h4=add32(h4,e);
+		}
+		return [h0,h1,h2,h3,h4];
+	}
+})(jQuery);
+/*
+jQuery.twStylesheet.js
+
+jQuery plugin to dynamically insert CSS rules into a document
+
+Usage:
+  jQuery.twStylesheet applies style definitions
+  jQuery.twStylesheet.remove neutralizes style definitions
+
+Copyright (c) UnaMesa Association 2009
+
+Triple licensed under the BSD, MIT and GPL licenses:
+  http://www.opensource.org/licenses/bsd-license.php
+  http://www.opensource.org/licenses/mit-license.php
+  http://www.gnu.org/licenses/gpl.html
+*/
+
+(function($) {
+
+var defaultId = "customStyleSheet"; // XXX: rename to dynamicStyleSheet?
+
+// Add or replace a style sheet
+// css argument is a string of CSS rule sets
+// options.id is an optional name identifying the style sheet
+// options.doc is an optional document reference
+// N.B.: Uses DOM methods instead of jQuery to ensure cross-browser comaptibility.
+$.twStylesheet = function(css, options) {
+	options = options || {};
+	var id = options.id || defaultId;
+	var doc = options.doc || document;
+	var el = doc.getElementById(id);
+	if(doc.createStyleSheet) { // IE-specific handling
+		if(el) {
+			el.parentNode.removeChild(el);
+		}
+		doc.getElementsByTagName("head")[0].insertAdjacentHTML("beforeEnd",
+			" <style id='" + id + "'>" + css + "</style>"); // fails without  
+	} else { // modern browsers
+		if(el) {
+			el.replaceChild(doc.createTextNode(css), el.firstChild);
+		} else {
+			el = doc.createElement("style");
+			el.type = "text/css";
+			el.id = id;
+			el.appendChild(doc.createTextNode(css));
+			doc.getElementsByTagName("head")[0].appendChild(el);
+		}
+	}
+};
+
+// Remove existing style sheet
+// options.id is an optional name identifying the style sheet
+// options.doc is an optional document reference
+$.twStylesheet.remove = function(options) {
+	options = options || {};
+	var id = options.id || defaultId;
+	var doc = options.doc || document;
+	var el = doc.getElementById(id);
+	if(el) {
+		el.parentNode.removeChild(el);
+	}
+};
+
+})(jQuery);
+//]]>
+</script>
+<script type="text/javascript">
+//<![CDATA[
+if(useJavaSaver)
+	document.write("<applet style='position:absolute;left:-1px' name='TiddlySaver' code='TiddlySaver.class' archive='TiddlySaver.jar' width='1' height='1'></applet>");
+//]]>
+</script>
+<!--POST-SCRIPT-START-->
+
+<!--POST-SCRIPT-END-->
+</body>
+</html>
diff --git a/docsrc/vigra.css b/docsrc/vigra.css
new file mode 100644
index 0000000..34458e3
--- /dev/null
+++ b/docsrc/vigra.css
@@ -0,0 +1,457 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+    font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+BODY,TD {
+       font-size: 90%;
+}
+H1 {
+    background-color: #e0d0a0;
+    padding: 0.5em;
+    text-align: center;
+    font-size: 160%;
+}
+H2 {
+       font-size: 120%;
+}
+H2.details_section {
+    background-color: #e0d0a0;
+    padding: 0.5em;
+    font-size: 140%;
+    text-align: center;
+}
+H3.details_section {
+    background-color: #e0d0a0;
+    padding: 0.5em;
+    border-width: 1px;
+    border-style: solid;
+    border-color: #c8aa54;
+    -moz-border-radius: 8px 8px 8px 8px;
+}
+.main_heading {
+    background-color: #e0d0a0;
+    padding: 1em;
+    text-align: center;
+    font-size: 200%;
+    border: 0px;
+    padding: 5px;
+    font-weight: bold;
+}
+.ingroups {
+    font-size: 60%;
+}
+H3 {
+       font-size: 100%;
+}
+table.function_index {
+    background-color: #e0d0a0;
+    padding: 0.3em;
+    font-size: 120%;
+    width: 100%;
+}
+CAPTION { font-weight: bold }
+div.line {
+	font-family: monospace, fixed;
+        font-size: 13px;
+	min-height: 13px;
+	line-height: 1.0;
+	text-wrap: unrestricted;
+	white-space: -moz-pre-wrap; /* Moz */
+	white-space: -pre-wrap;     /* Opera 4-6 */
+	white-space: -o-pre-wrap;   /* Opera 7 */
+	white-space: pre-wrap;      /* CSS3  */
+	word-wrap: break-word;      /* IE 5.5+ */
+	text-indent: -53px;
+	padding-left: 53px;
+	padding-bottom: 0px;
+	margin: 0px;
+	-webkit-transition-property: background-color, box-shadow;
+	-webkit-transition-duration: 0.5s;
+	-moz-transition-property: background-color, box-shadow;
+	-moz-transition-duration: 0.5s;
+	-ms-transition-property: background-color, box-shadow;
+	-ms-transition-duration: 0.5s;
+	-o-transition-property: background-color, box-shadow;
+	-o-transition-duration: 0.5s;
+	transition-property: background-color, box-shadow;
+	transition-duration: 0.5s;
+}
+DIV.qindex {
+    width: 100%;
+    background-color: #e0d0a0;
+    border: 1px solid #c8aa54;
+    text-align: center;
+    margin: 2px;
+    padding: 2px;
+    line-height: 140%;
+}
+DIV.nav {
+    width: 100%;
+    background-color: #e8eef2;
+    border: 1px solid #c8aa54;
+    text-align: center;
+    margin: 2px;
+    padding: 2px;
+    line-height: 140%;
+}
+DIV.navtab {
+       background-color: #e8eef2;
+       border: 1px solid #c8aa54;
+       text-align: center;
+       margin: 2px;
+       margin-right: 15px;
+       padding: 2px;
+}
+TD.navtab {
+       font-size: 70%;
+}
+A.qindex {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D;
+}
+A.qindex:visited {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D
+}
+A.qindex:hover {
+    text-decoration: none;
+    background-color: #ddddff;
+}
+A.qindexHL {
+    text-decoration: none;
+    font-weight: bold;
+    background-color: #6666cc;
+    color: #ffffff;
+    border: 1px double #9295C2;
+}
+A.qindexHL:hover {
+    text-decoration: none;
+    background-color: #6666cc;
+    color: #ffffff;
+}
+A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.el { text-decoration: none; font-weight: bold }
+A:link { color: #0040b0; }
+A:visited { color: #a00040; }
+A:hover { text-decoration: none; background-color: #f2f2ff }
+A.anchor { color: #000000;   text-decoration: none; background-color: none; }
+A.elRef { font-weight: bold }
+A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
+A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
+A.codeRef:link { font-weight: normal; color: #0000FF}
+A.codeRef:visited { font-weight: normal; color: #0000FF}
+code  { 
+/*    font-family: Lucida Console, monospace, fixed; */
+    font-family: monospace, fixed;
+    color: #303030; 
+    font-weight: bold;
+} 
+DL.el { margin-left: -1cm }
+.fragment {
+/*    font-family: Lucida Console, monospace, fixed; */
+    font-family: monospace, fixed;
+       font-size: 95%;
+}
+PRE.fragment {
+/*  border: 1px solid #c8aa54; */
+    border: 1px solid #dad0aa;
+    background-color: #fcfaf8;
+    margin-top: 4px;
+    margin-bottom: 4px;
+    margin-left: 2px;
+    margin-right: 8px;
+    padding-left: 6px;
+    padding-right: 6px;
+    padding-top: 4px;
+    padding-bottom: 4px;
+}
+DIV.fragment {
+    border: 1px solid #dad0aa;
+    background-color: #fcfaf8;
+    margin-top: 4px;
+    margin-bottom: 4px;
+    margin-left: 2px;
+    margin-right: 8px;
+    padding-left: 6px;
+    padding-right: 6px;
+    padding-top: 4px;
+    padding-bottom: 4px;
+}
+DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
+
+DIV.groupHeader {
+       margin-left: 16px;
+       margin-top: 12px;
+       margin-bottom: 6px;
+       font-weight: bold;
+}
+DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
+BODY {
+    background: #f8f0e0;
+    color: black;
+    margin-right: 20px;
+    margin-left: 20px;
+}
+TD.indexkey {
+/*  background-color: #e8eef2; */
+    background-color: #f8f0e0;
+    font-weight: bold;
+    padding-right  : 10px;
+    padding-top    : 2px;
+    padding-left   : 10px;
+    padding-bottom : 2px;
+    margin-left    : 0px;
+    margin-right   : 0px;
+    margin-top     : 2px;
+    margin-bottom  : 2px;
+/*  border: 1px solid #CCCCCC; */
+    border: 1px solid #e0d0a0;
+}
+TD.indexvalue {
+/*  background-color: #e8eef2; */
+    background-color: #f8f0e0;
+    font-style: italic;
+    padding-right  : 10px;
+    padding-top    : 2px;
+    padding-left   : 10px;
+    padding-bottom : 2px;
+    margin-left    : 0px;
+    margin-right   : 0px;
+    margin-top     : 2px;
+    margin-bottom  : 2px;
+/*  border: 1px solid #CCCCCC; */
+    border: 1px solid #e0d0a0;
+}
+TR.memlist {
+   background-color: #f0f0f0;
+}
+P.formulaDsp { text-align: center; }
+IMG.formulaDsp { }
+IMG.formulaInl { vertical-align: middle; }
+SPAN.keyword       { color: #008000 }
+SPAN.keywordtype   { color: #604020 }
+SPAN.keywordflow   { color: #e08000 }
+SPAN.comment       { color: #800000 }
+SPAN.preprocessor  { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral   { color: #008080 }
+.mdescLeft {
+    padding: 0px 8px 4px 8px;
+    font-size: 80%;
+    font-style: italic;
+    background-color: #fcfaf8;
+    border-top: 1px none #dad0a8;
+    border-right: 1px none #dad0a8;
+    border-bottom: 1px none #dad0a8;
+    border-left: 1px none #dad0a8;
+    margin: 0px;
+}
+.mdescRight {
+    padding: 0px 8px 4px 8px; 
+    font-size: 80%;
+    font-style: italic;
+    background-color: #fcfaf8;
+    border-top: 1px none #dad0a8;
+    border-right: 1px none #dad0a8;
+    border-bottom: 1px none #dad0a8;
+    border-left: 1px none #dad0a8;
+    margin: 0px;
+}
+.memItemLeft {
+    padding: 1px 0px 0px 8px;
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #dad0a8;
+    border-right-color: #dad0a8;
+    border-bottom-color: #dad0a8;
+    border-left-color: #dad0a8;
+    border-top-style: solid;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #fcfaf8;
+    font-size: 80%;
+}
+.memItemRight {
+    padding: 1px 8px 0px 8px; 
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #dad0a8;
+    border-right-color: #dad0a8;
+    border-bottom-color: #dad0a8;
+    border-left-color: #dad0a8;
+    border-top-style: solid;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #fcfaf8;
+    font-size: 80%;
+}
+.memTemplItemLeft {
+    padding: 1px 0px 0px 8px; 
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #dad0a8;
+    border-right-color: #dad0a8;
+    border-bottom-color: #dad0a8;
+    border-left-color: #dad0a8;
+    border-top-style: none;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #fcfaf8;
+    font-size: 80%;
+}
+.memTemplItemRight {
+    padding: 1px 8px 0px 8px; 
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #dad0a8;
+    border-right-color: #dad0a8;
+    border-bottom-color: #dad0a8;
+    border-left-color: #dad0a8;
+    border-top-style: none;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #fcfaf8;
+    font-size: 80%;
+}
+.memTemplParams {
+    padding: 1px 0px 0px 8px; 
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #dad0a8;
+    border-right-color: #dad0a8;
+    border-bottom-color: #dad0a8;
+    border-left-color: #dad0a8;
+    border-top-style: solid;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+/*       color: #606060; */
+    background-color: #fcfaf8;
+    font-size: 80%;
+}
+.search     { color: #003399;
+              font-weight: bold;
+}
+FORM.search {
+              margin-bottom: 0px;
+              margin-top: 0px;
+}
+INPUT.search { font-size: 75%;
+               color: #000080;
+               font-weight: normal;
+               background-color: #e8eef2;
+}
+TD.tiny      { font-size: 75%;
+}
+a {
+    color: #1A41A8;
+}
+a:visited {
+    color: #2A3798;
+}
+.dirtab { padding: 4px;
+          border-collapse: collapse;
+          border: 1px solid #c8aa54;
+}
+TH.dirtab { background: #e8eef2;
+            font-weight: bold;
+}
+HR { height: 1px;
+     border: none;
+     border-top: 1px solid black;
+}
+
+/* Style for detailed member documentation */
+/*
+.memtemplate {
+  font-size: 80%;
+  color: #606060;
+  font-weight: normal;
+  margin-left: 3px;
+}
+*/
+.memtemplate {
+  white-space: nowrap;
+  font-weight: bold;
+}
+.memnav {
+  background-color: #e8eef2;
+  border: 1px solid #c8aa54;
+  text-align: center;
+  margin: 2px;
+  margin-right: 15px;
+  padding: 2px;
+}
+.memitem {
+/*  padding: 4px; */
+  padding: 0px 5px 0px 0px;
+/*  background-color: #eef3f5; */
+  background-color: #f8f0e0;
+  border-width: 1px;
+  border-style: solid;
+/*  border-color: #dedeee; */
+  border-color: #e0d0a0;
+  -moz-border-radius: 8px 8px 8px 8px;
+  margin-bottom: 20px;
+}
+.memname {
+  white-space: nowrap;
+  font-weight: bold;
+}
+.memdoc{
+  padding-left: 10px;
+}
+.memproto {
+  background-color: #e0d0a0;
+  width: 100%;
+  border-width: 1px;
+  border-style: solid;
+  border-color: #c8aa54;
+  font-weight: bold;
+  padding: 5px 0px 5px 5px; 
+  -moz-border-radius: 8px 8px 8px 8px;
+}
+.paramkey {
+  text-align: right;
+}
+.paramtype {
+  white-space: nowrap;
+}
+.paramname {
+  color: #602020;
+  font-style: italic;
+  white-space: nowrap;
+}
+/* End Styling for detailed member documentation */
+
+/* for the tree view */
+.ftvtree {
+    font-family: sans-serif;
+    margin:0.5em;
+}
+.directory { font-size: 9pt; font-weight: bold; }
+.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; }
+.directory > h3 { margin-top: 0; }
+.directory p { margin: 0px; white-space: nowrap; }
+.directory div { display: none; margin: 0px; }
+.directory img { vertical-align: -30%; }
diff --git a/docsrc/vigra_1_8_2.css b/docsrc/vigra_1_8_2.css
new file mode 100644
index 0000000..fc2180d
--- /dev/null
+++ b/docsrc/vigra_1_8_2.css
@@ -0,0 +1,1622 @@
+/* Customized css version 1.8.2 */
+
+body, /*table, */div, p, dl { /*removed*/
+	font: 400 14px/19px Roboto,sans-serif;
+}
+
+/* @group Heading Levels */
+
+h1.groupheader {
+	font-size: 150%;
+}
+
+.title {
+	font-size: 150%;
+	font-weight: bold;
+	margin: 10px 2px;
+}
+
+h2.groupheader {
+	/*border-bottom: 1px solid #879ECB;*/ /*removed*/
+	/*border-top: 1px solid #879ECB;*/ /*added*/
+	/*color: #354C7B;*/ /*removed*/
+	font-size: 150%;
+	font-weight: normal;
+	margin-top: 1.75em;
+	padding-top: 8px;
+	padding-bottom: 4px;
+	width: 100%;
+}
+
+h3.groupheader {
+	font-size: 100%;
+}
+
+h1, h2, h3, h4, h5, h6 {
+	-webkit-transition: text-shadow 0.5s linear;
+	-moz-transition: text-shadow 0.5s linear;
+	-ms-transition: text-shadow 0.5s linear;
+	-o-transition: text-shadow 0.5s linear;
+	transition: text-shadow 0.5s linear;
+	/*margin-right: 15px;*/ /*removed*/
+}
+
+h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
+	text-shadow: 0 0 15px cyan;
+}
+
+dt {
+	font-weight: bold;
+}
+
+div.multicol {
+	-moz-column-gap: 1em;
+	-webkit-column-gap: 1em;
+	-moz-column-count: 3;
+	-webkit-column-count: 3;
+}
+
+p.startli, p.startdd, p.starttd {
+	margin-top: 2px;
+}
+
+p.endli {
+	margin-bottom: 0px;
+}
+
+p.enddd {
+	margin-bottom: 4px;
+}
+
+p.endtd {
+	margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+	font-weight: bold;
+}
+
+span.legend {
+        font-size: 70%;
+        text-align: center;
+}
+
+h3.version {
+        font-size: 90%;
+        text-align: center;
+}
+
+div.qindex, div.navtab{
+	background-color: #EBEFF6;
+	border: 1px solid #A3B4D7;
+	text-align: center;
+}
+
+div.qindex, div.navpath {
+	width: 100%;
+	line-height: 140%;
+}
+
+div.navtab {
+	margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+	color: #3D578C;
+	font-weight: normal;
+	text-decoration: none;
+}
+
+.contents a:visited {
+	color: #4665A2;
+}
+
+a:hover {
+	text-decoration: underline;
+}
+
+a.qindex {
+	font-weight: bold;
+}
+
+a.qindexHL {
+	font-weight: bold;
+	background-color: #9CAFD4;
+	color: #ffffff;
+	border: 1px double #869DCA;
+}
+
+.contents a.qindexHL:visited {
+        color: #ffffff;
+}
+
+a.el {
+	font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code, a.code:visited {
+	color: #4665A2; 
+}
+
+a.codeRef, a.codeRef:visited {
+	color: #4665A2; 
+}
+
+/* @end */
+
+dl.el {
+	margin-left: -1cm;
+}
+
+pre.fragment {
+        border: 1px solid #C4CFE5;
+        background-color: #FBFCFD;
+        padding: 4px 6px;
+        margin: 4px 8px 4px 2px;
+        overflow: auto;
+        word-wrap: break-word;
+        font-size:  9pt;
+        line-height: 125%;
+        font-family: monospace, fixed;
+        font-size: 105%;
+}
+
+div.fragment {
+        padding: 4px;
+        margin: 4px;
+	background-color: #FBFCFD;
+	/*border: 1px solid #C4CFE5;*/
+	border: 1px solid #dad0aa; /*added*/
+}
+
+div.line {
+	font-family: monospace, fixed;
+        font-size: 13px;
+	min-height: 17px; /*changed 13*/
+	line-height: 1.0;
+	text-wrap: unrestricted;
+	white-space: -moz-pre-wrap; /* Moz */
+	white-space: -pre-wrap;     /* Opera 4-6 */
+	white-space: -o-pre-wrap;   /* Opera 7 */
+	white-space: pre-wrap;      /* CSS3  */
+	word-wrap: break-word;      /* IE 5.5+ */
+	text-indent: -53px; /*changed -53*/
+	padding-left: 53px;
+	padding-bottom: 0px;
+	margin: 0px;
+	-webkit-transition-property: background-color, box-shadow;
+	-webkit-transition-duration: 0.5s;
+	-moz-transition-property: background-color, box-shadow;
+	-moz-transition-duration: 0.5s;
+	-ms-transition-property: background-color, box-shadow;
+	-ms-transition-duration: 0.5s;
+	-o-transition-property: background-color, box-shadow;
+	-o-transition-duration: 0.5s;
+	transition-property: background-color, box-shadow;
+	transition-duration: 0.5s;
+}
+
+div.line.glow {
+	background-color: cyan;
+	box-shadow: 0 0 10px cyan;
+}
+
+
+span.lineno {
+	padding-right: 4px;
+	text-align: right;
+	/*border-right: 2px solid #0F0;*/ /*removed*/
+	/*background-color: #E8E8E8;*/ /*removed*/
+        white-space: pre; 
+}
+span.lineno a {
+	background-color: #D8D8D8;
+}
+
+span.lineno a:hover {
+	background-color: #C8C8C8;
+}
+
+div.ah {
+	background-color: black;
+	font-weight: bold;
+	color: #ffffff;
+	margin-bottom: 3px;
+	margin-top: 3px;
+	padding: 0.2em;
+	border: solid thin #333;
+	border-radius: 0.5em;
+	-webkit-border-radius: .5em;
+	-moz-border-radius: .5em;
+	box-shadow: 2px 2px 3px #999;
+	-webkit-box-shadow: 2px 2px 3px #999;
+	-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+	background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+	margin-left: 16px;
+	margin-top: 12px;
+	font-weight: bold;
+}
+
+div.groupText {
+	margin-left: 16px;
+	font-style: italic;
+}
+
+body {
+	background-color: white;
+	color: black;
+        margin: 0;
+}
+
+/*div.contents {
+	margin-top: 10px;
+	margin-left: 12px;
+	margin-right: 8px;
+}*/ /*removed*/
+
+td.indexkey {
+	background-color: #EBEFF6;
+	font-weight: bold;
+	border: 1px solid #C4CFE5;
+	margin: 2px 0px 2px 0;
+	padding: 2px 10px;
+        white-space: nowrap;
+        vertical-align: top;
+}
+
+td.indexvalue {
+	background-color: #EBEFF6;
+	border: 1px solid #C4CFE5;
+	padding: 2px 10px;
+	margin: 2px 0px;
+}
+
+tr.memlist {
+	background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+	text-align: center;
+}
+
+img.formulaDsp {
+	
+}
+
+img.formulaInl {
+	vertical-align: middle;
+}
+
+div.center {
+	text-align: center;
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding: 0px;
+}
+
+div.center img {
+	border: 0px;
+}
+
+address.footer {
+	text-align: right;
+	padding-right: 12px;
+}
+
+img.footer {
+	border: 0px;
+	vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+	color: #008000
+}
+
+span.keywordtype {
+	color: #604020
+}
+
+span.keywordflow {
+	color: #e08000
+}
+
+span.comment {
+	color: #800000
+}
+
+span.preprocessor {
+	color: #806020
+}
+
+span.stringliteral {
+	color: #002080
+}
+
+span.charliteral {
+	color: #008080
+}
+
+span.vhdldigit { 
+	color: #ff00ff 
+}
+
+span.vhdlchar { 
+	color: #000000 
+}
+
+span.vhdlkeyword { 
+	color: #700070 
+}
+
+span.vhdllogic { 
+	color: #ff0000 
+}
+
+blockquote {
+        background-color: #F7F8FB;
+        border-left: 2px solid #9CAFD4;
+        margin: 0 24px 0 4px;
+        padding: 0 12px 0 16px;
+}
+
+/* @end */
+
+/*
+.search {
+	color: #003399;
+	font-weight: bold;
+}
+
+form.search {
+	margin-bottom: 0px;
+	margin-top: 0px;
+}
+
+input.search {
+	font-size: 75%;
+	color: #000080;
+	font-weight: normal;
+	background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+	font-size: 75%;
+}
+
+.dirtab {
+	padding: 4px;
+	border-collapse: collapse;
+	border: 1px solid #A3B4D7;
+}
+
+th.dirtab {
+	background: #EBEFF6;
+	font-weight: bold;
+}
+
+hr {
+	height: 0px;
+	border: none;
+	border-top: 1px solid #4A6AAA;
+}
+
+hr.footer {
+	height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+	border-spacing: 0px;
+	padding: 0px;
+}
+
+.memberdecls td, .fieldtable tr {
+	-webkit-transition-property: background-color, box-shadow;
+	-webkit-transition-duration: 0.5s;
+	-moz-transition-property: background-color, box-shadow;
+	-moz-transition-duration: 0.5s;
+	-ms-transition-property: background-color, box-shadow;
+	-ms-transition-duration: 0.5s;
+	-o-transition-property: background-color, box-shadow;
+	-o-transition-duration: 0.5s;
+	transition-property: background-color, box-shadow;
+	transition-duration: 0.5s;
+}
+
+.memberdecls td.glow, .fieldtable tr.glow {
+	background-color: cyan;
+	box-shadow: 0 0 15px cyan;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+	background-color: #F9FAFC;
+	border: none;
+	margin: 4px;
+	padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+	padding: 0px 8px 4px 8px;
+	color: #555;
+}
+
+.memSeparator {
+        border-bottom: 1px solid #DEE4F0;
+        line-height: 1px;
+        margin: 0px;
+        padding: 0px;
+}
+
+.memItemLeft, .memTemplItemLeft {
+        white-space: nowrap;
+}
+
+/*.memItemRight {
+	width: 100%;
+}*/
+
+.memTemplParams {
+	color: #4665A2;
+        white-space: nowrap;
+	font-size: 80%;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+	font-size: 80%;
+	color: #4665A2;
+	font-weight: normal;
+	margin-left: 9px;
+}
+
+.memnav {
+	background-color: #EBEFF6;
+	border: 1px solid #A3B4D7;
+	text-align: center;
+	margin: 2px;
+	margin-right: 15px;
+	padding: 2px;
+}
+
+.mempage {
+	width: 100%;
+}
+
+
+/*.memitem {*/
+/*  padding: 4px; */
+/*  padding: 0px 5px 0px 0px;*/
+/*  background-color: #eef3f5; */
+/*  background-color: #f8f0e0;
+  border-width: 1px;
+  border-style: solid;*/
+/*  border-color: #dedeee; */
+/*  border-color: #e0d0a0;
+  -moz-border-radius: 8px 8px 8px 8px;
+  margin-bottom: 20px;
+}*/
+/*.memitem {
+	padding: 0;
+	margin-bottom: 10px;
+	margin-right: 5px;
+        -webkit-transition: box-shadow 0.5s linear;
+        -moz-transition: box-shadow 0.5s linear;
+        -ms-transition: box-shadow 0.5s linear;
+        -o-transition: box-shadow 0.5s linear;
+        transition: box-shadow 0.5s linear;
+        display: table !important;
+        width: 100%;
+}*/
+
+.memitem.glow {
+         box-shadow: 0 0 15px cyan;
+}
+
+/*.memname {
+        font-weight: bold;
+        margin-left: 6px;
+}*/ /*removed*/
+
+/*.memname td {
+	vertical-align: bottom;
+}*/ /*removed*/
+
+
+/*.memproto, */ dl.reflist dt { /*removed*/
+	background-color: #e0d0a0;
+	/*width: 100%;*/
+  	border-width: 1px;
+  	border-style: solid;
+  	border-color: #c8aa54;
+
+        /*border-top: 1px solid #A8B8D9;
+        border-left: 1px solid #A8B8D9;
+        border-right: 1px solid #A8B8D9;*/
+
+        padding: 6px 0px 6px 0px;
+        color: #000000; /*#253555;*/
+        font-weight: bold;
+        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+        /*background-image:url('nav_f.png');*/
+        /*background-repeat:repeat-x;*/
+        /*background-color: #E2E8F2;*/ /*removed*/
+	/*background-color: #f8f0e0;*/ /*added*/
+        /* opera specific markup */
+        /*box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        border-top-right-radius: 4px;
+        border-top-left-radius: 4px;*/
+        /* firefox specific markup */
+        /*-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        -moz-border-radius-topright: 4px;
+        -moz-border-radius-topleft: 4px;*/
+        /* webkit specific markup */
+        /*-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        -webkit-border-top-right-radius: 4px;
+        -webkit-border-top-left-radius: 4px;*/
+
+}
+
+/*.memdoc, */dl.reflist dd { /*removed*/
+        /*border-bottom: 1px solid #A8B8D9;      
+        border-left: 1px solid #A8B8D9;      
+        border-right: 1px solid #A8B8D9;*/
+	border-width: 1px;
+	border-style: solid;
+	border-color: #c8aa54;
+        padding: 6px 10px 2px 10px;
+        background-color: #FBFCFD;
+        border-top-width: 0;
+        /*background-image:url('nav_g.png');*/
+        /*background-repeat:repeat-x;*/
+        background-color: #f8f0e0;/*#FFFFFF;*/
+        /* opera specific markup */
+        /*border-bottom-left-radius: 4px;
+        border-bottom-right-radius: 4px;
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);*/
+        /* firefox specific markup */
+        /*-moz-border-radius-bottomleft: 4px;
+        -moz-border-radius-bottomright: 4px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;*/
+        /* webkit specific markup */
+        /*-webkit-border-bottom-left-radius: 4px;
+        -webkit-border-bottom-right-radius: 4px;
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);*/
+}
+
+dl.reflist dt {
+        padding: 5px;
+}
+
+dl.reflist dd {
+        margin: 0px 0px 10px 0px;
+        padding: 5px;
+}
+
+.paramkey {
+	text-align: right;
+}
+
+.paramtype {
+	white-space: nowrap;
+}
+
+.paramname {
+	color: #602020;
+	white-space: nowrap;
+}
+.paramname em {
+	font-style: normal;
+}
+.paramname code {
+        line-height: 14px;
+}
+
+.params, .retval, .exception, .tparams {
+        margin-left: 0px;
+        padding-left: 0px;
+}       
+
+.params .paramname, .retval .paramname {
+        font-weight: bold;
+        vertical-align: top;
+}
+        
+.params .paramtype {
+        font-style: italic;
+        vertical-align: top;
+}       
+        
+.params .paramdir {
+        font-family: "courier new",courier,monospace;
+        vertical-align: top;
+}
+
+table.mlabels {
+	border-spacing: 0px;
+}
+
+td.mlabels-left {
+	width: 100%;
+	padding: 0px;
+}
+
+td.mlabels-right {
+	vertical-align: bottom;
+	padding: 0px;
+	white-space: nowrap;
+}
+
+span.mlabels {
+        margin-left: 8px;
+}
+
+span.mlabel {
+        background-color: #728DC1;
+        border-top:1px solid #5373B4;
+        border-left:1px solid #5373B4;
+        border-right:1px solid #C4CFE5;
+        border-bottom:1px solid #C4CFE5;
+	text-shadow: none;
+	color: white;
+	margin-right: 4px;
+	padding: 2px 3px;
+	border-radius: 3px;
+	font-size: 7pt;
+	white-space: nowrap;
+	vertical-align: middle;
+}
+
+
+
+/* @end */
+
+/* these are for tree view when not used as main index */
+
+div.directory {
+        margin: 10px 0px;
+        border-top: 1px solid #A8B8D9;
+        border-bottom: 1px solid #A8B8D9;
+        width: 100%;
+}
+
+.directory table {
+        border-collapse:collapse;
+}
+
+.directory td {
+        margin: 0px;
+        padding: 0px;
+	vertical-align: top;
+}
+
+.directory td.entry {
+        white-space: nowrap;
+        padding-right: 6px;
+}
+
+.directory td.entry a {
+        outline:none;
+}
+
+.directory td.entry a img {
+        border: none;
+}
+
+.directory td.desc {
+        width: 100%;
+        padding-left: 6px;
+	padding-right: 6px;
+	padding-top: 3px;
+	border-left: 1px solid rgba(0,0,0,0.05);
+}
+
+.directory tr.even {
+	padding-left: 6px;
+	background-color: #F7F8FB;
+}
+
+.directory img {
+	vertical-align: -30%;
+}
+
+.directory .levels {
+        white-space: nowrap;
+        width: 100%;
+        text-align: right;
+        font-size: 9pt;
+}
+
+.directory .levels span {
+        cursor: pointer;
+        padding-left: 2px;
+        padding-right: 2px;
+	color: #3D578C;
+}
+
+div.dynheader {
+        margin-top: 8px;
+	-webkit-touch-callout: none;
+	-webkit-user-select: none;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+address {
+	font-style: normal;
+	color: #2A3D61;
+}
+
+table.doxtable {
+	border-collapse:collapse;
+        margin-top: 4px;
+        margin-bottom: 4px;
+}
+
+table.doxtable td, table.doxtable th {
+	border: 1px solid #2D4068;
+	padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+	background-color: #374F7F;
+	color: #FFFFFF;
+	font-size: 110%;
+	padding-bottom: 4px;
+	padding-top: 5px;
+}
+
+table.fieldtable {
+        width: 100%;
+        margin-bottom: 10px;
+        border: 1px solid #A8B8D9;
+        border-spacing: 0px;
+        -moz-border-radius: 4px;
+        -webkit-border-radius: 4px;
+        border-radius: 4px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+        -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+        box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+}
+
+.fieldtable td, .fieldtable th {
+        padding: 3px 7px 2px;
+}
+
+.fieldtable td.fieldtype, .fieldtable td.fieldname {
+        white-space: nowrap;
+        border-right: 1px solid #A8B8D9;
+        border-bottom: 1px solid #A8B8D9;
+        vertical-align: top;
+}
+
+.fieldtable td.fielddoc {
+        border-bottom: 1px solid #A8B8D9;
+        width: 100%;
+}
+
+.fieldtable tr:last-child td {
+        border-bottom: none;
+}
+
+.fieldtable th {
+        background-image:url('nav_f.png');
+        background-repeat:repeat-x;
+        background-color: #E2E8F2;
+        font-size: 90%;
+        color: #253555;
+        padding-bottom: 4px;
+        padding-top: 5px;
+        text-align:left;
+        -moz-border-radius-topleft: 4px;
+        -moz-border-radius-topright: 4px;
+        -webkit-border-top-left-radius: 4px;
+        -webkit-border-top-right-radius: 4px;
+        border-top-left-radius: 4px;
+        border-top-right-radius: 4px;
+        border-bottom: 1px solid #A8B8D9;
+}
+
+
+.tabsearch {
+	top: 0px;
+	left: 10px;
+	height: 36px;
+	background-image: url('tab_b.png');
+	z-index: 101;
+	overflow: hidden;
+	font-size: 13px;
+}
+
+.navpath ul
+{
+	font-size: 11px;
+	background-image:url('tab_b.png');
+	background-repeat:repeat-x;
+	background-position: 0 -5px;
+	height:30px;
+	line-height:30px;
+	color:#8AA0CC;
+	border:solid 1px #C2CDE4;
+	overflow:hidden;
+	margin:0px;
+	padding:0px;
+}
+
+.navpath li
+{
+	list-style-type:none;
+	float:left;
+	padding-left:10px;
+	padding-right:15px;
+	background-image:url('bc_s.png');
+	background-repeat:no-repeat;
+	background-position:right;
+	color:#364D7C;
+}
+
+.navpath li.navelem a
+{
+	height:32px;
+	display:block;
+	text-decoration: none;
+	outline: none;
+	color: #283A5D;
+	font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+	text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+	text-decoration: none;        
+}
+
+.navpath li.navelem a:hover
+{
+	color:#6884BD;
+}
+
+.navpath li.footer
+{
+        list-style-type:none;
+        float:right;
+        padding-left:10px;
+        padding-right:15px;
+        background-image:none;
+        background-repeat:no-repeat;
+        background-position:right;
+        color:#364D7C;
+        font-size: 8pt;
+}
+
+
+div.summary
+{
+	float: right;
+	font-size: 8pt;
+	padding-right: 5px;
+	width: 50%;
+	text-align: right;
+}       
+
+div.summary a
+{
+	white-space: nowrap;
+}
+
+/*div.ingroups
+{
+	font-size: 8pt;
+	width: 50%;
+	text-align: left;
+}*/ /*removed*/
+
+div.ingroups a
+{
+	white-space: nowrap;
+}
+
+div.header
+{
+        background-image:url('nav_h.png');
+        background-repeat:repeat-x;
+	background-color: #F9FAFC;
+	margin:  0px;
+	border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+	padding: 5px 5px 5px 10px;
+}
+
+dl
+{
+        padding: 0 0 0 10px;
+}
+
+/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */
+dl.section
+{
+	margin-left: 0px;
+	padding-left: 0px;
+}
+
+dl.note
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #D0C000;
+}
+
+dl.warning, dl.attention
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #00D000;
+}
+
+dl.deprecated
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #505050;
+}
+
+dl.todo
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #00C0E0;
+}
+
+dl.test
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #3030E0;
+}
+
+dl.bug
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #C08050;
+}
+
+dl.section dd {
+	margin-bottom: 6px;
+}
+
+
+#projectlogo
+{
+	text-align: center;
+	vertical-align: bottom;
+	border-collapse: separate;
+}
+ 
+#projectlogo img
+{ 
+	border: 0px none;
+}
+ 
+#projectname
+{
+	font: 300% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 2px 0px;
+}
+    
+#projectbrief
+{
+	font: 120% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#projectnumber
+{
+	font: 50% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#titlearea
+{
+	padding: 0px;
+	margin: 0px;
+	width: 100%;
+	border-bottom: 1px solid #5373B4;
+}
+
+.image
+{
+        text-align: center;
+}
+
+.dotgraph
+{
+        text-align: center;
+}
+
+.mscgraph
+{
+        text-align: center;
+}
+
+.caption
+{
+	font-weight: bold;
+}
+
+div.zoom
+{
+	border: 1px solid #90A5CE;
+}
+
+dl.citelist {
+        margin-bottom:50px;
+}
+
+dl.citelist dt {
+        color:#334975;
+        float:left;
+        font-weight:bold;
+        margin-right:10px;
+        padding:5px;
+}
+
+dl.citelist dd {
+        margin:2px 0;
+        padding:5px 0;
+}
+
+div.toc {
+        padding: 14px 25px;
+        background-color: #F4F6FA;
+        border: 1px solid #D8DFEE;
+        border-radius: 7px 7px 7px 7px;
+        float: right;
+        height: auto;
+        margin: 0 20px 10px 10px;
+        width: 200px;
+}
+
+div.toc li {
+        background: url("bdwn.png") no-repeat scroll 0 5px transparent;
+        font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
+        margin-top: 5px;
+        padding-left: 10px;
+        padding-top: 2px;
+}
+
+div.toc h3 {
+        font: bold 12px/1.2 Arial,FreeSans,sans-serif;
+	color: #4665A2;
+        border-bottom: 0 none;
+        margin: 0;
+}
+
+div.toc ul {
+        list-style: none outside none;
+        border: medium none;
+        padding: 0px;
+}       
+
+div.toc li.level1 {
+        margin-left: 0px;
+}
+
+div.toc li.level2 {
+        margin-left: 15px;
+}
+
+div.toc li.level3 {
+        margin-left: 30px;
+}
+
+div.toc li.level4 {
+        margin-left: 45px;
+}
+
+.inherit_header {
+        font-weight: bold;
+        color: gray;
+        cursor: pointer;
+	-webkit-touch-callout: none;
+	-webkit-user-select: none;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+.inherit_header td {
+        padding: 6px 0px 2px 5px;
+}
+
+.inherit {
+        display: none;
+}
+
+tr.heading h2 {
+        margin-top: 12px;
+        margin-bottom: 4px;
+}
+
+ at media print
+{
+  #top { display: none; }
+  #side-nav { display: none; }
+  #nav-path { display: none; }
+  body { overflow:visible; }
+  h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
+  .summary { display: none; }
+  .memitem { page-break-inside: avoid; }
+  #doc-content
+  {
+    margin-left:0 !important;
+    height:auto !important;
+    width:auto !important;
+    overflow:inherit;
+    display:inline;
+  }
+}
+
+
+
+/* Customized css version 1.5.6 */
+
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+    font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+BODY,TD {
+       font-size: 90%;
+}
+H1 {
+    background-color: #e0d0a0;
+    padding: 0.5em;
+    text-align: center;
+    font-size: 160%;
+}
+H2 {
+       font-size: 120%;
+}
+H2.details_section {
+    background-color: #e0d0a0;
+    padding: 0.5em;
+    font-size: 140%;
+    text-align: center;
+}
+H3.details_section {
+    background-color: #e0d0a0;
+    padding: 0.5em;
+    border-width: 1px;
+    border-style: solid;
+    border-color: #c8aa54;
+    -moz-border-radius: 8px 8px 8px 8px;
+}
+.main_heading {
+    background-color: #e0d0a0;
+    padding: 1em;
+    text-align: center;
+    font-size: 200%;
+    border: 0px;
+    padding: 5px;
+    font-weight: bold;
+}
+.ingroups {
+    font-size: 60%;
+}
+H3 {
+       font-size: 100%;
+}
+table.function_index {
+    background-color: #e0d0a0;
+    padding: 0.3em;
+    font-size: 120%;
+    width: 100%;
+}
+CAPTION { font-weight: bold }
+DIV.qindex {
+    width: 100%;
+    background-color: #e0d0a0;
+    border: 1px solid #c8aa54;
+    text-align: center;
+    margin: 2px;
+    padding: 2px;
+    line-height: 140%;
+}
+DIV.nav {
+    width: 100%;
+    background-color: #e8eef2;
+    border: 1px solid #c8aa54;
+    text-align: center;
+    margin: 2px;
+    padding: 2px;
+    line-height: 140%;
+}
+DIV.navtab {
+       background-color: #e8eef2;
+       border: 1px solid #c8aa54;
+       text-align: center;
+       margin: 2px;
+       margin-right: 15px;
+       padding: 2px;
+}
+TD.navtab {
+       font-size: 70%;
+}
+A.qindex {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D;
+}
+A.qindex:visited {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D
+}
+A.qindex:hover {
+    text-decoration: none;
+    background-color: #ddddff;
+}
+A.qindexHL {
+    text-decoration: none;
+    font-weight: bold;
+    background-color: #6666cc;
+    color: #ffffff;
+    border: 1px double #9295C2;
+}
+A.qindexHL:hover {
+    text-decoration: none;
+    background-color: #6666cc;
+    color: #ffffff;
+}
+A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.el { text-decoration: none; font-weight: bold }
+A:link { color: #0040b0; }
+A:visited { color: #a00040; }
+A:hover { text-decoration: none; background-color: #f2f2ff }
+A.anchor { color: #000000;   text-decoration: none; background-color: none; }
+A.elRef { font-weight: bold }
+A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
+A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
+A.codeRef:link { font-weight: normal; color: #0000FF}
+A.codeRef:visited { font-weight: normal; color: #0000FF}
+code  { 
+/*    font-family: Lucida Console, monospace, fixed; */
+    font-family: monospace, fixed;
+    color: #303030; 
+    font-weight: bold;
+} 
+DL.el { margin-left: -1cm }
+.fragment {
+/*    font-family: Lucida Console, monospace, fixed; */
+    font-family: monospace, fixed;
+       font-size: 95%;
+}
+PRE.fragment {
+/*  border: 1px solid #c8aa54; */
+    border: 1px solid #dad0aa;
+    background-color: #fcfaf8;
+    margin-top: 4px;
+    margin-bottom: 4px;
+    margin-left: 2px;
+    margin-right: 8px;
+    padding-left: 6px;
+    padding-right: 6px;
+    padding-top: 4px;
+    padding-bottom: 4px;
+}
+DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
+
+DIV.groupHeader {
+       margin-left: 16px;
+       margin-top: 12px;
+       margin-bottom: 6px;
+       font-weight: bold;
+}
+DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
+BODY {
+    background: #f8f0e0;
+    color: black;
+    margin-right: 20px;
+    margin-left: 20px;
+}
+TD.indexkey {
+/*  background-color: #e8eef2; */
+    background-color: #f8f0e0;
+    font-weight: bold;
+    padding-right  : 10px;
+    padding-top    : 2px;
+    padding-left   : 10px;
+    padding-bottom : 2px;
+    margin-left    : 0px;
+    margin-right   : 0px;
+    margin-top     : 2px;
+    margin-bottom  : 2px;
+/*  border: 1px solid #CCCCCC; */
+    border: 1px solid #e0d0a0;
+}
+TD.indexvalue {
+/*  background-color: #e8eef2; */
+    background-color: #f8f0e0;
+    font-style: italic;
+    padding-right  : 10px;
+    padding-top    : 2px;
+    padding-left   : 10px;
+    padding-bottom : 2px;
+    margin-left    : 0px;
+    margin-right   : 0px;
+    margin-top     : 2px;
+    margin-bottom  : 2px;
+/*  border: 1px solid #CCCCCC; */
+    border: 1px solid #e0d0a0;
+}
+TR.memlist {
+   background-color: #f0f0f0;
+}
+P.formulaDsp { text-align: center; }
+IMG.formulaDsp { }
+IMG.formulaInl { vertical-align: middle; }
+SPAN.keyword       { color: #008000 }
+SPAN.keywordtype   { color: #604020 }
+SPAN.keywordflow   { color: #e08000 }
+SPAN.comment       { color: #800000 }
+SPAN.preprocessor  { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral   { color: #008080 }
+.mdescLeft {
+    padding: 0px 8px 4px 8px;
+    font-size: 80%;
+    font-style: italic;
+    background-color: #fcfaf8;
+    border-top: 1px none #dad0a8;
+    border-right: 1px none #dad0a8;
+    border-bottom: 1px none #dad0a8;
+    border-left: 1px none #dad0a8;
+    margin: 0px;
+}
+.mdescRight {
+    padding: 0px 8px 4px 8px; 
+    font-size: 80%;
+    font-style: italic;
+    background-color: #fcfaf8;
+    border-top: 1px none #dad0a8;
+    border-right: 1px none #dad0a8;
+    border-bottom: 1px none #dad0a8;
+    border-left: 1px none #dad0a8;
+    margin: 0px;
+}
+.memItemLeft {
+    padding: 1px 0px 0px 8px;
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #dad0a8;
+    border-right-color: #dad0a8;
+    border-bottom-color: #dad0a8;
+    border-left-color: #dad0a8;
+    border-top-style: solid;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #fcfaf8;
+    font-size: 80%;
+}
+.memItemRight {
+    padding: 1px 8px 0px 8px; 
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #dad0a8;
+    border-right-color: #dad0a8;
+    border-bottom-color: #dad0a8;
+    border-left-color: #dad0a8;
+    border-top-style: solid;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #fcfaf8;
+    font-size: 80%;
+}
+.memTemplItemLeft {
+    padding: 1px 0px 0px 8px; 
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #dad0a8;
+    border-right-color: #dad0a8;
+    border-bottom-color: #dad0a8;
+    border-left-color: #dad0a8;
+    border-top-style: none;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #fcfaf8;
+    font-size: 80%;
+}
+.memTemplItemRight {
+    padding: 1px 8px 0px 8px; 
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #dad0a8;
+    border-right-color: #dad0a8;
+    border-bottom-color: #dad0a8;
+    border-left-color: #dad0a8;
+    border-top-style: none;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+    background-color: #fcfaf8;
+    font-size: 80%;
+}
+.memTemplParams {
+    padding: 1px 0px 0px 8px; 
+    margin: 4px;
+    border-top-width: 1px;
+    border-right-width: 1px;
+    border-bottom-width: 1px;
+    border-left-width: 1px;
+    border-top-color: #dad0a8;
+    border-right-color: #dad0a8;
+    border-bottom-color: #dad0a8;
+    border-left-color: #dad0a8;
+    border-top-style: solid;
+    border-right-style: none;
+    border-bottom-style: none;
+    border-left-style: none;
+/*       color: #606060; */
+    background-color: #fcfaf8;
+    font-size: 80%;
+}
+.search     { color: #003399;
+              font-weight: bold;
+}
+FORM.search {
+              margin-bottom: 0px;
+              margin-top: 0px;
+}
+INPUT.search { font-size: 75%;
+               color: #000080;
+               font-weight: normal;
+               background-color: #e8eef2;
+}
+TD.tiny      { font-size: 75%;
+}
+a {
+    color: #1A41A8;
+}
+a:visited {
+    color: #2A3798;
+}
+.dirtab { padding: 4px;
+          border-collapse: collapse;
+          border: 1px solid #c8aa54;
+}
+TH.dirtab { background: #e8eef2;
+            font-weight: bold;
+}
+HR { height: 1px;
+     border: none;
+     border-top: 1px solid black;
+}
+
+/* Style for detailed member documentation */
+/*
+.memtemplate {
+  font-size: 80%;
+  color: #606060;
+  font-weight: normal;
+  margin-left: 3px;
+}
+*/
+.memtemplate {
+  white-space: nowrap;
+  font-weight: bold;
+}
+.memnav {
+  background-color: #e8eef2;
+  border: 1px solid #c8aa54;
+  text-align: center;
+  margin: 2px;
+  margin-right: 15px;
+  padding: 2px;
+}
+.memitem {
+/*  padding: 4px; */
+  padding: 0px 5px 0px 0px;
+/*  background-color: #eef3f5; */
+  background-color: #f8f0e0;
+  border-width: 1px;
+  border-style: solid;
+/*  border-color: #dedeee; */
+  border-color: #e0d0a0;
+  -moz-border-radius: 8px 8px 8px 8px;
+  margin-bottom: 20px;
+}
+.memname {
+  white-space: nowrap;
+  font-weight: bold;
+}
+.memdoc{
+  padding-left: 10px;
+}
+.memproto {
+  background-color: #e0d0a0;
+  width: 100%;
+  border-width: 1px;
+  border-style: solid;
+  border-color: #c8aa54;
+  font-weight: bold;
+  padding: 5px 0px 5px 5px; 
+  -moz-border-radius: 8px 8px 8px 8px;
+}
+.paramkey {
+  text-align: right;
+}
+.paramtype {
+  white-space: nowrap;
+}
+.paramname {
+  color: #602020;
+  font-style: italic;
+  white-space: nowrap;
+}
+/* End Styling for detailed member documentation */
+
+/* for the tree view */
+.ftvtree {
+    font-family: sans-serif;
+    margin:0.5em;
+}
+.directory { font-size: 9pt; font-weight: bold; }
+.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; }
+.directory > h3 { margin-top: 0; }
+.directory p { margin: 0px; white-space: nowrap; }
+.directory div { display: none; margin: 0px; }
+.directory img { vertical-align: -30%; }
diff --git a/include/vigra/accessor.hxx b/include/vigra/accessor.hxx
new file mode 100644
index 0000000..60c15b6
--- /dev/null
+++ b/include/vigra/accessor.hxx
@@ -0,0 +1,1023 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_ACCESSOR_HXX
+#define VIGRA_ACCESSOR_HXX
+
+#include "metaprogramming.hxx"
+#include "numerictraits.hxx"
+#include "tuple.hxx"
+
+namespace vigra {
+
+/** \addtogroup DataAccessors Data Accessors
+
+Basic templates to encapsulate access to the data of an iterator.
+
+Data accessors are used to allow for flexible access to the data
+an iterator points to. When we access the data directly, we
+are bound to what <TT>operator*()</TT> returns, if this method exists at
+all. Encapsulating access in an accessor enables a better
+decoupling of data structures and algorithms.
+<a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/DataAccessors.ps">This paper</a> contains
+a detailed description of the concept. Here is a brief list of the basic
+accessor requirements:
+
+<p>
+<table border=2 cellspacing=0 cellpadding=2 width="100%">
+<tr><th>
+    Operation
+    </th><th>
+    Result
+    </th><th>
+    Semantics
+    </th>
+</tr>
+<tr>
+    <td><tt>accessor(iter)</tt></td><td>convertible to <br><tt>Accessor::value_type const &</tt></td>
+    <td>read data at the current position of the iterator</td>
+</tr>
+<tr>
+    <td><tt>accessor(iter, index)</tt></td><td>convertible to <br><tt>Accessor::value_type const &</tt></td>
+    <td>read data at offset <tt>index</tt> relative to iterator's current position
+    (random-access iterator only)</td>
+</tr>
+<tr>
+    <td><tt>accessor.set(value, iter)</tt></td><td><tt>void</tt></td>
+    <td>write data <tt>value</tt> at the current position of the iterator (mutable iterator only)</td>
+</tr>
+<tr>
+    <td><tt>accessor.set(value, iter, index)</tt></td><td><tt>void</tt></td>
+    <td>write data <tt>value</tt> at offset <tt>index</tt> relative to iterator's current position
+    (mutable random-access iterator only)</td>
+</tr>
+<tr><td colspan=2>
+    <tt>Accessor::value_type</tt></td>
+    <td>type of the data field the accessor refers to</td>
+</tr>
+<tr><td colspan=3>
+        <tt>iter</tt> is an iterator<br>
+        <tt>index</tt> has the iterator's index type (<tt>Iterator::difference_type</tt>)<br>
+        <tt>value</tt> is convertible to <tt>Accessor::value_type const &</tt>
+    </td>
+</tr>
+</table>
+</p>
+
+The template <tt>AccessorTraits<T></tt> can be used to find the default accessor
+associated with the type <tt>T</tt>, e.g.
+
+\code
+typedef typename AccessorTraits<typename Image::value_type>::default_accessor       Accessor;
+typedef typename AccessorTraits<typename Image::value_type>::default_const_accessor ConstAccessor;
+\endcode
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                     StandardAccessor                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Encapsulate access to the values an iterator points to.
+
+    StandardAccessor is a trivial accessor that simply encapsulates
+    the iterator's operator*() and operator[]() in its
+    read and write functions. It passes its arguments <em>by reference</em>.
+    If you want to return items by value, you
+    must use StandardValueAccessor instead of StandardAccessor.
+    Both accessors have different optimization properties --
+    StandardAccessor is usually faster for compound pixel types,
+    while StandardValueAccessor is faster for the built-in types.
+
+    When a floating point number is assigned by means of an accessor
+    with integral value_type, the value is rounded and clipped as appropriate.
+
+    <b>\#include</b> \<vigra/accessor.hxx\><br>
+    Namespace: vigra
+*/
+template <class VALUETYPE>
+class StandardAccessor
+{
+  public:
+        /** the value_type
+        */
+    typedef VALUETYPE value_type;
+
+        /** read the current data item
+        */
+    template <class ITERATOR>
+    VALUETYPE const & operator()(ITERATOR const & i) const { return *i; }
+
+    VALUETYPE const & operator()(VALUETYPE const * i) const { return *i; }
+
+        /** read the data item at an offset (can be 1D or 2D or higher order difference).
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    VALUETYPE const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
+    {
+        return i[diff];
+    }
+
+        /** Write the current data item. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR>
+    void set(V const & value, ITERATOR const & i) const
+    { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
+
+        /* This overload is needed to make the accessor work with a std::back_inserter */
+    template <class V, class ITERATOR>
+    void set(V const & value, ITERATOR & i) const
+    { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
+
+        /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
+            The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR, class DIFFERENCE>
+    void set(V const & value, ITERATOR const & i, DIFFERENCE const & diff) const
+    {
+        i[diff]= detail::RequiresExplicitCast<VALUETYPE>::cast(value);
+    }
+};
+
+/** \brief Encapsulate access to the values an iterator points to.
+
+    StandardValueAccessor is a trivial accessor that simply encapsulates
+    the iterator's operator*() and operator[]() in its
+    read and write functions. It passes its arguments <em>by value</em>.
+    If the iterator returns its items by reference (such as \ref vigra::ImageIterator),
+    you can also use StandardAccessor.
+    These accessors have different optimization properties --
+    StandardAccessor is usually faster for compound pixel types,
+    while StandardValueAccessor is faster for the built-in types.
+
+    When a floating point number is assigned by means of an accessor
+    with integral value_type, the value is rounded and clipped as appropriate.
+
+    <b>\#include</b> \<vigra/accessor.hxx\><br>
+    Namespace: vigra
+*/
+template <class VALUETYPE>
+class StandardValueAccessor
+{
+  public:
+        /** the value_type
+        */
+    typedef VALUETYPE value_type;
+
+        /** Read the current data item. The type <TT>ITERATOR::reference</TT>
+            is automatically converted to <TT>VALUETYPE</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class ITERATOR>
+    VALUETYPE operator()(ITERATOR const & i) const
+        { return detail::RequiresExplicitCast<VALUETYPE>::cast(*i); }
+
+        /** Read the data item at an offset (can be 1D or 2D or higher order difference).
+            The type <TT>ITERATOR::index_reference</TT>
+            is automatically converted to <TT>VALUETYPE</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    VALUETYPE operator()(ITERATOR const & i, DIFFERENCE const & diff) const
+    {
+        return detail::RequiresExplicitCast<VALUETYPE>::cast(i[diff]);
+    }
+        /** Write the current data item. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR>
+    void set(V value, ITERATOR const & i) const
+        { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
+
+        /* This overload is needed to make the accessor work with a std::back_inserter */
+    template <class V, class ITERATOR>
+    void set(V value, ITERATOR & i) const
+        { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
+
+        /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
+            The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR, class DIFFERENCE>
+    void set(V value, ITERATOR const & i, DIFFERENCE const & diff) const
+    {
+        i[diff]= detail::RequiresExplicitCast<VALUETYPE>::cast(value);
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                StandardConstAccessor                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Encapsulate read access to the values an iterator points to.
+
+    StandardConstAccessor is a trivial accessor that simply encapsulates
+    the iterator's operator*() and operator[]() in its
+    read functions. It passes its arguments <em>by reference</em>.
+    If the iterator returns its items by value (such as \ref vigra::CoordinateIterator), you
+    must use StandardConstValueAccessor instead of StandardConstAccessor.
+    Both accessors also have different optimization properties --
+    StandardConstAccessor is usually faster for compound pixel types,
+    while StandardConstValueAccessor is faster for the built-in types.
+
+    <b>\#include</b> \<vigra/accessor.hxx\><br>
+    Namespace: vigra
+*/
+template <class VALUETYPE>
+class StandardConstAccessor
+{
+  public:
+    typedef VALUETYPE value_type;
+
+        /** read the current data item
+        */
+    template <class ITERATOR>
+    VALUETYPE const & operator()(ITERATOR const & i) const
+        { return *i; }
+
+        /** read the data item at an offset (can be 1D or 2D or higher order difference).
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    VALUETYPE const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
+    {
+        return i[diff];
+    }
+};
+
+/** \brief Encapsulate access to the values an iterator points to.
+
+    StandardConstValueAccessor is a trivial accessor that simply encapsulates
+    the iterator's operator*() and operator[]() in its
+    read functions. It passes its arguments <em>by value</em>.
+    If the iterator returns its items by reference (such as \ref vigra::ConstImageIterator),
+    you can also use StandardConstAccessor.
+    These accessors have different optimization properties --
+    StandardConstAccessor is usually faster for compound pixel types,
+    while StandardConstValueAccessor is faster for the built-in types.
+
+    When an iterator passes a floating point number to an accessor
+    with integral value_type, the value is rounded and clipped as appropriate.
+
+    <b>\#include</b> \<vigra/accessor.hxx\><br>
+    Namespace: vigra
+*/
+template <class VALUETYPE>
+class StandardConstValueAccessor
+{
+  public:
+    typedef VALUETYPE value_type;
+
+        /** Read the current data item. The type <TT>ITERATOR::reference</TT>
+            is automatically converted to <TT>VALUETYPE</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class ITERATOR>
+    VALUETYPE operator()(ITERATOR const & i) const
+        { return detail::RequiresExplicitCast<VALUETYPE>::cast(*i); }
+
+        /** Read the data item at an offset (can be 1D or 2D or higher order difference).
+            The type <TT>ITERATOR::index_reference</TT>
+            is automatically converted to <TT>VALUETYPE</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    VALUETYPE operator()(ITERATOR const & i, DIFFERENCE const & diff) const
+    {
+        return detail::RequiresExplicitCast<VALUETYPE>::cast(i[diff]);
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                 VectorComponentAccessor              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Accessor for one component of a vector.
+
+    This accessor allows to select a single component (a single 'band')
+    of a vector valued pixel type. The pixel type must support
+    <TT>operator[]</TT>. The index of the component to be selected
+    is passed in the constructor. The accessor returns its items
+    <em>by reference</em>. If you want to pass/return items by value,
+    use VectorComponentValueAccessor. If a floating point number
+    is assigned by means of an accessor with integral value_type, the
+    value is rounded and clipped as appropriate.
+
+    <b>Usage:</b>
+
+    \code
+    vigra::BRGBImage image(w,h);
+
+    // init red channel with 255
+    initImage(destImageRange(image,
+                             VectorComponentAccessor<vigra::BRGBImage::value_type>(0)),
+              255);
+    \endcode
+
+    <b>\#include</b> \<vigra/accessor.hxx\><br>
+    Namespace: vigra
+
+*/
+template <class VECTORTYPE>
+class VectorComponentAccessor
+{
+    int index_;
+  public:
+        /** the value_type
+        */
+    typedef typename VECTORTYPE::value_type value_type;
+
+        /** determine the component to be accessed
+        */
+    VectorComponentAccessor(int index)
+    : index_(index)
+    {}
+
+        /** read the current data item
+        */
+    template <class ITERATOR>
+    value_type const & operator()(ITERATOR const & i) const
+        { return (*i)[index_]; }
+
+        /** read the data item at an offset (can be 1D or 2D or higher order difference).
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    value_type const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
+    {
+        return i[diff][index_];
+    }
+
+        /** Write the current data item. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR>
+    void set(V const & value, ITERATOR const & i) const
+    {
+        (*i)[index_] = detail::RequiresExplicitCast<value_type>::cast(value);
+    }
+
+        /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
+            The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR, class DIFFERENCE>
+    void set(V const & value, ITERATOR const & i, DIFFERENCE const & diff) const 
+    { 
+        i[diff][index_]= detail::RequiresExplicitCast<value_type>::cast(value); 
+    }
+    
+        /** Reset the index to the given number.
+        */
+    void setIndex(int i)
+    {
+        index_ = i;
+    }
+};
+
+/** \brief Accessor for one component of a vector.
+
+    This accessor allows to select a single component (a single 'band')
+    of a vector valued pixel type. The pixel type must support
+    <TT>operator[]</TT>. The index of the component to be selected
+    is passed in the constructor. The accessor returns its items
+    <em>by value</em>. If you want to pass/return items by reference,
+    use VectorComponentAccessor. If a floating point number
+    is assigned by means of an accessor with integral value_type, the
+    value is rounded and clipped as appropriate.
+
+    <b>Usage:</b>
+
+    \code
+    vigra::BRGBImage image(w,h);
+
+    // init red channel with 255
+    initImage(destImageRange(image,
+                             VectorComponentValueAccessor<vigra::BRGBImage::value_type>(0)),
+              255);
+    \endcode
+
+    <b>\#include</b> \<vigra/accessor.hxx\><br>
+    Namespace: vigra
+
+*/
+template <class VECTORTYPE>
+class VectorComponentValueAccessor
+{
+    int index_;
+  public:
+        /** the value_type
+        */
+    typedef typename VECTORTYPE::value_type value_type;
+
+        /** determine the component to be accessed
+        */
+    VectorComponentValueAccessor(int index)
+    : index_(index)
+    {}
+
+        /** Read the current data item.
+            The type <TT>ITERATOR::index_reference::value_type</TT>
+            is automatically converted to <TT>value_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const
+        { return detail::RequiresExplicitCast<value_type>::cast((*i)[index_]); }
+
+        /** Read the data item at an offset (can be 1D or 2D or higher order difference).
+            The type <TT>ITERATOR::index_reference::value_type</TT>
+            is automatically converted to <TT>value_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE const & diff) const
+    { 
+        return detail::RequiresExplicitCast<value_type>::cast(i[diff][index_]); 
+    }
+    
+        /** Write the current data item. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR>
+    void set(V value, ITERATOR const & i) const 
+    { 
+        (*i)[index_] = detail::RequiresExplicitCast<value_type>::cast(value); 
+    }
+    
+        /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
+            The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR, class DIFFERENCE>
+    void set(V value, ITERATOR const & i, DIFFERENCE const & diff) const 
+    { 
+        i[diff][index_]= detail::RequiresExplicitCast<value_type>::cast(value); 
+    }
+    
+        /** Reset the index to the given number.
+        */
+    void setIndex(int i)
+    {
+        index_ = i;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                   VectorElementAccessor              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Accessor for one component of a vector.
+
+    This works like VectorComponentAccessor, only the template parameters differ: 
+    Here, we need a vector accessor type , whereas VectorComponentAccessor requires a vector type.
+
+    <b>Usage:</b>
+    
+    \code
+    vigra::BRGBImage image(w,h);
+    
+    // init red channel with 255
+    initImage(destImageRange(image, 
+                             VectorElementAccessor<vigra::BRGBImage::Accessor>(0)),
+              255);
+    \endcode
+    
+    <b>\#include</b> \<vigra/accessor.hxx\><br>
+    Namespace: vigra
+    
+*/
+template <class ACCESSOR>
+class VectorElementAccessor
+{
+    int index_;
+    ACCESSOR a_;
+  public:
+        /** the value_type
+        */
+    typedef typename ACCESSOR::component_type value_type;
+    
+        /** determine the component to be accessed
+        */
+    VectorElementAccessor(int index, ACCESSOR a = ACCESSOR())
+    : index_(index),
+      a_(a)
+    {}
+    
+        /** read the current data item
+        */
+    template <class ITERATOR>
+    value_type const & operator()(ITERATOR const & i) const 
+        { return a_.getComponent(i, index_); }
+    
+        /** read the data item at an offset (can be 1D or 2D or higher order difference).
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    value_type const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
+    { 
+        return a_.getComponent(i, diff, index_); 
+    }
+    
+        /** Write the current data item. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR>
+    void set(V const & value, ITERATOR const & i) const 
+    { 
+        a_.setComponent(detail::RequiresExplicitCast<value_type>::cast(value), i, index_); 
+    }
+
+        /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
+            The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR, class DIFFERENCE>
+    void set(V const & value, ITERATOR const & i, DIFFERENCE const & diff) const 
+    { 
+       a_.setComponent(detail::RequiresExplicitCast<value_type>::cast(value), i, diff, index_); 
+    }
+    
+        /** Reset the index to the given number.
+        */
+    void setIndex(int i)
+    {
+        index_ = i;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                    SequenceAccessor                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Accessor for items that are STL compatible sequences.
+
+    It encapsulates access to the sequences' begin() and end()
+    functions.
+
+    <b>Usage:</b>
+
+    <b>\#include</b> \<vigra/accessor.hxx\><br>
+    Namespace: vigra
+
+    \code
+    typedef std::list<std::list<int> > ListOfLists;
+
+    ListOfLists ll;
+    ...
+
+    typedef vigra::SequenceAccessor<ListOfLists::value_type> ListOfListsAccessor;
+    ListOfListsAccessor a;
+    for(ListOfLists::iterator li = ll.begin(); li != ll.end(); ++li)
+    {
+        for(ListOfListsAccessor::iterator i = a.begin(li); i != a.end(li); ++i)
+        {
+            *i = 10;
+        }
+    }
+    \endcode
+*/
+template <class SEQUENCE>
+class SequenceAccessor
+: public StandardAccessor<SEQUENCE>
+{
+  public:
+        /** the sequence's value_type
+        */
+    typedef typename SEQUENCE::value_type component_type;
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+    typedef typename
+            If<typename TypeTraits<SEQUENCE>::isConst,
+               typename SEQUENCE::const_iterator,
+               typename SEQUENCE::iterator>::type 
+            iterator;
+#else
+        /** the sequence's iterator type
+        */
+    typedef typename SEQUENCE::iterator iterator;
+#endif
+
+        /** get begin iterator for sequence at given iterator position
+        */
+    template <class ITERATOR>
+    iterator begin(ITERATOR const & i) const
+    {
+        return (*i).begin();
+    }
+
+        /** get end iterator for sequence at given iterator position
+        */
+    template <class ITERATOR>
+    iterator end(ITERATOR const & i)  const
+    {
+         return (*i).end();
+    }
+
+        /** get begin iterator for sequence at an offset
+            of given iterator position
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    iterator begin(ITERATOR const & i, DIFFERENCE const & diff)  const
+    {
+        return i[diff].begin();
+    }
+
+        /** get end iterator for sequence at a 2D difference vector
+            of given iterator position
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    iterator end(ITERATOR const & i, DIFFERENCE const & diff)  const
+    {
+        return i[diff].end();
+    }
+
+        /** get size of sequence at given iterator position
+        */
+    template <class ITERATOR>
+    unsigned int size(ITERATOR const & i) const { return (*i).size(); }
+
+        /** get size of sequence at 2D difference vector of given iterator position
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    unsigned int size(ITERATOR const & i, DIFFERENCE const & diff) const
+    { return i[diff].size(); }
+};
+
+/********************************************************/
+/*                                                      */
+/*                     VectorAccessor                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Accessor for items that are STL compatible vectors.
+
+    It encapsulates access to a vector's access functionality.
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/accessor.hxx\><br>
+    Namespace: vigra
+
+    The accessor has two modes of operation:
+
+    <ol>
+    <li> Access the vector's iterator via the <TT>begin()</TT> and <TT>end()</TT>
+    functions:
+
+    \code
+    typedef std::list<std::vector<int> > ListOfVectors;
+
+    ListOfVectors ll;
+    ...
+
+    typedef vigra::SequenceAccessor<ListOfVectors::value_type> ListOfVectorsAccessor;
+    ListOfVectorsAccessor a;
+    for(ListOfVectors::iterator li = ll.begin(); li != ll.end(); ++li)
+    {
+        for(ListOfVectorsAccessor::iterator i = a.begin(li); i != a.end(li); ++i)
+        {
+            *i = 10;
+        }
+    }
+    \endcode
+    <li> Access the vector's components via an index (internally calls
+    the vector's <TT>operator[]</TT> ):
+    \code
+    typedef std::list<std::vector<int> > ListOfVectors;
+
+    ListOfVectors ll;
+    ...
+
+    typedef vigra::SequenceAccessor<ListOfVectors::value_type> ListOfVectorsAccessor;
+    ListOfVectorsAccessor a;
+    for(ListOfVectors::iterator li = ll.begin(); li != ll.end(); ++li)
+    {
+        for(int i = 0; i != a.size(li); ++i)
+        {
+            a.setComponent(10, li, i);
+        }
+    }
+    \endcode
+    </ol>
+
+    <b> Required Interface:</b>
+
+    \code
+    VECTOR v;
+    VECTOR::iterator i;
+    value_type d;
+    int index;
+
+    d = v[index];
+    v[index] = d;
+    i = v.begin();
+    i = v.end();
+    v.size();
+    \endcode
+*/
+template <class VECTOR>
+class VectorAccessor
+: public SequenceAccessor<VECTOR>
+{
+  public:
+        /** the vector's value_type
+        */
+    typedef typename VECTOR::value_type component_type;
+
+        /** the vector element accessor associated with this vector accessor
+            (see \ref VectorElementAccessor)
+        */
+    typedef VectorElementAccessor<VectorAccessor<VECTOR> > ElementAccessor;
+
+        /** Read the component data at given vector index
+            at given iterator position
+        */
+    template <class ITERATOR>
+    component_type const & getComponent(ITERATOR const & i, int idx) const
+    {
+        return (*i)[idx];
+    }
+
+        /** Set the component data at given vector index
+            at given iterator position. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR>
+    void setComponent(V const & value, ITERATOR const & i, int idx) const
+    {
+        (*i)[idx] = detail::RequiresExplicitCast<component_type>::cast(value);
+    }
+
+        /** Read the component data at given vector index
+            at an offset of given iterator position
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    component_type const & getComponent(ITERATOR const & i, DIFFERENCE const & diff, int idx) const
+    {
+        return i[diff][idx];
+    }
+
+    /** Set the component data at given vector index
+        at an offset of given iterator position. The type <TT>V</TT> of the passed
+        in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+    */
+    template <class V, class ITERATOR, class DIFFERENCE>
+    void
+    setComponent(V const & value, ITERATOR const & i, DIFFERENCE const & diff, int idx) const
+    {
+        i[diff][idx] = detail::RequiresExplicitCast<component_type>::cast(value);
+    }
+};
+
+
+/********************************************************/
+/*                                                      */
+/*                 MultiImageAccessor2                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Access two images simultaneously.
+
+    This accessor is used when two images need to be treated as one
+    because an algorithm accepts only one image. For example,
+    \ref seededRegionGrowing() uses only one image two calculate
+    the cost for aggregating each pixel into a region. Sometimes, we
+    need more information to calculate this cost, for example gray value
+    and local gradient magnitude. These values can be stored in two images,
+    which appear as only one when we pass a <TT>MultiImageAccessor2</TT> to
+    the algorithms. Of course, the cost functor must accept a <TT>pair</TT>
+    of values for this to work. Instead of an actual image iterator, we
+    pass a <a href="CoordinateIterator.html">CoordinateIterator</a> which
+    selects the right pixels form both images.
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/accessor.hxx\><br>
+    Namespace: vigra
+
+    \code
+    using namespace vigra;
+
+    FImage gray_values(w,h), gradient_magnitude(w,h);
+    IImage seeds(w,h), labels(w,h);
+
+    seededRegionGrowing(
+        srcIterRange(CoordinateIterator(), CoordinateIterator(w,h),
+           MultiImageAccessor2<FImage::iterator, FImage::Accessor,
+                               FImage::iterator, FImage::Accessor>
+                              (gray_values.upperLeft(), gray_values.accessor(),
+                               gradient_magnitude.upperLeft(), gradient_magnitude.accessor())),
+        srcImage(seeds),
+        destImage(labels),
+        SomeCostFunctor());
+    \endcode
+*/
+
+template <class Iter1, class Acc1, class Iter2, class Acc2>
+class MultiImageAccessor2
+{
+  public:
+        /** The accessors value_type: construct a pair that contains
+            the corresponding image values.
+        */
+    typedef pair<typename Acc1::value_type, typename Acc2::value_type>
+            value_type;
+
+        /** Construct from two image iterators and associated accessors.
+        */
+    MultiImageAccessor2(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
+    : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
+    {}
+
+        /** read the current data item
+        */
+    template <class DIFFERENCE>
+    value_type operator()(DIFFERENCE const & d) const
+    {
+        return std::make_pair(a1_(i1_, d), a2_(i2_, d));
+    }
+
+        /** read the data item at an offset
+        */
+    template <class DIFFERENCE1, class DIFFERENCE2>
+    value_type operator()(DIFFERENCE1 d1, DIFFERENCE2 const & d2) const
+    {
+        d1 += d2;
+        return std::make_pair(a1_(i1_, d1), a2_(i2_, d1));
+    }
+
+  private:
+    Iter1 i1_;
+    Acc1 a1_;
+    Iter2 i2_;
+    Acc2 a2_;
+};
+
+//@}
+
+template <class T>
+struct AccessorTraits
+{
+    typedef StandardAccessor<T>        default_accessor;
+    typedef StandardConstAccessor<T>   default_const_accessor;
+};
+
+#define VIGRA_DEFINE_ACCESSOR_TRAITS(VALUE, ACCESSOR, CONST_ACCESSOR) \
+    template <> \
+    struct AccessorTraits<VALUE > \
+    { \
+        typedef ACCESSOR<VALUE >         default_accessor; \
+        typedef CONST_ACCESSOR<VALUE >   default_const_accessor; \
+    };
+
+VIGRA_DEFINE_ACCESSOR_TRAITS(signed char, StandardValueAccessor, StandardConstValueAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned char, StandardValueAccessor, StandardConstValueAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(short, StandardValueAccessor, StandardConstValueAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned short, StandardValueAccessor, StandardConstValueAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(int, StandardValueAccessor, StandardConstValueAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned int, StandardValueAccessor, StandardConstValueAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(long, StandardValueAccessor, StandardConstValueAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned long, StandardValueAccessor, StandardConstValueAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(float, StandardValueAccessor, StandardConstValueAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(double, StandardValueAccessor, StandardConstValueAccessor)
+
+template <class T, unsigned int RED_IDX, unsigned int GREEN_IDX, unsigned int BLUE_IDX> class RGBValue;
+template <class T> class RGBAccessor;
+template <class T, int SIZE> class TinyVector;
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class T, unsigned int RED_IDX, unsigned int GREEN_IDX, unsigned int BLUE_IDX>
+struct AccessorTraits<RGBValue<T, RED_IDX, GREEN_IDX, BLUE_IDX> >
+{
+    typedef RGBAccessor<RGBValue<T, RED_IDX, GREEN_IDX, BLUE_IDX> >   default_accessor;
+    typedef RGBAccessor<RGBValue<T, RED_IDX, GREEN_IDX, BLUE_IDX> >   default_const_accessor;
+};
+
+template <class T, int SIZE>
+struct AccessorTraits<TinyVector<T, SIZE> >
+{
+    typedef VectorAccessor<TinyVector<T, SIZE> >   default_accessor;
+    typedef VectorAccessor<TinyVector<T, SIZE> >   default_const_accessor;
+};
+
+#else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned char>, RGBAccessor, RGBAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<signed char>, RGBAccessor, RGBAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<short>, RGBAccessor, RGBAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned short>, RGBAccessor, RGBAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<int>, RGBAccessor, RGBAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned int>, RGBAccessor, RGBAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<long>, RGBAccessor, RGBAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned long>, RGBAccessor, RGBAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<float>, RGBAccessor, RGBAccessor)
+VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<double>, RGBAccessor, RGBAccessor)
+
+#define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<short, 2>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<short, 3>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<short, 4>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<int, 2>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<int, 3>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<int, 4>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<float, 2>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<float, 3>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<float, 4>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<double, 2>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<double, 3>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<double, 4>
+VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
+#undef VIGRA_PIXELTYPE
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+#undef VIGRA_DEFINE_ACCESSOR_TRAITS
+
+} // namespace vigra
+
+#endif // VIGRA_ACCESSOR_HXX
diff --git a/include/vigra/accumulator-grammar.hxx b/include/vigra/accumulator-grammar.hxx
new file mode 100644
index 0000000..b66e334
--- /dev/null
+++ b/include/vigra/accumulator-grammar.hxx
@@ -0,0 +1,749 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2011-2012 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_ACCUMULATOR_GRAMMAR_HXX
+#define VIGRA_ACCUMULATOR_GRAMMAR_HXX
+
+#ifdef _MSC_VER
+#pragma warning (disable: 4503)
+#endif
+
+#include "config.hxx"
+#include "metaprogramming.hxx"
+
+namespace vigra {
+
+namespace acc {
+
+/**************************************************************************/
+/*                                                                        */
+/*                      irreducible basic accumulators                    */
+/*                                                                        */
+/**************************************************************************/
+    
+   
+class CoordinateSystem;                        // returns an identity matrix of appropriate size
+
+template <unsigned N> class PowerSum;          // sum over powers of values
+template <unsigned N> class AbsPowerSum;       // sum over powers of absolute values
+
+class Skewness;                                // skewness
+class UnbiasedSkewness;                        // unbiased estimator for skewness
+class Kurtosis;                                // excess kurtosis
+class UnbiasedKurtosis;                        // unbiased estimator for excess kurtosis
+class FlatScatterMatrix;                       // flattened upper-triangular part of the scatter matrix
+class ScatterMatrixEigensystem;                // eigenvalues and eigenvectors of the scatter matrix
+
+    // in all histogram classes: set bin count at runtime if BinCount == 0
+template <int BinCount> class IntegerHistogram;      // use data values directly as bin indices
+template <int BinCount> class UserRangeHistogram;    // set min/max explicitly at runtime
+template <int BinCount> class AutoRangeHistogram;    // get min/max from accumulators
+template <int BinCount> class GlobalRangeHistogram;  // like AutoRangeHistogram, but use global min/max rather than region min/max
+
+class Minimum;                                 // minimum
+class Maximum;                                 // maximum
+template <class Hist> class StandardQuantiles; // compute (min, 10%, 25%, 50%, 75%, 90%, max) quantiles from 
+                                               // min/max accumulators and given histogram
+
+class ArgMinWeight;                            // store the value (or coordinate) where weight was minimal
+class ArgMaxWeight;                            // store the value (or coordinate) where weight was maximal
+
+    // FIXME: not yet implemented
+template <unsigned NDim> class MultiHistogram; // multi-dimensional histogram
+                                               // (always specify number of bins at runtime)
+
+class Centralize;                              // cache centralized values
+class PrincipalProjection;                     // cache values after principal projection
+    // FIXME: not yet implemented
+class Whiten;                                  // cache values after whitening
+class RangeMapping;                            // map value from [min, max] to another range and cache result (e.g. for histogram creation)
+
+template <int INDEX>  class DataArg;           // specifiy the index of the data member in a CoupledHandle
+template <int INDEX>  class WeightArg;         // specifiy the index of the weight member in a CoupledHandle
+template <int INDEX>  class LabelArg;          // specifiy the index of the label member in a CoupledHandle
+template <int INDEX>  class CoordArg;          // specifiy the index of the coord member in a CoupledHandle
+
+/* 
+Quantiles other than minimum and maximum require more thought:
+--------------------------------------------------------------
+ * Exact quantiles can be found in time O(n) using recursive partitioning (quickselect),
+   but this requires the data (or an auxiliary index array) to be re-arranged.
+ * Exact quantiles can be found in time O(k*n) using recursive histogram refinement,
+   were k = O(log(n)/log(BinCount)) is the expected number of required passes over the 
+   data, provided that bins are filled approximately evenly. If data can be re-arranged,
+   such that we remember the items corresponding to each bin, running time reduces to O(n) 
+   (this is Tibshirani's 'binmedian' algorithm). For the median, Tibshirani proves that
+   the initial histogram only needs to cover the interval [Mean-StdDev, Mean+StdDev].
+ * Both strategies can be combined: perform k passes to reduce bin size to about 
+   n/(BinCount)^k, and then perform quickselect on an auxiliary array of size 
+   O(n/(BinCount)^k) which has been filled during the final pass.
+ * Good approximate results can be obtained by early stopping of histogram refinement
+   (Tibshirani's 'binapprox' algorithm). A 2-pass algorithm for the median achieves
+   accuracy of StdDev/BinCount: Mean and StdDev are computed during pass 1, 
+   and a histogram over [Mean-StdDev, Mean+StdDev] during pass 2.
+ * A 1-pass approximation method is described in Chen et al. However, it assumes that
+   samples arrive in random order which is usually not true in image data.
+*/
+
+/**************************************************************************/
+/*                                                                        */
+/*                  modifiers for composite accumulators                  */
+/*                                                                        */
+/**************************************************************************/
+
+   // data normalization w.r.t. number of samples
+template <class A>    class DivideByCount;       //  A / count
+template <class A>    class RootDivideByCount;   //  sqrt(A / count)
+template <class A>    class DivideUnbiased;      //  A / (count - 1)  
+template <class A>    class RootDivideUnbiased;  //  sqrt(A / (count - 1))
+
+    // data access
+template <class A> class Coord;           // use pixel coordinate instead of pixel value (index 0 of CoupledHandle)
+template <class A> class Weighted;        // use (value, weight) pairs (index 1 and 2 of CoupledHandle)
+template <class A> class CoordWeighted;   // use (coord, weight) pairs(index 0 and end of CoupledHandle)
+template <class A> class DataFromHandle;  // extract data from index 1 of a CoupledHandle
+
+    // data preparation
+template <class A> class Central;    // subtract mean
+template <class A> class Principal;  // subtract mean and rotate to principal coordinates
+
+    // FIXME: not implemented yet
+template <class A> class Whitened;   // transform to principal coordinates and scale to unit variance
+
+template <class A> class Global;     // compute statistic A globally rather than per region
+
+/**************************************************************************/
+/*                                                                        */
+/*                   alias names for important features                   */
+/*                                                                        */
+/**************************************************************************/
+
+/** \brief Alias. Count. */
+typedef PowerSum<0>                                 Count;
+/** \brief Alias. Sum. */
+typedef PowerSum<1>                                 Sum;
+/** \brief Alias. Sum of squares. */
+typedef PowerSum<2>                                 SumOfSquares;
+
+/** \brief Alias. Mean. */
+typedef DivideByCount<Sum>                          Mean;
+/** \brief Alias. Root mean square. */
+typedef RootDivideByCount<SumOfSquares>             RootMeanSquares;
+
+// desired pseudocode (unfortunately not legal in C++)
+//
+//     template <unsigned N> 
+//     typedef DivideByCount<PowerSum<N> >          Moment;
+//
+// actual definition (desired behavior is realised by rules below)
+//
+/** \brief Alias. Moment<N>. */
+template <unsigned N> class                         Moment;  
+/** \brief Alias. CentralMoment<N>. */
+template <unsigned N> class                         CentralMoment;  
+
+/** \brief Alias. Sum of squared differences. */
+typedef Central<PowerSum<2> >                       SumOfSquaredDifferences;
+/** \brief Alias. Sum of squared differences. */
+typedef SumOfSquaredDifferences                     SSD;
+
+/** \brief Alias. Variance. */
+typedef DivideByCount<Central<PowerSum<2> > >       Variance;
+/** \brief Alias. Standard deviation. */
+typedef RootDivideByCount<Central<PowerSum<2> > >   StdDev;
+/** \brief Alias. Unbiased variance. */
+typedef DivideUnbiased<Central<PowerSum<2> > >      UnbiasedVariance;
+/** \brief Alias. Unbiased standard deviation. */
+typedef RootDivideUnbiased<Central<PowerSum<2> > >  UnbiasedStdDev;
+
+/** \brief Alias. Covariance. */
+typedef DivideByCount<FlatScatterMatrix>            Covariance;
+/** \brief Alias. Unbiased covariance. */
+typedef DivideUnbiased<FlatScatterMatrix>           UnbiasedCovariance;
+/** \brief Alias. Covariance eigensystem. */
+typedef DivideByCount<ScatterMatrixEigensystem>     CovarianceEigensystem;
+
+/** \brief Alias. Absolute sum. */
+typedef AbsPowerSum<1>                              AbsSum;
+/** \brief Alias. Sum of absolute differences. */
+typedef Central<AbsSum>                             SumOfAbsDifferences;
+/** \brief Alias. Mean absolute deviation. */
+typedef DivideByCount<SumOfAbsDifferences>          MeanAbsoluteDeviation;
+
+/** \brief Alias. Region center. */
+typedef Coord<Mean>                                 RegionCenter;
+/** \brief Alias. Region radii. */
+typedef Coord<Principal<StdDev> >                   RegionRadii;
+/** \brief Alias. Region axes. */
+typedef Coord<Principal<CoordinateSystem> >         RegionAxes;
+
+/** \brief Alias. Center of mass. */
+typedef Weighted<RegionCenter>                      CenterOfMass;
+/** \brief Alias. Moments of inertia. */
+typedef Weighted<Coord<Principal<Variance> > >      MomentsOfInertia;
+/** \brief Alias. Axes of inertia. */
+typedef Weighted<RegionAxes>                        AxesOfInertia;
+
+/**************************************************************************/
+/*                                                                        */
+/*                        Tag standardization rules                       */
+/*                                                                        */
+/**************************************************************************/
+
+namespace acc_detail {
+
+template <class A>
+struct ModifierRule
+{
+    typedef A type;
+};
+
+} // namespace acc_detail
+
+template <class A>
+struct Error___Tag_modifiers_of_same_kind_must_not_be_combined;
+
+    // apply rules as long as the Tag type changes ...
+template <class A, class S=typename acc_detail::ModifierRule<A>::type>
+struct StandardizeTag
+{
+    typedef typename StandardizeTag<S>::type type;
+};
+
+    // ... and stop otherwise ...
+template <class A>
+struct StandardizeTag<A, A>
+{
+    typedef A type;
+};
+
+    // ... or fail when the tag spec was non-conforming 
+template <class A, class B>
+struct StandardizeTag<A, Error___Tag_modifiers_of_same_kind_must_not_be_combined<B> >
+    : public Error___Tag_modifiers_of_same_kind_must_not_be_combined<B>
+{};
+
+namespace acc_detail {
+
+    // Assign priorities to modifiers to determine their standard order (by ascending priority).
+    // SubstitutionMask determines which modifiers must be automatically transferred to dependencies.
+enum { MinPriority = 1, 
+       AccumulatorPriority = 32,
+       PrepareDataPriority = 16,
+       NormalizePriority = 8,
+       AccessDataPriority = 4,
+       WeightingPriority = 2,
+       GlobalPriority = 1,
+       MaxPriority = 32,
+       SubstitutionMask = PrepareDataPriority | AccessDataPriority | WeightingPriority | GlobalPriority };
+
+template <class A>
+struct ModifierPriority
+{
+    static const int value = AccumulatorPriority;
+};
+
+#define VIGRA_MODIFIER_PRIORITY(MODIFIER, VALUE) \
+template <class A> \
+struct ModifierPriority<MODIFIER<A> > \
+{ \
+    static const int value = VALUE; \
+};
+
+VIGRA_MODIFIER_PRIORITY(Global, GlobalPriority)
+
+VIGRA_MODIFIER_PRIORITY(Weighted, WeightingPriority)
+
+VIGRA_MODIFIER_PRIORITY(Coord, AccessDataPriority)
+VIGRA_MODIFIER_PRIORITY(DataFromHandle, AccessDataPriority)
+
+VIGRA_MODIFIER_PRIORITY(DivideByCount, NormalizePriority)
+VIGRA_MODIFIER_PRIORITY(RootDivideByCount, NormalizePriority)
+VIGRA_MODIFIER_PRIORITY(DivideUnbiased, NormalizePriority)
+VIGRA_MODIFIER_PRIORITY(RootDivideUnbiased, NormalizePriority)
+
+VIGRA_MODIFIER_PRIORITY(Central, PrepareDataPriority)
+VIGRA_MODIFIER_PRIORITY(Principal, PrepareDataPriority)
+VIGRA_MODIFIER_PRIORITY(Whitened, PrepareDataPriority)
+
+    // explicitly set priority for base accumulators that look like modifiers
+VIGRA_MODIFIER_PRIORITY(StandardQuantiles, AccumulatorPriority)
+
+#undef VIGRA_MODIFIER_PRIORITY
+
+    // check if the tag A contains a modifier with TARGET_PRIORITY
+template <class A, int TARGET_PRIORITY, int PRIORITY=ModifierPriority<A>::value>
+struct HasModifierPriority
+{
+    typedef VigraFalseType type;
+    static const bool value = false;
+};
+
+template <class A, int TARGET_PRIORITY>
+struct HasModifierPriority<A, TARGET_PRIORITY, TARGET_PRIORITY>
+{
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+template <class A, template <class> class B, int TARGET_PRIORITY, int PRIORITY>
+struct HasModifierPriority<B<A>, TARGET_PRIORITY, PRIORITY>
+: public HasModifierPriority<A, TARGET_PRIORITY>
+{};
+
+template <class A, template <class> class B, int TARGET_PRIORITY>
+struct HasModifierPriority<B<A>, TARGET_PRIORITY, TARGET_PRIORITY>
+{
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+    // three-way compare 
+template <class A, class B>
+struct ModifierCompare
+{
+    static const int p1 = ModifierPriority<A>::value;
+    static const int p2 = ModifierPriority<B>::value;
+    static const int value = p1 < p2 
+                                ? -1
+                                : p2 < p1
+                                     ? 1
+                                     : 0;
+};
+
+template <class A>
+struct ModifierCompareToInner;
+
+template <class A, template <class> class B>
+struct ModifierCompareToInner<B<A> >
+: public ModifierCompare<B<A>, A>
+{};
+
+    // sort modifiers by ascending priority
+template <class A, int compare=ModifierCompareToInner<A>::value>
+struct ModifierOrder;
+
+    // do nothing if the order is correct (compare == -1)
+template <class A>
+struct ModifierOrder<A, -1>
+{
+    typedef A type;
+};
+
+    // fail if there are two modifiers with the same priority (compare == 0)
+template <class A, template <class> class B, template <class> class C>
+struct ModifierOrder<C<B<A> >, 0>
+{
+    typedef Error___Tag_modifiers_of_same_kind_must_not_be_combined<C<B<A> > > type;
+};
+
+    // sort if the order is reversed (compare == 1)
+template <class A, template <class> class B, template <class> class C>
+struct ModifierOrder<C<B<A> >, 1>
+{
+    typedef B<C<A> > type;
+};
+
+#define VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(OUTER, INNER, RESULT) \
+template <class A> \
+struct ModifierOrder<OUTER<INNER<A > >, 0> \
+{ \
+    typedef RESULT<A > type; \
+};
+
+    // drop duplicates
+VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Central, Central, Central)
+VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Principal, Principal, Principal)
+VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Whitened, Whitened)
+
+    // the strongest data preparation modifier takes precendence
+VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Principal, Central, Principal)
+VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Central, Whitened)
+VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Principal, Whitened)
+
+    // Coord takes precendence over DataFromHandle
+VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(DataFromHandle, Coord, Coord)
+
+#undef VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS
+
+    // drop duplicates
+template <class A, template <class> class B>
+struct ModifierRule<B<B<A> > >
+{
+    typedef B<A> type;
+};
+
+template <class A, int PRIORITY=ModifierPriority<A>::value>
+struct RecurseModifier;
+
+template <class A, template <class> class B, int PRIORITY>
+struct RecurseModifier<B<A>, PRIORITY>
+{
+    typedef typename ModifierOrder<B<typename StandardizeTag<A>::type> >::type type;
+};
+
+template <class A, template <class> class B>
+struct RecurseModifier<B<A>, AccumulatorPriority>
+{
+    typedef B<A> type;
+};
+
+    // recurse down the modifier chain, but only of B is actually a modifier,
+    // and not a templated base accumulator (i.e. do not recurse if B's
+    // priority is 'AccumulatorPriority')
+template <class A, template <class> class B>
+struct ModifierRule<B<A> >
+: public RecurseModifier<B<A> >
+{};
+
+    // reduce the SOURCE modifier to the TARGET modifier,
+    // using the given TEMPLATE arguments
+    // (this is a work-around for the lack of templated typedef in C++)
+#define VIGRA_REDUCE_MODFIER(TEMPLATE, SOURCE, TARGET) \
+template <TEMPLATE > \
+struct ModifierRule<SOURCE > \
+{ \
+    typedef TARGET type; \
+};
+
+#define VIGRA_VOID
+
+    // centralizing doesn't change the CoordinateSystem
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<CoordinateSystem>, CoordinateSystem)
+    // whitened CoordinateSystem are the same as principal CoordinateSystem
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<CoordinateSystem>, Principal<CoordinateSystem>)
+
+    // counting modified data is the same as counting data, except for weighted data and global counting
+VIGRA_REDUCE_MODFIER(template <class> class A, A<Count>, Count)
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Weighted<Count>, Weighted<Count>)
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, CoordWeighted<Count>, Weighted<Count>)
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Global<Count>, Global<Count>)
+
+    // reduce aliases that typedef can't handle
+VIGRA_REDUCE_MODFIER(unsigned N, Moment<N>, DivideByCount<PowerSum<N> >)
+VIGRA_REDUCE_MODFIER(unsigned N, CentralMoment<N>, DivideByCount<Central<PowerSum<N> > >)
+VIGRA_REDUCE_MODFIER(class A, CoordWeighted<A>, Weighted<Coord<A> >)
+
+    // reduce statistics that are inherently centered
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Centralize>, Centralize)
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Skewness>, Skewness)
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Kurtosis>, Kurtosis)
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<FlatScatterMatrix>, FlatScatterMatrix)
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
+
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Principal<Centralize>, PrincipalProjection)
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<Centralize>, Whiten)
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Principal<PrincipalProjection>, PrincipalProjection)
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<PrincipalProjection>, Whiten)
+VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<Whiten>, Whiten)
+
+    // reduce even absolute powers to plain powers
+template <unsigned N>
+struct ModifierRule<AbsPowerSum<N> >
+{
+    typedef typename IfBool<(N % 2 == 0), PowerSum<N>, AbsPowerSum<N> >::type type;
+};
+
+#undef VIGRA_VOID
+#undef VIGRA_REDUCE_MODFIER
+
+template <class A>
+struct ShouldBeWeighted
+{
+    typedef VigraFalseType type;
+    static const bool value = false;
+};
+
+template <>
+struct ShouldBeWeighted<ArgMinWeight>
+{
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+template <>
+struct ShouldBeWeighted<ArgMaxWeight>
+{
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+template <class A, template <class> class B>
+struct ShouldBeWeighted<B<A> >
+: public ShouldBeWeighted<A>
+{};
+
+} // namespace acc_detail
+
+template <class A>
+struct IsCoordinateFeature
+{
+    typedef VigraFalseType type;
+    static const bool value = false;
+};
+
+template <class A, template <class> class B>
+struct IsCoordinateFeature<B<A> >
+{
+    typedef typename IsCoordinateFeature<A>::type type;
+    static const bool value = IsCoordinateFeature<A>::value;
+};
+
+template <class A>
+struct IsCoordinateFeature<Coord<A> >
+{
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+template <class A>
+struct IsPrincipalFeature
+{
+    typedef VigraFalseType type;
+    static const bool value = false;
+};
+
+template <class A, template <class> class B>
+struct IsPrincipalFeature<B<A> >
+{
+    typedef typename IsPrincipalFeature<A>::type type;
+    static const bool value = IsPrincipalFeature<A>::value;
+};
+
+template <class A>
+struct IsPrincipalFeature<Principal<A> >
+{
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+template <class A>
+struct IsPrincipalFeature<Whitened<A> >
+{
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+/**************************************************************************/
+/*                                                                        */
+/*                           Tag transfer rules                           */
+/*                                                                        */
+/**************************************************************************/
+
+namespace acc_detail {
+
+template <class A>
+struct DefaultModifier;
+
+template <class A>
+struct ModifierPriority<DefaultModifier<A> >
+{
+    static const int value = ModifierPriority<A>::value << 1;
+};
+
+template <class A, int TargetPriority, int Priority=ModifierPriority<A>::value>
+struct InsertDefaultModifier
+{
+    typedef DefaultModifier<typename InsertDefaultModifier<A, (TargetPriority << 1)>::type> type;
+};
+
+template <class A, int TargetPriority>
+struct InsertDefaultModifier<A, TargetPriority, TargetPriority>
+{
+    typedef A type;
+};
+
+template <class A, int TargetPriority, int Priority=ModifierPriority<A>::value>
+struct TagLongForm;
+
+template <class A, int TargetPriority>
+struct TagLongForm<A, TargetPriority, MaxPriority>
+{
+    typedef typename InsertDefaultModifier<A, TargetPriority>::type type;
+};
+
+template <class A, template <class> class B, int TargetPriority>
+struct TagLongForm<B<A>, TargetPriority, MaxPriority>
+{
+    typedef typename InsertDefaultModifier<B<A>, TargetPriority>::type type;
+};
+
+template <class A, template <class> class B, int TargetPriority, int Priority>
+struct TagLongForm<B<A>, TargetPriority, Priority>
+{
+    typedef typename TagLongForm<A, (Priority << 1)>::type Inner;
+    typedef typename InsertDefaultModifier<B<Inner>, TargetPriority>::type type;
+};
+
+template <class A, template <class> class B, int TargetPriority>
+struct TagLongForm<B<A>, TargetPriority, TargetPriority>
+{
+    typedef typename TagLongForm<A, (TargetPriority << 1)>::type Inner;
+    typedef B<Inner> type;
+};
+
+template <class A>
+struct LongModifierRule
+{
+    typedef A type;
+};
+
+    // apply rules as long as the Tag type changes ...
+template <class A, class S=typename LongModifierRule<A>::type>
+struct StandardizeTagLongForm
+{
+    typedef typename StandardizeTagLongForm<S>::type type;
+};
+
+    // ... and stop otherwise ...
+template <class A>
+struct StandardizeTagLongForm<A, A>
+{
+    typedef A type;
+};
+
+template <class A, template <class> class B>
+struct LongModifierRule<B<A> >
+{
+    typedef B<typename LongModifierRule<A>::type> type;
+};
+
+template <class A>
+struct LongModifierRule<DefaultModifier<A> >
+{
+    typedef A type;
+};
+
+#define VIGRA_DROP_DATA_PREPARATION_MODIFIERS(SOURCE, TARGET) \
+template <> \
+struct LongModifierRule<SOURCE > \
+{ \
+    typedef TARGET type; \
+};
+
+VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Central<Sum>, Sum)
+VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<Sum>, Sum)
+VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<Sum>, Sum)
+VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<FlatScatterMatrix>, FlatScatterMatrix)
+VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<FlatScatterMatrix>, FlatScatterMatrix)
+VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
+VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
+
+#undef VIGRA_DROP_DATA_PREPARATION_MODIFIERS
+
+template <class A>
+struct CheckSubstitutionFlag
+{
+    static const bool value = (ModifierPriority<A>::value & SubstitutionMask) != 0;
+};
+
+template <class A, class B, 
+          bool substitute=CheckSubstitutionFlag<A>::value>
+struct SubstituteModifiers;
+
+template <class A, class B>
+struct SubstituteModifiers<A, B, false>
+{
+    typedef B type;
+};
+
+template <class A, template <class> class AA, class B, template <class> class BB>
+struct SubstituteModifiers<AA<A>, BB<B>, true>
+{
+    typedef AA<typename SubstituteModifiers<A, B>::type> type;
+};
+
+template <class A, class B, template <class> class BB>
+struct SubstituteModifiers<DefaultModifier<A>, BB<B>, true>
+{
+    typedef BB<typename SubstituteModifiers<A, B>::type> type;
+};
+
+template <class A, template <class> class AA, class B, template <class> class BB>
+struct SubstituteModifiers<AA<A>, BB<B>, false>
+{
+    typedef BB<typename SubstituteModifiers<A, B>::type> type;
+};
+
+} // namespace acc_detail
+
+template <class A, class B>
+struct TransferModifiers
+{
+    typedef typename StandardizeTag<A>::type StdA;
+    typedef typename StandardizeTag<B>::type StdB;
+    typedef typename acc_detail::TagLongForm<StdA, acc_detail::MinPriority>::type AA;
+    typedef typename acc_detail::TagLongForm<StdB, acc_detail::MinPriority>::type BB;
+    typedef typename acc_detail::SubstituteModifiers<AA, BB>::type AB;
+    typedef typename acc_detail::StandardizeTagLongForm<AB>::type StdAB;
+    typedef typename StandardizeTag<StdAB>::type type;
+};
+
+template <class A, class HEAD, class TAIL>
+struct TransferModifiers<A, TypeList<HEAD, TAIL> >
+{
+    typedef TypeList<typename TransferModifiers<A, HEAD>::type,
+                     typename TransferModifiers<A, TAIL>::type> type;
+};
+
+template <class A>
+struct TransferModifiers<A, void>
+{
+    typedef void type;
+};
+
+template <class TargetTag, class A=typename TargetTag::Dependencies>
+struct StandardizeDependencies
+#ifndef DOXYGEN
+: public StandardizeDependencies<TargetTag, typename A::type>
+#endif
+{};
+
+template <class TargetTag, class HEAD, class TAIL>
+struct StandardizeDependencies<TargetTag, TypeList<HEAD, TAIL> >
+{
+    typedef typename StandardizeTag<TargetTag>::type Target;
+    typedef typename TransferModifiers<Target, TypeList<HEAD, TAIL> >::type type;
+};
+
+template <class TargetTag>
+struct StandardizeDependencies<TargetTag, void>
+{
+    typedef void type;
+};
+
+}} // namespace vigra::acc
+
+#endif // VIGRA_ACCUMULATOR_GRAMMAR_HXX
diff --git a/include/vigra/accumulator.hxx b/include/vigra/accumulator.hxx
new file mode 100644
index 0000000..56cbc04
--- /dev/null
+++ b/include/vigra/accumulator.hxx
@@ -0,0 +1,5847 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2011-2012 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_ACCUMULATOR_HXX
+#define VIGRA_ACCUMULATOR_HXX
+
+#ifdef _MSC_VER
+#pragma warning (disable: 4503)
+#endif
+
+#include "accumulator-grammar.hxx"
+#include "config.hxx"
+#include "metaprogramming.hxx"
+#include "bit_array.hxx"
+#include "static_assert.hxx"
+#include "mathutil.hxx"
+#include "utilities.hxx"
+#include "multi_iterator_coupled.hxx"
+#include "matrix.hxx"
+#include "multi_math.hxx"
+#include "eigensystem.hxx"
+#include "histogram.hxx"
+#include <algorithm>
+#include <iostream>
+
+namespace vigra {
+  
+/** \defgroup FeatureAccumulators Feature Accumulators
+
+The namespace <tt>vigra::acc</tt> provides the function \ref vigra::acc::extractFeatures() along with associated statistics functors and accumulator classes. Together, they provide a framework for efficient compution of a wide variety of statistical features, both globally for an entire image, and locally for each region defined by a label array. Many different statistics can be composed out of a small number of fundamental statistics and suitable modifiers. The user simply selects the d [...]
+
+The function \ref acc::extractFeatures() "extractFeatures()" scans the data in as few passes as the selected statstics permit (usually one or two passes are sufficient). Statistics are computed by accurate incremental algorithms, whose internal state is maintained by accumulator objects. The state is updated by passing data to the accumulator one sample at a time. Accumulators are grouped within an accumulator chain. Dependencies between accumulators in the accumulator chain are automati [...]
+
+<b>\#include</b> \<vigra/accumulator.hxx\>
+
+    
+<b>Basic statistics:</b>
+    - PowerSum<N> (computes @f$ \sum_i x_i^N @f$)
+    - AbsPowerSum<N> (computes @f$ \sum_i |x_i|^N @f$)
+    - Skewness, UnbiasedSkewness
+    - Kurtosis, UnbiasedKurtosis
+    - Minimum, Maximum
+    - FlatScatterMatrix (flattened upper-triangular part of scatter matrix)
+    - 4 histogram classes (see \ref histogram "below")
+    - StandardQuantiles (0%, 10%, 25%, 50%, 75%, 90%, 100%)
+    - ArgMinWeight, ArgMaxWeight (store data or coordinate where weight assumes its minimal or maximal value)
+    - CoordinateSystem (identity matrix of appropriate size)
+    
+    <b>Modifiers:</b> (S is the statistc to be modified)
+    - Normalization
+      <table border="0">
+      <tr><td> DivideByCount<S>        </td><td>  S/Count           </td></tr>
+      <tr><td> RootDivideByCount<S>    </td><td>  sqrt( S/Count )     </td></tr>
+      <tr><td> DivideUnbiased<S>       </td><td>  S/(Count-1)       </td></tr>
+      <tr><td> RootDivideUnbiased<S>      </td><td>  sqrt( S/(Count-1) ) </td></tr>
+      </table>    
+    - Data preparation:
+      <table border="0">
+      <tr><td>  Central<S>   </td><td> substract mean before computing S </td></tr>
+      <tr><td>  Principal<S> </td><td> project onto PCA eigenvectors   </td></tr>
+      <tr><td>  Whitened<S>      </td><td> scale to unit variance after PCA   </td></tr>
+      <tr><td>  Coord<S>        </td><td> compute S from pixel coordinates rather than from pixel values    </td></tr>
+      <tr><td>  Weighted<S>     </td><td> compute weighted version of S   </td></tr>
+      <tr><td>  Global<S>       </td><td> compute S globally rather than per region (per region is default if labels are given)   </td></tr>
+      </table>
+      
+    Aliases for many important features are implemented (mainly as <tt>typedef FullName Alias</tt>). The alias names are equivalent to full names. Below are some examples for supported alias names. A full list of all available statistics and alias names can be found in the namespace reference <tt>vigra::acc</tt>. These examples also show how to compose statistics from the fundamental statistics and modifiers:
+    
+    <table border="0">
+    <tr><th> Alias           </th><th>   Full Name                 </th></tr>
+    <tr><td> Count           </td><td>  PowerSum<0>                </td></tr>
+    <tr><td> Sum             </td><td>  PowerSum<1>                </td></tr>
+    <tr><td> SumOfSquares    </td><td>  PowerSum<2>                </td></tr>
+    <tr><td> Mean            </td><td>  DivideByCount<PowerSum<1>> </td></tr>
+    <tr><td> RootMeanSquares   </td><td>  RootDivideByCount<PowerSum<2>> </td></tr>
+    <tr><td> Moment<N>       </td><td>  DivideByCount<PowerSum<N>>  </td></tr>
+    <tr><td> Variance        </td><td>  DivideByCount<Central<PowerSum<2>>>  </td></tr>
+    <tr><td> StdDev          </td><td>  RootDivideByCount<Central<PowerSum<2>>>  </td></tr>
+    <tr><td> Covariance      </td><td>  DivideByCount<FlatScatterMatrix> </td></tr>
+    <tr><td> RegionCenter    </td><td>  Coord<Mean>                </td></tr>
+    <tr><td> CenterOfMass    </td><td>  Weighted<Coord<Mean>>      </td></tr>
+    </table>
+    
+    There are a few <b>rules for composing statistics</b>:
+    - modifiers can be specified in any order, but are internally transformed to standard order: Global<Weighted<Coord<normalization<data preparation<basic statistic
+    - only one normalization modifier and one data preparation modifier (Central or Principal or Whitened) is permitted 
+    - Count ignores all modifiers except Global and Weighted
+    - Sum ignores Central and Principal, because sum would be zero
+    - ArgMinWeight and ArgMaxWeight are automatically Weighted
+
+
+    Here is an example how to use \ref acc::AccumulatorChain to compute statistics. (To use Weighted<> or Coord<> modifiers, see below):
+
+    \code
+    #include <vigra/multi_array.hxx>
+    #include <vigra/impex.hxx>
+    #include <vigra/accumulator.hxx>
+    using namespace vigra::acc;
+    typedef double DataType;
+    int size = 1000;
+    vigra::MultiArray<2, DataType> data(vigra::Shape2(size, size));
+   
+    AccumulatorChain<DataType, 
+        Select<Variance, Mean, StdDev, Minimum, Maximum, RootMeanSquares, Skewness, Covariance> >
+        a;
+        
+    std::cout << "passes required: " << a.passesRequired() << std::endl;
+    extractFeatures(data.begin(), data.end(), a); 
+    
+    std::cout << "Mean: " << get<Mean>(a) << std::endl;
+    std::cout << "Variance: " << get<Variance>(a) << std::endl;
+    \endcode
+    
+    The \ref acc::AccumulatorChain object contains the selected statistics and their dependencies. Statistics have to be wrapped with \ref acc::Select. The statistics are computed with the acc::extractFeatures function and the statistics can be accessed with acc::get . 
+
+    Rules and notes:
+    - order of statistics in Select<> is arbitrary
+    - up to 20 statistics in Select<>, but Select<> can be nested
+    - dependencies are automatically inserted
+    - duplicates are automatically removed
+    - extractFeatures() does as many passes through the data as necessary
+    - each accumulator only sees data in the appropriate pass (its "working pass")
+
+    The Accumulators can also be used with vector-valued data (vigra::RGBValue, vigra::TinyVector, vigra::MultiArray or vigra::MultiArrayView):
+    
+    \code
+    typedef vigra::RGBValue<double> DataType;
+    AccumulatorChain<DataType, Select<...> > a;
+    ...
+    \endcode
+
+    To compute <b>weighted statistics</b> (Weighted<>) or <b>statistics over coordinates</b> (Coord<>), the accumulator chain can be used with several coupled arrays, one for the data and another for the weights and/or the labels. "Coupled" means that statistics are computed over the corresponding elements of the involved arrays. This is internally done by means of \ref CoupledScanOrderIterator and \ref vigra::CoupledHandle which provide simultaneous access to several arrays (e.g. weight [...]
+    
+    \code 
+    vigra::MultiArray<3, RGBValue<unsigned char> > data(...);
+    vigra::MultiArray<3, double>                   weights(...);
+    
+    AccumulatorChain<CoupledArrays<3, RGBValue<unsigned char>, double>,
+                     Select<...> > a;
+    \endcode
+    
+This works likewise for label images which are needed for region statistics (see below). The indxx of the array holding data, weights, or labels respectively can be specified inside the Select wrapper. These <b>index specifiers</b> are: (INDEX is of type int)
+    - DataArg<INDEX>: data are in array 'INDEX' (default INDEX=1)
+    - LabelArg<INDEX>: labels are in array 'INDEX' (default INDEX=2)
+    - WeightArg<INDEX>: weights are in array 'INDEX' (default INDEX=rightmost index)
+
+Pixel coordinates are always at index 0. To collect statistics, you simply pass all arrays to the <tt>extractFeatures()</tt> function:
+    \code
+    using namespace vigra::acc;
+    vigra::MultiArray<3, double> data(...), weights(...);
+    
+    AccumulatorChain<CoupledArrays<3, double, double>, // two 3D arrays for data and weights
+        Select<DataArg<1>, WeightArg<2>,           // in which array to look (coordinates are always arg 0)
+               Mean, Variance,                     //statistics over values  
+               Coord<Mean>, Coord<Variance>,       //statistics over coordinates,
+               Weighted<Mean>, Weighted<Variance>, //weighted values,
+               Weighted<Coord<Mean> > > >          //weighted coordinates.
+        a;
+     
+    extractFeatures(data, weights, a);
+    \endcode
+    
+    This even works for a single array, which is useful if you want to combine values with coordinates. For example, to find the location of the minimum element in an array, you interpret the data as weights and select the <tt>Coord<ArgMinWeight></tt> statistic (note that the version of <tt>extractFeatures()</tt> below only works in conjunction with <tt>CoupledArrays</tt>, despite the fact that there is only one array involved):
+    \code 
+    using namespace vigra::acc;
+    vigra::MultiArray<3, double> data(...);
+    
+    AccumulatorChain<CoupledArrays<3, double>,
+                     Select<WeightArg<1>,           // we interprete the data as weights
+                            Coord<ArgMinWeight> > > // and look for the coordinate with minimal weight
+        a;
+        
+    extractFeatures(data, a);
+    std::cout << "minimum is at " << get<Coord<ArgMinWeight> >(a) << std::endl;
+    \endcode
+    
+    To compute <b>region statistics</b>, you use \ref acc::AccumulatorChainArray. Regions are defined by means of a label array whose elements specify the region ID of the corresponding point. Therefore, you will always need at least two arrays here, which are again best specified using the <tt>CoupledArrays</tt> helper:
+    
+    \code
+    using namespace vigra::acc;
+    vigra::MultiArray<3, double> data(...);
+    vigra::MultiArray<3, int> labels(...);
+
+    AccumulatorChainArray<CoupledArrays<3, double, int>,
+        Select<DataArg<1>, LabelArg<2>,       // in which array to look (coordinates are always arg 0)
+               Mean, Variance,                    //per-region statistics over values
+               Coord<Mean>, Coord<Variance>,      //per-region statistics over coordinates
+               Global<Mean>, Global<Variance> > > //global statistics
+    a;
+
+    a.ignoreLabel(0); //statistics will not be computed for region 0 (e.g. background)
+
+    extractFeatures(data, labels, a);
+
+    int regionlabel = ...;
+    std::cout << get<Mean>(a, regionlabel) << std::endl; //get Mean of region with label 'regionlabel'
+    \endcode
+
+   
+    In some application it will be known only at run-time which statistics have to be computed. An Accumulator with <b>run-time activation</b> is provided by the \ref acc::DynamicAccumulatorChain class. One specifies a set of statistics at compile-time and from this set one can activate the needed statistics at run-time:
+  
+    \code
+    using namespace vigra::acc;
+    vigra::MultiArray<2, double> data(...);
+    DynamicAccumulatorChain<double, 
+        Select<Mean, Minimum, Maximum, Variance, StdDev> > a; // at compile-time
+    activate<Mean>(a);      //at run-time
+    a.activate("Minimum");  //same as activate<Minimum>(a) (alias names are not recognized)
+    
+    extractFeatures(data.begin(), data.end(), a);
+    std::cout << "Mean: " << get<Mean>(a) << std::endl;       //ok
+    //std::cout << "Maximum: " << get<Maximum>(a) << std::endl; // run-time error because Maximum not activated
+    \endcode
+      
+    Likewise, for run-time activation of region statistics, use \ref acc::DynamicAccumulatorChainArray. 
+
+    <b>Accumulator merging</b> (e.g. for parallelization or hierarchical segmentation) is possible for many accumulators:
+
+    \code
+    using namespace vigra::acc;
+    vigra::MultiArray<2, double> data(...);
+    AccumulatorChain<double, Select<Mean, Variance, Skewness> > a, a1, a2;
+
+    extractFeatures(data.begin(), data.end(), a); //process entire data set at once
+    extractFeatures(data.begin(), data.begin()+data.size()/2, a1); //process first half
+    extractFeatures(data.begin()+data.size()/2, data.end(), a2); //process second half
+    a1 += a2; // merge: a1 now equals a0 (within numerical tolerances)
+    \endcode
+
+    Not all statistics can be merged (e.g. Principal<A> usually cannot, except for some important specializations). A statistic can be merged if the "+=" operator is supported (see the documentation of that particular statistic). If the accumulator chain only requires one pass to collect the data, it is also possible to just apply the extractFeatures() function repeatedly:
+
+    \code
+    using namespace vigra::acc;
+    vigra::MultiArray<2, double> data(...);
+    AccumulatorChain<double, Select<Mean, Variance> > a;
+
+    extractFeatures(data.begin(), data.begin()+data.size()/2, a); // this works because 
+    extractFeatures(data.begin()+data.size()/2, data.end(), a);   // all statistics only need pass 1
+    \endcode
+    
+    More care is needed to merge coordinate-based statistics. By default, all coordinate statistics are computed in the local coordinate system of the current region of interest. That is, the upper left corner of the ROI has the coordinate (0, 0) by default. This behavior is not desirable when you want to merge coordinate statistics from different ROIs: then, all accumulators should use the same coordinate system, usually the global system of the entire dataset. This can be achieved by t [...]
+
+    \code
+    using namespace vigra;
+    using namespace vigra::acc;
+    
+    MultiArray<2, double> data(width, height);
+    MultiArray<2, int>    labels(width, height);
+    
+    AccumulatorChainArray<CoupledArrays<2, double, int>,
+                          Select<DataArg<1>, LabelArg<2>, 
+                                 RegionCenter> >
+    a1, a2;
+    
+    // a1 is responsible for the left half of the image. The local coordinate system of this ROI 
+    // happens to be identical to the global coordinate system, so the offset is zero.
+    Shape2 origin(0,0);
+    a1.setCoordinateOffset(origin);
+    extractFeatures(data.subarray(origin, Shape2(width/2, height)), 
+                    labels.subarray(origin, Shape2(width/2, height)),
+                    a1);
+                    
+    // a2 is responsible for the right half, so the offset of the local coordinate system is (width/2, 0)
+    origin = Shape2(width/2, 0);
+    a2.setCoordinateOffset(origin);
+    extractFeatures(data.subarray(origin, Shape2(width, height)), 
+                    labels.subarray(origin, Shape2(width, height)),
+                    a2);
+   
+    // since both accumulators worked in the same global coordinate system, we can safely merge them
+    a1.merge(a2);
+    \endcode
+    
+    When you compute region statistics in ROIs, it is sometimes desirable to use a local region labeling in each ROI. In this way, the labels of each ROI cover a consecutive range of numbers starting with 0. This can save a lot of memory, because <tt>AccumulatorChainArray</tt> internally uses dense arrays -- accumulators will be allocated for all labels from 0 to the maxmimum label, even when many of them are unused. This is avoided by a local labeling. However, this means that label 1 ( [...]
+    
+    \code
+    std::vector<int> labelMapping(2);
+    labelMapping[0] = 0;   // background keeps label 0
+    labelMapping[1] = 2;   // local region 1 becomes global region 2
+    
+    a1.merge(a2, labelMapping);
+    \endcode
+
+    \anchor histogram
+    Four kinds of <b>histograms</b> are currently implemented:
+    
+    <table border="0">
+      <tr><td> IntegerHistogram      </td><td>   Data values are equal to bin indices   </td></tr>
+      <tr><td> UserRangeHistogram    </td><td>  User provides lower and upper bounds for linear range mapping from values to indices.    </td></tr>
+      <tr><td> AutoRangeHistogram    </td><td>  Range mapping bounds are defiend by minimum and maximum of the data (2 passes needed!)    </td></tr>
+      <tr><td> GlobalRangeHistogram    </td><td>  Likewise, but use global min/max rather than region min/max as AutoRangeHistogram will </td></tr>
+      </table>    
+  
+
+       
+    - The number of bins is specified at compile time (as template parameter int BinCount) or at run-time (if BinCount is zero at compile time). In the first case the return type of the accumulator is TinyVector<double, BinCount> (number of bins cannot be changed). In the second case, the return type is MultiArray<1, double> and the number of bins must be set before seeing data (see example below). 
+    - If UserRangeHistogram is used, the bounds for the linear range mapping from values to indices must be set before seeing data (see below).
+    - Options can be set by passing an instance of HistogramOptions to the accumulator chain (same options for all histograms in the chain) or by directly calling the appropriate member functions of the accumulators.
+    - Merging is supported if the range mapping of the histograms is the same.
+    - Histogram accumulators have two members for outliers (left_outliers, right_outliers).
+
+    With the StandardQuantiles class, <b>histogram quantiles</b> (0%, 10%, 25%, 50%, 75%, 90%, 100%) are computed from a given histgram using linear interpolation. The return type is TinyVector<double, 7> .
+
+    \anchor acc_hist_options Usage:
+    \code
+    using namespace vigra::acc;
+    typedef double DataType;
+    vigra::MultiArray<2, DataType> data(...);
+    
+    typedef UserRangeHistogram<40> SomeHistogram;   //binCount set at compile time
+    typedef UserRangeHistogram<0> SomeHistogram2; // binCount must be set at run-time
+    typedef AutoRangeHistogram<0> SomeHistogram3;
+    typedef StandardQuantiles<SomeHistogram3> Quantiles3;
+    
+    AccumulatorChain<DataType, Select<SomeHistogram, SomeHistogram2, SomeHistogram3, Quantiles3> > a;
+    
+    //set options for all histograms in the accumulator chain:
+    vigra::HistogramOptions histogram_opt;         
+    histogram_opt = histogram_opt.setBinCount(50); 
+    //histogram_opt = histogram_opt.setMinMax(0.1, 0.9); // this would set min/max for all three histograms, but range bounds 
+                                                         // shall be set automatically by min/max of data for SomeHistogram3
+    a.setHistogramOptions(histogram_opt);  
+
+    // set options for a specific histogram in the accumulator chain:
+    getAccumulator<SomeHistogram>(a).setMinMax(0.1, 0.9); // number of bins must be set before setting min/max
+    getAccumulator<SomeHistogram2>(a).setMinMax(0.0, 1.0);
+
+    extractFeatures(data.begin(), data.end(), a);
+
+    vigra::TinyVector<double, 40> hist = get<SomeHistogram>(a);
+    vigra::MultiArray<1, double> hist2 = get<SomeHistogram2>(a);
+    vigra::TinyVector<double, 7> quant = get<Quantiles3>(a);
+    double right_outliers = getAccumulator<SomeHistogram>(a).right_outliers;
+    \endcode
+
+
+    
+*/
+
+
+/** This namespace contains the accumulator classes, fundamental statistics and modifiers. See \ref FeatureAccumulators for examples of usage.
+*/
+namespace acc {
+
+/****************************************************************************/
+/*                                                                          */
+/*                             infrastructure                               */
+/*                                                                          */
+/****************************************************************************/
+
+  /// \brief Wrapper for MakeTypeList that additionally performs tag standardization.
+
+template <class T01=void, class T02=void, class T03=void, class T04=void, class T05=void,
+          class T06=void, class T07=void, class T08=void, class T09=void, class T10=void,
+          class T11=void, class T12=void, class T13=void, class T14=void, class T15=void,
+          class T16=void, class T17=void, class T18=void, class T19=void, class T20=void>
+struct Select
+: public MakeTypeList<
+    typename StandardizeTag<T01>::type, typename StandardizeTag<T02>::type, typename StandardizeTag<T03>::type, 
+    typename StandardizeTag<T04>::type, typename StandardizeTag<T05>::type, typename StandardizeTag<T06>::type, 
+    typename StandardizeTag<T07>::type, typename StandardizeTag<T08>::type, typename StandardizeTag<T09>::type, 
+    typename StandardizeTag<T10>::type, typename StandardizeTag<T11>::type, typename StandardizeTag<T12>::type, 
+    typename StandardizeTag<T13>::type, typename StandardizeTag<T14>::type, typename StandardizeTag<T15>::type, 
+    typename StandardizeTag<T16>::type, typename StandardizeTag<T17>::type, typename StandardizeTag<T18>::type, 
+    typename StandardizeTag<T19>::type, typename StandardizeTag<T20>::type
+    >
+{};
+
+    // enable nesting of Select<> expressions 
+template <class T01, class T02, class T03, class T04, class T05,
+          class T06, class T07, class T08, class T09, class T10,
+          class T11, class T12, class T13, class T14, class T15,
+          class T16, class T17, class T18, class T19, class T20>
+struct StandardizeTag<Select<T01, T02, T03, T04, T05,
+                             T06, T07, T08, T09, T10,
+                             T11, T12, T13, T14, T15,
+                             T16, T17, T18, T19, T20>, 
+                      Select<T01, T02, T03, T04, T05,
+                             T06, T07, T08, T09, T10,
+                             T11, T12, T13, T14, T15,
+                             T16, T17, T18, T19, T20> >
+{
+    typedef typename  Select<T01, T02, T03, T04, T05,
+                             T06, T07, T08, T09, T10,
+                             T11, T12, T13, T14, T15,
+                             T16, T17, T18, T19, T20>::type type;
+};
+
+struct AccumulatorBegin
+{
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "AccumulatorBegin (internal)";
+       // static const std::string n("AccumulatorBegin (internal)");
+       // return n;
+    }
+    
+    template <class T, class BASE>
+    struct Impl
+    : public BASE
+    {};
+};
+
+
+struct AccumulatorEnd;
+struct DataArgTag;
+struct WeightArgTag;
+struct LabelArgTag;
+struct CoordArgTag;
+struct LabelDispatchTag;
+
+struct Error__Global_statistics_are_only_defined_for_AccumulatorChainArray;
+
+/** \brief Specifies index of labels in CoupledHandle. 
+
+    LabelArg<INDEX> tells the acc::AccumulatorChainArray which index of the Handle contains the labels. (Note that coordinates are always index 0)
+ */
+template <int INDEX>
+class LabelArg
+{
+  public:
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("LabelArg<") + asString(INDEX) + "> (internal)";
+        // static const std::string n = std::string("LabelArg<") + asString(INDEX) + "> (internal)";
+        // return n;
+    }
+    
+    template <class T, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef LabelArgTag Tag;
+        typedef void value_type;
+        typedef void result_type;
+
+        static const int value = INDEX;
+        static const unsigned int workInPass = 0;
+    };
+};
+
+template <int INDEX>
+class CoordArg
+{
+  public:
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("CoordArg<") + asString(INDEX) + "> (internal)";
+        // static const std::string n = std::string("CoordArg<") + asString(INDEX) + "> (internal)";
+        // return n;
+    }
+    
+    template <class T, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef CoordArgTag Tag;
+        typedef void value_type;
+        typedef void result_type;
+
+        static const int value = INDEX;
+        static const unsigned int workInPass = 0;
+    };
+};
+
+template <class T, class TAG, class NEXT=AccumulatorEnd>
+struct AccumulatorBase;
+
+template <class Tag, class A>
+struct LookupTag;
+
+template <class Tag, class A, class TargetTag=typename A::Tag>
+struct LookupDependency;
+
+#ifndef _MSC_VER  // compiler bug? (causes 'ambiguous overload error')
+
+template <class TAG, class A>
+typename LookupTag<TAG, A>::reference
+getAccumulator(A & a);
+
+template <class TAG, class A>
+typename LookupDependency<TAG, A>::result_type
+getDependency(A const & a);
+
+#endif
+
+namespace acc_detail {
+
+/****************************************************************************/
+/*                                                                          */
+/*                   internal tag handling meta-functions                   */
+/*                                                                          */
+/****************************************************************************/
+
+    // we must make sure that Arg<INDEX> tags are at the end of the chain because 
+    // all other tags potentially depend on them
+template <class T>
+struct PushArgTagToTail
+{
+    typedef T type;
+};
+
+#define VIGRA_PUSHARGTAG(TAG) \
+template <int INDEX, class TAIL> \
+struct PushArgTagToTail<TypeList<TAG<INDEX>, TAIL> > \
+{ \
+    typedef typename Push<TAIL, TypeList<TAG<INDEX> > >::type type; \
+};
+
+VIGRA_PUSHARGTAG(DataArg)
+VIGRA_PUSHARGTAG(WeightArg)
+VIGRA_PUSHARGTAG(CoordArg)
+VIGRA_PUSHARGTAG(LabelArg)
+
+#undef VIGRA_PUSHARGTAG
+
+    // Insert the dependencies of the selected functors into the TypeList and sort
+    // the list such that dependencies come after the functors using them. Make sure 
+    // that each functor is contained only once.
+template <class T>
+struct AddDependencies;
+
+template <class HEAD, class TAIL>
+struct AddDependencies<TypeList<HEAD, TAIL> >
+{
+    typedef typename AddDependencies<TAIL>::type                                   TailWithDependencies;
+    typedef typename StandardizeDependencies<HEAD>::type                           HeadDependencies;
+    typedef typename AddDependencies<HeadDependencies>::type                       TransitiveHeadDependencies;
+    typedef TypeList<HEAD, TransitiveHeadDependencies>                             HeadWithDependencies;
+    typedef typename PushUnique<HeadWithDependencies, TailWithDependencies>::type  UnsortedDependencies;
+    typedef typename PushArgTagToTail<UnsortedDependencies>::type                  type;
+};
+
+template <>
+struct AddDependencies<void>
+{
+    typedef void type;
+};
+
+    // Helper class to activate dependencies at runtime (i.e. when activate<Tag>(accu) is called,
+    // activate() must also be called for Tag's dependencies).
+template <class Dependencies>
+struct ActivateDependencies;
+
+template <class HEAD, class TAIL>
+struct ActivateDependencies<TypeList<HEAD, TAIL> >
+{
+    template <class Chain, class ActiveFlags>
+    static void exec(ActiveFlags & flags)
+    {
+        LookupTag<HEAD, Chain>::type::activateImpl(flags);
+        ActivateDependencies<TAIL>::template exec<Chain>(flags);
+    }
+    
+    template <class Chain, class ActiveFlags, class GlobalFlags>
+    static void exec(ActiveFlags & flags, GlobalFlags & gflags)
+    {
+        LookupTag<HEAD, Chain>::type::template activateImpl<Chain>(flags, gflags);
+        ActivateDependencies<TAIL>::template exec<Chain>(flags, gflags);
+    }
+};
+
+template <class HEAD, class TAIL>
+struct ActivateDependencies<TypeList<Global<HEAD>, TAIL> >
+{
+    template <class Chain, class ActiveFlags, class GlobalFlags>
+    static void exec(ActiveFlags & flags, GlobalFlags & gflags)
+    {
+        LookupTag<Global<HEAD>, Chain>::type::activateImpl(gflags);
+        ActivateDependencies<TAIL>::template exec<Chain>(flags, gflags);
+    }
+};
+
+template <>
+struct ActivateDependencies<void>
+{
+    template <class Chain, class ActiveFlags>
+    static void exec(ActiveFlags &)
+    {}
+    
+    template <class Chain, class ActiveFlags, class GlobalFlags>
+    static void exec(ActiveFlags &, GlobalFlags &)
+    {}
+};
+
+template <class List>
+struct SeparateGlobalAndRegionTags;
+
+template <class HEAD, class TAIL>
+struct SeparateGlobalAndRegionTags<TypeList<HEAD, TAIL> >
+{
+    typedef SeparateGlobalAndRegionTags<TAIL>           Inner;
+    typedef TypeList<HEAD, typename Inner::RegionTags>  RegionTags;
+    typedef typename Inner::GlobalTags                  GlobalTags;
+};
+
+template <class HEAD, class TAIL>
+struct SeparateGlobalAndRegionTags<TypeList<Global<HEAD>, TAIL> >
+{
+    typedef SeparateGlobalAndRegionTags<TAIL>           Inner;
+    typedef typename Inner::RegionTags                  RegionTags;
+    typedef TypeList<HEAD, typename Inner::GlobalTags>  GlobalTags;
+};
+
+template <int INDEX, class TAIL>
+struct SeparateGlobalAndRegionTags<TypeList<DataArg<INDEX>, TAIL> >
+{
+    typedef SeparateGlobalAndRegionTags<TAIL>           Inner;
+    typedef TypeList<DataArg<INDEX>, typename Inner::RegionTags>  RegionTags;
+    typedef TypeList<DataArg<INDEX>, typename Inner::GlobalTags>  GlobalTags;
+};
+
+template <int INDEX, class TAIL>
+struct SeparateGlobalAndRegionTags<TypeList<LabelArg<INDEX>, TAIL> >
+{
+    typedef SeparateGlobalAndRegionTags<TAIL>           Inner;
+    typedef typename Inner::RegionTags                  RegionTags;
+    typedef TypeList<LabelArg<INDEX>, typename Inner::GlobalTags>  GlobalTags;
+};
+
+template <int INDEX, class TAIL>
+struct SeparateGlobalAndRegionTags<TypeList<WeightArg<INDEX>, TAIL> >
+{
+    typedef SeparateGlobalAndRegionTags<TAIL>           Inner;
+    typedef TypeList<WeightArg<INDEX>, typename Inner::RegionTags>  RegionTags;
+    typedef TypeList<WeightArg<INDEX>, typename Inner::GlobalTags>  GlobalTags;
+};
+
+template <int INDEX, class TAIL>
+struct SeparateGlobalAndRegionTags<TypeList<CoordArg<INDEX>, TAIL> >
+{
+    typedef SeparateGlobalAndRegionTags<TAIL>           Inner;
+    typedef TypeList<CoordArg<INDEX>, typename Inner::RegionTags>  RegionTags;
+    typedef TypeList<CoordArg<INDEX>, typename Inner::GlobalTags>  GlobalTags;
+};
+
+template <>
+struct SeparateGlobalAndRegionTags<void>
+{
+    typedef void RegionTags;
+    typedef void GlobalTags;
+};
+
+/****************************************************************************/
+/*                                                                          */
+/*          helper classes to handle tags at runtime via strings            */
+/*                                                                          */
+/****************************************************************************/
+
+template <class Accumulators>
+struct CollectAccumulatorNames;
+
+template <class HEAD, class TAIL>
+struct CollectAccumulatorNames<TypeList<HEAD, TAIL> >
+{
+    template <class BackInsertable>
+    static void exec(BackInsertable & a, bool skipInternals=true)
+    {
+        if(!skipInternals || HEAD::name().find("internal") == std::string::npos)
+            a.push_back(HEAD::name());
+        CollectAccumulatorNames<TAIL>::exec(a, skipInternals);
+    }
+};
+
+template <>
+struct CollectAccumulatorNames<void>
+{
+    template <class BackInsertable>
+    static void exec(BackInsertable & a, bool skipInternals=true)
+    {}
+};
+
+template <class T>
+struct ApplyVisitorToTag;
+
+template <class HEAD, class TAIL>
+struct ApplyVisitorToTag<TypeList<HEAD, TAIL> >
+{
+    template <class Accu, class Visitor>
+    static bool exec(Accu & a, std::string const & tag, Visitor const & v)
+    {
+        static std::string * name = VIGRA_SAFE_STATIC(name, new std::string(normalizeString(HEAD::name())));
+        if(*name == tag)
+        {
+            v.template exec<HEAD>(a);
+            return true;
+        }
+        else
+        {
+            return ApplyVisitorToTag<TAIL>::exec(a, tag, v);
+        }
+    }
+};
+
+template <>
+struct ApplyVisitorToTag<void>
+{
+    template <class Accu, class Visitor>
+    static bool exec(Accu & a, std::string const & tag, Visitor const & v)
+    {
+        return false;
+    }
+};
+
+struct ActivateTag_Visitor
+{
+    template <class TAG, class Accu>
+    void exec(Accu & a) const
+    {
+        a.template activate<TAG>();
+    }
+};
+
+struct TagIsActive_Visitor
+{
+    mutable bool result;
+    
+    template <class TAG, class Accu>
+    void exec(Accu & a) const
+    {
+        result = a.template isActive<TAG>();
+    }
+};
+
+/****************************************************************************/
+/*                                                                          */
+/*                    histogram initialization functors                     */
+/*                                                                          */
+/****************************************************************************/
+
+template <class TAG>
+struct SetHistogramBincount
+{
+    template <class Accu>
+    static void exec(Accu & a, HistogramOptions const & options)
+    {}
+};
+
+template <template <int> class Histogram>
+struct SetHistogramBincount<Histogram<0> >
+{
+    template <class Accu>
+    static void exec(Accu & a, HistogramOptions const & options)
+    {
+        a.setBinCount(options.binCount);
+    }
+};
+
+template <class TAG>
+struct ApplyHistogramOptions
+{
+    template <class Accu>
+    static void exec(Accu & a, HistogramOptions const & options)
+    {}
+};
+
+template <class TAG>
+struct ApplyHistogramOptions<StandardQuantiles<TAG> >
+{
+    template <class Accu>
+    static void exec(Accu & a, HistogramOptions const & options)
+    {}
+};
+
+template <class TAG, template <class> class MODIFIER>
+struct ApplyHistogramOptions<MODIFIER<TAG> >
+: public ApplyHistogramOptions<TAG>
+{};
+
+template <>
+struct ApplyHistogramOptions<IntegerHistogram<0> >
+{
+    template <class Accu>
+    static void exec(Accu & a, HistogramOptions const & options)
+    {
+        SetHistogramBincount<IntegerHistogram<0> >::exec(a, options);
+    }
+};
+
+template <int BinCount>
+struct ApplyHistogramOptions<UserRangeHistogram<BinCount> >
+{
+    template <class Accu>
+    static void exec(Accu & a, HistogramOptions const & options)
+    {
+        SetHistogramBincount<UserRangeHistogram<BinCount> >::exec(a, options);
+        if(a.scale_ == 0.0 && options.validMinMax())
+            a.setMinMax(options.minimum, options.maximum);
+    }
+};
+
+template <int BinCount>
+struct ApplyHistogramOptions<AutoRangeHistogram<BinCount> >
+{
+    template <class Accu>
+    static void exec(Accu & a, HistogramOptions const & options)
+    {
+        SetHistogramBincount<AutoRangeHistogram<BinCount> >::exec(a, options);
+        if(a.scale_ == 0.0 && options.validMinMax())
+            a.setMinMax(options.minimum, options.maximum);
+    }
+};
+
+template <int BinCount>
+struct ApplyHistogramOptions<GlobalRangeHistogram<BinCount> >
+{
+    template <class Accu>
+    static void exec(Accu & a, HistogramOptions const & options)
+    {
+        SetHistogramBincount<GlobalRangeHistogram<BinCount> >::exec(a, options);
+        if(a.scale_ == 0.0)
+        {
+            if(options.validMinMax())
+                a.setMinMax(options.minimum, options.maximum);
+            else
+                a.setRegionAutoInit(options.local_auto_init);
+        }
+    }
+};
+
+/****************************************************************************/
+/*                                                                          */
+/*                   internal accumulator chain classes                     */
+/*                                                                          */
+/****************************************************************************/
+
+    // AccumulatorEndImpl has the following functionalities:
+    //  * marks end of accumulator chain by the AccumulatorEnd tag
+    //  * provides empty implementation of standard accumulator functions
+    //  * provides active_accumulators_ flags for run-time activation of dynamic accumulators
+    //  * provides is_dirty_ flags for caching accumulators
+    //  * hold the GlobalAccumulatorHandle for global accumulator lookup from region accumulators
+template <unsigned LEVEL, class GlobalAccumulatorHandle>
+struct AccumulatorEndImpl
+{
+    typedef typename GlobalAccumulatorHandle::type  GlobalAccumulatorType;
+    
+    typedef AccumulatorEnd     Tag;
+    typedef void               value_type;
+    typedef bool               result_type;
+    typedef BitArray<LEVEL>    AccumulatorFlags;
+    
+    static const unsigned int  workInPass = 0; 
+    static const int           index = -1;
+    static const unsigned      level = LEVEL;
+    
+    AccumulatorFlags            active_accumulators_;
+    mutable AccumulatorFlags    is_dirty_;
+    GlobalAccumulatorHandle     globalAccumulator_;
+        
+    template <class GlobalAccumulator>
+    void setGlobalAccumulator(GlobalAccumulator const * a)
+    {
+        globalAccumulator_.pointer_ = a;
+    }
+
+    static std::string name()
+    {
+        return "AccumulatorEnd (internal)";
+    }
+        
+    bool operator()() const { return false; }
+    bool get() const { return false; }
+    
+    template <unsigned, class U>
+    void pass(U const &) 
+    {}
+    
+    template <unsigned, class U>
+    void pass(U const &, double) 
+    {}
+    
+    template <class U>
+    void mergeImpl(U const &) 
+    {}
+    
+    template <class U>
+    void resize(U const &) 
+    {}
+        
+    template <class U>
+    void setCoordinateOffsetImpl(U const &)
+    {}
+    
+    void activate() 
+    {}
+    
+    bool isActive() const 
+    { 
+        return false;
+    }
+    
+    template <class Flags>
+    static void activateImpl(Flags &)
+    {}
+    
+    template <class Accu, class Flags1, class Flags2>
+    static void activateImpl(Flags1 &, Flags2 &)
+    {}
+    
+    template <class Flags>
+    static bool isActiveImpl(Flags const &)
+    {
+        return true;
+    }
+    
+    void applyHistogramOptions(HistogramOptions const &)
+    {}
+    
+    static unsigned int passesRequired()
+    {
+        return 0;
+    }
+    
+    static unsigned int passesRequired(AccumulatorFlags const &)
+    {
+        return 0;
+    }
+
+    void reset()
+    {
+        active_accumulators_.clear();
+        is_dirty_.clear();
+    }
+        
+    template <int which>
+    void setDirtyImpl() const
+    {
+        is_dirty_.template set<which>();
+    }
+    
+    template <int which>
+    void setCleanImpl() const
+    {
+        is_dirty_.template reset<which>();
+    }
+    
+    template <int which>
+    bool isDirtyImpl() const
+    {
+        return is_dirty_.template test<which>();
+    }
+};
+
+    // DecoratorImpl implement the functionality of Decorator below
+template <class A, unsigned CurrentPass, bool allowRuntimeActivation, unsigned WorkPass=A::workInPass>
+struct DecoratorImpl
+{
+    template <class T>
+    static void exec(A & a, T const & t)
+    {}
+
+    template <class T>
+    static void exec(A & a, T const & t, double weight)
+    {}
+};
+
+template <class A, unsigned CurrentPass>
+struct DecoratorImpl<A, CurrentPass, false, CurrentPass>
+{
+    template <class T>
+    static void exec(A & a, T const & t)
+    {
+        a.update(t);
+    }
+    
+    template <class T>
+    static void exec(A & a, T const & t, double weight)
+    {
+        a.update(t, weight);
+    }
+
+    static typename A::result_type get(A const & a)
+    {
+        return a();
+    }
+
+    static void mergeImpl(A & a, A const & o)
+    {
+        a += o;
+    }
+
+    template <class T>
+    static void resize(A & a, T const & t)
+    {
+        a.reshape(t);
+    }
+    
+    static void applyHistogramOptions(A & a, HistogramOptions const & options)
+    {
+        ApplyHistogramOptions<typename A::Tag>::exec(a, options);
+    }
+
+    static unsigned int passesRequired()
+    {
+        static const unsigned int A_workInPass = A::workInPass;
+        return std::max(A_workInPass, A::InternalBaseType::passesRequired());
+    }
+};
+
+template <class A, unsigned CurrentPass>
+struct DecoratorImpl<A, CurrentPass, true, CurrentPass>
+{
+    static bool isActive(A const & a)
+    {
+        return A::isActiveImpl(getAccumulator<AccumulatorEnd>(a).active_accumulators_);
+    }
+    
+    template <class T>
+    static void exec(A & a, T const & t)
+    {
+        if(isActive(a))
+            a.update(t);
+    }
+
+    template <class T>
+    static void exec(A & a, T const & t, double weight)
+    {
+        if(isActive(a))
+            a.update(t, weight);
+    }
+
+    static typename A::result_type get(A const & a)
+    {
+        if(!isActive(a))
+        {
+            std::string message = std::string("get(accumulator): attempt to access inactive statistic '") +
+                                              A::Tag::name() + "'.";
+            vigra_precondition(false, message);
+        }
+        return a();
+    }
+
+    static void mergeImpl(A & a, A const & o)
+    {
+        if(isActive(a))
+            a += o;
+    }
+
+    template <class T>
+    static void resize(A & a, T const & t)
+    {
+        if(isActive(a))
+            a.reshape(t);
+    }
+    
+    static void applyHistogramOptions(A & a, HistogramOptions const & options)
+    {
+        if(isActive(a))
+            ApplyHistogramOptions<typename A::Tag>::exec(a, options);
+    }
+    
+    template <class ActiveFlags>
+    static unsigned int passesRequired(ActiveFlags const & flags)
+    {
+        static const unsigned int A_workInPass = A::workInPass;
+        return A::isActiveImpl(flags)
+                   ? std::max(A_workInPass, A::InternalBaseType::passesRequired(flags))
+                   : A::InternalBaseType::passesRequired(flags);
+    }
+};
+
+    // Generic reshape function (expands to a no-op when T has fixed shape, and to
+    // the appropriate specialized call otherwise). Shape is an instance of MultiArrayShape<N>::type.
+template <class T, class Shape>
+void reshapeImpl(T &, Shape const &)
+{}
+
+template <class T, class Shape, class Initial>
+void reshapeImpl(T &, Shape const &, Initial const & = T())
+{}
+
+template <unsigned int N, class T, class Alloc, class Shape>
+void reshapeImpl(MultiArray<N, T, Alloc> & a, Shape const & s, T const & initial = T())
+{
+    MultiArray<N, T, Alloc>(s, initial).swap(a);
+}
+
+template <class T, class Alloc, class Shape>
+void reshapeImpl(Matrix<T, Alloc> & a, Shape const & s, T const & initial = T())
+{
+    Matrix<T, Alloc>(s, initial).swap(a);
+}
+
+template <class T, class U>
+void copyShapeImpl(T const &, U const &)   // to be used for scalars and static arrays
+{}
+
+template <unsigned int N, class T, class Alloc, class U>
+void copyShapeImpl(MultiArray<N, T, Alloc> const & from, U & to) 
+{
+    to.reshape(from.shape());
+}
+
+template <class T, class Alloc, class U>
+void copyShapeImpl(Matrix<T, Alloc> const & from, U & to) 
+{
+    to.reshape(from.shape());
+}
+
+template <class T, class U>
+bool hasDataImpl(T const &)   // to be used for scalars and static arrays
+{
+    return true;
+}
+
+template <unsigned int N, class T, class Stride>
+bool hasDataImpl(MultiArrayView<N, T, Stride> const & a) 
+{
+    return a.hasData();
+}
+
+    // generic functions to create suitable shape objects from various input data types 
+template <unsigned int N, class T, class Stride>
+inline typename MultiArrayShape<N>::type
+shapeOf(MultiArrayView<N, T, Stride> const & a)
+{
+    return a.shape();
+}
+
+template <class T, int N>
+inline Shape1
+shapeOf(TinyVector<T, N> const &)
+{
+    return Shape1(N);
+}
+
+template <class T, class NEXT>
+inline CoupledHandle<T, NEXT> const &
+shapeOf(CoupledHandle<T, NEXT> const & t)
+{
+    return t;
+}
+
+#define VIGRA_SHAPE_OF(type) \
+inline Shape1 \
+shapeOf(type) \
+{ \
+    return Shape1(1); \
+}
+
+VIGRA_SHAPE_OF(unsigned char)
+VIGRA_SHAPE_OF(signed char)
+VIGRA_SHAPE_OF(unsigned short)
+VIGRA_SHAPE_OF(short)
+VIGRA_SHAPE_OF(unsigned int)
+VIGRA_SHAPE_OF(int)
+VIGRA_SHAPE_OF(unsigned long)
+VIGRA_SHAPE_OF(long)
+VIGRA_SHAPE_OF(unsigned long long)
+VIGRA_SHAPE_OF(long long)
+VIGRA_SHAPE_OF(float)
+VIGRA_SHAPE_OF(double)
+VIGRA_SHAPE_OF(long double)
+
+#undef VIGRA_SHAPE_OF
+
+    // LabelDispatch is only used in AccumulatorChainArrays and has the following functionalities:
+    //  * hold an accumulator chain for global statistics
+    //  * hold an array of accumulator chains (one per region) for region statistics
+    //  * forward data to the appropriate chains
+    //  * allocate the region array with appropriate size
+    //  * store and forward activation requests
+    //  * compute required number of passes as maximum from global and region accumulators
+template <class T, class GlobalAccumulators, class RegionAccumulators>
+struct LabelDispatch
+{
+    typedef LabelDispatchTag Tag;
+    typedef GlobalAccumulators GlobalAccumulatorChain;
+    typedef RegionAccumulators RegionAccumulatorChain;
+    typedef typename LookupTag<AccumulatorEnd, RegionAccumulatorChain>::type::AccumulatorFlags ActiveFlagsType;
+    typedef ArrayVector<RegionAccumulatorChain> RegionAccumulatorArray;
+        
+    typedef LabelDispatch type;
+    typedef LabelDispatch & reference;
+    typedef LabelDispatch const & const_reference;
+    typedef GlobalAccumulatorChain InternalBaseType;
+    
+    typedef T const & argument_type;
+    typedef argument_type first_argument_type;
+    typedef double second_argument_type;
+    typedef RegionAccumulatorChain & result_type;
+    
+    static const int index = GlobalAccumulatorChain::index + 1;
+    
+    template <class IndexDefinition, class TagFound=typename IndexDefinition::Tag>
+    struct CoordIndexSelector
+    {
+        static const int value = 0; // default: CoupledHandle holds coordinates at index 0 
+    };
+    
+    template <class IndexDefinition>
+    struct CoordIndexSelector<IndexDefinition, CoordArgTag>
+    {
+        static const int value = IndexDefinition::value;
+    };
+    
+    static const int coordIndex = CoordIndexSelector<typename LookupTag<CoordArgTag, GlobalAccumulatorChain>::type>::value;
+    static const int coordSize  = CoupledHandleCast<coordIndex, T>::type::value_type::static_size;
+    typedef TinyVector<double, coordSize> CoordinateType;
+    
+    GlobalAccumulatorChain next_;
+    RegionAccumulatorArray regions_;
+    HistogramOptions region_histogram_options_;
+    MultiArrayIndex ignore_label_;
+    ActiveFlagsType active_region_accumulators_;
+    CoordinateType coordinateOffset_;
+    
+    template <class IndexDefinition, class TagFound=typename IndexDefinition::Tag>
+    struct LabelIndexSelector
+    {
+        static const int value = 2; // default: CoupledHandle holds labels at index 2
+
+        template <class U, class NEXT>
+        static MultiArrayIndex exec(CoupledHandle<U, NEXT> const & t)
+        {
+            return (MultiArrayIndex)get<value>(t); 
+        }
+    };
+    
+    template <class IndexDefinition>
+    struct LabelIndexSelector<IndexDefinition, LabelArgTag>
+    {
+        static const int value = IndexDefinition::value;
+
+        template <class U, class NEXT>
+        static MultiArrayIndex exec(CoupledHandle<U, NEXT> const & t)
+        {
+            return (MultiArrayIndex)get<value>(t);
+        }
+    };
+    
+    template <class TAG>
+    struct ActivateImpl
+    {
+        typedef typename LookupTag<TAG, type>::type TargetAccumulator;
+        
+        static void activate(GlobalAccumulatorChain & globals, RegionAccumulatorArray & regions, 
+                             ActiveFlagsType & flags)
+        {
+            TargetAccumulator::template activateImpl<LabelDispatch>(
+                      flags, getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
+            for(unsigned int k=0; k<regions.size(); ++k)
+                getAccumulator<AccumulatorEnd>(regions[k]).active_accumulators_ = flags;
+        }
+        
+        static bool isActive(GlobalAccumulatorChain const &, ActiveFlagsType const & flags)
+        {
+            return TargetAccumulator::isActiveImpl(flags);
+        }
+    };
+    
+    template <class TAG>
+    struct ActivateImpl<Global<TAG> >
+    {
+        static void activate(GlobalAccumulatorChain & globals, RegionAccumulatorArray &, ActiveFlagsType &)
+        {
+            LookupTag<TAG, GlobalAccumulatorChain>::type::activateImpl(getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
+        }
+        
+        static bool isActive(GlobalAccumulatorChain const & globals, ActiveFlagsType const &)
+        {
+            return LookupTag<TAG, GlobalAccumulatorChain>::type::isActiveImpl(getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
+        }
+    };
+    
+    template <int INDEX>
+    struct ActivateImpl<LabelArg<INDEX> >
+    {
+        static void activate(GlobalAccumulatorChain &, RegionAccumulatorArray &, ActiveFlagsType &)
+        {}
+        
+        static bool isActive(GlobalAccumulatorChain const & globals, ActiveFlagsType const &)
+        {
+            return getAccumulator<LabelArg<INDEX> >(globals).isActive();
+        }
+    };
+    
+    typedef typename LookupTag<LabelArgTag, GlobalAccumulatorChain>::type FindLabelIndex;
+    
+    LabelDispatch()
+    : next_(),
+      regions_(),
+      region_histogram_options_(),
+      ignore_label_(-1),
+      active_region_accumulators_()
+    {}
+    
+    LabelDispatch(LabelDispatch const & o)
+    : next_(o.next_),
+      regions_(o.regions_),
+      region_histogram_options_(o.region_histogram_options_),
+      ignore_label_(o.ignore_label_),
+      active_region_accumulators_(o.active_region_accumulators_)
+    {
+        for(unsigned int k=0; k<regions_.size(); ++k)
+        {
+            getAccumulator<AccumulatorEnd>(regions_[k]).setGlobalAccumulator(&next_);
+        }
+    }
+    
+    MultiArrayIndex maxRegionLabel() const
+    {
+        return (MultiArrayIndex)regions_.size() - 1;
+    }
+    
+    void setMaxRegionLabel(unsigned maxlabel)
+    {
+        if(maxRegionLabel() == (MultiArrayIndex)maxlabel)
+            return;
+        unsigned int oldSize = regions_.size();
+        regions_.resize(maxlabel + 1);
+        for(unsigned int k=oldSize; k<regions_.size(); ++k)
+        {
+            getAccumulator<AccumulatorEnd>(regions_[k]).setGlobalAccumulator(&next_);
+            getAccumulator<AccumulatorEnd>(regions_[k]).active_accumulators_ = active_region_accumulators_;
+            regions_[k].applyHistogramOptions(region_histogram_options_);
+            regions_[k].setCoordinateOffsetImpl(coordinateOffset_);
+        }
+    }
+    
+    void ignoreLabel(MultiArrayIndex l)
+    {
+        ignore_label_ = l;
+    }
+    
+    void applyHistogramOptions(HistogramOptions const & options)
+    {
+        applyHistogramOptions(options, options);
+    }
+    
+    void applyHistogramOptions(HistogramOptions const & regionoptions, HistogramOptions const & globaloptions)
+    {
+        region_histogram_options_ = regionoptions;
+        for(unsigned int k=0; k<regions_.size(); ++k)
+        {
+            regions_[k].applyHistogramOptions(region_histogram_options_);
+        }
+        next_.applyHistogramOptions(globaloptions);
+    }
+    
+    void setCoordinateOffsetImpl(CoordinateType const & offset)
+    {
+        coordinateOffset_ = offset;
+        for(unsigned int k=0; k<regions_.size(); ++k)
+        {
+            regions_[k].setCoordinateOffsetImpl(coordinateOffset_);
+        }
+        next_.setCoordinateOffsetImpl(coordinateOffset_);
+    }
+    
+    template <class U>
+    void resize(U const & t)
+    {
+        if(regions_.size() == 0)
+        {
+            static const int labelIndex = LabelIndexSelector<FindLabelIndex>::value;
+            typedef typename CoupledHandleCast<labelIndex, T>::type LabelHandle;
+            typedef typename LabelHandle::value_type LabelType;
+            typedef MultiArrayView<LabelHandle::dimensions, LabelType, StridedArrayTag> LabelArray;
+            LabelArray labelArray(t.shape(), cast<labelIndex>(t).strides(), const_cast<LabelType *>(cast<labelIndex>(t).ptr()));
+            
+            LabelType minimum, maximum;
+            labelArray.minmax(&minimum, &maximum);
+            setMaxRegionLabel(maximum);
+        }
+        next_.resize(t);
+        // FIXME: only call resize when label k actually exists?
+        for(unsigned int k=0; k<regions_.size(); ++k)
+            regions_[k].resize(t);
+    }
+    
+    template <unsigned N>
+    void pass(T const & t)
+    {
+        if(LabelIndexSelector<FindLabelIndex>::exec(t) != ignore_label_)
+        {
+            next_.template pass<N>(t);
+            regions_[LabelIndexSelector<FindLabelIndex>::exec(t)].template pass<N>(t);
+        }
+    }
+    
+    template <unsigned N>
+    void pass(T const & t, double weight)
+    {
+        if(LabelIndexSelector<FindLabelIndex>::exec(t) != ignore_label_)
+        {
+            next_.template pass<N>(t, weight);
+            regions_[LabelIndexSelector<FindLabelIndex>::exec(t)].template pass<N>(t, weight);
+        }
+    }
+    
+    static unsigned int passesRequired()
+    {
+        return std::max(GlobalAccumulatorChain::passesRequired(), RegionAccumulatorChain::passesRequired());
+    }
+    
+    unsigned int passesRequiredDynamic() const
+    {
+        return std::max(GlobalAccumulatorChain::passesRequired(getAccumulator<AccumulatorEnd>(next_).active_accumulators_), 
+                        RegionAccumulatorChain::passesRequired(active_region_accumulators_));
+    }
+    
+    void reset()
+    {
+        next_.reset();
+        
+        active_region_accumulators_.clear();
+        RegionAccumulatorArray().swap(regions_);
+        // FIXME: or is it better to just reset the region accumulators?
+        // for(unsigned int k=0; k<regions_.size(); ++k)
+            // regions_[k].reset();
+    }
+    
+    template <class TAG>
+    void activate()
+    {
+        ActivateImpl<TAG>::activate(next_, regions_, active_region_accumulators_);
+    }
+    
+    void activateAll()
+    {
+        getAccumulator<AccumulatorEnd>(next_).active_accumulators_.set();
+        active_region_accumulators_.set();
+        for(unsigned int k=0; k<regions_.size(); ++k)
+            getAccumulator<AccumulatorEnd>(regions_[k]).active_accumulators_.set();
+    }
+    
+    template <class TAG>
+    bool isActive() const
+    {
+        return ActivateImpl<TAG>::isActive(next_, active_region_accumulators_);
+    }
+    
+    void mergeImpl(LabelDispatch const & o)
+    {
+        for(unsigned int k=0; k<regions_.size(); ++k)
+            regions_[k].mergeImpl(o.regions_[k]);
+        next_.mergeImpl(o.next_);
+    }
+    
+    void mergeImpl(unsigned i, unsigned j)
+    {
+        regions_[i].mergeImpl(regions_[j]);
+        regions_[j].reset();
+        getAccumulator<AccumulatorEnd>(regions_[j]).active_accumulators_ = active_region_accumulators_;
+    }
+    
+    template <class ArrayLike>
+    void mergeImpl(LabelDispatch const & o, ArrayLike const & labelMapping)
+    {
+        MultiArrayIndex newMaxLabel = std::max<MultiArrayIndex>(maxRegionLabel(), *argMax(labelMapping.begin(), labelMapping.end()));
+        setMaxRegionLabel(newMaxLabel);
+        for(unsigned int k=0; k<labelMapping.size(); ++k)
+            regions_[labelMapping[k]].mergeImpl(o.regions_[k]);
+        next_.mergeImpl(o.next_);
+    }
+};
+
+template <class TargetTag, class TagList>
+struct FindNextTag;
+
+template <class TargetTag, class HEAD, class TAIL>
+struct FindNextTag<TargetTag, TypeList<HEAD, TAIL> >
+{
+    typedef typename FindNextTag<TargetTag, TAIL>::type type;
+};
+
+template <class TargetTag, class TAIL>
+struct FindNextTag<TargetTag, TypeList<TargetTag, TAIL> >
+{
+    typedef typename TAIL::Head type;
+};
+
+template <class TargetTag>
+struct FindNextTag<TargetTag, TypeList<TargetTag, void> >
+{
+    typedef void type;
+};
+
+template <class TargetTag>
+struct FindNextTag<TargetTag, void>
+{
+    typedef void type;
+};
+
+    // AccumulatorFactory creates the decorator hierarchy for the given TAG and configuration CONFIG
+template <class TAG, class CONFIG, unsigned LEVEL=0>
+struct AccumulatorFactory
+{
+    typedef typename FindNextTag<TAG, typename CONFIG::TagList>::type NextTag;
+    typedef typename AccumulatorFactory<NextTag, CONFIG, LEVEL+1>::type NextType;
+    typedef typename CONFIG::InputType InputType;
+    
+    template <class T>
+    struct ConfigureTag
+    {
+        typedef TAG type;
+    };
+    
+        // When InputType is a CoupledHandle, some tags need to be wrapped into 
+        // DataFromHandle<> and/or Weighted<> modifiers. The following code does
+        // this when appropriate.
+    template <class T, class NEXT>
+    struct ConfigureTag<CoupledHandle<T, NEXT> >
+    {
+        typedef typename StandardizeTag<DataFromHandle<TAG> >::type WrappedTag;
+        typedef typename IfBool<(!HasModifierPriority<WrappedTag, WeightingPriority>::value && ShouldBeWeighted<WrappedTag>::value),
+                                 Weighted<WrappedTag>, WrappedTag>::type type;
+    };
+    
+    typedef typename ConfigureTag<InputType>::type UseTag;
+    
+        // base class of the decorator hierarchy: default (possibly empty) 
+        // implementations of all members
+    struct AccumulatorBase
+    {
+        typedef AccumulatorBase              ThisType;
+        typedef TAG                          Tag;
+        typedef NextType                     InternalBaseType;
+        typedef InputType                    input_type;
+        typedef input_type const &           argument_type;
+        typedef argument_type                first_argument_type;
+        typedef double                       second_argument_type;
+        typedef void                         result_type;
+        
+        static const unsigned int            workInPass = 1;
+        static const int                     index = InternalBaseType::index + 1;
+        
+        InternalBaseType next_;
+        
+        static std::string name()
+        {
+            return TAG::name();
+        }
+        
+        template <class ActiveFlags>
+        static void activateImpl(ActiveFlags & flags)
+        {
+            flags.template set<index>();
+            typedef typename StandardizeDependencies<Tag>::type StdDeps;
+            acc_detail::ActivateDependencies<StdDeps>::template exec<ThisType>(flags);
+        }
+        
+        template <class Accu, class ActiveFlags, class GlobalFlags>
+        static void activateImpl(ActiveFlags & flags, GlobalFlags & gflags)
+        {
+            flags.template set<index>();
+            typedef typename StandardizeDependencies<Tag>::type StdDeps;
+            acc_detail::ActivateDependencies<StdDeps>::template exec<Accu>(flags, gflags);
+        }
+        
+        template <class ActiveFlags>
+        static bool isActiveImpl(ActiveFlags & flags)
+        {
+            return flags.template test<index>();
+        }
+        
+        void setDirty() const
+        {
+            next_.template setDirtyImpl<index>();
+        }
+        
+        template <int INDEX>
+        void setDirtyImpl() const
+        {
+            next_.template setDirtyImpl<INDEX>();
+        }
+        
+        void setClean() const
+        {
+            next_.template setCleanImpl<index>();
+        }
+        
+        template <int INDEX>
+        void setCleanImpl() const
+        {
+            next_.template setCleanImpl<INDEX>();
+        }
+        
+        bool isDirty() const
+        {
+            return next_.template isDirtyImpl<index>();
+        }
+        
+        template <int INDEX>
+        bool isDirtyImpl() const
+        {
+            return next_.template isDirtyImpl<INDEX>();
+        }
+        
+        void reset()
+        {}
+        
+        template <class Shape>
+        void setCoordinateOffset(Shape const &)
+        {}
+        
+        template <class Shape>
+        void reshape(Shape const &)
+        {}
+        
+        void operator+=(AccumulatorBase const &)
+        {}
+        
+        template <class U>
+        void update(U const &)
+        {}
+        
+        template <class U>
+        void update(U const &, double)
+        {}
+        
+        template <class TargetTag>
+        typename LookupDependency<TargetTag, ThisType>::result_type
+        call_getDependency() const
+        {
+            return getDependency<TargetTag>(*this);
+        }
+    };
+
+        // The middle class(es) of the decorator hierarchy implement the actual feature computation.
+    typedef typename UseTag::template Impl<InputType, AccumulatorBase> AccumulatorImpl;
+    
+        // outer class of the decorator hierarchy. It has the following functionalities
+        //  * ensure that only active accumulators are called in a dynamic accumulator chain
+        //  * ensure that each accumulator is only called in its desired pass as defined in A::workInPass
+        //  * determine how many passes through the data are required
+    struct Accumulator
+    : public AccumulatorImpl
+    {
+        typedef Accumulator type;
+        typedef Accumulator & reference;
+        typedef Accumulator const & const_reference;
+        typedef AccumulatorImpl A;
+        
+        static const unsigned int workInPass = A::workInPass;
+        static const bool allowRuntimeActivation = CONFIG::allowRuntimeActivation;
+        
+        template <class T>
+        void resize(T const & t)
+        {
+            this->next_.resize(t);
+            DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::resize(*this, t);
+        }
+        
+        void reset()
+        {
+            this->next_.reset();
+            A::reset();
+        }
+        
+        typename A::result_type get() const
+        {
+            return DecoratorImpl<A, workInPass, allowRuntimeActivation>::get(*this);
+        }
+        
+        template <unsigned N, class T>
+        void pass(T const & t)
+        {
+            this->next_.template pass<N>(t);
+            DecoratorImpl<Accumulator, N, allowRuntimeActivation>::exec(*this, t);
+        }
+        
+        template <unsigned N, class T>
+        void pass(T const & t, double weight)
+        {
+            this->next_.template pass<N>(t, weight);
+            DecoratorImpl<Accumulator, N, allowRuntimeActivation>::exec(*this, t, weight);
+        }
+        
+        void mergeImpl(Accumulator const & o)
+        {
+            DecoratorImpl<Accumulator, Accumulator::workInPass, allowRuntimeActivation>::mergeImpl(*this, o);
+            this->next_.mergeImpl(o.next_);
+        }
+        
+        void applyHistogramOptions(HistogramOptions const & options)
+        {
+            DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::applyHistogramOptions(*this, options);
+            this->next_.applyHistogramOptions(options);
+        }
+        
+        template <class SHAPE>
+        void setCoordinateOffsetImpl(SHAPE const & offset)
+        {
+            this->setCoordinateOffset(offset);
+            this->next_.setCoordinateOffsetImpl(offset);
+        }
+        
+        static unsigned int passesRequired()
+        {
+            return DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::passesRequired();
+        }
+        
+        template <class ActiveFlags>
+        static unsigned int passesRequired(ActiveFlags const & flags)
+        {
+            return DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::passesRequired(flags);
+        }
+    };
+
+    typedef Accumulator type;
+};
+
+template <class CONFIG, unsigned LEVEL>
+struct AccumulatorFactory<void, CONFIG, LEVEL>
+{
+    typedef AccumulatorEndImpl<LEVEL, typename CONFIG::GlobalAccumulatorHandle> type;
+};
+
+struct InvalidGlobalAccumulatorHandle
+{
+    typedef Error__Global_statistics_are_only_defined_for_AccumulatorChainArray type;
+    
+    InvalidGlobalAccumulatorHandle()
+    : pointer_(0)
+    {}
+    
+    type const * pointer_;
+};
+
+    // helper classes to create an accumulator chain from a TypeList
+    // if dynamic=true,  a dynamic accumulator will be created
+    // if dynamic=false, a plain accumulator will be created
+template <class T, class Selected, bool dynamic=false, class GlobalHandle=InvalidGlobalAccumulatorHandle>
+struct ConfigureAccumulatorChain
+#ifndef DOXYGEN
+: public ConfigureAccumulatorChain<T, typename AddDependencies<typename Selected::type>::type, dynamic>
+#endif
+{};
+
+template <class T, class HEAD, class TAIL, bool dynamic, class GlobalHandle>
+struct ConfigureAccumulatorChain<T, TypeList<HEAD, TAIL>, dynamic, GlobalHandle>
+{
+    typedef TypeList<HEAD, TAIL> TagList;
+    typedef T InputType;
+    static const bool allowRuntimeActivation = dynamic;
+    typedef GlobalHandle GlobalAccumulatorHandle;
+ 
+    typedef typename AccumulatorFactory<HEAD, ConfigureAccumulatorChain>::type type;
+};
+
+template <class T, class Selected, bool dynamic=false>
+struct ConfigureAccumulatorChainArray
+#ifndef DOXYGEN
+: public ConfigureAccumulatorChainArray<T, typename AddDependencies<typename Selected::type>::type, dynamic>
+#endif
+{};
+
+template <class T, class HEAD, class TAIL, bool dynamic>
+struct ConfigureAccumulatorChainArray<T, TypeList<HEAD, TAIL>, dynamic>
+{
+    typedef TypeList<HEAD, TAIL> TagList;
+    typedef SeparateGlobalAndRegionTags<TagList> TagSeparator;
+    typedef typename TagSeparator::GlobalTags GlobalTags;
+    typedef typename TagSeparator::RegionTags RegionTags;
+    typedef typename ConfigureAccumulatorChain<T, GlobalTags, dynamic>::type GlobalAccumulatorChain;
+
+    struct GlobalAccumulatorHandle
+    {
+        typedef GlobalAccumulatorChain type;
+        
+        GlobalAccumulatorHandle()
+        : pointer_(0)
+        {}
+        
+        type const * pointer_;
+    };
+    
+    typedef typename ConfigureAccumulatorChain<T, RegionTags, dynamic, GlobalAccumulatorHandle>::type RegionAccumulatorChain;
+    
+    typedef LabelDispatch<T, GlobalAccumulatorChain, RegionAccumulatorChain> type;
+};
+
+} // namespace acc_detail 
+
+/****************************************************************************/
+/*                                                                          */
+/*                            accumulator chain                             */
+/*                                                                          */
+/****************************************************************************/
+
+// Implement the high-level interface of an accumulator chain
+template <class T, class NEXT>
+class AccumulatorChainImpl
+{
+  public:
+    typedef NEXT                                             InternalBaseType;
+    typedef AccumulatorBegin                                 Tag;
+    typedef typename InternalBaseType::argument_type         argument_type;
+    typedef typename InternalBaseType::first_argument_type   first_argument_type;
+    typedef typename InternalBaseType::second_argument_type  second_argument_type;
+    typedef void                                             value_type;
+    typedef typename InternalBaseType::result_type           result_type;
+    
+    static const int staticSize = InternalBaseType::index;
+
+    InternalBaseType next_;
+
+    /** \brief Current pass of the accumulator chain.
+    */
+    unsigned int current_pass_;
+    
+    AccumulatorChainImpl()
+    : current_pass_(0)
+    {}
+
+    /** Set options for all histograms in the accumulator chain. See histogram accumulators for possible options. The function is ignored if there is no histogram in the accumulator chain.
+    */
+    void setHistogramOptions(HistogramOptions const & options)
+    {
+        next_.applyHistogramOptions(options);
+    }
+    
+
+    /** Set regional and global options for all histograms in the accumulator chain.
+    */
+    void setHistogramOptions(HistogramOptions const & regionoptions, HistogramOptions const & globaloptions)
+    {
+        next_.applyHistogramOptions(regionoptions, globaloptions);
+    }
+    
+    /** Set an offset for <tt>Coord<...></tt> statistics.
+    
+        If the offset is non-zero, coordinate statistics such as <tt>RegionCenter</tt> are computed
+        in the global coordinate system defined by the \a offset. Without an offset, these statistics
+        are computed in the local coordinate system of the current region of interest.
+    */    
+    template <class SHAPE>
+    void setCoordinateOffset(SHAPE const & offset)
+    {
+        next_.setCoordinateOffsetImpl(offset);
+    }
+    
+    /** Reset current_pass_ of the accumulator chain to 'reset_to_pass'.
+    */
+    void reset(unsigned int reset_to_pass = 0)
+    {
+        current_pass_ = reset_to_pass;
+        if(reset_to_pass == 0)
+            next_.reset();
+    }
+    
+    template <unsigned N>
+    void update(T const & t)
+    {
+        if(current_pass_ == N)
+        {
+            next_.template pass<N>(t);
+        }
+        else if(current_pass_ < N)
+        {
+            current_pass_ = N;
+            if(N == 1)
+                next_.resize(acc_detail::shapeOf(t));
+            next_.template pass<N>(t);
+        }
+        else
+        {
+            std::string message("AccumulatorChain::update(): cannot return to pass ");
+            message << N << " after working on pass " << current_pass_ << ".";
+            vigra_precondition(false, message);
+        }
+    }
+    
+    template <unsigned N>
+    void update(T const & t, double weight)
+    {
+        if(current_pass_ == N)
+        {
+            next_.template pass<N>(t, weight);
+        }
+        else if(current_pass_ < N)
+        {
+            current_pass_ = N;
+            if(N == 1)
+                next_.resize(acc_detail::shapeOf(t));
+            next_.template pass<N>(t, weight);
+        }
+        else
+        {
+            std::string message("AccumulatorChain::update(): cannot return to pass ");
+            message << N << " after working on pass " << current_pass_ << ".";
+            vigra_precondition(false, message);
+       }
+    }
+    
+    /** Equivalent to merge(o) .
+    */
+    void operator+=(AccumulatorChainImpl const & o)
+    {
+        merge(o);
+    }
+    
+    /** Merge the accumulator chain with accumulator chain 'o'. This only works if all selected statistics in the accumulator chain support the '+=' operator. See the documentations of the particular statistics for support information.
+    */
+    void merge(AccumulatorChainImpl const & o)
+    {
+        next_.mergeImpl(o.next_);
+    }
+
+    result_type operator()() const
+    {
+        return next_.get();
+    }
+
+    void operator()(T const & t)
+    {
+        update<1>(t);
+    }
+    
+    void operator()(T const & t, double weight)
+    {
+        update<1>(t, weight);
+    }
+
+    void updatePass2(T const & t)
+    {
+        update<2>(t);
+    }
+    
+    void updatePass2(T const & t, double weight)
+    {
+        update<2>(t, weight);
+    }
+
+    /** Upate all accumulators in the accumulator chain that work in pass N with data t. Requirement: 0 < N < 6 and N >= current_pass_ . If N < current_pass_ call reset() first.  
+    */
+    void updatePassN(T const & t, unsigned int N)
+    {
+        switch (N)
+        {
+            case 1: update<1>(t); break;
+            case 2: update<2>(t); break;
+            case 3: update<3>(t); break;
+            case 4: update<4>(t); break;
+            case 5: update<5>(t); break;
+            default:
+                vigra_precondition(false,
+                     "AccumulatorChain::updatePassN(): 0 < N < 6 required.");
+        }
+    }
+    
+    /** Upate all accumulators in the accumulator chain that work in pass N with data t and weight. Requirement: 0 < N < 6 and N >= current_pass_ . If N < current_pass_ call reset() first. 
+    */
+    void updatePassN(T const & t, double weight, unsigned int N)
+    {
+        switch (N)
+        {
+            case 1: update<1>(t, weight); break;
+            case 2: update<2>(t, weight); break;
+            case 3: update<3>(t, weight); break;
+            case 4: update<4>(t, weight); break;
+            case 5: update<5>(t, weight); break;
+            default:
+                vigra_precondition(false,
+                     "AccumulatorChain::updatePassN(): 0 < N < 6 required.");
+        }
+    }
+  
+    /** Return the number of passes required to compute all statistics in the accumulator chain.
+    */
+    unsigned int passesRequired() const
+    {
+        return InternalBaseType::passesRequired();
+    }
+};
+
+
+
+   // Create an accumulator chain containing the Selected statistics and their dependencies.
+
+/** \brief Create an accumulator chain containing the selected statistics and their dependencies.
+
+    AccumulatorChain is used to compute global statistics which have to be selected at compile time. 
+
+    The template parameters are as follows:
+    - T: The input type
+        - either element type of the data(e.g. double, int, RGBValue, ...)
+        - or type of CoupledHandle (for simultaneous access to coordinates and/or weights)
+    - Selected: statistics to be computed and index specifier for the CoupledHandle, wrapped with Select
+    
+    Usage:
+    \code
+    typedef double DataType;
+    AccumulatorChain<DataType, Select<Variance, Mean, Minimum, ...> > accumulator;
+    \endcode
+
+    Usage, using CoupledHandle:
+    \code
+    const int dim = 3; //dimension of MultiArray
+    typedef double DataType;
+    typedef double WeightType;
+    typedef vigra::CoupledIteratorType<dim, DataType, WeightType>::HandleType Handle;
+    AccumulatorChain<Handle, Select<DataArg<1>, WeightArg<2>, Mean,...> > a;
+    \endcode
+
+    See \ref FeatureAccumulators for more information and examples of use.
+ */
+template <class T, class Selected, bool dynamic=false>
+class AccumulatorChain
+#ifndef DOXYGEN // hide AccumulatorChainImpl from documentation
+: public AccumulatorChainImpl<T, typename acc_detail::ConfigureAccumulatorChain<T, Selected, dynamic>::type>
+#endif
+{
+  public:
+  // \brief TypeList of Tags in the accumulator chain (?).
+    typedef typename acc_detail::ConfigureAccumulatorChain<T, Selected, dynamic>::TagList AccumulatorTags;
+  
+    /** Before having seen data (current_pass_==0), the shape of the data can be changed... (?)
+    */
+    template <class U, int N>
+    void reshape(TinyVector<U, N> const & s)
+    {
+        vigra_precondition(this->current_pass_ == 0,
+             "AccumulatorChain::reshape(): cannot reshape after seeing data. Call AccumulatorChain::reset() first.");
+        this->next_.resize(s);
+        this->current_pass_ = 1;
+    }
+     
+    /** Return the names of all tags in the accumulator chain (selected statistics and their dependencies).
+    */
+    static ArrayVector<std::string> const & tagNames()
+    {
+        static ArrayVector<std::string> * n = VIGRA_SAFE_STATIC(n, new ArrayVector<std::string>(collectTagNames()));
+        return *n;
+    }
+
+
+#ifdef DOXYGEN // hide AccumulatorChainImpl from documentation
+  
+  /** Set options for all histograms in the accumulator chain. See histogram accumulators for possible options. The function is ignored if there is no histogram in the accumulator chain.
+   */
+  void setHistogramOptions(HistogramOptions const & options);
+    
+  /** Set an offset for <tt>Coord<...></tt> statistics.
+  
+      If the offset is non-zero, coordinate statistics such as <tt>RegionCenter</tt> are computed
+      in the global coordinate system defined by the \a offset. Without an offset, these statistics
+      are computed in the local coordinate system of the current region of interest.
+  */    
+  template <class SHAPE>
+  void setCoordinateOffset(SHAPE const & offset);
+    
+  /** Reset current_pass_ of the accumulator chain to 'reset_to_pass'. */
+  void reset(unsigned int reset_to_pass = 0);
+
+  /** Equivalent to merge(o) . */
+  void operator+=(AccumulatorChainImpl const & o);
+  
+  /** Merge the accumulator chain with accumulator chain 'o'. This only works if all selected statistics in the accumulator chain support the '+=' operator. See the documentations of the particular statistics for support information.
+   */
+  void merge(AccumulatorChainImpl const & o);
+  
+  /** Upate all accumulators in the accumulator chain that work in pass N with data t. Requirement: 0 < N < 6 and N >= current_pass_ . If N < current_pass_ call reset first.  
+   */
+  void updatePassN(T const & t, unsigned int N);
+  
+  /** Upate all accumulators in the accumulator chain that work in pass N with data t and weight. Requirement: 0 < N < 6 and N >= current_pass_ . If N < current_pass_ call reset first. 
+   */
+  void updatePassN(T const & t, double weight, unsigned int N);
+  
+  /** Return the number of passes required to compute all statistics in the accumulator chain.
+   */
+  unsigned int passesRequired() const;
+  
+#endif   
+ 
+  private:
+    static ArrayVector<std::string> collectTagNames()
+    {
+        ArrayVector<std::string> n;
+        acc_detail::CollectAccumulatorNames<AccumulatorTags>::exec(n);
+        std::sort(n.begin(), n.end());
+        return n;
+    }
+}; 
+
+template <unsigned int N, class T1, class T2, class T3, class T4, class T5, class Selected, bool dynamic>
+class AccumulatorChain<CoupledArrays<N, T1, T2, T3, T4, T5>, Selected, dynamic>
+: public AccumulatorChain<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected, dynamic>
+{};
+
+
+    // Create a dynamic accumulator chain containing the Selected statistics and their dependencies.
+    // Statistics will only be computed if activate<Tag>() is called at runtime.
+/** \brief Create a dynamic accumulator chain containing the selected statistics and their dependencies.
+
+    DynamicAccumulatorChain is used to compute global statistics with run-time activation. A set of statistics is selected at run-time and from this set statistics can be activated at run-time by calling activate<stat>() or activate(std::string stat).
+
+    The template parameters are as follows:
+    - T: The input type
+        - either element type of the data(e.g. double, int, RGBValue, ...)
+        - or type of CoupledHandle (for access to coordinates and/or weights)
+    - Selected: statistics to be computed and index specifier for the CoupledHandle, wrapped with Select
+    
+    Usage:
+    \code
+    typedef double DataType;
+    DynamicAccumulatorChain<DataType, Select<Variance, Mean, Minimum, ...> > accumulator;
+    \endcode
+
+    Usage, using CoupledHandle:
+    \code
+    const int dim = 3; //dimension of MultiArray
+    typedef double DataType;
+    typedef double WeightType;
+    typedef vigra::CoupledIteratorType<dim, DataType, WeightType>::HandleType Handle;
+    DynamicAccumulatorChain<Handle, Select<DataArg<1>, WeightArg<2>, Mean,...> > a;
+    \endcode
+
+    See \ref FeatureAccumulators for more information and examples of use.
+ */
+template <class T, class Selected>
+class DynamicAccumulatorChain
+: public AccumulatorChain<T, Selected, true>
+{
+  public:
+    typedef typename AccumulatorChain<T, Selected, true>::InternalBaseType InternalBaseType;
+    typedef typename DynamicAccumulatorChain::AccumulatorTags AccumulatorTags;
+       
+    /** Activate statistic 'tag'. Alias names are not recognized. If the statistic is not in the accumulator chain a PreconditionViolation is thrown.
+    */
+    void activate(std::string tag)
+    {
+        vigra_precondition(activateImpl(tag),
+            std::string("DynamicAccumulatorChain::activate(): Tag '") + tag + "' not found.");
+    }
+    
+    /** %activate\<TAG\>() activates statistic 'TAG'. If the statistic is not in the accumulator chain it is ignored. (?)
+    */
+    template <class TAG>
+    void activate()
+    {
+        LookupTag<TAG, DynamicAccumulatorChain>::type::activateImpl(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
+    }
+    
+    /** Activate all statistics in the accumulator chain.
+    */
+    void activateAll()
+    {
+        getAccumulator<AccumulatorEnd>(*this).active_accumulators_.set();
+    }
+    /** Return true if the statistic 'tag' is active, i.e. activate(std::string tag) or activate<TAG>() has been called. If the statistic is not in the accumulator chain a PreconditionViolation is thrown. (Note that alias names are not recognized.)
+    */
+    bool isActive(std::string tag) const
+    {
+        acc_detail::TagIsActive_Visitor v;
+        vigra_precondition(isActiveImpl(tag, v),
+            std::string("DynamicAccumulatorChain::isActive(): Tag '") + tag + "' not found.");
+        return v.result;
+    }
+    
+    /** %isActive\<TAG\>() returns true if statistic 'TAG' is active, i.e. activate(std::string tag) or activate<TAG>() has been called. If the statistic is not in the accumulator chain, true is returned. (?)
+    */
+    template <class TAG>
+    bool isActive() const
+    {
+        return LookupTag<TAG, DynamicAccumulatorChain>::type::isActiveImpl(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
+    }
+
+    /** Return names of all statistics in the accumulator chain that are active.
+    */
+    ArrayVector<std::string> activeNames() const
+    {
+        ArrayVector<std::string> res;
+        for(unsigned k=0; k<DynamicAccumulatorChain::tagNames().size(); ++k)
+            if(isActive(DynamicAccumulatorChain::tagNames()[k]))
+                res.push_back(DynamicAccumulatorChain::tagNames()[k]);
+        return res;
+    }
+    
+    /** Return number of passes required to compute the active statistics in the accumulator chain.
+    */
+    unsigned int passesRequired() const
+    {
+        return InternalBaseType::passesRequired(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
+    }
+    
+  protected:
+  
+    bool activateImpl(std::string tag)
+    {
+        return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(*this, 
+                                         normalizeString(tag), acc_detail::ActivateTag_Visitor());
+    }
+    
+    bool isActiveImpl(std::string tag, acc_detail::TagIsActive_Visitor & v) const
+    {
+        return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(*this, normalizeString(tag), v);
+    }
+};
+
+template <unsigned int N, class T1, class T2, class T3, class T4, class T5, class Selected>
+class DynamicAccumulatorChain<CoupledArrays<N, T1, T2, T3, T4, T5>, Selected>
+: public DynamicAccumulatorChain<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected>
+{};
+
+
+
+/** \brief Create an array of accumulator chains containing the selected per-region and global statistics and their dependencies.
+
+    AccumulatorChainArray is used to compute per-region statistics (as well as global statistics). The statistics are selected at compile-time. An array of accumulator chains (one per region) for region statistics is created and one accumulator chain for global statistics. The region labels always start at 0. Use the Global modifier to compute global statistics (by default per-region statistics are computed). 
+
+    The template parameters are as follows:
+    - T: The input type, type of CoupledHandle (for access to coordinates, labels and weights)
+    - Selected: statistics to be computed and index specifier for the CoupledHandle, wrapped with Select
+
+    Usage:
+    \code
+    const int dim = 3; //dimension of MultiArray
+    typedef double DataType;
+    typedef double WeightType;
+    typedef unsigned int LabelType;
+    typedef vigra::CoupledIteratorType<dim, DataType, WeightType, LabelType>::HandleType Handle;
+    AccumulatorChainArray<Handle, Select<DataArg<1>, WeightArg<2>, LabelArg<3>, Mean, Variance, ...> > a;
+    \endcode
+
+    See \ref FeatureAccumulators for more information and examples of use.
+*/
+template <class T, class Selected, bool dynamic=false>
+class AccumulatorChainArray
+#ifndef DOXYGEN //hide AccumulatorChainImpl vom documentation
+: public AccumulatorChainImpl<T, typename acc_detail::ConfigureAccumulatorChainArray<T, Selected, dynamic>::type>
+#endif
+{
+  public:
+    typedef typename acc_detail::ConfigureAccumulatorChainArray<T, Selected, dynamic> Creator;
+    typedef typename Creator::TagList AccumulatorTags;
+    typedef typename Creator::GlobalTags GlobalTags;
+    typedef typename Creator::RegionTags RegionTags;
+    
+    /** Statistics will not be computed for label l. Note that only one label can be ignored.
+    */
+    void ignoreLabel(MultiArrayIndex l)
+    {
+        this->next_.ignoreLabel(l);
+    }
+    
+    /** Set the maximum region label (e.g. for merging two accumulator chains).
+    */
+    void setMaxRegionLabel(unsigned label)
+    {
+        this->next_.setMaxRegionLabel(label);
+    }
+    
+    /** %Maximum region label. (equal to regionCount() - 1)
+    */
+    MultiArrayIndex maxRegionLabel() const
+    {
+        return this->next_.maxRegionLabel();
+    }
+    
+    /** Number of Regions. (equal to maxRegionLabel() + 1)
+    */
+    unsigned int regionCount() const
+    {
+        return this->next_.regions_.size();
+    }
+    
+    /** Equivalent to <tt>merge(o)</tt>.
+    */
+    void operator+=(AccumulatorChainArray const & o)
+    {
+        merge(o);
+    }
+    
+    /** Merge region i with region j. 
+    */
+    void merge(unsigned i, unsigned j)
+    {
+        vigra_precondition(i <= maxRegionLabel() && j <= maxRegionLabel(),
+            "AccumulatorChainArray::merge(): region labels out of range.");
+        this->next_.mergeImpl(i, j);
+    }
+    
+    /** Merge with accumulator chain o. maxRegionLabel() of the two accumulators must be equal.
+    */
+    void merge(AccumulatorChainArray const & o)
+    {
+        if(maxRegionLabel() == -1)
+            setMaxRegionLabel(o.maxRegionLabel());
+        vigra_precondition(maxRegionLabel() == o.maxRegionLabel(),
+            "AccumulatorChainArray::merge(): maxRegionLabel must be equal.");
+        this->next_.mergeImpl(o.next_);
+    }
+
+    /** Merge with accumulator chain o using a mapping between labels of the two accumulators. Label l of accumulator chain o is mapped to labelMapping[l]. Hence, all elements of labelMapping must be <= maxRegionLabel() and size of labelMapping must match o.regionCount().
+    */
+    template <class ArrayLike>
+    void merge(AccumulatorChainArray const & o, ArrayLike const & labelMapping)
+    {
+        vigra_precondition(labelMapping.size() == o.regionCount(),
+            "AccumulatorChainArray::merge(): labelMapping.size() must match regionCount() of RHS.");
+        this->next_.mergeImpl(o.next_, labelMapping);
+    }
+
+    /** Return names of all tags in the accumulator chain (selected statistics and their dependencies).
+    */
+    static ArrayVector<std::string> const & tagNames()
+    {
+        static const ArrayVector<std::string> n = collectTagNames();
+        return n;
+    }
+
+
+#ifdef DOXYGEN // hide AccumulatorChainImpl from documentation
+
+  /** \copydoc vigra::acc::AccumulatorChain::setHistogramOptions(HistogramOptions const &) */
+  void setHistogramOptions(HistogramOptions const & options);
+
+  /** Set regional and global options for all histograms in the accumulator chain.
+   */
+  void setHistogramOptions(HistogramOptions const & regionoptions, HistogramOptions const & globaloptions);
+    
+  /** \copydoc vigra::acc::AccumulatorChain::setCoordinateOffset(SHAPE const &)
+  */    
+  template <class SHAPE>
+  void setCoordinateOffset(SHAPE const & offset)
+  
+  /** \copydoc vigra::acc::AccumulatorChain::reset() */
+  void reset(unsigned int reset_to_pass = 0);
+
+  /** \copydoc vigra::acc::AccumulatorChain::operator+=() */
+  void operator+=(AccumulatorChainImpl const & o);
+    
+  /** \copydoc vigra::acc::AccumulatorChain::updatePassN(T const &,unsigned int) */
+  void updatePassN(T const & t, unsigned int N);
+  
+  /** \copydoc vigra::acc::AccumulatorChain::updatePassN(T const &,double,unsigned int) */
+  void updatePassN(T const & t, double weight, unsigned int N);
+  
+#endif
+    
+  private:
+    static ArrayVector<std::string> collectTagNames()
+    {
+        ArrayVector<std::string> n;
+        acc_detail::CollectAccumulatorNames<AccumulatorTags>::exec(n);
+        std::sort(n.begin(), n.end());
+        return n;
+    }
+};
+
+template <unsigned int N, class T1, class T2, class T3, class T4, class T5, class Selected, bool dynamic>
+class AccumulatorChainArray<CoupledArrays<N, T1, T2, T3, T4, T5>, Selected, dynamic>
+: public AccumulatorChainArray<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected, dynamic>
+{};
+
+/** \brief Create an array of dynamic accumulator chains containing the selected per-region and global statistics and their dependencies.
+
+
+    DynamicAccumulatorChainArray is used to compute per-region statistics (as well as global statistics) with run-time activation. A set of statistics is selected at run-time and from this set statistics can be activated at run-time by calling activate<stat>() or activate(std::string stat).
+
+     The template parameters are as follows:
+    - T: The input type, type of CoupledHandle (for access to coordinates, labels and weights)
+    - Selected: statistics to be computed and index specifier for the CoupledHandle, wrapped with Select
+
+    Usage:
+    \code
+    const int dim = 3; //dimension of MultiArray
+    typedef double DataType;
+    typedef double WeightType;
+    typedef unsigned int LabelType;
+    typedef vigra::CoupledIteratorType<dim, DataType, WeightType, LabelType>::HandleType Handle;
+    DynamicAccumulatorChainArray<Handle, Select<DataArg<1>, WeightArg<2>, LabelArg<3>, Mean, Variance, ...> > a;
+    \endcode
+
+    See \ref FeatureAccumulators for more information and examples of use.
+*/
+template <class T, class Selected>
+class DynamicAccumulatorChainArray
+: public AccumulatorChainArray<T, Selected, true>
+{
+  public:
+    typedef typename DynamicAccumulatorChainArray::AccumulatorTags AccumulatorTags;
+
+    /** \copydoc DynamicAccumulatorChain::activate(std::string tag) */
+    void activate(std::string tag)
+    {
+        vigra_precondition(activateImpl(tag),
+            std::string("DynamicAccumulatorChainArray::activate(): Tag '") + tag + "' not found.");
+    }
+    
+    /** \copydoc DynamicAccumulatorChain::activate() */
+    template <class TAG>
+    void activate()
+    {
+        this->next_.template activate<TAG>();
+    }
+    
+    /** \copydoc DynamicAccumulatorChain::activateAll() */
+    void activateAll()
+    {
+        this->next_.activateAll();
+    }
+    
+    /** Return true if the statistic 'tag' is active, i.e. activate(std::string tag) or activate<TAG>() has been called. If the statistic is not in the accumulator chain a PreconditionViolation is thrown. (Note that alias names are not recognized.)
+     */
+    bool isActive(std::string tag) const
+    {
+        acc_detail::TagIsActive_Visitor v;
+        vigra_precondition(isActiveImpl(tag, v),
+            std::string("DynamicAccumulatorChainArray::isActive(): Tag '") + tag + "' not found.");
+        return v.result;
+    }
+    
+    /** %isActive\<TAG\>() returns true if statistic 'TAG' is active, i.e. activate(std::string tag) or activate<TAG>() has been called. If the statistic is not in the accumulator chain, true is returned. (?)
+     */
+    template <class TAG>
+    bool isActive() const
+    {
+        return this->next_.template isActive<TAG>();
+    }
+    
+    /** \copydoc DynamicAccumulatorChain::activeNames() */
+    ArrayVector<std::string> activeNames() const
+    {
+        ArrayVector<std::string> res;
+        for(unsigned k=0; k<DynamicAccumulatorChainArray::tagNames().size(); ++k)
+            if(isActive(DynamicAccumulatorChainArray::tagNames()[k]))
+                res.push_back(DynamicAccumulatorChainArray::tagNames()[k]);
+        return res;
+    }
+    
+    /** \copydoc DynamicAccumulatorChain::passesRequired() */
+    unsigned int passesRequired() const
+    {
+        return this->next_.passesRequiredDynamic();
+    }
+
+  protected:
+  
+    bool activateImpl(std::string tag)
+    {
+        return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(this->next_, 
+                                         normalizeString(tag), acc_detail::ActivateTag_Visitor());
+    }
+    
+    bool isActiveImpl(std::string tag, acc_detail::TagIsActive_Visitor & v) const
+    {
+        return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(this->next_, normalizeString(tag), v);
+    }
+};
+
+template <unsigned int N, class T1, class T2, class T3, class T4, class T5, class Selected>
+class DynamicAccumulatorChainArray<CoupledArrays<N, T1, T2, T3, T4, T5>, Selected>
+: public DynamicAccumulatorChainArray<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected>
+{};
+
+/****************************************************************************/
+/*                                                                          */
+/*                        generic access functions                          */
+/*                                                                          */
+/****************************************************************************/
+
+template <class TAG>
+struct Error__Attempt_to_access_inactive_statistic;
+
+namespace acc_detail {
+
+    // accumulator lookup rules: find the accumulator that implements TAG
+    
+    // When A does not implement TAG, continue search in A::InternalBaseType.
+template <class TAG, class A, class FromTag=typename A::Tag>
+struct LookupTagImpl
+#ifndef DOXYGEN
+: public LookupTagImpl<TAG, typename A::InternalBaseType>
+#endif
+{};
+
+    // 'const A' is treated like A, except that the reference member is now const.
+template <class TAG, class A, class FromTag>
+struct LookupTagImpl<TAG, A const, FromTag>
+: public LookupTagImpl<TAG, A>
+{
+    typedef typename LookupTagImpl<TAG, A>::type const & reference;
+    typedef typename LookupTagImpl<TAG, A>::type const * pointer;
+};
+
+    // When A implements TAG, report its type and associated information.
+template <class TAG, class A>
+struct LookupTagImpl<TAG, A, TAG>
+{
+    typedef TAG Tag;
+    typedef A type;
+    typedef A & reference;
+    typedef A * pointer;
+    typedef typename A::value_type value_type;
+    typedef typename A::result_type result_type;
+};
+
+    // Again, 'const A' is treated like A, except that the reference member is now const.
+template <class TAG, class A>
+struct LookupTagImpl<TAG, A const, TAG>
+: public LookupTagImpl<TAG, A, TAG>
+{
+    typedef typename LookupTagImpl<TAG, A, TAG>::type const & reference;
+    typedef typename LookupTagImpl<TAG, A, TAG>::type const * pointer;
+};
+
+    // Recursion termination: when we end up in AccumulatorEnd without finding a 
+    // suitable A, we stop and report an error
+template <class TAG, class A>
+struct LookupTagImpl<TAG, A, AccumulatorEnd>
+{
+    typedef TAG Tag;
+    typedef A type;
+    typedef A & reference;
+    typedef A * pointer;
+    typedef Error__Attempt_to_access_inactive_statistic<TAG> value_type;
+    typedef Error__Attempt_to_access_inactive_statistic<TAG> result_type;
+};
+
+    // ... except when we are actually looking for AccumulatorEnd
+template <class A>
+struct LookupTagImpl<AccumulatorEnd, A, AccumulatorEnd>
+{
+    typedef AccumulatorEnd Tag;
+    typedef A type;
+    typedef A & reference;
+    typedef A * pointer;
+    typedef void value_type;
+    typedef void result_type;
+};
+
+    // ... or we are looking for a global statistic, in which case
+    // we continue the serach via A::GlobalAccumulatorType, but remember that 
+    // we are actually looking for a global tag. 
+template <class TAG, class A>
+struct LookupTagImpl<Global<TAG>, A, AccumulatorEnd>
+: public LookupTagImpl<TAG, typename A::GlobalAccumulatorType>
+{
+    typedef Global<TAG> Tag;
+};
+
+    // When we encounter the LabelDispatch accumulator, we continue the
+    // search via LabelDispatch::RegionAccumulatorChain by default
+template <class TAG, class A>
+struct LookupTagImpl<TAG, A, LabelDispatchTag>
+: public LookupTagImpl<TAG, typename A::RegionAccumulatorChain>
+{};
+
+    // ... except when we are looking for a global statistic, in which case
+    // we continue via LabelDispatch::GlobalAccumulatorChain, but remember that 
+    // we are actually looking for a global tag.
+template <class TAG, class A>
+struct LookupTagImpl<Global<TAG>, A, LabelDispatchTag>
+: public LookupTagImpl<TAG, typename A::GlobalAccumulatorChain>
+{
+    typedef Global<TAG> Tag;
+};
+
+    // ... or we are looking for the LabelDispatch accumulator itself
+template <class A>
+struct LookupTagImpl<LabelDispatchTag, A, LabelDispatchTag>
+{
+    typedef LabelDispatchTag Tag;
+    typedef A type;
+    typedef A & reference;
+    typedef A * pointer;
+    typedef void value_type;
+    typedef void result_type;
+};
+
+} // namespace acc_detail
+
+    // Lookup the accumulator in the chain A that implements the given TAG.
+template <class Tag, class A>
+struct LookupTag
+: public acc_detail::LookupTagImpl<typename StandardizeTag<Tag>::type, A>
+{};
+
+    // Lookup the dependency TAG of the accumulator A.
+    // This template ensures that dependencies are used with matching modifiers.
+    // Specifically, if you search for Count as a dependency of Weighted<Mean>, the search
+    // actually returns Weighted<Count>, wheras Count will be returned for plain Mean.
+template <class Tag, class A, class TargetTag>
+struct LookupDependency
+: public acc_detail::LookupTagImpl<
+       typename TransferModifiers<TargetTag, typename StandardizeTag<Tag>::type>::type, A>
+{};
+ 
+
+namespace acc_detail {
+
+    // CastImpl applies the same rules as LookupTagImpl, but returns a reference to an 
+    // accumulator instance rather than an accumulator type
+template <class Tag, class FromTag, class reference>
+struct CastImpl
+{
+    template <class A>
+    static reference exec(A & a)
+    {
+        return CastImpl<Tag, typename A::InternalBaseType::Tag, reference>::exec(a.next_);
+    }
+    
+    template <class A>
+    static reference exec(A & a, MultiArrayIndex label)
+    {
+        return CastImpl<Tag, typename A::InternalBaseType::Tag, reference>::exec(a.next_, label);
+    }
+};
+
+template <class Tag, class reference>
+struct CastImpl<Tag, Tag, reference>
+{
+    template <class A>
+    static reference exec(A & a)
+    {
+        return const_cast<reference>(a);
+    }
+    
+    template <class A>
+    static reference exec(A & a, MultiArrayIndex)
+    {
+        vigra_precondition(false, 
+            "getAccumulator(): region accumulators can only be queried for AccumulatorChainArray.");
+        return a;
+    }
+};
+
+template <class Tag, class reference>
+struct CastImpl<Tag, AccumulatorEnd, reference>
+{
+    template <class A>
+    static reference exec(A & a)
+    {
+        return a;
+    }
+    
+    template <class A>
+    static reference exec(A & a, MultiArrayIndex)
+    {
+        return a;
+    }
+};
+
+template <class Tag, class reference>
+struct CastImpl<Global<Tag>, AccumulatorEnd, reference>
+{
+    template <class A>
+    static reference exec(A & a)
+    {
+        return CastImpl<Tag, typename A::GlobalAccumulatorType::Tag, reference>::exec(*a.globalAccumulator_.pointer_);
+    }
+};
+
+template <class reference>
+struct CastImpl<AccumulatorEnd, AccumulatorEnd, reference>
+{
+    template <class A>
+    static reference exec(A & a)
+    {
+        return a;
+    }
+    
+    template <class A>
+    static reference exec(A & a, MultiArrayIndex)
+    {
+        return a;
+    }
+};
+
+template <class Tag, class reference>
+struct CastImpl<Tag, LabelDispatchTag, reference>
+{
+    template <class A>
+    static reference exec(A & a)
+    {
+        vigra_precondition(false, 
+            "getAccumulator(): a region label is required when a region accumulator is queried.");
+        return CastImpl<Tag, typename A::RegionAccumulatorChain::Tag, reference>::exec(a.regions_[0]);
+    }
+    
+    template <class A>
+    static reference exec(A & a, MultiArrayIndex label)
+    {
+        return CastImpl<Tag, typename A::RegionAccumulatorChain::Tag, reference>::exec(a.regions_[label]);
+    }
+};
+
+template <class Tag, class reference>
+struct CastImpl<Global<Tag>, LabelDispatchTag, reference>
+{
+    template <class A>
+    static reference exec(A & a)
+    {
+        return CastImpl<Tag, typename A::GlobalAccumulatorChain::Tag, reference>::exec(a.next_);
+    }
+};
+
+template <class reference>
+struct CastImpl<LabelDispatchTag, LabelDispatchTag, reference>
+{
+    template <class A>
+    static reference exec(A & a)
+    {
+        return a;
+    }
+};
+
+} // namespace acc_detail
+
+    // Get a reference to the accumulator TAG in the accumulator chain A
+/** Get a reference to the accumulator 'TAG' in the accumulator chain 'a'. This can be useful for example to update a certain accumulator with data, set individual options or get information about a certain accumulator.\n
+Example of use (set options):
+\code
+    vigra::MultiArray<2, double> data(...);   
+    typedef UserRangeHistogram<40> SomeHistogram;   //binCount set at compile time
+    typedef UserRangeHistogram<0> SomeHistogram2; // binCount must be set at run-time
+    AccumulatorChain<DataType, Select<SomeHistogram, SomeHistogram2> > a;
+    
+    getAccumulator<SomeHistogram>(a).setMinMax(0.1, 0.9);
+    getAccumulator<SomeHistogram2>(a).setMinMax(0.0, 1.0);
+
+    extractFeatures(data.begin(), data.end(), a);
+\endcode
+
+Example of use (get information):
+\code
+  vigra::MultiArray<2, double> data(...));
+  AccumulatorChain<double, Select<Mean, Skewness> > a;
+
+  std::cout << "passes required for all statistics: " << a.passesRequired() << std::endl; //skewness needs two passes
+  std::cout << "passes required by Mean: " << getAccumulator<Mean>(a).passesRequired() << std::endl;
+\endcode
+See \ref FeatureAccumulators for more information about feature computation via accumulators.
+*/
+template <class TAG, class A>
+inline typename LookupTag<TAG, A>::reference
+getAccumulator(A & a)
+{
+    typedef typename LookupTag<TAG, A>::Tag StandardizedTag;
+    typedef typename LookupTag<TAG, A>::reference reference;
+    return acc_detail::CastImpl<StandardizedTag, typename A::Tag, reference>::exec(a);
+}
+
+    // Get a reference to the accumulator TAG for region 'label' in the accumulator chain A
+/** Get a reference to the accumulator 'TAG' for region 'label' in the accumulator chain 'a'.
+*/
+template <class TAG, class A>
+inline typename LookupTag<TAG, A>::reference
+getAccumulator(A & a, MultiArrayIndex label)
+{
+    typedef typename LookupTag<TAG, A>::Tag StandardizedTag;
+    typedef typename LookupTag<TAG, A>::reference reference;
+    return acc_detail::CastImpl<StandardizedTag, typename A::Tag, reference>::exec(a, label);
+}
+
+    // get the result of the accumulator specified by TAG
+/** Get the result of the accumulator 'TAG' in the accumulator chain 'a'.\n
+Example of use:
+\code
+    vigra::MultiArray<2, double> data(...);
+    AccumulatorChain<DataType, Select<Variance, Mean, StdDev> > a;
+    extractFeatures(data.begin(), data.end(), a); 
+    double mean = get<Mean>(a);
+\endcode
+See \ref FeatureAccumulators for more information about feature computation via accumulators.
+*/
+template <class TAG, class A>
+inline typename LookupTag<TAG, A>::result_type
+get(A const & a)
+{
+    return getAccumulator<TAG>(a).get();
+}
+
+    // get the result of the accumulator TAG for region 'label'
+/** Get the result of the accumulator 'TAG' for region 'label' in the accumulator chain 'a'.\n
+Example of use:
+\code
+    vigra::MultiArray<2, double> data(...);
+    vigra::MultiArray<2, int> labels(...);
+    typedef vigra::CoupledIteratorType<2, double, int>::type Iterator;
+    typedef Iterator::value_type Handle;
+
+    AccumulatorChainArray<Handle, 
+        Select<DataArg<1>, LabelArg<2>, Mean, Variance> > a;
+
+    Iterator start = createCoupledIterator(data, labels);
+    Iterator end = start.getEndIterator();
+    extractFeatures(start,end,a);
+
+    double mean_of_region_1 = get<Mean>(a,1);
+    double mean_of_background = get<Mean>(a,0);
+\endcode
+See \ref FeatureAccumulators for more information about feature computation via accumulators.
+*/
+template <class TAG, class A>
+inline typename LookupTag<TAG, A>::result_type
+get(A const & a, MultiArrayIndex label)
+{
+    return getAccumulator<TAG>(a, label).get();
+}
+
+    // Get the result of the accumulator specified by TAG without checking if the accumulator is active.
+    // This must be used within an accumulator implementation to access dependencies because
+    // it applies the approprate modifiers to the given TAG. It must not be used in other situations.
+    // FIXME: is there a shorter name?
+template <class TAG, class A>
+inline typename LookupDependency<TAG, A>::result_type
+getDependency(A const & a)
+{
+    typedef typename LookupDependency<TAG, A>::Tag StandardizedTag;
+    typedef typename LookupDependency<TAG, A>::reference reference;
+    return acc_detail::CastImpl<StandardizedTag, typename A::Tag, reference>::exec(a)();
+}
+
+    // activate the dynamic accumulator specified by Tag
+/** Activate the dynamic accumulator 'Tag' in the dynamic accumulator chain 'a'. Same as a.activate<Tag>() (see DynamicAccumulatorChain::activate<Tag>() or DynamicAccumulatorChainArray::activate<Tag>()). For run-time activation use DynamicAccumulatorChain::activate(std::string tag) or DynamicAccumulatorChainArray::activate(std::string tag) instead.\n
+See \ref FeatureAccumulators for more information about feature computation via accumulators.
+*/
+template <class Tag, class A>
+inline void
+activate(A & a)
+{
+    a.template activate<Tag>();
+}
+
+    // check if the dynamic accumulator specified by Tag is active
+/** Check if the dynamic accumulator 'Tag' in the accumulator chain 'a' is active. Same as a.isActive<Tag>() (see DynamicAccumulatorChain::isActive<Tag>() or DynamicAccumulatorChainArray::isActive<Tag>()). At run-time, use DynamicAccumulatorChain::isActive(std::string tag) const or DynamicAccumulatorChainArray::isActive(std::string tag) const instead.\n
+See \ref FeatureAccumulators for more information about feature computation via accumulators.
+*/
+template <class Tag, class A>
+inline bool
+isActive(A const & a)
+{
+    return a.template isActive<Tag>();
+}
+
+/****************************************************************************/
+/*                                                                          */
+/*                               generic loops                              */
+/*                                                                          */
+/****************************************************************************/
+
+/** Generic loop to collect statistics from one or several arrays.
+
+This function automatically performs as many passes over the data as necessary for the selected statistics. The basic version of <tt>extractFeatures()</tt> takes an iterator pair and a reference to an accumulator chain:
+\code
+namespace vigra { namespace acc {
+
+    template <class ITERATOR, class ACCUMULATOR>
+    void extractFeatures(ITERATOR start, ITERATOR end, ACCUMULATOR & a);
+}}
+\endcode
+The <tt>ITERATOR</tt> can be any STL-conforming <i>forward iterator</i> (including raw pointers and \ref vigra::CoupledScanOrderIterator). The <tt>ACCUMULATOR</tt> must be instantiated with the <tt>ITERATOR</tt>'s <tt>value_type</tt> as its first template argument. For example, to use a raw pointer you write:
+\code
+    AccumulatorChain<double, Select<Mean, Variance> > a;
+
+    double * start = ...,
+           * end   = ...;
+    extractFeatures(start, end, a);
+\endcode
+Similarly, you can use MultiArray's scan-order iterator:
+\code    
+    AccumulatorChain<TinyVector<float, 2>, Select<Mean, Variance> > a;
+
+    MultiArray<3, TinyVector<float, 2> > data(...);
+    extractFeatures(data.begin(), data.end(), a);
+\endcode
+An alternative syntax is used when you want to compute weighted or region statistics (or both). Then it is necessary to iterate over several arrays simultaneously. This fact is best conveyed to the accumulator via the helper class \ref vigra::CoupledArrays that is used as the accumulator's first template argument and holds the dimension and value types of the arrays involved. To actually compute the features, you then pass appropriate arrays to the <tt>extractfeatures()</tt> function dir [...]
+\code
+    MultiArray<3, double> data(...);
+    MultiArray<3, int> labels(...);
+
+    AccumulatorChainArray<CoupledArrays<3, double, int>,
+                          Select<DataArg<1>, LabelArg<2>, // where to look for data and region labels
+                                 Mean, Variance> >        // what statistics to compute
+        a;
+
+    extractFeatures(data, labels, a);
+\endcode
+This form of <tt>extractFeatures()</tt> is supported for up to five arrays (although at most three are currently making sense in practice):
+\code
+namespace vigra { namespace acc {
+
+    template <unsigned int N, class T1, class S1,
+              class ACCUMULATOR>
+    void extractFeatures(MultiArrayView<N, T1, S1> const & a1, 
+                         ACCUMULATOR & a);
+                         
+    ...
+
+    template <unsigned int N, class T1, class S1,
+                              class T2, class S2,
+                              class T3, class S3,
+                              class T4, class S4,
+                              class T5, class S5,
+              class ACCUMULATOR>
+    void extractFeatures(MultiArrayView<N, T1, S1> const & a1, 
+                         MultiArrayView<N, T2, S2> const & a2, 
+                         MultiArrayView<N, T3, S3> const & a3, 
+                         MultiArrayView<N, T4, S4> const & a4, 
+                         MultiArrayView<N, T5, S5> const & a5, 
+                         ACCUMULATOR & a);
+}}
+\endcode
+Of course, the number and types of the arrays specified in <tt>CoupledArrays</tt> must conform to the number and types of the arrays passed to <tt>extractFeatures()</tt>.
+
+See \ref FeatureAccumulators for more information about feature computation via accumulators.
+*/
+doxygen_overloaded_function(template <...> void extractFeatures)
+
+
+template <class ITERATOR, class ACCUMULATOR>
+void extractFeatures(ITERATOR start, ITERATOR end, ACCUMULATOR & a)
+{
+    for(unsigned int k=1; k <= a.passesRequired(); ++k)
+        for(ITERATOR i=start; i < end; ++i)
+            a.updatePassN(*i, k);
+}
+
+template <unsigned int N, class T1, class S1,
+          class ACCUMULATOR>
+void extractFeatures(MultiArrayView<N, T1, S1> const & a1, 
+                     ACCUMULATOR & a)
+{
+    typedef typename CoupledIteratorType<N, T1>::type Iterator;
+    Iterator start = createCoupledIterator(a1),
+             end   = start.getEndIterator();
+    extractFeatures(start, end, a);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2,
+          class ACCUMULATOR>
+void extractFeatures(MultiArrayView<N, T1, S1> const & a1, 
+                     MultiArrayView<N, T2, S2> const & a2, 
+                     ACCUMULATOR & a)
+{
+    typedef typename CoupledIteratorType<N, T1, T2>::type Iterator;
+    Iterator start = createCoupledIterator(a1, a2),
+             end   = start.getEndIterator();
+    extractFeatures(start, end, a);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2,
+                          class T3, class S3,
+          class ACCUMULATOR>
+void extractFeatures(MultiArrayView<N, T1, S1> const & a1, 
+                     MultiArrayView<N, T2, S2> const & a2, 
+                     MultiArrayView<N, T3, S3> const & a3, 
+                     ACCUMULATOR & a)
+{
+    typedef typename CoupledIteratorType<N, T1, T2, T3>::type Iterator;
+    Iterator start = createCoupledIterator(a1, a2, a3),
+             end   = start.getEndIterator();
+    extractFeatures(start, end, a);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2,
+                          class T3, class S3,
+                          class T4, class S4,
+          class ACCUMULATOR>
+void extractFeatures(MultiArrayView<N, T1, S1> const & a1, 
+                     MultiArrayView<N, T2, S2> const & a2, 
+                     MultiArrayView<N, T3, S3> const & a3, 
+                     MultiArrayView<N, T4, S4> const & a4, 
+                     ACCUMULATOR & a)
+{
+    typedef typename CoupledIteratorType<N, T1, T2, T3, T4>::type Iterator;
+    Iterator start = createCoupledIterator(a1, a2, a3, a4),
+             end   = start.getEndIterator();
+    extractFeatures(start, end, a);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2,
+                          class T3, class S3,
+                          class T4, class S4,
+                          class T5, class S5,
+          class ACCUMULATOR>
+void extractFeatures(MultiArrayView<N, T1, S1> const & a1, 
+                     MultiArrayView<N, T2, S2> const & a2, 
+                     MultiArrayView<N, T3, S3> const & a3, 
+                     MultiArrayView<N, T4, S4> const & a4, 
+                     MultiArrayView<N, T5, S5> const & a5, 
+                     ACCUMULATOR & a)
+{
+    typedef typename CoupledIteratorType<N, T1, T2, T3, T4, T5>::type Iterator;
+    Iterator start = createCoupledIterator(a1, a2, a3, a4, a5),
+             end   = start.getEndIterator();
+    extractFeatures(start, end, a);
+}
+
+/****************************************************************************/
+/*                                                                          */
+/*                          AccumulatorResultTraits                         */
+/*                                                                          */
+/****************************************************************************/
+
+template <class T>
+struct AccumulatorResultTraits
+{
+    typedef T                                       type;
+    typedef T                                       element_type;
+    typedef double                                  element_promote_type;
+    typedef T                                       MinmaxType;
+    typedef element_promote_type                    SumType;
+    typedef element_promote_type                    FlatCovarianceType;
+    typedef element_promote_type                    CovarianceType;
+};
+
+template <class T, int N>
+struct AccumulatorResultTraits<TinyVector<T, N> >
+{
+    typedef TinyVector<T, N>                             type;
+    typedef T                                            element_type;
+    typedef double                                       element_promote_type;
+    typedef TinyVector<T, N>                             MinmaxType;
+    typedef TinyVector<element_promote_type, N>          SumType;
+    typedef TinyVector<element_promote_type, N*(N+1)/2>  FlatCovarianceType;
+    typedef Matrix<element_promote_type>                 CovarianceType;
+};
+
+// (?) beign change
+template <class T, unsigned int RED_IDX, unsigned int GREEN_IDX, unsigned int BLUE_IDX>
+struct AccumulatorResultTraits<RGBValue<T, RED_IDX, GREEN_IDX, BLUE_IDX> >
+{
+    typedef RGBValue<T>                                  type;
+    typedef T                                            element_type;
+    typedef double                                       element_promote_type;
+    typedef RGBValue<T>                                  MinmaxType;
+    typedef RGBValue<element_promote_type>               SumType;
+    typedef TinyVector<element_promote_type, 3*(3+1)/2>  FlatCovarianceType;
+    typedef Matrix<element_promote_type>                 CovarianceType;
+};
+// end change
+
+
+template <unsigned int N, class T, class Stride>
+struct AccumulatorResultTraits<MultiArrayView<N, T, Stride> >
+{
+    typedef MultiArrayView<N, T, Stride>            type;
+    typedef T                                       element_type;
+    typedef double                                  element_promote_type;
+    typedef MultiArray<N, T>                        MinmaxType;
+    typedef MultiArray<N, element_promote_type>     SumType;
+    typedef MultiArray<1, element_promote_type>     FlatCovarianceType;
+    typedef Matrix<element_promote_type>            CovarianceType;
+};
+
+template <unsigned int N, class T, class Alloc>
+struct AccumulatorResultTraits<MultiArray<N, T, Alloc> >
+{
+    typedef MultiArrayView<N, T, Alloc>             type;
+    typedef T                                       element_type;
+    typedef double                                  element_promote_type;
+    typedef MultiArray<N, T>                        MinmaxType;
+    typedef MultiArray<N, element_promote_type>     SumType;
+    typedef MultiArray<1, element_promote_type>     FlatCovarianceType;
+    typedef Matrix<element_promote_type>            CovarianceType;
+};
+
+/****************************************************************************/
+/*                                                                          */
+/*                           modifier implementations                       */
+/*                                                                          */
+/****************************************************************************/
+
+/** \brief Modifier. Compute statistic globally rather than per region. 
+
+This modifier only works when labels are given (with (Dynamic)AccumulatorChainArray), in which case statistics are computed per-region by default.
+*/
+template <class TAG>
+class Global
+{
+  public:
+    typedef typename StandardizeTag<TAG>::type  TargetTag;
+    typedef typename TargetTag::Dependencies    Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("Global<") + TargetTag::name() + " >";
+        // static const std::string n = std::string("Global<") + TargetTag::name() + " >";
+        // return n;
+    }
+};
+
+/** \brief Specifies index of data in CoupledHandle. 
+
+    If AccumulatorChain is used with CoupledIterator, DataArg<INDEX> tells the accumulator chain which index of the Handle contains the data. (Coordinates are always index 0)
+*/
+template <int INDEX>
+class DataArg
+{
+  public:
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("DataArg<") + asString(INDEX) + "> (internal)";
+        // static const std::string n = std::string("DataArg<") + asString(INDEX) + "> (internal)";
+        // return n;
+    }
+    
+    template <class T, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef DataArgTag Tag;
+        typedef void value_type;
+        typedef void result_type;
+
+        static const int value = INDEX;
+        static const unsigned int workInPass = 0;
+    };
+};
+
+// Tags are automatically wrapped with DataFromHandle if CoupledHandle used
+template <class TAG>
+class DataFromHandle
+{
+  public:
+    typedef typename StandardizeTag<TAG>::type TargetTag;
+    typedef typename TargetTag::Dependencies Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("DataFromHandle<") + TargetTag::name() + " > (internal)";
+        // static const std::string n = std::string("DataFromHandle<") + TargetTag::name() + " > (internal)";
+        // return n;
+    }
+    
+    template <class IndexDefinition, class TagFound=typename IndexDefinition::Tag>
+    struct DataIndexSelector
+    {
+        static const int value = 1; // default: CoupledHandle holds data at index 1 
+        
+        template <class U, class NEXT>
+        static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type::const_reference 
+        exec(CoupledHandle<U, NEXT> const & t)
+        {
+            return vigra::get<value>(t);
+        }
+    };
+    
+    template <class IndexDefinition>
+    struct DataIndexSelector<IndexDefinition, DataArgTag>
+    {
+        static const int value = IndexDefinition::value;
+        
+        template <class U, class NEXT>
+        static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type::const_reference
+        exec(CoupledHandle<U, NEXT> const & t)
+        {
+            return vigra::get<value>(t);
+        }
+    };
+    
+    template <class T, class BASE>
+    struct SelectInputType
+    {
+        typedef typename LookupTag<DataArgTag, BASE>::type FindDataIndex;
+        typedef DataIndexSelector<FindDataIndex> DataIndex;
+        typedef typename CoupledHandleCast<DataIndex::value, T>::type::value_type type;
+    };
+    
+    template <class T, class BASE>
+    struct Impl
+    : public TargetTag::template Impl<typename SelectInputType<T, BASE>::type, BASE>
+    {
+        typedef SelectInputType<T, BASE>                InputTypeSelector;
+        typedef typename InputTypeSelector::DataIndex   DataIndex;
+        typedef typename InputTypeSelector::type        input_type;
+        typedef input_type const &                      argument_type;
+        typedef argument_type                           first_argument_type;
+        
+        typedef typename TargetTag::template Impl<input_type, BASE> ImplType;
+        
+        using ImplType::reshape;
+        
+        template <class U, class NEXT>
+        void reshape(CoupledHandle<U, NEXT> const & t)
+        {
+            ImplType::reshape(acc_detail::shapeOf(DataIndex::exec(t)));
+        }
+        
+        template <class U, class NEXT>
+        void update(CoupledHandle<U, NEXT> const & t)
+        {
+            ImplType::update(DataIndex::exec(t));
+        }
+        
+        template <class U, class NEXT>
+        void update(CoupledHandle<U, NEXT> const & t, double weight)
+        {
+            ImplType::update(DataIndex::exec(t), weight);
+        }
+    };
+};
+
+/** \brief Modifier. Compute statistic from pixel coordinates rather than from pixel values. 
+
+    AccumulatorChain must be used with CoupledIterator in order to have access to pixel coordinates.
+ */
+template <class TAG>
+class Coord
+{
+  public:
+    typedef typename StandardizeTag<TAG>::type   TargetTag;
+    typedef typename TargetTag::Dependencies     Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("Coord<") + TargetTag::name() + " >";
+        // static const std::string n = std::string("Coord<") + TargetTag::name() + " >";
+        // return n;
+    }
+    
+    template <class IndexDefinition, class TagFound=typename IndexDefinition::Tag>
+    struct CoordIndexSelector
+    {
+        static const int value = 0; // default: CoupledHandle holds coordinates at index 0 
+        
+        template <class U, class NEXT>
+        static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type::const_reference 
+        exec(CoupledHandle<U, NEXT> const & t)
+        {
+            return vigra::get<value>(t);
+        }
+    };
+    
+    template <class IndexDefinition>
+    struct CoordIndexSelector<IndexDefinition, CoordArgTag>
+    {
+        static const int value = IndexDefinition::value;
+        
+        template <class U, class NEXT>
+        static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type::const_reference
+        exec(CoupledHandle<U, NEXT> const & t)
+        {
+            return vigra::get<value>(t);
+        }
+    };
+     
+    template <class T, class BASE>
+    struct SelectInputType
+    {
+        typedef typename LookupTag<CoordArgTag, BASE>::type FindDataIndex;
+        typedef CoordIndexSelector<FindDataIndex> CoordIndex;
+        typedef typename CoupledHandleCast<CoordIndex::value, T>::type::value_type type;
+        static const int size = type::static_size;
+    };
+    
+    template <class T, class BASE>
+    struct Impl
+    : public TargetTag::template Impl<TinyVector<double, SelectInputType<T, BASE>::size>, BASE>
+    {
+        typedef SelectInputType<T, BASE>                              InputTypeSelector;
+        typedef typename InputTypeSelector::CoordIndex                CoordIndex;
+        typedef TinyVector<double, SelectInputType<T, BASE>::size>    input_type;
+        typedef input_type const &                                    argument_type;
+        typedef argument_type                                         first_argument_type;
+        
+        typedef typename TargetTag::template Impl<input_type, BASE> ImplType;
+        
+        input_type offset_;
+        
+        Impl()
+        : offset_()
+        {}
+        
+        void setCoordinateOffset(input_type const & offset)
+        {
+            offset_ = offset;
+        }
+        
+        using ImplType::reshape;
+        
+        template <class U, class NEXT>
+        void reshape(CoupledHandle<U, NEXT> const & t)
+        {
+            ImplType::reshape(acc_detail::shapeOf(CoordIndex::exec(t)));
+        }
+        
+        template <class U, class NEXT>
+        void update(CoupledHandle<U, NEXT> const & t)
+        {
+            ImplType::update(CoordIndex::exec(t)+offset_);
+        }
+        
+        template <class U, class NEXT>
+        void update(CoupledHandle<U, NEXT> const & t, double weight)
+        {
+            ImplType::update(CoordIndex::exec(t)+offset_, weight);
+        }
+    };
+};
+
+/** \brief Specifies index of data in CoupledHandle. 
+
+    If AccumulatorChain is used with CoupledIterator, WeightArg<INDEX> tells the accumulator chain which index of the Handle contains the weights. (Note that coordinates are always index 0.)
+*/
+template <int INDEX>
+class WeightArg
+{
+  public:
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("WeightArg<") + asString(INDEX) + "> (internal)";
+        // static const std::string n = std::string("WeightArg<") + asString(INDEX) + "> (internal)";
+        // return n;
+    }
+    
+    template <class T, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef WeightArgTag Tag;
+        typedef void value_type;
+        typedef void result_type;
+
+        static const int value = INDEX;
+        static const unsigned int workInPass = 0;
+    };
+};
+
+/** \brief Compute weighted version of the statistic.
+*/
+template <class TAG>
+class Weighted
+{
+  public:
+    typedef typename StandardizeTag<TAG>::type   TargetTag;
+    typedef typename TargetTag::Dependencies     Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("Weighted<") + TargetTag::name() + " >";
+        // static const std::string n = std::string("Weighted<") + TargetTag::name() + " >";
+        // return n;
+    }
+    
+    template <class IndexDefinition, class TagFound=typename IndexDefinition::Tag>
+    struct WeightIndexSelector
+    {
+        template <class U, class NEXT>
+        static double exec(CoupledHandle<U, NEXT> const & t)
+        {
+            return (double)*t; // default: CoupledHandle holds weights at the last (outermost) index 
+        }
+    };
+    
+    template <class IndexDefinition>
+    struct WeightIndexSelector<IndexDefinition, WeightArgTag>
+    {
+        template <class U, class NEXT>
+        static double exec(CoupledHandle<U, NEXT> const & t)
+        {
+            return (double)get<IndexDefinition::value>(t);
+        }
+    };
+    
+    template <class T, class BASE>
+    struct Impl
+    : public TargetTag::template Impl<T, BASE>
+    {
+        typedef typename TargetTag::template Impl<T, BASE> ImplType;
+        
+        typedef typename LookupTag<WeightArgTag, BASE>::type FindWeightIndex;
+                
+        template <class U, class NEXT>
+        void update(CoupledHandle<U, NEXT> const & t)
+        {
+            ImplType::update(t, WeightIndexSelector<FindWeightIndex>::exec(t));
+        }
+    };
+};
+
+// Centralize by subtracting the mean and cache the result
+class Centralize
+{
+  public:
+    typedef Select<Mean> Dependencies;
+    
+    static std::string name() 
+    { 
+         return "Centralize (internal)";
+        // static const std::string n("Centralize (internal)");
+        // return n;
+    }
+   
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        static const unsigned int workInPass = 2;
+        
+        typedef typename AccumulatorResultTraits<U>::element_promote_type element_type;
+        typedef typename AccumulatorResultTraits<U>::SumType              value_type;
+        typedef value_type const &                                  result_type;
+
+        mutable value_type value_;
+        
+        Impl()
+        : value_()  // call default constructor explicitly to ensure zero initialization
+        {}
+        
+        void reset()
+        {
+            value_ = element_type();
+        }
+    
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            acc_detail::reshapeImpl(value_, s);
+        }
+        
+        void update(U const & t) const
+        {
+            using namespace vigra::multi_math;
+            value_ = t - getDependency<Mean>(*this);
+        }
+        
+        void update(U const & t, double) const
+        {
+            update(t);
+        }
+        
+        result_type operator()(U const & t) const
+        {
+            update(t);
+            return value_;
+        }
+        
+        result_type operator()() const
+        {
+            return value_;
+        }
+    };
+};
+
+/** \brief Modifier. Substract mean before computing statistic. 
+
+Works in pass 2, %operator+=() not supported (merging not supported).
+*/
+template <class TAG>
+class Central
+{
+  public:
+    typedef typename StandardizeTag<TAG>::type                    TargetTag;
+    typedef Select<Centralize, typename TargetTag::Dependencies>  Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("Central<") + TargetTag::name() + " >";
+        // static const std::string n = std::string("Central<") + TargetTag::name() + " >";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE>
+    {
+        typedef typename TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE> ImplType;
+        
+        static const unsigned int workInPass = 2;
+        
+        void operator+=(Impl const & o)
+        {
+            vigra_precondition(false,
+                "Central<...>::operator+=(): not supported.");
+        }
+    
+        template <class T>
+        void update(T const & t)
+        {
+            ImplType::update(getDependency<Centralize>(*this));
+        }
+        
+        template <class T>
+        void update(T const & t, double weight)
+        {
+            ImplType::update(getDependency<Centralize>(*this), weight);
+        }
+    };
+};
+
+    // alternative implementation without caching 
+    //
+// template <class TAG>
+// class Central
+// {
+  // public:
+    // typedef typename StandardizeTag<TAG>::type TargetTag;
+    // typedef TypeList<Mean, typename TransferModifiers<Central<TargetTag>, typename TargetTag::Dependencies::type>::type> Dependencies;
+    
+    // template <class U, class BASE>
+    // struct Impl
+    // : public TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE>
+    // {
+        // typedef typename TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE> ImplType;
+        
+        // static const unsigned int workInPass = 2;
+        
+        // void operator+=(Impl const & o)
+        // {
+            // vigra_precondition(false,
+                // "Central<...>::operator+=(): not supported.");
+        // }
+    
+        // template <class T>
+        // void update(T const & t)
+        // {
+            // ImplType::update(t - getDependency<Mean>(*this));
+        // }
+        
+        // template <class T>
+        // void update(T const & t, double weight)
+        // {
+            // ImplType::update(t - getDependency<Mean>(*this), weight);
+        // }
+    // };
+// };
+
+
+class PrincipalProjection
+{
+  public:
+    typedef Select<Centralize, Principal<CoordinateSystem> > Dependencies;
+    
+    static std::string name() 
+    { 
+        return "PrincipalProjection (internal)";
+        // static const std::string n("PrincipalProjection (internal)");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        static const unsigned int workInPass = 2;
+        
+        typedef typename AccumulatorResultTraits<U>::element_promote_type element_type;
+        typedef typename AccumulatorResultTraits<U>::SumType              value_type;
+        typedef value_type const &                                  result_type;
+
+        mutable value_type value_;
+        
+        Impl()
+        : value_()  // call default constructor explicitly to ensure zero initialization
+        {}
+        
+        void reset()
+        {
+            value_ = element_type();
+        }
+    
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            acc_detail::reshapeImpl(value_, s);
+        }
+        
+        void update(U const & t) const
+        {
+            for(unsigned int k=0; k<t.size(); ++k)
+            {
+                value_[k] = getDependency<Principal<CoordinateSystem> >(*this)(0, k)*getDependency<Centralize>(*this)[0];
+                for(unsigned int d=1; d<t.size(); ++d)
+                    value_[k] += getDependency<Principal<CoordinateSystem> >(*this)(d, k)*getDependency<Centralize>(*this)[d];
+            }
+        }
+        
+        void update(U const & t, double) const
+        {
+            update(t);
+        }
+        
+        result_type operator()(U const & t) const
+        {
+            getAccumulator<Centralize>(*this).update(t);
+            update(t);
+            return value_;
+        }
+        
+        result_type operator()() const
+        {
+            return value_;
+        }
+    };
+};
+
+/** \brief Modifier. Project onto PCA eigenvectors.
+
+    Works in pass 2, %operator+=() not supported (merging not supported).
+*/
+template <class TAG>
+class Principal
+{
+  public:
+    typedef typename StandardizeTag<TAG>::type                             TargetTag;
+    typedef Select<PrincipalProjection, typename TargetTag::Dependencies>  Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("Principal<") + TargetTag::name() + " >";
+        // static const std::string n = std::string("Principal<") + TargetTag::name() + " >";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE>
+    {
+        typedef typename TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE> ImplType;
+        
+        static const unsigned int workInPass = 2;
+        
+        void operator+=(Impl const & o)
+        {
+            vigra_precondition(false,
+                "Principal<...>::operator+=(): not supported.");
+        }
+    
+        template <class T>
+        void update(T const & t)
+        {
+            ImplType::update(getDependency<PrincipalProjection>(*this));
+        }
+        
+        template <class T>
+        void update(T const & t, double weight)
+        {
+            ImplType::update(getDependency<PrincipalProjection>(*this), weight);
+        }
+    };
+};
+
+/*
+important notes on modifiers:
+ * upon accumulator creation, modifiers are reordered so that data preparation is innermost, 
+   and data access is outermost, e.g.:
+        Coord<DivideByCount<Principal<PowerSum<2> > > >
+ * modifiers are automatically transfered to dependencies as appropriate
+ * modifiers for lookup (getAccumulator and get) of dependent accumulators are automatically adjusted
+ * modifiers must adjust workInPass for the contained accumulator as appropriate
+ * we may implement convenience versions of Select that apply a modifier to all 
+   contained tags at once
+ * weighted accumulators have their own Count object when used together
+   with unweighted ones (this is as yet untested - FIXME)
+ * certain accumulators must remain unchanged when wrapped in certain modifiers: 
+    * Count: always except for Weighted<Count> and CoordWeighted<Count>
+    * Sum: data preparation modifiers
+    * FlatScatterMatrixImpl, CovarianceEigensystemImpl: Principal and Whitened
+ * will it be useful to implement initPass<N>() or finalizePass<N>() ?
+*/
+
+/****************************************************************************/
+/*                                                                          */
+/*                        the actual accumulators                           */
+/*                                                                          */
+/****************************************************************************/
+
+/** \brief Basic statistic. Identity matrix of appropriate size.
+*/
+class CoordinateSystem
+{
+  public:
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "CoordinateSystem";
+        // static const std::string n("CoordinateSystem");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef double              element_type;
+        typedef Matrix<double>      value_type;
+        typedef value_type const &  result_type;
+
+        value_type value_;
+        
+        Impl()
+        : value_()  // call default constructor explicitly to ensure zero initialization
+        {}
+        
+        void reset()
+        {
+            value_ = element_type();
+        }
+
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            acc_detail::reshapeImpl(value_, s);
+        }
+        
+        result_type operator()() const
+        {
+            return value_;
+        }
+    };
+};
+
+template <class BASE, class T, 
+          class ElementType=typename AccumulatorResultTraits<T>::element_promote_type, 
+          class SumType=typename AccumulatorResultTraits<T>::SumType>
+struct SumBaseImpl
+: public BASE
+{
+    typedef ElementType         element_type;
+    typedef SumType             value_type;
+    typedef value_type const &  result_type;
+
+    value_type value_;
+    
+    SumBaseImpl()
+    : value_()  // call default constructor explicitly to ensure zero initialization
+    {}
+    
+    void reset()
+    {
+        value_ = element_type();
+    }
+
+    template <class Shape>
+    void reshape(Shape const & s)
+    {
+        acc_detail::reshapeImpl(value_, s);
+    }
+    
+    void operator+=(SumBaseImpl const & o)
+    {
+        value_ += o.value_;
+    }
+
+    result_type operator()() const
+    {
+        return value_;
+    }
+};
+
+// Count
+template <>
+class PowerSum<0>
+{
+  public:
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "PowerSum<0>";
+        // static const std::string n("PowerSum<0>");
+        // return n;
+    }
+    
+    template <class T, class BASE>
+    struct Impl
+    : public SumBaseImpl<BASE, T, double, double>
+    {
+        void update(T const & t)
+        {
+            ++this->value_;
+        }
+        
+        void update(T const & t, double weight)
+        {
+            this->value_ += weight;
+        }
+    };
+};
+
+// Sum
+template <>
+class PowerSum<1>
+{
+  public:
+    typedef Select<> Dependencies;
+     
+    static std::string name() 
+    { 
+        return "PowerSum<1>";
+        // static const std::string n("PowerSum<1>");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public SumBaseImpl<BASE, U>
+    {
+        void update(U const & t)
+        {
+            this->value_ += t;
+        }
+        
+        void update(U const & t, double weight)
+        {
+            this->value_ += weight*t;
+        }
+    };
+};
+
+/** \brief Basic statistic. PowerSum<N> =@f$ \sum_i x_i^N @f$
+
+    Works in pass 1, %operator+=() supported (merging supported).
+*/
+template <unsigned N>
+class PowerSum
+{
+  public:
+    typedef Select<> Dependencies;
+     
+    static std::string name() 
+    { 
+        return std::string("PowerSum<") + asString(N) + ">";
+        // static const std::string n = std::string("PowerSum<") + asString(N) + ">";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public SumBaseImpl<BASE, U>
+    {
+        void update(U const & t)
+        {
+            using namespace vigra::multi_math;            
+            this->value_ += pow(t, (int)N);
+        }
+        
+        void update(U const & t, double weight)
+        {
+            using namespace vigra::multi_math;            
+            this->value_ += weight*pow(t, (int)N);
+        }
+    };
+};
+
+template <>
+class AbsPowerSum<1>
+{
+  public:
+    typedef Select<> Dependencies;
+     
+    static std::string name() 
+    { 
+        return "AbsPowerSum<1>";
+        // static const std::string n("AbsPowerSum<1>");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public SumBaseImpl<BASE, U>
+    {
+        void update(U const & t)
+        {
+            using namespace vigra::multi_math;            
+            this->value_ += abs(t);
+        }
+        
+        void update(U const & t, double weight)
+        {
+            using namespace vigra::multi_math;            
+            this->value_ += weight*abs(t);
+        }
+    };
+};
+
+/** \brief Basic statistic. AbsPowerSum<N> =@f$ \sum_i |x_i|^N @f$
+
+    Works in pass 1, %operator+=() supported (merging supported).
+*/
+template <unsigned N>
+class AbsPowerSum
+{
+  public:
+    typedef Select<> Dependencies;
+     
+    static std::string name() 
+    { 
+        return std::string("AbsPowerSum<") + asString(N) + ">";
+        // static const std::string n = std::string("AbsPowerSum<") + asString(N) + ">";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public SumBaseImpl<BASE, U>
+    {
+        void update(U const & t)
+        {
+            using namespace vigra::multi_math;            
+            this->value_ += pow(abs(t), (int)N);
+        }
+        
+        void update(U const & t, double weight)
+        {
+            using namespace vigra::multi_math;            
+            this->value_ += weight*pow(abs(t), (int)N);
+        }
+    };
+};
+
+template <class BASE, class VALUE_TYPE, class U>
+struct CachedResultBase
+: public BASE
+{
+    typedef typename AccumulatorResultTraits<U>::element_type  element_type;
+    typedef VALUE_TYPE                                         value_type;
+    typedef value_type const &                                 result_type;
+
+    mutable value_type value_;
+    
+    CachedResultBase()
+    : value_()  // call default constructor explicitly to ensure zero initialization
+    {}
+    
+    void reset()
+    {
+        value_ = element_type();
+        this->setClean();
+    }
+
+    template <class Shape>
+    void reshape(Shape const & s)
+    {
+        acc_detail::reshapeImpl(value_, s);
+    }
+
+    void operator+=(CachedResultBase const &)
+    {
+        this->setDirty();
+    }
+
+    void update(U const &)
+    {
+        this->setDirty();
+    }
+    
+    void update(U const &, double)
+    {
+         this->setDirty();
+    }
+};
+
+// cached Mean and Variance
+/** \brief Modifier. Divide statistic by Count:  DivideByCount<TAG> = TAG / Count .
+*/
+template <class TAG>
+class DivideByCount
+{
+  public:
+    typedef typename StandardizeTag<TAG>::type TargetTag;
+    typedef Select<TargetTag, Count> Dependencies;
+  
+    static std::string name() 
+    { 
+        return std::string("DivideByCount<") + TargetTag::name() + " >";
+        // static const std::string n = std::string("DivideByCount<") + TargetTag::name() + " >";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public CachedResultBase<BASE, typename LookupDependency<TargetTag, BASE>::value_type, U> 
+    {
+        typedef typename CachedResultBase<BASE, typename LookupDependency<TargetTag, BASE>::value_type, U>::result_type result_type;
+        
+        result_type operator()() const
+        {
+            if(this->isDirty())
+            {
+                using namespace multi_math;
+                this->value_ = getDependency<TargetTag>(*this) / getDependency<Count>(*this);
+                this->setClean();
+            }
+            return this->value_;
+        }
+    };
+};
+
+// UnbiasedVariance
+/** \brief Modifier. Divide statistics by Count-1:  DivideUnbiased<TAG> = TAG / (Count-1)
+*/
+template <class TAG>
+class DivideUnbiased
+{
+  public:
+    typedef typename StandardizeTag<TAG>::type TargetTag;
+    typedef Select<TargetTag, Count> Dependencies;
+      
+    static std::string name() 
+    { 
+        return std::string("DivideUnbiased<") + TargetTag::name() + " >";
+        // static const std::string n = std::string("DivideUnbiased<") + TargetTag::name() + " >";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename LookupDependency<TargetTag, BASE>::value_type  value_type;
+        typedef value_type                                       result_type;
+        
+        result_type operator()() const
+        {
+            using namespace multi_math;
+            return getDependency<TargetTag>(*this) / (getDependency<Count>(*this) - 1.0);
+        }
+    };
+};
+
+// RootMeanSquares and StdDev
+/** \brief Modifier. RootDivideByCount<TAG> = sqrt( TAG/Count )
+*/
+template <class TAG>
+class RootDivideByCount
+{
+  public:
+    typedef typename StandardizeTag<DivideByCount<TAG> >::type TargetTag;
+    typedef Select<TargetTag> Dependencies;
+    
+    static std::string name() 
+    { 
+        typedef typename StandardizeTag<TAG>::type InnerTag;
+        return std::string("RootDivideByCount<") + InnerTag::name() + " >";
+        // static const std::string n = std::string("RootDivideByCount<") + InnerTag::name() + " >";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename LookupDependency<TargetTag, BASE>::value_type  value_type;
+        typedef value_type                                       result_type;
+        
+        result_type operator()() const
+        {
+            using namespace multi_math;
+            return sqrt(getDependency<TargetTag>(*this));
+        }
+    };
+};
+
+// UnbiasedStdDev
+/** \brief Modifier. RootDivideUnbiased<TAG> = sqrt( TAG / (Count-1) )
+*/
+template <class TAG>
+class RootDivideUnbiased
+{
+  public:
+    typedef typename StandardizeTag<DivideUnbiased<TAG> >::type TargetTag;
+    typedef Select<TargetTag> Dependencies;
+    
+    static std::string name() 
+    { 
+        typedef typename StandardizeTag<TAG>::type InnerTag;
+        return std::string("RootDivideUnbiased<") + InnerTag::name() + " >";
+        // static const std::string n = std::string("RootDivideUnbiased<") + InnerTag::name() + " >";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename LookupDependency<TargetTag, BASE>::value_type  value_type;
+        typedef value_type                                       result_type;
+        
+        result_type operator()() const
+        {
+            using namespace multi_math;
+            return sqrt(getDependency<TargetTag>(*this));
+        }
+    };
+};
+
+/** \brief Spezialization: works in pass 1, %operator+=() supported (merging supported).
+*/
+template <>
+class Central<PowerSum<2> >
+{
+  public:
+    typedef Select<Mean, Count> Dependencies;
+     
+    static std::string name() 
+    { 
+        return "Central<PowerSum<2> >";
+        // static const std::string n("Central<PowerSum<2> >");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public SumBaseImpl<BASE, U>
+    {
+        void operator+=(Impl const & o)
+        {
+            using namespace vigra::multi_math;
+            double n1 = getDependency<Count>(*this), n2 = getDependency<Count>(o);
+            if(n1 == 0.0)
+            {
+                this->value_ = o.value_;
+            }
+            else if(n2 != 0.0)
+            {
+                this->value_ += o.value_ + n1 * n2 / (n1 + n2) * sq(getDependency<Mean>(*this) - getDependency<Mean>(o));
+            }
+        }
+    
+        void update(U const & t)
+        {
+            double n = getDependency<Count>(*this);
+            if(n > 1.0)
+            {
+                using namespace vigra::multi_math;
+                this->value_ += n / (n - 1.0) * sq(getDependency<Mean>(*this) - t);
+            }
+        }
+        
+        void update(U const & t, double weight)
+        {
+            double n = getDependency<Count>(*this);
+            if(n > weight)
+            {
+                using namespace vigra::multi_math;
+                this->value_ += n / (n - weight) * sq(getDependency<Mean>(*this) - t);
+            }
+        }
+    };
+};
+
+/** \brief Specialization: works in pass 2, %operator+=() supported (merging supported).
+*/
+template <>
+class Central<PowerSum<3> >
+{
+  public:
+    typedef Select<Centralize, Count, Mean, Central<PowerSum<2> > > Dependencies;
+     
+    static std::string name() 
+    { 
+        return "Central<PowerSum<3> >";
+        // static const std::string n("Central<PowerSum<3> >");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public SumBaseImpl<BASE, U>
+    {
+        typedef typename SumBaseImpl<BASE, U>::value_type value_type;
+
+        static const unsigned int workInPass = 2;
+        
+        void operator+=(Impl const & o)
+        {
+            typedef Central<PowerSum<2> > Sum2Tag;
+            
+            using namespace vigra::multi_math;
+            double n1 = getDependency<Count>(*this), n2 = getDependency<Count>(o);
+            if(n1 == 0.0)
+            {
+                this->value_ = o.value_;
+            }
+            else if(n2 != 0.0)
+            {
+                double n = n1 + n2;
+                double weight = n1 * n2 * (n1 - n2) / sq(n);
+                value_type delta = getDependency<Mean>(o) - getDependency<Mean>(*this);
+                this->value_ += o.value_ + weight * pow(delta, 3) +
+                               3.0 / n * delta * (n1 * getDependency<Sum2Tag>(o) - n2 * getDependency<Sum2Tag>(*this));
+            }
+        }
+    
+        void update(U const & t)
+        {
+            using namespace vigra::multi_math;            
+            this->value_ += pow(getDependency<Centralize>(*this), 3);
+        }
+        
+        void update(U const & t, double weight)
+        {
+            using namespace vigra::multi_math;            
+            this->value_ += weight*pow(getDependency<Centralize>(*this), 3);
+        }
+    };
+};
+/** \brief Specialization: works in pass 2, %operator+=() supported (merging supported).
+*/
+template <>
+class Central<PowerSum<4> >
+{
+  public:
+    typedef Select<Centralize, Central<PowerSum<3> > > Dependencies;
+     
+    static std::string name() 
+    { 
+        return "Central<PowerSum<4> >";
+        // static const std::string n("Central<PowerSum<4> >");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public SumBaseImpl<BASE, U>
+    {
+        typedef typename SumBaseImpl<BASE, U>::value_type value_type;
+
+        static const unsigned int workInPass = 2;
+        
+        void operator+=(Impl const & o)
+        {
+            typedef Central<PowerSum<2> > Sum2Tag;
+            typedef Central<PowerSum<3> > Sum3Tag;
+
+            using namespace vigra::multi_math;
+            double n1 = getDependency<Count>(*this), n2 = getDependency<Count>(o);
+            if(n1 == 0.0)
+            {
+                this->value_ = o.value_;
+            }
+            else if(n2 != 0.0)
+            {
+                double n = n1 + n2;
+                double n1_2 = sq(n1);
+                double n2_2 = sq(n2);
+                double n_2 = sq(n);
+                double weight = n1 * n2 * (n1_2 - n1*n2 + n2_2) / n_2 / n;
+                value_type delta = getDependency<Mean>(o) - getDependency<Mean>(*this);
+                this->value_ += o.value_ + weight * pow(delta, 4) +
+                              6.0 / n_2 * sq(delta) * (n1_2 * getDependency<Sum2Tag>(o) + n2_2 * getDependency<Sum2Tag>(*this)) +
+                              4.0 / n * delta * (n1 * getDependency<Sum3Tag>(o) - n2 * getDependency<Sum3Tag>(*this));
+            }
+        }
+    
+        void update(U const & t)
+        {
+            using namespace vigra::multi_math;            
+            this->value_ += pow(getDependency<Centralize>(*this), 4);
+        }
+        
+        void update(U const & t, double weight)
+        {
+            using namespace vigra::multi_math;            
+            this->value_ += weight*pow(getDependency<Centralize>(*this), 4);
+        }
+    };
+};
+
+/** \brief Basic statistic. Skewness. 
+
+    %Skewness =@f$ \frac{ \frac{1}{n}\sum_i (x_i-\hat{x})^3 }{ (\frac{1}{n}\sum_i (x_i-\hat{x})^2)^{3/2} } @f$ .
+    Works in pass 2, %operator+=() supported (merging supported).
+*/
+class Skewness
+{
+  public:
+    typedef Select<Central<PowerSum<2> >, Central<PowerSum<3> > > Dependencies;
+    
+    static std::string name() 
+    { 
+        return "Skewness";
+        // static const std::string n("Skewness");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        static const unsigned int workInPass = 2;
+        
+        typedef typename LookupDependency<Central<PowerSum<3> >, BASE>::value_type   value_type;
+        typedef value_type                                                    result_type;
+
+        result_type operator()() const
+        {
+            typedef Central<PowerSum<3> > Sum3;
+            typedef Central<PowerSum<2> > Sum2;
+        
+                        using namespace multi_math;
+            return sqrt(getDependency<Count>(*this)) * getDependency<Sum3>(*this) / pow(getDependency<Sum2>(*this), 1.5);
+        }
+    };
+};
+
+/** \brief Basic statistic. Unbiased Skewness.
+
+    Works in pass 2, %operator+=() supported (merging supported).
+*/
+class UnbiasedSkewness
+{
+  public:
+    typedef Select<Skewness> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "UnbiasedSkewness";
+        // static const std::string n("UnbiasedSkewness");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        static const unsigned int workInPass = 2;
+        
+        typedef typename LookupDependency<Central<PowerSum<3> >, BASE>::value_type   value_type;
+        typedef value_type                                                    result_type;
+
+        result_type operator()() const
+        {
+                        using namespace multi_math;
+            double n = getDependency<Count>(*this);
+            return sqrt(n*(n-1.0)) / (n - 2.0) * getDependency<Skewness>(*this);
+        }
+    };
+};
+
+/** \brief Basic statistic. Kurtosis. 
+
+    %Kurtosis = @f$ \frac{ \frac{1}{n}\sum_i (x_i-\bar{x})^4 }{
+    (\frac{1}{n} \sum_i(x_i-\bar{x})^2)^2 } - 3 @f$ . 
+    Works in pass 2, %operator+=() supported (merging supported).
+*/
+class Kurtosis
+{
+  public:
+    typedef Select<Central<PowerSum<2> >, Central<PowerSum<4> > > Dependencies;
+    
+    static std::string name() 
+    { 
+        return "Kurtosis";
+        // static const std::string n("Kurtosis");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        static const unsigned int workInPass = 2;
+        
+        typedef typename LookupDependency<Central<PowerSum<4> >, BASE>::value_type value_type;
+        typedef value_type                                                  result_type;
+
+        result_type operator()() const
+        {
+            typedef Central<PowerSum<4> > Sum4;
+            typedef Central<PowerSum<2> > Sum2;
+        
+                        using namespace multi_math;
+            return getDependency<Count>(*this) * getDependency<Sum4>(*this) / sq(getDependency<Sum2>(*this)) - value_type(3.0);
+        }
+    };
+};
+
+/** \brief Basic statistic. Unbiased Kurtosis.
+
+    Works in pass 2, %operator+=() supported (merging supported).
+*/
+class UnbiasedKurtosis
+{
+  public:
+    typedef Select<Kurtosis> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "UnbiasedKurtosis";
+        // static const std::string n("UnbiasedKurtosis");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        static const unsigned int workInPass = 2;
+        
+        typedef typename LookupDependency<Central<PowerSum<4> >, BASE>::value_type value_type;
+        typedef value_type                                                  result_type;
+
+        result_type operator()() const
+        {
+                        using namespace multi_math;
+            double n = getDependency<Count>(*this);
+            return (n-1.0)/((n-2.0)*(n-3.0))*((n+1.0)*getDependency<Kurtosis>(*this) + value_type(6.0));
+        }
+    };
+};
+
+namespace acc_detail {
+
+template <class Scatter, class Sum>
+void updateFlatScatterMatrix(Scatter & sc, Sum const & s, double w)
+{
+    int size = s.size();
+    for(MultiArrayIndex j=0, k=0; j<size; ++j)
+        for(MultiArrayIndex i=j; i<size; ++i, ++k)
+            sc[k] += w*s[i]*s[j];
+}
+
+template <class Sum>
+void updateFlatScatterMatrix(double & sc, Sum const & s, double w)
+{
+    sc += w*s*s;
+}
+
+template <class Cov, class Scatter>
+void flatScatterMatrixToScatterMatrix(Cov & cov, Scatter const & sc)
+{
+    int size = cov.shape(0), k=0;
+    for(MultiArrayIndex j=0; j<size; ++j)
+    {
+        cov(j,j) = sc[k++];
+        for(MultiArrayIndex i=j+1; i<size; ++i)
+        {
+            cov(i,j) = sc[k++];
+            cov(j,i) = cov(i,j);
+        }
+    }
+}
+
+template <class Scatter>
+void flatScatterMatrixToScatterMatrix(double & cov, Scatter const & sc)
+{
+    cov = sc;
+}
+
+template <class Cov, class Scatter>
+void flatScatterMatrixToCovariance(Cov & cov, Scatter const & sc, double n)
+{
+    int size = cov.shape(0), k=0;
+    for(MultiArrayIndex j=0; j<size; ++j)
+    {
+        cov(j,j) = sc[k++] / n;
+        for(MultiArrayIndex i=j+1; i<size; ++i)
+        {
+            cov(i,j) = sc[k++] / n;
+            cov(j,i) = cov(i,j);
+        }
+    }
+}
+
+template <class Scatter>
+void flatScatterMatrixToCovariance(double & cov, Scatter const & sc, double n)
+{
+    cov = sc / n;
+}
+
+} // namespace acc_detail
+
+// we only store the flattened upper triangular part of the scatter matrix
+/** \brief Basic statistic. Flattened uppter-triangular part of scatter matrix.
+
+    Works in pass 1, %operator+=() supported (merging supported).
+*/
+class FlatScatterMatrix
+{
+  public:
+    typedef Select<Mean, Count> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "FlatScatterMatrix";
+        // static const std::string n("FlatScatterMatrix");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename AccumulatorResultTraits<U>::element_promote_type  element_type;
+        typedef typename AccumulatorResultTraits<U>::FlatCovarianceType    value_type;
+        typedef value_type const &                                   result_type;
+       
+        typedef typename AccumulatorResultTraits<U>::SumType        SumType;
+
+        value_type value_;
+        SumType     diff_;
+        
+        Impl()
+        : value_(),  // call default constructor explicitly to ensure zero initialization
+          diff_()
+        {}
+        
+        void reset()
+        {
+            value_ = element_type();
+        }
+    
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            int size = prod(s);
+            acc_detail::reshapeImpl(value_, Shape1(size*(size+1)/2));
+            acc_detail::reshapeImpl(diff_, s);
+        }
+        
+        void operator+=(Impl const & o)
+        {
+            double n1 = getDependency<Count>(*this), n2 = getDependency<Count>(o);
+            if(n1 == 0.0)
+            {
+                value_ = o.value_;
+            }
+            else if(n2 != 0.0)
+            {
+                using namespace vigra::multi_math;
+                diff_ = getDependency<Mean>(*this) - getDependency<Mean>(o);
+                acc_detail::updateFlatScatterMatrix(value_, diff_, n1 * n2 / (n1 + n2));
+                value_ += o.value_;
+            }
+        }
+    
+        void update(U const & t)
+        {
+            compute(t);
+        }
+        
+        void update(U const & t, double weight)
+        {
+            compute(t, weight);
+        }
+        
+        result_type operator()() const
+        {
+            return value_;
+        }
+        
+      private:
+        void compute(U const & t, double weight = 1.0)
+        {
+            double n = getDependency<Count>(*this);
+            if(n > weight)
+            {
+                using namespace vigra::multi_math;
+                diff_ = getDependency<Mean>(*this) - t;
+                acc_detail::updateFlatScatterMatrix(value_, diff_, n * weight / (n - weight));
+            }
+        }
+    };
+};
+
+// Covariance
+template <>
+class DivideByCount<FlatScatterMatrix>
+{
+  public:
+    typedef Select<FlatScatterMatrix, Count> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "DivideByCount<FlatScatterMatrix>";
+        // static const std::string n("DivideByCount<FlatScatterMatrix>");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U>
+    {
+        typedef CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U> BaseType;      
+        typedef typename BaseType::result_type result_type;
+        
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            int size = prod(s);
+            acc_detail::reshapeImpl(this->value_, Shape2(size,size));
+        }
+        
+        result_type operator()() const
+        {
+            if(this->isDirty())
+            {
+                acc_detail::flatScatterMatrixToCovariance(this->value_, getDependency<FlatScatterMatrix>(*this), getDependency<Count>(*this));
+                this->setClean();
+            }
+            return this->value_;
+        }
+    };
+};
+
+// UnbiasedCovariance
+template <>
+class DivideUnbiased<FlatScatterMatrix>
+{
+  public:
+    typedef Select<FlatScatterMatrix, Count> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "DivideUnbiased<FlatScatterMatrix>";
+        // static const std::string n("DivideUnbiased<FlatScatterMatrix>");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U>
+    {
+        typedef CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U> BaseType;      
+        typedef typename BaseType::result_type result_type;
+        
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            int size = prod(s);
+            acc_detail::reshapeImpl(this->value_, Shape2(size,size));
+        }
+        
+        result_type operator()() const
+        {
+            if(this->isDirty())
+            {
+                acc_detail::flatScatterMatrixToCovariance(this->value_, getDependency<FlatScatterMatrix>(*this), getDependency<Count>(*this) - 1.0);
+                this->setClean();
+            }
+            return this->value_;
+        }
+    };
+};
+
+/** Basic statistic. ScatterMatrixEigensystem (?)
+*/
+class ScatterMatrixEigensystem
+{
+  public:
+    typedef Select<FlatScatterMatrix> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "ScatterMatrixEigensystem";
+        // static const std::string n("ScatterMatrixEigensystem");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename AccumulatorResultTraits<U>::element_promote_type  element_type;
+        typedef typename AccumulatorResultTraits<U>::SumType               EigenvalueType;
+        typedef typename AccumulatorResultTraits<U>::CovarianceType        EigenvectorType;
+        typedef std::pair<EigenvalueType, EigenvectorType>                 value_type;
+        typedef value_type const &                                         result_type;
+
+        mutable value_type value_;
+        
+        Impl()
+        : value_()
+        {}
+        
+        void operator+=(Impl const & o)
+        {
+            if(!acc_detail::hasDataImpl(value_.second))
+            {
+                acc_detail::copyShapeImpl(o.value_.first, value_.first);
+                acc_detail::copyShapeImpl(o.value_.second, value_.second);
+            }
+            this->setDirty();
+        }
+
+        void update(U const &)
+        {
+            this->setDirty();
+        }
+        
+        void update(U const &, double)
+        {
+             this->setDirty();
+        }
+
+        void reset()
+        {
+            value_.first = element_type();
+            value_.second = element_type();
+            this->setClean();
+        }
+    
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            int size = prod(s);
+            acc_detail::reshapeImpl(value_.first, Shape1(size));
+            acc_detail::reshapeImpl(value_.second, Shape2(size,size));
+        }
+        
+        result_type operator()() const
+        {
+            if(this->isDirty())
+            {
+                compute(getDependency<FlatScatterMatrix>(*this), value_.first, value_.second);
+                this->setClean();
+            }
+            return value_;
+        }
+        
+      private:
+        template <class Flat, class EW, class EV>
+        static void compute(Flat const & flatScatter, EW & ew, EV & ev)
+        {
+            EigenvectorType scatter(ev.shape());
+            acc_detail::flatScatterMatrixToScatterMatrix(scatter, flatScatter);
+            // create a view because EW could be a TinyVector
+            MultiArrayView<2, element_type> ewview(Shape2(ev.shape(0), 1), &ew[0]);
+            symmetricEigensystem(scatter, ewview, ev);
+        }
+        
+        static void compute(double v, double & ew, double & ev)
+        {
+            ew = v;
+            ev = 1.0;
+        }
+    };
+};
+
+// CovarianceEigensystem
+template <>
+class DivideByCount<ScatterMatrixEigensystem>
+{
+  public:
+    typedef Select<ScatterMatrixEigensystem, Count> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "DivideByCount<ScatterMatrixEigensystem>";
+        // static const std::string n("DivideByCount<ScatterMatrixEigensystem>");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename LookupDependency<ScatterMatrixEigensystem, BASE>::type  SMImpl;
+        typedef typename SMImpl::element_type                             element_type;
+        typedef typename SMImpl::EigenvalueType                           EigenvalueType;
+        typedef typename SMImpl::EigenvectorType                          EigenvectorType;
+        typedef std::pair<EigenvalueType, EigenvectorType const &>        value_type;
+        typedef value_type const &                                        result_type;
+
+        mutable value_type value_;
+        
+        Impl()
+        : value_(EigenvalueType(), BASE::template call_getDependency<ScatterMatrixEigensystem>().second)
+        {}
+        
+        void operator+=(Impl const &)
+        {
+            this->setDirty();
+        }
+
+        void update(U const &)
+        {
+            this->setDirty();
+        }
+        
+        void update(U const &, double)
+        {
+             this->setDirty();
+        }
+
+        void reset()
+        {
+            value_.first = element_type();
+            this->setClean();
+        }
+    
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            int size = prod(s);
+            acc_detail::reshapeImpl(value_.first, Shape2(size,1));
+        }
+        
+        result_type operator()() const
+        {
+            if(this->isDirty())
+            {
+                value_.first = getDependency<ScatterMatrixEigensystem>(*this).first / getDependency<Count>(*this);
+                this->setClean();
+            }
+            return value_;
+        }
+    };
+};
+
+// alternative implementation of CovarianceEigensystem - solve eigensystem directly
+//
+// template <>
+// class DivideByCount<ScatterMatrixEigensystem>
+// {
+  // public:
+    // typedef Select<Covariance> Dependencies;
+    
+    // template <class U, class BASE>
+    // struct Impl
+    // : public BASE
+    // {
+        // typedef typename AccumulatorResultTraits<U>::element_promote_type  element_type;
+        // typedef typename AccumulatorResultTraits<U>::SumType               EigenvalueType;
+        // typedef typename AccumulatorResultTraits<U>::CovarianceType        EigenvectorType;
+        // typedef std::pair<EigenvalueType, EigenvectorType>                 value_type;
+        // typedef value_type const &                                         result_type;
+
+        // mutable value_type value_;
+        
+        // Impl()
+        // : value_()
+        // {}
+        
+        // void operator+=(Impl const &)
+        // {
+            // this->setDirty();
+        // }
+
+        // void update(U const &)
+        // {
+            // this->setDirty();
+        // }
+        
+        // void update(U const &, double)
+        // {
+             // this->setDirty();
+        // }
+
+        // void reset()
+        // {
+            // value_.first = element_type();
+            // value_.second = element_type();
+            // this->setClean();
+        // }
+    
+        // template <class Shape>
+        // void reshape(Shape const & s)
+        // {
+            // int size = prod(s);
+            // acc_detail::reshapeImpl(value_.first, Shape2(size,1));
+            // acc_detail::reshapeImpl(value_.second, Shape2(size,size));
+        // }
+        
+        // result_type operator()() const
+        // {
+            // if(this->isDirty())
+            // {
+                // compute(getDependency<Covariance>(*this), value_.first, value_.second);
+                // this->setClean();
+            // }
+            // return value_;
+        // }
+        
+      // private:
+        // template <class Cov, class EW, class EV>
+        // static void compute(Cov const & cov, EW & ew, EV & ev)
+        // {
+            // // create a view because EW could be a TinyVector
+            // MultiArrayView<2, element_type> ewview(Shape2(cov.shape(0), 1), &ew[0]);
+            // symmetricEigensystem(cov, ewview, ev);
+        // }
+        
+        // static void compute(double cov, double & ew, double & ev)
+        // {
+            // ew = cov;
+            // ev = 1.0;
+        // }
+    // };
+// };
+
+// covariance eigenvalues
+/** \brief Specialization (covariance eigenvalues): works in pass 1, %operator+=() supported (merging).
+*/
+template <>
+class Principal<PowerSum<2> >
+{
+  public:
+    typedef Select<ScatterMatrixEigensystem> Dependencies;
+     
+    static std::string name() 
+    { 
+        return "Principal<PowerSum<2> >";
+        // static const std::string n("Principal<PowerSum<2> >");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename LookupDependency<ScatterMatrixEigensystem, BASE>::type::EigenvalueType value_type;
+        typedef value_type const &                                                       result_type;
+        
+        result_type operator()() const
+        {
+            return getDependency<ScatterMatrixEigensystem>(*this).first;
+        }
+    };
+};
+
+
+// Principal<CoordinateSystem> == covariance eigenvectors
+/** \brief Specialization (covariance eigenvectors): works in pass 1, %operator+=() supported (merging).
+*/
+template <>
+class Principal<CoordinateSystem>
+{
+  public:
+    typedef Select<ScatterMatrixEigensystem> Dependencies;
+     
+    static std::string name() 
+    { 
+        return "Principal<CoordinateSystem>";
+        // static const std::string n("Principal<CoordinateSystem>");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename LookupDependency<ScatterMatrixEigensystem, BASE>::type::EigenvectorType value_type;
+        typedef value_type const &                                                        result_type;
+        
+        result_type operator()() const
+        {
+            return getDependency<ScatterMatrixEigensystem>(*this).second;
+        }
+    };
+};
+
+/** \brief Basic statistic. %Minimum value.
+
+    Works in pass 1, %operator+=() supported (merging supported).
+*/
+class Minimum
+{
+  public:
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "Minimum";
+        // static const std::string n("Minimum");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename AccumulatorResultTraits<U>::element_type element_type;
+        typedef typename AccumulatorResultTraits<U>::MinmaxType   value_type;
+        typedef value_type const &                                result_type;
+
+        value_type value_;
+        
+        Impl()
+        {
+            value_ = NumericTraits<element_type>::max();
+        }
+        
+        void reset()
+        {
+            value_ = NumericTraits<element_type>::max();
+        }
+    
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            acc_detail::reshapeImpl(value_, s, NumericTraits<element_type>::max());
+        }
+        
+        void operator+=(Impl const & o)
+        {
+            updateImpl(o.value_); // necessary because std::min causes ambiguous overload
+        }
+    
+        void update(U const & t)
+        {
+            updateImpl(t);
+        }
+        
+        void update(U const & t, double)
+        {
+            updateImpl(t);
+        }
+        
+        result_type operator()() const
+        {
+            return value_;
+        }
+        
+      private:
+        template <class T>
+        void updateImpl(T const & o)
+        {
+            using namespace multi_math;
+            value_ = min(value_, o);
+        }
+        
+        template <class T, class Alloc>
+        void updateImpl(MultiArray<1, T, Alloc> const & o)
+        {
+            value_ = multi_math::min(value_, o);
+        }
+    };
+};
+
+/** \brief Basic statistic. %Maximum value.
+
+    Works in pass 1, %operator+=() supported (merging supported).
+*/
+class Maximum
+{
+  public:
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "Maximum";
+        // static const std::string n("Maximum");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename AccumulatorResultTraits<U>::element_type element_type;
+        typedef typename AccumulatorResultTraits<U>::MinmaxType   value_type;
+        typedef value_type const &                                result_type;
+
+        value_type value_;
+        
+        Impl()
+        {
+            value_ = NumericTraits<element_type>::min();
+        }
+        
+        void reset()
+        {
+            value_ = NumericTraits<element_type>::min();
+        }
+    
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            acc_detail::reshapeImpl(value_, s, NumericTraits<element_type>::min());
+        }
+        
+        void operator+=(Impl const & o)
+        {
+            updateImpl(o.value_); // necessary because std::max causes ambiguous overload
+        }
+    
+        void update(U const & t)
+        {
+            updateImpl(t);
+        }
+        
+        void update(U const & t, double)
+        {
+            updateImpl(t);
+        }
+        
+        result_type operator()() const
+        {
+            return value_;
+        }
+        
+      private:
+        template <class T>
+        void updateImpl(T const & o)
+        {
+            using namespace multi_math;
+            value_ = max(value_, o);
+        }
+        
+        template <class T, class Alloc>
+        void updateImpl(MultiArray<1, T, Alloc> const & o)
+        {
+            value_ = multi_math::max(value_, o);
+        }
+    };
+};
+
+/** \brief Basic statistic. Data value where weight assumes its minimal value. 
+
+    Weights must be given. Coord<ArgMinWeight> gives coordinate where weight assumes its minimal value. Works in pass 1, %operator+=() supported (merging supported).
+*/
+class ArgMinWeight
+{
+  public:
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "ArgMinWeight";
+        // static const std::string n("ArgMinWeight");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename AccumulatorResultTraits<U>::element_type element_type;
+        typedef typename AccumulatorResultTraits<U>::MinmaxType   value_type;
+        typedef value_type const &                                result_type;
+
+        double min_weight_;
+        value_type value_;
+        
+        Impl()
+        : min_weight_(NumericTraits<double>::max()),
+          value_()
+        {}
+        
+        void reset()
+        {
+            min_weight_ = NumericTraits<double>::max();
+            value_ = element_type();
+        }
+    
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            acc_detail::reshapeImpl(value_, s);
+        }
+        
+        void operator+=(Impl const & o)
+        {
+            using namespace multi_math;
+            if(o.min_weight_ < min_weight_)
+            {
+                min_weight_ = o.min_weight_;
+                value_ = o.value_;
+            }
+        }
+    
+        void update(U const & t)
+        {
+            vigra_precondition(false, "ArgMinWeight::update() needs weights.");
+        }
+        
+        void update(U const & t, double weight)
+        {
+            if(weight < min_weight_)
+            {
+                min_weight_ = weight;
+                value_ = t;
+            }
+        }
+        
+        result_type operator()() const
+        {
+            return value_;
+        }
+    };
+};
+
+/** \brief Basic statistic. Data where weight assumes its maximal value. 
+
+    Weights must be given. Coord<ArgMinWeight> gives coordinate where weight assumes its maximal value. Works in pass 1, %operator+=() supported (merging supported).
+*/
+class ArgMaxWeight
+{
+  public:
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return "ArgMaxWeight";
+        // static const std::string n("ArgMaxWeight");
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public BASE
+    {
+        typedef typename AccumulatorResultTraits<U>::element_type element_type;
+        typedef typename AccumulatorResultTraits<U>::MinmaxType   value_type;
+        typedef value_type const &                                result_type;
+
+        double max_weight_;
+        value_type value_;
+        
+        Impl()
+        : max_weight_(NumericTraits<double>::min()),
+          value_()
+        {}
+        
+        void reset()
+        {
+            max_weight_ = NumericTraits<double>::min();
+            value_ = element_type();
+        }
+    
+        template <class Shape>
+        void reshape(Shape const & s)
+        {
+            acc_detail::reshapeImpl(value_, s);
+        }
+        
+        void operator+=(Impl const & o)
+        {
+            using namespace multi_math;
+            if(o.max_weight_ > max_weight_)
+            {
+                max_weight_ = o.max_weight_;
+                value_ = o.value_;
+            }
+        }
+    
+        void update(U const & t)
+        {
+            vigra_precondition(false, "ArgMaxWeight::update() needs weights.");
+        }
+        
+        void update(U const & t, double weight)
+        {
+            if(weight > max_weight_)
+            {
+                max_weight_ = weight;
+                value_ = t;
+            }
+        }
+        
+        result_type operator()() const
+        {
+            return value_;
+        }
+    };
+};
+
+
+template <class BASE, int BinCount>
+class HistogramBase
+: public BASE
+{
+  public:
+  
+    typedef double                        element_type;
+    typedef TinyVector<double, BinCount>  value_type;
+    typedef value_type const &            result_type;
+    
+    value_type value_;
+    double left_outliers, right_outliers;
+    
+    HistogramBase()
+    : value_(),
+      left_outliers(), 
+      right_outliers()
+    {}
+    
+    void reset()
+    {
+        value_ = element_type();
+        left_outliers = 0.0;
+        right_outliers = 0.0;
+    }
+
+    void operator+=(HistogramBase const & o)
+    {
+        value_ += o.value_;
+        left_outliers += o.left_outliers;
+        right_outliers += o.right_outliers;
+    }
+        
+    result_type operator()() const
+    {
+        return value_;
+    }
+};
+
+template <class BASE>
+class HistogramBase<BASE, 0>
+: public BASE
+{
+  public:
+  
+    typedef double                        element_type;
+    typedef MultiArray<1, double>         value_type;
+    typedef value_type const &            result_type;
+    
+    value_type value_;
+    double left_outliers, right_outliers;
+    
+    HistogramBase()
+    : value_(),
+      left_outliers(), 
+      right_outliers()
+    {}
+    
+    void reset()
+    {
+        value_ = element_type();
+        left_outliers = 0.0;
+        right_outliers = 0.0;
+    }
+    
+    void operator+=(HistogramBase const & o)
+    {
+        if(value_.size() == 0)
+        {
+            value_ = o.value_;
+        }
+        else if(o.value_.size() > 0)
+        {
+            vigra_precondition(value_.size() == o.value_.size(),
+                "HistogramBase::operator+=(): bin counts must be equal.");
+            value_ += o.value_;
+        }
+        left_outliers += o.left_outliers;
+        right_outliers += o.right_outliers;
+    }
+        
+    void setBinCount(int binCount)
+    {
+        vigra_precondition(binCount > 0,
+            "HistogramBase:.setBinCount(): binCount > 0 required.");
+        value_type(Shape1(binCount)).swap(value_);
+    }
+
+    result_type operator()() const
+    {
+        return value_;
+    }
+};
+
+template <class BASE, int BinCount, class U=typename BASE::input_type>
+class RangeHistogramBase
+: public HistogramBase<BASE, BinCount>
+{
+  public:
+    double scale_, offset_, inverse_scale_;
+    
+    RangeHistogramBase()
+    : scale_(),
+      offset_(), 
+      inverse_scale_()
+    {}
+    
+    void reset()
+    {
+        scale_ = 0.0;
+        offset_ = 0.0;
+        inverse_scale_ = 0.0;
+        HistogramBase<BASE, BinCount>::reset();
+    }
+
+    void operator+=(RangeHistogramBase const & o)
+    {
+        vigra_precondition(scale_ == 0.0 || o.scale_ == 0.0 || (scale_ == o.scale_ && offset_ == o.offset_),
+            "RangeHistogramBase::operator+=(): cannot merge histograms with different data mapping.");
+        
+        HistogramBase<BASE, BinCount>::operator+=(o);
+        if(scale_ == 0.0)
+        {
+            scale_ = o.scale_;
+            offset_ = o.offset_;
+            inverse_scale_ = o.inverse_scale_;
+        }
+    }
+
+    void update(U const & t)
+    {
+        update(t, 1.0);
+    }
+    
+    void update(U const & t, double weight)
+    {
+        double m = mapItem(t);
+        int index =  (m == (double)this->value_.size())
+                       ? (int)m - 1
+                       : (int)m;
+        if(index < 0)
+            this->left_outliers += weight;
+        else if(index >= (int)this->value_.size())
+            this->right_outliers += weight;
+        else
+            this->value_[index] += weight;
+    }
+    
+    void setMinMax(double mi, double ma)
+    {
+        vigra_precondition(this->value_.size() > 0,
+            "RangeHistogramBase::setMinMax(...): setBinCount(...) has not been called.");
+        vigra_precondition(mi < ma,
+            "RangeHistogramBase::setMinMax(...): min < max required.");
+        offset_ = mi;
+        scale_ = (double)this->value_.size() / (ma - mi);
+        inverse_scale_ = 1.0 / scale_;
+    }
+    
+    double mapItem(double t) const
+    {
+        return scale_ * (t - offset_);
+    }
+    
+    double mapItemInverse(double t) const
+    {
+        return inverse_scale_ * t + offset_;
+    }
+    
+    template <class ArrayLike>
+    void computeStandardQuantiles(double minimum, double maximum, double count, 
+                                  ArrayLike const & desiredQuantiles, ArrayLike & res) const
+    {
+        if(count == 0.0) {
+            return;
+        }
+        
+        ArrayVector<double> keypoints, cumhist;
+        double mappedMinimum = mapItem(minimum);
+        double mappedMaximum = mapItem(maximum);
+        
+        keypoints.push_back(mappedMinimum);
+        cumhist.push_back(0.0);
+        
+        if(this->left_outliers > 0.0)
+        {
+            keypoints.push_back(0.0);
+            cumhist.push_back(this->left_outliers);
+        }
+        
+        int size = (int)this->value_.size();
+        double cumulative = this->left_outliers;
+        for(int k=0; k<size; ++k)
+        {
+            if(this->value_[k] > 0.0)
+            {
+                if(keypoints.back() <= k)
+                {
+                    keypoints.push_back(k);
+                    cumhist.push_back(cumulative);
+                }
+                cumulative += this->value_[k];
+                keypoints.push_back(k+1);
+                cumhist.push_back(cumulative);
+            }
+        }
+        
+        if(this->right_outliers > 0.0)
+        {
+            if(keypoints.back() != size)
+            {
+                keypoints.push_back(size);
+                cumhist.push_back(cumulative);
+            }
+            keypoints.push_back(mappedMaximum);
+            cumhist.push_back(count);
+        }
+        else
+        {
+            keypoints.back() = mappedMaximum;
+            cumhist.back() = count;
+        }
+        
+        int quantile = 0, end = (int)desiredQuantiles.size();
+        
+        if(desiredQuantiles[0] == 0.0)
+        {
+            res[0] = minimum;
+            ++quantile;
+        }
+        if(desiredQuantiles[end-1] == 1.0)
+        {
+            res[end-1] = maximum;
+            --end;
+        }
+        
+        int point = 0;
+        double qcount = count * desiredQuantiles[quantile];
+        while(quantile < end)
+        {
+            if(cumhist[point] < qcount && cumhist[point+1] >= qcount)
+            {
+                double t = (qcount - cumhist[point]) / (cumhist[point+1] - cumhist[point]) * (keypoints[point+1] - keypoints[point]);
+                res[quantile] = mapItemInverse(t + keypoints[point]);
+                ++quantile;
+                qcount = count * desiredQuantiles[quantile];
+            }
+            else
+            {
+                ++point;
+            }
+        }
+    }
+};
+
+/** \brief Histogram where data values are equal to bin indices.
+
+    - If BinCount != 0, the return type of the accumulator is TinyVector<double, BinCount> .
+    - If BinCount == 0, the return type of the accumulator is MultiArray<1, double> . BinCount can be set by calling getAccumulator<IntegerHistogram<0> >(acc_chain).setBinCount(bincount).  
+    - Outliers can be accessed via getAccumulator<IntegerHistogram<Bincount>>(a).left_outliers and getAccumulator<...>(acc_chain).right_outliers.
+    - Note that histogram options (for all histograms in the accumulator chain) can also be set by passing an instance of HistogramOptions to the accumulator chain via acc_chain.setHistogramOptions().
+    Works in pass 1, %operator+=() supported (merging supported).
+*/
+template <int BinCount>
+class IntegerHistogram
+{
+  public:
+    
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("IntegerHistogram<") + asString(BinCount) + ">";
+        // static const std::string n = std::string("IntegerHistogram<") + asString(BinCount) + ">";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public HistogramBase<BASE, BinCount>
+    {
+        void update(int index)
+        {
+            if(index < 0)
+                ++this->left_outliers;
+            else if(index >= (int)this->value_.size())
+                ++this->right_outliers;
+            else
+                ++this->value_[index];
+        }
+        
+        void update(int index, double weight)
+        {
+            // cannot compute quantile from weighted integer histograms,
+            // so force people to use UserRangeHistogram or AutoRangeHistogram
+            vigra_precondition(false, "IntegerHistogram::update(): weighted histograms not supported, use another histogram type.");
+        }
+    
+        template <class ArrayLike>
+        void computeStandardQuantiles(double minimum, double maximum, double count, 
+                                      ArrayLike const & desiredQuantiles, ArrayLike & res) const
+        {
+            int quantile = 0, end = (int)desiredQuantiles.size();
+            
+            if(desiredQuantiles[0] == 0.0)
+            {
+                res[0] = minimum;
+                ++quantile;
+            }
+            if(desiredQuantiles[end-1] == 1.0)
+            {
+                res[end-1] = maximum;
+                --end;
+            }
+            
+            count -= 1.0;
+            int currentBin = 0, size = (int)this->value_.size();
+            double cumulative1 = this->left_outliers,
+                   cumulative2 = this->value_[currentBin] + cumulative1;
+            
+            // add a to the quantiles to account for the fact that counting
+            // corresponds to 1-based indexing (one element == index 1)
+            double qcount = desiredQuantiles[quantile]*count + 1.0;
+            
+            while(quantile < end)
+            {
+                if(cumulative2 == qcount)
+                {
+                    res[quantile] = currentBin;
+                    ++quantile;
+                    qcount = desiredQuantiles[quantile]*count + 1.0;
+                }
+                else if(cumulative2 > qcount)
+                {
+                    if(cumulative1 > qcount) // in left_outlier bin
+                    {
+                        res[quantile] = minimum;
+                    }
+                    if(cumulative1 + 1.0 > qcount) // between bins
+                    {
+                        res[quantile] = currentBin - 1 + qcount - std::floor(qcount);
+                    }
+                    else // standard case
+                    {
+                        res[quantile] = currentBin;
+                    }
+                    ++quantile;
+                    qcount = desiredQuantiles[quantile]*count + 1.0;
+                }
+                else if(currentBin == size-1) // in right outlier bin
+                {
+                    res[quantile] = maximum;
+                    ++quantile;
+                    qcount = desiredQuantiles[quantile]*count + 1.0;
+                }
+                else
+                {
+                    ++currentBin;
+                    cumulative1 = cumulative2;
+                    cumulative2 += this->value_[currentBin];
+                }
+            }
+        }
+    };
+};
+
+/** \brief Histogram where user provides bounds for linear range mapping from values to indices.
+
+    - If BinCount != 0, the return type of the accumulator is TinyVector<double, BinCount> .
+    - If BinCount == 0, the return type of the accumulator is MultiArray<1, double> . BinCount can be set by calling getAccumulator<UserRangeHistogram<0> >(acc_chain).setBinCount(bincount).
+    - Bounds for the mapping (min/max) must be set before seeing data by calling getAccumulator<UserRangeHistogram<BinCount> >.setMinMax(min, max).
+    - Options can also be passed to the accumulator chain via an instance of HistogramOptions .
+    - Works in pass 1, %operator+=() is supported (merging) if both histograms have the same data mapping.
+    - Outliers can be accessed via getAccumulator<...>(a).left_outliers and getAccumulator<...>(a).right_outliers.
+    - Note that histogram options (for all histograms in the accumulator chain) can also be set by passing an instance of HistogramOptions to the accumulator chain via acc_chain.setHistogramOptions().
+*/
+template <int BinCount>
+class UserRangeHistogram
+{
+  public:
+    
+    typedef Select<> Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("UserRangeHistogram<") + asString(BinCount) + ">";
+        // static const std::string n = std::string("UserRangeHistogram<") + asString(BinCount) + ">";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public RangeHistogramBase<BASE, BinCount, U>
+    {
+        void update(U const & t)
+        {
+            update(t, 1.0);
+        }
+        
+        void update(U const & t, double weight)
+        {
+            vigra_precondition(this->scale_ != 0.0,
+                "UserRangeHistogram::update(): setMinMax(...) has not been called.");
+                
+            RangeHistogramBase<BASE, BinCount, U>::update(t, weight);
+        }
+    };
+};
+
+/** \brief Histogram where range mapping bounds are defined by minimum and maximum of data.
+
+    - If BinCount != 0, the return type of the accumulator is TinyVector<double, BinCount> .
+    - If BinCount == 0, the return type of the accumulator is MultiArray<1, double> . BinCount can be set by calling getAccumulator<AutoRangeHistogram>(acc_chain).setBinCount(bincount).
+    - Becomes a UserRangeHistogram if min/max is set.
+    - Works in pass 2, %operator+=() is supported (merging) if both histograms have the same data mapping.
+    - Outliers can be accessed via getAccumulator<...>(acc_chain).left_outliers and getAccumulator<...>(acc_chain).right_outliers .
+    - Note that histogram options (for all histograms in the accumulator chain) can also be set by passing an instance of HistogramOptions to the accumulator chain via acc_chain.setHistogramOptions().
+*/
+template <int BinCount>
+class AutoRangeHistogram
+{
+  public:
+    
+    typedef Select<Minimum, Maximum> Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("AutoRangeHistogram<") + asString(BinCount) + ">";
+        // static const std::string n = std::string("AutoRangeHistogram<") + asString(BinCount) + ">";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public RangeHistogramBase<BASE, BinCount, U>
+    {
+        static const unsigned int workInPass = LookupDependency<Minimum, BASE>::type::workInPass + 1;
+        
+        void update(U const & t)
+        {
+            update(t, 1.0);
+        }
+        
+        void update(U const & t, double weight)
+        {
+            if(this->scale_ == 0.0)
+                this->setMinMax(getDependency<Minimum>(*this), getDependency<Maximum>(*this));
+                
+            RangeHistogramBase<BASE, BinCount, U>::update(t, weight);
+        }
+    };
+};
+
+/** \brief Like AutoRangeHistogram, but use global min/max rather than region min/max.
+
+    - If BinCount != 0, the return type of the accumulator is TinyVector<double, BinCount> .
+    - If BinCount == 0, the return type of the accumulator is MultiArray<1, double> . BinCount can be set by calling getAccumulator<GlobalRangeHistogram<0>>(acc_chain).setBinCount(bincount).
+    - Becomes a UserRangeHistogram if min/max is set.
+    - Works in pass 2, %operator+=() is supported (merging) if both histograms have the same data mapping.
+    - Outliers can be accessed via getAccumulator<GlobalRangeHistogram<Bincount>>(acc_chain).left_outliers and getAccumulator<...>(acc_chain).right_outliers .
+    - Histogram options (for all histograms in the accumulator chain) can also be set by passing an instance of HistogramOptions to the accumulator chain via acc_chain.setHistogramOptions().
+*/
+template <int BinCount>
+class GlobalRangeHistogram
+{
+  public:
+    
+    typedef Select<Global<Minimum>, Global<Maximum>, Minimum, Maximum> Dependencies;
+    
+    static std::string name() 
+    { 
+        return std::string("GlobalRangeHistogram<") + asString(BinCount) + ">";
+        // static const std::string n = std::string("GlobalRangeHistogram<") + asString(BinCount) + ">";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public RangeHistogramBase<BASE, BinCount, U>
+    {
+        static const unsigned int workInPass = LookupDependency<Minimum, BASE>::type::workInPass + 1;
+        
+        bool useLocalMinimax_;
+        
+        Impl()
+        : useLocalMinimax_(false)
+        {}
+        
+        void setRegionAutoInit(bool locally)
+        {
+            this->scale_ = 0.0;
+            useLocalMinimax_ = locally;
+        }
+        
+        void update(U const & t)
+        {
+            update(t, 1.0);
+        }
+        
+        void update(U const & t, double weight)
+        {
+            if(this->scale_ == 0.0)
+            {
+                if(useLocalMinimax_)
+                    this->setMinMax(getDependency<Minimum>(*this), getDependency<Maximum>(*this));
+                else
+                    this->setMinMax(getDependency<Global<Minimum> >(*this), getDependency<Global<Maximum> >(*this));
+            }
+            
+            RangeHistogramBase<BASE, BinCount, U>::update(t, weight);
+        }
+    };
+};
+
+/** \brief Compute (0%, 10%, 25%, 50%, 75%, 90%, 100%) quantiles from given histogram.
+
+    Return type is TinyVector<double, 7> . 
+*/
+template <class HistogramAccumulator> 
+class StandardQuantiles
+{
+  public:
+    
+    typedef typename StandardizeTag<HistogramAccumulator>::type HistogramTag;
+    typedef Select<HistogramTag, Minimum, Maximum, Count> Dependencies;
+
+    static std::string name() 
+    { 
+        return std::string("StandardQuantiles<") + HistogramTag::name() + " >";
+        // static const std::string n = std::string("StandardQuantiles<") + HistogramTag::name() + " >";
+        // return n;
+    }
+    
+    template <class U, class BASE>
+    struct Impl
+    : public CachedResultBase<BASE, TinyVector<double, 7>, U>
+    {
+        typedef typename CachedResultBase<BASE, TinyVector<double, 7>, U>::result_type result_type;
+        typedef typename CachedResultBase<BASE, TinyVector<double, 7>, U>::value_type  value_type;
+        
+        static const unsigned int workInPass = LookupDependency<HistogramTag, BASE>::type::workInPass;
+        
+        result_type operator()() const
+        {
+            if(this->isDirty())
+            {
+                double desiredQuantiles[] = {0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0 };
+                getAccumulator<HistogramTag>(*this).computeStandardQuantiles(getDependency<Minimum>(*this), getDependency<Maximum>(*this), 
+                                                                             getDependency<Count>(*this), value_type(desiredQuantiles), 
+                                                                             this->value_);
+                this->setClean();
+            }
+            return this->value_;
+        }
+    };
+};
+
+}} // namespace vigra::acc
+
+#endif // VIGRA_ACCUMULATOR_HXX
diff --git a/include/vigra/affine_registration.hxx b/include/vigra/affine_registration.hxx
new file mode 100644
index 0000000..e608d97
--- /dev/null
+++ b/include/vigra/affine_registration.hxx
@@ -0,0 +1,806 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2005-2006 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+#ifndef VIGRA_AFFINE_REGISTRATION_HXX
+#define VIGRA_AFFINE_REGISTRATION_HXX
+
+#include "mathutil.hxx"
+#include "matrix.hxx"
+#include "linear_solve.hxx"
+#include "tinyvector.hxx"
+#include "splineimageview.hxx"
+#include "imagecontainer.hxx"
+#include "multi_shape.hxx"
+
+#include <cmath>
+
+namespace vigra {
+
+/** \addtogroup Registration Image Registration
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*       affineMatrix2DFromCorrespondingPoints          */
+/*                                                      */
+/********************************************************/
+
+/** \brief Create homogeneous matrix that maps corresponding points onto each other.
+ 
+    For use with \ref affineWarpImage(). When only two corresponding points are given,
+    the matrix will only represent a similarity transform 
+    (translation, rotation, and uniform scaling). When only one point pair is given,
+    the result will be a pure translation.
+*/
+template <class SrcIterator, class DestIterator>
+linalg::TemporaryMatrix<double> 
+affineMatrix2DFromCorrespondingPoints(SrcIterator s, SrcIterator send, DestIterator d)
+{
+    int size = send - s;
+    
+    linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
+
+    if(size == 1)
+    {
+        ret(0,2) = (*d)[0] - (*s)[0];
+        ret(1,2) = (*d)[1] - (*s)[1];
+    }
+    else if(size == 2)
+    {
+        Matrix<double> m(4,4), r(4,1), so(4,1);
+        
+        for(int k=0; k<size; ++k, ++s, ++d)
+        {
+            m(2*k,0) = (*s)[0];
+            m(2*k,1) = -(*s)[1];
+            m(2*k,2) = 1.0;
+            m(2*k,3) = 0.0;
+            r(2*k,0) = (*d)[0];
+            
+            m(2*k+1,0) = (*s)[1];
+            m(2*k+1,1) = (*s)[0];
+            m(2*k+1,2) = 0.0;
+            m(2*k+1,3) = 1.0;
+            r(2*k+1,0) = (*d)[1];
+        }
+    
+        if(!linearSolve(m, r, so))
+            vigra_fail("affineMatrix2DFromCorrespondingPoints(): singular solution matrix.");
+        
+        ret(0,0) = so(0,0);
+        ret(1,1) = so(0,0);
+        ret(0,1) = -so(1,0);
+        ret(1,0) = so(1,0);
+        ret(0,2) = so(2,0);
+        ret(1,2) = so(3,0);
+    }
+    else if(size >= 3)
+    {
+        Matrix<double> m(3,3),  rx(3,1), sx(3,1), ry(3,1), sy(3,1), c(3,1);
+        c(2,0) = 1.0;
+        for(int k=0; k<size; ++k, ++s, ++d)
+        {
+            c(0,0) = (*s)[0];
+            c(1,0) = (*s)[1];
+            
+            m  += outer(c);
+            rx += (*d)[0]*c;
+            ry += (*d)[1]*c;
+        }
+    
+        if(!linearSolve(m, rx, sx) || !linearSolve(m, ry, sy))
+            vigra_fail("affineMatrix2DFromCorrespondingPoints(): singular solution matrix.");
+        
+        ret(0,0) = sx(0,0);
+        ret(0,1) = sx(1,0);
+        ret(0,2) = sx(2,0);
+        ret(1,0) = sy(0,0);
+        ret(1,1) = sy(1,0);
+        ret(1,2) = sy(2,0);
+    }
+
+    return ret;
+}
+
+template <int SPLINEORDER = 2>
+class AffineMotionEstimationOptions
+{
+  public:
+    double burt_filter_strength;
+    int highest_level, iterations_per_level;
+    bool use_laplacian_pyramid;
+    
+    AffineMotionEstimationOptions()
+    : burt_filter_strength(0.4),
+      highest_level(4),
+      iterations_per_level(4),
+      use_laplacian_pyramid(false)
+    {}
+    
+    template <int ORDER>
+    AffineMotionEstimationOptions(AffineMotionEstimationOptions<ORDER>  const & other)
+    : burt_filter_strength(other.burt_filter_strength),
+      highest_level(other.highest_level),
+      iterations_per_level(other.iterations_per_level),
+      use_laplacian_pyramid(other.use_laplacian_pyramid)
+    {}
+    
+    template <int NEWORDER>
+    AffineMotionEstimationOptions<NEWORDER> splineOrder() const
+    {
+        return AffineMotionEstimationOptions<NEWORDER>(*this);
+    }
+    
+    AffineMotionEstimationOptions & burtFilterStrength(double strength)
+    {
+        vigra_precondition(0.25 <= strength && strength <= 0.5,
+          "AffineMotionEstimationOptions::burtFilterStrength(): strength must be between 0.25 and 0.5 (inclusive).");
+        burt_filter_strength = strength;
+        return *this;
+    }
+    
+    AffineMotionEstimationOptions & highestPyramidLevel(unsigned int level)
+    {
+        highest_level = (int)level;
+        return *this;
+    }
+    
+    AffineMotionEstimationOptions & iterationsPerLevel(unsigned int iter)
+    {
+        vigra_precondition(0 < iter,
+          "AffineMotionEstimationOptions::iterationsPerLevel(): must do at least one iteration per level.");
+        iterations_per_level = (int)iter;
+        return *this;
+    }
+    
+    AffineMotionEstimationOptions & useGaussianPyramid(bool f = true)
+    {
+        use_laplacian_pyramid = !f;
+        return *this;
+    }
+    
+    AffineMotionEstimationOptions & useLaplacianPyramid(bool f = true)
+    {
+        use_laplacian_pyramid = f;
+        return *this;
+    }
+};
+
+namespace detail {
+
+struct TranslationEstimationFunctor
+{
+    template <class SplineImage, class Image>
+    void operator()(SplineImage const & src, Image const & dest, Matrix<double> & matrix) const
+    {
+        int w = dest.width();
+        int h = dest.height();
+        
+        Matrix<double> grad(2,1), m(2,2), r(2,1), s(2,1);
+        double dx = matrix(0,0), dy = matrix(1,0);
+        
+        for(int y = 0; y < h; ++y)
+        {
+            double sx = matrix(0,1)*y + matrix(0,2);
+            double sy = matrix(1,1)*y + matrix(1,2);
+            for(int x = 0; x < w; ++x, sx += dx, sy += dy)
+            {
+                if(!src.isInside(sx, sy))
+                    continue;
+                  
+                grad(0,0) = src.dx(sx, sy);
+                grad(1,0) = src.dy(sx, sy);
+                double diff = dest(x, y) - src(sx, sy);
+                
+                m += outer(grad);
+                r -= diff*grad;
+            }
+        }
+        
+        linearSolve(m, r, s);
+        
+        matrix(0,2) -= s(0,0);
+        matrix(1,2) -= s(1,0);
+    }
+};
+
+struct SimilarityTransformEstimationFunctor
+{
+    template <class SplineImage, class Image>
+    void operator()(SplineImage const & src, Image const & dest, Matrix<double> & matrix) const
+    {
+        int w = dest.width();
+        int h = dest.height();
+        
+        Matrix<double> grad(2,1), coord(4, 2), c(4, 1), m(4, 4), r(4,1), s(4,1);
+        coord(0,0) = 1.0;
+        coord(1,1) = 1.0;
+        double dx = matrix(0,0), dy = matrix(1,0);
+        
+        for(int y = 0; y < h; ++y)
+        {
+            double sx = matrix(0,1)*y + matrix(0,2);
+            double sy = matrix(1,1)*y + matrix(1,2);
+            for(int x = 0; x < w; ++x, sx += dx, sy += dy)
+            {
+                if(!src.isInside(sx, sy))
+                    continue;
+                  
+                grad(0,0) = src.dx(sx, sy);
+                grad(1,0) = src.dy(sx, sy);
+                coord(2,0) = (double)x;
+                coord(3,1) = (double)x;
+                coord(3,0) = -(double)y;
+                coord(2,1) = (double)y;
+                double diff = dest(x, y) - src(sx, sy);
+                
+                c = coord * grad;
+                m += outer(c);
+                r -= diff*c;
+            }
+        }
+        
+        linearSolve(m, r, s);
+        
+        matrix(0,2) -= s(0,0);
+        matrix(1,2) -= s(1,0);
+        matrix(0,0) -= s(2,0);
+        matrix(1,1) -= s(2,0);
+        matrix(0,1) += s(3,0);
+        matrix(1,0) -= s(3,0);
+    }
+};
+
+struct AffineTransformEstimationFunctor
+{
+    template <class SplineImage, class Image>
+    void operator()(SplineImage const & src, Image const & dest, Matrix<double> & matrix) const
+    {
+        int w = dest.width();
+        int h = dest.height();
+        
+        Matrix<double> grad(2,1), coord(6, 2), c(6, 1), m(6,6), r(6,1), s(6,1);
+        coord(0,0) = 1.0;
+        coord(1,1) = 1.0;
+        double dx = matrix(0,0), dy = matrix(1,0);
+        
+        for(int y = 0; y < h; ++y)
+        {
+            double sx = matrix(0,1)*y + matrix(0,2);
+            double sy = matrix(1,1)*y + matrix(1,2);
+            for(int x = 0; x < w; ++x, sx += dx, sy += dy)
+            {
+                if(!src.isInside(sx, sy))
+                    continue;
+                  
+                grad(0,0) = src.dx(sx, sy);
+                grad(1,0) = src.dy(sx, sy);
+                coord(2,0) = (double)x;
+                coord(4,1) = (double)x;
+                coord(3,0) = (double)y;
+                coord(5,1) = (double)y;
+                double diff = dest(x, y) - src(sx, sy);
+                
+                c = coord * grad;
+                m += outer(c);
+                r -= diff*c;
+            }
+        }
+        
+        linearSolve(m, r, s);
+        
+        matrix(0,2) -= s(0,0);
+        matrix(1,2) -= s(1,0);
+        matrix(0,0) -= s(2,0);
+        matrix(0,1) -= s(3,0);
+        matrix(1,0) -= s(4,0);
+        matrix(1,1) -= s(5,0);
+    }
+};
+
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor, 
+          int SPLINEORDER, class Functor>
+void 
+estimateAffineMotionImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                         DestIterator dul, DestIterator dlr, DestAccessor dest,
+                         Matrix<double> & affineMatrix, 
+                         AffineMotionEstimationOptions<SPLINEORDER> const & options,
+                         Functor motionModel)
+{
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote STmpType;
+    typedef BasicImage<STmpType> STmpImage;
+    typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote DTmpType;
+    typedef BasicImage<DTmpType> DTmpImage;
+    
+    int toplevel = options.highest_level;
+    ImagePyramid<STmpImage> srcPyramid(0, toplevel, sul, slr, src);
+    ImagePyramid<DTmpImage> destPyramid(0, toplevel, dul, dlr, dest);
+    
+    if(options.use_laplacian_pyramid)
+    {
+        pyramidReduceBurtLaplacian(srcPyramid, 0, toplevel, options.burt_filter_strength);
+        pyramidReduceBurtLaplacian(destPyramid, 0, toplevel, options.burt_filter_strength);
+    }
+    else
+    {
+        pyramidReduceBurtFilter(srcPyramid, 0, toplevel, options.burt_filter_strength);
+        pyramidReduceBurtFilter(destPyramid, 0, toplevel, options.burt_filter_strength);
+    }
+        
+    Matrix<double> currentMatrix(affineMatrix(2,2) == 0.0 
+                                    ? identityMatrix<double>(3)
+                                    : affineMatrix);
+    currentMatrix(0,2) /= std::pow(2.0, toplevel);
+    currentMatrix(1,2) /= std::pow(2.0, toplevel);
+    
+    for(int level = toplevel; level >= 0; --level)
+    {
+        SplineImageView<SPLINEORDER, STmpType> sp(srcImageRange(srcPyramid[level]));
+        
+        for(int iter = 0; iter < options.iterations_per_level; ++iter)
+        {
+            motionModel(sp, destPyramid[level], currentMatrix);
+        }
+        
+        if(level > 0)
+        {
+            currentMatrix(0,2) *= 2.0;
+            currentMatrix(1,2) *= 2.0;
+        }
+    }
+    
+    affineMatrix = currentMatrix;
+}
+
+} // namespace detail 
+
+/********************************************************/
+/*                                                      */
+/*                 estimateTranslation                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Estimate the optical flow between two images according to a translation model.
+
+    Sorry, no \ref detailedDocumentation() available yet.
+
+    <b> Declarations:</b>
+
+    <b>\#include</b> \<vigra/affine_registration.hxx\><br>
+    Namespace: vigra
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1, 
+                  class T2, class S2, 
+                  int SPLINEORDER>
+        void 
+        estimateTranslation(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            Matrix<double> & affineMatrix, 
+                            AffineMotionEstimationOptions<SPLINEORDER> const & options = AffineMotionEstimationOptions<SPLINEORDER>());
+    }
+    \endcode
+
+    \deprecatedAPI{estimateTranslation}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  int SPLINEORDER = 2>
+        void
+        estimateTranslation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                            DestIterator dul, DestIterator dlr, DestAccessor dest,
+                            Matrix<double> & affineMatrix,
+                            AffineMotionEstimationOptions<SPLINEORDER> const & options = 
+                                                        AffineMotionEstimationOptions<>())
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  int SPLINEORDER = 2>
+        void
+        estimateTranslation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            triple<DestIterator, DestIterator, DestAccessor> dest,
+                            Matrix<double> & affineMatrix,
+                            AffineMotionEstimationOptions<SPLINEORDER> const & options =
+                                                        AffineMotionEstimationOptions<>())
+    }
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void estimateTranslation)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          int SPLINEORDER>
+inline void
+estimateTranslation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                    DestIterator dul, DestIterator dlr, DestAccessor dest,
+                    Matrix<double> & affineMatrix,
+                    AffineMotionEstimationOptions<SPLINEORDER> const & options)
+{
+    detail::estimateAffineMotionImpl(sul, slr, src, dul, dlr, dest, affineMatrix,
+                                     options, detail::TranslationEstimationFunctor());
+}
+             
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+estimateTranslation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                    DestIterator dul, DestIterator dlr, DestAccessor dest,
+                    Matrix<double> & affineMatrix)
+{
+    estimateTranslation(sul, slr, src, dul, dlr, dest,
+                        affineMatrix, AffineMotionEstimationOptions<>());
+}
+
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor, 
+          int SPLINEORDER>
+inline void 
+estimateTranslation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    triple<DestIterator, DestIterator, DestAccessor> dest,
+                    Matrix<double> & affineMatrix, 
+                    AffineMotionEstimationOptions<SPLINEORDER> const & options)
+{
+    estimateTranslation(src.first, src.second, src.third, dest.first, dest.second, dest.third,
+                        affineMatrix, options);
+}
+
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor>
+inline void 
+estimateTranslation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    triple<DestIterator, DestIterator, DestAccessor> dest,
+                    Matrix<double> & affineMatrix)
+{
+    estimateTranslation(src.first, src.second, src.third, dest.first, dest.second, dest.third,
+                        affineMatrix, AffineMotionEstimationOptions<>());
+}
+
+template <class T1, class S1, 
+          class T2, class S2, 
+          int SPLINEORDER>
+inline void 
+estimateTranslation(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest,
+                    Matrix<double> & affineMatrix, 
+                    AffineMotionEstimationOptions<SPLINEORDER> const & options)
+{
+    estimateTranslation(srcImageRange(src), destImageRange(dest),
+                        affineMatrix, options);
+}
+
+template <class T1, class S1, 
+          class T2, class S2>
+inline void 
+estimateTranslation(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest,
+                    Matrix<double> & affineMatrix)
+{
+    estimateTranslation(srcImageRange(src), destImageRange(dest),
+                        affineMatrix, AffineMotionEstimationOptions<>());
+}
+
+/********************************************************/
+/*                                                      */
+/*              estimateSimilarityTransform             */
+/*                                                      */
+/********************************************************/
+
+/** \brief Estimate the optical flow between two images according to a similarity transform model
+           (e.g. translation, rotation, and uniform scaling).
+
+    Sorry, no \ref detailedDocumentation() available yet.
+
+    <b> Declarations:</b>
+
+    <b>\#include</b> \<vigra/affine_registration.hxx\><br>
+    Namespace: vigra
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1, 
+                  class T2, class S2, 
+                  int SPLINEORDER>
+        void 
+        estimateSimilarityTransform(MultiArrayView<2, T1, S1> const & src,
+                                    MultiArrayView<2, T2, S2> dest,
+                                    Matrix<double> & affineMatrix, 
+                                    AffineMotionEstimationOptions<SPLINEORDER> const & options = 
+                                                        AffineMotionEstimationOptions<SPLINEORDER>());
+    }
+    \endcode
+
+    \deprecatedAPI{estimateSimilarityTransform}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  int SPLINEORDER = 2>
+        void
+        estimateSimilarityTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                            DestIterator dul, DestIterator dlr, DestAccessor dest,
+                            Matrix<double> & affineMatrix,
+                            AffineMotionEstimationOptions<SPLINEORDER> const & options = 
+                                                        AffineMotionEstimationOptions<>())
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  int SPLINEORDER = 2>
+        void
+        estimateSimilarityTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            triple<DestIterator, DestIterator, DestAccessor> dest,
+                            Matrix<double> & affineMatrix,
+                            AffineMotionEstimationOptions<SPLINEORDER> const & options =
+                                                        AffineMotionEstimationOptions<>())
+    }
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void estimateSimilarityTransform)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, 
+          int SPLINEORDER>
+inline void 
+estimateSimilarityTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                            DestIterator dul, DestIterator dlr, DestAccessor dest,
+                            Matrix<double> & affineMatrix, 
+                            AffineMotionEstimationOptions<SPLINEORDER> const & options)
+{
+    detail::estimateAffineMotionImpl(sul, slr, src, dul, dlr, dest, affineMatrix,
+                                     options, detail::SimilarityTransformEstimationFunctor());
+}
+             
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor>
+inline void 
+estimateSimilarityTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                            DestIterator dul, DestIterator dlr, DestAccessor dest,
+                            Matrix<double> & affineMatrix)
+{
+    estimateSimilarityTransform(sul, slr, src, dul, dlr, dest,
+                                affineMatrix, AffineMotionEstimationOptions<>());
+}
+             
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor, 
+          int SPLINEORDER>
+inline void 
+estimateSimilarityTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            triple<DestIterator, DestIterator, DestAccessor> dest,
+                            Matrix<double> & affineMatrix, 
+                            AffineMotionEstimationOptions<SPLINEORDER> const & options)
+{
+    estimateSimilarityTransform(src.first, src.second, src.third, dest.first, dest.second, dest.third,
+                                affineMatrix, options);
+}
+
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor>
+inline void 
+estimateSimilarityTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            triple<DestIterator, DestIterator, DestAccessor> dest,
+                            Matrix<double> & affineMatrix)
+{
+    estimateSimilarityTransform(src.first, src.second, src.third, dest.first, dest.second, dest.third,
+                                affineMatrix, AffineMotionEstimationOptions<>());
+}
+
+template <class T1, class S1, 
+          class T2, class S2, 
+          int SPLINEORDER>
+inline void 
+estimateSimilarityTransform(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            Matrix<double> & affineMatrix, 
+                            AffineMotionEstimationOptions<SPLINEORDER> const & options)
+{
+    estimateSimilarityTransform(srcImageRange(src), destImageRange(dest),
+                                affineMatrix, options);
+}
+
+template <class T1, class S1, 
+          class T2, class S2>
+inline void 
+estimateSimilarityTransform(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            Matrix<double> & affineMatrix)
+{
+    estimateSimilarityTransform(srcImageRange(src), destImageRange(dest),
+                                affineMatrix, AffineMotionEstimationOptions<>());
+}
+
+/********************************************************/
+/*                                                      */
+/*                estimateAffineTransform               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Estimate the optical flow between two images according to an affine transform model
+           (e.g. translation, rotation, non-uniform scaling, and shearing).
+
+    Sorry, no \ref detailedDocumentation() available yet.
+
+    <b> Declarations:</b>
+
+    <b>\#include</b> \<vigra/affine_registration.hxx\><br>
+    Namespace: vigra
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1, 
+                  class T2, class S2, 
+                  int SPLINEORDER>
+        void 
+        estimateAffineTransform(MultiArrayView<2, T1, S1> const & src,
+                                MultiArrayView<2, T2, S2> dest,
+                                Matrix<double> & affineMatrix, 
+                                AffineMotionEstimationOptions<SPLINEORDER> const & options = 
+                                                   AffineMotionEstimationOptions<SPLINEORDER>());
+    }
+    \endcode
+
+    \deprecatedAPI{estimateAffineTransform}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  int SPLINEORDER = 2>
+        void
+        estimateAffineTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                            DestIterator dul, DestIterator dlr, DestAccessor dest,
+                            Matrix<double> & affineMatrix,
+                            AffineMotionEstimationOptions<SPLINEORDER> const & options = 
+                                                        AffineMotionEstimationOptions<>())
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  int SPLINEORDER = 2>
+        void
+        estimateAffineTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            triple<DestIterator, DestIterator, DestAccessor> dest,
+                            Matrix<double> & affineMatrix,
+                            AffineMotionEstimationOptions<SPLINEORDER> const & options =
+                                                        AffineMotionEstimationOptions<>())
+    }
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void estimateAffineTransform)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, 
+          int SPLINEORDER>
+inline void 
+estimateAffineTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                        DestIterator dul, DestIterator dlr, DestAccessor dest,
+                        Matrix<double> & affineMatrix, 
+                        AffineMotionEstimationOptions<SPLINEORDER> const & options)
+{
+    detail::estimateAffineMotionImpl(sul, slr, src, dul, dlr, dest, affineMatrix,
+                                     options, detail::AffineTransformEstimationFunctor());
+}
+             
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor>
+inline void 
+estimateAffineTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                        DestIterator dul, DestIterator dlr, DestAccessor dest,
+                        Matrix<double> & affineMatrix)
+{
+    estimateAffineTransform(sul, slr, src, dul, dlr, dest,
+                            affineMatrix, AffineMotionEstimationOptions<>());
+}
+             
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor, 
+          int SPLINEORDER>
+inline void 
+estimateAffineTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        triple<DestIterator, DestIterator, DestAccessor> dest,
+                        Matrix<double> & affineMatrix, 
+                        AffineMotionEstimationOptions<SPLINEORDER> const & options)
+{
+    estimateAffineTransform(src.first, src.second, src.third, dest.first, dest.second, dest.third,
+                            affineMatrix, options);
+}
+
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor>
+inline void 
+estimateAffineTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        triple<DestIterator, DestIterator, DestAccessor> dest,
+                        Matrix<double> & affineMatrix)
+{
+    estimateAffineTransform(src.first, src.second, src.third, dest.first, dest.second, dest.third,
+                            affineMatrix, AffineMotionEstimationOptions<>());
+}
+             
+template <class T1, class S1, 
+          class T2, class S2, 
+          int SPLINEORDER>
+inline void 
+estimateAffineTransform(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, T2, S2> dest,
+                        Matrix<double> & affineMatrix, 
+                        AffineMotionEstimationOptions<SPLINEORDER> const & options)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "estimateAffineTransform(): shape mismatch between input and output.");
+    estimateAffineTransform(srcImageRange(src), destImageRange(dest),
+                            affineMatrix, options);
+}
+
+template <class T1, class S1, 
+          class T2, class S2>
+inline void 
+estimateAffineTransform(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, T2, S2> dest,
+                        Matrix<double> & affineMatrix)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "estimateAffineTransform(): shape mismatch between input and output.");
+    estimateAffineTransform(srcImageRange(src), destImageRange(dest),
+                            affineMatrix, AffineMotionEstimationOptions<>());
+}
+
+//@}
+
+} // namespace vigra
+
+
+#endif /* VIGRA_AFFINE_REGISTRATION_HXX */
diff --git a/include/vigra/affinegeometry.hxx b/include/vigra/affinegeometry.hxx
new file mode 100644
index 0000000..196834c
--- /dev/null
+++ b/include/vigra/affinegeometry.hxx
@@ -0,0 +1,421 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2005-2006 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+#ifndef VIGRA_AFFINEGEOMETRY_HXX
+#define VIGRA_AFFINEGEOMETRY_HXX
+
+#include "mathutil.hxx"
+#include "matrix.hxx"
+#include "tinyvector.hxx"
+#include "splineimageview.hxx"
+#include "multi_shape.hxx"
+
+#include <cmath>
+
+namespace vigra {
+
+/** \addtogroup GeometricTransformations Geometric Transformations
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                create affine matrices                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Create homogeneous matrix representing a 2D translation.
+ 
+    For use with \ref affineWarpImage().
+*/
+inline
+linalg::TemporaryMatrix<double> translationMatrix2D(TinyVector<double, 2> const & shift)
+{
+    linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
+    ret(0,2) = shift[0];
+    ret(1,2) = shift[1];
+    return ret;
+}
+
+/** \brief Create homogeneous matrix representing a 2D uniform scaling about the coordinate origin.
+ 
+    For use with \ref affineWarpImage().
+*/
+inline
+linalg::TemporaryMatrix<double> scalingMatrix2D(double scalingFactor)
+{
+    linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
+    ret(0,0) = scalingFactor;
+    ret(1,1) = scalingFactor;
+    return ret;
+}
+
+/** \brief Create homogeneous matrix representing a 2D non-uniform scaling about the coordinate origin.
+ 
+    For use with \ref affineWarpImage().
+*/
+inline
+linalg::TemporaryMatrix<double> scalingMatrix2D(double sx, double sy)
+{
+    linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
+    ret(0,0) = sx;
+    ret(1,1) = sy;
+    return ret;
+}
+
+/** \brief Create homogeneous matrix representing a 2D shearing.
+ 
+    For use with \ref affineWarpImage().
+*/
+inline
+linalg::TemporaryMatrix<double> shearMatrix2D(double s01, double s10)
+{
+    linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
+    ret(0,1) = s01;
+    ret(1,0) = s10;
+    return ret;
+}
+
+/** \brief Create homogeneous matrix representing a 2D rotation about the coordinate origin.
+ 
+    For use with \ref affineWarpImage(). Angle must be in radians.
+*/
+inline
+linalg::TemporaryMatrix<double> rotationMatrix2DRadians(double angle)
+{
+    linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
+    double s = std::sin(angle);
+    double c = std::cos(angle);
+    ret(0,0) = c;
+    ret(1,1) = c;
+    ret(0,1) = -s;
+    ret(1,0) = s;
+    return ret;
+}
+
+/** \brief Create homogeneous matrix representing a 2D rotation about the coordinate origin.
+ 
+    For use with \ref affineWarpImage(). Angle must be in degrees.
+*/
+inline
+linalg::TemporaryMatrix<double> rotationMatrix2DDegrees(double angle)
+{
+    return rotationMatrix2DRadians(angle*M_PI/180.0);
+}
+
+/** \brief Create homogeneous matrix representing a 2D rotation about the given point.
+ 
+    For use with \ref affineWarpImage(). Angle must be in radians.
+*/
+inline
+linalg::TemporaryMatrix<double> rotationMatrix2DRadians(double angle, TinyVector<double, 2> const & center)
+{
+    return translationMatrix2D(center) * rotationMatrix2DRadians(angle) * translationMatrix2D(-center);
+}
+
+/** \brief Create homogeneous matrix representing a 2D rotation about the given point.
+ 
+    For use with \ref affineWarpImage(). Angle must be in degrees.
+*/
+inline
+linalg::TemporaryMatrix<double> rotationMatrix2DDegrees(double angle, TinyVector<double, 2> const & center)
+{
+    return rotationMatrix2DRadians(angle*M_PI/180.0, center);
+}
+
+/********************************************************/
+/*                                                      */
+/*                      rotateImage                     */
+/*                                                      */
+/********************************************************/
+
+// documentation is in basicgeometry.hxx
+template <int ORDER, class T, 
+          class DestIterator, class DestAccessor>
+void rotateImage(SplineImageView<ORDER, T> const & src,
+                 DestIterator id, DestAccessor dest, 
+                 double angleInDegree, TinyVector<double, 2> const & center)
+{
+    int w = src.width();
+    int h = src.height();
+    
+    double angle = angleInDegree/180.0;
+    double c = cos_pi(angle); // avoid round-off errors for simple rotations
+    double s = sin_pi(angle);
+    
+    for(int y = 0; y < h; ++y, ++id.y)
+    {
+        typename DestIterator::row_iterator rd = id.rowIterator();
+        double sy =  (y - center[1])*c - center[0]*s + center[1];
+        double sx = -(y - center[1])*s - center[0]*c + center[0];
+        for(int x=0; x < w; ++x, ++rd, sx += c, sy += s)
+        {
+            if(src.isInside(sx, sy))
+                dest.set(src(sx, sy), rd);
+        }
+    }
+}
+
+template <int ORDER, class T, 
+          class DestIterator, class DestAccessor>
+inline void 
+rotateImage(SplineImageView<ORDER, T> const & src,
+            pair<DestIterator, DestAccessor> dest, 
+            double angleInDegree, TinyVector<double, 2> const & center)
+{
+    rotateImage(src, dest.first, dest.second, angleInDegree, center);
+}
+
+template <int ORDER, class T, 
+          class DestIterator, class DestAccessor>
+inline void 
+rotateImage(SplineImageView<ORDER, T> const & src,
+            DestIterator id, DestAccessor dest, 
+            double angleInDegree)
+{
+    TinyVector<double, 2> center((src.width()-1.0) / 2.0, (src.height()-1.0) / 2.0);
+    rotateImage(src, id, dest, angleInDegree, center);
+}
+
+template <int ORDER, class T, 
+          class DestIterator, class DestAccessor>
+inline void 
+rotateImage(SplineImageView<ORDER, T> const & src,
+            pair<DestIterator, DestAccessor> dest, 
+            double angleInDegree)
+{
+    TinyVector<double, 2> center((src.width()-1.0) / 2.0, (src.height()-1.0) / 2.0);
+    rotateImage(src, dest.first, dest.second, angleInDegree, center);
+}
+
+template <int ORDER, class T, 
+          class T2, class S2>
+inline void 
+rotateImage(SplineImageView<ORDER, T> const & src,
+            MultiArrayView<2, T2, S2> dest, 
+            double angleInDegree, TinyVector<double, 2> const & center)
+{
+    rotateImage(src, destImage(dest), angleInDegree, center);
+}
+
+template <int ORDER, class T, 
+          class T2, class S2>
+inline void 
+rotateImage(SplineImageView<ORDER, T> const & src,
+            MultiArrayView<2, T2, S2> dest, 
+            double angleInDegree)
+{
+    TinyVector<double, 2> center((src.width()-1.0) / 2.0, (src.height()-1.0) / 2.0);
+    rotateImage(src, destImage(dest), angleInDegree, center);
+}
+
+/********************************************************/
+/*                                                      */
+/*                  affineWarpImage                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Warp an image according to an affine transformation.
+
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <int ORDER, class T, 
+                  class T2, class S2,
+                  class C>
+        void
+        affineWarpImage(SplineImageView<ORDER, T> const & src,
+                        MultiArrayView<2, T2, S2> dest, 
+                        MultiArrayView<2, double, C> const & affineMatrix);
+    }
+    \endcode
+    
+    \deprecatedAPI{affineWarpImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <int ORDER, class T, 
+                class DestIterator, class DestAccessor,
+                class C>
+        void affineWarpImage(SplineImageView<ORDER, T> const & src,
+                            DestIterator dul, DestIterator dlr, DestAccessor dest, 
+                            MultiArrayView<2, double, C> const & affineMatrix);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <int ORDER, class T, 
+                class DestIterator, class DestAccessor,
+                class C>
+        void affineWarpImage(SplineImageView<ORDER, T> const & src,
+                            triple<DestIterator, DestIterator, DestAccessor> dest, 
+                            MultiArrayView<2, double, C> const & affineMatrix);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    The algorithm applies the given \a affineMatrix to the <i>destination coordinates</i> and copies
+    the image value from the resulting source coordinates, using the given SplineImageView \a src for interpolation. 
+    If the resulting coordinate is outside the source image, nothing will be written at that destination point.
+    
+    \code
+        for all dest pixels:
+            currentSrcCoordinate = affineMatrix * currentDestCoordinate;
+            if src.isInside(currentSrcCoordinate):
+                dest[currentDestCoordinate] = src[currentSrcCoordinate]; // copy an interpolated value
+    \endcode
+    
+    The matrix represents a 2-dimensional affine transform by means of homogeneous coordinates,
+    i.e. it must be a 3x3 matrix whose last row is (0,0,1).
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/affinegeometry.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(width, height);
+    SplineImageView<3, float> spline(src);
+    
+    MultiArray<2, float> dest1(src.shape());
+    
+    // equivalent (up to round-off errors) to 
+    //     rotateImage(spline, dest1, 45.0);
+    TinyVector<double, 2> center((width-1.0)/2.0, (height-1.0)/2.0);
+    affineWarpImage(spline, dest1, rotationMatrix2DDegrees(45.0, center));
+    
+    MultiArray<2, float> dest2(2*width-1, 2*height-1);
+    
+    // equivalent (up to round-off errors) to 
+    //     resizeImageSplineInterpolation(img, dest2);
+    // note that scaleFactor = 0.5, because we must pass the transformation from destination to source
+    affineWarpImage(spline, dest2, scalingMatrix2D(0.5));
+    \endcode
+
+    \deprecatedUsage{affineWarpImage}
+    \code
+    FImage src(width, height);
+    SplineImageView<3, Image::value_type> spline(srcImageRange(src));
+    
+    FImage dest1(width, height);
+    
+    // equivalent (up to round-off errors) with 
+    //     rotateImage(spline, destImage(dest1), 45.0);
+    TinyVector<double, 2> center((width-1.0)/2.0, (height-1.0)/2.0);
+    affineWarpImage(spline, destImageRange(dest1), rotationMatrix2DDegrees(45.0, center));
+    
+    FImage dest2(2*width-1, 2*height-1);
+    
+    // equivalent (up to round-off errors) with 
+    //     resizeImageSplineInterpolation(srcImageRange(img), destImageRange(dest2));
+    // note that scaleFactor = 0.5, because we must pass the transformation from destination to source
+    affineWarpImage(spline, destImageRange(dest2), scalingMatrix2D(0.5));
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    DestImageIterator dest_upperleft;
+    
+    double x = ..., y = ...;
+    
+    if (spline.isInside(x,y))
+        dest_accessor.set(spline(x, y), dest_upperleft);
+    \endcode
+    \deprecatedEnd
+    
+    <b>See also:</b> Functions to specify affine transformation: \ref translationMatrix2D(), \ref scalingMatrix2D(), 
+                    \ref shearMatrix2D(), \ref rotationMatrix2DRadians(), \ref rotationMatrix2DDegrees()
+*/
+doxygen_overloaded_function(template <...> void affineWarpImage)
+
+template <int ORDER, class T, 
+          class DestIterator, class DestAccessor,
+          class C>
+void affineWarpImage(SplineImageView<ORDER, T> const & src,
+                     DestIterator dul, DestIterator dlr, DestAccessor dest, 
+                     MultiArrayView<2, double, C> const & affineMatrix)
+{
+    vigra_precondition(rowCount(affineMatrix) == 3 && columnCount(affineMatrix) == 3 && 
+                       affineMatrix(2,0) == 0.0 && affineMatrix(2,1) == 0.0 && affineMatrix(2,2) == 1.0,
+        "affineWarpImage(): matrix doesn't represent an affine transformation with homogeneous 2D coordinates.");
+         
+    
+    double w = dlr.x - dul.x;
+    double h = dlr.y - dul.y;
+    
+    for(double y = 0.0; y < h; ++y, ++dul.y)
+    {
+        typename DestIterator::row_iterator rd = dul.rowIterator();
+        for(double x=0.0; x < w; ++x, ++rd)
+        {
+            double sx = x*affineMatrix(0,0) + y*affineMatrix(0,1) + affineMatrix(0,2);
+            double sy = x*affineMatrix(1,0) + y*affineMatrix(1,1) + affineMatrix(1,2);
+            if(src.isInside(sx, sy))
+                dest.set(src(sx, sy), rd);
+        }
+    }
+}
+
+template <int ORDER, class T, 
+          class DestIterator, class DestAccessor,
+          class C>
+inline void
+affineWarpImage(SplineImageView<ORDER, T> const & src,
+                triple<DestIterator, DestIterator, DestAccessor> dest, 
+                MultiArrayView<2, double, C> const & affineMatrix)
+{
+    affineWarpImage(src, dest.first, dest.second, dest.third, affineMatrix);
+}
+
+template <int ORDER, class T, 
+          class T2, class S2,
+          class C>
+inline void
+affineWarpImage(SplineImageView<ORDER, T> const & src,
+                MultiArrayView<2, T2, S2> dest, 
+                MultiArrayView<2, double, C> const & affineMatrix)
+{
+    affineWarpImage(src, destImageRange(dest), affineMatrix);
+}
+
+
+//@}
+
+} // namespace vigra
+
+
+#endif /* VIGRA_AFFINEGEOMETRY_HXX */
diff --git a/include/vigra/algorithm.hxx b/include/vigra/algorithm.hxx
new file mode 100644
index 0000000..c9440d4
--- /dev/null
+++ b/include/vigra/algorithm.hxx
@@ -0,0 +1,730 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2010-2011 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_ALGORITHM_HXX
+#define VIGRA_ALGORITHM_HXX
+
+#include "sized_int.hxx"
+#include "numerictraits.hxx"
+#include "inspector_passes.hxx"
+#include <algorithm>
+#include <functional>
+#include <iterator>
+
+namespace vigra {
+
+/** \addtogroup MathFunctions
+*/
+//@{
+    /** \brief Find the minimum element in a sequence.
+    
+        The function returns the iterator referring to the minimum element.
+        This is identical to the function <tt>std::min_element()</tt>.
+        
+        <b>Required Interface:</b>
+        
+        \code
+        Iterator is a standard forward iterator.
+        
+        bool f = *first < NumericTraits<typename std::iterator_traits<Iterator>::value_type>::max();
+        \endcode
+
+        <b>\#include</b> \<vigra/algorithm.hxx\><br>
+        Namespace: vigra
+    */
+template <class Iterator>
+Iterator argMin(Iterator first, Iterator last)
+{
+    if(first == last)
+        return last;
+    Iterator best = first;
+    for(++first; first != last; ++first)
+        if(*first < *best)
+            best = first;
+    return best;
+}
+
+    /** \brief Find the maximum element in a sequence.
+    
+        The function returns the iterator referring to the maximum element.
+        This is identical to the function <tt>std::max_element()</tt>.
+        
+        <b>Required Interface:</b>
+        
+        \code
+        Iterator is a standard forward iterator.
+        
+        bool f = NumericTraits<typename std::iterator_traits<Iterator>::value_type>::min() < *first;
+        \endcode
+
+        <b>\#include</b> \<vigra/algorithm.hxx\><br>
+        Namespace: vigra
+    */
+template <class Iterator>
+Iterator argMax(Iterator first, Iterator last)
+{
+    if(first == last)
+        return last;
+    Iterator best = first;
+    for(++first; first != last; ++first)
+        if(*best < *first)
+            best = first;
+    return best;
+}
+
+    /** \brief Find the minimum element in a sequence conforming to a condition.
+    
+        The function returns the iterator referring to the minimum element,
+        where only elements conforming to the condition (i.e. where 
+        <tt>condition(*iterator)</tt> evaluates to <tt>true</tt>) are considered.
+        If no element conforms to the condition, or the sequence is empty,
+        the end iterator \a last is returned.
+        
+        <b>Required Interface:</b>
+        
+        \code
+        Iterator is a standard forward iterator.
+        
+        bool c = condition(*first);
+        
+        bool f = *first < NumericTraits<typename std::iterator_traits<Iterator>::value_type>::max();
+        \endcode
+
+        <b>\#include</b> \<vigra/algorithm.hxx\><br>
+        Namespace: vigra
+    */
+template <class Iterator, class UnaryFunctor>
+Iterator argMinIf(Iterator first, Iterator last, UnaryFunctor condition)
+{
+    for(; first != last; ++first)
+        if(condition(*first))
+            break;
+    if(first == last)
+        return last;
+    Iterator best = first;
+    for(++first; first != last; ++first)
+        if(condition(*first) && *first < *best)
+            best = first;
+    return best;
+}
+
+    /** \brief Find the maximum element in a sequence conforming to a condition.
+    
+        The function returns the iterator referring to the maximum element,
+        where only elements conforming to the condition (i.e. where 
+        <tt>condition(*iterator)</tt> evaluates to <tt>true</tt>) are considered.
+        If no element conforms to the condition, or the sequence is empty,
+        the end iterator \a last is returned.
+        
+        <b>Required Interface:</b>
+        
+        \code
+        Iterator is a standard forward iterator.
+        
+        bool c = condition(*first);
+        
+        bool f = NumericTraits<typename std::iterator_traits<Iterator>::value_type>::min() < *first;
+        \endcode
+
+        <b>\#include</b> \<vigra/algorithm.hxx\><br>
+        Namespace: vigra
+    */
+template <class Iterator, class UnaryFunctor>
+Iterator argMaxIf(Iterator first, Iterator last, UnaryFunctor condition)
+{
+    for(; first != last; ++first)
+        if(condition(*first))
+            break;
+    if(first == last)
+        return last;
+    Iterator best = first;
+    for(++first; first != last; ++first)
+        if(condition(*first) && *best < *first)
+            best = first;
+    return best;
+}
+
+    /** \brief Fill an array with a sequence of numbers.
+    
+        The sequence starts at \a start and is incremented with \a step. Default start
+        and stepsize are 0 and 1 respectively.
+        
+        <b> Declaration:</b>
+
+        \code
+        namespace vigra {
+            template <class Iterator, class Value>
+            void linearSequence(Iterator first, Iterator last, 
+                          Value const & start = 0, Value const & step = 1);
+        }
+        \endcode
+        
+        <b>Required Interface:</b>
+        
+        \code
+        Iterator is a standard forward iterator.
+        
+        *first = start;
+        start += step;
+        \endcode
+
+        <b>\#include</b> \<vigra/algorithm.hxx\><br>
+        Namespace: vigra
+    */
+template <class Iterator, class Value>
+void linearSequence(Iterator first, Iterator last, Value start, Value step)
+{
+    for(; first != last; ++first, start += step)
+        *first = start;
+}
+
+template <class Iterator, class Value>
+void linearSequence(Iterator first, Iterator last, Value start)
+{
+    for(; first != last; ++first, ++start)
+        *first = start;
+}
+
+template <class Iterator>
+void linearSequence(Iterator first, Iterator last)
+{
+    typedef typename std::iterator_traits<Iterator>::value_type Value;
+    
+    linearSequence(first, last, NumericTraits<Value>::zero());
+}
+
+/** \brief Call an analyzing functor at every element of a sequence.
+
+    This function can be used to collect statistics of the sequence
+    <tt>[first, last)</tt> defined by these two input interators.
+    The results must be stored in the functor, which serves as a return
+    value.
+
+    <b> Declarations:</b>
+
+    \code
+    namespace vigra {
+        template <class InputIterator, class Functor>
+        void
+        inspectSequence(InputIterator first, InputIterator last, Functor & f);
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/algorithm.hxx\><br>
+    Namespace: vigra
+
+    \code
+    std::vector array(100);
+
+    // init functor
+    vigra::FindMinMax<int> minmax;
+
+    vigra::inspectSequence(array.begin(), array.end(), minmax);
+
+    cout << "Min: " << minmax.min << " Max: " << minmax.max;
+
+    \endcode
+
+*/
+doxygen_overloaded_function(template <...> void inspectSequence)
+
+namespace detail {
+
+template <class InputIterator>
+struct inspectSequence_binder
+{
+    InputIterator first;
+    InputIterator last;
+    inspectSequence_binder(InputIterator first_, InputIterator last_)
+        : first(first_), last(last_) {}
+    template <class Functor>
+    void operator()(Functor & f)
+    {
+        for (InputIterator i = first; i != last; ++i)
+            f(*i);
+    }
+};
+
+} // namespace detail
+
+template <class InputIterator, class Functor>
+inline void
+inspectSequence(InputIterator first, InputIterator last, Functor & f)
+{
+    detail::inspectSequence_binder<InputIterator> g(first, last);
+    detail::extra_passes_select(g, f);
+}
+   
+namespace detail {
+
+template <class Iterator, class Compare>
+struct IndexCompare
+{
+    Iterator i_;
+    Compare c_;
+    
+    IndexCompare(Iterator i, Compare c)
+    : i_(i),
+      c_(c)
+    {}
+
+    template <class Index>
+    bool operator()(Index const & l, Index const & r) const
+    {
+        return c_(i_[l], i_[r]);
+    }
+};
+
+} // namespace detail
+
+    /** \brief Return the index permutation that would sort the input array.
+    
+        To actually sort an array according to the ordering thus determined, use 
+        \ref applyPermutation().
+        
+        <b> Declarations:</b>
+
+        \code
+        namespace vigra {
+            // compare using std::less
+            template <class Iterator, class IndexIterator>
+            void indexSort(Iterator first, Iterator last, IndexIterator index_first);
+
+            // compare using functor Compare
+            template <class Iterator, class IndexIterator, class Compare>
+            void indexSort(Iterator first, Iterator last, IndexIterator index_first, Compare compare);
+        }
+        \endcode
+        
+        <b>Required Interface:</b>
+        
+        \code
+        Iterator and IndexIterators are random access iterators.
+        
+        bool res = compare(first[*index_first], first[*index_first]);
+        \endcode
+
+        <b>\#include</b> \<vigra/algorithm.hxx\><br>
+        Namespace: vigra
+    */
+template <class Iterator, class IndexIterator, class Compare>
+void indexSort(Iterator first, Iterator last, IndexIterator index_first, Compare c)
+{
+    int size = last - first;
+    linearSequence(index_first, index_first+size);
+    std::sort(index_first, index_first+size, 
+              detail::IndexCompare<Iterator, Compare>(first, c));
+}
+
+template <class Iterator, class IndexIterator>
+void indexSort(Iterator first, Iterator last, IndexIterator index_first)
+{
+    typedef typename std::iterator_traits<Iterator>::value_type Value;
+    indexSort(first, last, index_first, std::less<Value>());
+}
+
+    /** \brief Sort an array according to the given index permutation.
+    
+        The iterators \a in and \a out may not refer to the same array, as
+        this would overwrite the input prematurely.
+        
+        <b> Declaration:</b>
+
+        \code
+        namespace vigra {
+            template <class IndexIterator, class InIterator, class OutIterator>
+            void applyPermutation(IndexIterator index_first, IndexIterator index_last, 
+                                  InIterator in, OutIterator out);
+        }
+        \endcode
+        
+        <b>Required Interface:</b>
+        
+        \code
+        OutIterator and IndexIterators are forward iterators.
+        InIterator is a random access iterator.
+        
+        *out = in[*index_first];
+        \endcode
+
+        <b>\#include</b> \<vigra/algorithm.hxx\><br>
+        Namespace: vigra
+    */
+template <class IndexIterator, class InIterator, class OutIterator>
+void applyPermutation(IndexIterator index_first, IndexIterator index_last, 
+                      InIterator in, OutIterator out)
+{
+    for(; index_first != index_last; ++index_first, ++out)
+        *out = in[*index_first];
+}
+
+
+    /** \brief Compute the inverse of a given permutation.
+    
+        This is just another name for \ref indexSort(), referring to
+        another semantics.
+        
+        <b> Declaration:</b>
+
+        \code
+        namespace vigra {
+            template <class InIterator, class OutIterator>
+            void inversePermutation(InIterator first, InIterator last, 
+                                    OutIterator out);
+        }
+        \endcode
+        
+        <b>Required Interface:</b>
+        
+        \code
+        InIterator and OutIterator are random access iterators.
+        
+        *out = in[*index_first];
+        \endcode
+
+        <b>\#include</b> \<vigra/algorithm.hxx\><br>
+        Namespace: vigra
+    */
+template <class InIterator, class OutIterator>
+void inversePermutation(InIterator first, InIterator last, 
+                        OutIterator out)
+{
+    indexSort(first, last, out);
+}
+
+namespace detail {
+
+static bool isLittleEndian()
+{
+    static const UIntBiggest testint = 0x01;
+    return ((UInt8 *)&testint)[0] == 0x01;
+}
+
+template <class INT>
+struct ChecksumImpl
+{
+    static UInt32 table0[256];
+    static UInt32 table1[256];
+    static UInt32 table2[256];
+    static UInt32 table3[256];
+    
+    template <class InIterator>
+    static UInt32 exec(InIterator i, unsigned int size, UInt32 crc = 0xFFFFFFFF);
+};
+
+template <class INT>
+UInt32 ChecksumImpl<INT>::table0[256] = {
+    0x0U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x76dc419U, 0x706af48fU, 
+    0xe963a535U, 0x9e6495a3U, 0xedb8832U, 0x79dcb8a4U, 0xe0d5e91eU, 0x97d2d988U, 
+    0x9b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 
+    0xf3b97148U, 0x84be41deU, 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 
+    0x136c9856U, 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, 
+    0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, 0xa2677172U, 
+    0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, 0x35b5a8faU, 0x42b2986cU, 
+    0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 
+    0x26d930acU, 0x51de003aU, 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 
+    0xcfba9599U, 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, 
+    0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, 0x1db7106U, 
+    0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x6b6b51fU, 0x9fbfe4a5U, 0xe8b8d433U, 
+    0x7807c9a2U, 0xf00f934U, 0x9609a88eU, 0xe10e9818U, 0x7f6a0dbbU, 0x86d3d2dU, 
+    0x91646c97U, 0xe6635c01U, 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 
+    0x6c0695edU, 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, 
+    0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, 0xfbd44c65U, 
+    0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, 0x4adfa541U, 0x3dd895d7U, 
+    0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 
+    0x44042d73U, 0x33031de5U, 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 
+    0xbe0b1010U, 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, 
+    0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, 0x2eb40d81U, 
+    0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, 0x3b6e20cU, 0x74b1d29aU, 
+    0xead54739U, 0x9dd277afU, 0x4db2615U, 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 
+    0xd6d6a3eU, 0x7a6a5aa8U, 0xe40ecf0bU, 0x9309ff9dU, 0xa00ae27U, 0x7d079eb1U, 
+    0xf00f9344U, 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, 
+    0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, 0x67dd4accU, 
+    0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, 0xd6d6a3e8U, 0xa1d1937eU, 
+    0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 
+    0xd80d2bdaU, 0xaf0a1b4cU, 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 
+    0x316e8eefU, 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, 
+    0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, 0xb2bd0b28U, 
+    0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, 0x2cd99e8bU, 0x5bdeae1dU, 
+    0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, 0x26d930aU, 0x9c0906a9U, 0xeb0e363fU, 
+    0x72076785U, 0x5005713U, 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0xcb61b38U, 
+    0x92d28e9bU, 0xe5d5be0dU, 0x7cdcefb7U, 0xbdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, 
+    0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, 0x18b74777U, 
+    0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, 0x8f659effU, 0xf862ae69U, 
+    0x616bffd3U, 0x166ccf45U, 0xa00ae278U, 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 
+    0xa7672661U, 0xd06016f7U, 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 
+    0x40df0b66U, 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, 
+    0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, 0xcdd70693U, 
+    0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, 0x5d681b02U, 0x2a6f2b94U, 
+    0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU }; 
+
+template <class INT>
+UInt32 ChecksumImpl<INT>::table1[256] = {
+    0x00000000U, 0x191b3141U, 0x32366282U, 0x2b2d53c3U, 0x646cc504U,
+    0x7d77f445U, 0x565aa786U, 0x4f4196c7U, 0xc8d98a08U, 0xd1c2bb49U,
+    0xfaefe88aU, 0xe3f4d9cbU, 0xacb54f0cU, 0xb5ae7e4dU, 0x9e832d8eU,
+    0x87981ccfU, 0x4ac21251U, 0x53d92310U, 0x78f470d3U, 0x61ef4192U,
+    0x2eaed755U, 0x37b5e614U, 0x1c98b5d7U, 0x05838496U, 0x821b9859U,
+    0x9b00a918U, 0xb02dfadbU, 0xa936cb9aU, 0xe6775d5dU, 0xff6c6c1cU,
+    0xd4413fdfU, 0xcd5a0e9eU, 0x958424a2U, 0x8c9f15e3U, 0xa7b24620U,
+    0xbea97761U, 0xf1e8e1a6U, 0xe8f3d0e7U, 0xc3de8324U, 0xdac5b265U,
+    0x5d5daeaaU, 0x44469febU, 0x6f6bcc28U, 0x7670fd69U, 0x39316baeU,
+    0x202a5aefU, 0x0b07092cU, 0x121c386dU, 0xdf4636f3U, 0xc65d07b2U,
+    0xed705471U, 0xf46b6530U, 0xbb2af3f7U, 0xa231c2b6U, 0x891c9175U,
+    0x9007a034U, 0x179fbcfbU, 0x0e848dbaU, 0x25a9de79U, 0x3cb2ef38U,
+    0x73f379ffU, 0x6ae848beU, 0x41c51b7dU, 0x58de2a3cU, 0xf0794f05U,
+    0xe9627e44U, 0xc24f2d87U, 0xdb541cc6U, 0x94158a01U, 0x8d0ebb40U,
+    0xa623e883U, 0xbf38d9c2U, 0x38a0c50dU, 0x21bbf44cU, 0x0a96a78fU,
+    0x138d96ceU, 0x5ccc0009U, 0x45d73148U, 0x6efa628bU, 0x77e153caU,
+    0xbabb5d54U, 0xa3a06c15U, 0x888d3fd6U, 0x91960e97U, 0xded79850U,
+    0xc7cca911U, 0xece1fad2U, 0xf5facb93U, 0x7262d75cU, 0x6b79e61dU,
+    0x4054b5deU, 0x594f849fU, 0x160e1258U, 0x0f152319U, 0x243870daU,
+    0x3d23419bU, 0x65fd6ba7U, 0x7ce65ae6U, 0x57cb0925U, 0x4ed03864U,
+    0x0191aea3U, 0x188a9fe2U, 0x33a7cc21U, 0x2abcfd60U, 0xad24e1afU,
+    0xb43fd0eeU, 0x9f12832dU, 0x8609b26cU, 0xc94824abU, 0xd05315eaU,
+    0xfb7e4629U, 0xe2657768U, 0x2f3f79f6U, 0x362448b7U, 0x1d091b74U,
+    0x04122a35U, 0x4b53bcf2U, 0x52488db3U, 0x7965de70U, 0x607eef31U,
+    0xe7e6f3feU, 0xfefdc2bfU, 0xd5d0917cU, 0xcccba03dU, 0x838a36faU,
+    0x9a9107bbU, 0xb1bc5478U, 0xa8a76539U, 0x3b83984bU, 0x2298a90aU,
+    0x09b5fac9U, 0x10aecb88U, 0x5fef5d4fU, 0x46f46c0eU, 0x6dd93fcdU,
+    0x74c20e8cU, 0xf35a1243U, 0xea412302U, 0xc16c70c1U, 0xd8774180U,
+    0x9736d747U, 0x8e2de606U, 0xa500b5c5U, 0xbc1b8484U, 0x71418a1aU,
+    0x685abb5bU, 0x4377e898U, 0x5a6cd9d9U, 0x152d4f1eU, 0x0c367e5fU,
+    0x271b2d9cU, 0x3e001cddU, 0xb9980012U, 0xa0833153U, 0x8bae6290U,
+    0x92b553d1U, 0xddf4c516U, 0xc4eff457U, 0xefc2a794U, 0xf6d996d5U,
+    0xae07bce9U, 0xb71c8da8U, 0x9c31de6bU, 0x852aef2aU, 0xca6b79edU,
+    0xd37048acU, 0xf85d1b6fU, 0xe1462a2eU, 0x66de36e1U, 0x7fc507a0U,
+    0x54e85463U, 0x4df36522U, 0x02b2f3e5U, 0x1ba9c2a4U, 0x30849167U,
+    0x299fa026U, 0xe4c5aeb8U, 0xfdde9ff9U, 0xd6f3cc3aU, 0xcfe8fd7bU,
+    0x80a96bbcU, 0x99b25afdU, 0xb29f093eU, 0xab84387fU, 0x2c1c24b0U,
+    0x350715f1U, 0x1e2a4632U, 0x07317773U, 0x4870e1b4U, 0x516bd0f5U,
+    0x7a468336U, 0x635db277U, 0xcbfad74eU, 0xd2e1e60fU, 0xf9ccb5ccU,
+    0xe0d7848dU, 0xaf96124aU, 0xb68d230bU, 0x9da070c8U, 0x84bb4189U,
+    0x03235d46U, 0x1a386c07U, 0x31153fc4U, 0x280e0e85U, 0x674f9842U,
+    0x7e54a903U, 0x5579fac0U, 0x4c62cb81U, 0x8138c51fU, 0x9823f45eU,
+    0xb30ea79dU, 0xaa1596dcU, 0xe554001bU, 0xfc4f315aU, 0xd7626299U,
+    0xce7953d8U, 0x49e14f17U, 0x50fa7e56U, 0x7bd72d95U, 0x62cc1cd4U,
+    0x2d8d8a13U, 0x3496bb52U, 0x1fbbe891U, 0x06a0d9d0U, 0x5e7ef3ecU,
+    0x4765c2adU, 0x6c48916eU, 0x7553a02fU, 0x3a1236e8U, 0x230907a9U,
+    0x0824546aU, 0x113f652bU, 0x96a779e4U, 0x8fbc48a5U, 0xa4911b66U,
+    0xbd8a2a27U, 0xf2cbbce0U, 0xebd08da1U, 0xc0fdde62U, 0xd9e6ef23U,
+    0x14bce1bdU, 0x0da7d0fcU, 0x268a833fU, 0x3f91b27eU, 0x70d024b9U,
+    0x69cb15f8U, 0x42e6463bU, 0x5bfd777aU, 0xdc656bb5U, 0xc57e5af4U,
+    0xee530937U, 0xf7483876U, 0xb809aeb1U, 0xa1129ff0U, 0x8a3fcc33U,
+    0x9324fd72U };
+    
+template <class INT>
+UInt32 ChecksumImpl<INT>::table2[256] = {
+    0x00000000U, 0x01c26a37U, 0x0384d46eU, 0x0246be59U, 0x0709a8dcU,
+    0x06cbc2ebU, 0x048d7cb2U, 0x054f1685U, 0x0e1351b8U, 0x0fd13b8fU,
+    0x0d9785d6U, 0x0c55efe1U, 0x091af964U, 0x08d89353U, 0x0a9e2d0aU,
+    0x0b5c473dU, 0x1c26a370U, 0x1de4c947U, 0x1fa2771eU, 0x1e601d29U,
+    0x1b2f0bacU, 0x1aed619bU, 0x18abdfc2U, 0x1969b5f5U, 0x1235f2c8U,
+    0x13f798ffU, 0x11b126a6U, 0x10734c91U, 0x153c5a14U, 0x14fe3023U,
+    0x16b88e7aU, 0x177ae44dU, 0x384d46e0U, 0x398f2cd7U, 0x3bc9928eU,
+    0x3a0bf8b9U, 0x3f44ee3cU, 0x3e86840bU, 0x3cc03a52U, 0x3d025065U,
+    0x365e1758U, 0x379c7d6fU, 0x35dac336U, 0x3418a901U, 0x3157bf84U,
+    0x3095d5b3U, 0x32d36beaU, 0x331101ddU, 0x246be590U, 0x25a98fa7U,
+    0x27ef31feU, 0x262d5bc9U, 0x23624d4cU, 0x22a0277bU, 0x20e69922U,
+    0x2124f315U, 0x2a78b428U, 0x2bbade1fU, 0x29fc6046U, 0x283e0a71U,
+    0x2d711cf4U, 0x2cb376c3U, 0x2ef5c89aU, 0x2f37a2adU, 0x709a8dc0U,
+    0x7158e7f7U, 0x731e59aeU, 0x72dc3399U, 0x7793251cU, 0x76514f2bU,
+    0x7417f172U, 0x75d59b45U, 0x7e89dc78U, 0x7f4bb64fU, 0x7d0d0816U,
+    0x7ccf6221U, 0x798074a4U, 0x78421e93U, 0x7a04a0caU, 0x7bc6cafdU,
+    0x6cbc2eb0U, 0x6d7e4487U, 0x6f38fadeU, 0x6efa90e9U, 0x6bb5866cU,
+    0x6a77ec5bU, 0x68315202U, 0x69f33835U, 0x62af7f08U, 0x636d153fU,
+    0x612bab66U, 0x60e9c151U, 0x65a6d7d4U, 0x6464bde3U, 0x662203baU,
+    0x67e0698dU, 0x48d7cb20U, 0x4915a117U, 0x4b531f4eU, 0x4a917579U,
+    0x4fde63fcU, 0x4e1c09cbU, 0x4c5ab792U, 0x4d98dda5U, 0x46c49a98U,
+    0x4706f0afU, 0x45404ef6U, 0x448224c1U, 0x41cd3244U, 0x400f5873U,
+    0x4249e62aU, 0x438b8c1dU, 0x54f16850U, 0x55330267U, 0x5775bc3eU,
+    0x56b7d609U, 0x53f8c08cU, 0x523aaabbU, 0x507c14e2U, 0x51be7ed5U,
+    0x5ae239e8U, 0x5b2053dfU, 0x5966ed86U, 0x58a487b1U, 0x5deb9134U,
+    0x5c29fb03U, 0x5e6f455aU, 0x5fad2f6dU, 0xe1351b80U, 0xe0f771b7U,
+    0xe2b1cfeeU, 0xe373a5d9U, 0xe63cb35cU, 0xe7fed96bU, 0xe5b86732U,
+    0xe47a0d05U, 0xef264a38U, 0xeee4200fU, 0xeca29e56U, 0xed60f461U,
+    0xe82fe2e4U, 0xe9ed88d3U, 0xebab368aU, 0xea695cbdU, 0xfd13b8f0U,
+    0xfcd1d2c7U, 0xfe976c9eU, 0xff5506a9U, 0xfa1a102cU, 0xfbd87a1bU,
+    0xf99ec442U, 0xf85cae75U, 0xf300e948U, 0xf2c2837fU, 0xf0843d26U,
+    0xf1465711U, 0xf4094194U, 0xf5cb2ba3U, 0xf78d95faU, 0xf64fffcdU,
+    0xd9785d60U, 0xd8ba3757U, 0xdafc890eU, 0xdb3ee339U, 0xde71f5bcU,
+    0xdfb39f8bU, 0xddf521d2U, 0xdc374be5U, 0xd76b0cd8U, 0xd6a966efU,
+    0xd4efd8b6U, 0xd52db281U, 0xd062a404U, 0xd1a0ce33U, 0xd3e6706aU,
+    0xd2241a5dU, 0xc55efe10U, 0xc49c9427U, 0xc6da2a7eU, 0xc7184049U,
+    0xc25756ccU, 0xc3953cfbU, 0xc1d382a2U, 0xc011e895U, 0xcb4dafa8U,
+    0xca8fc59fU, 0xc8c97bc6U, 0xc90b11f1U, 0xcc440774U, 0xcd866d43U,
+    0xcfc0d31aU, 0xce02b92dU, 0x91af9640U, 0x906dfc77U, 0x922b422eU,
+    0x93e92819U, 0x96a63e9cU, 0x976454abU, 0x9522eaf2U, 0x94e080c5U,
+    0x9fbcc7f8U, 0x9e7eadcfU, 0x9c381396U, 0x9dfa79a1U, 0x98b56f24U,
+    0x99770513U, 0x9b31bb4aU, 0x9af3d17dU, 0x8d893530U, 0x8c4b5f07U,
+    0x8e0de15eU, 0x8fcf8b69U, 0x8a809decU, 0x8b42f7dbU, 0x89044982U,
+    0x88c623b5U, 0x839a6488U, 0x82580ebfU, 0x801eb0e6U, 0x81dcdad1U,
+    0x8493cc54U, 0x8551a663U, 0x8717183aU, 0x86d5720dU, 0xa9e2d0a0U,
+    0xa820ba97U, 0xaa6604ceU, 0xaba46ef9U, 0xaeeb787cU, 0xaf29124bU,
+    0xad6fac12U, 0xacadc625U, 0xa7f18118U, 0xa633eb2fU, 0xa4755576U,
+    0xa5b73f41U, 0xa0f829c4U, 0xa13a43f3U, 0xa37cfdaaU, 0xa2be979dU,
+    0xb5c473d0U, 0xb40619e7U, 0xb640a7beU, 0xb782cd89U, 0xb2cddb0cU,
+    0xb30fb13bU, 0xb1490f62U, 0xb08b6555U, 0xbbd72268U, 0xba15485fU,
+    0xb853f606U, 0xb9919c31U, 0xbcde8ab4U, 0xbd1ce083U, 0xbf5a5edaU,
+    0xbe9834edU };
+    
+template <class INT>
+UInt32 ChecksumImpl<INT>::table3[256] = {
+    0x00000000U, 0xb8bc6765U, 0xaa09c88bU, 0x12b5afeeU, 0x8f629757U,
+    0x37def032U, 0x256b5fdcU, 0x9dd738b9U, 0xc5b428efU, 0x7d084f8aU,
+    0x6fbde064U, 0xd7018701U, 0x4ad6bfb8U, 0xf26ad8ddU, 0xe0df7733U,
+    0x58631056U, 0x5019579fU, 0xe8a530faU, 0xfa109f14U, 0x42acf871U,
+    0xdf7bc0c8U, 0x67c7a7adU, 0x75720843U, 0xcdce6f26U, 0x95ad7f70U,
+    0x2d111815U, 0x3fa4b7fbU, 0x8718d09eU, 0x1acfe827U, 0xa2738f42U,
+    0xb0c620acU, 0x087a47c9U, 0xa032af3eU, 0x188ec85bU, 0x0a3b67b5U,
+    0xb28700d0U, 0x2f503869U, 0x97ec5f0cU, 0x8559f0e2U, 0x3de59787U,
+    0x658687d1U, 0xdd3ae0b4U, 0xcf8f4f5aU, 0x7733283fU, 0xeae41086U,
+    0x525877e3U, 0x40edd80dU, 0xf851bf68U, 0xf02bf8a1U, 0x48979fc4U,
+    0x5a22302aU, 0xe29e574fU, 0x7f496ff6U, 0xc7f50893U, 0xd540a77dU,
+    0x6dfcc018U, 0x359fd04eU, 0x8d23b72bU, 0x9f9618c5U, 0x272a7fa0U,
+    0xbafd4719U, 0x0241207cU, 0x10f48f92U, 0xa848e8f7U, 0x9b14583dU,
+    0x23a83f58U, 0x311d90b6U, 0x89a1f7d3U, 0x1476cf6aU, 0xaccaa80fU,
+    0xbe7f07e1U, 0x06c36084U, 0x5ea070d2U, 0xe61c17b7U, 0xf4a9b859U,
+    0x4c15df3cU, 0xd1c2e785U, 0x697e80e0U, 0x7bcb2f0eU, 0xc377486bU,
+    0xcb0d0fa2U, 0x73b168c7U, 0x6104c729U, 0xd9b8a04cU, 0x446f98f5U,
+    0xfcd3ff90U, 0xee66507eU, 0x56da371bU, 0x0eb9274dU, 0xb6054028U,
+    0xa4b0efc6U, 0x1c0c88a3U, 0x81dbb01aU, 0x3967d77fU, 0x2bd27891U,
+    0x936e1ff4U, 0x3b26f703U, 0x839a9066U, 0x912f3f88U, 0x299358edU,
+    0xb4446054U, 0x0cf80731U, 0x1e4da8dfU, 0xa6f1cfbaU, 0xfe92dfecU,
+    0x462eb889U, 0x549b1767U, 0xec277002U, 0x71f048bbU, 0xc94c2fdeU,
+    0xdbf98030U, 0x6345e755U, 0x6b3fa09cU, 0xd383c7f9U, 0xc1366817U,
+    0x798a0f72U, 0xe45d37cbU, 0x5ce150aeU, 0x4e54ff40U, 0xf6e89825U,
+    0xae8b8873U, 0x1637ef16U, 0x048240f8U, 0xbc3e279dU, 0x21e91f24U,
+    0x99557841U, 0x8be0d7afU, 0x335cb0caU, 0xed59b63bU, 0x55e5d15eU,
+    0x47507eb0U, 0xffec19d5U, 0x623b216cU, 0xda874609U, 0xc832e9e7U,
+    0x708e8e82U, 0x28ed9ed4U, 0x9051f9b1U, 0x82e4565fU, 0x3a58313aU,
+    0xa78f0983U, 0x1f336ee6U, 0x0d86c108U, 0xb53aa66dU, 0xbd40e1a4U,
+    0x05fc86c1U, 0x1749292fU, 0xaff54e4aU, 0x322276f3U, 0x8a9e1196U,
+    0x982bbe78U, 0x2097d91dU, 0x78f4c94bU, 0xc048ae2eU, 0xd2fd01c0U,
+    0x6a4166a5U, 0xf7965e1cU, 0x4f2a3979U, 0x5d9f9697U, 0xe523f1f2U,
+    0x4d6b1905U, 0xf5d77e60U, 0xe762d18eU, 0x5fdeb6ebU, 0xc2098e52U,
+    0x7ab5e937U, 0x680046d9U, 0xd0bc21bcU, 0x88df31eaU, 0x3063568fU,
+    0x22d6f961U, 0x9a6a9e04U, 0x07bda6bdU, 0xbf01c1d8U, 0xadb46e36U,
+    0x15080953U, 0x1d724e9aU, 0xa5ce29ffU, 0xb77b8611U, 0x0fc7e174U,
+    0x9210d9cdU, 0x2aacbea8U, 0x38191146U, 0x80a57623U, 0xd8c66675U,
+    0x607a0110U, 0x72cfaefeU, 0xca73c99bU, 0x57a4f122U, 0xef189647U,
+    0xfdad39a9U, 0x45115eccU, 0x764dee06U, 0xcef18963U, 0xdc44268dU,
+    0x64f841e8U, 0xf92f7951U, 0x41931e34U, 0x5326b1daU, 0xeb9ad6bfU,
+    0xb3f9c6e9U, 0x0b45a18cU, 0x19f00e62U, 0xa14c6907U, 0x3c9b51beU,
+    0x842736dbU, 0x96929935U, 0x2e2efe50U, 0x2654b999U, 0x9ee8defcU,
+    0x8c5d7112U, 0x34e11677U, 0xa9362eceU, 0x118a49abU, 0x033fe645U,
+    0xbb838120U, 0xe3e09176U, 0x5b5cf613U, 0x49e959fdU, 0xf1553e98U,
+    0x6c820621U, 0xd43e6144U, 0xc68bceaaU, 0x7e37a9cfU, 0xd67f4138U,
+    0x6ec3265dU, 0x7c7689b3U, 0xc4caeed6U, 0x591dd66fU, 0xe1a1b10aU,
+    0xf3141ee4U, 0x4ba87981U, 0x13cb69d7U, 0xab770eb2U, 0xb9c2a15cU,
+    0x017ec639U, 0x9ca9fe80U, 0x241599e5U, 0x36a0360bU, 0x8e1c516eU,
+    0x866616a7U, 0x3eda71c2U, 0x2c6fde2cU, 0x94d3b949U, 0x090481f0U,
+    0xb1b8e695U, 0xa30d497bU, 0x1bb12e1eU, 0x43d23e48U, 0xfb6e592dU,
+    0xe9dbf6c3U, 0x516791a6U, 0xccb0a91fU, 0x740cce7aU, 0x66b96194U,
+    0xde0506f1U };
+
+
+template <class INT>
+template <class InIterator>
+UInt32 ChecksumImpl<INT>::exec(InIterator i, unsigned int size, UInt32 crc)
+{
+    InIterator end = i + size;
+    
+    if(isLittleEndian() && size > 3)
+    {
+        // take care of alignment
+        for(; (std::size_t)i % 4 != 0; ++i)
+        {
+            crc = (crc >> 8) ^ table0[(crc ^ *i) & 0xFF];
+        }
+        for(; i < end-3; i+=4)
+        {
+            crc ^= *((UInt32 *)i);
+            crc = table3[crc & 0xFF] ^
+                  table2[(crc >> 8) & 0xFF] ^
+                  table1[(crc >> 16) & 0xFF] ^
+                  table0[crc >> 24];
+        }
+    }
+    for(; i < end; ++i)
+    {
+        crc = (crc >> 8) ^ table0[(crc ^ *i) & 0xFF];
+    }
+    return ~crc;
+}
+
+} // namespace detail
+
+    /** \brief Compute the CRC-32 checksum of a byte array.
+    
+        Implementation note: This function is slower on big-endian machines
+        because the "4 bytes at a time" optimization is only implemented for 
+        little-endian.
+    */
+inline UInt32 checksum(const char * data, unsigned int size)
+{
+    return detail::ChecksumImpl<UInt32>::exec(data, size);
+}
+
+    /** Concatenate a byte array to an existing CRC-32 checksum.
+    */
+inline UInt32 concatenateChecksum(UInt32 checksum, const char * data, unsigned int size)
+{
+    
+    return detail::ChecksumImpl<UInt32>::exec(data, size, ~checksum);
+}
+
+template <class T>
+void updateMin(T & x, const T & y)
+{
+    using std::min;
+    x = min(x, y);
+}
+
+template <class T>
+void updateMax(T & x, const T & y)
+{
+    using std::max;
+    x = max(x, y);
+}
+
+
+//@}
+
+} // namespace vigra
+
+#endif /* VIGRA_ALGORITHM_HXX */
diff --git a/include/vigra/array_vector.hxx b/include/vigra/array_vector.hxx
new file mode 100644
index 0000000..04816bc
--- /dev/null
+++ b/include/vigra/array_vector.hxx
@@ -0,0 +1,918 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_ARRAY_VECTOR_HXX
+#define VIGRA_ARRAY_VECTOR_HXX
+
+#include "error.hxx"
+#include "memory.hxx"
+#include "numerictraits.hxx"
+#include <memory>
+#include <algorithm>
+#include <iosfwd>
+
+#ifdef VIGRA_CHECK_BOUNDS
+#define VIGRA_ASSERT_INSIDE(diff) \
+  vigra_precondition(diff >= 0, "Index out of bounds");\
+  vigra_precondition((unsigned int)diff < size_, "Index out of bounds");
+#else
+#define VIGRA_ASSERT_INSIDE(diff)
+#endif
+
+namespace vigra
+{
+
+template <class T, class Alloc = std::allocator<T> >
+class ArrayVector;
+
+/** Provide STL conforming interface for C-arrays.
+
+    This template implements much of the functionality of <a href="http://www.sgi.com/tech/stl/Vector.html">std::vector</a>
+    on top of a C-array. <tt>ArrayVectorView</tt> does not manage the memory
+    it refers to (i.e. it does not allocate or deallocate any memory).
+    Thus, if the underlying memory changes, all dependent <tt>ArrayVectorView</tt>
+    objects are invalidated. This is especially important when <tt>ArrayVectorView</tt>
+    is used as a base class for <tt>ArrayVector</tt>, where several functions
+    (e.g. resize(), insert()) can allocate new memory and thus invalidate the
+    dependent views. The rules what operations invalidate view objects are the
+    same as the rules concerning standard iterators.
+
+    <b>\#include</b> \<vigra/array_vector.hxx\><br>
+    Namespace: vigra
+*/
+template <class T>
+class ArrayVectorView
+{
+    typedef ArrayVectorView<T> this_type;
+
+public:
+        /** default constructor
+        */
+    typedef T value_type;
+    typedef value_type & reference;
+    typedef value_type const & const_reference;
+    typedef value_type * pointer;
+    typedef value_type const * const_pointer;
+    typedef value_type * iterator;
+    typedef value_type const * const_iterator;
+    typedef std::size_t size_type;
+    typedef std::ptrdiff_t difference_type;
+    typedef std::reverse_iterator<iterator> reverse_iterator;
+    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+public:
+        /** default constructor.
+            View contains NULL pointer.
+        */
+    ArrayVectorView()
+    : size_(0),
+      data_(0)
+    {}
+
+        /** Construct for given array \a data of length \a size.
+            <tt>data, data+size</tt> must form a valid range.
+        */
+    ArrayVectorView( size_type size, pointer const & data)
+    : size_(size),
+      data_(data)
+    {}
+
+        /** Copy constructor.
+        */
+    ArrayVectorView( this_type const & rhs )
+    : size_(rhs.size_),
+      data_(rhs.data_)
+    {}
+
+        /** Copy assignment. There are 3 cases:
+
+            <ul>
+            <li> When this <tt>ArrayVectorView</tt> does not point to valid data
+                 (e.g. after default construction), it becomes a copy of \a rhs.
+            <li> When the shapes of the two arrays match, the array contents
+                 (not the pointers) are copied.
+            <li> Otherwise, a <tt>PreconditionViolation</tt> exception is thrown.
+            </ul>
+        */
+    ArrayVectorView & operator=( ArrayVectorView const & rhs );
+
+        /** Copy assignment.
+            When the shapes of the two arrays match, the array contents
+            (not the pointers) are copied. Otherwise, a <tt>PreconditionViolation</tt>
+            exception is thrown.
+        */
+    template <class U>
+    this_type & operator=( ArrayVectorView<U> const & rhs )
+    {
+        copyImpl(rhs);
+        return *this;
+    }
+
+        /** Overwrite all array elements with the value \a initial.
+        */
+    template <class U>
+    void init(U const & initial)
+    {
+        std::fill(begin(), end(), initial);
+    }
+
+        /** Copy array elements.
+            When the shapes of the two arrays match, the array contents
+            (not the pointers) are copied. Otherwise, a <tt>PreconditionViolation</tt>
+            exception is thrown.
+        */
+    void copy( this_type const & rhs )
+    {
+        if(data_ != rhs.data_)
+            copyImpl(rhs);
+    }
+
+        /** Copy array elements.
+            When the shapes of the two arrays match, the array contents
+            (not the pointers) are copied. Otherwise, a <tt>PreconditionViolation</tt>
+            exception is thrown.
+        */
+    template <class U>
+    void copy( ArrayVectorView<U> const & rhs )
+    {
+        copyImpl(rhs);
+    }
+
+        /** Swap array elements.
+            When the shapes of the two arrays match, the array contents
+            (not the pointers) are swapped. Otherwise, a <tt>PreconditionViolation</tt>
+            exception is thrown.
+        */
+    void swapData(this_type rhs)
+    {
+        if(data_ != rhs.data_)
+            swapDataImpl(rhs);
+    }
+
+        /** Swap array elements.
+            When the shapes of the two arrays match, the array contents
+            (not the pointers) are swapped. Otherwise, a <tt>PreconditionViolation</tt>
+            exception is thrown.
+        */
+    template <class U>
+    void swapData(ArrayVectorView<U> rhs)
+    {
+        swapDataImpl(rhs);
+    }
+
+        /** Construct <tt>ArrayVectorView</tt> referring to a subarray.
+            \a begin and \a end must be a valid sub-range of the current array.
+            Otherwise, a <tt>PreconditionViolation</tt>
+            exception is thrown.
+        */
+    this_type subarray (size_type begin, size_type end) const
+    {
+        vigra_precondition(begin <= end && end <= size_,
+                "ArrayVectorView::subarray(): Limits out of range.");
+        return this_type(end-begin, data_ + begin);
+    }
+
+        /** Get contained const pointer to the data.
+        */
+    inline const_pointer data() const
+    {
+        return data_;
+    }
+
+        /** Get contained pointer to the data.
+        */
+    inline pointer data()
+    {
+        return data_;
+    }
+
+        /** Get const iterator referring to the first array element.
+        */
+    inline const_iterator begin() const
+    {
+        return data();
+    }
+
+        /** Get iterator referring to the first array element.
+        */
+    inline iterator begin()
+    {
+        return data();
+    }
+
+        /** Get const iterator pointing beyond the last array element.
+        */
+    inline const_iterator end() const
+    {
+        return data() + size();
+    }
+
+        /** Get iterator pointing beyond the last array element.
+        */
+    inline iterator end()
+    {
+        return data() + size();
+    }
+
+        /** Get reverse iterator referring to the last array element.
+        */
+    inline reverse_iterator rbegin()
+    {
+        return (reverse_iterator(end()));
+    }
+
+        /** Get const reverse iterator referring to the last array element.
+        */
+    inline const_reverse_iterator rbegin() const
+    {
+        return (const_reverse_iterator(end()));
+    }
+
+        /** Get reverse iterator pointing before the first array element.
+        */
+    inline reverse_iterator rend()
+    {
+        return (reverse_iterator(begin()));
+    }
+
+        /** Get const reverse iterator pointing before the first array element.
+        */
+    inline const_reverse_iterator rend() const
+    {
+        return (const_reverse_iterator(begin()));
+    }
+
+        /** Access first array element.
+        */
+    reference front()
+    {
+        return *data_;
+    }
+
+        /** Read first array element.
+        */
+    const_reference front() const
+    {
+        return *data_;
+    }
+
+        /** Access last array element.
+        */
+    reference back()
+    {
+        return data_[size_-1];
+    }
+
+        /** Read last array element.
+        */
+    const_reference back() const
+    {
+        return data_[size_-1];
+    }
+
+        /** Access array element \a i.
+        */
+    reference operator[]( difference_type i )
+    {
+        VIGRA_ASSERT_INSIDE(i);
+        return data()[i];
+    }
+
+        /** Read array element \a i.
+        */
+    const_reference operator[]( difference_type i ) const
+    {
+        VIGRA_ASSERT_INSIDE(i);
+        return data()[i];
+    }
+
+        /** Equivalent to <tt>size() == 0</tt>.
+        */
+    bool empty() const
+    {
+        return size_ == 0;
+    }
+
+        /** Number of elements in the array.
+        */
+    size_type size() const
+    {
+        return size_;
+    }
+
+        /** Check for element-wise equality of two array.
+            Also returns <tt>false</tt> if the two arrays have different sizes.
+        */
+    template <class U>
+    bool operator==(ArrayVectorView<U> const & rhs) const;
+
+        /** check whether two arrays are not elementwise equal.
+            Also returns <tt>true</tt> if the two arrays have different sizes.
+         */
+    template <class U>
+    bool operator!=(ArrayVectorView<U> const & rhs) const
+    {
+        return !operator==(rhs);
+    }
+
+        /** check whether the given point is in the array range.
+         */
+    bool isInside (difference_type const & p) const
+    {
+        return p >= 0 && p < size_;
+    }
+
+  protected:
+
+    template <class U>
+    void copyImpl(const ArrayVectorView <U>& rhs);
+
+    void copyImpl(const ArrayVectorView & rhs);
+
+    template <class U>
+    void swapDataImpl(const ArrayVectorView <U>& rhs);
+
+    size_type size_;
+    pointer data_;
+};
+
+template <class T>
+ArrayVectorView<T> & ArrayVectorView<T>::operator=( ArrayVectorView<T> const & rhs )
+{
+    if(data_ == 0)
+    {
+        size_ = rhs.size_;
+        data_ = rhs.data_;
+    }
+    else if(data_ != rhs.data_)
+        copyImpl(rhs);
+    return *this;
+}
+
+template <class T>
+template <class U>
+bool ArrayVectorView<T>::operator==(ArrayVectorView<U> const & rhs) const
+{
+    if(size() != rhs.size())
+        return false;
+    for(unsigned int k=0; k<size(); ++k)
+        if(data_[k] != rhs[k])
+            return false;
+    return true;
+}
+
+template <class T>
+void
+ArrayVectorView <T>::copyImpl(const ArrayVectorView & rhs)
+{
+    vigra_precondition (size() == rhs.size(),
+        "ArrayVectorView::copy(): shape mismatch.");
+    if(size() == 0)  // needed because MSVC debug assertions in std::copy() may fire  
+        return;      // "invalid address: data_ == NULL" even when nothing is to be copied
+    // use copy() or copy_backward() according to possible overlap of this and rhs
+    if(data_ <= rhs.data())
+    {
+        std::copy(rhs.begin(), rhs.end(), begin());
+    }
+    else
+    {
+        std::copy_backward(rhs.begin(), rhs.end(), end());
+    }
+}
+
+template <class T>
+template <class U>
+void
+ArrayVectorView <T>::copyImpl(const ArrayVectorView <U>& rhs)
+{
+    vigra_precondition (size() == rhs.size(),
+        "ArrayVectorView::copy(): shape mismatch.");
+    std::copy(rhs.begin(), rhs.end(), begin());
+}
+
+template <class T>
+template <class U>
+void
+ArrayVectorView <T>::swapDataImpl(const ArrayVectorView <U>& rhs)
+{
+    vigra_precondition (size () == rhs.size() (),
+        "ArrayVectorView::swapData(): size mismatch.");
+
+    // check for overlap
+    if(data_ + size_ <= rhs.data_ || rhs.data_ + size_ <= data_)
+    {
+        for(unsigned int k=0; k<size_; ++k)
+            std::swap(data_[k], rhs.data_[k]);
+    }
+    else
+    {
+        ArrayVector<T> t(*this);
+        copyImpl(rhs);
+        rhs.copyImpl(*this);
+    }
+}
+
+
+/** Replacement for <tt>std::vector</tt>.
+
+    This template implements the same functionality as <tt>a href="http://www.sgi.com/tech/stl/Vector.html">std::vector</a></tt> (see there for detailed documentation).
+    However, it gives two useful guarantees, that <tt>std::vector</tt> fails
+    to provide:
+
+    <ul>
+    <li>The memory is always allocated as one contiguous piece.</li>
+    <li>The iterator is always a <TT>T *</TT> </li>
+    </ul>
+
+    This means that memory managed by <tt>ArrayVector</tt> can be passed
+    to algorithms that expect raw memory. This is especially important
+    when legacy or C code has to be called, but it is also useful for certain
+    optimizations.
+
+    Moreover, <tt>ArrayVector</tt> is derived from <tt>ArrayVectorView</tt> so that one
+    can create views of the array (in particular, subarrays). This implies another
+    important difference to <tt>std::vector</tt>: the indexing operator
+    (<tt>ArrayVector::operator[]</tt>) takes <tt>signed</tt> indices. In this way,
+    an <tt>ArrayVectorView</tt> can be used with negative indices:
+
+    \code
+    ArrayVector<int> data(100);
+    ArrayVectorView<int> view = data.subarray(50, 100);
+
+    view[-50] = 1; // valid access
+    \endcode
+
+    Refer to the documentation of <tt>std::vector</tt> for a detailed
+    description of <tt>ArrayVector</tt> functionality.
+
+    <b>\#include</b> \<vigra/array_vector.hxx\><br>
+    Namespace: vigra
+*/
+template <class T, class Alloc /* = std::allocator<T> */ >
+class ArrayVector
+: public ArrayVectorView<T>
+{
+    typedef ArrayVector<T, Alloc> this_type;
+    enum { minimumCapacity = 2, resizeFactor = 2 };
+
+public:
+    typedef ArrayVectorView<T> view_type;
+    typedef typename view_type::value_type value_type;
+    typedef typename view_type::reference reference;
+    typedef typename view_type::const_reference const_reference;
+    typedef typename view_type::pointer pointer;
+    typedef typename view_type::const_pointer const_pointer;
+    typedef typename view_type::iterator iterator;
+    typedef typename view_type::const_iterator const_iterator;
+    typedef typename view_type::size_type size_type;
+    typedef typename view_type::difference_type difference_type;
+    typedef typename view_type::reverse_iterator reverse_iterator;
+    typedef typename view_type::const_reverse_iterator const_reverse_iterator;
+    typedef Alloc        allocator_type;
+
+public:
+    ArrayVector()
+    : view_type(),
+      capacity_(minimumCapacity),
+      alloc_(Alloc())
+    {
+        this->data_ = reserve_raw(capacity_);
+    }
+
+    explicit ArrayVector(Alloc const & alloc)
+    : view_type(),
+      capacity_(minimumCapacity),
+      alloc_(alloc)
+    {
+        this->data_ = reserve_raw(capacity_);
+    }
+
+    explicit ArrayVector( size_type size, Alloc const & alloc = Alloc())
+    : view_type(),
+      alloc_(alloc)
+    {
+        initImpl(size, value_type(), VigraTrueType());
+    }
+
+    ArrayVector( size_type size, value_type const & initial, Alloc const & alloc = Alloc())
+    : view_type(),
+      alloc_(alloc)
+    {
+        initImpl(size, initial, VigraTrueType());
+    }
+
+
+    ArrayVector( this_type const & rhs )
+    : view_type(),
+      alloc_(rhs.alloc_)
+    {
+        initImpl(rhs.begin(), rhs.end(), VigraFalseType());
+    }
+
+    template <class U>
+    explicit ArrayVector( ArrayVectorView<U> const & rhs, Alloc const & alloc = Alloc() )
+    : view_type(),
+      alloc_(alloc)
+    {
+        initImpl(rhs.begin(), rhs.end(), VigraFalseType());
+    }
+
+    template <class InputIterator>
+    ArrayVector(InputIterator i, InputIterator end)
+    {
+        initImpl(i, end, typename NumericTraits<InputIterator>::isIntegral());
+    }
+
+    template <class InputIterator>
+    ArrayVector(InputIterator i, InputIterator end, Alloc const & alloc)
+    : alloc_(alloc)
+    {
+        initImpl(i, end, typename NumericTraits<InputIterator>::isIntegral());
+    }
+
+    this_type & operator=( this_type const & rhs )
+    {
+        if(this == &rhs)
+            return *this;
+        if(this->size_ == rhs.size_)
+            this->copyImpl(rhs);
+        else
+        {
+            ArrayVector t(rhs);
+            this->swap(t);
+        }
+        return *this;
+    }
+
+    template <class U>
+    this_type & operator=( ArrayVectorView<U> const & rhs);
+
+    ~ArrayVector()
+    {
+        deallocate(this->data_, this->size_);
+    }
+
+    void pop_back();
+
+    void push_back( value_type const & t );
+
+    iterator insert(iterator p, value_type const & v);
+
+    iterator insert(iterator p, size_type n, value_type const & v);
+
+    template <class InputIterator>
+    iterator insert(iterator p, InputIterator i, InputIterator iend);
+
+    iterator erase(iterator p);
+
+    iterator erase(iterator p, iterator q);
+
+    void clear();
+
+    void reserve( size_type new_capacity );
+
+    void reserve();
+
+    void resize( size_type new_size, value_type const & initial );
+
+    void resize( size_type new_size )
+    {
+        resize(new_size, value_type());
+    }
+
+    size_type capacity() const
+    {
+        return capacity_;
+    }
+
+    void swap(this_type & rhs);
+
+  private:
+
+    void deallocate(pointer data, size_type size);
+
+    pointer reserve_raw(size_type capacity);
+
+    void initImpl( size_type size, value_type const & initial, VigraTrueType /*isIntegral*/);
+
+    template <class Iter>
+    void initImpl( Iter i, Iter end, VigraFalseType /*isIntegral*/);
+
+    template <class Iter>
+    void initImpl( Iter i, Iter end, Error_NumericTraits_not_specialized_for_this_case)
+    {
+        initImpl(i, end, VigraFalseType());
+    }
+
+    size_type capacity_;
+    Alloc alloc_;
+};
+
+template <class T, class Alloc>
+template <class U>
+ArrayVector<T, Alloc> & ArrayVector<T, Alloc>::operator=( ArrayVectorView<U> const & rhs )
+{
+    if(this->size_ == rhs.size())
+        this->copyImpl(rhs);
+    else
+    {
+        ArrayVector t(rhs);
+        this->swap(t);
+    }
+    return *this;
+}
+
+template <class T, class Alloc>
+inline void ArrayVector<T, Alloc>::pop_back()
+{
+    --this->size_;
+    alloc_.destroy(this->data_ + this->size_);
+}
+
+template <class T, class Alloc>
+inline void ArrayVector<T, Alloc>::push_back( value_type const & t )
+{
+    reserve();
+    alloc_.construct(this->data_ + this->size_, t);
+    ++this->size_;
+}
+
+template <class T, class Alloc>
+inline void ArrayVector<T, Alloc>::clear()
+{
+    detail::destroy_n(this->data_, (int)this->size_);
+    this->size_ = 0;
+}
+
+template <class T, class Alloc>
+typename ArrayVector<T, Alloc>::iterator
+ArrayVector<T, Alloc>::insert(iterator p, value_type const & v)
+{
+    difference_type pos = p - this->begin();
+    if(p == this->end())
+    {
+        push_back(v);
+        p = this->begin() + pos;
+    }
+    else
+    {
+        T lastElement = this->back();
+        push_back(lastElement);
+        p = this->begin() + pos;
+        std::copy_backward(p, this->end() - 2, this->end() - 1);
+        *p = v;
+    }
+    return p;
+}
+
+template <class T, class Alloc>
+typename ArrayVector<T, Alloc>::iterator
+ArrayVector<T, Alloc>::insert(iterator p, size_type n, value_type const & v)
+{
+    difference_type pos = p - this->begin();
+    size_type new_size = this->size() + n;
+    if(new_size > capacity_)
+    {
+        size_type new_capacity = std::max(new_size, resizeFactor*capacity_);
+        pointer new_data = reserve_raw(new_capacity);
+        try
+        {
+            std::uninitialized_copy(this->begin(), p, new_data);
+            std::uninitialized_fill(new_data + pos, new_data + pos + n, v);
+            std::uninitialized_copy(p, this->end(), new_data + pos + n);
+        }
+        catch(...)
+        {
+            alloc_.deallocate(new_data, new_capacity);
+            throw;
+        }
+        deallocate(this->data_, this->size_);
+        capacity_ = new_capacity;
+        this->data_ = new_data;
+    }
+    else if(pos + n > this->size_)
+    {
+        size_type diff = pos + n - this->size_;
+        std::uninitialized_copy(p, this->end(), this->end() + diff);
+        std::uninitialized_fill(this->end(), this->end() + diff, v);
+        std::fill(p, this->end(), v);
+    }
+    else
+    {
+        size_type diff = this->size_ - (pos + n);
+        std::uninitialized_copy(this->end() - n, this->end(), this->end());
+        std::copy_backward(p, p + diff, this->end());
+        std::fill(p, p + n, v);
+    }
+    this->size_ = new_size;
+    return this->begin() + pos;
+}
+
+template <class T, class Alloc>
+template <class InputIterator>
+typename ArrayVector<T, Alloc>::iterator
+ArrayVector<T, Alloc>::insert(iterator p, InputIterator i, InputIterator iend)
+{
+    size_type n = std::distance(i, iend);
+    size_type pos = p - this->begin();
+    size_type new_size = this->size() + n;
+    if(new_size > capacity_)
+    {
+        size_type new_capacity = std::max(new_size, resizeFactor*capacity_);
+        pointer new_data = reserve_raw(new_capacity);
+        try
+        {
+            std::uninitialized_copy(this->begin(), p, new_data);
+            std::uninitialized_copy(i, iend, new_data + pos);
+            std::uninitialized_copy(p, this->end(), new_data + pos + n);
+        }
+        catch(...)
+        {
+            alloc_.deallocate(new_data, new_capacity);
+            throw;
+        }
+        deallocate(this->data_, this->size_);
+        capacity_ = new_capacity;
+        this->data_ = new_data;
+    }
+    else if(pos + n > this->size_)
+    {
+        size_type diff = pos + n - this->size_;
+        std::uninitialized_copy(p, this->end(), this->end() + diff);
+        InputIterator split = i;
+        std::advance(split, n - diff);
+        std::uninitialized_copy(split, iend, this->end());
+        std::copy(i, split, p);
+    }
+    else
+    {
+        size_type diff = this->size_ - (pos + n);
+        std::uninitialized_copy(this->end() - n, this->end(), this->end());
+        std::copy_backward(p, p + diff, this->end());
+        std::copy(i, iend, p);
+    }
+    this->size_ = new_size;
+    return this->begin() + pos;
+}
+
+template <class T, class Alloc>
+typename ArrayVector<T, Alloc>::iterator
+ArrayVector<T, Alloc>::erase(iterator p)
+{
+    std::copy(p+1, this->end(), p);
+    pop_back();
+    return p;
+}
+
+template <class T, class Alloc>
+typename ArrayVector<T, Alloc>::iterator
+ArrayVector<T, Alloc>::erase(iterator p, iterator q)
+{
+    std::copy(q, this->end(), p);
+    difference_type eraseCount = q - p;
+    detail::destroy_n(this->end() - eraseCount, eraseCount);
+    this->size_ -= eraseCount;
+    return p;
+}
+
+template <class T, class Alloc>
+inline void
+ArrayVector<T, Alloc>::reserve( size_type new_capacity )
+{
+    if(new_capacity <= capacity_)
+        return;
+    pointer new_data = reserve_raw(new_capacity);
+    if(this->size_ > 0)
+        std::uninitialized_copy(this->data_, this->data_+this->size_, new_data);
+    deallocate(this->data_, this->size_);
+    this->data_ = new_data;
+    capacity_ = new_capacity;
+}
+
+template <class T, class Alloc>
+inline void
+ArrayVector<T, Alloc>::reserve()
+{
+    if(capacity_ == 0)
+        reserve(minimumCapacity);
+    else if(this->size_ == capacity_)
+        reserve(resizeFactor*capacity_);
+}
+
+template <class T, class Alloc>
+inline void
+ArrayVector<T, Alloc>::resize( size_type new_size, value_type const & initial)
+{
+    if(new_size < this->size_)
+        erase(this->begin() + new_size, this->end());
+    else if(this->size_ < new_size)
+    {
+        insert(this->end(), new_size - this->size(), initial);
+    }
+}
+
+template <class T, class Alloc>
+inline void
+ArrayVector<T, Alloc>::initImpl( size_type size, value_type const & initial, VigraTrueType /*isIntegral*/)
+{
+    this->size_ = size;
+    capacity_ = size;
+    this->data_ = reserve_raw(capacity_);
+    if(this->size_ > 0)
+        std::uninitialized_fill(this->data_, this->data_+this->size_, initial);
+}
+
+template <class T, class Alloc>
+template <class Iter>
+inline void
+ArrayVector<T, Alloc>::initImpl( Iter i, Iter end, VigraFalseType /*isIntegral*/)
+{
+    this->size_ = std::distance(i, end);
+    capacity_ = this->size_;
+    this->data_ = reserve_raw(capacity_);
+    if(this->size_ > 0)
+        detail::uninitializedCopy(i, end, this->data_);
+}
+
+template <class T, class Alloc>
+inline void
+ArrayVector<T, Alloc>::swap(this_type & rhs)
+{
+    std::swap(this->size_, rhs.size_);
+    std::swap(capacity_, rhs.capacity_);
+    std::swap(this->data_, rhs.data_);
+}
+
+template <class T, class Alloc>
+inline void
+ArrayVector<T, Alloc>::deallocate(pointer data, size_type size)
+{
+    if(data)
+    {
+        detail::destroy_n(data, (int)size);
+        alloc_.deallocate(data, size);
+    }
+}
+
+template <class T, class Alloc>
+inline typename ArrayVector<T, Alloc>::pointer
+ArrayVector<T, Alloc>::reserve_raw(size_type capacity)
+{
+    pointer data = 0;
+    if(capacity)
+    {
+        data = alloc_.allocate(capacity);
+    }
+    return data;
+}
+
+} // namespace vigra
+
+namespace std {
+
+template <class T>
+ostream & operator<<(ostream & s, vigra::ArrayVectorView<T> const & a)
+{
+    for(int k=0; k<(int)a.size()-1; ++k)
+        s << a[k] << ", ";
+    if(a.size())
+            s << a.back();
+    return s;
+}
+
+} // namespace std
+
+#undef VIGRA_ASSERT_INSIDE
+#endif /* VIGRA_ARRAY_VECTOR_HXX */
diff --git a/include/vigra/autodiff.hxx b/include/vigra/autodiff.hxx
new file mode 100644
index 0000000..3353a4f
--- /dev/null
+++ b/include/vigra/autodiff.hxx
@@ -0,0 +1,636 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2012-2013 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_AUTODIFF_HXX
+#define VIGRA_AUTODIFF_HXX
+
+#include "tinyvector.hxx"
+#include "mathutil.hxx"
+#include <cmath>
+
+namespace vigra {
+
+namespace autodiff {
+
+/** Number type for automatic differentiation.
+
+    <a href="http://en.wikipedia.org/wiki/Automatic_differentiation">Automatic differentiation</a> 
+    allows one to compute the value of a numeric expression and its gradient 
+    with respect to the expression's arguments automatically and in one go. 
+    To support this, one needs a special number type that holds a scalar value
+    and the corresponding gradient vector of appropriate length. This is the
+    purpose of hte template class <tt>DualVector<T, N></tt>, where <tt>T</tt> is the
+    underlying numerical type (usually 'double'), and <tt>N</tt> denotes the 
+    length of the gradient vector. 
+    
+    The standard arithmetic and algebraic functions are overloaded for 
+    <tt>DualVector</tt> in order to implement the required arithmetic of 
+    dual numbers. When you replace all arguments in a numeric expression
+    with the appropriate <tt>DualVector</tt> instances, the result will be
+    a <tt>DualVector</tt> that contains the result value and gradient of
+    the expression, evaluated at the point defined by the input values.
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/autodiff.hxx\><br>
+    Namespace: vigra::autodiff
+
+    \code
+    typedef DualVector<double, 2> N;  // for expressions with two arguments
+    
+    N x(1.0, 0);  // first argument of the expression
+    N s(2.0, 1);  // second argument of the expression
+    
+    N y = exp(-0.5 * sq(x / s));
+    
+    std::cout << "Evaluated exp(- x^2 / (2 s^2)) at x=1 and s = 2:\n";
+    std::cout << "result = " << y.value() <<", gradient = " << y.gradient() << "\n";
+    \endcode
+    Note that the second argument of the <tt>DualVector</tt> constructors specifies that 
+    the derivative w.r.t 'x' shall be the element 0 of the gradient vector, and the
+    derivative w.r.t. 's' shall be element 1.
+*/
+template <class T, int N>
+class DualVector
+{
+  public:
+    typedef T                 value_type; ///< type of function values and gradient elements
+    typedef TinyVector<T, N>  Gradient;   ///< type of the gradient vector
+    
+    T v;
+    Gradient d;
+    
+        /** Zero initialization.
+        */
+    DualVector()
+    : v(), d()
+    {}
+    
+        /** Provide a value, but zero-initialize the gradient.
+        */
+    explicit DualVector(T const & val)
+    : v(val), d()
+    {}
+    
+        /** Initialize with given value and gradient.
+        */
+    DualVector(T const & val, Gradient const & grad)
+    : v(val), d(grad)
+    {}
+    
+        /** Shorthand for <tt>DualVector(val, Gradient(g0))</tt> when <tt>N == 1</tt>.
+        
+            Not to be used when <tt>N != 1</tt>.
+        */
+    DualVector(T const & val, T const & g0)
+    : v(val), d(g0)
+    {}
+    
+        /** Shorthand for <tt>DualVector(val, Gradient(g0, g1))</tt> when <tt>N == 2</tt>.
+        
+            Not to be used when <tt>N != 2</tt>.
+        */
+    DualVector(T const & val, T const & g0, T const & g1)
+    : v(val), d(g0, g1)
+    {}
+    
+        /** Initialize value to represent the argument number 'targetElement' in an
+            expression. 
+
+            The derivative of the expression w.r.t. this variable will be element 'targetElement'
+            of the resulting gradient vector.
+        */
+    DualVector(T const & val, int targetElement)
+    : v(val), d()
+    {
+        d[targetElement] = T(1.0);
+    }
+    
+        /** Get current value.
+        */
+    T value() const
+    {
+        return v;
+    }
+    
+        /** Get current gradient.
+        */
+    Gradient const & gradient() const
+    {
+        return d;
+    }
+    
+    DualVector operator+() const
+    {
+        return *this;
+    }
+    
+    DualVector operator-() const
+    {
+        return DualVector(-v, -d);
+    }
+    
+    DualVector & operator+=(DualVector const & o)
+    {
+        d += o.d;
+        v += o.v;
+        return *this;
+    }
+    
+    DualVector & operator+=(T const & o)
+    {
+        v += o;
+        return *this;
+    }
+    
+    DualVector & operator-=(DualVector const & o)
+    {
+        d -= o.d;
+        v -= o.v;
+        return *this;
+    }
+    
+    DualVector & operator-=(T const & o)
+    {
+        v -= o;
+        return *this;
+    }
+    
+    DualVector & operator*=(DualVector const & o)
+    {
+        d = o.v * d + v * o.d;
+        v *= o.v;
+        return *this;
+    }
+    
+    DualVector & operator*=(T const & o)
+    {
+        d *= o;
+        v *= o;
+        return *this;
+    }
+    
+    DualVector & operator/=(DualVector const & o)
+    {
+        d = (o.v * d - v * o.d) / sq(o.v);
+        v /= o.v;
+        return *this;
+    }
+    
+    DualVector & operator/=(T const & o)
+    {
+        d /= o;
+        v /= o;
+        return *this;
+    }
+};
+
+    /** Given a vector 'v' of expression arguments, create the corresponding
+        vector of dual numbers for automatic differentiation.
+    */
+template <class T, int N>
+TinyVector<DualVector<T, N>, N>
+dualMatrix(TinyVector<T, N> const & v)
+{
+    TinyVector<DualVector<T, N>, N> res;
+    for(int k=0; k<N; ++k)
+    {
+        res[k].v = v[k];
+        res[k].d[k] = T(1.0);
+    }
+    return res;
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator+(DualVector<T, N> v1, DualVector<T, N> const & v2)
+{
+    return v1 += v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator+(DualVector<T, N> v1, T v2)
+{
+    return v1 += v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator+(T v1, DualVector<T, N> v2)
+{
+    return v2 += v1;
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator-(DualVector<T, N> v1, DualVector<T, N> const & v2)
+{
+    return v1 -= v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator-(DualVector<T, N> v1, T v2)
+{
+    return v1 -= v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator-(T v1, DualVector<T, N> const & v2)
+{
+    return DualVector<T, N>(v1 - v2.v, -v2.d);
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator*(DualVector<T, N> v1, DualVector<T, N> const & v2)
+{
+    return v1 *= v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator*(DualVector<T, N> v1, T v2)
+{
+    return v1 *= v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator*(T v1, DualVector<T, N> v2)
+{
+    return v2 *= v1;
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator/(DualVector<T, N> v1, DualVector<T, N> const & v2)
+{
+    return v1 /= v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator/(DualVector<T, N> v1, T v2)
+{
+    return v1 /= v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> operator/(T v1, DualVector<T, N> const & v2)
+{
+    return DualVector<T, N>(v1 / v2.v, -v1*v2.d / sq(v2.v));
+}
+
+using vigra::abs;
+// abs(x + h) => x + h or -(x + h)
+template <typename T, int N>
+inline DualVector<T, N> abs(DualVector<T, N> const & v)
+{
+    return v.v < T(0.0) ? -v : v;
+}
+
+using std::fabs;
+// abs(x + h) => x + h or -(x + h)
+template <typename T, int N>
+inline DualVector<T, N> fabs(DualVector<T, N> const & v)
+{
+    return v.v < T(0.0) ? -v : v;
+}
+
+using std::log;
+// log(a + h) => log(a) + h / a
+template <typename T, int N>
+inline DualVector<T, N> log(DualVector<T, N> v) 
+{
+    v.d /= v.v;
+    v.v = log(v.v);
+    return v;
+}
+
+using std::exp;
+// exp(a + h) => exp(a) + exp(a) h
+template <class T, int N>
+inline DualVector<T, N> exp(DualVector<T, N> v)
+{
+    v.v = exp(v.v);
+    v.d *= v.v;
+    return v;
+}
+
+using vigra::sqrt;
+// sqrt(a + h) => sqrt(a) + h / (2 sqrt(a))
+template <typename T, int N>
+inline DualVector<T, N> sqrt(DualVector<T, N> v)
+{
+    v.v = sqrt(v.v);
+    v.d /= T(2.0) * v.v;
+    return v;
+}
+
+using std::sin;
+using std::cos;
+// sin(a + h) => sin(a) + cos(a) h
+template <typename T, int N>
+inline DualVector<T, N> sin(DualVector<T, N> v)
+{
+    v.d *= cos(v.v);
+    v.v = sin(v.v);
+    return v;
+}
+
+// cos(a + h) => cos(a) - sin(a) h
+template <typename T, int N>
+inline DualVector<T, N> cos(DualVector<T, N> v)
+{
+    v.d *= -sin(v.v);
+    v.v = cos(v.v);
+    return v;
+}
+
+using vigra::sin_pi;
+using vigra::cos_pi;
+// sin_pi(a + h) => sin_pi(a) + pi cos_pi(a) h
+template <typename T, int N>
+inline DualVector<T, N> sin_pi(DualVector<T, N> v)
+{
+    v.d *= M_PI*cos_pi(v.v);
+    v.v = sin_pi(v.v);
+    return v;
+}
+
+// cos_pi(a + h) => cos_pi(a) - pi sin_pi(a) h
+template <typename T, int N>
+inline DualVector<T, N> cos_pi(DualVector<T, N> v)
+{
+    v.d *= -M_PI*sin_pi(v.v);
+    v.v = cos_pi(v.v);
+    return v;
+}
+
+using std::asin;
+// asin(a + h) => asin(a) + 1 / sqrt(1 - a^2) h
+template <typename T, int N>
+inline DualVector<T, N> asin(DualVector<T, N> v)
+{
+    v.d /= sqrt(T(1.0) - sq(v.v));
+    v.v = asin(v.v);
+    return v;
+}
+
+using std::acos;
+// acos(a + h) => acos(a) - 1 / sqrt(1 - a^2) h
+template <typename T, int N>
+inline DualVector<T, N> acos(DualVector<T, N> v) 
+{
+    v.d /= -sqrt(T(1.0) - sq(v.v));
+    v.v = acos(v.v);
+    return v;
+}
+
+using std::tan;
+// tan(a + h) => tan(a) + (1 + tan(a)^2) h
+template <typename T, int N>
+inline DualVector<T, N> tan(DualVector<T, N> v)
+{
+    v.v = tan(v.v);
+    v.d *= T(1.0) + sq(v.v);
+    return v;
+}
+
+using std::atan;
+// atan(a + h) => atan(a) + 1 / (1 + a^2) h
+template <typename T, int N>
+inline DualVector<T, N> atan(DualVector<T, N> v)
+{
+    v.d /= T(1.0) + sq(v.v);
+    v.v = atan(v.v);
+    return v;
+}
+
+using std::sinh;
+using std::cosh;
+// sinh(a + h) => sinh(a) + cosh(a) h
+template <typename T, int N>
+inline DualVector<T, N> sinh(DualVector<T, N> v)
+{
+    v.d *= cosh(v.v);
+    v.v = sinh(v.v);
+    return v;
+}
+
+// cosh(a + h) => cosh(a) + sinh(a) h
+template <typename T, int N>
+inline DualVector<T, N> cosh(DualVector<T, N> v) 
+{
+    v.d *= sinh(v.v);
+    v.v = cosh(v.v);
+    return v;
+}
+
+using std::tanh;
+// tanh(a + h) => tanh(a) + (1 - tanh(a)^2) h
+template <typename T, int N>
+inline DualVector<T, N> tanh(DualVector<T, N> v)
+{
+    v.v = tanh(v.v);
+    v.d *= T(1.0) - sq(v.v);
+    return v;
+}
+
+using vigra::sq;
+// (a + h)^2 => a^2 + 2 a h
+template <class T, int N>
+inline DualVector<T, N> sq(DualVector<T, N> v)
+{
+    v.d *= T(2.0)*v.v;
+    v.v *= v.v;
+    return v;
+}
+
+using std::atan2;
+// atan2(b + db, a + da) => atan2(b, a) + (- b da + a db) / (a^2 + b^2)
+template <typename T, int N> 
+inline DualVector<T, N> atan2(DualVector<T, N> v1, DualVector<T, N> const & v2) 
+{
+    v1.d = (v2.v * v1.d - v1.v * v2.d) / (sq(v1.v) + sq(v2.v));
+    v1.v = atan2(v1.v, v2.v);
+    return v1;
+}
+
+
+using vigra::pow;
+// (a+da)^p => a^p + p*a^(p-1) da
+template <typename T, int N> 
+inline DualVector<T, N> pow(DualVector<T, N> v, T p)
+{
+    T pow_p_1 = pow(v.v, p-T(1.0));
+    v.d *= p * pow_p_1;
+    v.v *= pow_p_1;
+    return v;
+}
+
+// (a)^(p+dp) => a^p + a^p log(a) dp
+template <typename T, int N> 
+inline DualVector<T, N> pow(T v, DualVector<T, N> p)
+{
+    p.v = pow(v, p.v);
+    p.d *= p.v * log(v);
+    return p;
+}
+
+
+// (a+da)^(b+db) => a^b + b * a^(b-1) da + a^b log(a) * db
+template <typename T, int N> 
+inline DualVector<T, N> pow(DualVector<T, N> v, DualVector<T, N> const & p)
+{
+    T pow_p_1 = pow(v.v, p.v-T(1.0)),
+      pow_p   = v.v * pow_p_1;
+    v.d = p.v * pow_p_1 * v.d + pow_p * log(v.v) * p.d;
+    v.v = pow_p;
+    return v;
+}
+
+using vigra::min;
+template <class T, int N>
+inline DualVector<T, N> min(DualVector<T, N> const & v1, DualVector<T, N> const & v2)
+{
+    return v1.v < v2.v
+               ? v1
+               : v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> min(T v1, DualVector<T, N> const & v2)
+{
+    return v1 < v2.v
+               ? DualVector<T, N>(v1)
+               : v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> min(DualVector<T, N> const & v1, T v2)
+{
+    return v1.v < v2
+               ? v1
+               : DualVector<T, N>(v2);
+}
+
+using vigra::max;
+template <class T, int N>
+inline DualVector<T, N> max(DualVector<T, N> const & v1, DualVector<T, N> const & v2)
+{
+    return v1.v > v2.v
+               ? v1
+               : v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> max(T v1, DualVector<T, N> const & v2)
+{
+    return v1 > v2.v
+               ? DualVector<T, N>(v1)
+               : v2;
+}
+
+template <class T, int N>
+inline DualVector<T, N> max(DualVector<T, N> const & v1, T v2)
+{
+    return v1.v > v2
+               ? v1
+               : DualVector<T, N>(v2);
+}
+
+template <class T, int N>
+inline bool 
+operator==(DualVector<T, N> const & v1, DualVector<T, N> const & v2)
+{
+    return v1.v == v2.v && v1.d == v2.d;
+}
+
+template <class T, int N>
+inline bool 
+operator!=(DualVector<T, N> const & v1, DualVector<T, N> const & v2)
+{
+    return v1.v != v2.v || v1.d != v2.d;
+}
+
+#define VIGRA_DUALVECTOR_RELATIONAL_OPERATORS(op) \
+template <class T, int N> \
+inline bool  \
+operator op(DualVector<T, N> const & v1, DualVector<T, N> const & v2) \
+{ \
+    return v1.v op v2.v; \
+} \
+ \
+template <class T, int N> \
+inline bool  \
+operator op(T v1, DualVector<T, N> const & v2) \
+{ \
+    return v1 op v2.v; \
+} \
+ \
+template <class T, int N> \
+inline bool  \
+operator op(DualVector<T, N> const & v1, T v2) \
+{ \
+    return v1.v op v2; \
+}
+
+VIGRA_DUALVECTOR_RELATIONAL_OPERATORS(<)
+VIGRA_DUALVECTOR_RELATIONAL_OPERATORS(<=)
+VIGRA_DUALVECTOR_RELATIONAL_OPERATORS(>)
+VIGRA_DUALVECTOR_RELATIONAL_OPERATORS(>=)
+
+#undef VIGRA_DUALVECTOR_RELATIONAL_OPERATORS
+
+template <class T, int N>
+inline bool 
+closeAtTolerance(DualVector<T, N> const & v1, DualVector<T, N> const & v2, 
+                 T epsilon = NumericTraits<T>::epsilon())
+{
+    return vigra::closeAtTolerance(v1.v, v2.v, epsilon) && vigra::closeAtTolerance(v1.d, v2.d, epsilon);
+}
+
+} // namespace autodiff
+
+} // namespace vigra
+
+namespace std {
+
+   /// stream output
+template <class T, int N>
+ostream &
+operator<<(ostream & out, vigra::autodiff::DualVector<T, N> const & l)
+{
+    out << l.v << " " << l.d;
+    return out;
+}
+
+} // namespace std
+
+#endif // VIGRA_AUTODIFF_HXX
diff --git a/include/vigra/axistags.hxx b/include/vigra/axistags.hxx
new file mode 100644
index 0000000..4bb44e1
--- /dev/null
+++ b/include/vigra/axistags.hxx
@@ -0,0 +1,1097 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2010-2011 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_AXISTAGS_HXX
+#define VIGRA_AXISTAGS_HXX
+
+#include "utilities.hxx"
+#include "array_vector.hxx"
+#include "algorithm.hxx"
+#include "error.hxx"
+#include "functorexpression.hxx"
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+namespace vigra {
+
+class AxisInfo
+{
+  public:
+  
+    // this particular assignment of bits to types is crucial for 
+    // canonical axis ordering
+    enum AxisType { Channels = 1, 
+                    Space = 2, 
+                    Angle = 4, 
+                    Time = 8, 
+                    Frequency = 16, 
+                    UnknownAxisType = 32, 
+                    NonChannel = Space | Angle | Time | Frequency | UnknownAxisType,
+                    AllAxes = 2*UnknownAxisType-1 };
+
+    AxisInfo(std::string key = "?", AxisType typeFlags = UnknownAxisType, 
+             double resolution = 0.0, std::string description = "")
+    : key_(key),
+      description_(description),
+      resolution_(resolution),
+      flags_(typeFlags)
+    {}
+    
+    std::string key() const
+    {
+        return key_;
+    }
+    
+    std::string description() const
+    {
+        return description_;
+    }
+    
+    void setDescription(std::string const & description)
+    {
+        description_ = description;
+    }
+    
+    double resolution() const
+    {
+        return resolution_;
+    }
+    
+    void setResolution(double resolution)
+    {
+        resolution_ = resolution;
+    }
+    
+    AxisType typeFlags() const
+    {
+        return flags_ == 0
+                  ? UnknownAxisType
+                  : flags_;
+    }
+    
+    bool isUnknown() const
+    {
+        return isType(UnknownAxisType);
+    }
+    
+    bool isSpatial() const
+    {
+        return isType(Space);
+    }
+    
+    bool isTemporal() const
+    {
+        return isType(Time);
+    }
+    
+    bool isChannel() const
+    {
+        return isType(Channels);
+    }
+    
+    bool isFrequency() const
+    {
+        return isType(Frequency);
+    }
+    
+    bool isAngular() const
+    {
+        return isType(Angle);
+    }
+    
+    bool isType(AxisType type) const
+    {
+        return (typeFlags() & type) != 0;
+    }
+    
+    std::string repr() const
+    {
+        std::string res("AxisInfo: '");
+        res += key_ + "' (type:";
+        if(isUnknown())
+        {
+            res += " none";
+        }
+        else
+        {
+            if(isChannel())
+                res += " Channels";
+            if(isSpatial())
+                res += " Space";
+            if(isTemporal())
+                res += " Time";
+            if(isAngular())
+                res += " Angle";
+            if(isFrequency())
+                res += " Frequency";
+        }
+        if(resolution_ > 0.0)
+        {
+            res += ", resolution=";
+            res += asString(resolution_);
+        }
+        res += ")";
+        if(description_ != "")
+        {
+            res += " ";
+            res += description_;
+        }
+        return res;
+    }
+    
+    AxisInfo toFrequencyDomain(unsigned int size = 0, int sign = 1) const
+    {
+        AxisType type;
+        if(sign == 1)
+        {
+            vigra_precondition(!isFrequency(),
+                "AxisInfo::toFrequencyDomain(): axis is already in the Fourier domain.");
+            type = AxisType(Frequency | flags_);
+        }
+        else
+        {
+            vigra_precondition(isFrequency(),
+                "AxisInfo::fromFrequencyDomain(): axis is not in the Fourier domain.");
+            type = AxisType(~Frequency & flags_);
+        }
+        AxisInfo res(key(), type, 0.0, description_);
+        if(resolution_ > 0.0 && size > 0u)
+            res.resolution_ = 1.0 / (resolution_ * size);
+        return res;
+    }
+    
+    AxisInfo fromFrequencyDomain(unsigned int size = 0) const
+    {
+        return toFrequencyDomain(size, -1);
+    }
+
+    bool compatible(AxisInfo const & other) const
+    {
+        return isUnknown() || other.isUnknown() || 
+               ((typeFlags() & ~Frequency) == (other.typeFlags() & ~Frequency) &&
+                 key() == other.key());
+    }
+
+    bool operator==(AxisInfo const & other) const
+    {
+        return typeFlags() == other.typeFlags() && key() == other.key();
+    }
+
+    bool operator!=(AxisInfo const & other) const
+    {
+        return !operator==(other);
+    }
+    
+    // the primary ordering is according to axis type:
+    //     Channels < Space < Angle < Time < Frequency < Unknown
+    // the secondary ordering is the lexicographic ordering of the keys
+    //     "x" < "y" < "z"
+    bool operator<(AxisInfo const & other) const
+    {
+        return (typeFlags() < other.typeFlags()) || 
+                (typeFlags() == other.typeFlags() && key() < other.key());
+    }
+
+    bool operator<=(AxisInfo const & other) const
+    {
+        return !(other < *this);
+    }
+    
+    bool operator>(AxisInfo const & other) const
+    {
+        return other < *this;
+    }
+    
+    bool operator>=(AxisInfo const & other) const
+    {
+        return !(*this < other);
+    }
+    
+    // factory functions for standard tags
+    static AxisInfo x(double resolution = 0.0, std::string const & description = "")
+    {
+        return AxisInfo("x", Space, resolution, description);
+    }
+    
+    static AxisInfo y(double resolution = 0.0, std::string const & description = "")
+    {
+        return AxisInfo("y", Space, resolution, description);
+    }
+    
+    static AxisInfo z(double resolution = 0.0, std::string const & description = "")
+    {
+        return AxisInfo("z", Space, resolution, description);
+    }
+    
+    static AxisInfo t(double resolution = 0.0, std::string const & description = "")
+    {
+        return AxisInfo("t", Time, resolution, description);
+    }
+    
+    static AxisInfo fx(double resolution = 0.0, std::string const & description = "")
+    {
+        return AxisInfo("x", AxisType(Space | Frequency), resolution, description);
+    }
+    
+    static AxisInfo fy(double resolution = 0.0, std::string const & description = "")
+    {
+        return AxisInfo("y", AxisType(Space | Frequency), resolution, description);
+    }
+    
+    static AxisInfo fz(double resolution = 0.0, std::string const & description = "")
+    {
+        return AxisInfo("z", AxisType(Space | Frequency), resolution, description);
+    }
+    
+    static AxisInfo ft(double resolution = 0.0, std::string const & description = "")
+    {
+        return AxisInfo("t", AxisType(Time | Frequency), resolution, description);
+    }
+    
+    static AxisInfo c(std::string const & description = "")
+    {
+        return AxisInfo("c", Channels, 0.0, description);
+    }
+    
+    std::string key_, description_;
+    double resolution_;
+    AxisType flags_;
+};
+
+class AxisTags
+{
+  public:
+   
+    AxisTags()
+    {}
+    
+    AxisTags(int size)
+    : axes_(size)
+    {}
+    
+    AxisTags(AxisInfo const & i1)
+    {
+        push_back(i1);
+    }
+    
+    AxisTags(AxisInfo const & i1, AxisInfo const & i2)
+    {
+        push_back(i1);
+        push_back(i2);
+    }
+    
+    AxisTags(AxisInfo const & i1, AxisInfo const & i2, AxisInfo const & i3)
+    {
+        push_back(i1);
+        push_back(i2);
+        push_back(i3);
+    }
+    
+    AxisTags(AxisInfo const & i1, AxisInfo const & i2,
+             AxisInfo const & i3, AxisInfo const & i4)
+    {
+        push_back(i1);
+        push_back(i2);
+        push_back(i3);
+        push_back(i4);
+    }
+    
+    AxisTags(AxisInfo const & i1, AxisInfo const & i2,
+             AxisInfo const & i3, AxisInfo const & i4, AxisInfo const & i5)
+    {
+        push_back(i1);
+        push_back(i2);
+        push_back(i3);
+        push_back(i4);
+        push_back(i5);
+    }
+    
+    // static AxisTags fromJSON(std::string const & repr);
+
+    std::string toJSON() const
+    {
+        std::stringstream s;
+        s << "{\n  \"axes\": [";
+        for(unsigned int k=0; k<size(); ++k)
+        {
+            if(k > 0)
+                s << ",";
+            s << "\n";
+            s << "    {\n";
+            s << "      \"key\": \"" << axes_[k].key() << "\",\n";
+            s << "      \"typeFlags\": " << (unsigned int)axes_[k].typeFlags() << ",\n";
+            s << "      \"resolution\": " << std::setprecision(17) << axes_[k].resolution() << ",\n";
+            s << "      \"description\": \"" << axes_[k].description() << "\"\n";
+            s << "    }";
+        }
+        s << "\n  ]\n}";
+        return s.str();
+    }
+
+    unsigned int size() const
+    {
+        return axes_.size();
+    }
+    
+    int axisTypeCount(AxisInfo::AxisType type) const
+    {
+        int res = 0;
+        for(unsigned int k=0; k<size(); ++k)
+            if(axes_[k].isType(type))
+                ++res;
+        return res;
+    }
+    
+    std::string repr() const
+    {
+        std::string res;
+        if(size() > 0)
+            res += axes_[0].key();
+        for(unsigned int k=1; k<size(); ++k)
+        {
+            res += " ";
+            res += axes_[k].key();
+        }
+        return res;
+    }
+    
+    AxisInfo & get(int k)
+    {
+        checkIndex(k);
+        if(k < 0)
+            k += size();
+        return axes_[k];
+    }
+    
+    AxisInfo & get(std::string const & key)
+    {
+        return get(index(key));
+    }
+    
+    AxisInfo const & get(int k) const
+    {
+        checkIndex(k);
+        if(k < 0)
+            k += size();
+        return axes_[k];
+    }
+    
+    AxisInfo const & get(std::string const & key) const
+    {
+        return get(index(key));
+    }
+    
+    void set(int k, AxisInfo const & info)
+    {
+        checkIndex(k);
+        if(k < 0)
+            k += size();
+        checkDuplicates(k, info);
+        axes_[k] = info;
+    }
+
+    void set(std::string const & key, AxisInfo const & info)
+    {
+        set(index(key), info);
+    }
+
+    void insert(int k, AxisInfo const & i)
+    {
+        if(k == (int)size())
+        {
+            push_back(i);
+        }
+        else
+        {
+            checkIndex(k);
+            if(k < 0)
+                k += size();
+            checkDuplicates(size(), i);
+            axes_.insert(axes_.begin()+k, i);
+        }
+    }
+
+    void push_back(AxisInfo const & i)
+    {
+        checkDuplicates(size(), i);
+        axes_.push_back(i);
+    }
+    
+    void dropAxis(int k)
+    {
+        checkIndex(k);
+        ArrayVector<AxisInfo>::iterator i = k < 0
+                                                 ? axes_.end() + k
+                                                 : axes_.begin() + k;
+        axes_.erase(i, i+1);
+    }
+    
+    void dropAxis(std::string const & key)
+    {
+        dropAxis(index(key));
+    }
+    
+    void dropChannelAxis()
+    {
+        int k = channelIndex();
+        if(k < (int)size())
+            axes_.erase(axes_.begin() + k, axes_.begin() + k + 1);
+    }
+    
+    int index(std::string const & key) const
+    {
+        for(unsigned int k=0; k<size(); ++k)
+            if(axes_[k].key() == key)
+                return k;
+        return (int)size();
+    }
+    
+    double resolution(int k) const
+    {
+        return get(k).resolution_;
+    }
+    
+    double resolution(std::string const & key) const
+    {
+        return resolution(index(key));
+    }
+    
+    void setResolution(int k, double r) 
+    {
+        get(k).resolution_ = r;
+    }
+    
+    void setResolution(std::string const & key, double r) 
+    {
+        setResolution(index(key), r);
+    }
+    
+    void scaleResolution(int k, double factor)
+    {
+        get(k).resolution_ *= factor;
+    }
+    
+    void scaleResolution(std::string const & key, double factor)
+    {
+        get(key).resolution_ *= factor;
+    }
+    
+    std::string description(int k) const
+    {
+        return get(k).description_;
+    }
+    
+    std::string description(std::string const & key) const
+    {
+        return description(index(key));
+    }
+    
+    void setDescription(int k, std::string const & d) 
+    {
+        get(k).setDescription(d);
+    }
+    
+    void setDescription(std::string const & key, std::string const & d) 
+    {
+        setDescription(index(key), d);
+    }
+    
+    void setChannelDescription(std::string const & description)
+    {
+        int k = channelIndex();
+        if(k < (int)size())
+            axes_[k].setDescription(description);
+    }
+    
+    void toFrequencyDomain(int k, int size = 0, int sign = 1)
+    {
+        get(k) = get(k).toFrequencyDomain(size, sign);
+    }
+    
+    void toFrequencyDomain(std::string const & key, int size = 0, int sign = 1)
+    {
+        toFrequencyDomain(index(key), size, sign);
+    }
+    
+    void fromFrequencyDomain(int k, int size = 0)
+    {
+        toFrequencyDomain(k, size, -1);
+    }
+    
+    void fromFrequencyDomain(std::string const & key, int size = 0)
+    {
+        toFrequencyDomain(key, size, -1);
+    }
+    
+    bool hasChannelAxis() const
+    {
+        return channelIndex() != (int)size();
+    }
+    
+    // FIXME: cache the results of these functions?
+    int channelIndex() const
+    {
+        for(unsigned int k=0; k<size(); ++k)
+            if(axes_[k].isChannel())
+                return k;
+        return (int)size();
+    }
+    
+    int innerNonchannelIndex() const
+    {
+        int k = 0;
+        for(; k<(int)size(); ++k)
+            if(!axes_[k].isChannel())
+                break;
+        for(int i=k+1; i<(int)size(); ++i)
+        {
+            if(axes_[i].isChannel())
+                continue;
+            if(axes_[i] < axes_[k])
+                k = i;
+        }
+        return k;
+    }
+    
+    void swapaxes(int i1, int i2)
+    {
+        checkIndex(i1);
+        checkIndex(i2);
+        if(i1 < 0)
+            i1 += size();
+        if(i2 < 0)
+            i2 += size();
+        std::swap(axes_[i1], axes_[i2]);
+    }
+    
+    template <class T>
+    void transpose(ArrayVector<T> const & permutation)
+    {
+        if(permutation.size() == 0)
+        {
+            transpose();
+        }
+        else
+        {
+            vigra_precondition(permutation.size() == size(),
+                "AxisTags::transpose(): Permutation has wrong size.");
+            ArrayVector<AxisInfo> newAxes(size());
+            applyPermutation(permutation.begin(), permutation.end(), axes_.begin(), newAxes.begin());
+            axes_.swap(newAxes);
+        }
+    }
+    
+    void transpose()
+    {
+        std::reverse(axes_.begin(), axes_.end());
+    }
+    
+    template <class T>
+    void 
+    permutationToNormalOrder(ArrayVector<T> & permutation) const
+    {
+        permutation.resize(size());
+        indexSort(axes_.begin(), axes_.end(), permutation.begin());
+    }
+    
+    template <class T>
+    void 
+    permutationToNormalOrder(ArrayVector<T> & permutation, AxisInfo::AxisType types) const
+    {
+        ArrayVector<AxisInfo> matchingAxes;
+        for(int k=0; k<(int)size(); ++k)
+            if(axes_[k].isType(types))
+                matchingAxes.push_back(axes_[k]);
+        permutation.resize(matchingAxes.size());
+        indexSort(matchingAxes.begin(), matchingAxes.end(), permutation.begin());
+    }
+    
+    template <class T>
+    void 
+    permutationFromNormalOrder(ArrayVector<T> & inverse_permutation) const
+    {
+        ArrayVector<T> permutation;
+        permutationToNormalOrder(permutation);
+        inverse_permutation.resize(permutation.size());
+        indexSort(permutation.begin(), permutation.end(), inverse_permutation.begin());
+    }   
+    
+    template <class T>
+    void 
+    permutationFromNormalOrder(ArrayVector<T> & inverse_permutation, AxisInfo::AxisType types) const
+    {
+        ArrayVector<T> permutation;
+        permutationToNormalOrder(permutation, types);
+        inverse_permutation.resize(permutation.size());
+        indexSort(permutation.begin(), permutation.end(), inverse_permutation.begin());
+    }   
+    
+    template <class T>
+    void permutationToNumpyOrder(ArrayVector<T> & permutation) const
+    {
+        permutationToNormalOrder(permutation);
+        std::reverse(permutation.begin(), permutation.end());
+    }
+    
+    template <class T>
+    void permutationFromNumpyOrder(ArrayVector<T> & inverse_permutation) const
+    {
+        ArrayVector<T> permutation;
+        permutationToNumpyOrder(permutation);
+        inverse_permutation.resize(permutation.size());
+        indexSort(permutation.begin(), permutation.end(), inverse_permutation.begin());
+    }   
+    
+    template <class T>
+    void permutationToVigraOrder(ArrayVector<T> & permutation) const
+    {
+        permutation.resize(size());
+        indexSort(axes_.begin(), axes_.end(), permutation.begin());
+        int channel = channelIndex();
+        if(channel < (int)size())
+        {
+            for(int k=1; k<(int)size(); ++k)
+                permutation[k-1] = permutation[k];
+            permutation.back() = channel;
+        }
+    }
+    
+    template <class T>
+    void permutationFromVigraOrder(ArrayVector<T> & inverse_permutation) const
+    {
+        ArrayVector<T> permutation;
+        permutationToVigraOrder(permutation);
+        inverse_permutation.resize(permutation.size());
+        indexSort(permutation.begin(), permutation.end(), inverse_permutation.begin());
+    }   
+    
+    template <class T>
+    void permutationToOrder(ArrayVector<T> & permutation, std::string const & order) const
+    {
+        if(order == "A")
+        {
+            permutation.resize(size());
+            linearSequence(permutation.begin(), permutation.end());
+        }
+        else if(order == "C")
+        {
+            permutationToNumpyOrder(permutation);
+        }
+        else if(order == "F")
+        {
+            permutationToNormalOrder(permutation);
+        }
+        else if(order == "V")
+        {
+            permutationToVigraOrder(permutation);
+        }
+        else
+        {
+            vigra_precondition(false, 
+                "AxisTags::permutationToOrder(): unknown order '" + order + "'.");
+        }
+    }   
+    
+#if 0
+    ArrayVector<UInt32> matchOrdering(AxisTags const & other)
+    {
+        vigra_precondition(size() == other.size(),
+            "AxisTags::matchOrdering(): size mismatch.");
+        
+        ArrayVector<UInt32> permutation(size());
+        for(unsigned int k = 0; k<size(); ++k)
+        {
+            std::string key = other.get(k).key();
+            unsigned int l=0;
+            for(; l<size(); ++l)
+            {
+                if(key == get(l).key())
+                    break;
+            }
+            vigra_precondition(l < size(),
+                "AxisTags::matchOrdering(): key mismatch.");
+            permutation[k] = l;
+        }
+        return permutation;
+    }    
+#endif
+
+    bool compatible(AxisTags const & other) const
+    {
+        if(size() == 0 || other.size() == 0)
+            return true;
+        if(size() != other.size())
+            return false;
+        for(unsigned int k=0; k<size(); ++k)
+            if(!axes_[k].compatible(other.axes_[k]))
+                return false;
+        return true;
+    }
+
+    bool operator==(AxisTags const & other) const
+    {
+        if(size() != other.size())
+            return false;
+        return std::equal(axes_.begin(), axes_.end(), other.axes_.begin());
+    }
+
+    bool operator!=(AxisTags const & other) const
+    {
+        return !operator==(other);
+    }
+    
+  protected:
+    
+    void checkIndex(int k) const
+    {
+        vigra_precondition(k < (int)size() && k >= -(int)size(),
+            "AxisTags::checkIndex(): index out of range.");
+    }
+
+    void checkDuplicates(int i, AxisInfo const & info)
+    {
+        if(info.isChannel())
+        {  
+            for(int k=0; k<(int)size(); ++k)
+            {
+                vigra_precondition(k == i || !axes_[k].isChannel(),
+                     "AxisTags::checkDuplicates(): can only have one channel axis.");
+            }
+        }
+        else if(!info.isUnknown())
+        {
+            for(int k=0; k<(int)size(); ++k)
+            {
+                vigra_precondition(k == i || axes_[k].key() != info.key(),
+                     std::string("AxisTags::checkDuplicates(): axis key '" + 
+                                  info.key() + "' already exists."));
+            }
+        }
+    }
+
+    ArrayVector<AxisInfo> axes_;
+};
+
+// #if 0
+// struct PyGetFunctor
+// {
+    // AxisInfo const & operator()(python::object const & o) const
+    // {
+        // return python::extract<AxisInfo const &>(o)();
+    // }
+// };
+
+// class PyAxisTags
+// : public AxisTags<python::object, PyGetFunctor>
+// {
+    // typedef AxisTags<python::object, PyGetFunctor> BaseType;
+  // public:
+    // PyAxisTags()
+    // {}
+
+    // PyAxisTags(python::object i1, python::object i2,
+             // python::object i3, python::object i4, python::object i5)
+    // {
+        // if(PySequence_Check(i1.ptr()))
+        // {
+            // int size = len(i1);
+            // for(int k=0; k<size; ++k)
+                // if(python::extract<AxisInfo const &>(i1[k]).check())
+                    // push_back(i1[k]);
+        // }
+        // else if(PyInt_Check(i1.ptr()))
+        // {
+            // int size = python::extract<int>(i1)();
+            // for(int k=0; k<size; ++k)
+                // push_back(python::object(AxisInfo()));
+        // }
+        // else
+        // {
+            // if(python::extract<AxisInfo const &>(i1).check())
+                // push_back(i1);
+            // if(python::extract<AxisInfo const &>(i2).check())
+                // push_back(i2);
+            // if(python::extract<AxisInfo const &>(i3).check())
+                // push_back(i3);
+            // if(python::extract<AxisInfo const &>(i4).check())
+                // push_back(i4);
+            // if(python::extract<AxisInfo const &>(i5).check())
+                // push_back(i5);
+        // }
+    // }
+    
+    // python::object getitem(int k)
+    // {
+        // if(!checkIndex(k))
+        // {
+            // PyErr_SetString(PyExc_IndexError, "AxisInfo::getitem(): Invalid index or key.");
+            // python::throw_error_already_set();
+        // }
+        // if(k < 0)
+            // k += this->size();
+        // return this->axes_[k];
+    // }
+    
+    // python::object getitem(std::string const & key)
+    // {
+        // return getitem(this->findKey(key));
+    // }
+
+    // void setitem(int k, python::object i)
+    // {
+        // if(!this->checkIndex(k))
+        // {
+            // PyErr_SetString(PyExc_IndexError, "AxisInfo::setitem(): Invalid index or key.");
+            // python::throw_error_already_set();
+        // }
+        // if(!python::extract<AxisInfo const &>(i).check())
+        // {
+            // PyErr_SetString(PyExc_TypeError, "AxisInfo::setitem(): Item type must be AxisInfo.");
+            // python::throw_error_already_set();
+        // }
+        
+        // if(k < 0)
+            // k += this->size();
+        // this->axes_[k] = i;
+    // }
+    
+    // void setitem(std::string const & key, python::object i)
+    // {
+        // setitem(this->findKey(key), i);
+    // }
+
+    // void append(python::object i)
+    // {
+        // insert(size(), i);
+    // }
+
+    // void insert(int k, python::object i)
+    // {
+        // if(k < 0)
+            // k += this->size();
+        // if(k < 0)
+            // k = 0;
+        // if(k > (int)this->size())
+            // k = this->size();
+        // if(!python::extract<AxisInfo const &>(i).check())
+        // {
+            // PyErr_SetString(PyExc_TypeError, "AxisInfo::insert(): Item type must be AxisInfo.");
+            // python::throw_error_already_set();
+        // }
+        // this->axes_.insert(this->axes_.begin()+k, i);
+    // }
+    
+    // void insert(std::string const & key, python::object i)
+    // {
+        // insert(this->findKey(key), i);
+    // }
+
+    // python::list axesByFlag(AxisType typeFlags) const
+    // {
+        // python::list res;
+        // for(unsigned int k=0; k<this->size(); ++k)
+            // if(this->get(k).typeFlags() == typeFlags)
+                // res.append(k);
+        // return res;
+    // }
+
+    // python::list spatialAxes() const
+    // {
+        // python::list res;
+        // for(unsigned int k=0; k<this->size(); ++k)
+            // if(this->get(k).isSpatial())
+                // res.append(k);
+        // return res;
+    // }
+
+    // python::list temporalAxes() const
+    // {
+        // python::list res;
+        // for(unsigned int k=0; k<this->size(); ++k)
+            // if(this->get(k).isTemporal())
+                // res.append(k);
+        // return res;
+    // }
+
+    // python::list channelAxes() const
+    // {
+        // python::list res;
+        // for(unsigned int k=0; k<this->size(); ++k)
+            // if(this->get(k).isChannel())
+                // res.append(k);
+        // return res;
+    // }
+
+    // python::list frequencyAxes() const
+    // {
+        // python::list res;
+        // for(unsigned int k=0; k<this->size(); ++k)
+            // if(this->get(k).isFrequency())
+                // res.append(k);
+        // return res;
+    // }
+
+    // python::list angularAxes() const
+    // {
+        // python::list res;
+        // for(unsigned int k=0; k<this->size(); ++k)
+            // if(this->get(k).isAngular())
+                // res.append(k);
+        // return res;
+    // }
+
+    // python::list untaggedAxes() const
+    // {
+        // python::list res;
+        // for(unsigned int k=0; k<this->size(); ++k)
+            // if(this->get(k).isUnknown())
+                // res.append(k);
+        // return res;
+    // }
+
+    // template <class U>
+    // python::list vectorToPython(ArrayVector<U> const & v) const
+    // {
+        // python::list res;
+        // for(unsigned int k=0; k<v.size(); ++k)
+            // res.append(v[k]);
+        // return res;
+    // }
+
+    // python::list canonicalOrdering()
+    // {
+        // return vectorToPython(BaseType::canonicalOrdering());
+    // }
+
+    // python::list matchOrdering(PyAxisTags const & other)
+    // {
+        // return vectorToPython(BaseType::matchOrdering(other));
+    // }
+
+    // void transpose(python::object const & o)
+    // {
+        // unsigned int osize = len(o);
+        // ArrayVector<UInt32> permutation(osize);
+        
+        // for(unsigned int k=0; k<this->size(); ++k)
+            // permutation[k] = python::extract<UInt32>(o[k])();
+            
+        // BaseType::transpose(permutation);
+    // }
+
+    // void transpose()
+    // {
+        // BaseType::transpose();
+    // }
+// };
+
+// class TaggedShape
+// {
+  // public:
+
+    // ArrayVector<npy_intp> shape;
+    // python_ptr axistags;
+    // npy_intp channelCount;
+    // std::string channelDescription;
+    
+    // TaggedShape(MultiArrayIndex size)
+    // : shape(size)
+    // {}
+    
+    // template <int N>
+    // TaggedShape(typename MultiArrayShape<N>::type const & sh)
+    // : shape(sh.begin(), sh.end())
+    // {}
+    
+    // npy_intp & operator[](int i)
+    // {
+        // // rotate indices so that channels are located at index 0
+        // return shape[(i+1) % shape.size()];
+    // }
+    
+    // npy_intp operator[](int i) const
+    // {
+        // return shape[(i+1) % shape.size()];
+    // }
+    
+    // unsigned int size() const
+    // {
+        // return shape.size();
+    // }
+    
+    // // void setChannelDescription(std::string const & description)
+    // // {
+        // // if(axistags)
+        // // {
+            // // python_ptr func(PyString_FromString("setChannelDescription"), 
+                                         // // python_ptr::keep_count);
+            // // pythonToCppException(res);
+            
+            // // python_ptr d(PyString_FromString(d.c_str()), python_ptr::keep_count);
+            // // pythonToCppException(d);
+            
+            // // python_ptr res(PyObject_CallMethodObjArgs(axistags, func, d.get(), NULL),
+                           // // python_ptr::keep_count);
+            // // pythonToCppException(res);
+        // // }
+    // // }
+    
+    // // void setChannelCount(int channelCount)
+    // // {
+        // // shape[0] = channelCount;
+    // // }
+    
+    // void setChannelDescription(std::string const & description)
+    // {
+        // channelDescription = description;
+    // }
+    
+    // void setChannelCount(int count)
+    // {
+        // channelCount = count;
+    // }
+    
+    // void setChannelConfig(int channelCount, std::string const & description)
+    // {
+        // setChannelCount(channelCount);
+        // setChannelDescription(description);
+    // }
+// };
+// #endif
+
+} // namespace vigra
+
+#endif /* VIGRA_AXISTAGS_HXX */
diff --git a/include/vigra/basicgeometry.hxx b/include/vigra/basicgeometry.hxx
new file mode 100644
index 0000000..f203058
--- /dev/null
+++ b/include/vigra/basicgeometry.hxx
@@ -0,0 +1,973 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+#ifndef VIGRA_BASICGEOMETRY_HXX
+#define VIGRA_BASICGEOMETRY_HXX
+
+#include "error.hxx"
+#include "stdimage.hxx"
+#include "copyimage.hxx"
+#include "multi_shape.hxx"
+
+#include <cmath>
+
+namespace vigra {
+
+/** \addtogroup GeometricTransformations Geometric Transformations
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                      rotateImage                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Rotate an image by a multiple of 90 degrees or by an arbitrary angle.
+
+    If you specify the angle as an integer which is a multiple of 90 degrees, rotateImage()
+    just copies the pixels in the appropriate new order. It expects the destination image to 
+    have the correct shape for the desired rotation. That is, when the rotation is a multiple
+    of 180 degrees, source and destination must have the same shape, otherwise destination
+    must have the transposed shape of the source.
+    
+    If you want to rotate by an arbitrary angle and around an arbitrary center point,
+    you must specify the source image as a \ref vigra::SplineImageView, which is used for
+    interpolation at the required subpixel positions. If no center point is provided, the image 
+    center is used by default. The destination image must have the same size
+    as the source SplineImageView. 
+    
+    Positive angles refer to counter-clockwise rotation, negative ones to clockwise rotation.
+    All angles must be given in degrees.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // rotate by a multiple of 90 degrees
+        template <class T1, class S1,
+                  class T2, class S2>
+        void 
+        rotateImage(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest,
+                    int rotation);
+        
+        // rotate by an arbitrary angle around the given center point
+        template <int ORDER, class T, 
+                  class T2, class S2>
+        void 
+        rotateImage(SplineImageView<ORDER, T> const & src,
+                    MultiArrayView<2, T2, S2> dest, 
+                    double angleInDegree, 
+                    TinyVector<double, 2> const & center = (src.shape() - Shape2(1)) / 2.0);
+    }
+    \endcode
+    
+    \deprecatedAPI{rotateImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // rotate by a multiple of 90 degrees
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as,
+                    DestIterator id, DestAccessor ad, int rotation);
+
+        // rotate by an arbitrary angle around the given center point
+        template <int ORDER, class T, 
+                  class DestIterator, class DestAccessor>
+        void rotateImage(SplineImageView<ORDER, T> const & src,
+                         DestIterator id, DestAccessor dest, 
+                         double angleInDegree, TinyVector<double, 2> const & center = (src.shape() - Shape2(1)) / 2.0);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // rotate by a multiple of 90 degrees
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void 
+        rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                    pair<DestImageIterator, DestAccessor> dest, int rotation);
+                    
+        // rotate by an arbitrary angle around the given center point
+        template <int ORDER, class T, 
+                  class DestIterator, class DestAccessor>
+        void 
+        rotateImage(SplineImageView<ORDER, T> const & src,
+                    pair<DestImageIterator, DestAccessor> dest, 
+                    double angleInDegree, TinyVector<double, 2> const & center = (src.shape() - Shape2(1)) / 2.0);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/basicgeometry.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    // rotate counter-clockwise by 90 degrees (no interpolation required)
+    MultiArray<2, float> src(width, height),
+                         dest(height, width); // note that width and height are exchanged
+    ... // fill src
+    rotateImage(src, dest, 90);
+    
+    // rotate clockwise by 38.5 degrees, using a SplieImageView for cubic interpolation
+    SplineImageView<3, float> spline(srcImageRange(src));
+    MultiArray<2, float>  dest2(src.shape());
+    
+    vigra::rotateImage(spline, dest2, -38.5);
+    \endcode
+
+    \deprecatedUsage{rotateImage}
+    \code
+    // rotate counter-clockwise by 90 degrees (no interpolation required)
+    BImage src(width, height),
+           dest(height, width);    // note that width and height are exchanged
+    ... // fill src
+    
+    rotateImage(srcImageRange(src), destImage(dest), 90);
+    
+    // rotate clockwise by 38.5 degrees, using a SplieImageView for cubic interpolation
+    SplineImageView<3, float> spline(srcImageRange(src));
+    FImage dest2(width, height);
+    
+    rotateImage(spline, destImage(dest), -38.5);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+    
+    SrcAccessor src_accessor;
+    
+    dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
+    \endcode
+    \deprecatedEnd
+    
+    <b> Preconditions:</b>
+    \code
+    src.shape(0) > 1  &&  src.shape(1) > 1  
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void rotateImage)
+
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor>
+void rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as,
+                           DestIterator id, DestAccessor ad, int rotation)
+{
+    int x, y;
+    int ws = end.x - is.x;
+    int hs = end.y - is.y;
+
+    vigra_precondition(rotation % 90 == 0, 
+                "rotateImage(): "
+                "This function rotates images only about multiples of 90 degree");
+
+    rotation = rotation%360; 
+    if (rotation < 0)
+        rotation += 360;
+    
+    switch(rotation)
+    {
+        case 0:
+            copyImage(is, end, as, id, ad);
+            break;
+        case 90: 
+            is.x += (ws-1);
+            for(x=0; x != ws; x++, is.x--, id.y++)
+            {
+                typename SrcIterator::column_iterator cs = is.columnIterator();
+                typename DestIterator::row_iterator rd = id.rowIterator();
+                for(y=0; y != hs; y++, cs++, rd++)
+                {
+                    ad.set(as(cs), rd);
+                }
+        
+            }
+            break;
+
+        case 180:
+            end.x--;
+            end.y--;
+            for(x=0; x != ws; x++, end.x--, id.x++)
+            {
+                typename SrcIterator::column_iterator cs = end.columnIterator();
+                typename DestIterator::column_iterator cd = id.columnIterator();
+                for(y=0; y != hs; y++, cs--, cd++)
+                {
+                    ad.set(as(cs), cd);
+                }
+        
+            }
+            break;
+
+        case 270:  
+            is.y += (hs-1);
+            for(x=0; x != ws; x++, is.x++, id.y++)
+            {
+                typename SrcIterator::column_iterator cs = is.columnIterator();
+                typename DestIterator::row_iterator rd = id.rowIterator();
+                for(y=0; y != hs; y++, cs--, rd++)
+                {
+                    ad.set(as(cs), rd);
+                }
+        
+            }
+            break;
+        default: //not needful, because of the exception handig in if-statement 
+            vigra_fail("internal error"); 
+    }
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void 
+rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+              pair<DestImageIterator, DestAccessor> dest, int rotation)
+{
+    rotateImage(src.first, src.second, src.third, dest.first, dest.second, rotation);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void 
+rotateImage(MultiArrayView<2, T1, S1> const & src,
+            MultiArrayView<2, T2, S2> dest,
+            int rotation)
+{
+    if(rotation % 180 == 0)
+        vigra_precondition(src.shape() == dest.shape(),
+            "rotateImage(): shape mismatch between input and output.");
+    else
+        vigra_precondition(src.shape() == reverse(dest.shape()),
+            "rotateImage(): shape mismatch between input and output.");
+    rotateImage(srcImageRange(src), destImage(dest), rotation);
+}
+
+/********************************************************/
+/*                                                      */
+/*                     reflectImage                     */
+/*                                                      */
+/********************************************************/
+
+enum Reflect {horizontal = 1, vertical = 2};
+
+inline 
+Reflect operator|(Reflect l, Reflect r)
+{
+    return Reflect((unsigned int)l | (unsigned int)r);
+}
+
+/** \brief Reflect image horizontally or vertically.
+
+    The reflection direction refers to the reflection axis, i.e.
+    horizontal reflection turns the image upside down, vertical reflection
+    changes left for right. The directions are selected by the enum values
+    <tt>vigra::horizontal</tt> and <tt>vigra::vertical</tt>. The two directions 
+    can also be "or"ed together to perform both reflections simultaneously 
+    (see example below) -- this is the same as a 180 degree rotation. 
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void 
+        reflectImage(MultiArrayView<2, T1, S1> const & src,
+                     MultiArrayView<2, T2, S2> dest, Reflect reflect);
+    }
+    \endcode
+    
+    \deprecatedAPI{reflectImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
+                     DestIterator id, DestAccessor ad, Reflect axis);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void 
+        reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                     pair<DestImageIterator, DestAccessor> dest, Reflect axis);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/basicgeometry.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    MultiArray<2, float> src(width, height),
+                         dest(width, height);
+    ... // fill src
+    // reflect about both dimensions
+    vigra::reflectImage(src, dest, vigra::horizontal | vigra::vertical);
+    
+    \endcode
+
+    \deprecatedUsage{reflectImage}
+    \code
+    BImage src(width, height),
+           dest(width, height);
+    ... // fill src
+    
+    vigra::reflectImage(srcImageRange(src), destImage(dest), vigra::horizontal | vigra::vertical);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+    
+    SrcAccessor src_accessor;
+    
+    dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
+    \endcode
+    \deprecatedEnd
+    
+    <b> Preconditions:</b>
+    \code
+    src.shape(0) > 1  &&  src.shape(1) > 1  
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void reflectImage)
+
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor>
+void reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
+                  DestIterator id, DestAccessor ad, Reflect reflect)
+{
+    
+    int ws = end.x - is.x;
+    int hs = end.y - is.y;
+
+    int x, y;
+
+    if(reflect == horizontal)
+    {//flipImage
+        is.y += (hs-1);
+        for(x=0; x<ws; ++x, ++is.x, ++id.x) 
+        {
+            typename SrcIterator::column_iterator  cs = is.columnIterator();
+            typename DestIterator::column_iterator cd = id.columnIterator();
+            for(y=0; y!=hs;y++, cs--, cd++)
+            {
+                ad.set(as(cs), cd);
+            }
+        }
+    }
+    else if(reflect == vertical)
+    {//flopImage
+        is.x += (ws-1);
+        for(x=0; x < ws; ++x, --is.x, ++id.x) 
+        {
+
+            typename SrcIterator::column_iterator cs = is.columnIterator();
+            typename DestIterator::column_iterator cd = id.columnIterator();
+            for(y=0; y!=hs;y++, cs++, cd++)
+            {
+                ad.set(as(cs), cd);
+            }
+        }
+    }
+    else if(reflect == (horizontal | vertical))
+    {//flipFlopImage   //???
+        end.x--;
+        end.y--;
+        for(x=0; x != ws; x++, end.x--, id.x++)
+        {
+            typename SrcIterator::column_iterator cs = end.columnIterator();
+            typename DestIterator::column_iterator cd = id.columnIterator();
+            for(y=0; y != hs; y++, cs--, cd++)
+            {
+                ad.set(as(cs), cd);
+            }
+        }
+    }
+    else 
+        vigra_fail("reflectImage(): "
+                   "This function reflects horizontal or vertical,"
+                   "   'and' is included");
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void 
+reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+              pair<DestImageIterator, DestAccessor> dest, Reflect reflect)
+{
+    reflectImage(src.first, src.second, src.third, dest.first, dest.second, reflect);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void 
+reflectImage(MultiArrayView<2, T1, S1> const & src,
+             MultiArrayView<2, T2, S2> dest, Reflect reflect)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "reflectImage(): shape mismatch between input and output.");
+    reflectImage(srcImageRange(src), destImage(dest), reflect);
+}
+
+/********************************************************/
+/*                                                      */
+/*                    transposeImage                   */
+/*                                                      */
+/********************************************************/
+
+// names clash with sys/types.h on Mac OS / Darwin, see docs below
+enum Transpose{major = 1, minor = 2};
+
+/** \brief Transpose an image over the major or minor diagonal.
+
+    The transposition direction refers to the axis, i.e.
+    major transposition turns the upper right corner into the lower left one, 
+    whereas minor transposition changes the upper left corner into the lower right one. 
+    The directions are selected by the enum values
+    <tt>vigra::major</tt> and <tt>vigra::minor</tt>. The two directions 
+    can also be "or"ed together to perform both reflections simultaneously 
+    (see example below) -- this is the same as a 180 degree rotation.
+    (Caution: When doing multi-platform development, you should be
+    aware that some <sys/types.h> define major/minor, too.  Do not omit
+    the vigra namespace prefix.)
+    
+    Note that a similar effect can be chieved by MultiArrayView::transpose(). However,
+    the latter can only transpose about the major diagonal, and it doesn't rearrange the data
+    -  it just creates a view with transposed axis ordering. It depends on the context
+    which function is more appropriate.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void 
+        transposeImage(MultiArrayView<2, T1, S1> const & src,
+                       MultiArrayView<2, T2, S2> dest, Transpose axis);
+    }
+    \endcode
+    
+    \deprecatedAPI{transposeImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
+                       DestIterator id, DestAccessor ad, Transpose axis);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void 
+        transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                       pair<DestImageIterator, DestAccessor> dest, Transpose axis);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/basicgeometry.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    MultiArray<2, float> src(width, height),
+                         dest(height, width);   // note that dimensions are transposed
+    ... // fill src
+    
+    // transpose about the major diagonal
+    vigra::transposeImage(src, dest, vigra::major);
+    
+    // this produces the same data as transposing the view
+    assert(dest == src.transpose());
+    
+    // transposition about the minor diagonal has no correspondence in MultiArrayView
+    vigra::transposeImage(src, dest, vigra::minor);
+    \endcode
+
+    \deprecatedUsage{transposeImage}
+    \code
+    BImage src(width, height),
+           dest(width, height);
+    ... // fill src
+   
+    // transpose about both diagonals simultaneously
+    vigra::transposeImage(srcImageRange(src), destImage(dest), vigra::major | vigra::minor);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+    
+    SrcAccessor src_accessor;
+    
+    dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
+    \endcode
+    \deprecatedEnd
+    
+    <b> Preconditions:</b>
+    \code
+    src.shape(0) > 1  &&  src.shape(1) > 1  
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void transposeImage)
+
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor>
+void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
+                    DestIterator id, DestAccessor ad, Transpose transpose)
+{
+    int ws = end.x - is.x;
+    int hs = end.y - is.y;
+
+    int x, y;
+
+    if(transpose == major)
+    {//Die Funktion spiegelt das Bild um (0,0) (1,1) Diagonale
+        for(x=0; x != ws; x++, is.x++, id.y++)
+        {
+
+            typename SrcIterator::column_iterator cs = is.columnIterator();
+            typename DestIterator::row_iterator rd = id.rowIterator();
+            for(y=0; y != hs; y++, cs++, rd++)
+            {
+                ad.set(as(cs), rd);
+            }
+        }
+    }
+    else if(transpose == minor)
+    {//Die Funktion spiegelt das Bild (1,0) (0,1) Diagonale
+        end.x--;
+        end.y--;
+        for(x=0; x != ws; x++, --end.x, ++id.y)
+        {
+
+            typename SrcIterator::column_iterator cs = end.columnIterator();
+            typename DestIterator::row_iterator rd = id.rowIterator();
+            for(y=0; y != hs; y++, --cs, ++rd)
+            {
+                ad.set(as(cs), rd);
+            }
+        }
+    }
+    else if(transpose == (major | minor))
+    {//flipFlopImage  //???
+        end.x--;
+        end.y--;
+        for(x=0; x != ws; x++, end.x--, id.x++)
+        {
+            typename SrcIterator::column_iterator cs = end.columnIterator();
+            typename DestIterator::column_iterator cd = id.columnIterator();
+            for(y=0; y != hs; y++, cs--, cd++)
+            {
+                ad.set(as(cs), cd);
+            }
+        }
+    
+    }
+    else 
+        vigra_fail("transposeImage(): "
+                   "This function transposes major or minor,"
+                   "   'and' is included");
+
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void 
+transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+               pair<DestImageIterator, DestAccessor> dest, Transpose transpose)
+{
+    transposeImage(src.first, src.second, src.third, dest.first, dest.second, transpose);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void 
+transposeImage(MultiArrayView<2, T1, S1> const & src,
+               MultiArrayView<2, T2, S2> dest, Transpose transpose)
+{
+    vigra_precondition(src.shape() == reverse(dest.shape()),
+        "transposeImage(): shape mismatch between input and output.");
+    transposeImage(srcImageRange(src), destImage(dest), transpose);
+}
+
+/********************************************************/
+/*                                                      */
+/*                        resampleLine                  */
+/*                                                      */
+/********************************************************/
+
+/*
+* Vergroessert eine Linie um einen Faktor. 
+* Ist z.B. der Faktor = 4 so werden in der
+* neuen Linie(Destination) jedes Pixel genau 4 mal 
+* vorkommen, also es findet auch keine Glaetung 
+* statt (NoInterpolation). Als Parameter sollen
+* der Anfangs-, der Enditerator und der Accessor
+* der Ausgangslinie (Source line), der Anfangsiterator
+* und Accessor der Ziellinie (destination line) und
+* anschliessend der Faktor um den die Linie (Zeile)
+* vergroessert bzw. verkleinert werden soll. 
+*/
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor>
+void resampleLine(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
+                  DestIterator dest_iter, DestAccessor dest_acc, double factor)
+{
+    // The width of the src line.      
+    int src_width = src_iter_end - src_iter;
+ 
+    vigra_precondition(src_width > 0,
+                       "resampleLine(): input image too small.");
+    vigra_precondition(factor > 0.0,
+                       "resampleLine(): factor must be positive.");
+    
+    if (factor >= 1.0)
+    {
+        int int_factor = (int)factor;
+        double dx = factor - int_factor;
+        double saver = dx;
+        for ( ; src_iter != src_iter_end ; ++src_iter, saver += dx)
+        {
+            if (saver >= 1.0)
+            {
+                saver = saver - (int)saver;
+                dest_acc.set(src_acc(src_iter), dest_iter);
+                ++dest_iter;
+            }
+            for(int i = 0 ; i < int_factor ; i++, ++dest_iter)
+            {
+                dest_acc.set(src_acc(src_iter), dest_iter);
+            }
+        }
+    }
+    else
+    {
+        DestIterator dest_end = dest_iter + (int)VIGRA_CSTD::ceil(src_width*factor);  
+        factor = 1.0/factor;
+        int int_factor = (int)factor;
+        double dx = factor - int_factor;
+        double saver = dx;
+        src_iter_end -= 1;
+        for ( ; src_iter != src_iter_end && dest_iter != dest_end ; 
+              ++dest_iter, src_iter += int_factor, saver += dx)
+        {
+            if (saver >= 1.0)
+            {
+                saver = saver - (int)saver;
+                ++src_iter;
+            }
+            dest_acc.set(src_acc(src_iter), dest_iter);
+        }
+        if (dest_iter != dest_end)
+        {
+            dest_acc.set(src_acc(src_iter_end), dest_iter);
+        }
+    }
+}
+
+inline int sizeForResamplingFactor(int oldsize, double factor)
+{
+    return (factor < 1.0)
+        ? (int)VIGRA_CSTD::ceil(oldsize * factor) 
+        : (int)(oldsize * factor);
+}
+
+
+/********************************************************/
+/*                                                      */
+/*                     resampleImage                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Resample image by a given factor.
+
+    This algorithm is very fast and does not require any arithmetic on the pixel types.    
+    The input image must have a size of at
+    least 2x2. Destiniation pixels are directly copied from the appropriate
+    source pixels. The size of the result image is the product of <tt>factor</tt>
+    and the original size, where we round up if <tt>factor < 1.0</tt> and down otherwise.
+    This size calculation is the main difference to the convention used in the similar 
+    function \ref resizeImageNoInterpolation():
+    there, the result size is calculated as <tt>n*(old_width-1)+1</tt> and 
+    <tt>n*(old_height-1)+1</tt>. This is because \ref resizeImageNoInterpolation() 
+    does not replicate the last pixel of every row/column in order to make it compatible
+    with the other functions of the <tt>resizeImage...</tt> family.
+    
+    The function can be called with different resampling factors for x and y, or
+    with a single factor to be used for both directions.
+
+    It should also be noted that resampleImage() is implemented so that an enlargement followed
+    by the corresponding shrinking reproduces the original image. 
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void 
+        resampleImage(MultiArrayView<2, T1, S1> const & src,
+                      MultiArrayView<2, T2, S2> dest, double factor);
+
+        template <class T1, class S1,
+                  class T2, class S2>
+        void 
+        resampleImage(MultiArrayView<2, T1, S1> const & src,
+                      MultiArrayView<2, T2, S2> dest, double xfactor, double yfactor);
+    }
+    \endcode
+    
+    \deprecatedAPI{resampleImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                      DestIterator id, DestAccessor ad, double factor);
+                      
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                      DestIterator id, DestAccessor ad, double xfactor, double yfactor);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void 
+        resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                      pair<DestImageIterator, DestAccessor> dest, double factor);
+                      
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void 
+        resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                      pair<DestImageIterator, DestAccessor> dest, double xfactor, double yfactor);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/basicgeometry.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    double factor = 2.0;
+    MultiArray<2, float> src(width, height),
+                         dest((int)(factor*width), (int)(factor*height));   // enlarge image by factor
+    ... // fill src
+    
+    resampleImage(src, dest, factor);
+    \endcode
+    
+    \deprecatedUsage{resampleImage}
+    \code
+    // use old API
+    vigra::resampleImage(srcImageRange(src), destImage(dest), factor);    
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+    
+    SrcAccessor src_accessor;
+    
+    dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
+    \endcode
+    \deprecatedEnd
+    
+    <b> Preconditions:</b>
+    \code
+    src.shape(0) > 1  &&  src.shape(1) > 1  
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void resampleImage)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void 
+resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+              DestIterator id, DestAccessor ad, double xfactor, double yfactor)
+{
+    int width_old = iend.x - is.x;
+    int height_old = iend.y - is.y;
+    
+    //Bei Verkleinerung muss das dest-Bild ceiling(src*factor), da z.B.
+    //aus 6x6 grossem Bild wird eins 18x18 grosses gemacht bei Vergroesserungsfaktor 3.1
+    //umgekehrt damit wir vom 18x18 zu 6x6 (und nicht 5x5) bei Vergroesserung von 1/3.1
+    //muss das kleinste Integer das groesser als 18/3.1 ist genommen werden.
+    int height_new = sizeForResamplingFactor(height_old, yfactor);
+    int width_new = sizeForResamplingFactor(width_old, xfactor);
+    
+    vigra_precondition((width_old > 1) && (height_old > 1),
+                 "resampleImage(): "
+                 "Source image too small.\n");
+    vigra_precondition((width_new > 1) && (height_new > 1),
+                 "resampleImage(): "
+                 "Destination image too small.\n");
+        
+    typedef typename SrcAccessor::value_type SRCVT;
+    typedef BasicImage<SRCVT> TmpImage;
+    typedef typename TmpImage::traverser TmpImageIterator;
+
+    BasicImage<SRCVT> tmp(width_old, height_new);
+    
+    int x,y;
+    
+    typename BasicImage<SRCVT>::Iterator yt = tmp.upperLeft();
+
+    for(x=0; x<width_old; ++x, ++is.x, ++yt.x) 
+    {
+        typename SrcIterator::column_iterator c1 = is.columnIterator();
+        typename TmpImageIterator::column_iterator ct = yt.columnIterator();
+        resampleLine(c1, c1 + height_old, sa, ct, tmp.accessor(), yfactor);
+    }
+
+    yt = tmp.upperLeft();
+
+    for(y=0; y < height_new; ++y, ++yt.y, ++id.y) 
+    {
+        typename DestIterator::row_iterator rd = id.rowIterator();
+        typename TmpImageIterator::row_iterator rt = yt.rowIterator();
+        resampleLine(rt, rt + width_old, tmp.accessor(), rd, ad, xfactor);
+    }
+
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void 
+resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+              DestIterator id, DestAccessor ad, double factor)
+{
+  resampleImage(is, iend, sa, id, ad, factor, factor);
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void 
+resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+              pair<DestImageIterator, DestAccessor> dest, double factor)
+{
+  resampleImage(src.first, src.second, src.third, dest.first, dest.second, factor);
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void 
+resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+              pair<DestImageIterator, DestAccessor> dest, double xfactor, double yfactor)
+{
+  resampleImage(src.first, src.second, src.third, dest.first, dest.second, xfactor, yfactor);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void 
+resampleImage(MultiArrayView<2, T1, S1> const & src,
+              MultiArrayView<2, T2, S2> dest, double factor)
+{
+    if(factor > 1.0)
+        vigra_precondition(floor(factor*src.shape()) == dest.shape(),
+            "resampleImage(): shape mismatch between input and output.");
+    else
+        vigra_precondition(ceil(factor*src.shape()) == dest.shape(),
+            "resampleImage(): shape mismatch between input and output.");
+            
+    resampleImage(srcImageRange(src), destImage(dest), factor);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void 
+resampleImage(MultiArrayView<2, T1, S1> const & src,
+              MultiArrayView<2, T2, S2> dest, double xfactor, double yfactor)
+{
+    if(xfactor > 1.0)
+        vigra_precondition(floor(xfactor*src.shape(0)) == dest.shape(0),
+            "resampleImage(): shape mismatch between input and output.");
+    else
+        vigra_precondition(ceil(xfactor*src.shape(0)) == dest.shape(0),
+            "resampleImage(): shape mismatch between input and output.");
+    if(yfactor > 1.0)
+        vigra_precondition(floor(yfactor*src.shape(1)) == dest.shape(1),
+            "resampleImage(): shape mismatch between input and output.");
+    else
+        vigra_precondition(ceil(yfactor*src.shape(1)) == dest.shape(1),
+            "resampleImage(): shape mismatch between input and output.");
+            
+    resampleImage(srcImageRange(src), destImage(dest), xfactor, yfactor);
+}
+
+//@}
+
+} // namespace vigra
+
+
+#endif /* VIGRA_BASICGEOMETRY_HXX */
diff --git a/include/vigra/basicimage.hxx b/include/vigra/basicimage.hxx
new file mode 100644
index 0000000..a646fc0
--- /dev/null
+++ b/include/vigra/basicimage.hxx
@@ -0,0 +1,1512 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_BASICIMAGE_HXX
+#define VIGRA_BASICIMAGE_HXX
+
+#include <memory>
+#include <algorithm>
+#include "utilities.hxx"
+#include "iteratortraits.hxx"
+#include "accessor.hxx"
+#include "memory.hxx"
+#include "basicimageview.hxx"
+
+// Bounds checking Macro used if VIGRA_CHECK_BOUNDS is defined.
+#ifdef VIGRA_CHECK_BOUNDS
+#define VIGRA_ASSERT_INSIDE(diff) \
+  vigra_precondition(this->isInside(diff), "Index out of bounds")
+#else
+#define VIGRA_ASSERT_INSIDE(diff)
+#endif
+
+namespace vigra {
+
+template <class IMAGEITERATOR>
+class LineBasedColumnIteratorPolicy
+{
+  public:
+    typedef IMAGEITERATOR                             ImageIterator;
+    typedef typename IMAGEITERATOR::LineStartIterator LineStartIterator;
+    typedef typename IMAGEITERATOR::value_type        value_type;
+    typedef typename IMAGEITERATOR::difference_type::MoveY
+                                                      difference_type;
+    typedef typename IMAGEITERATOR::reference         reference;
+    typedef typename IMAGEITERATOR::index_reference   index_reference;
+    typedef typename IMAGEITERATOR::pointer           pointer;
+    typedef std::random_access_iterator_tag           iterator_category;
+
+
+    struct BaseType
+    {
+        explicit BaseType(LineStartIterator c = LineStartIterator(),
+                          difference_type o = 0)
+        : line_start_(c), offset_(o)
+        {}
+
+        LineStartIterator line_start_;
+        difference_type offset_;
+    };
+
+    static void initialize(BaseType &) {}
+
+    static reference dereference(BaseType const & d)
+        { return const_cast<reference>(*(*d.line_start_ + d.offset_)); }
+
+    static index_reference dereference(BaseType const & d, difference_type n)
+    {
+        return const_cast<index_reference>(*(d.line_start_[n] + d.offset_));
+    }
+
+    static bool equal(BaseType const & d1, BaseType const & d2)
+        { return d1.line_start_ == d2.line_start_; }
+
+    static bool less(BaseType const & d1, BaseType const & d2)
+        { return d1.line_start_ < d2.line_start_; }
+
+    static difference_type difference(BaseType const & d1, BaseType const & d2)
+        { return d1.line_start_ - d2.line_start_; }
+
+    static void increment(BaseType & d)
+        { ++d.line_start_; }
+
+    static void decrement(BaseType & d)
+        { --d.line_start_; }
+
+    static void advance(BaseType & d, difference_type n)
+        { d.line_start_ += n; }
+};
+
+/********************************************************/
+/*                                                      */
+/*                    BasicImageIterator                */
+/*                                                      */
+/********************************************************/
+
+/** Implementation of the standard image iterator for \ref vigra::BasicImage.
+    See \ref vigra::ImageIterator for documentation.
+
+    <b>\#include</b> \<vigra/basicimage.hxx\> <br/>
+    Namespace: vigra
+*/
+template <class IMAGEITERATOR, class PIXELTYPE,
+          class REFERENCE, class POINTER, class LINESTARTITERATOR>
+class BasicImageIteratorBase
+{
+  public:
+    typedef BasicImageIteratorBase<IMAGEITERATOR,
+            PIXELTYPE, REFERENCE, POINTER, LINESTARTITERATOR> self_type;
+
+    typedef LINESTARTITERATOR    LineStartIterator;
+    typedef PIXELTYPE            value_type;
+    typedef PIXELTYPE            PixelType;
+    typedef REFERENCE            reference;
+    typedef REFERENCE            index_reference;
+    typedef POINTER              pointer;
+    typedef Diff2D               difference_type;
+    typedef image_traverser_tag  iterator_category;
+    typedef POINTER              row_iterator;
+    typedef IteratorAdaptor<LineBasedColumnIteratorPolicy<IMAGEITERATOR> >
+                                 column_iterator;
+
+    typedef int                  MoveX;
+    typedef LINESTARTITERATOR    MoveY;
+
+    MoveX x;
+    MoveY y;
+
+    IMAGEITERATOR & operator+=(difference_type const & s)
+    {
+        x += s.x;
+        y += s.y;
+        return static_cast<IMAGEITERATOR &>(*this);
+    }
+
+    IMAGEITERATOR & operator-=(difference_type const & s)
+    {
+        x -= s.x;
+        y -= s.y;
+        return static_cast<IMAGEITERATOR &>(*this);
+    }
+
+    IMAGEITERATOR operator+(difference_type const & s) const
+    {
+        IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
+
+        ret += s;
+
+        return ret;
+    }
+
+    IMAGEITERATOR operator-(difference_type const & s) const
+    {
+        IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
+
+        ret -= s;
+
+        return ret;
+    }
+
+    difference_type operator-(BasicImageIteratorBase const & rhs) const
+    {
+        return difference_type(difference_type::MoveX(x - rhs.x),
+                               difference_type::MoveY(y - rhs.y));
+    }
+
+    bool operator==(BasicImageIteratorBase const & rhs) const
+    {
+        return (x == rhs.x) && (y == rhs.y);
+    }
+
+    bool operator!=(BasicImageIteratorBase const & rhs) const
+    {
+        return (x != rhs.x) || (y != rhs.y);
+    }
+
+    reference operator*() const
+    {
+        return *(*y + x );
+    }
+
+    pointer operator->() const
+    {
+        return *y + x;
+    }
+
+    index_reference operator[](difference_type const & d) const
+    {
+        return *(*(y + d.y) + x + d.x);
+    }
+
+    index_reference operator()(int dx, int dy) const
+    {
+        return *(*(y + dy) + x + dx);
+    }
+
+    pointer operator[](int dy) const
+    {
+        return y[dy] + x;
+    }
+
+    row_iterator rowIterator() const
+        { return *y + x; }
+
+    column_iterator columnIterator() const
+    {
+        typedef typename column_iterator::BaseType Iter;
+        return column_iterator(Iter(y, x));
+    }
+
+  protected:
+    BasicImageIteratorBase(LINESTARTITERATOR const & line)
+    : x(0),
+      y(line)
+    {}
+
+    BasicImageIteratorBase(int ix, LINESTARTITERATOR const & line)
+    : x(ix),
+      y(line)
+    {}
+
+    BasicImageIteratorBase()
+    : x(0),
+      y(0)
+    {}
+};
+
+/********************************************************/
+/*                                                      */
+/*                    BasicImageIterator                */
+/*                                                      */
+/********************************************************/
+
+/** Implementation of the standard image iterator for \ref vigra::BasicImage.
+    See \ref vigra::ImageIterator for documentation.
+
+    <b>\#include</b> \<vigra/basicimage.hxx\> <br/>
+    Namespace: vigra
+*/
+template <class PIXELTYPE, class ITERATOR>
+class BasicImageIterator
+: public BasicImageIteratorBase<BasicImageIterator<PIXELTYPE, ITERATOR>,
+                            PIXELTYPE, PIXELTYPE &, PIXELTYPE *, ITERATOR>
+{
+  public:
+
+    typedef BasicImageIteratorBase<BasicImageIterator, PIXELTYPE,
+                                PIXELTYPE &, PIXELTYPE *, ITERATOR> Base;
+
+
+    BasicImageIterator(ITERATOR line)
+    : Base(line)
+    {}
+
+    BasicImageIterator()
+    : Base()
+    {}
+};
+
+/********************************************************/
+/*                                                      */
+/*                ConstBasicImageIterator               */
+/*                                                      */
+/********************************************************/
+
+/** Implementation of the standard const image iterator for \ref vigra::BasicImage.
+    See \ref vigra::ConstImageIterator for documentation.
+
+    <b>\#include</b> \<vigra/basicimage.hxx\> <br/>
+    Namespace: vigra
+*/
+template <class PIXELTYPE, class ITERATOR>
+class ConstBasicImageIterator
+: public BasicImageIteratorBase<ConstBasicImageIterator<PIXELTYPE, ITERATOR>,
+                    PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR>
+{
+  public:
+
+    typedef BasicImageIteratorBase<ConstBasicImageIterator,
+              PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR> Base;
+
+
+    ConstBasicImageIterator(ITERATOR line)
+    : Base(line)
+    {}
+
+    ConstBasicImageIterator(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs)
+    : Base(rhs.x, rhs.y)
+    {}
+
+    ConstBasicImageIterator()
+    : Base()
+    {}
+
+    ConstBasicImageIterator &
+    operator=(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs)
+    {
+        Base::x = rhs.x;
+        Base::y = rhs.y;
+        return *this;
+    }
+
+};
+
+/********************************************************/
+/*                                                      */
+/*             definition of iterator traits            */
+/*                                                      */
+/********************************************************/
+
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class T>
+struct IteratorTraits<BasicImageIterator<T, T**> >
+: public IteratorTraitsBase<BasicImageIterator<T, T**> >
+{
+    typedef BasicImageIterator<T, T**>                    mutable_iterator;
+    typedef ConstBasicImageIterator<T, T**>               const_iterator;
+    typedef typename AccessorTraits<T>::default_accessor  DefaultAccessor;
+    typedef DefaultAccessor                               default_accessor;
+    typedef VigraTrueType                                 hasConstantStrides;
+};
+
+template <class T>
+struct IteratorTraits<ConstBasicImageIterator<T, T**> >
+: public IteratorTraitsBase<ConstBasicImageIterator<T, T**> >
+{
+    typedef BasicImageIterator<T, T**>                    mutable_iterator;
+    typedef ConstBasicImageIterator<T, T**>               const_iterator;
+    typedef typename AccessorTraits<T>::default_const_accessor  DefaultAccessor;
+    typedef DefaultAccessor                               default_accessor;
+    typedef VigraTrueType                                 hasConstantStrides;
+};
+
+#else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+#define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \
+    template <>  \
+    struct IteratorTraits<BasicImageIterator<VALUETYPE, VALUETYPE **> > \
+    : public IteratorTraitsBase<BasicImageIterator<VALUETYPE, VALUETYPE **> > \
+    { \
+        typedef BasicImageIterator<VALUETYPE, VALUETYPE**>             mutable_iterator; \
+        typedef ConstBasicImageIterator<VALUETYPE, VALUETYPE**>        const_iterator; \
+        typedef typename AccessorTraits<VALUETYPE >::default_accessor  DefaultAccessor; \
+        typedef DefaultAccessor                               default_accessor; \
+        typedef VigraTrueType                                 hasConstantStrides; \
+    }; \
+    \
+    template <>  \
+    struct IteratorTraits<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \
+    : public IteratorTraitsBase<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \
+    { \
+        typedef BasicImageIterator<VALUETYPE, VALUETYPE**>             mutable_iterator; \
+        typedef ConstBasicImageIterator<VALUETYPE, VALUETYPE**>        const_iterator; \
+        typedef typename AccessorTraits<VALUETYPE >::default_const_accessor  DefaultAccessor; \
+        typedef DefaultAccessor                               default_accessor; \
+        typedef VigraTrueType                                 hasConstantStrides; \
+    };
+
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>)
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>)
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned short>)
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>)
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned int>)
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>)
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>)
+
+#define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<short, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<short, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<short, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned short, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned short, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned short, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<int, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<int, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<int, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned int, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned int, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned int, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<float, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<float, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<float, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<double, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<double, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<double, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+
+#undef VIGRA_DEFINE_ITERATORTRAITS
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+/********************************************************/
+/*                                                      */
+/*                     BasicImage                       */
+/*                                                      */
+/********************************************************/
+
+/** \brief Fundamental class template for images.
+
+    A customized memory allocator can be specified as a templated argument
+    and passed in the constructor.
+
+    <b>\#include</b> \<vigra/basicimage.hxx\> <br/>
+    Namespace: vigra
+*/
+template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> >
+class BasicImage
+{
+  public:
+
+        /** the BasicImage's pixel type
+        */
+    typedef PIXELTYPE value_type;
+
+        /** the BasicImage's pixel type
+        */
+    typedef PIXELTYPE PixelType;
+
+        /** the BasicImage's reference type (i.e. the
+            return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>)
+        */
+    typedef PIXELTYPE &       reference;
+
+        /** the BasicImage's const reference type (i.e. the
+            return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>
+            when <TT>image</TT> is const)
+        */
+    typedef PIXELTYPE const & const_reference;
+
+        /** the BasicImage's pointer type
+        */
+    typedef PIXELTYPE *       pointer;
+
+        /** the BasicImage's const pointer type
+        */
+    typedef PIXELTYPE const * const_pointer;
+
+        /** the BasicImage's 1D random access iterator
+            (note: lower case 'iterator' is a STL compatible 1D random
+             access iterator, don't confuse with capitalized Iterator)
+        */
+    typedef PIXELTYPE * iterator;
+
+        /** deprecated, use <TT>iterator</TT> instead
+        */
+    typedef PIXELTYPE * ScanOrderIterator;
+
+        /** the BasicImage's 1D random access const iterator
+            (note: lower case 'const_iterator' is a STL compatible 1D
+            random access const iterator)
+        */
+    typedef PIXELTYPE const * const_iterator;
+
+        /** deprecated, use <TT>const_iterator</TT> instead
+        */
+    typedef PIXELTYPE const * ConstScanOrderIterator;
+
+        /** the BasicImage's 2D random access iterator ('traverser')
+        */
+    typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> traverser;
+
+        /** deprecated, use <TT>traverser</TT> instead
+        */
+    typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> Iterator;
+
+        /** the BasicImage's 2D random access const iterator ('const traverser')
+        */
+    typedef
+        ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
+        const_traverser;
+
+        /** deprecated, use <TT>const_traverser</TT> instead
+        */
+    typedef
+        ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
+        ConstIterator;
+
+        /** the row iterator associated with the traverser
+        */
+    typedef typename traverser::row_iterator row_iterator;
+
+        /** the const row iterator associated with the const_traverser
+        */
+    typedef typename const_traverser::row_iterator const_row_iterator;
+
+        /** the column iterator associated with the traverser
+        */
+    typedef typename traverser::column_iterator column_iterator;
+
+        /** the const column iterator associated with the const_traverser
+        */
+    typedef typename const_traverser::column_iterator const_column_iterator;
+
+        /** the BasicImage's difference type (argument type of image[diff])
+        */
+    typedef Diff2D difference_type;
+
+         /** the BasicImage's size type (result type of image.size())
+        */
+    typedef Size2D size_type;
+
+       /** the BasicImage's default accessor
+        */
+    typedef typename
+          IteratorTraits<traverser>::DefaultAccessor Accessor;
+
+        /** the BasicImage's default const accessor
+        */
+    typedef typename
+          IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor;
+
+        /** the BasicImage's allocator (default: std::allocator<value_type>)
+        */
+    typedef Alloc allocator_type;
+
+    typedef Alloc Allocator;
+    typedef typename Alloc::template rebind<PIXELTYPE *>::other LineAllocator;
+
+        /** construct image of size 0x0
+        */
+    BasicImage()
+    : data_(0),
+      width_(0),
+      height_(0)
+    {}
+
+        /** construct image of size 0x0, use the specified allocator.
+        */
+    explicit BasicImage(Alloc const & alloc)
+    : data_(0),
+      width_(0),
+      height_(0),
+      allocator_(alloc),
+      pallocator_(alloc)
+    {}
+
+        /** construct image of size width x height, use the specified allocator.
+        */
+    BasicImage(int width, int height, Alloc const & alloc = Alloc())
+    : data_(0),
+      width_(0),
+      height_(0),
+      allocator_(alloc),
+      pallocator_(alloc)
+    {
+        vigra_precondition((width >= 0) && (height >= 0),
+             "BasicImage::BasicImage(int width, int height): "
+             "width and height must be >= 0.\n");
+
+        resize(width, height, value_type());
+    }
+
+        /** construct image of size size.x x size.y, use the specified allocator.
+        */
+    explicit BasicImage(difference_type const & size, Alloc const & alloc = Alloc())
+    : data_(0),
+      width_(0),
+      height_(0),
+      allocator_(alloc),
+      pallocator_(alloc)
+    {
+        vigra_precondition((size.x >= 0) && (size.y >= 0),
+             "BasicImage::BasicImage(Diff2D size): "
+             "size.x and size.y must be >= 0.\n");
+
+        resize(size.x, size.y, value_type());
+    }
+
+        /** construct image of size width*height and initialize every
+        pixel with the value \a d (use this constructor, if
+        value_type doesn't have a default constructor).
+        Use the specified allocator.
+        */
+    BasicImage(int width, int height, value_type const & d, Alloc const & alloc = Alloc())
+    : data_(0),
+      width_(0),
+      height_(0),
+      allocator_(alloc),
+      pallocator_(alloc)
+    {
+        vigra_precondition((width >= 0) && (height >= 0),
+             "BasicImage::BasicImage(int width, int height, value_type const & ): "
+             "width and height must be >= 0.\n");
+
+        resize(width, height, d);
+    }
+
+        /** construct image of size width*height and try to skip initialization
+            of the memory (see BasicImage::resize for details).
+            Use the specified allocator.
+        */
+    BasicImage(int width, int height, SkipInitializationTag, Alloc const & alloc = Alloc())
+    : data_(0),
+      width_(0),
+      height_(0),
+      allocator_(alloc),
+      pallocator_(alloc)
+    {
+        vigra_precondition((width >= 0) && (height >= 0),
+             "BasicImage::BasicImage(int width, int height, value_type const & ): "
+             "width and height must be >= 0.\n");
+
+        resize(width, height, SkipInitialization);
+    }
+
+        /** construct image of size size.x x size.y and initialize
+        every pixel with given data (use this constructor, if
+        value_type doesn't have a default constructor). Use the specified allocator.
+        */
+    explicit BasicImage(difference_type const & size, value_type const & d, Alloc const & alloc = Alloc())
+    : data_(0),
+      width_(0),
+      height_(0),
+      allocator_(alloc),
+      pallocator_(alloc)
+    {
+        vigra_precondition((size.x >= 0) && (size.y >= 0),
+             "BasicImage::BasicImage(Diff2D const & size, value_type const & v): "
+             "size.x and size.y must be >= 0.\n");
+
+        resize(size.x, size.y, d);
+    }
+
+        /** construct image of size size.x x size.y and try to skip initialization
+            of the memory (see BasicImage::resize for details). Use the specified allocator.
+        */
+    explicit BasicImage(difference_type const & size, SkipInitializationTag, Alloc const & alloc = Alloc())
+    : data_(0),
+      width_(0),
+      height_(0),
+      allocator_(alloc),
+      pallocator_(alloc)
+    {
+        vigra_precondition((size.x >= 0) && (size.y >= 0),
+             "BasicImage::BasicImage(Diff2D const & size, value_type const & v): "
+             "size.x and size.y must be >= 0.\n");
+
+        resize(size.x, size.y, SkipInitialization);
+    }
+
+
+        /** construct image of size width*height and copy the data from the
+            given C-style array \a d. Use the specified allocator.
+        */
+    BasicImage(int width, int height, const_pointer d, Alloc const & alloc = Alloc())
+    : data_(0),
+      width_(0),
+      height_(0),
+      allocator_(alloc),
+      pallocator_(alloc)
+    {
+        vigra_precondition((width >= 0) && (height >= 0),
+             "BasicImage::BasicImage(int width, int height, const_pointer ): "
+             "width and height must be >= 0.\n");
+
+        resizeCopy(width, height, d);
+    }
+
+        /** construct image of size size.x x size.y  and copy the data from the
+            given C-style array. Use the specified allocator.
+        */
+    explicit BasicImage(difference_type const & size, const_pointer d, Alloc const & alloc = Alloc())
+    : data_(0),
+      width_(0),
+      height_(0),
+      allocator_(alloc),
+      pallocator_(alloc)
+    {
+        vigra_precondition((size.x >= 0) && (size.y >= 0),
+             "BasicImage::BasicImage(Diff2D const & size, const_pointer): "
+             "size.x and size.y must be >= 0.\n");
+
+        resizeCopy(size.x, size.y, d);
+    }
+
+        /** copy rhs image
+        */
+    BasicImage(const BasicImage & rhs)
+    : data_(0),
+      width_(0),
+      height_(0),
+      allocator_(rhs.allocator_),
+      pallocator_(rhs.pallocator_)
+    {
+        resizeCopy(rhs);
+    }
+
+        /** destructor
+        */
+    ~BasicImage()
+    {
+        deallocate();
+    }
+
+        /** copy rhs image (image is resized if necessary)
+        */
+    BasicImage & operator=(const BasicImage & rhs);
+
+        /** \deprecated set Image with const value
+        */
+    BasicImage & operator=(value_type pixel);
+
+        /** set Image with const value
+        */
+    BasicImage & init(value_type const & pixel);
+
+        /** reset image to specified size (dimensions must not be negative)
+            (old data are kept if new size matches old size)
+        */
+    void resize(int width, int height)
+    {
+        if(width != width_ || height != height_)
+            resize(width, height, value_type());
+    }
+
+        /** reset image to specified size (dimensions must not be negative)
+            (old data are kept if new size matches old size)
+        */
+    void resize(difference_type const & size)
+    {
+        if(size.x != width_ || size.y != height_)
+        {
+            resize(size.x, size.y, value_type());
+        }
+    }
+
+        /** reset image to specified size and initialize it with
+            given data (use this if value_type doesn't have a default
+            constructor, dimensions must not be negative,
+            old data are kept if new size matches old size)
+        */
+    void resize(int width, int height, value_type const & d)
+    {
+        resizeImpl(width, height, d, false);
+    }
+
+        /** reset image to specified size and skip initialization
+            if possible (use this if <tt>value_type</tt> is a built-in type 
+            or <tt>TinyVector<builtin&gt&</tt> and the data is 
+            immediately overridden afterwards). If <tt>value_type</tt> requires
+            initialization, <tt>SkipInitialization</tt> is ignored.
+            
+            Usage:
+            \code
+            image.resize(new_width, new_height, SkipInitialization);
+            \endcode
+        */
+    void resize(int width, int height, SkipInitializationTag)
+    {
+        resizeImpl(width, height, NumericTraits<value_type>::zero(), 
+                   CanSkipInitialization<value_type>::value);
+    }
+
+        /** resize image to given size and initialize by copying data
+            from the C-style array \a data.
+        */
+    void resizeCopy(int width, int height, const_pointer data);
+
+        /** resize image to size of other image and copy its data
+        */
+    void resizeCopy(const BasicImage & rhs)
+    {
+        resizeCopy(rhs.width(), rhs.height(), rhs.data_);
+    }
+
+        /** swap the internal data with the rhs image in constant time
+        */
+    void swap( BasicImage & rhs );
+
+        /** width of Image
+        */
+    int width() const
+    {
+        return width_;
+    }
+
+        /** height of Image
+        */
+    int height() const
+    {
+        return height_;
+    }
+
+        /** size of Image
+        */
+    size_type size() const
+    {
+        return size_type(width(), height());
+    }
+
+        /** test whether a given coordinate is inside the image
+        */
+    bool isInside(difference_type const & d) const
+    {
+        return d.x >= 0 && d.y >= 0 &&
+               d.x < width() && d.y < height();
+    }
+
+        /** access pixel at given location. <br>
+        usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
+        */
+    reference operator[](difference_type const & d)
+    {
+        VIGRA_ASSERT_INSIDE(d);
+        return lines_[d.y][d.x];
+    }
+
+        /** read pixel at given location. <br>
+        usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
+        */
+    const_reference operator[](difference_type const & d) const
+    {
+         VIGRA_ASSERT_INSIDE(d);
+        return lines_[d.y][d.x];
+    }
+
+        /** access pixel at given location. <br>
+        usage: <TT> value_type value = image(1,2) </TT>
+        */
+    reference operator()(int dx, int dy)
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(dx,dy));
+        return lines_[dy][dx];
+    }
+
+        /** read pixel at given location. <br>
+        usage: <TT> value_type value = image(1,2) </TT>
+        */
+    const_reference operator()(int dx, int dy) const
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(dx,dy));
+        return lines_[dy][dx];
+    }
+
+        /** access pixel at given location.
+            Note that the 'x' index is the trailing index. <br>
+        usage: <TT> value_type value = image[2][1] </TT>
+        */
+    pointer operator[](int dy)
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(0,dy));
+        return lines_[dy];
+    }
+
+        /** read pixel at given location.
+            Note that the 'x' index is the trailing index. <br>
+        usage: <TT> value_type value = image[2][1] </TT>
+        */
+    const_pointer operator[](int dy) const
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(0,dy));
+        return lines_[dy];
+    }
+
+        /** init 2D random access iterator pointing to upper left pixel
+        */
+    traverser upperLeft()
+    {
+        vigra_precondition(data_ != 0,
+          "BasicImage::upperLeft(): image must have non-zero size.");
+        return traverser(lines_);
+    }
+
+        /** init 2D random access iterator pointing to
+         pixel(width, height), i.e. one pixel right and below lower right
+         corner of the image as is common in C/C++.
+        */
+    traverser lowerRight()
+    {
+        vigra_precondition(data_ != 0,
+          "BasicImage::lowerRight(): image must have non-zero size.");
+        return upperLeft() + size();
+    }
+
+        /** init 2D random access const iterator pointing to upper left pixel
+        */
+    const_traverser upperLeft() const
+    {
+        vigra_precondition(data_ != 0,
+          "BasicImage::upperLeft(): image must have non-zero size.");
+        return const_traverser(const_cast<PIXELTYPE **>(lines_));
+    }
+
+        /** init 2D random access const iterator pointing to
+         pixel(width, height), i.e. one pixel right and below lower right
+         corner of the image as is common in C/C++.
+        */
+    const_traverser lowerRight() const
+    {
+        vigra_precondition(data_ != 0,
+          "BasicImage::lowerRight(): image must have non-zero size.");
+        return upperLeft() + size();
+    }
+
+        /** init 1D random access iterator pointing to first pixel
+        */
+    iterator begin()
+    {
+        vigra_precondition(data_ != 0,
+          "BasicImage::begin(): image must have non-zero size.");
+        return data_;
+    }
+
+        /** init 1D random access iterator pointing past the end
+        */
+    iterator end()
+    {
+        vigra_precondition(data_ != 0,
+          "BasicImage::end(): image must have non-zero size.");
+        return data_ + width() * height();
+    }
+
+        /** init 1D random access const iterator pointing to first pixel
+        */
+    const_iterator begin() const
+    {
+        vigra_precondition(data_ != 0,
+          "BasicImage::begin(): image must have non-zero size.");
+        return data_;
+    }
+
+        /** init 1D random access const iterator pointing past the end
+        */
+    const_iterator end() const
+    {
+        vigra_precondition(data_ != 0,
+          "BasicImage::end(): image must have non-zero size.");
+        return data_ + width() * height();
+    }
+
+        /** init 1D random access iterator pointing to first pixel of row \a y
+        */
+    row_iterator rowBegin(int y)
+    {
+        return lines_[y];
+    }
+
+        /** init 1D random access iterator pointing past the end of row \a y
+        */
+    row_iterator rowEnd(int y)
+    {
+        return rowBegin(y) + width();
+    }
+
+        /** init 1D random access const iterator pointing to first pixel of row \a y
+        */
+    const_row_iterator rowBegin(int y) const
+    {
+        return lines_[y];
+    }
+
+        /** init 1D random access const iterator pointing past the end of row \a y
+        */
+    const_row_iterator rowEnd(int y) const
+    {
+        return rowBegin(y) + width();
+    }
+
+        /** init 1D random access iterator pointing to first pixel of column \a x
+        */
+    column_iterator columnBegin(int x)
+    {
+        typedef typename column_iterator::BaseType Iter;
+        return column_iterator(Iter(lines_, x));
+    }
+
+        /** init 1D random access iterator pointing past the end of column \a x
+        */
+    column_iterator columnEnd(int x)
+    {
+        return columnBegin(x) + height();
+    }
+
+        /** init 1D random access const iterator pointing to first pixel of column \a x
+        */
+    const_column_iterator columnBegin(int x) const
+    {
+        typedef typename const_column_iterator::BaseType Iter;
+        return const_column_iterator(Iter(lines_, x));
+    }
+
+        /** init 1D random access const iterator pointing past the end of column \a x
+        */
+    const_column_iterator columnEnd(int x) const
+    {
+        return columnBegin(x) + height();
+    }
+
+        /** get a pointer to the internal data
+        */
+    const_pointer data() const
+    {
+        return data_;
+    }
+
+        /** return default accessor
+        */
+    Accessor accessor()
+    {
+        return Accessor();
+    }
+
+        /** return default const accessor
+        */
+    ConstAccessor accessor() const
+    {
+        return ConstAccessor();
+    }
+
+  private:
+
+    void deallocate();
+    void resizeImpl(int width, int height, value_type const & d, bool skipInit);
+
+
+    value_type ** initLineStartArray(value_type * data, int width, int height);
+
+    PIXELTYPE * data_;
+    PIXELTYPE ** lines_;
+    int width_, height_;
+    Alloc allocator_;
+    LineAllocator pallocator_;
+};
+
+template <class PIXELTYPE, class Alloc>
+BasicImage<PIXELTYPE, Alloc> &
+BasicImage<PIXELTYPE, Alloc>::operator=(const BasicImage & rhs)
+{
+    if(this != &rhs)
+    {
+        if((width() != rhs.width()) ||
+           (height() != rhs.height()))
+        {
+            resizeCopy(rhs);
+        }
+        else
+        {
+            ConstScanOrderIterator is = rhs.begin();
+            ConstScanOrderIterator iend = rhs.end();
+            ScanOrderIterator id = begin();
+
+            for(; is != iend; ++is, ++id) *id = *is;
+        }
+    }
+    return *this;
+}
+
+template <class PIXELTYPE, class Alloc>
+BasicImage<PIXELTYPE, Alloc> &
+BasicImage<PIXELTYPE, Alloc>::operator=(value_type pixel)
+{
+    ScanOrderIterator i = begin();
+    ScanOrderIterator iend = end();
+
+    for(; i != iend; ++i) *i = pixel;
+
+    return *this;
+}
+
+template <class PIXELTYPE, class Alloc>
+BasicImage<PIXELTYPE, Alloc> &
+BasicImage<PIXELTYPE, Alloc>::init(value_type const & pixel)
+{
+    ScanOrderIterator i = begin();
+    ScanOrderIterator iend = end();
+
+    for(; i != iend; ++i) *i = pixel;
+
+    return *this;
+}
+
+template <class PIXELTYPE, class Alloc>
+void
+BasicImage<PIXELTYPE, Alloc>::resizeImpl(int width, int height, value_type const & d, bool skipInit)
+{
+    vigra_precondition((width >= 0) && (height >= 0),
+         "BasicImage::resize(int width, int height, value_type const &): "
+         "width and height must be >= 0.\n");
+    vigra_precondition(width * height >= 0,
+         "BasicImage::resize(int width, int height, value_type const &): "
+         "width * height too large (integer overflow -> negative).\n");
+
+    if (width_ != width || height_ != height)  // change size?
+    {
+        value_type * newdata = 0;
+        value_type ** newlines = 0;
+        if(width*height > 0)
+        {
+            if (width*height != width_*height_) // different sizes, must reallocate
+            {
+                newdata = allocator_.allocate(typename Alloc::size_type(width*height));
+                if(!skipInit)
+                    std::uninitialized_fill_n(newdata, width*height, d);
+                newlines = initLineStartArray(newdata, width, height);
+                deallocate();
+            }
+            else // need only to reshape
+            {
+                newdata = data_;
+                if(!skipInit)
+                    std::fill_n(newdata, width*height, d);
+                newlines = initLineStartArray(newdata, width, height);
+                pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
+            }
+        }
+        else
+        {
+            deallocate();
+        }
+
+        data_ = newdata;
+        lines_ = newlines;
+        width_ = width;
+        height_ = height;
+    }
+    else if(width*height > 0 && !skipInit) // keep size, re-init data
+    {
+        std::fill_n(data_, width*height, d);
+    }
+}
+
+
+template <class PIXELTYPE, class Alloc>
+void
+BasicImage<PIXELTYPE, Alloc>::resizeCopy(int width, int height, const_pointer data)
+{
+    int newsize = width*height;
+    if (width_ != width || height_ != height)  // change size?
+    {
+        value_type * newdata = 0;
+        value_type ** newlines = 0;
+        if(newsize > 0)
+        {
+            if (newsize != width_*height_) // different sizes, must reallocate
+            {
+                newdata = allocator_.allocate(typename Alloc::size_type(newsize));
+                std::uninitialized_copy(data, data + newsize, newdata);
+                newlines = initLineStartArray(newdata, width, height);
+                deallocate();
+            }
+            else // need only to reshape
+            {
+                newdata = data_;
+                std::copy(data, data + newsize, newdata);
+                newlines = initLineStartArray(newdata, width, height);
+                pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
+            }
+        }
+        else
+        {
+            deallocate();
+        }
+
+        data_ = newdata;
+        lines_ = newlines;
+        width_ = width;
+        height_ = height;
+    }
+    else if(newsize > 0) // keep size, copy data
+    {
+        std::copy(data, data + newsize, data_);
+    }
+}
+
+template <class PIXELTYPE, class Alloc>
+void
+BasicImage<PIXELTYPE, Alloc>::swap( BasicImage & rhs )
+{
+  if (&rhs!=this)
+  {
+    std::swap( data_, rhs.data_ );
+    std::swap( lines_, rhs.lines_ );
+    std::swap( width_, rhs.width_ );
+    std::swap( height_, rhs.height_ );
+  }
+}
+
+template <class PIXELTYPE, class Alloc>
+void
+BasicImage<PIXELTYPE, Alloc>::deallocate()
+{
+    if(data_)
+    {
+        ScanOrderIterator i = begin();
+        ScanOrderIterator iend = end();
+
+        for(; i != iend; ++i)   (*i).~PIXELTYPE();
+
+        allocator_.deallocate(data_, typename Alloc::size_type(width()*height()));
+        pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
+    }
+}
+
+template <class PIXELTYPE, class Alloc>
+PIXELTYPE **
+BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, int width, int height)
+{
+    value_type ** lines = pallocator_.allocate(typename Alloc::size_type(height));
+    for(int y=0; y<height; ++y)
+         lines[y] = data + y*width;
+    return lines;
+}
+
+/********************************************************/
+/*                                                      */
+/*              argument object factories               */
+/*                                                      */
+/********************************************************/
+
+template <class PixelType, class Accessor, class Alloc>
+inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
+              typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
+srcImageRange(BasicImage<PixelType, Alloc> const & img, Accessor a)
+{
+    return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
+                  typename BasicImage<PixelType, Alloc>::const_traverser,
+          Accessor>(img.upperLeft(),
+                    img.lowerRight(),
+                    a);
+}
+
+template <class PixelType, class Accessor, class Alloc>
+inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
+              typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
+srcImageRange(BasicImage<PixelType, Alloc> const & img, Rect2D const & roi, Accessor a)
+{
+    vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
+                       roi.right() <= img.width() && roi.bottom() <= img.height(),
+                       "srcImageRange(): ROI rectangle outside image.");
+    return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
+                  typename BasicImage<PixelType, Alloc>::const_traverser,
+          Accessor>(img.upperLeft() + roi.upperLeft(),
+                    img.upperLeft() + roi.lowerRight(),
+                    a);
+}
+
+template <class PixelType, class Accessor, class Alloc>
+inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
+srcImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
+{
+    return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
+                Accessor>(img.upperLeft(), a);
+}
+
+template <class PixelType, class Accessor, class Alloc>
+inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
+srcImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul, Accessor a)
+{
+    vigra_precondition(img.isInside(ul),
+                       "srcImage(): ROI rectangle outside image.");
+    return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
+                Accessor>(img.upperLeft() + ul, a);
+}
+
+template <class PixelType, class Accessor, class Alloc>
+inline triple<typename BasicImage<PixelType, Alloc>::traverser,
+              typename BasicImage<PixelType, Alloc>::traverser, Accessor>
+destImageRange(BasicImage<PixelType, Alloc> & img, Accessor a)
+{
+    return triple<typename BasicImage<PixelType, Alloc>::traverser,
+                  typename BasicImage<PixelType, Alloc>::traverser,
+          Accessor>(img.upperLeft(),
+                    img.lowerRight(),
+                    a);
+}
+
+template <class PixelType, class Accessor, class Alloc>
+inline triple<typename BasicImage<PixelType, Alloc>::traverser,
+              typename BasicImage<PixelType, Alloc>::traverser, Accessor>
+destImageRange(BasicImage<PixelType, Alloc> & img, Rect2D const & roi, Accessor a)
+{
+    vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
+                       roi.right() <= img.width() && roi.bottom() <= img.height(),
+                       "destImageRange(): ROI rectangle outside image.");
+    return triple<typename BasicImage<PixelType, Alloc>::traverser,
+                  typename BasicImage<PixelType, Alloc>::traverser,
+          Accessor>(img.upperLeft() + roi.upperLeft(),
+                    img.upperLeft() + roi.lowerRight(),
+                    a);
+}
+
+template <class PixelType, class Accessor, class Alloc>
+inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor>
+destImage(BasicImage<PixelType, Alloc> & img, Accessor a)
+{
+    return pair<typename BasicImage<PixelType, Alloc>::traverser,
+                Accessor>(img.upperLeft(), a);
+}
+
+template <class PixelType, class Accessor, class Alloc>
+inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor>
+destImage(BasicImage<PixelType, Alloc> & img, Point2D const & ul, Accessor a)
+{
+    vigra_precondition(img.isInside(ul),
+                       "destImage(): ROI rectangle outside image.");
+    return pair<typename BasicImage<PixelType, Alloc>::traverser,
+                Accessor>(img.upperLeft() + ul, a);
+}
+
+template <class PixelType, class Accessor, class Alloc>
+inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
+maskImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
+{
+    return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
+                Accessor>(img.upperLeft(), a);
+}
+
+template <class PixelType, class Accessor, class Alloc>
+inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
+maskImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul, Accessor a)
+{
+    vigra_precondition(img.isInside(ul),
+                       "maskImage(): ROI rectangle outside image.");
+    return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
+                Accessor>(img.upperLeft() + ul, a);
+}
+
+/****************************************************************/
+
+template <class PixelType, class Alloc>
+inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
+              typename BasicImage<PixelType, Alloc>::const_traverser,
+              typename BasicImage<PixelType, Alloc>::ConstAccessor>
+srcImageRange(BasicImage<PixelType, Alloc> const & img)
+{
+    return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
+                  typename BasicImage<PixelType, Alloc>::const_traverser,
+                  typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
+                                                                        img.lowerRight(),
+                                                                        img.accessor());
+}
+
+template <class PixelType, class Alloc>
+inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
+              typename BasicImage<PixelType, Alloc>::const_traverser,
+              typename BasicImage<PixelType, Alloc>::ConstAccessor>
+srcImageRange(BasicImage<PixelType, Alloc> const & img, Rect2D const & roi)
+{
+    vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
+                       roi.right() <= img.width() && roi.bottom() <= img.height(),
+                       "srcImageRange(): ROI rectangle outside image.");
+    return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
+                  typename BasicImage<PixelType, Alloc>::const_traverser,
+                  typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + roi.upperLeft(),
+                                                                        img.upperLeft() + roi.lowerRight(),
+                                                                        img.accessor());
+}
+
+template <class PixelType, class Alloc>
+inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
+             typename BasicImage<PixelType, Alloc>::ConstAccessor>
+srcImage(BasicImage<PixelType, Alloc> const & img)
+{
+    return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
+                typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
+                                                                      img.accessor());
+}
+
+template <class PixelType, class Alloc>
+inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
+             typename BasicImage<PixelType, Alloc>::ConstAccessor>
+srcImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul)
+{
+    vigra_precondition(img.isInside(ul),
+                       "srcImage(): ROI rectangle outside image.");
+    return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
+                typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + ul,
+                                                                      img.accessor());
+}
+
+template <class PixelType, class Alloc>
+inline triple< typename BasicImage<PixelType, Alloc>::traverser,
+               typename BasicImage<PixelType, Alloc>::traverser,
+               typename BasicImage<PixelType, Alloc>::Accessor>
+destImageRange(BasicImage<PixelType, Alloc> & img)
+{
+    return triple<typename BasicImage<PixelType, Alloc>::traverser,
+                  typename BasicImage<PixelType, Alloc>::traverser,
+                  typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
+                                                                   img.lowerRight(),
+                                                                   img.accessor());
+}
+
+template <class PixelType, class Alloc>
+inline triple< typename BasicImage<PixelType, Alloc>::traverser,
+               typename BasicImage<PixelType, Alloc>::traverser,
+               typename BasicImage<PixelType, Alloc>::Accessor>
+destImageRange(BasicImage<PixelType, Alloc> & img, Rect2D const & roi)
+{
+    vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
+                       roi.right() <= img.width() && roi.bottom() <= img.height(),
+                       "destImageRange(): ROI rectangle outside image.");
+    return triple<typename BasicImage<PixelType, Alloc>::traverser,
+                  typename BasicImage<PixelType, Alloc>::traverser,
+                  typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft() + roi.upperLeft(),
+                                                                   img.upperLeft() + roi.lowerRight(),
+                                                                   img.accessor());
+}
+
+template <class PixelType, class Alloc>
+inline pair< typename BasicImage<PixelType, Alloc>::traverser,
+             typename BasicImage<PixelType, Alloc>::Accessor>
+destImage(BasicImage<PixelType, Alloc> & img)
+{
+    return pair<typename BasicImage<PixelType, Alloc>::traverser,
+                typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
+                                                          img.accessor());
+}
+
+template <class PixelType, class Alloc>
+inline pair< typename BasicImage<PixelType, Alloc>::traverser,
+             typename BasicImage<PixelType, Alloc>::Accessor>
+destImage(BasicImage<PixelType, Alloc> & img, Point2D const & ul)
+{
+    vigra_precondition(img.isInside(ul),
+                       "destImage(): ROI rectangle outside image.");
+    return pair<typename BasicImage<PixelType, Alloc>::traverser,
+                typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft() + ul,
+                                                                 img.accessor());
+}
+
+template <class PixelType, class Alloc>
+inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
+             typename BasicImage<PixelType, Alloc>::ConstAccessor>
+maskImage(BasicImage<PixelType, Alloc> const & img)
+{
+    return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
+                typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
+                                                                      img.accessor());
+}
+
+template <class PixelType, class Alloc>
+inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
+             typename BasicImage<PixelType, Alloc>::ConstAccessor>
+maskImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul)
+{
+    vigra_precondition(img.isInside(ul),
+                       "maskImage(): ROI rectangle outside image.");
+    return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
+                typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + ul,
+                                                                      img.accessor());
+}
+
+} // namespace vigra
+#undef VIGRA_ASSERT_INSIDE
+#endif // VIGRA_BASICIMAGE_HXX
diff --git a/include/vigra/basicimageview.hxx b/include/vigra/basicimageview.hxx
new file mode 100644
index 0000000..bc9f04b
--- /dev/null
+++ b/include/vigra/basicimageview.hxx
@@ -0,0 +1,707 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_BASICIMAGEVIEW_HXX
+#define VIGRA_BASICIMAGEVIEW_HXX
+
+#include "imageiterator.hxx"
+#include "initimage.hxx"
+
+// Bounds checking Macro used if VIGRA_CHECK_BOUNDS is defined.
+#ifdef VIGRA_CHECK_BOUNDS
+#define VIGRA_ASSERT_INSIDE(diff) \
+  vigra_precondition(this->isInside(diff), "Index out of bounds")
+#else
+#define VIGRA_ASSERT_INSIDE(diff)
+#endif
+
+
+namespace vigra {
+
+
+/********************************************************/
+/*                                                      */
+/*                     BasicImageView                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief BasicImage using foreign memory.
+
+    This class provides the same interface as \ref vigra::BasicImage
+    (with the exception of <tt>resize()</tt>) but the image's
+    memory is provided from the outside instead of allocated internally.
+
+    A <tt>BasicImageView</tt> can also be created from a
+    \ref vigra::MultiArrayView with the appropriate shape -- see
+    \ref MultiArrayToImage.
+
+    <b>\#include</b> \<vigra/basicimageview.hxx\> <br/>
+    Namespace: vigra
+*/
+template <class PIXELTYPE>
+class BasicImageView
+{
+  public:
+
+        /** the BasicImageView's pixel type
+        */
+    typedef PIXELTYPE value_type;
+
+        /** the BasicImageView's pixel type
+        */
+    typedef PIXELTYPE PixelType;
+
+        /** the BasicImageView's reference type (i.e. the
+            return type of image[diff] and image(dx,dy))
+        */
+    typedef PIXELTYPE &       reference;
+
+        /** the BasicImageView's const reference type (i.e. the
+            return type of image[diff] and image(dx,dy) when image is const)
+        */
+    typedef PIXELTYPE const & const_reference;
+
+        /** the BasicImageView's pointer type
+        */
+    typedef PIXELTYPE *       pointer;
+
+        /** the BasicImageView's const pointer type
+        */
+    typedef PIXELTYPE const * const_pointer;
+
+        /** the BasicImageView's 1D random access iterator
+            (note: lower case 'iterator' is a STL compatible 1D random
+             access iterator, don't confuse with capitalized Iterator)
+        */
+    typedef PIXELTYPE * iterator;
+
+        /** deprecated, use <TT>iterator</TT> instead
+        */
+    typedef PIXELTYPE * ScanOrderIterator;
+
+        /** the BasicImageView's 1D random access const iterator
+            (note: lower case 'const_iterator' is a STL compatible 1D
+            random access const iterator)
+        */
+    typedef PIXELTYPE const * const_iterator;
+
+        /** deprecated, use <TT>const_iterator</TT> instead
+        */
+    typedef PIXELTYPE const * ConstScanOrderIterator;
+
+        /** the BasicImageView's 2D random access iterator ('traverser')
+        */
+    typedef ImageIterator<value_type> traverser;
+
+        /** deprecated, use <TT>traverser</TT> instead
+        */
+    typedef ImageIterator<value_type> Iterator;
+
+        /** the BasicImageView's 2D random access const iterator ('const traverser')
+        */
+    typedef ConstImageIterator<value_type> const_traverser;
+
+        /** deprecated, use <TT>const_traverser</TT> instead
+        */
+    typedef ConstImageIterator<value_type> ConstIterator;
+
+        /** the row iterator associated with the traverser
+        */
+    typedef typename traverser::row_iterator row_iterator;
+
+        /** the const row iterator associated with the const_traverser
+        */
+    typedef typename const_traverser::row_iterator const_row_iterator;
+
+        /** the column iterator associated with the traverser
+        */
+    typedef typename traverser::column_iterator column_iterator;
+
+        /** the const column iterator associated with the const_traverser
+        */
+    typedef typename const_traverser::column_iterator const_column_iterator;
+
+        /** the BasicImageView's difference type (argument type of image[diff])
+        */
+    typedef Diff2D difference_type;
+
+         /** the BasicImageView's size type (result type of image.size())
+        */
+    typedef Size2D size_type;
+
+       /** the BasicImageView's default accessor
+        */
+    typedef typename
+          IteratorTraits<traverser>::DefaultAccessor Accessor;
+
+        /** the BasicImageView's default const accessor
+        */
+    typedef typename
+          IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor;
+
+        /** construct image of size 0x0
+        */
+    BasicImageView()
+    : data_(0),
+      width_(0),
+      height_(0),
+      stride_(0)
+    {}
+
+        /** construct view of size w x h
+        */
+    BasicImageView(const_pointer data, int w, int h, int stride = 0)
+    : data_(const_cast<pointer>(data)),
+      width_(w),
+      height_(h),
+      stride_(stride == 0 ? w : stride)
+    {}
+
+        /** construct view of size size.x x size.y
+        */
+    BasicImageView(const_pointer data, difference_type const & size, int stride = 0)
+    : data_(const_cast<pointer>(data)),
+      width_(size.x),
+      height_(size.y),
+      stride_(stride == 0 ? size.x : stride)
+    {}
+
+        /** set Image with const value
+        */
+    BasicImageView & init(value_type const & pixel)
+    {
+        initImage(upperLeft(), lowerRight(), accessor(), pixel);
+
+        return *this;
+    }
+
+        /** width of Image
+        */
+    int width() const
+    {
+        return width_;
+    }
+
+        /** height of Image
+        */
+    int height() const
+    {
+        return height_;
+    }
+
+        /** stride of Image.
+            Memory offset between the start of two successive rows.
+        */
+    int stride() const
+    {
+        return stride_;
+    }
+
+        /** size of Image
+        */
+    size_type size() const
+    {
+        return size_type(width(), height());
+    }
+
+        /** test whether a given coordinate is inside the image
+        */
+    bool isInside(difference_type const & d) const
+    {
+        return d.x >= 0 && d.y >= 0 &&
+               d.x < width() && d.y < height();
+    }
+
+        /** access pixel at given location. <br>
+        usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
+        */
+    reference operator[](difference_type const & d)
+    {
+        VIGRA_ASSERT_INSIDE(d);
+        return data_[d.y*stride_ + d.x];
+    }
+
+        /** read pixel at given location. <br>
+        usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
+        */
+    const_reference operator[](difference_type const & d) const
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(d));
+        return data_[d.y*stride_ + d.x];
+    }
+
+        /** access pixel at given location. <br>
+        usage: <TT> value_type value = image(1,2) </TT>
+        */
+    reference operator()(int dx, int dy)
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(dx,dy));
+        return data_[dy*stride_ + dx];
+    }
+
+        /** read pixel at given location. <br>
+        usage: <TT> value_type value = image(1,2) </TT>
+        */
+    const_reference operator()(int dx, int dy) const
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(dx, dy));
+        return data_[dy*stride_ + dx];
+    }
+
+        /** access pixel at given location.
+            Note that the 'x' index is the trailing index. <br>
+        usage: <TT> value_type value = image[2][1] </TT>
+        */
+    pointer operator[](int dy)
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(0, dy));
+        return data_ + dy*stride_;
+    }
+
+        /** read pixel at given location.
+            Note that the 'x' index is the trailing index. <br>
+        usage: <TT> value_type value = image[2][1] </TT>
+        */
+    const_pointer operator[](int dy) const
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(0,dy));
+        return data_ + dy*stride_;
+    }
+
+        /** init 2D random access iterator pointing to upper left pixel
+        */
+    traverser upperLeft()
+    {
+        return traverser(data_, stride_);
+    }
+
+        /** init 2D random access iterator pointing to
+         pixel(width, height), i.e. one pixel right and below lower right
+         corner of the image as is common in C/C++.
+        */
+    traverser lowerRight()
+    {
+        return upperLeft() + size();
+    }
+
+        /** init 2D random access const iterator pointing to upper left pixel
+        */
+    const_traverser upperLeft() const
+    {
+        return const_traverser(data_, stride_);
+    }
+
+        /** init 2D random access const iterator pointing to
+         pixel(width, height), i.e. one pixel right and below lower right
+         corner of the image as is common in C/C++.
+        */
+    const_traverser lowerRight() const
+    {
+        return upperLeft() + size();
+    }
+
+        /** init 1D random access iterator pointing to first pixel.
+            Note: Only works if stride equals width.
+        */
+    iterator begin()
+    {
+        vigra_precondition(stride_ == width_,
+            "BasicImageView::begin(): "
+            "can only create scan order iterator if width() == stride().");
+        return data_;
+    }
+
+        /** init 1D random access iterator pointing past the end.
+            Note: Only works if stride equals width.
+        */
+    iterator end()
+    {
+        vigra_precondition(stride_ == width_,
+            "BasicImageView::end(): "
+            "can only create scan order iterator if width() == stride().");
+        return data_ + width() * height();
+    }
+
+        /** init 1D random access const iterator pointing to first pixel.
+            Note: Only works if stride equals width.
+        */
+    const_iterator begin() const
+    {
+        vigra_precondition(stride_ == width_,
+            "BasicImageView::begin(): "
+            "can only create scan order iterator if width() == stride().");
+        return data_;
+    }
+
+        /** init 1D random access const iterator pointing past the end.
+            Note: Only works if stride equals width.
+        */
+    const_iterator end() const
+    {
+        vigra_precondition(stride_ == width_,
+            "BasicImageView::end(): "
+            "can only create scan order iterator if width() == stride().");
+        return data_ + width() * height();
+    }
+
+        /** init 1D random access iterator pointing to first pixel of row \a y
+        */
+    row_iterator rowBegin(int y)
+    {
+        return data_ + stride_ * y;
+    }
+
+        /** init 1D random access iterator pointing past the end of row \a y
+        */
+    row_iterator rowEnd(int y)
+    {
+        return rowBegin(y) + width();
+    }
+
+        /** init 1D random access const iterator pointing to first pixel of row \a y
+        */
+    const_row_iterator rowBegin(int y) const
+    {
+        return data_ + stride_ * y;
+    }
+
+        /** init 1D random access const iterator pointing past the end of row \a y
+        */
+    const_row_iterator rowEnd(int y) const
+    {
+        return rowBegin(y) + width();
+    }
+
+        /** init 1D random access iterator pointing to first pixel of column \a x
+        */
+    column_iterator columnBegin(int x)
+    {
+        typedef typename column_iterator::BaseType Iter;
+        return column_iterator(Iter(data_ + x, stride_));
+    }
+
+        /** init 1D random access iterator pointing past the end of column \a x
+        */
+    column_iterator columnEnd(int x)
+    {
+        return columnBegin(x) + height();
+    }
+
+        /** init 1D random access const iterator pointing to first pixel of column \a x
+        */
+    const_column_iterator columnBegin(int x) const
+    {
+        typedef typename const_column_iterator::BaseType Iter;
+        return const_column_iterator(Iter(data_ + x, stride_));
+    }
+
+        /** init 1D random access const iterator pointing past the end of column \a x
+        */
+    const_column_iterator columnEnd(int x) const
+    {
+        return columnBegin(x) + height();
+    }
+
+        /** get a pointer to the internal data
+        */
+    const_pointer data() const
+    {
+        return data_;
+    }
+
+        /** return default accessor
+        */
+    Accessor accessor()
+    {
+        return Accessor();
+    }
+
+        /** return default const accessor
+        */
+    ConstAccessor accessor() const
+    {
+        return ConstAccessor();
+    }
+
+  private:
+
+    pointer data_;
+    int width_, height_, stride_;
+};
+
+
+/********************************************************/
+/*                                                      */
+/*              argument object factories               */
+/*                                                      */
+/********************************************************/
+
+template <class PixelType, class Accessor>
+inline triple<typename BasicImageView<PixelType>::const_traverser,
+              typename BasicImageView<PixelType>::const_traverser, Accessor>
+srcImageRange(BasicImageView<PixelType> const & img, Accessor a)
+{
+    return triple<typename BasicImageView<PixelType>::const_traverser,
+                  typename BasicImageView<PixelType>::const_traverser,
+          Accessor>(img.upperLeft(),
+                    img.lowerRight(),
+                    a);
+}
+
+template <class PixelType, class Accessor>
+inline triple<typename BasicImageView<PixelType>::const_traverser,
+              typename BasicImageView<PixelType>::const_traverser, Accessor>
+srcImageRange(BasicImageView<PixelType> const & img, Rect2D const & roi, Accessor a)
+{
+    vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
+                       roi.right() <= img.width() && roi.bottom() <= img.height(),
+                       "srcImageRange(): ROI rectangle outside image.");
+    return triple<typename BasicImageView<PixelType>::const_traverser,
+                  typename BasicImageView<PixelType>::const_traverser,
+          Accessor>(img.upperLeft() + roi.upperLeft(),
+                    img.upperLeft() + roi.lowerRight(),
+                    a);
+}
+
+template <class PixelType, class Accessor>
+inline pair<typename BasicImageView<PixelType>::const_traverser, Accessor>
+srcImage(BasicImageView<PixelType> const & img, Accessor a)
+{
+    return pair<typename BasicImageView<PixelType>::const_traverser,
+                Accessor>(img.upperLeft(), a);
+}
+
+template <class PixelType, class Accessor>
+inline pair<typename BasicImageView<PixelType>::const_traverser, Accessor>
+srcImage(BasicImageView<PixelType> const & img, Point2D const & ul, Accessor a)
+{
+    vigra_precondition(img.isInside(ul),
+                       "srcImage(): ROI rectangle outside image.");
+    return pair<typename BasicImageView<PixelType>::const_traverser,
+                Accessor>(img.upperLeft() + ul, a);
+}
+
+template <class PixelType, class Accessor>
+inline triple<typename BasicImageView<PixelType>::traverser,
+              typename BasicImageView<PixelType>::traverser, Accessor>
+destImageRange(BasicImageView<PixelType> & img, Accessor a)
+{
+    return triple<typename BasicImageView<PixelType>::traverser,
+                  typename BasicImageView<PixelType>::traverser,
+          Accessor>(img.upperLeft(),
+                    img.lowerRight(),
+                    a);
+}
+
+template <class PixelType, class Accessor>
+inline triple<typename BasicImageView<PixelType>::traverser,
+              typename BasicImageView<PixelType>::traverser, Accessor>
+destImageRange(BasicImageView<PixelType> & img, Rect2D const & roi, Accessor a)
+{
+    vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
+                       roi.right() <= img.width() && roi.bottom() <= img.height(),
+                       "destImageRange(): ROI rectangle outside image.");
+    return triple<typename BasicImageView<PixelType>::traverser,
+                  typename BasicImageView<PixelType>::traverser,
+          Accessor>(img.upperLeft() + roi.upperLeft(),
+                    img.upperLeft() + roi.lowerRight(),
+                    a);
+}
+
+template <class PixelType, class Accessor>
+inline pair<typename BasicImageView<PixelType>::traverser, Accessor>
+destImage(BasicImageView<PixelType> & img, Accessor a)
+{
+    return pair<typename BasicImageView<PixelType>::traverser,
+                Accessor>(img.upperLeft(), a);
+}
+
+template <class PixelType, class Accessor>
+inline pair<typename BasicImageView<PixelType>::traverser, Accessor>
+destImage(BasicImageView<PixelType> & img, Point2D const & ul, Accessor a)
+{
+    vigra_precondition(img.isInside(ul),
+                       "destImage(): ROI rectangle outside image.");
+    return pair<typename BasicImageView<PixelType>::traverser,
+                Accessor>(img.upperLeft() + ul, a);
+}
+
+template <class PixelType, class Accessor>
+inline pair<typename BasicImageView<PixelType>::const_traverser, Accessor>
+maskImage(BasicImageView<PixelType> const & img, Accessor a)
+{
+    return pair<typename BasicImageView<PixelType>::const_traverser,
+                Accessor>(img.upperLeft(), a);
+}
+
+template <class PixelType, class Accessor>
+inline pair<typename BasicImageView<PixelType>::const_traverser, Accessor>
+maskImage(BasicImageView<PixelType> const & img, Point2D const & ul, Accessor a)
+{
+    vigra_precondition(img.isInside(ul),
+                       "maskImage(): ROI rectangle outside image.");
+    return pair<typename BasicImageView<PixelType>::const_traverser,
+                Accessor>(img.upperLeft() + ul, a);
+}
+
+/****************************************************************/
+
+template <class PixelType>
+inline triple<typename BasicImageView<PixelType>::const_traverser,
+              typename BasicImageView<PixelType>::const_traverser,
+              typename BasicImageView<PixelType>::ConstAccessor>
+srcImageRange(BasicImageView<PixelType> const & img)
+{
+    return triple<typename BasicImageView<PixelType>::const_traverser,
+                  typename BasicImageView<PixelType>::const_traverser,
+                  typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft(),
+                                                                        img.lowerRight(),
+                                                                        img.accessor());
+}
+
+template <class PixelType>
+inline triple<typename BasicImageView<PixelType>::const_traverser,
+              typename BasicImageView<PixelType>::const_traverser,
+              typename BasicImageView<PixelType>::ConstAccessor>
+srcImageRange(BasicImageView<PixelType> const & img, Rect2D const & roi)
+{
+    vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
+                       roi.right() <= img.width() && roi.bottom() <= img.height(),
+                       "srcImageRange(): ROI rectangle outside image.");
+    return triple<typename BasicImageView<PixelType>::const_traverser,
+                  typename BasicImageView<PixelType>::const_traverser,
+                  typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft() + roi.upperLeft(),
+                                                                        img.upperLeft() + roi.lowerRight(),
+                                                                        img.accessor());
+}
+
+template <class PixelType>
+inline pair< typename BasicImageView<PixelType>::const_traverser,
+             typename BasicImageView<PixelType>::ConstAccessor>
+srcImage(BasicImageView<PixelType> const & img)
+{
+    return pair<typename BasicImageView<PixelType>::const_traverser,
+                typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft(),
+                                                                      img.accessor());
+}
+
+template <class PixelType>
+inline pair< typename BasicImageView<PixelType>::const_traverser,
+             typename BasicImageView<PixelType>::ConstAccessor>
+srcImage(BasicImageView<PixelType> const & img, Point2D const & ul)
+{
+    vigra_precondition(img.isInside(ul),
+                       "srcImage(): ROI rectangle outside image.");
+    return pair<typename BasicImageView<PixelType>::const_traverser,
+                typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft() + ul,
+                                                                      img.accessor());
+}
+
+template <class PixelType>
+inline triple< typename BasicImageView<PixelType>::traverser,
+               typename BasicImageView<PixelType>::traverser,
+               typename BasicImageView<PixelType>::Accessor>
+destImageRange(BasicImageView<PixelType> & img)
+{
+    return triple<typename BasicImageView<PixelType>::traverser,
+                  typename BasicImageView<PixelType>::traverser,
+                  typename BasicImageView<PixelType>::Accessor>(img.upperLeft(),
+                                                                   img.lowerRight(),
+                                                                   img.accessor());
+}
+
+template <class PixelType>
+inline triple< typename BasicImageView<PixelType>::traverser,
+               typename BasicImageView<PixelType>::traverser,
+               typename BasicImageView<PixelType>::Accessor>
+destImageRange(BasicImageView<PixelType> & img, Rect2D const & roi)
+{
+    vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
+                       roi.right() <= img.width() && roi.bottom() <= img.height(),
+                       "destImageRange(): ROI rectangle outside image.");
+    return triple<typename BasicImageView<PixelType>::traverser,
+                  typename BasicImageView<PixelType>::traverser,
+                  typename BasicImageView<PixelType>::Accessor>(img.upperLeft() + roi.upperLeft(),
+                                                                   img.upperLeft() + roi.lowerRight(),
+                                                                   img.accessor());
+}
+
+template <class PixelType>
+inline pair< typename BasicImageView<PixelType>::traverser,
+             typename BasicImageView<PixelType>::Accessor>
+destImage(BasicImageView<PixelType> & img)
+{
+    return pair<typename BasicImageView<PixelType>::traverser,
+                typename BasicImageView<PixelType>::Accessor>(img.upperLeft(),
+                                                          img.accessor());
+}
+
+template <class PixelType>
+inline pair< typename BasicImageView<PixelType>::traverser,
+             typename BasicImageView<PixelType>::Accessor>
+destImage(BasicImageView<PixelType> & img, Point2D const & ul)
+{
+    vigra_precondition(img.isInside(ul),
+                       "destImage(): ROI rectangle outside image.");
+    return pair<typename BasicImageView<PixelType>::traverser,
+                typename BasicImageView<PixelType>::Accessor>(img.upperLeft() + ul,
+                                                                 img.accessor());
+}
+
+template <class PixelType>
+inline pair< typename BasicImageView<PixelType>::const_traverser,
+             typename BasicImageView<PixelType>::ConstAccessor>
+maskImage(BasicImageView<PixelType> const & img)
+{
+    return pair<typename BasicImageView<PixelType>::const_traverser,
+                typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft(),
+                                                                      img.accessor());
+}
+
+template <class PixelType>
+inline pair< typename BasicImageView<PixelType>::const_traverser,
+             typename BasicImageView<PixelType>::ConstAccessor>
+maskImage(BasicImageView<PixelType> const & img, Point2D const & ul)
+{
+    vigra_precondition(img.isInside(ul),
+                       "maskImage(): ROI rectangle outside image.");
+    return pair<typename BasicImageView<PixelType>::const_traverser,
+                typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft() + ul,
+                                                                      img.accessor());
+}
+
+} // namespace vigra
+#undef VIGRA_ASSERT_INSIDE
+#endif /* VIGRA_BASICIMAGEVIEW_HXX */
diff --git a/include/vigra/bessel.hxx b/include/vigra/bessel.hxx
new file mode 100644
index 0000000..2ec0733
--- /dev/null
+++ b/include/vigra/bessel.hxx
@@ -0,0 +1,337 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2010-2011 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_BESSEL_HXX
+#define VIGRA_BESSEL_HXX
+
+#include "mathutil.hxx"
+
+#ifdef HasBoostMath
+#include <boost/math/special_functions/bessel.hpp>
+#endif
+
+namespace vigra {
+
+/** \addtogroup MathFunctions 
+*/
+//@{
+
+namespace detail {
+
+template <class REAL>
+int msta1(REAL x, int mp)
+{
+    double a0,f0,f1,f;
+    int i,n0,n1,nn;
+
+    a0 = abs(x);
+    n0 = (int)(1.1*a0)+1;
+    f0 = 0.5*std::log10(6.28*n0) - n0*std::log10(1.36*a0/n0)-mp;
+    n1 = n0+5;
+    f1 = 0.5*std::log10(6.28*n1) - n1*std::log10(1.36*a0/n1)-mp;
+    for(i=0;i<20;i++) 
+    {
+        nn = int(n1-(n1-n0)/(1.0-f0/f1));
+        f = 0.5*std::log10(6.28*nn) - nn*std::log10(1.36*a0/nn)-mp;
+        if(abs(nn-n1) < 1) 
+            break;
+        n0 = n1;
+        f0 = f1;
+        n1 = nn;
+        f1 = f;
+    }
+    return nn;
+}
+
+template <class REAL>
+int msta2(REAL x, int n, int mp)
+{
+    double a0,ejn,hmp,f0,f1,f,obj;
+    int i,n0,n1,nn;
+
+    a0 = abs(x);
+    hmp = 0.5*mp;
+    ejn = 0.5*std::log10(6.28*n) - n*std::log10(1.36*a0/n);
+    if (ejn <= hmp) 
+    {
+        obj = mp;
+        n0 = (int)(1.1*a0);
+        if (n0 < 1) 
+            n0 = 1;
+    }
+    else 
+    {
+        obj = hmp+ejn;
+        n0 = n;
+    }
+    f0 = 0.5*std::log10(6.28*n0) - n0*std::log10(1.36*a0/n0)-obj;
+    n1 = n0+5;
+    f1 = 0.5*std::log10(6.28*n1) - n1*std::log10(1.36*a0/n1)-obj;
+    for (i=0;i<20;i++) 
+    {
+        nn = int(n1-(n1-n0)/(1.0-f0/f1));
+        f = 0.5*std::log10(6.28*nn) - nn*std::log10(1.36*a0/nn)-obj;
+        if (abs(nn-n1) < 1) 
+            break;
+        n0 = n1;
+        f0 = f1;
+        n1 = nn;
+        f1 = f;
+    }
+    return nn+10;
+}
+
+//
+//  INPUT:
+//  double x    -- argument of Bessel function of 1st and 2nd kind.
+//  int n       -- order
+//
+//  OUPUT:
+//
+//  int nm      -- highest order actually computed (nm <= n)
+//  double jn[] -- Bessel function of 1st kind, orders from 0 to nm
+//  double yn[] -- Bessel function of 2nd kind, orders from 0 to nm
+//
+//  Computes Bessel functions of all order up to 'n' using recurrence
+//  relations. If 'nm' < 'n' only 'nm' orders are returned.
+//
+// code has been adapted from C.R. Bond's implementation
+// see http://www.crbond.com/math.htm
+//
+template <class REAL>
+void bessjyn(int n, REAL x,int &nm, double *jn, double *yn)
+{
+    double t1,t2,f,f1,f2,bj0,bj1,bjk,by0,by1,cu,s0,su,sv;
+    double ec,bs,byk,p0,p1,q0,q1;
+    double a[] = {
+        -0.7031250000000000e-1,
+         0.1121520996093750,
+        -0.5725014209747314,
+         6.074042001273483};
+    double b[] = {
+         0.7324218750000000e-1,
+        -0.2271080017089844,
+         1.727727502584457,
+        -2.438052969955606e1};
+    double a1[] = {
+         0.1171875,
+        -0.1441955566406250,
+         0.6765925884246826,
+        -6.883914268109947};
+    double b1[] = {
+       -0.1025390625,
+        0.2775764465332031,
+       -1.993531733751297,
+        2.724882731126854e1};
+        
+    int i,k,m;
+    nm = n;
+    if (x < 1e-15) 
+    {
+        for (i=0;i<=n;i++) 
+        {
+            jn[i] = 0.0;
+            yn[i] = -1e308;
+        }
+        jn[0] = 1.0;
+        return;
+    }
+    if (x <= 300.0 || n > (int)(0.9*x)) 
+    {
+        if (n == 0) 
+            nm = 1;
+        m = msta1(x,200);
+        if (m < nm) 
+            nm = m;
+        else 
+            m = msta2(x,nm,15);
+        bs = 0.0;
+        su = 0.0;
+        sv = 0.0;
+        f2 = 0.0;
+        f1 = 1.0e-100;
+        for (k = m;k>=0;k--) 
+        {
+            f = 2.0*(k+1.0)/x*f1 - f2;
+            if (k <= nm) 
+                jn[k] = f;
+            if ((k == 2*(int)(k/2)) && (k != 0)) 
+            {
+                bs += 2.0*f;
+                su += (-1)*((k & 2)-1)*f/(double)k;
+            }
+            else if (k > 1) 
+            {
+                sv += (-1)*((k & 2)-1)*(double)k*f/(k*k-1.0);
+            }
+            f2 = f1;
+            f1 = f;
+        }
+        s0 = bs+f;
+        for (k=0;k<=nm;k++) 
+        {
+            jn[k] /= s0;
+        }
+        ec = std::log(0.5*x) + M_EULER_GAMMA;
+        by0 = M_2_PI*(ec*jn[0]-4.0*su/s0);
+        yn[0] = by0;
+        by1 = M_2_PI*((ec-1.0)*jn[1]-jn[0]/x-4.0*sv/s0);
+        yn[1] = by1;
+    }
+    else 
+    {
+        t1 = x-M_PI_4;
+        p0 = 1.0;
+        q0 = -0.125/x;
+        for (k=0;k<4;k++) 
+        {
+            p0 += a[k]*std::pow(x,-2*k-2);
+            q0 += b[k]*std::pow(x,-2*k-3);
+        }
+        cu = std::sqrt(M_2_PI/x);
+        bj0 = cu*(p0*std::cos(t1)-q0*std::sin(t1));
+        by0 = cu*(p0*std::sin(t1)+q0*std::cos(t1));
+        jn[0] = bj0;
+        yn[0] = by0;
+        t2 = x-0.75*M_PI;
+        p1 = 1.0;
+        q1 = 0.375/x;
+        for (k=0;k<4;k++) 
+        {
+            p1 += a1[k]*std::pow(x,-2*k-2);
+            q1 += b1[k]*std::pow(x,-2*k-3);
+        }
+        bj1 = cu*(p1*std::cos(t2)-q1*std::sin(t2));
+        by1 = cu*(p1*std::sin(t2)+q1*std::cos(t2));
+        jn[1] = bj1;
+        yn[1] = by1;
+        for (k=2;k<=nm;k++) 
+        {
+            bjk = 2.0*(k-1.0)*bj1/x-bj0;
+            jn[k] = bjk;
+            bj0 = bj1;
+            bj1 = bjk;
+        }
+    }
+    for (k=2;k<=nm;k++) 
+    {
+        byk = 2.0*(k-1.0)*by1/x-by0;
+        yn[k] = byk;
+        by0 = by1;
+        by1 = byk;
+    }
+}
+
+
+ 
+} // namespace detail
+
+    /** \brief Bessel function of the first kind. 
+
+        Computes the value of BesselJ of integer order <tt>n</tt> and argument <tt>x</tt>.
+        Negative <tt>x</tt> are unsupported and will result in a <tt>std::domain_error</tt>.
+
+        This function wraps a number of existing implementations and falls back to 
+        a rather slow algorithm if none of them is available. In particular,
+        it uses boost::math when <tt>HasBoostMath</tt> is \#defined, or native 
+        implementations on gcc and MSVC otherwise.
+
+        <b>\#include</b> \<vigra/bessel.hxx\><br>
+        Namespace: vigra
+    */
+inline double besselJ(int n, double x)
+{
+    if(x < 0.0)
+        throw std::domain_error("besselJ(n, x): x cannot be negative");
+    if(x < 1e-15)
+        return n == 0 ? 1.0 : 0.0;
+#if defined(HasBoostMath)
+    return boost::math::cyl_bessel_j((double)n, x);
+#elif defined(__GNUC__)
+    return ::jn(n, x);
+#elif defined(_MSC_VER)
+    return _jn(n, x);
+#else
+    int an = abs(n), nr = n, s = an+2;
+    ArrayVector<double> t(2*s);
+    detail::bessjyn(an, x, nr, &t[0], &t[s]);
+    if(n < 0 && odd(an))
+        return -t[an];
+    else
+        return  t[an];
+#endif
+}
+
+    /** \brief Bessel function of the second kind. 
+
+        Computes the value of BesselY of integer order <tt>n</tt> and argument <tt>x</tt>.
+        Negative <tt>x</tt> are unsupported and will result in a <tt>std::domain_error</tt>.
+
+        This function wraps a number of existing implementations and falls back to 
+        a rather slow algorithm if none of them is available. In particular,
+        it uses boost::math when <tt>HasBoostMath</tt> is \#defined, or native 
+        implementations on gcc and MSVC otherwise.
+
+        <b>\#include</b> \<vigra/bessel.hxx\><br>
+        Namespace: vigra
+    */
+inline double besselY(int n, double x)
+{
+    if(x < 0.0)
+        throw std::domain_error("besselY(n, x): x cannot be negative");
+    if(x == 0.0 )
+        return -std::numeric_limits<double>::infinity();
+#if defined(HasBoostMath)
+    return boost::math::cyl_neumann((double)n, x);
+#elif defined(__GNUC__)
+    return ::yn(n, x);
+#elif defined(_MSC_VER)
+    return _yn(n, x);
+#else
+    int an = abs(n), nr = n, s = an+2;
+    ArrayVector<double> t(2*s);
+    detail::bessjyn(an, x, nr, &t[0], &t[s]);
+    if(n < 0.0 && odd(n))
+        return -t[an+s];
+    else
+        return  t[an+s];
+#endif
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_BESSEL_HXX
diff --git a/include/vigra/bit_array.hxx b/include/vigra/bit_array.hxx
new file mode 100644
index 0000000..86d47e7
--- /dev/null
+++ b/include/vigra/bit_array.hxx
@@ -0,0 +1,318 @@
+#ifndef VIGRA_BIT_ARRAY_HXX
+#define VIGRA_BIT_ARRAY_HXX
+
+#include <functional>
+#include <ostream>
+#include "metaprogramming.hxx"
+
+namespace vigra {
+
+template <class> // undefined class to provoke usable error messages
+class vigra_error_BitArray_accepts_only_unsigned_underlying_types_and_no_;
+
+template <unsigned SIZE, class X> // bitwise operators do not necessarily work for bool
+struct EnableBitArray
+    : public enable_if<(HasMetaLog2<X>::value && !IsSameType<X, bool>::value && SIZE > 0)> {};
+
+// BitArray: a minimal subset of std::bitset with the extension of compile-time
+// access functions set<unsigned>(), test<unsigned>(), reset<unsigned>(), and
+// flip<unsigned>(), plus all relational operators;
+// furthermore, there are no range checks.
+
+template <unsigned SIZE, class WORD_TYPE = unsigned, class = void>
+class BitArray
+    : public
+      vigra_error_BitArray_accepts_only_unsigned_underlying_types_and_no_
+      <WORD_TYPE>
+{};
+
+template <unsigned SIZE, class WORD_TYPE>
+class BitArray<SIZE, WORD_TYPE, typename EnableBitArray<SIZE, WORD_TYPE>::type>
+{
+    // 'unsigned' will be the most efficent word type for most CPUs,
+    // since very long immediates such as a possible 64 bit 'unsigned long'
+    // are slower for many typical uses of BitArray
+  protected:
+    static const unsigned bit_size = SIZE;
+    static const unsigned word_len = MetaLog2<WORD_TYPE>::value;
+    static const unsigned array_len = (bit_size + word_len - 1) / word_len;
+    static const unsigned last_pos = array_len - 1;
+    template <unsigned pos>
+    struct bit_index
+    {
+        static const unsigned  word_pos = pos / word_len;
+        static const unsigned   bit_pos = pos % word_len;
+        static const WORD_TYPE bit_mask = WORD_TYPE(1) << bit_pos;
+    };
+    typedef bit_index<bit_size> size_index;
+    static const WORD_TYPE ones_mask = ~(WORD_TYPE(0));
+    static const unsigned border_pos = size_index::bit_pos;
+    static const WORD_TYPE last_mask = !border_pos ? 0
+                                                   : size_index::bit_mask - 1;
+    static const bool does_fit = border_pos == 0;
+    unsigned word_pos(unsigned pos) const
+    {
+        return pos / word_len;
+    };
+    WORD_TYPE bit_mask(unsigned pos) const
+    {
+        return WORD_TYPE(1) << (pos % word_len); // the compiler knows as well..
+    };
+
+    WORD_TYPE set_bits[array_len];
+
+  public:
+    unsigned size()
+    {
+        return bit_size;
+    }
+    void clear()
+    {
+        for (unsigned i = 0; i != array_len; ++i)
+            set_bits[i] = 0;
+    }
+    BitArray()
+    {
+        clear();
+    }
+    template <unsigned pos>
+    void set()
+    {
+        typedef bit_index<pos> index;
+        set_bits[index::word_pos] |= index::bit_mask;
+    }
+    template <unsigned pos>
+    void reset()
+    {
+        typedef bit_index<pos> index;
+        set_bits[index::word_pos] &= ~index::bit_mask;
+    }
+    template <unsigned pos>
+    void flip()
+    {
+        typedef bit_index<pos> index;
+        set_bits[index::word_pos] ^= index::bit_mask;
+    }
+    template <unsigned pos>
+    bool test() const
+    {
+        typedef bit_index<pos> index;
+        return (set_bits[index::word_pos] & index::bit_mask) != 0;
+    }
+
+    BitArray & set(unsigned pos, bool value = true)
+    {
+        (set_bits[word_pos(pos)] &= ~bit_mask(pos))
+                                 |= value ? bit_mask(pos) : 0;
+        return *this;
+    }
+    BitArray & reset(unsigned pos)
+    {
+        set_bits[word_pos(pos)] &= ~bit_mask(pos);
+        return *this;
+    }
+    BitArray & flip(unsigned pos)
+    {
+        set_bits[word_pos(pos)] ^= bit_mask(pos);
+        return *this;
+    }
+    bool test(unsigned pos) const
+    {
+        return set_bits[word_pos(pos)] & bit_mask(pos);
+    }
+    bool operator[](unsigned pos) const
+    {
+        return test(pos);
+    }
+
+    BitArray & set()
+    {
+        for (unsigned i = 0; i != last_pos + does_fit; ++i)
+            set_bits[i] = ones_mask;
+        if (!does_fit)
+            set_bits[last_pos] = last_mask;
+        return *this;
+    }
+    BitArray & reset()
+    {
+        for (unsigned i = 0; i != array_len; ++i)
+            set_bits[i] = 0;
+        return *this;
+    }
+    BitArray & flip()
+    {
+        for (unsigned i = 0; i != last_pos + does_fit; ++i)
+            set_bits[i] ^= ones_mask;
+        if (!does_fit)
+            set_bits[last_pos] ^= last_mask;
+        return *this;
+    }
+
+    operator bool() const
+    {
+        for (unsigned i = 0; i != array_len; ++i)
+            if (set_bits[i] != 0)
+                return true;
+        return false;
+    }
+    bool operator!() const
+    {
+        return !bool(*this);
+    }
+    bool any() const
+    {
+        return *this;
+    }
+    bool none() const
+    {
+        return !*this;
+    }
+    bool all() const
+    {
+        for (unsigned i = 0; i != last_pos + does_fit; ++i)
+            if (set_bits[i] != ones_mask)
+                return false;
+        if (!does_fit)
+            return set_bits[last_pos] == last_mask;
+        return true;
+    }
+    
+    BitArray operator~() const
+    {
+        BitArray x(*this);
+        x.flip();
+        return x;
+    }
+   
+  protected:
+    template <class F>
+    bool mutual_compare(const BitArray & t, F f, bool if_equal = false) const
+    {
+        for (int i = last_pos; i >= 0; i--)
+        {
+            WORD_TYPE x =   set_bits[i];
+            WORD_TYPE y = t.set_bits[i];
+            if (f(x, y))
+                return true;
+            if (f(y, x))
+                return false;
+        }
+        return if_equal;
+    }
+    typedef std::less<WORD_TYPE>    less;
+    typedef std::greater<WORD_TYPE> greater;
+    
+  public:
+    bool operator<(const BitArray & t) const
+    {
+        return mutual_compare(t, less());
+    }
+    bool operator>(const BitArray & t) const
+    {
+        return mutual_compare(t, greater());
+    }
+
+    bool operator<=(const BitArray & t) const
+    {
+        return mutual_compare(t, less(), true);
+    }
+    bool operator>=(const BitArray & t) const
+    {
+        return mutual_compare(t, greater(), true);
+    }
+
+    bool operator!=(const BitArray & t) const
+    {
+        for (unsigned i = 0; i != array_len; ++i)
+            if (set_bits[i] != t.set_bits[i])
+                return true;
+        return false;
+    }
+    bool operator==(const BitArray & t) const
+    {
+        return !operator!=(t);
+    }
+
+  protected:
+    struct bit_and_assign
+    {
+        static void assign(WORD_TYPE & a, WORD_TYPE b) { a &= b; }
+    };
+    struct exclusive_or_assign
+    {
+        static void assign(WORD_TYPE & a, WORD_TYPE b) { a ^= b; }
+    };
+    struct bit_or_assign
+    {
+        static void assign(WORD_TYPE & a, WORD_TYPE b) { a |= b; }
+    };
+    template <class A>
+    BitArray & assign_operator(const BitArray & x)
+    {
+        for (unsigned i = 0; i != array_len; ++i)
+            A::assign(set_bits[i], x.set_bits[i]);
+        return *this;
+    }
+  public:
+    BitArray & operator&=(const BitArray & x)
+    {
+        return assign_operator<bit_and_assign>(x);
+    }
+    BitArray & operator^=(const BitArray & x)
+    {
+        return assign_operator<exclusive_or_assign>(x);
+    }
+    BitArray & operator|=(const BitArray & x)
+    {
+        return assign_operator<bit_or_assign>(x);
+    }
+   
+  protected:
+    template <class A>
+    BitArray & bit_operator(const BitArray & y) const
+    {
+        BitArray x(*this);
+        return x.assign_operator<A>(y);
+    }
+  public:
+    BitArray operator&(const BitArray & y) const
+    {
+        return bit_operator<bit_and_assign>(y);
+    }
+    BitArray operator^(const BitArray & y) const
+    {
+        return bit_operator<exclusive_or_assign>(y);
+    }
+    BitArray operator|(const BitArray & y) const
+    {
+        return bit_operator<bit_or_assign>(y);
+    }
+
+    bool operator&&(const BitArray & y) const
+    {
+        return *this && y;
+    }
+    bool operator||(const BitArray & y) const
+    {
+        return *this || y;
+    }
+
+    friend std::ostream & operator<<(std::ostream & os, const BitArray & z)
+    {
+        for (int i = bit_size - 1; i >= 0; i--)
+            os << (z[i] ? "1" : "0");
+        return os;
+    }
+};
+
+// work around GCC's zero-sized array extension
+template <class WORD_TYPE>
+class BitArray<0, WORD_TYPE>
+{
+//    bool error[-(long int)sizeof(WORD_TYPE)];
+    void clear() {}
+};
+
+} // namespace vigra
+
+#endif // VIGRA_BIT_ARRAY_HXX
diff --git a/include/vigra/bordertreatment.hxx b/include/vigra/bordertreatment.hxx
new file mode 100644
index 0000000..4d75888
--- /dev/null
+++ b/include/vigra/bordertreatment.hxx
@@ -0,0 +1,90 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_BORDERTREATMENT_HXX
+#define VIGRA_BORDERTREATMENT_HXX
+
+namespace vigra {
+
+
+/** \page BorderTreatmentMode BorderTreatmentMode
+
+    Choose between different border treatment modes. In the convolution 
+    algorithms, these modes apply to 
+    all image pixels where the kernel does not completely fit inside 
+    the image.
+    
+    <b>\#include</b> \<vigra/bordertreatment.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    enum BorderTreatmentMode 
+    {
+          // do not operate on a pixel where the kernel does 
+          // not fit in the image
+       BORDER_TREATMENT_AVOID, 
+
+          // clip kernel at image border (this is only useful if the
+          //  kernel is >= 0 everywhere)
+       BORDER_TREATMENT_CLIP, 
+
+          // repeat the nearest valid pixel
+       BORDER_TREATMENT_REPEAT,
+
+          // reflect image at last row/column 
+       BORDER_TREATMENT_REFLECT, 
+
+          // wrap image around (periodic boundary conditions)
+       BORDER_TREATMENT_WRAP
+
+          // assume that all outside points have value zero
+       BORDER_TREATMENT_ZEROPAD
+    };
+    \endcode
+*/   
+enum BorderTreatmentMode 
+{
+   BORDER_TREATMENT_AVOID, 
+   BORDER_TREATMENT_CLIP, 
+   BORDER_TREATMENT_REPEAT,
+   BORDER_TREATMENT_REFLECT, 
+   BORDER_TREATMENT_WRAP,
+   BORDER_TREATMENT_ZEROPAD
+};
+
+} // namespace vigra
+
+#endif // VIGRA_BORDERTREATMENT_HXX
diff --git a/include/vigra/boundarytensor.hxx b/include/vigra/boundarytensor.hxx
new file mode 100644
index 0000000..5bac846
--- /dev/null
+++ b/include/vigra/boundarytensor.hxx
@@ -0,0 +1,897 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_BOUNDARYTENSOR_HXX
+#define VIGRA_BOUNDARYTENSOR_HXX
+
+#include <cmath>
+#include <functional>
+#include "utilities.hxx"
+#include "array_vector.hxx"
+#include "basicimage.hxx"
+#include "combineimages.hxx"
+#include "numerictraits.hxx"
+#include "convolution.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+namespace detail {
+
+/***********************************************************************/
+
+typedef ArrayVector<Kernel1D<double> > KernelArray;
+
+template <class KernelArray>
+void
+initGaussianPolarFilters1(double std_dev, KernelArray & k)
+{
+    typedef typename KernelArray::value_type Kernel;
+    typedef typename Kernel::iterator iterator;
+
+    vigra_precondition(std_dev >= 0.0,
+              "initGaussianPolarFilter1(): "
+              "Standard deviation must be >= 0.");
+
+    k.resize(4);
+
+    int radius = (int)(4.0*std_dev + 0.5);
+    std_dev *= 1.08179074376;
+    double f = 1.0 / VIGRA_CSTD::sqrt(2.0 * M_PI) / std_dev;  // norm
+    double a = 0.558868151788 / VIGRA_CSTD::pow(std_dev, 5);
+    double b = -2.04251639729 / VIGRA_CSTD::pow(std_dev, 3);
+    double sigma22 = -0.5 / std_dev / std_dev;
+
+
+    for(unsigned int i=0; i<k.size(); ++i)
+    {
+        k[i].initExplicitly(-radius, radius);
+        k[i].setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+    int ix;
+    iterator c = k[0].center();
+    for(ix=-radius; ix<=radius; ++ix)
+    {
+        double x = (double)ix;
+        c[ix] = f * VIGRA_CSTD::exp(sigma22 * x * x);
+    }
+
+    c = k[1].center();
+    for(ix=-radius; ix<=radius; ++ix)
+    {
+        double x = (double)ix;
+        c[ix] = f * x * VIGRA_CSTD::exp(sigma22 * x * x);
+    }
+
+    c = k[2].center();
+    double b2 = b / 3.0;
+    for(ix=-radius; ix<=radius; ++ix)
+    {
+        double x = (double)ix;
+        c[ix] = f * (b2 + a * x * x) * VIGRA_CSTD::exp(sigma22 * x * x);
+    }
+
+    c = k[3].center();
+    for(ix=-radius; ix<=radius; ++ix)
+    {
+        double x = (double)ix;
+        c[ix] = f * x * (b + a * x * x) * VIGRA_CSTD::exp(sigma22 * x * x);
+    }
+}
+
+template <class KernelArray>
+void
+initGaussianPolarFilters2(double std_dev, KernelArray & k)
+{
+    typedef typename KernelArray::value_type Kernel;
+    typedef typename Kernel::iterator iterator;
+
+    vigra_precondition(std_dev >= 0.0,
+              "initGaussianPolarFilter2(): "
+              "Standard deviation must be >= 0.");
+
+    k.resize(3);
+
+    int radius = (int)(4.0*std_dev + 0.5);
+    double f = 1.0 / VIGRA_CSTD::sqrt(2.0 * M_PI) / std_dev;  // norm
+    double sigma2 = std_dev*std_dev;
+    double sigma22 = -0.5 / sigma2;
+
+    for(unsigned int i=0; i<k.size(); ++i)
+    {
+        k[i].initExplicitly(-radius, radius);
+        k[i].setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+    int ix;
+    iterator c = k[0].center();
+    for(ix=-radius; ix<=radius; ++ix)
+    {
+        double x = (double)ix;
+        c[ix] = f * VIGRA_CSTD::exp(sigma22 * x * x);
+    }
+
+    c = k[1].center();
+    double f1 = f / sigma2;
+    for(ix=-radius; ix<=radius; ++ix)
+    {
+        double x = (double)ix;
+        c[ix] = f1 * x * VIGRA_CSTD::exp(sigma22 * x * x);
+    }
+
+    c = k[2].center();
+    double f2 = f / (sigma2 * sigma2);
+    for(ix=-radius; ix<=radius; ++ix)
+    {
+        double x = (double)ix;
+        c[ix] = f2 * (x * x - sigma2) * VIGRA_CSTD::exp(sigma22 * x * x);
+    }
+}
+
+template <class KernelArray>
+void
+initGaussianPolarFilters3(double std_dev, KernelArray & k)
+{
+    typedef typename KernelArray::value_type Kernel;
+    typedef typename Kernel::iterator iterator;
+
+    vigra_precondition(std_dev >= 0.0,
+              "initGaussianPolarFilter3(): "
+              "Standard deviation must be >= 0.");
+
+    k.resize(4);
+
+    int radius = (int)(4.0*std_dev + 0.5);
+    std_dev *= 1.15470053838;
+    double sigma22 = -0.5 / std_dev / std_dev;
+    double f = 1.0 / VIGRA_CSTD::sqrt(2.0 * M_PI) / std_dev;  // norm
+    double a = 0.883887052922 / VIGRA_CSTD::pow(std_dev, 5);
+
+    for(unsigned int i=0; i<k.size(); ++i)
+    {
+        k[i].initExplicitly(-radius, radius);
+        k[i].setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+    //double b = -1.3786348292 / VIGRA_CSTD::pow(std_dev, 3);
+
+    int ix;
+    iterator c = k[0].center();
+    for(ix=-radius; ix<=radius; ++ix)
+    {
+        double x = (double)ix;
+        c[ix] = f * VIGRA_CSTD::exp(sigma22 * x * x);
+    }
+
+    c = k[1].center();
+    for(ix=-radius; ix<=radius; ++ix)
+    {
+        double x = (double)ix;
+        c[ix] = f * x * VIGRA_CSTD::exp(sigma22 * x * x);
+    }
+
+    c = k[2].center();
+    double a2 = 3.0 * a;
+    for(ix=-radius; ix<=radius; ++ix)
+    {
+        double x = (double)ix;
+        c[ix] = f * a2 * x * x * VIGRA_CSTD::exp(sigma22 * x * x);
+    }
+
+    c = k[3].center();
+    for(ix=-radius; ix<=radius; ++ix)
+    {
+        double x = (double)ix;
+        c[ix] = f * a * x * x * x * VIGRA_CSTD::exp(sigma22 * x * x);
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+evenPolarFilters(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
+                 DestIterator dupperleft, DestAccessor dest,
+                 double scale, bool noLaplacian)
+{
+    vigra_precondition(dest.size(dupperleft) == 3,
+                       "evenPolarFilters(): image for even output must have 3 bands.");
+
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+
+    typedef typename
+       NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    typedef BasicImage<TinyVector<TmpType, 3> > TmpImage;
+    typedef typename TmpImage::traverser TmpTraverser;
+    TmpImage t(w, h);
+
+    KernelArray k2;
+    initGaussianPolarFilters2(scale, k2);
+
+    // calculate filter responses for even filters
+    VectorElementAccessor<typename TmpImage::Accessor> tmpBand(0, t.accessor());
+    convolveImage(srcIterRange(supperleft, slowerright, src),
+                  destImage(t, tmpBand), k2[2], k2[0]);
+    tmpBand.setIndex(1);
+    convolveImage(srcIterRange(supperleft, slowerright, src),
+                  destImage(t, tmpBand), k2[1], k2[1]);
+    tmpBand.setIndex(2);
+    convolveImage(srcIterRange(supperleft, slowerright, src),
+                  destImage(t, tmpBand), k2[0], k2[2]);
+
+    // create even tensor from filter responses
+    TmpTraverser tul(t.upperLeft());
+    TmpTraverser tlr(t.lowerRight());
+    for(; tul.y != tlr.y; ++tul.y, ++dupperleft.y)
+    {
+        typename TmpTraverser::row_iterator tr = tul.rowIterator();
+        typename TmpTraverser::row_iterator trend = tr + w;
+        typename DestIterator::row_iterator d = dupperleft.rowIterator();
+        if(noLaplacian)
+        {
+            for(; tr != trend; ++tr, ++d)
+            {
+                TmpType v = detail::RequiresExplicitCast<TmpType>::cast(0.5*sq((*tr)[0]-(*tr)[2]) + 2.0*sq((*tr)[1]));
+                dest.setComponent(v, d, 0);
+                dest.setComponent(0, d, 1);
+                dest.setComponent(v, d, 2);
+            }
+        }
+        else
+        {
+            for(; tr != trend; ++tr, ++d)
+            {
+                dest.setComponent(sq((*tr)[0]) + sq((*tr)[1]), d, 0);
+                dest.setComponent(-(*tr)[1] * ((*tr)[0] + (*tr)[2]), d, 1);
+                dest.setComponent(sq((*tr)[1]) + sq((*tr)[2]), d, 2);
+            }
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+oddPolarFilters(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
+                DestIterator dupperleft, DestAccessor dest,
+                double scale, bool addResult)
+{
+    vigra_precondition(dest.size(dupperleft) == 3,
+                       "oddPolarFilters(): image for odd output must have 3 bands.");
+
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+
+    typedef typename
+       NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    typedef BasicImage<TinyVector<TmpType, 4> > TmpImage;
+    typedef typename TmpImage::traverser TmpTraverser;
+    TmpImage t(w, h);
+
+    detail::KernelArray k1;
+    detail::initGaussianPolarFilters1(scale, k1);
+
+    // calculate filter responses for odd filters
+    VectorElementAccessor<typename TmpImage::Accessor> tmpBand(0, t.accessor());
+    convolveImage(srcIterRange(supperleft, slowerright, src),
+                  destImage(t, tmpBand), k1[3], k1[0]);
+    tmpBand.setIndex(1);
+    convolveImage(srcIterRange(supperleft, slowerright, src),
+                  destImage(t, tmpBand), k1[2], k1[1]);
+    tmpBand.setIndex(2);
+    convolveImage(srcIterRange(supperleft, slowerright, src),
+                  destImage(t, tmpBand), k1[1], k1[2]);
+    tmpBand.setIndex(3);
+    convolveImage(srcIterRange(supperleft, slowerright, src),
+                  destImage(t, tmpBand), k1[0], k1[3]);
+
+    // create odd tensor from filter responses
+    TmpTraverser tul(t.upperLeft());
+    TmpTraverser tlr(t.lowerRight());
+    for(; tul.y != tlr.y; ++tul.y, ++dupperleft.y)
+    {
+        typename TmpTraverser::row_iterator tr = tul.rowIterator();
+        typename TmpTraverser::row_iterator trend = tr + w;
+        typename DestIterator::row_iterator d = dupperleft.rowIterator();
+        if(addResult)
+        {
+            for(; tr != trend; ++tr, ++d)
+            {
+                TmpType d0 = (*tr)[0] + (*tr)[2];
+                TmpType d1 = -(*tr)[1] - (*tr)[3];
+
+                dest.setComponent(dest.getComponent(d, 0) + sq(d0), d, 0);
+                dest.setComponent(dest.getComponent(d, 1) + d0 * d1, d, 1);
+                dest.setComponent(dest.getComponent(d, 2) + sq(d1), d, 2);
+            }
+        }
+        else
+        {
+            for(; tr != trend; ++tr, ++d)
+            {
+                TmpType d0 = (*tr)[0] + (*tr)[2];
+                TmpType d1 = -(*tr)[1] - (*tr)[3];
+
+                dest.setComponent(sq(d0), d, 0);
+                dest.setComponent(d0 * d1, d, 1);
+                dest.setComponent(sq(d1), d, 2);
+            }
+        }
+    }
+}
+
+} // namespace detail
+
+/** \addtogroup CommonConvolutionFilters Common Filters
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                   rieszTransformOfLOG                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate Riesz transforms of the Laplacian of Gaussian.
+
+    The Riesz transforms of the Laplacian of Gaussian have the following transfer
+    functions (defined in a polar coordinate representation of the frequency domain):
+
+    \f[
+        F_{\sigma}(r, \phi)=(i \cos \phi)^n (i \sin \phi)^m r^2 e^{-r^2 \sigma^2 / 2}
+    \f]
+
+    where <i>n</i> = <tt>xorder</tt> and <i>m</i> = <tt>yorder</tt> determine th e
+    order of the transform, and <tt>sigma > 0</tt> is the scale of the Laplacian
+    of Gaussian. This function computes a good spatial domain approximation of
+    these transforms for <tt>xorder + yorder <= 2</tt>. The filter responses may be used
+    to calculate the monogenic signal or the boundary tensor.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        rieszTransformOfLOG(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            double scale, unsigned int xorder, unsigned int yorder);
+    }
+    \endcode
+
+    \deprecatedAPI{rieszTransformOfLOG}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                class DestIterator, class DestAccessor>
+        void rieszTransformOfLOG(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
+                                 DestIterator dupperleft, DestAccessor dest,
+                                 double scale, unsigned int xorder, unsigned int yorder);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                class DestIterator, class DestAccessor>
+        void rieszTransformOfLOG(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                 pair<DestIterator, DestAccessor> dest,
+                                 double scale, unsigned int xorder, unsigned int yorder);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/boundarytensor.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArrayView<2, double> impulse(17,17), res(17, 17);
+    impulse(8,8) = 1.0;
+
+    // calculate the impulse response of the first order Riesz transform in x-direction
+    rieszTransformOfLOG(impulse, res, 2.0, 1, 0);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void rieszTransformOfLOG)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void rieszTransformOfLOG(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
+                         DestIterator dupperleft, DestAccessor dest,
+                         double scale, unsigned int xorder, unsigned int yorder)
+{
+    unsigned int order = xorder + yorder;
+
+    vigra_precondition(order <= 2,
+            "rieszTransformOfLOG(): can only compute Riesz transforms up to order 2.");
+    vigra_precondition(scale > 0.0,
+            "rieszTransformOfLOG(): scale must be positive.");
+
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    typedef BasicImage<TmpType> TmpImage;
+
+    switch(order)
+    {
+        case 0:
+        {
+            detail::KernelArray k2;
+            detail::initGaussianPolarFilters2(scale, k2);
+
+            TmpImage t1(w, h), t2(w, h);
+
+            convolveImage(srcIterRange(supperleft, slowerright, src),
+                          destImage(t1), k2[2], k2[0]);
+            convolveImage(srcIterRange(supperleft, slowerright, src),
+                          destImage(t2), k2[0], k2[2]);
+            combineTwoImages(srcImageRange(t1), srcImage(t2),
+                             destIter(dupperleft, dest), std::plus<TmpType>());
+            break;
+        }
+        case 1:
+        {
+            detail::KernelArray k1;
+            detail::initGaussianPolarFilters1(scale, k1);
+
+            TmpImage t1(w, h), t2(w, h);
+
+            if(xorder == 1)
+            {
+                convolveImage(srcIterRange(supperleft, slowerright, src),
+                            destImage(t1), k1[3], k1[0]);
+                convolveImage(srcIterRange(supperleft, slowerright, src),
+                            destImage(t2), k1[1], k1[2]);
+            }
+            else
+            {
+                convolveImage(srcIterRange(supperleft, slowerright, src),
+                            destImage(t1), k1[0], k1[3]);
+                convolveImage(srcIterRange(supperleft, slowerright, src),
+                            destImage(t2), k1[2], k1[1]);
+            }
+            combineTwoImages(srcImageRange(t1), srcImage(t2),
+                             destIter(dupperleft, dest), std::plus<TmpType>());
+            break;
+        }
+        case 2:
+        {
+            detail::KernelArray k2;
+            detail::initGaussianPolarFilters2(scale, k2);
+
+            convolveImage(srcIterRange(supperleft, slowerright, src),
+                          destIter(dupperleft, dest), k2[xorder], k2[yorder]);
+            break;
+        }
+        /* for test purposes only: compute 3rd order polar filters */
+        case 3:
+        {
+            detail::KernelArray k3;
+            detail::initGaussianPolarFilters3(scale, k3);
+
+            TmpImage t1(w, h), t2(w, h);
+
+            if(xorder == 3)
+            {
+                convolveImage(srcIterRange(supperleft, slowerright, src),
+                            destImage(t1), k3[3], k3[0]);
+                convolveImage(srcIterRange(supperleft, slowerright, src),
+                            destImage(t2), k3[1], k3[2]);
+            }
+            else
+            {
+                convolveImage(srcIterRange(supperleft, slowerright, src),
+                            destImage(t1), k3[0], k3[3]);
+                convolveImage(srcIterRange(supperleft, slowerright, src),
+                            destImage(t2), k3[2], k3[1]);
+            }
+            combineTwoImages(srcImageRange(t1), srcImage(t2),
+                             destIter(dupperleft, dest), std::minus<TmpType>());
+            break;
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline
+void rieszTransformOfLOG(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                         pair<DestIterator, DestAccessor> dest,
+                         double scale, unsigned int xorder, unsigned int yorder)
+{
+    rieszTransformOfLOG(src.first, src.second, src.third, dest.first, dest.second,
+                        scale, xorder, yorder);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+rieszTransformOfLOG(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest,
+                    double scale, unsigned int xorder, unsigned int yorder)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "rieszTransformOfLOG(): shape mismatch between input and output.");
+    rieszTransformOfLOG(srcImageRange(src), destImage(dest),
+                        scale, xorder, yorder);
+}
+
+//@}
+
+/** \addtogroup TensorImaging Tensor Image Processing
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                     boundaryTensor                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the boundary tensor for a scalar valued image.
+
+    These functions calculate a spatial domain approximation of
+    the boundary tensor as described in
+
+    U. Köthe: <a href="http://hci.iwr.uni-heidelberg.de/people/ukoethe/papers/index.php#cite_polarfilters">
+    <i>"Integrated Edge and Junction Detection with the Boundary Tensor"</i></a>,
+     in: ICCV 03, Proc. of 9th Intl. Conf. on Computer Vision, Nice 2003, vol. 1,
+     pp. 424-431, Los Alamitos: IEEE Computer Society, 2003
+
+    with the Laplacian of Gaussian as the underlying bandpass filter (see
+    \ref rieszTransformOfLOG()). The output image must have 3 bands which will hold the
+    tensor components in the order t11, t12 (== t21), t22. The function
+    \ref boundaryTensor1() with the same interface implements a variant of the
+    boundary tensor where the 0th-order Riesz transform has been dropped, so that the
+    tensor is no longer sensitive to blobs.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        boundaryTensor(MultiArrayView<2, T1, S1> const & src,
+                       MultiArrayView<2, T2, S2> dest,
+                       double scale);
+    }
+    \endcode
+
+    \deprecatedAPI{boundaryTensor}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void boundaryTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
+                            DestIterator dupperleft, DestAccessor dest,
+                            double scale);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void boundaryTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<DestIterator, DestAccessor> dest,
+                            double scale);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/boundarytensor.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float>               img(w,h);
+    MultiArray<2, TinyVector<float, 3> bt(w,h);
+    ...
+    boundaryTensor(img, bt, 2.0);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void boundaryTensor)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void boundaryTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
+                    DestIterator dupperleft, DestAccessor dest,
+                    double scale)
+{
+    vigra_precondition(dest.size(dupperleft) == 3,
+                       "boundaryTensor(): image for even output must have 3 bands.");
+    vigra_precondition(scale > 0.0,
+                       "boundaryTensor(): scale must be positive.");
+
+    detail::evenPolarFilters(supperleft, slowerright, src,
+                             dupperleft, dest, scale, false);
+    detail::oddPolarFilters(supperleft, slowerright, src,
+                             dupperleft, dest, scale, true);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline
+void boundaryTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    pair<DestIterator, DestAccessor> dest,
+                    double scale)
+{
+    boundaryTensor(src.first, src.second, src.third,
+                   dest.first, dest.second, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+boundaryTensor(MultiArrayView<2, T1, S1> const & src,
+               MultiArrayView<2, T2, S2> dest,
+               double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "boundaryTensor(): shape mismatch between input and output.");
+    boundaryTensor(srcImageRange(src),
+                   destImage(dest), scale);
+}
+
+/** \brief Boundary tensor variant.
+
+    This function implements a variant of the boundary tensor where the 
+    0th-order Riesz transform has been dropped, so that the tensor is no 
+    longer sensitive to blobs. See \ref boundaryTensor() for more detailed 
+    documentation.
+
+    <b> Declarations:</b>
+
+    <b>\#include</b> \<vigra/boundarytensor.hxx\><br/>
+    Namespace: vigra
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        boundaryTensor1(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, T2, S2> dest,
+                        double scale);
+    }
+    \endcode
+
+    \deprecatedAPI{boundaryTensor1}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void boundaryTensor1(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
+                             DestIterator dupperleft, DestAccessor dest,
+                             double scale);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void boundaryTensor1(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                             pair<DestIterator, DestAccessor> dest,
+                             double scale);
+    }
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void boundaryTensor1)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void boundaryTensor1(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
+                    DestIterator dupperleft, DestAccessor dest,
+                    double scale)
+{
+    vigra_precondition(dest.size(dupperleft) == 3,
+                       "boundaryTensor1(): image for even output must have 3 bands.");
+    vigra_precondition(scale > 0.0,
+                       "boundaryTensor1(): scale must be positive.");
+
+    detail::evenPolarFilters(supperleft, slowerright, src,
+                             dupperleft, dest, scale, true);
+    detail::oddPolarFilters(supperleft, slowerright, src,
+                             dupperleft, dest, scale, true);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline
+void boundaryTensor1(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                     pair<DestIterator, DestAccessor> dest,
+                     double scale)
+{
+    boundaryTensor1(src.first, src.second, src.third,
+                    dest.first, dest.second, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+boundaryTensor1(MultiArrayView<2, T1, S1> const & src,
+                MultiArrayView<2, T2, S2> dest,
+                double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "boundaryTensor1(): shape mismatch between input and output.");
+    boundaryTensor1(srcImageRange(src),
+                    destImage(dest), scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*                    boundaryTensor3                   */
+/*                                                      */
+/********************************************************/
+
+/*  Add 3rd order Riesz transform to boundary tensor
+    ??? Does not work -- bug or too coarse approximation for 3rd order ???
+*/
+template <class SrcIterator, class SrcAccessor,
+          class DestIteratorEven, class DestAccessorEven,
+          class DestIteratorOdd, class DestAccessorOdd>
+void boundaryTensor3(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor sa,
+                     DestIteratorEven dupperleft_even, DestAccessorEven even,
+                     DestIteratorOdd dupperleft_odd, DestAccessorOdd odd,
+                     double scale)
+{
+    vigra_precondition(even.size(dupperleft_even) == 3,
+                       "boundaryTensor3(): image for even output must have 3 bands.");
+    vigra_precondition(odd.size(dupperleft_odd) == 3,
+                       "boundaryTensor3(): image for odd output must have 3 bands.");
+
+    detail::evenPolarFilters(supperleft, slowerright, sa,
+                             dupperleft_even, even, scale, false);
+
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+
+    typedef typename
+       NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    typedef BasicImage<TinyVector<TmpType, 4> > TmpImage;
+    TmpImage t1(w, h), t2(w, h);
+
+    detail::KernelArray k1, k3;
+    detail::initGaussianPolarFilters1(scale, k1);
+    detail::initGaussianPolarFilters3(scale, k3);
+
+    // calculate filter responses for odd filters
+    VectorElementAccessor<typename TmpImage::Accessor> tmpBand(0, t1.accessor());
+    convolveImage(srcIterRange(supperleft, slowerright, sa),
+                  destImage(t1, tmpBand), k1[3], k1[0]);
+    tmpBand.setIndex(1);
+    convolveImage(srcIterRange(supperleft, slowerright, sa),
+                  destImage(t1, tmpBand), k1[1], k1[2]);
+    tmpBand.setIndex(2);
+    convolveImage(srcIterRange(supperleft, slowerright, sa),
+                  destImage(t1, tmpBand), k3[3], k3[0]);
+    tmpBand.setIndex(3);
+    convolveImage(srcIterRange(supperleft, slowerright, sa),
+                  destImage(t1, tmpBand), k3[1], k3[2]);
+
+    tmpBand.setIndex(0);
+    convolveImage(srcIterRange(supperleft, slowerright, sa),
+                  destImage(t2, tmpBand), k1[0], k1[3]);
+    tmpBand.setIndex(1);
+    convolveImage(srcIterRange(supperleft, slowerright, sa),
+                  destImage(t2, tmpBand), k1[2], k1[1]);
+    tmpBand.setIndex(2);
+    convolveImage(srcIterRange(supperleft, slowerright, sa),
+                  destImage(t2, tmpBand), k3[0], k3[3]);
+    tmpBand.setIndex(3);
+    convolveImage(srcIterRange(supperleft, slowerright, sa),
+                  destImage(t2, tmpBand), k3[2], k3[1]);
+
+    // create odd tensor from filter responses
+    typedef typename TmpImage::traverser TmpTraverser;
+    TmpTraverser tul1(t1.upperLeft());
+    TmpTraverser tlr1(t1.lowerRight());
+    TmpTraverser tul2(t2.upperLeft());
+    for(; tul1.y != tlr1.y; ++tul1.y, ++tul2.y, ++dupperleft_odd.y)
+    {
+        typename TmpTraverser::row_iterator tr1 = tul1.rowIterator();
+        typename TmpTraverser::row_iterator trend1 = tr1 + w;
+        typename TmpTraverser::row_iterator tr2 = tul2.rowIterator();
+        typename DestIteratorOdd::row_iterator o = dupperleft_odd.rowIterator();
+        for(; tr1 != trend1; ++tr1, ++tr2, ++o)
+        {
+            TmpType d11 =  (*tr1)[0] + (*tr1)[2];
+            TmpType d12 = -(*tr1)[1] - (*tr1)[3];
+            TmpType d31 =  (*tr2)[0] - (*tr2)[2];
+            TmpType d32 =  (*tr2)[1] - (*tr2)[3];
+            TmpType d111 = 0.75 * d11 + 0.25 * d31;
+            TmpType d112 = 0.25 * (d12 + d32);
+            TmpType d122 = 0.25 * (d11 - d31);
+            TmpType d222 = 0.75 * d12 - 0.25 * d32;
+            TmpType d2 = sq(d112);
+            TmpType d3 = sq(d122);
+
+            odd.setComponent(0.25 * (sq(d111) + 2.0*d2 + d3), o, 0);
+            odd.setComponent(0.25 * (d111*d112 + 2.0*d112*d122 + d122*d222), o, 1);
+            odd.setComponent(0.25 * (d2 + 2.0*d3 + sq(d222)), o, 2);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIteratorEven, class DestAccessorEven,
+          class DestIteratorOdd, class DestAccessorOdd>
+inline
+void boundaryTensor3(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                     pair<DestIteratorEven, DestAccessorEven> even,
+                     pair<DestIteratorOdd, DestAccessorOdd> odd,
+                     double scale)
+{
+    boundaryTensor3(src.first, src.second, src.third,
+                    even.first, even.second, odd.first, odd.second, scale);
+}
+
+template <class T1, class S1,
+          class T2E, class S2Even,
+          class T2O, class S2Odd>
+inline
+void boundaryTensor3(MultiArrayView<2, T1, S1> const & src,
+                     MultiArrayView<2, T2E, S2Even> even,
+                     MultiArrayView<2, T2O, S2Odd> odd,
+                     double scale)
+{
+    vigra_precondition(src.shape() == even.shape() && src.shape() == odd.shape(),
+        "boundaryTensor3(): shape mismatch between input and output.");
+    boundaryTensor3(srcImageRange(src),
+                    destImage(even), destImage(odd), scale);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_BOUNDARYTENSOR_HXX
diff --git a/include/vigra/box.hxx b/include/vigra/box.hxx
new file mode 100644
index 0000000..2faa609
--- /dev/null
+++ b/include/vigra/box.hxx
@@ -0,0 +1,545 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2009-2010 by Ullrich Koethe and Hans Meine             */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_BOX_HXX
+#define VIGRA_BOX_HXX
+
+#include "metaprogramming.hxx"
+#include "numerictraits.hxx"
+#include "tinyvector.hxx"
+
+namespace vigra {
+
+namespace detail {
+
+// RangePolicy used for floating point coordinate types
+template<class VALUETYPE>
+struct EndInsidePolicy
+{
+    static inline bool isEmptyRange(VALUETYPE b, VALUETYPE e)
+    {
+        return e < b; // <=
+    }
+
+    static inline VALUETYPE pointEnd(VALUETYPE p)
+    {
+        return p; // +1
+    }
+};
+
+// RangePolicy used for integer coordinate types
+template<class VALUETYPE>
+struct EndOutsidePolicy
+{
+    static inline bool isEmptyRange(VALUETYPE b, VALUETYPE e)
+    {
+        return e <= b;
+    }
+
+    static inline VALUETYPE pointEnd(VALUETYPE p)
+    {
+        return p+1;
+    }
+};
+
+} // namespace vigra::detail
+
+/** \addtogroup RangesAndPoints */
+//@{
+   /** \brief Represent an n-dimensional box as a (begin, end) pair.
+     * Depending on the value type, end() is considered to be
+     * outside the box (as in the STL, for integer types), or
+     * inside (for floating point types).  size() will always be
+     * end() - begin().
+     */
+template<class VALUETYPE, unsigned int DIMENSION>
+class Box
+{
+  public:
+        /** STL-compatible definition of coordinate valuetype
+         */
+    typedef VALUETYPE value_type;
+
+        /** Promoted coordinate valuetype, used for volume()
+         */
+    typedef typename NumericTraits<VALUETYPE>::Promote VolumeType;
+
+        /** Vector type used for begin() and end()
+         */
+    typedef TinyVector<VALUETYPE, DIMENSION> Vector;
+
+    enum { Dimension = DIMENSION };
+
+  protected:
+    Vector begin_, end_;
+
+        /** Range policy (EndInsidePolicy/EndOutsidePolicy, depending on valuetype)
+         */
+    typedef typename If<typename NumericTraits<VALUETYPE>::isIntegral,
+                        detail::EndOutsidePolicy<VALUETYPE>,
+                        detail::EndInsidePolicy<VALUETYPE> >::type RangePolicy;
+
+  public:
+        /** Construct an empty box (isEmpty() will return true).
+         * (Internally, this will initialize all dimensions with the
+         * empty range [1..0].)
+         */
+    Box()
+    : begin_(NumericTraits<Vector>::one())
+    {}
+
+        /** Construct a box representing the given range.  Depending
+         * on the value type, end() is considered to be outside the
+         * box (as in the STL, for integer types), or inside (for
+         * floating point types).
+         */
+    Box(Vector const &begin, Vector const &end)
+    : begin_(begin), end_(end)
+    {}
+
+        /** Construct a box of given size at the origin (i.e. end() ==
+         * size()).
+         */
+    explicit Box(Vector const &size)
+    : end_(size)
+    {}
+
+        /** Get begin vector (i.e. smallest coordinates for each
+         * dimension).  This is the first point (scan-order wise)
+         * which is considered to be "in" the box.
+         */
+    Vector const & begin() const
+    {
+        return begin_;
+    }
+
+        /** Access begin vector (i.e. smallest coordinates for each
+         * dimension).  This is the first point (scan-order wise)
+         * which is considered to be "in" the box.
+         */
+    Vector & begin()
+    {
+        return begin_;
+    }
+
+        /** Get end vector (i.e. coordinates higher than begin() in
+         * each dimension for non-empty boxes).  This is begin() +
+         * size(), and depending on the valuetype (float/int), this is
+         * the last point within or the first point outside the box,
+         * respectively.
+         */
+    Vector const & end() const
+    {
+        return end_;
+    }
+
+        /** Access end vector (i.e. coordinates higher than begin() in
+         * each dimension for non-empty boxes).  This is begin() +
+         * size(), and depending on the valuetype (float/int), this is
+         * the last point within or the first point outside the box,
+         * respectively.
+         */
+    Vector & end()
+    {
+        return end_;
+    }
+
+        /** Change begin() without changing end(), changing size()
+         * accordingly.
+         */
+    void setBegin(Vector const &begin)
+    {
+        begin_ = begin;
+    }
+
+        /** Change end() without changing begin(), which will change
+         * the size() most probably.
+         */
+    void setEnd(Vector const &end)
+    {
+        end_ = end;
+    }
+
+        /** Move the whole box so that the given point will be
+         * begin() afterwards.
+         */
+    void moveTo(Vector const &newBegin)
+    {
+        end_ += newBegin - begin_;
+        begin_ = newBegin;
+    }
+
+        /** Move the whole box by the given offset.
+         * (Equivalent to operator+=)
+         */
+    void moveBy(Vector const &offset)
+    {
+        begin_ += offset;
+        end_ += offset;
+    }
+
+        /** Determine and return the area of this box. That is,
+         * if this rect isEmpty(), returns zero, otherwise returns the
+         * product of the extents in each dimension.
+         */
+    VolumeType volume() const
+    {
+        if(isEmpty())
+            return 0;
+
+        VolumeType result(end_[0] - begin_[0]);
+        for(unsigned int i = 1; i < DIMENSION; ++i)
+            result *= end_[i] - begin_[i];
+        return result;
+    }
+
+        /** Determine and return the size of this box. The size
+         * might be zero or even negative in one or more dimensions,
+         * and if so, isEmpty() will return true.
+         */
+    Vector size() const
+    {
+        return end_ - begin_;
+    }
+
+        /** Resize this box to the given extents. This will
+         * change end() only.
+         */
+    void setSize(Vector const &size)
+    {
+        end_ = begin_ + size;
+    }
+
+        /** Increase the size of the box by the given
+         * offset. This will move end() only. (If any of offset's
+         * components is negative, the box will get smaller
+         * accordingly.)
+         */
+    void addSize(Vector const &offset)
+    {
+        end_ += offset;
+    }
+
+        /** Adds a border of the given width around the box. That
+         * means, begin()'s components are moved by -borderWidth
+         * and end()'s by borderWidth. (If borderWidth is
+         * negative, the box will get smaller accordingly.)
+         */
+    void addBorder(VALUETYPE borderWidth)
+    {
+        for(unsigned int i = 0; i < DIMENSION; ++i)
+        {
+            begin_[i] -= borderWidth;
+            end_[i]   += borderWidth;
+        }
+    }
+
+        /// equality check
+    bool operator==(Box const &r) const
+    {
+        return (begin_ == r.begin_) && (end_ == r.end_);
+    }
+
+        /// inequality check
+    bool operator!=(Box const &r) const
+    {
+        return (begin_ != r.begin_) || (end_ != r.end_);
+    }
+
+        /** Return whether this box is considered empty. It is
+         * non-empty if all end() coordinates are greater than (or
+         * equal, for floating point valuetypes) the corresponding
+         * begin() coordinates. Uniting an empty box with something
+         * will return the bounding box of the 'something', and
+         * intersecting any box with an empty box will again yield an
+         * empty box.
+         */
+    bool isEmpty() const
+    {
+        for(unsigned int i = 0; i < DIMENSION; ++i)
+            if(RangePolicy::isEmptyRange(begin_[i], end_[i]))
+                return true;
+        return false;
+    }
+
+        /** Return whether this box contains the given point.
+         * That is, if the point lies within the range [begin, end] in
+         * each dimension (excluding end() itself for integer valuetypes).
+         */
+    bool contains(Vector const &p) const
+    {
+        for(unsigned int i = 0; i < DIMENSION; ++i)
+            if((p[i] < begin_[i]) ||
+               RangePolicy::isEmptyRange(p[i], end_[i]))
+                return false;
+        return true;
+    }
+
+        /** Return whether this box contains the given
+         * one. <tt>r1.contains(r2)</tt> returns the same as
+         * <tt>r1 == (r1|r2)</tt> (but is of course more
+         * efficient). That also means, a box (even an empty one!)
+         * contains() any empty box.
+         */
+    bool contains(Box const &r) const
+    {
+        if(r.isEmpty())
+            return true;
+        if(!contains(r.begin_))
+            return false;
+        for(unsigned int i = 0; i < DIMENSION; ++i)
+            if(r.end_[i] > end_[i])
+                return false;
+        return true;
+    }
+
+        /** Return whether this box overlaps with the given
+         * one. <tt>r1.intersects(r2)</tt> returns the same as
+         * <tt>!(r1&r2).isEmpty()</tt> (but is of course much more
+         * efficient).
+         */
+    bool intersects(Box const &r) const
+    {
+        if(r.isEmpty() || isEmpty())
+            return false;
+        for(unsigned int i = 0; i < DIMENSION; ++i)
+            if(RangePolicy::isEmptyRange(r.begin_[i], end_[i]) ||
+               RangePolicy::isEmptyRange(begin_[i], r.end_[i]))
+                return false;
+        return true;
+    }
+
+        /** Modifies this box by including the given point.
+         * The result will be the bounding box of the box and the
+         * point.  If isEmpty() returns true on the original box, the
+         * union will be a box containing only the given point.
+         */
+    Box &operator|=(Vector const &p)
+    {
+        if(isEmpty())
+        {
+            begin_ = p;
+            for(unsigned int i = 0; i < DIMENSION; ++i)
+                end_[i] = RangePolicy::pointEnd(p[i]);
+        }
+        else
+        {
+            for(unsigned int i = 0; i < DIMENSION; ++i)
+            {
+                if(p[i] < begin_[i])
+                    begin_[i] = p[i];
+                if(RangePolicy::isEmptyRange(p[i], end_[i]))
+                    end_[i] = RangePolicy::pointEnd(p[i]);
+            }
+        }
+        return *this;
+    }
+
+        /** Returns the union of this box and the given point.
+         * The result will be the bounding box of the box and the
+         * point.  If isEmpty() returns true on the original box, the
+         * union will be a box containing only the given point.
+         */
+    Box operator|(Vector const &p) const
+    {
+        Box result(*this);
+        result |= p;
+        return result;
+    }
+
+        /** Modifies this box by uniting it with the given one.
+         * The result will be the bounding box of both boxs. If one of
+         * the boxes isEmpty(), the union will be the other one.
+         */
+    Box &operator|=(Box const &r)
+    {
+        if(r.isEmpty())
+            return *this;
+        if(isEmpty())
+            return this->operator=(r);
+
+        for(unsigned int i = 0; i < DIMENSION; ++i)
+        {
+            if(r.begin_[i] < begin_[i])
+                begin_[i] = r.begin_[i];
+            if(end_[i] < r.end_[i])
+                end_[i] = r.end_[i];
+        }
+        return *this;
+    }
+
+        /** Returns the union of this box and the given one.
+         * The result will be the bounding box of both boxs. If one of
+         * the boxes isEmpty(), the union will be the other one.
+         */
+    Box operator|(Box const &r) const
+    {
+        Box result(*this);
+        result |= r;
+        return result;
+    }
+
+        /** Modifies this box by intersecting it with the given one.
+         * The result will be the maximal box contained in both
+         * original ones. Intersecting with an empty box will yield
+         * again an empty box.
+         */
+    Box &operator&=(Box const &r)
+    {
+        if(isEmpty())
+            return *this;
+        if(r.isEmpty())
+            return this->operator=(r);
+
+        for(unsigned int i = 0; i < DIMENSION; ++i)
+        {
+            if(begin_[i] < r.begin_[i])
+                begin_[i] = r.begin_[i];
+            if(r.end_[i] < end_[i])
+                end_[i] = r.end_[i];
+        }
+        return *this;
+    }
+
+        /** Intersects this box with the given one.
+         * The result will be the maximal box contained in both
+         * original ones.  Intersecting with an empty box will yield
+         * again an empty box.
+         */
+    Box operator&(Box const &r) const
+    {
+        Box result(*this);
+        result &= r;
+        return result;
+    }
+
+        /**
+         * Scale box by scalar multiply-assignment.  The same scalar
+         * multiply-assignment operation will be performed on both
+         * begin() and end().
+         */
+    Box &operator*=(double scale)
+    {
+        begin_ *= scale;
+        end_   *= scale;
+        return *this;
+    }
+
+        /**
+         * Return box scaled by given factor.  The same scalar
+         * multiplication will be performed on both begin() and end().
+         */
+    Box operator*(double scale)
+    {
+        Box result(*this);
+        result *= scale;
+        return result;
+    }
+
+        /**
+         * Scale box by scalar divide-assignment.  The same scalar
+         * divide-assignment operation will be performed on both
+         * begin() and end().
+         */
+    Box &operator/=(double scale)
+    {
+        begin_ /= scale;
+        end_   /= scale;
+        return *this;
+    }
+
+        /**
+         * Return box scaled by inverse of given factor.  The same scalar
+         * division will be performed on both begin() and end().
+         */
+    Box operator/(double scale)
+    {
+        Box result(*this);
+        result /= scale;
+        return result;
+    }
+
+        /**
+         * Translate box by vector addition-assignment.  The same vector
+         * addition-assignment operation will be performed on both
+         * begin() and end().
+         */
+    Box &operator+=(const Vector &offset)
+    {
+        begin_ += offset;
+        end_   += offset;
+        return *this;
+    }
+
+        /**
+         * Translate box by vector addition.  The same vector addition
+         * operation will be performed on both begin() and end().
+         */
+    Box operator+(const Vector &offset)
+    {
+        Box result(*this);
+        result += offset;
+        return result;
+    }
+
+        /**
+         * Translate box by vector subtract-assignment.  The same vector
+         * subtract-assignment operation will be performed on both
+         * begin() and end().
+         */
+    Box &operator-=(const Vector &offset)
+    {
+        begin_ -= offset;
+        end_   -= offset;
+        return *this;
+    }
+
+        /**
+         * Translate box by vector subtract.  The same vector subtract
+         * operation will be performed on both begin() and end().
+         */
+    Box operator-(const Vector &offset)
+    {
+        Box result(*this);
+        result -= offset;
+        return result;
+    }
+};
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_BOX_HXX
diff --git a/include/vigra/bucket_queue.hxx b/include/vigra/bucket_queue.hxx
new file mode 100644
index 0000000..dc9192c
--- /dev/null
+++ b/include/vigra/bucket_queue.hxx
@@ -0,0 +1,404 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2010-2011 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_BUCKET_QUEUE_HXX
+#define VIGRA_BUCKET_QUEUE_HXX
+
+#include "config.hxx"
+#include "error.hxx"
+#include "array_vector.hxx"
+#include <queue>
+
+namespace vigra {
+
+/** \brief Priority queue implemented using bucket sort.
+
+    This template implements functionality similar to <tt><a href="http://www.sgi.com/tech/stl/priority_queue.html">std::priority_queue</a></tt>,
+    but uses a more efficient algorithm based on bucket sort. It can be used
+    when all priorities are positive integers in a given range (typically, 0...255).
+    By default, <tt>BucketQueue\<ValueType\></tt> sorts the elements in descending order,
+    i.e. like in <tt>std::priority_queue</tt> the largest element has highest priority.
+    An ascending queue can be specified as <tt>BucketQueue\<ValueType, true\></tt>.
+    Elements with equal priorities are returned in a first-in first-out fashion.
+    
+    The main difference to <tt>std::priority_queue</tt> is the function <tt>push</tt>
+    which explicitly takes the priority of the element to be added as a second argument.
+    This allows optimization of <tt>ValueType</tt>: since the bucket uniquely
+    determines an element's priority, there is no need for <tt>ValueType</tt> to
+    store redundant priority information. If compatibility to <tt>std::priority_queue</tt>
+    is more important, use \ref vigra::MappedBucketQueue.
+
+    <b>\#include</b> \<vigra/bucket_queue.hxx\><br>
+    Namespace: vigra
+*/
+template <class ValueType,
+          bool Ascending = false>  // std::priority_queue is descending
+class BucketQueue
+{
+    ArrayVector<std::queue<ValueType> > buckets_;
+    std::size_t size_;
+    std::ptrdiff_t top_;
+    
+  public:
+  
+    typedef ValueType value_type;
+    typedef ValueType & reference;
+    typedef ValueType const & const_reference;
+    typedef std::size_t size_type;
+    typedef std::ptrdiff_t priority_type;
+    
+        /** \brief Create bucket queue with \arg bucket_count entries.
+            Priorities must be integers in the range <tt>[0, ..., bucket_count-1]</tt>.
+        */
+    BucketQueue(size_type bucket_count = 256)
+    : buckets_(bucket_count),
+      size_(0), top_(0)
+    {}
+    
+        /** \brief Number of elements in this queue.
+        */
+    size_type size() const
+    {
+        return size_;
+    }
+    
+        /** \brief Queue contains no elements.
+             Equivalent to <tt>size() == 0</tt>.
+        */
+    bool empty() const
+    {
+        return size() == 0;
+    }
+    
+        /** \brief Maximum index (i.e. priority) allowed in this queue.
+             Equivalent to <tt>bucket_count - 1</tt>.
+        */
+    priority_type maxIndex() const
+    {
+        return (priority_type)buckets_.size() - 1;
+    }
+    
+        /** \brief Priority of the current top element.
+        */
+    priority_type topPriority() const
+    {
+        return top_;
+    }
+    
+        /** \brief The current top element.
+        */
+    const_reference top() const
+    {
+        
+        return buckets_[top_].front();
+    }
+
+        /** \brief Remove the current top element.
+        */
+    void pop()
+    {
+        --size_;
+        buckets_[top_].pop();
+        
+        while(top_ > 0 && buckets_[top_].size() == 0)
+            --top_;
+    }
+    
+        /** \brief Insert new element \arg v with given \arg priority.
+        */
+    void push(value_type const & v, priority_type priority)
+    {
+        ++size_;
+        buckets_[priority].push(v);
+        
+        if(priority > top_)
+            top_ = priority;
+    }
+};
+
+template <class ValueType> 
+class BucketQueue<ValueType, true> // ascending queue
+{
+    ArrayVector<std::queue<ValueType> > buckets_;
+    std::size_t size_;
+    std::ptrdiff_t top_;
+    
+  public:
+  
+    typedef ValueType value_type;
+    typedef ValueType & reference;
+    typedef ValueType const & const_reference;
+    typedef std::size_t size_type;
+    typedef std::ptrdiff_t priority_type;
+    
+    BucketQueue(size_type bucket_count = 256)
+    : buckets_(bucket_count),
+      size_(0), top_((priority_type)bucket_count)
+    {}
+    
+    size_type size() const
+    {
+        return size_;
+    }
+    
+    bool empty() const
+    {
+        return size() == 0;
+    }
+    
+    priority_type maxIndex() const
+    {
+        return (priority_type)buckets_.size() - 1;
+    }
+    
+    priority_type topPriority() const
+    {
+        return top_;
+    }
+    
+    const_reference top() const
+    {
+        
+        return buckets_[top_].front();
+    }
+
+    void pop()
+    {
+        --size_;
+        buckets_[top_].pop();
+        
+        while(top_ < (priority_type)buckets_.size() && buckets_[top_].size() == 0)
+            ++top_;
+    }
+    
+    void push(value_type const & v, priority_type priority)
+    {
+        ++size_;
+        buckets_[priority].push(v);
+        
+        if(priority < top_)
+            top_ = priority;
+    }
+};
+
+/** \brief Priority queue implemented using bucket sort (STL compatible).
+
+    This template is compatible to <tt><a href="http://www.sgi.com/tech/stl/priority_queue.html">std::priority_queue</a></tt>,
+    but uses a more efficient algorithm based on bucket sort. It us used
+    like \ref vigra::BucketQueue, but has an additional <tt>PriorityFunctor</tt>
+    which extracts the priority value of an element of type <tt>ValueType</tt>.
+    Thus functor is called within <tt>push</tt> so that it does not need an
+    extra argument.
+
+    <b>\#include</b> \<vigra/bucket_queue.hxx\><br>
+    Namespace: vigra
+*/
+template <class ValueType,
+          class PriorityFunctor, 
+          bool Ascending = false> 
+class MappedBucketQueue
+: public BucketQueue<ValueType, Ascending>
+{
+    PriorityFunctor get_priority_;
+    
+  public:
+
+    typedef BucketQueue<ValueType, Ascending> BaseType;
+    typedef typename BaseType::value_type value_type;
+    typedef typename BaseType::reference reference;
+    typedef typename BaseType::const_reference const_reference;
+    typedef typename BaseType::size_type size_type;
+    typedef typename BaseType::priority_type priority_type;
+    
+        /** \brief Create a queue with \arg bucket_count entries.
+            Priorities will be computed by the <tt>PriorityFunctor</tt>
+            given in \arg priority (i.e. <tt>priority(v)</tt> must result in an integer,
+            where <tt>v</tt> is an instance of <tt>ValueType</tt>).
+        */
+    MappedBucketQueue(unsigned int bucket_count = 256,
+                      PriorityFunctor const & priority = PriorityFunctor())
+    : BaseType(bucket_count),
+      get_priority_(priority)
+    {}
+    
+        /** \brief Insert new element \arg v.
+            Its priority is calculated by <tt>priority(v)</tt>,
+            where <tt>priority</tt> is an instance of the 
+            <tt>PriorityFunctor</tt> passed in the constructor.
+            If the priority is outside the range <tt>[0, ..., bucket_count-1]</tt>,
+            it is clamped to the range borders.
+        */
+    void push(value_type const & v)
+    {
+        priority_type index = get_priority_(v);
+        
+        // clamp index to the allowed range
+        if(index > BaseType::maxIndex())
+            index = BaseType::maxIndex();
+        else if (index < 0)
+            index = 0;
+        
+        BaseType::push(v, index);
+    }
+};
+
+/** \brief Heap-based priority queue compatible to BucketQueue.
+
+    This template is compatible to \ref vigra::BucketQueue, but accepts arbitrary priority
+    types. Internally, it uses a <tt>std::priority_queue</tt>, but implements an 
+    API where priorities and payload data are separate, like in \ref vigra::BucketQueue.
+
+    <b>\#include</b> \<vigra/bucket_queue.hxx\><br>
+    Namespace: vigra
+*/
+template <class ValueType,
+          class PriorityType,
+          bool Ascending = false>  // std::priority_queue is descending
+class PriorityQueue
+{
+    typedef std::pair<ValueType, PriorityType> ElementType;
+    
+    struct Compare
+    {
+        typename IfBool<Ascending, std::greater<PriorityType>, 
+                                   std::less<PriorityType> >::type cmp;
+        
+        bool operator()(ElementType const & l, ElementType const & r) const
+        {
+            return cmp(l.second, r.second);
+        }
+    };
+    
+    typedef std::priority_queue<ElementType, std::vector<ElementType>, Compare> Heap;
+    
+    Heap heap_;
+    
+  public:
+  
+    typedef ValueType value_type;
+    typedef ValueType & reference;
+    typedef ValueType const & const_reference;
+    typedef typename Heap::size_type size_type;
+    typedef PriorityType priority_type;
+    
+        /** \brief Create empty priority queue.
+        */
+    PriorityQueue()
+    : heap_()
+    {}
+    
+        /** \brief Number of elements in this queue.
+        */
+    size_type size() const
+    {
+        return heap_.size();
+    }
+    
+        /** \brief Queue contains no elements.
+             Equivalent to <tt>size() == 0</tt>.
+        */
+    bool empty() const
+    {
+        return size() == 0;
+    }
+    
+        /** \brief Maximum index (i.e. priority) allowed in this queue.
+             Equivalent to <tt>bucket_count - 1</tt>.
+        */
+    priority_type maxIndex() const
+    {
+        return NumericTraits<priority_type>::max();
+    }
+    
+        /** \brief Priority of the current top element.
+        */
+    priority_type topPriority() const
+    {
+        return heap_.top().second;
+    }
+    
+        /** \brief The current top element.
+        */
+    const_reference top() const
+    {
+        
+        return heap_.top().first;
+    }
+
+        /** \brief Remove the current top element.
+        */
+    void pop()
+    {
+        heap_.pop();
+    }
+    
+        /** \brief Insert new element \arg v with given \arg priority.
+        */
+    void push(value_type const & v, priority_type priority)
+    {
+        heap_.push(ElementType(v, priority));
+    }
+};
+
+template <class ValueType,
+          bool Ascending>
+class PriorityQueue<ValueType, unsigned char, Ascending>
+: public BucketQueue<ValueType, Ascending>
+{
+  public:
+    typedef BucketQueue<ValueType, Ascending> BaseType;
+    
+    PriorityQueue()
+    : BaseType(NumericTraits<unsigned char>::max()+1)
+    {}
+};
+
+template <class ValueType,
+          bool Ascending>
+class PriorityQueue<ValueType, unsigned short, Ascending>
+: public BucketQueue<ValueType, Ascending>
+{
+  public:
+    typedef BucketQueue<ValueType, Ascending> BaseType;
+    
+    PriorityQueue()
+    : BaseType(NumericTraits<unsigned short>::max()+1)
+    {}
+};
+
+} // namespace vigra
+
+#endif // VIGRA_BUCKET_QUEUE_HXX
diff --git a/include/vigra/cellconfigurations.hxx b/include/vigra/cellconfigurations.hxx
new file mode 100644
index 0000000..99a6556
--- /dev/null
+++ b/include/vigra/cellconfigurations.hxx
@@ -0,0 +1,1331 @@
+/************************************************************************/
+/*                                                                      */
+/*             Copyright 2009-2010 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_CELLCONFIGURATIONS_HXX
+#define VIGRA_CELLCONFIGURATIONS_HXX
+
+#include "cellimage.hxx"
+
+namespace vigra {
+
+namespace cellimage {
+
+static CellType cellConfigurations[] = {
+  /*     */
+  /*  #  */
+  /*     */
+CellTypeVertex, /* 0 */
+
+  /*     */
+  /*  ## */
+  /*     */
+CellTypeVertex, /* 1 */
+
+  /*   # */
+  /*  #  */
+  /*     */
+CellTypeVertex, /* 2 */
+
+  /*   # */
+  /*  ## */
+  /*     */
+CellTypeVertex, /* 3 */
+
+  /*  #  */
+  /*  #  */
+  /*     */
+CellTypeVertex, /* 4 */
+
+  /*  #  */
+  /*  ## */
+  /*     */
+CellTypeVertexOrLine, /* 5 */
+
+  /*  ## */
+  /*  #  */
+  /*     */
+CellTypeVertex, /* 6 */
+
+  /*  ## */
+  /*  ## */
+  /*     */
+CellTypeVertex, /* 7 */
+
+  /* #   */
+  /*  #  */
+  /*     */
+CellTypeVertex, /* 8 */
+
+  /* #   */
+  /*  ## */
+  /*     */
+CellTypeLine,   /* 9 */
+
+  /* # # */
+  /*  #  */
+  /*     */
+CellTypeLine,   /* 10 */
+
+  /* # # */
+  /*  ## */
+  /*     */
+CellTypeLine,   /* 11 */
+
+  /* ##  */
+  /*  #  */
+  /*     */
+CellTypeVertex, /* 12 */
+
+  /* ##  */
+  /*  ## */
+  /*     */
+CellTypeVertexOrLine, /* 13 */
+
+  /* ### */
+  /*  #  */
+  /*     */
+CellTypeVertex,  /* 14 */
+
+  /* ### */
+  /*  ## */
+  /*     */
+CellTypeError,  /* 15 */
+
+  /*     */
+  /* ##  */
+  /*     */
+CellTypeVertex, /* 16 */
+
+  /*     */
+  /* ### */
+  /*     */
+CellTypeLine,   /* 17 */
+
+  /*   # */
+  /* ##  */
+  /*     */
+CellTypeLine,   /* 18 */
+
+  /*   # */
+  /* ### */
+  /*     */
+CellTypeLine,   /* 19 */
+
+  /*  #  */
+  /* ##  */
+  /*     */
+CellTypeVertexOrLine, /* 20 */
+
+  /*  #  */
+  /* ### */
+  /*     */
+CellTypeVertex, /* 21 */
+
+  /*  ## */
+  /* ##  */
+  /*     */
+CellTypeVertexOrLine, /* 22 */
+
+  /*  ## */
+  /* ### */
+  /*     */
+CellTypeVertex, /* 23 */
+
+  /* #   */
+  /* ##  */
+  /*     */
+CellTypeVertex, /* 24 */
+
+  /* #   */
+  /* ### */
+  /*     */
+CellTypeLine,   /* 25 */
+
+  /* # # */
+  /* ##  */
+  /*     */
+CellTypeLine,   /* 26 */
+
+  /* # # */
+  /* ### */
+  /*     */
+CellTypeLine,   /* 27 */
+
+  /* ##  */
+  /* ##  */
+  /*     */
+CellTypeVertex, /* 28 */
+
+  /* ##  */
+  /* ### */
+  /*     */
+CellTypeVertex, /* 29 */
+
+  /* ### */
+  /* ##  */
+  /*     */
+CellTypeError,  /* 30 */
+
+  /* ### */
+  /* ### */
+  /*     */
+CellTypeVertex, /* 31 */
+
+  /*     */
+  /*  #  */
+  /* #   */
+CellTypeVertex, /* 32 */
+
+  /*     */
+  /*  ## */
+  /* #   */
+CellTypeLine,   /* 33 */
+
+  /*   # */
+  /*  #  */
+  /* #   */
+CellTypeLine,   /* 34 */
+
+  /*   # */
+  /*  ## */
+  /* #   */
+CellTypeLine,   /* 35 */
+
+  /*  #  */
+  /*  #  */
+  /* #   */
+CellTypeLine,   /* 36 */
+
+  /*  #  */
+  /*  ## */
+  /* #   */
+CellTypeVertex, /* 37 */
+
+  /*  ## */
+  /*  #  */
+  /* #   */
+CellTypeLine,   /* 38 */
+
+  /*  ## */
+  /*  ## */
+  /* #   */
+CellTypeVertex, /* 39 */
+
+  /* #   */
+  /*  #  */
+  /* #   */
+CellTypeLine,   /* 40 */
+
+  /* #   */
+  /*  ## */
+  /* #   */
+CellTypeVertex, /* 41 */
+
+  /* # # */
+  /*  #  */
+  /* #   */
+CellTypeVertex, /* 42 */
+
+  /* # # */
+  /*  ## */
+  /* #   */
+CellTypeVertex, /* 43 */
+
+  /* ##  */
+  /*  #  */
+  /* #   */
+CellTypeLine,   /* 44 */
+
+  /* ##  */
+  /*  ## */
+  /* #   */
+CellTypeVertex, /* 45 */
+
+  /* ### */
+  /*  #  */
+  /* #   */
+CellTypeLine,   /* 46 */
+
+  /* ### */
+  /*  ## */
+  /* #   */
+CellTypeVertex, /* 47 */
+
+  /*     */
+  /* ##  */
+  /* #   */
+CellTypeVertex, /* 48 */
+
+  /*     */
+  /* ### */
+  /* #   */
+CellTypeLine,   /* 49 */
+
+  /*   # */
+  /* ##  */
+  /* #   */
+CellTypeLine,   /* 50 */
+
+  /*   # */
+  /* ### */
+  /* #   */
+CellTypeLine,   /* 51 */
+
+  /*  #  */
+  /* ##  */
+  /* #   */
+CellTypeVertexOrLine, /* 52 */
+
+  /*  #  */
+  /* ### */
+  /* #   */
+CellTypeVertex, /* 53 */
+
+  /*  ## */
+  /* ##  */
+  /* #   */
+CellTypeErrorOrLine,  /* 54 */
+
+  /*  ## */
+  /* ### */
+  /* #   */
+CellTypeError,  /* 55 */
+
+  /* #   */
+  /* ##  */
+  /* #   */
+CellTypeVertex,  /* 56 */
+
+  /* #   */
+  /* ### */
+  /* #   */
+CellTypeLine,   /* 57 */
+
+  /* # # */
+  /* ##  */
+  /* #   */
+CellTypeLine,   /* 58 */
+
+  /* # # */
+  /* ### */
+  /* #   */
+CellTypeLine,   /* 59 */
+
+  /* ##  */
+  /* ##  */
+  /* #   */
+CellTypeError,  /* 60 */
+
+  /* ##  */
+  /* ### */
+  /* #   */
+CellTypeVertex, /* 61 */
+
+  /* ### */
+  /* ##  */
+  /* #   */
+CellTypeError,  /* 62 */
+
+  /* ### */
+  /* ### */
+  /* #   */
+CellTypeError,  /* 63 */
+
+  /*     */
+  /*  #  */
+  /*  #  */
+CellTypeVertex, /* 64 */
+
+  /*     */
+  /*  ## */
+  /*  #  */
+CellTypeVertexOrLine, /* 65 */
+
+  /*   # */
+  /*  #  */
+  /*  #  */
+CellTypeLine,   /* 66 */
+
+  /*   # */
+  /*  ## */
+  /*  #  */
+CellTypeVertexOrLine, /* 67 */
+
+  /*  #  */
+  /*  #  */
+  /*  #  */
+CellTypeLine,   /* 68 */
+
+  /*  #  */
+  /*  ## */
+  /*  #  */
+CellTypeVertex, /* 69 */
+
+  /*  ## */
+  /*  #  */
+  /*  #  */
+CellTypeLine,   /* 70 */
+
+  /*  ## */
+  /*  ## */
+  /*  #  */
+CellTypeVertex, /* 71 */
+
+  /* #   */
+  /*  #  */
+  /*  #  */
+CellTypeLine,   /* 72 */
+
+  /* #   */
+  /*  ## */
+  /*  #  */
+CellTypeVertex, /* 73 */
+
+  /* # # */
+  /*  #  */
+  /*  #  */
+CellTypeVertex, /* 74 */
+
+  /* # # */
+  /*  ## */
+  /*  #  */
+CellTypeVertex, /* 75 */
+
+  /* ##  */
+  /*  #  */
+  /*  #  */
+CellTypeLine,   /* 76 */
+
+  /* ##  */
+  /*  ## */
+  /*  #  */
+CellTypeVertex, /* 77 */
+
+  /* ### */
+  /*  #  */
+  /*  #  */
+CellTypeLine,   /* 78 */
+
+  /* ### */
+  /*  ## */
+  /*  #  */
+CellTypeVertex, /* 79 */
+
+  /*     */
+  /* ##  */
+  /*  #  */
+CellTypeVertexOrLine, /* 80 */
+
+  /*     */
+  /* ### */
+  /*  #  */
+CellTypeVertex, /* 81 */
+
+  /*   # */
+  /* ##  */
+  /*  #  */
+CellTypeVertex, /* 82 */
+
+  /*   # */
+  /* ### */
+  /*  #  */
+CellTypeVertex, /* 83 */
+
+  /*  #  */
+  /* ##  */
+  /*  #  */
+CellTypeVertex, /* 84 */
+
+  /*  #  */
+  /* ### */
+  /*  #  */
+CellTypeVertex, /* 85 */
+
+  /*  ## */
+  /* ##  */
+  /*  #  */
+CellTypeVertex, /* 86 */
+
+  /*  ## */
+  /* ### */
+  /*  #  */
+CellTypeVertex, /* 87 */
+
+  /* #   */
+  /* ##  */
+  /*  #  */
+CellTypeVertexOrLine, /* 88 */
+
+  /* #   */
+  /* ### */
+  /*  #  */
+CellTypeVertex, /* 89 */
+
+  /* # # */
+  /* ##  */
+  /*  #  */
+CellTypeVertex, /* 90 */
+
+  /* # # */
+  /* ### */
+  /*  #  */
+CellTypeVertex,  /* 91 */
+
+  /* ##  */
+  /* ##  */
+  /*  #  */
+CellTypeVertex, /* 92 */
+
+  /* ##  */
+  /* ### */
+  /*  #  */
+CellTypeVertex, /* 93 */
+
+  /* ### */
+  /* ##  */
+  /*  #  */
+CellTypeVertex, /* 94 */
+
+  /* ### */
+  /* ### */
+  /*  #  */
+CellTypeVertex, /* 95 */
+
+  /*     */
+  /*  #  */
+  /* ##  */
+CellTypeVertex, /* 96 */
+
+  /*     */
+  /*  ## */
+  /* ##  */
+CellTypeVertexOrLine, /* 97 */
+
+  /*   # */
+  /*  #  */
+  /* ##  */
+CellTypeLine,   /* 98 */
+
+  /*   # */
+  /*  ## */
+  /* ##  */
+CellTypeErrorOrLine,  /* 99 */
+
+  /*  #  */
+  /*  #  */
+  /* ##  */
+CellTypeLine,   /* 100 */
+
+  /*  #  */
+  /*  ## */
+  /* ##  */
+CellTypeVertex, /* 101 */
+
+  /*  ## */
+  /*  #  */
+  /* ##  */
+CellTypeLine,   /* 102 */
+
+  /*  ## */
+  /*  ## */
+  /* ##  */
+CellTypeError,  /* 103 */
+
+  /* #   */
+  /*  #  */
+  /* ##  */
+CellTypeLine,   /* 104 */
+
+  /* #   */
+  /*  ## */
+  /* ##  */
+CellTypeVertex, /* 105 */
+
+  /* # # */
+  /*  #  */
+  /* ##  */
+CellTypeVertex, /* 106 */
+
+  /* # # */
+  /*  ## */
+  /* ##  */
+CellTypeVertex, /* 107 */
+
+  /* ##  */
+  /*  #  */
+  /* ##  */
+CellTypeLine,   /* 108 */
+
+  /* ##  */
+  /*  ## */
+  /* ##  */
+CellTypeVertex,  /* 109 */
+
+  /* ### */
+  /*  #  */
+  /* ##  */
+CellTypeLine,   /* 110 */
+
+  /* ### */
+  /*  ## */
+  /* ##  */
+CellTypeError,  /* 111 */
+
+  /*     */
+  /* ##  */
+  /* ##  */
+CellTypeVertex, /* 112 */
+
+  /*     */
+  /* ### */
+  /* ##  */
+CellTypeVertex, /* 113 */
+
+  /*   # */
+  /* ##  */
+  /* ##  */
+CellTypeVertex, /* 114 */
+
+  /*   # */
+  /* ### */
+  /* ##  */
+CellTypeError,  /* 115 */
+
+  /*  #  */
+  /* ##  */
+  /* ##  */
+CellTypeVertex, /* 116 */
+
+  /*  #  */
+  /* ### */
+  /* ##  */
+CellTypeVertex, /* 117 */
+
+  /*  ## */
+  /* ##  */
+  /* ##  */
+CellTypeError,  /* 118 */
+
+  /*  ## */
+  /* ### */
+  /* ##  */
+CellTypeVertex, /* 119 */
+
+  /* #   */
+  /* ##  */
+  /* ##  */
+CellTypeError,  /* 120 */
+
+  /* #   */
+  /* ### */
+  /* ##  */
+CellTypeVertex, /* 121 */
+
+  /* # # */
+  /* ##  */
+  /* ##  */
+CellTypeVertex, /* 122 */
+
+  /* # # */
+  /* ### */
+  /* ##  */
+CellTypeError,  /* 123 */
+
+  /* ##  */
+  /* ##  */
+  /* ##  */
+CellTypeVertex, /* 124 */
+
+  /* ##  */
+  /* ### */
+  /* ##  */
+CellTypeVertex, /* 125 */
+
+  /* ### */
+  /* ##  */
+  /* ##  */
+CellTypeError,  /* 126 */
+
+  /* ### */
+  /* ### */
+  /* ##  */
+CellTypeVertex, /* 127 */
+
+  /*     */
+  /*  #  */
+  /*   # */
+CellTypeVertex, /* 128 */
+
+  /*     */
+  /*  ## */
+  /*   # */
+CellTypeVertex, /* 129 */
+
+  /*   # */
+  /*  #  */
+  /*   # */
+CellTypeLine,   /* 130 */
+
+  /*   # */
+  /*  ## */
+  /*   # */
+CellTypeVertex,  /* 131 */
+
+  /*  #  */
+  /*  #  */
+  /*   # */
+CellTypeLine,   /* 132 */
+
+  /*  #  */
+  /*  ## */
+  /*   # */
+CellTypeVertexOrLine, /* 133 */
+
+  /*  ## */
+  /*  #  */
+  /*   # */
+CellTypeLine,   /* 134 */
+
+  /*  ## */
+  /*  ## */
+  /*   # */
+CellTypeError,  /* 135 */
+
+  /* #   */
+  /*  #  */
+  /*   # */
+CellTypeLine,   /* 136 */
+
+  /* #   */
+  /*  ## */
+  /*   # */
+CellTypeLine,   /* 137 */
+
+  /* # # */
+  /*  #  */
+  /*   # */
+CellTypeVertex, /* 138 */
+
+  /* # # */
+  /*  ## */
+  /*   # */
+CellTypeLine,   /* 139 */
+
+  /* ##  */
+  /*  #  */
+  /*   # */
+CellTypeLine,   /* 140 */
+
+  /* ##  */
+  /*  ## */
+  /*   # */
+CellTypeErrorOrLine,  /* 141 */
+
+  /* ### */
+  /*  #  */
+  /*   # */
+CellTypeLine,   /* 142 */
+
+  /* ### */
+  /*  ## */
+  /*   # */
+CellTypeError,  /* 143 */
+
+  /*     */
+  /* ##  */
+  /*   # */
+CellTypeLine,   /* 144 */
+
+  /*     */
+  /* ### */
+  /*   # */
+CellTypeLine,   /* 145 */
+
+  /*   # */
+  /* ##  */
+  /*   # */
+CellTypeVertex, /* 146 */
+
+  /*   # */
+  /* ### */
+  /*   # */
+CellTypeLine,   /* 147 */
+
+  /*  #  */
+  /* ##  */
+  /*   # */
+CellTypeVertex, /* 148 */
+
+  /*  #  */
+  /* ### */
+  /*   # */
+CellTypeVertex, /* 149 */
+
+  /*  ## */
+  /* ##  */
+  /*   # */
+CellTypeVertex, /* 150 */
+
+  /*  ## */
+  /* ### */
+  /*   # */
+CellTypeVertex, /* 151 */
+
+  /* #   */
+  /* ##  */
+  /*   # */
+CellTypeLine,   /* 152 */
+
+  /* #   */
+  /* ### */
+  /*   # */
+CellTypeLine,   /* 153 */
+
+  /* # # */
+  /* ##  */
+  /*   # */
+CellTypeVertex, /* 154 */
+
+  /* # # */
+  /* ### */
+  /*   # */
+CellTypeLine,   /* 155 */
+
+  /* ##  */
+  /* ##  */
+  /*   # */
+CellTypeVertex, /* 156 */
+
+  /* ##  */
+  /* ### */
+  /*   # */
+CellTypeError,  /* 157 */
+
+  /* ### */
+  /* ##  */
+  /*   # */
+CellTypeVertex, /* 158 */
+
+  /* ### */
+  /* ### */
+  /*   # */
+CellTypeError,  /* 159 */
+
+  /*     */
+  /*  #  */
+  /* # # */
+CellTypeLine,   /* 160 */
+
+  /*     */
+  /*  ## */
+  /* # # */
+CellTypeLine,   /* 161 */
+
+  /*   # */
+  /*  #  */
+  /* # # */
+CellTypeVertex, /* 162 */
+
+  /*   # */
+  /*  ## */
+  /* # # */
+CellTypeLine,   /* 163 */
+
+  /*  #  */
+  /*  #  */
+  /* # # */
+CellTypeVertex, /* 164 */
+
+  /*  #  */
+  /*  ## */
+  /* # # */
+CellTypeVertex, /* 165 */
+
+  /*  ## */
+  /*  #  */
+  /* # # */
+CellTypeVertex, /* 166 */
+
+  /*  ## */
+  /*  ## */
+  /* # # */
+CellTypeVertex, /* 167 */
+
+  /* #   */
+  /*  #  */
+  /* # # */
+CellTypeVertex, /* 168 */
+
+  /* #   */
+  /*  ## */
+  /* # # */
+CellTypeVertex, /* 169 */
+
+  /* # # */
+  /*  #  */
+  /* # # */
+CellTypeVertex, /* 170 */
+
+  /* # # */
+  /*  ## */
+  /* # # */
+CellTypeVertex, /* 171 */
+
+  /* ##  */
+  /*  #  */
+  /* # # */
+CellTypeVertex, /* 172 */
+
+  /* ##  */
+  /*  ## */
+  /* # # */
+CellTypeVertex, /* 173 */
+
+  /* ### */
+  /*  #  */
+  /* # # */
+CellTypeVertex, /* 174 */
+
+  /* ### */
+  /*  ## */
+  /* # # */
+CellTypeVertex, /* 175 */
+
+  /*     */
+  /* ##  */
+  /* # # */
+CellTypeLine,   /* 176 */
+
+  /*     */
+  /* ### */
+  /* # # */
+CellTypeLine,   /* 177 */
+
+  /*   # */
+  /* ##  */
+  /* # # */
+CellTypeVertex, /* 178 */
+
+  /*   # */
+  /* ### */
+  /* # # */
+CellTypeLine,   /* 179 */
+
+  /*  #  */
+  /* ##  */
+  /* # # */
+CellTypeVertex, /* 180 */
+
+  /*  #  */
+  /* ### */
+  /* # # */
+CellTypeVertex,  /* 181 */
+
+  /*  ## */
+  /* ##  */
+  /* # # */
+CellTypeVertex, /* 182 */
+
+  /*  ## */
+  /* ### */
+  /* # # */
+CellTypeError,  /* 183 */
+
+  /* #   */
+  /* ##  */
+  /* # # */
+CellTypeLine,   /* 184 */
+
+  /* #   */
+  /* ### */
+  /* # # */
+CellTypeLine,   /* 185 */
+
+  /* # # */
+  /* ##  */
+  /* # # */
+CellTypeVertex, /* 186 */
+
+  /* # # */
+  /* ### */
+  /* # # */
+CellTypeLine,   /* 187 */
+
+  /* ##  */
+  /* ##  */
+  /* # # */
+CellTypeVertex, /* 188 */
+
+  /* ##  */
+  /* ### */
+  /* # # */
+CellTypeError,  /* 189 */
+
+  /* ### */
+  /* ##  */
+  /* # # */
+CellTypeVertex, /* 190 */
+
+  /* ### */
+  /* ### */
+  /* # # */
+CellTypeError,  /* 191 */
+
+  /*     */
+  /*  #  */
+  /*  ## */
+CellTypeVertex, /* 192 */
+
+  /*     */
+  /*  ## */
+  /*  ## */
+CellTypeVertex, /* 193 */
+
+  /*   # */
+  /*  #  */
+  /*  ## */
+CellTypeLine,   /* 194 */
+
+  /*   # */
+  /*  ## */
+  /*  ## */
+CellTypeError,  /* 195 */
+
+  /*  #  */
+  /*  #  */
+  /*  ## */
+CellTypeLine,   /* 196 */
+
+  /*  #  */
+  /*  ## */
+  /*  ## */
+CellTypeVertex, /* 197 */
+
+  /*  ## */
+  /*  #  */
+  /*  ## */
+CellTypeLine,   /* 198 */
+
+  /*  ## */
+  /*  ## */
+  /*  ## */
+CellTypeVertex, /* 199 */
+
+  /* #   */
+  /*  #  */
+  /*  ## */
+CellTypeLine,   /* 200 */
+
+  /* #   */
+  /*  ## */
+  /*  ## */
+CellTypeVertex, /* 201 */
+
+  /* # # */
+  /*  #  */
+  /*  ## */
+CellTypeVertex, /* 202 */
+
+  /* # # */
+  /*  ## */
+  /*  ## */
+CellTypeVertex, /* 203 */
+
+  /* ##  */
+  /*  #  */
+  /*  ## */
+CellTypeLine,   /* 204 */
+
+  /* ##  */
+  /*  ## */
+  /*  ## */
+CellTypeError,  /* 205 */
+
+  /* ### */
+  /*  #  */
+  /*  ## */
+CellTypeLine,   /* 206 */
+
+  /* ### */
+  /*  ## */
+  /*  ## */
+CellTypeError,  /* 207 */
+
+  /*     */
+  /* ##  */
+  /*  ## */
+CellTypeVertexOrLine, /* 208 */
+
+  /*     */
+  /* ### */
+  /*  ## */
+CellTypeVertex, /* 209 */
+
+  /*   # */
+  /* ##  */
+  /*  ## */
+CellTypeVertex, /* 210 */
+
+  /*   # */
+  /* ### */
+  /*  ## */
+CellTypeVertex, /* 211 */
+
+  /*  #  */
+  /* ##  */
+  /*  ## */
+CellTypeVertex, /* 212 */
+
+  /*  #  */
+  /* ### */
+  /*  ## */
+CellTypeVertex, /* 213 */
+
+  /*  ## */
+  /* ##  */
+  /*  ## */
+CellTypeVertex,  /* 214 */
+
+  /*  ## */
+  /* ### */
+  /*  ## */
+CellTypeVertex, /* 215 */
+
+  /* #   */
+  /* ##  */
+  /*  ## */
+CellTypeErrorOrLine,  /* 216 */
+
+  /* #   */
+  /* ### */
+  /*  ## */
+CellTypeError,  /* 217 */
+
+  /* # # */
+  /* ##  */
+  /*  ## */
+CellTypeVertex, /* 218 */
+
+  /* # # */
+  /* ### */
+  /*  ## */
+CellTypeError,  /* 219 */
+
+  /* ##  */
+  /* ##  */
+  /*  ## */
+CellTypeError,  /* 220 */
+
+  /* ##  */
+  /* ### */
+  /*  ## */
+CellTypeVertex, /* 221 */
+
+  /* ### */
+  /* ##  */
+  /*  ## */
+CellTypeError,  /* 222 */
+
+  /* ### */
+  /* ### */
+  /*  ## */
+CellTypeVertex, /* 223 */
+
+  /*     */
+  /*  #  */
+  /* ### */
+CellTypeVertex,  /* 224 */
+
+  /*     */
+  /*  ## */
+  /* ### */
+CellTypeError,  /* 225 */
+
+  /*   # */
+  /*  #  */
+  /* ### */
+CellTypeLine,   /* 226 */
+
+  /*   # */
+  /*  ## */
+  /* ### */
+CellTypeError,  /* 227 */
+
+  /*  #  */
+  /*  #  */
+  /* ### */
+CellTypeLine,   /* 228 */
+
+  /*  #  */
+  /*  ## */
+  /* ### */
+CellTypeVertex, /* 229 */
+
+  /*  ## */
+  /*  #  */
+  /* ### */
+CellTypeLine,   /* 230 */
+
+  /*  ## */
+  /*  ## */
+  /* ### */
+CellTypeError,  /* 231 */
+
+  /* #   */
+  /*  #  */
+  /* ### */
+CellTypeLine,   /* 232 */
+
+  /* #   */
+  /*  ## */
+  /* ### */
+CellTypeVertex, /* 233 */
+
+  /* # # */
+  /*  #  */
+  /* ### */
+CellTypeVertex, /* 234 */
+
+  /* # # */
+  /*  ## */
+  /* ### */
+CellTypeVertex, /* 235 */
+
+  /* ##  */
+  /*  #  */
+  /* ### */
+CellTypeLine,   /* 236 */
+
+  /* ##  */
+  /*  ## */
+  /* ### */
+CellTypeError,  /* 237 */
+
+  /* ### */
+  /*  #  */
+  /* ### */
+CellTypeLine,   /* 238 */
+
+  /* ### */
+  /*  ## */
+  /* ### */
+CellTypeError,  /* 239 */
+
+  /*     */
+  /* ##  */
+  /* ### */
+CellTypeError,  /* 240 */
+
+  /*     */
+  /* ### */
+  /* ### */
+CellTypeVertex, /* 241 */
+
+  /*   # */
+  /* ##  */
+  /* ### */
+CellTypeVertex, /* 242 */
+
+  /*   # */
+  /* ### */
+  /* ### */
+CellTypeError,  /* 243 */
+
+  /*  #  */
+  /* ##  */
+  /* ### */
+CellTypeVertex, /* 244 */
+
+  /*  #  */
+  /* ### */
+  /* ### */
+CellTypeVertex, /* 245 */
+
+  /*  ## */
+  /* ##  */
+  /* ### */
+CellTypeError,  /* 246 */
+
+  /*  ## */
+  /* ### */
+  /* ### */
+CellTypeVertex, /* 247 */
+
+  /* #   */
+  /* ##  */
+  /* ### */
+CellTypeError,  /* 248 */
+
+  /* #   */
+  /* ### */
+  /* ### */
+CellTypeError,  /* 249 */
+
+  /* # # */
+  /* ##  */
+  /* ### */
+CellTypeVertex, /* 250 */
+
+  /* # # */
+  /* ### */
+  /* ### */
+CellTypeError,  /* 251 */
+
+  /* ##  */
+  /* ##  */
+  /* ### */
+CellTypeError,  /* 252 */
+
+  /* ##  */
+  /* ### */
+  /* ### */
+CellTypeVertex, /* 253 */
+
+  /* ### */
+  /* ##  */
+  /* ### */
+CellTypeError,  /* 254 */
+
+  /* ### */
+  /* ### */
+  /* ### */
+CellTypeVertex  /* 255 */
+};
+
+} // namespace cellimage
+
+} // namespace vigra
+
+#endif /* VIGRA_CELLCONFIGURATIONS_HXX */
diff --git a/include/vigra/cellimage.hxx b/include/vigra/cellimage.hxx
new file mode 100644
index 0000000..b83317e
--- /dev/null
+++ b/include/vigra/cellimage.hxx
@@ -0,0 +1,272 @@
+/************************************************************************/
+/*                                                                      */
+/*             Copyright 2009-2010 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_CELLIMAGE_HXX
+#define VIGRA_CELLIMAGE_HXX
+
+#include <vigra/basicimage.hxx>
+#include <vigra/pixelneighborhood.hxx>
+#include <functional>
+
+namespace vigra {
+
+namespace cellimage {
+
+enum CellType { CellTypeRegion = 0,
+                CellTypeLine = 1,
+                CellTypeVertex = 2,
+                CellTypeError = 3,
+                CellTypeVertexOrLine = 4,
+                CellTypeErrorOrLine = 5 };
+
+// -------------------------------------------------------------------
+//                          CellPixel, CellImage
+// -------------------------------------------------------------------
+typedef unsigned int CellLabel;
+
+struct CellPixel
+{
+private:
+    CellLabel typeLabel_;
+
+    friend struct CellPixelSerializer;
+
+public:
+    CellPixel() {}
+    CellPixel(CellType type, CellLabel label = 0)
+    : typeLabel_((label << 2) | type)
+    {}
+
+    inline CellType type() const
+        { return (CellType)(typeLabel_ & 3); }
+    inline void setType(CellType type)
+        { typeLabel_ = (label() << 2) | type; }
+    inline void setType(CellType type, CellLabel label)
+        { typeLabel_ = label << 2 | type; }
+
+    inline CellLabel label() const
+        { return typeLabel_ >> 2; }
+    inline void setLabel(CellLabel label)
+        { typeLabel_ = label << 2 | type(); }
+    inline void setLabel(CellLabel label, CellType type)
+        { typeLabel_ = label << 2 | type; }
+
+    bool operator==(CellPixel const & rhs) const
+        { return typeLabel_ == rhs.typeLabel_; }
+
+    bool operator!=(CellPixel const & rhs) const
+        { return typeLabel_ != rhs.typeLabel_; }
+};
+
+typedef BasicImage<CellPixel> CellImage;
+
+typedef vigra::NeighborhoodCirculator<CellImage::Iterator, EightNeighborCode>
+    CellImageEightCirculator;
+
+// -------------------------------------------------------------------
+//                     CellPixel Serialization
+// -------------------------------------------------------------------
+struct CellPixelSerializer
+{
+    int operator()(CellPixel const &p) const
+    {
+        return p.typeLabel_;
+    }
+
+    CellPixel operator()(int i) const
+    {
+        CellPixel result;
+        result.typeLabel_ = i;
+        return result;
+    }
+};
+
+// -------------------------------------------------------------------
+//                   CellPixel/CellImage Accessors
+// -------------------------------------------------------------------
+template<class VALUE_TYPE = CellType>
+struct TypeAccessor
+{
+    typedef VALUE_TYPE value_type;
+    typedef VALUE_TYPE result_type;
+
+    template<class Iterator>
+    value_type operator()(const Iterator &it) const
+    {
+        return it->type();
+    }
+
+    template<class Iterator>
+    void set(value_type type, const Iterator &it) const
+    {
+        it->setType(type);
+    }
+};
+
+typedef TypeAccessor<unsigned char> TypeAsByteAccessor;
+
+typedef TypeAccessor<> CellTypeAccessor;
+
+struct LabelAccessor
+{
+    typedef CellLabel value_type;
+
+    template<class Iterator>
+    CellLabel operator()(const Iterator &it) const
+    {
+        return it->label();
+    }
+
+    template<class Iterator>
+    void set(CellLabel label, const Iterator &it) const
+    {
+        it->setLabel(label);
+    }
+};
+
+template<CellType type>
+struct LabelWriter
+{
+    typedef CellLabel value_type;
+
+    template<class Iterator>
+    void set(CellLabel label, const Iterator &it) const
+    {
+        it->setLabel(label, type);
+    }
+};
+
+template<CellType type>
+struct CellTypeEquals : public std::unary_function<CellType, bool>
+{
+    bool operator()(CellType t) const
+    {
+        return t == type;
+    }
+
+    template<class Iterator>
+    bool operator()(const Iterator &it) const
+    {
+        return it->type() == type;
+    }
+};
+
+struct CellMask : public std::unary_function<vigra::cellimage::CellPixel, bool>
+{
+    vigra::cellimage::CellPixel maskPixel_;
+
+    CellMask(vigra::cellimage::CellPixel maskPixel)
+    : maskPixel_(maskPixel)
+    {}
+
+    template<class Iterator>
+    bool operator()(const Iterator &it) const
+    {
+        return *it == maskPixel_;
+    }
+};
+
+// -------------------------------------------------------------------
+//                        RelabelFunctor (unused!)
+// -------------------------------------------------------------------
+template<class VALUETYPE>
+struct RelabelFunctor
+{
+    typedef VALUETYPE value_type;
+    typedef VALUETYPE argument_type;
+    typedef VALUETYPE result_type;
+
+    RelabelFunctor(VALUETYPE oldValue, VALUETYPE newValue)
+        : oldValue_(oldValue),
+          newValue_(newValue)
+    {}
+
+    VALUETYPE operator()(VALUETYPE value) const
+    {
+        return (value == oldValue_) ? newValue_ : value;
+    }
+
+    VALUETYPE oldValue_, newValue_;
+};
+
+// -------------------------------------------------------------------
+//                              inspectCell
+// -------------------------------------------------------------------
+// thinking about "typename IteratorTraits<EndIterator>::DefaultAccessor":
+// is not needed since we're not implementing srcCellRange here, but
+// algorithms.
+// srcCellRange can not be implemented that easy, because most VIGRA
+// functions expect an ImageIterator, not a std::iterator
+template <class EndIterator, class Accessor, class Functor>
+void inspectCell(EndIterator endIterator, Accessor a, Functor & f)
+{
+    for(; endIterator.inRange(); ++endIterator)
+        f(a(endIterator));
+}
+
+template <class EndIterator, class Functor>
+void inspectCell(EndIterator endIterator, Functor & f)
+{
+    for(; endIterator.inRange(); ++endIterator)
+        f(*endIterator);
+}
+
+// -------------------------------------------------------------------
+//                             transformCell
+// -------------------------------------------------------------------
+template <class SrcEndIterator, class SrcAccessor,
+          class DestEndIterator, class DestAccessor, class Functor>
+void transformCell(SrcEndIterator srcEndIterator, SrcAccessor sa,
+                   DestEndIterator destEndIterator, DestAccessor da,
+                   Functor const & f)
+{
+    for(; srcEndIterator.inRange(); ++srcEndIterator, ++destEndIterator)
+        da.set(f(sa(srcEndIterator)), destEndIterator);
+}
+
+template <class SrcEndIterator, class DestEndIterator, class Functor>
+void transformCell(SrcEndIterator srcEndIterator,
+                   DestEndIterator destEndIterator,
+                   Functor const & f)
+{
+    for(; srcEndIterator.inRange(); ++srcEndIterator, ++destEndIterator)
+        *destEndIterator = f(*srcEndIterator);
+}
+
+} // namespace cellimage
+
+} // namespace vigra
+
+#endif // VIGRA_CELLIMAGE_HXX
diff --git a/include/vigra/clebsch-gordan.hxx b/include/vigra/clebsch-gordan.hxx
new file mode 100644
index 0000000..7ca86ff
--- /dev/null
+++ b/include/vigra/clebsch-gordan.hxx
@@ -0,0 +1,423 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2009-2010 by Ullrich Koethe and Janis Fehr          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_CLEBSCH_GORDAN_HXX
+#define VIGRA_CLEBSCH_GORDAN_HXX
+
+#include "config.hxx"
+#include "numerictraits.hxx"
+#include "error.hxx"
+#include "mathutil.hxx"
+#include "array_vector.hxx"
+
+namespace vigra {
+
+namespace {
+
+void ThreeJSymbolM(double l1, double l2, double l3, double m1,
+                   double &m2min, double &m2max, double *thrcof, int ndim,
+                   int &errflag)
+{
+    ContractViolation err;  
+    const double zero = 0.0, eps = 0.01, one = 1.0, two = 2.0;
+
+    int nfin, nlim, i, n, index, lstep, nfinp1, nfinp2, nfinp3, nstep2;
+    double oldfac, dv, newfac, sumbac = 0.0, thresh, a1s, sumfor, sumuni,
+    sum1, sum2, x, y, m2, m3, x1, x2, x3, y1, y2, y3, cnorm,
+    ratio, a1, c1, c2, c1old = 0.0, sign1, sign2;
+
+    // Parameter adjustments
+    --thrcof;
+
+    errflag = 0;
+
+    // "hugedouble" is the square root of one twentieth of the largest floating
+    // point number, approximately.
+    double hugedouble   = std::sqrt(NumericTraits<double>::max() / 20.0),
+    srhuge = std::sqrt(hugedouble),
+    tiny   = one / hugedouble,
+    srtiny = one / srhuge;
+
+    // lmatch = zero
+
+    //  Check error conditions 1, 2, and 3.
+    if (l1 - abs(m1) + eps < zero
+            || std::fmod(l1 + abs(m1) + eps, one) >= eps + eps) 
+    {
+        errflag = 1;
+        err << "ThreeJSymbolM: l1-abs(m1) less than zero or l1+abs(m1) not integer.\n";
+        throw err;
+    } 
+    else if (l1+l2-l3 < -eps || l1-l2+l3 < -eps || -(l1) + l2+l3 < -eps) 
+    {
+        errflag = 2;
+        err << " ThreeJSymbolM: l1, l2, l3 do not satisfy triangular condition:"
+            << l1 << " " << l2 << " " << l3 << "\n";
+        throw err;
+    } 
+    else if (std::fmod(l1 + l2 + l3 + eps, one) >= eps + eps) 
+    {
+        errflag = 3;
+        err << " ThreeJSymbolM: l1+l2+l3 not integer.\n";
+        throw err;
+    }
+
+    // limits for m2
+    m2min = std::max(-l2,-l3-m1);
+    m2max = std::min(l2,l3-m1);
+
+    // Check error condition 4.
+    if (std::fmod(m2max - m2min + eps, one) >= eps + eps) {
+        errflag = 4;
+        err << " ThreeJSymbolM: m2max-m2min not integer.\n";
+        throw err;
+    }
+    if (m2min < m2max - eps) 
+        goto L20;
+    if (m2min < m2max + eps) 
+        goto L10;
+
+    //  Check error condition 5.
+    errflag = 5;
+    err << " ThreeJSymbolM: m2min greater than m2max.\n";
+    throw err;
+
+    // This is reached in case that m2 and m3 can take only one value.
+L10:
+    // mscale = 0
+    thrcof[1] = (odd(int(abs(l2-l3-m1)+eps)) 
+                       ? -one 
+                       :  one) / std::sqrt(l1+l2+l3+one);
+    return;
+
+    // This is reached in case that M1 and M2 take more than one value.
+L20:
+    // mscale = 0
+    nfin = int(m2max - m2min + one + eps);
+    if (ndim - nfin >= 0) 
+        goto L23;
+
+    // Check error condition 6.
+
+    errflag = 6;
+    err << " ThreeJSymbolM: Dimension of result array for 3j coefficients too small.\n";
+    throw err;
+
+    //  Start of forward recursion from m2 = m2min
+
+L23:
+    m2 = m2min;
+    thrcof[1] = srtiny;
+    newfac = 0.0;
+    c1 = 0.0;
+    sum1 = tiny;
+
+    lstep = 1;
+L30:
+    ++lstep;
+    m2 += one;
+    m3 = -m1 - m2;
+
+    oldfac = newfac;
+    a1 = (l2 - m2 + one) * (l2 + m2) * (l3 + m3 + one) * (l3 - m3);
+    newfac = std::sqrt(a1);
+
+    dv = (l1+l2+l3+one) * (l2+l3-l1) - (l2-m2+one) * (l3+m3+one)
+         - (l2+m2-one) * (l3-m3-one);
+
+    if (lstep - 2 > 0) 
+        c1old = abs(c1);
+
+    // L32:
+    c1 = -dv / newfac;
+
+    if (lstep > 2) 
+        goto L60;
+
+    //  If m2 = m2min + 1, the third term in the recursion equation vanishes,  
+    //  hence
+
+    x = srtiny * c1;
+    thrcof[2] = x;
+    sum1 += tiny * c1 * c1;
+    if (lstep == nfin) 
+        goto L220;
+    goto L30;
+
+L60:
+    c2 = -oldfac / newfac;
+
+    // Recursion to the next 3j coefficient
+    x = c1 * thrcof[lstep-1] + c2 * thrcof[lstep-2];
+    thrcof[lstep] = x;
+    sumfor = sum1;
+    sum1 += x * x;
+    if (lstep == nfin) 
+        goto L100;
+
+    // See if last unnormalized 3j coefficient exceeds srhuge
+    if (abs(x) < srhuge) 
+        goto L80;
+
+    // This is reached if last 3j coefficient larger than srhuge,
+    // so that the recursion series thrcof(1), ... , thrcof(lstep)
+    // has to be rescaled to prevent overflow
+
+    // mscale = mscale + 1
+    for (i = 1; i <= lstep; ++i) 
+    {
+        if (abs(thrcof[i]) < srtiny) 
+            thrcof[i] = zero;
+        thrcof[i] /= srhuge;
+    }
+    sum1 /= hugedouble;
+    sumfor /= hugedouble;
+    x /= srhuge;
+
+    // As long as abs(c1) is decreasing, the recursion proceeds towards
+    // increasing 3j values and, hence, is numerically stable.  Once
+    // an increase of abs(c1) is detected, the recursion direction is
+    // reversed.
+
+L80:
+    if (c1old - abs(c1) > 0.0) 
+        goto L30;
+
+    //  Keep three 3j coefficients aroundi mmatch for comparison later
+    //  with backward recursion values.
+
+L100:
+    // mmatch = m2 - 1
+    nstep2 = nfin - lstep + 3;
+    x1 = x;
+    x2 = thrcof[lstep-1];
+    x3 = thrcof[lstep-2];
+
+    //  Starting backward recursion from m2max taking nstep2 steps, so
+    //  that forwards and backwards recursion overlap at the three points
+    //  m2 = mmatch+1, mmatch, mmatch-1.
+
+    nfinp1 = nfin + 1;
+    nfinp2 = nfin + 2;
+    nfinp3 = nfin + 3;
+    thrcof[nfin] = srtiny;
+    sum2 = tiny;
+
+    m2 = m2max + two;
+    lstep = 1;
+L110:
+    ++lstep;
+    m2 -= one;
+    m3 = -m1 - m2;
+    oldfac = newfac;
+    a1s = (l2-m2+two) * (l2+m2-one) * (l3+m3+two) * (l3-m3-one);
+    newfac = std::sqrt(a1s);
+    dv = (l1+l2+l3+one) * (l2+l3-l1) - (l2-m2+one) * (l3+m3+one)
+          - (l2+m2-one) * (l3-m3-one);
+    c1 = -dv / newfac;
+    if (lstep > 2) 
+        goto L120;
+
+    // if m2 = m2max + 1 the third term in the recursion equation vanishes
+
+    y = srtiny * c1;
+    thrcof[nfin - 1] = y;
+    if (lstep == nstep2) 
+        goto L200;
+    sumbac = sum2;
+    sum2 += y * y;
+    goto L110;
+
+L120:
+    c2 = -oldfac / newfac;
+
+    // Recursion to the next 3j coefficient
+
+    y = c1 * thrcof[nfinp2 - lstep] + c2 * thrcof[nfinp3 - lstep];
+
+    if (lstep == nstep2) 
+        goto L200;
+
+    thrcof[nfinp1 - lstep] = y;
+    sumbac = sum2;
+    sum2 += y * y;
+
+    // See if last 3j coefficient exceeds SRHUGE
+
+    if (abs(y) < srhuge) 
+        goto L110;
+
+    // This is reached if last 3j coefficient larger than srhuge,
+    // so that the recursion series thrcof(nfin), ... , thrcof(nfin-lstep+1)   
+    // has to be rescaled to prevent overflow.
+
+    // mscale = mscale + 1
+    for (i = 1; i <= lstep; ++i) 
+    {
+        index = nfin - i + 1;
+        if (abs(thrcof[index]) < srtiny) 
+            thrcof[index] = zero;
+        thrcof[index] /= srhuge;
+    }
+    sum2 /= hugedouble;
+    sumbac /= hugedouble;
+
+    goto L110;
+
+    //  The forward recursion 3j coefficients x1, x2, x3 are to be matched
+    //  with the corresponding backward recursion values y1, y2, y3.
+
+L200:
+    y3 = y;
+    y2 = thrcof[nfinp2-lstep];
+    y1 = thrcof[nfinp3-lstep];
+
+    //  Determine now ratio such that yi = ratio * xi  (i=1,2,3) holds
+    //  with minimal error.
+
+    ratio = (x1*y1 + x2*y2 + x3*y3) / (x1*x1 + x2*x2 + x3*x3);
+    nlim = nfin - nstep2 + 1;
+
+    if (abs(ratio) < one) 
+        goto L211;
+    for (n = 1; n <= nlim; ++n)
+        thrcof[n] = ratio * thrcof[n];
+    sumuni = ratio * ratio * sumfor + sumbac;
+    goto L230;
+
+L211:
+    ++nlim;
+    ratio = one / ratio;
+    for (n = nlim; n <= nfin; ++n)
+        thrcof[n] = ratio * thrcof[n];
+    sumuni = sumfor + ratio * ratio * sumbac;
+    goto L230;
+L220:
+    sumuni = sum1;
+
+    // Normalize 3j coefficients
+
+L230:
+    cnorm = one / std::sqrt((l1+l1+one) * sumuni);
+
+    // Sign convention for last 3j coefficient determines overall phase
+
+    sign1 = sign(thrcof[nfin]);
+    sign2 = odd(int(abs(l2-l3-m1)+eps)) 
+                   ? -one 
+                   : one;
+    if (sign1 * sign2 <= 0.0) 
+        goto L235;
+    else 
+        goto L236;
+
+L235:
+    cnorm = -cnorm;
+
+L236:
+    if (abs(cnorm) < one) 
+        goto L250;
+
+    for (n = 1; n <= nfin; ++n)
+        thrcof[n] = cnorm * thrcof[n];
+    return;
+
+L250:
+    thresh = tiny / abs(cnorm);
+    for (n = 1; n <= nfin; ++n) 
+    {
+        if (abs(thrcof[n]) < thresh) 
+            thrcof[n] = zero;
+        thrcof[n] = cnorm * thrcof[n];
+    }
+}
+
+} // anonymous namespace
+
+inline 
+double clebschGordan (double l1, double m1, double l2, double m2, double l3, double m3)
+{
+    const double err = 0.01;
+    double CG = 0.0, m2min, m2max, *cofp;                               
+    // array for calculation of 3-j symbols 
+    const int ncof = 100;
+    double cof[ncof];                                            
+    // reset error flag   
+    int errflag = 0;
+    ContractViolation Err;
+
+    // Check for physical restriction.
+    // All other restrictions are checked by the 3-j symbol routine.
+    if ( abs(m1 + m2 - m3) > err) 
+    {
+        errflag = 7;
+        Err << " clebschGordan: m1 + m2 - m3 is not zero.\n";
+        throw Err;
+    }                                                                   
+    // calculate minimum storage size needed for ThreeJSymbolM()
+    // if the dimension becomes negative the 3-j routine will capture it
+    int njm = roundi(std::min(l2,l3-m1) - std::max(-l2,-l3-m1) + 1);            
+
+    // allocate dynamic memory if necessary
+    ArrayVector<double> cofa;
+    if(njm > ncof)
+    {
+        cofa.resize(njm);
+        cofp = cofa.begin();
+    }
+    else
+    {
+        cofp = cof;
+    }
+
+    // calculate series of 3-j symbols
+    ThreeJSymbolM (l1,l2,l3,m1, m2min,m2max, cofp,njm, errflag);        
+    // calculated Clebsch-Gordan coefficient
+    if (! errflag)
+    {
+        CG = cofp[roundi(m2-m2min)] * (odd(roundi(l1-l2+m3)) ? -1 : 1) * std::sqrt(2*l3+1);
+    }
+    else
+    {
+        Err << " clebschGordan: 3jM-sym error.\n";
+        throw Err;
+    }
+    return CG;                                                          
+}
+
+} // namespace vigra 
+
+#endif // VIGRA_CLEBSCH_GORDAN_HXX
+
diff --git a/include/vigra/codec.hxx b/include/vigra/codec.hxx
new file mode 100644
index 0000000..d7e5772
--- /dev/null
+++ b/include/vigra/codec.hxx
@@ -0,0 +1,303 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2001-2002 by Gunnar Kedenburg                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/* Modifications by Pablo d'Angelo
+ * updated to vigra 1.4 by Douglas Wilkins
+ * as of 18 February 2006:
+ *  - Added UINT16 and UINT32 pixel types.
+ *  - Added support for obtaining extra bands beyond RGB.
+ *  - Added support for a position field that indicates the start of this
+ *    image relative to some global origin.
+ *  - Added support for x and y resolution fields.
+ *  - Added support for ICC Profiles
+ */
+
+#ifndef VIGRA_CODEC_HXX
+#define VIGRA_CODEC_HXX
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "array_vector.hxx"
+#include "config.hxx"
+#include "diff2d.hxx"
+#include "sized_int.hxx"
+
+// possible pixel types:
+// "undefined", "UINT8", "UINT16", "INT16", "UINT32", "INT32", "FLOAT", "DOUBLE"
+
+// possible compression types:
+// "undefined", "RLE", "LZW", "LOSSLESS", "JPEG", "DEFLATE"
+
+// possible file types:
+// "undefined", "TIFF", "VIFF", "JPEG", "PNG", "PNM", "BMP", "SUN", "XPM", "EXR"
+
+// possible name extensions:
+// "undefined", "tif", "tiff", "jpg", "jpeg", "png", "pnm", "bmp", "sun",
+// "xpm", "exr" (also capital forms)
+
+namespace vigra
+{
+    template <class T>
+    struct TypeAsString
+    {
+        static std::string result() { return "undefined"; }
+    };
+
+    template <>
+    struct TypeAsString<Int8>
+    {
+        static std::string result() { return "INT8"; }
+    };
+
+    template <>
+    struct TypeAsString<UInt8>
+    {
+        static std::string result() { return "UINT8"; }
+    };
+
+    template <>
+    struct TypeAsString<Int16>
+    {
+        static std::string result() { return "INT16"; }
+    };
+
+    template <>
+    struct TypeAsString<UInt16>
+    {
+        static std::string result() { return "UINT16"; }
+    };
+
+    template <>
+    struct TypeAsString<Int32>
+    {
+        static std::string result() { return "INT32"; }
+    };
+
+    template <>
+    struct TypeAsString<UInt32>
+    {
+        static std::string result() { return "UINT32"; }
+    };
+
+    template <>
+    struct TypeAsString<float>
+    {
+        static std::string result() { return "FLOAT"; }
+    };
+
+    template <>
+    struct TypeAsString<double>
+    {
+        static std::string result() { return "DOUBLE"; }
+    };
+
+
+    // codec description
+    struct CodecDesc
+    {
+        std::string fileType;
+        std::vector<std::string> pixelTypes;
+        std::vector<std::string> compressionTypes;
+        std::vector<std::vector<char> > magicStrings;
+        std::vector<std::string> fileExtensions;
+        std::vector<int> bandNumbers;
+    };
+
+    // Decoder and Encoder are virtual types that define a common
+    // interface for all image file formats impex supports.
+
+    struct Decoder
+    {
+        virtual ~Decoder() {};
+        virtual void init( const std::string & ) = 0;
+
+        // initialize with an image index. For codecs that do not support this feature, the standard init is called.
+        virtual void init( const std::string & fileName, unsigned int)
+        {
+          init(fileName);
+        }
+
+        virtual void close() = 0;
+        virtual void abort() = 0;
+
+        virtual std::string getFileType() const = 0;
+        virtual std::string getPixelType() const = 0;
+
+        virtual unsigned int getNumImages() const
+        {
+          return 1;
+        }
+
+        virtual void setImageIndex(unsigned int)
+        {
+        }
+
+        virtual unsigned int getImageIndex() const
+        {
+          return 0;
+        }
+
+        virtual unsigned int getWidth() const = 0;
+        virtual unsigned int getHeight() const = 0;
+        virtual unsigned int getNumBands() const = 0;
+        virtual unsigned int getNumExtraBands() const
+        {
+            return 0;
+        }
+
+        virtual vigra::Diff2D getPosition() const
+        {
+            return vigra::Diff2D();
+        }
+
+        virtual float getXResolution() const
+        {
+            return 0.0f;
+        }
+        virtual float getYResolution() const
+        {
+            return 0.0f;
+        }
+
+        virtual vigra::Size2D getCanvasSize() const
+        {
+            return vigra::Size2D(this->getWidth(), this->getHeight());
+        }
+
+        virtual unsigned int getOffset() const = 0;
+
+        virtual const void * currentScanlineOfBand( unsigned int ) const = 0;
+        virtual void nextScanline() = 0;
+
+        typedef ArrayVector<unsigned char> ICCProfile;
+
+        const ICCProfile & getICCProfile() const
+        {
+            return iccProfile_;
+        }
+
+        ICCProfile iccProfile_;
+    };
+
+    struct Encoder
+    {
+        virtual ~Encoder() {};
+        virtual void init( const std::string & ) = 0;
+
+        // initialize with file access mode. For codecs that do not support this feature, the standard init is called.
+        virtual void init( const std::string & fileName, const std::string & )
+        {
+          init(fileName);
+        }
+
+        virtual void close() = 0;
+        virtual void abort() = 0;
+
+        virtual std::string getFileType() const = 0;
+        virtual unsigned int getOffset() const = 0;
+
+        virtual void setWidth( unsigned int ) = 0;
+        virtual void setHeight( unsigned int ) = 0;
+        virtual void setNumBands( unsigned int ) = 0;
+        virtual void setCompressionType( const std::string &, int = -1 ) = 0;
+        virtual void setPixelType( const std::string & ) = 0;
+        virtual void finalizeSettings() = 0;
+
+        virtual void setPosition( const vigra::Diff2D & /*pos*/ )
+        {
+        }
+        virtual void setCanvasSize( const vigra::Size2D & /*size*/)
+        {
+        }
+        virtual void setXResolution( float /*xres*/ )
+        {
+        }
+        virtual void setYResolution( float /*yres*/ )
+        {
+        }
+
+        typedef ArrayVector<unsigned char> ICCProfile;
+
+        virtual void setICCProfile(const ICCProfile & /* data */)
+        {
+        }
+
+        virtual void * currentScanlineOfBand( unsigned int ) = 0;
+        virtual void nextScanline() = 0;
+
+        struct TIFFCompressionException {};
+    };
+
+    // codec factory for registration at the codec manager
+
+    struct CodecFactory
+    {
+        virtual CodecDesc getCodecDesc() const = 0;
+        virtual VIGRA_UNIQUE_PTR<Decoder> getDecoder() const = 0;
+        virtual VIGRA_UNIQUE_PTR<Encoder> getEncoder() const = 0;
+        virtual ~CodecFactory() {};
+    };
+
+    // factory functions to encapsulate the codec managers
+    //
+    // codecs are selected according to the following order:
+    // - (if provided) the FileType
+    // - (in case of decoders) the file's magic string
+    // - the filename extension
+
+    VIGRA_EXPORT VIGRA_UNIQUE_PTR<Decoder>
+    getDecoder( const std::string &, const std::string & = "undefined", unsigned int = 0 );
+
+    VIGRA_EXPORT VIGRA_UNIQUE_PTR<Encoder>
+    getEncoder( const std::string &, const std::string & = "undefined", const std::string & = "w" );
+
+    VIGRA_EXPORT std::string
+    getEncoderType( const std::string &, const std::string & = "undefined" );
+
+    // functions to query the capabilities of certain codecs
+
+    VIGRA_EXPORT std::vector<std::string> queryCodecPixelTypes( const std::string & );
+
+    VIGRA_EXPORT bool negotiatePixelType( std::string const & codecname,
+                 std::string const & srcPixeltype, std::string & destPixeltype);
+
+    VIGRA_EXPORT bool isPixelTypeSupported( const std::string &, const std::string & );
+
+    VIGRA_EXPORT bool isBandNumberSupported( const std::string &, int bands );
+}
+
+#endif // VIGRA_CODEC_HXX
diff --git a/include/vigra/colorconversions.hxx b/include/vigra/colorconversions.hxx
new file mode 100644
index 0000000..0fd7739
--- /dev/null
+++ b/include/vigra/colorconversions.hxx
@@ -0,0 +1,3420 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_COLORCONVERSIONS_HXX
+#define VIGRA_COLORCONVERSIONS_HXX
+
+#include <cmath>
+#include <string>
+#include "mathutil.hxx"
+#include "rgbvalue.hxx"
+#include "functortraits.hxx"
+
+namespace vigra {
+
+namespace detail
+{
+
+template<class ValueType>
+inline ValueType gammaCorrection(double value, double gamma)
+{
+    typedef typename NumericTraits<ValueType>::RealPromote Promote;
+    return NumericTraits<ValueType>::fromRealPromote(
+              RequiresExplicitCast<Promote>::cast(
+                (value < 0.0) 
+                    ? -std::pow(-value, gamma) 
+                    : std::pow(value, gamma)));
+}
+
+template<class ValueType>
+inline ValueType gammaCorrection(double value, double gamma, double norm)
+{
+    typedef typename NumericTraits<ValueType>::RealPromote Promote;
+    return NumericTraits<ValueType>::fromRealPromote(
+              RequiresExplicitCast<Promote>::cast(
+                (value < 0.0) 
+                    ? -norm*std::pow(-value/norm, gamma)
+                    : norm*std::pow(value/norm, gamma)));
+}
+
+template<class ValueType>
+inline ValueType sRGBCorrection(double value, double norm)
+{
+    value /= norm;
+    typedef typename NumericTraits<ValueType>::RealPromote Promote;
+    return NumericTraits<ValueType>::fromRealPromote(
+              RequiresExplicitCast<Promote>::cast(
+                (value <= 0.0031308) 
+                    ? norm*12.92*value 
+                    : norm*(1.055*std::pow(value, 0.41666666666666667) - 0.055)));
+}
+
+template<class ValueType>
+inline ValueType inverse_sRGBCorrection(double value, double norm)
+{
+    value /= norm;
+    typedef typename NumericTraits<ValueType>::RealPromote Promote;
+    return NumericTraits<ValueType>::fromRealPromote(
+             RequiresExplicitCast<Promote>::cast(
+                (value <= 0.04045) 
+                    ? norm*value / 12.92
+                    : norm*VIGRA_CSTD::pow((value + 0.055)/1.055, 2.4)));
+}
+
+
+} // namespace detail
+
+/** \defgroup ColorConversions  Color Space Conversions
+
+    Convert between RGB, sRGB, R'G'B', XYZ, L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, and Y'UV color spaces.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    <UL>
+    <LI> <b>RGB/sRGB/R'G'B'</b><br>
+        <em>linear and non-linear (gamma corrected) additive color</em>
+        <p>
+        <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref vigra::RGB2sRGBFunctor
+        <LI> \ref vigra::sRGB2RGBFunctor
+        <LI> \ref vigra::RGB2RGBPrimeFunctor
+        <LI> \ref vigra::RGBPrime2RGBFunctor
+        </UL><p>
+    <LI> <b>XYZ</b><br>
+        <em>device independent color representation 
+               (according to Publication CIE  No  15.2 "Colorimetry"
+                and ITU-R Recommendation BT.709)</em>
+        <p>
+        <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref vigra::RGB2XYZFunctor
+        <LI> \ref vigra::RGBPrime2XYZFunctor
+        <LI> \ref vigra::XYZ2RGBFunctor
+        <LI> \ref vigra::XYZ2RGBPrimeFunctor
+        </UL><p>
+    <LI> <b>L*a*b* </b><br>
+        <em>perceptually uniform color representation 
+               (according to Publication CIE No 15.2 "Colorimetry" and
+               ITU-R Recommendation BT.709)</em>
+        <p>
+        <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref vigra::RGB2LabFunctor
+        <LI> \ref vigra::RGBPrime2LabFunctor
+        <LI> \ref vigra::XYZ2LabFunctor
+        <LI> \ref vigra::Lab2RGBFunctor
+        <LI> \ref vigra::Lab2RGBPrimeFunctor
+        <LI> \ref vigra::Lab2XYZFunctor
+        <LI> \ref polar2Lab()
+        <LI> \ref lab2Polar()
+        </UL><p>
+    <LI> <b>L*u*v* </b><br>
+        <em>perceptually uniform color representation 
+               (according to Publication CIE No 15.2 "Colorimetry" and
+               ITU-R Recommendation BT.709)</em>
+        <p>
+        <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref vigra::RGB2LuvFunctor
+        <LI> \ref vigra::RGBPrime2LuvFunctor
+        <LI> \ref vigra::XYZ2LuvFunctor
+        <LI> \ref vigra::Luv2RGBFunctor
+        <LI> \ref vigra::Luv2RGBPrimeFunctor
+        <LI> \ref vigra::Luv2XYZFunctor
+        <LI> \ref polar2Luv()
+        <LI> \ref luv2Polar()
+        </UL><p>
+    <LI> <b>Y'PbPr and Y'CbCr </b><br>
+        <em>color difference coding
+                (according to ITU-R Recommendation BT. 601)</em>
+        <p>
+        <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref vigra::RGBPrime2YPrimePbPrFunctor
+        <LI> \ref vigra::YPrimePbPr2RGBPrimeFunctor
+        <LI> \ref polar2YPrimePbPr()
+        <LI> \ref yPrimePbPr2Polar()
+        <LI> \ref vigra::RGBPrime2YPrimeCbCrFunctor
+        <LI> \ref vigra::YPrimeCbCr2RGBPrimeFunctor
+        <LI> \ref polar2YPrimeCbCr()
+        <LI> \ref yPrimeCbCr2Polar()
+        </UL><p>
+    <LI> <b>Y'UV and Y'IQ </b><br>
+        <em>analog video coding according to NTSC and PAL standards</em>
+        <p>
+        <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref vigra::RGBPrime2YPrimeUVFunctor
+        <LI> \ref vigra::YPrimeUV2RGBPrimeFunctor
+        <LI> \ref polar2YPrimeUV()
+        <LI> \ref yPrimeUV2Polar()
+        <LI> \ref vigra::RGBPrime2YPrimeIQFunctor
+        <LI> \ref vigra::YPrimeIQ2RGBPrimeFunctor
+        <LI> \ref polar2YPrimeIQ()
+        <LI> \ref yPrimeIQ2Polar()
+        </UL><p>
+    </UL>
+    
+    \anchor _details
+    This module provides conversion from RGB/R'G'B' into more perceptually uniform
+    color spaces. In image analysis, colors are usually converted into another color space 
+    in order to get good estimates of perceived color differences by just calculating 
+    Euclidean distances between the transformed colors. The L*a*b* and L*u*v* were 
+    designed with exactly this application in mind and thus give the best results. But these
+    conversions are also the most computationally demanding. The Y'PbPr color difference
+    space (designed for coding digital video) is computationally much cheaper, and 
+    almost as good. Y'CbCr represents essentially the same transformation, but the color values 
+    are scaled so that they can be stored with 8 bits per channel with minimal loss of 
+    information. The other transformations are of lesser interest here: XYZ is a device independent
+    (but not perceptually uniform) color representation, and Y'IQ and Y'UV are the color 
+    spaces used by the PAL and NTSC analog video standards. Detailed information about
+    these color spaces and their transformations can be found in 
+    <a href="http://www.poynton.com/ColorFAQ.html">Charles Poynton's Color FAQ</a>
+    
+    When you want to perform a color conversion, you must first know in which
+    color space the data are given. Although this sounds trivial, it is
+    quite often done wrong, because the distinction between RGB and sRGB (still images) or R'G'B' 
+    (digital video) is frequently overlooked: nowadays, most still images are stored in
+    sRGB space, and treating them as RGB leads to wrong results (although the color primaries
+    are named the same). RGB and R'G'B' are related by a so called <em>gamma correction</em>:
+    
+    \f[
+        C' = C_{max} \left(\frac{C_{RGB}}{C_{max}} \right)^{0.45} \qquad
+    \f]
+    
+    where C represents one of the color channels R, G, and B, and \f$ C_{max} \f$ usually equals 255. 
+    The sRGB color space realizes a slight enhancement of this definition:
+    
+    \f[
+        C_{sRGB} = \left\{\begin{array}{ll}
+        12.92\,C_{RGB} & \textrm{ if }\frac{C_{RGB}}{C_{max}} \le 0.00304 \\
+        C_{max}\left( 1.055 \left(\frac{C_{RGB}}{C_{max}}\right)^{1/2.4}-0.055\right) & \textrm{ otherwise}
+        \end{array} \right.
+    \f]
+    
+    sRGB has now become a widely accepted international standard (IEC 61966-2.1) which is used by most 
+    consumer products (digital cameras, printers, and screens). In practice, you can 
+    distinguish between linear and gamma-corrected red, green, and blue by displaying the images: if they look
+    too dark, they are probably RGB, if they are OK, they are likely sRGB. (However, there are still a few older 
+    graphics cards and display programs which silently apply an additional gamma correction to every image, 
+    so that RGB appears correct and sRGB is too bright.) Whether or not the data are represented
+    in the sRGB color space can also be seen in the color space tag of an image's EXIF data, if available.
+    
+    The distinction between RGB and R'G'B' is important because some conversions start at 
+    RGB (XYZ, L*a*b*, L*u*v*), while others start at R'G'B' (Y'PbPr, Y'CbCr, Y'IQ, and Y'UV). 
+    The names of VIGRA's color conversion functors always make clear to which color space 
+    they must be applied.
+   
+    In addition VIGRA provides a <em>\ref PolarColors "polar coordinate interface"</em>
+    to several color spaces (L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, and Y'UV). This
+    interface makes use of the fact that these color spaces are conceptually similar:
+    they represent colors by a "brightness" coordinate (L* or Y') and a pair of 
+    "chromaticity" coordinates that span a plane of colors with equal brightness.
+    The polar representation transforms chroma coordinates into a color "angle"
+    (similar to hue in the HSV system) and a "saturation". The polar coordinates are 
+    normalized so that a color angle of 0 degrees is always associated with red
+    (green is at about 120 degrees, blue at about 240 degrees - exact values differ
+    between color spaces). A saturation of 1 is the highest saturation that any RGB color 
+    in the unit cube can have after transformation into the respective color space, 
+    and saturation 0 corresponds to gray. Polar coordinates provide a more intuitive 
+    interface to color specification by users and make different color spaces somewhat 
+    comparable.
+*/
+//@{
+
+
+/** \brief Convert linear (raw) RGB into non-linear (gamma corrected) R'G'B'.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the transformation
+    
+    \f[
+        R' = R_{max} \left(\frac{R}{R_{max}} \right)^{0.45} \qquad
+        G' = G_{max} \left(\frac{G}{G_{max}} \right)^{0.45} \qquad
+        B' = B_{max} \left(\frac{B}{B_{max}} \right)^{0.45}
+    \f]
+    
+    By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
+    in the constructor. If both source and target colors components are stored 
+    as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+    */
+template <class From, class To = From>
+class RGB2RGBPrimeFunctor
+{
+  public:
+  
+        /** the functor's argument type
+        */
+    typedef TinyVector<From, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<To, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<To, 3> value_type;
+  
+        /** the result component's promote type
+        */
+    typedef typename NumericTraits<To>::RealPromote component_type;
+    
+        /** Default constructor.
+            The maximum value for each RGB component defaults to 255
+        */
+    RGB2RGBPrimeFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGB2RGBPrimeFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & rgb) const
+    {
+        return TinyVector<To, 3>(
+            detail::gammaCorrection<To>(rgb[0], 0.45, max_),
+            detail::gammaCorrection<To>(rgb[1], 0.45, max_),
+            detail::gammaCorrection<To>(rgb[2], 0.45, max_));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB'";
+    }
+    
+  private:
+    component_type max_;    
+};
+
+template <>
+class RGB2RGBPrimeFunctor<unsigned char, unsigned char>
+{
+    unsigned char lut_[256];
+        
+  public:
+  
+    typedef TinyVector<unsigned char, 3> argument_type;
+    
+    typedef TinyVector<unsigned char, 3> result_type;
+    
+    typedef TinyVector<unsigned char, 3> value_type;
+    
+    RGB2RGBPrimeFunctor()
+    {
+        for(int i=0; i<256; ++i)
+        {
+            lut_[i] = detail::gammaCorrection<unsigned char>(i, 0.45, 255.0);
+        }
+    }
+    
+    RGB2RGBPrimeFunctor(double max)
+    {
+        for(int i=0; i<256; ++i)
+        {
+            lut_[i] = detail::gammaCorrection<unsigned char>(i, 0.45, max);
+        }
+    }
+    
+    template <class V>
+    TinyVector<unsigned char, 3> operator()(V const & rgb) const
+    {
+        return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB'";
+    }
+};
+
+template <class From, class To>
+class FunctorTraits<RGB2RGBPrimeFunctor<From, To> >
+: public FunctorTraitsBase<RGB2RGBPrimeFunctor<From, To> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert linear (raw) RGB into standardized sRGB.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The sRGB color space is a slight improvement over the R'G'B' space. It is now a widely accepted 
+    international standard (IEC 61966-2.1) which is used by most consumer products
+    (digital cameras, printers, and screens). The functor realizes the transformation
+    
+    \f[
+        C_{sRGB} = \left\{ \begin{array}{ll}
+        12.92\,C_{RGB} & \textrm{ if }\frac{C_{RGB}}{C_{max}} \le 0.0031308 \\
+        C_{max}\left( 1.055 \left(\frac{C_{RGB}}{C_{max}}\right)^{1/2.4}-0.055\right) & \textrm{ otherwise}
+        \end{array}  \right.
+    \f]
+    
+    where C is any of the primaries R, G, and B. By default, \f$ C_{max} = 255 \f$ (this default can be
+    overridden in the constructor). If both source and target color components are stored
+    as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+    */
+template <class From, class To = From>
+class RGB2sRGBFunctor
+{
+  public:
+  
+        /** the functor's argument type
+        */
+    typedef TinyVector<From, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<To, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<To, 3> value_type;
+  
+        /** the result component's promote type
+        */
+    typedef typename NumericTraits<To>::RealPromote component_type;
+    
+        /** Default constructor.
+            The maximum value for each RGB component defaults to 255
+        */
+    RGB2sRGBFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGB2sRGBFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & rgb) const
+    {
+        return TinyVector<To, 3>(
+            detail::sRGBCorrection<To>(rgb[0], max_),
+            detail::sRGBCorrection<To>(rgb[1], max_),
+            detail::sRGBCorrection<To>(rgb[2], max_));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "sRGB";
+    }
+    
+  private:
+    component_type max_;    
+};
+
+template <>
+class RGB2sRGBFunctor<unsigned char, unsigned char>
+{
+    unsigned char lut_[256];
+        
+  public:
+  
+    typedef TinyVector<unsigned char, 3> argument_type;
+    
+    typedef TinyVector<unsigned char, 3> result_type;
+    
+    typedef TinyVector<unsigned char, 3> value_type;
+    
+    RGB2sRGBFunctor()
+    {
+        for(int i=0; i<256; ++i)
+        {
+            lut_[i] = detail::sRGBCorrection<unsigned char>(i, 255.0);
+        }
+    }
+    
+    RGB2sRGBFunctor(double max)
+    {
+        for(int i=0; i<256; ++i)
+        {
+            lut_[i] = detail::sRGBCorrection<unsigned char>(i, max);
+        }
+    }
+    
+    template <class V>
+    TinyVector<unsigned char, 3> operator()(V const & rgb) const
+    {
+        return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "sRGB";
+    }
+};
+
+template <class From, class To>
+class FunctorTraits<RGB2sRGBFunctor<From, To> >
+: public FunctorTraitsBase<RGB2sRGBFunctor<From, To> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert non-linear (gamma corrected) R'G'B' into non-linear (raw) RGB.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the transformation
+    
+    \f[
+        R = R_{max} \left(\frac{R'}{R_{max}} \right)^{1/0.45} \qquad
+        G = G_{max} \left(\frac{G'}{G_{max}} \right)^{1/0.45} \qquad
+        B = B_{max} \left(\frac{B'}{B_{max}} \right)^{1/0.45}
+    \f]
+    
+    By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
+    in the constructor. If both source and target color components are stored 
+    as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class From, class To = From>
+class RGBPrime2RGBFunctor
+{
+  public:
+  
+        /** the functor's argument type
+        */
+    typedef TinyVector<From, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<To, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<To, 3> value_type;
+  
+        /** the result component's promote type
+        */
+    typedef typename NumericTraits<To>::RealPromote component_type;
+    
+        /** Default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    RGBPrime2RGBFunctor()
+    : max_(255.0), gamma_(1.0/0.45)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGBPrime2RGBFunctor(component_type max)
+    : max_(max), gamma_(1.0/0.45)
+    {}
+    
+        /** apply the transformation
+        */
+    result_type operator()(argument_type const & rgb) const
+    {
+        return TinyVector<To, 3>(
+            detail::gammaCorrection<To>(rgb[0], gamma_, max_),
+            detail::gammaCorrection<To>(rgb[1], gamma_, max_),
+            detail::gammaCorrection<To>(rgb[2], gamma_, max_));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB";
+    }
+
+  private:
+    component_type max_;
+    double gamma_;
+};
+
+template <>
+class RGBPrime2RGBFunctor<unsigned char, unsigned char>
+{    
+    unsigned char lut_[256];
+        
+  public:
+  
+    typedef TinyVector<unsigned char, 3> argument_type;
+    
+    typedef TinyVector<unsigned char, 3> result_type;
+    
+    typedef TinyVector<unsigned char, 3> value_type;
+    
+    RGBPrime2RGBFunctor()
+    {
+        for(int i=0; i<256; ++i)
+        {
+            lut_[i] = detail::gammaCorrection<unsigned char>(i, 1.0/0.45, 255.0);
+        }
+    }
+    
+    RGBPrime2RGBFunctor(double max)
+    {
+        for(int i=0; i<256; ++i)
+        {
+            lut_[i] = detail::gammaCorrection<unsigned char>(i, 1.0/0.45, max);
+        }
+    }
+    
+    template <class V>
+    TinyVector<unsigned char, 3> operator()(V const & rgb) const
+    {
+        return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB";
+    }
+};
+
+template <class From, class To>
+class FunctorTraits<RGBPrime2RGBFunctor<From, To> >
+: public FunctorTraitsBase<RGBPrime2RGBFunctor<From, To> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert standardized sRGB into non-linear (raw) RGB.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The sRGB color space is a slight improvement over the R'G'B' space. Is is now a widely accepted 
+    international standard (IEC 61966-2.1) which is used by most consumer products
+    (digital cameras, printers, and screens). The functor realizes the transformation
+    
+    \f[
+        C_{RGB} = \left\{\begin{array}{ll}
+        C_{sRGB} / 12.92 & \textrm{if }\frac{C_{sRGB}}{C_{max}} \le 0.04045 \\
+        C_{max}\left( \frac{C_{sRGB}/C_{max}+0.055}{1.055}\right)^{2.4} & \textrm{otherwise}
+        \end{array}\right.
+    \f]
+    
+    where C is one of the color channels R, G, or B, and \f$ C_{max}\f$ equals 255 by default (This default 
+    can be overridden in the constructor). If both source and target color components are stored 
+    as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class From, class To = From>
+class sRGB2RGBFunctor
+{
+  public:
+  
+        /** the functor's argument type
+        */
+    typedef TinyVector<From, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<To, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<To, 3> value_type;
+  
+        /** the result component's promote type
+        */
+    typedef typename NumericTraits<To>::RealPromote component_type;
+    
+        /** Default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    sRGB2RGBFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    sRGB2RGBFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    result_type operator()(argument_type const & rgb) const
+    {
+        return TinyVector<To, 3>(
+            detail::inverse_sRGBCorrection<To>(rgb[0], max_),
+            detail::inverse_sRGBCorrection<To>(rgb[1], max_),
+            detail::inverse_sRGBCorrection<To>(rgb[2], max_));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB";
+    }
+
+  private:
+    component_type max_;
+};
+
+template <>
+class sRGB2RGBFunctor<unsigned char, unsigned char>
+{    
+    unsigned char lut_[256];
+        
+  public:
+  
+    typedef TinyVector<unsigned char, 3> argument_type;
+    
+    typedef TinyVector<unsigned char, 3> result_type;
+    
+    typedef TinyVector<unsigned char, 3> value_type;
+    
+    sRGB2RGBFunctor()
+    {
+        for(int i=0; i<256; ++i)
+        {
+            lut_[i] = detail::inverse_sRGBCorrection<unsigned char>(i, 255.0);
+        }
+    }
+    
+    sRGB2RGBFunctor(double max)
+    {
+        for(int i=0; i<256; ++i)
+        {
+            lut_[i] = detail::inverse_sRGBCorrection<unsigned char>(i, max);
+        }
+    }
+    
+    template <class V>
+    TinyVector<unsigned char, 3> operator()(V const & rgb) const
+    {
+        return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB";
+    }
+};
+
+template <class From, class To>
+class FunctorTraits<sRGB2RGBFunctor<From, To> >
+: public FunctorTraitsBase<sRGB2RGBFunctor<From, To> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert linear (raw) RGB into standardized tri-stimulus XYZ.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    According to ITU-R Recommendation BT.709, the functor realizes the transformation
+    
+    \f[
+        \begin{array}{rcl}
+        X & = & 0.412453\enspace R / R_{max} + 0.357580\enspace G / G_{max} + 0.180423\enspace B / B_{max}\\
+        Y & = & 0.212671\enspace R / R_{max} + 0.715160\enspace G / G_{max} + 0.072169\enspace B / B_{max} \\
+        Z & = & 0.019334\enspace R / R_{max} + 0.119193\enspace G / G_{max} + 0.950227\enspace B / B_{max}
+        \end{array}
+    \f]
+    
+    By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
+    in the constructor. X, Y, and Z are always positive and reach their maximum for white. 
+    The white point is obtained by transforming RGB(255, 255, 255). It corresponds to the 
+    D65 illuminant. Y represents the <em>luminance</em> ("brightness") of the color. The above
+    transformation is officially defined in connection with the sRGB color space (i.e. when the RGB values
+    are obtained by inverse gamma correction of sRGB), other color spaces use slightly different numbers
+    or another standard illuminant (which gives raise to significantly different numbers).
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class RGB2XYZFunctor
+{
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<component_type, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<component_type, 3> value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    RGB2XYZFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGB2XYZFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    result_type operator()(argument_type const & rgb) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type red = rgb[0] / max_;
+        component_type green = rgb[1] / max_;
+        component_type blue = rgb[2] / max_;
+        result_type result;
+        result[0] = Convert::cast(0.412453*red + 0.357580*green + 0.180423*blue);
+        result[1] = Convert::cast(0.212671*red + 0.715160*green + 0.072169*blue);
+        result[2] = Convert::cast(0.019334*red + 0.119193*green + 0.950227*blue);
+        return result;
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "XYZ";
+    }
+
+  private:
+    component_type max_;
+};
+
+template <class T>
+class FunctorTraits<RGB2XYZFunctor<T> >
+: public FunctorTraitsBase<RGB2XYZFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert non-linear (gamma corrected) R'G'B' into standardized tri-stimulus XYZ.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the transformation
+    
+    \f[
+        R'G'B' \Rightarrow RGB \Rightarrow XYZ
+    \f]
+    
+    See vigra::RGBPrime2RGBFunctor and vigra::RGB2XYZFunctor for a description of the two 
+    steps.
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class RGBPrime2XYZFunctor
+{
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<component_type, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<component_type, 3> value_type;
+    
+        /** default constructor
+            The maximum value for each RGB component defaults to 255.
+        */
+    RGBPrime2XYZFunctor()
+    : gamma_(1.0/ 0.45), max_(component_type(255.0))
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGBPrime2XYZFunctor(component_type max)
+    : gamma_(1.0/ 0.45), max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    result_type operator()(argument_type const & rgb) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type red = detail::gammaCorrection<component_type>(rgb[0]/max_, gamma_);
+        component_type green = detail::gammaCorrection<component_type>(rgb[1]/max_, gamma_);
+        component_type blue = detail::gammaCorrection<component_type>(rgb[2]/max_, gamma_);
+        result_type result;
+        result[0] = Convert::cast(0.412453*red + 0.357580*green + 0.180423*blue);
+        result[1] = Convert::cast(0.212671*red + 0.715160*green + 0.072169*blue);
+        result[2] = Convert::cast(0.019334*red + 0.119193*green + 0.950227*blue);
+        return result;
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "XYZ";
+    }
+
+  private:
+    double gamma_;
+    component_type max_;
+};
+
+template <class T>
+class FunctorTraits<RGBPrime2XYZFunctor<T> >
+: public FunctorTraitsBase<RGBPrime2XYZFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert standardized tri-stimulus XYZ into linear (raw) RGB.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    According to ITU-R Recommendation BT.709, the functor realizes the transformation
+    
+    \f[
+        \begin{array}{rcl}
+        R & = & R_{max} (3.2404813432\enspace X - 1.5371515163\enspace Y - 0.4985363262\enspace Z) \\
+        G & = & G_{max} (-0.9692549500\enspace X + 1.8759900015\enspace Y + 0.0415559266\enspace Z) \\
+        B & = & B_{max} (0.0556466391\enspace X - 0.2040413384\enspace Y + 1.0573110696\enspace Z)
+        \end{array}
+    \f]
+    
+    By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
+    in the constructor. This is the inverse transform of vigra::RGB2XYZFunctor.
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class XYZ2RGBFunctor
+{
+    typedef typename NumericTraits<T>::RealPromote component_type;
+    
+    component_type max_;
+    
+  public:
+        /** the functor's argument type. (Actually, the argument type
+            is more general: <TT>V</TT> with arbitrary
+            <TT>V</TT>. But this cannot be expressed in a typedef.)
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<T, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<T, 3> value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    XYZ2RGBFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    XYZ2RGBFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & xyz) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type red   = Convert::cast( 3.2404813432*xyz[0] - 1.5371515163*xyz[1] - 0.4985363262*xyz[2]);
+        component_type green = Convert::cast(-0.9692549500*xyz[0] + 1.8759900015*xyz[1] + 0.0415559266*xyz[2]);
+        component_type blue  = Convert::cast( 0.0556466391*xyz[0] - 0.2040413384*xyz[1] + 1.0573110696*xyz[2]);
+        return value_type(NumericTraits<T>::fromRealPromote(red * max_),
+                          NumericTraits<T>::fromRealPromote(green * max_),
+                          NumericTraits<T>::fromRealPromote(blue * max_));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB";
+    }
+};
+
+template <class T>
+class FunctorTraits<XYZ2RGBFunctor<T> >
+: public FunctorTraitsBase<XYZ2RGBFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert standardized tri-stimulus XYZ into non-linear (gamma corrected) R'G'B'.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the transformation
+    
+    \f[
+        XYZ \Rightarrow RGB \Rightarrow R'G'B'
+    \f]
+    
+    See vigra::XYZ2RGBFunctor and vigra::RGB2RGBPrimeFunctor for a description of the two 
+    steps.
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class XYZ2RGBPrimeFunctor
+{
+    typedef typename NumericTraits<T>::RealPromote component_type;
+    
+    double gamma_;
+    component_type max_;
+    
+  public:
+  
+  public:
+        /** the functor's argument type. (actually, the argument type
+            can be any vector type with the same interface. 
+            But this cannot be expressed in a typedef.)
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<T, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<T, 3> value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    XYZ2RGBPrimeFunctor()
+    : gamma_(0.45), max_(component_type(255.0))
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    XYZ2RGBPrimeFunctor(component_type max)
+    : gamma_(0.45), max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & xyz) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type red   = Convert::cast( 3.2404813432*xyz[0] - 1.5371515163*xyz[1] - 0.4985363262*xyz[2]);
+        component_type green = Convert::cast(-0.9692549500*xyz[0] + 1.8759900015*xyz[1] + 0.0415559266*xyz[2]);
+        component_type blue  = Convert::cast( 0.0556466391*xyz[0] - 0.2040413384*xyz[1] + 1.0573110696*xyz[2]);
+        return value_type(NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(red, gamma_) * max_),
+                          NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(green, gamma_) * max_),
+                          NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(blue, gamma_) * max_));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB'";
+    }
+};
+
+template <class T>
+class FunctorTraits<XYZ2RGBPrimeFunctor<T> >
+: public FunctorTraitsBase<XYZ2RGBPrimeFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*u*v*.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the transformation
+    
+    \f[
+        \begin{array}{rcl}
+        L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\
+        & & \\
+        L^{*} & = & 903.3\enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\
+        & & \\
+        
+        u' & = & \frac{4 X}{X+15 Y + 3 Z}, \quad 
+             v' = \frac{9 Y}{X+15 Y + 3 Z}\\
+        & & \\
+        u^{*} & = & 13 L^{*} (u' - u_n'), \quad v^{*} = 13 L^{*} (v' - v_n')
+        \end{array}
+    \f]
+    
+    where \f$(X_n, Y_n, Z_n) = (0.950456, 1.0, 1.088754)\f$ is the reference white point of standard illuminant D65, 
+    and \f$u_n' = 0.197839, v_n'=0.468342\f$ are the quantities \f$u', v'\f$ calculated for this point. 
+    \f$L^{*}\f$ represents the <em>lightness</em> ("brightness") of the color, and \f$u^{*}, v^{*}\f$ code the 
+    chromaticity. (Instead of the rationals \f$\frac{216}{24389}\f$ and \f$\frac{24389}{27}\f$, the original standard gives the
+    rounded values 0.008856 and 903.3. As <a href="http://www.brucelindbloom.com/index.html?LContinuity.html">Bruce Lindbloom</a> 
+    points out, the rounded values give raise to a discontinuity which is removed by the accurate rationals. This bug will be fixed 
+    in future versions of the CIE Luv standard.)
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class XYZ2LuvFunctor
+{
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<component_type, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<component_type, 3> value_type;
+    
+    XYZ2LuvFunctor()
+    : gamma_(1.0/3.0),
+      kappa_(24389.0/27.0),
+      epsilon_(216.0/24389.0)
+    {}
+    
+    template <class V>
+    result_type operator()(V const & xyz) const
+    {
+        result_type result;
+        if(xyz[1] == NumericTraits<T>::zero())
+        {
+            result[0] = NumericTraits<component_type>::zero();
+            result[1] = NumericTraits<component_type>::zero();
+            result[2] = NumericTraits<component_type>::zero();
+        }
+        else
+        {
+            typedef detail::RequiresExplicitCast<component_type> Convert;
+            component_type L = Convert::cast(
+                                  xyz[1] < epsilon_
+                                      ? kappa_ * xyz[1]
+                                      : 116.0 * VIGRA_CSTD::pow((double)xyz[1], gamma_) - 16.0);
+            component_type denom = Convert::cast(xyz[0] + 15.0*xyz[1] + 3.0*xyz[2]);
+            component_type uprime = Convert::cast(4.0 * xyz[0] / denom);
+            component_type vprime = Convert::cast(9.0 * xyz[1] / denom);
+            result[0] = L;
+            result[1] = Convert::cast(13.0*L*(uprime - 0.197839));
+            result[2] = Convert::cast(13.0*L*(vprime - 0.468342));
+        }
+        return result;
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "Luv";
+    }
+
+  private:
+    double gamma_, kappa_, epsilon_;
+};
+
+template <class T>
+class FunctorTraits<XYZ2LuvFunctor<T> >
+: public FunctorTraitsBase<XYZ2LuvFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert perceptual uniform CIE L*u*v* into standardized tri-stimulus XYZ.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the inverse of the transformation described in vigra::XYZ2LuvFunctor
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class Luv2XYZFunctor
+{
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<component_type, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<component_type, 3> value_type;
+    
+    Luv2XYZFunctor()
+    : gamma_(3.0),
+      ikappa_(27.0/24389.0)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & luv) const
+    {
+        result_type result;
+        if(luv[0] == NumericTraits<T>::zero())
+        {
+            result[0] = NumericTraits<component_type>::zero();
+            result[1] = NumericTraits<component_type>::zero();
+            result[2] = NumericTraits<component_type>::zero();
+        }
+        else
+        {
+            typedef detail::RequiresExplicitCast<component_type> Convert;
+            component_type uprime = Convert::cast(luv[1] / 13.0 / luv[0] + 0.197839);
+            component_type vprime = Convert::cast(luv[2] / 13.0 / luv[0] + 0.468342);
+
+            result[1] = Convert::cast(
+                            luv[0] < 8.0 
+                                ? luv[0] * ikappa_ 
+                                : VIGRA_CSTD::pow((luv[0] + 16.0) / 116.0, gamma_));
+            result[0] = Convert::cast(9.0*uprime*result[1] / 4.0 / vprime);
+            result[2] = Convert::cast(((9.0 / vprime - 15.0)*result[1] - result[0])/ 3.0);
+        }
+        return result;
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "XYZ";
+    }
+
+  private:
+    double gamma_, ikappa_;
+};
+
+template <class T>
+class FunctorTraits<Luv2XYZFunctor<T> >
+: public FunctorTraitsBase<Luv2XYZFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*a*b*.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the transformation
+    
+    \f[
+        \begin{array}{rcl}
+        L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \mbox{if} \quad \frac{216}{24389} < \frac{Y}{Y_n}\\
+        & & \\
+        L^{*} & = & \frac{24389}{27} \enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\
+        & & \\
+        a^{*} & = & 500 \left[ \left( \frac{X}{X_n} \right)^\frac{1}{3} - \left( \frac{Y}{Y_n} \right)^\frac{1}{3} \right] \\
+        & & \\
+        b^{*} & = & 200 \left[ \left( \frac{Y}{Y_n} \right)^\frac{1}{3} - \left( \frac{Z}{Z_n} \right)^\frac{1}{3} \right] \\
+        \end{array}
+    \f]
+    
+    where \f$(X_n, Y_n, Z_n) = (0.950456, 1.0, 1.088754)\f$ is the reference white point of standard illuminant D65. 
+    \f$L^{*}\f$ represents the <em>lightness</em> ("brightness") of the color, and \f$a^{*}, b^{*}\f$ code the 
+    chromaticity. (Instead of the rationals \f$\frac{216}{24389}\f$ and \f$\frac{24389}{27}\f$, the original standard gives the
+    rounded values 0.008856 and 903.3. As <a href="http://www.brucelindbloom.com/index.html?LContinuity.html">Bruce Lindbloom</a> 
+    points out, the rounded values give raise to a discontinuity which is removed by the accurate rationals. This bug will be fixed 
+    in future versions of the CIE Lab standard.)
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class XYZ2LabFunctor
+{
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<component_type, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<component_type, 3> value_type;
+    
+    XYZ2LabFunctor()
+    : gamma_(1.0/3.0),
+      kappa_(24389.0/27.0),
+      epsilon_(216.0/24389.0)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & xyz) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type xgamma = Convert::cast(std::pow(xyz[0] / 0.950456, gamma_));
+        component_type ygamma = Convert::cast(std::pow((double)xyz[1], gamma_));
+        component_type zgamma = Convert::cast(std::pow(xyz[2] / 1.088754, gamma_));
+        component_type L = Convert::cast(
+                              xyz[1] < epsilon_ 
+                                  ? kappa_ * xyz[1] 
+                                  : 116.0 * ygamma - 16.0);
+        result_type result;
+        result[0] = L;
+        result[1] = Convert::cast(500.0*(xgamma - ygamma));
+        result[2] = Convert::cast(200.0*(ygamma - zgamma));
+        return result;
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "Lab";
+    }
+
+  private:
+    double gamma_, kappa_, epsilon_;
+};
+
+template <class T>
+class FunctorTraits<XYZ2LabFunctor<T> >
+: public FunctorTraitsBase<XYZ2LabFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert perceptual uniform CIE L*a*b* into standardized tri-stimulus XYZ.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the inverse of the transformation described in vigra::XYZ2LabFunctor
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class Lab2XYZFunctor
+{
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<component_type, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<component_type, 3> value_type;
+    
+        /** the functor's value type
+        */
+    Lab2XYZFunctor()
+    : gamma_(3.0),
+      ikappa_(27.0/24389.0)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & lab) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type Y = Convert::cast(
+                              lab[0] < 8.0
+                                  ? lab[0] * ikappa_
+                                  : std::pow((lab[0] + 16.0) / 116.0, gamma_));
+        component_type ygamma = Convert::cast(std::pow((double)Y, 1.0 / gamma_));
+        component_type X = Convert::cast(std::pow(lab[1] / 500.0 + ygamma, gamma_) * 0.950456);
+        component_type Z = Convert::cast(std::pow(-lab[2] / 200.0 + ygamma, gamma_) * 1.088754);
+        result_type result;
+        result[0] = X;
+        result[1] = Y;
+        result[2] = Z;
+        return result;
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "XYZ";
+    }
+
+  private:
+    double gamma_, ikappa_;
+};
+
+template <class T>
+class FunctorTraits<Lab2XYZFunctor<T> >
+: public FunctorTraitsBase<Lab2XYZFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert linear (raw) RGB into perceptual uniform CIE L*u*v*.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the transformation
+    
+    \f[
+        RGB \Rightarrow XYZ \Rightarrow L^*u^*v^*
+    \f]
+    
+    See vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description of the two 
+    steps. The resulting color components will have the following bounds:
+    
+    \f[
+        \begin{array}{rcl}
+        0 \leq & L^* & \leq 100 \\
+        -83.077 \leq & u^* & \leq 175.015 \\
+        -134.101 \leq & v^* & \leq 107.393
+        \end{array}
+    \f]
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class RGB2LuvFunctor
+{
+    /*
+    L in [0, 100]
+    u in [-83.077, 175.015]
+    v in [-134.101, 107.393]
+    maximum saturation: 179.04 
+    red = [53.2406, 175.015, 37.7522]
+    */
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef typename XYZ2LuvFunctor<component_type>::result_type result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef typename XYZ2LuvFunctor<component_type>::result_type value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    RGB2LuvFunctor()
+    : rgb2xyz(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGB2LuvFunctor(component_type max)
+    : rgb2xyz(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & rgb) const
+    {
+        return xyz2luv(rgb2xyz(rgb));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "Luv";
+    }
+
+  private:
+    RGB2XYZFunctor<T> rgb2xyz;
+    XYZ2LuvFunctor<component_type> xyz2luv;
+};
+
+template <class T>
+class FunctorTraits<RGB2LuvFunctor<T> >
+: public FunctorTraitsBase<RGB2LuvFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert linear (raw) RGB into perceptual uniform CIE L*a*b*.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the transformation
+    
+    \f[
+        RGB \Rightarrow XYZ \Rightarrow L^*a^*b^*
+    \f]
+    
+    See vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description of the two 
+    steps. The resulting color components will have the following bounds:
+    
+    \f[
+        \begin{array}{rcl}
+        0 \leq & L^* & \leq 100 \\
+        -86.1813 \leq & u^* & \leq 98.2352 \\
+        -107.862 \leq & v^* & \leq 94.4758
+        \end{array}
+    \f]
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class RGB2LabFunctor
+{
+    /*
+    L in [0, 100]
+    a in [-86.1813, 98.2352]
+    b in [-107.862, 94.4758] 
+    maximum saturation: 133.809
+    red = [53.2406, 80.0942, 67.2015]
+    */
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef typename XYZ2LabFunctor<component_type>::result_type result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef typename XYZ2LabFunctor<component_type>::result_type value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    RGB2LabFunctor()
+    : rgb2xyz(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGB2LabFunctor(component_type max)
+    : rgb2xyz(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & rgb) const
+    {
+        return xyz2lab(rgb2xyz(rgb));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "Lab";
+    }
+
+  private:
+    RGB2XYZFunctor<T> rgb2xyz;
+    XYZ2LabFunctor<component_type> xyz2lab;
+};
+
+template <class T>
+class FunctorTraits<RGB2LabFunctor<T> >
+: public FunctorTraitsBase<RGB2LabFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert perceptual uniform CIE L*u*v* into linear (raw) RGB.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the inverse of the transformation described in vigra::RGB2LuvFunctor
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class Luv2RGBFunctor
+{
+    typedef typename NumericTraits<T>::RealPromote component_type;
+    
+    XYZ2RGBFunctor<T> xyz2rgb;
+    Luv2XYZFunctor<component_type> luv2xyz;
+    
+  public:
+        /** the functor's argument type. (Actually, the argument type
+            can be any vector type with the same interface. 
+            But this cannot be expressed in a typedef.)
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef typename XYZ2RGBFunctor<T>::result_type result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef typename XYZ2RGBFunctor<T>::result_type value_type;
+    
+    Luv2RGBFunctor()
+    : xyz2rgb(255.0)
+    {}
+    
+    Luv2RGBFunctor(component_type max)
+    : xyz2rgb(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & luv) const
+    {
+        return xyz2rgb(luv2xyz(luv));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB";
+    }
+};
+
+template <class T>
+class FunctorTraits<Luv2RGBFunctor<T> >
+: public FunctorTraitsBase<Luv2RGBFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert perceptual uniform CIE L*a*b* into linear (raw) RGB.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the inverse of the transformation described in vigra::RGB2LabFunctor
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class Lab2RGBFunctor
+{
+    typedef typename NumericTraits<T>::RealPromote component_type;
+    
+    XYZ2RGBFunctor<T> xyz2rgb;
+    Lab2XYZFunctor<component_type> lab2xyz;
+    
+  public:
+  
+        /** the functor's argument type. (Actually, the argument type
+            can be any vector type with the same interface. 
+            But this cannot be expressed in a typedef.)
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef typename XYZ2RGBFunctor<T>::result_type result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef typename XYZ2RGBFunctor<T>::result_type value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    Lab2RGBFunctor()
+    : xyz2rgb(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    Lab2RGBFunctor(component_type max)
+    : xyz2rgb(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & lab) const
+    {
+        return xyz2rgb(lab2xyz(lab));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB";
+    }
+};
+
+template <class T>
+class FunctorTraits<Lab2RGBFunctor<T> >
+: public FunctorTraitsBase<Lab2RGBFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*u*v*.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the transformation
+    
+    \f[
+        R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*u^*v^*
+    \f]
+    
+    See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description of the three 
+    steps. The resulting color components will have the following bounds:
+    
+    \f[
+        \begin{array}{rcl}
+        0 \leq & L^* & \leq 100 \\
+        -83.077 \leq & u^* & \leq 175.015 \\
+        -134.101 \leq & v^* & \leq 107.393
+        \end{array}
+    \f]
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class RGBPrime2LuvFunctor
+{
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef typename XYZ2LuvFunctor<component_type>::result_type result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef typename XYZ2LuvFunctor<component_type>::result_type value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    RGBPrime2LuvFunctor()
+    : rgb2xyz(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGBPrime2LuvFunctor(component_type max)
+    : rgb2xyz(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & rgb) const
+    {
+        return xyz2luv(rgb2xyz(rgb));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "Luv";
+    }
+
+  private:
+    RGBPrime2XYZFunctor<T> rgb2xyz;
+    XYZ2LuvFunctor<component_type> xyz2luv;
+};
+
+template <class T>
+class FunctorTraits<RGBPrime2LuvFunctor<T> >
+: public FunctorTraitsBase<RGBPrime2LuvFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*a*b*.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the transformation
+    
+    \f[
+        R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*a^*b^*
+    \f]
+    
+    See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description of the three 
+    steps. The resulting color components will have the following bounds:
+    
+    \f[
+        \begin{array}{rcl}
+        0 \leq & L^* & \leq 100 \\
+        -86.1813 \leq & u^* & \leq 98.2352 \\
+        -107.862 \leq & v^* & \leq 94.4758
+        \end{array}
+    \f]
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class RGBPrime2LabFunctor
+{
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef typename XYZ2LabFunctor<component_type>::result_type result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef typename XYZ2LabFunctor<component_type>::result_type value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    RGBPrime2LabFunctor()
+    : rgb2xyz(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGBPrime2LabFunctor(component_type max)
+    : rgb2xyz(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & rgb) const
+    {
+        return xyz2lab(rgb2xyz(rgb));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "Lab";
+    }
+
+  private:
+    RGBPrime2XYZFunctor<T> rgb2xyz;
+    XYZ2LabFunctor<component_type> xyz2lab;
+};
+
+template <class T>
+class FunctorTraits<RGBPrime2LabFunctor<T> >
+: public FunctorTraitsBase<RGBPrime2LabFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert perceptual uniform CIE L*u*v* into non-linear (gamma corrected) R'G'B'.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the inverse of the transformation described in vigra::RGBPrime2LuvFunctor
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class Luv2RGBPrimeFunctor
+{
+    typedef typename NumericTraits<T>::RealPromote component_type;
+    
+    XYZ2RGBPrimeFunctor<T> xyz2rgb;
+    Luv2XYZFunctor<component_type> luv2xyz;
+    
+  public:
+  
+        /** the functor's argument type. (Actually, the argument type
+            can be any vector type with the same interface. 
+            But this cannot be expressed in a typedef.)
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef typename XYZ2RGBFunctor<T>::result_type result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef typename XYZ2RGBFunctor<T>::result_type value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    Luv2RGBPrimeFunctor()
+    : xyz2rgb(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    Luv2RGBPrimeFunctor(component_type max)
+    : xyz2rgb(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & luv) const
+    {
+        return xyz2rgb(luv2xyz(luv));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB'";
+    }
+};
+
+template <class T>
+class FunctorTraits<Luv2RGBPrimeFunctor<T> >
+: public FunctorTraitsBase<Luv2RGBPrimeFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert perceptual uniform CIE L*a*b* into non-linear (gamma corrected) R'G'B'.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the inverse of the transformation described in vigra::RGBPrime2LabFunctor
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class Lab2RGBPrimeFunctor
+{
+    typedef typename NumericTraits<T>::RealPromote component_type;
+    
+    XYZ2RGBPrimeFunctor<T> xyz2rgb;
+    Lab2XYZFunctor<component_type> lab2xyz;
+    
+  public:
+  
+        /** the functor's argument type. (Actually, the argument type
+            can be any vector type with the same interface. 
+            But this cannot be expressed in a typedef.)
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef typename XYZ2RGBFunctor<T>::result_type result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef typename XYZ2RGBFunctor<T>::result_type value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    Lab2RGBPrimeFunctor()
+    : xyz2rgb(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    Lab2RGBPrimeFunctor(component_type max)
+    : xyz2rgb(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & lab) const
+    {
+        return xyz2rgb(lab2xyz(lab));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB'";
+    }
+};
+
+template <class T>
+class FunctorTraits<Lab2RGBPrimeFunctor<T> >
+: public FunctorTraitsBase<Lab2RGBPrimeFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'PbPr color difference components.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    According to ITU-R Recommendation BT.601, the functor realizes the transformation
+    
+    \f[
+        \begin{array}{rcl}
+        Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
+        Pb & = & -0.1687358916\enspace R / R_{max} + 0.3312641084\enspace G / G_{max} + 0.5\enspace B / B_{max} \\
+        Pr & = & 0.5\enspace R / R_{max} + 0.4186875892\enspace G / G_{max} + 0.0813124108\enspace B / B_{max}
+        \end{array}
+    \f]
+    
+    By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
+    in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color, and
+    Pb and Pr are the blue (B'-Y') and red (R'-Y') color difference components. 
+    The transformation is scaled so that the following bounds apply:
+    
+    \f[
+        \begin{array}{rcl}
+        0 \leq & Y' & \leq 1 \\
+        -0.5 \leq & Pb & \leq 0.5 \\
+        -0.5 \leq & Pr & \leq 0.5
+        \end{array}
+    \f]
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class RGBPrime2YPrimePbPrFunctor
+{
+    /*
+    Y in [0, 1]
+    Pb in [-0.5, 0.5]
+    Pr in [-0.5, 0.5]
+    maximum saturation: 0.533887
+    red = [0.299, -0.168736, 0.5]
+    */
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<component_type, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<component_type, 3> value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    RGBPrime2YPrimePbPrFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGBPrime2YPrimePbPrFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & rgb) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type red = rgb[0] / max_;
+        component_type green = rgb[1] / max_;
+        component_type blue = rgb[2] / max_;
+        
+        result_type result;
+        result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
+        result[1] = Convert::cast(-0.1687358916*red - 0.3312641084*green + 0.5*blue);
+        result[2] = Convert::cast(0.5*red - 0.4186875892*green - 0.0813124108*blue);
+        return result;
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "Y'PbPr";
+    }
+
+  private:
+    component_type max_;
+};
+
+template <class T>
+class FunctorTraits<RGBPrime2YPrimePbPrFunctor<T> >
+: public FunctorTraitsBase<RGBPrime2YPrimePbPrFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert Y'PbPr color difference components into non-linear (gamma corrected) R'G'B'.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimePbPrFunctor
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class YPrimePbPr2RGBPrimeFunctor
+{
+    typedef typename NumericTraits<T>::RealPromote component_type;
+    
+    component_type max_;
+    
+  public:
+  
+        /** the functor's argument type. (Actually, the argument type
+            can be any vector type with the same interface. 
+            But this cannot be expressed in a typedef.)
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<T, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<T, 3> value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    YPrimePbPr2RGBPrimeFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    YPrimePbPr2RGBPrimeFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & ypbpr) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type nred   = Convert::cast(ypbpr[0] + 1.402*ypbpr[2]);
+        component_type ngreen = Convert::cast(ypbpr[0] - 0.3441362862*ypbpr[1] - 0.7141362862*ypbpr[2]);
+        component_type nblue  = Convert::cast(ypbpr[0] + 1.772*ypbpr[1]);
+        return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
+                           NumericTraits<T>::fromRealPromote(ngreen * max_),
+                           NumericTraits<T>::fromRealPromote(nblue * max_));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB'";
+    }
+};
+
+template <class T>
+class FunctorTraits<YPrimePbPr2RGBPrimeFunctor<T> >
+: public FunctorTraitsBase<YPrimePbPr2RGBPrimeFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'IQ components.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    According to the PAL analog video standard, the functor realizes the transformation
+    
+    \f[
+        \begin{array}{rcl}
+        Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
+        I & = & 0.596\enspace R / R_{max} - 0.274\enspace G / G_{max} - 0.322\enspace B / B_{max} \\
+        Q & = & 0.212\enspace R / R_{max} - 0.523\enspace G / G_{max} + 0.311\enspace B / B_{max}
+        \end{array}
+    \f]
+    
+    By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
+    in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color. 
+    The transformation is scaled so that the following bounds apply:
+    
+    \f[
+        \begin{array}{rcl}
+        0 \leq & Y' & \leq 1 \\
+        -0.596 \leq & I & \leq 0.596 \\
+        -0.523 \leq & Q & \leq 0.523
+        \end{array}
+    \f]
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class RGBPrime2YPrimeIQFunctor
+{
+    /*
+    Y in [0, 1]
+    I in [-0.596, 0.596]
+    Q in [-0.523, 0.523]
+    maximum saturation: 0.632582
+    red = [0.299, 0.596, 0.212]
+    */
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<component_type, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<component_type, 3> value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    RGBPrime2YPrimeIQFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGBPrime2YPrimeIQFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & rgb) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type red = rgb[0] / max_;
+        component_type green = rgb[1] / max_;
+        component_type blue = rgb[2] / max_;
+        
+        result_type result;
+        result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
+        result[1] = Convert::cast(0.596*red - 0.274*green - 0.322*blue);
+        result[2] = Convert::cast(0.212*red - 0.523*green + 0.311*blue);
+        return result;
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "Y'IQ";
+    }
+
+  private:
+    component_type max_;
+};
+
+template <class T>
+class FunctorTraits<RGBPrime2YPrimeIQFunctor<T> >
+: public FunctorTraitsBase<RGBPrime2YPrimeIQFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert Y'IQ color components into non-linear (gamma corrected) R'G'B'.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeIQFunctor
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class YPrimeIQ2RGBPrimeFunctor
+{
+    typedef typename NumericTraits<T>::RealPromote component_type;
+    
+    component_type max_;
+    
+  public:
+  
+        /** the functor's argument type. (Actually, the argument type
+            can be any vector type with the same interface. 
+            But this cannot be expressed in a typedef.)
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<T, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<T, 3> value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    YPrimeIQ2RGBPrimeFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    YPrimeIQ2RGBPrimeFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & yiq) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type nred   = Convert::cast(yiq[0] + 0.9548892043*yiq[1] + 0.6221039350*yiq[2]);
+        component_type ngreen = Convert::cast(yiq[0] - 0.2713547827*yiq[1] - 0.6475120259*yiq[2]);
+        component_type nblue  = Convert::cast(yiq[0] - 1.1072510054*yiq[1] + 1.7024603738*yiq[2]);
+        return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
+                           NumericTraits<T>::fromRealPromote(ngreen * max_),
+                           NumericTraits<T>::fromRealPromote(nblue * max_));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB'";
+    }
+};
+
+template <class T>
+class FunctorTraits<YPrimeIQ2RGBPrimeFunctor<T> >
+: public FunctorTraitsBase<YPrimeIQ2RGBPrimeFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'UV components.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    According to the NTSC analog video standard, the functor realizes the transformation
+    
+    \f[
+        \begin{array}{rcl}
+        Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
+        U & = & -0.147\enspace R / R_{max} - 0.289\enspace G / G_{max} + 0.436\enspace B / B_{max} \\
+        V & = & 0.615\enspace R / R_{max} - 0.515\enspace G / G_{max} - 0.100\enspace B / B_{max}
+        \end{array}
+    \f]
+    
+    By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
+    in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color. 
+    The transformation is scaled so that the following bounds apply:
+    
+    \f[
+        \begin{array}{rcl}
+        0 \leq & Y' & \leq 1 \\
+        -0.436 \leq & U & \leq 0.436 \\
+        -0.615 \leq & V & \leq 0.615
+        \end{array}
+    \f]
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class RGBPrime2YPrimeUVFunctor
+{
+    /*
+    Y in [0, 1]
+    U in [-0.436, 0.436]
+    V in [-0.615, 0.615]
+    maximum saturation: 0.632324
+    red = [0.299, -0.147, 0.615]
+    */
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<component_type, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<component_type, 3> value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    RGBPrime2YPrimeUVFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGBPrime2YPrimeUVFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & rgb) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type red = rgb[0] / max_;
+        component_type green = rgb[1] / max_;
+        component_type blue = rgb[2] / max_;
+        
+        result_type result;
+        result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
+        result[1] = Convert::cast(-0.1471376975*red - 0.2888623025*green + 0.436*blue);
+        result[2] = Convert::cast(0.6149122807*red - 0.5149122807*green - 0.100*blue);
+        return result;
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "Y'UV";
+    }
+
+  private:
+    component_type max_;
+};
+
+template <class T>
+class FunctorTraits<RGBPrime2YPrimeUVFunctor<T> >
+: public FunctorTraitsBase<RGBPrime2YPrimeUVFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert Y'UV color components into non-linear (gamma corrected) R'G'B'.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeUVFunctor
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class YPrimeUV2RGBPrimeFunctor
+{
+    typedef typename NumericTraits<T>::RealPromote component_type;
+    
+    component_type max_;
+    
+  public:
+  
+        /** the functor's argument type. (Actually, the argument type
+            can be any vector type with the same interface. 
+            But this cannot be expressed in a typedef.)
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<T, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<T, 3> value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    YPrimeUV2RGBPrimeFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    YPrimeUV2RGBPrimeFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & yuv) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type nred   = Convert::cast(yuv[0] + 1.140*yuv[2]);
+        component_type ngreen = Convert::cast(yuv[0] - 0.3946517044*yuv[1] - 0.580681431*yuv[2]);
+        component_type nblue  = Convert::cast(yuv[0] + 2.0321100920*yuv[1]);
+        return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
+                           NumericTraits<T>::fromRealPromote(ngreen * max_),
+                           NumericTraits<T>::fromRealPromote(nblue * max_));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB'";
+    }
+};
+
+template <class T>
+class FunctorTraits<YPrimeUV2RGBPrimeFunctor<T> >
+: public FunctorTraitsBase<YPrimeUV2RGBPrimeFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'CbCr color difference components.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    This functor basically applies the same transformation as vigra::RGBPrime2YPrimePbPrFunctor
+    but the color components are scaled so that they can be coded as 8 bit integers with
+    minimal loss of information:
+    
+    \f[
+        \begin{array}{rcl}
+        16\leq & Y' & \leq 235 \\
+        16 \leq & Cb & \leq 240 \\
+        16 \leq & Cr & \leq 240
+        \end{array}
+    \f]
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class RGBPrime2YPrimeCbCrFunctor
+{
+    /*
+    Y in [16, 235]
+    Cb in [16, 240]
+    Cr in [16, 240]
+    maximum saturation: 119.591
+    red = [81.481, 90.203, 240]
+    */
+  public:
+  
+        /** the result's component type
+        */
+    typedef typename NumericTraits<T>::RealPromote component_type;
+
+        /** the functor's argument type
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<component_type, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<component_type, 3> value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    RGBPrime2YPrimeCbCrFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    RGBPrime2YPrimeCbCrFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & rgb) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type red = rgb[0] / max_;
+        component_type green = rgb[1] / max_;
+        component_type blue = rgb[2] / max_;
+        
+        result_type result;
+        result[0] = Convert::cast(16.0 + 65.481*red + 128.553*green + 24.966*blue);
+        result[1] = Convert::cast(128.0 - 37.79683972*red - 74.20316028*green + 112.0*blue);
+        result[2] = Convert::cast(128.0 + 112.0*red - 93.78601998*green - 18.21398002*blue);
+        return result;
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "Y'CbCr";
+    }
+
+  private:
+    component_type max_;
+};
+
+template <class T>
+class FunctorTraits<RGBPrime2YPrimeCbCrFunctor<T> >
+: public FunctorTraitsBase<RGBPrime2YPrimeCbCrFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief Convert Y'CbCr color difference components into non-linear (gamma corrected) R'G'B'.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeCbCrFunctor
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+*/
+template <class T>
+class YPrimeCbCr2RGBPrimeFunctor
+{
+    typedef typename NumericTraits<T>::RealPromote component_type;
+    
+    component_type max_;
+    
+  public:
+  
+        /** the functor's argument type. (Actually, the argument type
+            can be any vector type with the same interface. 
+            But this cannot be expressed in a typedef.)
+        */
+    typedef TinyVector<T, 3> argument_type;
+  
+        /** the functor's result type
+        */
+    typedef TinyVector<T, 3> result_type;
+  
+        /** \deprecated use argument_type and result_type
+        */
+    typedef TinyVector<T, 3> value_type;
+    
+        /** default constructor.
+            The maximum value for each RGB component defaults to 255.
+        */
+    YPrimeCbCr2RGBPrimeFunctor()
+    : max_(255.0)
+    {}
+    
+        /** constructor
+            \arg max - the maximum value for each RGB component
+        */
+    YPrimeCbCr2RGBPrimeFunctor(component_type max)
+    : max_(max)
+    {}
+    
+        /** apply the transformation
+        */
+    template <class V>
+    result_type operator()(V const & ycbcr) const
+    {
+        typedef detail::RequiresExplicitCast<component_type> Convert;
+        component_type y  = Convert::cast(ycbcr[0] - 16.0);
+        component_type cb = Convert::cast(ycbcr[1] - 128.0);
+        component_type cr = Convert::cast(ycbcr[2] - 128.0);
+        
+        component_type nred   = Convert::cast(0.00456621*y + 0.006258928571*cr);
+        component_type ngreen = Convert::cast(0.00456621*y - 0.001536322706*cb - 0.003188108420*cr);
+        component_type nblue  = Convert::cast(0.00456621*y + 0.007910714286*cb);
+        return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
+                           NumericTraits<T>::fromRealPromote(ngreen * max_),
+                           NumericTraits<T>::fromRealPromote(nblue * max_));
+    }
+    
+    static std::string targetColorSpace()
+    {
+        return "RGB'";
+    }
+};
+
+template <class T>
+class FunctorTraits<YPrimeCbCr2RGBPrimeFunctor<T> >
+: public FunctorTraitsBase<YPrimeCbCr2RGBPrimeFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+//@}
+
+/*
+Polar coordinates of standard colors:
+=====================================
+
+Lab: black = [320.002, 0, 0]
+Luv: black = [347.827, 0, 0]
+YPbPr: black = [341.352, 0, 0]
+YCbCr: black = [341.352, 0, 0]
+YIQ: black = [19.5807, 0, 0]
+YUV: black = [346.557, 0, 0]
+Lab: red = [1.20391e-05, 0.532406, 0.781353]
+Luv: red = [360, 0.532406, 1]
+YPbPr: red = [360, 0.299, 0.988419]
+YCbCr: red = [360, 0.299, 0.988417]
+YIQ: red = [360, 0.299, 1]
+YUV: red = [360, 0.299, 1]
+Lab: green = [96.0184, 0.877351, 0.895108]
+Luv: green = [115.552, 0.877351, 0.758352]
+YPbPr: green = [123.001, 0.587, 1]
+YCbCr: green = [123.001, 0.587, 0.999996]
+YIQ: green = [137.231, 0.587, 0.933362]
+YUV: green = [137.257, 0.587, 0.933931]
+Lab: blue = [266.287, 0.322957, 0.999997]
+Luv: blue = [253.7, 0.322957, 0.729883]
+YPbPr: blue = [242.115, 0.114, 0.948831]
+YCbCr: blue = [242.115, 0.114, 0.948829]
+YIQ: blue = [243.585, 0.114, 0.707681]
+YUV: blue = [243.639, 0.114, 0.707424]
+Lab: yellow = [62.8531, 0.971395, 0.724189]
+Luv: yellow = [73.7, 0.971395, 0.597953]
+YPbPr: yellow = [62.1151, 0.886, 0.948831]
+YCbCr: yellow = [62.1149, 0.886, 0.948829]
+YIQ: yellow = [63.5851, 0.886, 0.707681]
+YUV: yellow = [63.6393, 0.886, 0.707424]
+Lab: magenta = [288.237, 0.603235, 0.863482]
+Luv: magenta = [295.553, 0.603235, 0.767457]
+YPbPr: magenta = [303.001, 0.413, 1]
+YCbCr: magenta = [303.001, 0.413, 0.999996]
+YIQ: magenta = [317.231, 0.413, 0.933362]
+YUV: magenta = [317.257, 0.413, 0.933931]
+Lab: cyan = [156.378, 0.911133, 0.374577]
+Luv: cyan = [180, 0.911133, 0.402694]
+YPbPr: cyan = [180, 0.701, 0.988419]
+YCbCr: cyan = [180, 0.701, 0.988417]
+YIQ: cyan = [180, 0.701, 1]
+YUV: cyan = [180, 0.701, 1]
+Lab: white = [320.002, 1, 0]
+Luv: white = [14.3606, 1, 3.26357e-06]
+YPbPr: white = [341.352, 1, 0]
+YCbCr: white = [341.352, 1, 0]
+YIQ: white = [154.581, 1, 1.24102e-16]
+YUV: white = [229.992, 1, 9.81512e-17]
+
+*/
+
+/** \ingroup ColorConversions
+    \defgroup PolarColors Polar Color Coordinates
+    
+    Transform colors from/to a polar representation (hue, brightness, saturation).
+    In many situations, this is more intuitive than direct initialization in a 
+    particular color space. The polar coordinates are 
+    normalized so that a color angle of 0 degrees is always associated with red
+    (green is at about 120 degrees, blue at about 240 degrees - exact values differ
+    between color spaces). A saturation of 1 is the highest saturation that any RGB color 
+    gets after transformation into the respective color space, and saturation 0 corresponds to
+    gray. Thus, different color spaces become somewhat comparable.
+*/
+//@{
+/** \brief Init L*a*b* color triple from polar representation.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    <b> Declarations:</b>
+    
+    \code
+    TinyVector<float, 3>
+    polar2Lab(double color, double brightness, double saturation);
+    
+    TinyVector<float, 3>
+    polar2Lab(TinyVector<float, 3> const & polar);
+    \endcode
+    
+    \arg color - the color angle in degrees
+    \arg brightness - between 0 and 1
+    \arg saturation - between 0 and 1
+    
+    L*a*b* polar coordinates of some important colors:
+    
+    \code
+    black   = [*, 0, 0]    * - arbitrary
+    white   = [*, 1, 0]    * - arbitrary
+    
+    red     = [      0, 0.532406, 0.781353]
+    yellow  = [62.8531, 0.971395, 0.724189]
+    green   = [96.0184, 0.877351, 0.895108]
+    cyan    = [156.378, 0.911133, 0.374577]
+    blue    = [266.287, 0.322957, 0.999997]
+    magenta = [288.237, 0.603235, 0.863482]
+    \endcode
+*/
+inline TinyVector<float, 3>
+polar2Lab(double color, double brightness, double saturation)
+{
+    double angle = (color+39.9977)/180.0*M_PI;
+    double normsat = saturation*133.809;
+    
+    TinyVector<float, 3> result;
+    result[0] = float(100.0*brightness);
+    result[1] = float(normsat*VIGRA_CSTD::cos(angle));
+    result[2] = float(normsat*VIGRA_CSTD::sin(angle));
+    return result;
+}
+
+
+template <class V>
+TinyVector<float, 3>
+polar2Lab(V const & polar)
+{
+    return polar2Lab(polar[0], polar[1], polar[2]);
+}
+
+/** \brief Create polar representation form L*a*b*
+
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        TinyVector<float, 3> lab2Polar(TinyVector<float, 3> const & lab);
+    }
+    \endcode
+    
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    This realizes the inverse of the transformation described in 
+    \ref polar2Lab().
+*/
+template <class V>
+TinyVector<float, 3>
+lab2Polar(V const & lab)
+{
+    TinyVector<float, 3> result;
+    result[1] = float(lab[0]/100.0);
+    double angle = (lab[1] == 0.0 && lab[2] == 0.0)
+        ? 0.0
+        : VIGRA_CSTD::atan2(lab[2], lab[1])/M_PI*180.0-39.9977;
+    result[0] = angle < 0.0 ?
+                    float(angle + 360.0) :
+                    float(angle);
+    result[2] = float(VIGRA_CSTD::sqrt(lab[1]*lab[1] + lab[2]*lab[2])/133.809);
+    return result;
+}
+
+/** \brief Init L*u*v* color triple from polar representation.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    <b> Declarations:</b>
+    
+    \code
+    TinyVector<float, 3>
+    polar2Luv(double color, double brightness, double saturation);
+    
+    TinyVector<float, 3>
+    polar2Luv(TinyVector<float, 3> const & polar);
+    \endcode
+    
+    \arg color - the color angle in degrees
+    \arg brightness - between 0 and 1
+    \arg saturation - between 0 and 1
+    
+    L*u*v* polar coordinates of some important colors:
+    
+    \code
+    black   = [*, 0, 0]    * - arbitrary
+    white   = [*, 1, 0]    * - arbitrary
+    
+    red     = [      0, 0.532406,        1]
+    yellow  = [   73.7, 0.971395, 0.597953]
+    green   = [115.552, 0.877351, 0.758352]
+    cyan    = [  180.0, 0.911133, 0.402694]
+    blue    = [  253.7, 0.322957, 0.729883]
+    magenta = [295.553, 0.603235, 0.767457]
+    \endcode
+*/
+inline TinyVector<float, 3>
+polar2Luv(double color, double brightness, double saturation)
+{
+    double angle = (color+12.1727)/180.0*M_PI;
+    double normsat = saturation*179.04;
+    
+    TinyVector<float, 3> result;
+    result[0] = float(100.0*brightness);
+    result[1] = float(normsat*VIGRA_CSTD::cos(angle));
+    result[2] = float(normsat*VIGRA_CSTD::sin(angle));
+    return result;
+}
+
+template <class V>
+TinyVector<float, 3>
+polar2Luv(V const & polar)
+{
+    return polar2Luv(polar[0], polar[1], polar[2]);
+}
+
+/** \brief Create polar representation form L*u*v*
+
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        TinyVector<float, 3> luv2Polar(TinyVector<float, 3> const & luv);
+    }
+    \endcode
+    
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    This realizes the inverse of the transformation described in 
+    \ref polar2Luv().
+*/
+template <class V>
+TinyVector<float, 3>
+luv2Polar(V const & luv)
+{
+    TinyVector<float, 3> result;
+    result[1] = float(luv[0]/100.0);
+    double angle = (luv[1] == 0.0 && luv[2] == 0.0)
+        ? 0.0
+        : VIGRA_CSTD::atan2(luv[2], luv[1])/M_PI*180.0-12.1727;
+    result[0] = angle < 0.0 ?
+                    float(angle + 360.0) :
+                    float(angle);
+    result[2] = float(VIGRA_CSTD::sqrt(luv[1]*luv[1] + luv[2]*luv[2])/179.04);
+    return result;
+}
+
+/** \brief Init Y'PbPr color triple from polar representation.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    <b> Declarations:</b>
+    
+    \code
+    TinyVector<float, 3>
+    polar2YPrimePbPr(double color, double brightness, double saturation);
+    
+    TinyVector<float, 3>
+    polar2YPrimePbPr(TinyVector<float, 3> const & polar);
+    \endcode
+    
+    \arg color - the color angle in degrees
+    \arg brightness - between 0 and 1
+    \arg saturation - between 0 and 1
+    
+    Y'PbPr polar coordinates of some important colors:
+    
+    \code
+    black   = [*, 0, 0]    * - arbitrary
+    white   = [*, 1, 0]    * - arbitrary
+    
+    red     = [      0,  0.299, 0.988419]
+    yellow  = [62.1151,  0.886, 0.948831]
+    green   = [123.001,  0.587,        1]
+    cyan    = [  180.0,  0.701, 0.988419]
+    blue    = [242.115,  0.114, 0.948831]
+    magenta = [303.001,  0.413,        1]
+    \endcode
+*/
+inline TinyVector<float, 3>
+polar2YPrimePbPr(double color, double brightness, double saturation)
+{
+    double angle = (color+18.6481)/180.0*M_PI;
+    double normsat = saturation*0.533887;
+    
+    TinyVector<float, 3> result;
+    result[0] = float(brightness);
+    result[1] = float(-normsat*VIGRA_CSTD::sin(angle));
+    result[2] = float(normsat*VIGRA_CSTD::cos(angle));
+    return result;
+}
+
+template <class V>
+TinyVector<float, 3>
+polar2YPrimePbPr(V const & polar)
+{
+    return polar2YPrimePbPr(polar[0], polar[1], polar[2]);
+}
+
+/** \brief Create polar representation form Y'PbPr
+
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        TinyVector<float, 3> yPrimePbPr2Polar(TinyVector<float, 3> const & ypbpr);
+    }
+    \endcode
+    
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    This realizes the inverse of the transformation described in 
+    \ref polar2YPrimePbPr().
+*/
+template <class V>
+TinyVector<float, 3>
+yPrimePbPr2Polar(V const & ypbpr)
+{
+    TinyVector<float, 3> result;
+    result[1] = float(ypbpr[0]);
+    double angle = (ypbpr[1] == 0.0 && ypbpr[2] == 0.0)
+        ? 0.0
+        : VIGRA_CSTD::atan2(-ypbpr[1], ypbpr[2])/M_PI*180.0-18.6481;
+    result[0] = angle < 0.0 ?
+                    float(angle + 360.0) :
+                    float(angle);
+    result[2] = float(VIGRA_CSTD::sqrt(ypbpr[1]*ypbpr[1] + ypbpr[2]*ypbpr[2])/0.533887);
+    return result;
+}
+
+/** \brief Init Y'CbCr color triple from polar representation.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    <b> Declarations:</b>
+    
+    \code
+    TinyVector<float, 3>
+    polar2YPrimeCbCr(double color, double brightness, double saturation);
+    
+    TinyVector<float, 3>
+    polar2YPrimeCbCr(TinyVector<float, 3> const & polar);
+    \endcode
+    
+    \arg color - the color angle in degrees
+    \arg brightness - between 0 and 1
+    \arg saturation - between 0 and 1
+    
+    Y'CbCr polar coordinates of some important colors:
+    
+    \code
+    black   = [*, 0, 0]    * - arbitrary
+    white   = [*, 1, 0]    * - arbitrary
+    
+    red     = [      0,  0.299, 0.988419]
+    yellow  = [62.1151,  0.886, 0.948831]
+    green   = [123.001,  0.587,        1]
+    cyan    = [  180.0,  0.701, 0.988419]
+    blue    = [242.115,  0.114, 0.948831]
+    magenta = [303.001,  0.413,        1]
+    \endcode
+*/
+inline TinyVector<float, 3>
+polar2YPrimeCbCr(double color, double brightness, double saturation)
+{
+    double angle = (color+18.6482)/180.0*M_PI;
+    double normsat = saturation*119.591;
+    
+    TinyVector<float, 3> result;
+    result[0] = float(brightness*219.0 + 16.0);
+    result[1] = float(-normsat*VIGRA_CSTD::sin(angle)+128.0);
+    result[2] = float(normsat*VIGRA_CSTD::cos(angle)+128.0);
+    return result;
+}
+
+template <class V>
+TinyVector<float, 3>
+polar2YPrimeCbCr(V const & polar)
+{
+    return polar2YPrimeCbCr(polar[0], polar[1], polar[2]);
+}
+
+/** \brief Create polar representation form Y'CbCr
+
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        TinyVector<float, 3> yPrimeCbCr2Polar(TinyVector<float, 3> const & ycbcr);
+    }
+    \endcode
+    
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    This realizes the inverse of the transformation described in 
+    \ref polar2YPrimeCbCr().
+*/
+template <class V>
+TinyVector<float, 3>
+yPrimeCbCr2Polar(V const & ycbcr)
+{
+    TinyVector<float, 3> result;
+    result[1] = float((ycbcr[0]-16.0)/219.0);
+    double cb = ycbcr[1]-128.0;
+    double cr = ycbcr[2]-128.0;
+    double angle = (cb == 0.0 && cr == 0.0)
+        ? 0.0
+        : VIGRA_CSTD::atan2(-cb, cr)/M_PI*180.0-18.6482;
+    result[0] = angle < 0.0 ?
+                    float(angle + 360.0) :
+                    float(angle);
+    result[2] = float(VIGRA_CSTD::sqrt(cb*cb + cr*cr)/119.591);
+    return result;
+}
+
+/** \brief Init Y'IQ color triple from polar representation.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    <b> Declarations:</b>
+    
+    \code
+    TinyVector<float, 3>
+    polar2YPrimeIQ(double color, double brightness, double saturation);
+    
+    TinyVector<float, 3>
+    polar2YPrimeIQ(TinyVector<float, 3> const & polar);
+    \endcode
+    
+    \arg color - the color angle in degrees
+    \arg brightness - between 0 and 1
+    \arg saturation - between 0 and 1
+    
+    Y'IQ polar coordinates of some important colors:
+    
+    \code
+    black   = [*, 0, 0]    * - arbitrary
+    white   = [*, 1, 0]    * - arbitrary
+    
+    red     = [      0, 0.299,        1]
+    yellow  = [63.5851, 0.886, 0.707681]
+    green   = [137.231, 0.587, 0.933362]
+    cyan    = [  180.0, 0.701,        1]
+    blue    = [243.585, 0.114, 0.707681]
+    magenta = [317.231, 0.413, 0.933362]
+    \endcode
+*/
+inline TinyVector<float, 3>
+polar2YPrimeIQ(double color, double brightness, double saturation)
+{
+    double angle = (color-19.5807)/180.0*M_PI;
+    double normsat = saturation*0.632582;
+    
+    TinyVector<float, 3> result;
+    result[0] = float(brightness);
+    result[1] = float(normsat*VIGRA_CSTD::cos(angle));
+    result[2] = float(-normsat*VIGRA_CSTD::sin(angle));
+    return result;
+}
+
+template <class V>
+TinyVector<float, 3>
+polar2YPrimeIQ(V const & polar)
+{
+    return polar2YPrimeIQ(polar[0], polar[1], polar[2]);
+}
+
+/** \brief Create polar representation form Y'IQ
+
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        TinyVector<float, 3> yPrimeIQ2Polar(TinyVector<float, 3> const & yiq);
+    }
+    \endcode
+    
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    This realizes the inverse of the transformation described in 
+    \ref polar2YPrimeIQ().
+*/
+template <class V>
+TinyVector<float, 3>
+yPrimeIQ2Polar(V const & yiq)
+{
+    TinyVector<float, 3> result;
+    result[1] = float(yiq[0]);
+    double angle = (yiq[1] == 0.0 && yiq[2] == 0.0)
+        ? 0.0
+        : VIGRA_CSTD::atan2(-yiq[2], yiq[1])/M_PI*180.0+19.5807;
+    result[0] = angle < 0.0 ?
+                    float(angle + 360.0) :
+                    float(angle);
+    result[2] = float(VIGRA_CSTD::sqrt(yiq[1]*yiq[1] + yiq[2]*yiq[2])/0.632582);
+    return result;
+}
+
+/** \brief Init Y'UV color triple from polar representation.
+
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    <b> Declarations:</b>
+    
+    \code
+    TinyVector<float, 3>
+    polar2YPrimeUV(double color, double brightness, double saturation);
+    
+    TinyVector<float, 3>
+    polar2YPrimeUV(TinyVector<float, 3> const & polar);
+    \endcode
+    
+    \arg color - the color angle in degrees
+    \arg brightness - between 0 and 1
+    \arg saturation - between 0 and 1
+    
+    Y'UV polar coordinates of some important colors:
+    
+    \code
+    black   = [*, 0, 0]    * - arbitrary
+    white   = [*, 1, 0]    * - arbitrary
+    
+    red     = [      0, 0.299,        1]
+    yellow  = [63.5851, 0.886, 0.707681]
+    green   = [137.231, 0.587, 0.933362]
+    cyan    = [  180.0, 0.701,        1]
+    blue    = [243.585, 0.114, 0.707681]
+    magenta = [317.231, 0.413, 0.933362]
+    \endcode
+*/
+inline TinyVector<float, 3>
+polar2YPrimeUV(double color, double brightness, double saturation)
+{
+    double angle = (color+13.4569)/180.0*M_PI;
+    double normsat = saturation*0.632324;
+    
+    TinyVector<float, 3> result;
+    result[0] = float(brightness);
+    result[1] = float(-normsat*VIGRA_CSTD::sin(angle));
+    result[2] = float(normsat*VIGRA_CSTD::cos(angle));
+    return result;
+}
+
+template <class V>
+TinyVector<float, 3>
+polar2YPrimeUV(V const & polar)
+{
+    return polar2YPrimeUV(polar[0], polar[1], polar[2]);
+}
+
+/** \brief Create polar representation form Y'UV
+
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        TinyVector<float, 3> yPrimeUV2Polar(TinyVector<float, 3> const & yuv);
+    }
+    \endcode
+    
+    <b>\#include</b> \<vigra/colorconversions.hxx\><br>
+    Namespace: vigra
+    
+    This realizes the inverse of the transformation described in 
+    \ref polar2YPrimeUV().
+*/
+template <class V>
+TinyVector<float, 3>
+yPrimeUV2Polar(V const & yuv)
+{
+    TinyVector<float, 3> result;
+    result[1] = float(yuv[0]);
+    double angle = (yuv[1] == 0.0 && yuv[2] == 0.0)
+        ? 0.0
+        : VIGRA_CSTD::atan2(-yuv[1], yuv[2])/M_PI*180.0-13.4569;
+    result[0] = angle < 0.0 ?
+                    float(angle + 360.0) :
+                    float(angle);
+    result[2] = float(VIGRA_CSTD::sqrt(yuv[1]*yuv[1] + yuv[2]*yuv[2])/0.632324);
+    return result;
+}
+
+//@}
+
+} // namespace vigra 
+
+#endif /* VIGRA_COLORCONVERSIONS_HXX */
diff --git a/include/vigra/combineimages.hxx b/include/vigra/combineimages.hxx
new file mode 100644
index 0000000..44a6c63
--- /dev/null
+++ b/include/vigra/combineimages.hxx
@@ -0,0 +1,814 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_COMBINEIMAGES_HXX
+#define VIGRA_COMBINEIMAGES_HXX
+
+#include "utilities.hxx"
+#include "numerictraits.hxx"
+#include "functortraits.hxx"
+#include "multi_shape.hxx"
+
+#include <cmath>
+
+namespace vigra {
+
+/** \addtogroup CombineAlgo Algorithms to Combine Images
+
+    Apply functor to calculate a pixelwise transformation depending on multiple images.
+    Note that the binary functors of the STL may be used with these functions.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                    combine...Lines                   */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator1, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class DestIterator, class DestAccessor, class Functor>
+void
+combineTwoLines(SrcIterator1 s1, 
+                SrcIterator1 s1end, SrcAccessor1 src1,
+                SrcIterator2 s2, SrcAccessor2 src2,
+                DestIterator d, DestAccessor dest,
+                Functor const & f)
+{
+    for(; s1 != s1end; ++s1, ++s2, ++d)
+        dest.set(f(src1(s1), src2(s2)), d);
+}
+
+template <class SrcIterator1, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class MaskIterator, class MaskAccessor, 
+          class DestIterator, class DestAccessor, class Functor>
+void
+combineTwoLinesIf(SrcIterator1 s1, 
+                  SrcIterator1 s1end, SrcAccessor1 src1,
+                  SrcIterator2 s2, SrcAccessor2 src2,
+                  MaskIterator m, MaskAccessor mask,
+                  DestIterator d, DestAccessor dest,
+                  Functor const & f)
+{
+    for(; s1 != s1end; ++s1, ++s2, ++m, ++d)
+        if(mask(m))
+            dest.set(f(src1(s1), src2(s2)), d);
+}
+
+template <class SrcIterator1, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class SrcIterator3, class SrcAccessor3,
+          class DestIterator, class DestAccessor, class Functor>
+void
+combineThreeLines(SrcIterator1 s1, 
+                  SrcIterator1 s1end, SrcAccessor1 src1,
+                  SrcIterator2 s2, SrcAccessor2 src2,
+                  SrcIterator3 s3, SrcAccessor3 src3,
+                  DestIterator d, DestAccessor dest,
+                  Functor const & f)
+{
+    for(; s1 != s1end; ++s1, ++s2, ++s3, ++d)
+        dest.set(f(src1(s1), src2(s2), src3(s3)), d);
+}
+
+/********************************************************/
+/*                                                      */
+/*                    combineTwoImages                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Combine two source images into destination image.
+
+    After the introduction of arithmetic and algebraic \ref MultiMathModule "array experessions",
+    this function is rarely needed. Moreover, \ref combineTwoMultiArrays() provides the 
+    same functionality for arbitrary dimensional arrays.
+
+    The transformation given by the functor is applied to the source 
+    pixels and the result written into the corresponding destination pixel.
+    This is typically used for operations like add and subtract.
+    Note that the binary functors of the STL can be used in addition to
+    the functors specifically defined in \ref CombineFunctor.
+    Creation of new functors is easiest by using \ref FunctorExpressions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T11, class S11,
+                  class T12, class S12,
+                  class T2, class S2,
+                  class Functor>
+        void
+        combineTwoImages(MultiArrayView<2, T11, S11> const & src1,
+                         MultiArrayView<2, T12, S12> const & src2,
+                         MultiArrayView<2, T2, S2> dest,
+                         Functor const & f);
+    }
+    \endcode
+    
+    \deprecatedAPI{combineTwoImages}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator1, class SrcAccessor1,
+              class SrcImageIterator2, class SrcAccessor2,
+              class DestImageIterator, class DestAccessor,
+              class Functor>
+        void
+        combineTwoImages(SrcImageIterator1 src1_upperleft, 
+                 SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
+                 SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
+                 DestImageIterator dest_upperleft, DestAccessor da,
+                 Functor const & f)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator1, class SrcAccessor1,
+              class SrcImageIterator2, class SrcAccessor2,
+              class DestImageIterator, class DestAccessor,
+              class Functor>
+        void
+        combineTwoImages(triple<SrcImageIterator1, SrcImageIterator1, SrcAccessor1> src1,
+                 pair<SrcImageIterator2, SrcAccessor2> src2,
+                 pair<DestImageIterator, DestAccessor> dest,
+                 Functor const & f)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/combineimages.hxx\><br>
+    Namespace: vigra
+
+    \code
+    #include <functional>     // for plus
+    MultiArray<2, float> src1(width, height), src2(width, height),
+                         dest(width, height);
+    ... // fill source images 
+    
+    combineTwoImages(src1, src2, dest,
+                     std::plus<float>());
+    \endcode
+
+    \deprecatedUsage{combineTwoImages}
+    \code
+    #include <functional>     // for plus
+    FImage src1(width, height), src2(width, height),
+           dest(width, height);
+    ... // fill source images 
+    
+    vigra::combineTwoImages(
+                srcIterRange(src1.upperLeft(), src1.lowerRight()), 
+                srcIter(src2.upperLeft()), 
+                destIter(dest.upperLeft()),  
+                std::plus<float>());
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator1 src1_upperleft, src1_lowerright;
+    SrcImageIterator2 src2_upperleft;
+    DestImageIterator dest_upperleft;
+    SrcImageIterator1::row_iterator sx1 = src1_upperleft.rowIterator();
+    SrcImageIterator2::row_iterator sx2 = src2_upperleft.rowIterator();
+    DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
+    
+    SrcAccessor1 src1_accessor;
+    SrcAccessor2 src2_accessor;
+    DestAccessor dest_accessor;
+    
+    Functor functor;
+
+    dest_accessor.set(
+          functor(src1_accessor(sx1), src2_accessor(sx2)), 
+          dx);
+
+    \endcode
+    \deprecatedEnd
+    
+    \see TransformFunctor, MultiMathModule, \ref FunctorExpressions
+*/
+doxygen_overloaded_function(template <...> void combineTwoImages)
+
+template <class SrcImageIterator1, class SrcAccessor1,
+          class SrcImageIterator2, class SrcAccessor2,
+          class DestImageIterator, class DestAccessor,
+          class Functor>
+void
+combineTwoImages(SrcImageIterator1 src1_upperleft, 
+                 SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
+                 SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
+                 DestImageIterator dest_upperleft, DestAccessor da,
+                 Functor const & f)
+{
+    int w = src1_lowerright.x - src1_upperleft.x;
+    
+    for(; src1_upperleft.y < src1_lowerright.y; 
+            ++src1_upperleft.y, ++src2_upperleft.y, ++dest_upperleft.y)
+    {
+        combineTwoLines(src1_upperleft.rowIterator(), 
+                        src1_upperleft.rowIterator() + w, sa1, 
+                        src2_upperleft.rowIterator(), sa2, 
+                        dest_upperleft.rowIterator(), da, f);
+    }
+}
+    
+template <class SrcImageIterator1, class SrcAccessor1,
+          class SrcImageIterator2, class SrcAccessor2,
+          class DestImageIterator, class DestAccessor,
+          class Functor>
+inline
+void
+combineTwoImages(triple<SrcImageIterator1, SrcImageIterator1, SrcAccessor1> src1,
+                 pair<SrcImageIterator2, SrcAccessor2> src2,
+                 pair<DestImageIterator, DestAccessor> dest,
+                 Functor const & f)
+{
+    combineTwoImages(src1.first, src1.second, src1.third, 
+                     src2.first, src2.second, 
+                     dest.first, dest.second, f);
+}
+
+template <class T11, class S11,
+          class T12, class S12,
+          class T2, class S2,
+          class Functor>
+inline void
+combineTwoImages(MultiArrayView<2, T11, S11> const & src1,
+                 MultiArrayView<2, T12, S12> const & src2,
+                 MultiArrayView<2, T2, S2> dest,
+                 Functor const & f)
+{
+    vigra_precondition(src1.shape() == src2.shape() && src1.shape() == dest.shape(),
+        "combineTwoImages(): shape mismatch between inputs and/or output.");
+    combineTwoImages(srcImageRange(src1), 
+                     srcImage(src2), 
+                     destImage(dest), f);
+}
+
+/********************************************************/
+/*                                                      */
+/*                  combineTwoImagesIf                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Combine ROI of two source images into destination image.
+
+    The transformation given by the functor is applied to all source 
+    pixels in the ROI (i.e. whenever the corresponding value of the mask array
+    is non-zero)
+    and the result written into the corresponding destination pixel.
+    This is typically used for operations like add and subtract.
+    Note that the binary functors of the STL can be used in addition to
+    the functors specifically defined in \ref CombineFunctor.
+    Creation of new functors is easiest by using \ref FunctorExpressions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T11, class S11,
+                  class T12, class S12,
+                  class TM, class SM,
+                  class T2, class S2,
+                  class Functor>
+        void
+        combineTwoImagesIf(MultiArrayView<2, T11, S11> const & src1,
+                           MultiArrayView<2, T12, S12> const & src2,
+                           MultiArrayView<2, TM, SM> const & mask,
+                           MultiArrayView<2, T2, S2> dest,
+                           Functor const & f);
+    }
+    \endcode
+    
+    \deprecatedAPI{combineTwoImagesIf}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator1, class SrcAccessor1,
+              class SrcImageIterator2, class SrcAccessor2,
+              class MaskImageIterator, class MaskAccessor,
+              class DestImageIterator, clas DestAccessor,
+              class Functor>
+        void
+        combineTwoImagesIf(SrcImageIterator1 src1_upperleft, 
+                   SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
+                   SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
+                   MaskImageIterator mask_upperleft, MaskAccessor ma,
+                   DestImageIterator dest_upperleft, DestAccessor da,
+                   Functor const & f)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator1, class SrcAccessor1,
+              class SrcImageIterator2, class SrcAccessor2,
+              class MaskImageIterator, class MaskAccessor,
+              class DestImageIterator, clas DestAccessor,
+              class Functor>
+        void
+        combineTwoImagesIf(triple<SrcImageIterator1, SrcImageIterator1, SrcAccessor1> src1,
+                   pair<SrcImageIterator2, SrcAccessor2> src2,
+                   pair<MaskImageIterator, MaskAccessor> mask,
+                   pair<DestImageIterator, DestAccessor> dest,
+                   Functor const & f)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/combineimages.hxx\><br>
+    Namespace: vigra
+
+    \code
+    #include <functional>     // for plus
+    MultiArray<2, float> src1(width, height), src2(width, height), mask(width, height),
+                         dest(width, height);
+    ... // fill source and mask images 
+
+    combineTwoImagesIf(src1, src2, mask, dest,
+                       std::plus<float>());
+    \endcode
+
+    \deprecatedUsage{combineTwoImagesIf}
+    \code
+    #include <functional>     // for plus
+    FImage src1(width, height), src2(width, height), mask(width, height),
+           dest(width, height);
+    ... // fill source and mask images 
+
+    vigra::combineTwoImagesIf(
+                srcIterRange(src1.upperLeft(), src1.lowerRight()), 
+                srcIter(src2.upperLeft()), 
+                maskIter(mask.upperLeft()), 
+                destIter(dest.upperLeft()),
+                std::plus<SrcValueType>());
+    
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator1 src1_upperleft, src1_lowerright;
+    SrcImageIterator2 src2_upperleft;
+    MaskImageIterator mask_upperleft;
+    DestImageIterator dest_upperleft;
+    SrcImageIterator1::row_iterator sx1 = src1_upperleft.rowIterator();
+    SrcImageIterator2::row_iterator sx2 = src2_upperleft.rowIterator();
+    MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator();
+    DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
+    
+    
+    SrcAccessor1 src1_accessor;
+    SrcAccessor2 src2_accessor;
+    MaskAccessor mask_accessor;
+    DestAccessor dest_accessor;
+    
+    Functor functor;
+    
+    if(mask_accessor(mx))
+       dest_accessor.set(
+          functor(src1_accessor(sx1), src2_accessor(sx2)), 
+          dx);
+
+    \endcode
+    \deprecatedEnd
+    
+    \see TransformFunctor, MultiMathModule, \ref FunctorExpressions
+*/
+doxygen_overloaded_function(template <...> void combineTwoImagesIf)
+
+template <class SrcImageIterator1, class SrcAccessor1,
+          class SrcImageIterator2, class SrcAccessor2,
+          class MaskImageIterator, class MaskAccessor,
+          class DestImageIterator, class DestAccessor,
+          class Functor>
+void
+combineTwoImagesIf(SrcImageIterator1 src1_upperleft, 
+                   SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
+                   SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
+                   MaskImageIterator mask_upperleft, MaskAccessor ma,
+                   DestImageIterator dest_upperleft, DestAccessor da,
+                   Functor const & f)
+{
+    int w = src1_lowerright.x - src1_upperleft.x;
+    
+    for(; src1_upperleft.y < src1_lowerright.y;
+          ++src1_upperleft.y, ++src2_upperleft.y, 
+          ++dest_upperleft.y, ++mask_upperleft.y)
+    {
+        combineTwoLinesIf(src1_upperleft.rowIterator(), 
+                          src1_upperleft.rowIterator() + w, sa1, 
+                          src2_upperleft.rowIterator(), sa2, 
+                          mask_upperleft.rowIterator(), ma, 
+                          dest_upperleft.rowIterator(), da, f);
+    }
+}
+    
+template <class SrcImageIterator1, class SrcAccessor1,
+          class SrcImageIterator2, class SrcAccessor2,
+          class MaskImageIterator, class MaskAccessor,
+          class DestImageIterator, class DestAccessor,
+          class Functor>
+inline
+void
+combineTwoImagesIf(triple<SrcImageIterator1, SrcImageIterator1, SrcAccessor1> src1,
+                   pair<SrcImageIterator2, SrcAccessor2> src2,
+                   pair<MaskImageIterator, MaskAccessor> mask,
+                   pair<DestImageIterator, DestAccessor> dest,
+                   Functor const & f)
+{
+    combineTwoImagesIf(src1.first, src1.second, src1.third, 
+                       src2.first, src2.second, 
+                       mask.first, mask.second, 
+                       dest.first, dest.second, f);
+}
+    
+template <class T11, class S11,
+          class T12, class S12,
+          class TM, class SM,
+          class T2, class S2,
+          class Functor>
+inline void
+combineTwoImagesIf(MultiArrayView<2, T11, S11> const & src1,
+                   MultiArrayView<2, T12, S12> const & src2,
+                   MultiArrayView<2, TM, SM> const & mask,
+                   MultiArrayView<2, T2, S2> dest,
+                   Functor const & f)
+{
+    vigra_precondition(src1.shape() == src2.shape() && src1.shape() == mask.shape() && src1.shape() == dest.shape(),
+        "combineTwoImagesIf(): shape mismatch between inputs and/or output.");
+    combineTwoImagesIf(srcImageRange(src1), 
+                       srcImage(src2), 
+                       maskImage(mask), 
+                       destImage(dest), f);
+}
+
+/********************************************************/
+/*                                                      */
+/*                  combineThreeImages                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Combine three source images into destination image.
+
+    After the introduction of arithmetic and algebraic \ref MultiMathModule "array experessions",
+    this function is rarely needed. Moreover, \ref combineThreeMultiArrays() provides the 
+    same functionality for arbitrary dimensional arrays.
+
+    The transformation given by the functor is applied to the source 
+    pixels and the result written into the corresponding destination pixel.
+    Creation of new functors is easiest by using \ref FunctorExpressions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T11, class S11,
+                  class T12, class S12,
+                  class T13, class S13,
+                  class T2, class S2,
+                  class Functor>
+        void
+        combineThreeImages(MultiArrayView<2, T11, S11> const & src1,
+                           MultiArrayView<2, T12, S12> const & src2,
+                           MultiArrayView<2, T13, S13> const & src3,
+                           MultiArrayView<2, T2, S2> dest,
+                           Functor const & f);
+    }
+    \endcode
+    
+    \deprecatedAPI{combineThreeImages}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator1, class SrcAccessor1,
+              class SrcImageIterator2, class SrcAccessor2,
+              class SrcImageIterator3, class SrcAccessor3,
+              class DestImageIterator, class DestAccessor,
+              class Functor>
+        void
+        combineThreeImages(SrcImageIterator1 src1_upperleft, 
+                   SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
+                   SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
+                   SrcImageIterator3 src2_upperleft, SrcAccessor3 sa3,
+                   DestImageIterator dest_upperleft, DestAccessor da,
+                   Functor const & f)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator1, class SrcAccessor1,
+              class SrcImageIterator2, class SrcAccessor2,
+              class SrcImageIterator3, class SrcAccessor3,
+              class DestImageIterator, class DestAccessor,
+              class Functor>
+        void
+        combineThreeImages(triple<SrcImageIterator1, SrcImageIterator1, SrcAccessor1> src1,
+                 pair<SrcImageIterator2, SrcAccessor2> src2,
+                 pair<SrcImageIterator3, SrcAccessor3> src3,
+                 pair<DestImageIterator, DestAccessor> dest,
+                 Functor const & f)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/combineimages.hxx\><br>
+    Namespace: vigra
+
+    \code
+    #include <vigra/functorexpression.hxx>
+    
+    MultiArray<2, float> src1(width, height), src2(width, height), src3(width, height),
+                         dest(width, height);
+    ... // fill source images 
+    
+    using namespace vigra::functor; // activate VIGRA's lambda library
+    
+    combineThreeImages(src1, src2, src3, dest,
+                       Arg1()*exp(-abs(Arg2()-Arg3())));
+    \endcode
+
+    \deprecatedUsage{combineThreeImages}
+    \code
+    FImage src1(width, height), src2(width, height), src3(width, height),
+           dest(width, height);
+    ... // fill source images 
+    
+    vigra::combineThreeImages(
+                srcIterRange(src1.upperLeft(), src1.lowerRight()), 
+                srcIter(src2.upperLeft()), 
+                srcIter(src3.upperLeft()), 
+                destIter(dest.upperLeft()),  
+                SomeThreeArgumentFunctor());
+    
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator1 src1_upperleft, src1_lowerright;
+    SrcImageIterator2 src2_upperleft;
+    SrcImageIterator3 src3_upperleft;
+    DestImageIterator dest_upperleft;
+    SrcImageIterator1::row_iterator sx1 = src1_upperleft.rowIterator();
+    SrcImageIterator2::row_iterator sx2 = src2_upperleft.rowIterator();
+    SrcImageIterator3::row_iterator sx3 = src3_upperleft.rowIterator();
+    DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
+    
+    SrcAccessor1 src1_accessor;
+    SrcAccessor2 src2_accessor;
+    SrcAccessor3 src3_accessor;
+    DestAccessor dest_accessor;
+    
+    Functor functor;
+
+    dest_accessor.set(
+          functor(src1_accessor(sx1), 
+                  src2_accessor(sx2), 
+                  src3_accessor(sx3)), 
+          dx);
+
+    \endcode
+    \deprecatedEnd
+    
+    \see TransformFunctor, MultiMathModule, \ref FunctorExpressions
+*/
+doxygen_overloaded_function(template <...> void combineThreeImages)
+
+template <class SrcImageIterator1, class SrcAccessor1,
+          class SrcImageIterator2, class SrcAccessor2,
+          class SrcImageIterator3, class SrcAccessor3,
+          class DestImageIterator, class DestAccessor,
+          class Functor>
+void
+combineThreeImages(SrcImageIterator1 src1_upperleft, 
+                   SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
+                   SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
+                   SrcImageIterator3 src3_upperleft, SrcAccessor3 sa3,
+                   DestImageIterator dest_upperleft, DestAccessor da,
+                   Functor const & f)
+{
+    int w = src1_lowerright.x - src1_upperleft.x;
+    
+    for(; src1_upperleft.y < src1_lowerright.y;
+        ++src1_upperleft.y, ++src2_upperleft.y, ++src3_upperleft.y, 
+        ++dest_upperleft.y)
+    {
+        combineThreeLines(src1_upperleft.rowIterator(), 
+                          src1_upperleft.rowIterator() + w, sa1, 
+                          src2_upperleft.rowIterator(), sa2, 
+                          src3_upperleft.rowIterator(), sa3, 
+                          dest_upperleft.rowIterator(), da, f);
+    }
+}
+    
+template <class SrcImageIterator1, class SrcAccessor1,
+          class SrcImageIterator2, class SrcAccessor2,
+          class SrcImageIterator3, class SrcAccessor3,
+          class DestImageIterator, class DestAccessor,
+          class Functor>
+inline
+void
+combineThreeImages(triple<SrcImageIterator1, SrcImageIterator1, SrcAccessor1> src1,
+                   pair<SrcImageIterator2, SrcAccessor2> src2,
+                   pair<SrcImageIterator3, SrcAccessor3> src3,
+                   pair<DestImageIterator, DestAccessor> dest,
+                   Functor const & f)
+{
+    combineThreeImages(src1.first, src1.second, src1.third, 
+                       src2.first, src2.second, 
+                       src3.first, src3.second, 
+                       dest.first, dest.second, f);
+}
+
+template <class T11, class S11,
+          class T12, class S12,
+          class T13, class S13,
+          class T2, class S2,
+          class Functor>
+inline void
+combineThreeImages(MultiArrayView<2, T11, S11> const & src1,
+                   MultiArrayView<2, T12, S12> const & src2,
+                   MultiArrayView<2, T13, S13> const & src3,
+                   MultiArrayView<2, T2, S2> dest,
+                   Functor const & f)
+{
+    vigra_precondition(src1.shape() == src2.shape() && src1.shape() == src3.shape() && src1.shape() == dest.shape(),
+        "combineThreeImages(): shape mismatch between inputs and/or output.");
+    combineThreeImages(srcImageRange(src1), 
+                       srcImage(src2), 
+                       srcImage(src3), 
+                       destImage(dest), f);
+}
+
+    
+//@}
+
+/** \addtogroup CombineFunctor Functors to Combine Images
+
+    Common functors with several arguments
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                    MagnitudeFunctor                  */
+/*                                                      */
+/********************************************************/
+
+/** Calculate the magnitude from two arguments.
+    Can be used in conjunction with \ref gradientBasedTransform().
+    
+    If the gradient is represented by a vector-valued image instead of 
+    a pair of scalar images, use \ref vigra::VectorNormFunctor.
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isBinaryFunctor</tt> are true (<tt>VigraTrueType</tt>)    
+*/
+template <class ValueType>
+class MagnitudeFunctor
+{
+  public:
+        /** the functor's first argument type
+        */
+    typedef ValueType first_argument_type;
+    
+        /** the functor's second argument type
+        */
+    typedef ValueType second_argument_type;
+    
+        /** the functor's result type
+        */
+    typedef typename SquareRootTraits<typename NormTraits<ValueType>::SquaredNormType>::SquareRootResult result_type;
+    
+        /** \deprecated use first_argument_type, second_argument_type, result_type
+        */
+    typedef ValueType value_type;
+    
+        /** calculate transform '<TT>sqrt(squaredNorm(v1) + squaredNorm(v2))</TT>'. 
+            
+        */
+    result_type operator()(first_argument_type const & v1, second_argument_type const & v2) const
+    {
+        return VIGRA_CSTD::sqrt(squaredNorm(v1) + squaredNorm(v2));
+    }
+};
+
+template <class T>
+class FunctorTraits<MagnitudeFunctor<T> >
+: public FunctorTraitsBase<MagnitudeFunctor<T> >
+{
+public:
+    typedef VigraTrueType isBinaryFunctor;
+};
+
+/********************************************************/
+/*                                                      */
+/*             RGBGradientMagnitudeFunctor              */
+/*                                                      */
+/********************************************************/
+
+
+/** Calculate the gradient magnitude from RGB arguments.
+    Can be used in conjunction with \ref gradientBasedTransform().
+
+    <b> Traits defined:</b>
+    
+    <tt>FunctorTraits::isBinaryFunctor</tt> are true (<tt>VigraTrueType</tt>)    
+*/
+template <class ValueType>
+class RGBGradientMagnitudeFunctor
+{
+  public:
+        /** the functor's first argument type
+        */
+    typedef RGBValue<ValueType> first_argument_type;
+    
+        /** the functor's second argument type
+        */
+    typedef RGBValue<ValueType> second_argument_type;
+    
+        /** the functor's result type
+        */
+    typedef typename NumericTraits<ValueType>::RealPromote result_type;
+    
+        /** \deprecated use first_argument_type, second_argument_type, result_type
+        */
+    typedef ValueType value_type;
+    
+        /** Calculate the gradient magnitude form given RGB components.
+            The function returns 
+            
+            \f[ \sqrt{|\nabla red|^2 + |\nabla green|^2 + |\nabla blue|^2}
+            \f]
+            
+            where \f$|\nabla red|^2\f$ is defined by <TT>gx.red()*gx.red() + gy.red()*gy.red()</TT>.
+            
+            <TT>ValueType</TT> (the RGB's component type) must support addition, multiplication, 
+            abd <TT>sqrt()</TT>.
+        */
+    result_type 
+    operator()(first_argument_type const & gx, second_argument_type const & gy) const
+    {
+        return VIGRA_CSTD::sqrt(gx.red()*gx.red() + gx.green()*gx.green() +
+                    gx.blue()*gx.blue() + gy.red()*gy.red() + 
+                    gy.green()*gy.green() + gy.blue()*gy.blue());
+    }
+};
+
+template <class T>
+class FunctorTraits<RGBGradientMagnitudeFunctor<T> >
+: public FunctorTraitsBase<RGBGradientMagnitudeFunctor<T> >
+{
+public:
+    typedef VigraTrueType isBinaryFunctor;
+};
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_COMBINEIMAGES_HXX
diff --git a/include/vigra/config.hxx b/include/vigra/config.hxx
new file mode 100644
index 0000000..82e231c
--- /dev/null
+++ b/include/vigra/config.hxx
@@ -0,0 +1,273 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_CONFIG_HXX
+#define VIGRA_CONFIG_HXX
+
+#include "configVersion.hxx"
+#include <stdexcept>
+
+///////////////////////////////////////////////////////////
+//                                                       //
+//                     VisualC++                         //
+//                                                       //
+///////////////////////////////////////////////////////////
+
+#ifdef _MSC_VER
+    // make sure that we use vigra/windows.h so that incompatibilities are fixed
+    #include "windows.h"
+
+    #if(_MSC_VER < 1100)    // before VisualC++ 5.0
+        #error "Need VisualC++ 5.0, Service Pack 2, or later"
+    #endif // _MSC_VER < 1100
+
+    #if (_MSC_VER < 1300)
+        #define NO_TYPENAME         // no 'typename' keyword
+        #define TEMPLATE_COPY_CONSTRUCTOR_BUG
+        #define NO_STL_MEMBER_TEMPLATES
+        #define NO_INLINE_STATIC_CONST_DEFINITION
+        #define CMATH_NOT_IN_STD
+        #define NO_COVARIANT_RETURN_TYPES
+
+        #ifdef VIGRA_NO_STD_MINMAX  // activate if necessary
+        namespace std {
+
+        template<class T>
+        const T& min(const T& x, const T& y)
+        {
+            return (y < x)
+                ? y
+                : x;
+        }
+
+        template<class T>
+        const T& max(const T& x, const T& y)
+        {
+            return (x < y)
+                ? y
+                : x;
+        }
+        }
+        #endif // VIGRA_NO_STD_MINMAX
+    #endif // (_MSC_VER < 1300)
+
+    #if _MSC_VER < 1310
+        #pragma warning( disable : 4786 4250 4244 4305)
+
+        #define NO_PARTIAL_TEMPLATE_SPECIALIZATION
+        #define NO_OUT_OF_LINE_MEMBER_TEMPLATES
+        #include <cmath>
+
+        #ifdef _MSC_EXTENSIONS
+        #ifndef CMATH_NOT_IN_STD
+                namespace std {
+        #endif // CMATH_NOT_IN_STD
+                inline double abs(double v) { return fabs(v); }
+                inline float  abs(float v)  { return fabs(v); }
+        #ifndef CMATH_NOT_IN_STD
+                }
+        #endif // CMATH_NOT_IN_STD
+        #endif // _MSC_EXTENSIONS
+    #endif // _MSC_VER < 1310
+
+    #if _MSC_VER < 1400
+        #define VIGRA_NO_WORKING_STRINGSTREAM
+    #endif
+    
+    #if _MSC_VER >= 1600
+        #define VIGRA_HAS_UNIQUE_PTR
+    #endif
+    
+    #define VIGRA_NEED_BIN_STREAMS
+    
+    #define VIGRA_NO_THREADSAFE_STATIC_INIT  // at least up to _MSC_VER <= 1600, probably higher
+    
+    // usage: 
+    //   static int * p = VIGRA_SAFE_STATIC(p, new int(42));
+    //
+    #define VIGRA_SAFE_STATIC(p, v) \
+    0; while(p == 0) ::vigra::detail::safeStaticInit(&p, v)
+    
+    namespace vigra { namespace detail {
+    template <class T>
+    inline void safeStaticInit(T ** p, T * v)
+    {
+        if (InterlockedCompareExchangePointer((PVOID *)p, v, 0) != 0)
+            delete v;
+    }
+    }} // namespace vigra::detail
+    
+    #ifndef VIGRA_ENABLE_ANNOYING_WARNINGS
+        #pragma warning ( disable: 4244 4267) // implicit integer conversion warnings
+    #endif
+
+    #ifdef VIGRA_DLL
+        #define VIGRA_EXPORT __declspec(dllexport)
+    #elif defined(VIGRA_STATIC_LIB)
+        #define VIGRA_EXPORT
+    #else
+        #define VIGRA_EXPORT __declspec(dllimport)
+    #endif
+#endif // _MSC_VER
+
+///////////////////////////////////////////////////////////
+//                                                       //
+//                           gcc                         //
+//                                                       //
+///////////////////////////////////////////////////////////
+
+#if defined(__GNUC__)
+    #if  __GNUC__ < 2 || ((__GNUC__ == 2) && (__GNUC_MINOR__ <= 8))
+        #error "Need at least g++ 2.95"
+    #endif
+    #if __GNUC__ < 3
+        #define VIGRA_NO_WORKING_STRINGSTREAM
+    #endif
+    #define HAS_HASH_CONTAINERS
+    
+    // these warnings produce too many false positives to be useful
+    #pragma GCC diagnostic ignored "-Wstrict-aliasing"  
+    #pragma GCC diagnostic ignored "-Wshadow"  
+    
+    #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
+        #define VIGRA_HAS_UNIQUE_PTR
+    #endif
+
+#endif  // __GNUC__
+
+///////////////////////////////////////////////////////////
+//                                                       //
+//                         MingW                         //
+//                                                       //
+///////////////////////////////////////////////////////////
+
+#if defined(__MINGW32__)
+    #define VIGRA_NEED_BIN_STREAMS
+
+    #ifdef VIGRA_DLL
+        #define VIGRA_EXPORT __declspec(dllexport)
+    #elif defined(VIGRA_STATIC_LIB)
+        #define VIGRA_EXPORT
+    #else
+        #define VIGRA_EXPORT __declspec(dllimport)
+    #endif
+#endif  // __MINGW32__
+
+///////////////////////////////////////////////////////////
+//                                                       //
+//                      SGI C++ 7.2                      //
+//                                                       //
+///////////////////////////////////////////////////////////
+
+#if defined(__sgi) && !defined(__GNUC__)
+    #if _COMPILER_VERSION < 720
+        #error "Need SGI C++ 7.2 or later"
+    #endif
+    #if (_COMPILER_VERSION  == 720) || (_COMPILER_VERSION  == 721)
+        #define SPECIAL_STDEXCEPTION_DEFINITION_NEEDED
+
+        namespace vigra {
+            typedef std::exception StdException; // must be above next #define !!
+        }
+        #define std
+        #define NO_NAMESPACE_STD
+    #endif // _COMPILER_VERSION
+    #define HAS_HASH_CONTAINERS
+#endif // __sgi
+
+///////////////////////////////////////////////////////////
+//                                                       //
+//                      Sun C++ ???                      //
+//                                                       //
+///////////////////////////////////////////////////////////
+
+#if defined(__sun) && !defined(__GNUC__)
+    #define VIGRA_HAS_ERF
+#endif // __sun
+
+///////////////////////////////////////////////////////////
+//                                                       //
+//                        general                        //
+//                                                       //
+///////////////////////////////////////////////////////////
+
+#ifdef CMATH_NOT_IN_STD
+    #define VIGRA_CSTD
+#else
+    #define VIGRA_CSTD std
+#endif
+
+#ifdef NO_TYPENAME
+    #define typename
+#endif
+
+#ifdef NO_EXPLICIT
+    #define explicit
+#endif
+
+#ifndef VIGRA_EXPORT
+    #define VIGRA_EXPORT
+#endif
+
+#ifdef VIGRA_HAS_UNIQUE_PTR
+#  define VIGRA_UNIQUE_PTR  std::unique_ptr
+#else
+#  define VIGRA_UNIQUE_PTR  std::auto_ptr
+#endif
+
+#ifndef VIGRA_NO_THREADSAFE_STATIC_INIT    
+    // usage: 
+    //   static int * p = VIGRA_SAFE_STATIC(p, new int(42));
+    //
+    #define VIGRA_SAFE_STATIC(p, v) v
+#endif
+
+namespace vigra {
+
+#ifndef SPECIAL_STDEXCEPTION_DEFINITION_NEEDED
+     typedef std::exception StdException;
+#endif
+
+} // namespace vigra
+
+#ifdef DOXYGEN
+#  define doxygen_overloaded_function(fun) fun(...);
+#else
+#  define doxygen_overloaded_function(fun)
+#endif
+
+
+#endif // VIGRA_CONFIG_HXX
diff --git a/include/vigra/configVersion.hxx b/include/vigra/configVersion.hxx
new file mode 100644
index 0000000..59d13ab
--- /dev/null
+++ b/include/vigra/configVersion.hxx
@@ -0,0 +1,45 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2013 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_CONFIG_VERSION_HXX
+#define VIGRA_CONFIG_VERSION_HXX
+
+    #define VIGRA_VERSION_MAJOR 1
+    #define VIGRA_VERSION_MINOR 10
+    #define VIGRA_VERSION_PATCH 0
+    #define VIGRA_VERSION "1.10.0"
+
+#endif /* VIGRA_CONFIG_VERSION_HXX */
diff --git a/include/vigra/contourcirculator.hxx b/include/vigra/contourcirculator.hxx
new file mode 100644
index 0000000..0e97742
--- /dev/null
+++ b/include/vigra/contourcirculator.hxx
@@ -0,0 +1,239 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_CONTOURCIRCULATOR_HXX
+#define VIGRA_CONTOURCIRCULATOR_HXX
+
+#include "pixelneighborhood.hxx"
+
+namespace vigra
+{
+
+/** \addtogroup ImageIteratorAdapters
+ */
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                CrackContourCirculator                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Circulator that walks around a given region.
+
+    The circulator follows the <em>crack contour</em> of a given region.
+    Here, a region is an 8-connected component of pixels with the same
+    value, such as the regions in a label image.
+    The crack contour is located between the inside and outside
+    pixels, that is "on the crack" between the region and the background.
+    Thus, the circulator moves from pixel corner to pixel corner. By definition,
+    the first corner (where the circulator was initialized) gets the
+    coordinate (0,0), and calls to <tt>*circulator</tt> return the distance
+    of the current corner to the initial one.
+
+    The circulator can be used to calculate the area of a region (in pixels):
+
+    \code
+    // start with a pixel within the region, whose left neighbor is outside
+    // (see CrackContourCirculator constructor)
+    ImageIterator region_anchor = ...;
+    int area = 0;
+
+    // calculate area from following the crack contour of the region
+    CrackContourCirculator<ImageIterator> crack(region_anchor);
+    CrackContourCirculator<ImageIterator> crackend(crack);
+    do
+    {
+        area += crack.diff().x * crack.pos().y -
+                crack.diff().y * crack.pos().x;
+    }
+    while(++crack != crackend);
+
+    area /= 2;
+    std::cout << "Area of region " << *region_anchor << ": " << area << std::endl;
+    \endcode
+
+    <b>\#include</b> \<vigra/contourcirculator.hxx\><br>
+    Namespace: vigra
+*/
+template <class IMAGEITERATOR>
+class CrackContourCirculator
+{
+    typedef NeighborhoodCirculator<IMAGEITERATOR, EightNeighborCode>
+            NEIGHBORHOODCIRCULATOR;
+    typedef typename IMAGEITERATOR::value_type label_type;
+
+protected:
+    NEIGHBORHOODCIRCULATOR neighborCirc_;
+    label_type label_;
+    Point2D pos_;
+
+    CrackContourCirculator(NEIGHBORHOODCIRCULATOR const & circ)
+        : neighborCirc_(circ),
+          label_(*(circ.center())),
+          pos_(0, 0)
+    {}
+
+public:
+        /** the circulator's value type
+        */
+    typedef Point2D value_type;
+
+        /** the circulator's reference type (return type of <TT>*circ</TT>)
+        */
+    typedef Point2D const & reference;
+
+        /** the circulator's pointer type (return type of <TT>operator-></TT>)
+        */
+    typedef Point2D const * pointer;
+
+        /** the circulator tag
+        */
+    typedef forward_circulator_tag iterator_category;
+
+        /** Initialize the circulator for a given region.
+
+            The image iterator <tt>in_the_region</tt> must refer
+            to a boundary pixel of the region to be analysed. The
+            direction code <tt>dir</tt> must point to a pixel outside the
+            region (the default assumes that the pixel left of the
+            given region pixel belongs to the background).
+            The first corner of the crack contour is the corner to the
+            right of this direction (i.e. the north west corner of
+            the region pixel, if the direction was West).
+        */
+    CrackContourCirculator(IMAGEITERATOR const & in_the_region,
+                           vigra::FourNeighborCode::Direction dir = vigra::FourNeighborCode::West)
+        : neighborCirc_(in_the_region, EightNeighborCode::code(dir)),
+          label_(*in_the_region),
+          pos_(0, 0)
+    {
+        neighborCirc_.turnLeft();
+    }
+
+        /** Move to the next crack corner of the contour (pre-increment).
+        */
+    CrackContourCirculator & operator++()
+    {
+        pos_ += neighborCirc_.diff();
+
+        neighborCirc_--;
+
+        if(*neighborCirc_ == label_)
+        {
+            neighborCirc_.moveCenterToNeighbor(); // TODO: simplify moveCenterToNeighbor()s
+            --neighborCirc_;
+        }
+        else
+        {
+            neighborCirc_.moveCenterToNeighbor(); // jump out
+            neighborCirc_ += 3;
+            if(*neighborCirc_ == label_)
+            {
+                neighborCirc_.moveCenterToNeighbor();
+                neighborCirc_.turnRight();
+            }
+            else
+            {
+                neighborCirc_.moveCenterToNeighbor();
+                neighborCirc_.turnLeft();
+                neighborCirc_.moveCenterToNeighbor();
+                neighborCirc_.turnRight();
+            }
+        }
+
+        return *this;
+    }
+
+        /** Move to the next crack corner of the contour (post-increment).
+        */
+    CrackContourCirculator operator++(int)
+    {
+        CrackContourCirculator ret(*this);
+        ++(*this);
+        return ret;
+    }
+
+        /** equality
+        */
+    bool operator==(CrackContourCirculator const & o) const
+    {
+        return neighborCirc_ == o.neighborCirc_;
+    }
+
+        /** inequality
+        */
+    bool operator!=(CrackContourCirculator const & o) const
+    {
+        return neighborCirc_ != o.neighborCirc_;
+    }
+
+        /** Get the coordinate of the current corner
+            (relative to the first corner).
+        */
+    reference pos() const
+        { return pos_; }
+
+        /** Equivalent to pos()
+        */
+    reference operator*() const
+        { return pos_; }
+
+        /** Access member of the current coordinate.
+        */
+    pointer operator->() const
+        { return &pos_; }
+
+        /** Access pixel to the right of the crack edge (outside of
+         * the region bounded by the crack contour we walk on). Note
+         * that after operator++, the iterator can still point to the
+         * same pixel (looking from another direction now).
+         */
+    IMAGEITERATOR outerPixel() const
+        { return NEIGHBORHOODCIRCULATOR(neighborCirc_).turnRight().base(); }
+
+        /** Get the offset from the current corner of the contour
+            to the next one.
+        */
+    Diff2D const & diff() const
+        { return neighborCirc_.diff(); }
+};
+
+//@}
+
+} // namespace vigra
+
+#endif /* VIGRA_CONTOURCIRCULATOR_HXX */
diff --git a/include/vigra/convolution.hxx b/include/vigra/convolution.hxx
new file mode 100644
index 0000000..8b59335
--- /dev/null
+++ b/include/vigra/convolution.hxx
@@ -0,0 +1,1883 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_CONVOLUTION_HXX
+#define VIGRA_CONVOLUTION_HXX
+
+#include <functional>
+#include "stdconvolution.hxx"
+#include "separableconvolution.hxx"
+#include "recursiveconvolution.hxx"
+#include "nonlineardiffusion.hxx"
+#include "combineimages.hxx"
+#include "multi_shape.hxx"
+
+
+/** \page Convolution Functions to Convolve Images and Signals
+
+    1D and 2D filters, including separable and recursive convolution, and non-linear diffusion
+
+    <b>\#include</b> \<vigra/convolution.hxx\><br>
+    Namespace: vigra
+
+    <UL style="list-style-image:url(documents/bullet.gif)">
+    <LI> \ref CommonConvolutionFilters
+         <BR>   <em>Short-hands for many common 2D convolution filters (including normalized convolution)</em>
+    <LI> \ref MultiArrayConvolutionFilters
+         <BR>   <em>Convolution filters for arbitrary dimensional arrays (MultiArray etc.)</em>
+    <LI> \ref ResamplingConvolutionFilters
+         <BR>   <em>Resampling convolution filters</em>
+    <LI> \ref vigra::Kernel2D
+         <BR>   <em>Generic 2-dimensional discrete convolution kernel </em>
+    <LI> \ref SeparableConvolution
+         <BR>   <em>1D convolution and separable filters in 2 dimensions </em>
+    <LI> \ref vigra::Kernel1D
+         <BR>   <em>Generic 1-dimensional discrete convolution kernel </em>
+    <LI> \ref RecursiveConvolution
+         <BR>   <em>Recursive filters (1st and 2nd order)</em>
+    <LI> \ref NonLinearDiffusion
+         <BR>   <em>Edge-preserving smoothing </em>
+    <LI> \ref BorderTreatmentMode
+         <BR>   <em>Choose between different border treatment modes </em>
+    <LI> \ref KernelArgumentObjectFactories
+         <BR>   <em>Factory functions to create argument objects to simplify passing kernels</em>
+    </UL>
+*/
+
+/** \page KernelArgumentObjectFactories Kernel Argument Object Factories
+
+    These factory functions allow to create argument objects for 1D
+    and 2D convolution kernel analogously to
+    \ref ArgumentObjectFactories for images.
+
+    \section Kernel1dFactory kernel1d()
+
+        Pass a \ref vigra::Kernel1D to a 1D or separable convolution algorithm.
+
+        These factories can be used to create argument objects when we
+        are given instances or subclasses of \ref vigra::Kernel1D
+        (analogous to the \ref ArgumentObjectFactories for images).
+        These factory functions access <TT>kernel.center()</TT>,
+        <TT>kernel.left()</TT>, <TT>kernel.right()</TT>, <TT>kernel.accessor()</TT>,
+        and  <TT>kernel.borderTreatment()</TT> to obtain the necessary
+        information. The following factory functions are provided:
+
+        <table>
+        <tr><th bgcolor="#f0e0c0" colspan=2 align=left>
+            <TT>\ref vigra::Kernel1D "vigra::Kernel1D<SomeType>" kernel;</TT>
+            </th>
+        </tr>
+        <tr><td>
+        <TT>kernel1d(kernel)</TT>
+        </td><td>
+            create argument object from information provided by
+            kernel
+
+        </td></tr>
+        <tr><td>
+        <TT>kernel1d(kernel, vigra::BORDER_TREATMENT_CLIP)</TT>
+        </td><td>
+            create argument object from information provided by
+            kernel, but use given border treatment mode
+
+        </td></tr>
+        <tr><td>
+        <TT>kernel1d(kerneliterator, kernelaccessor,</TT><br>
+        <TT>                kernelleft, kernelright,</TT><br>
+        <TT>                vigra::BORDER_TREATMENT_CLIP)</TT>
+        </td><td>
+            create argument object from explicitly given iterator
+            (pointing to the center of th kernel), accessor,
+            left and right boundaries, and border treatment mode
+
+        </table>
+
+        For usage examples see \ref convolveImage().
+
+    \section Kernel2dFactory kernel2d()
+
+        Pass a \ref vigra::Kernel2D to a 2D (non-separable) convolution algorithm.
+
+        These factories can be used to create argument objects when we
+        are given instances or subclasses of \ref vigra::Kernel2D
+        (analogous to the \ref ArgumentObjectFactories for images).
+        These factory functions access <TT>kernel.center()</TT>,
+        <TT>kernel.upperLeft()</TT>, <TT>kernel.lowerRight()</TT>, <TT>kernel.accessor()</TT>,
+        and  <TT>kernel.borderTreatment()</TT> to obtain the necessary
+        information. The following factory functions are provided:
+
+        <table>
+        <tr><th bgcolor="#f0e0c0" colspan=2 align=left>
+            <TT>\ref vigra::Kernel2D "vigra::Kernel2D<SomeType>" kernel;</TT>
+            </th>
+        </tr>
+        <tr><td>
+        <TT>kernel2d(kernel)</TT>
+        </td><td>
+            create argument object from information provided by
+            kernel
+
+        </td></tr>
+        <tr><td>
+        <TT>kernel2d(kernel, vigra::BORDER_TREATMENT_CLIP)</TT>
+        </td><td>
+            create argument object from information provided by
+            kernel, but use given border treatment mode
+
+        </td></tr>
+        <tr><td>
+        <TT>kernel2d(kerneliterator, kernelaccessor,</TT>
+        <TT>                upperleft, lowerright,</TT>
+        <TT>                vigra::BORDER_TREATMENT_CLIP)</TT>
+        </td><td>
+            create argument object from explicitly given iterator
+            (pointing to the center of th kernel), accessor,
+            upper left and lower right corners, and border treatment mode
+
+        </table>
+
+        For usage examples see \ref convolveImage().
+*/
+
+namespace vigra {
+
+
+
+/********************************************************/
+/*                                                      */
+/*             Common convolution filters               */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup CommonConvolutionFilters Common Filters
+
+    These functions calculate common filters by appropriate sequences of calls 
+    to \ref separableConvolveX() and \ref separableConvolveY() or explicit 2-dimensional
+    convolution.
+*/
+//@{
+
+/** \brief Convolve an image with the given kernel(s).
+
+    If you pass \ref vigra::Kernel2D to this function, it will perform an explicit 2-dimensional 
+    convolution. If you pass a single \ref vigra::Kernel1D, it performs a separable convolution,
+    i.e. it concatenates two 1D convolutions (along the x-axis and along the y-axis) with the same
+    kernel via internal calls to \ref separableConvolveX() and \ref separableConvolveY(). If two
+    1D kernels are specified, separable convolution uses different kernels for the x- and y-axis.
+
+    All \ref BorderTreatmentMode "border treatment modes" are supported.
+
+    The unput pixel type <tt>T1</tt> must be a \ref LinearSpace "linear space" over 
+    the kernel's value_type <tt>T</tt>, i.e. addition of source values, multiplication with kernel values,
+    and NumericTraits must be defined. The kernel's value_type must be an \ref AlgebraicField "algebraic field",
+    i.e. the arithmetic operations (+, -, *, /) and NumericTraits must be defined. Typically, you will use 
+    <tt>double</tt> for the kernel type.
+    
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // use the same 1D kernel for all axes
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class T>
+        void
+        convolveImage(MultiArrayView<2, T1, S1> const & src,
+                      MultiArrayView<2, T2, S2> dest,
+                      Kernel1D<T> const & k);
+
+        // use a different kernel for each axis
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class T>
+        void
+        convolveImage(MultiArrayView<2, T1, S1> const & src,
+                      MultiArrayView<2, T2, S2> dest,
+                      Kernel1D<T> const & kx, Kernel1D<T> const & ky);
+                      
+        // use a non-separable 2D kernel
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class T3>
+        void
+        convolveImage(MultiArrayView<2, T1, S1> const & src,
+                      MultiArrayView<2, T2, S2> dest,
+                      Kernel2D<T3> const & kernel);
+    }
+    \endcode
+
+    \deprecatedAPI{convolveImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // use a different kernel for each axis
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class T>
+        void convolveImage(SrcIterator supperleft,
+                           SrcIterator slowerright, SrcAccessor sa,
+                           DestIterator dupperleft, DestAccessor da,
+                           Kernel1D<T> const & kx, Kernel1D<T> const & ky);
+
+        // use a non-separable 2D kernel
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void convolveImage(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
+                           DestIterator dest_ul, DestAccessor dest_acc,
+                           KernelIterator ki, KernelAccessor ak,
+                           Diff2D kul, Diff2D klr, BorderTreatmentMode border);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // use a different kernel for each axis
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class T>
+        void
+        convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                      pair<DestIterator, DestAccessor> dest,
+                      Kernel1D<T> const & kx, Kernel1D<T> const & ky);
+
+        // use a non-separable 2D kernel
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                           pair<DestIterator, DestAccessor> dest,
+                           tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D,
+                           BorderTreatmentMode> kernel);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest1(w,h), dest2(w,h);
+    ...
+
+    // create horizontal sobel filter (symmetric difference in x-direction, smoothing in y direction)
+    Kernel1D<double> kx, ky;
+    kx.initSymmetricDifference();
+    ky.initBinomial(1);
+    
+    // calls separable convolution with the two 1D kernels
+    convolveImage(src, dest1, kx, ky);
+    
+    // create a 3x3 Laplacian filter
+    Kernel2D<double> laplace;
+    laplace.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) =
+            0.375,  0.25, 0.375,
+            0.25,  -2.5,  0.25,
+            0.375,  0.25, 0.375;
+    
+    // calls 2D convolution
+    convolveImage(src, dest2, laplace);
+    \endcode
+
+    \deprecatedUsage{convolveImage}
+    \code
+    vigra::FImage src(w,h), dest(w,h);
+    ...
+
+    // create horizontal sobel filter (symmetric difference in x-direction, smoothing in y direction)
+    Kernel1D<double> kx, ky;
+    kx.initSymmetricDifference();
+    ky.initBinomial(1);
+    
+    // calls separable convolution with the two 1D kernels
+    vigra::convolveImage(srcImageRange(src), destImage(dest), kx, ky);
+    
+    // create a 3x3 Laplacian filter
+    Kernel2D<double> laplace;
+    laplace.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) =
+            0.375,  0.25, 0.375,
+            0.25,  -2.5,  0.25,
+            0.375,  0.25, 0.375;
+
+    // calls 2D convolution
+    vigra::convolveImage(srcImageRange(src), destImage(dest), kernel2d(laplace));
+    \endcode
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    The image must be larger than the kernel radius. 
+    <ul>
+    <li>For 1D kernels, <tt>w > std::max(xkernel.right(), -xkernel.keft())</tt> and 
+         <tt>h > std::max(ykernel.right(), -ykernel.left())</tt> are required.
+    <li>For 2D kernels, <tt>w > std::max(kernel.lowerRight().x, -kernel.upperLeft().x)</tt> and 
+         <tt>h > std::max(kernel.lowerRight().y, -kernel.upperLeft().y)</tt> are required.
+    </ul>
+    If <tt>BORDER_TREATMENT_CLIP</tt> is requested: the sum of kernel elements must be != 0.
+*/
+doxygen_overloaded_function(template <...> void convolveImage)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class T>
+void convolveImage(SrcIterator supperleft,
+                   SrcIterator slowerright, SrcAccessor sa,
+                   DestIterator dupperleft, DestAccessor da,
+                   Kernel1D<T> const & kx, Kernel1D<T> const & ky)
+{
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        TmpType;
+    BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
+
+    separableConvolveX(srcIterRange(supperleft, slowerright, sa),
+                       destImage(tmp), kernel1d(kx));
+    separableConvolveY(srcImageRange(tmp),
+                       destIter(dupperleft, da), kernel1d(ky));
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class T>
+inline void
+convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+              pair<DestIterator, DestAccessor> dest,
+              Kernel1D<T> const & kx, Kernel1D<T> const & ky)
+{
+    convolveImage(src.first, src.second, src.third,
+                  dest.first, dest.second, kx, ky);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class T>
+inline void
+convolveImage(MultiArrayView<2, T1, S1> const & src,
+              MultiArrayView<2, T2, S2> dest,
+              Kernel1D<T> const & k)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "convolveImage(): shape mismatch between input and output.");
+    convolveImage(srcImageRange(src),
+                  destImage(dest), k, k);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class T>
+inline void
+convolveImage(MultiArrayView<2, T1, S1> const & src,
+              MultiArrayView<2, T2, S2> dest,
+              Kernel1D<T> const & kx, Kernel1D<T> const & ky)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "convolveImage(): shape mismatch between input and output.");
+    convolveImage(srcImageRange(src),
+                  destImage(dest), kx, ky);
+}
+
+/********************************************************/
+/*                                                      */
+/*                    simpleSharpening                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Perform simple sharpening function.
+
+    This function uses \ref convolveImage() with the following 3x3 filter:
+    
+    \code
+    -sharpening_factor/16.0,    -sharpening_factor/8.0,    -sharpening_factor/16.0,
+    -sharpening_factor/8.0,   1.0+sharpening_factor*0.75,  -sharpening_factor/8.0,
+    -sharpening_factor/16.0,    -sharpening_factor/8.0,    -sharpening_factor/16.0;    
+    \endcode
+    
+    and uses <TT>BORDER_TREATMENT_REFLECT</TT> as border treatment mode.
+
+    <b> Preconditions:</b>
+    \code  
+    1. sharpening_factor >= 0
+    2. scale >= 0
+    \endcode
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1, 
+                  class T2, class S2>
+        void
+        simpleSharpening(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest, 
+                         double sharpening_factor);
+    }
+    \endcode
+
+    \deprecatedAPI{simpleSharpening}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
+                              DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor, 
+                  class DestIterator, class DestAccessor>
+        void simpleSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                              pair<DestIterator, DestAccessor> dest, double sharpening_factor);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);
+    ...
+
+    // sharpening with sharpening_factor = 0.1
+    vigra::simpleSharpening(src, dest, 0.1);
+    \endcode
+
+    \deprecatedUsage{simpleSharpening}
+    \code
+    vigra::FImage src(w,h), dest(w,h);
+    ...
+
+    // sharpening with sharpening_factor = 0.1
+    vigra::simpleSharpening(srcImageRange(src), destImage(dest), 0.1);
+
+    \endcode
+    \deprecatedEnd
+*/    
+doxygen_overloaded_function(template <...> void simpleSharpening)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
+                    DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor)
+{
+
+    vigra_precondition(sharpening_factor >= 0.0,
+                       "simpleSharpening(): amount of sharpening must be >= 0.");
+
+    Kernel2D<double> kernel;
+
+    kernel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = -sharpening_factor/16.0,    -sharpening_factor/8.0,    -sharpening_factor/16.0,
+                                                        -sharpening_factor/8.0,   1.0+sharpening_factor*0.75,  -sharpening_factor/8.0,
+                                                        -sharpening_factor/16.0,    -sharpening_factor/8.0,    -sharpening_factor/16.0;
+
+    convolveImage(src_ul, src_lr, src_acc, dest_ul, dest_acc, 
+                  kernel.center(), kernel.accessor(), 
+                  kernel.upperLeft(), kernel.lowerRight() , BORDER_TREATMENT_REFLECT );
+}
+
+template <class SrcIterator, class SrcAccessor, 
+          class DestIterator, class DestAccessor>
+inline
+void simpleSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                      pair<DestIterator, DestAccessor> dest, double sharpening_factor)
+{
+    simpleSharpening(src.first, src.second, src.third,
+                     dest.first, dest.second, sharpening_factor);
+}
+
+template <class T1, class S1, 
+          class T2, class S2>
+inline void
+simpleSharpening(MultiArrayView<2, T1, S1> const & src,
+                 MultiArrayView<2, T2, S2> dest, 
+                 double sharpening_factor)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "simpleSharpening(): shape mismatch between input and output.");
+    simpleSharpening(srcImageRange(src),
+                     destImage(dest), sharpening_factor);
+}
+
+
+/********************************************************/
+/*                                                      */
+/*                    gaussianSharpening                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Perform sharpening function with gaussian filter.
+
+
+    This function uses \ref gaussianSmoothing() at the given scale to create a
+    temporary image 'smooth' and than blends the original and smoothed image 
+    according to the formula    
+
+    \code
+    dest = (1 + sharpening_factor)*src - sharpening_factor*smooth
+    \endcode
+
+    <b> Preconditions:</b>
+    \code  
+    1. sharpening_factor >= 0
+    2. scale >= 0
+    \endcode
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        gaussianSharpening(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, T2, S2> dest, 
+                           double sharpening_factor, 
+                           double scale);
+    }
+    \endcode
+
+    \deprecatedAPI{gaussianSharpening}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+      template <class SrcIterator, class SrcAccessor,
+                class DestIterator, class DestAccessor>
+      void gaussianSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
+                              DestIterator dest_ul, DestAccessor dest_acc, 
+                              double sharpening_factor, double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+      template <class SrcIterator, class SrcAccessor,
+                class DestIterator, class DestAccessor>
+      void gaussianSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                               pair<DestIterator, DestAccessor> dest, 
+                               double sharpening_factor, double scale)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);
+    ...
+
+    // sharpening with sharpening_factor = 3.0
+    // smoothing with scale = 0.5
+    gaussianSharpening(src, dest, 3.0, 0.5);
+    \endcode
+
+    \deprecatedUsage{gaussianSharpening}
+    \code
+    vigra::FImage src(w,h), dest(w,h);
+    ...
+
+    // sharpening with sharpening_factor = 3.0
+    // smoothing with scale = 0.5
+    vigra::gaussianSharpening(srcImageRange(src), destImage(dest), 3.0, 0.5);
+    \endcode
+    \deprecatedEnd
+*/    
+doxygen_overloaded_function(template <...> void gaussianSharpening)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void gaussianSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
+                        DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor, 
+                        double scale)
+{
+    vigra_precondition(sharpening_factor >= 0.0,
+                       "gaussianSharpening(): amount of sharpening must be >= 0");
+    vigra_precondition(scale >= 0.0,
+                       "gaussianSharpening(): scale parameter should be >= 0.");
+
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote ValueType;
+
+    BasicImage<ValueType> tmp(src_lr - src_ul, SkipInitialization);
+
+    gaussianSmoothing(src_ul, src_lr, src_acc, tmp.upperLeft(), tmp.accessor(), scale);
+
+    SrcIterator i_src = src_ul;
+    DestIterator i_dest = dest_ul;
+    typename BasicImage<ValueType>::traverser tmp_ul = tmp.upperLeft();
+    typename BasicImage<ValueType>::traverser i_tmp = tmp_ul;
+    typename BasicImage<ValueType>::Accessor tmp_acc = tmp.accessor();
+
+    for(; i_src.y != src_lr.y ; i_src.y++, i_dest.y++, i_tmp.y++ )
+    {
+        for (;i_src.x != src_lr.x ; i_src.x++, i_dest.x++, i_tmp.x++ )
+        {
+            dest_acc.set((1.0 + sharpening_factor)*src_acc(i_src) - sharpening_factor*tmp_acc(i_tmp), i_dest);
+        }
+        i_src.x = src_ul.x;
+        i_dest.x = dest_ul.x;
+        i_tmp.x = tmp_ul.x;
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+gaussianSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest, double sharpening_factor, 
+                   double scale)
+{
+    gaussianSharpening(src.first, src.second, src.third,
+                       dest.first, dest.second,
+                       sharpening_factor, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+gaussianSharpening(MultiArrayView<2, T1, S1> const & src,
+                   MultiArrayView<2, T2, S2> dest, 
+                   double sharpening_factor, 
+                   double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "gaussianSharpening(): shape mismatch between input and output.");
+    gaussianSharpening(srcImageRange(src),
+                       destImage(dest),
+                       sharpening_factor, scale);
+}
+
+
+
+/********************************************************/
+/*                                                      */
+/*                    gaussianSmoothing                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Perform isotropic Gaussian convolution.
+
+    This function is a shorthand for the concatenation of a call to
+    \ref separableConvolveX() and \ref separableConvolveY() with a
+    Gaussian kernel of the given scale. If two scales are provided, 
+    smoothing in x and y direction will have different strength. 
+    The function uses <TT>BORDER_TREATMENT_REFLECT</TT>. 
+    
+    Function \ref gaussianSmoothMultiArray() performs the same filter operation
+    on arbitrary dimensional arrays.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        gaussianSmoothing(MultiArrayView<2, T1, S1> const & src,
+                          MultiArrayView<2, T2, S2> dest,
+                          double scale_x, double scale_y = scale_x);
+    }
+    \endcode
+
+    \deprecatedAPI{gaussianSmoothing}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void gaussianSmoothing(SrcIterator supperleft,
+                                SrcIterator slowerright, SrcAccessor sa,
+                                DestIterator dupperleft, DestAccessor da,
+                                double scale_x, double scale_y = scale_x);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        gaussianSmoothing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                          pair<DestIterator, DestAccessor> dest,
+                          double scale_x, double scale_y = scale_x);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);
+    ...
+
+    // smooth with scale = 3.0
+    gaussianSmoothing(src, dest, 3.0);
+    \endcode
+
+    \deprecatedUsage{gaussianSmoothing}
+    \code
+    vigra::FImage src(w,h), dest(w,h);
+    ...
+
+    // smooth with scale = 3.0
+    vigra::gaussianSmoothing(srcImageRange(src), destImage(dest), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void gaussianSmoothing)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void 
+gaussianSmoothing(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor sa,
+                  DestIterator dupperleft, DestAccessor da,
+                  double scale_x, double scale_y)
+{
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        TmpType;
+    BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
+
+    Kernel1D<double> smooth_x, smooth_y;
+    smooth_x.initGaussian(scale_x);
+    smooth_x.setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    smooth_y.initGaussian(scale_y);
+    smooth_y.setBorderTreatment(BORDER_TREATMENT_REFLECT);
+
+    separableConvolveX(srcIterRange(supperleft, slowerright, sa),
+                       destImage(tmp), kernel1d(smooth_x));
+    separableConvolveY(srcImageRange(tmp),
+                       destIter(dupperleft, da), kernel1d(smooth_y));
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+gaussianSmoothing(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor sa,
+                  DestIterator dupperleft, DestAccessor da,
+                  double scale)
+{
+    gaussianSmoothing(supperleft, slowerright, sa,
+                      dupperleft, da,
+                      scale, scale);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+gaussianSmoothing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                  pair<DestIterator, DestAccessor> dest,
+                  double scale_x, double scale_y)
+{
+    gaussianSmoothing(src.first, src.second, src.third,
+                 dest.first, dest.second, scale_x, scale_y);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+gaussianSmoothing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                  pair<DestIterator, DestAccessor> dest,
+                  double scale)
+{
+    gaussianSmoothing(src.first, src.second, src.third,
+                      dest.first, dest.second, scale, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+gaussianSmoothing(MultiArrayView<2, T1, S1> const & src,
+                  MultiArrayView<2, T2, S2> dest,
+                  double scale_x, double scale_y)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "gaussianSmoothing(): shape mismatch between input and output.");
+    gaussianSmoothing(srcImageRange(src),
+                      destImage(dest), scale_x, scale_y);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+gaussianSmoothing(MultiArrayView<2, T1, S1> const & src,
+                  MultiArrayView<2, T2, S2> dest,
+                  double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "gaussianSmoothing(): shape mismatch between input and output.");
+    gaussianSmoothing(srcImageRange(src),
+                      destImage(dest), scale, scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*                     gaussianGradient                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the gradient vector by means of a 1st derivatives of
+    Gaussian filter.
+
+    This function is a shorthand for the concatenation of a call to
+    \ref separableConvolveX() and \ref separableConvolveY() with the
+    appropriate kernels at the given scale. Note that this function can either produce
+    two separate result images for the x- and y-components of the gradient, or write
+    into a vector valued image (with at least two components).
+
+    Function \ref gaussianGradientMultiArray() performs the same filter operation
+    on arbitrary dimensional arrays.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // write x and y component of the gradient into separate images
+        template <class T1, class S1,
+                  class T2X, class S2X,
+                  class T2Y, class S2Y>
+        void
+        gaussianGradient(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2X, S2X> destx,
+                         MultiArrayView<2, T2Y, S2Y> desty,
+                         double scale);
+
+       // write x and y component of the gradient into a vector-valued image
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        gaussianGradient(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, TinyVector<T2, 2>, S2> dest,
+                         double scale);
+    }
+    \endcode
+
+    \deprecatedAPI{gaussianGradient}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // write x and y component of the gradient into separate images
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIteratorX, class DestAccessorX,
+                  class DestIteratorY, class DestAccessorY>
+        void gaussianGradient(SrcIterator supperleft,
+                              SrcIterator slowerright, SrcAccessor sa,
+                              DestIteratorX dupperleftx, DestAccessorX dax,
+                              DestIteratorY dupperlefty, DestAccessorY day,
+                              double scale);
+
+        // write x and y component of the gradient into a vector-valued image
+        template <class SrcIterator, class SrcAccessor,
+                 class DestIterator, class DestAccessor>
+        void gaussianGradient(SrcIterator supperleft,
+                              SrcIterator slowerright, SrcAccessor src,
+                              DestIterator dupperleft, DestAccessor dest,
+                              double scale);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // write x and y component of the gradient into separate images
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIteratorX, class DestAccessorX,
+                  class DestIteratorY, class DestAccessorY>
+        void
+        gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                         pair<DestIteratorX, DestAccessorX> destx,
+                         pair<DestIteratorY, DestAccessorY> desty,
+                         double scale);
+
+        // write x and y component of the gradient into a vector-valued image
+        template <class SrcIterator, class SrcAccessor,
+                 class DestIterator, class DestAccessor>
+        void
+        gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                         pair<DestIterator, DestAccessor> dest,
+                         double scale);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), gradx(w,h), grady(w,h);
+    ...
+
+    // calculate gradient vector at scale = 3.0
+    gaussianGradient(src, gradx, grady, 3.0);
+    
+    // likewise, but use a vector image to store the gradient
+    MultiArray<2, TinyVector<float, 2> > dest(w,h);
+    gaussianGradient(src, dest, 3.0);
+    \endcode
+
+    \deprecatedUsage{gaussianGradient}
+    \code
+    vigra::FImage src(w,h), gradx(w,h), grady(w,h);
+    ...
+
+    // calculate gradient vector at scale = 3.0
+    vigra::gaussianGradient(srcImageRange(src),
+                             destImage(gradx), destImage(grady), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void gaussianGradient)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIteratorX, class DestAccessorX,
+          class DestIteratorY, class DestAccessorY>
+void gaussianGradient(SrcIterator supperleft,
+                        SrcIterator slowerright, SrcAccessor sa,
+                        DestIteratorX dupperleftx, DestAccessorX dax,
+                        DestIteratorY dupperlefty, DestAccessorY day,
+                        double scale)
+{
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        TmpType;
+    BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
+
+    Kernel1D<double> smooth, grad;
+    smooth.initGaussian(scale);
+    grad.initGaussianDerivative(scale, 1);
+
+    separableConvolveX(srcIterRange(supperleft, slowerright, sa),
+                       destImage(tmp), kernel1d(grad));
+    separableConvolveY(srcImageRange(tmp),
+                       destIter(dupperleftx, dax), kernel1d(smooth));
+    separableConvolveX(srcIterRange(supperleft, slowerright, sa),
+                       destImage(tmp), kernel1d(smooth));
+    separableConvolveY(srcImageRange(tmp),
+                       destIter(dupperlefty, day), kernel1d(grad));
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void gaussianGradient(SrcIterator supperleft,
+                        SrcIterator slowerright, SrcAccessor src,
+                        DestIterator dupperleft, DestAccessor dest,
+                        double scale)
+{
+    VectorElementAccessor<DestAccessor> gradx(0, dest), grady(1, dest);
+    gaussianGradient(supperleft, slowerright, src, 
+                     dupperleft, gradx, dupperleft, grady, scale);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIteratorX, class DestAccessorX,
+          class DestIteratorY, class DestAccessorY>
+inline void
+gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                 pair<DestIteratorX, DestAccessorX> destx,
+                 pair<DestIteratorY, DestAccessorY> desty,
+                 double scale)
+{
+    gaussianGradient(src.first, src.second, src.third,
+                 destx.first, destx.second, desty.first, desty.second, scale);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                 pair<DestIterator, DestAccessor> dest,
+                 double scale)
+{
+    gaussianGradient(src.first, src.second, src.third,
+                     dest.first, dest.second, scale);
+}
+
+template <class T1, class S1,
+          class T2X, class S2X,
+          class T2Y, class S2Y>
+inline void
+gaussianGradient(MultiArrayView<2, T1, S1> const & src,
+                 MultiArrayView<2, T2X, S2X> destx,
+                 MultiArrayView<2, T2Y, S2Y> desty,
+                 double scale)
+{
+    vigra_precondition(src.shape() == destx.shape(),
+        "gaussianGradient(): shape mismatch between input and output.");
+    gaussianGradient(srcImageRange(src),
+                     destImage(destx), destImage(desty), scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+gaussianGradient(MultiArrayView<2, T1, S1> const & src,
+                 MultiArrayView<2, TinyVector<T2, 2>, S2> dest,
+                 double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "gaussianGradient(): shape mismatch between input and output.");
+    gaussianGradient(srcImageRange(src),
+                     destImage(dest), scale);
+}
+
+/** \brief Calculate the gradient magnitude by means of a 1st derivatives of
+    Gaussian filter.
+
+    This function calls gaussianGradient() and returns the pixel-wise magnitude of
+    the resulting gradient vectors. If the original image has multiple bands,
+    the squared gradient magnitude is computed for each band separately, and the
+    return value is the square root of the sum of these squared magnitudes.
+
+    <b> Declarations:</b>
+
+    use arbitrary-dimensional arrays:
+    \code
+    namespace vigra {
+        // pass filter scale explicitly
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void 
+        gaussianGradientMagnitude(MultiArrayView<N, T1, S1> const & src,
+                                  MultiArrayView<N, T2, S2> dest,
+                                  double sigma,
+                                  ConvolutionOptions<N> opt = ConvolutionOptions<N>());
+
+        template <unsigned int N, class MT, class S1,
+                                  class T2, class S2>
+        void 
+        gaussianGradientMagnitude(MultiArrayView<N+1, Multiband<MT>, S1> const & src,
+                                  MultiArrayView<N,   T2, S2> dest,
+                                  double sigma,
+                                  ConvolutionOptions<N> opt = ConvolutionOptions<N>());
+                                  
+        // pass filter scale(s) in option object
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void 
+        gaussianGradientMagnitude(MultiArrayView<N, T1, S1> const & src,
+                                  MultiArrayView<N, T2, S2> dest,
+                                  ConvolutionOptions<N> const & opt);
+
+        template <unsigned int N, class MT, class S1,
+                                  class T2, class S2>
+        void 
+        gaussianGradientMagnitude(MultiArrayView<N+1, Multiband<MT>, S1> const & src,
+                                  MultiArrayView<N,   T2, S2> dest,
+                                  ConvolutionOptions<N> const & opt);
+    }
+    \endcode
+    Here, the input element types <tt>T1</tt> and <tt>MT</tt> can be arbitrary scalar types, and <tt>T1</tt> 
+    may also be <tt>TinyVector</tt> or <tt>RGBValue</tt>. The output element type <tt>T2</tt> should 
+    be the corresponding norm type (see \ref NormTraits "NormTraits"). In the <tt>Multiband<MT></tt>-version,
+    the input array's right-most dimension is interpreted as a channel axis, therefore it must 
+    have one dimension more than the output array.
+
+    \deprecatedAPI{gaussianGradientMagnitude}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void gaussianGradientMagnitude(SrcIterator sul,
+                                       SrcIterator slr, SrcAccessor src,
+                                       DestIterator dupperleft, DestAccessor dest,
+                                       double scale);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        gaussianGradientMagnitude(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                  pair<DestIterator, DestAccessor> dest,
+                                  double scale);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    // example 1
+    {
+        // use a 3-dimensional float array
+        MultiArray<3, float> volume(Shape3(w, h, d)), grad(volume.shape());
+        ...
+
+        // calculate gradient magnitude at scale = 3.0
+        gaussianGradientMagnitude(volume, grad, 3.0);
+    }
+    
+    // example 2
+    {
+        // use a 2-dimensional RGB array
+        MultiArray<2, RGBValue<float> > rgb(Shape2(w, h));
+        MultiArray<2, float> grad(rgb.shape());
+        ...
+
+        // calculate the color gradient magnitude at scale = 3.0
+        gaussianGradientMagnitude(rgb, grad, 3.0);
+    }
+    
+    // example 3
+    {
+        // use a 3-dimensional array whose right-most axis is interpreted as 
+        // a multi-spectral axis with arbitrary many channels
+        MultiArray<3, Multiband<float> > spectral(Shape3(w, h, channelCount));
+        MultiArray<2, float> grad(Shape2(w, h));
+        ...
+
+        // calculate the multi-channel gradient magnitude at scale = 3.0
+        // (note that the template parameter N (number of spatial dimensions)
+        //  must be provided explicitly as gaussianGradientMagnitude<2>(...) )
+        MultiArrayView<3, Multiband<float> > view(spectral);
+        gaussianGradientMagnitude<2>(view, grad, 3.0);
+    }
+    \endcode
+
+    \deprecatedUsage{gaussianGradientMagnitude}
+    \code
+    // use a traditional float or RGB image
+    FImage image(w, h), grad(w, h);
+    FRGBImage rgb(w, h);
+    ...
+
+    // calculate gradient magnitude at scale = 3.0
+    gaussianGradientMagnitude(srcImageRange(image), destImage(grad), 3.0);
+    
+    // calculate color gradient magnitude at scale = 3.0
+    gaussianGradientMagnitude(srcImageRange(rgb), destImage(grad), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void gaussianGradientMagnitude)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void gaussianGradientMagnitude(SrcIterator sul,
+                               SrcIterator slr, SrcAccessor src,
+                               DestIterator dupperleft, DestAccessor dest,
+                               double scale)
+{
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    BasicImage<TmpType> gradx(slr-sul, SkipInitialization), grady(slr-sul, SkipInitialization);
+
+    gaussianGradient(srcIterRange(sul, slr, src),
+                     destImage(gradx), destImage(grady), scale);
+    combineTwoImages(srcImageRange(gradx), srcImage(grady), destIter(dupperleft, dest),
+                     MagnitudeFunctor<TmpType>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+gaussianGradientMagnitude(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                          pair<DestIterator, DestAccessor> dest,
+                          double scale)
+{
+    gaussianGradientMagnitude(src.first, src.second, src.third,
+                              dest.first, dest.second, scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*                 laplacianOfGaussian                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Filter image with the Laplacian of Gaussian operator
+    at the given scale.
+
+    This function calls \ref separableConvolveX() and \ref separableConvolveY() with the appropriate 2nd derivative
+    of Gaussian kernels in x- and y-direction and then sums the results
+    to get the Laplacian.
+    
+    Function \ref laplacianOfGaussianMultiArray() performs the same filter operation
+    on arbitrary dimensional arrays.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        laplacianOfGaussian(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            double scale);
+    }
+    \endcode
+
+    \deprecatedAPI{laplacianOfGaussian}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void laplacianOfGaussian(SrcIterator supperleft,
+                                SrcIterator slowerright, SrcAccessor sa,
+                                DestIterator dupperleft, DestAccessor da,
+                                double scale);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        laplacianOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                          pair<DestIterator, DestAccessor> dest,
+                          double scale);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);
+    ...
+
+    // calculate Laplacian of Gaussian at scale = 3.0
+    laplacianOfGaussian(src, dest, 3.0);
+    \endcode
+
+    \deprecatedUsage{laplacianOfGaussian}
+    \code
+    vigra::FImage src(w,h), dest(w,h);
+    ...
+
+    // calculate Laplacian of Gaussian at scale = 3.0
+    vigra::laplacianOfGaussian(srcImageRange(src), destImage(dest), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void laplacianOfGaussian)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void laplacianOfGaussian(SrcIterator supperleft,
+                        SrcIterator slowerright, SrcAccessor sa,
+                        DestIterator dupperleft, DestAccessor da,
+                        double scale)
+{
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        TmpType;
+    BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization),
+                        tmpx(slowerright - supperleft, SkipInitialization),
+                        tmpy(slowerright - supperleft, SkipInitialization);
+
+    Kernel1D<double> smooth, deriv;
+    smooth.initGaussian(scale);
+    deriv.initGaussianDerivative(scale, 2);
+
+    separableConvolveX(srcIterRange(supperleft, slowerright, sa),
+                       destImage(tmp), kernel1d(deriv));
+    separableConvolveY(srcImageRange(tmp),
+                       destImage(tmpx), kernel1d(smooth));
+    separableConvolveX(srcIterRange(supperleft, slowerright, sa),
+                       destImage(tmp), kernel1d(smooth));
+    separableConvolveY(srcImageRange(tmp),
+                       destImage(tmpy), kernel1d(deriv));
+    combineTwoImages(srcImageRange(tmpx), srcImage(tmpy),
+                       destIter(dupperleft, da), std::plus<TmpType>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+laplacianOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    pair<DestIterator, DestAccessor> dest,
+                    double scale)
+{
+    laplacianOfGaussian(src.first, src.second, src.third,
+                        dest.first, dest.second, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+laplacianOfGaussian(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest,
+                    double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "laplacianOfGaussian(): shape mismatch between input and output.");
+    laplacianOfGaussian(srcImageRange(src),
+                        destImage(dest), scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*               hessianMatrixOfGaussian                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Filter image with the 2nd derivatives of the Gaussian
+    at the given scale to get the Hessian matrix.
+
+    The Hessian matrix is a symmetric matrix defined as:
+
+    \f[
+        \mbox{\rm Hessian}(I) = \left(
+        \begin{array}{cc}
+        G_{xx} \ast I & G_{xy} \ast I \\
+        G_{xy} \ast I & G_{yy} \ast I
+        \end{array} \right)
+    \f]
+
+    where \f$G_{xx}, G_{xy}, G_{yy}\f$ denote 2nd derivatives of Gaussians
+    at the given scale, and
+    \f$\ast\f$ is the convolution symbol. This function calls
+    \ref separableConvolveX() and \ref separableConvolveY()
+    with the appropriate 2nd derivative
+    of Gaussian kernels and puts the results in
+    the three destination images. The first destination image will
+    contain the second derivative in x-direction, the second one the mixed
+    derivative, and the third one holds the derivative in y-direction.
+    
+    Function \ref hessianOfGaussianMultiArray() performs the same filter operation
+    on arbitrary dimensional arrays.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        hessianMatrixOfGaussian(MultiArrayView<2, T1, S1> const & src,
+                                MultiArrayView<2, TinyVector<T2, 3>, S2> dest,
+                                double scale);
+    }
+    \endcode
+
+    \deprecatedAPI{hessianMatrixOfGaussian}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIteratorX, class DestAccessorX,
+                  class DestIteratorXY, class DestAccessorXY,
+                  class DestIteratorY, class DestAccessorY>
+        void hessianMatrixOfGaussian(SrcIterator supperleft,
+                                SrcIterator slowerright, SrcAccessor sa,
+                                DestIteratorX dupperleftx, DestAccessorX dax,
+                                DestIteratorXY dupperleftxy, DestAccessorXY daxy,
+                                DestIteratorY dupperlefty, DestAccessorY day,
+                                double scale);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIteratorX, class DestAccessorX,
+                  class DestIteratorXY, class DestAccessorXY,
+                  class DestIteratorY, class DestAccessorY>
+        void
+        hessianMatrixOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                          pair<DestIteratorX, DestAccessorX> destx,
+                          pair<DestIteratorXY, DestAccessorXY> destxy,
+                          pair<DestIteratorY, DestAccessorY> desty,
+                          double scale);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float>                  src(w,h);
+    MultiArray<2, TinyVector<float, 3> >  hessian(w,h);  // will hold the three components of the Hessian
+    ...
+
+    // calculate Hessian of Gaussian at scale = 3.0, use a 3-band output image
+    hessianMatrixOfGaussian(src, hessian, 3.0);
+    \endcode
+
+    \deprecatedUsage{hessianMatrixOfGaussian}
+    \code
+    vigra::FImage src(w,h), 
+                  hxx(w,h), hxy(w,h), hyy(w,h); // use a separate image for each component of the Hessian
+    ...
+
+    // calculate Hessian of Gaussian at scale = 3.0, use 3 single.band output images
+    vigra::hessianMatrixOfGaussian(srcImageRange(src),
+                                   destImage(hxx), destImage(hxy), destImage(hyy), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void hessianMatrixOfGaussian)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIteratorX, class DestAccessorX,
+          class DestIteratorXY, class DestAccessorXY,
+          class DestIteratorY, class DestAccessorY>
+void hessianMatrixOfGaussian(SrcIterator supperleft,
+                        SrcIterator slowerright, SrcAccessor sa,
+                        DestIteratorX dupperleftx, DestAccessorX dax,
+                        DestIteratorXY dupperleftxy, DestAccessorXY daxy,
+                        DestIteratorY dupperlefty, DestAccessorY day,
+                        double scale)
+{
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        TmpType;
+    BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
+
+    Kernel1D<double> smooth, deriv1, deriv2;
+    smooth.initGaussian(scale);
+    deriv1.initGaussianDerivative(scale, 1);
+    deriv2.initGaussianDerivative(scale, 2);
+
+    separableConvolveX(srcIterRange(supperleft, slowerright, sa),
+                       destImage(tmp), kernel1d(deriv2));
+    separableConvolveY(srcImageRange(tmp),
+                       destIter(dupperleftx, dax), kernel1d(smooth));
+    separableConvolveX(srcIterRange(supperleft, slowerright, sa),
+                       destImage(tmp), kernel1d(smooth));
+    separableConvolveY(srcImageRange(tmp),
+                       destIter(dupperlefty, day), kernel1d(deriv2));
+    separableConvolveX(srcIterRange(supperleft, slowerright, sa),
+                       destImage(tmp), kernel1d(deriv1));
+    separableConvolveY(srcImageRange(tmp),
+                       destIter(dupperleftxy, daxy), kernel1d(deriv1));
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIteratorX, class DestAccessorX,
+          class DestIteratorXY, class DestAccessorXY,
+          class DestIteratorY, class DestAccessorY>
+inline void
+hessianMatrixOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        pair<DestIteratorX, DestAccessorX> destx,
+                        pair<DestIteratorXY, DestAccessorXY> destxy,
+                        pair<DestIteratorY, DestAccessorY> desty,
+                        double scale)
+{
+    hessianMatrixOfGaussian(src.first, src.second, src.third,
+                            destx.first, destx.second,
+                            destxy.first, destxy.second,
+                            desty.first, desty.second,
+                            scale);
+}
+
+template <class T1, class S1,
+          class T2X, class S2X,
+          class T2XY, class S2XY,
+          class T2Y, class S2Y>
+inline void
+hessianMatrixOfGaussian(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, T2X, S2X> destx,
+                        MultiArrayView<2, T2XY, S2XY> destxy,
+                        MultiArrayView<2, T2Y, S2Y> desty,
+                        double scale)
+{
+    vigra_precondition(src.shape() == destx.shape() && src.shape() == destxy.shape() && src.shape() == desty.shape(),
+        "hessianMatrixOfGaussian(): shape mismatch between input and output.");
+    hessianMatrixOfGaussian(srcImageRange(src),
+                            destImage(destx),
+                            destImage(destxy),
+                            destImage(desty),
+                            scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+hessianMatrixOfGaussian(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, TinyVector<T2, 3>, S2> dest,
+                        double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "hessianMatrixOfGaussian(): shape mismatch between input and output.");
+        
+    MultiArrayView<3, T2> expanded(dest.expandElements(0));
+    
+    hessianMatrixOfGaussian(srcImageRange(src),
+                            destImage(expanded.bind<0>(0)),
+                            destImage(expanded.bind<0>(1)),
+                            destImage(expanded.bind<0>(2)),
+                            scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*                   structureTensor                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the Structure Tensor for each pixel of
+ and image, using Gaussian (derivative) filters.
+
+    The Structure Tensor is is a smoothed version of the Euclidean product
+    of the gradient vector with itself. I.e. it's a symmetric matrix defined as:
+
+    \f[
+        \mbox{\rm StructurTensor}(I) = \left(
+        \begin{array}{cc}
+        G \ast (I_x I_x) & G \ast (I_x I_y) \\
+        G \ast (I_x I_y) & G \ast (I_y I_y)
+        \end{array} \right) = \left(
+        \begin{array}{cc}
+        A & C \\
+        C & B
+        \end{array} \right)
+    \f]
+
+    where \f$G\f$ denotes Gaussian smoothing at the <i>outer scale</i>,
+    \f$I_x, I_y\f$ are the gradient components taken at the <i>inner scale</i>,
+    \f$\ast\f$ is the convolution symbol, and \f$I_x I_x\f$ etc. are pixelwise
+    products of the 1st derivative images. This function calls
+    \ref separableConvolveX() and \ref separableConvolveY() with the
+    appropriate Gaussian kernels and puts the results in
+    the three separate destination images (where the first one will
+    contain \f$G \ast (I_x I_x)\f$, the second one \f$G \ast (I_x I_y)\f$, and the
+    third one holds \f$G \ast (I_y I_y)\f$), or into a single 3-band image (where the bands
+    hold the result in the same order as above). The latter form is also applicable when
+    the source image is a multi-band image (e.g. RGB). In this case, tensors are
+    first computed for each band separately, and then summed up to get a single result tensor.
+    
+    Function \ref structureTensorMultiArray() performs the same filter operation
+    on arbitrary dimensional arrays.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // create three separate destination images
+        template <class T, class S,
+                  class TX, class SX,
+                  class TXY, class SXY,
+                  class TY, class SY>
+        void
+        structureTensor(MultiArrayView<2, S, T> const & src,
+                        MultiArrayView<2, TX, SX>       destx,
+                        MultiArrayView<2, TXY, SXY>     destxy,
+                        MultiArrayView<2, TY, SY>       desty,
+                        double inner_scale, double outer_scale);
+
+        // create a single 3-band destination image
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        structureTensor(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, TinyVector<T2, 3>, S2> dest,
+                        double inner_scale, double outer_scale);
+    }
+    \endcode
+
+    \deprecatedAPI{structureTensor}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // create three separate destination images
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIteratorX, class DestAccessorX,
+                  class DestIteratorXY, class DestAccessorXY,
+                  class DestIteratorY, class DestAccessorY>
+        void structureTensor(SrcIterator supperleft,
+                                SrcIterator slowerright, SrcAccessor sa,
+                                DestIteratorX dupperleftx, DestAccessorX dax,
+                                DestIteratorXY dupperleftxy, DestAccessorXY daxy,
+                                DestIteratorY dupperlefty, DestAccessorY day,
+                                double inner_scale, double outer_scale);
+
+        // create a single 3-band destination image
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void structureTensor(SrcIterator supperleft,
+                                SrcIterator slowerright, SrcAccessor sa,
+                                DestIterator dupperleft, DestAccessor da,
+                                double inner_scale, double outer_scale);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // create three separate destination images
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIteratorX, class DestAccessorX,
+                  class DestIteratorXY, class DestAccessorXY,
+                  class DestIteratorY, class DestAccessorY>
+        void
+        structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                          pair<DestIteratorX, DestAccessorX> destx,
+                          pair<DestIteratorXY, DestAccessorXY> destxy,
+                          pair<DestIteratorY, DestAccessorY> desty,
+                          double nner_scale, double outer_scale);
+
+        // create a single 3-band destination image
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                          pair<DestIterator, DestAccessor> dest,
+                          double nner_scale, double outer_scale);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, flost> src(w,h), 
+                         stxx(w,h), stxy(w,h), styy(w,h);  // use a separate image for each component
+    ...
+
+    // calculate Structure Tensor at inner scale = 1.0 and outer scale = 3.0
+    structureTensor(src, stxx, stxy, styy, 1.0, 3.0);
+
+    // likwise with a single 3-band destination image
+    MultiArray<2, TinyVector<float, 3> > st(w,h);
+    structureTensor(src, st, 1.0, 3.0);
+    \endcode
+
+    \deprecatedUsage{structureTensor}
+    \code
+    vigra::FImage src(w,h), 
+                  stxx(w,h), stxy(w,h), styy(w,h);
+    vigra::BasicImage<TinyVector<float, 3> > st(w,h);
+    ...
+
+    vigra::structureTensor(srcImageRange(src),
+                           destImage(stxx), destImage(stxy), destImage(styy), 1.0, 3.0);
+
+    vigra::structureTensor(srcImageRange(src), destImage(st), 1.0, 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void structureTensor)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIteratorX, class DestAccessorX,
+          class DestIteratorXY, class DestAccessorXY,
+          class DestIteratorY, class DestAccessorY>
+void structureTensor(SrcIterator supperleft,
+                        SrcIterator slowerright, SrcAccessor sa,
+                        DestIteratorX dupperleftx, DestAccessorX dax,
+                        DestIteratorXY dupperleftxy, DestAccessorXY daxy,
+                        DestIteratorY dupperlefty, DestAccessorY day,
+                        double inner_scale, double outer_scale)
+{
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        TmpType;
+    BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization),
+                        tmpx(slowerright - supperleft, SkipInitialization),
+                        tmpy(slowerright - supperleft, SkipInitialization);
+
+    gaussianGradient(srcIterRange(supperleft, slowerright, sa),
+           destImage(tmpx), destImage(tmpy), inner_scale);
+    combineTwoImages(srcImageRange(tmpx), srcImage(tmpx),
+                     destImage(tmp), std::multiplies<TmpType>());
+    gaussianSmoothing(srcImageRange(tmp),
+                      destIter(dupperleftx, dax), outer_scale);
+    combineTwoImages(srcImageRange(tmpy), srcImage(tmpy),
+                     destImage(tmp), std::multiplies<TmpType>());
+    gaussianSmoothing(srcImageRange(tmp),
+                      destIter(dupperlefty, day), outer_scale);
+    combineTwoImages(srcImageRange(tmpx), srcImage(tmpy),
+                     destImage(tmp), std::multiplies<TmpType>());
+    gaussianSmoothing(srcImageRange(tmp),
+                      destIter(dupperleftxy, daxy), outer_scale);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIteratorX, class DestAccessorX,
+          class DestIteratorXY, class DestAccessorXY,
+          class DestIteratorY, class DestAccessorY>
+inline void
+structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                  pair<DestIteratorX, DestAccessorX> destx,
+                  pair<DestIteratorXY, DestAccessorXY> destxy,
+                  pair<DestIteratorY, DestAccessorY> desty,
+                  double inner_scale, double outer_scale)
+{
+    structureTensor(src.first, src.second, src.third,
+                 destx.first, destx.second,
+                 destxy.first, destxy.second,
+                 desty.first, desty.second,
+                 inner_scale, outer_scale);
+}
+
+template <class T, class S,
+          class TX, class SX,
+          class TXY, class SXY,
+          class TY, class SY>
+inline void
+structureTensor(MultiArrayView<2, S, T> const & src,
+                MultiArrayView<2, TX, SX> destx,
+                MultiArrayView<2, TXY, SXY> destxy,
+                MultiArrayView<2, TY, SY> desty,
+                double inner_scale, double outer_scale)
+{
+    vigra_precondition(src.shape() == destx.shape(),
+        "structureTensor(): shape mismatch between input and output.");
+    structureTensor(srcImageRange(src),
+                    destImage(destx), destImage(destxy), destImage(desty),
+                    inner_scale, outer_scale);
+}
+
+namespace detail {
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void structureTensor(SrcIterator supperleft,
+                     SrcIterator slowerright, SrcAccessor src,
+                     DestIterator dupperleft, DestAccessor dest,
+                     double inner_scale, double outer_scale,
+                     VigraTrueType /* isScalar */)
+{
+    typedef VectorElementAccessor<DestAccessor> DA;
+    structureTensor(supperleft, slowerright, src,
+                    dupperleft, DA(0, dest),
+                    dupperleft, DA(1, dest),
+                    dupperleft, DA(2, dest),
+                    inner_scale, outer_scale);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void structureTensor(SrcIterator supperleft,
+                     SrcIterator slowerright, SrcAccessor src,
+                     DestIterator dupperleft, DestAccessor dest,
+                     double inner_scale, double outer_scale,
+                     VigraFalseType /* isScalar */)
+{
+    int bands = src.size(supperleft);
+    typedef VectorElementAccessor<SrcAccessor> SA;
+    
+    structureTensor(supperleft, slowerright, SA(0, src),
+                    dupperleft, dest,
+                    inner_scale, outer_scale,
+                    VigraTrueType() /* isScalar */);
+                    
+    BasicImage<typename DestAccessor::value_type> st(slowerright - supperleft, SkipInitialization);
+    for(int k=1; k < bands; ++k)
+    {
+        structureTensor(supperleft, slowerright, SA(k, src),
+                        st.upperLeft(), st.accessor(),
+                        inner_scale, outer_scale,
+                        VigraTrueType() /* isScalar */);
+        combineTwoImages(srcImageRange(st), srcIter(dupperleft, dest), destIter(dupperleft, dest),
+                         std::plus<typename DestAccessor::value_type>());
+    }
+}
+
+} // namespace detail
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void structureTensor(SrcIterator supperleft,
+                        SrcIterator slowerright, SrcAccessor src,
+                        DestIterator dupperleft, DestAccessor dest,
+                        double inner_scale, double outer_scale)
+{
+    typedef typename 
+        NumericTraits<typename SrcAccessor::value_type>::isScalar isScalar;
+    detail::structureTensor(supperleft, slowerright, src,
+                            dupperleft, dest, inner_scale, outer_scale, isScalar());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                pair<DestIterator, DestAccessor> dest,
+                double inner_scale, double outer_scale)
+{
+    structureTensor(src.first, src.second, src.third,
+                    dest.first, dest.second,
+                    inner_scale, outer_scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+structureTensor(MultiArrayView<2, T1, S1> const & src,
+                MultiArrayView<2, TinyVector<T2, 3>, S2> dest,
+                double inner_scale, double outer_scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "structureTensor(): shape mismatch between input and output.");
+    structureTensor(srcImageRange(src),
+                    destImage(dest),
+                    inner_scale, outer_scale);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_CONVOLUTION_HXX
diff --git a/include/vigra/coordinate_iterator.hxx b/include/vigra/coordinate_iterator.hxx
new file mode 100644
index 0000000..f5b5635
--- /dev/null
+++ b/include/vigra/coordinate_iterator.hxx
@@ -0,0 +1,762 @@
+/************************************************************************/
+/*                                                                      */
+/*    Copyright 2011-2012 by Markus Nullmeier and Ullrich Koethe        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_COORDINATE_ITERATOR_HXX
+#define VIGRA_COORDINATE_ITERATOR_HXX
+
+#include <complex>
+
+#include "tuple.hxx"
+#include "accessor.hxx"
+#include "tinyvector.hxx"
+#include "numerictraits.hxx"
+#include "multi_iterator.hxx"
+#include "multi_array.hxx"
+
+namespace vigra {
+
+template<unsigned N>
+struct StridePair
+{
+    typedef typename MultiArrayShape<N>::type  index_type;
+    typedef          TinyVector<double, N>     coord_type;
+    typedef          coord_type                deref_type;
+    typedef          StridePair                type;
+    typedef          StridePair                stride_type;
+    typedef          TinyVector<type, N>       stride_array_type;
+    typedef          TinyVector<index_type, N> shape_array_type;
+    typedef          shape_array_type          shape_type;
+
+    index_type index;
+    coord_type coord;
+
+    StridePair(const index_type & i) : index(i), coord(i) {}
+    StridePair(const coord_type & c) : index(),  coord(c) {}
+    StridePair(const index_type & i, const coord_type & c)
+        :            index       (i),             coord(c) {}
+    StridePair(  MultiArrayIndex  i, const coord_type & c)
+        :        index(index_type(i)),            coord(c) {}
+    StridePair() {}
+
+    // use just the coordinates for further processing ...
+    const coord_type & operator*() const
+    {
+        return this->coord;
+    }
+
+    void operator+=(const StridePair & x)
+    {
+        index += x.index;
+        coord += x.coord;
+    }
+    void operator-=(const StridePair & x)
+    {
+        index -= x.index;
+        coord -= x.coord;
+    }
+    StridePair operator+(const StridePair & x)
+    {
+        StridePair ret = *this;
+        ret += x;
+        return ret;
+    }
+    StridePair operator-(const StridePair & x)
+    {
+        StridePair ret = *this;
+        ret -= x;
+        return ret;
+    }
+    StridePair operator*(const StridePair & x)
+    {
+        StridePair ret = *this;
+        ret.index *= x.index;
+        ret.coord *= x.coord;
+        return ret;
+    }
+    StridePair operator/(const StridePair & x)
+    {
+        StridePair ret = *this;
+        ret.index /= x.index;
+        ret.coord /= x.coord;
+        return ret;
+    }
+
+    MultiArrayIndex & idx0()
+    {
+        return index[0];
+    }
+    const index_type & idx() const
+    {
+        return index;
+    }
+    double & dim0()
+    {
+        return coord[0];
+    }
+    double dim0() const
+    {
+        return coord[0];
+    }
+};
+
+template<unsigned M>
+struct NumericTraits<StridePair<M> >
+    : public NumericTraits<typename StridePair<M>::index_type>
+{};
+
+template<unsigned N>
+struct StridePairCoord : public TinyVector<double, N>
+{
+    typedef TinyVector<double, N> entry_type;
+
+    StridePairCoord(const entry_type & c) : entry_type(c) {}
+    StridePairCoord() {}
+
+    double & dim0()
+    {
+        return (*this)[0];
+    }
+    double dim0() const
+    {
+        return (*this)[0];
+    }
+};
+template<unsigned M>
+struct NumericTraits<StridePairCoord<M> >
+    : public NumericTraits<typename StridePairCoord<M>::entry_type>
+{};
+
+template<unsigned N>
+struct StridePairDiff : public StridePairCoord<N>
+{
+    MultiArrayIndex c;
+
+    typedef StridePairCoord<N> base_type;
+    StridePairDiff(MultiArrayIndex c_, const base_type & x)
+        : base_type(x), c(c_) {}
+    StridePairDiff(const base_type & x)
+        : base_type(x), c(0) {}
+    StridePairDiff(const TinyVector<double, N> & x)
+        : base_type(x), c(0) {}
+    StridePairDiff(const TinyVector<MultiArrayIndex, N> & x)
+        : base_type(x), c(0) {}
+    StridePairDiff() : c(0) {}
+
+    const base_type & base() const
+    {
+        return *this;
+    }
+    StridePairDiff operator*(const StridePairDiff & x)
+    {
+        StridePairDiff ret = base() * x.base();
+        ret.c = c * x.c;
+        return ret;
+    }
+};
+
+template<unsigned M>
+struct NumericTraits<StridePairDiff<M> >
+    : public NumericTraits<StridePairCoord<M> >
+{};
+
+template<unsigned N, class T>
+struct StridePairPointer : public StridePairCoord<N>
+{
+    typedef const T*                          index_type;
+    typedef StridePairCoord<N>                coord_type;
+    typedef typename coord_type::entry_type   coord_num_type;
+    typedef StridePairPointer                 type;
+    typedef type                              deref_type;
+    typedef StridePairDiff<N>                 stride_type;
+    typedef TinyVector<stride_type, N>        stride_array_type;
+    typedef typename MultiArrayShape<N>::type shape_array_type;
+    typedef          shape_array_type         shape_type;
+
+    index_type index;
+
+    StridePairPointer(const index_type & i, const coord_type & c)
+        : coord_type(c), index(i) {}
+
+    const type & operator*() const
+    {
+        return *this;
+    }
+    const T & value() const
+    {
+        return *index;
+    }
+    const coord_type & coord() const
+    {
+        return *this;
+    }
+
+    index_type & idx0()
+    {
+        return index;
+    }
+    const index_type & idx() const
+    {
+        return index;
+    }
+
+    void operator+=(stride_type x)
+    {
+        index += x.c;
+        coord_type::operator+=(x);
+    }
+    void operator-=(stride_type x)
+    {
+        index -= x.c;
+        coord_type::operator-=(x);
+    }
+};
+
+template<unsigned M, class T>
+struct NumericTraits<StridePairPointer<M, T> >
+    : public NumericTraits<typename StridePairPointer<M, T>::coord_type>
+{};
+
+namespace detail {
+
+template<class T, bool is_complex = NumericTraits<T>::isComplex::value,
+                  bool is_vector = !NumericTraits<T>::isScalar::value>
+struct weighted_abs
+{
+    static double get(const T & x)
+    {
+        return x;
+    }
+};
+
+template<class T>
+struct weighted_abs<T, true, false>
+{
+    static double get(const T & x)
+    {
+        using std::abs;
+        return abs(x);
+    }
+};
+
+template<class T, bool is_complex>
+struct weighted_abs<T, is_complex, true>
+{
+    static double get(const T & x)
+    {
+        return x.magnitude();
+    }
+};
+
+template<class T>
+struct accumulable_coord_access;
+template<class T>
+struct accumulable_value_access;
+template<class T>
+struct accumulable_weighted_access;
+
+template<unsigned N, class T>
+struct accumulable_coord_access<StridePairPointer<N, T> >
+{
+    typedef StridePairPointer<N, T> accumulable_type;
+    typedef typename accumulable_type::coord_num_type type;
+    static const type & get(const accumulable_type & v) { return v.coord(); }
+};
+
+template<unsigned N, class T>
+struct accumulable_value_access<StridePairPointer<N, T> >
+{
+    typedef StridePairPointer<N, T> accumulable_type;
+    typedef T type;
+    static const type & get(const accumulable_type & v) { return v.value(); }
+};
+
+template<unsigned N, class T>
+struct accumulable_weighted_access<StridePairPointer<N, T> >
+{
+    typedef StridePairPointer<N, T> accumulable_type;
+    typedef typename accumulable_type::coord_num_type type;
+    static type get(const accumulable_type & v)
+    {
+        return weighted_abs<T>::get(v.value()) * v.coord();
+    }
+};
+
+template<class X>
+void dismember(X & r, const X & x, unsigned i)
+{
+    r[i] = x[i];
+}
+template<unsigned N>
+void dismember(StridePair<N> & r, const StridePair<N> & x, unsigned i)
+{
+    r.index[i] = x.index[i];
+    r.coord[i] = x.coord[i];
+}
+template<unsigned N>
+void dismember(StridePairDiff<N> & r, const StridePairDiff<N> & x, unsigned i)
+{
+    r.c = static_cast<MultiArrayIndex>(r[i] = x[i]);
+}
+
+template<unsigned N, class X>
+TinyVector<X, N>
+dismember(const X & x)
+{
+    TinyVector<X, N> ret;
+    for (unsigned i = 0; i != N; ++i)
+        dismember(ret[i], x, i);
+    return ret;
+}
+template<unsigned N>
+TinyVector<StridePairDiff<N>, N>
+dismember(const TinyVector<MultiArrayIndex, N> & x,
+          const StridePairCoord<N> &             y)
+{
+    typedef StridePairDiff<N> type;
+    TinyVector<type, N> ret;
+    for (unsigned i = 0; i != N; ++i)
+    {
+        ret[i].c  = x[i];
+        ret[i][i] = y[i];
+    }
+    return ret;
+}
+
+} // namespace detail
+
+// A fake "pointer" for MultiIterator containing coordinates.
+// Indices (or a pointer) cannot be circumvented in coordiante iterators,
+// since floating point addition is not associative and
+// iterator comparison is done via via '<' or '!='. Class CoordinateStride
+// thus forwards iterator comparison to the index or pointer part
+// of its template parameter S.
+template<unsigned N, class S = StridePair<N> >
+class CoordinateStride : protected S
+{
+  public:
+    typedef          MultiArrayIndex     difference_type;
+    typedef typename S::stride_type      stride_type;
+    typedef typename S::deref_type       deref_type;
+    typedef          CoordinateStride<N> type;
+    typedef typename S::coord_type       coord_type;
+    typedef typename S::index_type       index_type;
+    typedef typename S::shape_array_type shape_array_type;
+
+  protected:
+    double stride_0;
+
+    CoordinateStride(void*) {} // used MultiIterator ctor, unused.
+
+  public:
+    CoordinateStride(const S & x, double s0)
+        : S(x), stride_0(s0) {}
+
+#ifndef DOXYGEN
+    using S::operator*;
+    using S::idx0;
+    using S::idx;
+    using S::dim0;
+    using S::operator+=;
+    using S::operator-=;
+#endif
+
+    void operator++()
+    {
+        ++idx0();
+        dim0() += stride_0;
+    }
+    void operator--()
+    {
+        --idx0();
+        dim0() -= stride_0;
+    }
+    void operator+=(difference_type n)
+    {
+        idx0() += n;
+        dim0() += n * stride_0;
+    }
+    void operator-=(difference_type n)
+    {
+        idx0() -= n;
+        dim0() -= n * stride_0;
+    }
+
+    stride_type operator[](difference_type n) const
+    {
+        type ret = *this;
+        ret[0] += n;
+        return ret;
+    }
+
+    stride_type operator[](stride_type x) const
+    {
+        return *this + x;
+    }
+
+    // ... but use the idx() for comparisons:
+    bool operator!=(const CoordinateStride & y) const
+    {
+        return idx() != y.idx();
+    }
+    bool operator==(const CoordinateStride & y) const
+    {
+        if (stride_0 != y.stride_0)
+            return false;
+        return idx() == y.idx();
+    }
+    bool operator<(const CoordinateStride & y) const
+    {
+        return idx() < y.idx();
+    }
+
+    bool operator<=(const CoordinateStride & y) const
+    {
+        if (stride_0 == y.stride_0)
+            return true;
+        return *this < y;
+    }
+    bool operator>(const CoordinateStride & y) const
+    {
+        return y < *this;
+    }
+    bool operator>=(const CoordinateStride & y) const
+    {
+        if (stride_0 == y.stride_0)
+            return true;
+        return operator>(y);
+    }
+
+    friend std::ostream &
+    operator<<(std::ostream & os, const CoordinateStride & x)
+    {
+        os << "{" << x.stride_0 << ": " << static_cast<const S &>(x) << "}";
+        return os;
+    }
+
+    typedef MultiIterator<N, deref_type, const deref_type &, CoordinateStride>
+        iterator_type;
+};
+
+template <unsigned N, class S>
+struct MultiIteratorStrideTraits<CoordinateStride<N, S> >
+{
+    typedef typename S::stride_type           stride_type;
+    typedef typename S::stride_array_type     stride_array_type;
+    typedef typename S::shape_array_type      shape_array_type;
+    static stride_array_type shift(const stride_array_type & s, unsigned d)
+    {
+        stride_array_type ret;
+        for (unsigned i = d; i != N; ++i)
+            ret[i - d] = s[i];
+        return ret;
+    }
+};
+
+template <unsigned N>
+struct CoordinateMultiIterator : public CoordinateStride<N>::iterator_type
+{
+    typedef CoordinateStride<N>                       ptr_type;
+    typedef typename ptr_type::iterator_type          base_type;
+    typedef typename ptr_type::stride_type            stride_type;
+    typedef typename ptr_type::shape_array_type       shape_array_type;
+    typedef typename ptr_type::coord_type             coord_type;
+    typedef typename ptr_type::index_type             index_type;
+
+    CoordinateMultiIterator(const stride_type & origin,
+                            const stride_type & stride,
+                            const index_type & shape)
+
+        : base_type(ptr_type(origin, stride.dim0()),
+                    detail::dismember<N>(stride),
+                    detail::dismember<N>(shape)) {}
+                                                 
+    CoordinateMultiIterator(const base_type & x) : base_type(x) {}
+};
+
+namespace detail {
+
+template<unsigned N>
+struct CoordinateMultiRangeReturns
+{
+    typedef          CoordinateMultiIterator<N>   iterator_type;
+    typedef typename iterator_type::coord_type    coord_type;
+    typedef          StridePair<N>                pair_type;
+    typedef typename pair_type::type              stride_type;
+    typedef typename pair_type::stride_array_type stride_array_type;
+
+    typedef typename AccessorTraits<coord_type>::default_const_accessor
+        access_type;
+    typedef triple<iterator_type, stride_array_type, access_type> type;
+};
+
+} // namespace detail
+
+template <unsigned N>
+typename detail::CoordinateMultiRangeReturns<N>::type
+coordinateMultiRange(const typename MultiArrayShape<N>::type & shape,
+                     const TinyVector<double, N> & stride
+                                                   = TinyVector<double, N>(1.0),
+                     const TinyVector<double, N> & origin
+                                                   = TinyVector<double, N>(0.0))
+{
+    typedef typename
+        detail::CoordinateMultiRangeReturns<N>::stride_type stride_type;
+    typedef typename
+        detail::CoordinateMultiRangeReturns<N>::access_type access_type;
+
+    return typename detail::CoordinateMultiRangeReturns<N>::type
+        (CoordinateMultiIterator<N>(stride_type(0, origin),
+                                    stride_type(1, stride),
+                                    shape),
+         detail::dismember<N>(stride_type(shape)),
+         access_type());
+}
+
+template <unsigned N, class T>
+struct CombinedMultiIterator
+    : public CoordinateStride<N, StridePairPointer<N, T> >::iterator_type
+{
+    typedef StridePairPointer<N, T>                   pair_type;
+    typedef CoordinateStride<N, pair_type>            ptr_type;
+    typedef typename ptr_type::iterator_type          base_type;
+    typedef typename ptr_type::stride_type            stride_type;
+    typedef typename ptr_type::coord_type             coord_type;
+    typedef typename pair_type::shape_array_type      shape_array_type;
+    
+    CombinedMultiIterator(const T*                               raw_pointer,
+                          const stride_type &                    origin,
+                          const TinyVector<MultiArrayIndex, N> & pointer_stride,
+                          const stride_type &                    stride,
+                          const shape_array_type &               shape)
+
+        : base_type(ptr_type(pair_type(raw_pointer, origin), stride.dim0()),
+                    detail::dismember<N>(pointer_stride, stride),
+                    shape) {}
+                                                 
+    CombinedMultiIterator(const base_type & x) : base_type(x) {}
+};
+
+template<unsigned N, class T>
+struct SrcCoordinateMultiArrayRangeReturns
+{
+    typedef          CombinedMultiIterator<N, T>  iterator_type;
+    typedef typename iterator_type::coord_type    coord_type;
+    typedef typename iterator_type::pair_type     pair_type;
+    typedef typename iterator_type::ptr_type      ptr_type;
+    typedef typename ptr_type::deref_type         deref_type;
+    typedef typename iterator_type::stride_type   stride_type;
+    typedef typename pair_type::stride_array_type stride_array_type;
+    typedef typename pair_type::shape_array_type  shape_array_type;
+
+    typedef typename AccessorTraits<deref_type>::default_const_accessor
+        access_type;
+    typedef triple<iterator_type, stride_array_type, access_type> type;
+};
+
+// work around GCC 4.4.3 template argument deduction bug:
+template<unsigned N>
+struct CoordinateSteps
+{
+    typedef const TinyVector<double, N> & type;
+};
+
+template <unsigned int N, class T, class StrideTag>
+inline typename SrcCoordinateMultiArrayRangeReturns<N, T>::type
+srcCoordinateMultiArrayRange(const MultiArrayView<N, T, StrideTag> & array,
+                             typename CoordinateSteps<N>::type stride
+                                                   = TinyVector<double, N>(1.0),
+                             typename CoordinateSteps<N>::type origin
+                                                   = TinyVector<double, N>(0.0))
+{
+    typedef SrcCoordinateMultiArrayRangeReturns<N, T> returns;
+    typedef typename returns::type                    type;
+    typedef typename returns::stride_type             stride_type;
+    typedef typename returns::access_type             access_type;
+    typedef typename returns::iterator_type           iterator_type;
+    typedef typename returns::shape_array_type        shape_array_type;
+    
+    shape_array_type shape = array.shape();
+    return type(iterator_type(array.traverser_begin().get(),
+                              stride_type(origin),
+                              array.stride(),
+                              stride_type(stride),
+                              shape),
+                detail::dismember<N>(stride_type(shape)),
+                access_type());
+}
+
+template <class VALUETYPE, class COORD>
+struct AccessorCoordinatePair
+{
+    typedef VALUETYPE                  value_type;
+    typedef COORD                      coord_type;
+    typedef AccessorCoordinatePair     type;
+
+          value_type   v;
+    const coord_type & c;
+
+    AccessorCoordinatePair(const value_type & v_, const coord_type & c_)
+        : v(v_), c(c_) {}
+
+    const value_type & value() const
+    {
+        return v;
+    }
+    const coord_type & coord() const
+    {
+        return c;
+    }
+};
+
+/** \brief Forward accessor to the value() part of the values an iterator
+           points to.
+
+    CoordinateConstValueAccessor is a accessor that forwards
+    the underlying accessor's operator() read functions.
+    It passes its arguments <em>by value</em>.
+
+    <b>\#include</b> \<vigra/coordinate_iterator.hxx\><br>
+    Namespace: vigra
+*/
+template <class Accessor, class COORD>
+class CoordinateConstValueAccessor
+{
+  public:
+    typedef typename Accessor::value_type               forward_type;
+    typedef AccessorCoordinatePair<forward_type, COORD> value_type;
+    Accessor a;
+    CoordinateConstValueAccessor(const Accessor & a_) : a(a_) {}
+        /** Read the current data item.
+        */
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const
+    {
+        const typename ITERATOR::value_type & x = *i;
+        return value_type(a(&x.value()), x.coord()); 
+    }
+        /** Read the data item at an offset.
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE const & diff) const
+    {
+        const typename ITERATOR::value_type & x = i[diff];
+        return value_type(a(&x.value()), x.coord());
+    }
+};
+
+template<unsigned N, class T, class Accessor>
+struct SrcCoordinateMultiArrayRangeAccessorReturns
+{
+    typedef          CombinedMultiIterator<N, T>  iterator_type;
+    typedef typename iterator_type::coord_type    coord_type;
+    typedef typename iterator_type::pair_type     pair_type;
+    typedef typename iterator_type::ptr_type      ptr_type;
+    typedef typename ptr_type::deref_type         deref_type;
+    typedef typename iterator_type::stride_type   stride_type;
+    typedef typename pair_type::stride_array_type stride_array_type;
+    typedef typename pair_type::shape_array_type  shape_array_type;
+
+    typedef CoordinateConstValueAccessor<Accessor, coord_type> access_type;
+    typedef triple<iterator_type, stride_array_type, access_type> type;
+};
+
+template <unsigned int N, class T, class StrideTag, class Access>
+inline typename SrcCoordinateMultiArrayRangeAccessorReturns<N, T, Access>::type
+srcCoordinateMultiArrayRangeAccessor(const MultiArrayView<N, T, StrideTag> &
+                                                                          array,
+                                     Access a,
+                                     typename CoordinateSteps<N>::type stride
+                                                   = TinyVector<double, N>(1.0),
+                                     typename CoordinateSteps<N>::type origin
+                                                   = TinyVector<double, N>(0.0))
+{
+    typedef SrcCoordinateMultiArrayRangeAccessorReturns<N, T, Access> returns;
+    typedef typename returns::type             type;
+    typedef typename returns::stride_type      stride_type;
+    typedef typename returns::access_type      access_type;
+    typedef typename returns::iterator_type    iterator_type;
+    typedef typename returns::shape_array_type shape_array_type;
+    
+    shape_array_type shape = array.shape();
+    return type(iterator_type(array.traverser_begin().get(),
+                              stride_type(origin),
+                              array.stride(),
+                              stride_type(stride),
+                              shape),
+                detail::dismember<N>(stride_type(shape)),
+                access_type(a));
+}
+
+} // namespace vigra
+
+namespace std {
+
+template <unsigned N>
+ostream &
+operator<<(ostream & os, const vigra::StridePair<N> & x)
+{
+    os << "[" << x.index << ", " << x.coord << "]";
+    return os;
+}
+
+template <unsigned N>
+ostream &
+operator<<(ostream & os, const vigra::StridePairDiff<N> & x)
+{
+    os << "<" << x.c << "; "
+       << static_cast<vigra::StridePairCoord<N> >(x) << ">";
+    return os;
+}
+
+template <unsigned N, class T>
+ostream &
+operator<<(ostream & os, const vigra::StridePairPointer<N, T> & x)
+{
+    os << "[" << x.value() << ", " << x.coord() << "]";
+    return os;
+}
+
+template <class VALUETYPE, class COORD>
+ostream &
+operator<<(ostream & os,
+           const vigra::AccessorCoordinatePair<VALUETYPE, COORD> & x)
+{
+    os << "[" << x.value() << ", " << x.coord() << "]";
+    return os;
+}
+
+} // namespace std
+
+#endif // VIGRA_COORDINATE_ITERATOR_HXX
diff --git a/include/vigra/copyimage.hxx b/include/vigra/copyimage.hxx
new file mode 100644
index 0000000..cccbf1c
--- /dev/null
+++ b/include/vigra/copyimage.hxx
@@ -0,0 +1,421 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_COPYIMAGE_HXX
+#define VIGRA_COPYIMAGE_HXX
+
+#include "utilities.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup CopyAlgo Algorithms to Copy Images
+    Copy images or regions
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                       copyLine                       */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+copyLine(SrcIterator s, 
+         SrcIterator send, SrcAccessor src,
+         DestIterator d, DestAccessor dest)
+{
+    for(; s != send; ++s, ++d)
+        dest.set(src(s), d);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class MaskIterator, class MaskAccessor, 
+          class DestIterator, class DestAccessor>
+void
+copyLineIf(SrcIterator s, 
+           SrcIterator send, SrcAccessor src,
+           MaskIterator m, MaskAccessor mask,
+           DestIterator d, DestAccessor dest)
+{
+    for(; s != send; ++s, ++d, ++m)
+        if(mask(m))
+            dest.set(src(s), d);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+swapLine(SrcIterator s, 
+         SrcIterator send, SrcAccessor src,
+         DestIterator d, DestAccessor dest)
+{
+    for(; s != send; ++s, ++d)
+    {
+        typename SrcAccessor::value_type t = src(s);
+        src.set(dest(d), s);
+        dest.set(t, d);
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*                        copyImage                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Copy source image into destination image.
+
+    If necessary, type conversion takes place.
+    Some variants of this function use accessors to access the pixel data.
+    
+    See \ref copyMultiArray() for a dimension-independent version of this algorithm.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        copyImage(MultiArrayView<2, T1, S1> const & src,
+                  MultiArrayView<2, T2, S2> dest);
+    }
+    \endcode
+    
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void
+        copyImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa,
+              DestImageIterator dest_upperleft, DestAccessor da)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void
+        copyImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                  pair<DestImageIterator, DestAccessor> dest)
+    }
+    \endcode
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/copyimage.hxx\><br>
+    Namespace: vigra
+
+    Use MultiArrayView API:
+    \code
+    MultiArray<2, int> src(Shape2(100, 200)),
+                       dest(Shape2(100, 200));
+    ...
+    
+    copyImage(src, dest);
+    
+    // equivalent to
+    dest = src;
+    \endcode
+
+    Use iterator-based API with accessor:
+    \code
+    MultiArray<2, RGBValue<unsigned char> > src(Shape2(100, 200)),
+    MultiArray<2, float>                    dest(Shape2(100, 200));
+    
+    // convert RGB to gray values in the fly
+    copyImage(srcImageRange(src, RGBToGrayAccessor<RGBValue<unsigned char> >()), 
+              destImage(dest));
+    \endcode
+    
+    <b> Required Interface:</b>
+    
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator      dest_upperleft;
+    SrcImageIterator::row_iterator sx = src_upperleft.rowIterator();
+    DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    dest_accessor.set(src_accessor(sx), dx);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void copyImage)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void
+copyImage(SrcImageIterator src_upperleft, 
+          SrcImageIterator src_lowerright, SrcAccessor sa,
+          DestImageIterator dest_upperleft, DestAccessor da)
+{
+    int w = src_lowerright.x - src_upperleft.x;
+    
+    for(; src_upperleft.y<src_lowerright.y; ++src_upperleft.y, ++dest_upperleft.y)
+    {
+        copyLine(src_upperleft.rowIterator(), 
+                 src_upperleft.rowIterator() + w, sa, 
+                 dest_upperleft.rowIterator(), da);
+    }
+}
+    
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline
+void
+copyImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+          pair<DestImageIterator, DestAccessor> dest)
+{
+    copyImage(src.first, src.second, src.third, 
+              dest.first, dest.second);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+copyImage(MultiArrayView<2, T1, S1> const & src,
+          MultiArrayView<2, T2, S2> dest)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "copyImage(): shape mismatch between input and output.");
+    copyImage(srcImageRange(src), destImage(dest));
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void
+swapImageData(SrcImageIterator src_upperleft, 
+              SrcImageIterator src_lowerright, SrcAccessor sa,
+              DestImageIterator dest_upperleft, DestAccessor da)
+{
+    int w = src_lowerright.x - src_upperleft.x;
+    
+    for(; src_upperleft.y<src_lowerright.y; ++src_upperleft.y, ++dest_upperleft.y)
+    {
+        swapLine(src_upperleft.rowIterator(), 
+                 src_upperleft.rowIterator() + w, sa, 
+                 dest_upperleft.rowIterator(), da);
+    }
+}
+    
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline
+void
+swapImageData(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+              pair<DestImageIterator, DestAccessor> dest)
+{
+    swapImageData(src.first, src.second, src.third, 
+                  dest.first, dest.second);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline
+void
+swapImageData(MultiArrayView<2, T1, S1> const & src,
+              MultiArrayView<2, T2, S2> dest)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "swapImageData(): shape mismatch between input and output.");
+    swapImageData(srcImageRange(src), destImage(dest));
+}
+
+/********************************************************/
+/*                                                      */
+/*                       copyImageIf                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Copy source ROI into destination image.
+
+    Pixel values are copied whenever the return value of the mask's
+    accessor is not zero.
+    If necessary, type conversion takes place.
+    Some variants of this function use accessors to access the pixel data.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class TM, class SM,
+                  class T2, class S2>
+        void
+        copyImageIf(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, TM, SM> const & mask,
+                    MultiArrayView<2, T2, S2> dest);
+    }
+    \endcode
+    
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class MaskImageIterator, class MaskAccessor,
+              class DestImageIterator, clas DestAccessor>
+        void
+        copyImageIf(SrcImageIterator src_upperleft, 
+            SrcImageIterator src_lowerright, SrcAccessor sa,
+            MaskImageIterator mask_upperleft, MaskAccessor ma,
+            DestImageIterator dest_upperleft, DestAccessor da)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class MaskImageIterator, class MaskAccessor,
+              class DestImageIterator, clas DestAccessor>
+        void
+        copyImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+            pair<MaskImageIterator, MaskAccessor> mask,
+            pair<DestImageIterator, DestAccessor> dest)
+    }
+    \endcode
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/copyimage.hxx\><br>
+    Namespace: vigra
+
+    Use MultiArrayView API:
+    \code
+    MultiArray<2, int> src(Shape2(100, 200)),
+                       mask(Shape2(100, 200)),
+                       dest(Shape2(100, 200));
+    ...
+    
+    copyImageIf(src, mask, dest);
+    \endcode
+
+    Use iterator-based API with accessor:
+    \code
+    MultiArray<2, RGBValue<unsigned char> > src(Shape2(100, 200)),
+    MultiArray<2, unsigned char>            mask(Shape2(100, 200));
+    MultiArray<2, float>                    dest(Shape2(100, 200));
+    
+    // convert RGB to gray values in the fly
+    copyImageIf(srcImageRange(src, RGBToGrayAccessor<RGBValue<unsigned char> >()), 
+                maskImage(mask), destImage(dest));
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+    MaskImageIterator mask_upperleft;
+    SrcImageIterator::row_iterator sx = src_upperleft.rowIterator();
+    MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator();
+    DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    MaskAccessor mask_accessor;
+    Functor functor;
+    
+    if(mask_accessor(mx))
+        dest_accessor.set(src_accessor(sx), dx);
+
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void copyImageIf)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class MaskImageIterator, class MaskAccessor,
+          class DestImageIterator, class DestAccessor>
+void
+copyImageIf(SrcImageIterator src_upperleft, 
+            SrcImageIterator src_lowerright, SrcAccessor sa,
+            MaskImageIterator mask_upperleft, MaskAccessor ma,
+        DestImageIterator dest_upperleft, DestAccessor da)
+{
+    int w = src_lowerright.x - src_upperleft.x;
+    
+    for(; src_upperleft.y<src_lowerright.y; 
+             ++src_upperleft.y, ++mask_upperleft.y, ++dest_upperleft.y)
+    {
+        copyLineIf(src_upperleft.rowIterator(), 
+                   src_upperleft.rowIterator() + w, sa, 
+                   mask_upperleft.rowIterator(), ma, 
+                   dest_upperleft.rowIterator(), da);
+    }
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class MaskImageIterator, class MaskAccessor,
+          class DestImageIterator, class DestAccessor>
+inline
+void
+copyImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+            pair<MaskImageIterator, MaskAccessor> mask,
+            pair<DestImageIterator, DestAccessor> dest)
+{
+    copyImageIf(src.first, src.second, src.third, 
+                mask.first, mask.second, 
+                dest.first, dest.second);
+}
+
+template <class T1, class S1,
+          class TM, class SM,
+          class T2, class S2>
+inline void
+copyImageIf(MultiArrayView<2, T1, S1> const & src,
+            MultiArrayView<2, TM, SM> const & mask,
+            MultiArrayView<2, T2, S2> dest)
+{
+    vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
+        "copyImageIf(): shape mismatch between input and output.");
+    copyImageIf(srcImageRange(src), 
+                maskImage(mask), 
+                destImage(dest));
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_COPYIMAGE_HXX
diff --git a/include/vigra/cornerdetection.hxx b/include/vigra/cornerdetection.hxx
new file mode 100644
index 0000000..5dd7bd5
--- /dev/null
+++ b/include/vigra/cornerdetection.hxx
@@ -0,0 +1,893 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_CORNERDETECTION_HXX
+#define VIGRA_CORNERDETECTION_HXX
+
+#include "utilities.hxx"
+#include "numerictraits.hxx"
+#include "stdimage.hxx"
+#include "combineimages.hxx"
+#include "convolution.hxx"
+#include "functortraits.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+template <class SrcType>
+struct CornerResponseFunctor
+{
+    typedef typename NumericTraits<SrcType>::RealPromote argument_type;
+    typedef argument_type result_type;
+    
+    result_type operator()(argument_type a1, 
+                        argument_type a2, argument_type a3) const
+    {
+      return detail::RequiresExplicitCast<result_type>::cast((a1*a2 - a3*a3) - 0.04 * (a1 + a2) * (a1 + a2));
+    }
+};
+
+template <class T>
+class FunctorTraits<CornerResponseFunctor<T> >
+: public FunctorTraitsBase<CornerResponseFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isTernaryFunctor;
+};
+
+template <class SrcType>
+struct FoerstnerCornerFunctor
+{
+    typedef typename NumericTraits<SrcType>::RealPromote argument_type;
+    typedef argument_type result_type;
+    
+    result_type operator()(argument_type a1, 
+                           argument_type a2, argument_type a3) const
+    {
+        return (a1*a2 - a3*a3) / (a1 + a2);
+    }
+};
+
+template <class T>
+class FunctorTraits<FoerstnerCornerFunctor<T> >
+: public FunctorTraitsBase<FoerstnerCornerFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isTernaryFunctor;
+};
+
+template <class SrcType>
+struct RohrCornerFunctor
+{
+    typedef typename NumericTraits<SrcType>::RealPromote argument_type;
+    typedef argument_type result_type;
+    
+    result_type operator()(argument_type a1, 
+                        argument_type a2, argument_type a3) const
+    {
+        return (a1*a2 - a3*a3);
+    }
+};
+
+template <class T>
+class FunctorTraits<RohrCornerFunctor<T> >
+: public FunctorTraitsBase<RohrCornerFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isTernaryFunctor;
+};
+
+template <class SrcType>
+struct BeaudetCornerFunctor
+{
+    typedef typename NumericTraits<SrcType>::RealPromote argument_type;
+    typedef argument_type result_type;
+    
+    result_type operator()(argument_type a1, 
+                        argument_type a2, argument_type a3) const
+    {
+        return (a3*a3 - a1*a2);
+    }
+};
+
+template <class T>
+class FunctorTraits<BeaudetCornerFunctor<T> >
+: public FunctorTraitsBase<BeaudetCornerFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isTernaryFunctor;
+};
+
+/** \addtogroup CornerDetection Corner Detection
+    Measure the 'cornerness' at each pixel.
+    Note: The Kitchen-Rosenfeld detector is not implemented because of its
+    inferior performance. The SUSAN detector is missing because it's patented.
+*/
+//@{ 
+                                    
+/********************************************************/
+/*                                                      */
+/*                 cornerResponseFunction               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find corners in an image (1).
+
+    This algorithm implements the so called 'corner response function'
+    to measure the 'cornerness' of each pixel in the image, according to
+    [C.G. Harris and M.J. Stevens: <em> "A Combined Corner and Edge Detector"</em>,
+    Proc. of 4th Alvey Vision Conference, 1988]. Several studies have found this to be a
+    very robust corner detector, although it moves the corners somewhat into one
+    region, depending on the scale.
+    
+    The algorithm first determines the structure tensor at each pixel by calling
+    \ref structureTensor(). Then the entries of the structure tensor are combined as 
+    
+    \f[
+        \mbox{\rm CornerResponse} = \mbox{\rm det(StructureTensor)} - 0.04 \mbox{\rm tr(StructureTensor)}^2
+        = A B - C^2 - 0.04 (A + B)^2
+    \f]
+    
+    The local maxima of the corner response denote the corners in the gray level 
+    image.
+    
+    The source value type must be a linear algebra, i.e. addition, subtraction, and
+    multiplication with itself, multiplication with doubles and 
+    \ref NumericTraits "NumericTraits" must 
+    be defined. 
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void 
+        cornerResponseFunction(MultiArrayView<2, T1, S1> const & src,
+                               MultiArrayView<2, T2, S2> dest,
+                               double scale);
+    }
+    \endcode
+    
+    \deprecatedAPI{cornerResponseFunction}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                               DestIterator dul, DestAccessor ad,
+                               double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void cornerResponseFunction(
+                   triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   double scale)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/cornerdetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), corners(w,h);
+    MultiArray<2, float>         corner_response(w,h);
+    ...
+    
+    // find corner response at scale 1.0
+    cornerResponseFunction(src, corner_response, 1.0);
+    
+    // find local maxima of corner response, mark with 1
+    localMaxima(corner_response, corners);
+    
+    // threshold corner response to keep only strong corners (above 400.0)
+    transformImage(corner_response, corner_response,
+                   Threshold<double, double>(400.0, std::numeric_limits<double>::max(), 0.0, 1.0)); 
+
+    // combine thresholding and local maxima
+    combineTwoImages(corners, corner_response,
+                     corners, std::multiplies<float>());
+    \endcode
+
+    \deprecatedUsage{cornerResponseFunction}
+    \code
+    vigra::BImage src(w,h), corners(w,h);
+    vigra::FImage corner_response(w,h);
+    
+    // empty corner image
+    corners.init(0.0);
+    ...
+    
+    // find corner response at scale 1.0
+    vigra::cornerResponseFunction(srcImageRange(src), destImage(corner_response), 
+                           1.0);
+    
+    // find local maxima of corner response, mark with 1
+    vigra::localMaxima(srcImageRange(corner_response), destImage(corners));
+    
+    // threshold corner response to keep only strong corners (above 400.0)
+    transformImage(srcImageRange(corner_response), destImage(corner_response),
+          vigra::Threshold<double, double>(
+               400.0, std::numeric_limits<double>::max(), 0.0, 1.0)); 
+
+    // combine thresholding and local maxima
+    vigra::combineTwoImages(srcImageRange(corners), srcImage(corner_response),
+                     destImage(corners), std::multiplies<float>());
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+    double d;
+    
+    u = u + u
+    u = u - u
+    u = u * u
+    u = d * u
+    
+    dest_accessor.set(u, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void cornerResponseFunction)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                       DestIterator dul, DestAccessor ad,
+                       double scale)
+{
+    vigra_precondition(scale > 0.0,
+                 "cornerResponseFunction(): Scale must be > 0");
+                 
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    
+    if(w <= 0 || h <= 0) return;
+    
+    typedef typename 
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+        
+    typedef BasicImage<TmpType> TmpImage;
+    
+    TmpImage gx(w,h);
+    TmpImage gy(w,h);
+    TmpImage gxy(w,h);
+
+    structureTensor(srcIterRange(sul, slr, as), 
+                    destImage(gx), destImage(gxy), destImage(gy), 
+                    scale, scale);
+    CornerResponseFunctor<typename SrcAccessor::value_type > cf;
+                    
+    combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), 
+                       destIter(dul, ad), cf );
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline 
+void cornerResponseFunction(
+           triple<SrcIterator, SrcIterator, SrcAccessor> src,
+           pair<DestIterator, DestAccessor> dest,
+           double scale)
+{
+    cornerResponseFunction(src.first, src.second, src.third,
+                            dest.first, dest.second,
+                            scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void 
+cornerResponseFunction(MultiArrayView<2, T1, S1> const & src,
+                       MultiArrayView<2, T2, S2> dest,
+                       double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "cornerResponseFunction(): shape mismatch between input and output.");
+    cornerResponseFunction(srcImageRange(src), destImage(dest), scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*               foerstnerCornerDetector                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find corners in an image (2).
+
+    This algorithm implements the so called 'Foerstner Corner Detector'
+    to measure the 'cornerness' of each pixel in the image, according to
+    [W. Förstner: <em> "A feature based correspondence algorithms for image
+    matching"</em>, Intl. Arch. Photogrammetry and Remote Sensing, vol. 24, pp 160-166, 
+    1986]. It is also known as the "Plessey Detector" by Harris. However, it should not 
+    be confused with the
+    "\link cornerResponseFunction Corner Response Function\endlink ",
+    another detector invented by Harris.
+    
+    The algorithm first determines the structure tensor at each pixel by calling
+    \ref structureTensor(), where the given scale is used for both the inner and outer scales. 
+    Then the entries of the structure tensor are combined as 
+    
+    \f[
+        \mbox{\rm FoerstnerCornerStrength} = \frac{\mbox{\rm det(StructureTensor)}}{\mbox{\rm tr(StructureTensor)}} = 
+        \frac{A B - C^2}{A + B}
+    \f]
+    
+    The local maxima of the corner strength denote the corners in the gray level 
+    image. Its performance is similar to the \ref cornerResponseFunction().
+    
+    The source value type must be a division algebra, i.e. addition, subtraction,
+    multiplication, and division with itself, multiplication with doubles and 
+    \ref NumericTraits "NumericTraits" must 
+    be defined.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        foerstnerCornerDetector(MultiArrayView<2, T1, S1> const & src,
+                                MultiArrayView<2, T2, S2> dest,
+                                double scale);
+    }
+    \endcode
+    
+    \deprecatedAPI{foerstnerCornerDetector}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                               DestIterator dul, DestAccessor ad,
+                               double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+         void foerstnerCornerDetector(
+                   triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   double scale)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/cornerdetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), corners(w,h);
+    MultiArray<2, float>         foerstner_corner_strength(w,h);
+    ...
+    
+    // find corner response at scale 1.0
+    foerstnerCornerDetector(src, foerstner_corner_strength, 1.0);
+    
+    // find local maxima of corner response, mark with 1
+    localMaxima(foerstner_corner_strength, corners);
+    \endcode
+
+    \deprecatedUsage{foerstnerCornerDetector}
+    \code
+    vigra::BImage src(w,h), corners(w,h);
+    vigra::FImage foerstner_corner_strength(w,h);
+    
+    // empty corner image
+    corners.init(0.0);
+    ...
+    
+    // find corner response at scale 1.0
+    vigra::foerstnerCornerDetector(srcImageRange(src), destImage(foerstner_corner_strength), 
+                                   1.0);
+    
+    // find local maxima of corner response, mark with 1
+    vigra::localMaxima(srcImageRange(foerstner_corner_strength), destImage(corners));
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+    double d;
+    
+    u = u + u
+    u = u - u
+    u = u * u
+    u = u / u
+    u = d * u
+    
+    dest_accessor.set(u, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void foerstnerCornerDetector)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                       DestIterator dul, DestAccessor ad,
+                       double scale)
+{
+    vigra_precondition(scale > 0.0,
+                 "foerstnerCornerDetector(): Scale must be > 0");
+                 
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    
+    if(w <= 0 || h <= 0) return;
+    
+    typedef typename 
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+        
+    typedef BasicImage<TmpType> TmpImage;
+    
+    TmpImage gx(w,h);
+    TmpImage gy(w,h);
+    TmpImage gxy(w,h);
+
+    structureTensor(srcIterRange(sul, slr, as), 
+                    destImage(gx), destImage(gxy), destImage(gy), 
+                    scale, scale);
+    FoerstnerCornerFunctor<typename SrcAccessor::value_type > cf;
+                    
+    combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), 
+                       destIter(dul, ad), cf );
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+foerstnerCornerDetector(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        pair<DestIterator, DestAccessor> dest,
+                        double scale)
+{
+    foerstnerCornerDetector(src.first, src.second, src.third,
+                            dest.first, dest.second,
+                            scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+foerstnerCornerDetector(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, T2, S2> dest,
+                        double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "foerstnerCornerDetector(): shape mismatch between input and output.");
+    foerstnerCornerDetector(srcImageRange(src),
+                            destImage(dest),
+                            scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*                   rohrCornerDetector                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find corners in an image (3).
+
+    This algorithm implements yet another structure tensor-based corner detector, 
+    according to [K. Rohr: <em>"Untersuchung von grauwertabhängigen 
+    Transformationen zur Ermittlung der optischen Flusses in Bildfolgen"</em>, 
+    Diploma thesis, Inst. für Nachrichtensysteme, Univ. Karlsruhe, 1987, see also
+    K. Rohr: <em>"Modelling and Identification of Characteristic Intensity Variations"</em>,
+    Image and Vision Computing 10:2 (1992) 66-76 and K. Rohr: <em>"Localization Properties of 
+    Direct Corner Detectors"</em>, J. of Mathematical Imaging and Vision 4:2 (1994) 139-150]. 
+    
+    The algorithm first determines the structure tensor at each pixel by calling
+    \ref structureTensor(), where the given scale is used for both the inner and outer scales. 
+    Then the entries of the structure tensor are combined as 
+    
+    \f[
+        \mbox{\rm RohrCornerStrength} = \mbox{\rm det(StructureTensor)} = A B - C^2
+    \f]
+    
+    The local maxima of the corner strength denote the corners in the gray level 
+    image. Its performance is similar to the \ref cornerResponseFunction().
+    
+    The source value type must be a linear algebra, i.e. addition, subtraction, and
+    multiplication with itself, multiplication with doubles and 
+    \ref NumericTraits "NumericTraits" must be defined.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        rohrCornerDetector(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, T2, S2> dest,
+                           double scale);
+    }
+    \endcode
+    
+    \deprecatedAPI{rohrCornerDetector}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                           DestIterator dul, DestAccessor ad,
+                           double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void rohrCornerDetector(
+                   triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   double scale)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/cornerdetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), corners(w,h);
+    MultiArray<2, float>         rohr_corner_strength(w,h);
+    ...
+    
+    // find corner response at scale 1.0
+    rohrCornerDetector(src, rohr_corner_strength, 1.0);
+    
+    // find local maxima of corner response, mark with 1
+    localMaxima(rohr_corner_strength, corners);
+    \endcode
+
+    \deprecatedUsage{rohrCornerDetector}
+    \code
+    vigra::BImage src(w,h), corners(w,h);
+    vigra::FImage rohr_corner_strength(w,h);
+    
+    // empty corner image
+    corners.init(0.0);
+    ...
+    
+    // find corner response at scale 1.0
+    vigra::rohrCornerDetector(srcImageRange(src), destImage(rohr_corner_strength), 
+                              1.0);
+    
+    // find local maxima of corner response, mark with 1
+    vigra::localMaxima(srcImageRange(rohr_corner_strength), destImage(corners));
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+    double d;
+    
+    u = u + u
+    u = u - u
+    u = u * u
+    u = d * u
+    
+    dest_accessor.set(u, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void rohrCornerDetector)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                       DestIterator dul, DestAccessor ad,
+                       double scale)
+{
+    vigra_precondition(scale > 0.0,
+                 "rohrCornerDetector(): Scale must be > 0");
+                 
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    
+    if(w <= 0 || h <= 0) return;
+    
+    typedef typename 
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+        
+    typedef BasicImage<TmpType> TmpImage;
+    
+    TmpImage gx(w,h);
+    TmpImage gy(w,h);
+    TmpImage gxy(w,h);
+
+    structureTensor(srcIterRange(sul, slr, as), 
+                    destImage(gx), destImage(gxy), destImage(gy), 
+                    scale, scale);
+    RohrCornerFunctor<typename SrcAccessor::value_type > cf;
+                    
+    combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), 
+                       destIter(dul, ad), cf );
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+rohrCornerDetector(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   double scale)
+{
+    rohrCornerDetector(src.first, src.second, src.third,
+                       dest.first, dest.second,
+                       scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+rohrCornerDetector(MultiArrayView<2, T1, S1> const & src,
+                   MultiArrayView<2, T2, S2> dest,
+                   double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "rohrCornerDetector(): shape mismatch between input and output.");
+    rohrCornerDetector(srcImageRange(src),
+                       destImage(dest),
+                       scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*                 beaudetCornerDetector                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find corners in an image (4).
+
+    This algorithm implements a corner detector  
+    according to [P.R. Beaudet: <em> "Rotationally Invariant Image Operators"</em>, 
+    Proc. Intl. Joint Conf. on Pattern Recognition, Kyoto, Japan, 1978, pp. 579-583]. 
+    
+    The algorithm calculates the corner strength as the negative determinant of the 
+    \link hessianMatrixOfGaussian() Hessian Matrix\endlink. 
+    The local maxima of the corner strength denote the corners in the gray level 
+    image. 
+    
+    The source value type must be a linear algebra, i.e. addition, subtraction, and
+    multiplication with itself, multiplication with doubles and 
+    \ref NumericTraits "NumericTraits" must 
+    be defined.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        beaudetCornerDetector(MultiArrayView<2, T1, S1> const & src,
+                              MultiArrayView<2, T2, S2> dest,
+                              double scale);
+    }
+    \endcode
+    
+    \deprecatedAPI{beaudetCornerDetector}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                           DestIterator dul, DestAccessor ad,
+                           double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void beaudetCornerDetector(
+                   triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   double scale)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/cornerdetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), corners(w,h);
+    MultiArray<2, float>         beaudet_corner_strength(w,h);
+    ...
+    
+    // find corner response at scale 1.0
+    beaudetCornerDetector(src, beaudet_corner_strength, 1.0);
+    
+    // find local maxima of corner response, mark with 1
+    localMaxima(beaudet_corner_strength, corners);
+    \endcode
+
+    \deprecatedUsage{beaudetCornerDetector}
+    \code
+    vigra::BImage src(w,h), corners(w,h);
+    vigra::FImage beaudet_corner_strength(w,h);
+    
+    // empty corner image
+    corners.init(0.0);
+    ...
+    
+    // find corner response at scale 1.0
+    vigra::beaudetCornerDetector(srcImageRange(src), destImage(beaudet_corner_strength), 
+                              1.0);
+    
+    // find local maxima of corner response, mark with 1
+    vigra::localMaxima(srcImageRange(beaudet_corner_strength), destImage(corners));
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+    double d;
+    
+    u = u + u
+    u = u - u
+    u = u * u
+    u = d * u
+    
+    dest_accessor.set(u, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void beaudetCornerDetector)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                       DestIterator dul, DestAccessor ad,
+                       double scale)
+{
+    vigra_precondition(scale > 0.0,
+                 "beaudetCornerDetector(): Scale must be > 0");
+                 
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    
+    if(w <= 0 || h <= 0) return;
+    
+    typedef typename 
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+        
+    typedef BasicImage<TmpType> TmpImage;
+    
+    TmpImage gx(w,h);
+    TmpImage gy(w,h);
+    TmpImage gxy(w,h);
+
+    hessianMatrixOfGaussian(srcIterRange(sul, slr, as), 
+                    destImage(gx), destImage(gxy), destImage(gy), 
+                    scale);
+    BeaudetCornerFunctor<typename SrcAccessor::value_type > cf;
+                    
+    combineThreeImages(srcImageRange(gx), srcImage(gy), srcImage(gxy), 
+                       destIter(dul, ad), cf );
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+beaudetCornerDetector(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                      pair<DestIterator, DestAccessor> dest,
+                      double scale)
+{
+    beaudetCornerDetector(src.first, src.second, src.third,
+                          dest.first, dest.second,
+                          scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+beaudetCornerDetector(MultiArrayView<2, T1, S1> const & src,
+                      MultiArrayView<2, T2, S2> dest,
+                      double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "beaudetCornerDetector(): shape mismatch between input and output.");
+    beaudetCornerDetector(srcImageRange(src),
+                          destImage(dest),
+                          scale);
+}
+
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_CORNERDETECTION_HXX
diff --git a/include/vigra/diff2d.hxx b/include/vigra/diff2d.hxx
new file mode 100644
index 0000000..da8fb94
--- /dev/null
+++ b/include/vigra/diff2d.hxx
@@ -0,0 +1,1425 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 1998-2003 by Hans Meine                   */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_DIFF2D_HXX
+#define VIGRA_DIFF2D_HXX
+
+#include <cmath> // for sqrt()
+#include <iosfwd>
+#include "config.hxx"
+#include "iteratortags.hxx"
+#include "iteratortraits.hxx"
+#include "iteratoradapter.hxx"
+#include "tuple.hxx"
+
+
+namespace vigra {
+
+
+template <class Diff>
+class Diff2DConstRowIteratorPolicy
+{
+  public:
+    typedef Diff                            BaseType;
+    typedef Diff                            value_type;
+    typedef typename Diff::MoveX            difference_type;
+    typedef Diff const &                    reference;
+    typedef Diff                            index_reference;
+    typedef Diff const *                    pointer;
+    typedef std::random_access_iterator_tag iterator_category;
+
+    static void initialize(BaseType &) {}
+
+    static reference dereference(BaseType const & d)
+        { return d; }
+
+    static index_reference dereference(BaseType d, difference_type n)
+    {
+        d.x += n;
+        return d;
+    }
+
+    static bool equal(BaseType const & d1, BaseType const & d2)
+        { return d1.x == d2.x; }
+
+    static bool less(BaseType const & d1, BaseType const & d2)
+        { return d1.x < d2.x; }
+
+    static difference_type difference(BaseType const & d1, BaseType const & d2)
+        { return d1.x - d2.x; }
+
+    static void increment(BaseType & d)
+        { ++d.x; }
+
+    static void decrement(BaseType & d)
+        { --d.x; }
+
+    static void advance(BaseType & d, difference_type n)
+        { d.x += n; }
+};
+
+template <class Diff>
+class Diff2DConstColumnIteratorPolicy
+{
+  public:
+    typedef Diff                            BaseType;
+    typedef Diff                            value_type;
+    typedef typename Diff::MoveY            difference_type;
+    typedef Diff const &                    reference;
+    typedef Diff                            index_reference;
+    typedef Diff const *                    pointer;
+    typedef std::random_access_iterator_tag iterator_category;
+
+    static void initialize(BaseType & /*d*/) {}
+
+    static reference dereference(BaseType const & d)
+        { return d; }
+
+    static index_reference dereference(BaseType d, difference_type n)
+    {
+        d.y += n;
+        return d;
+    }
+
+    static bool equal(BaseType const & d1, BaseType const & d2)
+        { return d1.y == d2.y; }
+
+    static bool less(BaseType const & d1, BaseType const & d2)
+        { return d1.y < d2.y; }
+
+    static difference_type difference(BaseType const & d1, BaseType const & d2)
+        { return d1.y - d2.y; }
+
+    static void increment(BaseType & d)
+        { ++d.y; }
+
+    static void decrement(BaseType & d)
+        { --d.y; }
+
+    static void advance(BaseType & d, difference_type n)
+        { d.y += n; }
+};
+
+/** \addtogroup RangesAndPoints Ranges and Points
+
+    Specify 2-D and N-D positions, extents, and boxes.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                      Diff2D                          */
+/*                                                      */
+/********************************************************/
+
+/** \brief Two dimensional difference vector.
+
+    This class acts primarily as a difference vector for specifying
+    pixel coordinates and region sizes. In addition, Diff2D fulfills
+    the requirements of an \ref ImageIterator, so that it can be used to
+    simulate an image whose pixels' values equal their coordinates. This
+    secondary usage is explained on page \ref CoordinateIterator.
+
+    Standard usage as a difference vector is mainly needed in the context
+    of images. For example, Diff2D may be used as an index for <TT>operator[]</TT>:
+
+    \code
+    vigra::Diff2D location(...);
+
+    value = image[location];
+    \endcode
+
+    This is especially important in connection with accessors, where the
+    offset variant of <TT>operator()</TT> takes only one offset object:
+
+    \code
+    // accessor(iterator, dx, dy); is not allowed
+    value = accessor(iterator, vigra::Diff2D(dx, dy));
+    \endcode
+
+
+    Diff2D is also returned by <TT>image.size()</TT>, so that we can create
+    new images by calculating their size using Diff2D's arithmetic
+    functions:
+
+    \code
+    // create an image that is 10 pixels smaller in each direction
+    Image new_image(old_image.size() - Diff2D(10,10));
+    \endcode
+
+    <b>\#include</b> \<vigra/diff2d.hxx\><br>
+    Namespace: vigra
+*/
+class Diff2D
+{
+  public:
+        /** The iterator's value type: a coordinate.
+        */
+    typedef Diff2D PixelType;
+
+        /** The iterator's value type: a coordinate.
+        */
+    typedef Diff2D value_type;
+
+        /** the iterator's reference type (return type of <TT>*iter</TT>)
+        */
+    typedef Diff2D const &       reference;
+
+        /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
+        */
+    typedef Diff2D               index_reference;
+
+        /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
+        */
+    typedef Diff2D const *       pointer;
+
+        /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
+        */
+    typedef Diff2D               difference_type;
+
+        /** the iterator tag (image traverser)
+        */
+    typedef image_traverser_tag  iterator_category;
+
+        /** The associated row iterator.
+        */
+    typedef IteratorAdaptor<Diff2DConstRowIteratorPolicy<Diff2D> >    row_iterator;
+
+        /** The associated column iterator.
+        */
+   typedef IteratorAdaptor<Diff2DConstColumnIteratorPolicy<Diff2D> > column_iterator;
+
+        /** type of the iterator's x-navigator
+        */
+    typedef int MoveX;
+        /** type of the iterator's y-navigator
+        */
+    typedef int MoveY;
+
+
+        /** Default Constructor. Init iterator at position (0,0)
+        */
+    Diff2D()
+    : x(0), y(0)
+    {}
+
+        /** Construct at given position.
+        */
+    Diff2D(int ax, int ay)
+    : x(ax), y(ay)
+    {}
+
+        /** Copy Constructor.
+        */
+    Diff2D(Diff2D const & v)
+    : x(v.x), y(v.y)
+    {}
+
+        /** Copy Assigment.
+        */
+    Diff2D & operator=(Diff2D const & v)
+    {
+        if(this != &v)
+        {
+            x = v.x;
+            y = v.y;
+        }
+        return *this;
+    }
+
+        /** Unary negation.
+        */
+    Diff2D operator-() const
+    {
+        return Diff2D(-x, -y);
+    }
+
+        /** Increase coordinate by specified offset.
+        */
+    Diff2D & operator+=(Diff2D const & offset)
+    {
+        x += offset.x;
+        y += offset.y;
+        return *this;
+    }
+
+        /** Decrease coordinate by specified vector.
+        */
+    Diff2D & operator-=(Diff2D const & offset)
+    {
+        x -= offset.x;
+        y -= offset.y;
+        return *this;
+    }
+
+       /** Create vector by scaling by factor.
+        */
+    Diff2D & operator*=(int factor)
+    {
+        x *= factor;
+        y *= factor;
+        return *this;
+    }
+
+       /** Create vector by scaling by factor.
+        */
+    Diff2D & operator*=(double factor)
+    {
+        x = (int)(x * factor);
+        y = (int)(y * factor);
+        return *this;
+    }
+
+       /** Create vector by scaling by 1/factor.
+        */
+    Diff2D & operator/=(int factor)
+    {
+        x /= factor;
+        y /= factor;
+        return *this;
+    }
+
+       /** Create vector by scaling by 1/factor.
+        */
+    Diff2D & operator/=(double factor)
+    {
+        x = (int)(x / factor);
+        y = (int)(y / factor);
+        return *this;
+    }
+
+       /** Create vector by scaling by factor.
+        */
+    Diff2D operator*(int factor) const
+    {
+        return Diff2D(x * factor, y * factor);
+    }
+
+       /** Create vector by scaling by factor.
+        */
+    Diff2D operator*(double factor) const
+    {
+        return Diff2D((int)(x * factor), (int)(y * factor));
+    }
+
+       /** Create vector by scaling by 1/factor.
+        */
+    Diff2D operator/(int factor) const
+    {
+        return Diff2D(x / factor, y / factor);
+    }
+
+       /** Create vector by scaling by 1/factor.
+        */
+    Diff2D operator/(double factor) const
+    {
+        return Diff2D((int)(x / factor), (int)(y / factor));
+    }
+
+        /** Calculate length of difference vector.
+        */
+    int squaredMagnitude() const
+    {
+        return x*x + y*y;
+    }
+
+        /** Calculate length of difference vector.
+        */
+    double magnitude() const
+    {
+        return VIGRA_CSTD::sqrt((double)squaredMagnitude());
+    }
+
+        /** Equality.
+        */
+    bool operator==(Diff2D const & r) const
+    {
+        return (x == r.x) && (y == r.y);
+    }
+
+        /** Inequality.
+        */
+    bool operator!=(Diff2D const & r) const
+    {
+        return (x != r.x) || (y != r.y);
+    }
+
+        /** Used for both access to the current x-coordinate \em and
+            to specify that an iterator navigation command is to be
+            applied in x-direction. <br>
+            usage:  <TT> x = diff2d.x </TT> (use \p Diff2D::x  as component of difference vector) <br>
+            or <TT>  ++diff.x   </TT> (use Diff2D as iterator, move right)
+         */
+    int x;
+        /** Used for both access to the current y-coordinate \em and
+            to specify that an iterator navigation command is to be
+            applied in y-direction. <br>
+            usage:  <TT> y = diff2d.y </TT> (use \p Diff2D::y as component of difference vector) <br>
+            or <TT>  ++diff.y   </TT> (use Diff2D as iterator, move right)
+        */
+    int y;
+
+        /** Access current coordinate.
+        */
+    reference operator*() const
+    {
+        return *this;
+    }
+
+        /** Read coordinate at an offset.
+        */
+    index_reference operator()(int const & dx, int const & dy) const
+    {
+        return Diff2D(x + dx, y + dy);
+    }
+
+        /** Read coordinate at an offset.
+        */
+    index_reference operator[](Diff2D const & offset) const
+    {
+        return Diff2D(x + offset.x, y + offset.y);
+    }
+
+        /** Read vector components.
+        */
+    int operator[](int index) const
+    {
+        return (&x)[index];
+    }
+
+        /** Access current coordinate.
+        */
+    pointer operator->() const
+    {
+        return this;
+    }
+
+        /** Get a row iterator at the current position.
+        */
+    row_iterator rowIterator() const
+        { return row_iterator(*this); }
+
+        /** Get a column iterator at the current position.
+        */
+    column_iterator columnIterator() const
+        { return column_iterator(*this); }
+};
+
+
+template <>
+struct IteratorTraits<Diff2D >
+{
+    typedef Diff2D                               Iterator;
+    typedef Iterator                             iterator;
+    typedef Iterator                             const_iterator;
+    // typedef                                   multable_iterator; undefined
+    typedef iterator::iterator_category          iterator_category;
+    typedef iterator::value_type                 value_type;
+    typedef iterator::reference                  reference;
+    typedef iterator::index_reference            index_reference;
+    typedef iterator::pointer                    pointer;
+    typedef iterator::difference_type            difference_type;
+    typedef iterator::row_iterator               row_iterator;
+    typedef iterator::column_iterator            column_iterator;
+    typedef StandardConstValueAccessor<Diff2D>   DefaultAccessor;
+    typedef StandardConstValueAccessor<Diff2D>   default_accessor;
+    typedef VigraTrueType                        hasConstantStrides;
+
+};
+
+/********************************************************/
+/*                                                      */
+/*                      Size2D                          */
+/*                                                      */
+/********************************************************/
+
+/** \brief Two dimensional size object.
+
+    Specializes \ref Diff2D for the specification of a 2-dimensional
+    extent, in contrast to a point or position (for the latter
+    use \ref Point2D).
+
+    \code
+    // create an image that is 10 pixels squared
+    Image new_image(Size2D(10,10));
+    \endcode
+
+    <b>\#include</b> \<vigra/diff2d.hxx\><br>
+    Namespace: vigra
+*/
+class Size2D : public Diff2D
+{
+public:
+        /** Default Constructor. Init point at position (0,0)
+        */
+    Size2D()
+    {}
+
+        /** Construct point at given position.
+        */
+    Size2D(int width, int height)
+    : Diff2D(width, height)
+    {}
+
+        /** Copy Constructor.
+        */
+    Size2D(Size2D const & v)
+    : Diff2D(v)
+    {}
+
+        /** Explicit conversion Constructor.
+        */
+    explicit Size2D(Diff2D const & v)
+    : Diff2D(v)
+    {}
+
+        /** Query the width.
+         */
+    int width() const
+    {
+        return x;
+    }
+
+        /** Query the height.
+         */
+    int height() const
+    {
+        return y;
+    }
+
+        /** Change the width.
+         */
+    void setWidth(int w)
+    {
+        x = w;
+    }
+
+        /** Change the height.
+         */
+    void setHeight(int h)
+    {
+        y = h;
+    }
+
+        /** Returns width()*height(), the area of a rectangle of this size.
+         */
+    int area() const
+    {
+        return width()*height();
+    }
+
+        /** Copy Assigment.
+        */
+    Size2D & operator=(Diff2D const & v)
+    {
+        return static_cast<Size2D &>(Diff2D::operator=(v));
+    }
+
+        /** Unary negation.
+        */
+    Size2D operator-() const
+    {
+        return Size2D(-x, -y);
+    }
+
+        /** Increase size by specified offset.
+        */
+    Size2D & operator+=(Diff2D const & offset)
+    {
+        return static_cast<Size2D &>(Diff2D::operator+=(offset));
+    }
+
+        /** Decrease size by specified offset.
+        */
+    Size2D & operator-=(Diff2D const & offset)
+    {
+        return static_cast<Size2D &>(Diff2D::operator-=(offset));
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                     Point2D                          */
+/*                                                      */
+/********************************************************/
+
+/** \brief Two dimensional point or position.
+
+    Specializes \ref Diff2D for the specification of a 2-dimensional
+    point or position, in contrast to an extent (for the latter
+    use \ref Size2D).
+
+    \code
+    // access an image at a point
+    value = image[Point2D(10, 20)];
+    \endcode
+
+    <b>\#include</b> \<vigra/diff2d.hxx\><br>
+    Namespace: vigra
+*/
+class Point2D : public Diff2D
+{
+public:
+        /** The iterator's value type: a coordinate.
+        */
+    typedef Point2D PixelType;
+
+        /** The iterator's value type: a coordinate.
+        */
+    typedef Point2D value_type;
+
+        /** the iterator's reference type (return type of <TT>*iter</TT>)
+        */
+    typedef Point2D const & reference;
+
+        /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
+        */
+    typedef Point2D         index_reference;
+
+        /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
+        */
+    typedef Point2D const * pointer;
+
+        /** Default Constructor. Init point at position (0,0)
+        */
+    Point2D()
+    {}
+
+        /** Construct point at given position.
+        */
+    Point2D(int x, int y)
+    : Diff2D(x, y)
+    {}
+
+        /** Copy Constructor.
+        */
+    Point2D(Point2D const & v)
+    : Diff2D(v)
+    {}
+
+        /** Explicit conversion Constructor.
+        */
+    explicit Point2D(Diff2D const & v)
+    : Diff2D(v)
+    {}
+
+        /** Query the points' x coordinate
+         */
+    int px() const
+    {
+        return x;
+    }
+
+        /** Query the points' y coordinate
+         */
+    int py() const
+    {
+        return y;
+    }
+
+        /** Copy Assigment.
+        */
+    Point2D & operator=(Diff2D const & v)
+    {
+        return static_cast<Point2D &>(Diff2D::operator=(v));
+    }
+
+        /** Unary negation.
+        */
+    Point2D operator-() const
+    {
+        return Point2D(-x, -y);
+    }
+
+        /** Increase point coordinates by specified offset.
+        */
+    Point2D & operator+=(Diff2D const & offset)
+    {
+        return static_cast<Point2D &>(Diff2D::operator+=(offset));
+    }
+
+        /** Decrease point coordinates by specified offset.
+        */
+    Point2D & operator-=(Diff2D const & offset)
+    {
+        return static_cast<Point2D &>(Diff2D::operator-=(offset));
+    }
+
+        /** Access current point coordinate.
+        */
+    reference operator*() const
+    {
+        return *this;
+    }
+
+        /** Read point coordinate at an offset.
+        */
+    index_reference operator()(int const & dx, int const & dy) const
+    {
+        return Point2D(x + dx, y + dy);
+    }
+
+        /** Read point coordinate at an offset.
+        */
+    index_reference operator[](Diff2D const & offset) const
+    {
+        return Point2D(x + offset.x, y + offset.y);
+    }
+
+        /** Access current point coordinate.
+        */
+    pointer operator->() const
+    {
+        return this;
+    }
+};
+
+/** Create vector by subtracting specified offset.
+ */
+inline Diff2D operator-(Diff2D const &a, Diff2D const &b)
+{
+    return Diff2D(a.x - b.x, a.y - b.y);
+}
+
+/** Create size by subtracting specified offset.
+ */
+inline Size2D operator-(Size2D const & s, Diff2D const &offset)
+{
+    return Size2D(s.x - offset.x, s.y - offset.y);
+}
+
+/** Calculate size of rect between two points.
+ */
+inline Point2D operator-(Point2D const & s, Diff2D const & offset)
+{
+    return Point2D(s.x - offset.x, s.y - offset.y);
+}
+
+/** The difference of two points is a size
+ */
+inline Size2D operator-(Point2D const & s, Point2D const & p)
+{
+    return Size2D(s.x - p.x, s.y - p.y);
+}
+
+/** Create vector by adding specified offset.
+ */
+inline Diff2D operator+(Diff2D const &a, Diff2D const &b)
+{
+    return Diff2D(a.x + b.x, a.y + b.y);
+}
+
+/** Create size by adding specified offset.
+ */
+inline Size2D operator+(Size2D const &a, Diff2D const &b)
+{
+    return Size2D(a.x + b.x, a.y + b.y);
+}
+
+/** Create point by adding specified offset.
+ */
+inline Point2D operator+(Point2D const &a, Diff2D const &b)
+{
+    return Point2D(a.x + b.x, a.y + b.y);
+}
+
+/** Add size and point
+ */
+inline Point2D operator+(Size2D const & s, Point2D const & p)
+{
+    return Point2D(s.x + p.x, s.y + p.y);
+}
+
+inline Point2D operator*(Point2D l, double r)
+{
+    l *= r;
+    return l;
+}
+
+inline Point2D operator*(double l, Point2D r)
+{
+    r *= l;
+    return r;
+}
+
+inline Size2D operator*(Size2D l, double r)
+{
+    l *= r;
+    return l;
+}
+
+inline Size2D operator*(double l, Size2D r)
+{
+    r *= l;
+    return r;
+}
+
+inline Point2D operator/(Point2D l, double r)
+{
+    l /= r;
+    return l;
+}
+
+inline Size2D operator/(Size2D l, double r)
+{
+    l /= r;
+    return l;
+}
+
+inline Point2D operator*(Point2D l, int r)
+{
+    l *= r;
+    return l;
+}
+
+inline Point2D operator*(int l, Point2D r)
+{
+    r *= l;
+    return r;
+}
+
+inline Size2D operator*(Size2D l, int r)
+{
+    l *= r;
+    return l;
+}
+
+inline Size2D operator*(int l, Size2D r)
+{
+    r *= l;
+    return r;
+}
+
+inline Point2D operator/(Point2D l, int r)
+{
+    l /= r;
+    return l;
+}
+
+inline Size2D operator/(Size2D l, int r)
+{
+    l /= r;
+    return l;
+}
+
+
+/********************************************************/
+/*                                                      */
+/*                      Rect2D                          */
+/*                                                      */
+/********************************************************/
+
+/** \brief Two dimensional rectangle.
+
+    This class stores a 2-dimensional rectangular range or region. Thus,
+    it follows the VIGRA convention that the upper left corner is inside
+    the rectangle, while the lower right is 1 pixel to the right and below the
+    last pixel in the rectangle.
+
+    A major advantage of this class is that it can be constructed from either
+    a pair of \ref Point2D, or from a \ref Point2D and an extend
+    (\ref Size2D). Rect2D overloads operators |=, &=, |, & to realize set
+    union (in the sense of a minimal bounding rectangle) and set intersection.
+
+    \code
+    Rect2D r1(Point2D(0,0), Point2D(10, 20)),
+           r2(Point2D(10, 15), Size2D(20, 20));
+    Point2D p(0,100);
+
+    Rect2D r3 =  r1 | r2; // upper left is (0,0), lower right is (30, 35)
+    assert(r3.contains(r2));
+    assert(!r3.contains(p));
+
+    r3 |= p;       // lower right now (30,101) so that p is inside r3
+    assert(r3.contains(p));
+    \endcode
+
+    <b>\#include</b> \<vigra/diff2d.hxx\><br>
+    Namespace: vigra
+*/
+class Rect2D
+{
+    Point2D upperLeft_, lowerRight_;
+
+public:
+        /** Construct a null rectangle (isEmpty() will return true)
+         */
+    Rect2D()
+    {}
+
+        /** Construct a rectangle representing the given range
+         * (lowerRight is considered to be outside the rectangle as
+         * usual in the VIGRA)
+         */
+    Rect2D(Point2D const &upperLeft, Point2D const &lowerRight)
+    : upperLeft_(upperLeft), lowerRight_(lowerRight)
+    {}
+
+        /** Construct a rectangle representing the given range
+         */
+    Rect2D(int left, int top, int right, int bottom)
+    : upperLeft_(left, top), lowerRight_(right, bottom)
+    {}
+
+        /** Construct a rectangle of given position and size
+         */
+    Rect2D(Point2D const &upperLeft, Size2D const &size)
+    : upperLeft_(upperLeft), lowerRight_(upperLeft + size)
+    {}
+
+        /** Construct a rectangle of given size at position (0,0)
+         */
+    explicit Rect2D(Size2D const &size)
+    : lowerRight_(Point2D(size))
+    {}
+
+        /** Return the first point (scan-order wise) which is
+         * considered to be "in" the rectangle.
+         */
+    Point2D const & upperLeft() const
+    {
+        return upperLeft_;
+    }
+
+        /** Return the first point to the right and below the
+         * rectangle.
+         */
+    Point2D const & lowerRight() const
+    {
+        return lowerRight_;
+    }
+
+        /** Change upperLeft() without changing lowerRight(), which
+         * will change the size most probably.
+         */
+    void setUpperLeft(Point2D const &ul)
+    {
+        upperLeft_ = ul;
+    }
+
+        /** Change lowerRight() without changing upperLeft(), which
+         * will change the size most probably.
+         */
+    void setLowerRight(Point2D const &lr)
+    {
+        lowerRight_ = lr;
+    }
+
+        /** Move the whole rectangle so that the given point will be
+         * upperLeft() afterwards.
+         */
+    void moveTo(Point2D const &newUpperLeft)
+    {
+        lowerRight_ += newUpperLeft - upperLeft_;
+        upperLeft_ = newUpperLeft;
+    }
+
+        /** Move the whole rectangle so that upperLeft() will become
+         * Point2D(left, top) afterwards.
+         */
+    void moveTo(int left, int top)
+    {
+        moveTo(Point2D(left, top));
+    }
+
+        /** Move the whole rectangle by the given 2D offset.
+         */
+    void moveBy(Diff2D const &offset)
+    {
+        upperLeft_ += offset;
+        lowerRight_ += offset;
+    }
+
+        /** Move the whole rectangle by the given x- and y-offsets.
+         */
+    void moveBy(int xOffset, int yOffset)
+    {
+        moveBy(Diff2D(xOffset, yOffset));
+    }
+
+        /** Return the left coordinate of this rectangle.
+         */
+    int left() const
+    {
+        return upperLeft_.x;
+    }
+
+        /** Return the top coordinate of this rectangle.
+         */
+    int top() const
+    {
+        return upperLeft_.y;
+    }
+
+        /** Return the right coordinate of this rectangle. That is the
+         * first column to the right of the rectangle.
+         */
+    int right() const
+    {
+        return lowerRight_.x;
+    }
+
+        /** Return the bottom coordinate of this rectangle. That is the
+         * first row below the rectangle.
+         */
+    int bottom() const
+    {
+        return lowerRight_.y;
+    }
+
+        /** Determine and return the width of this rectangle. It might be
+         * zero or even negative, and if so, isEmpty() will return true.
+         */
+    int width() const
+    {
+        return lowerRight_.x - upperLeft_.x;
+    }
+
+        /** Determine and return the height of this rectangle. It might be
+         * zero or even negative, and if so, isEmpty() will return true.
+         */
+    int height() const
+    {
+        return lowerRight_.y - upperLeft_.y;
+    }
+
+        /** Determine and return the area of this rectangle. That is, if
+         * this rect isEmpty(), returns zero, otherwise returns
+         * width()*height().
+         */
+    int area() const
+    {
+        return isEmpty() ? 0 : width()*height();
+    }
+
+        /** Determine and return the size of this rectangle. The width
+         * and/or height might be zero or even negative, and if so,
+         * isEmpty() will return true.
+         */
+    Size2D size() const
+    {
+        return lowerRight_ - upperLeft_;
+    }
+
+        /** Resize this rectangle to the given extents. This will move
+         * the lower right corner only.
+         */
+    void setSize(Size2D const &size)
+    {
+        lowerRight_ = upperLeft_ + size;
+    }
+
+        /** Resize this rectangle to the given extents. This will move
+         * the lower right corner only.
+         */
+    void setSize(int width, int height)
+    {
+        lowerRight_ = upperLeft_ + Size2D(width, height);
+    }
+
+        /** Increase the size of the rectangle by the given offset. This
+         * will move the lower right corner only. (If any of offset's
+         * components is negative, the rectangle will get smaller
+         * accordingly.)
+         */
+    void addSize(Size2D const &offset)
+    {
+        lowerRight_ += offset;
+    }
+
+        /** Adds a border of the given width around the rectangle. That
+         * means, upperLeft()'s components are moved by -borderWidth
+         * and lowerRight()'s by borderWidth. (If borderWidth is
+         * negative, the rectangle will get smaller accordingly.)
+         */
+    void addBorder(int borderWidth)
+    {
+        upperLeft_ += Diff2D(-borderWidth, -borderWidth);
+        lowerRight_ += Diff2D(borderWidth, borderWidth);
+    }
+
+        /** Adds a border with possibly different widths in x- and
+         * y-directions around the rectangle. That means, each x
+         * component is moved borderWidth pixels and each y component
+         * is moved borderHeight pixels to the outside. (If
+         * borderWidth is negative, the rectangle will get smaller
+         * accordingly.)
+         */
+    void addBorder(int borderWidth, int borderHeight)
+    {
+        upperLeft_ += Diff2D(-borderWidth, -borderHeight);
+        lowerRight_ += Diff2D(borderWidth, borderHeight);
+    }
+
+        /// equality check
+    bool operator==(Rect2D const &r) const
+    {
+        return (upperLeft_ == r.upperLeft_) && (lowerRight_ == r.lowerRight_);
+    }
+
+        /// inequality check
+    bool operator!=(Rect2D const &r) const
+    {
+        return (upperLeft_ != r.upperLeft_) || (lowerRight_ != r.lowerRight_);
+    }
+
+        /** Return whether this rectangle is considered empty. It is
+         * non-empty if both coordinates of the lower right corner are
+         * greater than the corresponding coordinate of the upper left
+         * corner. Uniting an empty rectangle with something will return
+         * the bounding rectangle of the 'something', intersecting with an
+         * empty rectangle will yield again an empty rectangle.
+         */
+    bool isEmpty() const
+    {
+        return ((lowerRight_.x <= upperLeft_.x) ||
+                (lowerRight_.y <= upperLeft_.y));
+    }
+
+        /** Return whether this rectangle contains the given point. That
+         * is, if the point lies within the valid range of an
+         * ImageIterator walking from upperLeft() to lowerRight()
+         * (excluding the latter).
+         */
+    bool contains(Point2D const &p) const
+    {
+        return ((upperLeft_.x <= p.x) &&
+                (upperLeft_.y <= p.y) &&
+                (p.x < lowerRight_.x) &&
+                (p.y < lowerRight_.y));
+    }
+
+        /** Return whether this rectangle contains the given
+         * one. <tt>r1.contains(r2)</tt> returns the same as
+         * <tt>r1 == (r1|r2)</tt> (but is of course more
+         * efficient). That also means, a rectangle (even an empty one!)
+         * contains() any empty rectangle.
+         */
+    bool contains(Rect2D const &r) const
+    {
+        return r.isEmpty() ||
+            (contains(r.upperLeft()) && contains(r.lowerRight()-Diff2D(1,1)));
+    }
+
+        /** Return whether this rectangle overlaps with the given
+         * one. <tt>r1.intersects(r2)</tt> returns the same as
+         * <tt>!(r1&r2).isEmpty()</tt> (but is of course much more
+         * efficient).
+         */
+    bool intersects(Rect2D const &r) const
+    {
+        return ((r.upperLeft_.x < lowerRight_.x) &&
+                (upperLeft_.x < r.lowerRight_.x) &&
+                (r.upperLeft_.y < lowerRight_.y) &&
+                (upperLeft_.y < r.lowerRight_.y))
+            && !r.isEmpty();
+    }
+
+        /** Modifies this rectangle by including the given point. The
+         * result is the bounding rectangle of the rectangle and the
+         * point. If isEmpty returns true, the union will be a
+         * rectangle containing only the given point.
+         */
+    Rect2D &operator|=(Point2D const &p)
+    {
+        if(isEmpty())
+        {
+            upperLeft_ = p;
+            lowerRight_ = p + Diff2D(1, 1);
+        }
+        else
+        {
+            if(p.x < upperLeft_.x)
+                upperLeft_.x = p.x;
+            if(p.y < upperLeft_.y)
+                upperLeft_.y = p.y;
+            if(lowerRight_.x <= p.x)
+                lowerRight_.x = p.x + 1;
+            if(lowerRight_.y <= p.y)
+                lowerRight_.y = p.y + 1;
+        }
+        return *this;
+    }
+
+        /** Returns the union of this rectangle and the given
+         * point. The result is the bounding rectangle of the
+         * rectangle and the point. If isEmpty returns true, the union
+         * will be a rectangle containing only the given point.
+         */
+    Rect2D operator|(Point2D const &p) const
+    {
+        Rect2D result(*this);
+        result |= p;
+        return result;
+    }
+
+        /** Modifies this rectangle by uniting it with the given
+         * one. The result is the bounding rectangle of both
+         * rectangles. If one of the rectangles isEmpty(), the union
+         * will be the other one.
+         */
+    Rect2D &operator|=(Rect2D const &r)
+    {
+        if(r.isEmpty())
+            return *this;
+        if(isEmpty())
+            return operator=(r);
+
+        if(r.upperLeft_.x < upperLeft_.x)
+            upperLeft_.x = r.upperLeft_.x;
+        if(r.upperLeft_.y < upperLeft_.y)
+            upperLeft_.y = r.upperLeft_.y;
+        if(lowerRight_.x < r.lowerRight_.x)
+            lowerRight_.x = r.lowerRight_.x;
+        if(lowerRight_.y < r.lowerRight_.y)
+            lowerRight_.y = r.lowerRight_.y;
+        return *this;
+    }
+
+        /** Returns the union of this rectangle and the given one. The
+         * result is the bounding rectangle of both rectangles. If one
+         * of the rectangles isEmpty(), the union will be the other
+         * one.
+         */
+    Rect2D operator|(Rect2D const &r) const
+    {
+        Rect2D result(*this);
+        result |= r;
+        return result;
+    }
+
+        /** Modifies this rectangle by intersecting it with the given
+         * point. The result is the bounding rect of the point (with
+         * width and height equal to 1) if it was contained in the
+         * original rect, or an empty rect otherwise.
+         */
+    Rect2D &operator&=(Point2D const &p)
+    {
+        if(contains(p))
+        {
+            upperLeft_ = p;
+            lowerRight_ = p + Diff2D(1, 1);
+        }
+        else
+            lowerRight_ = upperLeft_;
+        return *this;
+    }
+
+        /** Intersects this rectangle with the given point. The result
+         * is the bounding rect of the point (with width and height
+         * equal to 1) if it was contained in the original rect, or an
+         * empty rect otherwise.
+         */
+    Rect2D operator&(Point2D const &p) const
+    {
+        Rect2D result(*this);
+        result &= p;
+        return result;
+    }
+
+        /** Modifies this rectangle by intersecting it with the given
+         * one. The result is the maximal rectangle contained in both
+         * original ones. Intersecting with an empty rectangle will
+         * yield again an empty rectangle.
+         */
+    Rect2D &operator&=(Rect2D const &r)
+    {
+        if(isEmpty())
+            return *this;
+        if(r.isEmpty())
+            return operator=(r);
+
+        if(upperLeft_.x < r.upperLeft_.x)
+            upperLeft_.x = r.upperLeft_.x;
+        if(upperLeft_.y < r.upperLeft_.y)
+            upperLeft_.y = r.upperLeft_.y;
+        if(r.lowerRight_.x < lowerRight_.x)
+            lowerRight_.x = r.lowerRight_.x;
+        if(r.lowerRight_.y < lowerRight_.y)
+            lowerRight_.y = r.lowerRight_.y;
+        return *this;
+    }
+
+       /** Scale this rectangle by the given factor.
+        * To be specific, both upperLeft() and lowerRight() are
+        * multiplied by `factor`.
+        */
+    Rect2D & operator*=(int factor)
+    {
+        upperLeft_ *= factor;
+        lowerRight_ *= factor;
+        return *this;
+    }
+
+       /** Scale this rectangle by the given factor.
+        * To be specific, both upperLeft() and lowerRight() are
+        * multiplied by `factor`.
+        */
+    Rect2D & operator*=(double factor)
+    {
+        upperLeft_ *= factor;
+        lowerRight_ *= factor;
+        return *this;
+    }
+
+       /** Return rectangle scaled by the given factor.
+        * To be specific, both upperLeft() and lowerRight() are
+        * multiplied by `factor`.
+        */
+    Rect2D operator*(int factor) const
+    {
+        return Rect2D(*this)*=factor;
+    }
+
+       /** Return rectangle scaled by the given factor.
+        * To be specific, both upperLeft() and lowerRight() are
+        * multiplied by `factor`.
+        */
+    Rect2D operator*(double factor) const
+    {
+        return Rect2D(*this)*=factor;
+    }
+
+        /** Intersects this rectangle with the given one. The result
+         * is the maximal rectangle contained in both original ones.
+         * Intersecting with an empty rectangle will yield again an
+         * empty rectangle.
+         */
+    Rect2D operator&(Rect2D const &r) const
+    {
+        Rect2D result(*this);
+        result &= r;
+        return result;
+    }
+};
+
+
+/********************************************************/
+/*                                                      */
+/*                      Dist2D                          */
+/*                                                      */
+/********************************************************/
+
+/** @deprecated use \ref vigra::Diff2D instead
+*/
+class Dist2D
+{
+  public:
+    Dist2D(int the_width, int the_height)
+    : width(the_width),
+      height(the_height)
+    {}
+
+    Dist2D(Dist2D const & s)
+    : width(s.width),
+      height(s.height)
+    {}
+
+    Dist2D & operator=(Dist2D const & s)
+    {
+        if(this != &s)
+        {
+            width = s.width;
+            height = s.height;
+        }
+        return *this;
+    }
+
+    Dist2D & operator+=(Dist2D const & s)
+    {
+        width += s.width;
+        height += s.height;
+
+        return *this;
+    }
+
+    Dist2D  operator+(Dist2D const & s) const
+    {
+        Dist2D ret(*this);
+        ret += s;
+
+        return ret;
+    }
+
+    operator Diff2D()
+        { return Diff2D(width, height); }
+
+    int width;
+    int height;
+ };
+
+//@}
+
+} // namespace vigra
+
+namespace std {
+
+/**
+ * Output a \ref vigra::Diff2D as a tuple.
+ * Example Diff2D(-12, 13) -> "(-12, 13)"
+ */
+inline
+ostream & operator<<(ostream & o, vigra::Diff2D const & d)
+{
+    o << '(' << d.x << ", " << d.y << ')';
+    return o;
+}
+
+/**
+ * Output a \ref vigra::Size2D.
+ * Example Size2D(100, 200) -> "(100x200)"
+ */
+inline
+ostream &operator <<(ostream &s, vigra::Size2D const &d)
+{
+    s << '(' << d.x << 'x' << d.y << ')';
+    return s;
+}
+
+/**
+ * Output a description of a \ref vigra::Rect2D.
+ * Example Rect2D(10, 10, 30, 20) -> "[(10, 10) to (30, 20) = (20x10)]"
+ */
+inline
+ostream &operator <<(ostream &s, vigra::Rect2D const &r)
+{
+    s << "[" << r.upperLeft() << " to " << r.lowerRight()
+      << " = " << r.size() << "]";
+    return s;
+}
+
+} // namespace std
+
+#endif // VIGRA_DIFF2D_HXX
diff --git a/include/vigra/distancetransform.hxx b/include/vigra/distancetransform.hxx
new file mode 100644
index 0000000..51e298b
--- /dev/null
+++ b/include/vigra/distancetransform.hxx
@@ -0,0 +1,464 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_DISTANCETRANSFORM_HXX
+#define VIGRA_DISTANCETRANSFORM_HXX
+
+#include <cmath>
+#include "stdimage.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/*
+ * functors to determine the distance norm 
+ * these functors assume that dx and dy are positive
+ * (this is OK for use in internalDistanceTransform())
+ */
+ 
+// chessboard metric
+struct InternalDistanceTransformLInifinityNormFunctor
+{
+    float operator()(float dx, float dy) const
+    {
+        return (dx < dy) ? dy : dx;
+    }
+};
+
+// Manhattan metric
+struct InternalDistanceTransformL1NormFunctor
+{
+    float operator()(float dx, float dy) const
+    {
+        return dx + dy;
+    }
+};
+
+// Euclidean metric
+struct InternalDistanceTransformL2NormFunctor
+{
+    float operator()(float dx, float dy) const
+    {
+        return VIGRA_CSTD::sqrt(dx*dx + dy*dy);
+    }
+};
+
+
+template <class SrcImageIterator, class SrcAccessor,
+                   class DestImageIterator, class DestAccessor,
+                   class ValueType, class NormFunctor>
+void
+internalDistanceTransform(SrcImageIterator src_upperleft, 
+                SrcImageIterator src_lowerright, SrcAccessor sa,
+                DestImageIterator dest_upperleft, DestAccessor da,
+                ValueType background, NormFunctor norm)
+{
+    int w = src_lowerright.x - src_upperleft.x;  
+    int h = src_lowerright.y - src_upperleft.y;  
+    
+    FImage xdist(w,h), ydist(w,h);
+    
+    xdist = (FImage::value_type)w;    // init x and
+    ydist = (FImage::value_type)h;    // y distances with 'large' values
+
+    SrcImageIterator sy = src_upperleft;
+    DestImageIterator ry = dest_upperleft;
+    FImage::Iterator xdy = xdist.upperLeft();
+    FImage::Iterator ydy = ydist.upperLeft();
+    SrcImageIterator sx = sy;
+    DestImageIterator rx = ry;
+    FImage::Iterator xdx = xdy;
+    FImage::Iterator ydx = ydy;
+    
+    const Diff2D left(-1, 0);
+    const Diff2D right(1, 0);
+    const Diff2D top(0, -1);
+    const Diff2D bottom(0, 1);
+        
+    int x,y;
+    if(sa(sx) != background)    // first pixel
+    {
+        *xdx = 0.0;
+        *ydx = 0.0;
+        da.set(0.0, rx);
+    }
+    else
+    {
+        da.set(norm(*xdx, *ydx), rx);
+    }
+    
+    
+    for(x=1, ++xdx.x, ++ydx.x, ++sx.x, ++rx.x; 
+        x<w; 
+        ++x, ++xdx.x, ++ydx.x, ++sx.x, ++rx.x)   // first row left to right
+    {
+        if(sa(sx) != background)
+        {
+            *xdx = 0.0;
+            *ydx = 0.0;
+            da.set(0.0, rx);
+        }
+        else
+        {
+            *xdx  = xdx[left] + 1.0f;   // propagate x and
+            *ydx  = ydx[left];         // y components of distance from left pixel
+            da.set(norm(*xdx, *ydx), rx); // calculate distance from x and y components
+        }
+    }
+    for(x=w-2, xdx.x -= 2, ydx.x -= 2, sx.x -= 2, rx.x -= 2; 
+        x>=0; 
+        --x, --xdx.x, --ydx.x, --sx.x, --rx.x)   // first row right to left
+    {
+        float d = norm(xdx[right] + 1.0f, ydx[right]);
+        
+        if(da(rx) < d) continue;
+        
+        *xdx = xdx[right] + 1.0f;
+        *ydx = ydx[right];
+        da.set(d, rx);
+    }
+    for(y=1, ++xdy.y, ++ydy.y, ++sy.y, ++ry.y; 
+        y<h;
+        ++y, ++xdy.y, ++ydy.y, ++sy.y, ++ry.y)   // top to bottom
+    {
+        sx = sy;
+        rx = ry;
+        xdx = xdy;
+        ydx = ydy;
+        
+        if(sa(sx) != background)    // first pixel of current row
+        {
+            *xdx = 0.0f;
+            *ydx = 0.0f;
+            da.set(0.0, rx);
+        }
+        else
+        {
+            *xdx = xdx[top];
+            *ydx = ydx[top] + 1.0f;
+            da.set(norm(*xdx, *ydx), rx);
+        }
+        
+        for(x=1, ++xdx.x, ++ydx.x, ++sx.x, ++rx.x; 
+            x<w; 
+            ++x, ++xdx.x, ++ydx.x, ++sx.x, ++rx.x)  // current row left to right
+        {
+            if(sa(sx) != background)
+            {
+                *xdx = 0.0f;
+                *ydx = 0.0f;
+                da.set(0.0, rx);
+            }
+            else
+            {
+                float d1 = norm(xdx[left] + 1.0f, ydx[left]);
+                float d2 = norm(xdx[top], ydx[top] + 1.0f);
+                
+                if(d1 < d2)
+                {
+                    *xdx = xdx[left] + 1.0f;
+                    *ydx = ydx[left];
+                    da.set(d1, rx);
+                }
+                else
+                {
+                    *xdx = xdx[top];
+                    *ydx = ydx[top] + 1.0f;
+                    da.set(d2, rx);
+                }
+            }
+        }
+        for(x=w-2, xdx.x -= 2, ydx.x -= 2, sx.x -= 2, rx.x -= 2; 
+            x>=0; 
+            --x, --xdx.x, --ydx.x, --sx.x, --rx.x)  // current row right to left
+        {
+            float d1 = norm(xdx[right] + 1.0f, ydx[right]);
+            
+            if(da(rx) < d1) continue;
+            
+            *xdx = xdx[right] + 1.0f;
+            *ydx = ydx[right];
+            da.set(d1, rx);
+        }
+    }
+    for(y=h-2, xdy.y -= 2, ydy.y -= 2, sy.y -= 2, ry.y -= 2; 
+        y>=0;
+        --y, --xdy.y, --ydy.y, --sy.y, --ry.y)    // bottom to top
+    {
+        sx = sy;
+        rx = ry;
+        xdx = xdy;
+        ydx = ydy;
+        
+        float d = norm(xdx[bottom], ydx[bottom] + 1.0f);
+        if(d < da(rx))    // first pixel of current row
+        { 
+            *xdx = xdx[bottom];
+            *ydx = ydx[bottom] + 1.0f;
+            da.set(d, rx);
+        }
+            
+        for(x=1, ++xdx.x, ++ydx.x, ++sx.x, ++rx.x; 
+            x<w;
+            ++x, ++xdx.x, ++ydx.x, ++sx.x, ++rx.x)  // current row left to right
+        {
+            float d1 = norm(xdx[left] + 1.0f, ydx[left]);
+            float d2 = norm(xdx[bottom], ydx[bottom] + 1.0f);
+            
+            if(d1 < d2)
+            {
+                if(da(rx) < d1) continue;
+                *xdx = xdx[left] + 1.0f;
+                *ydx = ydx[left];
+                da.set(d1, rx);
+            }
+            else
+            {
+                if(da(rx) < d2) continue;
+                *xdx = xdx[bottom];
+                *ydx = ydx[bottom] + 1.0f;
+                da.set(d2, rx);
+            }
+        }
+        for(x=w-2, xdx.x -= 2, ydx.x -= 2, sx.x -= 2, rx.x -= 2; 
+            x>=0; 
+            --x, --xdx.x, --ydx.x, --sx.x, --rx.x)  // current row right to left
+        {
+            float d1 = norm(xdx[right] + 1.0f, ydx[right]);
+
+            if(da(rx) < d1) continue;
+            *xdx = xdx[right] + 1.0f;
+            *ydx = ydx[right];
+            da.set(d1, rx);
+        }
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*                 distanceTransform                    */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup DistanceTransform Distance Transform
+    Perform a distance transform using either the Euclidean, Manhattan, 
+    or chessboard metrics.
+    
+    See also: \ref MultiArrayDistanceTransform "multi-dimensional distance transforms"
+*/
+//@{
+
+/** For all background pixels, calculate the distance to 
+    the nearest object or contour. The label of the pixels to be considered 
+    background in the source image is passed in the parameter 'background'.
+    Source pixels with other labels will be considered objects. In the 
+    destination image, all pixels corresponding to background will be assigned 
+    the their distance value, all pixels corresponding to objects will be
+    assigned 0.
+    
+    The parameter 'norm' gives the distance norm to be used:
+    
+    <ul>
+
+    <li> norm == 0: use chessboard distance (L-infinity norm)
+    <li> norm == 1: use Manhattan distance (L1 norm)
+    <li> norm == 2: use Euclidean distance (L2 norm)
+    
+    </ul>
+    
+    If you use the L2 norm, the destination pixels must be real valued to give
+    correct results.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class ValueType>
+        void
+        distanceTransform(MultiArrayView<2, T1, S1> const & src,
+                          MultiArrayView<2, T2, S2> dest,
+                          ValueType background, int norm);
+    }
+    \endcode
+    
+    \deprecatedAPI{distanceTransform}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor,
+                  class ValueType>
+        void distanceTransform(SrcImageIterator src_upperleft, 
+                               SrcImageIterator src_lowerright, SrcAccessor sa,
+                               DestImageIterator dest_upperleft, DestAccessor da,
+                               ValueType background, int norm);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor,
+                  class ValueType>
+        void distanceTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                               pair<DestImageIterator, DestAccessor> dest,
+                               ValueType background, int norm);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/distancetransform.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), edges(w,h);
+    MultiArray<2, float>         distance(w, h);
+    ...
+
+    // detect edges in src image (edges will be marked 1, background 0)
+    differenceOfExponentialEdgeImage(src, edges, 0.8, 4.0);
+     
+    // find distance of all pixels from nearest edge
+    distanceTransform(edges, distance, 0,                   2);
+    //                                 ^ background label   ^ norm (Euclidean)
+    \endcode
+
+    \deprecatedUsage{distanceTransform}
+    \code
+    
+    vigra::BImage src(w,h), edges(w,h);
+    vigra::FImage distance(w, h);
+
+    // empty edge image
+    edges = 0;
+    ...
+
+    // detect edges in src image (edges will be marked 1, background 0)
+    vigra::differenceOfExponentialEdgeImage(srcImageRange(src), destImage(edges), 
+                                     0.8, 4.0);
+     
+    // find distance of all pixels from nearest edge
+    vigra::distanceTransform(srcImageRange(edges), destImage(distance),
+                             0,                   2);
+    //                       ^ background label   ^ norm (Euclidean)
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+    
+    SrcAccessor sa;
+    DestAccessor da;
+    
+    ValueType background;
+    float distance;
+    
+    sa(src_upperleft) != background;
+    da(dest_upperleft) < distance;
+    da.set(distance, dest_upperleft);
+ 
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void distanceTransform)
+
+template <class SrcImageIterator, class SrcAccessor,
+                   class DestImageIterator, class DestAccessor,
+                   class ValueType>
+inline void
+distanceTransform(SrcImageIterator src_upperleft, 
+                SrcImageIterator src_lowerright, SrcAccessor sa,
+                DestImageIterator dest_upperleft, DestAccessor da,
+                ValueType background, int norm)
+{
+    if(norm == 1)
+    {
+        internalDistanceTransform(src_upperleft, src_lowerright, sa,
+                                  dest_upperleft, da, background,
+                                  InternalDistanceTransformL1NormFunctor());
+    }
+    else if(norm == 2)
+    {
+        internalDistanceTransform(src_upperleft, src_lowerright, sa,
+                                  dest_upperleft, da, background,
+                                  InternalDistanceTransformL2NormFunctor());
+    }
+    else
+    {
+        internalDistanceTransform(src_upperleft, src_lowerright, sa,
+                                  dest_upperleft, da, background,
+                                  InternalDistanceTransformLInifinityNormFunctor());
+    }
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor,
+          class ValueType>
+inline void
+distanceTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                  pair<DestImageIterator, DestAccessor> dest,
+                  ValueType background, int norm)
+{
+    distanceTransform(src.first, src.second, src.third,
+                      dest.first, dest.second, background, norm);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class ValueType>
+inline void
+distanceTransform(MultiArrayView<2, T1, S1> const & src,
+                  MultiArrayView<2, T2, S2> dest,
+                  ValueType background, int norm)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "distanceTransform(): shape mismatch between input and output.");
+    distanceTransform(srcImageRange(src),
+                      destImage(dest), background, norm);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_DISTANCETRANSFORM_HXX
+
diff --git a/include/vigra/edgedetection.hxx b/include/vigra/edgedetection.hxx
new file mode 100644
index 0000000..0a84185
--- /dev/null
+++ b/include/vigra/edgedetection.hxx
@@ -0,0 +1,2994 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_EDGEDETECTION_HXX
+#define VIGRA_EDGEDETECTION_HXX
+
+#include <vector>
+#include <queue>
+#include <cmath>     // sqrt(), abs()
+#include "utilities.hxx"
+#include "numerictraits.hxx"
+#include "stdimage.hxx"
+#include "stdimagefunctions.hxx"
+#include "recursiveconvolution.hxx"
+#include "separableconvolution.hxx"
+#include "convolution.hxx"
+#include "labelimage.hxx"
+#include "mathutil.hxx"
+#include "pixelneighborhood.hxx"
+#include "linear_solve.hxx"
+#include "functorexpression.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup EdgeDetection Edge Detection
+    Edge detectors based on first and second derivatives,
+          and related post-processing.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*           differenceOfExponentialEdgeImage           */
+/*                                                      */
+/********************************************************/
+
+/** \brief Detect and mark edges in an edge image using the Shen/Castan zero-crossing detector.
+
+    This operator applies an exponential filter to the source image
+    at the given <TT>scale</TT> and subtracts the result from the original image.
+    Zero crossings are detected in the resulting difference image. Whenever the
+    gradient at a zero crossing is greater than the given <TT>gradient_threshold</TT>,
+    an edge point is marked (using <TT>edge_marker</TT>) in the destination image on
+    the darker side of the zero crossing (note that zero crossings occur
+    <i>between</i> pixels). For example:
+
+    \code
+    sign of difference image     resulting edge points (*)
+
+        + - -                          * * .
+        + + -               =>         . * *
+        + + +                          . . .
+    \endcode
+
+    Non-edge pixels (<TT>.</TT>) remain untouched in the destination image.
+    The result can be improved by the post-processing operation \ref removeShortEdges().
+    A more accurate edge placement can be achieved with the function
+    \ref differenceOfExponentialCrackEdgeImage().
+
+    The source value type
+    (<TT>SrcAccessor::value_type</TT>) must be a linear algebra, i.e. addition,
+    subtraction and multiplication of the type with itself, and multiplication
+    with double and
+    \ref NumericTraits "NumericTraits" must
+    be defined. In addition, this type must be less-comparable.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class GradValue, class DestValue>
+        void 
+        differenceOfExponentialEdgeImage(MultiArrayView<2, T1, S1> const & src,
+                                         MultiArrayView<2, T2, S2> dest,
+                                         double scale,
+                                         GradValue gradient_threshold,
+                                         DestValue edge_marker = NumericTraits<DestValue>::one());
+    }
+    \endcode
+
+    \deprecatedAPI{differenceOfExponentialEdgeImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+              class DestIterator, class DestAccessor,
+              class GradValue,
+              class DestValue = DestAccessor::value_type>
+        void differenceOfExponentialEdgeImage(
+               SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+               DestIterator dul, DestAccessor da,
+               double scale, GradValue gradient_threshold,
+               DestValue edge_marker = NumericTraits<DestValue>::one())
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+              class DestIterator, class DestAccessor,
+              class GradValue,
+              class DestValue = DestAccessor::value_type>
+        void differenceOfExponentialEdgeImage(
+               triple<SrcIterator, SrcIterator, SrcAccessor> src,
+               pair<DestIterator, DestAccessor> dest,
+               double scale, GradValue gradient_threshold,
+               DestValue edge_marker = NumericTraits<DestValue>::one())
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), edges(w,h);
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    differenceOfExponentialEdgeImage(src, edges,
+                                     0.8, 4.0, 1);
+    \endcode
+
+    \deprecatedUsage{differenceOfExponentialEdgeImage}
+    \code
+    vigra::BImage src(w,h), edges(w,h);
+
+    // empty edge image
+    edges = 0;
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    vigra::differenceOfExponentialEdgeImage(srcImageRange(src), destImage(edges),
+                                     0.8, 4.0, 1);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+    double d;
+    GradValue gradient_threshold;
+
+    u = u + u
+    u = u - u
+    u = u * u
+    u = d * u
+    u < gradient_threshold
+
+    DestValue edge_marker;
+    dest_accessor.set(edge_marker, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    \code
+    scale > 0
+    gradient_threshold > 0
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void differenceOfExponentialEdgeImage)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue, class DestValue>
+void differenceOfExponentialEdgeImage(
+               SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+           DestIterator dul, DestAccessor da,
+           double scale, GradValue gradient_threshold, DestValue edge_marker)
+{
+    vigra_precondition(scale > 0,
+                 "differenceOfExponentialEdgeImage(): scale > 0 required.");
+
+    vigra_precondition(gradient_threshold > 0,
+                 "differenceOfExponentialEdgeImage(): "
+         "gradient_threshold > 0 required.");
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    int x,y;
+
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+    TMPTYPE;
+    typedef BasicImage<TMPTYPE> TMPIMG;
+
+    TMPIMG tmp(w,h);
+    TMPIMG smooth(w,h);
+
+    recursiveSmoothX(srcIterRange(sul, slr, sa), destImage(tmp), scale / 2.0);
+    recursiveSmoothY(srcImageRange(tmp), destImage(tmp), scale / 2.0);
+
+    recursiveSmoothX(srcImageRange(tmp), destImage(smooth), scale);
+    recursiveSmoothY(srcImageRange(smooth), destImage(smooth), scale);
+
+    typename TMPIMG::Iterator iy = smooth.upperLeft();
+    typename TMPIMG::Iterator ty = tmp.upperLeft();
+    DestIterator              dy = dul;
+
+    const Diff2D right(1, 0);
+    const Diff2D bottom(0, 1);
+
+
+    TMPTYPE thresh = detail::RequiresExplicitCast<TMPTYPE>::cast((gradient_threshold * gradient_threshold) *
+                     NumericTraits<TMPTYPE>::one());
+    TMPTYPE zero = NumericTraits<TMPTYPE>::zero();
+
+    for(y=0; y<h-1; ++y, ++iy.y, ++ty.y, ++dy.y)
+    {
+        typename TMPIMG::Iterator ix = iy;
+        typename TMPIMG::Iterator tx = ty;
+        DestIterator              dx = dy;
+
+        for(x=0; x<w-1; ++x, ++ix.x, ++tx.x, ++dx.x)
+        {
+            TMPTYPE diff = *tx - *ix;
+            TMPTYPE gx = tx[right] - *tx;
+            TMPTYPE gy = tx[bottom] - *tx;
+
+            if((gx * gx > thresh) &&
+                (diff * (tx[right] - ix[right]) < zero))
+            {
+                if(gx < zero)
+                {
+                    da.set(edge_marker, dx, right);
+                }
+                else
+                {
+                    da.set(edge_marker, dx);
+                }
+            }
+            if(((gy * gy > thresh) &&
+                (diff * (tx[bottom] - ix[bottom]) < zero)))
+            {
+                if(gy < zero)
+                {
+                    da.set(edge_marker, dx, bottom);
+                }
+                else
+                {
+                    da.set(edge_marker, dx);
+                }
+            }
+        }
+    }
+
+    typename TMPIMG::Iterator ix = iy;
+    typename TMPIMG::Iterator tx = ty;
+    DestIterator              dx = dy;
+
+    for(x=0; x<w-1; ++x, ++ix.x, ++tx.x, ++dx.x)
+    {
+        TMPTYPE diff = *tx - *ix;
+        TMPTYPE gx = tx[right] - *tx;
+
+        if((gx * gx > thresh) &&
+           (diff * (tx[right] - ix[right]) < zero))
+        {
+            if(gx < zero)
+            {
+                da.set(edge_marker, dx, right);
+            }
+            else
+            {
+                da.set(edge_marker, dx);
+            }
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue>
+inline
+void differenceOfExponentialEdgeImage(
+               SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+           DestIterator dul, DestAccessor da,
+           double scale, GradValue gradient_threshold)
+{
+    differenceOfExponentialEdgeImage(sul, slr, sa, dul, da,
+                                        scale, gradient_threshold, 1);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue, class DestValue>
+inline void 
+differenceOfExponentialEdgeImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                 pair<DestIterator, DestAccessor> dest,
+                                 double scale, GradValue gradient_threshold,
+                                 DestValue edge_marker)
+{
+    differenceOfExponentialEdgeImage(src.first, src.second, src.third,
+                                     dest.first, dest.second,
+                                     scale, gradient_threshold, edge_marker);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue>
+inline void
+differenceOfExponentialEdgeImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                 pair<DestIterator, DestAccessor> dest,
+                                 double scale, GradValue gradient_threshold)
+{
+    differenceOfExponentialEdgeImage(src.first, src.second, src.third,
+                                     dest.first, dest.second,
+                                     scale, gradient_threshold, 1);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class GradValue, class DestValue>
+inline void 
+differenceOfExponentialEdgeImage(MultiArrayView<2, T1, S1> const & src,
+                                 MultiArrayView<2, T2, S2> dest,
+                                 double scale,
+                                 GradValue gradient_threshold,
+                                 DestValue edge_marker)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "differenceOfExponentialEdgeImage(): shape mismatch between input and output.");
+    differenceOfExponentialEdgeImage(srcImageRange(src),
+                                     destImage(dest),
+                                     scale, gradient_threshold, edge_marker);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class GradValue>
+inline void
+differenceOfExponentialEdgeImage(MultiArrayView<2, T1, S1> const & src,
+                                 MultiArrayView<2, T2, S2> dest,
+                                 double scale, GradValue gradient_threshold)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "differenceOfExponentialEdgeImage(): shape mismatch between input and output.");
+    differenceOfExponentialEdgeImage(srcImageRange(src),
+                                     destImage(dest),
+                                     scale, gradient_threshold, T2(1));
+}
+
+/********************************************************/
+/*                                                      */
+/*        differenceOfExponentialCrackEdgeImage         */
+/*                                                      */
+/********************************************************/
+
+/** \brief Detect and mark edges in a crack edge image using the Shen/Castan zero-crossing detector.
+
+    This operator applies an exponential filter to the source image
+    at the given <TT>scale</TT> and subtracts the result from the original image.
+    Zero crossings are detected in the resulting difference image. Whenever the
+    gradient at a zero crossing is greater than the given <TT>gradient_threshold</TT>,
+    an edge point is marked (using <TT>edge_marker</TT>) in the destination image
+    <i>between</i> the corresponding original pixels. Topologically, this means we
+    must insert additional pixels between the original ones to represent the
+    boundaries between the pixels (the so called zero- and one-cells, with the original
+    pixels being two-cells). Within VIGRA, such an image is called \ref CrackEdgeImage.
+    To allow insertion of the zero- and one-cells, the destination image must have twice the
+    size of the original (precisely, <TT>(2*w-1)</TT> by <TT>(2*h-1)</TT> pixels). Then the algorithm
+    proceeds as follows:
+
+    \code
+    sign of difference image     insert zero- and one-cells     resulting edge points (*)
+    
+                                         + . - . -                   . * . . .
+          + - -                          . . . . .                   . * * * .
+          + + -               =>         + . + . -           =>      . . . * .
+          + + +                          . . . . .                   . . . * *
+                                         + . + . +                   . . . . .
+    \endcode
+
+    Thus the edge points are marked where they actually are - in between the pixels.
+    An important property of the resulting edge image is that it conforms to the notion
+    of well-composedness as defined by Latecki et al., i.e. connected regions and edges
+    obtained by a subsequent \ref Labeling do not depend on
+    whether 4- or 8-connectivity is used.
+    The non-edge pixels (<TT>.</TT>) in the destination image remain unchanged.
+    The result conforms to the requirements of a \ref CrackEdgeImage. It can be further
+    improved by the post-processing operations \ref removeShortEdges() and
+    \ref closeGapsInCrackEdgeImage().
+
+    The source value type (<TT>SrcAccessor::value_type</TT>) must be a linear algebra, i.e. addition,
+    subtraction and multiplication of the type with itself, and multiplication
+    with double and
+    \ref NumericTraits "NumericTraits" must
+    be defined. In addition, this type must be less-comparable.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class GradValue, class DestValue>
+        void
+        differenceOfExponentialCrackEdgeImage(MultiArrayView<2, T1, S1> const & src,
+                                              MultiArrayView<2, T2, S2> dest,
+                                              double scale,
+                                              GradValue gradient_threshold,
+                                              DestValue edge_marker = NumericTraits<DestValue>::one());
+    }
+    \endcode
+
+    \deprecatedAPI{differenceOfExponentialCrackEdgeImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+              class DestIterator, class DestAccessor,
+              class GradValue,
+              class DestValue = DestAccessor::value_type>
+        void differenceOfExponentialCrackEdgeImage(
+               SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+               DestIterator dul, DestAccessor da,
+               double scale, GradValue gradient_threshold,
+               DestValue edge_marker = NumericTraits<DestValue>::one())
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+              class DestIterator, class DestAccessor,
+              class GradValue,
+              class DestValue = DestAccessor::value_type>
+        void differenceOfExponentialCrackEdgeImage(
+               triple<SrcIterator, SrcIterator, SrcAccessor> src,
+               pair<DestIterator, DestAccessor> dest,
+               double scale, GradValue gradient_threshold,
+               DestValue edge_marker = NumericTraits<DestValue>::one())
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), edges(2*w-1,2*h-1);
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    differenceOfExponentialCrackEdgeImage(src, edges,
+                                          0.8, 4.0, 1);
+    \endcode
+
+    \deprecatedUsage{differenceOfExponentialCrackEdgeImage}
+    \code
+    vigra::BImage src(w,h), edges(2*w-1,2*h-1);
+
+    // empty edge image
+    edges = 0;
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    vigra::differenceOfExponentialCrackEdgeImage(srcImageRange(src), destImage(edges),
+                                     0.8, 4.0, 1);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+    double d;
+    GradValue gradient_threshold;
+
+    u = u + u
+    u = u - u
+    u = u * u
+    u = d * u
+    u < gradient_threshold
+
+    DestValue edge_marker;
+    dest_accessor.set(edge_marker, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    \code
+    scale > 0
+    gradient_threshold > 0
+    \endcode
+
+    The destination image must have twice the size of the source:
+    \code
+    w_dest = 2 * w_src - 1
+    h_dest = 2 * h_src - 1
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void differenceOfExponentialCrackEdgeImage)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue, class DestValue>
+void differenceOfExponentialCrackEdgeImage(
+               SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+           DestIterator dul, DestAccessor da,
+           double scale, GradValue gradient_threshold,
+           DestValue edge_marker)
+{
+    vigra_precondition(scale > 0,
+                 "differenceOfExponentialCrackEdgeImage(): scale > 0 required.");
+
+    vigra_precondition(gradient_threshold > 0,
+                 "differenceOfExponentialCrackEdgeImage(): "
+         "gradient_threshold > 0 required.");
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    int x, y;
+
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+    TMPTYPE;
+    typedef BasicImage<TMPTYPE> TMPIMG;
+
+    TMPIMG tmp(w,h);
+    TMPIMG smooth(w,h);
+
+    TMPTYPE zero = NumericTraits<TMPTYPE>::zero();
+
+    const Diff2D right(1,0);
+    const Diff2D bottom(0,1);
+    const Diff2D left(-1,0);
+    const Diff2D top(0,-1);
+
+    recursiveSmoothX(srcIterRange(sul, slr, sa), destImage(tmp), scale / 2.0);
+    recursiveSmoothY(srcImageRange(tmp), destImage(tmp), scale / 2.0);
+
+    recursiveSmoothX(srcImageRange(tmp), destImage(smooth), scale);
+    recursiveSmoothY(srcImageRange(smooth), destImage(smooth), scale);
+
+    typename TMPIMG::Iterator iy = smooth.upperLeft();
+    typename TMPIMG::Iterator ty = tmp.upperLeft();
+    DestIterator              dy = dul;
+
+    TMPTYPE thresh = detail::RequiresExplicitCast<TMPTYPE>::cast((gradient_threshold * gradient_threshold) *
+                     NumericTraits<TMPTYPE>::one());
+
+    // find zero crossings above threshold
+    for(y=0; y<h-1; ++y, ++iy.y, ++ty.y, dy.y+=2)
+    {
+        typename TMPIMG::Iterator ix = iy;
+        typename TMPIMG::Iterator tx = ty;
+        DestIterator              dx = dy;
+
+        for(int x=0; x<w-1; ++x, ++ix.x, ++tx.x, dx.x+=2)
+        {
+            TMPTYPE diff = *tx - *ix;
+            TMPTYPE gx = tx[right] - *tx;
+            TMPTYPE gy = tx[bottom] - *tx;
+
+            if((gx * gx > thresh) &&
+               (diff * (tx[right] - ix[right]) < zero))
+            {
+                da.set(edge_marker, dx, right);
+            }
+            if((gy * gy > thresh) &&
+               (diff * (tx[bottom] - ix[bottom]) < zero))
+            {
+                da.set(edge_marker, dx, bottom);
+            }
+        }
+
+        TMPTYPE diff = *tx - *ix;
+        TMPTYPE gy = tx[bottom] - *tx;
+
+        if((gy * gy > thresh) &&
+           (diff * (tx[bottom] - ix[bottom]) < zero))
+        {
+            da.set(edge_marker, dx, bottom);
+        }
+    }
+
+    typename TMPIMG::Iterator ix = iy;
+    typename TMPIMG::Iterator tx = ty;
+    DestIterator              dx = dy;
+
+    for(x=0; x<w-1; ++x, ++ix.x, ++tx.x, dx.x+=2)
+    {
+        TMPTYPE diff = *tx - *ix;
+        TMPTYPE gx = tx[right] - *tx;
+
+        if((gx * gx > thresh) &&
+           (diff * (tx[right] - ix[right]) < zero))
+        {
+            da.set(edge_marker, dx, right);
+        }
+    }
+
+    iy = smooth.upperLeft() + Diff2D(0,1);
+    ty = tmp.upperLeft() + Diff2D(0,1);
+    dy = dul + Diff2D(1,2);
+
+    const Diff2D topleft(-1,-1);
+    const Diff2D topright(1,-1);
+    const Diff2D bottomleft(-1,1);
+    const Diff2D bottomright(1,1);
+
+    // find missing 1-cells below threshold (x-direction)
+    for(y=0; y<h-2; ++y, ++iy.y, ++ty.y, dy.y+=2)
+    {
+        typename TMPIMG::Iterator ix = iy;
+        typename TMPIMG::Iterator tx = ty;
+        DestIterator              dx = dy;
+
+        for(int x=0; x<w-2; ++x, ++ix.x, ++tx.x, dx.x+=2)
+        {
+            if(da(dx) == edge_marker) continue;
+
+            TMPTYPE diff = *tx - *ix;
+
+            if((diff * (tx[right] - ix[right]) < zero) &&
+               (((da(dx, bottomright) == edge_marker) &&
+                 (da(dx, topleft) == edge_marker)) ||
+                ((da(dx, bottomleft) == edge_marker) &&
+                 (da(dx, topright) == edge_marker))))
+
+            {
+                da.set(edge_marker, dx);
+            }
+        }
+    }
+
+    iy = smooth.upperLeft() + Diff2D(1,0);
+    ty = tmp.upperLeft() + Diff2D(1,0);
+    dy = dul + Diff2D(2,1);
+
+    // find missing 1-cells below threshold (y-direction)
+    for(y=0; y<h-2; ++y, ++iy.y, ++ty.y, dy.y+=2)
+    {
+        typename TMPIMG::Iterator ix = iy;
+        typename TMPIMG::Iterator tx = ty;
+        DestIterator              dx = dy;
+
+        for(int x=0; x<w-2; ++x, ++ix.x, ++tx.x, dx.x+=2)
+        {
+            if(da(dx) == edge_marker) continue;
+
+            TMPTYPE diff = *tx - *ix;
+
+            if((diff * (tx[bottom] - ix[bottom]) < zero) &&
+               (((da(dx, bottomright) == edge_marker) &&
+                 (da(dx, topleft) == edge_marker)) ||
+                ((da(dx, bottomleft) == edge_marker) &&
+                 (da(dx, topright) == edge_marker))))
+
+            {
+                da.set(edge_marker, dx);
+            }
+        }
+    }
+
+    dy = dul + Diff2D(1,1);
+
+    // find missing 0-cells
+    for(y=0; y<h-1; ++y, dy.y+=2)
+    {
+        DestIterator              dx = dy;
+
+        for(int x=0; x<w-1; ++x, dx.x+=2)
+        {
+            const Diff2D dist[] = {right, top, left, bottom };
+
+            int i;
+            for(i=0; i<4; ++i)
+            {
+            if(da(dx, dist[i]) == edge_marker) break;
+            }
+
+            if(i < 4) da.set(edge_marker, dx);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue, class DestValue>
+inline void
+differenceOfExponentialCrackEdgeImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                      pair<DestIterator, DestAccessor> dest,
+                                      double scale, GradValue gradient_threshold,
+                                      DestValue edge_marker)
+{
+    differenceOfExponentialCrackEdgeImage(src.first, src.second, src.third,
+                                          dest.first, dest.second,
+                                          scale, gradient_threshold, edge_marker);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class GradValue, class DestValue>
+inline void
+differenceOfExponentialCrackEdgeImage(MultiArrayView<2, T1, S1> const & src,
+                                      MultiArrayView<2, T2, S2> dest,
+                                      double scale,
+                                      GradValue gradient_threshold,
+                                      DestValue edge_marker)
+{
+    vigra_precondition(2*src.shape() - Shape2(1) == dest.shape(),
+        "differenceOfExponentialCrackEdgeImage(): shape mismatch between input and output.");
+    differenceOfExponentialCrackEdgeImage(srcImageRange(src),
+                                          destImage(dest),
+                                          scale, gradient_threshold, edge_marker);
+}
+
+/********************************************************/
+/*                                                      */
+/*                  removeShortEdges                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Remove short edges from an edge image.
+
+    This algorithm can be applied as a post-processing operation of
+    \ref differenceOfExponentialEdgeImage() and \ref differenceOfExponentialCrackEdgeImage().
+    It removes all edges that are shorter than <TT>min_edge_length</TT>. The corresponding
+    pixels are set to the <TT>non_edge_marker</TT>. The idea behind this algorithms is
+    that very short edges are probably caused by noise and don't represent interesting
+    image structure. Technically, the algorithms executes a connected components labeling,
+    so the image's value type must be equality comparable.
+
+    If the source image fulfills the requirements of a \ref CrackEdgeImage,
+    it will still do so after application of this algorithm.
+
+    Note that this algorithm, unlike most other algorithms in VIGRA, operates in-place,
+    i.e. on only one image. Also, the algorithm assumes that all non-edges pixels are already
+    marked with the given <TT>non_edge_marker</TT> value.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S, class Value>
+        void
+        removeShortEdges(MultiArrayView<2, T, S> image,
+                         unsigned int min_edge_length, Value non_edge_marker);
+    }
+    \endcode
+
+    \deprecatedAPI{removeShortEdges}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class Iterator, class Accessor, class SrcValue>
+        void removeShortEdges(
+               Iterator sul, Iterator slr, Accessor sa,
+               int min_edge_length, SrcValue non_edge_marker)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class Iterator, class Accessor, class SrcValue>
+        void removeShortEdges(
+               triple<Iterator, Iterator, Accessor> src,
+               int min_edge_length, SrcValue non_edge_marker)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), edges(w,h);
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    differenceOfExponentialEdgeImage(src, edges,
+                                     0.8, 4.0, 1);
+
+    // zero edges shorter than 10 pixels
+    removeShortEdges(edges, 10, 0);
+    \endcode
+
+    \deprecatedUsage{removeShortEdges}
+    \code
+    vigra::BImage src(w,h), edges(w,h);
+
+    // empty edge image
+    edges = 0;
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    vigra::differenceOfExponentialEdgeImage(srcImageRange(src), destImage(edges),
+                                     0.8, 4.0, 1);
+
+    // zero edges shorter than 10 pixels
+    vigra::removeShortEdges(srcImageRange(edges), 10, 0);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+
+    u == u
+
+    SrcValue non_edge_marker;
+    src_accessor.set(non_edge_marker, src_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void removeShortEdges)
+
+template <class Iterator, class Accessor, class Value>
+void removeShortEdges(
+               Iterator sul, Iterator slr, Accessor sa,
+           unsigned int min_edge_length, Value non_edge_marker)
+{
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    int x,y;
+
+    IImage labels(w, h);
+    labels = 0;
+
+    int number_of_regions =
+                labelImageWithBackground(srcIterRange(sul,slr,sa),
+                                     destImage(labels), true, non_edge_marker);
+
+    ArrayOfRegionStatistics<FindROISize<int> >
+                                         region_stats(number_of_regions);
+
+    inspectTwoImages(srcImageRange(labels), srcImage(labels), region_stats);
+
+    IImage::Iterator ly = labels.upperLeft();
+    Iterator oy = sul;
+
+    for(y=0; y<h; ++y, ++oy.y, ++ly.y)
+    {
+        Iterator ox(oy);
+        IImage::Iterator lx(ly);
+
+        for(x=0; x<w; ++x, ++ox.x, ++lx.x)
+        {
+            if(sa(ox) == non_edge_marker) continue;
+            if((region_stats[*lx].count) < min_edge_length)
+            {
+                 sa.set(non_edge_marker, ox);
+            }
+        }
+    }
+}
+
+template <class Iterator, class Accessor, class Value>
+inline void
+removeShortEdges(triple<Iterator, Iterator, Accessor> src,
+                 unsigned int min_edge_length, Value non_edge_marker)
+{
+    removeShortEdges(src.first, src.second, src.third,
+                     min_edge_length, non_edge_marker);
+}
+
+template <class T, class S, class Value>
+inline void
+removeShortEdges(MultiArrayView<2, T, S> image,
+                 unsigned int min_edge_length, Value non_edge_marker)
+{
+    removeShortEdges(destImageRange(image),
+                     min_edge_length, non_edge_marker);
+}
+
+/********************************************************/
+/*                                                      */
+/*             closeGapsInCrackEdgeImage                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Close one-pixel wide gaps in a cell grid edge image.
+
+    This algorithm is typically applied as a post-processing operation of
+    \ref differenceOfExponentialCrackEdgeImage(). The source image must fulfill
+    the requirements of a \ref CrackEdgeImage, and will still do so after
+    application of this algorithm.
+
+    It closes one pixel wide gaps in the edges resulting from this algorithm.
+    Since these gaps are usually caused by zero crossing slightly below the gradient
+    threshold used in edge detection, this algorithms acts like a weak hysteresis
+    thresholding. The newly found edge pixels are marked with the given <TT>edge_marker</TT>.
+    The image's value type must be equality comparable.
+
+    Note that this algorithm, unlike most other algorithms in VIGRA, operates in-place,
+    i.e. on only one image.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S, class Value>
+        void
+        closeGapsInCrackEdgeImage(MultiArrayView<2, T, S> image, Value edge_marker);
+    }
+    \endcode
+
+    \deprecatedAPI{closeGapsInCrackEdgeImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor, class SrcValue>
+        void closeGapsInCrackEdgeImage(
+               SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+               SrcValue edge_marker)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor, class SrcValue>
+        void closeGapsInCrackEdgeImage(
+               triple<SrcIterator, SrcIterator, SrcAccessor> src,
+               SrcValue edge_marker)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), edges(2*w-1, 2*h-1);
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    differenceOfExponentialCrackEdgeImage(src, edges,
+                                          0.8, 4.0, 1);
+
+    // close gaps, mark with 1
+    closeGapsInCrackEdgeImage(edges, 1);
+
+    // zero edges shorter than 20 pixels
+    removeShortEdges(edges, 10, 0);
+    \endcode
+
+    \deprecatedUsage{closeGapsInCrackEdgeImage}
+    \code
+    vigra::BImage src(w,h), edges(2*w-1, 2*h-1);
+
+    // empty edge image
+    edges = 0;
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    vigra::differenceOfExponentialCrackEdgeImage(srcImageRange(src), destImage(edges),
+                                         0.8, 4.0, 1);
+
+    // close gaps, mark with 1
+    vigra::closeGapsInCrackEdgeImage(srcImageRange(edges), 1);
+
+    // zero edges shorter than 20 pixels
+    vigra::removeShortEdges(srcImageRange(edges), 10, 0);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+
+    u == u
+    u != u
+
+    SrcValue edge_marker;
+    src_accessor.set(edge_marker, src_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void closeGapsInCrackEdgeImage)
+
+template <class SrcIterator, class SrcAccessor, class SrcValue>
+void closeGapsInCrackEdgeImage(
+               SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+           SrcValue edge_marker)
+{
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    
+    vigra_precondition(w % 2 == 1 && h % 2 == 1,
+        "closeGapsInCrackEdgeImage(): Input is not a crack edge image (must have odd-numbered shape).");
+        
+    int w2 = w / 2, h2 = h / 2, x, y;
+
+    int count1, count2, count3;
+
+    const Diff2D right(1,0);
+    const Diff2D bottom(0,1);
+    const Diff2D left(-1,0);
+    const Diff2D top(0,-1);
+
+    const Diff2D leftdist[] = { Diff2D(0, 0), Diff2D(-1, 1), Diff2D(-2, 0), Diff2D(-1, -1)};
+    const Diff2D rightdist[] = { Diff2D(2, 0), Diff2D(1, 1), Diff2D(0, 0), Diff2D(1, -1)};
+    const Diff2D topdist[] = { Diff2D(1, -1), Diff2D(0, 0), Diff2D(-1, -1), Diff2D(0, -2)};
+    const Diff2D bottomdist[] = { Diff2D(1, 1), Diff2D(0, 2), Diff2D(-1, 1), Diff2D(0, 0)};
+
+    int i;
+
+    SrcIterator sy = sul + Diff2D(0,1);
+    SrcIterator sx;
+
+    // close 1-pixel wide gaps (x-direction)
+    for(y=0; y<h2; ++y, sy.y+=2)
+    {
+        sx = sy + Diff2D(2,0);
+
+        for(x=2; x<w2; ++x, sx.x+=2)
+        {
+            if(sa(sx) == edge_marker) continue;
+
+            if(sa(sx, left) != edge_marker) continue;
+            if(sa(sx, right) != edge_marker) continue;
+
+            count1 = 0;
+            count2 = 0;
+            count3 = 0;
+
+            for(i=0; i<4; ++i)
+            {
+                if(sa(sx, leftdist[i]) == edge_marker)
+                {
+                    ++count1;
+                    count3 ^= 1 << i;
+                }
+                if(sa(sx, rightdist[i]) == edge_marker)
+                {
+                    ++count2;
+                    count3 ^= 1 << i;
+                }
+            }
+
+            if(count1 <= 1 || count2 <= 1 || count3 == 15)
+            {
+                sa.set(edge_marker, sx);
+            }
+        }
+   }
+
+    sy = sul + Diff2D(1,2);
+
+    // close 1-pixel wide gaps (y-direction)
+    for(y=2; y<h2; ++y, sy.y+=2)
+    {
+        sx = sy;
+
+        for(x=0; x<w2; ++x, sx.x+=2)
+        {
+            if(sa(sx) == edge_marker) continue;
+
+            if(sa(sx, top) != edge_marker) continue;
+            if(sa(sx, bottom) != edge_marker) continue;
+
+            count1 = 0;
+            count2 = 0;
+            count3 = 0;
+
+            for(i=0; i<4; ++i)
+            {
+                if(sa(sx, topdist[i]) == edge_marker)
+                {
+                    ++count1;
+                    count3 ^= 1 << i;
+                }
+                if(sa(sx, bottomdist[i]) == edge_marker)
+                {
+                    ++count2;
+                    count3 ^= 1 << i;
+                }
+            }
+
+            if(count1 <= 1 || count2 <= 1 || count3 == 15)
+            {
+                sa.set(edge_marker, sx);
+            }
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor, class SrcValue>
+inline void
+closeGapsInCrackEdgeImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                          SrcValue edge_marker)
+{
+    closeGapsInCrackEdgeImage(src.first, src.second, src.third,
+                              edge_marker);
+}
+
+template <class T, class S, class Value>
+inline void
+closeGapsInCrackEdgeImage(MultiArrayView<2, T, S> image, Value edge_marker)
+{
+    closeGapsInCrackEdgeImage(destImageRange(image), edge_marker);
+}
+
+/********************************************************/
+/*                                                      */
+/*              beautifyCrackEdgeImage                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Beautify crack edge image for visualization.
+
+    This algorithm is applied as a post-processing operation of
+    \ref differenceOfExponentialCrackEdgeImage(). The source image must fulfill
+    the requirements of a \ref CrackEdgeImage, but will <b> not</b> do so after
+    application of this algorithm. In particular, the algorithm removes zero-cells
+    marked as edges to avoid staircase effects on diagonal lines like this:
+
+    \code
+    original edge points (*)     resulting edge points
+
+          . * . . .                   . * . . .
+          . * * * .                   . . * . .
+          . . . * .           =>      . . . * .
+          . . . * *                   . . . . *
+          . . . . .                   . . . . .
+    \endcode
+
+    Therefore, this algorithm should only be applied as a visualization aid, i.e.
+    for human inspection. The algorithm assumes that edges are marked with <TT>edge_marker</TT>,
+    and background pixels with <TT>background_marker</TT>. The image's value type must be
+    equality comparable.
+
+    Note that this algorithm, unlike most other algorithms in VIGRA, operates in-place,
+    i.e. on only one image.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S, class Value>
+        void
+        beautifyCrackEdgeImage(MultiArrayView<2, T, S> image,
+                               Value edge_marker, Value background_marker);
+    }
+    \endcode
+
+    \deprecatedAPI{beautifyCrackEdgeImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor, class SrcValue>
+        void beautifyCrackEdgeImage(
+               SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+               SrcValue edge_marker, SrcValue background_marker)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor, class SrcValue>
+        void beautifyCrackEdgeImage(
+                   triple<SrcIterator, SrcIterator, SrcAccessor> src,
+               SrcValue edge_marker, SrcValue background_marker)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), edges(2*w-1, 2*h-1);
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    differenceOfExponentialCrackEdgeImage(src, edges,
+                                          0.8, 4.0, 1);
+
+    // beautify edge image for visualization
+    beautifyCrackEdgeImage(edges, 1, 0);
+
+    // show to the user ('window' is an unspecified GUI widget to display VIGRA images)
+    window.open(edges);
+    \endcode
+
+    \deprecatedUsage{beautifyCrackEdgeImage}
+    \code
+    vigra::BImage src(w,h), edges(2*w-1, 2*h-1);
+
+    // empty edge image
+    edges = 0;
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    vigra::differenceOfExponentialCrackEdgeImage(srcImageRange(src), destImage(edges),
+                                         0.8, 4.0, 1);
+
+    // beautify edge image for visualization
+    vigra::beautifyCrackEdgeImage(destImageRange(edges), 1, 0);
+
+    // show to the user
+    window.open(edges);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+
+    u == u
+    u != u
+
+    SrcValue background_marker;
+    src_accessor.set(background_marker, src_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void beautifyCrackEdgeImage)
+
+template <class SrcIterator, class SrcAccessor, class SrcValue>
+void beautifyCrackEdgeImage(
+               SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+           SrcValue edge_marker, SrcValue background_marker)
+{
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    
+    vigra_precondition(w % 2 == 1 && h % 2 == 1,
+        "beautifyCrackEdgeImage(): Input is not a crack edge image (must have odd-numbered shape).");
+        
+    int w2 = w / 2, h2 = h / 2, x, y;
+
+    SrcIterator sy = sul + Diff2D(1,1);
+    SrcIterator sx;
+
+    const Diff2D right(1,0);
+    const Diff2D bottom(0,1);
+    const Diff2D left(-1,0);
+    const Diff2D top(0,-1);
+
+    //  delete 0-cells at corners
+    for(y=0; y<h2; ++y, sy.y+=2)
+    {
+        sx = sy;
+
+        for(x=0; x<w2; ++x, sx.x+=2)
+        {
+            if(sa(sx) != edge_marker) continue;
+
+            if(sa(sx, right) == edge_marker && sa(sx, left) == edge_marker) continue;
+            if(sa(sx, bottom) == edge_marker && sa(sx, top) == edge_marker) continue;
+
+            sa.set(background_marker, sx);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor, class SrcValue>
+inline void
+beautifyCrackEdgeImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                       SrcValue edge_marker, SrcValue background_marker)
+{
+    beautifyCrackEdgeImage(src.first, src.second, src.third,
+                           edge_marker, background_marker);
+}
+
+template <class T, class S, class Value>
+inline void
+beautifyCrackEdgeImage(MultiArrayView<2, T, S> image,
+                       Value edge_marker, Value background_marker)
+{
+    beautifyCrackEdgeImage(destImageRange(image),
+                           edge_marker, background_marker);
+}
+
+
+/** Helper class that stores edgel attributes.
+*/
+class Edgel
+{
+  public:
+  
+        /** The type of an Edgel's members.
+        */
+    typedef float value_type;
+
+        /** The edgel's sub-pixel x coordinate.
+        */
+    value_type x;
+
+        /** The edgel's sub-pixel y coordinate.
+        */
+    value_type y;
+
+        /** The edgel's strength (magnitude of the gradient vector).
+        */
+    value_type strength;
+
+        /** \brief The edgel's orientation. 
+        
+        This is the clockwise angle in radians
+        between the x-axis and the edge, so that the bright side of the
+        edge is on the left when one looks along the orientation vector. 
+        The angle is measured clockwise because the y-axis increases 
+        downwards (left-handed coordinate system):
+
+        \code
+
+        edgel axis
+             \  
+        (dark \  (bright side)
+        side)  \ 
+                \ 
+                 +------------> x-axis
+                 |\    |
+                 | \ /_/  orientation angle
+                 |  \\
+                 |   \
+                 |   
+          y-axis V  
+        \endcode
+
+        So, for example a vertical edge with its dark side on the left
+        has orientation PI/2, and a horizontal edge with dark side on top
+        has orientation PI. Obviously, the edge's orientation changes
+        by PI if the contrast is reversed.
+        
+        Note that this convention changed as of VIGRA version 1.7.0.
+
+        */
+    value_type orientation;
+
+    Edgel()
+    : x(0.0), y(0.0), strength(0.0), orientation(0.0)
+    {}
+
+    Edgel(value_type ix, value_type iy, value_type is, value_type io)
+    : x(ix), y(iy), strength(is), orientation(io)
+    {}
+};
+
+template <class SrcIterator, class SrcAccessor, 
+          class MagnitudeImage, class BackInsertable, class GradValue>
+void internalCannyFindEdgels(SrcIterator ul, SrcAccessor grad,
+                             MagnitudeImage const & magnitude,
+                             BackInsertable & edgels, GradValue grad_thresh)
+{
+    typedef typename SrcAccessor::value_type PixelType;
+    typedef typename PixelType::value_type ValueType;
+
+    vigra_precondition(grad_thresh >= NumericTraits<GradValue>::zero(),
+         "cannyFindEdgels(): gradient threshold must not be negative.");
+    
+    double t = 0.5 / VIGRA_CSTD::sin(M_PI/8.0);
+
+    ul += Diff2D(1,1);
+    for(int y=1; y<magnitude.height()-1; ++y, ++ul.y)
+    {
+        SrcIterator ix = ul;
+        for(int x=1; x<magnitude.width()-1; ++x, ++ix.x)
+        {
+            double mag = magnitude(x, y);
+            if(mag <= grad_thresh)
+                   continue;
+            ValueType gradx = grad.getComponent(ix, 0);
+            ValueType grady = grad.getComponent(ix, 1);
+
+            int dx = (int)VIGRA_CSTD::floor(gradx*t/mag + 0.5);
+            int dy = (int)VIGRA_CSTD::floor(grady*t/mag + 0.5);
+
+            int x1 = x - dx,
+                x2 = x + dx,
+                y1 = y - dy,
+                y2 = y + dy;
+
+            double m1 = magnitude(x1, y1);
+            double m3 = magnitude(x2, y2);
+
+            if(m1 < mag && m3 <= mag)
+            {
+                Edgel edgel;
+
+                // local maximum => quadratic interpolation of sub-pixel location
+                double del = 0.5 * (m1 - m3) / (m1 + m3 - 2.0*mag);
+                edgel.x = Edgel::value_type(x + dx*del);
+                edgel.y = Edgel::value_type(y + dy*del);
+                edgel.strength = Edgel::value_type(mag);
+                double orientation = VIGRA_CSTD::atan2(grady, gradx) + 0.5*M_PI;
+                if(orientation < 0.0)
+                    orientation += 2.0*M_PI;
+                edgel.orientation = Edgel::value_type(orientation);
+                edgels.push_back(edgel);
+            }
+        }
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*                      cannyEdgelList                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Simple implementation of Canny's edge detector.
+    
+    The function can be called in two modes: If you pass a 'scale', it is assumed that the 
+    original image is scalar, and the Gaussian gradient is internally computed at the
+    given 'scale'. If the function is called without scale parameter, it is assumed that
+    the given image already contains the gradient (i.e. its value_type must be 
+    a vector of length 2).
+
+    On the basis of the gradient image, a simple non-maxima suppression is performed:
+    for each 3x3 neighborhood, it is determined whether the center pixel has
+    larger gradient magnitude than its two neighbors in gradient direction
+    (where the direction is rounded into octants). If this is the case,
+    a new \ref Edgel is appended to the given vector of <TT>edgels</TT>. The subpixel
+    edgel position is determined by fitting a parabola to the three gradient 
+    magnitude values mentioned above. The sub-pixel location of the parabola's tip
+    and the gradient magnitude and direction (from the pixel center)
+    are written in the newly created edgel.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class T, class S, class BackInsertable>
+        void
+        cannyEdgelList(MultiArrayView<2, T, S> const & src,
+                       BackInsertable & edgels,
+                       double scale);
+
+        // compute edgels from a pre-computed gradient image
+        template <class T, class S, class BackInsertable>
+        void
+        cannyEdgelList(MultiArrayView<2, TinyVector<T, 2>, S> const & src,
+                       BackInsertable & edgels);
+    }
+    \endcode
+
+    \deprecatedAPI{cannyEdgelList}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // compute edgels from a gradient image
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void 
+        cannyEdgelList(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                       BackInsertable & edgels);
+
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void
+        cannyEdgelList(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                       BackInsertable & edgels, double scale);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // compute edgels from a gradient image
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void
+        cannyEdgelList(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                       BackInsertable & edgels);
+
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void
+        cannyEdgelList(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                       BackInsertable & edgels, double scale);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h);
+
+    // create empty edgel list
+    std::vector<vigra::Edgel> edgels;
+    ...
+
+    // find edgels at scale 0.8
+    cannyEdgelList(src, edgels, 0.8);
+    \endcode
+
+    \deprecatedUsage{cannyEdgelList}
+    \code
+    vigra::BImage src(w,h);
+
+    // empty edgel list
+    std::vector<vigra::Edgel> edgels;
+    ...
+
+    // find edgels at scale 0.8
+    vigra::cannyEdgelList(srcImageRange(src), edgels, 0.8);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft;
+    SrcAccessor src_accessor;
+
+    src_accessor(src_upperleft);
+
+    BackInsertable edgels;
+    edgels.push_back(Edgel());
+    \endcode
+    SrcAccessor::value_type must be a type convertible to float
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    \code
+    scale > 0
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void cannyEdgelList)
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+void 
+cannyEdgelList(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+               BackInsertable & edgels, double scale)
+{
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    BasicImage<TinyVector<TmpType, 2> > grad(lr-ul);
+    gaussianGradient(srcIterRange(ul, lr, src), destImage(grad), scale);
+
+    cannyEdgelList(srcImageRange(grad), edgels);
+}
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+void 
+cannyEdgelList(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+               BackInsertable & edgels)
+{
+    using namespace functor;
+    
+    typedef typename SrcAccessor::value_type SrcType;
+    typedef typename NumericTraits<typename SrcType::value_type>::RealPromote TmpType;
+    BasicImage<TmpType> magnitude(lr-ul);
+    transformImage(srcIterRange(ul, lr, src), destImage(magnitude), norm(Arg1()));
+
+    // find edgels
+    internalCannyFindEdgels(ul, src, magnitude, edgels, NumericTraits<TmpType>::zero());
+}
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+inline void
+cannyEdgelList(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+               BackInsertable & edgels, double scale)
+{
+    cannyEdgelList(src.first, src.second, src.third, edgels, scale);
+}
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+inline void
+cannyEdgelList(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+               BackInsertable & edgels)
+{
+    cannyEdgelList(src.first, src.second, src.third, edgels);
+}
+
+template <class T, class S, class BackInsertable>
+inline void
+cannyEdgelList(MultiArrayView<2, T, S> const & src,
+               BackInsertable & edgels, double scale)
+{
+    cannyEdgelList(srcImageRange(src), edgels, scale);
+}
+
+template <class T, class S, class BackInsertable>
+inline void
+cannyEdgelList(MultiArrayView<2, TinyVector<T, 2>, S> const & src,
+               BackInsertable & edgels)
+{
+    cannyEdgelList(srcImageRange(src), edgels);
+}
+
+/********************************************************/
+/*                                                      */
+/*              cannyEdgelListThreshold                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Canny's edge detector with thresholding.
+    
+    This function works exactly like \ref cannyEdgelList(), but 
+    you also pass a threshold for the minimal gradient magnitude, 
+    so that edgels whose strength is below the threshold are not 
+    inserted into the edgel list.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class T, class S, 
+                  class BackInsertable, class GradValue>
+        void
+        cannyEdgelListThreshold(MultiArrayView<2, T, S> const & src,
+                                BackInsertable & edgels,
+                                double scale,
+                                GradValue grad_threshold);
+
+        // compute edgels from a pre-computed gradient image
+        template <class T, class S, 
+                  class BackInsertable, class GradValue>
+        void
+        cannyEdgelListThreshold(MultiArrayView<2, TinyVector<T, 2>, S> const & src,
+                                BackInsertable & edgels,
+                                GradValue grad_threshold);
+    }
+    \endcode
+
+    \deprecatedAPI{cannyEdgelListThreshold}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // compute edgels from a gradient image
+        template <class SrcIterator, class SrcAccessor, 
+                  class BackInsertable, class GradValue>
+        void 
+        cannyEdgelListThreshold(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                                BackInsertable & edgels, GradValue grad_threshold);
+
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class SrcIterator, class SrcAccessor, 
+                  class BackInsertable, class GradValue>
+        void 
+        cannyEdgelListThreshold(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                                BackInsertable & edgels, double scale, GradValue grad_threshold);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // compute edgels from a gradient image
+        template <class SrcIterator, class SrcAccessor, 
+                  class BackInsertable, class GradValue>
+        void
+        cannyEdgelListThreshold(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                BackInsertable & edgels, GradValue grad_threshold);
+
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class SrcIterator, class SrcAccessor, 
+                  class BackInsertable, class GradValue>
+        void
+        cannyEdgelListThreshold(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                BackInsertable & edgels, double scale, GradValue grad_threshold);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h);
+
+    // create empty edgel list
+    std::vector<vigra::Edgel> edgels;
+    ...
+
+    // find edgels at scale 0.8, only considering gradient magnitudes above 2.0
+    cannyEdgelListThreshold(src, edgels, 0.8, 2.0);
+    \endcode
+
+    \deprecatedUsage{cannyEdgelListThreshold}
+    \code
+    vigra::BImage src(w,h);
+
+    // empty edgel list
+    std::vector<vigra::Edgel> edgels;
+    ...
+
+    // find edgels at scale 0.8, only considering gradient above 2.0
+    vigra::cannyEdgelListThreshold(srcImageRange(src), edgels, 0.8, 2.0);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft;
+    SrcAccessor src_accessor;
+
+    src_accessor(src_upperleft);
+
+    BackInsertable edgels;
+    edgels.push_back(Edgel());
+    \endcode
+    SrcAccessor::value_type must be a type convertible to float
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    \code
+    scale > 0
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void cannyEdgelListThreshold)
+
+template <class SrcIterator, class SrcAccessor, 
+          class BackInsertable, class GradValue>
+void 
+cannyEdgelListThreshold(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                        BackInsertable & edgels, double scale, GradValue grad_threshold)
+{
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    BasicImage<TinyVector<TmpType, 2> > grad(lr-ul);
+    gaussianGradient(srcIterRange(ul, lr, src), destImage(grad), scale);
+
+    cannyEdgelListThreshold(srcImageRange(grad), edgels, grad_threshold);
+}
+
+template <class SrcIterator, class SrcAccessor, 
+          class BackInsertable, class GradValue>
+void 
+cannyEdgelListThreshold(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                        BackInsertable & edgels, GradValue grad_threshold)
+{
+    using namespace functor;
+    
+    typedef typename SrcAccessor::value_type SrcType;
+    typedef typename NumericTraits<typename SrcType::value_type>::RealPromote TmpType;
+    BasicImage<TmpType> magnitude(lr-ul);
+    transformImage(srcIterRange(ul, lr, src), destImage(magnitude), norm(Arg1()));
+
+    // find edgels
+    internalCannyFindEdgels(ul, src, magnitude, edgels, grad_threshold);
+}
+
+template <class SrcIterator, class SrcAccessor, 
+          class BackInsertable, class GradValue>
+inline void
+cannyEdgelListThreshold(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        BackInsertable & edgels, double scale, GradValue grad_threshold)
+{
+    cannyEdgelListThreshold(src.first, src.second, src.third, edgels, scale, grad_threshold);
+}
+
+template <class SrcIterator, class SrcAccessor, 
+          class BackInsertable, class GradValue>
+inline void
+cannyEdgelListThreshold(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        BackInsertable & edgels, GradValue grad_threshold)
+{
+    cannyEdgelListThreshold(src.first, src.second, src.third, edgels, grad_threshold);
+}
+
+template <class T, class S, 
+          class BackInsertable, class GradValue>
+inline void
+cannyEdgelListThreshold(MultiArrayView<2, T, S> const & src,
+                        BackInsertable & edgels,
+                        double scale,
+                        GradValue grad_threshold)
+{
+    cannyEdgelListThreshold(srcImageRange(src), edgels, scale, grad_threshold);
+}
+
+template <class T, class S, 
+          class BackInsertable, class GradValue>
+inline void
+cannyEdgelListThreshold(MultiArrayView<2, TinyVector<T, 2>, S> const & src,
+                        BackInsertable & edgels,
+                        GradValue grad_threshold)
+{
+    cannyEdgelListThreshold(srcImageRange(src), edgels, grad_threshold);
+}
+
+
+/********************************************************/
+/*                                                      */
+/*                       cannyEdgeImage                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Detect and mark edges in an edge image using Canny's algorithm.
+
+    This operator first calls \ref cannyEdgelList() with the given scale to generate an
+    edgel list for the given image. Then it scans this list and selects edgels
+    whose strength is above the given <TT>gradient_threshold</TT>. For each of these
+    edgels, the edgel's location is rounded to the nearest pixel, and that
+    pixel marked with the given <TT>edge_marker</TT>.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class GradValue, class DestValue>
+        void 
+        cannyEdgeImage(MultiArrayView<2, T1, S1> const & src,
+                       MultiArrayView<2, T2, S2> dest,
+                       double scale,
+                       GradValue gradient_threshold,
+                       DestValue edge_marker);
+    }
+    \endcode
+
+    \deprecatedAPI{cannyEdgeImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class GradValue, class DestValue>
+        void cannyEdgeImage(
+                   SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+                   DestIterator dul, DestAccessor da,
+                   double scale, GradValue gradient_threshold, DestValue edge_marker);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class GradValue, class DestValue>
+        void cannyEdgeImage(
+                   triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   double scale, GradValue gradient_threshold, DestValue edge_marker);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), edges(w,h);
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    cannyEdgeImage(src, edges, 0.8, 4.0, 1);
+    \endcode
+
+    \deprecatedUsage{cannyEdgeImage}
+    \code
+    vigra::BImage src(w,h), edges(w,h);
+
+    // empty edge image
+    edges = 0;
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
+    vigra::cannyEdgeImage(srcImageRange(src), destImage(edges),
+                                     0.8, 4.0, 1);
+    \endcode
+    <b> Required Interface:</b>
+    see also: \ref cannyEdgelList().
+    \code
+    DestImageIterator dest_upperleft;
+    DestAccessor dest_accessor;
+    DestValue edge_marker;
+
+    dest_accessor.set(edge_marker, dest_upperleft, vigra::Diff2D(1,1));
+    \endcode
+    \deprecatedEnd
+    
+    <b> Preconditions:</b>
+
+    \code
+    scale > 0
+    gradient_threshold > 0
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void cannyEdgeImage)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue, class DestValue>
+void cannyEdgeImage(
+           SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+           DestIterator dul, DestAccessor da,
+           double scale, GradValue gradient_threshold, DestValue edge_marker)
+{
+    std::vector<Edgel> edgels;
+
+    cannyEdgelListThreshold(sul, slr, sa, edgels, scale, gradient_threshold);
+    
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    for(unsigned int i=0; i<edgels.size(); ++i)
+    {
+        Diff2D pix((int)(edgels[i].x + 0.5), (int)(edgels[i].y + 0.5));
+        
+        if(pix.x < 0 || pix.x >= w || pix.y < 0 || pix.y >= h)
+            continue;
+
+        da.set(edge_marker, dul, pix);
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue, class DestValue>
+inline void 
+cannyEdgeImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+               pair<DestIterator, DestAccessor> dest,
+               double scale, GradValue gradient_threshold, DestValue edge_marker)
+{
+    cannyEdgeImage(src.first, src.second, src.third,
+                   dest.first, dest.second,
+                   scale, gradient_threshold, edge_marker);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class GradValue, class DestValue>
+inline void 
+cannyEdgeImage(MultiArrayView<2, T1, S1> const & src,
+               MultiArrayView<2, T2, S2> dest,
+               double scale, GradValue gradient_threshold, DestValue edge_marker)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "cannyEdgeImage(): shape mismatch between input and output.");
+    cannyEdgeImage(srcImageRange(src),
+                   destImage(dest),
+                   scale, gradient_threshold, edge_marker);
+}
+
+/********************************************************/
+
+namespace detail {
+
+template <class DestIterator>
+int neighborhoodConfiguration(DestIterator dul)
+{
+    int v = 0;
+    NeighborhoodCirculator<DestIterator, EightNeighborCode> c(dul, EightNeighborCode::SouthEast);
+    for(int i=0; i<8; ++i, --c)
+    {
+        v = (v << 1) | ((*c != 0) ? 1 : 0);
+    }
+
+    return v;
+}
+
+template <class GradValue>
+struct SimplePoint
+{
+    Diff2D point;
+    GradValue grad;
+
+    SimplePoint(Diff2D const & p, GradValue g)
+    : point(p), grad(g)
+    {}
+
+    bool operator<(SimplePoint const & o) const
+    {
+        return grad < o.grad;
+    }
+
+    bool operator>(SimplePoint const & o) const
+    {
+        return grad > o.grad;
+    }
+};
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue, class DestValue>
+void cannyEdgeImageFromGrad(
+           SrcIterator sul, SrcIterator slr, SrcAccessor grad,
+           DestIterator dul, DestAccessor da,
+           GradValue gradient_threshold, DestValue edge_marker)
+{
+    typedef typename SrcAccessor::value_type PixelType;
+    typedef typename NormTraits<PixelType>::SquaredNormType NormType;
+
+    NormType zero = NumericTraits<NormType>::zero();
+    double tan22_5 = M_SQRT2 - 1.0;
+    typename NormTraits<GradValue>::SquaredNormType g2thresh = squaredNorm(gradient_threshold);
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    sul += Diff2D(1,1);
+    dul += Diff2D(1,1);
+    Diff2D p(0,0);
+
+    for(int y = 1; y < h-1; ++y, ++sul.y, ++dul.y)
+    {
+        SrcIterator sx = sul;
+        DestIterator dx = dul;
+        for(int x = 1; x < w-1; ++x, ++sx.x, ++dx.x)
+        {
+            PixelType g = grad(sx);
+            NormType g2n = squaredNorm(g);
+            if(g2n < g2thresh)
+                continue;
+
+            NormType g2n1, g2n3;
+            // find out quadrant
+            if(abs(g[1]) < tan22_5*abs(g[0]))
+            {
+                // north-south edge
+                g2n1 = squaredNorm(grad(sx, Diff2D(-1, 0)));
+                g2n3 = squaredNorm(grad(sx, Diff2D(1, 0)));
+            }
+            else if(abs(g[0]) < tan22_5*abs(g[1]))
+            {
+                // west-east edge
+                g2n1 = squaredNorm(grad(sx, Diff2D(0, -1)));
+                g2n3 = squaredNorm(grad(sx, Diff2D(0, 1)));
+            }
+            else if(g[0]*g[1] < zero)
+            {
+                // north-west-south-east edge
+                g2n1 = squaredNorm(grad(sx, Diff2D(1, -1)));
+                g2n3 = squaredNorm(grad(sx, Diff2D(-1, 1)));
+            }
+            else
+            {
+                // north-east-south-west edge
+                g2n1 = squaredNorm(grad(sx, Diff2D(-1, -1)));
+                g2n3 = squaredNorm(grad(sx, Diff2D(1, 1)));
+            }
+
+            if(g2n1 < g2n && g2n3 <= g2n)
+            {
+                da.set(edge_marker, dx);
+            }
+        }
+    }
+}
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*          cannyEdgeImageFromGradWithThinning          */
+/*                                                      */
+/********************************************************/
+
+/** \brief Detect and mark edges in an edge image using Canny's algorithm.
+
+    The input pixels of this algorithm must be vectors of length 2 (see Required Interface below).
+    It first searches for all pixels whose gradient magnitude is larger
+    than the given <tt>gradient_threshold</tt> and larger than the magnitude of its two neighbors
+    in gradient direction (where these neighbors are determined by nearest neighbor
+    interpolation, i.e. according to the octant where the gradient points into).
+    The resulting edge pixel candidates are then subjected to topological thinning
+    so that the remaining edge pixels can be linked into edgel chains with a provable,
+    non-heuristic algorithm. Thinning is performed so that the pixels with highest gradient
+    magnitude survive. Optionally, the outermost pixels are marked as edge pixels
+    as well when <tt>addBorder</tt> is true. The remaining pixels will be marked in the destination
+    image with the value of <tt>edge_marker</tt> (all non-edge pixels remain untouched).
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class GradValue, class DestValue>
+        void 
+        cannyEdgeImageFromGradWithThinning(MultiArrayView<2, TinyVector<T1, 2>, S1> const & src,
+                                           MultiArrayView<2, T2, S2> dest,
+                                           GradValue gradient_threshold,
+                                           DestValue edge_marker,
+                                           bool addBorder = true);
+    }
+    \endcode
+
+    \deprecatedAPI{cannyEdgeImageFromGradWithThinning}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class GradValue, class DestValue>
+        void cannyEdgeImageFromGradWithThinning(
+                   SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+                   DestIterator dul, DestAccessor da,
+                   GradValue gradient_threshold,
+                   DestValue edge_marker, bool addBorder = true);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class GradValue, class DestValue>
+        void cannyEdgeImageFromGradWithThinning(
+                   triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   GradValue gradient_threshold,
+                   DestValue edge_marker, bool addBorder = true);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), edges(w,h);
+
+    MultiArray<2, TinyVector<float, 2> > grad(w,h);
+    // compute the image gradient at scale 0.8
+    gaussianGradient(src, grad, 0.8);
+
+    // find edges with gradient larger than 4.0, mark with 1, and add border
+    cannyEdgeImageFromGradWithThinning(grad, edges, 4.0, 1, true);
+    \endcode
+    
+    \deprecatedUsage{cannyEdgeImageFromGradWithThinning}
+    \code
+    vigra::BImage src(w,h), edges(w,h);
+
+    vigra::FVector2Image grad(w,h);
+    // compute the image gradient at scale 0.8
+    vigra::gaussianGradient(srcImageRange(src), destImage(grad), 0.8);
+
+    // empty edge image
+    edges = 0;
+    // find edges gradient larger than 4.0, mark with 1, and add border
+    vigra::cannyEdgeImageFromGradWithThinning(srcImageRange(grad), destImage(edges),
+                                              4.0, 1, true);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    // the input pixel type must be a vector with two elements
+    SrcImageIterator src_upperleft;
+    SrcAccessor src_accessor;
+    typedef SrcAccessor::value_type SrcPixel;
+    typedef NormTraits<SrcPixel>::SquaredNormType SrcSquaredNormType;
+
+    SrcPixel g = src_accessor(src_upperleft);
+    SrcPixel::value_type g0 = g[0];
+    SrcSquaredNormType gn = squaredNorm(g);
+
+    DestImageIterator dest_upperleft;
+    DestAccessor dest_accessor;
+    DestValue edge_marker;
+
+    dest_accessor.set(edge_marker, dest_upperleft, vigra::Diff2D(1,1));
+    \endcode
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    \code
+    gradient_threshold > 0
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void cannyEdgeImageFromGradWithThinning)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue, class DestValue>
+void cannyEdgeImageFromGradWithThinning(
+           SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+           DestIterator dul, DestAccessor da,
+           GradValue gradient_threshold,
+           DestValue edge_marker, bool addBorder = true)
+{
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    BImage edgeImage(w, h, BImage::value_type(0));
+    BImage::traverser eul = edgeImage.upperLeft();
+    BImage::Accessor ea = edgeImage.accessor();
+    if(addBorder)
+        initImageBorder(destImageRange(edgeImage), 1, 1);
+    detail::cannyEdgeImageFromGrad(sul, slr, sa, eul, ea, gradient_threshold, 1);
+
+    bool isSimplePoint[256] = {
+        0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,
+        0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+        1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+        0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1,
+        0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0,
+        0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0,
+        1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1,
+        0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+        0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,
+        1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0,
+        0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1,
+        1, 0, 1, 0 };
+
+    eul += Diff2D(1,1);
+    sul += Diff2D(1,1);
+    int w2 = w-2;
+    int h2 = h-2;
+
+    typedef detail::SimplePoint<GradValue> SP;
+    // use std::greater because we need the smallest gradients at the top of the queue
+    std::priority_queue<SP, std::vector<SP>, std::greater<SP> >  pqueue;
+
+    Diff2D p(0,0);
+    for(; p.y < h2; ++p.y)
+    {
+        for(p.x = 0; p.x < w2; ++p.x)
+        {
+            BImage::traverser e = eul + p;
+            if(*e == 0)
+                continue;
+            int v = detail::neighborhoodConfiguration(e);
+            if(isSimplePoint[v])
+            {
+                pqueue.push(SP(p, norm(sa(sul+p))));
+                *e = 2; // remember that it is already in queue
+            }
+        }
+    }
+
+    const Diff2D dist[] = { Diff2D(-1,0), Diff2D(0,-1), Diff2D(1,0),  Diff2D(0,1) };
+
+    while(pqueue.size())
+    {
+        p = pqueue.top().point;
+        pqueue.pop();
+
+        BImage::traverser e = eul + p;
+        int v = detail::neighborhoodConfiguration(e);
+        if(!isSimplePoint[v])
+            continue; // point may no longer be simple because its neighbors changed
+
+        *e = 0; // delete simple point
+
+        for(int i=0; i<4; ++i)
+        {
+            Diff2D pneu = p + dist[i];
+            if(pneu.x == -1 || pneu.y == -1 || pneu.x == w2 || pneu.y == h2)
+                continue; // do not remove points at the border
+
+            BImage::traverser eneu = eul + pneu;
+            if(*eneu == 1) // point is boundary and not yet in the queue
+            {
+                int v = detail::neighborhoodConfiguration(eneu);
+                if(isSimplePoint[v])
+                {
+                    pqueue.push(SP(pneu, norm(sa(sul+pneu))));
+                    *eneu = 2; // remember that it is already in queue
+                }
+            }
+        }
+    }
+
+    initImageIf(destIterRange(dul, dul+Diff2D(w,h), da),
+                maskImage(edgeImage), edge_marker);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue, class DestValue>
+inline void cannyEdgeImageFromGradWithThinning(
+           triple<SrcIterator, SrcIterator, SrcAccessor> src,
+           pair<DestIterator, DestAccessor> dest,
+           GradValue gradient_threshold,
+           DestValue edge_marker, bool addBorder = true)
+{
+    cannyEdgeImageFromGradWithThinning(src.first, src.second, src.third,
+                               dest.first, dest.second,
+                               gradient_threshold, edge_marker, addBorder);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class GradValue, class DestValue>
+inline void 
+cannyEdgeImageFromGradWithThinning(MultiArrayView<2, TinyVector<T1, 2>, S1> const & src,
+                                   MultiArrayView<2, T2, S2> dest,
+                                   GradValue gradient_threshold,
+                                   DestValue edge_marker, bool addBorder = true)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "cannyEdgeImageFromGradWithThinning(): shape mismatch between input and output.");
+    cannyEdgeImageFromGradWithThinning(srcImageRange(src),
+                                       destImage(dest),
+                                       gradient_threshold, edge_marker, addBorder);
+}
+
+/********************************************************/
+/*                                                      */
+/*              cannyEdgeImageWithThinning              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Detect and mark edges in an edge image using Canny's algorithm.
+
+    This operator first calls \ref gaussianGradient() to compute the gradient of the input
+    image, ad then \ref cannyEdgeImageFromGradWithThinning() to generate an
+    edge image. See there for more detailed documentation.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class GradValue, class DestValue>
+        void 
+        cannyEdgeImageWithThinning(MultiArrayView<2, T1, S1> const & src,
+                                   MultiArrayView<2, T2, S2> dest,
+                                   double scale, 
+                                   GradValue gradient_threshold,
+                                   DestValue edge_marker, 
+                                   bool addBorder = true);
+    }
+    \endcode
+
+    \deprecatedAPI{cannyEdgeImageWithThinning}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class GradValue, class DestValue>
+        void cannyEdgeImageWithThinning(
+                   SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+                   DestIterator dul, DestAccessor da,
+                   double scale, GradValue gradient_threshold,
+                   DestValue edge_marker, bool addBorder = true);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class GradValue, class DestValue>
+        void cannyEdgeImageWithThinning(
+                   triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   double scale, GradValue gradient_threshold,
+                   DestValue edge_marker, bool addBorder = true);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h), edges(w,h);
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1, and add border
+    cannyEdgeImageWithThinning(src, edges, 0.8, 4.0, 1, true);
+    \endcode
+
+    \deprecatedUsage{cannyEdgeImageWithThinning}
+    \code
+    vigra::BImage src(w,h), edges(w,h);
+
+    // empty edge image
+    edges = 0;
+    ...
+
+    // find edges at scale 0.8 with gradient larger than 4.0, mark with 1, annd add border
+    vigra::cannyEdgeImageWithThinning(srcImageRange(src), destImage(edges),
+                                     0.8, 4.0, 1, true);
+    \endcode
+    <b> Required Interface:</b>
+    see also: \ref cannyEdgelList().
+    \code
+    DestImageIterator dest_upperleft;
+    DestAccessor dest_accessor;
+    DestValue edge_marker;
+
+    dest_accessor.set(edge_marker, dest_upperleft, vigra::Diff2D(1,1));
+    \endcode
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    \code
+    scale > 0
+    gradient_threshold > 0
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void cannyEdgeImageWithThinning)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue, class DestValue>
+void cannyEdgeImageWithThinning(
+           SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+           DestIterator dul, DestAccessor da,
+           double scale, GradValue gradient_threshold,
+           DestValue edge_marker, bool addBorder = true)
+{
+    // mark pixels that are higher than their neighbors in gradient direction
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    BasicImage<TinyVector<TmpType, 2> > grad(slr-sul);
+    gaussianGradient(srcIterRange(sul, slr, sa), destImage(grad), scale);
+    cannyEdgeImageFromGradWithThinning(srcImageRange(grad), destIter(dul, da),
+                               gradient_threshold, edge_marker, addBorder);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class GradValue, class DestValue>
+inline void 
+cannyEdgeImageWithThinning(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                           pair<DestIterator, DestAccessor> dest,
+                           double scale, GradValue gradient_threshold,
+                           DestValue edge_marker, bool addBorder = true)
+{
+    cannyEdgeImageWithThinning(src.first, src.second, src.third,
+                               dest.first, dest.second,
+                               scale, gradient_threshold, edge_marker, addBorder);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class GradValue, class DestValue>
+inline void 
+cannyEdgeImageWithThinning(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, T2, S2> dest,
+                           double scale, GradValue gradient_threshold,
+                           DestValue edge_marker, bool addBorder = true)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "cannyEdgeImageWithThinning(): shape mismatch between input and output.");
+    cannyEdgeImageWithThinning(srcImageRange(src),
+                               destImage(dest),
+                               scale, gradient_threshold, edge_marker, addBorder);
+}
+
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor, 
+          class MaskImage, class BackInsertable, class GradValue>
+void internalCannyFindEdgels3x3(SrcIterator ul, SrcAccessor grad,
+                                MaskImage const & mask,
+                                BackInsertable & edgels,
+                                GradValue grad_thresh)
+{
+    typedef typename SrcAccessor::value_type PixelType;
+    typedef typename PixelType::value_type ValueType;
+
+    vigra_precondition(grad_thresh >= NumericTraits<GradValue>::zero(),
+         "cannyFindEdgels3x3(): gradient threshold must not be negative.");
+    
+    ul += Diff2D(1,1);
+    for(int y=1; y<mask.height()-1; ++y, ++ul.y)
+    {
+        SrcIterator ix = ul;
+        for(int x=1; x<mask.width()-1; ++x, ++ix.x)
+        {
+            if(!mask(x,y))
+                continue;
+
+            ValueType gradx = grad.getComponent(ix, 0);
+            ValueType grady = grad.getComponent(ix, 1);
+            double mag = hypot(gradx, grady);
+            if(mag <= grad_thresh)
+                   continue;
+            double c = gradx / mag,
+                   s = grady / mag;
+
+            Matrix<double> ml(3,3), mr(3,1), l(3,1), r(3,1);
+            l(0,0) = 1.0;
+
+            for(int yy = -1; yy <= 1; ++yy)
+            {
+                for(int xx = -1; xx <= 1; ++xx)
+                {
+                    double u = c*xx + s*yy;
+                    double v = norm(grad(ix, Diff2D(xx, yy)));
+                    l(1,0) = u;
+                    l(2,0) = u*u;
+                    ml += outer(l);
+                    mr += v*l;
+                }
+            }
+
+            linearSolve(ml, mr, r);
+
+            Edgel edgel;
+
+            // local maximum => quadratic interpolation of sub-pixel location
+            double del = -r(1,0) / 2.0 / r(2,0);
+            if(std::fabs(del) > 1.5)  // don't move by more than about a pixel diameter
+                del = 0.0;
+            edgel.x = Edgel::value_type(x + c*del);
+            edgel.y = Edgel::value_type(y + s*del);
+            edgel.strength = Edgel::value_type(mag);
+            double orientation = VIGRA_CSTD::atan2(grady, gradx) + 0.5*M_PI;
+            if(orientation < 0.0)
+                orientation += 2.0*M_PI;
+            edgel.orientation = Edgel::value_type(orientation);
+            edgels.push_back(edgel);
+        }
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*                   cannyEdgelList3x3                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Improved implementation of Canny's edge detector.
+
+    This operator first computes pixels which are crossed by the edge using
+    cannyEdgeImageWithThinning(). The gradient magnitudes in the 3x3 neighborhood of these
+    pixels are then projected onto the normal of the edge (as determined
+    by the gradient direction). The edgel's subpixel location is found by fitting a
+    parabola through the 9 gradient values and determining the parabola's tip.
+    A new \ref Edgel is appended to the given vector of <TT>edgels</TT>. Since the parabola
+    is fitted to 9 points rather than 3 points as in cannyEdgelList(), the accuracy is higher.
+    
+    The function can be called in two modes: If you pass a 'scale', it is assumed that the 
+    original image is scalar, and the Gaussian gradient is internally computed at the
+    given 'scale'. If the function is called without scale parameter, it is assumed that
+    the given image already contains the gradient (i.e. its value_type must be 
+    a vector of length 2).
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class T, class S, class BackInsertable>
+        void
+        cannyEdgelList3x3(MultiArrayView<2, T, S> const & src,
+                          BackInsertable & edgels, 
+                          double scale);
+
+        // compute edgels from a pre-computed gradient image
+        template <class T, class S, class BackInsertable>
+        void
+        cannyEdgelList3x3(MultiArrayView<2, TinyVector<T, 2>, S> const & src,
+                          BackInsertable & edgels);
+    }
+    \endcode
+
+    \deprecatedAPI{cannyEdgelList3x3}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // compute edgels from a gradient image
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void cannyEdgelList3x3(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                               BackInsertable & edgels);
+
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void cannyEdgelList3x3(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                               BackInsertable & edgels, double scale);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // compute edgels from a gradient image
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void
+        cannyEdgelList3x3(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                          BackInsertable & edgels);
+
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void
+        cannyEdgelList3x3(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                          BackInsertable & edgels, double scale);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h);
+
+    // create empty edgel list
+    std::vector<vigra::Edgel> edgels;
+    ...
+
+    // find edgels at scale 0.8
+    cannyEdgelList3x3(src, edgels, 0.8);
+    \endcode
+
+    \deprecatedUsage{cannyEdgelList3x3}
+    \code
+    vigra::BImage src(w,h);
+
+    // empty edgel list
+    std::vector<vigra::Edgel> edgels;
+    ...
+
+    // find edgels at scale 0.8
+    vigra::cannyEdgelList3x3(srcImageRange(src), edgels, 0.8);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft;
+    SrcAccessor src_accessor;
+
+    src_accessor(src_upperleft);
+
+    BackInsertable edgels;
+    edgels.push_back(Edgel());
+    \endcode
+    SrcAccessor::value_type must be a type convertible to float
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    \code
+    scale > 0
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void cannyEdgelList3x3)
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+void 
+cannyEdgelList3x3(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                  BackInsertable & edgels, double scale)
+{
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    BasicImage<TinyVector<TmpType, 2> > grad(lr-ul);
+    gaussianGradient(srcIterRange(ul, lr, src), destImage(grad), scale);
+
+    cannyEdgelList3x3(srcImageRange(grad), edgels);
+}
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+void 
+cannyEdgelList3x3(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                  BackInsertable & edgels)
+{
+    typedef typename NormTraits<typename SrcAccessor::value_type>::NormType NormType;
+    
+    UInt8Image edges(lr-ul);
+    cannyEdgeImageFromGradWithThinning(srcIterRange(ul, lr, src), destImage(edges),
+                                       0.0, 1, false);
+
+    // find edgels
+    internalCannyFindEdgels3x3(ul, src, edges, edgels, NumericTraits<NormType>::zero());
+}
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+inline void
+cannyEdgelList3x3(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                  BackInsertable & edgels, double scale)
+{
+    cannyEdgelList3x3(src.first, src.second, src.third, edgels, scale);
+}
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+inline void
+cannyEdgelList3x3(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                  BackInsertable & edgels)
+{
+    cannyEdgelList3x3(src.first, src.second, src.third, edgels);
+}
+
+template <class T, class S, class BackInsertable>
+inline void
+cannyEdgelList3x3(MultiArrayView<2, T, S> const & src,
+                  BackInsertable & edgels, double scale)
+{
+    cannyEdgelList3x3(srcImageRange(src), edgels, scale);
+}
+
+template <class T, class S, class BackInsertable>
+inline void
+cannyEdgelList3x3(MultiArrayView<2, TinyVector<T, 2>, S> const & src,
+                  BackInsertable & edgels)
+{
+    cannyEdgelList3x3(srcImageRange(src), edgels);
+}
+
+/********************************************************/
+/*                                                      */
+/*             cannyEdgelList3x3Threshold               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Improved implementation of Canny's edge detector with thresholding.
+
+    This function works exactly like \ref cannyEdgelList3x3(), but 
+    you also pass a threshold for the minimal gradient magnitude, 
+    so that edgels whose strength is below the threshold are not 
+    inserted into the edgel list.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // compute edgels from a gradient image
+        template <class SrcIterator, class SrcAccessor, 
+                  class BackInsertable, class GradValue>
+        void 
+        cannyEdgelList3x3Threshold(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                                   BackInsertable & edgels, GradValue grad_thresh);
+
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class SrcIterator, class SrcAccessor, 
+                  class BackInsertable, class GradValue>
+        void 
+        cannyEdgelList3x3Threshold(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                                   BackInsertable & edgels, double scale, GradValue grad_thresh);
+    }
+    \endcode
+
+    \deprecatedAPI{cannyEdgelList3x3Threshold}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // compute edgels from a gradient image
+        template <class SrcIterator, class SrcAccessor, 
+                  class BackInsertable, class GradValue>
+        void 
+        cannyEdgelList3x3Threshold(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                                   BackInsertable & edgels, GradValue grad_thresh);
+
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class SrcIterator, class SrcAccessor, 
+                  class BackInsertable, class GradValue>
+        void 
+        cannyEdgelList3x3Threshold(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                                   BackInsertable & edgels, double scale, GradValue grad_thresh);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // compute edgels from a gradient image
+        template <class SrcIterator, class SrcAccessor, 
+                  class BackInsertable, class GradValue>
+        void
+        cannyEdgelList3x3Threshold(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                   BackInsertable & edgels, GradValue grad_thresh);
+
+        // compute edgels from a scalar image (determine gradient internally at 'scale')
+        template <class SrcIterator, class SrcAccessor, 
+                  class BackInsertable, class GradValue>
+        void
+        cannyEdgelList3x3Threshold(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                   BackInsertable & edgels, double scale, GradValue grad_thresh);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/edgedetection.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h);
+
+    // create empty edgel list
+    std::vector<vigra::Edgel> edgels;
+    ...
+
+    // find edgels at scale 0.8 whose gradient is at least 4.0
+    cannyEdgelList3x3Threshold(src, edgels, 0.8, 4.0);
+    \endcode
+
+    \deprecatedUsage{cannyEdgelList3x3Threshold}
+    \code
+    vigra::BImage src(w,h);
+
+    // empty edgel list
+    std::vector<vigra::Edgel> edgels;
+    ...
+
+    // find edgels at scale 0.8 whose gradient is at least 4.0
+    vigra::cannyEdgelList3x3Threshold(srcImageRange(src), edgels, 0.8, 4.0);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft;
+    SrcAccessor src_accessor;
+
+    src_accessor(src_upperleft);
+
+    BackInsertable edgels;
+    edgels.push_back(Edgel());
+    \endcode
+    SrcAccessor::value_type must be a type convertible to float
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    \code
+    scale > 0
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void cannyEdgelList3x3Threshold)
+
+template <class SrcIterator, class SrcAccessor, 
+          class BackInsertable, class GradValue>
+void 
+cannyEdgelList3x3Threshold(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                           BackInsertable & edgels, double scale, GradValue grad_thresh)
+{
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    BasicImage<TinyVector<TmpType, 2> > grad(lr-ul);
+    gaussianGradient(srcIterRange(ul, lr, src), destImage(grad), scale);
+
+    cannyEdgelList3x3Threshold(srcImageRange(grad), edgels, grad_thresh);
+}
+
+template <class SrcIterator, class SrcAccessor, 
+          class BackInsertable, class GradValue>
+void 
+cannyEdgelList3x3Threshold(SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                           BackInsertable & edgels, GradValue grad_thresh)
+{
+    UInt8Image edges(lr-ul);
+    cannyEdgeImageFromGradWithThinning(srcIterRange(ul, lr, src), destImage(edges),
+                                       0.0, 1, false);
+
+    // find edgels
+    internalCannyFindEdgels3x3(ul, src, edges, edgels, grad_thresh);
+}
+
+template <class SrcIterator, class SrcAccessor, 
+          class BackInsertable, class GradValue>
+inline void
+cannyEdgelList3x3Threshold(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                           BackInsertable & edgels, double scale, GradValue grad_thresh)
+{
+    cannyEdgelList3x3Threshold(src.first, src.second, src.third, edgels, scale, grad_thresh);
+}
+
+template <class SrcIterator, class SrcAccessor, 
+          class BackInsertable, class GradValue>
+inline void
+cannyEdgelList3x3Threshold(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                           BackInsertable & edgels, GradValue grad_thresh)
+{
+    cannyEdgelList3x3Threshold(src.first, src.second, src.third, edgels, grad_thresh);
+}
+
+template <class T, class S, 
+          class BackInsertable, class GradValue>
+inline void
+cannyEdgelList3x3Threshold(MultiArrayView<2, T, S> const & src,
+                           BackInsertable & edgels, double scale, GradValue grad_thresh)
+{
+    cannyEdgelList3x3Threshold(srcImageRange(src), edgels, scale, grad_thresh);
+}
+
+template <class T, class S, 
+          class BackInsertable, class GradValue>
+inline void
+cannyEdgelList3x3Threshold(MultiArrayView<2, TinyVector<T, 2>, S> const & src,
+                           BackInsertable & edgels,
+                           GradValue grad_thresh)
+{
+    cannyEdgelList3x3Threshold(srcImageRange(src), edgels, grad_thresh);
+}
+
+//@}
+
+/** \page CrackEdgeImage Crack Edge Image
+
+Crack edges are marked <i>between</i> the pixels of an image.
+A Crack Edge Image is an image that represents these edges. In order
+to accommodate the cracks, the Crack Edge Image must be twice as large
+as the original image (precisely (2*w - 1) by (2*h - 1)). A Crack Edge Image
+can easily be derived from a binary image or from the signs of the
+response of a Laplacian filter. Consider the following sketch, where
+<TT>+</TT> encodes the foreground, <TT>-</TT> the background, and
+<TT>*</TT> the resulting crack edges.
+
+    \code
+sign of difference image         insert cracks         resulting CrackEdgeImage
+
+                                   + . - . -              . * . . .
+      + - -                        . . . . .              . * * * .
+      + + -               =>       + . + . -      =>      . . . * .
+      + + +                        . . . . .              . . . * *
+                                   + . + . +              . . . . .
+    \endcode
+
+Starting from the original binary image (left), we insert crack pixels
+to get to the double-sized image (center). Finally, we mark all
+crack pixels whose non-crack neighbors have different signs as
+crack edge points, while all other pixels (crack and non-crack) become
+region pixels.
+
+<b>Requirements on a Crack Edge Image:</b>
+
+<ul>
+    <li>Crack Edge Images have odd width and height.
+    <li>Crack pixels have at least one odd coordinate.
+    <li>Only crack pixels may be marked as edge points.
+    <li>Crack pixels with two odd coordinates must be marked as edge points
+        whenever any of their neighboring crack pixels was marked.
+</ul>
+
+The last two requirements ensure that both edges and regions are 4-connected.
+Thus, 4-connectivity and 8-connectivity yield identical connected
+components in a Crack Edge Image (so called <i>well-composedness</i>).
+This ensures that Crack Edge Images have nice topological properties
+(cf. L. J. Latecki: "Well-Composed Sets", Academic Press, 2000).
+*/
+
+
+} // namespace vigra
+
+#endif // VIGRA_EDGEDETECTION_HXX
diff --git a/include/vigra/eigensystem.hxx b/include/vigra/eigensystem.hxx
new file mode 100644
index 0000000..96fa1e5
--- /dev/null
+++ b/include/vigra/eigensystem.hxx
@@ -0,0 +1,1231 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 2004 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_EIGENSYSTEM_HXX
+#define VIGRA_EIGENSYSTEM_HXX
+
+#include <algorithm>
+#include <complex>
+#include "matrix.hxx"
+#include "array_vector.hxx"
+#include "polynomial.hxx"
+
+namespace vigra
+{
+
+namespace linalg
+{
+
+namespace detail
+{
+
+// code adapted from JAMA
+// a and b will be overwritten
+template <class T, class C1, class C2>
+void
+housholderTridiagonalization(MultiArrayView<2, T, C1> &a, MultiArrayView<2, T, C2> &b)
+{
+    const MultiArrayIndex n = rowCount(a);
+    vigra_precondition(n == columnCount(a),
+        "housholderTridiagonalization(): matrix must be square.");
+    vigra_precondition(n == rowCount(b) && 2 <= columnCount(b),
+        "housholderTridiagonalization(): matrix size mismatch.");
+
+    MultiArrayView<1, T, C2> d = b.bindOuter(0);
+    MultiArrayView<1, T, C2> e = b.bindOuter(1);
+
+    for(MultiArrayIndex j = 0; j < n; ++j)
+    {
+        d(j) = a(n-1, j);
+    }
+
+    // Householder reduction to tridiagonalMatrix form.
+
+    for(int i = n-1; i > 0; --i)
+    {
+        // Scale to avoid under/overflow.
+
+        T scale = 0.0;
+        T h = 0.0;
+        for(int k = 0; k < i; ++k)
+        {
+            scale = scale + abs(d(k));
+        }
+        if(scale == 0.0)
+        {
+            e(i) = d(i-1);
+            for(int j = 0; j < i; ++j)
+            {
+                d(j) = a(i-1, j);
+                a(i, j) = 0.0;
+                a(j, i) = 0.0;
+            }
+        }
+        else
+        {
+            // Generate Householder vector.
+
+            for(int k = 0; k < i; ++k)
+            {
+                d(k) /= scale;
+                h += sq(d(k));
+            }
+            T f = d(i-1);
+            T g = VIGRA_CSTD::sqrt(h);
+            if(f > 0) {
+                g = -g;
+            }
+            e(i) = scale * g;
+            h -= f * g;
+            d(i-1) = f - g;
+            for(int j = 0; j < i; ++j)
+            {
+               e(j) = 0.0;
+            }
+
+            // Apply similarity transformation to remaining columns.
+
+            for(int j = 0; j < i; ++j)
+            {
+               f = d(j);
+               a(j, i) = f;
+               g = e(j) + a(j, j) * f;
+               for(int k = j+1; k <= i-1; ++k)
+               {
+                   g += a(k, j) * d(k);
+                   e(k) += a(k, j) * f;
+               }
+               e(j) = g;
+            }
+            f = 0.0;
+            for(int j = 0; j < i; ++j)
+            {
+                e(j) /= h;
+                f += e(j) * d(j);
+            }
+            T hh = f / (h + h);
+            for(int j = 0; j < i; ++j)
+            {
+                e(j) -= hh * d(j);
+            }
+            for(int j = 0; j < i; ++j)
+            {
+                f = d(j);
+                g = e(j);
+                for(int k = j; k <= i-1; ++k)
+                {
+                    a(k, j) -= (f * e(k) + g * d(k));
+                }
+                d(j) = a(i-1, j);
+                a(i, j) = 0.0;
+            }
+        }
+        d(i) = h;
+    }
+
+    // Accumulate transformations.
+
+    for(MultiArrayIndex i = 0; i < n-1; ++i)
+    {
+        a(n-1, i) = a(i, i);
+        a(i, i) = 1.0;
+        T h = d(i+1);
+        if(h != 0.0)
+        {
+            for(MultiArrayIndex k = 0; k <= i; ++k)
+            {
+                d(k) = a(k, i+1) / h;
+            }
+            for(MultiArrayIndex j = 0; j <= i; ++j)
+            {
+                T g = 0.0;
+                for(MultiArrayIndex k = 0; k <= i; ++k)
+                {
+                    g += a(k, i+1) * a(k, j);
+                }
+                for(MultiArrayIndex k = 0; k <= i; ++k)
+                {
+                    a(k, j) -= g * d(k);
+                }
+            }
+        }
+        for(MultiArrayIndex k = 0; k <= i; ++k)
+        {
+            a(k, i+1) = 0.0;
+        }
+    }
+    for(MultiArrayIndex j = 0; j < n; ++j)
+    {
+        d(j) = a(n-1, j);
+        a(n-1, j) = 0.0;
+    }
+    a(n-1, n-1) = 1.0;
+    e(0) = 0.0;
+}
+
+// code adapted from JAMA
+// de and z will be overwritten
+template <class T, class C1, class C2>
+bool
+tridiagonalMatrixEigensystem(MultiArrayView<2, T, C1> &de, MultiArrayView<2, T, C2> &z)
+{
+    MultiArrayIndex n = rowCount(z);
+    vigra_precondition(n == columnCount(z),
+        "tridiagonalMatrixEigensystem(): matrix must be square.");
+    vigra_precondition(n == rowCount(de) && 2 <= columnCount(de),
+        "tridiagonalMatrixEigensystem(): matrix size mismatch.");
+
+    MultiArrayView<1, T, C2> d = de.bindOuter(0);
+    MultiArrayView<1, T, C2> e = de.bindOuter(1);
+
+    for(MultiArrayIndex i = 1; i < n; i++) {
+       e(i-1) = e(i);
+    }
+    e(n-1) = 0.0;
+
+    T f = 0.0;
+    T tst1 = 0.0;
+    T eps = VIGRA_CSTD::pow(2.0,-52.0);
+    for(MultiArrayIndex l = 0; l < n; ++l)
+    {
+        // Find small subdiagonalMatrix element
+
+        tst1 = std::max(tst1, abs(d(l)) + abs(e(l)));
+        MultiArrayIndex m = l;
+
+        // Original while-loop from Java code
+        while(m < n)
+        {
+            if(abs(e(m)) <= eps*tst1)
+                break;
+            ++m;
+        }
+
+        // If m == l, d(l) is an eigenvalue,
+        // otherwise, iterate.
+
+        if(m > l)
+        {
+            int iter = 0;
+            do
+            {
+                if(++iter > 50)
+                   return false; // too many iterations
+
+                // Compute implicit shift
+
+                T g = d(l);
+                T p = (d(l+1) - g) / (2.0 * e(l));
+                T r = hypot(p,1.0);
+                if(p < 0)
+                {
+                    r = -r;
+                }
+                d(l) = e(l) / (p + r);
+                d(l+1) = e(l) * (p + r);
+                T dl1 = d(l+1);
+                T h = g - d(l);
+                for(MultiArrayIndex i = l+2; i < n; ++i)
+                {
+                   d(i) -= h;
+                }
+                f = f + h;
+
+                // Implicit QL transformation.
+
+                p = d(m);
+                T c = 1.0;
+                T c2 = c;
+                T c3 = c;
+                T el1 = e(l+1);
+                T s = 0.0;
+                T s2 = 0.0;
+                for(int i = m-1; i >= (int)l; --i)
+                {
+                    c3 = c2;
+                    c2 = c;
+                    s2 = s;
+                    g = c * e(i);
+                    h = c * p;
+                    r = hypot(p,e(i));
+                    e(i+1) = s * r;
+                    s = e(i) / r;
+                    c = p / r;
+                    p = c * d(i) - s * g;
+                    d(i+1) = h + s * (c * g + s * d(i));
+
+                    // Accumulate transformation.
+
+                    for(MultiArrayIndex k = 0; k < n; ++k)
+                    {
+                         h = z(k, i+1);
+                         z(k, i+1) = s * z(k, i) + c * h;
+                        z(k, i) = c * z(k, i) - s * h;
+                    }
+                }
+                p = -s * s2 * c3 * el1 * e(l) / dl1;
+                e(l) = s * p;
+                d(l) = c * p;
+
+                // Check for convergence.
+
+            } while(abs(e(l)) > eps*tst1);
+        }
+        d(l) = d(l) + f;
+        e(l) = 0.0;
+    }
+
+    // Sort eigenvalues and corresponding vectors.
+
+    for(MultiArrayIndex i = 0; i < n-1; ++i)
+    {
+        MultiArrayIndex k = i;
+        T p = d(i);
+        for(MultiArrayIndex j = i+1; j < n; ++j)
+        {
+            T p1 = d(j);
+            if(p < p1)
+            {
+                k = j;
+                p = p1;
+            }
+        }
+        if(k != i)
+        {
+            std::swap(d(k), d(i));
+            for(MultiArrayIndex j = 0; j < n; ++j)
+            {
+                std::swap(z(j, i), z(j, k));
+            }
+        }
+    }
+    return true;
+}
+
+// Nonsymmetric reduction to Hessenberg form.
+
+template <class T, class C1, class C2>
+void nonsymmetricHessenbergReduction(MultiArrayView<2, T, C1> & H, MultiArrayView<2, T, C2> & V)
+{
+    //  This is derived from the Algol procedures orthes and ortran,
+    //  by Martin and Wilkinson, Handbook for Auto. Comp.,
+    //  Vol.ii-Linear Algebra, and the corresponding
+    //  Fortran subroutines in EISPACK.
+
+    int n = rowCount(H);
+    int low = 0;
+    int high = n-1;
+    ArrayVector<T> ort(n);
+
+    for(int m = low+1; m <= high-1; ++m)
+    {
+        // Scale column.
+
+        T scale = 0.0;
+        for(int i = m; i <= high; ++i)
+        {
+            scale = scale + abs(H(i, m-1));
+        }
+        if(scale != 0.0)
+        {
+
+            // Compute Householder transformation.
+
+            T h = 0.0;
+            for(int i = high; i >= m; --i)
+            {
+                ort[i] = H(i, m-1)/scale;
+                h += sq(ort[i]);
+            }
+            T g = VIGRA_CSTD::sqrt(h);
+            if(ort[m] > 0)
+            {
+                g = -g;
+            }
+            h = h - ort[m] * g;
+            ort[m] = ort[m] - g;
+
+            // Apply Householder similarity transformation
+            // H = (I-u*u'/h)*H*(I-u*u')/h)
+
+            for(int j = m; j < n; ++j)
+            {
+                T f = 0.0;
+                for(int i = high; i >= m; --i)
+                {
+                    f += ort[i]*H(i, j);
+                }
+                f = f/h;
+                for(int i = m; i <= high; ++i)
+                {
+                    H(i, j) -= f*ort[i];
+                }
+            }
+
+            for(int i = 0; i <= high; ++i)
+            {
+                T f = 0.0;
+                for(int j = high; j >= m; --j)
+                {
+                    f += ort[j]*H(i, j);
+                }
+                f = f/h;
+                for(int j = m; j <= high; ++j)
+                {
+                    H(i, j) -= f*ort[j];
+                }
+            }
+            ort[m] = scale*ort[m];
+            H(m, m-1) = scale*g;
+        }
+    }
+
+    // Accumulate transformations (Algol's ortran).
+
+    for(int i = 0; i < n; ++i)
+    {
+        for(int j = 0; j < n; ++j)
+        {
+            V(i, j) = (i == j ? 1.0 : 0.0);
+        }
+    }
+
+    for(int m = high-1; m >= low+1; --m)
+    {
+        if(H(m, m-1) != 0.0)
+        {
+            for(int i = m+1; i <= high; ++i)
+            {
+                ort[i] = H(i, m-1);
+            }
+            for(int j = m; j <= high; ++j)
+            {
+                T g = 0.0;
+                for(int i = m; i <= high; ++i)
+                {
+                    g += ort[i] * V(i, j);
+                }
+                // Double division avoids possible underflow
+                g = (g / ort[m]) / H(m, m-1);
+                for(int i = m; i <= high; ++i)
+                {
+                    V(i, j) += g * ort[i];
+                }
+            }
+        }
+    }
+}
+
+
+// Complex scalar division.
+
+template <class T>
+void cdiv(T xr, T xi, T yr, T yi, T & cdivr, T & cdivi)
+{
+    T r,d;
+    if(abs(yr) > abs(yi))
+    {
+        r = yi/yr;
+        d = yr + r*yi;
+        cdivr = (xr + r*xi)/d;
+        cdivi = (xi - r*xr)/d;
+    }
+    else
+    {
+        r = yr/yi;
+        d = yi + r*yr;
+        cdivr = (r*xr + xi)/d;
+        cdivi = (r*xi - xr)/d;
+    }
+}
+
+template <class T, class C>
+int hessenbergQrDecompositionHelper(MultiArrayView<2, T, C> & H, int n, int l, double eps,
+             T & p, T & q, T & r, T & s, T & w, T & x, T & y, T & z)
+{
+    int m = n-2;
+    while(m >= l)
+    {
+        z = H(m, m);
+        r = x - z;
+        s = y - z;
+        p = (r * s - w) / H(m+1, m) + H(m, m+1);
+        q = H(m+1, m+1) - z - r - s;
+        r = H(m+2, m+1);
+        s = abs(p) + abs(q) + abs(r);
+        p = p / s;
+        q = q / s;
+        r = r / s;
+        if(m == l)
+        {
+            break;
+        }
+        if(abs(H(m, m-1)) * (abs(q) + abs(r)) <
+            eps * (abs(p) * (abs(H(m-1, m-1)) + abs(z) +
+            abs(H(m+1, m+1)))))
+        {
+                break;
+        }
+        --m;
+    }
+    return m;
+}
+
+
+
+// Nonsymmetric reduction from Hessenberg to real Schur form.
+
+template <class T, class C1, class C2, class C3>
+bool hessenbergQrDecomposition(MultiArrayView<2, T, C1> & H, MultiArrayView<2, T, C2> & V,
+                                     MultiArrayView<2, T, C3> & de)
+{
+
+    //  This is derived from the Algol procedure hqr2,
+    //  by Martin and Wilkinson, Handbook for Auto. Comp.,
+    //  Vol.ii-Linear Algebra, and the corresponding
+    //  Fortran subroutine in EISPACK.
+
+    // Initialize
+    MultiArrayView<1, T, C3> d = de.bindOuter(0);
+    MultiArrayView<1, T, C3> e = de.bindOuter(1);
+
+    int nn = rowCount(H);
+    int n = nn-1;
+    int low = 0;
+    int high = nn-1;
+    T eps = VIGRA_CSTD::pow(2.0, sizeof(T) == sizeof(float)
+                                     ? -23.0
+                                     : -52.0);
+    T exshift = 0.0;
+    T p=0,q=0,r=0,s=0,z=0,t,w,x,y;
+    T norm = vigra::norm(H);
+
+    // Outer loop over eigenvalue index
+    int iter = 0;
+    while(n >= low)
+    {
+
+        // Look for single small sub-diagonal element
+        int l = n;
+        while (l > low)
+        {
+            s = abs(H(l-1, l-1)) + abs(H(l, l));
+            if(s == 0.0)
+            {
+                s = norm;
+            }
+            if(abs(H(l, l-1)) < eps * s)
+            {
+                break;
+            }
+            --l;
+        }
+
+        // Check for convergence
+        // One root found
+        if(l == n)
+        {
+            H(n, n) = H(n, n) + exshift;
+            d(n) = H(n, n);
+            e(n) = 0.0;
+            --n;
+            iter = 0;
+
+        // Two roots found
+
+        }
+        else if(l == n-1)
+        {
+            w = H(n, n-1) * H(n-1, n);
+            p = (H(n-1, n-1) - H(n, n)) / 2.0;
+            q = p * p + w;
+            z = VIGRA_CSTD::sqrt(abs(q));
+            H(n, n) = H(n, n) + exshift;
+            H(n-1, n-1) = H(n-1, n-1) + exshift;
+            x = H(n, n);
+
+            // Real pair
+
+            if(q >= 0)
+            {
+                if(p >= 0)
+                {
+                    z = p + z;
+                }
+                else
+                {
+                    z = p - z;
+                }
+                d(n-1) = x + z;
+                d(n) = d(n-1);
+                if(z != 0.0)
+                {
+                    d(n) = x - w / z;
+                }
+                e(n-1) = 0.0;
+                e(n) = 0.0;
+                x = H(n, n-1);
+                s = abs(x) + abs(z);
+                p = x / s;
+                q = z / s;
+                r = VIGRA_CSTD::sqrt(p * p+q * q);
+                p = p / r;
+                q = q / r;
+
+                // Row modification
+
+                for(int j = n-1; j < nn; ++j)
+                {
+                    z = H(n-1, j);
+                    H(n-1, j) = q * z + p * H(n, j);
+                    H(n, j) = q * H(n, j) - p * z;
+                }
+
+                // Column modification
+
+                for(int i = 0; i <= n; ++i)
+                {
+                    z = H(i, n-1);
+                    H(i, n-1) = q * z + p * H(i, n);
+                    H(i, n) = q * H(i, n) - p * z;
+                }
+
+                // Accumulate transformations
+
+                for(int i = low; i <= high; ++i)
+                {
+                    z = V(i, n-1);
+                    V(i, n-1) = q * z + p * V(i, n);
+                    V(i, n) = q * V(i, n) - p * z;
+                }
+
+            // Complex pair
+
+            }
+            else
+            {
+                d(n-1) = x + p;
+                d(n) = x + p;
+                e(n-1) = z;
+                e(n) = -z;
+            }
+            n = n - 2;
+            iter = 0;
+
+        // No convergence yet
+
+        }
+        else
+        {
+
+            // Form shift
+
+            x = H(n, n);
+            y = 0.0;
+            w = 0.0;
+            if(l < n)
+            {
+                y = H(n-1, n-1);
+                w = H(n, n-1) * H(n-1, n);
+            }
+
+            // Wilkinson's original ad hoc shift
+
+            if(iter == 10)
+            {
+                exshift += x;
+                for(int i = low; i <= n; ++i)
+                {
+                    H(i, i) -= x;
+                }
+                s = abs(H(n, n-1)) + abs(H(n-1, n-2));
+                x = y = 0.75 * s;
+                w = -0.4375 * s * s;
+            }
+
+            // MATLAB's new ad hoc shift
+
+            if(iter == 30)
+            {
+                 s = (y - x) / 2.0;
+                 s = s * s + w;
+                 if(s > 0)
+                 {
+                      s = VIGRA_CSTD::sqrt(s);
+                      if(y < x)
+                      {
+                          s = -s;
+                      }
+                      s = x - w / ((y - x) / 2.0 + s);
+                      for(int i = low; i <= n; ++i)
+                      {
+                          H(i, i) -= s;
+                      }
+                      exshift += s;
+                      x = y = w = 0.964;
+                 }
+            }
+
+            iter = iter + 1;
+            if(iter > 60)
+                return false;
+
+            // Look for two consecutive small sub-diagonal elements
+            int m = hessenbergQrDecompositionHelper(H, n, l, eps, p, q, r, s, w, x, y, z);
+            for(int i = m+2; i <= n; ++i)
+            {
+                H(i, i-2) = 0.0;
+                if(i > m+2)
+                {
+                    H(i, i-3) = 0.0;
+                }
+            }
+
+            // Double QR step involving rows l:n and columns m:n
+
+            for(int k = m; k <= n-1; ++k)
+            {
+                int notlast = (k != n-1);
+                if(k != m) {
+                    p = H(k, k-1);
+                    q = H(k+1, k-1);
+                    r = (notlast ? H(k+2, k-1) : 0.0);
+                    x = abs(p) + abs(q) + abs(r);
+                    if(x != 0.0)
+                    {
+                        p = p / x;
+                        q = q / x;
+                        r = r / x;
+                    }
+                }
+                if(x == 0.0)
+                {
+                    break;
+                }
+                s = VIGRA_CSTD::sqrt(p * p + q * q + r * r);
+                if(p < 0)
+                {
+                    s = -s;
+                }
+                if(s != 0)
+                {
+                    if(k != m)
+                    {
+                        H(k, k-1) = -s * x;
+                    }
+                    else if(l != m)
+                    {
+                        H(k, k-1) = -H(k, k-1);
+                    }
+                    p = p + s;
+                    x = p / s;
+                    y = q / s;
+                    z = r / s;
+                    q = q / p;
+                    r = r / p;
+
+                    // Row modification
+
+                    for(int j = k; j < nn; ++j)
+                    {
+                        p = H(k, j) + q * H(k+1, j);
+                        if(notlast)
+                        {
+                            p = p + r * H(k+2, j);
+                            H(k+2, j) = H(k+2, j) - p * z;
+                        }
+                        H(k, j) = H(k, j) - p * x;
+                        H(k+1, j) = H(k+1, j) - p * y;
+                    }
+
+                    // Column modification
+
+                    for(int i = 0; i <= std::min(n,k+3); ++i)
+                    {
+                        p = x * H(i, k) + y * H(i, k+1);
+                        if(notlast)
+                        {
+                            p = p + z * H(i, k+2);
+                            H(i, k+2) = H(i, k+2) - p * r;
+                        }
+                        H(i, k) = H(i, k) - p;
+                        H(i, k+1) = H(i, k+1) - p * q;
+                    }
+
+                    // Accumulate transformations
+
+                    for(int i = low; i <= high; ++i)
+                    {
+                        p = x * V(i, k) + y * V(i, k+1);
+                        if(notlast)
+                        {
+                            p = p + z * V(i, k+2);
+                            V(i, k+2) = V(i, k+2) - p * r;
+                        }
+                        V(i, k) = V(i, k) - p;
+                        V(i, k+1) = V(i, k+1) - p * q;
+                    }
+                }  // (s != 0)
+            }  // k loop
+        }  // check convergence
+    }  // while (n >= low)
+
+    // Backsubstitute to find vectors of upper triangular form
+
+    if(norm == 0.0)
+    {
+        return false;
+    }
+
+    for(n = nn-1; n >= 0; --n)
+    {
+        p = d(n);
+        q = e(n);
+
+        // Real vector
+
+        if(q == 0)
+        {
+            int l = n;
+            H(n, n) = 1.0;
+            for(int i = n-1; i >= 0; --i)
+            {
+                w = H(i, i) - p;
+                r = 0.0;
+                for(int j = l; j <= n; ++j)
+                {
+                    r = r + H(i, j) * H(j, n);
+                }
+                if(e(i) < 0.0)
+                {
+                    z = w;
+                    s = r;
+                }
+                else
+                {
+                    l = i;
+                    if(e(i) == 0.0)
+                    {
+                        if(w != 0.0)
+                        {
+                            H(i, n) = -r / w;
+                        }
+                        else
+                        {
+                            H(i, n) = -r / (eps * norm);
+                        }
+
+                    // Solve real equations
+
+                    }
+                    else
+                    {
+                        x = H(i, i+1);
+                        y = H(i+1, i);
+                        q = (d(i) - p) * (d(i) - p) + e(i) * e(i);
+                        t = (x * s - z * r) / q;
+                        H(i, n) = t;
+                        if(abs(x) > abs(z))
+                        {
+                            H(i+1, n) = (-r - w * t) / x;
+                        }
+                        else
+                        {
+                            H(i+1, n) = (-s - y * t) / z;
+                        }
+                    }
+
+                    // Overflow control
+
+                    t = abs(H(i, n));
+                    if((eps * t) * t > 1)
+                    {
+                        for(int j = i; j <= n; ++j)
+                        {
+                            H(j, n) = H(j, n) / t;
+                        }
+                    }
+                }
+            }
+
+        // Complex vector
+
+        }
+        else if(q < 0)
+        {
+            int l = n-1;
+
+            // Last vector component imaginary so matrix is triangular
+
+            if(abs(H(n, n-1)) > abs(H(n-1, n)))
+            {
+                H(n-1, n-1) = q / H(n, n-1);
+                H(n-1, n) = -(H(n, n) - p) / H(n, n-1);
+            }
+            else
+            {
+                cdiv(0.0,-H(n-1, n),H(n-1, n-1)-p,q, H(n-1, n-1), H(n-1, n));
+            }
+            H(n, n-1) = 0.0;
+            H(n, n) = 1.0;
+            for(int i = n-2; i >= 0; --i)
+            {
+                T ra,sa,vr,vi;
+                ra = 0.0;
+                sa = 0.0;
+                for(int j = l; j <= n; ++j)
+                {
+                    ra = ra + H(j, n-1) * H(i, j);
+                    sa = sa + H(j, n) * H(i, j);
+                }
+                w = H(i, i) - p;
+
+                if(e(i) < 0.0)
+                {
+                    z = w;
+                    r = ra;
+                    s = sa;
+                }
+                else
+                {
+                    l = i;
+                    if(e(i) == 0)
+                    {
+                        cdiv(-ra,-sa,w,q, H(i, n-1), H(i, n));
+                    }
+                    else
+                    {
+                        // Solve complex equations
+
+                        x = H(i, i+1);
+                        y = H(i+1, i);
+                        vr = (d(i) - p) * (d(i) - p) + e(i) * e(i) - q * q;
+                        vi = (d(i) - p) * 2.0 * q;
+                        if((vr == 0.0) && (vi == 0.0))
+                        {
+                            vr = eps * norm * (abs(w) + abs(q) +
+                            abs(x) + abs(y) + abs(z));
+                        }
+                        cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi, H(i, n-1), H(i, n));
+                        if(abs(x) > (abs(z) + abs(q)))
+                        {
+                            H(i+1, n-1) = (-ra - w * H(i, n-1) + q * H(i, n)) / x;
+                            H(i+1, n) = (-sa - w * H(i, n) - q * H(i, n-1)) / x;
+                        }
+                        else
+                        {
+                            cdiv(-r-y*H(i, n-1),-s-y*H(i, n),z,q, H(i+1, n-1), H(i+1, n));
+                        }
+                    }
+
+                    // Overflow control
+
+                    t = std::max(abs(H(i, n-1)),abs(H(i, n)));
+                    if((eps * t) * t > 1)
+                    {
+                        for(int j = i; j <= n; ++j)
+                        {
+                            H(j, n-1) = H(j, n-1) / t;
+                            H(j, n) = H(j, n) / t;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // Back transformation to get eigenvectors of original matrix
+
+    for(int j = nn-1; j >= low; --j)
+    {
+        for(int i = low; i <= high; ++i)
+        {
+            z = 0.0;
+            for(int k = low; k <= std::min(j,high); ++k)
+            {
+                z = z + V(i, k) * H(k, j);
+            }
+            V(i, j) = z;
+        }
+    }
+    return true;
+}
+
+} // namespace detail
+
+/** \addtogroup MatrixAlgebra
+*/
+//@{
+    /** Compute the eigensystem of a symmetric matrix.
+
+        \a a is a real symmetric matrix, \a ew is a single-column matrix
+        holding the eigenvalues, and \a ev is a matrix of the same size as
+        \a a whose columns are the corresponding eigenvectors. Eigenvalues
+        will be sorted from largest to smallest magnitude.
+        The algorithm returns <tt>false</tt> when it doesn't
+        converge. It can be applied in-place, i.e. <tt>&a == &ev</tt> is allowed.
+        The code of this function was adapted from JAMA.
+
+        <b>\#include</b> \<vigra/eigensystem.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+bool
+symmetricEigensystem(MultiArrayView<2, T, C1> const & a,
+            MultiArrayView<2, T, C2> & ew, MultiArrayView<2, T, C3> & ev)
+{
+    vigra_precondition(isSymmetric(a),
+        "symmetricEigensystem(): symmetric input matrix required.");
+    const MultiArrayIndex acols = columnCount(a);
+    vigra_precondition(1 == columnCount(ew) && acols == rowCount(ew) &&
+                       acols == columnCount(ev) && acols == rowCount(ev),
+        "symmetricEigensystem(): matrix shape mismatch.");
+
+    ev.copy(a); // does nothing if &ev == &a
+    Matrix<T> de(acols, 2);
+    detail::housholderTridiagonalization(ev, de);
+    if(!detail::tridiagonalMatrixEigensystem(de, ev))
+        return false;
+
+    ew.copy(columnVector(de, 0));
+    return true;
+}
+
+namespace detail{
+template <class T, class C1, class C2, class C3>
+bool
+symmetricEigensystem2x2(MultiArrayView<2, T, C1> const & a,
+            MultiArrayView<2, T, C2> & ew, MultiArrayView<2, T, C3> & ev)
+{
+    vigra_precondition(isSymmetric(a),
+        "symmetricEigensystem(): symmetric input matrix required.");
+ 
+    double evec[2]={0,0};
+      
+      /* Eigenvectors*/ 
+      if (a(0,1)==0){
+        if (fabs(a(1,1))>fabs(a(0,0))){
+          evec[0]=0.;
+          evec[1]=1.;
+          ew(0,0)=a(1,1);
+          ew(1,0)=a(0,0);
+         }
+        else if(fabs(a(0,0))>fabs(a(1,1))) {
+          evec[0]=1.;
+          evec[1]=0.;
+          ew(0,0)=a(0,0);
+          ew(1,0)=a(1,1);
+        }
+        else {
+          evec[0]=.5* M_SQRT2;
+          evec[1]=.5* M_SQRT2;
+          ew(0,0)=a(0,0);
+          ew(1,0)=a(1,1);
+        }
+      }
+      else{ 
+        double temp=a(1,1)-a(0,0);
+        
+        double coherence=sqrt(temp*temp+4*a(0,1)*a(0,1));
+        evec[0]=2*a(0,1);
+        evec[1]=temp+coherence;
+        temp=std::sqrt(evec[0]*evec[0]+evec[1]*evec[1]);
+        if (temp==0){
+          evec[0]=.5* M_SQRT2;
+          evec[1]=.5* M_SQRT2;
+          ew(0,0)=1.;
+          ew(1,0)=1.;
+        }
+        else{
+          evec[0]/=temp;
+          evec[1]/=temp;
+          
+          /* Eigenvalues */
+          ew(0,0)=.5*(a(0,0)+a(1,1)+coherence);
+          ew(1,0)=.5*(a(0,0)+a(1,1)-coherence);
+        }
+      }
+      ev(0,0)= evec[0];
+      ev(1,0)= evec[1];
+      ev(0,1)=-evec[1];
+      ev(1,1)= evec[0];
+      return true;
+}
+} // closing namespace detail 
+
+    /** Compute the eigensystem of a square, but
+        not necessarily symmetric matrix.
+
+        \a a is a real square matrix, \a ew is a single-column matrix
+        holding the possibly complex eigenvalues, and \a ev is a matrix of
+        the same size as \a a whose columns are the corresponding eigenvectors.
+        Eigenvalues will be sorted from largest to smallest magnitude.
+        The algorithm returns <tt>false</tt> when it doesn't
+        converge. It can be applied in-place, i.e. <tt>&a == &ev</tt> is allowed.
+        The code of this function was adapted from JAMA.
+
+        <b>\#include</b> \<vigra/eigensystem.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+bool
+nonsymmetricEigensystem(MultiArrayView<2, T, C1> const & a,
+         MultiArrayView<2, std::complex<T>, C2> & ew, MultiArrayView<2, T, C3> & ev)
+{
+    const MultiArrayIndex acols = columnCount(a);
+    vigra_precondition(acols == rowCount(a),
+        "nonsymmetricEigensystem(): square input matrix required.");
+    vigra_precondition(1 == columnCount(ew) && acols == rowCount(ew) &&
+                       acols == columnCount(ev) && acols == rowCount(ev),
+        "nonsymmetricEigensystem(): matrix shape mismatch.");
+
+    Matrix<T> H(a);
+    Matrix<T> de(acols, 2);
+    detail::nonsymmetricHessenbergReduction(H, ev);
+    if(!detail::hessenbergQrDecomposition(H, ev, de))
+        return false;
+
+    for(MultiArrayIndex i = 0; i < acols; ++i)
+    {
+        ew(i,0) = std::complex<T>(de(i, 0), de(i, 1));
+    }
+    return true;
+}
+
+    /** Compute the roots of a polynomial using the eigenvalue method.
+
+        \a poly is a real polynomial (compatible to \ref vigra::PolynomialView),
+        and \a roots a complex valued vector (compatible to <tt>std::vector</tt>
+        with a <tt>value_type</tt> compatible to the type <tt>POLYNOMIAL::Complex</tt>) to which
+        the roots are appended. The function calls \ref nonsymmetricEigensystem() with the standard
+        companion matrix yielding the roots as eigenvalues. It returns <tt>false</tt> if
+        it fails to converge.
+
+        <b>\#include</b> \<vigra/eigensystem.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+
+        \see polynomialRoots(), vigra::Polynomial
+     */
+template <class POLYNOMIAL, class VECTOR>
+bool polynomialRootsEigenvalueMethod(POLYNOMIAL const & poly, VECTOR & roots, bool polishRoots)
+{
+    typedef typename POLYNOMIAL::value_type T;
+    typedef typename POLYNOMIAL::Real    Real;
+    typedef typename POLYNOMIAL::Complex Complex;
+    typedef Matrix<T> TMatrix;
+    typedef Matrix<Complex> ComplexMatrix;
+
+    int const degree = poly.order();
+    double const eps = poly.epsilon();
+
+    TMatrix inMatrix(degree, degree);
+    for(int i = 0; i < degree; ++i)
+        inMatrix(0, i) = -poly[degree - i - 1] / poly[degree];
+    for(int i = 0; i < degree - 1; ++i)
+        inMatrix(i + 1, i) = NumericTraits<T>::one();
+    ComplexMatrix ew(degree, 1);
+    TMatrix ev(degree, degree);
+    bool success = nonsymmetricEigensystem(inMatrix, ew, ev);
+    if(!success)
+        return false;
+    for(int i = 0; i < degree; ++i)
+    {
+        if(polishRoots)
+            vigra::detail::laguerre1Root(poly, ew(i,0), 1);
+        roots.push_back(vigra::detail::deleteBelowEpsilon(ew(i,0), eps));
+    }
+    std::sort(roots.begin(), roots.end(), vigra::detail::PolynomialRootCompare<Real>(eps));
+    return true;
+}
+
+template <class POLYNOMIAL, class VECTOR>
+bool polynomialRootsEigenvalueMethod(POLYNOMIAL const & poly, VECTOR & roots)
+{
+    return polynomialRootsEigenvalueMethod(poly, roots, true);
+}
+
+    /** Compute the real roots of a real polynomial using the eigenvalue method.
+
+        \a poly is a real polynomial (compatible to \ref vigra::PolynomialView),
+        and \a roots a real valued vector (compatible to <tt>std::vector</tt>
+        with a <tt>value_type</tt> compatible to the type <tt>POLYNOMIAL::Real</tt>) to which
+        the roots are appended. The function calls \ref polynomialRootsEigenvalueMethod() and
+        throws away all complex roots. It returns <tt>false</tt> if it fails to converge.
+        The parameter <tt>polishRoots</tt> is ignored (it is only here for syntax compatibility 
+        with polynomialRealRoots()).
+        
+
+        <b>\#include</b> \<vigra/eigensystem.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+
+        \see polynomialRealRoots(), vigra::Polynomial
+     */
+template <class POLYNOMIAL, class VECTOR>
+bool polynomialRealRootsEigenvalueMethod(POLYNOMIAL const & p, VECTOR & roots, bool /* polishRoots */)
+{
+    typedef typename NumericTraits<typename VECTOR::value_type>::ComplexPromote Complex;
+    ArrayVector<Complex> croots;
+    if(!polynomialRootsEigenvalueMethod(p, croots))
+        return false;
+    for(unsigned int i = 0; i < croots.size(); ++i)
+        if(croots[i].imag() == 0.0)
+            roots.push_back(croots[i].real());
+    return true;
+}
+
+template <class POLYNOMIAL, class VECTOR>
+bool polynomialRealRootsEigenvalueMethod(POLYNOMIAL const & p, VECTOR & roots)
+{
+    return polynomialRealRootsEigenvalueMethod(p, roots, true);
+}
+
+
+//@}
+
+} // namespace linalg
+
+using linalg::symmetricEigensystem;
+using linalg::nonsymmetricEigensystem;
+using linalg::polynomialRootsEigenvalueMethod;
+using linalg::polynomialRealRootsEigenvalueMethod;
+
+} // namespace vigra
+
+#endif // VIGRA_EIGENSYSTEM_HXX
diff --git a/include/vigra/error.hxx b/include/vigra/error.hxx
new file mode 100644
index 0000000..39030dc
--- /dev/null
+++ b/include/vigra/error.hxx
@@ -0,0 +1,337 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_ERROR_HXX
+#define VIGRA_ERROR_HXX
+
+#include <stdexcept>
+#include <sstream>
+#include <string>
+#include "config.hxx"
+          
+/** \page ErrorReporting Error Reporting
+    Exceptions and assertions provided by VIGRA
+
+    <b>\#include</b> \<vigra/error.hxx\>
+    
+    VIGRA defines the following exception classes:
+    
+    \code
+    namespace vigra {
+        class ContractViolation : public std::exception;
+        class PreconditionViolation : public ContractViolation;
+        class PostconditionViolation : public ContractViolation;
+        class InvariantViolation : public ContractViolation;
+    }
+    \endcode
+    
+    The following associated macros throw the corresponding exception if 
+    their PREDICATE evaluates to '<TT>false</TT>':
+    
+    \code
+    vigra_precondition(PREDICATE, MESSAGE);
+    vigra_postcondition(PREDICATE, MESSAGE);
+    vigra_invariant(PREDICATE, MESSAGE);
+    \endcode
+    
+    The MESSAGE is passed to the exception and can be retrieved via
+    the overloaded member function '<TT>exception.what()</TT>'. If the compiler
+    flag '<TT>NDEBUG</TT>' is <em>not</em> defined, the file name and line number of 
+    the error are automatically included in the message. The macro
+    
+    \code
+    vigra_assert(PREDICATE, MESSAGE);
+    \endcode
+    
+    is identical to <tt>vigra_precondition()</tt> except that it is completely removed
+    when '<TT>NDEBUG</TT>' is defined. This is useful for test that are only needed during 
+    debugging, such as array index bound checking. The following macro
+    
+    \code
+    vigra_fail(MESSAGE);
+    \endcode
+    
+    unconditionally throws a '<TT>std::runtime_error</TT>' constructed from the message 
+    (along with file name and line number, if NDEBUG is not set).
+    
+    <b> Usage:</b>
+    
+    Include-File:
+    \<vigra/error.hxx\>
+    <p>
+    Namespace: vigra (except for the macros, of course)
+    
+    \code
+    int main(int argc, char ** argv)
+    {
+        try
+        {
+            const char* input_file_name = argv[1];
+
+            // read input image
+            vigra::ImageImportInfo info(input_file_name);
+
+            // fail if input image is not grayscale
+            vigra_precondition(info.isGrayscale(), "Input image must be grayscale");
+
+            ...// process image
+        }
+        catch (std::exception & e)
+        {
+            std::cerr << e.what() << std::endl; // print message
+            return 1;
+        }
+
+        return 0;
+    }
+    \endcode
+**/
+
+namespace vigra {
+
+class ContractViolation : public StdException
+{
+  public:
+    ContractViolation()
+    {}
+    
+    ContractViolation(char const * prefix, char const * message, 
+                      char const * file, int line)
+    {
+        (*this) << "\n" << prefix << "\n" << message << "\n("
+                 << file << ":" << line << ")\n";
+    }
+    
+    ContractViolation(char const * prefix, char const * message)
+    {
+        (*this) << "\n" << prefix << "\n" << message << "\n";
+    }
+    
+    ~ContractViolation() throw()
+    {}
+    
+    template<class T>
+    ContractViolation & operator<<(T const & data)
+    {
+        std::ostringstream what;
+        what << data;
+        what_ += what.str();
+        return *this;
+    }
+
+    virtual const char * what() const throw()
+    {
+        try
+        {
+            return what_.c_str();
+        }
+        catch(...)
+        {
+            return "vigra::ContractViolation: error message was lost, sorry.";
+        }
+    }
+  
+  private:
+    std::string what_;
+};
+
+class PreconditionViolation : public ContractViolation
+{
+  public:
+    PreconditionViolation(char const * message, const char * file, int line)
+    : ContractViolation("Precondition violation!", message, file, line)
+    {}
+    
+    PreconditionViolation(char const * message)
+    : ContractViolation("Precondition violation!", message)
+    {}
+};
+
+class PostconditionViolation : public ContractViolation
+{
+  public:
+    PostconditionViolation(char const * message, const char * file, int line)
+    : ContractViolation("Postcondition violation!", message, file, line)
+    {}
+    
+    PostconditionViolation(char const * message)
+    : ContractViolation("Postcondition violation!", message)
+    {}
+};
+
+class InvariantViolation : public ContractViolation
+{
+  public:
+    InvariantViolation(char const * message, const char * file, int line)
+    : ContractViolation("Invariant violation!", message, file, line)
+    {}
+    
+    InvariantViolation(char const * message)
+    : ContractViolation("Invariant violation!", message)
+    {}
+};
+
+//#ifndef NDEBUG
+
+#if 1
+
+inline
+void throw_invariant_error(bool predicate, char const * message, char const * file, int line)
+{
+    if(!predicate)
+       throw vigra::InvariantViolation(message, file, line); 
+}
+
+inline
+void throw_invariant_error(bool predicate, std::string message, char const * file, int line)
+{
+    if(!predicate)
+       throw vigra::InvariantViolation(message.c_str(), file, line); 
+}
+
+inline
+void throw_precondition_error(bool predicate, char const * message, char const * file, int line)
+{
+    if(!predicate)
+       throw vigra::PreconditionViolation(message, file, line); 
+}
+
+inline
+void throw_precondition_error(bool predicate, std::string message, char const * file, int line)
+{
+    if(!predicate)
+       throw vigra::PreconditionViolation(message.c_str(), file, line); 
+}
+
+inline
+void throw_postcondition_error(bool predicate, char const * message, char const * file, int line)
+{
+    if(!predicate)
+       throw vigra::PostconditionViolation(message, file, line); 
+}
+
+inline
+void throw_postcondition_error(bool predicate, std::string message, char const * file, int line)
+{
+    if(!predicate)
+       throw vigra::PostconditionViolation(message.c_str(), file, line); 
+}
+
+inline
+void throw_runtime_error(char const * message, char const * file, int line)
+{
+    std::ostringstream what;
+    what << "\n" << message << "\n(" << file << ":" << line << ")\n";
+    throw std::runtime_error(what.str()); 
+}
+
+inline
+void throw_runtime_error(std::string message, char const * file, int line)
+{
+    std::ostringstream what;
+    what << "\n" << message << "\n(" << file << ":" << line << ")\n";
+    throw std::runtime_error(what.str()); 
+}
+
+#define vigra_precondition(PREDICATE, MESSAGE) vigra::throw_precondition_error((PREDICATE), MESSAGE, __FILE__, __LINE__)
+
+#define vigra_assert(PREDICATE, MESSAGE) vigra_precondition(PREDICATE, MESSAGE)
+
+#define vigra_postcondition(PREDICATE, MESSAGE) vigra::throw_postcondition_error((PREDICATE), MESSAGE, __FILE__, __LINE__)
+
+#define vigra_invariant(PREDICATE, MESSAGE) vigra::throw_invariant_error((PREDICATE), MESSAGE, __FILE__, __LINE__)
+            
+#define vigra_fail(MESSAGE) vigra::throw_runtime_error(MESSAGE, __FILE__, __LINE__)
+
+#else // NDEBUG
+
+inline
+void throw_invariant_error(bool predicate, char const * message)
+{
+    if(!predicate)
+       throw vigra::InvariantViolation(message); 
+}
+
+inline
+void throw_precondition_error(bool predicate, char const * message)
+{
+    if(!predicate)
+       throw vigra::PreconditionViolation(message); 
+}
+
+inline
+void throw_postcondition_error(bool predicate, char const * message)
+{
+    if(!predicate)
+       throw vigra::PostconditionViolation(message); 
+}
+
+inline
+void throw_invariant_error(bool predicate, std::string message)
+{
+    if(!predicate)
+       throw vigra::InvariantViolation(message.c_str()); 
+}
+
+inline
+void throw_precondition_error(bool predicate, std::string message)
+{
+    if(!predicate)
+       throw vigra::PreconditionViolation(message.c_str()); 
+}
+
+inline
+void throw_postcondition_error(bool predicate, std::string message)
+{
+    if(!predicate)
+       throw vigra::PostconditionViolation(message.c_str()); 
+}
+
+#define vigra_precondition(PREDICATE, MESSAGE) vigra::throw_precondition_error((PREDICATE), MESSAGE)
+
+#define vigra_assert(PREDICATE, MESSAGE)
+
+#define vigra_postcondition(PREDICATE, MESSAGE) vigra::throw_postcondition_error((PREDICATE), MESSAGE)
+
+#define vigra_invariant(PREDICATE, MESSAGE) vigra::throw_invariant_error((PREDICATE), MESSAGE)
+            
+#define vigra_fail(MESSAGE) throw std::runtime_error(MESSAGE)
+
+#endif // NDEBUG
+
+} // namespace vigra
+
+#endif // VIGRA_ERROR_HXX
diff --git a/include/vigra/fftw.hxx b/include/vigra/fftw.hxx
new file mode 100644
index 0000000..b65fdef
--- /dev/null
+++ b/include/vigra/fftw.hxx
@@ -0,0 +1,1209 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_FFTW_HXX
+#define VIGRA_FFTW_HXX
+
+#include <cmath>
+#include <functional>
+#include "stdimage.hxx"
+#include "copyimage.hxx"
+#include "transformimage.hxx"
+#include "combineimages.hxx"
+#include "numerictraits.hxx"
+#include "imagecontainer.hxx"
+#include <fftw.h>
+
+namespace vigra {
+
+/********************************************************/
+/*                                                      */
+/*                    FFTWComplex                       */
+/*                                                      */
+/********************************************************/
+
+/* documentation: see fftw3.hxx
+*/
+class FFTWComplex
+: public fftw_complex
+{
+  public:
+        /** The complex' component type, as defined in '<TT>fftw.h</TT>'
+        */
+    typedef fftw_real value_type;
+
+        /** reference type (result of operator[])
+        */
+    typedef fftw_real & reference;
+
+        /** const reference type (result of operator[] const)
+        */
+    typedef fftw_real const & const_reference;
+
+        /** iterator type (result of begin() )
+        */
+    typedef fftw_real * iterator;
+
+        /** const iterator type (result of begin() const)
+        */
+    typedef fftw_real const * const_iterator;
+
+        /** The norm type (result of magnitude())
+        */
+    typedef fftw_real NormType;
+
+        /** The squared norm type (result of squaredMagnitde())
+        */
+    typedef fftw_real SquaredNormType;
+
+        /** Construct from real and imaginary part.
+            Default: 0.
+        */
+    FFTWComplex(value_type const & ire = 0.0, value_type const & iim = 0.0)
+    {
+        re = ire;
+        im = iim;
+    }
+
+        /** Copy constructor.
+        */
+    FFTWComplex(FFTWComplex const & o)
+    : fftw_complex(o)
+    {}
+
+        /** Construct from plain <TT>fftw_complex</TT>.
+        */
+    FFTWComplex(fftw_complex const & o)
+    : fftw_complex(o)
+    {}
+
+        /** Construct from TinyVector.
+        */
+    template <class T>
+    FFTWComplex(TinyVector<T, 2> const & o)
+    {
+        re = o[0];
+        im = o[1];
+    }
+
+        /** Assignment.
+        */
+    FFTWComplex& operator=(FFTWComplex const & o)
+    {
+        re = o.re;
+        im = o.im;
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    FFTWComplex& operator=(fftw_complex const & o)
+    {
+        re = o.re;
+        im = o.im;
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    FFTWComplex& operator=(fftw_real const & o)
+    {
+        re = o;
+        im = 0.0;
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    template <class T>
+    FFTWComplex& operator=(TinyVector<T, 2> const & o)
+    {
+        re = o[0];
+        im = o[1];
+        return *this;
+    }
+
+        /** Unary negation.
+        */
+    FFTWComplex operator-() const
+        { return FFTWComplex(-re, -im); }
+
+        /** Squared magnitude x*conj(x)
+        */
+    SquaredNormType squaredMagnitude() const
+        { return c_re(*this)*c_re(*this)+c_im(*this)*c_im(*this); }
+
+        /** Magnitude (length of radius vector).
+        */
+    NormType magnitude() const
+        { return VIGRA_CSTD::sqrt(squaredMagnitude()); }
+
+        /** Phase angle.
+        */
+    value_type phase() const
+        { return VIGRA_CSTD::atan2(c_im(*this),c_re(*this)); }
+
+        /** Access components as if number were a vector.
+        */
+    reference operator[](int i)
+        { return (&re)[i]; }
+
+        /** Read components as if number were a vector.
+        */
+    const_reference operator[](int i) const
+        { return (&re)[i]; }
+
+        /** Length of complex number (always 2).
+        */
+    int size() const
+        { return 2; }
+
+    iterator begin()
+        { return &re; }
+
+    iterator end()
+        { return &re + 2; }
+
+    const_iterator begin() const
+        { return &re; }
+
+    const_iterator end() const
+        { return &re + 2; }
+};
+
+/********************************************************/
+/*                                                      */
+/*                    FFTWComplex Traits                */
+/*                                                      */
+/********************************************************/
+
+/* documentation: see fftw3.hxx
+*/
+template<>
+struct NumericTraits<fftw_complex>
+{
+    typedef fftw_complex Type;
+    typedef fftw_complex Promote;
+    typedef fftw_complex RealPromote;
+    typedef fftw_complex ComplexPromote;
+    typedef fftw_real    ValueType;
+
+    typedef VigraFalseType isIntegral;
+    typedef VigraFalseType isScalar;
+    typedef NumericTraits<fftw_real>::isSigned isSigned;
+    typedef VigraFalseType isOrdered;
+    typedef VigraTrueType  isComplex;
+
+    static FFTWComplex zero() { return FFTWComplex(0.0, 0.0); }
+    static FFTWComplex one() { return FFTWComplex(1.0, 0.0); }
+    static FFTWComplex nonZero() { return one(); }
+
+    static const Promote & toPromote(const Type & v) { return v; }
+    static const RealPromote & toRealPromote(const Type & v) { return v; }
+    static const Type & fromPromote(const Promote & v) { return v; }
+    static const Type & fromRealPromote(const RealPromote & v) { return v; }
+};
+
+template<>
+struct NumericTraits<FFTWComplex>
+: public NumericTraits<fftw_complex>
+{
+    typedef FFTWComplex Type;
+    typedef FFTWComplex Promote;
+    typedef FFTWComplex RealPromote;
+    typedef FFTWComplex ComplexPromote;
+    typedef fftw_real   ValueType;
+
+    typedef VigraFalseType isIntegral;
+    typedef VigraFalseType isScalar;
+    typedef NumericTraits<fftw_real>::isSigned isSigned;
+    typedef VigraFalseType isOrdered;
+    typedef VigraTrueType  isComplex;
+};
+
+template<>
+struct NormTraits<fftw_complex>
+{
+    typedef fftw_complex Type;
+    typedef fftw_real    SquaredNormType;
+    typedef fftw_real    NormType;
+};
+
+template<>
+struct NormTraits<FFTWComplex>
+{
+    typedef FFTWComplex Type;
+    typedef fftw_real   SquaredNormType;
+    typedef fftw_real   NormType;
+};
+
+
+template <>
+struct PromoteTraits<fftw_complex, fftw_complex>
+{
+    typedef fftw_complex Promote;
+};
+
+template <>
+struct PromoteTraits<fftw_complex, double>
+{
+    typedef fftw_complex Promote;
+};
+
+template <>
+struct PromoteTraits<double, fftw_complex>
+{
+    typedef fftw_complex Promote;
+};
+
+template <>
+struct PromoteTraits<FFTWComplex, FFTWComplex>
+{
+    typedef FFTWComplex Promote;
+};
+
+template <>
+struct PromoteTraits<FFTWComplex, double>
+{
+    typedef FFTWComplex Promote;
+};
+
+template <>
+struct PromoteTraits<double, FFTWComplex>
+{
+    typedef FFTWComplex Promote;
+};
+
+
+/********************************************************/
+/*                                                      */
+/*                    FFTWComplex Operations            */
+/*                                                      */
+/********************************************************/
+
+/* documentation: see fftw3.hxx
+*/
+inline bool operator ==(FFTWComplex const &a, const FFTWComplex &b) {
+    return c_re(a) == c_re(b) && c_im(a) == c_im(b);
+}
+
+inline bool operator !=(FFTWComplex const &a, const FFTWComplex &b) {
+    return c_re(a) != c_re(b) || c_im(a) != c_im(b);
+}
+
+inline FFTWComplex &operator +=(FFTWComplex &a, const FFTWComplex &b) {
+    c_re(a) += c_re(b);
+    c_im(a) += c_im(b);
+    return a;
+}
+
+inline FFTWComplex &operator -=(FFTWComplex &a, const FFTWComplex &b) {
+    c_re(a) -= c_re(b);
+    c_im(a) -= c_im(b);
+    return a;
+}
+
+inline FFTWComplex &operator *=(FFTWComplex &a, const FFTWComplex &b) {
+    FFTWComplex::value_type t = c_re(a)*c_re(b)-c_im(a)*c_im(b);
+    c_im(a) = c_re(a)*c_im(b)+c_im(a)*c_re(b);
+    c_re(a) = t;
+    return a;
+}
+
+inline FFTWComplex &operator /=(FFTWComplex &a, const FFTWComplex &b) {
+    FFTWComplex::value_type sm = b.squaredMagnitude();
+    FFTWComplex::value_type t = (c_re(a)*c_re(b)+c_im(a)*c_im(b))/sm;
+    c_im(a) = (c_re(b)*c_im(a)-c_re(a)*c_im(b))/sm;
+    c_re(a) = t;
+    return a;
+}
+
+inline FFTWComplex &operator *=(FFTWComplex &a, const double &b) {
+    c_re(a) *= b;
+    c_im(a) *= b;
+    return a;
+}
+
+inline FFTWComplex &operator /=(FFTWComplex &a, const double &b) {
+    c_re(a) /= b;
+    c_im(a) /= b;
+    return a;
+}
+
+inline FFTWComplex operator +(FFTWComplex a, const FFTWComplex &b) {
+    a += b;
+    return a;
+}
+
+inline FFTWComplex operator -(FFTWComplex a, const FFTWComplex &b) {
+    a -= b;
+    return a;
+}
+
+inline FFTWComplex operator *(FFTWComplex a, const FFTWComplex &b) {
+    a *= b;
+    return a;
+}
+
+inline FFTWComplex operator *(FFTWComplex a, const double &b) {
+    a *= b;
+    return a;
+}
+
+inline FFTWComplex operator *(const double &a, FFTWComplex b) {
+    b *= a;
+    return b;
+}
+
+inline FFTWComplex operator /(FFTWComplex a, const FFTWComplex &b) {
+    a /= b;
+    return a;
+}
+
+inline FFTWComplex operator /(FFTWComplex a, const double &b) {
+    a /= b;
+    return a;
+}
+
+using VIGRA_CSTD::abs;
+
+inline FFTWComplex::value_type abs(const FFTWComplex &a)
+{
+    return a.magnitude();
+}
+
+inline FFTWComplex conj(const FFTWComplex &a)
+{
+    return FFTWComplex(a.re, -a.im);
+}
+
+inline FFTWComplex::NormType norm(const FFTWComplex &a)
+{
+    return a.magnitude();
+}
+
+inline FFTWComplex::SquaredNormType squaredNorm(const FFTWComplex &a)
+{
+    return a.squaredMagnitude();
+}
+
+/********************************************************/
+/*                                                      */
+/*                      FFTWRealImage                   */
+/*                                                      */
+/********************************************************/
+
+/* documentation: see fftw3.hxx
+*/
+typedef BasicImage<fftw_real> FFTWRealImage;
+
+/********************************************************/
+/*                                                      */
+/*                     FFTWComplexImage                 */
+/*                                                      */
+/********************************************************/
+
+template<>
+struct IteratorTraits<
+        BasicImageIterator<FFTWComplex, FFTWComplex **> >
+{
+    typedef BasicImageIterator<FFTWComplex, FFTWComplex **>  Iterator;
+    typedef Iterator                             iterator;
+    typedef BasicImageIterator<FFTWComplex, FFTWComplex **>         mutable_iterator;
+    typedef ConstBasicImageIterator<FFTWComplex, FFTWComplex **>    const_iterator;
+    typedef iterator::iterator_category          iterator_category;
+    typedef iterator::value_type                 value_type;
+    typedef iterator::reference                  reference;
+    typedef iterator::index_reference            index_reference;
+    typedef iterator::pointer                    pointer;
+    typedef iterator::difference_type            difference_type;
+    typedef iterator::row_iterator               row_iterator;
+    typedef iterator::column_iterator            column_iterator;
+    typedef VectorAccessor<FFTWComplex>          default_accessor;
+    typedef VectorAccessor<FFTWComplex>          DefaultAccessor;
+    typedef VigraTrueType                        hasConstantStrides;
+};
+
+template<>
+struct IteratorTraits<
+        ConstBasicImageIterator<FFTWComplex, FFTWComplex **> >
+{
+    typedef ConstBasicImageIterator<FFTWComplex, FFTWComplex **>    Iterator;
+    typedef Iterator                             iterator;
+    typedef BasicImageIterator<FFTWComplex, FFTWComplex **>         mutable_iterator;
+    typedef ConstBasicImageIterator<FFTWComplex, FFTWComplex **>    const_iterator;
+    typedef iterator::iterator_category          iterator_category;
+    typedef iterator::value_type                 value_type;
+    typedef iterator::reference                  reference;
+    typedef iterator::index_reference            index_reference;
+    typedef iterator::pointer                    pointer;
+    typedef iterator::difference_type            difference_type;
+    typedef iterator::row_iterator               row_iterator;
+    typedef iterator::column_iterator            column_iterator;
+    typedef VectorAccessor<FFTWComplex>          default_accessor;
+    typedef VectorAccessor<FFTWComplex>          DefaultAccessor;
+    typedef VigraTrueType                        hasConstantStrides;
+};
+
+/* documentation: see fftw3.hxx
+*/
+typedef BasicImage<FFTWComplex> FFTWComplexImage;
+
+/********************************************************/
+/*                                                      */
+/*                  FFTWComplex-Accessors               */
+/*                                                      */
+/********************************************************/
+
+/* documentation: see fftw3.hxx
+*/
+class FFTWRealAccessor
+{
+  public:
+
+        /// The accessor's value type.
+    typedef fftw_real value_type;
+
+        /// Read real part at iterator position.
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const {
+        return c_re(*i);
+    }
+
+        /// Read real part at offset from iterator position.
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE d) const {
+        return c_re(i[d]);
+    }
+
+        /// Write real part at iterator position.
+    template <class ITERATOR>
+    void set(value_type const & v, ITERATOR const & i) const {
+        c_re(*i)= v;
+    }
+
+        /// Write real part at offset from iterator position.
+    template <class ITERATOR, class DIFFERENCE>
+    void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const {
+        c_re(i[d])= v;
+    }
+};
+
+/* documentation: see fftw3.hxx
+*/
+class FFTWImaginaryAccessor
+{
+  public:
+        /// The accessor's value type.
+    typedef fftw_real value_type;
+
+        /// Read imaginary part at iterator position.
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const {
+        return c_im(*i);
+    }
+
+        /// Read imaginary part at offset from iterator position.
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE d) const {
+        return c_im(i[d]);
+    }
+
+        /// Write imaginary part at iterator position.
+    template <class ITERATOR>
+    void set(value_type const & v, ITERATOR const & i) const {
+        c_im(*i)= v;
+    }
+
+        /// Write imaginary part at offset from iterator position.
+    template <class ITERATOR, class DIFFERENCE>
+    void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const {
+        c_im(i[d])= v;
+    }
+};
+
+/* documentation: see fftw3.hxx
+*/
+class FFTWWriteRealAccessor: public FFTWRealAccessor
+{
+  public:
+        /// The accessor's value type.
+    typedef fftw_real value_type;
+
+        /** Write real number at iterator position. Set imaginary part
+            to 0.
+        */
+    template <class ITERATOR>
+    void set(value_type const & v, ITERATOR const & i) const {
+        c_re(*i)= v;
+        c_im(*i)= 0;
+    }
+
+        /** Write real number at offset from iterator position. Set imaginary part
+            to 0.
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const {
+        c_re(i[d])= v;
+        c_im(i[d])= 0;
+    }
+};
+
+/* documentation: see fftw3.hxx
+*/
+class FFTWMagnitudeAccessor
+{
+  public:
+        /// The accessor's value type.
+    typedef fftw_real value_type;
+
+        /// Read magnitude at iterator position.
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const {
+        return (*i).magnitude();
+    }
+
+        /// Read magnitude at offset from iterator position.
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE d) const {
+        return (i[d]).magnitude();
+    }
+};
+
+/* documentation: see fftw3.hxx
+*/
+class FFTWPhaseAccessor
+{
+  public:
+        /// The accessor's value type.
+    typedef fftw_real value_type;
+
+        /// Read phase at iterator position.
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const {
+        return (*i).phase();
+    }
+
+        /// Read phase at offset from iterator position.
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE d) const {
+        return (i[d]).phase();
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                    Fourier Transform                 */
+/*                                                      */
+/********************************************************/
+
+/** \page FourierTransformFFTW2 Fast Fourier Transform
+    
+    This documentation describes the deprecated VIGRA interface to 
+    FFTW 2. Use the \link FourierTransform interface to the newer
+    version FFTW 3\endlink instead.
+    
+    VIGRA uses the <a href="http://www.fftw.org/">FFTW Fast Fourier
+    Transform</a> package to perform Fourier transformations. VIGRA
+    provides a wrapper for FFTW's complex number type (FFTWComplex),
+    but FFTW's functions are used verbatim. If the image is stored as
+    a FFTWComplexImage, a FFT is performed like this:
+
+    \code
+    vigra::FFTWComplexImage spatial(width,height), fourier(width,height);
+    ... // fill image with data
+
+    // create a plan for optimal performance
+    fftwnd_plan forwardPlan=
+        fftw2d_create_plan(height, width, FFTW_FORWARD, FFTW_ESTIMATE );
+
+    // calculate FFT
+    fftwnd_one(forwardPlan, spatial.begin(), fourier.begin());
+    \endcode
+
+    Note that in the creation of a plan, the height must be given
+    first. Note also that <TT>spatial.begin()</TT> may only be passed
+    to <TT>fftwnd_one</TT> if the transform shall be applied to the
+    entire image. When you want to retrict operation to an ROI, you
+    create a copy of the ROI in an image of appropriate size.
+
+    More information on using FFTW can be found <a href="http://www.fftw.org/doc/">here</a>.
+
+    FFTW produces fourier images that have the DC component (the
+    origin of the Fourier space) in the upper left corner. Often, one
+    wants the origin in the center of the image, so that frequencies
+    always increase towards the border of the image. This can be
+    achieved by calling \ref moveDCToCenter(). The inverse
+    transformation is done by \ref moveDCToUpperLeft().
+
+    <b>\#include</b> \<vigra/fftw.hxx\><br>
+    Namespace: vigra
+*/
+
+/********************************************************/
+/*                                                      */
+/*                     moveDCToCenter                   */
+/*                                                      */
+/********************************************************/
+
+/* documentation: see fftw3.hxx
+*/
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void moveDCToCenter(SrcImageIterator src_upperleft,
+                               SrcImageIterator src_lowerright, SrcAccessor sa,
+                               DestImageIterator dest_upperleft, DestAccessor da)
+{
+    int w= src_lowerright.x - src_upperleft.x;
+    int h= src_lowerright.y - src_upperleft.y;
+    int w1 = w/2;
+    int h1 = h/2;
+    int w2 = (w+1)/2;
+    int h2 = (h+1)/2;
+
+    // 2. Quadrant  zum 4.
+    copyImage(srcIterRange(src_upperleft,
+                           src_upperleft  + Diff2D(w2, h2), sa),
+              destIter    (dest_upperleft + Diff2D(w1, h1), da));
+
+    // 4. Quadrant zum 2.
+    copyImage(srcIterRange(src_upperleft + Diff2D(w2, h2),
+                           src_lowerright, sa),
+              destIter    (dest_upperleft, da));
+
+    // 1. Quadrant zum 3.
+    copyImage(srcIterRange(src_upperleft  + Diff2D(w2, 0),
+                           src_upperleft  + Diff2D(w,  h2), sa),
+              destIter    (dest_upperleft + Diff2D(0,  h1), da));
+
+    // 3. Quadrant zum 1.
+    copyImage(srcIterRange(src_upperleft  + Diff2D(0,  h2),
+                           src_upperleft  + Diff2D(w2, h), sa),
+              destIter    (dest_upperleft + Diff2D(w1, 0), da));
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void moveDCToCenter(
+    triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+    pair<DestImageIterator, DestAccessor> dest)
+{
+    moveDCToCenter(src.first, src.second, src.third,
+                          dest.first, dest.second);
+}
+
+/********************************************************/
+/*                                                      */
+/*                   moveDCToUpperLeft                  */
+/*                                                      */
+/********************************************************/
+
+/* documentation: see fftw3.hxx
+*/
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void moveDCToUpperLeft(SrcImageIterator src_upperleft,
+                               SrcImageIterator src_lowerright, SrcAccessor sa,
+                               DestImageIterator dest_upperleft, DestAccessor da)
+{
+    int w= src_lowerright.x - src_upperleft.x;
+    int h= src_lowerright.y - src_upperleft.y;
+    int w2 = w/2;
+    int h2 = h/2;
+    int w1 = (w+1)/2;
+    int h1 = (h+1)/2;
+
+    // 2. Quadrant  zum 4.
+    copyImage(srcIterRange(src_upperleft,
+                           src_upperleft  + Diff2D(w2, h2), sa),
+              destIter    (dest_upperleft + Diff2D(w1, h1), da));
+
+    // 4. Quadrant zum 2.
+    copyImage(srcIterRange(src_upperleft + Diff2D(w2, h2),
+                           src_lowerright, sa),
+              destIter    (dest_upperleft, da));
+
+    // 1. Quadrant zum 3.
+    copyImage(srcIterRange(src_upperleft  + Diff2D(w2, 0),
+                           src_upperleft  + Diff2D(w,  h2), sa),
+              destIter    (dest_upperleft + Diff2D(0,  h1), da));
+
+    // 3. Quadrant zum 1.
+    copyImage(srcIterRange(src_upperleft  + Diff2D(0,  h2),
+                           src_upperleft  + Diff2D(w2, h), sa),
+              destIter    (dest_upperleft + Diff2D(w1, 0), da));
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void moveDCToUpperLeft(
+    triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+    pair<DestImageIterator, DestAccessor> dest)
+{
+    moveDCToUpperLeft(src.first, src.second, src.third,
+                                          dest.first, dest.second);
+}
+
+/********************************************************/
+/*                                                      */
+/*                   applyFourierFilter                 */
+/*                                                      */
+/********************************************************/
+
+/* documentation: see fftw3.hxx
+*/
+
+// applyFourierFilter versions without fftwnd_plans:
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+inline
+void applyFourierFilter(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                        pair<FilterImageIterator, FilterAccessor> filter,
+                        pair<DestImageIterator, DestAccessor> dest)
+{
+    applyFourierFilter(src.first, src.second, src.third,
+                       filter.first, filter.second,
+                       dest.first, dest.second);
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+void applyFourierFilter(SrcImageIterator srcUpperLeft,
+                        SrcImageIterator srcLowerRight, SrcAccessor sa,
+                        FilterImageIterator filterUpperLeft, FilterAccessor fa,
+                        DestImageIterator destUpperLeft, DestAccessor da)
+{
+    // copy real input images into a complex one...
+    int w= srcLowerRight.x - srcUpperLeft.x;
+    int h= srcLowerRight.y - srcUpperLeft.y;
+
+    FFTWComplexImage workImage(w, h);
+    copyImage(srcIterRange(srcUpperLeft, srcLowerRight, sa),
+              destImage(workImage, FFTWWriteRealAccessor()));
+
+    // ...and call the impl
+    FFTWComplexImage const & cworkImage = workImage;
+    applyFourierFilterImpl(cworkImage.upperLeft(), cworkImage.lowerRight(), cworkImage.accessor(),
+                           filterUpperLeft, fa,
+                           destUpperLeft, da);
+}
+
+typedef FFTWComplexImage::const_traverser FFTWConstTraverser;
+
+template <class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+inline
+void applyFourierFilter(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor sa,
+    FilterImageIterator filterUpperLeft, FilterAccessor fa,
+    DestImageIterator destUpperLeft, DestAccessor da)
+{
+    int w= srcLowerRight.x - srcUpperLeft.x;
+    int h= srcLowerRight.y - srcUpperLeft.y;
+
+    // test for right memory layout (fftw expects a 2*width*height floats array)
+    if (&(*(srcUpperLeft + Diff2D(w, 0))) == &(*(srcUpperLeft + Diff2D(0, 1))))
+        applyFourierFilterImpl(srcUpperLeft, srcLowerRight, sa,
+                               filterUpperLeft, fa,
+                               destUpperLeft, da);
+    else
+    {
+        FFTWComplexImage workImage(w, h);
+        copyImage(srcIterRange(srcUpperLeft, srcLowerRight, sa),
+                  destImage(workImage));
+
+        FFTWComplexImage const & cworkImage = workImage;
+        applyFourierFilterImpl(cworkImage.upperLeft(), cworkImage.lowerRight(), cworkImage.accessor(),
+                               filterUpperLeft, fa,
+                               destUpperLeft, da);
+    }
+}
+
+template <class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+void applyFourierFilterImpl(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor sa,
+    FilterImageIterator filterUpperLeft, FilterAccessor fa,
+    DestImageIterator destUpperLeft, DestAccessor da)
+{
+    // create plans and call variant with plan parameters
+    int w= srcLowerRight.x - srcUpperLeft.x;
+    int h= srcLowerRight.y - srcUpperLeft.y;
+
+    fftwnd_plan forwardPlan=
+        fftw2d_create_plan(h, w, FFTW_FORWARD, FFTW_ESTIMATE );
+    fftwnd_plan backwardPlan=
+        fftw2d_create_plan(h, w, FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_IN_PLACE);
+
+    applyFourierFilterImpl(srcUpperLeft, srcLowerRight, sa,
+                           filterUpperLeft, fa,
+                           destUpperLeft, da,
+                           forwardPlan, backwardPlan);
+
+    fftwnd_destroy_plan(forwardPlan);
+    fftwnd_destroy_plan(backwardPlan);
+}
+
+// applyFourierFilter versions with fftwnd_plans:
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+inline
+void applyFourierFilter(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                        pair<FilterImageIterator, FilterAccessor> filter,
+                        pair<DestImageIterator, DestAccessor> dest,
+                        const fftwnd_plan &forwardPlan, const fftwnd_plan &backwardPlan)
+{
+    applyFourierFilter(src.first, src.second, src.third,
+                       filter.first, filter.second,
+                       dest.first, dest.second,
+                       forwardPlan, backwardPlan);
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+void applyFourierFilter(SrcImageIterator srcUpperLeft,
+                        SrcImageIterator srcLowerRight, SrcAccessor sa,
+                        FilterImageIterator filterUpperLeft, FilterAccessor fa,
+                        DestImageIterator destUpperLeft, DestAccessor da,
+                        const fftwnd_plan &forwardPlan, const fftwnd_plan &backwardPlan)
+{
+    int w= srcLowerRight.x - srcUpperLeft.x;
+    int h= srcLowerRight.y - srcUpperLeft.y;
+
+    FFTWComplexImage workImage(w, h);
+    copyImage(srcIterRange(srcUpperLeft, srcLowerRight, sa),
+              destImage(workImage, FFTWWriteRealAccessor()));
+
+    FFTWComplexImage const & cworkImage = workImage;
+    applyFourierFilterImpl(cworkImage.upperLeft(), cworkImage.lowerRight(), cworkImage.accessor(),
+                           filterUpperLeft, fa,
+                           destUpperLeft, da,
+                           forwardPlan, backwardPlan);
+}
+
+template <class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+inline
+void applyFourierFilter(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor sa,
+    FilterImageIterator filterUpperLeft, FilterAccessor fa,
+    DestImageIterator destUpperLeft, DestAccessor da,
+    const fftwnd_plan &forwardPlan, const fftwnd_plan &backwardPlan)
+{
+    applyFourierFilterImpl(srcUpperLeft, srcLowerRight, sa,
+                           filterUpperLeft, fa,
+                           destUpperLeft, da,
+                           forwardPlan, backwardPlan);
+}
+
+template <class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+void applyFourierFilterImpl(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor sa,
+    FilterImageIterator filterUpperLeft, FilterAccessor fa,
+    DestImageIterator destUpperLeft, DestAccessor da,
+    const fftwnd_plan &forwardPlan, const fftwnd_plan &backwardPlan)
+{
+    FFTWComplexImage complexResultImg(srcLowerRight - srcUpperLeft);
+
+    // FFT from srcImage to complexResultImg
+    fftwnd_one(forwardPlan, const_cast<FFTWComplex *>(&(*srcUpperLeft)),
+               complexResultImg.begin());
+
+    // convolve in freq. domain (in complexResultImg)
+    combineTwoImages(srcImageRange(complexResultImg), srcIter(filterUpperLeft, fa),
+                     destImage(complexResultImg), std::multiplies<FFTWComplex>());
+
+    // FFT back into spatial domain (inplace in complexResultImg)
+    fftwnd_one(backwardPlan, complexResultImg.begin(), 0);
+
+    typedef typename
+        NumericTraits<typename DestAccessor::value_type>::isScalar
+        isScalarResult;
+
+    // normalization (after FFTs), maybe stripping imaginary part
+    applyFourierFilterImplNormalization(complexResultImg, destUpperLeft, da,
+                                        isScalarResult());
+}
+
+template <class DestImageIterator, class DestAccessor>
+void applyFourierFilterImplNormalization(FFTWComplexImage const &srcImage,
+                                         DestImageIterator destUpperLeft,
+                                         DestAccessor da,
+                                         VigraFalseType)
+{
+    double normFactor= 1.0/(srcImage.width() * srcImage.height());
+
+    for(int y=0; y<srcImage.height(); y++, destUpperLeft.y++)
+    {
+        DestImageIterator dIt= destUpperLeft;
+        for(int x= 0; x< srcImage.width(); x++, dIt.x++)
+        {
+            da.setComponent(srcImage(x, y).re*normFactor, dIt, 0);
+            da.setComponent(srcImage(x, y).im*normFactor, dIt, 1);
+        }
+    }
+}
+
+inline
+void applyFourierFilterImplNormalization(FFTWComplexImage const & srcImage,
+        FFTWComplexImage::traverser destUpperLeft,
+        FFTWComplexImage::Accessor da,
+        VigraFalseType)
+{
+    transformImage(srcImageRange(srcImage), destIter(destUpperLeft, da),
+                   linearIntensityTransform<FFTWComplex>(1.0/(srcImage.width() * srcImage.height())));
+}
+
+template <class DestImageIterator, class DestAccessor>
+void applyFourierFilterImplNormalization(FFTWComplexImage const & srcImage,
+                                         DestImageIterator destUpperLeft,
+                                         DestAccessor da,
+                                         VigraTrueType)
+{
+    double normFactor= 1.0/(srcImage.width() * srcImage.height());
+
+    for(int y=0; y<srcImage.height(); y++, destUpperLeft.y++)
+    {
+        DestImageIterator dIt= destUpperLeft;
+        for(int x= 0; x< srcImage.width(); x++, dIt.x++)
+            da.set(srcImage(x, y).re*normFactor, dIt);
+    }
+}
+
+/**********************************************************/
+/*                                                        */
+/*                applyFourierFilterFamily                */
+/*                                                        */
+/**********************************************************/
+
+/* documentation: see fftw3.hxx
+*/
+
+// applyFourierFilterFamily versions without fftwnd_plans:
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterType, class DestImage>
+inline
+void applyFourierFilterFamily(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                              const ImageArray<FilterType> &filters,
+                              ImageArray<DestImage> &results)
+{
+    applyFourierFilterFamily(src.first, src.second, src.third,
+                             filters, results);
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterType, class DestImage>
+void applyFourierFilterFamily(SrcImageIterator srcUpperLeft,
+                              SrcImageIterator srcLowerRight, SrcAccessor sa,
+                              const ImageArray<FilterType> &filters,
+                              ImageArray<DestImage> &results)
+{
+    int w= srcLowerRight.x - srcUpperLeft.x;
+    int h= srcLowerRight.y - srcUpperLeft.y;
+
+    FFTWComplexImage workImage(w, h);
+    copyImage(srcIterRange(srcUpperLeft, srcLowerRight, sa),
+              destImage(workImage, FFTWWriteRealAccessor()));
+
+    FFTWComplexImage const & cworkImage = workImage;
+    applyFourierFilterFamilyImpl(cworkImage.upperLeft(), cworkImage.lowerRight(), cworkImage.accessor(),
+                                 filters, results);
+}
+
+template <class FilterType, class DestImage>
+inline
+void applyFourierFilterFamily(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor sa,
+    const ImageArray<FilterType> &filters,
+    ImageArray<DestImage> &results)
+{
+    applyFourierFilterFamilyImpl(srcUpperLeft, srcLowerRight, sa,
+                                 filters, results);
+}
+
+template <class FilterType, class DestImage>
+void applyFourierFilterFamilyImpl(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor sa,
+    const ImageArray<FilterType> &filters,
+    ImageArray<DestImage> &results)
+{
+    int w= srcLowerRight.x - srcUpperLeft.x;
+    int h= srcLowerRight.y - srcUpperLeft.y;
+
+    fftwnd_plan forwardPlan=
+        fftw2d_create_plan(h, w, FFTW_FORWARD, FFTW_ESTIMATE );
+    fftwnd_plan backwardPlan=
+        fftw2d_create_plan(h, w, FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_IN_PLACE);
+
+    applyFourierFilterFamilyImpl(srcUpperLeft, srcLowerRight, sa,
+                                 filters, results,
+                                 forwardPlan, backwardPlan);
+
+    fftwnd_destroy_plan(forwardPlan);
+    fftwnd_destroy_plan(backwardPlan);
+}
+
+// applyFourierFilterFamily versions with fftwnd_plans:
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterType, class DestImage>
+inline
+void applyFourierFilterFamily(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                              const ImageArray<FilterType> &filters,
+                              ImageArray<DestImage> &results,
+                              const fftwnd_plan &forwardPlan, const fftwnd_plan &backwardPlan)
+{
+    applyFourierFilterFamily(src.first, src.second, src.third,
+                                 filters, results,
+                                 forwardPlan, backwardPlan);
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterType, class DestImage>
+void applyFourierFilterFamily(SrcImageIterator srcUpperLeft,
+                              SrcImageIterator srcLowerRight, SrcAccessor sa,
+                              const ImageArray<FilterType> &filters,
+                              ImageArray<DestImage> &results,
+                              const fftwnd_plan &forwardPlan, const fftwnd_plan &backwardPlan)
+{
+    int w= srcLowerRight.x - srcUpperLeft.x;
+    int h= srcLowerRight.y - srcUpperLeft.y;
+
+    FFTWComplexImage workImage(w, h);
+    copyImage(srcIterRange(srcUpperLeft, srcLowerRight, sa),
+              destImage(workImage, FFTWWriteRealAccessor()));
+
+    FFTWComplexImage const & cworkImage = workImage;
+    applyFourierFilterFamilyImpl(cworkImage.upperLeft(), cworkImage.lowerRight(), cworkImage.accessor(),
+                                 filters, results,
+                                 forwardPlan, backwardPlan);
+}
+
+template <class FilterType, class DestImage>
+inline
+void applyFourierFilterFamily(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor sa,
+    const ImageArray<FilterType> &filters,
+    ImageArray<DestImage> &results,
+    const fftwnd_plan &forwardPlan, const fftwnd_plan &backwardPlan)
+{
+    int w= srcLowerRight.x - srcUpperLeft.x;
+    int h= srcLowerRight.y - srcUpperLeft.y;
+
+    // test for right memory layout (fftw expects a 2*width*height floats array)
+    if (&(*(srcUpperLeft + Diff2D(w, 0))) == &(*(srcUpperLeft + Diff2D(0, 1))))
+        applyFourierFilterFamilyImpl(srcUpperLeft, srcLowerRight, sa,
+                                     filters, results,
+                                     forwardPlan, backwardPlan);
+    else
+    {
+        FFTWComplexImage workImage(w, h);
+        copyImage(srcIterRange(srcUpperLeft, srcLowerRight, sa),
+                  destImage(workImage));
+
+        FFTWComplexImage const & cworkImage = workImage;
+        applyFourierFilterFamilyImpl(cworkImage.upperLeft(), cworkImage.lowerRight(), cworkImage.accessor(),
+                                     filters, results,
+                                     forwardPlan, backwardPlan);
+    }
+}
+
+template <class FilterType, class DestImage>
+void applyFourierFilterFamilyImpl(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor sa,
+    const ImageArray<FilterType> &filters,
+    ImageArray<DestImage> &results,
+    const fftwnd_plan &forwardPlan, const fftwnd_plan &backwardPlan)
+{
+    // make sure the filter images have the right dimensions
+    vigra_precondition((srcLowerRight - srcUpperLeft) == filters.imageSize(),
+                       "applyFourierFilterFamily called with src image size != filters.imageSize()!");
+
+    // make sure the result image array has the right dimensions
+    results.resize(filters.size());
+    results.resizeImages(filters.imageSize());
+
+    // FFT from srcImage to freqImage
+    int w= srcLowerRight.x - srcUpperLeft.x;
+    int h= srcLowerRight.y - srcUpperLeft.y;
+
+    FFTWComplexImage freqImage(w, h);
+    FFTWComplexImage result(w, h);
+
+    fftwnd_one(forwardPlan, const_cast<FFTWComplex *>(&(*srcUpperLeft)), freqImage.begin());
+
+    typedef typename
+        NumericTraits<typename DestImage::Accessor::value_type>::isScalar
+        isScalarResult;
+
+    // convolve with filters in freq. domain
+    for (unsigned int i= 0;  i < filters.size(); i++)
+    {
+        combineTwoImages(srcImageRange(freqImage), srcImage(filters[i]),
+                         destImage(result), std::multiplies<FFTWComplex>());
+
+        // FFT back into spatial domain (inplace in destImage)
+        fftwnd_one(backwardPlan, result.begin(), 0);
+
+        // normalization (after FFTs), maybe stripping imaginary part
+        applyFourierFilterImplNormalization(result,
+                                            results[i].upperLeft(), results[i].accessor(),
+                                            isScalarResult());
+    }
+}
+
+} // namespace vigra
+
+#endif // VIGRA_FFTW_HXX
diff --git a/include/vigra/fftw3.hxx b/include/vigra/fftw3.hxx
new file mode 100644
index 0000000..112723d
--- /dev/null
+++ b/include/vigra/fftw3.hxx
@@ -0,0 +1,2772 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_FFTW3_HXX
+#define VIGRA_FFTW3_HXX
+
+#include <cmath>
+#include <functional>
+#include <complex>
+#include "stdimage.hxx"
+#include "copyimage.hxx"
+#include "transformimage.hxx"
+#include "combineimages.hxx"
+#include "numerictraits.hxx"
+#include "imagecontainer.hxx"
+#include <fftw3.h>
+
+namespace vigra {
+
+typedef double fftw_real;
+
+template <class T>
+struct FFTWReal;
+
+template <>
+struct FFTWReal<fftw_complex>
+{
+    typedef double type;
+};
+
+template <>
+struct FFTWReal<fftwf_complex>
+{
+    typedef float type;
+};
+
+template <>
+struct FFTWReal<fftwl_complex>
+{
+    typedef long double type;
+};
+
+template <class T>
+struct FFTWReal2Complex;
+
+template <>
+struct FFTWReal2Complex<double>
+{
+    typedef fftw_complex type;
+    typedef fftw_plan plan_type;
+};
+
+template <>
+struct FFTWReal2Complex<float>
+{
+    typedef fftwf_complex type;
+    typedef fftwf_plan plan_type;
+};
+
+template <>
+struct FFTWReal2Complex<long double>
+{
+    typedef fftwl_complex type;
+    typedef fftwl_plan plan_type;
+};
+
+/********************************************************/
+/*                                                      */
+/*                    FFTWComplex                       */
+/*                                                      */
+/********************************************************/
+
+/** \brief Wrapper class for the FFTW complex types '<TT>fftw_complex</TT>'.
+
+    This class encapsulates the low-level complex number types provided by the 
+    <a href="http://www.fftw.org/">FFTW Fast Fourier Transform</a> library (i.e. 
+    '<TT>fftw_complex</TT>', '<TT>fftwf_complex</TT>', '<TT>fftwl_complex</TT>'). 
+    In particular, it provides constructors, member functions and 
+    \ref FFTWComplexOperators "arithmetic operators" that make FFTW complex numbers
+    compatible with <tt>std::complex</tt>. In addition, the class defines 
+    transformations to polar coordinates and \ref FFTWComplexAccessors "accessors".
+
+    FFTWComplex implements the concepts \ref AlgebraicField and
+    \ref DivisionAlgebra. The standard image types <tt>FFTWRealImage</tt>
+    and <tt>FFTWComplexImage</tt> are defined.
+
+    <b>See also:</b>
+    <ul>
+        <li> \ref FFTWComplexTraits
+        <li> \ref FFTWComplexOperators
+        <li> \ref FFTWComplexAccessors
+    </ul>
+
+    <b>\#include</b> \<vigra/fftw3.hxx\> (for FFTW 3) or<br>
+    <b>\#include</b> \<vigra/fftw.hxx\> (for deprecated FFTW 2)<br>
+    Namespace: vigra
+*/
+template <class Real = double>
+class FFTWComplex
+{
+  public:
+        /** The wrapped complex type
+        */
+      typedef typename FFTWReal2Complex<Real>::type complex_type;
+
+        /** The complex' component type, as defined in '<TT>fftw3.h</TT>'
+        */
+    typedef Real value_type;
+
+        /** reference type (result of operator[])
+        */
+    typedef value_type & reference;
+
+        /** const reference type (result of operator[] const)
+        */
+    typedef value_type const & const_reference;
+
+        /** iterator type (result of begin() )
+        */
+    typedef value_type * iterator;
+
+        /** const iterator type (result of begin() const)
+        */
+    typedef value_type const * const_iterator;
+
+        /** The norm type (result of magnitude())
+        */
+    typedef value_type NormType;
+
+        /** The squared norm type (result of squaredMagnitde())
+        */
+    typedef value_type SquaredNormType;
+
+        /** Construct from real and imaginary part.
+            Default: 0.
+        */
+    FFTWComplex(value_type const & re = 0.0, value_type const & im = 0.0)
+    {
+        data_[0] = re;
+        data_[1] = im;
+    }
+
+        /** Copy constructor.
+        */
+    FFTWComplex(FFTWComplex const & o)
+    {
+        data_[0] = o.data_[0];
+        data_[1] = o.data_[1];
+    }
+
+        /** Copy constructor.
+        */
+    template <class U>
+    FFTWComplex(FFTWComplex<U> const & o)
+    {
+        data_[0] = (Real)o.real();
+        data_[1] = (Real)o.imag();
+    }
+
+        /** Construct from plain <TT>fftw_complex</TT>.
+        */
+    FFTWComplex(fftw_complex const & o)
+    {
+        data_[0] = (Real)o[0];
+        data_[1] = (Real)o[1];
+    }
+
+        /** Construct from plain <TT>fftwf_complex</TT>.
+        */
+    FFTWComplex(fftwf_complex const & o)
+    {
+        data_[0] = (Real)o[0];
+        data_[1] = (Real)o[1];
+    }
+
+        /** Construct from plain <TT>fftwl_complex</TT>.
+        */
+    FFTWComplex(fftwl_complex const & o)
+    {
+        data_[0] = (Real)o[0];
+        data_[1] = (Real)o[1];
+    }
+
+        /** Construct from std::complex.
+        */
+    template <class T>
+    FFTWComplex(std::complex<T> const & o)
+    {
+        data_[0] = (Real)o.real();
+        data_[1] = (Real)o.imag();
+    }
+
+        /** Construct from TinyVector.
+        */
+    template <class T>
+    FFTWComplex(TinyVector<T, 2> const & o)
+    {
+        data_[0] = (Real)o[0];
+        data_[1] = (Real)o[1];
+    }
+
+        /** Assignment.
+        */
+    FFTWComplex& operator=(FFTWComplex const & o)
+    {
+        data_[0] = o.data_[0];
+        data_[1] = o.data_[1];
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    template <class U>
+    FFTWComplex& operator=(FFTWComplex<U> const & o)
+    {
+        data_[0] = (Real)o.real();
+        data_[1] = (Real)o.imag();
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    FFTWComplex& operator=(fftw_complex const & o)
+    {
+        data_[0] = (Real)o[0];
+        data_[1] = (Real)o[1];
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    FFTWComplex& operator=(fftwf_complex const & o)
+    {
+        data_[0] = (Real)o[0];
+        data_[1] = (Real)o[1];
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    FFTWComplex& operator=(fftwl_complex const & o)
+    {
+        data_[0] = (Real)o[0];
+        data_[1] = (Real)o[1];
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    FFTWComplex& operator=(double o)
+    {
+        data_[0] = (Real)o;
+        data_[1] = 0.0;
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    FFTWComplex& operator=(float o)
+    {
+        data_[0] = (Real)o;
+        data_[1] = 0.0;
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    FFTWComplex& operator=(long double o)
+    {
+        data_[0] = (Real)o;
+        data_[1] = 0.0;
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    template <class T>
+    FFTWComplex& operator=(TinyVector<T, 2> const & o)
+    {
+        data_[0] = (Real)o[0];
+        data_[1] = (Real)o[1];
+        return *this;
+    }
+
+        /** Assignment.
+        */
+    template <class T>
+    FFTWComplex& operator=(std::complex<T> const & o)
+    {
+        data_[0] = (Real)o.real();
+        data_[1] = (Real)o.imag();
+        return *this;
+    }
+
+    reference re()
+        { return data_[0]; }
+
+    const_reference re() const
+        { return data_[0]; }
+
+    reference real()
+        { return data_[0]; }
+
+    const_reference real() const
+        { return data_[0]; }
+
+    reference im()
+        { return data_[1]; }
+
+    const_reference im() const
+        { return data_[1]; }
+
+    reference imag()
+        { return data_[1]; }
+
+    const_reference imag() const
+        { return data_[1]; }
+
+        /** Unary negation.
+        */
+    FFTWComplex operator-() const
+        { return FFTWComplex(-data_[0], -data_[1]); }
+
+        /** Squared magnitude x*conj(x)
+        */
+    SquaredNormType squaredMagnitude() const
+        { return data_[0]*data_[0]+data_[1]*data_[1]; }
+
+        /** Magnitude (length of radius vector).
+        */
+    NormType magnitude() const
+        { return VIGRA_CSTD::sqrt(squaredMagnitude()); }
+
+        /** Phase angle.
+        */
+    value_type phase() const
+        { return VIGRA_CSTD::atan2(data_[1], data_[0]); }
+
+        /** Access components as if number were a vector.
+        */
+    reference operator[](int i)
+        { return data_[i]; }
+
+        /** Read components as if number were a vector.
+        */
+    const_reference operator[](int i) const
+        { return data_[i]; }
+
+        /** Length of complex number (always 2).
+        */
+    int size() const
+        { return 2; }
+
+    iterator begin()
+        { return data_; }
+
+    iterator end()
+        { return data_ + 2; }
+
+    const_iterator begin() const
+        { return data_; }
+
+    const_iterator end() const
+        { return data_ + 2; }
+
+  private:
+    complex_type data_;
+};
+
+/********************************************************/
+/*                                                      */
+/*                     FFTWComplexTraits                */
+/*                                                      */
+/********************************************************/
+
+/** \page FFTWComplexTraits Numeric and Promote Traits of FFTWComplex
+
+    The numeric and promote traits for fftw_complex and FFTWComplex follow
+    the general specifications for \ref NumericPromotionTraits and
+    \ref AlgebraicField. They are explicitly specialized for the types
+    involved:
+
+    \code
+
+    template<>
+    struct NumericTraits<fftw_complex>
+    {
+        typedef fftw_complex Promote;
+        typedef fftw_complex RealPromote;
+        typedef fftw_complex ComplexPromote;
+        typedef fftw_real    ValueType;
+
+        typedef VigraFalseType isIntegral;
+        typedef VigraFalseType isScalar;
+        typedef VigraFalseType isOrdered;
+        typedef VigraTrueType  isComplex;
+
+        // etc.
+    };
+
+    template<class Real>
+    struct NumericTraits<FFTWComplex<Real> >
+    {
+        typedef FFTWComplex<Real> Promote;
+        typedef FFTWComplex<Real> RealPromote;
+        typedef FFTWComplex<Real> ComplexPromote;
+        typedef Real              ValueType;
+
+        typedef VigraFalseType isIntegral;
+        typedef VigraFalseType isScalar;
+        typedef VigraFalseType isOrdered;
+        typedef VigraTrueType  isComplex;
+
+        // etc.
+    };
+
+    template<>
+    struct NormTraits<fftw_complex>
+    {
+        typedef fftw_complex Type;
+        typedef fftw_real    SquaredNormType;
+        typedef fftw_real    NormType;
+    };
+
+    template<class Real>
+    struct NormTraits<FFTWComplex>
+    {
+        typedef FFTWComplex Type;
+        typedef fftw_real   SquaredNormType;
+        typedef fftw_real   NormType;
+    };
+
+    template <>
+    struct PromoteTraits<fftw_complex, fftw_complex>
+    {
+        typedef fftw_complex Promote;
+    };
+
+    template <>
+    struct PromoteTraits<fftw_complex, double>
+    {
+        typedef fftw_complex Promote;
+    };
+
+    template <>
+    struct PromoteTraits<double, fftw_complex>
+    {
+        typedef fftw_complex Promote;
+    };
+
+    template <class Real>
+    struct PromoteTraits<FFTWComplex<Real>, FFTWComplex<Real> >
+    {
+        typedef FFTWComplex<Real> Promote;
+    };
+
+    template <class Real>
+    struct PromoteTraits<FFTWComplex<Real>, double>
+    {
+        typedef FFTWComplex<Real> Promote;
+    };
+
+    template <class Real>
+    struct PromoteTraits<double, FFTWComplex<Real> >
+    {
+        typedef FFTWComplex<Real> Promote;
+    };
+    \endcode
+
+    <b>\#include</b> \<vigra/fftw3.hxx\> (for FFTW 3) or<br>
+    <b>\#include</b> \<vigra/fftw.hxx\> (for deprecated FFTW 2)<br>
+    Namespace: vigra
+
+*/
+template<>
+struct NumericTraits<fftw_complex>
+{
+    typedef fftw_complex Type;
+    typedef fftw_complex Promote;
+    typedef fftw_complex RealPromote;
+    typedef fftw_complex ComplexPromote;
+    typedef fftw_real    ValueType;
+
+    typedef VigraFalseType isIntegral;
+    typedef VigraFalseType isScalar;
+    typedef NumericTraits<fftw_real>::isSigned isSigned;
+    typedef VigraFalseType isOrdered;
+    typedef VigraTrueType  isComplex;
+
+    static FFTWComplex<> zero() { return FFTWComplex<>(0.0, 0.0); }
+    static FFTWComplex<> one() { return FFTWComplex<>(1.0, 0.0); }
+    static FFTWComplex<> nonZero() { return one(); }
+
+    static const Promote & toPromote(const Type & v) { return v; }
+    static const RealPromote & toRealPromote(const Type & v) { return v; }
+    static const Type & fromPromote(const Promote & v) { return v; }
+    static const Type & fromRealPromote(const RealPromote & v) { return v; }
+};
+
+template<class Real>
+struct NumericTraits<FFTWComplex<Real> >
+{
+    typedef FFTWComplex<Real> Type;
+    typedef FFTWComplex<Real> Promote;
+    typedef FFTWComplex<Real> RealPromote;
+    typedef FFTWComplex<Real> ComplexPromote;
+    typedef typename Type::value_type ValueType;
+
+    typedef VigraFalseType isIntegral;
+    typedef VigraFalseType isScalar;
+    typedef typename NumericTraits<ValueType>::isSigned isSigned;
+    typedef VigraFalseType isOrdered;
+    typedef VigraTrueType  isComplex;
+
+    static Type zero() { return Type(0.0, 0.0); }
+    static Type one() { return Type(1.0, 0.0); }
+    static Type nonZero() { return one(); }
+
+    static const Promote & toPromote(const Type & v) { return v; }
+    static const RealPromote & toRealPromote(const Type & v) { return v; }
+    static const Type & fromPromote(const Promote & v) { return v; }
+    static const Type & fromRealPromote(const RealPromote & v) { return v; }
+};
+
+template<>
+struct NormTraits<fftw_complex>
+{
+    typedef fftw_complex Type;
+    typedef fftw_real    SquaredNormType;
+    typedef fftw_real    NormType;
+};
+
+template<class Real>
+struct NormTraits<FFTWComplex<Real> >
+{
+    typedef FFTWComplex<Real>  Type;
+    typedef typename Type::SquaredNormType   SquaredNormType;
+    typedef typename Type::NormType   NormType;
+};
+
+template <>
+struct PromoteTraits<fftw_complex, fftw_complex>
+{
+    typedef fftw_complex Promote;
+};
+
+template <>
+struct PromoteTraits<fftw_complex, double>
+{
+    typedef fftw_complex Promote;
+};
+
+template <>
+struct PromoteTraits<double, fftw_complex>
+{
+    typedef fftw_complex Promote;
+};
+
+template <class Real>
+struct PromoteTraits<FFTWComplex<Real>, FFTWComplex<Real> >
+{
+    typedef FFTWComplex<Real> Promote;
+};
+
+template <class Real>
+struct PromoteTraits<FFTWComplex<Real>, double>
+{
+    typedef FFTWComplex<Real> Promote;
+};
+
+template <class Real>
+struct PromoteTraits<double, FFTWComplex<Real> >
+{
+    typedef FFTWComplex<Real> Promote;
+};
+
+template<class T>
+struct CanSkipInitialization<std::complex<T> >
+{
+    typedef typename CanSkipInitialization<T>::type type;
+    static const bool value = type::asBool;
+};
+
+template<class Real>
+struct CanSkipInitialization<FFTWComplex<Real> >
+{
+    typedef typename CanSkipInitialization<Real>::type type;
+    static const bool value = type::asBool;
+};
+
+namespace multi_math {
+
+template <class ARG>
+struct MultiMathOperand;
+
+template <class Real>
+struct MultiMathOperand<FFTWComplex<Real> >
+{
+    typedef MultiMathOperand<FFTWComplex<Real> > AllowOverload;
+    typedef FFTWComplex<Real> result_type;
+    
+    static const int ndim = 0;
+    
+    MultiMathOperand(FFTWComplex<Real> const & v)
+    : v_(v)
+    {}
+    
+    template <class SHAPE>
+    bool checkShape(SHAPE const &) const
+    {
+        return true;
+    }
+    
+    template <class SHAPE>
+    FFTWComplex<Real> const & operator[](SHAPE const &) const
+    {
+        return v_;
+    }
+
+    void inc(unsigned int /*LEVEL*/) const
+    {}
+
+    void reset(unsigned int /*LEVEL*/) const
+    {}
+    
+    FFTWComplex<Real> const & operator*() const
+    {
+        return v_;
+    }
+    
+    FFTWComplex<Real> v_;
+};
+
+} // namespace multi_math
+
+template<class Ty>
+class FFTWAllocator
+{
+  public:
+    typedef std::size_t size_type;
+    typedef std::ptrdiff_t difference_type;
+    typedef Ty *pointer;
+    typedef const Ty *const_pointer;
+    typedef Ty& reference;
+    typedef const Ty& const_reference;
+    typedef Ty value_type;
+    
+    pointer address(reference val) const
+        { return &val; }
+        
+    const_pointer address(const_reference val) const
+        { return &val; }
+        
+    template<class Other>
+    struct rebind
+    {
+        typedef FFTWAllocator<Other> other;
+    };
+    
+    FFTWAllocator() throw()
+    {}
+    
+    template<class Other>
+    FFTWAllocator(const FFTWAllocator<Other>& right) throw()
+    {}
+    
+    template<class Other>
+    FFTWAllocator& operator=(const FFTWAllocator<Other>& right)
+    {
+        return *this;
+    }
+    
+    pointer allocate(size_type count, void * = 0)
+    {
+        return (pointer)fftw_malloc(count * sizeof(Ty));
+    }
+    
+    void deallocate(pointer ptr, size_type count)
+    {
+        fftw_free(ptr);
+    }
+    
+    void construct(pointer ptr, const Ty& val)
+    {
+        new(ptr) Ty(val);
+        
+    }
+    
+    void destroy(pointer ptr)
+    {
+        ptr->~Ty();
+    }
+    
+    size_type max_size() const throw()
+    {
+        return NumericTraits<std::ptrdiff_t>::max() / sizeof(Ty);
+    }
+};
+
+} // namespace vigra
+
+namespace std {
+
+template<class Real>
+class allocator<vigra::FFTWComplex<Real> >
+{
+  public:
+    typedef vigra::FFTWComplex<Real> value_type;
+    typedef size_t size_type;
+    typedef std::ptrdiff_t difference_type;
+    typedef value_type *pointer;
+    typedef const value_type *const_pointer;
+    typedef value_type& reference;
+    typedef const value_type& const_reference;
+
+    pointer address(reference val) const
+        { return &val; }
+        
+    const_pointer address(const_reference val) const
+        { return &val; }
+        
+    template<class Other>
+    struct rebind
+    {
+        typedef allocator<Other> other;
+    };
+    
+    allocator() throw()
+    {}
+    
+    template<class Other>
+    allocator(const allocator<Other>& right) throw()
+    {}
+    
+    template<class Other>
+    allocator& operator=(const allocator<Other>& right)
+    {
+        return *this;
+    }
+    
+    pointer allocate(size_type count, void * = 0)
+    {
+        return (pointer)fftw_malloc(count * sizeof(value_type));
+    }
+
+    void deallocate(pointer ptr, size_type /*count*/)
+    {
+        fftw_free(ptr);
+    }
+    
+    void construct(pointer ptr, const value_type& val)
+    {
+        new(ptr) value_type(val);
+        
+    }
+    
+    void destroy(pointer ptr)
+    {
+        ptr->~value_type();
+    }
+    
+    size_type max_size() const throw()
+    {
+        return vigra::NumericTraits<std::ptrdiff_t>::max() / sizeof(value_type);
+    }
+};
+
+} // namespace std
+
+namespace vigra {
+
+/********************************************************/
+/*                                                      */
+/*                    FFTWComplex Operations            */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup FFTWComplexOperators Functions for FFTWComplex
+
+    <b>\#include</b> \<vigra/fftw3.hxx\> (for FFTW 3) or<br>
+    <b>\#include</b> \<vigra/fftw.hxx\> (for deprecated FFTW 2)<br>
+
+    These functions fulfill the requirements of an Algebraic Field.
+    Return types are determined according to \ref FFTWComplexTraits.
+
+    Namespace: vigra
+    <p>
+
+ */
+//@{
+    /// equal
+template <class R>
+inline bool operator ==(FFTWComplex<R> const &a, const FFTWComplex<R> &b) {
+    return a.re() == b.re() && a.im() == b.im();
+}
+
+template <class R>
+inline bool operator ==(FFTWComplex<R> const &a,  double b) {
+    return a.re() == b && a.im() == 0.0;
+}
+
+template <class R>
+inline bool operator ==(double a, const FFTWComplex<R> &b) {
+    return a == b.re() && 0.0 == b.im();
+}
+
+    /// not equal
+template <class R>
+inline bool operator !=(FFTWComplex<R> const &a, const FFTWComplex<R> &b) {
+    return a.re() != b.re() || a.im() != b.im();
+}
+
+    /// not equal
+template <class R>
+inline bool operator !=(FFTWComplex<R> const &a,  double b) {
+    return a.re() != b || a.im() != 0.0;
+}
+
+    /// not equal
+template <class R>
+inline bool operator !=(double a, const FFTWComplex<R> &b) {
+    return a != b.re() || 0.0 != b.im();
+}
+
+    /// add-assignment
+template <class R>
+inline FFTWComplex<R> & operator +=(FFTWComplex<R> &a, const FFTWComplex<R> &b) {
+    a.re() += b.re();
+    a.im() += b.im();
+    return a;
+}
+
+    /// subtract-assignment
+template <class R>
+inline FFTWComplex<R> & operator -=(FFTWComplex<R> &a, const FFTWComplex<R> &b) {
+    a.re() -= b.re();
+    a.im() -= b.im();
+    return a;
+}
+
+    /// multiply-assignment
+template <class R>
+inline FFTWComplex<R> & operator *=(FFTWComplex<R> &a, const FFTWComplex<R> &b) {
+    typename FFTWComplex<R>::value_type t = a.re()*b.re()-a.im()*b.im();
+    a.im() = a.re()*b.im()+a.im()*b.re();
+    a.re() = t;
+    return a;
+}
+
+    /// divide-assignment
+template <class R>
+inline FFTWComplex<R> & operator /=(FFTWComplex<R> &a, const FFTWComplex<R> &b) {
+    typename FFTWComplex<R>::value_type sm = b.squaredMagnitude();
+    typename FFTWComplex<R>::value_type t = (a.re()*b.re()+a.im()*b.im())/sm;
+    a.im() = (b.re()*a.im()-a.re()*b.im())/sm;
+    a.re() = t;
+    return a;
+}
+
+    /// add-assignment with scalar double
+template <class R>
+inline FFTWComplex<R> & operator +=(FFTWComplex<R> &a, double b) {
+    a.re() += (R)b;
+    return a;
+}
+
+    /// subtract-assignment with scalar double
+template <class R>
+inline FFTWComplex<R> & operator -=(FFTWComplex<R> &a, double b) {
+    a.re() -= (R)b;
+    return a;
+}
+
+    /// multiply-assignment with scalar double
+template <class R>
+inline FFTWComplex<R> & operator *=(FFTWComplex<R> &a, double b) {
+    a.re() *= (R)b;
+    a.im() *= (R)b;
+    return a;
+}
+
+    /// divide-assignment with scalar double
+template <class R>
+inline FFTWComplex<R> & operator /=(FFTWComplex<R> &a, double b) {
+    a.re() /= (R)b;
+    a.im() /= (R)b;
+    return a;
+}
+
+    /// addition
+template <class R>
+inline FFTWComplex<R> operator +(FFTWComplex<R> a, const FFTWComplex<R> &b) {
+    a += b;
+    return a;
+}
+
+    /// right addition with scalar double
+template <class R>
+inline FFTWComplex<R> operator +(FFTWComplex<R> a, double b) {
+    a += b;
+    return a;
+}
+
+    /// left addition with scalar double
+template <class R>
+inline FFTWComplex<R> operator +(double a, FFTWComplex<R> b) {
+    b += a;
+    return b;
+}
+
+    /// subtraction
+template <class R>
+inline FFTWComplex<R> operator -(FFTWComplex<R> a, const FFTWComplex<R> &b) {
+    a -= b;
+    return a;
+}
+
+    /// right subtraction with scalar double
+template <class R>
+inline FFTWComplex<R> operator -(FFTWComplex<R> a, double b) {
+    a -= b;
+    return a;
+}
+
+    /// left subtraction with scalar double
+template <class R>
+inline FFTWComplex<R> operator -(double a, FFTWComplex<R> const & b) {
+    return (-b) += a;
+}
+
+    /// multiplication
+template <class R>
+inline FFTWComplex<R> operator *(FFTWComplex<R> a, const FFTWComplex<R> &b) {
+    a *= b;
+    return a;
+}
+
+    /// right multiplication with scalar double
+template <class R>
+inline FFTWComplex<R> operator *(FFTWComplex<R> a, double b) {
+    a *= b;
+    return a;
+}
+
+    /// left multiplication with scalar double
+template <class R>
+inline FFTWComplex<R> operator *(double a, FFTWComplex<R> b) {
+    b *= a;
+    return b;
+}
+
+    /// division
+template <class R>
+inline FFTWComplex<R> operator /(FFTWComplex<R> a, const FFTWComplex<R> &b) {
+    a /= b;
+    return a;
+}
+
+    /// right division with scalar double
+template <class R>
+inline FFTWComplex<R> operator /(FFTWComplex<R> a, double b) {
+    a /= b;
+    return a;
+}
+
+using VIGRA_CSTD::abs;
+
+    /// absolute value (= magnitude)
+template <class R>
+inline typename FFTWComplex<R>::NormType abs(const FFTWComplex<R> &a)
+{
+    return a.magnitude();
+}
+
+    /// pahse
+template <class R>
+inline R arg(const FFTWComplex<R> &a)
+{
+    return a.phase();
+}
+
+    /// real part
+template <class R>
+inline R real(const FFTWComplex<R> &a)
+{
+    return a.real();
+}
+
+    /// imaginary part
+template <class R>
+inline R imag(const FFTWComplex<R> &a)
+{
+    return a.imag();
+}
+
+    /// complex conjugate
+template <class R>
+inline FFTWComplex<R> conj(const FFTWComplex<R> &a)
+{
+    return FFTWComplex<R>(a.re(), -a.im());
+}
+
+    /// norm (= magnitude)
+template <class R>
+inline typename FFTWComplex<R>::NormType norm(const FFTWComplex<R> &a)
+{
+    return a.magnitude();
+}
+
+    /// squared norm (= squared magnitude)
+template <class R>
+inline typename FFTWComplex<R>::SquaredNormType squaredNorm(const FFTWComplex<R> &a)
+{
+    return a.squaredMagnitude();
+}
+
+#define VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION(fct) \
+template <class R> \
+inline FFTWComplex<R> fct(const FFTWComplex<R> &a) \
+{ \
+    return std::fct(reinterpret_cast<std::complex<R> const &>(a)); \
+}
+
+VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION(cos)
+VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION(cosh)
+VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION(exp)
+VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION(log)
+VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION(log10)
+VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION(sin)
+VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION(sinh)
+VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION(sqrt)
+VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION(tan)
+VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION(tanh)
+
+#undef VIGRA_DEFINE_FFTW_COMPLEX_FUNCTION
+
+template <class R>
+inline FFTWComplex<R> pow(const FFTWComplex<R> &a, int e)
+{
+    return std::pow(reinterpret_cast<std::complex<R> const &>(a), e);
+}
+
+template <class R>
+inline FFTWComplex<R> pow(const FFTWComplex<R> &a, R const & e)
+{
+    return std::pow(reinterpret_cast<std::complex<R> const &>(a), e);
+}
+
+template <class R>
+inline FFTWComplex<R> pow(const FFTWComplex<R> &a, const FFTWComplex<R> & e)
+{
+    return std::pow(reinterpret_cast<std::complex<R> const &>(a), 
+                     reinterpret_cast<std::complex<R> const &>(e));
+}
+
+template <class R>
+inline FFTWComplex<R> pow(R const & a, const FFTWComplex<R> &e)
+{
+    return std::pow(a, reinterpret_cast<std::complex<R> const &>(e));
+}
+
+//@}
+
+} // namespace vigra
+
+namespace std {
+
+template <class Real>
+ostream & operator<<(ostream & s, vigra::FFTWComplex<Real> const & v)
+{
+    s << std::complex<Real>(v.re(), v.im());
+    return s;
+}
+
+} // namespace std
+
+namespace vigra {
+
+/** \addtogroup StandardImageTypes
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                      FFTWRealImage                   */
+/*                                                      */
+/********************************************************/
+
+    /** Float (<tt>fftw_real</tt>) image.
+
+        The type <tt>fftw_real</tt> is defined as <tt>double</tt> (in FFTW 2 it used to be
+        either <tt>float</tt> or <tt>double</tt>, as specified during compilation of FFTW).
+        FFTWRealImage uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and
+        their const counterparts to access the data.
+
+        <b>\#include</b> \<vigra/fftw3.hxx\> (for FFTW 3) or<br>
+        <b>\#include</b> \<vigra/fftw.hxx\> (for deprecated FFTW 2)<br>
+        Namespace: vigra
+    */
+typedef BasicImage<fftw_real> FFTWRealImage;
+
+/********************************************************/
+/*                                                      */
+/*                     FFTWComplexImage                 */
+/*                                                      */
+/********************************************************/
+
+template<class R>
+struct IteratorTraits<
+        BasicImageIterator<FFTWComplex<R>, FFTWComplex<R> **> >
+{
+    typedef FFTWComplex<R> Type;
+    typedef BasicImageIterator<Type, Type **>       Iterator;
+    typedef Iterator                                iterator;
+    typedef BasicImageIterator<Type, Type **>       mutable_iterator;
+    typedef ConstBasicImageIterator<Type, Type **>  const_iterator;
+    typedef typename iterator::iterator_category    iterator_category;
+    typedef typename iterator::value_type           value_type;
+    typedef typename iterator::reference            reference;
+    typedef typename iterator::index_reference      index_reference;
+    typedef typename iterator::pointer              pointer;
+    typedef typename iterator::difference_type      difference_type;
+    typedef typename iterator::row_iterator         row_iterator;
+    typedef typename iterator::column_iterator      column_iterator;
+    typedef VectorAccessor<Type>                    default_accessor;
+    typedef VectorAccessor<Type>                    DefaultAccessor;
+    typedef VigraTrueType                           hasConstantStrides;
+};
+
+template<class R>
+struct IteratorTraits<
+        ConstBasicImageIterator<FFTWComplex<R>, FFTWComplex<R> **> >
+{
+    typedef FFTWComplex<R> Type;
+    typedef ConstBasicImageIterator<Type, Type **> Iterator;
+    typedef Iterator                               iterator;
+    typedef BasicImageIterator<Type, Type **>      mutable_iterator;
+    typedef ConstBasicImageIterator<Type, Type **> const_iterator;
+    typedef typename iterator::iterator_category   iterator_category;
+    typedef typename iterator::value_type          value_type;
+    typedef typename iterator::reference           reference;
+    typedef typename iterator::index_reference     index_reference;
+    typedef typename iterator::pointer             pointer;
+    typedef typename iterator::difference_type     difference_type;
+    typedef typename iterator::row_iterator        row_iterator;
+    typedef typename iterator::column_iterator     column_iterator;
+    typedef VectorAccessor<Type>                   default_accessor;
+    typedef VectorAccessor<Type>                   DefaultAccessor;
+    typedef VigraTrueType                          hasConstantStrides;
+};
+
+    /** Complex (FFTWComplex) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and
+        their const counterparts to access the data.
+
+        <b>\#include</b> \<vigra/fftw3.hxx\> (for FFTW 3) or<br>
+        <b>\#include</b> \<vigra/fftw.hxx\> (for deprecated FFTW 2)<br>
+        Namespace: vigra
+    */
+typedef BasicImage<FFTWComplex<> > FFTWComplexImage;
+
+//@}
+
+/********************************************************/
+/*                                                      */
+/*                  FFTWComplex-Accessors               */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup DataAccessors
+*/
+//@{
+/** \defgroup FFTWComplexAccessors Accessors for FFTWComplex
+
+    Encapsulate access to pixels of type FFTWComplex
+*/
+//@{
+    /** Encapsulate access to the the real part of a complex number.
+
+    <b>\#include</b> \<vigra/fftw3.hxx\> (for FFTW 3) or<br>
+    <b>\#include</b> \<vigra/fftw.hxx\> (for deprecated FFTW 2)<br>
+    Namespace: vigra
+    */
+template <class Real = double>
+class FFTWRealAccessor
+{
+  public:
+
+        /// The accessor's value type.
+    typedef Real value_type;
+
+        /// Read real part at iterator position.
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const {
+        return (*i).re();
+    }
+
+        /// Read real part at offset from iterator position.
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE d) const {
+        return i[d].re();
+    }
+
+        /// Write real part at iterator position from a scalar.
+    template <class ITERATOR>
+    void set(value_type const & v, ITERATOR const & i) const {
+        (*i).re()= v;
+    }
+
+        /// Write real part at offset from iterator position from a scalar.
+    template <class ITERATOR, class DIFFERENCE>
+    void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const {
+        i[d].re()= v;
+    }
+
+        /// Write real part at iterator position into a scalar.
+    template <class R, class ITERATOR>
+    void set(FFTWComplex<R> const & v, ITERATOR const & i) const {
+        *i = v.re();
+    }
+
+        /// Write real part at offset from iterator position into a scalar.
+    template <class R, class ITERATOR, class DIFFERENCE>
+    void set(FFTWComplex<R> const & v, ITERATOR const & i, DIFFERENCE d) const {
+        i[d] = v.re();
+    }
+};
+
+    /** Encapsulate access to the the imaginary part of a complex number.
+
+    <b>\#include</b> \<vigra/fftw3.hxx\> (for FFTW 3) or<br>
+    <b>\#include</b> \<vigra/fftw.hxx\> (for deprecated FFTW 2)<br>
+    Namespace: vigra
+    */
+template <class Real = double>
+class FFTWImaginaryAccessor
+{
+  public:
+        /// The accessor's value type.
+    typedef Real value_type;
+
+        /// Read imaginary part at iterator position.
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const {
+        return (*i).im();
+    }
+
+        /// Read imaginary part at offset from iterator position.
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE d) const {
+        return i[d].im();
+    }
+
+        /// Write imaginary part at iterator position from a scalar.
+    template <class ITERATOR>
+    void set(value_type const & v, ITERATOR const & i) const {
+        (*i).im()= v;
+    }
+
+        /// Write imaginary part at offset from iterator position from a scalar.
+    template <class ITERATOR, class DIFFERENCE>
+    void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const {
+        i[d].im()= v;
+    }
+
+        /// Write imaginary part at iterator position into a scalar.
+    template <class R, class ITERATOR>
+    void set(FFTWComplex<R> const & v, ITERATOR const & i) const {
+        *i = v.im();
+    }
+
+        /// Write imaginary part at offset from iterator position into a scalar.
+    template <class R, class ITERATOR, class DIFFERENCE>
+    void set(FFTWComplex<R> const & v, ITERATOR const & i, DIFFERENCE d) const {
+        i[d] = v.im();
+    }
+};
+
+    /** Write a real number into a complex one. The imaginary part is set
+        to 0.
+
+    <b>\#include</b> \<vigra/fftw3.hxx\> (for FFTW 3) or<br>
+    <b>\#include</b> \<vigra/fftw.hxx\> (for deprecated FFTW 2)<br>
+    Namespace: vigra
+    */
+template <class Real = double>
+class FFTWWriteRealAccessor
+: public FFTWRealAccessor<Real>
+{
+  public:
+        /// The accessor's value type.
+    typedef Real value_type;
+
+        /** Write real number at iterator position. Set imaginary part
+            to 0.
+        */
+    template <class ITERATOR>
+    void set(value_type const & v, ITERATOR const & i) const {
+        (*i).re()= v;
+        (*i).im()= 0;
+    }
+
+        /** Write real number at offset from iterator position. Set imaginary part
+            to 0.
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const {
+        i[d].re()= v;
+        i[d].im()= 0;
+    }
+};
+
+    /** Calculate squared magnitude of complex number on the fly.
+
+    <b>\#include</b> \<vigra/fftw3.hxx\> (for FFTW 3) or<br>
+    Namespace: vigra
+    */
+template <class Real = double>
+class FFTWSquaredMagnitudeAccessor
+{
+  public:
+        /// The accessor's value type.
+    typedef Real value_type;
+
+        /// Read squared magnitude at iterator position.
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const {
+        return (*i).squaredMagnitude();
+    }
+
+        /// Read squared magnitude at offset from iterator position.
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE d) const {
+        return (i[d]).squaredMagnitude();
+    }
+};
+
+    /** Calculate magnitude of complex number on the fly.
+
+    <b>\#include</b> \<vigra/fftw3.hxx\> (for FFTW 3) or<br>
+    <b>\#include</b> \<vigra/fftw.hxx\> (for deprecated FFTW 2)<br>
+    Namespace: vigra
+    */
+template <class Real = double>
+class FFTWMagnitudeAccessor
+{
+  public:
+        /// The accessor's value type.
+    typedef Real value_type;
+
+        /// Read magnitude at iterator position.
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const {
+        return (*i).magnitude();
+    }
+
+        /// Read magnitude at offset from iterator position.
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE d) const {
+        return (i[d]).magnitude();
+    }
+};
+
+    /** Calculate phase of complex number on the fly.
+
+    <b>\#include</b> \<vigra/fftw3.hxx\> (for FFTW 3) or<br>
+    <b>\#include</b> \<vigra/fftw.hxx\> (for deprecated FFTW 2)<br>
+    Namespace: vigra
+    */
+template <class Real = double>
+class FFTWPhaseAccessor
+{
+  public:
+        /// The accessor's value type.
+    typedef Real value_type;
+
+        /// Read phase at iterator position.
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const {
+        return (*i).phase();
+    }
+
+        /// Read phase at offset from iterator position.
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE d) const {
+        return (i[d]).phase();
+    }
+};
+
+//@}
+//@}
+
+/********************************************************/
+/*                                                      */
+/*                    Fourier Transform                 */
+/*                                                      */
+/********************************************************/
+
+/* \addtogroup FourierTransform Fast Fourier Transform
+
+    This documentation describes the VIGRA interface to FFTW version 3. The interface
+    to the old FFTW version 2 (file "vigra/fftw.hxx") is deprecated.
+
+    VIGRA uses the <a href="http://www.fftw.org/">FFTW Fast Fourier
+    Transform</a> package to perform Fourier transformations. VIGRA
+    provides a wrapper for FFTW's complex number type (FFTWComplex),
+    but FFTW's functions are used verbatim. If the image is stored as
+    a FFTWComplexImage, the simplest call to an FFT function is like this:
+
+    \code
+    vigra::FFTWComplexImage spatial(width,height), fourier(width,height);
+    ... // fill image with data
+
+    // create a plan with estimated performance optimization
+    fftw_plan forwardPlan = fftw_plan_dft_2d(height, width,
+                                (fftw_complex *)spatial.begin(), (fftw_complex *)fourier.begin(),
+                                FFTW_FORWARD, FFTW_ESTIMATE );
+    // calculate FFT (this can be repeated as often as needed,
+    //                with fresh data written into the source array)
+    fftw_execute(forwardPlan);
+
+    // release the plan memory
+    fftw_destroy_plan(forwardPlan);
+
+    // likewise for the inverse transform
+    fftw_plan backwardPlan = fftw_plan_dft_2d(height, width,
+                                 (fftw_complex *)fourier.begin(), (fftw_complex *)spatial.begin(),
+                                 FFTW_BACKWARD, FFTW_ESTIMATE);
+    fftw_execute(backwardPlan);
+    fftw_destroy_plan(backwardPlan);
+
+    // do not forget to normalize the result according to the image size
+    transformImage(srcImageRange(spatial), destImage(spatial),
+                   std::bind1st(std::multiplies<FFTWComplex>(), 1.0 / width / height));
+    \endcode
+
+    Note that in the creation of a plan, the height must be given
+    first. Note also that <TT>spatial.begin()</TT> may only be passed
+    to <TT>fftw_plan_dft_2d</TT> if the transform shall be applied to the
+    entire image. When you want to restrict operation to an ROI, you
+    can create a copy of the ROI in an image of appropriate size, or
+    you may use the Guru interface to FFTW.
+
+    More information on using FFTW can be found <a href="http://www.fftw.org/doc/">here</a>.
+
+    FFTW produces fourier images that have the DC component (the
+    origin of the Fourier space) in the upper left corner. Often, one
+    wants the origin in the center of the image, so that frequencies
+    always increase towards the border of the image. This can be
+    achieved by calling \ref moveDCToCenter(). The inverse
+    transformation is done by \ref moveDCToUpperLeft().
+
+    <b>\#include</b> \<vigra/fftw3.hxx\><br>
+    Namespace: vigra
+*/
+
+/** \addtogroup FourierTransform Fast Fourier Transform
+
+    VIGRA provides a powerful C++ API for the popular <a href="http://www.fftw.org/">FFTW library</a>
+    for fast Fourier transforms. There are two versions of the API: an older one based on image 
+    iterators (and therefore restricted to 2D) and a new one based on \ref MultiArrayView that
+    works for arbitrary dimensions. In addition, the functions \ref convolveFFT() and 
+    \ref applyFourierFilter() provide an easy-to-use interface for FFT-based convolution,
+    a major application of Fourier transforms.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                     moveDCToCenter                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Rearrange the quadrants of a Fourier image so that the origin is
+          in the image center.
+
+    FFTW produces fourier images where the DC component (origin of
+    fourier space) is located in the upper left corner of the
+    image. The quadrants are placed like this (using a 4x4 image for
+    example):
+
+    \code
+            DC 4 3 3
+             4 4 3 3
+             1 1 2 2
+             1 1 2 2
+    \endcode
+
+    After applying the function, the quadrants are at their usual places:
+
+    \code
+            2 2  1 1
+            2 2  1 1
+            3 3 DC 4
+            3 3  4 4
+    \endcode
+
+    This transformation can be reversed by \ref moveDCToUpperLeft().
+    Note that the 2D versions of this transformation must not be executed in place - input
+    and output images must be different. In contrast, the nD version (with MultiArrayView
+    argument) always works in-place.
+
+    <b> Declarations:</b>
+
+    use MultiArrayView (this works in-place, with arbitrary dimension N):
+    \code
+    namespace vigra {
+        template <unsigned int N, class T, class Stride>
+        void moveDCToCenter(MultiArrayView<N, T, Stride> a);
+    }
+    \endcode
+
+    pass iterators explicitly (2D only, not in-place):
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void moveDCToCenter(SrcImageIterator src_upperleft,
+                               SrcImageIterator src_lowerright, SrcAccessor sa,
+                               DestImageIterator dest_upperleft, DestAccessor da);
+    }
+    \endcode
+
+
+    use argument objects in conjunction with \ref ArgumentObjectFactories (2D only, not in-place):
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void moveDCToCenter(
+            triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+            pair<DestImageIterator, DestAccessor> dest);
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/fftw3.hxx\> (for 2D variants) <br>
+    <b>\#include</b> \<vigra/multi_fft.hxx\> (for nD variants) <br>
+    Namespace: vigra
+
+    \code
+    vigra::FFTWComplexImage spatial(width,height), fourier(width,height);
+    ... // fill image with data
+
+    // create a plan with estimated performance optimization
+    fftw_plan forwardPlan = fftw_plan_dft_2d(height, width,
+                                (fftw_complex *)spatial.begin(), (fftw_complex *)fourier.begin(),
+                                FFTW_FORWARD, FFTW_ESTIMATE );
+    // calculate FFT
+    fftw_execute(forwardPlan);
+
+    vigra::FFTWComplexImage rearrangedFourier(width, height);
+    moveDCToCenter(srcImageRange(fourier), destImage(rearrangedFourier));
+
+    // delete the plan
+    fftw_destroy_plan(forwardPlan);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void moveDCToCenter)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void moveDCToCenter(SrcImageIterator src_upperleft,
+                               SrcImageIterator src_lowerright, SrcAccessor sa,
+                               DestImageIterator dest_upperleft, DestAccessor da)
+{
+    int w = int(src_lowerright.x - src_upperleft.x);
+    int h = int(src_lowerright.y - src_upperleft.y);
+    int w1 = w/2;
+    int h1 = h/2;
+    int w2 = (w+1)/2;
+    int h2 = (h+1)/2;
+
+    // 2. Quadrant  zum 4.
+    copyImage(srcIterRange(src_upperleft,
+                           src_upperleft  + Diff2D(w2, h2), sa),
+              destIter    (dest_upperleft + Diff2D(w1, h1), da));
+
+    // 4. Quadrant zum 2.
+    copyImage(srcIterRange(src_upperleft + Diff2D(w2, h2),
+                           src_lowerright, sa),
+              destIter    (dest_upperleft, da));
+
+    // 1. Quadrant zum 3.
+    copyImage(srcIterRange(src_upperleft  + Diff2D(w2, 0),
+                           src_upperleft  + Diff2D(w,  h2), sa),
+              destIter    (dest_upperleft + Diff2D(0,  h1), da));
+
+    // 3. Quadrant zum 1.
+    copyImage(srcIterRange(src_upperleft  + Diff2D(0,  h2),
+                           src_upperleft  + Diff2D(w2, h), sa),
+              destIter    (dest_upperleft + Diff2D(w1, 0), da));
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void moveDCToCenter(
+    triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+    pair<DestImageIterator, DestAccessor> dest)
+{
+    moveDCToCenter(src.first, src.second, src.third,
+                          dest.first, dest.second);
+}
+
+/********************************************************/
+/*                                                      */
+/*                   moveDCToUpperLeft                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Rearrange the quadrants of a Fourier image so that the origin is
+          in the image's upper left.
+
+     This function is the inversion of \ref moveDCToCenter(). See there
+     for a detailed description and usage examples.
+
+     <b> Declarations:</b>
+
+    use MultiArrayView (this works in-place, with arbitrary dimension N):
+    \code
+    namespace vigra {
+        template <unsigned int N, class T, class Stride>
+        void moveDCToUpperLeft(MultiArrayView<N, T, Stride> a);
+    }
+    \endcode
+
+    pass iterators explicitly (2D only, not in-place):
+     \code
+        namespace vigra {
+            template <class SrcImageIterator, class SrcAccessor,
+                      class DestImageIterator, class DestAccessor>
+            void moveDCToUpperLeft(SrcImageIterator src_upperleft,
+                                   SrcImageIterator src_lowerright, SrcAccessor sa,
+                                   DestImageIterator dest_upperleft, DestAccessor da);
+        }
+     \endcode
+
+
+     use argument objects in conjunction with \ref ArgumentObjectFactories (2D only, not in-place):
+     \code
+        namespace vigra {
+            template <class SrcImageIterator, class SrcAccessor,
+                      class DestImageIterator, class DestAccessor>
+            void moveDCToUpperLeft(
+                triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                pair<DestImageIterator, DestAccessor> dest);
+        }
+     \endcode
+*/
+doxygen_overloaded_function(template <...> void moveDCToUpperLeft)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void moveDCToUpperLeft(SrcImageIterator src_upperleft,
+                               SrcImageIterator src_lowerright, SrcAccessor sa,
+                               DestImageIterator dest_upperleft, DestAccessor da)
+{
+    int w = int(src_lowerright.x - src_upperleft.x);
+    int h = int(src_lowerright.y - src_upperleft.y);
+    int w2 = w/2;
+    int h2 = h/2;
+    int w1 = (w+1)/2;
+    int h1 = (h+1)/2;
+
+    // 2. Quadrant  zum 4.
+    copyImage(srcIterRange(src_upperleft,
+                           src_upperleft  + Diff2D(w2, h2), sa),
+              destIter    (dest_upperleft + Diff2D(w1, h1), da));
+
+    // 4. Quadrant zum 2.
+    copyImage(srcIterRange(src_upperleft + Diff2D(w2, h2),
+                           src_lowerright, sa),
+              destIter    (dest_upperleft, da));
+
+    // 1. Quadrant zum 3.
+    copyImage(srcIterRange(src_upperleft  + Diff2D(w2, 0),
+                           src_upperleft  + Diff2D(w,  h2), sa),
+              destIter    (dest_upperleft + Diff2D(0,  h1), da));
+
+    // 3. Quadrant zum 1.
+    copyImage(srcIterRange(src_upperleft  + Diff2D(0,  h2),
+                           src_upperleft  + Diff2D(w2, h), sa),
+              destIter    (dest_upperleft + Diff2D(w1, 0), da));
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void moveDCToUpperLeft(
+    triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+    pair<DestImageIterator, DestAccessor> dest)
+{
+    moveDCToUpperLeft(src.first, src.second, src.third,
+                                          dest.first, dest.second);
+}
+
+namespace detail {
+
+template <class T>
+void
+fourierTransformImpl(FFTWComplexImage::const_traverser sul,
+                     FFTWComplexImage::const_traverser slr, FFTWComplexImage::ConstAccessor src,
+                     FFTWComplexImage::traverser dul, FFTWComplexImage::Accessor dest, T sign)
+{
+    int w = int(slr.x - sul.x);
+    int h = int(slr.y - sul.y);
+
+    FFTWComplexImage sworkImage, dworkImage;
+
+    fftw_complex * srcPtr = (fftw_complex *)(&*sul);
+    fftw_complex * destPtr = (fftw_complex *)(&*dul);
+
+    // test for right memory layout (fftw expects a 2*width*height floats array)
+    if (h > 1 && &(*(sul + Diff2D(w, 0))) != &(*(sul + Diff2D(0, 1))))
+    {
+        sworkImage.resize(w, h);
+        copyImage(srcIterRange(sul, slr, src), destImage(sworkImage));
+        srcPtr = (fftw_complex *)(&(*sworkImage.upperLeft()));
+    }
+    if (h > 1 && &(*(dul + Diff2D(w, 0))) != &(*(dul + Diff2D(0, 1))))
+    {
+        dworkImage.resize(w, h);
+        destPtr = (fftw_complex *)(&(*dworkImage.upperLeft()));
+    }
+
+    fftw_plan plan = fftw_plan_dft_2d(h, w, srcPtr, destPtr, sign, FFTW_ESTIMATE );
+    fftw_execute(plan);
+    fftw_destroy_plan(plan);
+
+    if (h > 1 && &(*(dul + Diff2D(w, 0))) != &(*(dul + Diff2D(0, 1))))
+    {
+        copyImage(srcImageRange(dworkImage), destIter(dul, dest));
+    }
+}
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*                   fourierTransform                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Compute forward and inverse Fourier transforms.
+
+    The array referring to the spatial domain (i.e. the input in a forward transform, 
+    and the output in an inverse transform) may be scalar or complex. The array representing
+    the frequency domain (i.e. output for forward transform, input for inverse transform) 
+    must always be complex.
+    
+    The new implementations (those using MultiArrayView arguments) perform a normalized transform, 
+    whereas the old ones (using 2D iterators or argument objects) perform an un-normalized 
+    transform (i.e. the result of the inverse transform is scaled by the number of pixels).
+
+    In general, input and output arrays must have the same shape, with the exception of the 
+    special <a href="http://www.fftw.org/doc/Multi_002dDimensional-DFTs-of-Real-Data.html">R2C 
+    and C2R modes</a> defined by FFTW.
+    
+    The R2C transform reduces the redundancy in the Fourier representation of a real-valued signal:
+    Since the Fourier representation of a real signal is symmetric, about half of the Fourier coefficients 
+    can simply be dropped. By convention, this reduction is applied to the first (innermost) dimension, 
+    such that <tt>fourier.shape(0) == spatial.shape(0)/2 + 1</tt> holds. The correct frequency domain
+    shape can be conveniently computed by means of the function \ref fftwCorrespondingShapeR2C().
+    
+    Note that your program must always link against <tt>libfftw3</tt>. If you want to compute Fourier 
+    transforms for <tt>float</tt> or <tt>long double</tt> arrays, you must <i>additionally</i> link against <tt>libfftw3f</tt> and <tt>libfftw3l</tt> respectively. (Old-style functions only support <tt>double</tt>).
+    
+    The Fourier transform functions internally create <a href="http://www.fftw.org/doc/Using-Plans.html">FFTW plans</a>
+    which control the algorithm details. The plans are creates with the flag <tt>FFTW_ESTIMATE</tt>, i.e.
+    optimal settings are guessed or read from saved "wisdom" files. If you need more control over planning,
+    you can use the class \ref FFTWPlan.
+    
+    <b> Declarations:</b>
+
+    use complex-valued MultiArrayView arguments (this works for arbitrary dimension N):
+    \code
+    namespace vigra {
+        template <unsigned int N, class Real, class C1, class C2>
+        void 
+        fourierTransform(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                         MultiArrayView<N, FFTWComplex<Real>, C2> out);
+
+        template <unsigned int N, class Real, class C1, class C2>
+        void 
+        fourierTransformInverse(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                                MultiArrayView<N, FFTWComplex<Real>, C2> out);
+    }
+    \endcode
+
+    use real-valued MultiArrayView in the spatial domain, complex-valued MultiArrayView 
+    in the frequency domain (this works for arbitrary dimension N, and also supports
+    the R2C and C2R transform, depending on the array shape in the frequency domain):
+    \code
+    namespace vigra {
+        template <unsigned int N, class Real, class C1, class C2>
+        void 
+        fourierTransform(MultiArrayView<N, Real, C1> in, 
+                         MultiArrayView<N, FFTWComplex<Real>, C2> out);
+
+        template <unsigned int N, class Real, class C1, class C2>
+        void 
+        fourierTransformInverse(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                                MultiArrayView<N, Real, C2> out);
+    }
+    \endcode
+
+    pass iterators explicitly (2D only, double only):
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor>
+        void fourierTransform(SrcImageIterator srcUpperLeft,
+                              SrcImageIterator srcLowerRight, SrcAccessor src,
+                              FFTWComplexImage::traverser destUpperLeft, FFTWComplexImage::Accessor dest);
+
+        void
+        fourierTransformInverse(FFTWComplexImage::const_traverser sul,
+                                FFTWComplexImage::const_traverser slr, FFTWComplexImage::ConstAccessor src,
+                                FFTWComplexImage::traverser dul, FFTWComplexImage::Accessor dest)
+    }
+    \endcode
+
+    use argument objects in conjunction with \ref ArgumentObjectFactories (2D only, double only):
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor>
+        void fourierTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                              pair<FFTWComplexImage::traverser, FFTWComplexImage::Accessor> dest);
+
+        void
+        fourierTransformInverse(triple<FFTWComplexImage::const_traverser,
+                                       FFTWComplexImage::const_traverser, FFTWComplexImage::ConstAccessor> src,
+                                pair<FFTWComplexImage::traverser, FFTWComplexImage::Accessor> dest);
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/fftw3.hxx\> (old-style 2D variants)<br>
+    <b>\#include</b> \<vigra/multi_fft.hxx\> (new-style nD variants)<br>
+    Namespace: vigra
+
+    old-style example (using FFTWComplexImage):
+    \code
+    // compute complex Fourier transform of a real image, old-style implementation
+    vigra::DImage src(w, h);
+    vigra::FFTWComplexImage fourier(w, h);
+
+    fourierTransform(srcImageRange(src), destImage(fourier));
+
+    // compute inverse Fourier transform
+    // note that both source and destination image must be of type vigra::FFTWComplexImage
+    vigra::FFTWComplexImage inverseFourier(w, h);
+
+    fourierTransformInverse(srcImageRange(fourier), destImage(inverseFourier));
+    \endcode
+    
+    new-style examples (using MultiArray):
+    \code
+    // compute Fourier transform of a real array, using the R2C algorithm
+    MultiArray<2, double> src(Shape2(w, h));
+    MultiArray<2, FFTWComplex<double> > fourier(fftwCorrespondingShapeR2C(src.shape()));
+
+    fourierTransform(src, fourier);
+
+    // compute inverse Fourier transform, using the C2R algorithm
+    MultiArray<2, double> dest(src.shape());
+    fourierTransformInverse(fourier, dest);
+    \endcode
+
+    \code
+    // compute Fourier transform of a real array with standard algorithm
+    MultiArray<2, double> src(Shape2(w, h));
+    MultiArray<2, FFTWComplex<double> > fourier(src.shape());
+
+    fourierTransform(src, fourier);
+
+    // compute inverse Fourier transform, using the C2R algorithm
+    MultiArray<2, double> dest(src.shape());
+    fourierTransformInverse(fourier, dest);
+    \endcode
+    Complex input arrays are handled in the same way. 
+    
+*/
+doxygen_overloaded_function(template <...> void fourierTransform)
+
+inline void
+fourierTransform(FFTWComplexImage::const_traverser sul,
+                 FFTWComplexImage::const_traverser slr, FFTWComplexImage::ConstAccessor src,
+                 FFTWComplexImage::traverser dul, FFTWComplexImage::Accessor dest)
+{
+    detail::fourierTransformImpl(sul, slr, src, dul, dest, FFTW_FORWARD);
+}
+
+template <class SrcImageIterator, class SrcAccessor>
+void fourierTransform(SrcImageIterator srcUpperLeft,
+                      SrcImageIterator srcLowerRight, SrcAccessor sa,
+                      FFTWComplexImage::traverser destUpperLeft, FFTWComplexImage::Accessor da)
+{
+    // copy real input images into a complex one...
+    int w= srcLowerRight.x - srcUpperLeft.x;
+    int h= srcLowerRight.y - srcUpperLeft.y;
+
+    FFTWComplexImage workImage(w, h);
+    copyImage(srcIterRange(srcUpperLeft, srcLowerRight, sa),
+              destImage(workImage, FFTWWriteRealAccessor<>()));
+
+    // ...and call the complex -> complex version of the algorithm
+    FFTWComplexImage const & cworkImage = workImage;
+    fourierTransform(cworkImage.upperLeft(), cworkImage.lowerRight(), cworkImage.accessor(),
+                     destUpperLeft, da);
+}
+
+template <class SrcImageIterator, class SrcAccessor>
+inline
+void fourierTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                      pair<FFTWComplexImage::traverser, FFTWComplexImage::Accessor> dest)
+{
+    fourierTransform(src.first, src.second, src.third, dest.first, dest.second);
+}
+
+/** \brief Compute inverse Fourier transforms.
+
+    See \ref fourierTransform() for details.
+*/
+doxygen_overloaded_function(template <...> void fourierTransformInverse)
+
+inline void
+fourierTransformInverse(FFTWComplexImage::const_traverser sul,
+                        FFTWComplexImage::const_traverser slr, FFTWComplexImage::ConstAccessor src,
+                        FFTWComplexImage::traverser dul, FFTWComplexImage::Accessor dest)
+{
+    detail::fourierTransformImpl(sul, slr, src, dul, dest, FFTW_BACKWARD);
+}
+
+template <class DestImageIterator, class DestAccessor>
+void fourierTransformInverse(FFTWComplexImage::const_traverser sul,
+                             FFTWComplexImage::const_traverser slr, FFTWComplexImage::ConstAccessor src,
+                             DestImageIterator dul, DestAccessor dest)
+{
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    FFTWComplexImage workImage(w, h);
+    fourierTransformInverse(sul, slr, src, workImage.upperLeft(), workImage.accessor());
+    copyImage(srcImageRange(workImage), destIter(dul, dest));
+}
+
+
+template <class DestImageIterator, class DestAccessor>
+inline void
+fourierTransformInverse(triple<FFTWComplexImage::const_traverser,
+                               FFTWComplexImage::const_traverser, FFTWComplexImage::ConstAccessor> src,
+                        pair<DestImageIterator, DestAccessor> dest)
+{
+    fourierTransformInverse(src.first, src.second, src.third, dest.first, dest.second);
+}
+
+
+
+/********************************************************/
+/*                                                      */
+/*                   applyFourierFilter                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply a filter (defined in the frequency domain) to an image.
+
+    After transferring the image into the frequency domain, it is
+    multiplied pixel-wise with the filter and transformed back. The
+    result is put into the given destination image which must have the right size.
+    The result will be normalized to compensate for the two FFTs.
+
+    If the destination image is scalar, only the real part of the result image is
+    retained. In this case, you are responsible for choosing a filter image
+    which ensures a zero imaginary part of the result (e.g. use a real, even symmetric
+    filter image, or a purely imaginary, odd symmetric one).
+
+    The DC entry of the filter must be in the upper left, which is the
+    position where FFTW expects it (see \ref moveDCToUpperLeft()).
+    
+    See also \ref convolveFFT() for corresponding functionality on the basis of the
+    \ref MultiArrayView interface.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class FilterImageIterator, class FilterAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void applyFourierFilter(SrcImageIterator srcUpperLeft,
+                                SrcImageIterator srcLowerRight, SrcAccessor sa,
+                                FilterImageIterator filterUpperLeft, FilterAccessor fa,
+                                DestImageIterator destUpperLeft, DestAccessor da);
+    }
+    \endcode
+
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class FilterImageIterator, class FilterAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void applyFourierFilter(SrcImageIterator srcUpperLeft,
+                                SrcImageIterator srcLowerRight, SrcAccessor sa,
+                                FilterImageIterator filterUpperLeft, FilterAccessor fa,
+                                DestImageIterator destUpperLeft, DestAccessor da);
+    }
+    \endcode
+
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class FilterImageIterator, class FilterAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void applyFourierFilter(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                                pair<FilterImageIterator, FilterAccessor> filter,
+                                pair<DestImageIterator, DestAccessor> dest);
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/fftw3.hxx\><br>
+    Namespace: vigra
+
+    \code
+    // create a Gaussian filter in Fourier space
+    vigra::FImage gaussFilter(w, h), filter(w, h);
+    for(int y=0; y<h; ++y)
+        for(int x=0; x<w; ++x)
+        {
+            xx = float(x - w / 2) / w;
+            yy = float(y - h / 2) / h;
+
+            gaussFilter(x,y) = std::exp(-(xx*xx + yy*yy) / 2.0 * scale);
+        }
+
+    // applyFourierFilter() expects the filter's DC in the upper left
+    moveDCToUpperLeft(srcImageRange(gaussFilter), destImage(filter));
+
+    vigra::FFTWComplexImage result(w, h);
+
+    vigra::applyFourierFilter(srcImageRange(image), srcImage(filter), result);
+    \endcode
+
+    For inspection of the result, \ref FFTWMagnitudeAccessor might be
+    useful. If you want to apply the same filter repeatedly, it may be more
+    efficient to use the FFTW functions directly with FFTW plans optimized
+    for good performance.
+*/
+doxygen_overloaded_function(template <...> void applyFourierFilter)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+void applyFourierFilter(SrcImageIterator srcUpperLeft,
+                        SrcImageIterator srcLowerRight, SrcAccessor sa,
+                        FilterImageIterator filterUpperLeft, FilterAccessor fa,
+                        DestImageIterator destUpperLeft, DestAccessor da)
+{
+    // copy real input images into a complex one...
+    int w = int(srcLowerRight.x - srcUpperLeft.x);
+    int h = int(srcLowerRight.y - srcUpperLeft.y);
+
+    FFTWComplexImage workImage(w, h);
+    copyImage(srcIterRange(srcUpperLeft, srcLowerRight, sa),
+              destImage(workImage, FFTWWriteRealAccessor<>()));
+
+    // ...and call the impl
+    FFTWComplexImage const & cworkImage = workImage;
+    applyFourierFilterImpl(cworkImage.upperLeft(), cworkImage.lowerRight(), cworkImage.accessor(),
+                           filterUpperLeft, fa,
+                           destUpperLeft, da);
+}
+
+template <class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+inline
+void applyFourierFilter(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor sa,
+    FilterImageIterator filterUpperLeft, FilterAccessor fa,
+    DestImageIterator destUpperLeft, DestAccessor da)
+{
+    int w = srcLowerRight.x - srcUpperLeft.x;
+    int h = srcLowerRight.y - srcUpperLeft.y;
+
+    // test for right memory layout (fftw expects a 2*width*height floats array)
+    if (&(*(srcUpperLeft + Diff2D(w, 0))) == &(*(srcUpperLeft + Diff2D(0, 1))))
+        applyFourierFilterImpl(srcUpperLeft, srcLowerRight, sa,
+                               filterUpperLeft, fa,
+                               destUpperLeft, da);
+    else
+    {
+        FFTWComplexImage workImage(w, h);
+        copyImage(srcIterRange(srcUpperLeft, srcLowerRight, sa),
+                  destImage(workImage));
+
+        FFTWComplexImage const & cworkImage = workImage;
+        applyFourierFilterImpl(cworkImage.upperLeft(), cworkImage.lowerRight(), cworkImage.accessor(),
+                               filterUpperLeft, fa,
+                               destUpperLeft, da);
+    }
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+inline
+void applyFourierFilter(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                        pair<FilterImageIterator, FilterAccessor> filter,
+                        pair<DestImageIterator, DestAccessor> dest)
+{
+    applyFourierFilter(src.first, src.second, src.third,
+                       filter.first, filter.second,
+                       dest.first, dest.second);
+}
+
+template <class FilterImageIterator, class FilterAccessor,
+          class DestImageIterator, class DestAccessor>
+void applyFourierFilterImpl(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor,
+    FilterImageIterator filterUpperLeft, FilterAccessor fa,
+    DestImageIterator destUpperLeft, DestAccessor da)
+{
+    int w = int(srcLowerRight.x - srcUpperLeft.x);
+    int h = int(srcLowerRight.y - srcUpperLeft.y);
+
+    FFTWComplexImage complexResultImg(srcLowerRight - srcUpperLeft);
+
+    // FFT from srcImage to complexResultImg
+    fftw_plan forwardPlan=
+        fftw_plan_dft_2d(h, w, (fftw_complex *)&(*srcUpperLeft),
+                               (fftw_complex *)complexResultImg.begin(),
+                               FFTW_FORWARD, FFTW_ESTIMATE );
+    fftw_execute(forwardPlan);
+    fftw_destroy_plan(forwardPlan);
+
+    // convolve in freq. domain (in complexResultImg)
+    combineTwoImages(srcImageRange(complexResultImg), srcIter(filterUpperLeft, fa),
+                     destImage(complexResultImg), std::multiplies<FFTWComplex<> >());
+
+    // FFT back into spatial domain (inplace in complexResultImg)
+    fftw_plan backwardPlan=
+        fftw_plan_dft_2d(h, w, (fftw_complex *)complexResultImg.begin(),
+                               (fftw_complex *)complexResultImg.begin(),
+                               FFTW_BACKWARD, FFTW_ESTIMATE);
+    fftw_execute(backwardPlan);
+    fftw_destroy_plan(backwardPlan);
+
+    typedef typename
+        NumericTraits<typename DestAccessor::value_type>::isScalar
+        isScalarResult;
+
+    // normalization (after FFTs), maybe stripping imaginary part
+    applyFourierFilterImplNormalization(complexResultImg, destUpperLeft, da,
+                                        isScalarResult());
+}
+
+template <class DestImageIterator, class DestAccessor>
+void applyFourierFilterImplNormalization(FFTWComplexImage const &srcImage,
+                                         DestImageIterator destUpperLeft,
+                                         DestAccessor da,
+                                         VigraFalseType)
+{
+    double normFactor= 1.0/(srcImage.width() * srcImage.height());
+
+    for(int y=0; y<srcImage.height(); y++, destUpperLeft.y++)
+    {
+        DestImageIterator dIt= destUpperLeft;
+        for(int x= 0; x< srcImage.width(); x++, dIt.x++)
+        {
+            da.setComponent(srcImage(x, y).re()*normFactor, dIt, 0);
+            da.setComponent(srcImage(x, y).im()*normFactor, dIt, 1);
+        }
+    }
+}
+
+inline
+void applyFourierFilterImplNormalization(FFTWComplexImage const & srcImage,
+        FFTWComplexImage::traverser destUpperLeft,
+        FFTWComplexImage::Accessor da,
+        VigraFalseType)
+{
+    transformImage(srcImageRange(srcImage), destIter(destUpperLeft, da),
+                   linearIntensityTransform<FFTWComplex<> >(1.0/(srcImage.width() * srcImage.height())));
+}
+
+template <class DestImageIterator, class DestAccessor>
+void applyFourierFilterImplNormalization(FFTWComplexImage const & srcImage,
+                                         DestImageIterator destUpperLeft,
+                                         DestAccessor da,
+                                         VigraTrueType)
+{
+    double normFactor= 1.0/(srcImage.width() * srcImage.height());
+
+    for(int y=0; y<srcImage.height(); y++, destUpperLeft.y++)
+    {
+        DestImageIterator dIt= destUpperLeft;
+        for(int x= 0; x< srcImage.width(); x++, dIt.x++)
+            da.set(srcImage(x, y).re()*normFactor, dIt);
+    }
+}
+
+/**********************************************************/
+/*                                                        */
+/*                applyFourierFilterFamily                */
+/*                                                        */
+/**********************************************************/
+
+/** \brief Apply an array of filters (defined in the frequency domain) to an image.
+
+    This provides the same functionality as \ref applyFourierFilter(),
+    but applying several filters at once allows to avoid
+    repeated Fourier transforms of the source image.
+
+    Filters and result images must be stored in \ref vigra::ImageArray data
+    structures. In contrast to \ref applyFourierFilter(), this function adjusts
+    the size of the result images and the the length of the array.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor, class FilterType>
+        void applyFourierFilterFamily(SrcImageIterator srcUpperLeft,
+                                      SrcImageIterator srcLowerRight, SrcAccessor sa,
+                                      const ImageArray<FilterType> &filters,
+                                      ImageArray<FFTWComplexImage> &results)
+    }
+    \endcode
+
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor, class FilterType>
+        void applyFourierFilterFamily(SrcImageIterator srcUpperLeft,
+                                      SrcImageIterator srcLowerRight, SrcAccessor sa,
+                                      const ImageArray<FilterType> &filters,
+                                      ImageArray<FFTWComplexImage> &results)
+    }
+    \endcode
+
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor, class FilterType>
+        void applyFourierFilterFamily(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                                      const ImageArray<FilterType> &filters,
+                                      ImageArray<FFTWComplexImage> &results)
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/fftw3.hxx\><br>
+    Namespace: vigra
+
+    \code
+    // assuming the presence of a real-valued image named "image" to
+    // be filtered in this example
+
+    vigra::ImageArray<vigra::FImage> filters(16, image.size());
+
+    for (int i=0; i<filters.size(); i++)
+         // create some meaningful filters here
+         createMyFilterOfScale(i, destImage(filters[i]));
+
+    vigra::ImageArray<vigra::FFTWComplexImage> results();
+
+    vigra::applyFourierFilterFamily(srcImageRange(image), filters, results);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void applyFourierFilterFamily)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterType, class DestImage>
+inline
+void applyFourierFilterFamily(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                              const ImageArray<FilterType> &filters,
+                              ImageArray<DestImage> &results)
+{
+    applyFourierFilterFamily(src.first, src.second, src.third,
+                             filters, results);
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class FilterType, class DestImage>
+void applyFourierFilterFamily(SrcImageIterator srcUpperLeft,
+                              SrcImageIterator srcLowerRight, SrcAccessor sa,
+                              const ImageArray<FilterType> &filters,
+                              ImageArray<DestImage> &results)
+{
+    int w = int(srcLowerRight.x - srcUpperLeft.x);
+    int h = int(srcLowerRight.y - srcUpperLeft.y);
+
+    FFTWComplexImage workImage(w, h);
+    copyImage(srcIterRange(srcUpperLeft, srcLowerRight, sa),
+              destImage(workImage, FFTWWriteRealAccessor<>()));
+
+    FFTWComplexImage const & cworkImage = workImage;
+    applyFourierFilterFamilyImpl(cworkImage.upperLeft(), cworkImage.lowerRight(), cworkImage.accessor(),
+                                 filters, results);
+}
+
+template <class FilterType, class DestImage>
+inline
+void applyFourierFilterFamily(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor sa,
+    const ImageArray<FilterType> &filters,
+    ImageArray<DestImage> &results)
+{
+    int w= srcLowerRight.x - srcUpperLeft.x;
+
+    // test for right memory layout (fftw expects a 2*width*height floats array)
+    if (&(*(srcUpperLeft + Diff2D(w, 0))) == &(*(srcUpperLeft + Diff2D(0, 1))))
+        applyFourierFilterFamilyImpl(srcUpperLeft, srcLowerRight, sa,
+                                     filters, results);
+    else
+    {
+        int h = srcLowerRight.y - srcUpperLeft.y;
+        FFTWComplexImage workImage(w, h);
+        copyImage(srcIterRange(srcUpperLeft, srcLowerRight, sa),
+                  destImage(workImage));
+
+        FFTWComplexImage const & cworkImage = workImage;
+        applyFourierFilterFamilyImpl(cworkImage.upperLeft(), cworkImage.lowerRight(), cworkImage.accessor(),
+                                     filters, results);
+    }
+}
+
+template <class FilterType, class DestImage>
+void applyFourierFilterFamilyImpl(
+    FFTWComplexImage::const_traverser srcUpperLeft,
+    FFTWComplexImage::const_traverser srcLowerRight,
+    FFTWComplexImage::ConstAccessor sa,
+    const ImageArray<FilterType> &filters,
+    ImageArray<DestImage> &results)
+{
+    // FIXME: sa is not used
+    // (maybe check if StandardAccessor, else copy?)    
+
+    // make sure the filter images have the right dimensions
+    vigra_precondition((srcLowerRight - srcUpperLeft) == filters.imageSize(),
+                       "applyFourierFilterFamily called with src image size != filters.imageSize()!");
+
+    // make sure the result image array has the right dimensions
+    results.resize(filters.size());
+    results.resizeImages(filters.imageSize());
+
+    // FFT from srcImage to freqImage
+    int w = int(srcLowerRight.x - srcUpperLeft.x);
+    int h = int(srcLowerRight.y - srcUpperLeft.y);
+
+    FFTWComplexImage freqImage(w, h);
+    FFTWComplexImage result(w, h);
+
+    fftw_plan forwardPlan=
+        fftw_plan_dft_2d(h, w, (fftw_complex *)&(*srcUpperLeft),
+                               (fftw_complex *)freqImage.begin(),
+                               FFTW_FORWARD, FFTW_ESTIMATE );
+    fftw_execute(forwardPlan);
+    fftw_destroy_plan(forwardPlan);
+
+    fftw_plan backwardPlan=
+        fftw_plan_dft_2d(h, w, (fftw_complex *)result.begin(),
+                               (fftw_complex *)result.begin(),
+                               FFTW_BACKWARD, FFTW_ESTIMATE );
+    typedef typename
+        NumericTraits<typename DestImage::Accessor::value_type>::isScalar
+        isScalarResult;
+
+    // convolve with filters in freq. domain
+    for (unsigned int i= 0;  i < filters.size(); i++)
+    {
+        combineTwoImages(srcImageRange(freqImage), srcImage(filters[i]),
+                         destImage(result), std::multiplies<FFTWComplex<> >());
+
+        // FFT back into spatial domain (inplace in destImage)
+        fftw_execute(backwardPlan);
+
+        // normalization (after FFTs), maybe stripping imaginary part
+        applyFourierFilterImplNormalization(result,
+                                            results[i].upperLeft(), results[i].accessor(),
+                                            isScalarResult());
+    }
+    fftw_destroy_plan(backwardPlan);
+}
+
+/********************************************************/
+/*                                                      */
+/*                fourierTransformReal                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Real Fourier transforms for even and odd boundary conditions
+           (aka. cosine and sine transforms).
+
+
+    If the image is real and has even symmetry, its Fourier transform
+    is also real and has even symmetry. The Fourier transform of a real image with odd
+    symmetry is imaginary and has odd symmetry. In either case, only about a quarter
+    of the pixels need to be stored because the rest can be calculated from the symmetry
+    properties. This is especially useful, if the original image is implicitly assumed
+    to have reflective or anti-reflective boundary conditions. Then the "negative"
+    pixel locations are defined as
+
+    \code
+    even (reflective boundary conditions):      f[-x] = f[x]     (x = 1,...,N-1)
+    odd (anti-reflective boundary conditions):  f[-1] = 0
+                                                f[-x] = -f[x-2]  (x = 2,...,N-1)
+    \endcode
+
+    end similar at the other boundary (see the FFTW documentation for details).
+    This has the advantage that more efficient Fourier transforms that use only
+    real numbers can be implemented. These are also known as cosine and sine transforms
+    respectively.
+
+    If you use the odd transform it is important to note that in the Fourier domain,
+    the DC component is always zero and is therefore dropped from the data structure.
+    This means that index 0 in an odd symmetric Fourier domain image refers to
+    the <i>first</i> harmonic. This is especially important if an image is first
+    cosine transformed (even symmetry), then in the Fourier domain multiplied
+    with an odd symmetric filter (e.g. a first derivative) and finally transformed
+    back to the spatial domain with a sine transform (odd symmetric). For this to work
+    properly the image must be shifted left or up by one pixel (depending on whether
+    the x- or y-axis is odd symmetric) before the inverse transform can be applied.
+    (see example below).
+
+    The real Fourier transform functions are named <tt>fourierTransformReal??</tt>
+    where the questions marks stand for either <tt>E</tt> or <tt>O</tt> indicating
+    whether the x- and y-axis is to be transformed using even or odd symmetry.
+    The same functions can be used for both the forward and inverse transforms,
+    only the normalization changes. For signal processing, the following
+    normalization factors are most appropriate:
+
+    \code
+                          forward             inverse
+    ------------------------------------------------------------
+    X even, Y even           1.0         4.0 * (w-1) * (h-1)
+    X even, Y odd           -1.0        -4.0 * (w-1) * (h+1)
+    X odd,  Y even          -1.0        -4.0 * (w+1) * (h-1)
+    X odd,  Y odd            1.0         4.0 * (w+1) * (h+1)
+    \endcode
+
+    where <tt>w</tt> and <tt>h</tt> denote the image width and height.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class SrcTraverser, class SrcAccessor,
+                  class DestTraverser, class DestAccessor>
+        void
+        fourierTransformRealEE(SrcTraverser sul, SrcTraverser slr, SrcAccessor src,
+                               DestTraverser dul, DestAccessor dest, fftw_real norm);
+
+        fourierTransformRealEO, fourierTransformRealOE, fourierTransformRealOO likewise
+    }
+    \endcode
+
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcTraverser, class SrcAccessor,
+                  class DestTraverser, class DestAccessor>
+        void
+        fourierTransformRealEE(SrcTraverser sul, SrcTraverser slr, SrcAccessor src,
+                               DestTraverser dul, DestAccessor dest, fftw_real norm);
+
+        fourierTransformRealEO, fourierTransformRealOE, fourierTransformRealOO likewise
+    }
+    \endcode
+
+
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcTraverser, class SrcAccessor,
+                  class DestTraverser, class DestAccessor>
+        void
+        fourierTransformRealEE(triple<SrcTraverser, SrcTraverser, SrcAccessor> src,
+                               pair<DestTraverser, DestAccessor> dest, fftw_real norm);
+
+        fourierTransformRealEO, fourierTransformRealOE, fourierTransformRealOO likewise
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/fftw3.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::FImage spatial(width,height), fourier(width,height);
+    ... // fill image with data
+
+    // forward cosine transform == reflective boundary conditions
+    fourierTransformRealEE(srcImageRange(spatial), destImage(fourier), (fftw_real)1.0);
+
+    // multiply with a first derivative of Gaussian in x-direction
+    for(int y = 0; y < height; ++y)
+    {
+        for(int x = 1; x < width; ++x)
+        {
+            double dx = x * M_PI / (width - 1);
+            double dy = y * M_PI / (height - 1);
+            fourier(x-1, y) = fourier(x, y) * dx * std::exp(-(dx*dx + dy*dy) * scale*scale / 2.0);
+        }
+        fourier(width-1, y) = 0.0;
+    }
+
+    // inverse transform -- odd symmetry in x-direction, even in y,
+    //                      due to symmetry of the filter
+    fourierTransformRealOE(srcImageRange(fourier), destImage(spatial),
+                           (fftw_real)-4.0 * (width+1) * (height-1));
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void fourierTransformReal)
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealEE(triple<SrcTraverser, SrcTraverser, SrcAccessor> src,
+                               pair<DestTraverser, DestAccessor> dest, fftw_real norm)
+{
+    fourierTransformRealEE(src.first, src.second, src.third,
+                                   dest.first, dest.second, norm);
+}
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealEE(SrcTraverser sul, SrcTraverser slr, SrcAccessor src,
+                               DestTraverser dul, DestAccessor dest, fftw_real norm)
+{
+    fourierTransformRealWorkImageImpl(sul, slr, src, dul, dest,
+                                      norm, FFTW_REDFT00, FFTW_REDFT00);
+}
+
+template <class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealEE(
+         FFTWRealImage::const_traverser sul,
+         FFTWRealImage::const_traverser slr,
+         FFTWRealImage::Accessor src,
+         DestTraverser dul, DestAccessor dest, fftw_real norm)
+{
+    int w = slr.x - sul.x;
+
+    // test for right memory layout (fftw expects a width*height fftw_real array)
+    if (&(*(sul + Diff2D(w, 0))) == &(*(sul + Diff2D(0, 1))))
+        fourierTransformRealImpl(sul, slr, dul, dest,
+                                 norm, FFTW_REDFT00, FFTW_REDFT00);
+    else
+        fourierTransformRealWorkImageImpl(sul, slr, src, dul, dest,
+                                 norm, FFTW_REDFT00, FFTW_REDFT00);
+}
+
+/********************************************************************/
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealOE(triple<SrcTraverser, SrcTraverser, SrcAccessor> src,
+                               pair<DestTraverser, DestAccessor> dest, fftw_real norm)
+{
+    fourierTransformRealOE(src.first, src.second, src.third,
+                                   dest.first, dest.second, norm);
+}
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealOE(SrcTraverser sul, SrcTraverser slr, SrcAccessor src,
+                               DestTraverser dul, DestAccessor dest, fftw_real norm)
+{
+    fourierTransformRealWorkImageImpl(sul, slr, src, dul, dest,
+                                      norm, FFTW_RODFT00, FFTW_REDFT00);
+}
+
+template <class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealOE(
+         FFTWRealImage::const_traverser sul,
+         FFTWRealImage::const_traverser slr,
+         FFTWRealImage::Accessor src,
+         DestTraverser dul, DestAccessor dest, fftw_real norm)
+{
+    int w = slr.x - sul.x;
+
+    // test for right memory layout (fftw expects a width*height fftw_real array)
+    if (&(*(sul + Diff2D(w, 0))) == &(*(sul + Diff2D(0, 1))))
+        fourierTransformRealImpl(sul, slr, dul, dest,
+                                 norm, FFTW_RODFT00, FFTW_REDFT00);
+    else
+        fourierTransformRealWorkImageImpl(sul, slr, src, dul, dest,
+                                 norm, FFTW_RODFT00, FFTW_REDFT00);
+}
+
+/********************************************************************/
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealEO(triple<SrcTraverser, SrcTraverser, SrcAccessor> src,
+                               pair<DestTraverser, DestAccessor> dest, fftw_real norm)
+{
+    fourierTransformRealEO(src.first, src.second, src.third,
+                                   dest.first, dest.second, norm);
+}
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealEO(SrcTraverser sul, SrcTraverser slr, SrcAccessor src,
+                               DestTraverser dul, DestAccessor dest, fftw_real norm)
+{
+    fourierTransformRealWorkImageImpl(sul, slr, src, dul, dest,
+                                      norm, FFTW_REDFT00, FFTW_RODFT00);
+}
+
+template <class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealEO(
+         FFTWRealImage::const_traverser sul,
+         FFTWRealImage::const_traverser slr,
+         FFTWRealImage::Accessor src,
+         DestTraverser dul, DestAccessor dest, fftw_real norm)
+{
+    int w = slr.x - sul.x;
+
+    // test for right memory layout (fftw expects a width*height fftw_real array)
+    if (&(*(sul + Diff2D(w, 0))) == &(*(sul + Diff2D(0, 1))))
+        fourierTransformRealImpl(sul, slr, dul, dest,
+                                 norm, FFTW_REDFT00, FFTW_RODFT00);
+    else
+        fourierTransformRealWorkImageImpl(sul, slr, src, dul, dest,
+                                 norm, FFTW_REDFT00, FFTW_RODFT00);
+}
+
+/********************************************************************/
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealOO(triple<SrcTraverser, SrcTraverser, SrcAccessor> src,
+                               pair<DestTraverser, DestAccessor> dest, fftw_real norm)
+{
+    fourierTransformRealOO(src.first, src.second, src.third,
+                                   dest.first, dest.second, norm);
+}
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealOO(SrcTraverser sul, SrcTraverser slr, SrcAccessor src,
+                               DestTraverser dul, DestAccessor dest, fftw_real norm)
+{
+    fourierTransformRealWorkImageImpl(sul, slr, src, dul, dest,
+                                      norm, FFTW_RODFT00, FFTW_RODFT00);
+}
+
+template <class DestTraverser, class DestAccessor>
+inline void
+fourierTransformRealOO(
+         FFTWRealImage::const_traverser sul,
+         FFTWRealImage::const_traverser slr,
+         FFTWRealImage::Accessor src,
+         DestTraverser dul, DestAccessor dest, fftw_real norm)
+{
+    int w = slr.x - sul.x;
+
+    // test for right memory layout (fftw expects a width*height fftw_real array)
+    if (&(*(sul + Diff2D(w, 0))) == &(*(sul + Diff2D(0, 1))))
+        fourierTransformRealImpl(sul, slr, dul, dest,
+                                 norm, FFTW_RODFT00, FFTW_RODFT00);
+    else
+        fourierTransformRealWorkImageImpl(sul, slr, src, dul, dest,
+                                 norm, FFTW_RODFT00, FFTW_RODFT00);
+}
+
+/*******************************************************************/
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+void
+fourierTransformRealWorkImageImpl(SrcTraverser sul, SrcTraverser slr, SrcAccessor src,
+                                  DestTraverser dul, DestAccessor dest,
+                                  fftw_real norm, fftw_r2r_kind kindx, fftw_r2r_kind kindy)
+{
+    FFTWRealImage workImage(slr - sul);
+    copyImage(srcIterRange(sul, slr, src), destImage(workImage));
+    FFTWRealImage const & cworkImage = workImage;
+    fourierTransformRealImpl(cworkImage.upperLeft(), cworkImage.lowerRight(),
+                             dul, dest, norm, kindx, kindy);
+}
+
+
+template <class DestTraverser, class DestAccessor>
+void
+fourierTransformRealImpl(
+         FFTWRealImage::const_traverser sul,
+         FFTWRealImage::const_traverser slr,
+         DestTraverser dul, DestAccessor dest,
+         fftw_real norm, fftw_r2r_kind kindx, fftw_r2r_kind kindy)
+{
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    BasicImage<fftw_real> res(w, h);
+
+    fftw_plan plan = fftw_plan_r2r_2d(h, w,
+                         (fftw_real *)&(*sul), (fftw_real *)res.begin(),
+                         kindy, kindx, FFTW_ESTIMATE);
+    fftw_execute(plan);
+    fftw_destroy_plan(plan);
+
+    if(norm != 1.0)
+        transformImage(srcImageRange(res), destIter(dul, dest),
+                       std::bind1st(std::multiplies<fftw_real>(), 1.0 / norm));
+    else
+        copyImage(srcImageRange(res), destIter(dul, dest));
+}
+
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_FFTW3_HXX
diff --git a/include/vigra/fixedpoint.hxx b/include/vigra/fixedpoint.hxx
new file mode 100644
index 0000000..6da55e8
--- /dev/null
+++ b/include/vigra/fixedpoint.hxx
@@ -0,0 +1,1795 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2004-2005 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_FIXEDPOINT_HXX
+#define VIGRA_FIXEDPOINT_HXX
+
+#include "mathutil.hxx"
+#include "static_assert.hxx"
+#include "error.hxx"
+#include "numerictraits.hxx"
+
+namespace vigra {
+
+template <unsigned IntBits, unsigned FractionalBits>
+class FixedPoint;
+
+struct Error_FixedPointTraits_not_specialized_for_this_case;
+
+template <class T1, class T2>
+class FixedPointTraits
+{
+public:
+    typedef Error_FixedPointTraits_not_specialized_for_this_case PlusType;
+    typedef Error_FixedPointTraits_not_specialized_for_this_case MinusType;
+    typedef Error_FixedPointTraits_not_specialized_for_this_case MultipliesType;
+//    typedef Error_FixedPointTraits_not_specialized_for_this_case DividesType;
+};
+
+// return type policy: 
+//     * try to allocate enough bits to represent the biggest possible result
+//     * in case of add/subtract: if all bits of the internal int are used up, 
+//                                keep the representation
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+class FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >
+{
+    enum { MaxIntBits  = (IntBits1 < IntBits2) ? IntBits2 : IntBits1,
+           MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1,
+           PlusMinusIntBits = (MaxIntBits + 1 + MaxFracBits < 32) ?
+                               MaxIntBits + 1 : MaxIntBits,
+           MultipliesFracBits = (IntBits1 + IntBits2 < 31) 
+                                    ? (FracBits1 + FracBits2) > (31 - IntBits1 - IntBits2) 
+                                            ? 31 - IntBits1 - IntBits2
+                                            : FracBits1 + FracBits2
+                                    : 0
+         };
+public:
+    typedef FixedPoint<PlusMinusIntBits, MaxFracBits>               PlusType;
+    typedef FixedPoint<PlusMinusIntBits, MaxFracBits>               MinusType;
+    typedef FixedPoint<IntBits1 + IntBits2, MultipliesFracBits>  MultipliesType;
+//    typedef FixedPoint<IntBits1 + FracBits2, FracBits1 + IntBits2>  DividesType;
+};
+
+template <unsigned IntBits, unsigned FracBits>
+struct SquareRootTraits<FixedPoint<IntBits, FracBits> >
+{
+    enum { SRTotalBits = (IntBits + FracBits + 1) / 2,
+           SRIntBits   = (IntBits + 1) / 2,
+           SRFracBits  = SRTotalBits - SRIntBits
+         };
+public:
+    typedef FixedPoint<IntBits, FracBits>      Type;
+    typedef FixedPoint<SRIntBits, SRFracBits>  SquareRootResult;
+    typedef Type                               SquareRootArgument;
+};
+
+
+#ifndef DOXYGEN
+
+template <int N>
+struct FixedPoint_overflow_error__More_than_31_bits_requested
+: staticAssert::AssertBool<(N < 32)>
+{};
+
+#endif /* DOXYGEN */
+
+
+
+template <bool Predicate>
+struct FixedPoint_assignment_error__Target_object_has_too_few_integer_bits
+: staticAssert::AssertBool<Predicate>
+{};
+
+enum FixedPointNoShift { FPNoShift };
+
+namespace detail {
+
+template <bool MustRound>
+struct FPAssignWithRound;
+
+template <>
+struct FPAssignWithRound<false>
+{
+    template <int N>
+    static inline int exec(int v) { return v << (-N); }
+};
+
+template <>
+struct FPAssignWithRound<true>
+{
+    template <int N>
+    static inline int exec(int const v)
+    {
+        return (v + (1 << (N - 1))) >> (N);
+    }
+};
+
+template <bool MustRound>
+struct FPMulImplementation;
+
+template <>
+struct FPMulImplementation<false>
+{
+    template <int N>
+    static inline int exec(int l, int r) { return (l * r) << (-N); }
+};
+
+template <>
+struct FPMulImplementation<true>
+{
+    template <int N>
+    static inline int exec(int l, int r)
+    {
+        // there is not enough space in the result
+        // => perform calculations that preserve as much accuracy as possible
+        enum { diffl = N / 2, diffr = N  - diffl, maskl = (1 << diffl) - 1, maskr = (1 << diffr) - 1 };
+        int shiftl = l >> diffl;
+        int shiftr = r >> diffr;
+
+        return shiftl * shiftr + (((l & maskl) * shiftr) >> diffl) +
+                                 (((r & maskr) * shiftl) >> diffr);
+    }
+};
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*                      FixedPoint                      */
+/*                                                      */
+/********************************************************/
+
+/** Template for fixed point arithmetic.
+
+    Fixed point arithmetic is used when computations with fractional accuracy
+    must be made at the highest speed possible (e.g. in the inner loop
+    of a volume rendering routine). The speed-up relative to floating
+    point arithmetic can be dramatic, especially when one can avoid
+    conversions between integer and floating point numbers (these are 
+    very expensive because integer and floating point arithmetic
+    resides in different pipelines). 
+    
+    The template wraps an <tt>int</tt> and uses <tt>IntBits</tt> to
+    represent the integral part of a number, and <tt>FractionalBits</tt>
+    for the fractional part, where <tt>IntBits + FractionalBits < 32</tt>.
+    (The 32rd bit is reserved because FixedPoint is a signed type).
+    These numbers will be automatically allocated in an intelligent way
+    in the result of an arithmetic operation. For example, when two 
+    fixed point numbers are multiplied, the required number of integer
+    bits in the result is the sum of the number of integer bits of the
+    arguments, but only when so many bits are available. This is figured out
+    by means of FixedPointTraits, and a compile-time error is raised
+    when no suitable representation can be found. The idea is that the right
+    thing happens automatically as often as possible.
+
+    <tt>FixedPoint</tt> implements the required interface of an
+    \ref AlgebraicRing and the required numeric and
+    promotion traits. In addition, it supports functions <tt>add</tt>, 
+    <tt>sub</tt>, and <tt>mul</tt>, where a particular layout of the result can
+    be enforced. 
+    
+    <tt>unsigned char, signed char, unsigned short, signed short, int</tt> can be
+    transformed into a FixedPoint with appropriate layout by means of the factory
+    function <tt>fixedPoint()</tt>.
+
+    <b>See also:</b>
+    <ul>
+    <li> \ref FixedPointOperations
+    <li> \ref FixedPointTraits
+    </ul>
+
+    <b>\#include</b> \<vigra/fixedpoint.hxx\><br>
+    Namespace: vigra
+*/
+template <unsigned IntBits, unsigned FractionalBits>
+class FixedPoint
+{
+public:
+    enum {
+        INT_BITS        = IntBits,
+        FRACTIONAL_BITS = FractionalBits,
+        TOTAL_BITS      = IntBits + FractionalBits,
+        MAX             = (int)(((unsigned)1 << TOTAL_BITS) - 1),
+        ONE             = 1 << FractionalBits,
+        ONE_HALF        = ONE >> 1,
+        FRACTIONAL_MASK = ONE - 1,
+        INT_MASK        = MAX ^ FRACTIONAL_MASK
+    };
+
+    Int32 value;
+
+    FixedPoint()
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_requested<(IntBits + FractionalBits)>));
+    }
+
+        /** Construct from an int (fractional part will become zero).
+        */
+    explicit FixedPoint(int v)
+    : value(v << FractionalBits)
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_requested<(IntBits + FractionalBits)>));
+    }
+
+        /** Construct from an int by a bitwise copy. This is normally only used internally.
+        */
+    FixedPoint(int v, FixedPointNoShift)
+    : value(v)
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_requested<(IntBits + FractionalBits)>));
+    }
+
+        /** Construct from an double and round the fractional part to 
+            <tt>FractionalBits</tt> accuracy. A PreconditionViolation exception is raised when
+            the integer part is too small to represent the number.
+        */
+    explicit FixedPoint(double rhs)
+    : value((int)round(rhs * ONE))
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_requested<(IntBits + FractionalBits)>));
+        vigra_precondition(abs(rhs * ONE) <= (double)MAX,
+            "FixedPoint(double rhs): Too few integer bits to convert rhs.");
+    }
+
+        /** Copy constructor.
+        */
+    FixedPoint(const FixedPoint &other)
+    : value(other.value)
+    {}
+
+        /** Construct from a FixedPoint with different layout. It rounds as appropriate and raises
+            a compile-time error when the target type has too few integer bits.
+        */
+    template <unsigned Int2, unsigned Frac2>
+    FixedPoint(const FixedPoint<Int2, Frac2> &other)
+    : value(detail::FPAssignWithRound<(Frac2 > FractionalBits)>::template exec<int(Frac2) - int(FractionalBits)>(other.value))
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_requested<(IntBits + FractionalBits)>));
+        VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits >= Int2)>));
+    }
+
+        /** Assignment from int. The fractional part will become zero.  
+            A PreconditionViolation exception is raised when
+            the integer part is too small to represent the number.
+        */
+    FixedPoint &operator=(int rhs)
+    {
+        vigra_precondition(abs(rhs) < (1 << IntBits),
+            "FixedPoint::operator=(int rhs): Too few integer bits to represent rhs.");
+        value = rhs << FractionalBits;
+        return *this;
+    }
+
+        /** Assignment form double. The fractional part is rounded, and a 
+            PreconditionViolation exception is raised when
+            the integer part is too small to represent the number.
+        */
+    FixedPoint &operator=(double rhs)
+    {
+        vigra_precondition(abs(rhs) <= ((1 << IntBits) - 1),
+            "FixedPoint::operator=(double rhs): Too few integer bits to convert rhs.");
+        value = (int)round(rhs * ONE);
+        return *this;
+    }
+
+        /** Copy assignment.
+        */
+    FixedPoint & operator=(const FixedPoint &other)
+    {
+        value = other.value;
+        return *this;
+    }
+
+        /** Assignment from a FixedPoint with different layout. It rounds as appropriate and raises
+            a compile-time error when the target type has too few integer bits.
+        */
+    template <unsigned Int2, unsigned Frac2>
+    FixedPoint & operator=(const FixedPoint<Int2, Frac2> &other)
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits >= Int2)>));
+        value = detail::FPAssignWithRound<(Frac2 > FractionalBits)>::template exec<int(Frac2) - int(FractionalBits)>(other.value);
+        return *this;
+    }
+
+        /** Negation.
+        */
+    FixedPoint operator-() const
+    {
+        return FixedPoint(-value, FPNoShift);
+    }
+
+        /** Pre-increment.
+        */
+    FixedPoint & operator++()
+    {
+        value += ONE;
+        return *this;
+    }
+
+        /** Post-increment.
+        */
+    FixedPoint operator++(int)
+    {
+        FixedPoint old(*this);
+        value += ONE;
+        return old;
+    }
+
+        /** Pre-decrement.
+        */
+    FixedPoint & operator--()
+    {
+        value -= ONE;
+        return *this;
+    }
+
+        /** Post-decrement.
+        */
+    FixedPoint operator--(int)
+    {
+        FixedPoint old(*this);
+        value -= ONE;
+        return old;
+    }
+
+        /** Add-assignment from a FixedPoint with different layout. It rounds as appropriate and raises
+            a compile-time error when the target type has too few integer bits.
+        */
+    template <unsigned Int2, unsigned Frac2>
+    FixedPoint & operator+=(const FixedPoint<Int2, Frac2> &other)
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits >= Int2)>));
+        value += detail::FPAssignWithRound<(Frac2 > FractionalBits)>::template exec<Frac2 - FractionalBits>(other.value);
+        return *this;
+    }
+
+        /** Subtract-assignment from a FixedPoint with different layout. It rounds as appropriate and raises
+            a compile-time error when the target type has too few integer bits.
+        */
+    template <unsigned Int2, unsigned Frac2>
+    FixedPoint & operator-=(const FixedPoint<Int2, Frac2> &other)
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits >= Int2)>));
+        value -= detail::FPAssignWithRound<(Frac2 > FractionalBits)>::template exec<Frac2 - FractionalBits>(other.value);
+        return *this;
+    }
+    
+        /** Multiply-assignment from a FixedPoint with different layout. It rounds as appropriate and raises
+            a compile-time error when the target type has too few integer bits.
+        */
+    template <unsigned Int2, unsigned Frac2>
+    FixedPoint & operator*=(const FixedPoint<Int2, Frac2> &other)
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits >= Int2)>));
+        value = detail::FPMulImplementation<(Frac2 > 0)>::template exec<Frac2>(value, other.value);
+        return *this;
+    }
+};
+
+#define VIGRA_FIXED_POINT_FACTORY(T, INTBITS) \
+    inline FixedPoint<INTBITS, 0> fixedPoint(T t) \
+    { \
+        return FixedPoint<INTBITS, 0>(t, FPNoShift); \
+    }
+
+VIGRA_FIXED_POINT_FACTORY(unsigned char, 8)
+VIGRA_FIXED_POINT_FACTORY(signed char, 7)
+VIGRA_FIXED_POINT_FACTORY(unsigned short, 16)
+VIGRA_FIXED_POINT_FACTORY(signed short, 15)
+VIGRA_FIXED_POINT_FACTORY(int, 31)
+
+#undef VIGRA_FIXED_POINT_FACTORY
+
+template <class T>
+struct FixedPointCast;
+
+#define VIGRA_FIXED_POINT_CAST(type) \
+template <> \
+struct FixedPointCast<type> \
+{ \
+    template <unsigned IntBits, unsigned FracBits> \
+    static type cast(FixedPoint<IntBits, FracBits> v) \
+    { \
+        return round(v); \
+    } \
+};
+
+VIGRA_FIXED_POINT_CAST(Int8)
+VIGRA_FIXED_POINT_CAST(UInt8)
+VIGRA_FIXED_POINT_CAST(Int16)
+VIGRA_FIXED_POINT_CAST(UInt16)
+VIGRA_FIXED_POINT_CAST(Int32)
+VIGRA_FIXED_POINT_CAST(UInt32)
+
+#undef VIGRA_FIXED_POINT_CAST
+
+template <>
+struct FixedPointCast<float>
+{
+    template <unsigned IntBits, unsigned FracBits>
+    static float cast(FixedPoint<IntBits, FracBits> v)
+    {
+        return (float)v.value / FixedPoint<IntBits, FracBits>::ONE;
+    }
+};
+
+template <>
+struct FixedPointCast<double>
+{
+    template <unsigned IntBits, unsigned FracBits>
+    static double cast(FixedPoint<IntBits, FracBits> v)
+    {
+        return (double)v.value / FixedPoint<IntBits, FracBits>::ONE;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                 FixedPointOperations                 */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup FixedPointOperations Functions for FixedPoint
+
+    \brief     <b>\#include</b> \<vigra/fixedpoint.hxx\><br>
+
+    These functions fulfill the requirements of an \ref AlgebraicRing.
+
+    Namespace: vigra
+    <p>
+
+ */
+//@{
+
+    /** Convert a FixedPoint to a built-in type.
+        If the target is integral, the value is rounded.<br>
+        Usage:
+        \code
+        FixedPoint<16,15> fp(...);
+        
+        double d = fixed_point_cast<double>(fp);
+        \endcode
+    */
+template <class TARGET, unsigned IntBits, unsigned FracBits>
+TARGET fixed_point_cast(FixedPoint<IntBits, FracBits> v)
+{
+    return FixedPointCast<TARGET>::cast(v);
+}
+
+    /// equal
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+inline
+bool operator==(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
+{
+    enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
+    return (l.value << (MaxFracBits - FracBits1)) == (r.value << (MaxFracBits - FracBits2));
+}
+
+    /// not equal
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+inline
+bool operator!=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
+{
+    enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
+    return (l.value << (MaxFracBits - FracBits1)) != (r.value << (MaxFracBits - FracBits2));
+}
+
+    /// less than
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+inline
+bool operator<(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
+{
+    enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
+    return (l.value << (MaxFracBits - FracBits1)) < (r.value << (MaxFracBits - FracBits2));
+}
+
+    /// less or equal
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+inline
+bool operator<=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
+{
+    enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
+    return (l.value << (MaxFracBits - FracBits1)) <= (r.value << (MaxFracBits - FracBits2));
+}
+
+    /// greater
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+inline
+bool operator>(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
+{
+    enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
+    return (l.value << (MaxFracBits - FracBits1)) > (r.value << (MaxFracBits - FracBits2));
+}
+
+    /// greater or equal
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+inline
+bool operator>=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
+{
+    enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
+    return (l.value << (MaxFracBits - FracBits1)) >= (r.value << (MaxFracBits - FracBits2));
+}
+
+    /// addition with automatic determination of the appropriate result type.
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+inline
+typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::PlusType
+operator+(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
+{
+    enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
+    return typename
+        FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::
+        PlusType((l.value << (MaxFracBits - FracBits1)) + (r.value << (MaxFracBits - FracBits2)), FPNoShift);
+}
+
+    /// addition with enforced result type.
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2,
+          unsigned IntBits3, unsigned FracBits3>
+inline void
+add(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r,
+    FixedPoint<IntBits3, FracBits3> & result)
+{
+    result = l + r;
+}
+
+    /// subtraction with automatic determination of the appropriate result type.
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+inline
+typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::MinusType
+operator-(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
+{
+    enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
+    return typename
+        FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::
+        MinusType((l.value << (MaxFracBits - FracBits1)) - (r.value << (MaxFracBits - FracBits2)), FPNoShift);
+}
+
+    /// subtraction with enforced result type.
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2,
+          unsigned IntBits3, unsigned FracBits3>
+inline void
+sub(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r,
+    FixedPoint<IntBits3, FracBits3> & result)
+{
+    result = l - r;
+}
+
+    /// multiplication with automatic determination of the appropriate result type.
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+inline
+typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::MultipliesType
+operator*(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
+{
+    typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::
+        MultipliesType res;
+    mul(l, r, res);
+    return res;
+}
+
+    /// multiplication with enforced result type.
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2,
+          unsigned IntBits3, unsigned FracBits3>
+inline void
+mul(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r,
+    FixedPoint<IntBits3, FracBits3> & result)
+{
+    VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits1 + IntBits2 <= IntBits3)>));
+    enum { diff = FracBits1 + FracBits2 - FracBits3 };
+    result.value = detail::FPMulImplementation<(diff > 0)>::template exec<diff>(l.value, r.value);
+}
+
+    /// square root.
+template <unsigned IntBits, unsigned FracBits>
+inline typename SquareRootTraits<FixedPoint<IntBits, FracBits> >::SquareRootResult
+sqrt(FixedPoint<IntBits, FracBits> v)
+{
+    return typename SquareRootTraits<FixedPoint<IntBits, FracBits> >::SquareRootResult(sqrti(v.value), FPNoShift);
+}
+
+    /// absolute value.
+template <unsigned IntBits, unsigned FracBits>
+inline FixedPoint<IntBits, FracBits>
+abs(FixedPoint<IntBits, FracBits> v)
+{
+    return FixedPoint<IntBits, FracBits>(abs(v.value), FPNoShift);
+}
+
+    /// squared norm (same as v*v).
+template <unsigned IntBits, unsigned FracBits>
+inline
+typename FixedPointTraits<FixedPoint<IntBits, FracBits>, FixedPoint<IntBits, FracBits> >::MultipliesType
+squaredNorm(FixedPoint<IntBits, FracBits> v)
+{
+    return v*v;
+}
+
+    /// norm (same as abs).
+template <unsigned IntBits, unsigned FracBits>
+inline
+FixedPoint<IntBits, FracBits>
+norm(FixedPoint<IntBits, FracBits> const & v)
+{
+    return abs(v);
+}
+
+    /// fractional part.
+template <unsigned IntBits, unsigned FracBits>
+inline FixedPoint<0, FracBits>
+frac(FixedPoint<IntBits, FracBits> v)
+{
+    return FixedPoint<0, FracBits>(v.value & FixedPoint<IntBits, FracBits>::FRACTIONAL_MASK, FPNoShift);
+}
+
+    /// dual fractional part: <tt>1 - frac(v)</tt>.
+template <unsigned IntBits, unsigned FracBits>
+inline FixedPoint<0, FracBits>
+dual_frac(FixedPoint<IntBits, FracBits> v)
+{
+    return FixedPoint<0, FracBits>(FixedPoint<0, FracBits>::ONE - 
+                                   (v.value & FixedPoint<IntBits, FracBits>::FRACTIONAL_MASK), FPNoShift);
+}
+
+    /// rounding down.
+template <unsigned IntBits, unsigned FracBits>
+inline int
+floor(FixedPoint<IntBits, FracBits> v)
+{
+    return(v.value >> FracBits);
+}
+
+    /// rounding up.
+template <unsigned IntBits, unsigned FracBits>
+inline int
+ceil(FixedPoint<IntBits, FracBits> v)
+{
+    return((v.value + FixedPoint<IntBits, FracBits>::FRACTIONAL_MASK) >> FracBits);
+}
+
+    /// rounding to the nearest integer.
+template <unsigned IntBits, unsigned FracBits>
+inline int
+round(FixedPoint<IntBits, FracBits> v)
+{
+    return((v.value + FixedPoint<IntBits, FracBits>::ONE_HALF) >> FracBits);
+}
+
+//@}
+
+/********************************************************/
+/*                                                      */
+/*                     FixedPoint-Traits                */
+/*                                                      */
+/********************************************************/
+
+/** \page FixedPointTraits Numeric and Promote Traits of FixedPoint
+
+    The numeric and promote traits for FixedPoint follow
+    the general specifications for \ref NumericPromotionTraits and
+    \ref AlgebraicRing. They are implemented in terms of the traits of the basic types by
+    partial template specialization:
+
+    \code
+
+    template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+    class FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >
+    {
+        typedef FixedPoint<PlusMinusIntBits, MaxFracBits>               PlusType;
+        typedef FixedPoint<PlusMinusIntBits, MaxFracBits>               MinusType;
+        typedef FixedPoint<IntBits1 + IntBits2, FracBits1 + FracBits2>  MultipliesType;
+    };
+
+    template <unsigned IntBits, unsigned FracBits>
+    struct NumericTraits<FixedPoint<IntBits, FracBits> >
+    {
+        typedef FixedPoint<IntBits, FracBits> Type;
+            // Promote undefined because it depends on the layout, use FixedPointTraits
+            // RealPromote in AlgebraicRing -- multiplication with double is not supported.
+            // ComplexPromote in AlgebraicRing -- multiplication with double is not supported.
+        typedef Type ValueType;
+
+        typedef VigraFalseType isIntegral;
+        typedef VigraTrueType  isScalar;
+        typedef VigraTrueType  isSigned;
+        typedef VigraTrueType  isOrdered;
+        typedef VigraFalseType isComplex;
+
+        ... // etc.
+    };
+
+    template <unsigned IntBits, unsigned FracBits>
+    struct SquareRootTraits<FixedPoint<IntBits, FracBits> >
+    {
+        typedef FixedPoint<IntBits, FracBits>      Type;
+        typedef FixedPoint<SRIntBits, SRFracBits>  SquareRootResult;
+        typedef Type                               SquareRootArgument;
+    };
+    
+    template <unsigned IntBits, unsigned FracBits>
+    struct NormTraits<FixedPoint<IntBits, FracBits> >
+    {
+        typedef FixedPoint<IntBits, FracBits>         Type;
+        typedef typename 
+            FixedPointTraits<FixedPoint<IntBits, FracBits>, FixedPoint<IntBits, FracBits> >::MultipliesType
+                                                      SquaredNormType;
+        typedef Type                                  NormType;
+    };
+
+    template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+    struct PromoteTraits<FixedPoint<IntBits1, FracBits1>,
+                         FixedPoint<IntBits2, FracBits2> >
+    {
+        typedef typename 
+            FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::PlusType 
+            Promote;
+    };
+    \endcode
+
+    <b>\#include</b> \<vigra/fixedpoint.hxx\><br>
+    Namespace: vigra
+
+*/
+template <unsigned IntBits, unsigned FracBits>
+struct NumericTraits<FixedPoint<IntBits, FracBits> >
+{
+    typedef FixedPoint<IntBits, FracBits> Type;
+        //typedef FixedPoint<IntBits, FracBits> Promote;
+        //typedef FixedPoint<IntBits, FracBits> RealPromote;
+        //typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraFalseType isIntegral;
+    typedef VigraTrueType  isScalar;
+    typedef VigraTrueType  isSigned;
+    typedef VigraTrueType  isOrdered;
+    typedef VigraFalseType isComplex;
+
+    static Type zero() { return Type(0, FPNoShift); }
+    static Type one() { return Type(Type::ONE, FPNoShift); }
+    static Type nonZero() { return one(); }
+    static Type epsilon() { return Type(1, FPNoShift); }
+    static Type smallestPositive() { return Type(1, FPNoShift); }
+    static Type max() { return Type( Type::MAX, FPNoShift); }
+    static Type min() { return -max(); }
+};
+
+template <unsigned IntBits, unsigned FracBits>
+struct NormTraits<FixedPoint<IntBits, FracBits> >
+{
+    typedef FixedPoint<IntBits, FracBits>         Type;
+    typedef typename 
+        FixedPointTraits<FixedPoint<IntBits, FracBits>, FixedPoint<IntBits, FracBits> >::MultipliesType
+                                                  SquaredNormType;
+    typedef Type                                  NormType;
+};
+
+template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
+struct PromoteTraits<FixedPoint<IntBits1, FracBits1>,
+                     FixedPoint<IntBits2, FracBits2> >
+{
+    typedef typename 
+        FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::PlusType 
+        Promote;
+};
+
+/***********************************************************************************/
+
+enum FPOverflowHandling { FPOverflowIgnore, FPOverflowSaturate, FPOverflowError };
+
+template <int IntBits, FPOverflowHandling OverflowHandling = FPOverflowIgnore>
+class FixedPoint16;
+
+/********************************************************/
+/*                                                      */
+/*                     FixedPoint16-Traits              */
+/*                                                      */
+/********************************************************/
+
+/** \page FixedPoint16Traits Numeric and Promote Traits of FixedPoint16
+
+    The numeric and promote traits for FixedPoint16 follow
+    the general specifications for \ref NumericPromotionTraits and
+    \ref AlgebraicRing. They are implemented in terms of the traits of the basic types by
+    partial template specialization:
+
+    \code
+    template <int IntBits, FPOverflowHandling OverflowHandling>
+    struct NumericTraits<FixedPoint16<IntBits, OverflowHandling> >
+    {
+        typedef FixedPoint16<IntBits, OverflowHandling> Type;
+        typedef Type                                    Promote;
+            // RealPromote undefined -- multiplication with double is not supported.
+            // ComplexPromote undefined -- multiplication with double is not supported.
+        typedef Type ValueType;
+
+        typedef VigraFalseType isIntegral;
+        typedef VigraTrueType  isScalar;
+        typedef VigraTrueType  isSigned;
+        typedef VigraTrueType  isOrdered;
+        typedef VigraFalseType isComplex;
+
+        ... // etc.
+    };
+
+    template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+    struct PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>,
+                         FixedPoint16<IntBits2, OverflowHandling> >
+    {
+        typedef FixedPoint16<MetaMax<IntBits1, IntBits2>::value, OverflowHandling> Promote;
+        ... // etc.
+    };
+
+    template <int IntBits, FPOverflowHandling OverflowHandling>
+    struct NormTraits<FixedPoint16<IntBits, OverflowHandling> >
+    {
+        typedef FixedPoint16<IntBits, OverflowHandling>     Type;
+        typedef typename PromoteTraits<Type, Type>::Promote SquaredNormType;
+        typedef Type                                        NormType;
+    };
+
+    template <int IntBits, FPOverflowHandling OverflowHandling>
+    struct SquareRootTraits<FixedPoint16<IntBits, OverflowHandling> >
+    {
+        typedef FixedPoint16<IntBits, OverflowHandling>            Type;
+        typedef FixedPoint16<(IntBits + 1) / 2, OverflowHandling>  SquareRootResult;
+        typedef Type                                               SquareRootArgument;
+    };
+    \endcode
+
+    <b>\#include</b> \<vigra/fixedpoint.hxx\><br>
+    Namespace: vigra
+
+*/
+template <int IntBits, FPOverflowHandling OverflowHandling>
+struct NumericTraits<FixedPoint16<IntBits, OverflowHandling> >
+{
+    typedef FixedPoint16<IntBits, OverflowHandling> Type;
+    typedef Type                                    Promote;
+        // RealPromote undefined -- multiplication with double is not supported.
+        // ComplexPromote undefined -- multiplication with double is not supported.
+    typedef Type ValueType;
+
+    typedef VigraFalseType isIntegral;
+    typedef VigraTrueType  isScalar;
+    typedef VigraTrueType  isSigned;
+    typedef VigraTrueType  isOrdered;
+    typedef VigraFalseType isComplex;
+
+    static Type zero() { return Type(0, FPNoShift); }
+    static Type one() { return Type(Type::ONE, FPNoShift); }
+    static Type nonZero() { return one(); }
+    static Type epsilon() { return Type(1, FPNoShift); }
+    static Type smallestPositive() { return Type(1, FPNoShift); }
+    static Type max() { return Type( Type::MAX, FPNoShift); }
+    static Type min() { return Type( Type::MIN, FPNoShift); }
+
+    static Promote toPromote(Type v) { return v; }
+    static Type fromPromote(Promote v) { return v; }; 
+};
+
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+struct PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>,
+                     FixedPoint16<IntBits2, OverflowHandling> >
+{
+    typedef FixedPoint16<MetaMax<IntBits1, IntBits2>::value, OverflowHandling> Promote;
+    static Promote toPromote(FixedPoint16<IntBits1, OverflowHandling> v) { return Promote(v); }
+    static Promote toPromote(FixedPoint16<IntBits2, OverflowHandling> v) { return Promote(v); }
+};
+
+template <int IntBits, FPOverflowHandling OverflowHandling>
+struct PromoteTraits<FixedPoint16<IntBits, OverflowHandling>,
+                     FixedPoint16<IntBits, OverflowHandling> >
+{
+    typedef FixedPoint16<IntBits, OverflowHandling> Promote;
+    static Promote toPromote(FixedPoint16<IntBits, OverflowHandling> v) { return v; }
+};
+
+template <int IntBits, FPOverflowHandling OverflowHandling>
+struct NormTraits<FixedPoint16<IntBits, OverflowHandling> >
+{
+    typedef FixedPoint16<IntBits, OverflowHandling>     Type;
+    typedef typename PromoteTraits<Type, Type>::Promote SquaredNormType;
+    typedef Type                                        NormType;
+};
+
+template <int IntBits, FPOverflowHandling OverflowHandling>
+struct SquareRootTraits<FixedPoint16<IntBits, OverflowHandling> >
+{
+    typedef FixedPoint16<IntBits, OverflowHandling>            Type;
+    typedef FixedPoint16<(IntBits + 1) / 2, OverflowHandling>  SquareRootResult;
+    typedef Type                                               SquareRootArgument;
+};
+
+#ifndef DOXYGEN
+
+template <bool Compatible>
+struct FixedPoint_error__Right_shift_operator_has_unsupported_semantics
+: staticAssert::AssertBool<Compatible>
+{};
+
+#endif /* DOXYGEN */
+
+template <bool Predicate>
+struct FixedPoint16_assignment_error__Target_object_has_too_few_integer_bits
+: staticAssert::AssertBool<Predicate>
+{};
+
+namespace detail {
+
+template<int BeforeIntBits, int AfterIntBits, 
+         bool Round = false,
+         bool RightShift = (AfterIntBits >= BeforeIntBits)>
+struct FP16Align;
+
+template<int BeforeIntBits>
+struct FP16Align<BeforeIntBits, BeforeIntBits, true, true>
+{
+    static inline Int32 exec(Int32 v)
+    {
+        return v;
+    }
+};
+
+template<int BeforeIntBits>
+struct FP16Align<BeforeIntBits, BeforeIntBits, false, true>
+{
+    static inline Int32 exec(Int32 v)
+    {
+        return v;
+    }
+};
+
+template<int BeforeIntBits, int AfterIntBits>
+struct FP16Align<BeforeIntBits, AfterIntBits, false, true>
+{
+    static inline Int32 exec(Int32 v)
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
+        return v >> (AfterIntBits - BeforeIntBits);
+    }
+};
+
+template<int BeforeIntBits, int AfterIntBits>
+struct FP16Align<BeforeIntBits, AfterIntBits, true, true>
+{
+    enum { ONE_HALF = 1 << (AfterIntBits - BeforeIntBits - 1) };
+    static inline Int32 exec(Int32 v)
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
+        return (v + ONE_HALF) >> (AfterIntBits - BeforeIntBits);
+    }
+};
+
+template<int BeforeIntBits, int AfterIntBits, bool Round>
+struct FP16Align<BeforeIntBits, AfterIntBits, Round, false>
+{
+    static inline Int32 exec(Int32 v)
+    {
+        return v << (BeforeIntBits - AfterIntBits);
+    }
+};
+
+template <FPOverflowHandling OverflowHandling = FPOverflowIgnore>
+struct FP16OverflowHandling
+{
+    static inline Int32 exec(Int32 v)
+    {
+        return v;
+    }
+    
+    static inline Int32 exec(UInt32 v)
+    {
+        return v;
+    }
+};
+
+template <>
+struct FP16OverflowHandling<FPOverflowSaturate>
+{
+    static inline Int32 exec(Int32 v)
+    {
+        if(v >= 1 << 15)
+            return (1 << 15) - 1;
+        if(v < -(1 << 15))
+            return -(1 << 15);
+        return v;
+    }
+    static inline Int32 exec(UInt32 v)
+    {
+        if(v >= 1 << 15)
+            return (1 << 15) - 1;
+        return v;
+    }
+};
+
+template <>
+struct FP16OverflowHandling<FPOverflowError>
+{
+    static inline Int32 exec(Int32 v)
+    {
+        vigra_precondition(v < (1 << 15) && v >= -(1 << 15),
+             "FixedPoint16: Operation overflows.");
+        return v;
+    }
+    static inline Int32 exec(UInt32 v)
+    {
+        vigra_precondition(v < (1 << 15),
+             "FixedPoint16: Operation overflows.");
+        return v;
+    }
+};
+
+
+template <int IntBits1, int IntBits2, int IntBitsOut, 
+          FPOverflowHandling OverflowHandling >
+struct FP16AddImpl
+{
+    enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
+    static inline Int32 exec(Int32 t1, Int32 t2)
+    {
+       return FP16OverflowHandling<OverflowHandling>::exec(
+                  FP16Align<MinIntBits, IntBitsOut, /*Round*/ true>::exec(
+                      FP16Align<IntBits1, MinIntBits, /*Round*/ false>::exec(t1) + 
+                      FP16Align<IntBits2, MinIntBits, /*Round*/ false>::exec(t2)));
+    }
+};
+
+template <int IntBits1, int IntBits2, int IntBitsOut, 
+          FPOverflowHandling OverflowHandling >
+struct FP16SubImpl
+{
+    enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
+    static inline Int32 exec(Int32 t1, Int32 t2)
+    {
+       return FP16OverflowHandling<OverflowHandling>::exec(
+                  FP16Align<MinIntBits, IntBitsOut, /*Round*/ true>::exec(
+                      FP16Align<IntBits1, MinIntBits, /*Round*/ false>::exec(t1) - 
+                      FP16Align<IntBits2, MinIntBits, /*Round*/ false>::exec(t2)));
+    }
+};
+
+template <int IntBits1, int IntBits2, int IntBitsOut, 
+          FPOverflowHandling OverflowHandling >
+struct FP16MulImpl
+{
+    static inline Int32 exec(Int32 t1, Int32 t2)
+    {
+        return FP16OverflowHandling<OverflowHandling>::exec(
+                   FP16Align<IntBits1+IntBits2, IntBitsOut+15, /*Round*/ true>::exec(t1*t2));
+    }
+};
+
+template <int IntBits1, int IntBits2, int IntBitsOut, 
+          FPOverflowHandling OverflowHandling >
+struct FP16DivImpl
+{
+    static inline Int32 exec(Int32 t1, Int32 t2)
+    {
+        if(t2 == 0)
+            return (t1 >= 0)
+                       ?  (1 << 15) - 1
+                       : -(1 << 15);
+        return FP16OverflowHandling<OverflowHandling>::exec(
+                   FP16Align<IntBits1-IntBits2, IntBitsOut+1, /*Round*/ true>::exec((t1<<16)/t2));
+    }
+};
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*                      FixedPoint16                    */
+/*                                                      */
+/********************************************************/
+
+template <class TARGET, int IntBits, FPOverflowHandling OverflowHandling>
+TARGET fixed_point_cast(FixedPoint16<IntBits, OverflowHandling> v);
+
+/** Template for 16-bit signed fixed point arithmetic.
+
+    Fixed point arithmetic is used when computations with fractional accuracy
+    must be made at the highest speed possible (e.g. in the inner loop
+    of a volume rendering routine). The speed-up relative to floating
+    point arithmetic can be dramatic, especially when one can avoid
+    conversions between integer and floating point numbers (these are 
+    very expensive because integer and floating point arithmetic
+    resides in different pipelines). 
+    
+    The template wraps an <tt>Int16</tt> and uses <tt>IntBits</tt> to
+    represent the integral part of a number, and <tt>15 - IntBits</tt>
+    for the fractional part. The 16th bit is reserved because FixedPoint16 
+    is a signed type. Results of expressions with mixed types will preserve
+    larger number of <tt>IntBits</tt> of the results, in order to minimize
+    the possibility for overflow. Nonetheless, overflow can occur, and the 
+    template parameter <tt>OverflowHandling</tt> determines how this will be
+    handled:
+    
+    <DL>
+    <DT>FPOverflowIgnore<DD> (default) Ignore overflow, i.e. use the usual modulo behavior of the
+                             built-in integer types.
+                       
+    <DT>FPOverflowSaturate<DD> Use the largest or smallest representable number (depending on sign)
+                               in case of overflow.
+
+    <DT>FPOverflowError<DD> Throw <tt>PreconditionViolation</tt> upon overflow. This is useful for 
+                            debugging.
+    </DL>
+    
+    The implementation relies on Int32-arithmetic and requires that the right-shift operator
+    preserves signedness. Although not enforced by the C++ standard, this is implemented
+    by most of today's processors. This property is checked by a 
+    VIGRA_STATIC_ASSERT(FixedPoint_error__Right_shift_operator_has_unsupported_semantics).
+
+    <tt>FixedPoint16</tt> implements the required interface of an
+    \ref AlgebraicRing and the required numeric and
+    promotion traits. In addition, it supports functions <tt>add</tt>, 
+    <tt>sub</tt>, <tt>mul</tt>, and <tt>div</tt>, where a particular layout 
+    of the result can be enforced. 
+    
+    Built-in numeric types can be converted into <tt>FixedPoint16</tt> by the 
+    appropriate constructors, and from <tt>FixedPoint16</tt> by means of
+    <tt>fixed_point_cast<TargetType>(fixedPoint)</tt>.
+
+    <b>See also:</b>
+    <ul>
+    <li> \ref FixedPoint16Operations
+    <li> \ref FixedPoint16Traits
+    </ul>
+
+    <b>\#include</b> \<vigra/fixedpoint.hxx\><br>
+    Namespace: vigra
+*/
+template <int IntBits, FPOverflowHandling OverflowHandling>
+class FixedPoint16
+{
+public:
+    static const Int32 TOTAL_BITS      = 15; // bit 16 is sign
+    static const Int32 INT_BITS        = IntBits;
+    static const Int32 FRACTIONAL_BITS = TOTAL_BITS - INT_BITS;
+    static const Int32 MAX             = (Int32)((1u << TOTAL_BITS) - 1);
+    static const Int32 MIN             = -(Int32)(1u << TOTAL_BITS);
+    static const Int32 ONE             = 1 << FRACTIONAL_BITS;
+    static const Int32 ONE_HALF        = ONE >> 1;
+    static const Int32 FRACTIONAL_MASK = (1u << FRACTIONAL_BITS) - 1;
+    static const Int32 INT_MASK        = 0xffffffffu ^ FRACTIONAL_MASK;
+    
+    static const FixedPoint16 zero, pi, pi_2, mpi_2; 
+
+    Int16 value;
+
+    FixedPoint16()
+    : value(0)
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
+    }
+
+        /** Construct from an int (fractional part will become zero).
+            Possible overflow is handled according to the target type's <tt>OverflowHandling</tt>.
+        */
+    explicit FixedPoint16(Int32 v)
+    : value(detail::FP16OverflowHandling<OverflowHandling>::exec(v << FRACTIONAL_BITS))
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
+    }
+
+        /** Construct from an int by a bitwise copy. This is normally only used internally.
+        */
+    FixedPoint16(Int32 v, FixedPointNoShift)
+    : value(detail::FP16OverflowHandling<OverflowHandling>::exec(v))
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
+    }
+
+        /** Construct from a double and round the fractional part to 
+            <tt>FRACTIONAL_BITS</tt> accuracy. Possible overflow is handled according 
+            to the target type's <tt>OverflowHandling</tt>.
+        */
+    explicit FixedPoint16(double rhs)
+    : value(detail::FP16OverflowHandling<OverflowHandling>::exec(roundi(rhs * ONE)))
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
+    }
+
+        /** Copy constructor.
+        */
+    FixedPoint16(const FixedPoint16 &other)
+    : value(other.value)
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
+    }
+
+        /** Construct from a FixedPoint16 with different layout. It rounds as appropriate and 
+            handles possible overflow according to the target type's <tt>OverflowHandling</tt>.
+        */
+    template <int IntBits2, FPOverflowHandling OverflowHandling2>
+    FixedPoint16(const FixedPoint16<IntBits2, OverflowHandling2> &other)
+    : value(detail::FP16OverflowHandling<OverflowHandling>::exec(
+            detail::FP16Align<IntBits2, IntBits, /*Round*/true>::exec(other.value)))
+    {
+        VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
+    }
+
+        /** Assignment from int. The fractional part will become zero.  
+            Possible overflow is handled according to the target type's <tt>OverflowHandling</tt>.
+        */
+    FixedPoint16 &operator=(Int32 rhs)
+    {
+        value = detail::FP16OverflowHandling<OverflowHandling>::exec(rhs << FRACTIONAL_BITS);
+        return *this;
+    }
+
+        /** Assignment form double. The fractional part is rounded, and possible overflow is 
+            handled according to the target type's <tt>OverflowHandling</tt>.
+        */
+    FixedPoint16 &operator=(double rhs)
+    {
+        value = detail::FP16OverflowHandling<OverflowHandling>::exec(roundi(rhs * ONE));
+        return *this;
+    }
+
+        /** Copy assignment.
+        */
+    FixedPoint16 & operator=(const FixedPoint16 &other)
+    {
+        value = other.value;
+        return *this;
+    }
+
+        /** Assignment from a FixedPoint16 with different layout. It rounds as appropriate, and possible overflow is 
+            handled according to the target type's <tt>OverflowHandling</tt>.
+        */
+    template <int IntBits2>
+    FixedPoint16 & operator=(const FixedPoint16<IntBits2, OverflowHandling> &other)
+    {
+        value = detail::FP16OverflowHandling<OverflowHandling>::exec(
+                detail::FP16Align<IntBits2, IntBits, /*Round*/true>::exec(other.value));
+        return *this;
+    }
+
+        /** Conversion to float
+        */
+    operator float() const
+    {
+        return fixed_point_cast<float>(*this);
+    }
+
+        /** Conversion to double
+        */
+    operator double() const
+    {
+        return fixed_point_cast<double>(*this);
+    }
+
+        /** Unary plus.
+        */
+    FixedPoint16 operator+() const
+    {
+        return *this;
+    }
+
+        /** Negation.
+        */
+    FixedPoint16 operator-() const
+    {
+        return FixedPoint16(-value, FPNoShift);
+    }
+
+        /** Pre-increment.
+        */
+    FixedPoint16 & operator++()
+    {
+        value = detail::FP16OverflowHandling<OverflowHandling>::exec(value+ONE);
+        return *this;
+    }
+
+        /** Post-increment.
+        */
+    FixedPoint16 operator++(int)
+    {
+        FixedPoint16 old(*this);
+        ++(*this);
+        return old;
+    }
+
+        /** Pre-decrement.
+        */
+    FixedPoint16 & operator--()
+    {
+        value = detail::FP16OverflowHandling<OverflowHandling>::exec(value-ONE);
+        return *this;
+    }
+
+        /** Post-decrement.
+        */
+    FixedPoint16 operator--(int)
+    {
+        FixedPoint16 old(*this);
+        --(*this);
+        return old;
+    }
+
+        /** Add-assignment from a FixedPoint16 with different layout. It rounds as appropriate, and possible overflow is 
+            handled according to the target type's <tt>OverflowHandling</tt>.
+        */
+    template <int IntBits2>
+    FixedPoint16 & operator+=(const FixedPoint16<IntBits2, OverflowHandling> &other)
+    {
+        value = detail::FP16AddImpl<IntBits, IntBits2, IntBits, OverflowHandling>::exec(value, other.value);
+        return *this;
+    }
+
+        /** Subtract-assignment from a FixedPoint16 with different layout. It rounds as appropriate, and possible overflow is 
+            handled according to the target type's <tt>OverflowHandling</tt>.
+        */
+    template <int IntBits2>
+    FixedPoint16 & operator-=(const FixedPoint16<IntBits2, OverflowHandling> &other)
+    {
+        value = detail::FP16SubImpl<IntBits, IntBits2, IntBits, OverflowHandling>::exec(value, other.value);
+        return *this;
+    }
+    
+        /** Multiply-assignment from a FixedPoint16 with different layout. It rounds as appropriate, and possible overflow is 
+            handled according to the target type's <tt>OverflowHandling</tt>.
+        */
+    template <int IntBits2>
+    FixedPoint16 & operator*=(const FixedPoint16<IntBits2, OverflowHandling> &other)
+    {
+        value = detail::FP16MulImpl<IntBits, IntBits2, IntBits, OverflowHandling>::exec(value, other.value);
+        return *this;
+    }
+    
+        /** Divide-assignment from a FixedPoint16 with different layout. It rounds as appropriate, and possible overflow is 
+            handled according to the target type's <tt>OverflowHandling</tt>.
+        */
+    template <int IntBits2>
+    FixedPoint16 & operator/=(const FixedPoint16<IntBits2, OverflowHandling> &other)
+    {
+        value = detail::FP16DivImpl<IntBits, IntBits2, IntBits, OverflowHandling>::exec(value, other.value);
+        return *this;
+    }
+};
+
+template <int IntBits, FPOverflowHandling OverflowHandling>
+const FixedPoint16<IntBits, OverflowHandling> FixedPoint16<IntBits, OverflowHandling>::zero(0);
+
+template <int IntBits, FPOverflowHandling OverflowHandling>
+const FixedPoint16<IntBits, OverflowHandling> FixedPoint16<IntBits, OverflowHandling>::pi(M_PI);
+
+template <int IntBits, FPOverflowHandling OverflowHandling>
+const FixedPoint16<IntBits, OverflowHandling> FixedPoint16<IntBits, OverflowHandling>::pi_2(0.5 * M_PI);
+
+template <int IntBits, FPOverflowHandling OverflowHandling>
+const FixedPoint16<IntBits, OverflowHandling> FixedPoint16<IntBits, OverflowHandling>::mpi_2(-0.5 * M_PI); 
+
+namespace detail {
+
+template <class T>
+struct FixedPoint16Cast;
+
+#define VIGRA_FIXED_POINT_CAST(type) \
+template <> \
+struct FixedPoint16Cast<type> \
+{ \
+    template <int IntBits, FPOverflowHandling OverflowHandling> \
+    static type cast(FixedPoint16<IntBits, OverflowHandling> v) \
+    { \
+        return round(v); \
+    } \
+};
+
+VIGRA_FIXED_POINT_CAST(Int8)
+VIGRA_FIXED_POINT_CAST(UInt8)
+VIGRA_FIXED_POINT_CAST(Int16)
+VIGRA_FIXED_POINT_CAST(UInt16)
+VIGRA_FIXED_POINT_CAST(Int32)
+VIGRA_FIXED_POINT_CAST(UInt32)
+VIGRA_FIXED_POINT_CAST(Int64)
+VIGRA_FIXED_POINT_CAST(UInt64)
+
+#undef VIGRA_FIXED_POINT_CAST
+
+template <>
+struct FixedPoint16Cast<float>
+{
+    template <int IntBits, FPOverflowHandling OverflowHandling>
+    static float cast(FixedPoint16<IntBits, OverflowHandling> v)
+    {
+        return (float)v.value / FixedPoint16<IntBits, OverflowHandling>::ONE;
+    }
+};
+
+template <>
+struct FixedPoint16Cast<double>
+{
+    template <int IntBits, FPOverflowHandling OverflowHandling>
+    static double cast(FixedPoint16<IntBits, OverflowHandling> v)
+    {
+        return (double)v.value / FixedPoint16<IntBits, OverflowHandling>::ONE;
+    }
+};
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*                 FixedPoint16Operations               */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup FixedPoint16Operations Functions for FixedPoint16
+
+    \brief     <b>\#include</b> \<vigra/fixedpoint.hxx\><br>
+
+    These functions fulfill the requirements of an \ref AlgebraicRing.
+
+    Namespace: vigra
+    <p>
+
+ */
+//@{
+
+    /** Convert a FixedPoint16 to a built-in type.
+        If the target is integral, the value is rounded.<br>
+        Usage:
+        \code
+        FixedPoint16<16,15> fp(...);
+        
+        double d = fixed_point_cast<double>(fp);
+        \endcode
+    */
+template <class TARGET, int IntBits, FPOverflowHandling OverflowHandling>
+TARGET fixed_point_cast(FixedPoint16<IntBits, OverflowHandling> v)
+{
+    return detail::FixedPoint16Cast<TARGET>::cast(v);
+}
+
+
+    /// equal
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+inline
+bool operator==(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
+{
+    enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
+    return (l.value << (IntBits1 - MinIntBits)) == (r.value << (IntBits2 - MinIntBits));
+}
+
+    /// not equal
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+inline
+bool operator!=(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
+{
+    enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
+    return (l.value << (IntBits1 - MinIntBits)) != (r.value << (IntBits2 - MinIntBits));
+}
+
+    /// less than
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+inline
+bool operator<(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
+{
+    enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
+    return (l.value << (IntBits1 - MinIntBits)) < (r.value << (IntBits2 - MinIntBits));
+}
+
+    /// less or equal
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+inline
+bool operator<=(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
+{
+    enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
+    return (l.value << (IntBits1 - MinIntBits)) <= (r.value << (IntBits2 - MinIntBits));
+}
+
+    /// greater
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+inline
+bool operator>(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
+{
+    enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
+    return (l.value << (IntBits1 - MinIntBits)) > (r.value << (IntBits2 - MinIntBits));
+}
+
+    /// greater or equal
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+inline
+bool operator>=(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
+{
+    enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
+    return (l.value << (IntBits1 - MinIntBits)) >= (r.value << (IntBits2 - MinIntBits));
+}
+
+    /// addition with automatic determination of the appropriate result type.
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+inline
+typename PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
+operator+(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
+{
+    typedef typename
+        PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
+        Result;
+    return Result(detail::FP16AddImpl<IntBits1, IntBits2, Result::INT_BITS, OverflowHandling>::exec(l.value, r.value), FPNoShift);
+}
+
+    /// addition with enforced result type.
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2, int IntBits3>
+inline 
+FixedPoint16<IntBits3, OverflowHandling> &
+add(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r,
+    FixedPoint16<IntBits3, OverflowHandling> & result)
+{
+    result.value = detail::FP16AddImpl<IntBits1, IntBits2, IntBits3, OverflowHandling>::exec(l.value, r.value);
+    return result;
+}
+
+    /// subtraction with automatic determination of the appropriate result type.
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+inline
+typename PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
+operator-(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
+{
+    typedef typename
+        PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
+        Result;
+    return Result(detail::FP16SubImpl<IntBits1, IntBits2, Result::INT_BITS, OverflowHandling>::exec(l.value, r.value), FPNoShift);
+}
+
+    /// subtraction with enforced result type.
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2, int IntBits3>
+inline FixedPoint16<IntBits3, OverflowHandling> &
+sub(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r,
+    FixedPoint16<IntBits3, OverflowHandling> & result)
+{
+    result.value = detail::FP16SubImpl<IntBits1, IntBits2, IntBits3, OverflowHandling>::exec(l.value, r.value);
+    return result;
+}
+
+    /// multiplication with automatic determination of the appropriate result type.
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+inline
+typename PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
+operator*(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
+{
+    typedef typename
+        PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
+        Result;
+    return Result(detail::FP16MulImpl<IntBits1, IntBits2, Result::INT_BITS, OverflowHandling>::exec(l.value, r.value), FPNoShift);
+}
+
+    /// multiplication with enforced result type.
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2, int IntBits3>
+inline 
+FixedPoint16<IntBits3, OverflowHandling> &
+mul(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r,
+    FixedPoint16<IntBits3, OverflowHandling> & result)
+{
+    result.value = detail::FP16MulImpl<IntBits1, IntBits2, IntBits3, OverflowHandling>::exec(l.value, r.value);
+    return result;
+}
+
+    /// division with automatic determination of the appropriate result type.
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
+inline
+typename PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
+operator/(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
+{
+    typedef typename
+        PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
+        Result;
+    return Result(detail::FP16DivImpl<IntBits1, IntBits2, Result::INT_BITS, OverflowHandling>::exec(l.value, r.value), FPNoShift);
+}
+
+    /// division with enforced result type.
+template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2, int IntBits3>
+inline 
+FixedPoint16<IntBits3, OverflowHandling> &
+div(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r,
+    FixedPoint16<IntBits3, OverflowHandling> & result)
+{
+    result.value = detail::FP16DivImpl<IntBits1, IntBits2, IntBits3, OverflowHandling>::exec(l.value, r.value);
+    return result;
+}
+
+    /// square root.
+template <int IntBits, FPOverflowHandling OverflowHandling>
+inline typename SquareRootTraits<FixedPoint16<IntBits, OverflowHandling> >::SquareRootResult
+sqrt(FixedPoint16<IntBits, OverflowHandling> v)
+{
+    typedef typename SquareRootTraits<FixedPoint16<IntBits, OverflowHandling> >::SquareRootResult Result;
+    enum { Shift = 15 + IntBits - 2*Result::INT_BITS };
+    return Result(sqrti(v.value << Shift), FPNoShift);
+}
+
+#ifndef VIGRA_NO_HYPOT
+    using ::hypot;
+#endif
+
+    /// Length of hypotenuse. 
+template <int IntBits, FPOverflowHandling OverflowHandling>
+inline FixedPoint16<IntBits, OverflowHandling>
+hypot(FixedPoint16<IntBits, OverflowHandling> v1, FixedPoint16<IntBits, OverflowHandling> v2)
+{
+    UInt32 l = abs(v1.value), r = abs(v2.value);   
+    // sq(l) + sq(r) <= 2**31, so overflow handling after sqrti is sufficient
+    return FixedPoint16<IntBits, OverflowHandling>(
+                   detail::FP16OverflowHandling<OverflowHandling>::exec(sqrti(sq(l) + sq(r))), 
+                   FPNoShift);
+}
+
+using std::atan2;
+
+    /// Arctangent. Accuracy better than 1/3 degree (9 significant bits).
+template <int IntBits, FPOverflowHandling OverflowHandling>
+FixedPoint16<2, OverflowHandling>
+atan2(FixedPoint16<IntBits, OverflowHandling> y, FixedPoint16<IntBits, OverflowHandling> x)
+{
+    enum { ResIntBits = 2 };
+    typedef FixedPoint16<ResIntBits, OverflowHandling> FP;
+    static const Int32 Pi_4  = 25736,       // = roundi(0.25 * M_PI * (1 << 15)), at 15 frac bits
+                       Pi3_4 = 77208,       // = roundi(0.75 * M_PI * (1 << 15)),
+                       c1    = 6497,        // = roundi(0.19826763260224867 * (1 << 15)), 
+                       c2    = -1047730238; // = roundi(-0.9757748231899761 * (1 << 30));
+                       
+    // coefficients c1 and c2 minimize
+    //
+    // NIntegrate[(c1 r^3 + c2 r + Pi/4 - a)^4 /. r -> (Cos[a] - Sin[a])/(Cos[a] + Sin[a]), {a, 0, Pi/2}]
+    //
+    // Thanks to Jim Shima, http://www.dspguru.com/comp.dsp/tricks/alg/fxdatan2.htm
+
+    if(x.value == 0)
+        return (y.value > 0)
+                   ? FP::pi_2
+                   : (y.value < 0)
+                         ? FP::mpi_2
+                         : FP::zero;
+                         
+    Int32 abs_y = abs(y.value);
+    Int32 r, angle;
+    if(x.value > 0)
+    {
+        if(y.value == 0)
+            return FP::zero;
+        r = ((x.value - abs_y) << 15) / (x.value + abs_y); // 15 frac bits
+        angle = Pi_4;
+    }
+    else
+    {
+        if(y.value == 0)
+            return FP::pi;
+        r = ((x.value + abs_y) << 15) / (abs_y - x.value); // 15 frac bits
+        angle = Pi3_4;
+    }
+    
+    angle += r*((c2 + c1 * (sq(r) >> 15)) >> 15) >> 15;
+
+    return (y.value > 0)
+               ? FP(detail::FP16Align<0, ResIntBits, true>::exec( angle), FPNoShift)
+               : FP(detail::FP16Align<0, ResIntBits, true>::exec(-angle), FPNoShift);
+}
+
+    /// absolute value.
+template <int IntBits, FPOverflowHandling OverflowHandling>
+inline FixedPoint16<IntBits, OverflowHandling>
+abs(FixedPoint16<IntBits, OverflowHandling> v)
+{
+    return FixedPoint16<IntBits, OverflowHandling>(abs(v.value), FPNoShift);
+}
+
+    /// squared norm (same as v*v).
+template <int IntBits, FPOverflowHandling OverflowHandling>
+inline
+typename NormTraits<FixedPoint16<IntBits, OverflowHandling> >::SquaredNormType
+squaredNorm(FixedPoint16<IntBits, OverflowHandling> v)
+{
+    return v*v;
+}
+
+    /// norm (same as abs).
+template <int IntBits, FPOverflowHandling OverflowHandling>
+inline 
+typename NormTraits<FixedPoint16<IntBits, OverflowHandling> >::NormType
+norm(FixedPoint16<IntBits, OverflowHandling> const & v)
+{
+    return abs(v);
+}
+
+    /// fractional part. (difference between v and its floor)
+template <int IntBits, FPOverflowHandling OverflowHandling>
+inline FixedPoint16<IntBits, OverflowHandling>
+frac(FixedPoint16<IntBits, OverflowHandling> v)
+{
+    return FixedPoint16<IntBits, OverflowHandling>(
+           v.value - (v.value & FixedPoint16<IntBits, OverflowHandling>::INT_MASK), 
+           FPNoShift);
+}
+
+    /// dual fractional part. (1 - frac(v))
+template <int IntBits, FPOverflowHandling OverflowHandling>
+inline FixedPoint16<IntBits, OverflowHandling>
+dual_frac(FixedPoint16<IntBits, OverflowHandling> v)
+{
+    return FixedPoint16<IntBits, OverflowHandling>(
+           FixedPoint16<IntBits, OverflowHandling>::ONE - v.value + (v.value & FixedPoint16<IntBits, OverflowHandling>::INT_MASK), 
+           FPNoShift);
+}
+
+    /// rounding down.
+template <int IntBits, FPOverflowHandling OverflowHandling>
+inline Int32
+floor(FixedPoint16<IntBits, OverflowHandling> v)
+{
+    return(v.value >> FixedPoint16<IntBits, OverflowHandling>::FRACTIONAL_BITS);
+}
+
+    /// rounding up.
+template <int IntBits, FPOverflowHandling OverflowHandling>
+inline Int32
+ceil(FixedPoint16<IntBits, OverflowHandling> v)
+{
+    return((v.value + FixedPoint16<IntBits, OverflowHandling>::FRACTIONAL_MASK) >> 
+                      FixedPoint16<IntBits, OverflowHandling>::FRACTIONAL_BITS);
+}
+
+    /// rounding to the nearest integer.
+template <int IntBits, FPOverflowHandling OverflowHandling>
+inline Int32
+round(FixedPoint16<IntBits, OverflowHandling> v)
+{
+    return((v.value + FixedPoint16<IntBits, OverflowHandling>::ONE_HALF) >> 
+                      FixedPoint16<IntBits, OverflowHandling>::FRACTIONAL_BITS);
+}
+
+    /// rounding to the nearest integer.
+template <int IntBits, FPOverflowHandling OverflowHandling>
+inline Int32
+roundi(FixedPoint16<IntBits, OverflowHandling> v)
+{
+    return round(v);
+}
+
+//@}
+
+} // namespace vigra
+
+namespace std {
+
+template <int IntBits, vigra::FPOverflowHandling OverflowHandling>
+ostream & operator<<(ostream & s, vigra::FixedPoint16<IntBits, OverflowHandling> v)
+{
+    s << vigra::fixed_point_cast<float>(v);
+    return s;
+}
+
+} // namespace std
+
+#endif // VIGRA_FIXEDPOINT_HXX
diff --git a/include/vigra/flatmorphology.hxx b/include/vigra/flatmorphology.hxx
new file mode 100644
index 0000000..ea636f0
--- /dev/null
+++ b/include/vigra/flatmorphology.hxx
@@ -0,0 +1,1416 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_FLATMORPHOLOGY_HXX
+#define VIGRA_FLATMORPHOLOGY_HXX
+
+#include <cmath>
+#include <vector>
+#include "utilities.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup Morphology Basic Morphological Operations
+    Perform erosion, dilation, and median with disc structuring functions
+    
+    See also: \ref MultiArrayMorphology Separable morphology with parabola structuring functions in arbitrary dimensions
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                  discRankOrderFilter                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply rank order filter with disc structuring function to the image.
+
+    The pixel values of the source image <b> must</b> be in the range
+    0...255. Radius must be >= 0. Rank must be in the range 0.0 <= rank 
+    <= 1.0. The filter acts as a minimum filter if rank = 0.0, 
+    as a median if rank = 0.5, and as a maximum filter if rank = 1.0.
+    Accessor are used to access the pixel data.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        discRankOrderFilter(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            int radius, float rank);
+    }
+    \endcode
+    
+    \deprecatedAPI{discRankOrderFilter}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        discRankOrderFilter(SrcIterator upperleft1, 
+                            SrcIterator lowerright1, SrcAccessor sa,
+                            DestIterator upperleft2, DestAccessor da,
+                            int radius, float rank)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        discRankOrderFilter(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<DestIterator, DestAccessor> dest,
+                            int radius, float rank)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/flatmorphology.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w, h), dest(w, h);
+    
+    // do median filtering (because rank=0.5) in a cricle with radius 10
+    discRankOrderFilter(src, dest, 10, 0.5);
+    \endcode
+
+    \deprecatedUsage{discRankOrderFilter}
+    \code
+    vigra::CImage src, dest;
+    
+    // do median filtering
+    vigra::discRankOrderFilter(srcImageRange(src), destImage(dest), 10, 0.5);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator src_upperleft;
+    DestIterator dest_upperleft;
+    int x, y;
+    unsigned char value;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    
+    // value_type of accessor must be convertible to unsigned char
+    value = src_accessor(src_upperleft, x, y); 
+    
+    dest_accessor.set(value, dest_upperleft, x, y);
+    \endcode
+    \deprecatedEnd
+    
+    <b> Preconditions:</b>
+    
+    \code
+    for all source pixels: 0 <= value <= 255
+    
+    (rank >= 0.0) && (rank <= 1.0)
+    radius >= 0
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void discRankOrderFilter)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+discRankOrderFilter(SrcIterator upperleft1, 
+                    SrcIterator lowerright1, SrcAccessor sa,
+                    DestIterator upperleft2, DestAccessor da,
+                    int radius, float rank)
+{
+    vigra_precondition((rank >= 0.0) && (rank <= 1.0),
+            "discRankOrderFilter(): Rank must be between 0 and 1"
+            " (inclusive).");
+    
+    vigra_precondition(radius >= 0,
+            "discRankOrderFilter(): Radius must be >= 0.");
+    
+    int i, x, y, xmax, ymax, xx, yy;
+    int rankpos, winsize, leftsum;
+    
+    long hist[256];
+    
+    // prepare structuring function
+    std::vector<int> struct_function(radius+1);
+    struct_function[0] = radius;
+    
+    double r2 = (double)radius*radius;
+    for(i=1; i<=radius; ++i)
+    {
+        double r = (double) i - 0.5;
+        struct_function[i] = (int)(VIGRA_CSTD::sqrt(r2 - r*r) + 0.5);
+    }
+
+    int w = lowerright1.x - upperleft1.x;
+    int h = lowerright1.y - upperleft1.y;
+    
+    SrcIterator ys(upperleft1);
+    DestIterator yd(upperleft2);
+
+    for(y=0; y<h; ++y, ++ys.y, ++yd.y)
+    {
+        SrcIterator xs(ys);
+        DestIterator xd(yd);
+        
+        // first column
+        int x0 = 0;
+        int y0 = y;
+        int x1 = w - 1;
+        int y1 = h - y - 1;
+
+        // clear histogram
+        for(i=0; i<256; ++i) hist[i] = 0;
+        winsize = 0;
+        
+        // init histogram
+        ymax = (y1 < radius) ? y1 : radius;
+        for(yy=0; yy<=ymax; ++yy)
+        {
+            xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
+            for(xx=0; xx<=xmax; ++xx)
+            {
+                hist[sa(xs, Diff2D(xx, yy))]++;
+                winsize++;
+            }
+        }
+        
+        ymax = (y0 < radius) ? y0 : radius;
+        for(yy=1; yy<=ymax; ++yy)
+        {
+            xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
+            for(xx=0; xx<=xmax; ++xx)
+            {
+                hist[sa(xs, Diff2D(xx, -yy))]++;
+                winsize++;
+            }
+        }
+    
+        // find the desired histogram bin 
+        leftsum = 0;
+        if(rank == 0.0)
+        {
+            for(i=0; i<256; i++)
+            {
+                if(hist[i]) break;
+            }
+            rankpos = i;
+        }
+        else
+        {
+            for(i=0; i<256; i++)
+            {
+                if((float)(hist[i]+leftsum) / winsize >= rank) break;
+                leftsum += hist[i];
+            }
+            rankpos = i;
+        }
+        
+        da.set(rankpos, xd);
+        
+        ++xs.x;
+        ++xd.x;
+        
+        // inner columns
+        for(x=1; x<w; ++x, ++xs.x, ++xd.x)
+        {
+            x0 = x;
+            y0 = y;
+            x1 = w - x - 1;
+            y1 = h - y - 1;
+            
+            // update histogram 
+            // remove pixels at left border 
+            yy = (y1 < radius) ? y1 : radius;
+            for(; yy>=0; yy--)
+            {
+                unsigned char cur;
+                xx = struct_function[yy]+1;
+                if(xx > x0) break;
+                
+                cur = sa(xs, Diff2D(-xx, yy));
+                
+                hist[cur]--;
+                if(cur < rankpos) leftsum--;
+                winsize--;
+            }
+            yy = (y0 < radius) ? y0 : radius;
+            for(; yy>=1; yy--)
+            {
+                unsigned char cur;
+                xx = struct_function[yy]+1;
+                if(xx > x0) break;
+                
+                cur = sa(xs, Diff2D(-xx, -yy));
+                
+                hist[cur]--;
+                if(cur < rankpos) leftsum--;
+                winsize--;
+            }
+            
+            // add pixels at right border 
+            yy = (y1 < radius) ? y1 : radius;
+            for(; yy>=0; yy--)
+            {
+                unsigned char cur;
+                xx = struct_function[yy];
+                if(xx > x1) break;
+                
+                cur = sa(xs, Diff2D(xx, yy));
+                
+                hist[cur]++;
+                if(cur < rankpos) leftsum++;
+                winsize++;
+            }
+            yy = (y0 < radius) ? y0 : radius;
+            for(; yy>=1; yy--)
+            {
+                unsigned char cur;
+                xx = struct_function[yy];
+                if(xx > x1) break;
+                
+                cur = sa(xs, Diff2D(xx, -yy));
+                
+                hist[cur]++;
+                if(cur < rankpos) leftsum++;
+                winsize++;
+            }
+        
+            // find the desired histogram bin 
+            if(rank == 0.0)
+            {
+                if(leftsum == 0)
+                {
+                    // search to the right 
+                    for(i=rankpos; i<256; i++)
+                    {
+                        if(hist[i]) break;
+                    }
+                    rankpos = i;
+                }
+                else
+                {
+                    // search to the left 
+                    for(i=rankpos-1; i>=0; i--)
+                    {
+                        leftsum -= hist[i];
+                        if(leftsum == 0) break;
+                    }
+                    rankpos = i;
+                }
+            }
+            else  // rank > 0.0 
+            {
+                if((float)leftsum / winsize < rank)
+                {
+                    // search to the right 
+                    for(i=rankpos; i<256; i++)
+                    {
+                        if((float)(hist[i]+leftsum) / winsize >= rank) break;
+                        leftsum+=hist[i];
+                    }
+                    rankpos = i;
+                }
+                else
+                {
+                    // search to the left 
+                    for(i=rankpos-1; i>=0; i--)
+                    {
+                        leftsum-=hist[i];
+                        if((float)leftsum / winsize < rank) break;
+                    }
+                    rankpos = i;
+                }
+            }
+                    
+            da.set(rankpos, xd);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+discRankOrderFilter(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    pair<DestIterator, DestAccessor> dest,
+                    int radius, float rank)
+{
+    discRankOrderFilter(src.first, src.second, src.third,
+                        dest.first, dest.second,
+                        radius, rank);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+discRankOrderFilter(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest,
+                    int radius, float rank)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "discRankOrderFilter(): shape mismatch between input and output.");
+    discRankOrderFilter(srcImageRange(src),
+                        destImage(dest),
+                        radius, rank);
+}
+
+/********************************************************/
+/*                                                      */
+/*                      discErosion                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply erosion (minimum) filter with disc of given radius to image.
+
+    This is an abbreviation for the rank order filter with rank = 0.0.
+    See \ref discRankOrderFilter() for more information.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        discErosion(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest,
+                    int radius);
+    }
+    \endcode
+    
+    \deprecatedAPI{discErosion}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        discErosion(SrcIterator upperleft1, 
+                    SrcIterator lowerright1, SrcAccessor sa,
+                    DestIterator upperleft2, DestAccessor da,
+                    int radius)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        discErosion(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    pair<DestIterator, DestAccessor> dest,
+                    int radius)
+    }
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void discErosion)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+discErosion(SrcIterator upperleft1, 
+            SrcIterator lowerright1, SrcAccessor sa,
+            DestIterator upperleft2, DestAccessor da,
+            int radius)
+{
+    vigra_precondition(radius >= 0, "discErosion(): Radius must be >= 0.");
+    
+    discRankOrderFilter(upperleft1, lowerright1, sa, 
+                        upperleft2, da, radius, 0.0);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+discErosion(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            int radius)
+{
+    vigra_precondition(radius >= 0, "discErosion(): Radius must be >= 0.");
+    
+    discRankOrderFilter(src.first, src.second, src.third,
+                        dest.first, dest.second,
+                        radius, 0.0);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+discErosion(MultiArrayView<2, T1, S1> const & src,
+            MultiArrayView<2, T2, S2> dest,
+            int radius)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "discErosion(): shape mismatch between input and output.");
+    discErosion(srcImageRange(src), destImage(dest), radius);
+}
+
+/********************************************************/
+/*                                                      */
+/*                     discDilation                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply dilation (maximum) filter with disc of given radius to image.
+
+    This is an abbreviation for the rank order filter with rank = 1.0.
+    See \ref discRankOrderFilter() for more information.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        discDilation(MultiArrayView<2, T1, S1> const & src,
+                     MultiArrayView<2, T2, S2> dest,
+                     int radius);
+    }
+    \endcode
+    
+    \deprecatedAPI{discDilation}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        discDilation(SrcIterator upperleft1, 
+                    SrcIterator lowerright1, SrcAccessor sa,
+                    DestIterator upperleft2, DestAccessor da,
+                    int radius)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        discDilation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    pair<DestIterator, DestAccessor> dest,
+                    int radius)
+    }
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void discDilation)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+discDilation(SrcIterator upperleft1, 
+            SrcIterator lowerright1, SrcAccessor sa,
+            DestIterator upperleft2, DestAccessor da,
+            int radius)
+{
+    vigra_precondition(radius >= 0, "discDilation(): Radius must be >= 0.");
+    
+    discRankOrderFilter(upperleft1, lowerright1, sa, 
+                        upperleft2, da, radius, 1.0);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+discDilation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+             pair<DestIterator, DestAccessor> dest,
+             int radius)
+{
+    vigra_precondition(radius >= 0, "discDilation(): Radius must be >= 0.");
+    
+    discRankOrderFilter(src.first, src.second, src.third,
+                        dest.first, dest.second,
+                        radius, 1.0);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+discDilation(MultiArrayView<2, T1, S1> const & src,
+             MultiArrayView<2, T2, S2> dest,
+             int radius)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "discDilation(): shape mismatch between input and output.");
+    discDilation(srcImageRange(src), destImage(dest), radius);
+}
+
+/********************************************************/
+/*                                                      */
+/*                      discMedian                      */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply median filter with disc of given radius to image.
+
+    This is an abbreviation for the rank order filter with rank = 0.5.
+    See \ref discRankOrderFilter() for more information.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        discMedian(MultiArrayView<2, T1, S1> const & src,
+                   MultiArrayView<2, T2, S2> dest,
+                   int radius);
+    }
+    \endcode
+    
+    \deprecatedAPI{discMedian}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        discMedian(SrcIterator upperleft1, 
+                    SrcIterator lowerright1, SrcAccessor sa,
+                    DestIterator upperleft2, DestAccessor da,
+                    int radius)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        discMedian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    pair<DestIterator, DestAccessor> dest,
+                    int radius)
+    }
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void discMedian)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+discMedian(SrcIterator upperleft1, 
+            SrcIterator lowerright1, SrcAccessor sa,
+            DestIterator upperleft2, DestAccessor da,
+            int radius)
+{
+    vigra_precondition(radius >= 0, "discMedian(): Radius must be >= 0.");
+    
+    discRankOrderFilter(upperleft1, lowerright1, sa, 
+                        upperleft2, da, radius, 0.5);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+discMedian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+           pair<DestIterator, DestAccessor> dest,
+           int radius)
+{
+    vigra_precondition(radius >= 0, "discMedian(): Radius must be >= 0.");
+    
+    discRankOrderFilter(src.first, src.second, src.third,
+                        dest.first, dest.second,
+                        radius, 0.5);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+discMedian(MultiArrayView<2, T1, S1> const & src,
+           MultiArrayView<2, T2, S2> dest,
+           int radius)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "discMedian(): shape mismatch between input and output.");
+    discMedian(srcImageRange(src), destImage(dest), radius);
+}
+
+/********************************************************/
+/*                                                      */
+/*            discRankOrderFilterWithMask               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply rank order filter with disc structuring function to the image
+    using a mask.
+    
+    The pixel values of the source image <b> must</b> be in the range
+    0...255. Radius must be >= 0. Rank must be in the range 0.0 <= rank 
+    <= 1.0. The filter acts as a minimum filter if rank = 0.0, 
+    as a median if rank = 0.5, and as a maximum filter if rank = 1.0.
+    Accessor are used to access the pixel data.
+    
+    The mask is only applied to th input image, i.e. the function
+    generates an output wherever the current disc contains at least 
+    one pixel with mask value 'true'. Source pixels with mask value
+    'false' are ignored during the calculation of the rank order.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class TM, class SM,
+                  class T2, class S2>
+        void
+        discRankOrderFilterWithMask(MultiArrayView<2, T1, S1> const & src,
+                                    MultiArrayView<2, TM, SM> const & mask,
+                                    MultiArrayView<2, T2, S2> dest,
+                                    int radius, float rank);
+    }
+    \endcode
+    
+    \deprecatedAPI{discRankOrderFilterWithMask}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        discRankOrderFilterWithMask(SrcIterator upperleft1, 
+                                    SrcIterator lowerright1, SrcAccessor sa,
+                                    MaskIterator upperleftm, MaskAccessor mask,
+                                    DestIterator upperleft2, DestAccessor da,
+                                    int radius, float rank)
+    }
+    \endcode
+    group arguments (use in conjunction with \ref ArgumentObjectFactories):
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        discRankOrderFilterWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                    pair<MaskIterator, MaskAccessor> mask,
+                                    pair<DestIterator, DestAccessor> dest,
+                                    int radius, float rank)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/flatmorphology.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w, h), dest(w, h), mask(w, h);
+    ...
+    // do median filtering (since rank=0.5) in a circle with radius 10
+    // but change only the pixels under the mask
+    discRankOrderFilterWithMask(src, mask, dest, 10, 0.5);
+    \endcode
+
+    \deprecatedUsage{discRankOrderFilterWithMask}
+    \code
+    vigra::CImage src, dest, mask;
+    
+    // do median filtering
+    vigra::discRankOrderFilterWithMask(srcImageRange(src), 
+                                maskImage(mask), destImage(dest), 10, 0.5);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator src_upperleft;
+    DestIterator dest_upperleft;
+    MaskIterator mask_upperleft;
+    int x, y;
+    unsigned char value;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    MaskAccessor mask_accessor;
+                     
+    mask_accessor(mask_upperleft, x, y) // convertible to bool
+    
+    // value_type of accessor must be convertible to unsigned char
+    value = src_accessor(src_upperleft, x, y); 
+    
+    dest_accessor.set(value, dest_upperleft, x, y);
+    \endcode
+    \deprecatedEnd
+    
+    <b> Preconditions:</b>
+    
+    \code
+    for all source pixels: 0 <= value <= 255
+    
+    (rank >= 0.0) && (rank <= 1.0)
+    radius >= 0
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void discRankOrderFilterWithMask)
+
+template <class SrcIterator, class SrcAccessor,
+          class MaskIterator, class MaskAccessor,
+          class DestIterator, class DestAccessor>
+void
+discRankOrderFilterWithMask(SrcIterator upperleft1, 
+                            SrcIterator lowerright1, SrcAccessor sa,
+                            MaskIterator upperleftm, MaskAccessor mask,
+                            DestIterator upperleft2, DestAccessor da,
+                            int radius, float rank)
+{
+    vigra_precondition((rank >= 0.0) && (rank <= 1.0),
+                 "discRankOrderFilter(): Rank must be between 0 and 1"
+                 " (inclusive).");
+    
+    vigra_precondition(radius >= 0, "discRankOrderFilter(): Radius must be >= 0.");
+    
+    int i, x, y, xmax, ymax, xx, yy;
+    int rankpos, winsize, leftsum;
+    
+    long hist[256];
+    
+    // prepare structuring function
+    std::vector<int> struct_function(radius+1);
+    struct_function[0] = radius;
+    
+    double r2 = (double)radius*radius;
+    for(i=1; i<=radius; ++i)
+    {
+        double r = (double) i - 0.5;
+        struct_function[i] = (int)(VIGRA_CSTD::sqrt(r2 - r*r) + 0.5);
+    }
+
+    int w = lowerright1.x - upperleft1.x;
+    int h = lowerright1.y - upperleft1.y;
+        
+    SrcIterator ys(upperleft1);
+    MaskIterator ym(upperleftm);
+    DestIterator yd(upperleft2);
+
+    for(y=0; y<h; ++y, ++ys.y, ++yd.y, ++ym.y)
+    {
+        SrcIterator xs(ys);
+        MaskIterator xm(ym);
+        DestIterator xd(yd);
+        
+        // first column
+        int x0 = 0;
+        int y0 = y;
+        int x1 = w - 1;
+        int y1 = h - y - 1;
+
+        // clear histogram
+        for(i=0; i<256; ++i) hist[i] = 0;
+        winsize = 0;
+        leftsum = 0;
+        rankpos = 0;
+        
+        // init histogram
+        ymax = (y1 < radius) ? y1 : radius;
+        for(yy=0; yy<=ymax; ++yy)
+        {
+            xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
+            for(xx=0; xx<=xmax; ++xx)
+            {
+                Diff2D pos(xx, yy);
+                if(mask(xm, pos))
+                {
+                    hist[sa(xs, pos)]++;
+                    winsize++;
+                }
+            }
+        }
+        
+        ymax = (y0 < radius) ? y0 : radius;
+        for(yy=1; yy<=ymax; ++yy)
+        {
+            xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
+            for(xx=0; xx<=xmax; ++xx)
+            {
+                Diff2D pos(xx, -yy);
+                if(mask(xm, pos))
+                {
+                    hist[sa(xs, pos)]++;
+                    winsize++;
+                }
+            }
+        }
+    
+        // find the desired histogram bin 
+        if(winsize) 
+        {
+            if(rank == 0.0)
+            {
+                for(i=0; i<256; i++)
+                {
+                    if(hist[i]) break;
+                }
+                rankpos = i;
+            }
+            else
+            {
+                for(i=0; i<256; i++)
+                {
+                    if((float)(hist[i]+leftsum) / winsize >= rank) break;
+                    leftsum += hist[i];
+                }
+                rankpos = i;
+            }
+            
+            da.set(rankpos, xd);
+        }
+            
+        ++xs.x;
+        ++xd.x;
+        ++xm.x;
+        
+        // inner columns
+        for(x=1; x<w; ++x, ++xs.x, ++xd.x, ++xm.x)
+        {
+            x0 = x;
+            y0 = y;
+            x1 = w - x - 1;
+            y1 = h - y - 1;
+            
+            // update histogram 
+            // remove pixels at left border 
+            yy = (y1 < radius) ? y1 : radius;
+            for(; yy>=0; yy--)
+            {
+                unsigned char cur;
+                xx = struct_function[yy]+1;
+                if(xx > x0) break;
+                
+                Diff2D pos(-xx, yy);
+                if(mask(xm, pos))
+                {
+                    cur = sa(xs, pos);
+                    
+                    hist[cur]--;
+                    if(cur < rankpos) leftsum--;
+                    winsize--;
+                }
+            }
+            yy = (y0 < radius) ? y0 : radius;
+            for(; yy>=1; yy--)
+            {
+                unsigned char cur;
+                xx = struct_function[yy]+1;
+                if(xx > x0) break;
+                
+                Diff2D pos(-xx, -yy);
+                if(mask(xm, pos))
+                {
+                    cur = sa(xs, pos);
+                    
+                    hist[cur]--;
+                    if(cur < rankpos) leftsum--;
+                    winsize--;
+                }
+            }
+            
+            // add pixels at right border 
+            yy = (y1 < radius) ? y1 : radius;
+            for(; yy>=0; yy--)
+            {
+                unsigned char cur;
+                xx = struct_function[yy];
+                if(xx > x1) break;
+                
+                Diff2D pos(xx, yy);
+                if(mask(xm, pos))
+                {
+                    cur = sa(xs, pos);
+                    
+                    hist[cur]++;
+                    if(cur < rankpos) leftsum++;
+                    winsize++;
+                }
+            }
+            yy = (y0 < radius) ? y0 : radius;
+            for(; yy>=1; yy--)
+            {
+                unsigned char cur;
+                xx = struct_function[yy];
+                if(xx > x1) break;
+                
+                Diff2D pos(xx, -yy);
+                if(mask(xm, pos))
+                {
+                    cur = sa(xs, pos);
+                    
+                    hist[cur]++;
+                    if(cur < rankpos) leftsum++;
+                    winsize++;
+                }
+            }
+        
+            // find the desired histogram bin 
+            if(winsize) 
+            {
+                if(rank == 0.0)
+                {
+                    if(leftsum == 0)
+                    {
+                        // search to the right 
+                        for(i=rankpos; i<256; i++)
+                        {
+                            if(hist[i]) break;
+                        }
+                        rankpos = i;
+                    }
+                    else
+                    {
+                        // search to the left 
+                        for(i=rankpos-1; i>=0; i--)
+                        {
+                            leftsum -= hist[i];
+                            if(leftsum == 0) break;
+                        }
+                        rankpos = i;
+                    }
+                }
+                else  // rank > 0.0 
+                {
+                    if((float)leftsum / winsize < rank)
+                    {
+                        // search to the right 
+                        for(i=rankpos; i<256; i++)
+                        {
+                            if((float)(hist[i]+leftsum) / winsize >= rank) break;
+                            leftsum+=hist[i];
+                        }
+                        rankpos = i;
+                    }
+                    else
+                    {
+                        // search to the left 
+                        for(i=rankpos-1; i>=0; i--)
+                        {
+                            leftsum-=hist[i];
+                            if((float)leftsum / winsize < rank) break;
+                        }
+                        rankpos = i;
+                    }
+                }
+                        
+                da.set(rankpos, xd);
+            }
+            else
+            {
+                leftsum = 0;
+                rankpos = 0;
+            }
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class MaskIterator, class MaskAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+discRankOrderFilterWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<MaskIterator, MaskAccessor> mask,
+                            pair<DestIterator, DestAccessor> dest,
+                            int radius, float rank)
+{
+    discRankOrderFilterWithMask(src.first, src.second, src.third,
+                                mask.first, mask.second,
+                                dest.first, dest.second,
+                                radius, rank);
+}
+
+template <class T1, class S1,
+          class TM, class SM,
+          class T2, class S2>
+inline void
+discRankOrderFilterWithMask(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, TM, SM> const & mask,
+                            MultiArrayView<2, T2, S2> dest,
+                            int radius, float rank)
+{
+    vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
+        "discRankOrderFilterWithMask(): shape mismatch between input and output.");
+    discRankOrderFilterWithMask(srcImageRange(src),
+                                maskImage(mask),
+                                destImage(dest),
+                                radius, rank);
+}
+
+/********************************************************/
+/*                                                      */
+/*                 discErosionWithMask                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply erosion (minimum) filter with disc of given radius to image
+    using a mask.
+    
+    This is an abbreviation for the masked rank order filter with 
+    rank = 0.0. See \ref discRankOrderFilterWithMask() for more information.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class TM, class SM,
+                  class T2, class S2>
+        void 
+        discErosionWithMask(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, TM, SM> const & mask,
+                            MultiArrayView<2, T2, S2> dest,
+                            int radius);
+    }
+    \endcode
+    
+    \deprecatedAPI{discErosionWithMask}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        discErosionWithMask(SrcIterator upperleft1, 
+                            SrcIterator lowerright1, SrcAccessor sa,
+                            MaskIterator upperleftm, MaskAccessor mask,
+                            DestIterator upperleft2, DestAccessor da,
+                            int radius)
+    }
+    \endcode
+    group arguments (use in conjunction with \ref ArgumentObjectFactories):
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        discErosionWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<MaskIterator, MaskAccessor> mask,
+                            pair<DestIterator, DestAccessor> dest,
+                            int radius)
+    }
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void discErosionWithMask)
+
+template <class SrcIterator, class SrcAccessor,
+          class MaskIterator, class MaskAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+discErosionWithMask(SrcIterator upperleft1, 
+                    SrcIterator lowerright1, SrcAccessor sa,
+                    MaskIterator upperleftm, MaskAccessor mask,
+                    DestIterator upperleft2, DestAccessor da,
+                    int radius)
+{
+    vigra_precondition(radius >= 0, "discErosionWithMask(): Radius must be >= 0.");
+    
+    discRankOrderFilterWithMask(upperleft1, lowerright1, sa, 
+                                upperleftm, mask,
+                                upperleft2, da,
+                                radius, 0.0);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class MaskIterator, class MaskAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+discErosionWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    pair<MaskIterator, MaskAccessor> mask,
+                    pair<DestIterator, DestAccessor> dest,
+                    int radius)
+{
+    vigra_precondition(radius >= 0, "discErosionWithMask(): Radius must be >= 0.");
+    
+    discRankOrderFilterWithMask(src.first, src.second, src.third,
+                                mask.first, mask.second,
+                                dest.first, dest.second,
+                                radius, 0.0);
+}
+
+template <class T1, class S1,
+          class TM, class SM,
+          class T2, class S2>
+inline void 
+discErosionWithMask(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, TM, SM> const & mask,
+                    MultiArrayView<2, T2, S2> dest,
+                    int radius)
+{
+    vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
+        "discErosionWithMask(): shape mismatch between input and output.");
+    discErosionWithMask(srcImageRange(src), maskImage(mask), destImage(dest), radius);
+}
+
+/********************************************************/
+/*                                                      */
+/*                discDilationWithMask                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply dilation (maximum) filter with disc of given radius to image
+    using a mask.
+    
+    This is an abbreviation for the masked rank order filter with 
+    rank = 1.0. See \ref discRankOrderFilterWithMask() for more information.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class TM, class SM,
+                  class T2, class S2>
+        void 
+        discDilationWithMask(MultiArrayView<2, T1, S1> const & src,
+                             MultiArrayView<2, TM, SM> const & mask,
+                             MultiArrayView<2, T2, S2> dest,
+                             int radius);
+    }
+    \endcode
+    
+    \deprecatedAPI{discDilationWithMask}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        discDilationWithMask(SrcIterator upperleft1, 
+                            SrcIterator lowerright1, SrcAccessor sa,
+                            MaskIterator upperleftm, MaskAccessor mask,
+                            DestIterator upperleft2, DestAccessor da,
+                            int radius)
+    }
+    \endcode
+    group arguments (use in conjunction with \ref ArgumentObjectFactories):
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        discDilationWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<MaskIterator, MaskAccessor> mask,
+                            pair<DestIterator, DestAccessor> dest,
+                            int radius)
+    }
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void discDilationWithMask)
+
+template <class SrcIterator, class SrcAccessor,
+          class MaskIterator, class MaskAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+discDilationWithMask(SrcIterator upperleft1, 
+                     SrcIterator lowerright1, SrcAccessor sa,
+                     MaskIterator upperleftm, MaskAccessor mask,
+                     DestIterator upperleft2, DestAccessor da,
+                     int radius)
+{
+    vigra_precondition(radius >= 0, "discDilationWithMask(): Radius must be >= 0.");
+    
+    discRankOrderFilterWithMask(upperleft1, lowerright1, sa, 
+                                upperleftm, mask,
+                                upperleft2, da,
+                                radius, 1.0);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class MaskIterator, class MaskAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+discDilationWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                     pair<MaskIterator, MaskAccessor> mask,
+                     pair<DestIterator, DestAccessor> dest,
+                     int radius)
+{
+    vigra_precondition(radius >= 0, "discDilationWithMask(): Radius must be >= 0.");
+    
+    discRankOrderFilterWithMask(src.first, src.second, src.third,
+                                mask.first, mask.second,
+                                dest.first, dest.second,
+                                radius, 1.0);
+}
+
+template <class T1, class S1,
+          class TM, class SM,
+          class T2, class S2>
+inline void 
+discDilationWithMask(MultiArrayView<2, T1, S1> const & src,
+                     MultiArrayView<2, TM, SM> const & mask,
+                     MultiArrayView<2, T2, S2> dest,
+                     int radius)
+{
+    vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
+        "discDilationWithMask(): shape mismatch between input and output.");
+    discDilationWithMask(srcImageRange(src), maskImage(mask), destImage(dest), radius);
+}
+
+/********************************************************/
+/*                                                      */
+/*                 discMedianWithMask                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply median filter with disc of given radius to image
+    using a mask.
+    
+    This is an abbreviation for the masked rank order filter with 
+    rank = 0.5. See \ref discRankOrderFilterWithMask() for more information.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class TM, class SM,
+                  class T2, class S2>
+        void 
+        discMedianWithMask(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, TM, SM> const & mask,
+                           MultiArrayView<2, T2, S2> dest,
+                           int radius);
+    }
+    \endcode
+    
+    \deprecatedAPI{discMedianWithMask}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        discMedianWithMask(SrcIterator upperleft1, 
+                            SrcIterator lowerright1, SrcAccessor sa,
+                            MaskIterator upperleftm, MaskAccessor mask,
+                            DestIterator upperleft2, DestAccessor da,
+                            int radius)
+    }
+    \endcode
+    group arguments (use in conjunction with \ref ArgumentObjectFactories):
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        discMedianWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<MaskIterator, MaskAccessor> mask,
+                            pair<DestIterator, DestAccessor> dest,
+                            int radius)
+    }
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void discMedianWithMask)
+
+template <class SrcIterator, class SrcAccessor,
+          class MaskIterator, class MaskAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+discMedianWithMask(SrcIterator upperleft1, 
+                    SrcIterator lowerright1, SrcAccessor sa,
+                    MaskIterator upperleftm, MaskAccessor mask,
+                    DestIterator upperleft2, DestAccessor da,
+                    int radius)
+{
+    vigra_precondition(radius >= 0, "discMedianWithMask(): Radius must be >= 0.");
+    
+    discRankOrderFilterWithMask(upperleft1, lowerright1, sa, 
+                                upperleftm, mask,
+                                upperleft2, da,
+                                radius, 0.5);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class MaskIterator, class MaskAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+discMedianWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<MaskIterator, MaskAccessor> mask,
+                   pair<DestIterator, DestAccessor> dest,
+                   int radius)
+{
+    vigra_precondition(radius >= 0, "discMedianWithMask(): Radius must be >= 0.");
+    
+    discRankOrderFilterWithMask(src.first, src.second, src.third,
+                        mask.first, mask.second,
+                        dest.first, dest.second,
+                        radius, 0.5);
+}
+
+template <class T1, class S1,
+          class TM, class SM,
+          class T2, class S2>
+inline void 
+discMedianWithMask(MultiArrayView<2, T1, S1> const & src,
+                   MultiArrayView<2, TM, SM> const & mask,
+                   MultiArrayView<2, T2, S2> dest,
+                   int radius)
+{
+    vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
+        "discMedianWithMask(): shape mismatch between input and output.");
+    discMedianWithMask(srcImageRange(src), maskImage(mask), destImage(dest), radius);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_FLATMORPHOLOGY_HXX
diff --git a/include/vigra/functorexpression.hxx b/include/vigra/functorexpression.hxx
new file mode 100644
index 0000000..681c07a
--- /dev/null
+++ b/include/vigra/functorexpression.hxx
@@ -0,0 +1,2072 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+#ifndef VIGRA_FUNCTOREXPRESSION_HXX 
+#define VIGRA_FUNCTOREXPRESSION_HXX 
+
+
+/** \page FunctorExpressions Functor Expressions  
+
+    Simple automatic functor creation by means of expression templates
+    (also known as a "lambda library"). Note, however, that the \ref 
+    MultiMathModule module offers similar functionality with an easier
+    syntax.
+
+    <b>\#include</b> \<vigra/functorexpression.hxx\><br>
+    Namespace: vigra::functor
+    
+    <b> Motivation</b>
+    
+    Many generic algorithms are made more flexible by means of functors
+    which define part of the algorithms' behavior according to the
+    needs of a specific situation. For example, we can apply an exponential
+    to each pixel by passing a pointer to the <TT>exp</TT> function 
+    to <TT>transformImage()</TT>:
+    
+    \code
+    vigra::FImage src(w,h), dest(w,h);
+    ... // fill src
+    
+    vigra::transformImage(srcImageRange(src), destImage(dest), &exp);    
+    \endcode
+    
+    However, this only works for simple operations. If we wanted to 
+    apply the exponential to a scaled pixel value (i.e. we want to execute
+    <TT>exp(-beta*v)</TT>), we first need to implement a new functor:
+    
+    \code
+    struct Exponential
+    {
+        Exponential(double b)
+        : beta(b)
+        {}
+        
+        template <class PixelType>
+        PixelType operator()(PixelType const& v) const
+        {
+            return exp(-beta*v);
+        }
+        
+        double beta;
+    };
+    \endcode
+    
+    This functor would be used like this:
+    
+    \code
+    double beta =  ...;
+    vigra::transformImage(srcImageRange(src), destImage(dest), 
+                   Exponential(beta));    
+    \endcode
+    
+    However, this approach has some disadvantages:
+    
+    <UL>
+    
+    <li> Writing a functor is more work then simply program the loop
+          directly, i.e. non-generically. Programmers will tend to
+          avoid generic constructs, if they require so much writing. 
+    <li> Often, functors are only needed for a single expression. 
+          It is not desirable to get into the trouble of introducing 
+          and documenting a new class if that class is used only once.
+    <li> Functors cannot be implemented directly at the point of use.
+          Thus, to find out exactly what a functor is doing, one needs
+          to look somewhere else. This complicates use and maintenance
+          ot generic code.
+    
+    </UL>
+    
+    Therefore, it is necessary to provide a means to generate functors on 
+    the fly where they are needed. The C++ standard library contains so called
+    "functor combinators" that allow to construct complicated functors from 
+    simpler ones. The above problem "apply exp(-beta*v) to every pixel"
+    would be solved like this:
+    
+    \code
+    float beta = ...;
+    
+    vigra::transformImage(srcImageRange(src), destImage(dest), 
+                   std::compose1(std::ptr_fun(exp),
+                                 std::bind1st(std::multiplies<float>(), -beta)));
+    \endcode
+ 
+    I won't go into details on how this works. Suffice it to say that
+    this technique requires a functional programming style that is unfamiliar
+    to many programmers, and thus leads to code that is difficult to 
+    understand. Moreover, this technique has some limitations that prevent 
+    certain expressions from being implementable this way. Therefore, VIGRA
+    provides a better and simpler means to create functors on the fly.
+    
+    <b> Automatic Functor Creation</b>
+    
+    Automatic functor creation in VIGRA is based on a technique called
+    <a href="http://extreme.indiana.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html">Expression Templates</a>.
+    This means that C++ operators are
+    overloaded so that they don't execute the specified operation directly, 
+    but instead produce a functor which will later calculate the result.
+    This technique has the big advantage that the familiar operator notation
+    can be used, while all the flexibility of generic programming is preserved.
+    
+    The above problem "apply <TT>exp(-beta*v)</TT> to every pixel" will be solved
+    like this:
+    
+    \code
+    using namespace vigra::functor;
+    
+    float beta = ...;
+    
+    transformImage(srcImageRange(src), destImage(dest), 
+                   exp(Param(-beta)*Arg1()));
+    \endcode
+    
+    Here, four expression templates have been used to create the desired
+    functor:
+    
+    <DL>
+    
+    <DT><b><TT>Param(-beta):</TT></b><DD> creates a functor that represents a 
+         constant (<TT>-beta</TT> in this case)
+         
+    <DT><b><TT>Arg1():</TT></b><DD> represents the first argument of the expression (i.e.
+         the pixels of image <TT>src</TT> in the example). Likewise, <TT>Arg2()</TT> and
+         <TT>Arg3()</TT> are defined to represent more arguments. These are needed
+         for algorithms that have multiple input images, such as
+         \ref combineTwoImages() and \ref combineThreeImages().
+         
+    <DT><b>* (multiplication):</b><DD> creates a functor that returns the product of
+         its arguments. Likewise, the other C++ operators (i.e. 
+         <TT>+, -, *, /, %, ==, !=, <, <=, >, >=, &&, ||, &, |, ^, !, ~</TT>) 
+         are overloaded.
+    
+    <DT><b><TT>exp():</TT></b><DD> creates a functor that takes the exponential of its 
+        argument. Likewise, the other algebraic functions
+        (i.e. <TT>sq, sqrt, exp, log, log10, sin, asin, cos, acos, tan, 
+        atan, abs, floor, ceil, pow, atan2, fmod, min, max</TT>) 
+        are overloaded.
+    
+    </DL>
+    
+    We will explain additional capabilities of the functor creation mechanism 
+    by means of examples.
+    
+    The same argument can be used several times in the expression. 
+    For example, to calculate the gradient magnitude from the components
+    of the gradient vector, you may write:
+    
+    \code
+    using namespace vigra::functor;
+    
+    vigra::FImage gradient_x(w,h), gradient_y(w,h), magnitude(w,h);
+    ... // calculate gradient_x and gradient_y
+    
+    combineTwoImages(srcImageRange(gradient_x), srcImage(gradient_y),
+                     destImage(magnitude),
+                     sqrt(Arg1()*Arg1() + Arg2()*Arg2()));
+    \endcode
+    
+    It is also possible to build other functions into functor expressions. Suppose 
+    you want to apply <TT>my_complicated_function()</TT> to the sum of two images:
+    
+    \code
+    using namespace vigra::functor;
+    
+    vigra::FImage src1(w,h), src2(w,h), dest(w,h);
+    
+    double my_complicated_function(double);
+    
+    combineTwoImages(srcImageRange(src1), srcImage(src2), destImage(dest),
+                     applyFct(&my_complicated_function, Arg1()+Arg2()));    
+    \endcode
+    
+    [Note that the arguments of the wrapped function are passed as additional
+    arguments to <TT>applyFct()</TT>]
+    
+    You can implement conditional expression by means of the <TT>ifThenElse()</TT> 
+    functor. It corresponds to the "? :" operator that cannot be overloaded.
+    <TT>ifThenElse()</TT> can be used, for example, to threshold an image:
+    
+    \code
+    using namespace vigra::functor;
+    
+    vigra::FImage src(w,h), thresholded(w,h);
+    ...// fill src
+    
+    float threshold = ...;
+    
+    transformImage(srcImageRange(src), destImage(thresholded),
+                   ifThenElse(Arg1() < Param(threshold),
+                              Param(0.0),    // yes branch
+                              Param(1.0))    // no  branch
+                  );
+    \endcode
+
+    You can use the <TT>Var()</TT> functor to assign values to a variable 
+    (<TT>=, +=, -=, *=, /=</TT>  are supported). For example, the average gray
+    value of the image is calculated like this:
+    
+    \code
+    using namespace vigra::functor;
+    
+    vigra::FImage src(w,h);
+    ...// fill src
+    
+    double sum = 0.0;
+    
+    inspectImage(srcImageRange(src), Var(sum) += Arg1());
+    
+    std::cout << "Average: " << (sum / (w*h)) << std::endl;
+    \endcode
+    
+    For use in \ref inspectImage() and its relatives, there is a second
+    conditional functor <TT>ifThen()</TT> that emulates the <TT>if()</TT> statement
+    and does not return a value. Using <TT>ifThen()</TT>, we can calculate the size
+    of an image region:
+    
+    \code
+    using namespace vigra::functor;
+    
+    vigra::IImage label_image(w,h);
+    ...// mark regions by labels in label_image
+    
+    int region_label = ...; // the region we want to inspect
+    int size = 0;
+    
+    inspectImage(srcImageRange(label_image),
+                 ifThen(Arg1() == Param(region_label),
+                        Var(size) += Param(1)));
+                        
+    std::cout << "Size of region " << region_label << ": " << size << std::endl;
+    \endcode
+    
+    Often, we want to execute several commands in one functor. This can be done
+    by means of the overloaded <TT>operator,()</TT> ("operator comma"). Expressions
+    separated by a comma will be executed in succession. We can thus 
+    simultaneously find the size and the average gray value of a region:
+    
+    \code
+    using namespace vigra::functor;
+    
+    vigra::FImage src(w,h);
+    vigra::IImage label_image(w,h);
+    ...// segment src and mark regions in label_image
+    
+    int region_label = ...; // the region we want to inspect
+    int size = 0;
+    double sum = 0.0;
+    
+    inspectTwoImages(srcImageRange(src), srcImage(label_image),
+                     ifThen(Arg2() == Param(region_label),
+                     (
+                        Var(size) += Param(1), // the comma operator is invoked
+                        Var(sum) += Arg1()
+                     )));
+
+    std::cout << "Region " << region_label << ": size = " << size << 
+                                              ", average = " << sum / size << std::endl;
+    \endcode
+    
+    [Note that the list of comma-separated expressions must be enclosed in parentheses.]
+    
+    A comma separated list of expressions can also be applied in the context of
+    \ref transformImage() and its cousins. Here, a general rule of C++ applies: The 
+    return value of a comma expression is the value of its last subexpression.
+    For example, we can initialize an image so that each pixel contains its 
+    address in scan order:
+    
+    \code
+    using namespace vigra::functor;
+    
+    vigra::IImage img(w,h);
+    
+    int count = -1;
+    
+    initImageWithFunctor(destImageRange(img),
+                         (
+                              Var(count) += Param(1),  
+                              Var(count)     // this is the result of the comma expression
+                         ));
+    \endcode
+    
+    Further information about how this mechanism works can be found in
+    <a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/FunctorFactory.ps">this paper</a> (sorry, slightly out of date).
+*/
+
+#ifndef DOXYGEN
+
+#if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
+
+#include <cmath>
+#include "numerictraits.hxx"
+#include "mathutil.hxx"
+#include "functortraits.hxx"
+
+
+namespace vigra {
+
+namespace functor {
+
+/************************************************************/
+/*                                                          */
+/*                 unary functor base template              */
+/*                                                          */
+/************************************************************/
+
+
+struct ErrorType;
+
+template <class Operation>
+struct ResultTraits0;
+
+template <class Operation, class T1>
+struct ResultTraits1
+{
+    typedef T1 Res;
+};
+
+template <class Operation, class T1, class T2>
+struct ResultTraits2
+{
+    typedef typename PromoteTraits<T1, T2>::Promote Res;
+};
+
+template <class Operation, class T1, class T2, class T3>
+struct ResultTraits3
+{
+    typedef typename PromoteTraits<T1, T2>::Promote P1;
+    typedef typename PromoteTraits<P1, T3>::Promote Res;
+};
+
+template <class EXPR>
+struct UnaryFunctor
+{
+    UnaryFunctor(EXPR const & e)
+    : expr_(e)
+    {}
+    
+//    typename ResultTraits0<EXPR>::Res 
+    typename ResultTraits0<EXPR>::Res 
+    operator()() const
+    {
+        return expr_();
+    }
+    
+    template <class T1>
+    typename ResultTraits1<EXPR, T1>::Res 
+    operator()(T1 const & v) const
+    {
+        return expr_(v);
+    }
+    
+    template <class T1, class T2>
+    typename ResultTraits2<EXPR, T1, T2>::Res 
+    operator()(T1 const & v1, T2 const & v2) const
+    {
+        return expr_(v1, v2);
+    }
+    
+    template <class T1, class T2, class T3>
+    typename ResultTraits3<EXPR, T1, T2, T3>::Res 
+    operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
+    {
+        return expr_(v1, v2, v3);
+    }
+  
+  protected:  
+    EXPR expr_;
+  
+  private:
+    UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
+};
+
+template <class Expr>
+struct ResultTraits0<UnaryFunctor<Expr> >
+{
+    typedef typename ResultTraits0<Expr>::Res Res;
+};
+
+template <class Expr, class T1>
+struct ResultTraits1<UnaryFunctor<Expr>, T1>
+{
+    typedef typename ResultTraits1<Expr, T1>::Res Res;
+};
+
+template <class Expr, class T1, class T2>
+struct ResultTraits2<UnaryFunctor<Expr>, T1, T2>
+{
+    typedef typename ResultTraits2<Expr, T1, T2>::Res Res;
+};
+
+template <class Expr, class T1, class T2, class T3>
+struct ResultTraits3<UnaryFunctor<Expr>, T1, T2, T3>
+{
+    typedef typename ResultTraits3<Expr, T1, T2, T3>::Res Res;
+};
+
+/************************************************************/
+/*                                                          */
+/*                 unary functors for arguments             */
+/*                                                          */
+/************************************************************/
+
+struct ArgumentFunctor1; 
+struct ArgumentFunctor2;
+struct ArgumentFunctor3;
+
+template <>
+struct UnaryFunctor<ArgumentFunctor1>
+{
+    UnaryFunctor()
+    {}
+    
+    template <class T1>
+    T1 const & operator()(T1 const & v1) const
+    {
+        return v1;
+    }
+    
+    template <class T1, class T2>
+    T1 const & operator()(T1 const & v1, T2 const &) const
+    {
+        return v1;
+    }
+    
+    template <class T1, class T2, class T3>
+    T1 const & operator()(T1 const & v1, T2 const &, T3 const &) const
+    {
+        return v1;
+    }
+  
+  private:
+    UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
+};
+
+typedef UnaryFunctor<ArgumentFunctor1> Identity;
+
+template <>
+struct ResultTraits0<UnaryFunctor<ArgumentFunctor1> >
+{
+    typedef ErrorType Res;
+};
+
+template <class T1>
+struct ResultTraits1<UnaryFunctor<ArgumentFunctor1>, T1>
+{
+    typedef T1 Res;
+};
+
+template <class T1, class T2>
+struct ResultTraits2<UnaryFunctor<ArgumentFunctor1>, T1, T2>
+{
+    typedef T1 Res;
+};
+
+template <class T1, class T2, class T3>
+struct ResultTraits3<UnaryFunctor<ArgumentFunctor1>, T1, T2, T3>
+{
+    typedef T1 Res;
+};
+
+/************************************************************/
+
+inline
+UnaryFunctor<ArgumentFunctor1> 
+Arg1()
+{
+    return UnaryFunctor<ArgumentFunctor1>();
+}
+
+/************************************************************/
+
+template <>
+struct UnaryFunctor<ArgumentFunctor2>
+{
+    UnaryFunctor()
+    {}
+    
+    template <class T1, class T2>
+    T2 const & operator()(T1 const &, T2 const & v2) const
+    {
+        return v2;
+    }
+    
+    template <class T1, class T2, class T3>
+    T2 const & operator()(T1 const &, T2 const & v2, T3 const &) const
+    {
+        return v2;
+    }
+  
+  private:
+    UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
+};
+
+template <>
+struct ResultTraits0<UnaryFunctor<ArgumentFunctor2> >
+{
+    typedef ErrorType Res;
+};
+
+template <class T1>
+struct ResultTraits1<UnaryFunctor<ArgumentFunctor2>, T1>
+{
+    typedef ErrorType Res;
+};
+
+template <class T1, class T2>
+struct ResultTraits2<UnaryFunctor<ArgumentFunctor2>, T1, T2>
+{
+    typedef T2 Res;
+};
+
+template <class T1, class T2, class T3>
+struct ResultTraits3<UnaryFunctor<ArgumentFunctor2>, T1, T2, T3>
+{
+    typedef T2 Res;
+};
+
+/************************************************************/
+
+inline
+UnaryFunctor<ArgumentFunctor2> 
+Arg2()
+{
+    return UnaryFunctor<ArgumentFunctor2>();
+}
+
+/************************************************************/
+
+template <>
+struct UnaryFunctor<ArgumentFunctor3>
+{
+    UnaryFunctor()
+    {}
+    
+    template <class T1, class T2, class T3>
+    T3 const & operator()(T1 const &, T2 const &, T3 const & v3) const
+    {
+        return v3;
+    }
+  
+  private:
+    UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
+};
+
+template <>
+struct ResultTraits0<UnaryFunctor<ArgumentFunctor3> >
+{
+    typedef ErrorType Res;
+};
+
+template <class T1>
+struct ResultTraits1<UnaryFunctor<ArgumentFunctor3>, T1>
+{
+    typedef ErrorType Res;
+};
+
+template <class T1, class T2>
+struct ResultTraits2<UnaryFunctor<ArgumentFunctor3>, T1, T2>
+{
+    typedef ErrorType Res;
+};
+
+template <class T1, class T2, class T3>
+struct ResultTraits3<UnaryFunctor<ArgumentFunctor3>, T1, T2, T3>
+{
+    typedef T3 Res;
+};
+
+/************************************************************/
+
+inline
+UnaryFunctor<ArgumentFunctor3> 
+Arg3()
+{
+    return UnaryFunctor<ArgumentFunctor3>();
+}
+
+/************************************************************/
+/*                                                          */
+/*                    constant parameters                   */
+/*                                                          */
+/************************************************************/
+
+template <class T>
+struct ParameterFunctor
+{
+    ParameterFunctor(T v)
+    : value_(v)
+    {}
+    
+    T const & operator()() const
+    {
+        return value_;
+    }
+    
+    template <class U1>
+    T const & operator()(U1 const &) const
+    {
+        return value_;
+    }
+    
+    template <class U1, class U2>
+    T const & operator()(U1 const &, U2 const &) const
+    {
+        return value_;
+    }
+    
+    template <class U1, class U2, class U3>
+    T const & operator()(U1 const &, U2 const &, U3 const &) const
+    {
+        return value_;
+    }
+    
+  protected:
+    T value_;
+  
+  private:
+    ParameterFunctor & operator=(ParameterFunctor const &); // not implemented
+};
+
+template <class T>
+struct ResultTraits0<ParameterFunctor<T> >
+{
+    typedef T Res;
+};
+
+template <class T, class T1>
+struct ResultTraits1<ParameterFunctor<T>, T1>
+{
+    typedef T Res;
+};
+
+template <class T, class T1, class T2>
+struct ResultTraits2<ParameterFunctor<T>, T1, T2>
+{
+    typedef T Res;
+};
+
+template <class T, class T1, class T2, class T3>
+struct ResultTraits3<ParameterFunctor<T>, T1, T2, T3>
+{
+    typedef T Res;
+};
+
+template <class T>
+inline UnaryFunctor<ParameterFunctor<T> >
+Param(T const & v)
+{
+    ParameterFunctor<T> fv(v);
+    return UnaryFunctor<ParameterFunctor<T> >(fv);
+}
+
+/************************************************************/
+/*                                                          */
+/*                unary analyser base template              */
+/*                                                          */
+/************************************************************/
+
+
+template <class EXPR>
+class UnaryAnalyser
+{
+  public:
+    UnaryAnalyser(EXPR const & e)
+    : expr_(e)
+    {}
+    
+    void operator()() const
+    {
+        expr_();
+    }
+    
+    template <class T1>
+    void operator()(T1 const & v) const
+    {
+        expr_(v);
+    }
+    
+    template <class T1, class T2>
+    void operator()(T1 const & v1, T2 const & v2) const
+    {
+        expr_(v1, v2);
+    }
+    
+    template <class T1, class T2, class T3>
+    void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
+    {
+        expr_(v1, v2, v3);
+    }
+  protected:
+  
+    EXPR expr_;
+  
+  private:
+    UnaryAnalyser & operator=(UnaryAnalyser const &); // not implemented
+};
+
+/************************************************************/
+/*                                                          */
+/*                     variable assignment                  */
+/*                                                          */
+/************************************************************/
+
+template <class T>
+struct VarFunctor;
+
+template <class T>
+struct UnaryFunctor<VarFunctor<T> >;
+
+/************************************************************/
+
+#define MAKE_ASSIGNMENT_FUNCTOR(name, op) \
+    template <class V, class EXPR> \
+    struct AssignmentFunctor_##name \
+    { \
+        AssignmentFunctor_##name(UnaryFunctor<VarFunctor<V> > v,  \
+                                 UnaryFunctor<EXPR> const & e) \
+        : value_(v.value_), expr_(e) \
+        {} \
+         \
+        V & operator()() const \
+        { \
+            const_cast<V &>(value_) op expr_(); \
+            return const_cast<V &>(value_); \
+        } \
+         \
+        template <class T1>  \
+        V & operator()(T1 const & v1) const \
+        { \
+            const_cast<V &>(value_) op expr_(v1); \
+            return const_cast<V &>(value_); \
+        } \
+         \
+        template <class T1, class T2>  \
+        V & operator()(T1 const & v1, T2 const & v2) const \
+        { \
+            const_cast<V &>(value_) op expr_(v1, v2); \
+            return const_cast<V &>(value_); \
+        } \
+         \
+        template <class T1, class T2, class T3>  \
+        V & operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
+        { \
+            const_cast<V &>(value_) op expr_(v1, v2, v3); \
+            return const_cast<V &>(value_); \
+        } \
+         \
+      private: \
+        V & value_; \
+        UnaryFunctor<EXPR> expr_; \
+        \
+        AssignmentFunctor_##name & operator=(AssignmentFunctor_##name const &);\
+    }; 
+
+/************************************************************/
+
+MAKE_ASSIGNMENT_FUNCTOR(assign, =)
+MAKE_ASSIGNMENT_FUNCTOR(add, +=)
+MAKE_ASSIGNMENT_FUNCTOR(subtract, -=)
+MAKE_ASSIGNMENT_FUNCTOR(multiply, *=)
+MAKE_ASSIGNMENT_FUNCTOR(divide, /=)
+
+#undef MAKE_ASSIGNMENT_FUNCTOR
+
+/************************************************************/
+/*                                                          */
+/*                          variables                       */
+/*                                                          */
+/************************************************************/
+
+template <class T>
+struct UnaryFunctor<VarFunctor<T> >
+{
+    typedef T Res;
+    
+    UnaryFunctor(T & v)
+    : value_(v)
+    {}
+        
+    template <class EXPR>
+    UnaryAnalyser< AssignmentFunctor_assign<T, UnaryFunctor<EXPR> > >
+    operator=(UnaryFunctor<EXPR> const & e)
+    {
+        AssignmentFunctor_assign<T, UnaryFunctor<EXPR> > va(*this, e);
+        return UnaryAnalyser< AssignmentFunctor_assign<T, UnaryFunctor<EXPR> > >(va);
+    }
+    
+    template <class EXPR>
+    UnaryAnalyser< AssignmentFunctor_add<T, UnaryFunctor<EXPR> > >
+    operator+=(UnaryFunctor<EXPR> const & e)
+    {
+        AssignmentFunctor_add<T, UnaryFunctor<EXPR> > va(*this, e);
+        return UnaryAnalyser< AssignmentFunctor_add<T, UnaryFunctor<EXPR> > >(va);
+    }
+    
+    template <class EXPR>
+    UnaryAnalyser< AssignmentFunctor_subtract<T, UnaryFunctor<EXPR> > >
+    operator-=(UnaryFunctor<EXPR> const & e)
+    {
+        AssignmentFunctor_subtract<T, UnaryFunctor<EXPR> > va(*this, e);
+        return UnaryAnalyser< AssignmentFunctor_subtract<T, UnaryFunctor<EXPR> > >(va);
+    }
+    
+    template <class EXPR>
+    UnaryAnalyser< AssignmentFunctor_multiply<T, UnaryFunctor<EXPR> > >
+    operator*=(UnaryFunctor<EXPR> const & e)
+    {
+        AssignmentFunctor_multiply<T, UnaryFunctor<EXPR> > va(*this, e);
+        return UnaryAnalyser< AssignmentFunctor_multiply<T, UnaryFunctor<EXPR> > >(va);
+    }
+    
+    template <class EXPR>
+    UnaryAnalyser< AssignmentFunctor_divide<T, UnaryFunctor<EXPR> > >
+    operator/=(UnaryFunctor<EXPR> const & e)
+    {
+        AssignmentFunctor_divide<T, UnaryFunctor<EXPR> > va(*this, e);
+        return UnaryAnalyser< AssignmentFunctor_divide<T, UnaryFunctor<EXPR> > >(va);
+    }
+    
+    T const & operator()() const
+    {
+        return value_;
+    }
+    
+    template <class U1>
+    T const & operator()(U1 const &) const
+    {
+        return value_;
+    }
+    
+    template <class U1, class U2>
+    T const & operator()(U1 const &, U2 const &) const
+    {
+        return value_;
+    }
+    
+    template <class U1, class U2, class U3>
+    T const & operator()(U1 const &, U2 const &, U3 const &) const
+    {
+        return value_;
+    }
+    
+    T & value_;
+  
+  private:
+    UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
+};
+
+template <class T>
+struct ResultTraits0<UnaryFunctor<VarFunctor<T> > >
+{
+    typedef T Res;
+};
+
+template <class T, class T1>
+struct ResultTraits1<UnaryFunctor<VarFunctor<T> >, T1>
+{
+    typedef T Res;
+};
+
+template <class T, class T1, class T2>
+struct ResultTraits2<UnaryFunctor<VarFunctor<T> >, T1, T2>
+{
+    typedef T Res;
+};
+
+template <class T, class T1, class T2, class T3>
+struct ResultTraits3<UnaryFunctor<VarFunctor<T> >, T1, T2, T3>
+{
+    typedef T Res;
+};
+
+template <class T>
+inline UnaryFunctor<VarFunctor<T> >
+Var(T & v)
+{
+    return UnaryFunctor<VarFunctor<T> >(v);
+}
+
+/************************************************************/
+/*                                                          */
+/*                          if then                         */
+/*                                                          */
+/************************************************************/
+
+template <class EXPR1, class EXPR2>
+struct IfThenFunctor
+{
+    typedef void Res;
+    
+    IfThenFunctor(EXPR1 const & e1, EXPR2 const & e2)
+    : expr1_(e1), expr2_(e2)
+    {}
+    
+    void operator()() const 
+    {
+        if( expr1_() ) expr2_();
+    }
+
+    template <class T> 
+    void operator()(T const & v1) const 
+    {
+        if( expr1_(v1) ) expr2_(v1);
+    }
+
+    template <class T1, class T2> 
+    void operator()(T1 const & v1, T2 const & v2) const 
+    {
+        if( expr1_(v1, v2) ) expr2_(v1, v2);
+    }
+
+    template <class T1, class T2, class T3> 
+    void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const 
+    {
+        if( expr1_(v1, v2, v3) ) expr2_(v1, v2, v3);
+    }
+    
+  private:
+  
+    EXPR1 expr1_;
+    EXPR2 expr2_;
+  
+  private:
+    IfThenFunctor & operator=(IfThenFunctor const &); // not implemented
+};
+
+template <class EXPR1, class EXPR2>
+UnaryAnalyser<IfThenFunctor<UnaryFunctor<EXPR1>, 
+                            UnaryAnalyser<EXPR2> > >
+ifThen(UnaryFunctor<EXPR1> const & e1, 
+       UnaryAnalyser<EXPR2> const & e2)
+{
+    IfThenFunctor<UnaryFunctor<EXPR1>, 
+                  UnaryAnalyser<EXPR2> > p(e1, e2);
+    return UnaryAnalyser<IfThenFunctor<UnaryFunctor<EXPR1>, 
+                                       UnaryAnalyser<EXPR2> > >(p);
+}
+
+/************************************************************/
+/*                                                          */
+/*                         if then else                     */
+/*                                                          */
+/************************************************************/
+
+template <class EXPR1, class EXPR2, class EXPR3>
+struct IfThenElseFunctor;
+
+template <class EXPR1, class EXPR2, class EXPR3>
+struct ResultTraits0<IfThenElseFunctor<EXPR1, EXPR2, EXPR3> >
+{
+    typedef typename ResultTraits0<EXPR2>::Res R2;
+    typedef typename ResultTraits0<EXPR3>::Res R3;
+    typedef typename PromoteTraits<R2, R3>::Promote Res;
+};
+
+template <class EXPR1, class EXPR2, class EXPR3, class T1>
+struct ResultTraits1<IfThenElseFunctor<EXPR1, EXPR2, EXPR3>, T1>
+{
+    typedef typename ResultTraits1<EXPR2, T1>::Res R2;
+    typedef typename ResultTraits1<EXPR3, T1>::Res R3;
+    typedef typename PromoteTraits<R2, R3>::Promote Res;
+};
+
+template <class EXPR1, class EXPR2, class EXPR3, class T1, class T2>
+struct ResultTraits2<IfThenElseFunctor<EXPR1, EXPR2, EXPR3>, T1, T2>
+{
+    typedef typename ResultTraits2<EXPR2, T1, T2>::Res R2;
+    typedef typename ResultTraits2<EXPR3, T1, T2>::Res R3;
+    typedef typename PromoteTraits<R2, R3>::Promote Res;
+};
+
+template <class EXPR1, class EXPR2, class EXPR3, class T1, class T2, class T3>
+struct ResultTraits3<IfThenElseFunctor<EXPR1, EXPR2, EXPR3>, T1, T2, T3>
+{
+    typedef typename ResultTraits3<EXPR2, T1, T2, T3>::Res R2;
+    typedef typename ResultTraits3<EXPR3, T1, T2, T3>::Res R3;
+    typedef typename PromoteTraits<R2, R3>::Promote Res;
+};
+
+template <class EXPR1, class EXPR2, class EXPR3>
+struct IfThenElseFunctor
+{
+    IfThenElseFunctor(EXPR1 const & e1, EXPR2 const & e2, EXPR3 const & e3)
+    : expr1_(e1), expr2_(e2), expr3_(e3)
+    {}
+    
+    typename ResultTraits0<IfThenElseFunctor>::Res 
+    operator()() const 
+    {
+        if(expr1_())
+        {
+            return typename ResultTraits0<IfThenElseFunctor>::Res(expr2_());
+        }
+        else
+        {
+            return typename ResultTraits0<IfThenElseFunctor>::Res(expr3_());
+        }
+    }
+
+    template <class T> 
+    typename ResultTraits1<IfThenElseFunctor, T>::Res 
+    operator()(T const & v1) const 
+    {
+        if(expr1_(v1))
+        {
+            return typename ResultTraits1<IfThenElseFunctor, T>::Res(expr2_(v1));
+        }
+        else
+        {
+            return typename ResultTraits1<IfThenElseFunctor, T>::Res(expr3_(v1));
+        }
+    }
+
+    template <class T1, class T2> 
+    typename ResultTraits2<IfThenElseFunctor, T1, T2>::Res 
+    operator()(T1 const & v1, T2 const & v2) const 
+    {
+        if(expr1_(v1, v2))
+        {
+            return typename ResultTraits2<IfThenElseFunctor, T1, T2>::Res(expr2_(v1, v2));
+        }
+        else
+        {
+            return typename ResultTraits2<IfThenElseFunctor, T1, T2>::Res(expr3_(v1, v2));
+        }
+    }
+
+    template <class T1, class T2, class T3> 
+    typename ResultTraits3<IfThenElseFunctor, T1, T2, T3>::Res 
+    operator()(T1 const & v1, T2 const & v2, T3 const & v3) const 
+    {
+        if(expr1_(v1, v2, v3))
+        {
+            return typename ResultTraits3<IfThenElseFunctor, T1, T2, T3>::Res(expr2_(v1, v2, v3));
+        }
+        else
+        {
+            return typename ResultTraits3<IfThenElseFunctor, T1, T2, T3>::Res(expr3_(v1, v2, v3));
+        }
+    }
+    
+  private:
+  
+    EXPR1 expr1_;
+    EXPR2 expr2_;
+    EXPR3 expr3_;
+  
+    IfThenElseFunctor & operator=(IfThenElseFunctor const &); // not implemented
+};
+
+template <class EXPR1, class EXPR2, class EXPR3>
+UnaryFunctor<IfThenElseFunctor<UnaryFunctor<EXPR1>, 
+                               UnaryFunctor<EXPR2>, 
+                               UnaryFunctor<EXPR3> > >
+ifThenElse(UnaryFunctor<EXPR1> const & e1, 
+           UnaryFunctor<EXPR2> const & e2, 
+           UnaryFunctor<EXPR3> const & e3)
+{
+    IfThenElseFunctor<UnaryFunctor<EXPR1>, 
+                      UnaryFunctor<EXPR2>, 
+                      UnaryFunctor<EXPR3> > p(e1, e2, e3);
+    return UnaryFunctor<IfThenElseFunctor<UnaryFunctor<EXPR1>, 
+                                          UnaryFunctor<EXPR2>, 
+                                          UnaryFunctor<EXPR3> > >(p);
+}
+
+/************************************************************/
+/*                                                          */
+/*                functors for unary functions              */
+/*                                                          */
+/************************************************************/
+
+#define MAKE_FUNCTOR_UNARY_FUNCTION(function, namespc, traitsClass, traitsValue) \
+    using ::namespc::function; \
+    template <class EXPR> \
+    struct Functor_##function; \
+    \
+    template <class EXPR> \
+    struct ResultTraits0<Functor_##function<EXPR> > \
+    { \
+        typedef typename ResultTraits0<EXPR>::Res R1; \
+        typedef typename traitsClass<R1>::traitsValue Res; \
+    }; \
+    \
+    template <class EXPR, class T1> \
+    struct ResultTraits1<Functor_##function<EXPR>, T1> \
+    { \
+        typedef typename ResultTraits1<EXPR, T1>::Res R1; \
+        typedef typename traitsClass<R1>::traitsValue Res; \
+    }; \
+    \
+    template <class EXPR, class T1, class T2> \
+    struct ResultTraits2<Functor_##function<EXPR>, T1, T2> \
+    { \
+        typedef typename ResultTraits2<EXPR, T1, T2>::Res R1; \
+        typedef typename traitsClass<R1>::traitsValue Res; \
+    }; \
+    \
+    template <class EXPR, class T1, class T2, class T3> \
+    struct ResultTraits3<Functor_##function<EXPR>, T1, T2, T3> \
+    { \
+        typedef typename ResultTraits3<EXPR, T1, T2, T3>::Res R1; \
+        typedef typename traitsClass<R1>::traitsValue Res; \
+    }; \
+    \
+    template <class EXPR> \
+    struct Functor_##function \
+    { \
+        Functor_##function(EXPR const & e) \
+        : expr_(e) \
+        {} \
+         \
+        typename ResultTraits0<Functor_##function>::Res \
+        operator()() const \
+        { \
+            return function(expr_()); \
+        } \
+         \
+        template <class T> \
+        typename ResultTraits1<Functor_##function, T>::Res \
+        operator()(T const & v1) const \
+        { \
+            return function(expr_(v1)); \
+        } \
+         \
+        template <class T1, class T2> \
+        typename ResultTraits2<Functor_##function, T1, T2>::Res \
+        operator()(T1 const & v1, T2 const & v2) const \
+        { \
+            return function(expr_(v1, v2)); \
+        } \
+         \
+        template <class T1, class T2, class T3> \
+        typename ResultTraits3<Functor_##function, T1, T2, T3>::Res \
+        operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
+        { \
+            return function(expr_(v1, v2, v3)); \
+        } \
+         \
+      protected: \
+       \
+        EXPR expr_; \
+       \
+      private: \
+        Functor_##function & operator=(Functor_##function const &); \
+    }; \
+     \
+    template <class EXPR> \
+    inline UnaryFunctor<Functor_##function<UnaryFunctor<EXPR> > > \
+    function(UnaryFunctor<EXPR> const & e) \
+    { \
+        Functor_##function<UnaryFunctor<EXPR> > p(e); \
+        return UnaryFunctor<Functor_##function<UnaryFunctor<EXPR> > >(p); \
+    }
+
+/************************************************************/
+
+MAKE_FUNCTOR_UNARY_FUNCTION(sq, vigra, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(sqrt, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(exp, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(log, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(log10, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(sin, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(asin, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(cos, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(acos, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(tan, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(atan, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(floor, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(ceil, std, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(abs, vigra, NumericTraits, RealPromote)
+MAKE_FUNCTOR_UNARY_FUNCTION(norm, vigra, NormTraits, NormType)
+MAKE_FUNCTOR_UNARY_FUNCTION(squaredNorm, vigra, NormTraits, SquaredNormType)
+
+#undef MAKE_FUNCTOR_UNARY_FUNCTION
+
+/************************************************************/
+/*                                                          */
+/*                functors for unary operators              */
+/*                                                          */
+/************************************************************/
+
+#define MAKE_FUNCTOR_UNARY_OPERATOR(name, op) \
+    template <class EXPR> \
+    struct Functor_##name; \
+    \
+    template <class EXPR> \
+    struct ResultTraits0<Functor_##name<EXPR> > \
+    { \
+        typedef typename ResultTraits0<EXPR>::Res Res; \
+    }; \
+    \
+    template <class EXPR, class T1> \
+    struct ResultTraits1<Functor_##name<EXPR>, T1> \
+    { \
+        typedef typename ResultTraits1<EXPR, T1>::Res Res; \
+    }; \
+    \
+    template <class EXPR, class T1, class T2> \
+    struct ResultTraits2<Functor_##name<EXPR>, T1, T2> \
+    { \
+        typedef typename ResultTraits2<EXPR, T1, T2>::Res Res; \
+    }; \
+    \
+    template <class EXPR, class T1, class T2, class T3> \
+    struct ResultTraits3<Functor_##name<EXPR>, T1, T2, T3> \
+    { \
+        typedef typename ResultTraits3<EXPR, T1, T2, T3>::Res Res; \
+    }; \
+    \
+    template <class EXPR> \
+    struct Functor_##name \
+    { \
+        Functor_##name(EXPR const & e) \
+        : expr_(e) \
+        {} \
+         \
+        typename ResultTraits0<Functor_##name>::Res \
+        operator()() const \
+        { \
+            return op expr_(); \
+        } \
+         \
+        template <class T> \
+        typename ResultTraits1<Functor_##name, T>::Res \
+        operator()(T const & v1) const \
+        { \
+            return op expr_(v1); \
+        } \
+         \
+        template <class T1, class T2> \
+        typename ResultTraits2<Functor_##name, T1, T2>::Res \
+        operator()(T1 const & v1, T2 const & v2) const \
+        { \
+            return op expr_(v1, v2); \
+        } \
+         \
+        template <class T1, class T2, class T3> \
+        typename ResultTraits3<Functor_##name, T1, T2, T3>::Res \
+        operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
+        { \
+            return op expr_(v1, v2, v3); \
+        } \
+      protected: \
+       \
+        EXPR expr_; \
+       \
+      private: \
+        Functor_##name & operator=(Functor_##name const &);\
+    }; \
+     \
+    template <class EXPR> \
+    inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR> > > \
+    operator op(UnaryFunctor<EXPR> const & e) \
+    { \
+        Functor_##name<UnaryFunctor<EXPR> > p(e); \
+        return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR> > >(p); \
+    }
+
+
+/************************************************************/
+
+MAKE_FUNCTOR_UNARY_OPERATOR(minus, -)
+MAKE_FUNCTOR_UNARY_OPERATOR(negate, !)
+MAKE_FUNCTOR_UNARY_OPERATOR(bitNegate, ~)
+
+#undef MAKE_FUNCTOR_UNARY_OPERATOR
+
+/************************************************************/
+/*                                                          */
+/*               functors for binary functions              */
+/*                                                          */
+/************************************************************/
+
+#define MAKE_FUNCTOR_BINARY_FUNCTION(function) \
+    using std::function; \
+    template <class EXPR1, class EXPR2> \
+    struct Functor_##function; \
+    \
+    template <class EXPR1, class EXPR2> \
+    struct ResultTraits0<Functor_##function<EXPR1, EXPR2> > \
+    { \
+        typedef typename ResultTraits0<EXPR1>::Res R1; \
+        typedef typename ResultTraits0<EXPR2>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote R3; \
+        typedef typename NumericTraits<R3>::RealPromote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1> \
+    struct ResultTraits1<Functor_##function<EXPR1, EXPR2>, T1> \
+    { \
+        typedef typename ResultTraits1<EXPR1, T1>::Res R1; \
+        typedef typename ResultTraits1<EXPR2, T1>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote R3; \
+        typedef typename NumericTraits<R3>::RealPromote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1, class T2> \
+    struct ResultTraits2<Functor_##function<EXPR1, EXPR2>, T1, T2> \
+    { \
+        typedef typename ResultTraits2<EXPR1, T1, T2>::Res R1; \
+        typedef typename ResultTraits2<EXPR2, T1, T2>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote R3; \
+        typedef typename NumericTraits<R3>::RealPromote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1, class T2, class T3> \
+    struct ResultTraits3<Functor_##function<EXPR1, EXPR2>, T1, T2, T3> \
+    { \
+        typedef typename ResultTraits3<EXPR1, T1, T2, T3>::Res R1; \
+        typedef typename ResultTraits3<EXPR2, T1, T2, T3>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote R3; \
+        typedef typename NumericTraits<R3>::RealPromote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2> \
+    struct Functor_##function \
+    { \
+        Functor_##function(EXPR1 const & e1, EXPR2 const & e2) \
+        : expr1_(e1), expr2_(e2) \
+        {} \
+         \
+        typename ResultTraits0<Functor_##function>::Res \
+        operator()() const \
+        { \
+            return function(expr1_(), expr2_()); \
+        } \
+         \
+        template <class T> \
+        typename ResultTraits1<Functor_##function, T>::Res \
+        operator()(T const & v1) const \
+        { \
+            return function(expr1_(v1), expr2_(v1)); \
+        } \
+         \
+        template <class T1, class T2> \
+        typename ResultTraits2<Functor_##function, T1, T2>::Res \
+        operator()(T1 const & v1, T2 const & v2) const \
+        { \
+            return function(expr1_(v1, v2), expr2_(v1, v2)); \
+        } \
+         \
+        template <class T1, class T2, class T3> \
+        typename ResultTraits3<Functor_##function, T1, T2, T3>::Res \
+        operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
+        { \
+            return function(expr1_(v1, v2, v3), expr2_(v1, v2, v3)); \
+        } \
+         \
+      private: \
+         \
+        EXPR1 expr1_; \
+        EXPR2 expr2_; \
+        \
+        Functor_##function & operator=(Functor_##function const &); \
+    }; \
+     \
+    template <class EXPR1, class EXPR2> \
+    inline UnaryFunctor<Functor_##function<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > > \
+    function(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \
+    { \
+        Functor_##function<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2); \
+        return UnaryFunctor<Functor_##function<UnaryFunctor<EXPR1>,  \
+                                        UnaryFunctor<EXPR2> > >(p); \
+    }
+
+/************************************************************/
+
+MAKE_FUNCTOR_BINARY_FUNCTION(pow)
+MAKE_FUNCTOR_BINARY_FUNCTION(atan2)
+MAKE_FUNCTOR_BINARY_FUNCTION(fmod)
+
+#undef MAKE_FUNCTOR_BINARY_FUNCTION
+
+/************************************************************/
+
+#define MAKE_FUNCTOR_MINMAX(name, op) \
+    template <class EXPR1, class EXPR2> \
+    struct Functor_##name; \
+    \
+    template <class EXPR1, class EXPR2> \
+    struct ResultTraits0<Functor_##name<EXPR1, EXPR2> > \
+    { \
+        typedef typename ResultTraits0<EXPR1>::Res R1; \
+        typedef typename ResultTraits0<EXPR2>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1> \
+    struct ResultTraits1<Functor_##name<EXPR1, EXPR2>, T1> \
+    { \
+        typedef typename ResultTraits1<EXPR1, T1>::Res R1; \
+        typedef typename ResultTraits1<EXPR2, T1>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1, class T2> \
+    struct ResultTraits2<Functor_##name<EXPR1, EXPR2>, T1, T2> \
+    { \
+        typedef typename ResultTraits2<EXPR1, T1, T2>::Res R1; \
+        typedef typename ResultTraits2<EXPR2, T1, T2>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1, class T2, class T3> \
+    struct ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3> \
+    { \
+        typedef typename ResultTraits3<EXPR1, T1, T2, T3>::Res R1; \
+        typedef typename ResultTraits3<EXPR2, T1, T2, T3>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2> \
+    struct Functor_##name \
+    { \
+        Functor_##name(EXPR1 const & e1, EXPR2 const & e2) \
+        : expr1_(e1), expr2_(e2) \
+        {} \
+         \
+        typename ResultTraits0<Functor_##name>::Res \
+        operator()() const \
+        { \
+            typename \
+            ResultTraits0<Functor_##name<EXPR1, EXPR2> >::R1 r1(expr1_()); \
+            typename \
+            ResultTraits0<Functor_##name<EXPR1, EXPR2> >::R2 r2(expr2_()); \
+            return (r1 op r2) ? r1 : r2; \
+        } \
+         \
+        template <class T> \
+        typename ResultTraits1<Functor_##name, T>::Res \
+        operator()(T const & v1) const \
+        { \
+            typename \
+            ResultTraits1<Functor_##name<EXPR1, EXPR2>, T>::R1 r1(expr1_(v1)); \
+            typename \
+            ResultTraits1<Functor_##name<EXPR1, EXPR2>, T>::R2 r2(expr2_(v1)); \
+            return (r1 op r2) ? r1 : r2; \
+        } \
+         \
+        template <class T1, class T2> \
+        typename ResultTraits2<Functor_##name, T1, T2>::Res \
+        operator()(T1 const & v1, T2 const & v2) const \
+        { \
+            typename \
+            ResultTraits2<Functor_##name<EXPR1, EXPR2>, T1, T2>::R1 r1(expr1_(v1, v2)); \
+            typename \
+            ResultTraits2<Functor_##name<EXPR1, EXPR2>, T1, T2>::R2 r2(expr2_(v1, v2)); \
+            return (r1 op r2) ? r1 : r2; \
+        } \
+         \
+        template <class T1, class T2, class T3> \
+        typename ResultTraits3<Functor_##name, T1, T2, T3>::Res \
+        operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
+        { \
+            typename \
+            ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3>::R1 r1(expr1_(v1, v2, v3)); \
+            typename \
+            ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3>::R2 r2(expr2_(v1, v2, v3)); \
+            return (r1 op r2) ? r1 : r2; \
+        } \
+         \
+      private: \
+         \
+        EXPR1 expr1_; \
+        EXPR2 expr2_; \
+        \
+        Functor_##name & operator=(Functor_##name const &); \
+    }; \
+     \
+    template <class EXPR1, class EXPR2> \
+    inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > > \
+    name(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \
+    { \
+        Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2); \
+        return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>,  \
+                                        UnaryFunctor<EXPR2> > >(p); \
+    }
+
+MAKE_FUNCTOR_MINMAX(min, <)
+MAKE_FUNCTOR_MINMAX(max, >)
+
+#undef MAKE_FUNCTOR_MINMAX
+
+/************************************************************/
+/*                                                          */
+/*               functors for binary operators              */
+/*                                                          */
+/************************************************************/
+
+#define MAKE_FUNCTOR_BINARY_OPERATOR(name, op) \
+    template <class EXPR1, class EXPR2> \
+    struct Functor_##name; \
+    \
+    template <class EXPR1, class EXPR2> \
+    struct ResultTraits0<Functor_##name<EXPR1, EXPR2> > \
+    { \
+        typedef typename ResultTraits0<EXPR1>::Res R1; \
+        typedef typename ResultTraits0<EXPR2>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1> \
+    struct ResultTraits1<Functor_##name<EXPR1, EXPR2>, T1> \
+    { \
+        typedef typename ResultTraits1<EXPR1, T1>::Res R1; \
+        typedef typename ResultTraits1<EXPR2, T1>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1, class T2> \
+    struct ResultTraits2<Functor_##name<EXPR1, EXPR2>, T1, T2> \
+    { \
+        typedef typename ResultTraits2<EXPR1, T1, T2>::Res R1; \
+        typedef typename ResultTraits2<EXPR2, T1, T2>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1, class T2, class T3> \
+    struct ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3> \
+    { \
+        typedef typename ResultTraits3<EXPR1, T1, T2, T3>::Res R1; \
+        typedef typename ResultTraits3<EXPR2, T1, T2, T3>::Res R2; \
+        typedef typename PromoteTraits<R1, R2>::Promote Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2> \
+    struct Functor_##name \
+    { \
+        Functor_##name(EXPR1 const & e1, EXPR2 const & e2) \
+        : expr1_(e1), expr2_(e2) \
+        {} \
+         \
+        typename ResultTraits0<Functor_##name>::Res \
+        operator()() const \
+        { \
+            return expr1_() op expr2_(); \
+        } \
+         \
+        template <class T> \
+        typename ResultTraits1<Functor_##name, T>::Res \
+        operator()(T const & v1) const \
+        { \
+            return expr1_(v1) op expr2_(v1); \
+        } \
+         \
+        template <class T1, class T2> \
+        typename ResultTraits2<Functor_##name, T1, T2>::Res \
+        operator()(T1 const & v1, T2 const & v2) const \
+        { \
+            return expr1_(v1, v2) op expr2_(v1, v2); \
+        } \
+         \
+        template <class T1, class T2, class T3> \
+        typename ResultTraits3<Functor_##name, T1, T2, T3>::Res \
+        operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
+        { \
+            return expr1_(v1, v2, v3) op expr2_(v1, v2, v3); \
+        } \
+         \
+      private: \
+         \
+        EXPR1 expr1_; \
+        EXPR2 expr2_; \
+        \
+        Functor_##name & operator=(Functor_##name const &); \
+    }; \
+     \
+    template <class EXPR1, class EXPR2> \
+    inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > > \
+    operator op(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \
+    { \
+        Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2); \
+        return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>,  \
+                                        UnaryFunctor<EXPR2> > >(p); \
+    }
+
+/************************************************************/
+
+MAKE_FUNCTOR_BINARY_OPERATOR(add, +)
+MAKE_FUNCTOR_BINARY_OPERATOR(subtract, -)
+MAKE_FUNCTOR_BINARY_OPERATOR(multiply, *)
+MAKE_FUNCTOR_BINARY_OPERATOR(divide, /)
+MAKE_FUNCTOR_BINARY_OPERATOR(modulo, %)
+MAKE_FUNCTOR_BINARY_OPERATOR(bitAnd, &)
+MAKE_FUNCTOR_BINARY_OPERATOR(bitOr, |)
+MAKE_FUNCTOR_BINARY_OPERATOR(bitXor, ^)
+
+#undef MAKE_FUNCTOR_BINARY_OPERATOR
+
+/************************************************************/
+
+#define MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(name, op) \
+    template <class EXPR1, class EXPR2> \
+    struct Functor_##name; \
+    \
+    template <class EXPR1, class EXPR2> \
+    struct ResultTraits0<Functor_##name<EXPR1, EXPR2> > \
+    { \
+        typedef bool Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1> \
+    struct ResultTraits1<Functor_##name<EXPR1, EXPR2>, T1> \
+    { \
+        typedef bool Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1, class T2> \
+    struct ResultTraits2<Functor_##name<EXPR1, EXPR2>, T1, T2> \
+    { \
+        typedef bool Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2, class T1, class T2, class T3> \
+    struct ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3> \
+    { \
+        typedef bool Res; \
+    }; \
+    \
+    template <class EXPR1, class EXPR2> \
+    struct Functor_##name \
+    { \
+        Functor_##name(EXPR1 const & e1, EXPR2 const & e2) \
+        : expr1_(e1), expr2_(e2) \
+        {} \
+         \
+        bool operator()() const \
+        { \
+            return expr1_() op expr2_(); \
+        } \
+         \
+        template <class T> \
+        bool operator()(T const & v1) const \
+        { \
+            return expr1_(v1) op expr2_(v1); \
+        } \
+         \
+        template <class T1, class T2> \
+        bool operator()(T1 const & v1, T2 const & v2) const \
+        { \
+            return expr1_(v1, v2) op expr2_(v1, v2); \
+        } \
+         \
+        template <class T1, class T2, class T3> \
+        bool operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
+        { \
+            return expr1_(v1, v2, v3) op expr2_(v1, v2, v3); \
+        } \
+         \
+      private: \
+         \
+        EXPR1 expr1_; \
+        EXPR2 expr2_; \
+        \
+        Functor_##name & operator=(Functor_##name const &); \
+    }; \
+     \
+    template <class EXPR1, class EXPR2> \
+    inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > > \
+    operator op(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \
+    { \
+        Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2); \
+        return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>,  \
+                                        UnaryFunctor<EXPR2> > >(p); \
+    }
+
+/************************************************************/
+
+MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(equals, ==)
+MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(differs, !=)
+MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(less, <)
+MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(lessEqual, <=)
+MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(greater, >)
+MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(greaterEqual, >=)
+MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(and, &&)
+MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(or, ||)
+
+#undef MAKE_FUNCTOR_BINARY_OPERATOR_BOOL
+
+/************************************************************/
+/*                                                          */
+/*                         unary apply                      */
+/*                                                          */
+/************************************************************/
+
+template <class EXPR, class RES, class ARG>
+struct UnaryFctPtrFunctor
+{
+    UnaryFctPtrFunctor(EXPR const & e, RES (*fct)(ARG))
+    : expr_(e), f_(fct)
+    {}
+    
+    RES operator()() const 
+    {
+        return f_(expr_());
+    }
+    
+    template <class T> 
+    RES operator()(T const & v1) const 
+    {
+        return f_(expr_(v1));
+    }
+    
+    template <class T1, class T2> 
+    RES operator()(T1 const & v1, T2 const & v2) const 
+    {
+        return f_(expr_(v1, v2));
+    }
+    
+    template <class T1, class T2, class T3> 
+    RES operator()(T1 const & v1, T2 const & v2, T3 const & v3) const 
+    {
+        return f_(expr_(v1, v2, v3));
+    }
+  protected:
+  
+    EXPR expr_;
+    RES (*f_)(ARG);
+  
+  private:
+    UnaryFctPtrFunctor & operator=(UnaryFctPtrFunctor const &); // not implemented
+};
+
+template <class EXPR, class RES, class ARG>
+struct ResultTraits0<UnaryFctPtrFunctor<EXPR, RES, ARG> >
+{
+    typedef RES Res;
+};
+
+template <class EXPR, class RES, class ARG, class T1>
+struct ResultTraits1<UnaryFctPtrFunctor<EXPR, RES, ARG>, T1>
+{
+    typedef RES Res;
+};
+
+template <class EXPR, class RES, class ARG, class T1, class T2>
+struct ResultTraits2<UnaryFctPtrFunctor<EXPR, RES, ARG>, T1, T2>
+{
+    typedef RES Res;
+};
+
+template <class EXPR, class RES, class ARG, class T1, class T2, class T3>
+struct ResultTraits3<UnaryFctPtrFunctor<EXPR, RES, ARG>, T1, T2, T3>
+{
+    typedef RES Res;
+};
+
+template <class EXPR, class RES, class ARG>
+inline UnaryFunctor<UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> >
+applyFct(RES (*f)(ARG), UnaryFunctor<EXPR> const & e)
+{
+    UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> p(e, f);
+    return UnaryFunctor<UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> >(p);
+}
+
+/************************************************************/
+/*                                                          */
+/*                        binary apply                      */
+/*                                                          */
+/************************************************************/
+
+template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2>
+struct BinaryFctPtrFunctor
+{
+    BinaryFctPtrFunctor(EXPR1 const & e1, EXPR2 const & e2, 
+                        RES (*f)(ARG1, ARG2))
+    : expr1_(e1), expr2_(e2), f_(f)
+    {}
+    
+    RES operator()() const 
+    {
+        return f_(expr1_(), expr2_());
+    }
+    
+    template <class T> 
+    RES operator()(T const & v1) const 
+    {
+        return f_(expr1_(v1), expr2_(v1));
+    }
+    
+    template <class T1, class T2> 
+    RES operator()(T1 const & v1, T2 const & v2) const 
+    {
+        return f_(expr1_(v1, v2), expr2_(v1, v2));
+    }
+    
+    template <class T1, class T2, class T3> 
+    RES operator()(T1 const & v1, T2 const & v2, T3 const & v3) const 
+    {
+        return f_(expr1_(v1, v2, v3), expr2_(v1, v2, v3));
+    }
+    
+  protected:
+  
+    EXPR1 expr1_;
+    EXPR2 expr2_;
+    RES (*f_)(ARG1, ARG2);
+  
+  private:
+    BinaryFctPtrFunctor & operator=(BinaryFctPtrFunctor const &); // not implemented
+};
+
+template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2>
+struct ResultTraits0<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2> >
+{
+    typedef RES Res;
+};
+
+template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2, 
+          class T1>
+struct ResultTraits1<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2>, T1>
+{
+    typedef RES Res;
+};
+
+template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2, 
+          class T1, class T2>
+struct ResultTraits2<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2>, T1, T2>
+{
+    typedef RES Res;
+};
+
+template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2, 
+          class T1, class T2, class T3>
+struct ResultTraits3<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2>, T1, T2, T3>
+{
+    typedef RES Res;
+};
+
+template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2>
+inline UnaryFunctor<BinaryFctPtrFunctor<UnaryFunctor<EXPR1>, 
+                                 UnaryFunctor<EXPR2>, 
+                                 RES, ARG1, ARG2> >
+applyFct(RES (*f)(ARG1, ARG2), UnaryFunctor<EXPR1> const & e1, 
+         UnaryFunctor<EXPR2> const & e2)
+{
+    BinaryFctPtrFunctor<UnaryFunctor<EXPR1>, 
+                        UnaryFunctor<EXPR2>, 
+                        RES, ARG1, ARG2>  p(e1, e2, f);
+    return UnaryFunctor<BinaryFctPtrFunctor<UnaryFunctor<EXPR1>, 
+                                            UnaryFunctor<EXPR2>, 
+                                            RES, ARG1, ARG2> >(p);
+}
+
+/************************************************************/
+/*                                                          */
+/*                      comma operator                      */
+/*                                                          */
+/************************************************************/
+
+template <class EXPR1, class EXPR2>
+struct CommaFunctor
+{
+    CommaFunctor(EXPR1 const & e1, EXPR2 const & e2)
+    : expr1_(e1), expr2_(e2)
+    {}
+    
+    typename ResultTraits0<EXPR2>::Res 
+    operator()() const 
+    {
+        expr1_();
+        return expr2_();
+    }
+    
+    template <class T> 
+    typename ResultTraits1<EXPR2, T>::Res 
+    operator()(T const & v1) const 
+    {
+        expr1_(v1);
+        return expr2_(v1);
+    }
+    
+    template <class T1, class T2> 
+    typename ResultTraits2<EXPR2, T1, T2>::Res 
+    operator()(T1 const & v1, T2 const & v2) const 
+    {
+        expr1_(v1, v2);
+        return expr2_(v1, v2);
+    }
+    
+    template <class T1, class T2, class T3> 
+    typename ResultTraits3<EXPR2, T1, T2, T3>::Res 
+    operator()(T1 const & v1, T2 const & v2, T3 const & v3) const 
+    {
+        expr1_(v1, v2, v3);
+        return expr2_(v1, v2, v3);
+    }
+    
+  protected:
+  
+    EXPR1 expr1_;
+    EXPR2 expr2_;
+  
+  private:
+    CommaFunctor & operator=(CommaFunctor const &); // not implemented
+};
+
+template <class Expr1, class Expr2>
+struct ResultTraits0<CommaFunctor<Expr1, Expr2> >
+{
+    typedef typename ResultTraits0<Expr2>::Res Res;
+};
+
+template <class Expr1, class Expr2, class T1>
+struct ResultTraits1<CommaFunctor<Expr1, Expr2>, T1>
+{
+    typedef typename ResultTraits1<Expr2, T1>::Res Res;
+};
+
+template <class Expr1, class Expr2, class T1, class T2>
+struct ResultTraits2<CommaFunctor<Expr1, Expr2>, T1, T2>
+{
+    typedef typename ResultTraits2<Expr2, T1, T2>::Res Res;
+};
+
+template <class Expr1, class Expr2, class T1, class T2, class T3>
+struct ResultTraits3<CommaFunctor<Expr1, Expr2>, T1, T2, T3>
+{
+    typedef typename ResultTraits3<Expr2, T1, T2, T3>::Res Res;
+};
+
+template <class EXPR1, class EXPR2>
+inline UnaryFunctor<CommaFunctor<UnaryAnalyser<EXPR1>, 
+                            UnaryFunctor<EXPR2> > >
+operator,(UnaryAnalyser<EXPR1> const & e1, 
+          UnaryFunctor<EXPR2> const & e2)
+{
+    CommaFunctor<UnaryAnalyser<EXPR1>, 
+                            UnaryFunctor<EXPR2> >  p(e1, e2);
+    return UnaryFunctor<CommaFunctor<UnaryAnalyser<EXPR1>, 
+                            UnaryFunctor<EXPR2> > >(p);
+}
+
+/************************************************************/
+
+template <class EXPR1, class EXPR2>
+struct CommaAnalyser
+{
+    CommaAnalyser(EXPR1 const & e1, EXPR2 const & e2)
+    : expr1_(e1), expr2_(e2)
+    {}
+    
+    void operator()() const 
+    {
+        expr1_();
+        expr2_();
+    }
+    
+    template <class T> 
+    void operator()(T const & v1) const 
+    {
+        expr1_(v1);
+        expr2_(v1);
+    }
+    
+    template <class T1, class T2> 
+    void operator()(T1 const & v1, T2 const & v2) const 
+    {
+        expr1_(v1, v2);
+        expr2_(v1, v2);
+    }
+    
+    template <class T1, class T2, class T3> 
+    void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const 
+    {
+        expr1_(v1, v2, v3);
+        expr2_(v1, v2, v3);
+    }
+    
+  protected:
+  
+    EXPR1 expr1_;
+    EXPR2 expr2_;
+  
+  private:
+    CommaAnalyser & operator=(CommaAnalyser const &); // not implemented
+};
+
+template <class EXPR1, class EXPR2>
+inline UnaryAnalyser<CommaAnalyser<UnaryAnalyser<EXPR1>, 
+                            UnaryAnalyser<EXPR2> > >
+operator,(UnaryAnalyser<EXPR1> const & e1, 
+          UnaryAnalyser<EXPR2> const & e2)
+{
+    CommaAnalyser<UnaryAnalyser<EXPR1>, 
+                            UnaryAnalyser<EXPR2> >  p(e1, e2);
+    return UnaryAnalyser<CommaAnalyser<UnaryAnalyser<EXPR1>, 
+                            UnaryAnalyser<EXPR2> > >(p);
+}
+
+} // namespace functor
+
+#if defined(__GNUC__) &&  __GNUC__ < 3
+using functor::Arg1;
+using functor::Arg2;
+using functor::Arg3;
+using functor::Param;
+#endif
+
+template <class T>
+class FunctorTraits<functor::UnaryFunctor<T> >
+: public FunctorTraitsBase<functor::UnaryFunctor<T> >
+{
+  public:
+    typedef VigraTrueType isInitializer;
+    typedef VigraTrueType isUnaryFunctor;
+    typedef VigraTrueType isBinaryFunctor;
+    typedef VigraTrueType isTernaryFunctor;
+};
+
+template <class T>
+class FunctorTraits<functor::UnaryAnalyser<T> >
+: public FunctorTraitsBase<functor::UnaryAnalyser<T> >
+{
+  public:
+    typedef VigraTrueType isUnaryAnalyser;
+    typedef VigraTrueType isBinaryAnalyser;
+    typedef VigraTrueType isTernaryAnalyser;
+};
+
+
+
+} // namespace vigra
+
+#endif /* NO_PARTIAL_TEMPLATE_SPECIALIZATION */
+
+#endif // DOXYGEN
+
+#endif /* VIGRA_FUNCTOREXPRESSION_HXX  */
+
+
diff --git a/include/vigra/functortraits.hxx b/include/vigra/functortraits.hxx
new file mode 100644
index 0000000..175ffbf
--- /dev/null
+++ b/include/vigra/functortraits.hxx
@@ -0,0 +1,266 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2005 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_FUNCTORTRAITS_HXX
+#define VIGRA_FUNCTORTRAITS_HXX
+
+#include <functional>
+#include "metaprogramming.hxx"
+
+namespace vigra {
+
+struct InitializerTag {};
+struct UnaryFunctorTag {};
+struct BinaryFunctorTag {};
+struct TernaryFunctorTag {};
+struct UnaryAnalyserTag {};
+struct BinaryAnalyserTag {};
+struct TernaryAnalyserTag {};
+
+struct UnaryReduceFunctorTag
+: public InitializerTag, public UnaryAnalyserTag
+{};
+
+struct BinaryReduceFunctorTag
+: public InitializerTag, public BinaryAnalyserTag
+{};
+
+typedef UnaryFunctorTag UnaryExpandFunctorTag;
+typedef BinaryFunctorTag BinaryExpandFunctorTag;
+
+template <class T>
+class FunctorTraitsBase
+{
+  public:
+    typedef T type;
+    
+    typedef typename IsDerivedFrom<T, InitializerTag>::result isInitializer;
+
+    typedef typename IsDerivedFrom<T, UnaryFunctorTag>::result isUnaryFunctor;
+    typedef typename IsDerivedFrom<T, BinaryFunctorTag>::result isBinaryFunctor;
+    typedef typename IsDerivedFrom<T, TernaryFunctorTag>::result isTernaryFunctor;
+
+    typedef typename IsDerivedFrom<T, UnaryAnalyserTag>::result isUnaryAnalyser;
+    typedef typename IsDerivedFrom<T, BinaryAnalyserTag>::result isBinaryAnalyser;
+    typedef typename IsDerivedFrom<T, TernaryAnalyserTag>::result isTernaryAnalyser;
+};
+
+
+
+/** \addtogroup Functors
+*/
+//@{
+/** \brief Export associated information for a functor.
+
+    The FunctorTraits class contains the following fields:
+
+    \code
+    template <class T>
+    struct FunctorTraits
+    {
+        typedef T type;
+        
+        typedef ... isInitializer;
+
+        typedef ... isUnaryFunctor;
+        typedef ... isBinaryFunctor;
+        typedef ... isTernaryFunctor;
+        
+        typedef ... isUnaryAnalyser;
+        typedef ... isBinaryAnalyser;
+        typedef ... isTernaryAnalyser;
+    };
+    \endcode
+
+    where the dots are either <tt>VigraTrueType</tt> or <tt>VigraFalseType</tt>
+    depending on whether the functor supports the respective functionality or not.
+    Note that these traits are automatically defined correctly when your functor is derived 
+    from the appropriate functor tag classes: 
+    
+    \code
+    struct InitializerTag {};
+    struct UnaryFunctorTag {};
+    struct BinaryFunctorTag {};
+    struct TernaryFunctorTag {};
+    struct UnaryAnalyserTag {};
+    struct BinaryAnalyserTag {};
+    struct TernaryAnalyserTag {};
+    struct UnaryReduceFunctorTag : public InitializerTag, public UnaryAnalyserTag {};
+    struct BinaryReduceFunctorTag : public InitializerTag, public BinaryAnalyserTag {};
+    \endcode
+    
+    If a functor <tt>f</tt> is a model of these categories, it supports the following
+    calls (<tt>v</tt> is a variable such that the result type of the functor
+    calls can be converted into <tt>v</tt>'s type, and <tt>a1, a2, a3</tt> are
+    variables convertible into the functor's argument types):
+    
+    <DL>
+    <DT><b>Initializer</b>
+        <DD> <tt>v = f()</tt> (used with initImageWithFunctor())
+    <DT><b>UnaryFunctor</b>
+        <DD> <tt>v = f(a1)</tt> (used with transformImage())
+    <DT><b>BinaryFunctor</b>
+        <DD> <tt>v = f(a1, a2)</tt> (used with combineTwoImages())
+    <DT><b>TernaryFunctor</b>
+        <DD> <tt>v = f(a1, a2, a3)</tt> (used with combineThreeImages())
+    <DT><b>UnaryAnalyser</b>
+        <DD> <tt>f(a1)</tt> (return type <tt>void</tt>, used with inspectImage())
+    <DT><b>BinaryAnalyser</b>
+        <DD> <tt>f(a1, a2)</tt> (return type <tt>void</tt>, used with inspectTwoImages())
+    <DT><b>TernaryAnalyser</b>
+        <DD> <tt>f(a1, a2, a3)</tt> (return type <tt>void</tt>)
+    </DL>
+    
+    It should be noted that the functor's argument and result types are not contained
+    in the traits class: Since the function calls are often member template functions in 
+    VIGRA, many functors do not have fixed argument types. Neither are the result
+    types fixed in this case because they are computed (via a template meta-program)
+    from the argument types.
+
+    <b>\#include</b> \<vigra/functortraits.hxx\> <br/>
+    Namespace: vigra
+*/
+template <class T>
+class FunctorTraits
+: public FunctorTraitsBase<T>
+{};
+
+#define VIGRA_DEFINE_STL_FUNCTOR(name, unary, binary) \
+template <class T> \
+class FunctorTraits<name<T> > \
+{ \
+  public: \
+    typedef T type; \
+     \
+    typedef VigraFalseType isInitializer; \
+     \
+    typedef unary          isUnaryFunctor; \
+    typedef binary         isBinaryFunctor; \
+    typedef VigraFalseType isTernaryFunctor; \
+     \
+    typedef VigraFalseType isUnaryAnalyser; \
+    typedef VigraFalseType isBinaryAnalyser; \
+    typedef VigraFalseType isTernaryAnalyser; \
+};
+
+// ???TODO: these should also be specialized for the ptr_fun and mem_fun_ptr wrappers
+VIGRA_DEFINE_STL_FUNCTOR(std::plus, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::minus, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::multiplies, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::divides, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::modulus, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::equal_to, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::not_equal_to, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::greater, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::less, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::greater_equal, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::less_equal, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::logical_and, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::logical_or, VigraFalseType, VigraTrueType)
+VIGRA_DEFINE_STL_FUNCTOR(std::binary_negate, VigraFalseType, VigraTrueType)
+
+VIGRA_DEFINE_STL_FUNCTOR(std::negate, VigraTrueType, VigraFalseType)
+VIGRA_DEFINE_STL_FUNCTOR(std::logical_not, VigraTrueType, VigraFalseType)
+VIGRA_DEFINE_STL_FUNCTOR(std::unary_negate, VigraTrueType, VigraFalseType)
+VIGRA_DEFINE_STL_FUNCTOR(std::binder1st, VigraTrueType, VigraFalseType)
+VIGRA_DEFINE_STL_FUNCTOR(std::binder2nd, VigraTrueType, VigraFalseType)
+#undef VIGRA_DEFINE_STL_FUNCTOR
+
+template <class R>
+class FunctorTraits<R (*)()>
+{
+  public:
+    typedef R (*type)();
+    
+    typedef VigraTrueType  isInitializer;
+    typedef VigraFalseType isUnaryFunctor;
+    typedef VigraFalseType isBinaryFunctor;
+    typedef VigraFalseType isTernaryFunctor;
+    typedef VigraFalseType isUnaryAnalyser;
+    typedef VigraFalseType isBinaryAnalyser;
+    typedef VigraFalseType isTernaryAnalyser;
+};
+
+template <class R, class T>
+class FunctorTraits<R (*)(T)>
+{
+  public:
+    typedef R (*type)(T);
+    
+    typedef VigraFalseType isInitializer;
+    typedef VigraTrueType  isUnaryFunctor;
+    typedef VigraFalseType isBinaryFunctor;
+    typedef VigraFalseType isTernaryFunctor;
+    typedef VigraFalseType isUnaryAnalyser;
+    typedef VigraFalseType isBinaryAnalyser;
+    typedef VigraFalseType isTernaryAnalyser;
+};
+
+template <class R, class T1, class T2>
+class FunctorTraits<R (*)(T1, T2)>
+{
+  public:
+    typedef R (*type)(T1, T2);
+    
+    typedef VigraFalseType isInitializer;
+    typedef VigraFalseType isUnaryFunctor;
+    typedef VigraTrueType  isBinaryFunctor;
+    typedef VigraFalseType isTernaryFunctor;
+    typedef VigraFalseType isUnaryAnalyser;
+    typedef VigraFalseType isBinaryAnalyser;
+    typedef VigraFalseType isTernaryAnalyser;
+};
+
+template <class R, class T1, class T2, class T3>
+class FunctorTraits<R (*)(T1, T2, T3)>
+{
+  public:
+    typedef R (*type)(T1, T2, T3);
+    
+    typedef VigraFalseType isInitializer;
+    typedef VigraFalseType isUnaryFunctor;
+    typedef VigraFalseType isBinaryFunctor;
+    typedef VigraTrueType  isTernaryFunctor;
+    typedef VigraFalseType isUnaryAnalyser;
+    typedef VigraFalseType isBinaryAnalyser;
+    typedef VigraFalseType isTernaryAnalyser;
+};
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_FUNCTORTRAITS_HXX
diff --git a/include/vigra/gaborfilter.hxx b/include/vigra/gaborfilter.hxx
new file mode 100644
index 0000000..5411541
--- /dev/null
+++ b/include/vigra/gaborfilter.hxx
@@ -0,0 +1,458 @@
+/************************************************************************/
+/*                                                                      */
+/*         Copyright 2002-2004 by Ullrich Koethe and Hans Meine         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_GABORFILTER_HXX
+#define VIGRA_GABORFILTER_HXX
+
+#include "imagecontainer.hxx"
+#include "config.hxx"
+#include "stdimage.hxx"
+#include "copyimage.hxx"
+#include "transformimage.hxx"
+#include "combineimages.hxx"
+#include "utilities.hxx"
+#include "multi_shape.hxx"
+
+#include <functional>
+#include <vector>
+#include <cmath>
+
+namespace vigra {
+
+/** \addtogroup GaborFilter Gabor Filter
+    Functions to create or apply gabor filter (latter based on FFTW).
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                   createGaborFilter                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Create a gabor filter in frequency space.
+
+    The orientation is given in radians, the other parameters are the
+    center frequency (for example 0.375 or smaller) and the two
+    angular and radial sigmas of the gabor filter. (See \ref
+    angularGaborSigma() for an explanation of possible values.)
+
+    The energy of the filter is explicitly normalized to 1.0.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S>
+        void
+        createGaborFilter(MultiArrayView<2, T, S> dest,
+                          double orientation, double centerFrequency,
+                          double angularSigma, double radialSigma);
+    }
+    \endcode
+
+    \deprecatedAPI{createGaborFilter}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class DestImageIterator, class DestAccessor>
+        void createGaborFilter(DestImageIterator destUpperLeft,
+                               DestImageIterator destLowerRight,
+                               DestAccessor da,
+                               double orientation, double centerFrequency,
+                               double angularSigma, double radialSigma)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class DestImageIterator, class DestAccessor>
+        void createGaborFilter(triple<DestImageIterator,
+                                      DestImageIterator,
+                                      DestAccessor> dest,
+                               double orientation, double centerFrequency,
+                               double angularSigma, double radialSigma)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/gaborfilter.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> gabor(w,h);
+
+    createGaborFilter(gabor, orient, freq,
+                      angularGaborSigma(directionCount, freq),
+                      radialGaborSigma(freq));
+    \endcode
+
+    \deprecatedUsage{createGaborFilter}
+    \code
+    vigra::FImage gabor(w,h);
+
+    vigra::createGaborFilter(destImageRange(gabor), orient, freq,
+                             angularGaborSigma(directionCount, freq),
+                             radialGaborSigma(freq));
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void createGaborFilter)
+
+template <class DestImageIterator, class DestAccessor>
+void createGaborFilter(DestImageIterator destUpperLeft,
+                       DestImageIterator destLowerRight, DestAccessor da,
+                       double orientation, double centerFrequency,
+                       double angularSigma, double radialSigma)
+{
+    int w = int(destLowerRight.x - destUpperLeft.x);
+    int h = int(destLowerRight.y - destUpperLeft.y);
+
+    double squaredSum = 0.0;
+    double cosTheta= VIGRA_CSTD::cos(orientation);
+    double sinTheta= VIGRA_CSTD::sin(orientation);
+
+    double radialSigma2 = radialSigma*radialSigma;
+    double angularSigma2 = angularSigma*angularSigma;
+
+    double wscale = w % 1 ?
+                    1.0f / (w-1) :
+                    1.0f / w;
+    double hscale = h % 1 ?
+                    1.0f / (h-1) :
+                    1.0f / h;
+
+    int dcX= (w+1)/2, dcY= (h+1)/2;
+
+    double u, v;
+    for ( int y=0; y<h; y++, destUpperLeft.y++ )
+    {
+        typename DestImageIterator::row_iterator dix = destUpperLeft.rowIterator();
+
+        v = hscale * ((h - (y - dcY))%h - dcY);
+        for ( int x=0; x<w; x++, dix++ )
+        {
+            u= wscale*((x - dcX + w)%w - dcX);
+
+            double uu = cosTheta*u + sinTheta*v - centerFrequency;
+            double vv = -sinTheta*u + cosTheta*v;
+            double gabor;
+
+            gabor = VIGRA_CSTD::exp(-0.5*(uu*uu / radialSigma2 + vv*vv / angularSigma2));
+            squaredSum += gabor * gabor;
+            da.set( gabor, dix );
+        }
+    }
+    destUpperLeft.y -= h;
+
+    // clear out DC value and remove it from the squared sum
+    double dcValue = da(destUpperLeft);
+    squaredSum -= dcValue * dcValue;
+    da.set( 0.0, destUpperLeft );
+
+    // normalize energy to one
+    double factor = VIGRA_CSTD::sqrt(squaredSum);
+    for ( int y=0; y<h; y++, destUpperLeft.y++ )
+    {
+        typename DestImageIterator::row_iterator dix = destUpperLeft.rowIterator();
+
+        for ( int x=0; x<w; x++, dix++ )
+        {
+            da.set( da(dix) / factor, dix );
+        }
+    }
+}
+
+template <class DestImageIterator, class DestAccessor>
+inline void
+createGaborFilter(triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
+                  double orientation, double centerFrequency,
+                  double angularSigma, double radialSigma)
+{
+    createGaborFilter(dest.first, dest.second, dest.third,
+                      orientation, centerFrequency,
+                      angularSigma, radialSigma);
+}
+
+template <class T, class S>
+inline void
+createGaborFilter(MultiArrayView<2, T, S> dest,
+                  double orientation, double centerFrequency,
+                  double angularSigma, double radialSigma)
+{
+    createGaborFilter(destImageRange(dest),
+                      orientation, centerFrequency,
+                      angularSigma, radialSigma);
+}
+
+/********************************************************/
+/*                                                      */
+/*                   radialGaborSigma                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate sensible radial sigma for given parameters.
+
+    For a brief introduction what is meant with "sensible" sigmas, see
+    \ref angularGaborSigma().
+
+    <b> Declaration:</b>
+
+    \code
+    namespace vigra {
+        double radialGaborSigma(double centerFrequency)
+    }
+    \endcode
+ */
+
+inline double radialGaborSigma(double centerFrequency)
+{
+    double sfactor = 3.0 * VIGRA_CSTD::sqrt(VIGRA_CSTD::log(4.0));
+    return centerFrequency / sfactor;
+}
+
+/********************************************************/
+/*                                                      */
+/*                   angularGaborSigma                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate sensible angular sigma for given parameters.
+
+    "Sensible" means: If you use a range of gabor filters for feature
+    detection, you are interested in minimal redundancy. This is hard
+    to define but one possible try is to arrange the filters in
+    frequency space, so that the half-peak-magnitude ellipses touch
+    each other.
+
+    To do so, you must know the number of directions (first parameter
+    for the angular sigma function) and the center frequency of the
+    filter you want to calculate the sigmas for.
+
+    The exact formulas are:
+    \code
+    sigma_radial= 1/sqrt(ln(4)) * centerFrequency/3
+    \endcode
+
+    \code
+    sigma_angular= 1/sqrt(ln(4)) * tan(pi/(directions*2))
+                   * sqrt(8/9) * centerFrequency
+    \endcode
+
+    <b> Declaration:</b>
+
+    \code
+    namespace vigra {
+        double angularGaborSigma(int directionCount, double centerFrequency)
+    }
+    \endcode
+ */
+
+inline double angularGaborSigma(int directionCount, double centerFrequency)
+{
+    return VIGRA_CSTD::tan(M_PI/directionCount/2.0) * centerFrequency
+        * VIGRA_CSTD::sqrt(8.0 / (9 * VIGRA_CSTD::log(4.0)));
+}
+
+/********************************************************/
+/*                                                      */
+/*                   GaborFilterFamily                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Family of gabor filters of different scale and direction.
+
+    A GaborFilterFamily can be used to quickly create a whole family
+    of gabor filters in frequency space. Especially useful in
+    conjunction with \ref applyFourierFilterFamily, since it's derived
+    from \ref ImageArray.
+
+    The filter parameters are chosen to make the center frequencies
+    decrease in octaves with increasing scale indices, and to make the
+    half-peak-magnitude ellipses touch each other to somewhat reduce
+    redundancy in the filter answers. This is done by using \ref
+    angularGaborSigma() and \ref radialGaborSigma(), you'll find more
+    information there.
+
+    The template parameter ImageType should be a scalar image type suitable for filling in
+
+    <b>\#include</b> \<vigra/gaborfilter.hxx\><br/>
+    Namespace: vigra
+*/
+template <class ImageType, 
+          class Alloc = typename ImageType::allocator_type::template rebind<ImageType>::other >
+class GaborFilterFamily 
+: public ImageArray<ImageType, Alloc>
+{
+    typedef ImageArray<ImageType, Alloc> ParentClass;
+    int scaleCount_, directionCount_;
+    double maxCenterFrequency_;
+
+protected:
+    void initFilters()
+    {
+        for(int direction= 0; direction<directionCount_; direction++)
+            for(int scale= 0; scale<scaleCount_; scale++)
+            {
+                double angle = direction * M_PI / directionCount();
+                double centerFrequency =
+                    maxCenterFrequency_ / VIGRA_CSTD::pow(2.0, (double)scale);
+                createGaborFilter(destImageRange(this->images_[filterIndex(direction, scale)]),
+                                  angle, centerFrequency,
+                                  angularGaborSigma(directionCount(), centerFrequency),
+                                  radialGaborSigma(centerFrequency));
+            }
+    }
+
+public:
+    enum { stdFilterSize= 128, stdDirectionCount= 6, stdScaleCount= 4 };
+
+        /** Constructs a family of gabor filters in frequency
+            space. The filters will be calculated on construction, so
+            it makes sense to provide good parameters right now
+            although they can be changed later, too. If you leave them
+            out, the defaults are a \ref directionCount of 6, a \ref
+            scaleCount of 4 and a \ref maxCenterFrequency of
+            3/8(=0.375).
+        */
+    GaborFilterFamily(const Diff2D & size,
+                      int directionCount = stdDirectionCount, int scaleCount = stdScaleCount,
+                      double maxCenterFrequency = 3.0/8.0,
+                      Alloc const & alloc = Alloc())
+        : ParentClass(directionCount*scaleCount, size, alloc),
+          scaleCount_(scaleCount),
+          directionCount_(directionCount),
+          maxCenterFrequency_(maxCenterFrequency)
+    {
+        initFilters();
+    }
+
+        /** Convenience variant of the above constructor taking width
+            and height separately. Also, this one serves as default
+            constructor constructing 128x128 pixel filters.
+         */
+    GaborFilterFamily(int width= stdFilterSize, int height= -1,
+                      int directionCount = stdDirectionCount, int scaleCount = stdScaleCount,
+                      double maxCenterFrequency = 3.0/8.0,
+                      Alloc const & alloc = Alloc())
+        : ParentClass(directionCount*scaleCount, 
+                      Size2D(width, height > 0 ? height : width), alloc),
+          scaleCount_(scaleCount),
+          directionCount_(directionCount),
+          maxCenterFrequency_(maxCenterFrequency)
+    {
+        initFilters();
+    }
+
+        /** Return the index of the filter with the given direction and
+            scale in this ImageArray. direction must in the range
+            0..directionCount()-1 and scale in the range
+            0..rangeCount()-1. This is useful for example if you used
+            \ref applyFourierFilterFamily() and got a resulting
+            ImageArray which still has the same order of images, but no
+            \ref getFilter() method anymore.
+         */
+    int filterIndex(int direction, int scale) const
+    {
+        return scale*directionCount()+direction;
+    }
+
+        /** Return the filter with the given direction and
+            scale. direction must in the range 0..directionCount()-1
+            and scale in the range 0..rangeCount()-1.
+            <tt>filters.getFilter(direction, scale)</tt> is the same as
+            <tt>filters[filterIndex(direction, scale)]</tt>.
+         */
+    ImageType const & getFilter(int direction, int scale) const
+    {
+        return this->images_[filterIndex(direction, scale)];
+    }
+
+        /** Resize all filters (causing their recalculation).
+         */
+    virtual void resizeImages(const Diff2D &newSize)
+    {
+        ParentClass::resizeImages(newSize);
+        initFilters();
+    }
+
+        /** Query the number of filter scales available.
+         */
+    int scaleCount() const
+        { return scaleCount_; }
+
+        /** Query the number of filter directions available.
+         */
+    int directionCount() const
+        { return directionCount_; }
+
+        /** Change the number of directions / scales. This causes the
+            recalculation of all filters.
+         */
+    void setDirectionScaleCounts(int directionCount, int scaleCount)
+    {
+        this->resize(directionCount * scaleCount);
+        scaleCount_ = scaleCount;
+        directionCount_ = directionCount;
+        initFilters();
+    }
+
+        /** Return the center frequency of the filter(s) with
+            scale==0. Filters with scale>0 will have a center frequency
+            reduced in octaves:
+            <tt>centerFrequency= maxCenterFrequency / 2.0^scale</tt>
+        */
+    double maxCenterFrequency()
+        { return maxCenterFrequency_; }
+
+        /** Change the center frequency of the filter(s) with
+            scale==0. See \ref maxCenterFrequency().
+         */
+    void setMaxCenterFrequency(double maxCenterFrequency)
+    {
+        maxCenterFrequency_ = maxCenterFrequency;
+        initFilters();
+    }
+};
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_GABORFILTER_HXX
diff --git a/include/vigra/gaussians.hxx b/include/vigra/gaussians.hxx
new file mode 100644
index 0000000..27d5361
--- /dev/null
+++ b/include/vigra/gaussians.hxx
@@ -0,0 +1,234 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_GAUSSIANS_HXX
+#define VIGRA_GAUSSIANS_HXX
+
+#include <cmath>
+#include "config.hxx"
+#include "mathutil.hxx"
+#include "array_vector.hxx"
+#include "error.hxx"
+
+namespace vigra {
+
+#if 0
+/** \addtogroup MathFunctions Mathematical Functions
+*/
+//@{
+#endif
+/** The Gaussian function and its derivatives.
+
+    Implemented as a unary functor. Since it supports the <tt>radius()</tt> function
+    it can also be used as a kernel in \ref resamplingConvolveImage().
+
+    <b>\#include</b> \<vigra/gaussians.hxx\><br>
+    Namespace: vigra
+
+    \ingroup MathFunctions
+*/
+template <class T = double>
+class Gaussian
+{
+  public:
+
+        /** the value type if used as a kernel in \ref resamplingConvolveImage().
+        */
+    typedef T            value_type;
+        /** the functor's argument type
+        */
+    typedef T            argument_type;
+        /** the functor's result type
+        */
+    typedef T            result_type;
+
+        /** Create functor for the given standard deviation <tt>sigma</tt> and
+            derivative order <i>n</i>. The functor then realizes the function
+
+            \f[ f_{\sigma,n}(x)=\frac{\partial^n}{\partial x^n}
+                 \frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{x^2}{2\sigma^2}}
+            \f]
+
+            Precondition:
+            \code
+            sigma > 0.0
+            \endcode
+        */
+    explicit Gaussian(T sigma = 1.0, unsigned int derivativeOrder = 0)
+    : sigma_(sigma),
+      sigma2_(T(-0.5 / sigma / sigma)),
+      norm_(0.0),
+      order_(derivativeOrder),
+      hermitePolynomial_(derivativeOrder / 2 + 1)
+    {
+        vigra_precondition(sigma_ > 0.0,
+            "Gaussian::Gaussian(): sigma > 0 required.");
+        switch(order_)
+        {
+            case 1:
+            case 2:
+                norm_ = T(-1.0 / (VIGRA_CSTD::sqrt(2.0 * M_PI) * sq(sigma) * sigma));
+                break;
+            case 3:
+                norm_ = T(1.0 / (VIGRA_CSTD::sqrt(2.0 * M_PI) * sq(sigma) * sq(sigma) * sigma));
+                break;
+            default:
+                norm_ = T(1.0 / VIGRA_CSTD::sqrt(2.0 * M_PI) / sigma);
+        }
+        calculateHermitePolynomial();
+    }
+
+        /** Function (functor) call.
+        */
+    result_type operator()(argument_type x) const;
+
+        /** Get the standard deviation of the Gaussian.
+        */
+    value_type sigma() const
+        { return sigma_; }
+
+        /** Get the derivative order of the Gaussian.
+        */
+    unsigned int derivativeOrder() const
+        { return order_; }
+
+        /** Get the required filter radius for a discrete approximation of the Gaussian.
+            The radius is given as a multiple of the Gaussian's standard deviation
+            (default: <tt>sigma * (3 + 1/2 * derivativeOrder()</tt> -- the second term
+            accounts for the fact that the derivatives of the Gaussian become wider
+            with increasing order). The result is rounded to the next higher integer.
+        */
+    double radius(double sigmaMultiple = 3.0) const
+        { return VIGRA_CSTD::ceil(sigma_ * (sigmaMultiple + 0.5 * derivativeOrder())); }
+
+  private:
+    void calculateHermitePolynomial();
+    T horner(T x) const;
+
+    T sigma_, sigma2_, norm_;
+    unsigned int order_;
+    ArrayVector<T> hermitePolynomial_;
+};
+
+template <class T>
+typename Gaussian<T>::result_type
+Gaussian<T>::operator()(argument_type x) const
+{
+    T x2 = x * x;
+    T g  = norm_ * VIGRA_CSTD::exp(x2 * sigma2_);
+    switch(order_)
+    {
+        case 0:
+            return detail::RequiresExplicitCast<result_type>::cast(g);
+        case 1:
+            return detail::RequiresExplicitCast<result_type>::cast(x * g);
+        case 2:
+            return detail::RequiresExplicitCast<result_type>::cast((1.0 - sq(x / sigma_)) * g);
+        case 3:
+            return detail::RequiresExplicitCast<result_type>::cast((3.0 - sq(x / sigma_)) * x * g);
+        default:
+            return order_ % 2 == 0 ?
+                       detail::RequiresExplicitCast<result_type>::cast(g * horner(x2))
+                     : detail::RequiresExplicitCast<result_type>::cast(x * g * horner(x2));
+    }
+}
+
+template <class T>
+T Gaussian<T>::horner(T x) const
+{
+    int i = order_ / 2;
+    T res = hermitePolynomial_[i];
+    for(--i; i >= 0; --i)
+        res = x * res + hermitePolynomial_[i];
+    return res;
+}
+
+template <class T>
+void Gaussian<T>::calculateHermitePolynomial()
+{
+    if(order_ == 0)
+    {
+        hermitePolynomial_[0] = 1.0;
+    }
+    else if(order_ == 1)
+    {
+        hermitePolynomial_[0] = T(-1.0 / sigma_ / sigma_);
+    }
+    else
+    {
+        // calculate Hermite polynomial for requested derivative
+        // recursively according to
+        //     (0)
+        //    h   (x) = 1
+        //
+        //     (1)
+        //    h   (x) = -x / s^2
+        //
+        //     (n+1)                        (n)           (n-1)
+        //    h     (x) = -1 / s^2 * [ x * h   (x) + n * h     (x) ]
+        //
+        T s2 = T(-1.0 / sigma_ / sigma_);
+        ArrayVector<T> hn(3*order_+3, 0.0);
+        typename ArrayVector<T>::iterator hn0 = hn.begin(),
+                                          hn1 = hn0 + order_+1,
+                                          hn2 = hn1 + order_+1,
+                                          ht;
+        hn2[0] = 1.0;
+        hn1[1] = s2;
+        for(unsigned int i = 2; i <= order_; ++i)
+        {
+            hn0[0] = s2 * (i-1) * hn2[0];
+            for(unsigned int j = 1; j <= i; ++j)
+                hn0[j] = s2 * (hn1[j-1] + (i-1) * hn2[j]);
+            ht = hn2;
+            hn2 = hn1;
+            hn1 = hn0;
+            hn0 = ht;
+        }
+        // keep only non-zero coefficients of the polynomial
+        for(unsigned int i = 0; i < hermitePolynomial_.size(); ++i)
+            hermitePolynomial_[i] = order_ % 2 == 0 ?
+                                         hn1[2*i]
+                                       : hn1[2*i+1];
+    }
+}
+
+
+////@}
+
+} // namespace vigra
+
+
+#endif /* VIGRA_GAUSSIANS_HXX */
diff --git a/include/vigra/gradient_energy_tensor.hxx b/include/vigra/gradient_energy_tensor.hxx
new file mode 100644
index 0000000..eef6a15
--- /dev/null
+++ b/include/vigra/gradient_energy_tensor.hxx
@@ -0,0 +1,231 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2004-2005 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_GRADIENT_ENERGY_TENSOR_HXX
+#define VIGRA_GRADIENT_ENERGY_TENSOR_HXX
+
+#include <cmath>
+#include <functional>
+#include "utilities.hxx"
+#include "array_vector.hxx"
+#include "basicimage.hxx"
+#include "combineimages.hxx"
+#include "numerictraits.hxx"
+#include "convolution.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup TensorImaging Tensor Image Processing
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                 gradientEnergyTensor                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the gradient energy tensor for a scalar valued image.
+
+    These function calculates the gradient energy tensor (GET operator) as described in
+    
+    M. Felsberg, U. Köthe: 
+    <i>"GET: The Connection Between Monogenic Scale-Space and Gaussian Derivatives"</i>, 
+    in: R. Kimmel, N. Sochen, J. Weickert (Eds.): Scale Space and PDE Methods in Computer Vision, 
+    Proc. of Scale-Space 2005, Lecture Notes in Computer Science 3459, pp. 192-203, Heidelberg: Springer, 2005.
+    
+    U. Köthe, M. Felsberg: 
+    <i>"Riesz-Transforms Versus Derivatives: On the Relationship Between the Boundary Tensor and the Energy Tensor"</i>, 
+    in: ditto, pp. 179-191.
+
+    with the given filters: The derivative filter \a derivKernel is applied to the appropriate image dimensions 
+    in turn (see the papers above for details), and the other dimension is smoothed with \a smoothKernel. 
+    The kernels can be as small as 3x1, e.g. [0.5, 0, -0.5] and [3.0/16.0, 10.0/16.0, 3.0/16.0] respectively.  
+    The output image must have 3 bands which will hold the
+    tensor components in the order t11, t12 (== t21), t22. The signs of the output are adjusted for a right-handed
+    coordinate system. Thus, orientations derived from the tensor will be in counter-clockwise (mathematically positive)
+    order, with the x-axis at zero degrees (this is the standard in all VIGRA functions that deal with orientation).
+    
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        gradientEnergyTensor(MultiArrayView<2, T1, S1> const & src,
+                             MultiArrayView<2, T2, S2> dest,
+                             Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel);
+    }
+    \endcode
+
+    \deprecatedAPI{gradientEnergyTensor}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void gradientEnergyTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
+                                  DestIterator dupperleft, DestAccessor dest,
+                                  Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void gradientEnergyTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                  pair<DestIterator, DestAccessor> dest,
+                                  Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/gradient_energy_tensor.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> img(w,h);
+    MultiArray<2, TinyVector<float, 3> > get(w,h);
+    Kernel1D<double> grad, smooth;
+    grad.initGaussianDerivative(0.7, 1);
+    smooth.initGaussian(0.7);
+    ...
+    gradientEnergyTensor(img, get, grad, smooth);
+    \endcode
+
+    \deprecatedUsage{gradientEnergyTensor}
+    \code
+    FImage img(w,h);
+    FVector3Image get(w,h);
+    Kernel1D<double> grad, smooth;
+    grad.initGaussianDerivative(0.7, 1);
+    smooth.initGaussian(0.7);
+    ...
+    gradientEnergyTensor(srcImageRange(img), destImage(get), grad, smooth);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void gradientEnergyTensor)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void gradientEnergyTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
+                          DestIterator dupperleft, DestAccessor dest,
+                          Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel)
+{
+    vigra_precondition(dest.size(dupperleft) == 3,
+                       "gradientEnergyTensor(): output image must have 3 bands.");
+
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    typedef typename 
+       NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    typedef BasicImage<TmpType> TmpImage;    
+    TmpImage gx(w, h), gy(w, h), 
+             gxx(w, h), gxy(w, h), gyy(w, h), 
+             laplace(w, h), gx3(w, h), gy3(w, h);
+    
+    convolveImage(srcIterRange(supperleft, slowerright, src), destImage(gx), 
+                  derivKernel, smoothKernel);
+    convolveImage(srcIterRange(supperleft, slowerright, src), destImage(gy), 
+                  smoothKernel, derivKernel);
+    convolveImage(srcImageRange(gx), destImage(gxx), 
+                  derivKernel, smoothKernel);
+    convolveImage(srcImageRange(gx), destImage(gxy), 
+                  smoothKernel, derivKernel);
+    convolveImage(srcImageRange(gy), destImage(gyy), 
+                  smoothKernel, derivKernel);
+    combineTwoImages(srcImageRange(gxx), srcImage(gyy), destImage(laplace), 
+                     std::plus<TmpType>());
+    convolveImage(srcImageRange(laplace), destImage(gx3), 
+                  derivKernel, smoothKernel);
+    convolveImage(srcImageRange(laplace), destImage(gy3), 
+                  smoothKernel, derivKernel);
+    typename TmpImage::iterator gxi  = gx.begin(),
+                                gyi  = gy.begin(),
+                                gxxi = gxx.begin(),
+                                gxyi = gxy.begin(),
+                                gyyi = gyy.begin(),
+                                gx3i = gx3.begin(),
+                                gy3i = gy3.begin();
+    for(int y = 0; y < h; ++y, ++dupperleft.y)
+    {
+        typename DestIterator::row_iterator d = dupperleft.rowIterator(); 
+        for(int x = 0; x < w; ++x, ++d, ++gxi, ++gyi, ++gxxi, ++gxyi, ++gyyi, ++gx3i, ++gy3i)
+        {
+            dest.setComponent(sq(*gxxi) + sq(*gxyi) - *gxi * *gx3i, d, 0);
+            dest.setComponent(- *gxyi * (*gxxi + *gyyi) + 0.5 * (*gxi * *gy3i + *gyi * *gx3i), d, 1);
+            dest.setComponent(sq(*gxyi) + sq(*gyyi) - *gyi * *gy3i, d, 2);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+gradientEnergyTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                     pair<DestIterator, DestAccessor> dest,
+                     Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel)
+{
+    gradientEnergyTensor(src.first, src.second, src.third,
+                         dest.first, dest.second, derivKernel, smoothKernel);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+gradientEnergyTensor(MultiArrayView<2, T1, S1> const & src,
+                     MultiArrayView<2, T2, S2> dest,
+                     Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "gradientEnergyTensor(): shape mismatch between input and output.");
+    gradientEnergyTensor(srcImageRange(src),
+                         destImage(dest), derivKernel, smoothKernel);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_GRADIENT_ENERGY_TENSOR_HXX
diff --git a/include/vigra/graphs.hxx b/include/vigra/graphs.hxx
new file mode 100644
index 0000000..348bca5
--- /dev/null
+++ b/include/vigra/graphs.hxx
@@ -0,0 +1,286 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2011-2012 Stefan Schmidt and Ullrich Koethe            */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/**
+ * This header provides definitions of graph-related types
+ * and optionally provides a gateway to popular graph libraries
+ * (for now, BGL is supported).
+ */
+
+#ifndef VIGRA_GRAPH_HXX
+#define VIGRA_GRAPH_HXX
+
+#include "metaprogramming.hxx"
+#include "tinyvector.hxx"
+
+#ifdef WITH_BOOST_GRAPH
+
+#  include <boost/tuple/tuple.hpp>
+#  include <boost/graph/graph_traits.hpp>
+#  include <boost/graph/properties.hpp>
+
+#else // not WITH_BOOST_GRAPH
+
+// emulate the BGL-style interface
+namespace boost {
+
+struct no_property {};
+
+// tag classes were copied from boost:
+// directed_category tags
+struct directed_tag { };
+struct undirected_tag { };
+struct bidirectional_tag : public directed_tag { };
+
+// traversal_category tags
+struct incidence_graph_tag { };
+struct adjacency_graph_tag { };
+struct bidirectional_graph_tag : public incidence_graph_tag { };
+struct vertex_list_graph_tag { };
+struct edge_list_graph_tag { };
+struct adjacency_matrix_tag { };
+
+// edge_parallel_category tags
+struct allow_parallel_edge_tag { };
+struct disallow_parallel_edge_tag { };
+
+// property maps:
+struct readable_property_map_tag { };
+struct writable_property_map_tag { };
+struct read_write_property_map_tag
+    : public readable_property_map_tag, 
+      public writable_property_map_tag {};
+struct lvalue_property_map_tag
+    : public read_write_property_map_tag {};
+
+struct vertex_index_t {}; 
+
+struct edge_property_tag {};
+
+#ifndef BOOST_TUPLE_HPP
+
+// tie() support for std::pair, similar to Boost's one:
+// (necessary because std::pair doesn't define a suitable assignment operator)
+template<class T1, class T2>
+class tie_adapter 
+{
+  public:
+    tie_adapter(T1 &x, T2 &y) 
+        : x_(x), y_(y)
+    {}
+
+    template<class X, class Y>
+    tie_adapter & operator=(const std::pair<X, Y> &pair)
+    {
+        x_ = pair.first;
+        y_ = pair.second;
+        return *this;
+    }
+    
+  protected:
+    T1 &x_;
+    T2 &y_;
+};
+
+template<class T1, class T2>
+inline
+tie_adapter<T1, T2>
+tie(T1& t1, T2& t2) 
+{
+    return tie_adapter<T1, T2>(t1, t2);
+}
+#endif
+
+// graph_traits class template
+template <typename G>
+struct graph_traits {
+    typedef typename G::vertex_descriptor      vertex_descriptor;
+    typedef typename G::edge_descriptor        edge_descriptor;
+    typedef typename G::adjacency_iterator     adjacency_iterator;
+    typedef typename G::out_edge_iterator      out_edge_iterator;
+    typedef typename G::in_edge_iterator       in_edge_iterator;
+    typedef typename G::vertex_iterator        vertex_iterator;
+    typedef typename G::edge_iterator          edge_iterator;
+
+    typedef typename G::directed_category      directed_category;
+    typedef typename G::edge_parallel_category edge_parallel_category;
+    typedef typename G::traversal_category     traversal_category;
+
+    typedef typename G::vertices_size_type     vertices_size_type;
+    typedef typename G::edges_size_type        edges_size_type;
+    typedef typename G::degree_size_type       degree_size_type;
+
+    static inline vertex_descriptor null_vertex()
+    {
+        return vertex_descriptor(-1);
+    }
+};
+
+// property_traits class template
+template <typename PropMap>
+struct property_traits 
+{
+    typedef typename PropMap::key_type    key_type;
+    typedef typename PropMap::value_type  value_type; 
+    typedef typename PropMap::reference   reference;
+    typedef typename PropMap::category    category;
+};
+
+namespace {
+
+vertex_index_t vertex_index;
+
+} // anonymous namespace
+
+} // namespace boost
+
+#endif // WITH_BOOST_GRAPH
+
+namespace vigra {
+namespace boost_graph { 
+
+// vigra::boost_graph contains algorithms that are compatible to the Boost Graph Library
+using namespace boost;
+
+}} // namespace vigra::boost_graph
+
+
+
+
+#if 0
+namespace vigragraph {
+
+// custom get_helper for read-only property maps (by-value)
+
+template <class ValueType, class ReadablePropertyMap>
+struct get_helper { };
+
+template <class PropertyMap, class ValueType, class K>
+inline ValueType
+get(const get_helper<ValueType, PropertyMap>& pa, const K& k)
+{
+    const ValueType v = static_cast<const PropertyMap&>(pa)[k];
+    return v;
+}
+
+
+// ! A fallback template for adjacent_vertices() called with
+// a vertex_iterator 
+// (which may be specialized to be implemented more efficiently;
+//  the reason is that the iterator may have more information than
+//  the plain vertex_descriptor, e.g. it knows the neighborhood
+//  already which otherwise needs to be reconstructed.)
+template<class GRAPH>
+inline
+std::pair<typename graph_traits<GRAPH>::adjacency_iterator, 
+          typename graph_traits<GRAPH>::adjacency_iterator >
+adjacent_vertices_at_iterator(typename graph_traits<GRAPH>::vertex_iterator const &v,
+                              GRAPH const &g) 
+{    
+    // the default implementation just derefences the iterator
+    // to yield a vertex_descriptor and forwards the call
+    std::cout << "FB" << std::endl;
+    return adjacent_vertices(*v, g);
+}
+
+} // namespace vigragraph
+#endif
+
+#ifdef WITH_LEMON
+#  include <lemon/core.h>
+#else // not WITH_LEMON
+
+// emulate the lemon interface
+namespace lemon {
+
+struct Invalid {
+  public:
+    bool operator==(Invalid) const { return true;  }
+    bool operator!=(Invalid) const { return false; }
+    bool operator< (Invalid) const { return false; }
+
+    template <class T, int N>
+    operator vigra::TinyVector<T, N>() const
+    {
+       return vigra::TinyVector<T, N>(-1);
+    }
+};
+
+static const Invalid INVALID = Invalid();
+
+typedef vigra::VigraTrueType   True;
+typedef vigra::VigraFalseType  False;
+
+} // namespace lemon
+
+#endif // WITH_LEMON
+
+namespace lemon {
+
+template <class T>
+inline bool operator==(T const & t, Invalid)
+{
+    return t == T(Invalid());
+}
+
+template <class T>
+inline bool operator==(Invalid, T const & t)
+{
+    return t == T(Invalid());
+}
+
+template <class T>
+inline bool operator!=(T const & t, Invalid)
+{
+    return t != T(Invalid());
+}
+
+template <class T>
+inline bool operator!=(Invalid, T const & t)
+{
+    return t != T(Invalid());
+}
+
+} // namespace lemon
+
+namespace vigra {
+namespace lemon_graph { 
+
+// vigra::lemon_graph contains algorithms that are compatible to the LEMON graph library
+using namespace lemon;
+
+}} // namespace vigra::lemon_graph
+
+#endif // VIGRA_GRAPH_HXX
diff --git a/include/vigra/hdf5impex.hxx b/include/vigra/hdf5impex.hxx
new file mode 100644
index 0000000..ea3fd98
--- /dev/null
+++ b/include/vigra/hdf5impex.hxx
@@ -0,0 +1,3109 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2009 by Michael Hanselmann and Ullrich Koethe        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_HDF5IMPEX_HXX
+#define VIGRA_HDF5IMPEX_HXX
+
+#include <string>
+
+#define H5Gcreate_vers 2
+#define H5Gopen_vers 2
+#define H5Dopen_vers 2
+#define H5Dcreate_vers 2
+#define H5Acreate_vers 2
+
+#include <hdf5.h>
+
+#if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
+# ifndef H5Gopen
+#   define H5Gopen(a, b, c) H5Gopen(a, b)
+# endif
+# ifndef H5Gcreate
+#  define H5Gcreate(a, b, c, d, e) H5Gcreate(a, b, 1)
+# endif
+# ifndef H5Dopen
+#  define H5Dopen(a, b, c) H5Dopen(a, b)
+# endif
+# ifndef H5Dcreate
+#  define H5Dcreate(a, b, c, d, e, f, g) H5Dcreate(a, b, c, d, f)
+# endif
+# ifndef H5Acreate
+#  define H5Acreate(a, b, c, d, e, f) H5Acreate(a, b, c, d, e)
+# endif
+# ifndef H5Pset_obj_track_times
+#  define H5Pset_obj_track_times(a, b) do {} while (0)
+# endif
+# include <H5LT.h>
+#else
+# include <hdf5_hl.h>
+#endif
+
+#include "impex.hxx"
+#include "multi_array.hxx"
+#include "multi_iterator_coupled.hxx"
+#include "multi_impex.hxx"
+#include "utilities.hxx"
+#include "error.hxx"
+
+#include <algorithm>
+
+#if defined(_MSC_VER)
+#  include <io.h>
+#else
+#  include <unistd.h>
+#endif
+
+namespace vigra {
+
+/** \addtogroup VigraHDF5Impex Import/Export of Images and Arrays in HDF5 Format
+
+    Supports arrays with arbitrary element types and arbitrary many dimensions.
+    See the <a href="http://www.hdfgroup.org/HDF5/">HDF5 Website</a> for more
+    information on the HDF5 file format.
+*/
+//@{
+
+    /** \brief Check if given filename refers to a HDF5 file.
+    */
+inline bool isHDF5(char const * filename)
+{
+#ifdef _MSC_VER
+    return _access(filename, 0) != -1 && H5Fis_hdf5(filename);
+#else
+    return access(filename, F_OK) == 0 && H5Fis_hdf5(filename);
+#endif
+}
+
+    /** \brief Wrapper for hid_t objects.
+
+    Newly created or opened HDF5 handles are usually stored as objects of type 'hid_t'. When the handle
+    is no longer needed, the appropriate close function must be called. However, if a function is 
+    aborted by an exception, this is difficult to ensure. Class HDF5Handle is a smart pointer that 
+    solves this problem by calling the close function in the destructor (This is analogous to how 
+    VIGRA_UNIQUE_PTR calls 'delete' on the contained pointer). A pointer to the close function must be 
+    passed to the constructor, along with an error message that is raised when creation/opening fails. 
+    
+    Since HDF5Handle objects are convertible to hid_t, they can be used in the code in place 
+    of the latter.
+
+    <b>Usage:</b>
+
+    \code
+    HDF5Handle file_id(H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT), 
+                       &H5Fclose, 
+                       "Error message.");
+                       
+    ... // use file_id in the same way as a plain hid_t object
+    \endcode
+
+    <b>\#include</b> \<vigra/hdf5impex.hxx\><br>
+    Namespace: vigra
+    */
+class HDF5Handle
+{
+public:
+    typedef herr_t (*Destructor)(hid_t);
+    
+private:
+    hid_t handle_;
+    Destructor destructor_;
+    
+public:
+
+        /** \brief Default constructor.
+            Creates a NULL handle.
+        **/
+    HDF5Handle()
+    : handle_( 0 ),
+      destructor_(0)
+    {}
+
+        /** \brief Create a wrapper for a hid_t object.
+
+        The hid_t object \a h is assumed to be the return value of an open or create function.
+        It will be closed with the given close function \a destructor as soon as this 
+        HDF5Handle is destructed, except when \a destructor is a NULL pointer (in which
+        case nothing happens at destruction time). If \a h has a value that indicates
+        failed opening or creation (by HDF5 convention, this means if it is a negative number),
+        an exception is raised by calling <tt>vigra_fail(error_message)</tt>.
+
+        <b>Usage:</b>
+
+        \code
+        HDF5Handle file_id(H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT), 
+                           &H5Fclose, 
+                           "Error message.");
+                           
+        ... // use file_id in the same way
+        \endcode
+        */
+    HDF5Handle(hid_t h, Destructor destructor, const char * error_message)
+    : handle_( h ),
+      destructor_(destructor)
+    {
+        if(handle_ < 0)
+            vigra_fail(error_message);
+    }
+
+        /** \brief Copy constructor.
+            Hands over ownership of the RHS handle (analogous to VIGRA_UNIQUE_PTR).
+        */
+    HDF5Handle(HDF5Handle const & h)
+    : handle_( h.handle_ ),
+      destructor_(h.destructor_)
+    {
+        const_cast<HDF5Handle &>(h).handle_ = 0;
+    }
+    
+        /** \brief Assignment.
+            Calls close() for the LHS handle and hands over ownership of the 
+            RHS handle (analogous to VIGRA_UNIQUE_PTR).
+        */
+    HDF5Handle & operator=(HDF5Handle const & h)
+    {
+        if(h.handle_ != handle_)
+        {
+            close();
+            handle_ = h.handle_;
+            destructor_ = h.destructor_;
+            const_cast<HDF5Handle &>(h).handle_ = 0;
+        }
+        return *this;
+    }
+
+        /** \brief Destructor.
+            Calls close() for the contained handle.
+        */
+    ~HDF5Handle()
+    {
+        close();
+    }
+    
+        /** \brief Explicitly call the stored function (if one has been stored within
+             this object) for the contained handle and set the handle to NULL.
+        */
+    herr_t close()
+    {
+        herr_t res = 1;
+        if(handle_ && destructor_)
+            res = (*destructor_)(handle_);
+        handle_ = 0;
+        return res;
+    }
+
+        /** \brief Get a temporary hid_t object for the contained handle.
+            Do not call a close function on the return value - a crash will be likely
+            otherwise.
+        */
+    hid_t get() const
+    {
+        return handle_;
+    }
+
+        /** \brief Convert to a plain hid_t object.
+
+        This function ensures that hid_t objects can be transparently replaced with 
+        HDF5Handle objects in user code. Do not call a close function on the return 
+        value - a crash will be likely otherwise.
+        */
+    operator hid_t() const
+    {
+        return handle_;
+    }
+
+        /** \brief Equality comparison of the contained handle.
+        */
+    bool operator==(HDF5Handle const & h) const
+    {
+        return handle_ == h.handle_;
+    }
+
+        /** \brief Equality comparison of the contained handle.
+        */
+    bool operator==(hid_t h) const
+    {
+        return handle_ == h;
+    }
+
+        /** \brief Inequality comparison of the contained handle.
+        */
+    bool operator!=(HDF5Handle const & h) const
+    {
+        return handle_ != h.handle_;
+    }
+
+        /** \brief Inequality comparison of the contained handle.
+        */
+    bool operator!=(hid_t h) const
+    {
+        return handle_ != h;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                   HDF5ImportInfo                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Argument object for the function readHDF5().
+
+See \ref readHDF5() for a usage example. This object must be
+used to read an image or array from an HDF5 file 
+and enquire about its properties.
+
+<b>\#include</b> \<vigra/hdf5impex.hxx\><br>
+Namespace: vigra
+*/
+class HDF5ImportInfo
+{
+  public:
+    enum PixelType { UINT8, UINT16, UINT32, UINT64, 
+                     INT8, INT16, INT32, INT64,
+                     FLOAT, DOUBLE };
+
+        /** Construct HDF5ImportInfo object.
+
+            The dataset \a pathInFile in the HDF5 file \a filename is accessed to 
+            read its properties. \a pathInFile may contain '/'-separated group
+            names, but must end with the name of the desired dataset:
+            
+            \code
+            HDF5ImportInfo info(filename, "/group1/group2/my_dataset");
+            \endcode
+         */
+    VIGRA_EXPORT HDF5ImportInfo( const char* filePath, const char* pathInFile );
+
+    VIGRA_EXPORT ~HDF5ImportInfo();
+
+        /** Get the filename of this HDF5 object.
+         */
+    VIGRA_EXPORT const std::string& getFilePath() const;
+
+        /** Get the dataset's full name in the HDF5 file.
+         */
+    VIGRA_EXPORT const std::string& getPathInFile() const;
+
+        /** Get a handle to the file represented by this info object.
+         */
+    VIGRA_EXPORT hid_t getH5FileHandle() const;
+
+        /** Get a handle to the dataset represented by this info object.
+         */
+    VIGRA_EXPORT hid_t getDatasetHandle() const;
+
+        /** Get the number of dimensions of the dataset represented by this info object.
+         */
+    VIGRA_EXPORT MultiArrayIndex numDimensions() const;
+
+        /** Get the shape of the dataset represented by this info object.
+            
+            Note that the memory order between VIGRA and HDF5 files differs: VIGRA uses 
+            Fortran-order, while HDF5 uses C-order. This function therefore reverses the axis
+            order relative to the file contents. That is, when the axes in the file are 
+            ordered as 'z', 'y', 'x', this function will return the shape in the order
+            'x', 'y', 'z'.
+         */
+    VIGRA_EXPORT ArrayVector<hsize_t> const & shape() const
+    {
+        return m_dims;
+    }
+
+        /** Get the shape (length) of the dataset along dimension \a dim.
+            
+            Note that the memory order between VIGRA and HDF5 files differs: VIGRA uses 
+            Fortran-order, while HDF5 uses C-order. This function therefore reverses the axis
+            order relative to the file contents. That is, when the axes in the file are 
+            ordered as 'z', 'y', 'x', this function will return the shape in the order
+            'x', 'y', 'z'.
+         */
+    VIGRA_EXPORT MultiArrayIndex shapeOfDimension(const int dim) const;
+
+        /** Query the pixel type of the dataset.
+
+            Possible values are:
+            <DL>
+            <DT>"INT8"<DD> 8-bit signed integer (unsigned char)
+            <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
+            <DT>"INT16"<DD> 16-bit signed integer (short)
+            <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short)
+            <DT>"INT32"<DD> 32-bit signed integer (long)
+            <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long)
+            <DT>"INT64"<DD> 64-bit signed integer (long long)
+            <DT>"UINT64"<DD> 64-bit unsigned integer (unsigned long long)
+            <DT>"FLOAT"<DD> 32-bit floating point (float)
+            <DT>"DOUBLE"<DD> 64-bit floating point (double)
+            </DL>
+         */
+    VIGRA_EXPORT const char * getPixelType() const;
+
+        /** Query the pixel type of the dataset.
+
+            Same as getPixelType(), but the result is returned as a 
+            ImageImportInfo::PixelType enum. This is useful to implement
+            a switch() on the pixel type.
+
+            Possible values are:
+            <DL>
+            <DT>UINT8<DD> 8-bit unsigned integer (unsigned char)
+            <DT>INT16<DD> 16-bit signed integer (short)
+            <DT>UINT16<DD> 16-bit unsigned integer (unsigned short)
+            <DT>INT32<DD> 32-bit signed integer (long)
+            <DT>UINT32<DD> 32-bit unsigned integer (unsigned long)
+            <DT>FLOAT<DD> 32-bit floating point (float)
+            <DT>DOUBLE<DD> 64-bit floating point (double)
+            </DL>
+         */
+    VIGRA_EXPORT PixelType pixelType() const;
+
+  private:
+    HDF5Handle m_file_handle, m_dataset_handle;
+    std::string m_filename, m_path, m_pixeltype;
+    hssize_t m_dimensions;
+    ArrayVector<hsize_t> m_dims;
+};
+
+
+namespace detail {
+
+template<class type>
+inline hid_t getH5DataType()
+{
+    std::runtime_error("getH5DataType(): invalid type");
+    return 0;
+}
+
+#define VIGRA_H5_DATATYPE(type, h5type) \
+template<> \
+inline hid_t getH5DataType<type>() \
+{ return h5type;}
+
+VIGRA_H5_DATATYPE(char, H5T_NATIVE_CHAR)
+VIGRA_H5_DATATYPE(float, H5T_NATIVE_FLOAT)
+VIGRA_H5_DATATYPE(double, H5T_NATIVE_DOUBLE)
+VIGRA_H5_DATATYPE(long double, H5T_NATIVE_LDOUBLE)
+
+// char arrays with flexible length require 'handcrafted' H5 datatype
+template<>
+inline hid_t getH5DataType<char*>()
+{
+    hid_t stringtype = H5Tcopy (H5T_C_S1);
+    H5Tset_size(stringtype, H5T_VARIABLE);
+    return stringtype;
+}
+template<>
+inline hid_t getH5DataType<const char*>()
+{
+    hid_t stringtype = H5Tcopy (H5T_C_S1);
+    H5Tset_size(stringtype, H5T_VARIABLE);
+    return stringtype;
+}
+#undef VIGRA_H5_DATATYPE
+
+template <unsigned int SIZE>
+struct HDF5TypeBySize;
+
+template <>
+struct HDF5TypeBySize<1>
+{
+    static hid_t signed_type() { return H5T_NATIVE_INT8; }
+    static hid_t unsigned_type() { return H5T_NATIVE_UINT8; }
+};
+
+template <>
+struct HDF5TypeBySize<2>
+{
+    static hid_t signed_type() { return H5T_NATIVE_INT16; }
+    static hid_t unsigned_type() { return H5T_NATIVE_UINT16; }
+};
+
+template <>
+struct HDF5TypeBySize<4>
+{
+    static hid_t signed_type() { return H5T_NATIVE_INT32; }
+    static hid_t unsigned_type() { return H5T_NATIVE_UINT32; }
+};
+
+template <>
+struct HDF5TypeBySize<8>
+{
+    static hid_t signed_type() { return H5T_NATIVE_INT64; }
+    static hid_t unsigned_type() { return H5T_NATIVE_UINT64; }
+};
+
+#define VIGRA_H5_SIGNED_DATATYPE(type) \
+template<> \
+inline hid_t getH5DataType<type>() \
+{ return HDF5TypeBySize<sizeof(type)>::signed_type(); }
+
+VIGRA_H5_SIGNED_DATATYPE(signed char)
+VIGRA_H5_SIGNED_DATATYPE(signed short)
+VIGRA_H5_SIGNED_DATATYPE(signed int)
+VIGRA_H5_SIGNED_DATATYPE(signed long)
+VIGRA_H5_SIGNED_DATATYPE(signed long long)
+
+#undef VIGRA_H5_SIGNED_DATATYPE
+
+#define VIGRA_H5_UNSIGNED_DATATYPE(type) \
+template<> \
+inline hid_t getH5DataType<type>() \
+{ return HDF5TypeBySize<sizeof(type)>::unsigned_type(); }
+
+VIGRA_H5_UNSIGNED_DATATYPE(unsigned char)
+VIGRA_H5_UNSIGNED_DATATYPE(unsigned short)
+VIGRA_H5_UNSIGNED_DATATYPE(unsigned int)
+VIGRA_H5_UNSIGNED_DATATYPE(unsigned long)
+VIGRA_H5_UNSIGNED_DATATYPE(unsigned long long)
+
+#undef VIGRA_H5_UNSIGNED_DATATYPE
+
+#if 0
+template<>
+inline hid_t getH5DataType<FFTWComplex<float> >()
+{
+    hid_t complex_id = H5Tcreate (H5T_COMPOUND, sizeof (FFTWComplex<float>));
+    H5Tinsert (complex_id, "real", 0, H5T_NATIVE_FLOAT);
+    H5Tinsert (complex_id, "imaginary", sizeof(float), H5T_NATIVE_FLOAT);
+    return complex_id;
+}
+
+template<>
+inline hid_t getH5DataType<FFTWComplex<double> >()
+{
+    hid_t complex_id = H5Tcreate (H5T_COMPOUND, sizeof (FFTWComplex<double>));
+    H5Tinsert (complex_id, "real", 0, H5T_NATIVE_DOUBLE);
+    H5Tinsert (complex_id, "imaginary", sizeof(double), H5T_NATIVE_DOUBLE);
+    return complex_id;
+}
+#endif
+
+
+} // namespace detail
+
+// helper friend function for callback HDF5_ls_inserter_callback()
+void HDF5_ls_insert(void*, const std::string &);
+// callback function for ls(), called via HDF5File::H5Literate()
+// see http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2
+// for as to why.
+
+VIGRA_EXPORT H5O_type_t HDF5_get_type(hid_t, const char*);
+extern "C" VIGRA_EXPORT herr_t HDF5_ls_inserter_callback(hid_t, const char*, const H5L_info_t*, void*);
+
+/********************************************************/
+/*                                                      */
+/*                     HDF5File                         */
+/*                                                      */
+/********************************************************/
+
+
+/** \brief Access to HDF5 files
+
+HDF5File provides a convenient way of accessing data in HDF5 files. vigra::MultiArray
+structures of any dimension can be stored to / loaded from HDF5 files. Typical
+HDF5 features like subvolume access, chunks and data compression are available,
+string attributes can be attached to any dataset or group. Group- or dataset-handles
+are encapsulated in the class and managed automatically. The internal file-system like
+structure can be accessed by functions like "cd()" or "mkdir()".
+
+Note that the memory order between VIGRA and HDF5 files differs: VIGRA uses 
+Fortran-order, while HDF5 uses C-order. This means that a VIGRA MultiArray,
+whose indices represent the 'x'-, 'y'-, and 'z'-axis in that order, is reversed
+upon writing to an HDF5 file, i.e. in the file the axis order is 'z', 'y', 'x'. 
+Likewise, the order is reversed upon reading.
+
+<b>Example:</b>
+Write the MultiArray out_multi_array to file. Change the current directory to
+"/group" and read in the same MultiArray as in_multi_array.
+\code
+HDF5File file("/path/to/file",HDF5File::New);
+file.mkdir("group");
+file.write("/group/dataset", out_multi_array);
+
+file.cd("/group");
+file.read("dataset", in_multi_array);
+
+\endcode
+
+<b>\#include</b> \<vigra/hdf5impex.hxx\><br>
+Namespace: vigra
+*/
+class HDF5File
+{
+  protected:
+    HDF5Handle fileHandle_;
+
+    // current group handle
+    HDF5Handle cGroupHandle_;
+    
+  private:
+    // time tagging of datasets, turned off (= 0) by default.
+    int track_time;
+
+    // helper class for ls()
+    struct ls_closure
+    {
+        virtual void insert(const std::string &) = 0;
+        virtual ~ls_closure() {}
+    };
+    // datastructure to hold a list of dataset and group names
+    struct lsOpData : public ls_closure
+    {
+        std::vector<std::string> & objects;
+        lsOpData(std::vector<std::string> & o) : objects(o) {}
+        void insert(const std::string & x)
+        {
+            objects.push_back(x);
+        }
+    };
+    // (associative-)container closure
+    template<class Container>
+    struct ls_container_data : public ls_closure
+    {
+        Container & objects;
+        ls_container_data(Container & o) : objects(o) {}
+        void insert(const std::string & x)
+        {
+            objects.insert(std::string(x));
+        }
+    };
+
+  public:
+
+        // helper for callback HDF5_ls_inserter_callback(), used by ls()
+    friend void HDF5_ls_insert(void*, const std::string &);
+
+        /** \brief Set how a file is opened.
+
+            OpenMode::New creates a new file. If the file already exists, overwrite it.
+
+            OpenMode::Open opens a file for reading/writing. The file will be created,
+                           if necessary.
+        */
+    enum OpenMode {
+        New,           // Create new empty file (existing file will be deleted).
+        Open,          // Open file. Create if not existing.
+        OpenReadOnly   // Open file in read-only mode.
+    };
+
+        /** \brief Default constructor.
+
+        A file can later be opened via the open() function.
+        
+        If \a track_creation_times is non-zero, time tagging of datasets will be enabled (it is disabled
+        by default).
+        */
+    HDF5File(int track_creation_times = 0)
+    : track_time(track_creation_times)
+    {}
+
+        /** \brief Open or create an HDF5File object.
+
+        Creates or opens HDF5 file with given filename. 
+        The current group is set to "/".
+        
+        Note that the HDF5File class is not copyable (the copy constructor is 
+        private to enforce this).
+        */
+    HDF5File(std::string filename, OpenMode mode, int track_creation_times = 0)
+        : track_time(track_creation_times)
+    {
+        open(filename, mode);
+    }
+
+        /** \brief The destructor flushes and closes the file.
+         */
+    ~HDF5File()
+    {
+        // The members fileHandle_ and cGroupHandle_ are automatically closed
+        // as they are of type HDF5Handle and are properly initialised.
+        // The closing of fileHandle_ implies flushing the file to
+        // the operating system, see
+        // http://www.hdfgroup.org/HDF5/doc/RM/RM_H5F.html#File-Close .
+    }
+    
+    // copying is not permitted.
+  private:
+    HDF5File(const HDF5File &);
+    void operator=(const HDF5File &);
+
+  public:
+  
+        /** \brief Open or create the given file in the given mode and set the group to "/".
+            If another file is currently open, it is first closed.
+         */
+    void open(std::string filename, OpenMode mode)
+    {
+        close();
+        
+        std::string errorMessage = "HDF5File.open(): Could not open or create file '" + filename + "'.";
+        fileHandle_ = HDF5Handle(createFile_(filename, mode), &H5Fclose, errorMessage.c_str());
+        cGroupHandle_ = HDF5Handle(openCreateGroup_("/"), &H5Gclose, "HDF5File.open(): Failed to open root group.");
+    }
+
+        /** \brief Close the current file.
+         */
+    void close()
+    {
+        bool success = cGroupHandle_.close() >= 0 && fileHandle_.close() >= 0;
+        vigra_postcondition(success, "HDF5File.close() failed.");
+    }
+
+        /** \brief Change current group to "/".
+         */
+    inline void root()
+    {
+        std::string message = "HDF5File::root(): Could not open group '/'.";
+        cGroupHandle_ = HDF5Handle(H5Gopen(fileHandle_, "/", H5P_DEFAULT),&H5Gclose,message.c_str());
+    }
+
+        /** \brief Change the current group.
+            Both absolute and relative group names are allowed.
+         */
+    inline void cd(std::string groupName)
+    {
+        cGroupHandle_ = getGroupHandle(groupName, "HDF5File::cd()");
+    }
+
+        /** \brief Change the current group to its parent group.
+            Returns true if successful, false otherwise. If unsuccessful,
+            the group will not change.
+         */
+    inline bool cd_up()
+    {
+        std::string groupName = currentGroupName_();
+
+        //do not try to move up if we already in "/"
+        if(groupName == "/"){
+            return false;
+        }
+
+        size_t lastSlash = groupName.find_last_of('/');
+
+        std::string parentGroup (groupName.begin(), groupName.begin()+lastSlash+1);
+
+        cd(parentGroup);
+
+        return true;
+    }
+    
+        /** \brief Change the current group to its parent group.
+            Returns true if successful, false otherwise. If unsuccessful,
+            the group will not change.
+         */
+    inline bool cd_up(int levels)
+    {
+        std::string groupName = currentGroupName_();
+        
+        for(int i = 0; i<levels; i++)
+        {
+            if(!cd_up())
+            {
+                // restore old group if neccessary
+                if(groupName != currentGroupName_())
+                    cd(groupName);
+                return false;
+            }
+        }
+        return true;
+    }
+
+        /** \brief Create a new group.
+             If the first character is a "/", the path will be interpreted as absolute path,
+             otherwise it will be interpreted as path relative to the current group.
+        */
+    inline void mkdir(std::string groupName)
+    {
+        std::string message = "HDF5File::mkdir(): Could not create group '" + groupName + "'.\n";
+
+        // make groupName clean
+        groupName = get_absolute_path(groupName);
+        
+        HDF5Handle(openCreateGroup_(groupName.c_str()),&H5Gclose,message.c_str());
+    }
+
+        /** \brief Change the current group; create it if necessary.
+             If the first character is a "/", the path will be interpreted as absolute path,
+             otherwise it will be interpreted as path relative to the current group.
+        */
+    inline void cd_mk(std::string groupName)
+    {
+        std::string  message = "HDF5File::cd_mk(): Could not create group '" + groupName + "'.";
+
+        // make groupName clean
+        groupName = get_absolute_path(groupName);
+
+        cGroupHandle_ = HDF5Handle(openCreateGroup_(groupName.c_str()),&H5Gclose,message.c_str());
+    }
+
+        // helper function for the various ls() variants.
+    void ls_H5Literate(ls_closure & data) const
+    {
+        H5Literate(cGroupHandle_, H5_INDEX_NAME, H5_ITER_NATIVE, NULL,
+                   HDF5_ls_inserter_callback, static_cast<void*>(&data));
+    }
+
+        /** \brief List the contents of the current group.
+            The function returns a vector of strings holding the entries of the
+            current group. Only datasets and groups are listed, other objects
+            (e.g. datatypes) are ignored. Group names always have a trailing "/".
+        */
+    inline std::vector<std::string> ls() const
+    {
+        std::vector<std::string> list;
+        lsOpData data(list);
+        ls_H5Literate(data);
+        return list;
+    }
+
+        /** \brief List the contents of the current group into a container-like
+                   object via insert(). 
+                   
+            Only datasets and groups are inserted, other objects (e.g., datatypes) are ignored. 
+            Group names always have a trailing "/".
+
+            The argument cont is presumably an associative container, however,
+            only its member function <tt>cont.insert(std::string)</tt> will be
+            called.
+            \param cont      reference to a container supplying a member function
+                             <tt>insert(const i_type &)</tt>, where <tt>i_type</tt>
+                             is convertible to <tt>std::string</tt>.
+        */
+    template<class Container>
+    void ls(Container & cont) const
+    {
+        ls_container_data<Container> data(cont);
+        ls_H5Literate(data);
+    }
+
+        /** \brief Get the path of the current group.
+        */
+    inline std::string pwd() const
+    {
+        return currentGroupName_();
+    }
+
+        /** \brief Get the name of the associated file.
+        */
+    inline std::string filename() const
+    {
+        return fileName_();
+    }
+
+        /** \brief Check if given datasetName exists.
+        */
+    inline bool existsDataset(std::string datasetName)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+        return (H5Lexists(fileHandle_, datasetName.c_str(), H5P_DEFAULT) > 0);
+    }
+
+        /** \brief Get the number of dimensions of a certain dataset
+             If the first character is a "/", the path will be interpreted as absolute path,
+             otherwise it will be interpreted as path relative to the current group.
+        */
+    hssize_t getDatasetDimensions(std::string datasetName)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        //Open dataset and dataspace
+        std::string errorMessage = "HDF5File::getDatasetDimensions(): Unable to open dataset '" + datasetName + "'.";
+        HDF5Handle datasetHandle = HDF5Handle(getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
+
+        errorMessage = "HDF5File::getDatasetDimensions(): Unable to access dataspace.";
+        HDF5Handle dataspaceHandle(H5Dget_space(datasetHandle), &H5Sclose, errorMessage.c_str());
+
+        //return dimension information
+        return H5Sget_simple_extent_ndims(dataspaceHandle);
+    }
+
+        /** \brief Get the shape of each dimension of a certain dataset.
+            
+           Normally, this function is called after determining the dimension of the
+            dataset using \ref getDatasetDimensions().
+            If the first character is a "/", the path will be interpreted as absolute path,
+            otherwise it will be interpreted as path relative to the current group.
+            
+            Note that the memory order between VIGRA and HDF5 files differs: VIGRA uses 
+            Fortran-order, while HDF5 uses C-order. This function therefore reverses the axis
+            order relative to the file contents. That is, when the axes in the file are 
+            ordered as 'z', 'y', 'x', this function will return the shape in the order
+            'x', 'y', 'z'.
+        */
+    ArrayVector<hsize_t> getDatasetShape(std::string datasetName)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        //Open dataset and dataspace
+        std::string errorMessage = "HDF5File::getDatasetShape(): Unable to open dataset '" + datasetName + "'.";
+        HDF5Handle datasetHandle = HDF5Handle(getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
+
+        errorMessage = "HDF5File::getDatasetShape(): Unable to access dataspace.";
+        HDF5Handle dataspaceHandle(H5Dget_space(datasetHandle), &H5Sclose, errorMessage.c_str());
+
+        //get dimension information
+        ArrayVector<hsize_t>::size_type dimensions = H5Sget_simple_extent_ndims(dataspaceHandle);
+
+        ArrayVector<hsize_t> shape(dimensions);
+        ArrayVector<hsize_t> maxdims(dimensions);
+        H5Sget_simple_extent_dims(dataspaceHandle, shape.data(), maxdims.data());
+
+        // invert the dimensions to guarantee VIGRA-compatible order.
+        std::reverse(shape.begin(), shape.end());
+        return shape;
+    }
+
+        /** Query the pixel type of the dataset.
+
+            Possible values are:
+            <DL>
+            <DT>"INT8"<DD> 8-bit signed integer (unsigned char)
+            <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
+            <DT>"INT16"<DD> 16-bit signed integer (short)
+            <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short)
+            <DT>"INT32"<DD> 32-bit signed integer (long)
+            <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long)
+            <DT>"INT64"<DD> 64-bit signed integer (long long)
+            <DT>"UINT64"<DD> 64-bit unsigned integer (unsigned long long)
+            <DT>"FLOAT"<DD> 32-bit floating point (float)
+            <DT>"DOUBLE"<DD> 64-bit floating point (double)
+            <DT>"UNKNOWN"<DD> any other type
+            </DL>
+         */
+    std::string getDatasetType(std::string const & datasetName)
+    {
+        HDF5Handle datasetHandle = getDatasetHandle(datasetName);
+
+        hid_t datatype = H5Dget_type(datasetHandle);
+        H5T_class_t dataclass = H5Tget_class(datatype);
+        size_t datasize  = H5Tget_size(datatype);
+        H5T_sign_t datasign  = H5Tget_sign(datatype);
+
+        if(dataclass == H5T_FLOAT)
+        {
+            if(datasize == 4)
+                return "FLOAT";
+            else if(datasize == 8)
+                return "DOUBLE";
+        }
+        else if(dataclass == H5T_INTEGER)   
+        {
+            if(datasign == H5T_SGN_NONE)
+            {
+                if(datasize ==  1)
+                    return "UINT8";
+                else if(datasize == 2)
+                    return "UINT16";
+                else if(datasize == 4)
+                    return "UINT32";
+                else if(datasize == 8)
+                    return "UINT64";
+            }
+            else
+            {
+                if(datasize ==  1)
+                    return "INT8";
+                else if(datasize == 2)
+                    return "INT16";
+                else if(datasize == 4)
+                    return "INT32";
+                else if(datasize == 8)
+                    return "INT64";
+            }
+        }
+        return "UNKNOWN";
+    }
+        
+        /** \brief Obtain the HDF5 handle of a dataset.
+        */
+    inline HDF5Handle getDatasetHandle(std::string const & datasetName)
+    {
+        std::string errorMessage = "HDF5File::getDatasetHandle(): Unable to open dataset '" + datasetName + "'.";
+        return HDF5Handle(getDatasetHandle_(get_absolute_path(datasetName)), &H5Dclose, errorMessage.c_str());
+    }
+
+        /** \brief Obtain the HDF5 handle of a group.
+         */
+    inline HDF5Handle getGroupHandle(std::string group_name, std::string function_name = "HDF5File::getGroupHandle()")
+    {
+        std::string errorMessage = function_name + ": Group '" + group_name + "' not found.";
+
+        // make group_name clean
+        group_name = get_absolute_path(group_name);
+
+        // group must exist
+        vigra_precondition(group_name == "/" || H5Lexists(fileHandle_, group_name.c_str(), H5P_DEFAULT) != 0, 
+                           errorMessage.c_str());
+
+        // open group and return group handle
+        return HDF5Handle(openCreateGroup_(group_name), &H5Gclose, "Internal error");
+    }
+
+        /** \brief Obtain the HDF5 handle of a attribute.
+         */
+    inline HDF5Handle getAttributeHandle(std::string dataset_name, std::string attribute_name)
+    {
+        std::string message = "HDF5File::getAttributeHandle(): Attribute '" + attribute_name + "' not found.";
+        return HDF5Handle(H5Aopen(getDatasetHandle(dataset_name), attribute_name.c_str(), H5P_DEFAULT),
+                          &H5Aclose, message.c_str());
+    }
+
+    /* Writing Attributes */
+
+        /** \brief Write MultiArray Attributes.
+          * In contrast to datasets, subarray access, chunks and compression are not available.
+          */
+    template<unsigned int N, class T, class Stride>
+    inline void writeAttribute(std::string object_name, 
+                               std::string attribute_name, 
+                               const MultiArrayView<N, T, Stride> & array)
+    {
+        // make object_name clean
+        object_name = get_absolute_path(object_name);
+
+        write_attribute_(object_name, attribute_name, array, detail::getH5DataType<T>(), 1);
+    }
+
+    template<unsigned int N, class T, int SIZE, class Stride>
+    inline void writeAttribute(std::string datasetName, 
+                               std::string attributeName, 
+                               const MultiArrayView<N, TinyVector<T, SIZE>, Stride> & array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        write_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), SIZE);
+    }
+
+    template<unsigned int N, class T, class Stride>
+    inline void writeAttribute(std::string datasetName, 
+                               std::string attributeName, 
+                               const MultiArrayView<N, RGBValue<T>, Stride> & array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        write_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 3);
+    }
+
+        /** \brief Write a single value.
+          Specialization of the write function for simple datatypes
+         */
+    inline void writeAttribute(std::string object_name, std::string attribute_name, char data) 
+        { writeAtomicAttribute(object_name,attribute_name,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, signed char data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, signed short data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, signed int data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, signed long data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, signed long long data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, unsigned char data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, unsigned short data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, unsigned int data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, unsigned long data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, unsigned long long data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, float data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, double data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, long double data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, const char* data) 
+        { writeAtomicAttribute(datasetName,attributeName,data); }
+    inline void writeAttribute(std::string datasetName, std::string attributeName, std::string const & data) 
+        { writeAtomicAttribute(datasetName,attributeName,data.c_str()); }
+
+        /** \brief Test if attribute exists.
+        */
+    bool existsAttribute(std::string object_name, std::string attribute_name)
+    {
+        std::string obj_path = get_absolute_path(object_name);
+        htri_t exists = H5Aexists_by_name(fileHandle_, obj_path.c_str(),
+                                          attribute_name.c_str(), H5P_DEFAULT);
+        vigra_precondition(exists >= 0, "HDF5File::existsAttribute(): "
+                                        "object '" + object_name + "' "
+                                        "not found.");
+        return exists != 0;
+    }
+
+    // Reading Attributes
+
+        /** \brief Read MultiArray Attributes.
+          * In contrast to datasets, subarray access is not available.
+          */
+    template<unsigned int N, class T, class Stride>
+    inline void readAttribute(std::string object_name, 
+                              std::string attribute_name, 
+                              MultiArrayView<N, T, Stride> array)
+    {
+        // make object_name clean
+        object_name = get_absolute_path(object_name);
+
+        read_attribute_(object_name, attribute_name, array, detail::getH5DataType<T>(), 1);
+    }
+
+    template<unsigned int N, class T, int SIZE, class Stride>
+    inline void readAttribute(std::string datasetName, 
+                              std::string attributeName, 
+                              MultiArrayView<N, TinyVector<T, SIZE>, Stride> array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        read_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), SIZE);
+    }
+
+    template<unsigned int N, class T, class Stride>
+    inline void readAttribute(std::string datasetName, 
+                              std::string attributeName, 
+                              MultiArrayView<N, RGBValue<T>, Stride> array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        read_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 3);
+    }
+
+        /** \brief Read a single value.
+          Specialization of the read function for simple datatypes
+         */
+    inline void readAttribute(std::string object_name, std::string attribute_name, char &data)       
+        { readAtomicAttribute(object_name,attribute_name,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, signed char &data)        
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, signed short &data)       
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, signed int &data)       
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, signed long &data)       
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, signed long long &data)       
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, unsigned char &data)       
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, unsigned short &data)      
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, unsigned int &data)      
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, unsigned long &data)      
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, unsigned long long &data)      
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, float &data)       
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, double &data)      
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, long double &data) 
+        { readAtomicAttribute(datasetName,attributeName,data); }
+    inline void readAttribute(std::string datasetName, std::string attributeName, std::string &data) 
+        { readAtomicAttribute(datasetName,attributeName,data); }
+
+    // Writing data
+
+        /** \brief Write multi arrays.
+          
+            Chunks can be activated by setting 
+            \code iChunkSize = size; //size \> 0 
+            \endcode .
+            The chunks will be hypercubes with edge length size. When <tt>iChunkSize == 0</tt>
+            (default), the behavior depends on the <tt>compression</tt> setting: If no
+            compression is requested, the data is written without chunking. Otherwise,
+            chuning is required, and the chunk size is automatically selected such that
+            each chunk contains about 300k pixels.
+
+            Compression can be activated by setting 
+            \code compression = parameter; // 0 \< parameter \<= 9 
+            \endcode
+            where 0 stands for no compression and 9 for maximum compression.
+
+            If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+            otherwise it will be interpreted as path relative to the current group.
+
+            Note that the memory order between VIGRA and HDF5 files differs: VIGRA uses 
+            Fortran-order, while HDF5 uses C-order. This means that a VIGRA MultiArray,
+            whose indices represent the 'x'-, 'y'-, and 'z'-axis in that order, is reversed
+            upon writing to an HDF5 file, i.e. in the file the axis order is 'z', 'y', 'x'. 
+        */
+    template<unsigned int N, class T, class Stride>
+    inline void write(std::string datasetName, 
+                      const MultiArrayView<N, T, Stride> & array, 
+                      int iChunkSize = 0, int compression = 0)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        typename MultiArrayShape<N>::type chunkSize;
+        for(unsigned int i = 0; i < N; i++){
+            chunkSize[i] = iChunkSize;
+        }
+        write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize, compression);
+    }
+
+        /** \brief Write multi arrays.
+            Chunks can be activated by providing a MultiArrayShape as chunkSize.
+            chunkSize must have equal dimension as array.
+
+            Compression can be activated by setting 
+            \code compression = parameter; // 0 \< parameter \<= 9 
+            \endcode
+            where 0 stands for no compression and 9 for maximum compression.
+
+            If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+            otherwise it will be interpreted as path relative to the current group.
+
+            Note that the memory order between VIGRA and HDF5 files differs: VIGRA uses 
+            Fortran-order, while HDF5 uses C-order. This means that a VIGRA MultiArray,
+            whose indices represent the 'x'-, 'y'-, and 'z'-axis in that order, is reversed
+            upon writing to an HDF5 file, i.e. in the file the axis order is 'z', 'y', 'x'. 
+        */
+    template<unsigned int N, class T, class Stride>
+    inline void write(std::string datasetName, 
+                      const MultiArrayView<N, T, Stride> & array, 
+                      typename MultiArrayShape<N>::type chunkSize, int compression = 0)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize, compression);
+    }
+
+        /** \brief Write a multi array into a larger volume.
+            blockOffset determines the position, where array is written.
+
+            If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+            otherwise it will be interpreted as path relative to the current group.
+
+            Note that the memory order between VIGRA and HDF5 files differs: VIGRA uses 
+            Fortran-order, while HDF5 uses C-order. This means that a VIGRA MultiArray,
+            whose indices represent the 'x'-, 'y'-, and 'z'-axis in that order, is reversed
+            upon writing to an HDF5 file, i.e. in the file the axis order is 'z', 'y', 'x'. 
+        */
+    template<unsigned int N, class T, class Stride>
+    inline void writeBlock(std::string datasetName, 
+                           typename MultiArrayShape<N>::type blockOffset, 
+                           const MultiArrayView<N, T, Stride> & array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        writeBlock_(datasetName, blockOffset, array, detail::getH5DataType<T>(), 1);
+    }
+
+    // non-scalar (TinyVector) and unstrided multi arrays
+    template<unsigned int N, class T, int SIZE, class Stride>
+    inline void write(std::string datasetName, 
+                      const MultiArrayView<N, TinyVector<T, SIZE>, Stride> & array, 
+                      int iChunkSize = 0, int compression = 0)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        typename MultiArrayShape<N>::type chunkSize;
+        for(int i = 0; i < N; i++){
+            chunkSize[i] = iChunkSize;
+        }
+        write_(datasetName, array, detail::getH5DataType<T>(), SIZE, chunkSize, compression);
+    }
+
+    template<unsigned int N, class T, int SIZE, class Stride>
+    inline void write(std::string datasetName, 
+                      const MultiArrayView<N, TinyVector<T, SIZE>, Stride> & array, 
+                      typename MultiArrayShape<N>::type chunkSize, int compression = 0)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        write_(datasetName, array, detail::getH5DataType<T>(), SIZE, chunkSize, compression);
+    }
+
+        /** \brief Write array vectors.
+          
+            Compression can be activated by setting 
+            \code compression = parameter; // 0 \< parameter \<= 9 
+            \endcode
+            where 0 stands for no compression and 9 for maximum compression.
+
+            If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+            otherwise it will be interpreted as path relative to the current group.
+        */
+    template<class T>
+    void write(const std::string & datasetName,
+                      const ArrayVectorView<T> & array,
+                      int compression = 0)
+    {
+        // convert to a (trivial) MultiArrayView and forward.
+        MultiArrayShape<1>::type shape(array.size());
+        const MultiArrayView<1, T> m_array(shape, const_cast<T*>(array.data()));
+        write(datasetName, m_array, compression);
+    }
+
+    template<unsigned int N, class T, int SIZE, class Stride>
+    inline void writeBlock(std::string datasetName, 
+                           typename MultiArrayShape<N>::type blockOffset, 
+                           const MultiArrayView<N, TinyVector<T, SIZE>, Stride> & array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        writeBlock_(datasetName, blockOffset, array, detail::getH5DataType<T>(), SIZE);
+    }
+
+    // non-scalar (RGBValue) and unstrided multi arrays
+    template<unsigned int N, class T, class Stride>
+    inline void write(std::string datasetName, 
+                      const MultiArrayView<N, RGBValue<T>, Stride> & array, 
+                      int iChunkSize = 0, int compression = 0)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        typename MultiArrayShape<N>::type chunkSize;
+        for(int i = 0; i < N; i++){
+            chunkSize[i] = iChunkSize;
+        }
+        write_(datasetName, array, detail::getH5DataType<T>(), 3, chunkSize, compression);
+    }
+
+    template<unsigned int N, class T, class Stride>
+    inline void write(std::string datasetName, 
+                      const MultiArrayView<N, RGBValue<T>, Stride> & array, 
+                      typename MultiArrayShape<N>::type chunkSize, int compression = 0)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        write_(datasetName, array, detail::getH5DataType<T>(), 3, chunkSize, compression);
+    }
+
+    template<unsigned int N, class T, class Stride>
+    inline void writeBlock(std::string datasetName, 
+                           typename MultiArrayShape<N>::type blockOffset, 
+                           const MultiArrayView<N, RGBValue<T>, Stride> & array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        writeBlock_(datasetName, blockOffset, array, detail::getH5DataType<T>(), 3);
+    }
+
+         /** \brief Write a single value.
+            Specialization of the write function for simple datatypes
+         */
+    inline void write(std::string datasetName, char data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, signed char data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, signed short data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, signed int data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, signed long data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, signed long long data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, unsigned char data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, unsigned short data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, unsigned int data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, unsigned long data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, unsigned long long data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, float data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, double data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, long double data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, const char* data) { writeAtomic(datasetName,data); }
+    inline void write(std::string datasetName, std::string const & data) { writeAtomic(datasetName,data.c_str()); }
+
+    // Reading data
+    
+        /** \brief Read data into a multi array.
+            If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+            otherwise it will be interpreted as path relative to the current group.
+
+            Note that the memory order between VIGRA and HDF5 files differs: VIGRA uses 
+            Fortran-order, while HDF5 uses C-order. This means that a HDF5 dataset,
+            whose indices represent the 'z'-, 'y'-, and 'x'-axis in that order, is reversed
+            upon reading into a MultiArrayView, i.e. in the array axis order must be 'x', 'y', 'z'. 
+        */
+    template<unsigned int N, class T, class Stride>
+    inline void read(std::string datasetName, MultiArrayView<N, T, Stride> array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        read_(datasetName, array, detail::getH5DataType<T>(), 1);
+    }
+
+        /** \brief Read data into a MultiArray. Resize MultiArray to the correct size.
+            If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+            otherwise it will be interpreted as path relative to the current group.
+
+            Note that the memory order between VIGRA and HDF5 files differs: VIGRA uses 
+            Fortran-order, while HDF5 uses C-order. This means that a HDF5 dataset,
+            whose indices represent the 'z'-, 'y'-, and 'x'-axis in that order, is reversed
+            upon reading into a MultiArray, i.e. in the array axis order will be 'x', 'y', 'z'. 
+        */
+    template<unsigned int N, class T, class Alloc>
+    inline void readAndResize(std::string datasetName, MultiArray<N, T, Alloc> & array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        // get dataset dimension
+        ArrayVector<hsize_t> dimshape = getDatasetShape(datasetName);
+
+        // check if dimensions are correct
+        vigra_precondition(N == MultiArrayIndex(dimshape.size()), // the object in the HDF5 file may have one additional dimension which we then interpret as the pixel type bands
+            "HDF5File::readAndResize(): Array dimension disagrees with dataset dimension.");
+
+        // reshape target MultiArray
+        typename MultiArrayShape<N>::type shape;
+        for(int k=0; k < (int)dimshape.size(); ++k)
+            shape[k] = (MultiArrayIndex)dimshape[k];
+        array.reshape(shape);
+
+        read_(datasetName, array, detail::getH5DataType<T>(), 1);
+    }
+
+        /** \brief Read data into an array vector.
+          If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+          otherwise it will be interpreted as path relative to the current group.
+        */
+    template<class T>
+    inline void read(const std::string & datasetName, ArrayVectorView<T> array)
+    {
+        // convert to a (trivial) MultiArrayView and forward.
+        MultiArrayShape<1>::type shape(array.size());
+        MultiArrayView<1, T> m_array(shape, (array.data()));
+        read(datasetName, m_array);
+    }
+
+        /** \brief Read data into an array vector. Resize the array vector to the correct size.
+            If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+            otherwise it will be interpreted as path relative to the current group.
+        */
+    template<class T>
+    inline void readAndResize(std::string datasetName,
+                              ArrayVector<T> & array)
+    {
+        // make dataset name clean
+        datasetName = get_absolute_path(datasetName);
+
+        // get dataset dimension
+        ArrayVector<hsize_t> dimshape = getDatasetShape(datasetName);
+
+        // check if dimensions are correct
+        vigra_precondition(1 == MultiArrayIndex(dimshape.size()),
+            "HDF5File::readAndResize(): Array dimension disagrees with Dataset dimension must equal one for vigra::ArrayVector.");
+
+        // resize target array vector
+        array.resize((typename ArrayVector<T>::size_type)dimshape[0]);
+        // convert to a (trivial) MultiArrayView and forward.
+        MultiArrayShape<1>::type shape(array.size());
+        MultiArrayView<1, T> m_array(shape, (array.data()));
+
+        read_(datasetName, m_array, detail::getH5DataType<T>(), 1);
+    }
+
+        /** \brief Read a block of data into a multi array.
+            This function allows to read a small block out of a larger volume stored
+            in an HDF5 dataset.
+
+            blockOffset determines the position of the block.
+            blockSize determines the size in each dimension of the block.
+
+            If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+            otherwise it will be interpreted as path relative to the current group.
+
+            Note that the memory order between VIGRA and HDF5 files differs: VIGRA uses 
+            Fortran-order, while HDF5 uses C-order. This means that a HDF5 dataset,
+            whose indices represent the 'z'-, 'y'-, and 'x'-axis in that order, is reversed
+            upon reading into a MultiArray, i.e. in the array axis order will be 'x', 'y', 'z'. 
+        */
+    template<unsigned int N, class T, class Stride>
+    inline void readBlock(std::string datasetName, 
+                          typename MultiArrayShape<N>::type blockOffset, 
+                          typename MultiArrayShape<N>::type blockShape, 
+                          MultiArrayView<N, T, Stride> array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        readBlock_(datasetName, blockOffset, blockShape, array, detail::getH5DataType<T>(), 1);
+    }
+
+    // non-scalar (TinyVector) and unstrided target MultiArrayView
+    template<unsigned int N, class T, int SIZE, class Stride>
+    inline void read(std::string datasetName, MultiArrayView<N, TinyVector<T, SIZE>, Stride> array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        read_(datasetName, array, detail::getH5DataType<T>(), SIZE);
+    }
+
+    // non-scalar (TinyVector) MultiArray
+    template<unsigned int N, class T, int SIZE, class Alloc>
+    inline void readAndResize(std::string datasetName, MultiArray<N, TinyVector<T, SIZE>, Alloc> & array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        // get dataset dimension
+        ArrayVector<hsize_t> dimshape = getDatasetShape(datasetName);
+
+        // check if dimensions are correct
+        vigra_precondition((N+1) ==  MultiArrayIndex(dimshape.size()) &&
+                           SIZE == dimshape[0], // the object in the HDF5 file must have one additional dimension which we interpret as the pixel type bands
+            "HDF5File::readAndResize(): Array dimension disagrees with dataset dimension.");
+        
+        // reshape target MultiArray
+        typename MultiArrayShape<N>::type shape;
+        for(int k=1; k < (int)dimshape.size(); ++k)
+            shape[k-1] = (MultiArrayIndex)dimshape[k];
+        array.reshape(shape);
+
+        read_(datasetName, array, detail::getH5DataType<T>(), SIZE);
+    }
+
+    template<unsigned int N, class T, int SIZE, class Stride>
+    inline void readBlock(std::string datasetName, 
+                          typename MultiArrayShape<N>::type blockOffset, 
+                          typename MultiArrayShape<N>::type blockShape, 
+                          MultiArrayView<N, TinyVector<T, SIZE>, Stride> array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        readBlock_(datasetName, blockOffset, blockShape, array, detail::getH5DataType<T>(), SIZE);
+    }
+
+    // non-scalar (RGBValue) and unstrided target MultiArrayView
+    template<unsigned int N, class T, class Stride>
+    inline void read(std::string datasetName, MultiArrayView<N, RGBValue<T>, Stride> array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        read_(datasetName, array, detail::getH5DataType<T>(), 3);
+    }
+
+    // non-scalar (RGBValue) MultiArray
+    template<unsigned int N, class T, class Alloc>
+    inline void readAndResize(std::string datasetName, MultiArray<N, RGBValue<T>, Alloc> & array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        // get dataset dimension
+        ArrayVector<hsize_t> dimshape = getDatasetShape(datasetName);
+
+        // check if dimensions are correct
+        vigra_precondition((N+1) ==  MultiArrayIndex(dimshape.size()) &&
+                           3 == dimshape[0], // the object in the HDF5 file must have one additional dimension which we interpret as the pixel type bands
+            "HDF5File::readAndResize(): Array dimension disagrees with dataset dimension.");
+
+        // reshape target MultiArray
+        typename MultiArrayShape<N>::type shape;
+        for(int k=1; k < (int)dimshape.size(); ++k)
+            shape[k-1] = (MultiArrayIndex)dimshape[k];
+        array.reshape(shape);
+
+        read_(datasetName, array, detail::getH5DataType<T>(), 3);
+    }
+
+    template<unsigned int N, class T, class Stride>
+    inline void readBlock(std::string datasetName, 
+                          typename MultiArrayShape<N>::type blockOffset, 
+                          typename MultiArrayShape<N>::type blockShape, 
+                          MultiArrayView<N, RGBValue<T>, Stride> array)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        readBlock_(datasetName, blockOffset, blockShape, array, detail::getH5DataType<T>(), 3);
+    }
+
+        /** \brief Read a single value.
+            Specialization of the read function for simple datatypes
+         */
+    inline void read(std::string datasetName, char &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, signed char &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, signed short &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, signed int &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, signed long &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, signed long long &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, unsigned char &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, unsigned short &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, unsigned int &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, unsigned long &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, unsigned long long &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, float &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, double &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, long double &data) { readAtomic(datasetName,data); }
+    inline void read(std::string datasetName, std::string &data) { readAtomic(datasetName,data); }
+
+        /** \brief Create a new dataset.
+            This function can be used to create a dataset filled with a default value,
+            for example before writing data into it using \ref writeBlock().
+            Attention: only atomic datatypes are provided. For spectral data, add an
+            dimension (case RGB: add one dimension of size 3).
+
+            shape determines the dimension and the size of the dataset.
+
+            Chunks can be activated by providing a MultiArrayShape as chunkSize.
+            chunkSize must have equal dimension as array.
+
+            Compression can be activated by setting 
+            \code compression = parameter; // 0 \< parameter \<= 9 
+            \endcode
+            where 0 stands for no compression and 9 for maximum compression.
+
+            If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+            otherwise it will be interpreted as path relative to the current group.
+
+            Note that the memory order between VIGRA and HDF5 files differs: VIGRA uses 
+            Fortran-order, while HDF5 uses C-order. This means that a VIGRA MultiArray,
+            whose indices represent the 'x'-, 'y'-, and 'z'-axis in that order, is reversed
+            upon writing to an HDF5 file, i.e. in the file the axis order is 'z', 'y', 'x'. 
+        */
+    template<unsigned int N, class T>
+    inline void createDataset(std::string datasetName, 
+                              typename MultiArrayShape<N>::type shape, 
+                              T init = T(), 
+                              int iChunkSize = 0, 
+                              int compressionParameter = 0)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        typename MultiArrayShape<N>::type chunkSize;
+        for(int i = 0; i < N; i++){
+            chunkSize[i] = iChunkSize;
+        }
+        createDataset<N,T>(datasetName, shape, init, chunkSize, compressionParameter);
+    }
+
+    template<unsigned int N, class T>
+    inline void createDataset(std::string datasetName, 
+                              typename MultiArrayShape<N>::type shape, 
+                              T init, 
+                              typename MultiArrayShape<N>::type chunkSize, 
+                              int compressionParameter = 0)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        std::string groupname = SplitString(datasetName).first();
+        std::string setname = SplitString(datasetName).last();
+
+        hid_t parent = openCreateGroup_(groupname);
+
+        // delete the dataset if it already exists
+        deleteDataset_(parent, setname);
+
+        // create dataspace
+        // add an extra dimension in case that the data is non-scalar
+        HDF5Handle dataspaceHandle;
+
+        // invert dimensions to guarantee c-order
+        hsize_t shape_inv[N];
+        for(unsigned int k=0; k<N; ++k)
+            shape_inv[N-1-k] = shape[k];
+
+        // create dataspace
+        dataspaceHandle = HDF5Handle(H5Screate_simple(N, shape_inv, NULL),
+                                    &H5Sclose, "HDF5File::createDataset(): unable to create dataspace for scalar data.");
+
+        // set fill value
+        HDF5Handle plist ( H5Pcreate(H5P_DATASET_CREATE), &H5Pclose, "HDF5File::createDataset(): unable to create property list." );
+        H5Pset_fill_value(plist,detail::getH5DataType<T>(), &init);
+
+        // turn off time tagging of datasets by default.
+        H5Pset_obj_track_times(plist, track_time);
+
+        // enable chunks
+        ArrayVector<hsize_t> chunks(defineChunks(chunkSize, shape, 1, compressionParameter));
+        if(chunks.size() > 0)
+        {
+            std::reverse(chunks.begin(), chunks.end());
+            H5Pset_chunk (plist, chunks.size(), chunks.begin());
+        }
+
+        // enable compression
+        if(compressionParameter > 0)
+        {
+            H5Pset_deflate(plist, compressionParameter);
+        }
+
+        //create the dataset.
+        HDF5Handle datasetHandle ( H5Dcreate(parent, setname.c_str(), detail::getH5DataType<T>(), dataspaceHandle, H5P_DEFAULT, plist, H5P_DEFAULT),
+                                  &H5Dclose, "HDF5File::createDataset(): unable to create dataset.");
+        if(parent != cGroupHandle_)
+            H5Gclose(parent);
+    }
+
+        /** \brief Immediately write all data to disk
+        */
+    inline void flushToDisk()
+    {
+        H5Fflush(fileHandle_, H5F_SCOPE_GLOBAL);
+    }
+
+  private:
+
+        /* Simple extension of std::string for splitting into two parts
+         *
+         *  Strings (in particular: file/dataset paths) will be split into two
+         *  parts. The split is made at the last occurrence of the delimiter.
+         *
+         *  For example, "/path/to/some/file" will be split (delimiter = "/") into
+         *  first() = "/path/to/some" and last() = "file".
+         */
+    class SplitString: public std::string {
+    public:
+        SplitString(std::string &sstring): std::string(sstring) {};
+
+        // return the part of the string before the delimiter
+        std::string first(char delimiter = '/')
+        {
+            size_t last = find_last_of(delimiter);
+            if(last == std::string::npos) // delimiter not found --> no first
+                return "";
+
+            return std::string(begin(), begin()+last+1);
+        }
+
+        // return the part of the string after the delimiter
+        std::string last(char delimiter = '/')
+        {
+            size_t last = find_last_of(delimiter);
+            if(last == std::string::npos) // delimiter not found --> only last
+                return std::string(*this);
+            return std::string(begin()+last+1, end());
+        }
+    };
+    
+    template <class Shape>
+    ArrayVector<hsize_t> 
+    defineChunks(Shape const & chunks, Shape const & shape, int numBands, int compression = 0)
+    {
+        if(chunks[0] > 0)
+        {
+            ArrayVector<hsize_t> res(chunks.begin(), chunks.end());
+            if(numBands > 1)
+                res.insert(res.begin(), numBands);
+            return res;
+        }
+        else if(compression > 0)
+        {
+            // set default chunks to enable compression 
+            // (arbitrarily include about 300k pixels into each chunk, but make sure
+            //  that the chunk size doesn't exceed the shape)
+            ArrayVector<hsize_t> res(shape.begin(), shape.end());
+            hsize_t chunk_length = (hsize_t)std::pow(300000.0, 1.0 / shape.size());
+            for(unsigned int k=0; k < shape.size(); ++k)
+                if(res[k] > chunk_length)
+                    res[k] = chunk_length;
+            if(numBands > 1)
+                res.insert(res.begin(), numBands);
+            return res;
+        }
+        else
+        {
+            return ArrayVector<hsize_t>();
+        }
+    }
+
+  public:
+
+        /** \brief takes any path and converts it into an absolute path
+             in the current file.
+           
+             Elements like "." and ".." are treated as expected.
+             Links are not supported or resolved.
+        */
+    inline std::string get_absolute_path(std::string path) const {
+        // check for empty input or "." and return the current folder
+        if(path.length() == 0 || path == "."){
+            return currentGroupName_();
+        }
+
+        std::string str;
+        // convert to absolute path
+        if(relativePath_(path)){
+            std::string cname = currentGroupName_();
+            if (cname == "/")
+                str = currentGroupName_()+path;
+            else
+                str = currentGroupName_()+"/"+path;
+        }else{
+            str = path;
+        }
+
+        // cut out "./"
+        std::string::size_type startpos = 0;
+        while(str.find(std::string("./"), startpos) != std::string::npos){
+            std::string::size_type pos = str.find(std::string("./"), startpos);
+            startpos = pos+1;
+            // only cut if "./" is not part of "../" (see below)
+            if(str.substr(pos-1,3) != "../"){
+                // cut out part of the string
+                str = str.substr(0,pos) + str.substr(pos+2,str.length()-pos-2);
+                startpos = pos;
+            }
+        }
+
+        // cut out pairs of "bla/../"
+        while(str.find(std::string("..")) != std::string::npos){
+            std::string::size_type pos = str.find(std::string(".."));
+
+            // find first slash after ".."
+            std::string::size_type end = str.find("/",pos);
+            if(end != std::string::npos){
+                // also include slash
+                end++;
+            }else{
+                // no "/" after ".." --> this is a group, add a "/"
+                str = str + "/";
+                end = str.length();
+            }
+
+            // find first slash before ".."
+            std::string::size_type prev_slash = str.rfind("/",pos);
+            // if the root slash is the first before ".." --> Error
+            vigra_invariant(prev_slash != 0 && prev_slash != std::string::npos,
+                            "Error parsing path: "+str);
+            // find second slash before ".."
+            std::string::size_type begin = str.rfind("/",prev_slash-1);
+
+            // cut out part of the string
+            str = str.substr(0,begin+1) + str.substr(end,str.length()-end);
+        }
+
+        return str;
+    }
+    
+  protected:
+
+        /* checks if the given path is a relative path.
+         */
+    inline bool relativePath_(std::string & path) const
+    {
+        std::string::size_type pos = path.find('/') ;
+        if(pos == 0)
+            return false;
+
+        return true;
+    }
+
+        /* return the name of the current group
+         */
+    inline std::string currentGroupName_() const
+    {
+        int len = H5Iget_name(cGroupHandle_,NULL,1000);
+        ArrayVector<char> name (len+1,0);
+        H5Iget_name(cGroupHandle_,name.begin(),len+1);
+
+        return std::string(name.begin());
+    }
+
+        /* return the name of the current file
+         */
+    inline std::string fileName_() const
+    {
+        int len = H5Fget_name(fileHandle_,NULL,1000);
+        ArrayVector<char> name (len+1,0);
+        H5Fget_name(fileHandle_,name.begin(),len+1);
+
+        return std::string(name.begin());
+    }
+
+        /* create an empty file and open is
+         */
+    inline hid_t createFile_(std::string filePath, OpenMode mode = Open)
+    {
+        // try to open file
+        FILE * pFile;
+        pFile = fopen ( filePath.c_str(), "r" );
+        hid_t fileId;
+
+        // check if opening was successful (= file exists)
+        if ( pFile == NULL )
+        {
+            fileId = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+        }
+        else if(mode == Open)
+        {
+            fclose( pFile );
+            fileId = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
+        }
+        else if(mode == OpenReadOnly) {
+            fclose( pFile );
+            fileId = H5Fopen(filePath.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
+        }
+        else
+        {
+            fclose(pFile);
+            std::remove(filePath.c_str());
+            fileId = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+        }
+        return fileId;
+    }
+
+        /* open a group and subgroups. Create if necessary.
+         */
+    inline hid_t openCreateGroup_(std::string groupName)
+    {
+        // make groupName clean
+        groupName = get_absolute_path(groupName);
+
+        // open root group
+        hid_t parent = H5Gopen(fileHandle_, "/", H5P_DEFAULT);
+        if(groupName == "/")
+        {
+            return parent;
+        }
+
+        // remove leading /
+        groupName = std::string(groupName.begin()+1, groupName.end());
+
+        // check if the groupName has finishing slash
+        if( groupName.size() != 0 && *groupName.rbegin() != '/')
+        {
+            groupName = groupName + '/';
+        }
+
+        // open or create subgroups one by one
+        std::string::size_type begin = 0, end = groupName.find('/');
+        while (end != std::string::npos)
+        {
+            std::string group(groupName.begin()+begin, groupName.begin()+end);
+            hid_t prevParent = parent;
+
+            if(H5LTfind_dataset(parent, group.c_str()) == 0)
+            {
+                parent = H5Gcreate(prevParent, group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+            } else {
+                parent = H5Gopen(prevParent, group.c_str(), H5P_DEFAULT);
+            }
+            H5Gclose(prevParent);
+
+            if(parent < 0)
+            {
+                return parent;
+            }
+            begin = end + 1;
+            end = groupName.find('/', begin);
+        }
+
+        return parent;
+    }
+
+        /* delete a dataset by unlinking it from the file structure. This does not
+           delete the data!
+         */
+    inline void deleteDataset_(hid_t parent, std::string datasetName)
+    {
+        // delete existing data and create new dataset
+        if(H5LTfind_dataset(parent, datasetName.c_str()))
+        {
+
+    #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
+            if(H5Gunlink(parent, datasetName.c_str()) < 0)
+            {
+                vigra_postcondition(false, "HDF5File::deleteDataset_(): Unable to delete existing data.");
+            }
+    #else
+            if(H5Ldelete(parent, datasetName.c_str(), H5P_DEFAULT ) < 0)
+            {
+                vigra_postcondition(false, "HDF5File::deleteDataset_(): Unable to delete existing data.");
+            }
+    #endif
+        }
+    }
+
+        /* get the handle of a dataset specified by a string
+         */
+    inline hid_t getDatasetHandle_(std::string datasetName)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        std::string groupname = SplitString(datasetName).first();
+        std::string setname = SplitString(datasetName).last();
+
+        if(H5Lexists(fileHandle_, datasetName.c_str(), H5P_DEFAULT) <= 0)
+        {
+            std::cerr << "HDF5File::getDatasetHandle_(): Dataset '" << datasetName << "' does not exist.\n";
+            return -1;
+        }
+
+        // Open parent group
+        HDF5Handle groupHandle(openCreateGroup_(groupname), &H5Gclose, "HDF5File::getDatasetHandle_(): Internal error");
+
+        return H5Dopen(groupHandle, setname.c_str(), H5P_DEFAULT);
+    }
+
+        /* get the type of an object specified by a string
+         */
+    H5O_type_t get_object_type_(std::string name)
+    {
+        name = get_absolute_path(name);
+        std::string group_name = SplitString(name).first();
+        std::string object_name = SplitString(name).last();
+        if (!object_name.size())
+            return H5O_TYPE_GROUP;
+
+        htri_t exists = H5Lexists(fileHandle_, name.c_str(), H5P_DEFAULT);
+        vigra_precondition(exists > 0,  "HDF5File::get_object_type_(): "
+                                        "object \"" + name + "\" "
+                                        "not found.");
+        // open parent group
+        HDF5Handle group_handle(openCreateGroup_(group_name), &H5Gclose, "Internal error");
+        return HDF5_get_type(group_handle, name.c_str());
+    }
+
+        /* low-level write function to write vigra MultiArray data as an attribute
+         */
+    template<unsigned int N, class T, class Stride>
+    void write_attribute_(std::string name, 
+                          const std::string & attribute_name,
+                          const MultiArrayView<N, T, Stride> & array,
+                          const hid_t datatype, 
+                          const int numBandsOfType);
+
+        /* Write single value attribute
+           This function allows to write data of atomic datatypes (int, long, double)
+           as an attribute in the HDF5 file. So it is not necessary to create a MultiArray
+           of size 1 to write a single number.
+        */
+    template<class T>
+    inline void writeAtomicAttribute(std::string datasetName, std::string attributeName, const T data)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        typename MultiArrayShape<1>::type chunkSize;
+        chunkSize[0] = 0;
+        MultiArray<1,T> array(MultiArrayShape<1>::type(1));
+        array[0] = data;
+        write_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 1);
+    }
+
+        /* low-level read function to read vigra MultiArray data from attributes
+         */
+    template<unsigned int N, class T, class Stride>
+    void read_attribute_(std::string datasetName, 
+                         std::string attributeName, 
+                         MultiArrayView<N, T, Stride> array, 
+                         const hid_t datatype, const int numBandsOfType);
+
+        /* Read a single value attribute.
+           This functions allows to read a single value attribute of atomic datatype (int, long, double)
+           from the HDF5 file. So it is not necessary to create a MultiArray
+           of size 1 to read a single number.
+        */
+    template<class T>
+    inline void readAtomicAttribute(std::string datasetName, std::string attributeName, T & data)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        MultiArray<1,T> array(MultiArrayShape<1>::type(1));
+        read_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 1);
+        data = array[0];
+    }
+
+    inline void readAtomicAttribute(std::string datasetName, std::string attributeName, std::string & data)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        MultiArray<1,const char *> array(MultiArrayShape<1>::type(1));
+        read_attribute_(datasetName, attributeName, array, detail::getH5DataType<const char *>(), 1);
+        data = std::string(array[0]);
+    }
+
+        /* low-level write function to write vigra unstrided MultiArray data
+        */
+    template<unsigned int N, class T, class Stride>
+    void write_(std::string &datasetName, 
+                       const MultiArrayView<N, T, Stride> & array, 
+                       const hid_t datatype, 
+                       const int numBandsOfType, 
+                       typename MultiArrayShape<N>::type &chunkSize, 
+                       int compressionParameter = 0);
+
+        /* Write single value as dataset.
+           This functions allows to write data of atomic datatypes (int, long, double)
+           as a dataset in the HDF5 file. So it is not necessary to create a MultiArray
+           of size 1 to write a single number.
+
+           If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+           otherwise it will be interpreted as path relative to the current group.
+        */
+    template<class T>
+    inline void writeAtomic(std::string datasetName, const T data)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        typename MultiArrayShape<1>::type chunkSize;
+        chunkSize[0] = 0;
+        MultiArray<1,T> array(MultiArrayShape<1>::type(1));
+        array[0] = data;
+        write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize,0);
+    }
+
+        /* low-level read function to read vigra unstrided MultiArray data
+         */
+    template<unsigned int N, class T, class Stride>
+    void read_(std::string datasetName, 
+                      MultiArrayView<N, T, Stride> array, 
+                      const hid_t datatype, const int numBandsOfType);
+
+        /* Read a single value.
+           This functions allows to read a single datum of atomic datatype (int, long, double)
+           from the HDF5 file. So it is not necessary to create a MultiArray
+           of size 1 to read a single number.
+
+           If the first character of datasetName is a "/", the path will be interpreted as absolute path,
+           otherwise it will be interpreted as path relative to the current group.
+        */
+    template<class T>
+    inline void readAtomic(std::string datasetName, T & data)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        MultiArray<1,T> array(MultiArrayShape<1>::type(1));
+        read_(datasetName, array, detail::getH5DataType<T>(), 1);
+        data = array[0];
+    }
+
+    inline void readAtomic(std::string datasetName, std::string & data)
+    {
+        // make datasetName clean
+        datasetName = get_absolute_path(datasetName);
+
+        MultiArray<1,const char *> array(MultiArrayShape<1>::type(1));
+        read_(datasetName, array, detail::getH5DataType<const char *>(), 1);
+        data = std::string(array[0]);
+    }
+
+       /* low-level write function to write vigra unstrided MultiArray data into a sub-block of a dataset
+       */
+    template<unsigned int N, class T, class Stride>
+    void writeBlock_(std::string datasetName, 
+                     typename MultiArrayShape<N>::type &blockOffset, 
+                     const MultiArrayView<N, T, Stride> & array, 
+                     const hid_t datatype, 
+                     const int numBandsOfType);
+
+        /* low-level read function to read vigra unstrided MultiArray data from a sub-block of a dataset.
+        
+           The array must have the same shape as the block.
+        */
+    template<unsigned int N, class T, class Stride>
+    void readBlock_(std::string datasetName, 
+                    typename MultiArrayShape<N>::type &blockOffset, 
+                    typename MultiArrayShape<N>::type &blockShape, 
+                    MultiArrayView<N, T, Stride> &array, 
+                    const hid_t datatype, const int numBandsOfType);
+};  /* class HDF5File */
+
+/********************************************************************/
+
+template<unsigned int N, class T, class Stride>
+void HDF5File::write_(std::string &datasetName, 
+                      const MultiArrayView<N, T, Stride> & array, 
+                      const hid_t datatype, 
+                      const int numBandsOfType, 
+                      typename MultiArrayShape<N>::type &chunkSize, 
+                      int compressionParameter)
+{
+    std::string groupname = SplitString(datasetName).first();
+    std::string setname = SplitString(datasetName).last();
+
+    // shape of the array. Add one dimension, if array contains non-scalars.
+    ArrayVector<hsize_t> shape(array.shape().begin(), array.shape().end());
+    std::reverse(shape.begin(), shape.end());
+
+    if(numBandsOfType > 1)
+        shape.push_back(numBandsOfType);
+
+    HDF5Handle dataspace(H5Screate_simple(shape.size(), shape.begin(), NULL), &H5Sclose, 
+                         "HDF5File::write(): Can not create dataspace.");
+
+    // create and open group:
+    std::string errorMessage ("HDF5File::write(): can not create group '" + groupname + "'.");
+    HDF5Handle groupHandle(openCreateGroup_(groupname), &H5Gclose, errorMessage.c_str());
+
+    // delete dataset, if it already exists
+    deleteDataset_(groupHandle, setname.c_str());
+
+    // set up properties list
+    HDF5Handle plist(H5Pcreate(H5P_DATASET_CREATE), &H5Pclose, 
+                     "HDF5File::write(): unable to create property list." );
+
+    // turn off time tagging of datasets by default.
+    H5Pset_obj_track_times(plist, track_time);
+
+    // enable chunks
+    ArrayVector<hsize_t> chunks(defineChunks(chunkSize, array.shape(), numBandsOfType, compressionParameter));
+    if(chunks.size() > 0)
+    {
+        std::reverse(chunks.begin(), chunks.end());
+        H5Pset_chunk (plist, chunks.size(), chunks.begin());
+    }
+
+    // enable compression
+    if(compressionParameter > 0)
+    {
+        H5Pset_deflate(plist, compressionParameter);
+    }
+
+    // create dataset
+    HDF5Handle datasetHandle(H5Dcreate(groupHandle, setname.c_str(), datatype, dataspace,H5P_DEFAULT, plist, H5P_DEFAULT), 
+                             &H5Dclose, "HDF5File::write(): Can not create dataset.");
+
+    herr_t status = 0;
+    if(array.isUnstrided())
+    {
+        // Write the data directly from the array data buffer
+        status = H5Dwrite(datasetHandle, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.data());
+    }
+    else
+    {
+        // otherwise, we need an intermediate buffer
+        // FIXME: right now, the buffer has the same size as the array to be read
+        //        incomplete code for better solutions is below
+        // MultiArray<N, T> buffer(array);
+        // status = H5Dwrite(datasetHandle, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer.data());
+        
+        int offset = numBandsOfType > 1 ? 1 : 0;
+        std::reverse(shape.begin(), shape.end());
+        if(chunks.size() > 0)
+        {
+            // if the file is chunked, we use a buffer that matches the chunk size.
+            std::reverse(chunks.begin(), chunks.end());
+        }
+        else
+        {
+            // otherwise, we compute a suitable chunk size.
+            ArrayVector<hsize_t>(shape.size(), 1).swap(chunks);
+            chunks[0] = numBandsOfType;
+            MultiArrayIndex prod = 1;
+            for(unsigned int k=0; k<N;  ++k)
+            {
+                chunks[k+offset] = array.shape(k);
+                prod *= array.shape(k);
+                if(prod > 300000)
+                    break;
+            }
+        }
+
+        ArrayVector<hsize_t> null(shape.size(), 0),
+                             start(shape.size(), 0),
+                             count(shape.size(), 1);
+        
+        count[N-1-offset] = numBandsOfType;
+        
+        typedef typename MultiArrayShape<N>::type Shape;
+        Shape chunkCount, chunkMaxShape;
+        for(unsigned int k=offset; k<chunks.size(); ++k)
+        {
+            chunkMaxShape[k-offset] = chunks[k];
+            chunkCount[k-offset] = (MultiArrayIndex)std::ceil(double(shape[k]) / chunks[k]);
+        }
+        
+        typename CoupledIteratorType<N>::type chunkIter = createCoupledIterator(chunkCount),
+                                              chunkEnd  = chunkIter.getEndIterator();
+        for(; chunkIter != chunkEnd; ++chunkIter)
+        {
+            Shape chunkStart(chunkIter.point() * chunkMaxShape),
+                  chunkStop(min(chunkStart + chunkMaxShape, array.shape()));
+            MultiArray<N, T> buffer(array.subarray(chunkStart, chunkStop));
+            
+            for(unsigned int k=0; k<N; ++k)
+            {
+                start[N-1-k] = chunkStart[k];
+                count[N-1-k] = buffer.shape(k);
+            }
+            if(offset == 1)
+            {
+                start[N] = 0;
+                count[N] = numBandsOfType;
+            }
+            HDF5Handle filespace(H5Dget_space(datasetHandle),
+                                 &H5Sclose, "HDF5File::write(): unable to create hyperslabs.");
+            status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start.data(), NULL, count.data(), NULL);
+            if(status < 0)
+                break;
+                
+            HDF5Handle dataspace(H5Screate_simple(count.size(), count.data(), NULL),
+                                 &H5Sclose, "HDF5File::write(): unable to create hyperslabs."); 
+            status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, null.data(), NULL, count.data(), NULL);
+            if(status < 0)
+                break;
+                
+            status = H5Dwrite(datasetHandle, datatype, dataspace, filespace, H5P_DEFAULT, buffer.data());
+            if(status < 0)
+                break;
+        }
+    }
+    vigra_postcondition(status >= 0,
+        "HDF5File::write(): write to dataset '" + datasetName + "' via H5Dwrite() failed.");
+}
+
+/********************************************************************/
+
+template<unsigned int N, class T, class Stride>
+void HDF5File::writeBlock_(std::string datasetName, 
+                           typename MultiArrayShape<N>::type &blockOffset, 
+                           const MultiArrayView<N, T, Stride> & array, 
+                           const hid_t datatype, 
+                           const int numBandsOfType)
+{
+    // open dataset if it exists
+    std::string errorMessage = "HDF5File::writeBlock(): Error opening dataset '" + datasetName + "'.";
+    HDF5Handle datasetHandle (getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
+
+    // hyperslab parameters for position, size, ...
+    hsize_t boffset [N];
+    hsize_t bshape [N];
+    hsize_t bones [N];
+
+    for(int i = 0; i < N; i++){
+        boffset[i] = blockOffset[N-1-i];
+        bshape[i] = array.size(N-1-i);
+        bones[i] = 1;
+    }
+
+    // create a target dataspace in memory with the shape of the desired block
+    HDF5Handle memspace_handle (H5Screate_simple(N,bshape,NULL),&H5Sclose,"Unable to get origin dataspace");
+
+    // get file dataspace and select the desired block
+    HDF5Handle dataspaceHandle (H5Dget_space(datasetHandle),&H5Sclose,"Unable to create target dataspace");
+    H5Sselect_hyperslab(dataspaceHandle, H5S_SELECT_SET, boffset, bones, bones, bshape);
+
+    herr_t status = 0;
+    if(array.isUnstrided())
+    {
+        // when the array is unstrided, we can read the data directly from the array buffer
+        status = H5Dwrite( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, array.data());
+    }
+    else
+    {
+        // otherwise, we must copy the data into an unstrided extra buffer
+        MultiArray<N, T> buffer(array);
+        status = H5Dwrite( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, buffer.data());
+    }
+    vigra_postcondition(status >= 0,
+        "HDF5File::writeBlock(): write to dataset '" + datasetName + "' via H5Dwrite() failed.");
+}
+
+/********************************************************************/
+
+template<unsigned int N, class T, class Stride>
+void HDF5File::write_attribute_(std::string name, 
+                                const std::string & attribute_name,
+                                const MultiArrayView<N, T, Stride> & array,
+                                const hid_t datatype, 
+                                const int numBandsOfType)
+{
+    // shape of the array. Add one dimension, if array contains non-scalars.
+    ArrayVector<hsize_t> shape(array.shape().begin(), array.shape().end());
+    std::reverse(shape.begin(), shape.end());
+    if(numBandsOfType > 1)
+        shape.push_back(numBandsOfType);
+
+    HDF5Handle dataspace(H5Screate_simple(shape.size(),
+                                          shape.begin(), NULL),
+                         &H5Sclose, "HDF5File::writeAttribute(): Can not"
+                                    " create dataspace.");
+
+    std::string errorMessage ("HDF5File::writeAttribute(): can not find "
+                              "object '" + name + "'.");
+
+    H5O_type_t h5_type = get_object_type_(name);
+    bool is_group = h5_type == H5O_TYPE_GROUP;
+    if (!is_group && h5_type != H5O_TYPE_DATASET)
+        vigra_precondition(0, "HDF5File::writeAttribute(): object \""
+                               + name + "\" is neither a group nor a "
+                               "dataset.");
+    // get parent object handle
+    HDF5Handle object_handle(is_group
+                                 ? openCreateGroup_(name)
+                                 : getDatasetHandle_(name),
+                             is_group
+                                 ? &H5Gclose
+                                 : &H5Dclose,
+                             errorMessage.c_str());
+    // create / open attribute
+    bool exists = existsAttribute(name, attribute_name);
+    HDF5Handle attributeHandle(exists
+                               ? H5Aopen(object_handle,
+                                         attribute_name.c_str(),
+                                         H5P_DEFAULT)
+                               : H5Acreate(object_handle,
+                                           attribute_name.c_str(), datatype,
+                                           dataspace, H5P_DEFAULT,
+                                           H5P_DEFAULT),
+                               &H5Aclose,
+                               "HDF5File::writeAttribute(): Can not create"
+                               " attribute.");
+    herr_t status = 0;
+    if(array.isUnstrided())
+    {
+        // write the data directly from the array data buffer
+        status = H5Awrite(attributeHandle, datatype, array.data());
+    }
+    else
+    {
+        // write the data via an unstrided copy
+        // (we assume that attributes are small arrays, so that the wasted memory is uncritical)
+        MultiArray<N, T> buffer(array);
+        status = H5Awrite(attributeHandle, datatype, buffer.data());
+    }
+    vigra_postcondition(status >= 0,
+        "HDF5File::writeAttribute(): write to attribute '" + attribute_name + "' via H5Awrite() failed.");
+}
+    
+/********************************************************************/
+
+template<unsigned int N, class T, class Stride>
+void HDF5File::read_(std::string datasetName, 
+                     MultiArrayView<N, T, Stride> array, 
+                     const hid_t datatype, const int numBandsOfType)
+{
+    //Prepare to read without using HDF5ImportInfo
+    ArrayVector<hsize_t> dimshape = getDatasetShape(datasetName);
+
+    std::string errorMessage ("HDF5File::read(): Unable to open dataset '" + datasetName + "'.");
+    HDF5Handle datasetHandle(getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
+
+    // the object in the HDF5 file may have one additional dimension which we 
+    // interprete as the pixel type's bands
+    int offset = (numBandsOfType > 1)
+                    ? 1
+                    : 0;
+
+    vigra_precondition((N + offset ) == MultiArrayIndex(dimshape.size()), 
+        "HDF5File::read(): Array dimension disagrees with dataset dimension.");
+
+    typename MultiArrayShape<N>::type shape;
+    for(int k=offset; k < (int)dimshape.size(); ++k)
+        shape[k-offset] = (MultiArrayIndex)dimshape[k];
+
+    vigra_precondition(shape == array.shape(),
+                       "HDF5File::read(): Array shape disagrees with dataset shape.");
+    if (offset)
+        vigra_precondition(dimshape[0] == static_cast<hsize_t>(numBandsOfType),
+                           "HDF5File::read(): Band count doesn't match destination array compound type.");
+
+    herr_t status = 0;
+    if(array.isUnstrided())
+    {
+        // when the array is unstrided, we can read the data directly into the array buffer
+        status = H5Dread(datasetHandle, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.data() );
+    }
+    else
+    {
+        // otherwise, we need an intermediate buffer
+
+        ArrayVector<hsize_t> null(dimshape.size(), 0),
+                             chunks(dimshape.size(), 1),
+                             start(dimshape.size(), 0),
+                             count(dimshape.size(), 1);
+
+        HDF5Handle properties(H5Dget_create_plist(datasetHandle),
+                             &H5Pclose, "HDF5File::read(): failed to get property list");
+        if(H5D_CHUNKED == H5Pget_layout(properties))
+        {
+            // if the file is chunked, we use a buffer that matches the chunk size.
+            H5Pget_chunk(properties, chunks.size(), chunks.data());
+            std::reverse(chunks.begin(), chunks.end());
+        }
+        else
+        {
+            // otherwise, we compute a suitable chunk size.
+            chunks[0] = numBandsOfType;
+            MultiArrayIndex prod = 1;
+            for(unsigned int k=0; k<N; ++k)
+            {
+                chunks[k+offset] = array.shape(k);
+                prod *= array.shape(k);
+                if(prod > 300000)
+                    break;
+            }
+        }
+        
+        count[N-1-offset] = numBandsOfType;
+        
+        typedef typename MultiArrayShape<N>::type Shape;
+        Shape chunkCount, chunkMaxShape;
+        for(unsigned int k=offset; k<chunks.size(); ++k)
+        {
+            chunkMaxShape[k-offset] = chunks[k];
+            chunkCount[k-offset] = (MultiArrayIndex)std::ceil(double(dimshape[k]) / chunks[k]);
+        }
+        
+        typename CoupledIteratorType<N>::type chunkIter = createCoupledIterator(chunkCount),
+                                              chunkEnd  = chunkIter.getEndIterator();
+        for(; chunkIter != chunkEnd; ++chunkIter)
+        {
+            Shape chunkStart(chunkIter.point() * chunkMaxShape),
+                  chunkStop(min(chunkStart + chunkMaxShape, array.shape()));
+            MultiArray<N, T> buffer(chunkStop - chunkStart);
+            
+            for(unsigned int k=0; k<N; ++k)
+            {
+                start[N-1-k] = chunkStart[k];
+                count[N-1-k] = buffer.shape(k);
+            }
+            if(offset == 1)
+            {
+                start[N] = 0;
+                count[N] = numBandsOfType;
+            }
+            HDF5Handle filespace(H5Dget_space(datasetHandle),
+                                 &H5Sclose, "HDF5File::read(): unable to create hyperslabs.");
+            status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start.data(), NULL, count.data(), NULL);
+            if(status < 0)
+                break;
+                
+            HDF5Handle dataspace(H5Screate_simple(count.size(), count.data(), NULL),
+                                 &H5Sclose, "HDF5File::read(): unable to create hyperslabs."); 
+            status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, null.data(), NULL, count.data(), NULL);
+            if(status < 0)
+                break;
+                
+            status = H5Dread(datasetHandle, datatype, dataspace, filespace, H5P_DEFAULT, buffer.data());
+            if(status < 0)
+                break;
+                
+            array.subarray(chunkStart, chunkStop) = buffer;
+        }
+    }
+    vigra_postcondition(status >= 0,
+        "HDF5File::read(): read from dataset '" + datasetName + "' via H5Dread() failed.");
+}
+
+/********************************************************************/
+
+template<unsigned int N, class T, class Stride>
+void HDF5File::readBlock_(std::string datasetName, 
+                          typename MultiArrayShape<N>::type &blockOffset, 
+                          typename MultiArrayShape<N>::type &blockShape, 
+                          MultiArrayView<N, T, Stride> &array, 
+                          const hid_t datatype, const int numBandsOfType)
+{
+    //Prepare to read without using HDF5ImportInfo
+    //ArrayVector<hsize_t> dimshape = getDatasetShape(datasetName) ;
+    hssize_t dimensions = getDatasetDimensions(datasetName);
+
+    std::string errorMessage ("HDF5File::readBlock(): Unable to open dataset '" + datasetName + "'.");
+    HDF5Handle datasetHandle (getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
+
+    int offset = (numBandsOfType > 1)
+                     ? 1
+                     : 0;
+
+    vigra_precondition(( (N + offset ) ==  MultiArrayIndex(dimensions)), // the object in the HDF5 file may have one additional dimension which we then interpret as the pixel type bands
+        "HDF5File::readBlock(): Array dimension disagrees with data dimension.");
+
+    vigra_precondition(blockShape == array.shape(),
+         "HDF5File::readBlock(): Array shape disagrees with block size.");
+
+    // hyperslab parameters for position, size, ...
+    hsize_t boffset [N];
+    hsize_t bshape [N];
+    hsize_t bones [N];
+
+    for(int i = 0; i < N; i++){
+        // vigra and hdf5 use different indexing
+        boffset[i] = blockOffset[N-1-i];
+        //bshape[i] = blockShape[i];
+        bshape[i] = blockShape[N-1-i];
+        //boffset[i] = blockOffset[N-1-i];
+        bones[i] = 1;
+    }
+
+    // create a target dataspace in memory with the shape of the desired block
+    HDF5Handle memspace_handle(H5Screate_simple(N,bshape,NULL),&H5Sclose,
+                               "Unable to create target dataspace");
+
+    // get file dataspace and select the desired block
+    HDF5Handle dataspaceHandle(H5Dget_space(datasetHandle),&H5Sclose, 
+                               "Unable to get dataspace");
+    H5Sselect_hyperslab(dataspaceHandle, H5S_SELECT_SET, boffset, bones, bones, bshape);
+
+    herr_t status = 0;
+    if(array.isUnstrided())
+    {
+        // when the array is unstrided, we can read the data directly into the array buffer
+        status = H5Dread( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, array.data());
+    }
+    else
+    {
+        // otherwise, we need an unstrided extra buffer ...
+        MultiArray<N, T> buffer(array.shape());
+        status = H5Dread( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, buffer.data());
+        // ... and must copy the values
+        if(status >= 0)
+            array = buffer;
+    }
+    vigra_postcondition(status >= 0,
+        "HDF5File::readBlock(): read from dataset '" + datasetName + "' via H5Dread() failed.");
+}
+
+/********************************************************************/
+
+template<unsigned int N, class T, class Stride>
+void HDF5File::read_attribute_(std::string datasetName, 
+                               std::string attributeName, 
+                               MultiArrayView<N, T, Stride> array, 
+                               const hid_t datatype, const int numBandsOfType)
+{
+    std::string dataset_path = get_absolute_path(datasetName);
+    // open Attribute handle
+    std::string message = "HDF5File::readAttribute(): could not get handle for attribute '"+attributeName+"'' of object '"+dataset_path+"'.";
+    HDF5Handle attr_handle (H5Aopen_by_name(fileHandle_,dataset_path.c_str(),attributeName.c_str(),H5P_DEFAULT,H5P_DEFAULT),&H5Aclose, message.c_str());
+
+    // get Attribute dataspace
+    message = "HDF5File::readAttribute(): could not get dataspace for attribute '"+attributeName+"'' of object '"+dataset_path+"'.";
+    HDF5Handle attr_dataspace_handle (H5Aget_space(attr_handle),&H5Sclose,message.c_str());
+
+    // obtain Attribute shape
+    int raw_dims = H5Sget_simple_extent_ndims(attr_dataspace_handle);
+    int dims = std::max(raw_dims, 1); // scalar attributes may be stored with raw_dims==0
+    ArrayVector<hsize_t> dimshape(dims);
+    if(raw_dims > 0)
+        H5Sget_simple_extent_dims(attr_dataspace_handle, dimshape.data(), NULL);
+    else
+        dimshape[0] = 1;
+    
+    // invert the dimensions to guarantee VIGRA-compatible order
+    std::reverse(dimshape.begin(), dimshape.end());
+
+    int offset = (numBandsOfType > 1)
+                    ? 1
+                    : 0;
+    message = "HDF5File::readAttribute(): Array dimension disagrees with dataset dimension.";
+    // the object in the HDF5 file may have one additional dimension which we then interpret as the pixel type bands
+    vigra_precondition((N + offset) == MultiArrayIndex(dims), message);
+
+    for(int k=offset; k < (int)dimshape.size(); ++k)
+        vigra_precondition(array.shape()[k-offset] == (MultiArrayIndex)dimshape[k],
+                           "HDF5File::readAttribute(): Array shape disagrees with dataset shape");
+
+    herr_t status = 0;
+    if(array.isUnstrided())
+    {
+        // when the array is unstrided, we can read the data directly into the array buffer
+        status = H5Aread( attr_handle, datatype, array.data());
+    }
+    else
+    {
+        // otherwise, we need an unstrided extra buffer ...
+        // (we assume that attributes are small arrays, so that the wasted memory is uncritical)
+        MultiArray<N, T> buffer(array.shape());
+        status = H5Aread( attr_handle, datatype, buffer.data() );
+        // ... and must copy the values
+        if(status >= 0)
+            array = buffer;
+    }
+    vigra_postcondition(status >= 0,
+        "HDF5File::readAttribute(): read from attribute '" + attributeName + "' via H5Aread() failed.");
+}
+
+/********************************************************************/
+
+/** \brief Read the data specified by the given \ref vigra::HDF5ImportInfo object
+                and write the into the given 'array'.
+                
+    The array must have the correct number of dimensions and shape for the dataset 
+    represented by 'info'. When the element type of 'array' differs from the stored element
+    type, HDF5 will convert the type on the fly (except when the HDF5 version is 1.6 or below,
+    in which case an error will result). Multi-channel element types (i.e. \ref vigra::RGBValue,
+    \ref vigra::TinyVector, and \ref vigra::FFTWComplex) are recognized and handled correctly.
+    
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        template<unsigned int N, class T, class StrideTag>
+        void 
+        readHDF5(const HDF5ImportInfo &info, MultiArrayView<N, T, StrideTag> array);
+    }
+    \endcode
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/hdf5impex.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    
+    HDF5ImportInfo info(filename, dataset_name);
+    vigra_precondition(info.numDimensions() == 3, "Dataset must be 3-dimensional.");
+    
+    MultiArrayShape<3>::type shape(info.shape().begin());
+    MultiArray<3, int> array(shape);
+    
+    readHDF5(info, array);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void readHDF5)
+
+template<unsigned int N, class T, class StrideTag>
+inline void readHDF5(const HDF5ImportInfo &info, MultiArrayView<N, T, StrideTag> array)
+{
+    readHDF5(info, array, 0, 0); // last two arguments are not used
+}
+
+template<unsigned int N, class T, class StrideTag>
+void readHDF5(const HDF5ImportInfo &info, MultiArrayView<N, T, StrideTag> array, const hid_t datatype, const int numBandsOfType)
+{
+    HDF5File file(info.getFilePath(), HDF5File::OpenReadOnly);
+    file.read(info.getPathInFile(), array);
+    file.close();
+}
+
+inline hid_t openGroup(hid_t parent, std::string group_name)
+{
+    //std::cout << group_name << std::endl;
+    size_t last_slash = group_name.find_last_of('/'); 
+    if (last_slash == std::string::npos || last_slash != group_name.size() - 1)
+        group_name = group_name + '/';
+    std::string::size_type begin = 0, end = group_name.find('/');
+    int ii =  0;
+    while (end != std::string::npos)
+    {
+        std::string group(group_name.begin()+begin, group_name.begin()+end);
+        hid_t prev_parent = parent; 
+        parent = H5Gopen(prev_parent, group.c_str(), H5P_DEFAULT);
+
+        if(ii != 0)     H5Gclose(prev_parent);
+        if(parent < 0)  return parent;
+        ++ii; 
+        begin = end + 1;
+        end = group_name.find('/', begin);
+    }
+    return parent; 
+}
+
+inline hid_t createGroup(hid_t parent, std::string group_name)
+{
+    if(group_name.size() == 0 ||*group_name.rbegin() != '/')
+        group_name = group_name + '/';
+    if(group_name == "/")
+        return H5Gopen(parent, group_name.c_str(), H5P_DEFAULT);
+    
+    std::string::size_type begin = 0, end = group_name.find('/');
+    int ii =  0;
+    while (end != std::string::npos)
+    {
+        std::string group(group_name.begin()+begin, group_name.begin()+end);
+        hid_t prev_parent = parent; 
+        
+        if(H5LTfind_dataset(parent, group.c_str()) == 0)
+        {
+            parent = H5Gcreate(prev_parent, group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+        } else {
+            parent = H5Gopen(prev_parent, group.c_str(), H5P_DEFAULT);
+        }
+
+        if(ii != 0)     H5Gclose(prev_parent);
+        if(parent < 0)  return parent;
+        ++ii; 
+        begin = end + 1;
+        end = group_name.find('/', begin);
+    }
+    return parent; 
+}
+
+inline void deleteDataset(hid_t parent, std::string dataset_name)
+{
+    // delete existing data and create new dataset
+    if(H5LTfind_dataset(parent, dataset_name.c_str()))
+    {
+        //std::cout << "dataset already exists" << std::endl;
+#if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
+        if(H5Gunlink(parent, dataset_name.c_str()) < 0)
+        {
+            vigra_postcondition(false, "writeToHDF5File(): Unable to delete existing data.");
+        }
+#else
+        if(H5Ldelete(parent, dataset_name.c_str(), H5P_DEFAULT ) < 0)
+        {
+            vigra_postcondition(false, "createDataset(): Unable to delete existing data.");
+        }
+#endif
+    } 
+}
+
+inline hid_t createFile(std::string filePath, bool append_ = true)
+{
+    FILE * pFile;
+    pFile = fopen ( filePath.c_str(), "r" );
+    hid_t file_id; 
+    if ( pFile == NULL )
+    {
+        file_id = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+    } 
+    else if(append_)
+    {
+        fclose( pFile );
+        file_id = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
+    }
+    else
+    {
+        fclose(pFile);
+        std::remove(filePath.c_str());
+        file_id = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+    }
+    return file_id; 
+}
+
+template<unsigned int N, class T, class Tag>
+void createDataset(const char* filePath, const char* pathInFile, const MultiArrayView<N, T, Tag> & array, const hid_t datatype, const int numBandsOfType, HDF5Handle & file_handle, HDF5Handle & dataset_handle)
+{
+    std::string path_name(pathInFile), group_name, data_set_name, message;
+    std::string::size_type delimiter = path_name.rfind('/');
+    
+    //create or open file
+    file_handle = HDF5Handle(createFile(filePath), &H5Fclose, 
+                       "createDataset(): unable to open output file.");
+
+    // get the groupname and the filename
+    if(delimiter == std::string::npos)
+    {
+        group_name    = "/";
+        data_set_name = path_name;
+    }
+    else
+    {
+        group_name = std::string(path_name.begin(), path_name.begin()+delimiter);
+        data_set_name = std::string(path_name.begin()+delimiter+1, path_name.end());
+    }
+
+    // create all groups
+    HDF5Handle group(createGroup(file_handle, group_name), &H5Gclose, 
+                     "createDataset(): Unable to create and open group. generic v");
+
+    // delete the dataset if it already exists
+    deleteDataset(group, data_set_name);
+
+    // create dataspace
+    // add an extra dimension in case that the data is non-scalar
+    HDF5Handle dataspace_handle;
+    if(numBandsOfType > 1) {
+        // invert dimensions to guarantee c-order
+        hsize_t shape_inv[N+1]; // one additional dimension for pixel type channel(s)
+        for(unsigned int k=0; k<N; ++k) {
+            shape_inv[N-1-k] = array.shape(k);  // the channels (eg of an RGB image) are represented by the first dimension (before inversion)
+            //std::cout << shape_inv[N-k] << " (" << N << ")";
+        }
+        shape_inv[N] = numBandsOfType;
+
+        // create dataspace
+        dataspace_handle = HDF5Handle(H5Screate_simple(N+1, shape_inv, NULL),
+                                    &H5Sclose, "createDataset(): unable to create dataspace for non-scalar data.");
+    } else {
+        // invert dimensions to guarantee c-order
+        hsize_t shape_inv[N];
+        for(unsigned int k=0; k<N; ++k)
+            shape_inv[N-1-k] = array.shape(k);
+
+        // create dataspace
+        dataspace_handle = HDF5Handle(H5Screate_simple(N, shape_inv, NULL),
+                                    &H5Sclose, "createDataset(): unable to create dataspace for scalar data.");
+    }
+
+    //alloc memory for dataset. 
+    dataset_handle = HDF5Handle(H5Dcreate(group, 
+                                        data_set_name.c_str(), 
+                                        datatype, 
+                                        dataspace_handle, 
+                                        H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT),
+                              &H5Dclose, "createDataset(): unable to create dataset.");
+}
+
+
+
+
+/** \brief Store array data in an HDF5 file.
+                
+    The number of dimensions, shape and element type of the stored dataset is automatically 
+    determined from the properties of the given \a array. Strided arrays are stored in an
+    unstrided way, i.e. in contiguous scan-order. Multi-channel element types 
+    (i.e. \ref vigra::RGBValue, \ref vigra::TinyVector and \ref vigra::FFTWComplex)
+    are recognized and handled correctly
+    (in particular, the will form the innermost dimension of the stored dataset).
+    \a pathInFile may contain '/'-separated group names, but must end with the name 
+    of the dataset to be created.
+    
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        template<unsigned int N, class T, class StrideTag>
+        void 
+        writeHDF5(const char* filePath, const char* pathInFile, 
+                  MultiArrayView<N, T, StrideTag>const  & array);
+    }
+    \endcode
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/hdf5impex.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    MultiArrayShape<3>::type shape(100, 200, 20);
+    MultiArray<3, int> array(shape);
+    ... // fill array with data
+    
+    writeHDF5("mydata.h5", "/group1/my_dataset", array);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void writeHDF5)
+
+template<unsigned int N, class T, class StrideTag>
+inline void writeHDF5(const char* filePath, const char* pathInFile, const MultiArrayView<N, T, StrideTag> & array)
+{
+    //last two arguments are not used
+    writeHDF5(filePath, pathInFile, array, 0, 0);
+}
+
+template<unsigned int N, class T, class StrideTag>
+void writeHDF5(const char* filePath, const char* pathInFile, const MultiArrayView<N, T, StrideTag> & array, const hid_t datatype, const int numBandsOfType)
+{
+    HDF5File file(filePath, HDF5File::Open);
+    file.write(pathInFile, array);
+    file.close();
+}
+
+
+namespace detail
+{
+struct MaxSizeFnc
+{
+    size_t size;
+
+    MaxSizeFnc()
+    : size(0)
+    {}
+
+    void operator()(std::string const & in)
+    {
+        size = in.size() > size ? 
+                    in.size() :
+                    size;
+    }
+};
+}
+
+
+#if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 8) || DOXYGEN
+/** Write a numeric MultiArray as an attribute with name \a name 
+    of the dataset specified by the handle \a loc. 
+
+    <b>\#include</b> \<vigra/hdf5impex.hxx\><br>
+    Namespace: vigra
+*/
+template<size_t N, class T, class C>
+void writeHDF5Attr(hid_t loc, 
+                   const char* name, 
+                   MultiArrayView<N, T, C> const & array)
+{
+    if(H5Aexists(loc, name) > 0)
+        H5Adelete(loc, name);
+    
+    ArrayVector<hsize_t> shape(array.shape().begin(), 
+                               array.shape().end());
+    HDF5Handle 
+        dataspace_handle(H5Screate_simple(N, shape.data(), NULL),
+                         &H5Sclose, 
+                         "writeToHDF5File(): unable to create dataspace.");
+    
+    HDF5Handle attr(H5Acreate(loc, 
+                              name, 
+                              detail::getH5DataType<T>(), 
+                              dataspace_handle,
+                              H5P_DEFAULT ,H5P_DEFAULT ),
+                    &H5Aclose,
+                    "writeHDF5Attr: unable to create Attribute");
+
+    //copy data - since attributes are small - who cares!
+    ArrayVector<T> buffer;
+    for(int ii = 0; ii < array.size(); ++ii)
+        buffer.push_back(array[ii]);
+    H5Awrite(attr, detail::getH5DataType<T>(), buffer.data());
+}
+
+/** Write a string MultiArray as an attribute with name \a name 
+    of the dataset specified by the handle \a loc. 
+
+    <b>\#include</b> \<vigra/hdf5impex.hxx\><br>
+    Namespace: vigra
+*/
+template<size_t N, class C>
+void writeHDF5Attr(hid_t loc, 
+                   const char* name, 
+                   MultiArrayView<N, std::string, C> const & array)
+{
+    if(H5Aexists(loc, name) > 0)
+        H5Adelete(loc, name);
+    
+    ArrayVector<hsize_t> shape(array.shape().begin(), 
+                               array.shape().end());
+    HDF5Handle 
+        dataspace_handle(H5Screate_simple(N, shape.data(), NULL),
+                         &H5Sclose, 
+                         "writeToHDF5File(): unable to create dataspace.");
+    
+    HDF5Handle atype(H5Tcopy (H5T_C_S1), 
+                     &H5Tclose, 
+                     "writeToHDF5File(): unable to create type.");
+
+    detail::MaxSizeFnc max_size;
+    max_size = std::for_each(array.data(),array.data()+ array.size(), max_size);
+    H5Tset_size (atype, max_size.size);
+    
+    HDF5Handle attr(H5Acreate(loc, 
+                              name, 
+                              atype, 
+                              dataspace_handle,
+                              H5P_DEFAULT ,H5P_DEFAULT ),
+                    &H5Aclose,
+                    "writeHDF5Attr: unable to create Attribute");
+    
+    std::string buf ="";
+    for(int ii = 0; ii < array.size(); ++ii)
+    {
+        buf = buf + array[ii]
+                  + std::string(max_size.size - array[ii].size(), ' ');
+    }
+    H5Awrite(attr, atype, buf.c_str());
+}
+
+/** Write a numeric ArrayVectorView as an attribute with name \a name 
+    of the dataset specified by the handle \a loc. 
+
+    <b>\#include</b> \<vigra/hdf5impex.hxx\><br>
+    Namespace: vigra
+*/
+template<class T>
+inline void writeHDF5Attr(  hid_t loc,
+                            const char* name,
+                            ArrayVectorView<T>  & array)
+{
+    writeHDF5Attr(loc, name, 
+                  MultiArrayView<1, T>(MultiArrayShape<1>::type(array.size()),
+                                       array.data()));
+}
+
+/** write an Attribute given a file and a path in the file.
+    the path in the file should have the format 
+    [attribute] or /[subgroups/]dataset.attribute or
+    /[subgroups/]group.attribute.
+    The attribute is written to the root group, a dataset or a subgroup
+    respectively
+*/
+template<class Arr>
+inline void writeHDF5Attr(  std::string filePath,
+                            std::string pathInFile,
+                            Arr  & ar)
+{
+    std::string path_name(pathInFile), group_name, data_set_name, message, attr_name;
+    std::string::size_type delimiter = path_name.rfind('/');
+    
+    //create or open file
+    HDF5Handle file_id(createFile(filePath), &H5Fclose, 
+                       "writeToHDF5File(): unable to open output file.");
+
+    // get the groupname and the filename
+    if(delimiter == std::string::npos)
+    {
+        group_name    = "/";
+        data_set_name = path_name;
+    }
+
+    else
+    {
+        group_name = std::string(path_name.begin(), path_name.begin()+delimiter);
+        data_set_name = std::string(path_name.begin()+delimiter+1, path_name.end());
+    }
+    delimiter = data_set_name.rfind('.');
+    if(delimiter == std::string::npos)
+    {
+        attr_name = path_name;
+        data_set_name = "/";
+    }
+    else
+    {
+        attr_name = std::string(data_set_name.begin()+delimiter+1, data_set_name.end());
+        data_set_name = std::string(data_set_name.begin(), data_set_name.begin()+delimiter);
+    }
+    
+    HDF5Handle group(openGroup(file_id, group_name), &H5Gclose, 
+                     "writeToHDF5File(): Unable to create and open group. attr ver");
+
+    if(data_set_name != "/")
+    {
+        HDF5Handle dset(H5Dopen(group, data_set_name.c_str(), H5P_DEFAULT), &H5Dclose,
+                        "writeHDF5Attr():unable to open dataset");
+        writeHDF5Attr(hid_t(dset), attr_name.c_str(), ar);
+    }
+    else
+    {
+        writeHDF5Attr(hid_t(group), attr_name.c_str(), ar);
+    }
+
+}
+#endif
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_HDF5IMPEX_HXX
diff --git a/include/vigra/histogram.hxx b/include/vigra/histogram.hxx
new file mode 100644
index 0000000..3ec602a
--- /dev/null
+++ b/include/vigra/histogram.hxx
@@ -0,0 +1,368 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2011-2012 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_HISTOGRAM_HXX
+#define VIGRA_HISTOGRAM_HXX
+
+#include "config.hxx"
+#include "array_vector.hxx"
+#include <algorithm>
+
+namespace vigra {
+
+/** \brief Set histogram options.
+
+    HistogramOptions objects are used to pass histogram options to other objects. This \ref acc_hist_options "example" shows how it is is used to pass histogram options to an accumulator chain.
+*/
+class HistogramOptions
+{
+  public:
+
+    /** \brief Lower bound for linear range mapping from values to indices. */
+    double minimum;
+
+    /** \brief Upper bound for linear range mapping from values to indices. */
+    double maximum;
+
+    /** \brief Total number of bins in the histogram. */
+    int binCount;
+
+    /** \brief If true, range mapping bounds are defined by minimum and maximum of the data. */
+    bool local_auto_init;
+    
+    /** Initialize members with default values:
+
+	- minimum, maximum = 0.0
+	- binCount = 64
+	- local_auto_init = false
+    */
+    HistogramOptions()
+    : minimum(0.0), maximum(0.0),
+      binCount(64),
+      local_auto_init(false)
+    {}
+    
+    /** Set minimum = mi and maximum = ma. Requirement: mi < ma.
+    */
+    HistogramOptions & setMinMax(double mi, double ma)
+    {
+        vigra_precondition(mi < ma,
+            "HistogramOptions::setMinMax(): min < max required.");
+        minimum = mi;
+        maximum = ma;
+        return *this;
+    }
+
+    /** Set binCount = c. Requirement: c > 0.
+    */
+    HistogramOptions & setBinCount(int c)
+    {
+        vigra_precondition(c > 0,
+            "HistogramOptions::setBinCount(): binCount > 0 required.");
+        binCount = c;
+        return *this;
+    }
+
+    /** Set local_auto_init = true. Requirement: setMinMax() must not have been called before. */
+    HistogramOptions & regionAutoInit()
+    {
+        vigra_precondition(!validMinMax(),
+            "HistogramOptions::regionAutoInit(): you must not call setMinMax() when auto initialization is desired.");
+        local_auto_init = true;
+        return *this;
+    }
+
+    /** Set local_auto_init = false. Requirement: setMinMax() must not have been called before. */
+    HistogramOptions & globalAutoInit()
+    {
+        vigra_precondition(!validMinMax(),
+            "HistogramOptions::globalAutoInit(): you must not call setMinMax() when auto initialization is desired.");
+        local_auto_init = false;
+        return *this;
+    }
+    
+    /** Return minimum < maximum.
+    */
+    bool validMinMax() const
+    {
+        return minimum < maximum;
+    }
+};
+
+template <class DataType, class BinType>
+class HistogramView
+{
+    BinType * bins_;
+    int size_, stride_;
+    DataType offset_;
+    double scale_, scaleInverse_;
+    
+  public:
+    HistogramView(DataType const & min, DataType const & max, int binCount, 
+                  BinType * bins = 0, int stride = 1)
+    : bins_(bins),
+      size_(binCount),
+      stride_(stride),
+      offset_(min),
+      scale_(double(binCount) / (max - min)),
+      scaleInverse_(1.0 / scale_)
+    {}
+    
+    HistogramView & setData(BinType * bins , int stride = 1)
+    {
+        bins_ = bins;
+        stride_ = stride;
+        return *this;
+    }
+    
+    HistogramView & reset()
+    {
+        if(hasData())
+            for(int k=0; k<size_; ++k)
+                *(bins_ +k*stride_) = BinType();
+        return *this;
+    }
+    
+    void getBinCenters(ArrayVector<DataType> * centers) const
+    {
+        double invScale = 1.0 / scale_;
+        for(int k=0; k < size_; ++k)
+        {
+            (*centers)[k] = mapItemInverse(k + 0.5) ;
+        }
+    }
+    
+    int size() const
+    {
+        return size_;
+    }
+    
+    bool hasData() const
+    {
+        return bins_ != 0;
+    }
+    
+    BinType const & operator[](int k) const
+    {
+        return *(bins_ + k*stride_);
+    }
+
+	double mapItem(DataType const & d) const
+	{
+		return scale_ * (d - offset_);
+	}
+    
+	DataType mapItemInverse(double d) const
+	{
+		return DataType(d * scaleInverse_ + offset_);
+	}
+    
+    void add(DataType const & d, BinType weight = NumericTraits<BinType>::one())
+    {
+        get(int(mapItem(d))) += weight;
+    }
+
+  protected:
+
+	BinType & get(int index)
+	{
+        if(index < 0)
+            index = 0;
+        if(index >= size_)
+            index = size_ - 1;
+		return *(bins_ + index*stride_);
+	}
+};
+
+template <class T>
+class TrapezoidKernel
+{
+  public:
+    typedef T value_type;
+    
+    T operator[](double f) const
+    {
+        if(f < -0.5)
+            return 0.5*(f + 1.5);
+        if(f > 0.5)
+            return 0.5*(1.5 - f);
+        return 0.5;
+    }
+    
+    double radius() const
+    {
+        return 1.5;
+    }
+    
+    T findMaximum(double l, double c, double r) const
+    {
+        double curv = -2.0*c + r + l;
+        if(curv == 0.0)
+            return T(-0.5);
+        double extr = 0.5*(l-r) / curv;
+        if(curv < 0.0)
+        {
+            return extr < -0.5
+                       ? T(-0.5)
+                       : extr > 0.5
+                              ? T(0.5)
+                              : T(extr);
+        }
+        else
+        {
+            return extr < 0.0
+                       ? T(0.5)
+                       : T(-0.5);
+        }
+    }
+    
+    bool findMode(double l, double c, double r, double * m) const
+    {
+        double curv = -2.0*c + r + l;
+        if(curv >= 0.0)
+            return false;
+        *m = 0.5*(l-r) / curv;
+        if(*m < -0.5 || *m > 0.5)
+            return false;
+        return true;
+    }
+};
+
+template <class DataType, class KernelType>
+class KernelHistogramView
+: public HistogramView<DataType, typename KernelType::value_type>
+{
+    KernelType kernel_;
+    int radius_;
+    
+  public:
+  
+    typedef typename KernelType::value_type BinType;
+    typedef HistogramView<DataType, BinType> BaseType;
+
+    KernelHistogramView(DataType const & min, DataType const & max, int binCount, 
+                        BinType * bins = 0, int stride = 1)
+    : BaseType(min, max, binCount, bins, stride),
+      radius_(kernel_.radius()-0.5) // FIXME: this needs generalization
+    {}
+    
+    void add(DataType const & d, BinType weight = NumericTraits<BinType>::one())
+    {
+        double mapped = this->mapItem(d);
+        double f = mapped - std::floor(mapped) - kernel_.radius();
+        int center = int(mapped);
+        
+        for(int k=center+radius_; k>=center-radius_; --k, f += 1.0)
+        {   
+            this->get(k) += weight*kernel_[f];
+		}
+    }
+    
+    DataType findMode() const
+    {
+        double mmax = 0, vmax = 0, m;
+        
+        for(int k=0; k<this->size(); ++k)
+        {
+            double l = k > 0
+                         ? (*this)[k-1]
+                         : 0.0;
+            double c = (*this)[k];
+            double r = k < this->size() - 1
+                         ? (*this)[k+1]
+                         : 0.0;
+            if(kernel_.findMode(l, c, r, &m))
+            {
+                double v = l*kernel_[m+1.0] + c*kernel_[m] + r*kernel_[m-1.0];
+                if(vmax < v)
+                {
+                    mmax = m + k + 0.5;
+                    vmax = v;
+                }
+            }
+        }
+        return this->mapItemInverse(mmax);
+    }
+    
+    template <class Array>
+    void findModes(Array * modes)
+    {
+        double m;
+        for(int k=0; k<this->size(); ++k)
+        {
+            double l = k > 0
+                         ? (*this)[k-1]
+                         : 0.0;
+            double c = (*this)[k];
+            double r = k < this->size() - 1
+                         ? (*this)[k+1]
+                         : 0.0;
+            if(kernel_.findMode(l, c, r, &m))
+            {
+                double v = l*kernel_[m+1.0] + c*kernel_[m] + r*kernel_[m-1.0];
+                modes->push_back(std::make_pair(this->mapItemInverse(m + k + 0.5), v));
+            }
+        }
+    }
+};
+
+template <class DataType, class BinType>
+class Histogram
+: public HistogramView<DataType, BinType>
+{
+  public:
+    typedef HistogramView<DataType, BinType> BaseType;
+    ArrayVector<BinType> data_;
+    
+  public:
+    Histogram(DataType const & min, DataType const & max, int binCount, 
+                  BinType * bins = 0, int stride = 1)
+    : BaseType(min, max, binCount),
+      data_(binCount)
+    {
+        this->setData(&data_[0]);
+    }
+    
+    Histogram const & reset()
+    {
+        this->setData(&data_[0]);
+        BaseType::reset();
+        return *this;
+    }
+ };
+
+} // namespace vigra
+
+#endif // VIGRA_HISTOGRAM_HXX
diff --git a/include/vigra/imagecontainer.hxx b/include/vigra/imagecontainer.hxx
new file mode 100644
index 0000000..c7386d6
--- /dev/null
+++ b/include/vigra/imagecontainer.hxx
@@ -0,0 +1,775 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMAGECONTAINER_HXX
+#define VIGRA_IMAGECONTAINER_HXX
+
+#include "utilities.hxx"
+#include "array_vector.hxx"
+#include "copyimage.hxx"
+
+namespace vigra {
+
+/** \addtogroup ImageContainers Image Containers
+    Classes to manage multiple images (ImageArray..)
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                      ImageArray                      */
+/*                                                      */
+/********************************************************/
+
+/** \brief Fundamental class template for arrays of equal-sized images.
+
+    An ImageArray manages an array of images of the type given as
+    template parameter. Use it like a ArrayVector<ImageType>, it has
+    the same interface, only operator< is missing from ImageArray. It
+    offers additional functions for resizing the images and querying
+    their common size. See \ref imageSize() for additional notes.
+
+    A customized allocator can be passed as a template argument and via the constructor.
+    By default, the allocator of the <tt>ImageType</tt> is reused.
+
+    <b>\#include</b> \<vigra/imagecontainer.hxx\> <br/>
+    Namespace: vigra
+*/
+template <class ImageType,
+      class Alloc = typename ImageType::allocator_type::template rebind<ImageType>::other >
+class ImageArray
+{
+    Size2D imageSize_;
+
+protected:
+    typedef ArrayVector<ImageType, Alloc> ImageVector;
+    ImageVector images_;
+
+public:
+        /** the type of the contained values/images
+         */
+    typedef ImageType    value_type;
+
+    typedef typename ImageVector::iterator iterator;
+    typedef typename ImageVector::const_iterator const_iterator;
+    typedef typename ImageVector::reverse_iterator reverse_iterator;
+    typedef typename ImageVector::const_reverse_iterator const_reverse_iterator;
+    typedef typename ImageVector::reference reference;
+    typedef typename ImageVector::const_reference const_reference;
+#if !defined(_MSC_VER) || _MSC_VER >= 1300
+    typedef typename ImageVector::pointer pointer;
+#endif
+    typedef typename ImageVector::difference_type difference_type;
+    typedef typename ImageVector::size_type size_type;
+
+        /** init an array of numImages equal-sized images; use the specified allocator.
+         */
+    ImageArray(unsigned int numImages, const Diff2D &imageSize,
+               Alloc const & alloc = Alloc())
+        : imageSize_(imageSize),
+          images_(numImages, ImageType(), alloc)
+    {
+        for(unsigned int i=0; i<numImages; i++)
+            images_[i].resize(Size2D(imageSize));
+    }
+
+        /** Init an array of numImages equal-sized images. The size
+            depends on ImageType's default constructor (so it will
+            usually be 0x0); use the specified allocator.
+         */
+    ImageArray(unsigned int numImages= 0, Alloc const & alloc = Alloc())
+        : images_(numImages, alloc)
+    {
+        imageSize_= empty()? Size2D(0, 0) : front().size();
+    }
+
+        /** fill constructor: Init an array with numImages copies of
+            the given image. (STL-Sequence interface); use the specified allocator.
+         */
+    ImageArray(unsigned int numImages, const ImageType &image, Alloc const & alloc = Alloc())
+        : imageSize_(image.size()),
+          images_(numImages, image, alloc)
+    {
+    }
+
+        /** range constructor: Construct an array containing copies of
+            the images in [begin, end). Those images must all have the
+            same size, see \ref imageSize(). (STL-Sequence interface);
+            use the specified allocator.
+         */
+    template<class InputIterator>
+    ImageArray(InputIterator begin, InputIterator end, Alloc const & alloc = Alloc())
+        : imageSize_(begin!=end? (*begin).size() : Size2D(0,0)),
+          images_(begin, end, alloc)
+    {
+    }
+
+    virtual ~ImageArray() {}
+
+        /** Operator for a vector-like access to the contained images
+            (STL-Vector interface)
+         */
+    reference operator [](size_type index)
+    {
+        return images_[index];
+    }
+
+        /** Operator for a vector-like access to the contained images
+            (STL-Vector interface)
+         */
+    const_reference operator [](size_type index) const
+    {
+        return images_[index];
+    }
+
+        /** Returns an iterator pointing to the first image
+            (STL-Container interface)
+         */
+    iterator begin()
+    {
+        return images_.begin();
+    }
+
+        /** Returns an iterator pointing to the first image
+            (STL-Container interface)
+         */
+    const_iterator begin() const
+    {
+        return images_.begin();
+    }
+
+        /** Returns an iterator pointing behind the last image
+            (STL-Container interface)
+         */
+    iterator end()
+    {
+        return images_.end();
+    }
+
+        /** Returns an iterator pointing behind the last image
+            (STL-Container interface)
+         */
+    const_iterator end() const
+    {
+        return images_.end();
+    }
+
+        /** Returns a reverse_iterator pointing to the first image of
+            the reversed view of this array (STL-Reversable Container
+            interface)
+         */
+    reverse_iterator rbegin()
+    {
+        return images_.rbegin();
+    }
+
+        /** Returns a reverse_iterator pointing to the first image of
+            the reversed view of this array (STL-Reversable Container
+            interface)
+         */
+    const_reverse_iterator rbegin() const
+    {
+        return images_.rbegin();
+    }
+
+        /** Returns a reverse_iterator pointing behind the last image
+            of the reversed view of this array (STL-Reversable
+            Container interface)
+         */
+    reverse_iterator rend()
+    {
+        return images_.rend();
+    }
+
+        /** Returns a reverse_iterator pointing behind the last image
+            of the reversed view of this array (STL-Reversable
+            Container interface)
+         */
+    const_reverse_iterator rend() const
+    {
+        return images_.rend();
+    }
+
+        /** Query size of this ImageArray, that is: the number of
+            images. (STL-Container interface)
+        */
+    size_type size() const
+    {
+        return images_.size();
+    }
+
+        /** Query maximum size of this ImageArray, that is: the
+            max. parameter you may pass to resize(). (STL-Container
+            interface)
+        */
+    size_type max_size() const
+    {
+        return images_.max_size();
+    }
+
+        /** Returns true if and only if there are no contained
+            images. (STL-Container interface)
+        */
+    bool empty()
+    {
+        return images_.empty();
+    }
+
+        /** Returns true if and only if both ImageArrays have exactly
+            the same contents and all images did compare equal with the
+            corresponding image in the other ImageArray. (STL-Forward
+            Container interface)
+         */
+    bool operator ==(const ImageArray<ImageType, Alloc> &other)
+    {
+        return (imageSize() == other.imageSize())
+                && (images_ == other.images_);
+    }
+
+        /** Insert image at/before pos. (STL-Sequence interface)
+         */
+    iterator insert(iterator pos, const_reference image)
+    {
+        return images_.insert(pos, image);
+    }
+
+        /** Insert count copies of image at/before pos. (STL-Sequence
+            interface)
+         */
+    void insert (iterator pos, size_type count, const_reference image);
+
+        /** Insert copies of images from [begin, end) at/before
+            pos. (STL-Sequence interface)
+         */
+    template<class InputIterator>
+    void insert(iterator pos, InputIterator begin, InputIterator end)
+    {
+        images_.insert(pos, begin, end);
+    }
+
+        /** Removes the image at pos from this array. (STL-Sequence
+            interface)
+         */
+    iterator erase(iterator pos)
+    {
+        return images_.erase(pos);
+    }
+
+        /** Removes the images from [begin, end) from this
+            array. (STL-Sequence interface)
+         */
+    iterator erase(iterator begin, iterator end)
+    {
+        return images_.erase(begin, end);
+    }
+
+        /** Empty this array. (STL-Sequence interface)
+         */
+    void clear()
+    {
+        images_.clear();
+    }
+
+        /** Resize this ImageArray, throwing the last images away if
+            you make the array smaller or appending new images of the
+            right size at the end of the array if you make it
+            larger. (STL-Sequence interface)
+        */
+    void resize(size_type newSize)
+    {
+        if (newSize != size())
+        {
+            size_type oldSize= size();
+            images_.resize(newSize);
+            for (size_type i= oldSize; i<newSize; i++)
+                images_[i].resize(imageSize());
+        }
+    }
+
+        /** Resize this ImageArray, throwing the last images away if
+            you make the array smaller or appending new copies of image
+            at the end of the array if you make it larger.
+            precondition: <tt>image.size() == imageSize()</tt>
+            (STL-Sequence interface)
+        */
+    void resize(size_type newSize, ImageType &image)
+    {
+        if (newSize != size())
+        {
+            vigra_precondition(image.size() == imageSize(),
+                               "trying to append images of wrong size to ImageArray with resize()");
+            images_.resize(newSize, image);
+        }
+    }
+
+        /** return the first image. (STL-Sequence interface)
+         */
+    reference front()
+    {
+        return images_.front();
+    }
+
+        /** return the first image. (STL-Sequence interface)
+         */
+    const_reference front() const
+    {
+        return images_.front();
+    }
+
+        /** return the last image. (STL-Vector interface)
+         */
+    reference back()
+    {
+        return images_.back();
+    }
+
+        /** return the last image. (STL-Vector interface)
+         */
+    const_reference back() const
+    {
+        return images_.back();
+    }
+
+        /** append image to array (STL-Back Insertion Sequence interface)
+         */
+    void push_back(const_reference image)
+    {
+        images_.push_back(image);
+    }
+
+        /** remove last image from array (STL-Back Insertion Sequence interface)
+         */
+    void pop_back()
+    {
+        images_.pop_back();
+    }
+
+        /** swap contents of this array with the contents of other
+            (STL-Container interface)
+         */
+    void swap(const_reference other)
+    {
+        Size2D oldImageSize = imageSize_;
+        images_.swap(other.images_);
+        imageSize_ = other.imageSize_;
+        other.imageSize_ = oldImageSize;
+    }
+
+        /** number of image objects for which memory has been allocated
+            (STL-Vector interface)
+        */
+    size_type capacity() const
+    {
+        return images_.capacity();
+    }
+
+        /** increase capacity(). (STL-Vector interface)
+         */
+    void reserve(size_type n)
+    {
+        images_.reserve(n);
+    }
+
+        /** Query the size of the contained images. ImageArray will
+            maintain an array of equal-sized images of this
+            size. However, <em>do not resize the contained images
+            manually</em>. ImageArray currently has no way to detect or
+            prevent this.
+         */
+    Size2D imageSize() const
+        { return imageSize_; }
+
+        /** Resize all images to a common new size (No-op if
+            <tt>newSize == imageSize()</tt>). See \ref imageSize() for
+            an important note about resizing the images.
+        */
+    virtual void resizeImages(const Diff2D &newSize)
+    {
+        if (newSize!=imageSize())
+        {
+            for(unsigned int i=0; i<size(); i++)
+                images_[i].resize(Size2D(newSize));
+            imageSize_= newSize;
+        }
+    }
+
+        /** Resize all images to a common new size (No-op if
+            <tt>newSize == imageSize()</tt>). See \ref imageSize() for
+            an important note about resizing the images.
+
+            (Convenience function, same as calling
+            <tt>resizeImages(Diff2D(width, height));</tt>.)
+        */
+    void resizeImages(int width, int height)
+    {
+        resizeImages(Size2D(width, height));
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                      ImagePyramid                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Class template for logarithmically tapering image pyramids.
+
+    An ImagePyramid manages an array of images of the type given as
+    template parameter, where each level has half the width and height
+    of its predecessor.  It actually represents a sequence of pyramid
+    levels whose start and end index are configurable.  For Burt-style
+    pyramids, see also \ref pyramidReduceBurtFilter and \ref
+    pyramidExpandBurtFilter.
+
+    A customized allocator can be passed as a template argument and
+    via the constructor.  By default, the allocator of the
+    <tt>ImageType</tt> is reused.
+
+    <b>\#include</b> \<vigra/imagecontainer.hxx\> <br/>
+    Namespace: vigra
+*/
+template <class ImageType,
+      class Alloc = typename ImageType::allocator_type::template rebind<ImageType>::other >
+class ImagePyramid
+{
+    int lowestLevel_, highestLevel_;
+
+protected:
+    typedef ArrayVector<ImageType, Alloc> ImageVector;
+    ImageVector images_;
+
+public:
+        /** the type of the contained values/images
+         */
+    typedef ImageType    value_type;
+
+    typedef typename ImageVector::iterator iterator;
+    typedef typename ImageVector::const_iterator const_iterator;
+    typedef typename ImageVector::reverse_iterator reverse_iterator;
+    typedef typename ImageVector::const_reverse_iterator const_reverse_iterator;
+    typedef typename ImageVector::reference reference;
+    typedef typename ImageVector::const_reference const_reference;
+#if !defined(_MSC_VER) || _MSC_VER >= 1300
+    typedef typename ImageVector::pointer pointer;
+#endif
+    typedef typename ImageVector::difference_type difference_type;
+    typedef int size_type;
+
+        /** Init a pyramid between the given levels (inclusive).
+         *
+         * Allocate the given \a imageSize at the pyramid level given
+         * in \a sizeAppliesToLevel (default: level 0 / bottom) and
+         * size the other levels using recursive reduction/expansion
+         * by factors of 2.  Use the specified allocator for image
+         * creation.  The image type must be default constructible and
+         * resizable.  sizeAppliesToLevel must be the in range
+         * lowestLevel..highestLevel (inclusive).
+         */
+    ImagePyramid(int lowestLevel, int highestLevel,
+                 const Diff2D &imageSize, int sizeAppliesToLevel = 0,
+                 Alloc const & alloc = Alloc())
+        : lowestLevel_(0), highestLevel_(-1),
+          images_(alloc)
+    {
+        resize(lowestLevel, highestLevel, imageSize, sizeAppliesToLevel);
+    }
+
+        /**
+         * Init a pyramid between the given levels (inclusive).
+         *
+         * Copy the given \a image into the pyramid level given in \a
+         * copyImageToLevel (default: level 0 / bottom) and size the
+         * other levels using recursive reduction/expansion by factors
+         * of 2 (their image data is not initialized).  Use the
+         * specified allocator for image creation.  The image type
+         * must be default constructible and resizable.
+         * sizeAppliesToLevel must be the in range
+         * lowestLevel..highestLevel (inclusive).
+         */
+    ImagePyramid(int lowestLevel, int highestLevel,
+                 const ImageType &image, int copyImageToLevel = 0,
+                 Alloc const & alloc = Alloc())
+        : lowestLevel_(0), highestLevel_(-1),
+          images_(alloc)
+    {
+        resize(lowestLevel, highestLevel, image.size(), copyImageToLevel);
+        copyImage(srcImageRange(image), destImage((*this)[copyImageToLevel]));
+    }
+
+        /**
+         * Init a pyramid between the given levels (inclusive).
+         *
+         * Copy the image given by the range \a ul to \a lr into the
+         * pyramid level given in \a copyImageToLevel (default: level
+         * 0 / bottom) and size the other levels using recursive
+         * reduction/expansion by factors of 2 (their image data is
+         * not initialized).  Use the specified allocator for image
+         * creation.  The image type must be default constructible and
+         * resizable.  sizeAppliesToLevel must be the in range
+         * lowestLevel..highestLevel (inclusive).
+         */
+    template <class SrcIterator, class SrcAccessor>
+    ImagePyramid(int lowestLevel, int highestLevel,
+                 SrcIterator ul, SrcIterator lr, SrcAccessor src,
+                 int copyImageToLevel = 0,
+                 Alloc const & alloc = Alloc())
+        : lowestLevel_(0), highestLevel_(-1),
+          images_(alloc)
+    {
+        resize(lowestLevel, highestLevel, lr - ul, copyImageToLevel);
+        copyImage(srcIterRange(ul, lr, src), destImage((*this)[copyImageToLevel]));
+    }
+
+        /** Init an empty pyramid.  Use the specified allocator.
+         */
+    ImagePyramid(Alloc const & alloc = Alloc())
+        : lowestLevel_(0), highestLevel_(-1),
+          images_(alloc)
+    {}
+
+    virtual ~ImagePyramid() {}
+
+        /** Get the index of the lowest allocated level of the pyramid.
+        */
+    int lowestLevel() const
+    {
+        return lowestLevel_;
+    }
+
+        /** Get the index of the highest allocated level of the pyramid.
+        */
+    int highestLevel() const
+    {
+        return highestLevel_;
+    }
+
+        /** Operator for a vector-like access to the contained images
+            (STL-Vector interface)
+         */
+    reference operator [](size_type index)
+    {
+        return images_[index - lowestLevel_];
+    }
+
+        /** Operator for a vector-like access to the contained images
+            (STL-Vector interface)
+         */
+    const_reference operator [](size_type index) const
+    {
+        return images_[index - lowestLevel_];
+    }
+
+        /** Returns an iterator pointing to the first image
+            (STL-Container interface)
+         */
+    iterator begin()
+    {
+        return images_.begin();
+    }
+
+        /** Returns an iterator pointing to the first image
+            (STL-Container interface)
+         */
+    const_iterator begin() const
+    {
+        return images_.begin();
+    }
+
+        /** Returns an iterator pointing behind the last image
+            (STL-Container interface)
+         */
+    iterator end()
+    {
+        return images_.end();
+    }
+
+        /** Returns an iterator pointing behind the last image
+            (STL-Container interface)
+         */
+    const_iterator end() const
+    {
+        return images_.end();
+    }
+
+        /** Returns a reverse_iterator pointing to the first image of
+            the reversed view of this array (STL-Reversable Container
+            interface)
+         */
+    reverse_iterator rbegin()
+    {
+        return images_.rbegin();
+    }
+
+        /** Returns a reverse_iterator pointing to the first image of
+            the reversed view of this array (STL-Reversable Container
+            interface)
+         */
+    const_reverse_iterator rbegin() const
+    {
+        return images_.rbegin();
+    }
+
+        /** Returns a reverse_iterator pointing behind the last image
+            of the reversed view of this array (STL-Reversable
+            Container interface)
+         */
+    reverse_iterator rend()
+    {
+        return images_.rend();
+    }
+
+        /** Returns a reverse_iterator pointing behind the last image
+            of the reversed view of this array (STL-Reversable
+            Container interface)
+         */
+    const_reverse_iterator rend() const
+    {
+        return images_.rend();
+    }
+
+        /** Query size of this ImageArray, that is: the number of
+            images. (STL-Container interface)
+        */
+    size_type size() const
+    {
+        return images_.size();
+    }
+
+        /** Returns true if and only if there are no contained
+            images. (STL-Container interface)
+        */
+    bool empty()
+    {
+        return images_.empty();
+    }
+
+        /** Returns true if and only if both ImageArrays have exactly
+            the same contents and all images did compare equal with the
+            corresponding image in the other ImageArray. (STL-Forward
+            Container interface)
+         */
+    bool operator ==(const ImagePyramid<ImageType, Alloc> &other) const
+    {
+        return (lowestLevel_ == other.lowestLevel_) && (highestLevel_ == other.highestLevel_) &&
+                (images_ == other.images_);
+    }
+
+        /** Empty this array. (STL-Sequence interface)
+         */
+    void clear()
+    {
+        images_.clear();
+        lowestLevel_ = 0;
+        highestLevel_ = -1;
+    }
+
+        /** Resize this ImageArray, throwing the last images away if
+            you make the array smaller or appending new images of the
+            right size at the end of the array if you make it
+            larger. (STL-Sequence interface)
+        */
+    void resize(int lowestLevel, int highestLevel,
+                const Diff2D &imageSize, int sizeAppliesToLevel = 0)
+    {
+        vigra_precondition(lowestLevel <= highestLevel,
+           "ImagePyramid::resize(): lowestLevel <= highestLevel required.");
+        vigra_precondition(lowestLevel <= sizeAppliesToLevel && sizeAppliesToLevel <= highestLevel,
+           "ImagePyramid::resize(): sizeAppliesToLevel must be between lowest and highest level (inclusive).");
+
+        ImageVector images(highestLevel - lowestLevel + 1, ImageType());
+
+        images[sizeAppliesToLevel - lowestLevel].resize(imageSize);
+        for(int i=sizeAppliesToLevel + 1; i<=highestLevel; ++i)
+        {
+            unsigned int w = (images[i - 1 - lowestLevel].width() + 1) / 2;
+            unsigned int h = (images[i - 1 - lowestLevel].height() + 1) / 2;
+            images[i - lowestLevel].resize(w, h);
+        }
+        for(int i=sizeAppliesToLevel - 1; i>=lowestLevel; --i)
+        {
+            unsigned int w = 2*images[i + 1 - lowestLevel].width() - 1;
+            unsigned int h = 2*images[i + 1 - lowestLevel].height() - 1;
+            images[i - lowestLevel].resize(w, h);
+        }
+
+        images_.swap(images);
+        lowestLevel_ = lowestLevel;
+        highestLevel_ = highestLevel;
+    }
+
+        /** return the first image (lowestLevel()). (STL-Sequence interface)
+         */
+    reference front()
+    {
+        return images_.front();
+    }
+
+        /** return the first image (lowestLevel()). (STL-Sequence interface)
+         */
+    const_reference front() const
+    {
+        return images_.front();
+    }
+
+        /** return the last image (highestLevel()). (STL-Vector interface)
+         */
+    reference back()
+    {
+        return images_.back();
+    }
+
+        /** return the last image (highestLevel()). (STL-Vector interface)
+         */
+    const_reference back() const
+    {
+        return images_.back();
+    }
+
+        /** swap contents of this array with the contents of other
+            (STL-Container interface)
+         */
+    void swap(const ImagePyramid<ImageType, Alloc> &other)
+    {
+        images_.swap(other.images_);
+        std::swap(lowestLevel_, other.lowestLevel_);
+        std::swap(highestLevel_, other.highestLevel_);
+    }
+};
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_IMAGECONTAINER_HXX
diff --git a/include/vigra/imageinfo.hxx b/include/vigra/imageinfo.hxx
new file mode 100644
index 0000000..1c49525
--- /dev/null
+++ b/include/vigra/imageinfo.hxx
@@ -0,0 +1,568 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2001 by Ullrich Koethe                  */
+/*               Copyright 2001-2002 by Gunnar Kedenburg                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/* Modifications by Pablo d'Angelo
+ * updated to vigra 1.4 by Douglas Wilkins
+ * as of 18 February 2006:
+ *  - Added UINT16 and UINT32 pixel types.
+ *  - Added support for obtaining extra bands beyond RGB.
+ *  - Added support for a position field that indicates the start of this
+ *    image relative to some global origin.
+ *  - Added support for x and y resolution fields.
+ *  - Added support for ICC profiles
+ */
+
+#ifndef VIGRA_IMAGEINFO_HXX
+#define VIGRA_IMAGEINFO_HXX
+
+#include <memory>
+#include <string>
+#include "config.hxx"
+#include "error.hxx"
+#include "diff2d.hxx"
+#include "codec.hxx"
+#include "array_vector.hxx"
+#include "multi_iterator.hxx"
+
+namespace vigra
+{
+/** \addtogroup VigraImpex Image Import/Export Facilities
+
+    supports GIF, TIFF, JPEG, BMP, EXR, HDR, PNM (PBM, PGM, PPM), PNG, SunRaster, KHOROS-VIFF formats
+**/
+//@{
+
+    /** \brief List the image formats VIGRA can read and write.
+
+        This is useful for creating error messages if VIGRA encounters an
+        image format it doesn't recognize.
+
+        <b> Usage:</b>
+
+        <b>\#include</b> \<vigra/imageinfo.hxx\><br>
+        Namespace: vigra
+
+        \code
+        std::cout << "supported formats: " << vigra::impexListFormats() << std::endl;
+        \endcode
+
+    **/
+VIGRA_EXPORT std::string impexListFormats();
+
+    /** \brief List the file extension VIGRA understands.
+
+        This is useful for creating file dialogs that only list image files
+        VIGRA can actually import.
+
+        <b> Usage:</b>
+
+        <b>\#include</b> \<vigra/imageinfo.hxx\><br>
+        Namespace: vigra
+
+        \code
+        std::cout << "supported extensions: " << vigra::impexListExtensions() << std::endl;
+        \endcode
+
+    **/
+VIGRA_EXPORT std::string impexListExtensions();
+
+/** \brief Test whether a file is an image format known to VIGRA.
+
+    This checks the first few bytes of the file and compares them with the
+    "magic strings" of each recognized image format.
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/imageinfo.hxx\><br>
+    Namespace: vigra
+
+    \code
+    std::cout << "is image: " << vigra::isImage("foo.bmp") << std::endl;
+    \endcode
+
+**/
+VIGRA_EXPORT bool isImage(char const * filename);
+
+/********************************************************/
+/*                                                      */
+/*                   ImageExportInfo                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Argument object for the function exportImage().
+
+    See \ref exportImage() for usage example. This object must be used
+    to define the properties of an image to be written to disk.
+
+    <b>\#include</b> \<vigra/imageinfo.hxx\><br>
+    Namespace: vigra
+**/
+class ImageExportInfo
+{
+  public:
+        /** Construct ImageExportInfo object.
+
+            The image will be stored under the given \a filename.
+            The file type will be guessed from the extension unless overridden
+            by \ref setFileType(). Recognized extensions: '.bmp', '.exr', '.gif',
+            '.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras',
+            '.tif', '.tiff', '.xv', '.hdr'.
+            
+            EXR support requires libopenexr, JPEG support requires libjpeg,
+            PNG support requires libpng and TIFF support requires libtiff.
+            
+            If the data is exported to TIFF, the \a mode may be "a", in which case
+            the exported image is appended to the existing file, resulting in a 
+            multi-page TIFF image.
+         **/
+    VIGRA_EXPORT ImageExportInfo( const char * filename, const char * mode = "w" );
+    VIGRA_EXPORT ~ImageExportInfo();
+
+        /** Set image file name.
+
+            The file type will be guessed from the extension unless overridden
+            by \ref setFileType(). Recognized extensions: '.bmp', '.exr', '.gif',
+            '.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras',
+            '.tif', '.tiff', '.xv', '.hdr'.
+            EXR support requires libopenexr, JPEG support requires libjpeg,
+            PNG support requires libpng and TIFF support requires libtiff.
+         **/
+    VIGRA_EXPORT ImageExportInfo & setFileName(const char * filename);
+    VIGRA_EXPORT const char * getFileName() const;
+
+        /** Return the image file opening mode.
+         **/
+    VIGRA_EXPORT const char * getMode() const;
+
+        /** Store image as given file type.
+
+            This will override any type guessed
+            from the file name's extension. Recognized file types:
+
+            <DL>
+            <DT><b>BMP:</b><DD> Microsoft Windows bitmap image file.
+            <DT><b>EXR:</b><DD> OpenEXR high dynamic range image format.
+            (only available if libopenexr is installed)
+            <DT><b>GIF:</b><DD> CompuServe graphics interchange format; 8-bit color.
+            <DT><b>HDR:</b><DD> Radiance RGBE high dynamic range image format.
+            <DT><b>JPEG:</b><DD> Joint Photographic Experts Group JFIF format;
+            compressed 24-bit color (only available if libjpeg is installed).
+            <DT><b>PNG:</b><DD> Portable Network Graphic
+            (only available if libpng is installed).
+            <DT><b>PBM:</b><DD> Portable bitmap format (black and white).
+            <DT><b>PGM:</b><DD> Portable graymap format (gray scale).
+            <DT><b>PNM:</b><DD> Portable anymap.
+            <DT><b>PPM:</b><DD> Portable pixmap format (color).
+            <DT><b>SUN:</b><DD> SUN Rasterfile.
+            <DT><b>TIFF:</b><DD> Tagged Image File Format.
+            (only available if libtiff is installed.)
+            <DT><b>VIFF:</b><DD> Khoros Visualization image file.
+            </DL>
+
+            With the exception of TIFF, VIFF, PNG, and PNM all file types store
+            only 1 byte (gray scale and mapped RGB) or 3 bytes (RGB) per
+            pixel.
+
+            PNG can store UInt8 and UInt16 values, and supports 1 and 3 channel
+            images. One additional alpha channel is also supported.
+
+            PNM can store 1 and 3 channel images with UInt8, UInt16 and UInt32
+            values in each channel.
+
+            TIFF and VIFF are additionally able to store short and long
+            integers (2 or 4 bytes) and real values (32 bit float and
+            64 bit double) without conversion. So you will need to use
+            TIFF or VIFF if you need to store images with high
+            accuracy (the appropriate type to write is automatically
+            derived from the image type to be exported). However, many
+            other programs using TIFF (e.g. ImageMagick) have not
+            implemented support for those pixel types.  So don't be
+            surprised if the generated TIFF is not readable in some
+            cases.  If this happens, export the image as 'unsigned
+            char' or 'RGBValue\<unsigned char\>' by calling
+            \ref ImageExportInfo::setPixelType().
+
+            Support to reading and writing ICC color profiles is
+            provided for TIFF, JPEG, and PNG images.
+         **/
+    VIGRA_EXPORT ImageExportInfo & setFileType( const char * );
+    VIGRA_EXPORT const char * getFileType() const;
+
+        /** Set compression type and quality.
+
+            This option is ignored when the target file format doesn't recognize
+            the compression type. Valid arguments:
+
+            <DL>
+            <DT><b>NONE:</b><DD> (recognized by EXR and TIFF): do not compress (many other formats don't
+                           compress either, but it is not an option for them).
+            <DT><b>JPEG:</b><DD> (recognized by JPEG and TIFF): use JPEG compression.
+                           You can also specify a compression quality parameter by
+                           passing "JPEG QUALITY=N", where "N" must be an integer between 1 and 100
+                           (e.g. "JPEG QUALITY=70").
+            <DT><b>JPEG-ARITH:</b><DD> (recognized by new versions of JPEG): use arithmetic coding as a back-end
+                           after JPEG compression (by default, the back-end is Huffman coding).
+                           You can also specify a compression quality parameter by
+                           passing "JPEG-ARITH QUALITY=N", where "N" must be an integer between 1 and 100
+                           (e.g. "JPEG-ARITH QUALITY=70").
+            <DT><b>RLE, RunLength:</b><DD> (recognized by EXR and TIFF): use run-length encoding. (BMP also
+                          uses run-length encoding, but there it is not an option).
+            <DT><b>PACKBITS:</b><DD> (recognized by TIFF): use packbits encoding (a variant of RLE).
+            <DT><b>DEFLATE:</b><DD> (recognized by TIFF): use deflate encoding, as defined in zlib (PNG also
+                           uses deflate, but there it is not an option).
+            <DT><b>LZW:</b><DD> (recognized by TIFF): use Lempel-Ziv-Welch encoding.
+            <DT><b>ZIP:</b><DD> (recognized by EXR): use zip-style encoding.
+            <DT><b>PIZ:</b><DD> (recognized by EXR): use wavelet encoding.
+            <DT><b>PXR24:</b><DD> (recognized by EXR): reduce to 24-bit, then use zip-style encoding.
+            <DT><b>B44, B44A:</b><DD> (recognized by EXR): see OpenEXR documentation.
+            <DT><b>ASCII:</b><DD> (recognized by PNM): store pixels as ASCII (human readable numbers).
+            <DT><b>RAW:</b><DD> (recognized by PNM): store pixels as uncompressed binary data.
+            <DT><b>BILEVEL:</b><DD> (recognized by PNM): store as one bit per pixel.
+            <DT><b>1 ... 100:</b><DD> deprecated (equivalent to <tt>setCompression("JPEG QUALITY=number")</tt>
+                             where the number denotes the desired quality).
+            </DL>
+
+            Some of these options (e.g. "JPEG-ARITH", "LZW", "B44", "B44A") may only be available when
+            they have been enabled in the corresponding third-party library.
+         **/
+    VIGRA_EXPORT ImageExportInfo & setCompression( const char * type);
+
+    VIGRA_EXPORT const char * getCompression() const;
+
+        /** Set the pixel type of the image file. Possible values are:
+            <DL>
+            <DT><b>UINT8:</b><DD> 8-bit unsigned integer (unsigned char)
+            <DT><b>INT16:</b><DD> 16-bit signed integer (short)
+            <DT><b>UINT16:</b><DD> 16-bit unsigned integer (unsigned short)
+            <DT><b>INT32:</b><DD> 32-bit signed integer (long)
+            <DT><b>UINT32:</b><DD> 32-bit unsigned integer (unsigned long)
+            <DT><b>FLOAT:</b><DD> 32-bit floating point (float)
+            <DT><b>DOUBLE:</b><DD> 64-bit floating point (double)
+            </DL>
+
+            <b>Usage:</b>
+
+            \code
+            FImage img(w,h);
+
+            // by default, float images are exported with pixeltype float
+            // when the target format support this type, i.e. is TIFF or VIFF.
+            exportImage(srcImageRange(img), ImageExportInfo("asFloat.tif"));
+
+            // if this is not desired, force a different pixeltype
+            exportImage(srcImageRange(img), ImageExportInfo("asByte.tif").setPixelType("UINT8"));
+            \endcode
+         **/
+    VIGRA_EXPORT ImageExportInfo & setPixelType( const char * );
+
+        /** Get the pixel type of the image. Possible values are:
+            <DL>
+            <DT><b>UINT8:</b><DD> 8-bit unsigned integer (unsigned char)
+            <DT><b>INT16:</b><DD> 16-bit signed integer (short)
+            <DT><b>INT32:</b><DD> 32-bit signed integer (long)
+            <DT><b>FLOAT:</b><DD> 32-bit floating point (float)
+            <DT><b>DOUBLE:</b><DD> 64-bit floating point (double)
+            </DL>
+         **/
+    VIGRA_EXPORT const char * getPixelType() const;
+
+    VIGRA_EXPORT ImageExportInfo & setForcedRangeMapping(double fromMin, double fromMax,
+                                                     double toMin, double toMax);
+    VIGRA_EXPORT bool hasForcedRangeMapping() const;
+    VIGRA_EXPORT double getFromMin() const;
+    VIGRA_EXPORT double getFromMax() const;
+    VIGRA_EXPORT double getToMin() const;
+    VIGRA_EXPORT double getToMax() const;
+
+        /** Set the image resolution in horizontal direction
+         **/
+    VIGRA_EXPORT ImageExportInfo & setXResolution( float );
+    VIGRA_EXPORT float getXResolution() const;
+
+        /** Set the image resolution in vertical direction
+         **/
+    VIGRA_EXPORT ImageExportInfo & setYResolution( float );
+    VIGRA_EXPORT float getYResolution() const;
+
+        /** Set the position of the upper Left corner on a global
+            canvas.
+
+            Currently only supported by TIFF, PNG and OpenEXR files.
+
+            The offset is encoded in the XPosition and YPosition TIFF tags.
+
+            @param pos     position of the upper left corner in pixels
+                           (must be >= 0)
+         **/
+    VIGRA_EXPORT ImageExportInfo & setPosition(const Diff2D & pos);
+
+        /** Get the position of the upper left corner on
+            a global canvas.
+         **/
+    VIGRA_EXPORT Diff2D getPosition() const;
+
+        /** Get the size of the canvas, on which the image is positioned at
+            getPosition()
+         **/
+    VIGRA_EXPORT Size2D getCanvasSize() const;
+
+        /** Get the size of the canvas, on which the image is positioned at
+            getPosition()
+         **/
+    VIGRA_EXPORT ImageExportInfo & setCanvasSize(const Size2D & size);
+
+        /**
+          ICC profiles (handled as raw data so far).
+          see getICCProfile()/setICCProfile()
+         **/
+    typedef ArrayVector<unsigned char> ICCProfile;
+
+        /** Returns a reference to the ICC profile.
+         */
+    VIGRA_EXPORT const ICCProfile & getICCProfile() const;
+
+        /** Sets the ICC profile.
+            ICC profiles are currently supported by TIFF, PNG and JPEG images.
+            (Otherwise, the profile data is silently ignored.)
+         **/
+    VIGRA_EXPORT ImageExportInfo & setICCProfile(const ICCProfile & profile);
+
+  private:
+    std::string m_filename, m_filetype, m_pixeltype, m_comp, m_mode;
+    float m_x_res, m_y_res;
+    Diff2D m_pos;
+    ICCProfile m_icc_profile;
+    Size2D m_canvas_size;
+    double fromMin_, fromMax_, toMin_, toMax_;
+};
+
+// return an encoder for a given ImageExportInfo object
+VIGRA_EXPORT VIGRA_UNIQUE_PTR<Encoder> encoder( const ImageExportInfo & info );
+
+/********************************************************/
+/*                                                      */
+/*                   ImageImportInfo                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Argument object for the function importImage().
+
+See \ref importImage() for a usage example. This object must be
+used to read an image from disk and enquire about its properties.
+
+<b>\#include</b> \<vigra/imageinfo.hxx\><br>
+Namespace: vigra
+**/
+class ImageImportInfo
+{
+  public:
+    enum PixelType { UINT8, INT16, UINT16, INT32, UINT32, FLOAT, DOUBLE };
+
+        /** Construct ImageImportInfo object.
+
+            The image with the given filename is read into memory.
+            The file type will be determined by the first few bytes of the
+            file (magic number). Recognized file types:
+
+            <DL>
+            <DT><b>BMP:</b><DD> Microsoft Windows bitmap image file.
+            <DT><b>EXR:</b><DD> OpenEXR high dynamic range image format.
+            (only available if libopenexr is installed)
+            <DT><b>GIF:</b><DD> CompuServe graphics interchange format; 8-bit color.
+            <DT><b>HDR:</b><DD> Radiance RGBE high dynamic range image format.
+            <DT><b>JPEG:</b><DD> Joint Photographic Experts Group JFIF format;
+            compressed 24-bit color (only available if libjpeg is installed).
+            <DT><b>PNG:</b><DD> Portable Network Graphic
+            (only available if libpng is installed).
+            <DT><b>PBM:</b><DD> Portable bitmap format (black and white).
+            <DT><b>PGM:</b><DD> Portable graymap format (gray scale).
+            <DT><b>PNM:</b><DD> Portable anymap.
+            <DT><b>PPM:</b><DD> Portable pixmap format (color).
+            <DT><b>SUN:</b><DD> SUN Rasterfile.
+            <DT><b>TIFF:</b><DD> Tagged Image File Format.
+            (only available if libtiff is installed.)
+            <DT><b>VIFF:</b><DD> Khoros Visualization image file.
+            </DL>
+            
+            The parameter \a page can be used in conjunction with multi-page TIFF 
+            files in order to specify the desired page (i.e. image) in the file.
+         **/
+    VIGRA_EXPORT ImageImportInfo( const char * filename, unsigned int page = 0 );
+    VIGRA_EXPORT ~ImageImportInfo();
+
+    VIGRA_EXPORT const char * getFileName() const;
+
+        /** Get the file type of the image associated with this
+            info object.
+
+            See ImageImportInfo::ImageImportInfo for a list of the
+            available file types.
+         **/
+    VIGRA_EXPORT const char * getFileType() const;
+
+        /** Get width of the image.
+         **/
+    VIGRA_EXPORT int width() const;
+
+        /** Get height of the image.
+         **/
+    VIGRA_EXPORT int height() const;
+
+        /** Get the total number of bands in the image.
+         **/
+    VIGRA_EXPORT int numBands() const;
+
+        /** Get the number of extra (non color) bands in the image.
+         ** Usually these are the alpha channels.
+         **/
+    VIGRA_EXPORT int numExtraBands() const;
+
+        /** Get the number of images contained in the image file.
+         **/
+    VIGRA_EXPORT int numImages() const;
+
+        /** Sets the index of the image to import from the image file.
+         **/
+    VIGRA_EXPORT void setImageIndex(const int);
+
+        /** Gets the index of the image to import from the image file.
+         **/
+    VIGRA_EXPORT int getImageIndex() const;
+
+        /** Get size of the image.
+         **/
+    VIGRA_EXPORT Size2D size() const;
+
+        /** Get size of the image in a form compatible to MultiArray.
+         **/
+    VIGRA_EXPORT MultiArrayShape<2>::type shape() const;
+
+        /** Returns true if the image is gray scale.
+         **/
+    VIGRA_EXPORT bool isGrayscale() const;
+
+        /** Returns true if the image is colored (RGB).
+         **/
+    VIGRA_EXPORT bool isColor() const;
+
+        /** Query the pixel type of the image.
+
+            Possible values are:
+            <DL>
+            <DT><b>UINT8:</b><DD> 8-bit unsigned integer (unsigned char)
+            <DT><b>INT16:</b><DD> 16-bit signed integer (short)
+            <DT><b>UINT16:</b><DD> 16-bit unsigned integer (unsigned short)
+            <DT><b>INT32:</b><DD> 32-bit signed integer (long)
+            <DT><b>UINT32:</b><DD> 32-bit unsigned integer (unsigned long)
+            <DT><b>FLOAT:</b><DD> 32-bit floating point (float)
+            <DT><b>DOUBLE:</b><DD> 64-bit floating point (double)
+            </DL>
+         **/
+    VIGRA_EXPORT const char * getPixelType() const;
+
+        /** Query the pixel type of the image.
+
+            Same as getPixelType(), but the result is returned as a
+            ImageImportInfo::PixelType enum. This is useful to implement
+            a switch() on the pixel type.
+
+            Possible values are:
+            <DL>
+            <DT><b>UINT8:</b><DD> 8-bit unsigned integer (unsigned char)
+            <DT><b>INT16:</b><DD> 16-bit signed integer (short)
+            <DT><b>UINT16:</b><DD> 16-bit unsigned integer (unsigned short)
+            <DT><b>INT32:</b><DD> 32-bit signed integer (long)
+            <DT><b>UINT32:</b><DD> 32-bit unsigned integer (unsigned long)
+            <DT><b>FLOAT:</b><DD> 32-bit floating point (float)
+            <DT><b>DOUBLE:</b><DD> 64-bit floating point (double)
+            </DL>
+         **/
+    VIGRA_EXPORT PixelType pixelType() const;
+
+        /** Returns true if the image has 1 byte per pixel (gray) or
+            3 bytes per pixel (RGB).
+         **/
+    VIGRA_EXPORT bool isByte() const;
+
+        /** Returns the layer offset of the current image, if there is one
+         **/
+    VIGRA_EXPORT Diff2D getPosition() const;
+
+        /** Get the size of the canvas, on which the image is positioned at
+            getPosition()
+         **/
+    VIGRA_EXPORT Size2D getCanvasSize() const;
+
+        /** Returns the image resolution in horizontal direction
+         **/
+    VIGRA_EXPORT float getXResolution() const;
+
+        /** Returns the image resolution in vertical direction
+         **/
+    VIGRA_EXPORT float getYResolution() const;
+
+        /**
+          ICC profiles (handled as raw data so far).
+          see getICCProfile()/setICCProfile()
+         **/
+    typedef ArrayVector<unsigned char> ICCProfile;
+
+        /** Returns a reference to the ICC profile.
+
+           Note: The reference will become invalid when the
+           ImageImportInfo object has been destroyed.
+         **/
+    VIGRA_EXPORT const ICCProfile & getICCProfile() const;
+
+  private:
+    std::string m_filename, m_filetype, m_pixeltype;
+    int m_width, m_height, m_num_bands, m_num_extra_bands, m_num_images, m_image_index;
+    float m_x_res, m_y_res;
+    Diff2D m_pos;
+    Size2D m_canvas_size;
+    ICCProfile m_icc_profile;
+
+    void readHeader_();
+};
+
+// return a decoder for a given ImageImportInfo object
+VIGRA_EXPORT VIGRA_UNIQUE_PTR<Decoder> decoder( const ImageImportInfo & info );
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_IMAGEINFO_HXX
diff --git a/include/vigra/imageiterator.hxx b/include/vigra/imageiterator.hxx
new file mode 100644
index 0000000..7e443a7
--- /dev/null
+++ b/include/vigra/imageiterator.hxx
@@ -0,0 +1,1564 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_IMAGEITERATOR_HXX
+#define VIGRA_IMAGEITERATOR_HXX
+
+#include "utilities.hxx"
+#include "accessor.hxx"
+#include "iteratortraits.hxx"
+#include "metaprogramming.hxx"
+
+namespace vigra {
+
+template <class IMAGEITERATOR>
+class StridedIteratorPolicy
+{
+  public:
+    typedef IMAGEITERATOR                            ImageIterator;
+    typedef typename IMAGEITERATOR::value_type       value_type;
+    typedef typename IMAGEITERATOR::difference_type::MoveY
+                                                     difference_type;
+    typedef typename IMAGEITERATOR::reference        reference;
+    typedef typename IMAGEITERATOR::index_reference  index_reference;
+    typedef typename IMAGEITERATOR::pointer          pointer;
+    typedef std::random_access_iterator_tag iterator_category;
+
+
+    struct BaseType
+    {
+        explicit BaseType(pointer c = 0, difference_type stride = 0)
+        : current_(c), stride_(stride)
+        {}
+
+        pointer current_;
+        difference_type stride_;
+    };
+
+    static void initialize(BaseType & /* d */) {}
+
+    static reference dereference(BaseType const & d)
+        { return const_cast<reference>(*d.current_); }
+
+    static index_reference dereference(BaseType const & d, difference_type n)
+    {
+        return const_cast<index_reference>(d.current_[n*d.stride_]);
+    }
+
+    static bool equal(BaseType const & d1, BaseType const & d2)
+        { return d1.current_ == d2.current_; }
+
+    static bool less(BaseType const & d1, BaseType const & d2)
+        { return d1.current_ < d2.current_; }
+
+    static difference_type difference(BaseType const & d1, BaseType const & d2)
+        { return (d1.current_ - d2.current_) / d1.stride_; }
+
+    static void increment(BaseType & d)
+        { d.current_ += d.stride_; }
+
+    static void decrement(BaseType & d)
+        { d.current_ -= d.stride_; }
+
+    static void advance(BaseType & d, difference_type n)
+        { d.current_ += d.stride_*n; }
+};
+
+/** \addtogroup ImageIterators  Image Iterators
+
+    \brief General image iterator definition and implementations.
+
+<p>
+    The following tables describe the general requirements for image iterators
+    and their iterator traits. The iterator implementations provided here
+    may be used for any image data type that stores its
+    data as a linear array of pixels. The array will be interpreted as a
+    row-major matrix with a particular width.
+</p>
+<h3>Requirements for Image Iterators</h3>
+<p>
+
+<table border=2 cellspacing=0 cellpadding=2 width="100%">
+<tr><th colspan=2>
+    Local Types
+    </th><th>
+    Meaning
+    </th>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::value_type</tt></td><td>the underlying image's pixel type</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::PixelType</tt></td><td>the underlying image's pixel type</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::reference</tt></td>
+    <td>the iterator's reference type (return type of <TT>*iter</TT>). Will be
+    <tt>value_type &</tt> for a mutable iterator, and convertible to
+    <tt>value_type const &</tt> for a const iterator.</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::index_reference</tt></td>
+    <td>the iterator's index reference type (return type of <TT>iter[diff]</TT>). Will be
+    <tt>value_type &</tt> for a mutable iterator, and convertible to
+    <tt>value_type const &</tt> for a const iterator.</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::pointer</tt></td>
+    <td>the iterator's pointer type (return type of <TT>iter.operator->()</TT>). Will be
+    <tt>value_type *</tt> for a mutable iterator, and convertible to
+    <tt>value_type const *</tt> for a const iterator.</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::difference_type</tt></td>
+    <td>the iterator's difference type (<TT>vigra::Diff2D</TT>)</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::iterator_category</tt></td>
+    <td>the iterator tag (<tt>vigra::image_traverser_tag</tt>)</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::row_iterator</tt></td><td>the associated row iterator</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::column_iterator</tt></td><td>the associated column iterator</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::MoveX</tt></td><td>type of the horizontal navigator</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::MoveY</tt></td><td>type of the vertical navigator</td>
+</tr>
+<tr><th>
+    Operation
+    </th><th>
+    Result
+    </th><th>
+    Semantics
+    </th>
+</tr>
+<tr>
+    <td><tt>++i.x<br>i.x--</tt></td><td><tt>void</tt></td><td>increment x-coordinate</td>
+</tr>
+<tr>
+    <td><tt>--i.x<br>i.x--</tt></td><td><tt>void</tt></td><td>decrement x-coordinate</td>
+</tr>
+<tr>
+    <td><tt>i.x += dx</tt></td><td><tt>ImageIterator::MoveX &</tt></td>
+    <td>add <tt>dx</tt> to x-coordinate</td>
+</tr>
+<tr>
+    <td><tt>i.x -= dx</tt></td><td><tt>ImageIterator::MoveX &</tt></td>
+    <td>subtract <tt>dx</tt> from x-coordinate</td>
+</tr>
+<tr>
+    <td><tt>i.x - j.x</tt></td><td><tt>int</tt></td>
+    <td>difference of the x-coordinates of <tt>i</tt> and <tt>j</tt></td>
+</tr>
+<tr>
+    <td><tt>i.x = j.x</tt></td><td><tt>ImageIterator::MoveX &</tt></td><td><tt>i.x += j.x - i.x</tt></td>
+</tr>
+<tr>
+    <td><tt>i.x == i.y</tt></td><td><tt>bool</tt></td><td><tt>j.x - i.x == 0</tt></td>
+
+</tr>
+<tr>
+    <td><tt>i.x < j.x</tt></td><td><tt>bool</tt></td><td><tt>j.x - i.x > 0</tt></td>
+
+</tr>
+<tr>
+    <td><tt>++i.y<br>i.y++</tt></td><td><tt>void</tt></td><td>increment y-coordinate</td>
+</tr>
+<tr>
+    <td><tt>--i.y<br>i.y--</tt></td><td><tt>void</tt></td><td>decrement y-coordinate</td>
+</tr>
+<tr>
+    <td><tt>i.y += dy</tt></td><td><tt>ImageIterator::MoveY &</tt></td>
+    <td>add <tt>dy</tt> to y-coordinate</td>
+</tr>
+<tr>
+    <td><tt>i.y -= dy</tt></td><td><tt>ImageIterator::MoveY &</tt></td>
+    <td>subtract <tt>dy</tt> from y-coordinate</td>
+</tr>
+<tr>
+    <td><tt>i.y - j.y</tt></td><td><tt>int</tt></td>
+    <td>difference of the y-coordinates of <tt>i</tt> and <tt>j</tt></td>
+</tr>
+<tr>
+    <td><tt>i.y = j.y</tt></td><td><tt>ImageIterator::MoveY &</tt></td><td><tt>i.y += j.y - i.y</tt></td>
+</tr>
+<tr>
+    <td><tt>i.y == j.y</tt></td><td><tt>bool</tt></td><td><tt>j.y - i.y == 0</tt></td>
+
+</tr>
+<tr>
+    <td><tt>i.y < j.y</tt></td><td><tt>bool</tt></td><td><tt>j.y - i.y > 0</tt></td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator k(i)</tt></td><td>copy constructor</td>
+</tr>
+<tr>
+    <td><tt>k = i</tt></td><td><tt>ImageIterator &</tt></td><td>assignment</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator k</tt></td><td>default constructor</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::row_iterator r(i)</tt></td><td>construction of row iterator</td>
+</tr>
+<tr><td colspan=2>
+    <tt>ImageIterator::column_iterator c(i)</tt></td><td>construction of column iterator</td>
+</tr>
+<tr>
+    <td><tt>i += diff</tt></td><td><tt>ImageIterator &</tt></td>
+    <td><tt>{ i.x += diff.x<br>i.y += diff.y; }</tt></td>
+</tr>
+<tr>
+    <td><tt>i -= diff</tt></td><td><tt>ImageIterator &</tt></td>
+    <td><tt>{ i.x -= diff.x<br>i.y -= diff.y; }</tt></td>
+</tr>
+<tr>
+    <td><tt>i + diff</tt></td><td><tt>ImageIterator</tt></td>
+    <td><tt>{ ImageIterator tmp(i);<br>tmp += diff;<br>return tmp; }</tt></td>
+</tr>
+<tr>
+    <td><tt>i - diff</tt></td><td><tt>ImageIterator</tt></td>
+    <td><tt>{ ImageIterator tmp(i);<br>tmp -= diff;<br>return tmp; }</tt></td>
+</tr>
+<tr>
+    <td><tt>i - j</tt></td><td><tt>ImageIterator::difference_type</tt></td>
+    <td><tt>{ ImageIterator::difference_type tmp(i.x - j.x, i.y - j.y);<br>return tmp; }</tt></td>
+</tr>
+<tr>
+    <td><tt>i == j</tt></td><td><tt>bool</tt></td>
+    <td><tt>i.x == j.x && i.y == j.y</tt></td>
+</tr>
+<tr>
+    <td><tt>*i</tt></td><td><tt>ImageIterator::reference</tt></td>
+    <td>access the current pixel</td>
+</tr>
+<tr>
+    <td><tt>i[diff]</tt></td><td><tt>ImageIterator::index_reference</tt></td>
+    <td>access pixel at offset <tt>diff</tt></td>
+</tr>
+<tr>
+    <td><tt>i(dx, dy)</tt></td><td><tt>ImageIterator::index_reference</tt></td>
+    <td>access pixel at offset <tt>(dx, dy)</tt></td>
+</tr>
+<tr>
+    <td><tt>i->member()</tt></td><td>depends on operation</td>
+    <td>call member function of underlying pixel type via <tt>operator-></tt> of iterator</td>
+</tr>
+<tr><td colspan=3>
+       <tt>i, j, k</tt> are of type <tt>ImageIterator</tt><br>
+       <tt>diff</tt> is of type <tt>ImageIterator::difference_type</tt><br>
+       <tt>dx, dy</tt> are of type <tt>int</tt><br>
+    </td>
+</tr>
+</table>
+</p>
+<h3>Requirements for Image Iterator Traits</h3>
+<p>
+The following iterator traits must be defined for an image iterator:
+</p>
+<p>
+<table border=2 cellspacing=0 cellpadding=2 width="100%">
+<tr><th>
+    Types
+    </th><th>
+    Meaning
+    </th>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::Iterator</tt></td><td>the iterator type the traits are referring to</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::iterator</tt></td><td>the iterator type the traits are referring to</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::value_type</tt></td><td>the underlying image's pixel type</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::reference</tt></td>
+    <td>the iterator's reference type (return type of <TT>*iter</TT>)</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::index_reference</tt></td>
+    <td>the iterator's index reference type (return type of <TT>iter[diff]</TT>)</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::pointer</tt></td>
+    <td>the iterator's pointer type (return type of <TT>iter.operator->()</TT>)</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::difference_type</tt></td>
+    <td>the iterator's difference type</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::iterator_category</tt></td>
+    <td>the iterator tag (<tt>vigra::image_traverser_tag</tt>)</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::row_iterator</tt></td><td>the associated row iterator</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::column_iterator</tt></td><td>the associated column iterator</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::DefaultAccessor</tt></td>
+    <td>the default accessor to be used with the iterator</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::default_accessor</tt></td>
+    <td>the default accessor to be used with the iterator</td>
+</tr>
+<tr>
+    <td><tt>IteratorTraits<ImageIterator>::hasConstantStrides</tt></td>
+    <td>whether the iterator uses constant strides on the underlying memory
+        (always <tt>VigraTrueType</tt> for <tt>ImageIterator</tt>s).</td>
+</tr>
+</table>
+</p>
+*/
+//@{
+
+namespace detail {
+
+template <class StridedOrUnstrided>
+class DirectionSelector;
+
+template <>
+class DirectionSelector<UnstridedArrayTag>
+{
+  public:
+
+    template <class T>
+    class type
+    {
+      public:
+        type(T base)
+        : current_(base)
+        {}
+
+        type(type const & rhs)
+        : current_(rhs.current_)
+        {}
+
+        type & operator=(type const & rhs)
+        {
+            current_ = rhs.current_;
+            return *this;
+        }
+
+        void operator++() {++current_;}
+        void operator++(int) {++current_;}
+        void operator--() {--current_;}
+        void operator--(int) {--current_;}
+        void operator+=(int dx) {current_ += dx; }
+        void operator-=(int dx) {current_ -= dx; }
+
+        bool operator==(type const & rhs) const
+         { return current_ == rhs.current_; }
+
+        bool operator!=(type const & rhs) const
+         { return current_ != rhs.current_; }
+
+        bool operator<(type const & rhs) const
+         { return current_ < rhs.current_; }
+
+        bool operator<=(type const & rhs) const
+         { return current_ <= rhs.current_; }
+
+        bool operator>(type const & rhs) const
+         { return current_ > rhs.current_; }
+
+        bool operator>=(type const & rhs) const
+         { return current_ >= rhs.current_; }
+
+        int operator-(type const & rhs) const
+         { return current_ - rhs.current_; }
+
+        T operator()() const
+        { return current_; }
+
+        T operator()(int d) const
+        { return current_ + d; }
+
+        T current_;
+    };
+};
+
+template <>
+class DirectionSelector<StridedArrayTag>
+{
+  public:
+
+    template <class T>
+    class type
+    {
+      public:
+        type(int stride, T base = 0)
+        : stride_(stride),
+          current_(base)
+        {}
+
+        type(type const & rhs)
+        : stride_(rhs.stride_),
+          current_(rhs.current_)
+        {}
+
+        type & operator=(type const & rhs)
+        {
+            stride_ = rhs.stride_;
+            current_ = rhs.current_;
+            return *this;
+        }
+
+        void operator++() {current_ += stride_; }
+        void operator++(int) {current_ += stride_; }
+        void operator--() {current_ -= stride_; }
+        void operator--(int) {current_ -= stride_; }
+        void operator+=(int dy) {current_ += dy*stride_; }
+        void operator-=(int dy) {current_ -= dy*stride_; }
+
+        bool operator==(type const & rhs) const
+         { return (current_ == rhs.current_); }
+
+        bool operator!=(type const & rhs) const
+         { return (current_ != rhs.current_); }
+
+        bool operator<(type const & rhs) const
+         { return (current_ < rhs.current_); }
+
+        bool operator<=(type const & rhs) const
+         { return (current_ <= rhs.current_); }
+
+        bool operator>(type const & rhs) const
+         { return (current_ > rhs.current_); }
+
+        bool operator>=(type const & rhs) const
+         { return (current_ >= rhs.current_); }
+
+        int operator-(type const & rhs) const
+         { return (current_ - rhs.current_) / stride_; }
+
+        T operator()() const
+        { return current_; }
+
+        T operator()(int d) const
+        { return current_ + d*stride_; }
+
+        int stride_;
+        T current_;
+    };
+};
+
+template <class StridedOrUnstrided>
+class LinearIteratorSelector;
+
+template <>
+class LinearIteratorSelector<UnstridedArrayTag>
+{
+  public:
+    template <class IMAGEITERATOR>
+    class type
+    {
+      public:
+        typedef typename IMAGEITERATOR::pointer res;
+
+        template <class DirSelect>
+        static res construct(typename IMAGEITERATOR::pointer data, DirSelect const &)
+        {
+            return data;
+        }
+    };
+};
+
+template <>
+class LinearIteratorSelector<StridedArrayTag>
+{
+  public:
+    template <class IMAGEITERATOR>
+    class type
+    {
+      public:
+        typedef IteratorAdaptor<StridedIteratorPolicy<IMAGEITERATOR> > res;
+
+        template <class DirSelect>
+        static res construct(typename IMAGEITERATOR::pointer data, DirSelect const & d)
+        {
+            typedef typename res::BaseType Base;
+            return res(Base(data, d.stride_));
+        }
+    };
+};
+
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*                      ImageIteratorBase               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Base class for 2D random access iterators.
+
+    This class contains the navigational part of the iterator.
+    It is usually not constructed directly, but via some derived class such as
+    \ref ImageIterator or \ref StridedImageIterator.
+
+    <b>\#include</b> \<vigra/imageiterator.hxx\> <br/>
+    Namespace: vigra
+
+    The usage examples assume that you constructed two iterators like
+    this:
+
+    \code
+    vigra::ImageIterator<SomePixelType> iterator(base, width);
+    vigra::ImageIterator<SomePixelType> iterator1(base, width);
+    \endcode
+
+    See the paper: U. Koethe:
+    <a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/GenericProg2D.ps">Reusable Algorithms in Image Processing</a>
+    for a discussion of the concepts behind ImageIterators.
+
+*/
+template <class IMAGEITERATOR,
+          class PIXELTYPE, class REFERENCE, class POINTER,
+          class StridedOrUnstrided = UnstridedArrayTag>
+class ImageIteratorBase
+{
+    typedef typename
+        vigra::detail::LinearIteratorSelector<StridedOrUnstrided>::template type<ImageIteratorBase>
+        RowIteratorSelector;
+    typedef typename
+        vigra::detail::LinearIteratorSelector<StridedArrayTag>::template type<ImageIteratorBase>
+        ColumnIteratorSelector;
+  public:
+    typedef ImageIteratorBase<IMAGEITERATOR,
+                 PIXELTYPE, REFERENCE, POINTER, StridedOrUnstrided> self_type;
+
+        /** The underlying image's pixel type.
+        */
+    typedef PIXELTYPE value_type;
+
+        /** deprecated, use <TT>value_type</TT> instead.
+        */
+    typedef PIXELTYPE PixelType;
+
+        /** the iterator's reference type (return type of <TT>*iter</TT>)
+        */
+    typedef REFERENCE            reference;
+
+        /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
+        */
+    typedef REFERENCE            index_reference;
+
+        /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
+        */
+    typedef POINTER              pointer;
+
+        /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
+        */
+    typedef Diff2D               difference_type;
+
+        /** the iterator tag (image traverser)
+        */
+    typedef image_traverser_tag  iterator_category;
+
+        /** The associated row iterator.
+        */
+    typedef typename RowIteratorSelector::res row_iterator;
+
+        /** The associated column iterator.
+        */
+    typedef typename ColumnIteratorSelector::res column_iterator;
+
+        /** Let operations act in X direction
+        */
+    typedef typename
+        vigra::detail::DirectionSelector<StridedOrUnstrided>::template type<pointer> MoveX;
+
+        /** Let operations act in Y direction
+        */
+    typedef typename
+        vigra::detail::DirectionSelector<StridedArrayTag>::template type<int> MoveY;
+
+    /** @name Comparison of Iterators */
+    //@{
+        /** usage: <TT> iterator == iterator1 </TT>
+        */
+    bool operator==(ImageIteratorBase const & rhs) const
+    {
+        return (x == rhs.x) && (y == rhs.y);
+    }
+
+        /** usage: <TT> iterator != iterator1 </TT>
+        */
+    bool operator!=(ImageIteratorBase const & rhs) const
+    {
+        return (x != rhs.x) || (y != rhs.y);
+    }
+
+        /** usage: <TT> Diff2D dist = iterator - iterator1 </TT>
+        */
+    difference_type operator-(ImageIteratorBase const & rhs) const
+    {
+        return difference_type(x - rhs.x, y - rhs.y);
+    }
+
+    //@}
+
+    /** @name Specify coordinate to operate on */
+    //@{
+        /** Refer to iterator's x coordinate.
+            Usage examples:<br>
+            \code
+            ++iterator.x;        // move one step to the right
+            --iterator.x;        // move one step to the left
+            iterator.x += dx;    // move dx steps to the right
+            iterator.x -= dx;    // move dx steps to the left
+            bool notAtEndOfRow = iterator.x < lowerRight.x;   // compare x coordinates of two iterators
+            int width = lowerRight.x - upperLeft.x;           // calculate difference of x coordinates
+                                                              // between two iterators
+            \endcode
+        */
+    MoveX x;
+        /** Refer to iterator's y coordinate.
+            Usage examples:<br>
+            \code
+            ++iterator.y;        // move one step down
+            --iterator.y;        // move one step up
+            iterator.y += dy;    // move dy steps down
+            iterator.y -= dy;    // move dy steps up
+            bool notAtEndOfColumn = iterator.y < lowerRight.y; // compare y coordinates of two iterators
+            int height = lowerRight.y - upperLeft.y;           // calculate difference of y coordinates
+                                                               // between two iterators
+            \endcode
+        */
+    MoveY y;
+    //@}
+
+  protected:
+        /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
+        <TT>ystride</TT> must equal the physical image width (row length),
+        even if the iterator will only be used for a sub image. This constructor
+        must only be called for unstrided iterators
+        (<tt>StridedOrUnstrided == UnstridedArrayTag</tt>)
+        */
+    ImageIteratorBase(pointer base, int ystride)
+    : x(base),
+      y(ystride)
+    {}
+
+        /** Construct from raw memory with a horizontal stride of <TT>xstride</TT>
+        and a vertical stride of <TT>ystride</TT>. This constructor
+        may be used for iterators that shall skip pixels. Thus, it
+        must only be called for strided iterators
+        (<tt>StridedOrUnstrided == StridedArrayTag</tt>)
+        */
+    ImageIteratorBase(pointer base, int xstride, int ystride)
+    : x(xstride, base),
+      y(ystride)
+    {}
+
+        /** Copy constructor */
+    ImageIteratorBase(ImageIteratorBase const & rhs)
+    : x(rhs.x),
+      y(rhs.y)
+    {}
+
+        /** Default constructor */
+    ImageIteratorBase()
+    : x(0),
+      y(0)
+    {}
+
+        /** Copy assignment */
+    ImageIteratorBase & operator=(ImageIteratorBase const & rhs)
+    {
+        if(this != &rhs)
+        {
+            x = rhs.x;
+            y = rhs.y;
+        }
+        return *this;
+    }
+
+  public:
+    /** @name Random navigation */
+    //@{
+        /** Add offset via Diff2D
+        */
+    IMAGEITERATOR & operator+=(difference_type const & s)
+    {
+        x += s.x;
+        y += s.y;
+        return static_cast<IMAGEITERATOR &>(*this);
+    }
+        /** Subtract offset via Diff2D
+        */
+    IMAGEITERATOR & operator-=(difference_type const & s)
+    {
+        x -= s.x;
+        y -= s.y;
+        return static_cast<IMAGEITERATOR &>(*this);
+    }
+
+        /** Add a distance
+        */
+    IMAGEITERATOR operator+(difference_type const & s) const
+    {
+        IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
+
+        ret += s;
+
+        return ret;
+    }
+
+        /** Subtract a distance
+        */
+    IMAGEITERATOR operator-(difference_type const & s) const
+    {
+        IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
+
+        ret -= s;
+
+        return ret;
+    }
+   //@}
+
+    /** @name Access the Pixels */
+    //@{
+        /** Access current pixel. <br>
+            usage: <TT> SomePixelType value = *iterator </TT>
+        */
+    reference operator*() const
+    {
+        return *current();
+    }
+
+        /** Call member of current pixel. <br>
+            usage: <TT> iterator->pixelMemberFunction() </TT>
+        */
+    pointer operator->() const
+    {
+        return current();
+    }
+
+        /** Access pixel at offset from current location. <br>
+            usage: <TT> SomePixelType value = iterator[Diff2D(1,1)] </TT>
+        */
+    index_reference operator[](Diff2D const & d) const
+    {
+        return *current(d.x, d.y);
+    }
+
+        /** Access pixel at offset (dx, dy) from current location. <br>
+            usage: <TT> SomePixelType value = iterator(dx, dy) </TT>
+        */
+    index_reference operator()(int dx, int dy) const
+    {
+        return *current(dx, dy);
+    }
+
+        /** Read pixel with offset [dy][dx] from current pixel.
+            Note that the 'x' index is the trailing index. <br>
+            usage: <TT> SomePixelType value = iterator[dy][dx] </TT>
+        */
+    pointer operator[](int dy) const
+    {
+        return x() + y(dy);
+    }
+    //@}
+
+    row_iterator rowIterator() const
+    {
+        return RowIteratorSelector::construct(current(), x);
+    }
+
+    column_iterator columnIterator() const
+    {
+        return ColumnIteratorSelector::construct(current(), y);
+    }
+
+  private:
+
+    pointer current() const
+        { return x() + y(); }
+
+    pointer current(int dx, int dy) const
+        { return x(dx) + y(dy); }
+};
+
+/********************************************************/
+/*                                                      */
+/*                      ImageIterator                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Standard 2D random access iterator for images that store the
+    data in a linear array.
+
+    Most functions and local types are inherited from ImageIteratorBase.
+
+    See the paper: U. Koethe:
+    <a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/GenericProg2D.ps">Reusable Algorithms in Image Processing</a>
+    for a discussion of the concepts behind ImageIterators.
+
+    <b>\#include</b> \<vigra/imageiterator.hxx\> <br/>
+    Namespace: vigra
+
+*/
+template <class PIXELTYPE>
+class ImageIterator
+: public ImageIteratorBase<ImageIterator<PIXELTYPE>,
+                           PIXELTYPE, PIXELTYPE &, PIXELTYPE *>
+{
+  public:
+    typedef ImageIteratorBase<ImageIterator<PIXELTYPE>,
+                              PIXELTYPE, PIXELTYPE &, PIXELTYPE *> Base;
+
+    typedef typename Base::pointer         pointer;
+    typedef typename Base::difference_type difference_type;
+
+        /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
+        <TT>ystride</TT> must equal the physical image width (row length),
+        even if the iterator will only be used for a sub image.
+        If the raw memory is encapsulated in an image object this
+        object should have a factory function that constructs the
+        iterator.
+        */
+    ImageIterator(pointer base, int ystride)
+    : Base(base, ystride)
+    {}
+
+        /** Default constructor */
+    ImageIterator()
+    : Base()
+    {}
+
+};
+
+/********************************************************/
+/*                                                      */
+/*                   ConstImageIterator                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Standard 2D random access const iterator for images that
+    store the data as a linear array.
+
+    Most functions are inherited from ImageIteratorBase.
+
+    <b>\#include</b> \<vigra/imageiterator.hxx\> <br/>
+    Namespace: vigra
+
+*/
+template <class PIXELTYPE>
+class ConstImageIterator
+: public ImageIteratorBase<ConstImageIterator<PIXELTYPE>,
+                           PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *>
+{
+  public:
+    typedef ImageIteratorBase<ConstImageIterator<PIXELTYPE>,
+                        PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *> Base;
+
+    typedef typename Base::pointer         pointer;
+    typedef typename Base::difference_type difference_type;
+
+        /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
+        <TT>ystride</TT> must equal the physical image width (row length),
+        even if the iterator will only be used for a sub image.
+        If the raw memory is encapsulated in an image object this
+        object should have a factory function that constructs the
+        iterator.
+        */
+    ConstImageIterator(pointer base, int ystride)
+    : Base(base, ystride)
+    {}
+
+    ConstImageIterator(ImageIterator<PIXELTYPE> const & o)
+    : Base(o.x, o.y)
+    {}
+
+        /** Default constructor */
+    ConstImageIterator()
+    : Base()
+    {}
+
+    ConstImageIterator & operator=(ImageIterator<PIXELTYPE> const & o)
+    {
+        Base::x = o.x;
+        Base::y = o.y;
+        return *this;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                 StridedImageIterator                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Iterator to be used when pixels are to be skipped.
+
+    This iterator can be used when some pixels shall be automatically skipped, for example
+    if an image is to be sub-sampled: instead of advancing to the next pixel,
+    <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>.
+    Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types
+    are inherited from ImageIteratorBase.
+
+    <b> Usage:</b>
+
+    \code
+    BImage img(w,h);
+    ...
+    int xskip = 2, yskip = 2;
+    int wskip = w / xskip + 1, hskip = h / yskip + 1;
+
+    StridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip);
+    StridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip);
+
+    // now navigation with upperLeft and lowerRight lets the image appear to have half
+    // the original resolution in either dimension
+    \endcode
+
+    <b>\#include</b> \<vigra/imageiterator.hxx\> <br/>
+    Namespace: vigra
+
+*/
+template <class PIXELTYPE>
+class StridedImageIterator
+: public ImageIteratorBase<StridedImageIterator<PIXELTYPE>,
+                           PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag>
+{
+  public:
+    typedef ImageIteratorBase<StridedImageIterator<PIXELTYPE>,
+                              PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag> Base;
+
+    typedef typename Base::pointer         pointer;
+    typedef typename Base::difference_type difference_type;
+
+        /** Construct from raw memory with a vertical stride of <TT>ystride</TT>,
+        jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically.
+        <tt>ystride</tt> must be the physical width (row length) of the image.
+        */
+    StridedImageIterator(pointer base, int ystride, int xskip, int yskip)
+    : Base(base, xskip, ystride*yskip)
+    {}
+
+        /** Default constructor */
+    StridedImageIterator()
+    : Base()
+    {}
+
+};
+
+/********************************************************/
+/*                                                      */
+/*               ConstStridedImageIterator              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Const iterator to be used when pixels are to be skipped.
+
+    This iterator can be used when some pixels shall be automatically skipped, for example
+    if an image is to be sub-sampled: instead of advancing to the next pixel,
+    <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>.
+    Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types
+    are inherited from ImageIteratorBase.
+
+    <b> Usage:</b>
+
+    \code
+    BImage img(w,h);
+    ...
+    int xskip = 2, yskip = 2;
+    int wskip = w / xskip + 1, hskip = h / yskip + 1;
+
+    ConstStridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip);
+    ConstStridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip);
+
+    // now navigation with upperLeft and lowerRight lets the image appear to have half
+    // the original resolution in either dimension
+    \endcode
+
+    <b>\#include</b> \<vigra/imageiterator.hxx\> <br/>
+    Namespace: vigra
+
+*/
+template <class PIXELTYPE>
+class ConstStridedImageIterator
+: public ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>,
+                           PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
+                           StridedArrayTag>
+{
+  public:
+    typedef ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>,
+                        PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
+                        StridedArrayTag> Base;
+
+    typedef typename Base::pointer         pointer;
+    typedef typename Base::difference_type difference_type;
+
+        /** Construct from raw memory with a vertical stride of <TT>ystride</TT>,
+        jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically.
+        <tt>ystride</tt> must be the physical width (row length) of the image.
+        */
+    ConstStridedImageIterator(pointer base, int ystride, int xskip, int yskip)
+    : Base(base, xskip, ystride*yskip)
+    {}
+
+        /** Copy-construct from mutable iterator */
+    ConstStridedImageIterator(StridedImageIterator<PIXELTYPE> const & o)
+    : Base(o.x, o.y)
+    {}
+
+        /** Default constructor */
+    ConstStridedImageIterator()
+    : Base()
+    {}
+
+        /** Assign mutable iterator */
+    ConstStridedImageIterator & operator=(StridedImageIterator<PIXELTYPE> const & o)
+    {
+        Base::x = o.x;
+        Base::y = o.y;
+        return *this;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*             definition of iterator traits            */
+/*                                                      */
+/********************************************************/
+
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class T>
+struct IteratorTraits<ImageIterator<T> >
+: public IteratorTraitsBase<ImageIterator<T> >
+{
+    typedef ImageIterator<T>                              mutable_iterator;
+    typedef ConstImageIterator<T>                         const_iterator;
+    typedef typename AccessorTraits<T>::default_accessor  DefaultAccessor;
+    typedef DefaultAccessor                               default_accessor;
+    typedef VigraTrueType                                 hasConstantStrides;
+};
+
+template <class T>
+struct IteratorTraits<ConstImageIterator<T> >
+: public IteratorTraitsBase<ConstImageIterator<T> >
+{
+    typedef ImageIterator<T>                              mutable_iterator;
+    typedef ConstImageIterator<T>                         const_iterator;
+    typedef typename AccessorTraits<T>::default_const_accessor  DefaultAccessor;
+    typedef DefaultAccessor                               default_accessor;
+    typedef VigraTrueType                                 hasConstantStrides;
+};
+
+template <class T>
+struct IteratorTraits<StridedImageIterator<T> >
+: public IteratorTraitsBase<StridedImageIterator<T> >
+{
+    typedef StridedImageIterator<T>                       mutable_iterator;
+    typedef ConstStridedImageIterator<T>                  const_iterator;
+    typedef typename AccessorTraits<T>::default_accessor  DefaultAccessor;
+    typedef DefaultAccessor                               default_accessor;
+    typedef VigraTrueType                                 hasConstantStrides;
+};
+
+template <class T>
+struct IteratorTraits<ConstStridedImageIterator<T> >
+: public IteratorTraitsBase<ConstStridedImageIterator<T> >
+{
+    typedef StridedImageIterator<T>                       mutable_iterator;
+    typedef ConstStridedImageIterator<T>                  const_iterator;
+    typedef typename AccessorTraits<T>::default_const_accessor  DefaultAccessor;
+    typedef DefaultAccessor                               default_accessor;
+    typedef VigraTrueType                                 hasConstantStrides;
+};
+
+#else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+#define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \
+    template <>  \
+    struct IteratorTraits<ImageIterator<VALUETYPE > > \
+    : public IteratorTraitsBase<ImageIterator<VALUETYPE > > \
+    { \
+        typedef ImageIterator<VALUETYPE>                         mutable_iterator; \
+        typedef ConstImageIterator<VALUETYPE>                    const_iterator; \
+        typedef typename AccessorTraits<VALUETYPE >::default_accessor  DefaultAccessor; \
+        typedef DefaultAccessor                               default_accessor; \
+        typedef VigraTrueType                                 hasConstantStrides; \
+    }; \
+    \
+    template <>  \
+    struct IteratorTraits<ConstImageIterator<VALUETYPE > > \
+    : public IteratorTraitsBase<ConstImageIterator<VALUETYPE > > \
+    { \
+        typedef ImageIterator<VALUETYPE>                         mutable_iterator; \
+        typedef ConstImageIterator<VALUETYPE>                    const_iterator; \
+        typedef typename AccessorTraits<VALUETYPE >::default_const_accessor  DefaultAccessor; \
+        typedef DefaultAccessor                               default_accessor; \
+        typedef VigraTrueType                                 hasConstantStrides; \
+    }; \
+    template <>  \
+    struct IteratorTraits<StridedImageIterator<VALUETYPE > > \
+    : public IteratorTraitsBase<StridedImageIterator<VALUETYPE > > \
+    { \
+        typedef StridedImageIterator<VALUETYPE>                         mutable_iterator; \
+        typedef ConstStridedImageIterator<VALUETYPE>                    const_iterator; \
+        typedef typename AccessorTraits<VALUETYPE >::default_accessor  DefaultAccessor; \
+        typedef DefaultAccessor                               default_accessor; \
+        typedef VigraTrueType                                 hasConstantStrides; \
+    }; \
+    \
+    template <>  \
+    struct IteratorTraits<ConstStridedImageIterator<VALUETYPE > > \
+    : public IteratorTraitsBase<ConstStridedImageIterator<VALUETYPE > > \
+    { \
+        typedef StridedImageIterator<VALUETYPE>                         mutable_iterator; \
+        typedef ConstStridedImageIterator<VALUETYPE>                    const_iterator; \
+        typedef typename AccessorTraits<VALUETYPE >::default_const_accessor  DefaultAccessor; \
+        typedef DefaultAccessor                               default_accessor; \
+        typedef VigraTrueType                                 hasConstantStrides; \
+    };
+
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>)
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>)
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>)
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>)
+VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>)
+
+#define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<short, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<short, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<short, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<int, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<int, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<int, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<float, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<float, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<float, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<double, 2>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<double, 3>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+#define VIGRA_PIXELTYPE TinyVector<double, 4>
+VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
+#undef VIGRA_PIXELTYPE
+
+#undef VIGRA_DEFINE_ITERATORTRAITS
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class PIXELTYPE>
+class ConstValueIteratorPolicy
+{
+  public:
+
+    typedef PIXELTYPE                       value_type;
+    typedef int                             difference_type;
+    typedef PIXELTYPE const &               reference;
+    typedef PIXELTYPE const &               index_reference;
+    typedef PIXELTYPE const *               pointer;
+    typedef std::random_access_iterator_tag iterator_category;
+
+    struct BaseType
+    {
+        BaseType(PIXELTYPE const & v = PIXELTYPE(), int p = 0)
+        : value(v), pos(p)
+        {}
+
+        PIXELTYPE value;
+        int pos;
+    };
+
+    static void initialize(BaseType & d) {}
+
+    static reference dereference(BaseType const & d)
+        { return d.value; }
+
+    static index_reference dereference(BaseType d, difference_type)
+    {
+        return d.value;
+    }
+
+    static bool equal(BaseType const & d1, BaseType const & d2)
+        { return d1.pos == d2.pos; }
+
+    static bool less(BaseType const & d1, BaseType const & d2)
+        { return d1.pos < d2.pos; }
+
+    static difference_type difference(BaseType const & d1, BaseType const & d2)
+        { return d1.pos - d2.pos; }
+
+    static void increment(BaseType & d)
+        { ++d.pos; }
+
+    static void decrement(BaseType & d)
+        { --d.pos; }
+
+    static void advance(BaseType & d, difference_type n)
+        { d.pos += n; }
+};
+
+/********************************************************/
+/*                                                      */
+/*                 ConstValueIterator                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Iterator that always returns the constant specified in the
+    constructor.
+
+    This iterator can be used to simulate an image that
+    does not actually exist.
+
+    <b>\#include</b> \<vigra/imageiterator.hxx\> <br/>
+    Namespace: vigra
+
+*/
+template <class PIXELTYPE>
+class ConstValueIterator
+{
+  public:
+        /** The type of the constant the iterator holds.
+        */
+   typedef PIXELTYPE value_type;
+
+        /** The type of the constant the iterator holds.
+        */
+    typedef PIXELTYPE PixelType;
+
+        /** the iterator's reference type (return type of <TT>*iter</TT>)
+        */
+    typedef PIXELTYPE const &    reference;
+
+        /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
+        */
+    typedef PIXELTYPE const &    index_reference;
+
+        /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
+        */
+    typedef PIXELTYPE const *    pointer;
+
+        /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
+        */
+    typedef Diff2D               difference_type;
+
+        /** the iterator tag (image traverser)
+        */
+    typedef image_traverser_tag  iterator_category;
+
+        /** The associated row iterator.
+        */
+    typedef IteratorAdaptor<ConstValueIteratorPolicy<PIXELTYPE> > row_iterator;
+
+        /** The associated column iterator.
+        */
+    typedef IteratorAdaptor<ConstValueIteratorPolicy<PIXELTYPE> > column_iterator;
+
+        /** Let operations act in X direction
+        */
+    typedef int MoveX;
+
+        /** Let operations act in Y direction
+        */
+    typedef int MoveY;
+
+        /** Default Constructor. (the constant is set to
+        <TT>NumericTraits<PIXELTYPE>::zero()</TT> )
+        */
+    ConstValueIterator()
+    : value_(NumericTraits<PIXELTYPE>::zero()), x(0), y(0)
+    {}
+
+        /** Construct with given constant.
+        */
+    ConstValueIterator(PixelType const & v)
+    : value_(v), x(0), y(0)
+    {}
+
+        /** Copy Constructor.
+       */
+    ConstValueIterator(ConstValueIterator const & v)
+    : value_(v.value_), x(v.x), y(v.y)
+    {}
+
+        /** Copy Assigment.
+        */
+    ConstValueIterator & operator=(ConstValueIterator const & v)
+    {
+        if(this != &v)
+        {
+            value_ = v.value_;
+            x = v.x;
+            y = v.y;
+        }
+        return *this;
+    }
+
+        /** Move iterator by specified distance.
+        */
+    ConstValueIterator & operator+=(Diff2D const & d)
+    {
+        x += d.x;
+        y += d.y;
+        return *this;
+    }
+
+        /** Move iterator by specified distance.
+        */
+    ConstValueIterator & operator-=(Diff2D const & d)
+    {
+        x -= d.x;
+        y -= d.y;
+        return *this;
+    }
+
+        /** Create iterator at specified distance.
+        */
+    ConstValueIterator operator+(Diff2D const & d) const
+    {
+        ConstValueIterator ret(*this);
+        ret += d;
+        return ret;
+    }
+
+        /** Create iterator at specified distance.
+        */
+    ConstValueIterator operator-(Diff2D const & d) const
+    {
+        ConstValueIterator ret(*this);
+        ret -= d;
+        return ret;
+    }
+
+        /** Compute distance between two iterators
+        */
+    Diff2D operator-(ConstValueIterator const & r) const
+    {
+        return Diff2D(x - r.x, y - r.y);
+    }
+
+        /** Equality.
+        */
+    bool operator==(ConstValueIterator const & r) const
+    {
+        return (x == r.x) && (y == r.y);
+    }
+
+        /** Inequality.
+        */
+    bool operator!=(ConstValueIterator const & r) const
+    {
+        return (x != r.x) || (y != r.y);
+    }
+
+        /** Read current pixel (return specified constant).
+        */
+    reference operator*() const
+    {
+        return value_;
+    }
+
+        /** Call member function for stored constant.
+        */
+    pointer operator->() const
+    {
+        return &value_;
+    }
+
+        /** Read pixel at a distance (return specified constant).
+        */
+    index_reference operator()(int const &, int const &) const
+    {
+        return value_;
+    }
+
+        /** Read pixel at a distance (return specified constant).
+        */
+    index_reference operator[](Diff2D const &) const
+    {
+        return value_;
+    }
+
+        /** Get row iterator at current position (which will also hold the constant).
+        */
+    row_iterator rowIterator() const
+        { return row_iterator(typename row_iterator::BaseType(value_, x)); }
+
+        /** Get column iterator at current position (which will also hold the constant).
+        */
+    column_iterator columnIterator() const
+        { return column_iterator(typename column_iterator::BaseType(value_, y)); }
+
+    /** @name Specify coordinate direction for navigation commands */
+    //@{
+        /// refer to x coordinate
+    int x;
+        /// refer to y coordinate
+    int y;
+    //@}
+
+  private:
+
+    PixelType value_;
+};
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class T>
+struct IteratorTraits<ConstValueIterator<T> >
+{
+    typedef ConstValueIterator<T>                  Iterator;
+    typedef Iterator                               iterator;
+    typedef typename iterator::iterator_category   iterator_category;
+    typedef typename iterator::value_type          value_type;
+    typedef typename iterator::reference           reference;
+    typedef typename iterator::index_reference     index_reference;
+    typedef typename iterator::pointer             pointer;
+    typedef typename iterator::difference_type     difference_type;
+    typedef typename iterator::row_iterator        row_iterator;
+    typedef typename iterator::column_iterator     column_iterator;
+    typedef StandardConstAccessor<T>               DefaultAccessor;
+    typedef StandardConstAccessor<T>               default_accessor;
+    typedef VigraTrueType                                 hasConstantStrides;
+};
+
+#endif
+
+/** \brief Simulate an image where each pixel contains its coordinate.
+
+    CoordinateIterator used to be a separate class,
+    but has now become an alias for \ref vigra::Diff2D. This is possible because
+    Diff2D now provides all the necessary functionality.
+
+    CoordinateIterator behaves like a read-only \ref vigra::ImageIterator for
+    an image in which each pixel contains its coordinate. This is useful for
+    algorithms that need access to the current pixel's location.
+    For example, you can use CoordinateIterator/Diff2D to
+    find the center of mass of an image region. To implement this,
+    we first need a functor for center-of-mass calculations:
+
+    \code
+
+    struct CenterOfMassFunctor
+    {
+        CenterOfMassFunctor()
+        : x(0.0), y(0.0), size(0)
+        {}
+
+        void operator()(Diff2d const& diff)
+        {
+            ++size;
+            x += diff.x;
+            y += diff.y;
+        }
+
+        float xCenter() const
+        {   return x / size; }
+
+        float yCenter() const
+        {   return y / size; }
+
+        float x;
+        float y;
+        int size;
+    };
+    \endcode
+
+    Using this functor, we find the center of mass like so:
+
+    \code
+    vigra::BImage img(w,h);
+    ... // mark a region in the image with '1', background with '0'
+
+    CenterOfMassFunctor center;
+
+    vigra::inspectImageIf(
+        srcIterRange(Diff2D(), Diff2D() + img.size()),
+        srcImage(img),
+        center);
+
+    std::cout << "Center of mass: " << center.xCenter() <<
+                                ", " << center.yCenter() << std::endl;
+    \endcode
+
+    <b>\#include</b> \<vigra/imageiterator.hxx\> <br/>
+    Namespace: vigra
+*/
+typedef Diff2D CoordinateIterator;
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_IMAGEITERATOR_HXX
diff --git a/include/vigra/imageiteratoradapter.hxx b/include/vigra/imageiteratoradapter.hxx
new file mode 100644
index 0000000..023e8c7
--- /dev/null
+++ b/include/vigra/imageiteratoradapter.hxx
@@ -0,0 +1,605 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_IMAGEITERATORADAPTER_HXX
+#define VIGRA_IMAGEITERATORADAPTER_HXX
+
+#include <iterator>   // iterator tags
+
+namespace vigra {
+
+/** \addtogroup ImageIteratorAdapters Image Iterator Adapters
+
+     Iterate over rows, columns, neighborhoods, contours, and other image subsets
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                      ColumnIterator                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Iterator adapter to linearly access columns.
+
+    This iterator may be initialized from any standard ImageIterator,
+    a MultibandImageIterator and so on.
+    It gives you STL-compatible (random access iterator) access to
+    one column of the image. If the underlying iterator is a const iterator,
+    the column iterator will also be const (i.e. doesn't allow to change
+    the values it points to).
+    The iterator gets associated with the accessor of the base iterator.
+
+    Note that image iterators usually have a member <TT>columnIterator()</TT>
+    which returns a column iterator optimized for that particular image class.
+    ColumnIterator is only necessary if this 'native' column iterator
+    is not usable in a particular situation or is not provided.
+
+    <b>\#include</b> \<vigra/imageiteratoradapter.hxx\> <br/>
+    Namespace: vigra
+
+*/
+template <class IMAGE_ITERATOR>
+class ColumnIterator : private IMAGE_ITERATOR
+{
+  public:
+        /** the iterator's value type
+        */
+    typedef typename IMAGE_ITERATOR::value_type value_type;
+
+        /** the iterator's value type
+        */
+    typedef typename IMAGE_ITERATOR::value_type PixelType;
+
+        /** the iterator's reference type (return type of <TT>*iter</TT>)
+        */
+    typedef typename IMAGE_ITERATOR::reference              reference;
+
+        /** the iterator's index reference type (return type of <TT>iter[n]</TT>)
+        */
+    typedef typename IMAGE_ITERATOR::index_reference        index_reference;
+
+        /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
+        */
+    typedef typename IMAGE_ITERATOR::pointer                pointer;
+
+        /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
+        */
+    typedef typename IMAGE_ITERATOR::difference_type::MoveY difference_type;
+
+        /** the iterator tag (random access iterator)
+        */
+    typedef std::random_access_iterator_tag                 iterator_category;
+
+        /** the type of the adapted iterator
+        */
+    typedef IMAGE_ITERATOR Adaptee;
+
+        /** Construct from an the image iterator to be adapted.
+       */
+    ColumnIterator(IMAGE_ITERATOR  const & i)
+    : IMAGE_ITERATOR(i)
+    {}
+
+        /** Assignment.
+        */
+    ColumnIterator & operator=(ColumnIterator  const & i)
+    {
+        IMAGE_ITERATOR::operator=(i);
+
+        return *this;
+    }
+
+        /** Assign a new base iterator.
+        */
+    ColumnIterator & operator=(IMAGE_ITERATOR  const & i)
+    {
+        IMAGE_ITERATOR::operator=(i);
+
+        return *this;
+    }
+
+    /** @name Navigation */
+    //@{
+        ///
+    ColumnIterator &  operator++()
+    {
+        ++(this->y);
+        return *this;
+    }
+        ///
+    ColumnIterator  operator++(int)
+    {
+        ColumnIterator ret(*this);
+        (this->y)++;
+        return ret;
+    }
+
+        ///
+    ColumnIterator &  operator--()
+    {
+        --(this->y);
+        return *this;
+    }
+
+        ///
+    ColumnIterator  operator--(int)
+    {
+        ColumnIterator ret(*this);
+        (this->y)--;
+        return ret;
+    }
+
+        ///
+    ColumnIterator &  operator+=(int d)
+    {
+        this->y += d;
+        return *this;
+    }
+
+        ///
+    ColumnIterator &  operator-=(int d)
+    {
+        this->y -= d;
+        return *this;
+    }
+    //@}
+
+    /** @name Methods */
+    //@{
+        /** Construct iterator at a distance.
+        */
+    ColumnIterator operator+(int d) const
+    {
+        IMAGE_ITERATOR ret(*this);
+        ret.y += d;
+        return ColumnIterator(ret);
+    }
+        /** Construct iterator at a distance.
+        */
+    ColumnIterator operator-(int d) const
+    {
+        IMAGE_ITERATOR ret(*this);
+        ret.y -= d;
+        return ColumnIterator(ret);
+    }
+        /** Calculate distance.
+        */
+    int operator-(ColumnIterator const & c) const
+    {
+        return this->y - c.y;
+    }
+
+        /** Equality.
+        */
+    bool operator==(ColumnIterator const & c) const
+    {
+        return IMAGE_ITERATOR::operator==(c);
+    }
+
+        /** Inequality.
+        */
+    bool operator!=(ColumnIterator const & c) const
+    {
+        return IMAGE_ITERATOR::operator!=(c);
+    }
+
+        /** Smaller than.
+        */
+    bool operator<(ColumnIterator const & c) const
+    {
+        return this->y < c.y;
+    }
+
+        /** Access current pixel.
+        */
+    reference operator*() const
+    {
+        return IMAGE_ITERATOR::operator*();
+    }
+
+        /** Access pixel at distance d.
+        */
+    index_reference operator[](int d) const
+    {
+        return IMAGE_ITERATOR::operator()(0, d);
+    }
+
+        /** Call member function of current pixel.
+        */
+    pointer operator->() const
+    {
+        return IMAGE_ITERATOR::operator->();
+    }
+
+        /** Get a reference to the adapted iterator
+        */
+    Adaptee & adaptee() const { return (Adaptee &)*this; }
+
+    //@}
+};
+
+/********************************************************/
+/*                                                      */
+/*                      RowIterator                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Iterator adapter to linearly access row.
+
+    This iterator may be initialized from a standard ImageIterator,
+     a MultibandImageIterator and so on.
+    It gives you STL-compatible (random access iterator) access to
+    one row of the image. If the underlying iterator is a const iterator,
+    the row iterator will also be const (i.e. doesn't allow to change
+    the values it points to).
+    The iterator gets associated with the accessor of the base iterator.
+
+    Note that image iterators usually have a member <TT>rowIterator()</TT>
+    which returns a row iterator optimized for that particular image class.
+    RowIterator is only necessary if this 'native' row iterator
+    is not usable in a particular situation or is not provided.
+
+    <b>\#include</b> \<vigra/imageiteratoradapter.hxx\> <br/>
+    Namespace: vigra
+
+*/
+template <class IMAGE_ITERATOR>
+class RowIterator : private IMAGE_ITERATOR
+{
+  public:
+        /** the iterator's value type
+        */
+    typedef typename IMAGE_ITERATOR::value_type value_type;
+
+        /** the iterator's value type
+        */
+    typedef typename IMAGE_ITERATOR::value_type PixelType;
+
+        /** the iterator's reference type (return type of <TT>*iter</TT>)
+        */
+    typedef typename IMAGE_ITERATOR::reference              reference;
+
+        /** the iterator's index reference type (return type of <TT>iter[n]</TT>)
+        */
+    typedef typename IMAGE_ITERATOR::index_reference        index_reference;
+
+        /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
+        */
+    typedef typename IMAGE_ITERATOR::pointer                pointer;
+
+        /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
+        */
+    typedef typename IMAGE_ITERATOR::difference_type::MoveY difference_type;
+
+        /** the iterator tag (random access iterator)
+        */
+    typedef std::random_access_iterator_tag                 iterator_category;
+
+        /** the type of the adapted iterator
+        */
+    typedef IMAGE_ITERATOR Adaptee;
+
+        /** Construct from an the image iterator to be adapted.
+        */
+    RowIterator(IMAGE_ITERATOR  const & i)
+    : IMAGE_ITERATOR(i)
+    {}
+
+        /** Assignment.
+        */
+    RowIterator & operator=(RowIterator  const & i)
+    {
+        IMAGE_ITERATOR::operator=(i);
+
+        return *this;
+    }
+
+        /** Assign a new base iterator.
+        */
+    RowIterator & operator=(IMAGE_ITERATOR  const & i)
+    {
+        IMAGE_ITERATOR::operator=(i);
+
+        return *this;
+    }
+
+    /** @name Navigation */
+    //@{
+        ///
+    RowIterator &  operator++()
+    {
+        ++(this->x);
+        return *this;
+    }
+        ///
+    RowIterator  operator++(int)
+    {
+        RowIterator ret(*this);
+        (this->x)++;
+        return ret;
+    }
+
+        ///
+    RowIterator &  operator--()
+    {
+        --(this->x);
+        return *this;
+    }
+
+        ///
+    RowIterator  operator--(int)
+    {
+        RowIterator ret(*this);
+        (this->x)--;
+        return ret;
+    }
+
+        ///
+    RowIterator &  operator+=(int d)
+    {
+        this->x += d;
+        return *this;
+    }
+
+        ///
+    RowIterator &  operator-=(int d)
+    {
+        this->x -= d;
+        return *this;
+    }
+    //@}
+
+    /** @name Methods */
+    //@{
+        /** Construct iterator at a distance.
+        */
+    RowIterator operator+(int d) const
+    {
+        IMAGE_ITERATOR ret(*this);
+        ret.x += d;
+        return RowIterator(ret);
+    }
+        /** Construct iterator at a distance.
+        */
+    RowIterator operator-(int d) const
+    {
+        IMAGE_ITERATOR ret(*this);
+        ret.x -= d;
+        return RowIterator(ret);
+    }
+        /** Calculate distance.
+        */
+    int operator-(RowIterator const & c) const
+    {
+        return this->x - c.x;
+    }
+
+        /** Equality.
+        */
+    bool operator==(RowIterator const & c) const
+    {
+        return IMAGE_ITERATOR::operator==(c);
+    }
+
+        /** Inequality.
+        */
+    bool operator!=(RowIterator const & c) const
+    {
+        return IMAGE_ITERATOR::operator!=(c);
+    }
+
+        /** Smaller than.
+        */
+    bool operator<(RowIterator const & c) const
+    {
+        return this->x < c.x;
+    }
+
+        /** Access current pixel.
+        */
+    reference operator*() const
+    {
+        return IMAGE_ITERATOR::operator*();
+    }
+
+        /** Access pixel at distance d.
+        */
+    index_reference operator[](int d) const
+    {
+        return IMAGE_ITERATOR::operator()(d, 0);
+    }
+
+        /** Call member function of current pixel.
+        */
+    pointer operator->() const
+    {
+        return IMAGE_ITERATOR::operator->();
+    }
+
+        /** Get a reference to the adapted iterator
+        */
+    Adaptee & adaptee() const { return (Adaptee &)*this; }
+
+    //@}
+};
+
+/********************************************************/
+/*                                                      */
+/*                     LineIterator                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Iterator adapter to iterate along an arbitrary line on the image.
+
+    This iterator may be initialized from a standard ImageIterator,
+     a MultibandImageIterator and so on.
+    It gives you STL-compatible (forward iterator) access to
+    an arbitrary line on the image.
+    The iterator gets associated with the accessor of the base iterator.
+
+    <b>\#include</b> \<vigra/imageiteratoradapter.hxx\> <br/>
+    Namespace: vigra
+
+*/
+template <class IMAGE_ITERATOR>
+class LineIterator : private IMAGE_ITERATOR
+{
+  public:
+        /** the iterator's value type
+        */
+    typedef typename IMAGE_ITERATOR::value_type value_type;
+
+        /** the iterator's value type
+        */
+    typedef typename IMAGE_ITERATOR::value_type PixelType;
+
+        /** the iterator's reference type (return type of <TT>*iter</TT>)
+        */
+    typedef typename IMAGE_ITERATOR::reference              reference;
+
+        /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
+        */
+    typedef typename IMAGE_ITERATOR::pointer                pointer;
+
+        /** the iterator tag (forward iterator)
+        */
+    typedef std::forward_iterator_tag                       iterator_category;
+
+        /** the type of the adapted iterator
+        */
+    typedef IMAGE_ITERATOR Adaptee;
+
+        /** Construct from an the image iterator to be adapted.
+        */
+    LineIterator(IMAGE_ITERATOR  const & start,
+                 IMAGE_ITERATOR  const & end)
+    : IMAGE_ITERATOR(start), x_(0.0), y_(0.0)
+    {
+        int dx = end.x - start.x;
+        int dy = end.y - start.y;
+        int adx = (dx < 0) ? -dx : dx;
+        int ady = (dy < 0) ? -dy : dy;
+        int dd = (adx > ady) ? adx : ady;
+        if(dd == 0) dd = 1;
+
+        dx_ = (double)dx / dd;
+        dy_ = (double)dy / dd;
+        if(adx > ady) y_ += dy_ / 2.0;
+        else          x_ += dx_ / 2.0;
+    }
+
+    /** @name Navigation */
+    //@{
+        ///
+    LineIterator &  operator++()
+    {
+        x_ += dx_;
+        if(x_ >= 1.0) {
+            x_ -= 1.0;
+            ++(this->x);
+        }
+        else if(x_ <= -1.0) {
+            x_ += 1.0;
+            --(this->x);
+        }
+        y_ += dy_;
+        if(y_ >= 1.0) {
+            y_ -= 1.0;
+            ++(this->y);
+        }
+        else if(y_ <= -1.0) {
+            y_ += 1.0;
+            --(this->y);
+        }
+        return *this;
+    }
+        ///
+    LineIterator  operator++(int)
+    {
+        LineIterator ret(*this);
+        operator++();
+        return ret;
+    }
+
+    //@}
+
+    /** @name Methods */
+    //@{
+        /** Equality.
+       */
+    bool operator==(LineIterator const & c) const
+    {
+        return IMAGE_ITERATOR::operator==(c);
+    }
+
+        /** Inequality.
+       */
+    bool operator!=(LineIterator const & c) const
+    {
+        return IMAGE_ITERATOR::operator!=(c);
+    }
+
+        /** Access current pixel.
+       */
+    reference operator*() const
+    {
+        return IMAGE_ITERATOR::operator*();
+    }
+
+        /** Call member function for current pixel.
+       */
+    pointer operator->() const
+    {
+        return IMAGE_ITERATOR::operator->();
+    }
+
+        /** Get a reference to the adapted iterator
+       */
+    Adaptee & adaptee() const { return (Adaptee &)*this; }
+
+    //@}
+
+  private:
+
+    double x_, y_, dx_, dy_;
+};
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_IMAGEITERATORADAPTER_HXX
diff --git a/include/vigra/impex.hxx b/include/vigra/impex.hxx
new file mode 100644
index 0000000..00c5eb2
--- /dev/null
+++ b/include/vigra/impex.hxx
@@ -0,0 +1,1026 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2001-2002 by Gunnar Kedenburg                */
+/*        Copyright 2012 Christoph Spiel and Ullrich Koethe             */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+/**
+ * \file  impex.hxx
+ * \brief image import and export functions
+ *
+ * This module implements functions importImage() and exportImage().
+ * The matching implementation for any given datatype is selected by
+ * template meta code.
+ *
+ */
+
+#ifndef VIGRA_IMPEX_HXX
+#define VIGRA_IMPEX_HXX
+
+#include "stdimage.hxx"
+#include "imageinfo.hxx"
+#include "impexbase.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra
+{
+/** \addtogroup VigraImpex
+ * @{
+*/
+    namespace detail
+    {
+        template <class ValueType,
+                  class ImageIterator, class ImageAccessor>
+        void
+        read_image_band(Decoder* decoder,
+                        ImageIterator image_iterator, ImageAccessor image_accessor)
+        {
+            typedef typename ImageIterator::row_iterator ImageRowIterator;
+
+            const unsigned width(decoder->getWidth());
+            const unsigned height(decoder->getHeight());
+            const unsigned offset(decoder->getOffset());
+
+            for (unsigned y = 0U; y != height; ++y)
+            {
+                decoder->nextScanline();
+
+                const ValueType* scanline = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0));
+
+                ImageRowIterator is(image_iterator.rowIterator());
+                const ImageRowIterator is_end(is + width);
+
+                while (is != is_end)
+                {
+                    image_accessor.set(*scanline, is);
+                    scanline += offset;
+                    ++is;
+                }
+
+                ++image_iterator.y;
+            }
+        }
+
+
+        template <class ValueType,
+                  class ImageIterator, class ImageAccessor>
+        void
+        read_image_bands(Decoder* decoder,
+                         ImageIterator image_iterator, ImageAccessor image_accessor)
+        {
+            typedef typename ImageIterator::row_iterator ImageRowIterator;
+
+            const unsigned width(decoder->getWidth());
+            const unsigned height(decoder->getHeight());
+            const unsigned bands(decoder->getNumBands());
+            const unsigned offset(decoder->getOffset());
+            const unsigned accessor_size(image_accessor.size(image_iterator));
+            
+            // OPTIMIZATION: Specialization for the most common case
+            // of an RGB-image, i.e. 3 channels.
+            if (accessor_size == 3U)
+            {
+                const ValueType* scanline_0;
+                const ValueType* scanline_1;
+                const ValueType* scanline_2;
+
+                for (unsigned y = 0U; y != height; ++y)
+                {
+                    decoder->nextScanline();
+
+                    scanline_0 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0));
+                    
+                    if(bands == 1)
+                    {
+                        scanline_1 = scanline_0;
+                        scanline_2 = scanline_0;
+                    }
+                    else
+                    {
+                        scanline_1 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(1));
+                        scanline_2 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(2));
+                    }
+                    
+                    ImageRowIterator is(image_iterator.rowIterator());
+                    const ImageRowIterator is_end(is + width);
+
+                    while (is != is_end)
+                    {
+                        image_accessor.setComponent(*scanline_0, is, 0);
+                        image_accessor.setComponent(*scanline_1, is, 1);
+                        image_accessor.setComponent(*scanline_2, is, 2);
+
+                        scanline_0 += offset;
+                        scanline_1 += offset;
+                        scanline_2 += offset;
+
+                        ++is;
+                    }
+
+                    ++image_iterator.y;
+                }
+            }
+            else
+            {
+                std::vector<const ValueType*> scanlines(accessor_size);
+
+                for (unsigned y = 0U; y != height; ++y)
+                {
+                    decoder->nextScanline();
+                    
+                    scanlines[0] = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0));
+
+                    if(bands == 1)
+                    {
+                        for (unsigned i = 1U; i != accessor_size; ++i)
+                        {
+                            scanlines[i] = scanlines[0];
+                        }
+                    }
+                    else
+                    {
+                        for (unsigned i = 1U; i != accessor_size; ++i)
+                        {
+                            scanlines[i] = static_cast<const ValueType*>(decoder->currentScanlineOfBand(i));
+                        }
+                    }
+                    
+                    ImageRowIterator is(image_iterator.rowIterator());
+                    const ImageRowIterator is_end(is + width);
+
+                    while (is != is_end)
+                    {
+                        for (unsigned i = 0U; i != accessor_size; ++i)
+                        {
+                            image_accessor.setComponent(*scanlines[i], is, static_cast<int>(i));
+                            scanlines[i] += offset;
+                        }
+                        ++is;
+                    }
+
+                    ++image_iterator.y;
+                }
+            }
+        }
+
+
+        template <class ImageIterator, class ImageAccessor>
+        void
+        importImage(const ImageImportInfo& import_info,
+                    ImageIterator image_iterator, ImageAccessor image_accessor,
+                    /* isScalar? */ VigraTrueType)
+        {
+            VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
+
+            switch (pixel_t_of_string(decoder->getPixelType()))
+            {
+            case UNSIGNED_INT_8:
+                read_image_band<UInt8>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case UNSIGNED_INT_16:
+                read_image_band<UInt16>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case UNSIGNED_INT_32:
+                read_image_band<UInt32>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case SIGNED_INT_16:
+                read_image_band<Int16>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case SIGNED_INT_32:
+                read_image_band<Int32>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case IEEE_FLOAT_32:
+                read_image_band<float>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case IEEE_FLOAT_64:
+                read_image_band<double>(decoder.get(), image_iterator, image_accessor);
+                break;
+            default:
+                vigra_fail("detail::importImage<scalar>: not reached");
+            }
+
+            decoder->close();
+        }
+
+
+        template <class ImageIterator, class ImageAccessor>
+        void
+        importImage(const ImageImportInfo& import_info,
+                    ImageIterator image_iterator, ImageAccessor image_accessor,
+                    /* isScalar? */ VigraFalseType)
+        {
+            vigra_precondition(import_info.numBands() == image_accessor.size(image_iterator) ||
+                               import_info.numBands() == 1,
+                "importImage(): Number of channels in input and destination image don't match.");
+
+            VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
+            
+            switch (pixel_t_of_string(decoder->getPixelType()))
+            {
+            case UNSIGNED_INT_8:
+                read_image_bands<UInt8>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case UNSIGNED_INT_16:
+                read_image_bands<UInt16>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case UNSIGNED_INT_32:
+                read_image_bands<UInt32>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case SIGNED_INT_16:
+                read_image_bands<Int16>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case SIGNED_INT_32:
+                read_image_bands<Int32>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case IEEE_FLOAT_32:
+                read_image_bands<float>(decoder.get(), image_iterator, image_accessor);
+                break;
+            case IEEE_FLOAT_64:
+                read_image_bands<double>(decoder.get(), image_iterator, image_accessor);
+                break;
+            default:
+                vigra_fail("vigra::detail::importImage<non-scalar>: not reached");
+            }
+
+            decoder->close();
+        }
+
+        template<class ValueType,
+                 class ImageIterator, class ImageAccessor, class ImageScaler>
+        void
+        write_image_band(Encoder* encoder,
+                         ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
+                         const ImageScaler& image_scaler)
+        {
+            typedef typename ImageIterator::row_iterator ImageRowIterator;
+
+            typedef RequiresExplicitCast<ValueType> explicit_cast;
+
+            vigra_precondition(image_lower_right.x >= image_upper_left.x,
+                               "vigra::detail::write_image_band: negative width");
+            vigra_precondition(image_lower_right.y >= image_upper_left.y,
+                               "vigra::detail::write_image_band: negative height");
+
+            const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
+            const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
+
+            encoder->setWidth(width);
+            encoder->setHeight(height);
+            encoder->setNumBands(1);
+            encoder->finalizeSettings();
+
+            const unsigned offset(encoder->getOffset()); // correct offset only _after_ finalizeSettings()
+
+            // IMPLEMENTATION NOTE: We avoid calling the default
+            // constructor to allow classes ImageIterator that do not
+            // define one.
+            ImageIterator image_iterator(image_upper_left);
+
+            for (unsigned y = 0U; y != height; ++y)
+            {
+                ValueType* scanline = static_cast<ValueType*>(encoder->currentScanlineOfBand(0));
+
+                ImageRowIterator is(image_iterator.rowIterator());
+                const ImageRowIterator is_end(is + width);
+
+                while (is != is_end)
+                {
+                    *scanline = explicit_cast::cast(image_scaler(image_accessor(is)));
+                    scanline += offset;
+                    ++is;
+                }
+
+                encoder->nextScanline();
+
+                ++image_iterator.y;
+            }
+        }
+
+
+        template<class ValueType,
+                 class ImageIterator, class ImageAccessor, class ImageScaler>
+        void
+        write_image_bands(Encoder* encoder,
+                          ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
+                          const ImageScaler& image_scaler)
+        {
+            typedef typename ImageIterator::row_iterator ImageRowIterator;
+            typedef RequiresExplicitCast<ValueType> explicit_cast;
+
+            vigra_precondition(image_lower_right.x >= image_upper_left.x,
+                               "vigra::detail::write_image_bands: negative width");
+            vigra_precondition(image_lower_right.y >= image_upper_left.y,
+                               "vigra::detail::write_image_bands: negative height");
+
+            const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
+            const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
+            const unsigned accessor_size(image_accessor.size(image_upper_left));
+
+            encoder->setWidth(width);
+            encoder->setHeight(height);
+            encoder->setNumBands(accessor_size);
+            encoder->finalizeSettings();
+
+            const unsigned offset(encoder->getOffset()); // correct offset only _after_ finalizeSettings()
+
+            // IMPLEMENTATION NOTE: We avoid calling the default
+            // constructor to allow classes ImageIterator that do not
+            // define one.
+            ImageIterator image_iterator(image_upper_left);
+
+            // OPTIMIZATION: Specialization for the most common case
+            // of an RGB-image, i.e. 3 channels.
+            if (accessor_size == 3U)
+            {
+                ValueType* scanline_0;
+                ValueType* scanline_1;
+                ValueType* scanline_2;
+
+                for (unsigned y = 0U; y != height; ++y)
+                {
+                    scanline_0 = static_cast<ValueType*>(encoder->currentScanlineOfBand(0));
+                    scanline_1 = static_cast<ValueType*>(encoder->currentScanlineOfBand(1));
+                    scanline_2 = static_cast<ValueType*>(encoder->currentScanlineOfBand(2));
+
+                    ImageRowIterator is(image_iterator.rowIterator());
+                    const ImageRowIterator is_end(is + width);
+
+                    while (is != is_end)
+                    {
+                        *scanline_0 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 0)));
+                        *scanline_1 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 1)));
+                        *scanline_2 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 2)));
+
+                        scanline_0 += offset;
+                        scanline_1 += offset;
+                        scanline_2 += offset;
+
+                        ++is;
+                    }
+
+                    encoder->nextScanline();
+
+                    ++image_iterator.y;
+                }
+            }
+            else
+            {
+                std::vector<ValueType*> scanlines(accessor_size);
+
+                for (unsigned y = 0U; y != height; ++y)
+                {
+                    for (unsigned i = 0U; i != accessor_size; ++i)
+                    {
+                        scanlines[i] = static_cast<ValueType*>(encoder->currentScanlineOfBand(i));
+                    }
+
+                    ImageRowIterator is(image_iterator.rowIterator());
+                    const ImageRowIterator is_end(is + width);
+
+                    while (is != is_end)
+                    {
+                        for (unsigned i = 0U; i != accessor_size; ++i)
+                        {
+                            *scanlines[i] = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, static_cast<int>(i))));
+                            scanlines[i] += offset;
+                        }
+                        ++is;
+                    }
+
+                    encoder->nextScanline();
+
+                    ++image_iterator.y;
+                }
+            }
+        }
+
+
+        template <class ImageIterator, class ImageAccessor>
+        void
+        exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
+                    const ImageExportInfo& export_info,
+                    /* isScalar? */ VigraTrueType)
+        {
+            typedef typename ImageAccessor::value_type ImageValueType;
+
+            VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
+
+            std::string pixel_type(export_info.getPixelType());
+            const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
+            const pixel_t type(pixel_t_of_string(pixel_type));
+
+            encoder->setPixelType(pixel_type);
+
+            const range_t image_source_range(find_source_value_range(export_info,
+                                                                     image_upper_left, image_lower_right, image_accessor));
+            const range_t destination_range(find_destination_value_range(export_info, type));
+
+            if ((downcast || export_info.hasForcedRangeMapping()) &&
+                (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
+            {
+                const linear_transform image_rescaler(image_source_range, destination_range);
+
+                switch (type)
+                {
+                case UNSIGNED_INT_8:
+                    write_image_band<UInt8>(encoder.get(),
+                                            image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case UNSIGNED_INT_16:
+                    write_image_band<UInt16>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case UNSIGNED_INT_32:
+                    write_image_band<UInt32>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case SIGNED_INT_16:
+                    write_image_band<Int16>(encoder.get(),
+                                            image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case SIGNED_INT_32:
+                    write_image_band<Int32>(encoder.get(),
+                                            image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case IEEE_FLOAT_32:
+                    write_image_band<float>(encoder.get(),
+                                            image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case IEEE_FLOAT_64:
+                    write_image_band<double>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                default:
+                    vigra_fail("vigra::detail::exportImage<scalar>: not reached");
+                }
+            }
+            else
+            {
+                switch (type)
+                {
+                case UNSIGNED_INT_8:
+                    write_image_band<UInt8>(encoder.get(),
+                                            image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case UNSIGNED_INT_16:
+                    write_image_band<UInt16>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case UNSIGNED_INT_32:
+                    write_image_band<UInt32>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case SIGNED_INT_16:
+                    write_image_band<Int16>(encoder.get(),
+                                            image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case SIGNED_INT_32:
+                    write_image_band<Int32>(encoder.get(),
+                                            image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case IEEE_FLOAT_32:
+                    write_image_band<float>(encoder.get(),
+                                            image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case IEEE_FLOAT_64:
+                    write_image_band<double>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                default:
+                    vigra_fail("vigra::detail::exportImage<scalar>: not reached");
+                }
+            }
+
+            encoder->close();
+        }
+
+
+        template <class ImageIterator, class ImageAccessor>
+        void
+        exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
+                    const ImageExportInfo& export_info,
+                    /* isScalar? */ VigraFalseType)
+        {
+            typedef typename ImageAccessor::value_type ImageBaseType;
+            typedef typename ImageBaseType::value_type ImageValueType;
+
+            VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
+
+            std::string pixel_type(export_info.getPixelType());
+            const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
+            const pixel_t type(pixel_t_of_string(pixel_type));
+
+            encoder->setPixelType(pixel_type);
+
+            vigra_precondition(isBandNumberSupported(encoder->getFileType(), image_accessor.size(image_upper_left)),
+                               "exportImage(): file format does not support requested number of bands (color channels)");
+
+            const range_t image_source_range(find_source_value_range(export_info,
+                                                                     image_upper_left, image_lower_right, image_accessor));
+            const range_t destination_range(find_destination_value_range(export_info, pixel_t_of_string(pixel_type)));
+
+            if ((downcast || export_info.hasForcedRangeMapping()) &&
+                (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
+            {
+                const linear_transform image_rescaler(image_source_range, destination_range);
+
+                switch (type)
+                {
+                case UNSIGNED_INT_8:
+                    write_image_bands<UInt8>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case UNSIGNED_INT_16:
+                    write_image_bands<UInt16>(encoder.get(),
+                                              image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case UNSIGNED_INT_32:
+                    write_image_bands<UInt32>(encoder.get(),
+                                              image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case SIGNED_INT_16:
+                    write_image_bands<Int16>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case SIGNED_INT_32:
+                    write_image_bands<Int32>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case IEEE_FLOAT_32:
+                    write_image_bands<float>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                case IEEE_FLOAT_64:
+                    write_image_bands<double>(encoder.get(),
+                                              image_upper_left, image_lower_right, image_accessor, image_rescaler);
+                    break;
+                default:
+                    vigra_fail("vigra::detail::exportImage<non-scalar>: not reached");
+                }
+            }
+            else
+            {
+                switch (type)
+                {
+                case UNSIGNED_INT_8:
+                    write_image_bands<UInt8>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case UNSIGNED_INT_16:
+                    write_image_bands<UInt16>(encoder.get(),
+                                              image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case UNSIGNED_INT_32:
+                    write_image_bands<UInt32>(encoder.get(),
+                                              image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case SIGNED_INT_16:
+                    write_image_bands<Int16>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case SIGNED_INT_32:
+                    write_image_bands<Int32>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case IEEE_FLOAT_32:
+                    write_image_bands<float>(encoder.get(),
+                                             image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                case IEEE_FLOAT_64:
+                    write_image_bands<double>(encoder.get(),
+                                              image_upper_left, image_lower_right, image_accessor, identity());
+                    break;
+                default:
+                    vigra_fail("vigra::detail::exportImage<non-scalar>: not reached");
+                }
+            }
+
+            encoder->close();
+        }
+    }  // end namespace detail
+
+    /** 
+    \brief Read an image from a file.
+   
+    If the first parameter is \ref vigra::ImageImportInfo, this function assumes that the destination
+    image has already the appropriate shape. If the first parameter is a string, the destination
+    must be a \ref vigra::MultiArray reference, which will be reshaped automatically.
+    
+    If the input image has only a single band, but the destination has multiple bands (e.g. is an RGB
+    image), all bands will receive the same data. When a multi-band file is read into a single-band 
+    destination array, only the first band is read. Any other mismatch between the number of bands in
+    input and output is an error and will throw a precondition exception.
+    
+    <B>Declarations</B>
+   
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // read the data into an array view of appropriate size
+        template <class T, class S>
+        void
+        importImage(ImageImportInfo const & import_info,
+                    MultiArrayView<2, T, S> image);
+
+        // resize the given array and then read the data
+        template <class T, class A>
+        void
+        importImage(char const * filename,
+                    MultiArray<2, T, A> & image);
+
+        template <class T, class A>
+        void
+        importImage(std::string const & filename,
+                    MultiArray<2, T, A> & image);
+    }
+    \endcode
+   
+    \deprecatedAPI{importImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        void
+        importImage(const ImageImportInfo& importInfo,
+                    ImageIterator imageIterator, Accessor imageAccessor)
+    }
+    \endcode
+    Use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        void
+        importImage(const ImageImportInfo& importInfo,
+                    const pair<ImageIterator, Accessor>& image)
+    }
+    \endcode
+    \deprecatedEnd
+   
+    <b> Usage:</b>
+   
+    <B>\#include</B> \<vigra/impex.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    ImageImportInfo info("myimage.gif");
+
+    if (info.isGrayscale())
+    {
+        // create byte image of appropriate size
+        MultiArray<2, unsigned char> image(info.width(), info.height());
+
+        importImage(info, image);
+        ...
+    }
+    else
+    {
+        // create byte RGB image of appropriate size
+        MultiArray<2, RGBValue<unsigned char> > image(info.width(), info.height());
+
+        importImage(info, image);
+        ...
+    }
+    \endcode
+    When the type of input image is already known, this can be shortened:
+    \code
+    // create empty float image
+    MultiArray<2, float> image;
+    
+    // resize image and read the data
+    importImage("myimage.png", image);
+    \endcode
+
+    \deprecatedUsage{importImage}
+    \code
+        ImageImportInfo info("myimage.gif");
+   
+        if (info.isGrayscale())
+        {
+            // create byte image of appropriate size
+            BImage image(info.width(), info.height());
+   
+            importImage(info, destImage(image));
+            ...
+        }
+        else
+        {
+            // create byte RGB image of appropriate size
+            BRGBImage image(info.width(), info.height());
+   
+            importImage(info, destImage(image));
+            ...
+        }
+    \endcode
+    \deprecatedEnd
+   
+    <B>Preconditions</B>
+   
+    - The image file must be readable.
+    - The required support library must be installed (if the table doesn't specify an external library, 
+      VIGRA supports the format natively).
+    - The file type must be one of the following:
+   
+    <table cellspacing="10">
+    <tr align="left">
+    <th>Type</th><th> Extension </th><th> Name                           </th><th> Support Library </th>
+    </tr><tr>
+       <td> BMP  </td><td> bmp       </td><td> Microsoft Windows bitmap image file                        </td><td> </td>
+       </tr><tr>
+       <td> EXR  </td><td> exr       </td><td> OpenEXR high dynamic range image format                    </td><td> libopenexr </td>
+       </tr><tr>
+       <td> GIF  </td><td> gif       </td><td> CompuServe graphics interchange format, 8-bit color        </td><td> </td>
+       </tr><tr>
+       <td> HDR  </td><td> hdr       </td><td> Radiance RGBE high dynamic range image format              </td><td> </td>
+       </tr><tr>
+       <td> JPEG </td><td> jpg, jpeg </td><td> Joint Photographic Experts Group JFIF format, 24-bit color </td><td> libjpeg </td>
+       </tr><tr>
+       <td> PBM  </td><td> pbm       </td><td> Portable bitmap format (black and white)                   </td><td> </td>
+       </tr><tr>
+       <td> PGM  </td><td> pgm       </td><td> Portable graymap format (gray scale)                       </td><td> </td>
+       </tr><tr>
+       <td> PNG  </td><td> png       </td><td> Portable Network Graphic                                   </td><td> libpng </td>
+       </tr><tr>
+       <td> PNM  </td><td> pnm       </td><td> Portable anymap                                            </td><td> </td>
+       </tr><tr>
+       <td> PPM  </td><td> ppm       </td><td> Portable pixmap format (color)                             </td><td> </td>
+       </tr><tr>
+       <td> SUN  </td><td> ras       </td><td> SUN Rasterfile                                             </td><td> </td>
+       </tr><tr>
+       <td> TIFF </td><td> tif, tiff </td><td> Tagged Image File Format                                   </td><td> libtiff </td>
+       </tr><tr>
+       <td> VIFF </td><td> xv        </td><td> Khoros Visualization image file                            </td><td> </td>
+       </table>
+*/
+    doxygen_overloaded_function(template <...> void importImage)
+
+
+    template <class ImageIterator, class ImageAccessor>
+    inline void
+    importImage(const ImageImportInfo& import_info,
+                ImageIterator image_iterator, ImageAccessor image_accessor)
+    {
+        typedef typename ImageAccessor::value_type ImageValueType;
+        typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
+
+        detail::importImage(import_info,
+                    image_iterator, image_accessor,
+                    is_scalar());
+    }
+
+
+    template <class ImageIterator, class ImageAccessor>
+    inline void
+    importImage(ImageImportInfo const & import_info,
+                pair<ImageIterator, ImageAccessor> image)
+    {
+        importImage(import_info,
+                    image.first, image.second);
+    }
+
+    template <class T, class S>
+    inline void
+    importImage(ImageImportInfo const & import_info,
+                MultiArrayView<2, T, S> image)
+    {
+        vigra_precondition(import_info.shape() == image.shape(),
+            "importImage(): shape mismatch between input and output.");
+        importImage(import_info, destImage(image));
+    }
+
+    template <class T, class A>
+    inline void
+    importImage(char const * name,
+                MultiArray<2, T, A> & image)
+    {
+        ImageImportInfo info(name);
+        image.reshape(info.shape());
+        importImage(info, destImage(image));
+    }
+
+    template <class T, class A>
+    inline void
+    importImage(std::string const & name,
+                MultiArray<2, T, A> & image)
+    {
+        importImage(name.c_str(), image);
+    }
+
+    /** \brief Write an image to a file.
+    
+    The file can be specified either by a file name or by a \ref vigra::ImageExportInfo object.
+    In the latter case, you have much more control about how the file is written. By default,
+    the file format to be created is guessed from the filename extension. This can be 
+    overridden by an explicit file type in the ImageExportInfo object. If the file format
+    supports compression (e.g. JPEG and TIFF), default compression parameters are used
+    which can be overridden by the ImageExportInfo object.
+    
+    If the file format to be created supports the pixel type of the source image, this
+    pixel type will be kept in the file (e.g. <tt>float</tt> can be stored by TIFF without 
+    conversion) unless the ImageExportInfo object
+    explicitly requests a different storage type. If the array's pixel type is not supported by 
+    the file format, the pixel values are transformed to the range 0..255 and
+    converted to <tt>unsigned char</tt>, unless another mapping is explicitly requested by
+    the ImageExportInfo object.  
+    
+    Currently, the following file formats are supported.  The pixel types given in brackets
+    are those that are written without conversion:
+        - BMP: Microsoft Windows bitmap image file (pixel types: UINT8 as gray and RGB);
+        - GIF: CompuServe graphics interchange format, 8-bit color (pixel types: UINT8 as gray and RGB);
+        - JPEG: Joint Photographic Experts Group JFIF format, compressed 24-bit color
+                (pixel types: UINT8 as gray and RGB), only available if libjpeg is installed;
+        - PNG: Portable Network Graphic (pixel types: UINT8 and UINT16 with up to 4 channels),
+                only available if libpng is installed;
+        - PBM: Portable bitmap format (black and white);
+        - PGM: Portable graymap format (pixel types: UINT8, INT16, INT32 as gray scale);
+        - PNM: Portable anymap (pixel types: UINT8, INT16, INT32 as gray and RGB);
+        - PPM: Portable pixmap format (pixel types: UINT8, INT16, INT32 as RGB);
+        - SUN: SUN Rasterfile (pixel types: UINT8 as gray and RGB);
+        - TIFF: Tagged Image File Format
+              (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with up to 4 channels),
+              only available if libtiff is installed;
+        - VIFF: Khoros Visualization image file
+              (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with arbitrary many channels);
+    
+    <B>Declarations</B>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S>
+        void
+        exportImage(MultiArrayView<2, T, S> const & image,
+                    ImageExportInfo const & export_info);
+
+        template <class T, class S>
+        void
+        exportImage(MultiArrayView<2, T, S> const & image,
+                    char const * filename);
+
+        template <class T, class S>
+        void
+        exportImage(MultiArrayView<2, T, S> const & image,
+                    std::string const & filename);
+    }
+    \endcode
+    
+    \deprecatedAPI{exportImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class ImageAccessor>
+        void
+        exportImage(ImageIterator imageUpperLeft, ImageIterator imageLowerRight, ImageAccessor imageAccessor,
+                    const ImageExportInfo& exportInfo)
+    }
+    \endcode
+    Use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+        namespace vigra {
+            template <class ImageIterator, class ImageAccessor>
+            void exportImage(ImageIterator imageUpperLeft, ImageIterator imageLowerRight, ImageAccessor imageAccessor,
+                             const ImageExportInfo& exportInfo)
+        }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <B>\#include</B> \<vigra/impex.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, RGBValue<unsigned char> > image(width, height);
+    ...
+
+    // write as JPEG image, using compression quality 80
+    exportImage(image,
+                ImageExportInfo("my-image.jpg").setCompression("80"));
+
+    // Force it to a particular pixel type.  The pixel type must be supported by the
+    // desired image file format, otherwise an \ref vigra::PreconditionViolation
+    // exception will be thrown.
+    exportImage(image,
+                ImageExportInfo("my-INT16-image.tif").setPixelType("INT16"));
+    \endcode
+
+    \deprecatedUsage{exportImage}
+    \code
+    BRGBImage image(width, height);
+    ...
+
+    // write as JPEG image, using compression quality 80
+    exportImage(srcImageRange(image),
+                ImageExportInfo("my-image.jpg").setCompression("80"));
+
+    // Force it to a particular pixel type.  The pixel type must be supported by the
+    // desired image file format, otherwise an \ref vigra::PreconditionViolation
+    // exception will be thrown.
+    exportImage(srcImageRange(image),
+                ImageExportInfo("my-INT16-image.tif").setPixelType("INT16"));
+    \endcode
+    \deprecatedEnd
+    
+    <B>Preconditions</B>
+    
+    - The image file must be writable and
+    - the file type must be one of the supported file types.
+*/
+    doxygen_overloaded_function(template <...> void exportImage)
+
+
+    template <class ImageIterator, class ImageAccessor>
+    inline void
+    exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
+                const ImageExportInfo& export_info)
+    {
+        typedef typename ImageAccessor::value_type ImageValueType;
+        typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
+
+        try
+        {
+            detail::exportImage(image_upper_left, image_lower_right, image_accessor,
+                        export_info,
+                        is_scalar());
+        }
+        catch (Encoder::TIFFCompressionException&)
+        {
+            ImageExportInfo info(export_info);
+
+            info.setCompression("");
+            detail::exportImage(image_upper_left, image_lower_right, image_accessor,
+                                   info,
+                                   is_scalar());
+        }
+    }
+
+    template <class ImageIterator, class ImageAccessor>
+    inline void
+    exportImage(triple<ImageIterator, ImageIterator, ImageAccessor> image,
+                ImageExportInfo const & export_info)
+    {
+        exportImage(image.first, image.second, image.third,
+                    export_info);
+    }
+
+    template <class T, class S>
+    inline void
+    exportImage(MultiArrayView<2, T, S> const & image,
+                ImageExportInfo const & export_info)
+    {
+        exportImage(srcImageRange(image), export_info);
+    }
+
+    template <class T, class S>
+    inline void
+    exportImage(MultiArrayView<2, T, S> const & image,
+                char const * name)
+    {
+        ImageExportInfo export_info(name);
+        exportImage(srcImageRange(image), export_info);
+    }
+
+    template <class T, class S>
+    inline void
+    exportImage(MultiArrayView<2, T, S> const & image,
+                std::string const & name)
+    {
+        ImageExportInfo export_info(name.c_str());
+        exportImage(srcImageRange(image), export_info);
+    }
+
+/** @} */
+
+} // end namespace vigra
+
+#endif // VIGRA_IMPEX_HXX
diff --git a/include/vigra/impexalpha.hxx b/include/vigra/impexalpha.hxx
new file mode 100644
index 0000000..0426d67
--- /dev/null
+++ b/include/vigra/impexalpha.hxx
@@ -0,0 +1,1105 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2012 Christoph Spiel                         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEXALPHA_HXX
+#define VIGRA_IMPEXALPHA_HXX
+
+#include <vector>
+
+#include "imageinfo.hxx"
+#include "impex.hxx"
+#include "impexbase.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra
+{
+/** \addtogroup VigraImpex
+ * @{
+*/
+    namespace detail
+    {
+        template <class ValueType,
+                  class ImageIterator, class ImageAccessor,
+                  class AlphaIterator, class AlphaAccessor>
+        void
+        read_image_band_and_alpha(Decoder* decoder,
+                                  ImageIterator image_iterator, ImageAccessor image_accessor,
+                                  AlphaIterator alpha_iterator, AlphaAccessor alpha_accessor)
+        {
+            typedef typename ImageIterator::row_iterator ImageRowIterator;
+            typedef typename AlphaIterator::row_iterator AlphaRowIterator;
+
+            vigra_precondition(decoder->getNumExtraBands() == 1,
+                               "vigra::detail::read_image_band_and_alpha: expecting exactly one alpha band");
+            vigra_precondition(decoder->getNumBands() - decoder->getNumExtraBands() == 1,
+                               "vigra::detail::read_image_band_and_alpha: expecting exactly one image band");
+
+            const unsigned width(decoder->getWidth());
+            const unsigned height(decoder->getHeight());
+            const unsigned offset(decoder->getOffset());
+
+            for (unsigned y = 0U; y != height; ++y)
+            {
+                decoder->nextScanline();
+
+                const ValueType* scanline0 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0));
+                const ValueType* scanline1 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(1));
+
+                ImageRowIterator is(image_iterator.rowIterator());
+                const ImageRowIterator is_end(is + width);
+                AlphaRowIterator as(alpha_iterator.rowIterator());
+
+                while (is != is_end)
+                {
+                    image_accessor.set(*scanline0, is);
+                    scanline0 += offset;
+                    ++is;
+
+                    alpha_accessor.set(*scanline1, as);
+                    scanline1 += offset;
+                    ++as;
+                }
+
+                ++image_iterator.y;
+                ++alpha_iterator.y;
+            }
+        }
+
+
+        template <class ValueType,
+                  class ImageIterator, class ImageAccessor,
+                  class AlphaIterator, class AlphaAccessor>
+        void
+        read_image_bands_and_alpha(Decoder* decoder,
+                                   ImageIterator image_iterator, ImageAccessor image_accessor,
+                                   AlphaIterator alpha_iterator, AlphaAccessor alpha_accessor)
+        {
+            typedef typename ImageIterator::row_iterator ImageRowIterator;
+            typedef typename AlphaIterator::row_iterator AlphaRowIterator;
+
+            vigra_precondition(decoder->getNumExtraBands() == 1,
+                               "vigra::detail::read_image_bands_and_alpha: expecting exactly one alpha band");
+            vigra_precondition(decoder->getNumBands() - decoder->getNumExtraBands() == image_accessor.size(image_iterator),
+                               "vigra::detail::read_image_bands_and_alpha: number of channels and image accessor do not match");
+
+            const unsigned width(decoder->getWidth());
+            const unsigned height(decoder->getHeight());
+            const unsigned offset(decoder->getOffset());
+            const unsigned accessor_size(image_accessor.size(image_iterator));
+
+            // OPTIMIZATION: Specialization for the most common case
+            // of an RGBA-image, i.e. three color channels plus one
+            // alpha channel.
+            if (accessor_size == 3U)
+            {
+                const ValueType* scanline_0;
+                const ValueType* scanline_1;
+                const ValueType* scanline_2;
+                const ValueType* scanline_3; // alpha
+
+                for (unsigned y = 0U; y != height; ++y)
+                {
+                    decoder->nextScanline();
+
+                    scanline_0 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0));
+                    scanline_1 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(1));
+                    scanline_2 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(2));
+                    scanline_3 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(3));
+
+                    ImageRowIterator is(image_iterator.rowIterator());
+                    const ImageRowIterator is_end(is + width);
+                    AlphaRowIterator as(alpha_iterator.rowIterator());
+
+                    while (is != is_end)
+                    {
+                        image_accessor.setComponent(*scanline_0, is, 0);
+                        image_accessor.setComponent(*scanline_1, is, 1);
+                        image_accessor.setComponent(*scanline_2, is, 2);
+                        alpha_accessor.set(*scanline_3, as);
+                        scanline_0 += offset;
+                        scanline_1 += offset;
+                        scanline_2 += offset;
+                        scanline_3 += offset;
+
+                        ++is;
+                        ++as;
+                    }
+
+                    ++image_iterator.y;
+                    ++alpha_iterator.y;
+                }
+            }
+            else
+            {
+                std::vector<const ValueType*> scanlines(accessor_size + 1U);
+
+                for (unsigned y = 0U; y != height; ++y)
+                {
+                    decoder->nextScanline();
+
+                    for (unsigned i = 0U; i != accessor_size + 1U; ++i)
+                    {
+                        scanlines[i] = static_cast<const ValueType*>(decoder->currentScanlineOfBand(i));
+                    }
+
+                    ImageRowIterator is(image_iterator.rowIterator());
+                    const ImageRowIterator is_end(is + width);
+                    AlphaRowIterator as(alpha_iterator.rowIterator());
+
+                    while (is != is_end)
+                    {
+                        for (unsigned i = 0U; i != accessor_size; ++i)
+                        {
+                            image_accessor.setComponent(*scanlines[i], is, static_cast<int>(i));
+                            scanlines[i] += offset;
+                        }
+                        ++is;
+
+                        alpha_accessor.set(*scanlines[accessor_size], as);
+                        scanlines[accessor_size] += offset;
+                        ++as;
+                    }
+
+                    ++image_iterator.y;
+                    ++alpha_iterator.y;
+                }
+            }
+        }
+
+
+        template <class ImageIterator, class ImageAccessor,
+                  class AlphaIterator, class AlphaAccessor>
+        void
+        importImageAlpha(const ImageImportInfo& import_info,
+                         ImageIterator image_iterator, ImageAccessor image_accessor,
+                         AlphaIterator alpha_iterator, AlphaAccessor alpha_accessor,
+                         /* isScalar? */ VigraTrueType)
+        {
+            VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
+
+            switch (pixel_t_of_string(decoder->getPixelType()))
+            {
+            case UNSIGNED_INT_8:
+                read_image_band_and_alpha<UInt8>(decoder.get(),
+                                                 image_iterator, image_accessor,
+                                                 alpha_iterator, alpha_accessor);
+                break;
+            case UNSIGNED_INT_16:
+                read_image_band_and_alpha<UInt16>(decoder.get(),
+                                                  image_iterator, image_accessor,
+                                                  alpha_iterator, alpha_accessor);
+                break;
+            case UNSIGNED_INT_32:
+                read_image_band_and_alpha<UInt32>(decoder.get(),
+                                                  image_iterator, image_accessor,
+                                                  alpha_iterator, alpha_accessor);
+                break;
+            case SIGNED_INT_16:
+                read_image_band_and_alpha<Int16>(decoder.get(),
+                                                 image_iterator, image_accessor,
+                                                 alpha_iterator, alpha_accessor);
+                break;
+            case SIGNED_INT_32:
+                read_image_band_and_alpha<Int32>(decoder.get(),
+                                                 image_iterator, image_accessor,
+                                                 alpha_iterator, alpha_accessor);
+                break;
+            case IEEE_FLOAT_32:
+                read_image_band_and_alpha<float>(decoder.get(),
+                                                 image_iterator, image_accessor,
+                                                 alpha_iterator, alpha_accessor);
+                break;
+            case IEEE_FLOAT_64:
+                read_image_band_and_alpha<double>(decoder.get(),
+                                                  image_iterator, image_accessor,
+                                                  alpha_iterator, alpha_accessor);
+                break;
+            default:
+                vigra_fail("vigra::detail::importImageAlpha<scalar>: not reached");
+            }
+
+            decoder->close();
+        }
+
+
+        template <class ImageIterator, class ImageAccessor,
+                  class AlphaIterator, class AlphaAccessor>
+        void
+        importImageAlpha(const ImageImportInfo& import_info,
+                         ImageIterator image_iterator, ImageAccessor image_accessor,
+                         AlphaIterator alpha_iterator, AlphaAccessor alpha_accessor,
+                         /* isScalar? */ VigraFalseType)
+        {
+            VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
+
+            switch (pixel_t_of_string(decoder->getPixelType()))
+            {
+            case UNSIGNED_INT_8:
+                read_image_bands_and_alpha<UInt8>(decoder.get(),
+                                                  image_iterator, image_accessor,
+                                                  alpha_iterator, alpha_accessor);
+                break;
+            case UNSIGNED_INT_16:
+                read_image_bands_and_alpha<UInt16>(decoder.get(),
+                                                   image_iterator, image_accessor,
+                                                   alpha_iterator, alpha_accessor);
+                break;
+            case UNSIGNED_INT_32:
+                read_image_bands_and_alpha<UInt32>(decoder.get(),
+                                                   image_iterator, image_accessor,
+                                                   alpha_iterator, alpha_accessor);
+                break;
+            case SIGNED_INT_16:
+                read_image_bands_and_alpha<Int16>(decoder.get(),
+                                                  image_iterator, image_accessor,
+                                                  alpha_iterator, alpha_accessor);
+                break;
+            case SIGNED_INT_32:
+                read_image_bands_and_alpha<Int32>(decoder.get(),
+                                                  image_iterator, image_accessor,
+                                                  alpha_iterator, alpha_accessor);
+                break;
+            case IEEE_FLOAT_32:
+                read_image_bands_and_alpha<float>(decoder.get(),
+                                                  image_iterator, image_accessor,
+                                                  alpha_iterator, alpha_accessor);
+                break;
+            case IEEE_FLOAT_64:
+                read_image_bands_and_alpha<double>(decoder.get(),
+                                                   image_iterator, image_accessor,
+                                                   alpha_iterator, alpha_accessor);
+                break;
+            default:
+                vigra_fail("vigra::detail::importImageAlpha<non-scalar>: not reached");
+            }
+
+            decoder->close();
+        }
+    } // end namespace detail
+
+
+    /**
+    
+    \brief Read the image specified by the given \ref
+    vigra::ImageImportInfo object including its alpha channel. 
+    
+    See \ref importImage() for more information.
+    
+    <B>Declarations</B>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        importImageAlpha(ImageImportInfo const & import_info,
+                         MultiArrayView<2, T1, S1> image,
+                         MultiArrayView<2, T2, S2> alpha);
+    }
+    \endcode
+    
+    \deprecatedAPI{importImageAlpha}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+        namespace vigra {
+            template <class ImageIterator, class ImageAccessor,
+                      class AlphaIterator, class AlphaAccessor>
+            void
+            importImageAlpha(const ImageImportInfo& importInfo,
+                             ImageIterator imageIterator, ImageAccessor imageAccessor,
+                             AlphaIterator alphaIterator, AlphaAccessor alphaAccessor)
+        }
+    \endcode
+    Use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+        namespace vigra {
+            template <class ImageIterator, class ImageAccessor,
+                      class AlphaIterator, class AlphaAccessor>
+            void
+            importImageAlpha(const ImageImportInfo& importInfo,
+                             const pair<ImageIterator, ImageAccessor>& image,
+                             const pair<AlphaIterator, AlphaAccessor>& alpha)
+        }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <B>\#include</B> \<vigra/impexalpha.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    typedef UInt8 value_t;
+    ImageImportInfo info("zorro.tif");
+
+    if (info.isGrayscale())
+    {
+        MultiArray<2, value_t> alpha(info.shape());
+        MultiArray<2, value_t> image(info.shape());
+
+        importImageAlpha(info, image, alpha);
+        ...
+    }
+    else
+    {
+        MultiArray<2, value_t>            alpha(info.shape());
+        MultiArray<2, RGBValue<value_t> > image(info.shape());
+
+        importImageAlpha(info, image, alpha);
+        ...
+    }
+    \endcode
+
+    \deprecatedUsage{importImageAlpha}
+    \code
+    typedef UInt8 value_t;
+    ImageImportInfo info("zorro.tif");
+
+    if (info.isGrayscale())
+    {
+        BasicImage<value_t> alpha(info.size());
+        BasicImage<value_t> image(info.size());
+
+        importImageAlpha(info,
+                         image.upperLeft(), image.accessor(),
+                         alpha.upperLeft(), alpha.accessor());
+        ...
+    }
+    else
+    {
+        BasicImage<value_t> alpha(info.size());
+        BasicImage<vigra::RGBValue<value_t> > image(info.size());
+
+        importImageAlpha(info,
+                         image.upperLeft(), image.accessor(),
+                         alpha.upperLeft(), alpha.accessor());
+        ...
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <B>Preconditions</B>
+    
+    - The same preconditions hold as for importImage(), however the
+      only image formats that support alpha channels are
+      + TIFF and
+      + PNG.
+      In particular, JPEG does <B>not</B> support alpha channels.
+    - The alpha channel always is scalar-valued, i.e. comprises a
+      single band.
+*/
+    doxygen_overloaded_function(template <...> void importImageAlpha)
+
+
+    template <class ImageIterator, class ImageAccessor,
+              class AlphaIterator, class AlphaAccessor>
+    inline void
+    importImageAlpha(const ImageImportInfo& import_info,
+                     ImageIterator image_iterator, ImageAccessor image_accessor,
+                     AlphaIterator alpha_iterator, AlphaAccessor alpha_accessor)
+    {
+        typedef typename ImageAccessor::value_type ImageValueType;
+        typedef typename vigra::NumericTraits<ImageValueType>::isScalar is_scalar;
+
+        detail::importImageAlpha(import_info,
+                                 image_iterator, image_accessor,
+                                 alpha_iterator, alpha_accessor,
+                                 is_scalar());
+    }
+
+
+    template <class ImageIterator, class ImageAccessor,
+              class AlphaIterator, class AlphaAccessor>
+    inline void
+    importImageAlpha(ImageImportInfo const & import_info,
+                     pair<ImageIterator, ImageAccessor> image,
+                     pair<AlphaIterator, AlphaAccessor> alpha)
+    {
+        importImageAlpha(import_info,
+                         image.first, image.second,
+                         alpha.first, alpha.second);
+    }
+
+    template <class T1, class S1,
+              class T2, class S2>
+    inline void
+    importImageAlpha(ImageImportInfo const & import_info,
+                     MultiArrayView<2, T1, S1> image,
+                     MultiArrayView<2, T2, S2> alpha)
+    {
+        vigra_precondition(import_info.shape() == image.shape() && import_info.shape() == alpha.shape(),
+            "importImageAlpha(): shape mismatch between input and output.");
+        importImageAlpha(import_info, destImage(image), destImage(alpha));
+    }
+
+
+    namespace detail
+    {
+        template<class ValueType,
+                 class ImageIterator, class ImageAccessor, class ImageScaler,
+                 class AlphaIterator, class AlphaAccessor, class AlphaScaler>
+        void
+        write_image_band_and_alpha(Encoder* encoder,
+                                   ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
+                                   const ImageScaler& image_scaler,
+                                   AlphaIterator alpha_upper_left, AlphaAccessor alpha_accessor,
+                                   const AlphaScaler& alpha_scaler)
+        {
+            typedef typename ImageIterator::row_iterator ImageRowIterator;
+            typedef typename AlphaIterator::row_iterator AlphaRowIterator;
+
+            typedef detail::RequiresExplicitCast<ValueType> explicit_cast;
+
+            vigra_precondition(image_lower_right.x >= image_upper_left.x,
+                               "vigra::detail::write_image_band_and_alpha: negative width");
+            vigra_precondition(image_lower_right.y >= image_upper_left.y,
+                               "vigra::detail::write_image_band_and_alpha: negative height");
+
+            const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
+            const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
+
+            encoder->setWidth(width);
+            encoder->setHeight(height);
+            encoder->setNumBands(1 + 1);
+            encoder->finalizeSettings();
+
+            const unsigned offset(encoder->getOffset()); // correct offset only _after_ finalizeSettings()
+
+            // IMPLEMENTATION NOTE: We avoid calling the default constructor
+            // to allow classes ImageIterator and AlphaIterator that do not
+            // define one.
+            ImageIterator image_iterator(image_upper_left);
+            AlphaIterator alpha_iterator(alpha_upper_left);
+
+            for (unsigned y = 0U; y != height; ++y)
+            {
+                ValueType* scanline0 = static_cast<ValueType*>(encoder->currentScanlineOfBand(0));
+                ValueType* scanline1 = static_cast<ValueType*>(encoder->currentScanlineOfBand(1));
+
+                ImageRowIterator is(image_iterator.rowIterator());
+                const ImageRowIterator is_end(is + width);
+                AlphaRowIterator as(alpha_iterator.rowIterator());
+
+                while (is != is_end)
+                {
+                    *scanline0 = explicit_cast::cast(image_scaler(image_accessor(is)));
+                    scanline0 += offset;
+                    ++is;
+
+                    *scanline1 = explicit_cast::cast(alpha_scaler(alpha_accessor(as)));
+                    scanline1 += offset;
+                    ++as;
+                }
+
+                encoder->nextScanline();
+
+                ++image_iterator.y;
+                ++alpha_iterator.y;
+            }
+        }
+
+
+        template<class ValueType,
+                 class ImageIterator, class ImageAccessor, class ImageScaler,
+                 class AlphaIterator, class AlphaAccessor, class AlphaScaler>
+        void
+        write_image_bands_and_alpha(Encoder* encoder,
+                                    ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
+                                    const ImageScaler& image_scaler,
+                                    AlphaIterator alpha_upper_left, AlphaAccessor alpha_accessor,
+                                    const AlphaScaler& alpha_scaler)
+        {
+            typedef typename ImageIterator::row_iterator ImageRowIterator;
+            typedef typename AlphaIterator::row_iterator AlphaRowIterator;
+            typedef detail::RequiresExplicitCast<ValueType> explicit_cast;
+
+            vigra_precondition(image_lower_right.x >= image_upper_left.x,
+                               "vigra::detail::write_image_bands_and_alpha: negative width");
+            vigra_precondition(image_lower_right.y >= image_upper_left.y,
+                               "vigra::detail::write_image_bands_and_alpha: negative height");
+
+            const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
+            const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
+            const unsigned accessor_size(image_accessor.size(image_upper_left));
+
+            encoder->setWidth(width);
+            encoder->setHeight(height);
+            encoder->setNumBands(accessor_size + 1U);
+            encoder->finalizeSettings();
+
+            const unsigned offset(encoder->getOffset()); // correct offset only _after_ finalizeSettings()
+
+            // IMPLEMENTATION NOTE: We avoid calling the default constructor
+            // to allow classes ImageIterator and AlphaIterator that do not
+            // define one.
+            ImageIterator image_iterator(image_upper_left);
+            AlphaIterator alpha_iterator(alpha_upper_left);
+
+            // OPTIMIZATION: Specialization for the most common case
+            // of an RGBA-image, i.e. three color channels plus one
+            // alpha channel.
+            if (accessor_size == 3U)
+            {
+                ValueType* scanline_0;
+                ValueType* scanline_1;
+                ValueType* scanline_2;
+                ValueType* scanline_3; // alpha
+
+                for (unsigned y = 0U; y != height; ++y)
+                {
+                    scanline_0 = static_cast<ValueType*>(encoder->currentScanlineOfBand(0));
+                    scanline_1 = static_cast<ValueType*>(encoder->currentScanlineOfBand(1));
+                    scanline_2 = static_cast<ValueType*>(encoder->currentScanlineOfBand(2));
+                    scanline_3 = static_cast<ValueType*>(encoder->currentScanlineOfBand(3));
+
+                    ImageRowIterator is(image_iterator.rowIterator());
+                    const ImageRowIterator is_end(is + width);
+                    AlphaRowIterator as(alpha_iterator.rowIterator());
+
+                    while (is != is_end)
+                    {
+                        *scanline_0 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 0)));
+                        *scanline_1 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 1)));
+                        *scanline_2 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 2)));
+                        *scanline_3 = explicit_cast::cast(alpha_scaler(alpha_accessor(as)));
+                        scanline_0 += offset;
+                        scanline_1 += offset;
+                        scanline_2 += offset;
+                        scanline_3 += offset;
+
+                        ++is;
+                        ++as;
+                    }
+
+                    encoder->nextScanline();
+
+                    ++image_iterator.y;
+                    ++alpha_iterator.y;
+                }
+            }
+            else
+            {
+                std::vector<ValueType*> scanlines(accessor_size + 1U);
+
+                for (unsigned y = 0U; y != height; ++y)
+                {
+                    for (unsigned i = 0U; i != accessor_size + 1U; ++i)
+                    {
+                        scanlines[i] = static_cast<ValueType*>(encoder->currentScanlineOfBand(i));
+                    }
+
+                    ImageRowIterator is(image_iterator.rowIterator());
+                    const ImageRowIterator is_end(is + width);
+                    AlphaRowIterator as(alpha_iterator.rowIterator());
+
+                    while (is != is_end)
+                    {
+                        for (unsigned i = 0U; i != accessor_size; ++i)
+                        {
+                            *scanlines[i] = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, static_cast<int>(i))));
+                            scanlines[i] += offset;
+                        }
+                        ++is;
+
+                        *scanlines[accessor_size] = explicit_cast::cast(alpha_scaler(alpha_accessor(as)));
+                        scanlines[accessor_size] += offset;
+                        ++as;
+                    }
+
+                    encoder->nextScanline();
+
+                    ++image_iterator.y;
+                    ++alpha_iterator.y;
+                }
+            }
+        }
+
+
+        template <class ImageIterator, class ImageAccessor,
+                  class AlphaIterator, class AlphaAccessor>
+        void
+        exportImageAlpha(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
+                         AlphaIterator alpha_upper_left, AlphaAccessor alpha_accessor,
+                         const ImageExportInfo& export_info,
+                         /* isScalar? */ VigraTrueType)
+        {
+            typedef typename ImageAccessor::value_type ImageValueType;
+
+            VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
+
+            std::string pixel_type(export_info.getPixelType());
+            const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
+            const pixel_t type(pixel_t_of_string(pixel_type));
+
+            encoder->setPixelType(pixel_type);
+
+            const range_t image_source_range(find_source_value_range(export_info,
+                                                                     image_upper_left, image_lower_right, image_accessor));
+            const range_t alpha_source_range(find_source_value_range(export_info,
+                                                                     alpha_upper_left,
+                                                                     alpha_upper_left + (image_lower_right - image_upper_left),
+                                                                     alpha_accessor));
+            const range_t destination_range(find_destination_value_range(export_info, type));
+
+            if ((downcast || export_info.hasForcedRangeMapping()) &&
+                (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second ||
+                 alpha_source_range.first != destination_range.first || alpha_source_range.second != destination_range.second))
+            {
+                const linear_transform image_rescaler(image_source_range, destination_range);
+                const linear_transform alpha_rescaler(alpha_source_range, destination_range);
+
+                switch (type)
+                {
+                case UNSIGNED_INT_8:
+                    write_image_band_and_alpha<UInt8>(encoder.get(),
+                                                      image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                      alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case UNSIGNED_INT_16:
+                    write_image_band_and_alpha<UInt16>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                       alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case UNSIGNED_INT_32:
+                    write_image_band_and_alpha<UInt32>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                       alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case SIGNED_INT_16:
+                    write_image_band_and_alpha<Int16>(encoder.get(),
+                                                      image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                      alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case SIGNED_INT_32:
+                    write_image_band_and_alpha<Int32>(encoder.get(),
+                                                      image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                      alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case IEEE_FLOAT_32:
+                    write_image_band_and_alpha<float>(encoder.get(),
+                                                      image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                      alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case IEEE_FLOAT_64:
+                    write_image_band_and_alpha<double>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                       alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                default:
+                    vigra_fail("vigra::detail::exportImageAlpha<scalar>: not reached");
+                }
+            }
+            else
+            {
+                switch (type)
+                {
+                case UNSIGNED_INT_8:
+                    write_image_band_and_alpha<UInt8>(encoder.get(),
+                                                      image_upper_left, image_lower_right, image_accessor, identity(),
+                                                      alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case UNSIGNED_INT_16:
+                    write_image_band_and_alpha<UInt16>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, identity(),
+                                                       alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case UNSIGNED_INT_32:
+                    write_image_band_and_alpha<UInt32>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, identity(),
+                                                       alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case SIGNED_INT_16:
+                    write_image_band_and_alpha<Int16>(encoder.get(),
+                                                      image_upper_left, image_lower_right, image_accessor, identity(),
+                                                      alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case SIGNED_INT_32:
+                    write_image_band_and_alpha<Int32>(encoder.get(),
+                                                      image_upper_left, image_lower_right, image_accessor, identity(),
+                                                      alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case IEEE_FLOAT_32:
+                    write_image_band_and_alpha<float>(encoder.get(),
+                                                      image_upper_left, image_lower_right, image_accessor, identity(),
+                                                      alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case IEEE_FLOAT_64:
+                    write_image_band_and_alpha<double>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, identity(),
+                                                       alpha_upper_left, alpha_accessor, identity());
+                    break;
+                default:
+                    vigra_fail("vigra::detail::exportImageAlpha<scalar>: not reached");
+                }
+            }
+
+            encoder->close();
+        }
+
+
+        template <class ImageIterator, class ImageAccessor,
+                  class AlphaIterator, class AlphaAccessor>
+        void
+        exportImageAlpha(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
+                         AlphaIterator alpha_upper_left, AlphaAccessor alpha_accessor,
+                         const ImageExportInfo& export_info,
+                         /* isScalar? */ VigraFalseType)
+        {
+            typedef typename ImageAccessor::value_type ImageBaseType;
+            typedef typename ImageBaseType::value_type ImageValueType;
+
+            VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
+
+            std::string pixel_type(export_info.getPixelType());
+            const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
+            const pixel_t type(pixel_t_of_string(pixel_type));
+
+            encoder->setPixelType(pixel_type);
+
+            vigra_precondition(isBandNumberSupported(encoder->getFileType(), image_accessor.size(image_upper_left)),
+                               "exportImageAlpha(): file format does not support requested number of bands (color channels)");
+
+            const range_t image_source_range(find_source_value_range(export_info,
+                                                                     image_upper_left, image_lower_right, image_accessor));
+            const range_t alpha_source_range(find_source_value_range(export_info,
+                                                                     alpha_upper_left,
+                                                                     alpha_upper_left + (image_lower_right - image_upper_left),
+                                                                     alpha_accessor));
+            const range_t destination_range(find_destination_value_range(export_info, pixel_t_of_string(pixel_type)));
+
+            if ((downcast || export_info.hasForcedRangeMapping()) &&
+                (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second ||
+                 alpha_source_range.first != destination_range.first || alpha_source_range.second != destination_range.second))
+            {
+                const linear_transform image_rescaler(image_source_range, destination_range);
+                const linear_transform alpha_rescaler(alpha_source_range, destination_range);
+
+                switch (type)
+                {
+                case UNSIGNED_INT_8:
+                    write_image_bands_and_alpha<UInt8>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                       alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case UNSIGNED_INT_16:
+                    write_image_bands_and_alpha<UInt16>(encoder.get(),
+                                                        image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                        alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case UNSIGNED_INT_32:
+                    write_image_bands_and_alpha<UInt32>(encoder.get(),
+                                                        image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                        alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case SIGNED_INT_16:
+                    write_image_bands_and_alpha<Int16>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                       alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case SIGNED_INT_32:
+                    write_image_bands_and_alpha<Int32>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                       alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case IEEE_FLOAT_32:
+                    write_image_bands_and_alpha<float>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                       alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                case IEEE_FLOAT_64:
+                    write_image_bands_and_alpha<double>(encoder.get(),
+                                                        image_upper_left, image_lower_right, image_accessor, image_rescaler,
+                                                        alpha_upper_left, alpha_accessor, alpha_rescaler);
+                    break;
+                default:
+                    vigra_fail("vigra::detail::exportImageAlpha<non-scalar>: not reached");
+                }
+            }
+            else
+            {
+                switch (type)
+                {
+                case UNSIGNED_INT_8:
+                    write_image_bands_and_alpha<UInt8>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, identity(),
+                                                       alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case UNSIGNED_INT_16:
+                    write_image_bands_and_alpha<UInt16>(encoder.get(),
+                                                        image_upper_left, image_lower_right, image_accessor, identity(),
+                                                        alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case UNSIGNED_INT_32:
+                    write_image_bands_and_alpha<UInt32>(encoder.get(),
+                                                        image_upper_left, image_lower_right, image_accessor, identity(),
+                                                        alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case SIGNED_INT_16:
+                    write_image_bands_and_alpha<Int16>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, identity(),
+                                                       alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case SIGNED_INT_32:
+                    write_image_bands_and_alpha<Int32>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, identity(),
+                                                       alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case IEEE_FLOAT_32:
+                    write_image_bands_and_alpha<float>(encoder.get(),
+                                                       image_upper_left, image_lower_right, image_accessor, identity(),
+                                                       alpha_upper_left, alpha_accessor, identity());
+                    break;
+                case IEEE_FLOAT_64:
+                    write_image_bands_and_alpha<double>(encoder.get(),
+                                                        image_upper_left, image_lower_right, image_accessor, identity(),
+                                                        alpha_upper_left, alpha_accessor, identity());
+                    break;
+                default:
+                    vigra_fail("vigra::detail::exportImageAlpha<non-scalar>: not reached");
+                }
+            }
+
+            encoder->close();
+        }
+    } // end namespace detail
+
+
+    /**
+    \brief Write the image and its alpha channel to a file.
+    
+    See \ref exportImage() for more information.
+    
+    <B>Declarations</B>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        exportImageAlpha(MultiArrayView<2, T1, S1> const & image,
+                         MultiArrayView<2, T2, S2> const & alpha,
+                         ImageExportInfo const & export_info);
+
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        exportImageAlpha(MultiArrayView<2, T1, S1> const & image,
+                         MultiArrayView<2, T2, S2> const & alpha,
+                         char const * filename)
+
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        exportImageAlpha(MultiArrayView<2, T1, S1> const & image,
+                         MultiArrayView<2, T2, S2> const & alpha,
+                         std::string const & filename)
+    }
+    \endcode
+    
+    \deprecatedAPI{exportImageAlpha}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+        namespace vigra {
+            template <class ImageIterator, class ImageAccessor,
+                      class AlphaIterator, class AlphaAccessor>
+            void
+            exportImageAlpha(ImageIterator imageUpperLeft, ImageIterator imageLowerRight, ImageAccessor imageAccessor,
+                             AlphaIterator alphaUpperLeft, AlphaAccessor alphaAccessor,
+                             const ImageExportInfo& exportInfo)
+        }
+    \endcode
+    Use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+        namespace vigra {
+        template <class ImageIterator, class ImageAccessor,
+                  class AlphaIterator, class AlphaAccessor>
+        void
+        exportImageAlpha(const triple<ImageIterator, ImageIterator, ImageAccessor>& image,
+                         const pair<AlphaIterator, AlphaAccessor>& alpha,
+                         const ImageExportInfo& exportInfo)
+        }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <B>\#include</B> \<vigra/impexalpha.hxx\><br/>
+    Namespace: vigra
+    
+    \code
+    typedef UInt8 value_t;
+
+    MultiArray<2, value_t>            alpha(width, height);
+    MultiArray<2, RGBValue<value_t> > image(width, height);
+
+   ... // do some image processing
+
+    // specify the output filename 
+    exportImageAlpha(image, alpha, "zorro.tif");
+    
+    // use a ImageExportInfo if you need more control over the export
+    exportImageAlpha(image, alpha, ImageExportInfo("zorro.tif").setPixelType("FLOAT"));
+   \endcode
+
+    \deprecatedUsage{exportImageAlpha}
+    \code
+    typedef UInt8 value_t;
+    ImageExportInfo info("zorro.tif");
+
+    if (info.isGrayscale())
+    {
+        BasicImage<value_t> alpha;
+        BasicImage<value_t> image;
+
+        ...
+
+        exportImageAlpha(image.upperLeft(), image.lowerRight(), image.accessor(),
+                         alpha.upperLeft(), alpha.accessor(),
+                         info);
+    }
+    else
+    {
+        BasicImage<value_t> alpha;
+        BasicImage<vigra::RGBValue<value_t> > image;
+
+        ...
+
+        exportImageAlpha(image.upperLeft(), image.lowerRight(), image.accessor(),
+                         alpha.upperLeft(), alpha.accessor(),
+                         info);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <B>Preconditions</B>
+    
+    - The same preconditions hold as for exportImage(), however the
+      only image formats that support alpha channels are
+      + TIFF and
+      + PNG.
+      In particular, JPEG does <B>not</B> support alpha channels.
+    - The alpha channel always is scalar-valued, i.e. comprises a
+      single band.
+*/
+    doxygen_overloaded_function(template <...> void exportImageAlpha)
+
+
+    template <class ImageIterator, class ImageAccessor,
+              class AlphaIterator, class AlphaAccessor>
+    inline void
+    exportImageAlpha(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
+                     AlphaIterator alpha_upper_left, AlphaAccessor alpha_accessor,
+                     const ImageExportInfo& export_info)
+    {
+        typedef typename ImageAccessor::value_type ImageValueType;
+        typedef typename vigra::NumericTraits<ImageValueType>::isScalar is_scalar;
+
+        try
+        {
+            detail::exportImageAlpha(image_upper_left, image_lower_right, image_accessor,
+                                     alpha_upper_left, alpha_accessor,
+                                     export_info,
+                                     is_scalar());
+        }
+        catch (Encoder::TIFFCompressionException&)
+        {
+            ImageExportInfo info(export_info);
+
+            info.setCompression("");
+            detail::exportImageAlpha(image_upper_left, image_lower_right, image_accessor,
+                                     alpha_upper_left, alpha_accessor,
+                                     info,
+                                     is_scalar());
+        }
+    }
+
+
+    template <class ImageIterator, class ImageAccessor,
+              class AlphaIterator, class AlphaAccessor>
+    inline void
+    exportImageAlpha(triple<ImageIterator, ImageIterator, ImageAccessor> image,
+                     pair<AlphaIterator, AlphaAccessor> alpha,
+                     ImageExportInfo const & export_info)
+    {
+        exportImageAlpha(image.first, image.second, image.third,
+                         alpha.first, alpha.second,
+                         export_info);
+    }
+
+    template <class T1, class S1,
+              class T2, class S2>
+    inline void
+    exportImageAlpha(MultiArrayView<2, T1, S1> const & image,
+                     MultiArrayView<2, T2, S2> const & alpha,
+                     ImageExportInfo const & export_info)
+    {
+        exportImageAlpha(srcImageRange(image),
+                         srcImage(alpha),
+                         export_info);
+    }
+
+    template <class T1, class S1,
+              class T2, class S2>
+    inline void
+    exportImageAlpha(MultiArrayView<2, T1, S1> const & image,
+                     MultiArrayView<2, T2, S2> const & alpha,
+                     char const * name)
+    {
+        ImageExportInfo export_info(name);
+        exportImageAlpha(srcImageRange(image),
+                         srcImage(alpha),
+                         export_info);
+    }
+
+    template <class T1, class S1,
+              class T2, class S2>
+    inline void
+    exportImageAlpha(MultiArrayView<2, T1, S1> const & image,
+                     MultiArrayView<2, T2, S2> const & alpha,
+                     std::string const & name)
+    {
+        ImageExportInfo export_info(name.c_str());
+        exportImageAlpha(srcImageRange(image),
+                         srcImage(alpha),
+                         export_info);
+    }
+
+/** @} */
+    
+} // end namespace vigra
+
+#endif // VIGRA_IMPEXALPHA_HXX
diff --git a/include/vigra/impexbase.hxx b/include/vigra/impexbase.hxx
new file mode 100644
index 0000000..7a1fbc8
--- /dev/null
+++ b/include/vigra/impexbase.hxx
@@ -0,0 +1,236 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2012 Christoph Spiel                         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEXBASE_HXX
+#define VIGRA_IMPEXBASE_HXX
+
+
+#include <string>
+#include "inspectimage.hxx"
+#include "sized_int.hxx"
+#include "utilities.hxx"
+
+
+namespace vigra
+{
+    typedef enum
+    {
+        UNSIGNED_INT_8,
+        UNSIGNED_INT_16,
+        UNSIGNED_INT_32,
+        SIGNED_INT_16,
+        SIGNED_INT_32,
+        IEEE_FLOAT_32,
+        IEEE_FLOAT_64
+    } pixel_t;
+
+
+    namespace detail
+    {
+        inline static pixel_t
+        pixel_t_of_string(const std::string& pixel_type)
+        {
+            if (pixel_type == "UINT8")
+            {
+                return UNSIGNED_INT_8;
+            }
+            else if (pixel_type == "UINT16")
+            {
+                return UNSIGNED_INT_16;
+            }
+            else if (pixel_type == "UINT32")
+            {
+                return UNSIGNED_INT_32;
+            }
+            else if (pixel_type == "INT16")
+            {
+                return SIGNED_INT_16;
+            }
+            else if (pixel_type == "INT32")
+            {
+                return SIGNED_INT_32;
+            }
+            else if (pixel_type == "FLOAT")
+            {
+                return IEEE_FLOAT_32;
+            }
+            else if (pixel_type == "DOUBLE")
+            {
+                return IEEE_FLOAT_64;
+            }
+            else
+            {
+                vigra_fail("vigra_ext::detail::pixel_t_of_string: unknown pixel type");
+                return UNSIGNED_INT_8; // NOT REACHED
+            }
+        }
+
+
+        struct identity
+        {
+            template <typename T>
+            T operator()(T x) const
+            {
+                return x;
+            }
+        };
+
+
+        typedef pair<double, double> range_t;
+
+
+        class linear_transform
+        {
+        public:
+            linear_transform(const range_t& source, const range_t& destination) :
+                scale_((destination.second - destination.first) / (source.second - source.first)),
+                offset_(destination.first / scale_ - source.first)
+            {}
+
+            template <typename T>
+            double operator()(T x) const
+            {
+                return scale_ * (static_cast<double>(x) + offset_);
+            }
+
+        private:
+            const double scale_;
+            const double offset_;
+        };
+
+
+        template <class Iterator, class Accessor>
+        inline static range_t
+        find_value_range(Iterator upper_left, Iterator lower_right, Accessor accessor,
+                         /* is_scalar? */ VigraTrueType)
+        {
+            typedef typename Accessor::value_type value_type;
+
+            FindMinMax<value_type> extrema;
+
+            inspectImage(upper_left, lower_right, accessor, extrema);
+
+            return range_t(static_cast<double>(extrema.min), static_cast<double>(extrema.max));
+        }
+
+
+        template <class Iterator, class Accessor>
+        inline static range_t
+        find_value_range(Iterator upper_left, Iterator lower_right, Accessor accessor,
+                         /* is_scalar? */ VigraFalseType)
+        {
+            typedef typename Accessor::ElementAccessor element_accessor;
+            typedef typename element_accessor::value_type value_type;
+
+            const int number_of_bands(static_cast<int>(accessor.size(upper_left)));
+            FindMinMax<value_type> extrema;
+
+            for (int i = 0; i != number_of_bands; ++i)
+            {
+                element_accessor band(i, accessor);
+
+                inspectImage(upper_left, lower_right, band, extrema);
+            }
+
+            return range_t(static_cast<double>(extrema.min), static_cast<double>(extrema.max));
+        }
+
+
+        template <class SourceIterator, class SourceAccessor>
+        inline static range_t
+        find_source_value_range(const ImageExportInfo& export_info,
+                                SourceIterator upper_left, SourceIterator lower_right, SourceAccessor accessor)
+        {
+            if (export_info.getFromMin() < export_info.getFromMax())
+            {
+                return range_t(export_info.getFromMin(), export_info.getFromMax());
+            }
+            else
+            {
+                typedef typename SourceAccessor::value_type SourceValueType;
+                typedef typename NumericTraits<SourceValueType>::isScalar is_scalar;
+
+                const range_t range(find_value_range(upper_left, lower_right, accessor, is_scalar()));
+
+                if (range.first < range.second)
+                {
+                    return range_t(range.first, range.second);
+                }
+                else
+                {
+                    return range_t(range.first, range.first + 1.0);
+                }
+            }
+        }
+
+
+        template <typename T>
+        inline static range_t
+        find_destination_value_range(const ImageExportInfo& export_info)
+        {
+            if (export_info.getToMin() < export_info.getToMax())
+            {
+                return range_t(export_info.getToMin(), export_info.getToMax());
+            }
+            else
+            {
+                return range_t(static_cast<double>(NumericTraits<T>::min()),
+                               static_cast<double>(NumericTraits<T>::max()));
+            }
+        }
+
+
+        inline static range_t
+        find_destination_value_range(const ImageExportInfo& export_info, pixel_t pixel_type)
+        {
+            switch (pixel_type)
+            {
+            case UNSIGNED_INT_8: return find_destination_value_range<UInt8>(export_info);
+            case UNSIGNED_INT_16: return find_destination_value_range<UInt16>(export_info);
+            case UNSIGNED_INT_32: return find_destination_value_range<UInt32>(export_info);
+            case SIGNED_INT_16: return find_destination_value_range<Int16>(export_info);
+            case SIGNED_INT_32: return find_destination_value_range<Int32>(export_info);
+            case IEEE_FLOAT_32: return find_destination_value_range<float>(export_info);
+            case IEEE_FLOAT_64: return find_destination_value_range<double>(export_info);
+            default:
+                vigra_fail("vigra_ext::detail::find_destination_value_range: not reached");
+                return range_t(0.0, 0.0); // NOT REACHED
+            }
+        }
+    } // end namespace detail
+} // end namespace vigra
+
+
+#endif // VIGRA_IMPEXBASE_HXX
diff --git a/include/vigra/initimage.hxx b/include/vigra/initimage.hxx
new file mode 100644
index 0000000..3053abb
--- /dev/null
+++ b/include/vigra/initimage.hxx
@@ -0,0 +1,723 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_INITIMAGE_HXX
+#define VIGRA_INITIMAGE_HXX
+
+#include "utilities.hxx"
+#include "iteratortraits.hxx"
+#include "functortraits.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup InitAlgo Algorithms to Initialize Images
+    
+    Init images or image borders
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                       initLine                       */
+/*                                                      */
+/********************************************************/
+
+template <class DestIterator, class DestAccessor, class VALUETYPE>
+inline void
+initLineImpl(DestIterator d, DestIterator dend, DestAccessor dest,
+             VALUETYPE const & v, VigraFalseType)
+{
+    for(; d != dend; ++d)
+        dest.set(v, d);
+}
+
+template <class DestIterator, class DestAccessor, class FUNCTOR>
+inline void
+initLineImpl(DestIterator d, DestIterator dend, DestAccessor dest,
+             FUNCTOR const & f, VigraTrueType)
+{
+    for(; d != dend; ++d)
+        dest.set(f(), d);
+}
+
+template <class DestIterator, class DestAccessor, class VALUETYPE>
+inline void
+initLine(DestIterator d, DestIterator dend, DestAccessor dest,
+         VALUETYPE const & v)
+{
+    initLineImpl(d, dend, dest, v, typename FunctorTraits<VALUETYPE>::isInitializer());
+}
+
+template <class DestIterator, class DestAccessor, class FUNCTOR>
+inline void
+initLineFunctor(DestIterator d, DestIterator dend, DestAccessor dest,
+         FUNCTOR & f)
+{
+    for(; d != dend; ++d)
+        dest.set(f(), d);
+}
+
+template <class DestIterator, class DestAccessor, 
+          class MaskIterator, class MaskAccessor, 
+          class VALUETYPE>
+inline void
+initLineIfImpl(DestIterator d, DestIterator dend, DestAccessor dest,
+               MaskIterator m, MaskAccessor mask,
+               VALUETYPE const & v, VigraFalseType)
+{
+    for(; d != dend; ++d, ++m)
+        if(mask(m))
+            dest.set(v, d);
+}
+
+template <class DestIterator, class DestAccessor, 
+          class MaskIterator, class MaskAccessor, 
+          class FUNCTOR>
+inline void
+initLineIfImpl(DestIterator d, DestIterator dend, DestAccessor dest,
+               MaskIterator m, MaskAccessor mask,
+               FUNCTOR const & f, VigraTrueType)
+{
+    for(; d != dend; ++d, ++m)
+        if(mask(m))
+            dest.set(f(), d);
+}
+
+template <class DestIterator, class DestAccessor, 
+          class MaskIterator, class MaskAccessor, 
+          class VALUETYPE>
+inline void
+initLineIf(DestIterator d, DestIterator dend, DestAccessor dest,
+           MaskIterator m, MaskAccessor mask,
+           VALUETYPE const & v)
+{
+    initLineIfImpl(d, dend, dest, m, mask, v, typename FunctorTraits<VALUETYPE>::isInitializer());
+}
+
+template <class DestIterator, class DestAccessor, 
+          class MaskIterator, class MaskAccessor, 
+          class FUNCTOR>
+inline void
+initLineFunctorIf(DestIterator d, DestIterator dend, DestAccessor dest,
+                  MaskIterator m, MaskAccessor mask,
+                  FUNCTOR & f)
+{
+    for(; d != dend; ++d, ++m)
+        if(mask(m))
+            dest.set(f(), d);
+}
+
+/********************************************************/
+/*                                                      */
+/*                        initImage                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Write a value to every pixel in an image or rectangular ROI.
+
+    This function can be used to init the image.
+    
+    The initial value can either be a constant of appropriate type (compatible with 
+    the destination's value_type), or a functor with compatible result_type. These two 
+    cases are automatically distinguished when <tt>FunctorTraits<FUNCTOR>::isInitializer</tt>
+    yields <tt>VigraTrueType</tt>. Since the functor is passed by <tt>const</tt> reference, its 
+    <tt>operator()</tt> must be const, and its internal state may need to be <tt>mutable</tt>.
+    
+    Function \ref initMultiArray() implements the same functionality for arbitrary dimensional
+    arrays. In many situations, the assignment functions of \ref vigra::MultiArrayView offer
+    a simpler and more readable alternative to the init functions.
+
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S, class VALUETYPE>
+        void
+        initImage(MultiArrayView<2, T, S> img, VALUETYPE const & v);
+        
+        template <class T, class S, class FUNCTOR>
+        void
+        initImage(MultiArrayView<2, T, S> img, FUNCTOR const & v);
+    }
+    \endcode
+    
+    \deprecatedAPI{initImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor, class VALUETYPE>
+        void initImage(ImageIterator upperleft, ImageIterator lowerright, 
+                       Accessor a, VALUETYPE const & v);
+
+        template <class ImageIterator, class Accessor, class FUNCTOR>
+        void initImage(ImageIterator upperleft, ImageIterator lowerright, 
+                       Accessor a, FUNCTOR const & v);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor, class VALUETYPE>
+        void initImage(triple<ImageIterator, ImageIterator, Accessor> img, VALUETYPE const & v);
+
+        template <class ImageIterator, class Accessor, class FUNCTOR>
+        void initImage(triple<ImageIterator, ImageIterator, Accessor> img, FUNCTOR const & v);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/initimage.hxx\><br>
+    Namespace: vigra
+    
+    Initialize with a constant:
+    \code
+    MultiArray<2, unsigned char> img(100, 100);
+    
+    // init the image with the value 128
+    initImage(img, 128);
+    
+    // init the interior with the value 1
+    initImage(img.subarray(Shape2(10), Shape2(-10)), 1);
+    
+    // equivalent to
+    img = 128;
+    img.init(128);
+    img.subarray(Shape2(10), Shape2(-10)) = 1;
+    \endcode
+
+    Initialize with a functor:
+    \code
+    struct Counter {
+        Counter() : count(0) {}
+        
+        int operator()() const { return count++; }
+    
+        mutable int count;
+    };
+    
+    MultiArray<2, int> img(100, 100);
+        
+    // write the current count in every pixel
+    initImage(img, Counter());
+    
+    // equivalent to
+    #include <vigra/algorithm.hxx>
+    
+    linearSequence(img.begin(), img.end());
+    \endcode
+
+    \deprecatedUsage{initImage}
+    \code
+    vigra::BImage img(100, 100);
+    
+    // init the image with the value 128
+    vigra::initImage(destImageRange(img), 128);
+
+    // Initialize with a functor:
+    struct Counter {
+        Counter() : count(0) {}
+        
+        int operator()() const { return count++; }
+    
+        mutable int count;
+    };
+    
+    // write the current count in every pixel
+    vigra::initImage(destImageRange(img), Counter());
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator upperleft, lowerright;
+    ImageIterator::row_iterator ix = upperleft.rowIterator();
+    
+    Accessor accessor;
+    VALUETYPE v;
+    
+    accessor.set(v, ix); 
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void initImage)
+
+template <class ImageIterator, class Accessor, class VALUETYPE>
+void
+initImage(ImageIterator upperleft, ImageIterator lowerright, 
+          Accessor a,  VALUETYPE const & v)
+{
+    int w = lowerright.x - upperleft.x;
+    
+    for(; upperleft.y < lowerright.y; ++upperleft.y)
+    {
+        initLineImpl(upperleft.rowIterator(), upperleft.rowIterator() + w, a, 
+                     v, typename FunctorTraits<VALUETYPE>::isInitializer());
+    }
+}
+    
+template <class ImageIterator, class Accessor, class VALUETYPE>
+inline void
+initImage(triple<ImageIterator, ImageIterator, Accessor> img, VALUETYPE const & v)
+{
+    initImage(img.first, img.second, img.third, v);
+}
+    
+template <class T, class S, class VALUETYPE>
+inline void
+initImage(MultiArrayView<2, T, S> img, VALUETYPE const & v)
+{
+    initImage(destImageRange(img), v);
+}
+    
+/********************************************************/
+/*                                                      */
+/*                 initImageWithFunctor                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Write the result of a functor call to every pixel in an image or rectangular ROI.
+
+    This function can be used to init the image by calling the given 
+    functor for each pixel. The functor is 
+    passed by reference, so that its internal state can be updated in each call.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S, class FUNCTOR>
+        void
+        initImageWithFunctor(MultiArrayView<2, T, S> img, FUNCTOR & f);
+    }
+    \endcode
+    
+    \deprecatedAPI{initImageWithFunctor}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor, class FUNCTOR>
+        void
+        initImageWithFunctor(ImageIterator upperleft, ImageIterator lowerright, 
+                  Accessor a,  FUNCTOR & f);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor, class FUNCTOR>
+        void
+        initImageWithFunctor(triple<ImageIterator, ImageIterator, Accessor> img, FUNCTOR & f);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/initimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    struct Counter {
+        Counter() : count(0) {}
+        
+        int operator()() const { return count++; }
+    
+        int count;
+    };
+    
+    MultiArray<2, int> img(100, 100);
+        
+    // write the current count in every pixel
+    Counter counter;
+    initImageWithFunctor(img, counter);
+    
+    // equivalent to
+    #include <vigra/algorithm.hxx>
+    
+    linearSequence(img.begin(), img.end());
+    \endcode
+
+    \deprecatedUsage{initImageWithFunctor}
+    \code
+    struct Counter {
+        Counter() : count(0) {}
+        
+        int operator()() const { return count++; }
+    
+        mutable int count;
+    };
+    
+    vigra::IImage img(100, 100);
+        
+    // write the current count in every pixel
+    Counter counter;
+    vigra::initImageWithFunctor(destImageRange(img), counter);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator upperleft, lowerright;
+    ImageIterator::row_iterator ix = upperleft.rowIterator();
+    
+    Accessor accessor;
+    Functor f;
+    
+    accessor.set(f(), ix); 
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void initImageWithFunctor)
+
+template <class ImageIterator, class Accessor, class FUNCTOR>
+void
+initImageWithFunctor(ImageIterator upperleft, ImageIterator lowerright, 
+          Accessor a,  FUNCTOR & f)
+{
+    int w = lowerright.x - upperleft.x;
+    
+    for(; upperleft.y < lowerright.y; ++upperleft.y)
+    {
+        initLineFunctor(upperleft.rowIterator(), upperleft.rowIterator() + w, a, f);
+    }
+}
+    
+template <class ImageIterator, class Accessor, class FUNCTOR>
+inline void
+initImageWithFunctor(triple<ImageIterator, ImageIterator, Accessor> img, FUNCTOR & f)
+{
+    initImageWithFunctor(img.first, img.second, img.third, f);
+}
+    
+template <class T, class S, class FUNCTOR>
+inline void
+initImageWithFunctor(MultiArrayView<2, T, S> img, FUNCTOR & f)
+{
+    initImageWithFunctor(destImageRange(img), f);
+}
+    
+/********************************************************/
+/*                                                      */
+/*                      initImageIf                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Write value to pixel in the image if mask is true.
+
+    This function can be used to init a region-of-interest of the image.
+    
+    The initial value can either be a constant of appropriate type (compatible with 
+    the destination's value_type), or a functor with compatible result_type. These two 
+    cases are automatically distinguished when <tt>FunctorTraits<FUNCTOR>::isInitializer</tt>
+    yields <tt>VigraTrueType</tt>. Since the functor is passed by <tt>const</tt> reference, its 
+    <tt>operator()</tt> must be const, and its internal state may need to be <tt>mutable</tt>.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S, 
+                  class TM, class SM,
+                  class VALUETYPE>
+        void
+        initImageIf(MultiArrayView<2, T, S> img, 
+                    MultiArrayView<2, TM, SM> const & mask,
+                    VALUETYPE const & v);
+                    
+        template <class T, class S, 
+                  class TM, class SM,
+                  class FUNCTOR>
+        void
+        initImageIf(MultiArrayView<2, T, S> img, 
+                    MultiArrayView<2, TM, SM> const & mask,
+                    FUNCTOR const & v);
+    }
+    \endcode     
+    \deprecatedAPI{initImageIf}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor, 
+                  class MaskImageIterator, class MaskAccessor,
+                  class VALUETYPE>
+        void initImageIf(ImageIterator upperleft, ImageIterator lowerright, Accessor a,
+                         MaskImageIterator mask_upperleft, MaskAccessor ma,
+                         VALUETYPE const & v);
+
+        template <class ImageIterator, class Accessor, 
+                  class MaskImageIterator, class MaskAccessor,
+                  class FUNCTOR>
+        void initImageIf(ImageIterator upperleft, ImageIterator lowerright, Accessor a,
+                         MaskImageIterator mask_upperleft, MaskAccessor ma,
+                         FUNCTOR const & v);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor, 
+                  class MaskImageIterator, class MaskAccessor,
+                  class VALUETYPE>
+        void initImageIf(triple<ImageIterator, ImageIterator, Accessor> img, 
+                         pair<MaskImageIterator, MaskAccessor> mask,
+                         VALUETYPE const & v);
+
+        template <class ImageIterator, class Accessor, 
+                  class MaskImageIterator, class MaskAccessor,
+                  class FUNCTOR>
+        void initImageIf(triple<ImageIterator, ImageIterator, Accessor> img, 
+                         pair<MaskImageIterator, MaskAccessor> mask,
+                         FUNCTOR const & v);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/initimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, RGBValue<unsigned char> >  img(100, 100),
+    MultiArray<2, unsigned char>             mask(100, 100);
+    ... // init the ROI mask
+    
+    // set the ROI to one
+    initImageIf(img, mask,
+                NumericTraits<RGBValue<unsigned char> >::one());
+    \endcode
+
+    \deprecatedUsage{initImageIf}
+    \code
+    vigra::BImage img(100, 100);
+    vigra::BImage mask(100, 100);
+    
+    // zero the ROI
+    vigra::initImageIf(destImageRange(img), 
+                maskImage(mask),
+                vigra::NumericTraits<vigra::BImage::PixelType>::zero());
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator upperleft, lowerright;
+    MaskImageIterator mask_upperleft;
+    ImageIterator::row_iterator ix = upperleft.rowIterator();
+    MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator();
+    
+    Accessor accessor;
+    MaskAccessor mask_accessor;
+    VALUETYPE v;
+    
+    if(mask_accessor(mx)) accessor.set(v, ix); 
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void initImageIf)
+
+template <class ImageIterator, class Accessor, 
+          class MaskImageIterator, class MaskAccessor,
+          class VALUETYPE>
+void
+initImageIf(ImageIterator upperleft, ImageIterator lowerright, Accessor a,
+          MaskImageIterator mask_upperleft, MaskAccessor ma,
+          VALUETYPE const & v)
+{
+    int w = lowerright.x - upperleft.x;
+        
+    for(; upperleft.y < lowerright.y; ++upperleft.y, ++mask_upperleft.y)
+    {
+        initLineIfImpl(upperleft.rowIterator(), 
+                   upperleft.rowIterator() + w, a, 
+                   mask_upperleft.rowIterator(), ma, 
+                   v, typename FunctorTraits<VALUETYPE>::isInitializer());
+    }
+}
+    
+template <class ImageIterator, class Accessor, 
+          class MaskImageIterator, class MaskAccessor,
+          class VALUETYPE>
+inline void
+initImageIf(triple<ImageIterator, ImageIterator, Accessor> img, 
+            pair<MaskImageIterator, MaskAccessor> mask,
+            VALUETYPE const & v)
+{
+    initImageIf(img.first, img.second, img.third, mask.first, mask.second, v);
+}
+    
+template <class T, class S, 
+          class TM, class SM,
+          class VALUETYPE>
+inline void
+initImageIf(MultiArrayView<2, T, S> img, 
+            MultiArrayView<2, TM, SM> const & mask,
+            VALUETYPE const & v)
+{
+    vigra_precondition(img.shape() == mask.shape(),
+        "initImageIf(): shape mismatch between input and mask.");
+    initImageIf(destImageRange(img), maskImage(mask), v);
+}
+    
+/********************************************************/
+/*                                                      */
+/*                    initImageBorder                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Write value to the specified border pixels in the image.
+
+    A pixel is initialized if its distance to the border 
+    is at most 'borderwidth'. 
+    
+    The initial value can either be a constant of appropriate type (compatible with 
+    the destination's value_type), or a functor with compatible result_type. These two 
+    cases are automatically distinguished when <tt>FunctorTraits<FUNCTOR>::isInitializer</tt>
+    yields <tt>VigraTrueType</tt>. Since the functor is passed by <tt>const</tt> reference, its 
+    <tt>operator()</tt> must be const, and its internal state may need to be <tt>mutable</tt>.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S, class VALUETYPE>
+        void
+        initImageBorder(MultiArrayView<2, T, S> img, 
+                        int border_width, VALUETYPE const & v);
+                        
+        template <class T, class S, class FUNCTOR>
+        void
+        initImageBorder(MultiArrayView<2, T, S> img, 
+                        int border_width, FUNCTOR const & v);
+    }
+    \endcode
+    
+    \deprecatedAPI{initImageBorder}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor, class VALUETYPE>
+        void initImageBorder(ImageIterator upperleft, ImageIterator lowerright, Accessor a,
+                             int border_width, VALUETYPE const & v);
+
+        template <class ImageIterator, class Accessor, class FUNCTOR>
+        void initImageBorder(ImageIterator upperleft, ImageIterator lowerright, Accessor a,
+                             int border_width, FUNCTOR const & v);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor, class VALUETYPE>
+        void initImageBorder(triple<ImageIterator, ImageIterator, Accessor> img, 
+                             int border_width, VALUETYPE const & v);
+
+        template <class ImageIterator, class Accessor, class FUNCTOR>
+        void initImageBorder(triple<ImageIterator, ImageIterator, Accessor> img, 
+                             int border_width, FUNCTOR const & v);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/initimage.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    #include <vigra/random.hxx>
+    
+    MultiArray<2, int> img(100, 100);
+    
+    // fill a border of 5 pixels with random numbers
+    initImageBorder(img, 5, MersenneTwister());
+    \endcode
+
+    \deprecatedUsage{initImageBorder}
+    \code
+    vigra::BImage img(100, 100);
+    
+    // zero a border of 5 pixel
+    vigra::initImageBorder(destImageRange(img),
+                    5, vigra::NumericTraits<vigra::BImage::PixelType>::zero());
+    \endcode
+    <b> Required Interface:</b>
+    <br/>see \ref initImage()
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void initImageBorder)
+
+template <class ImageIterator, class Accessor, class VALUETYPE>
+inline 
+void
+initImageBorder(ImageIterator upperleft, ImageIterator lowerright, 
+                Accessor a,  int border_width, VALUETYPE const & v)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    int hb = (border_width > h) ? h : border_width;
+    int wb = (border_width > w) ? w : border_width;
+    
+    initImage(upperleft, upperleft+Diff2D(w,hb), a, v);
+    initImage(upperleft, upperleft+Diff2D(wb,h), a, v);
+    initImage(upperleft+Diff2D(0,h-hb), lowerright, a, v);
+    initImage(upperleft+Diff2D(w-wb,0), lowerright, a, v);
+}
+    
+template <class ImageIterator, class Accessor, class VALUETYPE>
+inline void
+initImageBorder(triple<ImageIterator, ImageIterator, Accessor> img, 
+                int border_width, VALUETYPE const & v)
+{
+    initImageBorder(img.first, img.second, img.third, border_width, v);
+}
+    
+template <class T, class S, class VALUETYPE>
+inline void
+initImageBorder(MultiArrayView<2, T, S> img, 
+                int border_width, VALUETYPE const & v)
+{
+    initImageBorder(destImageRange(img), border_width, v);
+}
+    
+//@}
+
+
+} // namespace vigra
+
+#endif // VIGRA_INITIMAGE_HXX
diff --git a/include/vigra/inspectimage.hxx b/include/vigra/inspectimage.hxx
new file mode 100644
index 0000000..6a6e909
--- /dev/null
+++ b/include/vigra/inspectimage.hxx
@@ -0,0 +1,2256 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_INSPECTIMAGE_HXX
+#define VIGRA_INSPECTIMAGE_HXX
+
+#include <vector>
+#include <algorithm>
+#include "utilities.hxx"
+#include "numerictraits.hxx"
+#include "iteratortraits.hxx"
+#include "functortraits.hxx"
+#include "rgbvalue.hxx"
+#include "inspector_passes.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup InspectAlgo Algorithms to Inspect Images
+
+    Collect information and statistics over all or selected pixels.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                      inspectLine                     */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor, class Functor>
+void
+inspectLine(SrcIterator s,
+            SrcIterator send, SrcAccessor src,
+            Functor & f)
+{
+    for(; s != send; ++s)
+        f(src(s));
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class MaskIterator, class MaskAccessor,
+          class Functor>
+void
+inspectLineIf(SrcIterator s,
+              SrcIterator send, SrcAccessor src,
+              MaskIterator m, MaskAccessor mask,
+              Functor & f)
+{
+    for(; s != send; ++s, ++m)
+        if(mask(m))
+            f(src(s));
+}
+
+template <class SrcIterator1, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class Functor>
+void
+inspectTwoLines(SrcIterator1 s1,
+                SrcIterator1 s1end, SrcAccessor1 src1,
+                SrcIterator2 s2, SrcAccessor2 src2,
+                Functor & f)
+{
+    for(; s1 != s1end; ++s1, ++s2)
+        f(src1(s1), src2(s2));
+}
+
+template <class SrcIterator1, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class MaskIterator, class MaskAccessor,
+          class Functor>
+void
+inspectTwoLinesIf(SrcIterator1 s1,
+                  SrcIterator1 s1end, SrcAccessor1 src1,
+                  SrcIterator2 s2, SrcAccessor2 src2,
+                  MaskIterator m, MaskAccessor mask,
+                  Functor & f)
+{
+    for(; s1 != s1end; ++s1, ++s2, ++m)
+        if(mask(m))
+            f(src1(s1), src2(s2));
+}
+
+/********************************************************/
+/*                                                      */
+/*                        inspectImage                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply read-only functor to every pixel in the image.
+
+    This function can be used to collect statistics of the image etc.
+    The results must be stored in the functor, which serves as a return value
+    (and is therefore passed by reference).
+    
+    For many common statistics, the use of \ref vigra::acc::extractFeatures() in combination with 
+    \ref FeatureAccumulators is more convenient.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S, class Functor>
+        void
+        inspectImage(MultiArrayView<2, T, S> const & img,
+                     Functor & f);
+    }
+    \endcode
+
+    \deprecatedAPI{inspectImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor, class Functor>
+        void
+        inspectImage(ImageIterator upperleft, ImageIterator lowerright, Accessor a, 
+                     Functor & f)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor, class Functor>
+        void
+        inspectImage(triple<ImageIterator, ImageIterator, Accessor> img,
+                     Functor & f)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> img(width, height);
+    ... // fill img
+    
+    // init functor
+    FindMinMax<unsined char> minmax;
+
+    inspectImage(img, minmax);
+
+    cout << "Min: " << minmax.min << " Max: " << minmax.max;
+    \endcode
+
+    \deprecatedUsage{inspectImage}
+    \code
+    // init functor
+    vigra::BImage img;
+
+    vigra::FindMinMax<vigra::BImage::PixelType> minmax;
+
+    vigra::inspectImage(srcImageRange(img), minmax);
+
+    cout << "Min: " << minmax.min << " Max: " << minmax.max;
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ConstImageIterator upperleft, lowerright;
+    ConstImageIterator::row_iterator ix = upperleft.rowIterator();
+
+    Accessor accessor;
+    Functor functor;
+
+    functor(accessor(ix));         // return not used
+    \endcode
+    \deprecatedEnd
+    
+    \see InspectFunctor, FeatureAccumulators
+*/
+doxygen_overloaded_function(template <...> void inspectImage)
+
+template <class ImageIterator, class Accessor>
+struct inspectImage_binder
+{
+    ImageIterator upperleft;
+    ImageIterator lowerright;
+    Accessor a;
+
+    inspectImage_binder(ImageIterator ul, ImageIterator lr, Accessor ac)
+        : upperleft(ul), lowerright(lr), a(ac) {}
+    template <class Functor>
+    void operator()(Functor & f)
+    {
+        int w = lowerright.x - upperleft.x;
+
+        for (ImageIterator t = upperleft; t.y < lowerright.y; ++t.y)
+        {
+            inspectLine(t.rowIterator(), t.rowIterator() + w, a, f);
+        }
+    }
+};
+
+template <class ImageIterator, class Accessor, class Functor>
+void
+inspectImage(ImageIterator upperleft, ImageIterator lowerright,
+         Accessor a, Functor & f)
+{
+    inspectImage_binder<ImageIterator, Accessor> g(upperleft, lowerright, a);
+    detail::extra_passes_select(g, f);
+}
+
+template <class ImageIterator, class Accessor, class Functor>
+inline void
+inspectImage(triple<ImageIterator, ImageIterator, Accessor> img,
+             Functor & f)
+{
+    inspectImage(img.first, img.second, img.third, f);
+}
+
+template <class T, class S, class Functor>
+inline void
+inspectImage(MultiArrayView<2, T, S> const & img,
+             Functor & f)
+{
+    inspectImage(srcImageRange(img), f);
+}
+
+namespace functor
+{
+    template <class T> class UnaryAnalyser;
+}
+
+template <class ImageIterator, class Accessor, class Functor>
+inline
+void
+inspectImage(ImageIterator upperleft, ImageIterator lowerright,
+         Accessor a, functor::UnaryAnalyser<Functor> const & f)
+{
+    inspectImage(upperleft, lowerright, a,
+                 const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+template <class ImageIterator, class Accessor, class Functor>
+inline void
+inspectImage(triple<ImageIterator, ImageIterator, Accessor> img,
+             functor::UnaryAnalyser<Functor> const & f)
+{
+    inspectImage(img.first, img.second, img.third,
+                 const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+template <class T, class S, class Functor>
+inline void
+inspectImage(MultiArrayView<2, T, S> const & img,
+             functor::UnaryAnalyser<Functor> const & f)
+{
+    inspectImage(srcImageRange(img),
+                 const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+/********************************************************/
+/*                                                      */
+/*                      inspectImageIf                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply read-only functor to every pixel in the ROI.
+
+    This function can be used to collect statistics of the ROI etc.
+    The functor is called whenever the return value of the mask's
+    accessor is not zero.
+    The results must be stored in the functor, which serves as a return
+    value (and is therefore passed by reference.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S,
+                  class TM, class SM, class Functor>
+        void
+        inspectImageIf(MultiArrayView<2, T, S> const & img,
+                       MultiArrayView<2, TM, SM> const & mask,
+                       Functor & f);
+    }
+    \endcode
+
+    \deprecatedAPI{inspectImageIf}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor,
+                  class MaskImageIterator, class MaskAccessor, class Functor>
+        void
+        inspectImageIf(ImageIterator upperleft, ImageIterator lowerright,
+               MaskImageIterator mask_upperleft, MaskAccessor ma,
+               Functor & f)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor,
+              class MaskImageIterator, class MaskAccessor, class Functor>
+        void
+        inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
+               pair<MaskImageIterator, MaskAccessor> mask,
+               Functor & f)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> img(100, 100),
+                                 mask(100, 100);
+    ... // fill img and mask
+    
+    // init functor
+    FindMinMax<unsigned char> minmax;
+
+    inspectImageIf(img, mask, minmax);
+
+    cout << "Min: " << minmax.min << " Max: " << minmax.max;
+    \endcode
+
+    \deprecatedUsage{inspectImageIf}
+    \code
+    vigra::BImage img(100, 100);
+    vigra::BImage mask(100, 100);
+
+    // init functor
+    vigra::FindMinMax<vigra::BImage::PixelType> minmax;
+
+    vigra::inspectImageIf(srcImageRange(img),
+                          maskImage(mask), minmax);
+
+    cout << "Min: " << minmax.min << " Max: " << minmax.max;
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ConstImageIterator upperleft, lowerright;
+    MaskImageIterator mask_upperleft;
+    ConstImageIterator::row_iterator ix = upperleft.rowIterator();
+    MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator();
+
+    Accessor accessor;
+    MaskAccessor mask_accessor;
+
+    Functor functor;
+
+    if(mask_accessor(mx)) functor(accessor(ix));
+    \endcode
+    \deprecatedEnd
+    
+    \see InspectFunctor, FeatureAccumulators
+*/
+doxygen_overloaded_function(template <...> void inspectImageIf)
+
+template <class ImageIterator, class Accessor,
+      class MaskImageIterator, class MaskAccessor>
+struct inspectImageIf_binder
+{
+    ImageIterator upperleft;
+    ImageIterator lowerright;
+    Accessor a;
+    MaskImageIterator mask_upperleft;
+    MaskAccessor ma;
+
+    inspectImageIf_binder(ImageIterator ul, ImageIterator lr, Accessor ac,
+                        MaskImageIterator m_ul, MaskAccessor m_ac)
+        : upperleft(ul), lowerright(lr), a(ac), mask_upperleft(m_ul), ma(m_ac)
+    {}
+    template <class Functor>
+    void operator()(Functor & f)
+    {
+        int w = lowerright.x - upperleft.x;
+
+        MaskImageIterator mt = mask_upperleft;
+        for (ImageIterator t = upperleft; t.y < lowerright.y; ++t.y, ++mt.y)
+        {
+            inspectLineIf(t.rowIterator(),
+                          t.rowIterator() + w, a,
+                          mt.rowIterator(), ma, f);
+        }
+    }
+};
+
+template <class ImageIterator, class Accessor,
+      class MaskImageIterator, class MaskAccessor, class Functor>
+void
+inspectImageIf(ImageIterator upperleft,
+               ImageIterator lowerright, Accessor a,
+           MaskImageIterator mask_upperleft, MaskAccessor ma,
+           Functor & f)
+{
+    inspectImageIf_binder<ImageIterator, Accessor, MaskImageIterator,
+                                                                   MaskAccessor>
+        g(upperleft, lowerright, a, mask_upperleft, ma);
+    detail::extra_passes_select(g, f);
+}
+
+template <class ImageIterator, class Accessor,
+      class MaskImageIterator, class MaskAccessor, class Functor>
+inline void
+inspectImageIf(ImageIterator upperleft,
+               ImageIterator lowerright, Accessor a,
+               MaskImageIterator mask_upperleft, MaskAccessor ma,
+               functor::UnaryAnalyser<Functor> const & f)
+{
+    inspectImageIf(upperleft, lowerright, a,
+                   mask_upperleft, ma, const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+template <class ImageIterator, class Accessor,
+          class MaskImageIterator, class MaskAccessor, class Functor>
+inline void
+inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
+               pair<MaskImageIterator, MaskAccessor> mask,
+               Functor & f)
+{
+    inspectImageIf(img.first, img.second, img.third,
+                   mask.first, mask.second, f);
+}
+
+template <class ImageIterator, class Accessor,
+          class MaskImageIterator, class MaskAccessor, class Functor>
+inline void
+inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
+               pair<MaskImageIterator, MaskAccessor> mask,
+               functor::UnaryAnalyser<Functor> const & f)
+{
+    inspectImageIf(img.first, img.second, img.third,
+                   mask.first, mask.second, const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+template <class T, class S,
+          class TM, class SM, class Functor>
+inline void
+inspectImageIf(MultiArrayView<2, T, S> const & img,
+               MultiArrayView<2, TM, SM> const & mask,
+               Functor & f)
+{
+    vigra_precondition(img.shape() == mask.shape(),
+        "inspectImageIf(): shape mismatch between input and output.");
+    inspectImageIf(srcImageRange(img),
+                   maskImage(mask), f);
+}
+
+template <class T, class S,
+          class TM, class SM, class Functor>
+inline void
+inspectImageIf(MultiArrayView<2, T, S> const & img,
+               MultiArrayView<2, TM, SM> const & mask,
+               functor::UnaryAnalyser<Functor> const & f)
+{
+    inspectImageIf(srcImageRange(img),
+                   maskImage(mask), const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+/********************************************************/
+/*                                                      */
+/*                  inspectTwoImages                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply read-only functor to every pixel of both images.
+
+    This function can be used to collect statistics for each region of a
+    labeled image, especially in conjunction with
+    the \ref ArrayOfRegionStatistics functor. The results must be
+    stored in the functor which serves as a return value.
+    
+    Note: For many common statistics, the use of \ref vigra::acc::extractFeatures() in combination 
+    with \ref FeatureAccumulators is more convenient.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class Functor>
+        void
+        inspectTwoImages(MultiArrayView<2, T1, S1> const & img1,
+                         MultiArrayView<2, T2, S2> const & img2,
+                         Functor & f);
+    }
+    \endcode
+
+    \deprecatedAPI{inspectTwoImages}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator1, class Accessor1,
+              class ImageIterator2, class Accessor2,
+              class Functor>
+        void
+        inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1,
+                 ImageIterator2 upperleft2, Accessor2 a2,
+                 Functor & f)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator1, class Accessor1,
+              class ImageIterator2, class Accessor2,
+              class Functor>
+        void
+        inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
+                         pair<ImageIterator2, Accessor2> img2,
+                 Functor & f)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> image1(width, height), image2(width, height);
+
+    SomeStatisticsFunctor stats(...);     // init functor
+
+    inspectTwoImages(image1, image2, stats);
+    \endcode
+
+    \deprecatedUsage{inspectTwoImages}
+    \code
+    vigra::BImage image1;
+    vigra::BImage image2;
+
+    SomeStatisticsFunctor stats(...);     // init functor
+
+    vigra::inspectTwoImages(srcImageRange(image1), srcImage(image2),
+                            stats);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator1 upperleft1, lowerright1;
+    ImageIterator2 upperleft2;
+    ImageIterator1::row_iterator ix1 = upperleft1.rowIterator();
+    ImageIterator2::row_iterator ix2 = upperleft2.rowIterator();
+
+    Accessor1 accessor1;
+    Accessor2 accessor2;
+
+    Functor functor;
+    functor(accessor1(ix1), accessor2(ix2));  // return not used
+    \endcode
+    \deprecatedEnd
+    
+    \see InspectFunctor, FeatureAccumulators
+*/
+doxygen_overloaded_function(template <...> void inspectTwoImages)
+
+template <class ImageIterator1, class Accessor1,
+          class ImageIterator2, class Accessor2>
+struct inspectTwoImages_binder
+{
+    ImageIterator1 upperleft1;
+    ImageIterator1 lowerright1;
+    Accessor1      a1;
+    ImageIterator2 upperleft2;
+    Accessor2      a2;
+    inspectTwoImages_binder(ImageIterator1 u1, ImageIterator1 l1, Accessor1 a1_,
+                        ImageIterator2 u2, Accessor2 a2_)
+        : upperleft1(u1), lowerright1(l1), a1(a1_), upperleft2(u2), a2(a2_) {}
+    template <class Functor>
+    void operator()(Functor & f)
+    {
+        int w = lowerright1.x - upperleft1.x;
+
+        ImageIterator1 t1 = upperleft1;
+        ImageIterator2 t2 = upperleft2;
+        for (; t1.y < lowerright1.y; ++t1.y, ++t2.y)
+        {
+            inspectTwoLines(t1.rowIterator(),
+                            t1.rowIterator() + w, a1,
+                            t2.rowIterator(), a2, f);
+        }
+    }
+};
+
+template <class ImageIterator1, class Accessor1,
+          class ImageIterator2, class Accessor2,
+          class Functor>
+void
+inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1,
+                 Accessor1 a1,
+                 ImageIterator2 upperleft2, Accessor2 a2,
+                 Functor & f)
+{
+    inspectTwoImages_binder<ImageIterator1, Accessor1,
+                            ImageIterator2, Accessor2>
+        g(upperleft1, lowerright1, a1, upperleft2, a2);
+    detail::extra_passes_select(g, f);
+}
+
+template <class ImageIterator1, class Accessor1,
+          class ImageIterator2, class Accessor2,
+          class Functor>
+inline void
+inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1,
+                 ImageIterator2 upperleft2, Accessor2 a2,
+                 functor::UnaryAnalyser<Functor> const & f)
+{
+    inspectTwoImages(upperleft1, lowerright1, a1,
+                     upperleft2, a2, const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+template <class ImageIterator1, class Accessor1,
+          class ImageIterator2, class Accessor2,
+          class Functor>
+inline void
+inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
+                 pair<ImageIterator2, Accessor2> img2,
+                 Functor & f)
+{
+    inspectTwoImages(img1.first, img1.second, img1.third,
+                     img2.first, img2.second, f);
+}
+
+template <class ImageIterator1, class Accessor1,
+          class ImageIterator2, class Accessor2,
+          class Functor>
+inline void
+inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
+                 pair<ImageIterator2, Accessor2> img2,
+                 functor::UnaryAnalyser<Functor> const & f)
+{
+    inspectTwoImages(img1.first, img1.second, img1.third,
+                     img2.first, img2.second, const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class Functor>
+inline void
+inspectTwoImages(MultiArrayView<2, T1, S1> const & img1,
+                 MultiArrayView<2, T2, S2> const & img2,
+                 Functor & f)
+{
+    vigra_precondition(img1.shape() == img2.shape(),
+        "inspectTwoImages(): shape mismatch between input and output.");
+    inspectTwoImages(srcImageRange(img1),
+                     srcImage(img2),
+                     f);
+}
+
+
+template <class T1, class S1,
+          class T2, class S2,
+          class Functor>
+inline void
+inspectTwoImages(MultiArrayView<2, T1, S1> const & img1,
+                 MultiArrayView<2, T2, S2> const & img2,
+                 functor::UnaryAnalyser<Functor> const & f)
+{
+    vigra_precondition(img1.shape() == img2.shape(),
+        "inspectTwoImages(): shape mismatch between input and output.");
+    inspectTwoImages(srcImageRange(img1),
+                     srcImage(img2), const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+/********************************************************/
+/*                                                      */
+/*                inspectTwoImagesIf                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply read-only functor to those pixels of both images where
+    the mask image is non-zero.
+
+    This function can be used to collect statistics for selected regions of a
+    labeled image, especially in conjunction with
+    the \ref ArrayOfRegionStatistics functor. The results must be
+    stored in the functor which serves as a return value.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class TM, class SM,
+                  class Functor>
+        void
+        inspectTwoImagesIf(MultiArrayView<2, T1, S1> const & img1,
+                           MultiArrayView<2, T2, S2> const & img2,
+                           MultiArrayView<2, TM, SM> const & mask,
+                           Functor & f);
+    }
+    \endcode
+
+    \deprecatedAPI{inspectTwoImagesIf}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator1, class Accessor1,
+                  class ImageIterator2, class Accessor2,
+                  class MaskImageIterator, class MaskAccessor,
+                  class Functor>
+        void
+        inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1,
+                         ImageIterator2 upperleft2, Accessor2 a2,
+                         MaskImageIterator mupperleft, MaskAccessor mask,
+                         Functor & f)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator1, class Accessor1,
+                  class ImageIterator2, class Accessor2,
+                  class MaskImageIterator, class MaskAccessor,
+                  class Functor>
+        void
+        inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
+                 pair<ImageIterator2, Accessor2> img2,
+                 pair<MaskImageIterator, MaskAccessor> mimg,
+                 Functor & f)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> image1(width, height), image2(width, height),
+                                 maskimage(width, height);
+
+    SomeStatisticsFunctor stats(...);     // init functor
+
+    inspectTwoImagesIf(image1, image2, maskimage, region_stats);
+    \endcode
+
+    \deprecatedUsage{inspectTwoImagesIf}
+    \code
+    vigra::BImage image1;
+    vigra::BImage image2;
+    vigra::BImage maskimage;
+
+    SomeStatisticsFunctor stats(...);     // init functor
+
+    vigra::inspectTwoImagesIf(srcImageRange(image1), srcImage(image2),
+                              srcImage(maskimage), region_stats);
+
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator1 upperleft1, lowerright1;
+    ImageIterator2 upperleft2;
+    MaskImageIterator upperleftm;
+    ImageIterator1::row_iterator ix1 = upperleft1.rowIterator();
+    ImageIterator2::row_iterator ix2 = upperleft2.rowIterator();
+    MaskImageIterator::row_iterator mx = mupperleft.rowIterator();
+
+    Accessor1 accessor1;
+    Accessor2 accessor2;
+    MaskAccessor mask;
+
+    Functor functor;
+    if(mask(mx))
+        functor(accessor1(ix1), accessor2(ix2));
+    \endcode
+    \deprecatedEnd
+    
+    \see InspectFunctor, FeatureAccumulators
+*/
+doxygen_overloaded_function(template <...> void inspectTwoImagesIf)
+
+template <class ImageIterator1, class Accessor1,
+          class ImageIterator2, class Accessor2,
+          class MaskImageIterator, class MaskAccessor>
+struct inspectTwoImagesIf_binder
+{
+    ImageIterator1    upperleft1;
+    ImageIterator1    lowerright1;
+    Accessor1         a1;
+    ImageIterator2    upperleft2;
+    Accessor2         a2;
+    MaskImageIterator mupperleft;
+    MaskAccessor      mask;
+    inspectTwoImagesIf_binder(ImageIterator1 u1, ImageIterator1 l1,
+                              Accessor1 a1_, ImageIterator2 u2, Accessor2 a2_,
+                              MaskImageIterator mu, MaskAccessor ma)
+        : upperleft1(u1), lowerright1(l1), a1(a1_), upperleft2(u2), a2(a2_),
+          mupperleft(mu), mask(ma) {}
+    template <class Functor>
+    void operator()(Functor & f)
+    {
+        int w = lowerright1.x - upperleft1.x;
+
+        ImageIterator1 t1 = upperleft1;
+        ImageIterator2 t2 = upperleft2;
+        MaskImageIterator mu = mupperleft;
+        for(; t1.y < lowerright1.y; ++t1.y, ++t2.y, ++mu.y)
+        {
+            inspectTwoLinesIf(t1.rowIterator(),
+                              t1.rowIterator() + w, a1,
+                              t2.rowIterator(), a2,
+                              mu.rowIterator(), mask, f);
+        }
+    }
+};
+
+template <class ImageIterator1, class Accessor1,
+          class ImageIterator2, class Accessor2,
+          class MaskImageIterator, class MaskAccessor,
+          class Functor>
+void
+inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1,
+                   Accessor1 a1,
+                   ImageIterator2 upperleft2, Accessor2 a2,
+                   MaskImageIterator mupperleft, MaskAccessor mask,
+                   Functor & f)
+{
+    inspectTwoImagesIf_binder<ImageIterator1, Accessor1,
+                              ImageIterator2, Accessor2,
+                              MaskImageIterator, MaskAccessor>
+        g(upperleft1, lowerright1, a1, upperleft2, a2, mupperleft, mask);
+    detail::extra_passes_select(g, f);
+}
+
+template <class ImageIterator1, class Accessor1,
+          class ImageIterator2, class Accessor2,
+          class MaskImageIterator, class MaskAccessor,
+          class Functor>
+inline void
+inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1,
+                 ImageIterator2 upperleft2, Accessor2 a2,
+                 MaskImageIterator mupperleft, MaskAccessor mask,
+                 functor::UnaryAnalyser<Functor> const & f)
+{
+    inspectTwoImagesIf(upperleft1, lowerright1, a1,
+                       upperleft2, a2,
+                       mupperleft, mask,
+                       const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+template <class ImageIterator1, class Accessor1,
+          class ImageIterator2, class Accessor2,
+          class MaskImageIterator, class MaskAccessor,
+          class Functor>
+inline void
+inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
+                   pair<ImageIterator2, Accessor2> img2,
+                   pair<MaskImageIterator, MaskAccessor> m,
+                   Functor & f)
+{
+    inspectTwoImagesIf(img1.first, img1.second, img1.third,
+                       img2.first, img2.second,
+                       m.first, m.second,
+                       f);
+}
+
+template <class ImageIterator1, class Accessor1,
+          class ImageIterator2, class Accessor2,
+          class MaskImageIterator, class MaskAccessor,
+          class Functor>
+inline void
+inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
+                   pair<ImageIterator2, Accessor2> img2,
+                   pair<MaskImageIterator, MaskAccessor> m,
+                   functor::UnaryAnalyser<Functor> const & f)
+{
+    inspectTwoImagesIf(img1.first, img1.second, img1.third,
+                       img2.first, img2.second,
+                       m.first, m.second,
+                       const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class TM, class SM,
+          class Functor>
+inline void
+inspectTwoImagesIf(MultiArrayView<2, T1, S1> const & img1,
+                   MultiArrayView<2, T2, S2> const & img2,
+                   MultiArrayView<2, TM, SM> const & mask,
+                   Functor & f)
+{
+    vigra_precondition(img1.shape() == img2.shape() && img1.shape() == mask.shape(),
+        "inspectTwoImagesIf(): shape mismatch between input and output.");
+    inspectTwoImagesIf(srcImageRange(img1),
+                       srcImage(img2),
+                       maskImage(mask),
+                       f);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class TM, class SM,
+          class Functor>
+inline void
+inspectTwoImagesIf(MultiArrayView<2, T1, S1> const & img1,
+                   MultiArrayView<2, T2, S2> const & img2,
+                   MultiArrayView<2, TM, SM> const & mask,
+                   functor::UnaryAnalyser<Functor> const & f)
+{
+    vigra_precondition(img1.shape() == img2.shape() && img1.shape() == mask.shape(),
+        "inspectTwoImagesIf(): shape mismatch between input and output.");
+    inspectTwoImagesIf(srcImageRange(img1),
+                       srcImage(img2),
+                       maskImage(mask),
+                       const_cast<functor::UnaryAnalyser<Functor> &>(f));
+}
+
+//@}
+
+/** \addtogroup InspectFunctor Functors To Inspect Images
+    Functors which report image statistics
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                     FindMinMax                       */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find the minimum and maximum pixel value in an image or ROI.
+
+    In addition the size of the ROI is calculated.
+    These functors can also be used in conjunction with
+    \ref ArrayOfRegionStatistics to find the extremes of all regions in
+    a labeled image.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryAnalyser</tt> is true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage img;
+
+    vigra::FindMinMax<vigra::BImage::PixelType> minmax;   // init functor
+
+    vigra::inspectImage(srcImageRange(img), minmax);
+
+    cout << "Min: " << minmax.min << " Max: " << minmax.max;
+
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+    VALUETYPE v1, v2(v1);
+
+    v1 < v2;
+    v1 = v2;
+    \endcode
+
+*/
+template <class VALUETYPE>
+class FindMinMax
+{
+   public:
+
+        /** the functor's argument type
+        */
+    typedef VALUETYPE argument_type;
+
+        /** the functor's result type
+        */
+    typedef VALUETYPE result_type;
+
+        /** \deprecated use argument_type
+        */
+    typedef VALUETYPE value_type;
+
+        /** init min and max
+        */
+    FindMinMax()
+    : min( NumericTraits<value_type>::max() ),
+      max( NumericTraits<value_type>::min() ),
+      count(0)
+    {}
+
+        /** (re-)init functor (clear min, max)
+        */
+    void reset()
+    {
+        count = 0;
+    }
+
+        /** update min and max
+        */
+    void operator()(argument_type const & v)
+    {
+        if(count)
+        {
+            if(v < min) min = v;
+            if(max < v) max = v;
+        }
+        else
+        {
+            min = v;
+            max = v;
+        }
+        ++count;
+    }
+
+        /** update min and max with components of RGBValue<VALUETYPE>
+        */
+    void operator()(RGBValue<VALUETYPE> const & v)
+    {
+        operator()(v.red());
+        operator()(v.green());
+        operator()(v.blue());
+    }
+
+        /** merge two statistics
+        */
+    void operator()(FindMinMax const & v)
+    {
+        if(v.count)
+        {
+            if(count)
+            {
+                if(v.min < min) min = v.min;
+                if((this->max) < v.max) max = v.max;
+            }
+            else
+            {
+                min = v.min;
+                max = v.max;
+            }
+        }
+        count += v.count;
+    }
+
+        /** the current min
+        */
+    VALUETYPE min;
+
+        /** the current max
+        */
+    VALUETYPE max;
+
+        /** the number of values processed so far
+        */
+    unsigned int count;
+
+};
+
+template <class VALUETYPE>
+class FunctorTraits<FindMinMax<VALUETYPE> >
+: public FunctorTraitsBase<FindMinMax<VALUETYPE> >
+{
+  public:
+    typedef VigraTrueType isUnaryAnalyser;
+};
+
+/********************************************************/
+/*                                                      */
+/*                      FindSum                         */
+/*                                                      */
+/********************************************************/
+
+/** \brief  Find the sum of the pixel values in an image or ROI.
+
+    This Functor can also be used in conjunction with
+    \ref ArrayOfRegionStatistics to find the sum of all regions in
+    a labeled image, and with the reduce mode of transformMultiArray().
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
+    are true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage img;
+
+    vigra::FindSum<vigra::BImage::PixelType> sum;   // init functor
+
+    vigra::inspectImage(srcImageRange(img), sum);
+
+    cout << "Sum: " << sum();
+
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+    VALUETYPE v1, v2(v1);
+
+    v1 += v2;
+    \endcode
+
+*/
+template <class VALUETYPE>
+class FindSum
+: public UnaryReduceFunctorTag
+{
+   public:
+
+        /** the functor's argument type
+        */
+    typedef VALUETYPE argument_type;
+
+        /** the functor's result type
+        */
+    typedef typename NumericTraits<VALUETYPE>::Promote result_type;
+
+        /** init sum
+        */
+    FindSum()
+    : sum_(NumericTraits<result_type>::zero())
+    {}
+
+        /** (re-)init sum
+        */
+    void reset()
+    {
+        sum_ = NumericTraits<result_type>::zero();
+    }
+
+        /** update sum
+        */
+    void operator()(argument_type const & v)
+    {
+        sum_ += v;
+    }
+
+        /** merge two statistics
+        */
+    void operator()(FindSum const & v)
+    {
+        sum_   += v.sum_;
+    }
+
+        /** return current sum
+        */
+    result_type sum() const
+    {
+        return sum_;
+    }
+
+        /** return current sum
+        */
+    result_type operator()() const
+    {
+        return sum_;
+    }
+
+    result_type sum_;
+};
+
+
+
+/********************************************************/
+/*                                                      */
+/*                    FindAverage                       */
+/*                                                      */
+/********************************************************/
+
+/** \brief  Find the average pixel value in an image or ROI.
+
+    In addition the size of the ROI is calculated.
+    This Functor can also be used in conjunction with
+    \ref ArrayOfRegionStatistics to find the average of all regions in
+    a labeled image.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
+    are true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage img;
+
+    vigra::FindAverage<vigra::BImage::PixelType> average;   // init functor
+
+    vigra::inspectImage(srcImageRange(img), average);
+
+    cout << "Average: " << average();
+
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+    VALUETYPE v1, v2(v1);
+    double d;
+
+    v1 += v2;
+    v1 / d;
+    \endcode
+
+*/
+template <class VALUETYPE>
+class FindAverage
+{
+   public:
+
+        /** the functor's argument type
+        */
+    typedef VALUETYPE argument_type;
+
+        /** the functor's first argument type (for calls with a weight)
+        */
+    typedef VALUETYPE first_argument_type;
+
+        /** the functor's second argument type (for calls with a weight)
+        */
+    typedef double second_argument_type;
+
+        /** the functor's result type
+        */
+    typedef typename NumericTraits<VALUETYPE>::RealPromote result_type;
+
+        /** \deprecated use argument_type and result_type
+        */
+    typedef typename NumericTraits<VALUETYPE>::RealPromote value_type;
+
+        /** init average
+        */
+    FindAverage()
+    : sum_(NumericTraits<result_type>::zero()), count_(0)
+    {}
+
+        /** (re-)init average
+        */
+    void reset()
+    {
+        count_ = 0;
+        sum_ = NumericTraits<result_type>::zero();
+    }
+
+        /** update average
+        */
+    void operator()(argument_type const & v)
+    {
+        sum_ += v;
+        ++count_;
+    }
+
+        /** update average, using weighted input.
+         * <tt>stats(value, 1.0)</tt> is equivalent to the unweighted
+         * call <tt>stats(value)</tt>, and <tt>stats(value, 2.0)</tt>
+         * is equivalent to two unweighted calls.
+         */
+    void operator()(first_argument_type const & v, second_argument_type weight)
+    {
+        sum_   += v * weight;
+        count_ += weight;
+    }
+
+        /** merge two statistics
+        */
+    void operator()(FindAverage const & v)
+    {
+        sum_   += v.sum_;
+        count_ += v.count_;
+    }
+
+        /** return number of values (sum of weights) seen so far
+        */
+    double count() const
+    {
+        return count_;
+    }
+
+        /** return current average
+        */
+    result_type average() const
+    {
+        return sum_ / (double)count_;
+    }
+
+        /** return current average
+        */
+    result_type operator()() const
+    {
+        return sum_ / (double)count_;
+    }
+
+    result_type sum_;
+    double count_;
+};
+
+template <class VALUETYPE>
+class FunctorTraits<FindAverage<VALUETYPE> >
+: public FunctorTraitsBase<FindAverage<VALUETYPE> >
+{
+  public:
+    typedef VigraTrueType isInitializer;
+    typedef VigraTrueType isUnaryAnalyser;
+};
+
+/********************************************************/
+/*                                                      */
+/*                 FindAverageAndVariance               */
+/*                                                      */
+/********************************************************/
+
+/** \brief  Find the average pixel value and its variance in an image or ROI.
+
+    This Functor uses West's algorithm to accumulate highly accurate values for
+    the mean and the sum of squared differences of all values seen so far (the
+    naive incremental algorithm for the computation of the sum of squares
+    produces large round-off errors when the mean is much larger than the
+    standard deviation of the data.) This Functor can also be used in
+    conjunction with \ref ArrayOfRegionStatistics to find the statistics of all
+    regions in a labeled image.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
+    are true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage img;
+
+    vigra::FindAverageAndVariance<vigra::BImage::PixelType> averageAndVariance;   // init functor
+
+    vigra::inspectImage(srcImageRange(img), averageAndVariance);
+
+    cout << "Average: " << averageAndVariance.average() << "\n";
+    cout << "Standard deviation: " << sqrt(averageAndVariance.variance()) << "\n";
+
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+    VALUETYPE v1, v2(v1);
+    double d;
+
+    v1 += v2;
+    v1 + v2;
+    v1 - v2;
+    v1 * v2;
+    v1 / d;
+    d * v1;
+    \endcode
+
+*/
+template <class VALUETYPE>
+class FindAverageAndVariance
+{
+   public:
+
+        /** the functor's argument type
+        */
+    typedef VALUETYPE argument_type;
+
+        /** the functor's first argument type (for calls with a weight)
+        */
+    typedef VALUETYPE first_argument_type;
+
+        /** the functor's second argument type (for calls with a weight)
+        */
+    typedef double second_argument_type;
+
+        /** the functor's result type
+        */
+    typedef typename NumericTraits<VALUETYPE>::RealPromote result_type;
+
+        /** \deprecated use argument_type and result_type
+        */
+    typedef typename NumericTraits<VALUETYPE>::RealPromote value_type;
+
+        /** init average
+        */
+    FindAverageAndVariance()
+    : mean_(NumericTraits<result_type>::zero()),
+      sumOfSquaredDifferences_(NumericTraits<result_type>::zero()),
+      count_(0.0)
+    {}
+
+        /** (re-)init average and variance
+        */
+    void reset()
+    {
+        count_ = 0.0;
+        mean_ = NumericTraits<result_type>::zero();
+        sumOfSquaredDifferences_ = NumericTraits<result_type>::zero();
+    }
+
+        /** update average and variance
+        */
+    void operator()(argument_type const & v)
+    {
+        ++count_;
+        result_type t1 = v - mean_;
+        result_type t2 = t1 / count_;
+        mean_ += t2;
+        sumOfSquaredDifferences_ += (count_-1.0)*t1*t2;
+    }
+
+        /** update average and variance, using weighted input.
+         * <tt>stats(value, 1.0)</tt> is equivalent to the unweighted
+         * call <tt>stats(value)</tt>, and <tt>stats(value, 2.0)</tt>
+         * is equivalent to two unweighted calls.
+         */
+    void operator()(first_argument_type const & v, second_argument_type weight)
+    {
+        count_ += weight;
+        result_type t1 = v - mean_;
+        result_type t2 = t1 * weight / count_;
+        mean_ += t2;
+
+        //sumOfSquaredDifferences_ += (count_ - weight)*t1*t2;
+
+        if(count_ > weight)
+            sumOfSquaredDifferences_ +=
+                (t1 * t1 * weight / count_) * (count_ - weight );
+    }
+
+        /** merge two statistics
+        */
+    void operator()(FindAverageAndVariance const & v)
+    {
+        double newCount = count_ + v.count_;
+        sumOfSquaredDifferences_ += v.sumOfSquaredDifferences_ +
+                                    count_ / newCount * v.count_ * (mean_ - v.mean_) * (mean_ - v.mean_);
+        mean_ = (count_ * mean_ + v.count_ * v.mean_) / newCount;
+        count_ += v.count_;
+    }
+
+        /** return number of values (sum of weights) seen so far
+        */
+    unsigned int count() const
+    {
+        return (unsigned int)count_;
+    }
+
+        /** return current average
+        */
+    result_type average() const
+    {
+        return mean_;
+    }
+
+        /** return current variance.
+            If <tt>unbiased = true</tt>, the sum of squared differences
+            is divided by <tt>count()-1</tt> instead of just <tt>count()</tt>.
+        */
+    result_type variance(bool unbiased = false) const
+    {
+        return unbiased
+                  ? sumOfSquaredDifferences_ / (count_ - 1.0)
+                  : sumOfSquaredDifferences_ / count_;
+    }
+
+        /** return current variance. calls <tt>variance()</tt>.
+        */
+    result_type operator()() const
+    {
+        return variance();
+    }
+
+    result_type mean_, sumOfSquaredDifferences_;
+    double count_;
+};
+
+template <class VALUETYPE>
+class FunctorTraits<FindAverageAndVariance<VALUETYPE> >
+: public FunctorTraitsBase<FindAverageAndVariance<VALUETYPE> >
+{
+  public:
+    typedef VigraTrueType isInitializer;
+    typedef VigraTrueType isUnaryAnalyser;
+};
+
+/********************************************************/
+/*                                                      */
+/*                    FindROISize                       */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the size of an ROI in an image.
+
+    This Functor is often used in conjunction with
+    \ref ArrayOfRegionStatistics to find the sizes of all regions in
+    a labeled image.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
+    are true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage img, mask;
+
+    vigra::FindROISize<vigra::BImage::PixelType> roisize;   // init functor
+
+    vigra::inspectImageIf(srcImageRange(img), srcImage(mask), roisize);
+
+    cout << "Size of ROI: " << roisize.count;
+
+    \endcode
+
+*/
+template <class VALUETYPE>
+class FindROISize
+{
+   public:
+
+        /** the functor's argument type
+        */
+    typedef VALUETYPE argument_type;
+
+        /** the functor's result type
+        */
+    typedef unsigned int result_type;
+
+        /** \deprecated use argument_type and result_type
+        */
+    typedef VALUETYPE value_type;
+
+        /** init counter to 0
+        */
+    FindROISize()
+    : count(0)
+    {}
+
+        /** (re-)init ROI size with 0
+        */
+    void reset()
+    {
+        count = 0;
+    }
+
+        /** update counter
+        */
+    void operator()(argument_type const &)
+    {
+        ++count;
+    }
+
+        /** return current size
+        */
+    result_type operator()() const
+    {
+        return count;
+    }
+
+        /** return current size
+        */
+    result_type size() const
+    {
+        return count;
+    }
+
+        /** merge two statistics
+        */
+    void operator()(FindROISize const & o)
+    {
+        count += o.count;
+    }
+
+        /** the current counter
+        */
+    result_type count;
+
+};
+
+template <class VALUETYPE>
+class FunctorTraits<FindROISize<VALUETYPE> >
+: public FunctorTraitsBase<FindROISize<VALUETYPE> >
+{
+  public:
+    typedef VigraTrueType isInitializer;
+    typedef VigraTrueType isUnaryAnalyser;
+};
+
+/********************************************************/
+/*                                                      */
+/*                FindBoundingRectangle                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the bounding rectangle of an ROI in an image.
+
+    As always in VIGRA, <TT>roiRect.lowerRight</TT> is <em> just outside the rectangle</em>.
+    That is, the last pixel actually in the rectangle is <TT>roiRect.lowerRight - Diff2D(1,1)</TT>.
+    This Functor is often used in conjunction with
+    \ref ArrayOfRegionStatistics to find the bounding rectangles
+    of all regions in a labeled image.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
+    are true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage img, mask;
+    ...
+
+    vigra::FindBoundingRectangle roiRect;   // init functor
+
+    // Diff2D is used as the iterator for the source image. This
+    // simulates an image where each pixel value equals the pixel's
+    // coordinates. The image 'mask' determines the ROI.
+    vigra::inspectImageIf(srcIterRange(Diff2D(0,0), (Diff2D)img.size()),
+                          srcImage(mask), roiRect);
+
+    cout << "Upper left of ROI: " <<
+        roiRect.upperLeft.x << ", " << roiRect.upperLeft.y << endl;
+    cout << "Lower right of ROI: " <<
+        roiRect.lowerRight.x << ", " << roiRect.lowerRight.y << endl;
+
+    \endcode
+
+*/
+class FindBoundingRectangle
+{
+  public:
+
+        /** the functor's argument type
+        */
+    typedef Diff2D argument_type;
+
+        /** the functors result type
+        */
+    typedef Rect2D result_type;
+
+        /** \deprecated use argument_type
+        */
+    typedef Diff2D value_type;
+
+        /** Upper left of the region as seen so far
+        */
+    Point2D upperLeft;
+
+        /** Lower right of the region as seen so far
+        */
+    Point2D lowerRight;
+
+        /** are the functors contents valid ?
+        */
+    bool valid;
+
+        /** init rectangle to invalid values
+        */
+    FindBoundingRectangle()
+    : valid(false)
+    {}
+
+        /** (re-)init functor to find other bounds
+        */
+    void reset()
+    {
+        valid = false;
+    }
+
+        /** update rectangle by including the coordinate coord
+        */
+    void operator()(argument_type const & coord)
+    {
+        if(!valid)
+        {
+            upperLeft = Point2D(coord);
+            lowerRight = Point2D(coord + Diff2D(1,1));
+            valid = true;
+        }
+        else
+        {
+            upperLeft.x = std::min(upperLeft.x, coord.x);
+            upperLeft.y = std::min(upperLeft.y, coord.y);
+            lowerRight.x = std::max(lowerRight.x, coord.x + 1);
+            lowerRight.y = std::max(lowerRight.y, coord.y + 1);
+        }
+    }
+
+        /** update rectangle by merging it with another rectangle
+        */
+    void operator()(FindBoundingRectangle const & otherRegion)
+    {
+        if(!valid)
+        {
+            upperLeft = otherRegion.upperLeft;
+            lowerRight = otherRegion.lowerRight;
+            valid = otherRegion.valid;
+        }
+        else if(otherRegion.valid)
+        {
+            upperLeft.x = std::min(upperLeft.x, otherRegion.upperLeft.x);
+            upperLeft.y = std::min(upperLeft.y, otherRegion.upperLeft.y);
+            lowerRight.x = std::max(lowerRight.x, otherRegion.lowerRight.x);
+            lowerRight.y = std::max(lowerRight.y, otherRegion.lowerRight.y);
+        }
+    }
+
+        /** Get size of current rectangle.
+        */
+    Size2D size() const
+    {
+        return lowerRight - upperLeft;
+    }
+
+        /** Get current rectangle. <TT>result_type::first</TT> is the upper
+            left corner of the rectangle, <TT>result_type::second</TT>
+            the lower right.
+        */
+    result_type operator()() const
+    {
+        return result_type(upperLeft, lowerRight);
+    }
+};
+
+template <>
+class FunctorTraits<FindBoundingRectangle>
+: public FunctorTraitsBase<FindBoundingRectangle>
+{
+  public:
+    typedef VigraTrueType isInitializer;
+    typedef VigraTrueType isUnaryAnalyser;
+};
+
+/********************************************************/
+/*                                                      */
+/*                 LastValueFunctor                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Stores and returns the last value it has seen.
+
+    This Functor is best used in conjunction with
+    \ref ArrayOfRegionStatistics to realize a look-up table.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
+    are true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage img;
+
+    vigra::ArrayOfRegionStatistics<LastValueFunctor<unsigned char> > lut(255);
+
+    for(int i=0; i<256; ++i)
+    {
+        lut[i] = ...; // init look-up table
+    }
+
+    vigra::transformImage(srcImageRange(img), destImage(img), lut);
+
+    \endcode
+
+*/
+template <class VALUETYPE>
+class LastValueFunctor
+{
+   public:
+
+        /** the functor's argument type
+        */
+    typedef VALUETYPE argument_type;
+
+        /** the functor's result type
+        */
+    typedef VALUETYPE result_type;
+
+        /** \deprecated use argument_type and result_type
+        */
+    typedef VALUETYPE value_type;
+
+        /** default construction of value (i.e. builtin types will be set to zero)
+        */
+    LastValueFunctor(argument_type const &initial = argument_type())
+    : value(initial)
+    {}
+
+        /** replace value
+        */
+    void operator=(argument_type const & v) { value = v; }
+
+        /** reset to initial value (the same as after default construction)
+        */
+    void reset() { value = VALUETYPE(); }
+
+        /** replace value
+        */
+    void operator()(argument_type const & v) { value = v; }
+
+        /** return current value
+        */
+    result_type const & operator()() const { return value; }
+
+        /** the current value
+        */
+    VALUETYPE value;
+
+};
+
+template <class VALUETYPE>
+class FunctorTraits<LastValueFunctor<VALUETYPE> >
+: public FunctorTraitsBase<LastValueFunctor<VALUETYPE> >
+{
+  public:
+    typedef VigraTrueType isInitializer;
+    typedef VigraTrueType isUnaryAnalyser;
+};
+
+/********************************************************/
+/*                                                      */
+/*                     ReduceFunctor                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply a functor to reduce the dimensionality of an array.
+
+    This functor can be used to emulate the <tt>reduce</tt> standard function of
+    functional programming using <tt>std::for_each()</tt> or <tt>inspectImage()</tt>
+    and similar functions. This functor is initialized with a functor encoding
+    the expression to be applied, and an accumulator storing the current state
+    of the reduction. For each element of the array, the embedded functor is called
+    with the accumulator and the current element(s) of the array. The result
+    of the reduction is available by calling <tt>reduceFunctor()</tt>.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryAnalyser</tt>, <tt>FunctorTraits::isBinaryAnalyser</tt>
+    and <tt>FunctorTraits::isInitializer</tt>
+    are true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage img;
+    ... // fill the image
+
+    // create a functor to sum the elements of the image
+    vigra::ReduceFunctor<std::plus<int>, int> sumElements(std::plus<int>, 0);
+
+    vigra::inspectImage(srcImageRange(img), sumElements);
+
+    cout << "The sum of the elements " << sumElements() << endl;
+
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+    FUNCTOR f;
+    VALUETYPE accumulator, current1, current2;
+
+    f(accumulator, current1); // for inspectImage()
+    f(accumulator, current1, current2); // for inspectTwoImages()
+    \endcode
+*/
+template <class FUNCTOR, class VALUETYPE>
+class ReduceFunctor
+{
+    FUNCTOR f_;
+    VALUETYPE start_, accumulator_;
+   public:
+
+        /** the functor's argument type
+            when used as a unary inspector.
+            (This is not strictly correct since the argument type
+            is actually a template parameter.)
+        */
+    typedef VALUETYPE argument_type;
+
+        /** the functor's first argument type
+            when used as a binary inspector.
+            (This is not strictly correct since the argument type
+            is actually a template parameter.)
+        */
+    typedef VALUETYPE first_argument_type;
+
+        /** the functor's second argument type
+            when used as a binary inspector.
+            (This is not strictly correct since the argument type
+            is actually a template parameter.)
+        */
+    typedef VALUETYPE second_argument_type;
+
+        /** the functor's result type
+        */
+    typedef VALUETYPE result_type;
+
+        /** create with the given functor and initial value \a initial
+            for the accumulator.
+        */
+    ReduceFunctor(FUNCTOR const & f, VALUETYPE const & initial)
+    : f_(f),
+      start_(initial),
+      accumulator_(initial)
+    {}
+
+        /** Reset accumulator to the initial value.
+        */
+    void reset()
+      { accumulator_ = start_; }
+
+        /** Use binary functor to connect given value with the accumulator.
+            The accumulator is used as the first argument, the value \a v
+            as the second.
+        */
+    template <class T>
+    void operator()(T const & v)
+    {
+        accumulator_ = f_(accumulator_, v);
+    }
+
+        /** Use ternary functor to connect given values with accumulator.
+            The accumulator is used as the first argument, the values \a v1
+            ans \a v2 as the second and third.
+        */
+    template <class T1, class T2>
+    void operator()(T1 const & v1, T2 const & v2)
+    {
+        accumulator_ = f_(accumulator_, v1, v2);
+    }
+
+        /** return current value
+        */
+    result_type const & operator()() const
+      { return accumulator_; }
+};
+
+template <class FUNCTOR, class VALUETYPE>
+ReduceFunctor<FUNCTOR, VALUETYPE>
+reduceFunctor(FUNCTOR const & f, VALUETYPE const & initial)
+{
+    return ReduceFunctor<FUNCTOR, VALUETYPE>(f, initial);
+}
+
+template <class FUNCTOR, class VALUETYPE>
+class FunctorTraits<ReduceFunctor<FUNCTOR, VALUETYPE> >
+: public FunctorTraitsBase<ReduceFunctor<FUNCTOR, VALUETYPE> >
+{
+  public:
+    typedef VigraTrueType isInitializer;
+    typedef VigraTrueType isUnaryAnalyser;
+    typedef VigraTrueType isBinaryAnalyser;
+};
+
+/********************************************************/
+/*                                                      */
+/*              ArrayOfRegionStatistics                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate statistics for all regions of a labeled image.
+
+    This Functor encapsulates an array of statistics functors, one
+    for each label, and selects the one to be updated according to the
+    pixel's label.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isBinaryAnalyser</tt> and <tt>FunctorTraits::isUnaryFunctor</tt>
+    are true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/inspectimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage img;
+    vigra::IImage labels;
+    int max_label;
+    ...
+
+    // init functor as an array of 'max_label' FindMinMax-Functors
+    vigra::ArrayOfRegionStatistics<vigra::FindMinMax<vigra::BImage::PixelType> >
+                                                         minmax(max_label);
+
+    vigra::inspectTwoImages(srcImageRange(img), srcImage(labels), minmax);
+
+    for(int i=0; i<= max_label; ++i)
+    {
+        cout << "Max gray level of region " << i << ": "
+             << minmax.region[i].max << endl;
+    }
+
+    // init functor as an array of 'max_label' FindAverage-Functors
+    vigra::ArrayOfRegionStatistics<vigra::FindAverage<vigra::BImage::PixelType> >
+                                                         average(max_label);
+
+    vigra::inspectTwoImages(srcImageRange(img), srcImage(labels), average);
+
+    // write back the average of each region into the original image
+    vigra::transformImage(srcImageRange(labels), destImage(img), average);
+
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+    RegionStatistics region;
+    RegionStatistics::argument_type a;
+    RegionStatistics::result_type r;
+
+    region(a);     // update statistics
+    r = region();  // return statistics
+
+    \endcode
+*/
+template <class RegionStatistics, class LabelType = int>
+class ArrayOfRegionStatistics
+    : public detail::get_extra_passes<RegionStatistics>
+{
+    typedef std::vector<RegionStatistics> RegionArray;
+
+  public:
+         /** argument type of the contained statistics object
+             becomes first argument of the analyser
+         */
+    typedef typename RegionStatistics::argument_type first_argument_type;
+
+         /** label type is used to determine the region to be updated
+         */
+    typedef LabelType second_argument_type;
+
+         /** label type is also used to determine the region to be
+             returned by the 1 argument operator()
+         */
+    typedef LabelType argument_type;
+
+         /** result type of the contained statistics object
+             becomes result type of the analyser
+         */
+    typedef typename RegionStatistics::result_type result_type;
+
+         /** the value type of the array: the contained statistics object.
+             <b>Note:</b> this definition was different in older
+             VIGRA versions. The old definition was wrong.
+         */
+    typedef RegionStatistics value_type;
+
+         /** the array's reference type
+         */
+    typedef RegionStatistics & reference;
+
+         /** the array's const reference type
+         */
+    typedef RegionStatistics const & const_reference;
+
+         /** type to iterate over the statistics array
+         */
+    typedef typename RegionArray::iterator iterator;
+
+         /** type to iterate over a const statistics array
+         */
+    typedef typename RegionArray::const_iterator const_iterator;
+
+        /** init array of RegionStatistics with default size 0.
+        */
+    ArrayOfRegionStatistics()
+    {}
+
+        /** init array of RegionStatistics with index domain
+            0...max_region_label.
+        */
+    ArrayOfRegionStatistics(unsigned int max_region_label)
+    : regions(max_region_label+1)
+    {}
+
+        /** resize array to new index domain 0...max_region_label.
+            All bin are re-initialized.
+        */
+    void resize(unsigned int max_region_label)
+    {
+        RegionArray newRegions(max_region_label+1);
+        regions.swap(newRegions);
+    }
+
+        /** reset the contained functors to their initial state.
+        */
+    void reset()
+    {
+        RegionArray newRegions(regions.size());
+        regions.swap(newRegions);
+    }
+
+        /** update regions statistics for region <TT>label</TT>. The label type
+            is converted to <TT>unsigned int</TT>.
+        */
+    void operator()(first_argument_type const & v, second_argument_type label) {
+        regions[static_cast<unsigned int>(label)](v);
+    }
+
+        /** merge second region into first
+        */
+    void merge(argument_type label1, argument_type label2) {
+        regions[static_cast<unsigned int>(label1)](regions[static_cast<unsigned int>(label2)]);
+    }
+
+        /** ask for maximal index (label) allowed
+        */
+    unsigned int maxRegionLabel() const
+        { return size() - 1; }
+
+        /** ask for array size (i.e. maxRegionLabel() + 1)
+        */
+    unsigned int size() const
+        { return regions.size(); }
+
+        /** access the statistics for a region via its label. The label type
+            is converted to <TT>unsigned int</TT>.
+        */
+    result_type operator()(argument_type label) const
+        { return regions[static_cast<unsigned int>(label)](); }
+
+        /** read the statistics functor for a region via its label
+        */
+    const_reference operator[](argument_type label) const
+        { return regions[static_cast<unsigned int>(label)]; }
+
+        /** access the statistics functor for a region via its label
+        */
+    reference operator[](argument_type label)
+        { return regions[static_cast<unsigned int>(label)]; }
+
+        /** iterator to the begin of the region array
+        */
+    iterator begin()
+        { return regions.begin(); }
+
+        /** const iterator to the begin of the region array
+        */
+    const_iterator begin() const
+        { return regions.begin(); }
+
+        /** iterator to the end of the region array
+        */
+    iterator end()
+        { return regions.end(); }
+
+        /** const iterator to the end of the region array
+        */
+    const_iterator end() const
+        { return regions.end(); }
+
+        /** prepare next pass for multi-pass RegionStatistics types
+        */
+    void calc_sync()
+    {
+        for (iterator j = begin(); j != end(); ++j)
+            this->sync(*j);
+    }
+    // update: passes >= 2
+    struct pass_n_dispatch
+    {
+        ArrayOfRegionStatistics & x;
+        unsigned                  pass_number;
+        pass_n_dispatch(ArrayOfRegionStatistics & a, unsigned n)
+            : x(a), pass_number(n) {}
+        template <class S> // instantiate only when used.
+        void operator()(const first_argument_type & v, S label)
+        {
+            x.regions[static_cast<unsigned>(label)].updatePassN(v, pass_number);
+        }
+    };
+    template <class N> // instantiate only when used.
+    pass_n_dispatch pass_n(N n)
+    {
+        if (n < 2 || static_cast<unsigned>(n) > this->max_passes)
+            vigra_fail("ArrayOfRegionStatistics::pass_n(): inconsistent use.");
+        return pass_n_dispatch(*this, n);
+    }
+
+    std::vector<RegionStatistics> regions;
+};
+
+template <class RegionStatistics, class LabelType>
+class FunctorTraits<ArrayOfRegionStatistics<RegionStatistics, LabelType> >
+: public FunctorTraitsBase<ArrayOfRegionStatistics<RegionStatistics, LabelType> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+    typedef VigraTrueType isBinaryAnalyser;
+};
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_INSPECTIMAGE_HXX
diff --git a/include/vigra/inspector_passes.hxx b/include/vigra/inspector_passes.hxx
new file mode 100644
index 0000000..bac8ea7
--- /dev/null
+++ b/include/vigra/inspector_passes.hxx
@@ -0,0 +1,79 @@
+#ifndef VIGRA_INSPECTOR_PASSES_HXX
+#define VIGRA_INSPECTOR_PASSES_HXX
+
+#include "metaprogramming.hxx"
+
+namespace vigra {
+
+// test and accomodate for functors that require extra passes over arrays / etc.
+
+namespace detail {
+
+template <bool>
+struct extra_passes_selector
+{
+    template <class Inspector, class Functor>
+    static void
+    call(Inspector, Functor &) {}
+};
+template <>
+struct extra_passes_selector<true>
+{
+    template <class Inspector, class Functor_n>
+    static void
+    call_n(Inspector g, Functor_n f_n)
+    {
+        g(f_n);
+    }
+    template <class Inspector, class Functor>
+    static void
+    call(Inspector g, Functor & f)
+    {
+        for (unsigned n = 2; n <= Functor::max_passes; ++n)
+        {
+            f.calc_sync();
+            call_n(g, f.pass_n(n));
+        }
+    }
+};
+
+template <class T>
+struct has_extra_passes : public sfinae_test<T, has_extra_passes>
+{
+    template <class U> has_extra_passes(U*, typename U::extra_passes* = 0);
+};
+
+template <class Functor, bool extra = has_extra_passes<Functor>::value>
+struct get_extra_passes
+    : public VigraFalseType
+{
+    void sync(Functor &) {}
+};
+
+template <class Functor>
+struct get_extra_passes<Functor, true>
+{
+    typedef get_extra_passes extra_passes;
+    static const unsigned max_passes = Functor::max_passes;
+    static const bool value = Functor::max_passes >= 2;
+
+    void sync(Functor & f)
+    {
+        f.calc_sync();
+    }
+};
+
+template <class Inspector, class Functor>
+inline
+void
+extra_passes_select(Inspector g, Functor & f)
+{
+    g(f);
+    extra_passes_selector<get_extra_passes<Functor>::value>::call(g, f);
+}
+
+} // namespace detail
+
+} // namespace vigra
+
+#endif // VIGRA_INSPECTOR_PASSES_HXX
diff --git a/include/vigra/interpolating_accessor.hxx b/include/vigra/interpolating_accessor.hxx
new file mode 100644
index 0000000..26b1ebc
--- /dev/null
+++ b/include/vigra/interpolating_accessor.hxx
@@ -0,0 +1,170 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_INTERPOLATING_ACCESSOR_HXX
+#define VIGRA_INTERPOLATING_ACCESSOR_HXX
+
+
+#include "accessor.hxx"
+#include "diff2d.hxx"
+
+namespace vigra {
+
+/** \addtogroup DataAccessors
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*            BilinearInterpolatingAccessor             */
+/*                                                      */
+/********************************************************/
+
+/** \brief Bilinear interpolation at non-integer positions.
+
+    This accessor allows an image be accessed at arbitrary non-integer
+    coordinates and performs an bi-linear interpolation to
+    obtain a pixel value.
+    It uses the given ACCESSOR (which is usually the
+    accessor originally associated with the iterator)
+    to access data.
+
+    <b>\#include</b> \<vigra/accessor.hxx\>
+    Namespace: vigra
+
+    <b> Required Interface:</b>
+
+    \code
+    ITERATOR iter;
+    ACCESSOR a;
+    VALUETYPE destvalue;
+    float s;
+    int x, y;
+
+    destvalue = s * a(iter, x, y) + s * a(iter, x, y);
+
+    \endcode
+*/
+template <class ACCESSOR, class VALUETYPE>
+class BilinearInterpolatingAccessor
+{
+  public:
+    /** the iterators' pixel type
+    */
+    typedef VALUETYPE value_type;
+
+    /** init from given accessor
+    */
+    BilinearInterpolatingAccessor(ACCESSOR a)
+    : a_(a)
+    {}
+
+    /** Interpolate the data item at a non-integer position.
+        Ensure that no outside pixels are accessed if
+        (x, y) is near the image border (as long as
+        0 <= x <= width-1, 0 <= y <= height-1).
+    */
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i, float x, float y) const
+    {
+        int ix = int(x);
+        int iy = int(y);
+        float dx = x - ix;
+        float dy = y - iy;
+
+        value_type ret;
+
+        // avoid dereferencing the iterator outside its range
+        if(dx == 0.0)
+        {
+            if(dy == 0.0)
+            {
+                ret = a_(i, Diff2D(ix, iy));
+            }
+            else
+            {
+                ret = detail::RequiresExplicitCast<value_type>::cast(
+                  (1.0 - dy) * a_(i, Diff2D(ix, iy)) +
+                  dy * a_(i, Diff2D(ix, iy + 1)));
+            }
+        }
+        else
+        {
+            if(dy == 0.0)
+            {
+                ret = detail::RequiresExplicitCast<value_type>::cast(
+                  (1.0 - dx) * a_(i, Diff2D(ix, iy)) +
+                  dx * a_(i, Diff2D(ix + 1, iy)));
+            }
+            else
+            {
+                ret = detail::RequiresExplicitCast<value_type>::cast(
+                  (1.0 - dx) * (1.0 - dy) * a_(i, Diff2D(ix, iy)) +
+                  dx * (1.0 - dy) * a_(i, Diff2D(ix + 1, iy)) +
+                  (1.0 - dx) * dy * a_(i, Diff2D(ix, iy + 1)) +
+                  dx * dy * a_(i, Diff2D(ix + 1, iy + 1)));
+            }
+        }
+
+        return ret;
+    }
+
+    /** Interpolate the data item at a non-integer position.
+        This function works as long as 0 <= x < width-1,
+        0 <= y < height-1. It is slightly faster than <TT>operator()</TT>.
+    */
+    template <class ITERATOR>
+    value_type unchecked(ITERATOR const & i, float x, float y) const
+    {
+        int ix = int(x);
+        int iy = int(y);
+        float dx = x - ix;
+        float dy = y - iy;
+        return detail::RequiresExplicitCast<value_type>::cast(
+               (1.0 - dx) * (1.0 - dy) * a_(i, Diff2D(ix, iy)) +
+               dx * (1.0 - dy) * a_(i, Diff2D(ix + 1, iy)) +
+               (1.0 - dx) * dy * a_(i, Diff2D(ix, iy + 1)) +
+               dx * dy * a_(i, Diff2D(ix + 1, iy + 1)));
+    }
+
+  private:
+    ACCESSOR a_;
+};
+
+//@}
+
+} // namespace vigra
+
+#endif /* VIGRA_INTERPOLATING_ACCESSOR_HXX */
diff --git a/include/vigra/invariant_features3D.hxx b/include/vigra/invariant_features3D.hxx
new file mode 100644
index 0000000..5c15d97
--- /dev/null
+++ b/include/vigra/invariant_features3D.hxx
@@ -0,0 +1,71 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2009-2010 by Ullrich Koethe and Janis Fehr          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_INVARIANT_FEATURES3D_HXX
+#define VIGRA_INVARIANT_FEATURES3D_HXX
+
+#include <complex>
+#include "config.hxx"
+#include "error.hxx"
+#include "utilities.hxx"
+#include "mathutil.hxx"
+#include "array_vector.hxx"
+#include "matrix.hxx"
+#include "tinyvector.hxx"
+#include "quaternion.hxx"
+
+namespace vigra {
+
+namespace detail  {
+
+// computes the normalization for SH base functions
+inline double realSH(double l, double m)
+{
+    return std::sqrt((2.0*l + 1.0) / (4.0*M_PI*facLM(l,m)));
+
+}
+
+template<int N, class T, class C>
+TinyVector<float, N> centerOfBB(MultiArrayView<N, T, C> const & A)
+{
+    return TinyVector<float, N>(A.shape()) /= 2.0;                        
+}
+
+} // namespace detail
+
+
+} // namespace vigra 
+
+#endif // VIGRA_INVARIANT_FEATURES3D_HXX
diff --git a/include/vigra/iteratoradapter.hxx b/include/vigra/iteratoradapter.hxx
new file mode 100644
index 0000000..3d86c0e
--- /dev/null
+++ b/include/vigra/iteratoradapter.hxx
@@ -0,0 +1,302 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_ITERATORADAPTER_HXX
+#define VIGRA_ITERATORADAPTER_HXX
+
+namespace vigra {
+
+/********************************************************/
+/*                                                      */
+/*                    IteratorAdaptor                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Quickly create 1-dimensional iterator adapters.
+
+    This class supports the easy creation of 1D iterator adapters out
+    of existing iterators. To use it, you must first implement a policy class
+    that defines the iterator's behavior. The policy is used to
+    instantiate the IteratorAdapter template, which thus automatically
+    obtains all required functions of an STL-compatible iterator.
+    General information on how this works can be found on the
+    <a href="http://www.boost.org/libs/utility/iterator_adaptors.htm">Boost Iterator Adaptor</a>
+    page, although there are some differences in the details of the
+    boost and VIGRA implementations.
+    Here is an example policy class that just exports the behaviour
+    of the underlying iterator:
+
+    \code
+    template <class Iterator>
+    class TrivialIteratorAdaptorPolicy
+    {
+      public:
+        // the underlying iterator
+        typedef Iterator                               BaseType;
+
+        // the adaptor's value type
+        typedef typename Iterator::value_type          value_type;
+
+        // the adaptor's difference type (result of 'iter1 - iter2',
+        //                                argument of 'iter[n]')
+        typedef typename Iterator::difference_type     difference_type;
+
+        // the adaptor's reference type (result of '*iter')
+        typedef typename Iterator::reference           reference;
+
+        // the adaptor's index_reference type (result of 'iter[n]')
+        typedef typename Iterator::index_reference     index_reference;
+
+        // the adaptor's pointer type (result of 'iter.operator->()')
+        typedef typename Iterator::pointer             pointer;
+
+        // the adaptor's iterator category
+        typedef typename Iterator::iterator_category   iterator_category;
+
+        // do some additional initialization in the adaptor's constructor
+        static void initialize(BaseType & d) {}
+
+        // called by '*iter', 'iter->'
+        static reference dereference(BaseType const & d)
+            { return *d; }
+
+        // called by 'iter[n]'
+        static index_reference dereference(BaseType d, difference_type n)
+            { return d[n]; }
+
+        // called by 'iter1 == iter2', 'iter1 != iter2'
+        static bool equal(BaseType const & d1, BaseType const & d2)
+            { return d1 == d2; }
+
+        // called by 'iter1 < iter2', 'iter1 <= iter2', 'iter1 > iter2', 'iter1 >= iter2'
+        static bool less(BaseType const & d1, BaseType const & d2)
+            { return d1 < d2; }
+
+        // called by 'iter1 - iter2'
+        static difference_type difference(BaseType const & d1, BaseType const & d2)
+            { return d1 - d2; }
+
+        // called by '++iter', 'iter++'
+        static void increment(BaseType & d)
+            { ++d; }
+
+        // called by '--iter', 'iter--'
+        static void decrement(BaseType & d)
+            { --d; }
+
+        // called by 'iter += n', 'iter -= n'
+        static void advance(BaseType & d, difference_type n)
+            { d += n; }
+    };
+    \endcode
+
+    This policy class is used like this:
+
+    \code
+    SomeIterator iter = ...;
+
+    vigra::IteratorAdaptor<vigra::TrivialIteratorAdaptorPolicy<SomeIterator> > iter_adaptor(iter);
+    \endcode
+
+    By changing the definition of the policy members, a wide range of
+    adaptor behaviors can be achieved. If the base iterator isn't a
+    random access iterator, just drop the functions that cannot be implemented.
+    This simply means that some adaptor functions may not be called,
+    as one would expect from an iterator that doesn't support random access.
+    Note also that the <TT>BaseType</TT> needs not be an iterator -
+    it can be any type that contains the information necessary for the
+    adaptor to do it's work.
+
+    <b>\#include</b> \<vigra/iteratoradapter.hxx\><br>
+    Namespace: vigra
+
+*/
+template <class Policy>
+class IteratorAdaptor
+{
+  public:
+
+    typedef typename Policy::BaseType BaseType;
+    typedef typename Policy::value_type        value_type;
+    typedef typename Policy::difference_type   difference_type;
+    typedef typename Policy::reference         reference;
+    typedef typename Policy::index_reference   index_reference;
+    typedef typename Policy::pointer           pointer;
+    typedef typename Policy::iterator_category iterator_category;
+
+    IteratorAdaptor()
+    : adaptee_()
+    {}
+
+        /** Construct from an instance of the policy class' BaseType
+            Note that the functions of the adaptor implement the
+            interface of an random access iterator as defined in the
+            C++ standard, so there is no need for explicit documentation.
+        */
+    explicit IteratorAdaptor(BaseType const & o)
+    : adaptee_(o)
+    {
+        Policy::initialize(adaptee_);
+    }
+
+    IteratorAdaptor(IteratorAdaptor const & o)
+    : adaptee_(o.adaptee_)
+    {}
+
+    IteratorAdaptor & operator=(BaseType const & o)
+    {
+        if(this != &o)
+        {
+            adaptee_ = o;
+            Policy::initialize(adaptee_);
+        }
+        return *this;
+    }
+
+    IteratorAdaptor & operator=(IteratorAdaptor const & o)
+    {
+        if(this != &o)
+            adaptee_ = o.adaptee_;
+        return *this;
+    }
+
+    IteratorAdaptor & operator+=(difference_type d)
+    {
+        Policy::advance(adaptee_, d);
+        return *this;
+    }
+
+    IteratorAdaptor operator+(difference_type d) const
+    {
+        return IteratorAdaptor(*this) += d;
+    }
+
+    IteratorAdaptor & operator-=(difference_type d)
+    {
+        Policy::advance(adaptee_, -d);
+        return *this;
+    }
+
+    IteratorAdaptor operator-(difference_type d) const
+    {
+        return IteratorAdaptor(*this) -= d;
+    }
+
+    IteratorAdaptor & operator++()
+    {
+        Policy::increment(adaptee_);
+        return *this;
+    }
+
+    IteratorAdaptor operator++(int)
+    {
+        IteratorAdaptor res(*this);
+        Policy::increment(adaptee_);
+        return res;
+    }
+
+    IteratorAdaptor & operator--()
+    {
+        Policy::decrement(adaptee_);
+        return *this;
+    }
+
+    IteratorAdaptor operator--(int)
+    {
+        IteratorAdaptor res(*this);
+        Policy::decrement(adaptee_);
+        return res;
+    }
+
+    bool operator==(IteratorAdaptor const & o) const
+    {
+        return Policy::equal(adaptee_, o.adaptee_);
+    }
+
+    bool operator!=(IteratorAdaptor const & o) const
+    {
+        return !Policy::equal(adaptee_, o.adaptee_);
+    }
+
+    bool operator<(IteratorAdaptor const & o) const
+    {
+        return Policy::less(adaptee_, o.adaptee_);
+    }
+
+    bool operator<=(IteratorAdaptor const & o) const
+    {
+        return !Policy::less(o.adaptee_, adaptee_);
+    }
+
+    bool operator>(IteratorAdaptor const & o) const
+    {
+        return Policy::less(o.adaptee_, adaptee_);
+    }
+
+    bool operator>=(IteratorAdaptor const & o) const
+    {
+        return !Policy::less(adaptee_, o.adaptee_);
+    }
+
+    difference_type operator-(IteratorAdaptor const & o) const
+    {
+        return Policy::difference(adaptee_, o.adaptee_);
+    }
+
+    reference operator*() const
+    {
+        return Policy::dereference(adaptee_);
+    }
+
+    index_reference operator[](difference_type d) const
+    {
+        return Policy::dereference(adaptee_, d);
+    }
+
+    pointer operator->() const
+    {
+        return &Policy::dereference(adaptee_);
+    }
+
+  protected:
+
+    BaseType adaptee_;
+};
+
+} // namespace vigra
+
+
+#endif /* VIGRA_ITERATORADAPTER_HXX */
diff --git a/include/vigra/iteratortags.hxx b/include/vigra/iteratortags.hxx
new file mode 100644
index 0000000..2d49443
--- /dev/null
+++ b/include/vigra/iteratortags.hxx
@@ -0,0 +1,52 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2003 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_ITERATORTAGS_HXX
+#define VIGRA_ITERATORTAGS_HXX
+
+#include <iterator>   // iterator tags
+
+struct image_traverser_tag {};
+
+struct multi_dimensional_traverser_tag {};
+
+struct forward_circulator_tag {};
+
+struct bidirectional_circulator_tag {};
+
+struct random_access_circulator_tag {};
+
+
+#endif /* VIGRA_ITERATORTAGS_HXX */
diff --git a/include/vigra/iteratortraits.hxx b/include/vigra/iteratortraits.hxx
new file mode 100644
index 0000000..e7f3577
--- /dev/null
+++ b/include/vigra/iteratortraits.hxx
@@ -0,0 +1,701 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_ITERATORTRAITS_HXX
+#define VIGRA_ITERATORTRAITS_HXX
+
+#include "accessor.hxx"
+#include "imageiteratoradapter.hxx"
+
+namespace vigra {
+
+/** \addtogroup ImageIterators
+*/
+//@{
+/** \brief Export associated information for each image iterator.
+
+    The IteratorTraits class contains the following fields:
+
+    \code
+    template <class T>
+    struct IteratorTraits
+    {
+        typedef T                                     Iterator;
+        typedef Iterator                              iterator;
+        typedef typename iterator::iterator_category  iterator_category;
+        typedef typename iterator::value_type         value_type;
+        typedef typename iterator::reference          reference;
+        typedef typename iterator::index_reference    index_reference;
+        typedef typename iterator::pointer            pointer;
+        typedef typename iterator::difference_type    difference_type;
+        typedef typename iterator::row_iterator       row_iterator;
+        typedef typename iterator::column_iterator    column_iterator;
+        typedef typename
+         AccessorTraits<value_type>::default_accessor DefaultAccessor;
+        typedef DefaultAccessor                       default_accessor;
+
+        typedef VigraTrueType/VigraFalseType          hasConstantStrides;
+    };
+    \endcode
+
+    By (partially) specializing this template for an iterator class
+    the defaults given above can be changed as appropriate. For example, iterators
+    for rgb images are associated with <TT>RGBAccessor<value_type></TT>
+    instead of <TT>StandardAccessor<value_type></TT>. To get the accessor
+    associated with a given iterator, use code like this:
+
+    \code
+    template <class Iterator>
+    void foo(Iterator i)
+    {
+        typedef typename IteratorTraits<Iterator>::DefaultAccessor Accessor;
+        Accessor a;
+        ...
+    }
+    \endcode
+
+    This technique is, for example, used by the
+    \ref IteratorBasedArgumentObjectFactories. The possibility to retrieve the default accessor by means of a traits
+    class is especially important since this information is not
+    contained in the iterator directly.
+    
+    The member <tt>hasConstantStrides</tt> is useful for certain 
+    optimizations: it helps to decide whether we can replace iterator
+    operations such as <tt>iter++</tt> or <tt>iter += n</tt> with
+    corresponding pointer operations (which may be faster), where
+    the pointer is obtained as the address of iterator's pointee 
+    (the object the iterator currently  refers to). 
+    This flag would be <tt>VigraFalseType</tt> for a
+    <tt>std::list<int>::iterator</tt>, but is <tt>VigraTrueType</tt> 
+    for most VIGRA iterators.
+
+    <b>\#include</b> \<vigra/iteratortraits.hxx\>
+    Namespace: vigra
+*/
+template <class T>
+struct IteratorTraits
+{
+    typedef T                                          Iterator;
+    typedef Iterator                                   iterator;
+    typedef typename iterator::iterator_category       iterator_category;
+    typedef typename iterator::value_type              value_type;
+    typedef typename iterator::reference               reference;
+    typedef typename iterator::index_reference         index_reference;
+    typedef typename iterator::pointer                 pointer;
+    typedef typename iterator::difference_type         difference_type;
+    typedef typename iterator::row_iterator            row_iterator;
+    typedef typename iterator::column_iterator         column_iterator;
+    typedef typename
+        AccessorTraits<value_type>::default_accessor   DefaultAccessor;
+    typedef DefaultAccessor                            default_accessor;
+
+    // default: disable the constant strides optimization
+    typedef VigraFalseType                             hasConstantStrides;
+};
+
+template <class T>
+struct IteratorTraitsBase
+{
+    typedef T                                     Iterator;
+    typedef Iterator                              iterator;
+    typedef typename iterator::iterator_category  iterator_category;
+    typedef typename iterator::value_type         value_type;
+    typedef typename iterator::reference          reference;
+    typedef typename iterator::index_reference    index_reference;
+    typedef typename iterator::pointer            pointer;
+    typedef typename iterator::difference_type    difference_type;
+    typedef typename iterator::row_iterator       row_iterator;
+    typedef typename iterator::column_iterator    column_iterator;
+};
+
+
+//@}
+
+
+/***********************************************************/
+
+/** \page ArgumentObjectFactories Argument Object Factories
+
+    Factory functions to create argument objects which simplify long argument lists.
+
+    <UL style="list-style-image:url(documents/bullet.gif)">
+    <LI> \ref ImageBasedArgumentObjectFactories
+    <LI> \ref MultiArrayBasedArgumentObjectFactories
+    <LI> \ref IteratorBasedArgumentObjectFactories
+    </UL>
+
+    Long argument lists provide for greater flexibility of functions,
+    but they are also tedious and error prone, when we don't need
+    the flexibility. Thus, we define argument objects which
+    automatically provide reasonable defaults for those arguments that we
+    didn't specify explicitly.
+
+    The argument objects are created via a number of factory functions.
+    Since these functions have descriptive names, they also serve
+    to improve readability: the name of each factory tells te purpose of its
+    argument object.
+
+    Consider the following example. Without argument objects we had to
+    write something like this (cf. \ref copyImageIf()):
+
+    \code
+    vigra::BImage img1, img2, img3;
+
+    // fill img1 and img2 ...
+
+    vigra::copyImageIf(img1.upperLeft(), img1.lowerRight(), img1.accessor(),
+                img2.upperLeft(), img2.accessor(),
+                img3.upperLeft(), img3.accessor());
+    \endcode
+
+    Using the argument object factories, this becomes much shorter and
+    more readable:
+
+    \code
+    vigra::copyImageIf(srcImageRange(img1),
+                maskImage(img2),
+                destImage(img3));
+    \endcode
+
+    The names of the factories clearly tell which image is source, mask,
+    and destination. In addition, the suffix <TT>Range</TT> must be used
+    for those argument objects that need to specify the lower right
+    corner of the region of interest. Typically, this is only the first
+    source argument, but sometimes the first destiniation argument must
+    also contain a range.
+
+    The factory functions come in two flavours: Iterator based and
+    image based factories. Above we have seen the image based variant.
+    The iterator based variant would look like this:
+
+    \code
+    vigra::copyImageIf(srcIterRange(img1.upperLeft(), img1.lowerRight()),
+                maskIter(img2.upperLeft()),
+                destIter(img3.upperLeft()));
+    \endcode
+
+    These factory functions contain the word <TT>Iter</TT> instead of the word
+    <TT>Image</TT>,  They would normally be used if we couldn't access the
+    images (for example, within a function which got passed iterators)
+    or if we didn't want to operate on the entire image. The default
+    accessor is obtained via \ref vigra::IteratorTraits.
+
+    All factory functions also allow to specify accessors explicitly. This
+    is useful if we can't use the default accessor. This variant looks
+    like this:
+
+    \code
+    vigra::copyImageIf(srcImageRange(img1),
+                maskImage(img2, MaskPredicateAccessor()),
+                destImage(img3));
+    \endcode
+
+    or
+
+    \code
+    vigra::copyImageIf(srcIterRange(img1.upperLeft(), img1.lowerRight()),
+                maskIter(img2.upperLeft(), MaskPredicateAccessor()),
+                destIter(img3.upperLeft()));
+    \endcode
+
+    All versions can be mixed freely within one expression.
+    Technically, the argument objects are simply defined as
+    pairs and triples of iterators and accessor so that all algorithms
+    should declare a call interface version based on pairs and triples
+    (see for example \ref copyImageIf()).
+
+  \section ImageBasedArgumentObjectFactories Image Based Argument Object Factories
+
+    <b>Include:</b> automatically included with the image classes<br>
+    Namespace: vigra
+
+    These factories can be used to create argument objects when we
+    are given instances or subclasses of \ref vigra::BasicImage (see
+    \ref StandardImageTypes for instances defined per default).
+    These factory functions access <TT>img.upperLeft()</TT>,
+    <TT>img.lowerRight()</TT>, and <TT>img.accessor()</TT> to obtain the iterators
+    and accessor for the given image (unless the accessor is
+    given explicitly). The following factory functions are provided:
+
+    <table>
+    <tr><th bgcolor="#f0e0c0" colspan=2 align=left>
+        <TT>\ref vigra::BasicImage "vigra::BasicImage<SomeType>" img;</TT> or <br>
+         <TT>\ref vigra::BasicImageView "vigra::BasicImageView<SomeType>" img;</TT>
+        </th>
+    </tr>
+    <tr><td>
+
+    <TT>srcImageRange(img)</TT>
+    </td><td>
+        create argument object containing upper left, lower right, and
+        default accessor of source image
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcImageRange(img, Rect2D(...))</TT>
+    </td><td>
+        create argument object containing the ROI specified by <tt>\ref vigra::Rect2D</tt> and
+        default accessor of source image
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcImageRange(img, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing upper left, lower right
+        of source image, and given accessor
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcImageRange(img, Rect2D(...), SomeAccessor())</TT>
+    </td><td>
+        create argument object containing the ROI specified by <tt>\ref vigra::Rect2D</tt> and
+        of source image, and given accessor
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcImage(img)</TT>
+    </td><td>
+        create argument object containing upper left, and
+        default accessor of source image
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcImage(img, Point2D(...))</TT>
+    </td><td>
+        create argument object with upper left at point given by <tt>\ref vigra::Point2D</tt>, and
+        default accessor of source image
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcImage(img, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing upper left
+        of source image, and given accessor
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcImage(img, Point2D(...), SomeAccessor())</TT>
+    </td><td>
+        create argument object with upper left at point given by <tt>\ref vigra::Point2D</tt> of source image,
+        and given accessor
+
+    </td></tr>
+    <tr><td>
+
+    <TT>maskImage(img)</TT>
+    </td><td>
+        create argument object containing upper left, and
+        default accessor of mask image
+
+    </td></tr>
+     <tr><td>
+
+    <TT>maskImage(img, Point2D(...))</TT>
+    </td><td>
+        create argument object with upper left at point given by <tt>\ref vigra::Point2D</tt>, and
+        default accessor of mask image
+
+    </td></tr>
+   <tr><td>
+
+    <TT>maskImage(img, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing upper left
+        of mask image, and given accessor
+
+    </td></tr>
+    <tr><td>
+
+    <TT>maskImage(img, Point2D(...), SomeAccessor())</TT>
+    </td><td>
+        create argument object with upper left at point given by <tt>\ref vigra::Point2D</tt> of mask image,
+        and given accessor
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destImageRange(img)</TT>
+    </td><td>
+        create argument object containing upper left, lower right, and
+        default accessor of destination image
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destImageRange(img, Rect2D(...))</TT>
+    </td><td>
+        create argument object containing the ROI specified by <tt>\ref vigra::Rect2D</tt> and
+        default accessor of destination image
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destImageRange(img, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing upper left, lower right
+        of destination image, and given accessor
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destImageRange(img, Rect2D(...), SomeAccessor())</TT>
+    </td><td>
+        create argument object containing the ROI specified by <tt>\ref vigra::Rect2D</tt>
+        of destination image, and given accessor
+
+    </td></tr>
+     <tr><td>
+
+    <TT>destImage(img)</TT>
+    </td><td>
+        create argument object containing upper left, and
+        default accessor of destination image
+
+    </td></tr>
+     <tr><td>
+
+    <TT>destImage(img, Point2D(...))</TT>
+    </td><td>
+        create argument object with upper left at point given by <tt>\ref vigra::Point2D</tt>, and
+        default accessor of destination image
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destImage(img, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing upper left
+        of destination image, and given accessor
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destImage(img, Point2D(...), SomeAccessor())</TT>
+    </td><td>
+        create argument object with upper left at point given by <tt>\ref vigra::Point2D</tt> of destination image,
+        and given accessor
+
+    </td></tr>
+    </table>
+
+
+  \section MultiArrayBasedArgumentObjectFactories MultiArrayView Based Argument Object Factories
+
+    <b>Include:</b> automatically included with 
+       \<vigra/multi_array.hxx\><br>
+    Namespace: vigra
+
+    These factories can be used to create argument objects when we
+    are given instances or subclasses of \ref vigra::MultiArrayView.
+    These factory functions access <TT>array.traverser_begin()</TT>,
+    <TT>array.traverser_end()</TT> to obtain the iterators. If no accessor is
+    given, they use the <tt>AccessorTraits<T></tt> to determine the default 
+    accessor associated with the array's value type <tt>T</tt>.
+    The following factory functions are provided:
+
+    <table>
+    <tr><th bgcolor="#f0e0c0" colspan=2 align=left>
+        <TT>\ref vigra::MultiArrayView "vigra::MultiArrayView<N, SomeType>" img;</TT>
+        </th>
+    </tr>
+    <tr><td>
+
+    <TT>srcMultiArrayRange(img)</TT>
+    </td><td>
+        create argument object containing a \ref vigra::MultiIterator 
+        marking the begin of the array, a shape object giving the desired
+        shape of the array (possibly a subarray) and the default const accessor for
+        <tt>SomeType</tt>
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcMultiArrayRange(img, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing a \ref vigra::MultiIterator 
+        marking the begin of the array, a shape object giving the desired
+        shape of the array (possibly a subarray) and the given accessor
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcMultiArray(img)</TT>
+    </td><td>
+        create argument object containing a \ref vigra::MultiIterator
+        marking the begin of the array, and the default const accessor for
+        <tt>SomeType</tt>
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcMultiArray(img, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing a \ref vigra::MultiIterator 
+        marking the begin of the array and the given accessor
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destMultiArrayRange(img)</TT>
+    </td><td>
+        create argument object containing a \ref vigra::MultiIterator 
+        marking the begin of the array, a shape object giving the desired
+        shape of the array (possibly a subarray) and the default accessor for
+        <tt>SomeType</tt>
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destMultiArrayRange(img, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing a \ref vigra::MultiIterator's 
+        marking the begin of the array, a shape object giving the desired
+        shape of the array (possibly a subarray) and the given accessor
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destMultiArray(img)</TT>
+    </td><td>
+        create argument object containing a \ref vigra::MultiIterator 
+        marking the begin of the array and the default accessor for
+        <tt>SomeType</tt>
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destMultiArray(img, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing a \ref vigra::MultiIterator's 
+        marking the begin of the array and the given accessor
+
+    </td></tr>
+    </table>
+
+
+  \section IteratorBasedArgumentObjectFactories Iterator Based Argument Object Factories
+
+    <b>\#include</b> \<vigra/iteratortraits.hxx\>
+    Namespace: vigra
+
+    These factories can be used to create argument objects when we
+    are given \ref ImageIterators.
+    These factory functions use \ref vigra::IteratorTraits to
+    get the default accessor for the given iterator unless the
+    accessor is given explicitly. The following factory functions
+    are provided:
+
+    <table>
+    <tr><th bgcolor="#f0e0c0" colspan=2 align=left>
+        <TT>\ref vigra::BasicImage::Iterator "vigra::BasicImage<SomeType>::Iterator" i1, i2;</TT>
+        </th>
+    </tr>
+    <tr><td>
+
+    <TT>srcIterRange(i1, i2)</TT>
+    </td><td>
+        create argument object containing the given iterators and
+        corresponding default accessor (for source image)
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcIterRange(i1, i2, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing given iterators and
+        accessor (for source image)
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcIter(i1)</TT>
+    </td><td>
+        create argument object containing the given iterator and
+        corresponding default accessor (for source image)
+
+    </td></tr>
+    <tr><td>
+
+    <TT>srcIter(i1, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing given iterator and
+        accessor (for source image)
+
+    </td></tr>
+    <tr><td>
+
+    <TT>maskIter(i1)</TT>
+    </td><td>
+        create argument object containing the given iterator and
+        corresponding default accessor (for mask image)
+
+    </td></tr>
+    <tr><td>
+
+    <TT>maskIter(i1, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing given iterator and
+        accessor (for mask image)
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destIterRange(i1, i2)</TT>
+    </td><td>
+        create argument object containing the given iterators and
+        corresponding default accessor (for destination image)
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destIterRange(i1, i2, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing given iterators and
+        accessor (for destination image)
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destIter(i1)</TT>
+    </td><td>
+        create argument object containing the given iterator and
+        corresponding default accessor (for destination image)
+
+    </td></tr>
+    <tr><td>
+
+    <TT>destIter(i1, SomeAccessor())</TT>
+    </td><td>
+        create argument object containing given iterator and
+        accessor (for destination image)
+
+    </td></tr>
+    </table>
+*/
+
+template <class Iterator, class Accessor>
+inline triple<Iterator, Iterator, Accessor>
+srcIterRange(Iterator const & upperleft, Iterator const & lowerright, Accessor a)
+{
+    return triple<Iterator, Iterator, Accessor>(upperleft, lowerright, a);
+}
+
+template <class Iterator, class Accessor>
+inline pair<Iterator, Accessor>
+srcIter(Iterator const & upperleft, Accessor a)
+{
+    return pair<Iterator, Accessor>(upperleft, a);
+}
+
+template <class Iterator, class Accessor>
+inline pair<Iterator, Accessor>
+maskIter(Iterator const & upperleft, Accessor a)
+{
+    return pair<Iterator, Accessor>(upperleft, a);
+}
+
+template <class Iterator, class Accessor>
+inline pair<Iterator, Accessor>
+destIter(Iterator const & upperleft, Accessor a)
+{
+    return pair<Iterator, Accessor>(upperleft, a);
+}
+
+
+template <class Iterator, class Accessor>
+inline triple<Iterator, Iterator, Accessor>
+destIterRange(Iterator const & upperleft, Iterator const & lowerright, Accessor a)
+{
+    return triple<Iterator, Iterator, Accessor>(upperleft, lowerright, a);
+}
+
+template <class Iterator>
+inline pair<Iterator, typename IteratorTraits<Iterator>::DefaultAccessor>
+srcIter(Iterator const & upperleft)
+{
+    return pair<Iterator, typename IteratorTraits<Iterator>::DefaultAccessor>(
+                  upperleft,
+                  typename IteratorTraits<Iterator>::DefaultAccessor());
+}
+
+template <class Iterator>
+inline triple<Iterator, Iterator, typename IteratorTraits<Iterator>::DefaultAccessor>
+srcIterRange(Iterator const & upperleft, Iterator const & lowerright)
+{
+    return triple<Iterator, Iterator,
+                  typename IteratorTraits<Iterator>::DefaultAccessor>(
+                  upperleft, lowerright,
+                  typename IteratorTraits<Iterator>::DefaultAccessor());
+}
+
+template <class Iterator>
+inline pair<Iterator, typename IteratorTraits<Iterator>::DefaultAccessor>
+maskIter(Iterator const & upperleft)
+{
+    return pair<Iterator, typename IteratorTraits<Iterator>::DefaultAccessor>(
+                  upperleft,
+                  typename IteratorTraits<Iterator>::DefaultAccessor());
+}
+
+template <class Iterator>
+inline pair<Iterator, typename IteratorTraits<Iterator>::DefaultAccessor>
+destIter(Iterator const & upperleft)
+{
+    return pair<Iterator, typename IteratorTraits<Iterator>::DefaultAccessor>(
+                  upperleft,
+                  typename IteratorTraits<Iterator>::DefaultAccessor());
+}
+
+template <class Iterator>
+inline triple<Iterator, Iterator, typename IteratorTraits<Iterator>::DefaultAccessor>
+destIterRange(Iterator const & upperleft, Iterator const & lowerright)
+{
+    return triple<Iterator, Iterator,
+                  typename IteratorTraits<Iterator>::DefaultAccessor>(
+                  upperleft, lowerright,
+                  typename IteratorTraits<Iterator>::DefaultAccessor());
+}
+
+} // namespace vigra
+
+#endif // VIGRA_ITERATORTRAITS_HXX
diff --git a/include/vigra/labelimage.hxx b/include/vigra/labelimage.hxx
new file mode 100644
index 0000000..13bfe8b
--- /dev/null
+++ b/include/vigra/labelimage.hxx
@@ -0,0 +1,1167 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_LABELIMAGE_HXX
+#define VIGRA_LABELIMAGE_HXX
+
+#include <vector>
+#include <functional>
+#include "utilities.hxx"
+#include "stdimage.hxx"
+#include "union_find.hxx"
+#include "sized_int.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup Labeling Connected Components Labeling
+     The 2-dimensional connected components algorithms may use either 4 or 8 connectivity.
+     By means of a functor the merge criterion can be defined arbitrarily.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                        labelImage                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find the connected components of a segmented image.
+
+    Connected components are defined as regions with uniform pixel
+    values. Thus, <TT>T1</TT> either must be
+    equality comparable, or a suitable EqualityFunctor must be
+    provided that realizes the desired predicate. The
+    destination's value type <tt>T2</tt> should be large enough to hold the labels
+    without overflow. Region numbers will be a consecutive sequence
+    starting with one and ending with the region number returned by
+    the function (inclusive). The parameter '<TT>eight_neighbors</TT>'
+    determines whether the regions should be 4-connected (false) or
+    8-connected (true). 
+
+    Return:  the number of regions found (= largest region label)
+    
+    See \ref labelMultiArray() for a dimension-independent implementation of 
+    connected components labelling.
+    
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class EqualityFunctor = std::equal_to<T1> >
+        unsigned int
+        labelImage(MultiArrayView<2, T1, S1> const & src,
+                   MultiArrayView<2, T2, S2> dest,
+                   bool eight_neighbors, EqualityFunctor equal = EqualityFunctor());
+    }
+    \endcode
+
+    \deprecatedAPI{labelImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        unsigned int labelImage(SrcIterator upperlefts,
+                                SrcIterator lowerrights, SrcAccessor sa,
+                                DestIterator upperleftd, DestAccessor da,
+                                bool eight_neighbors);
+
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class EqualityFunctor>
+        unsigned int labelImage(SrcIterator upperlefts,
+                                SrcIterator lowerrights, SrcAccessor sa,
+                                DestIterator upperleftd, DestAccessor da,
+                                bool eight_neighbors, EqualityFunctor equal);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        unsigned int labelImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                pair<DestIterator, DestAccessor> dest,
+                                bool eight_neighbors);
+
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class EqualityFunctor>
+        unsigned int labelImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                pair<DestIterator, DestAccessor> dest,
+                                bool eight_neighbors, EqualityFunctor equal)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/labelimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h);
+    MultiArray<2, unsigned int>  labels(w,h);
+
+    // threshold at 128
+    transformImage(src, src, Threshold<int, int>(128, 256, 0, 255));
+
+    // find 4-connected regions
+    labelImage(src, labels, false);
+    \endcode
+
+    \deprecatedUsage{labelImage}
+    \code
+    vigra::BImage src(w,h);
+    vigra::IImage labels(w,h);
+
+    // threshold at 128
+    vigra::transformImage(srcImageRange(src), destImage(src),
+       vigra::Threshold<vigra::BImage::PixelType, vigra::BImage::PixelType>(
+                                                    128, 256, 0, 255));
+
+    // find 4-connected regions
+    vigra::labelImage(srcImageRange(src), destImage(labels), false);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+
+    u == u                  // first form
+
+    EqualityFunctor equal;      // second form
+    equal(u, u)                 // second form
+
+    int i;
+    dest_accessor.set(i, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> unsigned int labelImage)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class EqualityFunctor>
+unsigned int labelImage(SrcIterator upperlefts,
+                        SrcIterator lowerrights, SrcAccessor sa,
+                        DestIterator upperleftd, DestAccessor da,
+                        bool eight_neighbors, EqualityFunctor equal)
+{
+    typedef typename DestAccessor::value_type LabelType;
+    
+    int w = lowerrights.x - upperlefts.x;
+    int h = lowerrights.y - upperlefts.y;
+    int x,y,i;
+
+    const Diff2D neighbor[] = {
+        Diff2D(-1,0),  // left
+        Diff2D(-1,-1), // topleft
+        Diff2D(0,-1),  // top
+        Diff2D(1,-1)   // topright
+    };
+
+    const int left = 0, /* unused:  topleft = 1, */ top = 2, topright = 3;
+    int step = eight_neighbors ? 1 : 2;
+
+    SrcIterator ys = upperlefts;
+    DestIterator yd = upperleftd;
+    
+    detail::UnionFindArray<LabelType>  label;    
+
+    // pass 1: scan image from upper left to lower right
+    // to find connected components
+
+    // Each component will be represented by a tree of pixels. Each
+    // pixel contains the scan order address of its parent in the
+    // tree.  In order for pass 2 to work correctly, the parent must
+    // always have a smaller scan order address than the child.
+    // Therefore, we can merge trees only at their roots, because the
+    // root of the combined tree must have the smallest scan order
+    // address among all the tree's pixels/ nodes.  The root of each
+    // tree is distinguished by pointing to itself (it contains its
+    // own scan order address). This condition is enforced whenever a
+    // new region is found or two regions are merged
+
+
+    for(y = 0; y != h; ++y, ++ys.y, ++yd.y)
+    {
+        SrcIterator xs = ys;
+        DestIterator xd = yd;
+
+        int endNeighbor = (y == 0) ? left : (eight_neighbors ? topright : top);
+
+        for(x = 0; x != w; ++x, ++xs.x, ++xd.x)
+        {
+            int beginNeighbor = (x == 0) ? top : left;
+            if(x == w-1 && endNeighbor == topright) endNeighbor = top;
+
+            for(i=beginNeighbor; i<=endNeighbor; i+=step)
+            {
+                if(equal(sa(xs), sa(xs, neighbor[i])))
+                {
+                    LabelType neighborLabel = label.find(da(xd,neighbor[i]));
+
+                    for(int j=i+2; j<=endNeighbor; j+=step)
+                    {
+                        if(equal(sa(xs), sa(xs, neighbor[j])))
+                        {
+                            neighborLabel = label.makeUnion(da(xd, neighbor[j]), neighborLabel);
+                            break;
+                        }
+                    }
+                    da.set(neighborLabel, xd);
+                    break;
+                }
+
+            }
+            if(i > endNeighbor)
+            {
+                da.set(label.makeNewLabel(), xd);
+            }
+        }
+    }
+
+    // pass 2: assign one label to each region (tree)
+    // so that labels form a consecutive sequence 1, 2, ...
+    unsigned int count = label.makeContiguous();    
+    
+    yd = upperleftd;
+    for(y=0; y != h; ++y, ++yd.y)
+    {
+        typename DestIterator::row_iterator xd = yd.rowIterator();
+        for(x = 0; x != w; ++x, ++xd)
+        {
+            da.set(label[da(xd)], xd);
+        }
+    }
+    return count;
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline
+unsigned int labelImage(SrcIterator upperlefts,
+                        SrcIterator lowerrights, SrcAccessor sa,
+                        DestIterator upperleftd, DestAccessor da,
+                        bool eight_neighbors)
+{
+    return labelImage(upperlefts, lowerrights, sa,
+                 upperleftd, da, eight_neighbors,
+                 std::equal_to<typename SrcAccessor::value_type>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class EqualityFunctor>
+inline unsigned int
+labelImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+           pair<DestIterator, DestAccessor> dest,
+           bool eight_neighbors, EqualityFunctor equal)
+{
+    return labelImage(src.first, src.second, src.third,
+                      dest.first, dest.second, eight_neighbors, equal);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline unsigned int
+labelImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+           pair<DestIterator, DestAccessor> dest,
+           bool eight_neighbors)
+{
+    return labelImage(src.first, src.second, src.third,
+                      dest.first, dest.second, eight_neighbors,
+                      std::equal_to<typename SrcAccessor::value_type>());
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class EqualityFunctor>
+inline unsigned int
+labelImage(MultiArrayView<2, T1, S1> const & src,
+           MultiArrayView<2, T2, S2> dest,
+           bool eight_neighbors, EqualityFunctor equal)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "labelImage(): shape mismatch between input and output.");
+    return labelImage(srcImageRange(src),
+                      destImage(dest), eight_neighbors, equal);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline unsigned int
+labelImage(MultiArrayView<2, T1, S1> const & src,
+           MultiArrayView<2, T2, S2> dest,
+           bool eight_neighbors)
+{
+    return labelImage(srcImageRange(src),
+                      destImage(dest), eight_neighbors,
+                      std::equal_to<T1>());
+}
+
+/********************************************************/
+/*                                                      */
+/*             labelImageWithBackground                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find the connected components of a segmented image,
+    excluding the background from labeling.
+
+    This function works like \ref labelImage(), but considers all background pixels
+    (i.e. pixels having the given '<TT>background_value</TT>') as a single region that
+    is ignored when determining connected components and remains untouched in the
+    destination image. Usually, you will zero-initialize the output image, so that
+    the background gets label 0 (remember that actual region labels start at one).
+
+    Return:  the number of non-background regions found (= largest region label)
+    
+    See \ref labelMultiArrayWithBackground() for a dimension-independent implementation
+    if this algorithm.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class ValueType, 
+                  class EqualityFunctor = std::equal_to<T1> >
+        unsigned int 
+        labelImageWithBackground(MultiArrayView<2, T1, S1> const & src,
+                                 MultiArrayView<2, T2, S2> dest,
+                                 bool eight_neighbors,
+                                 ValueType background_value, 
+                                 EqualityFunctor equal = EqualityFunctor());
+    }
+    \endcode
+
+    \deprecatedAPI{labelImageWithBackground}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class ValueType>
+        int labelImageWithBackground(SrcIterator upperlefts,
+                       SrcIterator lowerrights, SrcAccessor sa,
+                       DestIterator upperleftd, DestAccessor da,
+                       bool eight_neighbors,
+                       ValueType background_value );
+
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class ValueType, class EqualityFunctor>
+        int labelImageWithBackground(SrcIterator upperlefts,
+                       SrcIterator lowerrights, SrcAccessor sa,
+                       DestIterator upperleftd, DestAccessor da,
+                       bool eight_neighbors,
+                       ValueType background_value, EqualityFunctor equal);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class ValueType>
+        int labelImageWithBackground(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                     pair<DestIterator, DestAccessor> dest,
+                                     bool eight_neighbors,
+                                     ValueType background_value);
+
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class ValueType, class EqualityFunctor>
+        int labelImageWithBackground(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                     pair<DestIterator, DestAccessor> dest,
+                                     bool eight_neighbors,
+                                     ValueType background_value, EqualityFunctor equal);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/labelimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h);
+    MultiArray<2, unsigned int>  labels(w,h);
+
+    // threshold at 128
+    transformImage(src, src, Threshold<int, int>(128, 256, 0, 255));
+
+    // find 4-connected regions of foreground (= white pixels) only
+    labelImageWithBackground(src, labels, false, 0);
+    \endcode
+
+    \deprecatedUsage{labelImageWithBackground}
+    \code
+    vigra::BImage src(w,h);
+    vigra::IImage labels(w,h);
+
+    // threshold at 128
+    vigra::transformImage(srcImageRange(src), destImage(src),
+        vigra::Threshold<vigra::BImage::PixelType, vigra::BImage::PixelType>(
+                                                    128, 256, 0, 255));
+
+    // find 4-connected regions of foreground (= white pixels) only
+    vigra::labelImageWithBackground(srcImageRange(src), destImage(labels),
+                             false, 0);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+    ValueType background_value;
+
+    u == u                  // first form
+    u == background_value   // first form
+
+    EqualityFunctor equal;      // second form
+    equal(u, u)                 // second form
+    equal(u, background_value)  // second form
+
+    int i;
+    dest_accessor.set(i, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> unsigned int labelImageWithBackground)
+    
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class ValueType, class EqualityFunctor>
+unsigned int labelImageWithBackground(
+    SrcIterator upperlefts,
+    SrcIterator lowerrights, SrcAccessor sa,
+    DestIterator upperleftd, DestAccessor da,
+    bool eight_neighbors,
+    ValueType background_value, EqualityFunctor equal)
+{
+    int w = lowerrights.x - upperlefts.x;
+    int h = lowerrights.y - upperlefts.y;
+    int x,y,i;
+
+    const Diff2D neighbor[] = {
+        Diff2D(-1,0),  // left
+        Diff2D(-1,-1), // topleft
+        Diff2D(0,-1),  // top
+        Diff2D(1,-1)   // topright
+    };
+
+    const int left = 0, /* unused:  topleft = 1,*/ top = 2, topright = 3;
+    int step = eight_neighbors ? 1 : 2;
+
+    SrcIterator ys(upperlefts);
+    SrcIterator xs(ys);
+    
+    // temporary image to store region labels
+    typedef BasicImage<IntBiggest> TmpImage;
+    TmpImage labelimage(w, h);
+    TmpImage::ScanOrderIterator label = labelimage.begin();
+    TmpImage::Iterator yt = labelimage.upperLeft();
+    TmpImage::Iterator  xt(yt);
+
+    // pass 1: scan image from upper left to lower right
+    // find connected components
+
+    for(y = 0; y != h; ++y, ++ys.y, ++yt.y)
+    {
+        xs = ys;
+        xt = yt;
+
+        int endNeighbor = (y == 0) ? left : (eight_neighbors ? topright : top);
+
+        for(x = 0; x != w; ++x, ++xs.x, ++xt.x)
+        {
+            if(equal(sa(xs), background_value))
+            {
+                *xt = -1;
+            }
+            else
+            {
+                int beginNeighbor = (x == 0) ? top : left;
+                if(x == w-1 && endNeighbor == topright) endNeighbor = top;
+
+                for(i=beginNeighbor; i<=endNeighbor; i+=step)
+                {
+                    if(equal(sa(xs), sa(xs, neighbor[i])))
+                    {
+                        IntBiggest neighborLabel = xt[neighbor[i]];
+
+                        for(int j=i+2; j<=endNeighbor; j+=step)
+                        {
+                            if(equal(sa(xs), sa(xs, neighbor[j])))
+                            {
+                                IntBiggest neighborLabel1 = xt[neighbor[j]];
+
+                                if(neighborLabel != neighborLabel1)
+                                {
+                                    // find roots of the region trees
+                                    while(neighborLabel != label[neighborLabel])
+                                    {
+                                        neighborLabel = label[neighborLabel];
+                                    }
+                                    while(neighborLabel1 != label[neighborLabel1])
+                                    {
+                                        neighborLabel1 = label[neighborLabel1];
+                                    }
+
+                                    // merge the trees
+                                    if(neighborLabel1 < neighborLabel)
+                                    {
+                                        label[neighborLabel] = neighborLabel1;
+                                        neighborLabel = neighborLabel1;
+                                    }
+                                    else if(neighborLabel < neighborLabel1)
+                                    {
+                                        label[neighborLabel1] = neighborLabel;
+                                    }
+                                }
+                                break;
+                            }
+                        }
+                        *xt = neighborLabel;
+                        break;
+                    }
+
+                }
+                if(i > endNeighbor)
+                {
+                    // new region
+                    // The initial label of a new region equals the
+                    // scan order address of it's first pixel.
+                    // This is essential for correct operation of the algorithm.
+                    *xt = x + y*w;
+                }
+            }
+        }
+    }
+
+    // pass 2: assign contiguous labels to the regions
+    DestIterator yd(upperleftd);
+
+    int count = 0;
+    i = 0;
+    for(y=0; y != h; ++y, ++yd.y)
+    {
+        DestIterator xd(yd);
+        for(x = 0; x != w; ++x, ++xd.x, ++i)
+        {
+            if(label[i] == -1) continue;
+
+            if(label[i] == i)
+            {
+                label[i] = count++;
+            }
+            else
+            {
+                label[i] = label[label[i]];
+            }
+            da.set(label[i]+1, xd);
+        }
+    }
+
+    return count;
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class ValueType>
+inline
+unsigned int labelImageWithBackground(
+    SrcIterator upperlefts,
+    SrcIterator lowerrights, SrcAccessor sa,
+    DestIterator upperleftd, DestAccessor da,
+    bool eight_neighbors,
+    ValueType background_value)
+{
+    return labelImageWithBackground(upperlefts, lowerrights, sa,
+                            upperleftd, da,
+                            eight_neighbors, background_value,
+                            std::equal_to<typename SrcAccessor::value_type>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class ValueType, class EqualityFunctor>
+inline unsigned int 
+labelImageWithBackground(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                         pair<DestIterator, DestAccessor> dest,
+                         bool eight_neighbors,
+                         ValueType background_value, EqualityFunctor equal)
+{
+    return labelImageWithBackground(src.first, src.second, src.third,
+                                    dest.first, dest.second,
+                                    eight_neighbors, background_value, equal);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class ValueType>
+inline unsigned int
+labelImageWithBackground(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                         pair<DestIterator, DestAccessor> dest,
+                         bool eight_neighbors,
+                         ValueType background_value)
+{
+    return labelImageWithBackground(src.first, src.second, src.third,
+                                    dest.first, dest.second,
+                                    eight_neighbors, background_value,
+                                    std::equal_to<typename SrcAccessor::value_type>());
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class ValueType, class EqualityFunctor>
+inline unsigned int 
+labelImageWithBackground(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest,
+                         bool eight_neighbors,
+                         ValueType background_value, EqualityFunctor equal)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "labelImageWithBackground(): shape mismatch between input and output.");
+    return labelImageWithBackground(srcImageRange(src),
+                                    destImage(dest),
+                                    eight_neighbors, background_value, equal);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class ValueType>
+inline unsigned int
+labelImageWithBackground(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest,
+                         bool eight_neighbors,
+                         ValueType background_value)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "labelImageWithBackground(): shape mismatch between input and output.");
+    return labelImageWithBackground(srcImageRange(src),
+                                    destImage(dest),
+                                    eight_neighbors, background_value,
+                                    std::equal_to<T1>());
+}
+
+/********************************************************/
+/*                                                      */
+/*            regionImageToCrackEdgeImage               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Transform a labeled image into a crack edge (interpixel edge) image.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2, class DestValue>
+        void 
+        regionImageToCrackEdgeImage(MultiArrayView<2, T1, S1> const & src,
+                                    MultiArrayView<2, T2, S2> dest,
+                                    DestValue edge_marker);
+    }
+    \endcode
+
+    \deprecatedAPI{regionImageToCrackEdgeImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class DestValue>
+        void regionImageToCrackEdgeImage(
+                       SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+                       DestIterator dul, DestAccessor da,
+                       DestValue edge_marker)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class DestValue>
+        void regionImageToCrackEdgeImage(
+                   triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   DestValue edge_marker)
+    }
+    \endcode
+    \deprecatedEnd
+
+    This algorithm inserts border pixels (so called "crack edges" or "interpixel edges")
+    between regions in a labeled image like this (<TT>a</TT> and
+    <TT>c</TT> are the original labels, and <TT>0</TT> is the value of
+    <TT>edge_marker</TT> and denotes the inserted edges):
+
+    \code
+       original image     insert zero- and one-cells
+
+                                         a 0 c c c
+          a c c                          a 0 0 0 c
+          a a c               =>         a a a 0 c
+          a a a                          a a a 0 0
+                                         a a a a a
+    \endcode
+
+    The algorithm assumes that the original labeled image contains
+    no background. Therefore, it is suitable as a post-processing
+    operation of \ref labelImage() or \ref seededRegionGrowing().
+
+    The destination image must be twice the size of the original
+    (precisely, <TT>(2*w-1)</TT> by <TT>(2*h-1)</TT> pixels). The
+    source value type (<TT>SrcAccessor::value-type</TT>) must be
+    equality-comparable.
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/labelimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h);
+    MultiArray<2, unsigned int>  labels(w,h),
+                                 cellgrid(2*w-1, 2*h-1);
+
+    // threshold at 128
+    transformImage(src, src, Threshold<int, int>(128, 256, 0, 255));
+
+    // find 4-connected regions
+    labelImage(src, labels, false);
+
+    // create cell grid image, mark edges with 0
+    regionImageToCrackEdgeImage(labels, cellgrid, 0);
+    \endcode
+
+    \deprecatedUsage{regionImageToCrackEdgeImage}
+    \code
+    vigra::BImage src(w,h);
+    vigra::IImage labels(w,h);
+    vigra::IImage cellgrid(2*w-1, 2*h-1);
+
+    // threshold at 128
+    vigra::transformImage(srcImageRange(src), destImage(src),
+       vigra::Threshold<vigra::BImage::PixelType, vigra::BImage::PixelType>(
+                                                    128, 256, 0, 255));
+
+    // find 4-connected regions
+    vigra::labelImage(srcImageRange(src), destImage(labels), false);
+
+    // create cell grid image, mark edges with 0
+    vigra::regionImageToCrackEdgeImage(srcImageRange(labels), destImage(cellgrid), 0);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator src_upperleft, src_lowerright;
+    ImageIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+
+    u != u
+
+    DestValue edge_marker;
+    dest_accessor.set(edge_marker, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    The destination image must have twice the size of the source:
+    \code
+    w_dest = 2 * w_src - 1
+    h_dest = 2 * h_src - 1
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void regionImageToCrackEdgeImage)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, class DestValue>
+void regionImageToCrackEdgeImage(
+               SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+               DestIterator dul, DestAccessor da,
+               DestValue edge_marker)
+{
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    int x,y;
+
+    const Diff2D right(1,0);
+    const Diff2D left(-1,0);
+    const Diff2D bottomright(1,1);
+    const Diff2D bottom(0,1);
+    const Diff2D top(0,-1);
+
+    SrcIterator iy = sul;
+    DestIterator dy = dul;
+
+    for(y=0; y<h-1; ++y, ++iy.y, dy.y+=2)
+    {
+        SrcIterator ix = iy;
+        DestIterator dx = dy;
+
+        for(x=0; x<w-1; ++x, ++ix.x, dx.x+=2)
+        {
+            da.set(sa(ix), dx);
+            da.set(sa(ix), dx, bottomright);
+
+            if(sa(ix, right) != sa(ix))
+            {
+                da.set(edge_marker, dx, right);
+            }
+            else
+            {
+                da.set(sa(ix), dx, right);
+            }
+            if(sa(ix, bottom) != sa(ix))
+            {
+                da.set(edge_marker, dx, bottom);
+            }
+            else
+            {
+                da.set(sa(ix), dx, bottom);
+            }
+
+        }
+
+        da.set(sa(ix), dx);
+        if(sa(ix, bottom) != sa(ix))
+        {
+            da.set(edge_marker, dx, bottom);
+        }
+        else
+        {
+            da.set(sa(ix), dx, bottom);
+        }
+    }
+
+    SrcIterator ix = iy;
+    DestIterator dx = dy;
+
+    for(x=0; x<w-1; ++x, ++ix.x, dx.x+=2)
+    {
+        da.set(sa(ix), dx);
+        if(sa(ix, right) != sa(ix))
+        {
+            da.set(edge_marker, dx, right);
+        }
+        else
+        {
+            da.set(sa(ix), dx, right);
+        }
+    }
+    da.set(sa(ix), dx);
+
+    dy = dul + Diff2D(1,1);
+
+    const Diff2D dist[] = {right, top, left, bottom };
+    // find missing 0-cells
+    for(y=0; y<h-1; ++y, dy.y+=2)
+    {
+        DestIterator dx = dy;
+
+        for(x=0; x<w-1; ++x, dx.x+=2)
+        {
+            int i;
+            for(i=0; i<4; ++i)
+            {
+                if(da(dx, dist[i]) == edge_marker) break;
+            }
+
+            if(i < 4) da.set(edge_marker, dx);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, class DestValue>
+inline void 
+regionImageToCrackEdgeImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<DestIterator, DestAccessor> dest,
+                            DestValue edge_marker)
+{
+    regionImageToCrackEdgeImage(src.first, src.second, src.third,
+                                dest.first, dest.second,
+                                edge_marker);
+}
+
+template <class T1, class S1,
+          class T2, class S2, class DestValue>
+inline void 
+regionImageToCrackEdgeImage(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            DestValue edge_marker)
+{
+    vigra_precondition(2*src.shape()-Shape2(1) == dest.shape(),
+        "regionImageToCrackEdgeImage(): shape mismatch between input and output.");
+    regionImageToCrackEdgeImage(srcImageRange(src),
+                                destImage(dest),
+                                edge_marker);
+}
+
+/********************************************************/
+/*                                                      */
+/*                regionImageToEdgeImage                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Transform a labeled image into an edge image.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2, class DestValue>
+        void 
+        regionImageToEdgeImage(MultiArrayView<2, T1, S1> const & src,
+                               MultiArrayView<2, T2, S2> dest,
+                               DestValue edge_marker);
+    }
+    \endcode
+
+    \deprecatedAPI{regionImageToEdgeImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class DestValue>
+        void regionImageToEdgeImage(
+                       SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+                       DestIterator dul, DestAccessor da,
+                       DestValue edge_marker)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class DestValue>
+        void regionImageToEdgeImage(
+                   triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   DestValue edge_marker)
+    }
+    \endcode
+    \deprecatedEnd
+
+    This algorithm marks all pixels with the given <TT>edge_marker</TT>
+    which belong to a different region (label) than their right or lower
+    neighbors:
+
+    \code
+       original image                     edges
+                                 (assuming edge_marker == 1)
+
+          a c c                            1 1 *
+          a a c               =>           * 1 1
+          a a a                            * * *
+    \endcode
+
+    The non-edge pixels of the destination image will not be touched.
+    The source value type <TT>T1</TT> must be
+    equality-comparable.
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/labelimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w,h),
+                                 edges(w,h);
+    MultiArray<2, unsigned int>  labels(w,h);
+
+    edges = 255;  // init background (non-edge) to 255
+
+    // threshold at 128
+    transformImage(src, src, Threshold<int, int>(128, 256, 0, 255));
+
+    // find 4-connected regions
+    labelImage(src, labels, false);
+
+    // create edge image, mark edges with 0
+    regionImageToEdgeImage(labels, edges, 0);
+    \endcode
+
+    \deprecatedUsage{regionImageToEdgeImage}
+    \code
+    vigra::BImage src(w,h);
+    vigra::IImage labels(w,h);
+    vigra::IImage edges(w, h);
+    edges = 255;  // init background (non-edge) to 255
+
+    // threshold at 128
+    vigra::transformImage(srcImageRange(src), destImage(src),
+      vigra::Threshold<vigra::BImage::PixelType, vigra::BImage::PixelType>(
+                                                    128, 256, 0, 255));
+
+    // find 4-connected regions
+    vigra::labelImage(srcImageRange(src), destImage(labels), false);
+
+    // create edge image, mark edges with 0
+    vigra::regionImageToEdgeImage(srcImageRange(labels), destImage(edges), 0);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator src_upperleft, src_lowerright;
+    ImageIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+
+    u != u
+
+    DestValue edge_marker;
+    dest_accessor.set(edge_marker, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void regionImageToEdgeImage)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, class DestValue>
+void regionImageToEdgeImage(
+               SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+               DestIterator dul, DestAccessor da,
+               DestValue edge_marker)
+{
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    int x,y;
+
+    const Diff2D right(1,0);
+    const Diff2D left(-1,0);
+    const Diff2D bottomright(1,1);
+    const Diff2D bottom(0,1);
+    const Diff2D top(0,-1);
+
+    SrcIterator iy = sul;
+    DestIterator dy = dul;
+
+    for(y=0; y<h-1; ++y, ++iy.y, ++dy.y)
+    {
+        SrcIterator ix = iy;
+        DestIterator dx = dy;
+
+        for(x=0; x<w-1; ++x, ++ix.x, ++dx.x)
+        {
+            if(sa(ix, right) != sa(ix))
+            {
+                da.set(edge_marker, dx);
+            }
+            if(sa(ix, bottom) != sa(ix))
+            {
+                da.set(edge_marker, dx);
+            }
+        }
+
+        if(sa(ix, bottom) != sa(ix))
+        {
+            da.set(edge_marker, dx);
+        }
+    }
+
+    SrcIterator ix = iy;
+    DestIterator dx = dy;
+
+    for(x=0; x<w-1; ++x, ++ix.x, ++dx.x)
+    {
+        if(sa(ix, right) != sa(ix))
+        {
+            da.set(edge_marker, dx);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, class DestValue>
+inline void 
+regionImageToEdgeImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                       pair<DestIterator, DestAccessor> dest,
+                       DestValue edge_marker)
+{
+    regionImageToEdgeImage(src.first, src.second, src.third,
+                           dest.first, dest.second,
+                           edge_marker);
+}
+
+template <class T1, class S1,
+          class T2, class S2, class DestValue>
+inline void 
+regionImageToEdgeImage(MultiArrayView<2, T1, S1> const & src,
+                       MultiArrayView<2, T2, S2> dest,
+                       DestValue edge_marker)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "regionImageToEdgeImage(): shape mismatch between input and output.");
+    regionImageToEdgeImage(srcImageRange(src),
+                           destImage(dest),
+                           edge_marker);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_LABELIMAGE_HXX
diff --git a/include/vigra/labelvolume.hxx b/include/vigra/labelvolume.hxx
new file mode 100644
index 0000000..abf7396
--- /dev/null
+++ b/include/vigra/labelvolume.hxx
@@ -0,0 +1,740 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2006-2007 by F. Heinrich, B. Seppke, Ullrich Koethe    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_LABELVOLUME_HXX
+#define VIGRA_LABELVOLUME_HXX
+
+
+#include "voxelneighborhood.hxx"
+#include "multi_array.hxx"
+#include "union_find.hxx"
+
+namespace vigra{
+
+/** \addtogroup Labeling Connected Components Labeling
+     The 3-dimensional connected components algorithms may use either 6 or 26 connectivity.
+     By means of a functor the merge criterion can be defined arbitrarily.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                        labelVolume                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find the connected components of a segmented volume.
+
+    Connected components are defined as regions with uniform voxel
+    values. Thus, <TT>T1</TT> either must be equality comparable, 
+    or an EqualityFunctor must be provided explicitly that realizes 
+    the desired equivalence predicate. The destination's value type 
+    <tt>T2</tt> should be large enough to hold the labels
+    without overflow. Region numbers will be a consecutive sequence
+    starting with one and ending with the region number returned by
+    the function (inclusive).
+
+    Return:  the number of regions found (= largest region label)
+    
+    See \ref labelMultiArray() for a dimension-independent implementation of 
+    connected components labelling.
+
+    <b> Declarations:</b>
+
+    pass 3D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class Neighborhood3D, 
+                  class EqualityFunctor = std::equal_to<T1> >
+        unsigned int
+        labelVolume(MultiArrayView<3, T1, S1> const & source,
+                    MultiArrayView<3, T2, S2> dest,
+                    Neighborhood3D neighborhood3D,
+                    EqualityFunctor equal  = EqualityFunctor());
+
+    }
+    \endcode
+
+    \deprecatedAPI{labelVolume}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                  class DestIterator, class DestAccessor,
+                  class Neighborhood3D>
+        unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                                 DestIterator d_Iter, DestAccessor da,
+                                 Neighborhood3D neighborhood3D);
+
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                          class DestIterator, class DestAccessor,
+                          class Neighborhood3D, class EqualityFunctor>
+        unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                                 DestIterator d_Iter, DestAccessor da,
+                                 Neighborhood3D neighborhood3D, EqualityFunctor equal);
+
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                  class DestIterator, class DestAccessor,
+                  class Neighborhood3D>
+        unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                                 pair<DestIterator, DestAccessor> dest,
+                                 Neighborhood3D neighborhood3D);
+
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                 class DestIterator, class DestAccessor,
+                 class Neighborhood3D, class EqualityFunctor>
+        unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                                 pair<DestIterator, DestAccessor> dest,
+                                 Neighborhood3D neighborhood3D, EqualityFunctor equal);
+
+    }
+    \endcode
+    use with 3D-Six-Neighborhood:
+    \code
+    namespace vigra {    
+    
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                  class DestIterator, class DestAccessor>
+        unsigned int labelVolumeSix(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                                    pair<DestIterator, DestAccessor> dest);
+                                    
+    }
+    \endcode
+    \deprecatedEnd    
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/labelvolume.hxx\><br>
+    Namespace: vigra
+
+    \code
+    typedef MultiArray<3,int> IntVolume;
+    IntVolume src(Shape3(w,h,d));
+    IntVolume dest(Shape3(w,h,d));
+    
+    // find 6-connected regions
+    int max_region_label = labelVolumeSix(src, dest);
+
+    // find 26-connected regions
+    int max_region_label = labelVolume(src, dest, NeighborCode3DTwentySix());
+    \endcode
+
+    \deprecatedUsage{labelVolume}
+    \code
+    typedef vigra::MultiArray<3,int> IntVolume;
+    IntVolume src(IntVolume::difference_type(w,h,d));
+    IntVolume dest(IntVolume::difference_type(w,h,d));
+    
+    // find 6-connected regions
+    int max_region_label = vigra::labelVolumeSix(srcMultiArrayRange(src), destMultiArray(dest));
+
+    // find 26-connected regions
+    int max_region_label = vigra::labelVolume(srcMultiArrayRange(src), destMultiArray(dest), NeighborCode3DTwentySix());
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator src_begin;
+    SrcShape shape;
+    DestIterator dest_begin;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_begin);
+
+    u == u                      // first form
+
+    EqualityFunctor equal;      // second form
+    equal(u, u)                 // second form
+
+    int i;
+    dest_accessor.set(i, dest_begin);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> unsigned int labelVolume)
+
+
+template <class SrcIterator, class SrcAccessor,class SrcShape,
+          class DestIterator, class DestAccessor,
+          class Neighborhood3D, class EqualityFunctor>
+unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                         DestIterator d_Iter, DestAccessor da,
+                         Neighborhood3D, EqualityFunctor equal)
+{
+    typedef typename DestAccessor::value_type LabelType;
+    
+    //basically needed for iteration and border-checks
+    int w = srcShape[0], h = srcShape[1], d = srcShape[2];
+    int x,y,z;       
+        
+    // temporary image to store region labels
+    detail::UnionFindArray<LabelType>  label;
+        
+    //Declare traversers for all three dims at target
+    SrcIterator zs = s_Iter;
+    DestIterator zd = d_Iter;
+
+    // initialize the neighborhood traversers
+    NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
+    ++nce;
+    // pass 1: scan image from upper left front to lower right back
+    // to find connected components
+
+    // Each component will be represented by a tree of pixels. Each
+    // pixel contains the scan order address of its parent in the
+    // tree.  In order for pass 2 to work correctly, the parent must
+    // always have a smaller scan order address than the child.
+    // Therefore, we can merge trees only at their roots, because the
+    // root of the combined tree must have the smallest scan order
+    // address among all the tree's pixels/ nodes.  The root of each
+    // tree is distinguished by pointing to itself (it contains its
+    // own scan order address). This condition is enforced whenever a
+    // new region is found or two regions are merged
+    for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
+    {
+        SrcIterator ys(zs);
+        DestIterator yd(zd);
+
+        for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
+        {
+            SrcIterator xs(ys);
+            DestIterator xd(yd);
+
+            for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
+            {
+                LabelType currentLabel = label.nextFreeLabel();
+
+                //check whether there is a special border treatment to be used or not
+                AtVolumeBorder atBorder = isAtVolumeBorderCausal(x,y,z,w,h,d);
+
+                //We are not at the border!
+                if(atBorder == NotAtBorder)
+                {
+                    NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
+                
+                    do
+                    {            
+                        // if colors are equal
+                        if(equal(sa(xs), sa(xs, *nc)))
+                        {
+                            currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
+                        }
+                        ++nc;
+                    }
+                    while(nc!=nce);
+                }               
+                else //we are at a border - handle this!!
+                {
+                    NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
+                    int j=0;
+                    while(nc.direction() != Neighborhood3D::Error)
+                    {
+                        
+                        SrcShape s(x,y,z), sn = s + *nc;
+                        
+                        if (sn[0]<0 || sn[0]>=w || sn[1]<0 || sn[1]>=h || sn[2]<0 || sn[2]>=d)
+                        {  
+                          std::cerr << "coordinate error at " << s << ", offset " << *nc << ", index " << (nc).direction() << " at border " <<
+                                                                                                                              atBorder << std::endl;
+                        
+                        }
+                        
+                        //   colors equal???
+                        if(equal(sa(xs), sa(xs, *nc)))
+                        {
+                            currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
+                        }
+                        nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
+                    }
+                }
+                da.set(label.finalizeLabel(currentLabel), xd);
+            }
+        }
+    }
+    
+    LabelType count = label.makeContiguous();
+
+    // pass 2: assign one label to each region (tree)
+    // so that labels form a consecutive sequence 1, 2, ...
+    zd = d_Iter;
+    for(z=0; z != d; ++z, ++zd.dim2())
+    {
+        DestIterator yd(zd);
+
+        for(y=0; y != h; ++y, ++yd.dim1())
+        {
+            DestIterator xd(yd);
+
+            for(x = 0; x != w; ++x, ++xd.dim0())
+            {
+                da.set(label[da(xd)], xd);
+            }
+        }
+    }
+    return count;
+}
+
+template <class SrcIterator, class SrcAccessor,class SrcShape,
+          class DestIterator, class DestAccessor,
+          class Neighborhood3D>
+unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                         DestIterator d_Iter, DestAccessor da,
+                         Neighborhood3D neighborhood3D)
+{
+        return labelVolume(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor, 
+          class DestIterator, class DestAccessor,
+          class Neighborhood3D>
+unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                         pair<DestIterator, DestAccessor> dest,
+                         Neighborhood3D neighborhood3D)
+{
+    return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood3D, class EqualityFunctor>
+unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                         pair<DestIterator, DestAccessor> dest,
+                         Neighborhood3D neighborhood3D, EqualityFunctor equal)
+{
+    return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, equal);
+}
+
+template <class T1, class S1, 
+          class T2, class S2,
+          class Neighborhood3D, class EqualityFunctor>
+inline unsigned int
+labelVolume(MultiArrayView<3, T1, S1> const & source,
+            MultiArrayView<3, T2, S2> dest,
+            Neighborhood3D neighborhood3D,
+            EqualityFunctor equal)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "labelVolume(): shape mismatch between input and output.");
+    return labelVolume(srcMultiArrayRange(source), destMultiArray(dest), neighborhood3D, equal);
+}
+
+template <class T1, class S1, 
+          class T2, class S2,
+          class Neighborhood3D>
+inline unsigned int
+labelVolume(MultiArrayView<3, T1, S1> const & source,
+            MultiArrayView<3, T2, S2> dest,
+            Neighborhood3D neighborhood3D)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "labelVolume(): shape mismatch between input and output.");
+    return labelVolume(srcMultiArrayRange(source), destMultiArray(dest), neighborhood3D, std::equal_to<T1>());
+}
+
+/********************************************************/
+/*                                                      */
+/*                    labelVolumeSix                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find the connected components of a segmented volume
+     using the 6-neighborhood.
+     
+     See \ref labelVolume() for detailed documentation.
+
+*/
+template <class SrcIterator, class SrcAccessor,class SrcShape,
+          class DestIterator, class DestAccessor>
+unsigned int labelVolumeSix(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                            pair<DestIterator, DestAccessor> dest)
+{
+    return labelVolume(src.first, src.second, src.third, dest.first, dest.second, NeighborCode3DSix(), std::equal_to<typename SrcAccessor::value_type>());
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+unsigned int labelVolumeSix(MultiArrayView<3, T1, S1> const & source,
+                            MultiArrayView<3, T2, S2> dest)
+{
+    return labelVolume(srcMultiArrayRange(source), destMultiArray(dest), 
+                       NeighborCode3DSix(), std::equal_to<T1>());
+}
+
+/********************************************************/
+/*                                                      */
+/*               labelVolumeWithBackground              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find the connected components of a segmented volume,
+     excluding the background from labeling.
+
+    This function works like \ref labelVolume(), but considers all background voxels
+    (i.e. voxels having the given '<TT>background_value</TT>') as a single region that
+    is ignored when determining connected components and remains untouched in the
+    destination array. Usually, you will zero-initialize the output array, so that
+    the background gets label 0 (remember that actual region labels start at one).
+
+    Return:  the number of regions found (= largest region label)
+
+    See \ref labelMultiArrayWithBackground() for a dimension-independent implementation
+    if this algorithm.
+
+    <b> Declarations:</b>
+
+    pass 3D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class Neighborhood3D,
+                  class ValueType,
+                  class EqualityFunctor = std::equalt_to<T1> >
+        unsigned int
+        labelVolumeWithBackground(MultiArrayView<3, T1, S1> const & source,
+                                  MultiArrayView<3, T2, S2> dest,
+                                  Neighborhood3D neighborhood3D,
+                                  ValueType backgroundValue,
+                                  EqualityFunctor equal = EqualityFunctor());
+    }
+    \endcode
+
+    \deprecatedAPI{labelVolumeWithBackground}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                          class DestIterator, class DestAccessor,
+                          class Neighborhood3D, class ValueType>
+        unsigned int labelVolumeWithBackground(    SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                                                          DestIterator d_Iter, DestAccessor da,
+                                                          Neighborhood3D neighborhood3D, ValueType background_value);
+
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                          class DestIterator, class DestAccessor,
+                          class Neighborhood3D, class ValueType, class EqualityFunctor>
+        unsigned int labelVolumeWithBackground(    SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                                                            DestIterator d_Iter, DestAccessor da,
+                                                          Neighborhood3D neighborhood3D, ValueType background_value,
+                                                            EqualityFunctor equal);
+
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                          class DestIterator, class DestAccessor,
+                          class Neighborhood3D, class ValueType>
+        unsigned int labelVolumeWithBackground(    triple<SrcIterator, SrcShape, SrcAccessor> src,
+                                                          pair<DestIterator, DestAccessor> dest,
+                                                          Neighborhood3D neighborhood3D, ValueType background_value);
+
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                          class DestIterator, class DestAccessor,
+                          class Neighborhood3D, class ValueType, class EqualityFunctor>
+        unsigned int labelVolumeWithBackground(    triple<SrcIterator, SrcShape, SrcAccessor> src,
+                                                        pair<DestIterator, DestAccessor> dest,
+                                                        Neighborhood3D neighborhood3D, ValueType background_value,
+                                                        EqualityFunctor equal);
+
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/labelvolume.hxx\><br>
+    Namespace: vigra
+
+    \code
+    typedef vigra::MultiArray<3,int> IntVolume;
+    
+    IntVolume src(Shape3(w,h,d));
+    IntVolume dest(Shape3(w,h,d));
+
+    // find 6-connected regions
+    int max_region_label = labelVolumeWithBackground(src, dest, NeighborCode3DSix(), 0);
+    \endcode
+
+    \deprecatedUsage{labelVolumeWithBackground}
+    \code
+    typedef vigra::MultiArray<3,int> IntVolume;
+    IntVolume src(IntVolume::difference_type(w,h,d));
+    IntVolume dest(IntVolume::difference_type(w,h,d));
+
+    // find 6-connected regions
+    int max_region_label = vigra::labelVolumeWithBackground(
+    srcMultiArrayRange(src), destMultiArray(dest), NeighborCode3DSix(), 0);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator src_begin;
+    SrcShape shape;
+    DestIterator dest_begin;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_begin);
+
+    u == u                      // first form
+
+    EqualityFunctor equal;      // second form
+    equal(u, u)                 // second form
+
+    int i;
+    dest_accessor.set(i, dest_begin);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> unsigned int labelVolumeWithBackground)
+
+template <class SrcIterator, class SrcAccessor,class SrcShape,
+          class DestIterator, class DestAccessor,
+          class Neighborhood3D,
+          class ValueType, class EqualityFunctor>
+unsigned int labelVolumeWithBackground(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                                       DestIterator d_Iter, DestAccessor da,
+                                       Neighborhood3D,
+                                       ValueType backgroundValue, EqualityFunctor equal)
+{
+    typedef typename DestAccessor::value_type LabelType;
+    
+    //basically needed for iteration and border-checks
+    int w = srcShape[0], h = srcShape[1], d = srcShape[2];
+    int x,y,z;       
+        
+    // temporary image to store region labels
+    detail::UnionFindArray<LabelType>  label;
+        
+    //Declare traversers for all three dims at target
+    SrcIterator zs = s_Iter;
+    DestIterator zd = d_Iter;
+
+    // initialize the neighborhood traversers
+    NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
+    ++nce;
+    // pass 1: scan image from upper left front to lower right back
+    // to find connected components
+
+    // Each component will be represented by a tree of pixels. Each
+    // pixel contains the scan order address of its parent in the
+    // tree.  In order for pass 2 to work correctly, the parent must
+    // always have a smaller scan order address than the child.
+    // Therefore, we can merge trees only at their roots, because the
+    // root of the combined tree must have the smallest scan order
+    // address among all the tree's pixels/ nodes.  The root of each
+    // tree is distinguished by pointing to itself (it contains its
+    // own scan order address). This condition is enforced whenever a
+    // new region is found or two regions are merged
+    for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
+    {
+        SrcIterator ys(zs);
+        DestIterator yd(zd);
+
+        for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
+        {
+            SrcIterator xs(ys);
+            DestIterator xd(yd);
+
+            for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
+            {
+                if(equal(sa(xs), backgroundValue))
+                {
+                    da.set(label[0], xd);
+                    continue;
+                }
+
+                LabelType currentLabel = label.nextFreeLabel();
+
+                //check whether there is a special border treatment to be used or not
+                AtVolumeBorder atBorder = isAtVolumeBorderCausal(x,y,z,w,h,d);
+                    
+                //We are not at the border!
+                if(atBorder == NotAtBorder)
+                {
+                    NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
+                
+                    do
+                    {            
+                        // if colors are equal
+                        if(equal(sa(xs), sa(xs, *nc)))
+                        {
+                            currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
+                        }
+                        ++nc;
+                    }
+                    while(nc!=nce);
+                }               
+                else //we are at a border - handle this!!
+                {
+                    NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
+                    int j=0;
+                    while(nc.direction() != Neighborhood3D::Error)
+                    {
+                        SrcShape s(x,y,z), sn = s + *nc;
+                        
+                        if (sn[0]<0 || sn[0]>=w || sn[1]<0 || sn[1]>=h || sn[2]<0 || sn[2]>=d)
+                        {  
+                          std::cerr << "coordinate error at " << s << ", offset " << *nc << ", index " << (nc).direction() << " at border " <<
+                                                                                                                              atBorder << std::endl;
+                        
+                        }
+                        //   colors equal???
+                        if(equal(sa(xs), sa(xs, *nc)))
+                        {
+                            currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
+                        }
+                        nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
+                    }
+                }
+                da.set(label.finalizeLabel(currentLabel), xd);
+            }
+        }
+    }
+    
+    LabelType count = label.makeContiguous();
+
+    // pass 2: assign one label to each region (tree)
+    // so that labels form a consecutive sequence 1, 2, ...
+    zd = d_Iter;
+    for(z=0; z != d; ++z, ++zd.dim2())
+    {
+        DestIterator yd(zd);
+
+        for(y=0; y != h; ++y, ++yd.dim1())
+        {
+            DestIterator xd(yd);
+
+            for(x = 0; x != w; ++x, ++xd.dim0())
+            {
+                da.set(label[da(xd)], xd);
+            }
+        }
+    }
+    return count;
+}
+
+template <class SrcIterator, class SrcAccessor,class SrcShape,
+          class DestIterator, class DestAccessor,
+          class Neighborhood3D,
+          class ValueType>
+inline unsigned int 
+labelVolumeWithBackground(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                          DestIterator d_Iter, DestAccessor da,
+                          Neighborhood3D neighborhood3D, ValueType backgroundValue)
+{
+    return labelVolumeWithBackground(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, backgroundValue, std::equal_to<typename SrcAccessor::value_type>());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood3D,
+          class ValueType,
+          class EqualityFunctor>
+inline unsigned int
+labelVolumeWithBackground(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                          pair<DestIterator, DestAccessor> dest,
+                          Neighborhood3D neighborhood3D, ValueType backgroundValue, EqualityFunctor equal)
+{
+    return labelVolumeWithBackground(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, backgroundValue, equal);
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood3D,
+          class ValueType>
+inline unsigned int
+labelVolumeWithBackground(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                          pair<DestIterator, DestAccessor> dest,
+                          Neighborhood3D neighborhood3D, ValueType backgroundValue)
+{
+    return labelVolumeWithBackground(src.first, src.second, src.third, dest.first, dest.second, 
+                                     neighborhood3D, backgroundValue, std::equal_to<typename SrcAccessor::value_type>());
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class Neighborhood3D,
+          class ValueType,
+          class EqualityFunctor>
+inline unsigned int
+labelVolumeWithBackground(MultiArrayView<3, T1, S1> const & source,
+                          MultiArrayView<3, T2, S2> dest,
+                          Neighborhood3D neighborhood3D,
+                          ValueType backgroundValue,
+                          EqualityFunctor equal)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "labelVolumeWithBackground(): shape mismatch between input and output.");
+    return labelVolumeWithBackground(srcMultiArrayRange(source), destMultiArray(dest), 
+                                     neighborhood3D, backgroundValue, equal);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class Neighborhood3D,
+          class ValueType>
+inline unsigned int
+labelVolumeWithBackground(MultiArrayView<3, T1, S1> const & source,
+                          MultiArrayView<3, T2, S2> dest,
+                          Neighborhood3D neighborhood3D,
+                          ValueType backgroundValue)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "labelVolumeWithBackground(): shape mismatch between input and output.");
+    return labelVolumeWithBackground(srcMultiArrayRange(source), destMultiArray(dest), 
+                                     neighborhood3D, backgroundValue,
+                                     std::equal_to<T1>());
+}
+
+//@}
+
+} //end of namespace vigra
+
+#endif //VIGRA_LABELVOLUME_HXX
diff --git a/include/vigra/linear_algebra.hxx b/include/vigra/linear_algebra.hxx
new file mode 100644
index 0000000..99c223e
--- /dev/null
+++ b/include/vigra/linear_algebra.hxx
@@ -0,0 +1,44 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 2004 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_LINEAR_ALGEBRA_HXX
+#define VIGRA_LINEAR_ALGEBRA_HXX
+
+#include "matrix.hxx"
+#include "linear_solve.hxx"
+#include "eigensystem.hxx"
+
+#endif // VIGRA_LINEAR_ALGEBRA_HXX
diff --git a/include/vigra/linear_solve.hxx b/include/vigra/linear_solve.hxx
new file mode 100644
index 0000000..f6dd258
--- /dev/null
+++ b/include/vigra/linear_solve.hxx
@@ -0,0 +1,1279 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2003-2008 by Gunnar Kedenburg and Ullrich Koethe       */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_LINEAR_SOLVE_HXX
+#define VIGRA_LINEAR_SOLVE_HXX
+
+#include <ctype.h>
+#include <string>
+#include "mathutil.hxx"
+#include "matrix.hxx"
+#include "singular_value_decomposition.hxx"
+
+
+namespace vigra
+{
+
+namespace linalg
+{
+
+namespace detail {
+
+template <class T, class C1>
+T determinantByLUDecomposition(MultiArrayView<2, T, C1> const & a)
+{
+    typedef MultiArrayShape<2>::type Shape;
+
+    MultiArrayIndex m = rowCount(a), n = columnCount(a);
+    vigra_precondition(n == m,
+       "determinant(): square matrix required.");
+       
+    Matrix<T> LU(a);
+    T det = 1.0;
+
+    for (MultiArrayIndex j = 0; j < n; ++j) 
+    {
+        // Apply previous transformations.
+        for (MultiArrayIndex i = 0; i < m; ++i) 
+        {
+            MultiArrayIndex end = std::min(i, j);
+            T s = dot(rowVector(LU, Shape(i,0), end), columnVector(LU, Shape(0,j), end));
+            LU(i,j) = LU(i,j) -= s;
+        }
+
+        // Find pivot and exchange if necessary.
+        MultiArrayIndex p = j + argMax(abs(columnVector(LU, Shape(j,j), m)));
+        if (p != j) 
+        {
+            rowVector(LU, p).swapData(rowVector(LU, j));
+            det = -det;
+        }
+        
+        det *= LU(j,j);
+
+        // Compute multipliers.
+        if (LU(j,j) != 0.0)
+            columnVector(LU, Shape(j+1,j), m) /= LU(j,j);
+        else
+            break; // det is zero
+    }
+    return det;
+}
+
+// returns the new value of 'a' (when this Givens rotation is applied to 'a' and 'b')
+// the new value of 'b' is zero, of course
+template <class T>
+T givensCoefficients(T a, T b, T & c, T & s)
+{
+    if(abs(a) < abs(b))
+    {
+        T t = a/b, 
+          r = std::sqrt(1.0 + t*t);
+        s = 1.0 / r;
+        c = t*s;
+        return r*b;
+    }
+    else if(a != 0.0)
+    {
+        T t = b/a, 
+          r = std::sqrt(1.0 + t*t);
+        c = 1.0 / r;
+        s = t*c;
+        return r*a;
+    }
+    else // a == b == 0.0
+    {
+        c = 1.0;
+        s = 0.0;
+        return 0.0;
+    }
+}
+
+// see Golub, van Loan: Algorithm 5.1.3 (p. 216)
+template <class T>
+bool givensRotationMatrix(T a, T b, Matrix<T> & gTranspose)
+{
+    if(b == 0.0)
+        return false; // no rotation needed
+    givensCoefficients(a, b, gTranspose(0,0), gTranspose(0,1));
+    gTranspose(1,1) = gTranspose(0,0);
+    gTranspose(1,0) = -gTranspose(0,1);
+    return true;
+}
+
+// reflections are symmetric matrices and can thus be applied to rows
+// and columns in the same way => code simplification relative to rotations
+template <class T>
+inline bool 
+givensReflectionMatrix(T a, T b, Matrix<T> & g)
+{
+    if(b == 0.0)
+        return false; // no reflection needed
+    givensCoefficients(a, b, g(0,0), g(0,1));
+    g(1,1) = -g(0,0);
+    g(1,0) = g(0,1);
+    return true;
+}
+
+// see Golub, van Loan: Algorithm 5.2.2 (p. 227) and Section 12.5.2 (p. 608)
+template <class T, class C1, class C2>
+bool 
+qrGivensStepImpl(MultiArrayIndex i, MultiArrayView<2, T, C1> r, MultiArrayView<2, T, C2> rhs)
+{
+    typedef typename Matrix<T>::difference_type Shape;
+    
+    const MultiArrayIndex m = rowCount(r);
+    const MultiArrayIndex n = columnCount(r);
+    const MultiArrayIndex rhsCount = columnCount(rhs);
+    vigra_precondition(m == rowCount(rhs),
+                       "qrGivensStepImpl(): Matrix shape mismatch.");
+
+    Matrix<T> givens(2,2);
+    for(int k=m-1; k>(int)i; --k)
+    {
+        if(!givensReflectionMatrix(r(k-1,i), r(k,i), givens))
+            continue; // r(k,i) was already zero
+
+        r(k-1,i) = givens(0,0)*r(k-1,i) + givens(0,1)*r(k,i);
+        r(k,i) = 0.0;
+        
+        r.subarray(Shape(k-1,i+1), Shape(k+1,n)) = givens*r.subarray(Shape(k-1,i+1), Shape(k+1,n));
+        rhs.subarray(Shape(k-1,0), Shape(k+1,rhsCount)) = givens*rhs.subarray(Shape(k-1,0), Shape(k+1,rhsCount));
+    }
+    return r(i,i) != 0.0;
+}
+
+// see Golub, van Loan: Section 12.5.2 (p. 608)
+template <class T, class C1, class C2, class Permutation>
+void 
+upperTriangularCyclicShiftColumns(MultiArrayIndex i, MultiArrayIndex j, 
+                                  MultiArrayView<2, T, C1> &r, MultiArrayView<2, T, C2> &rhs, Permutation & permutation)
+{
+    typedef typename Matrix<T>::difference_type Shape;
+    
+    const MultiArrayIndex m = rowCount(r);
+    const MultiArrayIndex n = columnCount(r);
+    const MultiArrayIndex rhsCount = columnCount(rhs);
+    vigra_precondition(i < n && j < n,
+                       "upperTriangularCyclicShiftColumns(): Shift indices out of range.");
+    vigra_precondition(m == rowCount(rhs),
+                       "upperTriangularCyclicShiftColumns(): Matrix shape mismatch.");
+
+    if(j == i)
+        return;
+    if(j < i)
+        std::swap(j,i);
+        
+    Matrix<T> t = columnVector(r, i);
+    MultiArrayIndex ti = permutation[i];
+    for(MultiArrayIndex k=i; k<j;++k)
+    {
+        columnVector(r, k) = columnVector(r, k+1);
+        permutation[k] = permutation[k+1];
+    }
+    columnVector(r, j) = t;
+    permutation[j] = ti;
+    
+    Matrix<T> givens(2,2);
+    for(MultiArrayIndex k=i; k<j; ++k)
+    {
+        if(!givensReflectionMatrix(r(k,k), r(k+1,k), givens))
+            continue;  // r(k+1,k) was already zero
+        
+        r(k,k) = givens(0,0)*r(k,k) + givens(0,1)*r(k+1,k);
+        r(k+1,k) = 0.0;
+        
+        r.subarray(Shape(k,k+1), Shape(k+2,n)) = givens*r.subarray(Shape(k,k+1), Shape(k+2,n));
+        rhs.subarray(Shape(k,0), Shape(k+2,rhsCount)) = givens*rhs.subarray(Shape(k,0), Shape(k+2,rhsCount));
+    }
+}
+
+// see Golub, van Loan: Section 12.5.2 (p. 608)
+template <class T, class C1, class C2, class Permutation>
+void 
+upperTriangularSwapColumns(MultiArrayIndex i, MultiArrayIndex j, 
+                           MultiArrayView<2, T, C1> &r, MultiArrayView<2, T, C2> &rhs, Permutation & permutation)
+{    
+    typedef typename Matrix<T>::difference_type Shape;
+    
+    const MultiArrayIndex m = rowCount(r);
+    const MultiArrayIndex n = columnCount(r);
+    const MultiArrayIndex rhsCount = columnCount(rhs);
+    vigra_precondition(i < n && j < n,
+                       "upperTriangularSwapColumns(): Swap indices out of range.");
+    vigra_precondition(m == rowCount(rhs),
+                       "upperTriangularSwapColumns(): Matrix shape mismatch.");
+
+    if(j == i)
+        return;
+    if(j < i)
+        std::swap(j,i);
+
+    columnVector(r, i).swapData(columnVector(r, j));
+    std::swap(permutation[i], permutation[j]);
+    
+    Matrix<T> givens(2,2);
+    for(int k=m-1; k>(int)i; --k)
+    {
+        if(!givensReflectionMatrix(r(k-1,i), r(k,i), givens))
+            continue; // r(k,i) was already zero
+
+        r(k-1,i) = givens(0,0)*r(k-1,i) + givens(0,1)*r(k,i);
+        r(k,i) = 0.0;
+        
+        r.subarray(Shape(k-1,i+1), Shape(k+1,n)) = givens*r.subarray(Shape(k-1,i+1), Shape(k+1,n));
+        rhs.subarray(Shape(k-1,0), Shape(k+1,rhsCount)) = givens*rhs.subarray(Shape(k-1,0), Shape(k+1,rhsCount));
+    }
+    MultiArrayIndex end = std::min(j, m-1);
+    for(MultiArrayIndex k=i+1; k<end; ++k)
+    {
+        if(!givensReflectionMatrix(r(k,k), r(k+1,k), givens))
+            continue;  // r(k+1,k) was already zero
+        
+        r(k,k) = givens(0,0)*r(k,k) + givens(0,1)*r(k+1,k);
+        r(k+1,k) = 0.0;
+        
+        r.subarray(Shape(k,k+1), Shape(k+2,n)) = givens*r.subarray(Shape(k,k+1), Shape(k+2,n));
+        rhs.subarray(Shape(k,0), Shape(k+2,rhsCount)) = givens*rhs.subarray(Shape(k,0), Shape(k+2,rhsCount));
+    }
+}
+
+// see Lawson & Hanson: Algorithm H1 (p. 57)
+template <class T, class C1, class C2, class U>
+bool householderVector(MultiArrayView<2, T, C1> const & v, MultiArrayView<2, T, C2> & u, U & vnorm)
+{
+    vnorm = (v(0,0) > 0.0)
+                 ? -norm(v)
+                 :  norm(v);
+    U f = std::sqrt(vnorm*(vnorm - v(0,0)));
+    
+    if(f == NumericTraits<U>::zero())
+    {
+        u.init(NumericTraits<T>::zero());
+        return false;
+    }
+    else
+    {
+        u(0,0) = (v(0,0) - vnorm) / f;
+        for(MultiArrayIndex k=1; k<rowCount(u); ++k)
+            u(k,0) = v(k,0) / f;
+        return true;
+    }
+}
+
+// see Lawson & Hanson: Algorithm H1 (p. 57)
+template <class T, class C1, class C2, class C3>
+bool 
+qrHouseholderStepImpl(MultiArrayIndex i, MultiArrayView<2, T, C1> & r, 
+                      MultiArrayView<2, T, C2> & rhs, MultiArrayView<2, T, C3> & householderMatrix)
+{
+    typedef typename Matrix<T>::difference_type Shape;
+    
+    const MultiArrayIndex m = rowCount(r);
+    const MultiArrayIndex n = columnCount(r);
+    const MultiArrayIndex rhsCount = columnCount(rhs);
+
+    vigra_precondition(i < n && i < m,
+        "qrHouseholderStepImpl(): Index i out of range.");
+
+    Matrix<T> u(m-i,1);
+    T vnorm;
+    bool nontrivial = householderVector(columnVector(r, Shape(i,i), m), u, vnorm);
+    
+    r(i,i) = vnorm;
+    columnVector(r, Shape(i+1,i), m).init(NumericTraits<T>::zero());
+
+    if(columnCount(householderMatrix) == n)
+        columnVector(householderMatrix, Shape(i,i), m) = u;
+
+    if(nontrivial)
+    {
+        for(MultiArrayIndex k=i+1; k<n; ++k)
+            columnVector(r, Shape(i,k), m) -= dot(columnVector(r, Shape(i,k), m), u) * u;
+        for(MultiArrayIndex k=0; k<rhsCount; ++k)
+            columnVector(rhs, Shape(i,k), m) -= dot(columnVector(rhs, Shape(i,k), m), u) * u;
+    }
+    return r(i,i) != 0.0;
+}
+
+template <class T, class C1, class C2>
+bool 
+qrColumnHouseholderStep(MultiArrayIndex i, MultiArrayView<2, T, C1> &r, MultiArrayView<2, T, C2> &rhs)
+{
+    Matrix<T> dontStoreHouseholderVectors; // intentionally empty
+    return qrHouseholderStepImpl(i, r, rhs, dontStoreHouseholderVectors);
+}
+
+template <class T, class C1, class C2>
+bool 
+qrRowHouseholderStep(MultiArrayIndex i, MultiArrayView<2, T, C1> &r, MultiArrayView<2, T, C2> & householderMatrix)
+{
+    Matrix<T> dontTransformRHS; // intentionally empty
+    MultiArrayView<2, T, StridedArrayTag> rt = transpose(r),
+                                          ht = transpose(householderMatrix);
+    return qrHouseholderStepImpl(i, rt, dontTransformRHS, ht);
+}
+
+// O(n) algorithm due to Bischof: Incremental Condition Estimation, 1990
+template <class T, class C1, class C2, class SNType>
+void
+incrementalMaxSingularValueApproximation(MultiArrayView<2, T, C1> const & newColumn, 
+                                         MultiArrayView<2, T, C2> & z, SNType & v) 
+{
+    typedef typename Matrix<T>::difference_type Shape;
+    MultiArrayIndex n = rowCount(newColumn) - 1;
+    
+    SNType vneu = squaredNorm(newColumn);
+    T yv = dot(columnVector(newColumn, Shape(0,0),n), columnVector(z, Shape(0,0),n));
+    // use atan2 as it is robust against overflow/underflow
+    T t = 0.5*std::atan2(T(2.0*yv), T(sq(v)-vneu)),
+      s = std::sin(t),
+      c = std::cos(t);
+    v = std::sqrt(sq(c*v) + sq(s)*vneu + 2.0*s*c*yv);
+    columnVector(z, Shape(0,0),n) = c*columnVector(z, Shape(0,0),n) + s*columnVector(newColumn, Shape(0,0),n);
+    z(n,0) = s*newColumn(n,0);
+}
+
+// O(n) algorithm due to Bischof: Incremental Condition Estimation, 1990
+template <class T, class C1, class C2, class SNType>
+void
+incrementalMinSingularValueApproximation(MultiArrayView<2, T, C1> const & newColumn, 
+                                         MultiArrayView<2, T, C2> & z, SNType & v, double tolerance) 
+{
+    typedef typename Matrix<T>::difference_type Shape;
+
+    if(v <= tolerance)
+    {
+        v = 0.0;
+        return;
+    }
+
+    MultiArrayIndex n = rowCount(newColumn) - 1;
+    
+    T gamma = newColumn(n,0);
+    if(gamma == 0.0) 
+    {
+        v = 0.0;
+        return;
+    }
+    
+    T yv = dot(columnVector(newColumn, Shape(0,0),n), columnVector(z, Shape(0,0),n));
+    // use atan2 as it is robust against overflow/underflow
+    T t = 0.5*std::atan2(T(-2.0*yv), T(squaredNorm(gamma / v) + squaredNorm(yv) - 1.0)),
+      s = std::sin(t),
+      c = std::cos(t);
+    columnVector(z, Shape(0,0),n) *= c;
+    z(n,0) = (s - c*yv) / gamma;
+    v *= norm(gamma) / hypot(c*gamma, v*(s - c*yv));
+}
+
+// QR algorithm with optional column pivoting
+template <class T, class C1, class C2, class C3>
+unsigned int 
+qrTransformToTriangularImpl(MultiArrayView<2, T, C1> & r, MultiArrayView<2, T, C2> & rhs, MultiArrayView<2, T, C3> & householder,
+                            ArrayVector<MultiArrayIndex> & permutation, double epsilon)
+{
+    typedef typename Matrix<T>::difference_type Shape;
+    typedef typename NormTraits<MultiArrayView<2, T, C1> >::NormType NormType;
+    typedef typename NormTraits<MultiArrayView<2, T, C1> >::SquaredNormType SNType;
+    
+    const MultiArrayIndex m = rowCount(r);
+    const MultiArrayIndex n = columnCount(r);
+    const MultiArrayIndex maxRank = std::min(m, n);
+    
+    vigra_precondition(m >= n,
+        "qrTransformToTriangularImpl(): Coefficient matrix with at least as many rows as columns required.");
+
+    const MultiArrayIndex rhsCount = columnCount(rhs);
+    bool transformRHS = rhsCount > 0;
+    vigra_precondition(!transformRHS || m == rowCount(rhs),
+                       "qrTransformToTriangularImpl(): RHS matrix shape mismatch.");
+                       
+    bool storeHouseholderSteps = columnCount(householder) > 0;
+    vigra_precondition(!storeHouseholderSteps || r.shape() == householder.shape(),
+                       "qrTransformToTriangularImpl(): Householder matrix shape mismatch.");
+                       
+    bool pivoting = permutation.size() > 0;
+    vigra_precondition(!pivoting || n == (MultiArrayIndex)permutation.size(),
+                       "qrTransformToTriangularImpl(): Permutation array size mismatch.");
+
+    if(n == 0)
+        return 0; // trivial solution
+        
+    Matrix<SNType> columnSquaredNorms;
+    if(pivoting)
+    {
+        columnSquaredNorms.reshape(Shape(1,n));
+        for(MultiArrayIndex k=0; k<n; ++k)
+            columnSquaredNorms[k] = squaredNorm(columnVector(r, k));
+            
+        int pivot = argMax(columnSquaredNorms);
+        if(pivot != 0)
+        {
+            columnVector(r, 0).swapData(columnVector(r, pivot));
+            std::swap(columnSquaredNorms[0], columnSquaredNorms[pivot]);
+            std::swap(permutation[0], permutation[pivot]);
+        }
+    }
+    
+    qrHouseholderStepImpl(0, r, rhs, householder);
+    
+    MultiArrayIndex rank = 1;
+    NormType maxApproxSingularValue = norm(r(0,0)),
+             minApproxSingularValue = maxApproxSingularValue;
+    
+    double tolerance = (epsilon == 0.0)
+                          ? m*maxApproxSingularValue*NumericTraits<T>::epsilon()
+                          : epsilon;
+    
+    bool simpleSingularValueApproximation = (n < 4);
+    Matrix<T> zmax, zmin;
+    if(minApproxSingularValue <= tolerance)
+    {
+        rank = 0;
+        pivoting = false;
+        simpleSingularValueApproximation = true;
+    }
+    if(!simpleSingularValueApproximation)
+    {
+        zmax.reshape(Shape(m,1));
+        zmin.reshape(Shape(m,1));
+        zmax(0,0) = r(0,0);
+        zmin(0,0) = 1.0 / r(0,0);
+    }
+
+    for(MultiArrayIndex k=1; k<maxRank; ++k)
+    {
+        if(pivoting)
+        {
+            for(MultiArrayIndex l=k; l<n; ++l)
+                columnSquaredNorms[l] -= squaredNorm(r(k, l));
+            int pivot = k + argMax(rowVector(columnSquaredNorms, Shape(0,k), n));
+            if(pivot != (int)k)
+            {
+                columnVector(r, k).swapData(columnVector(r, pivot));
+                std::swap(columnSquaredNorms[k], columnSquaredNorms[pivot]);
+                std::swap(permutation[k], permutation[pivot]);
+            }
+        }
+        
+        qrHouseholderStepImpl(k, r, rhs, householder);
+
+        if(simpleSingularValueApproximation)
+        {
+            NormType nv = norm(r(k,k));        
+            maxApproxSingularValue = std::max(nv, maxApproxSingularValue);
+            minApproxSingularValue = std::min(nv, minApproxSingularValue);
+        }
+        else
+        {
+            incrementalMaxSingularValueApproximation(columnVector(r, Shape(0,k),k+1), zmax, maxApproxSingularValue);
+            incrementalMinSingularValueApproximation(columnVector(r, Shape(0,k),k+1), zmin, minApproxSingularValue, tolerance);
+        }
+        
+#if 0
+        Matrix<T> u(k+1,k+1), s(k+1, 1), v(k+1,k+1);
+        singularValueDecomposition(r.subarray(Shape(0,0), Shape(k+1,k+1)), u, s, v);
+        std::cerr << "estimate, svd " << k << ": " << minApproxSingularValue << " " << s(k,0) << "\n";
+#endif
+        
+        if(epsilon == 0.0)
+            tolerance = m*maxApproxSingularValue*NumericTraits<T>::epsilon();
+
+        if(minApproxSingularValue > tolerance)
+            ++rank;
+        else
+            pivoting = false; // matrix doesn't have full rank, triangulize the rest without pivoting
+    }
+    return (unsigned int)rank;
+}
+
+template <class T, class C1, class C2>
+unsigned int 
+qrTransformToUpperTriangular(MultiArrayView<2, T, C1> & r, MultiArrayView<2, T, C2> & rhs, 
+                             ArrayVector<MultiArrayIndex> & permutation, double epsilon = 0.0)
+{
+    Matrix<T> dontStoreHouseholderVectors; // intentionally empty
+    return qrTransformToTriangularImpl(r, rhs, dontStoreHouseholderVectors, permutation, epsilon);
+}
+
+// QR algorithm with optional row pivoting
+template <class T, class C1, class C2, class C3>
+unsigned int 
+qrTransformToLowerTriangular(MultiArrayView<2, T, C1> & r, MultiArrayView<2, T, C2> & rhs, MultiArrayView<2, T, C3> & householderMatrix, 
+                      double epsilon = 0.0)
+{
+    ArrayVector<MultiArrayIndex> permutation((unsigned int)rowCount(rhs));
+    for(MultiArrayIndex k=0; k<(MultiArrayIndex)permutation.size(); ++k)
+        permutation[k] = k;
+    Matrix<T> dontTransformRHS; // intentionally empty
+    MultiArrayView<2, T, StridedArrayTag> rt = transpose(r),
+                                          ht = transpose(householderMatrix);
+    unsigned int rank = qrTransformToTriangularImpl(rt, dontTransformRHS, ht, permutation, epsilon);
+    
+    // apply row permutation to RHS
+    Matrix<T> tempRHS(rhs);
+    for(MultiArrayIndex k=0; k<(MultiArrayIndex)permutation.size(); ++k)
+        rowVector(rhs, k) = rowVector(tempRHS, permutation[k]);
+    return rank;
+}
+
+// QR algorithm without column pivoting
+template <class T, class C1, class C2>
+inline bool
+qrTransformToUpperTriangular(MultiArrayView<2, T, C1> & r, MultiArrayView<2, T, C2> & rhs, 
+                      double epsilon = 0.0)
+{
+    ArrayVector<MultiArrayIndex> noPivoting; // intentionally empty
+    
+    return (qrTransformToUpperTriangular(r, rhs, noPivoting, epsilon) == 
+            (unsigned int)columnCount(r));
+}
+
+// QR algorithm without row pivoting
+template <class T, class C1, class C2>
+inline bool
+qrTransformToLowerTriangular(MultiArrayView<2, T, C1> & r, MultiArrayView<2, T, C2> & householder, 
+                      double epsilon = 0.0)
+{
+    Matrix<T> noPivoting; // intentionally empty
+    
+    return (qrTransformToLowerTriangular(r, noPivoting, householder, epsilon) == 
+           (unsigned int)rowCount(r));
+}
+
+// restore ordering of result vector elements after QR solution with column pivoting
+template <class T, class C1, class C2, class Permutation>
+void inverseRowPermutation(MultiArrayView<2, T, C1> &permuted, MultiArrayView<2, T, C2> &res,
+                           Permutation const & permutation)
+{
+    for(MultiArrayIndex k=0; k<columnCount(permuted); ++k)
+        for(MultiArrayIndex l=0; l<rowCount(permuted); ++l)
+            res(permutation[l], k) = permuted(l,k);
+}
+
+template <class T, class C1, class C2>
+void applyHouseholderColumnReflections(MultiArrayView<2, T, C1> const &householder, MultiArrayView<2, T, C2> &res)
+{
+    typedef typename Matrix<T>::difference_type Shape;
+    MultiArrayIndex n = rowCount(householder);
+    MultiArrayIndex m = columnCount(householder);
+    MultiArrayIndex rhsCount = columnCount(res);
+    
+    for(int k = m-1; k >= 0; --k)
+    {
+        MultiArrayView<2, T, C1> u = columnVector(householder, Shape(k,k), n);
+        for(MultiArrayIndex l=0; l<rhsCount; ++l)
+            columnVector(res, Shape(k,l), n) -= dot(columnVector(res, Shape(k,l), n), u) * u;
+    }
+}
+
+} // namespace detail
+
+template <class T, class C1, class C2, class C3>
+unsigned int 
+linearSolveQRReplace(MultiArrayView<2, T, C1> &A, MultiArrayView<2, T, C2> &b,
+                     MultiArrayView<2, T, C3> & res, 
+                     double epsilon = 0.0)
+{
+    typedef typename Matrix<T>::difference_type Shape;
+
+    MultiArrayIndex n = columnCount(A);
+    MultiArrayIndex m = rowCount(A);
+    MultiArrayIndex rhsCount = columnCount(res);
+    MultiArrayIndex rank = std::min(m,n);
+    Shape ul(MultiArrayIndex(0), MultiArrayIndex(0));
+
+    
+    vigra_precondition(rhsCount == columnCount(b),
+           "linearSolveQR(): RHS and solution must have the same number of columns.");
+    vigra_precondition(m == rowCount(b),
+           "linearSolveQR(): Coefficient matrix and RHS must have the same number of rows.");
+    vigra_precondition(n == rowCount(res),
+           "linearSolveQR(): Mismatch between column count of coefficient matrix and row count of solution.");
+    vigra_precondition(epsilon >= 0.0,
+           "linearSolveQR(): 'epsilon' must be non-negative.");
+    
+    if(m < n)
+    {
+        // minimum norm solution of underdetermined system
+        Matrix<T> householderMatrix(n, m);
+        MultiArrayView<2, T, StridedArrayTag> ht = transpose(householderMatrix);
+        rank = (MultiArrayIndex)detail::qrTransformToLowerTriangular(A, b, ht, epsilon);
+        res.subarray(Shape(rank,0), Shape(n, rhsCount)).init(NumericTraits<T>::zero());
+        if(rank < m)
+        {
+            // system is also rank-deficient => compute minimum norm least squares solution
+            MultiArrayView<2, T, C1> Asub = A.subarray(ul, Shape(m,rank));
+            detail::qrTransformToUpperTriangular(Asub, b, epsilon);
+            linearSolveUpperTriangular(A.subarray(ul, Shape(rank,rank)), 
+                                       b.subarray(ul, Shape(rank,rhsCount)), 
+                                       res.subarray(ul, Shape(rank, rhsCount)));
+        }
+        else
+        {
+            // system has full rank => compute minimum norm solution
+            linearSolveLowerTriangular(A.subarray(ul, Shape(rank,rank)), 
+                                       b.subarray(ul, Shape(rank, rhsCount)), 
+                                       res.subarray(ul, Shape(rank, rhsCount)));
+        }
+        detail::applyHouseholderColumnReflections(householderMatrix.subarray(ul, Shape(n, rank)), res);
+    }
+    else
+    {
+        // solution of well-determined or overdetermined system
+        ArrayVector<MultiArrayIndex> permutation((unsigned int)n);
+        for(MultiArrayIndex k=0; k<n; ++k)
+            permutation[k] = k;
+
+        rank = (MultiArrayIndex)detail::qrTransformToUpperTriangular(A, b, permutation, epsilon);
+        
+        Matrix<T> permutedSolution(n, rhsCount);
+        if(rank < n)
+        {
+            // system is rank-deficient => compute minimum norm solution
+            Matrix<T> householderMatrix(n, rank);
+            MultiArrayView<2, T, StridedArrayTag> ht = transpose(householderMatrix);
+            MultiArrayView<2, T, C1> Asub = A.subarray(ul, Shape(rank,n));
+            detail::qrTransformToLowerTriangular(Asub, ht, epsilon);
+            linearSolveLowerTriangular(A.subarray(ul, Shape(rank,rank)), 
+                                       b.subarray(ul, Shape(rank, rhsCount)), 
+                                       permutedSolution.subarray(ul, Shape(rank, rhsCount)));
+            detail::applyHouseholderColumnReflections(householderMatrix, permutedSolution);
+        }
+        else
+        {
+            // system has full rank => compute exact or least squares solution
+            linearSolveUpperTriangular(A.subarray(ul, Shape(rank,rank)), 
+                                       b.subarray(ul, Shape(rank,rhsCount)), 
+                                       permutedSolution);
+        }
+        detail::inverseRowPermutation(permutedSolution, res, permutation);
+    }
+    return (unsigned int)rank;
+}
+
+template <class T, class C1, class C2, class C3>
+unsigned int linearSolveQR(MultiArrayView<2, T, C1> const & A, MultiArrayView<2, T, C2> const & b,
+                                  MultiArrayView<2, T, C3> & res)
+{
+    Matrix<T> r(A), rhs(b);
+    return linearSolveQRReplace(r, rhs, res);
+}
+
+/** \defgroup MatrixAlgebra Advanced Matrix Algebra
+    
+    \brief Solution of linear systems, eigen systems, linear least squares etc.
+    
+    \ingroup LinearAlgebraModule
+ */
+//@{
+    /** Create the inverse or pseudo-inverse of matrix \a v.
+
+        If the matrix \a v is square, \a res must have the same shape and will contain the
+        inverse of \a v. If \a v is rectangular, \a res must have the transposed shape 
+        of \a v. The inverse is then computed in the least-squares 
+        sense, i.e. \a res will be the pseudo-inverse (Moore-Penrose inverse).
+        The function returns <tt>true</tt> upon success, and <tt>false</tt> if \a v 
+        is not invertible (has not full rank). The inverse is computed by means of QR 
+        decomposition. This function can be applied in-place.
+        
+        <b>\#include</b> \<vigra/linear_solve.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2>
+bool inverse(const MultiArrayView<2, T, C1> &v, MultiArrayView<2, T, C2> &res)
+{
+    typedef typename MultiArrayShape<2>::type Shape;
+    
+    const MultiArrayIndex n = columnCount(v);
+    const MultiArrayIndex m = rowCount(v);
+    vigra_precondition(n == rowCount(res) && m == columnCount(res),
+       "inverse(): shape of output matrix must be the transpose of the input matrix' shape.");
+    
+    if(m < n)
+    {
+        MultiArrayView<2, T, StridedArrayTag> vt = transpose(v);
+        Matrix<T> r(vt.shape()), q(n, n);
+        if(!qrDecomposition(vt, q, r))
+            return false; // a didn't have full rank
+        linearSolveUpperTriangular(r.subarray(Shape(0,0), Shape(m,m)), 
+                                   transpose(q).subarray(Shape(0,0), Shape(m,n)), 
+                                   transpose(res)); 
+    }
+    else
+    {
+        Matrix<T> r(v.shape()), q(m, m);
+        if(!qrDecomposition(v, q, r))
+            return false; // a didn't have full rank
+        linearSolveUpperTriangular(r.subarray(Shape(0,0), Shape(n,n)), 
+                                   transpose(q).subarray(Shape(0,0), Shape(n,m)), 
+                                   res); 
+    }
+    return true;
+}
+
+    /** Create the inverse or pseudo-inverse of matrix \a v.
+
+        The result is returned as a temporary matrix. If the matrix \a v is square, 
+        the result will have the same shape and contains the inverse of \a v. 
+        If \a v is rectangular, the result will have the transposed shape of \a v. 
+        The inverse is then computed in the least-squares 
+        sense, i.e. \a res will be the pseudo-inverse (Moore-Penrose inverse).
+        The inverse is computed by means of QR decomposition. If \a v
+        is not invertible, <tt>vigra::PreconditionViolation</tt> exception is thrown.
+        Usage:
+
+        \code
+        vigra::Matrix<double> v(n, n);
+        v = ...;
+
+        vigra::Matrix<double> m = inverse(v);
+        \endcode
+
+        <b>\#include</b> \<vigra/linear_solve.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+TemporaryMatrix<T> inverse(const MultiArrayView<2, T, C> &v)
+{
+    TemporaryMatrix<T> ret(columnCount(v), rowCount(v));  // transpose shape
+    vigra_precondition(inverse(v, ret),
+        "inverse(): matrix is not invertible.");
+    return ret;
+}
+
+template <class T>
+TemporaryMatrix<T> inverse(const TemporaryMatrix<T> &v)
+{
+    if(columnCount(v) == rowCount(v))
+    {
+        vigra_precondition(inverse(v, const_cast<TemporaryMatrix<T> &>(v)),
+            "inverse(): matrix is not invertible.");
+        return v;      
+    }
+    else
+    {
+        TemporaryMatrix<T> ret(columnCount(v), rowCount(v));  // transpose shape
+        vigra_precondition(inverse(v, ret),
+            "inverse(): matrix is not invertible.");
+        return ret;
+    }
+}
+
+    /** Compute the determinant of a square matrix.
+
+        \a method must be one of the following:
+        <DL>
+        <DT>"Cholesky"<DD> Compute the solution by means of Cholesky decomposition. This
+                           method is faster than "LU", but requires the matrix \a a 
+                           to be symmetric positive definite. If this is 
+                           not the case, a <tt>ContractViolation</tt> exception is thrown.
+                           
+        <DT>"LU"<DD> (default) Compute the solution by means of LU decomposition.
+        </DL>
+
+        <b>\#include</b> \<vigra/linear_solve.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1>
+T determinant(MultiArrayView<2, T, C1> const & a, std::string method = "LU")
+{
+    MultiArrayIndex n = columnCount(a);
+    vigra_precondition(rowCount(a) == n,
+               "determinant(): Square matrix required.");    
+
+    method = tolower(method);
+    
+    if(n == 1)
+        return a(0,0);
+    if(n == 2)
+        return a(0,0)*a(1,1) - a(0,1)*a(1,0);
+    if(method == "lu")
+    {
+        return detail::determinantByLUDecomposition(a);
+    }
+    else if(method == "cholesky")
+    {
+        Matrix<T> L(a.shape());
+        vigra_precondition(choleskyDecomposition(a, L),
+           "determinant(): Cholesky method requires symmetric positive definite matrix.");
+        T det = L(0,0);
+        for(MultiArrayIndex k=1; k<n; ++k)
+            det *= L(k,k);
+        return sq(det);
+    }
+    else
+    {
+        vigra_precondition(false, "determinant(): Unknown solution method.");
+    }
+    return T();
+}
+
+    /** Compute the logarithm of the determinant of a symmetric positive definite matrix.
+
+        This is useful to avoid multiplication of very large numbers in big matrices.
+        It is implemented by means of Cholesky decomposition.
+
+        <b>\#include</b> \<vigra/linear_solve.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1>
+T logDeterminant(MultiArrayView<2, T, C1> const & a)
+{
+    MultiArrayIndex n = columnCount(a);
+    vigra_precondition(rowCount(a) == n,
+               "logDeterminant(): Square matrix required.");    
+    if(n == 1)
+    {
+        vigra_precondition(a(0,0) > 0.0,
+                   "logDeterminant(): Matrix not positive definite.");    
+        return std::log(a(0,0));
+    }
+    if(n == 2)
+    {
+        T det = a(0,0)*a(1,1) - a(0,1)*a(1,0);
+        vigra_precondition(det > 0.0,
+                   "logDeterminant(): Matrix not positive definite.");    
+        return std::log(det);
+    }
+    else
+    {
+        Matrix<T> L(a.shape());
+        vigra_precondition(choleskyDecomposition(a, L),
+                "logDeterminant(): Matrix not positive definite.");  
+        T logdet = std::log(L(0,0)); 
+        for(MultiArrayIndex k=1; k<n; ++k)
+            logdet += std::log(L(k,k));  // L(k,k) is guaranteed to be positive
+        return 2.0*logdet;
+    }
+}
+
+    /** Cholesky decomposition.
+
+        \a A must be a symmetric positive definite matrix, and \a L will be a lower
+        triangular matrix, such that (up to round-off errors):
+
+        \code
+        A == L * transpose(L);
+        \endcode
+
+        This implementation cannot be applied in-place, i.e. <tt>&L == &A</tt> is an error.
+        If \a A is not symmetric, a <tt>ContractViolation</tt> exception is thrown. If it
+        is not positive definite, the function returns <tt>false</tt>.
+
+        <b>\#include</b> \<vigra/linear_solve.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2>
+bool choleskyDecomposition(MultiArrayView<2, T, C1> const & A,
+                           MultiArrayView<2, T, C2> &L)
+{
+    MultiArrayIndex n = columnCount(A); 
+    vigra_precondition(rowCount(A) == n,
+                       "choleskyDecomposition(): Input matrix must be square.");
+    vigra_precondition(n == columnCount(L) && n == rowCount(L),
+                       "choleskyDecomposition(): Output matrix must have same shape as input matrix.");
+    vigra_precondition(isSymmetric(A),
+                       "choleskyDecomposition(): Input matrix must be symmetric.");
+
+    for (MultiArrayIndex j = 0; j < n; ++j) 
+    {
+        T d(0.0);
+        for (MultiArrayIndex k = 0; k < j; ++k) 
+        {
+            T s(0.0);
+            for (MultiArrayIndex i = 0; i < k; ++i) 
+            {
+               s += L(k, i)*L(j, i);
+            }
+            L(j, k) = s = (A(j, k) - s)/L(k, k);
+            d = d + s*s;
+        }
+        d = A(j, j) - d;
+        if(d <= 0.0)
+            return false;  // A is not positive definite
+        L(j, j) = std::sqrt(d);
+        for (MultiArrayIndex k = j+1; k < n; ++k) 
+        {
+           L(j, k) = 0.0;
+        }
+    }
+    return true;
+}
+
+    /** QR decomposition.
+
+        \a a contains the original matrix, results are returned in \a q and \a r, where
+        \a q is a orthogonal matrix, and \a r is an upper triangular matrix, such that 
+        (up to round-off errors):
+
+        \code
+        a == q * r;
+        \endcode
+
+        If \a a doesn't have full rank, the function returns <tt>false</tt>. 
+        The decomposition is computed by householder transformations. It can be applied in-place,
+        i.e. <tt>&a == &q</tt> or <tt>&a == &r</tt> are allowed.
+
+        <b>\#include</b> \<vigra/linear_solve.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+bool qrDecomposition(MultiArrayView<2, T, C1> const & a,
+                     MultiArrayView<2, T, C2> &q, MultiArrayView<2, T, C3> &r,
+                     double epsilon = 0.0)
+{
+    const MultiArrayIndex m = rowCount(a);
+    const MultiArrayIndex n = columnCount(a);
+    vigra_precondition(n == columnCount(r) && m == rowCount(r) &&
+                       m == columnCount(q) && m == rowCount(q),
+                       "qrDecomposition(): Matrix shape mismatch.");
+
+    q = identityMatrix<T>(m);
+    MultiArrayView<2,T, StridedArrayTag> tq = transpose(q);
+    r = a;
+    ArrayVector<MultiArrayIndex> noPivoting; // intentionally empty
+    return ((MultiArrayIndex)detail::qrTransformToUpperTriangular(r, tq, noPivoting, epsilon) == std::min(m,n));
+}
+
+    /** Deprecated, use \ref linearSolveUpperTriangular().
+     */
+template <class T, class C1, class C2, class C3>
+inline 
+bool reverseElimination(const MultiArrayView<2, T, C1> &r, const MultiArrayView<2, T, C2> &b,
+                        MultiArrayView<2, T, C3> x)
+{
+    return linearSolveUpperTriangular(r, b, x);
+}
+
+    /** Solve a linear system with upper-triangular coefficient matrix.
+
+        The square matrix \a r must be an upper-triangular coefficient matrix as can,
+        for example, be obtained by means of QR decomposition. If \a r doesn't have full rank
+        the function fails and returns <tt>false</tt>, otherwise it returns <tt>true</tt>. The 
+        lower triangular part of matrix \a r will not be touched, so it doesn't need to contain zeros.
+        
+        The column vectors of matrix \a b are the right-hand sides of the equation (several equations
+        with the same coefficients can thus be solved in one go). The result is returned
+        int \a x, whose columns contain the solutions for the corresponding
+        columns of \a b. This implementation can be applied in-place, i.e. <tt>&b == &x</tt> is allowed.
+        The following size requirements apply:
+        
+        \code
+        rowCount(r) == columnCount(r);
+        rowCount(r) == rowCount(b);
+        columnCount(r) == rowCount(x);
+        columnCount(b) == columnCount(x);
+        \endcode
+
+        <b>\#include</b> \<vigra/linear_solve.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+bool linearSolveUpperTriangular(const MultiArrayView<2, T, C1> &r, const MultiArrayView<2, T, C2> &b,
+                                MultiArrayView<2, T, C3> x)
+{
+    MultiArrayIndex m = rowCount(r);
+    MultiArrayIndex rhsCount = columnCount(b);
+    vigra_precondition(m == columnCount(r),
+        "linearSolveUpperTriangular(): square coefficient matrix required.");
+    vigra_precondition(m == rowCount(b) && m == rowCount(x) && rhsCount == columnCount(x),
+        "linearSolveUpperTriangular(): matrix shape mismatch.");
+
+    for(MultiArrayIndex k = 0; k < rhsCount; ++k)
+    {
+        for(int i=m-1; i>=0; --i)
+        {
+            if(r(i,i) == NumericTraits<T>::zero())
+                return false;  // r doesn't have full rank
+            T sum = b(i, k);
+            for(MultiArrayIndex j=i+1; j<m; ++j)
+                 sum -= r(i, j) * x(j, k);
+            x(i, k) = sum / r(i, i);
+        }
+    }
+    return true;
+}
+
+    /** Solve a linear system with lower-triangular coefficient matrix.
+
+        The square matrix \a l must be a lower-triangular coefficient matrix. If \a l 
+        doesn't have full rank the function fails and returns <tt>false</tt>, 
+        otherwise it returns <tt>true</tt>. The upper triangular part of matrix \a l will not be touched, 
+        so it doesn't need to contain zeros.
+        
+        The column vectors of matrix \a b are the right-hand sides of the equation (several equations
+        with the same coefficients can thus be solved in one go). The result is returned
+        in \a x, whose columns contain the solutions for the corresponding
+        columns of \a b. This implementation can be applied in-place, i.e. <tt>&b == &x</tt> is allowed.
+        The following size requirements apply:
+        
+        \code
+        rowCount(l) == columnCount(l);
+        rowCount(l) == rowCount(b);
+        columnCount(l) == rowCount(x);
+        columnCount(b) == columnCount(x);
+        \endcode
+
+        <b>\#include</b> \<vigra/linear_solve.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+bool linearSolveLowerTriangular(const MultiArrayView<2, T, C1> &l, const MultiArrayView<2, T, C2> &b,
+                            MultiArrayView<2, T, C3> x)
+{
+    MultiArrayIndex m = columnCount(l);
+    MultiArrayIndex n = columnCount(b);
+    vigra_precondition(m == rowCount(l),
+        "linearSolveLowerTriangular(): square coefficient matrix required.");
+    vigra_precondition(m == rowCount(b) && m == rowCount(x) && n == columnCount(x),
+        "linearSolveLowerTriangular(): matrix shape mismatch.");
+
+    for(MultiArrayIndex k = 0; k < n; ++k)
+    {
+        for(MultiArrayIndex i=0; i<m; ++i)
+        {
+            if(l(i,i) == NumericTraits<T>::zero())
+                return false;  // l doesn't have full rank
+            T sum = b(i, k);
+            for(MultiArrayIndex j=0; j<i; ++j)
+                 sum -= l(i, j) * x(j, k);
+            x(i, k) = sum / l(i, i);
+        }
+    }
+    return true;
+}
+
+
+    /** Solve a linear system when the Cholesky decomposition of the left hand side is given.
+
+        The square matrix \a L must be a lower-triangular matrix resulting from Cholesky
+        decomposition of some positive definite coefficient matrix.
+        
+        The column vectors of matrix \a b are the right-hand sides of the equation (several equations
+        with the same matrix \a L can thus be solved in one go). The result is returned
+        in \a x, whose columns contain the solutions for the corresponding
+        columns of \a b. This implementation can be applied in-place, i.e. <tt>&b == &x</tt> is allowed.
+        The following size requirements apply:
+        
+        \code
+        rowCount(L) == columnCount(L);
+        rowCount(L) == rowCount(b);
+        columnCount(L) == rowCount(x);
+        columnCount(b) == columnCount(x);
+        \endcode
+
+        <b>\#include</b> \<vigra/linear_solve.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+inline 
+void choleskySolve(MultiArrayView<2, T, C1> const & L, MultiArrayView<2, T, C2> const & b, MultiArrayView<2, T, C3> & x)
+{
+    /* Solve L * y = b */
+    linearSolveLowerTriangular(L, b, x);
+    /* Solve L^T * x = y */
+    linearSolveUpperTriangular(transpose(L), x, x);
+}
+
+    /** Solve a linear system.
+    
+        <b> Declarations:</b>
+        
+        \code
+        // use MultiArrayViews for input and output
+        template <class T, class C1, class C2, class C3>
+        bool linearSolve(MultiArrayView<2, T, C1> const & A, 
+                         MultiArrayView<2, T, C2> const & b,
+                         MultiArrayView<2, T, C3> res, 
+                         std::string method = "QR");
+                         
+        // use TinyVector for RHS and result
+        template <class T, class C1, int N>
+        bool linearSolve(MultiArrayView<2, T, C1> const & A, 
+                         TinyVector<T, N> const & b,
+                         TinyVector<T, N> & res, 
+                         std::string method = "QR");
+        \endcode
+
+        \a A is the coefficient matrix, and the column vectors
+        in \a b are the right-hand sides of the equation (so, several equations
+        with the same coefficients can be solved in one go). The result is returned 
+        in \a res, whose columns contain the solutions for the corresponding
+        columns of \a b. The number of columns of \a A must equal the number of rows of
+        both \a b and \a res, and the number of columns of \a b and \a res must match. 
+        If right-hand-side and result are specified as TinyVector, the number of columns 
+        of \a A must equal N.
+        
+        \a method must be one of the following:
+        <DL>
+        <DT>"Cholesky"<DD> Compute the solution by means of Cholesky decomposition. The 
+                           coefficient matrix \a A must by symmetric positive definite. If
+                           this is not the case, the function returns <tt>false</tt>.
+                           
+        <DT>"QR"<DD> (default) Compute the solution by means of QR decomposition.  The 
+                           coefficient matrix \a A can be square or rectangular. In the latter case,
+                           it must have more rows than columns, and the solution will be computed in the 
+                           least squares sense. If \a A doesn't have full rank, the function 
+                           returns <tt>false</tt>.
+
+        <DT>"SVD"<DD> Compute the solution by means of singular value decomposition.  The 
+                           coefficient matrix \a A can be square or rectangular. In the latter case,
+                           it must have more rows than columns, and the solution will be computed in the 
+                           least squares sense. If \a A doesn't have full rank, the function 
+                           returns <tt>false</tt>.
+
+        <DT>"NE"<DD> Compute the solution by means of the normal equations, i.e. by applying Cholesky
+                           decomposition to the equivalent problem <tt>A'*A*x = A'*b</tt>. This only makes sense
+                           when the equation is to be solved in the least squares sense, i.e. when \a A is a 
+                           rectangular matrix with more rows than columns. If \a A doesn't have full column rank, 
+                           the function returns <tt>false</tt>.
+        </DL>
+        
+        This function can be applied in-place, i.e. <tt>&b == &res</tt> or <tt>&A == &res</tt> are allowed
+        (provided they have the required shapes).
+
+        The following size requirements apply:
+        
+        \code
+        rowCount(r) == rowCount(b);
+        columnCount(r) == rowCount(x);
+        columnCount(b) == columnCount(x);
+        \endcode
+
+        <b>\#include</b> \<vigra/linear_solve.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+doxygen_overloaded_function(template <...> bool linearSolve)
+
+template <class T, class C1, class C2, class C3>
+bool linearSolve(MultiArrayView<2, T, C1> const & A, 
+                 MultiArrayView<2, T, C2> const & b,
+                 MultiArrayView<2, T, C3> res, 
+                 std::string method = "QR")
+{
+    const MultiArrayIndex n = columnCount(A);
+    const MultiArrayIndex m = rowCount(A);
+
+    vigra_precondition(n <= m,
+        "linearSolve(): Coefficient matrix A must have at least as many rows as columns.");
+    vigra_precondition(n == rowCount(res) && 
+                       m == rowCount(b) && columnCount(b) == columnCount(res),
+        "linearSolve(): matrix shape mismatch.");
+
+    method = tolower(method);
+    if(method == "cholesky")
+    {
+        vigra_precondition(columnCount(A) == rowCount(A),
+            "linearSolve(): Cholesky method requires square coefficient matrix.");
+        Matrix<T> L(A.shape());
+        if(!choleskyDecomposition(A, L))
+            return false; // false if A wasn't symmetric positive definite
+        choleskySolve(L, b, res);
+    }
+    else if(method == "qr")
+    {
+        return (MultiArrayIndex)linearSolveQR(A, b, res) == n;
+    }
+    else if(method == "ne")
+    {
+        return linearSolve(transpose(A)*A, transpose(A)*b, res, "Cholesky");
+    }
+    else if(method == "svd")
+    {
+        MultiArrayIndex rhsCount = columnCount(b);
+        Matrix<T> u(A.shape()), s(n, 1), v(n, n);
+
+        MultiArrayIndex rank = (MultiArrayIndex)singularValueDecomposition(A, u, s, v);
+
+        Matrix<T> t = transpose(u)*b;
+        for(MultiArrayIndex l=0; l<rhsCount; ++l)
+        {
+            for(MultiArrayIndex k=0; k<rank; ++k)
+                t(k,l) /= s(k,0);
+            for(MultiArrayIndex k=rank; k<n; ++k)
+                t(k,l) = NumericTraits<T>::zero();
+        }
+        res = v*t;
+
+        return (rank == n);
+    }
+    else
+    {
+        vigra_precondition(false, "linearSolve(): Unknown solution method.");
+    }
+    return true;
+}
+
+template <class T, class C1, int N>
+bool linearSolve(MultiArrayView<2, T, C1> const & A, 
+                 TinyVector<T, N> const & b,
+                 TinyVector<T, N> & res, 
+                 std::string method = "QR")
+{
+    Shape2 shape(N, 1);
+    return linearSolve(A, MultiArrayView<2, T>(shape, b.data()), MultiArrayView<2, T>(shape, res.data()), method);
+}
+
+//@}
+
+} // namespace linalg
+
+using linalg::inverse;
+using linalg::determinant;
+using linalg::logDeterminant;
+using linalg::linearSolve;
+using linalg::choleskySolve;
+using linalg::choleskyDecomposition;
+using linalg::qrDecomposition;
+using linalg::linearSolveUpperTriangular;
+using linalg::linearSolveLowerTriangular;
+
+} // namespace vigra
+
+
+#endif // VIGRA_LINEAR_SOLVE_HXX
diff --git a/include/vigra/localminmax.hxx b/include/vigra/localminmax.hxx
new file mode 100644
index 0000000..f8515a8
--- /dev/null
+++ b/include/vigra/localminmax.hxx
@@ -0,0 +1,2014 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2010 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_LOCALMINMAX_HXX
+#define VIGRA_LOCALMINMAX_HXX
+
+#include <vector>
+#include <functional>
+#include "utilities.hxx"
+#include "stdimage.hxx"
+#include "initimage.hxx"
+#include "labelimage.hxx"
+#include "labelvolume.hxx"
+#include "pixelneighborhood.hxx"
+#include "voxelneighborhood.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra
+{
+
+/** \addtogroup LocalMinMax Local Minima and Maxima
+
+    Detect local minima and maxima in a gray level image,
+    including extremal plateaus larger than 1 pixel
+*/
+//@{
+
+namespace detail {
+
+template <class SrcIterator, class SrcAccessor,
+          class Neighborhood,
+          class Compare>
+inline bool
+isLocalExtremum(SrcIterator is, SrcAccessor sa, Neighborhood,
+                typename SrcAccessor::value_type threshold,
+                Compare compare, AtImageBorder atBorder)
+{
+    typename SrcAccessor::value_type v = sa(is);
+    
+    if(!compare(v, threshold))
+        return false;
+
+    int directionCount = Neighborhood::nearBorderDirectionCount(atBorder);
+    RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood> sc(is, atBorder);
+    for(int i = 0; i < directionCount; ++i, ++sc)
+    {
+        if(!compare(v, sa(sc)))
+            return false;
+    }
+    return true;
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DestValue, class Neighborhood,
+          class Compare>
+void
+localMinMax(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da,
+            DestValue marker, Neighborhood neighborhood,
+            typename SrcAccessor::value_type threshold,
+            Compare compare,
+            bool allowExtremaAtBorder = false)
+{
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    int x, y;
+
+    if(allowExtremaAtBorder)
+    {
+        SrcIterator is = sul;
+        DestIterator id = dul;
+        
+        for(x=0; x<w; ++x, ++is.x, ++id.x)
+        {
+            if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 
+                                isAtImageBorder(x, 0, w, h)))
+                da.set(marker, id);
+        }
+        
+        is = sul + Diff2D(0,1);
+        id = dul + Diff2D(0,1);
+        
+        for(y=1; y<h-1; ++y, ++is.y, ++id.y)
+        {
+            if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 
+                                isAtImageBorder(0, y, w, h)))
+                da.set(marker, id);
+        }
+        
+        is = sul + Diff2D(w-1,1);
+        id = dul + Diff2D(w-1,1);
+        
+        for(y=1; y<h-1; ++y, ++is.y, ++id.y)
+        {
+            if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 
+                                isAtImageBorder(w-1, y, w, h)))
+                da.set(marker, id);
+        }
+        
+        is = sul + Diff2D(0,h-1);
+        id = dul + Diff2D(0,h-1);
+        
+        for(x=0; x<w; ++x, ++is.x, ++id.x)
+        {
+            if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 
+                                isAtImageBorder(x, h-1, w, h)))
+                da.set(marker, id);
+        }
+    }
+
+    w -= 2;
+    h -= 2;
+    sul += Diff2D(1,1);
+    dul += Diff2D(1,1);
+
+    for(y=0; y<h; ++y, ++sul.y, ++dul.y)
+    {
+        SrcIterator  sx = sul;
+        DestIterator dx = dul;
+
+        for(x=0; x<w; ++x, ++sx.x, ++dx.x)
+        {
+            typename SrcAccessor::value_type v = sa(sx);
+            
+            if(!compare(v, threshold))
+                continue;
+
+            int i;
+            NeighborhoodCirculator<SrcIterator, Neighborhood> sc(sx);
+            for(i = 0; i < Neighborhood::DirectionCount; ++i, ++sc)
+            {
+                if(!compare(v, sa(sc)))
+                    break;
+            }
+            
+            if(i == Neighborhood::DirectionCount)
+                da.set(marker, dx);
+        }
+    }
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+        class DestIterator, class DestAccessor, class DestValue,
+        class Neighborhood, class Compare>
+void 
+localMinMax3D(SrcIterator sul, SrcShape shp, SrcAccessor sa, 
+              DestIterator dul, DestAccessor da,
+              DestValue marker,
+              Neighborhood neighborhood,
+              typename SrcAccessor::value_type threshold,
+              Compare compare,
+              bool allowExtremaAtBorder = false)
+{
+    int w = shp[0];
+    int h = shp[1];
+    int d = shp[2];
+
+    int x, y, z;
+
+    if (allowExtremaAtBorder)
+    {
+        throw std::runtime_error("Not implemented (use localMinima() or localMaxima() instead).");
+    }
+
+    w -= 2;
+    h -= 2;
+    d -= 2;
+    sul.dim0() += 1;
+    sul.dim1() += 1;
+    sul.dim2() += 1;
+    dul += Diff3D(1, 1, 1);
+
+    SrcIterator zs = sul;
+    DestIterator zd = dul;
+
+    for (z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
+    {
+        SrcIterator ys(zs);
+        DestIterator yd(zd);
+
+        for (y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
+        {
+            SrcIterator xs(ys);
+            DestIterator xd(yd);
+
+            for (x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
+            {
+
+                typename SrcAccessor::value_type v = sa(xs);
+                if (!compare(v, threshold))
+                    continue;
+
+                int i;
+                NeighborhoodCirculator<SrcIterator, Neighborhood> sc(xs);
+                for (i = 0; i < Neighborhood::DirectionCount; ++i, ++sc)
+                {
+                    if(!compare(v, sa(sc)))
+                        break;
+                }
+
+                if(i == Neighborhood::DirectionCount)
+                    da.set(marker, xd);
+            }
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, class DestValue,
+          class Neighborhood, class Compare, class Equal>
+void
+extendedLocalMinMax(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+                    DestIterator dul, DestAccessor da, DestValue marker,
+                    Neighborhood /*neighborhood*/,
+                    Compare compare, Equal equal, 
+                    typename SrcAccessor::value_type threshold,
+                    bool allowExtremaAtBorder = false)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    int i,x,y;
+
+    BasicImage<int> labels(w,h);
+
+    int number_of_regions =
+        labelImage(sul, slr, sa, labels.upperLeft(), labels.accessor(),
+                   (Neighborhood::DirectionCount == 8), equal);
+
+    // assume that a region is a extremum until the opposite is proved
+    std::vector<unsigned char> isExtremum(number_of_regions+1, (unsigned char)1);
+
+    BasicImage<int>::traverser ly = labels.upperLeft();
+
+    for(y=0; y<h; ++y, ++sul.y, ++ly.y)
+    {
+        SrcIterator  sx = sul;
+        BasicImage<int>::traverser lx(ly);
+
+        for(x=0; x<w; ++x, ++sx.x, ++lx.x)
+        {
+            int lab = *lx;
+            SrcType v = sa(sx);
+            
+            if(isExtremum[lab] == 0)
+                continue;
+                
+            if(!compare(v, threshold))
+            {
+                // mark all regions that don't exceed the threshold as non-extremum
+                isExtremum[lab] = 0;
+                continue;
+            }
+
+            AtImageBorder atBorder = isAtImageBorder(x, y, w, h);
+            if(atBorder == NotAtBorder)
+            {
+                NeighborhoodCirculator<SrcIterator, Neighborhood> sc(sx);
+                NeighborhoodCirculator<BasicImage<int>::traverser, Neighborhood> lc(lx);
+                for(i=0; i<Neighborhood::DirectionCount; ++i, ++sc, ++lc)
+                {
+                    if(lab != *lc && compare(sa(sc),v))
+                    {
+                        isExtremum[lab] = 0;
+                        break;
+                    }
+                }
+            }
+            else
+            {
+                if(allowExtremaAtBorder)
+                {
+                    RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood> 
+                                                               sc(sx, atBorder), scend(sc);
+                    do
+                    {
+                        if(lab != *(lx+sc.diff()) && compare(sa(sc),v))
+                        {
+                            isExtremum[lab] = 0;
+                            break;
+                        }
+                    }
+                    while(++sc != scend);
+                }
+                else
+                {
+                    isExtremum[lab] = 0;
+                }
+            }
+        }
+    }
+
+    ly = labels.upperLeft();
+    for(y=0; y<h; ++y, ++dul.y, ++ly.y)
+    {
+        DestIterator  xd = dul;
+        BasicImage<int>::Iterator lx(ly);
+
+        for(x=0; x<w; ++x, ++xd.x, ++lx.x)
+        {
+            if(isExtremum[*lx])
+                da.set(marker, xd);
+        }
+    }
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+        class DestIterator, class DestAccessor, class DestValue,
+        class Neighborhood, class Compare, class Equal>
+void 
+extendedLocalMinMax3D(SrcIterator sul, SrcShape shp, SrcAccessor sa,
+                      DestIterator dul, DestAccessor da,
+                      DestValue marker,
+                      Neighborhood neighbourhood,
+                      Compare compare,
+                      Equal equal,
+                      typename SrcAccessor::value_type threshold,
+                      bool allowExtremaAtBorder = false)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    int w = shp[0];
+    int h = shp[1];
+    int d = shp[2];
+
+    int i, x, y, z;
+
+    MultiArray<3, int> labels(shp);
+
+    int number_of_regions =
+        labelVolume(sul, shp, sa, labels.traverser_begin(), 
+                    typename AccessorTraits<int>::default_accessor(),
+                    neighbourhood);
+    
+    MultiArray<3, int>::traverser zl(labels.traverser_begin());
+
+    SrcIterator zs = sul;
+    DestIterator zd = dul;
+
+    // assume that a region is a extremum until the opposite is proved
+    std::vector<unsigned char> isExtremum(number_of_regions + 1, (unsigned char)1);
+
+    for (z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2(), ++zl.dim2())
+    {
+        SrcIterator ys(zs);
+        DestIterator yd(zd);
+        MultiArray<3, int>::traverser yl(zl);
+
+        for (y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1(), ++yl.dim1())
+        {
+            SrcIterator xs(ys);
+            DestIterator xd(yd);
+            MultiArray<3, int>::traverser xl(yl);
+
+            for (x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0(), ++xl.dim0())
+            {
+
+                int lab = *xl;
+                SrcType v = sa(xs);
+
+                if (isExtremum[lab] == 0)
+                    continue;
+
+                if (!compare(v, threshold))
+                {
+                    // mark all regions that don't exceed the threshold as non-extremum
+                    isExtremum[lab] = 0;
+                    continue;
+                }
+
+                AtVolumeBorder atBorder = isAtVolumeBorder(x, y, z, w, h, d);
+                if (atBorder == NotAtBorder)
+                {
+                    NeighborhoodCirculator<SrcIterator, Neighborhood> sc(xs);
+                    NeighborhoodCirculator<MultiArray<3, int>::traverser, Neighborhood> lc(xl);
+                    for (i = 0; i < Neighborhood::DirectionCount; ++i, ++sc, ++lc)
+                    {
+                        if (lab != *lc && compare(sa(sc), v))
+                        {
+
+                            isExtremum[lab] = 0;
+                            break;
+                        }
+                    }
+                }
+                else
+                {
+                    if (allowExtremaAtBorder)
+                    {
+                        RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood>
+                        sc(xs, atBorder), scend(sc);
+                        do
+                        {
+                            if (lab != *(xl + sc.diff()) && compare(sa(sc), v))
+                            {
+                                isExtremum[lab] = 0;
+                                break;
+                            }
+                        } 
+                        while (++sc != scend);
+                    }
+                    else
+                    {
+                        isExtremum[lab] = 0;
+                    }
+                }
+            }
+        }
+    }
+
+    zl = labels.traverser_begin();
+    zs = sul;
+    zd = dul;
+
+    for (z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2(), ++zl.dim2())
+    {
+        SrcIterator ys(zs);
+        DestIterator yd(zd);
+        MultiArray<3, int>::traverser yl(zl);
+
+        for (y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1(), ++yl.dim1())
+        {
+            SrcIterator xs(ys);
+            DestIterator xd(yd);
+            MultiArray<3, int>::traverser xl(yl);
+
+            for (x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0(), ++xl.dim0())
+            {
+                if(isExtremum[*xl])
+                    da.set(marker, xd);
+            }
+        }
+    }
+}
+
+} // namespace detail
+
+
+/** \brief Options object for localMinima() and localMaxima().
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/localminmax.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    MultiArray<2, unsigned char> src(w,h), minima(w,h);
+    ... // fill src
+
+    // use 4-neighborhood, allow minima at the image border, 
+    // and discard those where the gray value is not below 5
+    localMinima(src, minima,
+                LocalMinmaxOptions().neighborhood(4).allowAtBorder().threshold(5));
+
+    \endcode
+*/
+class LocalMinmaxOptions
+{
+  public:
+    double marker, thresh;
+    int neigh;
+    bool use_threshold, allow_at_border, allow_plateaus;
+    
+        /**\brief Construct default options object.
+         *
+            Defaults are: marker value '1', no threshold, indirect neighborhood, 
+                          don't allow extrema at border and extremal plateaus.
+         */
+    LocalMinmaxOptions()
+    : marker(1.0), 
+      thresh(0.0),
+      neigh(1),
+      use_threshold(false),
+      allow_at_border(false),
+      allow_plateaus(false)
+    {}
+    
+        /**\brief Use the given neighborhood. 
+        
+            The value '0' indicates direct neighborhood (i.e. 4-neighborhood 
+            in 2D, 6-neighborhood in 3D, 2*N neighborhood in N-D), the value '1'
+            indicates indirect neighborhood (i.e. 8-neighborhood in 2D, 
+            26-neighborhood in 3D, 3<sup>N</sup>-1 neighborhood in N-D). The appropriate 
+            number of neighbors for the desired dimension and the constants
+            <tt>DirectNeighborhood</tt> and <tt>IndirectNeighborhood</tt> can be used as well.
+        
+            Default: 1 (indirect neighborhood)
+         */
+    LocalMinmaxOptions & neighborhood(unsigned int n)
+    {
+        neigh = n;
+        return *this;
+    }
+    
+    LocalMinmaxOptions & neighborhood(NeighborhoodType n)
+    {
+        neigh = n;
+        return *this;
+    }
+    
+        /**\brief Mark extrema in the destination image with the given value.
+        
+            Default: 1
+         */
+    LocalMinmaxOptions & markWith(double m)
+    {
+        marker = m;
+        return *this;
+    }
+    
+        /**\brief Threshold the extrema.
+        
+           Discard minima whose gray value is not below the threshold.
+           and maxima whose gray level is not above the threshold.
+        
+            Default: don't threshold (i.e. return all extrema)
+         */
+    LocalMinmaxOptions & threshold(double t)
+    {
+        use_threshold = true;
+        thresh = t;
+        return *this;
+    }
+    
+        /**\brief Detect extrema at the image border.
+        
+            Default: false
+         */
+    LocalMinmaxOptions & allowAtBorder(bool f = true)
+    {
+        allow_at_border = f;
+        return *this;
+    }
+    
+        /**\brief Allow extremal plateaus.
+        
+            That is regions of constant gray value whose neighbors are all
+            higher (minima) or lower than the value of the region.
+        
+            Default: false
+         */
+    LocalMinmaxOptions & allowPlateaus(bool f = true)
+    {
+        allow_plateaus = f;
+        return *this;
+    }
+};
+
+
+/********************************************************/
+/*                                                      */
+/*                       localMinima                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find local minima in an image or multi-dimensional array.
+
+    By default, minima are defined as points which are not 
+    at the array border and whose value is lower than the value 
+    of all indirect neighbors (i.e. 8-neighbors in 2D, 
+    26-neighbors in 3D, 3<sup>N</sup>-1 neighbors in N-D). 
+    The detected points will be marked 
+    with the default value 1 in the destination array.
+    
+    The defaults can be overridden in various ways by providing 
+    \ref LocalMinmaxOptions : you can switch to the direct neighborhood
+    (i.e. 4-neighborhood in 2D, 6-neighborhood in 3D, 2*N neighborhood 
+    in N-D), allow minima at the border, discard minima where the function 
+    value is not below a given threshold, allow extended minima
+    (i.e. minima that form minimal plateaus rather than isolated pixels --
+    note that this option is only supported for 2D images), 
+    and change the marker in the destination image. See usage examples below 
+    for details. 
+    
+    There are also variants of the localMinima() function where parameters
+    are passed explicitly rather than via an option object. These versions
+    of the function are deprecated, but will be kept for compatibility.
+
+    <b> Declarations:</b>
+
+    use arbitrary-dimensional arrays:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class C1, class T2, class C2>
+        void
+        localMinima(MultiArrayView<N, T1, C1> src,
+                    MultiArrayView<N, T2, C2> dest,
+                    LocalMinmaxOptions const & options = LocalMinmaxOptions());
+    }
+    \endcode
+
+    \deprecatedAPI{localMinima}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+                    DestIterator dul, DestAccessor da,
+                    LocalMinmaxOptions const & options = LocalMinmaxOptions());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    pair<DestIterator, DestAccessor> dest,
+                    LocalMinmaxOptions const & options = LocalMinmaxOptions());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/localminmax.hxx\><br>
+    <b>\#include</b> \<vigra/multi_localminmax.hxx\><br>
+    Namespace: vigra
+
+    \code
+    // 3D examples (other dimensions work likewise)
+    Shape3 shape(w,h,d);
+    MultiArray<3, unsigned char> src(shape), minima(shape);
+    ... // fill src
+
+    // use default parameterisation
+    localMinima(src, minima);
+
+    // reset destination image
+    minima = 0;
+
+    // use direct neighborhood (i.e. 6-neighborhood since we are in 3D) 
+    // and allow minima at the image border
+    localMinima(src, minima,
+                LocalMinmaxOptions().neighborhood(0).allowAtBorder());
+    \endcode
+
+    \deprecatedUsage{localMinima}
+    \code
+    // 2D examples using BasicImage
+    BImage src(w,h), minima(w,h);
+    ... // fill src
+
+    // use default parameterisation
+    localMinima(srcImageRange(src), destImage(minima));
+
+    // reset destination image
+    minima = 0;
+
+    // use 4-neighborhood and allow minima at the image border
+    localMinima(srcImageRange(src), destImage(minima),
+                       LocalMinmaxOptions().neighborhood(4).allowAtBorder());
+
+    // reset destination image
+    minima = 0;
+
+    // allow extended minima (minimal plateaus) and use value '255' as a marker
+    localMinima(srcImageRange(src), destImage(minima),
+                       LocalMinmaxOptions().allowPlateaus().markWith(255));
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator src_upperleft, src_lowerright;
+    DestIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+
+    u < u
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void localMinima)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da,
+            LocalMinmaxOptions const & options = LocalMinmaxOptions())
+{
+    typedef typename SrcAccessor::value_type SrcType;
+    typedef typename DestAccessor::value_type DestType;
+    
+    SrcType threshold = options.use_threshold
+                           ? std::min(NumericTraits<SrcType>::max(), (SrcType)options.thresh)
+                           : NumericTraits<SrcType>::max();
+    DestType marker = (DestType)options.marker;
+    
+    if(options.allow_plateaus)
+    {
+        if(options.neigh == 0 || options.neigh == 4)
+        {
+            detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(),
+                                        std::less<SrcType>(), std::equal_to<SrcType>(), 
+                                        threshold, options.allow_at_border);
+        }
+        else if(options.neigh == 1 || options.neigh == 8)
+        {
+            detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(),
+                                        std::less<SrcType>(), std::equal_to<SrcType>(), 
+                                        threshold, options.allow_at_border);
+        }
+        else
+            vigra_precondition(false, "localMinima(): neighborhood must be 4 or 8.");
+
+    }
+    else
+    {
+        if(options.neigh == 0 || options.neigh == 4)
+        {
+            detail::localMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(),
+                                threshold, std::less<SrcType>(), options.allow_at_border);
+        }
+        else if(options.neigh == 1 || options.neigh == 8)
+        {
+            detail::localMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(),
+                                threshold, std::less<SrcType>(), options.allow_at_border);
+        }
+        else
+            vigra_precondition(false, "localMinima(): neighborhood must be 4 or 8.");
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DestValue>
+inline void
+localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da,
+            DestValue marker, FourNeighborCode neighborhood)
+{
+    detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood,
+                        NumericTraits<typename SrcAccessor::value_type>::max(),
+                        std::less<typename SrcAccessor::value_type>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DestValue>
+inline void
+localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da,
+            DestValue marker, EightNeighborCode neighborhood)
+{
+    detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood,
+                        NumericTraits<typename SrcAccessor::value_type>::max(),
+                        std::less<typename SrcAccessor::value_type>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, class DestValue>
+inline void
+localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da,
+            DestValue marker)
+{
+    localMinima(sul, slr, sa, dul, da, marker, EightNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DestValue>
+inline void
+localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            DestValue marker, FourNeighborCode neighborhood)
+{
+    localMinima(src.first, src.second, src.third,
+                dest.first, dest.second, marker, neighborhood);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DestValue>
+inline void
+localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            DestValue marker, EightNeighborCode neighborhood)
+{
+    localMinima(src.first, src.second, src.third,
+                dest.first, dest.second, marker, neighborhood);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, class DestValue>
+inline void
+localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            DestValue marker)
+{
+    localMinima(src.first, src.second, src.third,
+                dest.first, dest.second, marker, EightNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            LocalMinmaxOptions const & options = LocalMinmaxOptions())
+{
+    localMinima(src.first, src.second, src.third,
+                dest.first, dest.second, options);
+}
+
+/**************************************************************************/
+
+/********************************************************/
+/*                                                      */
+/*                       localMinima3D                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find local minima in a 3D multi array.
+
+    Deprecated, use localMinima() instead.
+
+ */
+doxygen_overloaded_function(template <...> void localMinima3D)
+
+template<class SrcIterator, class SrcAccessor, class SrcShape,
+         class DestIterator, class DestAccessor, class DestValue>
+inline void 
+localMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+              DestIterator dul, DestAccessor da,
+              DestValue marker,
+              NeighborCode3DTwentySix neighborhood)
+{
+    detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
+                NumericTraits<typename SrcAccessor::value_type>::max(),
+                std::less<typename SrcAccessor::value_type>());
+}
+
+template<class SrcIterator, class SrcAccessor, class SrcShape,
+         class DestIterator, class DestAccessor, class DestValue>
+inline void 
+localMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+              DestIterator dul, DestAccessor da,
+              DestValue marker,
+              NeighborCode3DSix neighborhood)
+{
+    detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
+                NumericTraits<typename SrcAccessor::value_type>::max(),
+                std::less<typename SrcAccessor::value_type>());
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class DestValue>
+inline void 
+localMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+              DestIterator dul, DestAccessor da,
+              DestValue marker)
+{
+    localMinima3D(sul, slr, sa, dul, da, marker, NeighborCode3DSix());
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class DestValue>
+inline void 
+localMinima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
+              pair<DestIterator, DestAccessor> dest,
+              DestValue marker,
+              NeighborCode3DSix neighborhood)
+{
+    localMinima3D(src.first, src.second, src.third, dest.first, dest.second,
+                  marker, neighborhood);
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class DestValue>
+inline void
+localMinima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
+              pair<DestIterator, DestAccessor> dest,
+              DestValue marker,
+              NeighborCode3DTwentySix neighborhood)
+{
+    localMinima3D(src.first, src.second, src.third, dest.first, dest.second,
+                  marker, neighborhood);
+}
+
+template<class T1, class S1,
+         class T2, class S2,
+         class DestValue,
+         class Neighborhood>
+inline void 
+localMinima3D(MultiArrayView<3, T1, S1> const & src,
+              MultiArrayView<3, T2, S2> dest,
+              DestValue marker,
+              Neighborhood neighborhood)
+{
+    localMinima3D(srcMultiArrayRange(src), destMultiArray(dest),
+                  marker, neighborhood);
+}
+
+template<class T1, class S1,
+         class T2, class S2,
+         class DestValue>
+inline void
+localMinima3D(MultiArrayView<2, T1, S1> const & src,
+              MultiArrayView<2, T2, S2> dest,
+              DestValue marker)
+{
+    localMinima3D(srcMultiArrayRange(src), destMultiArray(dest),
+                  marker, NeighborCode3DSix());
+}
+
+/**************************************************************************/
+
+/********************************************************/
+/*                                                      */
+/*                       localMaxima                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find local maxima in an image or multi-dimensional array.
+
+    By default, maxima are defined as points which are not 
+    at the array border and whose value is higher than the value 
+    of all indirect neighbors (i.e. 8-neighbors in 2D, 
+    26-neighbors in 3D, 3<sup>N</sup>-1 neighbors in N-D). 
+    The detected points will be marked 
+    with the default value 1 in the destination array.
+    
+    The defaults can be overridden in various ways by providing 
+    \ref LocalMinmaxOptions : you can switch to the direct neighborhood
+    (i.e. 4-neighborhood in 2D, 6-neighborhood in 3D, 2*N neighborhood 
+    in N-D), allow maxima at the border, discard maxima where the function 
+    value is not above a given threshold, allow extended maxima
+    (i.e. maxima that form maximal plateaus rather than isolated pixels --
+    note that this option is only supported for 2D images), 
+    and change the marker in the destination image. See usage examples below 
+    for details. 
+    
+    There are also variants of the localMaxima() function where parameters
+    are passed explicitly rather than via an option object. These versions
+    of the function are deprecated, but will be kept for compatibility.
+
+    <b> Declarations:</b>
+
+    use arbitrary-dimensional arrays:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class C1, class T2, class C2>
+        void
+        localMaxima(MultiArrayView<N, T1, C1> src,
+                    MultiArrayView<N, T2, C2> dest,
+                    LocalMinmaxOptions const & options = LocalMinmaxOptions());
+    }
+    \endcode
+
+    \deprecatedAPI{localMaxima}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+                    DestIterator dul, DestAccessor da,
+                    LocalMinmaxOptions const & options = LocalMinmaxOptions());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    pair<DestIterator, DestAccessor> dest,
+                    LocalMinmaxOptions const & options = LocalMinmaxOptions());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/localminmax.hxx\><br>
+    <b>\#include</b> \<vigra/multi_localminmax.hxx\><br>
+    Namespace: vigra
+
+    \code
+    // 3D examples (other dimensions work likewise)
+    Shape3 shape(w,h,d);
+    MultiArray<3, unsigned char> src(shape), maxima(shape);
+    ... // fill src
+
+    // use default parameterisation
+    localMaxima(src, maxima);
+
+    // reset destination image
+    maxima = 0;
+
+    // use direct neighborhood (i.e. 6-neighborhood sine we are in 3D)
+    // and allow maxima at the image border
+    localMaxima(src, maxima,
+                LocalMinmaxOptions().neighborhood(0).allowAtBorder());
+    \endcode
+
+    \deprecatedUsage{localMaxima}
+    \code
+    // 2D examples using BasicImage
+    BImage src(w,h), maxima(w,h);
+    ... // fill src
+
+    // use default parameterisation
+    localMaxima(srcImageRange(src), destImage(maxima));
+
+    // reset destination image
+    maxima = 0;
+
+    // use 4-neighborhood and allow maxima at the image border
+    localMaxima(srcImageRange(src), destImage(maxima),
+                       LocalMinmaxOptions().neighborhood(4).allowAtBorder());
+
+    // reset destination image
+    maxima = 0;
+
+    // allow extended maxima (maximal plateaus) and use value '255' as a marker
+    localMaxima(srcImageRange(src), destImage(maxima),
+                       LocalMinmaxOptions().allowPlateaus().markWith(255));
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator src_upperleft, src_lowerright;
+    DestIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+
+    u < u
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void localMaxima)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da,
+            LocalMinmaxOptions const & options = LocalMinmaxOptions())
+{
+    typedef typename SrcAccessor::value_type SrcType;
+    typedef typename DestAccessor::value_type DestType;
+    
+    SrcType threshold = options.use_threshold
+                           ? std::max(NumericTraits<SrcType>::min(), (SrcType)options.thresh)
+                           : NumericTraits<SrcType>::min();
+    DestType marker = (DestType)options.marker;
+    
+    if(options.allow_plateaus)
+    {
+        if(options.neigh == 0 || options.neigh == 4)
+        {
+            detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(),
+                                        std::greater<SrcType>(), std::equal_to<SrcType>(), 
+                                        threshold, options.allow_at_border);
+        }
+        else if(options.neigh == 1 || options.neigh == 8)
+        {
+            detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(),
+                                        std::greater<SrcType>(), std::equal_to<SrcType>(), 
+                                        threshold, options.allow_at_border);
+        }
+        else
+            vigra_precondition(false, "localMaxima(): neighborhood must be 4 or 8.");
+    }
+    else
+    {
+        if(options.neigh == 0 || options.neigh == 4)
+        {
+            detail::localMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(),
+                                threshold, std::greater<SrcType>(), options.allow_at_border);
+        }
+        else if(options.neigh == 1 || options.neigh == 8)
+        {
+            detail::localMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(),
+                                threshold, std::greater<SrcType>(), options.allow_at_border);
+        }
+        else
+            vigra_precondition(false, "localMaxima(): neighborhood must be 4 or 8.");
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DestValue>
+inline void
+localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da,
+            DestValue marker, FourNeighborCode neighborhood)
+{
+    detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood,
+                        NumericTraits<typename SrcAccessor::value_type>::min(),
+                        std::greater<typename SrcAccessor::value_type>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DestValue>
+inline void
+localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da,
+            DestValue marker, EightNeighborCode neighborhood)
+{
+    detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood,
+                        NumericTraits<typename SrcAccessor::value_type>::min(),
+                        std::greater<typename SrcAccessor::value_type>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, class DestValue>
+inline void
+localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da,
+            DestValue marker)
+{
+    localMaxima(sul, slr, sa, dul, da, marker, EightNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DestValue>
+inline void
+localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            DestValue marker, FourNeighborCode neighborhood)
+{
+    localMaxima(src.first, src.second, src.third,
+                dest.first, dest.second, marker, neighborhood);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DestValue>
+inline void
+localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            DestValue marker, EightNeighborCode neighborhood)
+{
+    localMaxima(src.first, src.second, src.third,
+                dest.first, dest.second, marker, neighborhood);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, class DestValue>
+inline void
+localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            DestValue marker)
+{
+    localMaxima(src.first, src.second, src.third,
+                dest.first, dest.second, marker, EightNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            LocalMinmaxOptions const & options = LocalMinmaxOptions())
+{
+    localMaxima(src.first, src.second, src.third,
+                dest.first, dest.second, options);
+}
+
+/**************************************************************************/
+
+/********************************************************/
+/*                                                      */
+/*                       localMaxima3D                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find local maxima in a 3D multi array.
+
+    Deprecated, use \ref localMaxima() instead.
+ */
+doxygen_overloaded_function(template <...> void localMaxima3D)
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class DestValue>
+inline void 
+localMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+              DestIterator dul, DestAccessor da,
+              DestValue marker,
+              NeighborCode3DSix neighborhood)
+{
+    detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
+                NumericTraits<typename SrcAccessor::value_type>::min(),
+                std::greater<typename SrcAccessor::value_type>());
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class DestValue>
+inline void 
+localMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+              DestIterator dul, DestAccessor da,
+              DestValue marker,
+              NeighborCode3DTwentySix neighborhood)
+{
+    detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
+                NumericTraits<typename SrcAccessor::value_type>::min(),
+                std::greater<typename SrcAccessor::value_type>());
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class DestValue>
+inline void 
+localMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
+              pair<DestIterator, DestAccessor> dest,
+              DestValue marker,
+              NeighborCode3DTwentySix neighborhood)
+{
+    localMaxima3D(src.first, src.second, src.third, dest.first, dest.second,
+                marker, neighborhood);
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class DestValue>
+inline void 
+localMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
+              pair<DestIterator, DestAccessor> dest,
+              DestValue marker)
+{
+    localMaxima3D(src.first, src.second, src.third, dest.first, dest.second,
+                marker, NeighborCode3DSix());
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class DestValue>
+inline void 
+localMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
+              pair<DestIterator, DestAccessor> dest,
+              DestValue marker,
+              NeighborCode3DSix neighborhood)
+{
+    localMaxima3D(src.first, src.second, src.third, dest.first, dest.second,
+                marker, neighborhood);
+}
+
+template<class T1, class S1,
+         class T2, class S2,
+         class DestValue,
+         class Neighborhood>
+inline void 
+localMaxima3D(MultiArrayView<3, T1, S1> const & src,
+              MultiArrayView<3, T2, S2> dest,
+              DestValue marker,
+              Neighborhood neighborhood)
+{
+    localMaxima3D(srcMultiArrayRange(src), destMultiArray(dest),
+                  marker, neighborhood);
+}
+
+template<class T1, class S1,
+         class T2, class S2,
+         class DestValue>
+inline void 
+localMaxima3D(MultiArrayView<3, T1, S1> const & src,
+              MultiArrayView<3, T2, S2> dest,
+              DestValue marker)
+{
+    localMaxima3D(srcMultiArrayRange(src), destMultiArray(dest),
+                  marker, NeighborCode3DSix());
+}
+
+
+/**************************************************************************/
+
+/********************************************************/
+/*                                                      */
+/*                 extendedLocalMinima                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find local minimal regions (plateaus) in an array.
+
+    This function is only needed when you want to pass a non-standard equality
+    predicate via <tt>EqualityFunctor</tt>. Otherwise (i.e. when equality
+    is defined by the '==' operator of the source value type <tt>T1</tt>),
+    you can simply call \ref localMinima() with the option 
+    <tt>LocalMinmaxOptions::allowPlateaus()</tt>.
+    
+    This function finds regions of uniform pixel values
+    whose neighboring regions all have larger values, i.e. it finds minimal 
+    plateaus of arbitrary size (including size 1). The <tt>EqualityFunctor</tt>
+    determines when pixels are considered equal, so that one can allow 
+    for plateaus that are not quite constant (this is often necessary 
+    with float pixel values). Otherwise, the functionality is identical to 
+    \ref localMinima().
+
+    <b> Declarations:</b>
+
+    use arbitrary-dimensional arrays:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2,
+                  class EqualityFunctor>
+        unsigned int
+        extendedLocalMinima(MultiArrayView<N, T1, S1> const & src,
+                            MultiArrayView<N, T2, S2> dest,
+                            EqualityFunctor const & equal,
+                            LocalMinmaxOptions options = LocalMinmaxOptions());
+    \endcode
+
+    \deprecatedAPI{extendedLocalMinima}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class DestValue = DestAccessor::value_type,
+                  class Neighborhood = EightNeighborCode,
+                  class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
+        void
+        extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+                            DestIterator dul, DestAccessor da,
+                            DestValue marker = NumericTraits<DestValue>::one(),
+                            Neighborhood neighborhood = EightNeighborCode(),
+                            EqualityFunctor equal = EqualityFunctor());
+                            
+        template<class SrcIterator, class SrcShape, class SrcAccessor,
+                 class DestIterator, class DestAccessor,
+                 class Neighborhood = NeighborCode3DSix,
+                 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
+        void 
+        extendedLocalMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+                              DestIterator dul, DestAccessor da,
+                              typename DestAccessor::value_type marker,
+                              Neighborhood neighborhood = Neighborhood(),
+                              EqualityFunctor equal = EqualityFunctor());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class DestValue = DestAccessor::value_type,
+                  class Neighborhood = EightNeighborCode,
+                  class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
+        void
+        extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<DestIterator, DestAccessor> dest,
+                            DestValue marker = NumericTraits<DestValue>::one(),
+                            Neighborhood neighborhood = EightNeighborCode(),
+                            EqualityFunctor equal = EqualityFunctor());
+                            
+        template<class SrcIterator, class SrcAccessor, class SrcShape,
+                 class DestIterator, class DestAccessor, 
+                 class Neighborhood>
+        void 
+        extendedLocalMinima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                              pair<DestIterator, DestAccessor> dest,
+                              typename DestAccessor::value_type marker,
+                              Neighborhood neighborhood);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/localminmax.hxx\><br>
+    Namespace: vigra
+
+    \code
+    // define an equality functor
+    template <class T>
+    struct EqualWithToleranceFunctor
+    {
+        EqualWithToleranceFunctor(T tolerance)
+        : t(tolerance)
+        {}
+
+        bool operator()(T l, T r) const
+        {
+            return abs(l-r) <= t;
+        }
+
+        T t;
+    };
+
+    MultiArray<2, unsigned char> src(w,h), minima(w,h);
+
+    // allow plateaus
+    localMinima(src, minima, LocalMinmaxOptions().allowPlateaus());
+
+    // reset result image
+    minima.init(0);
+    // allow plateaus with tolerance (grayvalues may differ by one)
+    extendedLocalMinima(src, minima, EqualWithToleranceFunctor<unsigned char>(1));
+    \endcode
+
+    \deprecatedUsage{extendedLocalMinima}
+    \code
+    // optional: define an equality functor
+    template <class T>
+    struct EqualWithToleranceFunctor
+    {
+        EqualWithToleranceFunctor(T tolerance)
+        : t(tolerance)
+        {}
+
+        bool operator()(T l, T r) const
+        {
+            return abs(l-r) <= t;
+        }
+
+        T t;
+    };
+
+    BImage src(w,h), minima(w,h);
+
+    // init destiniation image
+    minima.init(0);
+
+    extendedLocalMinima(srcImageRange(src), destImage(minima));
+
+    // allow plateaus with tolerance
+    minima.init(0);
+    extendedLocalMinima(srcImageRange(src), destImage(minima), 1.0,
+                               FourNeighborCode(),
+                               EqualWithToleranceFunctor<unsigned char>(1));
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+
+    EqualityFunctor equal;
+    u == u
+    equal(u, u);
+    u < u
+
+    DestValue marker;
+    dest_accessor.set(marker, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void extendedLocalMinima)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood, class EqualityFunctor>
+inline void
+extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da, 
+            typename DestAccessor::value_type marker,
+            Neighborhood neighborhood, EqualityFunctor equal)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    detail::extendedLocalMinMax(sul, slr, sa, dul, da,
+                                marker, neighborhood,
+                                std::less<SrcType>(), equal, 
+                                NumericTraits<typename SrcAccessor::value_type>::max());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+inline void
+extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da, 
+            typename DestAccessor::value_type marker,
+            Neighborhood neighborhood)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    extendedLocalMinima(sul, slr, sa, dul, da,
+                        marker, neighborhood, std::equal_to<SrcType>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da, 
+            typename DestAccessor::value_type marker)
+{
+    extendedLocalMinima(sul, slr, sa, dul, da,
+                        marker, EightNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da)
+{
+    extendedLocalMinima(sul, slr, sa, dul, da,
+                NumericTraits<typename DestAccessor::value_type>::one());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood, class EqualityFunctor>
+inline void
+extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            typename DestAccessor::value_type marker, Neighborhood neighborhood,
+            EqualityFunctor equal)
+{
+    extendedLocalMinima(src.first, src.second, src.third,
+                dest.first, dest.second, marker, neighborhood, equal);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+inline void
+extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            typename DestAccessor::value_type marker, Neighborhood neighborhood)
+{
+    extendedLocalMinima(src.first, src.second, src.third,
+                        dest.first, dest.second, marker, neighborhood);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            typename DestAccessor::value_type marker)
+{
+    extendedLocalMinima(src.first, src.second, src.third,
+                        dest.first, dest.second, marker, EightNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest)
+{
+    extendedLocalMinima(src.first, src.second, src.third,
+                        dest.first, dest.second);
+}
+
+/**************************************************************************/
+
+/********************************************************/
+/*                                                      */
+/*                 extendedLocalMinima3D                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find local minimal regions in a volume.
+
+    See \ref extendedLocalMinima().
+
+*/
+doxygen_overloaded_function(template <...> void extendedLocalMinima3D)
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class Neighborhood,
+         class EqualityFunctor>
+inline void 
+extendedLocalMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+                      DestIterator dul, DestAccessor da,
+                      typename DestAccessor::value_type marker,
+                      Neighborhood neighborhood,
+                      EqualityFunctor equal)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    detail::extendedLocalMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
+                std::less<SrcType>(), equal,
+                NumericTraits<typename SrcAccessor::value_type>::max());
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class Neighborhood>
+inline void 
+extendedLocalMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+                      DestIterator dul, DestAccessor da,
+                      typename DestAccessor::value_type marker,
+                      Neighborhood neighborhood)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    extendedLocalMinima3D(sul, slr, sa, dul, da, marker, neighborhood,
+                          std::equal_to<SrcType>());
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor>
+inline void 
+extendedLocalMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+                      DestIterator dul, DestAccessor da)
+{
+    extendedLocalMinima3D(sul, slr, sa, dul, da, 
+                          NumericTraits<typename DestAccessor::value_type>::one(),
+                          NeighborCode3DSix());
+}
+
+template<class SrcIterator, class SrcAccessor, class SrcShape,
+         class DestIterator, class DestAccessor, class Neighborhood>
+inline void 
+extendedLocalMinima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                      pair<DestIterator, DestAccessor> dest,
+                      typename DestAccessor::value_type marker,
+                      Neighborhood neighborhood)
+{
+    extendedLocalMinima3D(src.first, src.second, src.third, 
+                          dest.first, dest.second, 
+                          marker, neighborhood);
+}
+
+/**************************************************************************/
+
+/********************************************************/
+/*                                                      */
+/*                 extendedLocalMaxima                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find local maximal regions in an array.
+
+    This function is only needed when you want to pass a non-standard equality
+    predicate via <tt>EqualityFunctor</tt>. Otherwise (i.e. when equality
+    is defined by the '==' operator of the source value type <tt>T1</tt>),
+    you can simply call \ref localMaxima() with the option 
+    <tt>LocalMinmaxOptions::allowPlateaus()</tt>.
+    
+    This function finds regions of uniform pixel values
+    whose neighboring regions all have smaller values, i.e. it finds maximal 
+    plateaus of arbitrary size (including size 1). The <tt>EqualityFunctor</tt>
+    determines when pixels are considered equal, so that one can allow 
+    for plateaus that are not quite constant (this is often necessary 
+    with float pixel values). Otherwise, the functionality is identical to 
+    \ref localMaxima().
+
+    <b> Declarations:</b>
+
+    use arbitrary-dimensional arrays:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        unsigned int // return number of maxima
+        extendedLocalMaxima(MultiArrayView<N, T1, S1> const & src,
+                            MultiArrayView<N, T2, S2> dest,
+                            LocalMinmaxOptions options = LocalMinmaxOptions());
+    \endcode
+
+    \deprecatedAPI{extendedLocalMaxima}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class DestValue = DestAccessor::value_type,
+                  class Neighborhood = EightNeighborCode,
+                  class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
+        void
+        extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+                            DestIterator dul, DestAccessor da,
+                            DestValue marker = NumericTraits<DestValue>::one(),
+                            Neighborhood neighborhood = EightNeighborCode(),
+                            EqualityFunctor equal = EqualityFunctor())
+                            
+        template<class SrcIterator, class SrcShape, class SrcAccessor,
+                 class DestIterator, class DestAccessor,
+                 class Neighborhood = NeighborCode3DSix,
+                 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
+        void 
+        extendedLocalMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+                              DestIterator dul, DestAccessor da,
+                              typename DestAccessor::value_type marker,
+                              Neighborhood neighborhood = Neighborhood(),
+                              EqualityFunctor equal = EqualityFunctor());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class DestValue = DestAccessor::value_type,
+                  class Neighborhood = EightNeighborCode,
+                  class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> >
+        void
+        extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<DestIterator, DestAccessor> dest,
+                            DestValue marker = NumericTraits<DestValue>::one(),
+                            Neighborhood neighborhood = EightNeighborCode(),
+                            EqualityFunctor equal = EqualityFunctor())
+                            
+        template<class SrcIterator, class SrcAccessor, class SrcShape,
+                 class DestIterator, class DestAccessor, 
+                 class Neighborhood>
+        void 
+        extendedLocalMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                              pair<DestIterator, DestAccessor> dest,
+                              typename DestAccessor::value_type marker,
+                              Neighborhood neighborhood);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/localminmax.hxx\><br>
+    Namespace: vigra
+
+    \code
+    // define an equality functor
+    template <class T>
+    struct EqualWithToleranceFunctor
+    {
+        EqualWithToleranceFunctor(T tolerance)
+        : t(tolerance)
+        {}
+
+        bool operator()(T l, T r) const
+        {
+            return abs(l-r) <= t;
+        }
+
+        T t;
+    };
+
+    MultiArray<2, unsigned char> src(w,h), maxima(w,h);
+
+    // allow plateaus
+    localMaxima(src, maxima, LocalMinmaxOptions().allowPlateaus());
+
+    // reset result image
+    maxima.init(0);
+    // allow plateaus with tolerance (grayvalues may differ by one)
+    extendedLocalMaxima(src, maxima, EqualWithToleranceFunctor<unsigned char>(1));
+    \endcode
+
+    \deprecatedUsage{extendedLocalMaxima}
+    \code
+
+    // optional: define an equality functor
+    template <class T>
+    struct EqualWithToleranceFunctor
+    {
+        EqualWithToleranceFunctor(T tolerance)
+        : t(tolerance)
+        {}
+
+        bool operator()(T l, T r) const
+        {
+            return abs(l-r) <= t;
+        }
+
+        T t;
+    };
+
+    BImage src(w,h), maxima(w,h);
+
+    // init destiniation image
+    maxima.init(0);
+
+    extendedLocalMaxima(srcImageRange(src), destImage(maxima));
+
+    // allow plateaus with tolerance
+    maxima.init(0);
+    extendedLocalMaxima(srcImageRange(src), destImage(maxima), 1.0,
+                               FourNeighborCode(),
+                               EqualWithToleranceFunctor<unsigned char>(1));
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+
+    EqualityFunctor equal;
+    u == u
+    equal(u, u);
+    u < u
+
+    DestValue marker;
+    dest_accessor.set(marker, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void extendedLocalMaxima)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood, class EqualityFunctor>
+inline void
+extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da, 
+            typename DestAccessor::value_type marker,
+            Neighborhood neighborhood, EqualityFunctor equal)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    detail::extendedLocalMinMax(sul, slr, sa, dul, da,
+                                marker, neighborhood,
+                                std::greater<SrcType>(), equal, 
+                                NumericTraits<typename SrcAccessor::value_type>::min());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+inline void
+extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da, 
+            typename DestAccessor::value_type marker,
+            Neighborhood neighborhood)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    extendedLocalMaxima(sul, slr, sa, dul, da,
+                        marker, neighborhood, std::equal_to<SrcType>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da, 
+            typename DestAccessor::value_type marker)
+{
+    extendedLocalMaxima(sul, slr, sa, dul, da,
+                        marker, EightNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
+            DestIterator dul, DestAccessor da)
+{
+    extendedLocalMaxima(sul, slr, sa, dul, da,
+                NumericTraits<typename DestAccessor::value_type>::one());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood, class EqualityFunctor>
+inline void
+extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            typename DestAccessor::value_type marker, Neighborhood neighborhood,
+            EqualityFunctor equal)
+{
+    extendedLocalMaxima(src.first, src.second, src.third,
+                dest.first, dest.second, marker, neighborhood, equal);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+inline void
+extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            typename DestAccessor::value_type marker, Neighborhood neighborhood)
+{
+    extendedLocalMaxima(src.first, src.second, src.third,
+                        dest.first, dest.second, marker, neighborhood);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest,
+            typename DestAccessor::value_type marker)
+{
+    extendedLocalMaxima(src.first, src.second, src.third,
+                        dest.first, dest.second, marker, EightNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest)
+{
+    extendedLocalMaxima(src.first, src.second, src.third,
+                        dest.first, dest.second);
+}
+
+/********************************************************/
+/*                                                      */
+/*                 extendedLocalMaxima3D                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find local maximal regions in 3D multi array.
+
+    See \ref extendedLocalMaxima().
+ */
+
+doxygen_overloaded_function(template <...> void extendedLocalMaxima3D)
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class Neighborhood,
+         class EqualityFunctor>
+inline void 
+extendedLocalMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+                      DestIterator dul, DestAccessor da,
+                      typename DestAccessor::value_type marker,
+                      Neighborhood neighborhood,
+                      EqualityFunctor equal)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    detail::extendedLocalMinMax3D(sul, slr, sa, dul, da, marker, neighborhood,
+                                  std::greater<SrcType>(), equal, 
+                                  NumericTraits<typename SrcAccessor::value_type>::min());
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class Neighborhood>
+inline void 
+extendedLocalMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+                      DestIterator dul, DestAccessor da,
+                      typename DestAccessor::value_type marker,
+                      Neighborhood neighborhood)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    extendedLocalMaxima3D(sul, slr, sa, dul, da, 
+                          marker, neighborhood, 
+                          std::equal_to<SrcType>());
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor>
+inline void 
+extendedLocalMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa,
+                      DestIterator dul, DestAccessor da)
+{
+    extendedLocalMaxima3D(sul, slr, sa, dul, da, 
+                          NumericTraits<typename DestAccessor::value_type>::one(),
+                          NeighborCode3DSix());
+}
+
+template<class SrcIterator, class SrcShape, class SrcAccessor,
+         class DestIterator, class DestAccessor, class Neighborhood>
+inline void 
+extendedLocalMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                      pair<DestIterator, DestAccessor> dest,
+                      typename DestAccessor::value_type marker,
+                      Neighborhood neighborhood)
+{
+    extendedLocalMaxima3D(src.first, src.second, src.third, 
+                          dest.first, dest.second, 
+                          marker, neighborhood);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_LOCALMINMAX_HXX
diff --git a/include/vigra/mathutil.hxx b/include/vigra/mathutil.hxx
new file mode 100644
index 0000000..2a3360b
--- /dev/null
+++ b/include/vigra/mathutil.hxx
@@ -0,0 +1,1625 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2011 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MATHUTIL_HXX
+#define VIGRA_MATHUTIL_HXX
+
+#ifdef _MSC_VER
+# pragma warning (disable: 4996) // hypot/_hypot confusion
+#endif
+
+#include <cmath>
+#include <cstdlib>
+#include <complex>
+#include "config.hxx"
+#include "error.hxx"
+#include "tuple.hxx"
+#include "sized_int.hxx"
+#include "numerictraits.hxx"
+#include "algorithm.hxx"
+
+/** \page MathConstants Mathematical Constants
+
+    <TT>M_PI, M_SQRT2 etc.</TT>
+
+    <b>\#include</b> \<vigra/mathutil.hxx\>
+
+    Since mathematical constants such as <TT>M_PI</TT> and <TT>M_SQRT2</TT> 
+    are not officially standardized, we provide definitions here for those 
+    compilers that don't support them.
+
+    \code
+    #ifndef M_PI
+    #    define M_PI     3.14159265358979323846
+    #endif
+
+    #ifndef M_SQRT2
+    #    define M_2_PI   0.63661977236758134308
+    #endif
+
+    #ifndef M_PI_2
+    #    define M_PI_2   1.57079632679489661923
+    #endif
+
+    #ifndef M_PI_4
+    #    define M_PI_4   0.78539816339744830962
+    #endif
+
+    #ifndef M_SQRT2
+    #    define M_SQRT2  1.41421356237309504880
+    #endif
+
+    #ifndef M_EULER_GAMMA
+    #    define M_EULER_GAMMA  0.5772156649015329
+    #endif
+    \endcode
+*/
+#ifndef M_PI
+#    define M_PI     3.14159265358979323846
+#endif
+
+#ifndef M_2_PI
+#    define M_2_PI   0.63661977236758134308
+#endif
+
+#ifndef M_PI_2
+#    define M_PI_2   1.57079632679489661923
+#endif
+
+#ifndef M_PI_4
+#    define M_PI_4   0.78539816339744830962
+#endif
+
+#ifndef M_SQRT2
+#    define M_SQRT2  1.41421356237309504880
+#endif
+
+#ifndef M_E
+#    define M_E      2.71828182845904523536
+#endif
+
+#ifndef M_EULER_GAMMA
+#    define M_EULER_GAMMA  0.5772156649015329
+#endif
+
+namespace vigra {
+
+/** \addtogroup MathFunctions Mathematical Functions
+
+    Useful mathematical functions and functors.
+*/
+//@{
+// import functions into namespace vigra which VIGRA is going to overload
+
+using VIGRA_CSTD::pow;  
+using VIGRA_CSTD::floor;  
+using VIGRA_CSTD::ceil;  
+using VIGRA_CSTD::exp;  
+
+// import abs(float), abs(double), abs(long double) from <cmath>
+//        abs(int), abs(long), abs(long long) from <cstdlib>
+//        abs(std::complex<T>) from <complex>
+using std::abs;  
+
+// define the missing variants of abs() to avoid 'ambiguous overload'
+// errors in template functions
+#define VIGRA_DEFINE_UNSIGNED_ABS(T) \
+    inline T abs(T t) { return t; }
+
+VIGRA_DEFINE_UNSIGNED_ABS(bool)
+VIGRA_DEFINE_UNSIGNED_ABS(unsigned char)
+VIGRA_DEFINE_UNSIGNED_ABS(unsigned short)
+VIGRA_DEFINE_UNSIGNED_ABS(unsigned int)
+VIGRA_DEFINE_UNSIGNED_ABS(unsigned long)
+VIGRA_DEFINE_UNSIGNED_ABS(unsigned long long)
+
+#undef VIGRA_DEFINE_UNSIGNED_ABS
+
+#define VIGRA_DEFINE_MISSING_ABS(T) \
+    inline T abs(T t) { return t < 0 ? static_cast<T>(-t) : t; }
+
+VIGRA_DEFINE_MISSING_ABS(signed char)
+VIGRA_DEFINE_MISSING_ABS(signed short)
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+VIGRA_DEFINE_MISSING_ABS(signed long long)
+#endif
+
+#undef VIGRA_DEFINE_MISSING_ABS
+
+// scalar dot is needed for generic functions that should work with
+// scalars and vectors alike
+
+#define VIGRA_DEFINE_SCALAR_DOT(T) \
+    inline NumericTraits<T>::Promote dot(T l, T r) { return l*r; }
+
+VIGRA_DEFINE_SCALAR_DOT(unsigned char)
+VIGRA_DEFINE_SCALAR_DOT(unsigned short)
+VIGRA_DEFINE_SCALAR_DOT(unsigned int)
+VIGRA_DEFINE_SCALAR_DOT(unsigned long)
+VIGRA_DEFINE_SCALAR_DOT(unsigned long long)
+VIGRA_DEFINE_SCALAR_DOT(signed char)
+VIGRA_DEFINE_SCALAR_DOT(signed short)
+VIGRA_DEFINE_SCALAR_DOT(signed int)
+VIGRA_DEFINE_SCALAR_DOT(signed long)
+VIGRA_DEFINE_SCALAR_DOT(signed long long)
+VIGRA_DEFINE_SCALAR_DOT(float)
+VIGRA_DEFINE_SCALAR_DOT(double)
+VIGRA_DEFINE_SCALAR_DOT(long double)
+
+#undef VIGRA_DEFINE_SCALAR_DOT
+
+using std::pow;
+
+// support 'double' exponents for all floating point versions of pow()
+
+inline float pow(float v, double e)
+{
+    return std::pow(v, (float)e);
+}
+
+inline long double pow(long double v, double e)
+{
+    return std::pow(v, (long double)e);
+}
+
+    /** \brief The rounding function.
+
+        Defined for all floating point types. Rounds towards the nearest integer 
+        such that <tt>abs(round(t)) == round(abs(t))</tt> for all <tt>t</tt>.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+#ifdef DOXYGEN // only for documentation
+REAL round(REAL v);
+#endif
+
+inline float round(float t)
+{
+     return t >= 0.0
+                ? floor(t + 0.5f)
+                : ceil(t - 0.5f);
+}
+
+inline double round(double t)
+{
+     return t >= 0.0
+                ? floor(t + 0.5)
+                : ceil(t - 0.5);
+}
+
+inline long double round(long double t)
+{
+     return t >= 0.0
+                ? floor(t + 0.5)
+                : ceil(t - 0.5);
+}
+
+
+    /** \brief Round and cast to integer.
+
+        Rounds to the nearest integer like round(), but casts the result to 
+        <tt>int</tt> (this will be faster and is usually needed anyway).
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline int roundi(double t)
+{
+     return t >= 0.0
+                ? int(t + 0.5)
+                : int(t - 0.5);
+}
+
+    /** \brief Round up to the nearest power of 2.
+
+        Efficient algorithm for finding the smallest power of 2 which is not smaller than \a x
+        (function clp2() from Henry Warren: "Hacker's Delight", Addison-Wesley, 2003,
+         see http://www.hackersdelight.org/).
+        If \a x > 2^31, the function will return 0 because integer arithmetic is defined modulo 2^32.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline UInt32 ceilPower2(UInt32 x) 
+{
+    if(x == 0) return 0;
+    
+    x = x - 1;
+    x = x | (x >> 1);
+    x = x | (x >> 2);
+    x = x | (x >> 4);
+    x = x | (x >> 8);
+    x = x | (x >>16);
+    return x + 1;
+} 
+    
+    /** \brief Round down to the nearest power of 2.
+
+        Efficient algorithm for finding the largest power of 2 which is not greater than \a x
+        (function flp2() from Henry Warren: "Hacker's Delight", Addison-Wesley, 2003,
+         see http://www.hackersdelight.org/).
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline UInt32 floorPower2(UInt32 x) 
+{ 
+    x = x | (x >> 1);
+    x = x | (x >> 2);
+    x = x | (x >> 4);
+    x = x | (x >> 8);
+    x = x | (x >>16);
+    return x - (x >> 1);
+}
+
+namespace detail {
+
+template <class T>
+struct IntLog2
+{
+    static Int32 table[64];
+};
+
+template <class T>
+Int32 IntLog2<T>::table[64] = {
+         -1,  0,  -1,  15,  -1,  1,  28,  -1,  16,  -1,  -1,  -1,  2,  21,  
+         29,  -1,  -1,  -1,  19,  17,  10,  -1,  12,  -1,  -1,  3,  -1,  6,  
+         -1,  22,  30,  -1,  14,  -1,  27,  -1,  -1,  -1,  20,  -1,  18,  9,  
+         11,  -1,  5,  -1,  -1,  13,  26,  -1,  -1,  8,  -1,  4,  -1,  25,  
+         -1,  7,  24,  -1,  23,  -1,  31,  -1};
+
+} // namespace detail
+
+    /** \brief Compute the base-2 logarithm of an integer.
+
+        Returns the position of the left-most 1-bit in the given number \a x, or
+        -1 if \a x == 0. That is,
+        
+        \code
+        assert(k >= 0 && k < 32 && log2i(1 << k) == k);
+        \endcode
+        
+        The function uses Robert Harley's algorithm to determine the number of leading zeros
+        in \a x (algorithm nlz10() at http://www.hackersdelight.org/). But note that the functions
+        \ref floorPower2() or \ref ceilPower2() are more efficient and should be preferred when possible.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline Int32 log2i(UInt32 x) 
+{ 
+    // Propagate leftmost 1-bit to the right.
+    x = x | (x >> 1);
+    x = x | (x >> 2);
+    x = x | (x >> 4);
+    x = x | (x >> 8);
+    x = x | (x >>16);
+    x = x*0x06EB14F9; // Multiplier is 7*255**3. 
+    return detail::IntLog2<Int32>::table[x >> 26];
+}
+
+    /** \brief The square function.
+
+        <tt>sq(x) = x*x</tt> is needed so often that it makes sense to define it as a function.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class T>
+inline 
+typename NumericTraits<T>::Promote sq(T t)
+{
+    return t*t;
+}
+
+namespace detail {
+
+template <class V, unsigned>
+struct cond_mult
+{
+    static V call(const V & x, const V & y) { return x * y; }
+};
+template <class V>
+struct cond_mult<V, 0>
+{
+    static V call(const V &, const V & y) { return y; }
+};
+
+template <class V, unsigned n>
+struct power_static
+{
+    static V call(const V & x)
+    {
+        return n / 2
+            ? cond_mult<V, n & 1>::call(x, power_static<V, n / 2>::call(x * x))
+            : n & 1 ? x : V();
+    }
+};
+template <class V>
+struct power_static<V, 0>
+{
+    static V call(const V & x)
+    {
+        return V(1);
+    }
+};
+
+} // namespace detail
+
+    /** \brief Exponentiation to a positive integer power by squaring.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <unsigned n, class V>
+inline V power(const V & x)
+{
+    return detail::power_static<V, n>::call(x);
+}
+//doxygen_overloaded_function(template <unsigned n, class V> power(const V & x))
+
+namespace detail {
+
+template <class T>
+struct IntSquareRoot
+{
+    static UInt32 sqq_table[];
+    static UInt32 exec(UInt32 v);
+};
+
+template <class T>
+UInt32 IntSquareRoot<T>::sqq_table[] = {
+           0,  16,  22,  27,  32,  35,  39,  42,  45,  48,  50,  53,  55,  57,
+          59,  61,  64,  65,  67,  69,  71,  73,  75,  76,  78,  80,  81,  83,
+          84,  86,  87,  89,  90,  91,  93,  94,  96,  97,  98,  99, 101, 102,
+         103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118,
+         119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131, 132,
+         133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 145,
+         146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, 156, 157,
+         158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168,
+         169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178,
+         179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188,
+         189, 189, 190, 191, 192, 192, 193, 193, 194, 195, 195, 196, 197, 197,
+         198, 199, 199, 200, 201, 201, 202, 203, 203, 204, 204, 205, 206, 206,
+         207, 208, 208, 209, 209, 210, 211, 211, 212, 212, 213, 214, 214, 215,
+         215, 216, 217, 217, 218, 218, 219, 219, 220, 221, 221, 222, 222, 223,
+         224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, 230, 231,
+         231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238,
+         239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246,
+         246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253,
+         253, 254, 254, 255
+};
+
+template <class T>
+UInt32 IntSquareRoot<T>::exec(UInt32 x) 
+{
+    UInt32 xn;
+    if (x >= 0x10000)
+        if (x >= 0x1000000)
+            if (x >= 0x10000000)
+                if (x >= 0x40000000) {
+                    if (x >= (UInt32)65535*(UInt32)65535)
+                        return 65535;
+                    xn = sqq_table[x>>24] << 8;
+                } else
+                    xn = sqq_table[x>>22] << 7;
+            else
+                if (x >= 0x4000000)
+                    xn = sqq_table[x>>20] << 6;
+                else
+                    xn = sqq_table[x>>18] << 5;
+        else {
+            if (x >= 0x100000)
+                if (x >= 0x400000)
+                    xn = sqq_table[x>>16] << 4;
+                else
+                    xn = sqq_table[x>>14] << 3;
+            else
+                if (x >= 0x40000)
+                    xn = sqq_table[x>>12] << 2;
+                else
+                    xn = sqq_table[x>>10] << 1;
+
+            goto nr1;
+        }
+    else
+        if (x >= 0x100) {
+            if (x >= 0x1000)
+                if (x >= 0x4000)
+                    xn = (sqq_table[x>>8] >> 0) + 1;
+                else
+                    xn = (sqq_table[x>>6] >> 1) + 1;
+            else
+                if (x >= 0x400)
+                    xn = (sqq_table[x>>4] >> 2) + 1;
+                else
+                    xn = (sqq_table[x>>2] >> 3) + 1;
+
+            goto adj;
+        } else
+            return sqq_table[x] >> 4;
+
+    /* Run two iterations of the standard convergence formula */
+
+    xn = (xn + 1 + x / xn) / 2;
+  nr1:
+    xn = (xn + 1 + x / xn) / 2;
+  adj:
+
+    if (xn * xn > x) /* Correct rounding if necessary */
+        xn--;
+
+    return xn;
+}
+
+} // namespace detail
+
+using VIGRA_CSTD::sqrt;
+
+    /** \brief Signed integer square root.
+    
+        Useful for fast fixed-point computations.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline Int32 sqrti(Int32 v)
+{
+    if(v < 0)
+        throw std::domain_error("sqrti(Int32): negative argument.");
+    return (Int32)detail::IntSquareRoot<UInt32>::exec((UInt32)v);
+}
+
+    /** \brief Unsigned integer square root.
+
+        Useful for fast fixed-point computations.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline UInt32 sqrti(UInt32 v)
+{
+    return detail::IntSquareRoot<UInt32>::exec(v);
+}
+
+#ifdef VIGRA_NO_HYPOT
+    /** \brief Compute the Euclidean distance (length of the hypotenuse of a right-angled triangle).
+
+        The  hypot()  function  returns  the  sqrt(a*a  +  b*b).
+        It is implemented in a way that minimizes round-off error.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline double hypot(double a, double b) 
+{ 
+    double absa = VIGRA_CSTD::fabs(a), absb = VIGRA_CSTD::fabs(b);
+    if (absa > absb) 
+        return absa * VIGRA_CSTD::sqrt(1.0 + sq(absb/absa)); 
+    else 
+        return absb == 0.0
+                   ? 0.0
+                   : absb * VIGRA_CSTD::sqrt(1.0 + sq(absa/absb)); 
+}
+
+#else
+
+using ::hypot;
+
+#endif
+
+    /** \brief The sign function.
+
+        Returns 1, 0, or -1 depending on the sign of \a t, but with the same type as \a t.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class T>
+inline T sign(T t) 
+{ 
+    return t > NumericTraits<T>::zero()
+               ? NumericTraits<T>::one()
+               : t < NumericTraits<T>::zero()
+                    ? -NumericTraits<T>::one()
+                    : NumericTraits<T>::zero();
+}
+
+    /** \brief The integer sign function.
+
+        Returns 1, 0, or -1 depending on the sign of \a t, converted to int.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class T>
+inline int signi(T t) 
+{ 
+    return t > NumericTraits<T>::zero()
+               ? 1
+               : t < NumericTraits<T>::zero()
+                    ? -1
+                    : 0;
+}
+
+    /** \brief The binary sign function.
+
+        Transfers the sign of \a t2 to \a t1.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class T1, class T2>
+inline T1 sign(T1 t1, T2 t2) 
+{ 
+    return t2 >= NumericTraits<T2>::zero()
+               ? abs(t1)
+               : -abs(t1);
+}
+
+
+#ifdef DOXYGEN // only for documentation
+    /** \brief Check if an integer is even.
+
+        Defined for all integral types.
+    */
+bool even(int t);
+
+    /** \brief Check if an integer is odd.
+
+        Defined for all integral types.
+    */
+bool odd(int t);
+
+#endif
+
+#define VIGRA_DEFINE_ODD_EVEN(T) \
+    inline bool even(T t) { return (t&1) == 0; } \
+    inline bool odd(T t)  { return (t&1) == 1; }
+
+VIGRA_DEFINE_ODD_EVEN(char)
+VIGRA_DEFINE_ODD_EVEN(short)
+VIGRA_DEFINE_ODD_EVEN(int)
+VIGRA_DEFINE_ODD_EVEN(long)
+VIGRA_DEFINE_ODD_EVEN(long long)
+VIGRA_DEFINE_ODD_EVEN(unsigned char)
+VIGRA_DEFINE_ODD_EVEN(unsigned short)
+VIGRA_DEFINE_ODD_EVEN(unsigned int)
+VIGRA_DEFINE_ODD_EVEN(unsigned long)
+VIGRA_DEFINE_ODD_EVEN(unsigned long long)
+
+#undef VIGRA_DEFINE_ODD_EVEN
+
+#define VIGRA_DEFINE_NORM(T) \
+    inline NormTraits<T>::SquaredNormType squaredNorm(T t) { return sq(t); } \
+    inline NormTraits<T>::NormType norm(T t) { return abs(t); }
+
+VIGRA_DEFINE_NORM(bool)
+VIGRA_DEFINE_NORM(signed char)
+VIGRA_DEFINE_NORM(unsigned char)
+VIGRA_DEFINE_NORM(short)
+VIGRA_DEFINE_NORM(unsigned short)
+VIGRA_DEFINE_NORM(int)
+VIGRA_DEFINE_NORM(unsigned int)
+VIGRA_DEFINE_NORM(long)
+VIGRA_DEFINE_NORM(unsigned long)
+VIGRA_DEFINE_NORM(long long)
+VIGRA_DEFINE_NORM(unsigned long long)
+VIGRA_DEFINE_NORM(float)
+VIGRA_DEFINE_NORM(double)
+VIGRA_DEFINE_NORM(long double)
+
+#undef VIGRA_DEFINE_NORM
+
+template <class T>
+inline typename NormTraits<std::complex<T> >::SquaredNormType
+squaredNorm(std::complex<T> const & t)
+{
+    return sq(t.real()) + sq(t.imag());
+}
+
+#ifdef DOXYGEN // only for documentation
+    /** \brief The squared norm of a numerical object.
+
+        <ul>
+        <li>For scalar types: equals <tt>vigra::sq(t)</tt>.
+        <li>For vectorial types (including TinyVector): equals <tt>vigra::dot(t, t)</tt>.
+        <li>For complex number types: equals <tt>vigra::sq(t.real()) + vigra::sq(t.imag())</tt>.
+        <li>For array and matrix types: results in the squared Frobenius norm (sum of squares of the matrix elements).
+        </ul>
+    */
+NormTraits<T>::SquaredNormType squaredNorm(T const & t);
+
+#endif
+
+    /** \brief The norm of a numerical object.
+
+        For scalar types: implemented as <tt>abs(t)</tt><br>
+        otherwise: implemented as <tt>sqrt(squaredNorm(t))</tt>.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class T>
+inline typename NormTraits<T>::NormType 
+norm(T const & t)
+{
+    typedef typename NormTraits<T>::SquaredNormType SNT;
+    return sqrt(static_cast<typename SquareRootTraits<SNT>::SquareRootArgument>(squaredNorm(t)));
+}
+
+    /** \brief Compute the eigenvalues of a 2x2 real symmetric matrix.
+      
+        This uses the analytical eigenvalue formula 
+        \f[
+           \lambda_{1,2} = \frac{1}{2}\left(a_{00} + a_{11} \pm \sqrt{(a_{00} - a_{11})^2 + 4 a_{01}^2}\right)
+        \f]
+      
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class T>
+void symmetric2x2Eigenvalues(T a00, T a01, T a11, T * r0, T * r1)
+{
+    double d  = hypot(a00 - a11, 2.0*a01);
+    *r0 = static_cast<T>(0.5*(a00 + a11 + d));
+    *r1 = static_cast<T>(0.5*(a00 + a11 - d));
+    if(*r0 < *r1)
+        std::swap(*r0, *r1);
+}
+
+    /** \brief Compute the eigenvalues of a 3x3 real symmetric matrix.
+        
+        This uses a numerically stable version of the analytical eigenvalue formula according to
+        <p>
+        David Eberly: <a href="http://www.geometrictools.com/Documentation/EigenSymmetric3x3.pdf">
+        <em>"Eigensystems for 3 � 3 Symmetric Matrices (Revisited)"</em></a>, Geometric Tools Documentation, 2006
+        
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class T>
+void symmetric3x3Eigenvalues(T a00, T a01, T a02, T a11, T a12, T a22,
+                             T * r0, T * r1, T * r2)
+{
+    double inv3 = 1.0 / 3.0, root3 = std::sqrt(3.0);
+    
+    double c0 = a00*a11*a22 + 2.0*a01*a02*a12 - a00*a12*a12 - a11*a02*a02 - a22*a01*a01;
+    double c1 = a00*a11 - a01*a01 + a00*a22 - a02*a02 + a11*a22 - a12*a12;
+    double c2 = a00 + a11 + a22;
+    double c2Div3 = c2*inv3;
+    double aDiv3 = (c1 - c2*c2Div3)*inv3;
+    if (aDiv3 > 0.0) 
+        aDiv3 = 0.0;
+    double mbDiv2 = 0.5*(c0 + c2Div3*(2.0*c2Div3*c2Div3 - c1));
+    double q = mbDiv2*mbDiv2 + aDiv3*aDiv3*aDiv3;
+    if (q > 0.0) 
+        q = 0.0;
+    double magnitude = std::sqrt(-aDiv3);
+    double angle = std::atan2(std::sqrt(-q),mbDiv2)*inv3;
+    double cs = std::cos(angle);
+    double sn = std::sin(angle);
+    *r0 = static_cast<T>(c2Div3 + 2.0*magnitude*cs);
+    *r1 = static_cast<T>(c2Div3 - magnitude*(cs + root3*sn));
+    *r2 = static_cast<T>(c2Div3 - magnitude*(cs - root3*sn));
+    if(*r0 < *r1)
+        std::swap(*r0, *r1);
+    if(*r0 < *r2)
+        std::swap(*r0, *r2);
+    if(*r1 < *r2)
+        std::swap(*r1, *r2);
+}
+
+namespace detail {
+
+template <class T>
+T ellipticRD(T x, T y, T z)
+{
+    double f = 1.0, s = 0.0, X, Y, Z, m;
+    for(;;)
+    {
+        m = (x + y + 3.0*z) / 5.0;
+        X = 1.0 - x/m;
+        Y = 1.0 - y/m;
+        Z = 1.0 - z/m;
+        if(std::max(std::max(VIGRA_CSTD::fabs(X), VIGRA_CSTD::fabs(Y)), VIGRA_CSTD::fabs(Z)) < 0.01)
+            break;
+        double l = VIGRA_CSTD::sqrt(x*y) + VIGRA_CSTD::sqrt(x*z) + VIGRA_CSTD::sqrt(y*z);
+        s += f / (VIGRA_CSTD::sqrt(z)*(z + l));
+        f /= 4.0;
+        x = (x + l)/4.0;
+        y = (y + l)/4.0;
+        z = (z + l)/4.0;
+    }
+    double a = X*Y;
+    double b = sq(Z);
+    double c = a - b;
+    double d = a - 6.0*b;
+    double e = d + 2.0*c;
+    return 3.0*s + f*(1.0+d*(-3.0/14.0+d*9.0/88.0-Z*e*4.5/26.0)
+                      +Z*(e/6.0+Z*(-c*9.0/22.0+a*Z*3.0/26.0))) / VIGRA_CSTD::pow(m,1.5);
+}
+
+template <class T>
+T ellipticRF(T x, T y, T z)
+{
+    double X, Y, Z, m;
+    for(;;)
+    {
+        m = (x + y + z) / 3.0;
+        X = 1.0 - x/m;
+        Y = 1.0 - y/m;
+        Z = 1.0 - z/m;
+        if(std::max(std::max(VIGRA_CSTD::fabs(X), VIGRA_CSTD::fabs(Y)), VIGRA_CSTD::fabs(Z)) < 0.01)
+            break;
+        double l = VIGRA_CSTD::sqrt(x*y) + VIGRA_CSTD::sqrt(x*z) + VIGRA_CSTD::sqrt(y*z);
+        x = (x + l)/4.0;
+        y = (y + l)/4.0;
+        z = (z + l)/4.0;
+    }
+    double d = X*Y - sq(Z);
+    double p = X*Y*Z;
+    return (1.0 - d/10.0 + p/14.0 + sq(d)/24.0 - d*p*3.0/44.0) / VIGRA_CSTD::sqrt(m);
+}
+
+} // namespace detail
+
+    /** \brief The incomplete elliptic integral of the first kind.
+    
+        This function computes
+
+        \f[
+             \mbox{F}(x, k) = \int_0^x \frac{1}{\sqrt{1 - k^2 \sin(t)^2}} dt
+        \f]
+  
+        according to the algorithm given in Press et al. "Numerical Recipes". 
+
+        Note: In some libraries (e.g. Mathematica), the second parameter of the elliptic integral
+        functions must be k^2 rather than k. Check the documentation when results disagree!
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline double ellipticIntegralF(double x, double k)
+{
+    double c2 = sq(VIGRA_CSTD::cos(x));
+    double s = VIGRA_CSTD::sin(x);
+    return s*detail::ellipticRF(c2, 1.0 - sq(k*s), 1.0);
+}
+
+    /** \brief The incomplete elliptic integral of the second kind.
+      
+        This function computes
+      
+        \f[
+            \mbox{E}(x, k) = \int_0^x \sqrt{1 - k^2 \sin(t)^2} dt
+        \f]
+      
+        according to the algorithm given in Press et al. "Numerical Recipes". The
+        complete elliptic integral of the second kind is simply <tt>ellipticIntegralE(M_PI/2, k)</TT>.
+      
+        Note: In some libraries (e.g. Mathematica), the second parameter of the elliptic integral
+        functions must be k^2 rather than k. Check the documentation when results disagree!
+      
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline double ellipticIntegralE(double x, double k)
+{
+    double c2 = sq(VIGRA_CSTD::cos(x));
+    double s = VIGRA_CSTD::sin(x);
+    k = sq(k*s);
+    return s*(detail::ellipticRF(c2, 1.0-k, 1.0) - k/3.0*detail::ellipticRD(c2, 1.0-k, 1.0));
+}
+
+#ifdef _MSC_VER
+
+namespace detail {
+
+template <class T>
+double erfImpl(T x)
+{
+    double t = 1.0/(1.0+0.5*VIGRA_CSTD::fabs(x));
+    double ans = t*VIGRA_CSTD::exp(-x*x-1.26551223+t*(1.00002368+t*(0.37409196+
+                                    t*(0.09678418+t*(-0.18628806+t*(0.27886807+
+                                    t*(-1.13520398+t*(1.48851587+t*(-0.82215223+
+                                    t*0.17087277)))))))));
+    if (x >= 0.0)
+        return 1.0 - ans;
+    else
+        return ans - 1.0;
+}
+
+} // namespace detail 
+
+    /** \brief The error function.
+
+        If <tt>erf()</tt> is not provided in the C standard math library (as it should according to the
+        new C99 standard ?), VIGRA implements <tt>erf()</tt> as an approximation of the error 
+        function
+        
+        \f[
+            \mbox{erf}(x) = \int_0^x e^{-t^2} dt
+        \f]
+        
+        according to the formula given in Press et al. "Numerical Recipes".
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline double erf(double x)
+{
+    return detail::erfImpl(x);
+}
+
+#else
+
+using ::erf;
+
+#endif
+
+namespace detail {
+
+template <class T>
+double noncentralChi2CDFApprox(unsigned int degreesOfFreedom, T noncentrality, T arg)
+{
+    double a = degreesOfFreedom + noncentrality;
+    double b = (a + noncentrality) / sq(a);
+    double t = (VIGRA_CSTD::pow((double)arg / a, 1.0/3.0) - (1.0 - 2.0 / 9.0 * b)) / VIGRA_CSTD::sqrt(2.0 / 9.0 * b);
+    return 0.5*(1.0 + erf(t/VIGRA_CSTD::sqrt(2.0)));
+}
+
+template <class T>
+void noncentralChi2OneIteration(T arg, T & lans, T & dans, T & pans, unsigned int & j)
+{
+    double tol = -50.0;
+    if(lans < tol)
+    {
+        lans = lans + VIGRA_CSTD::log(arg / j);
+        dans = VIGRA_CSTD::exp(lans);
+    }
+    else
+    {
+        dans = dans * arg / j;
+    }
+    pans = pans - dans;
+    j += 2;
+}
+
+template <class T>
+std::pair<double, double> noncentralChi2CDF(unsigned int degreesOfFreedom, T noncentrality, T arg, T eps)
+{
+    vigra_precondition(noncentrality >= 0.0 && arg >= 0.0 && eps > 0.0,
+        "noncentralChi2P(): parameters must be positive.");
+    if (arg == 0.0 && degreesOfFreedom > 0)
+        return std::make_pair(0.0, 0.0);
+
+    // Determine initial values
+    double b1 = 0.5 * noncentrality,
+           ao = VIGRA_CSTD::exp(-b1),
+           eps2 = eps / ao,
+           lnrtpi2 = 0.22579135264473,
+           probability, density, lans, dans, pans, sum, am, hold;
+    unsigned int maxit = 500,
+        i, m;
+    if(degreesOfFreedom % 2)
+    {
+        i = 1;
+        lans = -0.5 * (arg + VIGRA_CSTD::log(arg)) - lnrtpi2;
+        dans = VIGRA_CSTD::exp(lans);
+        pans = erf(VIGRA_CSTD::sqrt(arg/2.0));
+    }
+    else
+    {
+        i = 2;
+        lans = -0.5 * arg;
+        dans = VIGRA_CSTD::exp(lans);
+        pans = 1.0 - dans;
+    }
+    
+    // Evaluate first term
+    if(degreesOfFreedom == 0)
+    {
+        m = 1;
+        degreesOfFreedom = 2;
+        am = b1;
+        sum = 1.0 / ao - 1.0 - am;
+        density = am * dans;
+        probability = 1.0 + am * pans;
+    }
+    else
+    {
+        m = 0;
+        degreesOfFreedom = degreesOfFreedom - 1;
+        am = 1.0;
+        sum = 1.0 / ao - 1.0;
+        while(i < degreesOfFreedom)
+            detail::noncentralChi2OneIteration(arg, lans, dans, pans, i);
+        degreesOfFreedom = degreesOfFreedom + 1;
+        density = dans;
+        probability = pans;
+    }
+    // Evaluate successive terms of the expansion
+    for(++m; m<maxit; ++m)
+    {
+        am = b1 * am / m;
+        detail::noncentralChi2OneIteration(arg, lans, dans, pans, degreesOfFreedom);
+        sum = sum - am;
+        density = density + am * dans;
+        hold = am * pans;
+        probability = probability + hold;
+        if((pans * sum < eps2) && (hold < eps2))
+            break; // converged
+    }
+    if(m == maxit)
+        vigra_fail("noncentralChi2P(): no convergence.");
+    return std::make_pair(0.5 * ao * density, std::min(1.0, std::max(0.0, ao * probability)));
+}
+
+} // namespace detail
+
+    /** \brief Chi square distribution. 
+
+        Computes the density of a chi square distribution with \a degreesOfFreedom 
+        and tolerance \a accuracy at the given argument \a arg
+        by calling <tt>noncentralChi2(degreesOfFreedom, 0.0, arg, accuracy)</tt>.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline double chi2(unsigned int degreesOfFreedom, double arg, double accuracy = 1e-7)
+{
+    return detail::noncentralChi2CDF(degreesOfFreedom, 0.0, arg, accuracy).first;
+}
+
+    /** \brief Cumulative chi square distribution. 
+
+        Computes the cumulative density of a chi square distribution with \a degreesOfFreedom 
+        and tolerance \a accuracy at the given argument \a arg, i.e. the probability that
+        a random number drawn from the distribution is below \a arg
+        by calling <tt>noncentralChi2CDF(degreesOfFreedom, 0.0, arg, accuracy)</tt>.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline double chi2CDF(unsigned int degreesOfFreedom, double arg, double accuracy = 1e-7)
+{
+    return detail::noncentralChi2CDF(degreesOfFreedom, 0.0, arg, accuracy).second;
+}
+
+    /** \brief Non-central chi square distribution. 
+
+        Computes the density of a non-central chi square distribution with \a degreesOfFreedom, 
+        noncentrality parameter \a noncentrality and tolerance \a accuracy at the given argument 
+        \a arg. It uses Algorithm AS 231 from Appl. Statist. (1987) Vol.36, No.3 (code ported from 
+        http://lib.stat.cmu.edu/apstat/231). The algorithm has linear complexity in the number of
+        degrees of freedom.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline double noncentralChi2(unsigned int degreesOfFreedom, 
+              double noncentrality, double arg, double accuracy = 1e-7)
+{
+    return detail::noncentralChi2CDF(degreesOfFreedom, noncentrality, arg, accuracy).first;
+}
+
+    /** \brief Cumulative non-central chi square distribution. 
+
+        Computes the cumulative density of a chi square distribution with \a degreesOfFreedom, 
+        noncentrality parameter \a noncentrality and tolerance \a accuracy at the given argument 
+        \a arg, i.e. the probability that a random number drawn from the distribution is below \a arg
+        It uses Algorithm AS 231 from Appl. Statist. (1987) Vol.36, No.3 (code ported from 
+        http://lib.stat.cmu.edu/apstat/231). The algorithm has linear complexity in the number of
+        degrees of freedom (see noncentralChi2CDFApprox() for a constant-time algorithm).
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline double noncentralChi2CDF(unsigned int degreesOfFreedom, 
+              double noncentrality, double arg, double accuracy = 1e-7)
+{
+    return detail::noncentralChi2CDF(degreesOfFreedom, noncentrality, arg, accuracy).second;
+}
+
+    /** \brief Cumulative non-central chi square distribution (approximate). 
+
+        Computes approximate values of the cumulative density of a chi square distribution with \a degreesOfFreedom, 
+        and noncentrality parameter \a noncentrality at the given argument 
+        \a arg, i.e. the probability that a random number drawn from the distribution is below \a arg
+        It uses the approximate transform into a normal distribution due to Wilson and Hilferty 
+        (see Abramovitz, Stegun: "Handbook of Mathematical Functions", formula 26.3.32). 
+        The algorithm's running time is independent of the inputs, i.e. is should be used
+        when noncentralChi2CDF() is too slow, and approximate values are sufficient. The accuracy is only 
+        about 0.1 for few degrees of freedom, but reaches about 0.001 above dof = 5.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline double noncentralChi2CDFApprox(unsigned int degreesOfFreedom, double noncentrality, double arg)
+{
+    return detail::noncentralChi2CDFApprox(degreesOfFreedom, noncentrality, arg);
+}
+
+namespace detail  {
+
+// computes (l+m)! / (l-m)!
+// l and m must be positive
+template <class T>
+T facLM(T l, T m)
+{
+    T tmp = NumericTraits<T>::one();
+    for(T f = l-m+1; f <= l+m; ++f)
+        tmp *= f;
+    return tmp;
+}
+
+} // namespace detail
+
+    /** \brief Associated Legendre polynomial. 
+
+        Computes the value of the associated Legendre polynomial of order <tt>l, m</tt> 
+        for argument <tt>x</tt>. <tt>x</tt> must be in the range <tt>[-1.0, 1.0]</tt>, 
+        otherwise an exception is thrown. The standard Legendre polynomials are the 
+        special case <tt>m == 0</tt>.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class REAL>
+REAL legendre(unsigned int l, int m, REAL x)
+{
+    vigra_precondition(abs(x) <= 1.0, "legendre(): x must be in [-1.0, 1.0].");
+    if (m < 0)
+    {
+        m = -m;
+        REAL s = odd(m)
+                   ? -1.0
+                   :  1.0;
+        return legendre(l,m,x) * s / detail::facLM<REAL>(l,m);
+    }
+    REAL result = 1.0;
+    if (m > 0)
+    {
+        REAL r = std::sqrt( (1.0-x) * (1.0+x) );
+        REAL f = 1.0;
+        for (int i=1; i<=m; i++)
+        {
+            result *= (-f) * r;
+            f += 2.0;
+        }
+    }
+    if((int)l == m) 
+        return result;
+
+    REAL result_1 = x * (2.0 * m + 1.0) * result;
+    if((int)l == m+1) 
+        return result_1;
+    REAL other = 0.0;
+    for(unsigned int i = m+2; i <= l; ++i)
+    {
+        other = ( (2.0*i-1.0) * x * result_1 - (i+m-1.0)*result) / (i-m);
+        result = result_1;
+        result_1 = other;
+    }
+    return other;
+}
+
+    /** \brief \brief Legendre polynomial. 
+
+        Computes the value of the Legendre polynomial of order <tt>l</tt> for argument <tt>x</tt>.
+        <tt>x</tt> must be in the range <tt>[-1.0, 1.0]</tt>, otherwise an exception is thrown.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class REAL>
+REAL legendre(unsigned int l, REAL x)
+{
+    return legendre(l, 0, x);
+}
+
+    /** \brief sin(pi*x). 
+
+        Essentially calls <tt>std::sin(M_PI*x)</tt> but uses a more accurate implementation
+        to make sure that <tt>sin_pi(1.0) == 0.0</tt> (which does not hold for
+        <tt>std::sin(M_PI)</tt> due to round-off error), and <tt>sin_pi(0.5) == 1.0</tt>.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class REAL>
+REAL sin_pi(REAL x)
+{
+    if(x < 0.0)
+        return -sin_pi(-x);
+    if(x < 0.5)
+        return std::sin(M_PI * x);
+
+    bool invert = false;
+    if(x < 1.0)
+    {
+        invert = true;
+        x = -x;
+    }
+
+    REAL rem = std::floor(x);
+    if(odd((int)rem))
+        invert = !invert;
+    rem = x - rem;
+    if(rem > 0.5)
+        rem = 1.0 - rem;
+    if(rem == 0.5)
+        rem = NumericTraits<REAL>::one();
+    else
+        rem = std::sin(M_PI * rem);
+    return invert 
+              ? -rem 
+              : rem;
+}
+
+    /** \brief cos(pi*x). 
+
+        Essentially calls <tt>std::cos(M_PI*x)</tt> but uses a more accurate implementation
+        to make sure that <tt>cos_pi(1.0) == -1.0</tt> and <tt>cos_pi(0.5) == 0.0</tt>.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class REAL>
+REAL cos_pi(REAL x)
+{
+    return sin_pi(x+0.5);
+}
+
+namespace detail {
+
+template <class REAL>
+struct GammaImpl
+{
+    static REAL gamma(REAL x);
+    static REAL loggamma(REAL x);
+    
+    static double g[];
+    static double a[];
+    static double t[];
+    static double u[];
+    static double v[];
+    static double s[];
+    static double r[];
+    static double w[];
+};
+
+template <class REAL>
+double GammaImpl<REAL>::g[] = {
+    1.0,
+    0.5772156649015329,
+   -0.6558780715202538,
+   -0.420026350340952e-1,
+    0.1665386113822915,
+   -0.421977345555443e-1,
+   -0.9621971527877e-2,
+    0.7218943246663e-2,
+   -0.11651675918591e-2,
+   -0.2152416741149e-3,
+    0.1280502823882e-3,
+   -0.201348547807e-4,
+   -0.12504934821e-5,
+    0.1133027232e-5,
+   -0.2056338417e-6,
+    0.6116095e-8,
+    0.50020075e-8,
+   -0.11812746e-8,
+    0.1043427e-9,
+    0.77823e-11,
+   -0.36968e-11,
+    0.51e-12,
+   -0.206e-13,
+   -0.54e-14,
+    0.14e-14
+};
+
+template <class REAL>
+double GammaImpl<REAL>::a[] = {
+    7.72156649015328655494e-02,
+    3.22467033424113591611e-01,
+    6.73523010531292681824e-02,
+    2.05808084325167332806e-02,
+    7.38555086081402883957e-03,
+    2.89051383673415629091e-03,
+    1.19270763183362067845e-03,
+    5.10069792153511336608e-04,
+    2.20862790713908385557e-04,
+    1.08011567247583939954e-04,
+    2.52144565451257326939e-05,
+    4.48640949618915160150e-05 
+};
+
+template <class REAL>
+double GammaImpl<REAL>::t[] = {
+    4.83836122723810047042e-01,
+    -1.47587722994593911752e-01,
+    6.46249402391333854778e-02,
+    -3.27885410759859649565e-02,
+    1.79706750811820387126e-02,
+    -1.03142241298341437450e-02,
+    6.10053870246291332635e-03,
+    -3.68452016781138256760e-03,
+    2.25964780900612472250e-03,
+    -1.40346469989232843813e-03,
+    8.81081882437654011382e-04,
+    -5.38595305356740546715e-04,
+    3.15632070903625950361e-04,
+    -3.12754168375120860518e-04,
+    3.35529192635519073543e-04
+};
+
+template <class REAL>
+double GammaImpl<REAL>::u[] = {
+    -7.72156649015328655494e-02,
+    6.32827064025093366517e-01,
+    1.45492250137234768737e+00,
+    9.77717527963372745603e-01,
+    2.28963728064692451092e-01,
+    1.33810918536787660377e-02
+};
+
+template <class REAL>
+double GammaImpl<REAL>::v[] = {
+    0.0,
+    2.45597793713041134822e+00,
+    2.12848976379893395361e+00,
+    7.69285150456672783825e-01,
+    1.04222645593369134254e-01,
+    3.21709242282423911810e-03
+};
+
+template <class REAL>
+double GammaImpl<REAL>::s[] = {
+    -7.72156649015328655494e-02,
+    2.14982415960608852501e-01,
+    3.25778796408930981787e-01,
+    1.46350472652464452805e-01,
+    2.66422703033638609560e-02,
+    1.84028451407337715652e-03,
+    3.19475326584100867617e-05
+};
+
+template <class REAL>
+double GammaImpl<REAL>::r[] = {
+    0.0,
+    1.39200533467621045958e+00,
+    7.21935547567138069525e-01,
+    1.71933865632803078993e-01,
+    1.86459191715652901344e-02,
+    7.77942496381893596434e-04,
+    7.32668430744625636189e-06
+};
+
+template <class REAL>
+double GammaImpl<REAL>::w[] = {
+    4.18938533204672725052e-01,
+    8.33333333333329678849e-02,
+    -2.77777777728775536470e-03,
+    7.93650558643019558500e-04,
+    -5.95187557450339963135e-04,
+    8.36339918996282139126e-04,
+    -1.63092934096575273989e-03
+};
+
+template <class REAL>
+REAL GammaImpl<REAL>::gamma(REAL x)
+{
+    int i, k, m, ix = (int)x;
+    double ga = 0.0, gr = 0.0, r = 0.0, z = 0.0;
+
+    vigra_precondition(x <= 171.0,
+        "gamma(): argument cannot exceed 171.0.");
+
+    if (x == ix) 
+    {
+        if (ix > 0) 
+        {
+            ga = 1.0;               // use factorial
+            for (i=2; i<ix; ++i) 
+            {
+               ga *= i;
+            }
+        }
+        else
+        {
+            vigra_precondition(false,
+                 "gamma(): gamma function is undefined for 0 and negative integers.");
+        }
+     }
+     else 
+     {
+        if (abs(x) > 1.0) 
+        {
+            z = abs(x);
+            m = (int)z;
+            r = 1.0;
+            for (k=1; k<=m; ++k) 
+            {
+                r *= (z-k);
+            }
+            z -= m;
+        }
+        else
+        {
+            z = x;
+        }
+        gr = g[24];
+        for (k=23; k>=0; --k) 
+        {
+            gr = gr*z+g[k];
+        }
+        ga = 1.0/(gr*z);
+        if (abs(x) > 1.0) 
+        {
+            ga *= r;
+            if (x < 0.0) 
+            {
+                ga = -M_PI/(x*ga*sin_pi(x));
+            }
+        }
+    }
+    return ga;
+}
+
+/*
+ * the following code is derived from lgamma_r() by Sun
+ * 
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+template <class REAL>
+REAL GammaImpl<REAL>::loggamma(REAL x)
+{
+    vigra_precondition(x > 0.0,
+        "loggamma(): argument must be positive.");
+    
+    vigra_precondition(x <= 1.0e307,
+        "loggamma(): argument must not exceed 1e307.");
+
+    double res;
+    
+    if (x < 4.2351647362715017e-22)
+    {
+        res = -std::log(x);
+    }
+    else if ((x == 2.0) || (x == 1.0))
+    {
+        res = 0.0;
+    }
+    else if (x < 2.0)
+    {
+        const double tc  =  1.46163214496836224576e+00;
+        const double tf  = -1.21486290535849611461e-01;
+        const double tt  = -3.63867699703950536541e-18;
+        if (x <= 0.9)
+        {
+            res = -std::log(x);
+            if (x >= 0.7316)
+            {
+                double y = 1.0-x;
+                double z = y*y;
+                double p1 = a[0]+z*(a[2]+z*(a[4]+z*(a[6]+z*(a[8]+z*a[10]))));
+                double p2 = z*(a[1]+z*(a[3]+z*(a[5]+z*(a[7]+z*(a[9]+z*a[11])))));
+                double p  = y*p1+p2;
+                res  += (p-0.5*y);
+            }
+            else if (x >= 0.23164)
+            {
+                double y = x-(tc-1.0);
+                double z = y*y;
+                double w = z*y;
+                double p1 = t[0]+w*(t[3]+w*(t[6]+w*(t[9] +w*t[12])));
+                double p2 = t[1]+w*(t[4]+w*(t[7]+w*(t[10]+w*t[13])));
+                double p3 = t[2]+w*(t[5]+w*(t[8]+w*(t[11]+w*t[14])));
+                double p  = z*p1-(tt-w*(p2+y*p3));
+                res += (tf + p);
+            }
+            else
+            {
+                double y = x;
+                double p1 = y*(u[0]+y*(u[1]+y*(u[2]+y*(u[3]+y*(u[4]+y*u[5])))));
+                double p2 = 1.0+y*(v[1]+y*(v[2]+y*(v[3]+y*(v[4]+y*v[5]))));
+                res += (-0.5*y + p1/p2);
+            }
+        }
+        else
+        {
+            res = 0.0;
+            if (x >= 1.7316)
+            {
+                double y = 2.0-x;
+                double z = y*y;
+                double p1 = a[0]+z*(a[2]+z*(a[4]+z*(a[6]+z*(a[8]+z*a[10]))));
+                double p2 = z*(a[1]+z*(a[3]+z*(a[5]+z*(a[7]+z*(a[9]+z*a[11])))));
+                double p  = y*p1+p2;
+                res  += (p-0.5*y);
+            }
+            else if(x >= 1.23164)
+            {
+                double y = x-tc;
+                double z = y*y;
+                double w = z*y;
+                double p1 = t[0]+w*(t[3]+w*(t[6]+w*(t[9] +w*t[12])));
+                double p2 = t[1]+w*(t[4]+w*(t[7]+w*(t[10]+w*t[13])));
+                double p3 = t[2]+w*(t[5]+w*(t[8]+w*(t[11]+w*t[14])));
+                double p  = z*p1-(tt-w*(p2+y*p3));
+                res += (tf + p);
+            }
+            else
+            {
+                double y = x-1.0;
+                double p1 = y*(u[0]+y*(u[1]+y*(u[2]+y*(u[3]+y*(u[4]+y*u[5])))));
+                double p2 = 1.0+y*(v[1]+y*(v[2]+y*(v[3]+y*(v[4]+y*v[5]))));
+                res += (-0.5*y + p1/p2);
+            }
+        }
+    }
+    else if(x < 8.0)
+    {
+        double i = std::floor(x);
+        double y = x-i;
+        double p = y*(s[0]+y*(s[1]+y*(s[2]+y*(s[3]+y*(s[4]+y*(s[5]+y*s[6]))))));
+        double q = 1.0+y*(r[1]+y*(r[2]+y*(r[3]+y*(r[4]+y*(r[5]+y*r[6])))));
+        res = 0.5*y+p/q;
+        double z = 1.0;
+        while (i > 2.0)
+        {
+            --i;
+            z *= (y+i);
+        }
+        res += std::log(z);
+    }
+    else if (x < 2.8823037615171174e+17)
+    {
+        double t = std::log(x);
+        double z = 1.0/x;
+        double y = z*z;
+        double yy = w[0]+z*(w[1]+y*(w[2]+y*(w[3]+y*(w[4]+y*(w[5]+y*w[6])))));
+        res = (x-0.5)*(t-1.0)+yy;
+    }
+    else
+    {
+        res =  x*(std::log(x) - 1.0);
+    }
+    
+    return res;
+}
+
+
+} // namespace detail
+
+    /** \brief The gamma function.
+
+        This function implements the algorithm from<br>
+        Zhang and Jin: "Computation of Special Functions", John Wiley and Sons, 1996.
+        
+        The argument must be <= 171.0 and cannot be zero or a negative integer. An
+        exception is thrown when these conditions are violated.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline double gamma(double x)
+{
+    return detail::GammaImpl<double>::gamma(x);
+}
+
+    /** \brief The natural logarithm of the gamma function.
+
+        This function is based on a free implementation by Sun Microsystems, Inc., see
+        <a href="http://www.sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/newlib/libm/mathfp/er_lgamma.c?rev=1.6&content-type=text/plain&cvsroot=src">sourceware.org</a> archive. It can be removed once all compilers support the new C99
+        math functions.
+        
+        The argument must be positive and < 1e30. An exception is thrown when these conditions are violated.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+inline double loggamma(double x)
+{
+    return detail::GammaImpl<double>::loggamma(x);
+}
+
+
+namespace detail {
+
+// both f1 and f2 are unsigned here
+template<class FPT>
+inline
+FPT safeFloatDivision( FPT f1, FPT f2 )
+{
+    return  f2 < NumericTraits<FPT>::one() && f1 > f2 * NumericTraits<FPT>::max()
+                ? NumericTraits<FPT>::max() 
+                : (f2 > NumericTraits<FPT>::one() && f1 < f2 * NumericTraits<FPT>::smallestPositive()) || 
+                   f1 == NumericTraits<FPT>::zero()
+                     ? NumericTraits<FPT>::zero() 
+                     : f1/f2;
+}
+
+} // namespace detail
+    
+    /** \brief Tolerance based floating-point comparison.
+
+        Check whether two floating point numbers are equal within the given tolerance.
+        This is useful because floating point numbers that should be equal in theory are
+        rarely exactly equal in practice. If the tolerance \a epsilon is not given,
+        twice the machine epsilon is used.
+
+        <b>\#include</b> \<vigra/mathutil.hxx\><br>
+        Namespace: vigra
+    */
+template <class T1, class T2>
+bool 
+closeAtTolerance(T1 l, T2 r, typename PromoteTraits<T1, T2>::Promote epsilon)
+{
+    typedef typename PromoteTraits<T1, T2>::Promote T;
+    if(l == 0.0)
+        return VIGRA_CSTD::fabs(r) <= epsilon;
+    if(r == 0.0)
+        return VIGRA_CSTD::fabs(l) <= epsilon;
+    T diff = VIGRA_CSTD::fabs( l - r );
+    T d1   = detail::safeFloatDivision<T>( diff, VIGRA_CSTD::fabs( r ) );
+    T d2   = detail::safeFloatDivision<T>( diff, VIGRA_CSTD::fabs( l ) );
+
+    return (d1 <= epsilon && d2 <= epsilon);
+}
+
+template <class T1, class T2>
+inline bool closeAtTolerance(T1 l, T2 r)
+{
+    typedef typename PromoteTraits<T1, T2>::Promote T;
+    return closeAtTolerance(l, r, T(2.0) * NumericTraits<T>::epsilon());
+}
+
+//@}
+
+} // namespace vigra
+
+#endif /* VIGRA_MATHUTIL_HXX */
diff --git a/include/vigra/matlab.hxx b/include/vigra/matlab.hxx
new file mode 100644
index 0000000..7cf565c
--- /dev/null
+++ b/include/vigra/matlab.hxx
@@ -0,0 +1,1304 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 2008 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_MATLAB_HXX
+#define VIGRA_MATLAB_HXX
+
+#include <string>
+
+#include "array_vector.hxx"
+#include "sized_int.hxx"
+#include "matrix.hxx"
+#include <map>
+#include <time.h>
+// This is needed with visual studio 10
+#ifdef _CHAR16T
+#define CHAR16_T
+#endif
+#include <mex.h>
+#include "matlab_FLEXTYPE.hxx"
+
+namespace vigra {
+
+namespace matlab {
+
+template <class T>
+struct ValueType;
+
+#define VIGRA_MATLAB_VALUETYPE_UTIL(type, functionName, typeID, matTypeName) \
+template <> \
+struct ValueType<type> \
+{ \
+    static bool check(mxArray const * t) \
+    { \
+        return mxIs##functionName(t); \
+    } \
+    \
+    static mxClassID const classID = typeID; \
+    \
+    static std::string typeName() \
+    { \
+        return #matTypeName; \
+    } \
+};
+
+VIGRA_MATLAB_VALUETYPE_UTIL(double, Double, mxDOUBLE_CLASS, double)
+VIGRA_MATLAB_VALUETYPE_UTIL(float, Single, mxSINGLE_CLASS, single)
+VIGRA_MATLAB_VALUETYPE_UTIL(Int8,  Int8, mxINT8_CLASS, int8)
+VIGRA_MATLAB_VALUETYPE_UTIL(UInt8,  Uint8, mxUINT8_CLASS, uint8)
+VIGRA_MATLAB_VALUETYPE_UTIL(Int16, Int16, mxINT16_CLASS, int16)
+VIGRA_MATLAB_VALUETYPE_UTIL(UInt16, Uint16, mxUINT16_CLASS, uint16)
+
+#if VIGRA_BITSOF_INT == 32
+VIGRA_MATLAB_VALUETYPE_UTIL(int, Int32, mxINT32_CLASS, int32)
+VIGRA_MATLAB_VALUETYPE_UTIL(unsigned int, Uint32, mxUINT32_CLASS, uint32)
+#elif VIGRA_BITSOF_INT == 64
+VIGRA_MATLAB_VALUETYPE_UTIL(int, Int64, mxINT64_CLASS, int64)
+VIGRA_MATLAB_VALUETYPE_UTIL(unsigned int, Uint64, mxUINT64_CLASS, uint64)
+#endif
+
+#if VIGRA_BITSOF_LONG == 32
+VIGRA_MATLAB_VALUETYPE_UTIL(long, Int32, mxINT32_CLASS, int32)
+VIGRA_MATLAB_VALUETYPE_UTIL(unsigned long, Uint32, mxUINT32_CLASS, uint32)
+#elif VIGRA_BITSOF_LONG == 64
+VIGRA_MATLAB_VALUETYPE_UTIL(long, Int64, mxINT64_CLASS, int64)
+VIGRA_MATLAB_VALUETYPE_UTIL(unsigned long, Uint64, mxUINT64_CLASS, uint64)
+#endif
+
+#if VIGRA_BITSOF_LONG_LONG == 32
+VIGRA_MATLAB_VALUETYPE_UTIL(long long, Int32, mxINT32_CLASS, int32)
+VIGRA_MATLAB_VALUETYPE_UTIL(unsigned long long, Uint32, mxUINT32_CLASS, uint32)
+#elif VIGRA_BITSOF_LONG_LONG == 64
+VIGRA_MATLAB_VALUETYPE_UTIL(long long, Int64, mxINT64_CLASS, int64)
+VIGRA_MATLAB_VALUETYPE_UTIL(unsigned long long, Uint64, mxUINT64_CLASS, uint64)
+#endif
+
+#undef VIGRA_MATLAB_VALUETYPE_UTIL
+
+class ConstStructArray
+{
+  protected:
+    mxArray * matPointer_;
+
+  public:
+
+    struct Proxy
+    {
+        mxArray * matPointer_;
+        int index_;
+
+        Proxy(mxArray * matPointer, int index)
+        : matPointer_(matPointer),
+          index_(index)
+        {}
+
+        operator const mxArray *() const
+        {
+            return mxGetFieldByNumber(matPointer_, 0, index_);
+        }
+    };
+
+    ConstStructArray(const mxArray * matPointer = 0)
+    : matPointer_(const_cast<mxArray *>(matPointer))
+    {
+        if(matPointer != 0 && !mxIsStruct(matPointer))
+            mexErrMsgTxt("StructArray(mxArray *): Argument must be a Matlab struct array.");
+    }
+
+    Proxy operator[](const char * field_name) const
+    {
+        if(matPointer_ == 0)
+            mexErrMsgTxt("StructArray::operator[]: Cannot access uninitialized struct array.");
+
+        int i = mxGetFieldNumber(matPointer_, field_name);
+        if(i == -1)
+            mexErrMsgTxt("StructArray::operator[]: Unknown field name.");
+
+        return Proxy(matPointer_, i);
+    }
+
+    Proxy operator[](std::string field_name) const
+    {
+        return operator[](field_name.c_str());
+    }
+
+    bool isValid() const
+    {
+        return matPointer_ != 0;
+    }
+
+    bool isValid(const char * field_name) const
+    {
+        return isValid() && mxGetFieldNumber(matPointer_, field_name) != -1;
+    }
+
+    bool isValid(std::string field_name) const
+    {
+        return isValid(field_name.c_str());
+    }
+};
+
+class ConstCellArray
+{
+  protected:
+    mxArray * matPointer_;
+    int size_;
+
+  public:
+
+    struct Proxy
+    {
+        mxArray * matPointer_;
+        int index_;
+
+        Proxy(mxArray * matPointer, int index)
+        : matPointer_(matPointer),
+          index_(index)
+        {}
+
+        operator const mxArray *() const
+        {
+            return mxGetCell(matPointer_, index_);
+        }
+    };
+
+    ConstCellArray(const mxArray * matPointer = 0)
+    : matPointer_(const_cast<mxArray *>(matPointer)),
+      size_(0)
+    {
+        if(matPointer != 0 && !mxIsCell(matPointer))
+            mexErrMsgTxt("CellArray(mxArray *): Argument must be a Matlab cell array.");
+        if(matPointer != 0)
+            size_ = static_cast<int>(mxGetNumberOfElements(matPointer));
+        else
+            size_ = -1;
+    }
+
+    Proxy operator[](int i) const
+    {
+        if(!isValid(i))
+            mexErrMsgTxt("CellArray::operator[]: Index out of range.");
+        return Proxy(matPointer_, i);
+    }
+
+    int size() const
+    {
+        return size_;
+    }
+
+    bool isValid( int i ) const
+    {
+        return i >= 0 && i < size_;
+    }
+
+};
+
+class CellArray
+: public ConstCellArray
+{
+  public:
+
+    struct Proxy
+    : public ConstCellArray::Proxy
+    {
+        Proxy(mxArray * matPointer, int index)
+        : ConstCellArray::Proxy(matPointer, index)
+        {}
+
+        void operator=(mxArray * v)
+        {
+            mxDestroyArray(mxGetCell(matPointer_, index_));
+            mxSetCell(matPointer_, index_, v);
+        }
+    };
+
+    CellArray(const mxArray * matPointer)
+    : ConstCellArray(matPointer)
+    {}
+
+    Proxy operator[](int i)
+    {
+        if(!isValid(i))
+            mexErrMsgTxt("CellArray::operator[]: Index out of range.");
+        return Proxy(matPointer_, i);
+    }
+
+    ConstCellArray::Proxy operator[](int i) const
+    {
+        if(!isValid(i))
+            mexErrMsgTxt("CellArray::operator[]: Index out of range.");
+        return ConstCellArray::Proxy(matPointer_, i);
+    }
+};
+
+
+
+
+
+template <class T, unsigned int SIZE>
+TinyVectorView<T, SIZE>
+getTinyVector(mxArray const * t)
+{
+    if(!ValueType<T>::check(t))
+    {
+        std::string msg = std::string("Input array must have type ") +
+                          ValueType<T>::typeName() + ".";
+        mexErrMsgTxt(msg.c_str());
+    }
+    if(SIZE != mxGetNumberOfElements(t))
+    {
+        mexErrMsgTxt("getTinyVector(): Input array has wrong number of elements.");
+    }
+
+    return TinyVectorView<T, SIZE>((T *)mxGetData(t));
+}
+
+template <unsigned int SIZE>
+typename MultiArrayShape<SIZE>::type
+getShape(mxArray const * t)
+{
+    if(!ValueType<Int32>::check(t))
+    {
+        std::string msg = std::string("Input array must have type 'int32'.");
+        mexErrMsgTxt(msg.c_str());
+    }
+    if(SIZE != mxGetNumberOfElements(t))
+    {
+        mexErrMsgTxt("getShape(): Input array has wrong number of elements.");
+    }
+    TinyVectorView<Int32, SIZE> res((MultiArrayIndex *)mxGetData(t));
+    return typename MultiArrayShape<SIZE>::type(res);
+}
+
+template <int DIM, class T>
+MultiArrayView<DIM, T>
+getMultiArray(mxArray const * t)
+{
+    typedef typename MultiArrayView<DIM, T>::difference_type Shape;
+
+    if(!ValueType<T>::check(t))
+    {
+        std::string msg = std::string("getMultiArray(): Input array must have type ") +
+                          ValueType<T>::typeName() + ".";
+        mexErrMsgTxt(msg.c_str());
+    }
+
+    Shape shape;
+    if(DIM > 1)
+    {
+        int mdim = mxGetNumberOfDimensions(t);
+        if(DIM < mdim)
+        {
+            mexErrMsgTxt("getMultiArray(): Input array has too many dimensions.");
+        }
+        const mwSize * matlabShape = mxGetDimensions(t);
+        for(int k=0; k<mdim; ++k)
+        {
+            shape[k] = static_cast<typename Shape::value_type>(matlabShape[k]);
+        }
+        for(int k=mdim; k<DIM; ++k)
+        {
+            shape[k] = 1;
+        }
+    }
+    else
+    {
+        shape[0] = static_cast<typename Shape::value_type>(mxGetNumberOfElements(t));
+    }
+    return MultiArrayView<DIM, T>(shape, (T *)mxGetData(t));
+}
+
+template <int DIM, class T>
+MultiArrayView<DIM, T>
+createMultiArray(typename MultiArrayShape<DIM>::type const & shape, mxArray * & t)
+{
+    mwSize matlabShape[DIM];
+    for(int k=0; k<DIM; ++k)
+        matlabShape[k] = static_cast<mwSize>(shape[k]);
+    t = mxCreateNumericArray(DIM, matlabShape, ValueType<T>::classID, mxREAL);
+
+    return MultiArrayView<DIM, T>(shape, (T *)mxGetData(t));
+}
+
+template <int DIM, class T>
+MultiArrayView<DIM, T>
+createMultiArray(typename MultiArrayShape<DIM>::type const & shape, CellArray::Proxy t)
+{
+    mwSize matlabShape[DIM];
+    for(int k=0; k<DIM; ++k)
+        matlabShape[k] = static_cast<mwSize>(shape[k]);
+    t = mxCreateNumericArray(DIM, matlabShape, ValueType<T>::classID, mxREAL);
+
+    return MultiArrayView<DIM, T>(shape, (T *)mxGetData(t));
+}
+
+template <class T>
+inline MultiArrayView<1, T>
+getArray(mxArray const * t)
+{
+    return getMultiArray<1, T>(t);
+}
+
+template <class T>
+inline MultiArrayView<1, T>
+createArray(MultiArrayIndex size, mxArray * & t)
+{
+    return createMultiArray<1, T>(MultiArrayShape<1>::type(size), t);
+}
+
+template <class T>
+inline MultiArrayView<1, T>
+createArray(MultiArrayIndex size, CellArray::Proxy t)
+{
+    return createMultiArray<1, T>(MultiArrayShape<1>::type(size), t);
+}
+
+template <class T>
+MultiArrayView<2, T>
+getMatrix(mxArray const * t)
+{
+    typedef typename MultiArrayView<2, T>::difference_type Shape;
+
+    if(!ValueType<T>::check(t))
+    {
+        std::string msg = std::string("getMatrix(): Input matrix must have type ") +
+                          ValueType<T>::typeName() + ".";
+        mexErrMsgTxt(msg.c_str());
+    }
+
+    if(2 != mxGetNumberOfDimensions(t))
+        mexErrMsgTxt("getMatrix(): Input matrix must have 2 dimensions.");
+
+    const mwSize * matlabShape = mxGetDimensions(t);
+    Shape shape(static_cast<MultiArrayIndex>(matlabShape[0]),
+                static_cast<MultiArrayIndex>(matlabShape[1]));
+
+    return MultiArrayView<2, T>(shape, (T *)mxGetData(t));
+}
+
+template <class T>
+MultiArrayView<2, T>
+createMatrix(mwSize rowCount, mwSize columnCount, mxArray * & t)
+{
+    typedef typename MultiArrayView<2, T>::difference_type Shape;
+
+    Shape shape(rowCount, columnCount);
+    t = mxCreateNumericMatrix(rowCount, columnCount, ValueType<T>::classID, mxREAL);
+
+    return MultiArrayView<2, T>(shape, (T *)mxGetData(t));
+}
+
+template <class T>
+MultiArrayView<2, T>
+createMatrix(mwSize rowCount, mwSize columnCount, CellArray::Proxy t)
+{
+    typedef typename MultiArrayView<2, T>::difference_type Shape;
+
+    Shape shape(rowCount, columnCount);
+    t = mxCreateNumericMatrix(rowCount, columnCount, ValueType<T>::classID, mxREAL);
+
+    return MultiArrayView<2, T>(shape, (T *)mxGetData(t));
+}
+
+template <class T>
+BasicImageView<T>
+getImage(mxArray const * t)
+{
+    if(!ValueType<T>::check(t))
+    {
+        std::string msg = std::string("getImage(): Input matrix must have type ") +
+                          ValueType<T>::typeName() + ".";
+        mexErrMsgTxt(msg.c_str());
+    }
+
+    if(2 != mxGetNumberOfDimensions(t))
+        mexErrMsgTxt("getImage(): Input matrix must have 2 dimensions.");
+
+    const mwSize * matlabShape = mxGetDimensions(t);
+    return BasicImageView<T>((T *)mxGetData(t), static_cast<int>(matlabShape[0]),
+                                                static_cast<int>(matlabShape[1]));
+}
+
+template <class T>
+BasicImageView<T>
+createImage(mwSize width, mwSize height, mxArray * & t)
+{
+    t = mxCreateNumericMatrix(width, height, ValueType<T>::classID, mxREAL);
+
+    return BasicImageView<T>((T *)mxGetData(t), width, height);
+}
+
+template <class T>
+BasicImageView<T>
+createImage(mwSize width, mwSize height, CellArray::Proxy t)
+{
+    t = mxCreateNumericMatrix(width, height, ValueType<T>::classID, mxREAL);
+
+    return BasicImageView<T>((T *)mxGetData(t), width, height);
+}
+
+inline ConstCellArray
+getCellArray(mxArray const * t)
+{
+    return ConstCellArray(t);
+}
+
+inline CellArray
+createCellArray(mwSize size, mxArray * & t)
+{
+    mwSize matSize[] = { size };
+    t = mxCreateCellArray(1, matSize);
+
+    return CellArray(t);
+}
+
+inline CellArray
+createCellArray(mwSize size, CellArray::Proxy t)
+{
+    mwSize matSize[] = { size };
+    t = mxCreateCellArray(1, matSize);
+
+    return CellArray(t);
+}
+
+inline ConstStructArray
+getStructArray(mxArray const * t)
+{
+    return ConstStructArray(t);
+}
+
+template<class T>
+T
+getScalar(mxArray const * t)
+{
+    if(mxIsEmpty(t))
+        mexErrMsgTxt("getScalar() on empty input.");
+    if(!mxIsNumeric(t) && !mxIsLogical(t))
+        mexErrMsgTxt("getScalar(): argument is not numeric.");
+    return static_cast<T>(mxGetScalar(t));
+}
+
+template<class T>
+mxArray *
+createScalar(T v)
+{
+    mxArray * m;
+    createMatrix<double>(1, 1, m)(0,0) = static_cast<double>(v);
+    return m;
+}
+
+inline std::string
+getString(mxArray const * t)
+{
+    if(mxIsEmpty(t))
+        mexErrMsgTxt("getString() on empty input.");
+    if(!mxIsChar(t))
+        mexErrMsgTxt("getString(): argument is not a string.");
+    int size = static_cast<int>(mxGetNumberOfElements(t) + 1);
+    ArrayVector<char> buf(size);
+    mxGetString(t, buf.begin(), size);
+    return std::string(buf.begin());
+}
+
+
+
+class CompileTimeError;
+
+namespace detail {
+
+class Required
+{
+  public:
+    void argumentWasProvided() const { /* empty because required arguments are always provided */ }
+};
+
+
+template<class T>
+class DefaultImpl
+{
+  public:
+
+    T defaultValue_;
+    mutable bool * argumentWasProvided_;
+
+    DefaultImpl(T v, bool * argFlag = 0)
+    : defaultValue_(v),
+      argumentWasProvided_(argFlag)
+    {
+        if(argumentWasProvided_ != 0)
+            *argumentWasProvided_ = false;
+    }
+
+    void argumentWasProvided() const
+    {
+        if(argumentWasProvided_ != 0)
+            *argumentWasProvided_ = true;
+    }
+};
+
+class OptionalImpl
+{
+  public:
+    mutable bool * argumentWasProvided_;
+
+    OptionalImpl(bool * argFlag = 0)
+    : argumentWasProvided_(argFlag)
+    {
+        if(argumentWasProvided_ != 0)
+            *argumentWasProvided_ = false;
+    }
+
+    void argumentWasProvided() const
+    {
+        if(argumentWasProvided_ != 0)
+            *argumentWasProvided_ = true;
+    }
+};
+
+} // namespace detail
+
+inline detail::Required v_required()
+{
+    return detail::Required();
+}
+
+template<class T>
+inline detail::DefaultImpl<T> v_default(T in)
+{
+    return detail::DefaultImpl<T>(in);
+}
+
+template<class T>
+inline detail::DefaultImpl<T> v_default(T in, bool & argFlag)
+{
+    return detail::DefaultImpl<T>(in, &argFlag);
+}
+
+inline detail::OptionalImpl v_optional()
+{
+    return detail::OptionalImpl();
+}
+
+inline detail::OptionalImpl v_optional(bool& argFlag)
+{
+    return detail::OptionalImpl(&argFlag);
+}
+
+// TODO:
+//    * handle rgb images
+//    * handle complex matrices
+//    * handle sparse matrices
+
+class InputArray
+{
+    int size_;
+    const mxArray ** data_;
+
+    std::string createErrMsg(std::string name)
+    {
+        std::string s1;
+        s1 =  "Required input '" + name + "' not found in option struct!";
+        return s1;
+    }
+    std::string createErrMsg(int pos)
+    {
+        char tmp[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+        std::string oi(1, tmp[pos%10]);
+        std::string s1  = "Required input in signature of function at position: '"+ oi+"' has not been supplied";
+        return s1;
+    }
+
+
+  public:
+    ConstStructArray options_;
+
+    /* Local Typedefs */
+    typedef const mxArray * value_type;
+    typedef value_type & reference;
+    typedef value_type const & const_reference;
+    typedef value_type * pointer;
+    typedef value_type const * const_pointer;
+    typedef int size_type;
+    typedef int difference_type;
+
+    /*Constructor*/
+    InputArray(size_type size, pointer data)
+    : size_(size),
+      data_(data),
+      options_(isValid(size-1) && mxIsStruct(data_[size-1])
+                 ? data_[size-1]
+                 : 0)
+    {}
+
+    /*Operators*/
+    const_reference operator[]( difference_type i ) const
+    {
+        if(!isValid(i))
+            mexErrMsgTxt("Too few input arguments.");
+        return data_[i];
+    }
+
+    value_type operator[]( std::string name) const
+    {
+        std::string errMsg = "Not Found " + name +" in OptionStruct or OptionStruct not set";
+        if(!isValid(name))
+            mexErrMsgTxt(errMsg.c_str());
+        return options_[name];
+    }
+
+
+    /*Some More Helper Func*/
+    size_type size() const
+    {
+        return size_;
+    }
+
+    bool isValid( difference_type i ) const
+    {
+        return i >= 0 && i < size_;
+    }
+
+    bool isValid(std::string name) const
+    {
+        return options_.isValid(name);
+    }
+
+    bool isEmpty(difference_type i) const
+    {
+        return mxIsEmpty(data_[i]);
+    }
+
+    bool isEmpty(std::string name) const
+    {
+        return mxIsEmpty(options_[name]);
+    }
+
+    bool hasData(difference_type i) const
+    {
+        return isValid(i) && !isEmpty(i);
+    }
+
+    bool hasData(std::string name) const
+    {
+        return isValid(name) && !isEmpty(name);
+    }
+
+    template<class Place>
+    mxClassID typeOf(Place posOrName)
+    {
+        return mxGetClassID((*this)[posOrName]);
+    }
+
+    /*Action to take if value not set*/
+    template <class T, class U, class Place>
+    T errorOrDefault(detail::DefaultImpl<U> const & o, Place posOrName)
+    {
+        return o.defaultValue_;
+    }
+
+    template <class T, class Place>
+    T errorOrDefault(detail::OptionalImpl, Place posOrName)
+    {
+        return T();
+    }
+
+    template <class T, class Place>
+    T errorOrDefault(detail::Required r, Place posOrName)
+    {
+        std::string a = createErrMsg(posOrName);
+        mexErrMsgTxt( a.c_str());
+        return T();
+    }
+
+    /*getter Func*/
+    template <class Place, class ReqType>
+    int getEnum(Place posOrName, ReqType req, std::map<std::string, int> const & converter)
+    {
+        if(!hasData(posOrName))
+        {
+            return errorOrDefault<int>(req, posOrName);
+        }
+        std::string enumAsString = matlab::getString((*this)[posOrName]);
+        typename std::map<std::string, int>::const_iterator m = converter.find(enumAsString);
+        if(m == converter.end())
+        {
+            std::string msg = std::string("Unknown option: ") + enumAsString + ".";
+            mexErrMsgTxt(msg.c_str());
+        }
+
+        req.argumentWasProvided();
+        return (*m).second;
+    }
+
+
+    /*String Type*/
+    template <class Place, class ReqType>
+    std::string getString(Place posOrName, ReqType req)
+    {
+        if(!hasData(posOrName))
+        {
+            return errorOrDefault<std::string>(req, posOrName);
+        }
+        else
+        {
+            req.argumentWasProvided();
+            return matlab::getString((*this)[posOrName]);
+        }
+    }
+
+    /*Scalar Type*/
+    template <class T,class Place, class ReqType>
+    T getScalar(Place posOrName, ReqType req)
+    {
+        if(!hasData(posOrName))
+        {
+            return errorOrDefault<T>(req, posOrName);
+        }
+        else
+        {
+            req.argumentWasProvided();
+            return matlab::getScalar<T>((*this)[posOrName]);
+        }
+    }
+
+
+    template <class T, class Place, class ReqType, class minClass, class maxClass>
+    T getScalarMinMax(Place posOrName, ReqType req, minClass min_, maxClass max_)
+    {
+        T temp = this->getScalar<T>(posOrName, req);
+        if (!is_in_range(temp, min_, max_))
+            mexErrMsgTxt("Value out of bounds.");
+        return temp;
+    }
+
+    template <class T, class Place, class ReqType, class iteratorType>
+    T getScalarVals(Place posOrName, ReqType req, iteratorType begin_, iteratorType end_)
+    {
+        T temp = this->getScalar<T>(posOrName, req);
+        for(iteratorType iter = begin_; iter != end_; ++iter)
+        {
+            if((*iter) == temp) return temp;
+        }
+        mexErrMsgTxt("Value not allowed");
+    }
+
+
+
+    template <class T, class Place, class ReqType, class iteratorType>
+    T getScalarVals2D3D(Place posOrName, ReqType req, iteratorType begin2D_, iteratorType end2D_,
+                                                     iteratorType begin3D_, iteratorType end3D_,
+                                                     int dimVar)
+    {
+        T temp = this->getScalar<T>(posOrName, req);
+        switch(dimVar)
+        {
+            case 2:
+                for(iteratorType iter = begin2D_; iter != end2D_; ++iter)
+                {
+                    if((*iter) == temp) return temp;
+                }
+                break;
+            case 3:
+                for(iteratorType iter = begin3D_; iter != end3D_; ++iter)
+                {
+                    if((*iter) == temp) return temp;
+                }
+                break;
+            default:
+                mexErrMsgTxt("dimVar specified must be 2 or 3");
+        }
+        mexErrMsgTxt("Value not allowed");
+    }
+
+    template <class Place, class ReqType>
+    bool getBool(Place posOrName, ReqType req)
+    {
+        return this->getScalarMinMax<int>(posOrName, req, 0, 1) != 0;
+    }
+
+    /*Array Type*/
+    template <unsigned int N, class T, class Place, class ReqType>
+    MultiArrayView<N,T> getMultiArray(Place posOrName, ReqType req)
+    {
+        if(!hasData(posOrName))
+        {
+            return errorOrDefault< MultiArrayView<N,T> >(req, posOrName);
+        }
+        else
+        {
+            req.argumentWasProvided();
+            value_type temp = (*this)[posOrName];
+            return matlab::getMultiArray<N,T>(temp);
+        }
+    }
+
+    template < class T, class Place, class ReqType>
+    BasicImageView<T> getImage(Place posOrName, ReqType req)
+    {
+        if(!hasData(posOrName))
+        {
+            return errorOrDefault<BasicImageView<T> >(req, posOrName);
+        }
+        else
+        {
+            req.argumentWasProvided();
+            value_type temp = (*this)[posOrName];
+            return matlab::getImage<T>(temp);
+        }
+    }
+
+    template<class T,unsigned int sze, class Place, class ReqType>
+    TinyVectorView< T, sze> getTinyVector(Place posOrName, ReqType req)
+    {
+        if(!hasData(posOrName))
+        {
+            return errorOrDefault<TinyVectorView< T, sze> >(req, posOrName);
+        }
+        else
+        {
+            req.argumentWasProvided();
+            value_type temp = (*this)[posOrName];
+            return matlab::getTinyVector< T, sze>(temp);
+        }
+    }
+
+    template< unsigned int sze, class Place, class ReqType>
+    TinyVectorView<MultiArrayIndex, sze> getShape(Place posOrName, ReqType req)
+    {
+        if(!hasData(posOrName))
+        {
+            return errorOrDefault<TinyVectorView<MultiArrayIndex, sze> >(req, posOrName);
+        }
+        else
+        {
+            req.argumentWasProvided();
+            value_type temp = (*this)[posOrName];
+            return matlab::getShape<sze>(temp);
+        }
+    }
+
+
+    template< class Place, class ReqType>
+    int getDimOfInput(Place posOrName, ReqType req)
+    {
+        if(!hasData(posOrName))
+        {
+            return errorOrDefault<int>(req, posOrName);
+        }
+        else
+        {
+            req.argumentWasProvided();
+            return mxGetNumberOfDimensions((*this)[posOrName]);
+        }
+    }
+
+    template<class ReqType>
+    ConstCellArray getCellArray(int posOrName, ReqType req)
+    {
+        if(!hasData(posOrName))
+        {
+            return errorOrDefault<ConstCellArray>(req, posOrName);
+        }
+        else
+        {
+            req.argumentWasProvided();
+            value_type temp = (*this)[posOrName];
+            return matlab::getCellArray(temp);
+        }
+    }
+
+    template<class ReqType>
+    ConstCellArray getCellArray(std::string posOrName, ReqType req)
+    {
+        CompileTimeError ERROR__Const_Cell_Array_May_Not_Be_In_Option_Struct;
+        return ConstCellArray(); //avoid compiler warning
+    }
+
+};
+
+class OutputArray
+{
+    int size_;
+    mxArray ** data_;
+    std::string createErrMsgOut(int pos)
+    {
+        char tmp[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+        std::string oi(1, tmp[pos%10]);
+        std::string s1 =  "Required Output at position: '" + oi + "' has not been supplied";
+        return s1;
+    }
+  public:
+
+    typedef mxArray * value_type;
+    typedef value_type & reference;
+    typedef value_type const & const_reference;
+    typedef value_type * pointer;
+    typedef value_type const * const_pointer;
+    typedef int size_type;
+    typedef int difference_type;
+
+    OutputArray(size_type size, pointer data)
+    : size_(size),
+      data_(data)
+    {}
+
+    reference operator[]( difference_type i )
+    {
+        if(!isValid(i))
+            mexErrMsgTxt("Too few output arguments.");
+        return data_[i];
+    }
+
+    const_reference operator[]( difference_type i ) const
+    {
+        if(!isValid(i))
+            mexErrMsgTxt("Too few output arguments.");
+        return data_[i];
+    }
+
+    size_type size() const
+    {
+        return size_;
+    }
+
+    bool isValid( difference_type i ) const
+    {
+        return i >= 0 && i < size_;
+    }
+
+    bool isEmpty(difference_type i){
+        return mxIsEmpty(data_[i]);
+    }
+
+    template <class T>
+    T errorOrDefault(detail::OptionalImpl const & o, int Pos)
+    {
+        return T();
+    }
+
+    template <class T>
+    T errorOrDefault(detail::Required r, int Pos)
+    {
+        mexErrMsgTxt(createErrMsgOut(Pos).c_str());
+        return T();
+    }
+
+    /* creating func */
+    template <unsigned int DIM, class T, class ReqType>
+    MultiArrayView<DIM, T> createMultiArray(int pos,ReqType req,
+                                            const TinyVector<int, DIM>  & shape)
+    {
+        if(!isValid(pos))
+            return errorOrDefault<MultiArrayView<DIM, T> >(req, pos);
+        req.argumentWasProvided();
+        return matlab::createMultiArray<DIM, T>(shape, (*this)[pos]);
+    }
+
+    template <class T, class ReqType>
+    BasicImageView<T> createImage(int pos, ReqType req,
+                                    mwSize width, mwSize height)
+    {
+        if(!isValid(pos))
+            return errorOrDefault<BasicImageView<T> >(req, pos);
+        req.argumentWasProvided();
+        return matlab::createImage<T>(width, height, (*this)[pos]);
+    }
+
+    template <class T, class ReqType>
+    BasicImageView<T> createImage(  int pos, ReqType req,
+                                    typename MultiArrayShape<2>::type const & shape)
+    {
+        return createImage<T>(pos, req, shape[1], shape[0]);
+    }
+
+    template <class T, class ReqType>
+    T* createScalar(int pos, ReqType req)
+    {
+        if(!isValid(pos))
+            return errorOrDefault<T*>(req, pos);
+        req.argumentWasProvided();
+        BasicImageView<T> temp = matlab::createImage<T>(1, 1, (*this)[pos]);
+        return &temp(0,0);
+    }
+
+    template <class T, class ReqType>
+    void createScalar(int pos, ReqType req, T val)
+    {
+        if(!isValid(pos))
+        {
+            errorOrDefault<T>(req, pos);
+            return;
+        }
+        req.argumentWasProvided();
+        BasicImageView<T> temp = matlab::createImage<T>(1, 1, (*this)[pos]);
+        temp(0,0) = val;
+    }
+
+    template <class ReqType>
+    ConstCellArray createCellArray(int pos, ReqType req, mwSize sze)
+    {
+        if(!isValid(pos))
+            return errorOrDefault<ConstCellArray>(req, pos);
+        return matlab::createCellArray(sze, (*this)[pos]);
+    }
+};
+
+
+
+/***********************************
+Rahuls code starts here
+************************************/
+using namespace vigra;
+
+
+/*++++++++++++++++++++++++++HELPERFUNC+++++++++++++++++++++++++++++++*
+ * This is used for better readability of the test cases            .
+ * Nothing to be done here.
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+int cantorPair(int x, int y){
+        return (int)(((x+y)*(x+y+1))/2+y);
+}
+
+int cantorPair(int x, int y, int z){
+        return cantorPair(cantorPair(x,y),z);
+}
+
+template <int x, int y>
+struct cP{
+    enum { value = (int)(((x+y)*(x+y+1))/2+y)};
+};
+
+template <int x, int y, int z>
+struct cP3{
+    enum { value = cP<cP<x, y>::value, z>::value};
+};
+
+template <class T>
+inline bool is_in_range(T in, T min, T max)
+{
+    return (in >= min && in <= max);
+}
+template<class T>
+inline bool is_in_range(T in, std::string min, T max)
+{
+    return(in <= max);
+}
+
+template<class T>
+inline bool is_in_range(T in, T min, std::string max)
+{
+    return (in >= min);
+}
+
+
+
+//Wrapper classes to STL-Map for use as a sparse array.
+
+//This is used for the ordering of the map. Lexicographical ordering of the index pairs.
+struct ShapeCmp {
+  bool operator()( TinyVector<int,2> s1, TinyVector<int,2>  s2 ) const {
+    if(s1[0] != s2[0]){
+        return (s1[0] < s2[0]);
+    } else {
+        return s1[1] < s2[1];
+    }
+  }
+};
+
+template<class T>
+class SparseArray
+{
+
+    std::map<TinyVector<int,2>, T,ShapeCmp> data;
+    int width, length;
+
+    public:
+    void assign(int i = 1, int j = 1){
+        width = j;
+        length = i;
+    }
+    SparseArray(int i = 1 , int j = 1){
+        width = j;
+        length = i;
+    }
+
+    //Any better idea? i would like to unify the get and operator() functions.
+    // Problem is that  operator() always passes a reference or creates one.
+    template<class indexType>
+    T& operator()(indexType i_, indexType j_){
+        Int32 i = static_cast<Int32>(i_);
+        Int32 j = static_cast<Int32>(j_);
+        TinyVector<int,2> newShapew(i, j);
+        typename std::map<TinyVector<int,2>, T, ShapeCmp>::iterator iter;
+        TinyVector<int,2> newShape;
+        return data[newShapew];
+    }
+
+    template<class indexType>
+    const T get(indexType i_, indexType j_){
+        Int32 i = static_cast<Int32>(i_);
+        Int32 j = static_cast<Int32>(j_);
+        TinyVector<int,2> newShape(i, j);
+        if(data.find(newShape) == data.end()) return 0;
+        else return data.find(newShape)->second;
+    }
+
+    //see documentation of mxCreateSparse and the mxGet functions to understand this.
+    void mapToMxArray(mxArray * & in){
+
+        int len = data.size();
+        in = mxCreateSparse(width, length, len, mxREAL);
+        int* jc = mxGetJc(in);
+        int* ir = mxGetIr(in);
+        double* pr = mxGetPr(in);
+        if(len == 0){
+            jc[0] = 1;
+            return;
+        }
+        typename std::map<TinyVector<int,2>, T, ShapeCmp>::iterator iter;
+        TinyVector<int,2> newShape;
+        int ii = 0;
+        int jj = 0;
+        int curjc = -1;
+        for( iter = data.begin(); iter != data.end(); ++iter ) {
+            newShape = iter->first;
+            ir[ii] = newShape[1];
+            pr[ii] = iter->second;
+            if(newShape[0]  != curjc){
+                curjc = newShape[0] ;
+                jc[jj] = ii;
+                jj++;
+            }
+
+            ii++;
+        }
+        jc[jj] = len;
+    }
+
+};
+
+enum DataDimension {IMAGE = 2, VOLUME = 3};
+
+} // namespace matlab
+
+} // namespace vigra
+
+void vigraMexFunction(vigra::matlab::OutputArray, vigra::matlab::InputArray);
+
+#ifndef VIGRA_CUSTOM_MEXFUNCTION
+
+/*
+    DO NOT Comment out this function. If you are using a
+    custom mexfunction just #define VIGRA_CUSTOM_MEXFUNCTION
+    before #including matlab.hxx.
+*/
+void mexFunction(int nlhs, mxArray *plhs[],
+                 int nrhs, const mxArray *prhs[])
+{
+  try
+  {
+    vigra::matlab::InputArray inputs(nrhs, prhs);
+    vigra::matlab::OutputArray outputs(nlhs, plhs);
+
+    vigraMexFunction(outputs, inputs);
+  }
+  catch(std::exception & e)
+  {
+    mexErrMsgTxt(e.what());
+  }
+}
+
+#endif /*CUSTOM_MEXFUNCTION*/
+
+
+#define VIGRA_CREATE_ENUM_AND_STD_MAP2(mapName, item1, item2) \
+    const int item1 = 1;\
+    const int item2 = 2;\
+    std::map<std::string,int>  mapName;\
+    mapName[#item1] = (int)item1;\
+    mapName[#item2] = (int)item2;\
+
+
+#define VIGRA_CREATE_ENUM_AND_STD_MAP3(mapName, item1, item2, item3) \
+    const int item1 = 1;\
+    const int item2 = 2;\
+    const int item3 = 3;\
+    std::map<std::string,int>  mapName;\
+    mapName[#item1] = (int)item1;\
+    mapName[#item2] = (int)item2;\
+    mapName[#item3] = (int)item3;\
+
+
+#define VIGRA_CREATE_ENUM_AND_STD_MAP4(mapName, item1, item2, item3, item4) \
+    const int item1 = 1;\
+    const int item2 = 2;\
+    const int item3 = 3;\
+    const int item4 = 4;\
+    std::map<std::string,int>  mapName;\
+    mapName[#item1] = (int)item1;\
+    mapName[#item2] = (int)item2;\
+    mapName[#item3] = (int)item3;\
+    mapName[#item4] = (int)item4;\
+
+#define VIGRA_CREATE_ENUM_AND_STD_MAP5(mapName, item1, item2, item3, item4, item5) \
+    const int item1 = 1;\
+    const int item2 = 2;\
+    const int item3 = 3;\
+    const int item4 = 4;\
+    const int item5 = 5;\
+    std::map<std::string, int>  mapName;\
+    mapName[#item1] = (int)item1;\
+    mapName[#item2] = (int)item2;\
+    mapName[#item3] = (int)item3;\
+    mapName[#item4] = (int)item4;\
+    mapName[#item5] = (int)item5;\
+
+#define VIGRA_CREATE_ENUM_AND_STD_MAP6(mapName, item1, item2, item3, item4, item5, item6) \
+    const int item1 = 1;\
+    const int item2 = 2;\
+    const int item3 = 3;\
+    const int item4 = 4;\
+    const int item5 = 5;\
+    const int item6 = 6;\
+    std::map<std::string,int>  mapName;\
+    mapName[#item1] = (int)item1;\
+    mapName[#item2] = (int)item2;\
+    mapName[#item3] = (int)item3;\
+    mapName[#item4] = (int)item4;\
+    mapName[#item5] = (int)item5;\
+    mapName[#item6] = (int)item6;\
+
+#endif // VIGRA_MATLAB_HXX
diff --git a/include/vigra/matlab_FLEXTYPE.hxx b/include/vigra/matlab_FLEXTYPE.hxx
new file mode 100644
index 0000000..9c7c4fd
--- /dev/null
+++ b/include/vigra/matlab_FLEXTYPE.hxx
@@ -0,0 +1,232 @@
+/************************************************************************/
+/*                                                                      */
+/*                    Copyright 2009 by Rahul Nair                      */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <string>
+#ifndef MATLAB_FLEXTYPE
+#define MATLAB_FLEXTYPE
+
+
+
+#define NOFLEXIBLETYPE vigraMain(outputs, inputs);
+
+
+#define FLEX_TYPE(inClass, pos, name)\
+    std::string name_str(#name);\
+    if ((1##pos##1) != 0 && ((pos < inputs.size()-1) || pos == (inputs.size()-1) && !inputs.options_.isValid()))\
+    {\
+        inClass = mxGetClassID(inputs[pos]);\
+    }\
+    else\
+    {\
+        if(!inputs.options_.isValid())\
+            mexErrMsgTxt("Input at (Position: pos, Name in Struct: name) not set");\
+        inClass = mxGetClassID(inputs.options_[#name]);\
+    }\
+
+#define DEFAULT_ERROR\
+    default:\
+    std::string msg = "Invalid Inputtype for data element '" + name_str + "' - see documentation for supported Types";\
+    mexErrMsgTxt(msg.c_str());\
+
+
+#define FLEXIBLE_TYPE_START(pos, name)\
+    mxClassID inClass;\
+    std::string name_str(#name);\
+    if ((1##pos##1) != 0 && ((pos < inputs.size()-1) || pos == (inputs.size()-1) && !inputs.options_.isValid()))\
+    {\
+        inClass = mxGetClassID(inputs[pos]);\
+    }\
+    else\
+    {\
+        if(!inputs.options_.isValid())\
+            mexErrMsgTxt("Input at (Position: pos, Name in Struct: name) not set");\
+        inClass = mxGetClassID(inputs.options_[#name]);\
+    }\
+    switch(inClass){\
+
+
+
+#define FLEXIBLE_TYPE_END\
+    default:\
+    std::string msg = "Invalid Inputtype for data element " + name_str + " - see documentation for supported Types";\
+    mexErrMsgTxt(msg.c_str());\
+    }
+
+
+/*UINT*/
+
+#define ALLOW_UINT\
+        case mxUINT8_CLASS:\
+            vigraMain<UInt8>(outputs, inputs);     break;\
+        case mxUINT16_CLASS:\
+            vigraMain<UInt16>(outputs, inputs);    break;\
+        case mxUINT32_CLASS:\
+            vigraMain<UInt32>(outputs, inputs);    break;\
+        case mxUINT64_CLASS:\
+            vigraMain<UInt64>(outputs, inputs);    break;
+
+
+#define ALLOW_UINT_8\
+        case mxUINT8_CLASS:\
+            vigraMain<UInt8>(outputs, inputs);     break;
+
+#define ALLOW_UINT_16\
+        case mxUINT16_CLASS:\
+            vigraMain<UInt16>(outputs, inputs);     break;
+
+#define ALLOW_UINT_32\
+        case mxUINT32_CLASS:\
+            vigraMain<UInt32>(outputs, inputs);     break;
+
+#define ALLOW_UINT_64\
+        case mxUINT64_CLASS:\
+            vigraMain<UInt64>(outputs, inputs);     break;
+
+#define ALLOW_UINT_8_16\
+        case mxUINT8_CLASS:\
+            vigraMain<UInt8>(outputs, inputs);     break;\
+        case mxUINT16_CLASS:\
+            vigraMain<UInt16>(outputs, inputs);    break;
+
+#define ALLOW_UINT_16_32\
+        case mxUINT16_CLASS:\
+            vigraMain<UInt16>(outputs, inputs);     break;\
+        case mxUINT32_CLASS:\
+            vigraMain<UInt32>(outputs, inputs);    break;
+
+#define ALLOW_UINT_32_64\
+        case mxUINT16_CLASS:\
+            vigraMain<UInt32>(outputs, inputs);     break;\
+        case mxUINT32_CLASS:\
+            vigraMain<UInt64>(outputs, inputs);    break;
+
+#define ALLOW_UINT_8_32\
+        case mxUINT8_CLASS:\
+            vigraMain<UInt8>(outputs, inputs);     break;\
+        case mxUINT16_CLASS:\
+            vigraMain<UInt16>(outputs, inputs);    break;\
+        case mxUINT32_CLASS:\
+            vigraMain<UInt32>(outputs, inputs);    break;
+
+#define ALLOW_UINT_16_64\
+        case mxUINT16_CLASS:\
+            vigraMain<UInt16>(outputs, inputs);    break;\
+        case mxUINT32_CLASS:\
+            vigraMain<UInt32>(outputs, inputs);    break;\
+        case mxUINT64_CLASS:\
+            vigraMain<UInt64>(outputs, inputs);     break;
+
+
+/*INT*/
+#define ALLOW_INT\
+        case mxINT8_CLASS:\
+            vigraMain<Int8>(outputs, inputs);     break;\
+        case mxINT16_CLASS:\
+            vigraMain<Int16>(outputs, inputs);    break;\
+        case mxINT32_CLASS:\
+            vigraMain<Int32>(outputs, inputs);    break;\
+        case mxINT64_CLASS:\
+            vigraMain<Int64>(outputs, inputs);    break;
+
+#define ALLOW_INT_8_64 ALLOW_INT;
+#define ALLOW_UINT_8_64 ALLOW_UINT;
+
+#define ALLOW_INT_8\
+        case mxINT8_CLASS:\
+            vigraMain<Int8>(outputs, inputs);     break;
+
+#define ALLOW_INT_16\
+        case mxINT16_CLASS:\
+            vigraMain<Int16>(outputs, inputs);     break;
+
+#define ALLOW_INT_32\
+        case mxINT32_CLASS:\
+            vigraMain<Int32>(outputs, inputs);     break;
+
+#define ALLOW_INT_64\
+        case mxINT64_CLASS:\
+            vigraMain<Int64>(outputs, inputs);     break;
+
+#define ALLOW_INT_8_16\
+        case mxINT8_CLASS:\
+            vigraMain<Int8>(outputs, inputs);     break;\
+        case mxINT16_CLASS:\
+            vigraMain<Int16>(outputs, inputs);    break;
+
+#define ALLOW_INT_16_32\
+        case mxINT16_CLASS:\
+            vigraMain<Int16>(outputs, inputs);     break;\
+        case mxINT32_CLASS:\
+            vigraMain<Int32>(outputs, inputs);    break;
+
+#define ALLOW_INT_32_64\
+        case mxINT16_CLASS:\
+            vigraMain<Int32>(outputs, inputs);     break;\
+        case mxINT32_CLASS:\
+            vigraMain<Int64>(outputs, inputs);    break;
+
+#define ALLOW_INT_8_32\
+        case mxINT8_CLASS:\
+            vigraMain<Int8>(outputs, inputs);     break;\
+        case mxINT16_CLASS:\
+            vigraMain<Int16>(outputs, inputs);    break;\
+        case mxINT32_CLASS:\
+            vigraMain<Int32>(outputs, inputs);    break;
+
+#define ALLOW_INT_16_64\
+        case mxINT16_CLASS:\
+            vigraMain<Int16>(outputs, inputs);    break;\
+        case mxINT32_CLASS:\
+            vigraMain<Int32>(outputs, inputs);    break;\
+        case mxINT64_CLASS:\
+            vigraMain<Int64>(outputs, inputs);     break;
+
+/*Float double*/
+
+#define ALLOW_FD\
+        case mxDOUBLE_CLASS:\
+            vigraMain<double>(outputs, inputs);    break;\
+        case mxSINGLE_CLASS:\
+            vigraMain<float>(outputs, inputs);     break;
+
+#define ALLOW_F\
+        case mxSINGLE_CLASS:\
+            vigraMain<float>(outputs, inputs);     break;
+
+#define ALLOW_D\
+        case mxDOUBLE_CLASS:\
+            vigraMain<double>(outputs, inputs);    break;
+
+#endif
diff --git a/include/vigra/matrix.hxx b/include/vigra/matrix.hxx
new file mode 100644
index 0000000..9a34c78
--- /dev/null
+++ b/include/vigra/matrix.hxx
@@ -0,0 +1,3026 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2003-2008 by Gunnar Kedenburg and Ullrich Koethe       */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_MATRIX_HXX
+#define VIGRA_MATRIX_HXX
+
+#include <cmath>
+#include <iosfwd>
+#include <iomanip>
+#include "multi_array.hxx"
+#include "mathutil.hxx"
+#include "numerictraits.hxx"
+#include "multi_pointoperators.hxx"
+
+
+namespace vigra
+{
+
+/** \defgroup LinearAlgebraModule Linear Algebra
+
+    \brief Classes and functions for matrix algebra, linear equations systems, eigen systems, least squares etc.
+*/
+
+/** \ingroup LinearAlgebraModule
+
+    Namespace <tt>vigra/linalg</tt> hold VIGRA's linear algebra functionality. But most of its contents
+    is exported into namespace <tt>vigra</tt> via <tt>using</tt> directives.
+*/
+namespace linalg
+{
+
+template <class T, class C>
+inline MultiArrayIndex 
+rowCount(const MultiArrayView<2, T, C> &x);
+
+template <class T, class C>
+inline MultiArrayIndex 
+columnCount(const MultiArrayView<2, T, C> &x);
+
+template <class T, class C>
+inline MultiArrayView <2, T, C>
+rowVector(MultiArrayView <2, T, C> const & m, MultiArrayIndex d);
+
+template <class T, class C>
+inline MultiArrayView <2, T, C>
+columnVector(MultiArrayView<2, T, C> const & m, MultiArrayIndex d);
+
+template <class T, class ALLOC = std::allocator<T> >
+class TemporaryMatrix;
+
+template <class T, class C1, class C2>
+void transpose(const MultiArrayView<2, T, C1> &v, MultiArrayView<2, T, C2> &r);
+
+template <class T, class C>
+bool isSymmetric(const MultiArrayView<2, T, C> &v);
+
+enum RawArrayMemoryLayout { RowMajor, ColumnMajor };
+
+/********************************************************/
+/*                                                      */
+/*                        Matrix                        */
+/*                                                      */
+/********************************************************/
+
+/** Matrix class. 
+
+    \ingroup LinearAlgebraModule 
+
+    This is the basic class for all linear algebra computations. Matrices are
+    stored in a <i>column-major</i> format, i.e. the row index is varying fastest.
+    This is the same format as in the lapack and gmm++ libraries, so it will
+    be easy to interface these libraries. In fact, if you need optimized
+    high performance code, you should use them. The VIGRA linear algebra
+    functionality is provided for smaller problems and rapid prototyping
+    (no one wants to spend half the day installing a new library just to
+    discover that the new algorithm idea didn't work anyway).
+
+    <b>See also:</b>
+    <ul>
+    <li> \ref LinearAlgebraFunctions
+    </ul>
+
+    <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+    <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+    Namespaces: vigra and vigra::linalg
+*/
+template <class T, class ALLOC = std::allocator<T> >
+class Matrix
+: public MultiArray<2, T, ALLOC>
+{
+    typedef MultiArray<2, T, ALLOC> BaseType;
+
+  public:
+    typedef Matrix<T, ALLOC>                        matrix_type;
+    typedef TemporaryMatrix<T, ALLOC>               temp_type;
+    typedef MultiArrayView<2, T>                    view_type;
+    typedef typename BaseType::value_type           value_type;
+    typedef typename BaseType::pointer              pointer;
+    typedef typename BaseType::const_pointer        const_pointer;
+    typedef typename BaseType::reference            reference;
+    typedef typename BaseType::const_reference      const_reference;
+    typedef typename BaseType::difference_type      difference_type;
+    typedef typename BaseType::difference_type_1    difference_type_1;
+    typedef ALLOC                                   allocator_type;
+
+        /** default constructor
+         */
+    Matrix()
+    {}
+
+        /** construct with given allocator
+         */
+    explicit Matrix(ALLOC const & alloc)
+    : BaseType(alloc)
+    {}
+
+        /** construct with given shape and init all
+            elements with zero. Note that the order of the axes is
+            <tt>difference_type(rows, columns)</tt> which
+            is the opposite of the usual VIGRA convention.
+         */
+    explicit Matrix(const difference_type &shape,
+                    ALLOC const & alloc = allocator_type())
+    : BaseType(shape, alloc)
+    {}
+
+        /** construct with given shape and init all
+            elements with zero. Note that the order of the axes is
+            <tt>(rows, columns)</tt> which
+            is the opposite of the usual VIGRA convention.
+         */
+    Matrix(difference_type_1 rows, difference_type_1 columns,
+                    ALLOC const & alloc = allocator_type())
+    : BaseType(difference_type(rows, columns), alloc)
+    {}
+
+        /** construct with given shape and init all
+            elements with the constant \a init. Note that the order of the axes is
+            <tt>difference_type(rows, columns)</tt> which
+            is the opposite of the usual VIGRA convention.
+         */
+    Matrix(const difference_type &shape, const_reference init,
+           allocator_type const & alloc = allocator_type())
+    : BaseType(shape, init, alloc)
+    {}
+
+        /** construct with given shape and init all
+            elements with the constant \a init. Note that the order of the axes is
+            <tt>(rows, columns)</tt> which
+            is the opposite of the usual VIGRA convention.
+         */
+    Matrix(difference_type_1 rows, difference_type_1 columns, const_reference init,
+           allocator_type const & alloc = allocator_type())
+    : BaseType(difference_type(rows, columns), init, alloc)
+    {}
+
+        /** construct with given shape and copy data from C-style array \a init.
+            Unless \a layout is <tt>ColumnMajor</tt>, the elements in this array
+            are assumed to be given in row-major order (the C standard order) and
+            will automatically be converted to the required column-major format.
+            Note that the order of the axes is <tt>difference_type(rows, columns)</tt> which
+            is the opposite of the usual VIGRA convention.
+         */
+    Matrix(const difference_type &shape, const_pointer init, RawArrayMemoryLayout layout = RowMajor,
+           allocator_type const & alloc = allocator_type())
+    : BaseType(shape, alloc) // FIXME: this function initializes the memory twice
+    {
+        if(layout == RowMajor)
+        {
+            difference_type trans(shape[1], shape[0]);
+            linalg::transpose(MultiArrayView<2, T>(trans, const_cast<pointer>(init)), *this);
+        }
+        else
+        {
+            std::copy(init, init + elementCount(), this->data());
+        }
+    }
+
+        /** construct with given shape and copy data from C-style array \a init.
+            Unless \a layout is <tt>ColumnMajor</tt>, the elements in this array
+            are assumed to be given in row-major order (the C standard order) and
+            will automatically be converted to the required column-major format.
+            Note that the order of the axes is <tt>(rows, columns)</tt> which
+            is the opposite of the usual VIGRA convention.
+         */
+    Matrix(difference_type_1 rows, difference_type_1 columns, const_pointer init, RawArrayMemoryLayout layout = RowMajor,
+           allocator_type const & alloc = allocator_type())
+    : BaseType(difference_type(rows, columns), alloc) // FIXME: this function initializes the memory twice
+    {
+        if(layout == RowMajor)
+        {
+            difference_type trans(columns, rows);
+            linalg::transpose(MultiArrayView<2, T>(trans, const_cast<pointer>(init)), *this);
+        }
+        else
+        {
+            std::copy(init, init + elementCount(), this->data());
+        }
+    }
+
+        /** copy constructor. Allocates new memory and
+            copies tha data.
+         */
+    Matrix(const Matrix &rhs)
+    : BaseType(rhs)
+    {}
+
+        /** construct from temporary matrix, which looses its data.
+
+            This operation is equivalent to
+            \code
+                TemporaryMatrix<T> temp = ...;
+
+                Matrix<T> m;
+                m.swap(temp);
+            \endcode
+         */
+    Matrix(const TemporaryMatrix<T, ALLOC> &rhs)
+    : BaseType(rhs.allocator())
+    {
+        this->swap(const_cast<TemporaryMatrix<T, ALLOC> &>(rhs));
+    }
+
+        /** construct from a MultiArrayView. Allocates new memory and
+            copies tha data. \a rhs is assumed to be in column-major order already.
+         */
+    template<class U, class C>
+    Matrix(const MultiArrayView<2, U, C> &rhs)
+    : BaseType(rhs)
+    {}
+
+        /** assignment.
+            If the size of \a rhs is the same as the matrix's old size, only the data
+            are copied. Otherwise, new storage is allocated, which invalidates
+            all objects (array views, iterators) depending on the matrix.
+         */
+    Matrix & operator=(const Matrix &rhs)
+    {
+        BaseType::operator=(rhs); // has the correct semantics already
+        return *this;
+    }
+
+        /** assign a temporary matrix. If the shapes of the two matrices match,
+            only the data are copied (in order to not invalidate views and iterators
+            depending on this matrix). Otherwise, the memory is swapped
+            between the two matrices, so that all depending objects
+            (array views, iterators) ar invalidated.
+         */
+    Matrix & operator=(const TemporaryMatrix<T, ALLOC> &rhs)
+    {
+        if(this->shape() == rhs.shape())
+            this->copy(rhs);
+        else
+            this->swap(const_cast<TemporaryMatrix<T, ALLOC> &>(rhs));
+        return *this;
+    }
+
+        /** assignment from arbitrary 2-dimensional MultiArrayView.<br>
+            If the size of \a rhs is the same as the matrix's old size, only the data
+            are copied. Otherwise, new storage is allocated, which invalidates
+            all objects (array views, iterators) depending on the matrix.
+            \a rhs is assumed to be in column-major order already.
+         */
+    template <class U, class C>
+    Matrix & operator=(const MultiArrayView<2, U, C> &rhs)
+    {
+        BaseType::operator=(rhs); // has the correct semantics already
+        return *this;
+    }
+
+        /** assignment from scalar.<br>
+            Equivalent to Matrix::init(v).
+         */
+    Matrix & operator=(value_type const & v)
+    {
+        return init(v);
+    }
+
+         /** init elements with a constant
+         */
+    template <class U>
+    Matrix & init(const U & init)
+    {
+        BaseType::init(init);
+        return *this;
+    }
+
+       /** reshape to the given shape and initialize with zero.
+         */
+    void reshape(difference_type_1 rows, difference_type_1 columns)
+    {
+        BaseType::reshape(difference_type(rows, columns));
+    }
+
+        /** reshape to the given shape and initialize with \a init.
+         */
+    void reshape(difference_type_1 rows, difference_type_1 columns, const_reference init)
+    {
+        BaseType::reshape(difference_type(rows, columns), init);
+    }
+
+        /** reshape to the given shape and initialize with zero.
+         */
+    void reshape(difference_type const & shape)
+    {
+        BaseType::reshape(shape);
+    }
+
+        /** reshape to the given shape and initialize with \a init.
+         */
+    void reshape(difference_type const & shape, const_reference init)
+    {
+        BaseType::reshape(shape, init);
+    }
+
+        /** Create a matrix view that represents the row vector of row \a d.
+         */
+    view_type rowVector(difference_type_1 d) const
+    {
+        return vigra::linalg::rowVector(*this, d);
+    }
+
+        /** Create a matrix view that represents the column vector of column \a d.
+         */
+    view_type columnVector(difference_type_1 d) const
+    {
+        return vigra::linalg::columnVector(*this, d);
+    }
+
+        /** number of rows (height) of the matrix.
+        */
+    difference_type_1 rowCount() const
+    {
+        return this->m_shape[0];
+    }
+
+        /** number of columns (width) of the matrix.
+        */
+    difference_type_1 columnCount() const
+    {
+        return this->m_shape[1];
+    }
+
+        /** number of elements (width*height) of the matrix.
+        */
+    difference_type_1 elementCount() const
+    {
+        return rowCount()*columnCount();
+    }
+
+        /** check whether the matrix is symmetric.
+        */
+    bool isSymmetric() const
+    {
+        return vigra::linalg::isSymmetric(*this);
+    }
+
+        /** sums over the matrix.
+        */
+    TemporaryMatrix<T> sum() const
+    {
+        TemporaryMatrix<T> result(1, 1);
+        vigra::transformMultiArray(srcMultiArrayRange(*this),
+                               destMultiArrayRange(result),
+                               vigra::FindSum<T>() );
+        return result;
+    }
+    
+        /** sums over dimension \a d of the matrix.
+        */
+    TemporaryMatrix<T> sum(difference_type_1 d) const
+    {
+        difference_type shape(d==0 ? 1 : this->m_shape[0], d==0 ? this->m_shape[1] : 1);
+        TemporaryMatrix<T> result(shape);
+        vigra::transformMultiArray(srcMultiArrayRange(*this),
+                               destMultiArrayRange(result),
+                               vigra::FindSum<T>() );
+        return result;
+    }
+
+        /** sums over the matrix.
+        */
+    TemporaryMatrix<T> mean() const
+    {
+        TemporaryMatrix<T> result(1, 1);
+        vigra::transformMultiArray(srcMultiArrayRange(*this),
+                               destMultiArrayRange(result),
+                               vigra::FindAverage<T>() );
+        return result;
+    }
+    
+        /** calculates mean over dimension \a d of the matrix.
+        */
+    TemporaryMatrix<T> mean(difference_type_1 d) const
+    {
+        difference_type shape(d==0 ? 1 : this->m_shape[0], d==0 ? this->m_shape[1] : 1);
+        TemporaryMatrix<T> result(shape);
+        vigra::transformMultiArray(srcMultiArrayRange(*this),
+                               destMultiArrayRange(result),
+                               vigra::FindAverage<T>() );
+        return result;
+    }
+
+
+#ifdef DOXYGEN
+// repeat the following functions for documentation. In real code, they are inherited.
+
+        /** read/write access to matrix element <tt>(row, column)</tt>.
+            Note that the order of the argument is the opposite of the usual
+            VIGRA convention due to column-major matrix order.
+        */
+    value_type & operator()(difference_type_1 row, difference_type_1 column);
+
+        /** read access to matrix element <tt>(row, column)</tt>.
+            Note that the order of the argument is the opposite of the usual
+            VIGRA convention due to column-major matrix order.
+        */
+    value_type operator()(difference_type_1 row, difference_type_1 column) const;
+
+        /** squared Frobenius norm. Sum of squares of the matrix elements.
+        */
+    typename NormTraits<Matrix>::SquaredNormType squaredNorm() const;
+
+        /** Frobenius norm. Root of sum of squares of the matrix elements.
+        */
+    typename NormTraits<Matrix>::NormType norm() const;
+
+        /** create a transposed view of this matrix.
+            No data are copied. If you want to transpose this matrix permanently, 
+            you have to assign the transposed view:
+            
+            \code
+            a = a.transpose();
+            \endcode
+         */
+    MultiArrayView<2, vluae_type, StridedArrayTag> transpose() const;
+#endif
+
+        /** add \a other to this (sizes must match).
+         */
+    template <class U, class C>
+    Matrix & operator+=(MultiArrayView<2, U, C> const & other)
+    {
+        BaseType::operator+=(other);
+        return *this;
+    }
+
+        /** subtract \a other from this (sizes must match).
+         */
+    template <class U, class C>
+    Matrix & operator-=(MultiArrayView<2, U, C> const & other)
+    {
+        BaseType::operator-=(other);
+        return *this;
+    }
+
+        /** multiply \a other element-wise with this matrix (sizes must match).
+         */
+    template <class U, class C>
+    Matrix & operator*=(MultiArrayView<2, U, C> const & other)
+    {
+        BaseType::operator*=(other);
+        return *this;
+    }
+
+        /** divide this matrix element-wise by \a other (sizes must match).
+         */
+    template <class U, class C>
+    Matrix & operator/=(MultiArrayView<2, U, C> const & other)
+    {
+        BaseType::operator/=(other);
+        return *this;
+    }
+
+        /** add \a other to each element of this matrix
+         */
+    Matrix & operator+=(T other)
+    {
+        BaseType::operator+=(other);
+        return *this;
+    }
+
+        /** subtract \a other from each element of this matrix
+         */
+    Matrix & operator-=(T other)
+    {
+        BaseType::operator-=(other);
+        return *this;
+    }
+
+        /** scalar multiply this with \a other
+         */
+    Matrix & operator*=(T other)
+    {
+        BaseType::operator*=(other);
+        return *this;
+    }
+
+        /** scalar divide this by \a other
+         */
+    Matrix & operator/=(T other)
+    {
+        BaseType::operator/=(other);
+        return *this;
+    }
+};
+
+// TemporaryMatrix is provided as an optimization: Functions returning a matrix can
+// use TemporaryMatrix to make explicit that it was allocated as a temporary data structure.
+// Functions receiving a TemporaryMatrix can thus often avoid to allocate new temporary
+// memory.
+template <class T, class ALLOC>  // default ALLOC already declared above
+class TemporaryMatrix
+: public Matrix<T, ALLOC>
+{
+    typedef Matrix<T, ALLOC> BaseType;
+  public:
+    typedef Matrix<T, ALLOC>                        matrix_type;
+    typedef TemporaryMatrix<T, ALLOC>               temp_type;
+    typedef MultiArrayView<2, T, StridedArrayTag>   view_type;
+    typedef typename BaseType::value_type           value_type;
+    typedef typename BaseType::pointer              pointer;
+    typedef typename BaseType::const_pointer        const_pointer;
+    typedef typename BaseType::reference            reference;
+    typedef typename BaseType::const_reference      const_reference;
+    typedef typename BaseType::difference_type      difference_type;
+    typedef typename BaseType::difference_type_1    difference_type_1;
+    typedef ALLOC                                   allocator_type;
+
+    TemporaryMatrix(difference_type const & shape)
+    : BaseType(shape, ALLOC())
+    {}
+
+    TemporaryMatrix(difference_type const & shape, const_reference init)
+    : BaseType(shape, init, ALLOC())
+    {}
+
+    TemporaryMatrix(difference_type_1 rows, difference_type_1 columns)
+    : BaseType(rows, columns, ALLOC())
+    {}
+
+    TemporaryMatrix(difference_type_1 rows, difference_type_1 columns, const_reference init)
+    : BaseType(rows, columns, init, ALLOC())
+    {}
+
+    template<class U, class C>
+    TemporaryMatrix(const MultiArrayView<2, U, C> &rhs)
+    : BaseType(rhs)
+    {}
+
+    TemporaryMatrix(const TemporaryMatrix &rhs)
+    : BaseType()
+    {
+        this->swap(const_cast<TemporaryMatrix &>(rhs));
+    }
+    
+    template <class U>
+    TemporaryMatrix & init(const U & init)
+    {
+        BaseType::init(init);
+        return *this;
+    }
+
+    template <class U, class C>
+    TemporaryMatrix & operator+=(MultiArrayView<2, U, C> const & other)
+    {
+        BaseType::operator+=(other);
+        return *this;
+    }
+
+    template <class U, class C>
+    TemporaryMatrix & operator-=(MultiArrayView<2, U, C> const & other)
+    {
+        BaseType::operator-=(other);
+        return *this;
+    }
+
+    template <class U, class C>
+    TemporaryMatrix & operator*=(MultiArrayView<2, U, C> const & other)
+    {
+        BaseType::operator*=(other);
+        return *this;
+    }
+
+    template <class U, class C>
+    TemporaryMatrix & operator/=(MultiArrayView<2, U, C> const & other)
+    {
+        BaseType::operator/=(other);
+        return *this;
+    }
+
+    TemporaryMatrix & operator+=(T other)
+    {
+        BaseType::operator+=(other);
+        return *this;
+    }
+
+    TemporaryMatrix & operator-=(T other)
+    {
+        BaseType::operator-=(other);
+        return *this;
+    }
+
+    TemporaryMatrix & operator*=(T other)
+    {
+        BaseType::operator*=(other);
+        return *this;
+    }
+
+    TemporaryMatrix & operator/=(T other)
+    {
+        BaseType::operator/=(other);
+        return *this;
+    }
+  private:
+
+    TemporaryMatrix &operator=(const TemporaryMatrix &rhs); // intentionally not implemented
+};
+
+/** \defgroup LinearAlgebraFunctions Matrix Functions
+
+    \brief Basic matrix algebra, element-wise mathematical functions, row and columns statistics, data normalization etc.
+    
+    \ingroup LinearAlgebraModule
+ */
+//@{
+
+    /** Number of rows of a matrix represented as a <tt>MultiArrayView<2, ...></tt>
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+inline MultiArrayIndex 
+rowCount(const MultiArrayView<2, T, C> &x)
+{
+    return x.shape(0);
+}
+
+    /** Number of columns of a matrix represented as a <tt>MultiArrayView<2, ...></tt>
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+inline MultiArrayIndex 
+columnCount(const MultiArrayView<2, T, C> &x)
+{
+    return x.shape(1);
+}
+
+    /** Create a row vector view for row \a d of the matrix \a m
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+inline MultiArrayView <2, T, C>
+rowVector(MultiArrayView <2, T, C> const & m, MultiArrayIndex d)
+{
+    typedef typename MultiArrayView <2, T, C>::difference_type Shape;
+    return m.subarray(Shape(d, 0), Shape(d+1, columnCount(m)));
+}
+
+
+    /** Create a row vector view of the matrix \a m starting at element \a first and ranging 
+        to column \a end (non-inclusive).
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+inline MultiArrayView <2, T, C>
+rowVector(MultiArrayView <2, T, C> const & m, MultiArrayShape<2>::type first, MultiArrayIndex end)
+{
+    typedef typename MultiArrayView <2, T, C>::difference_type Shape;
+    return m.subarray(first, Shape(first[0]+1, end));
+}
+
+    /** Create a column vector view for column \a d of the matrix \a m
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+inline MultiArrayView <2, T, C>
+columnVector(MultiArrayView<2, T, C> const & m, MultiArrayIndex d)
+{
+    typedef typename MultiArrayView <2, T, C>::difference_type Shape;
+    return m.subarray(Shape(0, d), Shape(rowCount(m), d+1));
+}
+
+    /** Create a column vector view of the matrix \a m starting at element \a first and 
+        ranging to row \a end (non-inclusive).
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     **/
+template <class T, class C>
+inline MultiArrayView <2, T, C>
+columnVector(MultiArrayView<2, T, C> const & m, MultiArrayShape<2>::type first, int end)
+{
+    typedef typename MultiArrayView <2, T, C>::difference_type Shape;
+    return m.subarray(first, Shape(end, first[1]+1));
+}
+
+    /** Create a sub vector view of the vector \a m starting at element \a first and 
+        ranging to row \a end (non-inclusive).
+        
+        Note: This function may only be called when either <tt>rowCount(m) == 1</tt> or
+        <tt>columnCount(m) == 1</tt>, i.e. when \a m really represents a vector. 
+        Otherwise, a PreconditionViolation exception is raised.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     **/
+template <class T, class C>
+inline MultiArrayView <2, T, C>
+subVector(MultiArrayView<2, T, C> const & m, int first, int end)
+{
+    typedef typename MultiArrayView <2, T, C>::difference_type Shape;
+    if(columnCount(m) == 1)
+        return m.subarray(Shape(first, 0), Shape(end, 1));
+    vigra_precondition(rowCount(m) == 1, 
+                       "linalg::subVector(): Input must be a vector (1xN or Nx1).");
+    return m.subarray(Shape(0, first), Shape(1, end));
+}
+
+    /** Check whether matrix \a m is symmetric.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+bool
+isSymmetric(MultiArrayView<2, T, C> const & m)
+{
+    const MultiArrayIndex size = rowCount(m);
+    if(size != columnCount(m))
+        return false;
+
+    for(MultiArrayIndex i = 0; i < size; ++i)
+        for(MultiArrayIndex j = i+1; j < size; ++j)
+            if(m(j, i) != m(i, j))
+                return false;
+    return true;
+}
+
+
+    /** Compute the trace of a square matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+typename NumericTraits<T>::Promote
+trace(MultiArrayView<2, T, C> const & m)
+{
+    typedef typename NumericTraits<T>::Promote SumType;
+    
+    const MultiArrayIndex size = rowCount(m);
+    vigra_precondition(size == columnCount(m), "linalg::trace(): Matrix must be square.");
+
+    SumType sum = NumericTraits<SumType>::zero();
+    for(MultiArrayIndex i = 0; i < size; ++i)
+        sum += m(i, i);
+    return sum;
+}
+
+#ifdef DOXYGEN // documentation only -- function is already defined in vigra/multi_array.hxx
+
+    /** calculate the squared Frobenius norm of a matrix.
+        Equal to the sum of squares of the matrix elements.
+
+        <b>\#include</b> \<vigra/matrix.hxx\>
+        Namespace: vigra
+     */
+template <class T, class ALLOC>
+typename Matrix<T, ALLLOC>::SquaredNormType
+squaredNorm(const Matrix<T, ALLLOC> &a);
+
+    /** calculate the Frobenius norm of a matrix.
+        Equal to the root of the sum of squares of the matrix elements.
+
+        <b>\#include</b> \<vigra/matrix.hxx\>
+        Namespace: vigra
+     */
+template <class T, class ALLOC>
+typename Matrix<T, ALLLOC>::NormType
+norm(const Matrix<T, ALLLOC> &a);
+
+#endif // DOXYGEN
+
+    /** initialize the given square matrix as an identity matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+void identityMatrix(MultiArrayView<2, T, C> &r)
+{
+    const MultiArrayIndex rows = rowCount(r);
+    vigra_precondition(rows == columnCount(r),
+       "identityMatrix(): Matrix must be square.");
+    for(MultiArrayIndex i = 0; i < rows; ++i) {
+        for(MultiArrayIndex j = 0; j < rows; ++j)
+            r(j, i) = NumericTraits<T>::zero();
+        r(i, i) = NumericTraits<T>::one();
+    }
+}
+
+    /** create an identity matrix of the given size.
+        Usage:
+
+        \code
+        vigra::Matrix<double> m = vigra::identityMatrix<double>(size);
+        \endcode
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T>
+TemporaryMatrix<T> identityMatrix(MultiArrayIndex size)
+{
+    TemporaryMatrix<T> ret(size, size, NumericTraits<T>::zero());
+    for(MultiArrayIndex i = 0; i < size; ++i)
+        ret(i, i) = NumericTraits<T>::one();
+    return ret;
+}
+
+    /** create matrix of ones of the given size.
+        Usage:
+
+        \code
+        vigra::Matrix<double> m = vigra::ones<double>(rows, cols);
+        \endcode
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T>
+TemporaryMatrix<T> ones(MultiArrayIndex rows, MultiArrayIndex cols)
+{
+    return TemporaryMatrix<T>(rows, cols, NumericTraits<T>::one());
+}
+
+
+
+template <class T, class C1, class C2>
+void diagonalMatrixImpl(MultiArrayView<1, T, C1> const & v, MultiArrayView<2, T, C2> &r)
+{
+    const MultiArrayIndex size = v.elementCount();
+    vigra_precondition(rowCount(r) == size && columnCount(r) == size,
+        "diagonalMatrix(): result must be a square matrix.");
+    for(MultiArrayIndex i = 0; i < size; ++i)
+        r(i, i) = v(i);
+}
+
+    /** make a diagonal matrix from a vector.
+        The vector is given as matrix \a v, which must either have a single
+        row or column. The result is written into the square matrix \a r.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2>
+void diagonalMatrix(MultiArrayView<2, T, C1> const & v, MultiArrayView<2, T, C2> &r)
+{
+    vigra_precondition(rowCount(v) == 1 || columnCount(v) == 1,
+        "diagonalMatrix(): input must be a vector.");
+    r.init(NumericTraits<T>::zero());
+    if(rowCount(v) == 1)
+        diagonalMatrixImpl(v.bindInner(0), r);
+    else
+        diagonalMatrixImpl(v.bindOuter(0), r);
+}
+
+    /** create a diagonal matrix from a vector.
+        The vector is given as matrix \a v, which must either have a single
+        row or column. The result is returned as a temporary matrix.
+        Usage:
+
+        \code
+        vigra::Matrix<double> v(1, len);
+        v = ...;
+
+        vigra::Matrix<double> m = diagonalMatrix(v);
+        \endcode
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+TemporaryMatrix<T> diagonalMatrix(MultiArrayView<2, T, C> const & v)
+{
+    vigra_precondition(rowCount(v) == 1 || columnCount(v) == 1,
+        "diagonalMatrix(): input must be a vector.");
+    MultiArrayIndex size = v.elementCount();
+    TemporaryMatrix<T> ret(size, size, NumericTraits<T>::zero());
+    if(rowCount(v) == 1)
+        diagonalMatrixImpl(v.bindInner(0), ret);
+    else
+        diagonalMatrixImpl(v.bindOuter(0), ret);
+    return ret;
+}
+
+    /** transpose matrix \a v.
+        The result is written into \a r which must have the correct (i.e.
+        transposed) shape.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2>
+void transpose(const MultiArrayView<2, T, C1> &v, MultiArrayView<2, T, C2> &r)
+{
+    const MultiArrayIndex rows = rowCount(r);
+    const MultiArrayIndex cols = columnCount(r);
+    vigra_precondition(rows == columnCount(v) && cols == rowCount(v),
+       "transpose(): arrays must have transposed shapes.");
+    for(MultiArrayIndex i = 0; i < cols; ++i)
+        for(MultiArrayIndex j = 0; j < rows; ++j)
+            r(j, i) = v(i, j);
+}
+
+    /** create the transpose of matrix \a v.
+        This does not copy any data, but only creates a transposed view 
+        to the original matrix. A copy is only made when the transposed view
+        is assigned to another matrix.
+        Usage:
+
+        \code
+        vigra::Matrix<double> v(rows, cols);
+        v = ...;
+
+        vigra::Matrix<double> m = transpose(v);
+        \endcode
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+inline MultiArrayView<2, T, StridedArrayTag> 
+transpose(MultiArrayView<2, T, C> const & v)
+{
+    return v.transpose();
+}
+
+    /** Create new matrix by concatenating two matrices \a a and \a b vertically, i.e. on top of each other.
+        The two matrices must have the same number of columns.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2>
+inline TemporaryMatrix<T>
+joinVertically(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
+{
+    typedef typename TemporaryMatrix<T>::difference_type Shape;
+    
+    MultiArrayIndex n = columnCount(a);
+    vigra_precondition(n == columnCount(b),
+       "joinVertically(): shape mismatch.");
+    
+    MultiArrayIndex ma = rowCount(a);
+    MultiArrayIndex mb = rowCount(b);
+    TemporaryMatrix<T> t(ma + mb, n, T());
+    t.subarray(Shape(0,0), Shape(ma, n)) = a;
+    t.subarray(Shape(ma,0), Shape(ma+mb, n)) = b;
+    return t;
+}
+
+    /** Create new matrix by concatenating two matrices \a a and \a b horizontally, i.e. side by side.
+        The two matrices must have the same number of rows.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2>
+inline TemporaryMatrix<T>
+joinHorizontally(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
+{
+    typedef typename TemporaryMatrix<T>::difference_type Shape;
+    
+    MultiArrayIndex m = rowCount(a);
+    vigra_precondition(m == rowCount(b),
+       "joinHorizontally(): shape mismatch.");
+    
+    MultiArrayIndex na = columnCount(a);
+    MultiArrayIndex nb = columnCount(b);
+    TemporaryMatrix<T> t(m, na + nb, T());
+    t.subarray(Shape(0,0), Shape(m, na)) = a;
+    t.subarray(Shape(0, na), Shape(m, na + nb)) = b;
+    return t;
+}
+
+    /** Initialize a matrix with repeated copies of a given matrix.
+    
+        Matrix \a r will consist of \a verticalCount downward repetitions of \a v,
+        and \a horizontalCount side-by-side repetitions. When \a v has size <tt>m</tt> by <tt>n</tt>,
+        \a r must have size <tt>(m*verticalCount)</tt> by <tt>(n*horizontalCount)</tt>.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2>
+void repeatMatrix(MultiArrayView<2, T, C1> const & v, MultiArrayView<2, T, C2> &r, 
+                  unsigned int verticalCount, unsigned int horizontalCount)
+{
+    typedef typename Matrix<T>::difference_type Shape;
+
+    MultiArrayIndex m = rowCount(v), n = columnCount(v);
+    vigra_precondition(m*verticalCount == rowCount(r) && n*horizontalCount == columnCount(r),
+        "repeatMatrix(): Shape mismatch.");
+        
+    for(MultiArrayIndex l=0; l<(MultiArrayIndex)horizontalCount; ++l)
+    {
+        for(MultiArrayIndex k=0; k<(MultiArrayIndex)verticalCount; ++k)
+        {
+            r.subarray(Shape(k*m, l*n), Shape((k+1)*m, (l+1)*n)) = v;
+        }
+    }
+}
+
+    /** Create a new matrix by repeating a given matrix.
+    
+        The resulting matrix \a r will consist of \a verticalCount downward repetitions of \a v,
+        and \a horizontalCount side-by-side repetitions, i.e. it will be of size 
+        <tt>(m*verticalCount)</tt> by <tt>(n*horizontalCount)</tt> when \a v has size <tt>m</tt> by <tt>n</tt>.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C>
+TemporaryMatrix<T> 
+repeatMatrix(MultiArrayView<2, T, C> const & v, unsigned int verticalCount, unsigned int horizontalCount)
+{
+    MultiArrayIndex m = rowCount(v), n = columnCount(v);
+    TemporaryMatrix<T> ret(verticalCount*m, horizontalCount*n);
+    repeatMatrix(v, ret, verticalCount, horizontalCount);
+    return ret;
+}
+
+    /** add matrices \a a and \a b.
+        The result is written into \a r. All three matrices must have the same shape.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+void add(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b,
+              MultiArrayView<2, T, C3> &r)
+{
+    const MultiArrayIndex rrows = rowCount(r);
+    const MultiArrayIndex rcols = columnCount(r);
+    vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) &&
+                       rrows == rowCount(b) && rcols == columnCount(b),
+                       "add(): Matrix shapes must agree.");
+
+    for(MultiArrayIndex i = 0; i < rcols; ++i) {
+        for(MultiArrayIndex j = 0; j < rrows; ++j) {
+            r(j, i) = a(j, i) + b(j, i);
+        }
+    }
+}
+
+    /** add matrices \a a and \a b.
+        The two matrices must have the same shape.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2>
+inline TemporaryMatrix<T>
+operator+(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
+{
+    return TemporaryMatrix<T>(a) += b;
+}
+
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator+(const TemporaryMatrix<T> &a, const MultiArrayView<2, T, C> &b)
+{
+    return const_cast<TemporaryMatrix<T> &>(a) += b;
+}
+
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator+(const MultiArrayView<2, T, C> &a, const TemporaryMatrix<T> &b)
+{
+    return const_cast<TemporaryMatrix<T> &>(b) += a;
+}
+
+template <class T>
+inline TemporaryMatrix<T>
+operator+(const TemporaryMatrix<T> &a, const TemporaryMatrix<T> &b)
+{
+    return const_cast<TemporaryMatrix<T> &>(a) += b;
+}
+
+    /** add scalar \a b to every element of the matrix \a a.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator+(const MultiArrayView<2, T, C> &a, T b)
+{
+    return TemporaryMatrix<T>(a) += b;
+}
+
+template <class T>
+inline TemporaryMatrix<T>
+operator+(const TemporaryMatrix<T> &a, T b)
+{
+    return const_cast<TemporaryMatrix<T> &>(a) += b;
+}
+
+    /** add scalar \a a to every element of the matrix \a b.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator+(T a, const MultiArrayView<2, T, C> &b)
+{
+    return TemporaryMatrix<T>(b) += a;
+}
+
+template <class T>
+inline TemporaryMatrix<T>
+operator+(T a, const TemporaryMatrix<T> &b)
+{
+    return const_cast<TemporaryMatrix<T> &>(b) += a;
+}
+
+    /** subtract matrix \a b from \a a.
+        The result is written into \a r. All three matrices must have the same shape.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+void sub(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b,
+              MultiArrayView<2, T, C3> &r)
+{
+    const MultiArrayIndex rrows = rowCount(r);
+    const MultiArrayIndex rcols = columnCount(r);
+    vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) &&
+                       rrows == rowCount(b) && rcols == columnCount(b),
+                       "subtract(): Matrix shapes must agree.");
+
+    for(MultiArrayIndex i = 0; i < rcols; ++i) {
+        for(MultiArrayIndex j = 0; j < rrows; ++j) {
+            r(j, i) = a(j, i) - b(j, i);
+        }
+    }
+}
+
+    /** subtract matrix \a b from \a a.
+        The two matrices must have the same shape.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2>
+inline TemporaryMatrix<T>
+operator-(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
+{
+    return TemporaryMatrix<T>(a) -= b;
+}
+
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator-(const TemporaryMatrix<T> &a, const MultiArrayView<2, T, C> &b)
+{
+    return const_cast<TemporaryMatrix<T> &>(a) -= b;
+}
+
+template <class T, class C>
+TemporaryMatrix<T>
+operator-(const MultiArrayView<2, T, C> &a, const TemporaryMatrix<T> &b)
+{
+    const MultiArrayIndex rows = rowCount(a);
+    const MultiArrayIndex cols = columnCount(a);
+    vigra_precondition(rows == b.rowCount() && cols == b.columnCount(),
+       "Matrix::operator-(): Shape mismatch.");
+
+    for(MultiArrayIndex i = 0; i < cols; ++i)
+        for(MultiArrayIndex j = 0; j < rows; ++j)
+            const_cast<TemporaryMatrix<T> &>(b)(j, i) = a(j, i) - b(j, i);
+    return b;
+}
+
+template <class T>
+inline TemporaryMatrix<T>
+operator-(const TemporaryMatrix<T> &a, const TemporaryMatrix<T> &b)
+{
+    return const_cast<TemporaryMatrix<T> &>(a) -= b;
+}
+
+    /** negate matrix \a a.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator-(const MultiArrayView<2, T, C> &a)
+{
+    return TemporaryMatrix<T>(a) *= -NumericTraits<T>::one();
+}
+
+template <class T>
+inline TemporaryMatrix<T>
+operator-(const TemporaryMatrix<T> &a)
+{
+    return const_cast<TemporaryMatrix<T> &>(a) *= -NumericTraits<T>::one();
+}
+
+    /** subtract scalar \a b from every element of the matrix \a a.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator-(const MultiArrayView<2, T, C> &a, T b)
+{
+    return TemporaryMatrix<T>(a) -= b;
+}
+
+template <class T>
+inline TemporaryMatrix<T>
+operator-(const TemporaryMatrix<T> &a, T b)
+{
+    return const_cast<TemporaryMatrix<T> &>(a) -= b;
+}
+
+    /** subtract every element of the matrix \a b from scalar \a a.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator-(T a, const MultiArrayView<2, T, C> &b)
+{
+    return TemporaryMatrix<T>(b.shape(), a) -= b;
+}
+
+    /** calculate the inner product of two matrices representing vectors.
+        Typically, matrix \a x has a single row, and matrix \a y has
+        a single column, and the other dimensions match. In addition, this
+        function handles the cases when either or both of the two inputs are 
+        transposed (e.g. it can compute the dot product of two column vectors). 
+        A <tt>PreconditionViolation</tt> exception is thrown when
+        the shape conditions are violated. 
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2>
+typename NormTraits<T>::SquaredNormType 
+dot(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2> &y)
+{
+    typename NormTraits<T>::SquaredNormType ret = 
+           NumericTraits<typename NormTraits<T>::SquaredNormType>::zero();
+    if(y.shape(1) == 1)
+    {
+        std::ptrdiff_t size = y.shape(0);
+        if(x.shape(0) == 1 && x.shape(1) == size) // proper scalar product
+            for(std::ptrdiff_t i = 0; i < size; ++i)
+                ret += x(0, i) * y(i, 0);
+        else if(x.shape(1) == 1u && x.shape(0) == size) // two column vectors
+            for(std::ptrdiff_t i = 0; i < size; ++i)
+                ret += x(i, 0) * y(i, 0);
+        else    
+            vigra_precondition(false, "dot(): wrong matrix shapes.");
+    }
+    else if(y.shape(0) == 1)
+    {
+        std::ptrdiff_t size = y.shape(1);
+        if(x.shape(0) == 1u && x.shape(1) == size) // two row vectors
+            for(std::ptrdiff_t i = 0; i < size; ++i)
+                ret += x(0, i) * y(0, i);
+        else if(x.shape(1) == 1u && x.shape(0) == size) // column dot row
+            for(std::ptrdiff_t i = 0; i < size; ++i)
+                ret += x(i, 0) * y(0, i);
+        else    
+            vigra_precondition(false, "dot(): wrong matrix shapes.");
+    }
+    else
+            vigra_precondition(false, "dot(): wrong matrix shapes.");
+    return ret;
+}
+
+    /** calculate the inner product of two vectors. The vector
+        lengths must match.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2>
+typename NormTraits<T>::SquaredNormType 
+dot(const MultiArrayView<1, T, C1> &x, const MultiArrayView<1, T, C2> &y)
+{
+    const MultiArrayIndex n = x.elementCount();
+    vigra_precondition(n == y.elementCount(),
+       "dot(): shape mismatch.");
+    typename NormTraits<T>::SquaredNormType ret = 
+                NumericTraits<typename NormTraits<T>::SquaredNormType>::zero();
+    for(MultiArrayIndex i = 0; i < n; ++i)
+        ret += x(i) * y(i);
+    return ret;
+}
+
+    /** calculate the cross product of two vectors of length 3.
+        The result is written into \a r.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+void cross(const MultiArrayView<1, T, C1> &x, const MultiArrayView<1, T, C2> &y,
+           MultiArrayView<1, T, C3> &r)
+{
+    vigra_precondition(3 == x.elementCount() && 3 == y.elementCount() && 3 == r.elementCount(),
+       "cross(): vectors must have length 3.");
+    r(0) = x(1)*y(2) - x(2)*y(1);
+    r(1) = x(2)*y(0) - x(0)*y(2);
+    r(2) = x(0)*y(1) - x(1)*y(0);
+}
+
+    /** calculate the cross product of two matrices representing vectors.
+        That is, \a x, \a y, and \a r must have a single column of length 3. The result
+        is written into \a r.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+void cross(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2> &y,
+           MultiArrayView<2, T, C3> &r)
+{
+    vigra_precondition(3 == rowCount(x) && 3 == rowCount(y) && 3 == rowCount(r) ,
+       "cross(): vectors must have length 3.");
+    r(0,0) = x(1,0)*y(2,0) - x(2,0)*y(1,0);
+    r(1,0) = x(2,0)*y(0,0) - x(0,0)*y(2,0);
+    r(2,0) = x(0,0)*y(1,0) - x(1,0)*y(0,0);
+}
+
+    /** calculate the cross product of two matrices representing vectors.
+        That is, \a x, and \a y must have a single column of length 3. The result
+        is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2>
+TemporaryMatrix<T>
+cross(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2> &y)
+{
+    TemporaryMatrix<T> ret(3, 1);
+    cross(x, y, ret);
+    return ret;
+}
+    /** calculate the outer product of two matrices representing vectors.
+        That is, matrix \a x must have a single column, and matrix \a y must
+        have a single row, and the other dimensions must match. The result
+        is written into \a r.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+void outer(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2> &y,
+      MultiArrayView<2, T, C3> &r)
+{
+    const MultiArrayIndex rows = rowCount(r);
+    const MultiArrayIndex cols = columnCount(r);
+    vigra_precondition(rows == rowCount(x) && cols == columnCount(y) &&
+                       1 == columnCount(x) && 1 == rowCount(y),
+       "outer(): shape mismatch.");
+    for(MultiArrayIndex i = 0; i < cols; ++i)
+        for(MultiArrayIndex j = 0; j < rows; ++j)
+            r(j, i) = x(j, 0) * y(0, i);
+}
+
+    /** calculate the outer product of two matrices representing vectors.
+        That is, matrix \a x must have a single column, and matrix \a y must
+        have a single row, and the other dimensions must match. The result
+        is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C1, class C2>
+TemporaryMatrix<T>
+outer(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2> &y)
+{
+    const MultiArrayIndex rows = rowCount(x);
+    const MultiArrayIndex cols = columnCount(y);
+    vigra_precondition(1 == columnCount(x) && 1 == rowCount(y),
+       "outer(): shape mismatch.");
+    TemporaryMatrix<T> ret(rows, cols);
+    outer(x, y, ret);
+    return ret;
+}
+
+    /** calculate the outer product of a matrix (representing a vector) with itself.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, class C>
+TemporaryMatrix<T>
+outer(const MultiArrayView<2, T, C> &x)
+{
+    const MultiArrayIndex rows = rowCount(x);
+    const MultiArrayIndex cols = columnCount(x);
+    vigra_precondition(rows == 1 || cols == 1,
+       "outer(): matrix does not represent a vector.");
+    const MultiArrayIndex size = std::max(rows, cols);
+    TemporaryMatrix<T> ret(size, size);
+
+    if(rows == 1)
+    {
+        for(MultiArrayIndex i = 0; i < size; ++i)
+            for(MultiArrayIndex j = 0; j < size; ++j)
+                ret(j, i) = x(0, j) * x(0, i);
+    }
+    else
+    {
+        for(MultiArrayIndex i = 0; i < size; ++i)
+            for(MultiArrayIndex j = 0; j < size; ++j)
+                ret(j, i) = x(j, 0) * x(i, 0);
+    }
+    return ret;
+}
+
+    /** calculate the outer product of a TinyVector with itself.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespaces: vigra and vigra::linalg
+     */
+template <class T, int N>
+TemporaryMatrix<T>
+outer(const TinyVector<T, N> &x)
+{
+    TemporaryMatrix<T> ret(N, N);
+
+    for(MultiArrayIndex i = 0; i < N; ++i)
+        for(MultiArrayIndex j = 0; j < N; ++j)
+            ret(j, i) = x[j] * x[i];
+    return ret;
+}
+
+template <class T>
+class PointWise
+{
+  public:
+    T const & t;
+    
+    PointWise(T const & it)
+    : t(it)
+    {}
+};
+
+template <class T>
+PointWise<T> pointWise(T const & t)
+{
+    return PointWise<T>(t);
+}
+
+
+    /** multiply matrix \a a with scalar \a b.
+        The result is written into \a r. \a a and \a r must have the same shape.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2>
+void smul(const MultiArrayView<2, T, C1> &a, T b, MultiArrayView<2, T, C2> &r)
+{
+    const MultiArrayIndex rows = rowCount(a);
+    const MultiArrayIndex cols = columnCount(a);
+    vigra_precondition(rows == rowCount(r) && cols == columnCount(r),
+                       "smul(): Matrix sizes must agree.");
+
+    for(MultiArrayIndex i = 0; i < cols; ++i)
+        for(MultiArrayIndex j = 0; j < rows; ++j)
+            r(j, i) = a(j, i) * b;
+}
+
+    /** multiply scalar \a a with matrix \a b.
+        The result is written into \a r. \a b and \a r must have the same shape.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C2, class C3>
+void smul(T a, const MultiArrayView<2, T, C2> &b, MultiArrayView<2, T, C3> &r)
+{
+    smul(b, a, r);
+}
+
+    /** perform matrix multiplication of matrices \a a and \a b.
+        The result is written into \a r. The three matrices must have matching shapes.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+void mmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b,
+         MultiArrayView<2, T, C3> &r)
+{
+    const MultiArrayIndex rrows = rowCount(r);
+    const MultiArrayIndex rcols = columnCount(r);
+    const MultiArrayIndex acols = columnCount(a);
+    vigra_precondition(rrows == rowCount(a) && rcols == columnCount(b) && acols == rowCount(b),
+                       "mmul(): Matrix shapes must agree.");
+
+    // order of loops ensures that inner loop goes down columns
+    for(MultiArrayIndex i = 0; i < rcols; ++i) 
+    {
+        for(MultiArrayIndex j = 0; j < rrows; ++j) 
+            r(j, i) = a(j, 0) * b(0, i);
+        for(MultiArrayIndex k = 1; k < acols; ++k) 
+            for(MultiArrayIndex j = 0; j < rrows; ++j) 
+                r(j, i) += a(j, k) * b(k, i);
+    }
+}
+
+    /** perform matrix multiplication of matrices \a a and \a b.
+        \a a and \a b must have matching shapes.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2>
+inline TemporaryMatrix<T>
+mmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
+{
+    TemporaryMatrix<T> ret(rowCount(a), columnCount(b));
+    mmul(a, b, ret);
+    return ret;
+}
+
+    /** multiply two matrices \a a and \a b pointwise.
+        The result is written into \a r. All three matrices must have the same shape.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+void pmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b,
+              MultiArrayView<2, T, C3> &r)
+{
+    const MultiArrayIndex rrows = rowCount(r);
+    const MultiArrayIndex rcols = columnCount(r);
+    vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) &&
+                       rrows == rowCount(b) && rcols == columnCount(b),
+                       "pmul(): Matrix shapes must agree.");
+
+    for(MultiArrayIndex i = 0; i < rcols; ++i) {
+        for(MultiArrayIndex j = 0; j < rrows; ++j) {
+            r(j, i) = a(j, i) * b(j, i);
+        }
+    }
+}
+
+    /** multiply matrices \a a and \a b pointwise.
+        \a a and \a b must have matching shapes.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2>
+inline TemporaryMatrix<T>
+pmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
+{
+    TemporaryMatrix<T> ret(a.shape());
+    pmul(a, b, ret);
+    return ret;
+}
+
+    /** multiply matrices \a a and \a b pointwise.
+        \a a and \a b must have matching shapes.
+        The result is returned as a temporary matrix.
+        
+        Usage:
+        
+        \code
+        Matrix<double> a(m,n), b(m,n);
+        
+        Matrix<double> c = a * pointWise(b);
+        // is equivalent to
+        // Matrix<double> c = pmul(a, b);
+        \endcode
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C, class U>
+inline TemporaryMatrix<T>
+operator*(const MultiArrayView<2, T, C> &a, PointWise<U> b)
+{
+    return pmul(a, b.t);
+}
+
+    /** multiply matrix \a a with scalar \a b.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator*(const MultiArrayView<2, T, C> &a, T b)
+{
+    return TemporaryMatrix<T>(a) *= b;
+}
+
+template <class T>
+inline TemporaryMatrix<T>
+operator*(const TemporaryMatrix<T> &a, T b)
+{
+    return const_cast<TemporaryMatrix<T> &>(a) *= b;
+}
+
+    /** multiply scalar \a a with matrix \a b.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator*(T a, const MultiArrayView<2, T, C> &b)
+{
+    return TemporaryMatrix<T>(b) *= a;
+}
+
+template <class T>
+inline TemporaryMatrix<T>
+operator*(T a, const TemporaryMatrix<T> &b)
+{
+    return const_cast<TemporaryMatrix<T> &>(b) *= a;
+}
+
+    /** multiply matrix \a a with TinyVector \a b.
+        \a a must be of size <tt>N x N</tt>. Vector \a b and the result
+        vector are interpreted as column vectors.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class A, int N, class DATA, class DERIVED>
+TinyVector<T, N>
+operator*(const Matrix<T, A> &a, const TinyVectorBase<T, N, DATA, DERIVED> &b)
+{
+    vigra_precondition(N == rowCount(a) && N == columnCount(a),
+         "operator*(Matrix, TinyVector): Shape mismatch.");
+
+    TinyVector<T, N> res = TinyVectorView<T, N>(&a(0,0)) * b[0];
+    for(MultiArrayIndex i = 1; i < N; ++i)
+        res += TinyVectorView<T, N>(&a(0,i)) * b[i];
+    return res;
+}
+
+    /** multiply TinyVector \a a with matrix \a b.
+        \a b must be of size <tt>N x N</tt>. Vector \a a and the result
+        vector are interpreted as row vectors.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, int N, class DATA, class DERIVED, class A>
+TinyVector<T, N>
+operator*(const TinyVectorBase<T, N, DATA, DERIVED> &a, const Matrix<T, A> &b)
+{
+    vigra_precondition(N == rowCount(b) && N == columnCount(b),
+         "operator*(TinyVector, Matrix): Shape mismatch.");
+
+    TinyVector<T, N> res;
+    for(MultiArrayIndex i = 0; i < N; ++i)
+        res[i] = dot(a, TinyVectorView<T, N>(&b(0,i)));
+    return res;
+}
+
+    /** perform matrix multiplication of matrices \a a and \a b.
+        \a a and \a b must have matching shapes.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2>
+inline TemporaryMatrix<T>
+operator*(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
+{
+    TemporaryMatrix<T> ret(rowCount(a), columnCount(b));
+    mmul(a, b, ret);
+    return ret;
+}
+
+    /** divide matrix \a a by scalar \a b.
+        The result is written into \a r. \a a and \a r must have the same shape.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2>
+void sdiv(const MultiArrayView<2, T, C1> &a, T b, MultiArrayView<2, T, C2> &r)
+{
+    const MultiArrayIndex rows = rowCount(a);
+    const MultiArrayIndex cols = columnCount(a);
+    vigra_precondition(rows == rowCount(r) && cols == columnCount(r),
+                       "sdiv(): Matrix sizes must agree.");
+
+    for(MultiArrayIndex i = 0; i < cols; ++i)
+        for(MultiArrayIndex j = 0; j < rows; ++j)
+            r(j, i) = a(j, i) / b;
+}
+
+    /** divide two matrices \a a and \a b pointwise.
+        The result is written into \a r. All three matrices must have the same shape.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2, class C3>
+void pdiv(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b,
+              MultiArrayView<2, T, C3> &r)
+{
+    const MultiArrayIndex rrows = rowCount(r);
+    const MultiArrayIndex rcols = columnCount(r);
+    vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) &&
+                       rrows == rowCount(b) && rcols == columnCount(b),
+                       "pdiv(): Matrix shapes must agree.");
+
+    for(MultiArrayIndex i = 0; i < rcols; ++i) {
+        for(MultiArrayIndex j = 0; j < rrows; ++j) {
+            r(j, i) = a(j, i) / b(j, i);
+        }
+    }
+}
+
+    /** divide matrices \a a and \a b pointwise.
+        \a a and \a b must have matching shapes.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C1, class C2>
+inline TemporaryMatrix<T>
+pdiv(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
+{
+    TemporaryMatrix<T> ret(a.shape());
+    pdiv(a, b, ret);
+    return ret;
+}
+
+    /** divide matrices \a a and \a b pointwise.
+        \a a and \a b must have matching shapes.
+        The result is returned as a temporary matrix.
+        
+        Usage:
+        
+        \code
+        Matrix<double> a(m,n), b(m,n);
+        
+        Matrix<double> c = a / pointWise(b);
+        // is equivalent to
+        // Matrix<double> c = pdiv(a, b);
+        \endcode
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C, class U>
+inline TemporaryMatrix<T>
+operator/(const MultiArrayView<2, T, C> &a, PointWise<U> b)
+{
+    return pdiv(a, b.t);
+}
+
+    /** divide matrix \a a by scalar \a b.
+        The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator/(const MultiArrayView<2, T, C> &a, T b)
+{
+    return TemporaryMatrix<T>(a) /= b;
+}
+
+template <class T>
+inline TemporaryMatrix<T>
+operator/(const TemporaryMatrix<T> &a, T b)
+{
+    return const_cast<TemporaryMatrix<T> &>(a) /= b;
+}
+
+    /** Create a matrix whose elements are the quotients between scalar \a a and
+        matrix \a b. The result is returned as a temporary matrix.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: vigra::linalg
+     */
+template <class T, class C>
+inline TemporaryMatrix<T>
+operator/(T a, const MultiArrayView<2, T, C> &b)
+{
+    return TemporaryMatrix<T>(b.shape(), a) / pointWise(b);
+}
+
+using vigra::argMin;
+using vigra::argMinIf;
+using vigra::argMax;
+using vigra::argMaxIf;
+
+    /** \brief Find the index of the minimum element in a matrix.
+    
+        The function returns the index in column-major scan-order sense,
+        i.e. according to the order used by <tt>MultiArrayView::operator[]</tt>.
+        If the matrix is actually a vector, this is just the row or columns index.
+        In case of a truly 2-dimensional matrix, the index can be converted to an 
+        index pair by calling <tt>MultiArrayView::scanOrderIndexToCoordinate()</tt>
+        
+        <b>Required Interface:</b>
+        
+        \code
+        bool f = a[0] < NumericTraits<T>::max();
+        \endcode
+
+        <b>\#include</b> \<vigra/matrix.hxx\><br>
+        Namespace: vigra
+    */
+template <class T, class C>
+int argMin(MultiArrayView<2, T, C> const & a)
+{
+    T vopt = NumericTraits<T>::max();
+    int best = -1;
+    for(int k=0; k < a.size(); ++k)
+    {
+        if(a[k] < vopt)
+        {
+            vopt = a[k];
+            best = k;
+        }
+    }
+    return best;
+}
+
+    /** \brief Find the index of the maximum element in a matrix.
+    
+        The function returns the index in column-major scan-order sense,
+        i.e. according to the order used by <tt>MultiArrayView::operator[]</tt>.
+        If the matrix is actually a vector, this is just the row or columns index.
+        In case of a truly 2-dimensional matrix, the index can be converted to an 
+        index pair by calling <tt>MultiArrayView::scanOrderIndexToCoordinate()</tt>
+        
+        <b>Required Interface:</b>
+        
+        \code
+        bool f = NumericTraits<T>::min() < a[0];
+        \endcode
+
+        <b>\#include</b> \<vigra/matrix.hxx\><br>
+        Namespace: vigra
+    */
+template <class T, class C>
+int argMax(MultiArrayView<2, T, C> const & a)
+{
+    T vopt = NumericTraits<T>::min();
+    int best = -1;
+    for(int k=0; k < a.size(); ++k)
+    {
+        if(vopt < a[k])
+        {
+            vopt = a[k];
+            best = k;
+        }
+    }
+    return best;
+}
+
+    /** \brief Find the index of the minimum element in a matrix subject to a condition.
+    
+        The function returns <tt>-1</tt> if no element conforms to \a condition.
+        Otherwise, the index of the maximum element is returned in column-major scan-order sense,
+        i.e. according to the order used by <tt>MultiArrayView::operator[]</tt>.
+        If the matrix is actually a vector, this is just the row or columns index.
+        In case of a truly 2-dimensional matrix, the index can be converted to an 
+        index pair by calling <tt>MultiArrayView::scanOrderIndexToCoordinate()</tt>
+        
+        <b>Required Interface:</b>
+        
+        \code
+        bool c = condition(a[0]);
+        bool f = a[0] < NumericTraits<T>::max();
+        \endcode
+
+        <b>\#include</b> \<vigra/matrix.hxx\><br>
+        Namespace: vigra
+    */
+template <class T, class C, class UnaryFunctor>
+int argMinIf(MultiArrayView<2, T, C> const & a, UnaryFunctor condition)
+{
+    T vopt = NumericTraits<T>::max();
+    int best = -1;
+    for(int k=0; k < a.size(); ++k)
+    {
+        if(condition(a[k]) && a[k] < vopt)
+        {
+            vopt = a[k];
+            best = k;
+        }
+    }
+    return best;
+}
+
+    /** \brief Find the index of the maximum element in a matrix subject to a condition.
+    
+        The function returns <tt>-1</tt> if no element conforms to \a condition.
+        Otherwise, the index of the maximum element is returned in column-major scan-order sense,
+        i.e. according to the order used by <tt>MultiArrayView::operator[]</tt>.
+        If the matrix is actually a vector, this is just the row or columns index.
+        In case of a truly 2-dimensional matrix, the index can be converted to an 
+        index pair by calling <tt>MultiArrayView::scanOrderIndexToCoordinate()</tt>
+        
+        <b>Required Interface:</b>
+        
+        \code
+        bool c = condition(a[0]);
+        bool f = NumericTraits<T>::min() < a[0];
+        \endcode
+
+        <b>\#include</b> \<vigra/matrix.hxx\><br>
+        Namespace: vigra
+    */
+template <class T, class C, class UnaryFunctor>
+int argMaxIf(MultiArrayView<2, T, C> const & a, UnaryFunctor condition)
+{
+    T vopt = NumericTraits<T>::min();
+    int best = -1;
+    for(int k=0; k < a.size(); ++k)
+    {
+        if(condition(a[k]) && vopt < a[k])
+        {
+            vopt = a[k];
+            best = k;
+        }
+    }
+    return best;
+}
+
+/** Matrix point-wise power.
+*/
+template <class T, class C>
+linalg::TemporaryMatrix<T> pow(MultiArrayView<2, T, C> const & v, T exponent)
+{
+    linalg::TemporaryMatrix<T> t(v.shape());
+    MultiArrayIndex m = rowCount(v), n = columnCount(v);
+
+    for(MultiArrayIndex i = 0; i < n; ++i)
+        for(MultiArrayIndex j = 0; j < m; ++j)
+            t(j, i) = vigra::pow(v(j, i), exponent);
+    return t;
+}
+
+template <class T>
+linalg::TemporaryMatrix<T> pow(linalg::TemporaryMatrix<T> const & v, T exponent)
+{
+    linalg::TemporaryMatrix<T> & t = const_cast<linalg::TemporaryMatrix<T> &>(v);
+    MultiArrayIndex m = rowCount(t), n = columnCount(t);
+
+    for(MultiArrayIndex i = 0; i < n; ++i)
+        for(MultiArrayIndex j = 0; j < m; ++j)
+            t(j, i) = vigra::pow(t(j, i), exponent);
+    return t;
+}
+
+template <class T, class C>
+linalg::TemporaryMatrix<T> pow(MultiArrayView<2, T, C> const & v, int exponent)
+{
+    linalg::TemporaryMatrix<T> t(v.shape());
+    MultiArrayIndex m = rowCount(v), n = columnCount(v);
+
+    for(MultiArrayIndex i = 0; i < n; ++i)
+        for(MultiArrayIndex j = 0; j < m; ++j)
+            t(j, i) = vigra::pow(v(j, i), exponent);
+    return t;
+}
+
+template <class T>
+linalg::TemporaryMatrix<T> pow(linalg::TemporaryMatrix<T> const & v, int exponent)
+{
+    linalg::TemporaryMatrix<T> & t = const_cast<linalg::TemporaryMatrix<T> &>(v);
+    MultiArrayIndex m = rowCount(t), n = columnCount(t);
+
+    for(MultiArrayIndex i = 0; i < n; ++i)
+        for(MultiArrayIndex j = 0; j < m; ++j)
+            t(j, i) = vigra::pow(t(j, i), exponent);
+    return t;
+}
+
+template <class C>
+linalg::TemporaryMatrix<int> pow(MultiArrayView<2, int, C> const & v, int exponent)
+{
+    linalg::TemporaryMatrix<int> t(v.shape());
+    MultiArrayIndex m = rowCount(v), n = columnCount(v);
+
+    for(MultiArrayIndex i = 0; i < n; ++i)
+        for(MultiArrayIndex j = 0; j < m; ++j)
+            t(j, i) = (int)vigra::pow((double)v(j, i), exponent);
+    return t;
+}
+
+inline
+linalg::TemporaryMatrix<int> pow(linalg::TemporaryMatrix<int> const & v, int exponent)
+{
+    linalg::TemporaryMatrix<int> & t = const_cast<linalg::TemporaryMatrix<int> &>(v);
+    MultiArrayIndex m = rowCount(t), n = columnCount(t);
+
+    for(MultiArrayIndex i = 0; i < n; ++i)
+        for(MultiArrayIndex j = 0; j < m; ++j)
+            t(j, i) = (int)vigra::pow((double)t(j, i), exponent);
+    return t;
+}
+
+    /** Matrix point-wise sqrt. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> sqrt(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise exp. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> exp(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise log. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> log(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise log10. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> log10(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise sin. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> sin(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise asin. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> asin(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise cos. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> cos(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise acos. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> acos(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise tan. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> tan(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise atan. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> atan(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise round. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> round(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise floor. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> floor(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise ceil. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> ceil(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise abs. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> abs(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise square. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> sq(MultiArrayView<2, T, C> const & v);
+    /** Matrix point-wise sign. */
+template <class T, class C>
+linalg::TemporaryMatrix<T> sign(MultiArrayView<2, T, C> const & v);
+
+#define VIGRA_MATRIX_UNARY_FUNCTION(FUNCTION, NAMESPACE) \
+using NAMESPACE::FUNCTION; \
+template <class T, class C> \
+linalg::TemporaryMatrix<T> FUNCTION(MultiArrayView<2, T, C> const & v) \
+{ \
+    linalg::TemporaryMatrix<T> t(v.shape()); \
+    MultiArrayIndex m = rowCount(v), n = columnCount(v); \
+ \
+    for(MultiArrayIndex i = 0; i < n; ++i) \
+        for(MultiArrayIndex j = 0; j < m; ++j) \
+            t(j, i) = NAMESPACE::FUNCTION(v(j, i)); \
+    return t; \
+} \
+ \
+template <class T> \
+linalg::TemporaryMatrix<T> FUNCTION(linalg::Matrix<T> const & v) \
+{ \
+    linalg::TemporaryMatrix<T> t(v.shape()); \
+    MultiArrayIndex m = rowCount(v), n = columnCount(v); \
+ \
+    for(MultiArrayIndex i = 0; i < n; ++i) \
+        for(MultiArrayIndex j = 0; j < m; ++j) \
+            t(j, i) = NAMESPACE::FUNCTION(v(j, i)); \
+    return t; \
+} \
+ \
+template <class T> \
+linalg::TemporaryMatrix<T> FUNCTION(linalg::TemporaryMatrix<T> const & v) \
+{ \
+    linalg::TemporaryMatrix<T> & t = const_cast<linalg::TemporaryMatrix<T> &>(v); \
+    MultiArrayIndex m = rowCount(t), n = columnCount(t); \
+ \
+    for(MultiArrayIndex i = 0; i < n; ++i) \
+        for(MultiArrayIndex j = 0; j < m; ++j) \
+            t(j, i) = NAMESPACE::FUNCTION(t(j, i)); \
+    return v; \
+}\
+}\
+using linalg::FUNCTION;\
+namespace linalg {
+
+VIGRA_MATRIX_UNARY_FUNCTION(sqrt, std)
+VIGRA_MATRIX_UNARY_FUNCTION(exp, std)
+VIGRA_MATRIX_UNARY_FUNCTION(log, std)
+VIGRA_MATRIX_UNARY_FUNCTION(log10, std)
+VIGRA_MATRIX_UNARY_FUNCTION(sin, std)
+VIGRA_MATRIX_UNARY_FUNCTION(asin, std)
+VIGRA_MATRIX_UNARY_FUNCTION(cos, std)
+VIGRA_MATRIX_UNARY_FUNCTION(acos, std)
+VIGRA_MATRIX_UNARY_FUNCTION(tan, std)
+VIGRA_MATRIX_UNARY_FUNCTION(atan, std)
+VIGRA_MATRIX_UNARY_FUNCTION(round, vigra)
+VIGRA_MATRIX_UNARY_FUNCTION(floor, vigra)
+VIGRA_MATRIX_UNARY_FUNCTION(ceil, vigra)
+VIGRA_MATRIX_UNARY_FUNCTION(abs, vigra)
+VIGRA_MATRIX_UNARY_FUNCTION(sq, vigra)
+VIGRA_MATRIX_UNARY_FUNCTION(sign, vigra)
+
+#undef VIGRA_MATRIX_UNARY_FUNCTION
+
+//@}
+
+} // namespace linalg
+
+using linalg::RowMajor;
+using linalg::ColumnMajor;
+using linalg::Matrix;
+using linalg::identityMatrix;
+using linalg::diagonalMatrix;
+using linalg::transpose;
+using linalg::pointWise;
+using linalg::trace;
+using linalg::dot;
+using linalg::cross;
+using linalg::outer;
+using linalg::rowCount;
+using linalg::columnCount;
+using linalg::rowVector;
+using linalg::columnVector;
+using linalg::subVector;
+using linalg::isSymmetric;
+using linalg::joinHorizontally;
+using linalg::joinVertically;
+using linalg::argMin;
+using linalg::argMinIf;
+using linalg::argMax;
+using linalg::argMaxIf;
+
+/********************************************************/
+/*                                                      */
+/*                       NormTraits                     */
+/*                                                      */
+/********************************************************/
+
+template <class T, class ALLOC>
+struct NormTraits<Matrix<T, ALLOC> >
+: public NormTraits<MultiArray<2, T, ALLOC> >
+{
+    typedef NormTraits<MultiArray<2, T, ALLOC> > BaseType;
+    typedef Matrix<T, ALLOC>                     Type;
+    typedef typename BaseType::SquaredNormType   SquaredNormType;
+    typedef typename BaseType::NormType          NormType;
+};
+
+template <class T, class ALLOC>
+struct NormTraits<linalg::TemporaryMatrix<T, ALLOC> >
+: public NormTraits<Matrix<T, ALLOC> >
+{
+    typedef NormTraits<Matrix<T, ALLOC> >        BaseType;
+    typedef linalg::TemporaryMatrix<T, ALLOC>    Type;
+    typedef typename BaseType::SquaredNormType   SquaredNormType;
+    typedef typename BaseType::NormType          NormType;
+};
+
+} // namespace vigra
+
+namespace std {
+
+/** \addtogroup LinearAlgebraFunctions
+ */
+//@{
+
+    /** print a matrix \a m to the stream \a s.
+
+        <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+        <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+        Namespace: std
+     */
+template <class T, class C>
+ostream &
+operator<<(ostream & s, const vigra::MultiArrayView<2, T, C> &m)
+{
+    const vigra::MultiArrayIndex rows = vigra::linalg::rowCount(m);
+    const vigra::MultiArrayIndex cols = vigra::linalg::columnCount(m);
+    ios::fmtflags flags = s.setf(ios::right | ios::fixed, ios::adjustfield | ios::floatfield);
+    for(vigra::MultiArrayIndex j = 0; j < rows; ++j)
+    {
+        for(vigra::MultiArrayIndex i = 0; i < cols; ++i)
+        {
+            s << m(j, i) << " ";
+        }
+        s << endl;
+    }
+    s.setf(flags);
+    return s;
+}
+
+//@}
+
+} // namespace std
+
+namespace vigra {
+
+namespace linalg {
+
+namespace detail {
+
+template <class T1, class C1, class T2, class C2, class T3, class C3>
+void
+columnStatisticsImpl(MultiArrayView<2, T1, C1> const & A, 
+                 MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3> & sumOfSquaredDifferences)
+{
+    MultiArrayIndex m = rowCount(A);
+    MultiArrayIndex n = columnCount(A);
+    vigra_precondition(1 == rowCount(mean) && n == columnCount(mean) &&
+                       1 == rowCount(sumOfSquaredDifferences) && n == columnCount(sumOfSquaredDifferences),
+                       "columnStatistics(): Shape mismatch between input and output.");
+
+    // West's algorithm for incremental variance computation
+    mean.init(NumericTraits<T2>::zero());
+    sumOfSquaredDifferences.init(NumericTraits<T3>::zero());
+    
+    for(MultiArrayIndex k=0; k<m; ++k)
+    {
+        typedef typename NumericTraits<T2>::RealPromote TmpType;
+        Matrix<T2> t = rowVector(A, k) - mean;
+        TmpType f  = TmpType(1.0 / (k + 1.0)),
+                f1 = TmpType(1.0 - f);
+        mean += f*t;
+        sumOfSquaredDifferences += f1*sq(t);
+    }
+}
+
+template <class T1, class C1, class T2, class C2, class T3, class C3>
+void
+columnStatistics2PassImpl(MultiArrayView<2, T1, C1> const & A, 
+                 MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3> & sumOfSquaredDifferences)
+{
+    MultiArrayIndex m = rowCount(A);
+    MultiArrayIndex n = columnCount(A);
+    vigra_precondition(1 == rowCount(mean) && n == columnCount(mean) &&
+                       1 == rowCount(sumOfSquaredDifferences) && n == columnCount(sumOfSquaredDifferences),
+                       "columnStatistics(): Shape mismatch between input and output.");
+
+    // two-pass algorithm for incremental variance computation
+    mean.init(NumericTraits<T2>::zero());    
+    for(MultiArrayIndex k=0; k<m; ++k)
+    {
+        mean += rowVector(A, k);
+    }
+    mean /= (double)m;
+    
+    sumOfSquaredDifferences.init(NumericTraits<T3>::zero());
+    for(MultiArrayIndex k=0; k<m; ++k)
+    {
+        sumOfSquaredDifferences += sq(rowVector(A, k) - mean);
+    }
+}
+
+} // namespace detail
+
+/** \addtogroup LinearAlgebraFunctions
+ */
+//@{
+    /** Compute statistics of every column of matrix \a A.
+    
+    The result matrices must be row vectors with as many columns as \a A.
+
+    <b> Declarations:</b>
+
+    compute only the mean:
+    \code
+    namespace vigra { namespace linalg {
+        template <class T1, class C1, class T2, class C2>
+        void
+        columnStatistics(MultiArrayView<2, T1, C1> const & A, 
+                         MultiArrayView<2, T2, C2> & mean);
+    } }
+    \endcode
+
+    compute mean and standard deviation:
+    \code
+    namespace vigra { namespace linalg {
+        template <class T1, class C1, class T2, class C2, class T3, class C3>
+        void
+        columnStatistics(MultiArrayView<2, T1, C1> const & A, 
+                         MultiArrayView<2, T2, C2> & mean, 
+                         MultiArrayView<2, T3, C3> & stdDev);
+    } }
+    \endcode
+
+    compute mean, standard deviation, and norm:
+    \code
+    namespace vigra { namespace linalg {
+        template <class T1, class C1, class T2, class C2, class T3, class C3, class T4, class C4>
+        void
+        columnStatistics(MultiArrayView<2, T1, C1> const & A, 
+                         MultiArrayView<2, T2, C2> & mean, 
+                         MultiArrayView<2, T3, C3> & stdDev, 
+                         MultiArrayView<2, T4, C4> & norm);
+    } }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+    <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+    Namespaces: vigra and vigra::linalg
+
+    \code
+    Matrix A(rows, columns);
+    .. // fill A
+    Matrix columnMean(1, columns), columnStdDev(1, columns), columnNorm(1, columns);
+
+    columnStatistics(A, columnMean, columnStdDev, columnNorm);
+
+    \endcode
+    */
+doxygen_overloaded_function(template <...> void columnStatistics)
+
+template <class T1, class C1, class T2, class C2>
+void
+columnStatistics(MultiArrayView<2, T1, C1> const & A, 
+                 MultiArrayView<2, T2, C2> & mean)
+{
+    MultiArrayIndex m = rowCount(A);
+    MultiArrayIndex n = columnCount(A);
+    vigra_precondition(1 == rowCount(mean) && n == columnCount(mean),
+                       "columnStatistics(): Shape mismatch between input and output.");
+
+    mean.init(NumericTraits<T2>::zero());
+    
+    for(MultiArrayIndex k=0; k<m; ++k)
+    {
+        mean += rowVector(A, k);
+    }
+    mean /= T2(m);
+}
+
+template <class T1, class C1, class T2, class C2, class T3, class C3>
+void
+columnStatistics(MultiArrayView<2, T1, C1> const & A, 
+                 MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3> & stdDev)
+{
+    detail::columnStatisticsImpl(A, mean, stdDev);
+    
+    if(rowCount(A) > 1)
+        stdDev = sqrt(stdDev / T3(rowCount(A) - 1.0));
+}
+
+template <class T1, class C1, class T2, class C2, class T3, class C3, class T4, class C4>
+void
+columnStatistics(MultiArrayView<2, T1, C1> const & A, 
+                 MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3> & stdDev, MultiArrayView<2, T4, C4> & norm)
+{
+    MultiArrayIndex m = rowCount(A);
+    MultiArrayIndex n = columnCount(A);
+    vigra_precondition(1 == rowCount(mean) && n == columnCount(mean) &&
+                       1 == rowCount(stdDev) && n == columnCount(stdDev) &&
+                       1 == rowCount(norm) && n == columnCount(norm),
+                       "columnStatistics(): Shape mismatch between input and output.");
+
+    detail::columnStatisticsImpl(A, mean, stdDev);
+    norm = sqrt(stdDev + T2(m) * sq(mean));
+    stdDev = sqrt(stdDev / T3(m - 1.0));
+}
+
+    /** Compute statistics of every row of matrix \a A.
+    
+    The result matrices must be column vectors with as many rows as \a A.
+
+    <b> Declarations:</b>
+
+    compute only the mean:
+    \code
+    namespace vigra { namespace linalg {
+        template <class T1, class C1, class T2, class C2>
+        void
+        rowStatistics(MultiArrayView<2, T1, C1> const & A, 
+                      MultiArrayView<2, T2, C2> & mean);
+    } }
+    \endcode
+
+    compute mean and standard deviation:
+    \code
+    namespace vigra { namespace linalg {
+        template <class T1, class C1, class T2, class C2, class T3, class C3>
+        void
+        rowStatistics(MultiArrayView<2, T1, C1> const & A, 
+                      MultiArrayView<2, T2, C2> & mean, 
+                      MultiArrayView<2, T3, C3> & stdDev);
+    } }
+    \endcode
+
+    compute mean, standard deviation, and norm:
+    \code
+    namespace vigra { namespace linalg {
+        template <class T1, class C1, class T2, class C2, class T3, class C3, class T4, class C4>
+        void
+        rowStatistics(MultiArrayView<2, T1, C1> const & A, 
+                      MultiArrayView<2, T2, C2> & mean, 
+                      MultiArrayView<2, T3, C3> & stdDev, 
+                      MultiArrayView<2, T4, C4> & norm);
+    } }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+    <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+    Namespaces: vigra and vigra::linalg
+
+    \code
+    Matrix A(rows, columns);
+    .. // fill A
+    Matrix rowMean(rows, 1), rowStdDev(rows, 1), rowNorm(rows, 1);
+
+    rowStatistics(a, rowMean, rowStdDev, rowNorm);
+
+    \endcode
+     */
+doxygen_overloaded_function(template <...> void rowStatistics)
+
+template <class T1, class C1, class T2, class C2>
+void
+rowStatistics(MultiArrayView<2, T1, C1> const & A, 
+                 MultiArrayView<2, T2, C2> & mean)
+{
+    vigra_precondition(1 == columnCount(mean) && rowCount(A) == rowCount(mean),
+                       "rowStatistics(): Shape mismatch between input and output.");
+    MultiArrayView<2, T2, StridedArrayTag> tm = transpose(mean);
+    columnStatistics(transpose(A), tm);
+}
+
+template <class T1, class C1, class T2, class C2, class T3, class C3>
+void
+rowStatistics(MultiArrayView<2, T1, C1> const & A, 
+                 MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3> & stdDev)
+{
+    vigra_precondition(1 == columnCount(mean) && rowCount(A) == rowCount(mean) &&
+                       1 == columnCount(stdDev) && rowCount(A) == rowCount(stdDev),
+                       "rowStatistics(): Shape mismatch between input and output.");
+    MultiArrayView<2, T2, StridedArrayTag> tm = transpose(mean);
+    MultiArrayView<2, T3, StridedArrayTag> ts = transpose(stdDev);
+    columnStatistics(transpose(A), tm, ts);
+}
+
+template <class T1, class C1, class T2, class C2, class T3, class C3, class T4, class C4>
+void
+rowStatistics(MultiArrayView<2, T1, C1> const & A, 
+                 MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3> & stdDev, MultiArrayView<2, T4, C4> & norm)
+{
+    vigra_precondition(1 == columnCount(mean) && rowCount(A) == rowCount(mean) &&
+                       1 == columnCount(stdDev) && rowCount(A) == rowCount(stdDev) &&
+                       1 == columnCount(norm) && rowCount(A) == rowCount(norm),
+                       "rowStatistics(): Shape mismatch between input and output.");
+    MultiArrayView<2, T2, StridedArrayTag> tm = transpose(mean);
+    MultiArrayView<2, T3, StridedArrayTag> ts = transpose(stdDev); 
+    MultiArrayView<2, T4, StridedArrayTag> tn = transpose(norm);
+    columnStatistics(transpose(A), tm, ts, tn);
+}
+
+namespace detail {
+
+template <class T1, class C1, class U, class T2, class C2, class T3, class C3>
+void updateCovarianceMatrix(MultiArrayView<2, T1, C1> const & features,
+                       U & count, MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3> & covariance)
+{
+    MultiArrayIndex n = std::max(rowCount(features), columnCount(features));
+    vigra_precondition(std::min(rowCount(features), columnCount(features)) == 1,
+          "updateCovarianceMatrix(): Features must be a row or column vector.");
+    vigra_precondition(mean.shape() == features.shape(),
+          "updateCovarianceMatrix(): Shape mismatch between feature vector and mean vector.");
+    vigra_precondition(n == rowCount(covariance) && n == columnCount(covariance),
+          "updateCovarianceMatrix(): Shape mismatch between feature vector and covariance matrix.");
+    
+    // West's algorithm for incremental covariance matrix computation
+    Matrix<T2> t = features - mean;
+    ++count;
+    double f  = 1.0 / count,
+           f1 = 1.0 - f;
+    mean += f*t;
+    
+    if(rowCount(features) == 1) // update column covariance from current row
+    {
+        for(MultiArrayIndex k=0; k<n; ++k)
+        {
+            covariance(k, k) += f1*sq(t(0, k));
+            for(MultiArrayIndex l=k+1; l<n; ++l)
+            {
+                covariance(k, l) += f1*t(0, k)*t(0, l);
+                covariance(l, k) = covariance(k, l);
+            }
+        }
+    }
+    else // update row covariance from current column
+    {
+        for(MultiArrayIndex k=0; k<n; ++k)
+        {
+            covariance(k, k) += f1*sq(t(k, 0));
+            for(MultiArrayIndex l=k+1; l<n; ++l)
+            {
+                covariance(k, l) += f1*t(k, 0)*t(l, 0);
+                covariance(l, k) = covariance(k, l);
+            }
+        }
+    }
+}
+
+} // namespace detail
+
+    /** \brief Compute the covariance matrix between the columns of a matrix \a features.
+    
+        The result matrix \a covariance must by a square matrix with as many rows and
+        columns as the number of columns in matrix \a features.
+
+        <b>\#include</b> \<vigra/matrix.hxx\><br>
+        Namespace: vigra
+    */
+template <class T1, class C1, class T2, class C2>
+void covarianceMatrixOfColumns(MultiArrayView<2, T1, C1> const & features,
+                               MultiArrayView<2, T2, C2> & covariance)
+{
+    MultiArrayIndex m = rowCount(features), n = columnCount(features);
+    vigra_precondition(n == rowCount(covariance) && n == columnCount(covariance),
+          "covarianceMatrixOfColumns(): Shape mismatch between feature matrix and covariance matrix.");
+    MultiArrayIndex count = 0;
+    Matrix<T2> means(1, n);
+    covariance.init(NumericTraits<T2>::zero());
+    for(MultiArrayIndex k=0; k<m; ++k)
+        detail::updateCovarianceMatrix(rowVector(features, k), count, means, covariance);
+    covariance /= T2(m - 1);
+}
+
+    /** \brief Compute the covariance matrix between the columns of a matrix \a features.
+    
+        The result is returned as a square temporary matrix with as many rows and
+        columns as the number of columns in matrix \a features.
+
+        <b>\#include</b> \<vigra/matrix.hxx\><br>
+        Namespace: vigra
+    */
+template <class T, class C>
+TemporaryMatrix<T> 
+covarianceMatrixOfColumns(MultiArrayView<2, T, C> const & features)
+{
+    TemporaryMatrix<T> res(columnCount(features), columnCount(features));
+    covarianceMatrixOfColumns(features, res);
+    return res;
+}
+
+    /** \brief Compute the covariance matrix between the rows of a matrix \a features.
+    
+        The result matrix \a covariance must by a square matrix with as many rows and
+        columns as the number of rows in matrix \a features.
+
+        <b>\#include</b> \<vigra/matrix.hxx\><br>
+        Namespace: vigra
+    */
+template <class T1, class C1, class T2, class C2>
+void covarianceMatrixOfRows(MultiArrayView<2, T1, C1> const & features,
+                            MultiArrayView<2, T2, C2> & covariance)
+{
+    MultiArrayIndex m = rowCount(features), n = columnCount(features);
+    vigra_precondition(m == rowCount(covariance) && m == columnCount(covariance),
+          "covarianceMatrixOfRows(): Shape mismatch between feature matrix and covariance matrix.");
+    MultiArrayIndex count = 0;
+    Matrix<T2> means(m, 1);
+    covariance.init(NumericTraits<T2>::zero());
+    for(MultiArrayIndex k=0; k<n; ++k)
+        detail::updateCovarianceMatrix(columnVector(features, k), count, means, covariance);
+    covariance /= T2(m - 1);
+}
+
+    /** \brief Compute the covariance matrix between the rows of a matrix \a features.
+    
+        The result is returned as a square temporary matrix with as many rows and
+        columns as the number of rows in matrix \a features.
+
+        <b>\#include</b> \<vigra/matrix.hxx\><br>
+        Namespace: vigra
+    */
+template <class T, class C>
+TemporaryMatrix<T> 
+covarianceMatrixOfRows(MultiArrayView<2, T, C> const & features)
+{
+    TemporaryMatrix<T> res(rowCount(features), rowCount(features));
+    covarianceMatrixOfRows(features, res);
+    return res;
+}
+
+enum DataPreparationGoals { ZeroMean = 1, UnitVariance = 2, UnitNorm = 4, UnitSum = 8 };
+
+inline DataPreparationGoals operator|(DataPreparationGoals l, DataPreparationGoals r)
+{
+    return DataPreparationGoals(int(l) | int(r));
+}
+
+namespace detail {
+
+template <class T, class C1, class C2, class C3, class C4>
+void
+prepareDataImpl(const MultiArrayView<2, T, C1> & A, 
+               MultiArrayView<2, T, C2> & res, MultiArrayView<2, T, C3> & offset, MultiArrayView<2, T, C4> & scaling, 
+               DataPreparationGoals goals)
+{
+    MultiArrayIndex m = rowCount(A);
+    MultiArrayIndex n = columnCount(A);
+    vigra_precondition(A.shape() == res.shape() && 
+                       n == columnCount(offset) && 1 == rowCount(offset) &&
+                       n == columnCount(scaling) && 1 == rowCount(scaling),
+                       "prepareDataImpl(): Shape mismatch between input and output.");
+
+    if(!goals)
+    {
+        res = A;
+        offset.init(NumericTraits<T>::zero());
+        scaling.init(NumericTraits<T>::one());
+        return;
+    }
+    
+    bool zeroMean = (goals & ZeroMean) != 0;
+    bool unitVariance = (goals & UnitVariance) != 0;
+    bool unitNorm = (goals & UnitNorm) != 0;
+    bool unitSum = (goals & UnitSum) != 0;
+
+    if(unitSum)
+    {
+        vigra_precondition(goals == UnitSum,
+             "prepareData(): Unit sum is not compatible with any other data preparation goal.");
+             
+        transformMultiArray(srcMultiArrayRange(A), destMultiArrayRange(scaling), FindSum<T>());
+        
+        offset.init(NumericTraits<T>::zero());
+        
+        for(MultiArrayIndex k=0; k<n; ++k)
+        {
+            if(scaling(0, k) != NumericTraits<T>::zero())
+            {
+                scaling(0, k) = NumericTraits<T>::one() / scaling(0, k);
+                columnVector(res, k) = columnVector(A, k) * scaling(0, k);
+            }
+            else
+            {
+                scaling(0, k) = NumericTraits<T>::one();
+            }
+        }
+        
+        return;     
+    }
+
+    vigra_precondition(!(unitVariance && unitNorm),
+        "prepareData(): Unit variance and unit norm cannot be achieved at the same time.");
+
+    Matrix<T> mean(1, n), sumOfSquaredDifferences(1, n);
+    detail::columnStatisticsImpl(A, mean, sumOfSquaredDifferences);
+    
+    for(MultiArrayIndex k=0; k<n; ++k)
+    {
+        T stdDev = std::sqrt(sumOfSquaredDifferences(0, k) / T(m-1));
+        if(closeAtTolerance(stdDev / mean(0,k), NumericTraits<T>::zero()))
+            stdDev = NumericTraits<T>::zero();
+        if(zeroMean && stdDev > NumericTraits<T>::zero()) 
+        {
+            columnVector(res, k) = columnVector(A, k) - mean(0,k);
+            offset(0, k) = mean(0, k);
+            mean(0, k) = NumericTraits<T>::zero();
+        }
+        else 
+        {
+            columnVector(res, k) = columnVector(A, k);
+            offset(0, k) = NumericTraits<T>::zero();
+        }
+        
+        T norm = mean(0,k) == NumericTraits<T>::zero()
+                  ? std::sqrt(sumOfSquaredDifferences(0, k))
+                  : std::sqrt(sumOfSquaredDifferences(0, k) + T(m) * sq(mean(0,k)));
+        if(unitNorm && norm > NumericTraits<T>::zero())
+        {
+            columnVector(res, k) /= norm;
+            scaling(0, k) = NumericTraits<T>::one() / norm;
+        }
+        else if(unitVariance && stdDev > NumericTraits<T>::zero())
+        {
+            columnVector(res, k) /= stdDev;
+            scaling(0, k) = NumericTraits<T>::one() / stdDev;
+        }
+        else
+        {
+            scaling(0, k) = NumericTraits<T>::one();
+        }
+    }
+}
+
+} // namespace detail
+
+    /** \brief Standardize the columns of a matrix according to given <tt>DataPreparationGoals</tt>.
+    
+    For every column of the matrix \a A, this function computes mean, 
+    standard deviation, and norm. It then applies a linear transformation to the values of 
+    the column according to these statistics and the given <tt>DataPreparationGoals</tt>.
+    The result is returned in matrix \a res which must have the same size as \a A.
+    Optionally, the transformation applied can also be returned in the matrices \a offset
+    and \a scaling (see below for an example how these matrices can be used to standardize
+    more data according to the same transformation).
+    
+    The following <tt>DataPreparationGoals</tt> are supported:
+    
+    <DL>
+    <DT><tt>ZeroMean</tt><DD> Subtract the column mean form every column if the values in the column are not constant. 
+                              Do nothing in a constant column.
+    <DT><tt>UnitSum</tt><DD> Scale the columns so that the their sum is one if the sum was initially non-zero. 
+                              Do nothing in a zero-sum column.
+    <DT><tt>UnitVariance</tt><DD> Divide by the column standard deviation if the values in the column are not constant. 
+                              Do nothing in a constant column.
+    <DT><tt>UnitNorm</tt><DD> Divide by the column norm if it is non-zero.
+    <DT><tt>ZeroMean | UnitVariance</tt><DD> First subtract the mean and then divide by the standard deviation, unless the 
+                                             column is constant (in which case the column remains unchanged).
+    <DT><tt>ZeroMean | UnitNorm</tt><DD> If the column is non-constant, subtract the mean. Then divide by the norm
+                                         of the result if the norm is non-zero.
+    </DL>
+
+    <b> Declarations:</b>
+
+    Standardize the matrix and return the parameters of the linear transformation.
+    The matrices \a offset and \a scaling must be row vectors with as many columns as \a A.
+    \code
+    namespace vigra { namespace linalg {
+        template <class T, class C1, class C2, class C3, class C4>
+        void
+        prepareColumns(MultiArrayView<2, T, C1> const & A, 
+                       MultiArrayView<2, T, C2> & res, 
+                       MultiArrayView<2, T, C3> & offset, 
+                       MultiArrayView<2, T, C4> & scaling, 
+                       DataPreparationGoals goals = ZeroMean | UnitVariance);
+    } }
+    \endcode
+
+    Only standardize the matrix.
+    \code
+    namespace vigra { namespace linalg {
+        template <class T, class C1, class C2>
+        void
+        prepareColumns(MultiArrayView<2, T, C1> const & A, 
+                       MultiArrayView<2, T, C2> & res, 
+                       DataPreparationGoals goals = ZeroMean | UnitVariance);
+    } }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+    <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+    Namespaces: vigra and vigra::linalg
+
+    \code
+    Matrix A(rows, columns);
+    .. // fill A
+    Matrix standardizedA(rows, columns), offset(1, columns), scaling(1, columns);
+
+    prepareColumns(A, standardizedA, offset, scaling, ZeroMean | UnitNorm);
+    
+    // use offset and scaling to prepare additional data according to the same transformation
+    Matrix newData(nrows, columns);
+    
+    Matrix standardizedNewData = (newData - repeatMatrix(offset, nrows, 1)) * pointWise(repeatMatrix(scaling, nrows, 1));
+
+    \endcode
+    */
+doxygen_overloaded_function(template <...> void prepareColumns)
+
+template <class T, class C1, class C2, class C3, class C4>
+inline void
+prepareColumns(MultiArrayView<2, T, C1> const & A, 
+               MultiArrayView<2, T, C2> & res, MultiArrayView<2, T, C3> & offset, MultiArrayView<2, T, C4> & scaling, 
+               DataPreparationGoals goals = ZeroMean | UnitVariance)
+{
+    detail::prepareDataImpl(A, res, offset, scaling, goals);
+}
+
+template <class T, class C1, class C2>
+inline void
+prepareColumns(MultiArrayView<2, T, C1> const & A, MultiArrayView<2, T, C2> & res, 
+               DataPreparationGoals goals = ZeroMean | UnitVariance)
+{
+    Matrix<T> offset(1, columnCount(A)), scaling(1, columnCount(A));
+    detail::prepareDataImpl(A, res, offset, scaling, goals);
+}
+
+    /** \brief Standardize the rows of a matrix according to given <tt>DataPreparationGoals</tt>.
+    
+    This algorithm works in the same way as \ref prepareColumns() (see there for detailed
+    documentation), but is applied to the rows of the matrix \a A instead. Accordingly, the
+    matrices holding the parameters of the linear transformation must be column vectors
+    with as many rows as \a A.
+
+    <b> Declarations:</b>
+
+    Standardize the matrix and return the parameters of the linear transformation.
+    The matrices \a offset and \a scaling must be column vectors
+    with as many rows as \a A.
+    
+    \code
+    namespace vigra { namespace linalg {
+        template <class T, class C1, class C2, class C3, class C4>
+        void
+        prepareRows(MultiArrayView<2, T, C1> const & A, 
+                    MultiArrayView<2, T, C2> & res, 
+                    MultiArrayView<2, T, C3> & offset, 
+                    MultiArrayView<2, T, C4> & scaling, 
+                    DataPreparationGoals goals = ZeroMean | UnitVariance)�;
+    } }
+    \endcode
+
+    Only standardize the matrix.
+    \code
+    namespace vigra { namespace linalg {
+        template <class T, class C1, class C2>
+        void
+        prepareRows(MultiArrayView<2, T, C1> const & A, 
+                    MultiArrayView<2, T, C2> & res, 
+                    DataPreparationGoals goals = ZeroMean | UnitVariance);
+    } }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/matrix.hxx\> or<br>
+    <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+    Namespaces: vigra and vigra::linalg
+
+    \code
+    Matrix A(rows, columns);
+    .. // fill A
+    Matrix standardizedA(rows, columns), offset(rows, 1), scaling(rows, 1);
+
+    prepareRows(A, standardizedA, offset, scaling, ZeroMean | UnitNorm);
+    
+    // use offset and scaling to prepare additional data according to the same transformation
+    Matrix newData(rows, ncolumns);
+    
+    Matrix standardizedNewData = (newData - repeatMatrix(offset, 1, ncolumns)) * pointWise(repeatMatrix(scaling, 1, ncolumns));
+
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void prepareRows)
+
+template <class T, class C1, class C2, class C3, class C4>
+inline void
+prepareRows(MultiArrayView<2, T, C1> const & A, 
+            MultiArrayView<2, T, C2> & res, MultiArrayView<2, T, C3> & offset, MultiArrayView<2, T, C4> & scaling, 
+            DataPreparationGoals goals = ZeroMean | UnitVariance)
+{
+    MultiArrayView<2, T, StridedArrayTag> tr = transpose(res), to = transpose(offset), ts = transpose(scaling);
+    detail::prepareDataImpl(transpose(A), tr, to, ts, goals);
+}
+
+template <class T, class C1, class C2>
+inline void
+prepareRows(MultiArrayView<2, T, C1> const & A, MultiArrayView<2, T, C2> & res, 
+            DataPreparationGoals goals = ZeroMean | UnitVariance)
+{
+    MultiArrayView<2, T, StridedArrayTag> tr = transpose(res);
+    Matrix<T> offset(1, rowCount(A)), scaling(1, rowCount(A));
+    detail::prepareDataImpl(transpose(A), tr, offset, scaling, goals);
+}
+
+//@}
+
+} // namespace linalg
+
+using linalg::columnStatistics;
+using linalg::prepareColumns;
+using linalg::rowStatistics;
+using linalg::prepareRows;
+using linalg::ZeroMean;
+using linalg::UnitVariance;
+using linalg::UnitNorm;
+using linalg::UnitSum;
+
+}  // namespace vigra
+
+
+
+#endif // VIGRA_MATRIX_HXX
diff --git a/include/vigra/memory.hxx b/include/vigra/memory.hxx
new file mode 100644
index 0000000..3d3b9fa
--- /dev/null
+++ b/include/vigra/memory.hxx
@@ -0,0 +1,119 @@
+/************************************************************************/
+/*                                                                      */
+/*         Copyright 2002-2003 by Ullrich Koethe, Hans Meine            */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MEMORY_HXX
+#define VIGRA_MEMORY_HXX
+
+#include "metaprogramming.hxx"
+
+namespace vigra { 
+
+enum SkipInitializationTag { SkipInitialization};
+
+template<class T>
+struct CanSkipInitialization
+{
+    typedef typename TypeTraits<T>::isBuiltinType type;
+    static const bool value = type::asBool;
+};
+
+namespace detail {
+
+// differs from std::uninitialized_copy by explicit type conversion
+template <class Src, class Dest>
+Dest uninitializedCopy(Src s, Src end, Dest d)
+{
+    typedef typename std::iterator_traits<Dest>::value_type T;
+    for(; s != end; ++s, ++d)
+        new(d) T(static_cast<T const &>(*s));
+    return d;
+}
+
+template <class T>
+inline void destroy_n(T * /* p */, std::ptrdiff_t /* n */, VigraTrueType /* isPOD */)
+{
+}
+
+template <class T>
+inline void destroy_n(T * p, std::ptrdiff_t n, VigraFalseType /* isPOD */)
+{
+    T * end = p + n;
+    for(; p != end; ++p)
+        p->~T();
+}
+
+template <class T>
+inline void destroy_n(T * p, std::ptrdiff_t n)
+{
+    destroy_n(p, n, typename TypeTraits<T>::isPOD());
+}
+
+/********************************************************************/
+
+// g++ 2.95 has std::destroy() in the STL
+#if !defined(__GNUC__) ||  __GNUC__ >= 3
+
+template <class T>
+inline void destroy(T * p, VigraTrueType /* isPOD */)
+{
+}
+
+template <class T>
+inline void destroy(T * p, VigraFalseType /* isPOD */)
+{
+    p->~T();
+}
+
+template <class T>
+inline void destroy(T * p)
+{
+    destroy(p, typename TypeTraits<T>::isPOD());
+}
+
+#else
+
+} } // namespace vigra::detail
+
+#include <memory>
+
+namespace vigra { namespace detail {
+
+using std::destroy;
+
+#endif
+
+} } // namespace vigra::detail
+
+#endif // VIGRA_MEMORY_HXX
diff --git a/include/vigra/meshgrid.hxx b/include/vigra/meshgrid.hxx
new file mode 100644
index 0000000..477972c
--- /dev/null
+++ b/include/vigra/meshgrid.hxx
@@ -0,0 +1,133 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 2009 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MESHGRID_HXX
+#define VIGRA_MESHGRID_HXX
+
+#include "tinyvector.hxx"
+#include "diff2d.hxx"
+
+namespace vigra{
+/** \addtogroup RangesAndPoints */
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                 MeshGridAccessor                     */
+/*                                                      */
+/********************************************************/
+/** Accessor for turning iteration over Diff2D into a mesh grid.
+
+    The mesh grid concept is adapted from MATLAB. It is a two banded image
+    (i.e. with 2D vector pixel type) whose first band contains the x-coordinates
+    of the current pixel, and whose second band contains the y-coordinates.
+    See \ref meshGrid() for more detailed documentation.
+*/
+struct MeshGridAccessor
+{
+        /** the value_type of a mesh grid is a 2D vector
+        */
+    typedef TinyVector<Diff2D::MoveX, 2> value_type;
+
+        /** read the current data item
+        */
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const
+    {
+        return value_type(i->x, i->y);
+    }
+
+        /** read the data item at an offset (can be 1D or 2D or higher order difference).
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE const & diff) const
+    {
+        return value_type(i->x+diff.x, i->y+diff.y);
+    }
+};
+
+/** Create a mesh grid for the specified rectangle.
+
+    The mesh grid concept is adapted from MATLAB. It is a two banded image
+    (i.e. with 2D vector pixel type) whose first band contains the x-coordinates
+    of the current pixel, and whose second band contains the y-coordinates.
+    If \a upperLeft is not the point (0,0), the mesh grid is translated relative to
+    the pixel indices.
+
+    <b> Declarations:</b>
+
+    \code
+    triple<Diff2D, Diff2D, MeshGridAccessor>
+    meshGrid(Diff2D upperLeft, Diff2D lowerRight);
+
+    triple<Diff2D, Diff2D, MeshGridAccessor>
+    meshGrid(Rect2D const & r);
+
+    \endcode
+
+    <b>Usage:</b>
+
+    \code
+    #include <vigra/meshgrid.hxx>
+    // create an image whose values are equal to each pixel's distance from the image center
+    int width = 5, height = 7;
+    int xc = width/2, yc = height/2; // the image center
+
+    FImage dist(width, height);
+    Point2D upperLeft(-xc, -yc);
+
+    using namespace vigra::functor;
+    transformImage(meshGrid(upperLeft, upperLeft+dist.size()),
+                   destImage(dist),
+                   norm(Arg1()));
+    \endcode
+*/
+inline
+triple<Diff2D, Diff2D, MeshGridAccessor>
+meshGrid(Diff2D upperLeft, Diff2D lowerRight)
+{
+    return triple<Diff2D, Diff2D, MeshGridAccessor>(upperLeft, lowerRight, MeshGridAccessor());
+}
+
+inline
+triple<Diff2D, Diff2D, MeshGridAccessor>
+meshGrid(Rect2D const & r)
+{
+    return triple<Diff2D, Diff2D, MeshGridAccessor>(r.upperLeft(), r.lowerRight(), MeshGridAccessor());
+}
+
+}//namespace vigra
+//@}
+#endif //VIGRA_MESHGRID_HXX
diff --git a/include/vigra/metaprogramming.hxx b/include/vigra/metaprogramming.hxx
new file mode 100644
index 0000000..e02a977
--- /dev/null
+++ b/include/vigra/metaprogramming.hxx
@@ -0,0 +1,848 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_METAPROGRAMMING_HXX
+#define VIGRA_METAPROGRAMMING_HXX
+
+#include "config.hxx"
+#include <climits>
+#include <limits>
+#include <algorithm>
+
+namespace vigra {
+
+// mask cl.exe shortcomings [begin]
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4503 )
+#endif
+
+template <int N>
+class MetaInt
+{
+  public:
+    static const int value = N;
+};
+
+template <int N1, int N2>
+class MetaMax
+{
+  public:
+    static const int value = N1 < N2 ? N2 : N1;
+};
+
+template <int N1, int N2>
+class MetaMin
+{
+  public:
+    static const int value = N1 < N2 ? N1 : N2;
+};
+
+struct VigraTrueType
+{
+   static const bool asBool = true, value = true;
+};
+
+struct VigraFalseType
+{
+    static const bool asBool = false, value = false;
+};
+
+/**  \addtogroup MultiArrayTags Multi-dimensional Array Tags
+      Meta-programming tags to mark array's as strided or unstrided.
+*/
+
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                   StridedArrayTag                    */
+/*                                                      */
+/********************************************************/
+
+/** tag for marking a MultiArray strided.
+
+    <b>\#include</b> \<vigra/multi_array.hxx\> <br/>
+    Namespace: vigra
+*/
+struct StridedArrayTag {};
+
+/********************************************************/
+/*                                                      */
+/*                  UnstridedArrayTag                   */
+/*                                                      */
+/********************************************************/
+
+/** tag for marking a MultiArray unstrided.
+
+    <b>\#include</b> \<vigra/multi_array.hxx\> <br/>
+    Namespace: vigra
+*/
+struct UnstridedArrayTag {};
+
+template<class T>
+class TypeTraits
+{
+  public:
+    typedef VigraFalseType isConst;
+    typedef VigraFalseType isPOD;
+    typedef VigraFalseType isBuiltinType;
+};
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template<class T>
+class TypeTraits<T const>
+: public TypeTraits<T>
+{
+  public:
+    typedef VigraTrueType isConst;
+};
+
+template<class T> 
+class TypeTraits<T *>
+{
+  public:
+    typedef VigraFalseType isConst;
+    typedef VigraTrueType isPOD;
+    typedef VigraTrueType isBuiltinType;
+};
+
+template<class T> 
+class TypeTraits<T const *>
+{
+  public:
+    typedef VigraFalseType isConst;
+    typedef VigraTrueType isPOD;
+    typedef VigraTrueType isBuiltinType;
+};
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+namespace detail {
+
+template <int size>
+struct SizeToType;
+
+} // namespace detail 
+
+#define VIGRA_TYPE_TRAITS(type, size) \
+template<> \
+class TypeTraits<type> \
+{ \
+  public: \
+    typedef VigraFalseType isConst; \
+    typedef VigraTrueType isPOD; \
+    typedef VigraTrueType isBuiltinType; \
+    typedef char TypeToSize[size]; \
+}; \
+ \
+namespace detail { \
+  TypeTraits<type>::TypeToSize * typeToSize(type); \
+  \
+  template <> \
+  struct SizeToType<size> \
+  { \
+      typedef type result; \
+  }; \
+} 
+
+VIGRA_TYPE_TRAITS(char, 1)
+VIGRA_TYPE_TRAITS(signed char, 2)
+VIGRA_TYPE_TRAITS(unsigned char, 3)
+VIGRA_TYPE_TRAITS(short, 4)
+VIGRA_TYPE_TRAITS(unsigned short, 5)
+VIGRA_TYPE_TRAITS(int, 6)
+VIGRA_TYPE_TRAITS(unsigned int, 7)
+VIGRA_TYPE_TRAITS(long, 8)
+VIGRA_TYPE_TRAITS(unsigned long, 9)
+VIGRA_TYPE_TRAITS(float, 10)
+VIGRA_TYPE_TRAITS(double, 11)
+VIGRA_TYPE_TRAITS(long double, 12)
+#ifdef LLONG_MAX
+VIGRA_TYPE_TRAITS(long long, 13)
+VIGRA_TYPE_TRAITS(unsigned long long, 14)
+#endif
+
+#undef VIGRA_TYPE_TRAITS
+
+//@}
+
+template <class A>
+struct Not;
+
+template <>
+struct Not<VigraTrueType>
+{
+    typedef VigraFalseType result;        // deprecated
+    static const bool boolResult = false; // deprecated
+    typedef VigraFalseType type;
+    static const bool value = false;
+};
+
+template <>
+struct Not<VigraFalseType>
+{
+    typedef VigraTrueType result;        // deprecated
+    static const bool boolResult = true; // deprecated
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+template <class L, class R>
+struct And;
+
+template <>
+struct And<VigraFalseType, VigraFalseType>
+{
+    typedef VigraFalseType result;        // deprecated
+    static const bool boolResult = false; // deprecated
+    typedef VigraFalseType type;
+    static const bool value = false;
+};
+
+template <>
+struct And<VigraFalseType, VigraTrueType>
+{
+    typedef VigraFalseType result;        // deprecated
+    static const bool boolResult = false; // deprecated
+    typedef VigraFalseType type;
+    static const bool value = false;
+};
+
+template <>
+struct And<VigraTrueType, VigraFalseType>
+{
+    typedef VigraFalseType result;        // deprecated
+    static const bool boolResult = false; // deprecated
+    typedef VigraFalseType type;
+    static const bool value = false;
+};
+
+template <>
+struct And<VigraTrueType, VigraTrueType>
+{
+    typedef VigraTrueType result;        // deprecated
+    static const bool boolResult = true; // deprecated
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+template <class L, class R>
+struct Or;
+
+template <>
+struct Or<VigraFalseType, VigraFalseType>
+{
+    typedef VigraFalseType result;        // deprecated
+    static const bool boolResult = false; // deprecated
+    typedef VigraFalseType type;
+    static const bool value = false;
+};
+
+template <>
+struct Or<VigraTrueType, VigraFalseType>
+{
+    typedef VigraTrueType result;        // deprecated
+    static const bool boolResult = true; // deprecated
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+template <>
+struct Or<VigraFalseType, VigraTrueType>
+{
+    typedef VigraTrueType result;        // deprecated
+    static const bool boolResult = true; // deprecated
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+template <>
+struct Or<VigraTrueType, VigraTrueType>
+{
+    typedef VigraTrueType result;        // deprecated
+    static const bool boolResult = true; // deprecated
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class PREDICATE, class TRUECASE, class FALSECASE>
+struct If;
+
+template <class TRUECASE, class FALSECASE>
+struct If<VigraTrueType, TRUECASE, FALSECASE>
+{
+    typedef TRUECASE type;
+};
+
+template <class TRUECASE, class FALSECASE>
+struct If<VigraFalseType, TRUECASE, FALSECASE>
+{
+    typedef FALSECASE type;
+};
+
+template <bool PREDICATE, class TRUECASE, class FALSECASE>
+struct IfBool;
+
+template <class TRUECASE, class FALSECASE>
+struct IfBool<true, TRUECASE, FALSECASE>
+{
+    typedef TRUECASE type;
+};
+
+template <class TRUECASE, class FALSECASE>
+struct IfBool<false, TRUECASE, FALSECASE>
+{
+    typedef FALSECASE type;
+};
+
+template <class L, class R>
+struct IsSameType
+{
+    typedef VigraFalseType result;        // deprecated
+    static const bool boolResult = false; // deprecated
+    typedef VigraFalseType type;
+    static const bool value = false;
+};
+
+template <class T>
+struct IsSameType<T, T>
+{
+    typedef VigraTrueType result;        // deprecated
+    static const bool boolResult = true; // deprecated
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+template <class L, class R>
+struct IsDifferentType
+{
+    typedef VigraTrueType type;
+    static const bool value = true;
+};
+
+template <class T>
+struct IsDifferentType<T, T>
+{
+    typedef VigraFalseType type;
+    static const bool value = false;
+};
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class From, class To>
+struct IsConvertibleTo
+{
+    typedef char falseResult[1];
+    typedef char trueResult[2];
+    
+    static From const & check();
+    
+    static falseResult * testIsConvertible(...);
+    static trueResult * testIsConvertible(To const &);
+    
+    enum { resultSize = sizeof(*testIsConvertible(check())) };
+    
+    static const bool value = (resultSize == 2);
+    typedef typename 
+        IfBool<value, VigraTrueType, VigraFalseType>::type
+        type;
+};
+
+template <class DERIVED, class BASE>
+struct IsDerivedFrom
+{
+    typedef char falseResult[1];
+    typedef char trueResult[2];
+    
+    static falseResult * testIsDerivedFrom(...);
+    static trueResult * testIsDerivedFrom(BASE const *);
+    
+    enum { resultSize = sizeof(*testIsDerivedFrom((DERIVED const *)0)) };
+    
+    static const bool value = (resultSize == 2);
+    typedef typename 
+        IfBool<value, VigraTrueType, VigraFalseType>::type
+        type;
+
+    static const bool boolResult = value; // deprecated
+    typedef type result;                  // deprecated
+};
+
+template <class T>
+struct UnqualifiedType
+{
+    typedef T type;
+};
+
+template <class T>
+struct UnqualifiedType<T const>
+{
+    typedef T type;
+};
+
+template <class T>
+struct UnqualifiedType<T &>
+: public UnqualifiedType<T>
+{};
+
+template <class T>
+struct UnqualifiedType<T const &>
+: public UnqualifiedType<T>
+{};
+
+template <class T>
+struct UnqualifiedType<T *>
+: public UnqualifiedType<T>
+{};
+
+template <class T>
+struct UnqualifiedType<T const *>
+: public UnqualifiedType<T>
+{};
+
+template <bool, class T = void>
+struct enable_if {};
+template <class T>
+struct enable_if<true, T> { typedef T type; };
+
+struct sfinae_void;
+
+template <class T, template<class> class USER>
+struct sfinae_test
+{
+    typedef char falseResult[1];
+    typedef char trueResult[2];
+    
+    static falseResult * test(...);
+    static trueResult * test(USER<sfinae_void>);
+    
+    enum { resultSize = sizeof(*test((T*)0)) };
+    
+    static const bool value = (resultSize == 2);
+    typedef typename
+        IfBool<value, VigraTrueType, VigraFalseType>::type
+        type;
+};
+
+template <class T>
+struct has_argument_type : public sfinae_test<T, has_argument_type>
+{
+    template <class U> has_argument_type(U*, typename U::argument_type* = 0);
+};
+
+template <class T>
+struct has_result_type : public sfinae_test<T, has_result_type>
+{
+    template <class U> has_result_type(U*, typename U::result_type* = 0);
+};
+
+template <class T>
+struct has_value_type : public sfinae_test<T, has_value_type>
+{
+    template <class U> has_value_type(U*, typename U::value_type* = 0);
+};
+
+template <class T>
+struct IsIterator : public sfinae_test<T, IsIterator>
+{
+    template <class U> IsIterator(U*, typename U::iterator_category* = 0);
+};
+
+template <class T>
+struct IsIterator<T*>
+{
+    static const bool value = true;
+    typedef VigraTrueType type;
+};
+
+template <class T>
+struct IsIterator<T const *>
+{
+    static const bool value = true;
+    typedef VigraTrueType type;
+};
+
+template <class T>
+struct has_real_promote_type : public sfinae_test<T, has_real_promote_type>
+{
+    template <class U>
+    has_real_promote_type(U*, typename U::real_promote_type* = 0);
+};
+
+template <class T, bool P = has_real_promote_type<T>::value>
+struct get_optional_real_promote
+{
+    typedef T type;
+};
+template <class T>
+struct get_optional_real_promote<T, true>
+{
+    typedef typename T::real_promote_type type;
+};
+
+template <class T>
+struct IsArray
+{
+    typedef char falseResult[1];
+    typedef char trueResult[2];
+    
+    static falseResult * test(...);
+    template <class U, unsigned n>
+    static trueResult * test(U (*)[n]);
+    
+    enum { resultSize = sizeof(*test((T*)0)) };
+    
+    static const bool value = (resultSize == 2);
+    typedef typename
+        IfBool<value, VigraTrueType, VigraFalseType>::type
+        type;
+};
+
+
+template <class D, class B, class Z> inline
+D & static_cast_2(Z & z)
+{
+    return static_cast<D &>(static_cast<B &>(z));
+}
+
+template <class A>
+class copy_if_same_as
+{
+    const bool copied;
+    const A *const data;
+    copy_if_same_as(const copy_if_same_as &);
+    void operator=(const copy_if_same_as &);
+public:
+    copy_if_same_as(const A & x, const A & y)
+        : copied(&x == &y), data(copied ? new A(y) : &x) {}
+    ~copy_if_same_as()
+    {
+        if (copied)
+            delete data;
+    }
+    const A & operator()() const { return *data; }
+};
+
+
+template <class>
+struct true_test : public VigraTrueType {};
+
+template <class>
+struct false_test : VigraFalseType {};
+
+template <class PC, class T, class F>
+struct ChooseBool
+{
+    static const bool value = IfBool<PC::value, T, F>::type::value;
+};
+
+template <bool>
+struct choose_type
+{
+    template <class A, class B>
+    static const A & at(const A & a, const B &) { return a; }
+    template <class A, class B>
+    static       A & at(      A & a,       B &) { return a; }
+};
+template <>
+struct choose_type<false>
+{
+    template <class A, class B>
+    static const B & at(const A &, const B & b) { return b; }
+    template <class A, class B>
+    static       B & at(      A &,       B & b) { return b; }
+};
+
+template <class X>
+struct HasMetaLog2
+{
+    static const bool value =   !std::numeric_limits<X>::is_signed
+                              && std::numeric_limits<X>::is_integer;
+};
+template <class X>
+struct EnableMetaLog2
+    : public enable_if<HasMetaLog2<X>::value> {};
+template <class>
+class vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_;
+
+// use a conforming template depth here (below 15 for up to 128 bits)
+template <class X = unsigned long,
+          X n = ~(X(0)), unsigned s = 1, unsigned t = 0, bool q = 1,
+          X m = 0, X z = 0, X u = 1, class = void>
+class MetaLog2
+    : public vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_<X>
+{};
+template <class X, X n, unsigned s, unsigned t, bool q, X m, X z, X u>
+struct MetaLog2 <X, n, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
+{
+    static const unsigned value
+        = t + MetaLog2<X, (n >> s), s * (1 + q), s, !q, n / 2, z, u>::value;
+};
+template <class X, unsigned s, unsigned t, bool q, X m, X z, X u>
+struct MetaLog2<X, z, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
+{
+    static const unsigned value
+        = 1 + MetaLog2<X, m / 2, 2, 1, 1, 0, z, u>::value;
+};
+template <class X, unsigned s, unsigned t, bool q, X z, X u>
+struct MetaLog2<X, z, s, t, q, u, z, u, typename EnableMetaLog2<X>::type>
+{
+    static const unsigned value = 2;
+};
+template <class X, unsigned s, unsigned t, bool q, X z, X u>
+struct MetaLog2<X, z, s, t, q, z, z, u, typename EnableMetaLog2<X>::type>
+{
+    static const unsigned value = 1;
+};
+template <class X, X z, X u>
+struct MetaLog2<X, z, 1, 0, 1, z, z, u, typename EnableMetaLog2<X>::type>
+{
+    // A value of zero for MetaLog2<X, 0> is likely to cause most harm,
+    // such as division by zero or zero array sizes, this is actually indended.
+    static const unsigned value = 0;
+};
+
+template <int X, unsigned int N>
+struct MetaPow
+{
+    static const long long value = MetaPow<X, N-1>::value * X;
+};
+
+template <int X>
+struct MetaPow<X, 0>
+{
+    static const long long value = 1;
+};
+
+/****************************************************************************/
+/*                                                                          */
+/*                        TypeList and its functions                        */
+/*                                                                          */
+/****************************************************************************/
+
+template<class HEAD, class TAIL=void>
+struct TypeList
+{
+	typedef TypeList<HEAD, TAIL> type;
+    typedef HEAD Head;
+    typedef TAIL Tail;
+};
+
+template <class List, class T>
+struct Contains;
+
+template <class Head, class Tail, class T>
+struct Contains<TypeList<Head, Tail>, T>
+{
+    typedef typename Contains<Tail, T>::type type;
+};
+
+template <class Head, class Tail>
+struct Contains<TypeList<Head, Tail>, Head>
+{
+    typedef VigraTrueType type;
+};
+
+template <class T>
+struct Contains<void, T>
+{
+    typedef VigraFalseType type;
+};
+
+template <class List, class T>
+struct Remove;
+
+template <class Head, class Tail, class T>
+struct Remove<TypeList<Head, Tail>, T>
+{
+    typedef TypeList<Head, typename Remove<Tail, T>::type> type;
+};
+
+template <class Head, class Tail>
+struct Remove<TypeList<Head, Tail>, Head>
+{
+    typedef Tail type;
+};
+
+template <class T>
+struct Remove<void, T>
+{
+    typedef void type;
+};
+
+template <class A, class Tail=void>
+struct Push
+{
+    typedef TypeList<A, typename Tail::type> type;
+};
+
+template <class Head, class Tail, class List>
+struct Push<TypeList<Head, Tail>, List>
+{
+    typedef typename Push<Tail, List>::type Rest;
+    typedef TypeList<Head, Rest> type;
+};
+
+template <class Head, class Tail>
+struct Push<TypeList<Head, Tail>, void>
+{
+    typedef TypeList<Head, Tail> type;
+};
+
+template <class A>
+struct Push<A, void>
+{
+    typedef TypeList<A> type;
+};
+
+template <class A>
+struct Push<void, A>
+{
+    typedef A type;
+};
+
+template <>
+struct Push<void, void>
+{
+    typedef void type;
+};
+
+template <class A, class Tail=void>
+struct PushUnique
+{
+    typedef typename Contains<Tail, A>::type AlreadyInList;
+    typedef typename If<AlreadyInList, typename Tail::type, TypeList<A, typename Tail::type> >::type type;
+};
+
+template <class Head, class Tail, class List>
+struct PushUnique<TypeList<Head, Tail>, List>
+{
+    typedef typename PushUnique<Tail, List>::type Rest;
+    typedef typename Contains<Rest, Head>::type HeadAlreadyInList;
+    typedef typename If<HeadAlreadyInList, Rest, TypeList<Head, Rest> >::type type;
+};
+
+template <class Head, class Tail>
+struct PushUnique<TypeList<Head, Tail>, void>
+{
+    typedef TypeList<Head, Tail> type;
+};
+
+template <class A>
+struct PushUnique<A, void>
+{
+    typedef TypeList<A> type;
+};
+
+template <class A>
+struct PushUnique<void, A>
+{
+    typedef A type;
+};
+
+template <>
+struct PushUnique<void, void>
+{
+    typedef void type;
+};
+
+template <class T01=void, class T02=void, class T03=void, class T04=void, class T05=void,
+          class T06=void, class T07=void, class T08=void, class T09=void, class T10=void,
+          class T11=void, class T12=void, class T13=void, class T14=void, class T15=void,
+          class T16=void, class T17=void, class T18=void, class T19=void, class T20=void>
+struct MakeTypeList
+{
+    typedef typename Push<T19, T20>::type L19;
+    typedef typename Push<T18, L19>::type L18;
+    typedef typename Push<T17, L18>::type L17;
+    typedef typename Push<T16, L17>::type L16;
+    typedef typename Push<T15, L16>::type L15;
+    typedef typename Push<T14, L15>::type L14;
+    typedef typename Push<T13, L14>::type L13;
+    typedef typename Push<T12, L13>::type L12;
+    typedef typename Push<T11, L12>::type L11;
+    typedef typename Push<T10, L11>::type L10;
+    typedef typename Push<T09, L10>::type L09;
+    typedef typename Push<T08, L09>::type L08;
+    typedef typename Push<T07, L08>::type L07;
+    typedef typename Push<T06, L07>::type L06;
+    typedef typename Push<T05, L06>::type L05;
+    typedef typename Push<T04, L05>::type L04;
+    typedef typename Push<T03, L04>::type L03;
+    typedef typename Push<T02, L03>::type L02;
+    typedef typename Push<T01, L02>::type L01;
+    typedef L01 type;
+};
+
+template <class T01=void, class T02=void, class T03=void, class T04=void, class T05=void,
+          class T06=void, class T07=void, class T08=void, class T09=void, class T10=void,
+          class T11=void, class T12=void, class T13=void, class T14=void, class T15=void,
+          class T16=void, class T17=void, class T18=void, class T19=void, class T20=void>
+struct MakeTypeListUnique
+{
+    typedef typename PushUnique<T19, T20>::type L19;
+    typedef typename PushUnique<T18, L19>::type L18;
+    typedef typename PushUnique<T17, L18>::type L17;
+    typedef typename PushUnique<T16, L17>::type L16;
+    typedef typename PushUnique<T15, L16>::type L15;
+    typedef typename PushUnique<T14, L15>::type L14;
+    typedef typename PushUnique<T13, L14>::type L13;
+    typedef typename PushUnique<T12, L13>::type L12;
+    typedef typename PushUnique<T11, L12>::type L11;
+    typedef typename PushUnique<T10, L11>::type L10;
+    typedef typename PushUnique<T09, L10>::type L09;
+    typedef typename PushUnique<T08, L09>::type L08;
+    typedef typename PushUnique<T07, L08>::type L07;
+    typedef typename PushUnique<T06, L07>::type L06;
+    typedef typename PushUnique<T05, L06>::type L05;
+    typedef typename PushUnique<T04, L05>::type L04;
+    typedef typename PushUnique<T03, L04>::type L03;
+    typedef typename PushUnique<T02, L03>::type L02;
+    typedef typename PushUnique<T01, L02>::type L01;
+    typedef L01 type;
+};
+
+// mask cl.exe shortcomings [end]
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+} // namespace vigra
+
+#endif /* VIGRA_METAPROGRAMMING_HXX */
diff --git a/include/vigra/multi_array.hxx b/include/vigra/multi_array.hxx
new file mode 100644
index 0000000..bcf8597
--- /dev/null
+++ b/include/vigra/multi_array.hxx
@@ -0,0 +1,3383 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2003-2008 by Gunnar Kedenburg and Ullrich Koethe       */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_MULTI_ARRAY_HXX
+#define VIGRA_MULTI_ARRAY_HXX
+
+#include <memory>
+#include <algorithm>
+#include "accessor.hxx"
+#include "tinyvector.hxx"
+#include "rgbvalue.hxx"
+#include "basicimage.hxx"
+#include "imageiterator.hxx"
+#include "numerictraits.hxx"
+#include "multi_iterator.hxx"
+#include "multi_pointoperators.hxx"
+#include "metaprogramming.hxx"
+#include "mathutil.hxx"
+
+// Bounds checking Macro used if VIGRA_CHECK_BOUNDS is defined.
+#ifdef VIGRA_CHECK_BOUNDS
+#define VIGRA_ASSERT_INSIDE(diff) \
+  vigra_precondition(this->isInside(diff), "Index out of bounds")
+#else
+#define VIGRA_ASSERT_INSIDE(diff)
+#endif
+
+namespace vigra
+{
+
+namespace detail
+{
+
+/********************************************************/
+/*                                                      */
+/*                     MaybeStrided                     */
+/*                                                      */
+/********************************************************/
+
+/* metatag implementing a test for marking MultiArrays that were
+    indexed at the zero'th dimension as strided, and all others as
+    unstrided.
+
+    <b>\#include</b> \<vigra/multi_array.hxx\> <br/>
+    Namespace: vigra::detail
+*/
+template <class StrideTag, unsigned int N>
+struct MaybeStrided
+{
+    typedef StrideTag type;
+};
+
+template <class StrideTag>
+struct MaybeStrided <StrideTag, 0>
+{
+    typedef StridedArrayTag type;
+};
+
+/********************************************************/
+/*                                                      */
+/*                MultiIteratorChooser                  */
+/*                                                      */
+/********************************************************/
+
+/* metatag implementing a test (by pattern matching) for marking
+    MultiArrays that were indexed at the zero'th dimension as strided.
+
+    <b>\#include</b> \<vigra/multi_array.hxx\> <br/>
+    Namespace: vigra::detail
+*/
+template <class O>
+struct MultiIteratorChooser;
+
+/********************************************************/
+/*                                                      */
+/*       MultiIteratorChooser <StridedArrayTag>         */
+/*                                                      */
+/********************************************************/
+
+/* specialization of the MultiIteratorChooser for strided arrays.
+
+    <b>\#include</b> \<vigra/multi_array.hxx\> <br/>
+    Namespace: vigra::detail
+*/
+template <>
+struct MultiIteratorChooser <StridedArrayTag>
+{
+    template <unsigned int N, class T, class REFERENCE, class POINTER>
+    struct Traverser
+    {
+        typedef StridedMultiIterator <N, T, REFERENCE, POINTER> type;
+    };
+    
+    template <unsigned int N, class T, class REFERENCE, class POINTER>
+    struct Iterator
+    {
+        typedef StridedScanOrderIterator <N, T, REFERENCE, POINTER> type;
+    };
+    
+    template <class Iter, class View>
+    static Iter constructIterator(View * v)
+    {
+        return v->begin();
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*      MultiIteratorChooser <UnstridedArrayTag>        */
+/*                                                      */
+/********************************************************/
+
+/* specialization of the MultiIteratorChooser for unstrided arrays.
+
+    <b>\#include</b> \<vigra/multi_array.hxx\> <br/>
+    Namespace: vigra::detail
+*/
+template <>
+struct MultiIteratorChooser <UnstridedArrayTag>
+{
+    template <unsigned int N, class T, class REFERENCE, class POINTER>
+    struct Traverser
+    {
+        typedef MultiIterator <N, T, REFERENCE, POINTER> type;
+    };
+    
+    template <unsigned int N, class T, class REFERENCE, class POINTER>
+    struct Iterator
+    {
+        typedef POINTER type;
+    };
+    
+    template <class Iter, class View>
+    static Iter constructIterator(View * v)
+    {
+        return v->data();
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                   helper functions                   */
+/*                                                      */
+/********************************************************/
+
+template <class DestIterator, class Shape, class T>
+inline void
+initMultiArrayData(DestIterator d, Shape const & shape, T const & init, MetaInt<0>)
+{
+    DestIterator dend = d + shape[0];
+    for(; d < dend; ++d)
+    {
+        *d = init;
+    }
+}
+
+template <class DestIterator, class Shape, class T, int N>
+void
+initMultiArrayData(DestIterator d, Shape const & shape, T const & init, MetaInt<N>)
+{
+    DestIterator dend = d + shape[N];
+    for(; d < dend; ++d)
+    {
+        initMultiArrayData(d.begin(), shape, init, MetaInt<N-1>());
+    }
+}
+
+// FIXME: the explicit overload for MultiIterator<1, UInt8, ... > works around a compiler crash in VisualStudio 2010
+#define VIGRA_COPY_MULTI_ARRAY_DATA(name, op) \
+template <class SrcIterator, class Shape, class DestIterator> \
+inline void \
+name##MultiArrayData(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<0>) \
+{     \
+    SrcIterator send = s + shape[0]; \
+    for(; s < send; ++s, ++d) \
+    { \
+        *d op detail::RequiresExplicitCast<typename DestIterator::value_type>::cast(*s); \
+    } \
+} \
+ \
+template <class Ref, class Ptr, class Shape, class DestIterator> \
+inline void \
+name##MultiArrayData(MultiIterator<1, UInt8, Ref, Ptr> si, Shape const & shape, DestIterator d, MetaInt<0>) \
+{ \
+    Ptr s = &(*si), send = s + shape[0]; \
+    for(; s < send; ++s, ++d) \
+    { \
+        *d op detail::RequiresExplicitCast<typename DestIterator::value_type>::cast(*s); \
+    } \
+} \
+\
+template <class SrcIterator, class Shape, class DestIterator, int N> \
+void \
+name##MultiArrayData(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<N>) \
+{ \
+    SrcIterator send = s + shape[N]; \
+    for(; s < send; ++s, ++d) \
+    { \
+        name##MultiArrayData(s.begin(), shape, d.begin(), MetaInt<N-1>()); \
+    } \
+} \
+\
+template <class DestIterator, class Shape, class T> \
+inline void \
+name##ScalarMultiArrayData(DestIterator d, Shape const & shape, T const & init, MetaInt<0>) \
+{     \
+    DestIterator dend = d + shape[0]; \
+    for(; d < dend; ++d) \
+    { \
+        *d op detail::RequiresExplicitCast<typename DestIterator::value_type>::cast(init); \
+    } \
+} \
+ \
+template <class DestIterator, class Shape, class T, int N> \
+void \
+name##ScalarMultiArrayData(DestIterator d, Shape const & shape, T const & init, MetaInt<N>) \
+{     \
+    DestIterator dend = d + shape[N]; \
+    for(; d < dend; ++d) \
+    { \
+        name##ScalarMultiArrayData(d.begin(), shape, init, MetaInt<N-1>()); \
+    } \
+}
+
+VIGRA_COPY_MULTI_ARRAY_DATA(copy, =)
+VIGRA_COPY_MULTI_ARRAY_DATA(copyAdd, +=)
+VIGRA_COPY_MULTI_ARRAY_DATA(copySub, -=)
+VIGRA_COPY_MULTI_ARRAY_DATA(copyMul, *=)
+VIGRA_COPY_MULTI_ARRAY_DATA(copyDiv, /=)
+
+#undef VIGRA_COPY_MULTI_ARRAY_DATA
+
+template <class SrcIterator, class Shape, class T, class ALLOC>
+inline void
+uninitializedCopyMultiArrayData(SrcIterator s, Shape const & shape, T * & d, ALLOC & a, MetaInt<0>)
+{
+    SrcIterator send = s + shape[0];
+    for(; s < send; ++s, ++d)
+    {
+        a.construct(d, static_cast<T const &>(*s));
+    }
+}
+
+// FIXME: this overload works around a compiler crash in VisualStudio 2010
+template <class Ref, class Ptr, class Shape, class T, class ALLOC>
+inline void
+uninitializedCopyMultiArrayData(MultiIterator<1, UInt8, Ref, Ptr> si, Shape const & shape, T * & d, ALLOC & a, MetaInt<0>)
+{
+    Ptr s = &(*si), send = s + shape[0];
+    for(; s < send; ++s, ++d)
+    {
+        a.construct(d, static_cast<T const &>(*s));
+    }
+}
+
+template <class SrcIterator, class Shape, class T, class ALLOC, int N>
+void
+uninitializedCopyMultiArrayData(SrcIterator s, Shape const & shape, T * & d, ALLOC & a, MetaInt<N>)
+{
+    SrcIterator send = s + shape[N];
+    for(; s < send; ++s)
+    {
+        uninitializedCopyMultiArrayData(s.begin(), shape, d, a, MetaInt<N-1>());
+    }
+}
+
+template <class SrcIterator, class Shape, class T, class Functor>
+inline void
+reduceOverMultiArray(SrcIterator s, Shape const & shape, T & result, Functor const & f, MetaInt<0>)
+{
+    SrcIterator send = s + shape[0];
+    for(; s < send; ++s)
+    {
+        f(result, *s);
+    }
+}
+
+template <class SrcIterator, class Shape, class T, class Functor, int N>
+void
+reduceOverMultiArray(SrcIterator s, Shape const & shape, T & result, Functor const & f, MetaInt<N>)
+{
+    SrcIterator send = s + shape[N];
+    for(; s < send; ++s)
+    {
+        reduceOverMultiArray(s.begin(), shape, result, f, MetaInt<N-1>());
+    }
+}
+
+struct MaxNormReduceFunctor
+{
+    template <class T, class U>
+    void operator()(T & result, U const & u) const
+    {
+        T v = norm(u);
+        if(result < v)
+            result = v;
+    }
+};
+
+struct L1NormReduceFunctor
+{
+    template <class T, class U>
+    void operator()(T & result, U const & u) const
+    {
+        result += norm(u);
+    }
+};
+
+struct SquaredL2NormReduceFunctor
+{
+    template <class T, class U>
+    void operator()(T & result, U const & u) const
+    {
+        result += squaredNorm(u);
+    }
+};
+
+template <class T>
+struct WeightedL2NormReduceFunctor
+{
+    T scale;
+
+    WeightedL2NormReduceFunctor(T s)
+    : scale(s)
+    {}
+
+    template <class U>
+    void operator()(T & result, U const & u) const
+    {
+        result += squaredNorm(u * scale);
+    }
+};
+
+struct SumReduceFunctor
+{
+    template <class T, class U>
+    void operator()(T & result, U const & u) const
+    {
+        result += u;
+    }
+};
+
+struct ProdReduceFunctor
+{
+    template <class T, class U>
+    void operator()(T & result, U const & u) const
+    {
+        result *= u;
+    }
+};
+
+struct MinmaxReduceFunctor
+{
+    template <class T, class U>
+    void operator()(T & result, U const & u) const
+    {
+        if(u < result.first)
+            result.first = u;
+        if(result.second < u)
+            result.second = u;
+    }
+};
+
+struct MeanVarianceReduceFunctor
+{
+    template <class T, class U>
+    void operator()(T & result, U const & u) const
+    {
+        ++result.first;
+        typename T::second_type t1 = u - result.second;
+        typename T::second_type t2 = t1 / result.first;
+        result.second += t2;
+        result.third += (result.first-1.0)*t1*t2;
+    }
+};
+
+struct AllTrueReduceFunctor
+{
+    template <class T, class U>
+    void operator()(T & result, U const & u) const
+    {
+        result = result && (u != NumericTraits<U>::zero());
+    }
+};
+
+struct AnyTrueReduceFunctor
+{
+    template <class T, class U>
+    void operator()(T & result, U const & u) const
+    {
+        result = result || (u != NumericTraits<U>::zero());
+    }
+};
+
+template <class SrcIterator, class Shape, class DestIterator>
+inline bool
+equalityOfMultiArrays(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<0>)
+{
+    SrcIterator send = s + shape[0];
+    for(; s < send; ++s, ++d)
+    {
+        if(!(*s == *d))
+            return false;
+    }
+    return true;
+}
+
+template <class SrcIterator, class Shape, class DestIterator, int N>
+bool
+equalityOfMultiArrays(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<N>)
+{
+    SrcIterator send = s + shape[N];
+    for(; s < send; ++s, ++d)
+    {
+        if(!equalityOfMultiArrays(s.begin(), shape, d.begin(), MetaInt<N-1>()))
+            return false;
+    }
+    return true;
+}
+
+
+template <class SrcIterator, class Shape, class DestIterator>
+inline void
+swapDataImpl(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<0>)
+{
+    SrcIterator send = s + shape[0];
+    for(; s < send; ++s, ++d)
+        std::swap(*s, *d);
+}
+
+template <class SrcIterator, class Shape, class DestIterator, int N>
+void
+swapDataImpl(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<N>)
+{
+    SrcIterator send = s + shape[N];
+    for(; s < send; ++s, ++d)
+        swapDataImpl(s.begin(), shape, d.begin(), MetaInt<N-1>());
+}
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*                     MultiArrayView                   */
+/*                                                      */
+/********************************************************/
+
+// forward declarations
+
+namespace multi_math {
+
+template <class T>
+struct MultiMathOperand;
+
+namespace math_detail {
+
+template <unsigned int N, class T, class C, class E>
+void assign(MultiArrayView<N, T, C>, MultiMathOperand<E> const &);
+
+template <unsigned int N, class T, class C, class E>
+void plusAssign(MultiArrayView<N, T, C>, MultiMathOperand<E> const &);
+
+template <unsigned int N, class T, class C, class E>
+void minusAssign(MultiArrayView<N, T, C>, MultiMathOperand<E> const &);
+
+template <unsigned int N, class T, class C, class E>
+void multiplyAssign(MultiArrayView<N, T, C>, MultiMathOperand<E> const &);
+
+template <unsigned int N, class T, class C, class E>
+void divideAssign(MultiArrayView<N, T, C>, MultiMathOperand<E> const &);
+
+template <unsigned int N, class T, class A, class E>
+void assignOrResize(MultiArray<N, T, A> &, MultiMathOperand<E> const &);
+
+template <unsigned int N, class T, class A, class E>
+void plusAssignOrResize(MultiArray<N, T, A> &, MultiMathOperand<E> const &);
+
+template <unsigned int N, class T, class A, class E>
+void minusAssignOrResize(MultiArray<N, T, A> &, MultiMathOperand<E> const &);
+
+template <unsigned int N, class T, class A, class E>
+void multiplyAssignOrResize(MultiArray<N, T, A> &, MultiMathOperand<E> const &);
+
+template <unsigned int N, class T, class A, class E>
+void divideAssignOrResize(MultiArray<N, T, A> &, MultiMathOperand<E> const &);
+
+} // namespace math_detail
+
+} // namespace multi_math
+
+template <class T> class FindSum;
+
+struct UnsuitableTypeForExpandElements {};
+
+template <class T>
+struct ExpandElementResult
+{
+    typedef UnsuitableTypeForExpandElements type;
+};
+
+template <class T>
+struct ExpandElementResult<std::complex<T> >
+{
+    typedef T type;
+    enum { size = 2 };
+};
+
+template <class T>
+class FFTWComplex;
+
+template <class T>
+struct ExpandElementResult<FFTWComplex<T> >
+{
+    typedef T type;
+    enum { size = 2 };
+};
+
+template <class T, int SIZE>
+struct ExpandElementResult<TinyVector<T, SIZE> >
+{
+    typedef T type;
+    enum { size = SIZE };
+};
+
+template <class T, unsigned int R, unsigned int G, unsigned int B>
+struct ExpandElementResult<RGBValue<T, R, G, B> >
+{
+    typedef T type;
+    enum { size = 3 };
+};
+
+#define VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(TYPE) \
+template <>  \
+struct ExpandElementResult<TYPE> \
+{ \
+    typedef TYPE type; \
+    enum { size = 1 }; \
+}; \
+
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(bool)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(char)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(signed char)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(signed short)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(signed int)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(signed long)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(signed long long)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(unsigned char)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(unsigned short)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(unsigned int)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(unsigned long)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(unsigned long long)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(float)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(double)
+VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(long double)
+
+#undef VIGRA_DEFINE_EXPAND_ELEMENT_RESULT
+
+
+/********************************************************/
+/*                                                      */
+/*                       NormTraits                     */
+/*                                                      */
+/********************************************************/
+
+template <unsigned int N, class T, class C>
+struct NormTraits<MultiArrayView<N, T, C> >
+{
+    typedef MultiArrayView<N, T, C>                                      Type;
+    typedef typename NormTraits<T>::SquaredNormType SquaredNormType;
+    typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
+};
+
+template <unsigned int N, class T, class A>
+struct NormTraits<MultiArray<N, T, A> >
+: public NormTraits<typename MultiArray<N, T, A>::view_type>
+{
+    typedef NormTraits<typename MultiArray<N, T, A>::view_type>  BaseType;
+    typedef MultiArray<N, T, A>                                  Type;
+    typedef typename BaseType::SquaredNormType                   SquaredNormType;
+    typedef typename BaseType::NormType                          NormType;
+};
+
+/** \brief Base class for, and view to, \ref vigra::MultiArray.
+
+This class implements the interface of both MultiArray and
+MultiArrayView.  By default, MultiArrayViews are tagged as
+strided (using <tt>StridedArrayTag</tt> as third template parameter). 
+This means that the array elements need not be consecutive in memory,
+making the view flexible to represent all kinds of subarrays and slices.
+In certain cases (which have become rare due to improvements of 
+optimizer and processor technology), an array may be tagged with 
+<tt>UnstridedArrayTag</tt> which indicates that the first array dimension
+is guaranteed to be unstrided, i.e. has consecutive elements in memory.
+
+In addition to the member functions described here, <tt>MultiArrayView</tt>
+and its subclasses support arithmetic and algebraic functions via the 
+module \ref MultiMathModule.
+
+If you want to apply an algorithm requiring an image to a
+<tt>MultiArrayView</tt> of appropriate (2-dimensional) shape, you can
+create a \ref vigra::BasicImageView that acts as a wrapper with the
+necessary interface -- see \ref MultiArrayToImage.
+
+The template parameter are as follows
+\code
+    N: the array dimension
+
+    T: the type of the array elements
+
+    C: a tag determining whether the array's inner dimension is strided
+       or not. An array is unstrided if the array elements occupy consecutive
+       memory location, strided if there is an offset in between (e.g.
+       when a view is created that skips every other array element).
+       The compiler can generate faster code for unstrided arrays.
+       Possible values: StridedArrayTag (default), UnstridedArrayTag
+\endcode
+
+<b>\#include</b> \<vigra/multi_array.hxx\> <br/>
+Namespace: vigra
+*/
+template <unsigned int N, class T, class StrideTag>
+class MultiArrayView
+{
+public:
+
+        /** the array's actual dimensionality.
+            This ensures that MultiArrayView can also be used for
+            scalars (that is, when <tt>N == 0</tt>). Calculated as:<br>
+            \code
+            actual_dimension = (N==0) ? 1 : N
+            \endcode
+         */
+    enum ActualDimension { actual_dimension = (N==0) ? 1 : N };
+
+        /** the array's value type
+         */
+    typedef T value_type;
+
+        /** reference type (result of operator[])
+         */
+    typedef value_type &reference;
+
+        /** const reference type (result of operator[] const)
+         */
+    typedef const value_type &const_reference;
+
+        /** pointer type
+         */
+    typedef value_type *pointer;
+
+        /** const pointer type
+         */
+    typedef const value_type *const_pointer;
+
+        /** difference type (used for multi-dimensional offsets and indices)
+         */
+    typedef typename MultiArrayShape<actual_dimension>::type difference_type;
+
+        /** key type (argument of index operator array[i] -- same as difference_type)
+         */
+    typedef difference_type key_type;
+
+        /** size type
+         */
+    typedef difference_type size_type;
+
+        /** difference and index type for a single dimension
+         */
+    typedef MultiArrayIndex difference_type_1;
+
+        /** scan-order iterator (StridedScanOrderIterator) type
+         */
+    typedef StridedScanOrderIterator<actual_dimension, T, T &, T *> iterator;
+
+        /** const scan-order iterator (StridedScanOrderIterator) type
+         */
+    typedef StridedScanOrderIterator<actual_dimension, T, T const &, T const *> const_iterator;
+
+        /** traverser (MultiIterator) type
+         */
+    typedef typename vigra::detail::MultiIteratorChooser <
+        StrideTag>::template Traverser <actual_dimension, T, T &, T *>::type traverser;
+
+        /** const traverser (MultiIterator) type
+         */
+    typedef typename vigra::detail::MultiIteratorChooser <
+        StrideTag>::template Traverser <actual_dimension, T, T const &, T const *>::type const_traverser;
+
+        /** the view type associated with this array.
+         */
+    typedef MultiArrayView <N, T, StrideTag> view_type;
+
+        /** the matrix type associated with this array.
+         */
+    typedef MultiArray <N, T> matrix_type;
+
+    bool checkInnerStride(UnstridedArrayTag) const
+    {
+        return m_stride[0] <= 1;
+    }
+    
+    bool checkInnerStride(StridedArrayTag) const
+    {
+        return true;
+    }
+
+  protected:
+
+    typedef typename difference_type::value_type diff_zero_t;
+
+        /** the shape of the image pointed to is stored here.
+        */
+    difference_type m_shape;
+
+        /** the strides (offset of a sample to the next) for every dimension
+            are stored here.
+        */
+    difference_type m_stride;
+
+        /** pointer to the image.
+         */
+    pointer m_ptr;
+
+    template <class CN>
+    void assignImpl(const MultiArrayView <N, T, CN>& rhs);
+
+    template <class U, class CN>
+    void copyImpl(const MultiArrayView <N, U, CN>& rhs);
+
+    template <class U, class CN>
+    void swapDataImpl(MultiArrayView <N, U, CN> rhs);
+
+    template <class CN>
+    bool arraysOverlap(const MultiArrayView <N, T, CN>& rhs) const;
+
+    template <class U, class CN>
+    bool arraysOverlap(const MultiArrayView <N, U, CN>&) const
+    {
+        return false;
+    }
+
+public:
+
+        /** default constructor: create an invalid view,
+         * i.e. hasData() returns false and size() is zero.
+         */
+    MultiArrayView ()
+        : m_shape (diff_zero_t(0)), m_stride (diff_zero_t(0)), m_ptr (0)
+    {}
+
+        /** construct from another array view.
+            Throws a precondition error if this array has UnstridedArrayTag, but the 
+            innermost dimension of \a other is strided.
+         */
+    template <class Stride>
+    MultiArrayView (const MultiArrayView<N, T, Stride> &other)
+    : m_shape (other.shape()),
+      m_stride (other.stride()),
+      m_ptr (other.data())
+    {
+        vigra_precondition(other.checkInnerStride(StrideTag()),
+            "MultiArrayView<..., UnstridedArrayTag>(MultiArrayView const &): cannot create unstrided view from strided array.");
+    }
+
+        /** construct from shape and pointer
+         */
+    MultiArrayView (const difference_type &shape, const_pointer ptr)
+    : m_shape (shape),
+      m_stride (detail::defaultStride<actual_dimension>(shape)),
+      m_ptr (const_cast<pointer>(ptr))
+    {}
+
+        /** Construct from shape, strides (offset of a sample to the
+            next) for every dimension, and pointer.  (Note that
+            strides are not given in bytes, but in offset steps of the
+            respective pointer type.)
+         */
+    MultiArrayView (const difference_type &shape,
+                    const difference_type &stride,
+                    const_pointer ptr)
+    : m_shape (shape),
+      m_stride (stride),
+      m_ptr (const_cast<pointer>(ptr))
+    {
+        vigra_precondition(checkInnerStride(StrideTag()),
+            "MultiArrayView<..., UnstridedArrayTag>::MultiArrayView(): First dimension of given array is not unstrided.");
+    }
+    
+        /** Construct from shape, strides (offset of a sample to the
+            next) for every dimension, and pointer.  (Note that
+            strides are not given in bytes, but in offset steps of the
+            respective pointer type.)
+         */
+    template <class ALLOC>
+    MultiArrayView (BasicImage<T, ALLOC> const & image)
+    : m_shape (Shape2(image.width(), image.height())),
+      m_stride (detail::defaultStride<actual_dimension>(m_shape)),
+      m_ptr (const_cast<pointer>(image.data()))
+    {}
+    
+        /** Conversion to a strided view.
+         */
+    operator MultiArrayView<N, T, StridedArrayTag>() const
+    {
+        return MultiArrayView<N, T, StridedArrayTag>(m_shape, m_stride, m_ptr);
+    }
+
+        /** Assignment. There are 3 cases:
+
+            <ul>
+            <li> When this <tt>MultiArrayView</tt> does not point to valid data
+                 (e.g. after default construction), it becomes a new view of \a rhs.
+            <li> Otherwise, when the shapes of the two arrays match, the contents 
+                 (i.e. the elements) of \a rhs are copied.
+            <li> Otherwise, a <tt>PreconditionViolation</tt> exception is thrown.
+            </ul>
+         */
+    MultiArrayView & operator=(MultiArrayView const & rhs)
+    {
+        if(this != &rhs)
+            assignImpl(rhs);
+        return *this;
+    }
+
+    template<class Stride2>
+    MultiArrayView & operator=(MultiArrayView<N, T, Stride2> const & rhs)
+    {
+        assignImpl(rhs);
+        return *this;
+    }
+
+        /** Assignment of a differently typed MultiArrayView. It copies the elements
+            of\a rhs or fails with <tt>PreconditionViolation</tt> exception when 
+            the shapes do not match.
+         */
+    template<class U, class C1>
+    MultiArrayView & operator=(MultiArrayView<N, U, C1> const & rhs)
+    {
+        vigra_precondition(this->shape() == rhs.shape(),
+            "MultiArrayView::operator=(): shape mismatch.");
+        this->copyImpl(rhs);
+        return *this;
+    }
+
+        /** Assignment of a scalar. Equivalent to MultiArrayView::init(v).
+         */
+    MultiArrayView & operator=(value_type const & v)
+    {
+        return init(v);
+    }
+
+        /** Add-assignment of a compatible MultiArrayView. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class U, class C1>
+    MultiArrayView & operator+=(MultiArrayView<N, U, C1> const & rhs);
+
+        /** Subtract-assignment of a compatible MultiArrayView. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class U, class C1>
+    MultiArrayView & operator-=(MultiArrayView<N, U, C1> const & rhs);
+
+        /** Multiply-assignment of a compatible MultiArrayView. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class U, class C1>
+    MultiArrayView & operator*=(MultiArrayView<N, U, C1> const & rhs);
+
+        /** Divide-assignment of a compatible MultiArrayView. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class U, class C1>
+    MultiArrayView & operator/=(MultiArrayView<N, U, C1> const & rhs);
+
+        /** Add-assignment of a scalar.
+         */
+    MultiArrayView & operator+=(T const & rhs)
+    {
+        detail::copyAddScalarMultiArrayData(traverser_begin(), shape(), rhs, MetaInt<actual_dimension-1>());
+        return *this;
+    }
+
+        /** Subtract-assignment of a scalar.
+         */
+    MultiArrayView & operator-=(T const & rhs)
+    {
+        detail::copySubScalarMultiArrayData(traverser_begin(), shape(), rhs, MetaInt<actual_dimension-1>());
+        return *this;
+    }
+
+        /** Multiply-assignment of a scalar.
+         */
+    MultiArrayView & operator*=(T const & rhs)
+    {
+        detail::copyMulScalarMultiArrayData(traverser_begin(), shape(), rhs, MetaInt<actual_dimension-1>());
+        return *this;
+    }
+
+        /** Divide-assignment of a scalar.
+         */
+    MultiArrayView & operator/=(T const & rhs)
+    {
+        detail::copyDivScalarMultiArrayData(traverser_begin(), shape(), rhs, MetaInt<actual_dimension-1>());
+        return *this;
+    }
+
+        /** Assignment of an array expression. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class Expression>
+    MultiArrayView & operator=(multi_math::MultiMathOperand<Expression> const & rhs)
+    {
+        multi_math::math_detail::assign(*this, rhs);
+        return *this;
+    }
+
+        /** Add-assignment of an array expression. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class Expression>
+    MultiArrayView & operator+=(multi_math::MultiMathOperand<Expression> const & rhs)
+    {
+        multi_math::math_detail::plusAssign(*this, rhs);
+        return *this;
+    }
+
+        /** Subtract-assignment of an array expression. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class Expression>
+    MultiArrayView & operator-=(multi_math::MultiMathOperand<Expression> const & rhs)
+    {
+        multi_math::math_detail::minusAssign(*this, rhs);
+        return *this;
+    }
+
+        /** Multiply-assignment of an array expression. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class Expression>
+    MultiArrayView & operator*=(multi_math::MultiMathOperand<Expression> const & rhs)
+    {
+        multi_math::math_detail::multiplyAssign(*this, rhs);
+        return *this;
+    }
+
+        /** Divide-assignment of an array expression. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class Expression>
+    MultiArrayView & operator/=(multi_math::MultiMathOperand<Expression> const & rhs)
+    {
+        multi_math::math_detail::divideAssign(*this, rhs);
+        return *this;
+    }
+
+        /** array access.
+         */
+    reference operator[] (const difference_type &d)
+    {
+        VIGRA_ASSERT_INSIDE(d);
+        return m_ptr [dot (d, m_stride)];
+    }
+
+        /** array access.
+         */
+    const_reference operator[] (const difference_type &d) const
+    {
+        VIGRA_ASSERT_INSIDE(d);
+        return m_ptr [dot (d, m_stride)];
+    }
+
+        /** equivalent to bindInner(), when M < N.
+         */
+    template <int M>
+    MultiArrayView <N-M, T, StridedArrayTag> operator[] (const TinyVector<MultiArrayIndex, M> &d) const
+    {
+        return bindInner(d);
+    }
+
+        /** Array access in scan-order sense.
+            Mostly useful to support standard indexing for 1-dimensional multi-arrays,
+            but works for any N. Use scanOrderIndexToCoordinate() and
+            coordinateToScanOrderIndex() for conversion between indices and coordinates.
+            
+            <b>Note:</b> This function should not be used in the inner loop, because the
+            conversion of the scan order index into a memory address is expensive
+            (it must take into account that memory may not be consecutive for subarrays
+            and/or strided arrays). Always prefer operator() if possible.            
+         */
+    reference operator[](difference_type_1 d)
+    {
+        VIGRA_ASSERT_INSIDE(scanOrderIndexToCoordinate(d));
+        return m_ptr [detail::ScanOrderToOffset<actual_dimension>::exec(d, m_shape, m_stride)];
+    }
+
+        /** Array access in scan-order sense.
+            Mostly useful to support standard indexing for 1-dimensional multi-arrays,
+            but works for any N. Use scanOrderIndexToCoordinate() and
+            coordinateToScanOrderIndex() for conversion between indices and coordinates.
+             
+            <b>Note:</b> This function should not be used in the inner loop, because the
+            conversion of the scan order index into a memory address is expensive
+            (it must take into account that memory may not be consecutive for subarrays
+            and/or strided arrays). Always prefer operator() if possible.            
+        */
+    const_reference operator[](difference_type_1 d) const
+    {
+        VIGRA_ASSERT_INSIDE(scanOrderIndexToCoordinate(d));
+        return m_ptr [detail::ScanOrderToOffset<actual_dimension>::exec(d, m_shape, m_stride)];
+    }
+
+        /** convert scan-order index to coordinate.
+         */
+    difference_type scanOrderIndexToCoordinate(difference_type_1 d) const
+    {
+        difference_type result;
+        detail::ScanOrderToCoordinate<actual_dimension>::exec(d, m_shape, result);
+        return result;
+    }
+
+        /** convert coordinate to scan-order index.
+         */
+    difference_type_1 coordinateToScanOrderIndex(const difference_type &d) const
+    {
+        return detail::CoordinateToScanOrder<actual_dimension>::exec(m_shape, d);
+    }
+
+        /** 1D array access. Use only if N == 1.
+         */
+    reference operator() (difference_type_1 x)
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(x));
+        return m_ptr [detail::CoordinatesToOffest<StrideTag>::exec(m_stride, x)];
+    }
+
+        /** 2D array access. Use only if N == 2.
+         */
+    reference operator() (difference_type_1 x, difference_type_1 y)
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(x, y));
+        return m_ptr [detail::CoordinatesToOffest<StrideTag>::exec(m_stride, x, y)];
+    }
+
+        /** 3D array access. Use only if N == 3.
+         */
+    reference operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z)
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(x, y, z));
+        return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z];
+    }
+
+        /** 4D array access. Use only if N == 4.
+         */
+    reference operator() (difference_type_1 x, difference_type_1 y,
+                          difference_type_1 z, difference_type_1 u)
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(x, y, z, u));
+        return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u];
+    }
+
+        /** 5D array access. Use only if N == 5.
+         */
+    reference operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z,
+                          difference_type_1 u, difference_type_1 v)
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(x, y,z, u,v));
+        return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u + m_stride[4]*v];
+    }
+
+        /** 1D const array access. Use only if N == 1.
+         */
+    const_reference operator() (difference_type_1 x) const
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(x));
+        return m_ptr [detail::CoordinatesToOffest<StrideTag>::exec(m_stride, x)];
+    }
+
+        /** 2D const array access. Use only if N == 2.
+         */
+    const_reference operator() (difference_type_1 x, difference_type_1 y) const
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(x, y));
+        return m_ptr [detail::CoordinatesToOffest<StrideTag>::exec(m_stride, x, y)];
+    }
+
+        /** 3D const array access. Use only if N == 3.
+         */
+    const_reference operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z) const
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(x,y,z));
+        return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z];
+    }
+
+        /** 4D const array access. Use only if N == 4.
+         */
+    const_reference operator() (difference_type_1 x, difference_type_1 y,
+                                difference_type_1 z, difference_type_1 u) const
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(x,y,z,u));
+        return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u];
+    }
+
+        /** 5D const array access. Use only if N == 5.
+         */
+    const_reference operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z,
+                                difference_type_1 u, difference_type_1 v) const
+    {
+        VIGRA_ASSERT_INSIDE(difference_type(x,y,z,u,v));
+        return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u + m_stride[4]*v];
+    }
+
+        /** Init with a constant.
+         */
+    template <class U>
+    MultiArrayView & init(const U & init)
+    {
+        if(hasData())
+            detail::copyScalarMultiArrayData(traverser_begin(), shape(), init, MetaInt<actual_dimension-1>());
+        return *this;
+    }
+
+
+        /** Copy the data of the right-hand array (array shapes must match).
+         */
+    void copy(const MultiArrayView & rhs)
+    {
+        if(this == &rhs)
+            return;
+        this->copyImpl(rhs);
+    }
+
+        /** Copy the data of the right-hand array (array shapes must match).
+         */
+    template <class U, class CN>
+    void copy(const MultiArrayView <N, U, CN>& rhs)
+    {
+        this->copyImpl(rhs);
+    }
+
+        /** swap the data between two MultiArrayView objects.
+
+            The shapes of the two array must match.
+        */
+    void swapData(MultiArrayView rhs)
+    {
+        if(this != &rhs)
+            swapDataImpl(rhs);
+    }
+
+        /** swap the data between two MultiArrayView objects.
+
+            The shapes of the two array must match.
+        */
+    template <class T2, class C2>
+    void swapData(MultiArrayView <N, T2, C2> rhs)
+    {
+        swapDataImpl(rhs);
+    }
+    
+        /** check whether the array is unstrided (i.e. has consecutive memory) up 
+            to the given dimension.
+
+            \a dimension can range from 0 ... N-1. If a certain dimension is unstrided, 
+            all lower dimensions are also unstrided.
+        */
+    bool isUnstrided(unsigned int dimension = N-1) const
+    {
+        difference_type s = vigra::detail::defaultStride<actual_dimension>(shape());
+        for(unsigned int k = 0; k <= dimension; ++k)
+            if(stride(k) != s[k])
+                return false;
+        return true;
+    }
+
+        /** bind the M outmost dimensions to certain indices.
+            this reduces the dimensionality of the image to
+            max { 1, N-M }.
+
+            <b>Usage:</b>
+            \code
+            // create a 3D array of size 40x30x20
+            typedef MultiArray<3, double>::difference_type Shape;
+            MultiArray<3, double> array3(Shape(40, 30, 20));
+
+            // get a 1D array by fixing index 1 to 12, and index 2 to 10
+            MultiArrayView <1, double> array1 = array3.bindOuter(TinyVector<MultiArrayIndex, 2>(12, 10));
+            \endcode
+        */
+    template <int M, class Index>
+    MultiArrayView <N-M, T, StrideTag> bindOuter(const TinyVector <Index, M> &d) const;
+
+        /** bind the M innermost dimensions to certain indices.
+            this reduces the dimensionality of the image to
+            max { 1, N-M }.
+
+            <b>Usage:</b>
+            \code
+            // create a 3D array of size 40x30x20
+            typedef MultiArray<3, double>::difference_type Shape;
+            MultiArray<3, double> array3(Shape(40, 30, 20));
+
+            // get a 1D array by fixing index 0 to 12, and index 1 to 10
+            MultiArrayView <1, double, StridedArrayTag> array1 = array3.bindInner(TinyVector<MultiArrayIndex, 2>(12, 10));
+            \endcode
+        */
+    template <int M, class Index>
+    MultiArrayView <N-M, T, StridedArrayTag> bindInner(const TinyVector <Index, M> &d) const;
+
+        /** bind dimension M to index d.
+            this reduces the dimensionality of the image to
+            max { 1, N-1 }.
+
+            <b>Usage:</b>
+            \code
+            // create a 3D array of size 40x30x20
+            typedef MultiArray<3, double>::difference_type Shape;
+            MultiArray<3, double> array3(Shape(40, 30, 20));
+
+            // get a 2D array by fixing index 1 to 12
+            MultiArrayView <2, double> array2 = array3.bind<1>(12);
+
+            // get a 2D array by fixing index 0 to 23
+            MultiArrayView <2, double, StridedArrayTag> array2a = array3.bind<0>(23);
+            \endcode
+         */
+    template <unsigned int M>
+    MultiArrayView <N-1, T, typename vigra::detail::MaybeStrided<StrideTag, M>::type >
+    bind (difference_type_1 d) const;
+
+        /** bind the outmost dimension to a certain index.
+            this reduces the dimensionality of the image to
+            max { 1, N-1 }.
+
+            <b>Usage:</b>
+            \code
+            // create a 3D array of size 40x30x20
+            typedef MultiArray<3, double>::difference_type Shape;
+            MultiArray<3, double> array3(Shape(40, 30, 20));
+
+            // get a 2D array by fixing the outermost index (i.e. index 2) to 12
+            MultiArrayView <2, double> array2 = array3.bindOuter(12);
+            \endcode
+        */
+    MultiArrayView <N-1, T, StrideTag> bindOuter (difference_type_1 d) const;
+
+        /** bind the innermost dimension to a certain index.
+            this reduces the dimensionality of the image to
+            max { 1, N-1 }.
+
+            <b>Usage:</b>
+            \code
+            // create a 3D array of size 40x30x20
+            typedef MultiArray<3, double>::difference_type Shape;
+            MultiArray<3, double> array3(Shape(40, 30, 20));
+
+            // get a 2D array by fixing the innermost index (i.e. index 0) to 23
+            MultiArrayView <2, double, StridedArrayTag> array2 = array3.bindInner(23);
+            \endcode
+        */
+    MultiArrayView <N-1, T, StridedArrayTag> bindInner (difference_type_1 d) const;
+
+        /** bind dimension m to index d.
+            this reduces the dimensionality of the image to
+            max { 1, N-1 }.
+
+            <b>Usage:</b>
+            \code
+            // create a 3D array of size 40x30x20
+            typedef MultiArray<3, double>::difference_type Shape;
+            MultiArray<3, double> array3(Shape(40, 30, 20));
+
+            // get a 2D array by fixing index 2 to 15
+            MultiArrayView <2, double, StridedArrayTag> array2 = array3.bindAt(2, 15);
+            \endcode
+         */
+    MultiArrayView <N-1, T, StridedArrayTag>
+    bindAt (difference_type_1 m, difference_type_1 d) const;
+    
+    
+        /** Create a view to channel 'i' of a vector-like value type. Possible value types
+            (of the original array) are: \ref TinyVector, \ref RGBValue, \ref FFTWComplex, 
+            and <tt>std::complex</tt>. The list can be extended to any type whose memory
+            layout is equivalent to a fixed-size C array, by specializing 
+            <tt>ExpandElementResult</tt>.
+
+            <b>Usage:</b>
+            \code
+                MultiArray<2, RGBValue<float> > rgb_image(Shape2(w, h));
+                
+                MultiArrayView<2, float, StridedArrayTag> red   = rgb_image.bindElementChannel(0);
+                MultiArrayView<2, float, StridedArrayTag> green = rgb_image.bindElementChannel(1);
+                MultiArrayView<2, float, StridedArrayTag> blue  = rgb_image.bindElementChannel(2);
+            \endcode
+        */
+    MultiArrayView <N, typename ExpandElementResult<T>::type, StridedArrayTag> 
+    bindElementChannel(difference_type_1 i) const
+    {
+        vigra_precondition(0 <= i && i < ExpandElementResult<T>::size,
+              "MultiArrayView::bindElementChannel(i): 'i' out of range.");
+        return expandElements(0).bindInner(i);
+    }
+
+        /** Create a view where a vector-like element type is expanded into a new 
+            array dimension. The new dimension is inserted at index position 'd',
+            which must be between 0 and N inclusive.
+            
+            Possible value types of the original array are: \ref TinyVector, \ref RGBValue, 
+            \ref FFTWComplex, <tt>std::complex</tt>, and the built-in number types (in this 
+            case, <tt>expandElements</tt> is equivalent to <tt>insertSingletonDimension</tt>). 
+            The list of supported types can be extended to any type whose memory
+            layout is equivalent to a fixed-size C array, by specializing 
+            <tt>ExpandElementResult</tt>.
+
+            <b>Usage:</b>
+            \code
+                MultiArray<2, RGBValue<float> > rgb_image(Shape2(w, h));
+                
+                MultiArrayView<3, float, StridedArrayTag> multiband_image = rgb_image.expandElements(2);
+            \endcode
+        */
+    MultiArrayView <N+1, typename ExpandElementResult<T>::type, StridedArrayTag> 
+    expandElements(difference_type_1 d) const;
+    
+        /** Add a singleton dimension (dimension of length 1).
+
+            Singleton dimensions don't change the size of the data, but introduce
+            a new index that can only take the value 0. This is mainly useful for
+            the 'reduce mode' of transformMultiArray() and combineTwoMultiArrays(),
+            because these functions require the source and destination arrays to
+            have the same number of dimensions.
+
+            The range of \a i must be <tt>0 <= i <= N</tt>. The new dimension will become
+            the i'th index, and the old indices from i upwards will shift one
+            place to the right.
+
+            <b>Usage:</b>
+
+            Suppose we want have a 2D array and want to create a 1D array that contains
+            the row average of the first array.
+            \code
+            typedef MultiArrayShape<2>::type Shape2;
+            MultiArray<2, double> original(Shape2(40, 30));
+
+            typedef MultiArrayShape<1>::type Shape1;
+            MultiArray<1, double> rowAverages(Shape1(30));
+
+            // temporarily add a singleton dimension to the destination array
+            transformMultiArray(srcMultiArrayRange(original),
+                                destMultiArrayRange(rowAverages.insertSingletonDimension(0)),
+                                FindAverage<double>());
+            \endcode
+         */
+    MultiArrayView <N+1, T, StrideTag>
+    insertSingletonDimension (difference_type_1 i) const;
+
+        /** Create a view to the diagonal elements of the array.
+        
+            This produces a 1D array view whose size equals the size
+            of the shortest dimension of the original array.
+
+            <b>Usage:</b>
+            \code
+            // create a 3D array of size 40x30x20
+            typedef MultiArray<3, double>::difference_type Shape;
+            MultiArray<3, double> array3(Shape(40, 30, 20));
+
+            // get a view to the diagonal elements
+            MultiArrayView <1, double, StridedArrayTag> diagonal = array3.diagonal();
+            assert(diagonal.shape(0) == 20);
+            \endcode
+        */
+    MultiArrayView<1, T, StridedArrayTag> diagonal() const
+    {
+        return MultiArrayView<1, T, StridedArrayTag>(Shape1(vigra::min(m_shape)), 
+                                                     Shape1(vigra::sum(m_stride)), m_ptr);
+    }
+
+        /** create a rectangular subarray that spans between the
+            points p and q, where p is in the subarray, q not. 
+            If an element of p or q is negative, it is subtracted
+            from the correspongng shape.
+
+            <b>Usage:</b>
+            \code
+            // create a 3D array of size 40x30x20
+            typedef MultiArray<3, double>::difference_type Shape;
+            MultiArray<3, double> array3(Shape(40, 30, 20));
+
+            // get a subarray set is smaller by one element at all sides
+            MultiArrayView <3, double> subarray  = array3.subarray(Shape(1,1,1), Shape(39, 29, 19));
+            
+            // specifying the end point with a vector of '-1' is equivalent
+            MultiArrayView <3, double> subarray2 = array3.subarray(Shape(1,1,1), Shape(-1, -1, -1));
+            \endcode
+        */
+    MultiArrayView subarray (difference_type p, difference_type q) const
+    {
+        detail::RelativeToAbsoluteCoordinate<actual_dimension-1>::exec(shape(), p);
+        detail::RelativeToAbsoluteCoordinate<actual_dimension-1>::exec(shape(), q);
+        const difference_type_1 offset = dot (m_stride, p);
+        return MultiArrayView (q - p, m_stride, m_ptr + offset);
+    }
+
+        /** apply an additional striding to the image, thereby reducing
+            the shape of the array.
+            for example, multiplying the stride of dimension one by three
+            turns an appropriately laid out (interleaved) rgb image into
+            a single band image.
+        */
+    MultiArrayView <N, T, StridedArrayTag>
+    stridearray (const difference_type &s) const
+    {
+        difference_type shape = m_shape;
+        for (unsigned int i = 0; i < actual_dimension; ++i)
+            shape [i] /= s [i];
+        return MultiArrayView <N, T, StridedArrayTag>(shape, m_stride * s, m_ptr);
+    }
+
+        /** Transpose an array. If N==2, this implements the usual matrix transposition.
+            For N > 2, it reverses the order of the indices.
+
+            <b>Usage:</b><br>
+            \code
+            typedef MultiArray<2, double>::difference_type Shape;
+            MultiArray<2, double> array(10, 20);
+
+            MultiArray<2, double, StridedArrayTag> transposed = array.transpose();
+
+            for(int i=0; i<array.shape(0), ++i)
+                for(int j=0; j<array.shape(1); ++j)
+                    assert(array(i, j) == transposed(j, i));
+            \endcode
+        */
+    MultiArrayView <N, T, StridedArrayTag>
+    transpose () const
+    {
+        difference_type shape(m_shape.begin(), difference_type::ReverseCopy),
+                        stride(m_stride.begin(), difference_type::ReverseCopy);
+        return MultiArrayView <N, T, StridedArrayTag>(shape, stride, m_ptr);
+    }
+
+        /** Permute the dimensions of the array.
+            The function exchanges the orer of the array's axes without copying the data.
+            Argument\a permutation specifies the desired order such that 
+            <tt>permutation[k] = j</tt> means that axis <tt>j</tt> in the original array
+            becomes axis <tt>k</tt> in the transposed array. 
+
+            <b>Usage:</b><br>
+            \code
+            typedef MultiArray<2, double>::difference_type Shape;
+            MultiArray<2, double> array(10, 20);
+
+            MultiArray<2, double, StridedArrayTag> transposed = array.transpose(Shape(1,0));
+
+            for(int i=0; i<array.shape(0), ++i)
+                for(int j=0; j<array.shape(1); ++j)
+                    assert(array(i, j) == transposed(j, i));
+            \endcode
+        */
+    MultiArrayView <N, T, StridedArrayTag>
+    transpose(const difference_type &permutation) const
+    {
+        return permuteDimensions(permutation);
+    }
+
+    MultiArrayView <N, T, StridedArrayTag>
+    permuteDimensions (const difference_type &s) const;
+
+        /** Permute the dimensions of the array so that the strides are in ascending order.
+            Determines the appropriate permutation and then calls permuteDimensions().
+        */
+    MultiArrayView <N, T, StridedArrayTag>
+    permuteStridesAscending() const;
+    
+        /** Permute the dimensions of the array so that the strides are in descending order.
+            Determines the appropriate permutation and then calls permuteDimensions().
+        */
+    MultiArrayView <N, T, StridedArrayTag>
+    permuteStridesDescending() const;
+    
+        /** Compute the ordering of the strides in this array.
+            The result is describes the current permutation of the axes relative 
+            to the standard ascending stride order.
+        */
+    difference_type strideOrdering() const
+    {
+        return strideOrdering(m_stride);
+    }
+    
+        /** Compute the ordering of the given strides.
+            The result is describes the current permutation of the axes relative 
+            to the standard ascending stride order.
+        */
+    static difference_type strideOrdering(difference_type strides);
+
+        /** number of the elements in the array.
+         */
+    difference_type_1 elementCount () const
+    {
+        difference_type_1 ret = m_shape[0];
+        for(int i = 1; i < actual_dimension; ++i)
+            ret *= m_shape[i];
+        return ret;
+    }
+
+        /** number of the elements in the array.
+            Same as <tt>elementCount()</tt>. Mostly useful to support the std::vector interface.
+         */
+    difference_type_1 size () const
+    {
+        return elementCount();
+    }
+
+        /** return the array's shape.
+         */
+    const difference_type & shape () const
+    {
+        return m_shape;
+    }
+
+        /** return the array's size at a certain dimension.
+         */
+    difference_type_1 size (difference_type_1 n) const
+    {
+        return m_shape [n];
+    }
+
+        /** return the array's shape at a certain dimension
+            (same as <tt>size(n)</tt>).
+         */
+    difference_type_1 shape (difference_type_1 n) const
+    {
+        return m_shape [n];
+    }
+
+        /** return the array's width (same as <tt>shape(0)</tt>).
+         */
+    difference_type_1 width() const
+    {
+        return m_shape [0];
+    }
+
+        /** return the array's height (same as <tt>shape(1)</tt>).
+         */
+    difference_type_1 height() const
+    {
+        return m_shape [1];
+    }
+
+        /** return the array's stride for every dimension.
+         */
+    const difference_type & stride () const
+    {
+        return m_stride;
+    }
+
+        /** return the array's stride at a certain dimension.
+         */
+    difference_type_1 stride (int n) const
+    {
+        return m_stride [n];
+    }
+
+        /** check whether two arrays are elementwise equal.
+         */
+    template <class U, class C1>
+    bool operator==(MultiArrayView<N, U, C1> const & rhs) const
+    {
+        if(this->shape() != rhs.shape())
+            return false;
+        return detail::equalityOfMultiArrays(traverser_begin(), shape(), rhs.traverser_begin(), MetaInt<actual_dimension-1>());
+    }
+
+        /** check whether two arrays are not elementwise equal.
+            Also true when the two arrays have different shapes.
+         */
+    template <class U, class C1>
+    bool operator!=(MultiArrayView<N, U, C1> const & rhs) const
+    {
+        return !operator==(rhs);
+    }
+
+        /** check whether the given point is in the array range.
+         */
+    bool isInside (difference_type const & p) const
+    {
+        for(int d=0; d<actual_dimension; ++d)
+            if(p[d] < 0 || p[d] >= shape(d))
+                return false;
+        return true;
+    }
+
+        /** Check if the array contains only non-zero elements (or if all elements
+            are 'true' if the value type is 'bool').
+         */
+    bool all() const
+    {
+        bool res = true;
+        detail::reduceOverMultiArray(traverser_begin(), shape(),
+                                     res, 
+                                     detail::AllTrueReduceFunctor(),
+                                     MetaInt<actual_dimension-1>());
+        return res;
+    }
+
+        /** Check if the array contains a non-zero element (or an element
+            that is 'true' if the value type is 'bool').
+         */
+    bool any() const
+    {
+        bool res = false;
+        detail::reduceOverMultiArray(traverser_begin(), shape(),
+                                     res, 
+                                     detail::AnyTrueReduceFunctor(),
+                                     MetaInt<actual_dimension-1>());
+        return res;
+    }
+
+        /** Find the minimum and maximum element in this array. 
+            See \ref FeatureAccumulators for a general feature 
+            extraction framework.
+         */
+    void minmax(T * minimum, T * maximum) const
+    {
+        std::pair<T, T> res(NumericTraits<T>::max(), NumericTraits<T>::min());
+        detail::reduceOverMultiArray(traverser_begin(), shape(),
+                                     res, 
+                                     detail::MinmaxReduceFunctor(),
+                                     MetaInt<actual_dimension-1>());
+        *minimum = res.first;
+        *maximum = res.second;
+    }
+
+        /** Compute the mean and variance of the values in this array. 
+            See \ref FeatureAccumulators for a general feature 
+            extraction framework.
+         */
+    template <class U>
+    void meanVariance(U * mean, U * variance) const
+    {
+        typedef typename NumericTraits<U>::RealPromote R;
+        R zero = R();
+        triple<double, R, R> res(0.0, zero, zero);
+        detail::reduceOverMultiArray(traverser_begin(), shape(),
+                                     res, 
+                                     detail::MeanVarianceReduceFunctor(),
+                                     MetaInt<actual_dimension-1>());
+        *mean     = res.second;
+        *variance = res.third / res.first;
+    }
+
+        /** Compute the sum of the array elements.
+
+            You must provide the type of the result by an explicit template parameter:
+            \code
+            MultiArray<2, UInt8> A(width, height);
+            
+            double sum = A.sum<double>();
+            \endcode
+         */
+    template <class U>
+    U sum() const
+    {
+        U res = NumericTraits<U>::zero();
+        detail::reduceOverMultiArray(traverser_begin(), shape(),
+                                     res, 
+                                     detail::SumReduceFunctor(),
+                                     MetaInt<actual_dimension-1>());
+        return res;
+    }
+
+        /** Compute the sum of the array elements over selected axes.
+        
+            \arg sums must have the same shape as this array, except for the
+            axes along which the sum is to be accumulated. These axes must be 
+            singletons. Note that you must include <tt>multi_pointoperators.hxx</tt>
+            for this function to work.
+
+            <b>Usage:</b>
+            \code
+            #include <vigra/multi_array.hxx>
+            #include <vigra/multi_pointoperators.hxx>
+            
+            MultiArray<2, double> A(Shape2(rows, cols));
+            ... // fill A
+            
+            // make the first axis a singleton to sum over the first index
+            MultiArray<2, double> rowSums(Shape2(1, cols));
+            A.sum(rowSums);
+            
+            // this is equivalent to
+            transformMultiArray(srcMultiArrayRange(A),
+                                destMultiArrayRange(rowSums),
+                                FindSum<double>());
+            \endcode
+         */
+    template <class U, class S>
+    void sum(MultiArrayView<N, U, S> sums) const
+    {
+        transformMultiArray(srcMultiArrayRange(*this),
+                            destMultiArrayRange(sums),
+                            FindSum<U>());
+    }
+
+        /** Compute the product of the array elements.
+
+            You must provide the type of the result by an explicit template parameter:
+            \code
+            MultiArray<2, UInt8> A(width, height);
+            
+            double prod = A.product<double>();
+            \endcode
+         */
+    template <class U>
+    U product() const
+    {
+        U res = NumericTraits<U>::one();
+        detail::reduceOverMultiArray(traverser_begin(), shape(),
+                                     res, 
+                                     detail::ProdReduceFunctor(),
+                                     MetaInt<actual_dimension-1>());
+        return res;
+    }
+
+        /** Compute the squared Euclidean norm of the array (sum of squares of the array elements).
+         */
+    typename NormTraits<MultiArrayView>::SquaredNormType 
+    squaredNorm() const
+    {
+        typedef typename NormTraits<MultiArrayView>::SquaredNormType SquaredNormType;
+        SquaredNormType res = NumericTraits<SquaredNormType>::zero();
+        detail::reduceOverMultiArray(traverser_begin(), shape(),
+                                     res, 
+                                     detail::SquaredL2NormReduceFunctor(),
+                                     MetaInt<actual_dimension-1>());
+        return res;
+    }
+
+        /** Compute various norms of the array.
+            The norm is determined by parameter \a type:
+
+            <ul>
+            <li> type == 0: maximum norm (L-infinity): maximum of absolute values of the array elements
+            <li> type == 1: Manhattan norm (L1): sum of absolute values of the array elements
+            <li> type == 2: Euclidean norm (L2): square root of <tt>squaredNorm()</tt> when \a useSquaredNorm is <tt>true</tt>,<br>
+                 or direct algorithm that avoids underflow/overflow otherwise.
+            </ul>
+
+            Parameter \a useSquaredNorm has no effect when \a type != 2. Defaults: compute L2 norm as square root of
+            <tt>squaredNorm()</tt>.
+         */
+    typename NormTraits<MultiArrayView>::NormType 
+    norm(int type = 2, bool useSquaredNorm = true) const;
+
+        /** return the pointer to the image data
+         */
+    pointer data () const
+    {
+        return m_ptr;
+    }
+    
+    pointer & unsafePtr()
+    {
+        return m_ptr;
+    }
+
+        /**
+         * returns true iff this view refers to valid data,
+         * i.e. data() is not a NULL pointer.  (this is false after
+         * default construction.)
+         */
+    bool hasData () const
+    {
+        return m_ptr != 0;
+    }
+
+        /** returns a scan-order iterator pointing
+            to the first array element.
+        */
+    iterator begin()
+    {
+        return iterator(*this);
+    }
+
+        /** returns a const scan-order iterator pointing
+            to the first array element.
+        */
+    const_iterator begin() const
+    {
+        return const_iterator(*this);
+    }
+
+        /** returns a scan-order iterator pointing
+            beyond the last array element.
+        */
+    iterator end()
+    {
+        return begin().getEndIterator();
+    }
+
+        /** returns a const scan-order iterator pointing
+            beyond the last array element.
+        */
+    const_iterator end() const
+    {
+        return begin().getEndIterator();
+    }
+
+        /** returns the N-dimensional MultiIterator pointing
+            to the first element in every dimension.
+        */
+    traverser traverser_begin ()
+    {
+        traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
+        return ret;
+    }
+
+        /** returns the N-dimensional MultiIterator pointing
+            to the const first element in every dimension.
+        */
+    const_traverser traverser_begin () const
+    {
+        const_traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
+        return ret;
+    }
+
+        /** returns the N-dimensional MultiIterator pointing
+            beyond the last element in dimension N, and to the
+            first element in every other dimension.
+        */
+    traverser traverser_end ()
+    {
+        traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
+        ret += m_shape [actual_dimension-1];
+        return ret;
+    }
+
+        /** returns the N-dimensional const MultiIterator pointing
+            beyond the last element in dimension N, and to the
+            first element in every other dimension.
+        */
+    const_traverser traverser_end () const
+    {
+        const_traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
+        ret += m_shape [actual_dimension-1];
+        return ret;
+    }
+
+    view_type view ()
+    {
+        return *this;
+    }
+};
+
+template <unsigned int N, class T, class Stride1>
+template <class Stride2>
+void
+MultiArrayView <N, T, Stride1>::assignImpl(MultiArrayView<N, T, Stride2> const & rhs)
+{
+    if(m_ptr == 0)
+    {
+        vigra_precondition(rhs.checkInnerStride(Stride1()),
+            "MultiArrayView<..., UnstridedArrayTag>::operator=(MultiArrayView const &): cannot create unstrided view from strided array.");
+                           
+        m_shape  = rhs.shape();
+        m_stride = rhs.stride();
+        m_ptr    = rhs.data();
+    }
+    else
+    {
+        vigra_precondition(this->shape() == rhs.shape(),
+            "MultiArrayView::operator=(MultiArrayView const &): shape mismatch.");
+        this->copyImpl(rhs);
+    }
+}
+
+template <unsigned int N, class T, class StrideTag>
+template <class CN>
+bool
+MultiArrayView <N, T, StrideTag>::arraysOverlap(const MultiArrayView <N, T, CN>& rhs) const
+{
+    vigra_precondition (shape () == rhs.shape (),
+        "MultiArrayView::arraysOverlap(): shape mismatch.");
+    const_pointer first_element = this->m_ptr,
+                  last_element = first_element + dot(this->m_shape - difference_type(1), this->m_stride);
+    typename MultiArrayView <N, T, CN>::const_pointer
+           rhs_first_element = rhs.data(),
+           rhs_last_element = rhs_first_element + dot(rhs.shape() - difference_type(1), rhs.stride());
+    return !(last_element < rhs_first_element || rhs_last_element < first_element);
+}
+
+template <unsigned int N, class T, class StrideTag>
+template <class U, class CN>
+void
+MultiArrayView <N, T, StrideTag>::copyImpl(const MultiArrayView <N, U, CN>& rhs)
+{
+    if(!arraysOverlap(rhs))
+    {
+        // no overlap -- can copy directly
+        detail::copyMultiArrayData(rhs.traverser_begin(), shape(), traverser_begin(), MetaInt<actual_dimension-1>());
+    }
+    else
+    {
+        // overlap: we got different views to the same data -- copy to intermediate memory in order to avoid
+        // overwriting elements that are still needed on the rhs.
+        MultiArray<N, T> tmp(rhs);
+        detail::copyMultiArrayData(tmp.traverser_begin(), shape(), traverser_begin(), MetaInt<actual_dimension-1>());
+    }
+}
+
+#define VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT(name, op) \
+template <unsigned int N, class T, class StrideTag> \
+template<class U, class C1> \
+MultiArrayView<N, T, StrideTag> &  \
+MultiArrayView <N, T, StrideTag>::operator op(MultiArrayView<N, U, C1> const & rhs) \
+{ \
+    vigra_precondition(this->shape() == rhs.shape(), "MultiArrayView::operator" #op "() size mismatch."); \
+    if(!arraysOverlap(rhs)) \
+    { \
+        detail::name##MultiArrayData(rhs.traverser_begin(), shape(), traverser_begin(), MetaInt<actual_dimension-1>()); \
+    } \
+    else \
+    { \
+        MultiArray<N, T> tmp(rhs); \
+        detail::name##MultiArrayData(tmp.traverser_begin(), shape(), traverser_begin(), MetaInt<actual_dimension-1>()); \
+    } \
+    return *this; \
+}
+
+VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT(copyAdd, +=)
+VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT(copySub, -=)
+VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT(copyMul, *=)
+VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT(copyDiv, /=)
+
+#undef VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT
+
+template <unsigned int N, class T, class StrideTag>
+template <class U, class CN>
+void
+MultiArrayView <N, T, StrideTag>::swapDataImpl(MultiArrayView <N, U, CN> rhs)
+{
+    vigra_precondition (shape () == rhs.shape (),
+        "MultiArrayView::swapData(): shape mismatch.");
+
+    // check for overlap of this and rhs
+    const_pointer first_element = this->m_ptr,
+                  last_element = first_element + dot(this->m_shape - difference_type(1), this->m_stride);
+    typename MultiArrayView <N, U, CN>::const_pointer
+           rhs_first_element = rhs.data(),
+           rhs_last_element = rhs_first_element + dot(rhs.shape() - difference_type(1), rhs.stride());
+    if(last_element < rhs_first_element || rhs_last_element < first_element)
+    {
+        // no overlap -- can swap directly
+        detail::swapDataImpl(traverser_begin(), shape(), rhs.traverser_begin(), MetaInt<actual_dimension-1>());
+    }
+    else
+    {
+        // overlap: we got different views to the same data -- copy to intermediate memory in order to avoid
+        // overwriting elements that are still needed.
+        MultiArray<N, T> tmp(*this);
+        copy(rhs);
+        rhs.copy(tmp);
+    }
+}
+
+template <unsigned int N, class T, class StrideTag>
+MultiArrayView <N, T, StridedArrayTag>
+MultiArrayView <N, T, StrideTag>::permuteDimensions (const difference_type &s) const
+{
+    difference_type shape, stride, check((typename difference_type::value_type)0);
+    for (unsigned int i = 0; i < actual_dimension; ++i)
+    {
+        shape[i]  = m_shape[s[i]];
+        stride[i] = m_stride[s[i]];
+        ++check[s[i]];
+    }
+    vigra_precondition(check == difference_type(1),
+       "MultiArrayView::transpose(): every dimension must occur exactly once.");
+    return MultiArrayView <N, T, StridedArrayTag>(shape, stride, m_ptr);
+}
+
+template <unsigned int N, class T, class StrideTag>
+typename MultiArrayView <N, T, StrideTag>::difference_type 
+MultiArrayView <N, T, StrideTag>::strideOrdering(difference_type stride)
+{
+    difference_type permutation;
+    for(int k=0; k<(int)N; ++k)
+        permutation[k] = k;
+    for(int k=0; k<(int)N-1; ++k)
+    {
+        int smallest = k;
+        for(int j=k+1; j<(int)N; ++j)
+        {
+            if(stride[j] < stride[smallest])
+                smallest = j;
+        }
+        if(smallest != k)
+        {
+            std::swap(stride[k], stride[smallest]);
+            std::swap(permutation[k], permutation[smallest]);
+        }
+    }
+    difference_type ordering;
+    for(unsigned int k=0; k<N; ++k)
+        ordering[permutation[k]] = k;
+    return ordering;
+}
+
+template <unsigned int N, class T, class StrideTag>
+MultiArrayView <N, T, StridedArrayTag>
+MultiArrayView <N, T, StrideTag>::permuteStridesAscending() const
+{
+    difference_type ordering(strideOrdering(m_stride)), permutation;
+    for(MultiArrayIndex k=0; k<N; ++k)
+        permutation[ordering[k]] = k;
+    return permuteDimensions(permutation);
+}
+
+template <unsigned int N, class T, class StrideTag>
+MultiArrayView <N, T, StridedArrayTag>
+MultiArrayView <N, T, StrideTag>::permuteStridesDescending() const
+{
+    difference_type ordering(strideOrdering(m_stride)), permutation;
+    for(MultiArrayIndex k=0; k<N; ++k)
+        permutation[N-1-ordering[k]] = k;
+    return permuteDimensions(permutation);
+}
+
+template <unsigned int N, class T, class StrideTag>
+template <int M, class Index>
+MultiArrayView <N-M, T, StrideTag>
+MultiArrayView <N, T, StrideTag>::bindOuter (const TinyVector <Index, M> &d) const
+{
+    TinyVector <MultiArrayIndex, M> stride;
+    stride.init (m_stride.begin () + N-M, m_stride.end ());
+    pointer ptr = m_ptr + dot (d, stride);
+    static const int NNew = (N-M == 0) ? 1 : N-M;
+    TinyVector <MultiArrayIndex, NNew> inner_shape, inner_stride;
+    if (N-M == 0)
+    {
+        inner_shape [0] = 1;
+        inner_stride [0] = 1;
+    }
+    else
+    {
+        inner_shape.init (m_shape.begin (), m_shape.end () - M);
+        inner_stride.init (m_stride.begin (), m_stride.end () - M);
+    }
+    return MultiArrayView <N-M, T, StrideTag> (inner_shape, inner_stride, ptr);
+}
+
+template <unsigned int N, class T, class StrideTag>
+template <int M, class Index>
+MultiArrayView <N - M, T, StridedArrayTag>
+MultiArrayView <N, T, StrideTag>::bindInner (const TinyVector <Index, M> &d) const
+{
+    TinyVector <MultiArrayIndex, M> stride;
+    stride.init (m_stride.begin (), m_stride.end () - N + M);
+    pointer ptr = m_ptr + dot (d, stride);
+    static const int NNew = (N-M == 0) ? 1 : N-M;
+    TinyVector <MultiArrayIndex, NNew> outer_shape, outer_stride;
+    if (N-M == 0)
+    {
+        outer_shape [0] = 1;
+        outer_stride [0] = 1;
+    }
+    else
+    {
+        outer_shape.init (m_shape.begin () + M, m_shape.end ());
+        outer_stride.init (m_stride.begin () + M, m_stride.end ());
+    }
+    return MultiArrayView <N-M, T, StridedArrayTag>
+        (outer_shape, outer_stride, ptr);
+}
+
+template <unsigned int N, class T, class StrideTag>
+template <unsigned int M>
+MultiArrayView <N-1, T, typename detail::MaybeStrided<StrideTag, M>::type >
+MultiArrayView <N, T, StrideTag>::bind (difference_type_1 d) const
+{
+    static const int NNew = (N-1 == 0) ? 1 : N-1;
+    TinyVector <MultiArrayIndex, NNew> shape, stride;
+    // the remaining dimensions are 0..n-1,n+1..N-1
+    if (N-1 == 0)
+    {
+        shape[0] = 1;
+        stride[0] = 1;
+    }
+    else
+    {
+        std::copy (m_shape.begin (), m_shape.begin () + M, shape.begin ());
+        std::copy (m_shape.begin () + M+1, m_shape.end (),
+                   shape.begin () + M);
+        std::copy (m_stride.begin (), m_stride.begin () + M, stride.begin ());
+        std::copy (m_stride.begin () + M+1, m_stride.end (),
+                   stride.begin () + M);
+    }
+    return MultiArrayView <N-1, T, typename detail::MaybeStrided<StrideTag, M>::type>
+        (shape, stride, m_ptr + d * m_stride[M]);
+}
+
+template <unsigned int N, class T, class StrideTag>
+MultiArrayView <N - 1, T, StrideTag>
+MultiArrayView <N, T, StrideTag>::bindOuter (difference_type_1 d) const
+{
+    static const int NNew = (N-1 == 0) ? 1 : N-1;
+    TinyVector <MultiArrayIndex, NNew> inner_shape, inner_stride;
+    if (N-1 == 0)
+    {
+        inner_shape [0] = 1;
+        inner_stride [0] = 1;
+    }
+    else
+    {
+        inner_shape.init (m_shape.begin (), m_shape.end () - 1);
+        inner_stride.init (m_stride.begin (), m_stride.end () - 1);
+    }
+    return MultiArrayView <N-1, T, StrideTag> (inner_shape, inner_stride,
+                                       m_ptr + d * m_stride [N-1]);
+}
+
+template <unsigned int N, class T, class StrideTag>
+MultiArrayView <N - 1, T, StridedArrayTag>
+MultiArrayView <N, T, StrideTag>::bindInner (difference_type_1 d) const
+{
+    static const int NNew = (N-1 == 0) ? 1 : N-1;
+    TinyVector <MultiArrayIndex, NNew> outer_shape, outer_stride;
+    if (N-1 == 0)
+    {
+        outer_shape [0] = 1;
+        outer_stride [0] = 1;
+    }
+    else
+    {
+        outer_shape.init (m_shape.begin () + 1, m_shape.end ());
+        outer_stride.init (m_stride.begin () + 1, m_stride.end ());
+    }
+    return MultiArrayView <N-1, T, StridedArrayTag>
+        (outer_shape, outer_stride, m_ptr + d * m_stride [0]);
+}
+
+template <unsigned int N, class T, class StrideTag>
+MultiArrayView <N - 1, T, StridedArrayTag>
+MultiArrayView <N, T, StrideTag>::bindAt (difference_type_1 n, difference_type_1 d) const
+{
+    vigra_precondition (
+        n < static_cast <int> (N),
+        "MultiArrayView <N, T, StrideTag>::bindAt(): dimension out of range.");
+    static const int NNew = (N-1 == 0) ? 1 : N-1;
+    TinyVector <MultiArrayIndex, NNew> shape, stride;
+    // the remaining dimensions are 0..n-1,n+1..N-1
+    if (N-1 == 0)
+    {
+        shape [0] = 1;
+        stride [0] = 1;
+    }
+    else
+    {
+        std::copy (m_shape.begin (), m_shape.begin () + n, shape.begin ());
+        std::copy (m_shape.begin () + n+1, m_shape.end (),
+                   shape.begin () + n);
+        std::copy (m_stride.begin (), m_stride.begin () + n, stride.begin ());
+        std::copy (m_stride.begin () + n+1, m_stride.end (),
+                   stride.begin () + n);
+    }
+    return MultiArrayView <N-1, T, StridedArrayTag>
+        (shape, stride, m_ptr + d * m_stride[n]);
+}
+
+
+template <unsigned int N, class T, class StrideTag>
+MultiArrayView <N+1, typename ExpandElementResult<T>::type, StridedArrayTag>
+MultiArrayView <N, T, StrideTag>::expandElements(difference_type_1 d) const
+{
+    vigra_precondition(0 <= d && d <= static_cast <difference_type_1> (N),
+          "MultiArrayView<N, ...>::expandElements(d): 0 <= 'd' <= N required.");
+    
+    int elementSize = ExpandElementResult<T>::size;
+    typename MultiArrayShape<N+1>::type newShape, newStrides;
+    for(int k=0; k<d; ++k)
+    {
+        newShape[k] = m_shape[k];
+        newStrides[k] = m_stride[k]*elementSize;
+    }   
+    
+    newShape[d] = elementSize;
+    newStrides[d] = 1;
+    
+    for(int k=d; k<N; ++k)
+    {
+        newShape[k+1] = m_shape[k];
+        newStrides[k+1] = m_stride[k]*elementSize;
+    }   
+    
+    typedef typename ExpandElementResult<T>::type U;     
+    return MultiArrayView<N+1, U, StridedArrayTag>(
+                    newShape, newStrides, reinterpret_cast<U*>(m_ptr));
+}
+
+template <unsigned int N, class T, class StrideTag>
+MultiArrayView <N+1, T, StrideTag>
+MultiArrayView <N, T, StrideTag>::insertSingletonDimension (difference_type_1 i) const
+{
+    vigra_precondition (
+        0 <= i && i <= static_cast <difference_type_1> (N),
+        "MultiArrayView <N, T, StrideTag>::insertSingletonDimension(): index out of range.");
+    TinyVector <MultiArrayIndex, N+1> shape, stride;
+    std::copy (m_shape.begin (), m_shape.begin () + i, shape.begin ());
+    std::copy (m_shape.begin () + i, m_shape.end (), shape.begin () + i + 1);
+    std::copy (m_stride.begin (), m_stride.begin () + i, stride.begin ());
+    std::copy (m_stride.begin () + i, m_stride.end (), stride.begin () + i + 1);
+    shape[i] = 1;
+    stride[i] = 1;
+
+    return MultiArrayView <N+1, T, StrideTag>(shape, stride, m_ptr);
+}
+
+template <unsigned int N, class T, class StrideTag>
+typename NormTraits<MultiArrayView <N, T, StrideTag> >::NormType
+MultiArrayView <N, T, StrideTag>::norm(int type, bool useSquaredNorm) const
+{
+    typedef typename NormTraits<MultiArrayView>::NormType NormType;
+
+    switch(type)
+    {
+      case 0:
+      {
+        NormType res = NumericTraits<NormType>::zero();
+        detail::reduceOverMultiArray(traverser_begin(), shape(), 
+                                     res, 
+                                     detail::MaxNormReduceFunctor(),
+                                     MetaInt<actual_dimension-1>());
+        return res;
+      }
+      case 1:
+      {
+        NormType res = NumericTraits<NormType>::zero();
+        detail::reduceOverMultiArray(traverser_begin(), shape(), 
+                                     res, 
+                                     detail::L1NormReduceFunctor(),
+                                     MetaInt<actual_dimension-1>());
+        return res;
+      }
+      case 2:
+      {
+        if(useSquaredNorm)
+        {
+            return sqrt((NormType)squaredNorm());
+        }
+        else
+        {
+            NormType normMax = NumericTraits<NormType>::zero();
+            detail::reduceOverMultiArray(traverser_begin(), shape(), 
+                                        normMax, 
+                                        detail::MaxNormReduceFunctor(),
+                                        MetaInt<actual_dimension-1>());
+            if(normMax == NumericTraits<NormType>::zero())
+                return normMax;
+            NormType res  = NumericTraits<NormType>::zero();
+            detail::reduceOverMultiArray(traverser_begin(), shape(), 
+                                         res, 
+                                         detail::WeightedL2NormReduceFunctor<NormType>(1.0/normMax),
+                                         MetaInt<actual_dimension-1>());
+            return sqrt(res)*normMax;
+        }
+      }
+      default:
+        vigra_precondition(false, "MultiArrayView::norm(): Unknown norm type.");
+        return NumericTraits<NormType>::zero(); // unreachable
+    }
+}
+
+
+/********************************************************/
+/*                                                      */
+/*                          norm                        */
+/*                                                      */
+/********************************************************/
+
+template <unsigned int N, class T, class StrideTag>
+inline typename NormTraits<MultiArrayView <N, T, StrideTag> >::SquaredNormType
+squaredNorm(MultiArrayView <N, T, StrideTag> const & a)
+{
+    return a.squaredNorm();
+}
+
+template <unsigned int N, class T, class StrideTag>
+inline typename NormTraits<MultiArrayView <N, T, StrideTag> >::NormType
+norm(MultiArrayView <N, T, StrideTag> const & a)
+{
+    return a.norm();
+}
+
+/********************************************************/
+/*                                                      */
+/*                       MultiArray                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Main <TT>MultiArray</TT> class containing the memory
+    management.
+
+This class inherits the interface of MultiArrayView, and implements
+the memory ownership.
+MultiArray's are always unstrided, striding them creates a MultiArrayView.
+
+
+The template parameters are as follows
+\code
+    N: the array dimension
+
+    T: the type of the array elements
+
+    A: the allocator used for internal storage management
+       (default: std::allocator<T>)
+\endcode
+
+<b>\#include</b> \<vigra/multi_array.hxx\> <br/>
+Namespace: vigra
+*/
+template <unsigned int N, class T, class A /* default already declared above */>
+class MultiArray 
+: public MultiArrayView <N, typename vigra::detail::ResolveMultiband<T>::type, 
+                            typename vigra::detail::ResolveMultiband<T>::Stride>
+{
+  public:
+    typedef typename vigra::detail::ResolveMultiband<T>::Stride actual_stride;
+
+        /** the view type associated with this array.
+         */
+    typedef MultiArrayView <N, typename vigra::detail::ResolveMultiband<T>::type, 
+                               typename vigra::detail::ResolveMultiband<T>::Stride> view_type;
+    
+    using view_type::actual_dimension;
+
+        /** the allocator type used to allocate the memory
+         */
+    typedef A allocator_type;
+
+        /** the matrix type associated with this array.
+         */
+    typedef MultiArray <N, T, A> matrix_type;
+
+        /** the array's value type
+         */
+    typedef typename view_type::value_type value_type;
+
+        /** pointer type
+         */
+    typedef typename view_type::pointer pointer;
+
+        /** const pointer type
+         */
+    typedef typename view_type::const_pointer const_pointer;
+
+        /** reference type (result of operator[])
+         */
+    typedef typename view_type::reference reference;
+
+        /** const reference type (result of operator[] const)
+         */
+    typedef typename view_type::const_reference const_reference;
+
+        /** size type
+         */
+    typedef typename view_type::size_type size_type;
+
+        /** difference type (used for multi-dimensional offsets and indices)
+         */
+    typedef typename view_type::difference_type difference_type;
+
+        /** difference and index type for a single dimension
+         */
+    typedef typename view_type::difference_type_1 difference_type_1;
+
+        /** traverser type
+         */
+    typedef typename view_type::traverser traverser;
+
+        /** traverser type to const data
+         */
+    typedef typename view_type::const_traverser  const_traverser;
+
+        // /** sequential (random access) iterator type
+         // */
+    // typedef typename vigra::detail::MultiIteratorChooser<actual_stride>::template Iterator<N, value_type, reference, pointer>::type
+    // iterator;
+
+        // /** sequential (random access) const iterator type
+         // */
+    // typedef typename vigra::detail::MultiIteratorChooser<actual_stride>::template Iterator<N, value_type, const_reference, const_pointer>::type
+    // const_iterator;
+
+        /** sequential (random access) iterator type
+         */
+    typedef typename view_type::iterator iterator;
+
+        /** sequential (random access) const iterator type
+         */
+    typedef typename view_type::const_iterator const_iterator;
+
+protected:
+
+    typedef typename difference_type::value_type diff_zero_t;
+
+        /** the allocator used to allocate the memory
+         */
+    allocator_type m_alloc;
+
+        /** allocate memory for s pixels, write its address into the given
+            pointer and initialize the pixels with init.
+        */
+    void allocate (pointer &ptr, difference_type_1 s, const_reference init);
+
+        /** allocate memory for s pixels, write its address into the given
+            pointer and initialize the linearized pixels to the values of init.
+        */
+    template <class U>
+    void allocate (pointer &ptr, difference_type_1 s, U const * init);
+
+        /** allocate memory, write its address into the given
+            pointer and initialize it by copying the data from the given MultiArrayView.
+        */
+    template <class U, class StrideTag>
+    void allocate (pointer &ptr, MultiArrayView<N, U, StrideTag> const & init);
+
+        /** deallocate the memory (of length s) starting at the given address.
+         */
+    void deallocate (pointer &ptr, difference_type_1 s);
+
+    template <class U, class StrideTag>
+    void copyOrReshape (const MultiArrayView<N, U, StrideTag> &rhs);
+public:
+        /** default constructor
+         */
+    MultiArray ()
+    : view_type (difference_type (diff_zero_t(0)),
+                 difference_type (diff_zero_t(0)), 0)
+    {}
+
+        /** construct with given allocator
+         */
+    MultiArray (allocator_type const & alloc)
+    : view_type(difference_type (diff_zero_t(0)),
+                difference_type (diff_zero_t(0)), 0),
+      m_alloc(alloc)
+    {}
+
+        /** construct with given length
+        
+            Use only for 1-dimensional arrays (<tt>N==1</tt>).
+         */
+    explicit MultiArray (difference_type_1 length,
+                         allocator_type const & alloc = allocator_type());
+
+
+        /** construct with given width and height
+        
+            Use only for 2-dimensional arrays (<tt>N==2</tt>).
+         */
+    MultiArray (difference_type_1 width, difference_type_1 height,
+                         allocator_type const & alloc = allocator_type());
+
+        /** construct with given shape
+         */
+    explicit MultiArray (const difference_type &shape,
+                         allocator_type const & alloc = allocator_type());
+
+        /** construct from shape with an initial value
+         */
+    MultiArray (const difference_type &shape, const_reference init,
+                allocator_type const & alloc = allocator_type());
+
+        /** construct from shape and copy values from the given array
+         */
+    MultiArray (const difference_type &shape, const_pointer init,
+                         allocator_type const & alloc = allocator_type());
+
+        /** copy constructor
+         */
+    MultiArray (const MultiArray &rhs)
+    : view_type(rhs.m_shape, rhs.m_stride, 0),
+      m_alloc (rhs.m_alloc)
+    {
+        allocate (this->m_ptr, this->elementCount (), rhs.data ());
+    }
+
+        /** constructor from an array expression
+         */
+    template<class Expression>
+    MultiArray (multi_math::MultiMathOperand<Expression> const & rhs,
+                allocator_type const & alloc = allocator_type())
+    : view_type(difference_type (diff_zero_t(0)),
+                difference_type (diff_zero_t(0)), 0),
+      m_alloc (alloc)
+    {
+        multi_math::math_detail::assignOrResize(*this, rhs);
+    }
+
+        /** construct by copying from a MultiArrayView
+         */
+    template <class U, class StrideTag>
+    MultiArray (const MultiArrayView<N, U, StrideTag>  &rhs,
+                allocator_type const & alloc = allocator_type());
+
+        /** assignment.<br>
+            If the size of \a rhs is the same as the left-hand side arrays's old size, only
+            the data are copied. Otherwise, new storage is allocated, which invalidates all
+            objects (array views, iterators) depending on the lhs array.
+         */
+    MultiArray & operator= (const MultiArray &rhs)
+    {
+        if (this != &rhs)
+            this->copyOrReshape(rhs);
+        return *this;
+    }
+
+        /** assignment from arbitrary MultiArrayView.<br>
+            If the size of \a rhs is the same as the left-hand side arrays's old size, only
+            the data are copied. Otherwise, new storage is allocated, which invalidates all
+            objects (array views, iterators) depending on the lhs array.
+         */
+    template <class U, class StrideTag>
+    MultiArray &operator= (const MultiArrayView<N, U, StrideTag> &rhs)
+    {
+        this->copyOrReshape(rhs);
+        return *this;
+    }
+
+        /** assignment from scalar.<br>
+            Equivalent to MultiArray::init(v).
+         */
+    MultiArray & operator=(value_type const & v)
+    {
+        return this->init(v);
+    }
+
+        /** Add-assignment from arbitrary MultiArrayView. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+            If the left array has no data (hasData() is false), this function is 
+            equivalent to a normal assignment (i.e. an empty
+            array is interpreted as a zero-array of appropriate size).
+         */
+    template <class U, class StrideTag>
+    MultiArray &operator+= (const MultiArrayView<N, U, StrideTag> &rhs)
+    {
+        if(this->hasData())
+            view_type::operator+=(rhs);
+        else
+            *this = rhs;
+        return *this;
+    }
+
+        /** Subtract-assignment from arbitrary MultiArrayView. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+            If the left array has no data (hasData() is false), this function is 
+            equivalent to an assignment of the negated rhs (i.e. an empty
+            array is interpreted as a zero-array of appropriate size).
+         */
+    template <class U, class StrideTag>
+    MultiArray &operator-= (const MultiArrayView<N, U, StrideTag> &rhs)
+    {
+        if(!this->hasData())
+            this->reshape(rhs.shape());
+        view_type::operator-=(rhs);
+        return *this;
+    }
+
+        /** Multiply-assignment from arbitrary MultiArrayView. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+            If the left array has no data (hasData() is false), this function is 
+            equivalent to reshape(rhs.shape()) with zero initialisation (i.e. an empty
+            array is interpreted as a zero-array of appropriate size).
+         */
+    template <class U, class StrideTag>
+    MultiArray &operator*= (const MultiArrayView<N, U, StrideTag> &rhs)
+    {
+        if(this->hasData())
+            view_type::operator*=(rhs);
+        else
+            this->reshape(rhs.shape());
+        return *this;
+    }
+
+        /** Divide-assignment from arbitrary MultiArrayView. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+            If the left array has no data (hasData() is false), this function is 
+            equivalent to reshape(rhs.shape()) with zero initialisation (i.e. an empty
+            array is interpreted as a zero-array of appropriate size).
+         */
+    template <class U, class StrideTag>
+    MultiArray &operator/= (const MultiArrayView<N, U, StrideTag> &rhs)
+    {
+        if(this->hasData())
+            view_type::operator/=(rhs);
+        else
+            this->reshape(rhs.shape());
+        return *this;
+    }
+
+        /** Add-assignment of a scalar.
+         */
+    MultiArray &operator+= (const T &rhs)
+    {
+        view_type::operator+=(rhs);
+        return *this;
+    }
+
+        /** Subtract-assignment of a scalar.
+         */
+    MultiArray &operator-= (const T &rhs)
+    {
+        view_type::operator-=(rhs);
+        return *this;
+    }
+
+        /** Multiply-assignment of a scalar.
+         */
+    MultiArray &operator*= (const T &rhs)
+    {
+        view_type::operator*=(rhs);
+        return *this;
+    }
+
+        /** Divide-assignment of a scalar.
+         */
+    MultiArray &operator/= (const T &rhs)
+    {
+        view_type::operator/=(rhs);
+        return *this;
+    }
+        /** Assignment of an array expression. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class Expression>
+    MultiArray & operator=(multi_math::MultiMathOperand<Expression> const & rhs)
+    {
+        multi_math::math_detail::assignOrResize(*this, rhs);
+        return *this;
+    }
+
+        /** Add-assignment of an array expression. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class Expression>
+    MultiArray & operator+=(multi_math::MultiMathOperand<Expression> const & rhs)
+    {
+        multi_math::math_detail::plusAssignOrResize(*this, rhs);
+        return *this;
+    }
+
+        /** Subtract-assignment of an array expression. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class Expression>
+    MultiArray & operator-=(multi_math::MultiMathOperand<Expression> const & rhs)
+    {
+        multi_math::math_detail::minusAssignOrResize(*this, rhs);
+        return *this;
+    }
+
+        /** Multiply-assignment of an array expression. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class Expression>
+    MultiArray & operator*=(multi_math::MultiMathOperand<Expression> const & rhs)
+    {
+        multi_math::math_detail::multiplyAssignOrResize(*this, rhs);
+        return *this;
+    }
+
+        /** Divide-assignment of an array expression. Fails with
+            <tt>PreconditionViolation</tt> exception when the shapes do not match.
+         */
+    template<class Expression>
+    MultiArray & operator/=(multi_math::MultiMathOperand<Expression> const & rhs)
+    {
+        multi_math::math_detail::divideAssignOrResize(*this, rhs);
+        return *this;
+    }
+
+        /** destructor
+         */
+    ~MultiArray ()
+    {
+        deallocate (this->m_ptr, this->elementCount ());
+    }
+
+
+        /** init elements with a constant
+         */
+    template <class U>
+    MultiArray & init(const U & init)
+    {
+        view_type::init(init);
+        return *this;
+    }
+
+        /** Allocate new memory with the given shape and initialize with zeros.<br>
+            <em>Note:</em> this operation invalidates all dependent objects
+            (array views and iterators)
+         */
+    void reshape (const difference_type &shape)
+    {
+        reshape (shape, value_type());
+    }
+
+        /** Allocate new memory with the given shape and initialize it
+            with the given value.<br>
+            <em>Note:</em> this operation invalidates all dependent objects
+            (array views and iterators)
+         */
+    void reshape (const difference_type &shape, const_reference init);
+
+        /** Swap the contents with another MultiArray. This is fast,
+            because no data are copied, but only pointers and shapes swapped.
+            <em>Note:</em> this operation invalidates all dependent objects
+            (array views and iterators)
+         */
+    void swap (MultiArray & other);
+
+        // /** sequential iterator pointing to the first array element.
+         // */
+    // iterator begin ()
+    // {
+        // return vigra::detail::MultiIteratorChooser<actual_stride>::template constructIterator<iterator>((view_type *)this);
+    // }
+
+        // /** sequential iterator pointing beyond the last array element.
+         // */
+    // iterator end ()
+    // {
+        // return begin() + this->elementCount();
+    // }
+
+        // /** sequential const iterator pointing to the first array element.
+         // */
+    // const_iterator begin () const
+    // {
+        // return vigra::detail::MultiIteratorChooser<actual_stride>::template constructIterator<iterator>((view_type const *)this);
+    // }
+
+        // /** sequential const iterator pointing beyond the last array element.
+         // */
+    // const_iterator end () const
+    // {
+        // return begin() + this->elementCount();
+    // }
+
+        /** get the allocator.
+         */
+    allocator_type const & allocator () const
+    {
+        return m_alloc;
+    }
+    
+    static difference_type defaultStride(difference_type const & shape)
+    {
+        return vigra::detail::ResolveMultiband<T>::defaultStride(shape);
+    }
+};
+
+template <unsigned int N, class T, class A>
+MultiArray <N, T, A>::MultiArray (difference_type_1 length,
+                                  allocator_type const & alloc)
+: view_type(difference_type(length),
+            defaultStride(difference_type(length)),
+            0),
+  m_alloc(alloc)
+{
+    allocate (this->m_ptr, this->elementCount (), value_type());
+}
+
+template <unsigned int N, class T, class A>
+MultiArray <N, T, A>::MultiArray (difference_type_1 width, difference_type_1 height,
+                                  allocator_type const & alloc)
+: view_type(difference_type(width, height),
+            defaultStride(difference_type(width, height)),
+            0),
+  m_alloc(alloc)
+{
+    allocate (this->m_ptr, this->elementCount (), value_type());
+}
+
+template <unsigned int N, class T, class A>
+MultiArray <N, T, A>::MultiArray (const difference_type &shape,
+                                  allocator_type const & alloc)
+: view_type(shape,
+            defaultStride(shape),
+            0),
+  m_alloc(alloc)
+{
+    if (N == 0)
+    {
+        this->m_shape [0] = 1;
+        this->m_stride [0] = 1;
+    }
+    allocate (this->m_ptr, this->elementCount (), value_type());
+}
+
+template <unsigned int N, class T, class A>
+MultiArray <N, T, A>::MultiArray (const difference_type &shape, const_reference init,
+                                  allocator_type const & alloc)
+: view_type(shape,
+            defaultStride(shape),
+            0),
+  m_alloc(alloc)
+{
+    if (N == 0)
+    {
+        this->m_shape [0] = 1;
+        this->m_stride [0] = 1;
+    }
+    allocate (this->m_ptr, this->elementCount (), init);
+}
+
+template <unsigned int N, class T, class A>
+MultiArray <N, T, A>::MultiArray (const difference_type &shape, const_pointer init,
+                                  allocator_type const & alloc)
+: view_type(shape,
+            defaultStride(shape),
+            0),
+  m_alloc(alloc)
+{
+    if (N == 0)
+    {
+        this->m_shape [0] = 1;
+        this->m_stride [0] = 1;
+    }
+    allocate (this->m_ptr, this->elementCount (), init);
+}
+
+template <unsigned int N, class T, class A>
+template <class U, class StrideTag>
+MultiArray <N, T, A>::MultiArray(const MultiArrayView<N, U, StrideTag>  &rhs,
+                                 allocator_type const & alloc)
+: view_type(rhs.shape(),
+            defaultStride(rhs.shape()),
+            0),
+  m_alloc (alloc)
+{
+    allocate (this->m_ptr, rhs);
+}
+
+template <unsigned int N, class T, class A>
+template <class U, class StrideTag>
+void
+MultiArray <N, T, A>::copyOrReshape(const MultiArrayView<N, U, StrideTag> &rhs)
+{
+    if (this->shape() == rhs.shape())
+        this->copy(rhs);
+    else
+    {
+        MultiArray t(rhs);
+        this->swap(t);
+    }
+}
+
+template <unsigned int N, class T, class A>
+void MultiArray <N, T, A>::reshape (const difference_type & new_shape,
+                                    const_reference initial)
+{
+    if (N == 0)
+    {
+        return;
+    }
+    else if(new_shape == this->shape())
+    {
+        this->init(initial);
+    }
+    else
+    {
+        difference_type new_stride = defaultStride(new_shape);
+        difference_type_1 new_size = prod(new_shape);
+        pointer new_ptr = pointer();
+        allocate (new_ptr, new_size, initial);
+        deallocate (this->m_ptr, this->elementCount ());
+        this->m_ptr = new_ptr;
+        this->m_shape = new_shape;
+        this->m_stride = new_stride;
+    }
+}
+
+
+template <unsigned int N, class T, class A>
+inline void
+MultiArray <N, T, A>::swap (MultiArray & other)
+{
+    if (this == &other)
+        return;
+    std::swap(this->m_shape,  other.m_shape);
+    std::swap(this->m_stride, other.m_stride);
+    std::swap(this->m_ptr,    other.m_ptr);
+    std::swap(this->m_alloc,  other.m_alloc);
+}
+
+template <unsigned int N, class T, class A>
+void MultiArray <N, T, A>::allocate (pointer & ptr, difference_type_1 s,
+                                     const_reference init)
+{
+    if(s == 0)
+    {
+        ptr = 0;
+        return;
+    }
+    ptr = m_alloc.allocate ((typename A::size_type)s);
+    difference_type_1 i;
+    try {
+        for (i = 0; i < s; ++i)
+            m_alloc.construct (ptr + i, init);
+    }
+    catch (...) {
+        for (difference_type_1 j = 0; j < i; ++j)
+            m_alloc.destroy (ptr + j);
+        m_alloc.deallocate (ptr, (typename A::size_type)s);
+        throw;
+    }
+}
+
+template <unsigned int N, class T, class A>
+template <class U>
+void MultiArray <N, T, A>::allocate (pointer & ptr, difference_type_1 s,
+                                     U const * init)
+{
+    if(s == 0)
+    {
+        ptr = 0;
+        return;
+    }
+    ptr = m_alloc.allocate ((typename A::size_type)s);
+    difference_type_1 i;
+    try {
+        for (i = 0; i < s; ++i, ++init)
+            m_alloc.construct (ptr + i, *init);
+    }
+    catch (...) {
+        for (difference_type_1 j = 0; j < i; ++j)
+            m_alloc.destroy (ptr + j);
+        m_alloc.deallocate (ptr, (typename A::size_type)s);
+        throw;
+    }
+}
+
+template <unsigned int N, class T, class A>
+template <class U, class StrideTag>
+void MultiArray <N, T, A>::allocate (pointer & ptr, MultiArrayView<N, U, StrideTag> const & init)
+{
+    difference_type_1 s = init.elementCount();
+    if(s == 0)
+    {
+        ptr = 0;
+        return;
+    }
+    ptr = m_alloc.allocate ((typename A::size_type)s);
+    pointer p = ptr;
+    try {
+        detail::uninitializedCopyMultiArrayData(init.traverser_begin(), init.shape(),
+                                                p, m_alloc, MetaInt<actual_dimension-1>());
+    }
+    catch (...) {
+        for (pointer pp = ptr; pp < p; ++pp)
+            m_alloc.destroy (pp);
+        m_alloc.deallocate (ptr, (typename A::size_type)s);
+        throw;
+    }
+}
+
+template <unsigned int N, class T, class A>
+inline void MultiArray <N, T, A>::deallocate (pointer & ptr, difference_type_1 s)
+{
+    if (ptr == 0)
+        return;
+    for (difference_type_1 i = 0; i < s; ++i)
+        m_alloc.destroy (ptr + i);
+    m_alloc.deallocate (ptr, (typename A::size_type)s);
+    ptr = 0;
+}
+
+/********************************************************/
+/*                                                      */
+/*              argument object factories               */
+/*                                                      */
+/********************************************************/
+
+template <unsigned int N, class T, class StrideTag>
+inline triple<typename MultiArrayView<N,T,StrideTag>::const_traverser,
+              typename MultiArrayView<N,T,StrideTag>::difference_type,
+              typename AccessorTraits<T>::default_const_accessor >
+srcMultiArrayRange( MultiArrayView<N,T,StrideTag> const & array )
+{
+    return triple<typename MultiArrayView<N,T,StrideTag>::const_traverser,
+                  typename MultiArrayView<N,T,StrideTag>::difference_type,
+                  typename AccessorTraits<T>::default_const_accessor >
+      ( array.traverser_begin(),
+        array.shape(),
+        typename AccessorTraits<T>::default_const_accessor() );
+}
+
+template <unsigned int N, class T, class StrideTag, class Accessor>
+inline triple<typename MultiArrayView<N,T,StrideTag>::const_traverser,
+              typename MultiArrayView<N,T,StrideTag>::difference_type,
+              Accessor >
+srcMultiArrayRange( MultiArrayView<N,T,StrideTag> const & array, Accessor a )
+{
+    return triple<typename MultiArrayView<N,T,StrideTag>::const_traverser,
+                  typename MultiArrayView<N,T,StrideTag>::difference_type,
+                  Accessor >
+      ( array.traverser_begin(),
+        array.shape(),
+        a);
+}
+
+template <unsigned int N, class T, class StrideTag>
+inline pair<typename MultiArrayView<N,T,StrideTag>::const_traverser,
+            typename AccessorTraits<T>::default_const_accessor >
+srcMultiArray( MultiArrayView<N,T,StrideTag> const & array )
+{
+    return pair<typename MultiArrayView<N,T,StrideTag>::const_traverser,
+                typename AccessorTraits<T>::default_const_accessor >
+      ( array.traverser_begin(),
+        typename AccessorTraits<T>::default_const_accessor() );
+}
+
+template <unsigned int N, class T, class StrideTag, class Accessor>
+inline pair<typename MultiArrayView<N,T,StrideTag>::const_traverser,
+            Accessor >
+srcMultiArray( MultiArrayView<N,T,StrideTag> const & array, Accessor a )
+{
+    return pair<typename MultiArrayView<N,T,StrideTag>::const_traverser,
+                Accessor >
+      ( array.traverser_begin(), a );
+}
+
+template <unsigned int N, class T, class StrideTag>
+inline triple<typename MultiArrayView<N,T,StrideTag>::traverser,
+              typename MultiArrayView<N,T,StrideTag>::difference_type,
+              typename AccessorTraits<T>::default_accessor >
+destMultiArrayRange( MultiArrayView<N,T,StrideTag> & array )
+{
+    return triple<typename MultiArrayView<N,T,StrideTag>::traverser,
+                  typename MultiArrayView<N,T,StrideTag>::difference_type,
+                  typename AccessorTraits<T>::default_accessor >
+      ( array.traverser_begin(),
+        array.shape(),
+        typename AccessorTraits<T>::default_accessor() );
+}
+
+template <unsigned int N, class T, class StrideTag, class Accessor>
+inline triple<typename MultiArrayView<N,T,StrideTag>::traverser,
+              typename MultiArrayView<N,T,StrideTag>::difference_type,
+              Accessor >
+destMultiArrayRange( MultiArrayView<N,T,StrideTag> & array, Accessor a )
+{
+    return triple<typename MultiArrayView<N,T,StrideTag>::traverser,
+                  typename MultiArrayView<N,T,StrideTag>::difference_type,
+                  Accessor >
+      ( array.traverser_begin(),
+        array.shape(),
+        a );
+}
+
+template <unsigned int N, class T, class StrideTag>
+inline pair<typename MultiArrayView<N,T,StrideTag>::traverser,
+            typename AccessorTraits<T>::default_accessor >
+destMultiArray( MultiArrayView<N,T,StrideTag> & array )
+{
+    return pair<typename MultiArrayView<N,T,StrideTag>::traverser,
+                typename AccessorTraits<T>::default_accessor >
+        ( array.traverser_begin(),
+          typename AccessorTraits<T>::default_accessor() );
+}
+
+template <unsigned int N, class T, class StrideTag, class Accessor>
+inline pair<typename MultiArrayView<N,T,StrideTag>::traverser,
+            Accessor >
+destMultiArray( MultiArrayView<N,T,StrideTag> & array, Accessor a )
+{
+    return pair<typename MultiArrayView<N,T,StrideTag>::traverser,
+                Accessor >
+        ( array.traverser_begin(), a );
+}
+
+/********************************************************************/
+
+template <class PixelType, class Accessor>
+inline triple<ConstStridedImageIterator<PixelType>,
+              ConstStridedImageIterator<PixelType>, Accessor>
+srcImageRange(const MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
+{
+    ConstStridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    return triple<ConstStridedImageIterator<PixelType>,
+                  ConstStridedImageIterator<PixelType>,
+                  Accessor>(
+                      ul, ul + Size2D(img.shape(0), img.shape(1)), a);
+}
+
+template <class PixelType, class Accessor>
+inline pair<ConstStridedImageIterator<PixelType>, Accessor>
+srcImage(const MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
+{
+    ConstStridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    return pair<ConstStridedImageIterator<PixelType>, Accessor>
+        (ul, a);
+}
+
+template <class PixelType, class Accessor>
+inline triple<StridedImageIterator<PixelType>,
+              StridedImageIterator<PixelType>, Accessor>
+destImageRange(MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
+{
+    StridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    return triple<StridedImageIterator<PixelType>,
+                  StridedImageIterator<PixelType>,
+                  Accessor>(
+                      ul, ul + Size2D(img.shape(0), img.shape(1)), a);
+}
+
+template <class PixelType, class Accessor>
+inline pair<StridedImageIterator<PixelType>, Accessor>
+destImage(MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
+{
+    StridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    return pair<StridedImageIterator<PixelType>, Accessor>
+        (ul, a);
+}
+
+template <class PixelType, class Accessor>
+inline pair<StridedImageIterator<PixelType>, Accessor>
+maskImage(MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
+{
+    StridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    return pair<StridedImageIterator<PixelType>, Accessor>
+        (ul, a);
+}
+
+// -------------------------------------------------------------------
+
+template <class PixelType>
+inline triple<ConstStridedImageIterator<PixelType>,
+              ConstStridedImageIterator<PixelType>,
+              typename AccessorTraits<PixelType>::default_const_accessor>
+srcImageRange(MultiArrayView<2, PixelType, StridedArrayTag> const & img)
+{
+    ConstStridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
+    return triple<ConstStridedImageIterator<PixelType>,
+                  ConstStridedImageIterator<PixelType>,
+                  Accessor>
+        (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
+}
+
+template <class PixelType>
+inline triple<ConstImageIterator<PixelType>,
+              ConstImageIterator<PixelType>,
+              typename AccessorTraits<PixelType>::default_const_accessor>
+srcImageRange(MultiArrayView<2, PixelType, UnstridedArrayTag> const & img)
+{
+    ConstImageIterator<PixelType>
+        ul(img.data(), img.stride(1));
+    typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
+    return triple<ConstImageIterator<PixelType>,
+                  ConstImageIterator<PixelType>,
+                  Accessor>
+        (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
+}
+
+template <class PixelType>
+inline pair< ConstStridedImageIterator<PixelType>,
+             typename AccessorTraits<PixelType>::default_const_accessor>
+srcImage(MultiArrayView<2, PixelType, StridedArrayTag> const & img)
+{
+    ConstStridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
+    return pair<ConstStridedImageIterator<PixelType>,
+                Accessor>
+        (ul, Accessor());
+}
+
+template <class PixelType>
+inline pair< ConstImageIterator<PixelType>,
+             typename AccessorTraits<PixelType>::default_const_accessor>
+srcImage(MultiArrayView<2, PixelType, UnstridedArrayTag> const & img)
+{
+    ConstImageIterator<PixelType>
+        ul(img.data(), img.stride(1));
+    typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
+    return pair<ConstImageIterator<PixelType>,
+                Accessor>
+        (ul, Accessor());
+}
+
+template <class PixelType>
+inline triple< StridedImageIterator<PixelType>,
+               StridedImageIterator<PixelType>,
+               typename AccessorTraits<PixelType>::default_accessor>
+destImageRange(MultiArrayView<2, PixelType, StridedArrayTag> & img)
+{
+    StridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
+    return triple<StridedImageIterator<PixelType>,
+                  StridedImageIterator<PixelType>,
+                  Accessor>
+        (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
+}
+
+template <class PixelType>
+inline triple< ImageIterator<PixelType>,
+               ImageIterator<PixelType>,
+               typename AccessorTraits<PixelType>::default_accessor>
+destImageRange(MultiArrayView<2, PixelType, UnstridedArrayTag> & img)
+{
+    ImageIterator<PixelType>
+        ul(img.data(), img.stride(1));
+    typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
+    return triple<ImageIterator<PixelType>,
+                  ImageIterator<PixelType>,
+                  Accessor>
+        (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
+}
+
+template <class PixelType>
+inline pair< StridedImageIterator<PixelType>,
+             typename AccessorTraits<PixelType>::default_accessor>
+destImage(MultiArrayView<2, PixelType, StridedArrayTag> & img)
+{
+    StridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
+    return pair<StridedImageIterator<PixelType>, Accessor>
+        (ul, Accessor());
+}
+
+template <class PixelType>
+inline pair< ImageIterator<PixelType>,
+             typename AccessorTraits<PixelType>::default_accessor>
+destImage(MultiArrayView<2, PixelType, UnstridedArrayTag> & img)
+{
+    ImageIterator<PixelType> ul(img.data(), img.stride(1));
+    typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
+    return pair<ImageIterator<PixelType>, Accessor>(ul, Accessor());
+}
+
+template <class PixelType>
+inline pair< ConstStridedImageIterator<PixelType>,
+             typename AccessorTraits<PixelType>::default_accessor>
+maskImage(MultiArrayView<2, PixelType, StridedArrayTag> const & img)
+{
+    ConstStridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
+    return pair<ConstStridedImageIterator<PixelType>, Accessor>
+        (ul, Accessor());
+}
+
+template <class PixelType>
+inline pair< ConstImageIterator<PixelType>,
+             typename AccessorTraits<PixelType>::default_accessor>
+maskImage(MultiArrayView<2, PixelType, UnstridedArrayTag> const & img)
+{
+    ConstImageIterator<PixelType>
+        ul(img.data(), img.stride(1));
+    typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
+    return pair<ConstImageIterator<PixelType>, Accessor>
+        (ul, Accessor());
+}
+
+/********************************************************/
+/*                                                      */
+/*                  makeBasicImageView                  */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup MultiArrayToImage Create BasicImageView from MultiArrayViews
+  
+    Some convenience functions for wrapping a \ref vigra::MultiArrayView's
+    data in a \ref vigra::BasicImageView. 
+*/
+//@{
+/** Create a \ref vigra::BasicImageView from an unstrided 2-dimensional
+    \ref vigra::MultiArrayView.
+
+    The \ref vigra::BasicImageView will have the same <tt>value_type </tt>
+    as the original \ref vigra::MultiArrayView.
+*/
+template <class T, class Stride>
+BasicImageView <T>
+makeBasicImageView (MultiArrayView <2, T, Stride> const &array)
+{
+    vigra_precondition(array.isUnstrided(),
+       "makeBasicImageView(array): array must be unstrided (i.e. array.isUnstrided() == true).");
+    return BasicImageView <T> (array.data (), array.shape (0),
+                               array.shape (1), array.stride(1));
+}
+
+/** Create a \ref vigra::BasicImageView from a 3-dimensional
+    \ref vigra::MultiArray.
+
+    This wrapper flattens the two innermost dimensions of the array
+    into single rows of the resulting image.
+    The \ref vigra::BasicImageView will have the same <tt>value_type </tt>
+    as the original \ref vigra::MultiArray.
+*/
+template <class T>
+BasicImageView <T>
+makeBasicImageView (MultiArray <3, T> const &array)
+{
+    vigra_precondition(array.stride(1) == array.shape(0),
+               "makeBasicImageView(): cannot join strided dimensions");
+    return BasicImageView <T> (array.data (),
+                               array.shape (0)*array.shape (1), array.shape (2), array.stride(2));
+}
+
+/** Create a \ref vigra::BasicImageView from a 3-dimensional
+    \ref vigra::MultiArray.
+
+    This wrapper only works if <tt>T</tt> is a scalar type and the
+    array's innermost dimension has size 3. It then re-interprets
+    the data array as a 2-dimensional array with value_type
+    <tt>RGBValue<T></tt>.
+*/
+template <class T, class Stride>
+BasicImageView <RGBValue<T> >
+makeRGBImageView (MultiArrayView<3, T, Stride> const &array)
+{
+    vigra_precondition(array.shape (0) == 3, 
+       "makeRGBImageView(): array.shape(0) must be 3.");
+    vigra_precondition(array.isUnstrided(),
+       "makeRGBImageView(array): array must be unstrided (i.e. array.isUnstrided() == true).");
+    return BasicImageView <RGBValue<T> > (
+        reinterpret_cast <RGBValue <T> *> (array.data ()),
+        array.shape (1), array.shape (2));
+}
+
+//@}
+
+} // namespace vigra
+
+#undef VIGRA_ASSERT_INSIDE
+
+#endif // VIGRA_MULTI_ARRAY_HXX
diff --git a/include/vigra/multi_convolution.hxx b/include/vigra/multi_convolution.hxx
new file mode 100644
index 0000000..4033b54
--- /dev/null
+++ b/include/vigra/multi_convolution.hxx
@@ -0,0 +1,2714 @@
+//-- -*- c++ -*-
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2003 by Christian-Dennis Rahn                */
+/*                        and Ullrich Koethe                            */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_CONVOLUTION_H
+#define VIGRA_MULTI_CONVOLUTION_H
+
+#include "separableconvolution.hxx"
+#include "array_vector.hxx"
+#include "multi_array.hxx"
+#include "accessor.hxx"
+#include "numerictraits.hxx"
+#include "navigator.hxx"
+#include "metaprogramming.hxx"
+#include "multi_pointoperators.hxx"
+#include "multi_math.hxx"
+#include "functorexpression.hxx"
+#include "tinyvector.hxx"
+#include "algorithm.hxx"
+
+namespace vigra
+{
+
+namespace detail
+{
+
+struct DoubleYielder
+{
+    const double value;
+    DoubleYielder(double v, unsigned, const char *const) : value(v) {}
+    DoubleYielder(double v)                              : value(v) {}
+    void operator++() {}
+    double operator*() const { return value; }
+};
+
+template <typename X>
+struct IteratorDoubleYielder
+{
+    X it;
+    IteratorDoubleYielder(X i, unsigned, const char *const) : it(i) {}
+    IteratorDoubleYielder(X i)                              : it(i) {}
+    void operator++() { ++it; }
+    double operator*() const { return *it; }
+};
+
+template <typename X>
+struct SequenceDoubleYielder
+{
+    typename X::const_iterator it;
+    SequenceDoubleYielder(const X & seq, unsigned dim,
+                          const char *const function_name = "SequenceDoubleYielder")
+        : it(seq.begin())
+    {
+        if (seq.size() == dim)
+            return;
+        std::string msg = "(): Parameter number be equal to the number of spatial dimensions.";
+        vigra_precondition(false, function_name + msg);
+    }
+    void operator++() { ++it; }
+    double operator*() const { return *it; }
+};
+
+template <typename X>
+struct WrapDoubleIterator
+{
+    typedef
+    typename IfBool< IsConvertibleTo<X, double>::value,
+        DoubleYielder,
+        typename IfBool< IsIterator<X>::value || IsArray<X>::value,
+            IteratorDoubleYielder<X>,
+            SequenceDoubleYielder<X>
+        >::type
+    >::type type;
+};
+
+template <class Param1, class Param2, class Param3>
+struct WrapDoubleIteratorTriple
+{
+    typename WrapDoubleIterator<Param1>::type sigma_eff_it;
+    typename WrapDoubleIterator<Param2>::type sigma_d_it;
+    typename WrapDoubleIterator<Param3>::type step_size_it;
+    WrapDoubleIteratorTriple(Param1 sigma_eff, Param2 sigma_d, Param3 step_size)
+        : sigma_eff_it(sigma_eff), sigma_d_it(sigma_d), step_size_it(step_size) {}
+    void operator++()
+    {
+        ++sigma_eff_it;
+        ++sigma_d_it;
+        ++step_size_it;
+    }
+    double sigma_eff() const { return *sigma_eff_it; }
+    double sigma_d() const { return *sigma_d_it; }
+    double step_size() const { return *step_size_it; }
+    static void sigma_precondition(double sigma, const char *const function_name)
+    {
+        if (sigma < 0.0)
+        {
+             std::string msg = "(): Scale must be positive.";
+             vigra_precondition(false, function_name + msg);
+        }
+    }
+    double sigma_scaled(const char *const function_name = "unknown function ") const
+    {
+        sigma_precondition(sigma_eff(), function_name);
+        sigma_precondition(sigma_d(), function_name);
+        double sigma_squared = sq(sigma_eff()) - sq(sigma_d());
+        if (sigma_squared > 0.0)
+        {
+            return std::sqrt(sigma_squared) / step_size();
+        }
+        else
+        {
+             std::string msg = "(): Scale would be imaginary or zero.";
+             vigra_precondition(false, function_name + msg);
+             return 0;
+        }
+    }
+};
+
+template <unsigned dim>
+struct multiArrayScaleParam
+{
+    typedef TinyVector<double, dim> p_vector;
+    typedef typename p_vector::const_iterator return_type;
+    p_vector vec;
+
+    template <class Param>
+    multiArrayScaleParam(Param val, const char *const function_name = "multiArrayScaleParam")
+    {
+        typename WrapDoubleIterator<Param>::type in(val, dim, function_name);
+        for (unsigned i = 0; i != dim; ++i, ++in)
+            vec[i] = *in;
+    }
+    return_type operator()() const
+    {
+        return vec.begin();
+    }
+    static void precondition(unsigned n_par, const char *const function_name = "multiArrayScaleParam")
+    {
+        char n[3] = "0.";
+        n[0] += dim;
+        std::string msg = "(): dimension parameter must be ";
+        vigra_precondition(dim == n_par, function_name + msg + n);
+    }
+    multiArrayScaleParam(double v0, double v1, const char *const function_name = "multiArrayScaleParam")
+    {
+        precondition(2, function_name);
+        vec = p_vector(v0, v1);
+    }
+    multiArrayScaleParam(double v0, double v1, double v2, const char *const function_name = "multiArrayScaleParam")
+    {
+        precondition(3, function_name);
+        vec = p_vector(v0, v1, v2);
+    }
+    multiArrayScaleParam(double v0, double v1, double v2,  double v3, const char *const function_name = "multiArrayScaleParam")
+    {
+        precondition(4, function_name);
+        vec = p_vector(v0, v1, v2, v3);
+    }
+    multiArrayScaleParam(double v0, double v1, double v2,  double v3, double v4, const char *const function_name = "multiArrayScaleParam")
+    {
+        precondition(5, function_name);
+        vec = p_vector(v0, v1, v2, v3, v4);
+    }
+};
+
+} // namespace detail
+
+#define VIGRA_CONVOLUTION_OPTIONS(function_name, default_value, member_name) \
+    template <class Param> \
+    ConvolutionOptions & function_name(const Param & val) \
+    { \
+        member_name = ParamVec(val, "ConvolutionOptions::" #function_name); \
+        return *this; \
+    } \
+    ConvolutionOptions & function_name() \
+    { \
+        member_name = ParamVec(default_value, "ConvolutionOptions::" #function_name); \
+        return *this; \
+    } \
+    ConvolutionOptions & function_name(double v0, double v1) \
+    { \
+        member_name = ParamVec(v0, v1, "ConvolutionOptions::" #function_name); \
+        return *this; \
+    } \
+    ConvolutionOptions & function_name(double v0, double v1, double v2) \
+    { \
+        member_name = ParamVec(v0, v1, v2, "ConvolutionOptions::" #function_name); \
+        return *this; \
+    } \
+    ConvolutionOptions & function_name(double v0, double v1, double v2, double v3) \
+    { \
+        member_name = ParamVec(v0, v1, v2, v3, "ConvolutionOptions::" #function_name); \
+        return *this; \
+    } \
+    ConvolutionOptions & function_name(double v0, double v1, double v2, double v3, double v4) \
+    { \
+        member_name = ParamVec(v0, v1, v2, v3, v4, "ConvolutionOptions::" #function_name); \
+        return *this; \
+    }
+
+
+/** \brief  Options class template for convolutions.
+ 
+  <b>\#include</b> \<vigra/multi_convolution.hxx\><br/>
+  Namespace: vigra
+  
+  This class enables the calculation of scale space convolutions
+  such as \ref gaussianGradientMultiArray() on data with anisotropic
+  discretization. For these, the result of the ordinary calculation
+  has to be multiplied by factors of \f$1/w^{n}\f$ for each dimension,
+  where \f$w\f$ is the step size of the grid in said dimension and
+  \f$n\f$ is the differential order of the convolution, e.g., 1 for
+  gaussianGradientMultiArray(), and 0 for gaussianSmoothMultiArray(),
+  respectively. Also for each dimension in turn, the convolution's scale
+  parameter \f$\sigma\f$ has to be replaced by
+  \f$\sqrt{\sigma_\mathrm{eff}^2 - \sigma_\mathrm{D}^2}\Big/w\f$,
+  where \f$\sigma_\mathrm{eff}\f$ is the resulting effective filtering
+  scale. The data is assumed to be already filtered by a 
+  gaussian smoothing with the scale parameter \f$\sigma_\mathrm{D}\f$
+  (such as by measuring equipment). All of the above changes are
+  automatically employed by the convolution functions for <tt>MultiArray</tt>s
+  if a corresponding options object is provided.
+
+  The <tt>ConvolutionOptions</tt> class must be parameterized by the dimension
+  <tt>dim</tt>
+  of the <tt>MultiArray</tt>s on which it is used. The actual per-axis
+  options are set by (overloaded) member functions explained below,
+  or else default to neutral values corresponding to the absence of the
+  particular option.
+  
+  All member functions set <tt>dim</tt> values of the respective convolution
+  option, one for each dimension. They may be set explicitly by multiple
+  arguments for up to five dimensions, or by a single argument to the same
+  value for all dimensions. For the general case, a single argument that is
+  either a C-syle array, an iterator, or a C++ standard library style
+  sequence (such as <tt>std::vector</tt>, with member functions <tt>begin()</tt>
+  and <tt>size()</tt>) supplies the option values for any number of dimensions.
+  
+  Note that the return value of all member functions is <tt>*this</tt>, which
+  provides the mechanism for concatenating member function calls as shown below.
+
+  <b>usage with explicit parameters:</b>
+
+  \code
+  ConvolutionOptions<2> opt = ConvolutionOptions<2>().stepSize(1, 2.3);
+  \endcode
+ 
+  <b>usage with arrays:</b>
+ 
+  \code
+  const double step_size[3] = { x_scale, y_scale, z_scale };
+  ConvolutionOptions<3> opt = ConvolutionOptions<3>().stepSize(step_size);
+  \endcode
+
+  <b>usage with C++ standard library style sequences:</b>
+ 
+  \code
+  TinyVector<double, 4> step_size(1, 1, 2.0, 1.5);
+  TinyVector<double, 4>  r_sigmas(1, 1, 2.3, 3.2);
+  ConvolutionOptions<4> opt = ConvolutionOptions<4>().stepSize(step_size).resolutionStdDev(r_sigmas);
+  \endcode
+
+  <b>usage with iterators:</b>
+
+  \code
+  ArrayVector<double> step_size;
+  step_size.push_back(0);
+  step_size.push_back(3);
+  step_size.push_back(4);
+  ArrayVector<double>::iterator i = step_size.begin();
+  ++i;
+  ConvolutionOptions<2> opt = ConvolutionOptions<2>().stepSize(i);
+  \endcode
+
+  <b>general usage in a convolution function call:</b>
+
+  \code
+  MultiArray<3, double> test_image;
+  MultiArray<3, double> out_image;
+  
+  double scale = 5.0;
+  gaussianSmoothMultiArray(test_image, out_image, scale,
+                           ConvolutionOptions<3>()
+                              .stepSize        (1, 1, 3.2)
+                              .resolutionStdDev(1, 1, 4)
+                          );
+  \endcode
+ 
+*/
+template <unsigned dim>
+class ConvolutionOptions
+{
+  public:
+    typedef typename MultiArrayShape<dim>::type Shape;
+    typedef detail::multiArrayScaleParam<dim> ParamVec;
+    typedef typename ParamVec::return_type    ParamIt;
+
+    ParamVec sigma_eff;
+    ParamVec sigma_d;
+    ParamVec step_size;
+    ParamVec outer_scale;
+    double window_ratio;
+    Shape from_point, to_point;
+     
+    ConvolutionOptions()
+    : sigma_eff(0.0),
+      sigma_d(0.0),
+      step_size(1.0),
+      outer_scale(0.0),
+      window_ratio(0.0)
+    {}
+
+    typedef typename detail::WrapDoubleIteratorTriple<ParamIt, ParamIt, ParamIt>
+        ScaleIterator;
+    typedef typename detail::WrapDoubleIterator<ParamIt>::type
+        StepIterator;
+
+    ScaleIterator scaleParams() const
+    {
+        return ScaleIterator(sigma_eff(), sigma_d(), step_size());
+    }
+    StepIterator stepParams() const
+    {
+        return StepIterator(step_size());
+    }
+
+    ConvolutionOptions outerOptions() const
+    {
+        ConvolutionOptions outer = *this;
+        // backward-compatible values:
+        return outer.stdDev(outer_scale()).resolutionStdDev(0.0);
+    }
+
+    // Step size per axis.
+    // Default: dim values of 1.0
+    VIGRA_CONVOLUTION_OPTIONS(stepSize, 1.0, step_size)
+#ifdef DOXYGEN
+        /** Step size(s) per axis, i.e., the distance between two
+            adjacent pixels. Required for <tt>MultiArray</tt>
+            containing anisotropic data.
+ 
+            Note that a convolution containing a derivative operator
+            of order <tt>n</tt> results in a multiplication by 
+            \f${\rm stepSize}^{-n}\f$ for each axis.
+            Also, the above standard deviations
+            are scaled according to the step size of each axis.
+            Default value for the options object if this member function is not
+            used: A value of 1.0 for each dimension.
+        */
+    ConvolutionOptions<dim> & stepSize(...);
+#endif
+
+    // Resolution standard deviation per axis.
+    // Default: dim values of 0.0
+    VIGRA_CONVOLUTION_OPTIONS(resolutionStdDev, 0.0, sigma_d)
+#ifdef DOXYGEN
+        /** Resolution standard deviation(s) per axis, i.e., a supposed
+            pre-existing gaussian filtering by this value.
+       
+            The standard deviation actually used by the convolution operators
+            is \f$\sqrt{{\rm sigma}^{2} - {\rm resolutionStdDev}^{2}}\f$ for each
+            axis.
+            Default value for the options object if this member function is not
+            used: A value of 0.0 for each dimension.
+        */
+    ConvolutionOptions<dim> & resolutionStdDev(...);
+#endif
+
+    // Standard deviation of scale space operators.
+    // Default: dim values of 0.0
+    VIGRA_CONVOLUTION_OPTIONS(stdDev, 0.0, sigma_eff)
+    VIGRA_CONVOLUTION_OPTIONS(innerScale, 0.0, sigma_eff)
+
+#ifdef DOXYGEN
+        /** Standard deviation(s) of scale space operators, or inner scale(s) for \ref structureTensorMultiArray().
+        
+            Usually not
+            needed, since a single value for all axes may be specified as a parameter
+            <tt>sigma</tt> to the call of
+            an convolution operator such as \ref gaussianGradientMultiArray(), and
+            anisotropic data requiring the use of the stepSize() member function.
+            Default value for the options object if this member function is not
+            used: A value of 0.0 for each dimension.
+        */
+    ConvolutionOptions<dim> & stdDev(...);
+
+        /** Standard deviation(s) of scale space operators, or inner scale(s) for \ref structureTensorMultiArray().
+        
+            Usually not
+            needed, since a single value for all axes may be specified as a parameter
+            <tt>sigma</tt> to the call of
+            an convolution operator such as \ref gaussianGradientMultiArray(), and
+            anisotropic data requiring the use of the stepSize() member function.
+            Default value for the options object if this member function is not
+            used: A value of 0.0 for each dimension.
+        */
+    ConvolutionOptions<dim> & innerScale(...);
+#endif
+
+    // Outer scale, for structure tensor.
+    // Default: dim values of 0.0
+    VIGRA_CONVOLUTION_OPTIONS(outerScale, 0.0, outer_scale)
+#ifdef DOXYGEN
+        /** Standard deviation(s) of the second convolution of the
+            structure tensor. 
+
+            Usually not needed, since a single value for
+            all axes may be specified as a parameter <tt>outerScale</tt> to
+            the call of \ref structureTensorMultiArray(), and
+            anisotropic data requiring the use of the stepSize() member
+            function.
+            Default value for the options object if this member function is not
+            used: A value of 0.0 for each dimension.
+        */
+    ConvolutionOptions<dim> & outerScale(...);
+#endif
+
+        /** Size of the filter window as a multiple of the scale parameter. 
+
+            This option is only used for Gaussian filters and their derivatives.
+            By default, the window size of a Gaussian filter is automatically 
+            determined such that the error resulting from restricting the 
+            infinitely large Gaussian function to a finite size is minimized. 
+            In particular, the window radius is determined as
+            <tt>radius = round(3.0 * sigma + 0.5 * order)</tt>, where 'order' is the 
+            desired derivative order. In some cases, it is desirable to trade off 
+            accuracy for speed, and this function can be used to request a smaller
+            window radius.
+            
+            Default: <tt>0.0</tt> (i.e. determine the window size automatically)
+        */
+    ConvolutionOptions<dim> & filterWindowSize(double ratio)
+    {
+        vigra_precondition(ratio >= 0.0,
+            "ConvolutionOptions::filterWindowSize(): ratio must not be negative.");
+        window_ratio = ratio;
+        return *this;
+    }
+
+        /** Restrict the filter to a subregion of the input array. 
+
+            This is useful for speeding up computations by ignoring irrelevant 
+            areas in the array. <b>Note:</b> It is assumed that the output array
+            of the convolution has the size given in this function.  Negative ROI 
+            boundaries are interpreted relative to the end of the respective dimension 
+            (i.e. <tt>if(to[k] < 0) to[k] += source.shape(k);</tt>).
+            
+            Default: <tt>from = Shape(), to = Shape()</tt> (i.e. use entire array)
+        */
+    ConvolutionOptions<dim> & subarray(Shape const & from, Shape const & to)
+    {
+        from_point = from;
+        to_point = to;
+        return *this;
+    }
+};
+
+namespace detail
+{
+
+/********************************************************/
+/*                                                      */
+/*        internalSeparableConvolveMultiArray           */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class KernelIterator>
+void
+internalSeparableConvolveMultiArrayTmp(
+                      SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                      DestIterator di, DestAccessor dest, KernelIterator kit)
+{
+    enum { N = 1 + SrcIterator::level };
+
+    typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
+    typedef typename AccessorTraits<TmpType>::default_accessor TmpAcessor;
+
+    // temporary array to hold the current line to enable in-place operation
+    ArrayVector<TmpType> tmp( shape[0] );
+
+    typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
+    typedef MultiArrayNavigator<DestIterator, N> DNavigator;
+    
+    TmpAcessor acc;
+
+    {
+        // only operate on first dimension here
+        SNavigator snav( si, shape, 0 );
+        DNavigator dnav( di, shape, 0 );
+        
+        for( ; snav.hasMore(); snav++, dnav++ )
+        {
+             // first copy source to tmp for maximum cache efficiency
+             copyLine(snav.begin(), snav.end(), src, tmp.begin(), acc);
+
+             convolveLine(srcIterRange(tmp.begin(), tmp.end(), acc),
+                          destIter( dnav.begin(), dest ),
+                          kernel1d( *kit ) );
+        }
+        ++kit;
+    }
+
+    // operate on further dimensions
+    for( int d = 1; d < N; ++d, ++kit )
+    {
+        DNavigator dnav( di, shape, d );
+
+        tmp.resize( shape[d] );
+
+        for( ; dnav.hasMore(); dnav++ )
+        {
+             // first copy source to tmp since convolveLine() cannot work in-place
+             copyLine(dnav.begin(), dnav.end(), dest, tmp.begin(), acc);
+
+             convolveLine(srcIterRange(tmp.begin(), tmp.end(), acc),
+                          destIter( dnav.begin(), dest ),
+                          kernel1d( *kit ) );
+        }
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*         internalSeparableConvolveSubarray            */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class KernelIterator>
+void
+internalSeparableConvolveSubarray(
+                      SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                      DestIterator di, DestAccessor dest, KernelIterator kit,
+                      SrcShape const & start, SrcShape const & stop)
+{
+    enum { N = 1 + SrcIterator::level };
+
+    typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
+    typedef MultiArray<N, TmpType> TmpArray;
+    typedef typename TmpArray::traverser TmpIterator;
+    typedef typename AccessorTraits<TmpType>::default_accessor TmpAcessor;
+    
+    SrcShape sstart, sstop, axisorder, tmpshape;
+    TinyVector<double, N> overhead;
+    for(int k=0; k<N; ++k)
+    {
+        sstart[k] = start[k] - kit[k].right();
+        if(sstart[k] < 0)
+            sstart[k] = 0;
+        sstop[k] = stop[k] - kit[k].left();
+        if(sstop[k] > shape[k])
+            sstop[k] = shape[k];
+        overhead[k] = double(sstop[k] - sstart[k]) / (stop[k] - start[k]);
+    }
+    
+    indexSort(overhead.begin(), overhead.end(), axisorder.begin(), std::greater<double>());
+    
+    SrcShape dstart, dstop(sstop - sstart);
+    dstop[axisorder[0]]  = stop[axisorder[0]] - start[axisorder[0]];
+    
+    // temporary array to hold the current line to enable in-place operation
+    MultiArray<N, TmpType> tmp(dstop);
+
+    typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
+    typedef MultiArrayNavigator<TmpIterator, N> TNavigator;
+    
+    TmpAcessor acc;
+
+    {
+        // only operate on first dimension here
+        SNavigator snav( si, sstart, sstop, axisorder[0]);
+        TNavigator tnav( tmp.traverser_begin(), dstart, dstop, axisorder[0]);
+        
+        ArrayVector<TmpType> tmpline(sstop[axisorder[0]] - sstart[axisorder[0]]);
+        
+        int lstart = start[axisorder[0]] - sstart[axisorder[0]];
+        int lstop  = lstart + (stop[axisorder[0]] - start[axisorder[0]]);
+
+        for( ; snav.hasMore(); snav++, tnav++ )
+        {
+            // first copy source to tmp for maximum cache efficiency
+            copyLine(snav.begin(), snav.end(), src, tmpline.begin(), acc);
+            
+            convolveLine(srcIterRange(tmpline.begin(), tmpline.end(), acc),
+                         destIter(tnav.begin(), acc),
+                         kernel1d( kit[axisorder[0]] ), lstart, lstop);
+        }
+    }
+    
+    // operate on further dimensions
+    for( int d = 1; d < N; ++d)
+    {
+        TNavigator tnav( tmp.traverser_begin(), dstart, dstop, axisorder[d]);
+        
+        ArrayVector<TmpType> tmpline(dstop[axisorder[d]] - dstart[axisorder[d]]);
+        
+        int lstart = start[axisorder[d]] - sstart[axisorder[d]];
+        int lstop  = lstart + (stop[axisorder[d]] - start[axisorder[d]]);
+
+        for( ; tnav.hasMore(); tnav++ )
+        {
+            // first copy source to tmp because convolveLine() cannot work in-place
+            copyLine(tnav.begin(), tnav.end(), acc, tmpline.begin(), acc );
+
+            convolveLine(srcIterRange(tmpline.begin(), tmpline.end(), acc),
+                         destIter( tnav.begin() + lstart, acc ),
+                         kernel1d( kit[axisorder[d]] ), lstart, lstop);
+        }
+        
+        dstart[axisorder[d]] = lstart;
+        dstop[axisorder[d]] = lstop;
+    }
+    
+    copyMultiArray(tmp.traverser_begin()+dstart, stop-start, acc, di, dest);              
+}
+
+
+template <class K>
+void 
+scaleKernel(K & kernel, double a)
+{
+    for(int i = kernel.left(); i <= kernel.right(); ++i)
+        kernel[i] = detail::RequiresExplicitCast<typename K::value_type>::cast(kernel[i] * a);
+}
+
+
+} // namespace detail
+
+/** \addtogroup MultiArrayConvolutionFilters Convolution filters for multi-dimensional arrays.
+
+    These functions realize a separable convolution on an arbitrary dimensional
+    array that is specified by iterators (compatible to \ref MultiIteratorPage)
+    and shape objects. It can therefore be applied to a wide range of data structures
+    (\ref vigra::MultiArrayView, \ref vigra::MultiArray etc.).
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*             separableConvolveMultiArray              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Separated convolution on multi-dimensional arrays.
+
+    This function computes a separated convolution on all dimensions
+    of the given multi-dimensional array. Both source and destination
+    arrays are represented by iterators, shape objects and accessors.
+    The destination array is required to already have the correct size.
+
+    There are two variants of this functions: one takes a single kernel
+    of type \ref vigra::Kernel1D which is then applied to all dimensions,
+    whereas the other requires an iterator referencing a sequence of
+    \ref vigra::Kernel1D objects, one for every dimension of the data.
+    Then the first kernel in this sequence is applied to the innermost
+    dimension (e.g. the x-axis of an image), while the last is applied to the
+    outermost dimension (e.g. the z-axis in a 3D image).
+
+    This function may work in-place, which means that <tt>source.data() == dest.data()</tt> is allowed.
+    A full-sized internal array is only allocated if working on the destination
+    array directly would cause round-off errors (i.e. if
+    <tt>typeid(typename NumericTraits<T2>::RealPromote) != typeid(T2)</tt>).
+    
+    If <tt>start</tt> and <tt>stop</tt> have non-default values, they must represent
+    a valid subarray of the input array. The convolution is then restricted to that 
+    subarray, and it is assumed that the output array only refers to the
+    subarray (i.e. <tt>dest.shape() == stop - start</tt>). Negative ROI boundaries are
+    interpreted relative to the end of the respective dimension 
+    (i.e. <tt>if(stop[k] < 0) stop[k] += source.shape(k);</tt>).
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        // apply each kernel from the sequence 'kernels' in turn
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2, 
+                  class KernelIterator>
+        void
+        separableConvolveMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                    MultiArrayView<N, T2, S2> dest, 
+                                    KernelIterator kernels,
+                                    typename MultiArrayShape<N>::type start = typename MultiArrayShape<N>::type(),
+                                    typename MultiArrayShape<N>::type stop  = typename MultiArrayShape<N>::type());
+
+        // apply the same kernel to all dimensions
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2, 
+                  class T>
+        void
+        separableConvolveMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                    MultiArrayView<N, T2, S2> dest,
+                                    Kernel1D<T> const & kernel,
+                                    typename MultiArrayShape<N>::type const & start = typename MultiArrayShape<N>::type(),
+                                    typename MultiArrayShape<N>::type const & stop = typename MultiArrayShape<N>::type());
+    }
+    \endcode
+
+    \deprecatedAPI{separableConvolveMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // apply the same kernel to all dimensions
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class T>
+        void
+        separableConvolveMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                    DestIterator diter, DestAccessor dest,
+                                    Kernel1D<T> const & kernel,
+                                    SrcShape const & start = SrcShape(),
+                                    SrcShape const & stop = SrcShape());
+
+        // apply each kernel from the sequence 'kernels' in turn
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class KernelIterator>
+        void
+        separableConvolveMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                    DestIterator diter, DestAccessor dest,
+                                    KernelIterator kernels,
+                                    SrcShape const & start = SrcShape(),
+                                    SrcShape const & stop = SrcShape());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // apply the same kernel to all dimensions
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class T>
+        void
+        separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                    pair<DestIterator, DestAccessor> const & dest,
+                                    Kernel1D<T> const & kernel,
+                                    SrcShape const & start = SrcShape(),
+                                    SrcShape const & stop = SrcShape());
+
+        // apply each kernel from the sequence 'kernels' in turn
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class KernelIterator>
+        void
+        separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                    pair<DestIterator, DestAccessor> const & dest,
+                                    KernelIterator kernels,
+                                    SrcShape const & start = SrcShape(),
+                                    SrcShape const & stop = SrcShape());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, float>         dest(shape);
+    ...
+    Kernel1D<float> gauss;
+    gauss.initGaussian(sigma);
+
+    // smooth all dimensions with the same kernel
+    separableConvolveMultiArray(source, dest, gauss);
+    
+    // create 3 Gauss kernels, one for each dimension, but smooth the z-axis less
+    ArrayVector<Kernel1D<float> > kernels(3, gauss);
+    kernels[2].initGaussian(sigma / 2.0);
+
+    // perform Gaussian smoothing on all dimensions
+    separableConvolveMultiArray(source, dest, kernels.begin());
+    
+    // create output array for a ROI
+    MultiArray<3, float> destROI(shape - Shape3(10,10,10));
+     
+    // only smooth the given ROI (ignore 5 pixels on all sides of the array)
+    separableConvolveMultiArray(source, destROI, gauss, Shape3(5,5,5), Shape3(-5,-5,-5));
+    \endcode
+
+    \deprecatedUsage{separableConvolveMultiArray}
+    \code
+    MultiArray<3, unsigned char>::size_type shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, float> dest(shape);
+    ...
+    Kernel1D<float> gauss;
+    gauss.initGaussian(sigma);
+    // create 3 Gauss kernels, one for each dimension
+    ArrayVector<Kernel1D<float> > kernels(3, gauss);
+
+    // perform Gaussian smoothing on all dimensions
+    separableConvolveMultiArray(source, dest, 
+                                kernels.begin());
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    see \ref separableConvolveImage(), in addition:
+
+    NumericTraits<T1>::RealPromote s = src[0];
+
+    s = s + s;
+    s = kernel(0) * s;
+    \endcode
+    \deprecatedEnd
+
+    \see vigra::Kernel1D, convolveLine()
+*/
+doxygen_overloaded_function(template <...> void separableConvolveMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class KernelIterator>
+void
+separableConvolveMultiArray( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                             DestIterator d, DestAccessor dest, 
+                             KernelIterator kernels,
+                             SrcShape start = SrcShape(),
+                             SrcShape stop = SrcShape())
+{
+    typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
+
+
+    if(stop != SrcShape())
+    {
+        
+        enum { N = 1 + SrcIterator::level };
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(shape, start);
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(shape, stop);
+        
+        for(int k=0; k<N; ++k)
+            vigra_precondition(0 <= start[k] && start[k] < stop[k] && stop[k] <= shape[k],
+              "separableConvolveMultiArray(): invalid subarray shape.");
+
+        detail::internalSeparableConvolveSubarray(s, shape, src, d, dest, kernels, start, stop);
+    }
+    else if(!IsSameType<TmpType, typename DestAccessor::value_type>::boolResult)
+    {
+        // need a temporary array to avoid rounding errors
+        MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
+        detail::internalSeparableConvolveMultiArrayTmp( s, shape, src,
+             tmpArray.traverser_begin(), typename AccessorTraits<TmpType>::default_accessor(), kernels );
+        copyMultiArray(srcMultiArrayRange(tmpArray), destIter(d, dest));
+    }
+    else
+    {
+        // work directly on the destination array
+        detail::internalSeparableConvolveMultiArrayTmp( s, shape, src, d, dest, kernels );
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class T>
+inline void
+separableConvolveMultiArray( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                             DestIterator d, DestAccessor dest,
+                             Kernel1D<T> const & kernel,
+                             SrcShape const & start = SrcShape(),
+                             SrcShape const & stop = SrcShape())
+{
+    ArrayVector<Kernel1D<T> > kernels(shape.size(), kernel);
+
+    separableConvolveMultiArray( s, shape, src, d, dest, kernels.begin(), start, stop);
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class KernelIterator>
+inline void
+separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                            pair<DestIterator, DestAccessor> const & dest, 
+                            KernelIterator kit,
+                            SrcShape const & start = SrcShape(),
+                            SrcShape const & stop = SrcShape())
+{
+    separableConvolveMultiArray( source.first, source.second, source.third,
+                                 dest.first, dest.second, kit, start, stop );
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class T>
+inline void
+separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                            pair<DestIterator, DestAccessor> const & dest,
+                            Kernel1D<T> const & kernel,
+                            SrcShape const & start = SrcShape(),
+                            SrcShape const & stop = SrcShape())
+{
+    ArrayVector<Kernel1D<T> > kernels(source.second.size(), kernel);
+
+    separableConvolveMultiArray( source.first, source.second, source.third,
+                                 dest.first, dest.second, kernels.begin(), start, stop);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2, 
+          class KernelIterator>
+inline void
+separableConvolveMultiArray(MultiArrayView<N, T1, S1> const & source,
+                            MultiArrayView<N, T2, S2> dest, 
+                            KernelIterator kit,
+                            typename MultiArrayShape<N>::type start = typename MultiArrayShape<N>::type(),
+                            typename MultiArrayShape<N>::type stop = typename MultiArrayShape<N>::type())
+{
+    if(stop != typename MultiArrayShape<N>::type())
+    {
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), start);
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), stop);
+        vigra_precondition(dest.shape() == (stop - start),
+            "separableConvolveMultiArray(): shape mismatch between ROI and output.");
+    }
+    else
+    {
+        vigra_precondition(source.shape() == dest.shape(),
+            "separableConvolveMultiArray(): shape mismatch between input and output.");
+    }
+    separableConvolveMultiArray( srcMultiArrayRange(source),
+                                 destMultiArray(dest), kit, start, stop );
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2, 
+          class T>
+inline void
+separableConvolveMultiArray(MultiArrayView<N, T1, S1> const & source,
+                            MultiArrayView<N, T2, S2> dest,
+                            Kernel1D<T> const & kernel,
+                            typename MultiArrayShape<N>::type const & start = typename MultiArrayShape<N>::type(),
+                            typename MultiArrayShape<N>::type const & stop = typename MultiArrayShape<N>::type())
+{
+    ArrayVector<Kernel1D<T> > kernels(N, kernel);
+    separableConvolveMultiArray(source, dest, kernels.begin(), start, stop);
+}
+
+/********************************************************/
+/*                                                      */
+/*            convolveMultiArrayOneDimension            */
+/*                                                      */
+/********************************************************/
+
+/** \brief Convolution along a single dimension of a multi-dimensional arrays.
+
+    This function computes a convolution along one dimension (specified by
+    the parameter <tt>dim</tt> of the given multi-dimensional array with the given
+    <tt>kernel</tt>. The destination array must already have the correct size.
+
+    If <tt>start</tt> and <tt>stop</tt> have non-default values, they must represent
+    a valid subarray of the input array. The convolution is then restricted to that 
+    subarray, and it is assumed that the output array only refers to the
+    subarray (i.e. <tt>dest.shape() == stop - start</tt>). Negative ROI boundaries are
+    interpreted relative to the end of the respective dimension 
+    (i.e. <tt>if(stop[k] < 0) stop[k] += source.shape(k);</tt>).
+
+    This function may work in-place, which means that <tt>source.data() == dest.data()</tt> is allowed.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2, 
+                  class T>
+        void
+        convolveMultiArrayOneDimension(MultiArrayView<N, T1, S1> const & source,
+                                       MultiArrayView<N, T2, S2> dest,
+                                       unsigned int dim, 
+                                       Kernel1D<T> const & kernel,
+                                       typename MultiArrayShape<N>::type start = typename MultiArrayShape<N>::type(),
+                                       typename MultiArrayShape<N>::type stop  = typename MultiArrayShape<N>::type());
+    }
+    \endcode
+
+    \deprecatedAPI{convolveMultiArrayOneDimension}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class T>
+        void
+        convolveMultiArrayOneDimension(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                       DestIterator diter, DestAccessor dest,
+                                       unsigned int dim, vigra::Kernel1D<T> const & kernel,
+                                       SrcShape const & start = SrcShape(),
+                                       SrcShape const & stop = SrcShape());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class T>
+        void
+        convolveMultiArrayOneDimension(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                       pair<DestIterator, DestAccessor> const & dest,
+                                       unsigned int dim, vigra::Kernel1D<T> const & kernel,
+                                       SrcShape const & start = SrcShape(),
+                                       SrcShape const & stop = SrcShape());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, float> dest(shape);
+    ...
+    Kernel1D<float> gauss;
+    gauss.initGaussian(sigma);
+
+    // perform Gaussian smoothing along dimension 1 (height)
+    convolveMultiArrayOneDimension(source, dest, 1, gauss);
+    \endcode
+
+    \see separableConvolveMultiArray()
+*/
+doxygen_overloaded_function(template <...> void convolveMultiArrayOneDimension)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class T>
+void
+convolveMultiArrayOneDimension(SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                               DestIterator d, DestAccessor dest,
+                               unsigned int dim, vigra::Kernel1D<T> const & kernel,
+                               SrcShape const & start = SrcShape(),
+                               SrcShape const & stop = SrcShape())
+{
+    enum { N = 1 + SrcIterator::level };
+    vigra_precondition( dim < N,
+                        "convolveMultiArrayOneDimension(): The dimension number to convolve must be smaller "
+                        "than the data dimensionality" );
+
+    typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
+    typedef typename AccessorTraits<TmpType>::default_const_accessor TmpAccessor;
+    ArrayVector<TmpType> tmp( shape[dim] );
+
+    typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
+    typedef MultiArrayNavigator<DestIterator, N> DNavigator;
+    
+    SrcShape sstart, sstop(shape), dstart, dstop(shape);
+    
+    if(stop != SrcShape())
+    {
+        sstart = start;
+        sstop  = stop;
+        sstart[dim] = 0;
+        sstop[dim]  = shape[dim];
+        dstop = stop - start;
+    }
+
+    SNavigator snav( s, sstart, sstop, dim );
+    DNavigator dnav( d, dstart, dstop, dim );
+
+    for( ; snav.hasMore(); snav++, dnav++ )
+    {
+        // first copy source to temp for maximum cache efficiency
+        copyLine(snav.begin(), snav.end(), src,
+                 tmp.begin(), typename AccessorTraits<TmpType>::default_accessor() );
+
+        convolveLine(srcIterRange( tmp.begin(), tmp.end(), TmpAccessor()),
+                     destIter( dnav.begin(), dest ),
+                     kernel1d( kernel), start[dim], stop[dim]);
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class T>
+inline void
+convolveMultiArrayOneDimension(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                               pair<DestIterator, DestAccessor> const & dest,
+                               unsigned int dim,
+                               Kernel1D<T> const & kernel,
+                               SrcShape const & start = SrcShape(),
+                               SrcShape const & stop = SrcShape())
+{
+    convolveMultiArrayOneDimension(source.first, source.second, source.third,
+                                   dest.first, dest.second, dim, kernel, start, stop);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2, 
+          class T>
+inline void
+convolveMultiArrayOneDimension(MultiArrayView<N, T1, S1> const & source,
+                               MultiArrayView<N, T2, S2> dest,
+                               unsigned int dim, 
+                               Kernel1D<T> const & kernel,
+                               typename MultiArrayShape<N>::type start = typename MultiArrayShape<N>::type(),
+                               typename MultiArrayShape<N>::type stop = typename MultiArrayShape<N>::type())
+{
+    if(stop != typename MultiArrayShape<N>::type())
+    {
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), start);
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), stop);
+        vigra_precondition(dest.shape() == (stop - start),
+            "convolveMultiArrayOneDimension(): shape mismatch between ROI and output.");
+    }
+    else
+    {
+        vigra_precondition(source.shape() == dest.shape(),
+            "convolveMultiArrayOneDimension(): shape mismatch between input and output.");
+    }
+    convolveMultiArrayOneDimension(srcMultiArrayRange(source),
+                                   destMultiArray(dest), dim, kernel, start, stop);
+}
+
+/********************************************************/
+/*                                                      */
+/*             gaussianSmoothMultiArray                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Isotropic Gaussian smoothing of a multi-dimensional arrays.
+
+    This function computes an isotropic convolution of the given N-dimensional
+    array with a Gaussian filter at the given standard deviation <tt>sigma</tt>.
+    Both source and destination arrays are represented by
+    iterators, shape objects and accessors. The destination array is required to
+    already have the correct size. This function may work in-place, which means
+    that <tt>source.data() == dest.data()</tt> is allowed. It is implemented by a call to
+    \ref separableConvolveMultiArray() with the appropriate kernel.
+
+    Anisotropic data should be passed with appropriate
+    \ref ConvolutionOptions, the parameter <tt>opt</tt> is otherwise optional
+    unless the parameter <tt>sigma</tt> is omitted.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        // pass filter scale explicitly
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        gaussianSmoothMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                 MultiArrayView<N, T2, S2> dest,
+                                 double sigma,
+                                 ConvolutionOptions<N> opt = ConvolutionOptions<N>());
+
+        // pass filer scale(s) in the option object
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        gaussianSmoothMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                 MultiArrayView<N, T2, S2> dest,
+                                 ConvolutionOptions<N> opt);
+    }
+    \endcode
+
+    \deprecatedAPI{gaussianSmoothMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        gaussianSmoothMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                 DestIterator diter, DestAccessor dest,
+                                 double sigma,
+                                 const ConvolutionOptions<N> & opt = ConvolutionOptions<N>());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        gaussianSmoothMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                 pair<DestIterator, DestAccessor> const & dest,
+                                 double sigma,
+                                 const ConvolutionOptions<N> & opt = ConvolutionOptions<N>());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, float>         dest(shape);
+    ...
+    // perform isotropic Gaussian smoothing at scale 'sigma'
+    gaussianSmoothMultiArray(source, dest, sigma);
+    \endcode
+
+    <b> Usage with anisotropic data:</b>
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, float>         dest(shape);
+    TinyVector<float, 3> step_size;
+    TinyVector<float, 3> resolution_sigmas;
+    ...
+    // perform anisotropic Gaussian smoothing at scale 'sigma'
+    gaussianSmoothMultiArray(source, dest, sigma,
+                             ConvolutionOptions<3>().stepSize(step_size).resolutionStdDev(resolution_sigmas));
+    \endcode
+
+    \see separableConvolveMultiArray()
+*/
+doxygen_overloaded_function(template <...> void gaussianSmoothMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+gaussianSmoothMultiArray( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                   DestIterator d, DestAccessor dest,
+                   const ConvolutionOptions<SrcShape::static_size> & opt,
+                   const char *const function_name = "gaussianSmoothMultiArray" )
+{
+    static const int N = SrcShape::static_size;
+
+    typename ConvolutionOptions<N>::ScaleIterator params = opt.scaleParams();
+    ArrayVector<Kernel1D<double> > kernels(N);
+
+    for (int dim = 0; dim < N; ++dim, ++params)
+        kernels[dim].initGaussian(params.sigma_scaled(function_name), 1.0, opt.window_ratio);
+
+    separableConvolveMultiArray(s, shape, src, d, dest, kernels.begin(), opt.from_point, opt.to_point);
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+gaussianSmoothMultiArray( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                   DestIterator d, DestAccessor dest, double sigma,
+                   const ConvolutionOptions<SrcShape::static_size> & opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    ConvolutionOptions<SrcShape::static_size> par = opt;
+    gaussianSmoothMultiArray(s, shape, src, d,  dest, par.stdDev(sigma));
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+gaussianSmoothMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                         pair<DestIterator, DestAccessor> const & dest,
+                         const ConvolutionOptions<SrcShape::static_size> & opt)
+{
+    gaussianSmoothMultiArray( source.first, source.second, source.third,
+                              dest.first, dest.second, opt );
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+gaussianSmoothMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                         pair<DestIterator, DestAccessor> const & dest, double sigma,
+                         const ConvolutionOptions<SrcShape::static_size> & opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    gaussianSmoothMultiArray( source.first, source.second, source.third,
+                              dest.first, dest.second, sigma, opt );
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+gaussianSmoothMultiArray(MultiArrayView<N, T1, S1> const & source,
+                         MultiArrayView<N, T2, S2> dest,
+                         ConvolutionOptions<N> opt)
+{
+    if(opt.to_point != typename MultiArrayShape<N>::type())
+    {
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.from_point);
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.to_point);
+        vigra_precondition(dest.shape() == (opt.to_point - opt.from_point),
+            "gaussianSmoothMultiArray(): shape mismatch between ROI and output.");
+    }
+    else
+    {
+        vigra_precondition(source.shape() == dest.shape(),
+            "gaussianSmoothMultiArray(): shape mismatch between input and output.");
+    }
+
+    gaussianSmoothMultiArray( srcMultiArrayRange(source),
+                              destMultiArray(dest), opt );
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+gaussianSmoothMultiArray(MultiArrayView<N, T1, S1> const & source,
+                         MultiArrayView<N, T2, S2> dest,
+                         double sigma,
+                         ConvolutionOptions<N> opt = ConvolutionOptions<N>())
+{
+    gaussianSmoothMultiArray( source, dest, opt.stdDev(sigma) );
+}
+
+
+/********************************************************/
+/*                                                      */
+/*             gaussianGradientMultiArray               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate Gaussian gradient of a multi-dimensional arrays.
+
+    This function computes the Gaussian gradient of the given N-dimensional
+    array with a sequence of first-derivative-of-Gaussian filters at the given
+    standard deviation <tt>sigma</tt> (differentiation is applied to each dimension
+    in turn, starting with the innermost dimension). The destination array is
+    required to have a vector valued pixel type with as many elements as the number of
+    dimensions. This function is implemented by calls to
+    \ref separableConvolveMultiArray() with the appropriate kernels.
+
+    Anisotropic data should be passed with appropriate
+    \ref ConvolutionOptions, the parameter <tt>opt</tt> is otherwise optional
+    unless the parameter <tt>sigma</tt> is omitted.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        // pass filter scale explicitly
+        template <unsigned int N, class T1, class S1,
+                  class T2, class S2>
+        void
+        gaussianGradientMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                   MultiArrayView<N, TinyVector<T2, N>, S2> dest,
+                                   double sigma,
+                                   ConvolutionOptions<N> opt = ConvolutionOptions<N>());
+
+        // pass filter scale(s) in option object
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        gaussianGradientMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                   MultiArrayView<N, TinyVector<T2, N>, S2> dest,
+                                   ConvolutionOptions<N> opt);
+    }
+    \endcode
+
+    \deprecatedAPI{gaussianGradientMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        gaussianGradientMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                   DestIterator diter, DestAccessor dest,
+                                   double sigma, 
+                                   const ConvolutionOptions<N> & opt = ConvolutionOptions<N>());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        gaussianGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                   pair<DestIterator, DestAccessor> const & dest,
+                                   double sigma,
+                                   const ConvolutionOptions<N> & opt = ConvolutionOptions<N>());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, TinyVector<float, 3> > dest(shape);
+    ...
+    // compute Gaussian gradient at scale sigma
+    gaussianGradientMultiArray(source, dest, sigma);
+    \endcode
+
+    <b> Usage with anisotropic data:</b>
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, TinyVector<float, 3> > dest(shape);
+    TinyVector<float, 3> step_size;
+    TinyVector<float, 3> resolution_sigmas;
+    ...
+    // compute Gaussian gradient at scale sigma
+    gaussianGradientMultiArray(source, dest, sigma,
+                               ConvolutionOptions<3>().stepSize(step_size).resolutionStdDev(resolution_sigmas));
+    \endcode
+
+    \see separableConvolveMultiArray()
+*/
+doxygen_overloaded_function(template <...> void gaussianGradientMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+gaussianGradientMultiArray(SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                           DestIterator di, DestAccessor dest,
+                           ConvolutionOptions<SrcShape::static_size> const & opt,
+                           const char *const function_name = "gaussianGradientMultiArray")
+{
+    typedef typename DestAccessor::value_type DestType;
+    typedef typename DestType::value_type     DestValueType;
+    typedef typename NumericTraits<DestValueType>::RealPromote KernelType;
+   
+    static const int N = SrcShape::static_size;
+    typedef typename ConvolutionOptions<N>::ScaleIterator ParamType;
+
+    for(int k=0; k<N; ++k)
+        if(shape[k] <=0)
+            return;
+
+    vigra_precondition(N == (int)dest.size(di),
+        "gaussianGradientMultiArray(): Wrong number of channels in output array.");
+
+    ParamType params = opt.scaleParams();
+    ParamType params2(params);
+
+    ArrayVector<Kernel1D<KernelType> > plain_kernels(N);
+    for (int dim = 0; dim < N; ++dim, ++params)
+    {
+        double sigma = params.sigma_scaled(function_name);
+        plain_kernels[dim].initGaussian(sigma, 1.0, opt.window_ratio);
+    }
+
+    typedef VectorElementAccessor<DestAccessor> ElementAccessor;
+
+    // compute gradient components
+    for (int dim = 0; dim < N; ++dim, ++params2)
+    {
+        ArrayVector<Kernel1D<KernelType> > kernels(plain_kernels);
+        kernels[dim].initGaussianDerivative(params2.sigma_scaled(), 1, 1.0, opt.window_ratio);
+        detail::scaleKernel(kernels[dim], 1.0 / params2.step_size());
+        separableConvolveMultiArray(si, shape, src, di, ElementAccessor(dim, dest), kernels.begin(), 
+                                    opt.from_point, opt.to_point);
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+gaussianGradientMultiArray(SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                           DestIterator di, DestAccessor dest, double sigma,
+                           ConvolutionOptions<SrcShape::static_size> opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    gaussianGradientMultiArray(si, shape, src, di, dest, opt.stdDev(sigma));
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+gaussianGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                           pair<DestIterator, DestAccessor> const & dest,
+                           ConvolutionOptions<SrcShape::static_size> const & opt )
+{
+    gaussianGradientMultiArray( source.first, source.second, source.third,
+                                dest.first, dest.second, opt );
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+gaussianGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                           pair<DestIterator, DestAccessor> const & dest,
+                           double sigma,
+                           const ConvolutionOptions<SrcShape::static_size> & opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    gaussianGradientMultiArray( source.first, source.second, source.third,
+                                dest.first, dest.second, sigma, opt );
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+gaussianGradientMultiArray(MultiArrayView<N, T1, S1> const & source,
+                           MultiArrayView<N, TinyVector<T2, N>, S2> dest,
+                           ConvolutionOptions<N> opt )
+{
+    if(opt.to_point != typename MultiArrayShape<N>::type())
+    {
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.from_point);
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.to_point);
+        vigra_precondition(dest.shape() == (opt.to_point - opt.from_point),
+            "gaussianGradientMultiArray(): shape mismatch between ROI and output.");
+    }
+    else
+    {
+        vigra_precondition(source.shape() == dest.shape(),
+            "gaussianGradientMultiArray(): shape mismatch between input and output.");
+    }
+
+    gaussianGradientMultiArray( srcMultiArrayRange(source),
+                                destMultiArray(dest), opt );
+}
+
+template <unsigned int N, class T1, class S1,
+          class T2, class S2>
+inline void
+gaussianGradientMultiArray(MultiArrayView<N, T1, S1> const & source,
+                           MultiArrayView<N, TinyVector<T2, N>, S2> dest,
+                           double sigma,
+                           ConvolutionOptions<N> opt = ConvolutionOptions<N>())
+{
+    gaussianGradientMultiArray( source, dest, opt.stdDev(sigma) );
+}
+
+/********************************************************/
+/*                                                      */
+/*              gaussianGradientMagnitude               */
+/*                                                      */
+/********************************************************/
+
+namespace detail {
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+void 
+gaussianGradientMagnitudeImpl(MultiArrayView<N+1, T1, S1> const & src,
+                              MultiArrayView<N, T2, S2> dest,
+                              ConvolutionOptions<N> opt = ConvolutionOptions<N>())
+{
+    typename MultiArrayShape<N>::type shape(src.shape().template subarray<0,N>());
+    if(opt.to_point != typename MultiArrayShape<N>::type())
+    {
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(shape, opt.from_point);
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(shape, opt.to_point);
+        vigra_precondition(dest.shape() == (opt.to_point - opt.from_point),
+            "gaussianGradientMagnitude(): shape mismatch between ROI and output.");
+    }
+    else
+    {
+        vigra_precondition(shape == dest.shape(),
+            "gaussianGradientMagnitude(): shape mismatch between input and output.");
+    }
+              
+    dest.init(0.0);
+    
+    typedef typename NumericTraits<T1>::RealPromote TmpType;
+    MultiArray<N, TinyVector<TmpType, N> > grad(dest.shape());
+    
+    using namespace multi_math;
+    
+    for(int k=0; k<src.shape(N); ++k)
+    {
+        gaussianGradientMultiArray(src.bindOuter(k), grad, opt);
+        
+        dest += squaredNorm(grad);
+    }
+    dest = sqrt(dest);
+}
+
+} // namespace detail
+
+    // documentation is in convolution.hxx
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void 
+gaussianGradientMagnitude(MultiArrayView<N+1, Multiband<T1>, S1> const & src,
+                          MultiArrayView<N, T2, S2> dest,
+                          ConvolutionOptions<N> const & opt)
+{
+    detail::gaussianGradientMagnitudeImpl<N, T1>(src, dest, opt);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void 
+gaussianGradientMagnitude(MultiArrayView<N, T1, S1> const & src,
+                          MultiArrayView<N, T2, S2> dest,
+                          ConvolutionOptions<N> const & opt)
+{
+    detail::gaussianGradientMagnitudeImpl<N, T1>(src.insertSingletonDimension(N), dest, opt);
+}
+
+template <unsigned int N, class T1, int M, class S1,
+                          class T2, class S2>
+inline void 
+gaussianGradientMagnitude(MultiArrayView<N, TinyVector<T1, M>, S1> const & src,
+                          MultiArrayView<N, T2, S2> dest,
+                          ConvolutionOptions<N> const & opt)
+{
+    detail::gaussianGradientMagnitudeImpl<N, T1>(src.expandElements(N), dest, opt);
+}
+
+template <unsigned int N, class T1, unsigned int R, unsigned int G, unsigned int B, class S1,
+                          class T2, class S2>
+inline void 
+gaussianGradientMagnitude(MultiArrayView<N, RGBValue<T1, R, G, B>, S1> const & src,
+                          MultiArrayView<N, T2, S2> dest,
+                          ConvolutionOptions<N> const & opt)
+{
+    detail::gaussianGradientMagnitudeImpl<N, T1>(src.expandElements(N), dest, opt);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void 
+gaussianGradientMagnitude(MultiArrayView<N, T1, S1> const & src,
+                          MultiArrayView<N, T2, S2> dest,
+                          double sigma,
+                          ConvolutionOptions<N> opt = ConvolutionOptions<N>())
+{
+    gaussianGradientMagnitude(src, dest, opt.stdDev(sigma));
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void 
+gaussianGradientMagnitude(MultiArrayView<N+1, Multiband<T1>, S1> const & src,
+                          MultiArrayView<N, T2, S2> dest,
+                          double sigma,
+                          ConvolutionOptions<N> opt = ConvolutionOptions<N>())
+{
+    gaussianGradientMagnitude<N>(src, dest, opt.stdDev(sigma));
+}
+
+/********************************************************/
+/*                                                      */
+/*             symmetricGradientMultiArray              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate gradient of a multi-dimensional arrays using symmetric difference filters.
+
+    This function computes the gradient of the given N-dimensional
+    array with a sequence of symmetric difference filters a (differentiation is applied
+    to each dimension in turn, starting with the innermost dimension). 
+    The destination array is required to have a vector valued pixel type with as many
+    elements as the number of dimensions. This function is implemented by calls to
+    \ref convolveMultiArrayOneDimension() with the symmetric difference kernel.
+
+    Anisotropic data should be passed with appropriate
+    \ref ConvolutionOptions, the parameter <tt>opt</tt> is optional
+    otherwise.
+    
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        symmetricGradientMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                    MultiArrayView<N, TinyVector<T2, N>, S2> dest,
+                                    ConvolutionOptions<N> opt = ConvolutionOptions<N>());
+    }
+    \endcode
+
+    \deprecatedAPI{symmetricGradientMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        symmetricGradientMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                    DestIterator diter, DestAccessor dest,
+                                    const ConvolutionOptions<N> & opt = ConvolutionOptions<N>());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        symmetricGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                    pair<DestIterator, DestAccessor> const & dest,
+                                    const ConvolutionOptions<N> & opt = ConvolutionOptions<N>());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<3, unsigned char>::size_type shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, TinyVector<float, 3> > dest(shape);
+    ...
+    // compute gradient
+    symmetricGradientMultiArray(srcMultiArrayRange(source), destMultiArray(dest));
+    \endcode
+
+    <b> Usage with anisotropic data:</b>
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, TinyVector<float, 3> > dest(shape);
+    TinyVector<float, 3> step_size;
+    ...
+    // compute gradient
+    symmetricGradientMultiArray(source, dest,
+                                ConvolutionOptions<3>().stepSize(step_size));
+    \endcode
+
+    \see convolveMultiArrayOneDimension()
+*/
+doxygen_overloaded_function(template <...> void symmetricGradientMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+symmetricGradientMultiArray(SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                            DestIterator di, DestAccessor dest,
+                            const ConvolutionOptions<SrcShape::static_size> & opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    typedef typename DestAccessor::value_type DestType;
+    typedef typename DestType::value_type     DestValueType;
+    typedef typename NumericTraits<DestValueType>::RealPromote KernelType;
+
+    static const int N = SrcShape::static_size;
+    typedef typename ConvolutionOptions<N>::StepIterator StepType;
+
+    for(int k=0; k<N; ++k)
+        if(shape[k] <=0)
+            return;
+
+    vigra_precondition(N == (int)dest.size(di),
+        "symmetricGradientMultiArray(): Wrong number of channels in output array.");
+
+    Kernel1D<KernelType> filter;
+    filter.initSymmetricDifference();
+
+    StepType step_size_it = opt.stepParams();
+
+    typedef VectorElementAccessor<DestAccessor> ElementAccessor;
+
+    // compute gradient components
+    for (int d = 0; d < N; ++d, ++step_size_it)
+    {
+        Kernel1D<KernelType> symmetric(filter);
+        detail::scaleKernel(symmetric, 1 / *step_size_it);
+        convolveMultiArrayOneDimension(si, shape, src,
+                                       di, ElementAccessor(d, dest),
+                                       d, symmetric, opt.from_point, opt.to_point);
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+symmetricGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                            pair<DestIterator, DestAccessor> const & dest,
+                            const ConvolutionOptions<SrcShape::static_size> & opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    symmetricGradientMultiArray(source.first, source.second, source.third,
+                                dest.first, dest.second, opt);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+symmetricGradientMultiArray(MultiArrayView<N, T1, S1> const & source,
+                            MultiArrayView<N, TinyVector<T2, N>, S2> dest,
+                            ConvolutionOptions<N> opt = ConvolutionOptions<N>())
+{
+    if(opt.to_point != typename MultiArrayShape<N>::type())
+    {
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.from_point);
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.to_point);
+        vigra_precondition(dest.shape() == (opt.to_point - opt.from_point),
+            "symmetricGradientMultiArray(): shape mismatch between ROI and output.");
+    }
+    else
+    {
+        vigra_precondition(source.shape() == dest.shape(),
+            "symmetricGradientMultiArray(): shape mismatch between input and output.");
+    }
+
+    symmetricGradientMultiArray(srcMultiArrayRange(source),
+                                destMultiArray(dest), opt);
+}
+
+/********************************************************/
+/*                                                      */
+/*            laplacianOfGaussianMultiArray             */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate Laplacian of a N-dimensional arrays using Gaussian derivative filters.
+
+    This function computes the Laplacian of the given N-dimensional
+    array with a sequence of second-derivative-of-Gaussian filters at the given
+    standard deviation <tt>sigma</tt>. Both source and destination 
+    arrays must have scalar value_type. This function is implemented by calls to
+    \ref separableConvolveMultiArray() with the appropriate kernels, followed by summation.
+
+    Anisotropic data should be passed with appropriate
+    \ref ConvolutionOptions, the parameter <tt>opt</tt> is otherwise optional
+    unless the parameter <tt>sigma</tt> is left out.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        // pass scale explicitly
+        template <unsigned int N, class T1, class S1,
+                  class T2, class S2>
+        void
+        laplacianOfGaussianMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                      MultiArrayView<N, T2, S2> dest,
+                                      double sigma,
+                                      ConvolutionOptions<N> opt = ConvolutionOptions<N>());
+        
+        // pass scale(s) in option object
+        template <unsigned int N, class T1, class S1,
+                  class T2, class S2>
+        void
+        laplacianOfGaussianMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                      MultiArrayView<N, T2, S2> dest,
+                                      ConvolutionOptions<N> opt );
+    }
+    \endcode
+
+    \deprecatedAPI{laplacianOfGaussianMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        laplacianOfGaussianMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                      DestIterator diter, DestAccessor dest,
+                                      double sigma,
+                                      const ConvolutionOptions<N> & opt = ConvolutionOptions<N>());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        laplacianOfGaussianMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                      pair<DestIterator, DestAccessor> const & dest,
+                                      double sigma,
+                                      const ConvolutionOptions<N> & opt = ConvolutionOptions<N>());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, float> source(shape);
+    MultiArray<3, float> laplacian(shape);
+    ...
+    // compute Laplacian at scale sigma
+    laplacianOfGaussianMultiArray(source, laplacian, sigma);
+    \endcode
+
+    <b> Usage with anisotropic data:</b>
+
+    \code
+    MultiArray<3, float> source(shape);
+    MultiArray<3, float> laplacian(shape);
+    TinyVector<float, 3> step_size;
+    TinyVector<float, 3> resolution_sigmas;
+    ...
+    // compute Laplacian at scale sigma
+    laplacianOfGaussianMultiArray(source, laplacian, sigma,
+                                  ConvolutionOptions<3>().stepSize(step_size).resolutionStdDev(resolution_sigmas));
+    \endcode
+
+    \see separableConvolveMultiArray()
+*/
+doxygen_overloaded_function(template <...> void laplacianOfGaussianMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+laplacianOfGaussianMultiArray(SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                              DestIterator di, DestAccessor dest,
+                              ConvolutionOptions<SrcShape::static_size> const & opt )
+{ 
+    using namespace functor;
+    
+    typedef typename DestAccessor::value_type DestType;
+    typedef typename NumericTraits<DestType>::RealPromote KernelType;
+    typedef typename AccessorTraits<KernelType>::default_accessor DerivativeAccessor;
+
+    static const int N = SrcShape::static_size;
+    typedef typename ConvolutionOptions<N>::ScaleIterator ParamType;
+    
+    ParamType params = opt.scaleParams();
+    ParamType params2(params);
+
+    ArrayVector<Kernel1D<KernelType> > plain_kernels(N);
+    for (int dim = 0; dim < N; ++dim, ++params)
+    {
+        double sigma = params.sigma_scaled("laplacianOfGaussianMultiArray");
+        plain_kernels[dim].initGaussian(sigma, 1.0, opt.window_ratio);
+    }
+    
+    SrcShape dshape(shape);
+    if(opt.to_point != SrcShape())
+        dshape = opt.to_point - opt.from_point;
+    
+    MultiArray<N, KernelType> derivative(dshape);
+
+    // compute 2nd derivatives and sum them up
+    for (int dim = 0; dim < N; ++dim, ++params2)
+    {
+        ArrayVector<Kernel1D<KernelType> > kernels(plain_kernels);
+        kernels[dim].initGaussianDerivative(params2.sigma_scaled(), 2, 1.0, opt.window_ratio);
+        detail::scaleKernel(kernels[dim], 1.0 / sq(params2.step_size()));
+
+        if (dim == 0)
+        {
+            separableConvolveMultiArray( si, shape, src, 
+                                         di, dest, kernels.begin(), opt.from_point, opt.to_point);
+        }
+        else
+        {
+            separableConvolveMultiArray( si, shape, src, 
+                                         derivative.traverser_begin(), DerivativeAccessor(), 
+                                         kernels.begin(), opt.from_point, opt.to_point);
+            combineTwoMultiArrays(di, dshape, dest, derivative.traverser_begin(), DerivativeAccessor(), 
+                                  di, dest, Arg1() + Arg2() );
+        }
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+laplacianOfGaussianMultiArray(SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                              DestIterator di, DestAccessor dest, double sigma,
+                              ConvolutionOptions<SrcShape::static_size> opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    laplacianOfGaussianMultiArray(si, shape, src, di, dest, opt.stdDev(sigma));
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+laplacianOfGaussianMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                              pair<DestIterator, DestAccessor> const & dest,
+                              ConvolutionOptions<SrcShape::static_size> const & opt )
+{
+    laplacianOfGaussianMultiArray( source.first, source.second, source.third,
+                                   dest.first, dest.second, opt );
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+laplacianOfGaussianMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                              pair<DestIterator, DestAccessor> const & dest,
+                              double sigma,
+                              const ConvolutionOptions<SrcShape::static_size> & opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    laplacianOfGaussianMultiArray( source.first, source.second, source.third,
+                                   dest.first, dest.second,  sigma, opt );
+}
+
+template <unsigned int N, class T1, class S1,
+          class T2, class S2>
+inline void
+laplacianOfGaussianMultiArray(MultiArrayView<N, T1, S1> const & source,
+                              MultiArrayView<N, T2, S2> dest,
+                              ConvolutionOptions<N> opt )
+{
+    if(opt.to_point != typename MultiArrayShape<N>::type())
+    {
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.from_point);
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.to_point);
+        vigra_precondition(dest.shape() == (opt.to_point - opt.from_point),
+            "laplacianOfGaussianMultiArray(): shape mismatch between ROI and output.");
+    }
+    else
+    {
+        vigra_precondition(source.shape() == dest.shape(),
+            "laplacianOfGaussianMultiArray(): shape mismatch between input and output.");
+    }
+
+    laplacianOfGaussianMultiArray( srcMultiArrayRange(source),
+                                   destMultiArray(dest), opt );
+}
+
+template <unsigned int N, class T1, class S1,
+          class T2, class S2>
+inline void
+laplacianOfGaussianMultiArray(MultiArrayView<N, T1, S1> const & source,
+                              MultiArrayView<N, T2, S2> dest,
+                              double sigma,
+                              ConvolutionOptions<N> opt = ConvolutionOptions<N>())
+{
+    laplacianOfGaussianMultiArray( source, dest, opt.stdDev(sigma) );
+}
+
+/********************************************************/
+/*                                                      */
+/*             gaussianDivergenceMultiArray             */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the divergence of a vector field using Gaussian derivative filters.
+
+    This function computes the divergence of the given N-dimensional vector field
+    with a sequence of first-derivative-of-Gaussian filters at the given
+    standard deviation <tt>sigma</tt>. The input vector field can either be given as a sequence
+    of scalar array views (one for each vector field component), represented by an
+    iterator range, or by a single vector array with the appropriate shape.
+    This function is implemented by calls to
+    \ref separableConvolveMultiArray() with the suitable kernels, followed by summation.
+
+    Anisotropic data should be passed with appropriate
+    \ref ConvolutionOptions, the parameter <tt>opt</tt> is otherwise optional
+    unless the parameter <tt>sigma</tt> is omitted.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        // specify input vector field as a sequence of scalar arrays
+        template <class Iterator, 
+                  unsigned int N, class T, class S>
+        void 
+        gaussianDivergenceMultiArray(Iterator vectorField, Iterator vectorFieldEnd,
+                                     MultiArrayView<N, T, S> divergence,
+                                     ConvolutionOptions<N> const & opt);
+        
+        template <class Iterator, 
+                  unsigned int N, class T, class S>
+        void 
+        gaussianDivergenceMultiArray(Iterator vectorField, Iterator vectorFieldEnd,
+                                     MultiArrayView<N, T, S> divergence,
+                                     double sigma,
+                                     ConvolutionOptions<N> opt = ConvolutionOptions<N>());
+        
+        // pass input vector field as an array of vectors
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void 
+        gaussianDivergenceMultiArray(MultiArrayView<N, TinyVector<T1, N>, S1> const & vectorField,
+                                     MultiArrayView<N, T2, S2> divergence,
+                                     ConvolutionOptions<N> const & opt);
+                                     
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void 
+        gaussianDivergenceMultiArray(MultiArrayView<N, TinyVector<T1, N>, S1> const & vectorField,
+                                     MultiArrayView<N, T2, S2> divergence,
+                                     double sigma,
+                                     ConvolutionOptions<N> opt = ConvolutionOptions<N>());
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, TinyVector<float, 3> > source(shape);
+    MultiArray<3, float> laplacian(shape);
+    ...
+    // compute divergence at scale sigma
+    gaussianDivergenceMultiArray(source, laplacian, sigma);
+    \endcode
+
+    <b> Usage with anisotropic data:</b>
+
+    \code
+    MultiArray<3, TinyVector<float, 3> > source(shape);
+    MultiArray<3, float> laplacian(shape);
+    TinyVector<float, 3> step_size;
+    TinyVector<float, 3> resolution_sigmas;
+    ...
+    // compute divergence at scale sigma
+    gaussianDivergenceMultiArray(source, laplacian, sigma,
+                                 ConvolutionOptions<3>().stepSize(step_size).resolutionStdDev(resolution_sigmas));
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void gaussianDivergenceMultiArray)
+
+template <class Iterator, 
+          unsigned int N, class T, class S>
+void 
+gaussianDivergenceMultiArray(Iterator vectorField, Iterator vectorFieldEnd,
+                             MultiArrayView<N, T, S> divergence,
+                             ConvolutionOptions<N> opt)
+{
+    typedef typename std::iterator_traits<Iterator>::value_type  ArrayType;
+    typedef typename ArrayType::value_type                       SrcType;
+    typedef typename NumericTraits<SrcType>::RealPromote         TmpType;
+    typedef Kernel1D<double>                                     Kernel;
+    
+    vigra_precondition(std::distance(vectorField, vectorFieldEnd) == N,
+        "gaussianDivergenceMultiArray(): wrong number of input arrays.");
+    // more checks are performed in separableConvolveMultiArray()
+    
+    typename ConvolutionOptions<N>::ScaleIterator params = opt.scaleParams();
+    ArrayVector<double> sigmas(N);
+    ArrayVector<Kernel> kernels(N);
+    for(unsigned int k = 0; k < N; ++k, ++params)
+    {
+        sigmas[k] = params.sigma_scaled("gaussianDivergenceMultiArray");
+        kernels[k].initGaussian(sigmas[k], 1.0, opt.window_ratio);
+    }
+    
+    MultiArray<N, TmpType> tmpDeriv(divergence.shape());
+    
+    for(unsigned int k=0; k < N; ++k, ++vectorField)
+    {
+        kernels[k].initGaussianDerivative(sigmas[k], 1, 1.0, opt.window_ratio);
+        if(k == 0)
+        {
+            separableConvolveMultiArray(*vectorField, divergence, kernels.begin(), opt.from_point, opt.to_point);
+        }
+        else
+        {
+            separableConvolveMultiArray(*vectorField, tmpDeriv, kernels.begin(), opt.from_point, opt.to_point);
+            divergence += tmpDeriv;
+        }
+        kernels[k].initGaussian(sigmas[k], 1.0, opt.window_ratio);
+    }
+}
+
+template <class Iterator, 
+          unsigned int N, class T, class S>
+inline void 
+gaussianDivergenceMultiArray(Iterator vectorField, Iterator vectorFieldEnd,
+                             MultiArrayView<N, T, S> divergence,
+                             double sigma,
+                             ConvolutionOptions<N> opt = ConvolutionOptions<N>())
+{
+    gaussianDivergenceMultiArray(vectorField, vectorFieldEnd, divergence, opt.stdDev(sigma));
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void 
+gaussianDivergenceMultiArray(MultiArrayView<N, TinyVector<T1, N>, S1> const & vectorField,
+                             MultiArrayView<N, T2, S2> divergence,
+                             ConvolutionOptions<N> const & opt)
+{
+    ArrayVector<MultiArrayView<N, T1> > field;
+    for(unsigned int k=0; k<N; ++k)
+        field.push_back(vectorField.bindElementChannel(k));
+
+    gaussianDivergenceMultiArray(field.begin(), field.end(), divergence, opt);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void 
+gaussianDivergenceMultiArray(MultiArrayView<N, TinyVector<T1, N>, S1> const & vectorField,
+                             MultiArrayView<N, T2, S2> divergence,
+                             double sigma,
+                             ConvolutionOptions<N> opt = ConvolutionOptions<N>())
+{
+    gaussianDivergenceMultiArray(vectorField, divergence, opt.stdDev(sigma));
+}
+
+/********************************************************/
+/*                                                      */
+/*              hessianOfGaussianMultiArray             */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate Hessian matrix of a N-dimensional arrays using Gaussian derivative filters.
+
+    This function computes the Hessian matrix the given scalar N-dimensional
+    array with a sequence of second-derivative-of-Gaussian filters at the given
+    standard deviation <tt>sigma</tt>. The destination array must 
+    have a vector valued element type with N*(N+1)/2 elements (it represents the
+    upper triangular part of the symmetric Hessian matrix, flattened row-wise). 
+    This function is implemented by calls to
+    \ref separableConvolveMultiArray() with the appropriate kernels.
+
+    Anisotropic data should be passed with appropriate
+    \ref ConvolutionOptions, the parameter <tt>opt</tt> is otherwise optional
+    unless the parameter <tt>sigma</tt> is omitted.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        // pass scale explicitly
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        hessianOfGaussianMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                    MultiArrayView<N, TinyVector<T2, int(N*(N+1)/2)>, S2> dest,
+                                    double sigma,
+                                    ConvolutionOptions<N> opt = ConvolutionOptions<N>());
+        
+        // pass scale(s) in option object
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        hessianOfGaussianMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                    MultiArrayView<N, TinyVector<T2, int(N*(N+1)/2)>, S2> dest,
+                                    ConvolutionOptions<N> opt);
+    }
+    \endcode
+
+    \deprecatedAPI{hessianOfGaussianMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        hessianOfGaussianMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                    DestIterator diter, DestAccessor dest,
+                                    double sigma,
+                                    const ConvolutionOptions<N> & opt = ConvolutionOptions<N>());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        hessianOfGaussianMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                    pair<DestIterator, DestAccessor> const & dest,
+                                    double sigma,
+                                    const ConvolutionOptions<N> & opt = ConvolutionOptions<N>());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, float> source(shape);
+    MultiArray<3, TinyVector<float, 6> > dest(shape);
+    ...
+    // compute Hessian at scale sigma
+    hessianOfGaussianMultiArray(source, dest, sigma);
+    \endcode
+
+    <b> Usage with anisotropic data:</b>
+
+    \code
+    MultiArray<3, float> source(shape);
+    MultiArray<3, TinyVector<float, 6> > dest(shape);
+    TinyVector<float, 3> step_size;
+    TinyVector<float, 3> resolution_sigmas;
+    ...
+    // compute Hessian at scale sigma
+    hessianOfGaussianMultiArray(source, dest, sigma,
+                                ConvolutionOptions<3>().stepSize(step_size).resolutionStdDev(resolution_sigmas));
+    \endcode
+
+    \see separableConvolveMultiArray(), vectorToTensorMultiArray()
+*/
+doxygen_overloaded_function(template <...> void hessianOfGaussianMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+hessianOfGaussianMultiArray(SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                            DestIterator di, DestAccessor dest,
+                            ConvolutionOptions<SrcShape::static_size> const & opt )
+{ 
+    typedef typename DestAccessor::value_type DestType;
+    typedef typename DestType::value_type     DestValueType;
+    typedef typename NumericTraits<DestValueType>::RealPromote KernelType;
+
+    static const int N = SrcShape::static_size;
+    static const int M = N*(N+1)/2;
+    typedef typename ConvolutionOptions<N>::ScaleIterator ParamType;
+    
+    for(int k=0; k<N; ++k)
+        if(shape[k] <=0)
+            return;
+
+    vigra_precondition(M == (int)dest.size(di),
+        "hessianOfGaussianMultiArray(): Wrong number of channels in output array.");
+
+    ParamType params_init = opt.scaleParams();
+
+    ArrayVector<Kernel1D<KernelType> > plain_kernels(N);
+    ParamType params(params_init);
+    for (int dim = 0; dim < N; ++dim, ++params)
+    {
+        double sigma = params.sigma_scaled("hessianOfGaussianMultiArray");
+        plain_kernels[dim].initGaussian(sigma, 1.0, opt.window_ratio);
+    }
+
+    typedef VectorElementAccessor<DestAccessor> ElementAccessor;
+
+    // compute elements of the Hessian matrix
+    ParamType params_i(params_init);
+    for (int b=0, i=0; i<N; ++i, ++params_i)
+    {
+        ParamType params_j(params_i);
+        for (int j=i; j<N; ++j, ++b, ++params_j)
+        {
+            ArrayVector<Kernel1D<KernelType> > kernels(plain_kernels);
+            if(i == j)
+            {
+                kernels[i].initGaussianDerivative(params_i.sigma_scaled(), 2, 1.0, opt.window_ratio);
+            }
+            else
+            {
+                kernels[i].initGaussianDerivative(params_i.sigma_scaled(), 1, 1.0, opt.window_ratio);
+                kernels[j].initGaussianDerivative(params_j.sigma_scaled(), 1, 1.0, opt.window_ratio);
+            }
+            detail::scaleKernel(kernels[i], 1 / params_i.step_size());
+            detail::scaleKernel(kernels[j], 1 / params_j.step_size());
+            separableConvolveMultiArray(si, shape, src, di, ElementAccessor(b, dest),
+                                        kernels.begin(), opt.from_point, opt.to_point);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+hessianOfGaussianMultiArray(SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                            DestIterator di, DestAccessor dest, double sigma,
+                            ConvolutionOptions<SrcShape::static_size> opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    hessianOfGaussianMultiArray(si, shape, src, di, dest, opt.stdDev(sigma));
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+hessianOfGaussianMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                            pair<DestIterator, DestAccessor> const & dest,
+                            ConvolutionOptions<SrcShape::static_size> const & opt )
+{
+    hessianOfGaussianMultiArray( source.first, source.second, source.third,
+                                 dest.first, dest.second, opt );
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+hessianOfGaussianMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                            pair<DestIterator, DestAccessor> const & dest,
+                            double sigma,
+                            const ConvolutionOptions<SrcShape::static_size> & opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    hessianOfGaussianMultiArray( source.first, source.second, source.third,
+                                 dest.first, dest.second, sigma, opt );
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+hessianOfGaussianMultiArray(MultiArrayView<N, T1, S1> const & source,
+                            MultiArrayView<N, TinyVector<T2, int(N*(N+1)/2)>, S2> dest,
+                            ConvolutionOptions<N> opt )
+{
+    if(opt.to_point != typename MultiArrayShape<N>::type())
+    {
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.from_point);
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.to_point);
+        vigra_precondition(dest.shape() == (opt.to_point - opt.from_point),
+            "hessianOfGaussianMultiArray(): shape mismatch between ROI and output.");
+    }
+    else
+    {
+        vigra_precondition(source.shape() == dest.shape(),
+            "hessianOfGaussianMultiArray(): shape mismatch between input and output.");
+    }
+
+    hessianOfGaussianMultiArray( srcMultiArrayRange(source),
+                                 destMultiArray(dest), opt );
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+hessianOfGaussianMultiArray(MultiArrayView<N, T1, S1> const & source,
+                            MultiArrayView<N, TinyVector<T2, int(N*(N+1)/2)>, S2> dest,
+                            double sigma,
+                            ConvolutionOptions<N> opt = ConvolutionOptions<N>())
+{
+    hessianOfGaussianMultiArray( source, dest, opt.stdDev(sigma) );
+}
+
+namespace detail {
+
+template<int N, class VectorType>
+struct StructurTensorFunctor
+{
+    typedef VectorType result_type;
+    typedef typename VectorType::value_type ValueType;
+    
+    template <class T>
+    VectorType operator()(T const & in) const
+    {
+        VectorType res;
+        for(int b=0, i=0; i<N; ++i)
+        {
+            for(int j=i; j<N; ++j, ++b)
+            {
+                res[b] = detail::RequiresExplicitCast<ValueType>::cast(in[i]*in[j]);
+            }
+        }
+        return res;
+    }
+};
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*               structureTensorMultiArray              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate th structure tensor of a multi-dimensional arrays.
+
+    This function computes the gradient (outer product) tensor for each element
+    of the given N-dimensional array with first-derivative-of-Gaussian filters at 
+    the given <tt>innerScale</tt>, followed by Gaussian smoothing at <tt>outerScale</tt>.
+    The destination array must have a vector valued pixel type with 
+    N*(N+1)/2 elements (it represents the upper triangular part of the symmetric 
+    structure tensor matrix, flattened row-wise). If the source array is also vector valued, the 
+    resulting structure tensor is the sum of the individual tensors for each channel.
+    This function is implemented by calls to
+    \ref separableConvolveMultiArray() with the appropriate kernels.
+
+    Anisotropic data should be passed with appropriate
+    \ref ConvolutionOptions, the parameter <tt>opt</tt> is otherwise optional
+    unless the parameters <tt>innerScale</tt> and <tt>outerScale</tt> are
+    both omitted.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        // pass scales explicitly
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        structureTensorMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                  MultiArrayView<N, TinyVector<T2, int(N*(N+1)/2)>, S2> dest,
+                                  double innerScale, double outerScale,
+                                  ConvolutionOptions<N> opt = ConvolutionOptions<N>());
+        
+        // pass scales in option object
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        structureTensorMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                  MultiArrayView<N, TinyVector<T2, int(N*(N+1)/2)>, S2> dest, 
+                                  ConvolutionOptions<N> opt );
+    }
+    \endcode
+
+    \deprecatedAPI{structureTensorMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        structureTensorMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                  DestIterator diter, DestAccessor dest,
+                                  double innerScale, double outerScale,
+                                  ConvolutionOptions<N> opt);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        structureTensorMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                  pair<DestIterator, DestAccessor> const & dest,
+                                  double innerScale, double outerScale,
+                                  const ConvolutionOptions<N> & opt);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, RGBValue<float> > source(shape);
+    MultiArray<3, TinyVector<float, 6> > dest(shape);
+    ...
+    // compute structure tensor at scales innerScale and outerScale
+    structureTensorMultiArray(source, dest, innerScale, outerScale);
+    \endcode
+
+    <b> Usage with anisotropic data:</b>
+
+    \code
+    MultiArray<3, RGBValue<float> > source(shape);
+    MultiArray<3, TinyVector<float, 6> > dest(shape);
+    TinyVector<float, 3> step_size;
+    TinyVector<float, 3> resolution_sigmas;
+    ...
+    // compute structure tensor at scales innerScale and outerScale
+    structureTensorMultiArray(source, dest, innerScale, outerScale,
+                              ConvolutionOptions<3>().stepSize(step_size).resolutionStdDev(resolution_sigmas));
+    \endcode
+
+    \see separableConvolveMultiArray(), vectorToTensorMultiArray()
+*/
+doxygen_overloaded_function(template <...> void structureTensorMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+structureTensorMultiArray(SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                          DestIterator di, DestAccessor dest, 
+                          ConvolutionOptions<SrcShape::static_size> opt)
+{
+    static const int N = SrcShape::static_size;
+    static const int M = N*(N+1)/2;
+    
+    typedef typename DestAccessor::value_type DestType;
+    typedef typename DestType::value_type     DestValueType;
+    typedef typename NumericTraits<DestValueType>::RealPromote KernelType;
+    typedef TinyVector<KernelType, N> GradientVector;
+    typedef typename AccessorTraits<GradientVector>::default_accessor GradientAccessor;
+    typedef typename AccessorTraits<DestType>::default_accessor GradientTensorAccessor;
+
+    for(int k=0; k<N; ++k)
+        if(shape[k] <=0)
+            return;
+
+    vigra_precondition(M == (int)dest.size(di),
+        "structureTensorMultiArray(): Wrong number of channels in output array.");
+        
+    ConvolutionOptions<N> innerOptions = opt;
+    ConvolutionOptions<N> outerOptions = opt.outerOptions();
+    typename ConvolutionOptions<N>::ScaleIterator params = outerOptions.scaleParams();
+    
+    SrcShape gradientShape(shape);
+    if(opt.to_point != SrcShape())
+    {
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(shape, opt.from_point);
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(shape, opt.to_point);
+        
+        for(int k=0; k<N; ++k, ++params)
+        {
+            Kernel1D<double> gauss;
+            gauss.initGaussian(params.sigma_scaled("structureTensorMultiArray"), 1.0, opt.window_ratio);
+            int dilation = gauss.right();
+            innerOptions.from_point[k] = std::max<MultiArrayIndex>(0, opt.from_point[k] - dilation);
+            innerOptions.to_point[k] = std::min<MultiArrayIndex>(shape[k], opt.to_point[k] + dilation);
+        }
+        outerOptions.from_point -= innerOptions.from_point;
+        outerOptions.to_point -= innerOptions.from_point;
+        gradientShape = innerOptions.to_point - innerOptions.from_point;
+    }
+
+    MultiArray<N, GradientVector> gradient(gradientShape);
+    MultiArray<N, DestType> gradientTensor(gradientShape);
+    gaussianGradientMultiArray(si, shape, src, 
+                               gradient.traverser_begin(), GradientAccessor(), 
+                               innerOptions,
+                               "structureTensorMultiArray");
+
+    transformMultiArray(gradient.traverser_begin(), gradientShape, GradientAccessor(), 
+                        gradientTensor.traverser_begin(), GradientTensorAccessor(), 
+                        detail::StructurTensorFunctor<N, DestType>());
+
+    gaussianSmoothMultiArray(gradientTensor.traverser_begin(), gradientShape, GradientTensorAccessor(), 
+                             di, dest, outerOptions,
+                             "structureTensorMultiArray");
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+structureTensorMultiArray(SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                          DestIterator di, DestAccessor dest,
+                          double innerScale, double outerScale,
+                          ConvolutionOptions<SrcShape::static_size> opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    structureTensorMultiArray(si, shape, src, di, dest,
+                              opt.stdDev(innerScale).outerScale(outerScale));
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+structureTensorMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                          pair<DestIterator, DestAccessor> const & dest, 
+                          ConvolutionOptions<SrcShape::static_size> const & opt )
+{
+    structureTensorMultiArray( source.first, source.second, source.third,
+                               dest.first, dest.second, opt );
+}
+
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+structureTensorMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                          pair<DestIterator, DestAccessor> const & dest,
+                          double innerScale, double outerScale,
+                          const ConvolutionOptions<SrcShape::static_size> & opt = ConvolutionOptions<SrcShape::static_size>())
+{
+    structureTensorMultiArray( source.first, source.second, source.third,
+                               dest.first, dest.second,
+                               innerScale, outerScale, opt);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+structureTensorMultiArray(MultiArrayView<N, T1, S1> const & source,
+                          MultiArrayView<N, TinyVector<T2, int(N*(N+1)/2)>, S2> dest, 
+                          ConvolutionOptions<N> opt )
+{
+    if(opt.to_point != typename MultiArrayShape<N>::type())
+    {
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.from_point);
+        detail::RelativeToAbsoluteCoordinate<N-1>::exec(source.shape(), opt.to_point);
+        vigra_precondition(dest.shape() == (opt.to_point - opt.from_point),
+            "structureTensorMultiArray(): shape mismatch between ROI and output.");
+    }
+    else
+    {
+        vigra_precondition(source.shape() == dest.shape(),
+            "structureTensorMultiArray(): shape mismatch between input and output.");
+    }
+
+    structureTensorMultiArray( srcMultiArrayRange(source),
+                               destMultiArray(dest), opt );
+}
+
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+structureTensorMultiArray(MultiArrayView<N, T1, S1> const & source,
+                          MultiArrayView<N, TinyVector<T2, int(N*(N+1)/2)>, S2> dest,
+                          double innerScale, double outerScale,
+                          ConvolutionOptions<N> opt = ConvolutionOptions<N>())
+{
+    structureTensorMultiArray(source, dest, opt.innerScale(innerScale).outerScale(outerScale));
+}
+
+//@}
+
+} //-- namespace vigra
+
+
+#endif        //-- VIGRA_MULTI_CONVOLUTION_H
diff --git a/include/vigra/multi_distance.hxx b/include/vigra/multi_distance.hxx
new file mode 100644
index 0000000..8482be7
--- /dev/null
+++ b/include/vigra/multi_distance.hxx
@@ -0,0 +1,665 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2003-2007 by Kasim Terzic, Christian-Dennis Rahn       */
+/*                        and Ullrich Koethe                            */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_DISTANCE_HXX
+#define VIGRA_MULTI_DISTANCE_HXX
+
+#include <vector>
+#include <functional>
+#include "array_vector.hxx"
+#include "multi_array.hxx"
+#include "accessor.hxx"
+#include "numerictraits.hxx"
+#include "navigator.hxx"
+#include "metaprogramming.hxx"
+#include "multi_pointoperators.hxx"
+#include "functorexpression.hxx"
+
+namespace vigra
+{
+
+namespace detail
+{
+
+template <class Value>
+struct DistParabolaStackEntry
+{
+    double left, center, right;
+    Value prevVal;
+    
+    DistParabolaStackEntry(Value const & p, double l, double c, double r)
+    : left(l), center(c), right(r), prevVal(p)
+    {}
+};
+
+/********************************************************/
+/*                                                      */
+/*                distParabola                          */
+/*                                                      */
+/*  Version with sigma (parabola spread) for morphology */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor >
+void distParabola(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                  DestIterator id, DestAccessor da, double sigma )
+{
+    // We assume that the data in the input is distance squared and treat it as such
+    double w = iend - is;
+    if(w <= 0)
+        return;
+        
+    double sigma2 = sigma * sigma;
+    double sigma22 = 2.0 * sigma2;
+    
+    typedef typename SrcAccessor::value_type SrcType;
+    typedef DistParabolaStackEntry<SrcType> Influence;
+    std::vector<Influence> _stack;
+    _stack.push_back(Influence(sa(is), 0.0, 0.0, w));
+    
+    ++is;
+    double current = 1.0;
+    while(current < w )
+    {
+        Influence & s = _stack.back();
+        double diff = current - s.center;
+        double intersection = current + (sa(is) - s.prevVal - sigma2*sq(diff)) / (sigma22 * diff);
+        
+        if( intersection < s.left) // previous point has no influence
+        {
+            _stack.pop_back();
+            if(_stack.empty())
+            {
+                _stack.push_back(Influence(sa(is), 0.0, current, w));
+            }
+            else
+            {
+                continue; // try new top of stack without advancing current
+            }
+        }
+        else if(intersection < s.right)
+        {
+            s.right = intersection;
+            _stack.push_back(Influence(sa(is), intersection, current, w));
+        }
+        ++is;
+        ++current;
+    }
+
+    // Now we have the stack indicating which rows are influenced by (and therefore
+    // closest to) which row. We can go through the stack and calculate the
+    // distance squared for each element of the column.
+    typename std::vector<Influence>::iterator it = _stack.begin();
+    for(current = 0.0; current < w; ++current, ++id)
+    {
+        while( current >= it->right) 
+            ++it; 
+        da.set(sigma2 * sq(current - it->center) + it->prevVal, id);
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void distParabola(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                         pair<DestIterator, DestAccessor> dest, double sigma)
+{
+    distParabola(src.first, src.second, src.third,
+                 dest.first, dest.second, sigma);
+}
+
+/********************************************************/
+/*                                                      */
+/*        internalSeparableMultiArrayDistTmp            */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class Array>
+void internalSeparableMultiArrayDistTmp(
+                      SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                      DestIterator di, DestAccessor dest, Array const & sigmas, bool invert)
+{
+    // Sigma is the spread of the parabolas. It determines the structuring element size
+    // for ND morphology. When calculating the distance transforms, sigma is usually set to 1,
+    // unless one wants to account for anisotropic pixel pitch
+    enum { N =  SrcShape::static_size};
+
+    // we need the Promote type here if we want to invert the image (dilation)
+    typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
+    
+    // temporary array to hold the current line to enable in-place operation
+    ArrayVector<TmpType> tmp( shape[0] );
+
+    typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
+    typedef MultiArrayNavigator<DestIterator, N> DNavigator;
+    
+    
+    // only operate on first dimension here
+    SNavigator snav( si, shape, 0 );
+    DNavigator dnav( di, shape, 0 );
+
+    using namespace vigra::functor;
+
+    for( ; snav.hasMore(); snav++, dnav++ )
+    {
+            // first copy source to temp for maximum cache efficiency
+            // Invert the values if necessary. Only needed for grayscale morphology
+            if(invert)
+                transformLine( snav.begin(), snav.end(), src, tmp.begin(),
+                               typename AccessorTraits<TmpType>::default_accessor(), 
+                               Param(NumericTraits<TmpType>::zero())-Arg1());
+            else
+                copyLine( snav.begin(), snav.end(), src, tmp.begin(),
+                          typename AccessorTraits<TmpType>::default_accessor() );
+
+            detail::distParabola( srcIterRange(tmp.begin(), tmp.end(),
+                          typename AccessorTraits<TmpType>::default_const_accessor()),
+                          destIter( dnav.begin(), dest ), sigmas[0] );
+    }
+    
+    // operate on further dimensions
+    for( int d = 1; d < N; ++d )
+    {
+        DNavigator dnav( di, shape, d );
+
+        tmp.resize( shape[d] );
+        
+
+        for( ; dnav.hasMore(); dnav++ )
+        {
+             // first copy source to temp for maximum cache efficiency
+             copyLine( dnav.begin(), dnav.end(), dest,
+                       tmp.begin(), typename AccessorTraits<TmpType>::default_accessor() );
+
+             detail::distParabola( srcIterRange(tmp.begin(), tmp.end(),
+                           typename AccessorTraits<TmpType>::default_const_accessor()),
+                           destIter( dnav.begin(), dest ), sigmas[d] );
+        }
+    }
+    if(invert) transformMultiArray( di, shape, dest, di, dest, -Arg1());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class Array>
+inline void internalSeparableMultiArrayDistTmp( SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                                                DestIterator di, DestAccessor dest, Array const & sigmas)
+{
+    internalSeparableMultiArrayDistTmp( si, shape, src, di, dest, sigmas, false );
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void internalSeparableMultiArrayDistTmp( SrcIterator si, SrcShape const & shape, SrcAccessor src,
+                                                DestIterator di, DestAccessor dest)
+{
+    ArrayVector<double> sigmas(shape.size(), 1.0);
+    internalSeparableMultiArrayDistTmp( si, shape, src, di, dest, sigmas, false );
+}
+
+} // namespace detail
+
+/** \addtogroup MultiArrayDistanceTransform Euclidean distance transform for multi-dimensional arrays.
+
+    These functions perform the Euclidean distance transform an arbitrary dimensional
+    array that is specified by iterators (compatible to \ref MultiIteratorPage)
+    and shape objects. It can therefore be applied to a wide range of data structures
+    (\ref vigra::MultiArrayView, \ref vigra::MultiArray etc.).
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*             separableMultiDistSquared                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Euclidean distance squared on multi-dimensional arrays.
+
+    The algorithm is taken from Donald Bailey: "An Efficient Euclidean Distance Transform",
+    Proc. IWCIA'04, Springer LNCS 3322, 2004.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        // explicitly specify pixel pitch for each coordinate
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2, 
+                  class Array>
+        void
+        separableMultiDistSquared(MultiArrayView<N, T1, S1> const & source,
+                                  MultiArrayView<N, T2, S2> dest,
+                                  bool background,
+                                  Array const & pixelPitch);
+
+        // use default pixel pitch = 1.0 for each coordinate
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        separableMultiDistSquared(MultiArrayView<N, T1, S1> const & source,
+                                  MultiArrayView<N, T2, S2> dest, 
+                                  bool background);
+    }
+    \endcode
+
+    \deprecatedAPI{separableMultiDistSquared}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // explicitly specify pixel pitch for each coordinate
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class Array>
+        void 
+        separableMultiDistSquared( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                                   DestIterator d, DestAccessor dest, 
+                                   bool background,
+                                   Array const & pixelPitch);
+                                        
+        // use default pixel pitch = 1.0 for each coordinate
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        separableMultiDistSquared(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                  DestIterator diter, DestAccessor dest, 
+                                  bool background);
+
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // explicitly specify pixel pitch for each coordinate
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class Array>
+        void 
+        separableMultiDistSquared( triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                   pair<DestIterator, DestAccessor> const & dest, 
+                                   bool background,
+                                   Array const & pixelPitch);
+                                               
+        // use default pixel pitch = 1.0 for each coordinate
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        separableMultiDistSquared(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                  pair<DestIterator, DestAccessor> const & dest,
+                                  bool background);
+
+    }
+    \endcode
+    \deprecatedEnd
+
+    This function performs a squared Euclidean squared distance transform on the given
+    multi-dimensional array. Both source and destination
+    arrays are represented by iterators, shape objects and accessors.
+    The destination array is required to already have the correct size.
+
+    This function expects a mask as its source, where background pixels are 
+    marked as zero, and non-background pixels as non-zero. If the parameter 
+    <i>background</i> is true, then the squared distance of all background
+    pixels to the nearest object is calculated. Otherwise, the distance of all
+    object pixels to the nearest background pixel is calculated.
+    
+    Optionally, one can pass an array that specifies the pixel pitch in each direction. 
+    This is necessary when the data have non-uniform resolution (as is common in confocal
+    microscopy, for example). 
+
+    This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
+    A full-sized internal array is only allocated if working on the destination
+    array directly would cause overflow errors (i.e. if
+    <tt> NumericTraits<typename DestAccessor::value_type>::max() < N * M*M</tt>, where M is the
+    size of the largest dimension of the array.
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_distance.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, unsigned int> dest(shape);
+    ...
+
+    // Calculate Euclidean distance squared for all background pixels 
+    separableMultiDistSquared(source, dest, true);
+    \endcode
+
+    \see vigra::distanceTransform(), vigra::separableMultiDistance()
+*/
+doxygen_overloaded_function(template <...> void separableMultiDistSquared)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class Array>
+void separableMultiDistSquared( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                                DestIterator d, DestAccessor dest, bool background,
+                                Array const & pixelPitch)
+{
+    int N = shape.size();
+
+    typedef typename SrcAccessor::value_type SrcType;
+    typedef typename DestAccessor::value_type DestType;
+    typedef typename NumericTraits<DestType>::RealPromote Real;
+
+    SrcType zero = NumericTraits<SrcType>::zero();
+
+    double dmax = 0.0;
+    bool pixelPitchIsReal = false;
+    for( int k=0; k<N; ++k)
+    {
+        if(int(pixelPitch[k]) != pixelPitch[k])
+            pixelPitchIsReal = true;
+        dmax += sq(pixelPitch[k]*shape[k]);
+    }
+            
+    using namespace vigra::functor;
+   
+    if(dmax > NumericTraits<DestType>::toRealPromote(NumericTraits<DestType>::max()) 
+       || pixelPitchIsReal) // need a temporary array to avoid overflows
+    {
+        // Threshold the values so all objects have infinity value in the beginning
+        Real maxDist = (Real)dmax, rzero = (Real)0.0;
+        MultiArray<SrcShape::static_size, Real> tmpArray(shape);
+        if(background == true)
+            transformMultiArray( s, shape, src, 
+                                 tmpArray.traverser_begin(), typename AccessorTraits<Real>::default_accessor(),
+                                 ifThenElse( Arg1() == Param(zero), Param(maxDist), Param(rzero) ));
+        else
+            transformMultiArray( s, shape, src, 
+                                 tmpArray.traverser_begin(), typename AccessorTraits<Real>::default_accessor(),
+                                 ifThenElse( Arg1() != Param(zero), Param(maxDist), Param(rzero) ));
+        
+        detail::internalSeparableMultiArrayDistTmp( tmpArray.traverser_begin(), 
+                shape, typename AccessorTraits<Real>::default_accessor(),
+                tmpArray.traverser_begin(), 
+                typename AccessorTraits<Real>::default_accessor(), pixelPitch);
+        
+        copyMultiArray(srcMultiArrayRange(tmpArray), destIter(d, dest));
+    }
+    else        // work directly on the destination array    
+    {
+        // Threshold the values so all objects have infinity value in the beginning
+        DestType maxDist = DestType(std::ceil(dmax)), rzero = (DestType)0;
+        if(background == true)
+            transformMultiArray( s, shape, src, d, dest,
+                                 ifThenElse( Arg1() == Param(zero), Param(maxDist), Param(rzero) ));
+        else
+            transformMultiArray( s, shape, src, d, dest, 
+                                 ifThenElse( Arg1() != Param(zero), Param(maxDist), Param(rzero) ));
+     
+        detail::internalSeparableMultiArrayDistTmp( d, shape, dest, d, dest, pixelPitch);
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline 
+void separableMultiDistSquared( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                                DestIterator d, DestAccessor dest, bool background)
+{
+    ArrayVector<double> pixelPitch(shape.size(), 1.0);
+    separableMultiDistSquared( s, shape, src, d, dest, background, pixelPitch );
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class Array>
+inline void separableMultiDistSquared( triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                       pair<DestIterator, DestAccessor> const & dest, bool background,
+                                       Array const & pixelPitch)
+{
+    separableMultiDistSquared( source.first, source.second, source.third,
+                               dest.first, dest.second, background, pixelPitch );
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void separableMultiDistSquared( triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                       pair<DestIterator, DestAccessor> const & dest, bool background)
+{
+    separableMultiDistSquared( source.first, source.second, source.third,
+                               dest.first, dest.second, background );
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2, 
+          class Array>
+inline void
+separableMultiDistSquared(MultiArrayView<N, T1, S1> const & source,
+                          MultiArrayView<N, T2, S2> dest, bool background,
+                          Array const & pixelPitch)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "separableMultiDistSquared(): shape mismatch between input and output.");
+    separableMultiDistSquared( srcMultiArrayRange(source),
+                               destMultiArray(dest), background, pixelPitch );
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+separableMultiDistSquared(MultiArrayView<N, T1, S1> const & source,
+                          MultiArrayView<N, T2, S2> dest, bool background)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "separableMultiDistSquared(): shape mismatch between input and output.");
+    separableMultiDistSquared( srcMultiArrayRange(source),
+                               destMultiArray(dest), background );
+}
+
+/********************************************************/
+/*                                                      */
+/*             separableMultiDistance                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Euclidean distance on multi-dimensional arrays.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        // explicitly specify pixel pitch for each coordinate
+        template <unsigned int N, class T1, class S1,
+                  class T2, class S2, class Array>
+        void 
+        separableMultiDistance(MultiArrayView<N, T1, S1> const & source,
+                               MultiArrayView<N, T2, S2> dest, 
+                               bool background,
+                               Array const & pixelPitch);
+
+        // use default pixel pitch = 1.0 for each coordinate
+        template <unsigned int N, class T1, class S1,
+                  class T2, class S2>
+        void 
+        separableMultiDistance(MultiArrayView<N, T1, S1> const & source,
+                               MultiArrayView<N, T2, S2> dest, 
+                               bool background);
+    }
+    \endcode
+
+    \deprecatedAPI{separableMultiDistance}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // explicitly specify pixel pitch for each coordinate
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class Array>
+        void 
+        separableMultiDistance( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                                DestIterator d, DestAccessor dest, 
+                                bool background,
+                                Array const & pixelPitch);
+                                        
+        // use default pixel pitch = 1.0 for each coordinate
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        separableMultiDistance(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                               DestIterator diter, DestAccessor dest, 
+                               bool background);
+
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // explicitly specify pixel pitch for each coordinate
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, class Array>
+        void 
+        separableMultiDistance( triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                pair<DestIterator, DestAccessor> const & dest, 
+                                bool background,
+                                Array const & pixelPitch);
+                                               
+        // use default pixel pitch = 1.0 for each coordinate
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        separableMultiDistance(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                               pair<DestIterator, DestAccessor> const & dest,
+                               bool background);
+
+    }
+    \endcode
+    \deprecatedEnd
+
+    This function performs a Euclidean distance transform on the given
+    multi-dimensional array. It simply calls \ref separableMultiDistSquared()
+    and takes the pixel-wise square root of the result. See \ref separableMultiDistSquared()
+    for more documentation.
+    
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_distance.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, float> dest(shape);
+    ...
+
+    // Calculate Euclidean distance squared for all background pixels 
+    separableMultiDistance(source, dest, true);
+    \endcode
+
+    \see vigra::distanceTransform(), vigra::separableMultiDistSquared()
+*/
+doxygen_overloaded_function(template <...> void separableMultiDistance)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class Array>
+void separableMultiDistance( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                             DestIterator d, DestAccessor dest, bool background,
+                             Array const & pixelPitch)
+{
+    separableMultiDistSquared( s, shape, src, d, dest, background, pixelPitch);
+    
+    // Finally, calculate the square root of the distances
+    using namespace vigra::functor;
+   
+    transformMultiArray( d, shape, dest, d, dest, sqrt(Arg1()) );
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void separableMultiDistance( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                             DestIterator d, DestAccessor dest, bool background)
+{
+    separableMultiDistSquared( s, shape, src, d, dest, background);
+    
+    // Finally, calculate the square root of the distances
+    using namespace vigra::functor;
+   
+    transformMultiArray( d, shape, dest, d, dest, sqrt(Arg1()) );
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class Array>
+inline void separableMultiDistance( triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                    pair<DestIterator, DestAccessor> const & dest, bool background,
+                                    Array const & pixelPitch)
+{
+    separableMultiDistance( source.first, source.second, source.third,
+                            dest.first, dest.second, background, pixelPitch );
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void separableMultiDistance( triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                    pair<DestIterator, DestAccessor> const & dest, bool background)
+{
+    separableMultiDistance( source.first, source.second, source.third,
+                            dest.first, dest.second, background );
+}
+
+template <unsigned int N, class T1, class S1,
+          class T2, class S2, class Array>
+inline void 
+separableMultiDistance(MultiArrayView<N, T1, S1> const & source,
+                       MultiArrayView<N, T2, S2> dest, 
+                       bool background,
+                       Array const & pixelPitch)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "separableMultiDistance(): shape mismatch between input and output.");
+    separableMultiDistance( srcMultiArrayRange(source),
+                            destMultiArray(dest), background, pixelPitch );
+}
+
+template <unsigned int N, class T1, class S1,
+          class T2, class S2>
+inline void 
+separableMultiDistance(MultiArrayView<N, T1, S1> const & source,
+                       MultiArrayView<N, T2, S2> dest, 
+                       bool background)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "separableMultiDistance(): shape mismatch between input and output.");
+    separableMultiDistance( srcMultiArrayRange(source),
+                            destMultiArray(dest), background );
+}
+
+//@}
+
+} //-- namespace vigra
+
+
+#endif        //-- VIGRA_MULTI_DISTANCE_HXX
diff --git a/include/vigra/multi_fft.hxx b/include/vigra/multi_fft.hxx
new file mode 100644
index 0000000..695fdef
--- /dev/null
+++ b/include/vigra/multi_fft.hxx
@@ -0,0 +1,2249 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2009-2010 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_FFT_HXX
+#define VIGRA_MULTI_FFT_HXX
+
+#include "fftw3.hxx"
+#include "multi_array.hxx"
+#include "navigator.hxx"
+#include "copyimage.hxx"
+
+namespace vigra {
+
+/********************************************************/
+/*                                                      */
+/*                    Fourier Transform                 */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup FourierTransform 
+*/
+//@{
+
+namespace detail {
+
+template <unsigned int N, class T, class C>
+void moveDCToCenterImpl(MultiArrayView<N, T, C> a, unsigned int startDimension)
+{
+    typedef typename MultiArrayView<N, T, C>::traverser Traverser;
+    typedef MultiArrayNavigator<Traverser, N> Navigator;
+    typedef typename Navigator::iterator Iterator;
+    
+    for(unsigned int d = startDimension; d < N; ++d)
+    {
+        Navigator nav(a.traverser_begin(), a.shape(), d);
+
+        for( ; nav.hasMore(); nav++ )
+        {
+            Iterator i = nav.begin();
+            int s  = nav.end() - i;
+            int s2 = s/2;
+                
+            if(even(s))
+            {
+                for(int k=0; k<s2; ++k)
+                {
+                    std::swap(i[k], i[k+s2]);
+                }
+            }
+            else            
+            {
+                T v = i[0];
+                for(int k=0; k<s2; ++k)
+                {
+                    i[k] = i[k+s2+1];
+                    i[k+s2+1] = i[k+1];
+                }
+                i[s2] = v;
+            }
+        }
+    }
+}
+
+template <unsigned int N, class T, class C>
+void moveDCToUpperLeftImpl(MultiArrayView<N, T, C> a, unsigned int startDimension)
+{
+    typedef typename MultiArrayView<N, T, C>::traverser Traverser;
+    typedef MultiArrayNavigator<Traverser, N> Navigator;
+    typedef typename Navigator::iterator Iterator;
+    
+    for(unsigned int d = startDimension; d < N; ++d)
+    {
+        Navigator nav(a.traverser_begin(), a.shape(), d);
+
+        for( ; nav.hasMore(); nav++ )
+        {
+            Iterator i = nav.begin();
+            int s  = nav.end() - i;
+            int s2 = s/2;
+            
+            if(even(s))
+            {
+                for(int k=0; k<s2; ++k)
+                {
+                    std::swap(i[k], i[k+s2]);
+                }
+            }
+            else            
+            {
+                T v = i[s2];
+                for(int k=s2; k>0; --k)
+                {
+                    i[k] = i[k+s2];
+                    i[k+s2] = i[k-1];
+                }
+                i[0] = v;
+            }
+        }
+    }
+}
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*                     moveDCToCenter                   */
+/*                                                      */
+/********************************************************/
+
+template <unsigned int N, class T, class C>
+inline void moveDCToCenter(MultiArrayView<N, T, C> a)
+{
+    detail::moveDCToCenterImpl(a, 0);
+}
+
+template <unsigned int N, class T, class C>
+inline void moveDCToUpperLeft(MultiArrayView<N, T, C> a)
+{
+    detail::moveDCToUpperLeftImpl(a, 0);
+}
+
+template <unsigned int N, class T, class C>
+inline void moveDCToHalfspaceCenter(MultiArrayView<N, T, C> a)
+{
+    detail::moveDCToCenterImpl(a, 1);
+}
+
+template <unsigned int N, class T, class C>
+inline void moveDCToHalfspaceUpperLeft(MultiArrayView<N, T, C> a)
+{
+    detail::moveDCToUpperLeftImpl(a, 1);
+}
+
+namespace detail
+{
+
+inline fftw_plan 
+fftwPlanCreate(unsigned int N, int* shape, 
+               FFTWComplex<double> * in,  int* instrides,  int instep,
+               FFTWComplex<double> * out, int* outstrides, int outstep,
+               int sign, unsigned int planner_flags)
+{
+    return fftw_plan_many_dft(N, shape, 1,
+                              (fftw_complex *)in, instrides, instep, 0,
+                              (fftw_complex *)out, outstrides, outstep, 0,
+                              sign, planner_flags);
+}
+
+inline fftw_plan 
+fftwPlanCreate(unsigned int N, int* shape, 
+               double * in,  int* instrides,  int instep,
+               FFTWComplex<double> * out, int* outstrides, int outstep,
+               int /*sign is ignored*/, unsigned int planner_flags)
+{
+    return fftw_plan_many_dft_r2c(N, shape, 1,
+                                   in, instrides, instep, 0,
+                                   (fftw_complex *)out, outstrides, outstep, 0,
+                                   planner_flags);
+}
+
+inline fftw_plan 
+fftwPlanCreate(unsigned int N, int* shape, 
+               FFTWComplex<double> * in,  int* instrides,  int instep,
+               double * out, int* outstrides, int outstep,
+               int /*sign is ignored*/, unsigned int planner_flags)
+{
+    return fftw_plan_many_dft_c2r(N, shape, 1,
+                                  (fftw_complex *)in, instrides, instep, 0,
+                                  out, outstrides, outstep, 0,
+                                  planner_flags);
+}
+
+inline fftwf_plan 
+fftwPlanCreate(unsigned int N, int* shape, 
+               FFTWComplex<float> * in,  int* instrides,  int instep,
+               FFTWComplex<float> * out, int* outstrides, int outstep,
+               int sign, unsigned int planner_flags)
+{
+    return fftwf_plan_many_dft(N, shape, 1,
+                               (fftwf_complex *)in, instrides, instep, 0,
+                               (fftwf_complex *)out, outstrides, outstep, 0,
+                               sign, planner_flags);
+}
+
+inline fftwf_plan 
+fftwPlanCreate(unsigned int N, int* shape, 
+               float * in,  int* instrides,  int instep,
+               FFTWComplex<float> * out, int* outstrides, int outstep,
+               int /*sign is ignored*/, unsigned int planner_flags)
+{
+    return fftwf_plan_many_dft_r2c(N, shape, 1,
+                                    in, instrides, instep, 0,
+                                    (fftwf_complex *)out, outstrides, outstep, 0,
+                                    planner_flags);
+}
+
+inline fftwf_plan 
+fftwPlanCreate(unsigned int N, int* shape, 
+               FFTWComplex<float> * in,  int* instrides,  int instep,
+               float * out, int* outstrides, int outstep,
+               int /*sign is ignored*/, unsigned int planner_flags)
+{
+    return fftwf_plan_many_dft_c2r(N, shape, 1,
+                                   (fftwf_complex *)in, instrides, instep, 0,
+                                   out, outstrides, outstep, 0,
+                                   planner_flags);
+}
+
+inline fftwl_plan 
+fftwPlanCreate(unsigned int N, int* shape, 
+               FFTWComplex<long double> * in,  int* instrides,  int instep,
+               FFTWComplex<long double> * out, int* outstrides, int outstep,
+               int sign, unsigned int planner_flags)
+{
+    return fftwl_plan_many_dft(N, shape, 1,
+                               (fftwl_complex *)in, instrides, instep, 0,
+                               (fftwl_complex *)out, outstrides, outstep, 0,
+                               sign, planner_flags);
+}
+
+inline fftwl_plan 
+fftwPlanCreate(unsigned int N, int* shape, 
+               long double * in,  int* instrides,  int instep,
+               FFTWComplex<long double> * out, int* outstrides, int outstep,
+               int /*sign is ignored*/, unsigned int planner_flags)
+{
+    return fftwl_plan_many_dft_r2c(N, shape, 1,
+                                    in, instrides, instep, 0,
+                                    (fftwl_complex *)out, outstrides, outstep, 0,
+                                    planner_flags);
+}
+
+inline fftwl_plan 
+fftwPlanCreate(unsigned int N, int* shape, 
+               FFTWComplex<long double> * in,  int* instrides,  int instep,
+               long double * out, int* outstrides, int outstep,
+               int /*sign is ignored*/, unsigned int planner_flags)
+{
+    return fftwl_plan_many_dft_c2r(N, shape, 1,
+                                   (fftwl_complex *)in, instrides, instep, 0,
+                                   out, outstrides, outstep, 0,
+                                   planner_flags);
+}
+
+inline void fftwPlanDestroy(fftw_plan plan)
+{
+    if(plan != 0)
+        fftw_destroy_plan(plan);
+}
+
+inline void fftwPlanDestroy(fftwf_plan plan)
+{
+    if(plan != 0)
+        fftwf_destroy_plan(plan);
+}
+
+inline void fftwPlanDestroy(fftwl_plan plan)
+{
+    if(plan != 0)
+        fftwl_destroy_plan(plan);
+}
+
+inline void 
+fftwPlanExecute(fftw_plan plan) 
+{
+    fftw_execute(plan);
+}
+
+inline void 
+fftwPlanExecute(fftwf_plan plan) 
+{
+    fftwf_execute(plan);
+}
+
+inline void 
+fftwPlanExecute(fftwl_plan plan) 
+{
+    fftwl_execute(plan);
+}
+
+inline void 
+fftwPlanExecute(fftw_plan plan, FFTWComplex<double> * in,  FFTWComplex<double> * out) 
+{
+    fftw_execute_dft(plan, (fftw_complex *)in, (fftw_complex *)out);
+}
+
+inline void 
+fftwPlanExecute(fftw_plan plan, double * in,  FFTWComplex<double> * out) 
+{
+    fftw_execute_dft_r2c(plan, in, (fftw_complex *)out);
+}
+
+inline void 
+fftwPlanExecute(fftw_plan plan, FFTWComplex<double> * in,  double * out) 
+{
+    fftw_execute_dft_c2r(plan, (fftw_complex *)in, out);
+}
+
+inline void 
+fftwPlanExecute(fftwf_plan plan, FFTWComplex<float> * in,  FFTWComplex<float> * out) 
+{
+    fftwf_execute_dft(plan, (fftwf_complex *)in, (fftwf_complex *)out);
+}
+
+inline void 
+fftwPlanExecute(fftwf_plan plan, float * in,  FFTWComplex<float> * out) 
+{
+    fftwf_execute_dft_r2c(plan, in, (fftwf_complex *)out);
+}
+
+inline void 
+fftwPlanExecute(fftwf_plan plan, FFTWComplex<float> * in,  float * out) 
+{
+    fftwf_execute_dft_c2r(plan, (fftwf_complex *)in, out);
+}
+
+inline void 
+fftwPlanExecute(fftwl_plan plan, FFTWComplex<long double> * in,  FFTWComplex<long double> * out) 
+{
+    fftwl_execute_dft(plan, (fftwl_complex *)in, (fftwl_complex *)out);
+}
+
+inline void 
+fftwPlanExecute(fftwl_plan plan, long double * in,  FFTWComplex<long double> * out) 
+{
+    fftwl_execute_dft_r2c(plan, in, (fftwl_complex *)out);
+}
+
+inline void 
+fftwPlanExecute(fftwl_plan plan, FFTWComplex<long double> * in,  long double * out) 
+{
+    fftwl_execute_dft_c2r(plan, (fftwl_complex *)in, out);
+}
+
+template <int DUMMY>
+struct FFTWPaddingSize
+{
+    static const int size = 1330;
+    static const int evenSize = 1063;
+    static int goodSizes[size];
+    static int goodEvenSizes[evenSize];
+    
+    static inline int find(int s)
+    {
+        if(s <= 0 || s >= goodSizes[size-1])
+            return s;
+        // find the smallest padding size that is at least as large as 's'
+        int * upperBound = std::upper_bound(goodSizes, goodSizes+size, s);
+        if(upperBound > goodSizes && upperBound[-1] == s)
+            return s;
+        else
+            return *upperBound;
+    }
+
+    static inline int findEven(int s)
+    {
+        if(s <= 0 || s >= goodEvenSizes[evenSize-1])
+            return s;
+        // find the smallest padding size that is at least as large as 's'
+        int * upperBound = std::upper_bound(goodEvenSizes, goodEvenSizes+evenSize, s);
+        if(upperBound > goodEvenSizes && upperBound[-1] == s)
+            return s;
+        else
+            return *upperBound;
+    }
+};
+    
+    // Image sizes where FFTW is fast. The list contains all
+    // numbers less than 100000 whose prime decomposition is of the form
+    // 2^a*3^b*5^c*7^d*11^e*13^f, where e+f is either 0 or 1, and the 
+    // other exponents are arbitrary
+template <int DUMMY>
+int FFTWPaddingSize<DUMMY>::goodSizes[size] = {
+        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 
+        18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 35, 36, 39, 40, 42, 44, 45, 48, 
+        49, 50, 52, 54, 55, 56, 60, 63, 64, 65, 66, 70, 72, 75, 77, 78, 80, 81, 
+        84, 88, 90, 91, 96, 98, 99, 100, 104, 105, 108, 110, 112, 117, 120, 125, 
+        126, 128, 130, 132, 135, 140, 144, 147, 150, 154, 156, 160, 162, 165, 
+        168, 175, 176, 180, 182, 189, 192, 195, 196, 198, 200, 208, 210, 216, 
+        220, 224, 225, 231, 234, 240, 243, 245, 250, 252, 256, 260, 264, 270, 
+        273, 275, 280, 288, 294, 297, 300, 308, 312, 315, 320, 324, 325, 330, 
+        336, 343, 350, 351, 352, 360, 364, 375, 378, 384, 385, 390, 392, 396, 
+        400, 405, 416, 420, 432, 440, 441, 448, 450, 455, 462, 468, 480, 486, 
+        490, 495, 500, 504, 512, 520, 525, 528, 539, 540, 546, 550, 560, 567, 
+        576, 585, 588, 594, 600, 616, 624, 625, 630, 637, 640, 648, 650, 660, 
+        672, 675, 686, 693, 700, 702, 704, 720, 728, 729, 735, 750, 756, 768, 
+        770, 780, 784, 792, 800, 810, 819, 825, 832, 840, 864, 875, 880, 882, 
+        891, 896, 900, 910, 924, 936, 945, 960, 972, 975, 980, 990, 1000, 1008, 
+        1024, 1029, 1040, 1050, 1053, 1056, 1078, 1080, 1092, 1100, 1120, 1125, 
+        1134, 1152, 1155, 1170, 1176, 1188, 1200, 1215, 1225, 1232, 1248, 1250, 
+        1260, 1274, 1280, 1296, 1300, 1320, 1323, 1344, 1350, 1365, 1372, 1375, 
+        1386, 1400, 1404, 1408, 1440, 1456, 1458, 1470, 1485, 1500, 1512, 1536, 
+        1540, 1560, 1568, 1575, 1584, 1600, 1617, 1620, 1625, 1638, 1650, 1664, 
+        1680, 1701, 1715, 1728, 1750, 1755, 1760, 1764, 1782, 1792, 1800, 1820, 
+        1848, 1872, 1875, 1890, 1911, 1920, 1925, 1944, 1950, 1960, 1980, 2000, 
+        2016, 2025, 2048, 2058, 2079, 2080, 2100, 2106, 2112, 2156, 2160, 2184, 
+        2187, 2200, 2205, 2240, 2250, 2268, 2275, 2304, 2310, 2340, 2352, 2376, 
+        2400, 2401, 2430, 2450, 2457, 2464, 2475, 2496, 2500, 2520, 2548, 2560, 
+        2592, 2600, 2625, 2640, 2646, 2673, 2688, 2695, 2700, 2730, 2744, 2750, 
+        2772, 2800, 2808, 2816, 2835, 2880, 2912, 2916, 2925, 2940, 2970, 3000, 
+        3024, 3072, 3080, 3087, 3120, 3125, 3136, 3150, 3159, 3168, 3185, 3200, 
+        3234, 3240, 3250, 3276, 3300, 3328, 3360, 3375, 3402, 3430, 3456, 3465, 
+        3500, 3510, 3520, 3528, 3564, 3584, 3600, 3640, 3645, 3675, 3696, 3744, 
+        3750, 3773, 3780, 3822, 3840, 3850, 3888, 3900, 3920, 3960, 3969, 4000, 
+        4032, 4050, 4095, 4096, 4116, 4125, 4158, 4160, 4200, 4212, 4224, 4312, 
+        4320, 4368, 4374, 4375, 4400, 4410, 4455, 4459, 4480, 4500, 4536, 4550, 
+        4608, 4620, 4680, 4704, 4725, 4752, 4800, 4802, 4851, 4860, 4875, 4900, 
+        4914, 4928, 4950, 4992, 5000, 5040, 5096, 5103, 5120, 5145, 5184, 5200, 
+        5250, 5265, 5280, 5292, 5346, 5376, 5390, 5400, 5460, 5488, 5500, 5544, 
+        5600, 5616, 5625, 5632, 5670, 5733, 5760, 5775, 5824, 5832, 5850, 5880, 
+        5940, 6000, 6048, 6075, 6125, 6144, 6160, 6174, 6237, 6240, 6250, 6272, 
+        6300, 6318, 6336, 6370, 6400, 6468, 6480, 6500, 6552, 6561, 6600, 6615, 
+        6656, 6720, 6750, 6804, 6825, 6860, 6875, 6912, 6930, 7000, 7020, 7040, 
+        7056, 7128, 7168, 7200, 7203, 7280, 7290, 7350, 7371, 7392, 7425, 7488, 
+        7500, 7546, 7560, 7644, 7680, 7700, 7776, 7800, 7840, 7875, 7920, 7938, 
+        8000, 8019, 8064, 8085, 8100, 8125, 8190, 8192, 8232, 8250, 8316, 8320, 
+        8400, 8424, 8448, 8505, 8575, 8624, 8640, 8736, 8748, 8750, 8775, 8800, 
+        8820, 8910, 8918, 8960, 9000, 9072, 9100, 9216, 9240, 9261, 9360, 9375, 
+        9408, 9450, 9477, 9504, 9555, 9600, 9604, 9625, 9702, 9720, 9750, 9800, 
+        9828, 9856, 9900, 9984, 10000, 10080, 10125, 10192, 10206, 10240, 10290, 
+        10368, 10395, 10400, 10500, 10530, 10560, 10584, 10692, 10752, 10780, 
+        10800, 10920, 10935, 10976, 11000, 11025, 11088, 11200, 11232, 11250, 
+        11264, 11319, 11340, 11375, 11466, 11520, 11550, 11648, 11664, 11700, 
+        11760, 11880, 11907, 12000, 12005, 12096, 12150, 12250, 12285, 12288, 
+        12320, 12348, 12375, 12474, 12480, 12500, 12544, 12600, 12636, 12672, 
+        12740, 12800, 12936, 12960, 13000, 13104, 13122, 13125, 13200, 13230, 
+        13312, 13365, 13377, 13440, 13475, 13500, 13608, 13650, 13720, 13750, 
+        13824, 13860, 14000, 14040, 14080, 14112, 14175, 14256, 14336, 14400, 
+        14406, 14553, 14560, 14580, 14625, 14700, 14742, 14784, 14850, 14976, 
+        15000, 15092, 15120, 15288, 15309, 15360, 15400, 15435, 15552, 15600, 
+        15625, 15680, 15750, 15795, 15840, 15876, 15925, 16000, 16038, 16128, 
+        16170, 16200, 16250, 16380, 16384, 16464, 16500, 16632, 16640, 16800, 
+        16807, 16848, 16875, 16896, 17010, 17150, 17199, 17248, 17280, 17325, 
+        17472, 17496, 17500, 17550, 17600, 17640, 17820, 17836, 17920, 18000, 
+        18144, 18200, 18225, 18375, 18432, 18480, 18522, 18711, 18720, 18750, 
+        18816, 18865, 18900, 18954, 19008, 19110, 19200, 19208, 19250, 19404, 
+        19440, 19500, 19600, 19656, 19683, 19712, 19800, 19845, 19968, 20000, 
+        20160, 20250, 20384, 20412, 20475, 20480, 20580, 20625, 20736, 20790, 
+        20800, 21000, 21060, 21120, 21168, 21384, 21504, 21560, 21600, 21609, 
+        21840, 21870, 21875, 21952, 22000, 22050, 22113, 22176, 22275, 22295, 
+        22400, 22464, 22500, 22528, 22638, 22680, 22750, 22932, 23040, 23100, 
+        23296, 23328, 23400, 23520, 23625, 23760, 23814, 24000, 24010, 24057, 
+        24192, 24255, 24300, 24375, 24500, 24570, 24576, 24640, 24696, 24750, 
+        24948, 24960, 25000, 25088, 25200, 25272, 25344, 25480, 25515, 25600, 
+        25725, 25872, 25920, 26000, 26208, 26244, 26250, 26325, 26400, 26411, 
+        26460, 26624, 26730, 26754, 26880, 26950, 27000, 27216, 27300, 27440, 
+        27500, 27648, 27720, 27783, 28000, 28080, 28125, 28160, 28224, 28350, 
+        28431, 28512, 28665, 28672, 28800, 28812, 28875, 29106, 29120, 29160, 
+        29250, 29400, 29484, 29568, 29700, 29952, 30000, 30184, 30240, 30375, 
+        30576, 30618, 30625, 30720, 30800, 30870, 31104, 31185, 31200, 31213, 
+        31250, 31360, 31500, 31590, 31680, 31752, 31850, 32000, 32076, 32256, 
+        32340, 32400, 32500, 32760, 32768, 32805, 32928, 33000, 33075, 33264, 
+        33280, 33600, 33614, 33696, 33750, 33792, 33957, 34020, 34125, 34300, 
+        34375, 34398, 34496, 34560, 34650, 34944, 34992, 35000, 35100, 35200, 
+        35280, 35640, 35672, 35721, 35840, 36000, 36015, 36288, 36400, 36450, 
+        36750, 36855, 36864, 36960, 37044, 37125, 37422, 37440, 37500, 37632, 
+        37730, 37800, 37908, 38016, 38220, 38400, 38416, 38500, 38808, 38880, 
+        39000, 39200, 39312, 39366, 39375, 39424, 39600, 39690, 39936, 40000, 
+        40095, 40131, 40320, 40425, 40500, 40625, 40768, 40824, 40950, 40960, 
+        41160, 41250, 41472, 41580, 41600, 42000, 42120, 42240, 42336, 42525, 
+        42768, 42875, 43008, 43120, 43200, 43218, 43659, 43680, 43740, 43750, 
+        43875, 43904, 44000, 44100, 44226, 44352, 44550, 44590, 44800, 44928, 
+        45000, 45056, 45276, 45360, 45500, 45864, 45927, 46080, 46200, 46305, 
+        46592, 46656, 46800, 46875, 47040, 47250, 47385, 47520, 47628, 47775, 
+        48000, 48020, 48114, 48125, 48384, 48510, 48600, 48750, 49000, 49140, 
+        49152, 49280, 49392, 49500, 49896, 49920, 50000, 50176, 50400, 50421, 
+        50544, 50625, 50688, 50960, 51030, 51200, 51450, 51597, 51744, 51840, 
+        51975, 52000, 52416, 52488, 52500, 52650, 52800, 52822, 52920, 53248, 
+        53460, 53508, 53760, 53900, 54000, 54432, 54600, 54675, 54880, 55000, 
+        55125, 55296, 55440, 55566, 56000, 56133, 56160, 56250, 56320, 56448, 
+        56595, 56700, 56862, 56875, 57024, 57330, 57344, 57600, 57624, 57750, 
+        58212, 58240, 58320, 58500, 58800, 58968, 59049, 59136, 59400, 59535, 
+        59904, 60000, 60025, 60368, 60480, 60750, 61152, 61236, 61250, 61425, 
+        61440, 61600, 61740, 61875, 62208, 62370, 62400, 62426, 62500, 62720, 
+        63000, 63180, 63360, 63504, 63700, 64000, 64152, 64512, 64680, 64800, 
+        64827, 65000, 65520, 65536, 65610, 65625, 65856, 66000, 66150, 66339, 
+        66528, 66560, 66825, 66885, 67200, 67228, 67375, 67392, 67500, 67584, 
+        67914, 68040, 68250, 68600, 68750, 68796, 68992, 69120, 69300, 69888, 
+        69984, 70000, 70200, 70400, 70560, 70875, 71280, 71344, 71442, 71680, 
+        72000, 72030, 72171, 72576, 72765, 72800, 72900, 73125, 73500, 73710, 
+        73728, 73920, 74088, 74250, 74844, 74880, 75000, 75264, 75460, 75600, 
+        75816, 76032, 76440, 76545, 76800, 76832, 77000, 77175, 77616, 77760, 
+        78000, 78125, 78400, 78624, 78732, 78750, 78848, 78975, 79200, 79233, 
+        79380, 79625, 79872, 80000, 80190, 80262, 80640, 80850, 81000, 81250, 
+        81536, 81648, 81900, 81920, 82320, 82500, 82944, 83160, 83200, 83349, 
+        84000, 84035, 84240, 84375, 84480, 84672, 85050, 85293, 85536, 85750, 
+        85995, 86016, 86240, 86400, 86436, 86625, 87318, 87360, 87480, 87500, 
+        87750, 87808, 88000, 88200, 88452, 88704, 89100, 89180, 89600, 89856, 
+        90000, 90112, 90552, 90720, 91000, 91125, 91728, 91854, 91875, 92160, 
+        92400, 92610, 93184, 93312, 93555, 93600, 93639, 93750, 94080, 94325, 
+        94500, 94770, 95040, 95256, 95550, 96000, 96040, 96228, 96250, 96768, 
+        97020, 97200, 97500, 98000, 98280, 98304, 98415, 98560, 98784, 99000, 
+        99225, 99792, 99840 
+}; 
+
+template <int DUMMY>
+int FFTWPaddingSize<DUMMY>::goodEvenSizes[evenSize] = { 
+        2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 
+        24, 26, 28, 30, 32, 36, 40, 42, 44, 48, 50, 52, 54, 56, 60, 64, 66, 70, 
+        72, 78, 80, 84, 88, 90, 96, 98, 100, 104, 108, 110, 112, 120, 126, 128, 
+        130, 132, 140, 144, 150, 154, 156, 160, 162, 168, 176, 180, 182, 192, 
+        196, 198, 200, 208, 210, 216, 220, 224, 234, 240, 250, 252, 256, 260, 
+        264, 270, 280, 288, 294, 300, 308, 312, 320, 324, 330, 336, 350, 352, 
+        360, 364, 378, 384, 390, 392, 396, 400, 416, 420, 432, 440, 448, 450, 
+        462, 468, 480, 486, 490, 500, 504, 512, 520, 528, 540, 546, 550, 560, 
+        576, 588, 594, 600, 616, 624, 630, 640, 648, 650, 660, 672, 686, 700, 
+        702, 704, 720, 728, 750, 756, 768, 770, 780, 784, 792, 800, 810, 832, 
+        840, 864, 880, 882, 896, 900, 910, 924, 936, 960, 972, 980, 990, 1000, 
+        1008, 1024, 1040, 1050, 1056, 1078, 1080, 1092, 1100, 1120, 1134, 1152, 
+        1170, 1176, 1188, 1200, 1232, 1248, 1250, 1260, 1274, 1280, 1296, 1300, 
+        1320, 1344, 1350, 1372, 1386, 1400, 1404, 1408, 1440, 1456, 1458, 1470, 
+        1500, 1512, 1536, 1540, 1560, 1568, 1584, 1600, 1620, 1638, 1650, 1664, 
+        1680, 1728, 1750, 1760, 1764, 1782, 1792, 1800, 1820, 1848, 1872, 1890, 
+        1920, 1944, 1950, 1960, 1980, 2000, 2016, 2048, 2058, 2080, 2100, 2106, 
+        2112, 2156, 2160, 2184, 2200, 2240, 2250, 2268, 2304, 2310, 2340, 2352, 
+        2376, 2400, 2430, 2450, 2464, 2496, 2500, 2520, 2548, 2560, 2592, 2600, 
+        2640, 2646, 2688, 2700, 2730, 2744, 2750, 2772, 2800, 2808, 2816, 2880, 
+        2912, 2916, 2940, 2970, 3000, 3024, 3072, 3080, 3120, 3136, 3150, 3168, 
+        3200, 3234, 3240, 3250, 3276, 3300, 3328, 3360, 3402, 3430, 3456, 3500, 
+        3510, 3520, 3528, 3564, 3584, 3600, 3640, 3696, 3744, 3750, 3780, 3822, 
+        3840, 3850, 3888, 3900, 3920, 3960, 4000, 4032, 4050, 4096, 4116, 4158, 
+        4160, 4200, 4212, 4224, 4312, 4320, 4368, 4374, 4400, 4410, 4480, 4500, 
+        4536, 4550, 4608, 4620, 4680, 4704, 4752, 4800, 4802, 4860, 4900, 4914, 
+        4928, 4950, 4992, 5000, 5040, 5096, 5120, 5184, 5200, 5250, 5280, 5292, 
+        5346, 5376, 5390, 5400, 5460, 5488, 5500, 5544, 5600, 5616, 5632, 5670, 
+        5760, 5824, 5832, 5850, 5880, 5940, 6000, 6048, 6144, 6160, 6174, 6240, 
+        6250, 6272, 6300, 6318, 6336, 6370, 6400, 6468, 6480, 6500, 6552, 6600, 
+        6656, 6720, 6750, 6804, 6860, 6912, 6930, 7000, 7020, 7040, 7056, 7128, 
+        7168, 7200, 7280, 7290, 7350, 7392, 7488, 7500, 7546, 7560, 7644, 7680, 
+        7700, 7776, 7800, 7840, 7920, 7938, 8000, 8064, 8100, 8190, 8192, 8232, 
+        8250, 8316, 8320, 8400, 8424, 8448, 8624, 8640, 8736, 8748, 8750, 8800, 
+        8820, 8910, 8918, 8960, 9000, 9072, 9100, 9216, 9240, 9360, 9408, 9450, 
+        9504, 9600, 9604, 9702, 9720, 9750, 9800, 9828, 9856, 9900, 9984, 10000, 
+        10080, 10192, 10206, 10240, 10290, 10368, 10400, 10500, 10530, 10560, 
+        10584, 10692, 10752, 10780, 10800, 10920, 10976, 11000, 11088, 11200, 
+        11232, 11250, 11264, 11340, 11466, 11520, 11550, 11648, 11664, 11700, 
+        11760, 11880, 12000, 12096, 12150, 12250, 12288, 12320, 12348, 12474, 
+        12480, 12500, 12544, 12600, 12636, 12672, 12740, 12800, 12936, 12960, 
+        13000, 13104, 13122, 13200, 13230, 13312, 13440, 13500, 13608, 13650, 
+        13720, 13750, 13824, 13860, 14000, 14040, 14080, 14112, 14256, 14336, 
+        14400, 14406, 14560, 14580, 14700, 14742, 14784, 14850, 14976, 15000, 
+        15092, 15120, 15288, 15360, 15400, 15552, 15600, 15680, 15750, 15840, 
+        15876, 16000, 16038, 16128, 16170, 16200, 16250, 16380, 16384, 16464, 
+        16500, 16632, 16640, 16800, 16848, 16896, 17010, 17150, 17248, 17280, 
+        17472, 17496, 17500, 17550, 17600, 17640, 17820, 17836, 17920, 18000, 
+        18144, 18200, 18432, 18480, 18522, 18720, 18750, 18816, 18900, 18954, 
+        19008, 19110, 19200, 19208, 19250, 19404, 19440, 19500, 19600, 19656, 
+        19712, 19800, 19968, 20000, 20160, 20250, 20384, 20412, 20480, 20580, 
+        20736, 20790, 20800, 21000, 21060, 21120, 21168, 21384, 21504, 21560, 
+        21600, 21840, 21870, 21952, 22000, 22050, 22176, 22400, 22464, 22500, 
+        22528, 22638, 22680, 22750, 22932, 23040, 23100, 23296, 23328, 23400, 
+        23520, 23760, 23814, 24000, 24010, 24192, 24300, 24500, 24570, 24576, 
+        24640, 24696, 24750, 24948, 24960, 25000, 25088, 25200, 25272, 25344, 
+        25480, 25600, 25872, 25920, 26000, 26208, 26244, 26250, 26400, 26460, 
+        26624, 26730, 26754, 26880, 26950, 27000, 27216, 27300, 27440, 27500, 
+        27648, 27720, 28000, 28080, 28160, 28224, 28350, 28512, 28672, 28800, 
+        28812, 29106, 29120, 29160, 29250, 29400, 29484, 29568, 29700, 29952, 
+        30000, 30184, 30240, 30576, 30618, 30720, 30800, 30870, 31104, 31200, 
+        31250, 31360, 31500, 31590, 31680, 31752, 31850, 32000, 32076, 32256, 
+        32340, 32400, 32500, 32760, 32768, 32928, 33000, 33264, 33280, 33600, 
+        33614, 33696, 33750, 33792, 34020, 34300, 34398, 34496, 34560, 34650, 
+        34944, 34992, 35000, 35100, 35200, 35280, 35640, 35672, 35840, 36000, 
+        36288, 36400, 36450, 36750, 36864, 36960, 37044, 37422, 37440, 37500, 
+        37632, 37730, 37800, 37908, 38016, 38220, 38400, 38416, 38500, 38808, 
+        38880, 39000, 39200, 39312, 39366, 39424, 39600, 39690, 39936, 40000, 
+        40320, 40500, 40768, 40824, 40950, 40960, 41160, 41250, 41472, 41580, 
+        41600, 42000, 42120, 42240, 42336, 42768, 43008, 43120, 43200, 43218, 
+        43680, 43740, 43750, 43904, 44000, 44100, 44226, 44352, 44550, 44590, 
+        44800, 44928, 45000, 45056, 45276, 45360, 45500, 45864, 46080, 46200, 
+        46592, 46656, 46800, 47040, 47250, 47520, 47628, 48000, 48020, 48114, 
+        48384, 48510, 48600, 48750, 49000, 49140, 49152, 49280, 49392, 49500, 
+        49896, 49920, 50000, 50176, 50400, 50544, 50688, 50960, 51030, 51200, 
+        51450, 51744, 51840, 52000, 52416, 52488, 52500, 52650, 52800, 52822, 
+        52920, 53248, 53460, 53508, 53760, 53900, 54000, 54432, 54600, 54880, 
+        55000, 55296, 55440, 55566, 56000, 56160, 56250, 56320, 56448, 56700, 
+        56862, 57024, 57330, 57344, 57600, 57624, 57750, 58212, 58240, 58320, 
+        58500, 58800, 58968, 59136, 59400, 59904, 60000, 60368, 60480, 60750, 
+        61152, 61236, 61250, 61440, 61600, 61740, 62208, 62370, 62400, 62426, 
+        62500, 62720, 63000, 63180, 63360, 63504, 63700, 64000, 64152, 64512, 
+        64680, 64800, 65000, 65520, 65536, 65610, 65856, 66000, 66150, 66528, 
+        66560, 67200, 67228, 67392, 67500, 67584, 67914, 68040, 68250, 68600, 
+        68750, 68796, 68992, 69120, 69300, 69888, 69984, 70000, 70200, 70400, 
+        70560, 71280, 71344, 71442, 71680, 72000, 72030, 72576, 72800, 72900, 
+        73500, 73710, 73728, 73920, 74088, 74250, 74844, 74880, 75000, 75264, 
+        75460, 75600, 75816, 76032, 76440, 76800, 76832, 77000, 77616, 77760, 
+        78000, 78400, 78624, 78732, 78750, 78848, 79200, 79380, 79872, 80000, 
+        80190, 80262, 80640, 80850, 81000, 81250, 81536, 81648, 81900, 81920, 
+        82320, 82500, 82944, 83160, 83200, 84000, 84240, 84480, 84672, 85050, 
+        85536, 85750, 86016, 86240, 86400, 86436, 87318, 87360, 87480, 87500, 
+        87750, 87808, 88000, 88200, 88452, 88704, 89100, 89180, 89600, 89856, 
+        90000, 90112, 90552, 90720, 91000, 91728, 91854, 92160, 92400, 92610, 
+        93184, 93312, 93600, 93750, 94080, 94500, 94770, 95040, 95256, 95550, 
+        96000, 96040, 96228, 96250, 96768, 97020, 97200, 97500, 98000, 98280, 
+        98304, 98560, 98784, 99000, 99792, 99840 
+}; 
+
+template <int M>
+struct FFTEmbedKernel
+{
+    template <unsigned int N, class Real, class C, class Shape>
+    static void 
+    exec(MultiArrayView<N, Real, C> & out, Shape const & kernelShape, 
+         Shape & srcPoint, Shape & destPoint, bool copyIt)
+    {
+        for(srcPoint[M]=0; srcPoint[M]<kernelShape[M]; ++srcPoint[M])
+        {
+            if(srcPoint[M] < (kernelShape[M] + 1) / 2)
+            {
+                destPoint[M] = srcPoint[M];
+            }
+            else
+            {
+                destPoint[M] = srcPoint[M] + out.shape(M) - kernelShape[M];
+                copyIt = true;
+            }
+            FFTEmbedKernel<M-1>::exec(out, kernelShape, srcPoint, destPoint, copyIt);
+        }
+    }
+};
+
+template <>
+struct FFTEmbedKernel<0>
+{
+    template <unsigned int N, class Real, class C, class Shape>
+    static void 
+    exec(MultiArrayView<N, Real, C> & out, Shape const & kernelShape, 
+         Shape & srcPoint, Shape & destPoint, bool copyIt)
+    {
+        for(srcPoint[0]=0; srcPoint[0]<kernelShape[0]; ++srcPoint[0])
+        {
+            if(srcPoint[0] < (kernelShape[0] + 1) / 2)
+            {
+                destPoint[0] = srcPoint[0];
+            }
+            else
+            {
+                destPoint[0] = srcPoint[0] + out.shape(0) - kernelShape[0];
+                copyIt = true;
+            }
+            if(copyIt)
+            {
+                out[destPoint] = out[srcPoint];
+                out[srcPoint] = 0.0;
+            }
+        }
+    }
+};
+
+template <unsigned int N, class Real, class C1, class C2>
+void 
+fftEmbedKernel(MultiArrayView<N, Real, C1> kernel,
+               MultiArrayView<N, Real, C2> out,
+               Real norm = 1.0)
+{
+    typedef typename MultiArrayShape<N>::type Shape;
+
+    MultiArrayView<N, Real, C2> kout = out.subarray(Shape(), kernel.shape());
+    
+    out.init(0.0);
+    kout = kernel;
+    if (norm != 1.0)
+        kout *= norm;
+    moveDCToUpperLeft(kout);
+    
+    Shape srcPoint, destPoint;    
+    FFTEmbedKernel<(int)N-1>::exec(out, kernel.shape(), srcPoint, destPoint, false);
+}
+
+template <unsigned int N, class Real, class C1, class C2>
+void 
+fftEmbedArray(MultiArrayView<N, Real, C1> in,
+              MultiArrayView<N, Real, C2> out)
+{
+    typedef typename MultiArrayShape<N>::type Shape;
+    
+    Shape diff = out.shape() - in.shape(), 
+          leftDiff = div(diff, MultiArrayIndex(2)),
+          rightDiff = diff - leftDiff,
+          right = in.shape() + leftDiff; 
+    
+    out.subarray(leftDiff, right) = in;
+    
+    typedef typename MultiArrayView<N, Real, C2>::traverser Traverser;
+    typedef MultiArrayNavigator<Traverser, N> Navigator;
+    typedef typename Navigator::iterator Iterator;
+    
+    for(unsigned int d = 0; d < N; ++d)
+    {
+        Navigator nav(out.traverser_begin(), out.shape(), d);
+
+        for( ; nav.hasMore(); nav++ )
+        {
+            Iterator i = nav.begin();
+            for(int k=1; k<=leftDiff[d]; ++k)
+                i[leftDiff[d] - k] = i[leftDiff[d] + k];
+            for(int k=0; k<rightDiff[d]; ++k)
+                i[right[d] + k] = i[right[d] - k - 2];
+        }
+    }
+}
+
+} // namespace detail
+
+template <class T, int N>
+TinyVector<T, N>
+fftwBestPaddedShape(TinyVector<T, N> shape)
+{
+    for(unsigned int k=0; k<N; ++k)
+        shape[k] = detail::FFTWPaddingSize<0>::find(shape[k]);
+    return shape;
+}
+
+template <class T, int N>
+TinyVector<T, N>
+fftwBestPaddedShapeR2C(TinyVector<T, N> shape)
+{
+    shape[0] = detail::FFTWPaddingSize<0>::findEven(shape[0]);
+    for(unsigned int k=1; k<N; ++k)
+        shape[k] = detail::FFTWPaddingSize<0>::find(shape[k]);
+    return shape;
+}
+
+/** \brief Find frequency domain shape for a R2C Fourier transform.
+
+    When a real valued array is transformed to the frequency domain, about half of the 
+    Fourier coefficients are redundant. The transform can be optimized as a <a href="http://www.fftw.org/doc/Multi_002dDimensional-DFTs-of-Real-Data.html">R2C 
+    transform</a> that doesn't compute and store the redundant coefficients. This function
+    computes the appropriate frequency domain shape for a given shape in the spatial domain.
+    It simply replaces <tt>shape[0]</tt> with <tt>shape[0] / 2 + 1</tt>.
+    
+    <b>\#include</b> \<vigra/multi_fft.hxx\><br/>
+    Namespace: vigra
+*/
+template <class T, int N>
+TinyVector<T, N>
+fftwCorrespondingShapeR2C(TinyVector<T, N> shape)
+{
+    shape[0] = shape[0] / 2 + 1;
+    return shape;
+}
+
+template <class T, int N>
+TinyVector<T, N>
+fftwCorrespondingShapeC2R(TinyVector<T, N> shape, bool oddDimension0 = false)
+{
+    shape[0] = oddDimension0
+                  ? (shape[0] - 1) * 2 + 1
+                  : (shape[0] - 1) * 2;
+    return shape;
+}
+
+/********************************************************/
+/*                                                      */
+/*                       FFTWPlan                       */
+/*                                                      */
+/********************************************************/
+
+/** C++ wrapper for FFTW plans.
+
+    The class encapsulates the calls to <tt>fftw_plan_dft_2d</tt>, <tt>fftw_execute</tt>, and
+    <tt>fftw_destroy_plan</tt> (and their <tt>float</tt> and <tt>long double</tt> counterparts)
+    in an easy-to-use interface.
+
+    Usually, you use this class only indirectly via \ref fourierTransform() 
+    and \ref fourierTransformInverse(). You only need this class if you want to have more control
+    about FFTW's planning process (by providing non-default planning flags) and/or want to re-use
+    plans for several transformations.
+    
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_fft.hxx\><br>
+    Namespace: vigra
+
+    \code
+    // compute complex Fourier transform of a real image
+    MultiArray<2, double> src(Shape2(w, h));
+    MultiArray<2, FFTWComplex<double> > fourier(Shape2(w, h));
+    
+    // create an optimized plan by measuring the speed of several algorithm variants
+    FFTWPlan<2, double> plan(src, fourier, FFTW_MEASURE);
+    
+    plan.execute(src, fourier); 
+    \endcode
+*/
+template <unsigned int N, class Real = double>
+class FFTWPlan
+{
+    typedef ArrayVector<int> Shape;
+    typedef typename FFTWReal2Complex<Real>::plan_type PlanType;
+    typedef typename FFTWComplex<Real>::complex_type Complex;
+    
+    PlanType plan;
+    Shape shape, instrides, outstrides;
+    int sign;
+    
+  public:
+        /** \brief Create an empty plan.
+        
+            The plan can be initialized later by one of the init() functions.
+        */
+    FFTWPlan()
+    : plan(0)
+    {}
+    
+        /** \brief Create a plan for a complex-to-complex transform.
+        
+            \arg SIGN must be <tt>FFTW_FORWARD</tt> or <tt>FFTW_BACKWARD</tt> according to the
+            desired transformation direction.
+            \arg planner_flags must be a combination of the <a href="http://www.fftw.org/doc/Planner-Flags.html">planner 
+            flags</a> defined by the FFTW library. The default <tt>FFTW_ESTIMATE</tt> will guess
+            optimal algorithm settings or read them from pre-loaded <a href="http://www.fftw.org/doc/Wisdom.html">"wisdom"</a>.
+        */
+    template <class C1, class C2>
+    FFTWPlan(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+             MultiArrayView<N, FFTWComplex<Real>, C2> out,
+             int SIGN, unsigned int planner_flags = FFTW_ESTIMATE)
+    : plan(0)
+    {
+        init(in, out, SIGN, planner_flags);
+    }
+    
+        /** \brief Create a plan for a real-to-complex transform.
+        
+            This always refers to a forward transform. The shape of the output determines
+            if a standard transform (when <tt>out.shape() == in.shape()</tt>) or an 
+            <a href="http://www.fftw.org/doc/Multi_002dDimensional-DFTs-of-Real-Data.html">R2C 
+            transform</a> (when <tt>out.shape() == fftwCorrespondingShapeR2C(in.shape())</tt>) will be executed. 
+            
+            \arg planner_flags must be a combination of the <a href="http://www.fftw.org/doc/Planner-Flags.html">planner 
+            flags</a> defined by the FFTW library. The default <tt>FFTW_ESTIMATE</tt> will guess
+            optimal algorithm settings or read them from pre-loaded <a href="http://www.fftw.org/doc/Wisdom.html">"wisdom"</a>.
+        */
+    template <class C1, class C2>
+    FFTWPlan(MultiArrayView<N, Real, C1> in, 
+             MultiArrayView<N, FFTWComplex<Real>, C2> out,
+             unsigned int planner_flags = FFTW_ESTIMATE)
+    : plan(0)
+    {
+        init(in, out, planner_flags);
+    }
+
+        /** \brief Create a plan for a complex-to-real transform.
+        
+            This always refers to a inverse transform. The shape of the input determines
+            if a standard transform (when <tt>in.shape() == out.shape()</tt>) or a 
+            <a href="http://www.fftw.org/doc/Multi_002dDimensional-DFTs-of-Real-Data.html">C2R 
+            transform</a> (when <tt>in.shape() == fftwCorrespondingShapeR2C(out.shape())</tt>) will be executed. 
+            
+            \arg planner_flags must be a combination of the <a href="http://www.fftw.org/doc/Planner-Flags.html">planner 
+            flags</a> defined by the FFTW library. The default <tt>FFTW_ESTIMATE</tt> will guess
+            optimal algorithm settings or read them from pre-loaded <a href="http://www.fftw.org/doc/Wisdom.html">"wisdom"</a>.
+        */
+    template <class C1, class C2>
+    FFTWPlan(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+             MultiArrayView<N, Real, C2> out,
+             unsigned int planner_flags = FFTW_ESTIMATE)
+    : plan(0)
+    {
+        init(in, out, planner_flags);
+    }
+    
+        /** \brief Copy constructor.
+        */
+    FFTWPlan(FFTWPlan const & other)
+    : plan(other.plan),
+      sign(other.sign)
+    {
+        FFTWPlan & o = const_cast<FFTWPlan &>(other);
+        shape.swap(o.shape);
+        instrides.swap(o.instrides);
+        outstrides.swap(o.outstrides);
+        o.plan = 0; // act like std::auto_ptr
+    }
+    
+        /** \brief Copy assigment.
+        */
+    FFTWPlan & operator=(FFTWPlan const & other)
+    {
+        if(this != &other)
+        {
+            FFTWPlan & o = const_cast<FFTWPlan &>(other);
+            plan = o.plan;
+            shape.swap(o.shape);
+            instrides.swap(o.instrides);
+            outstrides.swap(o.outstrides);
+            sign = o.sign;
+            o.plan = 0; // act like std::auto_ptr
+        }
+        return *this;
+    }
+
+        /** \brief Destructor.
+        */
+    ~FFTWPlan()
+    {
+        detail::fftwPlanDestroy(plan);
+    }
+
+        /** \brief Init a complex-to-complex transform.
+        
+            See the constructor with the same signature for details.
+        */
+    template <class C1, class C2>
+    void init(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+              MultiArrayView<N, FFTWComplex<Real>, C2> out,
+              int SIGN, unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        vigra_precondition(in.strideOrdering() == out.strideOrdering(),
+            "FFTWPlan.init(): input and output must have the same stride ordering.");
+            
+        initImpl(in.permuteStridesDescending(), out.permuteStridesDescending(), 
+                 SIGN, planner_flags);
+    }
+        
+        /** \brief Init a real-to-complex transform.
+        
+            See the constructor with the same signature for details.
+        */
+    template <class C1, class C2>
+    void init(MultiArrayView<N, Real, C1> in, 
+              MultiArrayView<N, FFTWComplex<Real>, C2> out,
+              unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        vigra_precondition(in.strideOrdering() == out.strideOrdering(),
+            "FFTWPlan.init(): input and output must have the same stride ordering.");
+
+        initImpl(in.permuteStridesDescending(), out.permuteStridesDescending(), 
+                 FFTW_FORWARD, planner_flags);
+    }
+        
+        /** \brief Init a complex-to-real transform.
+        
+            See the constructor with the same signature for details.
+        */
+    template <class C1, class C2>
+    void init(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+              MultiArrayView<N, Real, C2> out,
+              unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        vigra_precondition(in.strideOrdering() == out.strideOrdering(),
+            "FFTWPlan.init(): input and output must have the same stride ordering.");
+
+        initImpl(in.permuteStridesDescending(), out.permuteStridesDescending(), 
+                 FFTW_BACKWARD, planner_flags);
+    }
+    
+        /** \brief Execute a complex-to-complex transform.
+        
+            The array shapes must be the same as in the corresponding init function
+            or constructor. However, execute() can be called several times on
+            the same plan, even with different arrays, as long as they have the appropriate 
+            shapes.
+        */
+    template <class C1, class C2>
+    void execute(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                 MultiArrayView<N, FFTWComplex<Real>, C2> out) const
+    {
+        executeImpl(in.permuteStridesDescending(), out.permuteStridesDescending());
+    }
+    
+        /** \brief Execute a real-to-complex transform.
+        
+            The array shapes must be the same as in the corresponding init function
+            or constructor. However, execute() can be called several times on
+            the same plan, even with different arrays, as long as they have the appropriate 
+            shapes.
+        */
+    template <class C1, class C2>
+    void execute(MultiArrayView<N, Real, C1> in, 
+                 MultiArrayView<N, FFTWComplex<Real>, C2> out) const
+    {
+        executeImpl(in.permuteStridesDescending(), out.permuteStridesDescending());
+    }
+    
+        /** \brief Execute a complex-to-real transform.
+        
+            The array shapes must be the same as in the corresponding init function
+            or constructor. However, execute() can be called several times on
+            the same plan, even with different arrays, as long as they have the appropriate 
+            shapes.
+        */
+    template <class C1, class C2>
+    void execute(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                 MultiArrayView<N, Real, C2> out) const
+    {
+        executeImpl(in.permuteStridesDescending(), out.permuteStridesDescending());
+    }
+    
+  private:
+    
+    template <class MI, class MO>
+    void initImpl(MI ins, MO outs, int SIGN, unsigned int planner_flags);
+    
+    template <class MI, class MO>
+    void executeImpl(MI ins, MO outs) const;
+    
+    void checkShapes(MultiArrayView<N, FFTWComplex<Real>, StridedArrayTag> in, 
+                     MultiArrayView<N, FFTWComplex<Real>, StridedArrayTag> out) const
+    {
+        vigra_precondition(in.shape() == out.shape(),
+            "FFTWPlan.init(): input and output must have the same shape.");
+    }
+    
+    void checkShapes(MultiArrayView<N, Real, StridedArrayTag> ins, 
+                     MultiArrayView<N, FFTWComplex<Real>, StridedArrayTag> outs) const
+    {
+        for(int k=0; k<(int)N-1; ++k)
+            vigra_precondition(ins.shape(k) == outs.shape(k),
+                "FFTWPlan.init(): input and output must have matching shapes.");
+        vigra_precondition(ins.shape(N-1) / 2 + 1 == outs.shape(N-1),
+            "FFTWPlan.init(): input and output must have matching shapes.");
+    }
+    
+    void checkShapes(MultiArrayView<N, FFTWComplex<Real>, StridedArrayTag> ins, 
+                     MultiArrayView<N, Real, StridedArrayTag> outs) const
+    {
+        for(int k=0; k<(int)N-1; ++k)
+            vigra_precondition(ins.shape(k) == outs.shape(k),
+                "FFTWPlan.init(): input and output must have matching shapes.");
+        vigra_precondition(outs.shape(N-1) / 2 + 1 == ins.shape(N-1),
+            "FFTWPlan.init(): input and output must have matching shapes.");
+    }
+};
+
+template <unsigned int N, class Real>
+template <class MI, class MO>
+void
+FFTWPlan<N, Real>::initImpl(MI ins, MO outs, int SIGN, unsigned int planner_flags)
+{
+    checkShapes(ins, outs);
+    
+    typename MultiArrayShape<N>::type logicalShape(SIGN == FFTW_FORWARD
+                                                ? ins.shape()
+                                                : outs.shape());
+                                           
+    Shape newShape(logicalShape.begin(), logicalShape.end()),
+          newIStrides(ins.stride().begin(), ins.stride().end()),
+          newOStrides(outs.stride().begin(), outs.stride().end()),
+          itotal(ins.shape().begin(), ins.shape().end()), 
+          ototal(outs.shape().begin(), outs.shape().end());
+
+    for(unsigned int j=1; j<N; ++j)
+    {
+        itotal[j] = ins.stride(j-1) / ins.stride(j);
+        ototal[j] = outs.stride(j-1) / outs.stride(j);
+    }
+    
+    PlanType newPlan = detail::fftwPlanCreate(N, newShape.begin(), 
+                                  ins.data(), itotal.begin(), ins.stride(N-1),
+                                  outs.data(), ototal.begin(), outs.stride(N-1),
+                                  SIGN, planner_flags);
+    detail::fftwPlanDestroy(plan);
+    plan = newPlan;
+    shape.swap(newShape);
+    instrides.swap(newIStrides);
+    outstrides.swap(newOStrides);
+    sign = SIGN;
+}
+
+template <unsigned int N, class Real>
+template <class MI, class MO>
+void FFTWPlan<N, Real>::executeImpl(MI ins, MO outs) const
+{
+    vigra_precondition(plan != 0, "FFTWPlan::execute(): plan is NULL.");
+
+    typename MultiArrayShape<N>::type lshape(sign == FFTW_FORWARD
+                                                ? ins.shape()
+                                                : outs.shape());
+                                           
+    vigra_precondition((lshape == TinyVectorView<int, N>(shape.data())),
+        "FFTWPlan::execute(): shape mismatch between plan and data.");
+    vigra_precondition((ins.stride() == TinyVectorView<int, N>(instrides.data())),
+        "FFTWPlan::execute(): strides mismatch between plan and input data.");
+    vigra_precondition((outs.stride() == TinyVectorView<int, N>(outstrides.data())),
+        "FFTWPlan::execute(): strides mismatch between plan and output data.");
+
+    detail::fftwPlanExecute(plan, ins.data(), outs.data());
+    
+    typedef typename MO::value_type V;
+    if(sign == FFTW_BACKWARD)
+        outs *= V(1.0) / Real(outs.size());
+}
+
+/********************************************************/
+/*                                                      */
+/*                  FFTWConvolvePlan                    */
+/*                                                      */
+/********************************************************/
+
+/** C++ wrapper for a pair of FFTW plans used to perform FFT-based convolution.
+
+    The class encapsulates the calls to <tt>fftw_plan_dft_2d</tt>, <tt>fftw_execute</tt>, and
+    <tt>fftw_destroy_plan</tt> (and their <tt>float</tt> and <tt>long double</tt> counterparts)
+    in an easy-to-use interface. It always creates a pair of plans, one for the forward and one
+    for the inverse transform required for convolution.
+
+    Usually, you use this class only indirectly via \ref convolveFFT() and its variants. 
+    You only need this class if you want to have more control about FFTW's planning process 
+    (by providing non-default planning flags) and/or want to re-use plans for several convolutions.
+    
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_fft.hxx\><br>
+    Namespace: vigra
+
+    \code
+    // convolve a real array with a real kernel
+    MultiArray<2, double> src(Shape2(w, h)), dest(Shape2(w, h));
+    
+    MultiArray<2, double> spatial_kernel(Shape2(9, 9));
+    Gaussian<double> gauss(1.0);
+    
+    for(int y=0; y<9; ++y)
+        for(int x=0; x<9; ++x)
+            spatial_kernel(x, y) = gauss(x-4.0)*gauss(y-4.0);
+            
+    // create an optimized plan by measuring the speed of several algorithm variants
+    FFTWConvolvePlan<2, double> plan(src, spatial_kernel, dest, FFTW_MEASURE);
+    
+    plan.execute(src, spatial_kernel, dest); 
+    \endcode
+*/
+template <unsigned int N, class Real>
+class FFTWConvolvePlan
+{
+    typedef FFTWComplex<Real> Complex;
+    typedef MultiArrayView<N, Real, UnstridedArrayTag >     RArray;
+    typedef MultiArray<N, Complex, FFTWAllocator<Complex> > CArray;
+    
+    FFTWPlan<N, Real> forward_plan, backward_plan;
+    RArray realArray, realKernel;
+    CArray fourierArray, fourierKernel;
+    bool useFourierKernel;
+
+  public:
+  
+    typedef typename MultiArrayShape<N>::type Shape;
+
+        /** \brief Create an empty plan.
+        
+            The plan can be initialized later by one of the init() functions.
+        */
+    FFTWConvolvePlan()
+    : useFourierKernel(false)
+    {}
+    
+        /** \brief Create a plan to convolve a real array with a real kernel.
+        
+            The kernel must be defined in the spatial domain.
+            See \ref convolveFFT() for detailed information on required shapes and internal padding.
+        
+            \arg planner_flags must be a combination of the 
+            <a href="http://www.fftw.org/doc/Planner-Flags.html">planner 
+            flags</a> defined by the FFTW library. The default <tt>FFTW_ESTIMATE</tt> will guess
+            optimal algorithm settings or read them from pre-loaded 
+            <a href="http://www.fftw.org/doc/Wisdom.html">"wisdom"</a>.
+        */
+    template <class C1, class C2, class C3>
+    FFTWConvolvePlan(MultiArrayView<N, Real, C1> in, 
+                     MultiArrayView<N, Real, C2> kernel,
+                     MultiArrayView<N, Real, C3> out,
+                     unsigned int planner_flags = FFTW_ESTIMATE)
+    : useFourierKernel(false)
+    {
+        init(in, kernel, out, planner_flags);
+    }
+    
+        /** \brief Create a plan to convolve a real array with a complex kernel.
+        
+            The kernel must be defined in the Fourier domain, using the half-space format. 
+            See \ref convolveFFT() for detailed information on required shapes and internal padding.
+        
+            \arg planner_flags must be a combination of the 
+            <a href="http://www.fftw.org/doc/Planner-Flags.html">planner 
+            flags</a> defined by the FFTW library. The default <tt>FFTW_ESTIMATE</tt> will guess
+            optimal algorithm settings or read them from pre-loaded 
+            <a href="http://www.fftw.org/doc/Wisdom.html">"wisdom"</a>.
+        */
+    template <class C1, class C2, class C3>
+    FFTWConvolvePlan(MultiArrayView<N, Real, C1> in, 
+                     MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+                     MultiArrayView<N, Real, C3> out,
+                     unsigned int planner_flags = FFTW_ESTIMATE)
+    : useFourierKernel(true)
+    {
+        init(in, kernel, out, planner_flags);
+    }
+   
+        /** \brief Create a plan to convolve a complex array with a complex kernel.
+        
+            See \ref convolveFFT() for detailed information on required shapes and internal padding.
+        
+            \arg fourierDomainKernel determines if the kernel is defined in the spatial or
+                  Fourier domain.
+            \arg planner_flags must be a combination of the 
+            <a href="http://www.fftw.org/doc/Planner-Flags.html">planner 
+            flags</a> defined by the FFTW library. The default <tt>FFTW_ESTIMATE</tt> will guess
+            optimal algorithm settings or read them from pre-loaded 
+            <a href="http://www.fftw.org/doc/Wisdom.html">"wisdom"</a>.
+        */
+    template <class C1, class C2, class C3>
+    FFTWConvolvePlan(MultiArrayView<N, FFTWComplex<Real>, C1> in,
+                     MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+                     MultiArrayView<N, FFTWComplex<Real>, C3> out, 
+                     bool fourierDomainKernel,
+                     unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        init(in, kernel, out, fourierDomainKernel, planner_flags);
+    }
+
+ 
+        /** \brief Create a plan from just the shape information.
+        
+            See \ref convolveFFT() for detailed information on required shapes and internal padding.
+        
+            \arg fourierDomainKernel determines if the kernel is defined in the spatial or
+                  Fourier domain.
+            \arg planner_flags must be a combination of the 
+            <a href="http://www.fftw.org/doc/Planner-Flags.html">planner 
+            flags</a> defined by the FFTW library. The default <tt>FFTW_ESTIMATE</tt> will guess
+            optimal algorithm settings or read them from pre-loaded 
+            <a href="http://www.fftw.org/doc/Wisdom.html">"wisdom"</a>.
+        */
+    template <class C1, class C2, class C3>
+    FFTWConvolvePlan(Shape inOut, Shape kernel, 
+                     bool useFourierKernel = false,
+                     unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        if(useFourierKernel)
+            init(inOut, kernel, planner_flags);
+        else
+            initFourierKernel(inOut, kernel, planner_flags);
+    }
+    
+        /** \brief Init a plan to convolve a real array with a real kernel.
+         
+            See the constructor with the same signature for details.
+        */
+    template <class C1, class C2, class C3>
+    void init(MultiArrayView<N, Real, C1> in, 
+              MultiArrayView<N, Real, C2> kernel,
+              MultiArrayView<N, Real, C3> out,
+              unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        vigra_precondition(in.shape() == out.shape(),
+            "FFTWConvolvePlan::init(): input and output must have the same shape.");
+        init(in.shape(), kernel.shape(), planner_flags);
+    }
+    
+        /** \brief Init a plan to convolve a real array with a complex kernel.
+         
+            See the constructor with the same signature for details.
+        */
+    template <class C1, class C2, class C3>
+    void init(MultiArrayView<N, Real, C1> in, 
+              MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+              MultiArrayView<N, Real, C3> out,
+              unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        vigra_precondition(in.shape() == out.shape(),
+            "FFTWConvolvePlan::init(): input and output must have the same shape.");
+        initFourierKernel(in.shape(), kernel.shape(), planner_flags);
+    }
+    
+        /** \brief Init a plan to convolve a complex array with a complex kernel.
+         
+            See the constructor with the same signature for details.
+        */
+    template <class C1, class C2, class C3>
+    void init(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+              MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+              MultiArrayView<N, FFTWComplex<Real>, C3> out, 
+              bool fourierDomainKernel,
+              unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        vigra_precondition(in.shape() == out.shape(),
+            "FFTWConvolvePlan::init(): input and output must have the same shape.");
+        useFourierKernel = fourierDomainKernel;
+        initComplex(in.shape(), kernel.shape(), planner_flags);
+    }
+    
+        /** \brief Init a plan to convolve a real array with a sequence of kernels.
+         
+            The kernels can be either real or complex. The sequences \a kernels and \a outs
+            must have the same length. See the corresponding constructors 
+            for single kernels for details.
+        */
+    template <class C1, class KernelIterator, class OutIterator>
+    void initMany(MultiArrayView<N, Real, C1> in, 
+                  KernelIterator kernels, KernelIterator kernelsEnd,
+                  OutIterator outs, unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        typedef typename std::iterator_traits<KernelIterator>::value_type KernelArray;
+        typedef typename KernelArray::value_type KernelValue;
+        typedef typename std::iterator_traits<OutIterator>::value_type OutArray;
+        typedef typename OutArray::value_type OutValue;
+
+        bool realKernel = IsSameType<KernelValue, Real>::value;
+        bool fourierKernel = IsSameType<KernelValue, Complex>::value;
+
+        vigra_precondition(realKernel || fourierKernel,
+             "FFTWConvolvePlan::initMany(): kernels have unsuitable value_type.");
+        vigra_precondition((IsSameType<OutValue, Real>::value),
+             "FFTWConvolvePlan::initMany(): outputs have unsuitable value_type.");
+
+        if(realKernel)
+        {
+            initMany(in.shape(), checkShapes(in.shape(), kernels, kernelsEnd, outs),
+                     planner_flags);
+        }
+        else
+        {
+            initFourierKernelMany(in.shape(), 
+                                  checkShapesFourier(in.shape(), kernels, kernelsEnd, outs),
+                                  planner_flags);
+        }
+    }
+     
+        /** \brief Init a plan to convolve a complex array with a sequence of kernels.
+         
+            The kernels must be complex as well. The sequences \a kernels and \a outs
+            must have the same length. See the corresponding constructors 
+            for single kernels for details.
+        */
+    template <class C1, class KernelIterator, class OutIterator>
+    void initMany(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                  KernelIterator kernels, KernelIterator kernelsEnd,
+                  OutIterator outs,
+                  bool fourierDomainKernels,
+                  unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        typedef typename std::iterator_traits<KernelIterator>::value_type KernelArray;
+        typedef typename KernelArray::value_type KernelValue;
+        typedef typename std::iterator_traits<OutIterator>::value_type OutArray;
+        typedef typename OutArray::value_type OutValue;
+
+        vigra_precondition((IsSameType<KernelValue, Complex>::value),
+             "FFTWConvolvePlan::initMany(): kernels have unsuitable value_type.");
+        vigra_precondition((IsSameType<OutValue, Complex>::value),
+             "FFTWConvolvePlan::initMany(): outputs have unsuitable value_type.");
+
+        useFourierKernel = fourierDomainKernels;
+        
+        Shape paddedShape = checkShapesComplex(in.shape(), kernels, kernelsEnd, outs);
+    
+        CArray newFourierArray(paddedShape), newFourierKernel(paddedShape);
+    
+        FFTWPlan<N, Real> fplan(newFourierArray, newFourierArray, FFTW_FORWARD, planner_flags);
+        FFTWPlan<N, Real> bplan(newFourierArray, newFourierArray, FFTW_BACKWARD, planner_flags);
+    
+        forward_plan = fplan;
+        backward_plan = bplan;
+        fourierArray.swap(newFourierArray);
+        fourierKernel.swap(newFourierKernel);
+    }
+    
+    void init(Shape inOut, Shape kernel,
+              unsigned int planner_flags = FFTW_ESTIMATE);
+    
+    void initFourierKernel(Shape inOut, Shape kernel,
+                           unsigned int planner_flags = FFTW_ESTIMATE);
+    
+    void initComplex(Shape inOut, Shape kernel,
+                     unsigned int planner_flags = FFTW_ESTIMATE);
+    
+    void initMany(Shape inOut, Shape maxKernel,
+                  unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        init(inOut, maxKernel, planner_flags);
+    }
+    
+    void initFourierKernelMany(Shape inOut, Shape kernels,
+                               unsigned int planner_flags = FFTW_ESTIMATE)
+    {
+        initFourierKernel(inOut, kernels, planner_flags);
+    }
+        
+        /** \brief Execute a plan to convolve a real array with a real kernel.
+         
+            The array shapes must be the same as in the corresponding init function
+            or constructor. However, execute() can be called several times on
+            the same plan, even with different arrays, as long as they have the appropriate 
+            shapes.
+        */
+    template <class C1, class C2, class C3>
+    void execute(MultiArrayView<N, Real, C1> in, 
+                 MultiArrayView<N, Real, C2> kernel,
+                 MultiArrayView<N, Real, C3> out);
+    
+        /** \brief Execute a plan to convolve a real array with a complex kernel.
+         
+            The array shapes must be the same as in the corresponding init function
+            or constructor. However, execute() can be called several times on
+            the same plan, even with different arrays, as long as they have the appropriate 
+            shapes.
+        */
+    template <class C1, class C2, class C3>
+    void execute(MultiArrayView<N, Real, C1> in, 
+                 MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+                 MultiArrayView<N, Real, C3> out);
+
+        /** \brief Execute a plan to convolve a complex array with a complex kernel.
+         
+            The array shapes must be the same as in the corresponding init function
+            or constructor. However, execute() can be called several times on
+            the same plan, even with different arrays, as long as they have the appropriate 
+            shapes.
+        */
+    template <class C1, class C2, class C3>
+    void execute(MultiArrayView<N, FFTWComplex<Real>, C1> in,
+                 MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+                 MultiArrayView<N, FFTWComplex<Real>, C3> out);
+
+
+        /** \brief Execute a plan to convolve a complex array with a sequence of kernels.
+         
+            The array shapes must be the same as in the corresponding init function
+            or constructor. However, executeMany() can be called several times on
+            the same plan, even with different arrays, as long as they have the appropriate 
+            shapes.
+        */
+    template <class C1, class KernelIterator, class OutIterator>
+    void executeMany(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                     KernelIterator kernels, KernelIterator kernelsEnd,
+                     OutIterator outs);
+                     
+        /** \brief Execute a plan to convolve a real array with a sequence of kernels.
+         
+            The array shapes must be the same as in the corresponding init function
+            or constructor. However, executeMany() can be called several times on
+            the same plan, even with different arrays, as long as they have the appropriate 
+            shapes.
+        */
+    template <class C1, class KernelIterator, class OutIterator>
+    void executeMany(MultiArrayView<N, Real, C1> in, 
+                     KernelIterator kernels, KernelIterator kernelsEnd,
+                     OutIterator outs)
+    {
+        typedef typename std::iterator_traits<KernelIterator>::value_type KernelArray;
+        typedef typename KernelArray::value_type KernelValue;
+        typedef typename IsSameType<KernelValue, Complex>::type UseFourierKernel;
+        typedef typename std::iterator_traits<OutIterator>::value_type OutArray;
+        typedef typename OutArray::value_type OutValue;
+
+        bool realKernel = IsSameType<KernelValue, Real>::value;
+        bool fourierKernel = IsSameType<KernelValue, Complex>::value;
+
+        vigra_precondition(realKernel || fourierKernel,
+             "FFTWConvolvePlan::executeMany(): kernels have unsuitable value_type.");
+        vigra_precondition((IsSameType<OutValue, Real>::value),
+             "FFTWConvolvePlan::executeMany(): outputs have unsuitable value_type.");
+
+        executeManyImpl(in, kernels, kernelsEnd, outs, UseFourierKernel());
+    }
+
+  private:
+  
+    template <class KernelIterator, class OutIterator>
+    Shape checkShapes(Shape in, 
+                      KernelIterator kernels, KernelIterator kernelsEnd,
+                      OutIterator outs);
+     
+    template <class KernelIterator, class OutIterator>
+    Shape checkShapesFourier(Shape in, 
+                             KernelIterator kernels, KernelIterator kernelsEnd,
+                             OutIterator outs);
+     
+    template <class KernelIterator, class OutIterator>
+    Shape checkShapesComplex(Shape in, 
+                             KernelIterator kernels, KernelIterator kernelsEnd,
+                             OutIterator outs);
+    
+    template <class C1, class KernelIterator, class OutIterator>
+    void 
+    executeManyImpl(MultiArrayView<N, Real, C1> in, 
+                    KernelIterator kernels, KernelIterator kernelsEnd,
+                    OutIterator outs, VigraFalseType /* useFourierKernel*/);
+    
+    template <class C1, class KernelIterator, class OutIterator>
+    void 
+    executeManyImpl(MultiArrayView<N, Real, C1> in, 
+                    KernelIterator kernels, KernelIterator kernelsEnd,
+                    OutIterator outs, VigraTrueType /* useFourierKernel*/);
+    
+};    
+    
+template <unsigned int N, class Real>
+void 
+FFTWConvolvePlan<N, Real>::init(Shape in, Shape kernel,
+                                unsigned int planner_flags)
+{
+    Shape paddedShape = fftwBestPaddedShapeR2C(in + kernel - Shape(1)),
+          complexShape = fftwCorrespondingShapeR2C(paddedShape);
+     
+    CArray newFourierArray(complexShape), newFourierKernel(complexShape);
+    
+    Shape realStrides = 2*newFourierArray.stride();
+    realStrides[0] = 1;
+    RArray newRealArray(paddedShape, realStrides, (Real*)newFourierArray.data());
+    RArray newRealKernel(paddedShape, realStrides, (Real*)newFourierKernel.data());
+    
+    FFTWPlan<N, Real> fplan(newRealArray, newFourierArray, planner_flags);
+    FFTWPlan<N, Real> bplan(newFourierArray, newRealArray, planner_flags);
+    
+    forward_plan = fplan;
+    backward_plan = bplan;
+    realArray = newRealArray;
+    realKernel = newRealKernel;
+    fourierArray.swap(newFourierArray);
+    fourierKernel.swap(newFourierKernel);
+    useFourierKernel = false;
+}
+
+template <unsigned int N, class Real>
+void 
+FFTWConvolvePlan<N, Real>::initFourierKernel(Shape in, Shape kernel,
+                                             unsigned int planner_flags)
+{
+    Shape complexShape = kernel,
+          paddedShape  = fftwCorrespondingShapeC2R(complexShape);
+    
+    for(unsigned int k=0; k<N; ++k)
+        vigra_precondition(in[k] <= paddedShape[k],
+             "FFTWConvolvePlan::init(): kernel too small for given input.");
+
+    CArray newFourierArray(complexShape), newFourierKernel(complexShape);
+    
+    Shape realStrides = 2*newFourierArray.stride();
+    realStrides[0] = 1;
+    RArray newRealArray(paddedShape, realStrides, (Real*)newFourierArray.data());
+    RArray newRealKernel(paddedShape, realStrides, (Real*)newFourierKernel.data());
+    
+    FFTWPlan<N, Real> fplan(newRealArray, newFourierArray, planner_flags);
+    FFTWPlan<N, Real> bplan(newFourierArray, newRealArray, planner_flags);
+    
+    forward_plan = fplan;
+    backward_plan = bplan;
+    realArray = newRealArray;
+    realKernel = newRealKernel;
+    fourierArray.swap(newFourierArray);
+    fourierKernel.swap(newFourierKernel);
+    useFourierKernel = true;
+}
+
+template <unsigned int N, class Real>
+void 
+FFTWConvolvePlan<N, Real>::initComplex(Shape in, Shape kernel,
+                                        unsigned int planner_flags)
+{
+    Shape paddedShape;
+    
+    if(useFourierKernel)
+    {
+        for(unsigned int k=0; k<N; ++k)
+            vigra_precondition(in[k] <= kernel[k],
+                 "FFTWConvolvePlan::init(): kernel too small for given input.");
+
+        paddedShape = kernel;
+    }
+    else
+    {
+        paddedShape  = fftwBestPaddedShape(in + kernel - Shape(1));
+    }
+    
+    CArray newFourierArray(paddedShape), newFourierKernel(paddedShape);
+    
+    FFTWPlan<N, Real> fplan(newFourierArray, newFourierArray, FFTW_FORWARD, planner_flags);
+    FFTWPlan<N, Real> bplan(newFourierArray, newFourierArray, FFTW_BACKWARD, planner_flags);
+    
+    forward_plan = fplan;
+    backward_plan = bplan;
+    fourierArray.swap(newFourierArray);
+    fourierKernel.swap(newFourierKernel);
+}
+
+#ifndef DOXYGEN // doxygen documents these functions as free functions
+
+template <unsigned int N, class Real>
+template <class C1, class C2, class C3>
+void 
+FFTWConvolvePlan<N, Real>::execute(MultiArrayView<N, Real, C1> in, 
+                                    MultiArrayView<N, Real, C2> kernel,
+                                    MultiArrayView<N, Real, C3> out)
+{
+    vigra_precondition(!useFourierKernel,
+       "FFTWConvolvePlan::execute(): plan was generated for Fourier kernel, got spatial kernel.");
+
+    vigra_precondition(in.shape() == out.shape(),
+        "FFTWConvolvePlan::execute(): input and output must have the same shape.");
+    
+    Shape paddedShape = fftwBestPaddedShapeR2C(in.shape() + kernel.shape() - Shape(1)),
+          diff = paddedShape - in.shape(), 
+          left = div(diff, MultiArrayIndex(2)),
+          right = in.shape() + left;
+          
+    vigra_precondition(paddedShape == realArray.shape(),
+       "FFTWConvolvePlan::execute(): shape mismatch between input and plan.");
+
+    detail::fftEmbedArray(in, realArray);
+    forward_plan.execute(realArray, fourierArray);
+
+    detail::fftEmbedKernel(kernel, realKernel);
+    forward_plan.execute(realKernel, fourierKernel);
+    
+    fourierArray *= fourierKernel;
+    
+    backward_plan.execute(fourierArray, realArray);
+    
+    out = realArray.subarray(left, right);
+}
+
+template <unsigned int N, class Real>
+template <class C1, class C2, class C3>
+void 
+FFTWConvolvePlan<N, Real>::execute(MultiArrayView<N, Real, C1> in, 
+                                    MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+                                    MultiArrayView<N, Real, C3> out)
+{
+    vigra_precondition(useFourierKernel,
+       "FFTWConvolvePlan::execute(): plan was generated for spatial kernel, got Fourier kernel.");
+
+    vigra_precondition(in.shape() == out.shape(),
+        "FFTWConvolvePlan::execute(): input and output must have the same shape.");
+    
+    vigra_precondition(kernel.shape() == fourierArray.shape(),
+       "FFTWConvolvePlan::execute(): shape mismatch between kernel and plan.");
+
+    Shape paddedShape = fftwCorrespondingShapeC2R(kernel.shape(), odd(in.shape(0))),
+          diff = paddedShape - in.shape(), 
+          left = div(diff, MultiArrayIndex(2)),
+          right = in.shape() + left;
+          
+    vigra_precondition(paddedShape == realArray.shape(),
+       "FFTWConvolvePlan::execute(): shape mismatch between input and plan.");
+
+    detail::fftEmbedArray(in, realArray);
+    forward_plan.execute(realArray, fourierArray);
+
+    fourierKernel = kernel;
+    moveDCToHalfspaceUpperLeft(fourierKernel);
+
+    fourierArray *= fourierKernel;
+    
+    backward_plan.execute(fourierArray, realArray);
+    
+    out = realArray.subarray(left, right);
+}
+
+template <unsigned int N, class Real>
+template <class C1, class C2, class C3>
+void 
+FFTWConvolvePlan<N, Real>::execute(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                                    MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+                                    MultiArrayView<N, FFTWComplex<Real>, C3> out)
+{
+    vigra_precondition(in.shape() == out.shape(),
+        "FFTWConvolvePlan::execute(): input and output must have the same shape.");
+    
+    Shape paddedShape = fourierArray.shape(),
+          diff = paddedShape - in.shape(), 
+          left = div(diff, MultiArrayIndex(2)),
+          right = in.shape() + left;
+          
+    if(useFourierKernel)
+    {
+        vigra_precondition(kernel.shape() == fourierArray.shape(),
+           "FFTWConvolvePlan::execute(): shape mismatch between kernel and plan.");
+           
+        fourierKernel = kernel;
+        moveDCToUpperLeft(fourierKernel);
+    }
+    else
+    {
+        detail::fftEmbedKernel(kernel, fourierKernel);
+        forward_plan.execute(fourierKernel, fourierKernel);
+    }
+
+    detail::fftEmbedArray(in, fourierArray);
+    forward_plan.execute(fourierArray, fourierArray);
+
+    fourierArray *= fourierKernel;
+    
+    backward_plan.execute(fourierArray, fourierArray);
+    
+    out = fourierArray.subarray(left, right);
+}
+
+template <unsigned int N, class Real>
+template <class C1, class KernelIterator, class OutIterator>
+void 
+FFTWConvolvePlan<N, Real>::executeManyImpl(MultiArrayView<N, Real, C1> in, 
+                                           KernelIterator kernels, KernelIterator kernelsEnd,
+                                           OutIterator outs, VigraFalseType /*useFourierKernel*/)
+{
+    vigra_precondition(!useFourierKernel,
+       "FFTWConvolvePlan::execute(): plan was generated for Fourier kernel, got spatial kernel.");
+
+    Shape kernelMax = checkShapes(in.shape(), kernels, kernelsEnd, outs),
+          paddedShape = fftwBestPaddedShapeR2C(in.shape() + kernelMax - Shape(1)),
+          diff = paddedShape - in.shape(), 
+          left = div(diff, MultiArrayIndex(2)),
+          right = in.shape() + left;
+          
+    vigra_precondition(paddedShape == realArray.shape(),
+       "FFTWConvolvePlan::executeMany(): shape mismatch between input and plan.");
+
+    detail::fftEmbedArray(in, realArray);
+    forward_plan.execute(realArray, fourierArray);
+
+    for(; kernels != kernelsEnd; ++kernels, ++outs)
+    {
+        detail::fftEmbedKernel(*kernels, realKernel);
+        forward_plan.execute(realKernel, fourierKernel);
+        
+        fourierKernel *= fourierArray;
+        
+        backward_plan.execute(fourierKernel, realKernel);
+        
+        *outs = realKernel.subarray(left, right);
+    }
+}
+
+template <unsigned int N, class Real>
+template <class C1, class KernelIterator, class OutIterator>
+void 
+FFTWConvolvePlan<N, Real>::executeManyImpl(MultiArrayView<N, Real, C1> in, 
+                                           KernelIterator kernels, KernelIterator kernelsEnd,
+                                           OutIterator outs, VigraTrueType /*useFourierKernel*/)
+{
+    vigra_precondition(useFourierKernel,
+       "FFTWConvolvePlan::execute(): plan was generated for spatial kernel, got Fourier kernel.");
+
+    Shape complexShape = checkShapesFourier(in.shape(), kernels, kernelsEnd, outs),
+          paddedShape = fftwCorrespondingShapeC2R(complexShape, odd(in.shape(0))),
+          diff = paddedShape - in.shape(), 
+          left = div(diff, MultiArrayIndex(2)),
+          right = in.shape() + left;
+          
+    vigra_precondition(complexShape == fourierArray.shape(),
+       "FFTWConvolvePlan::executeFourierKernelMany(): shape mismatch between kernels and plan.");
+
+    vigra_precondition(paddedShape == realArray.shape(),
+       "FFTWConvolvePlan::executeFourierKernelMany(): shape mismatch between input and plan.");
+
+    detail::fftEmbedArray(in, realArray);
+    forward_plan.execute(realArray, fourierArray);
+
+    for(; kernels != kernelsEnd; ++kernels, ++outs)
+    {
+        fourierKernel = *kernels;
+        moveDCToHalfspaceUpperLeft(fourierKernel);
+        fourierKernel *= fourierArray;
+        
+        backward_plan.execute(fourierKernel, realKernel);
+        
+        *outs = realKernel.subarray(left, right);
+    }
+}
+
+template <unsigned int N, class Real>
+template <class C1, class KernelIterator, class OutIterator>
+void 
+FFTWConvolvePlan<N, Real>::executeMany(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                                       KernelIterator kernels, KernelIterator kernelsEnd,
+                                       OutIterator outs)
+{
+    typedef typename std::iterator_traits<KernelIterator>::value_type KernelArray;
+    typedef typename KernelArray::value_type KernelValue;
+    typedef typename std::iterator_traits<OutIterator>::value_type OutArray;
+    typedef typename OutArray::value_type OutValue;
+
+    vigra_precondition((IsSameType<KernelValue, Complex>::value),
+         "FFTWConvolvePlan::executeMany(): kernels have unsuitable value_type.");
+    vigra_precondition((IsSameType<OutValue, Complex>::value),
+         "FFTWConvolvePlan::executeMany(): outputs have unsuitable value_type.");
+
+    Shape paddedShape = checkShapesComplex(in.shape(), kernels, kernelsEnd, outs),
+          diff = paddedShape - in.shape(), 
+          left = div(diff, MultiArrayIndex(2)),
+          right = in.shape() + left;
+          
+    detail::fftEmbedArray(in, fourierArray);
+    forward_plan.execute(fourierArray, fourierArray);
+
+    for(; kernels != kernelsEnd; ++kernels, ++outs)
+    {
+        if(useFourierKernel)
+        {
+            fourierKernel = *kernels;
+            moveDCToUpperLeft(fourierKernel);
+        }
+        else
+        {
+            detail::fftEmbedKernel(*kernels, fourierKernel);
+            forward_plan.execute(fourierKernel, fourierKernel);
+        }
+
+        fourierKernel *= fourierArray;
+        
+        backward_plan.execute(fourierKernel, fourierKernel);
+        
+        *outs = fourierKernel.subarray(left, right);
+    }
+}
+
+#endif // DOXYGEN
+
+template <unsigned int N, class Real>
+template <class KernelIterator, class OutIterator>
+typename FFTWConvolvePlan<N, Real>::Shape 
+FFTWConvolvePlan<N, Real>::checkShapes(Shape in, 
+                                       KernelIterator kernels, KernelIterator kernelsEnd,
+                                       OutIterator outs)
+{
+    vigra_precondition(kernels != kernelsEnd,
+        "FFTWConvolvePlan::checkShapes(): empty kernel sequence.");
+
+    Shape kernelMax;            
+    for(; kernels != kernelsEnd; ++kernels, ++outs)
+    {
+        vigra_precondition(in == outs->shape(),
+            "FFTWConvolvePlan::checkShapes(): shape mismatch between input and (one) output.");
+        kernelMax = max(kernelMax, kernels->shape());
+    }
+    vigra_precondition(prod(kernelMax) > 0,
+        "FFTWConvolvePlan::checkShapes(): all kernels have size 0.");
+    return kernelMax;
+}
+ 
+template <unsigned int N, class Real>
+template <class KernelIterator, class OutIterator>
+typename FFTWConvolvePlan<N, Real>::Shape 
+FFTWConvolvePlan<N, Real>::checkShapesFourier(Shape in, 
+                                               KernelIterator kernels, KernelIterator kernelsEnd,
+                                               OutIterator outs)
+{
+    vigra_precondition(kernels != kernelsEnd,
+        "FFTWConvolvePlan::checkShapesFourier(): empty kernel sequence.");
+
+    Shape complexShape = kernels->shape(),
+          paddedShape  = fftwCorrespondingShapeC2R(complexShape);
+
+    for(unsigned int k=0; k<N; ++k)
+        vigra_precondition(in[k] <= paddedShape[k],
+             "FFTWConvolvePlan::checkShapesFourier(): kernels too small for given input.");
+
+    for(; kernels != kernelsEnd; ++kernels, ++outs)
+    {
+        vigra_precondition(in == outs->shape(),
+            "FFTWConvolvePlan::checkShapesFourier(): shape mismatch between input and (one) output.");
+        vigra_precondition(complexShape == kernels->shape(),
+            "FFTWConvolvePlan::checkShapesFourier(): all kernels must have the same size.");
+    }
+    return complexShape;
+}
+
+template <unsigned int N, class Real>
+template <class KernelIterator, class OutIterator>
+typename FFTWConvolvePlan<N, Real>::Shape 
+FFTWConvolvePlan<N, Real>::checkShapesComplex(Shape in, 
+                                               KernelIterator kernels, KernelIterator kernelsEnd,
+                                               OutIterator outs)
+{
+    vigra_precondition(kernels != kernelsEnd,
+        "FFTWConvolvePlan::checkShapesComplex(): empty kernel sequence.");
+
+    Shape kernelShape = kernels->shape();            
+    for(; kernels != kernelsEnd; ++kernels, ++outs)
+    {
+        vigra_precondition(in == outs->shape(),
+            "FFTWConvolvePlan::checkShapesComplex(): shape mismatch between input and (one) output.");
+        if(useFourierKernel)
+        {
+            vigra_precondition(kernelShape == kernels->shape(),
+                "FFTWConvolvePlan::checkShapesComplex(): Fourier domain kernels must have identical size.");
+        }
+        else
+        {
+            kernelShape = max(kernelShape, kernels->shape());
+        }
+    }
+    vigra_precondition(prod(kernelShape) > 0,
+        "FFTWConvolvePlan::checkShapesComplex(): all kernels have size 0.");
+        
+    if(useFourierKernel)
+    {
+        for(unsigned int k=0; k<N; ++k)
+            vigra_precondition(in[k] <= kernelShape[k],
+                 "FFTWConvolvePlan::checkShapesComplex(): kernels too small for given input.");
+        return kernelShape;
+    }
+    else
+    {
+        return fftwBestPaddedShape(in + kernelShape - Shape(1));
+    }
+}
+ 
+
+/********************************************************/
+/*                                                      */
+/*                   fourierTransform                   */
+/*                                                      */
+/********************************************************/
+
+template <unsigned int N, class Real, class C1, class C2>
+inline void 
+fourierTransform(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                 MultiArrayView<N, FFTWComplex<Real>, C2> out)
+{
+    FFTWPlan<N, Real>(in, out, FFTW_FORWARD).execute(in, out);
+}
+
+template <unsigned int N, class Real, class C1, class C2>
+inline void 
+fourierTransformInverse(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                        MultiArrayView<N, FFTWComplex<Real>, C2> out)
+{
+    FFTWPlan<N, Real>(in, out, FFTW_BACKWARD).execute(in, out);
+}
+
+template <unsigned int N, class Real, class C1, class C2>
+void 
+fourierTransform(MultiArrayView<N, Real, C1> in, 
+                 MultiArrayView<N, FFTWComplex<Real>, C2> out)
+{
+    if(in.shape() == out.shape())
+    {
+        // copy the input array into the output and then perform an in-place FFT
+        out = in;
+        FFTWPlan<N, Real>(out, out, FFTW_FORWARD).execute(out, out);
+    }
+    else if(out.shape() == fftwCorrespondingShapeR2C(in.shape()))
+    {
+        FFTWPlan<N, Real>(in, out).execute(in, out);
+    }
+    else
+        vigra_precondition(false,
+            "fourierTransform(): shape mismatch between input and output.");
+}
+
+template <unsigned int N, class Real, class C1, class C2>
+void 
+fourierTransformInverse(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                        MultiArrayView<N, Real, C2> out)
+{
+    vigra_precondition(in.shape() == fftwCorrespondingShapeR2C(out.shape()),
+        "fourierTransformInverse(): shape mismatch between input and output.");
+    FFTWPlan<N, Real>(in, out).execute(in, out);
+}
+
+//@}
+
+/** \addtogroup MultiArrayConvolutionFilters
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                     convolveFFT                      */
+/*                                                      */
+/********************************************************/
+
+/** \brief Convolve an array with a kernel by means of the Fourier transform.
+
+    Thanks to the convolution theorem of Fourier theory, a convolution in the spatial domain
+    is equivalent to a multiplication in the frequency domain. Thus, for certain kernels
+    (especially large, non-separable ones), it is advantageous to perform the convolution by first
+    transforming both array and kernel to the frequency domain, multiplying the frequency 
+    representations, and transforming the result back into the spatial domain. 
+    Some kernels have a much simpler definition in the frequency domain, so that they are readily 
+    computed there directly, avoiding Fourier transformation of those kernels. 
+    
+    The following functions implement various variants of FFT-based convolution:
+    
+        <DL>
+        <DT><b>convolveFFT</b><DD> Convolve a real-valued input array with a kernel such that the 
+                            result is also real-valued. That is, the kernel is either provided
+                            as a real-valued array in the spatial domain, or as a 
+                            complex-valued array in the Fourier domain, using the half-space format 
+                            of the R2C Fourier transform (see below).
+        <DT><b>convolveFFTMany</b><DD> Like <tt>convolveFFT</tt>, but you may provide many kernels at once 
+                            (using an iterator pair specifying the kernel sequence). 
+                            This has the advantage that the forward transform of the input array needs 
+                            to be executed only once.
+        <DT><b>convolveFFTComplex</b><DD> Convolve a complex-valued input array with a complex-valued kernel, 
+                            resulting in a complex-valued output array. An additional flag is used to 
+                            specify whether the kernel is defined in the spatial or frequency domain.
+        <DT><b>convolveFFTComplexMany</b><DD> Like <tt>convolveFFTComplex</tt>, but you may provide many kernels at once 
+                            (using an iterator pair specifying the kernel sequence). 
+                            This has the advantage that the forward transform of the input array needs 
+                            to be executed only once.
+        </DL>
+    
+    The output arrays must have the same shape as the input arrays. In the "Many" variants of the
+    convolution functions, the kernels must all have the same shape.
+    
+    The origin of the kernel is always assumed to be in the center of the kernel array (precisely,
+    at the point <tt>floor(kernel.shape() / 2.0)</tt>, except when the half-space format is used, see below). 
+    The function \ref moveDCToUpperLeft() will be called internally to align the kernel with the transformed 
+    input as appropriate.
+    
+    If a real input is combined with a real kernel, the kernel is automatically assumed to be defined
+    in the spatial domain. If a real input is combined with a complex kernel, the kernel is assumed 
+    to be defined in the Fourier domain in half-space format. If the input array is complex, a flag 
+    <tt>fourierDomainKernel</tt> determines where the kernel is defined.
+    
+    When the kernel is defined in the spatial domain, the convolution functions will automatically pad
+    (enlarge) the input array by at least the kernel radius in each direction. The newly added space is
+    filled according to reflective boundary conditions in order to minimize border artifacts during 
+    convolution. It is thus ensured that convolution in the Fourier domain yields the same results as 
+    convolution in the spatial domain (e.g. when \ref separableConvolveMultiArray() is called with the 
+    same kernel). A little further padding may be added to make sure that the padded array shape
+    uses integers which have only small prime factors, because FFTW is then able to use the fastest
+    possible algorithms. Any padding is automatically removed from the result arrays before the function
+    returns.
+    
+    When the kernel is defined in the frequency domain, it must be complex-valued, and its shape determines
+    the shape of the Fourier representation (i.e. the input is padded according to the shape of the kernel).
+    If we are going to perform a complex-valued convolution, the kernel must be defined for the entire 
+    frequency domain, and its shape directly determines the size of the FFT. 
+    
+    In contrast, a frequency domain kernel for a real-valued convolution must have symmetry properties
+    that allow to drop half of the kernel coefficients, as in the 
+    <a href="http://www.fftw.org/doc/Multi_002dDimensional-DFTs-of-Real-Data.html">R2C transform</a>. 
+    That is, the kernel must have the <i>half-space format</i>, that is the shape returned by <tt>fftwCorrespondingShapeR2C(fourier_shape)</tt>, where <tt>fourier_shape</tt> is the desired 
+    logical shape of the frequency representation (and thus the size of the padded input). The origin 
+    of the kernel must be at the point 
+    <tt>(0, floor(fourier_shape[0] / 2.0), ..., floor(fourier_shape[N-1] / 2.0))</tt> 
+    (i.e. as in a regular kernel except for the first dimension).
+    
+    The <tt>Real</tt> type in the declarations can be <tt>double</tt>, <tt>float</tt>, and 
+    <tt>long double</tt>. Your program must always link against <tt>libfftw3</tt>. If you use
+    <tt>float</tt> or <tt>long double</tt> arrays, you must <i>additionally</i> link against 
+    <tt>libfftw3f</tt> and <tt>libfftw3l</tt> respectively.
+    
+    The Fourier transform functions internally create <a href="http://www.fftw.org/doc/Using-Plans.html">FFTW plans</a>
+    which control the algorithm details. The plans are creates with the flag <tt>FFTW_ESTIMATE</tt>, i.e.
+    optimal settings are guessed or read from saved "wisdom" files. If you need more control over planning,
+    you can use the class \ref FFTWConvolvePlan.
+    
+    See also \ref applyFourierFilter() for corresponding functionality on the basis of the
+    old image iterator interface.
+    
+    <b> Declarations:</b>
+
+    Real-valued convolution with kernel in the spatial domain:
+    \code
+    namespace vigra {
+        template <unsigned int N, class Real, class C1, class C2, class C3>
+        void 
+        convolveFFT(MultiArrayView<N, Real, C1> in, 
+                    MultiArrayView<N, Real, C2> kernel,
+                    MultiArrayView<N, Real, C3> out);
+    }
+    \endcode
+
+    Real-valued convolution with kernel in the Fourier domain (half-space format):
+    \code
+    namespace vigra {
+        template <unsigned int N, class Real, class C1, class C2, class C3>
+        void 
+        convolveFFT(MultiArrayView<N, Real, C1> in, 
+                    MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+                    MultiArrayView<N, Real, C3> out);
+    }
+    \endcode
+
+    Series of real-valued convolutions with kernels in the spatial or Fourier domain 
+    (the kernel and out sequences must have the same length):
+    \code
+    namespace vigra {
+        template <unsigned int N, class Real, class C1, 
+                  class KernelIterator, class OutIterator>
+        void 
+        convolveFFTMany(MultiArrayView<N, Real, C1> in, 
+                        KernelIterator kernels, KernelIterator kernelsEnd,
+                        OutIterator outs);
+    }
+    \endcode
+
+    Complex-valued convolution (parameter <tt>fourierDomainKernel</tt> determines if
+    the kernel is defined in the spatial or Fourier domain):
+    \code
+    namespace vigra {
+        template <unsigned int N, class Real, class C1, class C2, class C3>
+        void
+        convolveFFTComplex(MultiArrayView<N, FFTWComplex<Real>, C1> in,
+                           MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+                           MultiArrayView<N, FFTWComplex<Real>, C3> out,
+                           bool fourierDomainKernel);
+    }
+    \endcode
+
+    Series of complex-valued convolutions (parameter <tt>fourierDomainKernel</tt> 
+    determines if the kernels are defined in the spatial or Fourier domain, 
+    the kernel and out sequences must have the same length):
+    \code
+    namespace vigra {
+        template <unsigned int N, class Real, class C1, 
+                  class KernelIterator, class OutIterator>
+        void 
+        convolveFFTComplexMany(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                               KernelIterator kernels, KernelIterator kernelsEnd,
+                               OutIterator outs,
+                               bool fourierDomainKernel);
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_fft.hxx\><br>
+    Namespace: vigra
+
+    \code
+    // convolve real array with a Gaussian (sigma=1) defined in the spatial domain
+    // (implicitly uses padding by at least 4 pixels)
+    MultiArray<2, double> src(Shape2(w, h)), dest(Shape2(w,h));
+    
+    MultiArray<2, double> spatial_kernel(Shape2(9, 9));
+    Gaussian<double> gauss(1.0);
+    
+    for(int y=0; y<9; ++y)
+        for(int x=0; x<9; ++x)
+            spatial_kernel(x, y) = gauss(x-4.0)*gauss(y-4.0);
+
+    convolveFFT(src, spatial_kernel, dest);
+    
+    // convolve real array with a Gaussian (sigma=1) defined in the Fourier domain
+    // (uses no padding, because the kernel size corresponds to the input size)
+    MultiArray<2, FFTWComplex<double> > fourier_kernel(fftwCorrespondingShapeR2C(src.shape()));
+    int y0 = h / 2;
+        
+    for(int y=0; y<fourier_kernel.shape(1); ++y)
+        for(int x=0; x<fourier_kernel.shape(0); ++x)
+            fourier_kernel(x, y) = exp(-0.5*sq(x / double(w))) * exp(-0.5*sq((y-y0)/double(h)));
+
+    convolveFFT(src, fourier_kernel, dest);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void convolveFFT)
+
+template <unsigned int N, class Real, class C1, class C2, class C3>
+void 
+convolveFFT(MultiArrayView<N, Real, C1> in, 
+            MultiArrayView<N, Real, C2> kernel,
+            MultiArrayView<N, Real, C3> out)
+{
+    FFTWConvolvePlan<N, Real>(in, kernel, out).execute(in, kernel, out);
+}
+
+template <unsigned int N, class Real, class C1, class C2, class C3>
+void 
+convolveFFT(MultiArrayView<N, Real, C1> in, 
+            MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+            MultiArrayView<N, Real, C3> out)
+{
+    FFTWConvolvePlan<N, Real>(in, kernel, out).execute(in, kernel, out);
+}
+
+/** \brief Convolve a complex-valued array by means of the Fourier transform.
+
+    See \ref convolveFFT() for details.
+*/
+doxygen_overloaded_function(template <...> void convolveFFTComplex)
+
+template <unsigned int N, class Real, class C1, class C2, class C3>
+void
+convolveFFTComplex(MultiArrayView<N, FFTWComplex<Real>, C1> in,
+            MultiArrayView<N, FFTWComplex<Real>, C2> kernel,
+            MultiArrayView<N, FFTWComplex<Real>, C3> out,
+            bool fourierDomainKernel)
+{
+    FFTWConvolvePlan<N, Real>(in, kernel, out, fourierDomainKernel).execute(in, kernel, out);
+}
+
+/** \brief Convolve a real-valued array with a sequence of kernels by means of the Fourier transform.
+
+    See \ref convolveFFT() for details.
+*/
+doxygen_overloaded_function(template <...> void convolveFFTMany)
+
+template <unsigned int N, class Real, class C1, 
+          class KernelIterator, class OutIterator>
+void 
+convolveFFTMany(MultiArrayView<N, Real, C1> in, 
+                KernelIterator kernels, KernelIterator kernelsEnd,
+                OutIterator outs)
+{
+    FFTWConvolvePlan<N, Real> plan;
+    plan.initMany(in, kernels, kernelsEnd, outs);
+    plan.executeMany(in, kernels, kernelsEnd, outs);
+}
+
+/** \brief Convolve a complex-valued array with a sequence of kernels by means of the Fourier transform.
+
+    See \ref convolveFFT() for details.
+*/
+doxygen_overloaded_function(template <...> void convolveFFTComplexMany)
+
+template <unsigned int N, class Real, class C1, 
+          class KernelIterator, class OutIterator>
+void 
+convolveFFTComplexMany(MultiArrayView<N, FFTWComplex<Real>, C1> in, 
+                KernelIterator kernels, KernelIterator kernelsEnd,
+                OutIterator outs,
+                bool fourierDomainKernel)
+{
+    FFTWConvolvePlan<N, Real> plan;
+    plan.initMany(in, kernels, kernelsEnd, outs, fourierDomainKernel);
+    plan.executeMany(in, kernels, kernelsEnd, outs);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_MULTI_FFT_HXX
diff --git a/include/vigra/multi_gridgraph.hxx b/include/vigra/multi_gridgraph.hxx
new file mode 100644
index 0000000..67c4c65
--- /dev/null
+++ b/include/vigra/multi_gridgraph.hxx
@@ -0,0 +1,3002 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2011-2012 by Stefan Schmidt and Ullrich Koethe         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_GRIDGRAPH_HXX
+#define VIGRA_MULTI_GRIDGRAPH_HXX
+
+#include "multi_iterator.hxx"
+#include "multi_array.hxx"
+#include "graphs.hxx"
+
+template <unsigned int N>
+struct NeighborhoodTests;
+
+namespace vigra {
+
+/** \addtogroup GraphDataStructures Graph Data Structures
+        
+        A GridGraph class implementing the APIs of the <a href="http://www.boost.org/doc/libs/release/libs/graph/">boost::graph</a> and
+        <a href="http://lemon.cs.elte.hu/">LEMON</a> libraries. See also
+        the \ref BoostGraphExtensions.
+*/
+//@{
+
+/*
+undirected edge_descriptor derived from TinyVector, 
+including flag for original edge orientation, 
+as necessary for source(), target() functions;
+This edge_descriptor allows to directly (without adapter object)
+index a MultiArrayView with one dimension more than the gridgraph, 
+the last coordinate indexing the edge number
+(missing edges at the border are just ignored) 
+
+The gridgraph class is able to convert/construct these edge_descriptors
+and to reconstruct the corresponding source/target nodes.
+
+FIXME: store edge index in (*this)[0] ??
+*/
+template<unsigned int N>
+class GridGraphArcDescriptor
+    : public MultiArrayShape<N+1>::type
+{
+  public:
+    typedef typename MultiArrayShape<N+1>::type  base_type;
+    typedef typename base_type::value_type       value_type;
+    typedef base_type                            edge_coord_type;
+    typedef value_type                           index_type;
+    typedef typename MultiArrayShape<N>::type    shape_type;
+    typedef TinyVectorView<value_type, N>        vertex_descriptor_view;
+
+    GridGraphArcDescriptor()
+    : is_reversed_(false)
+    {}
+
+    GridGraphArcDescriptor(lemon::Invalid)
+    : base_type(-1),
+      is_reversed_(false)
+    {}
+
+    GridGraphArcDescriptor(base_type const & b, bool reversed)
+    : base_type(b),
+      is_reversed_(reversed)
+    {}
+
+    GridGraphArcDescriptor(shape_type const &vertex,
+                           index_type edge_index,
+                           bool reversed=false)
+    : base_type(detail::DontInit())
+    {
+        set(vertex, edge_index, reversed);
+    }
+                                      
+    void set(shape_type const &vertex, index_type edge_index, bool reversed) 
+    {
+        this->template subarray<0,N>() = vertex;
+        (*this)[N] = edge_index;
+        is_reversed_ = reversed;
+    }
+        
+    void increment(GridGraphArcDescriptor const & diff, bool opposite=false) 
+    {
+        if(diff.is_reversed_)
+        {
+            is_reversed_ = !opposite;
+            this->template subarray<0,N>() += diff.template subarray<0,N>();
+        }
+        else
+        {
+            is_reversed_ = opposite;
+        }
+        (*this)[N] = diff[N];
+    }
+        
+    bool isReversed() const 
+    {
+        return is_reversed_;
+    }
+    
+    vertex_descriptor_view vertexDescriptor() const
+    {
+        return this->template subarray<0,N>();
+    }
+    
+    value_type edgeIndex() const
+    {
+        return (*this)[N];
+    }
+
+  protected:
+    bool is_reversed_;
+};
+
+inline MultiArrayIndex 
+gridGraphMaxDegree(unsigned int N, NeighborhoodType t)
+{
+    return t == DirectNeighborhood
+                ? 2*N
+                : pow(3.0, (int)N) - 1;
+}
+
+template <unsigned int N, NeighborhoodType>
+struct GridGraphMaxDegree;
+
+template <unsigned int N>
+struct GridGraphMaxDegree<N, DirectNeighborhood>
+{
+    static const MultiArrayIndex value = 2*N;
+};
+
+template <unsigned int N>
+struct GridGraphMaxDegree<N, IndirectNeighborhood>
+{
+    static const MultiArrayIndex value = MetaPow<3, N>::value - 1;
+};
+
+template <class Shape>
+MultiArrayIndex 
+gridGraphEdgeCount(Shape const & shape, NeighborhoodType t, bool directed)
+{
+    int res = 0;
+    if(t == DirectNeighborhood)
+    {
+        for(unsigned int k=0; k<shape.size(); ++k)
+            res += 2*prod(shape - Shape::unitVector(k));
+    }
+    else
+    {
+        res = prod(3*shape - Shape(2)) - prod(shape);
+    }
+    return directed
+               ? res
+               : res / 2;
+}
+
+namespace detail {
+
+template <class Shape>
+void
+computeNeighborOffsets(ArrayVector<Shape> const & neighborOffsets, 
+                       ArrayVector<ArrayVector<bool> > const & neighborExists,
+                       ArrayVector<ArrayVector<Shape> > & incrementOffsets,
+                       ArrayVector<ArrayVector<GridGraphArcDescriptor<Shape::static_size> > > & edgeDescriptorOffsets,
+                       ArrayVector<ArrayVector<MultiArrayIndex> > & indices,
+                       ArrayVector<ArrayVector<MultiArrayIndex> > & backIndices,
+                       bool directed)
+{
+    typedef GridGraphArcDescriptor<Shape::static_size> EdgeDescriptor;
+    
+    unsigned int borderTypeCount = neighborExists.size();
+    incrementOffsets.resize(borderTypeCount);
+    edgeDescriptorOffsets.resize(borderTypeCount);
+    indices.resize(borderTypeCount);
+    backIndices.resize(borderTypeCount);
+    
+    for(unsigned int k=0; k<borderTypeCount; ++k)
+    {
+        incrementOffsets[k].clear();
+        edgeDescriptorOffsets[k].clear();
+        indices[k].clear();
+        backIndices[k].clear();
+        
+        for(unsigned int j=0; j < neighborOffsets.size(); ++j)
+        {
+            if(neighborExists[k][j])
+            {
+                if(incrementOffsets[k].size() == 0)
+                {
+                    incrementOffsets[k].push_back(neighborOffsets[j]);
+                }
+                else
+                {
+                    incrementOffsets[k].push_back(neighborOffsets[j] - neighborOffsets[indices[k].back()]);
+                }
+                
+                if(directed || j < neighborOffsets.size() / 2) // directed or backward edge
+                {
+                    edgeDescriptorOffsets[k].push_back(EdgeDescriptor(Shape(), j));
+                }
+                else if(edgeDescriptorOffsets[k].size() == 0 || !edgeDescriptorOffsets[k].back().isReversed()) // the first forward edge
+                {
+                    edgeDescriptorOffsets[k].push_back(EdgeDescriptor(neighborOffsets[j], neighborOffsets.size()-j-1, true));
+                }       
+                else // second or higher forward edge
+                {
+                    edgeDescriptorOffsets[k].push_back(EdgeDescriptor(neighborOffsets[j] - neighborOffsets[indices[k].back()], 
+                                                                      neighborOffsets.size()-j-1, true));
+                }
+                
+                indices[k].push_back(j);
+                if(j < neighborOffsets.size() / 2)
+                    backIndices[k].push_back(j);
+            }
+        }
+    }
+}
+
+} // namespace detail
+
+template<unsigned int N, bool BackEdgesOnly=false>
+class GridGraphNeighborIterator
+{
+public:
+    typedef typename MultiArrayShape<N>::type          shape_type;
+    typedef MultiCoordinateIterator<N>                 vertex_iterator;
+    typedef typename vertex_iterator::value_type       vertex_descriptor;
+    typedef vertex_descriptor                          value_type;
+    typedef typename vertex_iterator::pointer          pointer;
+    typedef typename vertex_iterator::const_pointer    const_pointer;
+    typedef typename vertex_iterator::reference        reference;
+    typedef typename vertex_iterator::const_reference  const_reference;
+    typedef MultiArrayIndex                            difference_type;
+    typedef MultiArrayIndex                            index_type;
+    typedef std::forward_iterator_tag                  iterator_category;
+    
+    friend struct NeighborhoodTests<N>;
+
+    GridGraphNeighborIterator() 
+    : neighborOffsets_(0),
+      neighborIndices_(0),
+      index_(0)
+    {}
+
+    template <class DirectedTag>
+    GridGraphNeighborIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::Node const & v)
+    : neighborOffsets_(0),
+      neighborIndices_(0),
+      target_(v),
+      index_(0)
+    {
+        unsigned int nbtype = g.get_border_type(v);
+        neighborOffsets_ = &(*g.neighborIncrementArray())[nbtype];
+        neighborIndices_ = &(*g.neighborIndexArray(BackEdgesOnly))[nbtype];
+        updateTarget();
+    }
+
+    template <class DirectedTag>
+    GridGraphNeighborIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::NodeIt const & v)
+    : neighborOffsets_(0),
+      neighborIndices_(0),
+      target_(v),
+      index_(0)
+    {
+        unsigned int nbtype = g.get_border_type(v);
+        neighborOffsets_ = &(*g.neighborIncrementArray())[nbtype];
+        neighborIndices_ = &(*g.neighborIndexArray(BackEdgesOnly))[nbtype];
+        updateTarget();
+    }
+
+    // TODO: implement a "goto-neighbor" operation
+    // yielding a vertex_iterator! -> useful for 
+    // watershed algo.
+
+    GridGraphNeighborIterator & operator++()
+    {
+        ++index_;
+        updateTarget();
+        return *this;
+    }
+
+    GridGraphNeighborIterator operator++(int)
+    {
+        GridGraphNeighborIterator ret(*this);
+        ++*this;
+        return ret;
+    }
+
+    const_reference operator*() const
+    {
+        return target_;
+    }
+
+    const_pointer operator->() const
+    {
+        return &target_;
+    }
+    
+    operator const_reference() const
+    {
+        return target_;
+    }
+
+    const_reference target() const
+    {
+        return target_;
+    }
+
+    MultiArrayIndex index() const
+    {
+        return index_;
+    }
+
+    MultiArrayIndex neighborIndex() const
+    {
+        return (*neighborIndices_)[index_];
+    }
+
+    bool operator==(GridGraphNeighborIterator const & other) const
+    {
+        return index_ == other.index_;
+    }
+
+    bool operator!=(GridGraphNeighborIterator const & other) const
+    {
+        return index_ != other.index_;
+    }
+
+    bool isValid() const
+    {
+        return index_ < (MultiArrayIndex)neighborIndices_->size();
+    }
+    
+    bool atEnd() const
+    {
+        return index_ >= (MultiArrayIndex)neighborIndices_->size();
+    }
+    
+    GridGraphNeighborIterator getEndIterator() const
+    {
+        GridGraphNeighborIterator res(*this);
+        res.index_ = (MultiArrayIndex)neighborIndices_->size();
+        return res;
+    }
+
+  protected:
+
+        // for testing only
+    GridGraphNeighborIterator(ArrayVector<shape_type> const & neighborOffsets,
+                              ArrayVector<index_type> const & neighborIndices,
+                              ArrayVector<index_type> const & backIndices,
+                              vertex_descriptor source)
+    : neighborOffsets_(&neighborOffsets),
+      neighborIndices_(BackEdgesOnly ? &backIndices : &neighborIndices),
+      target_(source),
+      index_(0)
+    {
+        updateTarget();
+    }
+  
+    void updateTarget()
+    {
+        if(isValid())
+            target_ += (*neighborOffsets_)[index_];
+    }
+
+    ArrayVector<shape_type> const * neighborOffsets_;
+    ArrayVector<index_type> const * neighborIndices_;
+    vertex_descriptor target_;
+    MultiArrayIndex index_;
+};
+
+template<unsigned int N, bool BackEdgesOnly>
+class GridGraphEdgeIterator;
+
+template<unsigned int N, bool BackEdgesOnly=false>
+class GridGraphOutEdgeIterator
+{
+  public:
+    typedef typename MultiArrayShape<N>::type    shape_type;
+    typedef MultiArrayIndex                      index_type;
+    typedef GridGraphArcDescriptor<N>            arc_descriptor;
+    typedef typename MultiArrayShape<N+1>::type  value_type;
+    typedef value_type const &                   reference;
+    typedef value_type const &                   const_reference;
+    typedef value_type const *                   pointer;
+    typedef value_type const *                   const_pointer;
+    typedef MultiArrayIndex                      difference_type;
+    typedef std::forward_iterator_tag            iterator_category;
+
+    friend struct NeighborhoodTests<N>;
+    friend class GridGraphEdgeIterator<N, BackEdgesOnly>;
+
+    GridGraphOutEdgeIterator() 
+    : neighborOffsets_(0),
+      neighborIndices_(0),
+      index_(0)
+    {}
+
+    template <class DirectedTag>
+    GridGraphOutEdgeIterator(GridGraph<N, DirectedTag> const & g, 
+                             typename GridGraph<N, DirectedTag>::NodeIt const & v,
+                             bool opposite=false)
+    : neighborOffsets_(0),
+      neighborIndices_(0),
+      edge_descriptor_(),
+      index_(0)
+    {
+        unsigned int nbtype = g.get_border_type(v);
+        init(&(*g.edgeIncrementArray())[nbtype], &(*g.neighborIndexArray(BackEdgesOnly))[nbtype], *v, opposite);
+    }
+
+    template <class DirectedTag>
+    GridGraphOutEdgeIterator(GridGraph<N, DirectedTag> const & g, 
+                             typename GridGraph<N, DirectedTag>::Node const & v,
+                             bool opposite=false)
+    : neighborOffsets_(0),
+      neighborIndices_(0),
+      edge_descriptor_(),
+      index_(0)
+    {
+        unsigned int nbtype = g.get_border_type(v);
+        init(&(*g.edgeIncrementArray())[nbtype], &(*g.neighborIndexArray(BackEdgesOnly))[nbtype], v, opposite);
+    }
+    
+    GridGraphOutEdgeIterator & operator++()
+    {
+        increment(false);
+        return *this;
+    }
+
+    GridGraphOutEdgeIterator  operator++(int)
+    {
+        GridGraphOutEdgeIterator ret(*this);
+        ++*this;
+        return ret;
+    }
+
+    const_reference operator*() const
+    {
+        return edge_descriptor_;
+    }
+
+    operator const_reference() const
+    {
+        return edge_descriptor_;
+    }
+
+    const_pointer operator->() const
+    {
+        return &edge_descriptor_;
+    }
+
+    index_type index() const
+    {
+        return index_;
+    }
+
+    index_type neighborIndex() const
+    {
+        return (*neighborIndices_)[index_];
+    }
+
+    arc_descriptor const & arcDescriptor() const
+    {
+        return edge_descriptor_;
+    }
+
+    bool operator==(GridGraphOutEdgeIterator const & other) const
+    {
+        return index_ == other.index();
+    }
+
+    bool operator!=(GridGraphOutEdgeIterator const & other) const
+    {
+        return index_ != other.index();
+    }
+
+    bool isValid() const 
+    {
+        return index_ < (index_type)neighborIndices_->size();
+    }
+
+    bool atEnd() const 
+    {
+        return index_ >= (index_type)neighborIndices_->size();
+    }
+
+    GridGraphOutEdgeIterator getEndIterator() const
+    {
+        GridGraphOutEdgeIterator res(*this);
+        res.index_ = (index_type)neighborIndices_->size();
+        return res;
+    }
+
+  protected:
+  
+        // for testing only
+    GridGraphOutEdgeIterator(ArrayVector<arc_descriptor> const & neighborOffsets,
+                             ArrayVector<index_type> const & neighborIndices,
+                             ArrayVector<index_type> const & backIndices,
+                             shape_type const & source)
+    : neighborOffsets_(0),
+      neighborIndices_(0),
+      edge_descriptor_(),
+      index_(0)
+    {
+        init(&neighborOffsets, BackEdgesOnly ? &backIndices : &neighborIndices, source);
+    }
+
+    void init(ArrayVector<arc_descriptor> const * neighborOffsets,
+              ArrayVector<index_type> const * neighborIndices,
+              shape_type const & source,
+              bool opposite=false)
+    {
+        neighborOffsets_ = neighborOffsets;
+        neighborIndices_ = neighborIndices;
+        edge_descriptor_ = arc_descriptor(source, 0);
+        index_ = 0;
+        updateEdgeDescriptor(opposite);
+    }
+
+    void increment(bool opposite)
+    {
+        ++index_;
+        updateEdgeDescriptor(opposite);
+    }
+
+    void updateEdgeDescriptor(bool opposite)
+    {
+        if(isValid())
+            edge_descriptor_.increment((*neighborOffsets_)[index_], opposite);
+    }
+  
+    ArrayVector<arc_descriptor> const * neighborOffsets_;
+    ArrayVector<index_type> const * neighborIndices_;
+    arc_descriptor edge_descriptor_;
+    index_type index_;
+};
+
+template<unsigned int N, bool BackEdgesOnly=false>
+class GridGraphOutArcIterator
+: public GridGraphOutEdgeIterator<N, BackEdgesOnly>
+{
+  public:
+    typedef GridGraphOutEdgeIterator<N, BackEdgesOnly>        base_type;
+    typedef typename MultiArrayShape<N>::type  shape_type;
+    typedef MultiArrayIndex                    index_type;
+    typedef GridGraphArcDescriptor<N>          value_type;
+    typedef value_type const &                 reference;
+    typedef value_type const &                 const_reference;
+    typedef value_type const *                 pointer;
+    typedef value_type const *                 const_pointer;
+    typedef MultiArrayIndex                    difference_type;
+    typedef std::forward_iterator_tag          iterator_category;
+
+    friend struct NeighborhoodTests<N>;
+    friend class GridGraphEdgeIterator<N, BackEdgesOnly>;
+
+    GridGraphOutArcIterator() 
+    : base_type()
+    {}
+
+    explicit GridGraphOutArcIterator(base_type const & b) 
+    : base_type(b)
+    {}
+
+    template <class DirectedTag>
+    GridGraphOutArcIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::NodeIt const & v)
+    : base_type(g, v)
+    {}
+
+    template <class DirectedTag>
+    GridGraphOutArcIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::Node const & v)
+    : base_type(g, v)
+    {}
+
+    GridGraphOutArcIterator & operator++()
+    {
+        base_type::operator++();
+        return *this;
+    }
+
+    GridGraphOutArcIterator  operator++(int)
+    {
+        GridGraphOutArcIterator ret(*this);
+        ++*this;
+        return ret;
+    }
+
+    const_reference operator*() const
+    {
+        return this->edge_descriptor_;
+    }
+
+    operator const_reference() const
+    {
+        return this->edge_descriptor_;
+    }
+
+    const_pointer operator->() const
+    {
+        return &this->edge_descriptor_;
+    }
+
+    GridGraphOutArcIterator getEndIterator() const
+    {
+        return GridGraphOutArcIterator(base_type::getEndIterator());
+    }
+    
+  protected:
+
+        // for testing only
+    GridGraphOutArcIterator(ArrayVector<value_type> const & neighborOffsets,
+                            ArrayVector<index_type> const & neighborIndices,
+                            ArrayVector<index_type> const & backIndices,
+                            shape_type const & source)
+    : base_type(neighborOffsets, neighborIndices, backIndices, source)
+    {}
+};
+
+template<unsigned int N, bool BackEdgesOnly=false>
+class GridGraphInArcIterator
+: public GridGraphOutEdgeIterator<N, BackEdgesOnly>
+{
+  public:
+    typedef GridGraphOutEdgeIterator<N, BackEdgesOnly>        base_type;
+    typedef typename MultiArrayShape<N>::type  shape_type;
+    typedef MultiArrayIndex                    index_type;
+    typedef GridGraphArcDescriptor<N>          value_type;
+    typedef value_type const &                 reference;
+    typedef value_type const &                 const_reference;
+    typedef value_type const *                 pointer;
+    typedef value_type const *                 const_pointer;
+    typedef MultiArrayIndex                    difference_type;
+    typedef std::forward_iterator_tag          iterator_category;
+
+    friend struct NeighborhoodTests<N>;
+
+    GridGraphInArcIterator() 
+    : base_type()
+    {}
+
+    explicit GridGraphInArcIterator(base_type const & b) 
+    : base_type(b)
+    {}
+
+    template <class DirectedTag>
+    GridGraphInArcIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::NodeIt const & v)
+    : base_type(g, v, true)
+    {}
+
+    template <class DirectedTag>
+    GridGraphInArcIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::Node const & v)
+    : base_type(g, v, true)
+    {}
+
+    GridGraphInArcIterator & operator++()
+    {
+        base_type::increment(true);
+        return *this;
+    }
+
+    GridGraphInArcIterator  operator++(int)
+    {
+        GridGraphInArcIterator ret(*this);
+        ++*this;
+        return ret;
+    }
+
+    const_reference operator*() const
+    {
+        return this->edge_descriptor_;
+    }
+
+    operator const_reference() const
+    {
+        return this->edge_descriptor_;
+    }
+
+    const_pointer operator->() const
+    {
+        return &this->edge_descriptor_;
+    }
+
+    GridGraphInArcIterator getEndIterator() const
+    {
+        return GridGraphInArcIterator(base_type::getEndIterator());
+    }
+};
+
+    // Edge iterator for directed and undirected graphs. 
+    // Composed of a vertex_iterator and an out_edge_iterator.
+template<unsigned int N, bool BackEdgesOnly>
+class GridGraphEdgeIterator
+{
+public:
+    typedef GridGraphEdgeIterator<N, BackEdgesOnly>      self_type;
+    typedef MultiCoordinateIterator<N>                   vertex_iterator;
+    typedef typename vertex_iterator::value_type         vertex_descriptor;
+    typedef GridGraphOutArcIterator<N, BackEdgesOnly>    out_edge_iterator;
+    typedef typename MultiArrayShape<N+1>::type          edge_descriptor;
+    typedef edge_descriptor                              value_type;
+    typedef value_type const *                           pointer;
+    typedef value_type const *                           const_pointer;
+    typedef value_type const &                           reference;
+    typedef value_type const &                           const_reference;
+    typedef typename MultiArrayShape<N>::type            shape_type;
+    typedef MultiArrayIndex                              difference_type;
+    typedef MultiArrayIndex                              index_type;
+    typedef std::forward_iterator_tag                    iterator_category;
+
+    friend struct NeighborhoodTests<N>;
+
+    GridGraphEdgeIterator() 
+    : neighborOffsets_(0),
+      neighborIndices_(0)
+    {}
+    
+    template <class DirectedTag>
+    GridGraphEdgeIterator(GridGraph<N, DirectedTag> const & g)
+    : neighborOffsets_(g.edgeIncrementArray()),
+      neighborIndices_(g.neighborIndexArray(BackEdgesOnly)),
+      vertexIterator_(g),
+      outEdgeIterator_(g, vertexIterator_)
+    {
+        if(outEdgeIterator_.atEnd()) // in a undirected graph, the first point stores no edges
+        {
+            ++vertexIterator_;
+            if(vertexIterator_.isValid())
+                outEdgeIterator_ = out_edge_iterator(g, vertexIterator_);
+        }
+    }
+
+    GridGraphEdgeIterator & operator++()
+    {
+        ++outEdgeIterator_;
+        if(outEdgeIterator_.atEnd())
+        {
+            ++vertexIterator_;
+            if(vertexIterator_.isValid())
+            {
+                unsigned int borderType = vertexIterator_.borderType();
+                outEdgeIterator_.init(&(*neighborOffsets_)[borderType], &(*neighborIndices_)[borderType], *vertexIterator_);
+            }
+        }
+        return *this;
+    }
+
+    GridGraphEdgeIterator  operator++(int)
+    {
+        GridGraphEdgeIterator ret(*this);
+        ++*this;
+        return ret;
+    }
+
+    const_reference operator*() const
+    {
+        return *outEdgeIterator_;
+    }
+
+    operator const_reference() const
+    {
+        return *outEdgeIterator_;
+    }
+
+    const_pointer operator->() const
+    {
+        return outEdgeIterator_.operator->();
+    }
+
+    bool operator==(GridGraphEdgeIterator const & other) const
+    {
+        return (vertexIterator_ == other.vertexIterator_ && outEdgeIterator_ == other.outEdgeIterator_);
+    }
+
+    bool operator!=(GridGraphEdgeIterator const & other) const
+    {
+        return !operator==(other);
+    }
+    
+    bool isValid() const
+    {
+        return vertexIterator_.isValid();
+    }
+    
+    bool atEnd() const
+    {
+        return !isValid();
+    }
+    
+    GridGraphEdgeIterator getEndIterator() const
+    {
+        GridGraphEdgeIterator ret(*this);
+        ret.vertexIterator_ = vertexIterator_.getEndIterator();
+        vertex_iterator lastVertex = ret.vertexIterator_ - 1;
+        unsigned int borderType = lastVertex.borderType();
+        ret.outEdgeIterator_.init(&(*neighborOffsets_)[borderType], &(*neighborIndices_)[borderType], *lastVertex);
+        ret.outEdgeIterator_ = ret.outEdgeIterator_.getEndIterator();
+        return ret;
+    }
+
+   protected:
+   
+        // for testing only
+    GridGraphEdgeIterator(ArrayVector<ArrayVector<typename out_edge_iterator::value_type> > const & neighborOffsets,
+                          ArrayVector<ArrayVector<index_type> > const & neighborIndices,
+                          ArrayVector<ArrayVector<index_type> > const & backIndices,
+                          shape_type const & shape)
+    : neighborOffsets_(&neighborOffsets),
+      neighborIndices_(BackEdgesOnly ? &backIndices : &neighborIndices),
+      vertexIterator_(shape),
+      outEdgeIterator_(neighborOffsets[vertexIterator_.borderType()], 
+                       neighborIndices[vertexIterator_.borderType()], 
+                       backIndices[vertexIterator_.borderType()], shape_type())
+    {
+        if(outEdgeIterator_.atEnd()) // in a undirected graph, the first point stores no edges
+        {
+            ++vertexIterator_;
+            if(vertexIterator_.isValid())
+            {
+                unsigned int borderType = vertexIterator_.borderType();
+                outEdgeIterator_.init(&(*neighborOffsets_)[borderType], &(*neighborIndices_)[borderType], *vertexIterator_);
+            }
+        }
+    }
+
+    ArrayVector<ArrayVector<typename out_edge_iterator::value_type> > const * neighborOffsets_;
+    ArrayVector<ArrayVector<index_type> > const * neighborIndices_;
+    vertex_iterator vertexIterator_;
+    out_edge_iterator outEdgeIterator_;
+};
+
+template<unsigned int N, bool BackEdgesOnly>
+class GridGraphArcIterator
+: public GridGraphEdgeIterator<N, BackEdgesOnly>
+{
+public:
+    typedef GridGraphEdgeIterator<N, BackEdgesOnly>              base_type;
+    typedef GridGraphArcIterator<N, BackEdgesOnly>               self_type;
+    typedef MultiCoordinateIterator<N>                           vertex_iterator;
+    typedef typename vertex_iterator::value_type                 vertex_descriptor;
+    typedef GridGraphOutArcIterator<N, BackEdgesOnly>            out_edge_iterator;
+    typedef typename out_edge_iterator::value_type               edge_descriptor;
+    typedef edge_descriptor                                      value_type;
+    typedef value_type const *                                   pointer;
+    typedef value_type const *                                   const_pointer;
+    typedef value_type const &                                   reference;
+    typedef value_type const &                                   const_reference;
+    typedef typename MultiArrayShape<N>::type                    shape_type;
+    typedef MultiArrayIndex                                      difference_type;
+    typedef MultiArrayIndex                                      index_type;
+    typedef std::forward_iterator_tag                            iterator_category;
+
+    friend struct NeighborhoodTests<N>;
+
+    GridGraphArcIterator() 
+    : base_type()
+    {}
+
+    explicit GridGraphArcIterator(base_type const & b) 
+    : base_type(b)
+    {}
+
+    template <class DirectedTag>
+    GridGraphArcIterator(GridGraph<N, DirectedTag> const & g)
+    : base_type(g)
+    {}
+
+    GridGraphArcIterator & operator++()
+    {
+        base_type::operator++();
+        return *this;
+    }
+
+    GridGraphArcIterator  operator++(int)
+    {
+        GridGraphArcIterator ret(*this);
+        ++*this;
+        return ret;
+    }
+
+    const_reference operator*() const
+    {
+        return *(this->outEdgeIterator_);
+    }
+
+    operator const_reference() const
+    {
+        return *(this->outEdgeIterator_);
+    }
+
+    const_pointer operator->() const
+    {
+        return this->outEdgeIterator_.operator->();
+    }
+    
+    GridGraphArcIterator getEndIterator() const
+    {
+        return GridGraphArcIterator(base_type::getEndIterator());
+    }
+
+  protected:
+  
+        // for testing only
+    GridGraphArcIterator(ArrayVector<ArrayVector<value_type> > const & neighborOffsets,
+                          ArrayVector<ArrayVector<index_type> > const & neighborIndices,
+                          ArrayVector<ArrayVector<index_type> > const & backIndices,
+                          shape_type const & shape)
+    : base_type(neighborOffsets, neighborIndices, backIndices, shape)
+    {}
+};
+
+template<unsigned int N>
+inline bool operator==(MultiCoordinateIterator<N> const & i, lemon::Invalid)
+{
+    return i.atEnd();
+}
+
+template<unsigned int N>
+inline bool operator!=(MultiCoordinateIterator<N> const & i, lemon::Invalid)
+{
+    return i.isValid();
+}
+
+template<unsigned int N>
+inline bool operator==(lemon::Invalid, MultiCoordinateIterator<N> const & i)
+{
+    return i.atEnd();
+}
+
+template<unsigned int N>
+inline bool operator!=(lemon::Invalid, MultiCoordinateIterator<N> const & i)
+{
+    return i.isValid();
+}
+
+#define VIGRA_LEMON_INVALID_COMPARISON(type) \
+template<unsigned int N, bool BackEdgesOnly> \
+inline bool operator==(type<N, BackEdgesOnly> const & i, lemon::Invalid) \
+{ \
+    return i.atEnd(); \
+} \
+template<unsigned int N, bool BackEdgesOnly> \
+inline bool operator!=(type<N, BackEdgesOnly> const & i, lemon::Invalid) \
+{ \
+    return i.isValid(); \
+} \
+template<unsigned int N, bool BackEdgesOnly> \
+inline bool operator==(lemon::Invalid, type<N, BackEdgesOnly> const & i) \
+{ \
+    return i.atEnd(); \
+} \
+template<unsigned int N, bool BackEdgesOnly> \
+inline bool operator!=(lemon::Invalid, type<N, BackEdgesOnly> const & i) \
+{ \
+    return i.isValid(); \
+}
+
+VIGRA_LEMON_INVALID_COMPARISON(GridGraphNeighborIterator)
+VIGRA_LEMON_INVALID_COMPARISON(GridGraphOutEdgeIterator)
+VIGRA_LEMON_INVALID_COMPARISON(GridGraphOutArcIterator)
+VIGRA_LEMON_INVALID_COMPARISON(GridGraphInArcIterator)
+VIGRA_LEMON_INVALID_COMPARISON(GridGraphEdgeIterator)
+VIGRA_LEMON_INVALID_COMPARISON(GridGraphArcIterator)
+
+#undef VIGRA_LEMON_INVALID_COMPARISON
+
+using boost::directed_tag;
+using boost::undirected_tag;
+
+namespace detail {
+
+template <unsigned int N, class DirectedTag>
+struct GridGraphBase;
+
+template <unsigned int N>
+struct GridGraphBase<N, directed_tag>
+{
+    template <class T>
+    class ArcMap
+    : public MultiArray<N+1, Multiband<T> >
+    {
+      public:
+        typedef MultiArray<N+1, Multiband<T> >             base_type;
+        typedef typename base_type::difference_type        difference_type;
+        typedef typename base_type::key_type               key_type;
+        typedef typename base_type::value_type             value_type; 
+        typedef typename base_type::reference              reference;
+        typedef typename base_type::const_reference        const_reference;
+        typedef boost::read_write_property_map_tag         category;
+        
+        typedef lemon::True                                ReferenceMapTag;
+        typedef key_type                                   Key;
+        typedef value_type                                 Value;
+        typedef reference                                  Reference;
+        typedef const_reference                            ConstReference;
+
+        ArcMap()
+        : base_type()
+        {}
+        
+        explicit ArcMap(GridGraph<N, directed_tag> const & g)
+        : base_type(g.arc_propmap_shape())
+        {}
+        
+        ArcMap(GridGraph<N, directed_tag> const & g, T const & t)
+        : base_type(g.arc_propmap_shape(), t)
+        {}
+
+        explicit ArcMap(difference_type const & shape)
+        : base_type(shape)
+        {}
+        
+        ArcMap(difference_type const & shape, T const & t)
+        : base_type(shape, t)
+        {}
+        
+        ArcMap & operator=(ArcMap const & m)
+        {
+            base_type::operator=(m);
+            return *this;
+        }
+        
+        ArcMap & operator=(base_type const & m)
+        {
+            base_type::operator=(m);
+            return *this;
+        }
+        
+        // appropriate operator[] are inherited
+        
+        void set(Key const & k, Value const & v)
+        {
+            (*this)[k] = v;
+        }
+    };
+};
+
+template <unsigned int N>
+struct GridGraphBase<N, undirected_tag>
+{
+    typedef lemon::True UndirectedTag;
+    
+    template <class T>
+    class ArcMap
+    : public MultiArray<N+1, Multiband<T> >
+    {
+      public:
+        typedef MultiArray<N+1, Multiband<T> >             base_type;
+        typedef GridGraphArcDescriptor<N>                  difference_type;
+        typedef difference_type                            key_type;
+        typedef typename base_type::value_type             value_type; 
+        typedef typename base_type::reference              reference;
+        typedef typename base_type::const_reference        const_reference;
+        typedef boost::read_write_property_map_tag         category;
+        
+        typedef lemon::True                                ReferenceMapTag;
+        typedef key_type                                   Key;
+        typedef value_type                                 Value;
+        typedef reference                                  Reference;
+        typedef const_reference                            ConstReference;
+        
+        ArcMap()
+        : base_type()
+        {}
+        
+        explicit ArcMap(GridGraph<N, undirected_tag> const & g)
+        : base_type(g.arc_propmap_shape()),
+          graph_(&g)
+        {}
+        
+        ArcMap(GridGraph<N, undirected_tag> const & g, T const & t)
+        : base_type(g.arc_propmap_shape(), t),
+          graph_(&g)
+        {}
+        
+        ArcMap & operator=(ArcMap const & m)
+        {
+            base_type::operator=(m);
+            return *this;
+        }
+        
+        ArcMap & operator=(base_type const & m)
+        {
+            base_type::operator=(m);
+            return *this;
+        }
+        
+        reference operator[](difference_type const & s)
+        {
+            if(s.isReversed())
+            {
+                return base_type::operator[](graph_->directedArc(s));
+            }
+            else
+            {
+                return base_type::operator[](s);
+            }
+        }
+        
+        const_reference operator[](difference_type const & s) const
+        {
+            if(s.isReversed())
+            {
+                return base_type::operator[](graph_->directedArc(s));
+            }
+            else
+            {
+                return base_type::operator[](s);
+            }
+        }
+        
+        void set(Key const & k, Value const & v)
+        {
+            (*this)[k] = v;
+        }
+        
+        GridGraph<N, undirected_tag> const * graph_;
+    };
+};
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*                      GridGraph                       */
+/*                                                      */
+/********************************************************/
+
+/** \brief Define a grid graph in arbitrary dimensions.
+
+    A GridGraph connects each pixel to its direct or indirect neighbors. 
+    Direct neighbors are the adjacent point along the coordinate axes, 
+    whereas indirect neighbors include the diagonally adjacent points. Thus, 
+    direct neighbors correspond to the 4-neighborhood in 2D and the 
+    6-neighborhood in 3D, whereas indirect neighbors correspond to the 
+    8-neighborhood and 26-neighborhood respectively. The GridGraph class 
+    extends this scheme to arbitrary dimensions. While the dimension must be 
+    defined at compile time via the template parameter <tt>N</tt>, the 
+    desired neighborhood can be chosen at runtime in the GridGraph's 
+    constructor. The shape of the grid is also specified at runtime in terms 
+    of a suitable shape object. 
+
+    Another choice to be made at compile time is whether the graph should be directed 
+    or undirected. This is defined via the <tt>DirectedTag</tt> template parameter
+    which can take the values <tt>directed_tag</tt> or <tt>undirected_tag</tt>.
+    
+    The main difficulty in a grid graph is to skip the missing neighbors
+    of the pixels near the grid's border. For example, the upper left pixel in a 
+    2D grid has only two direct neighbors instead of the usual four. The GridGraph
+    class uses a precomputed set of internal look-up tables to efficiently determine the 
+    appropriate number and location of the existing neighbors. A key design decision 
+    to make this fast was to give up the requirement that edge IDs are contiguous 
+    integers (as in LEMON's implementation of a 2D grid graph, which became very
+    complicated and slow by enforcing this requirement). Instead, edges are numbered 
+    as if all nodes (including nodes at the grid's border) had the same degree.
+    Since edges crossing the border are not actually present in the graph, these IDs 
+    are missing, leading to gaps in the sequence of IDs. 
+    
+    For the sake of compatibility, the GridGraph class implements two 
+    popular graph APIs: the one defined by the <a href="http://www.boost.org/doc/libs/release/libs/graph/">boost::graph</a> library and
+    the one defined by the <a href="http://lemon.cs.elte.hu/">LEMON</a> library.
+    Their basic principles are very similar: The graph's nodes, edges and adjacency
+    structure are accessed via a set of iterators, whereas additional properties
+    (like node and edge weights) are provided via <i>property maps</i> that are
+    indexed with suitable node or edge descriptor objects returned by the iterators.
+    
+    Specifically, GridGraph implements the requirements of the following <a href="http://www.boost.org/doc/libs/release/libs/graph/doc/graph_concepts.html">concepts of the 
+    boost::graph API</a>: <b>Graph, IncidenceGraph, BidirectionalGraph, AdjacencyGraph, 
+    VertexListGraph, EdgeListGraph,</b> and <b>AdjacencyMatrix</b>. Likewise, it supports 
+    the concepts <b>Graph</b> and <b>Digraph</b> of the LEMON API. The property maps 
+    associated with a GridGraph support the boost concepts ReadablePropertyMap, 
+    WritablePropertyMap, ReadWritePropertyMap, and LvaluePropertyMap as well as the 
+    LEMON concepts ReadMap, WriteMap, ReadWriteMap, and ReferenceMap.
+    
+    VIGRA's GridGraph class is designed such that multi-dimensional coordinates
+    (i.e. <tt>TinyVector<MultiArrayIndex></tt>) serve as descriptor objects, which means
+    that normal <tt>MultiArray</tt>s or <tt>MultiArrayView</tt>s can serve as property
+    maps in most situations. Thus, node properties like a foreground probability for 
+    foreground/background segmentation can simply be stored as normal images.
+    
+    Since the boost::graph and LEMON APIs differ in how they call corresponding
+    functionality (e.g., they use the terms <tt>vertex</tt> and <tt>node</tt> respectively
+    in an exactly synonymous way), most GridGraph helper classes and functions are exposed 
+    under two different names. To implement your own algorithms, you can choose the API 
+    you like most. VIGRA adopts the convention that algorithms using the boost::graph 
+    API go into the namespace <tt>vigra::boost_graph</tt>, while those using the 
+    LEMON API are placed into the namespace <tt>vigra::lemon_graph</tt>. This helps 
+    to avoid name clashes when the two APIs happen to use the same name for different 
+    things. The documentation of the GridGraph members specifies which API the respective
+    function or class belongs to. Please consult the documentation of these 
+    libraries for tutorial introductions and full reference of the respective APIs.
+    
+    VIGRA adds an important new concept of its own: the back neighborhood
+    and associated adjacency and edge iterators. The back neighborhood of a given vertex 
+    with ID <tt>i</tt> is the set of all neighbor vertices whose ID is smaller than <tt>i</tt>.
+    This concept is useful if you work on the grid graph's vertices in scan order
+    and want to access just those neighbors that have already been processed. Connected
+    components labeling is a typical example of an algorithm that can take advantage of this 
+    possibility. In principle, a back neighborhood iterator could be implemented as
+    a filter iterator that simply skips all neighbors with inappropriate IDs. However,
+    in case of grid graphs it is more efficient to provide a special iterator for this purpose.
+    
+    <b>Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_gridgraph.hxx\> <br/>
+    Namespace: vigra
+    
+    At present, the GridGraph class is mainly used internally to implement image 
+    analysis functions for arbitrary dimensional arrays (e.g. detection of local 
+    extrema, connected components labeling, watersheds, SLIC superpixels). For example,
+    a dimension-independent algorithm to detect local maxima using the LEMON API
+    might look like this:
+    
+    \code
+    namespace vigra { namespace lemon_graph { 
+
+    template <class Graph, class InputMap, class OutputMap>
+    void
+    localMaxima(Graph const & g, 
+                InputMap const & src,
+                OutputMap & local_maxima,
+                typename OutputMap::value_type marker)
+    {
+        // define abreviations for the required iterators
+        typedef typename Graph::NodeIt    graph_scanner;
+        typedef typename Graph::OutArcIt  neighbor_iterator;
+
+        // iterate over all nodes (i.e. pixels)
+        for (graph_scanner node(g); node != INVALID; ++node) 
+        {
+            // remember the value of the current node
+            typename InputMap::value_type current = src[*node];
+
+            // iterate over all neighbors of the current node
+            bool is_local_maximum = true;
+            for (neighbor_iterator arc(g, node); arc != INVALID; ++arc)
+            {
+                // if a neighbor has larger value, the center node is not a local maximum
+                if (current < src[g.target(*arc)]) 
+                    is_local_maximum = false;
+            }
+            
+            // mark the node when it is a local maximum
+            if (is_local_maximum)
+                local_maxima[*node] = marker;
+        }
+    }
+    
+    }} // namespace vigra::lemon_graph
+    \endcode
+    
+    It should be noted that this algorithm will work for any LEMON-compatible graph class, 
+    not just our GridGraph. When implemented in terms of the boost::graph API, the same algorithm
+    looks like this:
+    
+    \code
+    namespace vigra { namespace boost_graph {
+
+    template <class Graph, class InputMap, class OutputMap>
+    void
+    localMaxima(Graph const & g, 
+                InputMap const & src,
+                OutputMap & local_maxima,
+                typename property_traits<OutputMap>::value_type marker)
+    {
+        // define abreviations and variables for the required iterators
+        typedef typename graph_traits<Graph>::vertex_iterator graph_scanner;
+        typedef typename graph_traits<Graph>::adjacency_iterator neighbor_iterator;
+
+        graph_scanner      node, node_end;
+        neighbor_iterator  arc, arc_end;
+
+        // iterate over all nodes (i.e. pixels)
+        tie(node, node_end) = vertices(g);
+        for (; node != node_end; ++node) 
+        {
+            // remember the value of the current node
+            typename property_traits<InputMap>::value_type current = get(src, *node);
+
+            // iterate over all neighbors of the current node
+            bool is_local_maximum = true;
+            tie(arc, arc_end) = adjacent_vertices(*node, g);
+            for (;arc != arc_end; ++arc)
+            {
+                // if a neighbor has larger value, the center node is not a local maximum
+                if (current < get(src, *arc))
+                    is_local_maximum = false;
+            }
+            
+            // mark the node when it is a local maximum
+            if (is_local_maximum)
+                put(local_maxima, *node, marker);
+        }
+    }
+
+    }} // namespace vigra::boost_graph
+    \endcode
+    
+    It can be seen that the differences between the APIs are mainly syntactic 
+    (especially note that boost::graph users traits classes and free functions, 
+    whereas LEMON uses nested typedefs and member functions). Either of these 
+    algorithms can now serve as the backend of a local maxima detector 
+    for <tt>MultiArrayViews</tt>:
+    
+    \code
+    namespace vigra {
+    
+    template <unsigned int N, class T1, 
+                              class T2>
+    void
+    localMaxima(MultiArrayView<N, T1> const & src,
+                MultiArrayView<N, T2> local_maxima,
+                T2 marker,
+                NeighborhoodType neighborhood = IndirectNeighborhood)
+    {
+        vigra_precondition(src.shape() == local_maxima.shape(),
+            "localMinMax(): shape mismatch between input and output.");
+        
+        // create a grid graph with appropriate shape and desired neighborhood
+        GridGraph<N, undirected_tag> graph(src.shape(), neighborhood);
+        
+        // forward the call to the graph-based algorithm, using 
+        // the given MultiArrayViews as property maps
+        lemon_graph::localMaxima(graph, src, local_maxima, marker);
+    }
+
+    } // namespace vigra
+    \endcode
+    
+    A slightly enhanced version of this code is actually used to implement this
+    functionality in VIGRA.
+*/
+template<unsigned int N, class DirectedTag>
+class GridGraph
+: public detail::GridGraphBase<N, DirectedTag>
+{
+public:
+        /** \brief 'true' if the graph is directed (API: boost::graph)
+        */
+    static const bool is_directed = IsSameType<DirectedTag, directed_tag>::value;
+    
+    typedef detail::GridGraphBase<N, DirectedTag>   base_type;
+    typedef GridGraph<N, DirectedTag>               self_type;
+    
+        /** \brief Shape type of the graph and a node property map.
+        */
+    typedef typename MultiArrayShape<N>::type       shape_type;
+    
+        /** \brief Shape type of an edge property map (must have one additional dimension).
+        */
+    typedef typename MultiArrayShape<N+1>::type     edge_propmap_shape_type;    
+    
+        /** \brief Type of node and edge IDs.
+        */
+    typedef MultiArrayIndex                         index_type;
+    
+        /** \brief Type to specify number of vertices (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::vertices_size_type</tt>).
+        */
+    typedef MultiArrayIndex                         vertices_size_type;
+    
+        /** \brief Type to specify number of edges (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::edges_size_type</tt>).
+        */
+    typedef MultiArrayIndex                         edges_size_type;
+    
+        /** \brief Type to specify number of neighbors (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::degree_size_type</tt>).
+        */
+    typedef MultiArrayIndex                         degree_size_type;
+
+        /** \brief Iterator over the vertices of the graph (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::vertex_iterator</tt>).
+        */
+    typedef MultiCoordinateIterator<N>              vertex_iterator;
+    
+        /** \brief Iterator over the neighbor vertices of a given vertex (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::adjacency_iterator</tt>).
+        */
+    typedef GridGraphNeighborIterator<N>            adjacency_iterator;
+    
+        /** \brief Same as adjacency_iterator (API: VIGRA).
+        */
+    typedef adjacency_iterator                      neighbor_vertex_iterator;
+    
+        /** \brief Iterator over only those neighbor vertices of a given vertex 
+                   that have smaller ID (API: VIGRA).
+        */
+    typedef GridGraphNeighborIterator<N, true>      back_neighbor_vertex_iterator;
+    
+        /** \brief Iterator over the incoming edges of a given vertex (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::in_edge_iterator</tt>).
+        */
+    typedef GridGraphInArcIterator<N>               in_edge_iterator;
+    
+        /** \brief Iterator over the outgoing edges of a given vertex (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::out_edge_iterator</tt>).
+        */
+    typedef GridGraphOutArcIterator<N>              out_edge_iterator;
+    
+        /** \brief Iterator over only those outgoing edges of a given vertex
+                   that go to vertices with smaller IDs (API: VIGRA).
+        */
+    typedef GridGraphOutArcIterator<N, true>        out_back_edge_iterator;
+    
+        /** \brief Iterator over the edges of a graph (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::edge_iterator</tt>).
+        */
+    typedef GridGraphArcIterator<N, !is_directed>   edge_iterator;
+    
+        /** \brief The vertex descriptor (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::vertex_descriptor</tt>).
+        */
+    typedef shape_type                              vertex_descriptor;
+    
+        /** \brief The edge descriptor (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::edge_descriptor</tt>).
+        */
+    typedef GridGraphArcDescriptor<N>               edge_descriptor;
+     
+        /** \brief Is the graph directed or undirected ? (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::directed_category</tt>).
+        */
+    typedef DirectedTag                             directed_category;
+    
+        /** \brief The graph does not allow multiple edges between the same vertices 
+                  (API: boost::graph, use via 
+                  <tt>boost::graph_traits<Graph>::edge_parallel_category</tt>).
+        */
+    typedef boost::disallow_parallel_edge_tag       edge_parallel_category;
+    
+        /** \brief The graph does not define internal property maps (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::vertex_property_type</tt>).
+        */
+    typedef boost::no_property                      vertex_property_type; // we only support "external properties".
+    // FIXME: Maybe support the vertex -> coordinate map (identity) as the only internal property map
+    // and additionally the vertex_descriptor -> ID map (vertex_index = SOI).
+
+        /** \brief Define several graph tags related to graph traversal (API: boost::graph,
+             use via <tt>boost::graph_traits<Graph>::traversal_category</tt>).
+        */
+    struct traversal_category 
+    : virtual public boost::bidirectional_graph_tag,
+      virtual public boost::adjacency_graph_tag,
+      virtual public boost::vertex_list_graph_tag,
+      virtual public boost::edge_list_graph_tag,
+      virtual public boost::adjacency_matrix_tag
+    {};
+    
+        // internal types
+    typedef ArrayVector<shape_type>                      NeighborOffsetArray;
+    typedef ArrayVector<NeighborOffsetArray>             RelativeNeighborOffsetsArray;
+    typedef ArrayVector<ArrayVector<edge_descriptor> >   RelativeEdgeOffsetsArray;
+    typedef ArrayVector<ArrayVector<MultiArrayIndex> >   IndexArray;
+
+    ////////////////////////////////////////////////////////////////////
+    
+    // LEMON interface
+    typedef self_type                               Graph;
+    
+        /** \brief The Node descriptor (API: LEMON).
+        */
+    typedef vertex_descriptor                       Node;
+    
+        /** \brief Iterator over all nodes of the graph (API: LEMON).
+        */
+    typedef vertex_iterator                         NodeIt;
+    
+        /** \brief The arc (directed edge) descriptor (API: LEMON).
+        */
+    typedef GridGraphArcDescriptor<N>               Arc;
+    
+        /** \brief Iterator over the outgoing edges of a node (API: LEMON).
+        */
+    typedef GridGraphOutArcIterator<N>              OutArcIt;
+    
+        /** \brief Iterator over only those outgoing edges of a node
+            that end in a node with smaller ID (API: VIGRA).
+        */
+    typedef GridGraphOutArcIterator<N, true>        OutBackArcIt;
+    
+        /** \brief Iterator over the acrs (directed edges) of a node (API: LEMON).
+        */
+    typedef GridGraphArcIterator<N, false>          ArcIt;
+    
+        /** \brief Iterator over the incoming arcs of a node (API: LEMON).
+        */
+    typedef GridGraphInArcIterator<N>               InArcIt;
+    
+        /** \brief The edge descriptor (API: LEMON).
+        */
+    typedef typename MultiArrayShape<N+1>::type     Edge;
+    
+        /** \brief Iterator over the incident edges of a node (API: LEMON).
+        */
+    typedef GridGraphOutEdgeIterator<N>             IncEdgeIt;
+    
+        /** \brief Iterator over only those incident edges of a node that
+            end in a node with smaller ID (API: VIGRA).
+        */
+    typedef GridGraphOutEdgeIterator<N, true>       IncBackEdgeIt;
+    
+        /** \brief Iterator over the edges of the graph (API: LEMON).
+        */
+    typedef GridGraphEdgeIterator<N, !is_directed>  EdgeIt;
+    
+    typedef lemon::True NodeNumTag;
+    typedef lemon::True EdgeNumTag;
+    typedef lemon::True ArcNumTag;
+    typedef lemon::True FindEdgeTag;
+    typedef lemon::True FindArcTag;
+    
+    ////////////////////////////////////////////////////////////////////
+    
+        /** \brief Type of a node property map that maps node descriptor objects 
+            onto property values of type <tt>T</tt> (API: LEMON).
+        */
+    template <class T>
+    class NodeMap
+    : public MultiArray<N, T>
+    {
+      public:
+        typedef MultiArray<N, T> base_type;
+        typedef typename base_type::difference_type        difference_type;
+        typedef typename base_type::key_type               key_type;
+        typedef typename base_type::value_type             value_type; 
+        typedef typename base_type::reference              reference;
+        typedef typename base_type::const_reference        const_reference;
+        typedef boost::read_write_property_map_tag         category;
+        
+        typedef lemon::True                                ReferenceMapTag;
+        typedef key_type                                   Key;
+        typedef value_type                                 Value;
+        typedef reference                                  Reference;
+        typedef const_reference                            ConstReference;
+
+        NodeMap()
+        : base_type()
+        {}
+        
+            /** \brief Construct property map for the given graph \a g
+                (preallocates a zero-initialized entry for each node of the graph).
+            */
+        explicit NodeMap(GridGraph const & g)
+        : base_type(g.shape())
+        {}
+        
+            /** \brief Construct property map for the given graph \a g
+                (preallocates an entry with initial value \a t for each node of the graph).
+            */
+        NodeMap(GridGraph const & g, T const & t)
+        : base_type(g.shape(), t)
+        {}
+
+            /** \brief Construct property map for the given \a shape.
+                (preallocates a zero-initialized entry for each node of a grid
+                graph with this shape).
+            */
+        explicit NodeMap(difference_type const & shape)
+        : base_type(shape)
+        {}
+        
+            /** \brief Construct property map for the given \a shape.
+                (preallocates an entry with initial value \a t for each node of a grid
+                graph with this shape).
+            */
+        NodeMap(difference_type const & shape, T const & t)
+        : base_type(shape, t)
+        {}
+        
+        NodeMap & operator=(NodeMap const & m)
+        {
+            base_type::operator=(m);
+            return *this;
+        }
+        
+        NodeMap & operator=(base_type const & m)
+        {
+            base_type::operator=(m);
+            return *this;
+        }
+        
+        // appropriate operator[] are inherited
+#ifdef DOXYGEN
+            /** \brief Read/write access to the value associated with node descriptor \a key.
+            */
+        Value & operator[](Key const & key);
+
+            /** \brief Read-only access to the value associated with node descriptor \a key.
+            */
+        Value const & operator[](Key const & key) const;
+#endif // DOXYGEN
+        
+            /** \brief Set the property of node desctiptor \a key to value \a v.
+            */
+        void set(Key const & k, Value const & v)
+        {
+            (*this)[k] = v;
+        }
+    };
+    
+    
+        /** \brief Type of an edge property map that maps edge descriptor objects 
+            onto property values of type <tt>T</tt> (API: LEMON).
+        */
+    template <class T>
+    class EdgeMap
+    : public MultiArray<N+1, Multiband<T> >
+    {
+      public:
+        typedef MultiArray<N+1, Multiband<T> >             base_type;
+        typedef typename base_type::difference_type        difference_type;
+        typedef typename base_type::key_type               key_type;
+        typedef typename base_type::value_type             value_type; 
+        typedef typename base_type::reference              reference;
+        typedef typename base_type::const_reference        const_reference;
+        typedef boost::read_write_property_map_tag         category;
+        
+        typedef lemon::True                                ReferenceMapTag;
+        typedef key_type                                   Key;
+        typedef value_type                                 Value;
+        typedef reference                                  Reference;
+        typedef const_reference                            ConstReference;
+
+        EdgeMap()
+        : base_type()
+        {}
+        
+            /** \brief Construct property map for the given graph \a g
+                (preallocates a zero-initialized entry for each edge of the graph).
+            */
+        explicit EdgeMap(GridGraph const & g)
+        : base_type(g.edge_propmap_shape())
+        {}
+        
+            /** \brief Construct property map for the given graph \a g
+                (preallocates an entry with initial value \a t for each edge of the graph).
+            */
+        EdgeMap(GridGraph const & g, T const & t)
+        : base_type(g.edge_propmap_shape(), t)
+        {}
+
+            /** \brief Construct property map for the given \a shape
+                (preallocates a zero-initialized entry for each edge of 
+                a grid graph with this shape).
+            */
+        explicit EdgeMap(difference_type const & shape)
+        : base_type(shape)
+        {}
+        
+            /** \brief Construct property map for the given \a shape
+                (preallocates an entry with initial value \a t for each edge 
+                of a grid graph with this shape).
+            */
+        EdgeMap(difference_type const & shape, T const & t)
+        : base_type(shape, t)
+        {}
+        
+        EdgeMap & operator=(EdgeMap const & m)
+        {
+            base_type::operator=(m);
+            return *this;
+        }
+        
+        EdgeMap & operator=(base_type const & m)
+        {
+            base_type::operator=(m);
+            return *this;
+        }
+        
+        // appropriate operator[] are inherited
+#ifdef DOXYGEN
+            /** \brief Read/write access to the value associated with edge descriptor \a key.
+            */
+        Value & operator[](Key const & key);
+
+            /** \brief Read-only access to the value associated with edge descriptor \a key.
+            */
+        Value const & operator[](Key const & key) const;
+#endif // DOXYGEN
+        
+            /** \brief Set the property of edge desctiptor \a key to value \a v.
+            */
+        void set(Key const & k, Value const & v)
+        {
+            (*this)[k] = v;
+        }
+    };
+
+#ifdef DOXYGEN
+        /** \brief Type of an arc property map that maps arc descriptor objects 
+            onto property values of type <tt>T</tt> (API: LEMON).
+        */
+    template <class T>
+    class ArcMap
+    : public MultiArray<N+1, Multiband<T> >
+    {
+      public:
+        
+            /** \brief Construct property map for the given graph \a g
+                (preallocates a zero-initialized entry for each arc of the graph).
+            */
+        explicit ArcMap(GridGraph const & g);
+        
+            /** \brief Construct property map for the given graph \a g
+                (preallocates an entry with initial value \a t for each arc of the graph).
+            */
+        ArcMap(GridGraph const & g, T const & t);
+
+            /** \brief Construct property map for the given \a shape
+                (preallocates a zero-initialized entry for each arc of 
+                a grid graph with this shape).
+            */
+        explicit ArcMap(difference_type const & shape);
+        
+            /** \brief Construct property map for the given \a shape
+                (preallocates an entry with initial value \a t for each arc of 
+                a grid graph with this shape).
+            */
+        ArcMap(difference_type const & shape, T const & t);
+
+            /** \brief Read/write access to the value associated with arc descriptor \a key.
+            */
+        Value & operator[](Key const & key);
+
+            /** \brief Read-only access to the value associated with arc descriptor \a key.
+            */
+        Value const & operator[](Key const & key) const;
+        
+            /** \brief Set the property of arc desctiptor \a key to value \a v.
+            */
+        void set(Key const & k, Value const & v);
+    };
+#endif // DOXYGEN
+
+        /** \brief Type of a property map that returns the coordinate of a given node (API: LEMON).
+        */
+    class IndexMap 
+    {
+      public:
+        typedef Node                                    Key;
+        typedef Node                                    Value;
+        typedef Key                                     key_type;
+        typedef Value                                   value_type; 
+        typedef Value const &                           reference;
+        typedef boost::readable_property_map_tag        category;
+
+        IndexMap()
+        {}
+
+            /** \brief Construct property map for the given graph.
+            */
+        explicit IndexMap(const GridGraph&)
+        {}
+
+            /** \brief Get the grid coordinate of the node descriptor \a key.
+            */
+        Value const & operator[](Key const & key) const 
+        {
+            return key;
+        }
+    };
+        
+        /** \brief Type of a property map that returns the number of incoming edges of a given node (API: LEMON, use via <tt>lemon::InDegMap<Graph></tt>).
+        */
+    class InDegMap
+    {
+      public:
+      
+        /// The graph type of InDegMap (works for directed and undirected graphs)
+        typedef GridGraph                               Graph;
+        typedef GridGraph                               Digraph;
+        typedef Node                                    Key;
+        typedef degree_size_type                        Value;
+        typedef Key                                     key_type;
+        typedef Value                                   value_type; 
+        typedef Value const &                           reference;
+        typedef boost::readable_property_map_tag        category;
+        
+            /** \brief Construct property map for the given graph.
+            */
+        explicit InDegMap(const GridGraph& graph)
+        : graph_(graph)
+        {}
+        
+            /** \brief Get the in-degree of the node descriptor \a key.
+            */
+        Value operator[](const Key& key) const 
+        {
+            return graph_.in_degree(key);
+        }
+        
+      protected:
+      
+        GridGraph const & graph_;
+    };
+
+        /** \brief Type of a property map that returns the number of outgoing edges of a given node (API: LEMON, use via <tt>lemon::OutDegMap<Graph></tt>).
+        */
+    class OutDegMap
+    {
+      public:
+      
+        /// The graph type of OutDegMap (works for directed and undirected graphs)
+        typedef GridGraph                               Graph;
+        typedef GridGraph                               Digraph;
+        typedef Node                                    Key;
+        typedef degree_size_type                        Value;
+        typedef Key                                     key_type;
+        typedef Value                                   value_type; 
+        typedef Value const &                           reference;
+        typedef boost::readable_property_map_tag        category;
+        
+            /** \brief Construct property map for the given graph.
+            */
+        explicit OutDegMap(const GridGraph& graph)
+        : graph_(graph)
+        {}
+        
+            /** \brief Get the out-degree of the node descriptor \a key.
+            */
+        Value operator[](const Key& key) const 
+        {
+            return graph_.out_degree(key);
+        }
+        
+      protected:
+      
+        GridGraph const & graph_;
+    };
+    
+    ////////////////////////////////////////////////////////////////////
+    
+        // dummy default constructor to satisfy adjacency_graph concept
+    GridGraph()
+    {}
+        
+        /** \brief Construct a grid graph with given \a shape and neighborhood type \a ntype.
+
+            The shape must have type <tt>MultiArrayShape<N>::type</tt> with the appropriate 
+            dimension <tt>N</tt>. The neighborhood type can take the values 
+            <tt>DirectNeighborhood</tt> to use only the axis-aligned edges (2N-neighborhood)
+            and <tt>IndirectNeighborhood</tt> to use all diagonal edges as well 
+            ((3<sup>N</sup>-1)-neighborhood).
+        */
+    GridGraph(shape_type const &shape, NeighborhoodType ntype = DirectNeighborhood) 
+    : shape_(shape),
+      num_vertices_(prod(shape)),
+      num_edges_(gridGraphEdgeCount(shape, ntype, is_directed)), 
+      neighborhoodType_(ntype)
+    {
+        ArrayVector<ArrayVector<bool> > neighborExists;
+        
+        // populate the neighborhood tables:
+        // FIXME: this might be static (but make sure that it works with multi-threading)
+        detail::makeArrayNeighborhood(neighborOffsets_, neighborExists, neighborhoodType_);
+        detail::computeNeighborOffsets(neighborOffsets_, neighborExists, incrementalOffsets_, 
+                                       edgeDescriptorOffsets_, neighborIndices_, backIndices_, is_directed);
+        
+        // compute the neighbor offsets per neighborhood type
+        // detail::makeArraySubNeighborhood(neighborhood[0], neighborExists, shape_type(1), neighborhoodIndices);
+    }
+    
+        /** \brief Get the ID (i.e. scan-order index) for node desciptor \a v (API: LEMON).
+        */
+    index_type id(Node const & v) const
+    {
+        return detail::CoordinateToScanOrder<N>::exec(shape(), v);
+    }
+
+    index_type id(NodeIt const & v) const
+    {
+        return v.scanOrderIndex();
+    }
+    
+    index_type id(neighbor_vertex_iterator const & v) const
+    {
+        return id(*v);
+    }
+    
+    index_type id(back_neighbor_vertex_iterator const & v) const
+    {
+        return id(*v);
+    }
+    
+        /** \brief Get node descriptor for given node ID \a i (API: LEMON).
+        */
+    Node nodeFromId(index_type i) const
+    {
+        Node res(SkipInitialization);
+        detail::ScanOrderToCoordinate<N>::exec(i, shape(), res);
+        return res;
+    }
+
+        /** \brief Get the maximum ID of any node in this graph (API: LEMON).
+        */
+    index_type maxNodeId() const
+    {
+        return prod(shape()) - 1;
+    }
+    
+        /** \brief Get the grid cordinate of the given node \a v (convenience function).
+        */
+    Node const & pos(Node const & v) const
+    {
+        return v;
+    }
+    
+        /** \brief Get vertex iterator pointing to the first vertex of this graph (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::vertices(graph)</tt>,<br/>
+            LEMON uses <tt>Graph::NodeIt(graph)</tt>).
+        */
+    vertex_iterator get_vertex_iterator() const 
+    {
+        return vertex_iterator(shape_);
+    }
+
+        /** \brief Get vertex iterator pointing to the given vertex (API: VIGRA).
+        */
+    vertex_iterator get_vertex_iterator(vertex_descriptor const & v) const 
+    {
+        return vertex_iterator(shape_) + v;
+    }
+
+        /** \brief Get vertex iterator pointing beyond the valid range of vertices of this graph (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::vertices(graph)</tt>,<br/>
+            LEMON uses the special value <tt>lemon::INVALID</tt> instead).
+        */
+    vertex_iterator get_vertex_end_iterator() const 
+    {
+        return get_vertex_iterator().getEndIterator();
+    }
+
+        /** \brief Get an iterator pointing to the first neighbor of the given vertex (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::adjacent_vertices(v, graph)</tt>,<br/>
+            LEMON uses <tt>Graph::ArcIt(g, v)</tt>).
+        */
+    neighbor_vertex_iterator get_neighbor_vertex_iterator(vertex_descriptor const & v) const 
+    {
+        return neighbor_vertex_iterator(*this, v);
+    }
+
+        /** \brief Get an iterator pointing beyond the range of neighbors of the given vertex (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::adjacent_vertices(v, graph)</tt>,<br/>
+            LEMON uses the speical value <tt>lemon::INVALID</tt> instead).
+        */
+    neighbor_vertex_iterator get_neighbor_vertex_end_iterator(vertex_descriptor const & v) const 
+    {
+       return get_neighbor_vertex_iterator(v).getEndIterator();
+    }
+
+        /** \brief Get an iterator pointing to the first backward neighbor of the given vertex (API: VIGRA,<br/>
+            in analogy to the boost::graph API, we also provide a free function <tt>boost::back_adjacent_vertices(v, g)</tt>,<br/>
+            and the LEMON analogue is <tt>Graph::OutBackArcIt(graph, v)</tt>).
+        */
+    back_neighbor_vertex_iterator get_back_neighbor_vertex_iterator(vertex_descriptor const & v) const 
+    {
+        return back_neighbor_vertex_iterator(*this, v);
+    }
+
+        /** \brief Get an iterator pointing beyond the range of backward neighbors of the given vertex (API: VIGRA,<br/>
+            in analogy to the boost::graph API, we also provide a free function <tt>boost::back_adjacent_vertices(v, g)</tt>,<br/>
+            and LEMON just uses <tt>lemon::INVALID</tt> instead).
+        */
+    back_neighbor_vertex_iterator get_back_neighbor_vertex_end_iterator(vertex_descriptor const & v) const 
+    {
+       return get_back_neighbor_vertex_iterator(v).getEndIterator();
+    }
+    
+    // --------------------------------------------------
+    // support for VertexListGraph:
+
+        /** \brief Get the number of vertices in this graph (convenience function,
+            the boost::graph API provides the free function <tt>boost::num_vertices(graph)</tt>).
+        */
+    vertices_size_type num_vertices() const 
+    {
+        return num_vertices_;
+    }
+
+        /** \brief Get the number of nodes in this graph (API: LEMON).
+        */
+    vertices_size_type nodeNum() const 
+    {
+        return num_vertices();
+    }
+
+    // --------------------------------------------------
+    // support for IncidenceGraph:
+
+         /** \brief Get the ID (i.e. scan-order index in an edge property map) for the
+             given edges descriptor \a e (API: LEMON).
+        */
+   index_type id(Edge const & e) const
+    {
+        return detail::CoordinateToScanOrder<N+1>::exec(edge_propmap_shape(), e);
+    }
+    
+    index_type id(EdgeIt const & e) const
+    {
+        return id(*e);
+    }
+    
+    index_type id(IncEdgeIt const & e) const
+    {
+        return id(*e);
+    }
+
+    index_type id(IncBackEdgeIt const & e) const
+    {
+        return id(*e);
+    }
+
+        /** \brief Get the edge descriptor for the given edge ID \a i (API: LEMON).
+        */
+    Edge edgeFromId(index_type i) const
+    {
+        Edge res(SkipInitialization);
+        detail::ScanOrderToCoordinate<N+1>::exec(i, edge_propmap_shape(), res);
+        return res;
+    }
+    
+        /** \brief Get the maximum ID of any edge in this graph (API: LEMON).
+        */
+    index_type maxEdgeId() const
+    {
+        if(is_directed)
+            return maxArcId();
+        if(edgeNum() == 0)
+            return -1;
+        Node lastNode = shape() - shape_type(1);
+        Arc a(lastNode, backIndices_[get_border_type(lastNode)].back(), false);
+        return detail::CoordinateToScanOrder<N+1>::exec(edge_propmap_shape(), a);
+    }
+    
+        /** \brief Get the ID (i.e. scan-order index an an arc property map) for 
+            the given ar \a a (API: LEMON).
+        */
+    index_type id(Arc const & a) const
+    {
+        return detail::CoordinateToScanOrder<N+1>::exec(arc_propmap_shape(), directedArc(a));
+    }
+    
+    index_type id(ArcIt const & a) const
+    {
+        return id(*a);
+    }
+    
+    index_type id(OutArcIt const & a) const
+    {
+        return id(*a);
+    }
+    
+    index_type id(OutBackArcIt const & a) const
+    {
+        return id(*a);
+    }
+        
+        /** \brief Get an arc descriptor for the given arc ID \a i (API: LEMON).
+        */
+    Arc arcFromId(index_type i) const
+    {
+        Arc res;
+        detail::ScanOrderToCoordinate<N+1>::exec(i, arc_propmap_shape(), res);
+        return undirectedArc(res);
+    }
+    
+        /** \brief Get the maximal ID af any arc in this graph (API: LEMON).
+        */
+    index_type maxArcId() const
+    {
+        if(edgeNum() == 0)
+            return -1;
+        Node lastNode = shape() - shape_type(1);
+        index_type n = neighborIndices_[get_border_type(lastNode)][0];
+        Arc a(neighbor(lastNode, n), oppositeIndex(n), false);
+        return detail::CoordinateToScanOrder<N+1>::exec(arc_propmap_shape(), a);
+    }
+    
+        /** \brief Return <tt>true</tt> when the arc is looking on the underlying
+            edge in its natural (i.e. forward) direction, <tt>false</tt> otherwise (API: LEMON).
+        */
+    bool direction(Arc const & a) const
+    {
+        return !a.isReversed();
+    }
+    
+        /** \brief Create an arc for the given edge \a e, oriented along the 
+            edge's natural (<tt>forward = true</tt>) or reversed 
+            (<tt>forward = false</tt>) direction (API: LEMON).
+        */
+    Arc direct(Edge const & e, bool forward) const
+    {
+        if(!is_directed || forward)
+            return Arc(e, !forward);
+        else
+            return Arc(v(e), oppositeIndex(e[N]), true);
+    }
+    
+        /** \brief Create an arc for the given edge \a e oriented
+            so that node \a n is the starting node of the arc (API: LEMON), or
+            return <tt>lemon::INVALID</tt> if the edge is not incident to this node.
+        */
+    Arc direct(Edge const & e, Node const & n) const
+    {
+        if(u(e) == n)
+            return direct(e, true);
+        if(v(e) == n)
+            return direct(e, false);
+        return Arc(lemon::INVALID);
+    }
+    
+        /** \brief Return the opposite node of the given node \a n
+            along edge \a e (API: LEMON), or return <tt>lemon::INVALID</tt>
+            if the edge is not incident to this node.
+        */
+    Node oppositeNode(Node const & n, Edge const & e) const
+    {
+        Node start(u(e)), end(v(e));
+        if(n == start)
+            return end;
+        if(n == end)
+            return start;
+        return Node(lemon::INVALID);
+    }
+    
+        /** \brief Create an arc referring to the same edge as the given 
+            arc \a a, but with reversed direction (API: LEMON).
+        */
+    Arc oppositeArc(Arc const & a) const
+    {
+        return is_directed
+                 ? Arc(neighbor(a.vertexDescriptor(), a.edgeIndex()), oppositeIndex(a.edgeIndex()), false)
+                 : Arc(a, !a.isReversed());
+    }
+    
+        // internal function
+    Arc directedArc(Arc const & a) const
+    {
+        return a.isReversed()
+                 ? Arc(neighbor(a.vertexDescriptor(), a.edgeIndex()), oppositeIndex(a.edgeIndex()), false)
+                 : a;
+    }
+    
+        // internal function
+    Arc undirectedArc(Arc const & a) const
+    {
+        return a.edgeIndex() < maxUniqueDegree() 
+                 ? a
+                 : Arc(neighbor(a.vertexDescriptor(), a.edgeIndex()), oppositeIndex(a.edgeIndex()), true);
+    }
+    
+        /** \brief Return the start node of the edge the given iterator is referring to (API: LEMON).
+        */
+    Node baseNode(IncEdgeIt const & e)  const
+    {
+        return source(e.arcDescriptor());
+    }
+    
+        /** \brief Return the start node of the edge the given iterator is referring to (API: VIGRA).
+        */
+    Node baseNode(IncBackEdgeIt const & e)  const
+    {
+        return source(e.arcDescriptor());
+    }
+    
+        /** \brief Return the start node of the edge the given iterator is referring to (API: LEMON).
+        */
+    Node baseNode(OutArcIt const & a)  const
+    {
+        return source(*a);
+    }
+    
+        /** \brief Return the start node of the edge the given iterator is referring to (API: VIGRA).
+        */
+    Node baseNode(OutBackArcIt const & a)  const
+    {
+        return source(*a);
+    }
+
+        /** \brief Return the end node of the edge the given iterator is referring to (API: LEMON).
+        */
+    Node runningNode(IncEdgeIt const & e)  const
+    {
+        return target(e.arcDescriptor());
+    }
+    
+        /** \brief Return the end node of the edge the given iterator is referring to (API: VIGRA).
+        */
+    Node runningNode(IncBackEdgeIt const & e)  const
+    {
+        return target(e.arcDescriptor());
+    }
+    
+        /** \brief Return the end node of the edge the given iterator is referring to (API: LEMON).
+        */
+    Node runningNode(OutArcIt const & a)  const
+    {
+        return target(*a);
+    }
+    
+        /** \brief Return the end node of the edge the given iterator is referring to (API: VIGRA).
+        */
+    Node runningNode(OutBackArcIt const & a)  const
+    {
+        return target(*a);
+    }
+    
+        /** \brief Get the start node of the given arc \a a (API: LEMON).
+        */
+    Node source(Arc const & a) const 
+    {
+        return source_or_target(a, true);
+    }
+
+        /** \brief Get the end node of the given arc \a a (API: LEMON).
+        */
+    Node target(Arc const & a) const 
+    {
+        return source_or_target(a, false);
+    }
+
+        /** \brief Get the start node of the given edge \a e (API: LEMON,<br/>
+            the boost::graph API provides the free function <tt>boost::source(e, graph)</tt>).
+        */
+    Node u(Edge const & e) const 
+    {
+        return Node(e.template subarray<0,N>());
+    }
+
+        /** \brief Get the end node of the given edge \a e (API: LEMON,<br/>
+            the boost::graph API provides the free function <tt>boost::target(e, graph)</tt>).
+        */
+    Node v(Edge const & e) const 
+    {
+        return Node(e.template subarray<0,N>()) + neighborOffsets_[e[N]];
+    }
+
+        /** \brief Get an iterator pointing to the first outgoing edge of the given vertex (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::out_edges(v, graph)</tt>,<br/>
+            LEMON uses <tt>Graph::OutArcIt(g, v)</tt>).
+        */
+    out_edge_iterator get_out_edge_iterator(vertex_descriptor const & v) const 
+    {
+        return out_edge_iterator(*this, v);
+    }
+
+        /** \brief Get an iterator pointing beyond the range of outgoing edges of the given vertex (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::out_edges(v, graph)</tt>,<br/>
+            LEMON uses the special value <tt>lemon::INVALID</tt> instead).
+        */
+    out_edge_iterator get_out_edge_end_iterator(vertex_descriptor const & v) const 
+    {
+        return get_out_edge_iterator(v).getEndIterator();
+    }
+
+        /** \brief Get an iterator pointing to the first outgoing backward edge of the given vertex (API: VIGRA,<br/>
+            in analogy to the boost::graph API, we also provide a free function <tt>boost::out_back_edges(v, g)</tt>,<br/>
+            and the LEMON analogue is <tt>Graph::IncBackEdgeIt(graph, v)</tt>).
+        */
+    out_back_edge_iterator get_out_back_edge_iterator(vertex_descriptor const & v) const 
+    {
+        return out_back_edge_iterator(*this, v);
+    }
+
+        /** \brief Get an iterator pointing beyond the range of outgoing backward edges of the given vertex (API: VIGRA,<br/>
+            in analogy to the boost::graph API, we also provide a free function <tt>boost::out_back_edges(v, g)</tt>,<br/>
+            and LEMON uses the special value <tt>lemon::INVALID</tt> instead).
+        */
+    out_back_edge_iterator get_out_back_edge_end_iterator(vertex_descriptor const & v) const 
+    {
+        return get_out_back_edge_iterator(v).getEndIterator();
+    }
+
+        /** \brief Get an iterator pointing to the first incoming edge of the given vertex (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::in_edges(v, graph)</tt>,<br/>
+            LEMON uses <tt>Graph::InArcIt(g, v)</tt>).
+        */
+    in_edge_iterator get_in_edge_iterator(vertex_descriptor const & v) const 
+    {
+        return in_edge_iterator(*this, v);
+    }
+
+        /** \brief Get an iterator pointing beyond the range of incoming edges of the given vertex (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::in_edges(v, graph)</tt>,<br/>
+            LEMON uses the special value <tt>lemon::INVALID</tt> instead).
+        */
+    in_edge_iterator get_in_edge_end_iterator(vertex_descriptor const & v) const 
+    {
+        return get_in_edge_iterator(v).getEndIterator();
+    }
+
+        /** \brief Get the number of outgoing edges of the given vertex (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::out_degree(v, graph)</tt>,<br/>
+            LEMON uses a special property map <tt>lemon::OutDegMap<Graph></tt>).
+        */
+    degree_size_type out_degree(vertex_descriptor const & v) const 
+    {
+        return (degree_size_type)neighborIndices_[get_border_type(v)].size();
+    }
+    
+        /** \brief Get the number of outgoing backward edges of the given vertex (API: VIGRA).
+        */
+    degree_size_type back_degree(vertex_descriptor const & v) const 
+    {
+        return (degree_size_type)backIndices_[get_border_type(v)].size();
+    }
+    
+        /** \brief Get the number of outgoing forward edges of the given vertex (API: VIGRA).
+        */
+    degree_size_type forward_degree(vertex_descriptor const & v) const 
+    {
+        unsigned int bt = get_border_type(v);
+        return (degree_size_type)(neighborIndices_[bt].size() - backIndices_[bt].size());
+    }
+    
+        /** \brief Get the number of incoming edges of the given vertex (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::in_degree(v, graph)</tt>,<br/>
+            LEMON uses a special property map <tt>lemon::InDegMap<Graph></tt>).
+        */
+    degree_size_type in_degree(vertex_descriptor const & v) const 
+    {
+        return out_degree(v);
+    }
+    
+        /** \brief Get the total number of edges (incoming plus outgoing) of the given vertex (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::degree(v, graph)</tt>,<br/>
+            LEMON has no analogue).
+        */
+    degree_size_type degree(vertex_descriptor const & v) const 
+    {
+        return is_directed
+                   ? 2*out_degree(v)
+                   : out_degree(v);
+    }
+    
+    // --------------------------------------------------
+    // support for EdgeListGraph:
+
+        /** \brief Get the number of edges in this graph (convenience function,
+            boost::graph API provides the free function <tt>boost::num_edges(graph)</tt>).
+        */
+    edges_size_type num_edges() const 
+    {
+        return num_edges_;
+    }
+
+        /** \brief Get the number of edges in this graph (API: LEMON).
+        */
+    edges_size_type edgeNum() const 
+    {
+        return num_edges();
+    }
+
+        /** \brief Get the number of arc in this graph (API: LEMON).
+        */
+    edges_size_type arcNum() const 
+    {
+        return is_directed
+                   ? num_edges()
+                   : 2*num_edges();
+    }
+    
+        /** \brief Get edge iterator pointing to the first edge of the graph (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::edges(graph)</tt>,<br/>
+            LEMON uses <tt>Graph::EdgeIt(graph)</tt>).
+        */
+    edge_iterator get_edge_iterator() const 
+    {
+        return edge_iterator(*this);
+    }
+
+        /** \brief Get edge iterator pointing beyond the valid range of edges of this graph (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::vertices(graph)</tt>,<br/>
+            LEMON uses the special value <tt>lemon::INVALID</tt> instead).
+        */
+    edge_iterator get_edge_end_iterator() const 
+    {
+        return get_edge_iterator().getEndIterator();
+    }
+
+    // --------------------------------------------------
+    // support for AdjacencyMatrix concept:
+
+        /** \brief Get a descriptor for the edge connecting vertices \a u and \a v,<br/>
+            or <tt>(lemon::INVALID, false)</tt> if no such edge exists (convenience function,<br/>
+            the boost::graph API provides the free function <tt>boost::edge(u, v, graph)</tt>).
+        */
+    std::pair<edge_descriptor, bool>
+    edge(vertex_descriptor const & u, vertex_descriptor const & v) const
+    {
+        std::pair<edge_descriptor, bool> res(lemon::INVALID, false);
+
+        neighbor_vertex_iterator i = get_neighbor_vertex_iterator(u),
+                                 end = i.getEndIterator();
+        for (; i != end; ++i) 
+        {
+            if (*i == v) 
+            {
+                res.first = make_edge_descriptor(u, i.neighborIndex());
+                res.second = true;
+                break;
+            }
+        }
+        return res;
+    }
+
+        /** \brief Get a descriptor for the edge connecting vertices \a u and \a v,<br/>or <tt>lemon::INVALID</tt> if no such edge exists (API: LEMON).
+        */
+    Edge findEdge(Node const & u, Node const & v, Edge const & = lemon::INVALID) const 
+    {
+        return this->edge(u, v).first;
+    }
+    
+        /** \brief Get a descriptor for the arc connecting vertices \a u and \a v,<br/>or <tt>lemon::INVALID</tt> if no such edge exists (API: LEMON).
+        */
+    Arc findArc(Node const & u, Node const & v, Arc const & = lemon::INVALID) const 
+    {
+        return this->edge(u, v).first;
+        // std::pair<edge_descriptor, bool> res(edge(u, v));
+        // return res.second
+                 // ? res.first
+                 // : Arc(lemon::INVALID);
+    }
+    
+        /** \brief Create a property map that returns the coordinate of each node (API: LEMON GridGraph).
+        */
+    IndexMap indexMap() const 
+    {
+        return IndexMap();
+    }
+
+    // --------------------------------------------------
+    // other helper functions:
+    
+    bool isDirected() const
+    {
+        return is_directed;
+    }
+    
+    degree_size_type maxDegree() const
+    {
+        return (degree_size_type)neighborOffsets_.size();
+    }
+
+    degree_size_type maxUniqueDegree() const 
+    {
+         return is_directed
+                    ? maxDegree()
+                    : maxDegree() / 2;
+    }
+
+    shape_type const & shape() const 
+    {
+        return shape_;
+    }
+
+    edge_propmap_shape_type edge_propmap_shape() const 
+    {
+        edge_propmap_shape_type res(SkipInitialization);
+        res.template subarray<0, N>() = shape_;
+        res[N] = maxUniqueDegree();
+        return res;
+    }
+
+    edge_propmap_shape_type arc_propmap_shape() const 
+    {
+        edge_propmap_shape_type res(SkipInitialization);
+        res.template subarray<0, N>() = shape_;
+        res[N] = maxDegree();
+        return res;
+    }
+
+    unsigned int get_border_type(vertex_descriptor const & v) const
+    {
+        return detail::BorderTypeImpl<N>::exec(v, shape_);
+    }
+
+    unsigned int get_border_type(vertex_iterator const & v) const
+    {
+        return v.borderType();
+    }
+    
+    index_type oppositeIndex(index_type neighborIndex) const
+    {
+        return  maxDegree() - neighborIndex - 1;
+    }
+
+        /* the given neighborIndex must be valid for the given vertex,
+           otherwise this function will crash
+        */
+    edge_descriptor make_edge_descriptor(vertex_descriptor const & v,
+                                         index_type neighborIndex) const
+    {
+        if(neighborIndex < maxUniqueDegree())
+            return edge_descriptor(v, neighborIndex, false);
+        else
+            return edge_descriptor(neighbor(v, neighborIndex), oppositeIndex(neighborIndex), true);
+    }
+    
+    shape_type const & neighborOffset(index_type neighborIndex) const
+    {
+        return neighborOffsets_[neighborIndex];
+    }
+
+    vertex_descriptor neighbor(vertex_descriptor const & v, index_type neighborIndex) const
+    {
+        return v + neighborOffsets_[neighborIndex];
+    }
+
+    vertex_descriptor 
+    source_or_target(edge_descriptor const & e, bool return_source) const
+    {
+        // source is always the attached node (first coords) unless the
+        // edge has been reversed. 
+        if ((return_source && e.isReversed()) ||
+            (!return_source && !e.isReversed())) 
+        {
+            return neighbor(e.vertexDescriptor(), e.edgeIndex());
+        } 
+        else 
+        {
+            return e.vertexDescriptor();
+        }
+    }
+    
+    NeighborOffsetArray const * neighborOffsetArray() const
+    {
+        return &neighborOffsets_;
+    }
+    
+    RelativeNeighborOffsetsArray const * neighborIncrementArray() const
+    {
+        return &incrementalOffsets_;
+    }
+    
+    RelativeEdgeOffsetsArray const * edgeIncrementArray() const
+    {
+        return &edgeDescriptorOffsets_;
+    }
+    
+    IndexArray const * neighborIndexArray(bool backEdgesOnly) const
+    {
+        return backEdgesOnly 
+                   ? &backIndices_
+                   : &neighborIndices_;
+    }
+
+  protected:
+    NeighborOffsetArray neighborOffsets_;
+    IndexArray neighborIndices_, backIndices_;
+    RelativeNeighborOffsetsArray incrementalOffsets_;
+    RelativeEdgeOffsetsArray edgeDescriptorOffsets_;
+    shape_type shape_;
+    MultiArrayIndex num_vertices_, num_edges_;
+    NeighborhoodType neighborhoodType_;
+};
+
+//@}
+
+} // namespace vigra
+
+namespace boost {
+
+/** \addtogroup BoostGraphExtensions GridGraph additions to namespace <tt>boost</tt>
+        
+        provides the required functionality to make \ref vigra::GridGraph compatible to the boost::graph library.
+*/
+//@{
+
+
+
+template <unsigned int N, class T, class Acc>
+struct property_traits<vigra::MultiArray<N, T, Acc> >
+{
+    typedef vigra::MultiArray<N, T, Acc>             type;
+    typedef typename type::key_type                  key_type;
+    typedef typename type::value_type                value_type; 
+    typedef typename type::reference                 reference;
+    typedef boost::read_write_property_map_tag       category;
+};
+
+template <unsigned int N, class T, class Acc>
+struct property_traits<vigra::MultiArray<N, T, Acc> const>
+{
+    typedef vigra::MultiArray<N, T, Acc> const       type;
+    typedef typename type::key_type                  key_type;
+    typedef typename type::value_type                value_type; 
+    typedef typename type::const_reference           reference;
+    typedef boost::readable_property_map_tag         category;
+};
+
+template <unsigned int N, class T, class Stride>
+struct property_traits<vigra::MultiArrayView<N, T, Stride> >
+{
+    typedef vigra::MultiArrayView<N, T, Stride>       type;
+    typedef typename type::key_type                   key_type;
+    typedef typename type::value_type                 value_type; 
+    typedef typename type::reference                  reference;
+    typedef boost::read_write_property_map_tag        category;
+};
+
+template <unsigned int N, class T, class Stride>
+struct property_traits<vigra::MultiArrayView<N, T, Stride> const>
+{
+    typedef vigra::MultiArrayView<N, T, Stride> const     type;
+    typedef typename type::key_type                       key_type;
+    typedef typename type::value_type                     value_type; 
+    typedef typename type::const_reference                reference;
+    typedef boost::readable_property_map_tag              category;
+};
+
+    /** \brief Return number of outgoing edges of vertex \a v (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+typename vigra::GridGraph<N, DirectedTag>::degree_size_type
+out_degree(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v, 
+           vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return g.out_degree(v);
+}
+
+    /** \brief Return number of incoming edges of vertex \a v (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+typename vigra::GridGraph<N, DirectedTag>::degree_size_type
+in_degree(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v, 
+          vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return g.in_degree(v);
+}
+
+    /** \brief Return total number of edges (incoming and outgoing) of vertex \a v (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+typename vigra::GridGraph<N, DirectedTag>::degree_size_type
+degree(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v, 
+       vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return g.degree(v);
+}
+
+    /** \brief Get a (begin, end) iterator pair for the vertices of graph \a g (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+std::pair<typename vigra::GridGraph<N, DirectedTag>::vertex_iterator, 
+          typename vigra::GridGraph<N, DirectedTag>::vertex_iterator>
+vertices(vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return std::make_pair(g.get_vertex_iterator(),
+                          g.get_vertex_end_iterator());    
+}
+
+    /** \brief Return the number of vertices in graph \a g (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+typename vigra::GridGraph<N, DirectedTag>::vertices_size_type
+num_vertices(vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return g.num_vertices();
+}
+
+    /** \brief Get a (begin, end) iterator pair for the neighbor vertices of 
+               vertex \a v in graph \a g (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+std::pair<typename vigra::GridGraph<N, DirectedTag>::adjacency_iterator, 
+          typename vigra::GridGraph<N, DirectedTag>::adjacency_iterator>
+adjacent_vertices(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
+                  vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return std::make_pair(g.get_neighbor_vertex_iterator(v),
+                          g.get_neighbor_vertex_end_iterator(v));    
+}
+
+    /** \brief Get a (begin, end) iterator pair for only thise neighbor vertices of 
+               vertex \a v that have smaller ID than \a v (API: VIGRA).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+std::pair<typename vigra::GridGraph<N, DirectedTag>::back_neighbor_vertex_iterator, 
+          typename vigra::GridGraph<N, DirectedTag>::back_neighbor_vertex_iterator>
+back_adjacent_vertices(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
+                       vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return std::make_pair(g.get_back_neighbor_vertex_iterator(v),
+                          g.get_back_neighbor_vertex_end_iterator(v));    
+}
+
+// adjacent_vertices variant in vigra namespace: allows to call adjacent_vertices with vertex_iterator argument
+template<unsigned int N, class DirectedTag>
+inline
+std::pair<typename vigra::GridGraph<N, DirectedTag>::adjacency_iterator, 
+          typename vigra::GridGraph<N, DirectedTag>::adjacency_iterator>
+adjacent_vertices_at_iterator(typename vigra::GridGraph<N, DirectedTag>::vertex_iterator const & v,
+                              vigra::GridGraph<N, DirectedTag> const & g) 
+{    
+    return std::make_pair(g.get_neighbor_vertex_iterator(v),
+                          g.get_neighbor_vertex_end_iterator(v));    
+}
+
+    /** \brief Get a (begin, end) iterator pair for the outgoing edges of 
+               vertex \a v in graph \a g (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+std::pair<typename vigra::GridGraph<N, DirectedTag>::out_edge_iterator, 
+          typename vigra::GridGraph<N, DirectedTag>::out_edge_iterator>
+out_edges(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
+          vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return std::make_pair(g.get_out_edge_iterator(v),
+                          g.get_out_edge_end_iterator(v));    
+}
+
+    /** \brief Get a (begin, end) iterator pair for only those outgoing edges of 
+               vertex \a v whose ID is smaller than that of \a v (API: VIGRA).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+std::pair<typename vigra::GridGraph<N, DirectedTag>::out_back_edge_iterator, 
+          typename vigra::GridGraph<N, DirectedTag>::out_back_edge_iterator>
+out_back_edges(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
+               vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return std::make_pair(g.get_out_back_edge_iterator(v),
+                          g.get_out_back_edge_end_iterator(v));    
+}
+
+    /** \brief Get a (begin, end) iterator pair for the incoming edges of 
+               vertex \a v in graph \a g (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+std::pair<typename vigra::GridGraph<N, DirectedTag>::in_edge_iterator, 
+          typename vigra::GridGraph<N, DirectedTag>::in_edge_iterator>
+in_edges(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
+         vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return std::make_pair(g.get_in_edge_iterator(v),
+                          g.get_in_edge_end_iterator(v));    
+}
+
+    /** \brief Get a vertex descriptor for the start vertex of edge \a e in graph \a g (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor 
+source(typename vigra::GridGraph<N, DirectedTag>::edge_descriptor const & e,
+       vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return g.source(e);
+}
+
+    /** \brief Get a vertex descriptor for the end vertex of edge \a e in graph \a g (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor 
+target(typename vigra::GridGraph<N, DirectedTag>::edge_descriptor const & e,
+       vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return g.target(e);
+}
+
+    /** \brief Get a (begin, end) iterator pair for the edges of graph \a g (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+std::pair<typename vigra::GridGraph<N, DirectedTag>::edge_iterator, 
+          typename vigra::GridGraph<N, DirectedTag>::edge_iterator>
+edges(vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return std::make_pair(g.get_edge_iterator(), g.get_edge_end_iterator());
+}
+
+    /** \brief Return the number of edges in graph \a g (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+inline
+typename vigra::GridGraph<N, DirectedTag>::edges_size_type
+num_edges(vigra::GridGraph<N, DirectedTag> const & g) 
+{
+    return g.num_edges();
+}
+
+// --------------------------------------------------
+// support for AdjacencyMatrix concept:
+
+// FIXME: test this
+    /** \brief Return the pair (edge_descriptor, true) when an edge between vertices 
+               \a u and \a v exists, or (lemon::INVALID, false) otherwise (API: boost).
+    */
+template<unsigned int N, class DirectedTag>
+std::pair<typename vigra::GridGraph<N, DirectedTag>::edge_descriptor, bool>
+edge(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & u,
+     typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
+     vigra::GridGraph<N, DirectedTag> const & g)
+{
+    return g.edge(u,v);
+}
+
+// provide get / put for MultiArrayViews, indexed by the 
+// above-defined vertex_descriptor and edge_descriptor (in our case, a coordinate tuple):
+// FIXME: place this into multi_array.hxx ?
+    /** \brief Put value \a val at key \a k in the property map \a pmap (API: boost).
+    */
+template<unsigned int N, class T, class Stride, class U>
+inline
+void put(vigra::MultiArrayView<N, T, Stride> & pmap,
+         typename vigra::MultiArrayView<N, T, Stride>::difference_type const & k,
+         U const & val) 
+{ 
+    pmap[k] = val;  
+}
+
+    /** \brief Read the value at key \a k in property map \a pmap (API: boost).
+    */
+template<unsigned int N, class T, class Stride>
+inline
+typename vigra::MultiArrayView<N, T, Stride>::const_reference 
+get(vigra::MultiArrayView<N, T, Stride> const & pmap,
+    typename vigra::MultiArrayView<N, T, Stride>::difference_type const & k)
+{ 
+    return pmap[k]; 
+}
+
+#if 0
+
+// property map support for mapping coordinates to scan-order indices:
+
+template<unsigned int N>
+struct IDMapper {
+    typedef typename vigra::GridGraph<N> graph_type;
+    typedef boost::readable_property_map_tag category;
+    typedef typename graph_type::index_type value_type;
+    typedef typename graph_type::vertex_descriptor key_type;
+    typedef const value_type& reference;
+
+
+    IDMapper(const graph_type &graph) 
+        : map_helper(graph.get_vertex_iterator())
+    {}
+
+    typename graph_type::vertex_iterator map_helper;
+};
+
+template<unsigned int N>
+struct property_map<vigra::GridGraph<N>, boost::vertex_index_t>
+{
+    typedef IDMapper<N> type;
+    typedef IDMapper<N> const_type;
+};
+
+
+template<unsigned int N>
+inline
+typename IDMapper<N>::value_type
+get(const IDMapper<N> & mapper, 
+    const typename IDMapper<N>::key_type &k)
+{ 
+    return (mapper.map_helper + k).scanOrderIndex();
+}
+
+
+template<unsigned int N>
+typename boost::property_map<vigra::GridGraph<N>, boost::vertex_index_t>::type
+//typename IDMapper<N>
+get(boost::vertex_index_t, const vigra::GridGraph<N> &graph) {
+    // return a lightweight wrapper for the CoupledIterator, which easily allows the conversion of 
+    // coordinates via its += operator followed by index().
+    return IDMapper<N>(graph);
+}
+
+// CHECK if required: also provide the direct (three-parameter) version for index lookup
+template<unsigned int N>
+typename vigra::GridGraph<N>::vertices_size_type
+get(boost::vertex_index_t, 
+    const vigra::GridGraph<N> &graph,
+    const typename vigra::GridGraph<N>::vertex_descriptor &v) {
+    return (IDMapper<N>(graph).map_helper + v).scanOrderIndex();
+}
+
+
+// TODO:
+// eventually provide an edge_index property map as well?
+// (edge_descriptor -> linear contiguous edge index)
+
+#endif
+
+//@}
+
+} // namespace boost
+
+namespace lemon {
+
+template <typename GR>
+class InDegMap;
+
+    // LEMON-compatible property map for the in-degree of the nodes
+template<unsigned int N, class DirectedTag>
+class InDegMap<vigra::GridGraph<N, DirectedTag> >
+: public vigra::GridGraph<N, DirectedTag>::InDegMap
+{
+  public:
+    typedef vigra::GridGraph<N, DirectedTag> Graph;
+    
+    explicit InDegMap(const Graph& graph)
+    : Graph::InDegMap(graph)
+    {}
+};
+
+template <typename GR>
+class OutDegMap;
+
+    // LEMON-compatible property map for the out-degree of the nodes
+template<unsigned int N, class DirectedTag>
+class OutDegMap<vigra::GridGraph<N, DirectedTag> >
+: public vigra::GridGraph<N, DirectedTag>::OutDegMap
+{
+  public:
+    typedef vigra::GridGraph<N, DirectedTag> Graph;
+    
+    explicit OutDegMap(const Graph& graph)
+    : Graph::OutDegMap(graph)
+    {}
+};
+
+
+} // namespace lemon
+
+namespace vigra {
+namespace boost_graph { 
+
+using boost::get;
+
+}} // namespace vigra::boost_graph
+
+
+namespace std {
+
+template<unsigned int N, class DirectedTag>
+ostream& operator<<(ostream& out,
+                    typename vigra::GridGraph<N, DirectedTag>::vertex_iterator const & arg)
+{
+    out << "v" << arg.scanOrderIndex();
+    return out;
+}
+
+template<unsigned int N, class DirectedTag>
+ostream& operator<<(ostream& out,
+                    typename vigra::GridGraph<N, DirectedTag>::adjacency_iterator const & arg)
+{
+    out << "nb" << arg.index();
+    return out;
+}
+
+} // namespace std
+
+
+
+#endif /* VIGRA_MULTI_GRIDGRAPH_HXX */
+
+
+
diff --git a/include/vigra/multi_impex.hxx b/include/vigra/multi_impex.hxx
new file mode 100644
index 0000000..e154cec
--- /dev/null
+++ b/include/vigra/multi_impex.hxx
@@ -0,0 +1,903 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2003 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_MULTI_IMPEX_HXX
+#define VIGRA_MULTI_IMPEX_HXX
+
+#include <memory>
+#include <iomanip>
+#include <sstream>
+#include <iostream>
+#include <string>
+#include <fstream>
+
+#include "config.hxx"
+#include "basicimageview.hxx"
+#include "impex.hxx"
+#include "multi_array.hxx"
+#include "multi_pointoperators.hxx"
+#include "sifImport.hxx"
+
+#ifdef _MSC_VER
+# include <direct.h>
+#else
+# include <unistd.h>
+#endif
+
+namespace vigra {
+
+/** \addtogroup VolumeImpex Import/export of volume data.
+*/
+
+//@{
+
+/** \brief Argument object for the function importVolume().
+
+    See \ref importVolume() for usage example. This object can be used
+    to define the properties of a volume data set to be read from disk.
+    Sorry, no \ref detailedDocumentation() available yet.
+
+    <b>\#include</b> \<vigra/multi_impex.hxx\> <br/>
+    Namespace: vigra
+**/
+class VolumeImportInfo
+{
+  public:
+    typedef ImageImportInfo::PixelType PixelType;
+
+        /// type of volume size returned by shape()
+    typedef MultiArrayShape<3>::type   ShapeType;
+
+        /// type of volume size returned by shape()
+    typedef ShapeType                  size_type;
+
+        /// 3D resolution type returned by resolution()
+    typedef TinyVector<float, 3>       Resolution;
+
+        /** Construct VolumeImportInfo from a single filename.
+        
+            The \a filename (which may contain a path) can be interpreted in three different ways:
+            <ul>
+            <li>If the name refers to a file that contains volume data, the header information
+                of this file is read. Two file formats are currently supported: Andor .SIF
+                and multi-page TIFF.
+            <li>If the name refers to a textfile, the constructor will attempt to interpret the file
+                in the ".info" format to obtain the header information. The volume data 
+                are then expected to be located in an accompanying RAW file. The ".info" file must
+                contain the following key-value pairs:
+                <UL>
+                <LI> name = [short descriptive name of the volume] (optional)
+                <LI> filename = [absolute or relative path to raw voxel data file] (required)
+                <li> description =  [arbitrary description of the data set] (optional)
+                <li> width = [positive integer] (required)
+                <li> height = [positive integer] (required)
+                <li> depth = [positive integer] (required)
+                <li> datatype = [ UINT8 | INT16 | UINT16 | INT32 | UINT32 | FLOAT | DOUBLE ] (required)
+                </UL>
+                Lines starting with "#" are ignored. To read the data correctly, the 
+                value_type of the target MultiArray must match the datatype stored in the file. 
+                Only single-band files are currently supported. 
+            <li>If the name refers to a 2D image file, the constructor will attempt to decompose
+                the filename into the format <tt>base_name + slice_number + name_extension</tt>.
+                If this decomposition succeeds, all images with the same base_name and name_extension
+                will be considered as the slices of an image stack. Slice numbers need not be consecutive
+                (i.e. gaps are allowed) and will be interpreted according to their numerical order
+                (i.e. "009", "010", "011" are read in the same order as "9", "10", "11"). The number of images
+                found determines the depth of the volume, the remaining header data are read from the given image.
+            </ul>
+         */
+    VIGRA_EXPORT VolumeImportInfo(const std::string &filename);
+
+        /** Construct VolumeImportInfo for a stack of images.
+        
+            The constructor will look for filenames of the form <tt>base_name + slice_number + name_extension</tt>.
+            All images conforming to this pattern will be considered as the slices of an image stack. 
+            Slice numbers need not be consecutive (i.e. gaps are allowed) and will be interpreted according 
+            to their numerical order (i.e. "009", "010", "011" are read in the same order as "9", "10", "11").
+            The number of images found determines the depth of the volume, the remaining header data are read 
+            from the given image. \a name_base may contain a path.
+         */
+    VIGRA_EXPORT VolumeImportInfo(const std::string &base_name, const std::string &name_extension);
+
+        /** Get the shape of the volume.
+         */
+    VIGRA_EXPORT ShapeType shape() const;
+
+        /** Get width of the volume.
+         **/
+    VIGRA_EXPORT MultiArrayIndex width() const;
+
+        /** Get height of the volume.
+         **/
+    VIGRA_EXPORT MultiArrayIndex height() const;
+
+        /** Get depth of the volume.
+         **/
+    VIGRA_EXPORT MultiArrayIndex depth() const;
+
+        /**
+         * resolution() contains the alignment and resolution of the
+         * volume.  resolution()[0] is the x increment in a left-handed
+         * world coordinate system of one unstrided step in the volume
+         * memory.  The [1] and [2] elements contain the y resp. z
+         * increments of the strided row resp. slice steps in the
+         * volume.
+         *
+         * EXAMPLES: (1.f, 1.f, 4.f) means that the slices are four
+         * times thicker than the x/y resolution.
+         * (1.f, -1.f, 1.f) means that the volume coordinate system is
+         * right-handed.
+         */
+    VIGRA_EXPORT Resolution resolution() const;
+
+        /** Query the file type.
+
+            Possible values are:
+            <DL>
+            <DT>"MULTIPAGE"<DD> Multiple 2D images in a single file (currently only supported by TIFF).
+            <DT>"SIF"<DD>  <a href="http://www.andor.com">Andor Technology's</a> .sif format.
+            <DT>"RAW"<DD> Raw data file, accompanied by a .info file
+            <DT>"STACK"<DD> A numbered set of 2D image files, one per slice of the volume.
+            </DL>
+         **/
+    VIGRA_EXPORT const char * getFileType() const;
+
+        /** Query the pixel type of the volume data.
+
+            Possible values are:
+            <DL>
+            <DT>"INT8"<DD> 8-bit signed integer (signed char)
+            <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
+            <DT>"INT16"<DD> 16-bit signed integer (short)
+            <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short)
+            <DT>"INT32"<DD> 32-bit signed integer (long)
+            <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long)
+            <DT>"INT64"<DD> 64-bit signed integer (long long)
+            <DT>"UINT64"<DD> 64-bit unsigned integer (unsigned long long)
+            <DT>"FLOAT"<DD> 32-bit floating point (float)
+            <DT>"DOUBLE"<DD> 64-bit floating point (double)
+            <DT>"UNKNOWN"<DD> any other type
+            </DL>
+         **/
+    VIGRA_EXPORT const char * getPixelType() const;
+
+        /** Query the pixel type of the volume data.
+
+            Same as getPixelType(), but the result is returned as a 
+            ImageImportInfo::PixelType enum. This is useful to implement
+            a switch() on the pixel type.
+
+            Possible values are:
+            <DL>
+            <DT>UINT8<DD> 8-bit unsigned integer (unsigned char)
+            <DT>INT16<DD> 16-bit signed integer (short)
+            <DT>UINT16<DD> 16-bit unsigned integer (unsigned short)
+            <DT>INT32<DD> 32-bit signed integer (long)
+            <DT>UINT32<DD> 32-bit unsigned integer (unsigned long)
+            <DT>FLOAT<DD> 32-bit floating point (float)
+            <DT>DOUBLE<DD> 64-bit floating point (double)
+            </DL>
+         **/
+    VIGRA_EXPORT PixelType pixelType() const;
+
+    VIGRA_EXPORT MultiArrayIndex numBands() const;
+    VIGRA_EXPORT bool isGrayscale() const;
+    VIGRA_EXPORT bool isColor() const;
+
+    // get base file name without path, image index, and extension
+    VIGRA_EXPORT const std::string &name() const;
+
+    VIGRA_EXPORT const std::string &description() const;
+
+    template <class T, class Stride>
+    void importImpl(MultiArrayView <3, T, Stride> &volume) const;
+
+  protected:
+    void getVolumeInfoFromFirstSlice(const std::string &filename);
+
+    size_type shape_;
+    Resolution resolution_;
+    //PixelType pixelType_;
+    int numBands_;
+
+    std::string path_, name_, description_, fileType_, pixelType_;
+
+    std::string rawFilename_;
+    std::string baseName_, extension_;
+    std::vector<std::string> numbers_;
+};
+
+/********************************************************/
+/*                                                      */
+/*                   VolumeExportInfo                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Argument object for the function exportVolume().
+
+    See \ref exportVolume() for usage example. This object must be used
+    to define the properties of a volume to be written to disk.
+
+    <b>\#include</b> \<vigra/imageinfo.hxx\> <br/>
+    Namespace: vigra
+**/
+class VolumeExportInfo
+{
+  public:
+        /** Construct VolumeExportInfo object to output volume data as a multi-page tiff.
+
+            The filename must refer to a TIFF file (extension '.tif' or '.tiff'). This function 
+            is only available when libtiff is installed.
+         **/
+    VIGRA_EXPORT VolumeExportInfo( const char * filename );
+    
+        /** Construct VolumeExportInfo object to output volume data as an image stack.
+
+            The volume will be stored in a by-slice manner, where the number of slices 
+            equals the depth of the volume. The file names will be enumerated like
+            <tt>name_base+"000"+name_ext</tt>, <tt>name_base+"001"+name_ext</tt> etc.
+            (the actual number of zeros depends on the depth). If the target image type
+            does not support the source voxel type, all slices will be mapped 
+            simultaneously to the appropriate target range.
+            The file type will be guessed from the extension unless overridden
+            by \ref setFileType(). 
+            
+            Recognized extensions: '.bmp', '.gif',
+            '.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras',
+            '.tif', '.tiff', '.xv', '.hdr'.
+            
+            JPEG support requires libjpeg, PNG support requires libpng, and
+            TIFF support requires libtiff.
+            
+            If \a name_ext is an empty string, the data is written as a multi-page tiff.
+         **/
+    VIGRA_EXPORT VolumeExportInfo( const char * name_base, const char * name_ext );
+    VIGRA_EXPORT ~VolumeExportInfo();
+
+        /** Set volume file name base.
+
+        **/
+    VIGRA_EXPORT VolumeExportInfo & setFileNameBase(const char * name_base);
+    
+        /** Set volume file name extension.
+
+            The file type will be guessed from the extension unless overridden
+            by \ref setFileType(). Recognized extensions: '.bmp', '.gif',
+            '.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras',
+            '.tif', '.tiff', '.xv', '.hdr'.
+            
+            JPEG support requires libjpeg, PNG support requires libpng, and
+            TIFF support requires libtiff.
+        **/
+    VIGRA_EXPORT VolumeExportInfo & setFileNameExt(const char * name_ext);
+    VIGRA_EXPORT const char * getFileNameBase() const;
+    VIGRA_EXPORT const char * getFileNameExt() const;
+
+        /** Store volume as given file type.
+
+            This will override any type guessed
+            from the file name's extension. Recognized file types:
+
+            <DL>
+            <DT>"BMP"<DD> Microsoft Windows bitmap image file.
+            <DT>"GIF"<DD> CompuServe graphics interchange format; 8-bit color.
+            <DT>"JPEG"<DD> Joint Photographic Experts Group JFIF format;
+            compressed 24-bit color (only available if libjpeg is installed).
+            <DT>"PNG"<DD> Portable Network Graphic
+            (only available if libpng is installed).
+            <DT>"PBM"<DD> Portable bitmap format (black and white).
+            <DT>"PGM"<DD> Portable graymap format (gray scale).
+            <DT>"PNM"<DD> Portable anymap.
+            <DT>"PPM"<DD> Portable pixmap format (color).
+            <DT>"SUN"<DD> SUN Rasterfile.
+            <DT>"TIFF"<DD> Tagged Image File Format.
+            (only available if libtiff is installed.)
+            <DT>"MULTIPAGE"<DD> Multi-page TIFF.
+               (only available if libtiff is installed.)
+            <DT>"VIFF"<DD> Khoros Visualization image file.
+            </DL>
+
+            With the exception of TIFF, VIFF, PNG, and PNM all file types store
+            only 1 byte (gray scale and mapped RGB) or 3 bytes (RGB) per
+            pixel.
+
+            PNG can store UInt8 and UInt16 values, and supports 1 and 3 channel
+            images. One additional alpha channel is also supported.
+
+            PNM can store 1 and 3 channel images with UInt8, UInt16 and UInt32
+            values in each channel.
+
+            TIFF and VIFF are additionally able to store short and long
+            integers (2 or 4 bytes) and real values (32 bit float and
+            64 bit double) without conversion. So you will need to use
+            TIFF or VIFF if you need to store images with high
+            accuracy (the appropriate type to write is automatically
+            derived from the image type to be exported). However, many
+            other programs using TIFF (e.g. ImageMagick) have not
+            implemented support for those pixel types.  So don't be
+            surprised if the generated TIFF is not readable in some
+            cases.  If this happens, export the image as 'unsigned
+            char' or 'RGBValue\<unsigned char\>' by calling
+            \ref ImageExportInfo::setPixelType().
+
+            Support to reading and writing ICC color profiles is
+            provided for TIFF, JPEG, and PNG images.
+         **/
+    VIGRA_EXPORT VolumeExportInfo & setFileType( const char * );
+    VIGRA_EXPORT const char * getFileType() const;
+
+        /** Set compression type and quality.
+
+            See \ref ImageExportInfo::setCompression() for details.
+         **/
+    VIGRA_EXPORT VolumeExportInfo & setCompression( const char * type);
+    VIGRA_EXPORT const char * getCompression() const;
+
+        /** Set the pixel type of the volume file(s). Possible values are:
+            <DL>
+            <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
+            <DT>"INT16"<DD> 16-bit signed integer (short)
+            <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short)
+            <DT>"INT32"<DD> 32-bit signed integer (long)
+            <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long)
+            <DT>"FLOAT"<DD> 32-bit floating point (float)
+            <DT>"DOUBLE"<DD> 64-bit floating point (double)
+            </DL>
+         **/
+    VIGRA_EXPORT VolumeExportInfo & setPixelType( const char * );
+
+        /** Get the pixel type of the images in the volume. Possible values are:
+            <DL>
+            <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
+            <DT>"INT16"<DD> 16-bit signed integer (short)
+            <DT>"INT32"<DD> 32-bit signed integer (long)
+            <DT>"FLOAT"<DD> 32-bit floating point (float)
+            <DT>"DOUBLE"<DD> 64-bit floating point (double)
+            </DL>
+         **/
+    VIGRA_EXPORT const char * getPixelType() const;
+    
+    VIGRA_EXPORT VolumeExportInfo & setForcedRangeMapping(double fromMin, double fromMax,
+                                                     double toMin, double toMax);    
+    VIGRA_EXPORT bool hasForcedRangeMapping() const;
+    VIGRA_EXPORT double getFromMin() const;
+    VIGRA_EXPORT double getFromMax() const;
+    VIGRA_EXPORT double getToMin() const;
+    VIGRA_EXPORT double getToMax() const;
+    
+        /** Set the volume resolution in horizontal direction
+         **/
+    VIGRA_EXPORT VolumeExportInfo & setXResolution( float );
+    VIGRA_EXPORT float getXResolution() const;
+
+        /** Set the image resolution in vertical direction
+         **/
+    VIGRA_EXPORT VolumeExportInfo & setYResolution( float );
+    VIGRA_EXPORT float getYResolution() const;
+
+        /** Set the image resolution in depth direction
+         **/
+    VIGRA_EXPORT VolumeExportInfo & setZResolution( float );
+    VIGRA_EXPORT float getZResolution() const;
+
+        /** Set the position of the upper Left corner on a global
+            canvas.
+
+            Currently only supported by TIFF and PNG files.
+
+            The offset is encoded in the XPosition and YPosition TIFF tags.
+
+            @param pos     position of the upper left corner in pixels
+                           (must be >= 0)
+         **/
+    // FIXME: mhanselm: we might want to support 3D positions
+    VIGRA_EXPORT VolumeExportInfo & setPosition(const Diff2D & pos);
+
+        /** Get the position of the upper left corner on
+            a global canvas.
+         **/
+    // FIXME: mhanselm: we might want to support 3D positions
+    VIGRA_EXPORT Diff2D getPosition() const;
+
+        /**
+          ICC profiles (handled as raw data so far).
+          see getICCProfile()/setICCProfile()
+         **/
+    typedef ArrayVector<unsigned char> ICCProfile;
+
+        /** Returns a reference to the ICC profile.
+         */
+    VIGRA_EXPORT const ICCProfile & getICCProfile() const;
+
+        /** Sets the ICC profile.
+            ICC profiles are currently supported by TIFF, PNG and JPEG images.
+            (Otherwise, the profile data is silently ignored.)
+         **/
+    VIGRA_EXPORT VolumeExportInfo & setICCProfile(const ICCProfile & profile);
+
+  private:
+    float m_x_res, m_y_res, m_z_res;
+
+    std::string m_filetype, m_filename_base, m_filename_ext, m_pixeltype, m_comp;
+    Diff2D m_pos;
+    ICCProfile m_icc_profile;
+    double fromMin_, fromMax_, toMin_, toMax_;
+};
+
+namespace detail {
+
+template <class DestIterator, class Shape, class T>
+inline void
+readVolumeImpl(DestIterator d, Shape const & shape, std::ifstream & s, ArrayVector<T> & buffer, MetaInt<0>)
+{
+    s.read((char*)buffer.begin(), shape[0]*sizeof(T));
+
+    DestIterator dend = d + shape[0];
+    int k = 0;
+    for(; d < dend; ++d, k++)
+    {
+        *d = buffer[k];
+    }
+}
+
+template <class DestIterator, class Shape, class T, int N>
+void
+readVolumeImpl(DestIterator d, Shape const & shape, std::ifstream & s, ArrayVector<T> & buffer, MetaInt<N>)
+{
+    DestIterator dend = d + shape[N];
+    for(; d < dend; ++d)
+    {
+        readVolumeImpl(d.begin(), shape, s, buffer, MetaInt<N-1>());
+    }
+}
+
+} // namespace detail
+
+template <class T, class Stride>
+void VolumeImportInfo::importImpl(MultiArrayView <3, T, Stride> &volume) const
+{
+    vigra_precondition(this->shape() == volume.shape(), "importVolume(): Output array must be shaped according to VolumeImportInfo.");
+
+    if(fileType_ == "RAW")
+    {
+        std::string dirName, baseName;
+        char oldCWD[2048];
+
+#ifdef _MSC_VER
+        if(_getcwd(oldCWD, 2048) == 0)
+        {
+            perror("getcwd");
+            vigra_fail("VolumeImportInfo: Unable to query current directory (getcwd).");
+        }
+        if(_chdir(path_.c_str()))
+        {
+            perror("chdir");
+            vigra_fail("VolumeImportInfo: Unable to change to new directory (chdir).");
+        }
+#else
+        if(getcwd(oldCWD, 2048) == 0)
+        {
+            perror("getcwd");
+            vigra_fail("VolumeImportInfo: Unable to query current directory (getcwd).");
+        }
+        if(chdir(path_.c_str()))
+        {
+            perror("chdir");
+            vigra_fail("VolumeImportInfo: Unable to change to new directory (chdir).");
+        }
+#endif
+
+        std::ifstream s(rawFilename_.c_str(), std::ios::binary);
+        vigra_precondition(s.good(), "RAW file could not be opened");
+
+        ArrayVector<T> buffer(shape_[0]);
+        detail::readVolumeImpl(volume.traverser_begin(), shape_, s, buffer, vigra::MetaInt<2>());
+
+        //vigra_precondition(s.good(), "RAW file could not be opened");
+        //s.read((char*)volume.data(), shape_[0]*shape_[1]*shape_[2]*sizeof(T));
+
+#ifdef _MSC_VER
+        if(_chdir(oldCWD))
+            perror("chdir");
+#else
+        if(chdir(oldCWD))
+            perror("chdir");
+#endif
+
+        vigra_postcondition(
+            volume.shape() == shape(), "imported volume has wrong size");
+    }
+    else if(fileType_ == "STACK")
+    {
+        for (unsigned int i = 0; i < numbers_.size(); ++i)
+        {
+            // build the filename
+            std::string name = baseName_ + numbers_[i] + extension_;
+
+            // import the image
+            ImageImportInfo info (name.c_str ());
+
+            // generate a basic image view to the current layer
+            MultiArrayView <2, T, Stride> view (volume.bindOuter (i));
+            vigra_precondition(view.shape() == info.shape(),
+                "importVolume(): the images have inconsistent sizes.");
+
+            importImage (info, destImage(view));
+        }
+    }
+    else if(fileType_ == "MULTIPAGE")
+    {
+        ImageImportInfo info(baseName_.c_str());
+
+        for(int k=0; k<info.numImages(); ++k)
+        {
+            info.setImageIndex(k);
+            importImage(info, volume.bindOuter(k));
+        }
+    }
+    // else if(fileType_ == "HDF5")
+    // {
+        // HDF5File file(baseName_, HDF5File::OpenReadOnly);
+        // file.read(extension_, volume);
+    // }
+    else if(fileType_ == "SIF")
+    {
+        SIFImportInfo infoSIF(baseName_.c_str());
+        readSIF(infoSIF, volume);
+    }
+}
+
+
+VIGRA_EXPORT void findImageSequence(const std::string &name_base,
+                       const std::string &name_ext,
+                       std::vector<std::string> & numbers);
+
+/********************************************************/
+/*                                                      */
+/*                    importVolume                      */
+/*                                                      */
+/********************************************************/
+
+/** \brief Function for importing a 3D volume.
+
+    <b>Declarations: </b>
+    
+    \code
+    namespace vigra {
+        // variant 1: read data specified by the given VolumeImportInfo object
+        template <class T, class Stride>
+        void 
+        importVolume(VolumeImportInfo const & info, 
+                     MultiArrayView <3, T, Stride> &volume);
+                     
+        // variant 2: read data using a single filename, resize volume automatically
+        template <class T, class Allocator>
+        void 
+        importVolume(MultiArray <3, T, Allocator> & volume,
+                     const std::string &filename);
+                           
+        // variant 3: read data from an image stack, resize volume automatically
+        template <class T, class Allocator>
+        void 
+        importVolume(MultiArray <3, T, Allocator> & volume,
+                     const std::string &name_base,
+                     const std::string &name_ext);
+    }
+    \endcode
+
+    Data can be read either from a single file containing 3D data (supported formats: 
+    Andor .SIF or multi-page TIFF), a ".info" text file which describes the contents of 
+    an accompanying raw data file, or a stack of 2D images (numbered according to the 
+    scheme <tt>name_base+"[0-9]+"+name_extension</tt>) each representing a slice of 
+    the volume. The decision which of these possibilities applies is taken in the 
+    \ref vigra::VolumeImportInfo::VolumeImportInfo(const std::string &) "VolumeImportInfo constructor",
+    see there for full details.
+    
+    Variant 1 is the basic version of this function. Here, the info object and a destination
+    array of approriate size must already be constructed. The other variants are just abbreviations
+    provided for your convenience:
+    \code
+    // variant 2 is equivalent to
+    VolumeImportInfo info(filename);
+    volume.reshape(info.shape());
+    importVolume(info, volume);    // call variant 1
+    
+    // variant 3 is equivalent to
+    VolumeImportInfo info(name_base, name_ext);
+    volume.reshape(info.shape());
+    importVolume(info, volume);    // call variant 1
+    \endcode
+    
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_impex.hxx\> <br/>
+    Namespace: vigra
+    
+    \code
+    // read data from a multi-page TIFF file, using variant 1
+    VolumeImportInfo info("multipage.tif");
+    MultiArray<3, float> volume(info.shape());
+    importVolume(info, volume);
+    
+    // read data from a stack of 2D png-images, using variant 1
+    VolumeImportInfo info("my_data", ".png");  // looks for files 'my_data0.png', 'my_data1.png' etc.
+    MultiArray<3, float> volume(info.shape());
+    importVolume(info, volume);
+    \endcode
+    Notice that slice numbers in a stack need not be consecutive (i.e. gaps are allowed) and 
+    will be interpreted according to their numerical order (i.e. "009", "010", "011" 
+    are read in the same order as "9", "10", "11"). The number of images
+    found determines the depth of the volume.
+*/
+doxygen_overloaded_function(template <...> void importVolume)
+
+template <class T, class Stride>
+void 
+importVolume(VolumeImportInfo const & info, 
+             MultiArrayView <3, T, Stride> &volume)
+{
+    info.importImpl(volume);
+}
+
+template <class T, class Allocator>
+void 
+importVolume(MultiArray <3, T, Allocator> &volume,
+             const std::string &filename)
+{
+    VolumeImportInfo info(filename);
+    volume.reshape(info.shape());
+
+    info.importImpl(volume);
+}
+
+template <class T, class Allocator>
+void importVolume (MultiArray <3, T, Allocator> & volume,
+                   const std::string &name_base,
+                   const std::string &name_ext)
+{
+    VolumeImportInfo info(name_base, name_ext);
+    volume.reshape(info.shape());
+
+    info.importImpl(volume);
+}
+
+namespace detail {
+
+template <class T>
+void setRangeMapping(std::string const & pixeltype,
+                     FindMinMax<T> const & minmax, ImageExportInfo & info)
+{
+    if(pixeltype == "UINT8")
+        info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
+                                   (double)NumericTraits<UInt8>::min(),
+                                   (double)NumericTraits<UInt8>::max());
+    else if(pixeltype == "INT16")
+        info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
+                                   (double)NumericTraits<Int16>::min(),
+                                   (double)NumericTraits<Int16>::max());
+    else if(pixeltype == "UINT16")
+        info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
+                                   (double)NumericTraits<UInt16>::min(),
+                                   (double)NumericTraits<UInt16>::max());
+    else if(pixeltype == "INT32")
+        info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
+                                   (double)NumericTraits<Int32>::min(),
+                                   (double)NumericTraits<Int32>::max());
+    else if(pixeltype == "UINT32")
+        info.setForcedRangeMapping((double)minmax.min, (double)minmax.max,
+                                   (double)NumericTraits<UInt32>::min(),
+                                   (double)NumericTraits<UInt32>::max());
+    else if(pixeltype == "FLOAT")
+        info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 0.0, 1.0);
+    else if(pixeltype == "DOUBLE")
+        info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 0.0, 1.0);
+}
+
+template <class T, class Tag>
+void setRangeMapping(MultiArrayView <3, T, Tag> const & volume,
+                     ImageExportInfo & info, VigraTrueType /* isScalar */)
+{
+    std::string pixeltype = info.getPixelType();
+    bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), info.getFileType()),
+                                       TypeAsString<T>::result(), pixeltype);
+
+    if(downcast)
+    {
+        FindMinMax<T> minmax;
+        inspectMultiArray(srcMultiArrayRange(volume), minmax);
+        setRangeMapping(pixeltype, minmax, info);
+    }
+}
+
+template <class T, class Tag>
+void setRangeMapping(MultiArrayView <3, T, Tag> const & volume,
+                     ImageExportInfo & info, VigraFalseType /* isScalar */)
+{
+    typedef typename T::value_type SrcComponent;
+    std::string pixeltype = info.getPixelType();
+    bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), info.getFileType()),
+                                       TypeAsString<SrcComponent>::result(), pixeltype);
+
+    if(downcast)
+    {
+        unsigned int bands = volume(0,0,0).size();
+        FindMinMax<SrcComponent> minmax;
+        for(unsigned int i=0; i<bands; ++i)
+        {
+            VectorComponentValueAccessor<T> band(i);
+            inspectMultiArray(srcMultiArrayRange(volume, band), minmax );
+        }
+        setRangeMapping(pixeltype, minmax, info);
+    }
+}
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*                    exportVolume                      */
+/*                                                      */
+/********************************************************/
+
+/** \brief Function for exporting a 3D volume.
+
+    <b> Declarations:</b>
+    
+    \code
+    namespace vigra {
+        // variant 1: writa data as specified in the given VolumeExportInfo object
+        template <class T, class Tag>
+        void 
+        exportVolume (MultiArrayView <3, T, Tag> const & volume,
+                      const VolumeExportInfo & info);
+                     
+        // variant 2: write data to a multi-page TIFF file
+        template <class T, class Tag>
+        void
+        exportVolume (MultiArrayView <3, T, Tag> const & volume,
+                      const std::string &filename);
+                           
+        // variant 3: write data to an image stack
+        template <class T, class Tag>
+        void
+        exportVolume (MultiArrayView <3, T, Tag> const & volume,
+                      const std::string &name_base,
+                      const std::string &name_ext);
+    }
+    \endcode
+
+    The volume can either be exported as a multi-page TIFF file (variant 2, only available if
+    libtiff is installed), or as a stack of 2D images, one image per slice (variant 3, files are named 
+    according to the scheme <tt>name_base+"000"+name_ext</tt>, <tt>name_base+"001"+name_ext</tt> etc.).
+    If the target image format does not support the source <tt>value_type</tt>, all slices will 
+    be mapped to the appropriate target range in the same way.
+    
+    Variant 1 is the basic version of the function. It allows full control over the export via
+    an already constructed \ref vigra::VolumeExportInfo object. The other two are just abbreviations
+    that construct the VolumeExportInfo object internally. 
+    
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_impex.hxx\> <br/>
+    Namespace: vigra
+    
+    \code
+    MultiArray<3, RGBValue<UInt8> > volume(shape);
+    ... // fill in data
+    
+    // export a stack named "my_data01.jpg", "my_data02.jpg" etc.
+    VolumeExportInfo info("my_data", ".jpg");
+    info.setCompression("JPEG QUALITY=95");
+    exportVolume(volume, info);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void exportVolume)
+
+template <class T, class Tag>
+void 
+exportVolume (MultiArrayView <3, T, Tag> const & volume,
+              const VolumeExportInfo & volinfo)
+{
+    if(volinfo.getFileType() == std::string("MULTIPAGE"))
+    {
+        char const * mode = "w";
+        std::string compression = "LZW";
+        if(volinfo.getCompression() != std::string())
+            compression = volinfo.getCompression();
+            
+        for(MultiArrayIndex k=0; k<volume.shape(2); ++k)
+        {
+            ImageExportInfo info(volinfo.getFileNameBase(), mode);
+            info.setFileType("TIFF");
+            info.setCompression(compression.c_str());
+            info.setPixelType(volinfo.getPixelType());
+            detail::setRangeMapping(volume, info, typename NumericTraits<T>::isScalar());
+            exportImage(volume.bindOuter(k), info);
+            mode = "a";
+        }
+    }
+    else
+    {
+        std::string name = std::string(volinfo.getFileNameBase()) + std::string(volinfo.getFileNameExt());
+        ImageExportInfo info(name.c_str());
+        info.setCompression(volinfo.getCompression());
+        info.setPixelType(volinfo.getPixelType());
+        detail::setRangeMapping(volume, info, typename NumericTraits<T>::isScalar());
+
+        const unsigned int depth = volume.shape (2);
+        int numlen = static_cast <int> (std::ceil (std::log10 ((double)depth)));
+        for (unsigned int i = 0; i < depth; ++i)
+        {
+            // build the filename
+            std::stringstream stream;
+            stream << std::setfill ('0') << std::setw (numlen) << i;
+            std::string name_num;
+            stream >> name_num;
+            std::string name = std::string(volinfo.getFileNameBase()) + name_num + std::string(volinfo.getFileNameExt());
+
+            MultiArrayView <2, T, Tag> view (volume.bindOuter (i));
+
+            // export the image
+            info.setFileName(name.c_str ());
+            exportImage(srcImageRange(view), info); 
+        }
+    }
+}
+
+template <class T, class Tag>
+inline void
+exportVolume (MultiArrayView <3, T, Tag> const & volume,
+              const std::string &filename)
+{
+    VolumeExportInfo volinfo(filename.c_str());
+    exportVolume(volume, volinfo);
+}
+
+template <class T, class Tag>
+inline void
+exportVolume (MultiArrayView <3, T, Tag> const & volume,
+              const std::string &name_base,
+              const std::string &name_ext)
+{
+    VolumeExportInfo volinfo(name_base.c_str(), name_ext.c_str());
+    exportVolume(volume, volinfo);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_MULTI_IMPEX_HXX
diff --git a/include/vigra/multi_iterator.hxx b/include/vigra/multi_iterator.hxx
new file mode 100644
index 0000000..3c29884
--- /dev/null
+++ b/include/vigra/multi_iterator.hxx
@@ -0,0 +1,2255 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2003-2012 by Gunnar Kedenburg and Ullrich Koethe       */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    ( Version 1.3.0, Sep 10 2004 )                                    */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_ITERATOR_HXX
+#define VIGRA_MULTI_ITERATOR_HXX
+
+#include <sys/types.h>
+#include "iteratortags.hxx"
+#include "multi_iterator_coupled.hxx"
+
+namespace vigra {
+
+template<unsigned int N, class DirectedTag>
+class GridGraph;
+
+/** \addtogroup MultiIteratorGroup
+*/
+//@{
+
+    /** \brief Iterate over a virtual array where each element contains its coordinate.
+
+        MultiCoordinateIterator behaves like a read-only random access iterator. 
+        It moves accross the given region of interest in scan-order (with the first
+        index changing most rapidly), and dereferencing the iterator returns the 
+        coordinate (i.e. multi-dimensional index) of the current array element. 
+        The functionality is thus similar to a meshgrid in Matlab or numpy. 
+        
+        Internally, it is just a wrapper of a \ref CoupledScanOrderIterator that
+        has been created without any array and whose reference type is not a 
+        \ref CoupledHandle, but the coordinate itself.
+                
+        The iterator supports all functions listed in the STL documentation for 
+        <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterators</a>.
+
+        <b>Usage:</b>
+
+        <b>\#include</b> \<vigra/multi_iterator.hxx\><br/>
+        Namespace: vigra
+        
+        \code
+        MultiCoordinateIterator<3> i(Shape3(3,2,1)), end = i.getEndIterator();
+        
+        for(; i != end; ++i)
+            std::cout << *i << "\n";
+            
+        // Output:
+        // (0, 0, 0)
+        // (1, 0, 0)
+        // (2, 0, 0)
+        // (0, 1, 0)
+        // (1, 1, 0)
+        // (2, 1, 0)
+        \endcode
+    */
+template<unsigned int N>
+class MultiCoordinateIterator
+    : public CoupledScanOrderIterator<N>
+{
+  public:
+    typedef CoupledScanOrderIterator<N>            base_type;
+
+    typedef typename base_type::shape_type         shape_type;
+    typedef typename base_type::difference_type    difference_type;
+    typedef MultiCoordinateIterator                iterator;
+    typedef std::random_access_iterator_tag        iterator_category;
+
+    typedef typename base_type::value_type         handle_type;
+    typedef typename handle_type::value_type       value_type;
+    typedef typename handle_type::reference        reference;
+    typedef typename handle_type::const_reference  const_reference;
+    typedef typename handle_type::pointer          pointer;
+    typedef typename handle_type::const_pointer    const_pointer;
+
+    MultiCoordinateIterator() 
+        : base_type(handle_type())
+    {}
+
+    explicit MultiCoordinateIterator(shape_type const & shape) 
+        : base_type(handle_type(shape))
+    {}
+
+    explicit MultiCoordinateIterator(shape_type const & start, shape_type const & end) 
+        : base_type(handle_type(end))
+    {
+        this->restrictToSubarray(start, end);
+    }
+
+    template<class DirectedTag>
+    explicit MultiCoordinateIterator(GridGraph<N, DirectedTag> const & g) 
+       : base_type(handle_type(g.shape()))
+    {}
+
+    // dereferencing the iterator yields the coordinate object
+    // (used as vertex_descriptor)
+    reference operator*()
+    {
+        return this->template get<0>();
+    }
+    
+    const_reference operator*() const
+    {
+        return this->template get<0>();
+    }
+    
+    operator value_type() const
+    {
+        return *(*this);
+    }
+
+    pointer operator->()
+    {
+        return &this->template get<0>();
+    }
+    
+    const_pointer operator->() const
+    {
+        return &this->template get<0>();
+    }
+
+    value_type operator[](MultiArrayIndex i) const
+    {
+        return *(MultiCoordinateIterator(*this) += i);
+    }
+
+    MultiCoordinateIterator & operator++()
+    {
+        base_type::operator++();
+        return *this;
+    }
+    
+    MultiCoordinateIterator operator++(int)
+    {
+        MultiCoordinateIterator res(*this);
+        ++*this;
+        return res;
+    }
+
+    MultiCoordinateIterator & operator+=(MultiArrayIndex i)
+    {
+        base_type::operator+=(i);
+        return *this;
+    }
+
+    MultiCoordinateIterator & operator+=(const shape_type &coordOffset)
+    {
+        base_type::operator+=(coordOffset);
+        return *this;
+    }
+
+    MultiCoordinateIterator & operator--()
+    {
+        base_type::operator--();
+        return *this;
+    }
+
+    MultiCoordinateIterator operator--(int)
+    {
+        MultiCoordinateIterator res(*this);
+        --*this;
+        return res;
+    }
+
+    MultiCoordinateIterator & operator-=(MultiArrayIndex i)
+    {
+        return operator+=(-i);
+    }
+
+    MultiCoordinateIterator & operator-=(const shape_type &coordOffset)
+    {
+        return operator+=(-coordOffset);
+    }
+
+    MultiCoordinateIterator getEndIterator() const
+    {
+        return MultiCoordinateIterator(base_type::getEndIterator());
+    }
+
+    MultiCoordinateIterator operator+(MultiArrayIndex d) const
+    {
+        return MultiCoordinateIterator(*this) += d;
+    }
+
+    MultiCoordinateIterator operator-(MultiArrayIndex d) const
+    {
+        return MultiCoordinateIterator(*this) -= d;
+    }
+
+    MultiCoordinateIterator operator+(const shape_type &coordOffset) const
+    {
+        return MultiCoordinateIterator(*this) += coordOffset;
+    }
+
+    MultiCoordinateIterator operator-(const shape_type &coordOffset) const
+    {
+        return MultiCoordinateIterator(*this) -= coordOffset;
+    }
+
+    MultiArrayIndex operator-(const MultiCoordinateIterator & other) const
+    {
+        return base_type::operator-(other);
+    }
+    
+  protected:
+    MultiCoordinateIterator(base_type const & base) 
+        : base_type(base)
+    {}
+};
+
+    /** \brief Sequential iterator for MultiArrayView.
+        
+        This iterator provides STL-compatible random access iterator functionality for arbitrary 
+        \ref MultiArrayView instances, regardless of their shapes and strides. The
+        class uses an implementation that minimizes speed penalties that could result from 
+        non-trivial strides. The <i>scan-order</i> is defined such that dimensions are iterated 
+        from front to back (first to last).
+        
+        You normally construct instances of this class by calling \ref MultiArrayView::begin() 
+        and \ref MultiArrayView::end(). 
+        
+        The iterator supports all functions listed in the STL documentation for 
+        <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterators</a>.
+        
+        <b>\#include</b> \<vigra/multi_iterator.hxx\><br/>
+        Namespace: vigra
+    */
+template <unsigned int N, class T, class REFERENCE, class POINTER>
+class StridedScanOrderIterator
+    : public CoupledIteratorType<N, T>::type
+{
+  public:
+    typedef typename CoupledIteratorType<N, T>::type  base_type;
+
+    typedef typename base_type::shape_type         shape_type;
+    typedef typename base_type::difference_type    difference_type;
+    typedef StridedScanOrderIterator              iterator;
+    typedef std::random_access_iterator_tag        iterator_category;
+
+    typedef T                                      value_type;
+    typedef REFERENCE                              reference;
+    typedef T const &                              const_reference;
+    typedef POINTER                                pointer;
+    typedef T const *                              const_pointer;
+
+    StridedScanOrderIterator() 
+        : base_type()
+    {}
+
+    template <class S>
+    explicit StridedScanOrderIterator(MultiArrayView<N, T, S> const & view) 
+        : base_type(createCoupledIterator(view))
+    {}
+
+    StridedScanOrderIterator(POINTER p, shape_type const & shape, shape_type const & strides) 
+        : base_type(createCoupledIterator(MultiArrayView<N, T, StridedArrayTag>(shape, strides, const_cast<T *>(p))))
+    {}
+
+    reference operator*()
+    {
+        return this->template get<1>();
+    }
+    
+    const_reference operator*() const
+    {
+        return this->template get<1>();
+    }
+
+    pointer operator->()
+    {
+        return &this->template get<1>();
+    }
+    
+    const_pointer operator->() const
+    {
+        return &this->template get<1>();
+    }
+
+    reference operator[](MultiArrayIndex i)
+    {
+        return *(StridedScanOrderIterator(*this) += i);
+    }
+
+    const_reference operator[](MultiArrayIndex i) const
+    {
+        return *(StridedScanOrderIterator(*this) += i);
+    }
+
+    StridedScanOrderIterator & operator++()
+    {
+        base_type::operator++();
+        return *this;
+    }
+    
+    StridedScanOrderIterator operator++(int)
+    {
+        StridedScanOrderIterator res(*this);
+        ++*this;
+        return res;
+    }
+
+    StridedScanOrderIterator & operator+=(MultiArrayIndex i)
+    {
+        base_type::operator+=(i);
+        return *this;
+    }
+
+    StridedScanOrderIterator & operator+=(const shape_type &coordOffset)
+    {
+        base_type::operator+=(coordOffset);
+        return *this;
+    }
+
+    StridedScanOrderIterator & operator--()
+    {
+        base_type::operator--();
+        return *this;
+    }
+
+    StridedScanOrderIterator operator--(int)
+    {
+        StridedScanOrderIterator res(*this);
+        --*this;
+        return res;
+    }
+
+    StridedScanOrderIterator & operator-=(MultiArrayIndex i)
+    {
+        return operator+=(-i);
+    }
+
+    StridedScanOrderIterator & operator-=(const shape_type &coordOffset)
+    {
+        return operator+=(-coordOffset);
+    }
+
+    StridedScanOrderIterator getEndIterator() const
+    {
+        return StridedScanOrderIterator(base_type::getEndIterator());
+    }
+
+    StridedScanOrderIterator operator+(MultiArrayIndex d) const
+    {
+        return StridedScanOrderIterator(*this) += d;
+    }
+
+    StridedScanOrderIterator operator-(MultiArrayIndex d) const
+    {
+        return StridedScanOrderIterator(*this) -= d;
+    }
+
+    MultiArrayIndex operator-(StridedScanOrderIterator const & other) const
+    {
+        return base_type::operator-(other);
+    }
+
+    StridedScanOrderIterator operator+(const shape_type &coordOffset) const
+    {
+        return StridedScanOrderIterator(*this) += coordOffset;
+    }
+
+    StridedScanOrderIterator operator-(const shape_type &coordOffset) const
+    {
+        return StridedScanOrderIterator(*this) -= coordOffset;
+    }
+    
+    MultiArrayIndex index() const
+    {
+        return this->scanOrderIndex();
+    }
+    
+  protected:
+    StridedScanOrderIterator(base_type const & base) 
+        : base_type(base)
+    {}
+};
+
+//@}
+
+/** \page MultiIteratorPage  Multi-dimensional Array Iterators
+
+General iterators for arrays of arbitrary dimension.
+
+<p>
+<UL style="list-style-image:url(documents/bullet.gif)">
+<LI> \ref vigra::MultiArrayShape
+     <BR>   <em>Difference type for \ref vigra::MultiArrayView or \ref vigra::MultiIterator</em>
+<LI> \ref vigra::MultiIterator
+     <BR>   <em>Iterator for unstrided \ref vigra::MultiArrayView</em>
+<LI> \ref vigra::StridedMultiIterator
+     <BR>   <em>Iterator for strided \ref vigra::MultiArrayView</em>
+<LI> \ref vigra::StridedScanOrderIterator
+     <BR>   <em>STL-compatible random access iterator for \ref vigra::MultiArrayView</em>
+<LI> \ref vigra::CoupledScanOrderIterator
+     <BR>   <em>Iterate over multiple images simultaneously in scan order</em>
+</UL>
+</p>
+
+<p>
+    The Multidimensional Iterator concept allows navigation on arrays
+    of arbitrary dimension. It provides two modes of iteration: 
+    <em>direct traversal</em>, and <em>hierarchical traversal</em>.
+    In general, hierarchical traversal will be faster, while only 
+    direct traversal allows for true random access in all dimensions.
+    Via the <tt>dim<K>()</tt> function, operations applying to a particular
+    dimension can be used in the direct traversal mode. In contrast,
+    direct traversal functions should not be used in the hierarchical mode
+    because the hierarchical functions are only well-defined if the
+    iterator points to element 0 in all dimensions below its current dimension.
+    The current dimension of a <tt>MultiIterator<N, ...></tt> is <tt>N-1</tt>.
+</p>
+<h3>General Requirements for MultiIterator</h3>
+<p>
+<table border=2 cellspacing=0 cellpadding=2 width="100%">
+<tr><th colspan=2>
+    Local Types
+    </th><th>
+    Meaning
+    </th>
+</tr>
+<tr><td colspan=2>
+    <tt>MultiIterator::value_type</tt></td><td>the underlying arrays's pixel type</td>
+</tr>
+<tr><td colspan=2>
+    <tt>MultiIterator::reference</tt></td>
+    <td>the iterator's reference type (return type of <TT>*iter</TT>). Will be
+    <tt>value_type &</tt> for a mutable iterator, and convertible to
+    <tt>value_type const &</tt> for a const iterator.</td>
+</tr>
+<tr><td colspan=2>
+    <tt>MultiIterator::pointer</tt></td>
+    <td>the iterator's pointer type (return type of <TT>iter.operator->()</TT>). Will be
+    <tt>value_type *</tt> for a mutable iterator, and convertible to
+    <tt>value_type const *</tt> for a const iterator.</td>
+</tr>
+<tr><td colspan=2>
+    <tt>MultiIterator::iterator_category</tt></td>
+    <td>the iterator tag (<tt>vigra::multi_dimensional_traverser_tag</tt>)</td>
+</tr>
+<tr><th>
+    Operation
+    </th><th>
+    Result
+    </th><th>
+    Semantics
+    </th>
+</tr>
+<tr><td colspan=2>
+    <tt>MultiIterator k;</tt></td><td>default constructor</td>
+</tr>
+<tr><td colspan=2>
+    <tt>MultiIterator k(i);</tt></td><td>copy constructor</td>
+</tr>
+<tr>
+    <td><tt>k = i</tt></td>
+    <td><tt>MultiIterator &</tt></td><td>assignment</td>
+</tr>
+<tr>
+    <td><tt>i == j</tt></td><td><tt>bool</tt></td>
+    <td>equality (iterators point to the same element)</td>
+</tr>
+<tr>
+    <td><tt>i != j</tt></td><td><tt>bool</tt></td>
+    <td>inequality (iterators don't point to the same element)</td>
+</tr>
+<tr>
+    <td><tt>*i</tt></td><td><tt>MultiIterator::reference</tt></td>
+    <td>access the current element</td>
+</tr>
+<tr>
+    <td><tt>i->member()</tt></td><td>depends on operation</td>
+    <td>call member function of underlying pixel type via <tt>operator-></tt> of iterator</td>
+</tr>
+</table>
+</p>
+<h3>Requirements for Direct Traversal</h3>
+<p>
+<table border=2 cellspacing=0 cellpadding=2 width="100%">
+<tr><th colspan=2>
+    Local Types
+    </th><th>
+    Meaning
+    </th>
+</tr>
+<tr><td colspan=2>
+    <tt>MultiIterator::multi_difference_type</tt></td>
+    <td>the iterator's multi-dimensional difference type (<TT>TinyVector<MultiArrayIndex, N></TT>)</td>
+</tr>
+<tr><th>
+    Operation
+    </th><th>
+    Result
+    </th><th>
+    Semantics
+    </th>
+</tr>
+<tr>
+    <td><tt>i += diff</tt></td><td><tt>MultiIterator &</tt></td>
+    <td>add offset to current position</td>
+</tr>
+<tr>
+    <td><tt>i -= diff</tt></td><td><tt>MultiIterator &</tt></td>
+    <td>subtract offset from current position</td>
+</tr>
+<tr>
+    <td><tt>i + diff</tt></td><td><tt>MultiIterator</tt></td>
+    <td>create traverser by adding offset</td>
+</tr>
+<tr>
+    <td><tt>i - diff</tt></td><td><tt>MultiIterator</tt></td>
+    <td>create traverser by subtracting offset</td>
+</tr>
+<tr>
+    <td><tt>i[diff]</tt></td><td><tt>MultiIterator::reference</tt></td>
+    <td>access element at offset <tt>diff</tt></td>
+</tr>
+<tr>
+    <td><tt>i.dim<K>()</tt></td><td><tt>MultiIterator<K+1, T, ...></tt></td>
+    <td>Access the traverser with the current dimension set to K. Typically used to call
+        navigation functions referring to a particular dimension.<br>
+        Example (assuming <tt>i, j</tt> are 3-dimensional):<br>
+        \code
+        i.dim<0>()++;   // increment dimension 0 
+        i.dim<1>()++;   // increment dimension 1 
+        i.dim<2>()++;   // increment dimension 2 
+        
+        j += MultiIterator::multi_difference_type(1,1,1);    // same effect
+        \endcode
+    </td>
+</tr>
+<tr><td colspan=3>
+       <tt>i, j</tt> are of type <tt>MultiIterator</tt><br>
+       <tt>diff</tt> is of type <tt>MultiIterator::multi_difference_type</tt><br>
+       <tt>K</tt> is an integer compile-time constant
+    </td>
+</tr>
+</table>
+</p>
+<p>
+Note that it is impossible to support an <tt>operator-</tt> between two iterators which returns
+a <tt>MultiIterator::multi_difference_type</tt> because it is impossible to decide to which
+dimension a difference applies. Consider for example, a 2-dimensional iterator <tt>i</tt>, and
+let <tt>j = i + multi_difference_type(width, 0)</tt>, <tt>k = i + multi_difference_type(0,1)</tt>, 
+where <tt>width</tt> is the array's total width. In general, <tt>j</tt> and <tt>k</tt> point to 
+the same memory location, so that the two cases cannot easily be distinguished (it is possible,
+but iterator performance will suffer significantly, as is experienced with 
+\ref vigra::ImageIterator where differencing is allowed).
+</p>
+
+<h3>Requirements for Hierarchical Traversal</h3>
+<p>
+<table border=2 cellspacing=0 cellpadding=2 width="100%">
+<tr><th colspan=2>
+    Local Types
+    </th><th>
+    Meaning
+    </th>
+</tr>
+<tr><td colspan=2>
+    <tt>MultiIterator::difference_type</tt></td>
+    <td>the iterator's difference type (<TT>MultiArrayIndex</TT>)</td>
+</tr>
+<tr><td colspan=2>
+    <tt>MultiIterator::next_type</tt></td><td>type of the next iterator
+       (referring to the next lower dimension) in the hierarchy</td>
+</tr>
+<tr><th>
+    Operation
+    </th><th>
+    Result
+    </th><th>
+    Semantics
+    </th>
+</tr>
+<tr>
+    <td><tt>++i</tt></td><td><tt>MultiIterator &</tt></td>
+    <td>pre-increment iterator in its current dimension</td>
+</tr>
+<tr>
+    <td><tt>i++</tt></td><td><tt>MultiIterator</tt></td>
+    <td>post-increment iterator in its current dimension</td>
+</tr>
+<tr>
+    <td><tt>--i</tt></td><td><tt>MultiIterator &</tt></td>
+    <td>pre-decrement iterator in its current dimension</td>
+</tr>
+<tr>
+    <td><tt>i--</tt></td><td><tt>MultiIterator</tt></td>
+    <td>post-decrement iterator in its current dimension</td>
+</tr>
+<tr>
+    <td><tt>i += d</tt></td><td><tt>MultiIterator &</tt></td>
+    <td>add <tt>d</tt> in current dimension</td>
+</tr>
+<tr>
+    <td><tt>i -= d</tt></td><td><tt>MultiIterator &</tt></td>
+    <td>subtract <tt>d</tt> in from dimension</td>
+</tr>
+<tr>
+    <td><tt>i + d</tt></td><td><tt>MultiIterator</tt></td>
+    <td>create new iterator by adding <tt>d</tt> in current dimension</td>
+</tr>
+<tr>
+    <td><tt>i - d</tt></td><td><tt>MultiIterator</tt></td>
+    <td>create new iterator by subtracting <tt>d</tt> in current dimension</td>
+</tr>
+<tr>
+    <td><tt>i - j</tt></td><td><tt>difference_type</tt></td>
+    <td>difference of <tt>i</tt> and <tt>j</tt> in the current dimension<br>
+    <em>Note:</em> The result of this operation is undefined if the iterator
+    doesn't point to element 0 in all dimensions below its current dimension.</td>
+</tr>
+<tr>
+    <td><tt>i < j</tt></td><td><tt>bool</tt></td>
+    <td><tt>i - j < 0</tt><br>
+    <em>Note:</em> The result of this operation is undefined if the iterator
+    doesn't point to element 0 in all dimensions below its current dimension.</td>
+</tr>
+<tr>
+    <td><tt>i[d]</tt></td><td><tt>MultiIterator::reference</tt></td>
+    <td>access element by adding offset <tt>d</tt> in current dimension</td>
+</tr>
+<tr>
+    <td><tt>i.begin()</tt></td><td><tt>next_type</tt></td>
+    <td>create the hierarchical iterator pointing to the first element in the 
+    next lower dimension.<br>
+    <em>Note:</em> The result of this operation is undefined if the iterator
+    doesn't point to element 0 in all dimensions below its current dimension.<br>
+    Usage:<br>
+    \code
+    MultiIterator<3, int> i3 = ..., end3 = ...;
+    for(; i3 != end3; ++i3)
+    {
+        MultiIterator<3, int>::next_type i2 = i3.begin(), end2 = i3.end();
+        for(; i2 != end2; ++i2)
+        {
+            MultiIterator<3, int>::next_type::next_type i1 = i2.begin(), end1 = i2.end();
+            for(; i1 != end1; ++i1)
+            {
+                ... // do something with the current element
+            }
+        }
+    }
+    
+    \endcode
+    </td>
+</tr>
+<tr>
+    <td><tt>i.end()</tt></td><td><tt>next_type</tt></td>
+    <td>create the hierarchical iterator pointing to the past-the-end location in the 
+    next lower dimension.<br>
+    <em>Note:</em> The result of this operation is undefined if the iterator
+    doesn't point to element 0 in all dimensions below its current dimension.</td>
+</tr>
+<tr><td colspan=3>
+       <tt>i, j</tt> are of type <tt>MultiIterator</tt><br>
+       <tt>d</tt> is of type <tt>MultiIterator::difference_type</tt>
+    </td>
+</tr>
+</table>
+</p>
+
+*/
+
+/** \addtogroup MultiIteratorGroup  
+*/
+//@{
+
+template <class POINTER>
+struct MultiIteratorStrideTraits
+{
+    typedef MultiArrayIndex    stride_type;
+    typedef const stride_type* stride_array_type;
+    typedef stride_array_type  shape_array_type;
+    static stride_array_type shift(stride_array_type s, unsigned d)
+    {
+        return s + d;
+    }
+};
+
+template <unsigned int N, class T, class REFERENCE = T &, class POINTER = T *>
+class MultiIterator;
+
+template <unsigned int N, class T, class REFERENCE = T &, class POINTER = T *>
+class StridedMultiIterator;
+
+/********************************************************/
+/*                                                      */
+/*                      MultiIterator                   */
+/*                                                      */
+/********************************************************/
+
+/********************************************************/
+/*                                                      */
+/*                   MultiIterator<1>                   */
+/*                                                      */
+/********************************************************/
+
+//
+template <class T, class REFERENCE, class POINTER>
+class MultiIterator<1, T, REFERENCE, POINTER>
+{
+  public:
+    enum { level = 0 };
+    typedef T value_type;
+    typedef REFERENCE reference;
+    typedef const value_type &const_reference;
+    typedef POINTER pointer;
+    typedef const value_type *const_pointer;
+    typedef typename MultiArrayShape<1>::type multi_difference_type;
+    typedef MultiIteratorStrideTraits<POINTER> stride_traits;
+    typedef typename stride_traits::stride_type difference_type;
+    typedef typename stride_traits::stride_array_type difference_array_type;
+    typedef typename stride_traits::shape_array_type shape_array_type;
+    typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
+    typedef std::random_access_iterator_tag iterator_category;
+
+  protected:
+    pointer m_ptr;
+
+  public:
+    MultiIterator ()
+        : m_ptr (0)
+    {}
+
+    MultiIterator (pointer ptr,
+          const difference_array_type &,
+          const shape_array_type &)
+        : m_ptr (ptr)
+    {}
+
+    void operator++ ()
+    {
+        ++m_ptr;
+    }
+
+    void operator-- ()
+    {
+        --m_ptr;
+    }
+
+    MultiIterator operator++ (int)
+    {
+        MultiIterator ret = *this;
+        ++(*this);
+        return ret;
+    }
+
+    MultiIterator operator-- (int)
+    {
+        MultiIterator ret = *this;
+        --(*this);
+        return ret;
+    }
+
+    MultiIterator &operator+= (difference_type n)
+    {
+        m_ptr += n;
+        return *this;
+    }
+
+    MultiIterator & operator+= (multi_difference_type const & d)
+    {
+        m_ptr += d[level];
+        return *this;
+    }
+
+    MultiIterator &operator-= (difference_type n)
+    {
+        m_ptr -= n;
+        return *this;
+    }
+
+    MultiIterator & operator-= (multi_difference_type const & d)
+    {
+        m_ptr -= d[level];
+        return *this;
+    }
+
+    MultiIterator operator+ (difference_type n) const
+    {
+        MultiIterator ret = *this;
+        ret += n;
+        return ret;
+    }
+
+    MultiIterator operator+ (multi_difference_type const & d) const
+    {
+        MultiIterator ret = *this;
+        ret += d;
+        return ret;
+    }
+
+    difference_type operator- (MultiIterator const & d) const
+    {
+        return (m_ptr - d.m_ptr);
+    }
+
+    MultiIterator operator- (difference_type n) const
+    {
+        MultiIterator ret = *this;
+        ret -= n;
+        return ret;
+    }
+
+    MultiIterator operator- (multi_difference_type const & d) const
+    {
+        MultiIterator ret = *this;
+        ret -= d;
+        return ret;
+    }
+
+    reference operator[] (difference_type n) const
+    {
+        return m_ptr [n];
+    }
+
+    reference operator[] (multi_difference_type const & d) const
+    {
+        return m_ptr [d[level]];
+    }
+
+    reference operator* () const
+    {
+        return *m_ptr;
+    }
+
+    pointer get () const
+    {
+        return m_ptr;
+    }
+
+    pointer operator->() const
+    {
+        return &(operator*());
+    }
+
+    bool operator!= (const MultiIterator &rhs) const
+    {
+        return m_ptr != rhs.m_ptr;
+    }
+
+    bool operator== (const MultiIterator &rhs) const
+    {
+        return m_ptr == rhs.m_ptr;
+    }
+
+    bool operator< (const MultiIterator &rhs) const
+    {
+        return m_ptr < rhs.m_ptr;
+    }
+
+    bool operator<= (const MultiIterator &rhs) const
+    {
+        return m_ptr <= rhs.m_ptr;
+    }
+
+    bool operator> (const MultiIterator &rhs) const
+    {
+        return m_ptr > rhs.m_ptr;
+    }
+
+    bool operator>= (const MultiIterator &rhs) const
+    {
+        return m_ptr >= rhs.m_ptr;
+    }
+
+    iterator iteratorForDimension(unsigned int d) const
+    {
+        vigra_precondition(d == 0,
+            "MultiIterator<1>::iteratorForDimension(d): d == 0 required");
+        const difference_type stride = 1;
+        return iterator(m_ptr, &stride, 0);
+    }
+
+    template <unsigned int K>
+    MultiIterator<K+1, T, REFERENCE, POINTER> &
+    dim()
+    {
+        return *this;
+    }
+
+    MultiIterator<1, T, REFERENCE, POINTER> &
+    dim0() { return *this; }
+
+  protected:
+
+    difference_type 
+    total_stride(typename multi_difference_type::const_iterator d) const
+    {
+        return d[level];
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                   MultiIterator<2>                   */
+/*                                                      */
+/********************************************************/
+
+//
+template <class T, class REFERENCE, class POINTER>
+class MultiIterator<2, T, REFERENCE, POINTER>
+#ifndef DOXYGEN  // doxygen doesn't understand this inheritance
+: public MultiIterator<1, T, REFERENCE, POINTER>
+#endif
+{
+  public:
+
+    typedef MultiIterator<1, T, REFERENCE, POINTER> base_type;
+    enum { level = 1 };
+    typedef T value_type;
+    typedef REFERENCE reference;
+    typedef const value_type &const_reference;
+    typedef POINTER pointer;
+    typedef const value_type *const_pointer;
+    typedef typename MultiArrayShape<2>::type multi_difference_type;
+    typedef MultiIteratorStrideTraits<POINTER> stride_traits;
+    typedef typename stride_traits::stride_type difference_type;
+    typedef typename stride_traits::stride_array_type difference_array_type;
+    typedef typename stride_traits::shape_array_type shape_array_type;
+    typedef base_type next_type;
+    typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
+    typedef multi_dimensional_traverser_tag iterator_category;
+
+  protected:
+    difference_array_type m_stride;
+    shape_array_type      m_shape;
+
+  public:
+    /* use default copy constructor and assignment operator */
+
+    MultiIterator ()
+        : base_type (),
+          m_stride (0), m_shape (0)
+    {}
+
+    MultiIterator (pointer ptr,
+          const difference_array_type & stride,
+          const shape_array_type & shape)
+        : base_type (ptr, stride, shape),
+          m_stride (stride), m_shape (shape)
+    {}
+
+    void operator++ ()
+    {
+        this->m_ptr += m_stride [level];
+    }
+
+    void operator-- ()
+    {
+        this->m_ptr -= m_stride [level];
+    }
+
+    MultiIterator operator++ (int)
+    {
+        MultiIterator ret = *this;
+        ++(*this);
+        return ret;
+    }
+
+    MultiIterator operator-- (int)
+    {
+        MultiIterator ret = *this;
+        --(*this);
+        return ret;
+    }
+
+    MultiIterator & operator+= (difference_type n)
+    {
+        this->m_ptr += n * m_stride [level];
+        return *this;
+    }
+
+    MultiIterator & operator+= (multi_difference_type const & d)
+    {
+        this->m_ptr += total_stride(d.begin());
+        return *this;
+    }
+
+    MultiIterator  &operator-= (difference_type n)
+    {
+        this->m_ptr -= n * m_stride [level];
+        return *this;
+    }
+
+    MultiIterator & operator-= (multi_difference_type const & d)
+    {
+        this->m_ptr -= total_stride(d.begin());
+        return *this;
+    }
+
+    MultiIterator operator+ (difference_type n) const
+    {
+        MultiIterator ret = *this;
+        ret += n;
+        return ret;
+    }
+
+    MultiIterator operator+ (multi_difference_type const & d) const
+    {
+        MultiIterator ret = *this;
+        ret += d;
+        return ret;
+    }
+
+    difference_type operator- (MultiIterator const & d) const
+    {
+        return (this->m_ptr - d.m_ptr) / this->m_stride[level];
+    }
+
+    MultiIterator operator- (difference_type n) const
+    {
+        MultiIterator ret = *this;
+        ret -= n;
+        return ret;
+    }
+
+    MultiIterator operator- (multi_difference_type const & d) const
+    {
+        MultiIterator ret = *this;
+        ret -= d;
+        return ret;
+    }
+
+    reference operator[] (difference_type n) const
+    {
+        return this->m_ptr [n*m_stride [level]];
+    }
+
+    reference operator[] (multi_difference_type const & d) const
+    {
+        return this->m_ptr [total_stride(d.begin())];
+    }
+
+    next_type begin () const
+    {
+        return *this;
+    }
+
+    next_type end () const
+    {
+        next_type ret = *this;
+        ret += m_shape [level-1];
+        return ret;
+    }
+
+    iterator iteratorForDimension(unsigned int d) const
+    {
+        vigra_precondition(d <= level,
+            "MultiIterator<N>::iteratorForDimension(d): d < N required");
+        return iterator(this->m_ptr, stride_traits::shift(m_stride, d), 0);
+    }
+
+    template <unsigned int K>
+    MultiIterator<K+1, T, REFERENCE, POINTER> &
+    dim()
+    {
+        return *this;
+    }
+
+    MultiIterator<1, T, REFERENCE, POINTER> &
+    dim0() { return *this; }
+    MultiIterator<2, T, REFERENCE, POINTER> &
+    dim1() { return *this; }
+
+  protected:
+
+    difference_type 
+    total_stride(typename multi_difference_type::const_iterator d) const
+    {
+        return d[level]*m_stride[level] + base_type::total_stride(d);
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                   MultiIterator<N>                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief A multi-dimensional hierarchical iterator to be used with 
+           \ref vigra::MultiArrayView if it is not strided.
+
+    See \ref MultiIteratorPage for further documentation.
+
+    <b>\#include</b> \<vigra/multi_iterator.hxx\> <br>
+    Namespace: vigra
+*/
+template <unsigned int N, class T, class REFERENCE, class POINTER>
+class MultiIterator 
+#ifndef DOXYGEN  // doxygen doesn't understand this inheritance
+: public MultiIterator<N-1, T, REFERENCE, POINTER>
+#endif
+{
+public:
+
+        /** the type of the parent in the inheritance hierarchy.
+         */
+    typedef MultiIterator<N-1, T, REFERENCE, POINTER> base_type;
+        
+        /** the iterator's level in the dimension hierarchy
+         */
+    enum { level = N-1 };
+
+        /** the iterator's value type
+         */
+    typedef T value_type;
+
+        /** reference type (result of operator[])
+         */
+    typedef REFERENCE reference;
+
+        /** const reference type (result of operator[] const)
+         */
+    typedef const value_type &const_reference;
+
+        /** pointer type
+         */
+    typedef POINTER pointer;
+
+        /** const pointer type
+         */
+    typedef const value_type *const_pointer;
+
+        /** multi difference type 
+            (used for offsetting along all axes simultaneously)
+         */
+    typedef typename MultiArrayShape<N>::type multi_difference_type;
+    
+        /** difference type (used for offsetting)
+         */
+#ifndef DOXYGEN
+    typedef MultiIteratorStrideTraits<POINTER> stride_traits;
+    typedef typename stride_traits::stride_type difference_type;
+    typedef typename stride_traits::stride_array_type difference_array_type;
+    typedef typename stride_traits::shape_array_type shape_array_type;
+#else
+    typedef MultiArrayIndex difference_type;
+#endif
+
+        /** the MultiIterator for the next lower dimension.
+         */
+    typedef base_type next_type;
+
+        /** the 1-dimensional iterator for this iterator hierarchy
+            (result of iteratorForDimension()).
+        */
+    typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
+
+        /** the iterator tag (image traverser)
+        */
+    typedef multi_dimensional_traverser_tag iterator_category;
+            
+    /* use default copy constructor and assignment operator */
+
+        /** default constructor.
+        */
+    MultiIterator ()
+    {}
+
+        /** construct from pointer, strides (offset of a sample to the
+            next) for every dimension, and the shape.
+        */
+    MultiIterator (pointer ptr,
+                   const difference_array_type & stride,
+                   const shape_array_type & shape)
+        : base_type (ptr, stride, shape)
+    {}
+
+
+        /** prefix-increment the iterator in its current dimension
+         */
+    void operator++ ()
+    {
+        this->m_ptr += this->m_stride [level];
+    }
+
+        /** prefix-decrement the iterator in its current dimension
+         */
+    void operator-- ()
+    {
+        this->m_ptr -= this->m_stride [level];
+    }
+
+        /** postfix-increment the iterator in its current dimension
+         */
+    MultiIterator operator++ (int)
+    {
+        MultiIterator ret = *this;
+        ++(*this);
+        return ret;
+    }
+
+        /** postfix-decrement the iterator in its current dimension
+         */
+    MultiIterator operator-- (int)
+    {
+        MultiIterator ret = *this;
+        --(*this);
+        return ret;
+    }
+
+        /** increment the iterator in its current dimension
+            by the given value.
+        */
+    MultiIterator & operator+= (difference_type n)
+    {
+        this->m_ptr += n * this->m_stride [level];
+        return *this;
+    }
+
+        /** increment the iterator in all dimensions
+            by the given offset.
+        */
+    MultiIterator & operator+= (multi_difference_type const & d)
+    {
+        this->m_ptr += total_stride(d.begin());
+        return *this;
+    }
+
+        /** decrement the iterator in its current dimension
+            by the given value.
+        */
+    MultiIterator & operator-= (difference_type n)
+    {
+        this->m_ptr -= n * this->m_stride [level];
+        return *this;
+    }
+
+        /** decrement the iterator in all dimensions
+            by the given offset.
+        */
+    MultiIterator & operator-= (multi_difference_type const & d)
+    {
+        this->m_ptr -= total_stride(d.begin());
+        return *this;
+    }
+
+        /** addition within current dimension
+         */
+    MultiIterator operator+ (difference_type n) const
+    {
+        MultiIterator ret = *this;
+        ret += n;
+        return ret;
+    }
+
+        /** addition along all dimensions
+         */
+    MultiIterator operator+ (multi_difference_type const & d) const
+    {
+        MultiIterator ret = *this;
+        ret += d;
+        return ret;
+    }
+
+        /** difference of two iterators in the current dimension.
+            The result of this operation is undefined if the iterator
+            doesn't point to element 0 in all dimensions below its current dimension.
+        */
+    difference_type operator- (MultiIterator const & d) const
+    {
+        return (this->m_ptr - d.m_ptr) / this->m_stride[level];
+    }
+
+        /** subtraction within current dimension
+         */
+    MultiIterator operator- (difference_type n) const
+    {
+        MultiIterator ret = *this;
+        ret -= n;
+        return ret;
+    }
+
+        /** subtraction along all dimensions
+         */
+    MultiIterator operator- (multi_difference_type const & d) const
+    {
+        MultiIterator ret = *this;
+        ret -= d;
+        return ret;
+    }
+
+#ifdef DOXYGEN /* documentation only: operators *, ->, ==, !=, <, <=, >, >= are inherited */
+        /** derefenrence item
+         */
+    reference operator* () const;
+
+        /** get address of current item
+         */
+    pointer get () const;
+
+        /** call method of current item
+         */
+    pointer operator->() const;
+
+        /** inequality. True if iterators reference different items.
+         */
+    bool operator!= (const MultiIterator &rhs) const;
+
+        /** equality. True if iterators reference the same items.
+         */
+    bool operator== (const MultiIterator &rhs) const;
+
+        /** less than.
+         */
+    bool operator< (const MultiIterator &rhs) const;
+
+        /** less or equal.
+         */
+    bool operator<= (const MultiIterator &rhs) const;
+
+        /** greater than.
+         */
+    bool operator> (const MultiIterator &rhs) const;
+    
+        /** greater or equal.
+         */
+    bool operator>= (const MultiIterator &rhs) const;
+#endif
+
+        /** access the array element at the given offset in 
+        the current dimension.
+        */
+    reference operator[] (difference_type n) const
+    {
+        return this->m_ptr [n* this->m_stride [level]];
+    }
+
+        /** access the array element at the given offset.
+        */
+    reference operator[] (multi_difference_type const & d) const
+    {
+        return this->m_ptr [total_stride(d.begin())];
+    }
+
+        /** Return the (N-1)-dimensional multi-iterator that points to 
+            the first (N-1)-dimensional subarray of the 
+            N-dimensional array this iterator is referring to.
+            The result is only valid if this iterator refers to location
+            0 in <em>all</em> dimensions below its current dimension N,
+            otherwise it is undefined. Usage:
+
+            \code
+
+            MultiIterator<2, int> outer = ...;  // this iterator
+
+            MultiIterator<2, int>::next_type inner = outer.begin();
+            for(; inner != outer.end(); ++inner)
+            {
+                // manipulate current 1D subimage
+            }
+            \endcode
+        */
+    next_type begin () const
+    {
+        return *this;
+    }
+
+        /** Return the (N-1)-dimensional multi-iterator that points beyond 
+            the last (N-1)-dimensional subarray of the 
+            N-dimensional array this iterator is referring to.
+            The result is only valid if this iterator refers to location
+            0 in <em>all</em> dimensions below its current dimension N,
+            otherwise it is undefined.
+        */
+    next_type end () const
+    {
+        next_type ret = *this;
+        ret += this->m_shape [level-1];
+        return ret;
+    }
+
+        /** Get a 1-dimensional, STL-compatible iterator for the
+            given dimension, pointing to the current element of <TT>this</TT>.
+            Usage:
+
+            \code
+
+            MultiIterator<3, int> outer = ...;  // this iterator
+
+            MultiIterator<3, int>::iterator i = outer.iteratorForDimension(1);
+            MultiIterator<3, int>::iterator end = i + height;
+            for(; i != end; ++i)
+            {
+                // go down the current column starting at the location of 'outer'
+            }
+            \endcode            
+        */
+    iterator iteratorForDimension(unsigned int d) const
+    {
+        vigra_precondition(d <= level,
+            "MultiIterator<N>::iteratorForDimension(d): d < N required");
+        return iterator(this->m_ptr, stride_traits::shift(this->m_stride, d),0);
+    }
+        /** Return the multi-iterator that operates on dimension K in order
+            to manipulate this dimension directly. Usage:
+               
+            \code
+                
+            MultiIterator<3, int> i3 = ...;
+                
+            i3.template dim<2>()++;  // increment outer dimension
+            i3.template dim<0>()++;  // increment inner dimension
+            \endcode
+            
+            For convenience, the same functionality is also available
+            as <tt>dim0()</tt>, <tt>dim1()</tt> etc. up to <tt>dim4()</tt>:
+            
+            \code
+                
+            MultiIterator<3, int> i3 = ...;
+                
+            i3.dim2()++;  // increment outer dimension
+            i3.dim0()++;  // increment inner dimension
+            \endcode            
+        */
+    template <unsigned int K>
+    MultiIterator<K+1, T, REFERENCE, POINTER> &
+    dim()
+    {
+        return *this;
+    }
+
+    MultiIterator<1, T, REFERENCE, POINTER> &
+    dim0() { return *this; }
+    MultiIterator<2, T, REFERENCE, POINTER> &
+    dim1() { return *this; }
+    MultiIterator<3, T, REFERENCE, POINTER> &
+    dim2() { return *this; }
+    MultiIterator<4, T, REFERENCE, POINTER> &
+    dim3() { return *this; }
+    MultiIterator<5, T, REFERENCE, POINTER> &
+    dim4() { return *this; }
+
+  protected:
+
+    difference_type 
+    total_stride(typename multi_difference_type::const_iterator d) const
+    {
+        return d[level]*this->m_stride[level] + base_type::total_stride(d);
+    }
+
+};
+
+/********************************************************/
+/*                                                      */
+/*                      StridedMultiIterator            */
+/*                                                      */
+/********************************************************/
+
+/********************************************************/
+/*                                                      */
+/*                   StridedMultiIterator<1>            */
+/*                                                      */
+/********************************************************/
+
+//
+template <class T, class REFERENCE, class POINTER>
+class StridedMultiIterator<1, T, REFERENCE, POINTER>
+{
+  public:
+    enum { level = 0 };
+    typedef T value_type;
+    typedef REFERENCE reference;
+    typedef const value_type &const_reference;
+    typedef POINTER pointer;
+    typedef const value_type *const_pointer;
+    typedef typename MultiArrayShape<1>::type multi_difference_type;
+    typedef MultiIteratorStrideTraits<POINTER> stride_traits;
+    typedef typename stride_traits::stride_type difference_type;
+    typedef typename stride_traits::stride_array_type difference_array_type;
+    typedef typename stride_traits::shape_array_type shape_array_type;
+    typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
+    typedef std::random_access_iterator_tag iterator_category;
+
+  protected:
+    pointer m_ptr;
+    difference_type m_stride;
+
+    /* use default copy constructor and assignment operator */
+
+  public:
+    StridedMultiIterator ()
+        : m_ptr (0), m_stride (0)
+    {}
+
+    StridedMultiIterator (pointer ptr,
+          const difference_array_type & stride,
+          const shape_array_type &)
+        : m_ptr (ptr), m_stride (stride [level])
+    {}
+
+    void operator++ ()
+    {
+        m_ptr += m_stride;
+    }
+
+    void operator-- ()
+    {
+        m_ptr -= m_stride;
+    }
+
+    StridedMultiIterator operator++ (int)
+    {
+        StridedMultiIterator ret = *this;
+        ++(*this);
+        return ret;
+    }
+
+    StridedMultiIterator operator-- (int)
+    {
+        StridedMultiIterator ret = *this;
+        --(*this);
+        return ret;
+    }
+
+    StridedMultiIterator &operator+= (difference_type n)
+    {
+        m_ptr += n * m_stride;
+        return *this;
+    }
+
+    StridedMultiIterator & operator+= (multi_difference_type const & d)
+    {
+        m_ptr += d[level] * m_stride;
+        return *this;
+    }
+
+    StridedMultiIterator &operator-= (difference_type n)
+    {
+        m_ptr -= n * m_stride;
+        return *this;
+    }
+
+    StridedMultiIterator & operator-= (multi_difference_type const & d)
+    {
+        m_ptr -= d[level] * m_stride;
+        return *this;
+    }
+
+    StridedMultiIterator operator+ (difference_type n) const
+    {
+        StridedMultiIterator ret = *this;
+        ret += n;
+        return ret;
+    }
+
+    StridedMultiIterator operator+ (multi_difference_type const & d) const
+    {
+        StridedMultiIterator ret = *this;
+        ret += d;
+        return ret;
+    }
+
+    difference_type operator- (StridedMultiIterator const & d) const
+    {
+        return (m_ptr - d.m_ptr) / m_stride;
+    }
+
+    StridedMultiIterator operator- (difference_type n) const
+    {
+        StridedMultiIterator ret = *this;
+        ret -= n;
+        return ret;
+    }
+
+    StridedMultiIterator operator- (multi_difference_type const & d) const
+    {
+        StridedMultiIterator ret = *this;
+        ret -= d;
+        return ret;
+    }
+
+    reference operator[] (difference_type n) const
+    {
+        return m_ptr [n*m_stride];
+    }
+
+    reference operator[] (multi_difference_type const & d) const
+    {
+        return m_ptr [d[level]*m_stride];
+    }
+
+    reference operator* () const
+    {
+        return *m_ptr;
+    }
+
+    pointer get () const
+    {
+        return m_ptr;
+    }
+
+    pointer operator->() const
+    {
+        return &(operator*());
+    }
+
+    bool operator!= (const StridedMultiIterator &rhs) const
+    {
+        return m_ptr != rhs.m_ptr;
+    }
+
+    bool operator== (const StridedMultiIterator &rhs) const
+    {
+        return m_ptr == rhs.m_ptr;
+    }
+
+    bool operator< (const StridedMultiIterator &rhs) const
+    {
+        return m_ptr < rhs.m_ptr;
+    }
+
+    bool operator<= (const StridedMultiIterator &rhs) const
+    {
+        return m_ptr <= rhs.m_ptr;
+    }
+
+    bool operator> (const StridedMultiIterator &rhs) const
+    {
+        return m_ptr > rhs.m_ptr;
+    }
+
+    bool operator>= (const StridedMultiIterator &rhs) const
+    {
+        return m_ptr >= rhs.m_ptr;
+    }
+
+    iterator iteratorForDimension(unsigned int d) const
+    {
+        vigra_precondition(d == 0,
+            "StridedMultiIterator<1>::iteratorForDimension(d): d == 0 required");
+        const difference_type stride = 1;
+        return iterator(m_ptr, &stride, 0);
+    }
+
+    template <unsigned int K>
+    StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
+    dim()
+    {
+        return *this;
+    }
+
+    StridedMultiIterator<1, T, REFERENCE, POINTER> &
+    dim0() { return *this; }
+
+  protected:
+
+    difference_type 
+    total_stride(typename multi_difference_type::const_iterator d) const
+    {
+        return d[level] * m_stride;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                   StridedMultiIterator<2>            */
+/*                                                      */
+/********************************************************/
+
+//
+template <class T, class REFERENCE, class POINTER>
+class StridedMultiIterator<2, T, REFERENCE, POINTER>
+#ifndef DOXYGEN  // doxygen doesn't understand this inheritance
+: public StridedMultiIterator<1, T, REFERENCE, POINTER>
+#endif
+{
+  public:
+
+    typedef StridedMultiIterator<1, T, REFERENCE, POINTER> base_type;
+    enum { level = 1 };
+    typedef T value_type;
+    typedef REFERENCE reference;
+    typedef const value_type &const_reference;
+    typedef POINTER pointer;
+    typedef const value_type *const_pointer;
+    typedef typename MultiArrayShape<2>::type multi_difference_type;
+    typedef MultiIteratorStrideTraits<POINTER> stride_traits;
+    typedef typename stride_traits::stride_type difference_type;
+    typedef typename stride_traits::stride_array_type difference_array_type;
+    typedef typename stride_traits::shape_array_type shape_array_type;
+    typedef base_type next_type;
+    typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
+    typedef multi_dimensional_traverser_tag iterator_category;
+
+  protected:
+    difference_array_type m_stride;
+    shape_array_type m_shape;
+
+  public:
+    /* use default copy constructor and assignment operator */
+
+    StridedMultiIterator ()
+        : base_type (),
+          m_stride (0), m_shape (0)
+    {}
+
+    StridedMultiIterator (pointer ptr,
+          const difference_array_type & stride,
+          const shape_array_type & shape)
+        : base_type (ptr, stride, shape),
+          m_stride (stride), m_shape (shape)
+    {}
+
+    void operator++ ()
+    {
+        this->m_ptr += m_stride [level];
+    }
+
+    void operator-- ()
+    {
+        this->m_ptr -= m_stride [level];
+    }
+
+    StridedMultiIterator operator++ (int)
+    {
+        StridedMultiIterator ret = *this;
+        ++(*this);
+        return ret;
+    }
+
+    StridedMultiIterator operator-- (int)
+    {
+        StridedMultiIterator ret = *this;
+        --(*this);
+        return ret;
+    }
+
+    StridedMultiIterator & operator+= (difference_type n)
+    {
+        this->m_ptr += n * m_stride [level];
+        return *this;
+    }
+
+    StridedMultiIterator & operator+= (multi_difference_type const & d)
+    {
+        this->m_ptr += total_stride(d.begin());
+        return *this;
+    }
+
+    StridedMultiIterator  &operator-= (difference_type n)
+    {
+        this->m_ptr -= n * m_stride [level];
+        return *this;
+    }
+
+    StridedMultiIterator & operator-= (multi_difference_type const & d)
+    {
+        this->m_ptr -= total_stride(d.begin());
+        return *this;
+    }
+
+    StridedMultiIterator operator+ (difference_type n) const
+    {
+        StridedMultiIterator ret = *this;
+        ret += n;
+        return ret;
+    }
+
+    StridedMultiIterator operator+ (multi_difference_type const & d) const
+    {
+        StridedMultiIterator ret = *this;
+        ret += d;
+        return ret;
+    }
+
+    difference_type operator- (StridedMultiIterator const & d) const
+    {
+        return (this->m_ptr - d.m_ptr) / this->m_stride[level];
+    }
+
+    StridedMultiIterator operator- (difference_type n) const
+    {
+        StridedMultiIterator ret = *this;
+        ret -= n;
+        return ret;
+    }
+
+    StridedMultiIterator operator- (multi_difference_type const & d) const
+    {
+        StridedMultiIterator ret = *this;
+        ret -= d;
+        return ret;
+    }
+
+    reference operator[] (difference_type n) const
+    {
+        return this->m_ptr [n*m_stride [level]];
+    }
+
+    reference operator[] (multi_difference_type const & d) const
+    {
+        return this->m_ptr [total_stride(d.begin())];
+    }
+
+    next_type begin () const
+    {
+        return *this;
+    }
+
+    next_type end () const
+    {
+        next_type ret = *this;
+        ret += m_shape [level-1];
+        return ret;
+    }
+
+    iterator iteratorForDimension(unsigned int d) const
+    {
+        vigra_precondition(d <= level,
+            "StridedMultiIterator<N>::iteratorForDimension(d): d < N required");
+        return iterator(this->m_ptr, stride_traits::shift(m_stride, d), 0);
+    }
+
+    template <unsigned int K>
+    StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
+    dim()
+    {
+        return *this;
+    }
+
+    StridedMultiIterator<1, T, REFERENCE, POINTER> &
+    dim0() { return *this; }
+    StridedMultiIterator<2, T, REFERENCE, POINTER> &
+    dim1() { return *this; }
+
+  protected:
+
+    difference_type 
+    total_stride(typename multi_difference_type::const_iterator d) const
+    {
+        return d[level]*m_stride[level] + base_type::total_stride(d);
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                   StridedMultiIterator<N>            */
+/*                                                      */
+/********************************************************/
+
+/** \brief A multi-dimensional hierarchical iterator to be used with 
+           \ref vigra::MultiArrayView if it is not strided.
+
+    See \ref MultiIteratorPage for further documentation.
+
+    <b>\#include</b> \<vigra/multi_iterator.hxx\> <br>
+    Namespace: vigra
+*/
+template <unsigned int N, class T, class REFERENCE, class POINTER>
+class StridedMultiIterator 
+#ifndef DOXYGEN  // doxygen doesn't understand this inheritance
+: public StridedMultiIterator<N-1, T, REFERENCE, POINTER>
+#endif
+{
+public:
+
+        /** the type of the parent in the inheritance hierarchy.
+         */
+    typedef StridedMultiIterator<N-1, T, REFERENCE, POINTER> base_type;
+        
+        /** the iterator's level in the dimension hierarchy
+         */
+    enum { level = N-1 };
+
+        /** the iterator's value type
+         */
+    typedef T value_type;
+
+        /** reference type (result of operator[])
+         */
+    typedef REFERENCE reference;
+
+        /** const reference type (result of operator[] const)
+         */
+    typedef const value_type &const_reference;
+
+        /** pointer type
+         */
+    typedef POINTER pointer;
+
+        /** const pointer type
+         */
+    typedef const value_type *const_pointer;
+
+        /** multi difference type 
+            (used for offsetting along all axes simultaneously)
+         */
+    typedef typename MultiArrayShape<N>::type multi_difference_type;
+
+        /** difference type (used for offsetting)
+         */
+#ifndef DOXYGEN
+    typedef MultiIteratorStrideTraits<POINTER> stride_traits;
+    typedef typename stride_traits::stride_type difference_type;
+    typedef typename stride_traits::stride_array_type difference_array_type;
+#else
+    typedef MultiArrayIndex difference_type;
+#endif
+    
+        /** the StridedMultiIterator for the next lower dimension.
+         */
+    typedef base_type next_type;
+
+        /** the 1-dimensional iterator for this iterator hierarchy
+            (result of iteratorForDimension()).
+        */
+    typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
+
+        /** the iterator tag (image traverser)
+        */
+    typedef multi_dimensional_traverser_tag iterator_category;
+            
+    /* use default copy constructor and assignment operator */
+
+        /** default constructor.
+        */
+    StridedMultiIterator ()
+    {}
+
+        /** construct from pointer, strides (offset of a sample to the
+            next) for every dimension, and the shape.
+        */
+    StridedMultiIterator (pointer ptr,
+                   const difference_array_type & stride,
+                   const difference_array_type & shape)
+        : base_type (ptr, stride, shape)
+    {}
+
+
+        /** prefix-increment the iterator in its current dimension
+         */
+    void operator++ ()
+    {
+        this->m_ptr += this->m_stride [level];
+    }
+
+        /** prefix-decrement the iterator in its current dimension
+         */
+    void operator-- ()
+    {
+        this->m_ptr -= this->m_stride [level];
+    }
+
+        /** postfix-increment the iterator in its current dimension
+         */
+    StridedMultiIterator operator++ (int)
+    {
+        StridedMultiIterator ret = *this;
+        ++(*this);
+        return ret;
+    }
+
+        /** postfix-decrement the iterator in its current dimension
+         */
+    StridedMultiIterator operator-- (int)
+    {
+        StridedMultiIterator ret = *this;
+        --(*this);
+        return ret;
+    }
+
+        /** increment the iterator in its current dimension
+            by the given value.
+        */
+    StridedMultiIterator & operator+= (difference_type n)
+    {
+        this->m_ptr += n * this->m_stride [level];
+        return *this;
+    }
+
+        /** increment the iterator in all dimensions
+            by the given offset.
+        */
+    StridedMultiIterator & operator+= (multi_difference_type const & d)
+    {
+        this->m_ptr += total_stride(d.begin());
+        return *this;
+    }
+
+        /** decrement the iterator in its current dimension
+            by the given value.
+        */
+    StridedMultiIterator & operator-= (difference_type n)
+    {
+        this->m_ptr -= n * this->m_stride [level];
+        return *this;
+    }
+
+        /** decrement the iterator in all dimensions
+            by the given offset.
+        */
+    StridedMultiIterator & operator-= (multi_difference_type const & d)
+    {
+        this->m_ptr -= total_stride(d.begin());
+        return *this;
+    }
+
+        /** addition within current dimension
+         */
+    StridedMultiIterator operator+ (difference_type n) const
+    {
+        StridedMultiIterator ret = *this;
+        ret += n;
+        return ret;
+    }
+
+        /** addition along all dimensions
+         */
+    StridedMultiIterator operator+ (multi_difference_type const & d) const
+    {
+        StridedMultiIterator ret = *this;
+        ret += d;
+        return ret;
+    }
+
+        /** difference of two iterators in the current dimension.
+            The result of this operation is undefined if the iterator
+            doesn't point to element 0 in all dimensions below its current dimension.
+        */
+    difference_type operator- (StridedMultiIterator const & d) const
+    {
+        return (this->m_ptr - d.m_ptr) / this->m_stride[level];
+    }
+
+        /** subtraction within current dimension
+         */
+    StridedMultiIterator operator- (difference_type n) const
+    {
+        StridedMultiIterator ret = *this;
+        ret -= n;
+        return ret;
+    }
+
+        /** subtraction along all dimensions
+         */
+    StridedMultiIterator operator- (multi_difference_type const & d) const
+    {
+        StridedMultiIterator ret = *this;
+        ret -= d;
+        return ret;
+    }
+
+#ifdef DOXYGEN /* documentation only: operators *, ->, ==, !=, <, <=, >, >= are inherited */
+        /** derefenrence item
+         */
+    reference operator* () const;
+
+        /** get address of current item
+         */
+    pointer get () const;
+
+        /** call method of current item
+         */
+    pointer operator->() const;
+
+        /** inequality. True if iterators reference different items.
+         */
+    bool operator!= (const StridedMultiIterator &rhs) const;
+
+        /** equality. True if iterators reference the same items.
+         */
+    bool operator== (const StridedMultiIterator &rhs) const;
+
+        /** less than.
+         */
+    bool operator< (const StridedMultiIterator &rhs) const;
+
+        /** less or equal.
+         */
+    bool operator<= (const StridedMultiIterator &rhs) const;
+
+        /** greater than.
+         */
+    bool operator> (const StridedMultiIterator &rhs) const;
+    
+        /** greater or equal.
+         */
+    bool operator>= (const StridedMultiIterator &rhs) const;
+#endif
+
+        /** access the array element at the given offset in 
+        the current dimension.
+        */
+    reference operator[] (difference_type n) const
+    {
+        return this->m_ptr [n* this->m_stride [level]];
+    }
+
+        /** access the array element at the given offset.
+        */
+    reference operator[] (multi_difference_type const & d) const
+    {
+        return this->m_ptr [total_stride(d.begin())];
+    }
+
+        /** Return the (N-1)-dimensional multi-iterator that points to 
+            the first (N-1)-dimensional subarray of the 
+            N-dimensional array this iterator is referring to.
+            The result is only valid if this iterator refers to location
+            0 in <em>all</em> dimensions below its current dimension N,
+            otherwise it is undefined. Usage:
+
+            \code
+
+            StridedMultiIterator<2, int> outer = ...;  // this iterator
+
+            StridedMultiIterator<2, int>::next_type inner = outer.begin();
+            for(; inner != outer.end(); ++inner)
+            {
+                // manipulate current 1D subimage
+            }
+            \endcode
+        */
+    next_type begin () const
+    {
+        return *this;
+    }
+
+        /** Return the (N-1)-dimensional multi-iterator that points beyond 
+            the last (N-1)-dimensional subarray of the 
+            N-dimensional array this iterator is referring to.
+            The result is only valid if this iterator refers to location
+            0 in <em>all</em> dimensions below its current dimension N,
+            otherwise it is undefined.
+        */
+    next_type end () const
+    {
+        next_type ret = *this;
+        ret += this->m_shape [level-1];
+        return ret;
+    }
+
+        /** Get a 1-dimensional, STL-compatible iterator for the
+            given dimension, pointing to the current element of <TT>this</TT>.
+            Usage:
+
+            \code
+
+            StridedMultiIterator<3, int> outer = ...;  // this iterator
+
+            StridedMultiIterator<3, int>::iterator i = outer.iteratorForDimension(1);
+            StridedMultiIterator<3, int>::iterator end = i + height;
+            for(; i != end; ++i)
+            {
+                // go down the current column starting at the location of 'outer'
+            }
+            \endcode            
+        */
+    iterator iteratorForDimension(unsigned int d) const
+    {
+        vigra_precondition(d <= level,
+            "StridedMultiIterator<N>::iteratorForDimension(d): d < N required");
+        return iterator(this->m_ptr, stride_traits::shift(this->m_stride, d),0);
+    }
+        /** Return the multi-iterator that operates on dimension K in order
+            to manipulate this dimension directly. Usage:
+               
+            \code
+                
+            StridedMultiIterator<3, int> i3 = ...;
+                
+            i3.template dim<2>()++;  // increment outer dimension
+            i3.template dim<0>()++;  // increment inner dimension
+            \endcode
+            
+            For convenience, the same functionality is also available
+            as <tt>dim0()</tt>, <tt>dim1()</tt> etc. up to <tt>dim4()</tt>:
+            
+            \code
+                
+            StridedMultiIterator<3, int> i3 = ...;
+                
+            i3.dim2()++;  // increment outer dimension
+            i3.dim0()++;  // increment inner dimension
+            \endcode            
+        */
+    template <unsigned int K>
+    StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
+    dim()
+    {
+        return *this;
+    }
+
+    StridedMultiIterator<1, T, REFERENCE, POINTER> &
+    dim0() { return *this; }
+    StridedMultiIterator<2, T, REFERENCE, POINTER> &
+    dim1() { return *this; }
+    StridedMultiIterator<3, T, REFERENCE, POINTER> &
+    dim2() { return *this; }
+    StridedMultiIterator<4, T, REFERENCE, POINTER> &
+    dim3() { return *this; }
+    StridedMultiIterator<5, T, REFERENCE, POINTER> &
+    dim4() { return *this; }
+
+  protected:
+
+    difference_type 
+    total_stride(typename multi_difference_type::const_iterator d) const
+    {
+        return d[level]*this->m_stride[level] + base_type::total_stride(d);
+    }
+
+};
+
+//@}
+
+} // namespace vigra
+
+namespace std {
+
+template <unsigned int N, class T, class REFERENCE, class POINTER>
+ostream & operator<<(ostream & o, vigra::StridedScanOrderIterator<N, T, REFERENCE, POINTER> const & i)
+{
+    o << *i;
+    return o;
+}
+
+} // namespace std
+
+#endif // VIGRA_MULTI_ITERATOR_HXX
diff --git a/include/vigra/multi_iterator_coupled.hxx b/include/vigra/multi_iterator_coupled.hxx
new file mode 100644
index 0000000..0458aba
--- /dev/null
+++ b/include/vigra/multi_iterator_coupled.hxx
@@ -0,0 +1,1185 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2011-2012 by Stefan Schmidt and Ullrich Koethe         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef MULTI_ITERATOR_COUPLED_HXX
+#define MULTI_ITERATOR_COUPLED_HXX
+
+#include "metaprogramming.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup MultiIteratorGroup
+*/
+//@{
+
+  /**
+     Handle class, used by CoupledScanOrderIterator as the value type to simultaneously itearate over multiple images.
+  */
+template <class T, class NEXT>
+class CoupledHandle
+: public NEXT
+{
+public:
+    typedef NEXT                            base_type;
+    typedef CoupledHandle<T, NEXT>          self_type;
+    
+    static const int index =                NEXT::index + 1;    // index of this member of the chain
+    static const unsigned int dimensions =  NEXT::dimensions;
+
+    typedef T                               value_type;
+    typedef T *                             pointer;
+    typedef T const *                       const_pointer;
+    typedef T &                             reference;
+    typedef T const &                       const_reference;
+    typedef typename base_type::shape_type  shape_type;
+
+    CoupledHandle()
+    : base_type(),
+      pointer_(), 
+      strides_()
+    {}
+
+    CoupledHandle(const_pointer p, shape_type const & strides, NEXT const & next)
+    : base_type(next),
+      pointer_(const_cast<pointer>(p)), 
+      strides_(strides)
+    {}
+
+    template <class Stride>
+    CoupledHandle(MultiArrayView<dimensions, T, Stride> const & v, NEXT const & next)
+    : base_type(next),
+      pointer_(const_cast<pointer>(v.data())), 
+      strides_(v.stride())
+    {
+        vigra_precondition(v.shape() == this->shape(), "createCoupledIterator(): shape mismatch.");
+    }
+
+    template<int DIMENSION>
+    inline void increment() 
+    {
+        pointer_ += strides_[DIMENSION];
+        base_type::template increment<DIMENSION>();
+    }
+    
+    template<int DIMENSION>
+    inline void decrement() 
+    {
+        pointer_ -= strides_[DIMENSION];
+        base_type::template decrement<DIMENSION>();
+    }
+    
+    // TODO: test if making the above a default case of the this hurts performance
+    template<int DIMENSION>
+    inline void increment(MultiArrayIndex offset) 
+    {
+        pointer_ += offset*strides_[DIMENSION];
+        base_type::template increment<DIMENSION>(offset);
+    }
+    
+    template<int DIMENSION>
+    inline void decrement(MultiArrayIndex offset) 
+    {
+        pointer_ -= offset*strides_[DIMENSION];
+        base_type::template decrement<DIMENSION>(offset);
+    }
+    
+    void restrictToSubarray(shape_type const & start, shape_type const & end)
+    {
+        pointer_ += dot(start, strides_);
+        base_type::restrictToSubarray(start, end);
+    }
+
+    // ptr access
+    reference operator*()
+    {
+        return *pointer_;
+    }
+
+    const_reference operator*() const
+    {
+        return *pointer_;
+    }
+
+    pointer operator->()
+    {
+        return pointer_;
+    }
+
+    const_pointer operator->() const
+    {
+        return pointer_;
+    }
+
+    pointer ptr()
+    {
+        return pointer_;
+    }
+
+    const_pointer ptr() const
+    {
+        return pointer_;
+    }
+
+    shape_type const & strides() const
+    {
+        return strides_;
+    }
+
+    pointer pointer_;
+    shape_type strides_;
+};
+
+
+template <int N>
+class CoupledHandle<TinyVector<MultiArrayIndex, N>, void>
+{
+public:
+    static const int index = 0;                   // index of this member of the chain
+    static const unsigned int dimensions = N;
+
+    typedef typename MultiArrayShape<N>::type   value_type;
+    typedef value_type const *                  pointer;
+    typedef value_type const *                  const_pointer;
+    typedef value_type const &                  reference;
+    typedef value_type const &                  const_reference;
+    typedef value_type                          shape_type;
+    typedef CoupledHandle<value_type, void>     self_type;
+
+    CoupledHandle()
+    : point_(),
+      shape_(),
+      scanOrderIndex_()
+    {}
+
+    CoupledHandle(value_type const & shape)
+    : point_(),
+      shape_(shape),
+      scanOrderIndex_()
+    {}
+
+    CoupledHandle(typename MultiArrayShape<N+1>::type const & shape)
+    : point_(),
+      shape_(shape.begin()),
+      scanOrderIndex_()
+    {}
+
+    template<int DIMENSION>
+    inline void increment() 
+    {
+        ++point_[DIMENSION];
+    }
+    
+    template<int DIMENSION>
+    inline void decrement() 
+    {
+        --point_[DIMENSION];
+    }
+    
+    // TODO: test if making the above a default case of the this hurts performance
+    template<int DIMENSION>
+    inline void increment(MultiArrayIndex offset) 
+    {
+        point_[DIMENSION] += offset;
+    }
+    
+    template<int DIMENSION>
+    inline void decrement(MultiArrayIndex offset) 
+    {
+        point_[DIMENSION] -= offset;
+    }
+    
+    void restrictToSubarray(shape_type const & start, shape_type const & end)
+    {
+        point_ = shape_type();
+        shape_ = end - start;
+        scanOrderIndex_ = 0;
+    }
+
+    inline void incrementIndex() 
+    {
+        ++scanOrderIndex_;
+    }
+    
+    inline void decrementIndex() 
+    {
+        --scanOrderIndex_;
+    }
+    
+    inline void incrementIndex(MultiArrayIndex offset) 
+    {
+        scanOrderIndex_ += offset;
+    }
+    
+    inline void decrementIndex(MultiArrayIndex offset) 
+    {
+        scanOrderIndex_ -= offset;
+    }
+
+    // access
+    MultiArrayIndex scanOrderIndex() const
+    {
+        return scanOrderIndex_;
+    }
+    
+    // access
+    const_reference point() const
+    {
+        return point_;
+    }
+    
+    // access
+    const_reference shape() const
+    {
+        return shape_;
+    }
+
+    const_reference operator*() const
+    {
+        return point_;
+    }
+
+    const_pointer operator->() const
+    {
+        return &point_;
+    }
+
+    const_pointer ptr() const
+    {
+        return &point_;
+    }
+    
+    unsigned int borderType() const
+    {
+        return detail::BorderTypeImpl<N>::exec(point_, shape_);
+    }
+
+    value_type point_, shape_;
+    MultiArrayIndex scanOrderIndex_;
+};
+
+template <unsigned int N, class T, class StrideTag>
+class MultiArrayView<N, Multiband<T>, StrideTag>
+: public MultiArrayView<N, T, StrideTag>
+{
+  public:
+    MultiArrayView(MultiArrayView<N, T, StrideTag> const & v)
+    : MultiArrayView<N, T, StrideTag>(v)
+    {}
+};
+
+template <class T, class NEXT>
+class CoupledHandle<Multiband<T>, NEXT>
+: public NEXT
+{
+public:
+    typedef NEXT                                  base_type;
+    typedef CoupledHandle<Multiband<T>, NEXT>     self_type;
+    
+    static const int index =                      NEXT::index + 1;    // index of this member of the chain
+    static const unsigned int dimensions =        NEXT::dimensions;
+
+    typedef MultiArrayView<1, T, StridedArrayTag> value_type;
+    typedef value_type *                          pointer;
+    typedef value_type const *                    const_pointer;
+    typedef value_type &                          reference;
+    typedef value_type const &                    const_reference;
+    typedef typename base_type::shape_type        shape_type;
+
+    CoupledHandle()
+    : base_type(),
+      view_(), 
+      strides_()
+    {}
+
+    CoupledHandle(const_reference p, shape_type const & strides, NEXT const & next)
+    : base_type(next),
+      view_(p), 
+      strides_(strides)
+    {}
+
+    template <class Stride>
+    CoupledHandle(MultiArrayView<dimensions+1, Multiband<T>, Stride> const & v, NEXT const & next)
+    : base_type(next),
+      view_(v.bindInner(shape_type())), 
+      strides_(v.bindOuter(0).stride())
+    {
+        vigra_precondition(v.bindOuter(0).shape() == this->shape(), "createCoupledIterator(): shape mismatch.");
+    }
+
+    template<int DIMENSION>
+    inline void increment() 
+    {
+        view_.unsafePtr() += strides_[DIMENSION];
+        base_type::template increment<DIMENSION>();
+    }
+    
+    template<int DIMENSION>
+    inline void decrement() 
+    {
+        view_.unsafePtr() -= strides_[DIMENSION];
+        base_type::template decrement<DIMENSION>();
+    }
+    
+    // TODO: test if making the above a default case of the this hurts performance
+    template<int DIMENSION>
+    inline void increment(MultiArrayIndex offset) 
+    {
+        view_.unsafePtr() += offset*strides_[DIMENSION];
+        base_type::template increment<DIMENSION>(offset);
+    }
+    
+    template<int DIMENSION>
+    inline void decrement(MultiArrayIndex offset) 
+    {
+        view_.unsafePtr() -= offset*strides_[DIMENSION];
+        base_type::template decrement<DIMENSION>(offset);
+    }
+    
+    void restrictToSubarray(shape_type const & start, shape_type const & end)
+    {
+        view_.unsafePtr() += dot(start, strides_);
+        base_type::restrictToSubarray(start, end);
+    }
+
+    // ptr access
+    reference operator*()
+    {
+        return view_;
+    }
+
+    const_reference operator*() const
+    {
+        return view_;
+    }
+
+    pointer operator->()
+    {
+        return &view_;
+    }
+
+    const_pointer operator->() const
+    {
+        return &view_;
+    }
+
+    pointer ptr()
+    {
+        return &view_;
+    }
+
+    const_pointer ptr() const
+    {
+        return &view_;
+    }
+
+    shape_type const & strides() const
+    {
+        return strides_;
+    }
+
+    value_type view_;
+    shape_type strides_;
+};
+
+template <unsigned TARGET_INDEX>
+struct Error__CoupledHandle_index_out_of_range;
+
+namespace detail {
+
+template <unsigned TARGET_INDEX, class Handle, bool isValid, unsigned int INDEX=Handle::index>
+struct CoupledHandleCastImpl
+{
+    typedef typename CoupledHandleCastImpl<TARGET_INDEX, typename Handle::base_type, isValid>::type type;
+};
+
+template <unsigned TARGET_INDEX, class Handle, unsigned int INDEX>
+struct CoupledHandleCastImpl<TARGET_INDEX, Handle, false, INDEX>
+{
+    typedef Error__CoupledHandle_index_out_of_range<TARGET_INDEX> type;
+};
+
+template <unsigned TARGET_INDEX, class Handle>
+struct CoupledHandleCastImpl<TARGET_INDEX, Handle, true, TARGET_INDEX>
+{
+    typedef Handle type;
+};
+
+} // namespace detail
+
+template <unsigned TARGET_INDEX, class Handle, unsigned int INDEX=Handle::index>
+struct CoupledHandleCast
+: public detail::CoupledHandleCastImpl<TARGET_INDEX, Handle, (TARGET_INDEX <= INDEX), INDEX>
+{};
+
+template <unsigned int TARGET_INDEX, class Handle>
+typename CoupledHandleCast<TARGET_INDEX, Handle>::type &
+cast(Handle & handle)
+{
+    return handle;
+};
+
+template <unsigned int TARGET_INDEX, class Handle>
+typename CoupledHandleCast<TARGET_INDEX, Handle>::type const &
+cast(Handle const & handle)
+{
+    return handle;
+};
+
+  /** Returns reference to the element in the band of the handle with index TARGET_INDEX.
+   */
+template <unsigned int TARGET_INDEX, class Handle>
+typename CoupledHandleCast<TARGET_INDEX, Handle>::type::reference
+get(Handle & handle)
+{
+    return *cast<TARGET_INDEX>(handle);
+};
+
+  /** Returns a constant reference to the element in the band of the handle with index TARGET_INDEX.
+   */
+template <unsigned int TARGET_INDEX, class Handle>
+typename CoupledHandleCast<TARGET_INDEX, Handle>::type::const_reference
+get(Handle const & handle)
+{
+    return *cast<TARGET_INDEX>(handle);
+};
+
+/********************************************************/
+/*                                                      */
+/*               CoupledScanOrderIterator<N>            */
+/*                                                      */
+/********************************************************/
+
+/** \brief Iterate over multiple images simultaneously in scan order. 
+
+    The value type of this iterator is an instance of the handle class CoupledHandle. This allows to iterate over multiple arrays simultaneously. The coordinates can be accessed as a special band (index 0) in the handle. The scan-order is defined such that dimensions are iterated from front to back (first to last).
+    
+    Instances of this class are usually constructed by calling createCoupledIterator() .
+
+    To get the type of a CoupledScanOrderIterator for arrays of a certain dimension and element types use CoupledIteratorType::type.
+
+    The iterator supports all functions listed in the STL documentation for
+        <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterators</a>.
+
+    Example of use:
+    \code
+    using namespace vigra;
+    MultiArray<2, double> image1(Shape2(5, 5));
+    MultiArray<2, double> image2(Shape2(5, 5));
+    // fill image with data ...
+    
+    typedef CoupledIteratorType<2, double, double>::type Iterator; // the type of the CoupledScanOrderIterator
+    
+    Iterator start = createCoupledIterator(image1, image2); // create coupled iterator for simultaneous iteration over image1, image2 and their coordinates
+    Iterator end = start.getEndIterator();
+    
+    for (Iterator it = start; it < end; ++it) {
+      std::cout << "coordinates: " << it.get<0>() << std::endl;
+      std::cout << "image1: " << it.get<1>() << std::endl;
+      std::cout << "image2: " << it.get<2>() << std::endl;
+    }
+    
+    //random access:
+    Iterator::value_type handle = start[15];
+    std::cout << "image1: " << get<1>(handle) << std::endl;
+    \endcode
+    
+    <b>\#include</b> \<vigra/multi_iterator_coupled.hxx\> <br/>
+    Namespace: vigra
+*/
+
+template <unsigned int N,
+          class HANDLES=CoupledHandle<TinyVector<MultiArrayIndex, N>, void>,
+          int DIMENSION = N-1>
+class CoupledScanOrderIterator
+#ifndef DOXYGEN  // doxygen doesn't understand this inheritance
+: protected CoupledScanOrderIterator<N, HANDLES, DIMENSION-1>
+#endif
+{
+    typedef CoupledScanOrderIterator<N, HANDLES, DIMENSION-1> base_type;
+    static const int dimension = DIMENSION;
+
+  public:
+
+    typedef typename MultiArrayShape<dimension+1>::type        shape_type;
+    typedef MultiArrayIndex                   difference_type;
+    typedef CoupledScanOrderIterator          iterator;
+    typedef std::random_access_iterator_tag   iterator_category;
+
+    typedef typename base_type::value_type      value_type;
+
+#ifdef DOXYGEN
+  /** The type of the CoupledHandle.
+   */
+    typedef HANDLES value_type;
+#endif
+
+    typedef typename base_type::reference       reference;
+    typedef typename base_type::const_reference const_reference; // FIXME: do we need both?
+    typedef typename base_type::pointer         pointer;
+
+    explicit CoupledScanOrderIterator(value_type const & handles = value_type())
+    : base_type(handles)
+    {}
+
+    value_type operator[](MultiArrayIndex i) const
+    {
+        return *(CoupledScanOrderIterator(*this) += i);
+    }
+
+    CoupledScanOrderIterator & operator++()
+    {
+        base_type::operator++();
+        if(this->point()[dimension-1] == this->shape()[dimension-1])
+        {
+            base_type::reset();
+            this->handles_.template increment<dimension>();
+        }
+        return *this;
+    }
+
+    CoupledScanOrderIterator operator++(int)
+    {
+        CoupledScanOrderIterator res(*this);
+        ++*this;
+        return res;
+    }
+
+    CoupledScanOrderIterator & operator+=(MultiArrayIndex i)
+    {
+        // FIXME: this looks very expensive
+        shape_type coordOffset;
+        detail::ScanOrderToCoordinate<N>::exec(i+scanOrderIndex(), this->shape(), coordOffset);
+        coordOffset -= point();
+        moveRelative(coordOffset);
+        this->handles_.scanOrderIndex_ += i;
+        return *this;
+    }
+
+    CoupledScanOrderIterator & operator+=(const shape_type &coordOffset)
+    {
+        moveRelative(coordOffset);
+        this->handles_.scanOrderIndex_ += detail::CoordinateToScanOrder<N>::exec(this->shape(), coordOffset);
+        return *this;
+    }
+
+    CoupledScanOrderIterator & operator--()
+    {
+        base_type::operator--();
+        if(this->point()[dimension-1] == -1)
+        {
+            base_type::inverseReset();
+            this->handles_.template decrement<dimension>();
+        }
+        return *this;
+    }
+
+    CoupledScanOrderIterator operator--(int)
+    {
+        CoupledScanOrderIterator res(*this);
+        --*this;
+        return res;
+    }
+
+    CoupledScanOrderIterator & operator-=(MultiArrayIndex i)
+    {
+        return operator+=(-i);
+    }
+
+    CoupledScanOrderIterator & operator-=(const shape_type &coordOffset)
+    {
+        return operator+=(-coordOffset);
+    }
+
+    /** Returns CoupledScanOrderIterator pointing beyond the last element.
+    */
+    CoupledScanOrderIterator getEndIterator() const
+    {
+        return operator+(prod(this->shape()) - this->scanOrderIndex());
+    }
+    
+    CoupledScanOrderIterator operator+(MultiArrayIndex d) const
+    {
+        return CoupledScanOrderIterator(*this) += d;
+    }
+
+    CoupledScanOrderIterator operator-(MultiArrayIndex d) const
+    {
+        return CoupledScanOrderIterator(*this) -= d;
+    }
+
+    CoupledScanOrderIterator operator+(const shape_type &coordOffset) const
+    {
+        return CoupledScanOrderIterator(*this) += coordOffset;
+    }
+
+    CoupledScanOrderIterator operator-(const shape_type &coordOffset) const
+    {
+        return CoupledScanOrderIterator(*this) -= coordOffset;
+    }
+
+    MultiArrayIndex operator-(CoupledScanOrderIterator const & r) const
+    {
+        return base_type::operator-(r);
+    }
+
+    bool operator==(CoupledScanOrderIterator const & r) const
+    {
+        return base_type::operator==(r);
+    }
+
+    bool operator!=(CoupledScanOrderIterator const & r) const
+    {
+        return base_type::operator!=(r);
+    }
+
+    bool operator<(CoupledScanOrderIterator const & r) const
+    {
+        return base_type::operator<(r);
+    }
+
+    bool operator<=(CoupledScanOrderIterator const & r) const
+    {
+        return base_type::operator<=(r);
+    }
+
+    bool operator>(CoupledScanOrderIterator const & r) const
+    {
+        return base_type::operator>(r);
+    }
+
+    bool operator>=(CoupledScanOrderIterator const & r) const
+    {
+        return base_type::operator>=(r);
+    }
+
+    CoupledScanOrderIterator & restrictToSubarray(shape_type const & start, shape_type const & end)
+    {
+        this->operator+=(-point());
+        this->handles_.restrictToSubarray(start, end);
+        return *this;
+    }
+
+    using base_type::operator*;
+    using base_type::point;
+    using base_type::shape;
+    using base_type::scanOrderIndex;
+    using base_type::atBorder;
+    using base_type::borderType;
+    using base_type::get;
+    using base_type::isValid;
+    using base_type::atEnd;
+
+#ifdef DOXYGEN
+  
+    /** Returns reference to the element in the band with index TARGET_INDEX.
+    */
+    template<unsigned int TARGET_INDEX> 
+    typename CoupledHandleCast<TARGET_INDEX, value_type>::type::reference
+    get();
+
+    /** Returns constant reference to the element in the band with index TARGET_INDEX.
+    */
+    template<unsigned int TARGET_INDEX> 
+    typename CoupledHandleCast<TARGET_INDEX, value_type>::type::const_reference
+    get() const;
+    
+#endif
+
+  protected:
+    void reset()
+    {
+        this->handles_.template decrement<dimension>(this->shape()[dimension]);
+    }
+
+    void inverseReset()
+    {
+        this->handles_.template increment<dimension>(this->shape()[dimension]);
+    }
+
+    void moveRelative(typename value_type::shape_type const & coordOffset)
+    {
+        base_type::moveRelative(coordOffset);
+        this->handles_.template increment<dimension>(coordOffset[dimension]);
+    }
+};
+
+
+
+template <unsigned int N, class HANDLES>
+class CoupledScanOrderIterator<N, HANDLES, 0>
+{
+    static const int dimension = 0;
+
+  public:
+
+    typedef CoupledScanOrderIterator<N, HANDLES, 0>  self_type;
+    typedef HANDLES                                  value_type;
+    typedef MultiArrayIndex                          difference_type;
+    typedef value_type &                             reference;
+    typedef value_type const &                       const_reference; 
+    typedef value_type *                             pointer;
+    typedef typename MultiArrayShape<1>::type        shape_type;
+    typedef CoupledScanOrderIterator                 iterator;
+    typedef std::random_access_iterator_tag          iterator_category;
+
+    explicit CoupledScanOrderIterator(value_type const & handles = value_type())
+    : handles_(handles)
+    {}
+
+    CoupledScanOrderIterator & operator++()
+    {
+        handles_.template increment<dimension>();
+        handles_.incrementIndex();
+        return *this;
+    }
+
+    CoupledScanOrderIterator operator++(int)
+    {
+        CoupledScanOrderIterator res(*this);
+        ++*this;
+        return res;
+    }
+
+    CoupledScanOrderIterator & operator+=(MultiArrayIndex i)
+    {
+        shape_type coordOffset;
+        detail::ScanOrderToCoordinate<N>::exec(i, shape(), coordOffset);
+        moveRelative(coordOffset);
+        handles_.scanOrderIndex_ += i;
+        return *this;
+    }
+
+    CoupledScanOrderIterator & operator+=(const shape_type &coordOffset)
+    {
+        moveRelative(coordOffset);
+        handles_.scanOrderIndex_ += detail::CoordinateToScanOrder<N>::exec(shape(), coordOffset);
+        return *this;
+    }
+
+    CoupledScanOrderIterator & operator-=(const shape_type &coordOffset)
+    {
+        return operator+=(-coordOffset);
+    }
+
+    CoupledScanOrderIterator & operator--()
+    {
+        handles_.template decrement<dimension>();
+        handles_.decrementIndex();
+        return *this;
+    }
+
+    CoupledScanOrderIterator operator--(int)
+    {
+        CoupledScanOrderIterator res(*this);
+        --this;
+        return res;
+    }
+
+    CoupledScanOrderIterator & operator-=(MultiArrayIndex i)
+    {
+        return operator+=(-i);
+    }
+
+    value_type operator[](MultiArrayIndex i) const
+    {
+        return *(CoupledScanOrderIterator(*this) += i);
+    }
+
+    CoupledScanOrderIterator
+    operator+(MultiArrayIndex d) const
+    {
+        return CoupledScanOrderIterator(*this) += d;
+    }
+
+    CoupledScanOrderIterator
+    operator-(MultiArrayIndex d) const
+    {
+        return CoupledScanOrderIterator(*this) -= d;
+    }
+
+    CoupledScanOrderIterator operator+(const shape_type &coordOffset) const
+    {
+        return CoupledScanOrderIterator(*this) += coordOffset;
+    }
+    
+    CoupledScanOrderIterator operator-(const shape_type &coordOffset) const
+    {
+        return CoupledScanOrderIterator(*this) -= coordOffset;
+    }
+
+    MultiArrayIndex
+    operator-(CoupledScanOrderIterator const & r) const
+    {
+        return scanOrderIndex() - r.scanOrderIndex();
+    }
+
+    bool operator==(CoupledScanOrderIterator const & r) const
+    {
+        return scanOrderIndex() == r.scanOrderIndex();
+    }
+
+    bool operator!=(CoupledScanOrderIterator const & r) const
+    {
+        return scanOrderIndex() != r.scanOrderIndex();
+    }
+
+    bool operator<(CoupledScanOrderIterator const & r) const
+    {
+        return scanOrderIndex() < r.scanOrderIndex();
+    }
+
+    bool operator<=(CoupledScanOrderIterator const & r) const
+    {
+        return scanOrderIndex() <= r.scanOrderIndex();
+    }
+
+    bool operator>(CoupledScanOrderIterator const & r) const
+    {
+        return scanOrderIndex() > r.scanOrderIndex();
+    }
+
+    bool operator>=(CoupledScanOrderIterator const & r) const
+    {
+        return scanOrderIndex() >= r.scanOrderIndex();
+    }
+
+    bool isValid() const
+    {
+        return handles_.scanOrderIndex() < prod(shape());
+    }
+
+    bool atEnd() const
+    {
+        return handles_.scanOrderIndex() >= prod(shape());
+    }
+
+    MultiArrayIndex scanOrderIndex() const
+    {
+        return handles_.scanOrderIndex();
+    }
+
+    typename value_type::shape_type const & point() const
+    {
+        return handles_.point();
+    }
+
+    typename value_type::shape_type const & shape() const
+    {
+        return handles_.shape();
+    }
+
+    reference operator*()
+    {
+        return handles_;
+    }
+
+    const_reference operator*() const
+    {
+        return handles_;
+    }
+
+    CoupledScanOrderIterator & restrictToSubarray(shape_type const & start, shape_type const & end)
+    {
+        operator+=(-point());
+        handles_.restrictToSubarray(start, end);
+        return *this;
+    }
+
+    CoupledScanOrderIterator getEndIterator() const
+    {
+        return operator+(prod(shape())-scanOrderIndex());
+    }
+
+    bool atBorder() const
+    {
+        return (handles_.borderType() != 0);
+    }
+
+    unsigned int borderType() const
+    {
+        return handles_.borderType();
+    }
+
+    template<unsigned int TARGET_INDEX> 
+    typename CoupledHandleCast<TARGET_INDEX, value_type>::type::reference
+    get() 
+    {
+        return vigra::get<TARGET_INDEX>(handles_);
+    }
+
+    template<unsigned int TARGET_INDEX> 
+    typename CoupledHandleCast<TARGET_INDEX, value_type>::type::const_reference
+    get() const
+    {
+        return vigra::get<TARGET_INDEX>(handles_);
+    }
+
+  protected:
+    void reset()
+    {
+        handles_.template decrement<dimension>(shape()[dimension]);
+    }
+
+    void inverseReset()
+    {
+        handles_.template increment<dimension>(shape()[dimension]);
+    }
+
+    void moveRelative(typename value_type::shape_type const & coordOffset)
+    {
+        handles_.template increment<dimension>(coordOffset[dimension]);
+    }   
+    
+    value_type handles_;
+};
+
+
+template <unsigned int N, class List>
+struct ComposeCoupledHandle;
+
+template <unsigned int N, class T, class TAIL>
+struct ComposeCoupledHandle<N, TypeList<T, TAIL> >
+{
+    typedef typename ComposeCoupledHandle<N, TAIL>::type  BaseType;
+    typedef typename MultiArrayShape<N>::type             shape_type;
+    typedef CoupledHandle<T, BaseType>                    type;
+    
+    template <class S>
+    type exec(MultiArrayView<N, T, S> const & m, 
+              shape_type const & start, shape_type const & end,
+              BaseType const & base)
+    {
+        return type(m.subarray(start, end).data(), m.stride(), base);
+    }
+    
+    template <class S>
+    type exec(MultiArrayView<N, T, S> const & m, BaseType const & base)
+    {
+        return type(m.data(), m.stride(), base);
+    }
+};
+
+template <unsigned int N>
+struct ComposeCoupledHandle<N, void>
+{
+    typedef typename MultiArrayShape<N>::type  shape_type;
+    typedef CoupledHandle<shape_type, void>    type;
+    
+    type exec(shape_type const & shape)
+    {
+        return type(shape);
+    }
+    
+    type exec(shape_type const & start, shape_type const & end)
+    {
+        return type(end-start);
+    }
+};
+
+template <unsigned int N, class T1=void, class T2=void, class T3=void, class T4=void, class T5=void>
+struct CoupledHandleType
+{
+    // reverse the order to get the desired index order
+    typedef typename MakeTypeList<T5, T4, T3, T2, T1>::type TypeList;
+    typedef typename ComposeCoupledHandle<N, TypeList>::type type;
+};
+
+template <unsigned int N, class T1, class T2, class T3, class T4, class T5>
+struct CoupledHandleType<N, Multiband<T1>, T2, T3, T4, T5>
+{
+    // reverse the order to get the desired index order
+    typedef typename MakeTypeList<T5, T4, T3, T2, Multiband<T1> >::type TypeList;
+    typedef typename ComposeCoupledHandle<N-1, TypeList>::type type;
+};
+
+/** Helper class to easliy get the type of a CoupledScanOrderIterator (and corresponding CoupledHandle) for up to five arrays of dimension N with element types T1,...,T5.
+ */
+template <unsigned int N, class T1=void, class T2=void, class T3=void, class T4=void, class T5=void>
+struct CoupledIteratorType
+{
+    /** Type of the CoupledHandle.*/
+    typedef typename CoupledHandleType<N, T1, T2, T3, T4, T5>::type HandleType;
+  
+    /** Type of the CoupledScanOrderIterator.*/
+    typedef CoupledScanOrderIterator<HandleType::dimensions, HandleType> IteratorType;
+    typedef IteratorType                                                 type;
+};
+
+/** Alias for \ref vigra::CoupledIteratorType (maybe easier to remember).
+ */
+template <unsigned int N, class T1=void, class T2=void, class T3=void, class T4=void, class T5=void>
+struct CoupledArrays
+: public CoupledIteratorType<N, T1, T2, T3, T4, T5>
+{};
+
+/** Returns a CoupledScanOrderIterator from shape to iterate over coordinates. 
+ */
+template <int N>
+typename CoupledIteratorType<N>::type
+createCoupledIterator(TinyVector<MultiArrayIndex, N> const & shape)
+{
+    typedef typename CoupledHandleType<N>::type   P0;
+    typedef CoupledScanOrderIterator<N, P0> IteratorType;
+    
+    return IteratorType(P0(shape));
+}
+
+/** Returns a CoupledScanOrderIterator to simultaneously iterate over image m1 and its coordinates. 
+ */
+template <unsigned int N1, class T1, class S1>
+typename CoupledIteratorType<N1, T1>::type
+createCoupledIterator(MultiArrayView<N1, T1, S1> const & m1)
+{
+    typedef typename CoupledHandleType<N1, T1>::type             P1;
+    typedef typename P1::base_type                               P0;
+    typedef CoupledScanOrderIterator<P1::dimensions, P1>         IteratorType;
+    
+    return IteratorType(P1(m1, 
+                        P0(m1.shape())));
+}
+
+/** Returns a CoupledScanOrderIterator to simultaneously iterate over images m1, m2 and their coordinates. 
+ */
+template <unsigned int N1, class T1, class S1,
+          unsigned int N2, class T2, class S2>
+typename CoupledIteratorType<N1, T1, T2>::type
+createCoupledIterator(MultiArrayView<N1, T1, S1> const & m1,
+                      MultiArrayView<N2, T2, S2> const & m2)
+{
+    typedef typename CoupledHandleType<N1, T1, T2>::type         P2;
+    typedef typename P2::base_type                               P1;
+    typedef typename P1::base_type                               P0;
+    typedef CoupledScanOrderIterator<P2::dimensions, P2> IteratorType;
+    
+    return IteratorType(P2(m2, 
+                        P1(m1, 
+                        P0(m1.shape()))));
+}
+
+/** Returns a CoupledScanOrderIterator to simultaneously iterate over images m1, m2, m3 and their coordinates. 
+ */
+template <unsigned int N1, class T1, class S1,
+          unsigned int N2, class T2, class S2,
+          unsigned int N3, class T3, class S3>
+typename CoupledIteratorType<N1, T1, T2, T3>::type
+createCoupledIterator(MultiArrayView<N1, T1, S1> const & m1,
+                      MultiArrayView<N2, T2, S2> const & m2,
+                      MultiArrayView<N3, T3, S3> const & m3)
+{
+    typedef typename CoupledHandleType<N1, T1, T2, T3>::type     P3;
+    typedef typename P3::base_type                               P2;
+    typedef typename P2::base_type                               P1;
+    typedef typename P1::base_type                               P0;
+    typedef CoupledScanOrderIterator<P3::dimensions, P3> IteratorType;
+    
+    return IteratorType(P3(m3, 
+                        P2(m2, 
+                        P1(m1, 
+                        P0(m1.shape())))));
+}
+
+/** Returns a CoupledScanOrderIterator to simultaneously iterate over images m1, m2, m3, m4 and their coordinates. 
+ */
+template <unsigned int N1, class T1, class S1,
+          unsigned int N2, class T2, class S2,
+          unsigned int N3, class T3, class S3,
+          unsigned int N4, class T4, class S4>
+typename CoupledIteratorType<N1, T1, T2, T3, T4>::type
+createCoupledIterator(MultiArrayView<N1, T1, S1> const & m1,
+                      MultiArrayView<N2, T2, S2> const & m2,
+                      MultiArrayView<N3, T3, S3> const & m3,
+                      MultiArrayView<N4, T4, S4> const & m4)
+{
+    typedef typename CoupledHandleType<N1, T1, T2, T3, T4>::type P4;
+    typedef typename P4::base_type                               P3;
+    typedef typename P3::base_type                               P2;
+    typedef typename P2::base_type                               P1;
+    typedef typename P1::base_type                               P0;
+    typedef CoupledScanOrderIterator<P4::dimensions, P4> IteratorType;
+    
+    return IteratorType(P4(m4, 
+                        P3(m3, 
+                        P2(m2, 
+                        P1(m1, 
+                        P0(m1.shape()))))));
+}
+
+/** Returns a CoupledScanOrderIterator to simultaneously iterate over images m1, m2, m3, m4, m5 and their coordinates. 
+ */
+template <unsigned int N1, class T1, class S1,
+          unsigned int N2, class T2, class S2,
+          unsigned int N3, class T3, class S3,
+          unsigned int N4, class T4, class S4,
+          unsigned int N5, class T5, class S5>
+typename CoupledIteratorType<N1, T1, T2, T3, T4, T5>::type
+createCoupledIterator(MultiArrayView<N1, T1, S1> const & m1,
+                      MultiArrayView<N2, T2, S2> const & m2,
+                      MultiArrayView<N3, T3, S3> const & m3,
+                      MultiArrayView<N4, T4, S4> const & m4,
+                      MultiArrayView<N5, T5, S5> const & m5)
+{
+    typedef typename CoupledHandleType<N1, T1, T2, T3, T4, T5>::type P5;
+    typedef typename P5::base_type                                   P4;
+    typedef typename P4::base_type                                   P3;
+    typedef typename P3::base_type                                   P2;
+    typedef typename P2::base_type                                   P1;
+    typedef typename P1::base_type                                   P0;
+    typedef CoupledScanOrderIterator<P1::dimensions, P5> IteratorType;
+    
+    return IteratorType(P5(m5, 
+                        P4(m4, 
+                        P3(m3, 
+                        P2(m2, 
+                        P1(m1, 
+                        P0(m1.shape())))))));
+}
+
+//@}
+
+} // namespace vigra
+
+namespace std {
+
+template <unsigned int N, class HANDLES, int DIMENSION>
+ostream & operator<<(ostream & o, vigra::CoupledScanOrderIterator<N, HANDLES, DIMENSION> const & i)
+{
+    o << i.point();
+    return o;
+}
+
+} // namespace std
+
+#endif /* MULTI_ITERATOR_COUPLED_HXX */
diff --git a/include/vigra/multi_labeling.hxx b/include/vigra/multi_labeling.hxx
new file mode 100644
index 0000000..a74ca5e
--- /dev/null
+++ b/include/vigra/multi_labeling.hxx
@@ -0,0 +1,344 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2012-2013 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_LABELING_HXX
+#define VIGRA_MULTI_LABELING_HXX
+
+#include "multi_array.hxx"
+#include "multi_gridgraph.hxx"
+#include "union_find.hxx"
+
+namespace vigra{
+
+/** \addtogroup Labeling
+*/
+//@{
+
+namespace lemon_graph { 
+
+template <class Graph, class T1Map, class T2Map, class Equal>
+typename T2Map::value_type
+labelGraph(Graph const & g, 
+           T1Map const & data,
+           T2Map & labels,
+           Equal const & equal)
+{
+    typedef typename Graph::NodeIt        graph_scanner;
+    typedef typename Graph::OutBackArcIt  neighbor_iterator;
+    typedef typename T2Map::value_type    LabelType;
+
+    vigra::detail::UnionFindArray<LabelType>  regions;
+
+    // pass 1: find connected components
+    for (graph_scanner node(g); node != INVALID; ++node) 
+    {
+        typename T1Map::value_type center = data[*node];
+        
+        // define tentative label for current node
+        LabelType currentLabel = regions.nextFreeLabel();
+        
+        for (neighbor_iterator arc(g, node); arc != INVALID; ++arc)
+        {
+            // merge regions if colors are equal
+            if(equal(center, data[g.target(*arc)]))
+            {
+                LabelType neighborLabel = regions[labels[g.target(*arc)]];
+                currentLabel = regions.makeUnion(neighborLabel, currentLabel);
+            }
+        }
+        // set label of current node
+        labels[*node] = regions.finalizeLabel(currentLabel);
+    }
+    
+    LabelType count = regions.makeContiguous();
+
+    // pass 2: make component labels contiguous
+    for (graph_scanner node(g); node != INVALID; ++node) 
+    {
+        labels[*node] = regions[labels[*node]];
+    }
+    return count;
+}
+
+template <class Graph, class T1Map, class T2Map, class Equal>
+typename T2Map::value_type
+labelGraphWithBackground(Graph const & g, 
+                         T1Map const & data,
+                         T2Map & labels,
+                         typename T1Map::value_type backgroundValue,
+                         Equal const & equal)
+{
+    typedef typename Graph::NodeIt        graph_scanner;
+    typedef typename Graph::OutBackArcIt  neighbor_iterator;
+    typedef typename T2Map::value_type    LabelType;
+
+    vigra::detail::UnionFindArray<LabelType>  regions;
+
+    // pass 1: find connected components
+    for (graph_scanner node(g); node != INVALID; ++node) 
+    {
+        typename T1Map::value_type center = data[*node];
+        
+        // background always gets label zero
+        if(equal(center, backgroundValue))
+        {
+            labels[*node] = 0;
+            continue;
+        }
+        
+        // define tentative label for current node
+        LabelType currentLabel = regions.nextFreeLabel();
+        
+        for (neighbor_iterator arc(g, node); arc != INVALID; ++arc)
+        {
+            // merge regions if colors are equal
+            if(equal(center, data[g.target(*arc)]))
+            {
+                LabelType neighborLabel = regions[labels[g.target(*arc)]];
+                currentLabel = regions.makeUnion(neighborLabel, currentLabel);
+            }
+        }
+        // set label of current node
+        labels[*node] = regions.finalizeLabel(currentLabel);
+    }
+    
+    LabelType count = regions.makeContiguous();
+
+    // pass 2: make component labels contiguous
+    for (graph_scanner node(g); node != INVALID; ++node) 
+    {
+        labels[*node] = regions[labels[*node]];
+    }
+    return count;
+}
+
+} // namespace lemon_graph
+
+/********************************************************/
+/*                                                      */
+/*                     labelMultiArray                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find the connected components of a MultiArray with arbitrary many dimensions.
+
+    <b> Declaration:</b>
+
+    \code
+    namespace vigra {
+
+        template <unsigned int N, class T, class S1,
+                                  class Label, class S2,
+                  class EqualityFunctor = std::equal_to<T> >
+        Label 
+        labelMultiArray(MultiArrayView<N, T, S1> const & data,
+                        MultiArrayView<N, Label, S2> labels,
+                        NeighborhoodType neighborhood = DirectNeighborhood,
+                        EqualityFunctor equal = std::equal_to<T>())
+
+    }
+    \endcode
+
+    Connected components are defined as regions with uniform values. 
+    Thus, the value type <tt>T</tt> of the input array \a data either 
+    must be equality comparable, or an EqualityFunctor must be
+    provided that realizes the desired predicate. The destination 
+    array's value type <tt>Label</tt> should be large enough to hold 
+    the labels without overflow. Region numbers will form a consecutive 
+    sequence starting at <b>one</b> and ending with the region number 
+    returned by the function (inclusive).
+    
+    Argument \a neighborhood specifies the type of connectivity used. It can
+    take the values <tt>DirectNeighborhood</tt> (which corresponds to
+    4-neighborhood in 2D and 6-neighborhood in 3D, default) or
+    <tt>IndirectNeighborhood</tt> (which corresponds to
+    8-neighborhood in 2D and 26-neighborhood in 3D).
+
+    Return:  the number of regions found (= highest region label, because labeling starts at 1)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_labeling.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<3,int> src(Shape3(w,h,d));
+    MultiArray<3,int> dest(Shape3(w,h,d));
+    
+    // find 6-connected regions
+    int max_region_label = labelMultiArray(src, dest);
+
+    // find 26-connected regions
+    max_region_label = labelMultiArray(src, dest, IndirectNeighborhood);
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+    T t;
+    t == t                      // T is equality comparable
+
+    EqualityFunctor equal;      // or a suitable functor is supplied
+    equal(t, t)
+    \endcode
+*/
+doxygen_overloaded_function(template <...> unsigned int labelMultiArray)
+
+template <unsigned int N, class T, class S1,
+                          class Label, class S2,
+          class Equal>
+inline Label 
+labelMultiArray(MultiArrayView<N, T, S1> const & data,
+                MultiArrayView<N, Label, S2> labels,
+                NeighborhoodType neighborhood,
+                Equal equal)
+{
+    vigra_precondition(data.shape() == labels.shape(),
+        "labelMultiArray(): shape mismatch between input and output.");
+        
+    GridGraph<N, undirected_tag> graph(data.shape(), neighborhood);
+    return lemon_graph::labelGraph(graph, data, labels, equal);
+}
+
+template <unsigned int N, class T, class S1,
+                          class Label, class S2>
+inline Label 
+labelMultiArray(MultiArrayView<N, T, S1> const & data,
+                MultiArrayView<N, Label, S2> labels,
+                NeighborhoodType neighborhood = DirectNeighborhood)
+{
+    return labelMultiArray(data, labels, neighborhood, std::equal_to<T>());
+}
+
+/********************************************************/
+/*                                                      */
+/*           labelMultiArrayWithBackground              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find the connected components of a MultiArray with arbitrary many dimensions,
+     excluding the background from labeling.
+
+    <b> Declaration:</b>
+
+    \code
+    namespace vigra {
+
+        template <unsigned int N, class T, class S1,
+                                  class Label, class S2
+                  class Equal = std::equal<T> >
+        Label 
+        labelMultiArrayWithBackground(MultiArrayView<N, T, S1> const & data,
+                                      MultiArrayView<N, Label, S2> labels,
+                                      NeighborhoodType neighborhood = DirectNeighborhood,
+                                      T backgroundValue = T(),
+                                      Equal equal = std::equal<T>());
+
+    }
+    \endcode
+
+    This function is the same as \ref labelMultiArray(), except for 
+    the additional parameter \a backgroundValue. Points in the input
+    array \a data with this value (which default to zero) are ignored 
+    during labeling, and  their output label is automatically set to 
+    zero. Region numbers will be a consecutive sequence starting at 
+    zero (when background was present) or at one (when no background 
+    was present) and ending with the region number returned by the 
+    function (inclusive).
+
+    Return: the number of non-background regions found (= highest region label, 
+    because background has label 0)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_labeling.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<3, int> src(Shape3(w,h,d));
+    MultiArray<3, int> dest(Shape3(w,h,d));
+    
+    // find 6-connected regions, ignoring background value zero (the default)
+    int max_region_label = labelMultiArrayWithBackground(src, dest);
+
+    // find 26-connected regions, using -1 as the background value
+    max_region_label = labelMultiArrayWithBackground(src, dest, IndirectNeighborhood, -1);
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+    T t, backgroundValue;
+    t == backgroundValue        // T is equality comparable
+
+    EqualityFunctor equal;      // or a suitable functor is supplied
+    equal(t, backgroundValue)
+    \endcode
+*/
+doxygen_overloaded_function(template <...> unsigned int labelMultiArrayWithBackground)
+
+template <unsigned int N, class T, class S1,
+                          class Label, class S2,
+          class Equal>
+inline Label 
+labelMultiArrayWithBackground(MultiArrayView<N, T, S1> const & data,
+                              MultiArrayView<N, Label, S2> labels,
+                              NeighborhoodType neighborhood,
+                              T backgroundValue,
+                              Equal equal)
+{
+    vigra_precondition(data.shape() == labels.shape(),
+        "labelMultiArrayWithBackground(): shape mismatch between input and output.");
+        
+    GridGraph<N, undirected_tag> graph(data.shape(), neighborhood);
+    return lemon_graph::labelGraphWithBackground(graph, data, labels, backgroundValue, equal);
+}
+
+template <unsigned int N, class T, class S1,
+                          class Label, class S2>
+inline Label 
+labelMultiArrayWithBackground(MultiArrayView<N, T, S1> const & data,
+                              MultiArrayView<N, Label, S2> labels,
+                              NeighborhoodType neighborhood = DirectNeighborhood,
+                              T backgroundValue = T())
+{
+    return labelMultiArrayWithBackground(data, labels, neighborhood, backgroundValue, std::equal_to<T>());
+}
+
+//@}
+
+} // namespace vigra
+
+#endif //VIGRA_MULTI_LABELING_HXX
diff --git a/include/vigra/multi_localminmax.hxx b/include/vigra/multi_localminmax.hxx
new file mode 100644
index 0000000..eddbab0
--- /dev/null
+++ b/include/vigra/multi_localminmax.hxx
@@ -0,0 +1,308 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2012-2013 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_MULTI_LOCALMINMAX_HXX
+#define VIGRA_MULTI_LOCALMINMAX_HXX
+
+#include <vector>
+#include <functional>
+#include "multi_array.hxx"
+#include "localminmax.hxx"
+#include "multi_gridgraph.hxx"
+#include "multi_labeling.hxx"
+#include "metaprogramming.hxx"
+
+namespace vigra {
+
+namespace boost_graph {
+
+  // Attempt without LValue propmaps, using only the free functions
+  // to access ReadablePropertyMap (input) and WritablePropertyMap (label)
+template <class Graph, class T1Map, class T2Map, class Compare>
+unsigned int
+localMinMaxGraph(Graph const &g, 
+                 T1Map const &src,
+                 T2Map &dest,
+                 typename property_traits<T2Map>::value_type marker,
+                 typename property_traits<T1Map const>::value_type threshold,
+                 Compare const &compare,
+                 bool allowAtBorder = true)
+{
+    typedef typename graph_traits<Graph>::vertex_iterator graph_scanner;
+    typedef typename graph_traits<Graph>::adjacency_iterator neighbor_iterator;
+
+    typedef typename property_traits<T1Map const>::value_type T1;
+
+    graph_scanner node, srcend;
+    neighbor_iterator arc, nbend;
+
+    unsigned int count = 0;
+    tie(node, srcend) = vertices(g);
+    for (; node != srcend; ++node) 
+    {
+        const T1 current = get(src, *node);
+
+        if (!compare(current, threshold))
+            continue;
+          
+        if(!allowAtBorder && node.atBorder())
+            continue;
+        
+        tie(arc, nbend) = adjacent_vertices(*node, g);
+        for (;arc != nbend; ++arc) 
+            if (!compare(current, get(src, *arc))) 
+                break;
+                
+        if (arc == nbend)
+        {
+            put(dest, *node, marker);
+            ++count;
+        }
+    }
+    return count;
+}
+
+} // namespace boost_graph
+
+namespace lemon_graph { 
+
+template <class Graph, class T1Map, class T2Map, class Compare>
+unsigned int
+localMinMaxGraph(Graph const &g, 
+                 T1Map const &src,
+                 T2Map &dest,
+                 typename T2Map::value_type marker,
+                 typename T1Map::value_type threshold,
+                 Compare const &compare,
+                 bool allowAtBorder = true)
+{
+    typedef typename Graph::NodeIt    graph_scanner;
+    typedef typename Graph::OutArcIt  neighbor_iterator;
+
+    unsigned int count = 0;
+    for (graph_scanner node(g); node != INVALID; ++node) 
+    {
+        typename T1Map::value_type current = src[*node];
+
+        if (!compare(current, threshold))
+            continue;
+          
+        if(!allowAtBorder && node.atBorder())
+            continue;
+        
+        neighbor_iterator arc(g, node);
+        for (; arc != INVALID; ++arc) 
+            if (!compare(current, src[g.target(*arc)])) 
+                break;
+                
+        if (arc == INVALID)
+        {
+            dest[*node] = marker;
+            ++count;
+        }
+    }
+    return count;
+}
+
+template <class Graph, class T1Map, class T2Map, class Compare, class Equal>
+unsigned int
+extendedLocalMinMaxGraph(Graph const &g, 
+                         T1Map const &src,
+                         T2Map &dest,
+                         typename T2Map::value_type marker,
+                         typename T1Map::value_type threshold,
+                         Compare const &compare,
+                         Equal const &equal,
+                         bool allowAtBorder = true)
+{
+    typename Graph::template NodeMap<unsigned int> regions(g);
+    
+    int max_region_label = labelGraph(g, src, regions, equal);
+    
+    // assume that a region is a extremum until the opposite is proved
+    std::vector<unsigned char> isExtremum(max_region_label+1, (unsigned char)1);
+
+    typedef typename Graph::NodeIt    graph_scanner;
+    typedef typename Graph::OutArcIt  neighbor_iterator;
+
+    unsigned int count = max_region_label;
+    for (graph_scanner node(g); node != INVALID; ++node) 
+    {
+        unsigned int label = regions[*node];
+        
+        if(!isExtremum[label])
+            continue;
+        
+        typename T1Map::value_type current = src[*node];
+
+        if (!compare(current, threshold) ||
+            (!allowAtBorder && node.atBorder()))
+        {
+            isExtremum[label] = 0;
+            --count;
+            continue;
+        }
+        
+        for (neighbor_iterator arc(g, node); arc != INVALID; ++arc) 
+        {
+            if (label != regions[g.target(*arc)] && compare(src[g.target(*arc)], current)) 
+            {
+                isExtremum[label] = 0;
+                --count;
+                break;
+            }
+        }
+    }
+    for (graph_scanner node(g); node != INVALID; ++node) 
+    {
+        if(isExtremum[regions[*node]])
+            dest[*node] = marker;
+    }
+    return count;
+}
+
+} // namespace lemon_graph
+
+template <unsigned int N, class T1, class C1, 
+                          class T2, class C2,
+          class Compare,
+          class EqualityFunctor>
+unsigned int
+localMinMax(MultiArrayView<N, T1, C1> const & src,
+            MultiArrayView<N, T2, C2> dest,
+            T1 threshold,
+            Compare const & compare,
+            EqualityFunctor const & equal,
+            LocalMinmaxOptions const & options = LocalMinmaxOptions())
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "localMinMax(): shape mismatch between input and output.");
+        
+    NeighborhoodType neighborhood = DirectNeighborhood;
+    
+    if(options.neigh == 0 || options.neigh == 2*N)
+        neighborhood = DirectNeighborhood;
+    else if(options.neigh == 1 || options.neigh == MetaPow<3, N>::value - 1)
+        neighborhood = IndirectNeighborhood;
+    else
+        vigra_precondition(false,
+            "localMinMax(): option object specifies invalid neighborhood type.");
+    
+    T2 marker = (T2)options.marker;
+    
+    GridGraph<N, undirected_tag> graph(src.shape(), neighborhood);
+    if(options.allow_plateaus)
+        return lemon_graph::extendedLocalMinMaxGraph(graph, src, dest, marker, threshold, 
+                                            compare, equal, options.allow_at_border);
+    else
+        return lemon_graph::localMinMaxGraph(graph, src, dest, marker, threshold, 
+                                             compare, options.allow_at_border);
+}
+
+/********************************************************/
+/*                                                      */
+/*                       localMinima                    */
+/*                                                      */
+/********************************************************/
+
+// documentation is in localminmax.hxx
+template <unsigned int N, class T1, class C1, class T2, class C2>
+inline unsigned int
+localMinima(MultiArrayView<N, T1, C1> const & src,
+            MultiArrayView<N, T2, C2> dest,
+            LocalMinmaxOptions const & options = LocalMinmaxOptions())
+{
+    T1 threshold = options.use_threshold
+                           ? std::min(NumericTraits<T1>::max(), (T1)options.thresh)
+                           : NumericTraits<T1>::max();
+    return localMinMax(src, dest, threshold, std::less<T1>(), std::equal_to<T1>(), options);
+}
+
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2,
+          class EqualityFunctor>
+inline unsigned int
+extendedLocalMinima(MultiArrayView<N, T1, S1> const & src,
+                    MultiArrayView<N, T2, S2> dest,
+                    EqualityFunctor const & equal,
+                    LocalMinmaxOptions options = LocalMinmaxOptions())
+{
+    options.allowPlateaus();
+    T1 threshold = options.use_threshold
+                           ? std::min(NumericTraits<T1>::max(), (T1)options.thresh)
+                           : NumericTraits<T1>::max();
+    return localMinMax(src, dest, threshold, std::less<T1>(), equal, options);
+}
+/********************************************************/
+/*                                                      */
+/*                       localMaxima                    */
+/*                                                      */
+/********************************************************/
+
+// documentation is in localminmax.hxx
+template <unsigned int N, class T1, class C1, class T2, class C2>
+inline unsigned int
+localMaxima(MultiArrayView<N, T1, C1> const & src,
+            MultiArrayView<N, T2, C2> dest,
+            LocalMinmaxOptions const & options = LocalMinmaxOptions())
+{
+    T1 threshold = options.use_threshold
+                           ? std::max(NumericTraits<T1>::min(), (T1)options.thresh)
+                           : NumericTraits<T1>::min();
+    return localMinMax(src, dest, threshold, std::greater<T1>(), std::equal_to<T1>(), options);
+}
+
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2,
+          class EqualityFunctor>
+inline unsigned int
+extendedLocalMaxima(MultiArrayView<N, T1, S1> const & src,
+                    MultiArrayView<N, T2, S2> dest,
+                    EqualityFunctor const & equal,
+                    LocalMinmaxOptions options = LocalMinmaxOptions())
+{
+    options.allowPlateaus();
+    T1 threshold = options.use_threshold
+                           ? std::max(NumericTraits<T1>::min(), (T1)options.thresh)
+                           : NumericTraits<T1>::min();
+    return localMinMax(src, dest, threshold, std::greater<T1>(), equal, options);
+}
+
+} // namespace vigra
+
+#endif // VIGRA_MULTI_LOCALMINMAX_HXX
diff --git a/include/vigra/multi_math.hxx b/include/vigra/multi_math.hxx
new file mode 100644
index 0000000..c737644
--- /dev/null
+++ b/include/vigra/multi_math.hxx
@@ -0,0 +1,882 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2010-2011 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_MATH_HXX
+#define VIGRA_MULTI_MATH_HXX
+
+#include "multi_array.hxx"
+#include "tinyvector.hxx"
+#include "rgbvalue.hxx"
+#include "mathutil.hxx"
+#include <complex>
+
+namespace vigra {
+
+/** \defgroup MultiMathModule vigra::multi_math
+
+    Namespace <tt>vigra::multi_math</tt> holds VIGRA's support for efficient arithmetic and algebraic functions on multi-dimensional arrays (that is, \ref MultiArrayView and its subclasses). All <tt>multi_math</tt> functions operate element-wise. If you need matrix multiplication, use \ref LinearAlgebraModule instead.
+    
+    In order to avoid overload ambiguities, multi-array arithmetic must be explicitly activated by
+    \code
+    using namespace vigra::multi_math;
+    \endcode
+    (this should not be done globally, but only in the scope where the functionality is actually used).
+    
+    You can then use the standard operators in the expected way:
+    \code
+    MultiArray<2, float> i(Shape2(100, 100)), j(Shape2(100, 100));
+    
+    MultiArray<2, float> h  = i + 4.0 * j;
+                         h += (i.transpose() - j) / 2.0;
+    \endcode
+    etc. (supported operators are <tt>+ - * / ! ~ % && || == != < <= > >= << >> & | ^ = += -= *= /=</tt>, with both scalar and array arguments). 
+    
+    Algebraic functions are available as well:
+    \code
+    h  = exp(-(sq(i) + sq(j)));
+    h *= atan2(-i, j);
+    \endcode
+    The following functions are implemented: <tt>abs, erf, even, odd, sign, signi, round, roundi, sqrt, sqrti, sq, 
+    norm, squaredNorm, gamma, loggamma, exp, log, log10, sin, sin_pi, cos, cos_pi, asin, acos, tan, atan, 
+    floor, ceil, conj, real, imag, arg, atan2, pow, fmod, min, max</tt>, 
+    provided the array's element type supports the respective function.
+    
+    Supported element types currently include the built-in numeric types, \ref TinyVector, \ref RGBValue, 
+    <tt>std::complex</tt>, and \ref FFTWComplex.
+
+    In addition, <tt>multi_math</tt> supports a number of functions that reduce arrays to scalars:
+    \code
+    double s = sum<double>(i);  // compute the sum of the elements, using 'double' as accumulator type
+    double p = product<double>(abs(i));  // compute the product of the elements' absolute values
+    
+    bool a = any(i < 0.0);  // check if any element of i is negative
+    bool b = all(i > 0.0);  // check if all elements of i are positive
+    \endcode
+    
+    Expressions are expanded so that no temporary arrays have to be created. To optimize cache locality,
+    loops are executed in the stride ordering of the left-hand-side array.
+    
+    <b>\#include</b> \<vigra/multi_math.hxx\>
+
+    Namespace: vigra::multi_math
+*/
+namespace multi_math {
+
+template <class ARG>
+struct MultiMathOperand
+{
+    typedef typename ARG::result_type result_type;
+    
+    static const int ndim = ARG::ndim;
+    
+    MultiMathOperand(ARG const & a)
+    : arg_(a)
+    {}
+        
+    // Check if all arrays involved in the expression have compatible shapes
+    // (including transparent expansion of singleton axes).
+    // 's' is the shape of the LHS array. If 's' is zero (i.e. the LHS is 
+    // not yet initialized), it is set to the maximal RHS shape.
+    //
+    template <class SHAPE>
+    bool checkShape(SHAPE & s) const
+    {
+        return arg_.checkShape(s);
+    }
+    
+    // increment the pointer of all RHS arrays along the given 'axis'
+    void inc(unsigned int axis) const
+    {
+        arg_.inc(axis);
+    }
+    
+    // reset the pointer of all RHS arrays along the given 'axis'
+    void reset(unsigned int axis) const
+    {
+        arg_.reset(axis);
+    }
+    
+    // get the value of the expression at the current pointer location
+    result_type operator*() const
+    {
+        return *arg_;
+    }
+    
+    // get the value of the expression at an offset of the current pointer location
+    template <class SHAPE>
+    result_type operator[](SHAPE const & s) const
+    {
+        return arg_[s];
+    }
+    
+    ARG arg_;
+};
+
+template <unsigned int N, class T, class C>
+struct MultiMathOperand<MultiArrayView<N, T, C> >
+{
+    typedef MultiMathOperand AllowOverload;    
+    typedef typename MultiArrayShape<N>::type Shape;
+
+    typedef T result_type;
+    
+    static const int ndim = (int)N;
+    
+    MultiMathOperand(MultiArrayView<N, T, C> const & a)
+    : p_(a.data()),
+      shape_(a.shape()),
+      strides_(a.stride())
+    {
+        // allow for transparent expansion of singleton dimensions
+        for(unsigned int k=0; k<N; ++k)
+            if(shape_[k] == 1)
+                strides_[k] = 0;
+    }
+    
+    bool checkShape(Shape & s) const
+    {
+        // support:
+        //   * transparent expansion of singleton dimensions
+        //   * determining LHS shape in a constructor
+        for(unsigned int k=0; k<N; ++k)
+        {
+            if(shape_[k] == 0)
+            {
+                return false;
+            }
+            else if(s[k] <= 1)
+            {
+                s[k] = shape_[k];
+            }
+            else if(shape_[k] > 1 && shape_[k] != s[k])
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    T const & operator[](Shape const & s) const
+    {
+        return p_[dot(s, strides_)];
+    }
+    
+    void inc(unsigned int axis) const
+    {
+        p_ += strides_[axis];
+    }
+    
+    void reset(unsigned int axis) const
+    {
+        p_ -= shape_[axis]*strides_[axis];
+    }
+    
+    result_type operator*() const
+    {
+        return *p_;
+    }
+    
+    mutable T const * p_;
+    Shape shape_, strides_;
+};
+
+template <unsigned int N, class T, class A>
+struct MultiMathOperand<MultiArray<N, T, A> >
+: public MultiMathOperand<MultiArrayView<N, T, UnstridedArrayTag> >
+{
+    typedef MultiMathOperand AllowOverload;
+    
+    MultiMathOperand(MultiArray<N, T, A> const & a)
+    : MultiMathOperand<MultiArrayView<N, T, UnstridedArrayTag> >(a)
+    {}
+};
+
+template <class T>
+struct MultiMathScalarOperand
+{
+    typedef MultiMathOperand<T> AllowOverload;
+    typedef T result_type;
+    
+    static const int ndim = 0;
+    
+    MultiMathScalarOperand(T const & v)
+    : v_(v)
+    {}
+    
+    template <class SHAPE>
+    bool checkShape(SHAPE const &) const
+    {
+        return true;
+    }
+    
+    template <class SHAPE>
+    T const & operator[](SHAPE const &) const
+    {
+        return v_;
+    }
+    
+    void inc(unsigned int /* axis */) const
+    {}
+    
+    void reset(unsigned int /* axis */) const
+    {}
+    
+    T const & operator*() const
+    {
+        return v_;
+    }
+    
+    T v_;
+};
+
+#define VIGRA_CONSTANT_OPERAND(template_dcl, type) \
+template template_dcl \
+struct MultiMathOperand<type > \
+: MultiMathScalarOperand<type > \
+{ \
+    MultiMathOperand(type const & v) \
+    : MultiMathScalarOperand<type >(v) \
+    {} \
+};
+
+VIGRA_CONSTANT_OPERAND(<>, signed char)
+VIGRA_CONSTANT_OPERAND(<>, signed short)
+VIGRA_CONSTANT_OPERAND(<>, signed int)
+VIGRA_CONSTANT_OPERAND(<>, signed long)
+VIGRA_CONSTANT_OPERAND(<>, signed long long)
+VIGRA_CONSTANT_OPERAND(<>, unsigned char)
+VIGRA_CONSTANT_OPERAND(<>, unsigned short)
+VIGRA_CONSTANT_OPERAND(<>, unsigned int)
+VIGRA_CONSTANT_OPERAND(<>, unsigned long)
+VIGRA_CONSTANT_OPERAND(<>, unsigned long long)
+VIGRA_CONSTANT_OPERAND(<>, float)
+VIGRA_CONSTANT_OPERAND(<>, double)
+VIGRA_CONSTANT_OPERAND(<>, long double)
+VIGRA_CONSTANT_OPERAND(<class T>, std::complex<T>)
+
+#define VIGRA_TINYVECTOR_ARGS <class T, int N>
+#define VIGRA_TINYVECTOR_DECL TinyVector<T, N>
+VIGRA_CONSTANT_OPERAND(VIGRA_TINYVECTOR_ARGS, VIGRA_TINYVECTOR_DECL)
+#undef VIGRA_TINYVECTOR_ARGS
+#undef VIGRA_TINYVECTOR_DECL
+
+#define VIGRA_RGBVALUE_ARGS <class V, unsigned int R, unsigned int G, unsigned int B>
+#define VIGRA_RGBVALUE_DECL RGBValue<V, R, G, B>
+VIGRA_CONSTANT_OPERAND(VIGRA_RGBVALUE_ARGS, VIGRA_RGBVALUE_DECL)
+#undef VIGRA_RGBVALUE_ARGS
+#undef VIGRA_RGBVALUE_DECL
+
+#undef VIGRA_CONSTANT_OPERAND
+
+template <class O, class F>
+struct MultiMathUnaryOperator
+{
+    typedef typename F::template Result<typename O::result_type>::type result_type;
+    
+    static const int ndim = O::ndim;
+                                    
+    MultiMathUnaryOperator(O const & o)
+    : o_(o)
+    {}
+    
+    template <class SHAPE>
+    bool checkShape(SHAPE & s) const
+    {
+        return o_.checkShape(s);
+    }
+    
+    //
+    void inc(unsigned int axis) const
+    {
+        o_.inc(axis);
+    }
+    
+    void reset(unsigned int axis) const
+    {
+        o_.reset(axis);
+    }
+    
+    template <class POINT>
+    result_type operator[](POINT const & p) const
+    {
+        return f_(o_[p]);
+    }
+    
+    result_type operator*() const
+    {
+        return f_(*o_);
+    }
+    
+    O o_;
+    F f_;
+};
+
+#define VIGRA_MULTIMATH_UNARY_OPERATOR(NAME, FCT, OPNAME, RESTYPE) \
+namespace math_detail { \
+struct NAME \
+{ \
+    template <class T> \
+    struct Result \
+    { \
+        typedef RESTYPE type; \
+    }; \
+     \
+    template <class T> \
+    typename Result<T>::type \
+    operator()(T const & t) const \
+    { \
+        return FCT(t); \
+    } \
+}; \
+} \
+ \
+template <unsigned int N, class T, class C> \
+MultiMathOperand<MultiMathUnaryOperator<MultiMathOperand<MultiArrayView<N, T, C> >, \
+                                        math_detail::NAME> > \
+OPNAME(MultiArrayView<N, T, C> const & v) \
+{ \
+    typedef MultiMathOperand<MultiArrayView<N, T, C> > O; \
+    typedef MultiMathUnaryOperator<O, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP(v)); \
+} \
+ \
+template <unsigned int N, class T, class A> \
+MultiMathOperand<MultiMathUnaryOperator<MultiMathOperand<MultiArray<N, T, A> >, \
+                                        math_detail::NAME> > \
+OPNAME(MultiArray<N, T, A> const & v) \
+{ \
+    typedef MultiMathOperand<MultiArray<N, T, A> > O; \
+    typedef MultiMathUnaryOperator<O, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP(v)); \
+} \
+ \
+template <class T> \
+MultiMathOperand<MultiMathUnaryOperator<MultiMathOperand<T>, \
+                                        math_detail::NAME> > \
+OPNAME(MultiMathOperand<T> const & v) \
+{ \
+    typedef MultiMathOperand<T> O; \
+    typedef MultiMathUnaryOperator<O, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP(v)); \
+}
+
+#define VIGRA_REALPROMOTE typename NumericTraits<T>::RealPromote
+
+#ifndef DOXYGEN  // doxygen gets confused by these macros
+
+VIGRA_MULTIMATH_UNARY_OPERATOR(Negate, -, operator-, T)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Not, !, operator!, T)
+VIGRA_MULTIMATH_UNARY_OPERATOR(BitwiseNot, ~, operator~, T)
+
+using vigra::abs;
+VIGRA_MULTIMATH_UNARY_OPERATOR(Abs, vigra::abs, abs, typename NormTraits<T>::NormType)
+
+using vigra::erf;
+VIGRA_MULTIMATH_UNARY_OPERATOR(Erf, vigra::erf, erf, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Even, vigra::even, even, bool)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Odd, vigra::odd, odd, bool)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Sign, vigra::sign, sign, T)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Signi, vigra::signi, signi, int)
+
+using vigra::round;
+VIGRA_MULTIMATH_UNARY_OPERATOR(Round, vigra::round, round, T)
+
+VIGRA_MULTIMATH_UNARY_OPERATOR(Roundi, vigra::roundi, roundi, int)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Sqrti, vigra::sqrti, sqrti, T)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Sq, vigra::sq, sq, typename NumericTraits<T>::Promote)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Norm, vigra::norm, norm, typename NormTraits<T>::NormType)
+VIGRA_MULTIMATH_UNARY_OPERATOR(SquaredNorm, vigra::squaredNorm, squaredNorm, 
+                               typename NormTraits<T>::SquaredNormType)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Sin_pi, vigra::sin_pi, sin_pi, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Cos_pi, vigra::cos_pi, cos_pi, VIGRA_REALPROMOTE)
+
+using vigra::gamma;
+VIGRA_MULTIMATH_UNARY_OPERATOR(Gamma, vigra::gamma, gamma, VIGRA_REALPROMOTE)
+
+using vigra::loggamma;
+VIGRA_MULTIMATH_UNARY_OPERATOR(Loggamma, vigra::loggamma, loggamma, VIGRA_REALPROMOTE)
+
+VIGRA_MULTIMATH_UNARY_OPERATOR(Sqrt, std::sqrt, sqrt, VIGRA_REALPROMOTE)
+using vigra::exp;
+VIGRA_MULTIMATH_UNARY_OPERATOR(Exp, vigra::exp, exp, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Log, std::log, log, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Log10, std::log10, log10, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Sin, std::sin, sin, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Asin, std::asin, asin, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Cos, std::cos, cos, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Acos, std::acos, acos, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Tan, std::tan, tan, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Atan, std::atan, atan, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Floor, std::floor, floor, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Ceil, std::ceil, ceil, VIGRA_REALPROMOTE)
+
+VIGRA_MULTIMATH_UNARY_OPERATOR(Conj, conj, conj, T)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Real, real, real, typename T::value_type)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Imag, imag, imag, typename T::value_type)
+VIGRA_MULTIMATH_UNARY_OPERATOR(Arg, arg, arg, typename T::value_type)
+
+#endif //DOXYGEN
+
+#undef VIGRA_REALPROMOTE
+#undef VIGRA_MULTIMATH_UNARY_OPERATOR
+
+template <class O1, class O2, class F>
+struct MultiMathBinaryOperator
+{
+    typedef typename F::template Result<typename O1::result_type,
+                                         typename O2::result_type>::type result_type;
+                                    
+    static const int ndim = O1::ndim > O2::ndim ? O1::ndim : O2::ndim;
+    
+    MultiMathBinaryOperator(O1 const & o1, O2 const & o2)
+    : o1_(o1),
+      o2_(o2)
+    {}
+    
+    template <class SHAPE>
+    bool checkShape(SHAPE & s) const
+    {
+        return o1_.checkShape(s) && o2_.checkShape(s);
+    }
+    
+    template <class POINT>
+    result_type operator[](POINT const & p) const
+    {
+        return f_(o1_[p], o2_[p]);
+    }
+    
+    void inc(unsigned int axis) const
+    {
+        o1_.inc(axis);
+        o2_.inc(axis);
+    }
+    
+    void reset(unsigned int axis) const
+    {
+        o1_.reset(axis);
+        o2_.reset(axis);
+    }
+    
+    result_type operator*() const
+    {
+        return f_(*o1_, *o2_);
+    }
+    
+    O1 o1_;
+    O2 o2_;
+    F f_;
+};
+
+
+// In the sequel, the nested type 'MultiMathOperand<T>::AllowOverload'
+// ensures that template functions only participate in overload
+// resolution when this type is defined, i.e. when T is a number 
+// or array type. It thus prevents 'ambiguous overload' errors.
+//
+#define VIGRA_MULTIMATH_BINARY_OPERATOR(NAME, FCT, OPNAME, SEP, RESTYPE) \
+\
+namespace math_detail { \
+struct NAME \
+{ \
+    template <class T1, class T2> \
+    struct Result \
+    { \
+        typedef RESTYPE type; \
+    }; \
+    \
+    template <class T1, class T2> \
+    typename Result<T1, T2>::type \
+    operator()(T1 const & t1, T2 const & t2) const \
+    { \
+        return FCT(t1 SEP t2); \
+    } \
+}; \
+} \
+ \
+template <unsigned int N, class T1, class A1, class T2, class A2> \
+MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1> >, \
+                                         MultiMathOperand<MultiArrayView<N, T2> >, \
+                                         math_detail::NAME> > \
+OPNAME(MultiArray<N, T1, A1> const & v1, MultiArray<N, T2, A2> const & v2) \
+{ \
+    typedef MultiMathOperand<MultiArrayView<N, T1> > O1; \
+    typedef MultiMathOperand<MultiArrayView<N, T2> > O2; \
+    typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP((MultiArrayView<N, T1> const &)v1, (MultiArrayView<N, T2> const &)v2)); \
+} \
+\
+template <unsigned int N, class T1, class C1, class T2, class C2> \
+MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1, C1> >, \
+                                         MultiMathOperand<MultiArrayView<N, T2, C2> >, \
+                                         math_detail::NAME> > \
+OPNAME(MultiArrayView<N, T1, C1> const & v1, MultiArrayView<N, T2, C2> const & v2) \
+{ \
+    typedef MultiMathOperand<MultiArrayView<N, T1, C1> > O1; \
+    typedef MultiMathOperand<MultiArrayView<N, T2, C2> > O2; \
+    typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP(v1, v2)); \
+} \
+\
+template <unsigned int N, class T1, class T2, class C2> \
+MultiMathOperand<MultiMathBinaryOperator<typename MultiMathOperand<T1>::AllowOverload, \
+                                         MultiMathOperand<MultiArrayView<N, T2, C2> >, \
+                                         math_detail::NAME> > \
+OPNAME(T1 const & v1, MultiArrayView<N, T2, C2> const & v2) \
+{ \
+    typedef MultiMathOperand<T1> O1; \
+    typedef MultiMathOperand<MultiArrayView<N, T2, C2> > O2; \
+    typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP(v1, v2)); \
+} \
+ \
+template <unsigned int N, class T1, class C1, class T2> \
+MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1, C1> >, \
+                                         typename MultiMathOperand<T2>::AllowOverload, \
+                                         math_detail::NAME> > \
+OPNAME(MultiArrayView<N, T1, C1> const & v1, T2 const & v2) \
+{ \
+    typedef MultiMathOperand<MultiArrayView<N, T1, C1> > O1; \
+    typedef MultiMathOperand<T2> O2; \
+    typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP(v1, v2)); \
+} \
+ \
+template <unsigned int N, class T1, class T2, class C2> \
+MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<T1>, \
+                                         MultiMathOperand<MultiArrayView<N, T2, C2> >, \
+                                         math_detail::NAME> > \
+OPNAME(MultiMathOperand<T1> const & v1, MultiArrayView<N, T2, C2> const & v2) \
+{ \
+    typedef MultiMathOperand<T1> O1; \
+    typedef MultiMathOperand<MultiArrayView<N, T2, C2> > O2; \
+    typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP(v1, v2)); \
+} \
+ \
+template <unsigned int N, class T1, class C1, class T2> \
+MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1, C1> >, \
+                                         MultiMathOperand<T2>, \
+                                         math_detail::NAME> > \
+OPNAME(MultiArrayView<N, T1, C1> const & v1, MultiMathOperand<T2> const & v2) \
+{ \
+    typedef MultiMathOperand<MultiArrayView<N, T1, C1> > O1; \
+    typedef MultiMathOperand<T2> O2; \
+    typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP(v1, v2)); \
+} \
+ \
+template <class T1, class T2> \
+MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<T1>, \
+                                         MultiMathOperand<T2>, \
+                                         math_detail::NAME> > \
+OPNAME(MultiMathOperand<T1> const & v1, MultiMathOperand<T2> const & v2) \
+{ \
+    typedef MultiMathOperand<T1> O1; \
+    typedef MultiMathOperand<T2> O2; \
+    typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP(v1, v2)); \
+} \
+\
+template <class T1, class T2> \
+MultiMathOperand<MultiMathBinaryOperator<typename MultiMathOperand<T1>::AllowOverload, \
+                                         MultiMathOperand<T2>, \
+                                         math_detail::NAME> > \
+OPNAME(T1 const & v1, MultiMathOperand<T2> const & v2) \
+{ \
+    typedef MultiMathOperand<T1> O1; \
+    typedef MultiMathOperand<T2> O2; \
+    typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP(v1, v2)); \
+} \
+\
+template <class T1, class T2> \
+MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<T1>, \
+                                         typename MultiMathOperand<T2>::AllowOverload, \
+                                         math_detail::NAME> > \
+OPNAME(MultiMathOperand<T1> const & v1, T2 const & v2) \
+{ \
+    typedef MultiMathOperand<T1> O1; \
+    typedef MultiMathOperand<T2> O2; \
+    typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \
+    return MultiMathOperand<OP>(OP(v1, v2)); \
+}
+
+#define VIGRA_NOTHING
+#define VIGRA_COMMA ,
+#define VIGRA_PROMOTE typename PromoteTraits<T1, T2>::Promote
+#define VIGRA_REALPROMOTE typename PromoteTraits<typename NumericTraits<T1>::RealPromote, \
+                                                 typename NumericTraits<T2>::RealPromote>::Promote
+
+VIGRA_MULTIMATH_BINARY_OPERATOR(Plus, VIGRA_NOTHING, operator+, +, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Minus, VIGRA_NOTHING, operator-, -, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Multiplies, VIGRA_NOTHING, operator*, *, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Divides, VIGRA_NOTHING, operator/, /, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Modulo, VIGRA_NOTHING, operator%, %, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(And, VIGRA_NOTHING, operator&&, &&, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Or, VIGRA_NOTHING, operator||, ||, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Equal, VIGRA_NOTHING, operator==, ==, bool)
+VIGRA_MULTIMATH_BINARY_OPERATOR(NotEqual, VIGRA_NOTHING, operator!=, !=, bool)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Less, VIGRA_NOTHING, operator<, <, bool)
+VIGRA_MULTIMATH_BINARY_OPERATOR(LessEqual, VIGRA_NOTHING, operator<=, <=, bool)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Greater, VIGRA_NOTHING, operator>, >, bool)
+VIGRA_MULTIMATH_BINARY_OPERATOR(GreaterEqual, VIGRA_NOTHING, operator>=, >=, bool)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Leftshift, VIGRA_NOTHING, operator<<, <<, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Rightshift, VIGRA_NOTHING, operator>>, >>, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(BitwiseAnd, VIGRA_NOTHING, operator&, &, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(BitwiseOr, VIGRA_NOTHING, operator|, |, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(BitwiseXor, VIGRA_NOTHING, operator^, ^, VIGRA_PROMOTE)
+
+VIGRA_MULTIMATH_BINARY_OPERATOR(Atan2, std::atan2, atan2, VIGRA_COMMA, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Pow, vigra::pow, pow, VIGRA_COMMA, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Fmod, std::fmod, fmod, VIGRA_COMMA, VIGRA_REALPROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Min, std::min, min, VIGRA_COMMA, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Max, std::max, max, VIGRA_COMMA, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Minimum, std::min, minimum, VIGRA_COMMA, VIGRA_PROMOTE)
+VIGRA_MULTIMATH_BINARY_OPERATOR(Maximum, std::max, maximum, VIGRA_COMMA, VIGRA_PROMOTE)
+
+#undef VIGRA_NOTHING
+#undef VIGRA_COMMA
+#undef VIGRA_PROMOTE
+#undef VIGRA_REALPROMOTE
+#undef VIGRA_MULTIMATH_BINARY_OPERATOR
+
+namespace math_detail {
+
+// We pass 'strideOrder' to the recursion in order to make sure
+// that the inner loop iterates over the output's major axis.
+// Of course, this does not help when the RHS arrays are ordered 
+// differently -- maybe it is better to find the most common order
+// among all arguments (both RHS and LHS)?
+//
+template <unsigned int N, class Assign>
+struct MultiMathExec
+{
+    enum { LEVEL = N-1 };
+    
+    template <class T, class Shape, class Expression>
+    static void exec(T * data, Shape const & shape, Shape const & strides, 
+                     Shape const & strideOrder, Expression const & e)
+    {
+        MultiArrayIndex axis = strideOrder[LEVEL];
+        for(MultiArrayIndex k=0; k<shape[axis]; ++k, data += strides[axis], e.inc(axis))
+        {
+            MultiMathExec<N-1, Assign>::exec(data, shape, strides, strideOrder, e);
+        }
+        e.reset(axis);
+        data -= shape[axis]*strides[axis];
+    }
+};
+
+template <class Assign>
+struct MultiMathExec<1, Assign>
+{
+    enum { LEVEL = 0 };
+    
+    template <class T, class Shape, class Expression>
+    static void exec(T * data, Shape const & shape, Shape const & strides, 
+                     Shape const & strideOrder, Expression const & e)
+    {
+        MultiArrayIndex axis = strideOrder[LEVEL];
+        for(MultiArrayIndex k=0; k<shape[axis]; ++k, data += strides[axis], e.inc(axis))
+        {
+            Assign::assign(data, e);
+        }
+        e.reset(axis);
+        data -= shape[axis]*strides[axis];
+    }
+};
+
+#define VIGRA_MULTIMATH_ASSIGN(NAME, OP) \
+struct MultiMath##NAME \
+{ \
+    template <class T, class Expression> \
+    static void assign(T * data, Expression const & e) \
+    { \
+        *data OP vigra::detail::RequiresExplicitCast<T>::cast(*e); \
+    } \
+}; \
+ \
+template <unsigned int N, class T, class C, class Expression> \
+void NAME(MultiArrayView<N, T, C> a, MultiMathOperand<Expression> const & e) \
+{ \
+    typename MultiArrayShape<N>::type shape(a.shape()); \
+     \
+    vigra_precondition(e.checkShape(shape), \
+       "multi_math: shape mismatch in expression."); \
+        \
+    MultiMathExec<N, MultiMath##NAME>::exec(a.data(), a.shape(), a.stride(), \
+                                            a.strideOrdering(), e); \
+} \
+ \
+template <unsigned int N, class T, class A, class Expression> \
+void NAME##OrResize(MultiArray<N, T, A> & a, MultiMathOperand<Expression> const & e) \
+{ \
+    typename MultiArrayShape<N>::type shape(a.shape()); \
+     \
+    vigra_precondition(e.checkShape(shape), \
+       "multi_math: shape mismatch in expression."); \
+        \
+    if(a.size() == 0) \
+        a.reshape(shape); \
+         \
+    MultiMathExec<N, MultiMath##NAME>::exec(a.data(), a.shape(), a.stride(), \
+                                            a.strideOrdering(), e); \
+}
+
+VIGRA_MULTIMATH_ASSIGN(assign, =)
+VIGRA_MULTIMATH_ASSIGN(plusAssign, +=)
+VIGRA_MULTIMATH_ASSIGN(minusAssign, -=)
+VIGRA_MULTIMATH_ASSIGN(multiplyAssign, *=)
+VIGRA_MULTIMATH_ASSIGN(divideAssign, /=)
+
+#undef VIGRA_MULTIMATH_ASSIGN
+
+template <unsigned int N, class Assign>
+struct MultiMathReduce
+{
+    enum { LEVEL = N-1 };
+    
+    template <class T, class Shape, class Expression>
+    static void exec(T & t, Shape const & shape, Expression const & e)
+    {
+        for(MultiArrayIndex k=0; k<shape[LEVEL]; ++k, e.inc(LEVEL))
+        {
+            MultiMathReduce<N-1, Assign>::exec(t, shape, e);
+        }
+        e.reset(LEVEL);
+    }
+};
+
+template <class Assign>
+struct MultiMathReduce<1, Assign>
+{
+    enum { LEVEL = 0 };
+    
+    template <class T, class Shape, class Expression>
+    static void exec(T & t, Shape const & shape, Expression const & e)
+    {
+        for(MultiArrayIndex k=0; k<shape[0]; ++k, e.inc(0))
+        {
+            Assign::assign(&t, e);
+        }
+        e.reset(0);
+    }
+};
+
+struct MultiMathReduceAll
+{
+    template <class T, class Expression>
+    static void assign(T * data, Expression const & e)
+    {
+        *data = *data && (*e != NumericTraits<typename Expression::result_type>::zero());
+    }
+};
+
+struct MultiMathReduceAny
+{
+    template <class T, class Expression>
+    static void assign(T * data, Expression const & e)
+    {
+        *data = *data || (*e != NumericTraits<typename Expression::result_type>::zero());
+    }
+};
+
+
+} // namespace math_detail
+
+template <class U, class T>
+U
+sum(MultiMathOperand<T> const & v, U res = NumericTraits<U>::zero()) 
+{ 
+    static const int ndim = MultiMathOperand<T>::ndim;
+    typename MultiArrayShape<ndim>::type shape;
+    v.checkShape(shape);
+    math_detail::MultiMathReduce<ndim, math_detail::MultiMathplusAssign>::exec(res, shape, v);
+    return res;
+}
+
+template <class U, unsigned int N, class T, class S>
+U
+sum(MultiArrayView<N, T, S> const & v, U res = NumericTraits<U>::zero()) 
+{ 
+    return v.template sum<U>() + res;
+}
+
+template <class U, class T>
+U
+product(MultiMathOperand<T> const & v, U res = NumericTraits<U>::one()) 
+{ 
+    static const int ndim = MultiMathOperand<T>::ndim;
+    typename MultiArrayShape<ndim>::type shape;
+    v.checkShape(shape);
+    math_detail::MultiMathReduce<ndim, math_detail::MultiMathmultiplyAssign>::exec(res, shape, v);
+    return res;
+}
+
+template <class U, unsigned int N, class T, class S>
+U
+product(MultiArrayView<N, T, S> const & v, U res = NumericTraits<U>::one()) 
+{ 
+    return v.template product<U>() * res;
+}
+
+template <class T>
+bool
+all(MultiMathOperand<T> const & v) 
+{ 
+    static const int ndim = MultiMathOperand<T>::ndim;
+    typename MultiArrayShape<ndim>::type shape;
+    v.checkShape(shape);
+    bool res = true;
+    math_detail::MultiMathReduce<ndim, math_detail::MultiMathReduceAll>::exec(res, shape, v);
+    return res;
+}
+
+template <class T>
+bool
+any(MultiMathOperand<T> const & v) 
+{ 
+    static const int ndim = MultiMathOperand<T>::ndim;
+    typename MultiArrayShape<ndim>::type shape;
+    v.checkShape(shape);
+    bool res = false;
+    math_detail::MultiMathReduce<ndim, math_detail::MultiMathReduceAny>::exec(res, shape, v);
+    return res;
+}
+
+
+}} // namespace vigra::multi_math
+
+#endif // VIGRA_MULTI_MATH_HXX
diff --git a/include/vigra/multi_morphology.hxx b/include/vigra/multi_morphology.hxx
new file mode 100644
index 0000000..1ca747f
--- /dev/null
+++ b/include/vigra/multi_morphology.hxx
@@ -0,0 +1,680 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2003-2007 by Kasim Terzic, Christian-Dennis Rahn       */
+/*                        and Ullrich Koethe                            */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_MORPHOLOGY_HXX
+#define VIGRA_MULTI_MORPHOLOGY_HXX
+
+#include <vector>
+#include <cmath>
+#include "multi_distance.hxx"
+#include "array_vector.hxx"
+#include "multi_array.hxx"
+#include "accessor.hxx"
+#include "numerictraits.hxx"
+#include "navigator.hxx"
+#include "metaprogramming.hxx"
+#include "multi_pointoperators.hxx"
+#include "functorexpression.hxx"
+
+namespace vigra
+{
+
+namespace detail {
+
+// this class simplifies the design, but more importantly, it makes sure
+// that the in-place code doesn't get compiled for boolean arrays 
+// (were it would never executed anyway -- see the specializations below)
+template <class DestType, class TmpType>
+struct MultiBinaryMorphologyImpl
+{
+    template <class SrcIterator, class SrcShape, class SrcAccessor,
+              class DestIterator, class DestAccessor>
+    static void
+    exec( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+          DestIterator d, DestAccessor dest, 
+          double radius, bool dilation)
+    {
+        using namespace vigra::functor;
+        
+        // Allocate a new temporary array if the distances squared wouldn't fit
+        MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
+            
+        separableMultiDistSquared(s, shape, src, 
+                                  tmpArray.traverser_begin(), typename AccessorTraits<TmpType>::default_accessor(), dilation );
+            
+        // threshold everything less than radius away from the edge
+        double radius2 = radius * radius;
+        DestType foreground = dilation 
+                                 ? NumericTraits<DestType>::zero()
+                                 : NumericTraits<DestType>::one(),
+                 background = dilation 
+                                 ? NumericTraits<DestType>::one()
+                                 : NumericTraits<DestType>::zero();
+        transformMultiArray( tmpArray.traverser_begin(), shape, StandardValueAccessor<double>(), 
+                             d, dest, 
+                             ifThenElse( Arg1() >= Param(radius2),
+                                         Param(foreground), Param(background) ) );
+    }
+};
+
+template <class DestType>
+struct MultiBinaryMorphologyImpl<DestType, DestType>
+{
+    template <class SrcIterator, class SrcShape, class SrcAccessor,
+              class DestIterator, class DestAccessor>
+    static void
+    exec( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+          DestIterator d, DestAccessor dest, 
+          double radius, bool dilation)
+    {
+        using namespace vigra::functor;
+
+        separableMultiDistSquared( s, shape, src, d, dest, dilation );
+        
+        // threshold everything less than radius away from the edge
+        DestType radius2 = detail::RequiresExplicitCast<DestType>::cast(radius * radius);
+        DestType foreground = dilation 
+                                 ? NumericTraits<DestType>::zero()
+                                 : NumericTraits<DestType>::one(),
+                 background = dilation 
+                                 ? NumericTraits<DestType>::one()
+                                 : NumericTraits<DestType>::zero();
+        transformMultiArray( d, shape, dest, d, dest, 
+                             ifThenElse( Arg1() > Param(radius2),
+                                         Param(foreground), Param(background) ) );
+    }
+};
+
+template <>
+struct MultiBinaryMorphologyImpl<bool, bool>
+{
+    template <class SrcIterator, class SrcShape, class SrcAccessor,
+              class DestIterator, class DestAccessor>
+    static void
+    exec( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+          DestIterator d, DestAccessor dest, double radius, bool dilation)
+    {
+        vigra_fail("multiBinaryMorphology(): Internal error (this function should never be called).");
+    }
+};
+
+} // namespace detail
+
+/** \addtogroup MultiArrayMorphology Morphological operators for multi-dimensional arrays.
+
+    These functions perform morphological operations on an arbitrary
+    dimensional array that is specified by iterators (compatible to \ref MultiIteratorPage)
+    and shape objects. It can therefore be applied to a wide range of data structures
+    (\ref vigra::MultiArrayView, \ref vigra::MultiArray etc.).
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*             multiBinaryErosion                       */
+/*                                                      */
+/********************************************************/
+/** \brief Binary erosion on multi-dimensional arrays.
+
+    This function applies a flat circular erosion operator with a given radius. The
+    operation is isotropic. The input is interpreted as a binary multi-dimensional 
+    array where non-zero pixels represent foreground and zero pixels represent 
+    background. In the output, foreground is always represented by ones 
+    (i.e. NumericTrais<typename DestAccessor::value_type>::one()).
+    
+    This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
+    A temporary internal array is only allocated if working on the destination
+    array directly would cause overflow errors (that is if
+    <tt> NumericTraits<typename DestAccessor::value_type>::max() < squaredNorm(shape)</tt>, 
+    i.e. the squared length of the image diagonal doesn't fit into the destination type).
+           
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        multiBinaryErosion(MultiArrayView<N, T1, S1> const & source,
+                           MultiArrayView<N, T2, S2> dest, 
+                           double radius);
+    }
+    \endcode
+
+    \deprecatedAPI{multiBinaryErosion}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        multiBinaryErosion(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                    DestIterator diter, DestAccessor dest, int radius);
+
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        multiBinaryErosion(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                    pair<DestIterator, DestAccessor> const & dest, 
+                                    int radius);
+
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_morphology.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, unsigned char> dest(shape);
+    ...
+
+    // perform isotropic binary erosion
+    multiBinaryErosion(source, dest, 3);
+    \endcode
+
+    \see vigra::discErosion(), vigra::multiGrayscaleErosion()
+*/
+doxygen_overloaded_function(template <...> void multiBinaryErosion)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+multiBinaryErosion( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                             DestIterator d, DestAccessor dest, double radius)
+{
+    typedef typename DestAccessor::value_type DestType;
+    typedef Int32 TmpType;
+    
+    double dmax = squaredNorm(shape);
+
+    // Get the distance squared transform of the image
+    if(dmax > NumericTraits<DestType>::toRealPromote(NumericTraits<DestType>::max()))
+    {
+        detail::MultiBinaryMorphologyImpl<DestType, TmpType>::exec(s, shape, src, d, dest, radius, false);
+    }
+    else    // work directly on the destination array
+    {
+        detail::MultiBinaryMorphologyImpl<DestType, DestType>::exec(s, shape, src, d, dest, radius, false);
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+multiBinaryErosion(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                   pair<DestIterator, DestAccessor> const & dest, double radius)
+{
+    multiBinaryErosion( source.first, source.second, source.third,
+                        dest.first, dest.second, radius );
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+multiBinaryErosion(MultiArrayView<N, T1, S1> const & source,
+                   MultiArrayView<N, T2, S2> dest, 
+                   double radius)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "multiBinaryErosion(): shape mismatch between input and output.");
+    multiBinaryErosion( srcMultiArrayRange(source),
+                        destMultiArray(dest), radius );
+}
+
+/********************************************************/
+/*                                                      */
+/*             multiBinaryDilation                      */
+/*                                                      */
+/********************************************************/
+
+/** \brief Binary dilation on multi-dimensional arrays.
+
+    This function applies a flat circular dilation operator with a given radius. The
+    operation is isotropic. The input is interpreted as a binary multi-dimensional 
+    array where non-zero pixels represent foreground and zero pixels represent 
+    background. In the output, foreground is always represented by ones 
+    (i.e. NumericTrais<typename DestAccessor::value_type>::one()).
+    
+    This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
+    A temporary internal array is only allocated if working on the destination
+    array directly would cause overflow errors (that is if
+    <tt> NumericTraits<typename DestAccessor::value_type>::max() < squaredNorm(shape)</tt>, 
+    i.e. the squared length of the image diagonal doesn't fit into the destination type).
+           
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void 
+        multiBinaryDilation(MultiArrayView<N, T1, S1> const & source,
+                            MultiArrayView<N, T2, S2> dest,
+                            double radius);
+    }
+    \endcode
+
+    \deprecatedAPI{multiBinaryDilation}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        multiBinaryDilation(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                    DestIterator diter, DestAccessor dest, int radius);
+
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        multiBinaryDilation(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                    pair<DestIterator, DestAccessor> const & dest, 
+                                    int radius);
+
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_morphology.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, unsigned char> dest(shape);
+    ...
+
+    // perform isotropic binary erosion
+    multiBinaryDilation(source, dest, 3);
+    \endcode
+
+    \see vigra::discDilation(), vigra::multiGrayscaleDilation()
+*/
+doxygen_overloaded_function(template <...> void multiBinaryDilation)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+multiBinaryDilation( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                             DestIterator d, DestAccessor dest, double radius)
+{
+    typedef typename DestAccessor::value_type DestType;
+    typedef Int32 TmpType;
+    
+    double dmax = squaredNorm(shape);
+
+    // Get the distance squared transform of the image
+    if(dmax > NumericTraits<DestType>::toRealPromote(NumericTraits<DestType>::max()))
+    {
+        detail::MultiBinaryMorphologyImpl<DestType, TmpType>::exec(s, shape, src, d, dest, radius, true);
+    }
+    else    // work directly on the destination array
+    {
+        detail::MultiBinaryMorphologyImpl<DestType, DestType>::exec(s, shape, src, d, dest, radius, true);
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+multiBinaryDilation(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                    pair<DestIterator, DestAccessor> const & dest, double radius)
+{
+    multiBinaryDilation( source.first, source.second, source.third,
+                         dest.first, dest.second, radius );
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void 
+multiBinaryDilation(MultiArrayView<N, T1, S1> const & source,
+                    MultiArrayView<N, T2, S2> dest,
+                    double radius)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "multiBinaryDilation(): shape mismatch between input and output.");
+    multiBinaryDilation( srcMultiArrayRange(source),
+                         destMultiArray(dest), radius );
+}
+
+/********************************************************/
+/*                                                      */
+/*             multiGrayscaleErosion                    */
+/*                                                      */
+/********************************************************/
+/** \brief Parabolic grayscale erosion on multi-dimensional arrays.
+
+    This function applies a parabolic erosion operator with a given spread (sigma) on
+    a grayscale array. The operation is isotropic.
+    The input is a grayscale multi-dimensional array.
+    
+    This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
+    A full-sized internal array is only allocated if working on the destination
+    array directly would cause overflow errors (i.e. if
+    <tt> typeid(typename DestAccessor::value_type) < N * M*M</tt>, where M is the
+    size of the largest dimension of the array.
+           
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        multiGrayscaleErosion(MultiArrayView<N, T1, S1> const & source,
+                              MultiArrayView<N, T2, S2> dest, 
+                              double sigma);
+    }
+    \endcode
+
+    \deprecatedAPI{multiGrayscaleErosion}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        multiGrayscaleErosion(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                    DestIterator diter, DestAccessor dest, double sigma);
+
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        multiGrayscaleErosion(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                    pair<DestIterator, DestAccessor> const & dest, 
+                                    double sigma);
+
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_morphology.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, unsigned char> dest(shape);
+    ...
+
+    // perform isotropic grayscale erosion
+    multiGrayscaleErosion(source, dest, 3.0);
+    \endcode
+
+    \see vigra::discErosion(), vigra::multiBinaryErosion()
+*/
+doxygen_overloaded_function(template <...> void multiGrayscaleErosion)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+multiGrayscaleErosion( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                       DestIterator d, DestAccessor dest, double sigma)
+{
+    typedef typename NumericTraits<typename DestAccessor::value_type>::ValueType DestType;
+    typedef typename NumericTraits<typename DestAccessor::value_type>::Promote TmpType;
+    DestType MaxValue = NumericTraits<DestType>::max();
+    enum { N = 1 + SrcIterator::level };
+    
+    // temporary array to hold the current line to enable in-place operation
+    ArrayVector<TmpType> tmp( shape[0] );
+        
+    int MaxDim = 0; 
+    for( int i=0; i<N; i++)
+        if(MaxDim < shape[i]) MaxDim = shape[i];
+    
+    using namespace vigra::functor;
+    
+    ArrayVector<double> sigmas(shape.size(), sigma);
+    
+    // Allocate a new temporary array if the distances squared wouldn't fit
+    if(N*MaxDim*MaxDim > MaxValue)
+    {
+        MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
+
+        detail::internalSeparableMultiArrayDistTmp( s, shape, src, tmpArray.traverser_begin(),
+            typename AccessorTraits<TmpType>::default_accessor(), sigmas );
+        
+        transformMultiArray( tmpArray.traverser_begin(), shape,
+                typename AccessorTraits<TmpType>::default_accessor(), d, dest,
+                ifThenElse( Arg1() > Param(MaxValue), Param(MaxValue), Arg1() ) );
+        //copyMultiArray( tmpArray.traverser_begin(), shape,
+        //        typename AccessorTraits<TmpType>::default_accessor(), d, dest );
+    }
+    else
+    {
+        detail::internalSeparableMultiArrayDistTmp( s, shape, src, d, dest, sigmas );
+    }
+
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+multiGrayscaleErosion(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                      pair<DestIterator, DestAccessor> const & dest, double sigma)
+{
+    multiGrayscaleErosion( source.first, source.second, source.third, 
+                           dest.first, dest.second, sigma);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+multiGrayscaleErosion(MultiArrayView<N, T1, S1> const & source,
+                      MultiArrayView<N, T2, S2> dest, 
+                      double sigma)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "multiGrayscaleErosion(): shape mismatch between input and output.");
+    multiGrayscaleErosion( srcMultiArrayRange(source), 
+                           destMultiArray(dest), sigma);
+}
+
+/********************************************************/
+/*                                                      */
+/*             multiGrayscaleDilation                   */
+/*                                                      */
+/********************************************************/
+/** \brief Parabolic grayscale dilation on multi-dimensional arrays.
+
+    This function applies a parabolic dilation operator with a given spread (sigma) on
+    a grayscale array. The operation is isotropic.
+    The input is a grayscale multi-dimensional array.
+    
+    This function may work in-place, which means that <tt>siter == diter</tt> is allowed.
+    A full-sized internal array is only allocated if working on the destination
+    array directly would cause overflow errors (i.e. if
+    <tt> typeid(typename DestAccessor::value_type) < N * M*M</tt>, where M is the
+    size of the largest dimension of the array.
+           
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void
+        multiGrayscaleDilation(MultiArrayView<N, T1, S1> const & source,
+                               MultiArrayView<N, T2, S2> dest,
+                               double sigma);
+    }
+    \endcode
+
+    \deprecatedAPI{multiGrayscaleDilation}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        multiGrayscaleDilation(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
+                                    DestIterator diter, DestAccessor dest, double sigma);
+
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        multiGrayscaleDilation(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                                    pair<DestIterator, DestAccessor> const & dest, 
+                                    double sigma);
+
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_morphology.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Shape3 shape(width, height, depth);
+    MultiArray<3, unsigned char> source(shape);
+    MultiArray<3, unsigned char> dest(shape);
+    ...
+
+    // perform isotropic grayscale erosion
+    multiGrayscaleDilation(source, dest, 3.0);
+    \endcode
+
+    \see vigra::discDilation(), vigra::multiBinaryDilation()
+*/
+doxygen_overloaded_function(template <...> void multiGrayscaleDilation)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void multiGrayscaleDilation( SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                             DestIterator d, DestAccessor dest, double sigma)
+{
+    typedef typename NumericTraits<typename DestAccessor::value_type>::ValueType DestType;
+    typedef typename NumericTraits<typename DestAccessor::value_type>::Promote TmpType;
+    DestType MinValue = NumericTraits<DestType>::min();
+    DestType MaxValue = NumericTraits<DestType>::max();
+    enum { N = 1 + SrcIterator::level };
+        
+    // temporary array to hold the current line to enable in-place operation
+    ArrayVector<TmpType> tmp( shape[0] );
+    
+    int MaxDim = 0; 
+    for( int i=0; i<N; i++)
+        if(MaxDim < shape[i]) MaxDim = shape[i];
+    
+    using namespace vigra::functor;
+
+    ArrayVector<double> sigmas(shape.size(), sigma);
+
+    // Allocate a new temporary array if the distances squared wouldn't fit
+    if(-N*MaxDim*MaxDim < MinValue || N*MaxDim*MaxDim > MaxValue)
+    {
+        MultiArray<SrcShape::static_size, TmpType> tmpArray(shape);
+
+        detail::internalSeparableMultiArrayDistTmp( s, shape, src, tmpArray.traverser_begin(),
+            typename AccessorTraits<TmpType>::default_accessor(), sigmas, true );
+        
+        transformMultiArray( tmpArray.traverser_begin(), shape,
+                typename AccessorTraits<TmpType>::default_accessor(), d, dest,
+                ifThenElse( Arg1() > Param(MaxValue), Param(MaxValue), 
+                    ifThenElse( Arg1() < Param(MinValue), Param(MinValue), Arg1() ) ) );
+    }
+    else
+    {
+        detail::internalSeparableMultiArrayDistTmp( s, shape, src, d, dest, sigmas, true );
+    }
+
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+multiGrayscaleDilation(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
+                       pair<DestIterator, DestAccessor> const & dest, double sigma)
+{
+    multiGrayscaleDilation( source.first, source.second, source.third, 
+                            dest.first, dest.second, sigma);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+multiGrayscaleDilation(MultiArrayView<N, T1, S1> const & source,
+                       MultiArrayView<N, T2, S2> dest,
+                       double sigma)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "multiGrayscaleDilation(): shape mismatch between input and output.");
+    multiGrayscaleDilation( srcMultiArrayRange(source), 
+                            destMultiArray(dest), sigma);
+}
+
+//@}
+
+} //-- namespace vigra
+
+
+#endif        //-- VIGRA_MULTI_MORPHOLOGY_HXX
diff --git a/include/vigra/multi_opencl.hxx b/include/vigra/multi_opencl.hxx
new file mode 100644
index 0000000..2682206
--- /dev/null
+++ b/include/vigra/multi_opencl.hxx
@@ -0,0 +1,443 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*               Copyright 2011-2011 by Michael Tesch                   */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_OPENCL_HXX
+#define VIGRA_OPENCL_HXX
+
+#include "numerictraits.hxx"
+
+#ifdef __APPLE__
+#include <OpenCL/opencl.h>
+#else
+#include <CL/opencl.h>
+#endif
+
+namespace vigra {
+
+/********************************************************/
+/*                                                      */
+/*                      NumericTraits                   */
+/*                                                      */
+/********************************************************/
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+#define VIGRA_OPENCL_VECTYPEN_INTEGER_TRAITS(basetype, n)               \
+  template<>                                                            \
+  struct NumericTraits< basetype##n >                                   \
+  {                                                                     \
+    typedef basetype##n Type;                                           \
+    typedef Type Promote;                                               \
+    typedef Type UnsignedPromote;                                       \
+    typedef Type RealPromote;                                           \
+    typedef std::complex<Type> ComplexPromote;                          \
+    typedef basetype ValueType;                                         \
+                                                                        \
+    typedef VigraFalseType isIntegral;                                  \
+    typedef VigraFalseType isScalar;                                    \
+    typedef typename NumericTraits<ValueType>::isSigned isSigned;       \
+    typedef VigraFalseType isOrdered;                                   \
+    typedef typename NumericTraits<ValueType>::isComplex isComplex;     \
+                                                                        \
+    static Type zero() { Type x; bzero(&x, sizeof(x)); return x; }      \
+    static Type one() { Type x = {{1}}; return x; }                     \
+    static Type nonZero() { return one(); }                             \
+                                                                        \
+    static Promote toPromote(Type const & v) { return v; }              \
+    static Type fromPromote(Promote const & v) { return v; }            \
+    static Type fromRealPromote(RealPromote v) { return v; }            \
+  }
+
+#define VIGRA_OPENCL_VECTYPEN_REAL_TRAITS(basetype, n)                  \
+  template<>                                                            \
+  struct NumericTraits< basetype##n >                                   \
+  {                                                                     \
+    typedef basetype##n Type;                                           \
+    typedef Type Promote;                                               \
+    typedef Type UnsignedPromote;                                       \
+    typedef Type RealPromote;                                           \
+    typedef std::complex<Type> ComplexPromote;                          \
+    typedef basetype ValueType;                                         \
+                                                                        \
+    typedef VigraFalseType isIntegral;                                  \
+    typedef VigraFalseType isScalar;                                    \
+    typedef typename NumericTraits<ValueType>::isSigned isSigned;       \
+    typedef VigraFalseType isOrdered;                                   \
+    typedef typename NumericTraits<ValueType>::isComplex isComplex;     \
+                                                                        \
+    static Type zero() { Type x; bzero(&x, sizeof(x)); return x; }      \
+    static Type one() { Type x = {{1}}; return x; }                     \
+    static Type nonZero() { return one(); }                             \
+    static Type epsilon() { Type x; x.x = NumericTraits<ValueType>::epsilon(); return x; } \
+    static Type smallestPositive() { Type x; x.x = NumericTraits<ValueType>::smallestPositive(); return x; } \
+                                                                        \
+    static Promote toPromote(Type const & v) { return v; }              \
+    static Type fromPromote(Promote const & v) { return v; }            \
+    static Type fromRealPromote(RealPromote v) { return v; }            \
+  }
+
+/// \todo - fix one() - maybe with .hi and .lo accessors?
+
+#define VIGRA_OPENCL_VECN_TRAITS(n)                          \
+  VIGRA_OPENCL_VECTYPEN_INTEGER_TRAITS(cl_char, n);          \
+    VIGRA_OPENCL_VECTYPEN_INTEGER_TRAITS(cl_uchar, n);       \
+    VIGRA_OPENCL_VECTYPEN_INTEGER_TRAITS(cl_short, n);       \
+    VIGRA_OPENCL_VECTYPEN_INTEGER_TRAITS(cl_ushort, n);      \
+    VIGRA_OPENCL_VECTYPEN_INTEGER_TRAITS(cl_int, n);         \
+    VIGRA_OPENCL_VECTYPEN_INTEGER_TRAITS(cl_uint, n);        \
+    VIGRA_OPENCL_VECTYPEN_INTEGER_TRAITS(cl_long, n);        \
+    VIGRA_OPENCL_VECTYPEN_INTEGER_TRAITS(cl_ulong, n);       \
+    VIGRA_OPENCL_VECTYPEN_REAL_TRAITS(cl_float, n);          \
+    VIGRA_OPENCL_VECTYPEN_REAL_TRAITS(cl_double, n);
+
+VIGRA_OPENCL_VECN_TRAITS(2);
+VIGRA_OPENCL_VECN_TRAITS(3);
+//VIGRA_OPENCL_VECN_TRAITS(4); // cl_type4 is the same as cl_type3
+VIGRA_OPENCL_VECN_TRAITS(8);
+VIGRA_OPENCL_VECN_TRAITS(16);
+
+#undef VIGRA_OPENCL_VECTYPEN_INTEGER_TRAITS
+#undef VIGRA_OPENCL_VECTYPEN_REAL_TRAITS
+#undef VIGRA_OPENCL_VECN_TRAITS
+
+/** \todo looks like the windows CL/cl_platform.h does signed/unsigned
+ *      strangely, so that the signed properties may not have the right
+ *      NumericalTraits::isSigned -- not sure if there's a reason for that.
+ */
+
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+/********************************************************/
+/*                                                      */
+/*                    SquareRootTraits                  */
+/*                                                      */
+/********************************************************/
+
+/********************************************************/
+/*                                                      */
+/*                       NormTraits                     */
+/*                                                      */
+/********************************************************/
+
+#if 0
+template<>
+struct NormTraits<fftw_complex>
+{
+    typedef fftw_complex Type;
+    typedef fftw_real    SquaredNormType;
+    typedef fftw_real    NormType;
+};
+
+template<class Real>
+struct NormTraits<FFTWComplex<Real> >
+{
+    typedef FFTWComplex<Real>  Type;
+    typedef typename Type::SquaredNormType   SquaredNormType;
+    typedef typename Type::NormType   NormType;
+};
+#endif
+
+/********************************************************/
+/*                                                      */
+/*                      PromoteTraits                   */
+/*                                                      */
+/********************************************************/
+
+#if 0
+template<class T>
+struct CanSkipInitialization<std::complex<T> >
+{
+    typedef typename CanSkipInitialization<T>::type type;
+    static const bool value = type::asBool;
+};
+#endif
+
+/********************************************************/
+/*                                                      */
+/*                      multi_math                      */
+/*                                                      */
+/********************************************************/
+
+namespace multi_math {
+
+/// \todo !
+
+/**     OpenCL 1.1 [6.2] - Convert operators */
+/**     OpenCL 1.1 [6.3] - Scalar/vector math operators */
+
+/**     OpenCL 1.1 [6.11.2] - Math Built-in Functions */
+/**     OpenCL 1.1 [6.11.3] - Integer Built-in Functions */
+/**     OpenCL 1.1 [6.11.4] - Common Built-in Functions */
+/**     OpenCL 1.1 [6.11.5] - Geometric Built-in Functions */
+/**     OpenCL 1.1 [6.11.6] - Relational Built-in Functions */
+/**     OpenCL 1.1 [6.11.7] - Vector Data Load/Store Built-in Functions */
+
+/**     OpenCL 1.1 [6.11.12] - Misc Vector Built-in Functions */
+
+/**     OpenCL 1.1 [6.11.12] - Image Read and Write Built-in Functions */
+
+
+} // namespace multi_math
+
+/********************************************************/
+/*                                                      */
+/*                  Channel Accessors                   */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup DataAccessors
+*/
+//@{
+/** \defgroup OpenCL-Accessors Accessors for OpenCL types
+
+    Encapsulate access to members of OpenCL vector types.
+
+
+    <b>\#include</b> \<vigra/multi_opencl.hxx\>
+
+    OpenCL 1.1 [6.1.7] - Vector Components
+
+    - cl_TYPE2Accessor_x
+    - cl_TYPE2Accessor_y
+    - cl_TYPE2Accessor_s0
+    - cl_TYPE2Accessor_s1
+
+    - cl_TYPE2WriteAccessor_x
+    - cl_TYPE2WriteAccessor_y
+    - cl_TYPE2WriteAccessor_s0
+    - cl_TYPE2WriteAccessor_s1
+
+    - cl_TYPE3Accessor_x
+    - cl_TYPE3Accessor_y
+    - cl_TYPE3Accessor_z
+    - cl_TYPE3Accessor_s0
+    - cl_TYPE3Accessor_s1
+    - cl_TYPE3Accessor_s2
+
+    - cl_TYPE3WriteAccessor_x
+    - cl_TYPE3WriteAccessor_y
+    - cl_TYPE3WriteAccessor_z
+    - cl_TYPE3WriteAccessor_s0
+    - cl_TYPE3WriteAccessor_s1
+    - ...
+
+    where TYPE is one of {char, uchar, short, ushort, int, uint, long, ulong, float, double }
+
+    For example:
+
+    \code
+
+    #include <vigra/multi_opencl.hxx>
+
+    MultiArrayView<2, cl_double3 > dataView = ...;
+
+    vigra::FindMinMax<double> minmax;
+    vigra::inspectMultiArray(srcMultiArrayRange(dataView, cl_double3Accessor_z()), minmax);
+    std::cout << "range of .z: " << minmax.min << " - " << minmax.max;
+
+    \endcode
+*/
+//@{
+/**
+   \class cl_charNAccessor_COMP
+   
+   access the first component.
+
+   \class cl_TYPE3WriteAccessor_s1
+
+   access the second component.
+
+   \class cl_TYPE3WriteAccessor_s2
+
+   access the third component.
+*/
+
+//@}
+//@}
+
+#define VIGRA_OPENCL_TYPE_ACCESSOR(basetype, n, NTH) \
+  class basetype##n##Accessor_##NTH                  \
+  {                                                             \
+  public:                                                       \
+    /** The accessor's value type. */                           \
+    typedef NumericTraits< basetype##n >::ValueType value_type; \
+                                                                \
+    /** Read component at iterator position. */                 \
+    template <class ITERATOR>                                   \
+      value_type operator()(ITERATOR const & i) const {         \
+      return (*i).NTH;                                          \
+    }                                                           \
+                                                                \
+    /** Read component at offset from iterator position. */             \
+    template <class ITERATOR, class DIFFERENCE>                         \
+      value_type operator()(ITERATOR const & i, DIFFERENCE d) const {   \
+      return i[d].NTH;                                                  \
+    }                                                                   \
+                                                                        \
+    /** Write component at iterator position from a scalar. */          \
+    template <class ITERATOR>                                           \
+      void set(value_type const & v, ITERATOR const & i) const {        \
+      (*i).NTH = v;                                                     \
+    }                                                                   \
+                                                                        \
+    /** Write component at offset from iterator position from a scalar. */ \
+    template <class ITERATOR, class DIFFERENCE>                         \
+      void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const { \
+      i[d].NTH = v;                                                     \
+    }                                                                   \
+                                                                        \
+    /** Write component at iterator position into a scalar. */          \
+    template <class R, class ITERATOR>                                  \
+      void set(FFTWComplex<R> const & v, ITERATOR const & i) const {    \
+      *i = v.NTH;                                                       \
+    }                                                                   \
+                                                                        \
+    /** Write component at offset from iterator position into a scalar. */ \
+    template <class R, class ITERATOR, class DIFFERENCE>                \
+      void set(FFTWComplex<R> const & v, ITERATOR const & i, DIFFERENCE d) const { \
+      i[d] = v.NTH;                                                     \
+    }                                                                   \
+  };                                                                    \
+  class basetype##n##WriteAccessor_##NTH                                \
+    : public basetype##n##Accessor_##NTH                                \
+  {                                                                     \
+  public:                                                               \
+    /** The accessor's value type. */                                   \
+    typedef NumericTraits< basetype##n >::ValueType value_type;         \
+                                                                        \
+    /** Write component at iterator position. */                        \
+    template <class ITERATOR>                                           \
+    void set(value_type const & v, ITERATOR const & i) const {          \
+      (*i).NTH = v;                                                     \
+    }                                                                   \
+                                                                        \
+    /** Write component at offset from iterator position. */            \
+    template <class ITERATOR, class DIFFERENCE>                         \
+    void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const { \
+      i[d].NTH = v;                                                     \
+    }                                                                   \
+  }
+
+#define VIGRA_OPENCL_TYPE2_ACCESSORS(basetype)  \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 2, s0);  \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 2, s1);  \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 2, x);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 2, y);
+
+#define VIGRA_OPENCL_TYPE3_ACCESSORS(basetype)  \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 3, s0);  \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 3, s1);  \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 3, s2);  \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 3, x);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 3, y);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 3, z);
+
+#define VIGRA_OPENCL_TYPE4_ACCESSORS(basetype)   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 4, s0);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 4, s1);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 4, s2);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 4, s3);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 4, x);    \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 4, y);    \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 4, z);    \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 4, w);
+
+#define VIGRA_OPENCL_TYPE8_ACCESSORS(basetype)   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 8, s0);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 8, s1);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 8, s2);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 8, s3);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 8, s4);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 8, s5);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 8, s6);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 8, s7);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 8, s8);
+
+#define VIGRA_OPENCL_TYPE16_ACCESSORS(basetype)   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, s0);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, s1);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, s2);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, s3);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, s4);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, s5);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, s6);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, s7);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, s8);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, sa);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, sb);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, sc);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, sd);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, se);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, sf);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, sA);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, sB);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, sC);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, sD);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, sE);   \
+  VIGRA_OPENCL_TYPE_ACCESSOR(basetype, 16, sF);
+
+/// \todo figure out half (.hi .lo, .even .odd) and other odd-sized accessors
+
+#define VIGRA_OPENCL_ACCESSORS(basetype)  \
+  VIGRA_OPENCL_TYPE2_ACCESSORS(basetype); \
+  VIGRA_OPENCL_TYPE3_ACCESSORS(basetype); \
+  VIGRA_OPENCL_TYPE4_ACCESSORS(basetype); \
+  VIGRA_OPENCL_TYPE8_ACCESSORS(basetype); \
+  VIGRA_OPENCL_TYPE16_ACCESSORS(basetype);
+
+VIGRA_OPENCL_ACCESSORS(cl_char);
+VIGRA_OPENCL_ACCESSORS(cl_uchar);
+VIGRA_OPENCL_ACCESSORS(cl_short);
+VIGRA_OPENCL_ACCESSORS(cl_ushort);
+VIGRA_OPENCL_ACCESSORS(cl_int);
+VIGRA_OPENCL_ACCESSORS(cl_uint);
+VIGRA_OPENCL_ACCESSORS(cl_long);
+VIGRA_OPENCL_ACCESSORS(cl_ulong);
+VIGRA_OPENCL_ACCESSORS(cl_float);
+VIGRA_OPENCL_ACCESSORS(cl_double);
+
+#undef VIGRA_OPENCL_TYPE_ACCESSOR
+#undef VIGRA_OPENCL_TYPE2_ACCESSORS
+#undef VIGRA_OPENCL_TYPE3_ACCESSORS
+#undef VIGRA_OPENCL_TYPE4_ACCESSORS
+#undef VIGRA_OPENCL_TYPE8_ACCESSORS
+#undef VIGRA_OPENCL_TYPE16_ACCESSORS
+#undef VIGRA_OPENCL_ACCESSORS
+
+} // namespace vigra
+
+#endif // VIGRA_OPENCL_HXX
diff --git a/include/vigra/multi_pointoperators.hxx b/include/vigra/multi_pointoperators.hxx
new file mode 100644
index 0000000..e94debd
--- /dev/null
+++ b/include/vigra/multi_pointoperators.hxx
@@ -0,0 +1,2030 @@
+//-- -*- c++ -*-
+/************************************************************************/
+/*                                                                      */
+/*      Copyright 2003 by Ullrich Koethe, B. Seppke, F. Heinrich        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_POINTOPERATORS_H
+#define VIGRA_MULTI_POINTOPERATORS_H
+
+#include "initimage.hxx"
+#include "copyimage.hxx"
+#include "transformimage.hxx"
+#include "combineimages.hxx"
+#include "inspectimage.hxx"
+#include "multi_array.hxx"
+#include "metaprogramming.hxx"
+#include "inspector_passes.hxx"
+
+
+
+namespace vigra
+{
+
+/** \addtogroup MultiPointoperators Point operators for multi-dimensional arrays.
+
+    Copy, transform, and inspect arbitrary dimensional arrays which are represented
+    by iterators compatible to \ref MultiIteratorPage. Note that are range is here
+    specified by a pair: an iterator referring to the first point of the array 
+    and a shape object specifying the size of the (rectangular) ROI.
+
+    <b>\#include</b> \<vigra/multi_pointoperators.hxx\><br/>
+    Namespace: vigra
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                    initMultiArray                    */
+/*                                                      */
+/********************************************************/
+
+template <class Iterator, class Shape, class Accessor, 
+          class VALUETYPE>
+inline void
+initMultiArrayImpl(Iterator s, Shape const & shape, Accessor a,  VALUETYPE const & v, MetaInt<0>)
+{
+    initLine(s, s + shape[0], a, v);
+}
+    
+template <class Iterator, class Shape, class Accessor, 
+          class VALUETYPE, int N>
+void
+initMultiArrayImpl(Iterator s, Shape const & shape, Accessor a,  
+                   VALUETYPE const & v, MetaInt<N>)
+{
+    Iterator send = s + shape[N];
+    for(; s < send; ++s)
+    {
+        initMultiArrayImpl(s.begin(), shape, a, v, MetaInt<N-1>());
+    }
+}
+    
+/** \brief Write a value to every element in a multi-dimensional array.
+
+    The initial value can either be a constant of appropriate type (compatible with 
+    the destination's value_type), or a functor with compatible result_type. These two 
+    cases are automatically distinguished when <tt>FunctorTraits<FUNCTOR>::isInitializer</tt>
+    yields <tt>VigraTrueType</tt>. Since the functor is passed by <tt>const</tt> reference, its 
+    <tt>operator()</tt> must be const, and its internal state may need to be <tt>mutable</tt>.
+    
+    <b> Declarations:</b>
+    
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T, class S, class VALUETYPE>
+        void
+        initMultiArray(MultiArrayView<N, T, S> s, VALUETYPE const & v);
+        
+        template <unsigned int N, class T, class S, class FUNCTOR>
+        void
+        initMultiArray(MultiArrayView<N, T, S> s, FUNCTOR const & f);
+    }
+    \endcode
+    
+    \deprecatedAPI{initMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class Iterator, class Shape, class Accessor, class VALUETYPE>
+        void
+        initMultiArray(Iterator s, Shape const & shape, Accessor a,  VALUETYPE const & v);
+
+        template <class Iterator, class Shape, class Accessor, class FUNCTOR>
+        void
+        initMultiArray(Iterator s, Shape const & shape, Accessor a,  FUNCTOR const & f);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class Iterator, class Shape, class Accessor, class VALUETYPE>
+        void
+        initMultiArray(triple<Iterator, Shape, Accessor> const & s, VALUETYPE const & v);
+
+
+        template <class Iterator, class Shape, class Accessor, class FUNCTOR>
+        void
+        initMultiArray(triple<Iterator, Shape, Accessor> const & s, FUNCTOR const & f);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/multi_pointoperators.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    MultiArray<3, unsigned int> array(Shape3(100, 200, 50));
+    
+    // make an array of all ones
+    initMultiArray(array, 1);
+    
+    // equivalent calls:
+    array = 1;
+    array.init(1);
+    
+    // fill the array with random numbers
+    #include <vigra/random.hxx> 
+    
+    initMultiArray(array, MersenneTwister());
+    \endcode
+
+    \deprecatedUsage{initMultiArray}
+    \code
+    MultiArray<3, int> array(Shape3(100, 200, 50));
+    
+    // make an array of all twos
+    vigra::initMultiArray(destMultiArrayRange(array), 2);
+    \endcode
+    <b> Required Interface:</b>
+    The function accepts either a value that is copied into every destination element: 
+    \code
+    MultiIterator begin;
+    
+    Accessor accessor;
+    VALUETYPE v;
+    
+    accessor.set(v, begin); 
+    \endcode
+    or a functor that is called (without argument) at every location,
+    and the result is written into the current element. Internally,
+    functors are recognized by the meta function 
+    <tt>FunctorTraits<FUNCTOR>::isInitializer</tt> yielding <tt>VigraTrueType</tt>.
+    Make sure that your functor correctly defines <tt>FunctorTraits</tt> because
+    otherwise the code will not compile.
+    \code
+    MultiIterator begin;    
+    Accessor accessor;
+    
+    FUNCTOR f;
+    assert(typeid(FunctorTraits<FUNCTOR>::isInitializer) == typeid(VigraTrueType));
+    
+    accessor.set(f(), begin); 
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void initMultiArray)
+
+template <class Iterator, class Shape, class Accessor, class VALUETYPE>
+inline void
+initMultiArray(Iterator s, Shape const & shape, Accessor a,  VALUETYPE const & v)
+{
+    initMultiArrayImpl(s, shape, a, v, MetaInt<Iterator::level>());
+}
+    
+template <class Iterator, class Shape, class Accessor, class VALUETYPE>
+inline void
+initMultiArray(triple<Iterator, Shape, Accessor> const & s, VALUETYPE const & v)
+{
+     initMultiArrayImpl(s.first, s.second, s.third, v, MetaInt<Iterator::level>());
+}
+
+template <unsigned int N, class T, class S, class VALUETYPE>
+inline void
+initMultiArray(MultiArrayView<N, T, S> s, VALUETYPE const & v)
+{
+    initMultiArray(destMultiArrayRange(s), v);
+}
+
+/********************************************************/
+/*                                                      */
+/*                  initMultiArrayBorder                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Write values to the specified border values in the array.
+
+    This functions is similar to \ref initMultiArray(), but it initializes only 
+    the array elements whose distance from any array border is at most \a border_width.
+    
+    <b> Declarations:</b>
+    
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T, class S, 
+                  class VALUETYPE>
+        void 
+        initMultiArrayBorder( MultiArrayView<N, T, S> array, 
+                              MultiArrayIndex border_width, VALUETYPE const & v);
+        
+        template <unsigned int N, class T, class S, 
+                  class FUNCTOR>
+        void 
+        initMultiArrayBorder( MultiArrayView<N, T, S> array, 
+                              MultiArrayIndex border_width, FUNCTOR const & v);
+    }
+    \endcode
+    
+    \deprecatedAPI{initMultiArrayBorder}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class Iterator, class Diff_type, class Accessor, 
+                  class VALUETYPE>
+        void
+        initMultiArrayBorder(Iterator upperleft, Diff_type shape, Accessor a,
+                             MultiArrayIndex border_width, VALUETYPE const & v);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class Iterator, class Diff_type, class Accessor, 
+                  class VALUETYPE>
+        inline void 
+        initMultiArrayBorder( triple<Iterator, Diff_type, Accessor> multiArray, 
+                              MultiArrayIndex border_width, VALUETYPE const & v);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/multi_pointoperators.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    MultiArray<3, unsigned int> array(Shape3(100, 200, 50));
+    
+    int border_width = 5;
+    
+    // init the array interior to 1, the border to 2
+    initMultiArray(array.subarray(Shape3(border_width), Shape3(-border_width)), 1);
+    initMultiArrayBorder(array, border_width, 2);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void initMultiArrayBorder)
+
+template <class Iterator, class Diff_type, class Accessor, 
+          class VALUETYPE>
+void
+initMultiArrayBorder(Iterator upperleft, Diff_type shape, Accessor a,
+                     MultiArrayIndex border_width, VALUETYPE const & v)
+{
+    Diff_type border(shape);
+    for(unsigned int dim=0; dim<shape.size(); dim++)
+    {
+        border[dim] = (border_width > shape[dim]) ? shape[dim] : border_width;
+    }
+
+    for(unsigned int dim=0; dim<shape.size(); dim++)
+    {
+        Diff_type  start(shape),
+                   offset(shape);
+        start = start-shape;
+        offset[dim]=border[dim];
+
+        initMultiArray(upperleft+start, offset, a, v);
+ 
+        start[dim]=shape[dim]-border[dim];
+        initMultiArray(upperleft+start, offset, a, v);
+    }
+}
+    
+template <class Iterator, class Diff_type, class Accessor, 
+          class VALUETYPE>
+inline void 
+initMultiArrayBorder( triple<Iterator, Diff_type, Accessor> multiArray, 
+                      MultiArrayIndex border_width, VALUETYPE const & v)
+{
+    initMultiArrayBorder(multiArray.first, multiArray.second, multiArray.third, border_width, v);
+}
+
+template <unsigned int N, class T, class S, 
+          class VALUETYPE>
+inline void 
+initMultiArrayBorder( MultiArrayView<N, T, S> array, 
+                      MultiArrayIndex border_width, VALUETYPE const & v)
+{
+    initMultiArrayBorder(destMultiArrayRange(array), border_width, v);
+}
+
+/********************************************************/
+/*                                                      */
+/*                    copyMultiArray                    */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor>
+void
+copyMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
+               DestIterator d, DestShape const & dshape, DestAccessor dest, MetaInt<0>)
+{
+    if(sshape[0] == 1)
+    {
+        initLine(d, d + dshape[0], dest, src(s));
+    }
+    else
+    {
+        copyLine(s, s + sshape[0], src, d, dest);
+    }
+}
+    
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor, int N>
+void
+copyMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
+                   DestIterator d, DestShape const & dshape, DestAccessor dest, MetaInt<N>)
+{
+    DestIterator dend = d + dshape[N];
+    if(sshape[N] == 1)
+    {
+        for(; d < dend; ++d)
+        {
+            copyMultiArrayImpl(s.begin(), sshape, src, d.begin(), dshape, dest, MetaInt<N-1>());
+        }
+    }
+    else
+    {
+        for(; d < dend; ++s, ++d)
+        {
+            copyMultiArrayImpl(s.begin(), sshape, src, d.begin(), dshape, dest, MetaInt<N-1>());
+        }
+    }
+}
+    
+/** \brief Copy a multi-dimensional array.
+
+    This function can be applied in two modes:
+    
+    <DL>
+    <DT><b>Standard Mode:</b>
+        <DD>If the source and destination arrays have the same size, 
+        the corresponding array elements are simply copied.
+        If necessary, type conversion takes place.
+    <DT><b>Expanding Mode:</b>
+        <DD>If the source array has length 1 along some (or even all) dimensions,
+        the source value at index 0 is used for all destination
+        elements in those dimensions. For example, if we have single row of data
+        (column length is 1), we can copy it into a 2D image of the same width:
+        The given row is automatically repeated for every row of the destination image.
+        Again, type conversion os performed if necessary.
+    </DL>
+        
+    The arrays must be represented by
+    iterators compatible with \ref vigra::MultiIterator, and the iteration range 
+    is specified by means of shape objects. If only the source shape is given
+    the destination array is assumed to have the same shape, and standard mode
+    is applied. If two shapes are given, the size of corresponding dimensions
+    must be either equal (standard copy), or the source length must be 1 
+    (expanding copy). 
+    
+    <b> Declarations:</b>
+    
+    <b>\#include</b> \<vigra/multi_pointoperators.hxx\><br>
+    Namespace: vigra
+    
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                  class T2, class S2>
+        void
+        copyMultiArray(MultiArrayView<N, T1, S1> const & source,
+                       MultiArrayView<N, T2, S2> dest);
+    }
+    \endcode
+    
+    \deprecatedAPI{copyMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        copyMultiArray(SrcIterator s, 
+                       SrcShape const & shape, SrcAccessor src,
+                       DestIterator d, DestAccessor dest);
+
+
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestShape, class DestAccessor>
+        void
+        copyMultiArray(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
+                       DestIterator d, DestShape const & dshape, DestAccessor dest);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src,
+                       pair<DestIterator, DestAccessor> const & dest);
+                       
+                       
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestShape, class DestAccessor>
+        void
+        copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src,
+                       triple<DestIterator, DestShape, DestAccessor> const & dest);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage - Standard Mode:</b>
+    
+    \code
+    MultiArray<3, int> src(Shape3(100, 200, 50)),
+                       dest(Shape3(100, 200, 50));
+    ...
+    
+    copyMultiArray(src, dest);
+    
+    // equivalent to
+    dest = src;
+    
+    // copy only the red channel (i.e. channl 0) of an RGB array
+    MultiArray<3, RGBValue<int> > rgb_src(Shape3(100, 200, 50));
+    
+    copyMultiArray(rgb_src.bindElementChannel(0), dest);
+    
+    // equivalent to 
+    dest = rgb_src.bindElementChannel(0);
+    \endcode
+
+    <b> Usage - Expanding Mode:</b>
+    
+    The source array is effectively only a 2D image (it has a 3D shape, but 'depth' is a
+    singleton dimension with length 1). Thus, the destination will contain 50 identical 
+    copies of this image:
+    
+    \code
+    MultiArray<3, int> src(Shape2(100, 200)),
+                       dest(Shape3(100, 200, 50));
+    ...
+    
+    copyMultiArray(src.insertSingletonDimension(2), dest);
+    
+    // create an RGB image with three identical color bands
+    MultiArray<3, RGBValue<int> > rgb_dest(Shape2(100, 200));
+    
+    copyMultiArray(src.insertSingletonDimension(2), rgb_dest.expandElements(2));
+    \endcode
+
+    \deprecatedUsage{copyMultiArray}
+    \code
+    typedef vigra::MultiArray<3, int> Array;
+    Array src(Array::size_type(100, 200, 50)),
+          dest(Array::size_type(100, 200, 50));
+    ...
+    
+    vigra::copyMultiArray(srcMultiArrayRange(src), destMultiArray(dest));
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    MultiIterator src_begin, dest_begin;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    dest_accessor.set(src_accessor(src_begin), dest_begin);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void copyMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+copyMultiArray(SrcIterator s, 
+               SrcShape const & shape, SrcAccessor src,
+               DestIterator d, DestAccessor dest)
+{    
+    copyMultiArrayImpl(s, shape, src, d, shape, dest, MetaInt<SrcIterator::level>());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor>
+void
+copyMultiArray(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
+               DestIterator d, DestShape const & dshape, DestAccessor dest)
+{    
+    vigra_precondition(sshape.size() == dshape.size(),
+        "copyMultiArray(): dimensionality of source and destination array differ");
+    for(unsigned int i=0; i<sshape.size(); ++i)
+        vigra_precondition(sshape[i] == 1 || sshape[i] == dshape[i],
+            "copyMultiArray(): mismatch between source and destination shapes:\n"
+            "length of each source dimension must either be 1 or equal to the corresponding "
+            "destination length.");
+    copyMultiArrayImpl(s, sshape, src, d, dshape, dest, MetaInt<SrcIterator::level>());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src,
+               pair<DestIterator, DestAccessor> const & dest)
+{
+    
+    copyMultiArray(src.first, src.second, src.third, dest.first, dest.second);
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor>
+inline void
+copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src,
+               triple<DestIterator, DestShape, DestAccessor> const & dest)
+{
+    
+    copyMultiArray(src.first, src.second, src.third, dest.first, dest.second, dest.third);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+copyMultiArray(MultiArrayView<N, T1, S1> const & source,
+               MultiArrayView<N, T2, S2> dest)
+{
+    for(int k=0; k<N; ++k)
+        vigra_precondition(source.shape(k) == dest.shape(k) || source.shape(k) == 1 || 1 == dest.shape(k),
+            "copyMultiArray(): shape mismatch between input and output.");
+    if(source.shape() == dest.shape())
+        copyMultiArray(srcMultiArrayRange(source), destMultiArray(dest));
+    else
+        copyMultiArray(srcMultiArrayRange(source), destMultiArrayRange(dest));
+}
+
+/********************************************************/
+/*                                                      */
+/*                 transformMultiArray                  */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+void
+transformMultiArrayReduceImpl(SrcIterator s, SrcShape const &, SrcAccessor src,
+               DestIterator d, DestShape const & dshape, DestAccessor dest, 
+               SrcShape const & reduceShape,
+               Functor const & ff, MetaInt<0>)
+{
+    DestIterator dend = d + dshape[0];
+    for(; d < dend; ++s.template dim<0>(), ++d)
+    {
+        Functor f = ff;
+        inspectMultiArray(s, reduceShape, src, f);
+        dest.set(f(), d);
+    }
+}
+    
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor, int N>
+void
+transformMultiArrayReduceImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
+                   DestIterator d, DestShape const & dshape, DestAccessor dest, 
+                   SrcShape const & reduceShape,
+                   Functor const & f, MetaInt<N>)
+{
+    DestIterator dend = d + dshape[N];
+    for(; d < dend; ++s.template dim<N>(), ++d)
+    {
+        transformMultiArrayReduceImpl(s, sshape, src, d.begin(), dshape, dest,
+                                      reduceShape, f, MetaInt<N-1>());
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+void
+transformMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
+               DestIterator d, DestShape const & dshape, DestAccessor dest, 
+               Functor const & f, VigraTrueType)
+{
+    // reduce mode
+    SrcShape reduceShape = sshape;
+    for(unsigned int i=0; i<dshape.size(); ++i)
+    {
+        vigra_precondition(dshape[i] == 1 || sshape[i] == dshape[i],
+            "transformMultiArray(): mismatch between source and destination shapes:\n"
+            "In 'reduce'-mode, the length of each destination dimension must either be 1\n"
+            "or equal to the corresponding source length.");
+        if(dshape[i] != 1)
+            reduceShape[i] = 1;
+    }
+    transformMultiArrayReduceImpl(s, sshape, src, d, dshape, dest, reduceShape,
+                                  f, MetaInt<SrcIterator::level>());
+}
+    
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+void
+transformMultiArrayExpandImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
+               DestIterator d, DestShape const & dshape, DestAccessor dest, 
+               Functor const & f, MetaInt<0>)
+{
+    if(sshape[0] == 1)
+    {
+        initLine(d, d + dshape[0], dest, f(src(s)));
+    }
+    else
+    {
+        transformLine(s, s + sshape[0], src, d, dest, f);
+    }
+}
+    
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor, int N>
+void
+transformMultiArrayExpandImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
+                   DestIterator d, DestShape const & dshape, DestAccessor dest, 
+                   Functor const & f, MetaInt<N>)
+{
+    DestIterator dend = d + dshape[N];
+    if(sshape[N] == 1)
+    {
+        for(; d < dend; ++d)
+        {
+            transformMultiArrayExpandImpl(s.begin(), sshape, src, d.begin(), dshape, dest,
+                                          f, MetaInt<N-1>());
+        }
+    }
+    else
+    {
+        for(; d < dend; ++s, ++d)
+        {
+            transformMultiArrayExpandImpl(s.begin(), sshape, src, d.begin(), dshape, dest,
+                                          f, MetaInt<N-1>());
+        }
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+void
+transformMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
+               DestIterator d, DestShape const & dshape, DestAccessor dest, 
+               Functor const & f, VigraFalseType)
+{
+    // expand mode
+    for(unsigned int i=0; i<sshape.size(); ++i)
+        vigra_precondition(sshape[i] == 1 || sshape[i] == dshape[i],
+            "transformMultiArray(): mismatch between source and destination shapes:\n"
+            "In 'expand'-mode, the length of each source dimension must either be 1\n"
+            "or equal to the corresponding destination length.");
+    transformMultiArrayExpandImpl(s, sshape, src, d, dshape, dest, 
+                                  f, MetaInt<SrcIterator::level>());
+}
+    
+/** \brief Transform a multi-dimensional array with a unary function or functor.
+
+    Note: The effect of this function can often be achieved in a simpler and
+    more readable way by means of \ref MultiMathModule "array experessions".
+    
+    This function can be applied in three modes:
+    
+    <DL>
+    <DT><b>Standard Mode:</b>
+        <DD>If the source and destination arrays have the same size, 
+        the transformation given by the functor is applied to every source
+        element and the result written into the corresponding destination element.
+        Unary functions, unary functors from the STL and the functors specifically 
+        defined in \ref TransformFunctor can be used in standard mode.
+        Creation of new functors is easiest by using \ref FunctorExpressions. 
+    <DT><b>Expanding Mode:</b>
+        <DD>If the source array has length 1 along some (or even all) dimensions,
+        the source value at index 0 is used for all destination
+        elements in those dimensions. In other words, the source index is not
+        incremented along these dimensions, but the transformation functor
+        is applied as usual. So, we can expand a small array (e.g. a single row of data,
+        column length is 1), into a larger one (e.g. a 2D image with the same width): 
+        the given values are simply reused as necessary (e.g. for every row of the 
+        destination image). The same functors as in standard mode can be applied.
+    <DT><b>Reducing Mode:</b>
+        <DD>If the destination array has length 1 along some (or even all) dimensions,
+        the source values in these dimensions are reduced to single values by means
+        of a suitable functor (e.g. \ref vigra::ReduceFunctor), which supports two 
+        function call operators: one
+        with a single argument to collect the values, and without argument to 
+        obtain the final (reduced) result. This behavior is a multi-dimensional
+        generalization of the C++ standard function <tt>std::accumulate()</tt>.
+    </DL>
+        
+    The arrays must be represented by MultiArrayViews. If source and destination shapes
+    match, standard mode is applied. If the shapes differ, the size of corresponding 
+    dimensions must either be equal, or the source length must be 1 
+    (expand mode), or the destination length must be 1 (reduce mode). However,
+    reduction and expansion cannot be executed at the same time, so the latter
+    conditions are mutual exclusive, even if they apply to different dimensions.
+    
+    <b> Declarations:</b>
+
+    <b>\#include</b> \<vigra/multi_pointoperators.hxx\><br>
+    Namespace: vigra
+    
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2, 
+                  class Functor>
+        void
+        transformMultiArray(MultiArrayView<N, T1, S1> const & source,
+                            MultiArrayView<N, T2, S2> dest, Functor const & f);
+    }
+    \endcode
+    
+    \deprecatedAPI{transformMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, 
+                  class Functor>
+        void
+        transformMultiArray(SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                            DestIterator d, DestAccessor dest, Functor const & f);
+
+
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestShape, class DestAccessor, 
+                  class Functor>
+        void
+        transformMultiArray(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
+                            DestIterator d, DestShape const & dshape, DestAccessor dest, 
+                            Functor const & f);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor, 
+                  class Functor>
+        void
+        transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src,
+                            pair<DestIterator, DestAccessor> const & dest, Functor const & f);
+
+
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestShape, class DestAccessor, 
+                  class Functor>
+        void
+        transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src,
+                            triple<DestIterator, DestShape, DestAccessor> const & dest, 
+                            Functor const & f)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage - Standard Mode:</b>
+
+    Source and destination array have the same size.
+    
+    \code
+    #include <cmath>         // for sqrt()
+
+    MultiArray<3, float>  src(Shape3(100, 200, 50)),
+                          dest(Shape3(100, 200, 50));
+    ...
+    
+    transformMultiArray(src, dest, &std::sqrt );
+    \endcode
+
+    <b> Usage - Expand Mode:</b>
+
+    The source array is effectively only a 2D image(it has a 3D shape, but depth is a singleton dimension 
+    with length 1). Thus, the destination will contain 50 identical copies of the transformed source image. 
+    
+    \code
+    #include <cmath>         // for sqrt()
+
+    MultiArray<3, float> src(Shape3(100, 200, 1)),
+                         dest(Shape3(100, 200, 50));
+    ...
+    
+    transformMultiArray(src, dest, &std::sqrt );
+    \endcode
+
+    <b> Usage - Reduce Mode:</b>
+
+    The destination array is effectively only 1D (it's width and height are singleton dimensions). 
+    Thus, it will contain accumulated data for every slice of the source volume
+    (or for every frame, if the source is interpreted as an image sequence).
+    In the example, we use the functor \ref vigra::FindAverage to calculate
+    the average gray value of every slice. 
+    
+    \code
+    MultiArray<3, float>  src(Shape3(100, 200, 50)),
+                          dest(Shape3(1, 1, 50));
+    ...
+    
+    transformMultiArray(src, dest,
+                        FindAverage<float>() );
+    \endcode
+    
+    Note that the functor must define the appropriate traits described below in order to be 
+    recognized as a reduce functor. This is most easily achieved by deriving from 
+    <tt>UnaryReduceFunctorTag</tt> (see \ref vigra::FunctorTraits).
+
+    \deprecatedUsage{transformMultiArray}
+    \code
+    #include <cmath>         // for sqrt()
+
+    typedef vigra::MultiArray<3, float> Array;
+    Array src(Shape3(100, 200, 50)),
+          dest(Shape3(100, 200, 50));
+    ...
+    
+    vigra::transformMultiArray(srcMultiArrayRange(src),
+                               destMultiArray(dest),
+                               (float(*)(float))&std::sqrt );
+
+    \endcode
+    \deprecatedEnd
+
+    <b> Required Interface:</b>
+
+    In standard and expand mode, the functor must be a model of UnaryFunction
+    (i.e. support one-argument function call which accepts values of type
+    <tt>T1</tt> and a return value that is convertible into <tt>T2</tt>.
+    
+    In reduce mode, it must be a model of UnaryAnalyser (i.e. support function call
+    with one argument and no return value <tt>functor(arg)</tt>) and Initializer
+    (i.e. support function call with no argument, but return value 
+    <tt>res = functor()</tt>). Internally, such functors are recognized by the 
+    meta functions <tt>FunctorTraits<FUNCTOR>::isUnaryAnalyser</tt> and
+    <tt>FunctorTraits<FUNCTOR>::isInitializer</tt> which must both yield 
+    <tt>VigraTrueType</tt>. Make sure that your functor correctly defines 
+    <tt>FunctorTraits</tt> because otherwise reduce mode will not work. 
+    This is most easily achieved by deriving the functor from 
+    <tt>UnaryReduceFunctorTag</tt> (see \ref vigra::FunctorTraits).
+    In addition, the functor must be copy constructible in order to start each reduction
+    with a fresh functor.
+    
+    \see TransformFunctor, MultiMathModule, \ref FunctorExpressions
+*/
+doxygen_overloaded_function(template <...> void transformMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, 
+          class Functor>
+inline void
+transformMultiArray(SrcIterator s, SrcShape const & shape, SrcAccessor src,
+                    DestIterator d, DestAccessor dest, Functor const & f)
+{    
+    transformMultiArrayExpandImpl(s, shape, src, d, shape, dest, 
+                                  f, MetaInt<SrcIterator::level>());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+void
+transformMultiArray(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
+               DestIterator d, DestShape const & dshape, DestAccessor dest, 
+               Functor const & f)
+{    
+    vigra_precondition(sshape.size() == dshape.size(),
+        "transformMultiArray(): dimensionality of source and destination array differ");
+    typedef FunctorTraits<Functor> FT;
+    typedef typename 
+        And<typename FT::isInitializer, typename FT::isUnaryAnalyser>::result
+        isAnalyserInitializer;
+    transformMultiArrayImpl(s, sshape, src, d, dshape, dest, 
+                            f, isAnalyserInitializer());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor, 
+          class Functor>
+inline void
+transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src,
+                    pair<DestIterator, DestAccessor> const & dest, Functor const & f)
+{
+    
+    transformMultiArray(src.first, src.second, src.third, 
+                        dest.first, dest.second, f);
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+inline void
+transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & src,
+               triple<DestIterator, DestShape, DestAccessor> const & dest, 
+               Functor const & f)
+{
+    transformMultiArray(src.first, src.second, src.third, 
+                        dest.first, dest.second, dest.third, f);
+}
+
+template <unsigned int N, class T1, class S1,
+          class T2, class S2, 
+          class Functor>
+inline void
+transformMultiArrayImpl(MultiArrayView<N, T1, S1> const & source,
+                        MultiArrayView<N, T2, S2> dest,
+                        Functor const & f, VigraFalseType)
+{
+    if(source.shape() == dest.shape())
+        transformMultiArray(srcMultiArrayRange(source), destMultiArray(dest), f);
+    else
+        transformMultiArray(srcMultiArrayRange(source), destMultiArrayRange(dest), f);
+}
+
+template <unsigned int N, class T1, class S1,
+          class T2, class S2, 
+          class Functor>
+inline void
+transformMultiArrayImpl(MultiArrayView<N, T1, S1> const & source,
+                        MultiArrayView<N, T2, S2> dest,
+                        Functor const & f, VigraTrueType)
+{
+    transformMultiArray(srcMultiArrayRange(source), destMultiArrayRange(dest), f);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2, 
+          class Functor>
+inline void
+transformMultiArray(MultiArrayView<N, T1, S1> const & source,
+                    MultiArrayView<N, T2, S2> dest, Functor const & f)
+{
+    for(int k=0; k<N; ++k)
+        vigra_precondition(source.shape(k) == dest.shape(k) || source.shape(k) == 1 || 1 == dest.shape(k),
+            "transformMultiArray(): shape mismatch between input and output.");
+
+    typedef FunctorTraits<Functor> FT;
+    typedef typename 
+        And<typename FT::isInitializer, typename FT::isUnaryAnalyser>::result
+        isAnalyserInitializer;
+    transformMultiArrayImpl(source, dest, f, isAnalyserInitializer());
+}
+
+/********************************************************/
+/*                                                      */
+/*                combineTwoMultiArrays                 */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+void
+combineTwoMultiArraysReduceImpl(
+               SrcIterator1 s1, SrcShape const & , SrcAccessor1 src1,
+               SrcIterator2 s2, SrcAccessor2 src2,
+               DestIterator d,  DestShape const & dshape, DestAccessor dest, 
+               SrcShape const & reduceShape,
+               Functor const & ff, MetaInt<0>)
+{
+    DestIterator dend = d + dshape[0];
+    for(; d < dend; ++s1.template dim<0>(), ++s2.template dim<0>(), ++d)
+    {
+        Functor f = ff;
+        inspectTwoMultiArrays(s1, reduceShape, src1, s2, src2, f);
+        dest.set(f(), d);
+    }
+}
+    
+template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor, int N>
+void
+combineTwoMultiArraysReduceImpl(
+               SrcIterator1 s1, SrcShape const & sshape, SrcAccessor1 src1,
+               SrcIterator2 s2, SrcAccessor2 src2,
+               DestIterator d,  DestShape const & dshape, DestAccessor dest, 
+               SrcShape const & reduceShape,
+               Functor const & f, MetaInt<N>)
+{
+    DestIterator dend = d + dshape[N];
+    for(; d < dend; ++s1.template dim<N>(), ++s2.template dim<N>(), ++d)
+    {
+        combineTwoMultiArraysReduceImpl(s1, sshape, src1, s2, src2, 
+                                        d.begin(), dshape, dest,
+                                        reduceShape, f, MetaInt<N-1>());
+    }
+}
+
+template <class SrcIterator1, class SrcShape1, class SrcAccessor1,
+          class SrcIterator2, class SrcShape2, class SrcAccessor2,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+void
+combineTwoMultiArraysImpl(
+               SrcIterator1 s1, SrcShape1 const & sshape1, SrcAccessor1 src1,
+               SrcIterator2 s2, SrcShape2 const & sshape2, SrcAccessor2 src2,
+               DestIterator d, DestShape const & dshape, DestAccessor dest, 
+               Functor const & f, VigraTrueType)
+{
+    // reduce mode
+    SrcShape1 reduceShape = sshape1;
+    for(unsigned int i=0; i<dshape.size(); ++i)
+    {
+        vigra_precondition(sshape1[i] == sshape2[i] && 
+                           (dshape[i] == 1 || sshape1[i] == dshape[i]),
+            "combineTwoMultiArrays(): mismatch between source and destination shapes:\n"
+            "In 'reduce'-mode, the two source shapes must be equal, and\n"
+            "the length of each destination dimension must either be 1\n"
+            "or equal to the corresponding source length.");
+        if(dshape[i] != 1)
+            reduceShape[i] = 1;
+    }
+    combineTwoMultiArraysReduceImpl(s1, sshape1, src1, s2, src2, 
+                                    d, dshape, dest, reduceShape,
+                                    f, MetaInt<SrcIterator1::level>());
+}
+    
+template <class SrcIterator1, class SrcShape1, class SrcAccessor1,
+          class SrcIterator2, class SrcShape2, class SrcAccessor2,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+void
+combineTwoMultiArraysExpandImpl(
+               SrcIterator1 s1, SrcShape1 const & sshape1, SrcAccessor1 src1,
+               SrcIterator2 s2, SrcShape2 const & sshape2, SrcAccessor2 src2,
+               DestIterator d, DestShape const & dshape, DestAccessor dest, 
+               Functor const & f, MetaInt<0>)
+{
+    DestIterator dend = d + dshape[0];
+    if(sshape1[0] == 1 && sshape2[0] == 1)
+    {
+        initLine(d, dend, dest, f(src1(s1), src2(s2)));
+    }
+    else if(sshape1[0] == 1)
+    {
+        typename SrcAccessor1::value_type sv1 = src1(s1);
+        for(; d < dend; ++d, ++s2)
+            dest.set(f(sv1, src2(s2)), d);
+    }
+    else if(sshape2[0] == 1)
+    {
+        typename SrcAccessor2::value_type sv2 = src2(s2);
+        for(; d < dend; ++d, ++s1)
+            dest.set(f(src1(s1), sv2), d);
+    }
+    else
+    {
+        combineTwoLines(s1, s1 + sshape1[0], src1, s2, src2, d, dest, f);
+    }
+}
+    
+template <class SrcIterator1, class SrcShape1, class SrcAccessor1,
+          class SrcIterator2, class SrcShape2, class SrcAccessor2,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor, int N>
+void
+combineTwoMultiArraysExpandImpl(
+               SrcIterator1 s1, SrcShape1 const & sshape1, SrcAccessor1 src1,
+               SrcIterator2 s2, SrcShape2 const & sshape2, SrcAccessor2 src2,
+               DestIterator d, DestShape const & dshape, DestAccessor dest, 
+               Functor const & f, MetaInt<N>)
+{
+    DestIterator dend = d + dshape[N];
+    int s1inc = sshape1[N] == 1
+                    ? 0 
+                    : 1;
+    int s2inc = sshape2[N] == 1
+                    ? 0 
+                    : 1;
+    for(; d < dend; ++d, s1 += s1inc, s2 += s2inc)
+    {
+        combineTwoMultiArraysExpandImpl(s1.begin(), sshape1, src1, 
+                                        s2.begin(), sshape2, src2, 
+                                        d.begin(), dshape, dest,
+                                        f, MetaInt<N-1>());
+    }
+}
+
+template <class SrcIterator1, class SrcShape1, class SrcAccessor1,
+          class SrcIterator2, class SrcShape2, class SrcAccessor2,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+void
+combineTwoMultiArraysImpl(
+               SrcIterator1 s1, SrcShape1 const & sshape1, SrcAccessor1 src1,
+               SrcIterator2 s2, SrcShape2 const & sshape2, SrcAccessor2 src2,
+               DestIterator d, DestShape const & dshape, DestAccessor dest, 
+               Functor const & f, VigraFalseType)
+{
+    // expand mode
+    for(unsigned int i=0; i<sshape1.size(); ++i)
+        vigra_precondition((sshape1[i] == 1 || sshape1[i] == dshape[i]) &&
+                           (sshape2[i] == 1 || sshape2[i] == dshape[i]),
+            "combineTwoMultiArrays(): mismatch between source and destination shapes:\n"
+            "In 'expand'-mode, the length of each source dimension must either be 1\n"
+            "or equal to the corresponding destination length.");
+    combineTwoMultiArraysExpandImpl(s1, sshape1, src1, s2, sshape2, src2, 
+                                    d, dshape, dest, 
+                                    f, MetaInt<SrcIterator1::level>());
+}
+
+/** \brief Combine two multi-dimensional arrays into one using a binary function or functor.
+
+    Note: The effect of this function can often be achieved in a simpler and
+    more readable way by means of \ref MultiMathModule "array experessions".
+    
+    This function can be applied in three modes:
+    
+    <DL>
+    <DT><b>Standard Mode:</b>
+        <DD>If the source and destination arrays have the same size, 
+        the transformation given by the functor is applied to every pair of
+        corresponding source elements and the result written into the corresponding 
+        destination element.
+        Binary functions, binary functors from the STL and the functors specifically 
+        defined in \ref CombineFunctor can be used in standard mode.
+        Creation of new functors is easiest by using \ref FunctorExpressions. 
+    <DT><b>Expanding Mode:</b>
+        <DD>If the source arrays have length 1 along some (or even all) dimensions,
+        the source values at index 0 are used for all destination
+        elements in those dimensions. In other words, the source index is not
+        incremented along those dimensions, but the transformation functor
+        is applied as usual. So, we can expand small arrays (e.g. a single row of data,
+        column length is 1), into larger ones (e.g. a 2D image with the same width): 
+        the given values are simply reused as necessary (e.g. for every row of the 
+        destination image). It is not even necessary that the source array shapes
+        are equal. For example, we can combine a small array with one that
+        hase the same size as the destination array. 
+        The same functors as in standard mode can be applied.
+    <DT><b>Reducing Mode:</b>
+        <DD>If the destination array has length 1 along some (or even all) dimensions,
+        the source values in these dimensions are reduced to single values by means
+        of a suitable functor which supports two function call operators: one
+        with two arguments to collect the values, and one without argument to 
+        obtain the final (reduced) result. This behavior is a multi-dimensional
+        generalization of the C++ standard function <tt>std::accumulate()</tt>.
+    </DL>
+        
+    The arrays must be represented by MultiArrayViews. If all shapes are identical, 
+    standard mode is applied. If the shapes differ, the size of corresponding dimensions
+    must either be equal, or the length of this dimension must be 1 in one or both source 
+    arrays (expand mode), or the destination length must be 1 (reduce mode). However,
+    reduction and expansion cannot be executed at the same time, so the latter
+    conditions are mutual exclusive, even if they apply to different dimensions.
+    
+    <b> Declarations:</b>
+    
+    <b>\#include</b> \<vigra/multi_pointoperators.hxx\><br>
+    Namespace: vigra
+    
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T11, class S11,
+                                  class T12, class S12,
+                                  class T2, class S2, 
+                  class Functor>
+        void
+        combineTwoMultiArrays(MultiArrayView<N, T11, S11> const & source1,
+                              MultiArrayView<N, T12, S12> const & source2,
+                              MultiArrayView<N, T2, S2> dest, 
+                              Functor const & f);
+    }
+    \endcode
+    
+    \deprecatedAPI{combineTwoMultiArrays}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+                  class SrcIterator2, class SrcAccessor2,
+                  class DestIterator, class DestAccessor, 
+                  class Functor>
+        void combineTwoMultiArrays(
+                       SrcIterator1 s1, SrcShape const & shape, SrcAccessor1 src1,
+                       SrcIterator2 s2, SrcAccessor2 src2,
+                       DestIterator d, DestAccessor dest, Functor const & f);
+
+
+        template <class SrcIterator1, class SrcShape1, class SrcAccessor1,
+                  class SrcIterator2, class SrcShape2, class SrcAccessor2,
+                  class DestIterator, class DestShape, class DestAccessor, 
+                  class Functor>
+        void combineTwoMultiArrays(
+                       SrcIterator1 s1, SrcShape1 const & sshape1, SrcAccessor1 src1,
+                       SrcIterator2 s2, SrcShape2 const & sshape2, SrcAccessor2 src2,
+                       DestIterator d, DestShape const & dshape, DestAccessor dest, 
+                       Functor const & f);
+            }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+                  class SrcIterator2, class SrcAccessor2,
+                  class DestIterator, class DestAccessor, class Functor>
+        void combineTwoMultiArrays(
+                       triple<SrcIterator1, SrcShape, SrcAccessor1> const & src1,
+                       pair<SrcIterator2, SrcAccessor2> const & src2,
+                       pair<DestIterator, DestAccessor> const & dest, Functor const & f);
+
+
+        template <class SrcIterator1, class SrcShape1, class SrcAccessor1,
+                  class SrcIterator2, class SrcShape2, class SrcAccessor2,
+                  class DestIterator, class DestShape, class DestAccessor, 
+                  class Functor>
+        void combineTwoMultiArrays(
+                       triple<SrcIterator1, SrcShape1, SrcAccessor1> const & src1,
+                       triple<SrcIterator2, SrcShape2, SrcAccessor2> const & src2,
+                       triple<DestIterator, DestShape, DestAccessor> const & dest, 
+                       Functor const & f);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage - Standard Mode:</b>
+    
+    Source and destination arrays have the same size.
+    
+    \code
+    #include <functional>     // for std::plus
+
+    MultiArray<3, int>  src1(Shape3(100, 200, 50)),
+                        src2(Shape3(100, 200, 50)),
+                        dest(Shape3(100, 200, 50));
+    ...
+    
+    combineTwoMultiArrays(src1, src2, dest,  
+                          std::plus<int>());
+    \endcode
+    
+    <b> Usage - Expand Mode:</b>
+
+    One source array is effectively only a 2D image (it has depth 1). This image will be added
+    to every slice of the other source array, and the result is written into the 
+    corresponding destination slice. 
+    
+    \code
+    #include <functional>     // for std::plus
+
+    MultiArray<3, int> src1(Shape3(100, 200, 1)),
+                       src2(Shape3(100, 200, 50)),
+                       dest(Shape3(100, 200, 50));
+    ...
+    
+    combineTwoMultiArrays(src1, src2, dest,  
+                          std::plus<int>());
+    \endcode
+
+    <b> Usage - Reduce Mode:</b>
+
+    The destination array is only 1D (it's width and height are singleton dimensions). 
+    Thus, it will contain accumulated data for every slice of the source volumes
+    (or for every frame, if the sources are interpreted as image sequences).
+    In the example, we use \ref vigra::ReduceFunctor together with a functor 
+    expression (see \ref FunctorExpressions) to calculate the total absolute difference 
+    of the gray values in every pair of source slices.
+    
+    \code
+    #include <vigra/functorexpression.hxx>
+    using namespace vigra::functor;
+        
+    MultiArray<3, int> src1(Shape3(100, 200, 50)),
+                       src2(Shape3(100, 200, 50)),
+                       dest(Shape3(1, 1, 50));
+    ...
+    
+    combineTwoMultiArrays(src1, src2, dest,  
+                          reduceFunctor(Arg1() + abs(Arg2() - Arg3()), 0) );
+                          // Arg1() is the sum accumulated so far, initialized with 0
+    \endcode
+
+    Note that the functor must define the appropriate traits described below in order to be 
+    recognized as a reduce functor. This is most easily achieved by deriving from 
+    <tt>BinaryReduceFunctorTag</tt> (see \ref vigra::FunctorTraits).
+
+    \deprecatedUsage{combineTwoMultiArrays}
+    \code
+    #include <functional>     // for std::plus
+
+    typedef vigra::MultiArray<3, int> Array;
+    Array src1(Shape3(100, 200, 50)),
+          src2(Shape3(100, 200, 50)),
+          dest(Shape3(100, 200, 50));
+    ...
+    
+    vigra::combineTwoMultiArrays(
+                srcMultiArrayRange(src1), 
+                srcMultiArray(src2), 
+                destMultiArray(dest),  
+                std::plus<int>());
+    \endcode
+    \deprecatedEnd
+    
+    <b> Required Interface:</b>
+    
+    In standard and expand mode, the functor must be a model of BinaryFunction
+    (i.e. support function call with two arguments and a return value which is convertible 
+    into <tt>T2</tt>:  <tt>T2 res = functor(arg1, arg2)</tt>):
+    
+    In reduce mode, it must be a model of BinaryAnalyser (i.e. support function call
+    with two arguments and no return value <tt>functor(arg1, arg2)</tt>) and Initializer
+    (i.e. support function call with no argument, but return value 
+    <tt>res = functor()</tt>). Internally, such functors are recognized by the 
+    meta functions <tt>FunctorTraits<FUNCTOR>::isBinaryAnalyser</tt> and
+    <tt>FunctorTraits<FUNCTOR>::isInitializer</tt> which must both yield 
+    <tt>VigraTrueType</tt>. Make sure that your functor correctly defines 
+    <tt>FunctorTraits</tt> because otherwise reduce mode will not work. 
+    This is most easily achieved by deriving the functor from 
+    <tt>BinaryReduceFunctorTag</tt> (see \ref vigra::FunctorTraits).
+    In addition, the functor must be copy constructible in order to start each reduction
+    with a fresh functor.
+    
+    \see TransformFunctor, MultiMathModule, \ref FunctorExpressions
+*/
+doxygen_overloaded_function(template <...> void combineTwoMultiArrays)
+
+template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class DestIterator, class DestAccessor, 
+          class Functor>
+inline void
+combineTwoMultiArrays(SrcIterator1 s1, SrcShape const & shape, SrcAccessor1 src1,
+               SrcIterator2 s2, SrcAccessor2 src2,
+               DestIterator d, DestAccessor dest, Functor const & f)
+{    
+    combineTwoMultiArraysExpandImpl(s1, shape, src1, s2, shape, src2, d, shape, dest, f, 
+                                    MetaInt<SrcIterator1::level>());
+}
+
+template <class SrcIterator1, class SrcShape1, class SrcAccessor1,
+          class SrcIterator2, class SrcShape2, class SrcAccessor2,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+void
+combineTwoMultiArrays(
+               SrcIterator1 s1, SrcShape1 const & sshape1, SrcAccessor1 src1,
+               SrcIterator2 s2, SrcShape2 const & sshape2, SrcAccessor2 src2,
+               DestIterator d, DestShape const & dshape, DestAccessor dest, 
+               Functor const & f)
+{    
+    vigra_precondition(sshape1.size() == dshape.size() && sshape2.size() == dshape.size(),
+        "combineTwoMultiArrays(): dimensionality of source and destination arrays differ");
+    
+    typedef FunctorTraits<Functor> FT;
+    typedef typename 
+        And<typename FT::isInitializer, typename FT::isBinaryAnalyser>::result
+        isAnalyserInitializer;
+    combineTwoMultiArraysImpl(s1, sshape1, src1, s2, sshape2, src2, d, dshape, dest, 
+                              f, isAnalyserInitializer());
+}
+
+template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class DestIterator, class DestAccessor, class Functor>
+inline void
+combineTwoMultiArrays(triple<SrcIterator1, SrcShape, SrcAccessor1> const & src1,
+                      pair<SrcIterator2, SrcAccessor2> const & src2,
+                      pair<DestIterator, DestAccessor> const & dest, 
+                      Functor const & f)
+{
+    
+    combineTwoMultiArrays(
+           src1.first, src1.second, src1.third, 
+           src2.first, src2.second, dest.first, dest.second, f);
+}
+
+template <class SrcIterator1, class SrcShape1, class SrcAccessor1,
+          class SrcIterator2, class SrcShape2, class SrcAccessor2,
+          class DestIterator, class DestShape, class DestAccessor, 
+          class Functor>
+inline void
+combineTwoMultiArrays(triple<SrcIterator1, SrcShape1, SrcAccessor1> const & src1,
+                      triple<SrcIterator2, SrcShape2, SrcAccessor2> const & src2,
+                      triple<DestIterator, DestShape, DestAccessor> const & dest, 
+                      Functor const & f)
+{
+    combineTwoMultiArrays(src1.first, src1.second, src1.third, 
+                          src2.first, src2.second, src2.third, 
+                          dest.first, dest.second, dest.third, f);
+}
+
+template <unsigned int N, class T11, class S11,
+                          class T12, class S12,
+                          class T2, class S2, 
+          class Functor>
+inline void
+combineTwoMultiArraysImpl(MultiArrayView<N, T11, S11> const & source1,
+                          MultiArrayView<N, T12, S12> const & source2,
+                          MultiArrayView<N, T2, S2> dest, 
+                          Functor const & f, VigraFalseType)
+{
+    
+    if(source1.shape() == source2.shape() && source1.shape() == dest.shape())
+        combineTwoMultiArrays(srcMultiArrayRange(source1), 
+                              srcMultiArray(source2), destMultiArray(dest), f);
+    else
+        combineTwoMultiArrays(srcMultiArrayRange(source1), 
+                              srcMultiArrayRange(source2), 
+                              destMultiArrayRange(dest), f);
+}
+
+template <unsigned int N, class T11, class S11,
+                          class T12, class S12,
+                          class T2, class S2, 
+          class Functor>
+inline void
+combineTwoMultiArraysImpl(MultiArrayView<N, T11, S11> const & source1,
+                          MultiArrayView<N, T12, S12> const & source2,
+                          MultiArrayView<N, T2, S2> dest, 
+                          Functor const & f, VigraTrueType)
+{
+    
+    combineTwoMultiArrays(srcMultiArrayRange(source1), 
+                          srcMultiArrayRange(source2), 
+                          destMultiArrayRange(dest), f);
+}
+
+template <unsigned int N, class T11, class S11,
+                          class T12, class S12,
+                          class T2, class S2, 
+          class Functor>
+inline void
+combineTwoMultiArrays(MultiArrayView<N, T11, S11> const & source1,
+                      MultiArrayView<N, T12, S12> const & source2,
+                      MultiArrayView<N, T2, S2> dest, 
+                      Functor const & f)
+{
+    for(int k=0; k<N; ++k)
+        vigra_precondition((source1.shape(k) == source2.shape(k) || source1.shape(k) == 1 || 1 == source2.shape(k)) &&
+                           (source1.shape(k) == dest.shape(k) || source1.shape(k) == 1 || 1 == dest.shape(k)),
+            "combineTwoMultiArrays(): shape mismatch between inputs and/or output.");
+
+    typedef FunctorTraits<Functor> FT;
+    typedef typename 
+        And<typename FT::isInitializer, typename FT::isBinaryAnalyser>::result
+        isAnalyserInitializer;
+    combineTwoMultiArraysImpl(source1, source2, dest, f, isAnalyserInitializer());
+}
+
+/********************************************************/
+/*                                                      */
+/*               combineThreeMultiArrays                */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class SrcIterator3, class SrcAccessor3,
+          class DestIterator, class DestAccessor, 
+          class Functor>
+inline void
+combineThreeMultiArraysImpl(SrcIterator1 s1, SrcShape const & shape, SrcAccessor1 src1,
+               SrcIterator2 s2, SrcAccessor2 src2,
+               SrcIterator3 s3, SrcAccessor3 src3,
+               DestIterator d, DestAccessor dest, Functor const & f, MetaInt<0>)
+{
+    combineThreeLines(s1, s1 + shape[0], src1, s2, src2, s3, src3, d, dest, f);
+}
+    
+template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class SrcIterator3, class SrcAccessor3,
+          class DestIterator, class DestAccessor, 
+          class Functor, int N>
+void
+combineThreeMultiArraysImpl(SrcIterator1 s1, SrcShape const & shape, SrcAccessor1 src1,
+               SrcIterator2 s2, SrcAccessor2 src2,
+               SrcIterator3 s3, SrcAccessor3 src3,
+               DestIterator d, DestAccessor dest, 
+                   Functor const & f, MetaInt<N>)
+{
+    SrcIterator1 s1end = s1 + shape[N];
+    for(; s1 < s1end; ++s1, ++s2, ++s3, ++d)
+    {
+        combineThreeMultiArraysImpl(s1.begin(), shape, src1, 
+                                  s2.begin(), src2, s3.begin(), src3, d.begin(), dest, 
+                                  f, MetaInt<N-1>());
+    }
+}
+    
+    
+/** \brief Combine three multi-dimensional arrays into one using a 
+           ternary function or functor.
+
+    Note: The effect of this function can often be achieved in a simpler and
+    more readable way by means of \ref MultiMathModule "array experessions".
+    
+    Except for the fact that it operates on three input arrays, this function is
+    identical to the standard mode of \ref combineTwoMultiArrays() (reduce and expand 
+    modes are not supported).
+    
+    <b> Declarations:</b>
+    
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T11, class S11,
+                                  class T12, class S12, 
+                                  class T13, class S13,
+                                  class T2, class S2, 
+                  class Functor>
+        void
+        combineThreeMultiArrays(MultiArrayView<N, T11, S11> const & source1,
+                                MultiArrayView<N, T12, S12> const & source2,
+                                MultiArrayView<N, T13, S13> const & source3,
+                                MultiArrayView<N, T2, S2> dest,
+                                Functor const & f);
+    }
+    \endcode
+    
+    \deprecatedAPI{combineThreeMultiArrays}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+                  class SrcIterator2, class SrcAccessor2,
+                  class SrcIterator3, class SrcAccessor3,
+                  class DestIterator, class DestAccessor, 
+                  class Functor>
+        void
+        combineThreeMultiArrays(SrcIterator1 s1, SrcShape const & shape, SrcAccessor1 src1,
+                       SrcIterator2 s2, SrcAccessor2 src2,
+                       SrcIterator3 s3, SrcAccessor3 src3,
+                       DestIterator d, DestAccessor dest, Functor const & f);
+                    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+                  class SrcIterator2, class SrcAccessor2,
+                  class SrcIterator3, class SrcAccessor3,
+                  class DestIterator, class DestAccessor, 
+                  class Functor>
+        inline void
+        combineThreeMultiArrays(triple<SrcIterator1, SrcShape, SrcAccessor1> const & src1,
+                       pair<SrcIterator2, SrcAccessor2> const & src2,
+                       pair<SrcIterator3, SrcAccessor3> const & src3,
+                       pair<DestIterator, DestAccessor> const & dest, Functor const & f);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/multi_pointoperators.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    #include <vigra/functorexpression.hxx>
+    
+    MultiArray<3, int> src1(Shape3(100, 200, 50)),
+                       src2(Shape3(100, 200, 50)),
+                       src3(Shape3(100, 200, 50)),
+                       dest(Shape3(100, 200, 50));
+    ...
+    
+    using namespace vigra::functor; // activate VIGRA's lambda library
+    
+    combineThreeMultiArrays(src1, src2, src3, dest,  
+                            Arg1()*exp(-abs(Arg2()-Arg3())));
+    \endcode
+    
+    \deprecatedUsage{combineThreeMultiArrays}
+    \code
+    #include <functional>     // for plus
+
+    typedef vigra::MultiArray<3, int> Array;
+    Array src1(Shape3(100, 200, 50)),
+          src2(Shape3(100, 200, 50)),
+          src3(Shape3(100, 200, 50)),
+          dest(Shape3(100, 200, 50));
+    ...
+    
+    vigra::combineThreeMultiArrays(
+                srcMultiArrayRange(src1), 
+                srcMultiArray(src2), 
+                srcMultiArray(src3), 
+                destMultiArray(dest),  
+                SomeThreeArgumentFunctor());
+    \endcode
+    \deprecatedEnd
+    
+    \see TransformFunctor, MultiMathModule, \ref FunctorExpressions
+*/
+doxygen_overloaded_function(template <...> void combineThreeMultiArrays)
+
+template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class SrcIterator3, class SrcAccessor3,
+          class DestIterator, class DestAccessor, 
+          class Functor>
+inline void
+combineThreeMultiArrays(SrcIterator1 s1, SrcShape const & shape, SrcAccessor1 src1,
+               SrcIterator2 s2, SrcAccessor2 src2,
+               SrcIterator3 s3, SrcAccessor3 src3,
+               DestIterator d, DestAccessor dest, Functor const & f)
+{    
+    combineThreeMultiArraysImpl(s1, shape, src1, s2, src2, s3, src3, d, dest, f, 
+                              MetaInt<SrcIterator1::level>());
+}
+
+template <class SrcIterator1, class SrcShape, class SrcAccessor1,
+          class SrcIterator2, class SrcAccessor2,
+          class SrcIterator3, class SrcAccessor3,
+          class DestIterator, class DestAccessor, 
+          class Functor>
+inline void
+combineThreeMultiArrays(triple<SrcIterator1, SrcShape, SrcAccessor1> const & src1,
+                        pair<SrcIterator2, SrcAccessor2> const & src2,
+                        pair<SrcIterator3, SrcAccessor3> const & src3,
+                        pair<DestIterator, DestAccessor> const & dest, Functor const & f)
+{
+    
+    combineThreeMultiArrays(
+           src1.first, src1.second, src1.third, 
+           src2.first, src2.second, src3.first, src3.second, dest.first, dest.second, f);
+}
+
+template <unsigned int N, class T11, class S11,
+                          class T12, class S12, 
+                          class T13, class S13,
+                          class T2, class S2, 
+          class Functor>
+inline void
+combineThreeMultiArrays(MultiArrayView<N, T11, S11> const & source1,
+                        MultiArrayView<N, T12, S12> const & source2,
+                        MultiArrayView<N, T13, S13> const & source3,
+                        MultiArrayView<N, T2, S2> dest, Functor const & f)
+{
+    vigra_precondition(source1.shape() == source2.shape() && source1.shape() == source3.shape() && source1.shape() == dest.shape(),
+        "combineThreeMultiArrays(): shape mismatch between inputs and/or output.");
+    
+    combineThreeMultiArrays(
+           srcMultiArrayRange(source1), 
+           srcMultiArray(source2), srcMultiArray(source3), destMultiArray(dest), f);
+}
+
+/********************************************************/
+/*                                                      */
+/*                  inspectMultiArray                   */
+/*                                                      */
+/********************************************************/
+
+template <class Iterator, class Shape, class Accessor, class Functor>
+inline void
+inspectMultiArrayImpl(Iterator s, Shape const & shape, Accessor a,  Functor & f, MetaInt<0>)
+{
+    inspectLine(s, s + shape[0], a, f);
+}
+    
+template <class Iterator, class Shape, class Accessor, class Functor, int N>
+void
+inspectMultiArrayImpl(Iterator s, Shape const & shape, Accessor a,  Functor & f, MetaInt<N>)
+{
+    Iterator send = s + shape[N];
+    for(; s < send; ++s)
+    {
+        inspectMultiArrayImpl(s.begin(), shape, a, f, MetaInt<N-1>());
+    }
+}
+    
+/** \brief Call an analyzing functor at every element of a multi-dimensional array.
+
+    This function can be used to collect statistics of the array etc.
+    The results must be stored in the functor, which serves as a return
+    value (therefore, it is passed to the function by reference). The array must be 
+    represented as a MultiArrayView.
+    
+    For many common statistics, the use of \ref  vigra::acc::extractFeatures() in combination with 
+    \ref FeatureAccumulators is more convenient.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T, class S, 
+                  class Functor>
+        void
+        inspectMultiArray(MultiArrayView<N, T, S> const & s, 
+                          Functor & f);
+    }
+    \endcode
+
+    \deprecatedAPI{inspectMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class Iterator, class Shape, class Accessor, class Functor>
+        void
+        inspectMultiArray(Iterator s, Shape const & shape, Accessor a,  Functor & f);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class Iterator, class Shape, class Accessor, class Functor>
+        void
+        inspectMultiArray(triple<Iterator, Shape, Accessor> const & s, Functor & f);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_pointoperators.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<3, int>  array(Shape3(100, 200, 50));
+    ... // fill array
+    
+    // init functor
+    FindMinMax<int> minmax;
+
+    inspectMultiArray(array, minmax);
+
+    cout << "Min: " << minmax.min << " Max: " << minmax.max;
+    \endcode
+    The functor must support function call with one argument.
+
+    \deprecatedUsage{inspectMultiArray}
+    \code
+    typedef vigra::MultiArray<3, int> Array;
+    Array array(Shape3(100, 200, 50));
+
+    // init functor
+    vigra::FindMinMax<int> minmax;
+
+    vigra::inspectMultiArray(srcMultiArrayRange(array), minmax);
+
+    cout << "Min: " << minmax.min << " Max: " << minmax.max;
+
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    MultiIterator src_begin;
+
+    Accessor accessor;
+    Functor functor;
+
+    functor(accessor(src_begin)); 
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void inspectMultiArray)
+
+template <class Iterator, class Shape, class Accessor>
+struct inspectMultiArray_binder
+{
+    Iterator      s;
+    const Shape & shape;
+    Accessor      a;
+    inspectMultiArray_binder(Iterator s_, const Shape & shape_, Accessor a_)
+        : s(s_), shape(shape_), a(a_) {}
+    template <class Functor>
+    void operator()(Functor & f)
+    {
+        inspectMultiArrayImpl(s, shape, a, f, MetaInt<Iterator::level>());
+    }
+};
+
+template <class Iterator, class Shape, class Accessor, class Functor>
+inline void
+inspectMultiArray(Iterator s, Shape const & shape, Accessor a, Functor & f)
+{
+    inspectMultiArray_binder<Iterator, Shape, Accessor> g(s, shape, a);
+    detail::extra_passes_select(g, f);
+}
+    
+template <class Iterator, class Shape, class Accessor, class Functor>
+inline void
+inspectMultiArray(triple<Iterator, Shape, Accessor> const & s, Functor & f)
+{
+    inspectMultiArray(s.first, s.second, s.third, f);
+}
+    
+template <unsigned int N, class T, class S, class Functor>
+inline void
+inspectMultiArray(MultiArrayView<N, T, S> const & s, Functor & f)
+{
+    inspectMultiArray(srcMultiArrayRange(s), f);
+}
+    
+/********************************************************/
+/*                                                      */
+/*                  inspectTwoMultiArrays               */
+/*                                                      */
+/********************************************************/
+
+template <class Iterator1, class Shape, class Accessor1, 
+          class Iterator2, class Accessor2, 
+          class Functor>
+inline void
+inspectTwoMultiArraysImpl(Iterator1 s1, Shape const & shape, Accessor1 a1,
+                          Iterator2 s2, Accessor2 a2,
+                          Functor & f, MetaInt<0>)
+{
+    inspectTwoLines(s1, s1 + shape[0], a1, s2, a2, f);
+}
+    
+template <class Iterator1, class Shape, class Accessor1, 
+          class Iterator2, class Accessor2, 
+          class Functor, int N>
+void
+inspectTwoMultiArraysImpl(Iterator1 s1, Shape const & shape, Accessor1 a1,
+                          Iterator2 s2, Accessor2 a2,
+                          Functor & f, MetaInt<N>)
+{
+    Iterator1 s1end = s1 + shape[N];
+    for(; s1 < s1end; ++s1, ++s2)
+    {
+        inspectTwoMultiArraysImpl(s1.begin(), shape, a1, 
+                                  s2.begin(), a2, f, MetaInt<N-1>());
+    }
+}
+    
+/** \brief Call an analyzing functor at all corresponding elements of 
+           two multi-dimensional arrays.
+
+    This function can be used to collect statistics over tow arrays.
+    For example, one can holde data, and the other region labels or weights.
+    The results must be stored in the functor, which serves as a return
+    value (and is therefore passed by reference). The arrays must be represented by
+    MultiArrayViews.
+    
+    For many common statistics, the use of \ref  vigra::acc::extractFeatures() in combination with 
+    \ref FeatureAccumulators is more convenient.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1, 
+                                  class T2, class S2, 
+                  class Functor>
+        void
+        inspectTwoMultiArrays(MultiArrayView<N, T1, S1> const & s1, 
+                              MultiArrayView<N, T2, S2> const & s2,
+                              Functor & f);
+    }
+    \endcode
+
+    \deprecatedAPI{inspectTwoMultiArrays}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class Iterator1, class Shape, class Accessor1, 
+                  class Iterator2, class Accessor2, 
+                  class Functor>
+        void
+        inspectTwoMultiArrays(Iterator1 s1, Shape const & shape, Accessor1 a1,
+                              Iterator2 s2, Accessor2 a2, Functor & f);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class Iterator1, class Shape1, class Accessor1, 
+                  class Iterator2, class Accessor2, 
+                  class Functor>
+        void
+        inspectTwoMultiArrays(triple<Iterator1, Shape1, Accessor1> const & s1, 
+                              pair<Iterator2, Accessor2> const & s2, Functor & f);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_pointoperators.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<3, int>  array1(Shape3(100, 200, 50)),
+                        array2(Shape3(100, 200, 50));
+
+    // init functor
+    SomeStatisticsFunctor stats(..);
+
+    inspectTwoMultiArrays(array1, array2, stats);
+    \endcode
+    The functor must support function call with two arguments.
+
+    \deprecatedUsage{inspectTwoMultiArrays}
+    \code
+    MultiArray<3, int>  array1(Shape3(100, 200, 50)),
+                        array2(Shape3(100, 200, 50));
+
+    // init functor
+    SomeStatisticsFunctor stats(..);
+
+    vigra::inspectTwoMultiArrays(srcMultiArrayRange(array1), srcMultiArray(array2), stats);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    MultiIterator src1_begin, src2_begin;
+
+    Accessor a1, a2;
+    Functor functor;
+
+    functor(a1(src1_begin), a2(src2_begin)); 
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void inspectTwoMultiArrays)
+
+template <class Iterator1, class Shape, class Accessor1,
+          class Iterator2, class Accessor2>
+struct inspectTwoMultiArrays_binder
+{
+    Iterator1     s1;
+    const Shape & shape;
+    Accessor1     a1;
+    Iterator2     s2;
+    Accessor2     a2;
+    inspectTwoMultiArrays_binder(Iterator1 s1_, const Shape & shape_,
+                                 Accessor1 a1_, Iterator2 s2_, Accessor2 a2_)
+        : s1(s1_), shape(shape_), a1(a1_), s2(s2_), a2(a2_) {}
+    template <class Functor>
+    void operator()(Functor & f)
+    {
+        inspectTwoMultiArraysImpl(s1, shape, a1, s2, a2, f,
+                                  MetaInt<Iterator1::level>());
+    }
+};
+    
+template <class Iterator1, class Shape, class Accessor1,
+          class Iterator2, class Accessor2,
+          class Functor>
+inline void
+inspectTwoMultiArrays(Iterator1 s1, Shape const & shape, Accessor1 a1,
+                      Iterator2 s2, Accessor2 a2, Functor & f)
+{
+    inspectTwoMultiArrays_binder<Iterator1, Shape, Accessor1,
+                                 Iterator2, Accessor2>
+        g(s1, shape, a1, s2, a2);
+    detail::extra_passes_select(g, f);
+}
+    
+template <class Iterator1, class Shape, class Accessor1, 
+          class Iterator2, class Accessor2, 
+          class Functor>
+inline void
+inspectTwoMultiArrays(triple<Iterator1, Shape, Accessor1> const & s1, 
+                      pair<Iterator2, Accessor2> const & s2, Functor & f)
+{
+    inspectTwoMultiArrays(s1.first, s1.second, s1.third, 
+                          s2.first, s2.second, f);
+}
+    
+template <unsigned int N, class T1, class S1, 
+                          class T2, class S2, 
+          class Functor>
+inline void
+inspectTwoMultiArrays(MultiArrayView<N, T1, S1> const & s1, 
+                      MultiArrayView<N, T2, S2> const & s2, Functor & f)
+{
+    vigra_precondition(s1.shape() == s2.shape(),
+        "inspectTwoMultiArrays(): shape mismatch between inputs.");
+    
+    inspectTwoMultiArrays(srcMultiArrayRange(s1), 
+                          srcMultiArray(s2), f);
+}
+    
+//@}
+
+}  //-- namespace vigra
+
+
+#endif  //-- VIGRA_MULTI_POINTOPERATORS_H
diff --git a/include/vigra/multi_resize.hxx b/include/vigra/multi_resize.hxx
new file mode 100644
index 0000000..c017acd
--- /dev/null
+++ b/include/vigra/multi_resize.hxx
@@ -0,0 +1,328 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_MULTI_RESIZE_HXX
+#define VIGRA_MULTI_RESIZE_HXX
+
+#include <vector>
+#include "resizeimage.hxx"
+#include "navigator.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+namespace detail {
+
+template <class SrcIterator, class Shape, class SrcAccessor,
+          class DestIterator, class DestAccessor, class Kernel>
+void
+internalResizeMultiArrayOneDimension(
+                      SrcIterator si, Shape const & sshape, SrcAccessor src,
+                      DestIterator di, Shape const & dshape, DestAccessor dest, 
+                      Kernel const & spline, unsigned int d)
+{
+    enum { N = 1 + SrcIterator::level };
+
+    typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
+
+    typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
+    typedef MultiArrayNavigator<DestIterator, N> DNavigator;
+
+    SNavigator snav( si, sshape, d );
+    DNavigator dnav( di, dshape, d );
+    
+    int ssize = sshape[d];
+    int dsize = dshape[d];
+
+    vigra_precondition(ssize > 1,
+                 "resizeMultiArraySplineInterpolation(): "
+                 "Source array too small.\n");
+
+    Rational<int> ratio(dsize - 1, ssize - 1);
+    Rational<int> offset(0);
+    resampling_detail::MapTargetToSourceCoordinate mapCoordinate(ratio, offset);
+    int period = lcm(ratio.numerator(), ratio.denominator());
+    
+    ArrayVector<double> const & prefilterCoeffs = spline.prefilterCoefficients();
+    ArrayVector<Kernel1D<double> > kernels(period);
+    createResamplingKernels(spline, mapCoordinate, kernels);
+
+    // temporary array to hold the current line to enable in-place operation
+    ArrayVector<TmpType> tmp( ssize );
+    typename ArrayVector<TmpType>::iterator t = tmp.begin(), tend = tmp.end();
+    typename AccessorTraits<TmpType>::default_accessor ta;
+    
+    for( ; snav.hasMore(); snav++, dnav++ )
+    {
+        // first copy source to temp for maximum cache efficiency
+        copyLine( snav.begin(), snav.end(), src, t, ta);
+
+        for(unsigned int b = 0; b < prefilterCoeffs.size(); ++b)
+        {
+            recursiveFilterLine(t, tend, ta, t, ta,
+                                prefilterCoeffs[b], BORDER_TREATMENT_REFLECT);
+        }
+        resamplingConvolveLine(t, tend, ta,
+                               dnav.begin(), dnav.begin() + dsize, dest,
+                               kernels, mapCoordinate);
+    }
+}
+
+} // namespace detail
+
+/** \addtogroup GeometricTransformations Geometric Transformations
+*/
+//@{
+
+
+/***************************************************************/
+/*                                                             */
+/*             resizeMultiArraySplineInterpolation             */
+/*                                                             */
+/***************************************************************/
+
+/** \brief Resize MultiArray using B-spline interpolation.
+
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2, 
+                  class Kernel = BSpline<3, double> >
+        void
+        resizeMultiArraySplineInterpolation(MultiArrayView<N, T1, S1> const & source,
+                                            MultiArrayView<N, T2, S2> dest,
+                                            Kernel const & spline = BSpline<3, double>());
+    }
+    \endcode
+
+    \deprecatedAPI{resizeMultiArraySplineInterpolation}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class Shape, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class Kernel = BSpline<3, double> >
+        void
+        resizeMultiArraySplineInterpolation(
+                              SrcIterator si, Shape const & sshape, SrcAccessor src,
+                              DestIterator di, Shape const & dshape, DestAccessor dest,
+                              Kernel const & spline = BSpline<3, double>());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class Shape, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class Kernel = BSpline<3, double> >
+        void
+        resizeMultiArraySplineInterpolation(
+                              triple<SrcIterator, Shape, SrcAccessor> src,
+                              triple<DestIterator, Shape, DestAccessor> dest,
+                              Kernel const & spline = BSpline<3, double>());
+    }
+    \endcode
+    \deprecatedEnd
+
+    The function implements separable spline interpolation algorithm described in
+
+    M. Unser, A. Aldroubi, M. Eden, <i>"B-Spline Signal Processing"</i>
+    IEEE Transactions on Signal Processing, vol. 41, no. 2, pp. 821-833 (part I),
+    pp. 834-848 (part II), 1993.
+
+    to obtain optimal interpolation quality and speed. You may pass the function
+    a spline of arbitrary order (e.g. <TT>BSpline<ORDER, double></tt> or
+    <TT>CatmullRomSpline<double></tt>). The default is a third order spline
+    which gives a twice continuously differentiable interpolant.
+    The implementation ensures that image values are interpolated rather
+    than smoothed by first calling a recursive (sharpening) prefilter as
+    described in the above paper. Then the actual interpolation is done
+    using \ref resamplingConvolveLine().
+
+    The range of both the input and output images (resp. regions)
+    must be given. The input image must have a size of at
+    least 4x4, the destination of at least 2x2. The scaling factors are then calculated
+    accordingly. If the source image is larger than the destination, it
+    is smoothed (band limited) using a recursive
+    exponential filter. The source value_type (SrcAccessor::value_type) must
+    be a linear algebra, i.e. it must support addition, subtraction,
+    and multiplication (+, -, *), multiplication with a scalar
+    real number and \ref NumericTraits "NumericTraits".
+    The function uses accessors.
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_resize.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<3, float> src(Shape3(5, 7, 10)),
+                         dest(Shape3(9, 13, 19)); // double the size
+
+    // use default cubic spline interpolator
+    resizeMultiArraySplineInterpolation(src, dest);
+
+    // use linear interpolator
+    resizeMultiArraySplineInterpolation(src, dest, BSpline<1, double>());
+    \endcode
+
+    \deprecatedUsage{resizeMultiArraySplineInterpolation}
+    \code
+    vigra::MultiArray<3, float> src(Shape3(5, 7, 10)),
+                                dest(Shape3(9, 13, 19)); // double the size
+
+    // use linear interpolator
+    vigra::resizeMultiArraySplineInterpolation(srcMultiArrayRange(src),
+               destMultiArrayRange(dest), BSpline<1, double>());
+
+    // use default cubic spline interpolator
+    vigra::resizeMultiArraySplineInterpolation(
+               srcMultiArrayRange(src),
+               destMultiArrayRange(dest));
+
+    \endcode
+    <b> Required Interface:</b>
+    The source and destination iterators must be compatible with \ref vigra::MultiIterator. The array value
+    types must be models of \ref LinearSpace.
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void resizeMultiArraySplineInterpolation)
+
+template <class SrcIterator, class Shape, class SrcAccessor,
+          class DestIterator, class DestAccessor, 
+          class Kernel>
+void
+resizeMultiArraySplineInterpolation(
+                      SrcIterator si, Shape const & sshape, SrcAccessor src,
+                      DestIterator di, Shape const & dshape, DestAccessor dest, 
+                      Kernel const & spline)
+{
+    enum { N = 1 + SrcIterator::level };
+    typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
+    typedef typename AccessorTraits<TmpType>::default_accessor TmpAccessor;
+        
+    if(N==1)
+    {
+        detail::internalResizeMultiArrayOneDimension(si, sshape, src, 
+                      di, dshape, dest, spline, 0);
+    }
+    else
+    {
+        unsigned int d = 0;
+        Shape tmpShape(sshape);
+        tmpShape[d] = dshape[d];
+        MultiArray<N, TmpType> tmp(tmpShape);
+        TmpAccessor ta;
+        
+        detail::internalResizeMultiArrayOneDimension(si, sshape, src, 
+                             tmp.traverser_begin(), tmpShape, ta, spline, d);
+        d = 1;
+        for(; d<N-1; ++d)
+        {
+            tmpShape[d] = dshape[d];
+            MultiArray<N, TmpType> dtmp(tmpShape);
+            
+            detail::internalResizeMultiArrayOneDimension(tmp.traverser_begin(), tmp.shape(), ta, 
+                                  dtmp.traverser_begin(), tmpShape, ta, spline, d);
+            dtmp.swap(tmp);
+        }
+        detail::internalResizeMultiArrayOneDimension(tmp.traverser_begin(), tmp.shape(), ta, 
+                                        di, dshape, dest, spline, d);
+    }
+}
+
+template <class SrcIterator, class Shape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+resizeMultiArraySplineInterpolation(
+                      SrcIterator si, Shape const & sshape, SrcAccessor src,
+                      DestIterator di, Shape const & dshape, DestAccessor dest)
+{
+    resizeMultiArraySplineInterpolation(si, sshape, src, di, dshape, dest, BSpline<3, double>());
+}
+
+template <class SrcIterator, class Shape, class SrcAccessor,
+          class DestIterator, class DestAccessor, 
+          class Kernel>
+inline void
+resizeMultiArraySplineInterpolation(triple<SrcIterator, Shape, SrcAccessor> src,
+                                    triple<DestIterator, Shape, DestAccessor> dest,
+                                    Kernel const & spline)
+{
+    resizeMultiArraySplineInterpolation(src.first, src.second, src.third,
+                                        dest.first, dest.second, dest.third, spline);
+}
+
+template <class SrcIterator, class Shape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+resizeMultiArraySplineInterpolation(triple<SrcIterator, Shape, SrcAccessor> src,
+                                    triple<DestIterator, Shape, DestAccessor> dest)
+{
+    resizeMultiArraySplineInterpolation(src.first, src.second, src.third,
+                                        dest.first, dest.second, dest.third);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2, 
+          class Kernel>
+inline void
+resizeMultiArraySplineInterpolation(MultiArrayView<N, T1, S1> const & source,
+                                    MultiArrayView<N, T2, S2> dest,
+                                    Kernel const & spline)
+{
+    resizeMultiArraySplineInterpolation(srcMultiArrayRange(source),
+                                        destMultiArrayRange(dest), spline);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void
+resizeMultiArraySplineInterpolation(MultiArrayView<N, T1, S1>  const & source,
+                                    MultiArrayView<N, T2, S2> dest)
+{
+    resizeMultiArraySplineInterpolation(srcMultiArrayRange(source),
+                                        destMultiArrayRange(dest));
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_MULTI_RESIZE_HXX
diff --git a/include/vigra/multi_shape.hxx b/include/vigra/multi_shape.hxx
new file mode 100644
index 0000000..ffc592b
--- /dev/null
+++ b/include/vigra/multi_shape.hxx
@@ -0,0 +1,675 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2011-2012 by Stefan Schmidt and Ullrich Koethe         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_SHAPE_HXX
+#define VIGRA_MULTI_SHAPE_HXX
+
+#include <sys/types.h>
+#include "tinyvector.hxx"
+#include "array_vector.hxx"
+#include "numerictraits.hxx"
+
+namespace vigra {
+
+/** \addtogroup MultiIteratorGroup  Multi-dimensional Shapes and Array Iterators
+
+    \brief Shape objects and general iterators for arrays of arbitrary dimension.
+*/
+//@{
+
+    /** Index type for a single dimension of a MultiArrayView or
+        MultiArray.
+    */
+typedef std::ptrdiff_t MultiArrayIndex;
+
+/********************************************************/
+/*                                                      */
+/*              Singleband and Multiband                */
+/*                                                      */
+/********************************************************/
+
+template <class T>
+struct Singleband  // the resulting MultiArray has no explicit channel axis 
+                   // (i.e. the number of channels is implicitly one)
+{
+    typedef T value_type;
+};
+
+template <class T>
+struct Multiband  // the last axis is explicitly designated as channel axis
+{
+    typedef T value_type;
+};
+
+template<class T>
+struct NumericTraits<Singleband<T> >
+: public NumericTraits<T>
+{};
+
+template<class T>
+struct NumericTraits<Multiband<T> >
+{
+    typedef Multiband<T> Type;
+/*
+    typedef int Promote;
+    typedef unsigned int UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+*/
+    typedef Type ValueType;
+
+    typedef typename NumericTraits<T>::isIntegral isIntegral;
+    typedef VigraFalseType isScalar;
+    typedef typename NumericTraits<T>::isSigned isSigned;
+    typedef typename NumericTraits<T>::isSigned isOrdered;
+    typedef typename NumericTraits<T>::isSigned isComplex;
+/*
+    static signed char zero() { return 0; }
+    static signed char one() { return 1; }
+    static signed char nonZero() { return 1; }
+    static signed char min() { return SCHAR_MIN; }
+    static signed char max() { return SCHAR_MAX; }
+
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = SCHAR_MIN, maxConst = SCHAR_MIN };
+#else
+    static const signed char minConst = SCHAR_MIN;
+    static const signed char maxConst = SCHAR_MIN;
+#endif
+
+    static Promote toPromote(signed char v) { return v; }
+    static RealPromote toRealPromote(signed char v) { return v; }
+    static signed char fromPromote(Promote v) {
+        return ((v < SCHAR_MIN) ? SCHAR_MIN : (v > SCHAR_MAX) ? SCHAR_MAX : v);
+    }
+    static signed char fromRealPromote(RealPromote v) {
+        return ((v < 0.0)
+                   ? ((v < (RealPromote)SCHAR_MIN)
+                       ? SCHAR_MIN
+                       : static_cast<signed char>(v - 0.5))
+                   : (v > (RealPromote)SCHAR_MAX)
+                       ? SCHAR_MAX
+                       : static_cast<signed char>(v + 0.5));
+    }
+*/
+};
+
+namespace detail {
+
+/********************************************************/
+/*                                                      */
+/*                    defaultStride                     */
+/*                                                      */
+/********************************************************/
+
+    /* generates the stride for a gapless shape.
+    */
+template <int N>
+inline TinyVector <MultiArrayIndex, N>
+defaultStride(const TinyVector <MultiArrayIndex, N> &shape)
+{
+    TinyVector <MultiArrayIndex, N> ret;
+    ret [0] = 1;
+    for (int i = 1; i < (int)N; ++i)
+        ret [i] = ret [i-1] * shape [i-1];
+    return ret;
+}
+
+    /* generates the stride for a gapless shape.
+    */
+template <int N>
+inline TinyVector <MultiArrayIndex, N>
+defaultMultibandStride(const TinyVector <MultiArrayIndex, N> &shape)
+{
+    TinyVector <MultiArrayIndex, N> ret;
+    ret [N-1] = 1;
+    for (int i = 0; i < (int)N-1; ++i)
+    {
+        int j = (i + int(N - 1)) % N;
+        ret [i] = ret [j] * shape [j];
+    }
+    return ret;
+}
+
+/********************************************************/
+/*                                                      */
+/*                  ResolveMultiband                    */
+/*                                                      */
+/********************************************************/
+
+template <class T>
+struct ResolveMultiband
+{
+    typedef T type;
+    typedef StridedArrayTag Stride;
+    static const bool value = false;
+
+    template <int N>
+    static TinyVector <MultiArrayIndex, N>
+    defaultStride(const TinyVector <MultiArrayIndex, N> &shape)
+    {
+        return vigra::detail::defaultStride(shape);
+    }
+};
+
+template <class T>
+struct ResolveMultiband<Singleband<T> >
+{
+    typedef T type;
+    typedef StridedArrayTag Stride;
+    static const bool value = false;
+
+    template <int N>
+    static TinyVector <MultiArrayIndex, N>
+    defaultStride(const TinyVector <MultiArrayIndex, N> &shape)
+    {
+        return vigra::detail::defaultStride(shape);
+    }
+};
+
+template <class T>
+struct ResolveMultiband<Multiband<T> >
+{
+    typedef T type;
+    typedef StridedArrayTag Stride;
+    static const bool value = true;
+
+    template <int N>
+    static TinyVector <MultiArrayIndex, N>
+    defaultStride(const TinyVector <MultiArrayIndex, N> &shape)
+    {
+        return vigra::detail::defaultMultibandStride(shape);
+    }
+};
+
+} // namespace detail
+
+template <unsigned int N, class T, class C = StridedArrayTag>
+class MultiArrayView;
+
+template <unsigned int N, class T, 
+          class A = std::allocator<typename vigra::detail::ResolveMultiband<T>::type> >
+class MultiArray;
+
+
+    /** Traits class for the difference type of all MultiIterator, MultiArrayView, and
+        MultiArray variants.
+    */
+template <unsigned int N>
+class MultiArrayShape
+{
+  public:
+        /** The difference type of all MultiIterator, MultiArrayView, and
+            MultiArray variants.
+        */
+    typedef TinyVector<MultiArrayIndex, N> type;
+};
+
+typedef MultiArrayShape<1>::type Shape1; ///< shape type for MultiArray<1, T>
+typedef MultiArrayShape<2>::type Shape2; ///< shape type for MultiArray<2, T>
+typedef MultiArrayShape<3>::type Shape3; ///< shape type for MultiArray<3, T>
+typedef MultiArrayShape<4>::type Shape4; ///< shape type for MultiArray<4, T>
+typedef MultiArrayShape<5>::type Shape5; ///< shape type for MultiArray<5, T>
+
+    /** \brief Choose the neighborhood system in a dimension-independent way.  
+    
+        DirectNeighborhood corresponds to 4-neighborhood in 2D and 6-neighborhood in 3D, whereas
+        IndirectNeighborhood means 8-neighborhood in 2D and 26-neighborhood in 3D. The general
+        formula for N dimensions are 2*N for direct neighborhood and 3^N-1 for indirect neighborhood. 
+    */
+enum NeighborhoodType { 
+        DirectNeighborhood=0,   ///< use only direct neighbors
+        IndirectNeighborhood=1  ///< use direct and indirect neighbors
+};
+
+// Helper functions
+
+namespace detail {
+
+/********************************************************/
+/*                                                      */
+/*                CoordinateToScanOrder                 */
+/*                                                      */
+/********************************************************/
+
+    /* Convert multi-dimensional index (i.e. a grid coordinate) to scan-order index.
+    */
+template <int K>
+struct CoordinateToScanOrder
+{
+    template <int N, class D1, class D2, class D3, class D4>
+    static MultiArrayIndex
+    exec(const TinyVectorBase <MultiArrayIndex, N, D1, D2> &shape,
+         const TinyVectorBase <MultiArrayIndex, N, D3, D4> & coordinate)
+    {
+        return coordinate[N-K] + shape[N-K] * CoordinateToScanOrder<K-1>::exec(shape, coordinate);
+    }
+};
+
+template <>
+struct CoordinateToScanOrder<1>
+{
+    template <int N, class D1, class D2, class D3, class D4>
+    static MultiArrayIndex
+    exec(const TinyVectorBase <MultiArrayIndex, N, D1, D2> & /*shape*/,
+         const TinyVectorBase <MultiArrayIndex, N, D3, D4> & coordinate)
+    {
+        return coordinate[N-1];
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                ScanOrderToCoordinate                 */
+/*                                                      */
+/********************************************************/
+
+    /* Convert scan-order index to multi-dimensional index (i.e. a grid coordinate).
+    */
+template <int K>
+struct ScanOrderToCoordinate
+{
+    template <int N>
+    static void
+    exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> &shape,
+         TinyVector <MultiArrayIndex, N> & result)
+    {
+        result[N-K] = (d % shape[N-K]);
+        ScanOrderToCoordinate<K-1>::exec(d / shape[N-K], shape, result);
+    }
+};
+
+template <>
+struct ScanOrderToCoordinate<1>
+{
+    template <int N>
+    static void
+    exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> & /*shape*/,
+         TinyVector <MultiArrayIndex, N> & result)
+    {
+        result[N-1] = d;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                 ScanOrderToOffset                    */
+/*                                                      */
+/********************************************************/
+
+    /* transforms an index in scan order sense to a pointer offset in a possibly
+       strided, multi-dimensional array.
+    */
+template <int K>
+struct ScanOrderToOffset
+{
+    template <int N>
+    static MultiArrayIndex
+    exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> &shape,
+         const TinyVector <MultiArrayIndex, N> & stride)
+    {
+        return stride[N-K] * (d % shape[N-K]) +
+               ScanOrderToOffset<K-1>::exec(d / shape[N-K], shape, stride);
+    }
+};
+
+template <>
+struct ScanOrderToOffset<1>
+{
+    template <int N>
+    static MultiArrayIndex
+    exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> & /*shape*/,
+         const TinyVector <MultiArrayIndex, N> & stride)
+    {
+        return stride[N-1] * d;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                 ScanOrderToOffset                    */
+/*                                                      */
+/********************************************************/
+
+    /* transforms a multi-dimensional index (grid coordinate) to a pointer offset in a possibly
+       strided, multi-dimensional array.
+    */
+template <class C>
+struct CoordinatesToOffest
+{
+    template <int N>
+    static MultiArrayIndex
+    exec(const TinyVector <MultiArrayIndex, N> & stride, MultiArrayIndex x)
+    {
+        return stride[0] * x;
+    }
+    template <int N>
+    static MultiArrayIndex
+    exec(const TinyVector <MultiArrayIndex, N> & stride, MultiArrayIndex x, MultiArrayIndex y)
+    {
+        return stride[0] * x + stride[1] * y;
+    }
+};
+
+template <>
+struct CoordinatesToOffest<UnstridedArrayTag>
+{
+    template <int N>
+    static MultiArrayIndex
+    exec(const TinyVector <MultiArrayIndex, N> & /*stride*/, MultiArrayIndex x)
+    {
+        return x;
+    }
+    template <int N>
+    static MultiArrayIndex
+    exec(const TinyVector <MultiArrayIndex, N> & stride, MultiArrayIndex x, MultiArrayIndex y)
+    {
+        return x + stride[1] * y;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*            RelativeToAbsoluteCoordinate              */
+/*                                                      */
+/********************************************************/
+
+    /* transforms a coordinate object with negative indices into the corresponding 
+       'shape - abs(index)'.
+    */
+template <int M>
+struct RelativeToAbsoluteCoordinate
+{
+    template <int N>
+    static void
+    exec(const TinyVector<MultiArrayIndex, N> & shape, TinyVector<MultiArrayIndex, N> & coord)
+    {
+        RelativeToAbsoluteCoordinate<M-1>::exec(shape, coord);
+        if(coord[M] < 0)
+            coord[M] += shape[M];
+    }
+};
+
+template <>
+struct RelativeToAbsoluteCoordinate<0>
+{
+    template <int N>
+    static void
+    exec(const TinyVector<MultiArrayIndex, N> & shape, TinyVector<MultiArrayIndex, N> & coord)
+    {
+        if(coord[0] < 0)
+            coord[0] += shape[0];
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                   BorderTypeImpl                     */
+/*                                                      */
+/********************************************************/
+
+// a border type is a compact bit-wise encoding of the fact that a 
+// given coordinate is at the border of the ROI. Each border corresponds
+// to one bit in the encoding, e.g. the left, right, top, bottom borders
+// of a 2D image are represented by bits 0 to 3 respectively. 
+// If a bit is set, the point in question is at the corresponding border.
+// A code of all zeros therefore means that the point is in the interior
+// of the ROI
+template <unsigned int N, unsigned int DIMENSION=N-1>
+struct BorderTypeImpl
+{
+    typedef typename MultiArrayShape<N>::type shape_type;
+    
+    static unsigned int exec(shape_type const & point, shape_type const & shape)
+    {
+        unsigned int res = BorderTypeImpl<N, DIMENSION-1>::exec(point, shape);
+        if(point[DIMENSION] == 0)
+            res |= (1 << 2*DIMENSION);
+        if(point[DIMENSION] == shape[DIMENSION]-1)
+            res |= (2 << 2*DIMENSION);
+        return res;
+    }
+};
+
+template <unsigned int N>
+struct BorderTypeImpl<N, 0>
+{
+    typedef typename MultiArrayShape<N>::type shape_type;
+    static const unsigned int DIMENSION = 0;
+    
+    static unsigned int exec(shape_type const & point, shape_type const & shape)
+    {
+        unsigned int res = 0;
+        if(point[DIMENSION] == 0)
+            res |= (1 << 2*DIMENSION);
+        if(point[DIMENSION] == shape[DIMENSION]-1)
+            res |= (2 << 2*DIMENSION);
+        return res;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                makeArrayNeighborhood                 */
+/*                                                      */
+/********************************************************/
+
+// Create the offsets to all direct neighbors, starting from the given Level (=dimension)
+// and append them to the given array. The algorithm is designed so that the offsets are 
+// sorted by ascending strides. This has two important consequences:
+//  * The first half of the array contains the causal neighbors (negative strides),
+//    the second half the anti-causal ones (positive strides), where 'causal' refers
+//    to all scan-order predecessors of the center pixel, and 'anticausal' to its successors.
+//  * For any neighbor k, its opposite (=point-reflected) neighbor is located at index
+//    'N-1-k', where N is the total number of neighbors.
+// The function 'exists' returns an array of flags that contains 'true' when the corresponding 
+// neighbor is inside the ROI for the given borderType, 'false' otherwise. 
+template <unsigned int Level>
+struct MakeDirectArrayNeighborhood
+{
+    template <class Array>
+    static void offsets(Array & a)
+    {
+        typedef typename Array::value_type Shape;
+        
+        Shape point;
+        point[Level] = -1;
+        a.push_back(point);
+        MakeDirectArrayNeighborhood<Level-1>::offsets(a);
+        point[Level] = 1;
+        a.push_back(point);
+    }
+    
+    template <class Array>
+    static void exists(Array & a, unsigned int borderType)
+    {
+        a.push_back((borderType & (1 << 2*Level)) == 0);
+        MakeDirectArrayNeighborhood<Level-1>::exists(a, borderType);
+        a.push_back((borderType & (2 << 2*Level)) == 0);
+    }
+};
+
+template <>
+struct MakeDirectArrayNeighborhood<0>
+{
+    template <class Array>
+    static void offsets(Array & a)
+    {
+        typedef typename Array::value_type Shape;
+        
+        Shape point;
+        point[0] = -1;
+        a.push_back(point);
+        point[0] = 1;
+        a.push_back(point);
+    }
+    
+    template <class Array>
+    static void exists(Array & a, unsigned int borderType)
+    {
+        a.push_back((borderType & 1) == 0);
+        a.push_back((borderType & 2) == 0);
+    }
+};
+
+// Likewise, create the offsets to all indirect neighbors according to the same rules.
+template <unsigned int Level>
+struct MakeIndirectArrayNeighborhood
+{
+    template <class Array, class Shape>
+    static void offsets(Array & a, Shape point, bool isCenter = true)
+    {
+        point[Level] = -1;
+        MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point, false);
+        point[Level] = 0;
+        MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point, isCenter);
+        point[Level] = 1;
+        MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point, false);
+    }
+    
+    template <class Array>
+    static void exists(Array & a, unsigned int borderType, bool isCenter = true)
+    {
+        if((borderType & (1 << 2*Level)) == 0)
+            MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType, false);
+        else 
+            MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
+
+        MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType, isCenter);
+
+        if((borderType & (2 << 2*Level)) == 0)
+            MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType, false);
+        else
+            MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
+    }
+
+    template <class Array>
+    static void markOutside(Array & a)
+    {
+        // Call markOutside() three times, for each possible offset at (Level-1)
+        MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
+        MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
+        MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
+    }
+
+};
+
+template <>
+struct MakeIndirectArrayNeighborhood<0>
+{
+    template <class Array, class Shape>
+    static void offsets(Array & a, Shape point, bool isCenter = true)
+    {
+        point[0] = -1;
+        a.push_back(point);
+        if(!isCenter) // the center point is not a neighbor, it's just convenient to do the enumeration this way...
+        {
+            point[0] = 0;
+            a.push_back(point);
+        }
+        point[0] = 1;
+        a.push_back(point);
+    }
+    
+    template <class Array>
+    static void exists(Array & a, unsigned int borderType, bool isCenter = true)
+    {
+        a.push_back((borderType & 1) == 0);
+        if(!isCenter)
+        {
+            a.push_back(true);
+        }
+        a.push_back((borderType & 2) == 0);
+    }
+
+    template <class Array>
+    static void markOutside(Array & a)
+    {
+        // Push 'false' three times, for each possible offset at level 0, whenever the point was 
+        // outside the ROI in one of the higher levels.
+        a.push_back(false);
+        a.push_back(false);
+        a.push_back(false);
+    }
+};
+
+// Create the list of neighbor offsets for the given neighborhood type 
+// and dimension (the dimension is implicitly defined by the Shape type)
+// an return it in 'neighborOffsets'. Moreover, create a list of flags
+// for each BorderType that is 'true' when the corresponding neighbor exists
+// in this border situation and return the result in 'neighborExists'.
+template <class Shape>
+void
+makeArrayNeighborhood(ArrayVector<Shape> & neighborOffsets, 
+                      ArrayVector<ArrayVector<bool> > & neighborExists,
+                      NeighborhoodType neighborhoodType = DirectNeighborhood)
+{
+    enum { N = Shape::static_size };
+    
+    neighborOffsets.clear();
+    if(neighborhoodType == DirectNeighborhood)
+    {
+        MakeDirectArrayNeighborhood<N-1>::offsets(neighborOffsets);
+    }
+    else
+    {
+        Shape point; // represents the center
+        MakeIndirectArrayNeighborhood<N-1>::offsets(neighborOffsets, point);
+    }
+    
+    unsigned int borderTypeCount = 1 << 2*N;
+    neighborExists.resize(borderTypeCount);
+
+    for(unsigned int k=0; k<borderTypeCount; ++k)
+    {
+        neighborExists[k].clear();
+        if(neighborhoodType == DirectNeighborhood)
+        {
+            MakeDirectArrayNeighborhood<N-1>::exists(neighborExists[k], k);
+        }
+        else
+        {
+            MakeIndirectArrayNeighborhood<N-1>::exists(neighborExists[k], k);
+        }
+    }
+}
+
+} // namespace detail
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_MULTI_SHAPE_HXX
diff --git a/include/vigra/multi_tensorutilities.hxx b/include/vigra/multi_tensorutilities.hxx
new file mode 100644
index 0000000..285858d
--- /dev/null
+++ b/include/vigra/multi_tensorutilities.hxx
@@ -0,0 +1,641 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2009-2010 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_TENSORUTILITIES_HXX
+#define VIGRA_MULTI_TENSORUTILITIES_HXX
+
+#include <cmath>
+#include "utilities.hxx"
+#include "mathutil.hxx"
+#include "metaprogramming.hxx"
+#include "multi_shape.hxx"
+#include "multi_pointoperators.hxx"
+
+namespace vigra {
+
+namespace detail {
+
+template <int N, class ArgumentVector, class ResultVector>
+class OuterProductFunctor
+{
+public:
+    typedef ArgumentVector argument_type;
+    typedef ResultVector result_type;
+    typedef typename ArgumentVector::value_type ValueType;
+    
+    result_type operator()(argument_type const & in) const
+    {
+        result_type res;
+        for(int b=0, i=0; i<N; ++i)
+        {
+            for(int j=i; j<N; ++j, ++b)
+            {
+                res[b] = detail::RequiresExplicitCast<ValueType>::cast(in[i]*in[j]);
+            }
+        }
+        return res;
+    }
+};
+
+template <int N, class ArgumentVector>
+class TensorTraceFunctor
+{
+public:
+
+    typedef ArgumentVector argument_type;
+    typedef typename ArgumentVector::value_type result_type;
+    
+    result_type exec(argument_type const & v, MetaInt<1>) const
+    {
+        return v[0];
+    }
+    
+    result_type exec(argument_type const & v, MetaInt<2>) const
+    {
+        return v[0] + v[2];
+    }
+    
+    result_type exec(argument_type const & v, MetaInt<3>) const
+    {
+        return v[0] + v[3] + v[5];
+    }
+    
+    template <int N2>
+    void exec(argument_type const & v, result_type & r, MetaInt<N2>) const
+    {
+        vigra_fail("tensorTraceMultiArray(): Sorry, can only handle dimensions up to 3.");
+    }
+
+    result_type operator()( const argument_type & a ) const
+    {
+        return exec(a, MetaInt<N>());
+    }
+};
+
+template <int N, class ArgumentVector, class ResultVector>
+class EigenvaluesFunctor
+{
+public:
+
+    typedef ArgumentVector argument_type;
+    typedef ResultVector result_type;
+    
+    void exec(argument_type const & v, result_type & r, MetaInt<1>) const
+    {
+        symmetric2x2Eigenvalues(v[0], &r[0]);
+    }
+    
+    void exec(argument_type const & v, result_type & r, MetaInt<2>) const
+    {
+        symmetric2x2Eigenvalues(v[0], v[1], v[2], &r[0], &r[1]);
+    }
+    
+    void exec(argument_type const & v, result_type & r, MetaInt<3>) const
+    {
+        symmetric3x3Eigenvalues(v[0], v[1], v[2], v[3], v[4], v[5], &r[0], &r[1], &r[2]);
+    }
+    
+    template <int N2>
+    void exec(argument_type const & v, result_type & r, MetaInt<N2>) const
+    {
+        vigra_fail("tensorEigenvaluesMultiArray(): Sorry, can only handle dimensions up to 3.");
+    }
+
+    result_type operator()( const argument_type & a ) const
+    {
+        result_type res;
+        exec(a, res, MetaInt<N>());
+        return res;
+    }
+};
+
+
+template <int N, class ArgumentVector>
+class DeterminantFunctor
+{
+public:
+
+    typedef ArgumentVector argument_type;
+    typedef typename ArgumentVector::value_type result_type;
+    
+    result_type exec(argument_type const & v, MetaInt<1>) const
+    {
+        return v[0];
+    }
+    
+    result_type exec(argument_type const & v, MetaInt<2>) const
+    {
+        return v[0]*v[2] - sq(v[1]);
+    }
+    
+    result_type exec(argument_type const & v, MetaInt<3>) const
+    {
+        result_type r0, r1, r2;
+        symmetric3x3Eigenvalues(v[0], v[1], v[2], v[3], v[4], v[5], &r0, &r1, &r2);
+        return r0*r1*r2;
+    }
+    
+    template <int N2>
+    void exec(argument_type const & v, result_type & r, MetaInt<N2>) const
+    {
+        vigra_fail("tensorDeterminantMultiArray(): Sorry, can only handle dimensions up to 3.");
+    }
+
+    result_type operator()( const argument_type & a ) const
+    {
+        return exec(a, MetaInt<N>());
+    }
+};
+
+} // namespace detail
+
+
+/** \addtogroup MultiPointoperators
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                vectorToTensorMultiArray              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the tensor (outer) product of a N-D vector with itself.
+
+    This function is useful to transform vector arrays into a tensor representation 
+    that can be used as input to tensor based processing and analysis functions
+    (e.g. tensor smoothing). When the input array has N dimensions, the input value_type 
+    must be a vector of length N, whereas the output value_type mus be vectors of length 
+    N*(N-1)/2 which will represent the upper triangular part of the resulting (symmetric) 
+    tensor. That is, for 2D arrays the output contains the elements 
+    <tt>[t11, t12 == t21, t22]</tt> in this order, whereas it contains the elements
+    <tt>[t11, t12, t13, t22, t23, t33]</tt> for 3D arrays.
+    
+    Currently, <tt>N <= 3</tt> is required.
+    
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void 
+        vectorToTensorMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                 MultiArrayView<N, T2, S2> dest);
+    }
+    \endcode
+
+    \deprecatedAPI{vectorToTensorMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        vectorToTensorMultiArray(SrcIterator  si, SrcShape const & shape, SrcAccessor src,
+                                 DestIterator di, DestAccessor dest);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        vectorToTensorMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> s,
+                                 pair<DestIterator, DestAccessor> d);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_tensorutilities.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<3, float>                  vol(shape);
+    MultiArray<3, TinyVector<float, 3> >  gradient(shape);
+    MultiArray<3, TinyVector<float, 6> >  tensor(shape);
+    
+    gaussianGradientMultiArray(vol, gradient, 2.0);
+    vectorToTensorMultiArray(gradient, tensor);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void vectorToTensorMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void 
+vectorToTensorMultiArray(SrcIterator  si, SrcShape const & shape, SrcAccessor src,
+                         DestIterator di, DestAccessor dest)
+{
+    static const int N = SrcShape::static_size;
+    static const int M = N*(N+1)/2;
+    
+    typedef typename SrcAccessor::value_type  SrcType;
+    typedef typename DestAccessor::value_type DestType;
+
+    for(int k=0; k<N; ++k)
+        if(shape[k] <=0)
+            return;
+
+    vigra_precondition(N == (int)src.size(si),
+        "vectorToTensorMultiArray(): Wrong number of channels in input array.");
+    vigra_precondition(M == (int)dest.size(di),
+        "vectorToTensorMultiArray(): Wrong number of channels in output array.");
+
+    transformMultiArray(si, shape, src, di, dest, 
+                        detail::OuterProductFunctor<N, SrcType, DestType>());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+vectorToTensorMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> s,
+                         pair<DestIterator, DestAccessor> d)
+{
+    vectorToTensorMultiArray(s.first, s.second, s.third, d.first, d.second);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void 
+vectorToTensorMultiArray(MultiArrayView<N, T1, S1> const & source,
+                         MultiArrayView<N, T2, S2> dest)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "vectorToTensorMultiArray(): shape mismatch between input and output.");
+    vectorToTensorMultiArray(srcMultiArrayRange(source), destMultiArray(dest));
+}
+
+/********************************************************/
+/*                                                      */
+/*                tensorTraceMultiArray                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the tensor trace for every element of a N-D tensor array.
+
+    This function turns a N-D tensor (whose value_type is a vector of length N*(N+1)/2, 
+    see \ref vectorToTensorMultiArray()) representing the upper triangular part of a 
+    symmetric tensor into a scalar array holding the tensor trace.
+    
+    Currently, <tt>N <= 3</tt> is required.
+    
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void 
+        tensorTraceMultiArray(MultiArrayView<N, T1, S1> const & source,
+                              MultiArrayView<N, T2, S2> dest);
+    }
+    \endcode
+
+    \deprecatedAPI{tensorTraceMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        tensorTraceMultiArray(SrcIterator si,  SrcShape const & shape, SrcAccessor src,
+                              DestIterator di, DestAccessor dest);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        tensorTraceMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> s,
+                              pair<DestIterator, DestAccessor> d);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_tensorutilities.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<3, float>                  vol(shape);
+    MultiArray<3, TinyVector<float, 6> >  hessian(shape);
+    MultiArray<3, float>                  trace(shape);
+    
+    hessianOfGaussianMultiArray(vol, hessian, 2.0);
+    tensorTraceMultiArray(hessian, trace);
+    \endcode
+
+    <b> Preconditions:</b>
+
+    <tt>N == 2</tt> or <tt>N == 3</tt>
+*/
+doxygen_overloaded_function(template <...> void tensorTraceMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void 
+tensorTraceMultiArray(SrcIterator si,  SrcShape const & shape, SrcAccessor src,
+                      DestIterator di, DestAccessor dest)
+{
+    static const int N = SrcShape::static_size;
+    typedef typename SrcAccessor::value_type  SrcType;
+
+    transformMultiArray(si, shape, src, di, dest, 
+                        detail::TensorTraceFunctor<N, SrcType>());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+tensorTraceMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> s,
+                      pair<DestIterator, DestAccessor> d)
+{
+    tensorTraceMultiArray(s.first, s.second, s.third, d.first, d.second);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void 
+tensorTraceMultiArray(MultiArrayView<N, T1, S1> const & source,
+                      MultiArrayView<N, T2, S2> dest)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "tensorTraceMultiArray(): shape mismatch between input and output.");
+    tensorTraceMultiArray(srcMultiArrayRange(source), destMultiArray(dest));
+}
+
+
+/********************************************************/
+/*                                                      */
+/*             tensorEigenvaluesMultiArray              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the tensor eigenvalues for every element of a N-D tensor array.
+
+    This function turns a N-D tensor (whose value_type is a vector of length N*(N+1)/2, 
+    see \ref vectorToTensorMultiArray()) representing the upper triangular part of a 
+    symmetric tensor into a vector-valued array holding the tensor eigenvalues (thus,
+    the destination value_type must be vectors of length N).
+    
+    Currently, <tt>N <= 3</tt> is required.
+    
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void 
+        tensorEigenvaluesMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                    MultiArrayView<N, T2, S2> dest);
+    }
+    \endcode
+
+    \deprecatedAPI{tensorEigenvaluesMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        tensorEigenvaluesMultiArray(SrcIterator si,  SrcShape const & shape, SrcAccessor src,
+                                    DestIterator di, DestAccessor dest);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        tensorEigenvaluesMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> s,
+                                    pair<DestIterator, DestAccessor> d);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage (MultiArrayView API):</b>
+
+    <b>\#include</b> \<vigra/multi_tensorutilities.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<3, float>                  vol(shape);
+    MultiArray<3, TinyVector<float, 6> >  hessian(shape);
+    MultiArray<3, TinyVector<float, 3> >  eigenvalues(shape);
+    
+    hessianOfGaussianMultiArray(vol, hessian, 2.0);
+    tensorEigenvaluesMultiArray(hessian, eigenvalues);
+    \endcode
+
+    <b> Preconditions:</b>
+
+    <tt>N == 2</tt> or <tt>N == 3</tt>
+*/
+doxygen_overloaded_function(template <...> void tensorEigenvaluesMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void 
+tensorEigenvaluesMultiArray(SrcIterator si,  SrcShape const & shape, SrcAccessor src,
+                            DestIterator di, DestAccessor dest)
+{
+    static const int N = SrcShape::static_size;
+    static const int M = N*(N+1)/2;
+    
+    typedef typename SrcAccessor::value_type  SrcType;
+    typedef typename DestAccessor::value_type DestType;
+
+    for(int k=0; k<N; ++k)
+        if(shape[k] <=0)
+            return;
+
+    vigra_precondition(M == (int)src.size(si),
+        "tensorEigenvaluesMultiArray(): Wrong number of channels in input array.");
+    vigra_precondition(N == (int)dest.size(di),
+        "tensorEigenvaluesMultiArray(): Wrong number of channels in output array.");
+
+    transformMultiArray(si, shape, src, di, dest, 
+                        detail::EigenvaluesFunctor<N, SrcType, DestType>());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+tensorEigenvaluesMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> s,
+                            pair<DestIterator, DestAccessor> d)
+{
+    tensorEigenvaluesMultiArray(s.first, s.second, s.third, d.first, d.second);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void 
+tensorEigenvaluesMultiArray(MultiArrayView<N, T1, S1> const & source,
+                            MultiArrayView<N, T2, S2> dest)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "tensorEigenvaluesMultiArray(): shape mismatch between input and output.");
+    tensorEigenvaluesMultiArray(srcMultiArrayRange(source), destMultiArray(dest));
+}
+
+/********************************************************/
+/*                                                      */
+/*             tensorDeterminantMultiArray              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the tensor determinant for every element of a ND tensor array.
+
+    This function turns a N-D tensor (whose value_type is a vector of length N*(N+1)/2, 
+    see \ref vectorToTensorMultiArray()) representing the upper triangular part of a 
+    symmetric tensor into the a scalar array holding the tensor determinant.
+    
+    Currently, <tt>N <= 3</tt> is required.
+    
+    <b> Declarations:</b>
+
+    pass arbitrary-dimensional array views:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T1, class S1,
+                                  class T2, class S2>
+        void 
+        tensorDeterminantMultiArray(MultiArrayView<N, T1, S1> const & source,
+                                    MultiArrayView<N, T2, S2> dest);
+    }
+    \endcode
+
+    \deprecatedAPI{tensorDeterminantMultiArray}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        tensorDeterminantMultiArray(SrcIterator si,  SrcShape const & shape, SrcAccessor src,
+                                    DestIterator di, DestAccessor dest);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcShape, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        tensorDeterminantMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> s,
+                                    pair<DestIterator, DestAccessor> d);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage (MultiArrayView API):</b>
+
+    <b>\#include</b> \<vigra/multi_tensorutilities.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<3, float>                  vol(shape);
+    MultiArray<3, TinyVector<float, 6> >  hessian(shape);
+    MultiArray<3, float>                  determinant(shape);
+    
+    hessianOfGaussianMultiArray(vol, hessian, 2.0);
+    tensorDeterminantMultiArray(hessian, determinant);
+    \endcode
+
+    <b> Preconditions:</b>
+
+    <tt>N == 2</tt> or <tt>N == 3</tt>
+*/
+doxygen_overloaded_function(template <...> void tensorDeterminantMultiArray)
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void 
+tensorDeterminantMultiArray(SrcIterator si,  SrcShape const & shape, SrcAccessor src,
+                            DestIterator di, DestAccessor dest)
+{
+    typedef typename SrcAccessor::value_type  SrcType;
+
+    static const int N = SrcShape::static_size;
+    static const int M = N*(N+1)/2;
+    
+    for(int k=0; k<N; ++k)
+        if(shape[k] <=0)
+            return;
+
+    vigra_precondition(M == (int)src.size(si),
+        "tensorDeterminantMultiArray(): Wrong number of channels in output array.");
+
+    transformMultiArray(si, shape, src, di, dest, 
+                        detail::DeterminantFunctor<N, SrcType>());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void 
+tensorDeterminantMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> s,
+                            pair<DestIterator, DestAccessor> d)
+{
+    tensorDeterminantMultiArray(s.first, s.second, s.third, d.first, d.second);
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline void 
+tensorDeterminantMultiArray(MultiArrayView<N, T1, S1> const & source,
+                            MultiArrayView<N, T2, S2> dest)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "tensorDeterminantMultiArray(): shape mismatch between input and output.");
+    tensorDeterminantMultiArray(srcMultiArrayRange(source), destMultiArray(dest));
+}
+
+//@}
+
+} // namespace vigra
+
+#endif /* VIGRA_MULTI_TENSORUTILITIES_HXX */
diff --git a/include/vigra/multi_watersheds.hxx b/include/vigra/multi_watersheds.hxx
new file mode 100644
index 0000000..5e1d24c
--- /dev/null
+++ b/include/vigra/multi_watersheds.hxx
@@ -0,0 +1,508 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2013 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_MULTI_WATERSHEDS_HXX
+#define VIGRA_MULTI_WATERSHEDS_HXX
+
+#include <functional>
+#include "mathutil.hxx"
+#include "multi_array.hxx"
+#include "multi_math.hxx"
+#include "multi_gridgraph.hxx"
+#include "multi_localminmax.hxx"
+#include "multi_labeling.hxx"
+#include "watersheds.hxx"
+#include "bucket_queue.hxx"
+#include "union_find.hxx"
+
+namespace vigra {
+
+/** \addtogroup SeededRegionGrowing
+*/
+//@{
+namespace lemon_graph {
+
+namespace graph_detail {
+
+template <class Graph, class T1Map, class T2Map>
+void
+prepareWatersheds(Graph const & g, 
+                  T1Map const & data,
+                  T2Map & lowestNeighborIndex)
+{
+    typedef typename Graph::NodeIt    graph_scanner;
+    typedef typename Graph::OutArcIt  neighbor_iterator;
+
+    for (graph_scanner node(g); node != INVALID; ++node) 
+    {
+        typename T1Map::value_type lowestValue  = data[*node];
+        typename T2Map::value_type lowestIndex  = -1;
+
+        for(neighbor_iterator arc(g, node); arc != INVALID; ++arc) 
+        {
+            if(data[g.target(*arc)] <= lowestValue)
+            {
+                lowestValue = data[g.target(*arc)];
+                lowestIndex = arc.neighborIndex();
+            }
+        }
+        lowestNeighborIndex[*node] = lowestIndex;
+    }
+}
+
+template <class Graph, class T1Map, class T2Map, class T3Map>
+typename T2Map::value_type
+unionFindWatersheds(Graph const & g,
+                    T1Map const & data, 
+                    T2Map const & lowestNeighborIndex,
+                    T3Map & labels)
+{
+    typedef typename Graph::NodeIt        graph_scanner;
+    typedef typename Graph::OutBackArcIt  neighbor_iterator;
+    typedef typename T3Map::value_type    LabelType;
+
+    vigra::detail::UnionFindArray<LabelType>  regions;
+
+    // pass 1: find connected components
+    for (graph_scanner node(g); node != INVALID; ++node) 
+    {
+        // define tentative label for current node
+        LabelType currentLabel = regions.nextFreeLabel();
+        bool hasPlateauNeighbor = false;
+        
+        for (neighbor_iterator arc(g, node); arc != INVALID; ++arc)
+        {
+            // merge regions if current target is center's lowest neighbor or vice versa
+            if(lowestNeighborIndex[*node] == arc.neighborIndex() || 
+               lowestNeighborIndex[g.target(*arc)] == g.oppositeIndex(arc.neighborIndex()))
+            {
+                if(data[*node] == data[g.target(*arc)])
+                    hasPlateauNeighbor = true;
+                LabelType neighborLabel = regions[labels[g.target(*arc)]];
+                currentLabel = regions.makeUnion(neighborLabel, currentLabel);
+            }
+        }
+        
+        if(hasPlateauNeighbor)
+        {
+            // we are on a plateau => link all plateau points
+            for (neighbor_iterator arc(g, node); arc != INVALID; ++arc)
+            {
+                if(data[*node] == data[g.target(*arc)])
+                {
+                    LabelType neighborLabel = regions[labels[g.target(*arc)]];
+                    currentLabel = regions.makeUnion(neighborLabel, currentLabel);
+                }
+            }
+        }
+        
+        // set label of current node
+        labels[*node] = regions.finalizeLabel(currentLabel);
+    }
+    
+    LabelType count = regions.makeContiguous();
+
+    // pass 2: make component labels contiguous
+    for (graph_scanner node(g); node != INVALID; ++node) 
+    {
+        labels[*node] = regions[labels[*node]];
+    }
+    return count;
+}
+
+template <class Graph, class T1Map, class T2Map>
+typename T2Map::value_type
+generateWatershedSeeds(Graph const & g, 
+                       T1Map const & data,
+                       T2Map & seeds,
+                       SeedOptions const & options = SeedOptions())
+{
+    typedef typename T1Map::value_type DataType;
+    typedef unsigned char MarkerType;
+    
+    typename Graph::template NodeMap<MarkerType>  minima(g);
+    
+    if(options.mini == SeedOptions::LevelSets)
+    {
+        vigra_precondition(options.thresholdIsValid<DataType>(),
+            "generateWatershedSeeds(): SeedOptions.levelSets() must be specified with threshold.");
+    
+        using namespace multi_math;
+        minima = data <= DataType(options.thresh);
+    }
+    else
+    {
+        DataType threshold = options.thresholdIsValid<DataType>()
+                                ? options.thresh
+                                : NumericTraits<DataType>::max();
+        
+        if(options.mini == SeedOptions::ExtendedMinima)
+            extendedLocalMinMaxGraph(g, data, minima, MarkerType(1), threshold, 
+                                     std::less<DataType>(), std::equal_to<DataType>(), true);
+        else
+            localMinMaxGraph(g, data, minima, MarkerType(1), threshold, 
+                             std::less<DataType>(), true);
+    }
+    return labelGraphWithBackground(g, minima, seeds, MarkerType(0), std::equal_to<MarkerType>());
+}
+
+
+template <class Graph, class T1Map, class T2Map>
+typename T2Map::value_type 
+seededWatersheds(Graph const & g, 
+                 T1Map const & data,
+                 T2Map & labels,
+                 WatershedOptions const & options)
+{
+    typedef typename Graph::Node        Node;
+    typedef typename Graph::NodeIt      graph_scanner;
+    typedef typename Graph::OutArcIt    neighbor_iterator;
+    typedef typename T1Map::value_type  CostType;
+    typedef typename T2Map::value_type  LabelType;
+
+    PriorityQueue<Node, CostType, true> pqueue;
+    
+    bool keepContours = ((options.terminate & KeepContours) != 0);
+    LabelType maxRegionLabel = 0;
+    
+    for (graph_scanner node(g); node != INVALID; ++node) 
+    {
+        LabelType label = labels[*node];
+        if(label != 0)
+        {
+            if(maxRegionLabel < label)
+                maxRegionLabel = label;
+                
+            for (neighbor_iterator arc(g, node); arc != INVALID; ++arc)
+            {
+                if(labels[g.target(*arc)] == 0)
+                {
+                    // register all seeds that have an unlabeled neighbor
+                    if(label == options.biased_label)
+                        pqueue.push(*node, data[*node] * options.bias);
+                    else
+                        pqueue.push(*node, data[*node]);
+                    break;
+                }
+            }
+        }
+    }
+    
+    LabelType contourLabel = maxRegionLabel + 1;  // temporary contour label
+    
+    // perform region growing
+    while(!pqueue.empty())
+    {
+        Node node = pqueue.top();
+        CostType cost = pqueue.topPriority();
+        pqueue.pop();
+        
+        if((options.terminate & StopAtThreshold) && (cost > options.max_cost))
+            break;
+
+        LabelType label = labels[node];
+        
+        if(label == contourLabel)
+            continue;
+
+        // Put the unlabeled neighbors in the priority queue.
+        for (neighbor_iterator arc(g, node); arc != INVALID; ++arc)
+        {
+            LabelType neighborLabel = labels[g.target(*arc)];
+            if(neighborLabel == 0)
+            {
+                labels[g.target(*arc)] = label;
+                CostType priority = (label == options.biased_label)
+                                       ? data[g.target(*arc)] * options.bias
+                                       : data[g.target(*arc)];
+                if(priority < cost)
+                    priority = cost;
+                pqueue.push(g.target(*arc), priority);
+            }
+            else if(keepContours && (label != neighborLabel) && (neighborLabel != contourLabel))
+            {
+                // The present neighbor is adjacent to more than one region
+                // => mark it as contour.
+                CostType priority = (neighborLabel == options.biased_label)
+                                       ? data[g.target(*arc)] * options.bias
+                                       : data[g.target(*arc)];
+                if(cost < priority) // neighbor not yet processed
+                    labels[g.target(*arc)] = contourLabel;
+            }
+        }
+    }
+    
+    if(keepContours)
+    {
+        // Replace the temporary contour label with label 0.
+        typename T2Map::iterator k   = labels.begin(),
+                                 end = labels.end();
+        for(; k != end; ++k)
+            if(*k == contourLabel)
+                *k = 0;
+    }
+    
+    return maxRegionLabel;
+}
+
+} // namespace graph_detail
+
+template <class Graph, class T1Map, class T2Map>
+typename T2Map::value_type 
+watershedsGraph(Graph const & g, 
+                T1Map const & data,
+                T2Map & labels,
+                WatershedOptions const & options)
+{
+    if(options.method == WatershedOptions::UnionFind)
+    {
+        vigra_precondition(g.maxDegree() <= NumericTraits<unsigned short>::max(),
+            "watershedsGraph(): cannot handle nodes with degree > 65535.");
+            
+        typename Graph::template NodeMap<unsigned short>  lowestNeighborIndex(g);
+        
+        graph_detail::prepareWatersheds(g, data, lowestNeighborIndex);
+        return graph_detail::unionFindWatersheds(g, data, lowestNeighborIndex, labels);
+    }
+    else if(options.method == WatershedOptions::RegionGrowing)
+    {
+        SeedOptions seed_options;
+        
+        // check if the user has explicitly requested seed computation
+        if(options.seed_options.mini != SeedOptions::Unspecified)
+        {
+            seed_options = options.seed_options;
+        }
+        else
+        {
+            // otherwise, don't compute seeds if 'labels' already contains them 
+            if(labels.any())
+                seed_options.mini = SeedOptions::Unspecified;
+        }
+
+        if(seed_options.mini != SeedOptions::Unspecified)
+        {
+            graph_detail::generateWatershedSeeds(g, data, labels, seed_options);
+        }
+        
+        return graph_detail::seededWatersheds(g, data, labels, options);
+    }
+    else
+    {
+        vigra_precondition(false,
+           "watershedsGraph(): invalid method in watershed options.");
+        return 0;
+    }
+}
+
+
+} // namespace lemon_graph
+
+    // documentation is in watersheds.hxx
+template <unsigned int N, class T, class S1,
+                          class Label, class S2>
+inline Label
+generateWatershedSeeds(MultiArrayView<N, T, S1> const & data,
+                       MultiArrayView<N, Label, S2> seeds,
+                       NeighborhoodType neighborhood = IndirectNeighborhood,
+                       SeedOptions const & options = SeedOptions())
+{
+    vigra_precondition(data.shape() == seeds.shape(),
+        "generateWatershedSeeds(): Shape mismatch between input and output.");
+    
+    GridGraph<N, undirected_tag> graph(data.shape(), neighborhood);
+    return lemon_graph::graph_detail::generateWatershedSeeds(graph, data, seeds, options);
+}
+
+
+/** \brief Watershed segmentation of an arbitrary-dimensional array.
+
+    This function implements variants of the watershed algorithms
+    described in
+
+    [1] L. Vincent and P. Soille: <em>"Watersheds in digital spaces: An efficient algorithm
+    based on immersion simulations"</em>, IEEE Trans. Patt. Analysis Mach. Intell. 13(6):583-598, 1991
+
+    [2] J. Roerdink, R. Meijster: <em>"The watershed transform: definitions, algorithms,
+    and parallelization strategies"</em>, Fundamenta Informaticae, 41:187-228, 2000
+
+    The source array \a data is a boundary indicator such as the gaussianGradientMagnitude()
+    or the trace of the \ref boundaryTensor(), and the destination \a labels is a label array
+    designating membership of each point in one of the regions found. Plateaus in the boundary
+    indicator are handled via simple tie breaking strategies. Argument \a neighborhood 
+    specifies the connectivity between points and can be <tt>DirectNeighborhood</tt> (meaning 
+    4-neighborhood in 2D and 6-neighborhood in 3D, default) or <tt>IndirectNeighborhood</tt> 
+    (meaning 8-neighborhood in 2D and 26-neighborhood in 3D).
+    
+    The watershed variant to be applied can be selected in the \ref WatershedOptions
+    object: When you call <tt>WatershedOptions::regionGrowing()</tt> (default), the flooding
+    algorithm from [1] is used. Alternatively, <tt>WatershedOptions::unionFind()</tt> uses
+    the scan-line algorithm 4.7 from [2]. The latter is faster, but does not support any options 
+    (if you pass options nonetheless, they are silently ignored).
+    
+    The region growing algorithm needs a seed for each region. Seeds can either be provided in
+    the destination array \a labels (which will then be overwritten with the result) or computed
+    automatically by an internal call to generateWatershedSeeds(). In the former case you have 
+    full control over seed placement, while the latter is more convenient. Automatic seed 
+    computation is performed when you provide seeding options via <tt>WatershedOptions::seedOptions()</tt> 
+    or when the array \a labels is empty (all zeros), in which case default seeding options 
+    are chosen. The destination image should be zero-initialized for automatic seed computation.
+    
+    Further options to be specified via \ref WatershedOptions are:
+    
+    <ul>
+    <li> <tt>keepContours()</tt>: Whether to keep a 1-pixel-wide contour (with label 0) between 
+         regions (otherwise, a complete grow is performed, i.e. all pixels are assigned to a region).
+    <li> <tt>stopAtThreshold()</tt>: Whether to stop growing when the boundaryness exceeds a threshold 
+         (remaining pixels keep label 0).
+    <li> <tt>biasLabel()</tt>: Whether one region (label) is to be preferred or discouraged by biasing its cost 
+         with a given factor (smaller than 1 for preference, larger than 1 for discouragement).
+    </ul>
+    
+    The option <tt>turboAlgorithm()</tt> is implied by method <tt>regionGrowing()</tt> (this is
+    in contrast to watershedsRegionGrowing(), which supports an additional algorithm in 2D only).
+
+    watershedsMultiArray() returns the number of regions found (= the highest region label, because 
+    labels start at 1). 
+
+    <b> Declaration:</b>
+
+    \code
+    namespace vigra {
+        template <unsigned int N, class T, class S1,
+                                  class Label, class S2>
+        Label
+        watershedsMultiArray(MultiArrayView<N, T, S1> const & data,
+                             MultiArrayView<N, Label, S2> labels,  // may also hold input seeds
+                             NeighborhoodType neighborhood = DirectNeighborhood,
+                             WatershedOptions const & options = WatershedOptions());
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_watersheds.hxx\><br>
+    Namespace: vigra
+
+    Example: watersheds of the gradient magnitude (the example works likewise for higher dimensions).
+
+    \code
+    MultiArray<2, unsigned char> src(Shape2(w, h));
+    ... // read input data
+    
+    // compute gradient magnitude at scale 1.0 as a boundary indicator
+    MultiArray<2, float> gradMag(src.shape());
+    gaussianGradientMagnitude(srcImageRange(src), destImage(gradMag), 1.0);
+
+    // example 1
+    {
+        // the pixel type of the destination image must be large enough to hold
+        // numbers up to 'max_region_label' to prevent overflow
+        MultiArray<2, unsigned int> labeling(src.shape());
+        
+        // call region-growing algorithm for 4-neighborhood, leave a 1-pixel boundary between 
+        // regions, and autogenerate seeds from all gradient minima where the magnitude is 
+        // less than 2.0.
+        unsigned int max_region_label = 
+              watershedsMultiArray(gradMag, labeling, DirectNeighborhood,
+                                   WatershedOptions().keepContours()
+                                      .seedOptions(SeedOptions().minima().threshold(2.0)));
+    }
+    
+    // example 2
+    {
+        MultiArray<2, unsigned int> labeling(src.shape());
+        
+        // compute seeds beforehand (use connected components of all pixels 
+        // where the gradient is below 4.0)
+        unsigned int max_region_label = generateWatershedSeeds(gradMag, labeling,
+                                                       SeedOptions().levelSets(4.0));
+        
+        // quantize the gradient image to 256 gray levels
+        float m, M;
+        gradMag.minmax(&m, &M);
+        
+        using namespace multi_math;
+        MultiArray<2, unsigned char> gradMag256(255.0 / (M - m) * (gradMag - m));
+        
+        // call region-growing algorithm with 8-neighborhood,
+        // since the data are 8-bit, a faster priority queue will be used
+        watershedsMultiArray(gradMag256, labeling, IndirectNeighborhood);
+    }
+    
+    // example 3
+    {
+        MultiArray<2, unsigned int> labeling(src.shape());
+        
+        .. // put seeds in 'labeling', e.g. from an interactive labeling program,
+           // make sure that label 1 corresponds to the background
+        
+        // bias the watershed algorithm so that the background is preferred
+        // by reducing the cost for label 1 to 90%
+        watershedsMultiArray(gradMag, labeling, 
+                             WatershedOptions().biasLabel(1, 0.9));
+    }
+    
+    // example 4
+    {
+        MultiArray<2, unsigned int> labeling(src.shape());
+        
+        // use the fast union-find algorithm with 4-neighborhood
+        watershedsMultiArray(gradMag, labeling, WatershedOptions().unionFind());
+    }
+    \endcode
+*/
+doxygen_overloaded_function(template <...> Label watershedsMultiArray)
+
+template <unsigned int N, class T, class S1,
+                          class Label, class S2>
+inline Label
+watershedsMultiArray(MultiArrayView<N, T, S1> const & data,
+                     MultiArrayView<N, Label, S2> labels,  // may also hold input seeds
+                     NeighborhoodType neighborhood = DirectNeighborhood,
+                     WatershedOptions const & options = WatershedOptions())
+{
+    vigra_precondition(data.shape() == labels.shape(),
+        "watershedsMultiArray(): Shape mismatch between input and output.");
+    
+    GridGraph<N, undirected_tag> graph(data.shape(), neighborhood);
+    return lemon_graph::watershedsGraph(graph, data, labels, options);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_MULTI_WATERSHEDS_HXX
diff --git a/include/vigra/navigator.hxx b/include/vigra/navigator.hxx
new file mode 100644
index 0000000..b882e05
--- /dev/null
+++ b/include/vigra/navigator.hxx
@@ -0,0 +1,435 @@
+/************************************************************************/
+/*                                                                      */
+/*                Copyright 2004 by Ullrich Koethe                      */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_NAVIGATOR_HXX
+#define VIGRA_NAVIGATOR_HXX
+
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/********************************************************/
+/*                                                      */
+/*                MultiArrayNavigator                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief A navigator that provides access to the 1D subranges of an
+    n-dimensional range given by a \ref vigra::MultiIterator and an nD shape.
+
+    Normally, the innermost loop of an iteration extends over the innermost
+    dimension of a given array. Sometimes, however, it is necessary to have
+    some other dimension in the inner loop. For example, instead of iterating over
+    the rows, the inner loop should extend over the columns. The class MultiArrayNavigator
+    encapsulates the necessary functionality. Given an arbitrary dimensional
+    array (represented by a vigra::MultiIterator/shape pair), and the desired
+    inner loop dimension <TT>d</TT>, it moves the encapsulated iterator to all possible
+    starting points of 1D subsets along the given dimension (e.g. all columns). By calling
+    <TT>begin()</TT> and <TT>end()</TT>, one can then obtain an STL-compatible 1-dimensional
+    iterator for the current subset.
+
+    The template parameters specify the embedded iterator type and its dimension.
+
+    <b>Usage:</b>
+
+    <b>\#include</b> \<vigra/navigator.hxx\>
+
+    Namespace: vigra
+
+    \code
+    typedef vigra::MultiArray<3, int>  Array;
+
+    Array a(Array::size_type(X, Y, Z));
+
+    typedef vigra::MultiArrayNavigator<Array::traverser, 3> Navigator;
+
+    for(int d=0; d<3; ++d)
+    {
+        // create Navigator for dimension d
+        Navigator nav(a.traverser_begin(), a.shape(), d);
+
+        // outer loop: move navigator to all starting points
+        // of 1D subsets that run parallel to coordinate axis d
+        for(; nav.hasMore(); ++nav)
+        {
+            // inner loop: linear iteration over current subset
+            //             d == {0, 1, 2}: iterate along {x, y, z}-axis respectively
+            Navigator::iterator i = nav.begin(), end = nav.end();
+            for(; i != end; ++i)
+                // do something
+        }
+    }
+    \endcode
+*/
+template <class MULTI_ITERATOR, unsigned int N>
+class MultiArrayNavigator
+#ifndef DOXYGEN  // doxygen doesn't understand this inheritance
+: public MultiArrayNavigator<MULTI_ITERATOR, N-1>
+#endif
+{
+    typedef MultiArrayNavigator<MULTI_ITERATOR, N-1> base_type;
+
+  public:
+    enum { level = N-1 };
+
+        /** The required shape type for the given iterator type.
+         */
+    typedef typename MULTI_ITERATOR::multi_difference_type shape_type;
+
+        /** The iterator type for the inner loop (result of begin() and end()).
+         */
+    typedef typename MULTI_ITERATOR::iterator iterator;
+
+        /** Construct navigator for multi-dimensional iterator <TT>i</TT>, array shape <TT>shape</TT>
+            and inner loop dimension <TT>inner_dimension</TT>.
+         */
+    MultiArrayNavigator(MULTI_ITERATOR const & i, shape_type const & shape, unsigned int inner_dimension)
+    : base_type(i, shape, inner_dimension)
+    {}
+
+    MultiArrayNavigator(MULTI_ITERATOR const & i, shape_type const & start, shape_type const & stop, 
+                        unsigned int inner_dimension)
+    : base_type(i, start, stop, inner_dimension)
+    {}
+
+        /** Advance to next starting location.
+         */
+    void operator++()
+    {
+        base_type::operator++();
+        if(this->point_[level-1] == this->stop_[level-1])
+        {
+            base_type::reset();
+            ++this->point_[level];
+            ++this->i_.template dim<level>();
+        }
+    }
+
+        /** Advance to next starting location.
+         */
+    void operator++(int)
+    {
+        ++*this;
+    }
+
+        /** true if there are more elements.
+         */
+    bool hasMore() const
+    {
+        return this->point_[level] < this->stop_[level];
+    }
+
+        /** true if iterator is exhausted.
+         */
+    bool atEnd() const
+    {
+        return this->point_[level] >= this->stop_[level];
+    }
+
+  protected:
+    void reset()
+    {
+        this->point_[level] = this->start_[level];
+        this->i_.template dim<level>() -= (this->stop_[level] - this->start_[level]);
+    }
+};
+
+template <class MULTI_ITERATOR>
+class MultiArrayNavigator<MULTI_ITERATOR, 1>
+{
+  public:
+    enum { level = 0 };
+    typedef typename MULTI_ITERATOR::multi_difference_type shape_type;
+    typedef typename MULTI_ITERATOR::iterator iterator;
+
+    MultiArrayNavigator(MULTI_ITERATOR const & i, shape_type const & shape, unsigned int inner_dimension)
+    : start_(), stop_(shape), point_(start_),
+      inner_dimension_(inner_dimension),
+      inner_shape_(stop_[inner_dimension] - start_[inner_dimension]),
+      i_(i + start_)
+    {
+        if(stop_[inner_dimension] > start_[inner_dimension])
+            stop_[inner_dimension] = start_[inner_dimension] + 1;
+    }
+
+    MultiArrayNavigator(MULTI_ITERATOR const & i, shape_type const & start, shape_type const & stop, 
+                        unsigned int inner_dimension)
+    : start_(start), stop_(stop), point_(start_),
+      inner_dimension_(inner_dimension),
+      inner_shape_(stop_[inner_dimension] - start_[inner_dimension]),
+      i_(i + start_)
+    {
+        if(stop_[inner_dimension] > start_[inner_dimension])
+            stop_[inner_dimension] = start_[inner_dimension] + 1;
+    }
+
+    void operator++()
+    {
+        ++point_[level];
+        ++i_.template dim<level>();
+    }
+
+    void operator++(int)
+    {
+        ++*this;
+    }
+
+    iterator begin() const
+    {
+        return i_.iteratorForDimension(inner_dimension_);
+    }
+
+    iterator end() const
+    {
+        return begin() + inner_shape_;
+    }
+
+    bool hasMore() const
+    {
+        return point_[level] < stop_[level];
+    }
+
+    bool atEnd() const
+    {
+        return point_[level] >= stop_[level];
+    }
+    
+    shape_type const & point() const
+    {
+        return point_;
+    }
+
+  protected:
+    void reset()
+    {
+        point_[level] = start_[level];
+        i_.template dim<level>() -= (stop_[level] - start_[level]);
+   }
+
+    shape_type start_, stop_, point_;
+    unsigned int inner_dimension_, inner_shape_;
+    MULTI_ITERATOR i_;
+};
+
+/********************************************************/
+/*                                                      */
+/*               MultiCoordinateNavigator               */
+/*                                                      */
+/********************************************************/
+
+/** \brief A navigator that provides access to the 1D subranges of an
+    n-dimensional range given by an nD shape.
+
+    This class works similarly to \ref MultiArrayNavigator, but instead of a 
+    1-dimensional iterator pair, it returns a pair of shapes whose difference
+    specifies a 1-dimensional range along the desired dimension. That is, when
+    the navigator refers to dimension <tt>d</tt>, the difference between
+    <tt>end()</tt> and <tt>begin()</tt> is <tt>1</tt> along all dimensions
+    except <tt>d</tt>.
+
+    The template parameters specifies the dimension of the shape.
+
+    <b>Usage:</b>
+
+    <b>\#include</b> \<vigra/navigator.hxx\>
+
+    Namespace: vigra
+
+    \code
+    typedef vigra::MultiArrayShape<3>::type Shape;
+    typedef vigra::MultiArray<3, int>  Array;
+    typedef vigra::MultiCoordinateNavigator<3> Navigator;
+
+    Array a(Shape(X, Y, Z));
+
+    for(int d=0; d<3; ++d)
+    {
+        // create Navigator for dimension d
+        Navigator nav(a.shape(), d);
+
+        // outer loop: move navigator to all starting points
+        // of 1D subsets that run parallel to coordinate axis d
+        for(; nav.hasMore(); ++nav)
+        {
+            // inner loop: linear iteration over current subset
+            //             d == {0, 1, 2}: iterate along {x, y, z}-axis respectively
+            Shape point = nav.begin(), end = nav.end();
+            for(; point[d] != end[d]; ++point[d])
+                a[point] = 5;
+        }
+    }
+    \endcode
+*/
+template <unsigned int Dimensions, unsigned int N = Dimensions>
+class MultiCoordinateNavigator
+#ifndef DOXYGEN  // doxygen doesn't understand this inheritance
+: public MultiCoordinateNavigator<Dimensions, N-1>
+#endif
+{
+    typedef MultiCoordinateNavigator<Dimensions, N-1> base_type;
+
+  public:
+    enum { level = N-1 };
+
+        /** The shape type for the given iterator type.
+         */
+    typedef typename MultiArrayShape<Dimensions>::type value_type;
+
+
+        /** Construct navigator for multi-dimensional iterator <TT>i</TT>, array shape <TT>shape</TT>
+            and inner loop dimension <TT>inner_dimension</TT>.
+         */
+    MultiCoordinateNavigator(value_type const & shape, unsigned int inner_dimension)
+    : base_type(shape, inner_dimension)
+    {
+        this->end_[level] = (this->inner_dimension_ == level)
+                                 ? 1
+                                 : this->shape_[level];
+    }
+
+        /** Advance to next starting location.
+         */
+    void operator++()
+    {
+        base_type::operator++();
+        if(base_type::atEnd() && this->i_[level] < this->end_[level])
+        {
+            ++this->i_[level];
+            if(this->i_[level] < this->end_[level])
+                base_type::reset();
+        }
+    }
+
+        /** Advance to next starting location.
+         */
+    void operator++(int)
+    {
+        ++*this;
+    }
+
+        /** true if there are more elements.
+         */
+    bool hasMore() const
+    {
+        return this->inner_dimension_ == level 
+                     ? base_type::hasMore() 
+                     : this->i_[level] < this->end_[level];
+    }
+
+        /** true if iterator is exhausted.
+         */
+    bool atEnd() const
+    {
+        return !hasMore();
+        // return this->inner_dimension_ == level 
+                     // ? base_type::atEnd()
+                     // : !(this->i_[level] < this->end_[level]);
+    }
+
+  protected:
+    void reset()
+    {
+        this->i_[level] = 0;
+        this->end_[level] = (this->inner_dimension_ == level)
+                                 ? 1
+                                 : this->shape_[level];
+        base_type::reset();
+    }
+};
+
+template <unsigned int Dimensions>
+class MultiCoordinateNavigator<Dimensions, 1>
+{
+  public:
+    enum { level = 0 };
+    typedef typename MultiArrayShape<Dimensions>::type value_type;
+ 
+    MultiCoordinateNavigator(value_type const & shape, unsigned int inner_dimension)
+    : shape_(shape),
+      inner_dimension_(inner_dimension)
+    {
+        end_[level] = (inner_dimension_ == level)
+                         ? 1
+                         : shape_[level];
+    }
+
+    void operator++()
+    {
+        ++i_[level];
+    }
+
+    void operator++(int)
+    {
+        ++*this;
+    }
+
+    value_type const & begin() const
+    {
+        return i_;
+    }
+
+    value_type end() const
+    {
+        value_type res = i_ + value_type(MultiArrayIndex(1));
+        res[inner_dimension_] = shape_[inner_dimension_];
+        return res;
+    }
+
+    bool hasMore() const
+    {
+        return i_[level] < end_[level];
+    }
+
+    bool atEnd() const
+    {
+      return !hasMore();
+    }
+
+  protected:
+    void reset()
+    {
+        i_[level] = 0;
+        end_[level] = (inner_dimension_ == level)
+                         ? 1
+                         : shape_[level];
+    }
+
+    value_type shape_, i_, end_;
+    unsigned int inner_dimension_;
+};
+
+} // namespace vigra
+
+#endif /* VIGRA_NAVIGATOR_HXX */
diff --git a/include/vigra/noise_normalization.hxx b/include/vigra/noise_normalization.hxx
new file mode 100644
index 0000000..56a67f6
--- /dev/null
+++ b/include/vigra/noise_normalization.hxx
@@ -0,0 +1,1752 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2006 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_NOISE_NORMALIZATION_HXX
+#define VIGRA_NOISE_NORMALIZATION_HXX
+
+#include "utilities.hxx"
+#include "tinyvector.hxx"
+#include "stdimage.hxx"
+#include "transformimage.hxx"
+#include "combineimages.hxx"
+#include "localminmax.hxx"
+#include "functorexpression.hxx"
+#include "numerictraits.hxx"
+#include "separableconvolution.hxx"
+#include "linear_solve.hxx"
+#include "array_vector.hxx"
+#include "static_assert.hxx"
+#include "multi_shape.hxx"
+
+#include <algorithm>
+
+namespace vigra {
+
+/** \addtogroup NoiseNormalization Noise Normalization
+    Estimate noise with intensity-dependent variance and transform it into additive Gaussian noise.
+*/
+//@{ 
+                                    
+/********************************************************/
+/*                                                      */
+/*               NoiseNormalizationOptions              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Pass options to one of the noise normalization functions.
+
+    <tt>NoiseNormalizationOptions</tt>  is an argument object that holds various optional
+    parameters used by the noise normalization functions. If a parameter is not explicitly
+    set, a suitable default will be used.
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/noise_normalization.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    MultiArray<2, float> src(w,h);
+    std::vector<TinyVector<double, 2> > result;
+    
+    ...
+    noiseVarianceEstimation(src, result, 
+                            NoiseNormalizationOptions().windowRadius(9).noiseVarianceInitialGuess(25.0));
+    \endcode
+*/
+class NoiseNormalizationOptions
+{
+  public:
+  
+        /** Initialize all options with default values.
+        */
+    NoiseNormalizationOptions()
+    : window_radius(6),
+      cluster_count(10),
+      noise_estimation_quantile(1.5),
+      averaging_quantile(0.8),
+      noise_variance_initial_guess(10.0),
+      use_gradient(true)
+    {}
+
+        /** Select the noise estimation algorithm.
+        
+            If \a r is <tt>true</tt>, use the gradient-based noise estimator according to Förstner (default).
+            Otherwise, use an algorithm that uses the intensity values directly.
+        */
+    NoiseNormalizationOptions & useGradient(bool r)
+    {
+        use_gradient = r;
+        return *this;
+    }
+
+        /** Set the window radius for a single noise estimate.
+            Every window of the given size gives raise to one intensity/variance pair.<br>
+            Default: 6 pixels
+        */
+    NoiseNormalizationOptions & windowRadius(unsigned int r)
+    {
+        vigra_precondition(r > 0,
+            "NoiseNormalizationOptions: window radius must be > 0.");
+        window_radius = r;
+        return *this;
+    }
+
+        /** Set the number of clusters for non-parametric noise normalization.
+            The intensity/variance pairs found are grouped into clusters before the noise
+            normalization transform is computed.<br>
+            Default: 10 clusters
+        */
+    NoiseNormalizationOptions & clusterCount(unsigned int c)
+    {
+        vigra_precondition(c > 0,
+            "NoiseNormalizationOptions: cluster count must be > 0.");
+        cluster_count = c;
+        return *this;
+    }
+
+        /** Set the quantile for cluster averaging.
+            After clustering, the cluster center (i.e. average noise variance as a function of the average
+            intensity in the cluster) is computed using only the cluster members whose estimated variance
+            is below \a quantile times the maximum variance in the cluster.<br>
+            Default: 0.8<br>
+            Precondition: 0 < \a quantile <= 1.0
+        */
+    NoiseNormalizationOptions & averagingQuantile(double quantile)
+    {
+        vigra_precondition(quantile > 0.0 && quantile <= 1.0,
+            "NoiseNormalizationOptions: averaging quantile must be between 0 and 1.");
+        averaging_quantile = quantile;
+        return *this;
+    }
+
+        /** Set the operating range of the robust noise estimator.
+            Intensity changes that are larger than \a quantile times the current estimate of the noise variance
+            are ignored by the robust noise estimator.<br>
+            Default: 1.5<br>
+            Precondition: 0 < \a quantile
+        */
+    NoiseNormalizationOptions & noiseEstimationQuantile(double quantile)
+    {
+        vigra_precondition(quantile > 0.0,
+            "NoiseNormalizationOptions: noise estimation quantile must be > 0.");
+        noise_estimation_quantile = quantile;
+        return *this;
+    }
+
+        /** Set the initial estimate of the noise variance.
+            Robust noise variance estimation is an iterative procedure starting at the given value.<br>
+            Default: 10.0<br>
+            Precondition: 0 < \a guess
+        */
+    NoiseNormalizationOptions & noiseVarianceInitialGuess(double guess)
+    {
+        vigra_precondition(guess > 0.0,
+            "NoiseNormalizationOptions: noise variance initial guess must be > 0.");
+        noise_variance_initial_guess = guess;
+        return *this;
+    }
+
+    unsigned int window_radius, cluster_count;
+    double noise_estimation_quantile, averaging_quantile, noise_variance_initial_guess;
+    bool use_gradient;
+};
+
+//@}
+
+template <class ArgumentType, class ResultType>
+class NonparametricNoiseNormalizationFunctor
+{
+    struct Segment
+    {
+        double lower, a, b, shift;
+    };
+
+    ArrayVector<Segment> segments_;
+
+    template <class T>
+    double exec(unsigned int k, T t) const
+    {
+        if(segments_[k].a == 0.0)
+        {
+            return t / VIGRA_CSTD::sqrt(segments_[k].b);
+        }
+        else
+        {
+            return 2.0 / segments_[k].a * VIGRA_CSTD::sqrt(std::max(0.0, segments_[k].a * t + segments_[k].b));
+        }
+    }
+
+  public:
+    typedef ArgumentType argument_type;
+    typedef ResultType result_type;
+
+    template <class Vector>
+    NonparametricNoiseNormalizationFunctor(Vector const & clusters)
+    : segments_(clusters.size()-1)
+    {
+        for(unsigned int k = 0; k<segments_.size(); ++k)
+        {
+            segments_[k].lower = clusters[k][0];
+            segments_[k].a = (clusters[k+1][1] - clusters[k][1]) / (clusters[k+1][0] - clusters[k][0]);
+            segments_[k].b = clusters[k][1] - segments_[k].a * clusters[k][0];
+            // FIXME: set a to zero if it is very small
+            //          - determine what 'very small' means
+            //          - shouldn't the two formulas (for a == 0, a != 0) be equal in the limit a -> 0 ?
+
+            if(k == 0)
+            {
+                segments_[k].shift = segments_[k].lower - exec(k, segments_[k].lower);
+            }
+            else
+            {
+                segments_[k].shift = exec(k-1, segments_[k].lower) - exec(k, segments_[k].lower) + segments_[k-1].shift;
+            }
+        }
+    }
+
+    result_type operator()(argument_type t) const
+    {
+        // find the segment
+        unsigned int k = 0;
+        for(; k < segments_.size(); ++k)
+            if(t < segments_[k].lower)
+                break;
+        if(k > 0)
+            --k;
+        return detail::RequiresExplicitCast<ResultType>::cast(exec(k, t) + segments_[k].shift);
+    }
+};
+
+template <class ArgumentType, class ResultType>
+class QuadraticNoiseNormalizationFunctor
+{
+    double a, b, c, d, f, o;
+
+    void init(double ia, double ib, double ic, double xmin)
+    {
+        a = ia;
+        b = ib;
+        c = ic;
+        d = VIGRA_CSTD::sqrt(VIGRA_CSTD::fabs(c));
+        if(c > 0.0)
+        {
+            o = VIGRA_CSTD::log(VIGRA_CSTD::fabs((2.0*c*xmin + b)/d + 2*VIGRA_CSTD::sqrt(c*sq(xmin) +b*xmin + a)))/d;
+            f = 0.0;
+        }
+        else
+        {
+            f = VIGRA_CSTD::sqrt(b*b - 4.0*a*c);
+            o = -VIGRA_CSTD::asin((2.0*c*xmin+b)/f)/d;
+        }
+    }
+
+  public:
+    typedef ArgumentType argument_type;
+    typedef ResultType result_type;
+
+    template <class Vector>
+    QuadraticNoiseNormalizationFunctor(Vector const & clusters)
+    {
+        double xmin = NumericTraits<double>::max();
+        Matrix<double> m(3,3), r(3, 1), l(3, 1);
+        for(unsigned int k = 0; k<clusters.size(); ++k)
+        {
+            l(0,0) = 1.0;
+            l(1,0) = clusters[k][0];
+            l(2,0) = sq(clusters[k][0]);
+            m += outer(l);
+            r += clusters[k][1]*l;
+            if(clusters[k][0] < xmin)
+                xmin = clusters[k][0];
+        }
+
+        linearSolve(m, r, l);
+        init(l(0,0), l(1,0), l(2,0), xmin);
+    }
+
+    result_type operator()(argument_type t) const
+    {
+        double r;
+        if(c > 0.0)
+            r = VIGRA_CSTD::log(VIGRA_CSTD::fabs((2.0*c*t + b)/d + 2.0*VIGRA_CSTD::sqrt(c*t*t +b*t + a)))/d-o;
+        else
+            r = -VIGRA_CSTD::asin((2.0*c*t+b)/f)/d-o;
+        return detail::RequiresExplicitCast<ResultType>::cast(r);
+    }
+};
+
+template <class ArgumentType, class ResultType>
+class LinearNoiseNormalizationFunctor
+{
+    double a, b, o;
+
+    void init(double ia, double ib, double xmin)
+    {
+        a = ia;
+        b = ib;
+        if(b != 0.0)
+        {
+            o = xmin - 2.0 / b * VIGRA_CSTD::sqrt(a + b * xmin);
+        }
+        else
+        {
+            o = xmin - xmin / VIGRA_CSTD::sqrt(a);
+        }
+    }
+
+  public:
+    typedef ArgumentType argument_type;
+    typedef ResultType result_type;
+
+    template <class Vector>
+    LinearNoiseNormalizationFunctor(Vector const & clusters)
+    {
+        double xmin = NumericTraits<double>::max();
+        Matrix<double> m(2,2), r(2, 1), l(2, 1);
+        for(unsigned int k = 0; k<clusters.size(); ++k)
+        {
+            l(0,0) = 1.0;
+            l(1,0) = clusters[k][0];
+            m += outer(l);
+            r += clusters[k][1]*l;
+            if(clusters[k][0] < xmin)
+                xmin = clusters[k][0];
+        }
+
+        linearSolve(m, r, l);
+        init(l(0,0), l(1,0), xmin);
+    }
+
+    result_type operator()(argument_type t) const
+    {
+        double r;
+        if(b != 0.0)
+            r = 2.0 / b * VIGRA_CSTD::sqrt(a + b*t) + o;
+        else
+            r =  t / VIGRA_CSTD::sqrt(a) + o;
+        return detail::RequiresExplicitCast<ResultType>::cast(r);
+    }
+};
+
+#define VIGRA_NoiseNormalizationFunctor(name, type, size) \
+template <class ResultType> \
+class name<type, ResultType> \
+{ \
+    ResultType lut_[size]; \
+    \
+  public: \
+    typedef type argument_type; \
+    typedef ResultType result_type; \
+     \
+    template <class Vector> \
+    name(Vector const & clusters) \
+    { \
+        name<double, ResultType> f(clusters); \
+         \
+        for(unsigned int k = 0; k < size; ++k) \
+        { \
+            lut_[k] = f(k); \
+        } \
+    } \
+     \
+    result_type operator()(argument_type t) const \
+    { \
+        return lut_[t]; \
+    } \
+};
+
+VIGRA_NoiseNormalizationFunctor(NonparametricNoiseNormalizationFunctor, UInt8, 256)
+VIGRA_NoiseNormalizationFunctor(NonparametricNoiseNormalizationFunctor, UInt16, 65536)
+VIGRA_NoiseNormalizationFunctor(QuadraticNoiseNormalizationFunctor, UInt8, 256)
+VIGRA_NoiseNormalizationFunctor(QuadraticNoiseNormalizationFunctor, UInt16, 65536)
+VIGRA_NoiseNormalizationFunctor(LinearNoiseNormalizationFunctor, UInt8, 256)
+VIGRA_NoiseNormalizationFunctor(LinearNoiseNormalizationFunctor, UInt16, 65536)
+
+#undef VIGRA_NoiseNormalizationFunctor
+
+namespace detail {
+
+template <class SrcIterator, class SrcAcessor,
+          class GradIterator>
+bool
+iterativeNoiseEstimationChi2(SrcIterator s, SrcAcessor src, GradIterator g,
+                         double & mean, double & variance,
+                         double robustnessThreshold, int windowRadius)
+{
+    double l2 = sq(robustnessThreshold);
+    double countThreshold = 1.0 - VIGRA_CSTD::exp(-l2);
+    double f = (1.0 - VIGRA_CSTD::exp(-l2)) / (1.0 - (1.0 + l2)*VIGRA_CSTD::exp(-l2));
+
+    Diff2D ul(-windowRadius, -windowRadius);
+    int r2 = sq(windowRadius);
+
+    for(int iter=0; iter<100 ; ++iter) // maximum iteration 100 only for terminating
+                                       // if something is wrong
+    {
+        double sum=0.0;
+        double gsum=0.0;
+        unsigned int count = 0;
+        unsigned int tcount = 0;
+
+        SrcIterator siy = s + ul;
+        GradIterator giy = g + ul;
+        for(int y=-windowRadius; y <= windowRadius; y++, ++siy.y, ++giy.y)
+        {
+            typename SrcIterator::row_iterator six = siy.rowIterator();
+            typename GradIterator::row_iterator gix = giy.rowIterator();
+            for(int x=-windowRadius; x <= windowRadius; x++, ++six, ++gix)
+            {
+                if (sq(x) + sq(y) > r2)
+                    continue;
+
+                ++tcount;
+                if (*gix < l2*variance)
+                {
+                    sum += src(six);
+                    gsum += *gix;
+                    ++count;
+                }
+            }
+        }
+        if (count==0) // not homogeneous enough
+            return false;
+
+        double oldvariance = variance;
+        variance= f * gsum / count;
+        mean = sum / count;
+
+        if ( closeAtTolerance(oldvariance - variance, 0.0, 1e-10))
+            return (count >= tcount * countThreshold / 2.0); // sufficiently many valid points
+    }
+    return false; // no convergence
+}
+
+template <class SrcIterator, class SrcAcessor,
+          class GradIterator>
+bool
+iterativeNoiseEstimationGauss(SrcIterator s, SrcAcessor src, GradIterator,
+                         double & mean, double & variance,
+                         double robustnessThreshold, int windowRadius)
+{
+    double l2 = sq(robustnessThreshold);
+    double countThreshold = erf(VIGRA_CSTD::sqrt(0.5 * l2));
+    double f = countThreshold / (countThreshold - VIGRA_CSTD::sqrt(2.0/M_PI*l2)*VIGRA_CSTD::exp(-l2/2.0));
+
+    mean = src(s);
+
+    Diff2D ul(-windowRadius, -windowRadius);
+    int r2 = sq(windowRadius);
+
+    for(int iter=0; iter<100 ; ++iter) // maximum iteration 100 only for terminating
+                                       // if something is wrong
+    {
+        double sum = 0.0;
+        double sum2 = 0.0;
+        unsigned int count = 0;
+        unsigned int tcount = 0;
+
+        SrcIterator siy = s + ul;
+        for(int y=-windowRadius; y <= windowRadius; y++, ++siy.y)
+        {
+            typename SrcIterator::row_iterator six = siy.rowIterator();
+            for(int x=-windowRadius; x <= windowRadius; x++, ++six)
+            {
+                if (sq(x) + sq(y) > r2)
+                    continue;
+
+                ++tcount;
+                if (sq(src(six) - mean) < l2*variance)
+                {
+                    sum += src(six);
+                    sum2 += sq(src(six));
+                    ++count;
+                }
+            }
+        }
+        if (count==0) // not homogeneous enough
+            return false;
+
+        double oldmean = mean;
+        double oldvariance = variance;
+        mean = sum / count;
+        variance= f * (sum2 / count - sq(mean));
+
+        if ( closeAtTolerance(oldmean - mean, 0.0, 1e-10) &&
+             closeAtTolerance(oldvariance - variance, 0.0, 1e-10))
+            return (count >= tcount * countThreshold / 2.0); // sufficiently many valid points
+    }
+    return false; // no convergence
+}
+
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+symmetricDifferenceSquaredMagnitude(
+     SrcIterator sul, SrcIterator slr, SrcAccessor src,
+     DestIterator dul, DestAccessor dest)
+{
+    using namespace functor;
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    typedef BasicImage<TmpType> TmpImage;
+
+    Kernel1D<double> mask;
+    mask.initSymmetricGradient();
+    mask.setBorderTreatment(BORDER_TREATMENT_REFLECT);
+
+    TmpImage dx(w, h), dy(w, h);
+    separableConvolveX(srcIterRange(sul, slr, src), destImage(dx),  kernel1d(mask));
+    separableConvolveY(srcIterRange(sul, slr, src), destImage(dy),  kernel1d(mask));
+    combineTwoImages(srcImageRange(dx), srcImage(dy), destIter(dul, dest), Arg1()*Arg1() + Arg2()*Arg2());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+findHomogeneousRegionsFoerstner(
+     SrcIterator sul, SrcIterator slr, SrcAccessor src,
+     DestIterator dul, DestAccessor dest,
+     unsigned int windowRadius = 6, double homogeneityThreshold = 40.0)
+{
+    using namespace vigra::functor;
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    BImage btmp(w, h);
+    transformImage(srcIterRange(sul, slr, src), destImage(btmp),
+                    ifThenElse(Arg1() <= Param(homogeneityThreshold), Param(1), Param(0)));
+
+    // Erosion
+    discErosion(srcImageRange(btmp), destIter(dul, dest), windowRadius);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+findHomogeneousRegions(
+     SrcIterator sul, SrcIterator slr, SrcAccessor src,
+     DestIterator dul, DestAccessor dest)
+{
+    localMinima(sul, slr, src, dul, dest);
+}
+
+template <class Vector1, class Vector2>
+void noiseVarianceListMedianCut(Vector1 const & noise, Vector2 & clusters,
+                                unsigned int maxClusterCount)
+{
+    typedef typename Vector2::value_type Result;
+
+    clusters.push_back(Result(0, noise.size()));
+
+    while(clusters.size() <= maxClusterCount)
+    {
+        // find biggest cluster
+        unsigned int kMax = 0;
+        double diffMax = 0.0;
+        for(unsigned int k=0; k < clusters.size(); ++k)
+        {
+            int k1 = clusters[k][0], k2 = clusters[k][1]-1;
+            
+#if 0       // turned the "internal error" in a postcondition message
+            // for the most likely case
+            std::string message("noiseVarianceListMedianCut(): internal error (");
+            message += std::string("k: ") + asString(k) + ", ";
+            message += std::string("k1: ") + asString(k1) + ", ";
+            message += std::string("k2: ") + asString(k2) + ", ";
+            message += std::string("noise.size(): ") + asString(noise.size()) + ", ";
+            message += std::string("clusters.size(): ") + asString(clusters.size()) + ").";
+            vigra_invariant(k1 >= 0 && k1 < (int)noise.size() && k2 >= 0 && k2 < (int)noise.size(), message.c_str());
+#endif
+            
+            vigra_postcondition(k1 >= 0 && k1 < (int)noise.size() && 
+                                k2 >= 0 && k2 < (int)noise.size(), 
+                "noiseVarianceClustering(): Unable to find homogeneous regions.");
+
+            double diff = noise[k2][0] - noise[k1][0];
+            if(diff > diffMax)
+            {
+                diffMax = diff;
+                kMax = k;
+            }
+        }
+
+        if(diffMax == 0.0)
+            return; // all clusters have only one value
+
+        unsigned int k1 = clusters[kMax][0],
+                     k2 = clusters[kMax][1];
+        unsigned int kSplit = k1 + (k2 - k1) / 2;
+        clusters[kMax][1] = kSplit;
+        clusters.push_back(Result(kSplit, k2));
+    }
+}
+
+struct SortNoiseByMean
+{
+    template <class T>
+    bool operator()(T const & l, T const & r) const
+    {
+        return l[0] < r[0];
+    }
+};
+
+struct SortNoiseByVariance
+{
+    template <class T>
+    bool operator()(T const & l, T const & r) const
+    {
+        return l[1] < r[1];
+    }
+};
+
+template <class Vector1, class Vector2, class Vector3>
+void noiseVarianceClusterAveraging(Vector1 & noise, Vector2 & clusters,
+                                   Vector3 & result, double quantile)
+{
+    typedef typename Vector1::iterator Iter;
+    typedef typename Vector3::value_type Result;
+
+    for(unsigned int k=0; k<clusters.size(); ++k)
+    {
+        Iter i1 = noise.begin() + clusters[k][0];
+        Iter i2 = noise.begin() + clusters[k][1];
+
+        std::sort(i1, i2, SortNoiseByVariance());
+
+        std::size_t size = static_cast<std::size_t>(VIGRA_CSTD::ceil(quantile*(i2 - i1)));
+        if(static_cast<std::size_t>(i2 - i1) < size)
+            size = i2 - i1;
+        if(size < 1)
+            size = 1;
+        i2 = i1 + size;
+
+        double mean = 0.0,
+               variance = 0.0;
+        for(; i1 < i2; ++i1)
+        {
+            mean += (*i1)[0];
+            variance += (*i1)[1];
+        }
+
+        result.push_back(Result(mean / size, variance / size));
+    }
+}
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+void noiseVarianceEstimationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                           BackInsertable & result,
+                           NoiseNormalizationOptions const & options)
+{
+    typedef typename BackInsertable::value_type ResultType;
+
+    unsigned int w = slr.x - sul.x;
+    unsigned int h = slr.y - sul.y;
+
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    typedef BasicImage<TmpType> TmpImage;
+
+    TmpImage gradient(w, h);
+    symmetricDifferenceSquaredMagnitude(sul, slr, src, gradient.upperLeft(), gradient.accessor());
+
+    BImage homogeneous(w, h);
+    findHomogeneousRegions(gradient.upperLeft(), gradient.lowerRight(), gradient.accessor(),
+                                   homogeneous.upperLeft(), homogeneous.accessor());
+
+    // Generate noise of each of the remaining pixels == centers of homogeneous areas (border is not used)
+    unsigned int windowRadius = options.window_radius;
+    for(unsigned int y=windowRadius; y<h-windowRadius; ++y)
+    {
+        for(unsigned int x=windowRadius; x<w-windowRadius; ++x)
+        {
+            if (! homogeneous(x, y))
+                continue;
+
+            Diff2D center(x, y);
+            double mean = 0.0, variance = options.noise_variance_initial_guess;
+
+            bool success;
+
+            if(options.use_gradient)
+            {
+                success = iterativeNoiseEstimationChi2(sul + center, src,
+                              gradient.upperLeft() + center, mean, variance,
+                              options.noise_estimation_quantile, windowRadius);
+            }
+            else
+            {
+                success = iterativeNoiseEstimationGauss(sul + center, src,
+                              gradient.upperLeft() + center, mean, variance,
+                              options.noise_estimation_quantile, windowRadius);
+            }
+            if (success)
+            {
+                result.push_back(ResultType(mean, variance));
+            }
+        }
+    }
+}
+
+template <class Vector, class BackInsertable>
+void noiseVarianceClusteringImpl(Vector & noise, BackInsertable & result,
+                           unsigned int clusterCount, double quantile)
+{
+    std::sort(noise.begin(), noise.end(), detail::SortNoiseByMean());
+
+    ArrayVector<TinyVector<unsigned int, 2> > clusters;
+    detail::noiseVarianceListMedianCut(noise, clusters, clusterCount);
+
+    std::sort(clusters.begin(), clusters.end(), detail::SortNoiseByMean());
+
+    detail::noiseVarianceClusterAveraging(noise, clusters, result, quantile);
+}
+
+template <class Functor,
+          class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+bool
+noiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                       DestIterator dul, DestAccessor dest,
+                       NoiseNormalizationOptions const & options)
+{
+    ArrayVector<TinyVector<double, 2> > noiseData;
+    noiseVarianceEstimationImpl(sul, slr, src, noiseData, options);
+
+    if(noiseData.size() < 10)
+        return false;
+
+    ArrayVector<TinyVector<double, 2> > noiseClusters;
+
+    noiseVarianceClusteringImpl(noiseData, noiseClusters,
+                                  options.cluster_count, options.averaging_quantile);
+
+    transformImage(sul, slr, src, dul, dest, Functor(noiseClusters));
+
+    return true;
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+bool
+nonparametricNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                    DestIterator dul, DestAccessor dest,
+                                    NoiseNormalizationOptions const & options,
+                                    VigraTrueType /* isScalar */)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+    typedef typename DestAccessor::value_type DestType;
+    return noiseNormalizationImpl<NonparametricNoiseNormalizationFunctor<SrcType, DestType> >
+                                                         (sul, slr, src, dul, dest, options);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+bool
+nonparametricNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                              DestIterator dul, DestAccessor dest,
+                              NoiseNormalizationOptions const & options,
+                              VigraFalseType /* isScalar */)
+{
+    int bands = src.size(sul);
+    for(int b=0; b<bands; ++b)
+    {
+        VectorElementAccessor<SrcAccessor> sband(b, src);
+        VectorElementAccessor<DestAccessor> dband(b, dest);
+        typedef typename VectorElementAccessor<SrcAccessor>::value_type SrcType;
+        typedef typename VectorElementAccessor<DestAccessor>::value_type DestType;
+
+        if(!noiseNormalizationImpl<NonparametricNoiseNormalizationFunctor<SrcType, DestType> >
+                                                           (sul, slr, sband, dul, dband, options))
+            return false;
+    }
+    return true;
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+bool
+quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                    DestIterator dul, DestAccessor dest,
+                                    NoiseNormalizationOptions const & options,
+                                    VigraTrueType /* isScalar */)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+    typedef typename DestAccessor::value_type DestType;
+    return noiseNormalizationImpl<QuadraticNoiseNormalizationFunctor<SrcType, DestType> >
+                                                         (sul, slr, src, dul, dest, options);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+bool
+quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                              DestIterator dul, DestAccessor dest,
+                              NoiseNormalizationOptions const & options,
+                              VigraFalseType /* isScalar */)
+{
+    int bands = src.size(sul);
+    for(int b=0; b<bands; ++b)
+    {
+        VectorElementAccessor<SrcAccessor> sband(b, src);
+        VectorElementAccessor<DestAccessor> dband(b, dest);
+        typedef typename VectorElementAccessor<SrcAccessor>::value_type SrcType;
+        typedef typename VectorElementAccessor<DestAccessor>::value_type DestType;
+
+        if(!noiseNormalizationImpl<QuadraticNoiseNormalizationFunctor<SrcType, DestType> >
+                                                           (sul, slr, sband, dul, dband, options))
+            return false;
+    }
+    return true;
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                              DestIterator dul, DestAccessor dest,
+                              double a0, double a1, double a2,
+                              VigraTrueType /* isScalar */)
+{
+    ArrayVector<TinyVector<double, 2> > noiseClusters;
+    noiseClusters.push_back(TinyVector<double, 2>(0.0, a0));
+    noiseClusters.push_back(TinyVector<double, 2>(1.0, a0 + a1 + a2));
+    noiseClusters.push_back(TinyVector<double, 2>(2.0, a0 + 2.0*a1 + 4.0*a2));
+    transformImage(sul, slr, src, dul, dest,
+                   QuadraticNoiseNormalizationFunctor<typename SrcAccessor::value_type,
+                                                   typename DestAccessor::value_type>(noiseClusters));
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                              DestIterator dul, DestAccessor dest,
+                              double a0, double a1, double a2,
+                              VigraFalseType /* isScalar */)
+{
+    int bands = src.size(sul);
+    for(int b=0; b<bands; ++b)
+    {
+        VectorElementAccessor<SrcAccessor> sband(b, src);
+        VectorElementAccessor<DestAccessor> dband(b, dest);
+        quadraticNoiseNormalizationImpl(sul, slr, sband, dul, dband, a0, a1, a2, VigraTrueType());
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+bool
+linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                    DestIterator dul, DestAccessor dest,
+                                    NoiseNormalizationOptions const & options,
+                                    VigraTrueType /* isScalar */)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+    typedef typename DestAccessor::value_type DestType;
+    return noiseNormalizationImpl<LinearNoiseNormalizationFunctor<SrcType, DestType> >
+                                                         (sul, slr, src, dul, dest, options);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+bool
+linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                              DestIterator dul, DestAccessor dest,
+                              NoiseNormalizationOptions const & options,
+                              VigraFalseType /* isScalar */)
+{
+    int bands = src.size(sul);
+    for(int b=0; b<bands; ++b)
+    {
+        VectorElementAccessor<SrcAccessor> sband(b, src);
+        VectorElementAccessor<DestAccessor> dband(b, dest);
+        typedef typename VectorElementAccessor<SrcAccessor>::value_type SrcType;
+        typedef typename VectorElementAccessor<DestAccessor>::value_type DestType;
+
+        if(!noiseNormalizationImpl<LinearNoiseNormalizationFunctor<SrcType, DestType> >
+                                                           (sul, slr, sband, dul, dband, options))
+            return false;
+    }
+    return true;
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                              DestIterator dul, DestAccessor dest,
+                              double a0, double a1,
+                              VigraTrueType /* isScalar */)
+{
+    ArrayVector<TinyVector<double, 2> > noiseClusters;
+    noiseClusters.push_back(TinyVector<double, 2>(0.0, a0));
+    noiseClusters.push_back(TinyVector<double, 2>(1.0, a0 + a1));
+    transformImage(sul, slr, src, dul, dest,
+                   LinearNoiseNormalizationFunctor<typename SrcAccessor::value_type,
+                                                   typename DestAccessor::value_type>(noiseClusters));
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                              DestIterator dul, DestAccessor dest,
+                              double a0, double a1,
+                              VigraFalseType /* isScalar */)
+{
+    int bands = src.size(sul);
+    for(int b=0; b<bands; ++b)
+    {
+        VectorElementAccessor<SrcAccessor> sband(b, src);
+        VectorElementAccessor<DestAccessor> dband(b, dest);
+        linearNoiseNormalizationImpl(sul, slr, sband, dul, dband, a0, a1, VigraTrueType());
+    }
+}
+
+} // namespace detail
+
+template <bool P>
+struct noiseVarianceEstimation_can_only_work_on_scalar_images
+: vigra::staticAssert::AssertBool<P>
+{};
+
+/** \addtogroup NoiseNormalization Noise Normalization
+    Estimate noise with intensity-dependent variance and transform it into additive Gaussian noise.
+*/
+//@{ 
+                                    
+/********************************************************/
+/*                                                      */
+/*                noiseVarianceEstimation               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Determine the noise variance as a function of the image intensity.
+
+    This operator applies an algorithm described in 
+    
+    W. Förstner: <i>"Image Preprocessing for Feature Extraction in Digital Intensity, Color and Range Images"</i>, 
+    Proc. Summer School on Data Analysis and the Statistical Foundations of Geomatics, 
+    Lecture Notes in Earth Science, Berlin: Springer, 1999
+    
+    in order to estimate the noise variance as a function of the image intensity in a robust way,
+    i.e. so that intensity changes due to edges do not bias the estimate. The source value type 
+    (<TT>SrcAccessor::value_type</TT>) must be a scalar type which is convertible to <tt>double</tt>.
+    The result is written into the \a result sequence, whose <tt>value_type</tt> must be constructible 
+    from two <tt>double</tt> values. The following options can be set via the \a options object 
+    (see \ref vigra::NoiseNormalizationOptions for details):<br><br>
+    
+    <tt>useGradient</tt>, <tt>windowRadius</tt>, <tt>noiseEstimationQuantile</tt>, <tt>noiseVarianceInitialGuess</tt>
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1, class BackInsertable>
+        void
+        noiseVarianceEstimation(MultiArrayView<2, T1, S1> const & src,
+                                BackInsertable & result,
+                                NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+    }
+    \endcode
+    
+    \deprecatedAPI{noiseVarianceEstimation}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void noiseVarianceEstimation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                     BackInsertable & result,
+                                     NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void noiseVarianceEstimation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                     BackInsertable & result,
+                                     NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/noise_normalization.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h);
+    std::vector<TinyVector<double, 2> > result;
+    
+    ...
+    noiseVarianceEstimation(src, result, 
+                            NoiseNormalizationOptions().windowRadius(9).noiseVarianceInitialGuess(25.0));
+    
+    // print the intensity / variance pairs found
+    for(int k=0; k<result.size(); ++k)
+        std::cout << "Intensity: " << result[k][0] << ", estimated variance: " << result[k][1] << std::endl;
+    \endcode
+
+    \deprecatedUsage{noiseVarianceEstimation}
+    \code
+    vigra::BImage src(w,h);
+    std::vector<vigra::TinyVector<double, 2> > result;
+    
+    ...
+    vigra::noiseVarianceEstimation(srcImageRange(src), result, 
+                                  vigra::NoiseNormalizationOptions().windowRadius(9).noiseVarianceInitialGuess(25.0));
+    
+    // print the intensity / variance pairs found
+    for(int k=0; k<result.size(); ++k)
+        std::cout << "Intensity: " << result[k][0] << ", estimated variance: " << result[k][1] << std::endl;
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator upperleft, lowerright;
+    SrcAccessor src;
+    
+    typedef SrcAccessor::value_type SrcType;
+    typedef NumericTraits<SrcType>::isScalar isScalar;
+    assert(isScalar::asBool == true);
+    
+    double value = src(uperleft);
+    
+    BackInsertable result;
+    typedef BackInsertable::value_type ResultType;    
+    double intensity, variance;
+    result.push_back(ResultType(intensity, variance));
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void noiseVarianceEstimation)
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+inline
+void noiseVarianceEstimation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                           BackInsertable & result,
+                           NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    typedef typename SrcAccessor::value_type SrcType;
+    typedef typename NumericTraits<SrcType>::isScalar isScalar;
+
+    VIGRA_STATIC_ASSERT((
+        noiseVarianceEstimation_can_only_work_on_scalar_images<(isScalar::asBool)>));
+
+    detail::noiseVarianceEstimationImpl(sul, slr, src, result, options);
+}
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+inline void
+noiseVarianceEstimation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        BackInsertable & result,
+                        NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    noiseVarianceEstimation(src.first, src.second, src.third, result, options);
+}
+
+template <class T1, class S1, class BackInsertable>
+inline void
+noiseVarianceEstimation(MultiArrayView<2, T1, S1> const & src,
+                        BackInsertable & result,
+                        NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    noiseVarianceEstimation(srcImageRange(src), result, options);
+}
+
+/********************************************************/
+/*                                                      */
+/*                noiseVarianceClustering               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Determine the noise variance as a function of the image intensity and cluster the results.
+
+    This operator first calls \ref noiseVarianceEstimation() to obtain a sequence of intensity/variance pairs,
+    which are then clustered using the median cut algorithm. Then the cluster centers (i.e. average variance vs.
+    average intensity) are determined and returned in the \a result sequence.
+    
+    In addition to the options valid for \ref noiseVarianceEstimation(), the following options can be set via 
+    the \a options object (see \ref vigra::NoiseNormalizationOptions for details):<br><br>
+    
+    <tt>clusterCount</tt>, <tt>averagingQuantile</tt>
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1, class BackInsertable>
+        void
+        noiseVarianceClustering(MultiArrayView<2, T1, S1> const & src,
+                                BackInsertable & result,
+                                NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+    }
+    \endcode
+    
+    \deprecatedAPI{noiseVarianceClustering}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void noiseVarianceClustering(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                BackInsertable & result,
+                                NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void noiseVarianceClustering(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                BackInsertable & result,
+                                NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/noise_normalization.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h);
+    std::vector<TinyVector<double, 2> > result;
+    
+    ...
+    noiseVarianceClustering(src, result, 
+                            NoiseNormalizationOptions().windowRadius(9).noiseVarianceInitialGuess(25.0).
+                            clusterCount(15));
+    
+    // print the intensity / variance pairs representing the cluster centers
+    for(int k=0; k<result.size(); ++k)
+        std::cout << "Cluster: " << k << ", intensity: " << result[k][0] << ", estimated variance: " << result[k][1] << std::endl;
+    \endcode
+
+    \deprecatedUsage{noiseVarianceClustering}
+    \code
+    vigra::BImage src(w,h);
+    std::vector<vigra::TinyVector<double, 2> > result;
+    
+    ...
+    vigra::noiseVarianceClustering(srcImageRange(src), result, 
+                                  vigra::NoiseNormalizationOptions().windowRadius(9).noiseVarianceInitialGuess(25.0).
+                                  clusterCount(15));
+    
+    // print the intensity / variance pairs representing the cluster centers
+    for(int k=0; k<result.size(); ++k)
+        std::cout << "Cluster: " << k << ", intensity: " << result[k][0] << ", estimated variance: " << result[k][1] << std::endl;
+    \endcode
+    <b> Required Interface:</b>
+    same as \ref noiseVarianceEstimation()
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void noiseVarianceClustering)
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+inline
+void noiseVarianceClustering(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                           BackInsertable & result,
+                           NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    ArrayVector<TinyVector<double, 2> > variance;
+    noiseVarianceEstimation(sul, slr, src, variance, options);
+    detail::noiseVarianceClusteringImpl(variance, result, options.cluster_count, options.averaging_quantile);
+}
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+inline void
+noiseVarianceClustering(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        BackInsertable & result,
+                        NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    noiseVarianceClustering(src.first, src.second, src.third, result, options);
+}
+
+template <class T1, class S1, class BackInsertable>
+inline void
+noiseVarianceClustering(MultiArrayView<2, T1, S1> const & src,
+                        BackInsertable & result,
+                        NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    noiseVarianceClustering(srcImageRange(src), result, options);
+}
+
+/********************************************************/
+/*                                                      */
+/*             nonparametricNoiseNormalization          */
+/*                                                      */
+/********************************************************/
+
+/** \brief Noise normalization by means of an estimated non-parametric noise model.
+
+    The original image is assumed to be corrupted by noise whose variance depends on the intensity in an unknown way.
+    The present functions first calls \ref noiseVarianceClustering() to obtain a sequence of intensity/variance pairs
+    (cluster centers) which estimate this dependency. The cluster centers are connected into a piecewise linear 
+    function which is the inverted according to the formula derived in 
+    
+    W. Förstner: <i>"Image Preprocessing for Feature Extraction in Digital Intensity, Color and Range Images"</i>, 
+    Proc. Summer School on Data Analysis and the Statistical Foundations of Geomatics, 
+    Lecture Notes in Earth Science, Berlin: Springer, 1999
+
+    The inverted formula defines a pixel-wise intensity transformation whose application turns the original image
+    into one that is corrupted by additive Gaussian noise with unit variance. Most subsequent algorithms will be able
+    to handle this type of noise much better than the original noise.
+    
+    RGB and other multiband images will be processed one band at a time. The function returns <tt>true</tt> on success.
+    Noise normalization will fail if the original image does not contain sufficiently homogeneous regions that
+    allow robust estimation of the noise variance.
+    
+    The \a options object may use all options described in \ref vigra::NoiseNormalizationOptions.
+    
+    The function returns <tt>false</tt> if the noise estimation failed, so that no normalization could be performed.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        bool
+        nonparametricNoiseNormalization(MultiArrayView<2, T1, S1> const & src,
+                                        MultiArrayView<2, T2, S2> dest,
+                                        NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+    }
+    \endcode
+    
+    \deprecatedAPI{nonparametricNoiseNormalization}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        bool nonparametricNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                             DestIterator dul, DestAccessor dest,
+                                             NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        bool nonparametricNoiseNormalization(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                             pair<DestIterator, DestAccessor> dest,
+                                             NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/noise_normalization.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, RGBValue<float> > src(w,h), dest(w, h);
+    
+    ...
+    nonparametricNoiseNormalization(src, dest, 
+                                    NoiseNormalizationOptions().windowRadius(9).noiseVarianceInitialGuess(25.0).
+                                    clusterCount(15));
+    \endcode
+
+    \deprecatedUsage{nonparametricNoiseNormalization}
+    \code
+    vigra::BRGBImage src(w,h), dest(w, h);
+    
+    ...
+    vigra::nonparametricNoiseNormalization(srcImageRange(src), destImage(dest), 
+                                           vigra::NoiseNormalizationOptions().windowRadius(9).noiseVarianceInitialGuess(25.0).
+                                           clusterCount(15));
+    \endcode
+    <b> Required Interface:</b>
+    same as \ref noiseVarianceEstimation()
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> bool nonparametricNoiseNormalization)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline bool
+nonparametricNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                DestIterator dul, DestAccessor dest,
+                                NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    return detail::nonparametricNoiseNormalizationImpl(sul, slr, src, dul, dest, options,
+                                         typename NumericTraits<SrcType>::isScalar());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline bool
+nonparametricNoiseNormalization(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                pair<DestIterator, DestAccessor> dest,
+                                NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    return nonparametricNoiseNormalization(src.first, src.second, src.third, dest.first, dest.second, options);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline bool
+nonparametricNoiseNormalization(MultiArrayView<2, T1, S1> const & src,
+                                MultiArrayView<2, T2, S2> dest,
+                                NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "nonparametricNoiseNormalization(): shape mismatch between input and output.");
+    return nonparametricNoiseNormalization(srcImageRange(src), destImage(dest), options);
+}
+
+/********************************************************/
+/*                                                      */
+/*               quadraticNoiseNormalization            */
+/*                                                      */
+/********************************************************/
+
+/** \brief Noise normalization by means of an estimated or given quadratic noise model.
+
+    This function works like \ref nonparametricNoiseNormalization() excapt that the model for the 
+    dependency between intensity and noise variance is assumed to be a 
+    quadratic function rather than a piecewise linear function. If the data conform to the quadratic model, 
+    this leads to a somewhat smoother transformation. The function returns <tt>false</tt> if the noise 
+    estimation failed, so that no normalization could be performed.
+
+    In the second variant of the function, the parameters of the quadratic model are not estimated, 
+    but explicitly given according to:
+    \code
+    variance = a0 + a1 * intensity + a2 * sq(intensity)
+    \endcode
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // estimate and apply a quadratic noise model
+        template <class T1, class S1,
+                  class T2, class S2>
+        bool
+        quadraticNoiseNormalization(MultiArrayView<2, T1, S1> const & src,
+                                    MultiArrayView<2, T2, S2> dest,
+                                    NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+        
+        // apply a given quadratic noise model
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        quadraticNoiseNormalization(MultiArrayView<2, T1, S1> const & src,
+                                    MultiArrayView<2, T2, S2> dest,
+                                    double a0, double a1, double a2);
+    }
+    \endcode
+    
+    \deprecatedAPI{quadraticNoiseNormalization}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // estimate and apply a quadratic noise model
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        bool quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                         DestIterator dul, DestAccessor dest,
+                                         NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+
+        // apply a given quadratic noise model
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                         DestIterator dul, DestAccessor dest,
+                                         double a0, double a1, double a2);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // estimate and apply a quadratic noise model
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        bool quadraticNoiseNormalization(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                         pair<DestIterator, DestAccessor> dest,
+                                         NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+
+        // apply a given quadratic noise model
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void quadraticNoiseNormalization(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                         pair<DestIterator, DestAccessor> dest,
+                                         double a0, double a1, double a2);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/noise_normalization.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, RGBValue<float> > src(w,h), dest(w, h);
+    
+    ...
+    // estimate the noise model and apply it to normalize the noise variance
+    bool success = quadraticNoiseNormalization(src, dest, 
+                                NoiseNormalizationOptions().windowRadius(9).noiseVarianceInitialGuess(25.0).
+                                clusterCount(15));
+    vigra_postcondition(success, "quadraticNoiseNormalization(): Unable to estimate noise model.");
+    
+    // apply a pre-computed noise model
+    quadraticNoiseNormalization(src, dest, 100, 0.02, 1e-6);
+    \endcode
+
+    \deprecatedUsage{quadraticNoiseNormalization}
+    \code
+    vigra::BRGBImage src(w,h), dest(w, h);
+    
+    ...
+    // estimate the noise model and apply it to normalize the noise variance
+    vigra::quadraticNoiseNormalization(srcImageRange(src), destImage(dest), 
+                                       vigra::NoiseNormalizationOptions().windowRadius(9).noiseVarianceInitialGuess(25.0).
+                                       clusterCount(15));
+
+    // apply a pre-computed noise model
+    vigra::quadraticNoiseNormalization(srcImageRange(src), destImage(dest), 
+                                       100, 0.02, 1e-6);
+    \endcode
+    \deprecatedEnd
+
+    <b> Required Interface:</b>
+    
+    The source value type must be convertible to <tt>double</tt> or must be a vector whose elements 
+    are convertible to <tt>double</tt>. Likewise, the destination type must be assignable from <tt>double</tt>
+    or a vector whose elements are assignable from <tt>double</tt>.
+*/
+doxygen_overloaded_function(template <...> bool quadraticNoiseNormalization)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline bool
+quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                            DestIterator dul, DestAccessor dest,
+                            NoiseNormalizationOptions const & options)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    return detail::quadraticNoiseNormalizationImpl(sul, slr, src, dul, dest, options,
+                                         typename NumericTraits<SrcType>::isScalar());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline bool
+quadraticNoiseNormalization(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<DestIterator, DestAccessor> dest,
+                            NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    return quadraticNoiseNormalization(src.first, src.second, src.third, dest.first, dest.second, options);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline bool
+quadraticNoiseNormalization(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "quadraticNoiseNormalization(): shape mismatch between input and output.");
+    return quadraticNoiseNormalization(srcImageRange(src), destImage(dest), options);
+}
+
+/********************************************************/
+/*                                                      */
+/*               quadraticNoiseNormalization            */
+/*                       (variant)                      */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                            DestIterator dul, DestAccessor dest,
+                            double a0, double a1, double a2)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    detail::quadraticNoiseNormalizationImpl(sul, slr, src, dul, dest, a0, a1, a2,
+                                         typename NumericTraits<SrcType>::isScalar());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+quadraticNoiseNormalization(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<DestIterator, DestAccessor> dest,
+                            double a0, double a1, double a2)
+{
+    quadraticNoiseNormalization(src.first, src.second, src.third, dest.first, dest.second, a0, a1, a2);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+quadraticNoiseNormalization(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            double a0, double a1, double a2)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "quadraticNoiseNormalization(): shape mismatch between input and output.");
+    quadraticNoiseNormalization(srcImageRange(src), destImage(dest), a0, a1, a2);
+}
+
+/********************************************************/
+/*                                                      */
+/*                linearNoiseNormalization              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Noise normalization by means of an estimated or given linear noise model.
+
+    This function works like \ref nonparametricNoiseNormalization() excapt that the model for the 
+    dependency between intensity and noise variance is assumed to be a 
+    linear function rather than a piecewise linear function. If the data conform to the linear model, 
+    this leads to a very simple transformation which is similar to the familiar gamma correction. 
+    The function returns <tt>false</tt> if the noise estimation failed, so that no 
+    normalization could be performed.
+
+    In the second variant of the function, the parameters of the linear model are not estimated, 
+    but explicitly given according to:
+    \code
+    variance = a0 + a1 * intensity
+    \endcode
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // estimate and apply a linear noise model
+        template <class T1, class S1,
+                  class T2, class S2>
+        bool
+        linearNoiseNormalization(MultiArrayView<2, T1, S1> const & src,
+                                 MultiArrayView<2, T2, S2> dest,
+                                 NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+
+        // apply a given linear noise model
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        linearNoiseNormalization(MultiArrayView<2, T1, S1> const & src,
+                                 MultiArrayView<2, T2, S2> dest,
+                                 double a0, double a1);
+    }
+    \endcode
+    
+    \deprecatedAPI{linearNoiseNormalization}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // estimate and apply a linear noise model
+        template <class SrcIterator, class SrcAccessor,
+                class DestIterator, class DestAccessor>
+        bool linearNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                      DestIterator dul, DestAccessor dest,
+                                      NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+
+        // apply a given linear noise model
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void linearNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                      DestIterator dul, DestAccessor dest,
+                                      double a0, double a1);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // estimate and apply a linear noise model
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        bool linearNoiseNormalization(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                      pair<DestIterator, DestAccessor> dest,
+                                      NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
+
+        // apply a given linear noise model
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void linearNoiseNormalization(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                      pair<DestIterator, DestAccessor> dest,
+                                      double a0, double a1);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/noise_normalization.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BRGBImage src(w,h), dest(w, h);
+    
+    ...
+    // estimate the noise model and apply it to normalize the noise variance
+    bool success = linearNoiseNormalization(src, dest, 
+                             NoiseNormalizationOptions().windowRadius(9).noiseVarianceInitialGuess(25.0).
+                             clusterCount(15));
+    vigra_postcondition(success, "linearNoiseNormalization(): Unable to estimate noise model.");
+    
+    // apply a pre-computed noise model
+    linearNoiseNormalization(src, dest, 100, 0.02);
+    \endcode
+
+    \deprecatedUsage{linearNoiseNormalization}
+    \code
+    vigra::BRGBImage src(w,h), dest(w, h);
+    
+    ...
+    // estimate the noise model and apply it to normalize the noise variance
+    vigra::linearNoiseNormalization(srcImageRange(src), destImage(dest), 
+                                    vigra::NoiseNormalizationOptions().windowRadius(9).noiseVarianceInitialGuess(25.0).
+                                    clusterCount(15));
+                                    
+    // apply a pre-computed noise model
+    vigra::linearNoiseNormalization(srcImageRange(src), destImage(dest), 
+                                    100, 0.02);
+    \endcode
+    \deprecatedEnd
+
+    <b> Required Interface:</b>
+    
+    The source value type must be convertible to <tt>double</tt> or must be a vector whose elements 
+    are convertible to <tt>double</tt>. Likewise, the destination type must be assignable from <tt>double</tt>
+    or a vector whose elements are assignable from <tt>double</tt>.
+*/
+doxygen_overloaded_function(template <...> bool linearNoiseNormalization)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline bool
+linearNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                DestIterator dul, DestAccessor dest,
+                                NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    return detail::linearNoiseNormalizationImpl(sul, slr, src, dul, dest, options,
+                                         typename NumericTraits<SrcType>::isScalar());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline bool
+linearNoiseNormalization(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                         pair<DestIterator, DestAccessor> dest,
+                         NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    return linearNoiseNormalization(src.first, src.second, src.third, dest.first, dest.second, options);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline bool
+linearNoiseNormalization(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest,
+                         NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "linearNoiseNormalization(): shape mismatch between input and output.");
+    return linearNoiseNormalization(srcImageRange(src), destImage(dest), options);
+}
+
+/********************************************************/
+/*                                                      */
+/*                 linearNoiseNormalization             */
+/*                       (variant)                      */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline
+void linearNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                              DestIterator dul, DestAccessor dest,
+                              double a0, double a1)
+{
+    typedef typename SrcAccessor::value_type SrcType;
+
+    detail::linearNoiseNormalizationImpl(sul, slr, src, dul, dest, a0, a1,
+                                         typename NumericTraits<SrcType>::isScalar());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+linearNoiseNormalization(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                         pair<DestIterator, DestAccessor> dest,
+                         double a0, double a1)
+{
+    linearNoiseNormalization(src.first, src.second, src.third, dest.first, dest.second, a0, a1);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+linearNoiseNormalization(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest,
+                         double a0, double a1)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "linearNoiseNormalization(): shape mismatch between input and output.");
+    linearNoiseNormalization(srcImageRange(src), destImage(dest), a0, a1);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_NOISE_NORMALIZATION_HXX
diff --git a/include/vigra/nonlineardiffusion.hxx b/include/vigra/nonlineardiffusion.hxx
new file mode 100644
index 0000000..1f3e5cb
--- /dev/null
+++ b/include/vigra/nonlineardiffusion.hxx
@@ -0,0 +1,777 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_NONLINEARDIFFUSION_HXX
+#define VIGRA_NONLINEARDIFFUSION_HXX
+
+#include <vector>
+#include "stdimage.hxx"
+#include "stdimagefunctions.hxx"
+#include "imageiteratoradapter.hxx"
+#include "functortraits.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+template <class SrcIterator, class SrcAccessor,
+          class CoeffIterator, class DestIterator>
+void internalNonlinearDiffusionDiagonalSolver(
+    SrcIterator sbegin, SrcIterator send, SrcAccessor sa,
+    CoeffIterator diag, CoeffIterator upper, CoeffIterator lower,
+    DestIterator dbegin)
+{
+    int w = send - sbegin - 1;
+    
+    int i;
+    
+    for(i=0; i<w; ++i)
+    {
+        lower[i] = lower[i] / diag[i];
+        
+        diag[i+1] = diag[i+1] - lower[i] * upper[i];
+    }
+    
+    dbegin[0] = sa(sbegin);
+    
+    for(i=1; i<=w; ++i)
+    {
+        dbegin[i] = sa(sbegin, i) - lower[i-1] * dbegin[i-1];
+    }
+    
+    dbegin[w] = dbegin[w] / diag[w];
+    
+    for(i=w-1; i>=0; --i)
+    {
+        dbegin[i] = (dbegin[i] - upper[i] * dbegin[i+1]) / diag[i];
+    }
+}
+
+
+template <class SrcIterator, class SrcAccessor,
+          class WeightIterator, class WeightAccessor,
+          class DestIterator, class DestAccessor>
+void internalNonlinearDiffusionAOSStep(
+                   SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                   WeightIterator wul, WeightAccessor aw,
+                   DestIterator dul, DestAccessor ad, double timestep)
+{
+    // use traits to determine SumType as to prevent possible overflow
+    typedef typename
+        NumericTraits<typename WeightAccessor::value_type>::RealPromote
+        WeightType;
+        
+    // calculate width and height of the image
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    int d = (w < h) ? h : w;
+
+    std::vector<WeightType> lower(d),
+                            diag(d),
+                            upper(d),
+                            res(d);
+
+    int x,y;
+    
+    WeightType one = NumericTraits<WeightType>::one();
+    
+     // create y iterators
+    SrcIterator ys = sul;
+    WeightIterator yw = wul;
+    DestIterator yd = dul;
+    
+    // x-direction
+    for(y=0; y<h; ++y, ++ys.y, ++yd.y, ++yw.y)
+    {
+        typename SrcIterator::row_iterator xs = ys.rowIterator();
+        typename WeightIterator::row_iterator xw = yw.rowIterator();
+        typename DestIterator::row_iterator xd = yd.rowIterator();
+
+        // fill 3-diag matrix
+        
+        diag[0] = one + timestep * (aw(xw) + aw(xw, 1));
+        for(x=1; x<w-1; ++x)
+        {
+            diag[x] = one + timestep * (2.0 * aw(xw, x) + aw(xw, x+1) + aw(xw, x-1));
+        }
+        diag[w-1] = one + timestep * (aw(xw, w-1) + aw(xw, w-2));
+
+        for(x=0; x<w-1; ++x)
+        {
+            lower[x] = -timestep * (aw(xw, x) + aw(xw, x+1));
+            upper[x] = lower[x];
+        }
+        
+        internalNonlinearDiffusionDiagonalSolver(xs, xs+w, as,
+                            diag.begin(), upper.begin(), lower.begin(), res.begin());
+                            
+        for(x=0; x<w; ++x, ++xd)
+        {
+            ad.set(res[x], xd);
+        }
+    }
+        
+    // y-direction
+    ys = sul;
+    yw = wul;
+    yd = dul;
+    
+    for(x=0; x<w; ++x, ++ys.x, ++yd.x, ++yw.x)
+    {
+        typename SrcIterator::column_iterator xs = ys.columnIterator();
+        typename WeightIterator::column_iterator xw = yw.columnIterator();
+        typename DestIterator::column_iterator xd = yd.columnIterator();
+
+        // fill 3-diag matrix
+        
+        diag[0] = one + timestep * (aw(xw) + aw(xw, 1));
+        for(y=1; y<h-1; ++y)
+        {
+            diag[y] = one + timestep * (2.0 * aw(xw, y) + aw(xw, y+1) + aw(xw, y-1));
+        }
+        diag[h-1] = one + timestep * (aw(xw, h-1) + aw(xw, h-2));
+
+        for(y=0; y<h-1; ++y)
+        {
+            lower[y] = -timestep * (aw(xw, y) + aw(xw, y+1));
+            upper[y] = lower[y];
+        }
+        
+        internalNonlinearDiffusionDiagonalSolver(xs, xs+h, as,
+                            diag.begin(), upper.begin(), lower.begin(), res.begin());
+                            
+        for(y=0; y<h; ++y, ++xd)
+        {
+            ad.set(0.5 * (ad(xd) + res[y]), xd);
+        }
+    }
+}
+
+/** \addtogroup NonLinearDiffusion Non-linear Diffusion and Total Variation
+    
+    Perform edge-preserving smoothing.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                  nonlinearDiffusion                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Perform edge-preserving smoothing at the given scale.
+
+    The algorithm solves the non-linear diffusion equation
+    
+    \f[
+        \frac{\partial}{\partial t} u =
+        \frac{\partial}{\partial x}
+          \left( g(|\nabla u|)
+                 \frac{\partial}{\partial x} u
+          \right)
+    \f]
+    
+    where <em> t</em> is the time, <b> x</b> is the location vector,
+    <em> u(</em><b> x</b><em> , t)</em> is the smoothed image at time <em> t</em>, and
+    <em> g(.)</em> is the location dependent diffusivity. At time zero, the image
+    <em> u(</em><b> x</b><em> , 0)</em> is simply the original image. The time is
+    proportional to the square of the scale parameter: \f$t = s^2\f$.
+    The diffusion equation is solved iteratively according
+    to the Additive Operator Splitting Scheme (AOS) from
+    
+    J. Weickert: <em>"Recursive Separable Schemes for Nonlinear Diffusion
+    Filters"</em>,
+    in: B. ter Haar Romeny, L. Florack, J. Koenderingk, M. Viergever (eds.):
+        1st Intl. Conf. on Scale-Space Theory in Computer Vision 1997,
+        Springer LNCS 1252
+
+    <TT>DiffusivityFunctor</TT> implements the gradient-dependent local diffusivity.
+    It is passed
+    as an argument to \ref gradientBasedTransform(). The return value must be
+    between 0 and 1 and determines the weight a pixel gets when
+    its neighbors are smoothed. Weickert recommends the use of the diffusivity
+    implemented by class \ref DiffusivityFunctor. It's also possible to use
+    other functors, for example one that always returns 1, in which case
+    we obtain the solution to the linear diffusion equation, i.e.
+    Gaussian convolution.
+    
+    The source value type must be a
+    linear space with internal addition, scalar multiplication, and
+    NumericTraits defined. The value_type of the DiffusivityFunctor must be the
+    scalar field over wich the source value type's linear space is defined.
+    
+    In addition to <TT>nonlinearDiffusion()</TT>, there is an algorithm
+    <TT>nonlinearDiffusionExplicit()</TT> which implements the Explicit Scheme
+    described in the above article. Both algorithms have the same interface,
+    but the explicit scheme gives slightly more accurate approximations of
+    the diffusion process at the cost of much slower processing.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class DiffusivityFunc>
+        void
+        nonlinearDiffusion(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, T2, S2> dest,
+                           DiffusivityFunc const & weight, double scale);
+                                   
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class DiffusivityFunc>
+        void
+        nonlinearDiffusionExplicit(MultiArrayView<2, T1, S1> const & src,
+                                   MultiArrayView<2, T2, S2> dest,
+                                   DiffusivityFunc const & weight, double scale);
+    }
+    \endcode
+    
+    \deprecatedAPI{nonlinearDiffusion}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class DiffusivityFunctor>
+        void nonlinearDiffusion(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                                DestIterator dul, DestAccessor ad,
+                                DiffusivityFunctor const & weight, double scale);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class DiffusivityFunctor>
+        void nonlinearDiffusion(
+                  triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                  pair<DestIterator, DestAccessor> dest,
+                  DiffusivityFunctor const & weight, double scale);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/nonlineardiffusion.hxx\><br/>
+    Namespace: vigra
+    
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);
+    float edge_threshold, scale;
+    ...
+    
+    nonlinearDiffusion(src, dest,
+                       DiffusivityFunctor<float>(edge_threshold), scale);
+    \endcode
+
+    \deprecatedUsage{nonlinearDiffusion}
+    \code
+    FImage src(w,h), dest(w,h);
+    float edge_threshold, scale;
+    ...
+    
+    nonlinearDiffusion(srcImageRange(src), destImage(dest),
+                       DiffusivityFunctor<float>(edge_threshold), scale);
+    \endcode
+    <b> Required Interface:</b>
+    <ul>
+    <li> <TT>SrcIterator</TT> and <TT>DestIterator</TT> are models of ImageIterator
+    <li> <TT>SrcAccessor</TT> and <TT>DestAccessor</TT> are models of StandardAccessor
+    <li> <TT>SrcAccessor::value_type</TT> is a linear space
+    <li> <TT>DiffusivityFunctor</TT> conforms to the requirements of
+          \ref gradientBasedTransform(). Its range is between 0 and 1.
+    <li> <TT>DiffusivityFunctor::value_type</TT> is an algebraic field
+    </ul>
+    \deprecatedEnd
+    
+    <b> Precondition:</b>
+    
+    <TT>scale > 0</TT>
+    
+    \see vigra::DiffusivityFunctor
+*/
+doxygen_overloaded_function(template <...> void nonlinearDiffusion)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DiffusivityFunc>
+void nonlinearDiffusion(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                   DestIterator dul, DestAccessor ad,
+                   DiffusivityFunc const & weight, double scale)
+{
+    vigra_precondition(scale > 0.0, "nonlinearDiffusion(): scale must be > 0");
+    
+    double total_time = scale*scale/2.0;
+    const double time_step = 5.0;
+    int number_of_steps = (int)(total_time / time_step);
+    double rest_time = total_time - time_step * number_of_steps;
+    
+    Size2D size(slr.x - sul.x, slr.y - sul.y);
+
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        TmpType;
+    typedef typename DiffusivityFunc::value_type WeightType;
+    
+    BasicImage<TmpType> smooth1(size);
+    BasicImage<TmpType> smooth2(size);
+    
+    BasicImage<WeightType> weights(size);
+    
+    typename BasicImage<TmpType>::Iterator s1 = smooth1.upperLeft(),
+                                  s2 = smooth2.upperLeft();
+    typename BasicImage<TmpType>::Accessor a = smooth1.accessor();
+    
+    typename BasicImage<WeightType>::Iterator wi = weights.upperLeft();
+    typename BasicImage<WeightType>::Accessor wa = weights.accessor();
+
+    gradientBasedTransform(sul, slr, as, wi, wa, weight);
+
+    internalNonlinearDiffusionAOSStep(sul, slr, as, wi, wa, s1, a, rest_time);
+
+    for(int i = 0; i < number_of_steps; ++i)
+    {
+        gradientBasedTransform(s1, s1+size, a, wi, wa, weight);
+                      
+        internalNonlinearDiffusionAOSStep(s1, s1+size, a, wi, wa, s2, a, time_step);
+    
+        std::swap(s1, s2);
+    }
+    
+    copyImage(s1, s1+size, a, dul, ad);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DiffusivityFunc>
+inline void
+nonlinearDiffusion(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   DiffusivityFunc const & weight, double scale)
+{
+    nonlinearDiffusion(src.first, src.second, src.third,
+                       dest.first, dest.second,
+                       weight, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class DiffusivityFunc>
+inline void
+nonlinearDiffusion(MultiArrayView<2, T1, S1> const & src,
+                   MultiArrayView<2, T2, S2> dest,
+                   DiffusivityFunc const & weight, double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "nonlinearDiffusion(): shape mismatch between input and output.");
+    nonlinearDiffusion(srcImageRange(src),
+                       destImage(dest),
+                       weight, scale);
+}
+
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class WeightIterator, class WeightAccessor,
+          class DestIterator, class DestAccessor>
+void internalNonlinearDiffusionExplicitStep(
+                   SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                   WeightIterator wul, WeightAccessor aw,
+                   DestIterator dul, DestAccessor ad,
+                   double time_step)
+{
+    // use traits to determine SumType as to prevent possible overflow
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        SumType;
+    
+    typedef typename
+        NumericTraits<typename WeightAccessor::value_type>::RealPromote
+        WeightType;
+        
+    // calculate width and height of the image
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    int x,y;
+    
+    const Diff2D left(-1, 0);
+    const Diff2D right(1, 0);
+    const Diff2D top(0, -1);
+    const Diff2D bottom(0, 1);
+    
+    WeightType gt, gb, gl, gr, g0;
+    WeightType one = NumericTraits<WeightType>::one();
+    SumType sum;
+    
+    time_step /= 2.0;
+    
+    // create y iterators
+    SrcIterator ys = sul;
+    WeightIterator yw = wul;
+    DestIterator yd = dul;
+        
+    SrcIterator xs = ys;
+    WeightIterator xw = yw;
+    DestIterator xd = yd;
+    
+    gt = (aw(xw) + aw(xw, bottom)) * time_step;
+    gb = (aw(xw) + aw(xw, bottom)) * time_step;
+    gl = (aw(xw) + aw(xw, right)) * time_step;
+    gr = (aw(xw) + aw(xw, right)) * time_step;
+    g0 = one - gt - gb - gr - gl;
+
+    sum = g0 * as(xs);
+    sum += gt * as(xs, bottom);
+    sum += gb * as(xs, bottom);
+    sum += gl * as(xs, right);
+    sum += gr * as(xs, right);
+
+    ad.set(sum, xd);
+
+    for(x=2, ++xs.x, ++xd.x, ++xw.x; x<w; ++x, ++xs.x, ++xd.x, ++xw.x)
+    {
+        gt = (aw(xw) + aw(xw, bottom)) * time_step;
+        gb = (aw(xw) + aw(xw, bottom)) * time_step;
+        gl = (aw(xw) + aw(xw, left)) * time_step;
+        gr = (aw(xw) + aw(xw, right)) * time_step;
+        g0 = one - gt - gb - gr - gl;
+
+        sum = g0 * as(xs);
+        sum += gt * as(xs, bottom);
+        sum += gb * as(xs, bottom);
+        sum += gl * as(xs, left);
+        sum += gr * as(xs, right);
+
+        ad.set(sum, xd);
+    }
+
+    gt = (aw(xw) + aw(xw, bottom)) * time_step;
+    gb = (aw(xw) + aw(xw, bottom)) * time_step;
+    gl = (aw(xw) + aw(xw, left)) * time_step;
+    gr = (aw(xw) + aw(xw, left)) * time_step;
+    g0 = one - gt - gb - gr - gl;
+
+    sum = g0 * as(xs);
+    sum += gt * as(xs, bottom);
+    sum += gb * as(xs, bottom);
+    sum += gl * as(xs, left);
+    sum += gr * as(xs, left);
+
+    ad.set(sum, xd);
+    
+    for(y=2, ++ys.y, ++yd.y, ++yw.y; y<h; ++y, ++ys.y, ++yd.y, ++yw.y)
+    {
+        xs = ys;
+        xd = yd;
+        xw = yw;
+        
+        gt = (aw(xw) + aw(xw, top)) * time_step;
+        gb = (aw(xw) + aw(xw, bottom)) * time_step;
+        gl = (aw(xw) + aw(xw, right)) * time_step;
+        gr = (aw(xw) + aw(xw, right)) * time_step;
+        g0 = one - gt - gb - gr - gl;
+
+        sum = g0 * as(xs);
+        sum += gt * as(xs, top);
+        sum += gb * as(xs, bottom);
+        sum += gl * as(xs, right);
+        sum += gr * as(xs, right);
+
+        ad.set(sum, xd);
+        
+        for(x=2, ++xs.x, ++xd.x, ++xw.x; x<w; ++x, ++xs.x, ++xd.x, ++xw.x)
+        {
+            gt = (aw(xw) + aw(xw, top)) * time_step;
+            gb = (aw(xw) + aw(xw, bottom)) * time_step;
+            gl = (aw(xw) + aw(xw, left)) * time_step;
+            gr = (aw(xw) + aw(xw, right)) * time_step;
+            g0 = one - gt - gb - gr - gl;
+            
+            sum = g0 * as(xs);
+            sum += gt * as(xs, top);
+            sum += gb * as(xs, bottom);
+            sum += gl * as(xs, left);
+            sum += gr * as(xs, right);
+            
+            ad.set(sum, xd);
+        }
+        
+        gt = (aw(xw) + aw(xw, top)) * time_step;
+        gb = (aw(xw) + aw(xw, bottom)) * time_step;
+        gl = (aw(xw) + aw(xw, left)) * time_step;
+        gr = (aw(xw) + aw(xw, left)) * time_step;
+        g0 = one - gt - gb - gr - gl;
+
+        sum = g0 * as(xs);
+        sum += gt * as(xs, top);
+        sum += gb * as(xs, bottom);
+        sum += gl * as(xs, left);
+        sum += gr * as(xs, left);
+
+        ad.set(sum, xd);
+    }
+    
+    xs = ys;
+    xd = yd;
+    xw = yw;
+
+    gt = (aw(xw) + aw(xw, top)) * time_step;
+    gb = (aw(xw) + aw(xw, top)) * time_step;
+    gl = (aw(xw) + aw(xw, right)) * time_step;
+    gr = (aw(xw) + aw(xw, right)) * time_step;
+    g0 = one - gt - gb - gr - gl;
+
+    sum = g0 * as(xs);
+    sum += gt * as(xs, top);
+    sum += gb * as(xs, top);
+    sum += gl * as(xs, right);
+    sum += gr * as(xs, right);
+
+    ad.set(sum, xd);
+
+    for(x=2, ++xs.x, ++xd.x, ++xw.x; x<w; ++x, ++xs.x, ++xd.x, ++xw.x)
+    {
+        gt = (aw(xw) + aw(xw, top)) * time_step;
+        gb = (aw(xw) + aw(xw, top)) * time_step;
+        gl = (aw(xw) + aw(xw, left)) * time_step;
+        gr = (aw(xw) + aw(xw, right)) * time_step;
+        g0 = one - gt - gb - gr - gl;
+
+        sum = g0 * as(xs);
+        sum += gt * as(xs, top);
+        sum += gb * as(xs, top);
+        sum += gl * as(xs, left);
+        sum += gr * as(xs, right);
+
+        ad.set(sum, xd);
+    }
+
+    gt = (aw(xw) + aw(xw, top)) * time_step;
+    gb = (aw(xw) + aw(xw, top)) * time_step;
+    gl = (aw(xw) + aw(xw, left)) * time_step;
+    gr = (aw(xw) + aw(xw, left)) * time_step;
+    g0 = one - gt - gb - gr - gl;
+
+    sum = g0 * as(xs);
+    sum += gt * as(xs, top);
+    sum += gb * as(xs, top);
+    sum += gl * as(xs, left);
+    sum += gr * as(xs, left);
+
+    ad.set(sum, xd);
+}
+
+/** \brief Perform edge-preserving smoothing at the given scale using an explicit scheme.
+
+    See \ref nonlinearDiffusion().
+*/
+doxygen_overloaded_function(template <...> void nonlinearDiffusionExplicit)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DiffusivityFunc>
+void nonlinearDiffusionExplicit(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                   DestIterator dul, DestAccessor ad,
+                   DiffusivityFunc const & weight, double scale)
+{
+    vigra_precondition(scale > 0.0, "nonlinearDiffusionExplicit(): scale must be > 0");
+    
+    double total_time = scale*scale/2.0;
+    const double time_step = 0.25;
+    int number_of_steps = total_time / time_step;
+    double rest_time = total_time - time_step * number_of_steps;
+    
+    Size2D size(slr.x - sul.x, slr.y - sul.y);
+
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        TmpType;
+    typedef typename DiffusivityFunc::value_type WeightType;
+    
+    BasicImage<TmpType> smooth1(size);
+    BasicImage<TmpType> smooth2(size);
+    
+    BasicImage<WeightType> weights(size);
+    
+    typename BasicImage<TmpType>::Iterator s1 = smooth1.upperLeft(),
+                                  s2 = smooth2.upperLeft();
+    typename BasicImage<TmpType>::Accessor a = smooth1.accessor();
+    
+    typename BasicImage<WeightType>::Iterator wi = weights.upperLeft();
+    typename BasicImage<WeightType>::Accessor wa = weights.accessor();
+
+    gradientBasedTransform(sul, slr, as, wi, wa, weight);
+
+    internalNonlinearDiffusionExplicitStep(sul, slr, as, wi, wa, s1, a, rest_time);
+
+    for(int i = 0; i < number_of_steps; ++i)
+    {
+        gradientBasedTransform(s1, s1+size, a, wi, wa, weight);
+                      
+        internalNonlinearDiffusionExplicitStep(s1, s1+size, a, wi, wa, s2, a, time_step);
+    
+        swap(s1, s2);
+    }
+    
+    copyImage(s1, s1+size, a, dul, ad);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class DiffusivityFunc>
+inline void
+nonlinearDiffusionExplicit(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                           pair<DestIterator, DestAccessor> dest,
+                           DiffusivityFunc const & weight, double scale)
+{
+    nonlinearDiffusionExplicit(src.first, src.second, src.third,
+                               dest.first, dest.second,
+                               weight, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class DiffusivityFunc>
+inline void
+nonlinearDiffusionExplicit(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, T2, S2> dest,
+                           DiffusivityFunc const & weight, double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "nonlinearDiffusionExplicit(): shape mismatch between input and output.");
+    nonlinearDiffusionExplicit(srcImageRange(src),
+                               destImage(dest),
+                               weight, scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*                   DiffusivityFunctor                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Diffusivity functor for non-linear diffusion.
+
+    This functor implements the diffusivity recommended by Weickert:
+    
+    \f[
+        g(|\nabla u|) = 1 -
+           \exp{\left(\frac{-3.315}{(|\nabla u| / thresh)^4}\right)}
+    \f]
+    
+    
+    where <TT>thresh</TT> is a threshold that determines whether a specific gradient
+    magnitude is interpreted as a significant edge (above the threshold)
+    or as noise. It is meant to be used with \ref nonlinearDiffusion().
+*/
+template <class Value>
+class DiffusivityFunctor
+{
+  public:
+         /** the functors first argument type (must be an algebraic field with <TT>exp()</TT> defined).
+             However, the functor also works with RGBValue<first_argument_type> (this hack is
+             necessary since Microsoft C++ doesn't support partial specialization).
+         */
+    typedef Value first_argument_type;
+    
+         /** the functors second argument type (same as first).
+             However, the functor also works with RGBValue<second_argument_type> (this hack is
+             necessary since Microsoft C++ doesn't support partial specialization).
+         */
+    typedef Value second_argument_type;
+    
+         /** the functors result type
+         */
+    typedef typename NumericTraits<Value>::RealPromote result_type;
+    
+         /** \deprecated use first_argument_type, second_argument_type, result_type
+         */
+    typedef Value value_type;
+    
+         /** init functor with given edge threshold
+         */
+    DiffusivityFunctor(Value const & thresh)
+    : weight_(thresh*thresh),
+      one_(NumericTraits<result_type>::one()),
+      zero_(NumericTraits<result_type>::zero())
+    {}
+    
+         /** calculate diffusivity from scalar arguments
+         */
+    result_type operator()(first_argument_type const & gx, second_argument_type const & gy) const
+    {
+        Value mag = (gx*gx + gy*gy) / weight_;
+                     
+        return (mag == zero_) ? one_ : one_ - VIGRA_CSTD::exp(-3.315 / mag / mag);
+    }
+    
+         /** calculate diffusivity from RGB arguments
+         */
+    result_type operator()(RGBValue<Value> const & gx, RGBValue<Value> const & gy) const
+    {
+        result_type mag = (gx.red()*gx.red() +
+                     gx.green()*gx.green() +
+                     gx.blue()*gx.blue() +
+                     gy.red()*gy.red() +
+                     gy.green()*gy.green() +
+                     gy.blue()*gy.blue()) / weight_;
+
+        return (mag == zero_) ? one_ : one_ - VIGRA_CSTD::exp(-3.315 / mag / mag);
+    }
+    
+    result_type weight_;
+    result_type one_;
+    result_type zero_;
+};
+
+template <class ValueType>
+class FunctorTraits<DiffusivityFunctor<ValueType> >
+: public FunctorTraitsBase<DiffusivityFunctor<ValueType> >
+{
+  public:
+    typedef VigraTrueType isBinaryFunctor;
+};
+
+
+//@}
+
+} // namespace vigra
+
+#endif /* VIGRA_NONLINEARDIFFUSION_HXX */
diff --git a/include/vigra/numerictraits.hxx b/include/vigra/numerictraits.hxx
new file mode 100644
index 0000000..994353c
--- /dev/null
+++ b/include/vigra/numerictraits.hxx
@@ -0,0 +1,1350 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_NUMERICTRAITS_HXX
+#define VIGRA_NUMERICTRAITS_HXX
+
+#include <climits>
+#include <limits>
+#include <cfloat>
+#include <complex>
+#include "metaprogramming.hxx"
+#include "sized_int.hxx"
+
+/********************************************************/
+/*                                                      */
+/*                      NumericTraits                   */
+/*                                                      */
+/********************************************************/
+
+
+/** \page NumericPromotionTraits Numeric and Promotion Traits
+
+    Meta-information about arithmetic types.
+    
+    <UL style="list-style-image:url(documents/bullet.gif)">
+    <LI> \ref NumericTraits
+         <BR>   <em>Unary traits for promotion, conversion, creation of arithmetic objects</em>
+    <LI> \ref PromoteTraits
+         <BR>   <em>Binary traits for promotion of arithmetic objects</em>
+    <LI> \ref SquareRootTraits
+         <BR>   <em>Unary traits for the calculation of the square root of arithmetic objects</em>
+    <LI> \ref NormTraits
+         <BR>   <em>Unary traits for the calculation of the norm and squared norm of arithmetic objects</em>
+    </UL>
+    
+    These traits classes contain information that is used by generic
+    algorithms and data structures to determine intermediate and result
+    types of numerical calculations, to convert between different 
+    representations of arithmetic types, and to create certain important
+    constants of each type. Thus, algorithms and data structures
+    operating that need arithmetic operations can be made more
+    independent from the actual data representation.
+    
+    NumericTraits are implemented as template specializations of one
+    arithmetic type, while PromoteTraits are specialized for a pair of
+    arithmetic types that shall be combined in one operation.    
+*/
+
+/** \page NumericTraits template<> struct NumericTraits<ArithmeticType>
+
+    Unary traits for promotion, conversion, creation of arithmetic objects.
+
+    <b>\#include</b> \<vigra/numerictraits.hxx\>
+
+    This traits class is used derive important properties of
+    an arithmetic type. Consider the following algorithm:
+    
+    \code
+    // calculate the sum of a sequence of bytes
+    int sumBytes(unsigned char * begin, unsigned char * end)
+    {
+        int result = 0;
+        for(; begin != end; ++begin)  result += *begin;
+        return result;
+    }
+    \endcode 
+    
+    The return type of this function can not be 'unsigned char' because
+    the summation would very likely overflow. Since we know the source
+    type, we can easily choose 'int' as an appropriate return type.
+    Likewise, we would have chosen 'float' if we had to sum a 
+    sequence of floats. If we want to make this 
+    algorithm generic, we would like to derive the appropriate return 
+    type automatically. This can be done with NumericTraits. 
+    The code would look like this (we use \ref DataAccessors to 
+    read the data from the sequence):
+    
+    \code
+    // calculate the sum of any sequence
+    template <class Iterator, class Accessor>
+    typename vigra::NumericTraits<typename Accessor::value_type>::Promote
+    sumSequence(Iterator begin, Iterator end, Accessor a)
+    {
+        // an abbreviation
+        typedef vigra::NumericTraits<typename Accessor::value_type>  SrcTraits;
+        
+        // find out result type
+        typedef typename SrcTraits::Promote ResultType;
+      
+        // init result to zero
+        ResultType result = vigra::NumericTraits<ResultType>::zero();
+    
+        for(; begin != end; ++begin)
+        {  
+            // cast current item to ResultType and add
+            result += SrcTraits::toPromote(a(begin));
+        }
+        
+        return result;
+    }
+    \endcode
+    
+    In this example NumericTraits is not only used to deduce the 
+    ReturnType of the operation, but also to initialize it with the
+    constant 'zero'. This is necessary since we do not know in general,
+    which expression must be used to obtain a zero of some arbitrary
+    type - '<TT>ResultType result = 0;</TT>' would only work if the 
+    ResultType had an constructor taking an '<TT>int</TT>' argument, and we 
+    would not even have any guarantee as to what the semantics of this
+    constructor are. In addition, the traits are used to cast the 
+    source type into the promote type.
+    
+    Similarly, an algorithm that needs multiplication would use the 
+    return type <TT>RealPromote</TT> and the functions <TT>one()</TT> and
+    <TT>toRealPromote()</TT>. The following members are defined in 
+    <b> <TT>NumericTraits<ArithmeticType></TT></b>:
+    
+    <table>
+    <tr><td>
+    <b> <TT>typedef ... Type;</TT></b>
+    </td><td>
+    
+            the type itself 
+        
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... Promote;</TT></b>
+    </td><td>
+    
+            promote type for addition and subtraction 
+        
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... RealPromote;</TT></b>
+    </td><td>
+            promote type for multiplication and division with a real number
+    
+    (only defined if <TT>ArithmeticType</TT> supports these operations) 
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... ComplexPromote;</TT></b>
+    </td><td>
+    
+            promote type for complex arithmetic 
+        
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... ValueType;</TT></b>
+    </td><td>
+    
+            for scalar types: the type itself<br>
+            otherwise: typename Type::value_type (if defined)
+        
+    </td></tr>
+    <tr><td>
+    <b> <TT>static Promote toPromote(ArithmeticType v);</TT></b>
+    </td><td>
+        convert to <TT>Promote</TT> type 
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>static RealPromote toRealPromote(ArithmeticType v);</TT></b>
+    </td><td>
+        convert to <TT>RealPromote</TT> type 
+
+    (only defined if <TT>ArithmeticType</TT> supports multiplication) 
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>static ArithmeticType fromPromote(Promote v);</TT></b> 
+    </td><td>
+        convert from <TT>Promote</TT> type
+    
+    if <TT>v</TT> is outside the range of <TT>ArithmeticType</TT> it is clipped;
+
+    </td></tr>
+    <tr><td>
+    <b> <TT>static ArithmeticType fromRealPromote(RealPromote v);</TT></b>
+    </td><td>
+        convert from <TT>RealPromote</TT> type 
+    
+    (only defined if 
+    <TT>ArithmeticType</TT> supports multiplication)
+    
+    if <TT>ArithmeticType</TT> is an integral type, the result is rounded 
+    
+    if <TT>v</TT> is outside the range of <TT>ArithmeticType</TT> it is clipped
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>static ArithmeticType zero();</TT></b>
+    </td><td>
+    create neutral element of addition
+    
+    i.e. <TT>(ArithmeticType a = ...,</TT> 
+    <TT>  a + NumericTraits<ArithmeticType>::zero() == a)</TT> 
+    must always yield <TT>true</TT> 
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>static ArithmeticType nonZero();</TT></b>
+    </td><td>
+    create a non-zero element (if multiplication is defined, this yields one())
+    
+    i.e. <TT>(ArithmeticType a = ...,</TT> 
+    <TT>  a + NumericTraits<ArithmeticType>::nonZero() == a)</TT> 
+    must always yield <TT>false</TT> 
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>static ArithmeticType min();</TT></b>
+    </td><td>
+    the smallest number representable in this type.<br>
+    Only available if isOrdered is VigraTrueType. For integral types,
+    this equals <TT>INT_MIN</TT> etc., for real valued types it is <TT>-FLT_MAX</TT>
+    etc. (<b>not</b> <TT>FLT_MIN</TT> -- this is the smallest positive <tt>float</tt>)
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>static ArithmeticType max();</TT></b>
+    </td><td>
+    the largest number representable in this type.<br>
+    Only available if isOrdered is VigraTrueType. For integral types,
+    this equals <TT>INT_MAX</TT> etc., for real valued types it is <TT>FLT_MAX</TT>
+    etc.
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>static ArithmeticType one();</TT></b>
+    </td><td>
+    create neutral element of multiplication 
+    
+    (only defined if <TT>ArithmeticType</TT> supports multiplication)
+    
+    i.e. <TT>(ArithmeticType a = ...,</TT> 
+    <TT>  a * NumericTraits<ArithmeticType>::one() == a)</TT> 
+    must always yield <TT>true</TT> 
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... isIntegral;</TT></b>
+    </td><td>
+        VigraTrueType if <TT>ArithmeticType</TT> is an integral type, 
+        VigraFalseType otherwise 
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... isScalar;</TT></b>
+    </td><td>
+        VigraTrueType if <TT>ArithmeticType</TT> is a scalar type, 
+        VigraFalseType otherwise 
+    
+    </td></tr>
+    <tr><td>
+    <tr><td>
+    <b> <TT>typedef ... isSigned;</TT></b>
+    </td><td>
+        VigraTrueType if <TT>ArithmeticType</TT> is a signed type, 
+        VigraFalseType otherwise 
+    
+    </td></tr>
+    <tr><td>
+    <tr><td>
+    <b> <TT>typedef ... isOrdered;</TT></b>
+    </td><td>
+        VigraTrueType if <TT>ArithmeticType</TT> supports operator<(), 
+        VigraFalseType otherwise 
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... isComplex;</TT></b>
+    </td><td>
+        VigraTrueType if <TT>ArithmeticType</TT> is a complex number, 
+        VigraFalseType otherwise 
+    
+    </td></tr>
+    <tr><td>
+    </table>
+    
+    NumericTraits for the built-in types are defined in <b>\#include</b> \<vigra/numerictraits.hxx\>
+    
+    Namespace: vigra
+    
+*/
+
+/** \page PromoteTraits template<> struct PromoteTraits<ArithmeticType1, ArithmeticType2>
+
+    Binary traits for promotion of arithmetic objects.
+    
+    <b>\#include</b> \<vigra/numerictraits.hxx\>
+
+    This traits class is used to determine the appropriate result type
+    of arithmetic expressions which depend of two arguments. Consider
+    the following function:
+    
+    \code
+    template <class T>
+    T min(T t1, T t2)
+    {
+        return (t1 < t2) ? t1 : t2;
+    }
+    \endcode
+    
+    This template is only applicable if both arguments have the same
+    type. However, sometimes we may want to use the function in cases
+    where the argument types differ. Then we can deduce the appropriate
+    return type by using <TT>PromoteTraits</TT>:
+    
+    \code
+    template <class T1, class T2>
+    typename vigra::PromoteTraits<T1, T2>::Promote
+    min(T1 t1, T2 t2)
+    {
+        return (t1 < t2) ? vigra::PromoteTraits<T1, T2>::toPromote(t1) : 
+                           vigra::PromoteTraits<T1, T2>::toPromote(t2);
+    }    
+    \endcode
+    
+    In addition, the traits class provide static functions to cast the
+    arguments to the promote type. For example, if <TT>T1</TT> were <TT>int</TT> and 
+    <TT>T2</TT> were <TT>float</TT>, the <TT>Promote</TT> type would be <TT>float</TT>. 
+    The following members are defined in 
+    <b> <TT>PromoteTraits<ArithmeticType1, ArithmeticType2></TT></b>:
+    
+    <table>
+    <tr>
+    <td>
+    <b> <TT>typedef ... Promote;</TT></b>
+    </td><td>
+            promote type 
+    </td></tr>
+    <tr><td>
+    <b> <TT>static Promote toPromote(ArithmeticType1 v);</TT></b> 
+    
+    <b> <TT>static Promote toPromote(ArithmeticType2 v);</TT></b>
+    </td><td>
+        convert to <TT>Promote</TT> type 
+    </td></tr>
+    </table>
+    
+    PromoteTraits for the built-in types are defined in <b>\#include</b> \<vigra/numerictraits.hxx\>
+    
+    Namespace: vigra
+*/
+
+/** \page SquareRootTraits template<> struct SquareRootTraits<ArithmeticType>
+
+    Unary traits for the calculation of the square root of arithmetic objects.
+    
+    <b>\#include</b> \<vigra/numerictraits.hxx\>
+
+    This traits class is used to determine appropriate argument and result types
+    for the function sqrt(). These traits are typically used like this:
+    
+    \code
+    ArithmeticType t = ...;
+    SquareRootTraits<ArithmeticType>::SquareRootResult r = 
+          sqrt((SquareRootTraits<ArithmeticType>::SquareRootArgument)t);
+    \endcode
+    
+    This approach avoids 'ambiguous overload errors' when taking the square root of 
+    an integer type. It also takes care of determining the proper result of the
+    sqrt() function of \ref vigra::FixedPoint and of the norm() function, when
+    it is implemented via sqrt(squaredNorm(x)).
+    The following members are defined in <b> <TT>SquareRootTraits<ArithmeticType></TT></b>:
+    
+    <table>
+    <tr><td>
+    <b> <TT>typedef ArithmeticType Type;</TT></b>
+    </td><td>
+            the type itself
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... SquareRootArgument;</TT></b>
+    </td><td>
+            required argument type for srqt(), i.e. <tt>sqrt((SquareRootArgument)x)</tt>
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... SquareRootResult;</TT></b>
+    </td><td>
+            result of <tt>sqrt((SquareRootArgument)x)</tt>
+    </td></tr>
+    </table>
+    
+    NormTraits for the built-in types are defined in <b>\#include</b> \<vigra/numerictraits.hxx\>
+    
+    Namespace: vigra
+*/
+
+/** \page NormTraits template<> struct NormTraits<ArithmeticType>
+
+    Unary traits for the calculation of the norm and squared norm of arithmetic objects.
+    
+    <b>\#include</b> \<vigra/numerictraits.hxx\>
+
+    This traits class is used to determine appropriate result types
+    for the functions norm() and squaredNorm(). These functions are always 
+    declared like this (where <tt>ArithmeticType</tt> is a type that supports a norm):
+    
+    \code
+    NormTraits<ArithmeticType>::NormType        norm(ArithmeticType const & t);
+    NormTraits<ArithmeticType>::SquaredNormType squaredNorm(ArithmeticType const & t);
+    \endcode
+    
+    The following members are defined in <b> <TT>NormTraits<ArithmeticType></TT></b>:
+    
+    <table>
+    <tr><td>
+    <b> <TT>typedef ArithmeticType Type;</TT></b>
+    </td><td>
+            the type itself
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... SquaredNormType;</TT></b>
+    </td><td>
+            result of <tt>squaredNorm(ArithmeticType)</tt>
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... NormType;</TT></b>
+    </td><td>
+            result of <tt>norm(ArithmeticType)</tt><br>
+            Usually equal to <tt>SquareRootTraits<SquaredNormType>::SquareRootResult</tt>
+    </td></tr>
+    </table>
+    
+    NormTraits for the built-in types are defined in <b>\#include</b> \<vigra/numerictraits.hxx\>
+    
+    Namespace: vigra
+*/
+
+
+namespace vigra {
+    namespace detail {
+        template <typename s, typename t>
+        inline static t clamp_integer_to_unsigned(s value, t maximum) {
+            return
+                value <= s() ?
+                t() :
+                (value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value));
+        }
+
+        template <typename s, typename t>
+        inline static t clamp_integer_to_signed(s value, t minimum, t maximum) {
+            return
+                value <= static_cast<s>(minimum) ?
+                minimum :
+                (value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value));
+        }
+
+        template <typename s, typename t>
+        inline static t clamp_float_to_unsigned(s value, t maximum) {
+            return
+                value <= s() ?
+                t() :
+                (value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value + 0.5));
+        }
+
+        template <typename s, typename t>
+        inline static t clamp_float_to_signed(s value, t minimum, t maximum) {
+            if (value >= s()) {
+                return value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value + 0.5);
+            } else {
+                return value <= static_cast<s>(minimum) ? minimum : static_cast<t>(value - 0.5);
+            }
+        }
+    } // end namespace detail
+
+struct Error_NumericTraits_not_specialized_for_this_case { };
+struct Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char { };
+
+template<class A>
+struct NumericTraits
+{
+    typedef Error_NumericTraits_not_specialized_for_this_case Type;
+    typedef Error_NumericTraits_not_specialized_for_this_case Promote;
+    typedef Error_NumericTraits_not_specialized_for_this_case UnsignedPromote;
+    typedef Error_NumericTraits_not_specialized_for_this_case RealPromote;
+    typedef Error_NumericTraits_not_specialized_for_this_case ComplexPromote;
+    typedef Error_NumericTraits_not_specialized_for_this_case ValueType;
+
+    typedef Error_NumericTraits_not_specialized_for_this_case isScalar;
+    typedef Error_NumericTraits_not_specialized_for_this_case isIntegral;
+    typedef Error_NumericTraits_not_specialized_for_this_case isSigned;
+    typedef Error_NumericTraits_not_specialized_for_this_case isOrdered;
+    typedef Error_NumericTraits_not_specialized_for_this_case isComplex;
+};
+
+template<>
+struct NumericTraits<char>
+{
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char Type;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char Promote;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char UnsignedPromote;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char RealPromote;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char ComplexPromote;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char ValueType;
+
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isScalar;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isIntegral;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isSigned;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isOrdered;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isComplex;
+};
+
+#ifndef NO_BOOL
+template<>
+struct NumericTraits<bool>
+{
+    typedef bool Type;
+    typedef int Promote;
+    typedef unsigned int UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraTrueType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraFalseType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static bool zero() { return false; }
+    static bool one() { return true; }
+    static bool nonZero() { return true; }
+    static bool min() { return false; }
+    static bool max() { return true; }
+    
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = false , maxConst = true };
+#else
+    static const bool minConst = false;
+    static const bool maxConst = true;
+#endif
+    
+    static Promote toPromote(bool v) { return v ? 1 : 0; }
+    static RealPromote toRealPromote(bool v) { return v ? 1.0 : 0.0; }
+    static bool fromPromote(Promote v) { 
+        return (v == 0) ? false : true; 
+    }
+    static bool fromRealPromote(RealPromote v) {
+        return (v == 0.0) ? false : true; 
+    }
+};
+#endif
+
+template<>
+struct NumericTraits<signed char>
+{
+    typedef signed char Type;
+    typedef int Promote;
+    typedef unsigned int UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraTrueType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static signed char zero() { return 0; }
+    static signed char one() { return 1; }
+    static signed char nonZero() { return 1; }
+    static signed char min() { return SCHAR_MIN; }
+    static signed char max() { return SCHAR_MAX; }
+    
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = SCHAR_MIN, maxConst = SCHAR_MIN };
+#else
+    static const signed char minConst = SCHAR_MIN;
+    static const signed char maxConst = SCHAR_MIN;
+#endif
+    
+    static Promote toPromote(signed char v) { return v; }
+    static RealPromote toRealPromote(signed char v) { return v; }
+    static signed char fromPromote(Promote v) {
+        return detail::clamp_integer_to_signed<Promote, signed char>(v, SCHAR_MIN, SCHAR_MAX);
+    }
+    static signed char fromRealPromote(RealPromote v) {
+        return detail::clamp_float_to_signed<RealPromote, signed char>(v, SCHAR_MIN, SCHAR_MAX);
+    }
+};
+
+template<>
+struct NumericTraits<unsigned char>
+{
+    typedef unsigned char Type;
+    typedef int Promote;
+    typedef unsigned int UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraTrueType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraFalseType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static unsigned char zero() { return 0; }
+    static unsigned char one() { return 1; }
+    static unsigned char nonZero() { return 1; }
+    static unsigned char min() { return 0; }
+    static unsigned char max() { return UCHAR_MAX; }
+    
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = 0, maxConst = UCHAR_MAX };
+#else
+    static const unsigned char minConst = 0;
+    static const unsigned char maxConst = UCHAR_MAX;
+#endif
+    
+    static Promote toPromote(unsigned char v) { return v; }
+    static RealPromote toRealPromote(unsigned char v) { return v; }
+    static unsigned char fromPromote(Promote v) {
+        return detail::clamp_integer_to_unsigned<Promote, unsigned char>(v, UCHAR_MAX);
+    }
+    static unsigned char fromRealPromote(RealPromote v) {
+        return detail::clamp_float_to_unsigned<RealPromote, unsigned char>(v, UCHAR_MAX);
+    }
+};
+
+template<>
+struct NumericTraits<short int>
+{
+    typedef short int Type;
+    typedef int Promote;
+    typedef unsigned int UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraTrueType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static short int zero() { return 0; }
+    static short int one() { return 1; }
+    static short int nonZero() { return 1; }
+    static short int min() { return SHRT_MIN; }
+    static short int max() { return SHRT_MAX; }
+    
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = SHRT_MIN, maxConst = SHRT_MAX };
+#else
+    static const short int minConst = SHRT_MIN;
+    static const short int maxConst = SHRT_MAX;
+#endif
+    
+    static Promote toPromote(short int v) { return v; }
+    static RealPromote toRealPromote(short int v) { return v; }
+    static short int fromPromote(Promote v) {
+        return detail::clamp_integer_to_signed<Promote, short int>(v, SHRT_MIN, SHRT_MAX);
+    }
+    static short int fromRealPromote(RealPromote v) {
+        return detail::clamp_float_to_signed<RealPromote, short int>(v, SHRT_MIN, SHRT_MAX);
+    }
+};
+
+template<>
+struct NumericTraits<short unsigned int>
+{
+    typedef short unsigned int Type;
+    typedef int Promote;
+    typedef unsigned int UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraTrueType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraFalseType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+
+    static short unsigned int zero() { return 0; }
+    static short unsigned int one() { return 1; }
+    static short unsigned int nonZero() { return 1; }
+    static short unsigned int min() { return 0; }
+    static short unsigned int max() { return USHRT_MAX; }
+    
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = 0, maxConst = USHRT_MAX };
+#else
+    static const short unsigned int minConst = 0;
+    static const short unsigned int maxConst = USHRT_MAX;
+#endif
+
+    static Promote toPromote(short unsigned int v) { return v; }
+    static RealPromote toRealPromote(short unsigned int v) { return v; }
+    static short unsigned int fromPromote(Promote v) {
+        return detail::clamp_integer_to_unsigned<Promote, short unsigned int>(v, USHRT_MAX);
+    }
+    static short unsigned int fromRealPromote(RealPromote v) {
+        return detail::clamp_float_to_unsigned<RealPromote, short unsigned int>(v, USHRT_MAX);
+    }
+};
+
+template<>
+struct NumericTraits<int>
+{
+    typedef int Type;
+    typedef int Promote;
+    typedef unsigned int UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraTrueType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+
+    static int zero() { return 0; }
+    static int one() { return 1; }
+    static int nonZero() { return 1; }
+    static int min() { return INT_MIN; }
+    static int max() { return INT_MAX; }
+    
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = INT_MIN, maxConst = INT_MAX };
+#else
+    static const int minConst = INT_MIN;
+    static const int maxConst = INT_MAX;
+#endif
+
+    static Promote toPromote(int v) { return v; }
+    static RealPromote toRealPromote(int v) { return v; }
+    static int fromPromote(Promote v) { return v; }
+    static int fromRealPromote(RealPromote v) {
+        return detail::clamp_float_to_signed<RealPromote, int>(v, INT_MIN, INT_MAX);
+    }
+};
+
+template<>
+struct NumericTraits<unsigned int>
+{
+    typedef unsigned int Type;
+    typedef unsigned int Promote;
+    typedef unsigned int UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraTrueType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraFalseType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static unsigned int zero() { return 0; }
+    static unsigned int one() { return 1; }
+    static unsigned int nonZero() { return 1; }
+    static unsigned int min() { return 0; }
+    static unsigned int max() { return UINT_MAX; }
+    
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = 0, maxConst = UINT_MAX };
+#else
+    static const unsigned int minConst = 0;
+    static const unsigned int maxConst = UINT_MAX;
+#endif
+
+    static Promote toPromote(unsigned int v) { return v; }
+    static RealPromote toRealPromote(unsigned int v) { return v; }
+    static unsigned int fromPromote(Promote v) { return v; }
+    static unsigned int fromRealPromote(RealPromote v) {
+        return detail::clamp_float_to_unsigned<RealPromote, unsigned int>(v, UINT_MAX);
+    }
+};
+
+template<>
+struct NumericTraits<long>
+{
+    typedef long Type;
+    typedef long Promote;
+    typedef unsigned long UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraTrueType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static long zero() { return 0; }
+    static long one() { return 1; }
+    static long nonZero() { return 1; }
+    static long min() { return LONG_MIN; }
+    static long max() { return LONG_MAX; }
+    
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = LONG_MIN, maxConst = LONG_MAX };
+#else
+    static const long minConst = LONG_MIN;
+    static const long maxConst = LONG_MAX;
+#endif
+
+    static Promote toPromote(long v) { return v; }
+    static RealPromote toRealPromote(long v) { return static_cast<RealPromote>(v); }
+    static long fromPromote(Promote v) { return v; }
+    static long fromRealPromote(RealPromote v) {
+        return detail::clamp_float_to_signed<RealPromote, long>(v, LONG_MIN, LONG_MAX);
+    }
+};
+
+template<>
+struct NumericTraits<unsigned long>
+{
+    typedef unsigned long Type;
+    typedef unsigned long Promote;
+    typedef unsigned long UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraTrueType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraFalseType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static unsigned long zero() { return 0; }
+    static unsigned long one() { return 1; }
+    static unsigned long nonZero() { return 1; }
+    static unsigned long min() { return 0; }
+    static unsigned long max() { return ULONG_MAX; }
+    
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = 0, maxConst = ULONG_MAX };
+#else
+    static const unsigned long minConst = 0;
+    static const unsigned long maxConst = ULONG_MAX;
+#endif
+
+    static Promote toPromote(unsigned long v) { return v; }
+    static RealPromote toRealPromote(unsigned long v) { return static_cast<RealPromote>(v); }
+    static unsigned long fromPromote(Promote v) { return v; }
+    static unsigned long fromRealPromote(RealPromote v) {
+        return detail::clamp_float_to_unsigned<RealPromote, unsigned long>(v, ULONG_MAX);
+    }
+};
+
+#ifdef LLONG_MAX
+template<>
+struct NumericTraits<long long>
+{
+    typedef long long Type;
+    typedef long long Promote;
+    typedef unsigned long long UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraTrueType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static long long zero() { return 0; }
+    static long long one() { return 1; }
+    static long long nonZero() { return 1; }
+    static long long min() { return LLONG_MIN; }
+    static long long max() { return LLONG_MAX; }
+    
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = LLONG_MIN, maxConst = LLONG_MAX };
+#else
+    static const long long minConst = LLONG_MIN;
+    static const long long maxConst = LLONG_MAX;
+#endif
+
+    static Promote toPromote(long long v) { return v; }
+    static RealPromote toRealPromote(long long v) { return (RealPromote)v; }
+    static long long fromPromote(Promote v) { return v; }
+    static long long fromRealPromote(RealPromote v) {
+        return detail::clamp_float_to_signed<RealPromote, long long>(v, LLONG_MIN, LLONG_MAX);
+    }
+};
+
+template<>
+struct NumericTraits<unsigned long long>
+{
+    typedef unsigned long long Type;
+    typedef unsigned long long Promote;
+    typedef unsigned long long UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraTrueType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraFalseType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static unsigned long long zero() { return 0; }
+    static unsigned long long one() { return 1; }
+    static unsigned long long nonZero() { return 1; }
+    static unsigned long long min() { return 0; }
+    static unsigned long long max() { return ULLONG_MAX; }
+    
+#ifdef NO_INLINE_STATIC_CONST_DEFINITION
+    enum { minConst = 0, maxConst = ULLONG_MAX };
+#else
+    static const unsigned long long minConst = 0;
+    static const unsigned long long maxConst = ULLONG_MAX;
+#endif
+
+    static Promote toPromote(unsigned long long v) { return v; }
+    static RealPromote toRealPromote(unsigned long long v) { return (RealPromote)v; }
+    static unsigned long long fromPromote(Promote v) { return v; }
+    static unsigned long long fromRealPromote(RealPromote v) {
+        return detail::clamp_float_to_unsigned<RealPromote, unsigned long long>(v, ULLONG_MAX);
+    }
+};
+#endif // LLONG_MAX
+
+template<>
+struct NumericTraits<float>
+{
+    typedef float Type;
+    typedef float Promote;
+    typedef float UnsignedPromote;
+    typedef float RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+    
+    typedef VigraFalseType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static float zero() { return 0.0; }
+    static float one() { return 1.0; }
+    static float nonZero() { return 1.0; }
+    static float epsilon() { return FLT_EPSILON; }
+    static float smallestPositive() { return FLT_MIN; }
+    static float min() { return -FLT_MAX; }
+    static float max() { return FLT_MAX; }
+    
+    static Promote toPromote(float v) { return v; }
+    static RealPromote toRealPromote(float v) { return v; }
+    static float fromPromote(Promote v) { return v; }
+    static float fromRealPromote(RealPromote v) { return v; }
+};
+
+template<>
+struct NumericTraits<double>
+{
+    typedef double Type;
+    typedef double Promote;
+    typedef double UnsignedPromote;
+    typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraFalseType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static double zero() { return 0.0; }
+    static double one() { return 1.0; }
+    static double nonZero() { return 1.0; }
+    static double epsilon() { return DBL_EPSILON; }
+    static double smallestPositive() { return DBL_MIN; }
+    static double min() { return -DBL_MAX; }
+    static double max() { return DBL_MAX; }
+
+    static Promote toPromote(double v) { return v; }
+    static RealPromote toRealPromote(double v) { return v; }
+    static double fromPromote(Promote v) { return v; }
+    static double fromRealPromote(RealPromote v) { return v; }
+};
+
+template<>
+struct NumericTraits<long double>
+{
+    typedef long double Type;
+    typedef long double Promote;
+    typedef long double UnsignedPromote;
+    typedef long double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
+    typedef VigraFalseType isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+    
+    static long double zero() { return 0.0; }
+    static long double one() { return 1.0; }
+    static long double nonZero() { return 1.0; }
+    static long double epsilon() { return LDBL_EPSILON; }
+    static long double smallestPositive() { return LDBL_MIN; }
+    static long double min() { return -LDBL_MAX; }
+    static long double max() { return LDBL_MAX; }
+
+    static Promote toPromote(long double v) { return v; }
+    static RealPromote toRealPromote(long double v) { return v; }
+    static long double fromPromote(Promote v) { return v; }
+    static long double fromRealPromote(RealPromote v) { return v; }
+};
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template<class T>
+struct NumericTraits<std::complex<T> >
+{
+    typedef std::complex<T> Type;
+    typedef std::complex<typename NumericTraits<T>::Promote> Promote;
+    typedef std::complex<typename NumericTraits<T>::UnsignedPromote> UnsignedPromote;
+    typedef std::complex<typename NumericTraits<T>::RealPromote> RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef T ValueType;
+
+    typedef VigraFalseType isIntegral;
+    typedef VigraFalseType isScalar;
+    typedef typename NumericTraits<T>::isSigned isSigned;
+    typedef VigraFalseType isOrdered;
+    typedef VigraTrueType isComplex;
+    
+    static Type zero() { return Type(0.0); }
+    static Type one() { return Type(1.0); }
+    static Type nonZero() { return one(); }
+    static Type epsilon() { return Type(NumericTraits<T>::epsilon()); }
+    static Type smallestPositive() { return Type(NumericTraits<T>::smallestPositive()); }
+
+    static Promote toPromote(Type const & v) { return v; }
+    static Type fromPromote(Promote const & v) { return v; }
+    static Type fromRealPromote(RealPromote v) { return Type(v); }
+};
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+/********************************************************/
+/*                                                      */
+/*                    SquareRootTraits                  */
+/*                                                      */
+/********************************************************/
+
+template<class T>
+struct SquareRootTraits
+{
+    typedef T                                                    Type;
+    typedef typename NumericTraits<T>::RealPromote               SquareRootResult;
+    typedef typename NumericTraits<T>::RealPromote               SquareRootArgument;
+};
+
+
+/********************************************************/
+/*                                                      */
+/*                       NormTraits                     */
+/*                                                      */
+/********************************************************/
+
+struct Error_NormTraits_not_specialized_for_this_case { };
+
+template<class T>
+struct NormTraits
+{
+    typedef T                                                Type;
+    typedef Error_NormTraits_not_specialized_for_this_case   SquaredNormType;
+    typedef Error_NormTraits_not_specialized_for_this_case   NormType;
+};
+
+#define VIGRA_DEFINE_NORM_TRAITS(T) \
+    template <> struct NormTraits<T> { \
+        typedef T Type; \
+        typedef NumericTraits<T>::Promote SquaredNormType; \
+        typedef T NormType; \
+    };
+
+VIGRA_DEFINE_NORM_TRAITS(bool)
+VIGRA_DEFINE_NORM_TRAITS(signed char)
+VIGRA_DEFINE_NORM_TRAITS(unsigned char)
+VIGRA_DEFINE_NORM_TRAITS(short)
+VIGRA_DEFINE_NORM_TRAITS(unsigned short)
+VIGRA_DEFINE_NORM_TRAITS(int)
+VIGRA_DEFINE_NORM_TRAITS(unsigned int)
+VIGRA_DEFINE_NORM_TRAITS(long)
+VIGRA_DEFINE_NORM_TRAITS(unsigned long)
+VIGRA_DEFINE_NORM_TRAITS(float)
+VIGRA_DEFINE_NORM_TRAITS(double)
+VIGRA_DEFINE_NORM_TRAITS(long double)
+
+#ifdef LLONG_MAX
+VIGRA_DEFINE_NORM_TRAITS(long long)
+VIGRA_DEFINE_NORM_TRAITS(unsigned long long)
+#endif // LLONG_MAX
+
+#undef VIGRA_DEFINE_NORM_TRAITS
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template<class T>
+struct NormTraits<std::complex<T> >
+{
+    typedef std::complex<T>                                              Type;
+    typedef typename NormTraits<T>::SquaredNormType                      SquaredNormType;
+    typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
+};
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+/********************************************************/
+/*                                                      */
+/*                      PromoteTraits                   */
+/*                                                      */
+/********************************************************/
+
+namespace detail {
+
+template <class T, class U>
+struct PromoteType
+{
+    static T & t();
+    static U & u();
+    // let C++ figure out the promote type by adding a T and an U
+    typedef typename SizeToType<sizeof(*typeToSize(t() + u()))>::result Promote;
+    static Promote toPromote(T t) { return Promote(t); }
+    static Promote toPromote(U u) { return Promote(u); }
+};
+
+
+template <class T>
+struct PromoteType<T, T>
+{
+    static T & t();
+    // let C++ figure out the promote type by adding two Ts
+    typedef typename SizeToType<sizeof(*typeToSize(t() + t()))>::result Promote;
+    static Promote toPromote(T t) { return Promote(t); }
+};
+
+} // namespace detail
+
+struct Error_PromoteTraits_not_specialized_for_this_case { };
+
+template<class A, class B>
+struct PromoteTraits
+{
+    typedef Error_PromoteTraits_not_specialized_for_this_case Promote;
+};
+
+#include "promote_traits.hxx"
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class T>
+struct PromoteTraits<std::complex<T>, std::complex<T> >
+{
+    typedef std::complex<typename PromoteTraits<T, T>::Promote> Promote;
+    static Promote toPromote(std::complex<T> const & v) { return v; }
+};
+
+template <class T1, class T2>
+struct PromoteTraits<std::complex<T1>, std::complex<T2> >
+{
+    typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
+    static Promote toPromote(std::complex<T1> const & v) { return v; }
+    static Promote toPromote(std::complex<T2> const & v) { return v; }
+};
+
+template <class T1, class T2>
+struct PromoteTraits<std::complex<T1>, T2 >
+{
+    typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
+    static Promote toPromote(std::complex<T1> const & v) { return v; }
+    static Promote toPromote(T2 const & v) { return Promote(v); }
+};
+
+template <class T1, class T2>
+struct PromoteTraits<T1, std::complex<T2> >
+{
+    typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
+    static Promote toPromote(T1 const & v) { return Promote(v); }
+    static Promote toPromote(std::complex<T2> const & v) { return v; }
+};
+
+#endif
+
+namespace detail {
+
+template <class T>
+struct RequiresExplicitCast {
+    template <class U>
+    static U const & cast(U const & v)
+        { return v; }
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1300
+#  define VIGRA_SPECIALIZED_CAST(type) \
+    template <> \
+    struct RequiresExplicitCast<type> { \
+        static type cast(float v) \
+            { return NumericTraits<type>::fromRealPromote(v); } \
+        static type cast(double v) \
+            { return NumericTraits<type>::fromRealPromote(v); } \
+        static type cast(type v) \
+            { return v; } \
+        template <class U> \
+        static type cast(U v) \
+            { return static_cast<type>(v); } \
+ \
+    };
+#else
+#  define VIGRA_SPECIALIZED_CAST(type) \
+    template <> \
+    struct RequiresExplicitCast<type> { \
+        static type cast(float v) \
+            { return NumericTraits<type>::fromRealPromote(v); } \
+        static type cast(double v) \
+            { return NumericTraits<type>::fromRealPromote(v); } \
+        static type cast(signed char v) \
+            { return v; } \
+        static type cast(unsigned char v) \
+            { return v; } \
+        static type cast(short v) \
+            { return v; } \
+        static type cast(unsigned short v) \
+            { return v; } \
+        static type cast(int v) \
+            { return v; } \
+        static type cast(unsigned int v) \
+            { return v; } \
+        static type cast(long v) \
+            { return v; } \
+        static type cast(unsigned long v) \
+            { return v; } \
+    };
+#endif
+
+
+VIGRA_SPECIALIZED_CAST(signed char)
+VIGRA_SPECIALIZED_CAST(unsigned char)
+VIGRA_SPECIALIZED_CAST(short)
+VIGRA_SPECIALIZED_CAST(unsigned short)
+VIGRA_SPECIALIZED_CAST(int)
+VIGRA_SPECIALIZED_CAST(unsigned int)
+VIGRA_SPECIALIZED_CAST(long)
+VIGRA_SPECIALIZED_CAST(unsigned long)
+
+template <>
+struct RequiresExplicitCast<bool> {
+    template <class U>
+    static bool cast(U v)
+    { return v == NumericTraits<U>::zero()
+                ? false
+                : true; }
+};
+
+template <>
+struct RequiresExplicitCast<float> {
+    static float cast(int v)
+        { return (float)v; }
+
+    static float cast(unsigned int v)
+        { return (float)v; }
+
+    static float cast(long v)
+        { return (float)v; }
+
+    static float cast(unsigned long v)
+        { return (float)v; }
+
+    static float cast(long long v)
+        { return (float)v; }
+
+    static float cast(unsigned long long v)
+        { return (float)v; }
+
+    static float cast(double v)
+        { return (float)v; }
+
+    static float cast(long double v)
+        { return (float)v; }
+
+    template <class U>
+    static U cast(U v)
+        { return v; }
+};
+
+template <>
+struct RequiresExplicitCast<double> {
+    static double cast(Int64 v)
+        { return (double)v; }
+
+    static double cast(UInt64 v)
+        { return (double)v; }
+
+    template <class U>
+    static U cast(U v)
+        { return v; }
+};
+
+#undef VIGRA_SPECIALIZED_CAST
+
+} // namespace detail
+
+
+
+} // namespace vigra
+
+#endif // VIGRA_NUMERICTRAITS_HXX
+
diff --git a/include/vigra/numpy_array.hxx b/include/vigra/numpy_array.hxx
new file mode 100644
index 0000000..d8264bc
--- /dev/null
+++ b/include/vigra/numpy_array.hxx
@@ -0,0 +1,1232 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2009 by Ullrich Koethe and Hans Meine                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_NUMPY_ARRAY_HXX
+#define VIGRA_NUMPY_ARRAY_HXX
+
+#ifndef NPY_NO_DEPRECATED_API
+# define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#endif 
+
+#include <Python.h>
+#include <string>
+#include <iostream>
+#include <numpy/arrayobject.h>
+#include "multi_array.hxx"
+#include "array_vector.hxx"
+#include "python_utility.hxx"
+#include "numpy_array_traits.hxx"
+#include "numpy_array_taggedshape.hxx"
+
+// NumPy function called by NumPy's import_array() macro (and our import_vigranumpy() below)
+int _import_array();
+
+namespace vigra {
+
+static inline void import_vigranumpy()
+{
+    // roughly equivalent to import_array():
+    if(_import_array() < 0)
+        pythonToCppException(0);
+
+    // Import vigra to activate the numpy array converters, but ensure that 
+    // cyclic imports (from within vigra itself) are avoided.
+    char const * load_vigra = 
+        "import sys\n"
+        "if not sys.modules.has_key('vigra.vigranumpycore'):\n"
+        "    import vigra\n";
+    pythonToCppException(PyRun_SimpleString(load_vigra) == 0);
+}
+
+/********************************************************/
+/*                                                      */
+/*               MultibandVectorAccessor                */
+/*                                                      */
+/********************************************************/
+
+template <class T>
+class MultibandVectorAccessor
+{
+    MultiArrayIndex size_, stride_;
+
+  public:
+    MultibandVectorAccessor(MultiArrayIndex size, MultiArrayIndex stride)
+    : size_(size),
+      stride_(stride)
+    {}
+
+
+    typedef Multiband<T> value_type;
+
+        /** the vector's value_type
+        */
+    typedef T component_type;
+
+    typedef VectorElementAccessor<MultibandVectorAccessor<T> > ElementAccessor;
+
+        /** Read the component data at given vector index
+            at given iterator position
+        */
+    template <class ITERATOR>
+    component_type const & getComponent(ITERATOR const & i, int idx) const
+    {
+        return *(&*i+idx*stride_);
+    }
+
+        /** Set the component data at given vector index
+            at given iterator position. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+        */
+    template <class V, class ITERATOR>
+    void setComponent(V const & value, ITERATOR const & i, int idx) const
+    {
+        *(&*i+idx*stride_) = detail::RequiresExplicitCast<component_type>::cast(value);
+    }
+
+        /** Read the component data at given vector index
+            at an offset of given iterator position
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    component_type const & getComponent(ITERATOR const & i, DIFFERENCE const & diff, int idx) const
+    {
+        return *(&i[diff]+idx*stride_);
+    }
+
+    /** Set the component data at given vector index
+        at an offset of given iterator position. The type <TT>V</TT> of the passed
+        in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
+            In case of a conversion floating point -> integral this includes rounding and clipping.
+    */
+    template <class V, class ITERATOR, class DIFFERENCE>
+    void
+    setComponent(V const & value, ITERATOR const & i, DIFFERENCE const & diff, int idx) const
+    {
+        *(&i[diff]+idx*stride_) = detail::RequiresExplicitCast<component_type>::cast(value);
+    }
+
+    template <class U>
+    MultiArrayIndex size(U) const
+    {
+        return size_;
+    }
+};
+
+/********************************************************/
+
+template <class TYPECODE> // pseudo-template to avoid inline expansion of the function
+                          // will always be NPY_TYPES
+PyObject *
+constructArray(TaggedShape tagged_shape, TYPECODE typeCode, bool init,
+               python_ptr arraytype = python_ptr());
+
+/********************************************************/
+/*                                                      */
+/*                    NumpyAnyArray                     */
+/*                                                      */
+/********************************************************/
+
+/** Wrapper class for a Python array.
+
+    This class stores a reference-counted pointer to an Python numpy array object,
+    i.e. an object where <tt>PyArray_Check(object)</tt> returns true (in Python, the
+    object is then a subclass of <tt>numpy.ndarray</tt>). This class is mainly used
+    as a smart pointer to these arrays, but some basic access and conversion functions
+    are also provided.
+
+    <b>\#include</b> \<vigra/numpy_array.hxx\><br>
+    Namespace: vigra
+*/
+class NumpyAnyArray
+{
+  protected:
+    python_ptr pyArray_;
+
+  public:
+
+        /// difference type
+    typedef ArrayVector<npy_intp> difference_type;
+
+    static python_ptr getArrayTypeObject()
+    {
+        return detail::getArrayTypeObject();
+    }
+
+    static std::string defaultOrder(std::string defaultValue = "C")
+    {
+        return detail::defaultOrder(defaultValue);
+    }
+
+    static python_ptr defaultAxistags(int ndim, std::string order = "")
+    {
+        return detail::defaultAxistags(ndim, order);
+    }
+
+    static python_ptr emptyAxistags(int ndim)
+    {
+        return detail::emptyAxistags(ndim);
+    }
+
+        /**
+         Construct from a Python object. If \a obj is NULL, or is not a subclass
+         of numpy.ndarray, the resulting NumpyAnyArray will have no data (i.e.
+         hasData() returns false). Otherwise, it creates a new reference to the array
+         \a obj, unless \a createCopy is true, where a new array is created by calling
+         the C-equivalent of obj->copy().
+         */
+    explicit NumpyAnyArray(PyObject * obj = 0, bool createCopy = false, PyTypeObject * type = 0)
+    {
+        if(obj == 0)
+            return;
+        vigra_precondition(type == 0 || PyType_IsSubtype(type, &PyArray_Type),
+             "NumpyAnyArray(obj, createCopy, type): type must be numpy.ndarray or a subclass thereof.");
+        if(createCopy)
+            makeCopy(obj, type);
+        else
+            vigra_precondition(makeReference(obj, type), "NumpyAnyArray(obj): obj isn't a numpy array.");
+    }
+
+        /**
+         Copy constructor. By default, it creates a new reference to the array
+         \a other. When \a createCopy is true, a new array is created by calling
+         the C-equivalent of other.copy().
+         */
+    NumpyAnyArray(NumpyAnyArray const & other, bool createCopy = false, PyTypeObject * type = 0)
+    {
+        if(!other.hasData())
+            return;
+        vigra_precondition(type == 0 || PyType_IsSubtype(type, &PyArray_Type),
+             "NumpyAnyArray(obj, createCopy, type): type must be numpy.ndarray or a subclass thereof.");
+        if(createCopy)
+            makeCopy(other.pyObject(), type);
+        else
+            makeReference(other.pyObject(), type);
+    }
+
+    // auto-generated destructor is ok
+
+        /**
+         * Assignment operator. If this is already a view with data
+         * (i.e. hasData() is true) and the shapes match, the RHS
+         * array contents are copied via the C-equivalent of
+         * 'self[...] = other[...]'. If the shapes don't matched,
+         * broadcasting is tried on the trailing (i.e. channel)
+         * dimension.
+         * If the LHS is an empty view, assignment is identical to
+         * makeReference(other.pyObject()).
+         */
+    NumpyAnyArray & operator=(NumpyAnyArray const & other)
+    {
+        if(hasData())
+        {
+            vigra_precondition(other.hasData(),
+                "NumpyArray::operator=(): Cannot assign from empty array.");
+
+            python_ptr arraytype = getArrayTypeObject();
+            python_ptr f(PyString_FromString("_copyValuesImpl"), python_ptr::keep_count);
+            if(PyObject_HasAttr(arraytype, f))
+            {
+                python_ptr res(PyObject_CallMethodObjArgs(arraytype, f.get(),
+                                                          pyArray_.get(), other.pyArray_.get(), NULL),
+                               python_ptr::keep_count);
+                vigra_postcondition(res.get() != 0,
+                       "NumpyArray::operator=(): VigraArray._copyValuesImpl() failed.");
+            }
+            else
+            {
+                PyArrayObject * sarray = (PyArrayObject *)pyArray_.get();
+                PyArrayObject * tarray = (PyArrayObject *)other.pyArray_.get();
+
+                if(PyArray_CopyInto(tarray, sarray) == -1)
+                    pythonToCppException(0);
+            }
+        }
+        else
+        {
+            pyArray_ = other.pyArray_;
+        }
+        return *this;
+    }
+
+        /**
+         Returns the number of dimensions of this array, or 0 if
+         hasData() is false.
+         */
+    MultiArrayIndex ndim() const
+    {
+        if(hasData())
+            return PyArray_NDIM(pyArray());
+        return 0;
+    }
+
+        /**
+         Returns the number of spatial dimensions of this array, or 0 if
+         hasData() is false. If the enclosed Python array does not define
+         the attribute spatialDimensions, ndim() is returned.
+         */
+    MultiArrayIndex spatialDimensions() const
+    {
+        if(!hasData())
+            return 0;
+        return pythonGetAttr(pyObject(), "spatialDimensions", ndim());
+    }
+
+    bool hasChannelAxis() const
+    {
+        if(!hasData())
+            return false;
+        return channelIndex() == ndim();
+    }
+
+    MultiArrayIndex channelIndex() const
+    {
+        if(!hasData())
+            return 0;
+        return pythonGetAttr(pyObject(), "channelIndex", ndim());
+    }
+
+    MultiArrayIndex innerNonchannelIndex() const
+    {
+        if(!hasData())
+            return 0;
+        return pythonGetAttr(pyObject(), "innerNonchannelIndex", ndim());
+    }
+
+        /**
+         Returns the shape of this array. The size of
+         the returned shape equals ndim().
+         */
+    difference_type shape() const
+    {
+        if(hasData())
+            return difference_type(PyArray_DIMS(pyArray()), PyArray_DIMS(pyArray()) + ndim());
+        return difference_type();
+    }
+
+        /** Compute the ordering of the strides of this array.
+            The result is describes the current permutation of the axes relative
+            to an ascending stride order.
+        */
+    difference_type strideOrdering() const
+    {
+        if(!hasData())
+            return difference_type();
+        MultiArrayIndex N = ndim();
+        difference_type stride(PyArray_STRIDES(pyArray()), PyArray_STRIDES(pyArray()) + N),
+                        permutation(N);
+        for(MultiArrayIndex k=0; k<N; ++k)
+            permutation[k] = k;
+        for(MultiArrayIndex k=0; k<N-1; ++k)
+        {
+            MultiArrayIndex smallest = k;
+            for(MultiArrayIndex j=k+1; j<N; ++j)
+            {
+                if(stride[j] < stride[smallest])
+                    smallest = j;
+            }
+            if(smallest != k)
+            {
+                std::swap(stride[k], stride[smallest]);
+                std::swap(permutation[k], permutation[smallest]);
+            }
+        }
+        difference_type ordering(N);
+        for(MultiArrayIndex k=0; k<N; ++k)
+            ordering[permutation[k]] = k;
+        return ordering;
+    }
+
+        // /**
+         // Returns the the permutation that will transpose this array into
+         // canonical ordering (currently: F-order). The size of
+         // the returned permutation equals ndim().
+         // */
+    // difference_type permutationToNormalOrder() const
+    // {
+        // if(!hasData())
+            // return difference_type();
+
+        // // difference_type res(detail::getAxisPermutationImpl(pyArray_,
+                                               // // "permutationToNormalOrder", true));
+        // difference_type res;
+        // detail::getAxisPermutationImpl(res, pyArray_, "permutationToNormalOrder", true);
+        // if(res.size() == 0)
+        // {
+            // res.resize(ndim());
+            // linearSequence(res.begin(), res.end(), ndim()-1, MultiArrayIndex(-1));
+        // }
+        // return res;
+    // }
+
+        /**
+         Returns the value type of the elements in this array, or -1
+         when hasData() is false.
+         */
+    int dtype() const
+    {
+        if(hasData())
+            return PyArray_DESCR(pyArray())->type_num;
+        return -1;
+    }
+
+        /**
+         * Return the AxisTags of this array or a NULL pointer when the attribute
+           'axistags' is missing in the Python object or this array has no data.
+         */
+    python_ptr axistags() const
+    {
+        python_ptr axistags;
+        if(pyObject())
+        {
+            python_ptr key(PyString_FromString("axistags"), python_ptr::keep_count);
+            axistags.reset(PyObject_GetAttr(pyObject(), key), python_ptr::keep_count);
+            if(!axistags)
+                PyErr_Clear();
+        }
+        return axistags;
+    }
+
+        /**
+         * Return a borrowed reference to the internal PyArrayObject.
+         */
+    PyArrayObject * pyArray() const
+    {
+        return (PyArrayObject *)pyArray_.get();
+    }
+
+        /**
+         * Return a borrowed reference to the internal PyArrayObject
+         * (see pyArray()), cast to PyObject for your convenience.
+         */
+    PyObject * pyObject() const
+    {
+        return pyArray_.get();
+    }
+
+        /**
+           Reset the NumpyAnyArray to the given object. If \a obj is a numpy array object,
+           a new reference to that array is created, and the function returns
+           true. Otherwise, it returns false and the NumpyAnyArray remains unchanged.
+           If \a type is given, the new reference will be a view with that type, provided
+           that \a type is a numpy ndarray or a subclass thereof. Otherwise, an
+           exception is thrown.
+         */
+    bool makeReference(PyObject * obj, PyTypeObject * type = 0)
+    {
+        if(obj == 0 || !PyArray_Check(obj))
+            return false;
+        if(type != 0)
+        {
+            vigra_precondition(PyType_IsSubtype(type, &PyArray_Type) != 0,
+                "NumpyAnyArray::makeReference(obj, type): type must be numpy.ndarray or a subclass thereof.");
+            obj = PyArray_View((PyArrayObject*)obj, 0, type);
+            pythonToCppException(obj);
+        }
+        pyArray_.reset(obj);
+        return true;
+    }
+
+        /**
+           Create a copy of the given array object. If \a obj is a numpy array object,
+           a copy is created via the C-equivalent of 'obj->copy()'. If
+           this call fails, or obj was not an array, an exception is thrown
+           and the NumpyAnyArray remains unchanged.
+         */
+    void makeCopy(PyObject * obj, PyTypeObject * type = 0)
+    {
+        vigra_precondition(obj && PyArray_Check(obj),
+             "NumpyAnyArray::makeCopy(obj): obj is not an array.");
+        vigra_precondition(type == 0 || PyType_IsSubtype(type, &PyArray_Type),
+             "NumpyAnyArray::makeCopy(obj, type): type must be numpy.ndarray or a subclass thereof.");
+        python_ptr array(PyArray_NewCopy((PyArrayObject*)obj, NPY_ANYORDER), python_ptr::keep_count);
+        pythonToCppException(array);
+        makeReference(array, type);
+    }
+
+         /**
+           Check whether this NumpyAnyArray actually points to a Python array.
+         */
+    bool hasData() const
+    {
+        return pyArray_ != 0;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                    constructArray                    */
+/*                                                      */
+/********************************************************/
+
+namespace detail {
+
+inline bool
+nontrivialPermutation(ArrayVector<npy_intp> const & p)
+{
+    for(unsigned int k=0; k<p.size(); ++k)
+        if(p[k] != k)
+            return true;
+    return false;
+}
+
+} // namespace detail
+
+template <class TYPECODE> // pseudo-template to avoid inline expansion of the function
+                          // will always be NPY_TYPES
+PyObject *
+constructArray(TaggedShape tagged_shape, TYPECODE typeCode, bool init, python_ptr arraytype)
+{
+    ArrayVector<npy_intp> shape = finalizeTaggedShape(tagged_shape);
+    PyAxisTags axistags(tagged_shape.axistags);
+
+    int ndim = (int)shape.size();
+    ArrayVector<npy_intp> inverse_permutation;
+    int order = 1; // Fortran order
+
+    if(axistags)
+    {
+        if(!arraytype)
+            arraytype = NumpyAnyArray::getArrayTypeObject();
+
+        inverse_permutation = axistags.permutationFromNormalOrder();
+        vigra_precondition(ndim == (int)inverse_permutation.size(),
+                     "axistags.permutationFromNormalOrder(): permutation has wrong size.");
+    }
+    else
+    {
+        arraytype = python_ptr((PyObject*)&PyArray_Type);
+        order = 0; // C order
+    }
+
+//    std::cerr << "constructArray: " << shape << "\n" << inverse_permutation << "\n";
+
+    python_ptr array(PyArray_New((PyTypeObject *)arraytype.get(), ndim, shape.begin(),
+                                  typeCode, 0, 0, 0, order, 0),
+                     python_ptr::keep_count);
+    pythonToCppException(array);
+
+    if(detail::nontrivialPermutation(inverse_permutation))
+    {
+        PyArray_Dims permute = { inverse_permutation.begin(), ndim };
+        array = python_ptr(PyArray_Transpose((PyArrayObject*)array.get(), &permute),
+                           python_ptr::keep_count);
+        pythonToCppException(array);
+    }
+
+    if(arraytype != (PyObject*)&PyArray_Type && axistags)
+        pythonToCppException(PyObject_SetAttrString(array, "axistags", axistags.axistags) != -1);
+
+    if(init)
+        PyArray_FILLWBYTE((PyArrayObject *)array.get(), 0);
+
+    return array.release();
+}
+
+// FIXME: reimplement in terms of TaggedShape?
+template <class TINY_VECTOR>
+inline
+python_ptr constructNumpyArrayFromData(
+    TINY_VECTOR const & shape, npy_intp *strides,
+    NPY_TYPES typeCode, void *data)
+{
+    ArrayVector<npy_intp> pyShape(shape.begin(), shape.end());
+
+#ifndef NPY_ARRAY_WRITEABLE
+#  define NPY_ARRAY_WRITEABLE NPY_WRITEABLE    // old API compatibility
+#endif
+
+    python_ptr array(PyArray_New(&PyArray_Type, shape.size(), pyShape.begin(),
+                                 typeCode, strides, data, 0, NPY_ARRAY_WRITEABLE, 0),
+                     python_ptr::keep_count);
+    pythonToCppException(array);
+
+    return array;
+}
+
+/********************************************************/
+/*                                                      */
+/*                     NumpyArray                       */
+/*                                                      */
+/********************************************************/
+
+/** Provide the MultiArrayView interface for a Python array.
+
+    This class inherits from both \ref vigra::MultiArrayView and \ref vigra::NumpyAnyArray
+    in order to support easy and save application of VIGRA functions to Python arrays.
+
+    <b>\#include</b> \<vigra/numpy_array.hxx\><br>
+    Namespace: vigra
+*/
+template <unsigned int N, class T, class Stride = StridedArrayTag>
+class NumpyArray
+: public MultiArrayView<N, typename NumpyArrayTraits<N, T, Stride>::value_type, Stride>,
+  public NumpyAnyArray
+{
+  public:
+    typedef NumpyArrayTraits<N, T, Stride> ArrayTraits;
+    typedef typename ArrayTraits::dtype dtype;
+    typedef T pseudo_value_type;
+
+    static NPY_TYPES const typeCode = ArrayTraits::typeCode;
+
+        /** the view type associated with this array.
+         */
+    typedef MultiArrayView<N, typename ArrayTraits::value_type, Stride> view_type;
+
+    enum { actual_dimension = view_type::actual_dimension };
+
+        /** the array's value type
+         */
+    typedef typename view_type::value_type value_type;
+
+        /** pointer type
+         */
+    typedef typename view_type::pointer pointer;
+
+        /** const pointer type
+         */
+    typedef typename view_type::const_pointer const_pointer;
+
+        /** reference type (result of operator[])
+         */
+    typedef typename view_type::reference reference;
+
+        /** const reference type (result of operator[] const)
+         */
+    typedef typename view_type::const_reference const_reference;
+
+        /** size type
+         */
+    typedef typename view_type::size_type size_type;
+
+        /** difference type (used for multi-dimensional offsets and indices)
+         */
+    typedef typename view_type::difference_type difference_type;
+
+        /** difference and index type for a single dimension
+         */
+    typedef typename view_type::difference_type_1 difference_type_1;
+
+        /** type of an array specifying an axis permutation
+         */
+    typedef typename NumpyAnyArray::difference_type permutation_type;
+
+        /** traverser type
+         */
+    typedef typename view_type::traverser traverser;
+
+        /** traverser type to const data
+         */
+    typedef typename view_type::const_traverser const_traverser;
+
+        /** sequential (random access) iterator type
+         */
+    typedef typename view_type::iterator iterator;
+
+        /** sequential (random access) const iterator type
+         */
+    typedef typename view_type::const_iterator const_iterator;
+
+    using view_type::shape;   // resolve ambiguity of multiple inheritance
+    using view_type::hasData; // resolve ambiguity of multiple inheritance
+    using view_type::strideOrdering; // resolve ambiguity of multiple inheritance
+
+  protected:
+
+    // this function assumes that pyArray_ has already been set, and compatibility been checked
+    void setupArrayView();
+
+    static python_ptr init(difference_type const & shape, bool init = true,
+                           std::string const & order = "")
+    {
+        vigra_precondition(order == "" || order == "C" || order == "F" ||
+                           order == "V" || order == "A",
+            "NumpyArray.init(): order must be in ['C', 'F', 'V', 'A', ''].");
+        return python_ptr(constructArray(ArrayTraits::taggedShape(shape, order), typeCode, init),
+                          python_ptr::keep_count);
+    }
+
+  public:
+
+    using view_type::init;
+
+        /**
+         * Construct from a given PyObject pointer. When the given
+         * python object is NULL, the internal python array will be
+         * NULL and hasData() will return false.
+         *
+         * Otherwise, the function attempts to create a
+         * new reference to the given Python object, unless
+         * copying is forced by setting \a createCopy to true.
+         * If either of this fails, the function throws an exception.
+         * This will not happen if isReferenceCompatible(obj) (in case
+         * of creating a new reference) or isCopyCompatible(obj)
+         * (in case of copying) have returned true beforehand.
+         */
+    explicit NumpyArray(PyObject *obj = 0, bool createCopy = false)
+    {
+        if(obj == 0)
+            return;
+        if(createCopy)
+            makeCopy(obj);
+        else
+            vigra_precondition(makeReference(obj),
+                  "NumpyArray(obj): Cannot construct from incompatible array.");
+    }
+
+       /**
+         * Copy constructor; does not copy the memory, but creates a
+         * new reference to the same underlying python object, unless
+         * a copy is forced by setting \a createCopy to true.
+         * (If the source object has no data, this one will have
+         * no data, too.)
+         */
+    NumpyArray(const NumpyArray &other, bool createCopy = false)
+    : view_type(),
+      NumpyAnyArray()
+    {
+        if(!other.hasData())
+            return;
+        if(createCopy)
+            makeCopy(other.pyObject());
+        else
+            makeReferenceUnchecked(other.pyObject());
+    }
+
+       /**
+         * Allocate new memory and copy data from a MultiArrayView.
+         */
+    template <class U, class S>
+    explicit NumpyArray(const MultiArrayView<N, U, S> &other)
+    {
+        if(!other.hasData())
+            return;
+        vigra_postcondition(makeReference(init(other.shape(), false)),
+                  "NumpyArray(MultiArrayView): Python constructor did not produce a compatible array.");
+        view_type::operator=(other);
+    }
+
+        /**
+         * Construct a new array object, allocating an internal python
+         * ndarray of the given shape in the given order (default: VIGRA order), initialized
+         * with zeros.
+         *
+         * An exception is thrown when construction fails.
+         */
+    explicit NumpyArray(difference_type const & shape, std::string const & order = "")
+    {
+        vigra_postcondition(makeReference(init(shape, true, order)),
+                     "NumpyArray(shape): Python constructor did not produce a compatible array.");
+    }
+
+        /**
+         * Construct a new array object, allocating an internal python
+         * ndarray according to the given tagged shape, initialized with zeros.
+         *
+         * An exception is thrown when construction fails.
+         */
+    explicit NumpyArray(TaggedShape const & tagged_shape)
+    {
+        reshapeIfEmpty(tagged_shape,
+           "NumpyArray(tagged_shape): Python constructor did not produce a compatible array.");
+    }
+
+        /**
+         * Constructor from NumpyAnyArray.
+         * Equivalent to NumpyArray(other.pyObject())
+         */
+    explicit NumpyArray(const NumpyAnyArray &other, bool createCopy = false)
+    {
+        if(!other.hasData())
+            return;
+        if(createCopy)
+            makeCopy(other.pyObject());
+        else
+            vigra_precondition(makeReference(other.pyObject()), //, false),
+                   "NumpyArray(NumpyAnyArray): Cannot construct from incompatible or empty array.");
+    }
+
+        /**
+         * Assignment operator. If this is already a view with data
+         * (i.e. hasData() is true) and the shapes match, the RHS
+         * array contents are copied.  If this is an empty view,
+         * assignment is identical to makeReferenceUnchecked(other.pyObject()).
+         * See MultiArrayView::operator= for further information on
+         * semantics.
+         */
+    NumpyArray &operator=(const NumpyArray &other)
+    {
+        if(hasData())
+            view_type::operator=(other);
+        else
+            makeReferenceUnchecked(other.pyObject());
+        return *this;
+    }
+
+        /**
+         * Assignment operator. If this is already a view with data
+         * (i.e. hasData() is true) and the shapes match, the RHS
+         * array contents are copied.  If this is an empty view,
+         * assignment is identical to makeReferenceUnchecked(other.pyObject()).
+         * See MultiArrayView::operator= for further information on
+         * semantics.
+         */
+    template <class U, class S>
+    NumpyArray &operator=(const NumpyArray<N, U, S> &other)
+    {
+        if(hasData())
+        {
+            vigra_precondition(shape() == other.shape(),
+                "NumpyArray::operator=(): shape mismatch.");
+            view_type::operator=(other);
+        }
+        else if(other.hasData())
+        {
+            NumpyArray copy;
+            copy.reshapeIfEmpty(other.taggedShape(),
+                "NumpyArray::operator=(): reshape failed unexpectedly.");
+            copy = other;
+            makeReferenceUnchecked(copy.pyObject());
+        }
+        return *this;
+    }
+
+        /**
+         * Assignment operator. If this is already a view with data
+         * (i.e. hasData() is true) and the shapes match, the RHS
+         * array contents are copied.  If this is an empty view,
+         * a new buffer with the RHS shape is allocated before copying.
+         */
+    template <class U, class S>
+    NumpyArray &operator=(const MultiArrayView<N, U, S> &other)
+    {
+        if(hasData())
+        {
+            vigra_precondition(shape() == other.shape(),
+                "NumpyArray::operator=(): shape mismatch.");
+            view_type::operator=(other);
+        }
+        else if(other.hasData())
+        {
+            NumpyArray copy;
+            copy.reshapeIfEmpty(other.shape(),
+                "NumpyArray::operator=(): reshape failed unexpectedly.");
+            copy = other;
+            makeReferenceUnchecked(copy.pyObject());
+        }
+        return *this;
+    }
+
+        /**
+         * Assignment operator. If this is already a view with data
+         * (i.e. hasData() is true) and the shapes match, the RHS
+         * array contents are copied.
+         * If this is an empty view, assignment is identical to
+         * makeReference(other.pyObject()).
+         * Otherwise, an exception is thrown.
+         */
+    NumpyArray &operator=(const NumpyAnyArray &other)
+    {
+        if(hasData())
+        {
+            NumpyAnyArray::operator=(other);
+        }
+        else if(isReferenceCompatible(other.pyObject()))
+        {
+            makeReferenceUnchecked(other.pyObject());
+        }
+        else
+        {
+            vigra_precondition(false,
+                "NumpyArray::operator=(): Cannot assign from incompatible array.");
+        }
+        return *this;
+    }
+
+        /**
+         Permute the entries of the given array \a data exactly like the axes of this NumpyArray
+         were permuted upon conversion from numpy.
+         */
+    template <class U>
+    ArrayVector<U>
+    permuteLikewise(ArrayVector<U> const & data) const
+    {
+        vigra_precondition(hasData(),
+            "NumpyArray::permuteLikewise(): array has no data.");
+
+        ArrayVector<U> res(data.size());
+        ArrayTraits::permuteLikewise(this->pyArray_, data, res);
+        return res;
+    }
+
+        /**
+         Permute the entries of the given array \a data exactly like the axes of this NumpyArray
+         were permuted upon conversion from numpy.
+         */
+    template <class U, int K>
+    TinyVector<U, K>
+    permuteLikewise(TinyVector<U, K> const & data) const
+    {
+        vigra_precondition(hasData(),
+            "NumpyArray::permuteLikewise(): array has no data.");
+
+        TinyVector<U, K> res;
+        ArrayTraits::permuteLikewise(this->pyArray_, data, res);
+        return res;
+    }
+
+        /**
+         Get the permutation of the axes of this NumpyArray
+         that was performed upon conversion from numpy.
+         */
+    template <int K>
+    TinyVector<npy_intp, K>
+    permuteLikewise() const
+    {
+        vigra_precondition(hasData(),
+            "NumpyArray::permuteLikewise(): array has no data.");
+
+        TinyVector<npy_intp, K> data, res;
+        linearSequence(data.begin(), data.end());
+        ArrayTraits::permuteLikewise(this->pyArray_, data, res);
+        return res;
+    }
+
+        /**
+         * Test whether a given python object is a numpy array that can be
+         * converted (copied) into an array compatible to this NumpyArray type.
+         * This means that the array's shape conforms to the requirements of
+         * makeCopy().
+         */
+    static bool isCopyCompatible(PyObject *obj)
+    {
+#if VIGRA_CONVERTER_DEBUG
+        std::cerr << "class " << typeid(NumpyArray).name() << " got " << obj->ob_type->tp_name << "\n";
+        std::cerr << "using traits " << typeid(ArrayTraits).name() << "\n";
+        std::cerr<<"isArray: "<< ArrayTraits::isArray(obj)<<std::endl;
+        std::cerr<<"isShapeCompatible: "<< ArrayTraits::isShapeCompatible((PyArrayObject *)obj)<<std::endl;
+#endif
+
+        return ArrayTraits::isArray(obj) &&
+               ArrayTraits::isShapeCompatible((PyArrayObject *)obj);
+    }
+
+        /**
+         * Test whether a given python object is a numpy array with a
+         * compatible dtype and the correct shape and strides, so that it
+         * can be referenced as a view by this NumpyArray type (i.e.
+         * it conforms to the requirements of makeReference()).
+         */
+    static bool isReferenceCompatible(PyObject *obj)
+    {
+        return ArrayTraits::isArray(obj) &&
+               ArrayTraits::isPropertyCompatible((PyArrayObject *)obj);
+    }
+
+        /**
+         * Deprecated, use isReferenceCompatible(obj) instead.
+         */
+    static bool isStrictlyCompatible(PyObject *obj)
+    {
+        return isReferenceCompatible(obj);
+    }
+
+        /**
+         * Create a vector representing the standard stride ordering of a NumpyArray.
+         * That is, we get a vector representing the range [0,...,N-1], which
+         * denotes the stride ordering for Fortran order.
+         */
+    static difference_type standardStrideOrdering()
+    {
+        difference_type strideOrdering;
+        for(unsigned int k=0; k<N; ++k)
+            strideOrdering[k] = k;
+        return strideOrdering;
+    }
+
+        /**
+         * Set up a view to the given object without checking compatibility.
+         * This function must not be used unless isReferenceCompatible(obj) returned
+         * true on the given object (otherwise, a crash is likely).
+         */
+    void makeReferenceUnchecked(PyObject *obj)
+    {
+        NumpyAnyArray::makeReference(obj);
+        setupArrayView();
+    }
+
+        /**
+         * Try to set up a view referencing the given PyObject.
+         * Returns false if the python object is not a compatible
+         * numpy array (see isReferenceCompatible()).
+         *
+         * The second parameter ('strict') is deprecated and will be ignored.
+         */
+    bool makeReference(PyObject *obj, bool /* strict */ = false)
+    {
+        if(!isReferenceCompatible(obj))
+            return false;
+        makeReferenceUnchecked(obj);
+        return true;
+    }
+
+        /**
+         * Try to set up a view referencing the same data as the given
+         * NumpyAnyArray.  This overloaded variant simply calls
+         * makeReference() on array.pyObject(). The parameter \a strict
+         * is deprecated and will be ignored.
+         */
+    bool makeReference(const NumpyAnyArray &array, bool strict = false)
+    {
+        return makeReference(array.pyObject(), strict);
+    }
+
+        /**
+         * Set up an unsafe reference to the given MultiArrayView.
+         * ATTENTION: This creates a numpy.ndarray that points to the
+         * same data, but does not own it, so it must be ensured by
+         * other means that the memory does not get freed before the
+         * end of the ndarray's lifetime!  (One elegant way would be
+         * to set the 'base' attribute of the resulting ndarray to a
+         * python object which directly or indirectly holds the memory
+         * of the given MultiArrayView.)
+         */
+    void makeUnsafeReference(const view_type &multiArrayView)
+    {
+        vigra_precondition(!hasData(),
+            "makeUnsafeReference(): cannot replace existing view with given buffer");
+
+        // construct an ndarray that points to our data (taking strides into account):
+        python_ptr array(ArrayTraits::unsafeConstructorFromData(multiArrayView.shape(),
+                                  multiArrayView.data(), multiArrayView.stride()));
+
+        view_type::operator=(multiArrayView);
+        pyArray_ = array;
+    }
+
+        /**
+         Try to create a copy of the given PyObject.
+         Raises an exception when obj is not a compatible array
+         (see isCopyCompatible() or isReferenceCompatible(), according to the
+         parameter \a strict) or the Python constructor call failed.
+         */
+    void makeCopy(PyObject *obj, bool strict = false)
+    {
+#if VIGRA_CONVERTER_DEBUG
+        int ndim = PyArray_NDIM((PyArrayObject *)obj);
+        npy_intp * s = PyArray_DIMS((PyArrayObject *)obj);
+        std::cerr << "makeCopy: " << ndim << " " <<  ArrayVectorView<npy_intp>(ndim, s) <<
+                     ", strides " << ArrayVectorView<npy_intp>(ndim, PyArray_STRIDES((PyArrayObject *)obj)) << "\n";
+        std::cerr << "for " << typeid(*this).name() << "\n";
+#endif
+        vigra_precondition(strict ? isReferenceCompatible(obj) : isCopyCompatible(obj),
+                     "NumpyArray::makeCopy(obj): Cannot copy an incompatible array.");
+
+        NumpyAnyArray copy(obj, true);
+        makeReferenceUnchecked(copy.pyObject());
+    }
+
+        /**
+            Allocate new memory with the given shape and initialize with zeros.<br>
+            If a stride ordering is given, the resulting array will have this stride
+            ordering, when it is compatible with the array's memory layout (unstrided
+            arrays only permit the standard ascending stride ordering).
+
+            <em>Note:</em> this operation invalidates dependent objects
+            (MultiArrayViews and iterators)
+         */
+    void reshape(difference_type const & shape)
+    {
+        vigra_postcondition(makeReference(init(shape)),
+                "NumpyArray.reshape(shape): Python constructor did not produce a compatible array.");
+    }
+
+        /**
+            When this array has no data, allocate new memory with the given \a shape and
+            initialize with zeros. Otherwise, check if the new shape matches the old shape
+            and throw a precondition exception with the given \a message if not.
+         */
+    void reshapeIfEmpty(difference_type const & shape, std::string message = "")
+    {
+        // FIXME: is this really a good replacement?
+        // reshapeIfEmpty(shape, standardStrideOrdering(), message);
+        reshapeIfEmpty(TaggedShape(shape), message);
+    }
+
+        /**
+            When this array has no data, allocate new memory with the given \a shape and
+            initialize with zeros. Otherwise, check if the new shape matches the old shape
+            and throw a precondition exception with the given \a message if not.
+         */
+    void reshapeIfEmpty(TaggedShape tagged_shape, std::string message = "")
+    {
+        ArrayTraits::finalizeTaggedShape(tagged_shape);
+
+        if(hasData())
+        {
+            vigra_precondition(tagged_shape.compatible(taggedShape()), message.c_str());
+        }
+        else
+        {
+            python_ptr array(constructArray(tagged_shape, typeCode, true),
+                             python_ptr::keep_count);
+            vigra_postcondition(makeReference(NumpyAnyArray(array.get())),
+                  "NumpyArray.reshapeIfEmpty(): Python constructor did not produce a compatible array.");
+        }
+    }
+
+    TaggedShape taggedShape() const
+    {
+        return ArrayTraits::taggedShape(this->shape(), PyAxisTags(this->axistags(), true));
+    }
+};
+
+    // this function assumes that pyArray_ has already been set, and compatibility been checked
+template <unsigned int N, class T, class Stride>
+void NumpyArray<N, T, Stride>::setupArrayView()
+{
+    if(NumpyAnyArray::hasData())
+    {
+        permutation_type permute;
+        ArrayTraits::permutationToSetupOrder(this->pyArray_, permute);
+
+        vigra_precondition(abs((int)permute.size() - actual_dimension) <= 1,
+            "NumpyArray::setupArrayView(): got array of incompatible shape (should never happen).");
+
+        applyPermutation(permute.begin(), permute.end(),
+                         PyArray_DIMS(pyArray()), this->m_shape.begin());
+        applyPermutation(permute.begin(), permute.end(),
+                         PyArray_STRIDES(pyArray()), this->m_stride.begin());
+
+        if((int)permute.size() == actual_dimension - 1)
+        {
+            this->m_shape[actual_dimension-1] = 1;
+            this->m_stride[actual_dimension-1] = sizeof(value_type);
+        }
+
+        this->m_stride /= sizeof(value_type);
+        this->m_ptr = reinterpret_cast<pointer>(PyArray_DATA(pyArray()));
+        vigra_precondition(this->checkInnerStride(Stride()),
+            "NumpyArray<..., UnstridedArrayTag>::setupArrayView(): First dimension of given array is not unstrided (should never happen).");
+
+    }
+    else
+    {
+        this->m_ptr = 0;
+    }
+}
+
+
+typedef NumpyArray<2, float >  NumpyFArray2;
+typedef NumpyArray<3, float >  NumpyFArray3;
+typedef NumpyArray<4, float >  NumpyFArray4;
+typedef NumpyArray<2, Singleband<float> >  NumpyFImage;
+typedef NumpyArray<3, Singleband<float> >  NumpyFVolume;
+typedef NumpyArray<2, RGBValue<float> >  NumpyFRGBImage;
+typedef NumpyArray<3, RGBValue<float> >  NumpyFRGBVolume;
+typedef NumpyArray<3, Multiband<float> >  NumpyFMultibandImage;
+typedef NumpyArray<4, Multiband<float> >  NumpyFMultibandVolume;
+
+/********************************************************/
+/*                                                      */
+/*   NumpyArray Multiband Argument Object Factories     */
+/*                                                      */
+/********************************************************/
+
+template <class PixelType, class Stride>
+inline triple<ConstStridedImageIterator<PixelType>,
+              ConstStridedImageIterator<PixelType>,
+              MultibandVectorAccessor<PixelType> >
+srcImageRange(NumpyArray<3, Multiband<PixelType>, Stride> const & img)
+{
+    ConstStridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    return triple<ConstStridedImageIterator<PixelType>,
+                  ConstStridedImageIterator<PixelType>,
+                  MultibandVectorAccessor<PixelType> >
+        (ul, ul + Size2D(img.shape(0), img.shape(1)), MultibandVectorAccessor<PixelType>(img.shape(2), img.stride(2)));
+}
+
+template <class PixelType, class Stride>
+inline pair< ConstStridedImageIterator<PixelType>,
+             MultibandVectorAccessor<PixelType> >
+srcImage(NumpyArray<3, Multiband<PixelType>, Stride> const & img)
+{
+    ConstStridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    return pair<ConstStridedImageIterator<PixelType>, MultibandVectorAccessor<PixelType> >
+        (ul, MultibandVectorAccessor<PixelType>(img.shape(2), img.stride(2)));
+}
+
+template <class PixelType, class Stride>
+inline triple< StridedImageIterator<PixelType>,
+               StridedImageIterator<PixelType>,
+               MultibandVectorAccessor<PixelType> >
+destImageRange(NumpyArray<3, Multiband<PixelType>, Stride> & img)
+{
+    StridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    return triple<StridedImageIterator<PixelType>,
+                  StridedImageIterator<PixelType>,
+                  MultibandVectorAccessor<PixelType> >
+        (ul, ul + Size2D(img.shape(0), img.shape(1)),
+        MultibandVectorAccessor<PixelType>(img.shape(2), img.stride(2)));
+}
+
+template <class PixelType, class Stride>
+inline pair< StridedImageIterator<PixelType>,
+             MultibandVectorAccessor<PixelType> >
+destImage(NumpyArray<3, Multiband<PixelType>, Stride> & img)
+{
+    StridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    return pair<StridedImageIterator<PixelType>, MultibandVectorAccessor<PixelType> >
+        (ul, MultibandVectorAccessor<PixelType>(img.shape(2), img.stride(2)));
+}
+
+template <class PixelType, class Stride>
+inline pair< ConstStridedImageIterator<PixelType>,
+             MultibandVectorAccessor<PixelType> >
+maskImage(NumpyArray<3, Multiband<PixelType>, Stride> const & img)
+{
+    ConstStridedImageIterator<PixelType>
+        ul(img.data(), 1, img.stride(0), img.stride(1));
+    return pair<ConstStridedImageIterator<PixelType>, MultibandVectorAccessor<PixelType> >
+        (ul, MultibandVectorAccessor<PixelType>(img.shape(2), img.stride(2)));
+}
+
+} // namespace vigra
+
+#endif // VIGRA_NUMPY_ARRAY_HXX
diff --git a/include/vigra/numpy_array_converters.hxx b/include/vigra/numpy_array_converters.hxx
new file mode 100644
index 0000000..c27716b
--- /dev/null
+++ b/include/vigra/numpy_array_converters.hxx
@@ -0,0 +1,304 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2009 by Ullrich Koethe and Hans Meine                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_NUMPY_ARRAY_CONVERTERS_HXX
+#define VIGRA_NUMPY_ARRAY_CONVERTERS_HXX
+
+#include "numpy_array.hxx"
+#include "metaprogramming.hxx"
+#include <boost/python.hpp>
+#include <boost/python/to_python_converter.hpp>
+#include <set>
+
+namespace vigra {
+
+template <class Array>
+PyObject * returnNumpyArray(Array const & a)
+{
+    PyObject * pa = a.pyObject();
+    if(pa == 0)
+        PyErr_SetString(PyExc_ValueError, "returnNumpyArray(): Conversion to Python failed, array has no data.");
+    else
+        Py_INCREF(pa);
+    return pa;
+}
+
+VIGRA_EXPORT std::set<std::string> & exportedArrayKeys();
+
+template <class ArrayType>
+struct NumpyArrayConverter {};
+
+template <unsigned int N, class T, class Stride>
+struct NumpyArrayConverter<NumpyArray<N, T, Stride> >
+{
+    typedef NumpyArray<N, T, Stride> ArrayType;
+    typedef typename ArrayType::ArrayTraits ArrayTraits;
+    
+    NumpyArrayConverter();
+        
+    static void* convertible(PyObject* obj);
+
+    // from Python
+    static void construct(PyObject* obj, 
+        boost::python::converter::rvalue_from_python_stage1_data* data);
+
+    // to Python
+    static PyObject* convert(ArrayType const& a)
+    {
+        return returnNumpyArray(a);
+    }
+};
+
+template <unsigned int N, class T, class Stride>
+NumpyArrayConverter<NumpyArray<N, T, Stride> >::NumpyArrayConverter()
+{
+    using namespace boost::python;
+    
+    converter::registration const * reg = converter::registry::query(type_id<ArrayType>());
+    
+    // register the to_python_converter only once
+    // FIXME: I'm not sure if this is correct.
+    if(!reg || !reg->rvalue_chain)
+    {
+        to_python_converter<ArrayType, NumpyArrayConverter>();
+    }
+    converter::registry::insert(&convertible, &construct, type_id<ArrayType>());
+}
+    
+template <unsigned int N, class T, class Stride>
+void * NumpyArrayConverter<NumpyArray<N, T, Stride> >::convertible(PyObject* obj)
+{
+    bool isCompatible = obj == Py_None || ArrayType::isStrictlyCompatible(obj);
+    // std::cerr << "compatible for " << typeid(NumpyArray<N, T, Stride>).name() << ": " << isCompatible << "\n";
+    return isCompatible
+             ? obj
+             : 0;
+}
+
+// from Python
+template <unsigned int N, class T, class Stride>
+void NumpyArrayConverter<NumpyArray<N, T, Stride> >::construct(PyObject* obj, 
+                   boost::python::converter::rvalue_from_python_stage1_data* data)
+{
+    void* const storage =   
+        ((boost::python::converter::rvalue_from_python_storage<ArrayType>* ) data)->storage.bytes;
+
+    ArrayType * array = new (storage) ArrayType();
+    if(obj != Py_None)
+        array->makeReferenceUnchecked(obj);
+
+    data->convertible = storage;
+}
+
+template <unsigned int N, class T, class Stride>
+struct NumpyArrayConverter<MultiArrayView<N, T, Stride> >
+: public NumpyArrayConverter<NumpyArray<N, T, Stride> >
+{
+    typedef NumpyArrayConverter<NumpyArray<N, T, Stride> > BaseType;
+    typedef MultiArrayView<N, T, Stride> ArrayType;
+    
+    NumpyArrayConverter()
+    {
+        using namespace boost::python;
+        converter::registry::insert(&BaseType::convertible, &BaseType::construct, 
+                                    type_id<ArrayType>());
+    }
+};
+
+template <class Iter, class End>
+struct RegisterNumpyArrayConverters
+{
+    static void exec()
+    {
+        typedef typename UnqualifiedType<typename boost::mpl::deref<Iter>::type>::type Type;
+        NumpyArrayConverter<Type>();
+        RegisterNumpyArrayConverters<typename boost::mpl::next<Iter>::type, End>::exec();
+    }
+};
+
+template <class End>
+struct RegisterNumpyArrayConverters<End, End>
+{
+    static void exec()
+    {}
+};
+
+template <class Typelist>
+void registerNumpyArrayConverters(Typelist)
+{
+    RegisterNumpyArrayConverters<typename boost::mpl::begin<Typelist>::type, 
+                                 typename boost::mpl::end<Typelist>::type >::exec();
+}
+
+template <class FN>
+FN registerConverters(FN f)
+{
+    registerNumpyArrayConverters(boost::python::detail::get_signature(f));
+    return f;
+}
+
+
+} // namespace vigra
+
+namespace boost { namespace python {
+
+#define VIGRA_PYTHON_MULTITYPE_FUNCTOR(functor_name, function) \
+template <class T> \
+struct functor_name##Impl \
+{ \
+    typedef functor_name##Impl type; \
+     \
+    static void def(const char * pythonName) \
+    { \
+        boost::python::def(pythonName, vigra::registerConverters(&function<T>)); \
+    } \
+     \
+    template <class A1> \
+    static void def(const char * pythonName, A1 const & a1) \
+    { \
+        boost::python::def(pythonName, vigra::registerConverters(&function<T>), a1); \
+    } \
+     \
+    template <class A1, class A2> \
+    static void def(const char * pythonName, A1 const & a1, A2 const & a2) \
+    { \
+        boost::python::def(pythonName, vigra::registerConverters(&function<T>), a1, a2); \
+    } \
+     \
+    template <class A1, class A2, class A3> \
+    static void def(const char * pythonName, A1 const & a1, A2 const & a2, A3 const & a3) \
+    { \
+        boost::python::def(pythonName, vigra::registerConverters(&function<T>), a1, a2, a3); \
+    } \
+}; \
+ \
+template <> \
+struct functor_name##Impl<void> \
+{ \
+    typedef void type; \
+}; \
+ \
+template <class T1, \
+          class T2 = void, \
+          class T3 = void, \
+          class T4 = void, \
+          class T5 = void, \
+          class T6 = void, \
+          class T7 = void, \
+          class T8 = void, \
+          class T9 = void, \
+          class T10 = void, \
+          class T11 = void, \
+          class T12 = void> \
+struct functor_name \
+: public boost::python::TypeList<typename functor_name##Impl<T1>::type, \
+         boost::python::TypeList<typename functor_name##Impl<T2>::type, \
+         boost::python::TypeList<typename functor_name##Impl<T3>::type, \
+         boost::python::TypeList<typename functor_name##Impl<T4>::type, \
+         boost::python::TypeList<typename functor_name##Impl<T5>::type, \
+         boost::python::TypeList<typename functor_name##Impl<T6>::type, \
+         boost::python::TypeList<typename functor_name##Impl<T7>::type, \
+         boost::python::TypeList<typename functor_name##Impl<T8>::type, \
+         boost::python::TypeList<typename functor_name##Impl<T9>::type, \
+         boost::python::TypeList<typename functor_name##Impl<T10>::type, \
+         boost::python::TypeList<typename functor_name##Impl<T11>::type, \
+         boost::python::TypeList<typename functor_name##Impl<T12>::type, \
+         boost::python::TypeList<void, void> > > > > > > > > > > > > \
+{};
+
+template <class Head, class Tail>
+struct TypeList
+{
+    typedef Head head;
+    typedef Tail tail;
+};
+
+// in the sequel, the doc string is only registered with the last
+// overload, so that it shows up only once
+template <class Head, class Tail>
+inline void multidef(char const* functor_name, TypeList<Head, Tail>)
+{
+    Head::def(functor_name);
+    multidef(functor_name, Tail());
+}
+
+template <class Head, class Tail>
+inline void multidef(char const* functor_name, TypeList<Head, Tail>, const char * help)
+{
+    Head::def(functor_name);
+    multidef(functor_name, Tail(), help);
+}
+
+template <class Head, class Tail, class Args>
+inline void multidef(char const* functor_name, TypeList<Head, Tail>, Args const& args)
+{
+    Head::def(functor_name, args);
+    multidef(functor_name, Tail(), args);
+}
+
+template <class Head, class Tail, class Args>
+inline void multidef(char const* functor_name, TypeList<Head, Tail>, Args const& args, char const * help)
+{
+    Head::def(functor_name, args);
+    multidef(functor_name, Tail(), args, help);
+}
+
+template <class Head, class Tail>
+inline void multidef(char const* functor_name, TypeList<Head, TypeList<void, Tail> >)
+{
+    Head::def(functor_name);
+}
+
+template <class Head, class Tail, class Args>
+inline void multidef(char const* functor_name, TypeList<Head, TypeList<void, Tail> >, Args const& args)
+{
+    Head::def(functor_name, args);
+}
+
+template <class Head, class Tail>
+inline void multidef(char const* functor_name, TypeList<Head, TypeList<void, Tail> >, const char * help)
+{
+    Head::def(functor_name, help);
+}
+
+template <class Head, class Tail, class Args>
+inline void multidef(char const* functor_name, TypeList<Head, TypeList<void, Tail> >, Args const& args, const char * help)
+{
+    Head::def(functor_name, args, help);
+}
+
+}} // namespace boost::python
+
+#endif // VIGRA_NUMPY_ARRAY_CONVERTERS_HXX
diff --git a/include/vigra/numpy_array_taggedshape.hxx b/include/vigra/numpy_array_taggedshape.hxx
new file mode 100644
index 0000000..f328bd0
--- /dev/null
+++ b/include/vigra/numpy_array_taggedshape.hxx
@@ -0,0 +1,838 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2009 by Ullrich Koethe and Hans Meine                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_NUMPY_ARRAY_TAGGEDSHAPE_HXX
+#define VIGRA_NUMPY_ARRAY_TAGGEDSHAPE_HXX
+
+#ifndef NPY_NO_DEPRECATED_API
+# define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#endif 
+
+#include <string>
+#include "array_vector.hxx"
+#include "python_utility.hxx"
+#include "axistags.hxx"
+
+namespace vigra {
+
+namespace detail {
+
+inline
+python_ptr getArrayTypeObject()
+{
+    python_ptr arraytype((PyObject*)&PyArray_Type);
+    python_ptr vigra(PyImport_ImportModule("vigra"));
+    if(!vigra)
+        PyErr_Clear();
+    return pythonGetAttr(vigra, "standardArrayType", arraytype);
+}
+
+inline 
+std::string defaultOrder(std::string defaultValue = "C")
+{
+    python_ptr arraytype = getArrayTypeObject();
+    return pythonGetAttr(arraytype, "defaultOrder", defaultValue);
+}
+
+inline 
+python_ptr defaultAxistags(int ndim, std::string order = "")
+{
+    if(order == "")
+        order = defaultOrder();
+    python_ptr arraytype = getArrayTypeObject();
+    python_ptr func(PyString_FromString("defaultAxistags"), python_ptr::keep_count);
+    python_ptr d(PyInt_FromLong(ndim), python_ptr::keep_count);
+    python_ptr o(PyString_FromString(order.c_str()), python_ptr::keep_count);
+    python_ptr axistags(PyObject_CallMethodObjArgs(arraytype, func.get(), d.get(), o.get(), NULL),
+                        python_ptr::keep_count);
+    if(axistags)
+        return axistags;
+    PyErr_Clear();
+    return python_ptr();
+}
+
+inline 
+python_ptr emptyAxistags(int ndim)
+{
+    python_ptr arraytype = getArrayTypeObject();
+    python_ptr func(PyString_FromString("_empty_axistags"), python_ptr::keep_count);
+    python_ptr d(PyInt_FromLong(ndim), python_ptr::keep_count);
+    python_ptr axistags(PyObject_CallMethodObjArgs(arraytype, func.get(), d.get(), NULL),
+                        python_ptr::keep_count);
+    if(axistags)
+        return axistags;
+    PyErr_Clear();
+    return python_ptr();
+}
+
+inline 
+void
+getAxisPermutationImpl(ArrayVector<npy_intp> & permute,
+                       python_ptr object, const char * name, 
+                       AxisInfo::AxisType type, bool ignoreErrors)
+{
+    python_ptr func(PyString_FromString(name), python_ptr::keep_count);
+    python_ptr t(PyInt_FromLong((long)type), python_ptr::keep_count);
+    python_ptr permutation(PyObject_CallMethodObjArgs(object, func.get(), t.get(), NULL), 
+                           python_ptr::keep_count);
+    if(!permutation && ignoreErrors)
+    {
+        PyErr_Clear();
+        return;
+    }
+    pythonToCppException(permutation);
+    
+    if(!PySequence_Check(permutation))
+    {
+        if(ignoreErrors)
+            return;
+        std::string message = std::string(name) + "() did not return a sequence.";
+        PyErr_SetString(PyExc_ValueError, message.c_str());
+        pythonToCppException(false);
+    }
+        
+    ArrayVector<npy_intp> res(PySequence_Length(permutation));
+    for(int k=0; k<(int)res.size(); ++k)
+    {
+        python_ptr i(PySequence_GetItem(permutation, k), python_ptr::keep_count);
+        if(!PyInt_Check(i))
+        {
+            if(ignoreErrors)
+                return;
+            std::string message = std::string(name) + "() did not return a sequence of int.";
+            PyErr_SetString(PyExc_ValueError, message.c_str());
+            pythonToCppException(false);
+        }
+        res[k] = PyInt_AsLong(i);
+    }
+    res.swap(permute);
+}
+
+inline 
+void
+getAxisPermutationImpl(ArrayVector<npy_intp> & permute,
+                       python_ptr object, const char * name, bool ignoreErrors)
+{
+    getAxisPermutationImpl(permute, object, name, AxisInfo::AllAxes, ignoreErrors);
+}
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*                     PyAxisTags                       */
+/*                                                      */
+/********************************************************/
+
+// FIXME: right now, we implement this class using the standard
+//        Python C-API only. It would be easier and more efficient 
+//        to use boost::python here, but it would cause NumpyArray
+//        to depend on boost, making it more difficult to use
+//        NumpyArray in connection with other glue code generators.
+class PyAxisTags
+{
+  public:
+    typedef PyObject * pointer;
+    
+    python_ptr axistags;
+    
+    PyAxisTags(python_ptr tags = python_ptr(), bool createCopy = false)
+    {
+        if(!tags)
+            return;
+        // FIXME: do a more elaborate type check here?
+        if(!PySequence_Check(tags))
+        {
+            PyErr_SetString(PyExc_TypeError, 
+                           "PyAxisTags(tags): tags argument must have type 'AxisTags'.");
+            pythonToCppException(false);
+        }
+        else if(PySequence_Length(tags) == 0)
+        {
+            return;
+        }
+        
+        if(createCopy)
+        {
+            python_ptr func(PyString_FromString("__copy__"), python_ptr::keep_count);
+            axistags = python_ptr(PyObject_CallMethodObjArgs(tags, func.get(), NULL), 
+                                  python_ptr::keep_count);
+        }
+        else
+        {
+            axistags = tags;
+        }
+    }
+    
+    PyAxisTags(PyAxisTags const & other, bool createCopy = false)
+    {
+        if(!other.axistags)
+            return;
+        if(createCopy)
+        {
+            python_ptr func(PyString_FromString("__copy__"), python_ptr::keep_count);
+            axistags = python_ptr(PyObject_CallMethodObjArgs(other.axistags, func.get(), NULL), 
+                                  python_ptr::keep_count);
+        }
+        else
+        {
+            axistags = other.axistags;
+        }
+    }
+    
+    PyAxisTags(int ndim, std::string const & order = "")
+    {
+        if(order != "")
+            axistags = detail::defaultAxistags(ndim, order);
+        else
+            axistags = detail::emptyAxistags(ndim);
+    }
+    
+    long size() const
+    {
+        return axistags
+                   ? PySequence_Length(axistags)
+                   : 0;
+    }
+    
+    long channelIndex(long defaultVal) const
+    {
+        return pythonGetAttr(axistags, "channelIndex", defaultVal);
+    }
+
+    long channelIndex() const
+    {
+        return channelIndex(size());
+    }
+
+    bool hasChannelAxis() const
+    {
+        return channelIndex() != size();
+    }
+    
+    long innerNonchannelIndex(long defaultVal) const
+    {
+        return pythonGetAttr(axistags, "innerNonchannelIndex", defaultVal);
+    }
+
+    long innerNonchannelIndex() const
+    {
+        return innerNonchannelIndex(size());
+    }
+
+    void setChannelDescription(std::string const & description)
+    {
+        if(!axistags)
+            return;
+        python_ptr d(PyString_FromString(description.c_str()), python_ptr::keep_count);
+        python_ptr func(PyString_FromString("setChannelDescription"), python_ptr::keep_count);
+        python_ptr res(PyObject_CallMethodObjArgs(axistags, func.get(), d.get(), NULL), 
+                       python_ptr::keep_count);
+        pythonToCppException(res);
+    }
+
+    double resolution(long index)
+    {
+        if(!axistags)
+            return 0.0;
+        python_ptr func(PyString_FromString("resolution"), python_ptr::keep_count);
+        python_ptr i(PyInt_FromLong(index), python_ptr::keep_count);
+        python_ptr res(PyObject_CallMethodObjArgs(axistags, func.get(), i.get(), NULL), 
+                       python_ptr::keep_count);
+        pythonToCppException(res);
+        if(!PyFloat_Check(res))
+        {
+            PyErr_SetString(PyExc_TypeError, "AxisTags.resolution() did not return float.");
+            pythonToCppException(false);
+        }
+        return PyFloat_AsDouble(res);
+    }
+ 
+    void setResolution(long index, double resolution)
+    {
+        if(!axistags)
+            return;
+        python_ptr func(PyString_FromString("setResolution"), python_ptr::keep_count);
+        python_ptr i(PyInt_FromLong(index), python_ptr::keep_count);
+        python_ptr r(PyFloat_FromDouble(resolution), python_ptr::keep_count);
+        python_ptr res(PyObject_CallMethodObjArgs(axistags, func.get(), i.get(), r.get(), NULL), 
+                       python_ptr::keep_count);
+        pythonToCppException(res);
+    }
+ 
+    void scaleResolution(long index, double factor)
+    {
+        if(!axistags)
+            return;
+        python_ptr func(PyString_FromString("scaleResolution"), python_ptr::keep_count);
+        python_ptr i(PyInt_FromLong(index), python_ptr::keep_count);
+        python_ptr f(PyFloat_FromDouble(factor), python_ptr::keep_count);
+        python_ptr res(PyObject_CallMethodObjArgs(axistags, func.get(), i.get(), f.get(), NULL), 
+                       python_ptr::keep_count);
+        pythonToCppException(res);
+    }
+ 
+    void toFrequencyDomain(long index, int size, int sign = 1)
+    {
+        if(!axistags)
+            return;
+        python_ptr func(sign == 1
+                           ? PyString_FromString("toFrequencyDomain")
+                           : PyString_FromString("fromFrequencyDomain"), 
+                        python_ptr::keep_count);
+        python_ptr i(PyInt_FromLong(index), python_ptr::keep_count);
+        python_ptr s(PyInt_FromLong(size), python_ptr::keep_count);
+        python_ptr res(PyObject_CallMethodObjArgs(axistags, func.get(), i.get(), s.get(), NULL), 
+                       python_ptr::keep_count);
+        pythonToCppException(res);
+    }
+ 
+    void fromFrequencyDomain(long index, int size)
+    {
+        toFrequencyDomain(index, size, -1);
+    }
+ 
+    ArrayVector<npy_intp> 
+    permutationToNormalOrder(bool ignoreErrors = false) const
+    {
+        ArrayVector<npy_intp> permute;
+        detail::getAxisPermutationImpl(permute, axistags, "permutationToNormalOrder", ignoreErrors);
+        return permute;
+    }
+
+    ArrayVector<npy_intp> 
+    permutationToNormalOrder(AxisInfo::AxisType types, bool ignoreErrors = false) const
+    {
+        ArrayVector<npy_intp> permute;
+        detail::getAxisPermutationImpl(permute, axistags, 
+                                            "permutationToNormalOrder", types, ignoreErrors);
+        return permute;
+    }
+
+    ArrayVector<npy_intp> 
+    permutationFromNormalOrder(bool ignoreErrors = false) const
+    {
+        ArrayVector<npy_intp> permute;
+        detail::getAxisPermutationImpl(permute, axistags, 
+                                       "permutationFromNormalOrder", ignoreErrors);
+        return permute;
+    }
+    
+    ArrayVector<npy_intp> 
+    permutationFromNormalOrder(AxisInfo::AxisType types, bool ignoreErrors = false) const
+    {
+        ArrayVector<npy_intp> permute;
+        detail::getAxisPermutationImpl(permute, axistags, 
+                                       "permutationFromNormalOrder", types, ignoreErrors);
+        return permute;
+    }
+    
+    void dropChannelAxis()
+    {
+        if(!axistags)
+            return;
+        python_ptr func(PyString_FromString("dropChannelAxis"), 
+                               python_ptr::keep_count);
+        python_ptr res(PyObject_CallMethodObjArgs(axistags, func.get(), NULL), 
+                       python_ptr::keep_count);
+        pythonToCppException(res);
+    }
+    
+    void insertChannelAxis()
+    {
+        if(!axistags)
+            return;
+        python_ptr func(PyString_FromString("insertChannelAxis"), 
+                               python_ptr::keep_count);
+        python_ptr res(PyObject_CallMethodObjArgs(axistags, func.get(), NULL), 
+                       python_ptr::keep_count);
+        pythonToCppException(res);
+    }
+    
+    operator pointer()
+    {
+        return axistags.get();
+    }
+
+    bool operator!() const
+    {
+        return !axistags;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                     TaggedShape                      */
+/*                                                      */
+/********************************************************/
+
+class TaggedShape
+{
+  public:
+    enum ChannelAxis { first, last, none };
+    
+    ArrayVector<npy_intp> shape, original_shape;
+    PyAxisTags axistags;
+    ChannelAxis channelAxis;
+    std::string channelDescription;
+    
+    explicit TaggedShape(MultiArrayIndex size)
+    : shape(size),
+      axistags(size),
+      channelAxis(none)
+    {}
+    
+    template <class U, int N>
+    TaggedShape(TinyVector<U, N> const & sh, PyAxisTags tags)
+    : shape(sh.begin(), sh.end()),
+      original_shape(sh.begin(), sh.end()),
+      axistags(tags),
+      channelAxis(none)
+    {}
+    
+    template <class T>
+    TaggedShape(ArrayVector<T> const & sh, PyAxisTags tags)
+    : shape(sh.begin(), sh.end()),
+      original_shape(sh.begin(), sh.end()),
+      axistags(tags),
+      channelAxis(none)
+    {}
+    
+    template <class U, int N>
+    explicit TaggedShape(TinyVector<U, N> const & sh)
+    : shape(sh.begin(), sh.end()),
+      original_shape(sh.begin(), sh.end()),
+      channelAxis(none)
+    {}
+    
+    template <class T>
+    explicit TaggedShape(ArrayVector<T> const & sh)
+    : shape(sh.begin(), sh.end()),
+      original_shape(sh.begin(), sh.end()),
+      channelAxis(none)
+    {}
+    
+    template <class U, int N>
+    TaggedShape & resize(TinyVector<U, N> const & sh)
+    {
+        int start = channelAxis == first
+                        ? 1
+                        : 0, 
+            stop = channelAxis == last
+                        ? (int)size()-1
+                        : (int)size();
+                        
+        vigra_precondition(N == stop - start || size() == 0,
+             "TaggedShape.resize(): size mismatch.");
+             
+        if(size() == 0)
+            shape.resize(N);
+        
+        for(int k=0; k<N; ++k)
+            shape[k+start] = sh[k];
+            
+        return *this;
+    }
+    
+    TaggedShape & resize(MultiArrayIndex v1)
+    {
+        return resize(TinyVector<MultiArrayIndex, 1>(v1));
+    }
+    
+    TaggedShape & resize(MultiArrayIndex v1, MultiArrayIndex v2)
+    {
+        return resize(TinyVector<MultiArrayIndex, 2>(v1, v2));
+    }
+    
+    TaggedShape & resize(MultiArrayIndex v1, MultiArrayIndex v2, MultiArrayIndex v3)
+    {
+        return resize(TinyVector<MultiArrayIndex, 3>(v1, v2, v3));
+    }
+    
+    TaggedShape & resize(MultiArrayIndex v1, MultiArrayIndex v2, 
+                         MultiArrayIndex v3, MultiArrayIndex v4)
+    {
+        return resize(TinyVector<MultiArrayIndex, 4>(v1, v2, v3, v4));
+    }
+    
+    npy_intp & operator[](int i)
+    {
+        return shape[i];
+    }
+    
+    npy_intp operator[](int i) const
+    {
+        return shape[i];
+    }
+    
+    unsigned int size() const
+    {
+        return shape.size();
+    }
+    
+    TaggedShape & operator+=(int v)
+    {
+        int start = channelAxis == first
+                        ? 1
+                        : 0, 
+            stop = channelAxis == last
+                        ? (int)size()-1
+                        : (int)size();
+        for(int k=start; k<stop; ++k)
+            shape[k] += v;
+            
+        return *this;
+    }
+    
+    TaggedShape & operator-=(int v)
+    {
+        return operator+=(-v);
+    }
+    
+    TaggedShape & operator*=(int factor)
+    {
+        int start = channelAxis == first
+                        ? 1
+                        : 0, 
+            stop = channelAxis == last
+                        ? (int)size()-1
+                        : (int)size();
+        for(int k=start; k<stop; ++k)
+            shape[k] *= factor;
+            
+        return *this;
+    }
+    
+    void rotateToNormalOrder()
+    {
+        if(axistags && channelAxis == last)
+        {
+            int ndim = (int)size();
+            
+            npy_intp channelCount = shape[ndim-1];            
+            for(int k=ndim-1; k>0; --k)
+                shape[k] = shape[k-1];
+            shape[0] = channelCount;
+            
+            channelCount = original_shape[ndim-1];            
+            for(int k=ndim-1; k>0; --k)
+                original_shape[k] = original_shape[k-1];
+            original_shape[0] = channelCount;
+            
+            channelAxis = first;
+        }
+    }
+    
+    TaggedShape & setChannelDescription(std::string const & description)
+    {
+        // we only remember the description here, and will actually set
+        // it in the finalize function
+        channelDescription = description;
+        return *this;
+    }
+    
+    TaggedShape & setChannelIndexLast()
+    {
+        // FIXME: add some checks?
+        channelAxis = last;
+        return *this;
+    }
+    
+    // transposeShape() means: only shape and resolution are transposed, not the axis keys
+    template <class U, int N>
+    TaggedShape & transposeShape(TinyVector<U, N> const & p)
+    {
+        int ntags = axistags.size();
+        ArrayVector<npy_intp> permute = axistags.permutationToNormalOrder();
+        
+        int tstart = (axistags.channelIndex(ntags) < ntags)
+                        ? 1
+                        : 0;
+        int sstart = (channelAxis == first)
+                        ? 1
+                        : 0;
+        int ndim = ntags - tstart;
+
+        vigra_precondition(N == ndim,
+             "TaggedShape.transposeShape(): size mismatch.");
+             
+        PyAxisTags newAxistags(axistags.axistags); // force copy
+        for(int k=0; k<ndim; ++k)
+        {
+            original_shape[k+sstart] = shape[p[k]+sstart];
+            newAxistags.setResolution(permute[k+tstart], axistags.resolution(permute[p[k]+tstart]));
+        }
+        shape = original_shape;
+        axistags = newAxistags;
+        
+        return *this;
+    }
+
+    TaggedShape & toFrequencyDomain(int sign = 1)
+    {
+        int ntags = axistags.size();
+        
+        ArrayVector<npy_intp> permute = axistags.permutationToNormalOrder();
+        
+        int tstart = (axistags.channelIndex(ntags) < ntags)
+                        ? 1
+                        : 0;
+        int sstart = (channelAxis == first)
+                        ? 1
+                        : 0;
+        int send  = (channelAxis == last)
+                        ? (int)size()-1
+                        : (int)size();
+        int size = send - sstart;
+        
+        for(int k=0; k<size; ++k)
+        {
+            axistags.toFrequencyDomain(permute[k+tstart], shape[k+sstart], sign);
+        }
+        
+        return *this;
+    }
+
+    TaggedShape & fromFrequencyDomain()
+    {
+        return toFrequencyDomain(-1);
+    }
+    
+    bool compatible(TaggedShape const & other) const
+    {
+        if(channelCount() != other.channelCount())
+            return false;
+            
+        int start = channelAxis == first
+                        ? 1
+                        : 0, 
+            stop = channelAxis == last
+                        ? (int)size()-1
+                        : (int)size();
+        int ostart = other.channelAxis == first
+                        ? 1
+                        : 0, 
+            ostop = other.channelAxis == last
+                        ? (int)other.size()-1
+                        : (int)other.size();
+                        
+        int len = stop - start;
+        if(len != ostop - ostart)
+            return false;
+        
+        for(int k=0; k<len; ++k)
+            if(shape[k+start] != other.shape[k+ostart])
+                return false;
+        return true;
+    }
+    
+    TaggedShape & setChannelCount(int count)
+    {
+        switch(channelAxis)
+        {
+          case first:
+            if(count > 0)
+            {
+                shape[0] = count;
+            }
+            else
+            {
+                shape.erase(shape.begin());
+                original_shape.erase(original_shape.begin());
+                channelAxis = none;
+            }
+            break;
+          case last:
+            if(count > 0)
+            {
+                shape[size()-1] = count;
+            }
+            else
+            {
+                shape.pop_back();
+                original_shape.pop_back();
+                channelAxis = none;
+            }
+            break;
+          case none:
+            if(count > 0)
+            {
+                shape.push_back(count);
+                original_shape.push_back(count);
+                channelAxis = last;
+            }
+            break;
+        }
+        return *this;
+    }
+    
+    int channelCount() const
+    {
+        switch(channelAxis)
+        {
+          case first:
+            return shape[0];
+          case last:
+            return shape[size()-1];
+          default:
+            return 1;
+        }
+    }
+};
+
+inline 
+void scaleAxisResolution(TaggedShape & tagged_shape)
+{
+    if(tagged_shape.size() != tagged_shape.original_shape.size())
+        return;
+    
+    int ntags = tagged_shape.axistags.size();
+    
+    ArrayVector<npy_intp> permute = tagged_shape.axistags.permutationToNormalOrder();
+    
+    int tstart = (tagged_shape.axistags.channelIndex(ntags) < ntags)
+                    ? 1
+                    : 0;
+    int sstart = (tagged_shape.channelAxis == TaggedShape::first)
+                    ? 1
+                    : 0;
+    int size = (int)tagged_shape.size() - sstart;
+    
+    for(int k=0; k<size; ++k)
+    {
+        int sk = k + sstart;
+        if(tagged_shape.shape[sk] == tagged_shape.original_shape[sk])
+            continue;
+        double factor = (tagged_shape.original_shape[sk] - 1.0) / (tagged_shape.shape[sk] - 1.0);
+        tagged_shape.axistags.scaleResolution(permute[k+tstart], factor);
+    }
+}
+
+inline 
+void unifyTaggedShapeSize(TaggedShape & tagged_shape)
+{
+    PyAxisTags axistags = tagged_shape.axistags;
+    ArrayVector<npy_intp> & shape = tagged_shape.shape;
+
+    int ndim = (int)shape.size();
+    int ntags = axistags.size();
+    
+    long channelIndex = axistags.channelIndex();
+
+    if(tagged_shape.channelAxis == TaggedShape::none)
+    {
+        // shape has no channel axis
+        if(channelIndex == ntags)
+        {
+            // std::cerr << "branch (shape, axitags) 0 0\n";
+            // axistags have no channel axis either => sizes should match
+            vigra_precondition(ndim == ntags,
+                 "constructArray(): size mismatch between shape and axistags.");
+        }
+        else
+        {
+            // std::cerr << "branch (shape, axitags) 0 1\n";
+            if(ndim+1 == ntags)
+            {
+                // std::cerr << "   drop channel axis\n";
+                // axistags have one additional element => drop the channel tag
+                // FIXME: would it be cleaner to make this an error ?
+                axistags.dropChannelAxis();
+            }
+            else
+            {
+                vigra_precondition(ndim == ntags,
+                     "constructArray(): size mismatch between shape and axistags.");
+            }
+        }
+    }
+    else
+    {
+        // shape has a channel axis
+        if(channelIndex == ntags)
+        {
+            // std::cerr << "branch (shape, axitags) 1 0\n";
+            // axistags have no channel axis => should be one element shorter
+            vigra_precondition(ndim == ntags+1,
+                 "constructArray(): size mismatch between shape and axistags.");
+                 
+            if(shape[0] == 1)
+            {
+                // std::cerr << "   drop channel axis\n";
+                // we have a singleband image => drop the channel axis
+                shape.erase(shape.begin());
+                ndim -= 1;
+            }
+            else
+            {
+                // std::cerr << "   insert channel axis\n";
+                // we have a multiband image => add a channel tag
+                axistags.insertChannelAxis();
+            }
+        }
+        else
+        {
+            // std::cerr << "branch (shape, axitags) 1 1\n";
+            // axistags have channel axis => sizes should match
+            vigra_precondition(ndim == ntags,
+                 "constructArray(): size mismatch between shape and axistags.");
+        }
+    }
+}
+
+inline
+ArrayVector<npy_intp> finalizeTaggedShape(TaggedShape & tagged_shape)
+{
+    if(tagged_shape.axistags)
+    {
+        tagged_shape.rotateToNormalOrder();
+    
+        // we assume here that the axistag object belongs to the array to be created
+        // so that we can freely edit it
+        scaleAxisResolution(tagged_shape);
+            
+        // this must be after scaleAxisResolution(), because the latter requires 
+        // shape and original_shape to be still in sync
+        unifyTaggedShapeSize(tagged_shape);
+                
+        if(tagged_shape.channelDescription != "")
+            tagged_shape.axistags.setChannelDescription(tagged_shape.channelDescription);
+    }
+    return tagged_shape.shape;
+}
+
+} // namespace vigra
+
+#endif // VIGRA_NUMPY_ARRAY_TAGGEDSHAPE_HXX
diff --git a/include/vigra/numpy_array_traits.hxx b/include/vigra/numpy_array_traits.hxx
new file mode 100644
index 0000000..1352d21
--- /dev/null
+++ b/include/vigra/numpy_array_traits.hxx
@@ -0,0 +1,840 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2009 by Ullrich Koethe and Hans Meine                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_NUMPY_ARRAY_TRAITS_HXX
+#define VIGRA_NUMPY_ARRAY_TRAITS_HXX
+
+#ifndef NPY_NO_DEPRECATED_API
+# define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#endif 
+
+#include "numerictraits.hxx"
+#include "multi_array.hxx"
+#include "numpy_array_taggedshape.hxx"
+
+namespace vigra {
+
+/********************************************************/
+/*                                                      */
+/*               NumpyArrayValuetypeTraits              */
+/*                                                      */
+/********************************************************/
+
+template<class ValueType>
+struct ERROR_NumpyArrayValuetypeTraits_not_specialized_for_ { };
+
+template<class ValueType>
+struct NumpyArrayValuetypeTraits
+{
+    static bool isValuetypeCompatible(PyArrayObject const * obj)
+    {
+        return ERROR_NumpyArrayValuetypeTraits_not_specialized_for_<ValueType>();
+    }
+
+    static ERROR_NumpyArrayValuetypeTraits_not_specialized_for_<ValueType> typeCode;
+
+    static std::string typeName()
+    {
+        return std::string("ERROR: NumpyArrayValuetypeTraits not specialized for this case");
+    }
+
+    static std::string typeNameImpex()
+    {
+        return std::string("ERROR: NumpyArrayValuetypeTraits not specialized for this case");
+    }
+
+    static PyObject * typeObject()
+    {
+        return (PyObject *)0;
+    }
+};
+
+template<class ValueType>
+ERROR_NumpyArrayValuetypeTraits_not_specialized_for_<ValueType> NumpyArrayValuetypeTraits<ValueType>::typeCode;
+
+#define VIGRA_NUMPY_VALUETYPE_TRAITS(type, typeID, numpyTypeName, impexTypeName) \
+template <> \
+struct NumpyArrayValuetypeTraits<type > \
+{ \
+    static bool isValuetypeCompatible(PyArrayObject const * obj) /* obj must not be NULL */ \
+    { \
+        return PyArray_EquivTypenums(typeID, PyArray_DESCR((PyArrayObject *)obj)->type_num) && \
+               PyArray_ITEMSIZE((PyArrayObject *)obj) == sizeof(type); \
+    } \
+    \
+    static NPY_TYPES const typeCode = typeID; \
+    \
+    static std::string typeName() \
+    { \
+        return #numpyTypeName; \
+    } \
+    \
+    static std::string typeNameImpex() \
+    { \
+        return impexTypeName; \
+    } \
+    \
+    static PyObject * typeObject() \
+    { \
+        return PyArray_TypeObjectFromType(typeID); \
+    } \
+};
+
+VIGRA_NUMPY_VALUETYPE_TRAITS(bool,           NPY_BOOL, bool, "UINT8")
+VIGRA_NUMPY_VALUETYPE_TRAITS(signed char,    NPY_INT8, int8, "INT16")
+VIGRA_NUMPY_VALUETYPE_TRAITS(unsigned char,  NPY_UINT8, uint8, "UINT8")
+VIGRA_NUMPY_VALUETYPE_TRAITS(short,          NPY_INT16, int16, "INT16")
+VIGRA_NUMPY_VALUETYPE_TRAITS(unsigned short, NPY_UINT16, uint16, "UINT16")
+
+#if VIGRA_BITSOF_LONG == 32
+VIGRA_NUMPY_VALUETYPE_TRAITS(long,           NPY_INT32, int32, "INT32")
+VIGRA_NUMPY_VALUETYPE_TRAITS(unsigned long,  NPY_UINT32, uint32, "UINT32")
+#elif VIGRA_BITSOF_LONG == 64
+VIGRA_NUMPY_VALUETYPE_TRAITS(long,           NPY_INT64, int64, "DOUBLE")
+VIGRA_NUMPY_VALUETYPE_TRAITS(unsigned long,  NPY_UINT64, uint64, "DOUBLE")
+#endif
+
+#if VIGRA_BITSOF_INT == 32
+VIGRA_NUMPY_VALUETYPE_TRAITS(int,            NPY_INT32, int32, "INT32")
+VIGRA_NUMPY_VALUETYPE_TRAITS(unsigned int,   NPY_UINT32, uint32, "UINT32")
+#elif VIGRA_BITSOF_INT == 64
+VIGRA_NUMPY_VALUETYPE_TRAITS(int,            NPY_INT64, int64, "DOUBLE")
+VIGRA_NUMPY_VALUETYPE_TRAITS(unsigned int,   NPY_UINT64, uint64, "DOUBLE")
+#endif
+
+#ifdef PY_LONG_LONG
+# if VIGRA_BITSOF_LONG_LONG == 32
+VIGRA_NUMPY_VALUETYPE_TRAITS(long long,            NPY_INT32, int32, "INT32")
+VIGRA_NUMPY_VALUETYPE_TRAITS(unsigned long long,   NPY_UINT32, uint32, "UINT32")
+# elif VIGRA_BITSOF_LONG_LONG == 64
+VIGRA_NUMPY_VALUETYPE_TRAITS(long long,          NPY_INT64, int64, "DOUBLE")
+VIGRA_NUMPY_VALUETYPE_TRAITS(unsigned long long, NPY_UINT64, uint64, "DOUBLE")
+# endif
+#endif
+
+VIGRA_NUMPY_VALUETYPE_TRAITS(npy_float32, NPY_FLOAT32, float32, "FLOAT")
+VIGRA_NUMPY_VALUETYPE_TRAITS(npy_float64, NPY_FLOAT64, float64, "DOUBLE")
+#if NPY_SIZEOF_LONGDOUBLE != NPY_SIZEOF_DOUBLE
+VIGRA_NUMPY_VALUETYPE_TRAITS(npy_longdouble, NPY_LONGDOUBLE, longdouble, "")
+#endif
+VIGRA_NUMPY_VALUETYPE_TRAITS(npy_cfloat, NPY_CFLOAT, complex64, "")
+VIGRA_NUMPY_VALUETYPE_TRAITS(std::complex<npy_float>, NPY_CFLOAT, complex64, "")
+VIGRA_NUMPY_VALUETYPE_TRAITS(npy_cdouble, NPY_CDOUBLE, complex128, "")
+VIGRA_NUMPY_VALUETYPE_TRAITS(std::complex<npy_double>, NPY_CDOUBLE, complex128, "")
+VIGRA_NUMPY_VALUETYPE_TRAITS(npy_clongdouble, NPY_CLONGDOUBLE, clongdouble, "")
+#if NPY_SIZEOF_LONGDOUBLE != NPY_SIZEOF_DOUBLE
+VIGRA_NUMPY_VALUETYPE_TRAITS(std::complex<npy_longdouble>, NPY_CLONGDOUBLE, clongdouble, "")
+#endif
+
+#undef VIGRA_NUMPY_VALUETYPE_TRAITS
+
+/********************************************************/
+/*                                                      */
+/*                  NumpyArrayTraits                    */
+/*                                                      */
+/********************************************************/
+
+template<unsigned int N, class T, class Stride>
+struct NumpyArrayTraits;
+
+/********************************************************/
+
+template<unsigned int N, class T>
+struct NumpyArrayTraits<N, T, StridedArrayTag>
+{
+    typedef T dtype;
+    typedef T value_type;
+    typedef NumpyArrayValuetypeTraits<T> ValuetypeTraits;
+    static NPY_TYPES const typeCode = ValuetypeTraits::typeCode;
+
+    static bool isArray(PyObject * obj)
+    {
+        return obj && PyArray_Check(obj);
+    }
+
+    static bool isValuetypeCompatible(PyArrayObject * obj)  /* obj must not be NULL */
+    {
+        return ValuetypeTraits::isValuetypeCompatible(obj);
+    }
+
+    static bool isShapeCompatible(PyArrayObject * array) /* array must not be NULL */
+    {
+        int ndim = PyArray_NDIM(array);
+
+        return ndim == N;
+    }
+
+    // The '*Compatible' functions are called whenever a NumpyArray is to be constructed
+    // from a Python numpy.ndarray to check whether types and memory layout are
+    // compatible. During overload resolution, boost::python iterates through the list
+    // of overloads and invokes the first function where all arguments pass this check.
+    static bool isPropertyCompatible(PyArrayObject * obj) /* obj must not be NULL */
+    {
+        return isShapeCompatible(obj) && isValuetypeCompatible(obj);
+    }
+    
+    // Construct a tagged shape from a 'shape - axistags' pair (called in 
+    // NumpyArray::taggedShape()).
+    template <class U>
+    static TaggedShape taggedShape(TinyVector<U, N> const & shape, PyAxisTags axistags)
+    {
+        return TaggedShape(shape, axistags);
+    }
+
+    // Construct a tagged shape from a 'shape - order' pair by creating
+    // the appropriate axistags object for that order and NumpyArray type.
+    // (called in NumpyArray constructors via NumpyArray::init())
+    template <class U>
+    static TaggedShape taggedShape(TinyVector<U, N> const & shape,
+                                   std::string const & /* order */ = "")
+    {
+        // We ignore the 'order' parameter, because we don't know the axis meaning
+        // in a plain array (use Singleband, Multiband, TinyVector etc. instead).
+        // Since we also have no useful axistags in this case, we enforce
+        // the result array to be a plain numpy.ndarray by passing empty axistags.
+        return TaggedShape(shape, PyAxisTags());
+    }
+
+    // Adjust a TaggedShape that was created by another array to the properties of
+    // the present NumpyArray type (called in NumpyArray::reshapeIfEmpty()).
+    static void finalizeTaggedShape(TaggedShape & tagged_shape)
+    {
+        vigra_precondition(tagged_shape.size() == N,
+                  "reshapeIfEmpty(): tagged_shape has wrong size.");
+    }
+    
+    // This function is used to synchronize the axis re-ordering of 'data'
+    // with that of 'array'. For example, when we want to apply Gaussian smoothing
+    // with a different scale for each axis, 'data' would contains those scales,
+    // and permuteLikewise() would make sure that the scales are applied to the right
+    // axes, regardless of axis re-ordering.
+    template <class ARRAY>
+    static void permuteLikewise(python_ptr array, ARRAY const & data, ARRAY & res)
+    {
+        vigra_precondition((int)data.size() == N,
+            "NumpyArray::permuteLikewise(): size mismatch.");
+        
+        ArrayVector<npy_intp> permute;
+        detail::getAxisPermutationImpl(permute, array, "permutationToNormalOrder", 
+                                       AxisInfo::AllAxes, true);
+
+        if(permute.size() != 0)
+        {
+            applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
+        }
+    }
+    
+    // This function is called in NumpyArray::setupArrayView() to determine the
+    // desired axis re-ordering.
+    template <class U>
+    static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
+    {
+        detail::getAxisPermutationImpl(permute, array, "permutationToNormalOrder", 
+                                       AxisInfo::AllAxes, true);
+
+        if(permute.size() == 0)
+        {
+            permute.resize(N);
+            linearSequence(permute.begin(), permute.end());
+        }
+    }
+
+    // This function is called in NumpyArray::makeUnsafeReference() to create
+    // a numpy.ndarray view for a block of memory managed by C++.
+    // The term 'unsafe' should remind you that memory management cannot be done
+    // automatically, bu must be done explicitly by the programmer.
+    template <class U>
+    static python_ptr unsafeConstructorFromData(TinyVector<U, N> const & shape,
+                                                T *data, TinyVector<U, N> const & stride)
+    {
+        TinyVector<npy_intp, N> npyStride(stride * sizeof(T));
+        return constructNumpyArrayFromData(shape, npyStride.begin(), 
+                                                    ValuetypeTraits::typeCode, data);
+    }
+};
+
+/********************************************************/
+
+template<unsigned int N, class T>
+struct NumpyArrayTraits<N, T, UnstridedArrayTag>
+: public NumpyArrayTraits<N, T, StridedArrayTag>
+{
+    typedef NumpyArrayTraits<N, T, StridedArrayTag> BaseType;
+    typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
+
+    static bool isShapeCompatible(PyArrayObject * array) /* obj must not be NULL */
+    {
+        PyObject * obj = (PyObject *)array;
+        int ndim = PyArray_NDIM(array);
+        long channelIndex = pythonGetAttr(obj, "channelIndex", ndim);
+        long majorIndex = pythonGetAttr(obj, "innerNonchannelIndex", ndim);
+        npy_intp * strides = PyArray_STRIDES(array);
+        
+        if(channelIndex < ndim)
+        {
+            // When we have a channel axis, it will become the innermost dimension
+            return (ndim == N && strides[channelIndex] == sizeof(T));
+        }
+        else if(majorIndex < ndim)
+        {
+            // When we have axistags, but no channel axis, the major spatial
+            // axis will be the innermost dimension
+            return (ndim == N && strides[majorIndex] == sizeof(T));
+        }
+        else 
+        {
+            // When we have no axistags, the first axis will be the innermost dimension
+            return (ndim == N && strides[0] == sizeof(T));
+        }
+    }
+
+    static bool isPropertyCompatible(PyArrayObject * obj) /* obj must not be NULL */
+    {
+        return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
+    }
+};
+
+/********************************************************/
+
+template<unsigned int N, class T>
+struct NumpyArrayTraits<N, Singleband<T>, StridedArrayTag>
+: public NumpyArrayTraits<N, T, StridedArrayTag>
+{
+    typedef NumpyArrayTraits<N, T, StridedArrayTag> BaseType;
+    typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
+
+    static bool isShapeCompatible(PyArrayObject * array) /* array must not be NULL */
+    {
+        PyObject * obj = (PyObject *)array;
+        int ndim = PyArray_NDIM(array);
+        long channelIndex = pythonGetAttr(obj, "channelIndex", ndim);
+        
+        // If we have no channel axis (because either we don't have axistags, 
+        // or the tags do not contain a channel axis), ndim must match.
+        if(channelIndex == ndim)
+            return ndim == N;
+            
+        // Otherwise, the channel axis must be a singleton axis that we can drop.
+        return ndim == N+1 && PyArray_DIM(array, channelIndex) == 1;
+    }
+
+    static bool isPropertyCompatible(PyArrayObject * obj) /* obj must not be NULL */
+    {
+        return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
+    }
+
+    template <class U>
+    static TaggedShape taggedShape(TinyVector<U, N> const & shape, PyAxisTags axistags)
+    {
+        return TaggedShape(shape, axistags).setChannelCount(1);
+    }
+
+    template <class U>
+    static TaggedShape taggedShape(TinyVector<U, N> const & shape, std::string const & order = "")
+    {
+        return TaggedShape(shape, 
+                  PyAxisTags(detail::defaultAxistags(shape.size()+1, order))).setChannelCount(1);
+    }
+
+    static void finalizeTaggedShape(TaggedShape & tagged_shape)
+    {
+        if(tagged_shape.axistags.hasChannelAxis())
+        {
+            tagged_shape.setChannelCount(1);
+            vigra_precondition(tagged_shape.size() == N+1,
+                     "reshapeIfEmpty(): tagged_shape has wrong size.");
+        }
+        else
+        {
+            tagged_shape.setChannelCount(0);
+            vigra_precondition(tagged_shape.size() == N,
+                     "reshapeIfEmpty(): tagged_shape has wrong size.");
+        }
+    }
+    
+    template <class ARRAY>
+    static void permuteLikewise(python_ptr array, ARRAY const & data, ARRAY & res)
+    {
+        vigra_precondition((int)data.size() == N,
+            "NumpyArray::permuteLikewise(): size mismatch.");
+        
+        ArrayVector<npy_intp> permute;
+        detail::getAxisPermutationImpl(permute, array, "permutationToNormalOrder", 
+                                       AxisInfo::NonChannel, true);
+
+        if(permute.size() == 0)
+        {
+            permute.resize(N);
+            linearSequence(permute.begin(), permute.end());
+        }
+        
+        applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
+    }
+    
+    template <class U>
+    static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
+    {
+        detail::getAxisPermutationImpl(permute, array, "permutationToNormalOrder", 
+                                       AxisInfo::AllAxes, true);
+        if(permute.size() == 0)
+        {
+            permute.resize(N);
+            linearSequence(permute.begin(), permute.end());
+        }
+        else if(permute.size() == N+1)
+        {
+            permute.erase(permute.begin());
+        }
+    }
+};
+
+/********************************************************/
+
+template<unsigned int N, class T>
+struct NumpyArrayTraits<N, Singleband<T>, UnstridedArrayTag>
+: public NumpyArrayTraits<N, Singleband<T>, StridedArrayTag>
+{
+    typedef NumpyArrayTraits<N, T, UnstridedArrayTag> UnstridedTraits;
+    typedef NumpyArrayTraits<N, Singleband<T>, StridedArrayTag> BaseType;
+    typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
+
+    static bool isShapeCompatible(PyArrayObject * array) /* obj must not be NULL */
+    {
+        PyObject * obj = (PyObject *)array;
+        int ndim = PyArray_NDIM(array);
+        long channelIndex = pythonGetAttr(obj, "channelIndex", ndim);
+        long majorIndex = pythonGetAttr(obj, "innerNonchannelIndex", ndim);
+        npy_intp * strides = PyArray_STRIDES(array);
+        
+        // If we have no axistags, ndim must match, and axis 0 must be unstrided.
+        if(majorIndex == ndim) 
+            return N == ndim && strides[0] == sizeof(T);
+            
+        // If we have axistags, but no channel axis, ndim must match, 
+        // and the major non-channel axis must be unstrided.
+        if(channelIndex == ndim) 
+            return N == ndim && strides[majorIndex] == sizeof(T);
+            
+        // Otherwise, the channel axis must be a singleton axis that we can drop,
+        // and the major non-channel axis must be unstrided.
+        return ndim == N+1 && PyArray_DIM(array, channelIndex) == 1 && 
+                strides[majorIndex] == sizeof(T);
+    }
+
+    static bool isPropertyCompatible(PyArrayObject * obj) /* obj must not be NULL */
+    {
+        return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
+    }
+};
+
+/********************************************************/
+
+template<unsigned int N, class T>
+struct NumpyArrayTraits<N, Multiband<T>, StridedArrayTag>
+: public NumpyArrayTraits<N, T, StridedArrayTag>
+{
+    typedef NumpyArrayTraits<N, T, StridedArrayTag> BaseType;
+    typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
+
+    static bool isShapeCompatible(PyArrayObject * array) /* array must not be NULL */
+    {
+        PyObject * obj = (PyObject*)array;
+        int ndim = PyArray_NDIM(array);
+        long channelIndex = pythonGetAttr(obj, "channelIndex", ndim);
+        long majorIndex = pythonGetAttr(obj, "innerNonchannelIndex", ndim);
+        
+        if(channelIndex < ndim)
+        {
+            // When we have a channel axis, ndim must match.
+            return ndim == N;
+        }
+        else if(majorIndex < ndim)
+        {
+            // When we have axistags, but no channel axis, we must add a singleton axis.
+            return ndim == N-1;
+        }
+        else
+        {
+            // When we have no axistags, we may add a singleton dimension.
+            return ndim == N || ndim == N-1;
+        }
+    }
+
+    static bool isPropertyCompatible(PyArrayObject * obj) /* obj must not be NULL */
+    {
+        return isShapeCompatible(obj) && ValuetypeTraits::isValuetypeCompatible(obj);
+    }
+
+    template <class U>
+    static TaggedShape taggedShape(TinyVector<U, N> const & shape, PyAxisTags axistags)
+    {
+        return TaggedShape(shape, axistags).setChannelIndexLast();
+    }
+
+    template <class U>
+    static TaggedShape taggedShape(TinyVector<U, N> const & shape, std::string const & order = "")
+    {
+        return TaggedShape(shape, 
+                    PyAxisTags(detail::defaultAxistags(shape.size(), order))).setChannelIndexLast();
+    }
+
+    static void finalizeTaggedShape(TaggedShape & tagged_shape)
+    {
+        // When there is only one channel, and the axistags don't enforce an
+        // explicit channel axis, we return an array without explicit channel axis.
+        if(tagged_shape.channelCount() == 1 && !tagged_shape.axistags.hasChannelAxis())
+        {
+            tagged_shape.setChannelCount(0);
+            vigra_precondition(tagged_shape.size() == N-1,
+                  "reshapeIfEmpty(): tagged_shape has wrong size.");
+        }
+        else
+        {
+            vigra_precondition(tagged_shape.size() == N,
+                  "reshapeIfEmpty(): tagged_shape has wrong size.");
+        }
+    }
+
+    template <class ARRAY>
+    static void permuteLikewise(python_ptr array, ARRAY const & data, ARRAY & res)
+    {
+        ArrayVector<npy_intp> permute;
+        
+        if((int)data.size() == N)
+        {
+            vigra_precondition(PyArray_NDIM((PyArrayObject*)array.get()) == N,
+                "NumpyArray::permuteLikewise(): input array has no channel axis.");
+
+            detail::getAxisPermutationImpl(permute, array, "permutationToNormalOrder", 
+                                           AxisInfo::AllAxes, true);
+
+            if(permute.size() == 0)
+            {
+                permute.resize(N);
+                linearSequence(permute.begin(), permute.end());
+            }
+            else
+            {
+                // rotate channel axis to last position
+                int channelIndex = permute[0];
+                for(int k=1; k<N; ++k)
+                    permute[k-1] = permute[k];
+                permute[N-1] = channelIndex;
+            }
+        }
+        else
+        {
+            vigra_precondition((int)data.size() == N-1,
+                "NumpyArray::permuteLikewise(): size mismatch.");
+
+            detail::getAxisPermutationImpl(permute, array, "permutationToNormalOrder", 
+                                           AxisInfo::NonChannel, true);
+
+            if(permute.size() == 0)
+            {
+                permute.resize(N-1);
+                linearSequence(permute.begin(), permute.end());
+            }
+        }
+        
+        applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
+    }
+    
+    template <class U>
+    static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
+    {
+        detail::getAxisPermutationImpl(permute, array, "permutationToNormalOrder", 
+                                       AxisInfo::AllAxes, true);
+
+        if(permute.size() == 0)
+        {
+            permute.resize(PyArray_NDIM((PyArrayObject*)array.get()));
+            linearSequence(permute.begin(), permute.end());
+        }
+        else if(permute.size() == N)
+        {
+            // if we have a channel axis, rotate it to last position
+            int channelIndex = permute[0];
+            for(int k=1; k<N; ++k)
+                permute[k-1] = permute[k];
+            permute[N-1] = channelIndex;
+        }
+    }
+};
+
+/********************************************************/
+
+template<unsigned int N, class T>
+struct NumpyArrayTraits<N, Multiband<T>, UnstridedArrayTag>
+: public NumpyArrayTraits<N, Multiband<T>, StridedArrayTag>
+{
+    typedef NumpyArrayTraits<N, Multiband<T>, StridedArrayTag> BaseType;
+    typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
+
+    static bool isShapeCompatible(PyArrayObject * array) /* obj must not be NULL */
+    {
+        PyObject * obj = (PyObject *)array;
+        int ndim = PyArray_NDIM(array);
+        long channelIndex = pythonGetAttr(obj, "channelIndex", ndim);
+        long majorIndex = pythonGetAttr(obj, "innerNonchannelIndex", ndim);
+        npy_intp * strides = PyArray_STRIDES(array);
+
+        if(channelIndex < ndim)
+        {
+            // When we have a channel axis, ndim must match, and the major non-channel
+            // axis must be unstrided.
+            return ndim == N && strides[majorIndex] == sizeof(T);
+        }
+        else if(majorIndex < ndim)
+        {
+            // When we have axistags, but no channel axis, we will add a
+            // singleton channel axis, and the major non-channel axis must be unstrided.
+            return ndim == N-1 && strides[majorIndex] == sizeof(T);
+        }
+        else
+        {
+            // When we have no axistags, axis 0 must be unstrided, but we
+            // may add a singleton dimension at the end.
+            return (ndim == N || ndim == N-1) && strides[0] == sizeof(T);
+        }
+    }
+
+    static bool isPropertyCompatible(PyArrayObject * obj) /* obj must not be NULL */
+    {
+        return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
+    }
+};
+
+/********************************************************/
+
+template<unsigned int N, int M, class T>
+struct NumpyArrayTraits<N, TinyVector<T, M>, StridedArrayTag>
+{
+    typedef T dtype;
+    typedef TinyVector<T, M> value_type;
+    typedef NumpyArrayValuetypeTraits<T> ValuetypeTraits;
+    static NPY_TYPES const typeCode = ValuetypeTraits::typeCode;
+
+    static bool isArray(PyObject * obj)
+    {
+        return obj && PyArray_Check(obj);
+    }
+
+    static bool isValuetypeCompatible(PyArrayObject * obj)  /* obj must not be NULL */
+    {
+        return ValuetypeTraits::isValuetypeCompatible(obj);
+    }
+
+    static bool isShapeCompatible(PyArrayObject * array) /* array must not be NULL */
+    {
+        PyObject * obj = (PyObject *)array;
+        
+         // We need an extra channel axis.
+         if(PyArray_NDIM(array) != N+1)
+            return false;
+            
+        // When there are no axistags, we assume that the last axis represents the channels.
+        long channelIndex = pythonGetAttr(obj, "channelIndex", N);
+        npy_intp * strides = PyArray_STRIDES(array);
+        
+        return PyArray_DIM(array, channelIndex) == M && strides[channelIndex] == sizeof(T);
+    }
+
+    static bool isPropertyCompatible(PyArrayObject * obj) /* obj must not be NULL */
+    {
+        return isShapeCompatible(obj) && ValuetypeTraits::isValuetypeCompatible(obj);
+    }
+
+    template <class U>
+    static TaggedShape taggedShape(TinyVector<U, N> const & shape, PyAxisTags axistags)
+    {
+        return TaggedShape(shape, axistags).setChannelCount(M);
+    }
+
+    template <class U>
+    static TaggedShape taggedShape(TinyVector<U, N> const & shape, std::string const & order = "")
+    {
+        return TaggedShape(shape, 
+                     PyAxisTags(detail::defaultAxistags(shape.size()+1, order))).setChannelCount(M);
+    }
+
+    static void finalizeTaggedShape(TaggedShape & tagged_shape)
+    {
+        tagged_shape.setChannelCount(M);
+        vigra_precondition(tagged_shape.size() == N+1,
+              "reshapeIfEmpty(): tagged_shape has wrong size.");
+    }
+
+    template <class ARRAY>
+    static void permuteLikewise(python_ptr array, ARRAY const & data, ARRAY & res)
+    {
+        vigra_precondition((int)data.size() == N,
+            "NumpyArray::permuteLikewise(): size mismatch.");
+        
+        ArrayVector<npy_intp> permute;
+        detail::getAxisPermutationImpl(permute, array, "permutationToNormalOrder", 
+                                       AxisInfo::NonChannel, true);
+
+        if(permute.size() == 0)
+        {
+            permute.resize(N);
+            linearSequence(permute.begin(), permute.end());
+        }
+        
+        applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
+    }
+    
+    template <class U>
+    static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
+    {
+        detail::getAxisPermutationImpl(permute, array, "permutationToNormalOrder", 
+                                       AxisInfo::AllAxes, true);
+        if(permute.size() == 0)
+        {
+            permute.resize(N);
+            linearSequence(permute.begin(), permute.end());
+        }
+        else if(permute.size() == N+1)
+        {
+            permute.erase(permute.begin());
+        }
+    }
+    
+    template <class U>
+    static python_ptr unsafeConstructorFromData(TinyVector<U, N> const & shape,
+                                                value_type *data, TinyVector<U, N> const & stride)
+    {
+        TinyVector<npy_intp, N+1> npyShape;
+        std::copy(shape.begin(), shape.end(), npyShape.begin());
+        npyShape[N] = M;
+
+        TinyVector<npy_intp, N+1> npyStride;
+        std::transform(
+            stride.begin(), stride.end(), npyStride.begin(),
+            std::bind2nd(std::multiplies<npy_intp>(), sizeof(value_type)));
+        npyStride[N] = sizeof(T);
+
+        return constructNumpyArrayFromData(npyShape, npyStride.begin(), 
+                                                    ValuetypeTraits::typeCode, data);
+    }
+};
+
+/********************************************************/
+
+template<unsigned int N, int M, class T>
+struct NumpyArrayTraits<N, TinyVector<T, M>, UnstridedArrayTag>
+: public NumpyArrayTraits<N, TinyVector<T, M>, StridedArrayTag>
+{
+    typedef NumpyArrayTraits<N, TinyVector<T, M>, StridedArrayTag> BaseType;
+    typedef typename BaseType::value_type value_type;
+    typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
+
+    static bool isShapeCompatible(PyArrayObject * array) /* obj must not be NULL */
+    {
+        PyObject * obj = (PyObject *)array;
+        int ndim = PyArray_NDIM(array);
+        
+         // We need an extra channel axis. 
+        if(ndim != N+1)
+            return false;
+            
+        long channelIndex = pythonGetAttr(obj, "channelIndex", ndim);
+        long majorIndex = pythonGetAttr(obj, "innerNonchannelIndex", ndim);
+        npy_intp * strides = PyArray_STRIDES(array);
+        
+        if(majorIndex < ndim)
+        {
+            // We have axistags, but no channel axis => cannot be a TinyVector image
+            if(channelIndex == ndim)
+                return false;
+                
+            // We have an explicit channel axis => shapes and strides must match
+            return PyArray_DIM(array, channelIndex) == M && 
+                   strides[channelIndex] == sizeof(T) &&
+                   strides[majorIndex] == sizeof(TinyVector<T, M>);
+            
+            
+        }
+        else
+        {
+            // we have no axistags => we assume that the channel axis is last
+            return PyArray_DIM(array, N) == M && 
+                   strides[N] == sizeof(T) &&
+                   strides[0] == sizeof(TinyVector<T, M>);
+        }
+    }
+
+    static bool isPropertyCompatible(PyArrayObject * obj) /* obj must not be NULL */
+    {
+        return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
+    }
+};
+
+/********************************************************/
+
+template<unsigned int N, class T>
+struct NumpyArrayTraits<N, RGBValue<T>, StridedArrayTag>
+: public NumpyArrayTraits<N, TinyVector<T, 3>, StridedArrayTag>
+{
+    typedef T dtype;
+    typedef RGBValue<T> value_type;
+    typedef NumpyArrayValuetypeTraits<T> ValuetypeTraits;
+};
+
+/********************************************************/
+
+template<unsigned int N, class T>
+struct NumpyArrayTraits<N, RGBValue<T>, UnstridedArrayTag>
+: public NumpyArrayTraits<N, RGBValue<T>, StridedArrayTag>
+{
+    typedef NumpyArrayTraits<N, TinyVector<T, 3>, UnstridedArrayTag> UnstridedTraits;
+    typedef NumpyArrayTraits<N, RGBValue<T>, StridedArrayTag> BaseType;
+    typedef typename BaseType::value_type value_type;
+    typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
+
+    static bool isShapeCompatible(PyArrayObject * obj) /* obj must not be NULL */
+    {
+        return UnstridedTraits::isShapeCompatible(obj);
+    }
+
+    static bool isPropertyCompatible(PyArrayObject * obj) /* obj must not be NULL */
+    {
+        return UnstridedTraits::isPropertyCompatible(obj);
+    }
+};
+
+} // namespace vigra
+
+#endif // VIGRA_NUMPY_ARRAY_TRAITS_HXX
diff --git a/include/vigra/orientedtensorfilters.hxx b/include/vigra/orientedtensorfilters.hxx
new file mode 100644
index 0000000..8a2c501
--- /dev/null
+++ b/include/vigra/orientedtensorfilters.hxx
@@ -0,0 +1,640 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_ORIENTEDTENSORFILTERS_HXX
+#define VIGRA_ORIENTEDTENSORFILTERS_HXX
+
+#include <cmath>
+#include "utilities.hxx"
+#include "initimage.hxx"
+#include "stdconvolution.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup TensorImaging Tensor Image Processing
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                     hourGlassFilter                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Anisotropic tensor smoothing with the hourglass filter.
+
+    This function implements anisotropic tensor smoothing by an
+    hourglass-shaped filters as described in
+    
+    U. Köthe: <a href="http://hci.iwr.uni-heidelberg.de/people/ukoethe/papers/index.php#cite_structureTensor">
+    <i>"Edge and Junction Detection with an Improved Structure Tensor"</i></a>, 
+     in: Proc. of 25th DAGM Symposium, Magdeburg 2003, Lecture Notes in Computer Science 2781, 
+     pp. 25-32, Heidelberg: Springer, 2003
+     
+    It is closely related to the structure tensor (see \ref structureTensor()), but
+    replaces the linear tensor smoothing with a smoothing along edges only. 
+    Smoothing across edges is largely suppressed. This means that the
+    image structure is preserved much better because nearby features
+    such as parallel edges are not blended into each other. 
+    
+    The hourglass filter is typically applied to a gradient tensor, i.e. the 
+    Euclidean product of the gradient with itself, which can be obtained by a
+    gradient operator followed with \ref vectorToTensor(), see example below. 
+    The hourglass shape of the filter can be interpreted as indicating the likely 
+    continuations of a local edge element. The parameter <tt>sigma</tt> determines
+    the radius of the hourglass (i.e. how far the influence of the edge element 
+    reaches), and <tt>rho</tt> controls its opening angle (i.e. how narrow the 
+    edge orientation os followed). Recommended values are <tt>sigma = 1.4</tt>
+    (or, more generally, two to three times the scale of the gradient operator
+    used in the first step), and <tt>rho = 0.4</tt> which corresponds to an 
+    opening angle of 22.5 degrees to either side of the edge.
+    
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        hourGlassFilter(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, T2, S2> dest,
+                        double sigma, double rho);
+    }
+    \endcode
+
+    \deprecatedAPI{hourGlassFilter}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void hourGlassFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                             DestIterator dul, DestAccessor dest,
+                             double sigma, double rho);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        inline
+        void hourGlassFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
+                             pair<DestIterator, DestAccessor> d,
+                             double sigma, double rho);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/orientedtensorfilters.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float>                  img(w,h);
+    MultiArray<2, TinyVector<float, 2> >  gradient(w,h);
+    MultiArray<2, TinyVector<float, 3> >  tensor(w,h), smoothedTensor(w,h);
+    
+    gaussianGradient(img, gradient, 1.0);
+    vectorToTensor(gradient, tensor);
+    hourGlassFilter(tensor, smoothedTensor, 2.0, 0.4);
+    \endcode
+
+    \deprecatedUsage{hourGlassFilter}
+    \code
+    FImage img(w,h);
+    FVector2Image gradient(w,h);
+    FVector3Image tensor(w,h), smoothedTensor(w,h);
+    
+    gaussianGradient(srcImageRange(img), destImage(gradient), 1.0);
+    vectorToTensor(srcImageRange(gradient), destImage(tensor));
+    hourGlassFilter(srcImageRange(tensor), destImage(smoothedTensor), 2.0, 0.4);
+    \endcode
+    \deprecatedEnd
+    
+    \see vectorToTensor()
+*/
+doxygen_overloaded_function(template <...> void hourGlassFilter)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void hourGlassFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                     DestIterator dul, DestAccessor dest,
+                     double sigma, double rho)
+{
+    vigra_precondition(sigma >= 0.0 && rho >= 0.0,
+                       "hourGlassFilter(): sigma and rho must be >= 0.0");
+    vigra_precondition(src.size(sul) == 3,
+                       "hourGlassFilter(): input image must have 3 bands.");
+    vigra_precondition(dest.size(dul) == 3,
+                       "hourGlassFilter(): output image must have 3 bands.");
+
+    // TODO: normalization
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    double radius = VIGRA_CSTD::floor(3.0*sigma + 0.5);
+    double sigma2 = -0.5 / sigma / sigma;
+    double rho2 = -0.5 / rho / rho;
+    double norm = 1.0 / (2.0 * M_PI * sigma * sigma);
+
+    initImage(dul, dul+Diff2D(w,h), dest, NumericTraits<typename DestAccessor::value_type>::zero());
+
+    for(int y=0; y<h; ++y, ++sul.y, ++dul.y)
+    {
+        SrcIterator s = sul;
+        DestIterator d = dul;
+        for(int x=0; x<w; ++x, ++s.x, ++d.x)
+        {
+            double phi = 0.5 * VIGRA_CSTD::atan2(
+                                     2.0*src.getComponent(s,1),
+                                     (double)src.getComponent(s,0) - src.getComponent(s,2));
+            double u = VIGRA_CSTD::sin(phi);
+            double v = VIGRA_CSTD::cos(phi);
+
+            double x0 = x - radius < 0 ? -x : -radius;
+            double y0 = y - radius < 0 ? -y : -radius;
+            double x1 = x + radius >= w ? w - x - 1 : radius;
+            double y1 = y + radius >= h ? h - y - 1 : radius;
+
+            DestIterator dwul = d + Diff2D((int)x0, (int)y0);
+
+            for(double yy=y0; yy <= y1; ++yy, ++dwul.y)
+            {
+                typename DestIterator::row_iterator dw = dwul.rowIterator();
+                for(double xx=x0; xx <= x1; ++xx, ++dw)
+                {
+                    double r2 = xx*xx + yy*yy;
+                    double p  = u*xx - v*yy;
+                    double q  = v*xx + u*yy;
+                    double kernel = (p == 0.0) ?
+                                      (q == 0.0) ?
+                                       norm :
+                                       0.0 :
+                                       norm * VIGRA_CSTD::exp(sigma2*r2 + rho2*q*q/p/p);
+                    dest.set(dest(dw) + kernel*src(s), dw);
+                }
+            }
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+hourGlassFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
+                pair<DestIterator, DestAccessor> d,
+                double sigma, double rho)
+{
+    hourGlassFilter(s.first, s.second, s.third, d.first, d.second, sigma, rho);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+hourGlassFilter(MultiArrayView<2, T1, S1> const & src,
+                MultiArrayView<2, T2, S2> dest,
+                double sigma, double rho)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "hourGlassFilter(): shape mismatch between input and output.");
+    hourGlassFilter(srcImageRange(src), destImage(dest), sigma, rho);
+}
+
+/********************************************************/
+/*                                                      */
+/*                    ellipticGaussian                  */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void ellipticGaussian(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                      DestIterator dul, DestAccessor dest,
+                      double sigmax, double sigmin)
+{
+    vigra_precondition(sigmax >= sigmin && sigmin >= 0.0,
+                       "ellipticGaussian(): "
+                       "sigmax >= sigmin and sigmin >= 0.0 required");
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    double radius = VIGRA_CSTD::floor(3.0*sigmax + 0.5);
+    double sigmin2 = -0.5 / sigmin / sigmin;
+    double norm = 1.0 / (2.0 * M_PI * sigmin * sigmax);
+
+    initImage(dul, dul+Diff2D(w,h), dest, NumericTraits<typename DestAccessor::value_type>::zero());
+
+    for(int y=0; y<h; ++y, ++sul.y, ++dul.y)
+    {
+        SrcIterator s = sul;
+        DestIterator d = dul;
+        for(int x=0; x<w; ++x, ++s.x, ++d.x)
+        {
+            typedef typename 
+               NumericTraits<typename SrcAccessor::component_type>::RealPromote TmpType;
+            TmpType d1 = src.getComponent(s,0) + src.getComponent(s,2);
+            TmpType d2 = src.getComponent(s,0) - src.getComponent(s,2);
+            TmpType d3 = 2.0 * src.getComponent(s,1);
+            TmpType d4 = VIGRA_CSTD::sqrt(sq(d2) + sq(d3));
+            TmpType excentricity = 1.0 - (d1 - d4) / (d1 + d4);
+            double sigmax2 = -0.5 / sq((sigmax - sigmin)*excentricity + sigmin);
+            
+            double phi = 0.5 * VIGRA_CSTD::atan2(d3, d2);
+            double u = VIGRA_CSTD::sin(phi);
+            double v = VIGRA_CSTD::cos(phi);
+
+            double x0 = x - radius < 0 ? -x : -radius;
+            double y0 = y - radius < 0 ? -y : -radius;
+            double x1 = x + radius >= w ? w - x - 1 : radius;
+            double y1 = y + radius >= h ? h - y - 1 : radius;
+
+            DestIterator dwul = d + Diff2D((int)x0, (int)y0);
+
+            for(double yy=y0; yy <= y1; ++yy, ++dwul.y)
+            {
+                typename DestIterator::row_iterator dw = dwul.rowIterator();
+                for(double xx=x0; xx <= x1; ++xx, ++dw)
+                {
+                    double p  = u*xx - v*yy;
+                    double q  = v*xx + u*yy;
+                    double kernel = norm * VIGRA_CSTD::exp(sigmax2*p*p + sigmin2*q*q);
+                    dest.set(dest(dw) + kernel*src(s), dw);
+                }
+            }
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+ellipticGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                 pair<DestIterator, DestAccessor> dest,
+                 double sigmax, double sigmin)
+{
+    ellipticGaussian(src.first, src.second, src.third, dest.first, dest.second, sigmax, sigmin);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+ellipticGaussian(MultiArrayView<2, T1, S1> const & src,
+                 MultiArrayView<2, T2, S2> dest,
+                 double sigmax, double sigmin)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "ellipticGaussian(): shape mismatch between input and output.");
+    ellipticGaussian(srcImageRange(src), destImage(dest), sigmax, sigmin);
+}
+
+/********************************************************/
+/*                                                      */
+/*         kernels for orientedTrigonometricFilter      */
+/*                                                      */
+/********************************************************/
+
+class FoerstnerKernelBase
+{
+  public:
+    typedef double ResultType;
+    typedef double WeightType;
+    typedef DVector2Image::value_type VectorType;
+    typedef VectorType::value_type    ValueType;
+  
+    FoerstnerKernelBase(double scale, bool ringShaped = false)
+    : radius_((int)(3.0*scale+0.5)),
+      weights_(2*radius_+1, 2*radius_+1),
+      vectors_(2*radius_+1, 2*radius_+1)
+    {
+        double norm = 1.0 / (2.0 * M_PI * scale * scale);
+        double s2 = -0.5 / scale / scale;
+        
+        for(int y = -radius_; y <= radius_; ++y)
+        {
+            for(int x = -radius_; x <= radius_; ++x)
+            {
+                double d2 = x*x + y*y;
+                double d = VIGRA_CSTD::sqrt(d2);
+                vectors_(x+radius_,y+radius_) = d != 0.0 ?
+                                                  VectorType(x/d, -y/d) :
+                                                  VectorType(ValueType(0), ValueType(0));
+                weights_(x+radius_,y+radius_) = ringShaped ? 
+                                       norm * d2 * VIGRA_CSTD::exp(d2 * s2) :
+                                       norm * VIGRA_CSTD::exp(d2 * s2);
+            }
+        }
+    }   
+    
+    ResultType operator()(int x, int y, VectorType const &) const
+    {
+        // isotropic filtering
+        return weights_(radius_, radius_);
+    }
+
+    int radius_;
+    DImage weights_;
+    DVector2Image vectors_;
+};
+
+class FoerstnerRingKernelBase
+: public FoerstnerKernelBase
+{
+  public:
+    FoerstnerRingKernelBase(double scale)
+    : FoerstnerKernelBase(scale, true)
+    {}
+};
+
+class Cos2RingKernel
+: public FoerstnerKernelBase
+{
+  public:
+    typedef double ResultType;
+    typedef double WeightType;
+    typedef DVector2Image::value_type VectorType;
+  
+    Cos2RingKernel(double scale)
+    : FoerstnerKernelBase(scale, true)
+    {}
+    
+    ResultType operator()(int x, int y, VectorType const & v) const
+    {
+        if(x == 0 && y == 0)
+            return weights_(radius_, radius_);
+        double d = dot(vectors_(x+radius_, y+radius_), v);
+        return d * d * weights_(x+radius_, y+radius_);
+    }
+};
+
+class Cos2Kernel
+: public FoerstnerKernelBase
+{
+  public:
+    typedef double ResultType;
+    typedef double WeightType;
+    typedef DVector2Image::value_type VectorType;
+  
+    Cos2Kernel(double scale)
+    : FoerstnerKernelBase(scale, false)
+    {}
+    
+    ResultType operator()(int x, int y, VectorType const & v) const
+    {
+        if(x == 0 && y == 0)
+            return weights_(radius_, radius_);
+        double d = dot(vectors_(x+radius_, y+radius_), v);
+        return d * d * weights_(x+radius_, y+radius_);
+    }
+};
+
+class Sin2RingKernel
+: public FoerstnerKernelBase
+{
+  public:
+    typedef double ResultType;
+    typedef double WeightType;
+    typedef DVector2Image::value_type VectorType;
+  
+    Sin2RingKernel(double scale)
+    : FoerstnerKernelBase(scale, true)
+    {}
+    
+    ResultType operator()(int x, int y, VectorType const & v) const
+    {
+        if(x == 0 && y == 0)
+            return weights_(radius_, radius_);
+        double d = dot(vectors_(x+radius_, y+radius_), v);
+        return (1.0 - d * d) * weights_(x+radius_, y+radius_);
+    }
+};
+
+class Sin2Kernel
+: public FoerstnerKernelBase
+{
+  public:
+    typedef double ResultType;
+    typedef double WeightType;
+    typedef DVector2Image::value_type VectorType;
+  
+    Sin2Kernel(double scale)
+    : FoerstnerKernelBase(scale, false)
+    {}
+    
+    ResultType operator()(int x, int y, VectorType const & v) const
+    {
+        if(x == 0 && y == 0)
+            return weights_(radius_, radius_);
+        double d = dot(vectors_(x+radius_, y+radius_), v);
+        return (1.0 - d * d) * weights_(x+radius_, y+radius_);
+    }
+};
+
+class Sin6RingKernel
+: public FoerstnerKernelBase
+{
+  public:
+    typedef double ResultType;
+    typedef double WeightType;
+    typedef DVector2Image::value_type VectorType;
+  
+    Sin6RingKernel(double scale)
+    : FoerstnerKernelBase(scale, true)
+    {}
+    
+    ResultType operator()(int x, int y, VectorType const & v) const
+    {
+        if(x == 0 && y == 0)
+            return weights_(radius_, radius_);
+        double d = dot(vectors_(x+radius_, y+radius_), v);
+        return VIGRA_CSTD::pow(1.0 - d * d, 3) * weights_(x+radius_, y+radius_);
+    }
+};
+
+class Sin6Kernel
+: public FoerstnerKernelBase
+{
+  public:
+    typedef double ResultType;
+    typedef double WeightType;
+    typedef DVector2Image::value_type VectorType;
+  
+    Sin6Kernel(double scale)
+    : FoerstnerKernelBase(scale, false)
+    {}
+    
+    ResultType operator()(int x, int y, VectorType const & v) const
+    {
+        if(x == 0 && y == 0)
+            return weights_(radius_, radius_);
+        double d = dot(vectors_(x+radius_, y+radius_), v);
+        return VIGRA_CSTD::pow(1.0 - d * d, 3) * weights_(x+radius_, y+radius_);
+    }
+};
+
+class Cos6RingKernel
+: public FoerstnerKernelBase
+{
+  public:
+    typedef double ResultType;
+    typedef double WeightType;
+    typedef DVector2Image::value_type VectorType;
+  
+    Cos6RingKernel(double scale)
+    : FoerstnerKernelBase(scale, true)
+    {}
+    
+    ResultType operator()(int x, int y, VectorType const & v) const
+    {
+        if(x == 0 && y == 0)
+            return weights_(radius_, radius_);
+        double d = dot(vectors_(x+radius_, y+radius_), v);
+        return (1.0 - VIGRA_CSTD::pow(1.0 - d * d, 3)) * weights_(x+radius_, y+radius_);
+    }
+};
+
+class Cos6Kernel
+: public FoerstnerKernelBase
+{
+  public:
+    typedef double ResultType;
+    typedef double WeightType;
+    typedef DVector2Image::value_type VectorType;
+  
+    Cos6Kernel(double scale)
+    : FoerstnerKernelBase(scale, false)
+    {}
+    
+    ResultType operator()(int x, int y, VectorType const & v) const
+    {
+        if(x == 0 && y == 0)
+            return weights_(radius_, radius_);
+        double d = dot(vectors_(x+radius_, y+radius_), v);
+        return (1.0 - VIGRA_CSTD::pow(1.0 - d * d, 3)) * weights_(x+radius_, y+radius_);
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*              orientedTrigonometricFilter             */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Kernel>
+void orientedTrigonometricFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                    DestIterator dul, DestAccessor dest,
+                    Kernel const & kernel)
+{
+    vigra_precondition(src.size(sul) == 2,
+                       "orientedTrigonometricFilter(): input image must have 2 bands.");
+    vigra_precondition(dest.size(dul) == 3,
+                       "orientedTrigonometricFilter(): output image must have 3 bands.");
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    int radius = kernel.radius_;
+    
+    typedef typename SrcAccessor::value_type VectorType;
+    typedef typename DestAccessor::value_type TensorType;
+
+    initImage(dul, dul+Diff2D(w,h), dest, NumericTraits<TensorType>::zero());
+
+    for(int y=0; y<h; ++y, ++sul.y, ++dul.y)
+    {
+        SrcIterator s = sul;
+        DestIterator d = dul;
+        for(int x=0; x<w; ++x, ++s.x, ++d.x)
+        {
+            int x0 = x - radius < 0 ? -x : -radius;
+            int y0 = y - radius < 0 ? -y : -radius;
+            int x1 = x + radius >= w ? w - x - 1 : radius;
+            int y1 = y + radius >= h ? h - y - 1 : radius;
+
+            VectorType v(src(s));
+            TensorType t(sq(v[0]), v[0]*v[1], sq(v[1]));
+            double sqMag = t[0] + t[2];
+            double mag = VIGRA_CSTD::sqrt(sqMag);
+            if(mag != 0.0)
+                v /= mag;
+            else
+                v *= 0.0;
+            Diff2D dd;
+            for(dd.y = y0; dd.y <= y1; ++dd.y)
+            {
+                for(dd.x = x0; dd.x <= x1; ++dd.x)
+                {
+                    dest.set(dest(d, dd) + kernel(dd.x, dd.y, v) * t, d, dd);
+                }
+            }
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Kernel>
+inline void
+orientedTrigonometricFilter(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<DestIterator, DestAccessor> dest,
+                            Kernel const & kernel)
+{
+    orientedTrigonometricFilter(src.first, src.second, src.third, dest.first, dest.second, kernel);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class Kernel>
+inline void
+orientedTrigonometricFilter(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            Kernel const & kernel)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "orientedTrigonometricFilter(): shape mismatch between input and output.");
+    orientedTrigonometricFilter(srcImageRange(src), destImage(dest), kernel);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif /* VIGRA_ORIENTEDTENSORFILTERS_HXX */
diff --git a/include/vigra/pixelneighborhood.hxx b/include/vigra/pixelneighborhood.hxx
new file mode 100644
index 0000000..b4d8f85
--- /dev/null
+++ b/include/vigra/pixelneighborhood.hxx
@@ -0,0 +1,1531 @@
+/************************************************************************/
+/*                                                                      */
+/*          Copyright 1998-2005 by Hans Meine, Ullrich Koethe           */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_PIXELNEIGHBORHOOD_HXX
+#define VIGRA_PIXELNEIGHBORHOOD_HXX
+
+#include "utilities.hxx"
+
+namespace vigra {
+
+/** \addtogroup PixelNeighborhood Utilities to manage pixel neighborhoods
+
+    4- and 8-neighborhood definitions and circulators.
+
+    <b>\#include</b> \<vigra/pixelneighborhood.hxx\><br>
+
+    <b>See also:</b> \ref vigra::NeighborhoodCirculator
+ */
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                      AtImageBorder                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Encode whether a point is near the image border.
+
+    This enum is used with \ref isAtImageBorder() and
+    \ref vigra::RestrictedNeighborhoodCirculator.
+
+    <b>\#include</b> \<vigra/pixelneighborhood.hxx\><br>
+    Namespace: vigra
+*/
+
+enum AtImageBorder
+{
+        NotAtBorder       = 0,     ///<  
+        RightBorder       = 1,     ///<  
+        LeftBorder        = 2,     ///<  
+        TopBorder         = 4,     ///<  
+        BottomBorder      = 8,     ///<  
+        FrontBorder       = 16,    ///<  
+        RearBorder        = 32,
+        TopRightBorder    = TopBorder    | RightBorder,   //5
+        TopLeftBorder     = TopBorder    | LeftBorder,    //6
+        TopFrontBorder    = TopBorder    | FrontBorder,   //20
+        TopRearBorder     = TopBorder    | RearBorder,    //36
+        BottomLeftBorder  = BottomBorder | LeftBorder,    //10
+        BottomRightBorder = BottomBorder | RightBorder,   //9
+        BottomFrontBorder = BottomBorder | FrontBorder,   //24
+        BottomRearBorder  = BottomBorder | RearBorder,    //40
+        FrontLeftBorder   = FrontBorder  | LeftBorder,    //18
+        FrontRightBorder  = FrontBorder  | RightBorder,   //17
+        RearLeftBorder    = RearBorder   | LeftBorder,    //34
+        RearRightBorder   = RearBorder   | RightBorder,   //33
+
+        TopRightFrontBorder    = TopBorder    | RightBorder | FrontBorder,    //21
+        TopLeftFrontBorder     = TopBorder    | LeftBorder  | FrontBorder,    //22
+        BottomLeftFrontBorder  = BottomBorder | LeftBorder  | FrontBorder,    //26
+        BottomRightFrontBorder = BottomBorder | RightBorder | FrontBorder,    //25
+        TopRightRearBorder     = TopBorder    | RightBorder | RearBorder,     //37
+        TopLeftRearBorder      = TopBorder    | LeftBorder  | RearBorder,     //38
+        BottomLeftRearBorder   = BottomBorder | LeftBorder  | RearBorder,     //42
+        BottomRightRearBorder  = BottomBorder | RightBorder | RearBorder      //41
+};
+
+
+/** \brief Find out whether a point is at the image border.
+
+    This function checks if \a x == 0 or \a x == \a width - 1 and
+    \a y == 0 or \a y == \a height - 1 and returns the appropriate value
+    of \ref vigra::AtImageBorder, or zero when the point is not at the image border.
+    The behavior of the function is undefined if (x,y) is not inside the image.
+
+    <b>\#include</b> \<vigra/pixelneighborhood.hxx\><br>
+    Namespace: vigra
+*/
+inline AtImageBorder isAtImageBorder(int x, int y, int width, int height)
+{
+    return static_cast<AtImageBorder>((x == 0
+                                         ? LeftBorder
+                                         : x == width-1
+                                             ? RightBorder
+                                             : NotAtBorder) |
+                                       (y == 0
+                                         ? TopBorder
+                                         : y == height-1
+                                             ? BottomBorder
+                                             : NotAtBorder));
+}
+
+/********************************************************/
+/*                                                      */
+/*                    FourNeighborhood                  */
+/*                                                      */
+/********************************************************/
+
+/** Utilities for 4-neighborhood. */
+namespace FourNeighborhood
+{
+
+/** \brief Encapsulation of direction management for 4-neighborhood.
+
+    This helper class allows the transformation between Freeman chain codes
+    (East = 0, North = 1 etc.) and the corresponding Diff2D instances
+    and back.
+
+    You can either use the chain codes by explicit qualification:
+
+    \code
+    // the following three lines are equivalent
+    FourNeighborhood::NeighborCode::Direction d = FourNeighborhood::NeighborCode::East;
+    FourNeighborCode::Direction d = FourNeighborCode::East;
+    FourNeighborhood::Direction d = FourNeighborhood::East;
+    \endcode
+
+    or you can fix 4-neighborhood by importing the entire namespace in
+    your function:
+
+    \code
+    using namespace FourNeighborhood;
+
+    Direction d = East;
+    \endcode
+
+    If you want to pass 4-neighborhood codes as a template parameter, use
+    the class FourNeighborhood::NeighborCode.
+
+    <b>\#include</b> \<vigra/pixelneighborhood.hxx\><br>
+    Namespace: vigra::FourNeighborhood
+*/
+class NeighborCode
+{
+  public:
+
+    typedef Diff2D difference_type;
+
+        /** Freeman direction codes for the 4-neighborhood.
+            <tt>East = 0</tt>, <tt>North = 1</tt> etc.
+            <tt>DirectionCount</tt> may be used for portable loop termination conditions.
+            <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive)
+            neighbors in the causal neighborhood, i.e. in the set of neighbors that have
+            already been visited when the image is traversed in scan order.
+            <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the opposite.
+        */
+    enum Direction {
+        Error = -1,     ///<  
+        East = 0,       ///<  
+        North,          ///<  
+        West,           ///<  
+        South,          ///<  
+        DirectionCount, ///<  
+        CausalFirst = North,     ///<  
+        CausalLast  = West,      ///<  
+        AntiCausalFirst = South, ///<  
+        AntiCausalLast  = East,   ///<  
+
+        InitialDirection = East,
+        OppositeDirPrefix = 1,
+        OppositeOffset = West
+    };
+    
+    template <int DUMMY>
+    struct StaticData
+    {
+        static unsigned int b[];
+        static unsigned int c[];
+        static Direction bd[11][4];
+        static Diff2D d[];
+        static Diff2D rd[][4];
+    };
+
+    static unsigned int directionBit(Direction d)
+    {
+        return StaticData<0>::b[d];
+    };
+
+        /** The number of valid neighbors if the current center is at the image border.
+        */
+    static unsigned int nearBorderDirectionCount(AtImageBorder b)
+    {
+        return StaticData<0>::c[b];
+    }
+
+        /** The valid direction codes when the center is at the image border.
+            \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
+        */
+    static Direction nearBorderDirections(AtImageBorder b, int index)
+    {
+        return StaticData<0>::bd[b][index];
+    }
+
+        /** Transform direction code into corresponding Diff2D offset.
+            (note: there is no bounds checking on the code you pass.)
+        */
+    static Diff2D const & diff(Direction code)
+    {
+        return StaticData<0>::d[code];
+    }
+
+        /** Equivalent to <tt>diff(static_cast<Direction>(code))</tt>.
+            (note: there is no bounds checking on the code you pass.)
+        */
+    static Diff2D const & diff(int code) { return diff(static_cast<Direction>(code)); }
+
+        /** Get the relative offset from one neighbor to the other.
+            For example, <tt>relativeDiff(East, West) == Diff2D(-2,0)</tt>.
+            (note: there is no bounds checking on the code you pass.)
+        */
+    static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
+    {
+        return StaticData<0>::rd[fromCode][toCode];
+    }
+
+        /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
+            (note: there is no bounds checking on the code you pass.)
+        */
+    static Diff2D const & relativeDiff(int fromCode, int toCode)
+    {
+        return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
+    }
+
+        /**  X-component of diff() */
+    static int dX(Direction code) { return diff(code).x; }
+        /**  Y-component of diff() */
+    static int dY(Direction code) { return diff(code).y; }
+        /**  X-component of diff() */
+    static int dX(int code) { return diff(code).x; }
+        /**  Y-component of diff() */
+    static int dY(int code) { return diff(code).y; }
+
+        /** Transform Diff2D offset into corresponding direction code.
+            The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
+            is not in the 4-neighborhood.
+        */
+    static Direction code(Diff2D const & diff)
+    {
+        switch(diff.x)
+        {
+            case  0:
+            {
+                switch(diff.y)
+                {
+                    case 1:
+                        return South;
+                    case -1:
+                        return North;
+                    default:
+                        return Error;
+                }
+            }
+            case -1:
+            {
+                return (diff.y == 0) ?
+                            West :
+                            Error;
+            }
+            case  1:
+            {
+                return (diff.y == 0) ?
+                            East :
+                            Error;
+            }
+        }
+        return Error;
+    }
+
+        /** Check whether a code refers to a diagonal direction.
+            Useful if you want to abstract the differences between 4- and 8-neighborhood.
+            Always <tt>false</tt> for 4-neighborhood.
+        */
+    static bool isDiagonal(Direction) { return false; }
+
+    static Diff2D const & right()        { return diff(East); }    /**<  Offset to the right neighbor */
+    static Diff2D const & top()          { return diff(North); }   /**<  Offset to the top neighbor */
+    static Diff2D const & left()         { return diff(West); }    /**<  Offset to the left neighbor */
+    static Diff2D const & bottom()       { return diff(South); }   /**<  Offset to the bottom neighbor */
+
+    static Diff2D const & east()       { return diff(East); }    /**<  Offset to the east neighbor */
+    static Diff2D const & north()      { return diff(North); }   /**<  Offset to the north neighbor */
+    static Diff2D const & west()       { return diff(West); }    /**<  Offset to the west neighbor */
+    static Diff2D const & south()      { return diff(South); }   /**<  Offset to the south neighbor */
+};
+
+
+    /** Export NeighborCode::Direction into the scope of namespace FourNeighborhood.
+    */
+typedef NeighborCode::Direction Direction;
+
+static const Direction Error          = NeighborCode::Error;          /**<  Export NeighborCode::Error to namespace FourNeighborhood */
+static const Direction East           = NeighborCode::East;           /**<  Export NeighborCode::East to namespace FourNeighborhood */
+static const Direction North          = NeighborCode::North;          /**<  Export NeighborCode::North to namespace FourNeighborhood */
+static const Direction West           = NeighborCode::West;           /**<  Export NeighborCode::West to namespace FourNeighborhood */
+static const Direction South          = NeighborCode::South;          /**<  Export NeighborCode::South to namespace FourNeighborhood */
+static const Direction DirectionCount = NeighborCode::DirectionCount; /**<  Export NeighborCode::DirectionCount to namespace FourNeighborhood */
+
+inline Diff2D const & east()       { return NeighborCode::diff(East); }    /**<  Offset to the east neighbor */
+inline Diff2D const & north()      { return NeighborCode::diff(North); }   /**<  Offset to the north neighbor */
+inline Diff2D const & west()       { return NeighborCode::diff(West); }    /**<  Offset to the west neighbor */
+inline Diff2D const & south()      { return NeighborCode::diff(South); }   /**<  Offset to the south neighbor */
+
+
+template <int DUMMY>
+unsigned int NeighborCode::StaticData<DUMMY>::b[] = {1 << East,
+                                                    1 << North,
+                                                    1 << West,
+                                                    1 << South };
+
+template <int DUMMY>
+unsigned int NeighborCode::StaticData<DUMMY>::c[] = { 4, 3, 3, 0, 3, 2, 2, 0, 3, 2, 2};
+
+template <int DUMMY>
+Direction NeighborCode::StaticData<DUMMY>::bd[11][4] = {
+                { East, North, West, South},
+                { North, West, South, Error},
+                { East, North, South, Error},
+                { Error, Error, Error, Error},
+                { East, West, South, Error},
+                { West, South, Error, Error},
+                { East, South, Error, Error},
+                { Error, Error, Error, Error},
+                { East, North, West, Error},
+                { North, West, Error, Error},
+                { East, North, Error, Error}
+             };
+
+template <int DUMMY>
+Diff2D NeighborCode::StaticData<DUMMY>::d[] = {
+            Diff2D(1, 0), Diff2D(0, -1), Diff2D(-1, 0), Diff2D(0, 1)
+        };
+
+template <int DUMMY>
+Diff2D NeighborCode::StaticData<DUMMY>::rd[][4] = {
+            { Diff2D(0, 0), Diff2D(-1, -1), Diff2D(-2, 0), Diff2D(-1, 1) },
+            { Diff2D(1, 1), Diff2D(0, 0), Diff2D(-1, 1), Diff2D(0, 2) },
+            { Diff2D(2, 0), Diff2D(1, -1), Diff2D(0, 0), Diff2D(1, 1) },
+            { Diff2D(1, -1), Diff2D(0, -2), Diff2D(-1, -1), Diff2D(0, 0) }
+        };
+
+} // namespace FourNeighborhood
+
+
+
+    /** Export \ref vigra::FourNeighborhood::NeighborCode into the scope of namespace vigra.
+    */
+typedef FourNeighborhood::NeighborCode FourNeighborCode;
+
+/********************************************************/
+/*                                                      */
+/*                   EightNeighborhood                  */
+/*                                                      */
+/********************************************************/
+
+/** Utilities for 8-neighborhood. */
+namespace EightNeighborhood
+{
+/** \brief Encapsulation of direction management for the 8-neighborhood.
+
+    This helper class allows the transformation between Freeman chain codes
+    (East = 0, NorthEast = 1 etc.) and the corresponding Diff2D instances
+    and back.
+
+    You can either use the chain codes by explicit qualification:
+
+    \code
+    // the following three lines are equivalent
+    EightNeighborhood::NeighborCode::Direction d = EightNeighborhood::NeighborCode::East;
+    EightNeighborCode::Direction d               = EightNeighborCode::East;
+    EightNeighborhood::Direction d               = EightNeighborhood::East;
+    \endcode
+
+    or you can fix 8-neighborhood by importing the entire namespace in
+    your function:
+
+    \code
+    using namespace EightNeighborhood;
+
+    Direction d = East;
+    \endcode
+
+    If you want to pass 8-neighborhood codes as a template parameter, use
+    the class EightNeighborhood::NeighborCode.
+
+    <b>\#include</b> \<vigra/pixelneighborhood.hxx\><br>
+    Namespace: vigra::EightNeighborhood
+*/
+class NeighborCode
+{
+  public:
+
+    typedef Diff2D difference_type;
+
+        /** Freeman direction codes for the 8-neighborhood.
+            <tt>East = 0</tt>, <tt>North = 1</tt> etc.
+            <tt>DirectionCount</tt> may be used for portable loop termination conditions.
+            <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive)
+            neighbors in the causal neighborhood, i.e. in the set of neighbors that have
+            already been visited when the image is traversed in scan order.
+            <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the opposite.
+        */
+    enum Direction {
+        Error = -1,     ///<  
+        East = 0,       ///<  
+        NorthEast,      ///<  
+        North,          ///<  
+        NorthWest,      ///<  
+        West,           ///<  
+        SouthWest,      ///<  
+        South,          ///<  
+        SouthEast,      ///<  
+        DirectionCount, ///<  
+        CausalFirst = NorthEast,     ///<  
+        CausalLast  = West,          ///<  
+        AntiCausalFirst = SouthWest, ///<  
+        AntiCausalLast  = East,       ///<  
+
+        InitialDirection = East,
+        OppositeDirPrefix = 1,
+        OppositeOffset = West
+    };
+
+    template <int DUMMY>
+    struct StaticData
+    {
+        static unsigned int b[];
+        static unsigned int c[];
+        static Direction bd[11][8];
+        static Diff2D d[];
+        static Diff2D rd[][8];
+    };
+
+    static unsigned int directionBit(Direction d)
+    {
+        return StaticData<0>::b[d];
+    };
+
+        /** The number of valid neighbors if the current center is at the image border.
+        */
+    static unsigned int nearBorderDirectionCount(AtImageBorder b)
+    {
+        return StaticData<0>::c[b];
+    }
+
+        /** The valid direction codes when the center is at the image border.
+            \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
+        */
+    static Direction nearBorderDirections(AtImageBorder b, int index)
+    {
+        return StaticData<0>::bd[b][index];
+    }
+
+        /** Transform direction code into corresponding Diff2D offset.
+            (note: there is no bounds checking on the code you pass.)
+        */
+    static Diff2D const & diff(Direction code)
+    {
+        return StaticData<0>::d[code];
+    }
+
+        /** Equivalent to diff(static_cast<Direction>(code)).
+            (note: there is no bounds checking on the code you pass.)
+        */
+    static Diff2D const & diff(int code) { return diff(static_cast<Direction>(code)); }
+
+        /** Get the relative offset from one neighbor to the other.
+            For example, <tt>relativeDiff(East, West) == Diff2D(-2,0)</tt>.
+            (note: there is no bounds checking on the code you pass.)
+        */
+    static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
+    {
+        return StaticData<0>::rd[fromCode][toCode];
+    }
+
+        /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
+            (note: there is no bounds checking on the code you pass.)
+        */
+    static Diff2D const & relativeDiff(int fromCode, int toCode)
+    {
+        return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
+    }
+
+        /**  X-component of diff() */
+    static int dX(Direction code) { return diff(code).x; }
+        /**  Y-component of diff() */
+    static int dY(Direction code) { return diff(code).y; }
+        /**  X-component of diff() */
+    static int dX(int code) { return diff(code).x; }
+        /**  Y-component of diff() */
+    static int dY(int code) { return diff(code).y; }
+
+        /** Transform 4-neighborhood code into 8-neighborhood code.
+        */
+    static Direction code(FourNeighborhood::Direction d)
+        { return static_cast<Direction>(2*d); }
+
+        /** Transform Diff2D offset into corresponding direction code.
+            The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
+            is not in the 8-neighborhood.
+        */
+    static Direction code(Diff2D const & diff)
+    {
+        switch(diff.x)
+        {
+            case  0:
+            {
+                switch(diff.y)
+                {
+                    case 1:
+                        return South;
+                    case -1:
+                        return North;
+                    default:
+                        return Error;
+                }
+            }
+            case -1:
+            {
+                switch(diff.y)
+                {
+                    case 0:
+                        return West;
+                    case 1:
+                        return SouthWest;
+                    case -1:
+                        return NorthWest;
+                    default:
+                        return Error;
+                }
+            }
+            case  1:
+            {
+                switch(diff.y)
+                {
+                    case 0:
+                        return East;
+                    case 1:
+                        return SouthEast;
+                    case -1:
+                        return NorthEast;
+                    default:
+                        return Error;
+                }
+            }
+        }
+        return Error;
+    }
+
+        /** Check whether a code refers to a diagonal direction.
+            Useful if you want to abstract the differences between 4- and 8-neighborhood.
+        */
+    static bool isDiagonal(Direction code) { return (code % 2) != 0; }
+
+    static Diff2D const & right()        { return diff(East); }        /**<  Offset to the right neighbor */
+    static Diff2D const & topRight()     { return diff(NorthEast); }   /**<  Offset to the topRight neighbor */
+    static Diff2D const & top()          { return diff(North); }       /**<  Offset to the top neighbor */
+    static Diff2D const & topLeft()      { return diff(NorthWest); }   /**<  Offset to the topLeft neighbor */
+    static Diff2D const & left()         { return diff(West); }        /**<  Offset to the left neighbor */
+    static Diff2D const & bottomLeft()   { return diff(SouthWest); }   /**<  Offset to the bottomLeft neighbor */
+    static Diff2D const & bottom()       { return diff(South); }       /**<  Offset to the bottom neighbor */
+    static Diff2D const & bottomRight()  { return diff(SouthEast); }   /**<  Offset to the bottomRight neighbor */
+
+    static Diff2D const & east()       { return diff(East); }        /**<  Offset to the east neighbor */
+    static Diff2D const & northEast()  { return diff(NorthEast); }   /**<  Offset to the northEast neighbor */
+    static Diff2D const & north()      { return diff(North); }       /**<  Offset to the north neighbor */
+    static Diff2D const & northWest()  { return diff(NorthWest); }   /**<  Offset to the northWest neighbor */
+    static Diff2D const & west()       { return diff(West); }        /**<  Offset to the west neighbor */
+    static Diff2D const & southWest()  { return diff(SouthWest); }   /**<  Offset to the southWest neighbor */
+    static Diff2D const & south()      { return diff(South); }       /**<  Offset to the south neighbor */
+    static Diff2D const & southEast()  { return diff(SouthEast); }   /**<  Offset to the southEast neighbor */
+};
+
+    /** Export NeighborCode::Direction into the scope of namespace EightNeighborhood.
+    */
+typedef NeighborCode::Direction Direction;
+
+static const Direction East           = NeighborCode::East;        /**<  Export NeighborCode::East to namespace EightNeighborhood */
+static const Direction NorthEast      = NeighborCode::NorthEast;   /**<  Export NeighborCode::NorthEast to namespace EightNeighborhood */
+static const Direction North          = NeighborCode::North;       /**<  Export NeighborCode::North to namespace EightNeighborhood */
+static const Direction NorthWest      = NeighborCode::NorthWest;   /**<  Export NeighborCode::NorthWest to namespace EightNeighborhood */
+static const Direction West           = NeighborCode::West;        /**<  Export NeighborCode::West to namespace EightNeighborhood */
+static const Direction SouthWest      = NeighborCode::SouthWest;   /**<  Export NeighborCode::SouthWest to namespace EightNeighborhood */
+static const Direction South          = NeighborCode::South;       /**<  Export NeighborCode::South to namespace EightNeighborhood */
+static const Direction SouthEast      = NeighborCode::SouthEast;   /**<  Export NeighborCode::SouthEast to namespace EightNeighborhood */
+static const Direction DirectionCount = NeighborCode::DirectionCount;   /**<  Export NeighborCode::DirectionCount to namespace EightNeighborhood */
+
+inline Diff2D const & east()       { return NeighborCode::diff(East); }        /**<  Offset to the east neighbor */
+inline Diff2D const & northEast()  { return NeighborCode::diff(NorthEast); }   /**<  Offset to the northEast neighbor */
+inline Diff2D const & north()      { return NeighborCode::diff(North); }       /**<  Offset to the north neighbor */
+inline Diff2D const & northWest()  { return NeighborCode::diff(NorthWest); }   /**<  Offset to the northWest neighbor */
+inline Diff2D const & west()       { return NeighborCode::diff(West); }        /**<  Offset to the west neighbor */
+inline Diff2D const & southWest()  { return NeighborCode::diff(SouthWest); }   /**<  Offset to the southWest neighbor */
+inline Diff2D const & south()      { return NeighborCode::diff(South); }       /**<  Offset to the south neighbor */
+inline Diff2D const & southEast()  { return NeighborCode::diff(SouthEast); }   /**<  Offset to the southEast neighbor */
+
+template <int DUMMY>
+unsigned int NeighborCode::StaticData<DUMMY>::b[] = {
+                                   1 << East,
+                                   1 << NorthEast,
+                                   1 << North,
+                                   1 << NorthWest,
+                                   1 << West,
+                                   1 << SouthWest,
+                                   1 << South,
+                                   1 << SouthEast};
+
+template <int DUMMY>
+unsigned int NeighborCode::StaticData<DUMMY>::c[] = { 8, 5, 5, 0, 5, 3, 3, 0, 5, 3, 3};
+
+template <int DUMMY>
+Direction NeighborCode::StaticData<DUMMY>::bd[11][8] = {
+                { East, NorthEast, North, NorthWest, West, SouthWest, South, SouthEast},
+                { North, NorthWest, West, SouthWest, South, Error, Error, Error},
+                { East, NorthEast, North, South, SouthEast, Error, Error, Error},
+                { Error, Error, Error, Error, Error, Error, Error, Error},
+                { East, West, SouthWest, South, SouthEast, Error, Error, Error},
+                { West, SouthWest, South, Error, Error, Error, Error, Error},
+                { East, South, SouthEast, Error, Error, Error, Error, Error},
+                { Error, Error, Error, Error, Error, Error, Error, Error},
+                { East, NorthEast, North, NorthWest, West, Error, Error, Error},
+                { North, NorthWest, West, Error, Error, Error, Error, Error},
+                { East, NorthEast, North, Error, Error, Error, Error, Error}
+             };
+
+template <int DUMMY>
+Diff2D NeighborCode::StaticData<DUMMY>::d[] = {
+            Diff2D(1, 0), Diff2D(1, -1), Diff2D(0, -1), Diff2D(-1, -1),
+            Diff2D(-1, 0), Diff2D(-1, 1), Diff2D(0, 1), Diff2D(1, 1)
+        };
+
+template <int DUMMY>
+Diff2D NeighborCode::StaticData<DUMMY>::rd[][8] = {
+            { Diff2D(0, 0), Diff2D(0, -1), Diff2D(-1, -1), Diff2D(-2, -1),
+              Diff2D(-2, 0), Diff2D(-2, 1), Diff2D(-1, 1), Diff2D(0, 1) },
+            { Diff2D(0, 1), Diff2D(0, 0), Diff2D(-1, 0), Diff2D(-2, 0),
+              Diff2D(-2, 1), Diff2D(-2, 2), Diff2D(-1, 2), Diff2D(0, 2) },
+            { Diff2D(1, 1), Diff2D(1, 0), Diff2D(0, 0), Diff2D(-1, 0),
+              Diff2D(-1, 1), Diff2D(-1, 2), Diff2D(0, 2), Diff2D(1, 2) },
+            { Diff2D(2, 1), Diff2D(2, 0), Diff2D(1, 0), Diff2D(0, 0),
+              Diff2D(0, 1), Diff2D(0, 2), Diff2D(1, 2), Diff2D(2, 2) },
+            { Diff2D(2, 0), Diff2D(2, -1), Diff2D(1, -1), Diff2D(0, -1),
+              Diff2D(0, 0), Diff2D(0, 1), Diff2D(1, 1), Diff2D(2, 1) },
+            { Diff2D(2, -1), Diff2D(2, -2), Diff2D(1, -2), Diff2D(0, -2),
+              Diff2D(0, -1), Diff2D(0, 0), Diff2D(1, 0), Diff2D(2, 0) },
+            { Diff2D(1, -1), Diff2D(1, -2), Diff2D(0, -2), Diff2D(-1, -2),
+              Diff2D(-1, -1), Diff2D(-1, 0), Diff2D(0, 0), Diff2D(1, 0) },
+            { Diff2D(0, -1), Diff2D(0, -2), Diff2D(-1, -2), Diff2D(-2, -2),
+              Diff2D(-2, -1), Diff2D(-2, 0), Diff2D(-1, 0), Diff2D(0, 0) }
+        };
+
+} // namespace EightNeighborhood
+
+    /** Export \ref vigra::EightNeighborhood::NeighborCode into the scope of namespace vigra.
+    */
+typedef EightNeighborhood::NeighborCode EightNeighborCode;
+
+/********************************************************/
+/*                                                      */
+/*              NeighborOffsetCirculator                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Circulator that walks around a given location.
+
+    The template parameter defines the kind of neighborhood used, e.g.
+
+    \code
+    NeighborOffsetCirculator<EightNeighborCode> eight_circulator;
+    NeighborOffsetCirculator<FourNeighborCode>  four_circulator;
+    \endcode
+
+    Since this circulator doesn't know about the pixels in any particular image,
+    you usually don't use it directly but rather as a base class or helper for
+    neighborhood circulators referring to a particular image (e.g. NeighborhoodCirculator)
+
+    <b>\#include</b> \<vigra/pixelneighborhood.hxx\><br>
+    Namespace: vigra
+*/
+template<class NEIGHBORCODE>
+class NeighborOffsetCirculator
+: public NEIGHBORCODE
+{
+public:
+    typedef NEIGHBORCODE NeighborCode;
+
+        /** return type of direction()
+        */
+    typedef typename NEIGHBORCODE::Direction Direction;
+
+        /** the circulator's value type
+        */
+    typedef typename NEIGHBORCODE::difference_type value_type;
+
+        /** the circulator's reference type (return type of <TT>*circ</TT>)
+        */
+    typedef value_type const & reference;
+
+        /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
+        */
+    typedef value_type const & index_reference;
+
+        /** the circulator's pointer type (return type of <TT>operator-></TT>)
+        */
+    typedef value_type const * pointer;
+
+        /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
+        */
+    typedef int difference_type;
+
+        /** the circulator tag (random access iterator)
+        */
+    typedef random_access_circulator_tag iterator_category;
+
+protected:
+    Direction direction_;
+
+public:
+        /** Create circulator referring to the given direction.
+        */
+    NeighborOffsetCirculator(Direction dir = NEIGHBORCODE::InitialDirection)
+        : direction_(dir)
+    {
+    }
+
+        /** pre-increment */
+    NeighborOffsetCirculator & operator++()
+    {
+        direction_ = static_cast<Direction>((direction_+1) % NEIGHBORCODE::DirectionCount);
+        return *this;
+    }
+
+        /** pre-decrement */
+    NeighborOffsetCirculator & operator--()
+    {
+        direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::DirectionCount-1) % NEIGHBORCODE::DirectionCount);
+        return *this;
+    }
+
+        /** post-increment */
+    NeighborOffsetCirculator operator++(int)
+    {
+        NeighborOffsetCirculator ret(*this);
+        operator++();
+        return ret;
+    }
+
+        /** post-decrement */
+    NeighborOffsetCirculator operator--(int)
+    {
+        NeighborOffsetCirculator ret(*this);
+        operator--();
+        return ret;
+    }
+
+        /** add-assignment */
+    NeighborOffsetCirculator & operator+=(difference_type d)
+    {
+        direction_ = static_cast<Direction>((direction_ + d) % NEIGHBORCODE::DirectionCount);
+        if(direction_ < 0)
+            direction_ = static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
+        return *this;
+    }
+
+        /** subtract-assignment */
+    NeighborOffsetCirculator & operator-=(difference_type d)
+    {
+        direction_ = static_cast<Direction>((direction_ - d) % NEIGHBORCODE::DirectionCount);
+        if(direction_ < 0)
+            direction_ = static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
+        return *this;
+    }
+
+        /** addition */
+    NeighborOffsetCirculator operator+(difference_type d) const
+    {
+        return NeighborOffsetCirculator(*this) += d;
+    }
+
+        /** subtraction */
+    NeighborOffsetCirculator operator-(difference_type d) const
+    {
+        return NeighborOffsetCirculator(*this) -= d;
+    }
+
+        /** Move to the direction that is 'right' relative to the current direction.
+            This is equivalent to <tt>four_circulator--</tt> and
+            <tt>eight_circulator -= 2</tt> respectively.
+        */
+    NeighborOffsetCirculator & turnRight()
+    {
+        direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::South) % NEIGHBORCODE::DirectionCount);
+        return *this;
+    }
+
+        /** Move to the direction that is 'left' relative to the current direction.
+            This is equivalent to <tt>four_circulator++</tt> and
+            <tt>eight_circulator += 2</tt> respectively.
+        */
+    NeighborOffsetCirculator & turnLeft()
+    {
+        direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::North) % NEIGHBORCODE::DirectionCount);
+        return *this;
+    }
+
+        /** Move to the opposite direction of the current direction.
+            This is equivalent to <tt>four_circulator += 2</tt> and
+            <tt>eight_circulator += 4</tt> respectively.
+        */
+    NeighborOffsetCirculator & turnRound()
+    {
+        direction_ = opposite();
+        return *this;
+    }
+
+        /** Move to the given direction.
+        */
+    NeighborOffsetCirculator & turnTo(Direction d)
+    {
+        direction_ = d;
+        return *this;
+    }
+
+        /** equality */
+    bool operator==(NeighborOffsetCirculator const & o) const
+    {
+        return direction_ == o.direction_;
+    }
+
+        /** inequality */
+    bool operator!=(NeighborOffsetCirculator const & o) const
+    {
+        return direction_ != o.direction_;
+    }
+
+        /** subtraction */
+    difference_type operator-(NeighborOffsetCirculator const & o) const
+    {
+        return direction_ - o.direction_;
+    }
+
+        /** dereference */
+    reference operator*() const
+    {
+        return diff();
+    }
+
+        /** index */
+    index_reference operator[](difference_type d) const
+    {
+        return NEIGHBORCODE::diff(direction(d));
+    }
+
+        /** member access */
+    pointer operator->() const
+    {
+        return &diff();
+    }
+
+        /** Get offset from center to current neighbor.
+        */
+    reference diff() const
+    {
+        return NEIGHBORCODE::diff(direction_);
+    }
+
+        /** Get offset to given direction.
+        */
+    static reference diff(Direction dir)
+    {
+        return NEIGHBORCODE::diff(dir);
+    }
+
+        /** Get relative distance from current neighbor to neighbor
+            at given offset.
+        */
+    value_type relativeDiff(difference_type offset) const
+    {
+        Direction toDir = static_cast<Direction>((direction_ + offset) % NEIGHBORCODE::DirectionCount);
+        if(toDir < 0)
+            toDir = static_cast<Direction>(toDir + NEIGHBORCODE::DirectionCount);
+        return NEIGHBORCODE::relativeDiff(direction_, toDir);
+    }
+
+        /** X-component of diff()  */
+    int dX() const
+    {
+        return NEIGHBORCODE::dX(direction_);
+    }
+
+        /** Y-component of diff() */
+    int dY() const
+    {
+        return NEIGHBORCODE::dY(direction_);
+    }
+
+        /** Check whether current direction is a diagonal one.
+        */
+    bool isDiagonal() const
+    {
+        return NEIGHBORCODE::isDiagonal(direction_);
+    }
+
+        /** Get current direction.
+        */
+    Direction direction() const
+    {
+        return direction_;
+    }
+
+        /** Get current direction bit.
+        */
+    unsigned int directionBit() const
+    {
+        return NEIGHBORCODE::directionBit(direction_);
+    }
+
+        /** Get opposite of current direction.
+        */
+    Direction opposite() const
+    {
+        return static_cast<Direction>((NEIGHBORCODE::OppositeDirPrefix*direction_ + NEIGHBORCODE::OppositeOffset) % NEIGHBORCODE::DirectionCount);
+    }
+
+        /** Get opposite bit of current direction.
+        */
+    unsigned int oppositeDirectionBit() const
+    {
+        return NEIGHBORCODE::directionBit(opposite());
+    }
+
+        /** Get direction code at offset of current direction.
+        */
+    Direction direction(difference_type offset) const
+    {
+        int result = (direction_ + offset) % NEIGHBORCODE::DirectionCount;
+        if(result < 0)
+            result += NEIGHBORCODE::DirectionCount;
+        return static_cast<Direction>(result);
+    }
+};
+
+/** Specialization of NeighborOffsetCirculator for 8-neighborhood.
+*/
+typedef NeighborOffsetCirculator<EightNeighborCode> EightNeighborOffsetCirculator;
+
+/** Specialization of NeighborOffsetCirculator for 4-neighborhood.
+*/
+typedef NeighborOffsetCirculator<FourNeighborCode> FourNeighborOffsetCirculator;
+
+
+//@}
+
+/** \addtogroup ImageIteratorAdapters
+ */
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                NeighborhoodCirculator                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Circulator that walks around a given location in a given image.
+
+    The template parameters define the kind of neighborhood used and the underlying
+    image. The access functions return the value of the current neighbor pixel.
+    Use <tt>center()</tt> to access the center pixel of the neighborhood.
+    The center can be changed by calling <tt>moveCenterToNeighbor()</tt>
+    or <tt>swapCenterNeighbor()</tt>. Note that this circulator cannot be used
+    when the center is at the image border. You must then use
+    \ref vigra::RestrictedNeighborhoodCirculator
+
+    <b>Usage:</b><br>
+
+    <b>\#include</b> \<vigra/pixelneighborhood.hxx\><br>
+    Namespace: vigra
+
+    \code
+    BImage::traverser upperleft(...), lowerright(...);
+
+    int width  = lowerright.x - upperleft.x;
+    int height = lowerright.y - upperleft.y;
+
+    ++upperleft.y; // avoid image border
+    for(int y=1; y<height-1; ++y, ++upperleft.y)
+    {
+        BImage::traverser ix = upperleft + Diff2D(1,0);
+        for(int x=1; x<width-1; ++x, ++ix.x)
+        {
+            // analyse all neighbors of a pixel (use FourNeighborCode
+            // instead of EightNeighborCode for 4-neighborhood):
+            NeighborhoodCirculator<BImage::traverser, EightNeighborCode>
+                           circulator(ix),
+                           end(circulator);
+            do
+            {
+                analysisFunc(*circulator, ...); // do sth. with current neighbor
+            }
+            while(++circulator != end); // compare with start/end circulator
+        }
+    }
+    \endcode
+*/
+template <class IMAGEITERATOR, class NEIGHBORCODE>
+class NeighborhoodCirculator : private IMAGEITERATOR
+{
+    typedef NeighborOffsetCirculator<NEIGHBORCODE> NEIGHBOROFFSETCIRCULATOR;
+
+
+public:
+        /** type of the underlying image iterator
+        */
+    typedef IMAGEITERATOR base_type;
+
+        /** type of the used neighbor code
+        */
+    typedef NEIGHBORCODE NeighborCode;
+
+        /** the circulator's value type
+        */
+    typedef typename IMAGEITERATOR::value_type value_type;
+
+        /** type of the direction code
+        */
+    typedef typename NEIGHBORCODE::Direction Direction;
+
+        /** the circulator's reference type (return type of <TT>*circ</TT>)
+        */
+    typedef typename IMAGEITERATOR::reference reference;
+
+        /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
+        */
+
+    typedef reference index_reference;
+
+        /** the circulator's pointer type (return type of <TT>operator-></TT>)
+        */
+    typedef typename IMAGEITERATOR::pointer pointer;
+
+        /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
+        */
+    typedef typename NEIGHBOROFFSETCIRCULATOR::difference_type difference_type;
+
+        /** the circulator tag (random_access_circulator_tag)
+        */
+    typedef typename NEIGHBOROFFSETCIRCULATOR::iterator_category iterator_category;
+
+        /** Construct circulator with given <tt>center</tt> pixel, pointing to the neighbor
+            at the given direction <tt>d</tt>.
+        */
+    NeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEITERATOR(),
+                           Direction d = NEIGHBOROFFSETCIRCULATOR::InitialDirection)
+        : IMAGEITERATOR(center), neighborCode_(d)
+    {
+        IMAGEITERATOR::operator+=(neighborCode_.diff());
+    }
+
+        /** pre-increment */
+    NeighborhoodCirculator & operator++()
+    {
+        return operator+=(1);
+    }
+
+        /** post-increment */
+    NeighborhoodCirculator operator++(int)
+    {
+        NeighborhoodCirculator ret(*this);
+        operator++();
+        return ret;
+    }
+
+        /** pre-decrement */
+    NeighborhoodCirculator & operator--()
+    {
+        return operator+=(-1);
+    }
+
+        /** post-decrement */
+    NeighborhoodCirculator operator--(int)
+    {
+        NeighborhoodCirculator ret(*this);
+        operator--();
+        return ret;
+    }
+
+        /** add-assignment */
+    NeighborhoodCirculator & operator+=(difference_type d)
+    {
+        IMAGEITERATOR::operator+=(neighborCode_.relativeDiff(d));
+        neighborCode_+= d;
+        return *this;
+    }
+
+        /** subtract-assignment */
+    NeighborhoodCirculator & operator-=(difference_type d)
+    {
+        return operator+=(-d);
+    }
+
+        /** addition */
+    NeighborhoodCirculator operator+(difference_type d) const
+    {
+        NeighborhoodCirculator result(*this);
+        result+= d;
+        return result;
+    }
+
+        /** subtraction */
+    NeighborhoodCirculator operator-(difference_type d) const
+    {
+        NeighborhoodCirculator result(*this);
+        result-= d;
+        return result;
+    }
+
+        /** Move to the direction that is 'right' relative to the current direction.
+            This is equivalent to <tt>four_circulator--</tt> and
+            <tt>eight_circulator -= 2</tt> respectively.
+        */
+    NeighborhoodCirculator & turnRight()
+    {
+        Direction oldDirection = neighborCode_.direction();
+        neighborCode_.turnRight();
+        IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
+                                  (oldDirection, neighborCode_.direction()));
+        return *this;
+    }
+
+        /** Move to the direction that is 'left' relative to the current direction.
+            This is equivalent to <tt>four_circulator++</tt> and
+            <tt>eight_circulator += 2</tt> respectively.
+        */
+    NeighborhoodCirculator & turnLeft()
+    {
+        Direction oldDirection = neighborCode_.direction();
+        neighborCode_.turnLeft();
+        IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
+                                  (oldDirection, neighborCode_.direction()));
+        return *this;
+    }
+
+        /** Move to the opposite direction of the current direction.
+            This is equivalent to <tt>four_circulator += 2</tt> and
+            <tt>eight_circulator += 4</tt> respectively.
+        */
+    NeighborhoodCirculator & turnRound()
+    {
+        Direction oldDirection = neighborCode_.direction();
+        neighborCode_.turnRound();
+        IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
+                                  (oldDirection, neighborCode_.direction()));
+        return *this;
+    }
+
+        /** Move to the given direction.
+        */
+    NeighborhoodCirculator & turnTo(Direction d)
+    {
+        Direction oldDirection = neighborCode_.direction();
+        neighborCode_.turnTo(d);
+        IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
+                                  (oldDirection, neighborCode_.direction()));
+        return *this;
+    }
+
+        /** Move the center in the current direction.
+            The current neighbor becomes the new center, the direction does not change.
+        */
+    NeighborhoodCirculator & moveCenterToNeighbor()
+    {
+        IMAGEITERATOR::operator+=(neighborCode_.diff());
+        return *this;
+    }
+
+        /** Exchange the center with the current neighbor.
+            Equivalent to <tt>circ.moveCenterToNeighbor().turnRound()</tt>
+            (but shorter and more efficient).
+        */
+    NeighborhoodCirculator & swapCenterNeighbor()
+    {
+        neighborCode_.turnRound();
+        IMAGEITERATOR::operator+=(neighborCode_.diff());
+        return *this;
+    }
+
+        /** equality */
+    bool operator==(NeighborhoodCirculator const & rhs) const
+    {
+        return neighborCode_ == rhs.neighborCode_ &&
+               IMAGEITERATOR::operator==(rhs);
+    }
+
+        /** inequality */
+    bool operator!=(NeighborhoodCirculator const & rhs) const
+    {
+        return neighborCode_ != rhs.neighborCode_ ||
+               IMAGEITERATOR::operator!=(rhs);
+    }
+
+        /** subtraction */
+    difference_type operator-(NeighborhoodCirculator const & rhs) const
+    {
+        return neighborCode_ - rhs.neighborCode_;
+    }
+
+        /** dereference */
+    reference operator*() const
+    {
+        return IMAGEITERATOR::operator*();
+    }
+
+        /** index */
+    index_reference operator[](difference_type d) const
+    {
+        return IMAGEITERATOR::operator[](neighborCode_.relativeDiff(d));
+    }
+
+        /** member access */
+    pointer operator->() const
+    {
+        return IMAGEITERATOR::operator->();
+    }
+
+        /** Get the base iterator for the current neighbor. */
+    base_type const & base() const
+    {
+        return *this;
+    }
+
+        /** Get the base iterator for the center of the circulator. */
+    base_type center() const
+    {
+        return (base_type)*this - neighborCode_.diff();
+    }
+
+        /** Get the current direction. */
+    Direction direction() const
+    {
+        return neighborCode_.direction();
+    }
+
+        /** Get the current direction bit. */
+    unsigned int directionBit() const
+    {
+        return neighborCode_.directionBit();
+    }
+
+        /** Get the difference vector (Diff2D) from the center to the current neighbor. */
+    typename NEIGHBOROFFSETCIRCULATOR::value_type const & diff() const
+    {
+        return neighborCode_.diff();
+    }
+
+        /** Is the current neighbor a diagonal neighbor? */
+    bool isDiagonal() const
+    {
+        return neighborCode_.isDiagonal();
+    }
+
+private:
+    NEIGHBOROFFSETCIRCULATOR neighborCode_;
+};
+
+/********************************************************/
+/*                                                      */
+/*            RestrictedNeighborhoodCirculator          */
+/*                                                      */
+/********************************************************/
+
+/** \brief Circulator that walks around a given location in a given image,
+           using a restricted neighborhood.
+
+    This circulator behaves essentially like \ref vigra::NeighborhoodCirculator,
+    but can also be used near the image border, where some of the neighbor points
+    would be outside the image und must not be accessed.
+    The template parameters define the kind of neighborhood used (four or eight)
+    and the underlying image, whereas the required neighborhood restriction is
+    given by the last constructor argument. This below for typical usage.
+
+    The access functions return the value of the current neighbor pixel. Use <tt>center()</tt> to
+    access the center pixel of the neighborhood.
+
+    <b>Usage:</b><br>
+
+    <b>\#include</b> \<vigra/pixelneighborhood.hxx\><br>
+    Namespace: vigra
+
+    \code
+    BImage::traverser upperleft(...), lowerright(...);
+
+    int width  = lowerright.x - upperleft.x;
+    int height = lowerright.y - upperleft.y;
+
+    for(int y=0; y<height; ++y, ++upperleft.y)
+    {
+        BImage::traverser ix = upperleft;
+        for(int x=0; x<width; ++x, ++ix.x)
+        {
+            // use FourNeighborCode instead of EightNeighborCode for 4-neighborhood
+            RestrictedNeighborhoodCirculator<BImage::traverser, EightNeighborCode>
+                           circulator(ix, isAtImageBorder(x, y, width, height)),
+                           end(circulator);
+            do
+            {
+                ... // do something with the circulator
+            }
+            while(++circulator != end); // out-of-range pixels will be automatically skipped
+        }
+    }
+    \endcode
+*/
+template <class IMAGEITERATOR, class NEIGHBORCODE>
+class RestrictedNeighborhoodCirculator
+: private NeighborhoodCirculator<IMAGEITERATOR, NEIGHBORCODE>
+{
+    typedef NeighborhoodCirculator<IMAGEITERATOR, NEIGHBORCODE> BaseType;
+
+public:
+        /** type of the underlying image iterator
+        */
+    typedef IMAGEITERATOR base_type;
+
+        /** type of the used neighbor code
+        */
+    typedef NEIGHBORCODE NeighborCode;
+
+        /** the circulator's value type
+        */
+    typedef typename BaseType::value_type value_type;
+
+        /** type of the direction code
+        */
+    typedef typename BaseType::Direction Direction;
+
+        /** the circulator's reference type (return type of <TT>*circ</TT>)
+        */
+    typedef typename BaseType::reference reference;
+
+        /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
+        */
+    typedef typename BaseType::index_reference index_reference;
+
+        /** the circulator's pointer type (return type of <TT>operator-></TT>)
+        */
+    typedef typename BaseType::pointer pointer;
+
+        /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
+        */
+    typedef typename BaseType::difference_type difference_type;
+
+        /** the circulator tag (random_access_circulator_tag)
+        */
+    typedef typename BaseType::iterator_category iterator_category;
+
+        /** Construct circulator with given <tt>center</tt> pixel, using the restricted
+            neighborhood given by \a atBorder.
+        */
+    RestrictedNeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEITERATOR(),
+                                     AtImageBorder atBorder = NotAtBorder)
+        : BaseType(center, NEIGHBORCODE::nearBorderDirections(atBorder, 0)),
+          whichBorder_(atBorder),
+          count_(NEIGHBORCODE::nearBorderDirectionCount(atBorder)),
+          current_(0)
+    {}
+
+        /** pre-increment */
+    RestrictedNeighborhoodCirculator & operator++()
+    {
+        return operator+=(1);
+    }
+
+        /** post-increment */
+    RestrictedNeighborhoodCirculator operator++(int)
+    {
+        RestrictedNeighborhoodCirculator ret(*this);
+        operator++();
+        return ret;
+    }
+
+        /** pre-decrement */
+    RestrictedNeighborhoodCirculator & operator--()
+    {
+        return operator+=(-1);
+    }
+
+        /** post-decrement */
+    RestrictedNeighborhoodCirculator operator--(int)
+    {
+        RestrictedNeighborhoodCirculator ret(*this);
+        operator--();
+        return ret;
+    }
+
+        /** add-assignment */
+    RestrictedNeighborhoodCirculator & operator+=(difference_type d)
+    {
+        current_ = static_cast<Direction>((current_ + count_ + d) % count_);
+        BaseType::turnTo(NEIGHBORCODE::nearBorderDirections(whichBorder_, current_));
+        return *this;
+    }
+
+        /** subtract-assignment */
+    RestrictedNeighborhoodCirculator & operator-=(difference_type d)
+    {
+        return operator+=(-d);
+    }
+
+        /** addition */
+    RestrictedNeighborhoodCirculator operator+(difference_type d) const
+    {
+        RestrictedNeighborhoodCirculator result(*this);
+        result+= d;
+        return result;
+    }
+
+        /** subtraction */
+    RestrictedNeighborhoodCirculator operator-(difference_type d) const
+    {
+        RestrictedNeighborhoodCirculator result(*this);
+        result-= d;
+        return result;
+    }
+
+        /** equality */
+    bool operator==(RestrictedNeighborhoodCirculator const & rhs) const
+    {
+        return current_ == rhs.current_;
+    }
+
+        /** inequality */
+    bool operator!=(RestrictedNeighborhoodCirculator const & rhs) const
+    {
+        return current_ != rhs.current_;
+    }
+
+        /** subtraction */
+    difference_type operator-(RestrictedNeighborhoodCirculator const & rhs) const
+    {
+        return (current_ - rhs.current_) % count_;
+    }
+
+        /** dereference */
+    reference operator*() const
+    {
+        return BaseType::operator*();
+    }
+
+        /** member access */
+    pointer operator->() const
+    {
+        return BaseType::operator->();
+    }
+
+        /** Get the base iterator for the current neighbor. */
+    base_type const & base() const
+    {
+        return BaseType::base();
+    }
+
+        /** Get the base iterator for the center of the circulator. */
+    base_type center() const
+    {
+        return BaseType::center();
+    }
+
+        /** Get the current direction. */
+    Direction direction() const
+    {
+        return BaseType::direction();
+    }
+
+        /** Get the current direction bit. */
+    unsigned int directionBit() const
+    {
+        return BaseType::directionBit();
+    }
+
+        /** Get the difference vector (Diff2D) from the center to the current neighbor. */
+    typename NeighborCode::difference_type const & diff() const
+    {
+        return BaseType::diff();
+    }
+
+        /** Is the current neighbor a diagonal neighbor? */
+    bool isDiagonal() const
+    {
+        return BaseType::isDiagonal();
+    }
+
+private:
+     AtImageBorder whichBorder_;
+     signed char count_, current_;
+};
+
+//@}
+
+} // namespace vigra
+
+#endif /* VIGRA_PIXELNEIGHBORHOOD_HXX */
diff --git a/include/vigra/polygon.hxx b/include/vigra/polygon.hxx
new file mode 100644
index 0000000..b103772
--- /dev/null
+++ b/include/vigra/polygon.hxx
@@ -0,0 +1,130 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2010 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_POLYGON_HXX
+#define VIGRA_POLYGON_HXX
+
+#include <cmath>
+#include <cstdlib>
+#include <iterator>
+#include <algorithm>
+#include "config.hxx"
+#include "error.hxx"
+#include "array_vector.hxx"
+
+namespace vigra {
+
+/** \addtogroup MathFunctions
+*/
+//@{
+
+namespace detail {
+
+template < class Point >    
+bool sortPoints(Point const & p1, Point const & p2) 
+{
+    return (p1[0]<p2[0]) || (p1[0] == p2[0] && p1[1] < p2[1]);
+}
+
+template < class Point >    
+bool orderedClockwise(const Point &O, const Point &A, const Point &B)
+{
+    return (A[0] - O[0]) * (B[1] - O[1]) - (A[1] - O[1]) * (B[0] - O[0]) <= 0;
+}
+
+} // namespace detail
+
+
+/** \brief Compute convex hull of a 2D polygon.
+
+    The input array \a points contains a (not necessarily ordered) set of 2D points
+    whose convex hull is to be computed. The array's <tt>value_type</tt> (i.e. the point type)
+    must be compatible with std::vector (in particular, it must support indexing, 
+    copying, and have <tt>size() == 2</tt>). The points of the convex hull will be appended
+    to the output array \a convex_hull (which must support <tt>std::back_inserter(convex_hull)</tt>). 
+    Since the convex hull is a closed polygon, the first and last point of the output will 
+    be the same (i.e. the first point will simply be inserted at the end again). The points
+    of the convex hull will be ordered counter-clockwise, starting with the leftmost point
+    of the input. The function implements Andrew's Monotone Chain algorithm.
+*/
+template<class PointArray1, class PointArray2>
+void convexHull(const PointArray1 &points, PointArray2 & convex_hull)
+{
+    vigra_precondition(points.size() >= 2,
+                       "convexHull(): at least two input points are needed.");
+    vigra_precondition(points[0].size() == 2,
+                       "convexHull(): 2-dimensional points required.");
+    
+    typedef typename PointArray1::value_type Point;
+    
+    ArrayVector<Point> ordered(points.begin(), points.end());
+    std::sort(ordered.begin(), ordered.end(), detail::sortPoints<Point>);
+    
+    ArrayVector<Point> H;
+    
+    int n = points.size(), k=0;
+    
+    // Build lower hull
+    for (int i = 0; i < n; i++) 
+    {
+        while (k >= 2 && detail::orderedClockwise(H[k-2], H[k-1], ordered[i])) 
+        {
+            H.pop_back();
+            --k;
+        }
+        H.push_back(ordered[i]);
+        ++k;
+    }
+    
+    // Build upper hull
+    for (int i = n-2, t = k+1; i >= 0; i--) 
+    {
+        while (k >= t && detail::orderedClockwise(H[k-2], H[k-1], ordered[i])) 
+        {
+            H.pop_back();
+            --k;
+        }
+        H.push_back(ordered[i]);
+        ++k;
+    }
+    
+    std::copy(H.begin(), H.begin()+k, std::back_inserter(convex_hull));
+}
+
+//@}
+
+} // namespace vigra
+
+#endif /* VIGRA_POLYGON_HXX */
diff --git a/include/vigra/polynomial.hxx b/include/vigra/polynomial.hxx
new file mode 100644
index 0000000..4ee0964
--- /dev/null
+++ b/include/vigra/polynomial.hxx
@@ -0,0 +1,1112 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_POLYNOMIAL_HXX
+#define VIGRA_POLYNOMIAL_HXX
+
+#include <cmath>
+#include <complex>
+#include <algorithm>
+#include <iosfwd>
+#include "error.hxx"
+#include "mathutil.hxx"
+#include "numerictraits.hxx"
+#include "array_vector.hxx"
+
+namespace vigra {
+
+template <class T> class Polynomial;
+template <unsigned int MAXORDER, class T> class StaticPolynomial;
+
+/*****************************************************************/
+/*                                                               */
+/*                         PolynomialView                        */
+/*                                                               */
+/*****************************************************************/
+
+/** Polynomial interface for an externally managed array.
+
+    The coefficient type <tt>T</tt> can be either a scalar or complex 
+    (compatible to <tt>std::complex</tt>) type.
+    
+    \see vigra::Polynomial, vigra::StaticPolynomial, polynomialRoots()
+
+    <b>\#include</b> \<vigra/polynomial.hxx\><br>
+    Namespace: vigra
+    
+    \ingroup Polynomials
+*/
+template <class T>
+class PolynomialView
+{
+  public:
+    
+        /** Coefficient type of the polynomial
+        */
+    typedef T         value_type;
+
+        /** Promote type of <tt>value_type</tt>
+            used for polynomial calculations
+        */
+    typedef typename NumericTraits<T>::RealPromote RealPromote;
+
+        /** Scalar type associated with <tt>RealPromote</tt>
+        */
+    typedef typename NumericTraits<RealPromote>::ValueType Real;
+
+        /** Complex type associated with <tt>RealPromote</tt>
+        */
+    typedef typename NumericTraits<RealPromote>::ComplexPromote Complex;
+
+        /** Iterator for the coefficient sequence
+        */
+    typedef T *       iterator;
+
+        /** Const iterator for the coefficient sequence
+        */
+    typedef T const * const_iterator;
+    
+    typedef Polynomial<Real> RealPolynomial;
+    typedef Polynomial<Complex> ComplexPolynomial;
+    
+    
+        /** Construct from a coefficient array of given <tt>order</tt>.
+
+            The externally managed array must have length <tt>order+1</tt>
+            and is interpreted as representing the polynomial:
+            
+            \code
+            coeffs[0] + x * coeffs[1] + x * x * coeffs[2] + ...
+            \endcode
+            
+            The coefficients are not copied, we only store a pointer to the 
+            array.<tt>epsilon</tt> (default: 1.0e-14) determines the precision 
+            of subsequent algorithms (especially root finding) performed on the
+            polynomial.
+        */
+    PolynomialView(T * coeffs, unsigned int order, double epsilon = 1.0e-14)
+    : coeffs_(coeffs),
+      order_(order),
+      epsilon_(epsilon)
+    {}
+    
+        /// Access the coefficient of x^i
+    T & operator[](unsigned int i)
+        { return coeffs_[i]; }
+    
+        /// Access the coefficient of x^i
+    T const & operator[](unsigned int i) const
+        { return coeffs_[i]; }
+    
+        /** Evaluate the polynomial at the point <tt>v</tt> 
+        
+            Multiplication must be defined between the types
+            <tt>V</tt> and <tt>PromoteTraits<T, V>::Promote</tt>.
+            If both <tt>V</tt> and <tt>V</tt> are scalar, the result will
+            be a scalar, otherwise it will be complex.
+        */
+    template <class V>
+    typename PromoteTraits<T, V>::Promote
+    operator()(V v) const;
+    
+        /** Differentiate the polynomial <tt>n</tt> times.
+        */
+    void differentiate(unsigned int n = 1);
+    
+        /** Deflate the polynomial at the root <tt>r</tt> with 
+            the given <tt>multiplicity</tt>.
+            
+            The behavior of this function is undefined if <tt>r</tt>
+            is not a root with at least the given multiplicity.
+            This function calls forwardBackwardDeflate().
+        */
+    void deflate(T const & r, unsigned int multiplicity = 1);
+    
+        /** Forward-deflate the polynomial at the root <tt>r</tt>.
+            
+            The behavior of this function is undefined if <tt>r</tt>
+            is not a root. Forward deflation is best if <tt>r</tt> is
+            the biggest root (by magnitude).
+        */
+    void forwardDeflate(T const & v);
+    
+        /** Forward/backward eflate the polynomial at the root <tt>r</tt>.
+            
+            The behavior of this function is undefined if <tt>r</tt>
+            is not a root. Combined forward/backward deflation is best 
+            if <tt>r</tt> is an intermediate root or we don't know
+            <tt>r</tt>'s relation to the other roots of the polynomial.
+        */
+    void forwardBackwardDeflate(T v);
+    
+        /** Backward-deflate the polynomial at the root <tt>r</tt>.
+            
+            The behavior of this function is undefined if <tt>r</tt>
+            is not a root. Backward deflation is best if <tt>r</tt> is
+            the smallest root (by magnitude).
+        */
+    void backwardDeflate(T v);
+    
+        /** Deflate the polynomial with the complex conjugate roots 
+            <tt>r</tt> and <tt>conj(r)</tt>.
+            
+            The behavior of this function is undefined if these are not
+            roots.
+        */
+    void deflateConjugatePair(Complex const & v);
+    
+        /** Adjust the polynomial's order if the highest coefficients are near zero.
+            The order is reduced as long as the absolute value does not exceed 
+            the given \a epsilon.
+        */
+    void minimizeOrder(double epsilon = 0.0);    
+    
+        /** Normalize the polynomial, i.e. dived by the highest coefficient.
+        */
+    void normalize();
+     
+    void balance();
+        
+        /** Get iterator for the coefficient sequence.
+        */
+    iterator begin()
+        { return coeffs_; }
+    
+        /** Get end iterator for the coefficient sequence.
+        */
+    iterator end()
+        { return begin() + size(); }
+    
+        /** Get const_iterator for the coefficient sequence.
+        */
+    const_iterator begin() const
+        { return coeffs_; }
+    
+        /** Get end const_iterator for the coefficient sequence.
+        */
+    const_iterator end() const
+        { return begin() + size(); }
+    
+        /** Get length of the coefficient sequence (<tt>order() + 1</tt>).
+        */
+    unsigned int size() const
+        { return order_ + 1; }
+        
+        /** Get order of the polynomial.
+        */
+    unsigned int order() const
+        { return order_; }
+        
+        /** Get requested precision for polynomial algorithms 
+            (especially root finding).
+        */
+    double epsilon() const
+        { return epsilon_; }
+        
+        /** Set requested precision for polynomial algorithms 
+            (especially root finding).
+        */
+    void setEpsilon(double eps)
+        { epsilon_ = eps; }
+
+  protected:
+    PolynomialView(double epsilon = 1e-14)
+    : coeffs_(0),
+      order_(0),
+      epsilon_(epsilon)
+    {}
+    
+    void setCoeffs(T * coeffs, unsigned int order)
+    {
+        coeffs_ = coeffs;
+        order_ = order;
+    }
+  
+    T * coeffs_;
+    unsigned int order_;
+    double epsilon_;
+};
+
+template <class T>
+template <class U>
+typename PromoteTraits<T, U>::Promote
+PolynomialView<T>::operator()(U v) const
+{
+    typename PromoteTraits<T, U>::Promote p(coeffs_[order_]);
+    for(int i = order_ - 1; i >= 0; --i)
+    {
+       p = v * p + coeffs_[i];
+    }
+    return p;
+}
+
+/*
+template <class T>
+typename PolynomialView<T>::Complex 
+PolynomialView<T>::operator()(Complex const & v) const
+{
+    Complex p(coeffs_[order_]);
+    for(int i = order_ - 1; i >= 0; --i)
+    {
+       p = v * p + coeffs_[i];
+    }
+    return p;
+}
+*/
+
+template <class T>
+void
+PolynomialView<T>::differentiate(unsigned int n)
+{
+    if(n == 0)
+        return;
+    if(order_ == 0)
+    {
+        coeffs_[0] = 0.0;
+        return;
+    }
+    for(unsigned int i = 1; i <= order_; ++i)
+    {
+        coeffs_[i-1] = double(i)*coeffs_[i];
+    }
+    --order_;
+    if(n > 1)
+        differentiate(n-1);
+}
+
+template <class T>
+void
+PolynomialView<T>::deflate(T const & v, unsigned int multiplicity)
+{
+    vigra_precondition(order_ > 0,
+        "PolynomialView<T>::deflate(): cannot deflate 0th order polynomial.");
+    if(v == 0.0)
+    {
+        ++coeffs_;
+        --order_;
+    }
+    else
+    {
+        // we use combined forward/backward deflation because
+        // our initial guess seems to favour convergence to 
+        // a root with magnitude near the median among all roots
+        forwardBackwardDeflate(v);
+    }
+    if(multiplicity > 1)
+        deflate(v, multiplicity-1);
+}
+
+template <class T>
+void
+PolynomialView<T>::forwardDeflate(T const & v)
+{
+    for(int i = order_-1; i > 0; --i)
+    {
+        coeffs_[i] += v * coeffs_[i+1];
+    }
+    ++coeffs_;
+    --order_;
+}
+
+template <class T>
+void
+PolynomialView<T>::forwardBackwardDeflate(T v)
+{
+    unsigned int order2 = order_ / 2;
+    T tmp = coeffs_[order_];
+    for(unsigned int i = order_-1; i >= order2; --i)
+    {
+        T tmp1 = coeffs_[i];
+        coeffs_[i] = tmp;
+        tmp = tmp1 + v * tmp;
+    }
+    v = -1.0 / v;
+    coeffs_[0] *= v;
+    for(unsigned int i = 1; i < order2; ++i)
+    {
+        coeffs_[i] = v * (coeffs_[i] - coeffs_[i-1]);
+    }
+    --order_;
+}
+
+template <class T>
+void
+PolynomialView<T>::backwardDeflate(T v)
+{
+    v = -1.0 / v;
+    coeffs_[0] *= v;
+    for(unsigned int i = 1; i < order_; ++i)
+    {
+        coeffs_[i] = v * (coeffs_[i] - coeffs_[i-1]);
+    }
+    --order_;
+}
+
+template <class T>
+void
+PolynomialView<T>::deflateConjugatePair(Complex const & v)
+{
+    vigra_precondition(order_ > 1,
+        "PolynomialView<T>::deflateConjugatePair(): cannot deflate 2 roots "
+        "from 1st order polynomial.");
+    Real a = 2.0*v.real();
+    Real b = -sq(v.real()) - sq(v.imag());
+    coeffs_[order_-1] += a * coeffs_[order_];
+    for(int i = order_-2; i > 1; --i)
+    {
+        coeffs_[i] += a * coeffs_[i+1] + b*coeffs_[i+2];
+    }
+    coeffs_ += 2;
+    order_ -= 2;
+}
+    
+template <class T>
+void 
+PolynomialView<T>::minimizeOrder(double epsilon)
+{
+    while(std::abs(coeffs_[order_]) <= epsilon && order_ > 0)
+            --order_;
+}
+
+template <class T>
+void 
+PolynomialView<T>::normalize()
+{
+    for(unsigned int i = 0; i<order_; ++i)
+        coeffs_[i] /= coeffs_[order_];
+    coeffs_[order_] = T(1.0);
+}
+
+template <class T>
+void 
+PolynomialView<T>::balance()
+{
+    Real p0 = abs(coeffs_[0]), po = abs(coeffs_[order_]);
+    Real norm = (p0 > 0.0)
+                    ? VIGRA_CSTD::sqrt(p0*po) 
+                    : po;
+    for(unsigned int i = 0; i<=order_; ++i)
+        coeffs_[i] /= norm;
+}
+
+/*****************************************************************/
+/*                                                               */
+/*                           Polynomial                          */
+/*                                                               */
+/*****************************************************************/
+
+/** Polynomial with internally managed array.
+
+    Most interesting functionality is inherited from \ref vigra::PolynomialView.
+
+    \see vigra::PolynomialView, vigra::StaticPolynomial, polynomialRoots()
+
+    <b>\#include</b> \<vigra/polynomial.hxx\><br>
+    Namespace: vigra
+    
+    \ingroup Polynomials
+*/
+template <class T>
+class Polynomial
+: public PolynomialView<T>
+{
+    typedef PolynomialView<T> BaseType;
+  public:
+    typedef typename BaseType::Real    Real;
+    typedef typename BaseType::Complex Complex;
+    typedef Polynomial<Real>           RealPolynomial;
+    typedef Polynomial<Complex>        ComplexPolynomial;
+
+    typedef T         value_type;
+    typedef T *       iterator;
+    typedef T const * const_iterator;    
+    
+        /** Construct polynomial with given <tt>order</tt> and all coefficients
+            set to zero (they can be set later using <tt>operator[]</tt>
+            or the iterators). <tt>epsilon</tt> (default: 1.0e-14) determines 
+            the precision of subsequent algorithms (especially root finding) 
+            performed on the polynomial.
+        */
+    Polynomial(unsigned int order = 0, double epsilon = 1.0e-14)
+    : BaseType(epsilon),
+      polynomial_(order + 1, T())
+    {
+        this->setCoeffs(&polynomial_[0], order);
+    }
+    
+        /** Copy constructor
+        */
+    Polynomial(Polynomial const & p)
+    : BaseType(p.epsilon()),
+      polynomial_(p.begin(), p.end())
+    {
+        this->setCoeffs(&polynomial_[0], p.order());
+    }
+
+        /** Construct polynomial by copying the given coefficient sequence.
+        */
+    template <class ITER>
+    Polynomial(ITER i, unsigned int order)
+    : BaseType(),
+      polynomial_(i, i + order + 1)
+    {
+        this->setCoeffs(&polynomial_[0], order);
+    }
+    
+        /** Construct polynomial by copying the given coefficient sequence.
+            Set <tt>epsilon</tt> (default: 1.0e-14) as 
+            the precision of subsequent algorithms (especially root finding) 
+            performed on the polynomial.
+        */
+    template <class ITER>
+    Polynomial(ITER i, unsigned int order, double epsilon)
+    : BaseType(epsilon),
+      polynomial_(i, i + order + 1)
+    {
+        this->setCoeffs(&polynomial_[0], order);
+    }
+    
+        /** Assigment
+        */
+    Polynomial & operator=(Polynomial const & p)
+    {
+        if(this == &p)
+            return *this;
+        ArrayVector<T> tmp(p.begin(), p.end());
+        polynomial_.swap(tmp);
+        this->setCoeffs(&polynomial_[0], p.order());
+        this->epsilon_ = p.epsilon_;
+        return *this;
+    }
+    
+        /** Construct new polynomial representing the derivative of this
+            polynomial.
+        */
+    Polynomial<T> getDerivative(unsigned int n = 1) const
+    {
+        Polynomial<T> res(*this);
+        res.differentiate(n);
+        return res;
+    }
+
+        /** Construct new polynomial representing this polynomial after
+            deflation at the real root <tt>r</tt>.
+        */
+    Polynomial<T> 
+    getDeflated(Real r) const
+    {
+        Polynomial<T> res(*this);
+        res.deflate(r);
+        return res;
+    }
+
+        /** Construct new polynomial representing this polynomial after
+            deflation at the complex root <tt>r</tt>. The resulting
+            polynomial will have complex coefficients, even if this
+            polynomial had real ones.
+        */
+    Polynomial<Complex> 
+    getDeflated(Complex const & r) const
+    {
+        Polynomial<Complex> res(this->begin(), this->order(), this->epsilon());
+        res.deflate(r);
+        return res;
+    }
+
+  protected:
+    ArrayVector<T> polynomial_;
+};
+
+/*****************************************************************/
+/*                                                               */
+/*                        StaticPolynomial                       */
+/*                                                               */
+/*****************************************************************/
+
+/** Polynomial with internally managed array of static length.
+
+    Most interesting functionality is inherited from \ref vigra::PolynomialView.
+    This class differs from \ref vigra::Polynomial in that it allocates
+    its memory statically which is much faster. Therefore, <tt>StaticPolynomial</tt>
+    can only represent polynomials up to the given <tt>MAXORDER</tt>.
+
+    \see vigra::PolynomialView, vigra::Polynomial, polynomialRoots()
+
+    <b>\#include</b> \<vigra/polynomial.hxx\><br>
+    Namespace: vigra
+    
+    \ingroup Polynomials
+*/
+template <unsigned int MAXORDER, class T>
+class StaticPolynomial
+: public PolynomialView<T>
+{
+    typedef PolynomialView<T> BaseType;
+    
+  public:
+    typedef typename BaseType::Real    Real;
+    typedef typename BaseType::Complex Complex;
+    typedef StaticPolynomial<MAXORDER, Real> RealPolynomial;
+    typedef StaticPolynomial<MAXORDER, Complex> ComplexPolynomial;
+
+    typedef T         value_type;
+    typedef T *       iterator;
+    typedef T const * const_iterator;
+    
+    
+        /** Construct polynomial with given <tt>order <= MAXORDER</tt> and all 
+            coefficients set to zero (they can be set later using <tt>operator[]</tt>
+            or the iterators). <tt>epsilon</tt> (default: 1.0e-14) determines 
+            the precision of subsequent algorithms (especially root finding) 
+            performed on the polynomial.
+        */
+    StaticPolynomial(unsigned int order = 0, double epsilon = 1.0e-14)
+    : BaseType(epsilon)
+    {
+        vigra_precondition(order <= MAXORDER,
+            "StaticPolynomial(): order exceeds MAXORDER.");
+        std::fill_n(polynomial_, order+1, T());
+        this->setCoeffs(polynomial_, order);
+    }
+    
+        /** Copy constructor
+        */
+    StaticPolynomial(StaticPolynomial const & p)
+    : BaseType(p.epsilon())
+    {
+        std::copy(p.begin(), p.end(), polynomial_);
+        this->setCoeffs(polynomial_, p.order());
+    }
+
+        /** Construct polynomial by copying the given coefficient sequence.
+            <tt>order <= MAXORDER</tt> is required.
+        */
+    template <class ITER>
+    StaticPolynomial(ITER i, unsigned int order)
+    : BaseType()
+    {
+        vigra_precondition(order <= MAXORDER,
+            "StaticPolynomial(): order exceeds MAXORDER.");
+        std::copy(i, i + order + 1, polynomial_);
+        this->setCoeffs(polynomial_, order);
+    }
+    
+        /** Construct polynomial by copying the given coefficient sequence.
+            <tt>order <= MAXORDER</tt> is required. Set <tt>epsilon</tt> (default: 1.0e-14) as 
+            the precision of subsequent algorithms (especially root finding) 
+            performed on the polynomial.
+        */
+    template <class ITER>
+    StaticPolynomial(ITER i, unsigned int order, double epsilon)
+    : BaseType(epsilon)
+    {
+        vigra_precondition(order <= MAXORDER,
+            "StaticPolynomial(): order exceeds MAXORDER.");
+        std::copy(i, i + order + 1, polynomial_);
+        this->setCoeffs(polynomial_, order);
+    }
+    
+        /** Assigment.
+        */
+    StaticPolynomial & operator=(StaticPolynomial const & p)
+    {
+        if(this == &p)
+            return *this;
+        std::copy(p.begin(), p.end(), polynomial_);
+        this->setCoeffs(polynomial_, p.order());
+        this->epsilon_ = p.epsilon_;
+        return *this;
+    }
+    
+        /** Construct new polynomial representing the derivative of this
+            polynomial.
+        */
+    StaticPolynomial getDerivative(unsigned int n = 1) const
+    {
+        StaticPolynomial res(*this);
+        res.differentiate(n);
+        return res;
+    }
+
+        /** Construct new polynomial representing this polynomial after
+            deflation at the real root <tt>r</tt>.
+        */
+    StaticPolynomial 
+    getDeflated(Real r) const
+    {
+        StaticPolynomial res(*this);
+        res.deflate(r);
+        return res;
+    }
+
+        /** Construct new polynomial representing this polynomial after
+            deflation at the complex root <tt>r</tt>. The resulting
+            polynomial will have complex coefficients, even if this
+            polynomial had real ones.
+        */
+    StaticPolynomial<MAXORDER, Complex> 
+    getDeflated(Complex const & r) const
+    {
+        StaticPolynomial<MAXORDER, Complex>  res(this->begin(), this->order(), this->epsilon());
+        res.deflate(r);
+        return res;
+    }
+    
+    void setOrder(unsigned int order)
+    {
+        vigra_precondition(order <= MAXORDER,
+            "taticPolynomial::setOrder(): order exceeds MAXORDER.");
+        this->order_ = order;
+    }
+
+  protected:
+    T polynomial_[MAXORDER+1];
+};
+
+/************************************************************/
+
+namespace detail {
+
+// replacement for complex division (some compilers have numerically
+// less stable implementations); code from python complexobject.c
+template <class T>
+std::complex<T> complexDiv(std::complex<T> const & a, std::complex<T> const & b)
+{
+     const double abs_breal = b.real() < 0 ? -b.real() : b.real();
+     const double abs_bimag = b.imag() < 0 ? -b.imag() : b.imag();
+
+     if (abs_breal >= abs_bimag) 
+     {
+        /* divide tops and bottom by b.real() */
+        if (abs_breal == 0.0) 
+        {
+            return std::complex<T>(a.real() / abs_breal, a.imag() / abs_breal);
+        }
+        else 
+        {
+            const double ratio = b.imag() / b.real();
+            const double denom = b.real() + b.imag() * ratio;
+            return std::complex<T>((a.real() + a.imag() * ratio) / denom,
+                                   (a.imag() - a.real() * ratio) / denom);
+        }
+    }
+    else 
+    {
+        /* divide tops and bottom by b.imag() */
+        const double ratio = b.real() / b.imag();
+        const double denom = b.real() * ratio + b.imag();
+        return std::complex<T>((a.real() * ratio + a.imag()) / denom,
+                               (a.imag() * ratio - a.real()) / denom);
+    }
+}
+
+template <class T>
+std::complex<T> deleteBelowEpsilon(std::complex<T> const & x, double eps)
+{
+    return std::abs(x.imag()) <= 2.0*eps*std::abs(x.real()) 
+                ? std::complex<T>(x.real())
+                : std::abs(x.real()) <= 2.0*eps*std::abs(x.imag()) 
+                    ? std::complex<T>(NumericTraits<T>::zero(), x.imag())
+                    :  x;
+}
+
+template <class POLYNOMIAL>
+typename POLYNOMIAL::value_type
+laguerreStartingGuess(POLYNOMIAL const & p)
+{
+    double N = p.order();
+    typename POLYNOMIAL::value_type centroid = -p[p.order()-1] / N / p[p.order()];
+    double dist = VIGRA_CSTD::pow(std::abs(p(centroid) / p[p.order()]), 1.0 / N);
+    return centroid + dist;
+}
+
+template <class POLYNOMIAL, class Complex>
+int laguerre1Root(POLYNOMIAL const & p, Complex & x, unsigned int multiplicity)
+{
+    typedef typename NumericTraits<Complex>::ValueType Real;
+    
+    double frac[] = {0.0, 0.5, 0.25, 0.75, 0.13, 0.38, 0.62, 0.88, 1.0};
+    int maxiter = 80, 
+        count;
+    double N = p.order();
+    double eps  = p.epsilon(),
+           eps2 = VIGRA_CSTD::sqrt(eps);
+        
+    if(multiplicity == 0)
+        x = laguerreStartingGuess(p);
+        
+    bool mayTryDerivative = true;  // try derivative for multiple roots
+    
+    for(count = 0; count < maxiter; ++count)
+    {
+        // Horner's algorithm to calculate values of polynomial and its
+        // first two derivatives and estimate error for current x
+        Complex p0(p[p.order()]);
+        Complex p1(0.0);
+        Complex p2(0.0);
+        Real ax    = std::abs(x);
+        Real err = std::abs(p0);
+        for(int i = p.order()-1; i >= 0; --i)
+        {
+            p2  = p2  * x  + p1;
+            p1  = p1  * x  + p0;
+            p0  = p0  * x  + p[i];
+            err = err * ax + std::abs(p0);
+        }
+        p2 *= 2.0;
+        err *= eps;
+        Real ap0 = std::abs(p0);
+        if(ap0 <= err)
+        {
+            break;  // converged
+        }
+        Complex g = complexDiv(p1, p0);
+        Complex g2 = g * g;
+        Complex h = g2 - complexDiv(p2, p0);
+        // estimate root multiplicity according to Tien Chen
+        if(g2 != 0.0)
+        {
+            multiplicity = (unsigned int)VIGRA_CSTD::floor(N / 
+                                (std::abs(N * complexDiv(h, g2) - 1.0) + 1.0) + 0.5);
+            if(multiplicity < 1)
+                multiplicity = 1;
+        }
+        // improve accuracy of multiple roots on the derivative, as suggested by C. Bond
+        // (do this only if we are already near the root, otherwise we may converge to 
+        //  a different root of the derivative polynomial)
+        if(mayTryDerivative && multiplicity > 1 && ap0 < eps2)
+        {
+            Complex x1 = x;
+            int derivativeMultiplicity = laguerre1Root(p.getDerivative(), x1, multiplicity-1);
+            if(derivativeMultiplicity && std::abs(p(x1)) < std::abs(p(x)))
+            {
+                // successful search on derivative
+                x = x1;
+                return derivativeMultiplicity + 1;
+            }
+            else
+            {
+                // unsuccessful search on derivative => don't do it again
+                mayTryDerivative = false;
+            }
+        }
+        Complex sq = VIGRA_CSTD::sqrt((N - 1.0) * (N * h - g2));
+        Complex gp = g + sq;
+        Complex gm = g - sq;
+        if(std::abs(gp) < std::abs(gm))
+            gp = gm;
+        Complex dx;
+        if(gp != 0.0)
+        {
+            dx = complexDiv(Complex(N) , gp);
+        }
+        else
+        {
+            // re-initialisation trick due to Numerical Recipes
+            dx = (1.0 + ax) * Complex(VIGRA_CSTD::cos(double(count)), VIGRA_CSTD::sin(double(count)));
+        }
+        Complex x1 = x - dx;
+
+        if(x1 - x == 0.0)
+        {
+            break;  // converged
+        }
+        if((count + 1) % 10)
+            x = x1;
+        else
+            // cycle breaking trick according to Numerical Recipes
+            x = x - frac[(count+1)/10] * dx;
+    }
+    return count < maxiter ? 
+        multiplicity : 
+        0;
+}
+
+template <class Real>
+struct PolynomialRootCompare
+{
+    Real epsilon;
+
+    PolynomialRootCompare(Real eps)
+    : epsilon(eps)
+    {}
+    
+    template <class T>
+    bool operator()(T const & l, T const & r)
+    {
+        return closeAtTolerance(l.real(), r.real(), epsilon)
+                     ? l.imag() < r.imag()
+                     : l.real() < r.real();
+    }
+};
+
+} // namespace detail 
+
+/** \addtogroup Polynomials Polynomials and root determination
+
+    Classes to represent polynomials and functions to find polynomial roots.
+*/
+//@{
+
+/*****************************************************************/
+/*                                                               */
+/*                         polynomialRoots                       */
+/*                                                               */
+/*****************************************************************/
+
+/** Determine the roots of the polynomial <tt>poriginal</tt>.
+
+    The roots are appended to the vector <tt>roots</tt>, with optional root
+    polishing as specified by <tt>polishRoots</tt> (default: do polishing). The function uses an 
+    improved version of Laguerre's algorithm. The improvements are as follows:
+    
+    <ul>
+    <li>It uses a clever initial guess for the iteration, according to a proposal by Tien Chen</li>
+    <li>It estimates each root's multiplicity, again according to Tien Chen, and reduces multiplicity
+        by switching to the polynomial's derivative (which has the same root, with multiplicity
+        reduced by one), as proposed by C. Bond.</li>
+    </ul>
+    
+    The algorithm has been successfully used for polynomials up to order 80.
+    The function stops and returns <tt>false</tt> if an iteration fails to converge within 
+    80 steps. The type <tt>POLYNOMIAL</tt> must be compatible to 
+    \ref vigra::PolynomialView, <tt>VECTOR</tt> must be compatible to <tt>std::vector</tt>
+    with a <tt>value_type</tt> compatible to the type <tt>POLYNOMIAL::Complex</tt>.
+
+    <b> Declaration:</b>
+
+    pass arguments explicitly:
+    \code
+    namespace vigra {
+        template <class POLYNOMIAL, class VECTOR>
+        bool 
+        polynomialRoots(POLYNOMIAL const & poriginal, VECTOR & roots, bool polishRoots = true);
+    }
+    \endcode
+
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/polynomial.hxx\><br>
+    Namespace: vigra
+
+    \code
+    // encode the polynomial  x^4 - 1
+    Polynomial<double> poly(4);
+    poly[0] = -1.0;
+    poly[4] =  1.0;
+
+    ArrayVector<std::complex<double> > roots;
+    polynomialRoots(poly, roots);
+    \endcode
+
+    \see polynomialRootsEigenvalueMethod()
+*/
+template <class POLYNOMIAL, class VECTOR>
+bool polynomialRoots(POLYNOMIAL const & poriginal, VECTOR & roots, bool polishRoots)
+{
+    typedef typename POLYNOMIAL::Real    Real;
+    typedef typename POLYNOMIAL::Complex Complex;
+    typedef typename POLYNOMIAL::ComplexPolynomial WorkPolynomial;
+    
+    double eps  = poriginal.epsilon();
+
+    WorkPolynomial p(poriginal.begin(), poriginal.order(), eps);
+    p.minimizeOrder();
+    if(p.order() == 0)
+        return true;
+
+    Complex x = detail::laguerreStartingGuess(p);
+    
+    unsigned int multiplicity = 1;
+    bool triedConjugate = false;
+    
+    // handle the high order cases
+    while(p.order() > 2)
+    {
+        p.balance();
+        
+        // find root estimate using Laguerre's method on deflated polynomial p;
+        // zero return indicates failure to converge
+        multiplicity = detail::laguerre1Root(p, x, multiplicity);
+    
+        if(multiplicity == 0)
+            return false;
+        // polish root on original polynomial poriginal;
+        // zero return indicates failure to converge
+        if(polishRoots && !detail::laguerre1Root(poriginal, x, multiplicity))
+            return false;
+        x = detail::deleteBelowEpsilon(x, eps);
+        roots.push_back(x);
+        p.deflate(x);
+        // determine the next starting guess
+        if(multiplicity > 1)
+        {
+            // probably multiple root => keep current root as starting guess
+            --multiplicity;
+            triedConjugate = false;
+        }
+        else
+        {
+            // need a new starting guess
+            if(x.imag() != 0.0 && !triedConjugate)
+            {
+                // if the root is complex and we don't already have 
+                // the conjugate root => try the conjugate as starting guess
+                triedConjugate = true;
+                x = conj(x);
+            }
+            else
+            {
+                // otherwise generate new starting guess
+                triedConjugate = false;
+                x = detail::laguerreStartingGuess(p);
+            }
+        }
+    }
+    
+    // handle the low order cases
+    if(p.order() == 2)
+    {
+        Complex a = p[2];
+        Complex b = p[1];
+        Complex c = p[0];
+        Complex b2 = std::sqrt(b*b - 4.0*a*c);
+        Complex q;
+        if((conj(b)*b2).real() >= 0.0)
+            q = -0.5 * (b + b2);
+        else
+            q = -0.5 * (b - b2);
+        x = detail::complexDiv(q, a);
+        if(polishRoots)
+            detail::laguerre1Root(poriginal, x, 1);
+        roots.push_back(detail::deleteBelowEpsilon(x, eps));
+        x = detail::complexDiv(c, q);
+        if(polishRoots)
+            detail::laguerre1Root(poriginal, x, 1);
+        roots.push_back(detail::deleteBelowEpsilon(x, eps));
+    }
+    else if(p.order() == 1)
+    {
+        x = detail::complexDiv(-p[0], p[1]);
+        if(polishRoots)
+            detail::laguerre1Root(poriginal, x, 1);
+        roots.push_back(detail::deleteBelowEpsilon(x, eps));
+    }
+    std::sort(roots.begin(), roots.end(), detail::PolynomialRootCompare<Real>(eps));
+    return true;
+}
+
+template <class POLYNOMIAL, class VECTOR>
+inline bool 
+polynomialRoots(POLYNOMIAL const & poriginal, VECTOR & roots)
+{
+    return polynomialRoots(poriginal, roots, true);
+}
+
+/** Determine the real roots of the polynomial <tt>p</tt>.
+
+    This function simply calls \ref polynomialRoots() and than throws away all complex roots.
+    Accordingly, <tt>VECTOR</tt> must be compatible to <tt>std::vector</tt>
+    with a <tt>value_type</tt> compatible to the type <tt>POLYNOMIAL::Real</tt>.
+
+    <b> Declaration:</b>
+
+    pass arguments explicitly:
+    \code
+    namespace vigra {
+        template <class POLYNOMIAL, class VECTOR>
+        bool 
+        polynomialRealRoots(POLYNOMIAL const & p, VECTOR & roots, bool polishRoots = true);
+    }
+    \endcode
+
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/polynomial.hxx\><br>
+    Namespace: vigra
+
+    \code
+    // encode the polynomial  x^4 - 1
+    Polynomial<double> poly(4);
+    poly[0] = -1.0;
+    poly[4] =  1.0;
+
+    ArrayVector<double> roots;
+    polynomialRealRoots(poly, roots);
+    \endcode
+
+    \see polynomialRealRootsEigenvalueMethod()
+*/
+template <class POLYNOMIAL, class VECTOR>
+bool polynomialRealRoots(POLYNOMIAL const & p, VECTOR & roots, bool polishRoots)
+{
+    typedef typename NumericTraits<typename VECTOR::value_type>::ComplexPromote Complex;
+    ArrayVector<Complex> croots;
+    if(!polynomialRoots(p, croots, polishRoots))
+        return false;
+    for(unsigned int i = 0; i < croots.size(); ++i)
+        if(croots[i].imag() == 0.0)
+            roots.push_back(croots[i].real());
+    return true;
+}
+
+template <class POLYNOMIAL, class VECTOR>
+inline bool 
+polynomialRealRoots(POLYNOMIAL const & poriginal, VECTOR & roots)
+{
+    return polynomialRealRoots(poriginal, roots, true);
+}
+
+//@}
+
+} // namespace vigra
+
+namespace std {
+
+template <class T>
+ostream & operator<<(ostream & o, vigra::PolynomialView<T> const & p)
+{
+    for(unsigned int k=0; k < p.order(); ++k)
+        o << p[k] << " ";
+    o << p[p.order()];
+    return o;
+}
+
+} // namespace std 
+
+#endif // VIGRA_POLYNOMIAL_HXX
diff --git a/include/vigra/project2ellipse.hxx b/include/vigra/project2ellipse.hxx
new file mode 100644
index 0000000..f57fe01
--- /dev/null
+++ b/include/vigra/project2ellipse.hxx
@@ -0,0 +1,177 @@
+
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2012 by Frank Lenzen &                     */
+/*                                           Ullrich Koethe             */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_PROJECT2ELLIPSE_HXX
+#define VIGRA_PROJECT2ELLIPSE_HXX
+#include <iostream>
+
+namespace vigra{
+
+  namespace detail{
+
+//---------------------------------------------------------------------------
+
+void projectEllipse2D_FirstQuad (double &vx, double &vy, double a, double b, const double eps, const int iter_max){                
+  
+  double t=0,tmin,tmax,d1,d2,f,x1,y1,l;                      
+  int i;
+  tmax=std::max(2*a*vx,2*b*vy);
+  tmin=-b*b;
+  d1=a*vx/(tmax+a*a);
+  d2=b*vy/(tmax+b*b);
+  f=d1*d1+d2*d2-1;
+    
+  for (i=0;i<iter_max;i++){
+  
+    t=.5*(tmin+tmax);
+    d1=a*vx/(t+a*a);
+    d2=b*vy/(t+b*b);
+    f=d1*d1+d2*d2-1;
+    x1=a*vx/(t+a*a);
+    y1=b*vy/(t+b*b);
+    l=x1*x1+y1*y1-1;
+   
+    if (fabs(l)<eps)
+      break;
+    if(f>0)
+      tmin=t;
+    else if(f<0)
+      tmax=t;
+    else
+      break;
+  }
+  d1=vx;
+  d2=vy;
+  vx=a*a*vx/(t+a*a);
+  vy=b*b*vy/(t+b*b);
+  d1 = vx - d1;
+  d2 = vy - d2;
+  return;
+}
+
+
+void projectEllipse2D(double &vx, double &vy, const double _a,const double _b,const double eps,const int max_iter){
+  
+  //double err;
+  double a=_a,b=_b;
+  
+  //check if inside ellipse
+  if (((vx/a)*(vx/a)+(vy/b)*(vy/b))<=1){
+    return;
+  }
+  
+  // special case of a circle
+  if (fabs(a-b) < eps){
+    double l = sqrt(vx*vx+vy*vy);
+    if (l>(a+b)/2.){
+      vx=(a+b)/(2*l)*vx;
+      vy=(a+b)/(2*l)*vy;
+    }
+    return;
+  }
+  
+  // reflect vx -> -vx, if necessary
+  bool x_reflect;
+  if (vx > eps){
+    x_reflect = false;
+  }
+  else if (vx < -eps){
+    x_reflect = true;
+    vx = -vx;
+  }
+  else{
+    x_reflect = false;
+    vx = 0.0;
+  }
+  // reflect vy -> vy = -V if necessary
+  bool y_reflect;
+  if (vy > eps){
+    y_reflect = false;
+  }
+  else if (vy < -eps){
+    y_reflect = true;
+    vy = -vy;
+  }
+  else{
+    y_reflect = false;
+    vy = 0.0;
+  }
+  
+  // swap axes if necessary
+  bool swapped;
+  if (a >= b){
+    swapped = false;
+  }
+  else{
+    swapped = true;
+    std::swap(a,b);
+    std::swap(vx,vy);
+  }
+  if (vx != 0.0){
+    if (vy != 0.0){
+      projectEllipse2D_FirstQuad(vx,vy,a,b,eps,max_iter);
+    }
+    else{
+      if (vx < a - b*b/a){
+        double vx_temp = vx;
+        vx = a*a*vx/(a*a-b*b);
+        vy = vy*sqrt(fabs(1.0-vx_temp/a*vx_temp/a));
+      }
+      else{
+        vx = a;
+        vy = 0.0;
+      }
+    }
+  }
+  else{
+    vx = 0.0;
+    vy = b;
+  }
+  if (swapped){
+    std::swap(vx,vy);
+  }
+  if (y_reflect){
+    vy = -vy;
+  }
+  if (x_reflect){
+    vx = -vx;
+  }
+  return;
+}
+  } //closing namespace detail
+} //closing namespace vigra
+#endif // VIGRA_PROJECT2ELLIPSE_HXX
\ No newline at end of file
diff --git a/include/vigra/promote_traits.hxx b/include/vigra/promote_traits.hxx
new file mode 100644
index 0000000..645895a
--- /dev/null
+++ b/include/vigra/promote_traits.hxx
@@ -0,0 +1,1520 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2008 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_PROMOTETRAITS_HXX
+#define VIGRA_PROMOTETRAITS_HXX
+
+// this file was autogenerated from promote_traits.hxx.py - DO NOT EDIT
+
+template <>
+struct PromoteTraits<bool, bool> : public detail::PromoteType<bool, bool>
+{
+    typedef detail::PromoteType<bool, bool>::Promote Promote;
+    using detail::PromoteType<bool, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<bool, signed char> : public detail::PromoteType<bool, signed char>
+{
+    typedef detail::PromoteType<bool, signed char>::Promote Promote;
+    using detail::PromoteType<bool, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<bool, unsigned char> : public detail::PromoteType<bool, unsigned char>
+{
+    typedef detail::PromoteType<bool, unsigned char>::Promote Promote;
+    using detail::PromoteType<bool, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<bool, short> : public detail::PromoteType<bool, short>
+{
+    typedef detail::PromoteType<bool, short>::Promote Promote;
+    using detail::PromoteType<bool, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<bool, unsigned short> : public detail::PromoteType<bool, unsigned short>
+{
+    typedef detail::PromoteType<bool, unsigned short>::Promote Promote;
+    using detail::PromoteType<bool, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<bool, int> : public detail::PromoteType<bool, int>
+{
+    typedef detail::PromoteType<bool, int>::Promote Promote;
+    using detail::PromoteType<bool, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<bool, unsigned int> : public detail::PromoteType<bool, unsigned int>
+{
+    typedef detail::PromoteType<bool, unsigned int>::Promote Promote;
+    using detail::PromoteType<bool, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<bool, long> : public detail::PromoteType<bool, long>
+{
+    typedef detail::PromoteType<bool, long>::Promote Promote;
+    using detail::PromoteType<bool, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<bool, unsigned long> : public detail::PromoteType<bool, unsigned long>
+{
+    typedef detail::PromoteType<bool, unsigned long>::Promote Promote;
+    using detail::PromoteType<bool, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<bool, float> : public detail::PromoteType<bool, float>
+{
+    typedef detail::PromoteType<bool, float>::Promote Promote;
+    using detail::PromoteType<bool, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<bool, double> : public detail::PromoteType<bool, double>
+{
+    typedef detail::PromoteType<bool, double>::Promote Promote;
+    using detail::PromoteType<bool, double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<bool, long double> : public detail::PromoteType<bool, long double>
+{
+    typedef detail::PromoteType<bool, long double>::Promote Promote;
+    using detail::PromoteType<bool, long double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<bool, long long> : public detail::PromoteType<bool, long long>
+{
+    typedef detail::PromoteType<bool, long long>::Promote Promote;
+    using detail::PromoteType<bool, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<bool, unsigned long long> : public detail::PromoteType<bool, unsigned long long>
+{
+    typedef detail::PromoteType<bool, unsigned long long>::Promote Promote;
+    using detail::PromoteType<bool, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+template <>
+struct PromoteTraits<signed char, signed char> : public detail::PromoteType<signed char, signed char>
+{
+    typedef detail::PromoteType<signed char, signed char>::Promote Promote;
+    using detail::PromoteType<signed char, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<signed char, bool> : public detail::PromoteType<signed char, bool>
+{
+    typedef detail::PromoteType<signed char, bool>::Promote Promote;
+    using detail::PromoteType<signed char, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<signed char, unsigned char> : public detail::PromoteType<signed char, unsigned char>
+{
+    typedef detail::PromoteType<signed char, unsigned char>::Promote Promote;
+    using detail::PromoteType<signed char, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<signed char, short> : public detail::PromoteType<signed char, short>
+{
+    typedef detail::PromoteType<signed char, short>::Promote Promote;
+    using detail::PromoteType<signed char, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<signed char, unsigned short> : public detail::PromoteType<signed char, unsigned short>
+{
+    typedef detail::PromoteType<signed char, unsigned short>::Promote Promote;
+    using detail::PromoteType<signed char, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<signed char, int> : public detail::PromoteType<signed char, int>
+{
+    typedef detail::PromoteType<signed char, int>::Promote Promote;
+    using detail::PromoteType<signed char, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<signed char, unsigned int> : public detail::PromoteType<signed char, unsigned int>
+{
+    typedef detail::PromoteType<signed char, unsigned int>::Promote Promote;
+    using detail::PromoteType<signed char, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<signed char, long> : public detail::PromoteType<signed char, long>
+{
+    typedef detail::PromoteType<signed char, long>::Promote Promote;
+    using detail::PromoteType<signed char, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<signed char, unsigned long> : public detail::PromoteType<signed char, unsigned long>
+{
+    typedef detail::PromoteType<signed char, unsigned long>::Promote Promote;
+    using detail::PromoteType<signed char, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<signed char, float> : public detail::PromoteType<signed char, float>
+{
+    typedef detail::PromoteType<signed char, float>::Promote Promote;
+    using detail::PromoteType<signed char, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<signed char, double> : public detail::PromoteType<signed char, double>
+{
+    typedef detail::PromoteType<signed char, double>::Promote Promote;
+    using detail::PromoteType<signed char, double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<signed char, long double> : public detail::PromoteType<signed char, long double>
+{
+    typedef detail::PromoteType<signed char, long double>::Promote Promote;
+    using detail::PromoteType<signed char, long double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<signed char, long long> : public detail::PromoteType<signed char, long long>
+{
+    typedef detail::PromoteType<signed char, long long>::Promote Promote;
+    using detail::PromoteType<signed char, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<signed char, unsigned long long> : public detail::PromoteType<signed char, unsigned long long>
+{
+    typedef detail::PromoteType<signed char, unsigned long long>::Promote Promote;
+    using detail::PromoteType<signed char, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+template <>
+struct PromoteTraits<unsigned char, unsigned char> : public detail::PromoteType<unsigned char, unsigned char>
+{
+    typedef detail::PromoteType<unsigned char, unsigned char>::Promote Promote;
+    using detail::PromoteType<unsigned char, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned char, bool> : public detail::PromoteType<unsigned char, bool>
+{
+    typedef detail::PromoteType<unsigned char, bool>::Promote Promote;
+    using detail::PromoteType<unsigned char, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned char, signed char> : public detail::PromoteType<unsigned char, signed char>
+{
+    typedef detail::PromoteType<unsigned char, signed char>::Promote Promote;
+    using detail::PromoteType<unsigned char, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned char, short> : public detail::PromoteType<unsigned char, short>
+{
+    typedef detail::PromoteType<unsigned char, short>::Promote Promote;
+    using detail::PromoteType<unsigned char, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned char, unsigned short> : public detail::PromoteType<unsigned char, unsigned short>
+{
+    typedef detail::PromoteType<unsigned char, unsigned short>::Promote Promote;
+    using detail::PromoteType<unsigned char, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned char, int> : public detail::PromoteType<unsigned char, int>
+{
+    typedef detail::PromoteType<unsigned char, int>::Promote Promote;
+    using detail::PromoteType<unsigned char, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned char, unsigned int> : public detail::PromoteType<unsigned char, unsigned int>
+{
+    typedef detail::PromoteType<unsigned char, unsigned int>::Promote Promote;
+    using detail::PromoteType<unsigned char, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned char, long> : public detail::PromoteType<unsigned char, long>
+{
+    typedef detail::PromoteType<unsigned char, long>::Promote Promote;
+    using detail::PromoteType<unsigned char, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned char, unsigned long> : public detail::PromoteType<unsigned char, unsigned long>
+{
+    typedef detail::PromoteType<unsigned char, unsigned long>::Promote Promote;
+    using detail::PromoteType<unsigned char, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned char, float> : public detail::PromoteType<unsigned char, float>
+{
+    typedef detail::PromoteType<unsigned char, float>::Promote Promote;
+    using detail::PromoteType<unsigned char, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned char, double> : public detail::PromoteType<unsigned char, double>
+{
+    typedef detail::PromoteType<unsigned char, double>::Promote Promote;
+    using detail::PromoteType<unsigned char, double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned char, long double> : public detail::PromoteType<unsigned char, long double>
+{
+    typedef detail::PromoteType<unsigned char, long double>::Promote Promote;
+    using detail::PromoteType<unsigned char, long double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned char, long long> : public detail::PromoteType<unsigned char, long long>
+{
+    typedef detail::PromoteType<unsigned char, long long>::Promote Promote;
+    using detail::PromoteType<unsigned char, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned char, unsigned long long> : public detail::PromoteType<unsigned char, unsigned long long>
+{
+    typedef detail::PromoteType<unsigned char, unsigned long long>::Promote Promote;
+    using detail::PromoteType<unsigned char, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+template <>
+struct PromoteTraits<short, short> : public detail::PromoteType<short, short>
+{
+    typedef detail::PromoteType<short, short>::Promote Promote;
+    using detail::PromoteType<short, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<short, bool> : public detail::PromoteType<short, bool>
+{
+    typedef detail::PromoteType<short, bool>::Promote Promote;
+    using detail::PromoteType<short, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<short, signed char> : public detail::PromoteType<short, signed char>
+{
+    typedef detail::PromoteType<short, signed char>::Promote Promote;
+    using detail::PromoteType<short, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<short, unsigned char> : public detail::PromoteType<short, unsigned char>
+{
+    typedef detail::PromoteType<short, unsigned char>::Promote Promote;
+    using detail::PromoteType<short, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<short, unsigned short> : public detail::PromoteType<short, unsigned short>
+{
+    typedef detail::PromoteType<short, unsigned short>::Promote Promote;
+    using detail::PromoteType<short, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<short, int> : public detail::PromoteType<short, int>
+{
+    typedef detail::PromoteType<short, int>::Promote Promote;
+    using detail::PromoteType<short, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<short, unsigned int> : public detail::PromoteType<short, unsigned int>
+{
+    typedef detail::PromoteType<short, unsigned int>::Promote Promote;
+    using detail::PromoteType<short, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<short, long> : public detail::PromoteType<short, long>
+{
+    typedef detail::PromoteType<short, long>::Promote Promote;
+    using detail::PromoteType<short, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<short, unsigned long> : public detail::PromoteType<short, unsigned long>
+{
+    typedef detail::PromoteType<short, unsigned long>::Promote Promote;
+    using detail::PromoteType<short, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<short, float> : public detail::PromoteType<short, float>
+{
+    typedef detail::PromoteType<short, float>::Promote Promote;
+    using detail::PromoteType<short, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<short, double> : public detail::PromoteType<short, double>
+{
+    typedef detail::PromoteType<short, double>::Promote Promote;
+    using detail::PromoteType<short, double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<short, long double> : public detail::PromoteType<short, long double>
+{
+    typedef detail::PromoteType<short, long double>::Promote Promote;
+    using detail::PromoteType<short, long double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<short, long long> : public detail::PromoteType<short, long long>
+{
+    typedef detail::PromoteType<short, long long>::Promote Promote;
+    using detail::PromoteType<short, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<short, unsigned long long> : public detail::PromoteType<short, unsigned long long>
+{
+    typedef detail::PromoteType<short, unsigned long long>::Promote Promote;
+    using detail::PromoteType<short, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+template <>
+struct PromoteTraits<unsigned short, unsigned short> : public detail::PromoteType<unsigned short, unsigned short>
+{
+    typedef detail::PromoteType<unsigned short, unsigned short>::Promote Promote;
+    using detail::PromoteType<unsigned short, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned short, bool> : public detail::PromoteType<unsigned short, bool>
+{
+    typedef detail::PromoteType<unsigned short, bool>::Promote Promote;
+    using detail::PromoteType<unsigned short, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned short, signed char> : public detail::PromoteType<unsigned short, signed char>
+{
+    typedef detail::PromoteType<unsigned short, signed char>::Promote Promote;
+    using detail::PromoteType<unsigned short, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned short, unsigned char> : public detail::PromoteType<unsigned short, unsigned char>
+{
+    typedef detail::PromoteType<unsigned short, unsigned char>::Promote Promote;
+    using detail::PromoteType<unsigned short, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned short, short> : public detail::PromoteType<unsigned short, short>
+{
+    typedef detail::PromoteType<unsigned short, short>::Promote Promote;
+    using detail::PromoteType<unsigned short, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned short, int> : public detail::PromoteType<unsigned short, int>
+{
+    typedef detail::PromoteType<unsigned short, int>::Promote Promote;
+    using detail::PromoteType<unsigned short, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned short, unsigned int> : public detail::PromoteType<unsigned short, unsigned int>
+{
+    typedef detail::PromoteType<unsigned short, unsigned int>::Promote Promote;
+    using detail::PromoteType<unsigned short, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned short, long> : public detail::PromoteType<unsigned short, long>
+{
+    typedef detail::PromoteType<unsigned short, long>::Promote Promote;
+    using detail::PromoteType<unsigned short, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned short, unsigned long> : public detail::PromoteType<unsigned short, unsigned long>
+{
+    typedef detail::PromoteType<unsigned short, unsigned long>::Promote Promote;
+    using detail::PromoteType<unsigned short, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned short, float> : public detail::PromoteType<unsigned short, float>
+{
+    typedef detail::PromoteType<unsigned short, float>::Promote Promote;
+    using detail::PromoteType<unsigned short, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned short, double> : public detail::PromoteType<unsigned short, double>
+{
+    typedef detail::PromoteType<unsigned short, double>::Promote Promote;
+    using detail::PromoteType<unsigned short, double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned short, long double> : public detail::PromoteType<unsigned short, long double>
+{
+    typedef detail::PromoteType<unsigned short, long double>::Promote Promote;
+    using detail::PromoteType<unsigned short, long double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned short, long long> : public detail::PromoteType<unsigned short, long long>
+{
+    typedef detail::PromoteType<unsigned short, long long>::Promote Promote;
+    using detail::PromoteType<unsigned short, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned short, unsigned long long> : public detail::PromoteType<unsigned short, unsigned long long>
+{
+    typedef detail::PromoteType<unsigned short, unsigned long long>::Promote Promote;
+    using detail::PromoteType<unsigned short, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+template <>
+struct PromoteTraits<int, int> : public detail::PromoteType<int, int>
+{
+    typedef detail::PromoteType<int, int>::Promote Promote;
+    using detail::PromoteType<int, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<int, bool> : public detail::PromoteType<int, bool>
+{
+    typedef detail::PromoteType<int, bool>::Promote Promote;
+    using detail::PromoteType<int, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<int, signed char> : public detail::PromoteType<int, signed char>
+{
+    typedef detail::PromoteType<int, signed char>::Promote Promote;
+    using detail::PromoteType<int, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<int, unsigned char> : public detail::PromoteType<int, unsigned char>
+{
+    typedef detail::PromoteType<int, unsigned char>::Promote Promote;
+    using detail::PromoteType<int, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<int, short> : public detail::PromoteType<int, short>
+{
+    typedef detail::PromoteType<int, short>::Promote Promote;
+    using detail::PromoteType<int, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<int, unsigned short> : public detail::PromoteType<int, unsigned short>
+{
+    typedef detail::PromoteType<int, unsigned short>::Promote Promote;
+    using detail::PromoteType<int, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<int, unsigned int> : public detail::PromoteType<int, unsigned int>
+{
+    typedef detail::PromoteType<int, unsigned int>::Promote Promote;
+    using detail::PromoteType<int, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<int, long> : public detail::PromoteType<int, long>
+{
+    typedef detail::PromoteType<int, long>::Promote Promote;
+    using detail::PromoteType<int, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<int, unsigned long> : public detail::PromoteType<int, unsigned long>
+{
+    typedef detail::PromoteType<int, unsigned long>::Promote Promote;
+    using detail::PromoteType<int, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<int, float> : public detail::PromoteType<int, float>
+{
+    typedef detail::PromoteType<int, float>::Promote Promote;
+    using detail::PromoteType<int, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<int, double> : public detail::PromoteType<int, double>
+{
+    typedef detail::PromoteType<int, double>::Promote Promote;
+    using detail::PromoteType<int, double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<int, long double> : public detail::PromoteType<int, long double>
+{
+    typedef detail::PromoteType<int, long double>::Promote Promote;
+    using detail::PromoteType<int, long double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<int, long long> : public detail::PromoteType<int, long long>
+{
+    typedef detail::PromoteType<int, long long>::Promote Promote;
+    using detail::PromoteType<int, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<int, unsigned long long> : public detail::PromoteType<int, unsigned long long>
+{
+    typedef detail::PromoteType<int, unsigned long long>::Promote Promote;
+    using detail::PromoteType<int, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+template <>
+struct PromoteTraits<unsigned int, unsigned int> : public detail::PromoteType<unsigned int, unsigned int>
+{
+    typedef detail::PromoteType<unsigned int, unsigned int>::Promote Promote;
+    using detail::PromoteType<unsigned int, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned int, bool> : public detail::PromoteType<unsigned int, bool>
+{
+    typedef detail::PromoteType<unsigned int, bool>::Promote Promote;
+    using detail::PromoteType<unsigned int, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned int, signed char> : public detail::PromoteType<unsigned int, signed char>
+{
+    typedef detail::PromoteType<unsigned int, signed char>::Promote Promote;
+    using detail::PromoteType<unsigned int, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned int, unsigned char> : public detail::PromoteType<unsigned int, unsigned char>
+{
+    typedef detail::PromoteType<unsigned int, unsigned char>::Promote Promote;
+    using detail::PromoteType<unsigned int, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned int, short> : public detail::PromoteType<unsigned int, short>
+{
+    typedef detail::PromoteType<unsigned int, short>::Promote Promote;
+    using detail::PromoteType<unsigned int, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned int, unsigned short> : public detail::PromoteType<unsigned int, unsigned short>
+{
+    typedef detail::PromoteType<unsigned int, unsigned short>::Promote Promote;
+    using detail::PromoteType<unsigned int, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned int, int> : public detail::PromoteType<unsigned int, int>
+{
+    typedef detail::PromoteType<unsigned int, int>::Promote Promote;
+    using detail::PromoteType<unsigned int, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned int, long> : public detail::PromoteType<unsigned int, long>
+{
+    typedef detail::PromoteType<unsigned int, long>::Promote Promote;
+    using detail::PromoteType<unsigned int, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned int, unsigned long> : public detail::PromoteType<unsigned int, unsigned long>
+{
+    typedef detail::PromoteType<unsigned int, unsigned long>::Promote Promote;
+    using detail::PromoteType<unsigned int, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned int, float> : public detail::PromoteType<unsigned int, float>
+{
+    typedef detail::PromoteType<unsigned int, float>::Promote Promote;
+    using detail::PromoteType<unsigned int, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned int, double> : public detail::PromoteType<unsigned int, double>
+{
+    typedef detail::PromoteType<unsigned int, double>::Promote Promote;
+    using detail::PromoteType<unsigned int, double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned int, long double> : public detail::PromoteType<unsigned int, long double>
+{
+    typedef detail::PromoteType<unsigned int, long double>::Promote Promote;
+    using detail::PromoteType<unsigned int, long double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned int, long long> : public detail::PromoteType<unsigned int, long long>
+{
+    typedef detail::PromoteType<unsigned int, long long>::Promote Promote;
+    using detail::PromoteType<unsigned int, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned int, unsigned long long> : public detail::PromoteType<unsigned int, unsigned long long>
+{
+    typedef detail::PromoteType<unsigned int, unsigned long long>::Promote Promote;
+    using detail::PromoteType<unsigned int, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+template <>
+struct PromoteTraits<long, long> : public detail::PromoteType<long, long>
+{
+    typedef detail::PromoteType<long, long>::Promote Promote;
+    using detail::PromoteType<long, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long, bool> : public detail::PromoteType<long, bool>
+{
+    typedef detail::PromoteType<long, bool>::Promote Promote;
+    using detail::PromoteType<long, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long, signed char> : public detail::PromoteType<long, signed char>
+{
+    typedef detail::PromoteType<long, signed char>::Promote Promote;
+    using detail::PromoteType<long, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long, unsigned char> : public detail::PromoteType<long, unsigned char>
+{
+    typedef detail::PromoteType<long, unsigned char>::Promote Promote;
+    using detail::PromoteType<long, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long, short> : public detail::PromoteType<long, short>
+{
+    typedef detail::PromoteType<long, short>::Promote Promote;
+    using detail::PromoteType<long, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long, unsigned short> : public detail::PromoteType<long, unsigned short>
+{
+    typedef detail::PromoteType<long, unsigned short>::Promote Promote;
+    using detail::PromoteType<long, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long, int> : public detail::PromoteType<long, int>
+{
+    typedef detail::PromoteType<long, int>::Promote Promote;
+    using detail::PromoteType<long, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long, unsigned int> : public detail::PromoteType<long, unsigned int>
+{
+    typedef detail::PromoteType<long, unsigned int>::Promote Promote;
+    using detail::PromoteType<long, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long, unsigned long> : public detail::PromoteType<long, unsigned long>
+{
+    typedef detail::PromoteType<long, unsigned long>::Promote Promote;
+    using detail::PromoteType<long, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long, float> : public detail::PromoteType<long, float>
+{
+    typedef detail::PromoteType<long, float>::Promote Promote;
+    using detail::PromoteType<long, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long, double> : public detail::PromoteType<long, double>
+{
+    typedef detail::PromoteType<long, double>::Promote Promote;
+    using detail::PromoteType<long, double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long, long double> : public detail::PromoteType<long, long double>
+{
+    typedef detail::PromoteType<long, long double>::Promote Promote;
+    using detail::PromoteType<long, long double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long, long long> : public detail::PromoteType<long, long long>
+{
+    typedef detail::PromoteType<long, long long>::Promote Promote;
+    using detail::PromoteType<long, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long, unsigned long long> : public detail::PromoteType<long, unsigned long long>
+{
+    typedef detail::PromoteType<long, unsigned long long>::Promote Promote;
+    using detail::PromoteType<long, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+template <>
+struct PromoteTraits<unsigned long, unsigned long> : public detail::PromoteType<unsigned long, unsigned long>
+{
+    typedef detail::PromoteType<unsigned long, unsigned long>::Promote Promote;
+    using detail::PromoteType<unsigned long, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned long, bool> : public detail::PromoteType<unsigned long, bool>
+{
+    typedef detail::PromoteType<unsigned long, bool>::Promote Promote;
+    using detail::PromoteType<unsigned long, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned long, signed char> : public detail::PromoteType<unsigned long, signed char>
+{
+    typedef detail::PromoteType<unsigned long, signed char>::Promote Promote;
+    using detail::PromoteType<unsigned long, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned long, unsigned char> : public detail::PromoteType<unsigned long, unsigned char>
+{
+    typedef detail::PromoteType<unsigned long, unsigned char>::Promote Promote;
+    using detail::PromoteType<unsigned long, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned long, short> : public detail::PromoteType<unsigned long, short>
+{
+    typedef detail::PromoteType<unsigned long, short>::Promote Promote;
+    using detail::PromoteType<unsigned long, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned long, unsigned short> : public detail::PromoteType<unsigned long, unsigned short>
+{
+    typedef detail::PromoteType<unsigned long, unsigned short>::Promote Promote;
+    using detail::PromoteType<unsigned long, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned long, int> : public detail::PromoteType<unsigned long, int>
+{
+    typedef detail::PromoteType<unsigned long, int>::Promote Promote;
+    using detail::PromoteType<unsigned long, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned long, unsigned int> : public detail::PromoteType<unsigned long, unsigned int>
+{
+    typedef detail::PromoteType<unsigned long, unsigned int>::Promote Promote;
+    using detail::PromoteType<unsigned long, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned long, long> : public detail::PromoteType<unsigned long, long>
+{
+    typedef detail::PromoteType<unsigned long, long>::Promote Promote;
+    using detail::PromoteType<unsigned long, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned long, float> : public detail::PromoteType<unsigned long, float>
+{
+    typedef detail::PromoteType<unsigned long, float>::Promote Promote;
+    using detail::PromoteType<unsigned long, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned long, double> : public detail::PromoteType<unsigned long, double>
+{
+    typedef detail::PromoteType<unsigned long, double>::Promote Promote;
+    using detail::PromoteType<unsigned long, double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<unsigned long, long double> : public detail::PromoteType<unsigned long, long double>
+{
+    typedef detail::PromoteType<unsigned long, long double>::Promote Promote;
+    using detail::PromoteType<unsigned long, long double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long, long long> : public detail::PromoteType<unsigned long, long long>
+{
+    typedef detail::PromoteType<unsigned long, long long>::Promote Promote;
+    using detail::PromoteType<unsigned long, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long, unsigned long long> : public detail::PromoteType<unsigned long, unsigned long long>
+{
+    typedef detail::PromoteType<unsigned long, unsigned long long>::Promote Promote;
+    using detail::PromoteType<unsigned long, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+template <>
+struct PromoteTraits<float, float> : public detail::PromoteType<float, float>
+{
+    typedef detail::PromoteType<float, float>::Promote Promote;
+    using detail::PromoteType<float, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<float, bool> : public detail::PromoteType<float, bool>
+{
+    typedef detail::PromoteType<float, bool>::Promote Promote;
+    using detail::PromoteType<float, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<float, signed char> : public detail::PromoteType<float, signed char>
+{
+    typedef detail::PromoteType<float, signed char>::Promote Promote;
+    using detail::PromoteType<float, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<float, unsigned char> : public detail::PromoteType<float, unsigned char>
+{
+    typedef detail::PromoteType<float, unsigned char>::Promote Promote;
+    using detail::PromoteType<float, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<float, short> : public detail::PromoteType<float, short>
+{
+    typedef detail::PromoteType<float, short>::Promote Promote;
+    using detail::PromoteType<float, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<float, unsigned short> : public detail::PromoteType<float, unsigned short>
+{
+    typedef detail::PromoteType<float, unsigned short>::Promote Promote;
+    using detail::PromoteType<float, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<float, int> : public detail::PromoteType<float, int>
+{
+    typedef detail::PromoteType<float, int>::Promote Promote;
+    using detail::PromoteType<float, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<float, unsigned int> : public detail::PromoteType<float, unsigned int>
+{
+    typedef detail::PromoteType<float, unsigned int>::Promote Promote;
+    using detail::PromoteType<float, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<float, long> : public detail::PromoteType<float, long>
+{
+    typedef detail::PromoteType<float, long>::Promote Promote;
+    using detail::PromoteType<float, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<float, unsigned long> : public detail::PromoteType<float, unsigned long>
+{
+    typedef detail::PromoteType<float, unsigned long>::Promote Promote;
+    using detail::PromoteType<float, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<float, double> : public detail::PromoteType<float, double>
+{
+    typedef detail::PromoteType<float, double>::Promote Promote;
+    using detail::PromoteType<float, double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<float, long double> : public detail::PromoteType<float, long double>
+{
+    typedef detail::PromoteType<float, long double>::Promote Promote;
+    using detail::PromoteType<float, long double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<float, long long> : public detail::PromoteType<float, long long>
+{
+    typedef detail::PromoteType<float, long long>::Promote Promote;
+    using detail::PromoteType<float, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<float, unsigned long long> : public detail::PromoteType<float, unsigned long long>
+{
+    typedef detail::PromoteType<float, unsigned long long>::Promote Promote;
+    using detail::PromoteType<float, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+template <>
+struct PromoteTraits<double, double> : public detail::PromoteType<double, double>
+{
+    typedef detail::PromoteType<double, double>::Promote Promote;
+    using detail::PromoteType<double, double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<double, bool> : public detail::PromoteType<double, bool>
+{
+    typedef detail::PromoteType<double, bool>::Promote Promote;
+    using detail::PromoteType<double, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<double, signed char> : public detail::PromoteType<double, signed char>
+{
+    typedef detail::PromoteType<double, signed char>::Promote Promote;
+    using detail::PromoteType<double, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<double, unsigned char> : public detail::PromoteType<double, unsigned char>
+{
+    typedef detail::PromoteType<double, unsigned char>::Promote Promote;
+    using detail::PromoteType<double, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<double, short> : public detail::PromoteType<double, short>
+{
+    typedef detail::PromoteType<double, short>::Promote Promote;
+    using detail::PromoteType<double, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<double, unsigned short> : public detail::PromoteType<double, unsigned short>
+{
+    typedef detail::PromoteType<double, unsigned short>::Promote Promote;
+    using detail::PromoteType<double, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<double, int> : public detail::PromoteType<double, int>
+{
+    typedef detail::PromoteType<double, int>::Promote Promote;
+    using detail::PromoteType<double, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<double, unsigned int> : public detail::PromoteType<double, unsigned int>
+{
+    typedef detail::PromoteType<double, unsigned int>::Promote Promote;
+    using detail::PromoteType<double, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<double, long> : public detail::PromoteType<double, long>
+{
+    typedef detail::PromoteType<double, long>::Promote Promote;
+    using detail::PromoteType<double, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<double, unsigned long> : public detail::PromoteType<double, unsigned long>
+{
+    typedef detail::PromoteType<double, unsigned long>::Promote Promote;
+    using detail::PromoteType<double, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<double, float> : public detail::PromoteType<double, float>
+{
+    typedef detail::PromoteType<double, float>::Promote Promote;
+    using detail::PromoteType<double, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<double, long double> : public detail::PromoteType<double, long double>
+{
+    typedef detail::PromoteType<double, long double>::Promote Promote;
+    using detail::PromoteType<double, long double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<double, long long> : public detail::PromoteType<double, long long>
+{
+    typedef detail::PromoteType<double, long long>::Promote Promote;
+    using detail::PromoteType<double, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<double, unsigned long long> : public detail::PromoteType<double, unsigned long long>
+{
+    typedef detail::PromoteType<double, unsigned long long>::Promote Promote;
+    using detail::PromoteType<double, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+template <>
+struct PromoteTraits<long double, long double> : public detail::PromoteType<long double, long double>
+{
+    typedef detail::PromoteType<long double, long double>::Promote Promote;
+    using detail::PromoteType<long double, long double>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long double, bool> : public detail::PromoteType<long double, bool>
+{
+    typedef detail::PromoteType<long double, bool>::Promote Promote;
+    using detail::PromoteType<long double, bool>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long double, signed char> : public detail::PromoteType<long double, signed char>
+{
+    typedef detail::PromoteType<long double, signed char>::Promote Promote;
+    using detail::PromoteType<long double, signed char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long double, unsigned char> : public detail::PromoteType<long double, unsigned char>
+{
+    typedef detail::PromoteType<long double, unsigned char>::Promote Promote;
+    using detail::PromoteType<long double, unsigned char>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long double, short> : public detail::PromoteType<long double, short>
+{
+    typedef detail::PromoteType<long double, short>::Promote Promote;
+    using detail::PromoteType<long double, short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long double, unsigned short> : public detail::PromoteType<long double, unsigned short>
+{
+    typedef detail::PromoteType<long double, unsigned short>::Promote Promote;
+    using detail::PromoteType<long double, unsigned short>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long double, int> : public detail::PromoteType<long double, int>
+{
+    typedef detail::PromoteType<long double, int>::Promote Promote;
+    using detail::PromoteType<long double, int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long double, unsigned int> : public detail::PromoteType<long double, unsigned int>
+{
+    typedef detail::PromoteType<long double, unsigned int>::Promote Promote;
+    using detail::PromoteType<long double, unsigned int>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long double, long> : public detail::PromoteType<long double, long>
+{
+    typedef detail::PromoteType<long double, long>::Promote Promote;
+    using detail::PromoteType<long double, long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long double, unsigned long> : public detail::PromoteType<long double, unsigned long>
+{
+    typedef detail::PromoteType<long double, unsigned long>::Promote Promote;
+    using detail::PromoteType<long double, unsigned long>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long double, float> : public detail::PromoteType<long double, float>
+{
+    typedef detail::PromoteType<long double, float>::Promote Promote;
+    using detail::PromoteType<long double, float>::toPromote;
+};
+
+template <>
+struct PromoteTraits<long double, double> : public detail::PromoteType<long double, double>
+{
+    typedef detail::PromoteType<long double, double>::Promote Promote;
+    using detail::PromoteType<long double, double>::toPromote;
+};
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long double, long long> : public detail::PromoteType<long double, long long>
+{
+    typedef detail::PromoteType<long double, long long>::Promote Promote;
+    using detail::PromoteType<long double, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long double, unsigned long long> : public detail::PromoteType<long double, unsigned long long>
+{
+    typedef detail::PromoteType<long double, unsigned long long>::Promote Promote;
+    using detail::PromoteType<long double, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, long long> : public detail::PromoteType<long long, long long>
+{
+    typedef detail::PromoteType<long long, long long>::Promote Promote;
+    using detail::PromoteType<long long, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, bool> : public detail::PromoteType<long long, bool>
+{
+    typedef detail::PromoteType<long long, bool>::Promote Promote;
+    using detail::PromoteType<long long, bool>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, signed char> : public detail::PromoteType<long long, signed char>
+{
+    typedef detail::PromoteType<long long, signed char>::Promote Promote;
+    using detail::PromoteType<long long, signed char>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, unsigned char> : public detail::PromoteType<long long, unsigned char>
+{
+    typedef detail::PromoteType<long long, unsigned char>::Promote Promote;
+    using detail::PromoteType<long long, unsigned char>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, short> : public detail::PromoteType<long long, short>
+{
+    typedef detail::PromoteType<long long, short>::Promote Promote;
+    using detail::PromoteType<long long, short>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, unsigned short> : public detail::PromoteType<long long, unsigned short>
+{
+    typedef detail::PromoteType<long long, unsigned short>::Promote Promote;
+    using detail::PromoteType<long long, unsigned short>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, int> : public detail::PromoteType<long long, int>
+{
+    typedef detail::PromoteType<long long, int>::Promote Promote;
+    using detail::PromoteType<long long, int>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, unsigned int> : public detail::PromoteType<long long, unsigned int>
+{
+    typedef detail::PromoteType<long long, unsigned int>::Promote Promote;
+    using detail::PromoteType<long long, unsigned int>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, long> : public detail::PromoteType<long long, long>
+{
+    typedef detail::PromoteType<long long, long>::Promote Promote;
+    using detail::PromoteType<long long, long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, unsigned long> : public detail::PromoteType<long long, unsigned long>
+{
+    typedef detail::PromoteType<long long, unsigned long>::Promote Promote;
+    using detail::PromoteType<long long, unsigned long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, float> : public detail::PromoteType<long long, float>
+{
+    typedef detail::PromoteType<long long, float>::Promote Promote;
+    using detail::PromoteType<long long, float>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, double> : public detail::PromoteType<long long, double>
+{
+    typedef detail::PromoteType<long long, double>::Promote Promote;
+    using detail::PromoteType<long long, double>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, long double> : public detail::PromoteType<long long, long double>
+{
+    typedef detail::PromoteType<long long, long double>::Promote Promote;
+    using detail::PromoteType<long long, long double>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<long long, unsigned long long> : public detail::PromoteType<long long, unsigned long long>
+{
+    typedef detail::PromoteType<long long, unsigned long long>::Promote Promote;
+    using detail::PromoteType<long long, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, unsigned long long> : public detail::PromoteType<unsigned long long, unsigned long long>
+{
+    typedef detail::PromoteType<unsigned long long, unsigned long long>::Promote Promote;
+    using detail::PromoteType<unsigned long long, unsigned long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, bool> : public detail::PromoteType<unsigned long long, bool>
+{
+    typedef detail::PromoteType<unsigned long long, bool>::Promote Promote;
+    using detail::PromoteType<unsigned long long, bool>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, signed char> : public detail::PromoteType<unsigned long long, signed char>
+{
+    typedef detail::PromoteType<unsigned long long, signed char>::Promote Promote;
+    using detail::PromoteType<unsigned long long, signed char>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, unsigned char> : public detail::PromoteType<unsigned long long, unsigned char>
+{
+    typedef detail::PromoteType<unsigned long long, unsigned char>::Promote Promote;
+    using detail::PromoteType<unsigned long long, unsigned char>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, short> : public detail::PromoteType<unsigned long long, short>
+{
+    typedef detail::PromoteType<unsigned long long, short>::Promote Promote;
+    using detail::PromoteType<unsigned long long, short>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, unsigned short> : public detail::PromoteType<unsigned long long, unsigned short>
+{
+    typedef detail::PromoteType<unsigned long long, unsigned short>::Promote Promote;
+    using detail::PromoteType<unsigned long long, unsigned short>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, int> : public detail::PromoteType<unsigned long long, int>
+{
+    typedef detail::PromoteType<unsigned long long, int>::Promote Promote;
+    using detail::PromoteType<unsigned long long, int>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, unsigned int> : public detail::PromoteType<unsigned long long, unsigned int>
+{
+    typedef detail::PromoteType<unsigned long long, unsigned int>::Promote Promote;
+    using detail::PromoteType<unsigned long long, unsigned int>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, long> : public detail::PromoteType<unsigned long long, long>
+{
+    typedef detail::PromoteType<unsigned long long, long>::Promote Promote;
+    using detail::PromoteType<unsigned long long, long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, unsigned long> : public detail::PromoteType<unsigned long long, unsigned long>
+{
+    typedef detail::PromoteType<unsigned long long, unsigned long>::Promote Promote;
+    using detail::PromoteType<unsigned long long, unsigned long>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, float> : public detail::PromoteType<unsigned long long, float>
+{
+    typedef detail::PromoteType<unsigned long long, float>::Promote Promote;
+    using detail::PromoteType<unsigned long long, float>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, double> : public detail::PromoteType<unsigned long long, double>
+{
+    typedef detail::PromoteType<unsigned long long, double>::Promote Promote;
+    using detail::PromoteType<unsigned long long, double>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, long double> : public detail::PromoteType<unsigned long long, long double>
+{
+    typedef detail::PromoteType<unsigned long long, long double>::Promote Promote;
+    using detail::PromoteType<unsigned long long, long double>::toPromote;
+};
+#endif // LLONG_MAX
+
+#ifdef LLONG_MAX
+template <>
+struct PromoteTraits<unsigned long long, long long> : public detail::PromoteType<unsigned long long, long long>
+{
+    typedef detail::PromoteType<unsigned long long, long long>::Promote Promote;
+    using detail::PromoteType<unsigned long long, long long>::toPromote;
+};
+#endif // LLONG_MAX
+
+
+
+#endif // VIGRA_PROMOTETRAITS_HXX
diff --git a/include/vigra/promote_traits.hxx.py b/include/vigra/promote_traits.hxx.py
new file mode 100644
index 0000000..e6b4408
--- /dev/null
+++ b/include/vigra/promote_traits.hxx.py
@@ -0,0 +1,74 @@
+t = ['bool', 'signed char', 'unsigned char', 'short', 'unsigned short', 
+     'int', 'unsigned int', 'long', 'unsigned long', 'float', 'double', 
+     'long double', 'long long', 'unsigned long long']
+
+pt = '''template <>
+struct PromoteTraits<%(A)s, %(B)s> : public detail::PromoteType<%(A)s, %(B)s>
+{
+    typedef detail::PromoteType<%(A)s, %(B)s>::Promote Promote;
+    using detail::PromoteType<%(A)s, %(B)s>::toPromote;
+};
+'''
+
+def ifdefAround(k, l, s):
+    if (k in ['long long', 'unsigned long long']) or (l in ['long long', 'unsigned long long']):
+        return '#ifdef LLONG_MAX\n'+s+'#endif // LLONG_MAX\n\n'
+    else:
+        return s + '\n'   
+
+s = '''/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2008 by Ullrich Koethe                  */
+/*       Cognitive Systems Group, University of Hamburg, Germany        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_PROMOTETRAITS_HXX
+#define VIGRA_PROMOTETRAITS_HXX
+
+// this file was autogenerated from promote_traits.hxx.py - DO NOT EDIT
+
+'''
+for k in t:
+    s += ifdefAround(k, k, pt % { 'A': k, 'B': k})
+    for l in t:
+        if l == k: continue
+        s += ifdefAround(k, l, pt % { 'A': k, 'B': l})
+
+s += '''
+
+#endif // VIGRA_PROMOTETRAITS_HXX
+'''
+open('promote_traits.hxx', 'w').write(s)
+
+        
diff --git a/include/vigra/python_utility.hxx b/include/vigra/python_utility.hxx
new file mode 100644
index 0000000..8222901
--- /dev/null
+++ b/include/vigra/python_utility.hxx
@@ -0,0 +1,415 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2009 by Ullrich Koethe and Hans Meine                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_PYTHON_UTILITY_HXX
+#define VIGRA_PYTHON_UTILITY_HXX
+
+#include <Python.h>
+#include <algorithm>
+#include <string>
+#include "vigra/error.hxx"
+#include "vigra/tinyvector.hxx"
+
+namespace vigra {
+
+template <class PYOBJECT_PTR>
+void pythonToCppException(PYOBJECT_PTR obj)
+{
+    if(obj != 0)
+        return;
+    PyObject * type, * value, * trace;
+    PyErr_Fetch(&type, &value, &trace);
+    if(type == 0)
+        return;
+    std::string message(((PyTypeObject *)type)->tp_name);
+    if(PyString_Check(value))
+    {
+        message += std::string(": ") + PyString_AS_STRING(value);
+    }
+
+    Py_XDECREF(type);
+    Py_XDECREF(value);
+    Py_XDECREF(trace);
+    throw std::runtime_error(message.c_str());
+}
+
+/********************************************************/
+/*                                                      */
+/*                       python_ptr                     */
+/*                                                      */
+/********************************************************/
+
+class python_ptr
+{
+  private:
+    PyObject * ptr_;
+
+  public:
+
+    typedef PyObject element_type;
+    typedef PyObject value_type;
+    typedef PyObject * pointer;
+    typedef PyObject & reference;
+
+    enum refcount_policy { increment_count, borrowed_reference = increment_count,
+                           keep_count, new_reference = keep_count };
+
+    explicit python_ptr(pointer p = 0, refcount_policy rp = increment_count)
+    : ptr_( p )
+    {
+        if(rp == increment_count)
+        {
+            Py_XINCREF(ptr_);
+        }
+    }
+
+    python_ptr(python_ptr const & p)
+    : ptr_(p.ptr_)
+    {
+        Py_XINCREF(ptr_);
+    }
+
+    python_ptr & operator=(pointer p)
+    {
+        reset(p);
+        return *this;
+    }
+
+    python_ptr & operator=(python_ptr const & r)
+    {
+        reset(r.ptr_);
+        return *this;
+    }
+
+    ~python_ptr()
+    {
+        reset();
+    }
+
+    void reset(pointer p = 0, refcount_policy rp = increment_count)
+    {
+        if(p == ptr_)
+            return;
+        if(rp == increment_count)
+        {
+            Py_XINCREF(p);
+        }
+        Py_XDECREF(ptr_);
+        ptr_ = p;
+    }
+
+    pointer release(bool return_borrowed_reference = false)
+    {
+        pointer p = ptr_;
+        ptr_ = 0;
+        if(return_borrowed_reference)
+        {
+            Py_XDECREF(p);
+        }
+        return p;
+    }
+
+    reference operator* () const
+    {
+        vigra_precondition(ptr_ != 0, "python_ptr::operator*(): Cannot dereference NULL pointer.");
+        return *ptr_;
+    }
+
+    pointer operator-> () const
+    {
+        vigra_precondition(ptr_ != 0, "python_ptr::operator->(): Cannot dereference NULL pointer.");
+        return ptr_;
+    }
+
+    pointer ptr() const
+    {
+        return ptr_;
+    }
+
+    pointer get() const
+    {
+        return ptr_;
+    }
+
+    operator pointer() const
+    {
+        return ptr_;
+    }
+
+    bool operator! () const
+    {
+        return ptr_ == 0;
+    }
+
+    bool unique() const
+    {
+        return ptr_ && ptr_->ob_refcnt == 1;
+    }
+
+    void swap(python_ptr & other)
+    {
+        std::swap(ptr_, other.ptr_);
+    }
+
+    bool operator==(python_ptr const & p) const
+    {
+        return ptr_ == p.ptr_;
+    }
+
+    bool operator==(pointer p) const
+    {
+        return ptr_ == p;
+    }
+
+    bool operator!=(python_ptr const & p) const
+    {
+        return ptr_ != p.ptr_;
+    }
+
+    bool operator!=(pointer p) const
+    {
+        return ptr_ != p;
+    }
+};
+
+inline void swap(python_ptr & a, python_ptr & b)
+{
+    a.swap(b);
+}
+
+/****************************************************************/
+
+inline python_ptr 
+makePythonDictionary(char const * k1 = 0, PyObject * a1 = 0,
+                    char const * k2 = 0, PyObject * a2 = 0,
+                    char const * k3 = 0, PyObject * a3 = 0)
+{
+    python_ptr dict(PyDict_New(), python_ptr::keep_count);
+    pythonToCppException(dict);
+    if(k1 && a1)
+        PyDict_SetItemString(dict, k1, a1);
+    if(k2 && a2)
+        PyDict_SetItemString(dict, k2, a2);
+    if(k3 && a3)
+        PyDict_SetItemString(dict, k3, a3);
+    return dict;
+}
+
+/****************************************************************/
+
+inline python_ptr pythonFromData(bool t)
+{
+    python_ptr res(PyBool_FromLong(t ? 1 : 0), python_ptr::keep_count);
+    pythonToCppException(res);
+    return res;
+}
+
+inline python_ptr pythonFromData(std::string const & s)
+{
+    python_ptr res(PyString_FromString(s.c_str()), python_ptr::keep_count);
+    pythonToCppException(res);
+    return res;
+}
+
+inline python_ptr pythonFromData(long long t)
+{
+    python_ptr res;
+    if(t > (long long)NumericTraits<long>::max() || t < (long long)NumericTraits<long>::min())
+        res = python_ptr(PyLong_FromLongLong(t), python_ptr::keep_count);
+    else
+        res = python_ptr(PyInt_FromLong((long)t), python_ptr::keep_count);
+    pythonToCppException(res);
+    return res;
+}
+
+inline python_ptr pythonFromData(unsigned long long t)
+{
+    python_ptr res;
+    if(t > (unsigned long long)NumericTraits<long>::max())
+        res = python_ptr(PyLong_FromUnsignedLongLong(t), python_ptr::keep_count);
+    else
+        res = python_ptr(PyInt_FromLong((long)t), python_ptr::keep_count);
+    pythonToCppException(res);
+    return res;
+}
+
+#define VIGRA_PYTHON_FROM_DATA(type, fct, cast_type) \
+inline python_ptr pythonFromData(type t) \
+{ \
+    python_ptr res(fct((cast_type)t), python_ptr::keep_count); \
+    pythonToCppException(res); \
+    return res; \
+}
+
+VIGRA_PYTHON_FROM_DATA(signed char, PyInt_FromLong, long)
+VIGRA_PYTHON_FROM_DATA(unsigned char, PyInt_FromLong, long)
+VIGRA_PYTHON_FROM_DATA(short, PyInt_FromLong, long)
+VIGRA_PYTHON_FROM_DATA(unsigned short, PyInt_FromLong, long)
+VIGRA_PYTHON_FROM_DATA(long, PyInt_FromLong, long)
+VIGRA_PYTHON_FROM_DATA(unsigned long, PyInt_FromSize_t, size_t)
+VIGRA_PYTHON_FROM_DATA(int, PyInt_FromSsize_t, Py_ssize_t)
+VIGRA_PYTHON_FROM_DATA(unsigned int, PyInt_FromSize_t, size_t)
+VIGRA_PYTHON_FROM_DATA(float, PyFloat_FromDouble, double)
+VIGRA_PYTHON_FROM_DATA(double, PyFloat_FromDouble, double)
+VIGRA_PYTHON_FROM_DATA(char const *, PyString_FromString, char const *)
+
+#undef VIGRA_PYTHON_FROM_DATA
+
+/****************************************************************/
+
+#define VIGRA_DATA_FROM_PYTHON(type, check, extract) \
+inline type dataFromPython(PyObject * data, type const & defaultVal) \
+{ \
+    return data && check(data) \
+             ? (type)extract(data) \
+             : defaultVal; \
+}
+
+VIGRA_DATA_FROM_PYTHON(signed char, PyInt_Check, PyInt_AsLong)
+VIGRA_DATA_FROM_PYTHON(unsigned char, PyInt_Check, PyInt_AsLong)
+VIGRA_DATA_FROM_PYTHON(short, PyInt_Check, PyInt_AsLong)
+VIGRA_DATA_FROM_PYTHON(unsigned short, PyInt_Check, PyInt_AsLong)
+VIGRA_DATA_FROM_PYTHON(long, PyInt_Check, PyInt_AsLong)
+VIGRA_DATA_FROM_PYTHON(unsigned long, PyInt_Check, PyInt_AsUnsignedLongMask)
+VIGRA_DATA_FROM_PYTHON(int, PyInt_Check, PyInt_AsLong)
+VIGRA_DATA_FROM_PYTHON(unsigned int, PyInt_Check, PyInt_AsUnsignedLongMask)
+VIGRA_DATA_FROM_PYTHON(long long, PyInt_Check, PyInt_AsSsize_t)
+VIGRA_DATA_FROM_PYTHON(unsigned long long, PyInt_Check, PyInt_AsUnsignedLongLongMask)
+VIGRA_DATA_FROM_PYTHON(float, PyFloat_Check, PyFloat_AsDouble)
+VIGRA_DATA_FROM_PYTHON(double, PyFloat_Check, PyFloat_AsDouble)
+
+inline std::string dataFromPython(PyObject * data, const char * defaultVal) 
+{ 
+    return data && PyString_Check(data) 
+             ? std::string(PyString_AsString(data)) 
+             : std::string(defaultVal); 
+}
+
+inline std::string dataFromPython(PyObject * data, std::string const & defaultVal) 
+{ 
+    return data && PyString_Check(data) 
+             ? std::string(PyString_AsString(data)) 
+             : defaultVal; 
+}
+
+inline python_ptr dataFromPython(PyObject * data, python_ptr defaultVal) 
+{ 
+    return data
+             ? python_ptr(data) 
+             : defaultVal; 
+}
+
+#undef VIGRA_DATA_FROM_PYTHON
+
+/****************************************************************/
+
+template <class T>
+T pythonGetAttr(PyObject * obj, const char * key, T defaultValue)
+{
+    if(!obj)
+        return defaultValue;
+        
+    python_ptr k(PyString_FromString(key), python_ptr::keep_count);
+    pythonToCppException(k);
+    python_ptr pres(PyObject_GetAttr(obj, k), python_ptr::keep_count);
+    if(!pres)
+        PyErr_Clear();
+    return dataFromPython(pres, defaultValue);
+}
+
+inline std::string 
+pythonGetAttr(PyObject * obj, const char * key, const char * defaultValue)
+{
+    if(!obj)
+        return std::string(defaultValue);
+        
+    python_ptr k(PyString_FromString(key), python_ptr::keep_count);
+    pythonToCppException(k);
+    python_ptr pres(PyObject_GetAttr(obj, k), python_ptr::keep_count);
+    if(!pres)
+        PyErr_Clear();
+    return dataFromPython(pres, defaultValue);
+}
+
+/****************************************************************/
+
+template <class T, int N>
+python_ptr shapeToPythonTuple(TinyVector<T, N> const & shape)
+{
+    python_ptr tuple(PyTuple_New(N), python_ptr::keep_count);
+    pythonToCppException(tuple);
+    for(unsigned int k=0; k<N; ++k)
+    {
+        PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromData(shape[k]).release());
+    }
+    return tuple;
+}
+
+template <class T>
+python_ptr shapeToPythonTuple(ArrayVectorView<T> const & shape)
+{
+    python_ptr tuple(PyTuple_New(shape.size()), python_ptr::keep_count);
+    pythonToCppException(tuple);
+    for(unsigned int k=0; k<shape.size(); ++k)
+    {
+        PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromData(shape[k]).release());
+    }
+    return tuple;
+}
+
+/****************************************************************/
+
+class PyAllowThreads
+{
+    PyThreadState * save_;
+    
+    // make it non-copyable
+    PyAllowThreads(PyAllowThreads const &);
+    PyAllowThreads & operator=(PyAllowThreads const &);
+  
+  public:
+    PyAllowThreads()
+    : save_(PyEval_SaveThread())
+    {}
+    
+    ~PyAllowThreads()
+    {
+        PyEval_RestoreThread(save_);
+    }
+};
+
+} // namespace vigra
+
+#endif  // VIGRA_PYTHON_UTILITY_HXX
diff --git a/include/vigra/quadprog.hxx b/include/vigra/quadprog.hxx
new file mode 100644
index 0000000..59ad27e
--- /dev/null
+++ b/include/vigra/quadprog.hxx
@@ -0,0 +1,354 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 2008 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR activeSet PARTICULAR PURPOSE AND  */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_QUADPROG_HXX
+#define VIGRA_QUADPROG_HXX
+
+#include <limits>
+#include "mathutil.hxx"
+#include "matrix.hxx"
+#include "linear_solve.hxx"
+#include "numerictraits.hxx"
+#include "array_vector.hxx"
+
+namespace vigra {
+
+namespace detail {
+
+template <class T, class C1, class C2, class C3>
+bool quadprogAddConstraint(MultiArrayView<2, T, C1> & R, MultiArrayView<2, T, C2> & J, MultiArrayView<2, T, C3> & d, 
+                           int activeConstraintCount, double& R_norm)
+{
+    typedef typename MultiArrayShape<2>::type Shape;
+    int n=columnCount(J);
+    linalg::detail::qrGivensStepImpl(0, subVector(d, activeConstraintCount, n),
+                                     J.subarray(Shape(activeConstraintCount,0), Shape(n,n)));
+    if (abs(d(activeConstraintCount,0)) <= NumericTraits<T>::epsilon() * R_norm) // problem degenerate
+        return false;
+    R_norm = std::max<T>(R_norm, abs(d(activeConstraintCount,0)));
+
+    ++activeConstraintCount;   
+    // add d as a new column to R
+    columnVector(R, Shape(0, activeConstraintCount - 1), activeConstraintCount) = subVector(d, 0, activeConstraintCount);  
+    return true;
+}
+
+template <class T, class C1, class C2, class C3>
+void quadprogDeleteConstraint(MultiArrayView<2, T, C1> & R, MultiArrayView<2, T, C2> & J, MultiArrayView<2, T, C3> & u, 
+                              int activeConstraintCount,  int constraintToBeRemoved)
+{
+    typedef typename MultiArrayShape<2>::type Shape;
+    
+    int newActiveConstraintCount = activeConstraintCount - 1;
+
+    if(constraintToBeRemoved == newActiveConstraintCount)
+        return;
+
+    std::swap(u(constraintToBeRemoved,0), u(newActiveConstraintCount,0));
+    columnVector(R, constraintToBeRemoved).swapData(columnVector(R, newActiveConstraintCount));
+    linalg::detail::qrGivensStepImpl(0, R.subarray(Shape(constraintToBeRemoved, constraintToBeRemoved), 
+                                                   Shape(newActiveConstraintCount,newActiveConstraintCount)),
+                                        J.subarray(Shape(constraintToBeRemoved, 0), 
+                                                   Shape(newActiveConstraintCount,newActiveConstraintCount)));
+}
+
+} // namespace detail
+
+/** \addtogroup Optimization Optimization and Regression
+ */
+//@{
+   /** Solve Quadratic Programming Problem.
+
+     The quadraticProgramming() function implements the algorithm described in
+     
+     D. Goldfarb, A. Idnani: <i>"A numerically stable dual method for solving
+                 strictly convex quadratic programs"</i>, Mathematical Programming 27:1-33, 1983. 
+     
+     for the solution of (convex) quadratic programming problems by means of a primal-dual method.
+         
+     <b>\#include</b> \<vigra/quadprog.hxx\> <br/>
+     Namespaces: vigra
+
+     <b>Declaration:</b>
+
+     \code
+     namespace vigra { 
+         template <class T, class C1, class C2, class C3, class C4, class C5, class C6, class C7>
+         T 
+         quadraticProgramming(MultiArrayView<2, T, C1> const & GG, MultiArrayView<2, T, C2> const & g,  
+                              MultiArrayView<2, T, C3> const & CE, MultiArrayView<2, T, C4> const & ce,  
+                              MultiArrayView<2, T, C5> const & CI, MultiArrayView<2, T, C6> const & ci, 
+                              MultiArrayView<2, T, C7> & x);
+     }
+     \endcode
+
+     The problem must be specified in the form:
+
+     \f{eqnarray*}
+        \mbox{minimize } &\,& \frac{1}{2} \mbox{\bf x}'\,\mbox{\bf G}\, \mbox{\bf x} + \mbox{\bf g}'\,\mbox{\bf x} \\
+        \mbox{subject to} &\,& \mbox{\bf C}_E\, \mbox{\bf x} = \mbox{\bf c}_e \\
+         &\,& \mbox{\bf C}_I\,\mbox{\bf x} \ge \mbox{\bf c}_i
+     \f}            
+     Matrix <b>G</b> G must be symmetric positive definite, and matrix <b>C</b><sub>E</sub> must have full row rank. 
+     Matrix and vector dimensions must be as follows:
+     <ul>
+     <li> <b>G</b>: [n * n], <b>g</b>: [n * 1]
+     <li> <b>C</b><sub>E</sub>: [me * n], <b>c</b><sub>e</sub>: [me * 1]
+     <li> <b>C</b><sub>I</sub>: [mi * n], <b>c</b><sub>i</sub>: [mi * 1]
+     <li> <b>x</b>: [n * 1]
+     </ul>
+     
+     The function writes the optimal solution into the vector \a x and returns the cost of this solution. 
+     If the problem is infeasible, std::numeric_limits::infinity() is returned. In this case
+     the value of vector \a x is undefined.
+     
+     <b>Usage:</b>
+     
+     Minimize <tt> f = 0.5 * x'*G*x + g'*x </tt> subject to <tt> -1 <= x <= 1</tt>. 
+     The solution is <tt> x' = [1.0, 0.5, -1.0] </tt> with <tt> f = -22.625</tt>.
+     \code
+      double Gdata[] = {13.0, 12.0, -2.0,
+                        12.0, 17.0,  6.0,
+                        -2.0,  6.0, 12.0};
+
+      double gdata[] = {-22.0, -14.5, 13.0};
+
+      double CIdata[] = { 1.0,  0.0,  0.0,
+                          0.0,  1.0,  0.0,
+                          0.0,  0.0,  1.0,
+                         -1.0,  0.0,  0.0,
+                          0.0, -1.0,  0.0,
+                          0.0,  0.0, -1.0};
+                        
+      double cidata[] = {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0};
+
+      Matrix<double> G(3,3, Gdata), 
+                     g(3,1, gdata), 
+                     CE,             // empty since there are no equality constraints
+                     ce,             // likewise
+                     CI(7,3, CIdata), 
+                     ci(7,1, cidata), 
+                     x(3,1);
+                   
+      double f = quadraticProgramming(G, g, CE, ce, CI, ci, x);
+     \endcode
+   */
+template <class T, class C1, class C2, class C3, class C4, class C5, class C6, class C7>
+T 
+quadraticProgramming(MultiArrayView<2, T, C1> const & G, MultiArrayView<2, T, C2> const & g,  
+               MultiArrayView<2, T, C3> const & CE, MultiArrayView<2, T, C4> const & ce,  
+               MultiArrayView<2, T, C5> const & CI, MultiArrayView<2, T, C6> const & ci, 
+               MultiArrayView<2, T, C7> & x)
+{
+    using namespace linalg;
+    typedef typename MultiArrayShape<2>::type Shape;
+    
+    int n  = rowCount(g),
+        me = rowCount(ce),
+        mi = rowCount(ci),
+        constraintCount = me + mi;
+        
+    vigra_precondition(columnCount(G) == n && rowCount(G) == n,
+        "quadraticProgramming(): Matrix shape mismatch between G and g.");
+    vigra_precondition(rowCount(x) == n,
+        "quadraticProgramming(): Output vector x has illegal shape.");
+    vigra_precondition((me > 0 && columnCount(CE) == n && rowCount(CE) == me) || 
+                       (me == 0 && columnCount(CE) == 0),
+        "quadraticProgramming(): Matrix CE has illegal shape.");
+    vigra_precondition((mi > 0 && columnCount(CI) == n && rowCount(CI) == mi) || 
+                       (mi == 0 && columnCount(CI) == 0),
+        "quadraticProgramming(): Matrix CI has illegal shape.");
+
+    Matrix<T> J = identityMatrix<T>(n);
+    {
+        Matrix<T> L(G.shape());
+        choleskyDecomposition(G, L);
+        // find unconstrained minimizer of the quadratic form  0.5 * x G x + g' x
+        choleskySolve(L, -g, x);
+        // compute the inverse of the factorized matrix G^-1, this is the initial value for J
+        linearSolveLowerTriangular(L, J, J);
+    }
+    // current solution value
+    T f_value = 0.5 * dot(g, x);
+    
+    T epsilonZ   = NumericTraits<T>::epsilon() * sq(J.norm(0)),
+      inf        = std::numeric_limits<T>::infinity();
+    
+    Matrix<T> R(n, n), r(constraintCount, 1), u(constraintCount,1);
+    T R_norm = NumericTraits<T>::one();
+    
+    // incorporate equality constraints
+    for (int i=0; i < me; ++i)
+    {
+        MultiArrayView<2, T, C3> np = rowVector(CE, i);
+        Matrix<T> d = J*transpose(np);
+        Matrix<T> z = transpose(J).subarray(Shape(0, i), Shape(n,n))*subVector(d, i, n);
+        linearSolveUpperTriangular(R.subarray(Shape(0, 0), Shape(i,i)), 
+                                   subVector(d, 0, i), 
+                                   subVector(r, 0, i));
+        // compute step in primal space so that the constraint becomes satisfied
+        T step = (squaredNorm(z) <= epsilonZ) // i.e. z == 0
+                     ? 0.0 
+                     : (-dot(np, x) + ce(i,0)) / dot(z, np);
+    
+        x += step * z;    
+        u(i,0) = step;
+        subVector(u, 0, i) -= step * subVector(r, 0, i);
+        
+        f_value += 0.5 * sq(step) * dot(z, np);
+    
+        vigra_precondition(vigra::detail::quadprogAddConstraint(R, J, d, i, R_norm),
+            "quadraticProgramming(): Equality constraints are linearly dependent.");
+    }
+    int activeConstraintCount = me;
+  
+    // determine optimum solution and corresponding active inequality constraints
+    ArrayVector<int> activeSet(mi);
+    for (int i = 0; i < mi; ++i)
+        activeSet[i] = i;
+
+    int constraintToBeAdded = 0;
+    T ss = 0.0;
+    for (int i = activeConstraintCount-me; i < mi; ++i)
+    {
+        T s = dot(rowVector(CI, activeSet[i]), x) - ci(activeSet[i], 0);
+        if (s < ss)
+        {
+            ss = s;
+            constraintToBeAdded = i;
+        }
+    }
+
+    int iter = 0, maxIter = 10*mi;    
+    while(iter++ < maxIter)
+    {        
+        if (ss >= 0.0)       // all constraints are satisfied
+            return f_value;  // => solved!
+
+        // determine step direction in the primal space (through J, see the paper)
+        MultiArrayView<2, T, C5> np = rowVector(CI, activeSet[constraintToBeAdded]);
+        Matrix<T> d = J*transpose(np);
+        Matrix<T> z = transpose(J).subarray(Shape(0, activeConstraintCount), Shape(n,n))*subVector(d, activeConstraintCount, n);
+        
+        // compute negative of the step direction in the dual space
+        linearSolveUpperTriangular(R.subarray(Shape(0, 0), Shape(activeConstraintCount,activeConstraintCount)), 
+                                   subVector(d, 0, activeConstraintCount), 
+                                   subVector(r, 0, activeConstraintCount));
+
+        // determine minimum step length in primal space such that activeSet[constraintToBeAdded] becomes feasible
+        T primalStep = (squaredNorm(z) <= epsilonZ) // i.e. z == 0
+                          ? inf
+                          : -ss / dot(z, np);
+      
+        // determine maximum step length in dual space that doesn't violate dual feasibility
+        // and the corresponding index
+        T dualStep = inf; 
+        int constraintToBeRemoved = 0;
+        for (int k = me; k < activeConstraintCount; ++k)
+        {
+            if (r(k,0) > 0.0)
+            {
+                if (u(k,0) / r(k,0) < dualStep)
+                {
+                    dualStep = u(k,0) / r(k,0);
+                    constraintToBeRemoved = k;
+                }
+            }
+        }
+        
+        // the step is chosen as the minimum of dualStep and primalStep
+        T step = std::min(dualStep, primalStep);
+      
+        // take step and update matrices
+      
+        if (step == inf)
+        {
+            // case (i): no step in primal or dual space possible
+            return inf; // QPP is infeasible 
+        }
+        if (primalStep == inf)
+        {
+            // case (ii): step in dual space
+            subVector(u, 0, activeConstraintCount) -= step * subVector(r, 0, activeConstraintCount);
+            vigra::detail::quadprogDeleteConstraint(R, J, u, activeConstraintCount, constraintToBeRemoved);
+            --activeConstraintCount;
+            std::swap(activeSet[constraintToBeRemoved-me], activeSet[activeConstraintCount-me]);
+            continue;
+        }
+      
+        // case (iii): step in primal and dual space      
+        x += step * z;
+        // update the solution value
+        f_value += 0.5 * sq(step) * dot(z, np);
+        // u = [u 1]' + step * [-r 1]
+        subVector(u, 0, activeConstraintCount) -= step * subVector(r, 0, activeConstraintCount);
+        u(activeConstraintCount,0) = step;
+      
+        if (step == primalStep)
+        {
+            // add constraintToBeAdded to the active set
+            vigra::detail::quadprogAddConstraint(R, J, d, activeConstraintCount, R_norm);
+            std::swap(activeSet[constraintToBeAdded], activeSet[activeConstraintCount-me]);
+            ++activeConstraintCount;
+        }
+        else
+        {
+            // drop constraintToBeRemoved from the active set
+            vigra::detail::quadprogDeleteConstraint(R, J, u, activeConstraintCount, constraintToBeRemoved);
+            --activeConstraintCount;
+            std::swap(activeSet[constraintToBeRemoved-me], activeSet[activeConstraintCount-me]);
+        }
+        
+        // update values of inactive inequality constraints
+        ss = 0.0;
+        for (int i = activeConstraintCount-me; i < mi; ++i)
+        {
+            // compute CI*x - ci with appropriate row permutation
+            T s = dot(rowVector(CI, activeSet[i]), x) - ci(activeSet[i], 0);
+            if (s < ss)
+            {
+                ss = s;
+                constraintToBeAdded = i;
+            }
+        }
+    }
+    return inf; // too many iterations
+}
+
+//@}
+
+} // namespace vigra
+
+#endif
diff --git a/include/vigra/quaternion.hxx b/include/vigra/quaternion.hxx
new file mode 100644
index 0000000..16f0558
--- /dev/null
+++ b/include/vigra/quaternion.hxx
@@ -0,0 +1,559 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2004-2010 by Hans Meine und Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_QUATERNION_HXX
+#define VIGRA_QUATERNION_HXX
+
+#include "config.hxx"
+#include "numerictraits.hxx"
+#include "tinyvector.hxx"
+#include "matrix.hxx"
+#include "mathutil.hxx"
+#include <iosfwd>   // ostream
+
+
+namespace vigra {
+
+/** Quaternion class.
+
+    Quaternions are mainly used as a compact representation for 3D rotations because
+    they are much less prone to round-off errors than rotation matrices, especially
+    when many rotations are concatenated. In addition, the angle/axis interpretation
+    of normalized quaternions is very intuitive. Read the 
+    <a href="http://en.wikipedia.org/wiki/Quaternion">Wikipedia entry on quaternions</a> 
+    for more information on the mathematics.
+    
+    See also: \ref QuaternionOperations
+*/
+template<class ValueType>
+class Quaternion {
+  public:
+    typedef TinyVector<ValueType, 3> Vector;
+    
+        /** the quaternion's valuetype
+        */
+    typedef ValueType value_type;
+
+        /** reference (return of operator[]).
+        */
+    typedef ValueType & reference;
+
+        /** const reference (return of operator[] const).
+        */
+    typedef ValueType const & const_reference;
+
+        /** the quaternion's squared norm type
+        */
+    typedef typename NormTraits<ValueType>::SquaredNormType SquaredNormType;
+
+        /** the quaternion's norm type
+        */
+    typedef typename NormTraits<ValueType>::NormType NormType;
+
+        /** Construct a quaternion with explicit values for the real and imaginary parts.
+        */
+    Quaternion(ValueType w = 0, ValueType x = 0, ValueType y = 0, ValueType z = 0)
+    : w_(w), v_(x, y, z)
+    {}
+    
+        /** Construct a quaternion with real value and imaginary vector.
+        
+            Equivalent to <tt>Quaternion(w, v[0], v[1], v[2])</tt>.
+        */
+    Quaternion(ValueType w, const Vector &v)
+    : w_(w), v_(v)
+    {}
+
+        /** Copy constructor.
+        */
+    Quaternion(const Quaternion &q)
+    : w_(q.w_), v_(q.v_)
+    {}
+    
+        /** Copy assignment.
+        */
+    Quaternion & operator=(Quaternion const & other)
+    {
+        w_ = other.w_;
+        v_ = other.v_;
+        return *this;
+    }
+    
+        /** Assign \a w to the real part and set the imaginary part to zero.
+        */
+    Quaternion & operator=(ValueType w)
+    {
+        w_ = w;
+        v_.init(0);
+        return *this;
+    }
+
+        /**
+         * Creates a Quaternion which represents the operation of
+         * rotating around the given axis by the given angle.
+         *
+         * The angle should be in the range -pi..3*pi for sensible
+         * results.
+         */
+    static Quaternion
+    createRotation(double angle, const Vector &rotationAxis)
+    {
+        // the natural range would be -pi..pi, but the reflective
+        // behavior around pi is too unexpected:
+        if(angle > M_PI)
+            angle -= 2.0*M_PI;
+        double t = VIGRA_CSTD::sin(angle/2.0);
+        double norm = rotationAxis.magnitude();
+        return Quaternion(VIGRA_CSTD::sqrt(1.0-t*t), t*rotationAxis/norm);
+    }
+
+        /** Read real part.
+        */
+    ValueType w() const { return w_; }
+        /** Access real part.
+        */
+    ValueType &w() { return w_; }
+        /** Set real part.
+        */
+    void setW(ValueType w) { w_ = w; }
+
+        /** Read imaginary part.
+        */
+    const Vector &v() const { return v_; }
+        /** Access imaginary part.
+        */
+    Vector &v() { return v_; }
+        /** Set imaginary part.
+        */
+    void setV(const Vector & v) { v_ = v; }
+        /** Set imaginary part.
+        */
+    void setV(ValueType x, ValueType y, ValueType z)
+    {
+        v_[0] = x;
+        v_[1] = y;
+        v_[2] = z;
+    }
+
+    ValueType x() const { return v_[0]; }
+    ValueType y() const { return v_[1]; }
+    ValueType z() const { return v_[2]; }
+    ValueType &x() { return v_[0]; }
+    ValueType &y() { return v_[1]; }
+    ValueType &z() { return v_[2]; }
+    void setX(ValueType x) { v_[0] = x; }
+    void setY(ValueType y) { v_[1] = y; }
+    void setZ(ValueType z) { v_[2] = z; }
+    
+        /** Access entry at index (0 <=> w(), 1 <=> v[0] etc.).
+        */
+    value_type & operator[](int index)
+    {
+        return (&w_)[index];
+    }
+    
+        /** Read entry at index (0 <=> w(), 1 <=> v[0] etc.).
+        */
+    value_type operator[](int index) const
+    {
+        return (&w_)[index];
+    }
+    
+        /** Magnitude.
+        */
+    NormType magnitude() const
+    {
+        return VIGRA_CSTD::sqrt((NormType)squaredMagnitude());
+    }
+
+        /** Squared magnitude.
+        */
+    SquaredNormType squaredMagnitude() const
+    {
+        return w_*w_ + v_.squaredMagnitude();
+    }
+
+        /** Add \a w to the real part.
+        
+            If the quaternion represents a rotation, the rotation angle is
+            increased by \a w.
+        */
+    Quaternion &operator+=(value_type const &w)
+    {
+        w_ += w;
+        return *this;
+    }
+
+        /** Add assigment.
+        */
+    Quaternion &operator+=(Quaternion const &other)
+    {
+        w_ += other.w_;
+        v_ += other.v_;
+        return *this;
+    }
+
+        /** Subtract \a w from the real part.
+        
+            If the quaternion represents a rotation, the rotation angle is
+            decreased by \a w.
+        */
+    Quaternion &operator-=(value_type const &w)
+    {
+        w_ -= w;
+        return *this;
+    }
+
+        /** Subtract assigment.
+        */
+    Quaternion &operator-=(Quaternion const &other)
+    {
+        w_ -= other.w_;
+        v_ -= other.v_;
+        return *this;
+    }
+
+        /** Addition.
+        */
+    Quaternion operator+() const
+    {
+        return *this;
+    }
+
+        /** Subtraction.
+        */
+    Quaternion operator-() const
+    {
+        return Quaternion(-w_, -v_);
+    }
+
+        /** Multiply assignment.
+        
+            If the quaternions represent rotations, the rotations of <tt>this</tt> and 
+            \a other are concatenated.
+        */
+    Quaternion &operator*=(Quaternion const &other)
+    {
+        value_type newW = w_*other.w_ - dot(v_, other.v_);
+        v_              = w_ * other.v_ + other.w_ * v_ + cross(v_, other.v_);
+        w_              = newW;
+        return *this;
+    }
+
+        /** Multiply all entries with the scalar \a scale.
+        */
+    Quaternion &operator*=(double scale)
+    {
+        w_ *= scale;
+        v_ *= scale;
+        return *this;
+    }
+
+        /** Divide assignment.
+        */
+    Quaternion &operator/=(Quaternion const &other)
+    {
+        (*this) *= conj(other) / squaredNorm(other);
+        return *this;
+    }
+
+        /** Devide all entries by the scalar \a scale.
+        */
+    Quaternion &operator/=(double scale)
+    {
+        w_ /= scale;
+        v_ /= scale;
+        return *this;
+    }
+
+        /** Equal.
+        */
+    bool operator==(Quaternion const &other) const
+    {
+      return (w_ == other.w_) && (v_ == other.v_);
+    }
+
+        /** Not equal.
+        */
+    bool operator!=(Quaternion const &other) const
+    {
+      return (w_ != other.w_) || (v_ != other.v_);
+    }
+
+        /**
+         * Fill the first 3x3 elements of the given matrix with a
+         * rotation matrix performing the same 3D rotation as this
+         * quaternion.  If matrix is in column-major format, it should
+         * be pre-multiplied with the vectors to be rotated, i.e.
+         * matrix[0][0-3] will be the rotated X axis.
+         */
+    template<class MatrixType>
+    void fillRotationMatrix(MatrixType &matrix) const
+    {
+        // scale by 2 / norm
+        typename NumericTraits<ValueType>::RealPromote s =
+            2 / (typename NumericTraits<ValueType>::RealPromote)squaredMagnitude();
+
+        Vector
+            vs = v_ * s,
+            wv = w_ * vs,
+            vv = vs * v_;
+        value_type
+            xy = vs[0] * v_[1],
+            xz = vs[0] * v_[2],
+            yz = vs[1] * v_[2];
+
+        matrix[0][0] = 1 - (vv[1] + vv[2]);
+        matrix[0][1] =     ( xy   - wv[2]);
+        matrix[0][2] =     ( xz   + wv[1]);
+
+        matrix[1][0] =     ( xy   + wv[2]);
+        matrix[1][1] = 1 - (vv[0] + vv[2]);
+        matrix[1][2] =     ( yz   - wv[0]);
+
+        matrix[2][0] =     ( xz   - wv[1]);
+        matrix[2][1] =     ( yz   + wv[0]);
+        matrix[2][2] = 1 - (vv[0] + vv[1]);
+    }
+
+    void fillRotationMatrix(Matrix<value_type> &matrix) const
+    {
+        // scale by 2 / norm
+        typename NumericTraits<ValueType>::RealPromote s =
+            2 / (typename NumericTraits<ValueType>::RealPromote)squaredMagnitude();
+
+        Vector
+            vs = v_ * s,
+            wv = w_ * vs,
+            vv = vs * v_;
+        value_type
+            xy = vs[0] * v_[1],
+            xz = vs[0] * v_[2],
+            yz = vs[1] * v_[2];
+
+        matrix(0, 0) = 1 - (vv[1] + vv[2]);
+        matrix(0, 1) =     ( xy   - wv[2]);
+        matrix(0, 2) =     ( xz   + wv[1]);
+
+        matrix(1, 0) =     ( xy   + wv[2]);
+        matrix(1, 1) = 1 - (vv[0] + vv[2]);
+        matrix(1, 2) =     ( yz   - wv[0]);
+
+        matrix(2, 0) =     ( xz   - wv[1]);
+        matrix(2, 1) =     ( yz   + wv[0]);
+        matrix(2, 2) = 1 - (vv[0] + vv[1]);
+    }
+
+  protected:
+    ValueType w_;
+    Vector v_;
+};
+
+template<class T>
+struct NormTraits<Quaternion<T> >
+{
+    typedef Quaternion<T>                                                  Type;
+    typedef typename NumericTraits<T>::Promote                             SquaredNormType;
+    typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult   NormType;
+};
+
+
+/** \defgroup QuaternionOperations Quaternion Operations
+*/
+//@{
+
+    /// Create conjugate quaternion.
+template<class ValueType>
+Quaternion<ValueType> conj(Quaternion<ValueType> const & q)
+{
+    return Quaternion<ValueType>(q.w(), -q.v());
+}
+
+    /// Addition.
+template<typename Type>
+inline Quaternion<Type>
+operator+(const Quaternion<Type>& t1,
+           const Quaternion<Type>& t2) 
+{
+  return Quaternion<Type>(t1) += t2;
+}
+
+    /// Addition of a scalar on the right.
+template<typename Type>
+inline Quaternion<Type>
+operator+(const Quaternion<Type>& t1,
+           const Type& t2) 
+{
+  return Quaternion<Type>(t1) += t2;
+}
+
+    /// Addition of a scalar on the left.
+template<typename Type>
+inline Quaternion<Type>
+operator+(const Type& t1,
+           const Quaternion<Type>& t2) 
+{
+  return Quaternion<Type>(t1) += t2;
+}
+
+    /// Subtraction.
+template<typename Type>
+inline Quaternion<Type>
+operator-(const Quaternion<Type>& t1,
+           const Quaternion<Type>& t2) 
+{
+  return Quaternion<Type>(t1) -= t2;
+}
+
+    /// Subtraction of a scalar on the right.
+template<typename Type>
+inline Quaternion<Type>
+operator-(const Quaternion<Type>& t1,
+           const Type& t2) 
+{
+  return Quaternion<Type>(t1) -= t2;
+}
+
+    /// Subtraction of a scalar on the left.
+template<typename Type>
+inline Quaternion<Type>
+operator-(const Type& t1,
+           const Quaternion<Type>& t2) 
+{
+  return Quaternion<Type>(t1) -= t2;
+}
+
+    /// Multiplication.
+template<typename Type>
+inline Quaternion<Type>
+operator*(const Quaternion<Type>& t1,
+           const Quaternion<Type>& t2) 
+{
+  return Quaternion<Type>(t1) *= t2;
+}
+
+    /// Multiplication with a scalar on the right.
+template<typename Type>
+inline Quaternion<Type>
+operator*(const Quaternion<Type>& t1,
+           double t2) 
+{
+  return Quaternion<Type>(t1) *= t2;
+}
+  
+    /// Multiplication with a scalar on the left.
+template<typename Type>
+inline Quaternion<Type>
+operator*(double t1,
+           const Quaternion<Type>& t2)
+{
+  return Quaternion<Type>(t1) *= t2;
+}
+
+    /// Division
+template<typename Type>
+inline Quaternion<Type>
+operator/(const Quaternion<Type>& t1,
+           const Quaternion<Type>& t2) 
+{
+  return Quaternion<Type>(t1) /= t2;
+}
+
+    /// Division by a scalar.
+template<typename Type>
+inline Quaternion<Type>
+operator/(const Quaternion<Type>& t1,
+           double t2) 
+{
+  return Quaternion<Type>(t1) /= t2;
+}
+  
+    /// Division of a scalar by a Quaternion.
+template<typename Type>
+inline Quaternion<Type>
+operator/(double t1,
+           const Quaternion<Type>& t2)
+{
+  return Quaternion<Type>(t1) /= t2;
+}
+
+    /// squared norm
+template<typename Type>
+inline
+typename Quaternion<Type>::SquaredNormType
+squaredNorm(Quaternion<Type> const & q)
+{
+    return q.squaredMagnitude();
+}
+
+    /// norm
+template<typename Type>
+inline
+typename Quaternion<Type>::NormType
+abs(Quaternion<Type> const & q)
+{
+    return norm(q);
+}
+
+//@}
+
+} // namespace vigra
+
+namespace std {
+
+template<class ValueType>
+inline
+ostream & operator<<(ostream & os, vigra::Quaternion<ValueType> const & q)
+{
+    os << q.w() << " " << q.x() << " " << q.y() << " " << q.z();
+    return os;
+}
+
+template<class ValueType>
+inline
+istream & operator>>(istream & is, vigra::Quaternion<ValueType> & q)
+{
+    ValueType w, x, y, z;
+    is >> w >> x >> y >> z;
+    q.setW(w);
+    q.setX(x);
+    q.setY(y);
+    q.setZ(z);
+    return is;
+}
+
+} // namespace std
+
+#endif // VIGRA_QUATERNION_HXX
diff --git a/include/vigra/random.hxx b/include/vigra/random.hxx
new file mode 100644
index 0000000..ff1ad73
--- /dev/null
+++ b/include/vigra/random.hxx
@@ -0,0 +1,911 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 2008 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_RANDOM_HXX
+#define VIGRA_RANDOM_HXX
+
+#include "mathutil.hxx"
+#include "functortraits.hxx"
+#include "array_vector.hxx"
+
+#include <ctime>
+
+    // includes to get the current process and thread IDs
+    // to be used for automated seeding
+#ifdef _MSC_VER
+  #include <vigra/windows.h>  // for GetCurrentProcessId() and GetCurrentThreadId()
+#endif
+
+#if __linux__
+  #include <unistd.h>       // for getpid()
+  #include <sys/syscall.h>  // for SYS_gettid
+#endif
+
+#if __APPLE__
+  #include <unistd.h>               // for getpid()
+  #include <sys/syscall.h>          // SYS_thread_selfid
+  #include <AvailabilityMacros.h>   // to check if we are on MacOS 10.6 or later
+#endif
+
+namespace vigra {
+
+enum RandomSeedTag { RandomSeed };
+
+namespace detail {
+
+enum RandomEngineTag { TT800, MT19937 };
+
+
+template<RandomEngineTag EngineTag>
+struct RandomState;
+
+template <RandomEngineTag EngineTag>
+void seed(UInt32 theSeed, RandomState<EngineTag> & engine)
+{
+    engine.state_[0] = theSeed;
+    for(UInt32 i=1; i<RandomState<EngineTag>::N; ++i)
+    {
+        engine.state_[i] = 1812433253U * (engine.state_[i-1] ^ (engine.state_[i-1] >> 30)) + i;
+    }
+}
+
+template <class Iterator, RandomEngineTag EngineTag>
+void seed(Iterator init, UInt32 key_length, RandomState<EngineTag> & engine)
+{
+    const UInt32 N = RandomState<EngineTag>::N;
+    int k = (int)std::max(N, key_length);
+    UInt32 i = 1, j = 0;
+    Iterator data = init;
+    for (; k; --k) 
+    {
+        engine.state_[i] = (engine.state_[i] ^ ((engine.state_[i-1] ^ (engine.state_[i-1] >> 30)) * 1664525U))
+                           + *data + j; /* non linear */
+        ++i; ++j; ++data;
+        
+        if (i >= N) 
+        { 
+            engine.state_[0] = engine.state_[N-1]; 
+            i=1; 
+        }
+        if (j>=key_length)
+        { 
+            j=0;
+            data = init;
+        }
+    }
+
+    for (k=N-1; k; --k) 
+    {
+        engine.state_[i] = (engine.state_[i] ^ ((engine.state_[i-1] ^ (engine.state_[i-1] >> 30)) * 1566083941U))
+                           - i; /* non linear */
+        ++i;
+        if (i>=N) 
+        { 
+            engine.state_[0] = engine.state_[N-1]; 
+            i=1; 
+        }
+    }
+
+    engine.state_[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ 
+}
+
+template <RandomEngineTag EngineTag>
+void seed(RandomSeedTag, RandomState<EngineTag> & engine)
+{
+    static UInt32 globalCount = 0;
+    ArrayVector<UInt32> seedData;
+    
+    seedData.push_back((UInt32)time(0));
+    seedData.push_back((UInt32)clock());
+    seedData.push_back(++globalCount);
+    
+    std::size_t ptr((char*)&engine - (char*)0);
+    seedData.push_back((UInt32)(ptr & 0xffffffff));
+    static const UInt32 shift = sizeof(ptr) > 4 ? 32 : 16;
+    seedData.push_back((UInt32)(ptr >> shift));
+    
+#ifdef _MSC_VER
+    seedData.push_back((UInt32)GetCurrentProcessId());
+    seedData.push_back((UInt32)GetCurrentThreadId());
+#endif
+
+#ifdef __linux__
+    seedData.push_back((UInt32)getpid());
+# ifdef SYS_gettid
+    seedData.push_back((UInt32)syscall(SYS_gettid));
+# endif
+#endif
+
+#ifdef __APPLE__
+    seedData.push_back((UInt32)getpid());
+  #if defined(SYS_thread_selfid) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6)
+    // SYS_thread_selfid was introduced in MacOS 10.6
+    seedData.push_back((UInt32)syscall(SYS_thread_selfid));
+  #endif
+#endif
+
+    seed(seedData.begin(), seedData.size(), engine);
+}
+
+    /* Tempered twister TT800 by M. Matsumoto */
+template<>
+struct RandomState<TT800>
+{
+    static const UInt32 N = 25, M = 7;
+    
+    mutable UInt32 state_[N];
+    mutable UInt32 current_;
+                   
+    RandomState()
+    : current_(0)
+    {
+        UInt32 seeds[N] = { 
+            0x95f24dab, 0x0b685215, 0xe76ccae7, 0xaf3ec239, 0x715fad23,
+            0x24a590ad, 0x69e4b5ef, 0xbf456141, 0x96bc1b7b, 0xa7bdf825,
+            0xc1de75b7, 0x8858a9c9, 0x2da87693, 0xb657f9dd, 0xffdc8a9f,
+            0x8121da71, 0x8b823ecb, 0x885d05f5, 0x4e20cd47, 0x5a9ad5d9,
+            0x512c0c03, 0xea857ccd, 0x4cc1d30f, 0x8891a8a1, 0xa6b7aadb
+        };
+         
+        for(UInt32 i=0; i<N; ++i)
+            state_[i] = seeds[i];
+    }
+
+  protected:  
+
+    UInt32 get() const
+    {
+        if(current_ == N)
+            generateNumbers<void>();
+            
+        UInt32 y = state_[current_++];
+        y ^= (y << 7) & 0x2b5b2500; 
+        y ^= (y << 15) & 0xdb8b0000; 
+        return y ^ (y >> 16);
+    }
+    
+    template <class DUMMY>
+    void generateNumbers() const;
+
+    void seedImpl(RandomSeedTag)
+    {
+        seed(RandomSeed, *this);
+    }
+
+    void seedImpl(UInt32 theSeed)
+    {
+        seed(theSeed, *this);
+    }
+    
+    template<class Iterator>
+    void seedImpl(Iterator init, UInt32 length)
+    {
+        seed(init, length, *this);
+    }
+};
+
+template <class DUMMY>
+void RandomState<TT800>::generateNumbers() const
+{
+    UInt32 mag01[2]= { 0x0, 0x8ebfd028 };
+
+    for(UInt32 i=0; i<N-M; ++i)
+    {
+        state_[i] = state_[i+M] ^ (state_[i] >> 1) ^ mag01[state_[i] % 2];
+    }
+    for (UInt32 i=N-M; i<N; ++i) 
+    {
+        state_[i] = state_[i+(M-N)] ^ (state_[i] >> 1) ^ mag01[state_[i] % 2];
+    }
+    current_ = 0;
+}
+
+    /* Mersenne twister MT19937 by M. Matsumoto */
+template<>
+struct RandomState<MT19937>
+{
+    static const UInt32 N = 624, M = 397;
+    
+    mutable UInt32 state_[N];
+    mutable UInt32 current_;
+                   
+    RandomState()
+    : current_(0)
+    {
+        seed(19650218U, *this);
+    }
+
+  protected:  
+
+    UInt32 get() const
+    {
+        if(current_ == N)
+            generateNumbers<void>();
+            
+        UInt32 x = state_[current_++];
+        x ^= (x >> 11);
+        x ^= (x << 7) & 0x9D2C5680U;
+        x ^= (x << 15) & 0xEFC60000U;
+        return x ^ (x >> 18);
+    }
+    
+    template <class DUMMY>
+    void generateNumbers() const;
+
+    static UInt32 twiddle(UInt32 u, UInt32 v) 
+    {
+        return (((u & 0x80000000U) | (v & 0x7FFFFFFFU)) >> 1)
+                ^ ((v & 1U) ? 0x9908B0DFU : 0x0U);
+    }
+
+    void seedImpl(RandomSeedTag)
+    {
+        seed(RandomSeed, *this);
+        generateNumbers<void>();
+    }
+
+    void seedImpl(UInt32 theSeed)
+    {
+        seed(theSeed, *this);
+        generateNumbers<void>();
+    }
+    
+    template<class Iterator>
+    void seedImpl(Iterator init, UInt32 length)
+    {
+        seed(19650218U, *this);
+        seed(init, length, *this);
+        generateNumbers<void>();
+    }
+};
+
+template <class DUMMY>
+void RandomState<MT19937>::generateNumbers() const
+{
+    for (unsigned int i = 0; i < (N - M); ++i)
+    {
+        state_[i] = state_[i + M] ^ twiddle(state_[i], state_[i + 1]);
+    }
+    for (unsigned int i = N - M; i < (N - 1); ++i)
+    {
+        state_[i] = state_[i + M - N] ^ twiddle(state_[i], state_[i + 1]);
+    }
+    state_[N - 1] = state_[M - 1] ^ twiddle(state_[N - 1], state_[0]);
+    current_ = 0;
+}
+
+} // namespace detail
+
+
+/** \addtogroup RandomNumberGeneration Random Number Generation
+
+     High-quality random number generators and related functors.
+*/
+//@{
+
+/** Generic random number generator.
+
+    The actual generator is passed in the template argument <tt>Engine</tt>. Two generators
+    are currently available:
+    <ul>
+    <li> <tt>RandomMT19937</tt>: The state-of-the-art <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html">Mersenne Twister</a> with a state length of 2<sup>19937</sup> and very high statistical quality.
+    <li> <tt>RandomTT800</tt>: (default) The Tempered Twister, a simpler predecessor of the Mersenne Twister with period length 2<sup>800</sup>.
+    </ul>
+    
+    Both generators have been designed by <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/eindex.html">Makoto Matsumoto</a>. 
+    
+    <b>Traits defined:</b>
+    
+    \verbatim FunctorTraits<RandomNumberGenerator<Engine> >::isInitializer \endverbatim
+    is true (<tt>VigraTrueType</tt>).
+*/
+template <class Engine = detail::RandomState<detail::MT19937> >
+class RandomNumberGenerator
+: public Engine
+{
+    mutable double normalCached_;
+    mutable bool normalCachedValid_;
+    
+  public:
+  
+        /** Create a new random generator object with standard seed.
+            
+            Due to standard seeding, the random numbers generated will always be the same. 
+            This is useful for debugging.
+        */
+    RandomNumberGenerator()
+    : normalCached_(0.0),
+      normalCachedValid_(false)
+    {}
+  
+        /** Create a new random generator object with a random seed.
+        
+            The seed is obtained from the machines current <tt>clock()</tt> and <tt>time()</tt>
+            values.
+        
+            <b>Usage:</b>
+            \code
+            RandomNumberGenerator<> rnd = RandomNumberGenerator<>(RandomSeed);
+            \endcode
+        */
+    RandomNumberGenerator(RandomSeedTag)
+    : normalCached_(0.0),
+      normalCachedValid_(false)
+    {
+        this->seedImpl(RandomSeed);
+    }
+  
+        /** Create a new random generator object from the given seed.
+            
+            The same seed will always produce identical random sequences.
+            If \a ignoreSeed is <tt>true</tt>, the given seed is ignored,
+            and the generator is seeded randomly (as if it was constructed 
+            with <tt>RandomNumberGenerator<>(RandomSeed)</tt>). This allows 
+            you to switch between random and deterministic seeding at
+            run-time.
+        */
+    RandomNumberGenerator(UInt32 theSeed, bool ignoreSeed=false)
+    : normalCached_(0.0),
+      normalCachedValid_(false)
+    {
+        if(ignoreSeed)
+            this->seedImpl(RandomSeed);
+        else
+            this->seedImpl(theSeed);
+    }
+
+        /** Create a new random generator object from the given seed sequence.
+            
+            Longer seed sequences lead to better initialization in the sense that the generator's 
+            state space is covered much better than is possible with 32-bit seeds alone.
+        */
+    template<class Iterator>
+    RandomNumberGenerator(Iterator init, UInt32 length)
+    : normalCached_(0.0),
+      normalCachedValid_(false)
+    {
+        this->seedImpl(init, length);
+    }
+
+  
+        /** Re-initialize the random generator object with a random seed.
+        
+            The seed is obtained from the machines current <tt>clock()</tt> and <tt>time()</tt>
+            values.
+        
+            <b>Usage:</b>
+            \code
+            RandomNumberGenerator<> rnd = ...;
+            ...
+            rnd.seed(RandomSeed);
+            \endcode
+        */
+    void seed(RandomSeedTag)
+    {
+        this->seedImpl(RandomSeed);
+        normalCachedValid_ = false;
+    }
+
+        /** Re-initialize the random generator object from the given seed.
+            
+            The same seed will always produce identical random sequences.
+            If \a ignoreSeed is <tt>true</tt>, the given seed is ignored,
+            and the generator is seeded randomly (as if <tt>seed(RandomSeed)</tt>
+            was called). This allows you to switch between random and deterministic 
+            seeding at run-time.
+        */
+    void seed(UInt32 theSeed, bool ignoreSeed=false)
+    {
+        if(ignoreSeed)
+            this->seedImpl(RandomSeed);
+        else
+            this->seedImpl(theSeed);
+        normalCachedValid_ = false;
+    }
+
+        /** Re-initialize the random generator object from the given seed sequence.
+            
+            Longer seed sequences lead to better initialization in the sense that the generator's 
+            state space is covered much better than is possible with 32-bit seeds alone.
+        */
+    template<class Iterator>
+    void seed(Iterator init, UInt32 length)
+    {
+        this->seedImpl(init, length);
+        normalCachedValid_ = false;
+    }
+
+        /** Return a uniformly distributed integer random number in [0, 2<sup>32</sup>).
+            
+            That is, 0 <= i < 2<sup>32</sup>. 
+        */
+    UInt32 operator()() const
+    {
+        return this->get();
+    }
+
+        /** Return a uniformly distributed integer random number in [0, 2<sup>32</sup>).
+            
+            That is, 0 <= i < 2<sup>32</sup>. 
+        */
+    UInt32 uniformInt() const
+    {
+        return this->get();
+    }
+
+
+#if 0 // difficult implementation necessary if low bits are not sufficiently random
+        // in [0,beyond)
+    UInt32 uniformInt(UInt32 beyond) const
+    {
+        if(beyond < 2)
+            return 0;
+
+        UInt32 factor = factorForUniformInt(beyond);
+        UInt32 res = this->get() / factor;
+
+        // Use rejection method to avoid quantization bias.
+        // On average, we will need two raw random numbers to generate one.
+        while(res >= beyond)
+            res = this->get() / factor;
+        return res;
+    }
+#endif /* #if 0 */
+
+        /** Return a uniformly distributed integer random number in [0, <tt>beyond</tt>).
+            
+            That is, 0 <= i < <tt>beyond</tt>. 
+        */
+    UInt32 uniformInt(UInt32 beyond) const
+    {
+        // in [0,beyond) -- simple implementation when low bits are sufficiently random, which is
+        // the case for TT800 and MT19937
+        if(beyond < 2)
+            return 0;
+
+        UInt32 remainder = (NumericTraits<UInt32>::max() - beyond + 1) % beyond;
+        UInt32 lastSafeValue = NumericTraits<UInt32>::max() - remainder;
+        UInt32 res = this->get();
+
+        // Use rejection method to avoid quantization bias.
+        // We will need two raw random numbers in amortized worst case.
+        while(res > lastSafeValue)
+            res = this->get();
+        return res % beyond;
+    }
+    
+        /** Return a uniformly distributed double-precision random number in [0.0, 1.0).
+            
+            That is, 0.0 <= i < 1.0. All 53-bit bits of the mantissa are random (two 32-bit integers are used to 
+            create this number).
+        */
+    double uniform53() const
+    {
+        // make full use of the entire 53-bit mantissa of a double, by Isaku Wada
+        return ( (this->get() >> 5) * 67108864.0 + (this->get() >> 6)) * (1.0/9007199254740992.0); 
+    }
+    
+        /** Return a uniformly distributed double-precision random number in [0.0, 1.0].
+            
+            That is, 0.0 <= i <= 1.0. This number is computed by <tt>uniformInt()</tt> / (2<sup>32</sup> - 1), 
+            so it has effectively only 32 random bits. 
+        */
+    double uniform() const
+    {
+        return (double)this->get() / 4294967295.0;
+    }
+
+        /** Return a uniformly distributed double-precision random number in [lower, upper].
+           
+            That is, <tt>lower</tt> <= i <= <tt>upper</tt>. This number is computed 
+            from <tt>uniform()</tt>, so it has effectively only 32 random bits. 
+        */
+    double uniform(double lower, double upper) const
+    {
+        vigra_precondition(lower < upper,
+          "RandomNumberGenerator::uniform(): lower bound must be smaller than upper bound."); 
+        return uniform() * (upper-lower) + lower;
+    }
+
+        /** Return a standard normal variate (Gaussian) random number.
+           
+            Mean is zero, standard deviation is 1.0. It uses the polar form of the 
+            Box-Muller transform.
+        */
+    double normal() const;
+    
+        /** Return a normal variate (Gaussian) random number with the given mean and standard deviation.
+           
+            It uses the polar form of the Box-Muller transform.
+        */
+    double normal(double mean, double stddev) const
+    {
+        vigra_precondition(stddev > 0.0,
+          "RandomNumberGenerator::normal(): standard deviation must be positive."); 
+        return normal()*stddev + mean;
+    }
+    
+        /** Access the global (program-wide) instance of the present random number generator.
+        
+            Normally, you will create a local generator by one of the constructor calls. But sometimes
+            it is useful to have all program parts access the same generator.
+        */
+    static RandomNumberGenerator & global()
+    {
+        return global_;
+    }
+
+    static UInt32 factorForUniformInt(UInt32 range)
+    {
+        return (range > 2147483648U || range == 0)
+                     ? 1
+                     : 2*(2147483648U / ceilPower2(range));
+    }
+    
+    static RandomNumberGenerator global_;
+};
+
+template <class Engine>
+RandomNumberGenerator<Engine> RandomNumberGenerator<Engine>::global_(RandomSeed);
+
+
+template <class Engine>
+double RandomNumberGenerator<Engine>::normal() const
+{
+    if(normalCachedValid_)
+    {
+        normalCachedValid_ = false;
+        return normalCached_;
+    }
+    else
+    {
+        double x1, x2, w;
+        do 
+        {
+             x1 = uniform(-1.0, 1.0);
+             x2 = uniform(-1.0, 1.0);
+             w = x1 * x1 + x2 * x2;
+        } 
+        while ( w > 1.0 || w == 0.0);
+        
+        w = std::sqrt( -2.0 * std::log( w )  / w );
+
+        normalCached_ = x2 * w;
+        normalCachedValid_ = true;
+
+        return x1 * w;
+    }
+}
+
+    /** Shorthand for the TT800 random number generator class.
+    */
+typedef RandomNumberGenerator<detail::RandomState<detail::TT800> >  RandomTT800; 
+
+    /** Shorthand for the TT800 random number generator class (same as RandomTT800).
+    */
+typedef RandomNumberGenerator<detail::RandomState<detail::TT800> >  TemperedTwister; 
+
+    /** Shorthand for the MT19937 random number generator class.
+    */
+typedef RandomNumberGenerator<detail::RandomState<detail::MT19937> > RandomMT19937;
+
+    /** Shorthand for the MT19937 random number generator class (same as RandomMT19937).
+    */
+typedef RandomNumberGenerator<detail::RandomState<detail::MT19937> > MersenneTwister;
+
+    /** Access the global (program-wide) instance of the TT800 random number generator.
+    */
+inline RandomTT800   & randomTT800()   { return RandomTT800::global(); }
+
+    /** Access the global (program-wide) instance of the MT19937 random number generator.
+    */
+inline RandomMT19937 & randomMT19937() { return RandomMT19937::global(); }
+
+template <class Engine>
+class FunctorTraits<RandomNumberGenerator<Engine> >
+{
+  public:
+    typedef RandomNumberGenerator<Engine> type;
+    
+    typedef VigraTrueType  isInitializer;
+    
+    typedef VigraFalseType isUnaryFunctor;
+    typedef VigraFalseType isBinaryFunctor;
+    typedef VigraFalseType isTernaryFunctor;
+    
+    typedef VigraFalseType isUnaryAnalyser;
+    typedef VigraFalseType isBinaryAnalyser;
+    typedef VigraFalseType isTernaryAnalyser;
+};
+
+
+/** Functor to create uniformly distributed integer random numbers.
+
+    This functor encapsulates the appropriate functions of the given random number
+    <tt>Engine</tt> (usually <tt>RandomTT800</tt> or <tt>RandomMT19937</tt>)
+    in an STL-compatible interface. 
+    
+    <b>Traits defined:</b>
+    
+    \verbatim FunctorTraits<UniformIntRandomFunctor<Engine> >::isInitializer \endverbatim
+    and
+    \verbatim FunctorTraits<UniformIntRandomFunctor<Engine> >::isUnaryFunctor \endverbatim
+    are true (<tt>VigraTrueType</tt>).
+*/
+template <class Engine = MersenneTwister>
+class UniformIntRandomFunctor
+{
+    UInt32 lower_, difference_, factor_;
+    Engine const & generator_;
+    bool useLowBits_;
+
+  public:
+  
+    typedef UInt32 argument_type; ///< STL required functor argument type
+    typedef UInt32 result_type; ///< STL required functor result type
+
+        /** Create functor for uniform random integers in the range [0, 2<sup>32</sup>) 
+            using the given engine.
+            
+            That is, the generated numbers satisfy 0 <= i < 2<sup>32</sup>.
+        */
+    explicit UniformIntRandomFunctor(Engine const & generator = Engine::global() )
+    : lower_(0), difference_(0xffffffff), factor_(1),
+      generator_(generator),
+      useLowBits_(true)
+    {}
+    
+        /** Create functor for uniform random integers in the range [<tt>lower</tt>, <tt>upper</tt>]
+            using the given engine.
+            
+            That is, the generated numbers satisfy <tt>lower</tt> <= i <= <tt>upper</tt>.
+            \a useLowBits should be set to <tt>false</tt> when the engine generates
+            random numbers whose low bits are significantly less random than the high
+            bits. This does not apply to <tt>RandomTT800</tt> and <tt>RandomMT19937</tt>,
+            but is necessary for simpler linear congruential generators.
+        */
+    UniformIntRandomFunctor(UInt32 lower, UInt32 upper, 
+                            Engine const & generator = Engine::global(),
+                            bool useLowBits = true)
+    : lower_(lower), difference_(upper-lower), 
+      factor_(Engine::factorForUniformInt(difference_ + 1)),
+      generator_(generator),
+      useLowBits_(useLowBits)
+    {
+        vigra_precondition(lower < upper,
+          "UniformIntRandomFunctor(): lower bound must be smaller than upper bound."); 
+    }
+    
+        /** Return a random number as specified in the constructor.
+        */
+    UInt32 operator()() const
+    {
+        if(difference_ == 0xffffffff) // lower_ is necessarily 0
+            return generator_();
+        else if(useLowBits_)
+            return generator_.uniformInt(difference_+1) + lower_;
+        else
+        {
+            UInt32 res = generator_() / factor_;
+
+            // Use rejection method to avoid quantization bias.
+            // On average, we will need two raw random numbers to generate one.
+            while(res > difference_)
+                res = generator_() / factor_;
+            return res + lower_;
+        }
+    }
+
+        /** Return a uniformly distributed integer random number in the range [0, <tt>beyond</tt>).
+        
+            That is, 0 <= i < <tt>beyond</tt>. This is a required interface for 
+            <tt>std::random_shuffle</tt>. It ignores the limits specified 
+            in the constructor and the flag <tt>useLowBits</tt>.
+        */
+    UInt32 operator()(UInt32 beyond) const
+    {
+        if(beyond < 2)
+            return 0;
+
+        return generator_.uniformInt(beyond);
+    }
+};
+
+template <class Engine>
+class FunctorTraits<UniformIntRandomFunctor<Engine> >
+{
+  public:
+    typedef UniformIntRandomFunctor<Engine> type;
+    
+    typedef VigraTrueType  isInitializer;
+    
+    typedef VigraTrueType  isUnaryFunctor;
+    typedef VigraFalseType isBinaryFunctor;
+    typedef VigraFalseType isTernaryFunctor;
+    
+    typedef VigraFalseType isUnaryAnalyser;
+    typedef VigraFalseType isBinaryAnalyser;
+    typedef VigraFalseType isTernaryAnalyser;
+};
+
+/** Functor to create uniformly distributed double-precision random numbers.
+
+    This functor encapsulates the function <tt>uniform()</tt> of the given random number
+    <tt>Engine</tt> (usually <tt>RandomTT800</tt> or <tt>RandomMT19937</tt>)
+    in an STL-compatible interface. 
+    
+    <b>Traits defined:</b>
+    
+    \verbatim FunctorTraits<UniformIntRandomFunctor<Engine> >::isInitializer \endverbatim
+    is true (<tt>VigraTrueType</tt>).
+*/
+template <class Engine = MersenneTwister>
+class UniformRandomFunctor
+{
+    double offset_, scale_;
+    Engine const & generator_;
+
+  public:
+  
+    typedef double result_type; ///< STL required functor result type
+
+        /** Create functor for uniform random double-precision numbers in the range [0.0, 1.0] 
+            using the given engine.
+            
+            That is, the generated numbers satisfy 0.0 <= i <= 1.0.
+        */
+    UniformRandomFunctor(Engine const & generator = Engine::global())
+    : offset_(0.0),
+      scale_(1.0),
+      generator_(generator)
+    {}
+
+        /** Create functor for uniform random double-precision numbers in the range [<tt>lower</tt>, <tt>upper</tt>]
+            using the given engine.
+            
+            That is, the generated numbers satisfy <tt>lower</tt> <= i <= <tt>upper</tt>.
+        */
+    UniformRandomFunctor(double lower, double upper, 
+                         Engine & generator = Engine::global())
+    : offset_(lower),
+      scale_(upper - lower),
+      generator_(generator)
+    {
+        vigra_precondition(lower < upper,
+          "UniformRandomFunctor(): lower bound must be smaller than upper bound."); 
+    }
+    
+        /** Return a random number as specified in the constructor.
+        */
+    double operator()() const
+    {
+        return generator_.uniform() * scale_ + offset_;
+    }
+};
+
+template <class Engine>
+class FunctorTraits<UniformRandomFunctor<Engine> >
+{
+  public:
+    typedef UniformRandomFunctor<Engine> type;
+    
+    typedef VigraTrueType  isInitializer;
+    
+    typedef VigraFalseType isUnaryFunctor;
+    typedef VigraFalseType isBinaryFunctor;
+    typedef VigraFalseType isTernaryFunctor;
+    
+    typedef VigraFalseType isUnaryAnalyser;
+    typedef VigraFalseType isBinaryAnalyser;
+    typedef VigraFalseType isTernaryAnalyser;
+};
+
+/** Functor to create normal variate random numbers.
+
+    This functor encapsulates the function <tt>normal()</tt> of the given random number
+    <tt>Engine</tt> (usually <tt>RandomTT800</tt> or <tt>RandomMT19937</tt>)
+    in an STL-compatible interface. 
+    
+    <b>Traits defined:</b>
+    
+    \verbatim FunctorTraits<UniformIntRandomFunctor<Engine> >::isInitializer \endverbatim
+    is true (<tt>VigraTrueType</tt>).
+*/
+template <class Engine = MersenneTwister>
+class NormalRandomFunctor
+{
+    double mean_, stddev_;
+    Engine const & generator_;
+
+  public:
+  
+    typedef double result_type; ///< STL required functor result type
+
+        /** Create functor for standard normal random numbers 
+            using the given engine.
+            
+            That is, mean is 0.0 and standard deviation is 1.0.
+        */
+    NormalRandomFunctor(Engine const & generator = Engine::global())
+    : mean_(0.0),
+      stddev_(1.0),
+      generator_(generator)
+    {}
+
+        /** Create functor for normal random numbers with given mean and standard deviation
+            using the given engine.
+        */
+    NormalRandomFunctor(double mean, double stddev, 
+                        Engine & generator = Engine::global())
+    : mean_(mean),
+      stddev_(stddev),
+      generator_(generator)
+    {
+        vigra_precondition(stddev > 0.0,
+          "NormalRandomFunctor(): standard deviation must be positive."); 
+    }
+    
+        /** Return a random number as specified in the constructor.
+        */
+    double operator()() const
+    {
+        return generator_.normal() * stddev_ + mean_;
+    }
+
+};
+
+template <class Engine>
+class FunctorTraits<NormalRandomFunctor<Engine> >
+{
+  public:
+    typedef UniformRandomFunctor<Engine>  type;
+    
+    typedef VigraTrueType  isInitializer;
+    
+    typedef VigraFalseType isUnaryFunctor;
+    typedef VigraFalseType isBinaryFunctor;
+    typedef VigraFalseType isTernaryFunctor;
+    
+    typedef VigraFalseType isUnaryAnalyser;
+    typedef VigraFalseType isBinaryAnalyser;
+    typedef VigraFalseType isTernaryAnalyser;
+};
+
+//@}
+
+} // namespace vigra 
+
+#endif // VIGRA_RANDOM_HXX
diff --git a/include/vigra/random_forest.hxx b/include/vigra/random_forest.hxx
new file mode 100644
index 0000000..940f1bc
--- /dev/null
+++ b/include/vigra/random_forest.hxx
@@ -0,0 +1,1383 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by  Ullrich Koethe and Rahul Nair         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_RANDOM_FOREST_HXX
+#define VIGRA_RANDOM_FOREST_HXX
+
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <set>
+#include <list>
+#include <numeric>
+#include "mathutil.hxx"
+#include "array_vector.hxx"
+#include "sized_int.hxx"
+#include "matrix.hxx"
+#include "random.hxx"
+#include "functorexpression.hxx"
+#include "random_forest/rf_common.hxx"
+#include "random_forest/rf_nodeproxy.hxx"
+#include "random_forest/rf_split.hxx"
+#include "random_forest/rf_decisionTree.hxx"
+#include "random_forest/rf_visitors.hxx"
+#include "random_forest/rf_region.hxx"
+#include "sampling.hxx"
+#include "random_forest/rf_preprocessing.hxx"
+#include "random_forest/rf_online_prediction_set.hxx"
+#include "random_forest/rf_earlystopping.hxx"
+#include "random_forest/rf_ridge_split.hxx"
+namespace vigra
+{
+
+/** \addtogroup MachineLearning Machine Learning
+
+    This module provides classification algorithms that map 
+    features to labels or label probabilities.
+    Look at the RandomForest class first for a overview of most of the 
+    functionality provided as well as use cases. 
+**/
+//@{
+
+namespace detail
+{
+
+
+
+/* \brief sampling option factory function
+ */
+inline SamplerOptions make_sampler_opt ( RandomForestOptions     & RF_opt)
+{
+    SamplerOptions return_opt;
+    return_opt.withReplacement(RF_opt.sample_with_replacement_);
+    return_opt.stratified(RF_opt.stratification_method_ == RF_EQUAL);
+    return return_opt;
+}
+}//namespace detail
+
+/** Random Forest class
+ *
+ * \tparam <LabelType = double> Type used for predicted labels.
+ * \tparam <PreprocessorTag = ClassificationTag> Class used to preprocess
+ *          the input while learning and predicting. Currently Available:
+ *          ClassificationTag and RegressionTag. It is recommended to use
+ *          Splitfunctor::Preprocessor_t while using custom splitfunctors
+ *          as they may need the data to be in a different format. 
+ *          \sa Preprocessor
+ *  
+ *  Simple usage for classification (regression is not yet supported):
+ *  look at RandomForest::learn() as well as RandomForestOptions() for additional
+ *  options. 
+ *
+ *  \code
+ *  using namespace vigra;
+ *  using namespace rf;
+ *  typedef xxx feature_t; \\ replace xxx with whichever type
+ *  typedef yyy label_t;   \\ likewise 
+ *  
+ *  // allocate the training data
+ *  MultiArrayView<2, feature_t> f = get_training_features();
+ *  MultiArrayView<2, label_t>   l = get_training_labels();
+ *  
+ *  RandomForest<label_t> rf;
+ *
+ *  // construct visitor to calculate out-of-bag error
+ *  visitors::OOB_Error oob_v;
+ *
+ *  // perform training
+ *  rf.learn(f, l, visitors::create_visitor(oob_v));
+ *
+ *  std::cout << "the out-of-bag error is: " << oob_v.oob_breiman << "\n";
+ *      
+ *  // get features for new data to be used for prediction
+ *  MultiArrayView<2, feature_t> pf = get_features();
+ *
+ *  // allocate space for the response (pf.shape(0) is the number of samples)
+ *  MultiArrayView<2, label_t> prediction(pf.shape(0), 1);
+ *  MultiArrayView<2, double> prob(pf.shape(0), rf.class_count());
+ *      
+ *  // perform prediction on new data
+ *  rf.predictLabels(pf, prediction);
+ *  rf.predictProbabilities(pf, prob);
+ *
+ *  \endcode
+ *
+ *  Additional information such as Variable Importance measures are accessed
+ *  via Visitors defined in rf::visitors. 
+ *  Have a look at rf::split for other splitting methods.
+ *
+*/
+template <class LabelType = double , class PreprocessorTag = ClassificationTag >
+class RandomForest
+{
+
+  public:
+    //public typedefs
+    typedef RandomForestOptions             Options_t;
+    typedef detail::DecisionTree            DecisionTree_t;
+    typedef ProblemSpec<LabelType>          ProblemSpec_t;
+    typedef GiniSplit                       Default_Split_t;
+    typedef EarlyStoppStd                   Default_Stop_t;
+    typedef rf::visitors::StopVisiting      Default_Visitor_t;
+    typedef  DT_StackEntry<ArrayVectorView<Int32>::iterator>
+                    StackEntry_t;
+    typedef LabelType                       LabelT; 
+
+    //problem independent data.
+    Options_t                                   options_;
+    //problem dependent data members - is only set if
+    //a copy constructor, some sort of import
+    //function or the learn function is called
+    ArrayVector<DecisionTree_t>                 trees_;
+    ProblemSpec_t                               ext_param_;
+    /*mutable ArrayVector<int>                    tree_indices_;*/
+    rf::visitors::OnlineLearnVisitor            online_visitor_;
+
+
+    void reset()
+    {
+        ext_param_.clear();
+        trees_.clear();
+    }
+
+  public:
+
+    /** \name Constructors
+     * Note: No copy Constructor specified as no pointers are manipulated
+     * in this class
+     */
+    /*\{*/
+    /**\brief default constructor
+     *
+     * \param options   general options to the Random Forest. Must be of Type
+     *                  Options_t
+     * \param ext_param problem specific values that can be supplied 
+     *                  additionally. (class weights , labels etc)
+     * \sa  RandomForestOptions, ProblemSpec
+     *
+     */
+    RandomForest(Options_t const & options = Options_t(), 
+                 ProblemSpec_t const & ext_param = ProblemSpec_t())
+    :
+        options_(options),
+        ext_param_(ext_param)/*,
+        tree_indices_(options.tree_count_,0)*/
+    {
+        /*for(int ii = 0 ; ii < int(tree_indices_.size()); ++ii)
+            tree_indices_[ii] = ii;*/
+    }
+
+    /**\brief Create RF from external source
+     * \param treeCount Number of trees to add.
+     * \param topology_begin     
+     *                  Iterator to a Container where the topology_ data
+     *                  of the trees are stored.
+     *                  Iterator should support at least treeCount forward 
+     *                  iterations. (i.e. topology_end - topology_begin >= treeCount
+     * \param parameter_begin  
+     *                  iterator to a Container where the parameters_ data
+     *                  of the trees are stored. Iterator should support at 
+     *                  least treeCount forward iterations.
+     * \param problem_spec 
+     *                  Extrinsic parameters that specify the problem e.g.
+     *                  ClassCount, featureCount etc.
+     * \param options   (optional) specify options used to train the original
+     *                  Random forest. This parameter is not used anywhere
+     *                  during prediction and thus is optional.
+     *
+     */
+     /* TODO: This constructor may be replaced by a Constructor using
+     * NodeProxy iterators to encapsulate the underlying data type.
+     */
+    template<class TopologyIterator, class ParameterIterator>
+    RandomForest(int                       treeCount,
+                  TopologyIterator         topology_begin,
+                  ParameterIterator        parameter_begin,
+                  ProblemSpec_t const & problem_spec,
+                  Options_t const &     options = Options_t())
+    :
+        trees_(treeCount, DecisionTree_t(problem_spec)),
+        ext_param_(problem_spec),
+        options_(options)
+    {
+        for(unsigned int k=0; k<treeCount; ++k, ++topology_begin, ++parameter_begin)
+        {
+            trees_[k].topology_ = *topology_begin;
+            trees_[k].parameters_ = *parameter_begin;
+        }
+    }
+
+    /*\}*/
+
+
+    /** \name Data Access
+     * data access interface - usage of member variables is deprecated
+     */
+
+    /*\{*/
+
+
+    /**\brief return external parameters for viewing
+     * \return ProblemSpec_t
+     */
+    ProblemSpec_t const & ext_param() const
+    {
+        vigra_precondition(ext_param_.used() == true,
+           "RandomForest::ext_param(): "
+           "Random forest has not been trained yet.");
+        return ext_param_;
+    }
+
+    /**\brief set external parameters
+     *
+     *  \param in external parameters to be set
+     *
+     * set external parameters explicitly. 
+     * If Random Forest has not been trained the preprocessor will 
+     * either ignore filling values set this way or will throw an exception 
+     * if values specified manually do not match the value calculated 
+     & during the preparation step.
+     */
+    void set_ext_param(ProblemSpec_t const & in)
+    {
+        vigra_precondition(ext_param_.used() == false,
+            "RandomForest::set_ext_param():"
+            "Random forest has been trained! Call reset()"
+            "before specifying new extrinsic parameters.");
+    }
+
+    /**\brief access random forest options
+     *
+     * \return random forest options
+     */
+    Options_t & set_options()
+    {
+        return options_;
+    }
+
+
+    /**\brief access const random forest options
+     *
+     * \return const Option_t
+     */
+    Options_t const & options() const
+    {
+        return options_;
+    }
+
+    /**\brief access const trees
+     */
+    DecisionTree_t const & tree(int index) const
+    {
+        return trees_[index];
+    }
+
+    /**\brief access trees
+     */
+    DecisionTree_t & tree(int index)
+    {
+        return trees_[index];
+    }
+
+    /*\}*/
+
+    /**\brief return number of features used while 
+     * training.
+     */
+    int feature_count() const
+    {
+      return ext_param_.column_count_;
+    }
+    
+    
+    /**\brief return number of features used while 
+     * training.
+     *
+     * deprecated. Use feature_count() instead.
+     */
+    int column_count() const
+    {
+      return ext_param_.column_count_;
+    }
+
+    /**\brief return number of classes used while 
+     * training.
+     */
+    int class_count() const
+    {
+      return ext_param_.class_count_;
+    }
+
+    /**\brief return number of trees
+     */
+    int tree_count() const
+    {
+      return options_.tree_count_;
+    }
+
+
+    
+    template<class U,class C1,
+        class U2, class C2,
+        class Split_t,
+        class Stop_t,
+        class Visitor_t,
+        class Random_t>
+    void onlineLearn(   MultiArrayView<2,U,C1> const & features,
+                        MultiArrayView<2,U2,C2> const & response,
+                        int new_start_index,
+                        Visitor_t visitor_,
+                        Split_t split_,
+                        Stop_t stop_,
+                        Random_t & random,
+                        bool adjust_thresholds=false);
+
+    template <class U, class C1, class U2,class C2>
+    void onlineLearn(   MultiArrayView<2, U, C1> const  & features,
+                        MultiArrayView<2, U2,C2> const  & labels,int new_start_index,bool adjust_thresholds=false)
+    {
+        RandomNumberGenerator<> rnd = RandomNumberGenerator<>(RandomSeed);
+        onlineLearn(features, 
+                    labels, 
+                    new_start_index,
+                    rf_default(), 
+                    rf_default(), 
+                    rf_default(),
+                    rnd,
+                    adjust_thresholds);
+    }
+
+    template<class U,class C1,
+        class U2, class C2,
+        class Split_t,
+        class Stop_t,
+        class Visitor_t,
+        class Random_t>
+    void reLearnTree(MultiArrayView<2,U,C1> const & features,
+                     MultiArrayView<2,U2,C2> const & response,
+                     int treeId,
+                     Visitor_t visitor_,
+                     Split_t split_,
+                     Stop_t stop_,
+                     Random_t & random);
+
+    template<class U, class C1, class U2, class C2>
+    void reLearnTree(MultiArrayView<2, U, C1> const & features,
+                     MultiArrayView<2, U2, C2> const & labels,
+                     int treeId)
+    {
+        RandomNumberGenerator<> rnd = RandomNumberGenerator<>(RandomSeed);
+        reLearnTree(features,
+                    labels,
+                    treeId,
+                    rf_default(),
+                    rf_default(),
+                    rf_default(),
+                    rnd);
+    }
+
+
+    /**\name Learning
+     * Following functions differ in the degree of customization
+     * allowed
+     */
+    /*\{*/
+    /**\brief learn on data with custom config and random number generator
+     *
+     * \param features  a N x M matrix containing N samples with M
+     *                  features
+     * \param response  a N x D matrix containing the corresponding
+     *                  response. Current split functors assume D to
+     *                  be 1 and ignore any additional columns.
+     *                  This is not enforced to allow future support
+     *                  for uncertain labels, label independent strata etc.
+     *                  The Preprocessor specified during construction
+     *                  should be able to handle features and labels
+     *                  features and the labels.
+     *                  see also: SplitFunctor, Preprocessing
+     *
+     * \param visitor   visitor which is to be applied after each split,
+     *                  tree and at the end. Use rf_default() for using
+     *                  default value. (No Visitors)
+     *                  see also: rf::visitors
+     * \param split     split functor to be used to calculate each split
+     *                  use rf_default() for using default value. (GiniSplit)
+     *                  see also:  rf::split 
+     * \param stop
+     *                  predicate to be used to calculate each split
+     *                  use rf_default() for using default value. (EarlyStoppStd)
+     * \param random    RandomNumberGenerator to be used. Use
+     *                  rf_default() to use default value.(RandomMT19337)
+     *
+     *
+     */
+    template <class U, class C1,
+             class U2,class C2,
+             class Split_t,
+             class Stop_t,
+             class Visitor_t,
+             class Random_t>
+    void learn( MultiArrayView<2, U, C1> const  &   features,
+                MultiArrayView<2, U2,C2> const  &   response,
+                Visitor_t                           visitor,
+                Split_t                             split,
+                Stop_t                              stop,
+                Random_t                 const  &   random);
+
+    template <class U, class C1,
+             class U2,class C2,
+             class Split_t,
+             class Stop_t,
+             class Visitor_t>
+    void learn( MultiArrayView<2, U, C1> const  &   features,
+                MultiArrayView<2, U2,C2> const  &   response,
+                Visitor_t                           visitor,
+                Split_t                             split,
+                Stop_t                              stop)
+
+    {
+        RandomNumberGenerator<> rnd = RandomNumberGenerator<>(RandomSeed);
+        learn(  features, 
+                response,
+                visitor, 
+                split, 
+                stop,
+                rnd);
+    }
+
+    template <class U, class C1, class U2,class C2, class Visitor_t>
+    void learn( MultiArrayView<2, U, C1> const  & features,
+                MultiArrayView<2, U2,C2> const  & labels,
+                Visitor_t                         visitor)
+    {
+        learn(  features, 
+                labels, 
+                visitor, 
+                rf_default(), 
+                rf_default());
+    }
+
+    template <class U, class C1, class U2,class C2, 
+              class Visitor_t, class Split_t>
+    void learn(   MultiArrayView<2, U, C1> const  & features,
+                  MultiArrayView<2, U2,C2> const  & labels,
+                  Visitor_t                         visitor,
+                  Split_t                           split)
+    {
+        learn(  features, 
+                labels, 
+                visitor, 
+                split, 
+                rf_default());
+    }
+
+    /**\brief learn on data with default configuration
+     *
+     * \param features  a N x M matrix containing N samples with M
+     *                  features
+     * \param labels    a N x D matrix containing the corresponding
+     *                  N labels. Current split functors assume D to
+     *                  be 1 and ignore any additional columns.
+     *                  this is not enforced to allow future support
+     *                  for uncertain labels.
+     *
+     * learning is done with:
+     *
+     * \sa rf::split, EarlyStoppStd
+     *
+     * - Randomly seeded random number generator
+     * - default gini split functor as described by Breiman
+     * - default The standard early stopping criterion
+     */
+    template <class U, class C1, class U2,class C2>
+    void learn(   MultiArrayView<2, U, C1> const  & features,
+                    MultiArrayView<2, U2,C2> const  & labels)
+    {
+        learn(  features, 
+                labels, 
+                rf_default(), 
+                rf_default(), 
+                rf_default());
+    }
+    /*\}*/
+
+
+
+    /**\name prediction
+     */
+    /*\{*/
+    /** \brief predict a label given a feature.
+     *
+     * \param features: a 1 by featureCount matrix containing
+     *        data point to be predicted (this only works in
+     *        classification setting)
+     * \param stop: early stopping criterion
+     * \return double value representing class. You can use the
+     *         predictLabels() function together with the
+     *         rf.external_parameter().class_type_ attribute
+     *         to get back the same type used during learning. 
+     */
+    template <class U, class C, class Stop>
+    LabelType predictLabel(MultiArrayView<2, U, C>const & features, Stop & stop) const;
+
+    template <class U, class C>
+    LabelType predictLabel(MultiArrayView<2, U, C>const & features)
+    {
+        return predictLabel(features, rf_default()); 
+    } 
+    /** \brief predict a label with features and class priors
+     *
+     * \param features: same as above.
+     * \param prior:   iterator to prior weighting of classes
+     * \return sam as above.
+     */
+    template <class U, class C>
+    LabelType predictLabel(MultiArrayView<2, U, C> const & features,
+                                ArrayVectorView<double> prior) const;
+
+    /** \brief predict multiple labels with given features
+     *
+     * \param features: a n by featureCount matrix containing
+     *        data point to be predicted (this only works in
+     *        classification setting)
+     * \param labels: a n by 1 matrix passed by reference to store
+     *        output.
+     *
+     * If the input contains an NaN value, an precondition exception is thrown.
+     */
+    template <class U, class C1, class T, class C2>
+    void predictLabels(MultiArrayView<2, U, C1>const & features,
+                       MultiArrayView<2, T, C2> & labels) const
+    {
+        vigra_precondition(features.shape(0) == labels.shape(0),
+            "RandomForest::predictLabels(): Label array has wrong size.");
+        for(int k=0; k<features.shape(0); ++k)
+        {
+            vigra_precondition(!detail::contains_nan(rowVector(features, k)),
+                "RandomForest::predictLabels(): NaN in feature matrix.");
+            labels(k,0) = detail::RequiresExplicitCast<T>::cast(predictLabel(rowVector(features, k), rf_default()));
+        }
+    }
+
+    /** \brief predict multiple labels with given features
+     *
+     * \param features: a n by featureCount matrix containing
+     *        data point to be predicted (this only works in
+     *        classification setting)
+     * \param labels: a n by 1 matrix passed by reference to store
+     *        output.
+     * \param nanLabel: label to be returned for the row of the input that
+     *        contain an NaN value.
+     */
+    template <class U, class C1, class T, class C2>
+    void predictLabels(MultiArrayView<2, U, C1>const & features,
+                       MultiArrayView<2, T, C2> & labels,
+                       LabelType nanLabel) const
+    {
+        vigra_precondition(features.shape(0) == labels.shape(0),
+            "RandomForest::predictLabels(): Label array has wrong size.");
+        for(int k=0; k<features.shape(0); ++k)
+        {
+            if(detail::contains_nan(rowVector(features, k)))
+                labels(k,0) = nanLabel;
+            else
+                labels(k,0) = detail::RequiresExplicitCast<T>::cast(predictLabel(rowVector(features, k), rf_default()));
+        }
+    }
+
+    /** \brief predict multiple labels with given features
+     *
+     * \param features: a n by featureCount matrix containing
+     *        data point to be predicted (this only works in
+     *        classification setting)
+     * \param labels: a n by 1 matrix passed by reference to store
+     *        output.
+     * \param stop: an early stopping criterion.
+     */
+    template <class U, class C1, class T, class C2, class Stop>
+    void predictLabels(MultiArrayView<2, U, C1>const & features,
+                       MultiArrayView<2, T, C2> & labels,
+                       Stop                     & stop) const
+    {
+        vigra_precondition(features.shape(0) == labels.shape(0),
+            "RandomForest::predictLabels(): Label array has wrong size.");
+        for(int k=0; k<features.shape(0); ++k)
+            labels(k,0) = detail::RequiresExplicitCast<T>::cast(predictLabel(rowVector(features, k), stop));
+    }
+    /** \brief predict the class probabilities for multiple labels
+     *
+     *  \param features same as above
+     *  \param prob a n x class_count_ matrix. passed by reference to
+     *  save class probabilities
+     *  \param stop earlystopping criterion
+     *  \sa EarlyStopping
+     
+        When a row of the feature array contains an NaN, the corresponding instance
+        cannot belong to any of the classes. The corresponding row in the probability 
+        array will therefore contain all zeros.
+     */
+    template <class U, class C1, class T, class C2, class Stop>
+    void predictProbabilities(MultiArrayView<2, U, C1>const &   features,
+                              MultiArrayView<2, T, C2> &        prob,
+                              Stop                     &        stop) const;
+    template <class T1,class T2, class C>
+    void predictProbabilities(OnlinePredictionSet<T1> &  predictionSet,
+                               MultiArrayView<2, T2, C> &       prob);
+
+    /** \brief predict the class probabilities for multiple labels
+     *
+     *  \param features same as above
+     *  \param prob a n x class_count_ matrix. passed by reference to
+     *  save class probabilities
+     */
+    template <class U, class C1, class T, class C2>
+    void predictProbabilities(MultiArrayView<2, U, C1>const &   features,
+                              MultiArrayView<2, T, C2> &        prob)  const
+    {
+        predictProbabilities(features, prob, rf_default()); 
+    }   
+
+    template <class U, class C1, class T, class C2>
+    void predictRaw(MultiArrayView<2, U, C1>const &   features,
+                    MultiArrayView<2, T, C2> &        prob)  const;
+
+
+    /*\}*/
+
+};
+
+
+template <class LabelType, class PreprocessorTag>
+template<class U,class C1,
+    class U2, class C2,
+    class Split_t,
+    class Stop_t,
+    class Visitor_t,
+    class Random_t>
+void RandomForest<LabelType, PreprocessorTag>::onlineLearn(MultiArrayView<2,U,C1> const & features,
+                                                             MultiArrayView<2,U2,C2> const & response,
+                                                             int new_start_index,
+                                                             Visitor_t visitor_,
+                                                             Split_t split_,
+                                                             Stop_t stop_,
+                                                             Random_t & random,
+                                                             bool adjust_thresholds)
+{
+    online_visitor_.activate();
+    online_visitor_.adjust_thresholds=adjust_thresholds;
+
+    using namespace rf;
+    //typedefs
+    typedef Processor<PreprocessorTag,LabelType,U,C1,U2,C2> Preprocessor_t;
+    typedef          UniformIntRandomFunctor<Random_t>
+                                                    RandFunctor_t;
+    // default values and initialization
+    // Value Chooser chooses second argument as value if first argument
+    // is of type RF_DEFAULT. (thanks to template magic - don't care about
+    // it - just smile and wave.
+    
+    #define RF_CHOOSER(type_) detail::Value_Chooser<type_, Default_##type_> 
+    Default_Stop_t default_stop(options_);
+    typename RF_CHOOSER(Stop_t)::type stop
+            = RF_CHOOSER(Stop_t)::choose(stop_, default_stop); 
+    Default_Split_t default_split;
+    typename RF_CHOOSER(Split_t)::type split 
+            = RF_CHOOSER(Split_t)::choose(split_, default_split); 
+    rf::visitors::StopVisiting stopvisiting;
+    typedef  rf::visitors::detail::VisitorNode
+                <rf::visitors::OnlineLearnVisitor, 
+                 typename RF_CHOOSER(Visitor_t)::type> 
+                                                        IntermedVis; 
+    IntermedVis
+        visitor(online_visitor_, RF_CHOOSER(Visitor_t)::choose(visitor_, stopvisiting));
+    #undef RF_CHOOSER
+    vigra_precondition(options_.prepare_online_learning_,"onlineLearn: online learning must be enabled on RandomForest construction");
+
+    // Preprocess the data to get something the split functor can work
+    // with. Also fill the ext_param structure by preprocessing
+    // option parameters that could only be completely evaluated
+    // when the training data is known.
+    ext_param_.class_count_=0;
+    Preprocessor_t preprocessor(    features, response,
+                                    options_, ext_param_);
+
+    // Make stl compatible random functor.
+    RandFunctor_t           randint     ( random);
+
+    // Give the Split functor information about the data.
+    split.set_external_parameters(ext_param_);
+    stop.set_external_parameters(ext_param_);
+
+
+    //Create poisson samples
+    PoissonSampler<RandomTT800> poisson_sampler(1.0,vigra::Int32(new_start_index),vigra::Int32(ext_param().row_count_));
+
+    //TODO: visitors for online learning
+    //visitor.visit_at_beginning(*this, preprocessor);
+
+    // THE MAIN EFFING RF LOOP - YEAY DUDE!
+    for(int ii = 0; ii < (int)trees_.size(); ++ii)
+    {
+        online_visitor_.tree_id=ii;
+        poisson_sampler.sample();
+        std::map<int,int> leaf_parents;
+        leaf_parents.clear();
+        //Get all the leaf nodes for that sample
+        for(int s=0;s<poisson_sampler.numOfSamples();++s)
+        {
+            int sample=poisson_sampler[s];
+            online_visitor_.current_label=preprocessor.response()(sample,0);
+            online_visitor_.last_node_id=StackEntry_t::DecisionTreeNoParent;
+            int leaf=trees_[ii].getToLeaf(rowVector(features,sample),online_visitor_);
+
+
+            //Add to the list for that leaf
+            online_visitor_.add_to_index_list(ii,leaf,sample);
+            //TODO: Class count?
+            //Store parent
+            if(Node<e_ConstProbNode>(trees_[ii].topology_,trees_[ii].parameters_,leaf).prob_begin()[preprocessor.response()(sample,0)]!=1.0)
+            {
+                leaf_parents[leaf]=online_visitor_.last_node_id;
+            }
+        }
+
+
+        std::map<int,int>::iterator leaf_iterator;
+        for(leaf_iterator=leaf_parents.begin();leaf_iterator!=leaf_parents.end();++leaf_iterator)
+        {
+            int leaf=leaf_iterator->first;
+            int parent=leaf_iterator->second;
+            int lin_index=online_visitor_.trees_online_information[ii].exterior_to_index[leaf];
+            ArrayVector<Int32> indeces;
+            indeces.clear();
+            indeces.swap(online_visitor_.trees_online_information[ii].index_lists[lin_index]);
+            StackEntry_t stack_entry(indeces.begin(),
+                                     indeces.end(),
+                                     ext_param_.class_count_);
+
+
+            if(parent!=-1)
+            {
+                if(NodeBase(trees_[ii].topology_,trees_[ii].parameters_,parent).child(0)==leaf)
+                {
+                    stack_entry.leftParent=parent;
+                }
+                else
+                {
+                    vigra_assert(NodeBase(trees_[ii].topology_,trees_[ii].parameters_,parent).child(1)==leaf,"last_node_id seems to be wrong");
+                    stack_entry.rightParent=parent;
+                }
+            }
+            //trees_[ii].continueLearn(preprocessor.features(),preprocessor.response(),stack_entry,split,stop,visitor,randint,leaf);
+            trees_[ii].continueLearn(preprocessor.features(),preprocessor.response(),stack_entry,split,stop,visitor,randint,-1);
+            //Now, the last one moved onto leaf
+            online_visitor_.move_exterior_node(ii,trees_[ii].topology_.size(),ii,leaf);
+            //Now it should be classified correctly!
+        }
+
+        /*visitor
+            .visit_after_tree(  *this,
+                                preprocessor,
+                                poisson_sampler,
+                                stack_entry,
+                                ii);*/
+    }
+
+    //visitor.visit_at_end(*this, preprocessor);
+    online_visitor_.deactivate();
+}
+
+template<class LabelType, class PreprocessorTag>
+template<class U,class C1,
+    class U2, class C2,
+    class Split_t,
+    class Stop_t,
+    class Visitor_t,
+    class Random_t>
+void RandomForest<LabelType, PreprocessorTag>::reLearnTree(MultiArrayView<2,U,C1> const & features,
+                 MultiArrayView<2,U2,C2> const & response,
+                 int treeId,
+                 Visitor_t visitor_,
+                 Split_t split_,
+                 Stop_t stop_,
+                 Random_t & random)
+{
+    using namespace rf;
+    
+    
+    typedef          UniformIntRandomFunctor<Random_t>
+                                                    RandFunctor_t;
+
+    // See rf_preprocessing.hxx for more info on this
+    ext_param_.class_count_=0;
+    typedef Processor<PreprocessorTag,LabelType, U, C1, U2, C2> Preprocessor_t;
+    
+    // default values and initialization
+    // Value Chooser chooses second argument as value if first argument
+    // is of type RF_DEFAULT. (thanks to template magic - don't care about
+    // it - just smile and wave.
+    
+    #define RF_CHOOSER(type_) detail::Value_Chooser<type_, Default_##type_> 
+    Default_Stop_t default_stop(options_);
+    typename RF_CHOOSER(Stop_t)::type stop
+            = RF_CHOOSER(Stop_t)::choose(stop_, default_stop); 
+    Default_Split_t default_split;
+    typename RF_CHOOSER(Split_t)::type split 
+            = RF_CHOOSER(Split_t)::choose(split_, default_split); 
+    rf::visitors::StopVisiting stopvisiting;
+    typedef  rf::visitors::detail::VisitorNode
+                <rf::visitors::OnlineLearnVisitor, 
+                typename RF_CHOOSER(Visitor_t)::type> IntermedVis; 
+    IntermedVis
+        visitor(online_visitor_, RF_CHOOSER(Visitor_t)::choose(visitor_, stopvisiting));
+    #undef RF_CHOOSER
+    vigra_precondition(options_.prepare_online_learning_,"reLearnTree: Re learning trees only makes sense, if online learning is enabled");
+    online_visitor_.activate();
+
+    // Make stl compatible random functor.
+    RandFunctor_t           randint     ( random);
+
+    // Preprocess the data to get something the split functor can work
+    // with. Also fill the ext_param structure by preprocessing
+    // option parameters that could only be completely evaluated
+    // when the training data is known.
+    Preprocessor_t preprocessor(    features, response,
+                                    options_, ext_param_);
+
+    // Give the Split functor information about the data.
+    split.set_external_parameters(ext_param_);
+    stop.set_external_parameters(ext_param_);
+
+    /**\todo    replace this crappy class out. It uses function pointers.
+     *          and is making code slower according to me.
+     *          Comment from Nathan: This is copied from Rahul, so me=Rahul
+     */
+    Sampler<Random_t > sampler(preprocessor.strata().begin(),
+                               preprocessor.strata().end(),
+                               detail::make_sampler_opt(options_)
+                                        .sampleSize(ext_param().actual_msample_),
+                               &random);
+    //initialize First region/node/stack entry
+    sampler
+        .sample();
+
+    StackEntry_t
+        first_stack_entry(  sampler.sampledIndices().begin(),
+                            sampler.sampledIndices().end(),
+                            ext_param_.class_count_);
+    first_stack_entry
+        .set_oob_range(     sampler.oobIndices().begin(),
+                            sampler.oobIndices().end());
+    online_visitor_.reset_tree(treeId);
+    online_visitor_.tree_id=treeId;
+    trees_[treeId].reset();
+    trees_[treeId]
+        .learn( preprocessor.features(),
+                preprocessor.response(),
+                first_stack_entry,
+                split,
+                stop,
+                visitor,
+                randint);
+    visitor
+        .visit_after_tree(  *this,
+                            preprocessor,
+                            sampler,
+                            first_stack_entry,
+                            treeId);
+
+    online_visitor_.deactivate();
+}
+
+template <class LabelType, class PreprocessorTag>
+template <class U, class C1,
+         class U2,class C2,
+         class Split_t,
+         class Stop_t,
+         class Visitor_t,
+         class Random_t>
+void RandomForest<LabelType, PreprocessorTag>::
+                     learn( MultiArrayView<2, U, C1> const  &   features,
+                            MultiArrayView<2, U2,C2> const  &   response,
+                            Visitor_t                           visitor_,
+                            Split_t                             split_,
+                            Stop_t                              stop_,
+                            Random_t                 const  &   random)
+{
+    using namespace rf;
+    //this->reset();
+    //typedefs
+    typedef          UniformIntRandomFunctor<Random_t>
+                                                    RandFunctor_t;
+
+    // See rf_preprocessing.hxx for more info on this
+    typedef Processor<PreprocessorTag,LabelType, U, C1, U2, C2> Preprocessor_t;
+
+    vigra_precondition(features.shape(0) == response.shape(0),
+        "RandomForest::learn(): shape mismatch between features and response.");
+    
+    // default values and initialization
+    // Value Chooser chooses second argument as value if first argument
+    // is of type RF_DEFAULT. (thanks to template magic - don't care about
+    // it - just smile and wave).
+    
+    #define RF_CHOOSER(type_) detail::Value_Chooser<type_, Default_##type_> 
+    Default_Stop_t default_stop(options_);
+    typename RF_CHOOSER(Stop_t)::type stop
+            = RF_CHOOSER(Stop_t)::choose(stop_, default_stop); 
+    Default_Split_t default_split;
+    typename RF_CHOOSER(Split_t)::type split 
+            = RF_CHOOSER(Split_t)::choose(split_, default_split); 
+    rf::visitors::StopVisiting stopvisiting;
+    typedef  rf::visitors::detail::VisitorNode<
+                rf::visitors::OnlineLearnVisitor, 
+                typename RF_CHOOSER(Visitor_t)::type> IntermedVis; 
+    IntermedVis
+        visitor(online_visitor_, RF_CHOOSER(Visitor_t)::choose(visitor_, stopvisiting));
+    #undef RF_CHOOSER
+    if(options_.prepare_online_learning_)
+        online_visitor_.activate();
+    else
+        online_visitor_.deactivate();
+
+
+    // Make stl compatible random functor.
+    RandFunctor_t           randint     ( random);
+
+
+    // Preprocess the data to get something the split functor can work
+    // with. Also fill the ext_param structure by preprocessing
+    // option parameters that could only be completely evaluated
+    // when the training data is known.
+    Preprocessor_t preprocessor(    features, response,
+                                    options_, ext_param_);
+
+    // Give the Split functor information about the data.
+    split.set_external_parameters(ext_param_);
+    stop.set_external_parameters(ext_param_);
+
+
+    //initialize trees.
+    trees_.resize(options_.tree_count_  , DecisionTree_t(ext_param_));
+
+    Sampler<Random_t > sampler(preprocessor.strata().begin(),
+                               preprocessor.strata().end(),
+                               detail::make_sampler_opt(options_)
+                                        .sampleSize(ext_param().actual_msample_),
+                               &random);
+
+    visitor.visit_at_beginning(*this, preprocessor);
+    // THE MAIN EFFING RF LOOP - YEAY DUDE!
+    
+    for(int ii = 0; ii < (int)trees_.size(); ++ii)
+    {
+        //initialize First region/node/stack entry
+        sampler
+            .sample();  
+        StackEntry_t
+            first_stack_entry(  sampler.sampledIndices().begin(),
+                                sampler.sampledIndices().end(),
+                                ext_param_.class_count_);
+        first_stack_entry
+            .set_oob_range(     sampler.oobIndices().begin(),
+                                sampler.oobIndices().end());
+        trees_[ii]
+            .learn(             preprocessor.features(),
+                                preprocessor.response(),
+                                first_stack_entry,
+                                split,
+                                stop,
+                                visitor,
+                                randint);
+        visitor
+            .visit_after_tree(  *this,
+                                preprocessor,
+                                sampler,
+                                first_stack_entry,
+                                ii);
+    }
+
+    visitor.visit_at_end(*this, preprocessor);
+    // Only for online learning?
+    online_visitor_.deactivate();
+}
+
+
+
+
+template <class LabelType, class Tag>
+template <class U, class C, class Stop>
+LabelType RandomForest<LabelType, Tag>
+    ::predictLabel(MultiArrayView<2, U, C> const & features, Stop & stop) const
+{
+    vigra_precondition(columnCount(features) >= ext_param_.column_count_,
+        "RandomForestn::predictLabel():"
+            " Too few columns in feature matrix.");
+    vigra_precondition(rowCount(features) == 1,
+        "RandomForestn::predictLabel():"
+            " Feature matrix must have a singlerow.");
+    MultiArray<2, double> probabilities(Shape2(1, ext_param_.class_count_), 0.0);
+    LabelType          d;
+    predictProbabilities(features, probabilities, stop);
+    ext_param_.to_classlabel(argMax(probabilities), d);
+    return d;
+}
+
+
+//Same thing as above with priors for each label !!!
+template <class LabelType, class PreprocessorTag>
+template <class U, class C>
+LabelType RandomForest<LabelType, PreprocessorTag>
+    ::predictLabel( MultiArrayView<2, U, C> const & features,
+                    ArrayVectorView<double> priors) const
+{
+    using namespace functor;
+    vigra_precondition(columnCount(features) >= ext_param_.column_count_,
+        "RandomForestn::predictLabel(): Too few columns in feature matrix.");
+    vigra_precondition(rowCount(features) == 1,
+        "RandomForestn::predictLabel():"
+        " Feature matrix must have a single row.");
+    Matrix<double>  prob(1,ext_param_.class_count_);
+    predictProbabilities(features, prob);
+    std::transform( prob.begin(), prob.end(),
+                    priors.begin(), prob.begin(),
+                    Arg1()*Arg2());
+    LabelType          d;
+    ext_param_.to_classlabel(argMax(prob), d);
+    return d;
+}
+
+template<class LabelType,class PreprocessorTag>
+template <class T1,class T2, class C>
+void RandomForest<LabelType,PreprocessorTag>
+    ::predictProbabilities(OnlinePredictionSet<T1> &  predictionSet,
+                          MultiArrayView<2, T2, C> &       prob)
+{
+    //Features are n xp
+    //prob is n x NumOfLabel probability for each feature in each class
+    
+    vigra_precondition(rowCount(predictionSet.features) == rowCount(prob),
+                       "RandomFroest::predictProbabilities():"
+                       " Feature matrix and probability matrix size mismatch.");
+    // num of features must be bigger than num of features in Random forest training
+    // but why bigger?
+    vigra_precondition( columnCount(predictionSet.features) >= ext_param_.column_count_,
+      "RandomForestn::predictProbabilities():"
+        " Too few columns in feature matrix.");
+    vigra_precondition( columnCount(prob)
+                        == (MultiArrayIndex)ext_param_.class_count_,
+      "RandomForestn::predictProbabilities():"
+      " Probability matrix must have as many columns as there are classes.");
+    prob.init(0.0);
+    //store total weights
+    std::vector<T1> totalWeights(predictionSet.indices[0].size(),0.0);
+    //Go through all trees
+    int set_id=-1;
+    for(int k=0; k<options_.tree_count_; ++k)
+    {
+        set_id=(set_id+1) % predictionSet.indices[0].size();
+        typedef std::set<SampleRange<T1> > my_set;
+        typedef typename my_set::iterator set_it;
+        //typedef std::set<std::pair<int,SampleRange<T1> > >::iterator set_it;
+        //Build a stack with all the ranges we have
+        std::vector<std::pair<int,set_it> > stack;
+        stack.clear();
+        for(set_it i=predictionSet.ranges[set_id].begin();
+             i!=predictionSet.ranges[set_id].end();++i)
+            stack.push_back(std::pair<int,set_it>(2,i));
+        //get weights predicted by single tree
+        int num_decisions=0;
+        while(!stack.empty())
+        {
+            set_it range=stack.back().second;
+            int index=stack.back().first;
+            stack.pop_back();
+            ++num_decisions;
+
+            if(trees_[k].isLeafNode(trees_[k].topology_[index]))
+            {
+                ArrayVector<double>::iterator weights=Node<e_ConstProbNode>(trees_[k].topology_,
+                                                                            trees_[k].parameters_,
+                                                                            index).prob_begin();
+                for(int i=range->start;i!=range->end;++i)
+                {
+                    //update votecount.
+                    for(int l=0; l<ext_param_.class_count_; ++l)
+                    {
+                        prob(predictionSet.indices[set_id][i], l) += (T2)weights[l];
+                        //every weight in totalWeight.
+                        totalWeights[predictionSet.indices[set_id][i]] += (T1)weights[l];
+                    }
+                }
+            }
+
+            else
+            {
+                if(trees_[k].topology_[index]!=i_ThresholdNode)
+                {
+                    throw std::runtime_error("predicting with online prediction sets is only supported for RFs with threshold nodes");
+                }
+                Node<i_ThresholdNode> node(trees_[k].topology_,trees_[k].parameters_,index);
+                if(range->min_boundaries[node.column()]>=node.threshold())
+                {
+                    //Everything goes to right child
+                    stack.push_back(std::pair<int,set_it>(node.child(1),range));
+                    continue;
+                }
+                if(range->max_boundaries[node.column()]<node.threshold())
+                {
+                    //Everything goes to the left child
+                    stack.push_back(std::pair<int,set_it>(node.child(0),range));
+                    continue;
+                }
+                //We have to split at this node
+                SampleRange<T1> new_range=*range;
+                new_range.min_boundaries[node.column()]=FLT_MAX;
+                range->max_boundaries[node.column()]=-FLT_MAX;
+                new_range.start=new_range.end=range->end;
+                int i=range->start;
+                while(i!=range->end)
+                {
+                    //Decide for range->indices[i]
+                    if(predictionSet.features(predictionSet.indices[set_id][i],node.column())>=node.threshold())
+                    {
+                        new_range.min_boundaries[node.column()]=std::min(new_range.min_boundaries[node.column()],
+                                                                    predictionSet.features(predictionSet.indices[set_id][i],node.column()));
+                        --range->end;
+                        --new_range.start;
+                        std::swap(predictionSet.indices[set_id][i],predictionSet.indices[set_id][range->end]);
+
+                    }
+                    else
+                    {
+                        range->max_boundaries[node.column()]=std::max(range->max_boundaries[node.column()],
+                                                                 predictionSet.features(predictionSet.indices[set_id][i],node.column()));
+                        ++i;
+                    }
+                }
+                //The old one ...
+                if(range->start==range->end)
+                {
+                    predictionSet.ranges[set_id].erase(range);
+                }
+                else
+                {
+                    stack.push_back(std::pair<int,set_it>(node.child(0),range));
+                }
+                //And the new one ...
+                if(new_range.start!=new_range.end)
+                {
+                    std::pair<set_it,bool> new_it=predictionSet.ranges[set_id].insert(new_range);
+                    stack.push_back(std::pair<int,set_it>(node.child(1),new_it.first));
+                }
+            }
+        }
+        predictionSet.cumulativePredTime[k]=num_decisions;
+    }
+    for(unsigned int i=0;i<totalWeights.size();++i)
+    {
+        double test=0.0;
+        //Normalise votes in each row by total VoteCount (totalWeight
+        for(int l=0; l<ext_param_.class_count_; ++l)
+        {
+            test+=prob(i,l);
+            prob(i, l) /= totalWeights[i];
+        }
+        assert(test==totalWeights[i]);
+        assert(totalWeights[i]>0.0);
+    }
+}
+
+template <class LabelType, class PreprocessorTag>
+template <class U, class C1, class T, class C2, class Stop_t>
+void RandomForest<LabelType, PreprocessorTag>
+    ::predictProbabilities(MultiArrayView<2, U, C1>const &  features,
+                           MultiArrayView<2, T, C2> &       prob,
+                           Stop_t                   &       stop_) const
+{
+    //Features are n xp
+    //prob is n x NumOfLabel probability for each feature in each class
+
+    vigra_precondition(rowCount(features) == rowCount(prob),
+      "RandomForestn::predictProbabilities():"
+        " Feature matrix and probability matrix size mismatch.");
+
+    // num of features must be bigger than num of features in Random forest training
+    // but why bigger?
+    vigra_precondition( columnCount(features) >= ext_param_.column_count_,
+      "RandomForestn::predictProbabilities():"
+        " Too few columns in feature matrix.");
+    vigra_precondition( columnCount(prob)
+                        == (MultiArrayIndex)ext_param_.class_count_,
+      "RandomForestn::predictProbabilities():"
+      " Probability matrix must have as many columns as there are classes.");
+
+    #define RF_CHOOSER(type_) detail::Value_Chooser<type_, Default_##type_> 
+    Default_Stop_t default_stop(options_);
+    typename RF_CHOOSER(Stop_t)::type & stop
+            = RF_CHOOSER(Stop_t)::choose(stop_, default_stop); 
+    #undef RF_CHOOSER 
+    stop.set_external_parameters(ext_param_, tree_count());
+    prob.init(NumericTraits<T>::zero());
+    /* This code was originally there for testing early stopping
+     * - we wanted the order of the trees to be randomized
+    if(tree_indices_.size() != 0)
+    {
+       std::random_shuffle(tree_indices_.begin(),
+                           tree_indices_.end()); 
+    }
+    */
+    //Classify for each row.
+    for(int row=0; row < rowCount(features); ++row)
+    {
+        MultiArrayView<2, U, StridedArrayTag> currentRow(rowVector(features, row));
+        
+        // when the features contain an NaN, the instance doesn't belong to any class
+        // => indicate this by returning a zero probability array.
+        if(detail::contains_nan(currentRow))
+        {
+            rowVector(prob, row).init(0.0);
+            continue;
+        }
+    
+        ArrayVector<double>::const_iterator weights;
+
+        //totalWeight == totalVoteCount!
+        double totalWeight = 0.0;
+
+        //Let each tree classify...
+        for(int k=0; k<options_.tree_count_; ++k)
+        {
+            //get weights predicted by single tree
+            weights = trees_[k /*tree_indices_[k]*/].predict(currentRow);
+
+            //update votecount.
+            int weighted = options_.predict_weighted_;
+            for(int l=0; l<ext_param_.class_count_; ++l)
+            {
+                double cur_w = weights[l] * (weighted * (*(weights-1))
+                                           + (1-weighted));
+                prob(row, l) += (T)cur_w;
+                //every weight in totalWeight.
+                totalWeight += cur_w;
+            }
+            if(stop.after_prediction(weights, 
+                                     k,
+                                     rowVector(prob, row),
+                                     totalWeight))
+            {
+                break;
+            }
+        }
+
+        //Normalise votes in each row by total VoteCount (totalWeight
+        for(int l=0; l< ext_param_.class_count_; ++l)
+        {
+            prob(row, l) /= detail::RequiresExplicitCast<T>::cast(totalWeight);
+        }
+    }
+
+}
+
+template <class LabelType, class PreprocessorTag>
+template <class U, class C1, class T, class C2>
+void RandomForest<LabelType, PreprocessorTag>
+    ::predictRaw(MultiArrayView<2, U, C1>const &  features,
+                           MultiArrayView<2, T, C2> &       prob) const
+{
+    //Features are n xp
+    //prob is n x NumOfLabel probability for each feature in each class
+
+    vigra_precondition(rowCount(features) == rowCount(prob),
+      "RandomForestn::predictProbabilities():"
+        " Feature matrix and probability matrix size mismatch.");
+
+    // num of features must be bigger than num of features in Random forest training
+    // but why bigger?
+    vigra_precondition( columnCount(features) >= ext_param_.column_count_,
+      "RandomForestn::predictProbabilities():"
+        " Too few columns in feature matrix.");
+    vigra_precondition( columnCount(prob)
+                        == (MultiArrayIndex)ext_param_.class_count_,
+      "RandomForestn::predictProbabilities():"
+      " Probability matrix must have as many columns as there are classes.");
+
+    #define RF_CHOOSER(type_) detail::Value_Chooser<type_, Default_##type_> 
+    prob.init(NumericTraits<T>::zero());
+    /* This code was originally there for testing early stopping
+     * - we wanted the order of the trees to be randomized
+    if(tree_indices_.size() != 0)
+    {
+       std::random_shuffle(tree_indices_.begin(),
+                           tree_indices_.end()); 
+    }
+    */
+    //Classify for each row.
+    for(int row=0; row < rowCount(features); ++row)
+    {
+        ArrayVector<double>::const_iterator weights;
+
+        //totalWeight == totalVoteCount!
+        double totalWeight = 0.0;
+
+        //Let each tree classify...
+        for(int k=0; k<options_.tree_count_; ++k)
+        {
+            //get weights predicted by single tree
+            weights = trees_[k /*tree_indices_[k]*/].predict(rowVector(features, row));
+
+            //update votecount.
+            int weighted = options_.predict_weighted_;
+            for(int l=0; l<ext_param_.class_count_; ++l)
+            {
+                double cur_w = weights[l] * (weighted * (*(weights-1))
+                                           + (1-weighted));
+                prob(row, l) += (T)cur_w;
+                //every weight in totalWeight.
+                totalWeight += cur_w;
+            }
+        }
+    }
+    prob/= options_.tree_count_;
+
+}
+
+//@}
+
+} // namespace vigra
+
+#include "random_forest/rf_algorithm.hxx"
+#endif // VIGRA_RANDOM_FOREST_HXX
diff --git a/include/vigra/random_forest/features.hxx b/include/vigra/random_forest/features.hxx
new file mode 100644
index 0000000..d050785
--- /dev/null
+++ b/include/vigra/random_forest/features.hxx
@@ -0,0 +1,114 @@
+#ifndef RN_FEATURES_HXX
+#define RN_FEATURES_HXX
+
+
+
+
+
+class FeatureBase
+{
+public:
+    MultiArrayShape<2>::type shape() = 0;
+    int shape(int index)
+    {
+        return shape()[index];
+    }
+    double & operator() (int i, int j) = 0;
+};
+
+
+class CompositFeatures : public FeatureBase
+{
+public:
+    typedef typename MultiArrayShape<2>::type
+        Shp;
+    ArrayVector<Shp> 
+        ext2int;
+    ArrayVector<FeatureBase > sub_feats;
+    void add(FeatureBase & feat)
+    {
+        if(feat.shape(0) != this->shape(0))
+            throw std::runtime_error("Wrong Number Of samples");
+
+        sub_feats.push_back(feat);
+        for(int ii = 0; ii < feat.shape(1); ++ii)
+            ext2int.push_back(Shp(sub_feats.size()-1,
+                                  ii));
+
+    }
+
+    MultiArrayShape<2>::type shape()
+    {
+        return MultiArrayShape<2>::type(sub_feats[0].shape(0),
+                                        ext2int.size());
+    }
+
+    double & operator() (int i, int j)
+    {
+        return sub_feats[ext2int[j][0]](i, ext2int[j][1]);
+    }
+};
+
+template<int N, class T, class C>
+class NeighborFeatures : public FeatureBase
+{
+public:
+    typedef typename MultiArrayShape<N>::type Shp;
+    MultiArrayView<N, T, C> raw_data;
+    ArrayVector<Shp > 
+                            feat_coos;
+    MultiArrayShape<2>::type shape()
+    {
+        return MultiArrayShape<2>::type(raw_data.size(),
+                                        feat_coos.size());
+    }
+
+    double & operator() (int i, int j)
+    {
+        return raw_data(raw_data.scanOrderIndexToCoordinate(i) + feat_coos(j));
+    }
+    NeighborFeatures(MultiArrayView<N, T, C> & in, MultiArrayView<2, int> const & coos)
+        : raw_data(in)
+    {
+        for(int ii = 0; ii < coos.shape(0); ++ii)
+            feat_coos.push_back(Shp());
+            for(int jj = 0; jj < coos.shape(1); ++jj)
+                feat_coos.back()[jj] = coos(ii, jj);
+    }
+
+};
+
+
+class BindFeatureColumn : public FeatureBase
+{
+    typedef typename MultiArrayShape<N>::type Shp;
+    int index; 
+    FeatureBase & underlying;
+
+    MultiArrayShape<2>::type shape()
+    {
+        return MultiArrayShape<2>::type(underlying.shape(0), 1);
+    }
+
+    double & operator() (int i, int j)
+    {
+        return  underlying(i, index);
+    }
+    double & operator[](int i)
+    {
+        return underlying(i, index); 
+    }
+    
+    BindFeatureColumn(FeaetureBase & in, int index_)
+        : index(index_), underlying(in) 
+    {
+        ;
+    }
+};
+
+FeatureBase columnVector(FeatureBase & in, int ii)
+{
+    return BindFeatureColumn(in, ii);
+}
+
+#endif
diff --git a/include/vigra/random_forest/rf_algorithm.hxx b/include/vigra/random_forest/rf_algorithm.hxx
new file mode 100644
index 0000000..fba236a
--- /dev/null
+++ b/include/vigra/random_forest/rf_algorithm.hxx
@@ -0,0 +1,1339 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair                             */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+#define VIGRA_RF_ALGORITHM_HXX
+
+#include <vector>
+#include "splices.hxx"
+#include <queue>
+#include <fstream>
+namespace vigra
+{
+ 
+namespace rf
+{
+/** This namespace contains all algorithms developed for feature 
+ * selection
+ *
+ */
+namespace algorithms
+{
+
+namespace detail
+{
+    /** create a MultiArray containing only columns supplied between iterators
+        b and e
+    */
+    template<class OrigMultiArray,
+             class Iter,
+             class DestMultiArray>
+    void choose(OrigMultiArray     const & in,
+                Iter               const & b,
+                Iter               const & e,
+                DestMultiArray        & out)
+    {
+        int columnCount = std::distance(b, e);
+        int rowCount     = in.shape(0);
+        out.reshape(MultiArrayShape<2>::type(rowCount, columnCount));
+        int ii = 0;
+        for(Iter iter = b; iter != e; ++iter, ++ii)
+        {
+            columnVector(out, ii) = columnVector(in, *iter);
+        }
+    }
+}
+
+
+
+/** Standard random forest Errorrate callback functor
+ *
+ * returns the random forest error estimate when invoked. 
+ */
+class RFErrorCallback
+{
+    RandomForestOptions options;
+    
+    public:
+    /** Default constructor
+     *
+     * optionally supply options to the random forest classifier
+     * \sa RandomForestOptions
+     */
+    RFErrorCallback(RandomForestOptions opt = RandomForestOptions())
+    : options(opt)
+    {}
+
+    /** returns the RF OOB error estimate given features and 
+     * labels
+     */
+    template<class Feature_t, class Response_t>
+    double operator() (Feature_t const & features,
+                       Response_t const & response)
+    {
+        RandomForest<>             rf(options);
+        visitors::OOB_Error        oob;
+        rf.learn(features, 
+                 response, 
+                 visitors::create_visitor(oob ));
+        return oob.oob_breiman;
+    }
+};
+
+
+/** Structure to hold Variable Selection results
+ */
+class VariableSelectionResult
+{
+    bool initialized;
+
+  public:
+    VariableSelectionResult()
+    : initialized(false)
+    {}
+
+    typedef std::vector<int> FeatureList_t;
+    typedef std::vector<double> ErrorList_t;
+    typedef FeatureList_t::iterator Pivot_t;
+
+    Pivot_t pivot;
+
+    /** list of features. 
+     */
+    FeatureList_t selected;
+    
+    /** vector of size (number of features)
+     *
+     * the i-th entry encodes the error rate obtained
+     * while using features [0 - i](including i) 
+     *
+     * if the i-th entry is -1 then no error rate was obtained
+     * this may happen if more than one feature is added to the
+     * selected list in one step of the algorithm.
+     *
+     * during initialisation error[m+n-1] is always filled
+     */
+    ErrorList_t errors;
+    
+
+    /** errorrate using no features
+     */
+    double no_features;
+
+    template<class FeatureT, 
+             class ResponseT, 
+             class Iter,
+             class ErrorRateCallBack>
+    bool init(FeatureT const & all_features,
+              ResponseT const & response,
+              Iter b,
+              Iter e,
+              ErrorRateCallBack errorcallback)
+    {
+        bool ret_ = init(all_features, response, errorcallback); 
+        if(!ret_)
+            return false;
+        vigra_precondition(std::distance(b, e) == (std::ptrdiff_t)selected.size(),
+                           "Number of features in ranking != number of features matrix");
+        std::copy(b, e, selected.begin());
+        return true;
+    }
+    
+    template<class FeatureT, 
+             class ResponseT, 
+             class Iter>
+    bool init(FeatureT const & all_features,
+              ResponseT const & response,
+              Iter b,
+              Iter e)
+    {
+        RFErrorCallback ecallback;
+        return init(all_features, response, b, e, ecallback);
+    }
+
+
+    template<class FeatureT, 
+             class ResponseT>
+    bool init(FeatureT const & all_features,
+              ResponseT const & response)
+    {
+        return init(all_features, response, RFErrorCallback());
+    }
+    /**initialization routine. Will be called only once in the lifetime
+     * of a VariableSelectionResult. Subsequent calls will not reinitialize
+     * member variables.
+     *
+     * This is intended, to allow continuing variable selection at a point 
+     * stopped in an earlier iteration. 
+     *
+     * returns true if initialization was successful and false if 
+     * the object was already initialized before.
+     */
+    template<class FeatureT, 
+             class ResponseT,
+             class ErrorRateCallBack>
+    bool init(FeatureT const & all_features,
+              ResponseT const & response,
+              ErrorRateCallBack errorcallback)
+    {
+        if(initialized)
+        {
+            return false;
+        }
+        initialized = true;
+        // calculate error with all features
+        selected.resize(all_features.shape(1), 0);
+        for(unsigned int ii = 0; ii < selected.size(); ++ii)
+            selected[ii] = ii;
+        errors.resize(all_features.shape(1), -1);
+        errors.back() = errorcallback(all_features, response);
+
+        // calculate error rate if no features are chosen 
+        // corresponds to max(prior probability) of the classes
+        std::map<typename ResponseT::value_type, int>     res_map;
+        std::vector<int>                                 cts;
+        int                                             counter = 0;
+        for(int ii = 0; ii < response.shape(0); ++ii)
+        {
+            if(res_map.find(response(ii, 0)) == res_map.end())
+            {
+                res_map[response(ii, 0)] = counter;
+                ++counter;
+                cts.push_back(0);
+            }
+            cts[res_map[response(ii,0)]] +=1;
+        }
+        no_features = double(*(std::max_element(cts.begin(),
+                                                 cts.end())))
+                    / double(response.shape(0));
+
+        /*init not_selected vector;
+        not_selected.resize(all_features.shape(1), 0);
+        for(int ii = 0; ii < not_selected.size(); ++ii)
+        {
+            not_selected[ii] = ii;
+        }
+        initialized = true;
+        */
+        pivot = selected.begin();
+        return true;
+    }
+};
+
+
+    
+/** Perform forward selection
+ *
+ * \param features    IN:     n x p matrix containing n instances with p attributes/features
+ *                             used in the variable selection algorithm
+ * \param response  IN:     n x 1 matrix containing the corresponding response
+ * \param result    IN/OUT: VariableSelectionResult struct which will contain the results
+ *                             of the algorithm. 
+ *                             Features between result.selected.begin() and result.pivot will
+ *                             be left untouched.
+ *                             \sa VariableSelectionResult
+ * \param errorcallback
+ *                     IN, OPTIONAL: 
+ *                             Functor that returns the error rate given a set of 
+ *                             features and labels. Default is the RandomForest OOB Error.
+ *
+ * Forward selection subsequently chooses the next feature that decreases the Error rate most.
+ *
+ * usage:
+ * \code
+ *         MultiArray<2, double>     features = createSomeFeatures();
+ *         MultiArray<2, int>        labels   = createCorrespondingLabels();
+ *         VariableSelectionResult  result;
+ *         forward_selection(features, labels, result);
+ * \endcode
+ * To use forward selection but ensure that a specific feature e.g. feature 5 is always 
+ * included one would do the following
+ *
+ * \code
+ *         VariableSelectionResult result;
+ *         result.init(features, labels);
+ *         std::swap(result.selected[0], result.selected[5]);
+ *         result.setPivot(1);
+ *         forward_selection(features, labels, result);
+ * \endcode
+ *
+ * \sa VariableSelectionResult
+ *
+ */                    
+template<class FeatureT, class ResponseT, class ErrorRateCallBack>
+void forward_selection(FeatureT          const & features,
+                       ResponseT          const & response,
+                       VariableSelectionResult & result,
+                       ErrorRateCallBack          errorcallback)
+{
+    VariableSelectionResult::FeatureList_t & selected         = result.selected;
+    VariableSelectionResult::ErrorList_t &     errors            = result.errors;
+    VariableSelectionResult::Pivot_t       & pivot            = result.pivot;    
+    int featureCount = features.shape(1);
+    // initialize result struct if in use for the first time
+    if(!result.init(features, response, errorcallback))
+    {
+        //result is being reused just ensure that the number of features is
+        //the same.
+        vigra_precondition((int)selected.size() == featureCount,
+                           "forward_selection(): Number of features in Feature "
+                           "matrix and number of features in previously used "
+                           "result struct mismatch!");
+    }
+    
+
+    int not_selected_size = std::distance(pivot, selected.end());
+    while(not_selected_size > 1)
+    {
+        std::vector<double> current_errors;
+        VariableSelectionResult::Pivot_t next = pivot;
+        for(int ii = 0; ii < not_selected_size; ++ii, ++next)
+        {
+            std::swap(*pivot, *next);
+            MultiArray<2, double> cur_feats;
+            detail::choose( features, 
+                            selected.begin(), 
+                            pivot+1, 
+                            cur_feats);
+            double error = errorcallback(cur_feats, response);
+            current_errors.push_back(error);
+            std::swap(*pivot, *next);
+        }
+        int pos = std::distance(current_errors.begin(),
+                                std::min_element(current_errors.begin(),
+                                                   current_errors.end()));
+        next = pivot;
+        std::advance(next, pos);
+        std::swap(*pivot, *next);
+        errors[std::distance(selected.begin(), pivot)] = current_errors[pos];
+#ifdef RN_VERBOSE
+            std::copy(current_errors.begin(), current_errors.end(), std::ostream_iterator<double>(std::cerr, ", "));
+            std::cerr << "Choosing " << *pivot << " at error of " <<  current_errors[pos] << std::endl;
+#endif
+        ++pivot;
+        not_selected_size = std::distance(pivot, selected.end());
+    }
+}
+template<class FeatureT, class ResponseT>
+void forward_selection(FeatureT          const & features,
+                       ResponseT          const & response,
+                       VariableSelectionResult & result)
+{
+    forward_selection(features, response, result, RFErrorCallback());
+}
+
+
+/** Perform backward elimination
+ *
+ * \param features    IN:     n x p matrix containing n instances with p attributes/features
+ *                             used in the variable selection algorithm
+ * \param response  IN:     n x 1 matrix containing the corresponding response
+ * \param result    IN/OUT: VariableSelectionResult struct which will contain the results
+ *                             of the algorithm. 
+ *                             Features between result.pivot and result.selected.end() will
+ *                             be left untouched.
+ *                             \sa VariableSelectionResult
+ * \param errorcallback
+ *                     IN, OPTIONAL: 
+ *                             Functor that returns the error rate given a set of 
+ *                             features and labels. Default is the RandomForest OOB Error.
+ *
+ * Backward elimination subsequently eliminates features that have the least influence
+ * on the error rate
+ *
+ * usage:
+ * \code
+ *         MultiArray<2, double>     features = createSomeFeatures();
+ *         MultiArray<2, int>        labels   = createCorrespondingLabels();
+ *         VariableSelectionResult  result;
+ *         backward_elimination(features, labels, result);
+ * \endcode
+ * To use backward elimination but ensure that a specific feature e.g. feature 5 is always 
+ * excluded one would do the following:
+ *
+ * \code
+ *         VariableSelectionResult result;
+ *         result.init(features, labels);
+ *         std::swap(result.selected[result.selected.size()-1], result.selected[5]);
+ *         result.setPivot(result.selected.size()-1);
+ *         backward_elimination(features, labels, result);
+ * \endcode
+ *
+ * \sa VariableSelectionResult
+ *
+ */                    
+template<class FeatureT, class ResponseT, class ErrorRateCallBack>
+void backward_elimination(FeatureT              const & features,
+                             ResponseT         const & response,
+                          VariableSelectionResult & result,
+                          ErrorRateCallBack         errorcallback)
+{
+    int featureCount = features.shape(1);
+    VariableSelectionResult::FeatureList_t & selected         = result.selected;
+    VariableSelectionResult::ErrorList_t &     errors            = result.errors;
+    VariableSelectionResult::Pivot_t       & pivot            = result.pivot;    
+    
+    // initialize result struct if in use for the first time
+    if(!result.init(features, response, errorcallback))
+    {
+        //result is being reused just ensure that the number of features is
+        //the same.
+        vigra_precondition((int)selected.size() == featureCount,
+                           "backward_elimination(): Number of features in Feature "
+                           "matrix and number of features in previously used "
+                           "result struct mismatch!");
+    }
+    pivot = selected.end() - 1;    
+
+    int selected_size = std::distance(selected.begin(), pivot);
+    while(selected_size > 1)
+    {
+        VariableSelectionResult::Pivot_t next = selected.begin();
+        std::vector<double> current_errors;
+        for(int ii = 0; ii < selected_size; ++ii, ++next)
+        {
+            std::swap(*pivot, *next);
+            MultiArray<2, double> cur_feats;
+            detail::choose( features, 
+                            selected.begin(), 
+                            pivot+1, 
+                            cur_feats);
+            double error = errorcallback(cur_feats, response);
+            current_errors.push_back(error);
+            std::swap(*pivot, *next);
+        }
+        int pos = std::distance(current_errors.begin(),
+                                std::min_element(current_errors.begin(),
+                                                   current_errors.end()));
+        next = selected.begin();
+        std::advance(next, pos);
+        std::swap(*pivot, *next);
+//        std::cerr << std::distance(selected.begin(), pivot) << " " << pos << " " << current_errors.size() << " " << errors.size() << std::endl;
+        errors[std::distance(selected.begin(), pivot)-1] = current_errors[pos];
+        selected_size = std::distance(selected.begin(), pivot);
+#ifdef RN_VERBOSE
+            std::copy(current_errors.begin(), current_errors.end(), std::ostream_iterator<double>(std::cerr, ", "));
+            std::cerr << "Eliminating " << *pivot << " at error of " << current_errors[pos] << std::endl;
+#endif
+        --pivot;
+    }
+}
+
+template<class FeatureT, class ResponseT>
+void backward_elimination(FeatureT              const & features,
+                             ResponseT         const & response,
+                          VariableSelectionResult & result)
+{
+    backward_elimination(features, response, result, RFErrorCallback());
+}
+
+/** Perform rank selection using a predefined ranking
+ *
+ * \param features    IN:     n x p matrix containing n instances with p attributes/features
+ *                             used in the variable selection algorithm
+ * \param response  IN:     n x 1 matrix containing the corresponding response
+ * \param result    IN/OUT: VariableSelectionResult struct which will contain the results
+ *                             of the algorithm. The struct should be initialized with the
+ *                             predefined ranking.
+ *                         
+ *                             \sa VariableSelectionResult
+ * \param errorcallback
+ *                     IN, OPTIONAL: 
+ *                             Functor that returns the error rate given a set of 
+ *                             features and labels. Default is the RandomForest OOB Error.
+ *
+ * Often some variable importance, score measure is used to create the ordering in which
+ * variables have to be selected. This method takes such a ranking and calculates the 
+ * corresponding error rates. 
+ *
+ * usage:
+ * \code
+ *         MultiArray<2, double>     features = createSomeFeatures();
+ *         MultiArray<2, int>        labels   = createCorrespondingLabels();
+ *         std::vector<int>        ranking  = createRanking(features);
+ *         VariableSelectionResult  result;
+ *         result.init(features, labels, ranking.begin(), ranking.end());
+ *         backward_elimination(features, labels, result);
+ * \endcode
+ *
+ * \sa VariableSelectionResult
+ *
+ */                    
+template<class FeatureT, class ResponseT, class ErrorRateCallBack>
+void rank_selection      (FeatureT              const & features,
+                             ResponseT         const & response,
+                          VariableSelectionResult & result,
+                          ErrorRateCallBack         errorcallback)
+{
+    VariableSelectionResult::FeatureList_t & selected         = result.selected;
+    VariableSelectionResult::ErrorList_t &     errors            = result.errors;
+    VariableSelectionResult::Pivot_t       & iter            = result.pivot;
+    int featureCount = features.shape(1);
+    // initialize result struct if in use for the first time
+    if(!result.init(features, response, errorcallback))
+    {
+        //result is being reused just ensure that the number of features is
+        //the same.
+        vigra_precondition((int)selected.size() == featureCount,
+                           "forward_selection(): Number of features in Feature "
+                           "matrix and number of features in previously used "
+                           "result struct mismatch!");
+    }
+    
+    int ii = 0;
+    for(; iter != selected.end(); ++iter)
+    {
+        ++ii;
+        MultiArray<2, double> cur_feats;
+        detail::choose( features, 
+                        selected.begin(), 
+                        iter+1, 
+                        cur_feats);
+        double error = errorcallback(cur_feats, response);
+        errors[std::distance(selected.begin(), iter)] = error;
+#ifdef RN_VERBOSE
+            std::copy(selected.begin(), iter+1, std::ostream_iterator<int>(std::cerr, ", "));
+            std::cerr << "Choosing " << *(iter+1) << " at error of " <<  error << std::endl;
+#endif
+
+    }
+}
+
+template<class FeatureT, class ResponseT>
+void rank_selection      (FeatureT              const & features,
+                             ResponseT         const & response,
+                          VariableSelectionResult & result)
+{
+    rank_selection(features, response, result, RFErrorCallback());
+}
+
+
+
+enum ClusterLeafTypes{c_Leaf = 95, c_Node = 99};
+
+/* View of a Node in the hierarchical clustering 
+ * class 
+ * For internal use only - 
+ * \sa NodeBase
+ */
+class ClusterNode
+: public NodeBase
+{
+    public:
+
+    typedef NodeBase BT;
+
+        /**constructors **/
+    ClusterNode():NodeBase(){}
+    ClusterNode(    int                      nCol,
+                    BT::T_Container_type    &   topology,
+                    BT::P_Container_type    &   split_param)
+                :   BT(nCol + 5, 5,topology, split_param)
+    {
+        status() = 0; 
+        BT::column_data()[0] = nCol;
+        if(nCol == 1)
+            BT::typeID() = c_Leaf;
+        else
+            BT::typeID() = c_Node;
+    }
+
+    ClusterNode(           BT::T_Container_type  const  &   topology,
+                    BT::P_Container_type  const  &   split_param,
+                    int                  n             )
+                :   NodeBase(5 , 5,topology, split_param, n)
+    {
+        //TODO : is there a more elegant way to do this?
+        BT::topology_size_ += BT::column_data()[0];
+    }
+
+    ClusterNode( BT & node_)
+        :   BT(5, 5, node_) 
+    {
+        //TODO : is there a more elegant way to do this?
+        BT::topology_size_ += BT::column_data()[0];
+        BT::parameter_size_ += 0;
+    }
+    int index()
+    {
+        return static_cast<int>(BT::parameters_begin()[1]);
+    }
+    void set_index(int in)
+    {
+        BT::parameters_begin()[1] = in;
+    }
+    double& mean()
+    {
+        return BT::parameters_begin()[2];
+    }
+    double& stdev()
+    {
+        return BT::parameters_begin()[3];
+    }
+    double& status()
+    {
+        return BT::parameters_begin()[4];
+    }
+};
+
+/** Stackentry class for HClustering class
+ */
+struct HC_Entry
+{
+    int parent;
+    int level;
+    int addr; 
+    bool infm;
+    HC_Entry(int p, int l, int a, bool in)
+        : parent(p), level(l), addr(a), infm(in)
+    {}
+};
+
+
+/** Hierarchical Clustering class. 
+ * Performs single linkage clustering
+ * \code
+ *         Matrix<double> distance = get_distance_matrix();
+ *      linkage.cluster(distance);
+ *      // Draw clustering tree.
+ *      Draw<double, int> draw(features, labels, "linkagetree.graph");
+ *      linkage.breadth_first_traversal(draw);
+ * \endcode
+ * \sa ClusterImportanceVisitor
+ *
+ * once the clustering has taken place. Information queries can be made
+ * using the breadth_first_traversal() method and iterate() method
+ *
+ */
+class HClustering
+{
+public:
+    typedef MultiArrayShape<2>::type Shp;
+    ArrayVector<int>         topology_;
+    ArrayVector<double>     parameters_;
+    int                     begin_addr;
+
+    // Calculates the distance between two 
+    double dist_func(double a, double b)
+    {
+        return std::min(a, b); 
+    }
+
+    /** Visit each node with a Functor 
+     * in creation order (should be depth first)
+     */
+    template<class Functor>
+    void iterate(Functor & tester)
+    {
+
+        std::vector<int> stack; 
+        stack.push_back(begin_addr); 
+        while(!stack.empty())
+        {
+            ClusterNode node(topology_, parameters_, stack.back());
+            stack.pop_back();
+            if(!tester(node))
+            {
+                if(node.columns_size() != 1)
+                {
+                    stack.push_back(node.child(0));
+                    stack.push_back(node.child(1));
+                }
+            }
+        }
+    }
+
+    /** Perform breadth first traversal of hierarchical cluster tree
+     */
+    template<class Functor>
+    void breadth_first_traversal(Functor & tester)
+    {
+
+        std::queue<HC_Entry> queue; 
+        int level = 0;
+        int parent = -1;
+        int addr   = -1;
+        bool infm  = false;
+        queue.push(HC_Entry(parent,level,begin_addr, infm)); 
+        while(!queue.empty())
+        {
+            level  = queue.front().level;
+            parent = queue.front().parent;
+            addr   = queue.front().addr;
+            infm   = queue.front().infm;
+            ClusterNode node(topology_, parameters_, queue.front().addr);
+            ClusterNode parnt;
+            if(parent != -1)
+            {
+                parnt = ClusterNode(topology_, parameters_, parent); 
+            }
+            queue.pop();
+            bool istrue = tester(node, level, parnt, infm);
+            if(node.columns_size() != 1)
+            {
+                queue.push(HC_Entry(addr, level +1,node.child(0),istrue));
+                queue.push(HC_Entry(addr, level +1,node.child(1),istrue));
+            }
+        }
+    }
+    /**save to HDF5 - defunct - has to be updated to new HDF5 interface
+     */
+#ifdef HasHDF5
+    void save(std::string file, std::string prefix)
+    {
+
+        vigra::writeHDF5(file.c_str(), (prefix + "topology").c_str(), 
+                               MultiArrayView<2, int>(
+                                    Shp(topology_.size(),1),
+                                    topology_.data()));
+        vigra::writeHDF5(file.c_str(), (prefix + "parameters").c_str(), 
+                               MultiArrayView<2, double>(
+                                    Shp(parameters_.size(), 1),
+                                    parameters_.data()));
+        vigra::writeHDF5(file.c_str(), (prefix + "begin_addr").c_str(), 
+                               MultiArrayView<2, int>(Shp(1,1), &begin_addr));
+
+    }
+#endif
+
+    /**Perform single linkage clustering
+     * \param distance distance matrix used. \sa CorrelationVisitor
+     */
+    template<class T, class C>
+    void cluster(MultiArrayView<2, T, C> distance)
+    {
+        MultiArray<2, T> dist(distance); 
+        std::vector<std::pair<int, int> > addr; 
+        int index = 0;
+        for(int ii = 0; ii < distance.shape(0); ++ii)
+        {
+            addr.push_back(std::make_pair(topology_.size(), ii));
+            ClusterNode leaf(1, topology_, parameters_);
+            leaf.set_index(index);
+            ++index;
+            leaf.columns_begin()[0] = ii;
+        }
+
+        while(addr.size() != 1)
+        {
+            //find the two nodes with the smallest distance
+            int ii_min = 0;
+            int jj_min = 1;
+            double min_dist = dist((addr.begin()+ii_min)->second, 
+                              (addr.begin()+jj_min)->second);
+            for(unsigned int ii = 0; ii < addr.size(); ++ii)
+            {
+                for(unsigned int jj = ii+1; jj < addr.size(); ++jj)
+                {
+                    if(  dist((addr.begin()+ii_min)->second, 
+                              (addr.begin()+jj_min)->second)
+                       > dist((addr.begin()+ii)->second, 
+                              (addr.begin()+jj)->second))
+                    {
+                        min_dist = dist((addr.begin()+ii)->second, 
+                              (addr.begin()+jj)->second);
+                        ii_min = ii; 
+                        jj_min = jj;
+                    }
+                }
+            }
+
+            //merge two nodes
+            int col_size = 0;
+            // The problem is that creating a new node invalidates the iterators stored
+            // in firstChild and secondChild.
+            {
+                ClusterNode firstChild(topology_, 
+                                       parameters_, 
+                                       (addr.begin() +ii_min)->first);
+                ClusterNode secondChild(topology_, 
+                                       parameters_, 
+                                       (addr.begin() +jj_min)->first);
+                col_size = firstChild.columns_size() + secondChild.columns_size();
+            }
+            int cur_addr = topology_.size();
+            begin_addr = cur_addr;
+//            std::cerr << col_size << std::endl;
+            ClusterNode parent(col_size,
+                               topology_,
+                               parameters_); 
+            ClusterNode firstChild(topology_, 
+                                   parameters_, 
+                                   (addr.begin() +ii_min)->first);
+            ClusterNode secondChild(topology_, 
+                                   parameters_, 
+                                   (addr.begin() +jj_min)->first);
+            parent.parameters_begin()[0] = min_dist;
+            parent.set_index(index);
+            ++index;
+            std::merge(firstChild.columns_begin(), firstChild.columns_end(),
+                       secondChild.columns_begin(),secondChild.columns_end(),
+                       parent.columns_begin());
+            //merge nodes in addr
+            int to_desc;
+            int ii_keep;
+            if(*parent.columns_begin() ==  *firstChild.columns_begin())
+            {
+                parent.child(0) = (addr.begin()+ii_min)->first;
+                parent.child(1) = (addr.begin()+jj_min)->first;
+                (addr.begin()+ii_min)->first = cur_addr;
+                ii_keep = ii_min;
+                to_desc = (addr.begin()+jj_min)->second;
+                addr.erase(addr.begin()+jj_min);
+            }
+            else
+            {
+                parent.child(1) = (addr.begin()+ii_min)->first;
+                parent.child(0) = (addr.begin()+jj_min)->first;
+                (addr.begin()+jj_min)->first = cur_addr;
+                ii_keep = jj_min;
+                to_desc = (addr.begin()+ii_min)->second;
+                addr.erase(addr.begin()+ii_min);
+            }
+            //update distances;
+            
+            for(int jj = 0 ; jj < (int)addr.size(); ++jj)
+            {
+                if(jj == ii_keep)
+                    continue;
+                double bla = dist_func(
+                                  dist(to_desc, (addr.begin()+jj)->second),
+                                  dist((addr.begin()+ii_keep)->second,
+                                        (addr.begin()+jj)->second));
+
+                dist((addr.begin()+ii_keep)->second,
+                     (addr.begin()+jj)->second) = bla;
+                dist((addr.begin()+jj)->second,
+                     (addr.begin()+ii_keep)->second) = bla;
+            }
+        }
+    }
+
+};
+
+
+/** Normalize the status value in the HClustering tree (HClustering Visitor)
+ */
+class NormalizeStatus
+{
+public:
+    double n;
+    /** Constructor
+     * \param m normalize status() by m
+     */
+    NormalizeStatus(double m)
+        :n(m)
+    {}
+    template<class Node>
+    bool operator()(Node& node)
+    {
+        node.status()/=n;
+        return false;
+    }
+};
+
+
+/** Perform Permutation importance on HClustering clusters
+ * (See visit_after_tree() method of visitors::VariableImportance to 
+ * see the basic idea. (Just that we apply the permutation not only to
+ * variables but also to clusters))
+ */
+template<class Iter, class DT>
+class PermuteCluster
+{
+public:
+    typedef MultiArrayShape<2>::type Shp;
+    Matrix<double> tmp_mem_;
+    MultiArrayView<2, double> perm_imp;
+    MultiArrayView<2, double> orig_imp;
+    Matrix<double> feats_;
+    Matrix<int>    labels_;
+    const int      nPerm;
+    DT const &           dt;
+    int index;
+    int oob_size;
+
+    template<class Feat_T, class Label_T>
+    PermuteCluster(Iter  a, 
+                   Iter  b,
+                   Feat_T const & feats,
+                   Label_T const & labls, 
+                   MultiArrayView<2, double> p_imp, 
+                   MultiArrayView<2, double> o_imp, 
+                   int np,
+                   DT const  & dt_)
+        :tmp_mem_(_spl(a, b).size(), feats.shape(1)),
+         perm_imp(p_imp),
+         orig_imp(o_imp),
+         feats_(_spl(a,b).size(), feats.shape(1)),
+         labels_(_spl(a,b).size(),1),
+         nPerm(np),
+         dt(dt_),
+         index(0),
+         oob_size(b-a)
+    {
+        copy_splice(_spl(a,b),
+                    _spl(feats.shape(1)),
+                    feats,
+                    feats_);
+        copy_splice(_spl(a,b),
+                    _spl(labls.shape(1)),
+                    labls,
+                    labels_);
+    }
+
+    template<class Node>
+    bool operator()(Node& node)
+    {
+        tmp_mem_ = feats_;
+        RandomMT19937 random;
+        int class_count = perm_imp.shape(1) - 1;
+        //permute columns together
+        for(int kk = 0; kk < nPerm; ++kk)
+        {
+            tmp_mem_ = feats_;
+            for(int ii = 0; ii < rowCount(feats_); ++ii)
+            {
+                int index = random.uniformInt(rowCount(feats_) - ii) +ii;
+                for(int jj = 0; jj < node.columns_size(); ++jj)
+                {
+                    if(node.columns_begin()[jj] != feats_.shape(1))
+                        tmp_mem_(ii, node.columns_begin()[jj]) 
+                            = tmp_mem_(index, node.columns_begin()[jj]);
+                }
+            }
+            
+            for(int ii = 0; ii < rowCount(tmp_mem_); ++ii)
+            {
+                if(dt
+                        .predictLabel(rowVector(tmp_mem_, ii)) 
+                    ==  labels_(ii, 0))
+                {
+                    //per class
+                    ++perm_imp(index,labels_(ii, 0));
+                    //total
+                    ++perm_imp(index, class_count);
+                }
+            }
+        }
+        double node_status  = perm_imp(index, class_count);
+        node_status /= nPerm;
+        node_status -= orig_imp(0, class_count);
+        node_status *= -1;
+        node_status /= oob_size;
+        node.status() += node_status;
+        ++index;
+         
+        return false;
+    }
+};
+
+/** Convert ClusteringTree into a list (HClustering visitor)
+ */
+class GetClusterVariables
+{
+public:
+    /** NumberOfClusters x NumberOfVariables MultiArrayView containing
+     * in each row the variable belonging to a cluster
+     */
+    MultiArrayView<2, int>    variables;
+    int index;
+    GetClusterVariables(MultiArrayView<2, int> vars)
+        :variables(vars), index(0)
+    {}
+#ifdef HasHDF5
+    void save(std::string file, std::string prefix)
+    {
+        vigra::writeHDF5(file.c_str(), (prefix + "_variables").c_str(), 
+                               variables);
+    }
+#endif
+
+    template<class Node>
+    bool operator()(Node& node)
+    {
+        for(int ii = 0; ii < node.columns_size(); ++ii)
+            variables(index, ii) = node.columns_begin()[ii];
+        ++index;
+        return false;
+    }
+};
+/** corrects the status fields of a linkage Clustering (HClustering Visitor)
+ *  
+ *  such that status(currentNode) = min(status(parent), status(currentNode))
+ *  \sa cluster_permutation_importance()
+ */
+class CorrectStatus
+{
+public:
+    template<class Nde>
+    bool operator()(Nde & cur, int level, Nde parent, bool infm)
+    {
+        if(parent.hasData_)
+            cur.status() = std::min(parent.status(), cur.status());
+        return true;
+    }
+};
+
+
+/** draw current linkage Clustering (HClustering Visitor)
+ *
+ * create a graphviz .dot file
+ * usage:
+ * \code
+ *         Matrix<double> distance = get_distance_matrix();
+ *      linkage.cluster(distance);
+ *      Draw<double, int> draw(features, labels, "linkagetree.graph");
+ *      linkage.breadth_first_traversal(draw);
+ * \endcode 
+ */
+template<class T1,
+         class T2, 
+         class C1 = UnstridedArrayTag,
+         class C2 = UnstridedArrayTag> 
+class Draw
+{
+public:
+    typedef MultiArrayShape<2>::type Shp;
+    MultiArrayView<2, T1, C1> const &   features_;
+    MultiArrayView<2, T2, C2> const &   labels_;
+    std::ofstream graphviz;
+
+
+    Draw(MultiArrayView<2, T1, C1> const & features, 
+         MultiArrayView<2, T2, C2> const& labels,
+         std::string const  gz)
+        :features_(features), labels_(labels), 
+        graphviz(gz.c_str(), std::ios::out)
+    {
+        graphviz << "digraph G\n{\n node [shape=\"record\"]";
+    }
+    ~Draw()
+    {
+        graphviz << "\n}\n";
+        graphviz.close();
+    }
+
+    template<class Nde>
+    bool operator()(Nde & cur, int level, Nde parent, bool infm)
+    {
+        graphviz << "node" << cur.index() << " [style=\"filled\"][label = \" #Feats: "<< cur.columns_size() << "\\n";
+        graphviz << " status: " << cur.status() << "\\n";
+        for(int kk = 0; kk < cur.columns_size(); ++kk)
+        {
+                graphviz  << cur.columns_begin()[kk] << " ";
+                if(kk % 15 == 14)
+                    graphviz << "\\n";
+        }
+        graphviz << "\"] [color = \"" <<cur.status() << " 1.000 1.000\"];\n";
+        if(parent.hasData_)
+        graphviz << "\"node" << parent.index() << "\" -> \"node" << cur.index() <<"\";\n";
+        return true;
+    }
+};
+
+/** calculate Cluster based permutation importance while learning. (RandomForestVisitor)
+ */
+class ClusterImportanceVisitor : public visitors::VisitorBase
+{
+    public:
+
+    /** List of variables as produced by GetClusterVariables
+     */
+    MultiArray<2, int>          variables;
+    /** Corresponding importance measures
+     */
+    MultiArray<2, double>       cluster_importance_;
+    /** Corresponding error
+     */
+    MultiArray<2, double>       cluster_stdev_;
+    int                         repetition_count_;
+    bool                        in_place_;
+    HClustering            &    clustering;
+
+
+#ifdef HasHDF5
+    void save(std::string filename, std::string prefix)
+    {
+        std::string prefix1 = "cluster_importance_" + prefix;
+        writeHDF5(filename.c_str(), 
+                        prefix1.c_str(), 
+                        cluster_importance_);
+        prefix1 = "vars_" + prefix;
+        writeHDF5(filename.c_str(), 
+                        prefix1.c_str(), 
+                        variables);
+    }
+#endif
+
+    ClusterImportanceVisitor(HClustering & clst, int rep_cnt = 10) 
+    :   repetition_count_(rep_cnt), clustering(clst)
+
+    {}
+
+    /** Allocate enough memory 
+     */
+    template<class RF, class PR>
+    void visit_at_beginning(RF const & rf, PR const & pr)
+    {
+        Int32 const  class_count = rf.ext_param_.class_count_;
+        Int32 const  column_count = rf.ext_param_.column_count_+1;
+        cluster_importance_
+            .reshape(MultiArrayShape<2>::type(2*column_count-1, 
+                                                class_count+1));
+        cluster_stdev_
+            .reshape(MultiArrayShape<2>::type(2*column_count-1, 
+                                                class_count+1));
+        variables
+            .reshape(MultiArrayShape<2>::type(2*column_count-1, 
+                                                column_count), -1);
+        GetClusterVariables gcv(variables);
+        clustering.iterate(gcv);
+        
+    }
+
+    /**compute permutation based var imp. 
+     * (Only an Array of size oob_sample_count x 1 is created.
+     *  - apposed to oob_sample_count x feature_count in the other method.
+     * 
+     * \sa FieldProxy
+     */
+    template<class RF, class PR, class SM, class ST>
+    void after_tree_ip_impl(RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {
+        typedef MultiArrayShape<2>::type Shp_t;
+        Int32                   column_count = rf.ext_param_.column_count_ +1;
+        Int32                   class_count  = rf.ext_param_.class_count_;  
+        
+        // remove the const cast on the features (yep , I know what I am 
+        // doing here.) data is not destroyed.
+        typename PR::Feature_t & features 
+            = const_cast<typename PR::Feature_t &>(pr.features());
+
+        //find the oob indices of current tree. 
+        ArrayVector<Int32>      oob_indices;
+        ArrayVector<Int32>::iterator
+                                iter;
+        
+        if(rf.ext_param_.actual_msample_ < pr.features().shape(0)- 10000)
+        {
+            ArrayVector<int> cts(2, 0);
+            ArrayVector<Int32> indices(pr.features().shape(0));
+            for(int ii = 0; ii < pr.features().shape(0); ++ii)
+               indices.push_back(ii); 
+            std::random_shuffle(indices.begin(), indices.end());
+            for(int ii = 0; ii < rf.ext_param_.row_count_; ++ii)
+            {
+                if(!sm.is_used()[indices[ii]] && cts[pr.response()(indices[ii], 0)] < 3000)
+                {
+                    oob_indices.push_back(indices[ii]);
+                    ++cts[pr.response()(indices[ii], 0)];
+                }
+            }
+        }
+        else
+        {
+            for(int ii = 0; ii < rf.ext_param_.row_count_; ++ii)
+                if(!sm.is_used()[ii])
+                    oob_indices.push_back(ii);
+        }
+
+        // Random foo
+        RandomMT19937           random(RandomSeed);
+        UniformIntRandomFunctor<RandomMT19937>  
+                                randint(random);
+
+        //make some space for the results
+        MultiArray<2, double>
+                    oob_right(Shp_t(1, class_count + 1)); 
+        
+        // get the oob success rate with the original samples
+        for(iter = oob_indices.begin(); 
+            iter != oob_indices.end(); 
+            ++iter)
+        {
+            if(rf.tree(index)
+                    .predictLabel(rowVector(features, *iter)) 
+                ==  pr.response()(*iter, 0))
+            {
+                //per class
+                ++oob_right[pr.response()(*iter,0)];
+                //total
+                ++oob_right[class_count];
+            }
+        }
+        
+        MultiArray<2, double>
+                    perm_oob_right (Shp_t(2* column_count-1, class_count + 1)); 
+        
+        PermuteCluster<ArrayVector<Int32>::iterator,typename RF::DecisionTree_t>
+            pc(oob_indices.begin(), oob_indices.end(), 
+                            pr.features(),
+                            pr.response(),
+                            perm_oob_right,
+                            oob_right,
+                            repetition_count_,
+                            rf.tree(index));
+        clustering.iterate(pc);
+
+        perm_oob_right  /=  repetition_count_;
+        for(int ii = 0; ii < rowCount(perm_oob_right); ++ii)
+            rowVector(perm_oob_right, ii) -= oob_right;
+
+        perm_oob_right       *= -1;
+        perm_oob_right       /= oob_indices.size();
+        cluster_importance_  += perm_oob_right;
+    }
+
+    /** calculate permutation based impurity after every tree has been 
+     * learned  default behaviour is that this happens out of place.
+     * If you have very big data sets and want to avoid copying of data 
+     * set the in_place_ flag to true. 
+     */
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {    
+            after_tree_ip_impl(rf, pr, sm, st, index);
+    }
+
+    /** Normalise variable importance after the number of trees is known.
+     */
+    template<class RF, class PR>
+    void visit_at_end(RF & rf, PR & pr)
+    {
+        NormalizeStatus nrm(rf.tree_count());
+        clustering.iterate(nrm);
+        cluster_importance_ /= rf.trees_.size();
+    }
+};
+
+/** Perform hierarchical clustering of variables and assess importance of clusters
+ *
+ * \param features    IN:     n x p matrix containing n instances with p attributes/features
+ *                             used in the variable selection algorithm
+ * \param response  IN:     n x 1 matrix containing the corresponding response
+ * \param linkage    OUT:    Hierarchical grouping of variables.
+ * \param distance  OUT:    distance matrix used for creating the linkage
+ *
+ * Performs Hierarchical clustering of variables. And calculates the permutation importance 
+ * measures of each of the clusters. Use the Draw functor to create human readable output
+ * The cluster-permutation importance measure corresponds to the normal permutation importance
+ * measure with all columns corresponding to a cluster permuted. 
+ * The importance measure for each cluster is stored as the status() field of each clusternode
+ * \sa HClustering
+ *
+ * usage:
+ * \code
+ *         MultiArray<2, double>     features = createSomeFeatures();
+ *         MultiArray<2, int>        labels   = createCorrespondingLabels();
+ *         HClustering                linkage;
+ *         MultiArray<2, double>    distance;
+ *         cluster_permutation_importance(features, labels, linkage, distance)
+ *        // create graphviz output
+ *
+ *      Draw<double, int> draw(features, labels, "linkagetree.graph");
+ *      linkage.breadth_first_traversal(draw);
+ *
+ * \endcode
+ *
+ *
+ */                    
+template<class FeatureT, class ResponseT>
+void cluster_permutation_importance(FeatureT              const & features,
+                                         ResponseT         const &     response,
+                                    HClustering               & linkage,
+                                    MultiArray<2, double>      & distance)
+{
+
+        RandomForestOptions opt;
+        opt.tree_count(100);
+        if(features.shape(0) > 40000)
+            opt.samples_per_tree(20000).use_stratification(RF_EQUAL);
+
+
+        vigra::RandomForest<int> RF(opt); 
+        visitors::RandomForestProgressVisitor             progress;
+        visitors::CorrelationVisitor                     missc;
+        RF.learn(features, response,
+                 create_visitor(missc, progress));
+        distance = missc.distance;
+        /*
+           missc.save(exp_dir + dset.name() + "_result.h5", dset.name()+"MACH");
+           */
+
+
+        // Produce linkage
+        linkage.cluster(distance);
+        
+        //linkage.save(exp_dir + dset.name() + "_result.h5", "_linkage_CC/");
+        vigra::RandomForest<int> RF2(opt); 
+        ClusterImportanceVisitor          ci(linkage);
+        RF2.learn(features, 
+                  response,
+                  create_visitor(progress, ci));
+        
+        
+        CorrectStatus cs;
+        linkage.breadth_first_traversal(cs);
+
+        //ci.save(exp_dir + dset.name() + "_result.h5", dset.name());
+        //Draw<double, int> draw(dset.features(), dset.response(), exp_dir+ dset.name() + ".graph");
+        //linkage.breadth_first_traversal(draw);
+
+}
+
+    
+template<class FeatureT, class ResponseT>
+void cluster_permutation_importance(FeatureT              const & features,
+                                         ResponseT         const &     response,
+                                    HClustering               & linkage)
+{
+    MultiArray<2, double> distance;
+    cluster_permutation_importance(features, response, linkage, distance);
+}
+
+    
+template<class Array1, class Vector1>
+void get_ranking(Array1 const & in, Vector1 & out)
+{
+    std::map<double, int> mymap;
+    for(int ii = 0; ii < in.size(); ++ii)
+        mymap[in[ii]] = ii;
+    for(std::map<double, int>::reverse_iterator iter = mymap.rbegin(); iter!= mymap.rend(); ++iter)
+    {
+        out.push_back(iter->second);
+    }
+}
+}//namespace algorithms
+}//namespace rf
+}//namespace vigra
diff --git a/include/vigra/random_forest/rf_common.hxx b/include/vigra/random_forest/rf_common.hxx
new file mode 100755
index 0000000..a82b1f5
--- /dev/null
+++ b/include/vigra/random_forest/rf_common.hxx
@@ -0,0 +1,908 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by  Ullrich Koethe and Rahul Nair         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_RF_COMMON_HXX
+#define VIGRA_RF_COMMON_HXX
+
+namespace vigra
+{
+
+
+struct ClassificationTag
+{};
+
+struct RegressionTag
+{};
+
+namespace detail
+{
+    class RF_DEFAULT;
+}
+inline detail::RF_DEFAULT& rf_default();
+namespace detail
+{
+
+/* \brief singleton default tag class -
+ *
+ *  use the rf_default() factory function to use the tag.
+ *  \sa RandomForest<>::learn();
+ */
+class RF_DEFAULT
+{
+    private:
+        RF_DEFAULT()
+        {}
+    public:
+        friend RF_DEFAULT& ::vigra::rf_default();
+
+        /** ok workaround for automatic choice of the decisiontree
+         * stackentry.
+         */
+};
+
+/* \brief chooses between default type and type supplied
+ * 
+ * This is an internal class and you shouldn't really care about it.
+ * Just pass on used in RandomForest.learn()
+ * Usage:
+ *\code
+ *      // example: use container type supplied by user or ArrayVector if 
+ *      //          rf_default() was specified as argument;
+ *      template<class Container_t>
+ *      void do_some_foo(Container_t in)
+ *      {
+ *          typedef ArrayVector<int>    Default_Container_t;
+ *          Default_Container_t         default_value;
+ *          Value_Chooser<Container_t,  Default_Container_t> 
+ *                      choose(in, default_value);
+ *
+ *          // if the user didn't care and the in was of type 
+ *          // RF_DEFAULT then default_value is used.
+ *          do_some_more_foo(choose.value());
+ *      }
+ *      Value_Chooser choose_val<Type, Default_Type>
+ *\endcode
+ */
+template<class T, class C>
+class Value_Chooser
+{
+public:
+    typedef T type;
+    static T & choose(T & t, C &)
+    {
+        return t; 
+    }
+};
+
+template<class C>
+class Value_Chooser<detail::RF_DEFAULT, C>
+{
+public:
+    typedef C type;
+    
+    static C & choose(detail::RF_DEFAULT &, C & c)
+    {
+        return c; 
+    }
+};
+
+
+
+
+} //namespace detail
+
+
+/**\brief factory function to return a RF_DEFAULT tag
+ * \sa RandomForest<>::learn()
+ */
+detail::RF_DEFAULT& rf_default()
+{
+    static detail::RF_DEFAULT result;
+    return result;
+}
+
+/** tags used with the RandomForestOptions class
+ * \sa RF_Traits::Option_t
+ */
+enum RF_OptionTag   { RF_EQUAL,
+                      RF_PROPORTIONAL,
+                      RF_EXTERNAL,
+                      RF_NONE,
+                      RF_FUNCTION,
+                      RF_LOG,
+                      RF_SQRT,
+                      RF_CONST,
+                      RF_ALL};
+
+
+/** \addtogroup MachineLearning 
+**/
+//@{
+
+/**\brief Options object for the random forest
+ *
+ * usage:
+ * RandomForestOptions a =  RandomForestOptions()
+ *                              .param1(value1)
+ *                              .param2(value2)
+ *                              ...
+ *
+ * This class only contains options/parameters that are not problem
+ * dependent. The ProblemSpec class contains methods to set class weights
+ * if necessary.
+ *
+ * Note that the return value of all methods is *this which makes
+ * concatenating of options as above possible.
+ */
+class RandomForestOptions
+{
+  public:
+    /**\name sampling options*/
+    /*\{*/
+    // look at the member access functions for documentation
+    double  training_set_proportion_;
+    int     training_set_size_;
+    int (*training_set_func_)(int);
+    RF_OptionTag
+        training_set_calc_switch_;
+
+    bool    sample_with_replacement_;
+    RF_OptionTag
+            stratification_method_;
+
+
+    /**\name general random forest options
+     *
+     * these usually will be used by most split functors and
+     * stopping predicates
+     */
+    /*\{*/
+    RF_OptionTag    mtry_switch_;
+    int     mtry_;
+    int (*mtry_func_)(int) ;
+
+    bool predict_weighted_; 
+    int tree_count_;
+    int min_split_node_size_;
+    bool prepare_online_learning_;
+    /*\}*/
+
+    typedef ArrayVector<double> double_array;
+    typedef std::map<std::string, double_array> map_type;
+
+    int serialized_size() const
+    {
+        return 12;
+    }
+    
+
+    bool operator==(RandomForestOptions & rhs) const
+    {
+        bool result = true;
+        #define COMPARE(field) result = result && (this->field == rhs.field); 
+        COMPARE(training_set_proportion_);
+        COMPARE(training_set_size_);
+        COMPARE(training_set_calc_switch_);
+        COMPARE(sample_with_replacement_);
+        COMPARE(stratification_method_);
+        COMPARE(mtry_switch_);
+        COMPARE(mtry_);
+        COMPARE(tree_count_);
+        COMPARE(min_split_node_size_);
+        COMPARE(predict_weighted_);
+        #undef COMPARE
+
+        return result;
+    }
+    bool operator!=(RandomForestOptions & rhs_) const
+    {
+        return !(*this == rhs_);
+    }
+    template<class Iter>
+    void unserialize(Iter const & begin, Iter const & end)
+    {
+        Iter iter = begin;
+        vigra_precondition(static_cast<int>(end - begin) == serialized_size(), 
+                           "RandomForestOptions::unserialize():"
+                           "wrong number of parameters");
+        #define PULL(item_, type_) item_ = type_(*iter); ++iter;
+        PULL(training_set_proportion_, double);
+        PULL(training_set_size_, int);
+        ++iter; //PULL(training_set_func_, double);
+        PULL(training_set_calc_switch_, (RF_OptionTag)int);
+        PULL(sample_with_replacement_, 0 != );
+        PULL(stratification_method_, (RF_OptionTag)int);
+        PULL(mtry_switch_, (RF_OptionTag)int);
+        PULL(mtry_, int);
+        ++iter; //PULL(mtry_func_, double);
+        PULL(tree_count_, int);
+        PULL(min_split_node_size_, int);
+        PULL(predict_weighted_, 0 !=);
+        #undef PULL
+    }
+    template<class Iter>
+    void serialize(Iter const &  begin, Iter const & end) const
+    {
+        Iter iter = begin;
+        vigra_precondition(static_cast<int>(end - begin) == serialized_size(), 
+                           "RandomForestOptions::serialize():"
+                           "wrong number of parameters");
+        #define PUSH(item_) *iter = double(item_); ++iter;
+        PUSH(training_set_proportion_);
+        PUSH(training_set_size_);
+        if(training_set_func_ != 0)
+        {
+            PUSH(1);
+        }
+        else
+        {
+            PUSH(0);
+        }
+        PUSH(training_set_calc_switch_);
+        PUSH(sample_with_replacement_);
+        PUSH(stratification_method_);
+        PUSH(mtry_switch_);
+        PUSH(mtry_);
+        if(mtry_func_ != 0)
+        {
+            PUSH(1);
+        }
+        else
+        {
+            PUSH(0);
+        }
+        PUSH(tree_count_);
+        PUSH(min_split_node_size_);
+        PUSH(predict_weighted_);
+        #undef PUSH
+    }
+    
+    void make_from_map(map_type & in) // -> const: .operator[] -> .find
+    {
+        #define PULL(item_, type_) item_ = type_(in[#item_][0]); 
+        #define PULLBOOL(item_, type_) item_ = type_(in[#item_][0] > 0); 
+        PULL(training_set_proportion_,double);
+        PULL(training_set_size_, int);
+        PULL(mtry_, int);
+        PULL(tree_count_, int);
+        PULL(min_split_node_size_, int);
+        PULLBOOL(sample_with_replacement_, bool);
+        PULLBOOL(prepare_online_learning_, bool);
+        PULLBOOL(predict_weighted_, bool);
+        
+        PULL(training_set_calc_switch_, (RF_OptionTag)(int));
+
+        PULL(stratification_method_, (RF_OptionTag)(int));
+        PULL(mtry_switch_, (RF_OptionTag)(int));
+        
+        /*don't pull*/
+        //PULL(mtry_func_!=0, int);
+        //PULL(training_set_func,int);
+        #undef PULL
+        #undef PULLBOOL
+    }
+    void make_map(map_type & in) const
+    {
+        #define PUSH(item_, type_) in[#item_] = double_array(1, double(item_));
+        #define PUSHFUNC(item_, type_) in[#item_] = double_array(1, double(item_!=0));
+        PUSH(training_set_proportion_,double);
+        PUSH(training_set_size_, int);
+        PUSH(mtry_, int);
+        PUSH(tree_count_, int);
+        PUSH(min_split_node_size_, int);
+        PUSH(sample_with_replacement_, bool);
+        PUSH(prepare_online_learning_, bool);
+        PUSH(predict_weighted_, bool);
+        
+        PUSH(training_set_calc_switch_, RF_OptionTag);
+        PUSH(stratification_method_, RF_OptionTag);
+        PUSH(mtry_switch_, RF_OptionTag);
+        
+        PUSHFUNC(mtry_func_, int);
+        PUSHFUNC(training_set_func_,int);
+        #undef PUSH
+        #undef PUSHFUNC
+    }
+
+
+    /**\brief create a RandomForestOptions object with default initialisation.
+     *
+     * look at the other member functions for more information on default
+     * values
+     */
+    RandomForestOptions()
+    :
+        training_set_proportion_(1.0),
+        training_set_size_(0),
+        training_set_func_(0),
+        training_set_calc_switch_(RF_PROPORTIONAL),
+        sample_with_replacement_(true),
+        stratification_method_(RF_NONE),
+        mtry_switch_(RF_SQRT),
+        mtry_(0),
+        mtry_func_(0),
+        predict_weighted_(false),
+        tree_count_(256),
+        min_split_node_size_(1),
+        prepare_online_learning_(false)
+    {}
+
+    /**\brief specify stratification strategy
+     *
+     * default: RF_NONE
+     * possible values: RF_EQUAL, RF_PROPORTIONAL,
+     *                  RF_EXTERNAL, RF_NONE
+     * RF_EQUAL:        get equal amount of samples per class.
+     * RF_PROPORTIONAL: sample proportional to fraction of class samples
+     *                  in population
+     * RF_EXTERNAL:     strata_weights_ field of the ProblemSpec_t object
+     *                  has been set externally. (defunct)
+     */
+    RandomForestOptions & use_stratification(RF_OptionTag in)
+    {
+        vigra_precondition(in == RF_EQUAL ||
+                           in == RF_PROPORTIONAL ||
+                           in == RF_EXTERNAL ||
+                           in == RF_NONE,
+                           "RandomForestOptions::use_stratification()"
+                           "input must be RF_EQUAL, RF_PROPORTIONAL,"
+                           "RF_EXTERNAL or RF_NONE");
+        stratification_method_ = in;
+        return *this;
+    }
+
+    RandomForestOptions & prepare_online_learning(bool in)
+    {
+        prepare_online_learning_=in;
+        return *this;
+    }
+
+    /**\brief sample from training population with or without replacement?
+     *
+     * <br> Default: true
+     */
+    RandomForestOptions & sample_with_replacement(bool in)
+    {
+        sample_with_replacement_ = in;
+        return *this;
+    }
+
+    /**\brief  specify the fraction of the total number of samples 
+     * used per tree for learning. 
+     *
+     * This value should be in [0.0 1.0] if sampling without
+     * replacement has been specified.
+     *
+     * <br> default : 1.0
+     */
+    RandomForestOptions & samples_per_tree(double in)
+    {
+        training_set_proportion_ = in;
+        training_set_calc_switch_ = RF_PROPORTIONAL;
+        return *this;
+    }
+
+    /**\brief directly specify the number of samples per tree
+     */
+    RandomForestOptions & samples_per_tree(int in)
+    {
+        training_set_size_ = in;
+        training_set_calc_switch_ = RF_CONST;
+        return *this;
+    }
+
+    /**\brief use external function to calculate the number of samples each
+     *        tree should be learnt with.
+     *
+     * \param in function pointer that takes the number of rows in the
+     *           learning data and outputs the number samples per tree.
+     */
+    RandomForestOptions & samples_per_tree(int (*in)(int))
+    {
+        training_set_func_ = in;
+        training_set_calc_switch_ = RF_FUNCTION;
+        return *this;
+    }
+    
+    /**\brief weight each tree with number of samples in that node
+     */
+    RandomForestOptions & predict_weighted()
+    {
+        predict_weighted_ = true;
+        return *this;
+    }
+
+    /**\brief use built in mapping to calculate mtry
+     *
+     * Use one of the built in mappings to calculate mtry from the number
+     * of columns in the input feature data.
+     * \param in possible values: RF_LOG, RF_SQRT or RF_ALL
+     *           <br> default: RF_SQRT.
+     */
+    RandomForestOptions & features_per_node(RF_OptionTag in)
+    {
+        vigra_precondition(in == RF_LOG ||
+                           in == RF_SQRT||
+                           in == RF_ALL,
+                           "RandomForestOptions()::features_per_node():"
+                           "input must be of type RF_LOG or RF_SQRT");
+        mtry_switch_ = in;
+        return *this;
+    }
+
+    /**\brief Set mtry to a constant value
+     *
+     * mtry is the number of columns/variates/variables randomly chosen
+     * to select the best split from.
+     *
+     */
+    RandomForestOptions & features_per_node(int in)
+    {
+        mtry_ = in;
+        mtry_switch_ = RF_CONST;
+        return *this;
+    }
+
+    /**\brief use a external function to calculate mtry
+     *
+     * \param in function pointer that takes int (number of columns
+     *           of the and outputs int (mtry)
+     */
+    RandomForestOptions & features_per_node(int(*in)(int))
+    {
+        mtry_func_ = in;
+        mtry_switch_ = RF_FUNCTION;
+        return *this;
+    }
+
+    /** How many trees to create?
+     *
+     * <br> Default: 255.
+     */
+    RandomForestOptions & tree_count(int in)
+    {
+        tree_count_ = in;
+        return *this;
+    }
+
+    /**\brief Number of examples required for a node to be split.
+     *
+     *  When the number of examples in a node is below this number,
+     *  the node is not split even if class separation is not yet perfect.
+     *  Instead, the node returns the proportion of each class
+     *  (among the remaining examples) during the prediction phase.
+     *  <br> Default: 1 (complete growing)
+     */
+    RandomForestOptions & min_split_node_size(int in)
+    {
+        min_split_node_size_ = in;
+        return *this;
+    }
+};
+
+
+/** \brief problem types 
+ */
+enum Problem_t{REGRESSION, CLASSIFICATION, CHECKLATER};
+
+
+/** \brief problem specification class for the random forest.
+ *
+ * This class contains all the problem specific parameters the random
+ * forest needs for learning. Specification of an instance of this class
+ * is optional as all necessary fields will be computed prior to learning
+ * if not specified.
+ *
+ * if needed usage is similar to that of RandomForestOptions
+ */
+
+template<class LabelType = double>
+class ProblemSpec
+{
+
+
+public:
+
+    /** \brief  problem class
+     */
+
+    typedef LabelType       Label_t;
+    ArrayVector<Label_t>    classes;
+    typedef ArrayVector<double>                 double_array;
+    typedef std::map<std::string, double_array> map_type;
+
+    int                     column_count_;    // number of features
+    int                     class_count_;     // number of classes
+    int                     row_count_;       // number of samples
+
+    int                     actual_mtry_;     // mtry used in training
+    int                     actual_msample_;  // number if in-bag samples per tree
+
+    Problem_t               problem_type_;    // classification or regression
+    
+    int used_;                                // this ProblemSpec is valid
+    ArrayVector<double>     class_weights_;   // if classes have different importance
+    int                     is_weighted_;     // class_weights_ are used
+    double                  precision_;       // termination criterion for regression loss
+    int                     response_size_; 
+        
+    template<class T> 
+    void to_classlabel(int index, T & out) const
+    {
+        out = T(classes[index]);
+    }
+    template<class T> 
+    int to_classIndex(T index) const
+    {
+        return std::find(classes.begin(), classes.end(), index) - classes.begin();
+    }
+
+    #define EQUALS(field) field(rhs.field)
+    ProblemSpec(ProblemSpec const & rhs)
+    : 
+        EQUALS(column_count_),
+        EQUALS(class_count_),
+        EQUALS(row_count_),
+        EQUALS(actual_mtry_),
+        EQUALS(actual_msample_),
+        EQUALS(problem_type_),
+        EQUALS(used_),
+        EQUALS(class_weights_),
+        EQUALS(is_weighted_),
+        EQUALS(precision_),
+        EQUALS(response_size_)
+    {
+        std::back_insert_iterator<ArrayVector<Label_t> >
+                        iter(classes);
+        std::copy(rhs.classes.begin(), rhs.classes.end(), iter); 
+    }
+    #undef EQUALS
+    #define EQUALS(field) field(rhs.field)
+    template<class T>
+    ProblemSpec(ProblemSpec<T> const & rhs)
+    : 
+        EQUALS(column_count_),
+        EQUALS(class_count_),
+        EQUALS(row_count_),
+        EQUALS(actual_mtry_),
+        EQUALS(actual_msample_),
+        EQUALS(problem_type_),
+        EQUALS(used_),
+        EQUALS(class_weights_),
+        EQUALS(is_weighted_),
+        EQUALS(precision_),
+        EQUALS(response_size_)
+    {
+        std::back_insert_iterator<ArrayVector<Label_t> >
+                        iter(classes);
+        std::copy(rhs.classes.begin(), rhs.classes.end(), iter); 
+    }
+    #undef EQUALS
+
+    #define EQUALS(field) (this->field = rhs.field);
+    ProblemSpec & operator=(ProblemSpec const & rhs)
+    {
+        EQUALS(column_count_);
+        EQUALS(class_count_);
+        EQUALS(row_count_);
+        EQUALS(actual_mtry_);
+        EQUALS(actual_msample_);
+        EQUALS(problem_type_);
+        EQUALS(used_);
+        EQUALS(is_weighted_);
+        EQUALS(precision_);
+        EQUALS(response_size_)
+        class_weights_.clear();
+        std::back_insert_iterator<ArrayVector<double> >
+                        iter2(class_weights_);
+        std::copy(rhs.class_weights_.begin(), rhs.class_weights_.end(), iter2); 
+        classes.clear();
+        std::back_insert_iterator<ArrayVector<Label_t> >
+                        iter(classes);
+        std::copy(rhs.classes.begin(), rhs.classes.end(), iter); 
+        return *this;
+    }
+
+    template<class T>
+    ProblemSpec<Label_t> & operator=(ProblemSpec<T> const & rhs)
+    {
+        EQUALS(column_count_);
+        EQUALS(class_count_);
+        EQUALS(row_count_);
+        EQUALS(actual_mtry_);
+        EQUALS(actual_msample_);
+        EQUALS(problem_type_);
+        EQUALS(used_);
+        EQUALS(is_weighted_);
+        EQUALS(precision_);
+        EQUALS(response_size_)
+        class_weights_.clear();
+        std::back_insert_iterator<ArrayVector<double> >
+                        iter2(class_weights_);
+        std::copy(rhs.class_weights_.begin(), rhs.class_weights_.end(), iter2); 
+        classes.clear();
+        std::back_insert_iterator<ArrayVector<Label_t> >
+                        iter(classes);
+        std::copy(rhs.classes.begin(), rhs.classes.end(), iter); 
+        return *this;
+    }
+    #undef EQUALS
+
+    template<class T>
+    bool operator==(ProblemSpec<T> const & rhs)
+    {
+        bool result = true;
+        #define COMPARE(field) result = result && (this->field == rhs.field);
+        COMPARE(column_count_);
+        COMPARE(class_count_);
+        COMPARE(row_count_);
+        COMPARE(actual_mtry_);
+        COMPARE(actual_msample_);
+        COMPARE(problem_type_);
+        COMPARE(is_weighted_);
+        COMPARE(precision_);
+        COMPARE(used_);
+        COMPARE(class_weights_);
+        COMPARE(classes);
+        COMPARE(response_size_)
+        #undef COMPARE
+        return result;
+    }
+
+    bool operator!=(ProblemSpec & rhs)
+    {
+        return !(*this == rhs);
+    }
+
+
+    size_t serialized_size() const
+    {
+        return 10 + class_count_ *int(is_weighted_+1);
+    }
+
+
+    template<class Iter>
+    void unserialize(Iter const & begin, Iter const & end)
+    {
+        Iter iter = begin;
+        vigra_precondition(end - begin >= 10, 
+                           "ProblemSpec::unserialize():"
+                           "wrong number of parameters");
+        #define PULL(item_, type_) item_ = type_(*iter); ++iter;
+        PULL(column_count_,int);
+        PULL(class_count_, int);
+
+        vigra_precondition(end - begin >= 10 + class_count_, 
+                           "ProblemSpec::unserialize(): 1");
+        PULL(row_count_, int);
+        PULL(actual_mtry_,int);
+        PULL(actual_msample_, int);
+        PULL(problem_type_, Problem_t);
+        PULL(is_weighted_, int);
+        PULL(used_, int);
+        PULL(precision_, double);
+        PULL(response_size_, int);
+        if(is_weighted_)
+        {
+            vigra_precondition(end - begin == 10 + 2*class_count_, 
+                               "ProblemSpec::unserialize(): 2");
+            class_weights_.insert(class_weights_.end(),
+                                  iter, 
+                                  iter + class_count_);
+            iter += class_count_; 
+        }
+        classes.insert(classes.end(), iter, end);
+        #undef PULL
+    }
+
+
+    template<class Iter>
+    void serialize(Iter const & begin, Iter const & end) const
+    {
+        Iter iter = begin;
+        vigra_precondition(end - begin == serialized_size(), 
+                           "RandomForestOptions::serialize():"
+                           "wrong number of parameters");
+        #define PUSH(item_) *iter = double(item_); ++iter;
+        PUSH(column_count_);
+        PUSH(class_count_)
+        PUSH(row_count_);
+        PUSH(actual_mtry_);
+        PUSH(actual_msample_);
+        PUSH(problem_type_);
+        PUSH(is_weighted_);
+        PUSH(used_);
+        PUSH(precision_);
+        PUSH(response_size_);
+        if(is_weighted_)
+        {
+            std::copy(class_weights_.begin(),
+                      class_weights_.end(),
+                      iter);
+            iter += class_count_; 
+        }
+        std::copy(classes.begin(),
+                  classes.end(),
+                  iter);
+        #undef PUSH
+    }
+
+    void make_from_map(map_type & in) // -> const: .operator[] -> .find
+    {
+        #define PULL(item_, type_) item_ = type_(in[#item_][0]); 
+        PULL(column_count_,int);
+        PULL(class_count_, int);
+        PULL(row_count_, int);
+        PULL(actual_mtry_,int);
+        PULL(actual_msample_, int);
+        PULL(problem_type_, (Problem_t)int);
+        PULL(is_weighted_, int);
+        PULL(used_, int);
+        PULL(precision_, double);
+        PULL(response_size_, int);
+        class_weights_ = in["class_weights_"];
+        #undef PUSH
+    }
+    void make_map(map_type & in) const
+    {
+        #define PUSH(item_) in[#item_] = double_array(1, double(item_));
+        PUSH(column_count_);
+        PUSH(class_count_)
+        PUSH(row_count_);
+        PUSH(actual_mtry_);
+        PUSH(actual_msample_);
+        PUSH(problem_type_);
+        PUSH(is_weighted_);
+        PUSH(used_);
+        PUSH(precision_);
+        PUSH(response_size_);
+        in["class_weights_"] = class_weights_;
+        #undef PUSH
+    }
+    
+    /**\brief set default values (-> values not set)
+     */
+    ProblemSpec()
+    :   column_count_(0),
+        class_count_(0),
+        row_count_(0),
+        actual_mtry_(0),
+        actual_msample_(0),
+        problem_type_(CHECKLATER),
+        used_(false),
+        is_weighted_(false),
+        precision_(0.0),
+        response_size_(1)
+    {}
+
+
+    ProblemSpec & column_count(int in)
+    {
+        column_count_ = in;
+        return *this;
+    }
+
+    /**\brief supply with class labels -
+     * 
+     * the preprocessor will not calculate the labels needed in this case.
+     */
+    template<class C_Iter>
+    ProblemSpec & classes_(C_Iter begin, C_Iter end)
+    {
+        int size = end-begin;
+        for(int k=0; k<size; ++k, ++begin)
+            classes.push_back(detail::RequiresExplicitCast<LabelType>::cast(*begin));
+        class_count_ = size;
+        return *this;
+    }
+
+    /** \brief supply with class weights  -
+     *
+     * this is the only case where you would really have to 
+     * create a ProblemSpec object.
+     */
+    template<class W_Iter>
+    ProblemSpec & class_weights(W_Iter begin, W_Iter end)
+    {
+        class_weights_.insert(class_weights_.end(), begin, end);
+        is_weighted_ = true;
+        return *this;
+    }
+
+
+
+    void clear()
+    {
+        used_ = false; 
+        classes.clear();
+        class_weights_.clear();
+        column_count_ = 0 ;
+        class_count_ = 0;
+        actual_mtry_ = 0;
+        actual_msample_ = 0;
+        problem_type_ = CHECKLATER;
+        is_weighted_ = false;
+        precision_   = 0.0;
+        response_size_ = 0;
+
+    }
+
+    bool used() const
+    {
+        return used_ != 0;
+    }
+};
+
+
+//@}
+
+
+
+/**\brief Standard early stopping criterion
+ *
+ * Stop if region.size() < min_split_node_size_;
+ */
+class EarlyStoppStd
+{
+    public:
+    int min_split_node_size_;
+
+    template<class Opt>
+    EarlyStoppStd(Opt opt)
+    :   min_split_node_size_(opt.min_split_node_size_)
+    {}
+
+    template<class T>
+    void set_external_parameters(ProblemSpec<T>const  &, int /* tree_count */ = 0, bool /* is_weighted_ */ = false)
+    {}
+
+    template<class Region>
+    bool operator()(Region& region)
+    {
+        return region.size() < min_split_node_size_;
+    }
+
+    template<class WeightIter, class T, class C>
+    bool after_prediction(WeightIter,  int /* k */, MultiArrayView<2, T, C> /* prob */, double /* totalCt */)
+    {
+        return false; 
+    }
+};
+
+
+} // namespace vigra
+
+#endif //VIGRA_RF_COMMON_HXX
diff --git a/include/vigra/random_forest/rf_decisionTree.hxx b/include/vigra/random_forest/rf_decisionTree.hxx
new file mode 100755
index 0000000..61e09f8
--- /dev/null
+++ b/include/vigra/random_forest/rf_decisionTree.hxx
@@ -0,0 +1,478 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by  Ullrich Koethe and Rahul Nair         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_RANDOM_FOREST_DT_HXX
+#define VIGRA_RANDOM_FOREST_DT_HXX
+
+#include <algorithm>
+#include <map>
+#include <numeric>
+#include "vigra/multi_array.hxx"
+#include "vigra/mathutil.hxx"
+#include "vigra/array_vector.hxx"
+#include "vigra/sized_int.hxx"
+#include "vigra/matrix.hxx"
+#include "vigra/random.hxx"
+#include "vigra/functorexpression.hxx"
+#include <vector>
+
+#include "rf_common.hxx"
+#include "rf_visitors.hxx"
+#include "rf_nodeproxy.hxx"
+namespace vigra
+{
+
+namespace detail
+{
+ // todo FINALLY DECIDE TO USE CAMEL CASE OR UNDERSCORES !!!!!!
+/* decisiontree classifier. 
+ *
+ * This class is actually meant to be used in conjunction with the 
+ * Random Forest Classifier 
+ * - My suggestion would be to use the RandomForest classifier with 
+ *   following parameters instead of directly using this 
+ *   class (Preprocessing default values etc is handled in there):
+ *
+ * \code
+ *      RandomForest decisionTree(RF_Traits::Options_t()
+ *                                  .features_per_node(RF_ALL)
+ *                                  .tree_count(1)            );
+ * \endcode
+ * 
+ * \todo remove the classCount and featurecount from the topology
+ *       array. Pass ext_param_ to the nodes!
+ * \todo Use relative addressing of nodes?
+ */
+class DecisionTree
+{
+    /* \todo make private?*/
+  public:
+    
+    /* value type of container array. use whenever referencing it
+     */
+    typedef Int32 TreeInt;
+
+    ArrayVector<TreeInt>  topology_;
+    ArrayVector<double>   parameters_;
+
+    ProblemSpec<> ext_param_;
+    unsigned int classCount_;
+
+
+  public:
+    /* \brief Create tree with parameters */
+    template<class T>
+    DecisionTree(ProblemSpec<T> ext_param)
+    :
+        ext_param_(ext_param),
+        classCount_(ext_param.class_count_)
+    {}
+
+    /* clears all memory used.
+     */
+    void reset(unsigned int classCount = 0)
+    {
+        if(classCount)
+            classCount_ = classCount;
+        topology_.clear();
+        parameters_.clear();
+    }
+
+
+    /* learn a Tree
+     *
+     * \tparam  StackEntry_t The Stackentry containing Node/StackEntry_t 
+     *          Information used during learning. Each Split functor has a 
+     *          Stack entry associated with it (Split_t::StackEntry_t)
+     * \sa RandomForest::learn()
+     */
+    template <  class U, class C,
+                class U2, class C2,
+                class StackEntry_t,
+                class Stop_t,
+                class Split_t,
+                class Visitor_t,
+                class Random_t >
+    void learn(     MultiArrayView<2, U, C> const      & features,
+                    MultiArrayView<2, U2, C2> const    & labels,
+                    StackEntry_t const &                 stack_entry,
+                    Split_t                              split,
+                    Stop_t                               stop,
+                    Visitor_t &                          visitor,
+                    Random_t &                           randint);
+    template <  class U, class C,
+             class U2, class C2,
+             class StackEntry_t,
+             class Stop_t,
+             class Split_t,
+             class Visitor_t,
+             class Random_t>
+    void continueLearn(   MultiArrayView<2, U, C> const       & features,
+                          MultiArrayView<2, U2, C2> const     & labels,
+                          StackEntry_t const &                  stack_entry,
+                          Split_t                               split,
+                          Stop_t                                stop,
+                          Visitor_t &                           visitor,
+                          Random_t &                            randint,
+                          //an index to which the last created exterior node will be moved (because it is not used anymore)
+                          int                                   garbaged_child=-1);
+
+    /* is a node a Leaf Node? */
+    inline bool isLeafNode(TreeInt in) const
+    {
+        return (in & LeafNodeTag) == LeafNodeTag;
+    }
+
+    /* data driven traversal from root to leaf
+     *
+     * traverse through tree with data given in features. Use Visitors to 
+     * collect statistics along the way. 
+     */
+    template<class U, class C, class Visitor_t>
+    TreeInt getToLeaf(MultiArrayView<2, U, C> const & features, 
+                      Visitor_t  & visitor) const
+    {
+        TreeInt index = 2;
+        while(!isLeafNode(topology_[index]))
+        {
+            visitor.visit_internal_node(*this, index, topology_[index],features);
+            switch(topology_[index])
+            {
+                case i_ThresholdNode:
+                {
+                    Node<i_ThresholdNode> 
+                                node(topology_, parameters_, index);
+                    index = node.next(features);
+                    break;
+                }
+                case i_HyperplaneNode:
+                {
+                    Node<i_HyperplaneNode> 
+                                node(topology_, parameters_, index);
+                    index = node.next(features);
+                    break;
+                }
+                case i_HypersphereNode:
+                {
+                    Node<i_HypersphereNode> 
+                                node(topology_, parameters_, index);
+                    index = node.next(features);
+                    break;
+                }
+#if 0 
+                // for quick prototyping! has to be implemented.
+                case i_VirtualNode:
+                {
+                    Node<i_VirtualNode> 
+                                node(topology_, parameters, index);
+                    index = node.next(features);
+                }
+#endif
+                default:
+                    vigra_fail("DecisionTree::getToLeaf():"
+                               "encountered unknown internal Node Type");
+            }
+        }
+        visitor.visit_external_node(*this, index, topology_[index],features);
+        return index;
+    }
+    /* traverse tree to get statistics
+     *
+     * Tree is traversed in order the Nodes are in memory (i.e. if no 
+     * relearning//pruning scheme is utilized this will be pre order)
+     */
+    template<class Visitor_t>
+    void traverse_mem_order(Visitor_t visitor) const
+    {
+        TreeInt index = 2;
+        Int32 ii = 0;
+        while(index < topology_.size())
+        {
+            if(isLeafNode(topology_[index]))
+            {
+                visitor
+                    .visit_external_node(*this, index, topology_[index]);
+            }
+            else
+            {
+                visitor
+                    ._internal_node(*this, index, topology_[index]);
+            }
+        }
+    }
+
+    template<class Visitor_t>
+    void traverse_post_order(Visitor_t visitor,  TreeInt start = 2) const
+    {
+        typedef TinyVector<double, 2> Entry; 
+        std::vector<Entry > stack;
+        std::vector<double> result_stack;
+        stack.push_back(Entry(2, 0));
+        int addr; 
+        while(!stack.empty())
+        {
+            addr = stack.back()[0];
+            NodeBase node(topology_, parameters_, stack.back()[0]);
+            if(stack.back()[1] == 1)
+            {
+                stack.pop_back();
+                double leftRes = result_stack.back();
+                double rightRes = result_stack.back();
+                result_stack.pop_back();
+                result_stack.pop_back();
+                result_stack.push_back(rightRes+ leftRes);
+                visitor.visit_internal_node(*this, 
+                                            addr, 
+                                            node.typeID(), 
+                                            rightRes+leftRes);
+            }
+            else
+            {
+                if(isLeafNode(node.typeID()))
+                {
+                    visitor.visit_external_node(*this, 
+                                                addr, 
+                                                node.typeID(), 
+                                                node.weights());
+                    stack.pop_back();
+                    result_stack.push_back(node.weights());
+                }
+                else
+                {
+                    stack.back()[1] = 1; 
+                    stack.push_back(Entry(node.child(0), 0));
+                    stack.push_back(Entry(node.child(1), 0));
+                }
+                    
+            }
+        }
+    }
+
+    /* same thing as above, without any visitors */
+    template<class U, class C>
+    TreeInt getToLeaf(MultiArrayView<2, U, C> const & features) const
+    {
+        ::vigra::rf::visitors::StopVisiting stop;
+        return getToLeaf(features, stop);
+    }
+
+
+    template <class U, class C>
+    ArrayVector<double>::iterator
+    predict(MultiArrayView<2, U, C> const & features) const
+    {
+        TreeInt nodeindex = getToLeaf(features);
+        switch(topology_[nodeindex])
+        {
+            case e_ConstProbNode:
+                return Node<e_ConstProbNode>(topology_, 
+                                             parameters_,
+                                             nodeindex).prob_begin();
+                break;
+#if 0 
+            //first make the Logistic regression stuff...
+            case e_LogRegProbNode:
+                return Node<e_LogRegProbNode>(topology_, 
+                                              parameters_,
+                                              nodeindex).prob_begin();
+#endif            
+            default:
+                vigra_fail("DecisionTree::predict() :"
+                           " encountered unknown external Node Type");
+        }
+        return ArrayVector<double>::iterator();
+    }
+
+
+
+    template <class U, class C>
+    Int32 predictLabel(MultiArrayView<2, U, C> const & features) const
+    {
+        ArrayVector<double>::const_iterator weights = predict(features);
+        return argMax(weights, weights+classCount_) - weights;
+    }
+
+};
+
+
+template <  class U, class C,
+            class U2, class C2,
+            class StackEntry_t,
+            class Stop_t,
+            class Split_t,
+            class Visitor_t,
+            class Random_t>
+void DecisionTree::learn(   MultiArrayView<2, U, C> const       & features,
+                            MultiArrayView<2, U2, C2> const     & labels,
+                            StackEntry_t const &                  stack_entry,
+                            Split_t                               split,
+                            Stop_t                                stop,
+                            Visitor_t &                           visitor,
+                            Random_t &                            randint)
+{
+    this->reset();
+    topology_.reserve(256);
+    parameters_.reserve(256);
+    topology_.push_back(features.shape(1));
+    topology_.push_back(classCount_);
+    continueLearn(features,labels,stack_entry,split,stop,visitor,randint);
+}
+
+template <  class U, class C,
+            class U2, class C2,
+            class StackEntry_t,
+            class Stop_t,
+            class Split_t,
+            class Visitor_t,
+            class Random_t>
+void DecisionTree::continueLearn(   MultiArrayView<2, U, C> const       & features,
+                            MultiArrayView<2, U2, C2> const     & labels,
+                            StackEntry_t const &                  stack_entry,
+                            Split_t                               split,
+                            Stop_t                                stop,
+                            Visitor_t &                           visitor,
+                            Random_t &                            randint,
+                            //an index to which the last created exterior node will be moved (because it is not used anymore)
+                            int                                   garbaged_child)
+{
+    std::vector<StackEntry_t> stack;
+    stack.reserve(128);
+    ArrayVector<StackEntry_t> child_stack_entry(2, stack_entry);
+    stack.push_back(stack_entry);
+    size_t last_node_pos = 0;
+    StackEntry_t top=stack.back();
+
+    while(!stack.empty())
+    {
+
+        // Take an element of the stack. Obvious ain't it?
+        top = stack.back();
+        stack.pop_back();
+
+        // Make sure no data from the last round has remained in Pipeline;
+        child_stack_entry[0].reset();
+        child_stack_entry[1].reset();
+        split.reset();
+
+
+        //Either the Stopping criterion decides that the split should 
+        //produce a Terminal Node or the Split itself decides what 
+        //kind of node to make
+        TreeInt NodeID;
+        
+        if(stop(top))
+            NodeID = split.makeTerminalNode(features, 
+                                            labels, 
+                                            top, 
+                                            randint);
+        else
+        {
+            //TIC;
+            NodeID = split.findBestSplit(features, 
+                                         labels, 
+                                         top, 
+                                         child_stack_entry, 
+                                         randint);
+            //std::cerr << TOC <<" " << NodeID << ";" <<std::endl;
+        }
+
+        // do some visiting yawn - just added this comment as eye candy
+        // (looks odd otherwise with my syntax highlighting....
+        visitor.visit_after_split(*this, split, top, 
+                                  child_stack_entry[0], 
+                                  child_stack_entry[1],
+                                  features, 
+                                  labels);
+
+
+        // Update the Child entries of the parent
+        // Using InteriorNodeBase because exact parameter form not needed.
+        // look at the Node base before getting scared.
+        last_node_pos = topology_.size();
+        if(top.leftParent != StackEntry_t::DecisionTreeNoParent)
+        {
+            NodeBase(topology_, 
+                     parameters_, 
+                     top.leftParent).child(0) = last_node_pos;
+        }
+        else if(top.rightParent != StackEntry_t::DecisionTreeNoParent)
+        {
+            NodeBase(topology_, 
+                     parameters_, 
+                     top.rightParent).child(1) = last_node_pos;
+        }
+
+
+        // Supply the split functor with the Node type it requires.
+        // set the address to which the children of this node should point 
+        // to and push back children onto stack
+        if(!isLeafNode(NodeID))
+        {
+            child_stack_entry[0].leftParent = topology_.size();
+            child_stack_entry[1].rightParent = topology_.size();    
+            child_stack_entry[0].rightParent = -1;
+            child_stack_entry[1].leftParent = -1;
+            stack.push_back(child_stack_entry[0]);
+            stack.push_back(child_stack_entry[1]);
+        }
+
+        //copy the newly created node form the split functor to the
+        //decision tree.
+        NodeBase node(split.createNode(), topology_, parameters_ );
+    }
+    if(garbaged_child!=-1)
+    {
+        Node<e_ConstProbNode>(topology_,parameters_,garbaged_child).copy(Node<e_ConstProbNode>(topology_,parameters_,last_node_pos));
+
+        int last_parameter_size = Node<e_ConstProbNode>(topology_,parameters_,garbaged_child).parameters_size();
+        topology_.resize(last_node_pos);
+        parameters_.resize(parameters_.size() - last_parameter_size);
+    
+        if(top.leftParent != StackEntry_t::DecisionTreeNoParent)
+            NodeBase(topology_, 
+                     parameters_, 
+                     top.leftParent).child(0) = garbaged_child;
+        else if(top.rightParent != StackEntry_t::DecisionTreeNoParent)
+            NodeBase(topology_, 
+                     parameters_, 
+                     top.rightParent).child(1) = garbaged_child;
+    }
+}
+
+} //namespace detail
+
+} //namespace vigra
+
+#endif //VIGRA_RANDOM_FOREST_DT_HXX
diff --git a/include/vigra/random_forest/rf_earlystopping.hxx b/include/vigra/random_forest/rf_earlystopping.hxx
new file mode 100644
index 0000000..37dffd7
--- /dev/null
+++ b/include/vigra/random_forest/rf_earlystopping.hxx
@@ -0,0 +1,418 @@
+#ifndef RF_EARLY_STOPPING_P_HXX
+#define RF_EARLY_STOPPING_P_HXX
+#include <cmath>
+#include "rf_common.hxx"
+
+namespace vigra
+{
+
+#if 0    
+namespace es_detail
+{
+    template<class T>
+    T power(T const & in, int n)
+    {
+        T result = NumericTraits<T>::one();
+        for(int ii = 0; ii < n ;++ii)
+            result *= in;
+        return result;
+    }
+}
+#endif
+
+/**Base class from which all EarlyStopping Functors derive.
+ */
+class StopBase
+{
+protected:
+    ProblemSpec<> ext_param_;
+    int tree_count_ ;
+    bool is_weighted_;
+
+public:
+    template<class T>
+    void set_external_parameters(ProblemSpec<T> const  &prob, int tree_count = 0, bool is_weighted = false)
+    {
+        ext_param_ = prob; 
+        is_weighted_ = is_weighted;
+        tree_count_ = tree_count;
+    }
+
+#ifdef DOXYGEN
+        /** called after the prediction of a tree was added to the total prediction
+         * \param weightIter Iterator to the weights delivered by current tree.
+         * \param k          after kth tree
+         * \param prob       Total probability array
+         * \param totalCt    sum of probability array. 
+         */
+    template<class WeightIter, class T, class C>
+    bool after_prediction(WeightIter weightIter, int k, MultiArrayView<2, T, C> const &  prob , double totalCt)
+#else
+    template<class WeightIter, class T, class C>
+    bool after_prediction(WeightIter,  int /* k */, MultiArrayView<2, T, C> const & /* prob */, double /* totalCt */)
+    {return false;}
+#endif //DOXYGEN
+};
+
+
+/**Stop predicting after a set number of trees
+ */
+class StopAfterTree : public StopBase
+{
+public:
+    double max_tree_p;
+    int max_tree_;
+    typedef StopBase SB;
+    
+    ArrayVector<double> depths;
+    
+    /** Constructor
+     * \param max_tree number of trees to be used for prediction
+     */
+    StopAfterTree(double max_tree)
+    :
+        max_tree_p(max_tree)
+    {}
+
+    template<class T>
+    void set_external_parameters(ProblemSpec<T> const  &prob, int tree_count = 0, bool is_weighted = false)
+    {
+        max_tree_ = ceil(max_tree_p * tree_count);
+        SB::set_external_parameters(prob, tree_count, is_weighted);
+    }
+
+    template<class WeightIter, class T, class C>
+    bool after_prediction(WeightIter,  int k, MultiArrayView<2, T, C> const & /* prob */, double /* totalCt */)
+    {
+        if(k == SB::tree_count_ -1)
+        {
+                depths.push_back(double(k+1)/double(SB::tree_count_));
+                return false;
+        }
+        if(k < max_tree_)
+           return false;
+        depths.push_back(double(k+1)/double(SB::tree_count_));
+        return true;  
+    }
+};
+
+/** Stop predicting after a certain amount of votes exceed certain proportion.
+ *  case unweighted voting: stop if the leading class exceeds proportion * SB::tree_count_ 
+ *  case weighted voting: stop if the leading class exceeds proportion * msample_ * SB::tree_count_ ;
+ *                          (maximal number of votes possible in both cases)
+ */
+class StopAfterVoteCount : public StopBase
+{
+public:
+    double proportion_;
+    typedef StopBase SB;
+    ArrayVector<double> depths;
+
+    /** Constructor
+     * \param proportion specify proportion to be used.
+     */
+    StopAfterVoteCount(double proportion)
+    :
+        proportion_(proportion)
+    {}
+
+    template<class WeightIter, class T, class C>
+    bool after_prediction(WeightIter,  int k, MultiArrayView<2, T, C> const & prob, double /* totalCt */)
+    {
+        if(k == SB::tree_count_ -1)
+        {
+                depths.push_back(double(k+1)/double(SB::tree_count_));
+                return false;
+        }
+
+
+        if(SB::is_weighted_)
+        {
+            if(prob[argMax(prob)] > proportion_ *SB::ext_param_.actual_msample_* SB::tree_count_)
+            {
+                depths.push_back(double(k+1)/double(SB::tree_count_));
+                return true;
+            }
+        }
+        else
+        {
+            if(prob[argMax(prob)] > proportion_ * SB::tree_count_)
+            {
+                depths.push_back(double(k+1)/double(SB::tree_count_));
+                return true;
+            }
+        }
+        return false;
+    }
+
+};
+
+
+/** Stop predicting if the 2norm of the probabilities does not change*/
+class StopIfConverging : public StopBase
+
+{
+public:
+    double thresh_;
+    int num_;
+    MultiArray<2, double> last_;
+    MultiArray<2, double> cur_;
+    ArrayVector<double> depths;
+    typedef StopBase SB;
+
+    /** Constructor
+     * \param thresh: If the two norm of the probabilities changes less then thresh then stop
+     * \param num   : look at atleast num trees before stopping
+     */
+    StopIfConverging(double thresh, int num = 10)
+    :
+        thresh_(thresh), 
+        num_(num)
+    {}
+
+    template<class T>
+    void set_external_parameters(ProblemSpec<T> const  &prob, int tree_count = 0, bool is_weighted = false)
+    {
+        last_.reshape(MultiArrayShape<2>::type(1, prob.class_count_), 0);
+        cur_.reshape(MultiArrayShape<2>::type(1, prob.class_count_), 0);
+        SB::set_external_parameters(prob, tree_count, is_weighted);
+    }
+    template<class WeightIter, class T, class C>
+    bool after_prediction(WeightIter iter,  int k, MultiArrayView<2, T, C> const & prob, double totalCt)
+    {
+        if(k == SB::tree_count_ -1)
+        {
+                depths.push_back(double(k+1)/double(SB::tree_count_));
+                return false;
+        }
+        if(k <= num_)
+        {
+            last_ = prob;
+            last_/= last_.norm(1);
+            return false;
+        }
+        else 
+        {
+            cur_ = prob;
+            cur_ /= cur_.norm(1);
+            last_ -= cur_;
+            double nrm = last_.norm(); 
+            if(nrm < thresh_)
+            {
+                depths.push_back(double(k+1)/double(SB::tree_count_));
+                return true;
+            }
+            else
+            {
+                last_ = cur_;
+            }
+        }
+        return false;
+    }
+};
+
+
+/** Stop predicting if the margin prob(leading class) - prob(second class) exceeds a proportion
+ *  case unweighted voting: stop if margin exceeds proportion * SB::tree_count_ 
+ *  case weighted voting: stop if margin exceeds proportion * msample_ * SB::tree_count_ ;
+ *                          (maximal number of votes possible in both cases)
+ */
+class StopIfMargin : public StopBase  
+{
+public:
+    double proportion_;
+    typedef StopBase SB;
+    ArrayVector<double> depths;
+
+    /** Constructor
+     * \param proportion specify proportion to be used.
+     */
+    StopIfMargin(double proportion)
+    :
+        proportion_(proportion)
+    {}
+
+    template<class WeightIter, class T, class C>
+    bool after_prediction(WeightIter,  int k, MultiArrayView<2, T, C> prob, double /* totalCt */)
+    {
+        if(k == SB::tree_count_ -1)
+        {
+                depths.push_back(double(k+1)/double(SB::tree_count_));
+                return false;
+        }
+        int index = argMax(prob);
+        double a = prob[argMax(prob)];
+        prob[argMax(prob)] = 0;
+        double b = prob[argMax(prob)];
+        prob[index] = a; 
+        double margin = a - b;
+        if(SB::is_weighted_)
+        {
+            if(margin > proportion_ *SB::ext_param_.actual_msample_ * SB::tree_count_)
+            {
+                depths.push_back(double(k+1)/double(SB::tree_count_));
+                return true;
+            }
+        }
+        else
+        {
+            if(prob[argMax(prob)] > proportion_ * SB::tree_count_)
+            {
+                depths.push_back(double(k+1)/double(SB::tree_count_));
+                return true;
+            }
+        }
+        return false;
+    }
+};
+
+
+/**Probabilistic Stopping criterion (binomial test)
+ *
+ * Can only be used in a two class setting
+ *
+ * Stop if the Parameters estimated for the underlying binomial distribution
+ * can be estimated with certainty over 1-alpha.
+ * (Thesis, Rahul Nair Page 80 onwards: called the "binomial" criterion
+ */
+class StopIfBinTest : public StopBase  
+{
+public:
+    double alpha_;  
+    MultiArrayView<2, double> n_choose_k;
+    /** Constructor
+     * \param alpha specify alpha (=proportion) value for binomial test.
+     * \param nck_ Matrix with precomputed values for n choose k
+     * nck_(n, k) is n choose k. 
+     */
+    StopIfBinTest(double alpha, MultiArrayView<2, double> nck_)
+    :
+        alpha_(alpha),
+        n_choose_k(nck_)
+    {}
+    typedef StopBase SB;
+    
+    /**ArrayVector that will contain the fraction of trees that was visited before terminating
+     */
+    ArrayVector<double> depths;
+
+    double binomial(int N, int k, double p)
+    {
+//        return n_choose_k(N, k) * es_detail::power(p, k) *es_detail::power(1 - p, N-k);
+        return n_choose_k(N, k) * std::pow(p, k) * std::pow(1 - p, N-k);
+    }
+
+    template<class WeightIter, class T, class C>
+    bool after_prediction(WeightIter iter,  int k, MultiArrayView<2, T, C> prob, double totalCt)
+    {
+        if(k == SB::tree_count_ -1)
+        {
+                depths.push_back(double(k+1)/double(SB::tree_count_));
+                return false;
+        }
+        if(k < 10)
+        {
+            return false;
+        }
+        int index = argMax(prob);
+        int n_a  = prob[index];
+        int n_b  = prob[(index+1)%2];
+        int n_tilde = (SB::tree_count_ - n_a + n_b);
+        double p_a = double(n_b - n_a + n_tilde)/double(2* n_tilde);
+        vigra_precondition(p_a <= 1, "probability should be smaller than 1");
+        double cum_val = 0;
+        int c = 0; 
+  //      std::cerr << "prob: " << p_a << std::endl;
+        if(n_a <= 0)n_a = 0;
+        if(n_b <= 0)n_b = 0;
+        for(int ii = 0; ii <= n_b + n_a;++ii)
+        {
+//            std::cerr << "nb +ba " << n_b + n_a << " " << ii <<std::endl;
+            cum_val += binomial(n_b + n_a, ii, p_a); 
+            if(cum_val >= 1 -alpha_)
+            {
+                c = ii;
+                break;
+            }
+        }
+//        std::cerr << c << " " << n_a << " " << n_b << " " << p_a <<   alpha_ << std::endl;
+        if(c < n_a)
+        {
+            depths.push_back(double(k+1)/double(SB::tree_count_));
+            return true;
+        }
+
+        return false;
+    }
+};
+
+/**Probabilistic Stopping criteria. (toChange)
+ *
+ * Can only be used in a two class setting
+ *
+ * Stop if the probability that the decision will change after seeing all trees falls under
+ * a specified value alpha.
+ * (Thesis, Rahul Nair Page 80 onwards: called the "toChange" criterion
+ */
+class StopIfProb : public StopBase  
+{
+public:
+    double alpha_;  
+    MultiArrayView<2, double> n_choose_k;
+    
+    
+    /** Constructor
+     * \param alpha specify alpha (=proportion) value
+     * \param nck_ Matrix with precomputed values for n choose k
+     * nck_(n, k) is n choose k. 
+     */
+    StopIfProb(double alpha, MultiArrayView<2, double> nck_)
+    :
+        alpha_(alpha),
+        n_choose_k(nck_)
+    {}
+    typedef StopBase SB;
+    /**ArrayVector that will contain the fraction of trees that was visited before terminating
+     */
+    ArrayVector<double> depths;
+
+    double binomial(int N, int k, double p)
+    {
+//        return n_choose_k(N, k) * es_detail::power(p, k) *es_detail::power(1 - p, N-k);
+        return n_choose_k(N, k) * std::pow(p, k) * std::pow(1 - p, N-k);
+    }
+
+    template<class WeightIter, class T, class C>
+    bool after_prediction(WeightIter iter,  int k, MultiArrayView<2, T, C> prob, double totalCt)
+    {
+        if(k == SB::tree_count_ -1)
+        {
+                depths.push_back(double(k+1)/double(SB::tree_count_));
+                return false;
+        }
+        if(k <= 10)
+        {
+            return false;
+        }
+        int index = argMax(prob);
+        int n_a  = prob[index];
+        int n_b  = prob[(index+1)%2];
+        int n_needed = ceil(double(SB::tree_count_)/2.0)-n_a;
+        int n_tilde = SB::tree_count_ - (n_a +n_b);
+        if(n_tilde <= 0) n_tilde = 0;
+        if(n_needed <= 0) n_needed = 0;
+        double p = 0;
+        for(int ii = n_needed; ii < n_tilde; ++ii)
+            p += binomial(n_tilde, ii, 0.5);
+        
+        if(p >= 1-alpha_)
+        {
+            depths.push_back(double(k+1)/double(SB::tree_count_));
+            return true;
+        }
+
+        return false;
+    }
+};
+} //namespace vigra;
+#endif //RF_EARLY_STOPPING_P_HXX
diff --git a/include/vigra/random_forest/rf_nodeproxy.hxx b/include/vigra/random_forest/rf_nodeproxy.hxx
new file mode 100755
index 0000000..7da919b
--- /dev/null
+++ b/include/vigra/random_forest/rf_nodeproxy.hxx
@@ -0,0 +1,672 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by  Ullrich Koethe and Rahul Nair         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_RANDOM_FOREST_NP_HXX
+#define VIGRA_RANDOM_FOREST_NP_HXX
+
+#include <algorithm>
+#include <map>
+#include <numeric>
+#include "vigra/mathutil.hxx"
+#include "vigra/array_vector.hxx"
+#include "vigra/sized_int.hxx"
+#include "vigra/matrix.hxx"
+#include "vigra/random.hxx"
+#include "vigra/functorexpression.hxx"
+
+
+namespace vigra
+{
+
+
+
+enum NodeTags
+{
+    UnFilledNode        = 42,
+    AllColumns          = 0x00000000,
+    ToBePrunedTag       = 0x80000000,
+    LeafNodeTag         = 0x40000000,
+
+    i_ThresholdNode     = 0,
+    i_HyperplaneNode    = 1,
+    i_HypersphereNode   = 2,
+    e_ConstProbNode     = 0 | LeafNodeTag,
+    e_LogRegProbNode    = 1 | LeafNodeTag
+};
+
+/** NodeBase class.
+
+    \ingroup DecicionTree
+
+    This class implements common features of all nodes.
+    Memory Structure:
+        Int32   Array:  TypeID, ParameterAddr, Child0, Child1, [ColumnData]0_
+        double  Array:  NodeWeight, [Parameters]1_
+
+        TODO: Throw away the crappy iterators and use vigra::ArrayVectorView
+             it is not like anybody else is going to use this NodeBase class
+             is it?
+
+        TODO: use the RF_Traits::ProblemSpec_t to specify the external 
+             parameters instead of the options.
+*/
+
+
+class NodeBase
+{
+  public:
+    typedef Int32                               INT;
+    typedef ArrayVector<INT>                    T_Container_type;
+    typedef ArrayVector<double>                 P_Container_type;
+    typedef T_Container_type::iterator          Topology_type;
+    typedef P_Container_type::iterator          Parameter_type;
+
+
+    mutable Topology_type                       topology_;
+    int                                         topology_size_;
+
+    mutable Parameter_type                      parameters_;
+    int                                         parameter_size_ ;
+
+        // Tree Parameters
+    int                                         featureCount_;
+    int                                         classCount_;
+
+        // Node Parameters
+    bool                                        hasData_;
+
+
+
+
+    /** get Node Weight
+     */
+    double &      weights()
+    {
+            return parameters_begin()[0];
+    }
+
+    double const &      weights() const
+    {
+            return parameters_begin()[0];
+    }
+
+    /** has the data been set?
+     * todo: throw this out - bad design
+     */
+    bool          data() const
+    {
+        return hasData_;
+    }
+
+    /** get the node type id
+     * \sa NodeTags
+     */
+    INT&          typeID()
+    {
+        return topology_[0];
+    }
+
+    INT const &          typeID() const
+    {
+        return topology_[0];
+    }
+
+    /** Where in the parameter_ array are the weights?
+     */
+    INT &          parameter_addr()
+    {
+        return topology_[1];
+    }
+
+    INT const &    parameter_addr() const
+    {
+        return topology_[1];
+    }
+
+    /** Column Range **/
+    Topology_type  column_data() const
+    {
+        return topology_ + 4 ;
+    }
+
+    /** get the start iterator to the columns
+     *  - once again - throw out - static members are crap.
+     */
+    Topology_type columns_begin() const
+    {
+            return column_data()+1;
+    }
+
+    /** how many columns?
+     */
+    int      columns_size() const
+    {
+        if(*column_data() == AllColumns)
+            return featureCount_;
+        else
+            return *column_data();;
+    }
+
+    /** end iterator to the columns
+     */
+    Topology_type  columns_end() const
+    {
+        return columns_begin() + columns_size();
+    }
+
+    /** Topology Range - gives access to the raw Topo memory
+     * the size_ member was added as a result of premature 
+     * optimisation.
+     */ 
+    Topology_type   topology_begin() const
+    {
+        return topology_;
+    }
+    Topology_type   topology_end() const
+    {
+        return topology_begin() + topology_size();
+    }
+    int          topology_size() const
+    {
+        return topology_size_;
+    }
+
+    /** Parameter Range **/
+    Parameter_type  parameters_begin() const
+    {
+        return parameters_;
+    }
+    Parameter_type  parameters_end() const
+    {
+        return parameters_begin() + parameters_size();
+    }
+
+    int          parameters_size() const
+    {
+        return parameter_size_;
+    }
+
+
+    /** where are the child nodes?
+     */
+    INT &           child(Int32 l)
+    {
+        return topology_begin()[2+l];
+    }
+
+    /** where are the child nodes?
+     */
+    INT const  &           child(Int32 l) const
+    {
+        return topology_begin()[2+l];
+    }
+
+    /** Default Constructor**/
+    NodeBase()
+    :
+                    hasData_(false)
+    {}
+    void copy(const NodeBase& o)
+    {
+        vigra_precondition(topology_size_==o.topology_size_,"Cannot copy nodes of different sizes");
+        vigra_precondition(featureCount_==o.featureCount_,"Cannot copy nodes with different feature count");
+        vigra_precondition(classCount_==o.classCount_,"Cannot copy nodes with different class counts");
+        vigra_precondition(parameters_size() ==o.parameters_size(),"Cannot copy nodes with different parameter sizes");
+        std::copy(o.topology_begin(), o.topology_end(), topology_);
+        std::copy(o.parameters_begin(),o.parameters_end(), parameters_);
+    }
+
+    /** create ReadOnly Base Node at position n (actual length is unknown)
+     * only common features i.e. children etc are accessible.
+     */
+    NodeBase(   T_Container_type const   &  topology,
+                P_Container_type const   &  parameter,
+                INT                         n)
+    :
+                    topology_   (const_cast<Topology_type>(topology.begin()+ n)),
+                    topology_size_(4),
+                    parameters_  (const_cast<Parameter_type>(parameter.begin() + parameter_addr())),
+                    parameter_size_(1),
+                    featureCount_(topology[0]),
+                    classCount_(topology[1]),
+                    hasData_(true)
+    {
+        /*while((int)xrange.size() <  featureCount_)
+            xrange.push_back(xrange.size());*/
+    }
+
+    /** create ReadOnly node with known length (the parameter range is valid)
+     */
+    NodeBase(   int                      tLen,
+                int                      pLen,
+                T_Container_type const & topology,
+                P_Container_type const & parameter,
+                INT                         n)
+    :
+                    topology_   (const_cast<Topology_type>(topology.begin()+ n)),
+                    topology_size_(tLen),
+                    parameters_  (const_cast<Parameter_type>(parameter.begin() + parameter_addr())),
+                    parameter_size_(pLen),
+                    featureCount_(topology[0]),
+                    classCount_(topology[1]),
+                    hasData_(true)
+    {
+        /*while((int)xrange.size() <  featureCount_)
+            xrange.push_back(xrange.size());*/
+    }
+    /** create ReadOnly node with known length 
+     * from existing Node
+     */
+    NodeBase(   int                      tLen,
+                int                      pLen,
+                NodeBase &               node)
+    :
+                    topology_   (node.topology_),
+                    topology_size_(tLen),
+                    parameters_  (node.parameters_),
+                    parameter_size_(pLen),
+                    featureCount_(node.featureCount_),
+                    classCount_(node.classCount_),
+                    hasData_(true)
+    {
+        /*while((int)xrange.size() <  featureCount_)
+            xrange.push_back(xrange.size());*/
+    }
+
+
+   /** create new Node at end of vector
+    * \param tLen number of integers needed in the topolog vector
+    * \param pLen number of parameters needed (this includes the node
+    *           weight)
+    * \param topology reference to Topology array of decision tree.
+    * \param parameter reference to Parameter array of decision tree.
+    **/
+    NodeBase(   int                      tLen,
+                int                      pLen,
+                T_Container_type   &        topology,
+                P_Container_type   &        parameter)
+    :
+                    topology_size_(tLen),
+                    parameter_size_(pLen),
+                    featureCount_(topology[0]),
+                    classCount_(topology[1]),
+                    hasData_(true)
+    {
+        /*while((int)xrange.size() <  featureCount_)
+            xrange.push_back(xrange.size());*/
+
+        size_t n = topology.size();
+        for(int ii = 0; ii < tLen; ++ii)
+            topology.push_back(0);
+        //topology.resize (n  + tLen);
+
+        topology_           =   topology.begin()+ n;
+        typeID()            =   UnFilledNode;
+
+        parameter_addr()    =   static_cast<int>(parameter.size());
+
+        //parameter.resize(parameter.size() + pLen);
+        for(int ii = 0; ii < pLen; ++ii)
+            parameter.push_back(0);
+
+        parameters_          =   parameter.begin()+ parameter_addr();
+        weights() = 1;
+    }
+
+
+  /** PseudoCopy Constructor  - 
+   *
+   * Copy Node to the end of a container. 
+   * Since each Node views on different data there can't be a real 
+   * copy constructor (unless both objects should point to the 
+   * same underlying data.                                  
+   */
+    NodeBase(   NodeBase      const  &    toCopy,
+                T_Container_type      &    topology,
+                P_Container_type     &    parameter)
+    :
+                    topology_size_(toCopy.topology_size()),
+                    parameter_size_(toCopy.parameters_size()),
+                    featureCount_(topology[0]),
+                    classCount_(topology[1]),
+                    hasData_(true)
+    {
+        /*while((int)xrange.size() <  featureCount_)
+            xrange.push_back(xrange.size());*/
+
+        size_t n            = topology.size();
+        for(int ii = 0; ii < toCopy.topology_size(); ++ii)
+            topology.push_back(toCopy.topology_begin()[ii]);
+//        topology.insert(topology.end(), toCopy.topology_begin(), toCopy.topology_end());
+        topology_           =   topology.begin()+ n;
+        parameter_addr()    =   static_cast<int>(parameter.size());
+        for(int ii = 0; ii < toCopy.parameters_size(); ++ii)
+            parameter.push_back(toCopy.parameters_begin()[ii]);
+//        parameter.insert(parameter.end(), toCopy.parameters_begin(), toCopy.parameters_end());
+        parameters_          =   parameter.begin()+ parameter_addr();
+    }
+};
+
+
+template<NodeTags NodeType>
+class Node;
+
+template<>
+class Node<i_ThresholdNode>
+: public NodeBase
+{
+
+
+    public:
+    typedef NodeBase BT;
+
+        /**constructors **/
+
+    Node(   BT::T_Container_type &   topology,
+            BT::P_Container_type &   param)
+                :   BT(5,2,topology, param)
+    {
+        BT::typeID() = i_ThresholdNode;
+    }
+
+    Node(   BT::T_Container_type const     &   topology,
+            BT::P_Container_type const     &   param,
+                    INT                   n             )
+                :   BT(5,2,topology, param, n)
+    {}
+
+    Node( BT & node_)
+        :   BT(5, 2, node_) 
+    {}
+
+    double& threshold()
+    {
+        return BT::parameters_begin()[1];
+    }
+
+    double const & threshold() const
+    {
+        return BT::parameters_begin()[1];
+    }
+
+    BT::INT& column()
+    {
+        return BT::column_data()[0];
+    }
+    BT::INT const & column() const
+    {
+        return BT::column_data()[0];
+    }
+
+    template<class U, class C>
+    BT::INT  next(MultiArrayView<2,U,C> const & feature) const
+    {
+        return (feature(0, column()) < threshold())? child(0):child(1);
+    }
+};
+
+
+template<>
+class Node<i_HyperplaneNode>
+: public NodeBase
+{
+    public:
+
+    typedef NodeBase BT;
+
+        /**constructors **/
+
+    Node(           int                      nCol,
+                    BT::T_Container_type    &   topology,
+                    BT::P_Container_type    &   split_param)
+                :   BT(nCol + 5,nCol + 2,topology, split_param)
+    {
+        BT::typeID() = i_HyperplaneNode;
+    }
+
+    Node(           BT::T_Container_type  const  &   topology,
+                    BT::P_Container_type  const  &   split_param,
+                    int                  n             )
+                :   NodeBase(5 , 2,topology, split_param, n)
+    {
+        //TODO : is there a more elegant way to do this?
+        BT::topology_size_ += BT::column_data()[0]== AllColumns ?
+                                        0
+                                    :   BT::column_data()[0];
+        BT::parameter_size_ += BT::columns_size();
+    }
+
+    Node( BT & node_)
+        :   BT(5, 2, node_) 
+    {
+        //TODO : is there a more elegant way to do this?
+        BT::topology_size_ += BT::column_data()[0]== AllColumns ?
+                                        0
+                                    :   BT::column_data()[0];
+        BT::parameter_size_ += BT::columns_size();
+    }
+
+
+    double const & intercept() const
+    {
+        return BT::parameters_begin()[1];
+    }
+    double& intercept()
+    {
+        return BT::parameters_begin()[1];
+    }
+
+    BT::Parameter_type weights() const
+    {
+        return BT::parameters_begin()+2;
+    }
+
+    BT::Parameter_type weights()
+    {
+        return BT::parameters_begin()+2;
+    }
+
+
+    template<class U, class C>
+    BT::INT next(MultiArrayView<2,U,C> const & feature) const
+    {
+        double result = -1 * intercept();
+        if(*(BT::column_data()) == AllColumns)
+        {
+            for(int ii = 0; ii < BT::columns_size(); ++ii)
+            {
+                result +=feature[ii] * weights()[ii];
+            }
+        }
+        else
+        {
+            for(int ii = 0; ii < BT::columns_size(); ++ii)
+            {
+                result +=feature[BT::columns_begin()[ii]] * weights()[ii];
+            }
+        }
+        return result < 0 ? BT::child(0)
+                          : BT::child(1);
+    }
+};
+
+
+
+template<>
+class Node<i_HypersphereNode>
+: public NodeBase
+{
+    public:
+
+    typedef NodeBase BT;
+
+        /**constructors **/
+
+    Node(           int                      nCol,
+                    BT::T_Container_type    &   topology,
+                    BT::P_Container_type    &   param)
+                :   NodeBase(nCol + 5,nCol + 1,topology, param)
+    {
+        BT::typeID() = i_HypersphereNode;
+    }
+
+    Node(           BT::T_Container_type  const  &   topology,
+                    BT::P_Container_type  const  &  param,
+                    int                  n             )
+                :   NodeBase(5, 1,topology, param, n)
+    {
+        BT::topology_size_ += BT::column_data()[0]== AllColumns ?
+                                        0
+                                    :   BT::column_data()[0];
+        BT::parameter_size_ += BT::columns_size();
+    }
+
+    Node( BT & node_)
+        :   BT(5, 1, node_) 
+    {
+        BT::topology_size_ += BT::column_data()[0]== AllColumns ?
+                                        0
+                                    :   BT::column_data()[0];
+        BT::parameter_size_ += BT::columns_size();
+
+    }
+
+    double const & squaredRadius() const
+    {
+        return BT::parameters_begin()[1];
+    }
+
+    double& squaredRadius()
+    {
+        return BT::parameters_begin()[1];
+    }
+
+    BT::Parameter_type center() const
+    {
+        return BT::parameters_begin()+2;
+    }
+
+    BT::Parameter_type center()
+    {
+        return BT::parameters_begin()+2;
+    }
+
+    template<class U, class C>
+    BT::INT next(MultiArrayView<2,U,C> const & feature) const
+    {
+        double result = -1 * squaredRadius();
+        if(*(BT::column_data()) == AllColumns)
+        {
+            for(int ii = 0; ii < BT::columns_size(); ++ii)
+            {
+                result += (feature[ii] - center()[ii])*
+                          (feature[ii] - center()[ii]);
+            }
+        }
+        else
+        {
+            for(int ii = 0; ii < BT::columns_size(); ++ii)
+            {
+                result += (feature[BT::columns_begin()[ii]] - center()[ii])*
+                          (feature[BT::columns_begin()[ii]] - center()[ii]);
+            }
+        }
+        return result < 0 ? BT::child(0)
+                          : BT::child(1);
+    }
+};
+
+
+/** ExteriorNodeBase class.
+
+    \ingroup DecicionTree
+
+    This class implements common features of all interior nodes.
+    All interior nodes are derived classes of ExteriorNodeBase.
+*/
+
+
+
+
+
+
+template<>
+class Node<e_ConstProbNode>
+: public NodeBase
+{
+    public:
+
+    typedef     NodeBase    BT;
+
+    Node(           BT::T_Container_type    &   topology,
+                    BT::P_Container_type    &   param)
+                    :
+                BT(2,topology[1]+1, topology, param)
+
+    {
+        BT::typeID() = e_ConstProbNode;
+    }
+
+
+    Node(           BT::T_Container_type const &   topology,
+                    BT::P_Container_type const &   param,
+                    int                  n             )
+                :   BT(2, topology[1]+1,topology, param, n)
+    { }
+
+
+    Node( BT & node_)
+        :   BT(2, node_.classCount_ +1, node_) 
+    {}
+    BT::Parameter_type  prob_begin() const
+    {
+        return BT::parameters_begin()+1;
+    }
+    BT::Parameter_type  prob_end() const
+    {
+        return prob_begin() + prob_size();
+    }
+    int prob_size() const
+    {
+        return BT::classCount_;
+    }
+};
+
+template<>
+class Node<e_LogRegProbNode>;
+
+} // namespace vigra
+
+#endif //RF_nodeproxy
diff --git a/include/vigra/random_forest/rf_online_prediction_set.hxx b/include/vigra/random_forest/rf_online_prediction_set.hxx
new file mode 100644
index 0000000..d34e12b
--- /dev/null
+++ b/include/vigra/random_forest/rf_online_prediction_set.hxx
@@ -0,0 +1,77 @@
+#include "../multi_array.hxx"
+#include <set>
+#include <vector>
+
+namespace vigra
+{
+
+template<class T>
+struct SampleRange
+{
+    SampleRange(int start,int end,int num_features)
+    {
+        this->start=start;
+        this->end=end;
+        this->min_boundaries.resize(num_features,-FLT_MAX);
+        this->max_boundaries.resize(num_features,FLT_MAX);
+    }
+    
+    int start;
+    mutable int end;
+    mutable std::vector<T> max_boundaries;
+    mutable std::vector<T> min_boundaries;
+    
+    bool operator<(const SampleRange& o) const
+    {
+        return o.start<start;
+    }
+};
+
+template<class T>
+class OnlinePredictionSet
+{
+public:
+    template<class U>
+    OnlinePredictionSet(MultiArrayView<2,T,U>& features,int num_sets)
+    {
+        this->features=features;
+        std::vector<int> init(features.shape(0));
+        for(unsigned int i=0;i<init.size();++i)
+            init[i]=i;
+        indices.resize(num_sets,init);
+        std::set<SampleRange<T> > set_init;
+        set_init.insert(SampleRange<T>(0,init.size(),features.shape(1)));
+        ranges.resize(num_sets,set_init);
+        cumulativePredTime.resize(num_sets,0);
+    }
+    
+    int get_worsed_tree()
+    {
+        int result=0;
+        for(unsigned int i=0;i<cumulativePredTime.size();++i)
+        {
+            if(cumulativePredTime[i]>cumulativePredTime[result])
+            {
+                result=i;
+            }
+        }
+        return result;
+    }
+    
+    void reset_tree(int index)
+    {
+        index=index % ranges.size();
+        std::set<SampleRange<T> > set_init;
+        set_init.insert(SampleRange<T>(0,features.shape(0),features.shape(1)));
+        ranges[index]=set_init;
+        cumulativePredTime[index]=0;
+    }
+    
+    std::vector<std::set<SampleRange<T> > > ranges;
+    std::vector<std::vector<int> > indices;
+    std::vector<int> cumulativePredTime;
+    MultiArray<2,T> features;
+};
+
+}
+
diff --git a/include/vigra/random_forest/rf_preprocessing.hxx b/include/vigra/random_forest/rf_preprocessing.hxx
new file mode 100755
index 0000000..a3622b6
--- /dev/null
+++ b/include/vigra/random_forest/rf_preprocessing.hxx
@@ -0,0 +1,335 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by  Ullrich Koethe and Rahul Nair         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_RF_PREPROCESSING_HXX
+#define VIGRA_RF_PREPROCESSING_HXX
+
+#include <limits>
+#include "rf_common.hxx"
+
+namespace vigra
+{
+
+/** Class used while preprocessing  (currently used only during learn)
+ *
+ * This class is internally used by the Random Forest learn function. 
+ * Different split functors may need to process the data in different manners
+ * (i.e., regression labels that should not be touched and classification 
+ * labels that must be converted into a integral format)
+ *
+ * This Class only exists in specialized versions, where the Tag class is 
+ * fixed. 
+ *
+ * The Tag class is determined by Splitfunctor::Preprocessor_t . Currently
+ * it can either be ClassificationTag or RegressionTag.  look At the 
+ * RegressionTag specialisation for the basic interface if you ever happen
+ * to care.... - or need some sort of vague new preprocessor.  
+ * new preprocessor ( Soft labels or whatever)
+ */
+template<class Tag, class LabelType, class T1, class C1, class T2, class C2>
+class Processor;
+
+namespace detail
+{
+
+    /* Common helper function used in all Processors. 
+     * This function analyses the options struct and calculates the real 
+     * values needed for the current problem (data)
+     */
+    template<class T>
+    void fill_external_parameters(RandomForestOptions const  & options,
+                                  ProblemSpec<T> & ext_param)
+    {
+        // set correct value for mtry
+        switch(options.mtry_switch_)
+        {
+            case RF_SQRT:
+                ext_param.actual_mtry_ =
+                    int(std::floor(
+                            std::sqrt(double(ext_param.column_count_))
+                            + 0.5));
+                break;
+            case RF_LOG:
+                // this is in Breimans original paper
+                ext_param.actual_mtry_ =
+                    int(1+(std::log(double(ext_param.column_count_))
+                           /std::log(2.0)));
+                break;
+            case RF_FUNCTION:
+                ext_param.actual_mtry_ =
+                    options.mtry_func_(ext_param.column_count_);
+                break;
+            case RF_ALL:
+                ext_param.actual_mtry_ = ext_param.column_count_;
+                break;
+            default:
+                ext_param.actual_mtry_ =
+                    options.mtry_;
+        }
+        // set correct value for msample
+        switch(options.training_set_calc_switch_)
+        {
+            case RF_CONST:
+                ext_param.actual_msample_ =
+                    options.training_set_size_;
+                break;
+            case RF_PROPORTIONAL:
+                ext_param.actual_msample_ =
+                    (int)std::ceil(  options.training_set_proportion_ *
+                                     ext_param.row_count_);
+                    break;
+            case RF_FUNCTION:
+                ext_param.actual_msample_ =
+                    options.training_set_func_(ext_param.row_count_);
+                break;
+            default:
+                vigra_precondition(1!= 1, "unexpected error");
+
+        }
+
+    }
+    
+    /* Returns true if MultiArray contains NaNs
+     */
+    template<unsigned int N, class T, class C>
+    bool contains_nan(MultiArrayView<N, T, C> const & in)
+    {
+        for(int ii = 0; ii < in.size(); ++ii)
+            if(in[ii] != in[ii])
+                return true;
+        return false; 
+    }
+    
+    /* Returns true if MultiArray contains Infs
+     */
+    template<unsigned int N, class T, class C>
+    bool contains_inf(MultiArrayView<N, T, C> const & in)
+    {
+         if(!std::numeric_limits<T>::has_infinity)
+             return false;
+         for(int ii = 0; ii < in.size(); ++ii)
+            if(in[ii] == std::numeric_limits<T>::infinity())
+                return true;
+         return false;
+    }
+} // namespace detail
+
+
+
+/** Preprocessor used during Classification
+ *
+ * This class converts the labels int Integral labels which are used by the 
+ * standard split functor to address memory in the node objects.
+ */
+template<class LabelType, class T1, class C1, class T2, class C2>
+class Processor<ClassificationTag, LabelType, T1, C1, T2, C2>
+{
+    public:
+    typedef Int32 LabelInt;
+    typedef MultiArrayView<2, T1, C1> Feature_t;
+    typedef MultiArray<2, T1> FeatureWithMemory_t;
+    typedef MultiArrayView<2,LabelInt> Label_t;
+    MultiArrayView<2, T1, C1>const &    features_;
+    MultiArray<2, LabelInt>             intLabels_;
+    MultiArrayView<2, LabelInt>         strata_;
+
+    template<class T>
+    Processor(MultiArrayView<2, T1, C1>const & features,   
+              MultiArrayView<2, T2, C2>const & response,
+              RandomForestOptions &options,         
+              ProblemSpec<T> &ext_param)
+    :
+        features_( features) // do not touch the features. 
+    {
+        vigra_precondition(!detail::contains_nan(features), "RandomForest(): Feature matrix "
+                                                           "contains NaNs");
+        vigra_precondition(!detail::contains_nan(response), "RandomForest(): Response "
+                                                           "contains NaNs");
+        vigra_precondition(!detail::contains_inf(features), "RandomForest(): Feature matrix "
+                                                           "contains inf");
+        vigra_precondition(!detail::contains_inf(response), "RandomForest(): Response "
+                                                           "contains inf");
+        // set some of the problem specific parameters 
+        ext_param.column_count_  = features.shape(1);
+        ext_param.row_count_     = features.shape(0);
+        ext_param.problem_type_  = CLASSIFICATION;
+        ext_param.used_          = true;
+        intLabels_.reshape(response.shape());
+
+        //get the class labels
+        if(ext_param.class_count_ == 0)
+        {
+            // fill up a map with the current labels and then create the 
+            // integral labels.
+            std::set<T2>                    labelToInt;
+            for(MultiArrayIndex k = 0; k < features.shape(0); ++k)
+                labelToInt.insert(response(k,0));
+            std::vector<T2> tmp_(labelToInt.begin(), labelToInt.end());
+            ext_param.classes_(tmp_.begin(), tmp_.end());
+        }
+        for(MultiArrayIndex k = 0; k < features.shape(0); ++k)
+        {
+            if(std::find(ext_param.classes.begin(), ext_param.classes.end(), response(k,0)) == ext_param.classes.end())
+            {
+                throw std::runtime_error("RandomForest(): invalid label in training data.");
+            }
+            else
+                intLabels_(k, 0) = std::find(ext_param.classes.begin(), ext_param.classes.end(), response(k,0))
+                                    - ext_param.classes.begin();
+        }
+        // set class weights
+        if(ext_param.class_weights_.size() == 0)
+        {
+            ArrayVector<T2> 
+                tmp((std::size_t)ext_param.class_count_, 
+                    NumericTraits<T2>::one());
+            ext_param.class_weights(tmp.begin(), tmp.end());
+        }
+
+        // set mtry and msample
+        detail::fill_external_parameters(options, ext_param);
+
+        // set strata
+        strata_ = intLabels_;
+
+    }
+
+    /** Access the processed features
+     */
+    MultiArrayView<2, T1, C1>const & features()
+    {
+        return features_;
+    }
+
+    /** Access processed labels
+     */
+    MultiArrayView<2, LabelInt> response()
+    {
+        return MultiArrayView<2, LabelInt>(intLabels_);
+    }
+
+    /** Access processed strata
+     */
+    ArrayVectorView < LabelInt>  strata()
+    {
+        return ArrayVectorView<LabelInt>(intLabels_.size(), intLabels_.data());
+    }
+
+    /** Access strata fraction sized - not used currently
+     */
+    ArrayVectorView< double> strata_prob()
+    {
+        return ArrayVectorView< double>();
+    }
+};
+
+
+
+/** Regression Preprocessor - This basically does not do anything with the
+ * data.
+ */
+template<class LabelType, class T1, class C1, class T2, class C2>
+class Processor<RegressionTag,LabelType, T1, C1, T2, C2>
+{
+public:
+    // only views are created - no data copied.
+    MultiArrayView<2, T1, C1>   features_;
+    MultiArrayView<2, T2, C2>   response_;
+    RandomForestOptions const & options_;
+    ProblemSpec<LabelType> const &
+                                ext_param_;
+    // will only be filled if needed
+    MultiArray<2, int>      strata_;
+    bool strata_filled;
+
+    // copy the views.
+    template<class T>
+    Processor(  MultiArrayView<2, T1, C1>   features,
+                MultiArrayView<2, T2, C2>   response,
+                RandomForestOptions const & options,
+                ProblemSpec<T>& ext_param)
+    :
+        features_(features),
+        response_(response),
+        options_(options),
+        ext_param_(ext_param)
+    {
+        // set some of the problem specific parameters 
+        ext_param.column_count_  = features.shape(1);
+        ext_param.row_count_     = features.shape(0);
+        ext_param.problem_type_  = REGRESSION;
+        ext_param.used_          = true;
+        detail::fill_external_parameters(options, ext_param);
+        vigra_precondition(!detail::contains_nan(features), "Processor(): Feature Matrix "
+                                                           "Contains NaNs");
+        vigra_precondition(!detail::contains_nan(response), "Processor(): Response "
+                                                           "Contains NaNs");
+        vigra_precondition(!detail::contains_inf(features), "Processor(): Feature Matrix "
+                                                           "Contains inf");
+        vigra_precondition(!detail::contains_inf(response), "Processor(): Response "
+                                                           "Contains inf");
+        strata_ = MultiArray<2, int> (MultiArrayShape<2>::type(response_.shape(0), 1));
+        ext_param.response_size_ = response.shape(1);
+        ext_param.class_count_ = response_.shape(1);
+        std::vector<T2> tmp_(ext_param.class_count_, 0);
+            ext_param.classes_(tmp_.begin(), tmp_.end());
+    }
+
+    /** access preprocessed features
+     */
+    MultiArrayView<2, T1, C1> & features()
+    {
+        return features_;
+    }
+
+    /** access preprocessed response
+     */
+    MultiArrayView<2, T2, C2> & response()
+    {
+        return response_;
+    }
+
+    /** access strata - this is not used currently
+     */
+    MultiArray<2, int> & strata()
+    {
+        return strata_;
+    }
+};
+}
+#endif //VIGRA_RF_PREPROCESSING_HXX
+
+
+
diff --git a/include/vigra/random_forest/rf_region.hxx b/include/vigra/random_forest/rf_region.hxx
new file mode 100755
index 0000000..5fb4067
--- /dev/null
+++ b/include/vigra/random_forest/rf_region.hxx
@@ -0,0 +1,197 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by  Ullrich Koethe and Rahul Nair         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+#ifndef VIGRA_RANDOM_FOREST_REGION_HXX
+#define VIGRA_RANDOM_FOREST_REGION_HXX
+#include <algorithm>
+#include <map>
+#include <numeric>
+#include "vigra/mathutil.hxx"
+#include "vigra/array_vector.hxx"
+#include "vigra/sized_int.hxx"
+#include "vigra/matrix.hxx"
+#include "vigra/random.hxx"
+#include "vigra/functorexpression.hxx"
+
+
+
+namespace vigra
+{
+
+
+/** Standard Stackentry used to Build a Tree. Contains Information 
+ * About the current region being split
+ */
+template <class Iter>
+class DT_StackEntry
+{
+  public:
+    typedef Iter IndexIterator;
+    // tree specific stuff
+    enum  ParentTag
+    {
+        DecisionTreeNoParent = -1
+    };
+
+    /** Address of left and Right parent in the topology container
+     */
+    Int32                                   leftParent;
+    Int32                                   rightParent;
+    /** rule associated with current node
+     */
+    ArrayVector<std::pair<Int32, double> >  rule;
+
+
+    // RegionSpecificStuff
+    ArrayVector<double>                     classCounts_;
+    ArrayVector<double>                     weightedClassCounts_;
+    bool                                    classCountsIsValid;
+    bool                                    weightedClassCountsIsValid;
+    IndexIterator                           begin_,  end_;
+    int                                     size_; 
+    IndexIterator                           oob_begin_, oob_end_;
+    int                                     oob_size_;
+
+    Int32 depth()
+    {
+        return rule.size();
+    }
+
+    void setRange(IndexIterator s, IndexIterator e)
+    {
+        begin_      = s;
+        end_        = e;
+        size_       = e-s;
+    }
+    void set_oob_range(IndexIterator s, IndexIterator e)
+    {
+        oob_begin_   = s;
+        oob_end_     = e;
+        oob_size_       = e-s;
+    }
+
+    void reset()
+    {
+        begin_      = end_      = IndexIterator();
+        oob_begin_  = oob_end_  = IndexIterator();
+        size_       = oob_size_ = 0;
+        leftParent  = DecisionTreeNoParent;
+        rightParent = DecisionTreeNoParent;
+        classCountsIsValid = false;
+    }
+
+    bool  isPure()
+    {
+        int num = 0;
+
+        for(int ii = 0; ii < (int)classCounts().size(); ++ii)
+        {
+            num += classCounts()[ii] > 0;
+        }
+        return num <= 1;
+    }
+
+    int&  operator[](int i)
+    {
+        return *(begin_+i);
+    }
+
+    IndexIterator & begin()
+    {
+        return begin_;
+    }
+
+    IndexIterator & end()
+    {
+        return end_;
+    }
+    IndexIterator & oob_begin()
+    {
+        return oob_begin_;
+    }
+
+    IndexIterator & oob_end()
+    {
+        return oob_end_;
+    }
+    ArrayVector<double> & classCounts()
+    {
+        return classCounts_;
+    }
+    ArrayVector<double> & weightedClassCounts()
+    {
+        return classCounts_;
+    }
+    bool  classCountsValid(bool u)
+    {
+        classCountsIsValid = u;
+        return classCountsIsValid;
+
+    }
+
+    void classCounts(ArrayVector<Int32> in);
+
+    DT_StackEntry( IndexIterator i, IndexIterator e,
+                        int classCount,
+                        Int32 lp = DecisionTreeNoParent,
+                        Int32 rp = DecisionTreeNoParent)
+    :
+        leftParent(lp),
+        rightParent(rp),
+        classCounts_(classCount, 0u),
+        classCountsIsValid(false),
+        begin_(i),
+        end_(e),
+        size_(e-i)
+    {}
+
+    
+    Int32 size()const
+    {
+        return size_;
+    }
+
+
+    Int32 oob_size()const
+    {
+        return oob_size_;
+    }
+
+};
+
+
+}
+//namespace vigra
+
+#endif // VIGRA_RANDOM_FOREST_REGION_HXX
diff --git a/include/vigra/random_forest/rf_ridge_split.hxx b/include/vigra/random_forest/rf_ridge_split.hxx
new file mode 100644
index 0000000..bb65ddd
--- /dev/null
+++ b/include/vigra/random_forest/rf_ridge_split.hxx
@@ -0,0 +1,446 @@
+//
+// C++ Interface: rf_ridge_split
+//
+// Description: 
+//
+//
+// Author: Nico Splitthoff <splitthoff at zg00103>, (C) 2009
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef VIGRA_RANDOM_FOREST_RIDGE_SPLIT_H
+#define VIGRA_RANDOM_FOREST_RIDGE_SPLIT_H
+//#include "rf_sampling.hxx"
+#include "../sampling.hxx"
+#include "rf_split.hxx"
+#include "rf_nodeproxy.hxx"
+#include "../regression.hxx"
+
+#define outm(v) std::cout << (#v) << ": " << (v) << std::endl;
+#define outm2(v) std::cout << (#v) << ": " << (v) << ", ";
+
+namespace vigra
+{
+
+/*template<>
+class Node<i_RegrNode>
+: public NodeBase
+{
+public:
+    typedef NodeBase BT;
+
+
+    Node(   BT::T_Container_type &   topology,
+        BT::P_Container_type &   param,
+            int nNumCols)
+    :   BT(5+nNumCols,2+nNumCols,topology, param)
+    {
+        BT::typeID() = i_RegrNode;
+    }
+
+    Node(   BT::T_Container_type     &   topology,
+        BT::P_Container_type     &   param,
+        INT                   n             )
+    :   BT(5,2,topology, param, n)
+    {}
+
+    Node( BT & node_)
+    :   BT(5, 2, node_) 
+    {}
+
+    double& threshold()
+    {
+        return BT::parameters_begin()[1];
+    }
+
+    BT::INT& column()
+    {
+        return BT::column_data()[0];
+    }
+
+    template<class U, class C>
+            BT::INT& next(MultiArrayView<2,U,C> const & feature)
+            {
+                return (feature(0, column()) < threshold())? child(0):child(1);
+            }
+};*/
+
+
+template<class ColumnDecisionFunctor, class Tag = ClassificationTag>
+class RidgeSplit: public SplitBase<Tag>
+{
+  public:
+
+
+    typedef SplitBase<Tag> SB;
+
+    ArrayVector<Int32>          splitColumns;
+    ColumnDecisionFunctor       bgfunc;
+
+    double                      region_gini_;
+    ArrayVector<double>         min_gini_;
+    ArrayVector<std::ptrdiff_t> min_indices_;
+    ArrayVector<double>         min_thresholds_;
+
+    int                         bestSplitIndex;
+    
+    //dns
+    bool            m_bDoScalingInTraining;
+    bool            m_bDoBestLambdaBasedOnGini;
+    
+    RidgeSplit()
+    :m_bDoScalingInTraining(true),
+    m_bDoBestLambdaBasedOnGini(true)
+    {
+    }
+
+    double minGini() const
+    {
+        return min_gini_[bestSplitIndex];
+    }
+    
+    int bestSplitColumn() const
+    {
+        return splitColumns[bestSplitIndex];
+    }
+    
+    bool& doScalingInTraining()
+    { return m_bDoScalingInTraining; }
+
+    bool& doBestLambdaBasedOnGini()
+    { return m_bDoBestLambdaBasedOnGini; }
+
+    template<class T>
+            void set_external_parameters(ProblemSpec<T> const & in)
+    {
+        SB::set_external_parameters(in);        
+        bgfunc.set_external_parameters(in);
+        int featureCount_ = in.column_count_;
+        splitColumns.resize(featureCount_);
+        for(int k=0; k<featureCount_; ++k)
+            splitColumns[k] = k;
+        min_gini_.resize(featureCount_);
+        min_indices_.resize(featureCount_);
+        min_thresholds_.resize(featureCount_);
+    }
+
+    
+    template<class T, class C, class T2, class C2, class Region, class Random>
+    int findBestSplit(MultiArrayView<2, T, C> features,
+                      MultiArrayView<2, T2, C2>  multiClassLabels,
+                      Region & region,
+                      ArrayVector<Region>& childRegions,
+                      Random & randint)
+    {
+
+    //std::cerr << "Split called" << std::endl;
+    typedef typename MultiArrayView <2, T, C>::difference_type fShape;
+    typedef typename MultiArrayView <2, T2, C2>::difference_type lShape;
+    typedef typename MultiArrayView <2, double>::difference_type dShape;
+        
+        // calculate things that haven't been calculated yet. 
+//    std::cout << "start" << std::endl;
+        if(std::accumulate(region.classCounts().begin(),
+                           region.classCounts().end(), 0) != region.size())
+        {
+            RandomForestClassCounter<   MultiArrayView<2,T2, C2>, 
+                                        ArrayVector<double> >
+                counter(multiClassLabels, region.classCounts());
+            std::for_each(  region.begin(), region.end(), counter);
+            region.classCountsIsValid = true;
+        }
+
+
+        // Is the region pure already?
+        region_gini_ = GiniCriterion::impurity(region.classCounts(),
+                region.size());
+        if(region_gini_ == 0 || region.size() < SB::ext_param_.actual_mtry_ || region.oob_size() < 2)
+            return  SB::makeTerminalNode(features, multiClassLabels, region, randint);
+
+        // select columns  to be tried.
+    for(int ii = 0; ii < SB::ext_param_.actual_mtry_; ++ii)
+        std::swap(splitColumns[ii], 
+            splitColumns[ii+ randint(features.shape(1) - ii)]);
+
+    //do implicit binary case
+    MultiArray<2, T2> labels(lShape(multiClassLabels.shape(0),1));
+      //number of classes should be >1, otherwise makeTerminalNode would have been called
+      int nNumClasses=0;
+      for(int n=0; n<(int)region.classCounts().size(); n++)
+        nNumClasses+=((region.classCounts()[n]>0) ? 1:0);
+      
+      //convert to binary case
+      if(nNumClasses>2)
+      {
+        int nMaxClass=0;
+        int nMaxClassCounts=0;
+        for(int n=0; n<(int)region.classCounts().size(); n++)
+        {
+          //this should occur in any case:
+          //we had more than two non-zero classes in order to get here
+          if(region.classCounts()[n]>nMaxClassCounts)
+          {
+        nMaxClassCounts=region.classCounts()[n];
+        nMaxClass=n;
+          }
+        }
+        
+        //create binary labels
+        for(int n=0; n<multiClassLabels.shape(0); n++)
+          labels(n,0)=((multiClassLabels(n,0)==nMaxClass) ? 1:0);
+      }
+      else
+        labels=multiClassLabels;
+
+    //_do implicit binary case
+    
+    //uncomment this for some debugging
+/*  int nNumCases=features.shape(0);
+
+    typedef typename MultiArrayView <2, int>::difference_type nShape;
+    MultiArray<2, int> elementCounterArray(nShape(nNumCases,1),(int)0);
+    int nUniqueElements=0;
+    for(int n=0; n<region.size(); n++)
+        elementCounterArray[region[n]]++;
+    
+    for(int n=0; n<nNumCases; n++)
+        nUniqueElements+=((elementCounterArray[n]>0) ? 1:0);
+    
+    outm(nUniqueElements);
+    nUniqueElements=0;
+    MultiArray<2, int> elementCounterArray_oob(nShape(nNumCases,1),(int)0);
+    for(int n=0; n<region.oob_size(); n++)
+        elementCounterArray_oob[region.oob_begin()[n]]++;
+    for(int n=0; n<nNumCases; n++)
+        nUniqueElements+=((elementCounterArray_oob[n]>0) ? 1:0);
+    outm(nUniqueElements);
+    
+    int notUniqueElements=0;
+    for(int n=0; n<nNumCases; n++)
+        notUniqueElements+=(((elementCounterArray_oob[n]>0) && (elementCounterArray[n]>0)) ? 1:0);
+    outm(notUniqueElements);*/
+    
+    //outm(SB::ext_param_.actual_mtry_);
+    
+    
+//select submatrix of features for regression calculation
+    MultiArrayView<2, T, C> cVector;
+    MultiArray<2, T> xtrain(fShape(region.size(),SB::ext_param_.actual_mtry_));
+    //we only want -1 and 1 for this
+    MultiArray<2, double> regrLabels(dShape(region.size(),1));
+
+    //copy data into a vigra data structure and centre and scale while doing so
+    MultiArray<2, double> meanMatrix(dShape(SB::ext_param_.actual_mtry_,1));
+    MultiArray<2, double> stdMatrix(dShape(SB::ext_param_.actual_mtry_,1));
+    for(int m=0; m<SB::ext_param_.actual_mtry_; m++)
+    {
+        cVector=columnVector(features, splitColumns[m]);
+        
+        //centre and scale the data
+        double dCurrFeatureColumnMean=0.0;
+        double dCurrFeatureColumnStd=1.0; //default value
+        
+        //calc mean on bootstrap data
+        for(int n=0; n<region.size(); n++)
+          dCurrFeatureColumnMean+=cVector[region[n]];
+        dCurrFeatureColumnMean/=region.size();
+        //calc scaling
+        if(m_bDoScalingInTraining)
+        {
+          for(int n=0; n<region.size(); n++)
+          {
+              dCurrFeatureColumnStd+=
+            (cVector[region[n]]-dCurrFeatureColumnMean)*(cVector[region[n]]-dCurrFeatureColumnMean);
+          }
+          //unbiased std estimator:
+          dCurrFeatureColumnStd=sqrt(dCurrFeatureColumnStd/(region.size()-1));
+        }
+        //dCurrFeatureColumnStd is still 1.0 if we didn't want scaling
+        stdMatrix(m,0)=dCurrFeatureColumnStd;
+        
+        meanMatrix(m,0)=dCurrFeatureColumnMean;
+        
+        //get feature matrix, i.e. A (note that weighting is done automatically
+        //since rows can occur multiple times -> bagging)
+        for(int n=0; n<region.size(); n++)
+            xtrain(n,m)=(cVector[region[n]]-dCurrFeatureColumnMean)/dCurrFeatureColumnStd;
+    }
+    
+//    std::cout << "middle" << std::endl;
+    //get label vector (i.e. b)
+    for(int n=0; n<region.size(); n++)
+    {
+        //we checked for/built binary case further up.
+        //class labels should thus be either 0 or 1
+        //-> convert to -1 and 1 for regression
+        regrLabels(n,0)=((labels[region[n]]==0) ? -1:1);
+    }
+
+    MultiArray<2, double> dLambdas(dShape(11,1));
+    int nCounter=0;
+    for(int nLambda=-5; nLambda<=5; nLambda++)
+        dLambdas[nCounter++]=pow(10.0,nLambda);
+    //destination vector for regression coefficients; use same type as for xtrain
+    MultiArray<2, double> regrCoef(dShape(SB::ext_param_.actual_mtry_,11));
+    ridgeRegressionSeries(xtrain,regrLabels,regrCoef,dLambdas);
+    
+    double dMaxRidgeSum=NumericTraits<double>::min();
+    double dCurrRidgeSum;
+    int nMaxRidgeSumAtLambdaInd=0;
+
+    for(int nLambdaInd=0; nLambdaInd<11; nLambdaInd++)
+    {
+        //just sum up the correct answers
+        //(correct means >=intercept for class 1, <intercept for class 0)
+        //(intercept=0 or intercept=threshold based on gini)
+        dCurrRidgeSum=0.0;
+        
+        //assemble projection vector
+        MultiArray<2, double> dDistanceFromHyperplane(dShape(features.shape(0),1));
+        
+        for(int n=0; n<region.oob_size(); n++)
+        {
+          dDistanceFromHyperplane(region.oob_begin()[n],0)=0.0;
+          for (int m=0; m<SB::ext_param_.actual_mtry_; m++)
+          {
+            dDistanceFromHyperplane(region.oob_begin()[n],0)+=
+              features(region.oob_begin()[n],splitColumns[m])*regrCoef(m,nLambdaInd);
+          }
+        }
+
+        double dCurrIntercept=0.0;
+        if(m_bDoBestLambdaBasedOnGini)
+        {
+          //calculate gini index
+          bgfunc(dDistanceFromHyperplane,
+              labels, 
+              region.oob_begin(), region.oob_end(), 
+              region.classCounts());
+          dCurrIntercept=bgfunc.min_threshold_;
+        }
+        else
+        {
+          for (int m=0; m<SB::ext_param_.actual_mtry_; m++)
+            dCurrIntercept+=meanMatrix(m,0)*regrCoef(m,nLambdaInd);
+        }
+        
+        for(int n=0; n<region.oob_size(); n++)
+        {
+            //check what lambda performs best on oob data
+            int nClassPrediction=((dDistanceFromHyperplane(region.oob_begin()[n],0) >=dCurrIntercept) ? 1:0);
+            dCurrRidgeSum+=((nClassPrediction == labels(region.oob_begin()[n],0)) ? 1:0);
+        }
+        if(dCurrRidgeSum>dMaxRidgeSum)
+        {
+            dMaxRidgeSum=dCurrRidgeSum;
+            nMaxRidgeSumAtLambdaInd=nLambdaInd;
+        }
+    }
+
+//    std::cout << "middle2" << std::endl;
+        //create a Node for output
+        Node<i_HyperplaneNode>   node(SB::ext_param_.actual_mtry_, SB::t_data, SB::p_data);
+
+    //normalise coeffs
+        //data was scaled (by 1.0 or by std) -> take into account
+        MultiArray<2, double> dCoeffVector(dShape(SB::ext_param_.actual_mtry_,1));
+        for(int n=0; n<SB::ext_param_.actual_mtry_; n++)
+          dCoeffVector(n,0)=regrCoef(n,nMaxRidgeSumAtLambdaInd)*stdMatrix(n,0);
+        
+        //calc norm
+        double dVnorm=columnVector(regrCoef,nMaxRidgeSumAtLambdaInd).norm();
+
+        for(int n=0; n<SB::ext_param_.actual_mtry_; n++)
+            node.weights()[n]=dCoeffVector(n,0)/dVnorm;
+    //_normalise coeffs
+    
+    //save the columns
+        node.column_data()[0]=SB::ext_param_.actual_mtry_;
+        for(int n=0; n<SB::ext_param_.actual_mtry_; n++)
+            node.column_data()[n+1]=splitColumns[n];
+
+    //assemble projection vector
+        //careful here: "region" is a pointer to indices...
+        //all the indices in "region" need to have valid data
+        //convert from "region" space to original "feature" space
+        MultiArray<2, double> dDistanceFromHyperplane(dShape(features.shape(0),1));
+        
+        for(int n=0; n<region.size(); n++)
+        {
+            dDistanceFromHyperplane(region[n],0)=0.0;
+            for (int m=0; m<SB::ext_param_.actual_mtry_; m++)
+            {
+              dDistanceFromHyperplane(region[n],0)+=
+               features(region[n],m)*node.weights()[m];
+            }
+        }
+        for(int n=0; n<region.oob_size(); n++)
+        {
+            dDistanceFromHyperplane(region.oob_begin()[n],0)=0.0;
+            for (int m=0; m<SB::ext_param_.actual_mtry_; m++)
+            {
+              dDistanceFromHyperplane(region.oob_begin()[n],0)+=
+            features(region.oob_begin()[n],m)*node.weights()[m];
+            }
+        }
+        
+    //calculate gini index
+        bgfunc(dDistanceFromHyperplane,
+            labels, 
+            region.begin(), region.end(), 
+            region.classCounts());
+    
+        // did not find any suitable split
+    if(closeAtTolerance(bgfunc.min_gini_, NumericTraits<double>::max()))
+        return  SB::makeTerminalNode(features, multiClassLabels, region, randint);
+    
+    //take gini threshold here due to scaling, normalisation, etc. of the coefficients
+    node.intercept()    = bgfunc.min_threshold_;
+    SB::node_ = node;
+    
+    childRegions[0].classCounts() = bgfunc.bestCurrentCounts[0];
+    childRegions[1].classCounts() = bgfunc.bestCurrentCounts[1];
+    childRegions[0].classCountsIsValid = true;
+    childRegions[1].classCountsIsValid = true;
+    
+        // Save the ranges of the child stack entries.
+    childRegions[0].setRange(   region.begin()  , region.begin() + bgfunc.min_index_   );
+    childRegions[0].rule = region.rule;
+    childRegions[0].rule.push_back(std::make_pair(1, 1.0));
+    childRegions[1].setRange(   region.begin() + bgfunc.min_index_       , region.end()    );
+    childRegions[1].rule = region.rule;
+    childRegions[1].rule.push_back(std::make_pair(1, 1.0));
+    
+    //adjust oob ranges
+//    std::cout << "adjust oob" << std::endl;
+    //sort the oobs
+      std::sort(region.oob_begin(), region.oob_end(), 
+            SortSamplesByDimensions< MultiArray<2, double> > (dDistanceFromHyperplane, 0));
+            
+      //find split index
+      int nOOBindx;
+      for(nOOBindx=0; nOOBindx<region.oob_size(); nOOBindx++)
+      {
+        if(dDistanceFromHyperplane(region.oob_begin()[nOOBindx],0)>=node.intercept())
+          break;
+      }
+
+      childRegions[0].set_oob_range(   region.oob_begin()  , region.oob_begin() + nOOBindx   );
+      childRegions[1].set_oob_range(   region.oob_begin() + nOOBindx , region.oob_end() );
+
+//    std::cout << "end" << std::endl;
+//    outm2(region.oob_begin());outm2(nOOBindx);outm(region.oob_begin() + nOOBindx);
+    //_adjust oob ranges
+
+    return i_HyperplaneNode;
+    }
+};
+
+/** Standard ridge regression split
+ */
+typedef RidgeSplit<BestGiniOfColumn<GiniCriterion> >  GiniRidgeSplit;
+
+
+} //namespace vigra
+#endif // VIGRA_RANDOM_FOREST_RIDGE_SPLIT_H
diff --git a/include/vigra/random_forest/rf_split.hxx b/include/vigra/random_forest/rf_split.hxx
new file mode 100644
index 0000000..838e335
--- /dev/null
+++ b/include/vigra/random_forest/rf_split.hxx
@@ -0,0 +1,1380 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by  Ullrich Koethe and Rahul Nair         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+#ifndef VIGRA_RANDOM_FOREST_SPLIT_HXX
+#define VIGRA_RANDOM_FOREST_SPLIT_HXX
+#include <algorithm>
+#include <cstddef>
+#include <map>
+#include <numeric>
+#include <math.h>
+#include "../mathutil.hxx"
+#include "../array_vector.hxx"
+#include "../sized_int.hxx"
+#include "../matrix.hxx"
+#include "../random.hxx"
+#include "../functorexpression.hxx"
+#include "rf_nodeproxy.hxx"
+//#include "rf_sampling.hxx"
+#include "rf_region.hxx"
+//#include "../hokashyap.hxx"
+//#include "vigra/rf_helpers.hxx"
+
+namespace vigra
+{
+
+// Incomplete Class to ensure that findBestSplit is always implemented in
+// the derived classes of SplitBase
+class CompileTimeError;
+
+
+namespace detail
+{
+    template<class Tag>
+    class Normalise
+    {
+      public:
+        template<class Iter>
+        static void exec(Iter begin, Iter  end)
+        {}
+    };
+
+    template<>
+    class Normalise<ClassificationTag>
+    {
+      public:
+        template<class Iter>
+        static void exec (Iter begin, Iter end)
+        {
+            double bla = std::accumulate(begin, end, 0.0);
+            for(int ii = 0; ii < end - begin; ++ii)
+                begin[ii] = begin[ii]/bla ;
+        }
+    };
+}
+
+
+/** Base Class for all SplitFunctors used with the \ref RandomForest class
+    defines the interface used while learning a tree.
+**/
+template<class Tag>
+class SplitBase
+{
+  public:
+
+    typedef Tag           RF_Tag;
+    typedef DT_StackEntry<ArrayVectorView<Int32>::iterator>
+                                        StackEntry_t;
+
+    ProblemSpec<>           ext_param_;
+
+    NodeBase::T_Container_type          t_data;
+    NodeBase::P_Container_type          p_data;
+
+    NodeBase                            node_;
+
+    /** returns the DecisionTree Node created by
+        \ref SplitBase::findBestSplit() or \ref SplitBase::makeTerminalNode().
+    **/
+
+    template<class T>
+    void set_external_parameters(ProblemSpec<T> const & in)
+    {
+        ext_param_ = in;
+        t_data.push_back(in.column_count_);
+        t_data.push_back(in.class_count_);
+    }
+
+    NodeBase & createNode() 
+    {
+        return node_;
+    }
+
+    int classCount() const
+    {
+        return int(t_data[1]);
+    }
+
+    int featureCount() const
+    {
+        return int(t_data[0]);
+    }
+
+    /** resets internal data. Should always be called before
+        calling findBestSplit or makeTerminalNode
+    **/
+    void reset()
+    {
+        t_data.resize(2);
+        p_data.resize(0);
+    }
+
+
+    /** findBestSplit has to be re-implemented in derived split functor.
+        The defaut implementation only insures that a CompileTime error is issued
+        if no such method was defined.
+    **/
+
+    template<class T, class C, class T2, class C2, class Region, class Random>
+    int findBestSplit(MultiArrayView<2, T, C> features,
+                      MultiArrayView<2, T2, C2> labels,
+                      Region region,
+                      ArrayVector<Region> childs,
+                      Random randint)
+    {
+#ifndef __clang__   
+        // FIXME: This compile-time checking trick does not work for clang.
+        CompileTimeError SplitFunctor__findBestSplit_member_was_not_defined;
+#endif
+        return 0;
+    }
+
+    /** Default action for creating a terminal Node.
+        sets the Class probability of the remaining region according to
+        the class histogram
+    **/
+    template<class T, class C, class T2,class C2, class Region, class Random>
+    int makeTerminalNode(MultiArrayView<2, T, C> features,
+                      MultiArrayView<2, T2, C2>  labels,
+                      Region &                   region,
+                      Random                     randint)
+    {
+        Node<e_ConstProbNode> ret(t_data, p_data);
+        node_ = ret;
+        if(ext_param_.class_weights_.size() != region.classCounts().size())
+        {
+            std::copy(region.classCounts().begin(),
+                      region.classCounts().end(),
+                      ret.prob_begin());
+        }
+        else
+        {
+            std::transform(region.classCounts().begin(),
+                           region.classCounts().end(),
+                           ext_param_.class_weights_.begin(),
+                           ret.prob_begin(), std::multiplies<double>());
+        }
+        detail::Normalise<RF_Tag>::exec(ret.prob_begin(), ret.prob_end());
+//        std::copy(ret.prob_begin(), ret.prob_end(), std::ostream_iterator<double>(std::cerr, ", " ));
+//        std::cerr << std::endl;
+        ret.weights() = region.size();  
+        return e_ConstProbNode;
+    }
+
+
+};
+
+/** Functor to sort the indices of a feature Matrix by a certain dimension
+**/
+template<class DataMatrix>
+class SortSamplesByDimensions
+{
+    DataMatrix const & data_;
+    MultiArrayIndex sortColumn_;
+    double thresVal_;
+  public:
+
+    SortSamplesByDimensions(DataMatrix const & data, 
+                            MultiArrayIndex sortColumn,
+                            double thresVal = 0.0)
+    : data_(data),
+      sortColumn_(sortColumn),
+      thresVal_(thresVal)
+    {}
+
+    void setColumn(MultiArrayIndex sortColumn)
+    {
+        sortColumn_ = sortColumn;
+    }
+    void setThreshold(double value)
+    {
+        thresVal_ = value; 
+    }
+
+    bool operator()(MultiArrayIndex l, MultiArrayIndex r) const
+    {
+        return data_(l, sortColumn_) < data_(r, sortColumn_);
+    }
+    bool operator()(MultiArrayIndex l) const
+    {
+        return data_(l, sortColumn_) < thresVal_;
+    }
+};
+
+template<class DataMatrix>
+class DimensionNotEqual
+{
+    DataMatrix const & data_;
+    MultiArrayIndex sortColumn_;
+
+  public:
+
+    DimensionNotEqual(DataMatrix const & data, 
+                            MultiArrayIndex sortColumn)
+    : data_(data),
+      sortColumn_(sortColumn)
+    {}
+
+    void setColumn(MultiArrayIndex sortColumn)
+    {
+        sortColumn_ = sortColumn;
+    }
+
+    bool operator()(MultiArrayIndex l, MultiArrayIndex r) const
+    {
+        return data_(l, sortColumn_) != data_(r, sortColumn_);
+    }
+};
+
+template<class DataMatrix>
+class SortSamplesByHyperplane
+{
+    DataMatrix const & data_;
+    Node<i_HyperplaneNode> const & node_;
+
+  public:
+
+    SortSamplesByHyperplane(DataMatrix              const & data, 
+                            Node<i_HyperplaneNode>  const & node)
+    :       
+            data_(data), 
+            node_(node)
+    {}
+
+    /** calculate the distance of a sample point to a hyperplane
+     */
+    double operator[](MultiArrayIndex l) const
+    {
+        double result_l = -1 * node_.intercept();
+        for(int ii = 0; ii < node_.columns_size(); ++ii)
+        {
+            result_l +=     rowVector(data_, l)[node_.columns_begin()[ii]] 
+                        *   node_.weights()[ii];
+        }
+        return result_l;
+    }
+
+    bool operator()(MultiArrayIndex l, MultiArrayIndex r) const
+    {
+        return (*this)[l]  < (*this)[r];
+    }
+
+};
+
+/** makes a Class Histogram given indices in a labels_ array
+ *  usage: 
+ *      MultiArrayView<2, T2, C2> labels = makeSomeLabels()
+ *      ArrayVector<int> hist(numberOfLabels(labels), 0);
+ *      RandomForestClassCounter<T2, C2, ArrayVector> counter(labels, hist);
+ *
+ *      Container<int> indices = getSomeIndices()
+ *      std::for_each(indices, counter);
+ */
+template <class DataSource, class CountArray>
+class RandomForestClassCounter
+{
+    DataSource  const &     labels_;
+    CountArray        &     counts_;
+
+  public:
+
+    RandomForestClassCounter(DataSource  const & labels, 
+                             CountArray & counts)
+    : labels_(labels),
+      counts_(counts)
+    {
+        reset();
+    }
+
+    void reset()
+    {
+        counts_.init(0);
+    }
+
+    void operator()(MultiArrayIndex l) const
+    {
+        counts_[labels_[l]] +=1;
+    }
+};
+
+
+/** Functor To Calculate the Best possible Split Based on the Gini Index
+    given Labels and Features along a given Axis
+*/
+
+namespace detail
+{
+    template<int N>
+    class ConstArr
+    {
+    public:
+        double operator[](size_t) const
+        {
+            return (double)N;
+        }
+    };
+
+
+}
+
+
+
+
+/** Functor to calculate the entropy based impurity
+ */
+class EntropyCriterion
+{
+public:
+    /**calculate the weighted gini impurity based on class histogram
+     * and class weights
+     */
+    template<class Array, class Array2>
+    double operator()        (Array     const & hist, 
+                              Array2    const & weights, 
+                              double            total = 1.0) const
+    {
+        return impurity(hist, weights, total);
+    }
+    
+    /** calculate the gini based impurity based on class histogram
+     */
+    template<class Array>
+    double operator()(Array const & hist, double total = 1.0) const
+    {
+        return impurity(hist, total);
+    }
+    
+    /** static version of operator(hist total)
+     */
+    template<class Array>
+    static double impurity(Array const & hist, double total)
+    {
+        return impurity(hist, detail::ConstArr<1>(), total);
+    }
+
+    /** static version of operator(hist, weights, total)
+     */
+    template<class Array, class Array2>
+    static double impurity   (Array     const & hist, 
+                              Array2    const & weights, 
+                              double            total)
+    {
+
+        int     class_count     = hist.size();
+        double  entropy            = 0.0;
+        if(class_count == 2)
+        {
+            double p0           = (hist[0]/total);
+            double p1           = (hist[1]/total);
+            entropy             = 0 - weights[0]*p0*std::log(p0) - weights[1]*p1*std::log(p1);
+        }
+        else
+        {
+            for(int ii = 0; ii < class_count; ++ii)
+            {
+                double w        = weights[ii];
+                double pii      = hist[ii]/total;
+                entropy         -= w*( pii*std::log(pii));
+            }
+        }
+        entropy             = total * entropy;
+        return entropy; 
+    }
+};
+
+/** Functor to calculate the gini impurity
+ */
+class GiniCriterion
+{
+public:
+    /**calculate the weighted gini impurity based on class histogram
+     * and class weights
+     */
+    template<class Array, class Array2>
+    double operator()        (Array     const & hist, 
+                              Array2    const & weights, 
+                              double            total = 1.0) const
+    {
+        return impurity(hist, weights, total);
+    }
+    
+    /** calculate the gini based impurity based on class histogram
+     */
+    template<class Array>
+    double operator()(Array const & hist, double total = 1.0) const
+    {
+        return impurity(hist, total);
+    }
+    
+    /** static version of operator(hist total)
+     */
+    template<class Array>
+    static double impurity(Array const & hist, double total)
+    {
+        return impurity(hist, detail::ConstArr<1>(), total);
+    }
+
+    /** static version of operator(hist, weights, total)
+     */
+    template<class Array, class Array2>
+    static double impurity   (Array     const & hist, 
+                              Array2    const & weights, 
+                              double            total)
+    {
+
+        int     class_count     = hist.size();
+        double  gini            = 0.0;
+        if(class_count == 2)
+        {
+            double w            = weights[0] * weights[1];
+            gini                = w * (hist[0] * hist[1] / total);
+        }
+        else
+        {
+            for(int ii = 0; ii < class_count; ++ii)
+            {
+                double w        = weights[ii];
+                gini           += w*( hist[ii]*( 1.0 - w * hist[ii]/total ) );
+            }
+        }
+        return gini; 
+    }
+};
+
+
+template <class DataSource, class Impurity= GiniCriterion>
+class ImpurityLoss
+{
+
+    DataSource  const &         labels_;
+    ArrayVector<double>        counts_;
+    ArrayVector<double> const  class_weights_;
+    double                      total_counts_;
+    Impurity                    impurity_;
+
+  public:
+
+    template<class T>
+    ImpurityLoss(DataSource  const & labels, 
+                                ProblemSpec<T> const & ext_)
+    : labels_(labels),
+      counts_(ext_.class_count_, 0.0),
+      class_weights_(ext_.class_weights_),
+      total_counts_(0.0)
+    {}
+
+    void reset()
+    {
+        counts_.init(0);
+        total_counts_ = 0.0;
+    }
+
+    template<class Counts>
+    double increment_histogram(Counts const & counts)
+    {
+        std::transform(counts.begin(), counts.end(),
+                       counts_.begin(), counts_.begin(),
+                       std::plus<double>());
+        total_counts_ = std::accumulate( counts_.begin(), 
+                                         counts_.end(),
+                                         0.0);
+        return impurity_(counts_, class_weights_, total_counts_);
+    }
+
+    template<class Counts>
+    double decrement_histogram(Counts const & counts)
+    {
+        std::transform(counts.begin(), counts.end(),
+                       counts_.begin(), counts_.begin(),
+                       std::minus<double>());
+        total_counts_ = std::accumulate( counts_.begin(), 
+                                         counts_.end(),
+                                         0.0);
+        return impurity_(counts_, class_weights_, total_counts_);
+    }
+
+    template<class Iter>
+    double increment(Iter begin, Iter end)
+    {
+        for(Iter iter = begin; iter != end; ++iter)
+        {
+            counts_[labels_(*iter, 0)] +=1.0;
+            total_counts_ +=1.0;
+        }
+        return impurity_(counts_, class_weights_, total_counts_);
+    }
+
+    template<class Iter>
+    double decrement(Iter const &  begin, Iter const & end)
+    {
+        for(Iter iter = begin; iter != end; ++iter)
+        {
+            counts_[labels_(*iter,0)] -=1.0;
+            total_counts_ -=1.0;
+        }
+        return impurity_(counts_, class_weights_, total_counts_);
+    }
+
+    template<class Iter, class Resp_t>
+    double init (Iter begin, Iter end, Resp_t resp)
+    {
+        reset();
+        std::copy(resp.begin(), resp.end(), counts_.begin());
+        total_counts_ = std::accumulate(counts_.begin(), counts_.end(), 0.0); 
+        return impurity_(counts_,class_weights_, total_counts_);
+    }
+    
+    ArrayVector<double> const & response()
+    {
+        return counts_;
+    }
+};
+    
+    
+    
+    template <class DataSource>
+    class RegressionForestCounter
+    {
+    public:
+        typedef MultiArrayShape<2>::type Shp;
+        DataSource const &      labels_;
+        ArrayVector <double>    mean_;
+        ArrayVector <double>    variance_;
+        ArrayVector <double>    tmp_;
+        size_t                  count_;
+        int*                    end_;
+        
+        template<class T>
+        RegressionForestCounter(DataSource const & labels, 
+                                ProblemSpec<T> const & ext_)
+        :
+        labels_(labels),
+        mean_(ext_.response_size_, 0.0),
+        variance_(ext_.response_size_, 0.0),
+        tmp_(ext_.response_size_),
+        count_(0)
+        {}
+        
+        template<class Iter>
+        double increment (Iter begin, Iter end)
+        {
+            for(Iter iter = begin; iter != end; ++iter)
+            {
+                ++count_;
+                for(unsigned int ii = 0; ii < mean_.size(); ++ii)
+                    tmp_[ii] = labels_(*iter, ii) - mean_[ii]; 
+                double f  = 1.0 / count_,
+                f1 = 1.0 - f;
+                for(unsigned int ii = 0; ii < mean_.size(); ++ii)
+                    mean_[ii] += f*tmp_[ii]; 
+                for(unsigned int ii = 0; ii < mean_.size(); ++ii)
+                    variance_[ii] += f1*sq(tmp_[ii]);
+            }
+            double res = std::accumulate(variance_.begin(), 
+                                         variance_.end(),
+                                         0.0,
+                                         std::plus<double>());
+            //std::cerr << res << "  ) = ";
+            return res;
+        }
+        
+        template<class Iter>      //This is BROKEN
+        double decrement (Iter begin, Iter end)
+        {
+            for(Iter iter = begin; iter != end; ++iter)
+            {
+                --count_;
+            }
+
+            begin = end;
+            end   = end + count_;
+            
+
+            for(unsigned int ii = 0; ii < mean_.size(); ++ii)
+            {
+                mean_[ii] = 0;        
+                for(Iter iter = begin; iter != end; ++iter)
+                {
+                    mean_[ii] += labels_(*iter, ii);
+                }
+                mean_[ii] /= count_;
+                variance_[ii] = 0;
+                for(Iter iter = begin; iter != end; ++iter)
+                {
+                    variance_[ii] += (labels_(*iter, ii) - mean_[ii])*(labels_(*iter, ii) - mean_[ii]);
+                }
+            }
+            double res = std::accumulate(variance_.begin(), 
+                                         variance_.end(),
+                                         0.0,
+                                         std::plus<double>());
+            //std::cerr << res << "  ) = ";
+            return res;
+        }
+
+        
+        template<class Iter, class Resp_t>
+        double init (Iter begin, Iter end, Resp_t resp)
+        {
+            reset();
+            return this->increment(begin, end);
+            
+        }
+        
+        
+        ArrayVector<double> const & response()
+        {
+            return mean_;
+        }
+        
+        void reset()
+        {
+            mean_.init(0.0);
+            variance_.init(0.0);
+            count_ = 0; 
+        }
+    };
+    
+    
+template <class DataSource>
+class RegressionForestCounter2
+{
+public:
+    typedef MultiArrayShape<2>::type Shp;
+    DataSource const &      labels_;
+    ArrayVector <double>    mean_;
+    ArrayVector <double>    variance_;
+    ArrayVector <double>    tmp_;
+    size_t                  count_;
+
+    template<class T>
+    RegressionForestCounter2(DataSource const & labels, 
+                            ProblemSpec<T> const & ext_)
+    :
+        labels_(labels),
+        mean_(ext_.response_size_, 0.0),
+        variance_(ext_.response_size_, 0.0),
+        tmp_(ext_.response_size_),
+        count_(0)
+    {}
+    
+    template<class Iter>
+    double increment (Iter begin, Iter end)
+    {
+        for(Iter iter = begin; iter != end; ++iter)
+        {
+            ++count_;
+            for(int ii = 0; ii < mean_.size(); ++ii)
+                tmp_[ii] = labels_(*iter, ii) - mean_[ii]; 
+            double f  = 1.0 / count_,
+                   f1 = 1.0 - f;
+            for(int ii = 0; ii < mean_.size(); ++ii)
+                mean_[ii] += f*tmp_[ii]; 
+            for(int ii = 0; ii < mean_.size(); ++ii)
+                variance_[ii] += f1*sq(tmp_[ii]);
+        }
+        double res = std::accumulate(variance_.begin(), 
+                               variance_.end(),
+                               0.0,
+                               std::plus<double>())
+                /((count_ == 1)? 1:(count_ -1));
+        //std::cerr << res << "  ) = ";
+        return res;
+    }
+
+    template<class Iter>      //This is BROKEN
+    double decrement (Iter begin, Iter end)
+    {
+        for(Iter iter = begin; iter != end; ++iter)
+        {
+            double f  = 1.0 / count_,
+                   f1 = 1.0 - f;
+            for(int ii = 0; ii < mean_.size(); ++ii)
+                mean_[ii] = (mean_[ii] - f*labels_(*iter,ii))/(1-f); 
+            for(int ii = 0; ii < mean_.size(); ++ii)
+                variance_[ii] -= f1*sq(labels_(*iter,ii) - mean_[ii]);
+            --count_;
+        }
+        double res =  std::accumulate(variance_.begin(), 
+                               variance_.end(),
+                               0.0,
+                               std::plus<double>())
+                /((count_ == 1)? 1:(count_ -1));
+        //std::cerr << "( " << res << " + ";
+        return res;
+    }
+    /* west's algorithm for incremental variance
+    // calculation
+    template<class Iter>
+    double increment (Iter begin, Iter end)
+    {
+        for(Iter iter = begin; iter != end; ++iter)
+        {
+            ++count_;
+            for(int ii = 0; ii < mean_.size(); ++ii)
+                tmp_[ii] = labels_(*iter, ii) - mean_[ii]; 
+            double f  = 1.0 / count_,
+                   f1 = 1.0 - f;
+            for(int ii = 0; ii < mean_.size(); ++ii)
+                mean_[ii] += f*tmp_[ii]; 
+            for(int ii = 0; ii < mean_.size(); ++ii)
+                variance_[ii] += f1*sq(tmp_[ii]);
+        }
+        return std::accumulate(variance_.begin(), 
+                               variance_.end(),
+                               0.0,
+                               std::plus<double>())
+                /(count_ -1);
+    }
+
+    template<class Iter>
+    double decrement (Iter begin, Iter end)
+    {
+        for(Iter iter = begin; iter != end; ++iter)
+        {
+            --count_;
+            for(int ii = 0; ii < mean_.size(); ++ii)
+                tmp_[ii] = labels_(*iter, ii) - mean_[ii]; 
+            double f  = 1.0 / count_,
+                   f1 = 1.0 + f;
+            for(int ii = 0; ii < mean_.size(); ++ii)
+                mean_[ii] -= f*tmp_[ii]; 
+            for(int ii = 0; ii < mean_.size(); ++ii)
+                variance_[ii] -= f1*sq(tmp_[ii]);
+        }
+        return std::accumulate(variance_.begin(), 
+                               variance_.end(),
+                               0.0,
+                               std::plus<double>())
+                /(count_ -1);
+    }*/
+
+    template<class Iter, class Resp_t>
+    double init (Iter begin, Iter end, Resp_t resp)
+    {
+        reset();
+        return this->increment(begin, end, resp);
+    }
+    
+
+    ArrayVector<double> const & response()
+    {
+        return mean_;
+    }
+
+    void reset()
+    {
+        mean_.init(0.0);
+        variance_.init(0.0);
+        count_ = 0; 
+    }
+};
+
+template<class Tag, class Datatyp>
+struct LossTraits;
+
+struct LSQLoss
+{};
+
+template<class Datatype>
+struct LossTraits<GiniCriterion, Datatype>
+{
+    typedef ImpurityLoss<Datatype, GiniCriterion> type;
+};
+
+template<class Datatype>
+struct LossTraits<EntropyCriterion, Datatype>
+{
+    typedef ImpurityLoss<Datatype, EntropyCriterion> type;
+};
+
+template<class Datatype>
+struct LossTraits<LSQLoss, Datatype>
+{
+    typedef RegressionForestCounter<Datatype> type;
+};
+
+/** Given a column, choose a split that minimizes some loss
+ */
+template<class LineSearchLossTag>
+class BestGiniOfColumn
+{
+public:
+    ArrayVector<double>     class_weights_;
+    ArrayVector<double>     bestCurrentCounts[2];
+    double                  min_gini_;
+    std::ptrdiff_t               min_index_;
+    double                  min_threshold_;
+    ProblemSpec<>           ext_param_;
+
+    BestGiniOfColumn()
+    {}
+
+    template<class T> 
+    BestGiniOfColumn(ProblemSpec<T> const & ext)
+    :
+        class_weights_(ext.class_weights_),
+        ext_param_(ext)
+    {
+        bestCurrentCounts[0].resize(ext.class_count_);
+        bestCurrentCounts[1].resize(ext.class_count_);
+    }
+    template<class T> 
+    void set_external_parameters(ProblemSpec<T> const & ext)
+    {
+        class_weights_ = ext.class_weights_; 
+        ext_param_ = ext;
+        bestCurrentCounts[0].resize(ext.class_count_);
+        bestCurrentCounts[1].resize(ext.class_count_);
+    }
+    /** calculate the best gini split along a Feature Column
+     * \param column  the feature vector - has to support the [] operator
+     * \param labels  the label vector 
+     * \param begin 
+     * \param end     (in and out)
+     *                begin and end iterators to the indices of the
+     *                samples in the current region. 
+     *                the range begin - end is sorted by the column supplied
+     *                during function execution.
+     * \param region_response
+     *                ???
+     *                class histogram of the range. 
+     *
+     *  precondition: begin, end valid range, 
+     *                class_counts positive integer valued array with the 
+     *                class counts in the current range.
+     *                labels.size() >= max(begin, end); 
+     *  postcondition:
+     *                begin, end sorted by column given. 
+     *                min_gini_ contains the minimum gini found or 
+     *                NumericTraits<double>::max if no split was found.
+     *                min_index_ contains the splitting index in the range
+     *                or invalid data if no split was found.
+     *                BestCirremtcounts[0] and [1] contain the 
+     *                class histogram of the left and right region of 
+     *                the left and right regions. 
+     */
+    template<   class DataSourceF_t,
+                class DataSource_t, 
+                class I_Iter, 
+                class Array>
+    void operator()(DataSourceF_t   const & column,
+                    DataSource_t    const & labels,
+                    I_Iter                & begin, 
+                    I_Iter                & end,
+                    Array           const & region_response)
+    {
+        std::sort(begin, end, 
+                  SortSamplesByDimensions<DataSourceF_t>(column, 0));
+        typedef typename 
+            LossTraits<LineSearchLossTag, DataSource_t>::type LineSearchLoss;
+        LineSearchLoss left(labels, ext_param_); //initialize left and right region
+        LineSearchLoss right(labels, ext_param_);
+
+        
+
+        min_gini_ = right.init(begin, end, region_response);  
+        min_threshold_ = *begin;
+        min_index_     = 0;  //the starting point where to split 
+        DimensionNotEqual<DataSourceF_t> comp(column, 0); 
+        
+        I_Iter iter = begin;
+        I_Iter next = std::adjacent_find(iter, end, comp);
+        //std::cerr << std::distance(begin, end) << std::endl;
+        while( next  != end)
+        {
+            double lr  =  right.decrement(iter, next + 1);
+            double ll  =  left.increment(iter , next + 1);
+            double loss = lr +ll;
+            //std::cerr <<lr << " + "<< ll << " " << loss << " ";
+#ifdef CLASSIFIER_TEST
+            if(loss < min_gini_ && !closeAtTolerance(loss, min_gini_))
+#else
+            if(loss < min_gini_ )
+#endif 
+            {
+                bestCurrentCounts[0] = left.response();
+                bestCurrentCounts[1] = right.response();
+#ifdef CLASSIFIER_TEST
+                min_gini_       = loss < min_gini_? loss : min_gini_;
+#else
+                min_gini_       = loss; 
+#endif
+                min_index_      = next - begin +1 ;
+                min_threshold_  = (double(column(*next,0)) + double(column(*(next +1), 0)))/2.0;
+            }
+            iter = next +1 ;
+            next = std::adjacent_find(iter, end, comp);
+        }
+        //std::cerr << std::endl << " 000 " << std::endl;
+        //int in;
+        //std::cin >> in;
+    }
+
+    template<class DataSource_t, class Iter, class Array>
+    double loss_of_region(DataSource_t const & labels,
+                          Iter & begin, 
+                          Iter & end, 
+                          Array const & region_response) const
+    {
+        typedef typename 
+            LossTraits<LineSearchLossTag, DataSource_t>::type LineSearchLoss;
+        LineSearchLoss region_loss(labels, ext_param_);
+        return 
+            region_loss.init(begin, end, region_response);
+    }
+
+};
+
+namespace detail
+{
+    template<class T>
+    struct Correction
+    {
+        template<class Region, class LabelT>
+        static void exec(Region & in, LabelT & labels)
+        {}
+    };
+    
+    template<>
+    struct Correction<ClassificationTag>
+    {
+        template<class Region, class LabelT>
+        static void exec(Region & region, LabelT & labels) 
+        {
+            if(std::accumulate(region.classCounts().begin(),
+                               region.classCounts().end(), 0.0) != region.size())
+            {
+                RandomForestClassCounter<   LabelT, 
+                                            ArrayVector<double> >
+                    counter(labels, region.classCounts());
+                std::for_each(  region.begin(), region.end(), counter);
+                region.classCountsIsValid = true;
+            }
+        }
+    };
+}
+
+/** Chooses mtry columns and applies ColumnDecisionFunctor to each of the
+ * columns. Then Chooses the column that is best
+ */
+template<class ColumnDecisionFunctor, class Tag = ClassificationTag>
+class ThresholdSplit: public SplitBase<Tag>
+{
+  public:
+
+
+    typedef SplitBase<Tag> SB;
+    
+    ArrayVector<Int32>          splitColumns;
+    ColumnDecisionFunctor       bgfunc;
+
+    double                      region_gini_;
+    ArrayVector<double>         min_gini_;
+    ArrayVector<std::ptrdiff_t>      min_indices_;
+    ArrayVector<double>         min_thresholds_;
+
+    int                         bestSplitIndex;
+
+    double minGini() const
+    {
+        return min_gini_[bestSplitIndex];
+    }
+    int bestSplitColumn() const
+    {
+        return splitColumns[bestSplitIndex];
+    }
+    double bestSplitThreshold() const
+    {
+        return min_thresholds_[bestSplitIndex];
+    }
+
+    template<class T>
+    void set_external_parameters(ProblemSpec<T> const & in)
+    {
+        SB::set_external_parameters(in);        
+        bgfunc.set_external_parameters( SB::ext_param_);
+        int featureCount_ = SB::ext_param_.column_count_;
+        splitColumns.resize(featureCount_);
+        for(int k=0; k<featureCount_; ++k)
+            splitColumns[k] = k;
+        min_gini_.resize(featureCount_);
+        min_indices_.resize(featureCount_);
+        min_thresholds_.resize(featureCount_);
+    }
+
+
+    template<class T, class C, class T2, class C2, class Region, class Random>
+    int findBestSplit(MultiArrayView<2, T, C> features,
+                      MultiArrayView<2, T2, C2>  labels,
+                      Region & region,
+                      ArrayVector<Region>& childRegions,
+                      Random & randint)
+    {
+
+        typedef typename Region::IndexIterator IndexIterator;
+        if(region.size() == 0)
+        {
+           std::cerr << "SplitFunctor::findBestSplit(): stackentry with 0 examples encountered\n"
+                        "continuing learning process...."; 
+        }
+        // calculate things that haven't been calculated yet. 
+        detail::Correction<Tag>::exec(region, labels);
+
+
+        // Is the region pure already?
+        region_gini_ = bgfunc.loss_of_region(labels,
+                                             region.begin(), 
+                                             region.end(),
+                                             region.classCounts());
+        if(region_gini_ <= SB::ext_param_.precision_)
+            return  this->makeTerminalNode(features, labels, region, randint);
+
+        // select columns  to be tried.
+        for(int ii = 0; ii < SB::ext_param_.actual_mtry_; ++ii)
+            std::swap(splitColumns[ii], 
+                      splitColumns[ii+ randint(features.shape(1) - ii)]);
+
+        // find the best gini index
+        bestSplitIndex              = 0;
+        double  current_min_gini    = region_gini_;
+        int     num2try             = features.shape(1);
+        for(int k=0; k<num2try; ++k)
+        {
+            //this functor does all the work
+            bgfunc(columnVector(features, splitColumns[k]),
+                   labels, 
+                   region.begin(), region.end(), 
+                   region.classCounts());
+            min_gini_[k]            = bgfunc.min_gini_; 
+            min_indices_[k]         = bgfunc.min_index_;
+            min_thresholds_[k]      = bgfunc.min_threshold_;
+#ifdef CLASSIFIER_TEST
+            if(     bgfunc.min_gini_ < current_min_gini
+               &&  !closeAtTolerance(bgfunc.min_gini_, current_min_gini))
+#else
+            if(bgfunc.min_gini_ < current_min_gini)
+#endif
+            {
+                current_min_gini = bgfunc.min_gini_;
+                childRegions[0].classCounts() = bgfunc.bestCurrentCounts[0];
+                childRegions[1].classCounts() = bgfunc.bestCurrentCounts[1];
+                childRegions[0].classCountsIsValid = true;
+                childRegions[1].classCountsIsValid = true;
+
+                bestSplitIndex   = k;
+                num2try = SB::ext_param_.actual_mtry_;
+            }
+        }
+        //std::cerr << current_min_gini << "curr " << region_gini_ << std::endl;
+        // did not find any suitable split
+        if(closeAtTolerance(current_min_gini, region_gini_))
+            return  this->makeTerminalNode(features, labels, region, randint);
+        
+        //create a Node for output
+        Node<i_ThresholdNode>   node(SB::t_data, SB::p_data);
+        SB::node_ = node;
+        node.threshold()    = min_thresholds_[bestSplitIndex];
+        node.column()       = splitColumns[bestSplitIndex];
+        
+        // partition the range according to the best dimension 
+        SortSamplesByDimensions<MultiArrayView<2, T, C> > 
+            sorter(features, node.column(), node.threshold());
+        IndexIterator bestSplit =
+            std::partition(region.begin(), region.end(), sorter);
+        // Save the ranges of the child stack entries.
+        childRegions[0].setRange(   region.begin()  , bestSplit       );
+        childRegions[0].rule = region.rule;
+        childRegions[0].rule.push_back(std::make_pair(1, 1.0));
+        childRegions[1].setRange(   bestSplit       , region.end()    );
+        childRegions[1].rule = region.rule;
+        childRegions[1].rule.push_back(std::make_pair(1, 1.0));
+
+        return i_ThresholdNode;
+    }
+};
+
+typedef  ThresholdSplit<BestGiniOfColumn<GiniCriterion> >                      GiniSplit;
+typedef  ThresholdSplit<BestGiniOfColumn<EntropyCriterion> >                 EntropySplit;
+typedef  ThresholdSplit<BestGiniOfColumn<LSQLoss>, RegressionTag>              RegressionSplit;
+
+namespace rf
+{
+
+/** This namespace contains additional Splitfunctors.
+ *
+ * The Split functor classes are designed in a modular fashion because new split functors may 
+ * share a lot of code with existing ones. 
+ * 
+ * ThresholdSplit implements the functionality needed for any split functor, that makes its 
+ * decision via one dimensional axis-parallel cuts. The Template parameter defines how the split
+ * along one dimension is chosen. 
+ *
+ * The BestGiniOfColumn class chooses a split that minimizes one of the Loss functions supplied
+ * (GiniCriterion for classification and LSQLoss for regression). Median chooses the Split in a 
+ * kD tree fashion. 
+ *
+ *
+ * Currently defined typedefs: 
+ * \code
+ * typedef  ThresholdSplit<BestGiniOfColumn<GiniCriterion> >                 GiniSplit;
+ * typedef  ThresholdSplit<BestGiniOfColumn<LSQLoss>, RegressionTag>         RegressionSplit;
+ * typedef  ThresholdSplit<Median> MedianSplit;
+ * \endcode
+ */
+namespace split
+{
+
+/** This Functor chooses the median value of a column
+ */
+class Median
+{
+public:
+
+    typedef GiniCriterion   LineSearchLossTag;
+    ArrayVector<double>     class_weights_;
+    ArrayVector<double>     bestCurrentCounts[2];
+    double                  min_gini_;
+    std::ptrdiff_t          min_index_;
+    double                  min_threshold_;
+    ProblemSpec<>           ext_param_;
+
+    Median()
+    {}
+
+    template<class T> 
+    Median(ProblemSpec<T> const & ext)
+    :
+        class_weights_(ext.class_weights_),
+        ext_param_(ext)
+    {
+        bestCurrentCounts[0].resize(ext.class_count_);
+        bestCurrentCounts[1].resize(ext.class_count_);
+    }
+  
+    template<class T> 
+    void set_external_parameters(ProblemSpec<T> const & ext)
+    {
+        class_weights_ = ext.class_weights_; 
+        ext_param_ = ext;
+        bestCurrentCounts[0].resize(ext.class_count_);
+        bestCurrentCounts[1].resize(ext.class_count_);
+    }
+     
+    template<   class DataSourceF_t,
+                class DataSource_t, 
+                class I_Iter, 
+                class Array>
+    void operator()(DataSourceF_t   const & column,
+                    DataSource_t    const & labels,
+                    I_Iter                & begin, 
+                    I_Iter                & end,
+                    Array           const & region_response)
+    {
+        std::sort(begin, end, 
+                  SortSamplesByDimensions<DataSourceF_t>(column, 0));
+        typedef typename 
+            LossTraits<LineSearchLossTag, DataSource_t>::type LineSearchLoss;
+        LineSearchLoss left(labels, ext_param_);
+        LineSearchLoss right(labels, ext_param_);
+        right.init(begin, end, region_response);
+
+        min_gini_ = NumericTraits<double>::max();
+        min_index_ = floor(double(end - begin)/2.0); 
+        min_threshold_ =  column[*(begin + min_index_)];
+        SortSamplesByDimensions<DataSourceF_t> 
+            sorter(column, 0, min_threshold_);
+        I_Iter part = std::partition(begin, end, sorter);
+        DimensionNotEqual<DataSourceF_t> comp(column, 0); 
+        if(part == begin)
+        {
+            part= std::adjacent_find(part, end, comp)+1;
+            
+        }
+        if(part >= end)
+        {
+            return; 
+        }
+        else
+        {
+            min_threshold_ = column[*part];
+        }
+        min_gini_ = right.decrement(begin, part) 
+              +     left.increment(begin , part);
+
+        bestCurrentCounts[0] = left.response();
+        bestCurrentCounts[1] = right.response();
+        
+        min_index_      = part - begin;
+    }
+
+    template<class DataSource_t, class Iter, class Array>
+    double loss_of_region(DataSource_t const & labels,
+                          Iter & begin, 
+                          Iter & end, 
+                          Array const & region_response) const
+    {
+        typedef typename 
+            LossTraits<LineSearchLossTag, DataSource_t>::type LineSearchLoss;
+        LineSearchLoss region_loss(labels, ext_param_);
+        return 
+            region_loss.init(begin, end, region_response);
+    }
+
+};
+
+typedef  ThresholdSplit<Median> MedianSplit;
+
+
+/** This Functor chooses a random value of a column
+ */
+class RandomSplitOfColumn
+{
+public:
+
+    typedef GiniCriterion   LineSearchLossTag;
+    ArrayVector<double>     class_weights_;
+    ArrayVector<double>     bestCurrentCounts[2];
+    double                  min_gini_;
+    std::ptrdiff_t          min_index_;
+    double                  min_threshold_;
+    ProblemSpec<>           ext_param_;
+    typedef RandomMT19937   Random_t;
+    Random_t                random;
+
+    RandomSplitOfColumn()
+    {}
+
+    template<class T> 
+    RandomSplitOfColumn(ProblemSpec<T> const & ext)
+    :
+        class_weights_(ext.class_weights_),
+        ext_param_(ext),
+        random(RandomSeed)
+    {
+        bestCurrentCounts[0].resize(ext.class_count_);
+        bestCurrentCounts[1].resize(ext.class_count_);
+    }
+    
+    template<class T> 
+    RandomSplitOfColumn(ProblemSpec<T> const & ext, Random_t & random_)
+    :
+        class_weights_(ext.class_weights_),
+        ext_param_(ext),
+        random(random_)
+    {
+        bestCurrentCounts[0].resize(ext.class_count_);
+        bestCurrentCounts[1].resize(ext.class_count_);
+    }
+  
+    template<class T> 
+    void set_external_parameters(ProblemSpec<T> const & ext)
+    {
+        class_weights_ = ext.class_weights_; 
+        ext_param_ = ext;
+        bestCurrentCounts[0].resize(ext.class_count_);
+        bestCurrentCounts[1].resize(ext.class_count_);
+    }
+     
+    template<   class DataSourceF_t,
+                class DataSource_t, 
+                class I_Iter, 
+                class Array>
+    void operator()(DataSourceF_t   const & column,
+                    DataSource_t    const & labels,
+                    I_Iter                & begin, 
+                    I_Iter                & end,
+                    Array           const & region_response)
+    {
+        std::sort(begin, end, 
+                  SortSamplesByDimensions<DataSourceF_t>(column, 0));
+        typedef typename 
+            LossTraits<LineSearchLossTag, DataSource_t>::type LineSearchLoss;
+        LineSearchLoss left(labels, ext_param_);
+        LineSearchLoss right(labels, ext_param_);
+        right.init(begin, end, region_response);
+
+        
+        min_gini_ = NumericTraits<double>::max();
+        int tmp_pt = random.uniformInt(std::distance(begin, end));
+        min_index_ = tmp_pt;
+        min_threshold_ =  column[*(begin + min_index_)];
+        SortSamplesByDimensions<DataSourceF_t> 
+            sorter(column, 0, min_threshold_);
+        I_Iter part = std::partition(begin, end, sorter);
+        DimensionNotEqual<DataSourceF_t> comp(column, 0); 
+        if(part == begin)
+        {
+            part= std::adjacent_find(part, end, comp)+1;
+            
+        }
+        if(part >= end)
+        {
+            return; 
+        }
+        else
+        {
+            min_threshold_ = column[*part];
+        }
+        min_gini_ = right.decrement(begin, part) 
+              +     left.increment(begin , part);
+
+        bestCurrentCounts[0] = left.response();
+        bestCurrentCounts[1] = right.response();
+        
+        min_index_      = part - begin;
+    }
+
+    template<class DataSource_t, class Iter, class Array>
+    double loss_of_region(DataSource_t const & labels,
+                          Iter & begin, 
+                          Iter & end, 
+                          Array const & region_response) const
+    {
+        typedef typename 
+            LossTraits<LineSearchLossTag, DataSource_t>::type LineSearchLoss;
+        LineSearchLoss region_loss(labels, ext_param_);
+        return 
+            region_loss.init(begin, end, region_response);
+    }
+
+};
+
+typedef  ThresholdSplit<RandomSplitOfColumn> RandomSplit;
+}
+}
+
+
+} //namespace vigra
+#endif // VIGRA_RANDOM_FOREST_SPLIT_HXX
diff --git a/include/vigra/random_forest/rf_visitors.hxx b/include/vigra/random_forest/rf_visitors.hxx
new file mode 100755
index 0000000..c927013
--- /dev/null
+++ b/include/vigra/random_forest/rf_visitors.hxx
@@ -0,0 +1,1722 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by  Ullrich Koethe and Rahul Nair         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+#ifndef RF_VISITORS_HXX
+#define RF_VISITORS_HXX
+
+#ifdef HasHDF5
+# include "vigra/hdf5impex.hxx"
+#endif // HasHDF5
+#include <vigra/windows.h>
+#include <iostream>
+#include <iomanip>
+
+#include <vigra/multi_pointoperators.hxx>
+#include <vigra/timing.hxx>
+
+namespace vigra
+{
+namespace rf
+{
+/** \addtogroup MachineLearning Machine Learning
+**/
+//@{
+
+/**
+    This namespace contains all classes and methods related to extracting information during 
+    learning of the random forest. All Visitors share the same interface defined in 
+    visitors::VisitorBase. The member methods are invoked at certain points of the main code in 
+    the order they were supplied.
+    
+    For the Random Forest the  Visitor concept is implemented as a statically linked list 
+    (Using templates). Each Visitor object is encapsulated in a detail::VisitorNode object. The 
+    VisitorNode object calls the Next Visitor after one of its visit() methods have terminated.
+    
+    To simplify usage create_visitor() factory methods are supplied.
+    Use the create_visitor() method to supply visitor objects to the RandomForest::learn() method.
+    It is possible to supply more than one visitor. They will then be invoked in serial order.
+
+    The calculated information are stored as public data members of the class. - see documentation
+    of the individual visitors
+    
+    While creating a new visitor the new class should therefore publicly inherit from this class 
+    (i.e.: see visitors::OOB_Error).
+
+    \code
+
+      typedef xxx feature_t \\ replace xxx with whichever type
+      typedef yyy label_t   \\ meme chose. 
+      MultiArrayView<2, feature_t> f = get_some_features();
+      MultiArrayView<2, label_t>   l = get_some_labels();
+      RandomForest<> rf()
+    
+      //calculate OOB Error
+      visitors::OOB_Error oob_v;
+      //calculate Variable Importance
+      visitors::VariableImportanceVisitor varimp_v;
+
+      double oob_error = rf.learn(f, l, visitors::create_visitor(oob_v, varimp_v);
+      //the data can be found in the attributes of oob_v and varimp_v now
+      
+    \endcode
+*/
+namespace visitors
+{
+    
+    
+/** Base Class from which all Visitors derive. Can be used as a template to create new 
+ * Visitors.
+ */
+class VisitorBase
+{
+    public:
+    bool active_;   
+    bool is_active()
+    {
+        return active_;
+    }
+
+    bool has_value()
+    {
+        return false;
+    }
+
+    VisitorBase()
+        : active_(true)
+    {}
+
+    void deactivate()
+    {
+        active_ = false;
+    }
+    void activate()
+    {
+        active_ = true;
+    }
+    
+    /** do something after the the Split has decided how to process the Region
+     * (Stack entry)
+     *
+     * \param tree      reference to the tree that is currently being learned
+     * \param split     reference to the split object
+     * \param parent    current stack entry  which was used to decide the split
+     * \param leftChild left stack entry that will be pushed
+     * \param rightChild
+     *                  right stack entry that will be pushed.
+     * \param features  features matrix
+     * \param labels    label matrix
+     * \sa RF_Traits::StackEntry_t
+     */
+    template<class Tree, class Split, class Region, class Feature_t, class Label_t>
+    void visit_after_split( Tree          & tree, 
+                            Split         & split,
+                            Region        & parent,
+                            Region        & leftChild,
+                            Region        & rightChild,
+                            Feature_t     & features,
+                            Label_t       & labels)
+    {}
+    
+    /** do something after each tree has been learned
+     *
+     * \param rf        reference to the random forest object that called this
+     *                  visitor
+     * \param pr        reference to the preprocessor that processed the input
+     * \param sm        reference to the sampler object
+     * \param st        reference to the first stack entry
+     * \param index     index of current tree
+     */
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {}
+    
+    /** do something after all trees have been learned
+     *
+     * \param rf        reference to the random forest object that called this
+     *                  visitor
+     * \param pr        reference to the preprocessor that processed the input
+     */
+    template<class RF, class PR>
+    void visit_at_end(RF const & rf, PR const & pr)
+    {}
+    
+    /** do something before learning starts 
+     *
+     * \param rf        reference to the random forest object that called this
+     *                  visitor
+     * \param pr        reference to the Processor class used.
+     */
+    template<class RF, class PR>
+    void visit_at_beginning(RF const & rf, PR const & pr)
+    {}
+    /** do some thing while traversing tree after it has been learned 
+     *  (external nodes)
+     *
+     * \param tr        reference to the tree object that called this visitor
+     * \param index     index in the topology_ array we currently are at
+     * \param node_t    type of node we have (will be e_.... - )
+     * \param features  feature matrix
+     * \sa  NodeTags;
+     *
+     * you can create the node by using a switch on node_tag and using the 
+     * corresponding Node objects. Or - if you do not care about the type 
+     * use the NodeBase class.
+     */
+    template<class TR, class IntT, class TopT,class Feat>
+    void visit_external_node(TR & tr, IntT index, TopT node_t,Feat & features)
+    {}
+    
+    /** do something when visiting a internal node after it has been learned
+     *
+     * \sa visit_external_node
+     */
+    template<class TR, class IntT, class TopT,class Feat>
+    void visit_internal_node(TR & tr, IntT index, TopT node_t,Feat & features)
+    {}
+
+    /** return a double value.  The value of the first 
+     * visitor encountered that has a return value is returned with the
+     * RandomForest::learn() method - or -1.0 if no return value visitor
+     * existed. This functionality basically only exists so that the 
+     * OOB - visitor can return the oob error rate like in the old version 
+     * of the random forest.
+     */
+    double return_val()
+    {
+        return -1.0;
+    }
+};
+
+
+/** Last Visitor that should be called to stop the recursion.
+ */
+class StopVisiting: public VisitorBase
+{
+    public:
+    bool has_value()
+    {
+        return true;
+    }
+    double return_val()
+    {
+        return -1.0;
+    }
+};
+namespace detail
+{
+/** Container elements of the statically linked Visitor list.
+ *
+ * use the create_visitor() factory functions to create visitors up to size 10;
+ *
+ */
+template <class Visitor, class Next = StopVisiting>
+class VisitorNode
+{
+    public:
+    
+    StopVisiting    stop_;
+    Next            next_;
+    Visitor &       visitor_;   
+    VisitorNode(Visitor & visitor, Next & next) 
+    : 
+        next_(next), visitor_(visitor)
+    {}
+
+    VisitorNode(Visitor &  visitor) 
+    : 
+        next_(stop_), visitor_(visitor)
+    {}
+
+    template<class Tree, class Split, class Region, class Feature_t, class Label_t>
+    void visit_after_split( Tree          & tree, 
+                            Split         & split,
+                            Region        & parent,
+                            Region        & leftChild,
+                            Region        & rightChild,
+                            Feature_t     & features,
+                            Label_t       & labels)
+    {
+        if(visitor_.is_active())
+            visitor_.visit_after_split(tree, split, 
+                                       parent, leftChild, rightChild,
+                                       features, labels);
+        next_.visit_after_split(tree, split, parent, leftChild, rightChild,
+                                features, labels);
+    }
+
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {
+        if(visitor_.is_active())
+            visitor_.visit_after_tree(rf, pr, sm, st, index);
+        next_.visit_after_tree(rf, pr, sm, st, index);
+    }
+
+    template<class RF, class PR>
+    void visit_at_beginning(RF & rf, PR & pr)
+    {
+        if(visitor_.is_active())
+            visitor_.visit_at_beginning(rf, pr);
+        next_.visit_at_beginning(rf, pr);
+    }
+    template<class RF, class PR>
+    void visit_at_end(RF & rf, PR & pr)
+    {
+        if(visitor_.is_active())
+            visitor_.visit_at_end(rf, pr);
+        next_.visit_at_end(rf, pr);
+    }
+    
+    template<class TR, class IntT, class TopT,class Feat>
+    void visit_external_node(TR & tr, IntT & index, TopT & node_t,Feat & features)
+    {
+        if(visitor_.is_active())
+            visitor_.visit_external_node(tr, index, node_t,features);
+        next_.visit_external_node(tr, index, node_t,features);
+    }
+    template<class TR, class IntT, class TopT,class Feat>
+    void visit_internal_node(TR & tr, IntT & index, TopT & node_t,Feat & features)
+    {
+        if(visitor_.is_active())
+            visitor_.visit_internal_node(tr, index, node_t,features);
+        next_.visit_internal_node(tr, index, node_t,features);
+    }
+
+    double return_val()
+    {
+        if(visitor_.is_active() && visitor_.has_value())
+            return visitor_.return_val();
+        return next_.return_val();
+    }
+};
+
+} //namespace detail
+
+//////////////////////////////////////////////////////////////////////////////
+//  Visitor Factory function up to 10 visitors                              //
+//////////////////////////////////////////////////////////////////////////////
+
+/** factory method to to be used with RandomForest::learn()
+ */
+template<class A>
+detail::VisitorNode<A>
+create_visitor(A & a)
+{
+   typedef detail::VisitorNode<A> _0_t;
+   _0_t _0(a);
+   return _0;
+}
+
+
+/** factory method to to be used with RandomForest::learn()
+ */
+template<class A, class B>
+detail::VisitorNode<A, detail::VisitorNode<B> >
+create_visitor(A & a, B & b)
+{
+   typedef detail::VisitorNode<B> _1_t;
+   _1_t _1(b);
+   typedef detail::VisitorNode<A, _1_t> _0_t;
+   _0_t _0(a, _1);
+   return _0;
+}
+
+
+/** factory method to to be used with RandomForest::learn()
+ */
+template<class A, class B, class C>
+detail::VisitorNode<A, detail::VisitorNode<B, detail::VisitorNode<C> > >
+create_visitor(A & a, B & b, C & c)
+{
+   typedef detail::VisitorNode<C> _2_t;
+   _2_t _2(c);
+   typedef detail::VisitorNode<B, _2_t> _1_t;
+   _1_t _1(b, _2);
+   typedef detail::VisitorNode<A, _1_t> _0_t;
+   _0_t _0(a, _1);
+   return _0;
+}
+
+
+/** factory method to to be used with RandomForest::learn()
+ */
+template<class A, class B, class C, class D>
+detail::VisitorNode<A, detail::VisitorNode<B, detail::VisitorNode<C, 
+    detail::VisitorNode<D> > > >
+create_visitor(A & a, B & b, C & c, D & d)
+{
+   typedef detail::VisitorNode<D> _3_t;
+   _3_t _3(d);
+   typedef detail::VisitorNode<C, _3_t> _2_t;
+   _2_t _2(c, _3);
+   typedef detail::VisitorNode<B, _2_t> _1_t;
+   _1_t _1(b, _2);
+   typedef detail::VisitorNode<A, _1_t> _0_t;
+   _0_t _0(a, _1);
+   return _0;
+}
+
+
+/** factory method to to be used with RandomForest::learn()
+ */
+template<class A, class B, class C, class D, class E>
+detail::VisitorNode<A, detail::VisitorNode<B, detail::VisitorNode<C, 
+    detail::VisitorNode<D, detail::VisitorNode<E> > > > >
+create_visitor(A & a, B & b, C & c, 
+               D & d, E & e)
+{
+   typedef detail::VisitorNode<E> _4_t;
+   _4_t _4(e);
+   typedef detail::VisitorNode<D, _4_t> _3_t;
+   _3_t _3(d, _4);
+   typedef detail::VisitorNode<C, _3_t> _2_t;
+   _2_t _2(c, _3);
+   typedef detail::VisitorNode<B, _2_t> _1_t;
+   _1_t _1(b, _2);
+   typedef detail::VisitorNode<A, _1_t> _0_t;
+   _0_t _0(a, _1);
+   return _0;
+}
+
+
+/** factory method to to be used with RandomForest::learn()
+ */
+template<class A, class B, class C, class D, class E,
+         class F>
+detail::VisitorNode<A, detail::VisitorNode<B, detail::VisitorNode<C, 
+    detail::VisitorNode<D, detail::VisitorNode<E, detail::VisitorNode<F> > > > > >
+create_visitor(A & a, B & b, C & c, 
+               D & d, E & e, F & f)
+{
+   typedef detail::VisitorNode<F> _5_t;
+   _5_t _5(f);
+   typedef detail::VisitorNode<E, _5_t> _4_t;
+   _4_t _4(e, _5);
+   typedef detail::VisitorNode<D, _4_t> _3_t;
+   _3_t _3(d, _4);
+   typedef detail::VisitorNode<C, _3_t> _2_t;
+   _2_t _2(c, _3);
+   typedef detail::VisitorNode<B, _2_t> _1_t;
+   _1_t _1(b, _2);
+   typedef detail::VisitorNode<A, _1_t> _0_t;
+   _0_t _0(a, _1);
+   return _0;
+}
+
+
+/** factory method to to be used with RandomForest::learn()
+ */
+template<class A, class B, class C, class D, class E,
+         class F, class G>
+detail::VisitorNode<A, detail::VisitorNode<B, detail::VisitorNode<C, 
+    detail::VisitorNode<D, detail::VisitorNode<E, detail::VisitorNode<F, 
+    detail::VisitorNode<G> > > > > > >
+create_visitor(A & a, B & b, C & c, 
+               D & d, E & e, F & f, G & g)
+{
+   typedef detail::VisitorNode<G> _6_t;
+   _6_t _6(g);
+   typedef detail::VisitorNode<F, _6_t> _5_t;
+   _5_t _5(f, _6);
+   typedef detail::VisitorNode<E, _5_t> _4_t;
+   _4_t _4(e, _5);
+   typedef detail::VisitorNode<D, _4_t> _3_t;
+   _3_t _3(d, _4);
+   typedef detail::VisitorNode<C, _3_t> _2_t;
+   _2_t _2(c, _3);
+   typedef detail::VisitorNode<B, _2_t> _1_t;
+   _1_t _1(b, _2);
+   typedef detail::VisitorNode<A, _1_t> _0_t;
+   _0_t _0(a, _1);
+   return _0;
+}
+
+
+/** factory method to to be used with RandomForest::learn()
+ */
+template<class A, class B, class C, class D, class E,
+         class F, class G, class H>
+detail::VisitorNode<A, detail::VisitorNode<B, detail::VisitorNode<C, 
+    detail::VisitorNode<D, detail::VisitorNode<E, detail::VisitorNode<F, 
+    detail::VisitorNode<G, detail::VisitorNode<H> > > > > > > >
+create_visitor(A & a, B & b, C & c, 
+               D & d, E & e, F & f, 
+               G & g, H & h)
+{
+   typedef detail::VisitorNode<H> _7_t;
+   _7_t _7(h);
+   typedef detail::VisitorNode<G, _7_t> _6_t;
+   _6_t _6(g, _7);
+   typedef detail::VisitorNode<F, _6_t> _5_t;
+   _5_t _5(f, _6);
+   typedef detail::VisitorNode<E, _5_t> _4_t;
+   _4_t _4(e, _5);
+   typedef detail::VisitorNode<D, _4_t> _3_t;
+   _3_t _3(d, _4);
+   typedef detail::VisitorNode<C, _3_t> _2_t;
+   _2_t _2(c, _3);
+   typedef detail::VisitorNode<B, _2_t> _1_t;
+   _1_t _1(b, _2);
+   typedef detail::VisitorNode<A, _1_t> _0_t;
+   _0_t _0(a, _1);
+   return _0;
+}
+
+
+/** factory method to to be used with RandomForest::learn()
+ */
+template<class A, class B, class C, class D, class E,
+         class F, class G, class H, class I>
+detail::VisitorNode<A, detail::VisitorNode<B, detail::VisitorNode<C, 
+    detail::VisitorNode<D, detail::VisitorNode<E, detail::VisitorNode<F, 
+    detail::VisitorNode<G, detail::VisitorNode<H, detail::VisitorNode<I> > > > > > > > >
+create_visitor(A & a, B & b, C & c, 
+               D & d, E & e, F & f, 
+               G & g, H & h, I & i)
+{
+   typedef detail::VisitorNode<I> _8_t;
+   _8_t _8(i);
+   typedef detail::VisitorNode<H, _8_t> _7_t;
+   _7_t _7(h, _8);
+   typedef detail::VisitorNode<G, _7_t> _6_t;
+   _6_t _6(g, _7);
+   typedef detail::VisitorNode<F, _6_t> _5_t;
+   _5_t _5(f, _6);
+   typedef detail::VisitorNode<E, _5_t> _4_t;
+   _4_t _4(e, _5);
+   typedef detail::VisitorNode<D, _4_t> _3_t;
+   _3_t _3(d, _4);
+   typedef detail::VisitorNode<C, _3_t> _2_t;
+   _2_t _2(c, _3);
+   typedef detail::VisitorNode<B, _2_t> _1_t;
+   _1_t _1(b, _2);
+   typedef detail::VisitorNode<A, _1_t> _0_t;
+   _0_t _0(a, _1);
+   return _0;
+}
+
+/** factory method to to be used with RandomForest::learn()
+ */
+template<class A, class B, class C, class D, class E,
+         class F, class G, class H, class I, class J>
+detail::VisitorNode<A, detail::VisitorNode<B, detail::VisitorNode<C, 
+    detail::VisitorNode<D, detail::VisitorNode<E, detail::VisitorNode<F, 
+    detail::VisitorNode<G, detail::VisitorNode<H, detail::VisitorNode<I,
+    detail::VisitorNode<J> > > > > > > > > >
+create_visitor(A & a, B & b, C & c, 
+               D & d, E & e, F & f, 
+               G & g, H & h, I & i,
+               J & j)
+{
+   typedef detail::VisitorNode<J> _9_t;
+   _9_t _9(j);
+   typedef detail::VisitorNode<I, _9_t> _8_t;
+   _8_t _8(i, _9);
+   typedef detail::VisitorNode<H, _8_t> _7_t;
+   _7_t _7(h, _8);
+   typedef detail::VisitorNode<G, _7_t> _6_t;
+   _6_t _6(g, _7);
+   typedef detail::VisitorNode<F, _6_t> _5_t;
+   _5_t _5(f, _6);
+   typedef detail::VisitorNode<E, _5_t> _4_t;
+   _4_t _4(e, _5);
+   typedef detail::VisitorNode<D, _4_t> _3_t;
+   _3_t _3(d, _4);
+   typedef detail::VisitorNode<C, _3_t> _2_t;
+   _2_t _2(c, _3);
+   typedef detail::VisitorNode<B, _2_t> _1_t;
+   _1_t _1(b, _2);
+   typedef detail::VisitorNode<A, _1_t> _0_t;
+   _0_t _0(a, _1);
+   return _0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Visitors of communal interest.                                           //
+//////////////////////////////////////////////////////////////////////////////
+
+
+/** Visitor to gain information, later needed for online learning.
+ */
+
+class OnlineLearnVisitor: public VisitorBase
+{
+public:
+    //Set if we adjust thresholds
+    bool adjust_thresholds;
+    //Current tree id
+    int tree_id;
+    //Last node id for finding parent
+    int last_node_id;
+    //Need to now the label for interior node visiting
+    vigra::Int32 current_label;
+    //marginal distribution for interior nodes
+    //
+    OnlineLearnVisitor():
+        adjust_thresholds(false), tree_id(0), last_node_id(0), current_label(0)
+    {}
+    struct MarginalDistribution
+    {
+        ArrayVector<Int32> leftCounts;
+        Int32 leftTotalCounts;
+        ArrayVector<Int32> rightCounts;
+        Int32 rightTotalCounts;
+        double gap_left;
+        double gap_right;
+    };
+    typedef ArrayVector<vigra::Int32> IndexList;
+
+    //All information for one tree
+    struct TreeOnlineInformation
+    {
+        std::vector<MarginalDistribution> mag_distributions;
+        std::vector<IndexList> index_lists;
+        //map for linear index of mag_distributions
+        std::map<int,int> interior_to_index;
+        //map for linear index of index_lists
+        std::map<int,int> exterior_to_index;
+    };
+
+    //All trees
+    std::vector<TreeOnlineInformation> trees_online_information;
+
+    /** Initialize, set the number of trees
+     */
+    template<class RF,class PR>
+    void visit_at_beginning(RF & rf,const PR & pr)
+    {
+        tree_id=0;
+        trees_online_information.resize(rf.options_.tree_count_);
+    }
+
+    /** Reset a tree
+     */
+    void reset_tree(int tree_id)
+    {
+        trees_online_information[tree_id].mag_distributions.clear();
+        trees_online_information[tree_id].index_lists.clear();
+        trees_online_information[tree_id].interior_to_index.clear();
+        trees_online_information[tree_id].exterior_to_index.clear();
+    }
+
+    /** simply increase the tree count
+    */
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {
+        tree_id++;
+    }
+    
+    template<class Tree, class Split, class Region, class Feature_t, class Label_t>
+    void visit_after_split( Tree          & tree, 
+                Split         & split,
+                            Region       & parent,
+                            Region        & leftChild,
+                            Region        & rightChild,
+                            Feature_t     & features,
+                            Label_t       & labels)
+    {
+        int linear_index;
+        int addr=tree.topology_.size();
+        if(split.createNode().typeID() == i_ThresholdNode)
+        {
+            if(adjust_thresholds)
+            {
+                //Store marginal distribution
+                linear_index=trees_online_information[tree_id].mag_distributions.size();
+                trees_online_information[tree_id].interior_to_index[addr]=linear_index;
+                trees_online_information[tree_id].mag_distributions.push_back(MarginalDistribution());
+
+                trees_online_information[tree_id].mag_distributions.back().leftCounts=leftChild.classCounts_;
+                trees_online_information[tree_id].mag_distributions.back().rightCounts=rightChild.classCounts_;
+
+                trees_online_information[tree_id].mag_distributions.back().leftTotalCounts=leftChild.size_;
+                trees_online_information[tree_id].mag_distributions.back().rightTotalCounts=rightChild.size_;
+                //Store the gap
+                double gap_left,gap_right;
+                int i;
+                gap_left=features(leftChild[0],split.bestSplitColumn());
+                for(i=1;i<leftChild.size();++i)
+                    if(features(leftChild[i],split.bestSplitColumn())>gap_left)
+                        gap_left=features(leftChild[i],split.bestSplitColumn());
+                gap_right=features(rightChild[0],split.bestSplitColumn());
+                for(i=1;i<rightChild.size();++i)
+                    if(features(rightChild[i],split.bestSplitColumn())<gap_right)
+                        gap_right=features(rightChild[i],split.bestSplitColumn());
+                trees_online_information[tree_id].mag_distributions.back().gap_left=gap_left;
+                trees_online_information[tree_id].mag_distributions.back().gap_right=gap_right;
+            }
+        }
+        else
+        {
+            //Store index list
+            linear_index=trees_online_information[tree_id].index_lists.size();
+            trees_online_information[tree_id].exterior_to_index[addr]=linear_index;
+
+            trees_online_information[tree_id].index_lists.push_back(IndexList());
+
+            trees_online_information[tree_id].index_lists.back().resize(parent.size_,0);
+            std::copy(parent.begin_,parent.end_,trees_online_information[tree_id].index_lists.back().begin());
+        }
+    }
+    void add_to_index_list(int tree,int node,int index)
+    {
+        if(!this->active_)
+            return;
+        TreeOnlineInformation &ti=trees_online_information[tree];
+        ti.index_lists[ti.exterior_to_index[node]].push_back(index);
+    }
+    void move_exterior_node(int src_tree,int src_index,int dst_tree,int dst_index)
+    {
+        if(!this->active_)
+            return;
+        trees_online_information[dst_tree].exterior_to_index[dst_index]=trees_online_information[src_tree].exterior_to_index[src_index];
+        trees_online_information[src_tree].exterior_to_index.erase(src_index);
+    }
+    /** do something when visiting a internal node during getToLeaf
+     *
+     * remember as last node id, for finding the parent of the last external node
+     * also: adjust class counts and borders
+     */
+    template<class TR, class IntT, class TopT,class Feat>
+        void visit_internal_node(TR & tr, IntT index, TopT node_t,Feat & features)
+        {
+            last_node_id=index;
+            if(adjust_thresholds)
+            {
+                vigra_assert(node_t==i_ThresholdNode,"We can only visit threshold nodes");
+                //Check if we are in the gap
+                double value=features(0, Node<i_ThresholdNode>(tr.topology_,tr.parameters_,index).column());
+                TreeOnlineInformation &ti=trees_online_information[tree_id];
+                MarginalDistribution &m=ti.mag_distributions[ti.interior_to_index[index]];
+                if(value>m.gap_left && value<m.gap_right)
+                {
+                    //Check which site we want to go
+                    if(m.leftCounts[current_label]/double(m.leftTotalCounts)>m.rightCounts[current_label]/double(m.rightTotalCounts))
+                    {
+                        //We want to go left
+                        m.gap_left=value;
+                    }
+                    else
+                    {
+                        //We want to go right
+                        m.gap_right=value;
+                    }
+                    Node<i_ThresholdNode>(tr.topology_,tr.parameters_,index).threshold()=(m.gap_right+m.gap_left)/2.0;
+                }
+                //Adjust class counts
+                if(value>Node<i_ThresholdNode>(tr.topology_,tr.parameters_,index).threshold())
+                {
+                    ++m.rightTotalCounts;
+                    ++m.rightCounts[current_label];
+                }
+                else
+                {
+                    ++m.leftTotalCounts;
+                    ++m.rightCounts[current_label];
+                }
+            }
+        }
+    /** do something when visiting a extern node during getToLeaf
+     * 
+     * Store the new index!
+     */
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Out of Bag Error estimates                                               //
+//////////////////////////////////////////////////////////////////////////////
+
+
+/** Visitor that calculates the oob error of each individual randomized
+ * decision tree. 
+ *
+ * After training a tree, all those samples that are OOB for this particular tree
+ * are put down the tree and the error estimated. 
+ * the per tree oob error is the average of the individual error estimates. 
+ * (oobError = average error of one randomized tree)
+ * Note: This is Not the OOB - Error estimate suggested by Breiman (See OOB_Error 
+ * visitor)
+ */
+class OOB_PerTreeError:public VisitorBase
+{
+public:
+    /** Average error of one randomized decision tree
+     */
+    double oobError;
+
+    int totalOobCount;
+    ArrayVector<int> oobCount,oobErrorCount;
+
+    OOB_PerTreeError()
+    : oobError(0.0),
+      totalOobCount(0)
+    {}
+
+
+    bool has_value()
+    {
+        return true;
+    }
+
+
+    /** does the basic calculation per tree*/
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(    RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {
+        //do the first time called.
+        if(int(oobCount.size()) != rf.ext_param_.row_count_)
+        {
+            oobCount.resize(rf.ext_param_.row_count_, 0);
+            oobErrorCount.resize(rf.ext_param_.row_count_, 0);
+        }
+        // go through the samples
+        for(int l = 0; l < rf.ext_param_.row_count_; ++l)
+        {
+            // if the lth sample is oob...
+            if(!sm.is_used()[l])
+            {
+                ++oobCount[l];
+                if(     rf.tree(index)
+                            .predictLabel(rowVector(pr.features(), l)) 
+                    !=  pr.response()(l,0))
+                {
+                    ++oobErrorCount[l];
+                }
+            }
+
+        }
+    }
+
+    /** Does the normalisation
+     */
+    template<class RF, class PR>
+    void visit_at_end(RF & rf, PR & pr)
+    {
+        // do some normalisation
+        for(int l=0; l < (int)rf.ext_param_.row_count_; ++l)
+        {
+            if(oobCount[l])
+            {
+                oobError += double(oobErrorCount[l]) / oobCount[l];
+                ++totalOobCount;
+            }
+        } 
+        oobError/=totalOobCount;
+    }
+    
+};
+
+/** Visitor that calculates the oob error of the ensemble
+ *  This rate should be used to estimate the crossvalidation 
+ *  error rate.
+ *  Here each sample is put down those trees, for which this sample
+ *  is OOB i.e. if sample #1 is  OOB for trees 1, 3 and 5 we calculate
+ *  the output using the ensemble consisting only of trees 1 3 and 5. 
+ *
+ *  Using normal bagged sampling each sample is OOB for approx. 33% of trees
+ *  The error rate obtained as such therefore corresponds to crossvalidation
+ *  rate obtained using a ensemble containing 33% of the trees.
+ */
+class OOB_Error : public VisitorBase
+{
+    typedef MultiArrayShape<2>::type Shp;
+    int class_count;
+    bool is_weighted;
+    MultiArray<2,double> tmp_prob;
+    public:
+
+    MultiArray<2, double>       prob_oob; 
+    /** Ensemble oob error rate
+     */
+    double                      oob_breiman;
+
+    MultiArray<2, double>       oobCount;
+    ArrayVector< int>           indices; 
+    OOB_Error() : VisitorBase(), oob_breiman(0.0) {}
+#ifdef HasHDF5
+    void save(std::string filen, std::string pathn)
+    {
+        if(*(pathn.end()-1) != '/')
+            pathn += "/";
+        const char* filename = filen.c_str();
+        MultiArray<2, double> temp(Shp(1,1), 0.0); 
+        temp[0] = oob_breiman;
+        writeHDF5(filename, (pathn + "breiman_error").c_str(), temp);
+    }
+#endif
+    // negative value if sample was ib, number indicates how often.
+    //  value >=0  if sample was oob, 0 means fail 1, correct
+
+    template<class RF, class PR>
+    void visit_at_beginning(RF & rf, PR & pr)
+    {
+        class_count = rf.class_count();
+        tmp_prob.reshape(Shp(1, class_count), 0); 
+        prob_oob.reshape(Shp(rf.ext_param().row_count_,class_count), 0);
+        is_weighted = rf.options().predict_weighted_;
+        indices.resize(rf.ext_param().row_count_);
+        if(int(oobCount.size()) != rf.ext_param_.row_count_)
+        {
+            oobCount.reshape(Shp(rf.ext_param_.row_count_, 1), 0);
+        }
+        for(int ii = 0; ii < rf.ext_param().row_count_; ++ii)
+        {
+            indices[ii] = ii;
+        }
+    }
+
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {
+        // go through the samples
+        int total_oob =0;
+        // FIXME: magic number 10000: invoke special treatment when when msample << sample_count
+        //                            (i.e. the OOB sample ist very large)
+        //                     40000: use at most 40000 OOB samples per class for OOB error estimate 
+        if(rf.ext_param_.actual_msample_ < pr.features().shape(0) - 10000)
+        {
+            ArrayVector<int> oob_indices;
+            ArrayVector<int> cts(class_count, 0);
+            std::random_shuffle(indices.begin(), indices.end());
+            for(int ii = 0; ii < rf.ext_param_.row_count_; ++ii)
+            {
+                if(!sm.is_used()[indices[ii]] && cts[pr.response()(indices[ii], 0)] < 40000)
+                {
+                    oob_indices.push_back(indices[ii]);
+                    ++cts[pr.response()(indices[ii], 0)];
+                }
+            }
+            for(unsigned int ll = 0; ll < oob_indices.size(); ++ll)
+            {
+                // update number of trees in which current sample is oob
+                ++oobCount[oob_indices[ll]];
+
+                // update number of oob samples in this tree.
+                ++total_oob; 
+                // get the predicted votes ---> tmp_prob;
+                int pos =  rf.tree(index).getToLeaf(rowVector(pr.features(),oob_indices[ll]));
+                Node<e_ConstProbNode> node ( rf.tree(index).topology_, 
+                                                    rf.tree(index).parameters_,
+                                                    pos);
+                tmp_prob.init(0); 
+                for(int ii = 0; ii < class_count; ++ii)
+                {
+                    tmp_prob[ii] = node.prob_begin()[ii];
+                }
+                if(is_weighted)
+                {
+                    for(int ii = 0; ii < class_count; ++ii)
+                        tmp_prob[ii] = tmp_prob[ii] * (*(node.prob_begin()-1));
+                }
+                rowVector(prob_oob, oob_indices[ll]) += tmp_prob;
+                
+            }
+        }else
+        {
+            for(int ll = 0; ll < rf.ext_param_.row_count_; ++ll)
+            {
+                // if the lth sample is oob...
+                if(!sm.is_used()[ll])
+                {
+                    // update number of trees in which current sample is oob
+                    ++oobCount[ll];
+
+                    // update number of oob samples in this tree.
+                    ++total_oob; 
+                    // get the predicted votes ---> tmp_prob;
+                    int pos =  rf.tree(index).getToLeaf(rowVector(pr.features(),ll));
+                    Node<e_ConstProbNode> node ( rf.tree(index).topology_, 
+                                                        rf.tree(index).parameters_,
+                                                        pos);
+                    tmp_prob.init(0); 
+                    for(int ii = 0; ii < class_count; ++ii)
+                    {
+                        tmp_prob[ii] = node.prob_begin()[ii];
+                    }
+                    if(is_weighted)
+                    {
+                        for(int ii = 0; ii < class_count; ++ii)
+                            tmp_prob[ii] = tmp_prob[ii] * (*(node.prob_begin()-1));
+                    }
+                    rowVector(prob_oob, ll) += tmp_prob;
+                }
+            }
+        }
+        // go through the ib samples; 
+    }
+
+    /** Normalise variable importance after the number of trees is known.
+     */
+    template<class RF, class PR>
+    void visit_at_end(RF & rf, PR & pr)
+    {
+        // ullis original metric and breiman style stuff
+        int totalOobCount =0;
+        int breimanstyle = 0;
+        for(int ll=0; ll < (int)rf.ext_param_.row_count_; ++ll)
+        {
+            if(oobCount[ll])
+            {
+                if(argMax(rowVector(prob_oob, ll)) != pr.response()(ll, 0))
+                   ++breimanstyle;
+                ++totalOobCount;
+            }
+        }
+        oob_breiman = double(breimanstyle)/totalOobCount; 
+    }
+};
+
+
+/** Visitor that calculates different OOB error statistics
+ */
+class CompleteOOBInfo : public VisitorBase
+{
+    typedef MultiArrayShape<2>::type Shp;
+    int class_count;
+    bool is_weighted;
+    MultiArray<2,double> tmp_prob;
+    public:
+
+    /** OOB Error rate of each individual tree
+     */
+    MultiArray<2, double>       oob_per_tree;
+    /** Mean of oob_per_tree
+     */
+    double                      oob_mean;
+    /**Standard deviation of oob_per_tree
+     */
+    double                      oob_std;
+    
+    MultiArray<2, double>       prob_oob; 
+    /** Ensemble OOB error
+     *
+     * \sa OOB_Error
+     */
+    double                      oob_breiman;
+
+    MultiArray<2, double>       oobCount;
+    MultiArray<2, double>       oobErrorCount;
+    /** Per Tree OOB error calculated as in OOB_PerTreeError
+     * (Ulli's version)
+     */
+    double                      oob_per_tree2;
+
+    /**Column containing the development of the Ensemble
+     * error rate with increasing number of trees
+     */
+    MultiArray<2, double>       breiman_per_tree;
+    /** 4 dimensional array containing the development of confusion matrices 
+     * with number of trees - can be used to estimate ROC curves etc.
+     *
+     * oobroc_per_tree(ii,jj,kk,ll) 
+     * corresponds true label = ii 
+     * predicted label = jj
+     * confusion matrix after ll trees
+     *
+     * explanation of third index:
+     *
+     * Two class case:
+     * kk = 0 - (treeCount-1)
+     *         Threshold is on Probability for class 0  is kk/(treeCount-1);
+     * More classes:
+     * kk = 0. Threshold on probability set by argMax of the probability array.
+     */
+    MultiArray<4, double>       oobroc_per_tree;
+    
+    CompleteOOBInfo() : VisitorBase(), oob_mean(0), oob_std(0), oob_per_tree2(0)  {}
+
+#ifdef HasHDF5
+    /** save to HDF5 file
+     */
+    void save(std::string filen, std::string pathn)
+    {
+        if(*(pathn.end()-1) != '/')
+            pathn += "/";
+        const char* filename = filen.c_str();
+        MultiArray<2, double> temp(Shp(1,1), 0.0); 
+        writeHDF5(filename, (pathn + "oob_per_tree").c_str(), oob_per_tree);
+        writeHDF5(filename, (pathn + "oobroc_per_tree").c_str(), oobroc_per_tree);
+        writeHDF5(filename, (pathn + "breiman_per_tree").c_str(), breiman_per_tree);
+        temp[0] = oob_mean;
+        writeHDF5(filename, (pathn + "per_tree_error").c_str(), temp);
+        temp[0] = oob_std;
+        writeHDF5(filename, (pathn + "per_tree_error_std").c_str(), temp);
+        temp[0] = oob_breiman;
+        writeHDF5(filename, (pathn + "breiman_error").c_str(), temp);
+        temp[0] = oob_per_tree2;
+        writeHDF5(filename, (pathn + "ulli_error").c_str(), temp);
+    }
+#endif
+    // negative value if sample was ib, number indicates how often.
+    //  value >=0  if sample was oob, 0 means fail 1, correct
+
+    template<class RF, class PR>
+    void visit_at_beginning(RF & rf, PR & pr)
+    {
+        class_count = rf.class_count();
+        if(class_count == 2)
+            oobroc_per_tree.reshape(MultiArrayShape<4>::type(2,2,rf.tree_count(), rf.tree_count()));
+        else
+            oobroc_per_tree.reshape(MultiArrayShape<4>::type(rf.class_count(),rf.class_count(),1, rf.tree_count()));
+        tmp_prob.reshape(Shp(1, class_count), 0); 
+        prob_oob.reshape(Shp(rf.ext_param().row_count_,class_count), 0);
+        is_weighted = rf.options().predict_weighted_;
+        oob_per_tree.reshape(Shp(1, rf.tree_count()), 0);
+        breiman_per_tree.reshape(Shp(1, rf.tree_count()), 0);
+        //do the first time called.
+        if(int(oobCount.size()) != rf.ext_param_.row_count_)
+        {
+            oobCount.reshape(Shp(rf.ext_param_.row_count_, 1), 0);
+            oobErrorCount.reshape(Shp(rf.ext_param_.row_count_,1), 0);
+        }
+    }
+
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {
+        // go through the samples
+        int total_oob =0;
+        int wrong_oob =0;
+        for(int ll = 0; ll < rf.ext_param_.row_count_; ++ll)
+        {
+            // if the lth sample is oob...
+            if(!sm.is_used()[ll])
+            {
+                // update number of trees in which current sample is oob
+                ++oobCount[ll];
+
+                // update number of oob samples in this tree.
+                ++total_oob; 
+                // get the predicted votes ---> tmp_prob;
+                int pos =  rf.tree(index).getToLeaf(rowVector(pr.features(),ll));
+                Node<e_ConstProbNode> node ( rf.tree(index).topology_, 
+                                                    rf.tree(index).parameters_,
+                                                    pos);
+                tmp_prob.init(0); 
+                for(int ii = 0; ii < class_count; ++ii)
+                {
+                    tmp_prob[ii] = node.prob_begin()[ii];
+                }
+                if(is_weighted)
+                {
+                    for(int ii = 0; ii < class_count; ++ii)
+                        tmp_prob[ii] = tmp_prob[ii] * (*(node.prob_begin()-1));
+                }
+                rowVector(prob_oob, ll) += tmp_prob;
+                int label = argMax(tmp_prob); 
+                
+                if(label != pr.response()(ll, 0))
+                {
+                    // update number of wrong oob samples in this tree.
+                    ++wrong_oob;
+                    // update number of trees in which current sample is wrong oob
+                    ++oobErrorCount[ll];
+                }
+            }
+        }
+        int breimanstyle = 0;
+        int totalOobCount = 0;
+        for(int ll=0; ll < (int)rf.ext_param_.row_count_; ++ll)
+        {
+            if(oobCount[ll])
+            {
+                if(argMax(rowVector(prob_oob, ll)) != pr.response()(ll, 0))
+                   ++breimanstyle;
+                ++totalOobCount;
+                if(oobroc_per_tree.shape(2) == 1)
+                {
+                    oobroc_per_tree(pr.response()(ll,0), argMax(rowVector(prob_oob, ll)),0 ,index)++;
+                }
+            }
+        }
+        if(oobroc_per_tree.shape(2) == 1)
+            oobroc_per_tree.bindOuter(index)/=totalOobCount;
+        if(oobroc_per_tree.shape(2) > 1)
+        {
+            MultiArrayView<3, double> current_roc 
+                    = oobroc_per_tree.bindOuter(index);
+            for(int gg = 0; gg < current_roc.shape(2); ++gg)
+            {
+                for(int ll=0; ll < (int)rf.ext_param_.row_count_; ++ll)
+                {
+                    if(oobCount[ll])
+                    {
+                        int pred = prob_oob(ll, 1) > (double(gg)/double(current_roc.shape(2)))?
+                                        1 : 0; 
+                        current_roc(pr.response()(ll, 0), pred, gg)+= 1; 
+                    }
+                }
+                current_roc.bindOuter(gg)/= totalOobCount;
+            }
+        }
+        breiman_per_tree[index] = double(breimanstyle)/double(totalOobCount);
+        oob_per_tree[index] = double(wrong_oob)/double(total_oob);
+        // go through the ib samples; 
+    }
+
+    /** Normalise variable importance after the number of trees is known.
+     */
+    template<class RF, class PR>
+    void visit_at_end(RF & rf, PR & pr)
+    {
+        // ullis original metric and breiman style stuff
+        oob_per_tree2 = 0; 
+        int totalOobCount =0;
+        int breimanstyle = 0;
+        for(int ll=0; ll < (int)rf.ext_param_.row_count_; ++ll)
+        {
+            if(oobCount[ll])
+            {
+                if(argMax(rowVector(prob_oob, ll)) != pr.response()(ll, 0))
+                   ++breimanstyle;
+                oob_per_tree2 += double(oobErrorCount[ll]) / oobCount[ll];
+                ++totalOobCount;
+            }
+        }
+        oob_per_tree2 /= totalOobCount; 
+        oob_breiman = double(breimanstyle)/totalOobCount; 
+        // mean error of each tree
+        MultiArrayView<2, double> mean(Shp(1,1), &oob_mean);
+        MultiArrayView<2, double> stdDev(Shp(1,1), &oob_std);
+        rowStatistics(oob_per_tree, mean, stdDev);
+    }
+};
+
+/** calculate variable importance while learning.
+ */
+class VariableImportanceVisitor : public VisitorBase
+{
+    public:
+
+    /** This Array has the same entries as the R - random forest variable
+     *  importance.
+     *  Matrix is   featureCount by (classCount +2)
+     *  variable_importance_(ii,jj) is the variable importance measure of 
+     *  the ii-th variable according to:
+     *  jj = 0 - (classCount-1)
+     *      classwise permutation importance 
+     *  jj = rowCount(variable_importance_) -2
+     *      permutation importance
+     *  jj = rowCount(variable_importance_) -1
+     *      gini decrease importance.
+     *
+     *  permutation importance:
+     *  The difference between the fraction of OOB samples classified correctly
+     *  before and after permuting (randomizing) the ii-th column is calculated.
+     *  The ii-th column is permuted rep_cnt times.
+     *
+     *  class wise permutation importance:
+     *  same as permutation importance. We only look at those OOB samples whose 
+     *  response corresponds to class jj.
+     *
+     *  gini decrease importance:
+     *  row ii corresponds to the sum of all gini decreases induced by variable ii 
+     *  in each node of the random forest.
+     */
+    MultiArray<2, double>       variable_importance_;
+    int                         repetition_count_;
+    bool                        in_place_;
+
+#ifdef HasHDF5
+    void save(std::string filename, std::string prefix)
+    {
+        prefix = "variable_importance_" + prefix;
+        writeHDF5(filename.c_str(), 
+                        prefix.c_str(), 
+                        variable_importance_);
+    }
+#endif
+
+    /* Constructor
+     * \param rep_cnt (defautl: 10) how often should 
+     * the permutation take place. Set to 1 to make calculation faster (but
+     * possibly more instable)
+     */
+    VariableImportanceVisitor(int rep_cnt = 10) 
+    :   repetition_count_(rep_cnt)
+
+    {}
+
+    /** calculates impurity decrease based variable importance after every
+     * split.  
+     */
+    template<class Tree, class Split, class Region, class Feature_t, class Label_t>
+    void visit_after_split( Tree          & tree, 
+                            Split         & split,
+                            Region        & parent,
+                            Region        & leftChild,
+                            Region        & rightChild,
+                            Feature_t     & features,
+                            Label_t       & labels)
+    {
+        //resize to right size when called the first time
+        
+        Int32 const  class_count = tree.ext_param_.class_count_;
+        Int32 const  column_count = tree.ext_param_.column_count_;
+        if(variable_importance_.size() == 0)
+        {
+            
+            variable_importance_
+                .reshape(MultiArrayShape<2>::type(column_count, 
+                                                 class_count+2));
+        }
+
+        if(split.createNode().typeID() == i_ThresholdNode)
+        {
+            Node<i_ThresholdNode> node(split.createNode());
+            variable_importance_(node.column(),class_count+1) 
+                += split.region_gini_ - split.minGini();
+        }
+    }
+
+    /**compute permutation based var imp. 
+     * (Only an Array of size oob_sample_count x 1 is created.
+     *  - apposed to oob_sample_count x feature_count in the other method.
+     * 
+     * \sa FieldProxy
+     */
+    template<class RF, class PR, class SM, class ST>
+    void after_tree_ip_impl(RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {
+        typedef MultiArrayShape<2>::type Shp_t;
+        Int32                   column_count = rf.ext_param_.column_count_;
+        Int32                   class_count  = rf.ext_param_.class_count_;  
+        
+        /* This solution saves memory uptake but not multithreading
+         * compatible
+         */
+        // remove the const cast on the features (yep , I know what I am 
+        // doing here.) data is not destroyed.
+        //typename PR::Feature_t & features 
+        //    = const_cast<typename PR::Feature_t &>(pr.features());
+
+        typedef typename PR::FeatureWithMemory_t FeatureArray;
+        typedef typename FeatureArray::value_type FeatureValue;
+
+        FeatureArray features = pr.features();
+
+        //find the oob indices of current tree. 
+        ArrayVector<Int32>      oob_indices;
+        ArrayVector<Int32>::iterator
+                                iter;
+        for(int ii = 0; ii < rf.ext_param_.row_count_; ++ii)
+            if(!sm.is_used()[ii])
+                oob_indices.push_back(ii);
+
+        //create space to back up a column      
+        ArrayVector<FeatureValue>     backup_column;
+
+        // Random foo
+#ifdef CLASSIFIER_TEST
+        RandomMT19937           random(1);
+#else 
+        RandomMT19937           random(RandomSeed);
+#endif
+        UniformIntRandomFunctor<RandomMT19937>  
+                                randint(random);
+
+
+        //make some space for the results
+        MultiArray<2, double>
+                    oob_right(Shp_t(1, class_count + 1)); 
+        MultiArray<2, double>
+                    perm_oob_right (Shp_t(1, class_count + 1)); 
+            
+        
+        // get the oob success rate with the original samples
+        for(iter = oob_indices.begin(); 
+            iter != oob_indices.end(); 
+            ++iter)
+        {
+            if(rf.tree(index)
+                    .predictLabel(rowVector(features, *iter)) 
+                ==  pr.response()(*iter, 0))
+            {
+                //per class
+                ++oob_right[pr.response()(*iter,0)];
+                //total
+                ++oob_right[class_count];
+            }
+        }
+        //get the oob rate after permuting the ii'th dimension.
+        for(int ii = 0; ii < column_count; ++ii)
+        {
+            perm_oob_right.init(0.0); 
+            //make backup of original column
+            backup_column.clear();
+            for(iter = oob_indices.begin(); 
+                iter != oob_indices.end(); 
+                ++iter)
+            {
+                backup_column.push_back(features(*iter,ii));
+            }
+            
+            //get the oob rate after permuting the ii'th dimension.
+            for(int rr = 0; rr < repetition_count_; ++rr)
+            {               
+                //permute dimension. 
+                int n = oob_indices.size();
+                for(int jj = 1; jj < n; ++jj)
+                    std::swap(features(oob_indices[jj], ii), 
+                              features(oob_indices[randint(jj+1)], ii));
+
+                //get the oob success rate after permuting
+                for(iter = oob_indices.begin(); 
+                    iter != oob_indices.end(); 
+                    ++iter)
+                {
+                    if(rf.tree(index)
+                            .predictLabel(rowVector(features, *iter)) 
+                        ==  pr.response()(*iter, 0))
+                    {
+                        //per class
+                        ++perm_oob_right[pr.response()(*iter, 0)];
+                        //total
+                        ++perm_oob_right[class_count];
+                    }
+                }
+            }
+            
+            
+            //normalise and add to the variable_importance array.
+            perm_oob_right  /=  repetition_count_;
+            perm_oob_right -=oob_right;
+            perm_oob_right *= -1;
+            perm_oob_right      /=  oob_indices.size();
+            variable_importance_
+                .subarray(Shp_t(ii,0), 
+                          Shp_t(ii+1,class_count+1)) += perm_oob_right;
+            //copy back permuted dimension
+            for(int jj = 0; jj < int(oob_indices.size()); ++jj)
+                features(oob_indices[jj], ii) = backup_column[jj];
+        }
+    }
+
+    /** calculate permutation based impurity after every tree has been 
+     * learned  default behaviour is that this happens out of place.
+     * If you have very big data sets and want to avoid copying of data 
+     * set the in_place_ flag to true. 
+     */
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {
+            after_tree_ip_impl(rf, pr, sm, st, index);
+    }
+
+    /** Normalise variable importance after the number of trees is known.
+     */
+    template<class RF, class PR>
+    void visit_at_end(RF & rf, PR & pr)
+    {
+        variable_importance_ /= rf.trees_.size();
+    }
+};
+
+/** Verbose output
+ */
+class RandomForestProgressVisitor : public VisitorBase {
+    public:
+    RandomForestProgressVisitor() : VisitorBase() {}
+
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(RF& rf, PR & pr,  SM & sm, ST & st, int index){
+        if(index != rf.options().tree_count_-1) {
+            std::cout << "\r[" << std::setw(10) << (index+1)/static_cast<double>(rf.options().tree_count_)*100 << "%]"
+                      << " (" << index+1 << " of " << rf.options().tree_count_ << ") done" << std::flush;
+        }
+        else {
+            std::cout << "\r[" << std::setw(10) << 100.0 << "%]" << std::endl;
+        }
+    }
+    
+    template<class RF, class PR>
+    void visit_at_end(RF const & rf, PR const & pr) {
+        std::string a = TOCS;
+        std::cout << "all " << rf.options().tree_count_ << " trees have been learned in " << a  << std::endl;
+    }
+    
+    template<class RF, class PR>
+    void visit_at_beginning(RF const & rf, PR const & pr) {
+        TIC;
+        std::cout << "growing random forest, which will have " << rf.options().tree_count_ << " trees" << std::endl;
+    }
+    
+    private:
+    USETICTOC;
+};
+
+
+/** Computes Correlation/Similarity Matrix of features while learning
+ * random forest.
+ */
+class CorrelationVisitor : public VisitorBase
+{
+    public:
+    /** gini_missc(ii, jj) describes how well variable jj can describe a partition
+     * created on variable ii(when variable ii was chosen)
+     */ 
+    MultiArray<2, double>   gini_missc;
+    MultiArray<2, int>      tmp_labels;
+    /** additional noise features. 
+     */
+    MultiArray<2, double>   noise;
+    MultiArray<2, double>   noise_l;
+    /** how well can a noise column describe a partition created on variable ii.
+     */
+    MultiArray<2, double>   corr_noise;
+    MultiArray<2, double>   corr_l;
+
+    /** Similarity Matrix
+     * 
+     * (numberOfFeatures + 1) by (number Of Features + 1) Matrix
+     * gini_missc 
+     *  - row normalized by the number of times the column was chosen
+     *  - mean of corr_noise subtracted
+     *  - and symmetrised. 
+     *          
+     */
+    MultiArray<2, double>   similarity;
+    /** Distance Matrix 1-similarity
+     */
+    MultiArray<2, double>   distance;
+    ArrayVector<int>        tmp_cc;
+    
+    /** How often was variable ii chosen
+     */
+    ArrayVector<int>        numChoices;
+    typedef BestGiniOfColumn<GiniCriterion> ColumnDecisionFunctor;
+    BestGiniOfColumn<GiniCriterion>         bgfunc;
+    void save(std::string file, std::string prefix)
+    {
+        /*
+        std::string tmp;
+#define VAR_WRITE(NAME) \
+        tmp = #NAME;\
+        tmp += "_";\
+        tmp += prefix;\
+        vigra::writeToHDF5File(file.c_str(), tmp.c_str(), NAME);
+        VAR_WRITE(gini_missc);
+        VAR_WRITE(corr_noise);
+        VAR_WRITE(distance);
+        VAR_WRITE(similarity);
+        vigra::writeToHDF5File(file.c_str(), "nChoices", MultiArrayView<2, int>(MultiArrayShape<2>::type(numChoices.size(),1), numChoices.data()));
+#undef VAR_WRITE
+*/
+    }
+    template<class RF, class PR>
+    void visit_at_beginning(RF const & rf, PR  & pr)
+    {
+        typedef MultiArrayShape<2>::type Shp;
+        int n = rf.ext_param_.column_count_;
+        gini_missc.reshape(Shp(n +1,n+ 1));
+        corr_noise.reshape(Shp(n + 1, 10));
+        corr_l.reshape(Shp(n +1, 10));
+
+        noise.reshape(Shp(pr.features().shape(0), 10));
+        noise_l.reshape(Shp(pr.features().shape(0), 10));
+        RandomMT19937 random(RandomSeed);
+        for(int ii = 0; ii < noise.size(); ++ii)
+        {
+            noise[ii]   = random.uniform53();
+            noise_l[ii] = random.uniform53()  > 0.5;
+        }
+        bgfunc = ColumnDecisionFunctor( rf.ext_param_);
+        tmp_labels.reshape(pr.response().shape()); 
+        tmp_cc.resize(2);
+        numChoices.resize(n+1);
+        // look at all axes
+    }
+    template<class RF, class PR>
+    void visit_at_end(RF const & rf, PR const & pr)
+    {
+        typedef MultiArrayShape<2>::type Shp;
+        similarity.reshape(gini_missc.shape());
+        similarity = gini_missc;;
+        MultiArray<2, double> mean_noise(Shp(corr_noise.shape(0), 1));
+        rowStatistics(corr_noise, mean_noise);
+        mean_noise/= MultiArrayView<2, int>(mean_noise.shape(), numChoices.data());        
+        int rC = similarity.shape(0);
+        for(int jj = 0; jj < rC-1; ++jj)
+        {
+            rowVector(similarity, jj) /= numChoices[jj];
+            rowVector(similarity, jj) -= mean_noise(jj, 0);
+        }
+        for(int jj = 0; jj < rC; ++jj)
+        {
+            similarity(rC -1, jj) /= numChoices[jj];
+        }
+        rowVector(similarity, rC -  1) -= mean_noise(rC-1, 0);
+        similarity = abs(similarity);
+        FindMinMax<double> minmax;
+        inspectMultiArray(srcMultiArrayRange(similarity), minmax);
+        
+        for(int jj = 0; jj < rC; ++jj)
+            similarity(jj, jj) = minmax.max;
+        
+        similarity.subarray(Shp(0,0), Shp(rC-1, rC-1)) 
+            += similarity.subarray(Shp(0,0), Shp(rC-1, rC-1)).transpose();
+        similarity.subarray(Shp(0,0), Shp(rC-1, rC-1))/= 2;  
+        columnVector(similarity, rC-1) = rowVector(similarity, rC-1).transpose();
+        for(int jj = 0; jj < rC; ++jj)
+            similarity(jj, jj) = 0;
+        
+        FindMinMax<double> minmax2;
+        inspectMultiArray(srcMultiArrayRange(similarity), minmax2);
+        for(int jj = 0; jj < rC; ++jj)
+            similarity(jj, jj) = minmax2.max;
+        distance.reshape(gini_missc.shape(), minmax2.max);
+        distance -= similarity; 
+    }
+
+    template<class Tree, class Split, class Region, class Feature_t, class Label_t>
+    void visit_after_split( Tree          & tree, 
+                            Split         & split,
+                            Region        & parent,
+                            Region        & leftChild,
+                            Region        & rightChild,
+                            Feature_t     & features,
+                            Label_t       & labels)
+    {
+        if(split.createNode().typeID() == i_ThresholdNode)
+        {
+            double wgini;
+            tmp_cc.init(0); 
+            for(int ii = 0; ii < parent.size(); ++ii)
+            {
+                tmp_labels[parent[ii]] 
+                    = (features(parent[ii], split.bestSplitColumn()) < split.bestSplitThreshold());
+                ++tmp_cc[tmp_labels[parent[ii]]];
+            }
+            double region_gini = bgfunc.loss_of_region(tmp_labels, 
+                                                       parent.begin(),
+                                                       parent.end(),
+                                                       tmp_cc);
+
+            int n = split.bestSplitColumn(); 
+            ++numChoices[n];
+            ++(*(numChoices.end()-1));
+            //this functor does all the work
+            for(int k = 0; k < features.shape(1); ++k)
+            {
+                bgfunc(columnVector(features, k),
+                       tmp_labels, 
+                       parent.begin(), parent.end(), 
+                       tmp_cc);
+                wgini = (region_gini - bgfunc.min_gini_);
+                gini_missc(n, k) 
+                    += wgini;
+            }
+            for(int k = 0; k < 10; ++k)
+            {
+                bgfunc(columnVector(noise, k),
+                       tmp_labels, 
+                       parent.begin(), parent.end(), 
+                       tmp_cc);
+                wgini = (region_gini - bgfunc.min_gini_);
+                corr_noise(n, k) 
+                    += wgini;
+            }
+            
+            for(int k = 0; k < 10; ++k)
+            {
+                bgfunc(columnVector(noise_l, k),
+                       tmp_labels, 
+                       parent.begin(), parent.end(), 
+                       tmp_cc);
+                wgini = (region_gini - bgfunc.min_gini_);
+                corr_l(n, k) 
+                    += wgini;
+            }
+            bgfunc(labels, tmp_labels, parent.begin(), parent.end(),tmp_cc);
+            wgini = (region_gini - bgfunc.min_gini_);
+            gini_missc(n, columnCount(gini_missc)-1) 
+                += wgini;
+            
+            region_gini = split.region_gini_;
+#if 1 
+            Node<i_ThresholdNode> node(split.createNode());
+            gini_missc(rowCount(gini_missc)-1, 
+                                  node.column()) 
+                 +=split.region_gini_ - split.minGini();
+#endif
+            for(int k = 0; k < 10; ++k)
+            {
+                split.bgfunc(columnVector(noise, k),
+                             labels, 
+                             parent.begin(), parent.end(), 
+                             parent.classCounts());
+                corr_noise(rowCount(gini_missc)-1, 
+                           k) 
+                     += wgini;
+            }
+#if 0
+            for(int k = 0; k < tree.ext_param_.actual_mtry_; ++k)
+            {
+                wgini = region_gini - split.min_gini_[k];
+                
+                gini_missc(rowCount(gini_missc)-1, 
+                                      split.splitColumns[k]) 
+                     += wgini;
+            }
+            
+            for(int k=tree.ext_param_.actual_mtry_; k<features.shape(1); ++k)
+            {
+                split.bgfunc(columnVector(features, split.splitColumns[k]),
+                             labels, 
+                             parent.begin(), parent.end(), 
+                             parent.classCounts());
+                wgini = region_gini - split.bgfunc.min_gini_;
+                gini_missc(rowCount(gini_missc)-1, 
+                                      split.splitColumns[k]) += wgini;
+            }
+#endif
+            // remember to partition the data according to the best.
+                gini_missc(rowCount(gini_missc)-1, 
+                           columnCount(gini_missc)-1) 
+                     += region_gini;
+                SortSamplesByDimensions<Feature_t> 
+                sorter(features, split.bestSplitColumn(), split.bestSplitThreshold());
+            std::partition(parent.begin(), parent.end(), sorter);
+        }
+    }
+};
+
+
+} // namespace visitors
+} // namespace rf
+} // namespace vigra
+
+//@}
+#endif // RF_VISITORS_HXX
diff --git a/include/vigra/random_forest/splices.hxx b/include/vigra/random_forest/splices.hxx
new file mode 100755
index 0000000..bf3151c
--- /dev/null
+++ b/include/vigra/random_forest/splices.hxx
@@ -0,0 +1,140 @@
+#ifndef SPLICES_HXX
+#define SPLICES_HXX
+#include <vigra/multi_array.hxx>
+#include <iterator>
+
+namespace vigra
+{
+/** Idea for a class to use for easy splicing
+ *
+ * usage (with factory function _spl)
+ *
+ * // copy every even indexed element to a 5 x 5 
+ * // sized matrix
+ * Matrix<double> a(10, 10)
+ * MultiArrayView<2,double> b(_spl_shp(_spl(0,2,10),
+ *                                     _spl(0,2,10)));
+ * copy_splice(_spl(0,2,10),_spl(0,2,10), a, b);
+ * 
+ * it is also possible to supply iterator ranges
+ * std::vector<int> indices;
+ * indices.push_back(3) (...)
+ * 
+ * copy_splice(_spl(indices.begin(), indices.end()),
+ *             _spl(a.shape(1)),
+ *             a, b)
+ *
+ * if you only have a forward iterator then you must
+ * specify the size of the splice with 
+ * _spl(set.begin(), set.end(), set.size());
+ *
+ * ok.. what we actually need is a decent iota iterator
+ * or something like xrange but for now it should suffice.
+ */
+template<class T>
+class Splice
+{
+    int size_;
+    T begin_;
+    T end_;
+public:
+    Splice(T  &begin, T &end)
+        : size_(std::distance(begin, end)),
+          begin_(begin),
+          end_(end)
+    {}
+
+    int operator[](int index)
+    {
+        T ii = begin_;
+        std::advance(ii, index);
+        return *ii;
+    }
+
+    int size()
+    {
+        return size_;
+    }
+};
+
+template<>
+class Splice<int>
+{
+    int begin_;
+    int interval_;
+    int end_;
+    int size_;
+    public:
+    Splice(int begin, int end)
+    : begin_(begin), 
+      interval_(1),
+      end_(end),
+      size_(end - begin)
+    {}
+
+    Splice(int begin, int interval, int end) 
+    : begin_(begin), 
+      interval_(interval),
+      end_(end),
+      size_(int(std::floor((double(end) -double(begin))/interval)))
+    {}
+    
+    int operator[](int index)
+    {
+        int ii = begin_ + index * interval_;
+        return ii;
+    }
+
+    int size()
+    {
+        return size_;
+    }
+};
+
+template<class T>
+Splice<T> _spl(T b, T e)
+{
+    return Splice<T>(b, e);
+}
+template<class T>
+Splice<T> _spl(T b, int size, T e)
+{
+    return Splice<T>(b, size, e);
+}
+
+inline Splice<int> _spl(int size)
+{
+    return Splice<int>(0, size);
+}
+
+
+
+template<class T, class G>
+inline MultiArrayShape<2>::type _spl_shp(Splice<T> f,
+                                                  Splice<G> h)
+{
+    return MultiArrayShape<2>::type(f.size(), h.size());
+}
+
+
+
+
+template<   class R, class F, 
+            class T, class C,
+            class T2, class C2 >
+void copy_splice(  Splice<R> _first,
+                   Splice<F> _second,
+                   MultiArrayView<2, T, C>  src,
+                   MultiArrayView<2, T2, C2> dest)
+{
+    for(int jj = 0 ; jj < _second.size(); ++jj)
+    {
+        for(int ii = 0 ; ii < _first.size(); ++ii)
+        {
+            dest(ii, jj) = src(_first[ii], _second[jj]);
+        }
+    }
+}
+
+};
+#endif //SPLICES_HXX
diff --git a/include/vigra/random_forest_deprec.hxx b/include/vigra/random_forest_deprec.hxx
new file mode 100644
index 0000000..dd3f68d
--- /dev/null
+++ b/include/vigra/random_forest_deprec.hxx
@@ -0,0 +1,1142 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 2008 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_RANDOM_FOREST_DEPREC_HXX
+#define VIGRA_RANDOM_FOREST_DEPREC_HXX
+
+#include <algorithm>
+#include <map>
+#include <numeric>
+#include <iostream>
+#include <ctime>
+#include <cstdlib>
+#include "vigra/mathutil.hxx"
+#include "vigra/array_vector.hxx"
+#include "vigra/sized_int.hxx"
+#include "vigra/matrix.hxx"
+#include "vigra/random.hxx"
+#include "vigra/functorexpression.hxx"
+
+
+namespace vigra
+{
+
+/** \addtogroup MachineLearning 
+**/
+//@{
+
+namespace detail
+{
+
+template<class DataMatrix>
+class RandomForestDeprecFeatureSorter
+{
+    DataMatrix const & data_;
+    MultiArrayIndex sortColumn_;
+
+  public:
+
+    RandomForestDeprecFeatureSorter(DataMatrix const & data, MultiArrayIndex sortColumn)
+    : data_(data),
+      sortColumn_(sortColumn)
+    {}
+
+    void setColumn(MultiArrayIndex sortColumn)
+    {
+        sortColumn_ = sortColumn;
+    }
+
+    bool operator()(MultiArrayIndex l, MultiArrayIndex r) const
+    {
+        return data_(l, sortColumn_) < data_(r, sortColumn_);
+    }
+};
+
+template<class LabelArray>
+class RandomForestDeprecLabelSorter
+{
+    LabelArray const & labels_;
+
+  public:
+
+    RandomForestDeprecLabelSorter(LabelArray const & labels)
+    : labels_(labels)
+    {}
+
+    bool operator()(MultiArrayIndex l, MultiArrayIndex r) const
+    {
+        return labels_[l] < labels_[r];
+    }
+};
+
+template <class CountArray>
+class RandomForestDeprecClassCounter
+{
+    ArrayVector<int> const & labels_;
+    CountArray & counts_;
+
+  public:
+
+    RandomForestDeprecClassCounter(ArrayVector<int> const & labels, CountArray & counts)
+    : labels_(labels),
+      counts_(counts)
+    {
+        reset();
+    }
+
+    void reset()
+    {
+        counts_.init(0);
+    }
+
+    void operator()(MultiArrayIndex l) const
+    {
+        ++counts_[labels_[l]];
+    }
+};
+
+struct DecisionTreeDeprecCountNonzeroFunctor
+{
+    double operator()(double old, double other) const
+    {
+        if(other != 0.0)
+            ++old;
+        return old;
+    }
+};
+
+struct DecisionTreeDeprecNode
+{
+    DecisionTreeDeprecNode(int t, MultiArrayIndex bestColumn)
+    : thresholdIndex(t), splitColumn(bestColumn)
+    {}
+
+    int children[2];
+    int thresholdIndex;
+    Int32 splitColumn;
+};
+
+template <class INT>
+struct DecisionTreeDeprecNodeProxy
+{
+    DecisionTreeDeprecNodeProxy(ArrayVector<INT> const & tree, INT n)
+    : node(const_cast<ArrayVector<INT> &>(tree).begin()+n)
+    {}
+
+    INT & child(INT l) const
+    {
+        return node[l];
+    }
+
+    INT & decisionWeightsIndex() const
+    {
+        return node[2];
+    }
+
+    typename ArrayVector<INT>::iterator decisionColumns() const
+    {
+        return node+3;
+    }
+
+    mutable typename ArrayVector<INT>::iterator node;
+};
+
+struct DecisionTreeDeprecAxisSplitFunctor
+{
+    ArrayVector<Int32> splitColumns;
+    ArrayVector<double> classCounts, currentCounts[2], bestCounts[2], classWeights;
+    double threshold;
+    double totalCounts[2], bestTotalCounts[2];
+    int mtry, classCount, bestSplitColumn;
+    bool pure[2], isWeighted;
+
+    void init(int mtry, int cols, int classCount, ArrayVector<double> const & weights)
+    {
+        this->mtry = mtry;
+        splitColumns.resize(cols);
+        for(int k=0; k<cols; ++k)
+            splitColumns[k] = k;
+
+        this->classCount = classCount;
+        classCounts.resize(classCount);
+        currentCounts[0].resize(classCount);
+        currentCounts[1].resize(classCount);
+        bestCounts[0].resize(classCount);
+        bestCounts[1].resize(classCount);
+
+        isWeighted = weights.size() > 0;
+        if(isWeighted)
+            classWeights = weights;
+        else
+            classWeights.resize(classCount, 1.0);
+    }
+
+    bool isPure(int k) const
+    {
+        return pure[k];
+    }
+
+    unsigned int totalCount(int k) const
+    {
+        return (unsigned int)bestTotalCounts[k];
+    }
+
+    int sizeofNode() const { return 4; }
+
+    int writeSplitParameters(ArrayVector<Int32> & tree,
+                                ArrayVector<double> &terminalWeights)
+    {
+        int currentWeightIndex = terminalWeights.size();
+        terminalWeights.push_back(threshold);
+
+        int currentNodeIndex = tree.size();
+        tree.push_back(-1);  // left child
+        tree.push_back(-1);  // right child
+        tree.push_back(currentWeightIndex);
+        tree.push_back(bestSplitColumn);
+
+        return currentNodeIndex;
+    }
+
+    void writeWeights(int l, ArrayVector<double> &terminalWeights)
+    {
+        for(int k=0; k<classCount; ++k)
+            terminalWeights.push_back(isWeighted
+                                           ? bestCounts[l][k]
+                                           : bestCounts[l][k] / totalCount(l));
+    }
+
+    template <class U, class C, class AxesIterator, class WeightIterator>
+    bool decideAtNode(MultiArrayView<2, U, C> const & features,
+                      AxesIterator a, WeightIterator w) const
+    {
+        return (features(0, *a) < *w);
+    }
+
+    template <class U, class C, class IndexIterator, class Random>
+    IndexIterator findBestSplit(MultiArrayView<2, U, C> const & features,
+                                ArrayVector<int> const & labels,
+                                IndexIterator indices, int exampleCount,
+                                Random & randint);
+
+};
+
+
+template <class U, class C, class IndexIterator, class Random>
+IndexIterator
+DecisionTreeDeprecAxisSplitFunctor::findBestSplit(MultiArrayView<2, U, C> const & features,
+                                            ArrayVector<int> const & labels,
+                                            IndexIterator indices, int exampleCount,
+                                            Random & randint)
+{
+    // select columns to be tried for split
+    for(int k=0; k<mtry; ++k)
+        std::swap(splitColumns[k], splitColumns[k+randint(columnCount(features)-k)]);
+
+    RandomForestDeprecFeatureSorter<MultiArrayView<2, U, C> > sorter(features, 0);
+    RandomForestDeprecClassCounter<ArrayVector<double> > counter(labels, classCounts);
+    std::for_each(indices, indices+exampleCount, counter);
+
+    // find the best gini index
+    double minGini = NumericTraits<double>::max();
+    IndexIterator bestSplit = indices;
+    for(int k=0; k<mtry; ++k)
+    {
+        sorter.setColumn(splitColumns[k]);
+        std::sort(indices, indices+exampleCount, sorter);
+
+        currentCounts[0].init(0);
+        std::transform(classCounts.begin(), classCounts.end(), classWeights.begin(),
+                       currentCounts[1].begin(), std::multiplies<double>());
+        totalCounts[0] = 0;
+        totalCounts[1] = std::accumulate(currentCounts[1].begin(), currentCounts[1].end(), 0.0);
+        for(int m = 0; m < exampleCount-1; ++m)
+        {
+            int label = labels[indices[m]];
+            double w = classWeights[label];
+            currentCounts[0][label] += w;
+            totalCounts[0] += w;
+            currentCounts[1][label] -= w;
+            totalCounts[1] -= w;
+
+            if (m < exampleCount-2 &&
+                features(indices[m], splitColumns[k]) == features(indices[m+1], splitColumns[k]))
+                continue ;
+
+            double gini = 0.0;
+            if(classCount == 2)
+            {
+                gini = currentCounts[0][0]*currentCounts[0][1] / totalCounts[0] +
+                       currentCounts[1][0]*currentCounts[1][1] / totalCounts[1];
+            }
+            else
+            {
+                for(int l=0; l<classCount; ++l)
+                    gini += currentCounts[0][l]*(1.0 - currentCounts[0][l] / totalCounts[0]) +
+                            currentCounts[1][l]*(1.0 - currentCounts[1][l] / totalCounts[1]);
+            }
+            if(gini < minGini)
+            {
+                minGini = gini;
+                bestSplit = indices+m;
+                bestSplitColumn = splitColumns[k];
+                bestCounts[0] = currentCounts[0];
+                bestCounts[1] = currentCounts[1];
+            }
+        }
+
+
+
+    }
+        //std::cerr << minGini << " " << bestSplitColumn << std::endl;
+    // split using the best feature
+    sorter.setColumn(bestSplitColumn);
+    std::sort(indices, indices+exampleCount, sorter);
+
+    for(int k=0; k<2; ++k)
+    {
+        bestTotalCounts[k] = std::accumulate(bestCounts[k].begin(), bestCounts[k].end(), 0.0);
+    }
+
+    threshold = (features(bestSplit[0], bestSplitColumn) + features(bestSplit[1], bestSplitColumn)) / 2.0;
+    ++bestSplit;
+
+    counter.reset();
+    std::for_each(indices, bestSplit, counter);
+    pure[0] = 1.0 == std::accumulate(classCounts.begin(), classCounts.end(), 0.0, DecisionTreeDeprecCountNonzeroFunctor());
+    counter.reset();
+    std::for_each(bestSplit, indices+exampleCount, counter);
+    pure[1] = 1.0 == std::accumulate(classCounts.begin(), classCounts.end(), 0.0, DecisionTreeDeprecCountNonzeroFunctor());
+
+    return bestSplit;
+}
+
+enum  { DecisionTreeDeprecNoParent = -1 };
+
+template <class Iterator>
+struct DecisionTreeDeprecStackEntry
+{
+    DecisionTreeDeprecStackEntry(Iterator i, int c,
+                           int lp = DecisionTreeDeprecNoParent, int rp = DecisionTreeDeprecNoParent)
+    : indices(i), exampleCount(c),
+      leftParent(lp), rightParent(rp)
+    {}
+
+    Iterator indices;
+    int exampleCount, leftParent, rightParent;
+};
+
+class DecisionTreeDeprec
+{
+  public:
+    typedef Int32 TreeInt;
+    ArrayVector<TreeInt>  tree_;
+    ArrayVector<double> terminalWeights_;
+    unsigned int classCount_;
+    DecisionTreeDeprecAxisSplitFunctor split;
+
+  public:
+
+
+    DecisionTreeDeprec(unsigned int classCount)
+    : classCount_(classCount)
+    {}
+
+    void reset(unsigned int classCount = 0)
+    {
+        if(classCount)
+            classCount_ = classCount;
+        tree_.clear();
+        terminalWeights_.clear();
+    }
+
+    template <class U, class C, class Iterator, class Options, class Random>
+    void learn(MultiArrayView<2, U, C> const & features,
+               ArrayVector<int> const & labels,
+               Iterator indices, int exampleCount,
+               Options const & options,
+               Random & randint);
+
+    template <class U, class C>
+    ArrayVector<double>::const_iterator
+    predict(MultiArrayView<2, U, C> const & features) const
+    {
+        int nodeindex = 0;
+        for(;;)
+        {
+            DecisionTreeDeprecNodeProxy<TreeInt> node(tree_, nodeindex);
+            nodeindex = split.decideAtNode(features, node.decisionColumns(),
+                                       terminalWeights_.begin() + node.decisionWeightsIndex())
+                                ? node.child(0)
+                                : node.child(1);
+            if(nodeindex <= 0)
+                return terminalWeights_.begin() + (-nodeindex);
+        }
+    }
+
+    template <class U, class C>
+    int
+    predictLabel(MultiArrayView<2, U, C> const & features) const
+    {
+        ArrayVector<double>::const_iterator weights = predict(features);
+        return argMax(weights, weights+classCount_) - weights;
+    }
+
+    template <class U, class C>
+    int
+    leafID(MultiArrayView<2, U, C> const & features) const
+    {
+        int nodeindex = 0;
+        for(;;)
+        {
+            DecisionTreeDeprecNodeProxy<TreeInt> node(tree_, nodeindex);
+            nodeindex = split.decideAtNode(features, node.decisionColumns(),
+                                       terminalWeights_.begin() + node.decisionWeightsIndex())
+                                ? node.child(0)
+                                : node.child(1);
+            if(nodeindex <= 0)
+                return -nodeindex;
+        }
+    }
+
+    void depth(int & maxDep, int & interiorCount, int & leafCount, int k = 0, int d = 1) const
+    {
+        DecisionTreeDeprecNodeProxy<TreeInt> node(tree_, k);
+        ++interiorCount;
+        ++d;
+        for(int l=0; l<2; ++l)
+        {
+            int child = node.child(l);
+            if(child > 0)
+                depth(maxDep, interiorCount, leafCount, child, d);
+            else
+            {
+                ++leafCount;
+                if(maxDep < d)
+                    maxDep = d;
+            }
+        }
+    }
+
+    void printStatistics(std::ostream & o) const
+    {
+        int maxDep = 0, interiorCount = 0, leafCount = 0;
+        depth(maxDep, interiorCount, leafCount);
+
+        o << "interior nodes: " << interiorCount <<
+             ", terminal nodes: " << leafCount <<
+             ", depth: " << maxDep << "\n";
+    }
+
+    void print(std::ostream & o, int k = 0, std::string s = "") const
+    {
+        DecisionTreeDeprecNodeProxy<TreeInt> node(tree_, k);
+        o << s << (*node.decisionColumns()) << " " << terminalWeights_[node.decisionWeightsIndex()] << "\n";
+
+        for(int l=0; l<2; ++l)
+        {
+            int child = node.child(l);
+            if(child <= 0)
+                o << s << " weights " << terminalWeights_[-child] << " "
+                                      << terminalWeights_[-child+1] << "\n";
+            else
+                print(o, child, s+" ");
+        }
+    }
+};
+
+
+template <class U, class C, class Iterator, class Options, class Random>
+void DecisionTreeDeprec::learn(MultiArrayView<2, U, C> const & features,
+                          ArrayVector<int> const & labels,
+                          Iterator indices, int exampleCount,
+                          Options const & options,
+                          Random & randint)
+{
+    ArrayVector<double> const & classLoss = options.class_weights;
+
+    vigra_precondition(classLoss.size() == 0 || classLoss.size() == classCount_,
+        "DecisionTreeDeprec2::learn(): class weights array has wrong size.");
+
+    reset();
+
+    unsigned int mtry = options.mtry;
+    MultiArrayIndex cols = columnCount(features);
+
+    split.init(mtry, cols, classCount_, classLoss);
+
+    typedef DecisionTreeDeprecStackEntry<Iterator> Entry;
+    ArrayVector<Entry> stack;
+    stack.push_back(Entry(indices, exampleCount));
+
+    while(!stack.empty())
+    {
+//        std::cerr << "*";
+        indices = stack.back().indices;
+        exampleCount = stack.back().exampleCount;
+        int leftParent  = stack.back().leftParent,
+            rightParent = stack.back().rightParent;
+
+        stack.pop_back();
+
+        Iterator bestSplit = split.findBestSplit(features, labels, indices, exampleCount, randint);
+
+
+        int currentNode = split.writeSplitParameters(tree_, terminalWeights_);
+
+        if(leftParent != DecisionTreeDeprecNoParent)
+            DecisionTreeDeprecNodeProxy<TreeInt>(tree_, leftParent).child(0) = currentNode;
+        if(rightParent != DecisionTreeDeprecNoParent)
+            DecisionTreeDeprecNodeProxy<TreeInt>(tree_, rightParent).child(1) = currentNode;
+        leftParent = currentNode;
+        rightParent = DecisionTreeDeprecNoParent;
+
+        for(int l=0; l<2; ++l)
+        {
+
+            if(!split.isPure(l) && split.totalCount(l) >= options.min_split_node_size)
+            {
+                // sample is still large enough and not yet perfectly separated => split
+                stack.push_back(Entry(indices, split.totalCount(l), leftParent, rightParent));
+            }
+            else
+            {
+                DecisionTreeDeprecNodeProxy<TreeInt>(tree_, currentNode).child(l) = -(TreeInt)terminalWeights_.size();
+
+                split.writeWeights(l, terminalWeights_);
+            }
+            std::swap(leftParent, rightParent);
+            indices = bestSplit;
+        }
+    }
+//    std::cerr << "\n";
+}
+
+} // namespace detail
+
+class RandomForestOptionsDeprec
+{
+  public:
+        /** Initialize all options with default values.
+        */
+    RandomForestOptionsDeprec()
+    : training_set_proportion(1.0),
+      mtry(0),
+      min_split_node_size(1),
+      training_set_size(0),
+      sample_with_replacement(true),
+      sample_classes_individually(false),
+      treeCount(255)
+    {}
+
+        /** Number of features considered in each node.
+
+            If \a n is 0 (the default), the number of features tried in every node
+            is determined by the square root of the total number of features.
+            According to Breiman, this quantity should always be optimized by means
+            of the out-of-bag error.<br>
+            Default: 0 (use <tt>sqrt(columnCount(featureMatrix))</tt>)
+        */
+    RandomForestOptionsDeprec & featuresPerNode(unsigned int n)
+    {
+        mtry = n;
+        return *this;
+    }
+
+        /** How to sample the subset of the training data for each tree.
+
+            Each tree is only trained with a subset of the entire training data.
+            If \a r is <tt>true</tt>, this subset is sampled from the entire training set with
+            replacement.<br>
+            Default: <tt>true</tt> (use sampling with replacement))
+        */
+    RandomForestOptionsDeprec & sampleWithReplacement(bool r)
+    {
+        sample_with_replacement = r;
+        return *this;
+    }
+
+    RandomForestOptionsDeprec & setTreeCount(unsigned int cnt)
+    {
+        treeCount = cnt;
+        return *this;
+    }
+        /** Proportion of training examples used for each tree.
+
+            If \a p is 1.0 (the default), and samples are drawn with replacement,
+            the training set of each tree will contain as many examples as the entire
+            training set, but some are drawn multiply and others not at all. On average,
+            each tree is actually trained on about 65% of the examples in the full
+            training set. Changing the proportion makes mainly sense when
+            sampleWithReplacement() is set to <tt>false</tt>. trainingSetSizeProportional() gets
+            overridden by trainingSetSizeAbsolute().<br>
+            Default: 1.0
+        */
+    RandomForestOptionsDeprec & trainingSetSizeProportional(double p)
+    {
+        vigra_precondition(p >= 0.0 && p <= 1.0,
+            "RandomForestOptionsDeprec::trainingSetSizeProportional(): proportion must be in [0, 1].");
+        if(training_set_size == 0) // otherwise, absolute size gets priority
+            training_set_proportion = p;
+        return *this;
+    }
+
+        /** Size of the training set for each tree.
+
+            If this option is set, it overrides the proportion set by
+            trainingSetSizeProportional(). When classes are sampled individually,
+            the number of examples is divided by the number of classes (rounded upwards)
+            to determine the number of examples drawn from every class.<br>
+            Default: <tt>0</tt> (determine size by proportion)
+        */
+    RandomForestOptionsDeprec & trainingSetSizeAbsolute(unsigned int s)
+    {
+        training_set_size = s;
+        if(s > 0)
+            training_set_proportion = 0.0;
+        return *this;
+    }
+
+        /** Are the classes sampled individually?
+
+            If \a s is <tt>false</tt> (the default), the training set for each tree is sampled
+            without considering class labels. Otherwise, samples are drawn from each
+            class independently. The latter is especially useful in connection
+            with the specification of an absolute training set size: then, the same number of
+            examples is drawn from every class. This can be used as a counter-measure when the
+            classes are very unbalanced in size.<br>
+            Default: <tt>false</tt>
+        */
+    RandomForestOptionsDeprec & sampleClassesIndividually(bool s)
+    {
+        sample_classes_individually = s;
+        return *this;
+    }
+
+        /** Number of examples required for a node to be split.
+
+            When the number of examples in a node is below this number, the node is not
+            split even if class separation is not yet perfect. Instead, the node returns
+            the proportion of each class (among the remaining examples) during the
+            prediction phase.<br>
+            Default: 1 (complete growing)
+        */
+    RandomForestOptionsDeprec & minSplitNodeSize(unsigned int n)
+    {
+        if(n == 0)
+            n = 1;
+        min_split_node_size = n;
+        return *this;
+    }
+
+        /** Use a weighted random forest.
+
+            This is usually used to penalize the errors for the minority class.
+            Weights must be convertible to <tt>double</tt>, and the array of weights
+            must contain as many entries as there are classes.<br>
+            Default: do not use weights
+        */
+    template <class WeightIterator>
+    RandomForestOptionsDeprec & weights(WeightIterator weights, unsigned int classCount)
+    {
+        class_weights.clear();
+        if(weights != 0)
+            class_weights.insert(weights, classCount);
+        return *this;
+    }
+
+    RandomForestOptionsDeprec & oobData(MultiArrayView<2, UInt8>& data)
+    {
+        oob_data =data;
+        return *this;
+    }
+
+    MultiArrayView<2, UInt8> oob_data;
+    ArrayVector<double> class_weights;
+    double training_set_proportion;
+    unsigned int mtry, min_split_node_size, training_set_size;
+    bool sample_with_replacement, sample_classes_individually;
+    unsigned int treeCount;
+};
+
+/*****************************************************************/
+/*                                                               */
+/*                          RandomForestDeprec                   */
+/*                                                               */
+/*****************************************************************/
+
+template <class ClassLabelType>
+class RandomForestDeprec
+{
+  public:
+    ArrayVector<ClassLabelType> classes_;
+    ArrayVector<detail::DecisionTreeDeprec> trees_;
+    MultiArrayIndex columnCount_;
+    RandomForestOptionsDeprec options_;
+
+  public:
+
+    //First two constructors are straight forward.
+    //they take either the iterators to an Array of Classlabels or the values
+    template<class ClassLabelIterator>
+    RandomForestDeprec(ClassLabelIterator cl, ClassLabelIterator cend,
+                  unsigned int treeCount = 255,
+                  RandomForestOptionsDeprec const & options = RandomForestOptionsDeprec())
+    : classes_(cl, cend),
+      trees_(treeCount, detail::DecisionTreeDeprec(classes_.size())),
+      columnCount_(0),
+      options_(options)
+    {
+        vigra_precondition(options.training_set_proportion == 0.0 ||
+                           options.training_set_size == 0,
+            "RandomForestOptionsDeprec: absolute and proportional training set sizes "
+            "cannot be specified at the same time.");
+        vigra_precondition(classes_.size() > 1,
+            "RandomForestOptionsDeprec::weights(): need at least two classes.");
+        vigra_precondition(options.class_weights.size() == 0 || options.class_weights.size() == classes_.size(),
+            "RandomForestOptionsDeprec::weights(): wrong number of classes.");
+    }
+
+    RandomForestDeprec(ClassLabelType const & c1, ClassLabelType const & c2,
+                  unsigned int treeCount = 255,
+                  RandomForestOptionsDeprec const & options = RandomForestOptionsDeprec())
+    : classes_(2),
+      trees_(treeCount, detail::DecisionTreeDeprec(2)),
+      columnCount_(0),
+      options_(options)
+    {
+        vigra_precondition(options.class_weights.size() == 0 || options.class_weights.size() == 2,
+            "RandomForestOptionsDeprec::weights(): wrong number of classes.");
+        classes_[0] = c1;
+        classes_[1] = c2;
+    }
+    //This is esp. For the CrosValidator Class
+    template<class ClassLabelIterator>
+    RandomForestDeprec(ClassLabelIterator cl, ClassLabelIterator cend,
+                  RandomForestOptionsDeprec const & options )
+    : classes_(cl, cend),
+      trees_(options.treeCount , detail::DecisionTreeDeprec(classes_.size())),
+      columnCount_(0),
+      options_(options)
+    {
+
+        vigra_precondition(options.training_set_proportion == 0.0 ||
+                           options.training_set_size == 0,
+            "RandomForestOptionsDeprec: absolute and proportional training set sizes "
+            "cannot be specified at the same time.");
+        vigra_precondition(classes_.size() > 1,
+            "RandomForestOptionsDeprec::weights(): need at least two classes.");
+        vigra_precondition(options.class_weights.size() == 0 || options.class_weights.size() == classes_.size(),
+            "RandomForestOptionsDeprec::weights(): wrong number of classes.");
+    }
+
+    //Not understood yet
+    //Does not use the options object but the columnCount object.
+    template<class ClassLabelIterator, class TreeIterator, class WeightIterator>
+    RandomForestDeprec(ClassLabelIterator cl, ClassLabelIterator cend,
+                  unsigned int treeCount, unsigned int columnCount,
+                  TreeIterator trees, WeightIterator weights)
+    : classes_(cl, cend),
+      trees_(treeCount, detail::DecisionTreeDeprec(classes_.size())),
+      columnCount_(columnCount)
+    {
+        for(unsigned int k=0; k<treeCount; ++k, ++trees, ++weights)
+        {
+            trees_[k].tree_ = *trees;
+            trees_[k].terminalWeights_ = *weights;
+        }
+    }
+
+    int featureCount() const
+    {
+        vigra_precondition(columnCount_ > 0,
+           "RandomForestDeprec::featureCount(): Random forest has not been trained yet.");
+        return columnCount_;
+    }
+
+    int labelCount() const
+    {
+        return classes_.size();
+    }
+
+    int treeCount() const
+    {
+        return trees_.size();
+    }
+
+    // loss == 0.0 means unweighted random forest
+    template <class U, class C, class Array, class Random>
+    double learn(MultiArrayView<2, U, C> const & features, Array const & labels,
+               Random const& random);
+
+    template <class U, class C, class Array>
+    double learn(MultiArrayView<2, U, C> const & features, Array const & labels)
+    {
+        RandomNumberGenerator<> generator(RandomSeed);
+        return learn(features, labels, generator);
+    }
+
+    template <class U, class C>
+    ClassLabelType predictLabel(MultiArrayView<2, U, C> const & features) const;
+
+    template <class U, class C1, class T, class C2>
+    void predictLabels(MultiArrayView<2, U, C1> const & features,
+                       MultiArrayView<2, T, C2> & labels) const
+    {
+        vigra_precondition(features.shape(0) == labels.shape(0),
+            "RandomForestDeprec::predictLabels(): Label array has wrong size.");
+        for(int k=0; k<features.shape(0); ++k)
+            labels(k,0) = predictLabel(rowVector(features, k));
+    }
+
+    template <class U, class C, class Iterator>
+    ClassLabelType predictLabel(MultiArrayView<2, U, C> const & features,
+                                Iterator priors) const;
+
+    template <class U, class C1, class T, class C2>
+    void predictProbabilities(MultiArrayView<2, U, C1> const & features,
+                              MultiArrayView<2, T, C2> & prob) const;
+
+    template <class U, class C1, class T, class C2>
+    void predictNodes(MultiArrayView<2, U, C1> const & features,
+                                                   MultiArrayView<2, T, C2> & NodeIDs) const;
+};
+
+template <class ClassLabelType>
+template <class U, class C1, class Array, class Random>
+double
+RandomForestDeprec<ClassLabelType>::learn(MultiArrayView<2, U, C1> const & features,
+                                             Array const & labels,
+                                             Random const& random)
+{
+    unsigned int classCount = classes_.size();
+    unsigned int m = rowCount(features);
+    unsigned int n = columnCount(features);
+    vigra_precondition((unsigned int)(m) == (unsigned int)labels.size(),
+      "RandomForestDeprec::learn(): Label array has wrong size.");
+
+    vigra_precondition(options_.training_set_size <= m || options_.sample_with_replacement,
+       "RandomForestDeprec::learn(): Requested training set size exceeds total number of examples.");
+
+    MultiArrayIndex mtry = (options_.mtry == 0)
+                                ? int(std::floor(std::sqrt(double(n)) + 0.5))
+                                : options_.mtry;
+
+    vigra_precondition(mtry <= (MultiArrayIndex)n,
+       "RandomForestDeprec::learn(): mtry must be less than number of features.");
+
+    MultiArrayIndex msamples = options_.training_set_size;
+    if(options_.sample_classes_individually)
+        msamples = int(std::ceil(double(msamples) / classCount));
+
+    ArrayVector<int> intLabels(m), classExampleCounts(classCount);
+
+    // verify the input labels
+    int minClassCount;
+    {
+        typedef std::map<ClassLabelType, int > LabelChecker;
+        typedef typename LabelChecker::iterator LabelCheckerIterator;
+        LabelChecker labelChecker;
+        for(unsigned int k=0; k<classCount; ++k)
+            labelChecker[classes_[k]] = k;
+
+        for(unsigned int k=0; k<m; ++k)
+        {
+            LabelCheckerIterator found = labelChecker.find(labels[k]);
+            vigra_precondition(found != labelChecker.end(),
+                "RandomForestDeprec::learn(): Unknown class label encountered.");
+            intLabels[k] = found->second;
+            ++classExampleCounts[intLabels[k]];
+        }
+        minClassCount = *argMin(classExampleCounts.begin(), classExampleCounts.end());
+        vigra_precondition(minClassCount > 0,
+             "RandomForestDeprec::learn(): At least one class is missing in the training set.");
+        if(msamples > 0 && options_.sample_classes_individually &&
+                          !options_.sample_with_replacement)
+        {
+            vigra_precondition(msamples <= minClassCount,
+                "RandomForestDeprec::learn(): Too few examples in smallest class to reach "
+                "requested training set size.");
+        }
+    }
+    columnCount_ = n;
+    ArrayVector<int> indices(m);
+    for(unsigned int k=0; k<m; ++k)
+        indices[k] = k;
+
+    if(options_.sample_classes_individually)
+    {
+        detail::RandomForestDeprecLabelSorter<ArrayVector<int> > sorter(intLabels);
+        std::sort(indices.begin(), indices.end(), sorter);
+    }
+
+    ArrayVector<int> usedIndices(m), oobCount(m), oobErrorCount(m);
+
+    UniformIntRandomFunctor<Random> randint(0, m-1, random);
+    //std::cerr << "Learning a RF \n";
+    for(unsigned int k=0; k<trees_.size(); ++k)
+    {
+       //std::cerr << "Learning tree " << k << " ...\n";
+
+        ArrayVector<int> trainingSet;
+        usedIndices.init(0);
+
+        if(options_.sample_classes_individually)
+        {
+            int first = 0;
+            for(unsigned int l=0; l<classCount; ++l)
+            {
+                int lc = classExampleCounts[l];
+                int lsamples = (msamples == 0)
+                                   ? int(std::ceil(options_.training_set_proportion*lc))
+                                   : msamples;
+
+                if(options_.sample_with_replacement)
+                {
+                    for(int ll=0; ll<lsamples; ++ll)
+                    {
+                        trainingSet.push_back(indices[first+randint(lc)]);
+                        ++usedIndices[trainingSet.back()];
+                    }
+                }
+                else
+                {
+                    for(int ll=0; ll<lsamples; ++ll)
+                    {
+                        std::swap(indices[first+ll], indices[first+ll+randint(lc-ll)]);
+                        trainingSet.push_back(indices[first+ll]);
+                        ++usedIndices[trainingSet.back()];
+                    }
+                    //std::sort(indices.begin(), indices.begin()+lsamples);
+                }
+                first += lc;
+            }
+        }
+        else
+        {
+            if(msamples == 0)
+                msamples = int(std::ceil(options_.training_set_proportion*m));
+
+            if(options_.sample_with_replacement)
+            {
+                for(int l=0; l<msamples; ++l)
+                {
+                    trainingSet.push_back(indices[randint(m)]);
+                    ++usedIndices[trainingSet.back()];
+                }
+            }
+            else
+            {
+                for(int l=0; l<msamples; ++l)
+                {
+                    std::swap(indices[l], indices[l+randint(m-l)/*oikas*/]);
+                    trainingSet.push_back(indices[l]);
+                    ++usedIndices[trainingSet.back()];
+                }
+
+
+            }
+
+        }
+        trees_[k].learn(features, intLabels,
+                        trainingSet.begin(), trainingSet.size(),
+                        options_.featuresPerNode(mtry), randint);
+//        for(unsigned int l=0; l<m; ++l)
+//        {
+//            if(!usedIndices[l])
+//            {
+//                ++oobCount[l];
+//                if(trees_[k].predictLabel(rowVector(features, l)) != intLabels[l])
+//                    ++oobErrorCount[l];
+//            }
+//        }
+
+        for(unsigned int l=0; l<m; ++l)
+        {
+            if(!usedIndices[l])
+            {
+                ++oobCount[l];
+                if(trees_[k].predictLabel(rowVector(features, l)) != intLabels[l])
+                {
+                    ++oobErrorCount[l];
+                    if(options_.oob_data.data() != 0)
+                        options_.oob_data(l, k) = 2;
+                }
+                else if(options_.oob_data.data() != 0)
+                {
+                    options_.oob_data(l, k) = 1;
+                }
+            }
+        }
+        // TODO: default value for oob_data
+        // TODO: implement variable importance
+        //if(!options_.sample_with_replacement){
+        //std::cerr << "done\n";
+        //trees_[k].print(std::cerr);
+        #ifdef VIGRA_RF_VERBOSE
+        trees_[k].printStatistics(std::cerr);
+        #endif
+    }
+    double oobError = 0.0;
+    int totalOobCount = 0;
+    for(unsigned int l=0; l<m; ++l)
+        if(oobCount[l])
+        {
+            oobError += double(oobErrorCount[l]) / oobCount[l];
+            ++totalOobCount;
+        }
+    return oobError / totalOobCount;
+}
+
+template <class ClassLabelType>
+template <class U, class C>
+ClassLabelType
+RandomForestDeprec<ClassLabelType>::predictLabel(MultiArrayView<2, U, C> const & features) const
+{
+    vigra_precondition(columnCount(features) >= featureCount(),
+        "RandomForestDeprec::predictLabel(): Too few columns in feature matrix.");
+    vigra_precondition(rowCount(features) == 1,
+        "RandomForestDeprec::predictLabel(): Feature matrix must have a single row.");
+    Matrix<double> prob(1, classes_.size());
+    predictProbabilities(features, prob);
+    return classes_[argMax(prob)];
+}
+
+
+//Same thing as above with priors for each label !!!
+template <class ClassLabelType>
+template <class U, class C, class Iterator>
+ClassLabelType
+RandomForestDeprec<ClassLabelType>::predictLabel(MultiArrayView<2, U, C> const & features,
+                                           Iterator priors) const
+{
+    using namespace functor;
+    vigra_precondition(columnCount(features) >= featureCount(),
+        "RandomForestDeprec::predictLabel(): Too few columns in feature matrix.");
+    vigra_precondition(rowCount(features) == 1,
+        "RandomForestDeprec::predictLabel(): Feature matrix must have a single row.");
+    Matrix<double> prob(1,classes_.size());
+    predictProbabilities(features, prob);
+    std::transform(prob.begin(), prob.end(), priors, prob.begin(), Arg1()*Arg2());
+    return classes_[argMax(prob)];
+}
+
+template <class ClassLabelType>
+template <class U, class C1, class T, class C2>
+void
+RandomForestDeprec<ClassLabelType>::predictProbabilities(MultiArrayView<2, U, C1> const & features,
+                                                   MultiArrayView<2, T, C2> & prob) const
+{
+
+    //Features are n xp
+    //prob is n x NumOfLabel probability for each feature in each class
+
+    vigra_precondition(rowCount(features) == rowCount(prob),
+      "RandomForestDeprec::predictProbabilities(): Feature matrix and probability matrix size mismatch.");
+
+    // num of features must be bigger than num of features in Random forest training
+    // but why bigger?
+    vigra_precondition(columnCount(features) >= featureCount(),
+      "RandomForestDeprec::predictProbabilities(): Too few columns in feature matrix.");
+    vigra_precondition(columnCount(prob) == (MultiArrayIndex)labelCount(),
+      "RandomForestDeprec::predictProbabilities(): Probability matrix must have as many columns as there are classes.");
+
+    //Classify for each row.
+    for(int row=0; row < rowCount(features); ++row)
+    {
+    //contains the weights returned by a single tree???
+    //thought that one tree has only one vote???
+    //Pruning???
+        ArrayVector<double>::const_iterator weights;
+
+        //totalWeight == totalVoteCount!
+    double totalWeight = 0.0;
+
+    //Set each VoteCount = 0 - prob(row,l) contains vote counts until
+    //further normalisation
+        for(unsigned int l=0; l<classes_.size(); ++l)
+            prob(row, l) = 0.0;
+
+    //Let each tree classify...
+        for(unsigned int k=0; k<trees_.size(); ++k)
+        {
+        //get weights predicted by single tree
+            weights = trees_[k].predict(rowVector(features, row));
+
+        //update votecount.
+            for(unsigned int l=0; l<classes_.size(); ++l)
+            {
+                prob(row, l) += detail::RequiresExplicitCast<T>::cast(weights[l]);
+                //every weight in totalWeight.
+                totalWeight += weights[l];
+            }
+        }
+
+    //Normalise votes in each row by total VoteCount (totalWeight
+        for(unsigned int l=0; l<classes_.size(); ++l)
+                prob(row, l) /= detail::RequiresExplicitCast<T>::cast(totalWeight);
+    }
+}
+
+
+template <class ClassLabelType>
+template <class U, class C1, class T, class C2>
+void
+RandomForestDeprec<ClassLabelType>::predictNodes(MultiArrayView<2, U, C1> const & features,
+                                                   MultiArrayView<2, T, C2> & NodeIDs) const
+{
+    vigra_precondition(columnCount(features) >= featureCount(),
+      "RandomForestDeprec::getNodesRF(): Too few columns in feature matrix.");
+    vigra_precondition(rowCount(features) <= rowCount(NodeIDs),
+      "RandomForestDeprec::getNodesRF(): Too few rows in NodeIds matrix");
+    vigra_precondition(columnCount(NodeIDs) >= treeCount(),
+      "RandomForestDeprec::getNodesRF(): Too few columns in NodeIds matrix.");
+    NodeIDs.init(0);
+    for(unsigned int k=0; k<trees_.size(); ++k)
+    {
+        for(int row=0; row < rowCount(features); ++row)
+        {
+            NodeIDs(row,k) = trees_[k].leafID(rowVector(features, row));
+        }
+    }
+}
+
+//@}
+
+} // namespace vigra
+
+
+#endif // VIGRA_RANDOM_FOREST_HXX
+
diff --git a/include/vigra/random_forest_hdf5_impex.hxx b/include/vigra/random_forest_hdf5_impex.hxx
new file mode 100644
index 0000000..ff34fbe
--- /dev/null
+++ b/include/vigra/random_forest_hdf5_impex.hxx
@@ -0,0 +1,305 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2009 by Rahul Nair and  Ullrich Koethe               */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_RANDOM_FOREST_IMPEX_HDF5_HXX
+#define VIGRA_RANDOM_FOREST_IMPEX_HDF5_HXX
+
+#include "config.hxx"
+#include "random_forest.hxx"
+#include "hdf5impex.hxx"
+#include <string>
+
+namespace vigra 
+{
+
+static const char *const rf_hdf5_options       = "_options";
+static const char *const rf_hdf5_ext_param     = "_ext_param";
+static const char *const rf_hdf5_labels        = "labels";
+static const char *const rf_hdf5_topology      = "topology";
+static const char *const rf_hdf5_parameters    = "parameters";
+static const char *const rf_hdf5_tree          = "Tree_";
+static const char *const rf_hdf5_version_group = ".";
+static const char *const rf_hdf5_version_tag   = "vigra_random_forest_version";
+static const double      rf_hdf5_version       =  0.1;
+
+namespace detail
+{
+
+VIGRA_EXPORT void options_import_HDF5(HDF5File &, RandomForestOptions &,
+                                      const std::string &);
+
+VIGRA_EXPORT void options_export_HDF5(HDF5File &, const RandomForestOptions &,
+                                      const std::string &);
+
+VIGRA_EXPORT void dt_import_HDF5(HDF5File &, detail::DecisionTree &,
+                                 const std::string &);
+
+VIGRA_EXPORT void dt_export_HDF5(HDF5File &, const detail::DecisionTree &,
+                                 const std::string &);
+
+template<class X>
+void rf_import_HDF5_to_map(HDF5File & h5context, X & param,
+                           const char *const ignored_label = 0)
+{
+    // read a map containing all the double fields
+    typedef typename X::map_type map_type;
+    typedef std::pair<typename map_type::iterator, bool> inserter_type;
+    typedef typename map_type::value_type value_type;
+    typedef typename map_type::mapped_type mapped_type;
+
+    map_type serialized_param;
+    bool ignored_seen = ignored_label == 0;
+
+    std::vector<std::string> names = h5context.ls();
+    std::vector<std::string>::const_iterator j;
+    for (j = names.begin(); j != names.end(); ++j)
+    {
+        if (ignored_label && *j == ignored_label)
+        {
+            ignored_seen = true;
+            continue;
+        }
+        // get sort of an iterator to a new empty array vector in the map ...
+        inserter_type new_array
+            = serialized_param.insert(value_type(*j, mapped_type()));
+        // ... and read the data into that place.
+        h5context.readAndResize(*j, (*(new_array.first)).second);
+    }
+    vigra_precondition(ignored_seen, "rf_import_HDF5_to_map(): "
+                                                         "labels are missing.");
+    param.make_from_map(serialized_param);
+}
+
+template<class T>
+void problemspec_import_HDF5(HDF5File & h5context, ProblemSpec<T> & param,
+                             const std::string & name)
+{
+    h5context.cd(name);
+    rf_import_HDF5_to_map(h5context, param, rf_hdf5_labels);
+    // load_class_labels
+    ArrayVector<T> labels;
+    h5context.readAndResize(rf_hdf5_labels, labels);
+    param.classes_(labels.begin(), labels.end());
+    h5context.cd_up();
+}
+
+template<class X>
+void rf_export_map_to_HDF5(HDF5File & h5context, const X & param)
+{
+    typedef typename X::map_type map_type;
+    map_type serialized_param;
+    // get a map containing all the double fields
+    param.make_map(serialized_param);
+    typename map_type::const_iterator j;
+    for (j = serialized_param.begin(); j != serialized_param.end(); ++j)
+        h5context.write(j->first, j->second);
+}
+
+template<class T>
+void problemspec_export_HDF5(HDF5File & h5context, ProblemSpec<T> const & param,
+                             const std::string & name)
+{
+    h5context.cd_mk(name);
+    rf_export_map_to_HDF5(h5context, param);
+    h5context.write(rf_hdf5_labels, param.classes);
+    h5context.cd_up();
+}
+
+struct padded_number_string_data;
+class VIGRA_EXPORT padded_number_string
+{
+private:
+    padded_number_string_data* padded_number;
+protected:
+    padded_number_string(const padded_number_string &);
+    void operator=(const padded_number_string &);
+public:
+    padded_number_string(int n);
+    std::string operator()(int k) const;
+    ~padded_number_string();
+};
+
+inline std::string get_cwd(HDF5File & h5context)
+{
+    return h5context.get_absolute_path(h5context.pwd());
+}
+
+} // namespace detail
+
+/** \brief Save a random forest to an HDF5File object into a specified HDF5
+           group.
+    
+    The random forest is saved as a set of HDF5 datasets, groups, and
+    attributes below a certain HDF5 group (default: current group of the
+    HDF5File object). No additional data should be stored in that group.
+    
+    \param rf        Random forest object to be exported
+    \param h5context HDF5File object to use
+    \param pathname  If empty or not supplied, save the random forest to the
+                     current group of the HDF5File object. Otherwise, save to a
+                     new-created group specified by the path name, which may
+                     be either relative or absolute.
+*/
+template<class T, class Tag>
+void rf_export_HDF5(const RandomForest<T, Tag> & rf,
+                    HDF5File & h5context,
+                    const std::string & pathname = "")
+{
+    std::string cwd;
+    if (pathname.size()) {
+        cwd = detail::get_cwd(h5context);
+        h5context.cd_mk(pathname);
+    }
+    // version attribute
+    h5context.writeAttribute(rf_hdf5_version_group, rf_hdf5_version_tag,
+                             rf_hdf5_version);
+    // save serialized options
+    detail::options_export_HDF5(h5context, rf.options(), rf_hdf5_options);
+    // save external parameters
+    detail::problemspec_export_HDF5(h5context, rf.ext_param(),
+                                    rf_hdf5_ext_param);
+    // save trees
+    int tree_count = rf.options_.tree_count_;
+    detail::padded_number_string tree_number(tree_count);
+    for (int i = 0; i < tree_count; ++i)
+        detail::dt_export_HDF5(h5context, rf.tree(i),
+                                                 rf_hdf5_tree + tree_number(i));
+
+    if (pathname.size())
+        h5context.cd(cwd);
+}
+
+/** \brief Save a random forest to a named HDF5 file into a specified HDF5
+           group.
+    
+    The random forest is saved as a set of HDF5 datasets, groups, and
+    attributes below a certain HDF5 group (default: root). No additional data
+    should be stored in that group.
+    
+    \param rf       Random forest object to be exported
+    \param filename Name of an HDF5 file to open
+    \param pathname If empty or not supplied, save the random forest to the
+                    root group of the HDF5 file. Otherwise, save to a
+                    new-created group specified by the path name (relative
+                    to the root group).
+*/
+template<class T, class Tag>
+void rf_export_HDF5(const RandomForest<T, Tag> & rf,
+                    const std::string & filename, 
+                    const std::string & pathname = "")
+{
+    HDF5File h5context(filename , HDF5File::Open);
+    rf_export_HDF5(rf, h5context, pathname);
+}
+
+/** \brief Read a random forest from an HDF5File object's specified group.
+    
+    The random forest is read from a certain HDF5 group (default: current group
+    of the HDF5File object) as a set of HDF5 datasets, groups, and
+    attributes. No additional data should be present in that group.
+    
+    \param rf        Random forest object to be imported
+    \param h5context HDF5File object to use
+    \param pathname  If empty or not supplied, read from the random forest
+                     from the current group of the HDF5File object. Otherwise,
+                     use the group specified by the path name, which may
+                     be either relative or absolute.
+*/
+template<class T, class Tag>
+bool rf_import_HDF5(RandomForest<T, Tag> & rf,
+                    HDF5File & h5context,
+                    const std::string & pathname = "")
+{
+    std::string cwd;
+    if (pathname.size()) {
+        cwd = detail::get_cwd(h5context);
+        h5context.cd(pathname);
+    }
+    // version attribute
+    if (h5context.existsAttribute(rf_hdf5_version_group, rf_hdf5_version_tag))
+    {
+        double read_version;
+        h5context.readAttribute(rf_hdf5_version_group, rf_hdf5_version_tag,
+                                read_version);
+        vigra_precondition(read_version <= rf_hdf5_version,
+                          "rf_import_HDF5(): unexpected file format version.");
+    }
+    // get serialized options
+    detail::options_import_HDF5(h5context, rf.options_, rf_hdf5_options);
+    // get external parameters
+    detail::problemspec_import_HDF5(h5context, rf.ext_param_,
+                                    rf_hdf5_ext_param);
+    // get all groups in base path
+    // no check for the rf_hdf5_tree prefix...
+    std::vector<std::string> names = h5context.ls();
+    std::vector<std::string>::const_iterator j;
+    for (j = names.begin(); j != names.end(); ++j)
+    {
+        if ((*j->rbegin() == '/') && (*j->begin() != '_')) // skip the above
+        {
+            rf.trees_.push_back(detail::DecisionTree(rf.ext_param_));
+            detail::dt_import_HDF5(h5context, rf.trees_.back(), *j);
+        }
+    }
+    if (pathname.size())
+        h5context.cd(cwd);
+    return true;
+}
+
+/** \brief Read a random forest from a named HDF5 file's specified group.
+    
+    The random forest is read from a certain HDF5 group (default: root group
+    of the HDF5 file) as a set of HDF5 datasets, groups, and attributes.
+    No additional data should be present in that group.
+    
+    \param rf        Random forest object to be imported
+    \param filename Name of an HDF5 file to open
+    \param pathname  If empty or not supplied, read from the random forest
+                     from the current group of the HDF5 file. Otherwise,
+                     use the group specified by the path name, which may
+                     be either relative or absolute.
+*/
+template<class T, class Tag>
+bool rf_import_HDF5(RandomForest<T, Tag> & rf,
+                    const std::string & filename, 
+                    const std::string & pathname = "")
+{
+    HDF5File h5context(filename, HDF5File::OpenReadOnly);
+    return rf_import_HDF5(rf, h5context, pathname);
+}
+
+} // namespace vigra
+
+#endif // VIGRA_RANDOM_FOREST_HDF5_IMPEX_HXX
diff --git a/include/vigra/rational.hxx b/include/vigra/rational.hxx
new file mode 100644
index 0000000..1094032
--- /dev/null
+++ b/include/vigra/rational.hxx
@@ -0,0 +1,1312 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    It was adapted from the file boost/rational.hpp of the            */
+/*    boost library.                                                    */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+// this file is based on work by Paul Moore:
+//
+//  (C) Copyright Paul Moore 1999. Permission to copy, use, modify, sell and
+//  distribute this software is granted provided this copyright notice appears
+//  in all copies. This software is provided "as is" without express or
+//  implied warranty, and with no claim as to its suitability for any purpose.
+//
+//  See http://www.boost.org/libs/rational for documentation.
+
+
+#ifndef VIGRA_RATIONAL_HPP
+#define VIGRA_RATIONAL_HPP
+
+#include <cmath>
+#include <stdexcept>
+#include <iosfwd>
+#include "config.hxx"
+#include "mathutil.hxx"
+#include "numerictraits.hxx"
+#include "metaprogramming.hxx"
+
+namespace vigra {
+
+/** \addtogroup MathFunctions Mathematical Functions
+*/
+//@{
+
+
+/********************************************************/
+/*                                                      */
+/*                         gcd                          */
+/*                                                      */
+/********************************************************/
+
+/** Calculate the greatest common divisor.
+
+    This function works for arbitrary integer types, including user-defined
+    (e.g. infinite precision) ones.
+
+    <b>\#include</b> \<vigra/rational.hxx\><br>
+    Namespace: vigra
+*/
+template <typename IntType>
+IntType gcd(IntType n, IntType m)
+{
+    // Avoid repeated construction
+    IntType zero(0);
+
+    // This is abs() - given the existence of broken compilers with Koenig
+    // lookup issues and other problems, I code this explicitly. (Remember,
+    // IntType may be a user-defined type).
+    if (n < zero)
+        n = -n;
+    if (m < zero)
+        m = -m;
+
+    // As n and m are now positive, we can be sure that %= returns a
+    // positive value (the standard guarantees this for built-in types,
+    // and we require it of user-defined types).
+    for(;;) {
+      if(m == zero)
+        return n;
+      n %= m;
+      if(n == zero)
+        return m;
+      m %= n;
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*                         lcm                          */
+/*                                                      */
+/********************************************************/
+
+/** Calculate the lowest common multiple.
+
+    This function works for arbitrary integer types, including user-defined
+    (e.g. infinite precision) ones.
+
+    <b>\#include</b> \<vigra/rational.hxx\><br>
+    Namespace: vigra
+*/
+template <typename IntType>
+IntType lcm(IntType n, IntType m)
+{
+    // Avoid repeated construction
+    IntType zero(0);
+
+    if (n == zero || m == zero)
+        return zero;
+
+    n /= gcd(n, m);
+    n *= m;
+
+    if (n < zero)
+        n = -n;
+    return n;
+}
+
+//@}
+
+class bad_rational : public std::domain_error
+{
+public:
+    explicit bad_rational() : std::domain_error("bad rational: zero denominator") {}
+};
+
+template <typename IntType>
+class Rational;
+
+template <typename IntType>
+Rational<IntType> abs(const Rational<IntType>& r);
+template <typename IntType>
+Rational<IntType> pow(const Rational<IntType>& r, int n);
+template <typename IntType>
+Rational<IntType> floor(const Rational<IntType>& r);
+template <typename IntType>
+Rational<IntType> ceil(const Rational<IntType>& r);
+
+/********************************************************/
+/*                                                      */
+/*                       Rational                       */
+/*                                                      */
+/********************************************************/
+
+/** Template for rational numbers.
+
+    This template can make use of arbitrary integer types, including
+    user-defined (e.g. infinite precision) ones. Note, however,
+    that overflow in either the numerator or denominator is not
+    detected during calculations -- the standard behavior of the integer type
+    (e.g. wrap around) applies.
+
+    The class can represent and handle positive and negative infinity
+    resulting from division by zero. Indeterminate expressions such as 0/0
+    are signaled by a <tt>bad_rational</tt> exception which is derived from
+    <tt>std::domain_error</tt>.
+
+    <tt>Rational</tt> implements the required interface of an
+    \ref AlgebraicField and the required \ref RationalTraits "numeric and
+    promotion traits". All arithmetic and comparison operators, as well
+    as the relevant algebraic functions are supported .
+
+    <b>See also:</b>
+    <ul>
+    <li> \ref RationalTraits
+    <li> \ref RationalOperations
+    </ul>
+
+
+    <b>\#include</b> \<vigra/rational.hxx\><br>
+    Namespace: vigra
+*/
+template <typename IntType>
+class Rational
+{
+public:
+        /** The type of numerator and denominator
+        */
+    typedef IntType value_type;
+
+        /** Determine whether arguments should be passed as
+            <tt>IntType</tt> or <tt>IntType const &</tt>.
+        */
+    typedef typename If<typename TypeTraits<IntType>::isBuiltinType,
+                        IntType, IntType const &>::type param_type;
+
+        /** Default constructor: creates zero (<tt>0/1</tt>)
+        */
+    Rational()
+    : num(0),
+      den(1)
+    {}
+
+        /** Copy constructor
+        */
+    template <class U>
+    Rational(Rational<U> const & r)
+    : num(r.numerator()),
+      den(r.denominator())
+    {}
+
+        /** Integer constructor: creates <tt>n/1</tt>
+        */
+    Rational(param_type n)
+    : num(n),
+      den(IntType(1))
+    {}
+
+        /** Ratio constructor: creates <tt>n/d</tt>.
+
+            The ratio will be normalized unless <tt>doNormalize = false</tt>.
+            Since the internal representation is assumed to be normalized,
+            <tt>doNormalize = false</tt> must only be used as an optimization
+            if <tt>n</tt> and <tt>d</tt> are known to be already normalized
+            (i.e. have 1 as their greatest common divisor).
+        */
+    Rational(param_type n, param_type d, bool doNormalize = true)
+    : num(n),
+      den(d)
+    {
+        if(doNormalize)
+            normalize();
+    }
+
+        /** Construct as an approximation of a real number.
+
+            The maximal allowed relative error is given by <tt>epsilon</tt>.
+        */
+    explicit Rational(double v, double epsilon = 1e-4)
+    : num(IntType(v < 0.0 ?
+                    v/epsilon - 0.5
+                  : v/epsilon + 0.5)),
+      den(IntType(1.0/epsilon + 0.5))
+    {
+        normalize();
+    }
+
+    // Default copy constructor and assignment are fine
+
+        /** Assignment from <tt>IntType</tt>.
+        */
+    Rational& operator=(param_type n) { return assign(n, 1); }
+
+        /** Assignment from <tt>IntType</tt> pair.
+        */
+    Rational& assign(param_type n, param_type d, bool doNormalize = true);
+
+        /** Access numerator.
+        */
+    param_type numerator() const { return num; }
+
+        /** Access denominator.
+        */
+    param_type denominator() const { return den; }
+
+        /** Add-assignment from <tt>Rational</tt>
+
+            <tt>throws bad_rational</tt> if indeterminate expression.
+        */
+    Rational& operator+= (const Rational & r);
+
+        /** Subtract-assignment from <tt>Rational</tt>
+
+            <tt>throws bad_rational</tt> if indeterminate expression.
+        */
+    Rational& operator-= (const Rational & r);
+
+        /** Multiply-assignment from <tt>Rational</tt>
+
+            <tt>throws bad_rational</tt> if indeterminate expression.
+        */
+    Rational& operator*= (const Rational & r);
+
+        /** Divide-assignment from <tt>Rational</tt>
+
+            <tt>throws bad_rational</tt> if indeterminate expression.
+        */
+    Rational& operator/= (const Rational & r);
+
+        /** Add-assignment from <tt>IntType</tt>
+
+            <tt>throws bad_rational</tt> if indeterminate expression.
+        */
+    Rational& operator+= (param_type i);
+
+        /** Subtract-assignment from <tt>IntType</tt>
+
+            <tt>throws bad_rational</tt> if indeterminate expression.
+        */
+    Rational& operator-= (param_type i);
+
+        /** Multiply-assignment from <tt>IntType</tt>
+
+            <tt>throws bad_rational</tt> if indeterminate expression.
+        */
+    Rational& operator*= (param_type i);
+
+        /** Divide-assignment from <tt>IntType</tt>
+
+            <tt>throws bad_rational</tt> if indeterminate expression.
+        */
+    Rational& operator/= (param_type i);
+
+        /** Pre-increment.
+        */
+    Rational& operator++();
+        /** Pre-decrement.
+        */
+    Rational& operator--();
+
+        /** Post-increment.
+        */
+    Rational operator++(int) { Rational res(*this); operator++(); return res; }
+        /** Post-decrement.
+        */
+    Rational operator--(int) { Rational res(*this); operator--(); return res; }
+
+        /** Check for zero by calling <tt>!numerator()</tt>
+        */
+    bool operator!() const { return !num; }
+
+        /** Check whether we have positive infinity.
+        */
+    bool is_pinf() const
+    {
+        IntType zero(0);
+        return den == zero && num > zero;
+    }
+
+        /** Check whether we have negative infinity.
+        */
+    bool is_ninf() const
+    {
+        IntType zero(0);
+        return den == zero && num < zero;
+    }
+
+        /** Check whether we have positive or negative infinity.
+        */
+    bool is_inf() const
+    {
+        IntType zero(0);
+        return den == zero && num != zero;
+    }
+
+        /** Check the sign.
+
+            Gives 1 if the number is positive, -1 if negative, and 0 otherwise.
+        */
+    int sign() const
+    {
+        IntType zero(0);
+        return num == zero ? 0 : num < zero ? -1 : 1;
+    }
+
+private:
+    // Implementation - numerator and denominator (normalized).
+    // Other possibilities - separate whole-part, or sign, fields?
+    IntType num;
+    IntType den;
+
+    // Representation note: Fractions are kept in normalized form at all
+    // times. normalized form is defined as gcd(num,den) == 1 and den > 0.
+    // In particular, note that the implementation of abs() below relies
+    // on den always being positive.
+    void normalize();
+};
+
+// Assign in place
+template <typename IntType>
+inline Rational<IntType>&
+Rational<IntType>::assign(param_type n, param_type d, bool doNormalize)
+{
+    num = n;
+    den = d;
+    if(doNormalize)
+        normalize();
+    return *this;
+}
+
+// Arithmetic assignment operators
+template <typename IntType>
+Rational<IntType>& Rational<IntType>::operator+= (const Rational & r)
+{
+    IntType zero(0);
+
+    // handle the Inf and NaN cases
+    if(den == zero)
+    {
+        if(r.den == zero && sign()*r.sign() < 0)
+            throw bad_rational();
+        return *this;
+    }
+    if(r.den == zero)
+    {
+        assign(r.num, zero, false); // Inf or -Inf
+        return *this;
+    }
+
+    // This calculation avoids overflow, and minimises the number of expensive
+    // calculations. Thanks to Nickolay Mladenov for this algorithm.
+    //
+    // Proof:
+    // We have to compute a/b + c/d, where gcd(a,b)=1 and gcd(b,c)=1.
+    // Let g = gcd(b,d), and b = b1*g, d=d1*g. Then gcd(b1,d1)=1
+    //
+    // The result is (a*d1 + c*b1) / (b1*d1*g).
+    // Now we have to normalize this ratio.
+    // Let's assume h | gcd((a*d1 + c*b1), (b1*d1*g)), and h > 1
+    // If h | b1 then gcd(h,d1)=1 and hence h|(a*d1+c*b1) => h|a.
+    // But since gcd(a,b1)=1 we have h=1.
+    // Similarly h|d1 leads to h=1.
+    // So we have that h | gcd((a*d1 + c*b1) , (b1*d1*g)) => h|g
+    // Finally we have gcd((a*d1 + c*b1), (b1*d1*g)) = gcd((a*d1 + c*b1), g)
+    // Which proves that instead of normalizing the result, it is better to
+    // divide num and den by gcd((a*d1 + c*b1), g)
+
+    // Protect against self-modification
+    IntType r_num = r.num;
+    IntType r_den = r.den;
+
+    IntType g = gcd(den, r_den);
+    den /= g;  // = b1 from the calculations above
+    num = num * (r_den / g) + r_num * den;
+    g = gcd(num, g);
+    num /= g;
+    den *= r_den/g;
+
+    return *this;
+}
+
+template <typename IntType>
+Rational<IntType>& Rational<IntType>::operator-= (const Rational & r)
+{
+    IntType zero(0);
+
+    // handle the Inf and NaN cases
+    if(den == zero)
+    {
+        if(r.den == zero && sign()*r.sign() > 0)
+            throw bad_rational();
+        return *this;
+    }
+    if(r.den == zero)
+    {
+        assign(-r.num, zero, false); // Inf or -Inf
+        return *this;
+    }
+
+    // Protect against self-modification
+    IntType r_num = r.num;
+    IntType r_den = r.den;
+
+    // This calculation avoids overflow, and minimises the number of expensive
+    // calculations. It corresponds exactly to the += case above
+    IntType g = gcd(den, r_den);
+    den /= g;
+    num = num * (r_den / g) - r_num * den;
+    g = gcd(num, g);
+    num /= g;
+    den *= r_den/g;
+
+    return *this;
+}
+
+template <typename IntType>
+Rational<IntType>& Rational<IntType>::operator*= (const Rational & r)
+{
+    IntType zero(0);
+
+    // handle the Inf and NaN cases
+    if(den == zero)
+    {
+        if(r.num == zero)
+            throw bad_rational();
+        num *= r.sign();
+        return *this;
+    }
+    if(r.den == zero)
+    {
+        if(num == zero)
+            throw bad_rational();
+        num = r.num * sign();
+        den = zero;
+        return *this;
+    }
+
+    // Protect against self-modification
+    IntType r_num = r.num;
+    IntType r_den = r.den;
+
+    // Avoid overflow and preserve normalization
+    IntType gcd1 = gcd<IntType>(num, r_den);
+    IntType gcd2 = gcd<IntType>(r_num, den);
+    num = (num/gcd1) * (r_num/gcd2);
+    den = (den/gcd2) * (r_den/gcd1);
+    return *this;
+}
+
+template <typename IntType>
+Rational<IntType>& Rational<IntType>::operator/= (const Rational & r)
+{
+    IntType zero(0);
+
+    // handle the Inf and NaN cases
+    if(den == zero)
+    {
+        if(r.den == zero)
+            throw bad_rational();
+        if(r.num != zero)
+            num *= r.sign();
+        return *this;
+    }
+    if(r.num == zero)
+    {
+        if(num == zero)
+            throw bad_rational();
+        num = IntType(sign());  // normalized inf!
+        den = zero;
+        return *this;
+    }
+
+    if (num == zero)
+        return *this;
+
+    // Protect against self-modification
+    IntType r_num = r.num;
+    IntType r_den = r.den;
+
+    // Avoid overflow and preserve normalization
+    IntType gcd1 = gcd<IntType>(num, r_num);
+    IntType gcd2 = gcd<IntType>(r_den, den);
+    num = (num/gcd1) * (r_den/gcd2);
+    den = (den/gcd2) * (r_num/gcd1);
+
+    if (den < zero) {
+        num = -num;
+        den = -den;
+    }
+    return *this;
+}
+
+// Mixed-mode operators -- implement explicitly to save gcd() calculations
+template <typename IntType>
+inline Rational<IntType>&
+Rational<IntType>::operator+= (param_type i)
+{
+    num += i * den;
+    return *this;
+}
+
+template <typename IntType>
+inline Rational<IntType>&
+Rational<IntType>::operator-= (param_type i)
+{
+    num -= i * den;
+    return *this;
+}
+
+template <typename IntType>
+Rational<IntType>&
+Rational<IntType>::operator*= (param_type i)
+{
+    if(i == IntType(1))
+        return *this;
+    IntType zero(0);
+    if(i == zero)
+    {
+        if(den == zero)
+        {
+            throw bad_rational();
+        }
+        else
+        {
+            num = zero;
+            den = IntType(1);
+            return *this;
+        }
+    }
+
+    IntType g = gcd(i, den);
+    den /= g;
+    num *= i / g;
+    return *this;
+}
+
+template <typename IntType>
+Rational<IntType>&
+Rational<IntType>::operator/= (param_type i)
+{
+    if(i == IntType(1))
+        return *this;
+
+    IntType zero(0);
+    if(i == zero)
+    {
+        if(num == zero)
+            throw bad_rational();
+        num = IntType(sign()); // normalized inf!
+        den = zero;
+        return *this;
+    }
+
+    IntType g = gcd(i, num);
+    if(i < zero)
+    {
+        num /= -g;
+        den *= -i / g;
+    }
+    else
+    {
+        num /= g;
+        den *= i / g;
+    }
+    return *this;
+}
+
+// Increment and decrement
+template <typename IntType>
+inline Rational<IntType>& Rational<IntType>::operator++()
+{
+    // This can never denormalise the fraction
+    num += den;
+    return *this;
+}
+
+template <typename IntType>
+inline Rational<IntType>& Rational<IntType>::operator--()
+{
+    // This can never denormalise the fraction
+    num -= den;
+    return *this;
+}
+
+// Normalisation
+template <typename IntType>
+void Rational<IntType>::normalize()
+{
+    // Avoid repeated construction
+    IntType zero(0);
+
+    if (den == zero)
+    {
+        if(num == zero)
+            throw bad_rational();
+        if(num < zero)
+            num = IntType(-1);
+        else
+            num = IntType(1);
+        return;
+    }
+
+    // Handle the case of zero separately, to avoid division by zero
+    if (num == zero) {
+        den = IntType(1);
+        return;
+    }
+
+    IntType g = gcd<IntType>(num, den);
+
+    num /= g;
+    den /= g;
+
+    // Ensure that the denominator is positive
+    if (den < zero) {
+        num = -num;
+        den = -den;
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*                      Rational-Traits                 */
+/*                                                      */
+/********************************************************/
+
+/** \page RationalTraits Numeric and Promote Traits of Rational
+
+    The numeric and promote traits for Rational follow
+    the general specifications for \ref NumericPromotionTraits and
+    \ref AlgebraicField. They are implemented in terms of the traits of the basic types by
+    partial template specialization:
+
+    \code
+
+    template <class T>
+    struct NumericTraits<Rational<T> >
+    {
+        typedef Rational<typename NumericTraits<T>::Promote> Promote;
+        typedef Rational<typename NumericTraits<T>::RealPromote> RealPromote;
+
+        typedef typename NumericTraits<T>::isIntegral isIntegral;
+        typedef VigraTrueType isScalar;
+        typedef typename NumericTraits<T>::isSigned isSigned;
+        typedef VigraTrueType isOrdered;
+
+        // etc.
+    };
+
+    template<class T>
+    struct NormTraits<Rational<T> >
+    {
+        typedef Rational<T>                           Type;
+        typedef typename NumericTraits<Type>::Promote SquaredNormType;
+        typedef Type                                  NormType;
+    };
+
+    template <class T1, class T2>
+    struct PromoteTraits<Rational<T1>, Rational<T2> >
+    {
+        typedef Rational<typename PromoteTraits<T1, T2>::Promote> Promote;
+    };
+    \endcode
+
+    <b>\#include</b> \<vigra/rational.hxx\><br>
+    Namespace: vigra
+
+*/
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template<class T>
+struct NumericTraits<Rational<T> >
+{
+    typedef Rational<T> Type;
+    typedef Rational<typename NumericTraits<T>::Promote> Promote;
+    typedef Rational<typename NumericTraits<T>::RealPromote> RealPromote;
+    typedef std::complex<Rational<RealPromote> > ComplexPromote;
+    typedef T ValueType;
+
+    typedef typename NumericTraits<T>::isIntegral isIntegral;
+    typedef VigraTrueType isScalar;
+    typedef typename NumericTraits<T>::isSigned isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+
+    static Type zero() { return Type(0); }
+    static Type one() { return Type(1); }
+    static Type nonZero() { return one(); }
+
+    static Promote toPromote(Type const & v)
+        { return Promote(v.numerator(), v.denominator(), false); }
+    static RealPromote toRealPromote(Type const & v)
+        { return RealPromote(v.numerator(), v.denominator(), false); }
+    static Type fromPromote(Promote const & v)
+        { return Type(NumericTraits<T>::fromPromote(v.numerator()),
+                      NumericTraits<T>::fromPromote(v.denominator()), false); }
+    static Type fromRealPromote(RealPromote const & v)
+        { return Type(NumericTraits<T>::fromRealPromote(v.numerator()),
+                      NumericTraits<T>::fromRealPromote(v.denominator()), false); }
+};
+
+template<class T>
+struct NormTraits<Rational<T> >
+{
+    typedef Rational<T>                           Type;
+    typedef typename NumericTraits<Type>::Promote SquaredNormType;
+    typedef Type                                  NormType;
+};
+
+template <class T>
+struct PromoteTraits<Rational<T>, Rational<T> >
+{
+    typedef Rational<typename PromoteTraits<T, T>::Promote> Promote;
+    static Promote toPromote(Rational<T> const & v) { return v; }
+};
+
+template <class T1, class T2>
+struct PromoteTraits<Rational<T1>, Rational<T2> >
+{
+    typedef Rational<typename PromoteTraits<T1, T2>::Promote> Promote;
+    static Promote toPromote(Rational<T1> const & v) { return v; }
+    static Promote toPromote(Rational<T2> const & v) { return v; }
+};
+
+template <class T1, class T2>
+struct PromoteTraits<Rational<T1>, T2 >
+{
+    typedef Rational<typename PromoteTraits<T1, T2>::Promote> Promote;
+    static Promote toPromote(Rational<T1> const & v) { return v; }
+    static Promote toPromote(T2 const & v) { return Promote(v); }
+};
+
+template <class T1, class T2>
+struct PromoteTraits<T1, Rational<T2> >
+{
+    typedef Rational<typename PromoteTraits<T1, T2>::Promote> Promote;
+    static Promote toPromote(T1 const & v) { return Promote(v); }
+    static Promote toPromote(Rational<T2> const & v) { return v; }
+};
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+/********************************************************/
+/*                                                      */
+/*                   RationalOperations                 */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup RationalOperations Functions for Rational
+
+    \brief     <b>\#include</b> \<vigra/rational.hxx\><br>
+
+    These functions fulfill the requirements of an \ref AlgebraicField.
+
+    Namespace: vigra
+    <p>
+
+ */
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                        arithmetic                    */
+/*                                                      */
+/********************************************************/
+
+    /// unary plus
+template <typename IntType>
+inline Rational<IntType> operator+ (const Rational<IntType>& r)
+{
+    return r;
+}
+
+    /// unary minus (negation)
+template <typename IntType>
+inline Rational<IntType> operator- (const Rational<IntType>& r)
+{
+    return Rational<IntType>(-r.numerator(), r.denominator(), false);
+}
+
+    /// addition
+template <typename IntType>
+inline Rational<IntType> operator+(Rational<IntType> l, Rational<IntType> const & r)
+{
+    return l += r;
+}
+
+    /// subtraction
+template <typename IntType>
+inline Rational<IntType> operator-(Rational<IntType> l, Rational<IntType> const & r)
+{
+    return l -= r;
+}
+
+    /// multiplication
+template <typename IntType>
+inline Rational<IntType> operator*(Rational<IntType> l, Rational<IntType> const & r)
+{
+    return l *= r;
+}
+
+    /// division
+template <typename IntType>
+inline Rational<IntType> operator/(Rational<IntType> l, Rational<IntType> const & r)
+{
+    return l /= r;
+}
+
+    /// addition of right-hand <tt>IntType</tt> argument
+template <typename IntType>
+inline Rational<IntType>
+operator+(Rational<IntType> l, typename Rational<IntType>::param_type r)
+{
+    return l += r;
+}
+
+    /// subtraction of right-hand <tt>IntType</tt> argument
+template <typename IntType>
+inline Rational<IntType>
+operator-(Rational<IntType> l, typename Rational<IntType>::param_type r)
+{
+    return l -= r;
+}
+
+    /// multiplication with right-hand <tt>IntType</tt> argument
+template <typename IntType>
+inline Rational<IntType>
+operator*(Rational<IntType> l, typename Rational<IntType>::param_type r)
+{
+    return l *= r;
+}
+
+    /// division by right-hand <tt>IntType</tt> argument
+template <typename IntType>
+inline Rational<IntType>
+operator/(Rational<IntType> l, typename Rational<IntType>::param_type r)
+{
+    return l /= r;
+}
+
+    /// addition of left-hand <tt>IntType</tt> argument
+template <typename IntType>
+inline Rational<IntType>
+operator+(typename Rational<IntType>::param_type l, Rational<IntType> r)
+{
+    return r += l;
+}
+
+    /// subtraction from left-hand <tt>IntType</tt> argument
+template <typename IntType>
+inline Rational<IntType>
+operator-(typename Rational<IntType>::param_type l, Rational<IntType> const & r)
+{
+    return (-r) += l;
+}
+
+    /// multiplication with left-hand <tt>IntType</tt> argument
+template <typename IntType>
+inline Rational<IntType>
+operator*(typename Rational<IntType>::param_type l, Rational<IntType> r)
+{
+    return r *= l;
+}
+
+    /// division of left-hand <tt>IntType</tt> argument
+template <typename IntType>
+inline Rational<IntType>
+operator/(typename Rational<IntType>::param_type l, Rational<IntType> const & r)
+{
+    if(r.numerator() < IntType(0))
+        return Rational<IntType>(-r.denominator(), -r.numerator(), false) *= l;
+    else
+        return Rational<IntType>(r.denominator(), r.numerator(), false) *= l;
+}
+
+/********************************************************/
+/*                                                      */
+/*                        comparison                    */
+/*                                                      */
+/********************************************************/
+
+
+    /// equality
+template <typename IntType1, typename IntType2>
+inline bool
+operator== (const Rational<IntType1> & l, const Rational<IntType2>& r)
+{
+    return l.denominator() == r.denominator() &&
+           l.numerator() == r.numerator(); // works since numbers are normalized, even
+                                           // if they represent +-infinity
+}
+
+    /// equality with right-hand <tt>IntType2</tt> argument
+template <typename IntType1, typename IntType2>
+inline bool
+operator== (const Rational<IntType1> & l, IntType2 const & i)
+{
+    return ((l.denominator() == IntType1(1)) && (l.numerator() == i));
+}
+
+    /// equality with left-hand <tt>IntType1</tt> argument
+template <typename IntType1, typename IntType2>
+inline bool
+operator==(IntType1 const & l, Rational<IntType2> const & r)
+{
+    return r == l;
+}
+
+    /// inequality
+template <typename IntType1, typename IntType2>
+inline bool
+operator!=(Rational<IntType1> const & l, Rational<IntType2> const & r)
+{
+    return l.denominator() != r.denominator() ||
+           l.numerator() != r.numerator(); // works since numbers are normalized, even
+                                           // if they represent +-infinity
+}
+
+    /// inequality with right-hand <tt>IntType2</tt> argument
+template <typename IntType1, typename IntType2>
+inline bool
+operator!= (const Rational<IntType1> & l, IntType2 const & i)
+{
+    return ((l.denominator() != IntType1(1)) || (l.numerator() != i));
+}
+
+    /// inequality with left-hand <tt>IntType1</tt> argument
+template <typename IntType1, typename IntType2>
+inline bool
+operator!=(IntType1 const & l, Rational<IntType2> const & r)
+{
+    return r != l;
+}
+
+    /// less-than
+template <typename IntType1, typename IntType2>
+bool
+operator< (const Rational<IntType1> & l, const Rational<IntType2>& r)
+{
+    // Avoid repeated construction
+    typedef typename PromoteTraits<IntType1, IntType2>::Promote IntType;
+    IntType zero(0);
+
+    // Handle the easy cases. Take advantage of the fact
+    // that the denominator is never negative.
+    if(l.denominator() == zero)
+    {
+        if(r.denominator() == zero)
+            // -inf < inf, !(-inf < -inf), !(inf < -inf), !(inf < inf)
+            return l.numerator() < r.numerator();
+        else
+            // -inf < -1, -inf < 0, -inf < 1
+            // !(inf < -1), !(inf < 0), !(inf < 1)
+            return l.numerator() < zero;
+    }
+    if(r.denominator() == zero)
+        // -1 < inf, 0 < inf, 1 < inf
+        // !(-1 < -inf), !(0 < -inf), !(1 < -inf)
+        return r.numerator() > zero;
+    // !(1 < -1), !(1 < 0), !(0 < -1), !(0 < 0)
+    if(l.numerator() >= zero && r.numerator() <= zero)
+        return false;
+    // -1 < 0, -1 < 1, 0 < 1 (note: !(0 < 0) was already handled!)
+    if(l.numerator() <= zero && r.numerator() >= zero)
+        return true;
+
+    // both numbers have the same sign (and are neither zero or +-infinity)
+    // => calculate result, avoid overflow
+    IntType gcd1 = gcd<IntType>(l.numerator(), r.numerator());
+    IntType gcd2 = gcd<IntType>(r.denominator(), l.denominator());
+    return (l.numerator()/gcd1) * (r.denominator()/gcd2) <
+           (l.denominator()/gcd2) * (r.numerator()/gcd1);
+}
+
+    /// less-than with right-hand <tt>IntType2</tt> argument
+template <typename IntType1, typename IntType2>
+bool
+operator< (const Rational<IntType1> & l, IntType2 const & i)
+{
+    // Avoid repeated construction
+    typedef typename PromoteTraits<IntType1, IntType2>::Promote IntType;
+    IntType zero(0);
+
+    // Handle the easy cases. Take advantage of the fact
+    // that the denominator is never negative.
+    if(l.denominator() == zero)
+        // -inf < -1, -inf < 0, -inf < 1
+        // !(inf < -1), !(inf < 0), !(inf < 1)
+        return l.numerator() < zero;
+    // !(1 < -1), !(1 < 0), !(0 < -1), !(0 < 0)
+    if(l.numerator() >= zero && i <= zero)
+        return false;
+    // -1 < 0, -1 < 1, 0 < 1 (note: !(0 < 0) was already handled!)
+    if(l.numerator() <= zero && i >= zero)
+        return true;
+
+    // Now, use the fact that n/d truncates towards zero as long as n and d
+    // are both positive.
+    // Divide instead of multiplying to avoid overflow issues. Of course,
+    // division may be slower, but accuracy is more important than speed...
+    if (l.numerator() > zero)
+        return (l.numerator()/l.denominator()) < i;
+    else
+        return -i < (-l.numerator()/l.denominator());
+}
+
+    /// less-than with left-hand <tt>IntType1</tt> argument
+template <typename IntType1, typename IntType2>
+inline bool
+operator<(IntType1 const & l, Rational<IntType2> const & r)
+{
+    return r > l;
+}
+
+    /// greater-than
+template <typename IntType1, typename IntType2>
+inline bool
+operator>(Rational<IntType1> const & l, Rational<IntType2> const & r)
+{
+    return r < l;
+}
+
+    /// greater-than with right-hand <tt>IntType2</tt> argument
+template <typename IntType1, typename IntType2>
+bool
+operator> (const Rational<IntType1> & l, IntType2 const & i)
+{
+    // Trap equality first
+    if (l.numerator() == i && l.denominator() == IntType1(1))
+        return false;
+
+    // Otherwise, we can use operator<
+    return !(l < i);
+}
+
+    /// greater-than with left-hand <tt>IntType1</tt> argument
+template <typename IntType1, typename IntType2>
+inline bool
+operator>(IntType1 const & l, Rational<IntType2> const & r)
+{
+    return r < l;
+}
+
+    /// less-equal
+template <typename IntType1, typename IntType2>
+inline bool
+operator<=(Rational<IntType1> const & l, Rational<IntType2> const & r)
+{
+    return !(r < l);
+}
+
+    /// less-equal with right-hand <tt>IntType2</tt> argument
+template <typename IntType1, typename IntType2>
+inline bool
+operator<=(Rational<IntType1> const & l, IntType2 const & r)
+{
+    return !(l > r);
+}
+
+    /// less-equal with left-hand <tt>IntType1</tt> argument
+template <typename IntType1, typename IntType2>
+inline bool
+operator<=(IntType1 const & l, Rational<IntType2> const & r)
+{
+    return r >= l;
+}
+
+    /// greater-equal
+template <typename IntType1, typename IntType2>
+inline bool
+operator>=(Rational<IntType1> const & l, Rational<IntType2> const & r)
+{
+    return !(l < r);
+}
+
+    /// greater-equal with right-hand <tt>IntType2</tt> argument
+template <typename IntType1, typename IntType2>
+inline bool
+operator>=(Rational<IntType1> const & l, IntType2 const & r)
+{
+    return !(l < r);
+}
+
+    /// greater-equal with left-hand <tt>IntType1</tt> argument
+template <typename IntType1, typename IntType2>
+inline bool
+operator>=(IntType1 const & l, Rational<IntType2> const & r)
+{
+    return r <= l;
+}
+
+/********************************************************/
+/*                                                      */
+/*                 algebraic functions                  */
+/*                                                      */
+/********************************************************/
+
+    /// absolute value
+template <typename IntType>
+inline Rational<IntType>
+abs(const Rational<IntType>& r)
+{
+    if (r.numerator() >= IntType(0))
+        return r;
+
+    return Rational<IntType>(-r.numerator(), r.denominator(), false);
+}
+
+    /// norm (same as <tt>abs(r)</tt>)
+template <typename IntType>
+inline Rational<IntType>
+norm(const Rational<IntType>& r)
+{
+    return abs(r);
+}
+
+    /// squared norm
+template <typename IntType>
+inline typename NormTraits<Rational<IntType> >::SquaredNormType
+squaredNorm(const Rational<IntType>& r)
+{
+    return typename NormTraits<Rational<IntType> >::SquaredNormType(sq(r.numerator()), sq(r.denominator()), false);
+}
+
+    /** integer powers
+
+        <tt>throws bad_rational</tt> if indeterminate expression.
+    */
+template <typename IntType>
+Rational<IntType>
+pow(const Rational<IntType>& r, int e)
+{
+    IntType zero(0);
+    int ae;
+    if(e == 0)
+    {
+        if(r.denominator() == zero)
+                throw bad_rational();
+        return Rational<IntType>(IntType(1));
+    }
+    else if(e < 0)
+    {
+        if(r.numerator() == zero)
+            return Rational<IntType>(IntType(1), zero, false);
+        if(r.denominator() == zero)
+            return Rational<IntType>(zero);
+        ae = -e;
+    }
+    else
+    {
+        if(r.denominator() == zero || r.numerator() == zero)
+            return r;
+        ae = e;
+    }
+
+    IntType nold = r.numerator(), dold = r.denominator(),
+            nnew = IntType(1), dnew = IntType(1);
+    for(; ae != 0; ae >>= 1, nold *= nold, dold *= dold)
+    {
+        if(ae % 2 != 0)
+        {
+            nnew *= nold;
+            dnew *= dold;
+        }
+    }
+    if(e < 0)
+    {
+        if(nnew < zero)
+            return Rational<IntType>(-dnew, -nnew, false);
+        else
+            return Rational<IntType>(dnew, nnew, false);
+    }
+    else
+        return Rational<IntType>(nnew, dnew, false);
+}
+
+    /// largest integer not larger than <tt>r</tt>
+template <typename IntType>
+Rational<IntType>
+floor(const Rational<IntType>& r)
+{
+    IntType zero(0), one(1);
+    if(r.denominator() == zero || r.denominator() == one)
+        return r;
+    return r.numerator() < zero ?
+                   Rational<IntType>(r.numerator() / r.denominator() - one)
+                 : Rational<IntType>(r.numerator() / r.denominator());
+}
+
+    /// smallest integer not smaller than <tt>r</tt>
+template <typename IntType>
+Rational<IntType>
+ceil(const Rational<IntType>& r)
+{
+    IntType zero(0), one(1);
+    if(r.denominator() == zero || r.denominator() == one)
+        return r;
+    return r.numerator() < IntType(0) ?
+                   Rational<IntType>(r.numerator() / r.denominator())
+                 : Rational<IntType>(r.numerator() / r.denominator() + one);
+}
+
+
+    /** Type conversion
+
+        Executes <tt>static_cast<T>(numerator()) / denominator()</tt>.
+
+        <b>Usage:</b>
+
+        \code
+        Rational<int> r;
+        int i;
+        double d;
+        i = rational_cast<int>(r);     // round r downwards
+        d = rational_cast<double>(r);  // represent rational as a double
+        r = rational_cast<Rational<int> >(r);   // no change
+        \endcode
+    */
+template <typename T, typename IntType>
+inline T rational_cast(const Rational<IntType>& src)
+{
+    return static_cast<T>(src.numerator())/src.denominator();
+}
+
+template <class T>
+inline T const & rational_cast(T const & v)
+{
+    return v;
+}
+
+//@}
+
+template <typename IntType>
+std::ostream& operator<< (std::ostream& os, const vigra::Rational<IntType>& r)
+{
+    os << r.numerator() << '/' << r.denominator();
+    return os;
+}
+
+} // namespace vigra
+
+#endif  // VIGRA_RATIONAL_HPP
+
diff --git a/include/vigra/recursiveconvolution.hxx b/include/vigra/recursiveconvolution.hxx
new file mode 100644
index 0000000..8705631
--- /dev/null
+++ b/include/vigra/recursiveconvolution.hxx
@@ -0,0 +1,2229 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_RECURSIVECONVOLUTION_HXX
+#define VIGRA_RECURSIVECONVOLUTION_HXX
+
+#include <cmath>
+#include <vector>
+#include "utilities.hxx"
+#include "numerictraits.hxx"
+#include "imageiteratoradapter.hxx"
+#include "bordertreatment.hxx"
+#include "array_vector.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/********************************************************/
+/*                                                      */
+/*         Recursive convolution functions              */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup RecursiveConvolution Recursive convolution functions
+    
+    First order recursive filters and their specialization for 
+    the exponential filter and its derivatives (1D and separable 2D).
+    These filters are very fast, and the speed does not depend on the 
+    filter size. 
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                   recursiveFilterLine                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs a 1-dimensional recursive convolution of the source signal.
+
+    The function performs a causal and an anti-causal first or second order 
+    recursive filtering with the given filter parameter <TT>b1</TT> and 
+    border treatment <TT>border</TT> (first order filter, <TT>b2 = 0</TT>) or parameters 
+    <TT>b1, b2</TT> and <TT>BORDER_TREATMENT_REFLECT</TT> (second order filter). Thus, 
+    the result is always a filtering with linear phase.
+    \f[
+        \begin{array}{rcl}
+        a_{i, causal} & = & source_i + b1 * a_{i-1, causal} + b2 * a_{i-2, causal} \\
+        a_{i, anticausal} & = & source_i + b1 * a_{i+1, anticausal} + b2 * a_{i+2, anticausal} \\
+        dest_i & = & \frac{1 - b1 - b2}{1 + b1 + b2}(a_{i, causal} + a_{i, anticausal} - source_i)
+        \end{array}
+    \f]
+   
+    The signal's value_type (SrcAccessor::value_type) must be a
+    linear space over <TT>double</TT>,
+    i.e. addition of source values, multiplication with <TT>double</TT>,
+    and <TT>NumericTraits</TT> must be defined.     
+    
+    <b> Declaration:</b>
+    
+    <b>First order recursive filter:</b>
+    
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+              class DestIterator, class DestAccessor>
+        void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                     DestIterator id, DestAccessor ad, 
+                     double b1, BorderTreatmentMode border)
+    }
+    \endcode
+    
+    <b>Second order recursive filter:</b>
+    
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+              class DestIterator, class DestAccessor>
+        void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                     DestIterator id, DestAccessor ad, 
+                     double b1, double b2)
+    }
+    \endcode
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+    
+    
+    \code
+    vector<float> src, dest;    
+    ...
+    
+    DefaultAccessor<vector<float>::iterator, float> FAccessor;
+    
+    
+    recursiveFilterLine(src.begin(), src.end(), FAccessor(), 
+                        dest.begin(), FAccessor(), 
+                        0.5, BORDER_TREATMENT_REFLECT);
+    \endcode
+
+    <b> Required Interface:</b>
+    
+    \code
+    RandomAccessIterator is, isend;
+    RandomAccessIterator id;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    
+    NumericTraits<SrcAccessor::value_type>::RealPromote s = src_accessor(is);
+    double d;
+    
+    s = s + s;
+    s = d * s;
+
+    dest_accessor.set(
+        NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id);
+    \endcode
+
+    <b> Preconditions:</b>
+    
+    \code
+    -1 < b  < 1
+    \endcode
+
+*/
+doxygen_overloaded_function(template <...> void recursiveFilterLine)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                         DestIterator id, DestAccessor ad, double b, BorderTreatmentMode border)
+{
+    int w = isend - is;
+    SrcIterator istart = is;
+    
+    int x;
+    
+    vigra_precondition(-1.0 < b && b < 1.0,
+                 "recursiveFilterLine(): -1 < factor < 1 required.\n");
+                 
+    // trivial case: b == 0.0 is an identity filter => simply copy the data and return
+    if(b == 0.0)
+    {
+        for(; is != isend; ++is, ++id)
+        {
+            ad.set(as(is), id);
+        }
+        return;
+    }
+
+    double eps = 0.00001;
+    int kernelw = std::min(w-1, (int)(VIGRA_CSTD::log(eps)/VIGRA_CSTD::log(VIGRA_CSTD::fabs(b))));
+    
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote TempType;
+    typedef NumericTraits<typename DestAccessor::value_type> DestTraits;
+    typedef typename DestTraits::RealPromote RealPromote;
+    
+    // store result of causal filtering
+    std::vector<TempType> vline(w);
+    typename std::vector<TempType>::iterator line = vline.begin();
+    
+    double norm = (1.0 - b) / (1.0 + b);
+
+    TempType old;
+    
+    if(border == BORDER_TREATMENT_REPEAT ||
+       border == BORDER_TREATMENT_AVOID)
+    {
+         old = TempType((1.0 / (1.0 - b)) * as(is));
+    }
+    else if(border == BORDER_TREATMENT_REFLECT)
+    {
+        is += kernelw;
+        old = TempType((1.0 / (1.0 - b)) * as(is));
+        for(x = 0; x < kernelw; ++x, --is)
+            old = TempType(as(is) + b * old);
+    }
+    else if(border == BORDER_TREATMENT_WRAP)
+    {
+        is = isend - kernelw; 
+        old = TempType((1.0 / (1.0 - b)) * as(is));
+        for(x = 0; x < kernelw; ++x, ++is)
+            old = TempType(as(is) + b * old);
+    }
+    else if(border == BORDER_TREATMENT_CLIP ||
+            border == BORDER_TREATMENT_ZEROPAD)
+    {
+        old = NumericTraits<TempType>::zero();
+    }
+    else
+    {
+        vigra_fail("recursiveFilterLine(): Unknown border treatment mode.\n");
+        old = NumericTraits<TempType>::zero(); // fix a stupid warning
+    }
+
+    // left side of filter
+    for(x=0, is = istart; x < w; ++x, ++is)
+    {
+        old = TempType(as(is) + b * old);
+        line[x] = old;
+    }
+
+    // right side of the filter
+    if(border == BORDER_TREATMENT_REPEAT ||
+       border == BORDER_TREATMENT_AVOID)
+    {
+        is = isend - 1;
+        old = TempType((1.0 / (1.0 - b)) * as(is));
+    }
+    else if(border == BORDER_TREATMENT_REFLECT)
+    {
+        old = line[w-2];
+    }
+    else if(border == BORDER_TREATMENT_WRAP)
+    {
+      is = istart + kernelw - 1;
+      old = TempType((1.0 / (1.0 - b)) * as(is));
+      for(x = 0; x < kernelw; ++x, --is)
+          old = TempType(as(is) + b * old);
+    }
+    else if(border == BORDER_TREATMENT_CLIP ||
+            border == BORDER_TREATMENT_ZEROPAD)
+    {
+        old = NumericTraits<TempType>::zero();
+    }
+    
+    is = isend - 1;
+    id += w - 1;
+    if(border == BORDER_TREATMENT_CLIP)
+    {    
+       // correction factors for b
+        double bright = b;
+        double bleft = VIGRA_CSTD::pow(b, w);
+
+        for(x=w-1; x>=0; --x, --is, --id)
+        {    
+            TempType f = TempType(b * old);
+            old = as(is) + f;
+            double norm = (1.0 - b) / (1.0 + b - bleft - bright);
+            bleft /= b;
+            bright *= b;
+            ad.set(norm * (line[x] + f), id);
+        }
+    }
+    else if(border == BORDER_TREATMENT_AVOID)
+    {
+        for(x=w-1; x >= kernelw; --x, --is, --id)
+        {    
+            TempType f = TempType(b * old);
+            old = as(is) + f;
+            if(x < w - kernelw)
+                ad.set(DestTraits::fromRealPromote(RealPromote(norm * (line[x] + f))), id);
+        }
+    }
+    else
+    {
+        for(x=w-1; x>=0; --x, --is, --id)
+        {    
+            TempType f = TempType(b * old);
+            old = as(is) + f;
+            ad.set(DestTraits::fromRealPromote(RealPromote(norm * (line[x] + f))), id);
+        }
+    }
+}
+            
+/********************************************************/
+/*                                                      */
+/*            recursiveFilterLine (2nd order)           */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                         DestIterator id, DestAccessor ad, double b1, double b2)
+{
+    int w = isend - is;
+    int x;
+    
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote TempType;
+    
+    // speichert den Ergebnis der linkseitigen Filterung.
+    std::vector<TempType> vline(w+1);
+    typename std::vector<TempType>::iterator line = vline.begin();
+    
+    double norm  = 1.0 - b1 - b2;
+    double norm1 = (1.0 - b1 - b2) / (1.0 + b1 + b2);
+    double norm2 = norm * norm;
+    
+
+    // init left side of filter
+    int kernelw = std::min(w-1, std::max(8, (int)(1.0 / norm + 0.5)));  
+    is += (kernelw - 2);
+    line[kernelw] = as(is);
+    line[kernelw-1] = as(is);
+    for(x = kernelw - 2; x > 0; --x, --is)
+    {
+        line[x] = detail::RequiresExplicitCast<TempType>::cast(as(is) + b1 * line[x+1] + b2 * line[x+2]);
+    }
+    line[0] = detail::RequiresExplicitCast<TempType>::cast(as(is) + b1 * line[1] + b2 * line[2]);
+    ++is;
+    line[1] = detail::RequiresExplicitCast<TempType>::cast(as(is) + b1 * line[0] + b2 * line[1]);
+    ++is;
+    for(x=2; x < w; ++x, ++is)
+    {
+        line[x] = detail::RequiresExplicitCast<TempType>::cast(as(is) + b1 * line[x-1] + b2 * line[x-2]);
+    }
+    line[w] = line[w-1];
+
+    line[w-1] = detail::RequiresExplicitCast<TempType>::cast(norm1 * (line[w-1] + b1 * line[w-2] + b2 * line[w-3]));
+    line[w-2] = detail::RequiresExplicitCast<TempType>::cast(norm1 * (line[w-2] + b1 * line[w] + b2 * line[w-2]));
+    id += w-1;
+    ad.set(line[w-1], id);
+    --id;
+    ad.set(line[w-2], id);
+    --id;
+    for(x=w-3; x>=0; --x, --id, --is)
+    {    
+        line[x] = detail::RequiresExplicitCast<TempType>::cast(norm2 * line[x] + b1 * line[x+1] + b2 * line[x+2]);
+        ad.set(line[x], id);
+    }
+}
+            
+/********************************************************/
+/*                                                      */
+/*              recursiveGaussianFilterLine             */
+/*                                                      */
+/********************************************************/
+
+// AUTHOR: Sebastian Boppel
+
+/** \brief Compute a 1-dimensional recursive approximation of Gaussian smoothing.
+
+    The function applies a causal and an anti-causal third order recursive filter 
+    which optimally approximates the Gaussian filter, as proposed in
+    
+    I. Young, L. van Vliet: <i>Recursive implementation of the Gaussian filter</i><br>
+    Signal Processing 44:139-151, 1995
+    
+    The formulas for transforming the given scale parameter <tt>sigma</tt> into the actual filter coefficients
+    are taken from Luigi Rosa's Matlab implementation.
+   
+    The signal's value_type (SrcAccessor::value_type) must be a
+    linear space over <TT>double</TT>, i.e. addition of source values, multiplication with <TT>double</TT>,
+    and <TT>NumericTraits</TT> must be defined.     
+    
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void 
+        recursiveGaussianFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                                    DestIterator id, DestAccessor ad, 
+                                    double sigma);
+    }
+    \endcode
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+    
+    
+    \code
+    vector<float> src, dest;    
+    ...
+    
+    vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
+    double sigma = 2.5;
+    
+    vigra::recursiveGaussianFilterLine(src.begin(), src.end(), FAccessor(), 
+                                       dest.begin(), FAccessor(), 
+                                       sigma);
+    \endcode
+
+    <b> Required Interface:</b>
+    
+    \code
+    RandomAccessIterator is, isend;
+    RandomAccessIterator id;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    
+    NumericTraits<SrcAccessor::value_type>::RealPromote s = src_accessor(is);
+    double d;
+    
+    s = s + s;
+    s = d * s;
+
+    dest_accessor.set(
+        NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id);
+    \endcode
+
+    <b> Preconditions:</b>
+    
+    \code
+    0 <= sigma (absolute values are used for negative sigma)
+    \endcode
+
+*/
+doxygen_overloaded_function(template <...> void recursiveGaussianFilterLine)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void 
+recursiveGaussianFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                            DestIterator id, DestAccessor ad, 
+                            double sigma)
+{
+    //coefficients taken out Luigi Rosa's implementation for Matlab
+    double q = 1.31564 * (std::sqrt(1.0 + 0.490811 * sigma*sigma) - 1.0);
+    double qq = q*q;
+    double qqq = qq*q;
+    double b0 = 1.0/(1.57825 + 2.44413*q + 1.4281*qq + 0.422205*qqq);
+    double b1 = (2.44413*q + 2.85619*qq + 1.26661*qqq)*b0;
+    double b2 = (-1.4281*qq - 1.26661*qqq)*b0;
+    double b3 = 0.422205*qqq*b0;
+    double B = 1.0 - (b1 + b2 + b3);
+    
+    int w = isend - is;
+    vigra_precondition(w >= 4,
+        "recursiveGaussianFilterLine(): line must have at least length 4.");
+        
+    int kernelw = std::min(w-4, (int)(4.0*sigma));
+ 
+    int x;
+    
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote TempType;
+    
+    // speichert das Ergebnis der linkseitigen Filterung.
+    std::vector<TempType> yforward(w);
+    
+    std::vector<TempType> ybackward(w, 0.0);
+    
+    // initialise the filter for reflective boundary conditions
+    for(x=kernelw; x>=0; --x)
+    {
+        ybackward[x] = detail::RequiresExplicitCast<TempType>::cast(B*as(is, x) + (b1*ybackward[x+1]+b2*ybackward[x+2]+b3*ybackward[x+3]));
+    }
+
+    //from left to right - causal - forward
+    yforward[0] = detail::RequiresExplicitCast<TempType>::cast(B*as(is) + (b1*ybackward[1]+b2*ybackward[2]+b3*ybackward[3]));
+
+    ++is;    
+    yforward[1] = detail::RequiresExplicitCast<TempType>::cast(B*as(is) + (b1*yforward[0]+b2*ybackward[1]+b3*ybackward[2]));
+
+    ++is;
+    yforward[2] = detail::RequiresExplicitCast<TempType>::cast(B*as(is) + (b1*yforward[1]+b2*yforward[0]+b3*ybackward[1]));
+
+    ++is;
+    for(x=3; x < w; ++x, ++is)
+    {
+        yforward[x] = detail::RequiresExplicitCast<TempType>::cast(B*as(is) + (b1*yforward[x-1]+b2*yforward[x-2]+b3*yforward[x-3]));
+    }
+    
+    //from right to left - anticausal - backward
+    ybackward[w-1] = detail::RequiresExplicitCast<TempType>::cast(B*yforward[w-1] + (b1*yforward[w-2]+b2*yforward[w-3]+b3*yforward[w-4]));
+        
+    ybackward[w-2] = detail::RequiresExplicitCast<TempType>::cast(B*yforward[w-2] + (b1*ybackward[w-1]+b2*yforward[w-2]+b3*yforward[w-3]));
+    
+    ybackward[w-3] = detail::RequiresExplicitCast<TempType>::cast(B*yforward[w-3] + (b1*ybackward[w-2]+b2*ybackward[w-1]+b3*yforward[w-2]));
+    
+    for(x=w-4; x>=0; --x)
+    {
+        ybackward[x] = detail::RequiresExplicitCast<TempType>::cast(B*yforward[x]+(b1*ybackward[x+1]+b2*ybackward[x+2]+b3*ybackward[x+3]));
+    }
+
+    // output
+    for(x=0; x < w; ++x, ++id)
+    {
+        ad.set(ybackward[x], id);
+    }
+}
+
+            
+/********************************************************/
+/*                                                      */
+/*                    recursiveSmoothLine               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Convolves the image with a 1-dimensional exponential filter.
+
+    This function calls \ref recursiveFilterLine() with <TT>b = exp(-1.0/scale)</TT>
+    and <TT>border = BORDER_TREATMENT_REPEAT</TT>. See 
+    \ref recursiveFilterLine() for more documentation.
+    
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+              class DestIterator, class DestAccessor>
+        void recursiveSmoothLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                     DestIterator id, DestAccessor ad, double scale)
+    }
+    \endcode
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+    
+    
+    \code
+    vector<float> src, dest;    
+    ...
+    
+    vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
+    
+    
+    vigra::recursiveSmoothLine(src.begin(), src.end(), FAccessor(), 
+                        dest.begin(), FAccessor(), 3.0);
+    \endcode
+
+    <b> Required Interface:</b>
+    
+    \code
+    RandomAccessIterator is, isend;
+    RandomAccessIterator id;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    
+    NumericTraits<SrcAccessor::value_type>::RealPromote s = src_accessor(is);
+    double d;
+    
+    s = s + s;
+    s = d * s;
+
+    dest_accessor.set(
+        NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id);
+    \endcode
+
+    <b> Preconditions:</b>
+    
+    \code
+    scale > 0
+    \endcode
+
+*/
+doxygen_overloaded_function(template <...> void recursiveSmoothLine)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline 
+void recursiveSmoothLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                         DestIterator id, DestAccessor ad, double scale)
+{
+    vigra_precondition(scale >= 0,
+                 "recursiveSmoothLine(): scale must be >= 0.\n");
+                 
+    double b = (scale == 0.0) ? 
+                    0.0 :
+                    VIGRA_CSTD::exp(-1.0/scale);
+    
+    recursiveFilterLine(is, isend, as, id, ad, b, BORDER_TREATMENT_REPEAT);
+}
+            
+/********************************************************/
+/*                                                      */
+/*             recursiveFirstDerivativeLine             */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs a 1 dimensional recursive convolution of the source signal.
+
+    It uses the first derivative an exponential  <TT>d/dx exp(-abs(x)/scale)</TT> as 
+    a kernel. The signal's value_type (SrcAccessor::value_type) must be a
+    linear space over <TT>double</TT>,
+    i.e. addition and subtraction of source values, multiplication with 
+    <TT>double</TT>, and <TT>NumericTraits</TT> must be defined. Border 
+    treatment is always <TT>BORDER_TREATMENT_REPEAT</TT>.
+    
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+              class DestIterator, class DestAccessor>
+        void recursiveFirstDerivativeLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                     DestIterator id, DestAccessor ad, double scale)
+    }
+    \endcode
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+    
+    
+    \code
+    vector<float> src, dest;    
+    ...
+    
+    vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
+    
+    
+    vigra::recursiveFirstDerivativeLine(src.begin(), src.end(), FAccessor(), 
+                        dest.begin(), FAccessor(), 3.0);
+    \endcode
+
+    <b> Required Interface:</b>
+    
+    \code
+    RandomAccessIterator is, isend;
+    RandomAccessIterator id;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    
+    NumericTraits<SrcAccessor::value_type>::RealPromote s = src_accessor(is);
+    double d;
+    
+    s = s + s;
+    s = -s;
+    s = d * s;
+
+    dest_accessor.set(
+        NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id);
+    \endcode
+
+    <b> Preconditions:</b>
+    
+    \code
+    scale > 0
+    \endcode
+
+*/
+doxygen_overloaded_function(template <...> void recursiveFirstDerivativeLine)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void recursiveFirstDerivativeLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                         DestIterator id, DestAccessor ad, double scale)
+{
+    vigra_precondition(scale > 0,
+                 "recursiveFirstDerivativeLine(): scale must be > 0.\n");
+
+    int w = isend -is;
+    
+    int x;
+    
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote 
+    TempType;
+    typedef NumericTraits<typename DestAccessor::value_type> DestTraits;
+
+    std::vector<TempType> vline(w);
+    typename std::vector<TempType>::iterator line = vline.begin();
+    
+    double b = VIGRA_CSTD::exp(-1.0/scale);
+    double norm = (1.0 - b) * (1.0 - b) / 2.0 / b;
+    TempType old = (1.0 / (1.0 - b)) * as(is);
+
+    // left side of filter
+    for(x=0; x<w; ++x, ++is)
+    {
+        old = as(is) + b * old;
+        line[x] = -old;
+    }
+    
+    // right side of the filter
+    --is;
+    old = (1.0 / (1.0 - b)) * as(is);
+    id += w;
+    ++is;
+    
+    for(x=w-1; x>=0; --x)
+    {    
+        --is;
+        --id;
+
+        old = as(is) + b * old;
+
+        ad.set(DestTraits::fromRealPromote(norm * (line[x] + old)), id);
+    }
+}
+            
+/********************************************************/
+/*                                                      */
+/*            recursiveSecondDerivativeLine             */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs a 1 dimensional recursive convolution of the source signal.
+
+    It uses the second derivative an exponential  <TT>d2/dx2 exp(-abs(x)/scale)</TT> as 
+    a kernel. The signal's value_type (SrcAccessor::value_type) must be a
+    linear space over <TT>double</TT>,
+    i.e. addition and subtraction of source values, multiplication with 
+    <TT>double</TT>, and <TT>NumericTraits</TT> must be defined. Border 
+    treatment is always <TT>BORDER_TREATMENT_REPEAT</TT>.
+    
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+              class DestIterator, class DestAccessor>
+        void recursiveSecondDerivativeLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                     DestIterator id, DestAccessor ad, double scale)
+    }
+    \endcode
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+    
+    
+    \code
+    vector<float> src, dest;    
+    ...
+    
+    vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
+    
+    
+    vigra::recursiveSecondDerivativeLine(src.begin(), src.end(), FAccessor(), 
+                        dest.begin(), FAccessor(), 3.0);
+    \endcode
+
+    <b> Required Interface:</b>
+    
+    \code
+    RandomAccessIterator is, isend;
+    RandomAccessIterator id;
+    
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    
+    NumericTraits<SrcAccessor::value_type>::RealPromote s = src_accessor(is);
+    double d;
+    
+    s = s + s;
+    s = s - s;
+    s = d * s;
+
+    dest_accessor.set(
+        NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id);
+    \endcode
+
+    <b> Preconditions:</b>
+    
+    \code
+    scale > 0
+    \endcode
+
+*/
+doxygen_overloaded_function(template <...> void recursiveSecondDerivativeLine)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void recursiveSecondDerivativeLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
+                         DestIterator id, DestAccessor ad, double scale)
+{
+    vigra_precondition(scale > 0,
+                 "recursiveSecondDerivativeLine(): scale must be > 0.\n");
+
+    int w = isend -is;
+    
+    int x;
+    
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote 
+    TempType;
+    typedef NumericTraits<typename DestAccessor::value_type> DestTraits;
+    
+    std::vector<TempType> vline(w);
+    typename std::vector<TempType>::iterator line = vline.begin();
+        
+    double b = VIGRA_CSTD::exp(-1.0/scale);
+    double a = -2.0 / (1.0 - b);
+    double norm = (1.0 - b) * (1.0 - b) * (1.0 - b) / (1.0 + b);
+    TempType old = detail::RequiresExplicitCast<TempType>::cast((1.0 / (1.0 - b)) * as(is));
+
+    // left side of filter
+    for(x=0; x<w; ++x, ++is)
+    {
+        line[x] = old;
+        old = detail::RequiresExplicitCast<TempType>::cast(as(is) + b * old);
+    }
+    
+    // right side of the filter
+    --is;
+    old = detail::RequiresExplicitCast<TempType>::cast((1.0 / (1.0 - b)) * as(is));
+    id += w;
+    ++is;
+    
+    for(x=w-1; x>=0; --x)
+    {    
+        --is;
+        --id;
+
+        TempType f = detail::RequiresExplicitCast<TempType>::cast(old + a * as(is));
+        old = detail::RequiresExplicitCast<TempType>::cast(as(is) + b * old);
+        ad.set(DestTraits::fromRealPromote(detail::RequiresExplicitCast<TempType>::cast(norm * (line[x] + f))), id);
+    }
+}
+            
+/********************************************************/
+/*                                                      */
+/*                   recursiveFilterX                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs 1 dimensional recursive filtering (1st and 2nd order) in x direction.
+
+    It calls \ref recursiveFilterLine() for every row of the
+    image. See \ref recursiveFilterLine() for more information about 
+    required interfaces and vigra_preconditions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // first order filter
+        template <class T1, class S1,
+                  class T2, class S2>
+        void 
+        recursiveFilterX(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest, 
+                         double b, BorderTreatmentMode border);
+                         
+        // second order filter
+        template <class T1, class S1,
+                  class T2, class S2>
+        void 
+        recursiveFilterX(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest, 
+                         double b1, double b2);
+    }
+    \endcode
+    
+    \deprecatedAPI{recursiveFilterX}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // first order filter
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void recursiveFilterX(SrcImageIterator supperleft, 
+                               SrcImageIterator slowerright, SrcAccessor as,
+                               DestImageIterator dupperleft, DestAccessor ad, 
+                               double b, BorderTreatmentMode border);
+
+        // second order filter
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void recursiveFilterX(SrcImageIterator supperleft, 
+                               SrcImageIterator slowerright, SrcAccessor as,
+                               DestImageIterator dupperleft, DestAccessor ad, 
+                               double b1, double b2);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // first order filter
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void recursiveFilterX(
+                    triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                    pair<DestImageIterator, DestAccessor> dest, 
+                    double b, BorderTreatmentMode border);
+
+        // second order filter
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void recursiveFilterX(
+                    triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                    pair<DestImageIterator, DestAccessor> dest, 
+                    double b1, double b2);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);    
+    ...
+    
+    // apply a first-order filter to the x-axis
+    recursiveFilterX(src, dest, 0.5, BORDER_TREATMENT_REFLECT);
+    \endcode
+
+    \deprecatedUsage{recursiveFilterX}
+    \code
+    vigra::FImage src(w,h), dest(w,h);    
+    ...
+    
+    vigra::recursiveFilterX(srcImageRange(src), destImage(dest), 
+           0.5, BORDER_TREATMENT_REFLECT);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void recursiveFilterX)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void recursiveFilterX(SrcImageIterator supperleft, 
+                       SrcImageIterator slowerright, SrcAccessor as,
+                       DestImageIterator dupperleft, DestAccessor ad, 
+                       double b, BorderTreatmentMode border)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int y;
+    
+    for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
+    {
+        typename SrcImageIterator::row_iterator rs = supperleft.rowIterator();
+        typename DestImageIterator::row_iterator rd = dupperleft.rowIterator();
+
+        recursiveFilterLine(rs, rs+w, as, 
+                             rd, ad, 
+                             b, border);
+    }
+}
+            
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void 
+recursiveFilterX(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                 pair<DestImageIterator, DestAccessor> dest, 
+                 double b, BorderTreatmentMode border)
+{
+    recursiveFilterX(src.first, src.second, src.third,
+                     dest.first, dest.second, b, border);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void 
+recursiveFilterX(MultiArrayView<2, T1, S1> const & src,
+                 MultiArrayView<2, T2, S2> dest, 
+                 double b, BorderTreatmentMode border)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveFilterX(): shape mismatch between input and output.");
+    recursiveFilterX(srcImageRange(src),
+                     destImage(dest), b, border);
+}
+
+/********************************************************/
+/*                                                      */
+/*            recursiveFilterX (2nd order)              */
+/*                                                      */
+/********************************************************/
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void recursiveFilterX(SrcImageIterator supperleft, 
+                       SrcImageIterator slowerright, SrcAccessor as,
+                       DestImageIterator dupperleft, DestAccessor ad, 
+                       double b1, double b2)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int y;
+    
+    for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
+    {
+        typename SrcImageIterator::row_iterator rs = supperleft.rowIterator();
+        typename DestImageIterator::row_iterator rd = dupperleft.rowIterator();
+
+        recursiveFilterLine(rs, rs+w, as, 
+                             rd, ad, 
+                             b1, b2);
+    }
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void 
+recursiveFilterX(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                 pair<DestImageIterator, DestAccessor> dest, 
+                 double b1, double b2)
+{
+    recursiveFilterX(src.first, src.second, src.third,
+                     dest.first, dest.second, b1, b2);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void 
+recursiveFilterX(MultiArrayView<2, T1, S1> const & src,
+                 MultiArrayView<2, T2, S2> dest, 
+                 double b1, double b2)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveFilterX(): shape mismatch between input and output.");
+    recursiveFilterX(srcImageRange(src),
+                     destImage(dest), b1, b2);
+}
+
+/********************************************************/
+/*                                                      */
+/*               recursiveGaussianFilterX               */
+/*                                                      */
+/********************************************************/
+
+// AUTHOR: Sebastian Boppel
+
+/** \brief Compute 1 dimensional recursive approximation of Gaussian smoothing in y direction.
+
+    It calls \ref recursiveGaussianFilterLine() for every column of the
+    image. See \ref recursiveGaussianFilterLine() for more information about 
+    required interfaces and vigra_preconditions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void 
+        recursiveGaussianFilterX(MultiArrayView<2, T1, S1> const & src,
+                                 MultiArrayView<2, T2, S2> dest, 
+                                 double sigma);
+    }
+    \endcode
+    
+    \deprecatedAPI{recursiveGaussianFilterX}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void 
+        recursiveGaussianFilterX(SrcImageIterator supperleft, SrcImageIterator slowerright, SrcAccessor as,
+                                 DestImageIterator dupperleft, DestAccessor ad, 
+                                 double sigma);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void 
+        recursiveGaussianFilterX(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                                 pair<DestImageIterator, DestAccessor> dest, 
+                                 double sigma);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);    
+    ...
+    
+    recursiveGaussianFilterX(src, dest, 3.0);
+    \endcode
+
+    \deprecatedUsage{recursiveGaussianFilterX}
+    \code
+    vigra::FImage src(w,h), dest(w,h);    
+    ...
+    
+    vigra::recursiveGaussianFilterX(srcImageRange(src), destImage(dest), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void recursiveGaussianFilterX)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void 
+recursiveGaussianFilterX(SrcImageIterator supperleft, SrcImageIterator slowerright, SrcAccessor as,
+                         DestImageIterator dupperleft, DestAccessor ad, 
+                         double sigma)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int y;
+    
+    for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
+    {
+        typename SrcImageIterator::row_iterator rs = supperleft.rowIterator();
+        typename DestImageIterator::row_iterator rd = dupperleft.rowIterator();
+
+        recursiveGaussianFilterLine(rs, rs+w, as, 
+                                    rd, ad, 
+                                    sigma);
+    }
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void 
+recursiveGaussianFilterX(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                         pair<DestImageIterator, DestAccessor> dest, 
+                         double sigma)
+{
+    recursiveGaussianFilterX(src.first, src.second, src.third,
+                             dest.first, dest.second, sigma);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void 
+recursiveGaussianFilterX(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest, 
+                         double sigma)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveGaussianFilterX(): shape mismatch between input and output.");
+    recursiveGaussianFilterX(srcImageRange(src),
+                             destImage(dest), sigma);
+}
+
+/********************************************************/
+/*                                                      */
+/*                    recursiveSmoothX                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs 1 dimensional recursive smoothing in x direction.
+
+    It calls \ref recursiveSmoothLine() for every row of the
+    image. See \ref recursiveSmoothLine() for more information about 
+    required interfaces and vigra_preconditions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        recursiveSmoothX(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest, 
+                         double scale);
+    }
+    \endcode
+    
+    \deprecatedAPI{recursiveSmoothX}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveSmoothX(SrcImageIterator supperleft, 
+                  SrcImageIterator slowerright, SrcAccessor as,
+                  DestImageIterator dupperleft, DestAccessor ad, 
+                  double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveSmoothX(
+            triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+            pair<DestImageIterator, DestAccessor> dest, 
+            double scale)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);    
+    ...
+    
+    recursiveSmoothX(src, dest, 3.0);
+    \endcode
+
+    \deprecatedUsage{recursiveGaussianFilterX}
+    \code
+    vigra::FImage src(w,h), dest(w,h);    
+    ...
+    
+    vigra::recursiveSmoothX(srcImageRange(src), destImage(dest), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void recursiveSmoothX)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void recursiveSmoothX(SrcImageIterator supperleft, 
+                      SrcImageIterator slowerright, SrcAccessor as,
+                      DestImageIterator dupperleft, DestAccessor ad, 
+                      double scale)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int y;
+    
+    for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
+    {
+        typename SrcImageIterator::row_iterator rs = supperleft.rowIterator();
+        typename DestImageIterator::row_iterator rd = dupperleft.rowIterator();
+
+        recursiveSmoothLine(rs, rs+w, as, 
+                            rd, ad, 
+                            scale);
+    }
+}
+            
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void
+recursiveSmoothX(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                 pair<DestImageIterator, DestAccessor> dest, 
+                 double scale)
+{
+    recursiveSmoothX(src.first, src.second, src.third,
+                     dest.first, dest.second, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+recursiveSmoothX(MultiArrayView<2, T1, S1> const & src,
+                 MultiArrayView<2, T2, S2> dest, 
+                 double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveSmoothX(): shape mismatch between input and output.");
+    recursiveSmoothX(srcImageRange(src),
+                     destImage(dest), scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*                     recursiveFilterY                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs 1 dimensional recursive filtering (1st and 2nd order) in y direction.
+
+    It calls \ref recursiveFilterLine() for every column of the
+    image. See \ref recursiveFilterLine() for more information about 
+    required interfaces and vigra_preconditions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        // first order filter
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        recursiveFilterY(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest, 
+                         double b, BorderTreatmentMode border);
+                         
+        // second order filter
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        recursiveFilterY(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest, 
+                         double b1, double b2);
+    }
+    \endcode
+    
+    \deprecatedAPI{recursiveFilterY}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        // first order filter
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void recursiveFilterY(SrcImageIterator supperleft, 
+                               SrcImageIterator slowerright, SrcAccessor as,
+                               DestImageIterator dupperleft, DestAccessor ad, 
+                               double b, BorderTreatmentMode border);
+
+        // second order filter
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void recursiveFilterY(SrcImageIterator supperleft, 
+                               SrcImageIterator slowerright, SrcAccessor as,
+                               DestImageIterator dupperleft, DestAccessor ad, 
+                               double b1, double b2);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        // first order filter
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void recursiveFilterY(
+                    triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                    pair<DestImageIterator, DestAccessor> dest, 
+                    double b, BorderTreatmentMode border);
+
+        // second order filter
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void recursiveFilterY(
+                    triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                    pair<DestImageIterator, DestAccessor> dest, 
+                    double b1, double b2);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);    
+    ...
+    
+    // apply a second-order filter to the y-axis
+    recursiveFilterY(src, dest, -0.6, -0.06);
+    \endcode
+
+    \deprecatedUsage{recursiveFilterY}
+    \code
+    vigra::FImage src(w,h), dest(w,h);    
+    ...
+    
+    vigra::recursiveFilterY(srcImageRange(src), destImage(dest), -0.6, -0.06);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void recursiveFilterY)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void recursiveFilterY(SrcImageIterator supperleft, 
+                       SrcImageIterator slowerright, SrcAccessor as,
+                       DestImageIterator dupperleft, DestAccessor ad, 
+                       double b, BorderTreatmentMode border)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int x;
+    
+    for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
+    {
+        typename SrcImageIterator::column_iterator cs = supperleft.columnIterator();
+        typename DestImageIterator::column_iterator cd = dupperleft.columnIterator();
+
+        recursiveFilterLine(cs, cs+h, as, 
+                            cd, ad, 
+                            b, border);
+    }
+}
+            
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void
+recursiveFilterY(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                 pair<DestImageIterator, DestAccessor> dest, 
+                 double b, BorderTreatmentMode border)
+{
+    recursiveFilterY(src.first, src.second, src.third,
+                     dest.first, dest.second, b, border);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+recursiveFilterY(MultiArrayView<2, T1, S1> const & src,
+                 MultiArrayView<2, T2, S2> dest, 
+                 double b, BorderTreatmentMode border)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveFilterY(): shape mismatch between input and output.");
+    recursiveFilterY(srcImageRange(src),
+                     destImage(dest), b, border);
+}
+
+/********************************************************/
+/*                                                      */
+/*            recursiveFilterY (2nd order)              */
+/*                                                      */
+/********************************************************/
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void recursiveFilterY(SrcImageIterator supperleft, 
+                       SrcImageIterator slowerright, SrcAccessor as,
+                       DestImageIterator dupperleft, DestAccessor ad, 
+                       double b1, double b2)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int x;
+    
+    for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
+    {
+        typename SrcImageIterator::column_iterator cs = supperleft.columnIterator();
+        typename DestImageIterator::column_iterator cd = dupperleft.columnIterator();
+
+        recursiveFilterLine(cs, cs+h, as, 
+                            cd, ad, 
+                            b1, b2);
+    }
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void
+recursiveFilterY(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                 pair<DestImageIterator, DestAccessor> dest, 
+                 double b1, double b2)
+{
+    recursiveFilterY(src.first, src.second, src.third,
+                     dest.first, dest.second, b1, b2);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+recursiveFilterY(MultiArrayView<2, T1, S1> const & src,
+                 MultiArrayView<2, T2, S2> dest, 
+                 double b1, double b2)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveFilterY(): shape mismatch between input and output.");
+    recursiveFilterY(srcImageRange(src),
+                     destImage(dest), b1, b2);
+}
+
+/********************************************************/
+/*                                                      */
+/*               recursiveGaussianFilterY               */
+/*                                                      */
+/********************************************************/
+
+// AUTHOR: Sebastian Boppel
+
+/** \brief Compute 1 dimensional recursive approximation of Gaussian smoothing in y direction.
+
+    It calls \ref recursiveGaussianFilterLine() for every column of the
+    image. See \ref recursiveGaussianFilterLine() for more information about 
+    required interfaces and vigra_preconditions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void 
+        recursiveGaussianFilterY(MultiArrayView<2, T1, S1> const & src,
+                                 MultiArrayView<2, T2, S2> dest, 
+                                 double sigma);
+    }
+    \endcode
+    
+    \deprecatedAPI{recursiveGaussianFilterY}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void 
+        recursiveGaussianFilterY(SrcImageIterator supperleft, SrcImageIterator slowerright, SrcAccessor as,
+                                 DestImageIterator dupperleft, DestAccessor ad, 
+                                 double sigma);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void 
+        recursiveGaussianFilterY(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                                 pair<DestImageIterator, DestAccessor> dest, 
+                                 double sigma);
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);    
+    ...
+    
+    recursiveGaussianFilterY(src, dest, 3.0);
+    \endcode
+
+    \deprecatedUsage{recursiveGaussianFilterY}
+    \code
+    vigra::FImage src(w,h), dest(w,h);    
+    ...
+    
+    vigra::recursiveGaussianFilterY(srcImageRange(src), destImage(dest), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void recursiveGaussianFilterY)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void 
+recursiveGaussianFilterY(SrcImageIterator supperleft, SrcImageIterator slowerright, SrcAccessor as,
+                         DestImageIterator dupperleft, DestAccessor ad, 
+                         double sigma)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int x;
+    
+    for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
+    {
+        typename SrcImageIterator::column_iterator cs = supperleft.columnIterator();
+        typename DestImageIterator::column_iterator cd = dupperleft.columnIterator();
+
+        recursiveGaussianFilterLine(cs, cs+h, as, 
+                                    cd, ad, 
+                                    sigma);
+    } 
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void 
+recursiveGaussianFilterY(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                         pair<DestImageIterator, DestAccessor> dest, 
+                         double sigma)
+{
+    recursiveGaussianFilterY(src.first, src.second, src.third,
+                             dest.first, dest.second, sigma);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void 
+recursiveGaussianFilterY(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest, 
+                         double sigma)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveGaussianFilterY(): shape mismatch between input and output.");
+    recursiveGaussianFilterY(srcImageRange(src),
+                             destImage(dest), sigma);
+}
+
+
+/********************************************************/
+/*                                                      */
+/*                     recursiveSmoothY                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs 1 dimensional recursive smoothing in y direction.
+
+    It calls \ref recursiveSmoothLine() for every column of the
+    image. See \ref recursiveSmoothLine() for more information about 
+    required interfaces and vigra_preconditions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void 
+        recursiveSmoothY(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, T2, S2> dest, 
+                         double scale);
+    }
+    \endcode
+    
+    \deprecatedAPI{recursiveSmoothY}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveSmoothY(SrcImageIterator supperleft, 
+                  SrcImageIterator slowerright, SrcAccessor as,
+                  DestImageIterator dupperleft, DestAccessor ad, 
+                  double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveSmoothY(
+            triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+            pair<DestImageIterator, DestAccessor> dest, 
+            double scale)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);    
+    ...
+    
+    recursiveSmoothY(src, dest, 3.0);
+    \endcode
+
+    \deprecatedUsage{recursiveSmoothY}
+    \code
+    vigra::FImage src(w,h), dest(w,h);    
+    ...
+    
+    vigra::recursiveSmoothY(srcImageRange(src), destImage(dest), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void recursiveSmoothY)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void recursiveSmoothY(SrcImageIterator supperleft, 
+                      SrcImageIterator slowerright, SrcAccessor as,
+                      DestImageIterator dupperleft, DestAccessor ad, 
+              double scale)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int x;
+    
+    for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
+    {
+        typename SrcImageIterator::column_iterator cs = supperleft.columnIterator();
+        typename DestImageIterator::column_iterator cd = dupperleft.columnIterator();
+
+        recursiveSmoothLine(cs, cs+h, as, 
+                            cd, ad, 
+                            scale);
+    }
+}
+            
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void 
+recursiveSmoothY(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                 pair<DestImageIterator, DestAccessor> dest, 
+                 double scale)
+{
+    recursiveSmoothY(src.first, src.second, src.third,
+                     dest.first, dest.second, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void 
+recursiveSmoothY(MultiArrayView<2, T1, S1> const & src,
+                 MultiArrayView<2, T2, S2> dest, 
+                 double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveSmoothY(): shape mismatch between input and output.");
+    recursiveSmoothY(srcImageRange(src),
+                     destImage(dest), scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*              recursiveFirstDerivativeX               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Recursively calculates the 1 dimensional first derivative in x 
+    direction.
+    
+    It calls \ref recursiveFirstDerivativeLine() for every 
+    row of the image. See \ref recursiveFirstDerivativeLine() for more 
+    information about required interfaces and vigra_preconditions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        recursiveFirstDerivativeX(MultiArrayView<2, T1, S1> const & src,
+                                  MultiArrayView<2, T2, S2> dest, 
+                                  double scale);
+    }
+    \endcode
+    
+    \deprecatedAPI{recursiveFirstDerivativeX}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveFirstDerivativeX(SrcImageIterator supperleft, 
+                  SrcImageIterator slowerright, SrcAccessor as,
+                  DestImageIterator dupperleft, DestAccessor ad, 
+                  double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveFirstDerivativeX(
+            triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+            pair<DestImageIterator, DestAccessor> dest, 
+            double scale)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);    
+    ...
+    
+    recursiveFirstDerivativeX(src, dest, 3.0);
+    \endcode
+
+    \deprecatedUsage{recursiveFirstDerivativeX}
+    \code
+    vigra::FImage src(w,h), dest(w,h);    
+    ...
+    
+    vigra::recursiveFirstDerivativeX(srcImageRange(src), destImage(dest), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void recursiveFirstDerivativeX)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void recursiveFirstDerivativeX(SrcImageIterator supperleft, 
+                      SrcImageIterator slowerright, SrcAccessor as,
+                      DestImageIterator dupperleft, DestAccessor ad, 
+              double scale)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int y;
+    
+    for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
+    {
+        typename SrcImageIterator::row_iterator rs = supperleft.rowIterator();
+        typename DestImageIterator::row_iterator rd = dupperleft.rowIterator();
+
+        recursiveFirstDerivativeLine(rs, rs+w, as, 
+                                     rd, ad, 
+                                     scale);
+    }
+}
+            
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void
+recursiveFirstDerivativeX(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                          pair<DestImageIterator, DestAccessor> dest, 
+                          double scale)
+{
+    recursiveFirstDerivativeX(src.first, src.second, src.third,
+                              dest.first, dest.second, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+recursiveFirstDerivativeX(MultiArrayView<2, T1, S1> const & src,
+                          MultiArrayView<2, T2, S2> dest, 
+                          double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveFirstDerivativeX(): shape mismatch between input and output.");
+    recursiveFirstDerivativeX(srcImageRange(src),
+                              destImage(dest), scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*              recursiveFirstDerivativeY               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Recursively calculates the 1 dimensional first derivative in y 
+    direction.
+    
+    It calls \ref recursiveFirstDerivativeLine() for every 
+    column of the image. See \ref recursiveFirstDerivativeLine() for more 
+    information about required interfaces and vigra_preconditions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        recursiveFirstDerivativeY(MultiArrayView<2, T1, S1> const & src,
+                                  MultiArrayView<2, T2, S2> dest, 
+                                  double scale);
+    }
+    \endcode
+    
+    \deprecatedAPI{recursiveFirstDerivativeY}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveFirstDerivativeY(SrcImageIterator supperleft, 
+                  SrcImageIterator slowerright, SrcAccessor as,
+                  DestImageIterator dupperleft, DestAccessor ad, 
+                  double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveFirstDerivativeY(
+            triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+            pair<DestImageIterator, DestAccessor> dest, 
+            double scale)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);    
+    ...
+    
+    recursiveFirstDerivativeY(src, dest, 3.0);
+    \endcode
+
+    \deprecatedUsage{recursiveFirstDerivativeY}
+    \code
+    vigra::FImage src(w,h), dest(w,h);    
+    ...
+    
+    vigra::recursiveFirstDerivativeY(srcImageRange(src), destImage(dest), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void recursiveFirstDerivativeY)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void recursiveFirstDerivativeY(SrcImageIterator supperleft, 
+                      SrcImageIterator slowerright, SrcAccessor as,
+                      DestImageIterator dupperleft, DestAccessor ad, 
+              double scale)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int x;
+    
+    for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
+    {
+        typename SrcImageIterator::column_iterator cs = supperleft.columnIterator();
+        typename DestImageIterator::column_iterator cd = dupperleft.columnIterator();
+
+        recursiveFirstDerivativeLine(cs, cs+h, as, 
+                                     cd, ad, 
+                                     scale);
+    }
+}
+            
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void
+recursiveFirstDerivativeY(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                          pair<DestImageIterator, DestAccessor> dest, 
+                          double scale)
+{
+    recursiveFirstDerivativeY(src.first, src.second, src.third,
+                              dest.first, dest.second, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+recursiveFirstDerivativeY(MultiArrayView<2, T1, S1> const & src,
+                          MultiArrayView<2, T2, S2> dest, 
+                          double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveFirstDerivativeY(): shape mismatch between input and output.");
+    recursiveFirstDerivativeY(srcImageRange(src),
+                              destImage(dest), scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*             recursiveSecondDerivativeX               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Recursively calculates the 1 dimensional second derivative in x 
+    direction.
+    
+    It calls \ref recursiveSecondDerivativeLine() for every 
+    row of the image. See \ref recursiveSecondDerivativeLine() for more 
+    information about required interfaces and vigra_preconditions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        recursiveSecondDerivativeX(MultiArrayView<2, T1, S1> const & src,
+                                   MultiArrayView<2, T2, S2> dest, 
+                                   double scale);
+    }
+    \endcode
+    
+    \deprecatedAPI{recursiveSecondDerivativeX}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveSecondDerivativeX(SrcImageIterator supperleft, 
+                  SrcImageIterator slowerright, SrcAccessor as,
+                  DestImageIterator dupperleft, DestAccessor ad, 
+                  double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveSecondDerivativeX(
+            triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+            pair<DestImageIterator, DestAccessor> dest, 
+            double scale)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);    
+    ...
+    
+    recursiveSecondDerivativeX(src, dest, 3.0);
+    \endcode
+
+    \deprecatedUsage{recursiveSecondDerivativeX}
+    \code
+    vigra::FImage src(w,h), dest(w,h);    
+    ...
+    
+    vigra::recursiveSecondDerivativeX(srcImageRange(src), destImage(dest), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void recursiveSecondDerivativeX)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void recursiveSecondDerivativeX(SrcImageIterator supperleft, 
+                      SrcImageIterator slowerright, SrcAccessor as,
+                      DestImageIterator dupperleft, DestAccessor ad, 
+              double scale)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int y;
+    
+    for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
+    {
+        typename SrcImageIterator::row_iterator rs = supperleft.rowIterator();
+        typename DestImageIterator::row_iterator rd = dupperleft.rowIterator();
+
+        recursiveSecondDerivativeLine(rs, rs+w, as, 
+                                      rd, ad, 
+                                      scale);
+    }
+}
+            
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void
+recursiveSecondDerivativeX(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                           pair<DestImageIterator, DestAccessor> dest, 
+                           double scale)
+{
+    recursiveSecondDerivativeX(src.first, src.second, src.third,
+                               dest.first, dest.second, scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+recursiveSecondDerivativeX(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, T2, S2> dest, 
+                           double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveSecondDerivativeX(): shape mismatch between input and output.");
+    recursiveSecondDerivativeX(srcImageRange(src),
+                               destImage(dest), scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*             recursiveSecondDerivativeY               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Recursively calculates the 1 dimensional second derivative in y 
+    direction.
+    
+    It calls \ref recursiveSecondDerivativeLine() for every 
+    column of the image. See \ref recursiveSecondDerivativeLine() for more 
+    information about required interfaces and vigra_preconditions.
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        recursiveSecondDerivativeY(MultiArrayView<2, T1, S1> const & src,
+                                   MultiArrayView<2, T2, S2> dest, 
+                                   double scale);
+    }
+    \endcode
+    
+    \deprecatedAPI{recursiveSecondDerivativeY}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveSecondDerivativeY(SrcImageIterator supperleft, 
+                  SrcImageIterator slowerright, SrcAccessor as,
+                  DestImageIterator dupperleft, DestAccessor ad, 
+                  double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+              class DestImageIterator, class DestAccessor>
+        void recursiveSecondDerivativeY(
+            triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+            pair<DestImageIterator, DestAccessor> dest, 
+            double scale)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/recursiveconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);    
+    ...
+    
+    recursiveSecondDerivativeY(src, dest, 3.0);
+    \endcode
+
+    \deprecatedUsage{recursiveSecondDerivativeY}
+    \code
+    vigra::FImage src(w,h), dest(w,h);    
+    ...
+    
+    vigra::recursiveSecondDerivativeY(srcImageRange(src), destImage(dest), 3.0);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void recursiveSecondDerivativeY)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+void recursiveSecondDerivativeY(SrcImageIterator supperleft, 
+                      SrcImageIterator slowerright, SrcAccessor as,
+                      DestImageIterator dupperleft, DestAccessor ad, 
+              double scale)
+{
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+    
+    int x;
+    
+    for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
+    {
+        typename SrcImageIterator::column_iterator cs = supperleft.columnIterator();
+        typename DestImageIterator::column_iterator cd = dupperleft.columnIterator();
+
+        recursiveSecondDerivativeLine(cs, cs+h, as, 
+                                      cd, ad, 
+                                      scale);
+    }
+}
+            
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor>
+inline void
+recursiveSecondDerivativeY(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                           pair<DestImageIterator, DestAccessor> dest, 
+                           double scale)
+{
+    recursiveSecondDerivativeY(src.first, src.second, src.third,
+                               dest.first, dest.second, scale);
+}
+            
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+recursiveSecondDerivativeY(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, T2, S2> dest, 
+                           double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "recursiveSecondDerivativeY(): shape mismatch between input and output.");
+    recursiveSecondDerivativeY(srcImageRange(src),
+                               destImage(dest), scale);
+}
+            
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_RECURSIVECONVOLUTION_HXX
diff --git a/include/vigra/regression.hxx b/include/vigra/regression.hxx
new file mode 100644
index 0000000..c10c80e
--- /dev/null
+++ b/include/vigra/regression.hxx
@@ -0,0 +1,1276 @@
+/************************************************************************/
+/*                                                                      */
+/*             Copyright 2008-2013 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_REGRESSION_HXX
+#define VIGRA_REGRESSION_HXX
+
+#include "matrix.hxx"
+#include "linear_solve.hxx"
+#include "singular_value_decomposition.hxx"
+#include "numerictraits.hxx"
+#include "functorexpression.hxx"
+#include "autodiff.hxx"
+
+
+namespace vigra
+{
+
+namespace linalg
+{
+
+/** \addtogroup Optimization Optimization and Regression
+ */
+//@{
+   /** Ordinary Least Squares Regression.
+
+       Given a matrix \a A with <tt>m</tt> rows and <tt>n</tt> columns (with <tt>m \>= n</tt>),
+       and a column vector \a b of length <tt>m</tt> rows, this function computes
+       the column vector \a x of length <tt>n</tt> rows that solves the optimization problem
+
+        \f[ \tilde \textrm{\bf x} = \textrm{argmin}
+            \left|\left|\textrm{\bf A} \textrm{\bf x} - \textrm{\bf b}\right|\right|_2^2
+        \f]
+
+       When \a b is a matrix with <tt>k</tt> columns, \a x must also have
+       <tt>k</tt> columns, which will contain the solutions for the corresponding columns of
+       \a b. Note that all matrices must already have the correct shape.
+
+       This function is just another name for \ref linearSolve(), perhaps
+       leading to more readable code when \a A is a rectangular matrix. It returns
+       <tt>false</tt> when the rank of \a A is less than <tt>n</tt>.
+       See \ref linearSolve() for more documentation.
+
+       <b>\#include</b> \<vigra/regression.hxx\><br/>
+       Namespaces: vigra and vigra::linalg
+   */
+template <class T, class C1, class C2, class C3>
+inline bool
+leastSquares(MultiArrayView<2, T, C1> const & A,
+             MultiArrayView<2, T, C2> const &b, MultiArrayView<2, T, C3> &x,
+             std::string method = "QR")
+{
+    return linearSolve(A, b, x, method);
+}
+
+   /** Weighted Least Squares Regression.
+
+       Given a matrix \a A with <tt>m</tt> rows and <tt>n</tt> columns (with <tt>m \>= n</tt>),
+       a vector \a b of length <tt>m</tt>, and a weight vector \a weights of length <tt>m</tt>
+       with non-negative entries, this function computes the vector \a x of length <tt>n</tt>
+       that solves the optimization problem
+
+        \f[ \tilde \textrm{\bf x} = \textrm{argmin}
+            \left(\textrm{\bf A} \textrm{\bf x} - \textrm{\bf b}\right)^T
+             \textrm{diag}(\textrm{\bf weights})
+             \left(\textrm{\bf A} \textrm{\bf x} - \textrm{\bf b}\right)
+        \f]
+
+       where <tt>diag(weights)</tt> creates a diagonal matrix from \a weights.
+       The algorithm calls \ref leastSquares() on the equivalent problem
+
+        \f[ \tilde \textrm{\bf x} = \textrm{argmin}
+             \left|\left|\textrm{diag}(\textrm{\bf weights})^{1/2}\textrm{\bf A} \textrm{\bf x} -
+                  \textrm{diag}(\textrm{\bf weights})^{1/2} \textrm{\bf b}\right|\right|_2^2
+        \f]
+
+       where the square root of \a weights is just taken element-wise.
+
+       When \a b is a matrix with <tt>k</tt> columns, \a x must also have
+       <tt>k</tt> columns, which will contain the solutions for the corresponding columns of
+       \a b. Note that all matrices must already have the correct shape.
+
+       The function returns
+       <tt>false</tt> when the rank of the weighted matrix \a A is less than <tt>n</tt>.
+
+       <b>\#include</b> \<vigra/regression.hxx\><br/>
+       Namespaces: vigra and vigra::linalg
+   */
+template <class T, class C1, class C2, class C3, class C4>
+bool
+weightedLeastSquares(MultiArrayView<2, T, C1> const & A,
+             MultiArrayView<2, T, C2> const &b, MultiArrayView<2, T, C3> const &weights,
+             MultiArrayView<2, T, C4> &x, std::string method = "QR")
+{
+    const unsigned int rows = rowCount(A);
+    const unsigned int cols = columnCount(A);
+    const unsigned int rhsCount = columnCount(b);
+    vigra_precondition(rows >= cols,
+       "weightedLeastSquares(): Input matrix A must be rectangular with rowCount >= columnCount.");
+    vigra_precondition(rowCount(b) == rows,
+       "weightedLeastSquares(): Shape mismatch between matrices A and b.");
+    vigra_precondition(rowCount(b) == rowCount(weights) && columnCount(weights) == 1,
+       "weightedLeastSquares(): Weight matrix has wrong shape.");
+    vigra_precondition(rowCount(x) == cols && columnCount(x) == rhsCount,
+       "weightedLeastSquares(): Result matrix x has wrong shape.");
+
+    Matrix<T> wa(A.shape()), wb(b.shape());
+
+    for(unsigned int k=0; k<rows; ++k)
+    {
+        vigra_precondition(weights(k,0) >= 0,
+           "weightedLeastSquares(): Weights must be positive.");
+        T w = std::sqrt(weights(k,0));
+        for(unsigned int l=0; l<cols; ++l)
+            wa(k,l) = w * A(k,l);
+        for(unsigned int l=0; l<rhsCount; ++l)
+            wb(k,l) = w * b(k,l);
+    }
+
+    return leastSquares(wa, wb, x, method);
+}
+
+   /** Ridge Regression.
+
+       Given a matrix \a A with <tt>m</tt> rows and <tt>n</tt> columns (with <tt>m \>= n</tt>),
+       a vector \a b of length <tt>m</tt>, and a regularization parameter <tt>lambda \>= 0.0</tt>,
+       this function computes the vector \a x of length <tt>n</tt>
+       that solves the optimization problem
+
+        \f[ \tilde \textrm{\bf x} = \textrm{argmin}
+            \left|\left|\textrm{\bf A} \textrm{\bf x} - \textrm{\bf b}\right|\right|_2^2 +
+            \lambda \textrm{\bf x}^T\textrm{\bf x}
+        \f]
+
+       This is implemented by means of \ref singularValueDecomposition().
+
+       When \a b is a matrix with <tt>k</tt> columns, \a x must also have
+       <tt>k</tt> columns, which will contain the solutions for the corresponding columns of
+       \a b. Note that all matrices must already have the correct shape.
+
+       The function returns <tt>false</tt> if the rank of \a A is less than <tt>n</tt>
+       and <tt>lambda == 0.0</tt>.
+
+       <b>\#include</b> \<vigra/regression.hxx\><br/>
+       Namespaces: vigra and vigra::linalg
+   */
+template <class T, class C1, class C2, class C3>
+bool
+ridgeRegression(MultiArrayView<2, T, C1> const & A,
+                MultiArrayView<2, T, C2> const &b, MultiArrayView<2, T, C3> &x, double lambda)
+{
+    const unsigned int rows = rowCount(A);
+    const unsigned int cols = columnCount(A);
+    const unsigned int rhsCount = columnCount(b);
+    vigra_precondition(rows >= cols,
+       "ridgeRegression(): Input matrix A must be rectangular with rowCount >= columnCount.");
+    vigra_precondition(rowCount(b) == rows,
+       "ridgeRegression(): Shape mismatch between matrices A and b.");
+    vigra_precondition(rowCount(x) == cols && columnCount(x) == rhsCount,
+       "ridgeRegression(): Result matrix x has wrong shape.");
+    vigra_precondition(lambda >= 0.0,
+       "ridgeRegression(): lambda >= 0.0 required.");
+
+    unsigned int m = rows;
+    unsigned int n = cols;
+
+    Matrix<T> u(m, n), s(n, 1), v(n, n);
+
+    unsigned int rank = singularValueDecomposition(A, u, s, v);
+    if(rank < n && lambda == 0.0)
+        return false;
+
+    Matrix<T> t = transpose(u)*b;
+    for(unsigned int k=0; k<cols; ++k)
+        for(unsigned int l=0; l<rhsCount; ++l)
+            t(k,l) *= s(k,0) / (sq(s(k,0)) + lambda);
+    x = v*t;
+    return true;
+}
+
+   /** Weighted ridge Regression.
+
+       Given a matrix \a A with <tt>m</tt> rows and <tt>n</tt> columns (with <tt>m \>= n</tt>),
+       a vector \a b of length <tt>m</tt>, a weight vector \a weights of length <tt>m</tt>
+       with non-negative entries, and a regularization parameter <tt>lambda >= 0.0</tt>
+       this function computes the vector \a x of length <tt>n</tt>
+       that solves the optimization problem
+
+        \f[ \tilde \textrm{\bf x} = \textrm{argmin}
+            \left(\textrm{\bf A} \textrm{\bf x} - \textrm{\bf b}\right)^T
+             \textrm{diag}(\textrm{\bf weights})
+             \left(\textrm{\bf A} \textrm{\bf x} - \textrm{\bf b}\right) +
+             \lambda \textrm{\bf x}^T\textrm{\bf x}
+        \f]
+
+       where <tt>diag(weights)</tt> creates a diagonal matrix from \a weights.
+       The algorithm calls \ref ridgeRegression() on the equivalent problem
+
+        \f[ \tilde \textrm{\bf x} = \textrm{argmin}
+            \left|\left|\textrm{diag}(\textrm{\bf weights})^{1/2}\textrm{\bf A} \textrm{\bf x} -
+                  \textrm{diag}(\textrm{\bf weights})^{1/2} \textrm{\bf b}\right|\right|_2^2 +
+             \lambda \textrm{\bf x}^T\textrm{\bf x}
+        \f]
+
+       where the square root of \a weights is just taken element-wise.  This solution is
+       computed by means of \ref singularValueDecomposition().
+
+       When \a b is a matrix with <tt>k</tt> columns, \a x must also have
+       <tt>k</tt> columns, which will contain the solutions for the corresponding columns of
+       \a b. Note that all matrices must already have the correct shape.
+
+       The function returns <tt>false</tt> if the rank of \a A is less than <tt>n</tt>
+       and <tt>lambda == 0.0</tt>.
+
+       <b>\#include</b> \<vigra/regression.hxx\><br/>
+       Namespaces: vigra and vigra::linalg
+   */
+template <class T, class C1, class C2, class C3, class C4>
+bool
+weightedRidgeRegression(MultiArrayView<2, T, C1> const & A,
+             MultiArrayView<2, T, C2> const &b, MultiArrayView<2, T, C3> const &weights,
+             MultiArrayView<2, T, C4> &x, double lambda)
+{
+    const unsigned int rows = rowCount(A);
+    const unsigned int cols = columnCount(A);
+    const unsigned int rhsCount = columnCount(b);
+    vigra_precondition(rows >= cols,
+       "weightedRidgeRegression(): Input matrix A must be rectangular with rowCount >= columnCount.");
+    vigra_precondition(rowCount(b) == rows,
+       "weightedRidgeRegression(): Shape mismatch between matrices A and b.");
+    vigra_precondition(rowCount(b) == rowCount(weights) && columnCount(weights) == 1,
+       "weightedRidgeRegression(): Weight matrix has wrong shape.");
+    vigra_precondition(rowCount(x) == cols && columnCount(x) == rhsCount,
+       "weightedRidgeRegression(): Result matrix x has wrong shape.");
+    vigra_precondition(lambda >= 0.0,
+       "weightedRidgeRegression(): lambda >= 0.0 required.");
+
+    Matrix<T> wa(A.shape()), wb(b.shape());
+
+    for(unsigned int k=0; k<rows; ++k)
+    {
+        vigra_precondition(weights(k,0) >= 0,
+           "weightedRidgeRegression(): Weights must be positive.");
+        T w = std::sqrt(weights(k,0));
+        for(unsigned int l=0; l<cols; ++l)
+            wa(k,l) = w * A(k,l);
+        for(unsigned int l=0; l<rhsCount; ++l)
+            wb(k,l) = w * b(k,l);
+    }
+
+    return ridgeRegression(wa, wb, x, lambda);
+}
+
+   /** Ridge Regression with many lambdas.
+
+       This executes \ref ridgeRegression() for a sequence of regularization parameters. This
+       is implemented so that the \ref singularValueDecomposition() has to be executed only once.
+       \a lambda must be an array conforming to the <tt>std::vector</tt> interface, i.e. must
+       support <tt>lambda.size()</tt> and <tt>lambda[k]</tt>. The columns of the matrix \a x
+       will contain the solutions for the corresponding lambda, so the  number of columns of
+       the matrix \a x must be equal to <tt>lambda.size()</tt>, and \a b must be a columns vector,
+       i.e. cannot contain several right hand sides at once.
+
+       The function returns <tt>false</tt> when the matrix \a A is rank deficient. If this
+       happens, and one of the lambdas is zero, the corresponding column of \a x will be skipped.
+
+       <b>\#include</b> \<vigra/regression.hxx\><br/>
+       Namespaces: vigra and vigra::linalg
+   */
+template <class T, class C1, class C2, class C3, class Array>
+bool
+ridgeRegressionSeries(MultiArrayView<2, T, C1> const & A,
+          MultiArrayView<2, T, C2> const &b, MultiArrayView<2, T, C3> &x, Array const & lambda)
+{
+    const unsigned int rows = rowCount(A);
+    const unsigned int cols = columnCount(A);
+    const unsigned int lambdaCount = lambda.size();
+    vigra_precondition(rows >= cols,
+       "ridgeRegressionSeries(): Input matrix A must be rectangular with rowCount >= columnCount.");
+    vigra_precondition(rowCount(b) == rows && columnCount(b) == 1,
+       "ridgeRegressionSeries(): Shape mismatch between matrices A and b.");
+    vigra_precondition(rowCount(x) == cols && columnCount(x) == lambdaCount,
+       "ridgeRegressionSeries(): Result matrix x has wrong shape.");
+
+    unsigned int m = rows;
+    unsigned int n = cols;
+
+    Matrix<T> u(m, n), s(n, 1), v(n, n);
+
+    unsigned int rank = singularValueDecomposition(A, u, s, v);
+
+    Matrix<T> xl = transpose(u)*b;
+    Matrix<T> xt(cols,1);
+    for(unsigned int i=0; i<lambdaCount; ++i)
+    {
+        vigra_precondition(lambda[i] >= 0.0,
+           "ridgeRegressionSeries(): lambda >= 0.0 required.");
+        if(lambda[i] == 0.0 && rank < rows)
+            continue;
+        for(unsigned int k=0; k<cols; ++k)
+            xt(k,0) = xl(k,0) * s(k,0) / (sq(s(k,0)) + lambda[i]);
+        columnVector(x, i) = v*xt;
+    }
+    return (rank == n);
+}
+
+/** \brief Pass options to leastAngleRegression().
+
+    <b>\#include</b> \<vigra/regression.hxx\><br/>
+    Namespaces: vigra and vigra::linalg
+*/
+class LeastAngleRegressionOptions
+{
+  public:
+    enum Mode { LARS, LASSO, NNLASSO };
+
+        /** Initialize all options with default values.
+        */
+    LeastAngleRegressionOptions()
+    : max_solution_count(0),
+      unconstrained_dimension_count(0),
+      mode(LASSO),
+      least_squares_solutions(true)
+    {}
+
+        /** Maximum number of solutions to be computed.
+
+            If \a n is 0 (the default), the number of solutions is determined by the length
+            of the solution array. Otherwise, the minimum of maxSolutionCount() and that
+            length is taken.<br>
+            Default: 0 (use length of solution array)
+        */
+    LeastAngleRegressionOptions & maxSolutionCount(unsigned int n)
+    {
+        max_solution_count = (int)n;
+        return *this;
+    }
+
+        /** Set the mode of the algorithm.
+
+            Mode must be one of "lars", "lasso", "nnlasso". The function just calls
+            the member function of the corresponding name to set the mode.
+
+            Default: "lasso"
+        */
+    LeastAngleRegressionOptions & setMode(std::string mode)
+    {
+        mode = tolower(mode);
+        if(mode == "lars")
+            this->lars();
+        else if(mode == "lasso")
+            this->lasso();
+        else if(mode == "nnlasso")
+            this->nnlasso();
+        else
+            vigra_fail("LeastAngleRegressionOptions.setMode(): Invalid mode.");
+        return *this;
+    }
+
+
+        /** Use the plain LARS algorithm.
+
+            Default: inactive
+        */
+    LeastAngleRegressionOptions & lars()
+    {
+        mode = LARS;
+        return *this;
+    }
+
+        /** Use the LASSO modification of the LARS algorithm.
+
+            This allows features to be removed from the active set under certain conditions.<br>
+            Default: active
+        */
+    LeastAngleRegressionOptions & lasso()
+    {
+        mode = LASSO;
+        return *this;
+    }
+
+        /** Use the non-negative LASSO modification of the LARS algorithm.
+
+            This enforces all non-zero entries in the solution to be positive.<br>
+            Default: inactive
+        */
+    LeastAngleRegressionOptions & nnlasso()
+    {
+        mode = NNLASSO;
+        return *this;
+    }
+
+        /** Compute least squares solutions.
+
+            Use least angle regression to determine active sets, but
+            return least squares solutions for the features in each active set,
+            instead of constrained solutions.<br>
+            Default: <tt>true</tt>
+        */
+    LeastAngleRegressionOptions & leastSquaresSolutions(bool select = true)
+    {
+        least_squares_solutions = select;
+        return *this;
+    }
+
+    int max_solution_count, unconstrained_dimension_count;
+    Mode mode;
+    bool least_squares_solutions;
+};
+
+namespace detail {
+
+template <class T, class C1, class C2>
+struct LarsData
+{
+    typedef typename MultiArrayShape<2>::type Shape;
+
+    int activeSetSize;
+    MultiArrayView<2, T, C1> A;
+    MultiArrayView<2, T, C2> b;
+    Matrix<T> R, qtb, lars_solution, lars_prediction, next_lsq_solution, next_lsq_prediction, searchVector;
+    ArrayVector<MultiArrayIndex> columnPermutation;
+
+    // init data for a new run
+    LarsData(MultiArrayView<2, T, C1> const & Ai, MultiArrayView<2, T, C2> const & bi)
+    : activeSetSize(1),
+      A(Ai), b(bi), R(A), qtb(b),
+      lars_solution(A.shape(1), 1), lars_prediction(A.shape(0), 1),
+      next_lsq_solution(A.shape(1), 1), next_lsq_prediction(A.shape(0), 1), searchVector(A.shape(0), 1),
+      columnPermutation(A.shape(1))
+    {
+        for(unsigned int k=0; k<columnPermutation.size(); ++k)
+            columnPermutation[k] = k;
+    }
+
+    // copy data for the recursive call in nnlassolsq
+    LarsData(LarsData const & d, int asetSize)
+    : activeSetSize(asetSize),
+      A(d.R.subarray(Shape(0,0), Shape(d.A.shape(0), activeSetSize))), b(d.qtb), R(A), qtb(b),
+      lars_solution(d.lars_solution.subarray(Shape(0,0), Shape(activeSetSize, 1))), lars_prediction(d.lars_prediction),
+      next_lsq_solution(d.next_lsq_solution.subarray(Shape(0,0), Shape(activeSetSize, 1))), 
+      next_lsq_prediction(d.next_lsq_prediction), searchVector(d.searchVector),
+      columnPermutation(A.shape(1))
+    {
+        for(unsigned int k=0; k<columnPermutation.size(); ++k)
+            columnPermutation[k] = k;
+    }
+};
+
+template <class T, class C1, class C2, class Array1, class Array2, class Array3>
+unsigned int 
+leastAngleRegressionMainLoop(LarsData<T, C1, C2> & d,
+                             Array1 & activeSets, 
+                             Array2 * lars_solutions, Array3 * lsq_solutions,
+                             LeastAngleRegressionOptions const & options)
+{
+    using namespace vigra::functor;
+
+    typedef typename MultiArrayShape<2>::type Shape;
+    typedef typename Matrix<T>::view_type Subarray;
+    typedef ArrayVector<MultiArrayIndex> Permutation;
+    typedef typename Permutation::view_type ColumnSet;
+
+    vigra_precondition(d.activeSetSize > 0,
+       "leastAngleRegressionMainLoop() must not be called with empty active set.");
+
+    bool enforce_positive = (options.mode == LeastAngleRegressionOptions::NNLASSO);
+    bool lasso_modification = (options.mode != LeastAngleRegressionOptions::LARS);
+
+    const MultiArrayIndex rows = rowCount(d.R);
+    const MultiArrayIndex cols = columnCount(d.R);
+    const MultiArrayIndex maxRank = std::min(rows, cols);
+
+    MultiArrayIndex maxSolutionCount = options.max_solution_count;
+    if(maxSolutionCount == 0)
+        maxSolutionCount = lasso_modification
+                                ? 10*maxRank
+                                : maxRank;
+
+    bool needToRemoveColumn = false;
+    MultiArrayIndex columnToBeAdded = 0, columnToBeRemoved = 0;
+    MultiArrayIndex currentSolutionCount = 0;
+    while(currentSolutionCount < maxSolutionCount)
+    {
+        //ColumnSet activeSet = d.columnPermutation.subarray(0, (unsigned int)d.activeSetSize);
+        ColumnSet inactiveSet = d.columnPermutation.subarray((unsigned int)d.activeSetSize, (unsigned int)cols);
+
+        // find next dimension to be activated
+        Matrix<T> cLARS = transpose(d.A) * (d.b - d.lars_prediction),      // correlation with LARS residual
+                  cLSQ  = transpose(d.A) * (d.b - d.next_lsq_prediction);  // correlation with LSQ residual
+
+        // In theory, all vectors in the active set should have the same correlation C, and
+        // the correlation of all others should not exceed this. In practice, we may find the
+        // maximum correlation in any variable due to tiny numerical inaccuracies. Therefore, we
+        // determine C from the entire set of variables.
+        MultiArrayIndex cmaxIndex = enforce_positive
+                                      ? argMax(cLARS)
+                                      : argMax(abs(cLARS));
+        T C = abs(cLARS(cmaxIndex, 0));
+
+        Matrix<T> ac(cols - d.activeSetSize, 1);
+        for(MultiArrayIndex k = 0; k<cols-d.activeSetSize; ++k)
+        {
+            T rho = cLSQ(inactiveSet[k], 0), 
+              cc  = C - sign(rho)*cLARS(inactiveSet[k], 0);
+
+            if(rho == 0.0)  // make sure that 0/0 cannot happen in the other cases
+                ac(k,0) = 1.0; // variable k is linearly dependent on the active set
+            else if(rho > 0.0)
+                ac(k,0) = cc / (cc + rho); // variable k would enter the active set with positive sign
+            else if(enforce_positive)
+                ac(k,0) = 1.0; // variable k cannot enter the active set because it would be negative
+            else
+                ac(k,0) = cc / (cc - rho); // variable k would enter the active set with negative sign
+        }
+
+        // in the non-negative case: make sure that a column just removed cannot re-enter right away
+        // (in standard LASSO, this is allowed, because the variable may re-enter with opposite sign)
+        if(enforce_positive && needToRemoveColumn)
+                ac(columnToBeRemoved-d.activeSetSize,0) = 1.0;
+
+        // find candidate
+        // Note: R uses Arg1() > epsilon, but this is only possible because it allows several variables to
+        //       join the active set simultaneously, so that gamma = 0 cannot occur.
+        columnToBeAdded = argMin(ac);
+
+        // if no new column can be added, we do a full step gamma = 1.0 and then stop, unless a column is removed below
+        T gamma = (d.activeSetSize == maxRank)
+                     ? 1.0
+                     : ac(columnToBeAdded, 0);
+
+        // adjust columnToBeAdded: we skipped the active set
+        if(columnToBeAdded >= 0)
+            columnToBeAdded += d.activeSetSize;
+
+        // check whether we have to remove a column from the active set
+        needToRemoveColumn = false;
+        if(lasso_modification)
+        {
+            // find dimensions whose weight changes sign below gamma*searchDirection
+            Matrix<T> s(Shape(d.activeSetSize, 1), NumericTraits<T>::max());
+            for(MultiArrayIndex k=0; k<d.activeSetSize; ++k)
+            {
+                if(( enforce_positive && d.next_lsq_solution(k,0) < 0.0) ||
+                   (!enforce_positive && sign(d.lars_solution(k,0))*sign(d.next_lsq_solution(k,0)) == -1.0))
+                        s(k,0) = d.lars_solution(k,0) / (d.lars_solution(k,0) - d.next_lsq_solution(k,0));
+            }
+
+            columnToBeRemoved = argMinIf(s, Arg1() <= Param(gamma));
+            if(columnToBeRemoved >= 0)
+            {
+                needToRemoveColumn = true; // remove takes precedence over add
+                gamma = s(columnToBeRemoved, 0);
+            }
+        }
+
+        // compute the current solutions
+        d.lars_prediction  = gamma * d.next_lsq_prediction + (1.0 - gamma) * d.lars_prediction;
+        d.lars_solution    = gamma * d.next_lsq_solution   + (1.0 - gamma) * d.lars_solution;
+        if(needToRemoveColumn)
+            d.lars_solution(columnToBeRemoved, 0) = 0.0;  // turn possible epsilon into an exact zero
+
+        // write the current solution
+        ++currentSolutionCount;
+        activeSets.push_back(typename Array1::value_type(d.columnPermutation.begin(), d.columnPermutation.begin()+d.activeSetSize));
+
+        if(lsq_solutions != 0)
+        {
+            if(enforce_positive)
+            {
+                ArrayVector<Matrix<T> > nnresults;
+                ArrayVector<ArrayVector<MultiArrayIndex> > nnactiveSets;
+                LarsData<T, C1, C2> nnd(d, d.activeSetSize);
+
+                leastAngleRegressionMainLoop(nnd, nnactiveSets, &nnresults, (Array3*)0,
+                                             LeastAngleRegressionOptions().leastSquaresSolutions(false).nnlasso());
+                //Matrix<T> nnlsq_solution(d.activeSetSize, 1);
+                typename Array2::value_type nnlsq_solution(Shape(d.activeSetSize, 1));
+                for(unsigned int k=0; k<nnactiveSets.back().size(); ++k)
+                {
+                    nnlsq_solution(nnactiveSets.back()[k],0) = nnresults.back()[k];
+                }
+                //lsq_solutions->push_back(nnlsq_solution);
+                lsq_solutions->push_back(typename Array3::value_type());
+                lsq_solutions->back() = nnlsq_solution;
+            }
+            else
+            {
+                //lsq_solutions->push_back(d.next_lsq_solution.subarray(Shape(0,0), Shape(d.activeSetSize, 1)));
+                lsq_solutions->push_back(typename Array3::value_type());
+                lsq_solutions->back() = d.next_lsq_solution.subarray(Shape(0,0), Shape(d.activeSetSize, 1));
+            }
+        }
+        if(lars_solutions != 0)
+        {
+            //lars_solutions->push_back(d.lars_solution.subarray(Shape(0,0), Shape(d.activeSetSize, 1)));
+            lars_solutions->push_back(typename Array2::value_type());
+            lars_solutions->back() = d.lars_solution.subarray(Shape(0,0), Shape(d.activeSetSize, 1));
+        }
+
+        // no further solutions possible
+        if(gamma == 1.0)
+            break;
+
+        if(needToRemoveColumn)
+        {
+            --d.activeSetSize;
+            if(columnToBeRemoved != d.activeSetSize)
+            {
+                // remove column 'columnToBeRemoved' and restore triangular form of R
+                // note: columnPermutation is automatically swapped here
+                detail::upperTriangularSwapColumns(columnToBeRemoved, d.activeSetSize, d.R, d.qtb, d.columnPermutation);
+
+                // swap solution entries
+                std::swap(d.lars_solution(columnToBeRemoved, 0), d.lars_solution(d.activeSetSize,0));
+                std::swap(d.next_lsq_solution(columnToBeRemoved, 0), d.next_lsq_solution(d.activeSetSize,0));
+                columnToBeRemoved = d.activeSetSize; // keep track of removed column
+            }
+            d.lars_solution(d.activeSetSize,0) = 0.0;
+            d.next_lsq_solution(d.activeSetSize,0) = 0.0;
+        }
+        else
+        {
+            vigra_invariant(columnToBeAdded >= 0,
+                "leastAngleRegression(): internal error (columnToBeAdded < 0)");
+            // add column 'columnToBeAdded'
+            if(d.activeSetSize != columnToBeAdded)
+            {
+                std::swap(d.columnPermutation[d.activeSetSize], d.columnPermutation[columnToBeAdded]);
+                columnVector(d.R, d.activeSetSize).swapData(columnVector(d.R, columnToBeAdded));
+                columnToBeAdded = d.activeSetSize; // keep track of added column
+            }
+
+            // zero the corresponding entries of the solutions
+            d.next_lsq_solution(d.activeSetSize,0) = 0.0;
+            d.lars_solution(d.activeSetSize,0) = 0.0;
+
+            // reduce R (i.e. its newly added column) to triangular form
+            detail::qrColumnHouseholderStep(d.activeSetSize, d.R, d.qtb);
+            ++d.activeSetSize;
+        }
+
+        // compute the LSQ solution of the new active set
+        Subarray Ractive = d.R.subarray(Shape(0,0), Shape(d.activeSetSize, d.activeSetSize));
+        Subarray qtbactive = d.qtb.subarray(Shape(0,0), Shape(d.activeSetSize, 1));
+        Subarray next_lsq_solution_view = d.next_lsq_solution.subarray(Shape(0,0), Shape(d.activeSetSize, 1));
+        linearSolveUpperTriangular(Ractive, qtbactive, next_lsq_solution_view);
+
+        // compute the LSQ prediction of the new active set
+        d.next_lsq_prediction.init(0.0);
+        for(MultiArrayIndex k=0; k<d.activeSetSize; ++k)
+            d.next_lsq_prediction += next_lsq_solution_view(k,0)*columnVector(d.A, d.columnPermutation[k]);
+    }
+
+    return (unsigned int)currentSolutionCount;
+}
+
+template <class T, class C1, class C2, class Array1, class Array2>
+unsigned int
+leastAngleRegressionImpl(MultiArrayView<2, T, C1> const & A, MultiArrayView<2, T, C2> const &b,
+                         Array1 & activeSets, Array2 * lasso_solutions, Array2 * lsq_solutions,
+                         LeastAngleRegressionOptions const & options)
+{
+    using namespace vigra::functor;
+
+    const MultiArrayIndex rows = rowCount(A);
+
+    vigra_precondition(rowCount(b) == rows && columnCount(b) == 1,
+       "leastAngleRegression(): Shape mismatch between matrices A and b.");
+
+    bool enforce_positive = (options.mode == LeastAngleRegressionOptions::NNLASSO);
+
+    detail::LarsData<T, C1, C2> d(A, b);
+
+    // find dimension with largest correlation
+    Matrix<T> c = transpose(A)*b;
+    MultiArrayIndex initialColumn = enforce_positive
+                                       ? argMaxIf(c, Arg1() > Param(0.0))
+                                       : argMax(abs(c));
+    if(initialColumn == -1)
+        return 0; // no solution found
+
+    // prepare initial active set and search direction etc.
+    std::swap(d.columnPermutation[0], d.columnPermutation[initialColumn]);
+    columnVector(d.R, 0).swapData(columnVector(d.R, initialColumn));
+    detail::qrColumnHouseholderStep(0, d.R, d.qtb);
+    d.next_lsq_solution(0,0) = d.qtb(0,0) / d.R(0,0);
+    d.next_lsq_prediction = d.next_lsq_solution(0,0) * columnVector(A, d.columnPermutation[0]);
+    d.searchVector = d.next_lsq_solution(0,0) * columnVector(A, d.columnPermutation[0]);
+
+    return leastAngleRegressionMainLoop(d, activeSets, lasso_solutions, lsq_solutions, options);
+}
+
+} // namespace detail
+
+/** Least Angle Regression.
+
+       <b>\#include</b> \<vigra/regression.hxx\><br/>
+       Namespaces: vigra and vigra::linalg
+     
+       <b> Declarations:</b>
+     
+       \code
+       namespace vigra {
+          namespace linalg {
+            // compute either LASSO or least squares solutions
+            template <class T, class C1, class C2, class Array1, class Array2>
+            unsigned int
+            leastAngleRegression(MultiArrayView<2, T, C1> const & A, MultiArrayView<2, T, C2> const &b,
+                     Array1 & activeSets, Array2 & solutions,
+                     LeastAngleRegressionOptions const & options = LeastAngleRegressionOptions());
+
+            // compute LASSO and least squares solutions
+            template <class T, class C1, class C2, class Array1, class Array2>
+            unsigned int
+            leastAngleRegression(MultiArrayView<2, T, C1> const & A, MultiArrayView<2, T, C2> const &b,
+                     Array1 & activeSets, Array2 & lasso_solutions, Array2 & lsq_solutions,
+                     LeastAngleRegressionOptions const & options = LeastAngleRegressionOptions());
+          }
+          using linalg::leastAngleRegression;
+       }
+       \endcode
+
+       This function implements Least Angle Regression (LARS) as described in
+
+              
+       B.Efron, T.Hastie, I.Johnstone, and R.Tibshirani: <i>"Least Angle Regression"</i>,
+       Annals of Statistics 32(2):407-499, 2004.
+
+       It is an efficient algorithm to solve the L1-regularized least squares (LASSO) problem
+
+        \f[ \tilde \textrm{\bf x} = \textrm{argmin}
+             \left|\left|\textrm{\bf A} \textrm{\bf x} - \textrm{\bf b}\right|\right|_2^2
+           \textrm{ subject to } \left|\left|\textrm{\bf x}\right|\right|_1\le s
+        \f]
+
+       and the L1-regularized non-negative least squares (NN-LASSO) problem
+
+        \f[ \tilde \textrm{\bf x} = \textrm{argmin} \left|\left|\textrm{\bf A} \textrm{\bf x} - \textrm{\bf b}\right|\right|_2^2
+           \textrm{ subject to } \left|\left|\textrm{\bf x}\right|\right|_1\le s \textrm{ and } \textrm{\bf x}\ge \textrm{\bf 0}
+        \f]
+
+       where \a A is a matrix with <tt>m</tt> rows and <tt>n</tt> columns (often with <tt>m \< n</tt>),
+       \a b a vector of length <tt>m</tt>, and a regularization parameter s \>= 0.0.
+       L1-regularization has the desirable effect that it causes the solution <b>x</b> to be sparse, i.e. only
+       the most important elements in <b>x</b> (called the <em>active set</em>) have non-zero values. The
+       key insight of the LARS algorithm is the following: When the solution vector <b>x</b> is considered
+       as a function of the regularization parameter s, then <b>x</b>(s) is a piecewise
+       linear function, i.e. a polyline in n-dimensional space. The knots of the polyline <b>x</b>(s)
+       are located precisely at those values of s where one variable enters or leaves the active set
+       and can be efficiently computed.
+
+       Therefore, leastAngleRegression() returns the entire solution path as a sequence of knot points, starting
+       at \f$\textrm{\bf x}(s=0)\f$ (where the only feasible solution is obviously <b>x</b> = 0) and ending at
+       \f$\textrm{\bf x}(s=\infty)\f$ (where the solution becomes the ordinary least squares solution). Actually,
+       the initial null solution is not explicitly returned, i.e. the sequence starts at the first non-zero
+       solution with one variable in the active set. The function leastAngleRegression() returns the number
+       of solutions (i.e. knot points) computed.
+
+       The sequences of active sets and corresponding variable weights are returned in \a activeSets and
+       \a solutions respectively. That is, <tt>activeSets[i]</tt> is an \ref vigra::ArrayVector "ArrayVector\<int\>"
+       containing the indices of the variables that are active at the i-th knot, and <tt>solutions</tt> is a
+       \ref vigra::linalg::Matrix "Matrix\<T\>" containing the weights of those variables, in the same order (see
+       example below). Variables not contained in <tt>activeSets[i]</tt> are zero at this solution.
+
+       The behavior of the algorithm can be adapted by \ref vigra::linalg::LeastAngleRegressionOptions
+       "LeastAngleRegressionOptions":
+        <DL>
+        <DT><b>options.lasso()</b> (active by default)
+                          <DD> Compute the LASSO solution as described above.
+        <DT><b>options.nnlasso()</b> (inactive by default)
+                          <DD> Compute non-negative LASSO solutions, i.e. use the additional constraint that
+                               <b>x</b> \>= 0 in all solutions.
+        <DT><b>options.lars()</b> (inactive by default)
+                          <DD> Compute a solution path according to the plain LARS rule, i.e. never remove
+                               a variable from the active set once it entered.
+        <DT><b>options.leastSquaresSolutions(bool)</b> (default: true)
+                          <DD> Use the algorithm mode selected above
+                               to determine the sequence of active sets, but then compute and return an
+                               ordinary (unconstrained) least squares solution for every active set.<br>
+                               <b>Note:</b> The second form of leastAngleRegression() ignores this option and
+                               does always compute both constrained and unconstrained solutions (returned in
+                               \a lasso_solutions and \a lsq_solutions respectively).
+        <DT><b>maxSolutionCount(unsigned int n)</b> (default: n = 0, i.e. compute all solutions)
+                          <DD> Compute at most <tt>n</tt> solutions.
+        </DL>
+
+        <b>Usage:</b>
+
+        \code
+        int m = ..., n = ...;
+        Matrix<double> A(m, n), b(m, 1);
+        ... // fill A and b
+
+        // normalize the input
+        Matrix<double> offset(1,n), scaling(1,n);
+        prepareColumns(A, A, offset, scaling, DataPreparationGoals(ZeroMean|UnitVariance));
+        prepareColumns(b, b, DataPreparationGoals(ZeroMean));
+
+        // arrays to hold the output
+        ArrayVector<ArrayVector<int> > activeSets;
+        ArrayVector<Matrix<double> > solutions;
+
+        // run leastAngleRegression() in non-negative LASSO mode
+        int numSolutions = leastAngleRegression(A, b, activeSets, solutions,
+                                    LeastAngleRegressionOptions().nnlasso());
+
+        // print results
+        Matrix<double> denseSolution(1, n);
+        for (MultiArrayIndex k = 0; k < numSolutions; ++k)
+        {
+            // transform the sparse solution into a dense vector
+            denseSolution.init(0.0); // ensure that inactive variables are zero
+            for (unsigned int i = 0; i < activeSets[k].size(); ++i)
+            {
+                // set the values of the active variables;
+                // activeSets[k][i] is the true index of the i-th variable in the active set
+                denseSolution(0, activeSets[k][i]) = solutions[k](i,0);
+            }
+
+            // invert the input normalization
+            denseSolution = denseSolution * pointWise(scaling);
+
+            // output the solution
+            std::cout << "solution " << k << ":\n" << denseSolution << std::endl;
+        }
+        \endcode
+
+        <b>Required Interface:</b>
+
+        <ul>
+        <li> <tt>T</tt> must be numeric type (compatible to double)
+        <li> <tt>Array1 a1;</tt><br>
+             <tt>a1.push_back(ArrayVector\<int\>());</tt>
+        <li> <tt>Array2 a2;</tt><br>
+             <tt>a2.push_back(Matrix\<T\>());</tt>
+        </ul>
+   */
+doxygen_overloaded_function(template <...> unsigned int leastAngleRegression)
+
+template <class T, class C1, class C2, class Array1, class Array2>
+inline unsigned int
+leastAngleRegression(MultiArrayView<2, T, C1> const & A, MultiArrayView<2, T, C2> const &b,
+                     Array1 & activeSets, Array2 & solutions,
+                     LeastAngleRegressionOptions const & options = LeastAngleRegressionOptions())
+{
+    if(options.least_squares_solutions)
+        return detail::leastAngleRegressionImpl(A, b, activeSets, (Array2*)0, &solutions, options);
+    else
+        return detail::leastAngleRegressionImpl(A, b, activeSets, &solutions, (Array2*)0, options);
+}
+
+template <class T, class C1, class C2, class Array1, class Array2>
+inline unsigned int
+leastAngleRegression(MultiArrayView<2, T, C1> const & A, MultiArrayView<2, T, C2> const &b,
+                     Array1 & activeSets, Array2 & lasso_solutions, Array2 & lsq_solutions,
+                     LeastAngleRegressionOptions const & options = LeastAngleRegressionOptions())
+{
+    return detail::leastAngleRegressionImpl(A, b, activeSets, &lasso_solutions, &lsq_solutions, options);
+}
+
+   /** Non-negative Least Squares Regression.
+
+       Given a matrix \a A with <tt>m</tt> rows and <tt>n</tt> columns (with <tt>m \>= n</tt>),
+       and a column vector \a b of length <tt>m</tt> rows, this function computes
+       a column vector \a x of length <tt>n</tt> with <b>non-negative entries</b> that solves the optimization problem
+
+        \f[ \tilde \textrm{\bf x} = \textrm{argmin}
+            \left|\left|\textrm{\bf A} \textrm{\bf x} - \textrm{\bf b}\right|\right|_2^2
+            \textrm{ subject to } \textrm{\bf x} \ge \textrm{\bf 0}
+        \f]
+
+       Both \a b and \a x must be column vectors (i.e. matrices with <tt>1</tt> column).
+       Note that all matrices must already have the correct shape. The solution is computed by means
+       of \ref leastAngleRegression() with non-negativity constraint.
+
+       <b>\#include</b> \<vigra/regression.hxx\>
+       Namespaces: vigra and vigra::linalg
+   */
+template <class T, class C1, class C2, class C3>
+inline void
+nonnegativeLeastSquares(MultiArrayView<2, T, C1> const & A,
+                        MultiArrayView<2, T, C2> const &b, MultiArrayView<2, T, C3> &x)
+{
+    vigra_precondition(columnCount(A) == rowCount(x) && rowCount(A) == rowCount(b),
+        "nonnegativeLeastSquares(): Matrix shape mismatch.");
+    vigra_precondition(columnCount(b) == 1 && columnCount(x) == 1,
+        "nonnegativeLeastSquares(): RHS and solution must be vectors (i.e. columnCount == 1).");
+
+    ArrayVector<ArrayVector<MultiArrayIndex> > activeSets;
+    ArrayVector<Matrix<T> > results;
+
+    leastAngleRegression(A, b, activeSets, results,
+                         LeastAngleRegressionOptions().leastSquaresSolutions(false).nnlasso());
+    x.init(NumericTraits<T>::zero());
+    if(activeSets.size() > 0)
+        for(unsigned int k=0; k<activeSets.back().size(); ++k)
+            x(activeSets.back()[k],0) = results.back()[k];
+}
+
+
+//@}
+
+} // namespace linalg
+
+using linalg::leastSquares;
+using linalg::weightedLeastSquares;
+using linalg::ridgeRegression;
+using linalg::weightedRidgeRegression;
+using linalg::ridgeRegressionSeries;
+using linalg::nonnegativeLeastSquares;
+using linalg::leastAngleRegression;
+using linalg::LeastAngleRegressionOptions;
+
+namespace detail {
+
+template <class T, class S>
+inline T 
+getRow(MultiArrayView<1, T, S> const & a, MultiArrayIndex i)
+{
+    return a(i);
+}
+
+template <class T, class S>
+inline MultiArrayView<1, T>
+getRow(MultiArrayView<2, T, S> const & a, MultiArrayIndex i)
+{
+    return a.bindInner(i);
+}
+
+} // namespace detail
+
+/** \addtogroup Optimization
+ */
+//@{
+
+/** \brief Pass options to nonlinearLeastSquares().
+
+    <b>\#include</b> \<vigra/regression.hxx\>
+    Namespace: vigra
+*/
+class NonlinearLSQOptions
+{
+  public:
+  
+    double epsilon, lambda, tau;
+    int max_iter;
+    
+        /** \brief Initialize options with default values.
+        */
+    NonlinearLSQOptions()
+    : epsilon(0.0),
+      lambda(0.1),
+      tau(1.4),
+      max_iter(50)
+    {}
+    
+        /** \brief Set minimum relative improvement in residual.
+        
+            The algorithm stops when the relative improvement in residuals
+            between consecutive iterations is less than this value.
+            
+            Default: 0 (i.e. choose tolerance automatically, will be 10*epsilon of the numeric type)
+        */
+    NonlinearLSQOptions & tolerance(double eps)
+    {
+        epsilon = eps;
+        return *this;
+    }
+    
+        /** \brief Set maximum number of iterations.
+        
+            Default: 50
+        */
+    NonlinearLSQOptions & maxIterations(int iter)
+    {
+        max_iter = iter;
+        return *this;
+    }
+    
+        /** \brief Set damping parameters for Levenberg-Marquardt algorithm.
+        
+            \a lambda determines by how much the diagonal is emphasized, and \a v is 
+            the factor by which lambda will be increased if more damping is needed 
+            for convergence
+            (see <a href="http://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm">Wikipedia</a>
+            for more explanations).
+        
+            Default: lambda = 0.1, v = 1.4
+        */
+    NonlinearLSQOptions & dampingParamters(double lambda, double v)
+    {
+        vigra_precondition(lambda > 0.0 && v > 0.0,
+            "NonlinearLSQOptions::dampingParamters(): parameters must be positive.");
+        this->lambda = lambda;
+        tau = v;
+        return *this;
+    }
+};
+
+template <unsigned int D, class T, class S1, class S2, 
+          class U, int N, 
+          class Functor>
+T
+nonlinearLeastSquaresImpl(MultiArrayView<D, T, S1> const & features,
+                          MultiArrayView<1, T, S2> const & response,
+                          TinyVector<U, N> & p, 
+                          Functor model,
+                          NonlinearLSQOptions const & options)
+{
+    vigra_precondition(features.shape(0) == response.shape(0),
+                       "nonlinearLeastSquares(): shape mismatch between features and response.");
+                       
+    double t = options.tau, l = options.lambda;  // initial damping parameters
+    
+    double epsilonT = NumericTraits<T>::epsilon()*10.0,
+           epsilonU = NumericTraits<U>::epsilon()*10.0,
+           epsilon = options.epsilon <= 0.0
+                         ? std::max(epsilonT, epsilonU)
+                         : options.epsilon;
+    
+    linalg::Matrix<T> jj(N,N);  // outer product of the Jacobian
+    TinyVector<U, N> jr, dp;
+    
+    T residual = 0.0;
+    bool didStep = true;
+    
+    for(int iter=0; iter<options.max_iter; ++iter)
+    {
+        if(didStep)
+        {
+            // update the residual and Jacobian
+            residual = 0.0;
+            jr = 0.0;
+            jj = 0.0;
+            
+            for(int i=0; i<features.shape(0); ++i)
+            {
+                autodiff::DualVector<U, N> res = model(detail::getRow(features, i), autodiff::dualMatrix(p));
+                
+                T r = response(i) - res.v;
+                jr += r * res.d;
+                jj += outer(res.d);
+                residual += sq(r);
+            }
+        }
+        
+        // perform a damped gradient step
+        linalg::Matrix<T> djj(jj);
+        djj.diagonal() *= 1.0 + l;        
+        linearSolve(djj, jr, dp);
+        
+        TinyVector<U, N> p_new = p + dp;
+        
+        // compute the new residual
+        T residual_new = 0.0;
+        for(int i=0; i<features.shape(0); ++i)
+        {
+            residual_new += sq(response(i) - model(detail::getRow(features, i), p_new));
+        }
+        
+        if(residual_new < residual)
+        {
+            // accept the step
+            p = p_new;
+            if(std::abs((residual - residual_new) / residual) < epsilon)
+                return residual_new;
+            // try less damping in the next iteration
+            l /= t;
+            didStep = true;
+        }
+        else
+        {
+            // reject the step und use more damping in the next iteration
+            l *= t;
+            didStep = false;
+        }
+    }
+    
+    return residual;
+}
+
+/********************************************************/
+/*                                                      */
+/*                 nonlinearLeastSquares                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Fit a non-linear model to given data by minimizing least squares loss.
+
+    <b> Declarations:</b>
+    
+    \code
+    namespace vigra {
+        // variant 1: optimize a univariate model ('x' is a 1D array of scalar data points)
+        template <class T, class S1, class S2, 
+                  class U, int N, 
+                  class Functor>
+        T
+        nonlinearLeastSquares(MultiArrayView<1, T, S1> const & x,
+                              MultiArrayView<1, T, S2> const & y,
+                              TinyVector<U, N> & model_parameters, 
+                              Functor model,
+                              NonlinearLSQOptions const & options = NonlinearLSQOptions());
+
+        // variant 2: optimize a multivariate model ('x' is a 2D array of vector-valued data points)
+        template <class T, class S1, class S2, 
+                  class U, int N, 
+                  class Functor>
+        T
+        nonlinearLeastSquares(MultiArrayView<2, T, S1> const & x,
+                              MultiArrayView<1, T, S2> const & y,
+                              TinyVector<U, N> & model_parameters, 
+                              Functor model,
+                              NonlinearLSQOptions const & options = NonlinearLSQOptions());
+    }
+    \endcode
+    
+    This function implements the 
+    <a href="http://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm">Levenberg-Marquardt algorithm</a>
+    to fit a non-linear model to given data. The model depends on a vector of 
+    parameters <b>p</b> which are to be choosen such that the least-squares residual 
+    between the data and the model's predictions is minimized according to the objective function:
+
+    \f[ \tilde \textrm{\bf p} = \textrm{argmin}_{\textrm{\bf p}} \sum_i \left( y_i - f(\textrm{\bf x}_i; \textrm{\bf p}) \right)^2
+    \f]
+
+    where \f$f(\textrm{\bf x}; \textrm{\bf p})\f$ is the model to be optimized 
+    (with arguments \f$\textrm{\bf x}\f$ and parameters \f$\textrm{\bf p}\f$), and 
+    \f$(\textrm{\bf x}_i; y_i)\f$ are the feature/response pairs of the given data. 
+    Since the model is non-linear (otherwise, you should use ordinary \ref leastSquares()), 
+    it must be linearized in terms of a first-order Taylor expansion, and the optimal 
+    parameters <b>p</b> have to be determined iteratively. In order for the iterations to 
+    converge to the desired solution, a good initial guess on <b>p</b> is required.
+    
+    The model must be specified by a functor which takes one of the following forms:
+    \code
+    typedef double DataType;   // type of your data samples, may be any numeric type
+    static const int N = ...;  // number of model parameters
+    
+    // variant 1: the features x are scalars
+    struct UnivariateModel 
+    {
+        template <class T>
+        T operator()(DataType x, TinyVector<T, N> const & p) const { ... }
+    };
+    
+    // variant 2: the features x are vectors
+    struct MultivariateModel
+    {
+        template <class T>
+        T operator()(MultiArrayView<1, DataType> const & x, TinyVector<T, N> const & p) const { ... }
+    };
+    \endcode
+    Each call to the functor's <tt>operator()</tt> computes the model's prediction for a single data
+    point. The current model parameters are specified in a TinyVector of appropriate length. 
+    The type <tt>T</tt> must be templated: normally, it is the same as <tt>DataType</tt>, but
+    the nonlinearLeastSquares() function will temporarily replace it with a special number type
+    that supports <a href="http://en.wikipedia.org/wiki/Automatic_differentiation">automatic differentiation</a> 
+    (see \ref vigra::autodiff::DualVector). In this way, the derivatives needed in the model's Taylor 
+    expansion can be computed automatically.
+    
+    When the model is univariate (has a single scalar argument), the samples must be passed to 
+    nonlinearLeastSquares() in a pair 'x', 'y' of 1D <tt>MultiArrayView</tt>s (variant 1).
+    When the model is multivariate (has a vector-valued argument), the 'x' input must
+    be a 2D <tt>MultiArrayView</tt> (variant 2) whose rows represent a single data sample 
+    (i.e. the number of columns corresponds to the length of the model's argument vector). 
+    The number of rows in 'x' defines the number of data samples and must match the length
+    of array 'y'.
+    
+    The <tt>TinyVector</tt> 'model_parameters' holds the initial guess for the model parameters and
+    will be overwritten by the optimal values found by the algorithm. The algorithm's internal behavior
+    can be controlled by customizing the option object \ref vigra::NonlinearLSQOptions. 
+    
+    The function returns the residual sum of squared errors of the final solution.
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/regression.hxx\><br>
+    Namespace: vigra
+    
+    Suppose that we want to fit a centered Gaussian function of the form
+    \f[ f(x ; a, s, b) = a \exp\left(-\frac{x^2}{2 s^2}\right) + b  \f]
+    to noisy data \f$(x_i, y_i)\f$, i.e. we want to find parameters a, s, b such that
+    the residual \f$\sum_i \left(y_i - f(x_i; a,s,b)\right)^2\f$ is minimized.
+    The model parameters are placed in a <tt>TinyVector<T, 3></tt> <b>p</b> according to the rules<br/>
+    <tt>p[0] <=> a</tt>, <tt>p[1] <=> s</tt> and <tt>p[2] <=> b</tt>.<br/> The following
+    functor computes the model's prediction for a single data point <tt>x</tt>:
+    \code
+    struct GaussianModel
+    {
+        template <class T>
+        T operator()(double x, TinyVector<T, 3> const & p) const
+        {
+            return p[0] * exp(-0.5 * sq(x / p[1])) + p[2];
+        }
+    };
+    \endcode
+    Now we can find optimal values for the parameters like this:
+    \code
+    int size = ...;  // number of data points
+    MultiArray<1, double> x(size), y(size);    
+    ...   // fill the data arrays
+    
+    TinyVector<double, 3> p(2.0, 1.0, 0.5);  // your initial guess of the parameters
+                                             // (will be overwritten with the optimal values)
+    double residual = nonlinearLeastSquares(x, y, p, GaussianModel());
+    
+    std::cout << "Model parameters: a=" << p[0] << ", s=" << p[1] << ", b=" << p[2] << " (residual: " << residual << ")\n";
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void nonlinearLeastSquares)
+
+template <class T, class S1, class S2, 
+          class U, int N, 
+          class Functor>
+inline T
+nonlinearLeastSquares(MultiArrayView<1, T, S1> const & features,
+                      MultiArrayView<1, T, S2> const & response,
+                      TinyVector<U, N> & p, 
+                      Functor model,
+                      NonlinearLSQOptions const & options = NonlinearLSQOptions())
+{
+    return nonlinearLeastSquaresImpl(features, response, p, model, options);
+}
+
+template <class T, class S1, class S2, 
+          class U, int N, 
+          class Functor>
+inline T
+nonlinearLeastSquares(MultiArrayView<2, T, S1> const & features,
+                      MultiArrayView<1, T, S2> const & response,
+                      TinyVector<U, N> & p, 
+                      Functor model,
+                      NonlinearLSQOptions const & options = NonlinearLSQOptions())
+{
+    return nonlinearLeastSquaresImpl(features, response, p, model, options);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_REGRESSION_HXX
diff --git a/include/vigra/resampling_convolution.hxx b/include/vigra/resampling_convolution.hxx
new file mode 100644
index 0000000..da64210
--- /dev/null
+++ b/include/vigra/resampling_convolution.hxx
@@ -0,0 +1,1202 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_RESAMPLING_CONVOLUTION_HXX
+#define VIGRA_RESAMPLING_CONVOLUTION_HXX
+
+#include <cmath>
+#include "stdimage.hxx"
+#include "array_vector.hxx"
+#include "rational.hxx"
+#include "functortraits.hxx"
+#include "functorexpression.hxx"
+#include "transformimage.hxx"
+#include "imagecontainer.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+namespace resampling_detail
+{
+
+struct MapTargetToSourceCoordinate
+{
+    MapTargetToSourceCoordinate(Rational<int> const & samplingRatio,
+                                Rational<int> const & offset)
+    : a(samplingRatio.denominator()*offset.denominator()),
+      b(samplingRatio.numerator()*offset.numerator()),
+      c(samplingRatio.numerator()*offset.denominator())
+    {}
+
+//        the following functions are more efficient realizations of:
+//             rational_cast<T>(i / samplingRatio + offset);
+//        we need efficiency because this may be called in the inner loop
+
+    int operator()(int i) const
+    {
+        return (i * a + b) / c;
+    }
+
+    double toDouble(int i) const
+    {
+        return double(i * a + b) / c;
+    }
+
+    Rational<int> toRational(int i) const
+    {
+        return Rational<int>(i * a + b, c);
+    }
+    
+    bool isExpand2() const
+    {
+        return a == 1 && b == 0 && c == 2;
+    }
+    
+    bool isReduce2() const
+    {
+        return a == 2 && b == 0 && c == 1;
+    }
+
+    int a, b, c;
+};
+
+} // namespace resampling_detail
+
+template <>
+class FunctorTraits<resampling_detail::MapTargetToSourceCoordinate>
+: public FunctorTraitsBase<resampling_detail::MapTargetToSourceCoordinate>
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+template <class SrcIter, class SrcAcc,
+          class DestIter, class DestAcc,
+          class KernelArray>
+void
+resamplingExpandLine2(SrcIter s, SrcIter send, SrcAcc src,
+                       DestIter d, DestIter dend, DestAcc dest,
+                       KernelArray const & kernels)
+{
+    typedef typename KernelArray::value_type Kernel;
+    typedef typename KernelArray::const_reference KernelRef;
+    typedef typename Kernel::const_iterator KernelIter;
+
+    typedef typename
+        PromoteTraits<typename SrcAcc::value_type, typename Kernel::value_type>::Promote
+        TmpType;
+
+    int wo = send - s;
+    int wn = dend - d;
+    int wo2 = 2*wo - 2;
+    
+    int ileft = std::max(kernels[0].right(), kernels[1].right());
+    int iright = wo + std::min(kernels[0].left(), kernels[1].left()) - 1;
+    for(int i = 0; i < wn; ++i, ++d)
+    {
+        int is = i / 2;
+        KernelRef kernel = kernels[i & 1];
+        KernelIter k = kernel.center() + kernel.right();
+        TmpType sum = NumericTraits<TmpType>::zero();        
+        if(is < ileft)
+        {
+            for(int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
+            {
+                int mm = (m < 0) 
+                        ? -m 
+                        : m;
+                sum += *k * src(s, mm);
+            }        
+        }
+        else if(is > iright)
+        {
+            for(int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
+            {
+                int mm =  (m >= wo) 
+                            ? wo2 - m
+                            : m;
+                sum += *k * src(s, mm);
+            }        
+        }
+        else
+        {
+            SrcIter ss = s + is - kernel.right();
+            for(int m = 0; m < kernel.size(); ++m, --k, ++ss)
+            {
+                sum += *k * src(ss);
+            }        
+        }
+        dest.set(sum, d);
+    }
+}
+
+template <class SrcIter, class SrcAcc,
+          class DestIter, class DestAcc,
+          class KernelArray>
+void
+resamplingReduceLine2(SrcIter s, SrcIter send, SrcAcc src,
+                       DestIter d, DestIter dend, DestAcc dest,
+                       KernelArray const & kernels)
+{
+    typedef typename KernelArray::value_type Kernel;
+    typedef typename KernelArray::const_reference KernelRef;
+    typedef typename Kernel::const_iterator KernelIter;
+
+    KernelRef kernel = kernels[0];
+    KernelIter kbegin = kernel.center() + kernel.right();
+
+    typedef typename
+        PromoteTraits<typename SrcAcc::value_type, typename Kernel::value_type>::Promote
+        TmpType;
+
+    int wo = send - s;
+    int wn = dend - d;
+    int wo2 = 2*wo - 2;
+    
+    int ileft = kernel.right();
+    int iright = wo + kernel.left() - 1;
+    for(int i = 0; i < wn; ++i, ++d)
+    {
+        int is = 2 * i;
+        KernelIter k = kbegin;
+        TmpType sum = NumericTraits<TmpType>::zero();        
+        if(is < ileft)
+        {
+            for(int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
+            {
+                int mm = (m < 0) 
+                        ? -m 
+                        : m;
+                sum += *k * src(s, mm);
+            }        
+        }
+        else if(is > iright)
+        {
+            for(int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
+            {
+                int mm =  (m >= wo) 
+                            ? wo2 - m
+                            : m;
+                sum += *k * src(s, mm);
+            }        
+        }
+        else
+        {
+            SrcIter ss = s + is - kernel.right();
+            for(int m = 0; m < kernel.size(); ++m, --k, ++ss)
+            {
+                sum += *k * src(ss);
+            }        
+        }
+        dest.set(sum, d);
+    }
+}
+
+/** \addtogroup ResamplingConvolutionFilters Resampling Convolution Filters
+
+    These functions implement the convolution operation when the source and target images
+    have different sizes. This is realized by accessing a continuous kernel at the
+    appropriate non-integer positions. The technique is, for example, described in
+    D. Schumacher: <i>General Filtered Image Rescaling</i>, in: Graphics Gems III,
+    Academic Press, 1992.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                resamplingConvolveLine                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs a 1-dimensional resampling convolution of the source signal using the given
+    set of kernels.
+
+    This function is mainly used internally: It is called for each dimension of a 
+    higher dimensional array in order to perform a separable resize operation.
+
+    <b> Declaration:</b>
+
+    <b>\#include</b> \<vigra/resampling_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    namespace vigra {
+        template <class SrcIter, class SrcAcc,
+                  class DestIter, class DestAcc,
+                  class KernelArray,
+                  class Functor>
+        void
+        resamplingConvolveLine(SrcIter s, SrcIter send, SrcAcc src,
+                               DestIter d, DestIter dend, DestAcc dest,
+                               KernelArray const & kernels,
+                               Functor mapTargetToSourceCoordinate)    
+    }
+    \endcode
+
+*/
+doxygen_overloaded_function(template <...> void resamplingConvolveLine)
+
+template <class SrcIter, class SrcAcc,
+          class DestIter, class DestAcc,
+          class KernelArray,
+          class Functor>
+void
+resamplingConvolveLine(SrcIter s, SrcIter send, SrcAcc src,
+                       DestIter d, DestIter dend, DestAcc dest,
+                       KernelArray const & kernels,
+                       Functor mapTargetToSourceCoordinate)
+{
+    if(mapTargetToSourceCoordinate.isExpand2())
+    {
+        resamplingExpandLine2(s, send, src, d, dend, dest, kernels);
+        return;
+    }
+    if(mapTargetToSourceCoordinate.isReduce2())
+    {
+        resamplingReduceLine2(s, send, src, d, dend, dest, kernels);
+        return;
+    }
+    
+    typedef typename
+        NumericTraits<typename SrcAcc::value_type>::RealPromote
+        TmpType;
+    typedef typename KernelArray::value_type Kernel;
+    typedef typename Kernel::const_iterator KernelIter;
+
+    int wo = send - s;
+    int wn = dend - d;
+    int wo2 = 2*wo - 2;
+
+    int i;
+    typename KernelArray::const_iterator kernel = kernels.begin();
+    for(i=0; i<wn; ++i, ++d, ++kernel)
+    {
+        // use the kernels periodically
+        if(kernel == kernels.end())
+            kernel = kernels.begin();
+
+        // calculate current target point into source location
+        int is = mapTargetToSourceCoordinate(i);
+
+        TmpType sum = NumericTraits<TmpType>::zero();
+
+        int lbound = is - kernel->right(),
+            hbound = is - kernel->left();
+
+        KernelIter k = kernel->center() + kernel->right();
+        if(lbound < 0 || hbound >= wo)
+        {
+            vigra_precondition(-lbound < wo && wo2 - hbound >= 0,
+                "resamplingConvolveLine(): kernel or offset larger than image.");
+            for(int m=lbound; m <= hbound; ++m, --k)
+            {
+                int mm = (m < 0) ?
+                            -m :
+                            (m >= wo) ?
+                                wo2 - m :
+                                m;
+                sum = TmpType(sum + *k * src(s, mm));
+            }
+        }
+        else
+        {
+            SrcIter ss = s + lbound;
+            SrcIter ssend = s + hbound;
+
+            for(; ss <= ssend; ++ss, --k)
+            {
+                sum = TmpType(sum + *k * src(ss));
+            }
+        }
+
+        dest.set(sum, d);
+    }
+}
+
+template <class Kernel, class MapCoordinate, class KernelArray>
+void
+createResamplingKernels(Kernel const & kernel,
+             MapCoordinate const & mapCoordinate, KernelArray & kernels)
+{
+    for(unsigned int idest = 0; idest < kernels.size(); ++idest)
+    {
+        int isrc = mapCoordinate(idest);
+        double idsrc = mapCoordinate.toDouble(idest);
+        double offset = idsrc - isrc;
+        double radius = kernel.radius();
+        int left = std::min(0, int(ceil(-radius - offset)));
+        int right = std::max(0, int(floor(radius - offset)));
+        kernels[idest].initExplicitly(left, right);
+
+        double x = left + offset;
+        for(int i = left; i <= right; ++i, ++x)
+            kernels[idest][i] = kernel(x);
+        kernels[idest].normalize(1.0, kernel.derivativeOrder(), offset);
+    }
+}
+
+/** \brief Apply a resampling filter in the x-direction.
+
+    This function implements a convolution operation in x-direction
+    (i.e. applies a 1D filter to every row) where the width of the source
+    and destination images differ. This is typically used to avoid aliasing if
+    the image is scaled down, or to interpolate smoothly if the image is scaled up.
+    The target coordinates are transformed into source coordinates by
+
+    \code
+    xsource = (xtarget - offset) / samplingRatio
+    \endcode
+
+    The <tt>samplingRatio</tt> and <tt>offset</tt> must be given as \ref vigra::Rational
+    in order to avoid rounding errors in this transformation. It is required that for all
+    pixels of the target image, <tt>xsource</tt> remains within the range of the source
+    image (i.e. <tt>0 <= xsource <= sourceWidth-1</tt>. Since <tt>xsource</tt> is
+    in general not an integer, the <tt>kernel</tt> must be a functor that can be accessed at
+    arbitrary (<tt>double</tt>) coordinates. It must also provide a member function <tt>radius()</tt>
+    which specifies the support (non-zero interval) of the kernel. VIGRA already
+    provides a number of suitable functors, e.g. \ref vigra::Gaussian, \ref vigra::BSpline
+    \ref vigra::CatmullRomSpline, and \ref vigra::CoscotFunction. The function
+    \ref resizeImageSplineInterpolation() is implemented by means of resamplingConvolveX() and
+    resamplingConvolveY().
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class Kernel>
+        void
+        resamplingConvolveX(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            Kernel const & kernel,
+                            Rational<int> const & samplingRatio, Rational<int> const & offset);
+    }
+    \endcode
+
+    \deprecatedAPI{resamplingConvolveX}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIter, class SrcAcc,
+                  class DestIter, class DestAcc,
+                  class Kernel>
+        void
+        resamplingConvolveX(SrcIter sul, SrcIter slr, SrcAcc src,
+                            DestIter dul, DestIter dlr, DestAcc dest,
+                            Kernel const & kernel,
+                            Rational<int> const & samplingRatio, Rational<int> const & offset);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIter, class SrcAcc,
+                  class DestIter, class DestAcc,
+                  class Kernel>
+        void
+        resamplingConvolveX(triple<SrcIter, SrcIter, SrcAcc> src,
+                            triple<DestIter, DestIter, DestAcc> dest,
+                            Kernel const & kernel,
+                            Rational<int> const & samplingRatio, Rational<int> const & offset);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/resampling_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Rational<int> ratio(2), offset(0);
+
+    MultiArray<2, float> src(w,h),
+                         dest(rational_cast<int>(ratio*w), h);
+
+    float sigma = 2.0;
+    Gaussian<float> smooth(sigma);
+    ...
+
+    // simultaneously enlarge and smooth source image
+    resamplingConvolveX(src, dest,
+                        smooth, ratio, offset);
+    \endcode
+
+    \deprecatedUsage{resamplingConvolveX}
+    \code
+    Rational<int> ratio(2), offset(0);
+
+    FImage src(w,h),
+           dest(rational_cast<int>(ratio*w), h);
+
+    float sigma = 2.0;
+    Gaussian<float> smooth(sigma);
+    ...
+
+    // simultaneously enlarge and smooth source image
+    resamplingConvolveX(srcImageRange(src), destImageRange(dest),
+                        smooth, ratio, offset);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    Kernel kernel;
+    int kernelRadius = kernel.radius();
+    double x = ...;  // must be <= radius()
+    double value = kernel(x);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void resamplingConvolveX)
+
+template <class SrcIter, class SrcAcc,
+          class DestIter, class DestAcc,
+          class Kernel>
+void
+resamplingConvolveX(SrcIter sul, SrcIter slr, SrcAcc src,
+                    DestIter dul, DestIter dlr, DestAcc dest,
+                    Kernel const & kernel,
+                    Rational<int> const & samplingRatio, Rational<int> const & offset)
+{
+    int wold = slr.x - sul.x;
+    int wnew = dlr.x - dul.x;
+
+    vigra_precondition(!samplingRatio.is_inf() && samplingRatio > 0,
+                "resamplingConvolveX(): sampling ratio must be > 0 and < infinity");
+    vigra_precondition(!offset.is_inf(),
+                "resamplingConvolveX(): offset must be < infinity");
+
+    int period = lcm(samplingRatio.numerator(), samplingRatio.denominator());
+    resampling_detail::MapTargetToSourceCoordinate mapCoordinate(samplingRatio, offset);
+
+    ArrayVector<Kernel1D<double> > kernels(period);
+
+    createResamplingKernels(kernel, mapCoordinate, kernels);
+
+    for(; sul.y < slr.y; ++sul.y, ++dul.y)
+    {
+        typename SrcIter::row_iterator sr = sul.rowIterator();
+        typename DestIter::row_iterator dr = dul.rowIterator();
+        resamplingConvolveLine(sr, sr+wold, src, dr, dr+wnew, dest,
+                               kernels, mapCoordinate);
+    }
+}
+
+template <class SrcIter, class SrcAcc,
+          class DestIter, class DestAcc,
+          class Kernel>
+inline void
+resamplingConvolveX(triple<SrcIter, SrcIter, SrcAcc> src,
+                    triple<DestIter, DestIter, DestAcc> dest,
+                    Kernel const & kernel,
+                    Rational<int> const & samplingRatio, Rational<int> const & offset)
+{
+    resamplingConvolveX(src.first, src.second, src.third,
+                        dest.first, dest.second, dest.third,
+                        kernel, samplingRatio, offset);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class Kernel>
+inline void
+resamplingConvolveX(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest,
+                    Kernel const & kernel,
+                    Rational<int> const & samplingRatio, Rational<int> const & offset)
+{
+    resamplingConvolveX(srcImageRange(src),
+                        destImageRange(dest),
+                        kernel, samplingRatio, offset);
+}
+
+/********************************************************/
+/*                                                      */
+/*                  resamplingConvolveY                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply a resampling filter in the y-direction.
+
+    This function implements a convolution operation in y-direction
+    (i.e. applies a 1D filter to every column) where the height of the source
+    and destination images differ. This is typically used to avoid aliasing if
+    the image is scaled down, or to interpolate smoothly if the image is scaled up.
+    The target coordinates are transformed into source coordinates by
+
+    \code
+    ysource = (ytarget - offset) / samplingRatio
+    \endcode
+
+    The <tt>samplingRatio</tt> and <tt>offset</tt> must be given as \ref vigra::Rational
+    in order to avoid rounding errors in this transformation. It is required that for all
+    pixels of the target image, <tt>ysource</tt> remains within the range of the source
+    image (i.e. <tt>0 <= ysource <= sourceHeight-1</tt>. Since <tt>ysource</tt> is
+    in general not an integer, the <tt>kernel</tt> must be a functor that can be accessed at
+    arbitrary (<tt>double</tt>) coordinates. It must also provide a member function <tt>radius()</tt>
+    which specifies the support (non-zero interval) of the kernel. VIGRA already
+    provides a number of suitable functors, e.g. \ref vigra::Gaussian, \ref vigra::BSpline
+    \ref vigra::CatmullRomSpline, and \ref vigra::CoscotFunction. The function
+    \ref resizeImageSplineInterpolation() is implemented by means of resamplingConvolveX() and
+    resamplingConvolveY().
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class Kernel>
+        void
+        resamplingConvolveY(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest,
+                            Kernel const & kernel,
+                            Rational<int> const & samplingRatio, Rational<int> const & offset);
+    }
+    \endcode
+
+    \deprecatedAPI{resamplingConvolveY}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIter, class SrcAcc,
+                  class DestIter, class DestAcc,
+                  class Kernel>
+        void
+        resamplingConvolveY(SrcIter sul, SrcIter slr, SrcAcc src,
+                            DestIter dul, DestIter dlr, DestAcc dest,
+                            Kernel const & kernel,
+                            Rational<int> const & samplingRatio, Rational<int> const & offset);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIter, class SrcAcc,
+                  class DestIter, class DestAcc,
+                  class Kernel>
+        void
+        resamplingConvolveY(triple<SrcIter, SrcIter, SrcAcc> src,
+                            triple<DestIter, DestIter, DestAcc> dest,
+                            Kernel const & kernel,
+                            Rational<int> const & samplingRatio, Rational<int> const & offset);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/resampling_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Rational<int> ratio(2), offset(0);
+
+    MultiArray<2, float> src(w,h),
+                         dest(w, rational_cast<int>(ratio*h));
+
+    float sigma = 2.0;
+    Gaussian<float> smooth(sigma);
+    ...
+
+    // simultaneously enlarge and smooth source image
+    resamplingConvolveY(src, dest,
+                        smooth, ratio, offset);
+    \endcode
+
+    \deprecatedUsage{resamplingConvolveY}
+    \code
+    Rational<int> ratio(2), offset(0);
+
+    FImage src(w,h),
+           dest(w, rational_cast<int>(ratio*h));
+
+    float sigma = 2.0;
+    Gaussian<float> smooth(sigma);
+    ...
+
+    // simultaneously enlarge and smooth source image
+    resamplingConvolveY(srcImageRange(src), destImageRange(dest),
+                        smooth, ratio, offset);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    Kernel kernel;
+    int kernelRadius = kernel.radius();
+    double y = ...;  // must be <= radius()
+    double value = kernel(y);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void resamplingConvolveY)
+
+template <class SrcIter, class SrcAcc,
+          class DestIter, class DestAcc,
+          class Kernel>
+void
+resamplingConvolveY(SrcIter sul, SrcIter slr, SrcAcc src,
+                    DestIter dul, DestIter dlr, DestAcc dest,
+                    Kernel const & kernel,
+                    Rational<int> const & samplingRatio, Rational<int> const & offset)
+{
+    int hold = slr.y - sul.y;
+    int hnew = dlr.y - dul.y;
+
+    vigra_precondition(!samplingRatio.is_inf() && samplingRatio > 0,
+                "resamplingConvolveY(): sampling ratio must be > 0 and < infinity");
+    vigra_precondition(!offset.is_inf(),
+                "resamplingConvolveY(): offset must be < infinity");
+
+    int period = lcm(samplingRatio.numerator(), samplingRatio.denominator());
+
+    resampling_detail::MapTargetToSourceCoordinate mapCoordinate(samplingRatio, offset);
+
+    ArrayVector<Kernel1D<double> > kernels(period);
+
+    createResamplingKernels(kernel, mapCoordinate, kernels);
+
+    for(; sul.x < slr.x; ++sul.x, ++dul.x)
+    {
+        typename SrcIter::column_iterator sc = sul.columnIterator();
+        typename DestIter::column_iterator dc = dul.columnIterator();
+        resamplingConvolveLine(sc, sc+hold, src, dc, dc+hnew, dest,
+                               kernels, mapCoordinate);
+    }
+}
+
+template <class SrcIter, class SrcAccessor,
+          class DestIter, class DestAccessor,
+          class Kernel>
+inline void
+resamplingConvolveY(triple<SrcIter, SrcIter, SrcAccessor> src,
+                    triple<DestIter, DestIter, DestAccessor> dest,
+                    Kernel const & kernel,
+                    Rational<int> const & samplingRatio, Rational<int> const & offset)
+{
+    resamplingConvolveY(src.first, src.second, src.third,
+                        dest.first, dest.second, dest.third,
+                        kernel, samplingRatio, offset);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class Kernel>
+inline void
+resamplingConvolveY(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest,
+                    Kernel const & kernel,
+                    Rational<int> const & samplingRatio, Rational<int> const & offset)
+{
+    resamplingConvolveY(srcImageRange(src),
+                        destImageRange(dest),
+                        kernel, samplingRatio, offset);
+}
+
+/********************************************************/
+/*                                                      */
+/*               resamplingConvolveImage                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply two separable resampling filters successively, the first in x-direction,
+           the second in y-direction.
+
+    This function is a shorthand for the concatenation of a call to
+    \ref resamplingConvolveX() and \ref resamplingConvolveY()
+    with the given kernels. See there for detailed documentation.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class KernelX, class KernelY>
+        void
+        resamplingConvolveImage(MultiArrayView<2, T1, S1> const & src,
+                                MultiArrayView<2, T2, S2> dest,
+                                KernelX const & kx,
+                                Rational<int> const & samplingRatioX, Rational<int> const & offsetX,
+                                KernelY const & ky,
+                                Rational<int> const & samplingRatioY, Rational<int> const & offsetY);
+    }
+    \endcode
+
+    \deprecatedAPI{resamplingConvolveImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class KernelX, class KernelY>
+        void resamplingConvolveImage(SrcIterator sul,SrcIterator slr, SrcAccessor src,
+                           DestIterator dul, DestIterator dlr, DestAccessor dest,
+                           KernelX const & kx,
+                           Rational<int> const & samplingRatioX, Rational<int> const & offsetX,
+                           KernelY const & ky,
+                           Rational<int> const & samplingRatioY, Rational<int> const & offsetY);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class KernelX, class KernelY>
+        void
+        resamplingConvolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                           triple<DestIterator, DestIterator, DestAccessor> dest,
+                           KernelX const & kx,
+                           Rational<int> const & samplingRatioX, Rational<int> const & offsetX,
+                           KernelY const & ky,
+                           Rational<int> const & samplingRatioY, Rational<int> const & offsetY);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/resampling_convolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    Rational<int> xratio(2), yratio(3), offset(0);
+
+    MultiArray<2, float> src(w,h),
+                         dest(rational_cast<int>(xratio*w), rational_cast<int>(yratio*h));
+
+    float sigma = 2.0;
+    Gaussian<float> smooth(sigma);
+    ...
+
+    // simultaneously enlarge and smooth source image
+    resamplingConvolveImage(src, dest,
+                            smooth, xratio, offset,
+                            smooth, yratio, offset);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void resamplingConvolveImage)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelX, class KernelY>
+void resamplingConvolveImage(SrcIterator sul,SrcIterator slr, SrcAccessor src,
+                   DestIterator dul, DestIterator dlr, DestAccessor dest,
+                   KernelX const & kx,
+                   Rational<int> const & samplingRatioX, Rational<int> const & offsetX,
+                   KernelY const & ky,
+                   Rational<int> const & samplingRatioY, Rational<int> const & offsetY)
+{
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        TmpType;
+
+    BasicImage<TmpType> tmp(dlr.x - dul.x, slr.y - sul.y);
+
+    resamplingConvolveX(srcIterRange(sul, slr, src),
+                        destImageRange(tmp),
+                        kx, samplingRatioX, offsetX);
+    resamplingConvolveY(srcImageRange(tmp),
+                        destIterRange(dul, dlr, dest),
+                        ky, samplingRatioY, offsetY);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelX, class KernelY>
+inline void
+resamplingConvolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        triple<DestIterator, DestIterator, DestAccessor> dest,
+                        KernelX const & kx,
+                        Rational<int> const & samplingRatioX, Rational<int> const & offsetX,
+                        KernelY const & ky,
+                        Rational<int> const & samplingRatioY, Rational<int> const & offsetY)
+{
+    resamplingConvolveImage(src.first, src.second, src.third,
+                            dest.first, dest.second, dest.third,
+                            kx, samplingRatioX, offsetX,
+                            ky, samplingRatioY, offsetY);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class KernelX, class KernelY>
+inline void
+resamplingConvolveImage(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, T2, S2> dest,
+                        KernelX const & kx,
+                        Rational<int> const & samplingRatioX, Rational<int> const & offsetX,
+                        KernelY const & ky,
+                        Rational<int> const & samplingRatioY, Rational<int> const & offsetY)
+{
+    resamplingConvolveImage(srcImageRange(src),
+                            destImageRange(dest),
+                            kx, samplingRatioX, offsetX,
+                            ky, samplingRatioY, offsetY);
+}
+
+/** \brief Two-fold down-sampling for image pyramid construction.
+
+    Sorry, no \ref detailedDocumentation() available yet.
+
+    <b> Declarations:</b>
+
+    <b>\#include</b> \<vigra/resampling_convolution.hxx\><br>
+    Namespace: vigra
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void pyramidReduceBurtFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                     DestIterator dul, DestIterator dlr, DestAccessor dest,
+                                     double centerValue = 0.4);
+    }
+    \endcode
+
+    \deprecatedAPI{pyramidReduceBurtFilter}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void pyramidReduceBurtFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                     DestIterator dul, DestIterator dlr, DestAccessor dest,
+                                     double centerValue = 0.4);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void pyramidReduceBurtFilter(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                     triple<DestIterator, DestIterator, DestAccessor> dest,
+                                     double centerValue = 0.4);
+    }
+    \endcode
+    \deprecatedEnd
+
+    use a \ref vigra::ImagePyramid :
+    \code
+    namespace vigra {
+        template <class Image, class Alloc>
+        void pyramidReduceBurtFilter(ImagePyramid<Image, Alloc> & pyramid, int fromLevel, int toLevel,
+                                     double centerValue = 0.4);
+    }
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void pyramidReduceBurtFilter)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void pyramidReduceBurtFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                             DestIterator dul, DestIterator dlr, DestAccessor dest,
+                             double centerValue = 0.4)
+{
+    vigra_precondition(0.25 <= centerValue && centerValue <= 0.5,
+             "pyramidReduceBurtFilter(): centerValue must be between 0.25 and 0.5.");
+             
+    int wold = slr.x - sul.x;
+    int wnew = dlr.x - dul.x;
+    int hold = slr.y - sul.y;
+    int hnew = dlr.y - dul.y;
+    
+    vigra_precondition(wnew == (wold + 1) / 2 && hnew == (hold + 1) / 2,
+       "pyramidReduceBurtFilter(): oldSize = ceil(newSize / 2) required.");
+    
+    vigra_precondition(wnew == (wold + 1) / 2 && hnew == (hold + 1) / 2,
+       "pyramidReduceBurtFilter(): oldSize = ceil(newSize / 2) required.");
+    
+    Rational<int> samplingRatio(1,2), offset(0);
+    resampling_detail::MapTargetToSourceCoordinate mapCoordinate(samplingRatio, offset);
+    
+    ArrayVector<Kernel1D<double> > kernels(1);
+    kernels[0].initExplicitly(-2, 2) = 0.25 - centerValue / 2.0, 0.25, centerValue, 0.25, 0.25 - centerValue / 2.0;
+   
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        TmpType;
+    typedef BasicImage<TmpType> TmpImage;
+    typedef typename TmpImage::traverser TmpIterator;
+    
+    BasicImage<TmpType> tmp(wnew, hold);
+    
+    TmpIterator tul = tmp.upperLeft();
+
+    for(; sul.y < slr.y; ++sul.y, ++tul.y)
+    {
+        typename SrcIterator::row_iterator sr = sul.rowIterator();
+        typename TmpIterator::row_iterator tr = tul.rowIterator();
+        // FIXME: replace with reduceLineBurtFilter()
+        resamplingConvolveLine(sr, sr+wold, src, tr, tr+wnew, tmp.accessor(),
+                               kernels, mapCoordinate);
+    }
+    
+    tul  = tmp.upperLeft();
+
+    for(; dul.x < dlr.x; ++dul.x, ++tul.x)
+    {
+        typename DestIterator::column_iterator dc = dul.columnIterator();
+        typename TmpIterator::column_iterator tc = tul.columnIterator();
+        resamplingConvolveLine(tc, tc+hold, tmp.accessor(), dc, dc+hnew, dest,
+                               kernels, mapCoordinate);
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline
+void pyramidReduceBurtFilter(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                             triple<DestIterator, DestIterator, DestAccessor> dest,
+                             double centerValue = 0.4)
+{
+    pyramidReduceBurtFilter(src.first, src.second, src.third, 
+                            dest.first, dest.second, dest.third, centerValue);
+}
+
+template <class Image, class Alloc>
+inline
+void pyramidReduceBurtFilter(ImagePyramid<Image, Alloc> & pyramid, int fromLevel, int toLevel,
+                             double centerValue = 0.4)
+{
+    vigra_precondition(fromLevel  < toLevel,
+       "pyramidReduceBurtFilter(): fromLevel must be smaller than toLevel.");
+    vigra_precondition(pyramid.lowestLevel() <= fromLevel && toLevel <= pyramid.highestLevel(),
+       "pyramidReduceBurtFilter(): fromLevel and toLevel must be between the lowest and highest pyramid levels (inclusive).");
+
+    for(int i=fromLevel+1; i <= toLevel; ++i)
+        pyramidReduceBurtFilter(srcImageRange(pyramid[i-1]), destImageRange(pyramid[i]), centerValue);
+}
+
+/** \brief Two-fold up-sampling for image pyramid reconstruction.
+
+    Sorry, no \ref detailedDocumentation() available yet.
+
+    <b> Declarations:</b>
+
+    <b>\#include</b> \<vigra/resampling_convolution.hxx\><br>
+    Namespace: vigra
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void pyramidExpandBurtFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                     DestIterator dul, DestIterator dlr, DestAccessor dest,
+                                     double centerValue = 0.4);
+    }
+    \endcode
+
+    \deprecatedAPI{pyramidExpandBurtFilter}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void pyramidExpandBurtFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                     DestIterator dul, DestIterator dlr, DestAccessor dest,
+                                     double centerValue = 0.4);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void pyramidExpandBurtFilter(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                     triple<DestIterator, DestIterator, DestAccessor> dest,
+                                     double centerValue = 0.4);
+    }
+    \endcode
+    \deprecatedEnd
+
+    use a \ref vigra::ImagePyramid :
+    \code
+    namespace vigra {
+        template <class Image, class Alloc>
+        void pyramidExpandBurtFilter(ImagePyramid<Image, Alloc> & pyramid, int fromLevel, int toLevel,
+                                     double centerValue = 0.4);
+    }
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void pyramidExpandBurtFilter)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void pyramidExpandBurtFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                             DestIterator dul, DestIterator dlr, DestAccessor dest,
+                             double centerValue = 0.4)
+{
+    vigra_precondition(0.25 <= centerValue && centerValue <= 0.5,
+             "pyramidExpandBurtFilter(): centerValue must be between 0.25 and 0.5.");
+             
+    int wold = slr.x - sul.x;
+    int wnew = dlr.x - dul.x;
+    int hold = slr.y - sul.y;
+    int hnew = dlr.y - dul.y;
+    
+    vigra_precondition(wold == (wnew + 1) / 2 && hold == (hnew + 1) / 2,
+       "pyramidExpandBurtFilter(): oldSize = ceil(newSize / 2) required.");
+    
+    vigra_precondition(wold == (wnew + 1) / 2 && hold == (hnew + 1) / 2,
+       "pyramidExpandBurtFilter(): oldSize = ceil(newSize / 2) required.");
+    
+    Rational<int> samplingRatio(2), offset(0);
+    resampling_detail::MapTargetToSourceCoordinate mapCoordinate(samplingRatio, offset);
+    
+    ArrayVector<Kernel1D<double> > kernels(2);
+    kernels[0].initExplicitly(-1, 1) = 0.5 - centerValue, 2.0*centerValue, 0.5 - centerValue;
+    kernels[1].initExplicitly(-1, 0) = 0.5, 0.5;
+   
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        TmpType;
+    typedef BasicImage<TmpType> TmpImage;
+    typedef typename TmpImage::traverser TmpIterator;
+    
+    BasicImage<TmpType> tmp(wnew, hold);
+    
+    TmpIterator tul = tmp.upperLeft();
+
+    for(; sul.y < slr.y; ++sul.y, ++tul.y)
+    {
+        typename SrcIterator::row_iterator sr = sul.rowIterator();
+        typename TmpIterator::row_iterator tr = tul.rowIterator();
+        // FIXME: replace with expandLineBurtFilter()
+        resamplingConvolveLine(sr, sr+wold, src, tr, tr+wnew, tmp.accessor(),
+                               kernels, mapCoordinate);
+    }
+    
+    tul  = tmp.upperLeft();
+
+    for(; dul.x < dlr.x; ++dul.x, ++tul.x)
+    {
+        typename DestIterator::column_iterator dc = dul.columnIterator();
+        typename TmpIterator::column_iterator tc = tul.columnIterator();
+        resamplingConvolveLine(tc, tc+hold, tmp.accessor(), dc, dc+hnew, dest,
+                               kernels, mapCoordinate);
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline
+void pyramidExpandBurtFilter(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                             triple<DestIterator, DestIterator, DestAccessor> dest,
+                             double centerValue = 0.4)
+{
+    pyramidExpandBurtFilter(src.first, src.second, src.third, 
+                            dest.first, dest.second, dest.third, centerValue);
+}
+
+
+template <class Image, class Alloc>
+inline
+void pyramidExpandBurtFilter(ImagePyramid<Image, Alloc> & pyramid, int fromLevel, int toLevel,
+                             double centerValue = 0.4)
+{
+    vigra_precondition(fromLevel  > toLevel,
+       "pyramidExpandBurtFilter(): fromLevel must be larger than toLevel.");
+    vigra_precondition(pyramid.lowestLevel() <= toLevel && fromLevel <= pyramid.highestLevel(),
+       "pyramidExpandBurtFilter(): fromLevel and toLevel must be between the lowest and highest pyramid levels (inclusive).");
+
+    for(int i=fromLevel-1; i >= toLevel; --i)
+        pyramidExpandBurtFilter(srcImageRange(pyramid[i+1]), destImageRange(pyramid[i]), centerValue);
+}
+
+/** \brief Create a Laplacian pyramid.
+
+    Sorry, no \ref detailedDocumentation() available yet.
+
+    <b>\#include</b> \<vigra/resampling_convolution.hxx\><br>
+    Namespace: vigra
+*/
+template <class Image, class Alloc>
+inline void
+pyramidReduceBurtLaplacian(ImagePyramid<Image, Alloc> & pyramid, int fromLevel, int toLevel,
+                           double centerValue = 0.4)
+{
+    using namespace functor;
+    
+    pyramidReduceBurtFilter(pyramid, fromLevel, toLevel, centerValue);
+    for(int i=fromLevel; i < toLevel; ++i)
+    {
+        typename ImagePyramid<Image, Alloc>::value_type tmpImage(pyramid[i].size());
+        pyramidExpandBurtFilter(srcImageRange(pyramid[i+1]), destImageRange(tmpImage), centerValue);
+        combineTwoImages(srcImageRange(tmpImage), srcImage(pyramid[i]), destImage(pyramid[i]),
+                       Arg1() - Arg2()); 
+    }
+}
+
+/** \brief Reconstruct a Laplacian pyramid.
+
+    Sorry, no \ref detailedDocumentation() available yet.
+
+    <b>\#include</b> \<vigra/resampling_convolution.hxx\><br>
+    Namespace: vigra
+*/
+template <class Image, class Alloc>
+inline void
+pyramidExpandBurtLaplacian(ImagePyramid<Image, Alloc> & pyramid, int fromLevel, int toLevel,
+                           double centerValue = 0.4)
+{
+    using namespace functor;
+    
+    vigra_precondition(fromLevel  > toLevel,
+       "pyramidExpandBurtLaplacian(): fromLevel must be larger than toLevel.");
+    vigra_precondition(pyramid.lowestLevel() <= toLevel && fromLevel <= pyramid.highestLevel(),
+       "pyramidExpandBurtLaplacian(): fromLevel and toLevel must be between the lowest and highest pyramid levels (inclusive).");
+
+    for(int i=fromLevel-1; i >= toLevel; --i)
+    {
+        typename ImagePyramid<Image, Alloc>::value_type tmpImage(pyramid[i].size());
+        pyramidExpandBurtFilter(srcImageRange(pyramid[i+1]), destImageRange(tmpImage), centerValue);
+        combineTwoImages(srcImageRange(tmpImage), srcImage(pyramid[i]), destImage(pyramid[i]),
+                       Arg1() - Arg2()); 
+    }
+}
+
+//@}
+
+} // namespace vigra
+
+
+#endif /* VIGRA_RESAMPLING_CONVOLUTION_HXX */
diff --git a/include/vigra/resizeimage.hxx b/include/vigra/resizeimage.hxx
new file mode 100644
index 0000000..cdd7255
--- /dev/null
+++ b/include/vigra/resizeimage.hxx
@@ -0,0 +1,1115 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_RESIZEIMAGE_HXX
+#define VIGRA_RESIZEIMAGE_HXX
+
+#include <vector>
+#include "utilities.hxx"
+#include "numerictraits.hxx"
+#include "stdimage.hxx"
+#include "recursiveconvolution.hxx"
+#include "separableconvolution.hxx"
+#include "resampling_convolution.hxx"
+#include "splines.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/*****************************************************************/
+/*                                                               */
+/*                         CoscotFunction                        */
+/*                                                               */
+/*****************************************************************/
+
+/** The Coscot interpolation function.
+
+    Implements the Coscot interpolation function proposed by Maria Magnusson Seger
+    (maria at isy.liu.se) in the context of tomographic reconstruction. It provides a fast
+    transition between the pass- and stop-bands and minimal ripple outside the transition
+    region. Both properties are important for this application and can be tuned by the parameters
+    <i>m</i> and <i>h</i> (with defaults 3 and 0.5). The function is defined by
+
+    \f[ f_{m,h}(x) = \left\{ \begin{array}{ll}
+                                   \frac{1}{2m}\sin(\pi x)\cot(\pi x / (2 m))(h + (1-h)\cos(\pi x/m)) & |x| \leq m \\
+                                  0 & \mbox{otherwise}
+                        \end{array}\right.
+    \f]
+
+    It can be used as a functor, and as a kernel for
+    \ref resamplingConvolveImage() to create a differentiable interpolant
+    of an image.
+
+    <b>\#include</b> \<vigra/resizeimage.hxx\><br>
+    Namespace: vigra
+
+    \ingroup MathFunctions
+*/
+template <class T>
+class CoscotFunction
+{
+  public:
+
+        /** the kernel's value type
+        */
+    typedef T            value_type;
+        /** the unary functor's argument type
+        */
+    typedef T            argument_type;
+        /** the splines polynomial order
+        */
+    typedef T            result_type;
+
+    CoscotFunction(unsigned int m = 3, double h = 0.5)
+    : m_(m),
+      h_(h)
+    {}
+
+        /** function (functor) call
+        */
+    result_type operator()(argument_type x) const
+    {
+        return x == 0.0 ?
+                    1.0
+                  : abs(x) < m_ ?
+                        VIGRA_CSTD::sin(M_PI*x) / VIGRA_CSTD::tan(M_PI * x / 2.0 / m_) *
+                             (h_ + (1.0 - h_) * VIGRA_CSTD::cos(M_PI * x / m_)) / 2.0 / m_
+                      : 0.0;
+    }
+
+        /** index operator -- same as operator()
+        */
+    value_type operator[](value_type x) const
+        { return operator()(x); }
+
+        /** Radius of the function's support.
+            Needed for  \ref resamplingConvolveImage(), equals m.
+        */
+    double radius() const
+        { return m_; }
+
+        /** Derivative order of the function: always 0.
+        */
+    unsigned int derivativeOrder() const
+        { return 0; }
+
+        /** Prefilter coefficients for compatibility with \ref vigra::BSpline.
+            (array has zero length, since prefiltering is not necessary).
+        */
+    ArrayVector<double> const & prefilterCoefficients() const
+    {
+        return prefilterCoefficients_;
+    }
+    
+  protected:
+    static ArrayVector<double> prefilterCoefficients_;
+    unsigned int m_;
+    double h_;
+};
+
+template <class T>
+ArrayVector<double> CoscotFunction<T>::prefilterCoefficients_;
+
+
+
+/** \addtogroup GeometricTransformations Geometric Transformations
+    Zoom up and down by repeating pixels, or using various interpolation schemes.
+
+    See also: \ref resamplingConvolveImage(), \ref resampleImage(), \ref resizeMultiArraySplineInterpolation()
+
+    <b>\#include</b> \<vigra/stdimagefunctions.hxx\><br>
+    <b>or</b><br>
+    <b>\#include</b> \<vigra/resizeimage.hxx\><br>
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*               resizeLineNoInterpolation              */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+resizeLineNoInterpolation(SrcIterator i1, SrcIterator iend, SrcAccessor as,
+                           DestIterator id, DestIterator idend, DestAccessor ad)
+{
+    int wold = iend - i1;
+    int wnew = idend - id;
+
+    if(wnew == 1)
+    {
+        ad.set(as(i1), id);
+        return;
+    }
+    
+    double dx = (double)(wold - 1) / (wnew - 1);
+    double x = 0.5;
+    for(; id != idend; ++id, x += dx)
+    {
+        int ix = (int)x;
+        ad.set(as(i1, ix), id);
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*              resizeImageNoInterpolation              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Resize image by repeating the nearest pixel values.
+
+    This algorithm is very fast and does not require any arithmetic on
+    the pixel types.
+
+    The range of both the input and output images (resp. regions) must
+    be given. Both images must have a size of at least 2x2 pixels. The
+    scaling factors are then calculated accordingly. Destination
+    pixels are directly copied from the appropriate source pixels.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        resizeImageNoInterpolation(MultiArrayView<2, T1, S1> const & src,
+                                   MultiArrayView<2, T2, S2> dest);
+    }
+    \endcode
+
+    \deprecatedAPI{resizeImageNoInterpolation}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void
+        resizeImageNoInterpolation(
+              SrcImageIterator is, SrcImageIterator iend, SrcAccessor sa,
+              DestImageIterator id, DestImageIterator idend, DestAccessor da)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void
+        resizeImageNoInterpolation(
+              triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+              triple<DestImageIterator, DestImageIterator, DestAccessor> dest)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/resizeimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w, h);
+    MultiArray<2, float>         dest(w_new, h_new);
+    
+    resizeImageNoInterpolation(src, dest);
+    \endcode
+
+    \deprecatedUsage{resizeImageNoInterpolation}
+    \code
+    vigra::resizeImageNoInterpolation(
+               src.upperLeft(), src.lowerRight(), src.accessor(),
+               dest.upperLeft(), dest.lowerRight(), dest.accessor());
+
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft, src_lowerright;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
+
+    \endcode
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    Source and destination must have at least 2 pixels along each axis.
+*/
+doxygen_overloaded_function(template <...> void resizeImageNoInterpolation)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+resizeImageNoInterpolation(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                      DestIterator id, DestIterator idend, DestAccessor da)
+{
+    int w = iend.x - is.x;
+    int h = iend.y - is.y;
+
+    int wnew = idend.x - id.x;
+    int hnew = idend.y - id.y;
+
+    vigra_precondition((w > 1) && (h > 1),
+                 "resizeImageNoInterpolation(): "
+                 "Source image too small.\n");
+    vigra_precondition((wnew > 1) && (hnew > 1),
+                 "resizeImageNoInterpolation(): "
+                 "Destination image too small.\n");
+
+    typedef BasicImage<typename SrcAccessor::value_type> TmpImage;
+    typedef typename TmpImage::traverser TmpImageIterator;
+
+    TmpImage tmp(w, hnew);
+
+    TmpImageIterator yt = tmp.upperLeft();
+
+    for(int x=0; x<w; ++x, ++is.x, ++yt.x)
+    {
+        typename SrcIterator::column_iterator c1 = is.columnIterator();
+        typename TmpImageIterator::column_iterator ct = yt.columnIterator();
+
+        resizeLineNoInterpolation(c1, c1 + h, sa, ct, ct + hnew, tmp.accessor());
+    }
+
+    yt = tmp.upperLeft();
+
+    for(int y=0; y < hnew; ++y, ++yt.y, ++id.y)
+    {
+        typename DestIterator::row_iterator rd = id.rowIterator();
+        typename TmpImageIterator::row_iterator rt = yt.rowIterator();
+
+        resizeLineNoInterpolation(rt, rt + w, tmp.accessor(), rd, rd + wnew, da);
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+resizeImageNoInterpolation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                           triple<DestIterator, DestIterator, DestAccessor> dest)
+{
+    resizeImageNoInterpolation(src.first, src.second, src.third,
+                               dest.first, dest.second, dest.third);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+resizeImageNoInterpolation(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, T2, S2> dest)
+{
+    resizeImageNoInterpolation(srcImageRange(src),
+                               destImageRange(dest));
+}
+
+/********************************************************/
+/*                                                      */
+/*             resizeLineLinearInterpolation            */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+resizeLineLinearInterpolation(SrcIterator i1, SrcIterator iend, SrcAccessor as,
+                           DestIterator id, DestIterator idend, DestAccessor ad)
+{
+    int wold = iend - i1;
+    int wnew = idend - id;
+
+    if((wold <= 1) || (wnew <= 1)) return; // oder error ?
+
+    typedef
+        NumericTraits<typename DestAccessor::value_type> DestTraits;
+    typedef typename DestTraits::RealPromote RealPromote;
+
+    ad.set(DestTraits::fromRealPromote(as(i1)), id);
+    ++id;
+
+    --iend, --idend;
+    ad.set(DestTraits::fromRealPromote(as(iend)), idend);
+
+    double dx = (double)(wold - 1) / (wnew - 1);
+    double x = dx;
+
+    for(; id != idend; ++id, x += dx)
+    {
+        if(x >= 1.0)
+        {
+            int xx = (int)x;
+            i1 += xx;
+            x -= (double)xx;
+        }
+        double x1 = 1.0 - x;
+
+        ad.set(DestTraits::fromRealPromote(RealPromote(x1 * as(i1) + x * as(i1, 1))), id);
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*           resizeImageLinearInterpolation             */
+/*                                                      */
+/********************************************************/
+
+/** \brief Resize image using linear interpolation.
+
+    The function uses the standard separable bilinear interpolation algorithm to
+    obtain a good compromise between quality and speed.
+
+    The range must of both the input and output images (resp. regions)
+    must be given. Both images must have a size of at
+    least 2x2. The scaling factors are then calculated
+    accordingly. If the source image is larger than the destination, it
+    is smoothed (band limited) using a recursive
+    exponential filter. The source value_type (SrcAccessor::value_type) must
+    be a linear space, i.e. it must support addition, multiplication
+    with a scalar real number and \ref NumericTraits "NumericTraits".
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        resizeImageLinearInterpolation(MultiArrayView<2, T1, S1> const & src,
+                                       MultiArrayView<2, T2, S2> dest);
+    }
+    \endcode
+
+    \deprecatedAPI{resizeImageLinearInterpolation}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void
+        resizeImageLinearInterpolation(
+              SrcImageIterator is, SrcImageIterator iend, SrcAccessor sa,
+              DestImageIterator id, DestImageIterator idend, DestAccessor da)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor>
+        void
+        resizeImageLinearInterpolation(
+              triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+              triple<DestImageIterator, DestImageIterator, DestAccessor> dest)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/resizeimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w, h);
+    MultiArray<2, float>         dest(w_new, h_new);
+    
+    resizeImageLinearInterpolation(src, dest);
+    \endcode
+
+    \deprecatedUsage{resizeImageLinearInterpolation}
+    \code
+    vigra::resizeImageLinearInterpolation(
+               src.upperLeft(), src.lowerRight(), src.accessor(),
+               dest.upperLeft(), dest.lowerRight(), dest.accessor());
+
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft, src_lowerright;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    NumericTraits<SrcAccessor::value_type>::RealPromote
+                             u = src_accessor(src_upperleft),
+                 v = src_accessor(src_upperleft, 1);
+    double d;
+
+    u = d * v;
+    u = u + v;
+
+    dest_accessor.set(
+        NumericTraits<DestAccessor::value_type>::fromRealPromote(u),
+    dest_upperleft);
+
+    \endcode
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    Source and destination must have at least 2 pixels along each axis.
+*/
+doxygen_overloaded_function(template <...> void resizeImageLinearInterpolation)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+resizeImageLinearInterpolation(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                      DestIterator id, DestIterator idend, DestAccessor da)
+{
+    int w = iend.x - is.x;
+    int h = iend.y - is.y;
+
+    int wnew = idend.x - id.x;
+    int hnew = idend.y - id.y;
+
+    vigra_precondition((w > 1) && (h > 1),
+                 "resizeImageLinearInterpolation(): "
+                 "Source image too small.\n");
+    vigra_precondition((wnew > 1) && (hnew > 1),
+                 "resizeImageLinearInterpolation(): "
+                 "Destination image too small.\n");
+
+    double const scale = 2.0;
+
+    typedef typename SrcAccessor::value_type SRCVT;
+    typedef typename NumericTraits<SRCVT>::RealPromote TMPTYPE;
+    typedef BasicImage<TMPTYPE> TmpImage;
+    typedef typename TmpImage::traverser TmpImageIterator;
+
+    BasicImage<TMPTYPE> tmp(w, hnew);
+    BasicImage<TMPTYPE> line((h > w) ? h : w, 1);
+
+    int x,y;
+
+    typename BasicImage<TMPTYPE>::Iterator yt = tmp.upperLeft();
+    typename TmpImageIterator::row_iterator lt = line.upperLeft().rowIterator();
+
+    for(x=0; x<w; ++x, ++is.x, ++yt.x)
+    {
+        typename SrcIterator::column_iterator c1 = is.columnIterator();
+        typename TmpImageIterator::column_iterator ct = yt.columnIterator();
+
+        if(hnew < h)
+        {
+            recursiveSmoothLine(c1, c1 + h, sa,
+                 lt, line.accessor(), (double)h/hnew/scale);
+
+            resizeLineLinearInterpolation(lt, lt + h, line.accessor(),
+                                          ct, ct + hnew, tmp.accessor());
+        }
+        else
+        {
+            resizeLineLinearInterpolation(c1, c1 + h, sa,
+                                          ct, ct + hnew, tmp.accessor());
+        }
+    }
+
+    yt = tmp.upperLeft();
+
+    for(y=0; y < hnew; ++y, ++yt.y, ++id.y)
+    {
+        typename DestIterator::row_iterator rd = id.rowIterator();
+        typename TmpImageIterator::row_iterator rt = yt.rowIterator();
+
+        if(wnew < w)
+        {
+            recursiveSmoothLine(rt, rt + w, tmp.accessor(),
+                              lt, line.accessor(), (double)w/wnew/scale);
+
+            resizeLineLinearInterpolation(lt, lt + w, line.accessor(),
+                                          rd, rd + wnew, da);
+        }
+        else
+        {
+            resizeLineLinearInterpolation(rt, rt + w, tmp.accessor(),
+                                          rd, rd + wnew, da);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+resizeImageLinearInterpolation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                               triple<DestIterator, DestIterator, DestAccessor> dest)
+{
+    resizeImageLinearInterpolation(src.first, src.second, src.third,
+                                   dest.first, dest.second, dest.third);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+resizeImageLinearInterpolation(MultiArrayView<2, T1, S1> const & src,
+                               MultiArrayView<2, T2, S2> dest)
+{
+    resizeImageLinearInterpolation(srcImageRange(src),
+                                   destImageRange(dest));
+}
+
+/***************************************************************/
+/*                                                             */
+/*                resizeImageSplineInterpolation               */
+/*                                                             */
+/***************************************************************/
+
+/** \brief Resize image using B-spline interpolation.
+
+    The function implements separable spline interpolation algorithm described in
+
+    M. Unser, A. Aldroubi, M. Eden, <i>"B-Spline Signal Processing"</i>
+    IEEE Transactions on Signal Processing, vol. 41, no. 2, pp. 821-833 (part I),
+    pp. 834-848 (part II), 1993.
+
+    to obtain optimal interpolation quality and speed. You may pass the function
+    a spline of arbitrary order (e.g. <TT>BSpline<ORDER, double></tt> or
+    <TT>CatmullRomSpline<double></tt>). The default is a third order spline
+    which gives a twice continuously differentiable interpolant.
+    The implementation ensures that image values are interpolated rather
+    than smoothed by first calling a recursive (sharpening) prefilter as
+    described in the above paper. Then the actual interpolation is done
+    using \ref resamplingConvolveLine().
+
+    The range of both the input and output images (resp. regions)
+    must be given. The input image must have a size of at
+    least 4x4, the destination of at least 2x2. The scaling factors are then calculated
+    accordingly. If the source image is larger than the destination, it
+    is smoothed (band limited) using a recursive
+    exponential filter. The source value_type (SrcAccessor::value_type) must
+    be a linear algebra, i.e. it must support addition, subtraction,
+    and multiplication (+, -, *), multiplication with a scalar
+    real number and \ref NumericTraits "NumericTraits".
+    The function uses accessors.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class SPLINE>
+        void
+        resizeImageSplineInterpolation(MultiArrayView<2, T1, S1> const & src,
+                                       MultiArrayView<2, T2, S2> dest,
+                                       SPLINE const & spline = BSpline<3, double>());
+    }
+    \endcode
+
+    \deprecatedAPI{resizeImageSplineInterpolation}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor,
+                  class SPLINE>
+        void
+        resizeImageSplineInterpolation(
+              SrcImageIterator is, SrcImageIterator iend, SrcAccessor sa,
+              DestImageIterator id, DestImageIterator idend, DestAccessor da,
+              SPLINE spline = BSpline<3, double>())
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor,
+                  class SPLINE>
+        void
+        resizeImageSplineInterpolation(
+              triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+              triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
+              SPLINE spline = BSpline<3, double>())
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/resizeimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char> src(w, h);
+    MultiArray<2, float>         dest(w_new, h_new);
+    
+    // use default cubic spline interpolator
+    resizeImageSplineInterpolation(src, dest);
+    
+    // use 5th-order spline interpolator
+    resizeImageSplineInterpolation(src, dest, BSpline<5, double>());
+    \endcode
+
+    \deprecatedUsage{resizeImageSplineInterpolation}
+    \code
+    vigra::resizeImageSplineInterpolation(
+               src.upperLeft(), src.lowerRight(), src.accessor(),
+               dest.upperLeft(), dest.lowerRight(), dest.accessor());
+
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft, src_lowerright;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    NumericTraits<SrcAccessor::value_type>::RealPromote
+                             u = src_accessor(src_upperleft),
+                 v = src_accessor(src_upperleft, 1);
+    double d;
+
+    u = d * v;
+    u = u + v;
+    u = u - v;
+    u = u * v;
+    u += v;
+    u -= v;
+
+    dest_accessor.set(
+        NumericTraits<DestAccessor::value_type>::fromRealPromote(u),
+    dest_upperleft);
+
+    \endcode
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    Source and destination must have at least 2 pixels along each axis.
+*/
+doxygen_overloaded_function(template <...> void resizeImageSplineInterpolation)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class SPLINE>
+void
+resizeImageSplineInterpolation(
+    SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
+    DestIterator dest_iter, DestIterator dest_iter_end, DestAccessor dest_acc,
+    SPLINE const & spline)
+{
+
+    int width_old = src_iter_end.x - src_iter.x;
+    int height_old = src_iter_end.y - src_iter.y;
+
+    int width_new = dest_iter_end.x - dest_iter.x;
+    int height_new = dest_iter_end.y - dest_iter.y;
+
+    vigra_precondition((width_old > 1) && (height_old > 1),
+                 "resizeImageSplineInterpolation(): "
+                 "Source image too small.\n");
+
+    vigra_precondition((width_new > 1) && (height_new > 1),
+                 "resizeImageSplineInterpolation(): "
+                 "Destination image too small.\n");
+
+    Rational<int> xratio(width_new - 1, width_old - 1);
+    Rational<int> yratio(height_new - 1, height_old - 1);
+    Rational<int> offset(0);
+    resampling_detail::MapTargetToSourceCoordinate xmapCoordinate(xratio, offset);
+    resampling_detail::MapTargetToSourceCoordinate ymapCoordinate(yratio, offset);
+    int xperiod = lcm(xratio.numerator(), xratio.denominator());
+    int yperiod = lcm(yratio.numerator(), yratio.denominator());
+
+    double const scale = 2.0;
+
+    typedef typename SrcAccessor::value_type SRCVT;
+    typedef typename NumericTraits<SRCVT>::RealPromote TMPTYPE;
+    typedef BasicImage<TMPTYPE> TmpImage;
+    typedef typename TmpImage::traverser TmpImageIterator;
+
+    BasicImage<TMPTYPE> tmp(width_old, height_new);
+
+    BasicImage<TMPTYPE> line((height_old > width_old) ? height_old : width_old, 1);
+    typename BasicImage<TMPTYPE>::Accessor tmp_acc = tmp.accessor();
+    ArrayVector<double> const & prefilterCoeffs = spline.prefilterCoefficients();
+
+    int x,y;
+
+    ArrayVector<Kernel1D<double> > kernels(yperiod);
+    createResamplingKernels(spline, ymapCoordinate, kernels);
+
+    typename BasicImage<TMPTYPE>::Iterator y_tmp = tmp.upperLeft();
+    typename TmpImageIterator::row_iterator line_tmp = line.upperLeft().rowIterator();
+
+    for(x=0; x<width_old; ++x, ++src_iter.x, ++y_tmp.x)
+    {
+
+        typename SrcIterator::column_iterator c_src = src_iter.columnIterator();
+        typename TmpImageIterator::column_iterator c_tmp = y_tmp.columnIterator();
+
+        if(prefilterCoeffs.size() == 0)
+        {
+            if(height_new >= height_old)
+            {
+                resamplingConvolveLine(c_src, c_src + height_old, src_acc,
+                                       c_tmp, c_tmp + height_new, tmp_acc,
+                                       kernels, ymapCoordinate);
+            }
+            else
+            {
+                recursiveSmoothLine(c_src, c_src + height_old, src_acc,
+                     line_tmp, line.accessor(), (double)height_old/height_new/scale);
+                resamplingConvolveLine(line_tmp, line_tmp + height_old, line.accessor(),
+                                       c_tmp, c_tmp + height_new, tmp_acc,
+                                       kernels, ymapCoordinate);
+            }
+        }
+        else
+        {
+            recursiveFilterLine(c_src, c_src + height_old, src_acc,
+                                line_tmp, line.accessor(),
+                                prefilterCoeffs[0], BORDER_TREATMENT_REFLECT);
+            for(unsigned int b = 1; b < prefilterCoeffs.size(); ++b)
+            {
+                recursiveFilterLine(line_tmp, line_tmp + height_old, line.accessor(),
+                                    line_tmp, line.accessor(),
+                                    prefilterCoeffs[b], BORDER_TREATMENT_REFLECT);
+            }
+            if(height_new < height_old)
+            {
+                recursiveSmoothLine(line_tmp, line_tmp + height_old, line.accessor(),
+                     line_tmp, line.accessor(), (double)height_old/height_new/scale);
+            }
+            resamplingConvolveLine(line_tmp, line_tmp + height_old, line.accessor(),
+                                   c_tmp, c_tmp + height_new, tmp_acc,
+                                   kernels, ymapCoordinate);
+        }
+    }
+
+    y_tmp = tmp.upperLeft();
+
+    kernels.resize(xperiod);
+    createResamplingKernels(spline, xmapCoordinate, kernels);
+
+    for(y=0; y < height_new; ++y, ++y_tmp.y, ++dest_iter.y)
+    {
+        typename DestIterator::row_iterator r_dest = dest_iter.rowIterator();
+        typename TmpImageIterator::row_iterator r_tmp = y_tmp.rowIterator();
+
+        if(prefilterCoeffs.size() == 0)
+        {
+            if(width_new >= width_old)
+            {
+                resamplingConvolveLine(r_tmp, r_tmp + width_old, tmp.accessor(),
+                                       r_dest, r_dest + width_new, dest_acc,
+                                       kernels, xmapCoordinate);
+            }
+            else
+            {
+                recursiveSmoothLine(r_tmp, r_tmp + width_old, tmp.accessor(),
+                                  line_tmp, line.accessor(), (double)width_old/width_new/scale);
+                resamplingConvolveLine(line_tmp, line_tmp + width_old, line.accessor(),
+                                       r_dest, r_dest + width_new, dest_acc,
+                                       kernels, xmapCoordinate);
+            }
+        }
+        else
+        {
+            recursiveFilterLine(r_tmp, r_tmp + width_old, tmp.accessor(),
+                                line_tmp, line.accessor(),
+                                prefilterCoeffs[0], BORDER_TREATMENT_REFLECT);
+            for(unsigned int b = 1; b < prefilterCoeffs.size(); ++b)
+            {
+                recursiveFilterLine(line_tmp, line_tmp + width_old, line.accessor(),
+                                    line_tmp, line.accessor(),
+                                    prefilterCoeffs[b], BORDER_TREATMENT_REFLECT);
+            }
+            if(width_new < width_old)
+            {
+                recursiveSmoothLine(line_tmp, line_tmp + width_old, line.accessor(),
+                                    line_tmp, line.accessor(), (double)width_old/width_new/scale);
+            }
+            resamplingConvolveLine(line_tmp, line_tmp + width_old, line.accessor(),
+                                   r_dest, r_dest + width_new, dest_acc,
+                                   kernels, xmapCoordinate);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+resizeImageSplineInterpolation(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                      DestIterator id, DestIterator idend, DestAccessor da)
+{
+    resizeImageSplineInterpolation(is, iend, sa, id, idend, da, BSpline<3, double>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class SPLINE>
+inline void
+resizeImageSplineInterpolation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                               triple<DestIterator, DestIterator, DestAccessor> dest,
+                               SPLINE const & spline)
+{
+    resizeImageSplineInterpolation(src.first, src.second, src.third,
+                                   dest.first, dest.second, dest.third, spline);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+resizeImageSplineInterpolation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                               triple<DestIterator, DestIterator, DestAccessor> dest)
+{
+    resizeImageSplineInterpolation(src.first, src.second, src.third,
+                                   dest.first, dest.second, dest.third);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class SPLINE>
+inline void
+resizeImageSplineInterpolation(MultiArrayView<2, T1, S1> const & src,
+                               MultiArrayView<2, T2, S2> dest,
+                               SPLINE const & spline)
+{
+    resizeImageSplineInterpolation(srcImageRange(src),
+                                   destImageRange(dest), spline);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+resizeImageSplineInterpolation(MultiArrayView<2, T1, S1> const & src,
+                               MultiArrayView<2, T2, S2> dest)
+{
+    resizeImageSplineInterpolation(srcImageRange(src),
+                                   destImageRange(dest));
+}
+
+/*****************************************************************/
+/*                                                               */
+/*              resizeImageCatmullRomInterpolation               */
+/*                                                               */
+/*****************************************************************/
+
+/** \brief Resize image using the Catmull/Rom interpolation function.
+
+    The function calls like \ref resizeImageSplineInterpolation() with
+    \ref vigra::CatmullRomSpline as an interpolation kernel.
+    The interpolated function has one continuous derivative.
+    (See \ref resizeImageSplineInterpolation() for more documentation)
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        resizeImageCatmullRomInterpolation(MultiArrayView<2, T1, S1> const & src,
+                                           MultiArrayView<2, T2, S2> dest);
+    }
+    \endcode
+
+    \deprecatedAPI{resizeImageCatmullRomInterpolation}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        resizeImageCatmullRomInterpolation(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
+                              DestIterator dest_iter, DestIterator dest_iter_end, DestAccessor dest_acc);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        resizeImageCatmullRomInterpolation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                              triple<DestIterator, DestIterator, DestAccessor> dest);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b>\#include</b> \<vigra/resizeimage.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    MultiArray<2, unsigned char> src(w, h);
+    MultiArray<2, float>         dest(w_new, h_new);
+    
+    resizeImageCatmullRomInterpolation(src, dest);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void resizeImageCatmullRomInterpolation)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+resizeImageCatmullRomInterpolation(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
+                      DestIterator dest_iter, DestIterator dest_iter_end, DestAccessor dest_acc)
+{
+    resizeImageSplineInterpolation(src_iter, src_iter_end, src_acc, dest_iter, dest_iter_end, dest_acc,
+                                  CatmullRomSpline<double>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+resizeImageCatmullRomInterpolation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                   triple<DestIterator, DestIterator, DestAccessor> dest)
+{
+    resizeImageCatmullRomInterpolation(src.first, src.second, src.third,
+                                       dest.first, dest.second, dest.third);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+resizeImageCatmullRomInterpolation(MultiArrayView<2, T1, S1> const & src,
+                                   MultiArrayView<2, T2, S2> dest)
+{
+    resizeImageCatmullRomInterpolation(srcImageRange(src),
+                                       destImageRange(dest));
+}
+
+/*****************************************************************/
+/*                                                               */
+/*              resizeImageCoscotInterpolation                   */
+/*                                                               */
+/*****************************************************************/
+
+/** \brief Resize image using the Coscot interpolation function.
+
+    The function calls \ref resizeImageSplineInterpolation() with
+    \ref vigra::CoscotFunction as an interpolation kernel.
+    The interpolated function has one continuous derivative.
+    (See \ref resizeImageSplineInterpolation() for more documentation)
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        resizeImageCoscotInterpolation(MultiArrayView<2, T1, S1> const & src,
+                                       MultiArrayView<2, T2, S2> dest);
+    }
+    \endcode
+
+    \deprecatedAPI{resizeImageCoscotInterpolation}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        resizeImageCoscotInterpolation(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
+                              DestIterator dest_iter, DestIterator dest_iter_end, DestAccessor dest_acc);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        resizeImageCoscotInterpolation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                              triple<DestIterator, DestIterator, DestAccessor> dest);
+    }
+    \endcode
+    \deprecatedEnd
+
+
+    <b>\#include</b> \<vigra/resizeimage.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    MultiArray<2, unsigned char> src(w, h);
+    MultiArray<2, float>         dest(w_new, h_new);
+    
+    resizeImageCoscotInterpolation(src, dest);
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void resizeImageCoscotInterpolation)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+resizeImageCoscotInterpolation(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
+                      DestIterator dest_iter, DestIterator dest_iter_end, DestAccessor dest_acc)
+{
+    resizeImageSplineInterpolation(src_iter, src_iter_end, src_acc, dest_iter, dest_iter_end, dest_acc,
+                                   CoscotFunction<double>());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+resizeImageCoscotInterpolation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                               triple<DestIterator, DestIterator, DestAccessor> dest)
+{
+    resizeImageCoscotInterpolation(src.first, src.second, src.third,
+                                   dest.first, dest.second, dest.third);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+resizeImageCoscotInterpolation(MultiArrayView<2, T1, S1> const & src,
+                               MultiArrayView<2, T2, S2> dest)
+{
+    resizeImageCoscotInterpolation(srcImageRange(src),
+                                   destImageRange(dest));
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_RESIZEIMAGE_HXX
diff --git a/include/vigra/rfftw.hxx b/include/vigra/rfftw.hxx
new file mode 100644
index 0000000..1517dc4
--- /dev/null
+++ b/include/vigra/rfftw.hxx
@@ -0,0 +1,248 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_RFFTW_HXX
+#define VIGRA_RFFTW_HXX
+
+#include "array_vector.hxx"
+#include "fftw.hxx"
+#include <rfftw.h>
+
+namespace vigra {
+
+namespace detail {
+
+struct FFTWSinCosConfig
+{
+    ArrayVector<fftw_real> twiddles;
+    ArrayVector<fftw_real> fftwInput;
+    ArrayVector<fftw_complex> fftwTmpResult;
+    fftw_real norm;
+    rfftwnd_plan fftwPlan;
+};
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Config>
+void 
+cosineTransformLineImpl(SrcIterator s, SrcIterator send, SrcAccessor src, 
+                        DestIterator d, DestAccessor dest,
+                        Config & config)
+{
+    int size = send - s;
+    int ns2 = size / 2;
+    int nm1 = size - 1;
+    int modn = size % 2;
+
+    if(size <= 0)
+        return;
+    
+    fftw_real const * twiddles = config.twiddles.begin();
+    fftw_real * fftwInput = config.fftwInput.begin();
+    fftw_complex * fftwTmpResult = config.fftwTmpResult.begin();
+    fftw_real norm = config.norm;
+    rfftwnd_plan fftwPlan = config.fftwPlan;
+
+    switch(size)
+    {
+      case 1:
+      {
+        dest.set(src(s) / norm, d);
+        break;
+      }
+      case 2:
+      {
+        dest.set((src(s) + src(s, 1)) / norm, d);
+        dest.set((src(s) - src(s, 1)) / norm, d, 1);
+        break;
+      }
+      case 3:
+      {
+        fftw_real x1p3 = src(s) + src(s, 2);
+        fftw_real tx2 =  2.0 * src(s, 1);
+
+        dest.set((x1p3 + tx2) / norm, d, 0);
+        dest.set((src(s) - src(s, 2)) / norm, d, 1);
+        dest.set((x1p3 - tx2) / norm, d, 2);
+        break;
+      }
+      default:
+      {
+        fftw_real c1 = src(s) - src(s, nm1);
+        fftwInput[0] = src(s) + src(s, nm1);
+        for(int k=1; k<ns2; ++k)
+        {
+            int kc = nm1 - k;
+            fftw_real t1 = src(s, k) + src(s, kc);
+            fftw_real t2 = src(s, k) - src(s, kc);
+            c1 = c1 + twiddles[kc] * t2;
+            t2 = twiddles[k] * t2;
+            fftwInput[k] = t1 - t2;
+            fftwInput[kc] = t1 + t2;
+        }
+
+        if (modn != 0)
+        {
+            fftwInput[ns2] = 2.0*src(s, ns2);
+        }
+        rfftwnd_one_real_to_complex(fftwPlan, fftwInput, fftwTmpResult);
+        dest.set(fftwTmpResult[0].re / norm, d, 0);
+        for(int k=1; k<(size+1)/2; ++k)
+        {
+            dest.set(fftwTmpResult[k].re, d, 2*k-1);
+            dest.set(fftwTmpResult[k].im, d, 2*k);
+        }
+        fftw_real xim2 = dest(d, 1);
+        dest.set(c1 / norm, d, 1);
+        for(int k=3; k<size; k+=2)
+        {
+            fftw_real xi = dest(d, k);
+            dest.set(dest(d, k-2) - dest(d, k-1) / norm, d, k);
+            dest.set(xim2 / norm, d, k-1);
+            xim2 = xi;
+        }
+        if (modn != 0)
+        {
+            dest.set(xim2 / norm, d, size-1);
+        }
+      }
+    }
+}
+
+} // namespace detail
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+void cosineTransformX(SrcTraverser sul, SrcTraverser slr, SrcAccessor src,
+                      DestTraverser dul, DestAccessor dest, fftw_real norm)
+{
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    
+    detail::FFTWSinCosConfig config;
+
+    // horizontal transformation
+    int ns2 = w / 2;
+    int nm1 = w - 1;
+    int modn = w % 2;
+    
+    config.twiddles.resize(w+1);
+    config.fftwInput.resize(w+1);
+    config.fftwTmpResult.resize(w+1);
+    config.norm = norm;
+    config.fftwPlan = rfftw2d_create_plan(1, nm1, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE );
+
+    fftw_real dt = M_PI / nm1;
+    for(int k=1; k<ns2; ++k)
+    {
+        fftw_real f = dt * k;
+        config.twiddles[k] = 2.0*VIGRA_CSTD::sin(f);
+        config.twiddles[nm1-k] = 2.0*VIGRA_CSTD::cos(f);
+    }
+
+    for(; sul.y != slr.y; ++sul.y, ++dul.y)
+    {
+        typename SrcTraverser::row_iterator s = sul.rowIterator();
+        typename SrcTraverser::row_iterator send = s + w;
+        typename DestTraverser::row_iterator d = dul.rowIterator();
+        cosineTransformLineImpl(s, send, src, d, dest, config);
+    }
+
+    rfftwnd_destroy_plan(config.fftwPlan);
+}
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+void cosineTransformY(SrcTraverser sul, SrcTraverser slr, SrcAccessor src,
+                      DestTraverser dul, DestAccessor dest, fftw_real norm)
+{
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+    
+    detail::FFTWSinCosConfig config;
+
+    // horizontal transformation
+    int ns2 = h / 2;
+    int nm1 = h - 1;
+    int modn = h % 2;
+    
+    config.twiddles.resize(h + 1);
+    config.fftwInput.resize(h + 1);
+    config.fftwTmpResult.resize(h + 1);
+    config.norm = norm;
+    config.fftwPlan = rfftw2d_create_plan(1, nm1, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE );
+
+    fftw_real dt = M_PI / nm1;
+    for(int k=1; k<ns2; ++k)
+    {
+        fftw_real f = dt * k;
+        config.twiddles[k] = 2.0*VIGRA_CSTD::sin(f);
+        config.twiddles[nm1-k] = 2.0*VIGRA_CSTD::cos(f);
+    }
+
+    for(; sul.x != slr.x; ++sul.x, ++dul.x)
+    {
+        typename SrcTraverser::column_iterator s = sul.columnIterator();
+        typename SrcTraverser::column_iterator send = s + h;
+        typename DestTraverser::column_iterator d = dul.columnIterator();
+        cosineTransformLineImpl(s, send, src, d, dest, config);
+    }
+
+    rfftwnd_destroy_plan(config.fftwPlan);
+}
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+inline void 
+realFourierTransformXEvenYEven(SrcTraverser sul, SrcTraverser slr, SrcAccessor src,
+                      DestTraverser dul, DestAccessor dest, fftw_real norm)
+{
+    BasicImage<fftw_real> tmp(slr - sul);
+    cosineTransformX(sul, slr, src, tmp.upperLeft(), tmp.accessor(), 1.0);
+    cosineTransformY(tmp.upperLeft(), tmp.lowerRight(), tmp.accessor(), dul, dest, norm);
+}
+
+template <class SrcTraverser, class SrcAccessor,
+          class DestTraverser, class DestAccessor>
+inline void 
+realFourierTransformXEvenYEven(triple<SrcTraverser, SrcTraverser, SrcAccessor> src,
+                      pair<DestTraverser, DestAccessor> dest, fftw_real norm)
+{
+    realFourierTransformXEvenYEven(src.first, src.second, src.third, dest.first, dest.second, norm);
+}
+
+} // namespace vigra
+
+#endif // VIGRA_RFFTW_HXX
diff --git a/include/vigra/rgbvalue.hxx b/include/vigra/rgbvalue.hxx
new file mode 100644
index 0000000..dd912ec
--- /dev/null
+++ b/include/vigra/rgbvalue.hxx
@@ -0,0 +1,1331 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_RGBVALUE_HXX
+#define VIGRA_RGBVALUE_HXX
+
+#include <cmath>    // abs(double)
+#include <cstdlib>  // abs(int)
+#include "config.hxx"
+#include "numerictraits.hxx"
+#include "accessor.hxx"
+#include "tinyvector.hxx"
+#include "static_assert.hxx"
+
+namespace vigra {
+
+namespace detail {
+
+template <unsigned int I, unsigned int R, unsigned int G, unsigned int B>
+struct SelectColorIndexRHS;
+
+template <unsigned int R, unsigned int G, unsigned int B>
+struct SelectColorIndexRHS<0, R, G, B>
+{
+    enum { res = R };
+};
+
+template <unsigned int R, unsigned int G, unsigned int B>
+struct SelectColorIndexRHS<1, R, G, B>
+{
+    enum { res = G };
+};
+
+template <unsigned int R, unsigned int G, unsigned int B>
+struct SelectColorIndexRHS<2, R, G, B>
+{
+    enum { res = B };
+};
+
+} // namespace detail
+
+#ifndef DOXYGEN
+
+template <unsigned int R, unsigned int G, unsigned int B>
+struct RGBValue_bad_color_indices
+: staticAssert::AssertBool<(R < 3 && G < 3 && B < 3 &&
+                           ((1 << R) + (1 << G) + (1 << B) == 7))>
+{};
+
+#endif /* DOXYGEN */
+
+
+/********************************************************/
+/*                                                      */
+/*                      RGBValue                        */
+/*                                                      */
+/********************************************************/
+
+/** \brief Class for a single RGB value.
+
+    This class contains three values (of the specified type) that represent
+    red, green, and blue color channels. By means of the template parameters
+    <tt>RED_IDX, GREEN_IDX, BLUE_IDX</tt>, the indices 0, 1, 2 can be assigned to
+    the three colors arbitrarily, so that, for example, a BGR type can be created
+    as
+
+    \code
+    typedef RGBValue<unsigned char, 2,1,0> BGRValue;
+    \endcode
+
+    The standard order red=0, green=1, blue=2 is the default. There are three possibilities
+    to access the color values: accessor functions (\ref red(), \ref green(),
+    \ref blue()), index operator (operator[](dx), where the <tt>rgb[RED_IDX]</tt>
+    returns red etc.) and iterator (STL-compatible random access
+    iterator that references the three colors in turn). The latter two
+    methods, together with the necessary embedded typedefs, ensure
+    compatibility of a RGBValue with a STL vector.
+
+    \ref RGBValueOperators "Arithmetic operations" are defined as component-wise applications of these
+    operations. Addition, subtraction, and multiplication of two RGBValues
+    (+=, -=, *=, +, -, *, unary -), multiplication and division of an
+    RGBValue with a double, and NumericTraits/PromoteTraits are defined,
+    so that RGBValue fulfills the requirements of a \ref LinearAlgebraConcept "Linear Algebra".
+
+    A number of \ref RGBValueAccessors "accessors" are provided
+    that support access to RGBValues as a whole, to a selected
+    color component, or to the luminance value.
+
+    <b>\#include</b> \<vigra/rgbvalue.hxx\><br>
+    Namespace: vigra
+*/
+template <class VALUETYPE, unsigned int RED_IDX = 0, unsigned int GREEN_IDX = 1, unsigned int BLUE_IDX = 2>
+class RGBValue
+: public TinyVector<VALUETYPE, 3>
+{
+    typedef TinyVector<VALUETYPE, 3> Base;
+
+        // inverse mapping from index to color
+    enum {
+      IDX0 = (RED_IDX == 0) ? 0 : (GREEN_IDX == 0) ? 1 : 2,
+      IDX1 = (RED_IDX == 1) ? 0 : (GREEN_IDX == 1) ? 1 : 2,
+      IDX2 = (RED_IDX == 2) ? 0 : (GREEN_IDX == 2) ? 1 : 2
+    };
+
+  public:
+        /** STL-compatible definition of valuetype
+        */
+    typedef typename Base::value_type value_type;
+        /** STL-compatible definition of iterator
+        */
+    typedef typename Base::iterator iterator;
+        /** STL-compatible definition of const iterator
+        */
+    typedef typename Base::const_iterator const_iterator;
+        /** squared norm type (result of squaredManitude())
+        */
+    typedef typename Base::SquaredNormType SquaredNormType;
+        /** norm type (result of magnitude())
+        */
+    typedef typename Base::NormType NormType;
+
+    typedef typename Base::reference reference;
+    typedef typename Base::const_reference const_reference;
+    typedef typename Base::pointer pointer;
+    typedef typename Base::const_pointer const_pointer;
+    typedef typename Base::size_type size_type;
+    typedef typename Base::difference_type difference_type;
+    typedef typename Base::scalar_multiplier scalar_multiplier;
+    typedef typename Base::ReverseCopyTag ReverseCopyTag;
+
+        /** Color index positions
+        */
+    enum
+    {
+      RedIdx = RED_IDX,
+      GreenIdx = GREEN_IDX,
+      BlueIdx = BLUE_IDX
+    };
+
+        /** Construct from explicit color values.
+            \a first, \a second, \a third are written in this order,
+            irrespective of how the color indices are specified.
+        */
+    RGBValue(value_type first, value_type second, value_type third)
+    : Base(first, second, third)
+    {
+        VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
+    }
+
+        /** Construct gray value.
+        */
+    RGBValue(value_type gray)
+    : Base(gray, gray, gray)
+    {
+        VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
+    }
+
+        /** Copy from raw memory. The order is preserved,
+            irrespective of how the color indices are specified.
+        */
+    explicit RGBValue(const_pointer i)
+    : Base(i)
+    {
+        VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
+    }
+
+        /** Construct by reverse copying from raw memory.
+        */
+    RGBValue(const_pointer i, ReverseCopyTag reverse)
+    : Base(i, reverse)
+    {
+        VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
+    }
+
+        /** Default constructor (sets all components to 0)
+        */
+    RGBValue()
+    : Base(0, 0, 0)
+    {
+        VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
+    }
+
+#if !defined(TEMPLATE_COPY_CONSTRUCTOR_BUG)
+
+    RGBValue(RGBValue const & r)
+    : Base((Base const &)r)
+    {
+        VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
+    }
+
+    RGBValue & operator=(RGBValue const & r)
+    {
+        Base::operator=(r);
+        return *this;
+    }
+
+#endif // TEMPLATE_COPY_CONSTRUCTOR_BUG
+
+        /** Copy constructor.
+        */
+    template <class U, unsigned int R, unsigned int G, unsigned int B>
+    RGBValue(RGBValue<U, R, G, B> const & r)
+    : Base(detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX0, R, G, B>::res]),
+           detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX1, R, G, B>::res]),
+           detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectColorIndexRHS<IDX2, R, G, B>::res]))
+    {
+        VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
+    }
+
+        /** Copy assignment.
+        */
+    template <class U, unsigned int R, unsigned int G, unsigned int B>
+    RGBValue & operator=(RGBValue<U, R, G, B> const & r)
+    {
+        setRed(detail::RequiresExplicitCast<value_type>::cast(r.red()));
+        setGreen(detail::RequiresExplicitCast<value_type>::cast(r.green()));
+        setBlue(detail::RequiresExplicitCast<value_type>::cast(r.blue()));
+        return *this;
+    }
+
+        /** construct from TinyVector
+        */
+    RGBValue(TinyVector<value_type, 3> const & r)
+    : Base(r)
+    {
+        VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, BLUE_IDX>));
+    }
+
+        /** assign TinyVector.
+        */
+    RGBValue & operator=(TinyVector<value_type, 3> const & r)
+    {
+        Base::operator=(r);
+        return *this;
+    }
+
+        /** Unary negation (construct RGBValue with negative values)
+        */
+    RGBValue operator-() const
+    {
+        return RGBValue(-(*this)[0], -(*this)[1], -(*this)[2]);
+    }
+
+        /** Access red component.
+        */
+    value_type & red() { return (*this)[RED_IDX]; }
+
+        /** Access green component.
+        */
+    value_type & green() { return (*this)[GREEN_IDX]; }
+
+        /** Access blue component.
+        */
+    value_type & blue() { return (*this)[BLUE_IDX]; }
+
+        /** Get red component.
+        */
+    value_type const & red() const { return (*this)[RED_IDX]; }
+
+        /** Get green component.
+        */
+    value_type const & green() const { return (*this)[GREEN_IDX]; }
+
+        /** Get blue component.
+        */
+    value_type const & blue() const { return (*this)[BLUE_IDX]; }
+
+        /** Calculate luminance.
+        */
+    value_type luminance() const {
+         return detail::RequiresExplicitCast<value_type>::cast(0.3*red() + 0.59*green() + 0.11*blue()); }
+
+        /** Calculate magnitude.
+        */
+    NormType magnitude() const {
+         return Base::magnitude();
+    }
+
+        /** Calculate squared magnitude.
+        */
+    SquaredNormType squaredMagnitude() const {
+         return Base::squaredMagnitude();
+    }
+
+        /** Set red component. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
+        */
+    template <class V>
+    void setRed(V value) { (*this)[RED_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
+
+        /** Set green component.The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
+        */
+    template <class V>
+    void setGreen(V value) { (*this)[GREEN_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
+
+        /** Set blue component.The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
+        */
+    template <class V>
+    void setBlue(V value) { (*this)[BLUE_IDX] = detail::RequiresExplicitCast<value_type>::cast(value); }
+
+
+    template <class V>
+    void setRGB(V r, V g, V b)
+    {
+        (*this)[RED_IDX] = detail::RequiresExplicitCast<value_type>::cast(r);
+        (*this)[GREEN_IDX] = detail::RequiresExplicitCast<value_type>::cast(g);
+        (*this)[BLUE_IDX] = detail::RequiresExplicitCast<value_type>::cast(b);
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                     RGBValue Comparison              */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup RGBValueOperators Functions for RGBValue
+
+    \brief Implement basic arithmetic and equality for RGBValue.
+
+    These functions fulfill the requirements of a Linear Algebra.
+    Return types are determined according to \ref RGBValueTraits.
+
+    <b>\#include</b> \<vigra/rgbvalue.hxx\><br>
+    Namespace: vigra
+    <p>
+
+ */
+//@{
+    /// component-wise equal
+template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
+          class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
+inline
+bool
+operator==(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
+           RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
+{
+    return (l.red() == r.red()) &&
+           (l.green() == r.green()) &&
+           (l.blue() == r.blue());
+}
+
+    /// component-wise not equal
+template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
+          class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
+inline
+bool
+operator!=(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l,
+           RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
+{
+    return (l.red() != r.red()) ||
+           (l.green() != r.green()) ||
+           (l.blue() != r.blue());
+}
+
+template <class V, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
+                   unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
+inline
+bool
+closeAtTolerance(RGBValue<V, RIDX1, GIDX1, BIDX1> const & l,
+                 RGBValue<V, RIDX2, GIDX2, BIDX2> const & r,
+                 V epsilon = NumericTraits<V>::epsilon())
+{
+    return closeAtTolerance(l.red(), r.red(), epsilon) &&
+           closeAtTolerance(l.green(), r.green(), epsilon) &&
+           closeAtTolerance(l.blue(), r.blue(), epsilon);
+}
+
+
+//@}
+
+/********************************************************/
+/*                                                      */
+/*                      RGBValue-Traits                 */
+/*                                                      */
+/********************************************************/
+
+/** \page RGBValueTraits Numeric and Promote Traits of RGBValue
+    The numeric and promote traits for RGBValues follow
+    the general specifications for \ref NumericPromotionTraits.
+    They are implemented in terms of the traits of the basic types by
+    partial template specialization. Note that PromoteTraits are only defined
+    for the case that the color indices are the same in both RGBValues.
+
+    \code
+
+    template <class T, unsigned int R, unsigned int G, unsigned int B>
+    struct NumericTraits<RGBValue<T, R, G, B> >
+    {
+        typedef RGBValue<T, R, G, B> Type;
+        typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promote;
+        typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> RealPromote;
+        typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B> ComplexPromote;
+        typedef T ValueType;
+
+        typedef typename NumericTraits<T>::isIntegral isIntegral;
+        typedef VigraFalseType isScalar;
+        typedef typename NumericTraits<T>::isSigned isSigned;
+
+        // etc.
+    };
+
+    template <class T, unsigned int R, unsigned int G, unsigned int B>
+    struct NormTraits<RGBValue<T, R, G, B> >
+    {
+        typedef RGBValue<T, R, G, B> Type;
+        typedef typename Type::SquaredNormType    SquaredNormType;
+        typedef typename Type::NormType           NormType;
+    };
+
+    template <class T1, unsigned int R, unsigned int G, unsigned int B, class T2>
+    struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> >
+    {
+        typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> Promote;
+    };
+
+    template <class T, unsigned int R, unsigned int G, unsigned int B>
+    struct PromoteTraits<RGBValue<T, R, G, B>, double >
+    {
+        typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
+    };
+
+    template <class T, unsigned int R, unsigned int G, unsigned int B>
+    struct PromoteTraits<double, RGBValue<T, R, G, B> >
+    {
+        typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
+    };
+    \endcode
+
+    <b>\#include</b> \<vigra/rgbvalue.hxx\><br>
+    Namespace: vigra
+
+*/
+
+#if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
+
+template <class T, unsigned int R, unsigned int G, unsigned int B>
+struct NumericTraits<RGBValue<T, R, G, B> >
+{
+    typedef RGBValue<T, R, G, B> Type;
+    typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promote;
+    typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> RealPromote;
+    typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B> ComplexPromote;
+    typedef T ValueType;
+
+    typedef typename NumericTraits<T>::isIntegral isIntegral;
+    typedef VigraFalseType isScalar;
+    typedef typename NumericTraits<T>::isSigned isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+
+    static Type zero()
+    {
+        return Type(NumericTraits<T>::zero());
+    }
+    static Type one()
+    {
+        return Type(NumericTraits<T>::one());
+    }
+    static Type nonZero()
+    {
+        return Type(NumericTraits<T>::nonZero());
+    }
+
+    static Type min()
+    {
+        return Type(NumericTraits<T>::min());
+    }
+    static Type max()
+    {
+        return Type(NumericTraits<T>::max());
+    }
+
+    static Promote toPromote(Type const & v)
+    {
+        return Promote(v);
+    }
+    static RealPromote toRealPromote(Type const & v)
+    {
+        return RealPromote(v);
+    }
+    static Type fromPromote(Promote const & v)
+    {
+      return Type(NumericTraits<T>::fromPromote(v.red()),
+                  NumericTraits<T>::fromPromote(v.green()),
+                  NumericTraits<T>::fromPromote(v.blue()));
+    }
+    static Type fromRealPromote(RealPromote const & v)
+    {
+        return Type(NumericTraits<T>::fromRealPromote(v.red()),
+                    NumericTraits<T>::fromRealPromote(v.green()),
+                    NumericTraits<T>::fromRealPromote(v.blue()));
+    }
+};
+
+template <class T, unsigned int R, unsigned int G, unsigned int B>
+struct NormTraits<RGBValue<T, R, G, B> >
+{
+    typedef RGBValue<T, R, G, B> Type;
+    typedef typename Type::SquaredNormType    SquaredNormType;
+    typedef typename Type::NormType           NormType;
+};
+
+template <class T1, unsigned int R, unsigned int G, unsigned int B, class T2>
+struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> >
+{
+    typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> Promote;
+};
+
+template <class T, unsigned int R, unsigned int G, unsigned int B>
+struct PromoteTraits<RGBValue<T, R, G, B>, double >
+{
+    typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
+};
+
+template <class T, unsigned int R, unsigned int G, unsigned int B>
+struct PromoteTraits<double, RGBValue<T, R, G, B> >
+{
+    typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promote;
+};
+
+template<class T, unsigned int R, unsigned int G, unsigned int B>
+struct CanSkipInitialization<RGBValue<T, R, G, B> >
+{
+    typedef typename CanSkipInitialization<T>::type type;
+    static const bool value = type::asBool;
+};
+
+
+#else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+#define RGBVALUE_NUMTRAITS(T) \
+template<>\
+struct NumericTraits<RGBValue<T, 0, 1, 2> >\
+{\
+    typedef RGBValue<T> Type; \
+    typedef RGBValue<NumericTraits<T>::Promote> Promote; \
+    typedef RGBValue<NumericTraits<T>::RealPromote> RealPromote; \
+    typedef RGBValue<NumericTraits<T>::ComplexPromote> ComplexPromote; \
+    typedef T ValueType; \
+    \
+    typedef NumericTraits<T>::isIntegral isIntegral; \
+    typedef VigraFalseType isScalar; \
+    typedef NumericTraits<T>::isSigned isSigned; \
+    typedef VigraFalseType isOrdered; \
+    typedef VigraFalseType isComplex; \
+    \
+    static RGBValue<T> zero() { \
+        return RGBValue<T>(NumericTraits<T>::zero()); \
+    }\
+    static RGBValue<T> one() { \
+        return RGBValue<T>(NumericTraits<T>::one()); \
+    }\
+    static RGBValue<T> nonZero() { \
+        return RGBValue<T>(NumericTraits<T>::nonZero()); \
+    }\
+    \
+    static Promote toPromote(RGBValue<T> const & v) { \
+        return Promote(v); \
+    }\
+    static RealPromote toRealPromote(RGBValue<T> const & v) { \
+        return RealPromote(v); \
+    }\
+    static RGBValue<T> fromPromote(Promote const & v) { \
+        RGBValue<T> res;\
+        RGBValue<T>::iterator d = res.begin();\
+        Promote::const_iterator s = v.begin();\
+        for(; d != res.end(); ++d, ++s)\
+            *d = NumericTraits<T>::fromPromote(*s);\
+        return res;\
+    }\
+    static RGBValue<T> fromRealPromote(RealPromote const & v) {\
+        RGBValue<T> res;\
+        RGBValue<T>::iterator d = res.begin();\
+        RealPromote::const_iterator s = v.begin();\
+        for(; d != res.end(); ++d, ++s)\
+            *d = NumericTraits<T>::fromRealPromote(*s);\
+        return res;\
+    }\
+}; \
+template<>\
+struct NormTraits<RGBValue<T, 0, 1, 2> >\
+{\
+    typedef RGBValue<T> Type;\
+    typedef Type::SquaredNormType           SquaredNormType; \
+    typedef Type::NormType NormType; \
+};
+
+#define RGBVALUE_PROMTRAITS1(type1) \
+template<> \
+struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type1, 0, 1, 2> > \
+{ \
+    typedef RGBValue<PromoteTraits<type1, type1>::Promote> Promote; \
+    static Promote toPromote(RGBValue<type1> const & v) { \
+        return static_cast<Promote>(v); } \
+}; \
+template <> \
+struct PromoteTraits<RGBValue<type1, 0, 1, 2>, double > \
+{ \
+    typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
+}; \
+template <> \
+struct PromoteTraits<double, RGBValue<type1, 0, 1, 2> > \
+{ \
+    typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \
+};
+
+#define RGBVALUE_PROMTRAITS2(type1, type2) \
+template<> \
+struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type2, 0, 1, 2> > \
+{ \
+    typedef RGBValue<PromoteTraits<type1, type2>::Promote> Promote; \
+    static Promote toPromote(RGBValue<type1> const & v) { \
+        return static_cast<Promote>(v); } \
+    static Promote toPromote(RGBValue<type2> const & v) { \
+        return static_cast<Promote>(v); } \
+};
+
+RGBVALUE_NUMTRAITS(unsigned char)
+RGBVALUE_NUMTRAITS(int)
+RGBVALUE_NUMTRAITS(float)
+RGBVALUE_NUMTRAITS(double)
+RGBVALUE_PROMTRAITS1(unsigned char)
+RGBVALUE_PROMTRAITS1(int)
+RGBVALUE_PROMTRAITS1(float)
+RGBVALUE_PROMTRAITS1(double)
+RGBVALUE_PROMTRAITS2(float, unsigned char)
+RGBVALUE_PROMTRAITS2(unsigned char, float)
+RGBVALUE_PROMTRAITS2(int, unsigned char)
+RGBVALUE_PROMTRAITS2(unsigned char, int)
+RGBVALUE_PROMTRAITS2(int, float)
+RGBVALUE_PROMTRAITS2(float, int)
+RGBVALUE_PROMTRAITS2(double, unsigned char)
+RGBVALUE_PROMTRAITS2(unsigned char, double)
+RGBVALUE_PROMTRAITS2(int, double)
+RGBVALUE_PROMTRAITS2(double, int)
+RGBVALUE_PROMTRAITS2(double, float)
+RGBVALUE_PROMTRAITS2(float, double)
+
+#undef RGBVALUE_NUMTRAITS
+#undef RGBVALUE_PROMTRAITS1
+#undef RGBVALUE_PROMTRAITS2
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+
+/********************************************************/
+/*                                                      */
+/*                      RGBValue-Arithmetic             */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup RGBValueOperators
+ */
+//@{
+    /// componentwise add-assignment
+template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
+          class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
+inline
+RGBValue<V1, RIDX1, GIDX1, BIDX1> &
+operator+=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
+           RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
+{
+    l.red() += r.red();
+    l.green() += r.green();
+    l.blue() += r.blue();
+    return l;
+}
+
+    /// componentwise subtract-assignment
+template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
+          class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
+inline
+RGBValue<V1, RIDX1, GIDX1, BIDX1> &
+operator-=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
+           RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
+{
+    l.red() -= r.red();
+    l.green() -= r.green();
+    l.blue() -= r.blue();
+    return l;
+}
+
+    /// componentwise multiply-assignment
+template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
+          class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
+inline
+RGBValue<V1, RIDX1, GIDX1, BIDX1> &
+operator*=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
+           RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
+{
+    l.red() = V1(l.red() * r.red());
+    l.green() = V1(l.green() * r.green());
+    l.blue() = V1(l.blue() * r.blue());
+    return l;
+}
+
+    /// componentwise scalar multiply-assignment
+template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
+inline
+RGBValue<V, RIDX, GIDX, BIDX> &
+operator*=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
+{
+    l.red() = V(l.red() * r);
+    l.green() = V(l.green() * r);
+    l.blue() = V(l.blue() * r);
+    return l;
+}
+
+    /// componentwise divide-assignment
+template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
+          class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
+inline
+RGBValue<V1, RIDX1, GIDX1, BIDX1> &
+operator/=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
+           RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
+{
+    l.red() = V1(l.red() / r.red());
+    l.green() = V1(l.green() / r.green());
+    l.blue() = V1(l.blue() / r.blue());
+    return l;
+}
+
+    /// componentwise scalar divide-assignment
+template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
+inline
+RGBValue<V, RIDX, GIDX, BIDX> &
+operator/=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r)
+{
+    l.red() = V(l.red() / r);
+    l.green() = V(l.green() / r);
+    l.blue() = V(l.blue() / r);
+    return l;
+}
+
+using VIGRA_CSTD::abs;
+
+    /// component-wise absolute value
+template <class T, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
+inline
+RGBValue<T, RIDX, GIDX, BIDX>
+abs(RGBValue<T, RIDX, GIDX, BIDX> const & v)
+{
+  return RGBValue<T, RIDX, GIDX, BIDX>(abs(v.red()), abs(v.green()), abs(v.blue()));
+}
+
+    /// component-wise addition
+template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
+inline
+typename PromoteTraits<RGBValue<V1, R, G, B>,
+                       RGBValue<V2, R, G, B> >::Promote
+operator+(RGBValue<V1, R, G, B> const & r1,
+          RGBValue<V2, R, G, B> const & r2)
+{
+    typename PromoteTraits<RGBValue<V1, R, G, B>,
+                           RGBValue<V2, R, G, B> >::Promote res(r1);
+
+    res += r2;
+
+    return res;
+}
+
+    /// component-wise subtraction
+template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
+inline
+typename PromoteTraits<RGBValue<V1, R, G, B>,
+                       RGBValue<V2, R, G, B> >::Promote
+operator-(RGBValue<V1, R, G, B> const & r1,
+          RGBValue<V2, R, G, B> const & r2)
+{
+    typename PromoteTraits<RGBValue<V1, R, G, B>,
+                           RGBValue<V2, R, G, B> >::Promote res(r1);
+
+    res -= r2;
+
+    return res;
+}
+
+    /// component-wise multiplication
+template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
+inline
+typename PromoteTraits<RGBValue<V1, R, G, B>,
+                       RGBValue<V2, R, G, B> >::Promote
+operator*(RGBValue<V1, R, G, B> const & r1,
+          RGBValue<V2, R, G, B> const & r2)
+{
+    typename PromoteTraits<RGBValue<V1, R, G, B>,
+                           RGBValue<V2, R, G, B> >::Promote res(r1);
+
+    res *= r2;
+
+    return res;
+}
+
+    /// component-wise left scalar multiplication
+template <class V, unsigned int R, unsigned int G, unsigned int B>
+inline
+typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
+operator*(double v, RGBValue<V, R, G, B> const & r)
+{
+    typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
+
+    res *= v;
+
+    return res;
+}
+
+    /// component-wise right scalar multiplication
+template <class V, unsigned int R, unsigned int G, unsigned int B>
+inline
+typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
+operator*(RGBValue<V, R, G, B> const & r, double v)
+{
+    typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
+
+    res *= v;
+
+    return res;
+}
+
+    /// component-wise division
+template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
+inline
+typename PromoteTraits<RGBValue<V1, R, G, B>,
+                       RGBValue<V2, R, G, B> >::Promote
+operator/(RGBValue<V1, R, G, B> const & r1,
+          RGBValue<V2, R, G, B> const & r2)
+{
+    typename PromoteTraits<RGBValue<V1, R, G, B>,
+                           RGBValue<V2, R, G, B> >::Promote res(r1);
+
+    res /= r2;
+
+    return res;
+}
+
+    /// component-wise scalar division
+template <class V, unsigned int R, unsigned int G, unsigned int B>
+inline
+typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote
+operator/(RGBValue<V, R, G, B> const & r, double v)
+{
+    typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r);
+
+    res /= v;
+
+    return res;
+}
+
+    /// cross product
+template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2>
+inline
+typename PromoteTraits<RGBValue<V1, R, G, B>,
+                       RGBValue<V2, R, G, B> >::Promote
+cross(RGBValue<V1, R, G, B> const & r1,
+      RGBValue<V2, R, G, B> const & r2)
+{
+    typedef typename PromoteTraits<RGBValue<V1, R, G, B>,
+                                   RGBValue<V2, R, G, B> >::Promote
+            Res;
+
+    return  Res(r1.green()*r2.blue() - r1.blue()*r2.green(),
+                r1.blue()*r2.red() - r1.red()*r2.blue(),
+                r1.red()*r2.green() - r1.green()*r2.red());
+}
+
+    /// dot product
+template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BIDX1,
+          class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2>
+inline
+typename PromoteTraits<V1, V2>::Promote
+dot(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & r1,
+    RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r2)
+{
+    return r1.red()*r2.red() + r1.green()*r2.green() + r1.blue()*r2.blue();
+}
+
+using VIGRA_CSTD::ceil;
+
+    /** Apply ceil() function to each RGB component.
+    */
+template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
+inline
+RGBValue<V, RIDX, GIDX, BIDX>
+ceil(RGBValue<V, RIDX, GIDX, BIDX> const & r)
+{
+    return RGBValue<V, RIDX, GIDX, BIDX>(ceil(r.red()),
+                                         ceil(r.green()),
+                                         ceil(r.blue()));
+}
+
+using VIGRA_CSTD::floor;
+
+    /** Apply floor() function to each RGB component.
+    */
+template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
+inline
+RGBValue<V, RIDX, GIDX, BIDX>
+floor(RGBValue<V, RIDX, GIDX, BIDX> const & r)
+{
+    return RGBValue<V, RIDX, GIDX, BIDX>(floor(r.red()),
+                                         floor(r.green()),
+                                         floor(r.blue()));
+}
+
+// overload min and max to avoid that std:min() and std::max() match
+template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
+inline
+RGBValue<V, RIDX, GIDX, BIDX>
+min(RGBValue<V, RIDX, GIDX, BIDX> const & l,
+    RGBValue<V, RIDX, GIDX, BIDX> const & r)
+{
+    typedef typename detail::LoopType<3>::type ltype;
+    RGBValue<V, RIDX, GIDX, BIDX> res(l);
+    ltype::min(res.begin(), r.begin());
+    return res;
+}
+
+template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX>
+inline
+RGBValue<V, RIDX, GIDX, BIDX>
+max(RGBValue<V, RIDX, GIDX, BIDX> const & l,
+    RGBValue<V, RIDX, GIDX, BIDX> const & r)
+{
+    typedef typename detail::LoopType<3>::type ltype;
+    RGBValue<V, RIDX, GIDX, BIDX> res(l);
+    ltype::max(res.begin(), r.begin());
+    return res;
+}
+
+
+//@}
+
+/********************************************************/
+/*                                                      */
+/*                      RGBValue-Accessors              */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup DataAccessors
+*/
+//@{
+/** \defgroup RGBValueAccessors Accessors for RGBValue */
+//@{
+    /** Encapsulate access to rgb values.
+
+    <b>\#include</b> \<vigra/rgbvalue.hxx\><br>
+    Namespace: vigra
+    */
+template <class RGBVALUE>
+class RGBAccessor
+: public VectorAccessor<RGBVALUE>
+{
+  public:
+
+    typedef typename RGBVALUE::value_type component_type;
+
+        /** Get value of the red component
+        */
+    template <class RGBIterator>
+    component_type const & red(RGBIterator const & rgb) const
+    {
+        return (*rgb).red();
+    }
+
+    template <class V, class RGBIterator>
+    void setRGB(V r, V g, V b, RGBIterator const & rgb) const
+    {
+        (*rgb).setRGB( r, g, b );
+    }
+
+
+        /** Set value of the red component. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
+        */
+    template <class V, class RGBIterator>
+    void setRed(V value, RGBIterator const & rgb) const
+    {
+        (*rgb).setRed(value);
+    }
+
+        /** Get value of the red component at an offset
+        */
+    template <class RGBIterator, class DIFFERENCE>
+    component_type const & red(RGBIterator const & rgb, DIFFERENCE diff) const
+    {
+        return rgb[diff].red();
+    }
+
+        /** Set value of the red component at an offset. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
+        */
+    template <class V, class RGBIterator, class DIFFERENCE>
+    void setRed(V value, RGBIterator const & rgb, DIFFERENCE diff) const
+    {
+        rgb[diff].setRed(value);
+    }
+
+        /** Get value of the green component
+        */
+    template <class RGBIterator>
+    component_type const & green(RGBIterator const & rgb) const
+    {
+        return (*rgb).green();
+    }
+
+        /** Set value of the green component. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
+        */
+    template <class V, class RGBIterator>
+    void setGreen(V value, RGBIterator const & rgb) const
+    {
+        (*rgb).setGreen(value);
+    }
+
+        /** Get value of the green component at an offset
+        */
+    template <class RGBIterator, class DIFFERENCE>
+    component_type const & green(RGBIterator const & rgb, DIFFERENCE d) const
+    {
+        return rgb[d].green();
+    }
+
+        /** Set value of the green component at an offset. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
+        */
+    template <class V, class RGBIterator, class DIFFERENCE>
+    void setGreen(V value, RGBIterator const & rgb, DIFFERENCE d) const
+    {
+        rgb[d].setGreen(value);
+    }
+
+        /** Get value of the blue component
+        */
+    template <class RGBIterator>
+    component_type const & blue(RGBIterator const & rgb) const
+    {
+        return (*rgb).blue();
+    }
+
+        /** Set value of the blue component. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
+        */
+    template <class V, class RGBIterator>
+    void setBlue(V value, RGBIterator const & rgb) const
+    {
+        (*rgb).setBlue(value);
+    }
+
+        /** Get value of the blue component at an offset
+        */
+    template <class RGBIterator, class DIFFERENCE>
+    component_type const & blue(RGBIterator const & rgb, DIFFERENCE d) const
+    {
+        return rgb[d].blue();
+    }
+
+        /** Set value of the blue component at an offset. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
+        */
+    template <class V, class RGBIterator, class DIFFERENCE>
+    void setBlue(V value, RGBIterator const & rgb, DIFFERENCE d) const
+    {
+        rgb[d].setBlue(value);
+    }
+
+};
+
+
+/********************************************************/
+/*                                                      */
+/*                       RedAccessor                    */
+/*                                                      */
+/********************************************************/
+
+    /** Encapsulate access to red band of an rgb value.
+
+    <b>\#include</b> \<vigra/rgbvalue.hxx\><br>
+    Namespace: vigra
+    */
+template <class RGBVALUE>
+class RedAccessor
+{
+  public:
+    typedef typename RGBVALUE::value_type value_type;
+
+        /** Get value of the red component
+        */
+    template <class ITERATOR>
+    value_type const & operator()(ITERATOR const & i) const {
+        return (*i).red();
+    }
+
+        /** Get value of the red component at an offset
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
+    {
+        return i[d].red();
+    }
+
+        /** Set value of the red component. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+        */
+    template <class V, class ITERATOR>
+    void set(V value, ITERATOR const & i) const {
+        (*i).setRed(value);
+    }
+
+
+        /** Set value of the red component at an offset. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+        */
+    template <class V, class ITERATOR, class DIFFERENCE>
+    void set(V value, ITERATOR const & i, DIFFERENCE d) const
+    {
+        i[d].setRed(value);
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                     GreenAccessor                    */
+/*                                                      */
+/********************************************************/
+
+    /** Encapsulate access to green band of an rgb value.
+
+    <b>\#include</b> \<vigra/rgbvalue.hxx\><br>
+    Namespace: vigra
+    */
+template <class RGBVALUE>
+class GreenAccessor
+{
+  public:
+    typedef typename RGBVALUE::value_type value_type;
+
+        /** Get value of the green component
+        */
+    template <class ITERATOR>
+    value_type const & operator()(ITERATOR const & i) const {
+        return (*i).green();
+    }
+
+        /** Get value of the green component at an offset
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
+    {
+        return i[d].green();
+    }
+
+        /** Set value of the green component. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+        */
+    template <class V, class ITERATOR>
+    void set(V value, ITERATOR const & i) const {
+        (*i).setGreen(value);
+    }
+
+
+        /** Set value of the green component at an offset. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+        */
+    template <class V, class ITERATOR, class DIFFERENCE>
+    void set(V value, ITERATOR const & i, DIFFERENCE d) const
+    {
+        i[d].setGreen(value);
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                     BlueAccessor                     */
+/*                                                      */
+/********************************************************/
+
+    /** Encapsulate access to blue band of an rgb value.
+
+    <b>\#include</b> \<vigra/rgbvalue.hxx\><br>
+    Namespace: vigra
+    */
+template <class RGBVALUE>
+class BlueAccessor
+{
+  public:
+    typedef typename RGBVALUE::value_type value_type;
+
+        /** Get value of the blue component
+        */
+    template <class ITERATOR>
+    value_type const & operator()(ITERATOR const & i) const {
+        return (*i).blue();
+    }
+
+        /** Get value of the blue component at an offset
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    value_type const & operator()(ITERATOR const & i, DIFFERENCE d) const
+    {
+        return i[d].blue();
+    }
+
+        /** Set value of the blue component. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+        */
+    template <class V, class ITERATOR>
+    void set(V value, ITERATOR const & i) const {
+        (*i).setBlue(value);
+    }
+
+
+        /** Set value of the blue component at an offset. The type <TT>V</TT> of the passed
+            in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
+        */
+    template <class V, class ITERATOR, class DIFFERENCE>
+    void set(V value, ITERATOR const & i, DIFFERENCE d) const
+    {
+        i[d].setBlue(value);
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                  RGBToGrayAccessor                   */
+/*                                                      */
+/********************************************************/
+
+    /** Encapsulate access to luminance of an rgb value.
+
+    <b>\#include</b> \<vigra/rgbvalue.hxx\><br>
+    Namespace: vigra
+    */
+template <class RGBVALUE>
+class RGBToGrayAccessor
+{
+  public:
+    typedef typename RGBVALUE::value_type value_type;
+
+        /** Get value of the luminance
+        */
+    template <class ITERATOR>
+    value_type operator()(ITERATOR const & i) const {
+                return (*i).luminance(); }
+
+        /** Get value of the luminance at an offset
+        */
+    template <class ITERATOR, class DIFFERENCE>
+    value_type operator()(ITERATOR const & i, DIFFERENCE d) const
+    {
+        return i[d].luminance();
+    }
+};
+
+
+/********************************************************/
+/*                                                      */
+/*                  GrayToRGBAccessor                   */
+/*                                                      */
+/********************************************************/
+
+    /** Create an RGB view for a grayscale image by making all three channels
+        equal.
+
+    <b>\#include</b> \<vigra/rgbvalue.hxx\><br>
+    Namespace: vigra
+    */
+template <class VALUETYPE>
+class GrayToRGBAccessor
+{
+   public:
+     typedef typename vigra::RGBValue<VALUETYPE> value_type;
+
+         /** Get RGB value for the given pixel.
+         */
+     template <class ITERATOR>
+     value_type operator()(ITERATOR const & i) const {
+                 return value_type(*i,*i,*i); }
+
+         /** Get RGB value at an offset
+         */
+     template <class ITERATOR, class DIFFERENCE>
+     value_type operator()(ITERATOR const & i, DIFFERENCE d) const
+     {
+         return value_type(i[d],i[d],i[d]);
+     }
+};
+
+
+//@}
+//@}
+
+
+} // namespace vigra
+
+#endif // VIGRA_RGBVALUE_HXX
diff --git a/include/vigra/sampling.hxx b/include/vigra/sampling.hxx
new file mode 100644
index 0000000..a84531d
--- /dev/null
+++ b/include/vigra/sampling.hxx
@@ -0,0 +1,567 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by  Ullrich Koethe and Rahul Nair         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_SAMPLING_HXX
+#define VIGRA_SAMPLING_HXX
+
+#include "array_vector.hxx"
+#include "random.hxx"
+#include <map>
+#include <memory>
+#include <cmath>
+
+namespace vigra
+{
+
+/** \addtogroup MachineLearning Machine Learning
+**/
+//@{
+
+
+/**\brief Options object for the Sampler class.
+ 
+  <b>usage:</b>
+ 
+  \code
+  SamplerOptions opt =  SamplerOptions()
+                               .withReplacement()
+                               .sampleProportion(0.5);
+  \endcode
+ 
+  Note that the return value of all methods is <tt>*this</tt> which makes
+  concatenating of options as above possible.
+*/
+class SamplerOptions
+{
+  public:
+
+    double sample_proportion;
+    unsigned int sample_size;
+    bool   sample_with_replacement;
+    bool   stratified_sampling;
+    
+    SamplerOptions()
+    : sample_proportion(1.0),
+      sample_size(0), 
+      sample_with_replacement(true),
+      stratified_sampling(false)
+    {}
+
+        /**\brief Sample from training population with replacement.
+         *
+         * <br> Default: true
+         */
+    SamplerOptions& withReplacement(bool in = true)
+    {
+        sample_with_replacement = in;
+        return *this;
+    }
+
+        /**\brief Sample from training population without replacement.
+         *
+         * <br> Default (if you don't call this function): false
+         */
+    SamplerOptions& withoutReplacement(bool in = true)
+    {
+        sample_with_replacement = !in;
+        return *this;
+    }
+
+        /**\brief Draw the given number of samples.
+         * If stratifiedSampling is true, the \a size is equally distributed
+         * across all strata (e.g. <tt>size / strataCount</tt> samples are taken 
+         * from each stratum, subject to rounding).
+         *
+         * <br> Default: 0 (i.e. determine the count by means of sampleProportion())
+         */
+    SamplerOptions& sampleSize(unsigned int size)
+    {
+        sample_size = size;
+        return *this;
+    }
+
+
+        /**\brief Determine the number of samples to draw as a proportion of the total
+         * number. That is, we draw <tt>count = totalCount * proportion</tt> samples. 
+         * This option is overridden when an absolute count is specified by sampleSize().
+         * 
+         * If stratifiedSampling is true, the count is equally distributed
+         * across all strata (e.g. <tt>totalCount * proportion / strataCount</tt> samples are taken 
+         * from each stratum).
+         *
+         * <br> Default: 1.0
+         */
+    SamplerOptions& sampleProportion(double proportion)
+    {
+        vigra_precondition(proportion >= 0.0,
+               "SamplerOptions::sampleProportion(): argument must not be negative.");
+        sample_proportion = proportion;
+        return *this;
+    }
+
+        /**\brief Draw equally many samples from each "stratum". 
+         *  A stratum is a group of like entities, e.g. pixels belonging 
+         *  to the same object class. This is useful to create balanced samples  
+         *  when the class probabilities are very unbalanced (e.g.
+         *  when there are many background and few foreground pixels).
+         *  Stratified sampling thus avoids that a trained classifier is biased 
+         *  towards the majority class. 
+         *
+         * <br> Default (if you don't call this function): false
+         */
+    SamplerOptions& stratified(bool in = true)
+    {
+        stratified_sampling = in;
+        return *this;
+    }
+};
+
+/************************************************************/
+/*                                                          */
+/*                        Sampler                           */
+/*                                                          */
+/************************************************************/
+
+/** \brief Create random samples from a sequence of indices.
+
+    Selecting data items at random is a basic task of machine learning,
+    for example in boostrapping, RandomForest training, and cross validation.
+    This class implements various ways to select random samples via their indices. 
+    Indices are assumed to be consecutive in
+    the range <tt>0 <= index < total_sample_count</tt>.
+    
+    The class always contains a current sample which can be accessed by 
+    the index operator or by the function sampledIndices(). The indices
+    that are not in the current sample (out-of-bag indices) can be accessed
+    via the function oobIndices().
+    
+    The sampling method (with/without replacement, stratified or not) and the
+    number of samples to draw are determined by the option object 
+    SamplerOptions.
+    
+    <b>Usage:</b>
+    
+    <b>\#include</b> \<vigra/sampling.hxx\><br>
+    Namespace: vigra
+    
+    Create a Sampler with default options, i.e. sample as many indices as there 
+    are data elements, with replacement. On average, the sample will contain 
+    <tt>0.63*totalCount</tt> distinct indices.
+    
+    \code
+    int totalCount = 10000;   // total number of data elements
+    int numberOfSamples = 20; // repeat experiment 20 times 
+    Sampler<> sampler(totalCount);
+    for(int k=0; k<numberOfSamples; ++k)
+    {
+        // process current sample
+        for(int i=0; i<sampler.sampleSize(); ++i)
+        {
+            int currentIndex = sampler[i];
+            processData(data[currentIndex]);
+        }
+        // create next sample
+        sampler.sample();
+    }
+    \endcode
+    
+    Create a Sampler for stratified sampling, without replacement.
+    
+    \code
+    // prepare the strata (i.e. specify which stratum each element belongs to)
+    int stratumSize1 = 2000, stratumSize2 = 8000,
+        totalCount = stratumSize1 + stratumSize2;
+    ArrayVerctor<int> strata(totalCount);
+    for(int i=0; i<stratumSize1; ++i)
+        strata[i] = 1;
+    for(int i=stratumSize1; i<stratumSize2; ++i)
+        strata[i] = 2;
+        
+    int sampleSize = 200; // i.e. sample 100 elements from each of the two strata
+    int numberOfSamples = 20; // repeat experiment 20 times 
+    Sampler<> stratifiedSampler(strata.begin(), strata.end(),
+                     SamplerOptions().withoutReplacement().stratified().sampleSize(sampleSize));
+    // create first sample
+    sampler.sample();
+
+    for(int k=0; k<numberOfSamples; ++k)
+    {
+        // process current sample
+        for(int i=0; i<sampler.sampleSize(); ++i)
+        {
+            int currentIndex = sampler[i];
+            processData(data[currentIndex]);
+        }
+        // create next sample
+        sampler.sample();
+    }
+    \endcode
+*/
+template<class Random = MersenneTwister >
+class Sampler
+{
+  public:
+        /** Internal type of the indices.
+            Currently, 64-bit indices are not supported because this
+            requires extension of the random number generator classes.
+        */
+    typedef Int32                               IndexType;
+    
+    typedef ArrayVector<IndexType>              IndexArrayType;
+    
+        /** Type of the array view object that is returned by 
+            sampledIndices() and oobIndices().
+        */
+    typedef ArrayVectorView <IndexType>         IndexArrayViewType;
+
+  private:
+    typedef std::map<IndexType, IndexArrayType> StrataIndicesType;
+    typedef std::map<IndexType, int>            StrataSizesType;
+    typedef ArrayVector<bool>                   IsUsedArrayType;
+    typedef ArrayVectorView<bool>               IsUsedArrayViewType;
+    
+    static const int        oobInvalid = -1;
+
+    int                     total_count_, sample_size_;
+    mutable int             current_oob_count_;
+    StrataIndicesType       strata_indices_;
+    StrataSizesType         strata_sample_size_;
+    IndexArrayType          current_sample_;
+    mutable IndexArrayType  current_oob_sample_;
+    IsUsedArrayType         is_used_;
+    Random                  default_random_;
+    Random const &          random_;
+    SamplerOptions          options_;
+
+    void initStrataCount()
+    {
+        // compute how many samples to take from each stratum
+        // (may be unequal if sample_size_ is not a multiple of strataCount())
+        int strata_sample_size = (int)std::ceil(double(sample_size_) / strataCount());
+        int strata_total_count = strata_sample_size * strataCount();
+
+        for(StrataIndicesType::iterator i = strata_indices_.begin(); 
+             i != strata_indices_.end(); ++i)
+        {
+            if(strata_total_count > sample_size_)
+            {
+                strata_sample_size_[i->first] = strata_sample_size - 1;
+                --strata_total_count;
+            }
+            else
+            {
+                strata_sample_size_[i->first] = strata_sample_size;
+            }
+        }
+    }
+
+  public:
+    
+        /** Create a sampler for \a totalCount data objects.
+            
+            In each invocation of <tt>sample()</tt> below, it will sample
+            indices according to the options passed. If no options are given, 
+            <tt>totalCount</tt> indices will be drawn with replacement.
+        */
+    Sampler(UInt32 totalCount, SamplerOptions const & opt = SamplerOptions(), 
+            Random const * rnd = 0)
+    : total_count_(totalCount),
+      sample_size_(opt.sample_size == 0
+                         ? (int)(std::ceil(total_count_ * opt.sample_proportion))
+                         : opt.sample_size),
+      current_oob_count_(oobInvalid),
+      current_sample_(sample_size_),
+      current_oob_sample_(total_count_),
+      is_used_(total_count_),
+      default_random_(RandomSeed),
+      random_(rnd ? *rnd : default_random_),
+      options_(opt)
+    {
+        vigra_precondition(opt.sample_with_replacement || sample_size_ <= total_count_,
+          "Sampler(): Cannot draw without replacement when data size is smaller than sample count.");
+          
+        vigra_precondition(!opt.stratified_sampling,
+          "Sampler(): Stratified sampling requested, but no strata given.");
+          
+        // initialize a single stratum containing all data
+        strata_indices_[0].resize(total_count_);
+        for(int i=0; i<total_count_; ++i)
+            strata_indices_[0][i] = i;
+
+        initStrataCount();
+        //this is screwing up the random forest tests.
+        //sample();
+    }
+    
+        /** Create a sampler for stratified sampling.
+            
+            <tt>strataBegin</tt> and <tt>strataEnd</tt> must refer to a sequence 
+            which specifies for each sample the stratum it belongs to. The
+            total number of data objects will be set to <tt>strataEnd - strataBegin</tt>.
+            Equally many samples (subject to rounding) will be drawn from each stratum, 
+            unless the option object explicitly requests unstratified sampling, 
+            in which case the strata are ignored.
+        */
+    template <class Iterator>
+    Sampler(Iterator strataBegin, Iterator strataEnd, SamplerOptions const & opt = SamplerOptions(), 
+            Random const * rnd = 0)
+    : total_count_(strataEnd - strataBegin),
+      sample_size_(opt.sample_size == 0
+                         ? (int)(std::ceil(total_count_ * opt.sample_proportion))
+                         : opt.sample_size),
+      current_oob_count_(oobInvalid),
+      current_sample_(sample_size_),
+      current_oob_sample_(total_count_),
+      is_used_(total_count_),
+      default_random_(RandomSeed),
+      random_(rnd ? *rnd : default_random_),
+      options_(opt)
+    {
+        vigra_precondition(opt.sample_with_replacement || sample_size_ <= total_count_,
+          "Sampler(): Cannot draw without replacement when data size is smaller than sample count.");
+          
+        // copy the strata indices
+        if(opt.stratified_sampling)
+        {
+            for(int i = 0; strataBegin != strataEnd; ++i, ++strataBegin)
+            {
+                strata_indices_[*strataBegin].push_back(i);
+            }
+        }
+        else
+        {
+            strata_indices_[0].resize(total_count_);
+            for(int i=0; i<total_count_; ++i)
+                strata_indices_[0][i] = i;
+        }
+            
+        vigra_precondition(sample_size_ >= (int)strata_indices_.size(),
+            "Sampler(): Requested sample count must be at least as large as the number of strata.");
+
+        initStrataCount();
+        //this is screwing up the random forest tests.
+        //sample();
+    }
+
+        /** Return the k-th index in the current sample.
+         */
+    IndexType operator[](int k) const
+    {
+        return current_sample_[k];
+    }
+
+        /** Create a new sample.
+         */
+    void sample();
+
+        /** The total number of data elements.
+         */
+    int totalCount() const
+    {
+        return total_count_;
+    }
+
+        /** The number of data elements that have been sampled.
+         */
+    int sampleSize() const
+    {
+        return sample_size_;
+    }
+
+        /** Same as sampleSize().
+         */
+    int size() const
+    {
+        return sample_size_;
+    }
+
+        /** The number of strata to be used.
+            Will be 1 if no strata are given. Will be ignored when
+            stratifiedSampling() is false.
+         */
+    int strataCount() const
+    {
+        return strata_indices_.size();
+    }
+
+        /** Whether to use stratified sampling.
+            (If this is false, strata will be ignored even if present.)
+         */
+    bool stratifiedSampling() const
+    {
+        return options_.stratified_sampling;
+    }
+    
+        /** Whether sampling should be performed with replacement.
+         */
+    bool withReplacement() const
+    {
+        return options_.sample_with_replacement;
+    }
+    
+        /** Return an array view containing the indices in the current sample.
+         */
+    IndexArrayViewType sampledIndices() const
+    {
+        return current_sample_;
+    }
+    
+        /** Return an array view containing the out-of-bag indices.
+            (i.e. the indices that are not in the current sample)
+         */
+    IndexArrayViewType oobIndices() const
+    {
+        if(current_oob_count_ == oobInvalid)
+        {
+            current_oob_count_ = 0;
+            for(int i = 0; i<total_count_; ++i)
+            {
+                if(!is_used_[i])
+                {
+                    current_oob_sample_[current_oob_count_] = i;
+                    ++current_oob_count_;
+                }
+            }
+        }
+        return current_oob_sample_.subarray(0, current_oob_count_);
+    }
+    IsUsedArrayType const & is_used() const
+    {
+        return is_used_;
+    }
+};
+
+
+template<class Random>
+void Sampler<Random>::sample()
+{
+    current_oob_count_ = oobInvalid;
+    is_used_.init(false);
+    
+    if(options_.sample_with_replacement)
+    {
+        //Go thru all strata
+        int j = 0;
+        StrataIndicesType::iterator iter;
+        for(iter = strata_indices_.begin(); iter != strata_indices_.end(); ++iter)
+        {
+            // do sampling with replacement in each strata and copy data.
+            int stratum_size = iter->second.size();
+            for(int i = 0; i < (int)strata_sample_size_[iter->first]; ++i, ++j)
+            {
+                current_sample_[j] = iter->second[random_.uniformInt(stratum_size)];
+                is_used_[current_sample_[j]] = true;
+            }
+        }
+    }
+    else
+    {
+        //Go thru all strata
+        int j = 0;
+        StrataIndicesType::iterator iter;
+        for(iter = strata_indices_.begin(); iter != strata_indices_.end(); ++iter)
+        {
+            // do sampling without replacement in each strata and copy data.
+            int stratum_size = iter->second.size();
+            for(int i = 0; i < (int)strata_sample_size_[iter->first]; ++i, ++j)
+            {
+                std::swap(iter->second[i], iter->second[i+ random_.uniformInt(stratum_size - i)]);
+                current_sample_[j] = iter->second[i];
+                is_used_[current_sample_[j]] = true;
+            }
+        }
+    }
+}
+
+template<class Random =RandomTT800 >
+class PoissonSampler
+{
+public:
+    Random  randfloat;
+    typedef Int32                               IndexType;
+    typedef vigra::ArrayVector     <IndexType>  IndexArrayType;
+    IndexArrayType        used_indices_;
+    double lambda;
+    int minIndex;
+    int maxIndex;
+    
+    PoissonSampler(double lambda,IndexType minIndex,IndexType maxIndex)
+    : lambda(lambda),
+      minIndex(minIndex),
+      maxIndex(maxIndex)
+    {}
+
+    void sample(  )
+    {
+        used_indices_.clear();
+        IndexType i;
+        for(i=minIndex;i<maxIndex;++i)
+        {
+            //from http://en.wikipedia.org/wiki/Poisson_distribution
+            int k=0;
+            double p=1;
+            double L=exp(-lambda);
+            do
+            {
+                ++k;
+                p*=randfloat.uniform53();
+
+            }while(p>L);
+            --k;
+            //Insert i this many time
+            while(k>0)
+            {
+                used_indices_.push_back(i);
+                --k;
+            }
+        }
+    }
+
+    IndexType const & operator[](int in) const
+    {
+        return used_indices_[in];
+    }
+    
+    int numOfSamples() const
+    {
+        return used_indices_.size();
+    }
+};
+
+//@}
+
+} // namespace vigra
+
+#endif /*VIGRA_SAMPLING_HXX*/
diff --git a/include/vigra/seededregiongrowing.hxx b/include/vigra/seededregiongrowing.hxx
new file mode 100644
index 0000000..a0dcd4a
--- /dev/null
+++ b/include/vigra/seededregiongrowing.hxx
@@ -0,0 +1,1000 @@
+/************************************************************************/
+/*                                                                      */
+/*         Copyright 1998-2010 by Ullrich Koethe, Hans Meine            */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_SEEDEDREGIONGROWING_HXX
+#define VIGRA_SEEDEDREGIONGROWING_HXX
+
+#include <vector>
+#include <stack>
+#include <queue>
+#include "utilities.hxx"
+#include "stdimage.hxx"
+#include "stdimagefunctions.hxx"
+#include "pixelneighborhood.hxx"
+#include "bucket_queue.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+namespace detail {
+
+template <class COST>
+class SeedRgPixel
+{
+public:
+    Point2D location_, nearest_;
+    COST cost_;
+    int count_;
+    int label_;
+    int dist_;
+
+    SeedRgPixel()
+    : location_(0,0), nearest_(0,0), cost_(0), count_(0), label_(0)
+    {}
+
+    SeedRgPixel(Point2D const & location, Point2D const & nearest,
+                COST const & cost, int const & count, int const & label)
+    : location_(location), nearest_(nearest),
+      cost_(cost), count_(count), label_(label)
+    {
+        int dx = location_.x - nearest_.x;
+        int dy = location_.y - nearest_.y;
+        dist_ = dx * dx + dy * dy;
+    }
+
+    void set(Point2D const & location, Point2D const & nearest,
+             COST const & cost, int const & count, int const & label)
+    {
+        location_ = location;
+        nearest_ = nearest;
+        cost_ = cost;
+        count_ = count;
+        label_ = label;
+
+        int dx = location_.x - nearest_.x;
+        int dy = location_.y - nearest_.y;
+        dist_ = dx * dx + dy * dy;
+    }
+
+    struct Compare
+    {
+        // must implement > since priority_queue looks for largest element
+        bool operator()(SeedRgPixel const & l,
+                        SeedRgPixel const & r) const
+        {
+            if(r.cost_ == l.cost_)
+            {
+                if(r.dist_ == l.dist_) return r.count_ < l.count_;
+
+                return r.dist_ < l.dist_;
+            }
+
+            return r.cost_ < l.cost_;
+        }
+        bool operator()(SeedRgPixel const * l,
+                        SeedRgPixel const * r) const
+        {
+            if(r->cost_ == l->cost_)
+            {
+                if(r->dist_ == l->dist_) return r->count_ < l->count_;
+
+                return r->dist_ < l->dist_;
+            }
+
+            return r->cost_ < l->cost_;
+        }
+    };
+
+    struct Allocator
+    {
+        ~Allocator()
+        {
+            while(!freelist_.empty())
+            {
+                delete freelist_.top();
+                freelist_.pop();
+            }
+        }
+
+        SeedRgPixel *
+        create(Point2D const & location, Point2D const & nearest,
+               COST const & cost, int const & count, int const & label)
+        {
+            if(!freelist_.empty())
+            {
+                SeedRgPixel * res = freelist_.top();
+                freelist_.pop();
+                res->set(location, nearest, cost, count, label);
+                return res;
+            }
+
+            return new SeedRgPixel(location, nearest, cost, count, label);
+        }
+
+        void dismiss(SeedRgPixel * p)
+        {
+            freelist_.push(p);
+        }
+
+        std::stack<SeedRgPixel<COST> *> freelist_;
+    };
+};
+
+struct UnlabelWatersheds
+{
+    int operator()(int label) const
+    {
+        return label < 0 ? 0 : label;
+    }
+};
+
+} // namespace detail
+
+/** \addtogroup SeededRegionGrowing Region Segmentation Algorithms
+    Region growing, watersheds, and voronoi tesselation
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                    seededRegionGrowing               */
+/*                                                      */
+/********************************************************/
+
+/** Choose between different types of Region Growing */
+enum SRGType { 
+    CompleteGrow = 0, 
+    KeepContours = 1, 
+    StopAtThreshold = 2, 
+    SRGWatershedLabel = -1 
+};
+
+/** \brief Region Segmentation by means of Seeded Region Growing.
+
+    This algorithm implements seeded region growing as described in
+
+    R. Adams, L. Bischof: <em>"Seeded Region Growing"</em>, IEEE Trans. on Pattern
+    Analysis and Maschine Intelligence, vol 16, no 6, 1994, and
+
+    Ullrich Köthe:
+    <em><a href="http://hci.iwr.uni-heidelberg.de/people/ukoethe/papers/index.php#cite_primary_segmentation">Primary Image Segmentation</a></em>,
+    in: G. Sagerer, S.
+    Posch, F. Kummert (eds.): Mustererkennung 1995, Proc. 17. DAGM-Symposium,
+    Springer 1995
+
+    The seed image is a partly segmented image which contains uniquely
+    labeled regions (the seeds) and unlabeled pixels (the candidates, label 0).
+    The highest seed label found in the seed image is returned by the algorithm.
+    
+    Seed regions can be as large as you wish and as small as one pixel. If
+    there are no candidates, the algorithm will simply copy the seed image
+    into the output image. Otherwise it will aggregate the candidates into
+    the existing regions so that a cost function is minimized. 
+    Candidates are taken from the neighborhood of the already assigned pixels, 
+    where the type of neighborhood is determined by parameter <tt>neighborhood</tt>
+    which can take the values <tt>FourNeighborCode()</tt> (the default) 
+    or <tt>EightNeighborCode()</tt>. The algorithm basically works as follows 
+    (illustrated for 4-neighborhood, but 8-neighborhood works in the same way):
+
+    <ol>
+
+    <li> Find all candidate pixels that are 4-adjacent to a seed region.
+    Calculate the cost for aggregating each candidate into its adjacent region
+    and put the candidates into a priority queue.
+
+    <li> While( priority queue is not empty and termination criterion is not fulfilled)
+
+        <ol>
+
+        <li> Take the candidate with least cost from the queue. If it has not
+        already been merged, merge it with it's adjacent region.
+
+        <li> Put all candidates that are 4-adjacent to the pixel just processed
+        into the priority queue.
+
+        </ol>
+
+    </ol>
+
+    <tt>SRGType</tt> can take the following values:
+    
+    <DL>
+    <DT><tt>CompleteGrow</tt> <DD> produce a complete tesselation of the volume (default).
+    <DT><tt>KeepContours</tt> <DD> keep a 1-voxel wide unlabeled contour between all regions.
+    <DT><tt>StopAtThreshold</tt> <DD> stop when the boundary indicator values exceed the 
+                             threshold given by parameter <tt>max_cost</tt>.
+    <DT><tt>KeepContours | StopAtThreshold</tt> <DD> keep 1-voxel wide contour and stop at given <tt>max_cost</tt>.
+    </DL>
+
+    The cost is determined jointly by the source image and the
+    region statistics functor. The source image contains feature values for each
+    pixel which will be used by the region statistics functor to calculate and
+    update statistics for each region and to calculate the cost for each
+    candidate. The <TT>RegionStatisticsArray</TT> must be compatible to the
+    \ref ArrayOfRegionStatistics functor and contains an <em> array</em> of
+    statistics objects for each region. The indices must correspond to the
+    labels of the seed regions. The statistics for the initial regions must have
+    been calculated prior to calling <TT>seededRegionGrowing()</TT> (for example by
+    means of \ref inspectTwoImagesIf()).
+
+    For each candidate
+    <TT>x</TT> that is adjacent to region <TT>i</TT>, the algorithm will call
+    <TT>stats[i].cost(as(x))</TT> to get the cost (where <TT>x</TT> is a <TT>SrcIterator</TT>
+    and <TT>as</TT> is
+    the SrcAccessor). When a candidate has been merged with a region, the
+    statistics are updated by calling <TT>stats[i].operator()(as(x))</TT>. Since
+    the <TT>RegionStatisticsArray</TT> is passed by reference, this will overwrite
+    the original statistics.
+
+    If a candidate could be merged into more than one regions with identical
+    cost, the algorithm will favour the nearest region. If <tt>StopAtThreshold</tt> is active, 
+    and the cost of the current candidate at any point in the algorithm exceeds the optional 
+    <tt>max_cost</tt> value (which defaults to <tt>NumericTraits<double>::max()</tt>), 
+    region growing is aborted, and all voxels not yet assigned to a region remain unlabeled.
+
+    In some cases, the cost only depends on the feature value of the current
+    pixel. Then the update operation will simply be a no-op, and the <TT>cost()</TT>
+    function returns its argument. This behavior is implemented by the
+    \ref SeedRgDirectValueFunctor. With <tt>SRGType == KeepContours</tt>,
+    this is equivalent to the watershed algorithm.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class TS, class AS,
+                  class T2, class S2,
+                  class RegionStatisticsArray, class Neighborhood>
+        TS
+        seededRegionGrowing(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, TS, AS> const & seeds,
+                            MultiArrayView<2, T2, S2>         labels,
+                            RegionStatisticsArray &           stats,
+                            SRGType                           srgType = CompleteGrow, 
+                            Neighborhood                      n = FourNeighborCode(),
+                            double                            max_cost = NumericTraits<double>::max());
+    }
+    \endcode
+
+    \deprecatedAPI{seededRegionGrowing}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class SeedImageIterator, class SeedAccessor,
+                  class DestIterator, class DestAccessor,
+                  class RegionStatisticsArray, class Neighborhood>
+        typename SeedAccessor::value_type 
+        seededRegionGrowing(SrcIterator srcul, SrcIterator srclr, SrcAccessor as,
+                            SeedImageIterator seedsul, SeedAccessor aseeds,
+                            DestIterator destul, DestAccessor ad,
+                            RegionStatisticsArray & stats,
+                            SRGType srgType = CompleteGrow,
+                            Neighborhood neighborhood = FourNeighborCode(),
+                            double max_cost = NumericTraits<double>::max());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class SeedImageIterator, class SeedAccessor,
+                  class DestIterator, class DestAccessor,
+                  class RegionStatisticsArray, class Neighborhood>
+        typename SeedAccessor::value_type
+        seededRegionGrowing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<SeedImageIterator, SeedAccessor> seeds,
+                            pair<DestIterator, DestAccessor> dest,
+                            RegionStatisticsArray & stats,
+                            SRGType srgType = CompleteGrow,
+                            Neighborhood neighborhood = FourNeighborCode(),
+                            double max_cost = NumericTraits<double>::max());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/seededregiongrowing.hxx\><br>
+    Namespace: vigra
+
+    Example: implementation of the voronoi tesselation
+
+    \code
+    MultiArray<2, int>      points(w,h);
+    MultiArray<2, float>    dist(x,y);
+
+    int max_region_label = 100;
+
+    // throw in some random points:
+    for(int i = 1; i <= max_region_label; ++i)
+           points(w * rand() / RAND_MAX , h * rand() / RAND_MAX) = i;
+
+    // calculate Euclidean distance transform
+    distanceTransform(points, dist, 2);
+
+    // init statistics functor
+    ArrayOfRegionStatistics<SeedRgDirectValueFunctor<float> >  stats(max_region_label);
+
+    // find voronoi region of each point (the point image is overwritten with the 
+    // voronoi region labels)
+    seededRegionGrowing(dist, points, points, stats);
+    \endcode
+
+    \deprecatedUsage{seededRegionGrowing}
+    \code
+    vigra::BImage points(w,h);
+    vigra::FImage dist(x,y);
+
+    // empty edge image
+    points = 0;
+    dist = 0;
+
+    int max_region_label = 100;
+
+    // throw in some random points:
+    for(int i = 1; i <= max_region_label; ++i)
+           points(w * rand() / RAND_MAX , h * rand() / RAND_MAX) = i;
+
+    // calculate Euclidean distance transform
+    vigra::distanceTransform(srcImageRange(points), destImage(dist), 2);
+
+    // init statistics functor
+    vigra::ArrayOfRegionStatistics<vigra::SeedRgDirectValueFunctor<float> >
+                                              stats(max_region_label);
+
+    // find voronoi region of each point
+    vigra:: seededRegionGrowing(srcImageRange(dist), srcImage(points),
+                               destImage(points), stats);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator src_upperleft, src_lowerright;
+    SeedImageIterator seed_upperleft;
+    DestIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    SeedAccessor seed_accessor;
+    DestAccessor dest_accessor;
+
+    RegionStatisticsArray stats;
+
+    // calculate costs
+    RegionStatisticsArray::value_type::cost_type cost =
+        stats[seed_accessor(seed_upperleft)].cost(src_accessor(src_upperleft));
+
+    // compare costs
+    cost < cost;
+
+    // update statistics
+    stats[seed_accessor(seed_upperleft)](src_accessor(src_upperleft));
+
+    // set result
+    dest_accessor.set(seed_accessor(seed_upperleft), dest_upperleft);
+    \endcode
+    \deprecatedEnd
+
+    Further requirements are determined by the <TT>RegionStatisticsArray</TT>.
+*/
+doxygen_overloaded_function(template <...> void seededRegionGrowing)
+
+template <class SrcIterator, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray, class Neighborhood>
+typename SeedAccessor::value_type
+seededRegionGrowing(SrcIterator srcul,
+                    SrcIterator srclr, SrcAccessor as,
+                    SeedImageIterator seedsul, SeedAccessor aseeds,
+                    DestIterator destul, DestAccessor ad,
+                    RegionStatisticsArray & stats,
+                    SRGType srgType,
+                    Neighborhood,
+                    double max_cost)
+{
+    int w = srclr.x - srcul.x;
+    int h = srclr.y - srcul.y;
+    int count = 0;
+
+    SrcIterator isy = srcul, isx = srcul;  // iterators for the src image
+
+    typedef typename SeedAccessor::value_type LabelType;
+    typedef typename RegionStatisticsArray::value_type RegionStatistics;
+    typedef typename RegionStatistics::cost_type CostType;
+    typedef detail::SeedRgPixel<CostType> Pixel;
+
+    typename Pixel::Allocator allocator;
+
+    typedef std::priority_queue<Pixel *, std::vector<Pixel *>,
+                                typename Pixel::Compare>  SeedRgPixelHeap;
+
+    // copy seed image in an image with border
+    IImage regions(w+2, h+2);
+    IImage::Iterator ir = regions.upperLeft() + Diff2D(1,1);
+    IImage::Iterator iry, irx;
+
+    initImageBorder(destImageRange(regions), 1, SRGWatershedLabel);
+    copyImage(seedsul, seedsul+Diff2D(w,h), aseeds, ir, regions.accessor());
+
+    // allocate and init memory for the results
+
+    SeedRgPixelHeap pheap;
+    int cneighbor, maxRegionLabel = 0;
+    
+    typedef typename Neighborhood::Direction Direction;
+    int directionCount = Neighborhood::DirectionCount;
+    
+    Point2D pos(0,0);
+    for(isy=srcul, iry=ir, pos.y=0; pos.y<h;
+        ++pos.y, ++isy.y, ++iry.y)
+    {
+        for(isx=isy, irx=iry, pos.x=0; pos.x<w;
+            ++pos.x, ++isx.x, ++irx.x)
+        {
+            if(*irx == 0)
+            {
+                // find candidate pixels for growing and fill heap
+                for(int i=0; i<directionCount; i++)
+                {
+                    // cneighbor = irx[dist[i]];
+                    cneighbor = irx[Neighborhood::diff((Direction)i)];
+                    if(cneighbor > 0)
+                    {
+                        CostType cost = stats[cneighbor].cost(as(isx));
+
+                        Pixel * pixel =
+                            allocator.create(pos, pos+Neighborhood::diff((Direction)i), cost, count++, cneighbor);
+                        pheap.push(pixel);
+                    }
+                }
+            }
+            else
+            {
+                vigra_precondition((LabelType)*irx <= stats.maxRegionLabel(),
+                    "seededRegionGrowing(): Largest label exceeds size of RegionStatisticsArray.");
+                if(maxRegionLabel < *irx)
+                    maxRegionLabel = *irx;
+            }
+        }
+    }
+    
+    // perform region growing
+    while(pheap.size() != 0)
+    {
+        Pixel * pixel = pheap.top();
+        pheap.pop();
+
+        Point2D pos = pixel->location_;
+        Point2D nearest = pixel->nearest_;
+        int lab = pixel->label_;
+        CostType cost = pixel->cost_;
+
+        allocator.dismiss(pixel);
+
+        if((srgType & StopAtThreshold) != 0 && cost > max_cost)
+            break;
+
+        irx = ir + pos;
+        isx = srcul + pos;
+
+        if(*irx) // already labelled region / watershed?
+            continue;
+
+        if((srgType & KeepContours) != 0)
+        {
+            for(int i=0; i<directionCount; i++)
+            {
+                cneighbor = irx[Neighborhood::diff((Direction)i)];
+                if((cneighbor>0) && (cneighbor != lab))
+                {
+                    lab = SRGWatershedLabel;
+                    break;
+                }
+            }
+        }
+
+        *irx = lab;
+
+        if((srgType & KeepContours) == 0 || lab > 0)
+        {
+            // update statistics
+            stats[*irx](as(isx));
+
+            // search neighborhood
+            // second pass: find new candidate pixels
+            for(int i=0; i<directionCount; i++)
+            {
+                if(irx[Neighborhood::diff((Direction)i)] == 0)
+                {
+                    CostType cost = stats[lab].cost(as(isx, Neighborhood::diff((Direction)i)));
+
+                    Pixel * new_pixel =
+                        allocator.create(pos+Neighborhood::diff((Direction)i), nearest, cost, count++, lab);
+                    pheap.push(new_pixel);
+                }
+            }
+        }
+    }
+    
+    // free temporary memory
+    while(pheap.size() != 0)
+    {
+        allocator.dismiss(pheap.top());
+        pheap.pop();
+    }
+
+    // write result
+    transformImage(ir, ir+Point2D(w,h), regions.accessor(), destul, ad,
+                   detail::UnlabelWatersheds());
+
+    return (LabelType)maxRegionLabel;
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray, class Neighborhood>
+inline typename SeedAccessor::value_type
+seededRegionGrowing(SrcIterator srcul,
+                    SrcIterator srclr, SrcAccessor as,
+                    SeedImageIterator seedsul, SeedAccessor aseeds,
+                    DestIterator destul, DestAccessor ad,
+                    RegionStatisticsArray & stats,
+                    SRGType srgType,
+                    Neighborhood n)
+{
+    return seededRegionGrowing(srcul, srclr, as,
+                                seedsul, aseeds,
+                                destul, ad,
+                                stats, srgType, n, NumericTraits<double>::max());
+}
+
+
+
+template <class SrcIterator, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray>
+inline typename SeedAccessor::value_type
+seededRegionGrowing(SrcIterator srcul,
+                    SrcIterator srclr, SrcAccessor as,
+                    SeedImageIterator seedsul, SeedAccessor aseeds,
+                    DestIterator destul, DestAccessor ad,
+                    RegionStatisticsArray & stats,
+                    SRGType srgType)
+{
+    return seededRegionGrowing(srcul, srclr, as,
+                                seedsul, aseeds,
+                                destul, ad,
+                                stats, srgType, FourNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray>
+inline typename SeedAccessor::value_type
+seededRegionGrowing(SrcIterator srcul,
+                    SrcIterator srclr, SrcAccessor as,
+                    SeedImageIterator seedsul, SeedAccessor aseeds,
+                    DestIterator destul, DestAccessor ad,
+                    RegionStatisticsArray & stats)
+{
+    return seededRegionGrowing(srcul, srclr, as,
+                                seedsul, aseeds,
+                                destul, ad,
+                                stats, CompleteGrow);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray, class Neighborhood>
+inline typename SeedAccessor::value_type
+seededRegionGrowing(triple<SrcIterator, SrcIterator, SrcAccessor> img1,
+                    pair<SeedImageIterator, SeedAccessor> img3,
+                    pair<DestIterator, DestAccessor> img4,
+                    RegionStatisticsArray & stats,
+                    SRGType srgType, 
+                    Neighborhood n,
+                    double max_cost = NumericTraits<double>::max())
+{
+    return seededRegionGrowing(img1.first, img1.second, img1.third,
+                                img3.first, img3.second,
+                                img4.first, img4.second,
+                                stats, srgType, n, max_cost);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray>
+inline typename SeedAccessor::value_type
+seededRegionGrowing(triple<SrcIterator, SrcIterator, SrcAccessor> img1,
+                    pair<SeedImageIterator, SeedAccessor> img3,
+                    pair<DestIterator, DestAccessor> img4,
+                    RegionStatisticsArray & stats,
+                    SRGType srgType)
+{
+    return seededRegionGrowing(img1.first, img1.second, img1.third,
+                                img3.first, img3.second,
+                                img4.first, img4.second,
+                                stats, srgType, FourNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray>
+inline typename SeedAccessor::value_type
+seededRegionGrowing(triple<SrcIterator, SrcIterator, SrcAccessor> img1,
+                    pair<SeedImageIterator, SeedAccessor> img3,
+                    pair<DestIterator, DestAccessor> img4,
+                    RegionStatisticsArray & stats)
+{
+    return seededRegionGrowing(img1.first, img1.second, img1.third,
+                            img3.first, img3.second,
+                            img4.first, img4.second,
+                            stats, CompleteGrow);
+}
+
+template <class T1, class S1,
+          class TS, class AS,
+          class T2, class S2,
+          class RegionStatisticsArray, class Neighborhood>
+inline TS
+seededRegionGrowing(MultiArrayView<2, T1, S1> const & img1,
+                    MultiArrayView<2, TS, AS> const & img3,
+                    MultiArrayView<2, T2, S2> img4,
+                    RegionStatisticsArray & stats,
+                    SRGType srgType, 
+                    Neighborhood n,
+                    double max_cost = NumericTraits<double>::max())
+{
+    vigra_precondition(img1.shape() == img3.shape(),
+        "seededRegionGrowing(): shape mismatch between input and output.");
+    return seededRegionGrowing(srcImageRange(img1),
+                               srcImage(img3),
+                               destImage(img4),
+                               stats, srgType, n, max_cost);
+}
+
+template <class T1, class S1,
+          class TS, class AS,
+          class T2, class S2,
+          class RegionStatisticsArray>
+inline TS
+seededRegionGrowing(MultiArrayView<2, T1, S1> const & img1,
+                    MultiArrayView<2, TS, AS> const & img3,
+                    MultiArrayView<2, T2, S2> img4,
+                    RegionStatisticsArray & stats,
+                    SRGType srgType)
+{
+    vigra_precondition(img1.shape() == img3.shape(),
+        "seededRegionGrowing(): shape mismatch between input and output.");
+    return seededRegionGrowing(srcImageRange(img1),
+                               srcImage(img3),
+                               destImage(img4),
+                               stats, srgType, FourNeighborCode());
+}
+
+template <class T1, class S1,
+          class TS, class AS,
+          class T2, class S2,
+          class RegionStatisticsArray>
+inline TS
+seededRegionGrowing(MultiArrayView<2, T1, S1> const & img1,
+                    MultiArrayView<2, TS, AS> const & img3,
+                    MultiArrayView<2, T2, S2> img4,
+                    RegionStatisticsArray & stats)
+{
+    vigra_precondition(img1.shape() == img3.shape(),
+        "seededRegionGrowing(): shape mismatch between input and output.");
+    return seededRegionGrowing(srcImageRange(img1),
+                               srcImage(img3),
+                               destImage(img4),
+                               stats, CompleteGrow);
+}
+
+/********************************************************/
+/*                                                      */
+/*                fastSeededRegionGrowing               */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray, class Neighborhood>
+typename DestAccessor::value_type 
+fastSeededRegionGrowing(SrcIterator srcul, SrcIterator srclr, SrcAccessor as,
+                        DestIterator destul, DestAccessor ad,
+                        RegionStatisticsArray & stats,
+                        SRGType srgType,
+                        Neighborhood,
+                        double max_cost,
+                        std::ptrdiff_t bucket_count = 256)
+{
+    typedef typename DestAccessor::value_type LabelType;
+
+    vigra_precondition((srgType & KeepContours) == 0,
+       "fastSeededRegionGrowing(): the turbo algorithm doesn't support 'KeepContours', sorry.");
+    
+    int w = srclr.x - srcul.x;
+    int h = srclr.y - srcul.y;
+
+    SrcIterator isy = srcul, isx = srcul;  // iterators for the src image
+    DestIterator idy = destul, idx = destul;  // iterators for the dest image
+
+    BucketQueue<Point2D, true> pqueue(bucket_count);
+    LabelType maxRegionLabel = 0;
+    
+    Point2D pos(0,0);
+    for(isy=srcul, idy = destul, pos.y=0; pos.y<h; ++pos.y, ++isy.y, ++idy.y)
+    {
+        for(isx=isy, idx=idy, pos.x=0; pos.x<w; ++pos.x, ++isx.x, ++idx.x)
+        {
+            LabelType label = ad(idx);
+            if(label != 0)
+            {
+                vigra_precondition(label <= stats.maxRegionLabel(),
+                    "fastSeededRegionGrowing(): Largest label exceeds size of RegionStatisticsArray.");
+
+                if(maxRegionLabel < label)
+                    maxRegionLabel = label;
+                
+                AtImageBorder atBorder = isAtImageBorder(pos.x, pos.y, w, h);
+                if(atBorder == NotAtBorder)
+                {
+                    NeighborhoodCirculator<DestIterator, Neighborhood> c(idx), cend(c);
+                    do
+                    {
+                        if(ad(c) == 0)
+                        {
+                            std::ptrdiff_t priority = (std::ptrdiff_t)stats[label].cost(as(isx));
+                            pqueue.push(pos, priority);
+                            break;
+                        }
+                    }
+                    while(++c != cend);
+                }
+                else
+                {
+                    RestrictedNeighborhoodCirculator<DestIterator, Neighborhood> 
+                                                            c(idx, atBorder), cend(c);
+                    do
+                    {
+                        if(ad(c) == 0)
+                        {
+                            std::ptrdiff_t priority = (std::ptrdiff_t)stats[label].cost(as(isx));
+                            pqueue.push(pos, priority);
+                            break;
+                        }
+                    }
+                    while(++c != cend);
+                }
+            }
+        }
+    }
+    
+    // perform region growing
+    while(!pqueue.empty())
+    {
+        Point2D pos = pqueue.top();
+        std::ptrdiff_t cost = pqueue.topPriority();
+        pqueue.pop();
+        
+        if((srgType & StopAtThreshold) != 0 && cost > max_cost)
+            break;
+
+        idx = destul + pos;
+        isx = srcul + pos;
+        
+        std::ptrdiff_t label = ad(idx);
+
+        AtImageBorder atBorder = isAtImageBorder(pos.x, pos.y, w, h);
+        if(atBorder == NotAtBorder)
+        {
+            NeighborhoodCirculator<DestIterator, Neighborhood> c(idx), cend(c);
+            
+            do
+            {
+                std::ptrdiff_t nlabel = ad(c);
+                if(nlabel == 0)
+                {
+                    ad.set(label, idx, c.diff());
+                    std::ptrdiff_t priority = 
+                           std::max((std::ptrdiff_t)stats[label].cost(as(isx, c.diff())), cost);
+                    pqueue.push(pos+c.diff(), priority);
+                }
+            }
+            while(++c != cend);
+        }
+        else
+        {
+            RestrictedNeighborhoodCirculator<DestIterator, Neighborhood> 
+                                                    c(idx, atBorder), cend(c);
+            do
+            {
+                std::ptrdiff_t nlabel = ad(c);
+                if(nlabel == 0)
+                {
+                    ad.set(label, idx, c.diff());
+                    std::ptrdiff_t priority = 
+                           std::max((std::ptrdiff_t)stats[label].cost(as(isx, c.diff())), cost);
+                    pqueue.push(pos+c.diff(), priority);
+                }
+            }
+            while(++c != cend);
+        }
+    }
+    
+    return maxRegionLabel;
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray, class Neighborhood>
+inline typename DestAccessor::value_type 
+fastSeededRegionGrowing(SrcIterator srcul, SrcIterator srclr, SrcAccessor as,
+                        DestIterator destul, DestAccessor ad,
+                        RegionStatisticsArray & stats,
+                        SRGType srgType,
+                        Neighborhood n)
+{
+    return fastSeededRegionGrowing(srcul, srclr, as,
+                                    destul, ad,
+                                    stats, srgType, n, NumericTraits<double>::max(), 256);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray>
+inline typename DestAccessor::value_type 
+fastSeededRegionGrowing(SrcIterator srcul, SrcIterator srclr, SrcAccessor as,
+                        DestIterator destul, DestAccessor ad,
+                        RegionStatisticsArray & stats,
+                        SRGType srgType)
+{
+    return fastSeededRegionGrowing(srcul, srclr, as,
+                                    destul, ad,
+                                    stats, srgType, FourNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray>
+inline typename DestAccessor::value_type 
+fastSeededRegionGrowing(SrcIterator srcul, SrcIterator srclr, SrcAccessor as,
+                        DestIterator destul, DestAccessor ad,
+                        RegionStatisticsArray & stats)
+{
+    return fastSeededRegionGrowing(srcul, srclr, as,
+                                    destul, ad,
+                                    stats, CompleteGrow);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class RegionStatisticsArray, class Neighborhood>
+inline typename DestAccessor::value_type 
+fastSeededRegionGrowing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        pair<DestIterator, DestAccessor> dest,
+                        RegionStatisticsArray & stats,
+                        SRGType srgType, 
+                        Neighborhood n,
+                        double max_cost,
+                        std::ptrdiff_t bucket_count = 256)
+{
+    return fastSeededRegionGrowing(src.first, src.second, src.third,
+                                   dest.first, dest.second,
+                                   stats, srgType, n, max_cost, bucket_count);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class RegionStatisticsArray, class Neighborhood>
+inline T2
+fastSeededRegionGrowing(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, T2, S2> dest,
+                        RegionStatisticsArray & stats,
+                        SRGType srgType, 
+                        Neighborhood n,
+                        double max_cost,
+                        std::ptrdiff_t bucket_count = 256)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "fastSeededRegionGrowing(): shape mismatch between input and output.");
+    return fastSeededRegionGrowing(srcImageRange(src),
+                                   destImage(dest),
+                                   stats, srgType, n, max_cost, bucket_count);
+}
+
+/********************************************************/
+/*                                                      */
+/*               SeedRgDirectValueFunctor               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Statistics functor to be used for seeded region growing.
+
+    This functor can be used if the cost of a candidate during
+    \ref seededRegionGrowing() is equal to the feature value of that
+    candidate and does not depend on properties of the region it is going to
+    be merged with.
+
+    <b>\#include</b> \<vigra/seededregiongrowing.hxx\><br>
+    Namespace: vigra
+*/
+template <class Value>
+class SeedRgDirectValueFunctor
+{
+  public:
+        /** the functor's argument type
+        */
+    typedef Value argument_type;
+
+        /** the functor's result type (unused, only necessary for
+            use of SeedRgDirectValueFunctor in \ref vigra::ArrayOfRegionStatistics
+        */
+    typedef Value result_type;
+
+        /** \deprecated use argument_type
+        */
+    typedef Value value_type;
+
+        /** the return type of the cost() function
+        */
+    typedef Value cost_type;
+
+        /** Do nothing (since we need not update region statistics).
+        */
+    void operator()(argument_type const &) const {}
+
+        /** Return argument (since cost is identical to feature value)
+        */
+    cost_type const & cost(argument_type const & v) const
+    {
+        return v;
+    }
+};
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_SEEDEDREGIONGROWING_HXX
+
diff --git a/include/vigra/seededregiongrowing3d.hxx b/include/vigra/seededregiongrowing3d.hxx
new file mode 100644
index 0000000..a52e4df
--- /dev/null
+++ b/include/vigra/seededregiongrowing3d.hxx
@@ -0,0 +1,668 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2003-2007 by Kasim Terzic, Christian-Dennis Rahn       */
+/*                        and Ullrich Koethe                            */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_SEEDEDREGIONGROWING_3D_HXX
+#define VIGRA_SEEDEDREGIONGROWING_3D_HXX
+
+#include <vector>
+#include <stack>
+#include <queue>
+#include "utilities.hxx"
+#include "stdimage.hxx"
+#include "stdimagefunctions.hxx"
+#include "seededregiongrowing.hxx"
+#include "multi_shape.hxx"
+#include "multi_pointoperators.hxx"
+#include "voxelneighborhood.hxx"
+
+namespace vigra {
+
+namespace detail {
+
+template <class COST, class Diff_type>
+class SeedRgVoxel
+{
+public:
+    Diff_type location_, nearest_;
+    COST cost_;
+    int count_;
+    int label_;
+    int dist_;
+
+    SeedRgVoxel()
+    //: location_(0,0,0), nearest_(0,0,0), cost_(0), count_(0), label_(0)
+    {
+        location_ = Diff_type(0,0,0);
+        nearest_ = Diff_type(0,0,0);
+        cost_ = 0;
+        count_ = 0;
+        label_ = 0;
+    }
+
+    SeedRgVoxel(Diff_type const & location, Diff_type const & nearest,
+                COST const & cost, int const & count, int const & label)
+    : location_(location), nearest_(nearest),
+      cost_(cost), count_(count), label_(label)
+    {
+        int dx = location_[0] - nearest_[0];
+        int dy = location_[1] - nearest_[1];
+        int dz = location_[2] - nearest_[2];
+        dist_ = dx * dx + dy * dy + dz * dz;
+    }
+
+    void set(Diff_type const & location, Diff_type const & nearest,
+             COST const & cost, int const & count, int const & label)
+    {
+        location_ = location;
+        nearest_ = nearest;
+        cost_ = cost;
+        count_ = count;
+        label_ = label;
+
+        int dx = location_[0] - nearest_[0];
+        int dy = location_[1] - nearest_[1];
+        int dz = location_[2] - nearest_[2];
+        dist_ = dx * dx + dy * dy + dz * dz;
+    }
+
+    struct Compare
+    {
+        // must implement > since priority_queue looks for largest element
+        bool operator()(SeedRgVoxel const & l,
+                        SeedRgVoxel const & r) const
+        {
+            if(r.cost_ == l.cost_)
+            {
+                if(r.dist_ == l.dist_) return r.count_ < l.count_;
+
+                return r.dist_ < l.dist_;
+            }
+
+            return r.cost_ < l.cost_;
+        }
+        bool operator()(SeedRgVoxel const * l,
+                        SeedRgVoxel const * r) const
+        {
+            if(r->cost_ == l->cost_)
+            {
+                if(r->dist_ == l->dist_) return r->count_ < l->count_;
+
+                return r->dist_ < l->dist_;
+            }
+
+            return r->cost_ < l->cost_;
+        }
+    };
+
+    struct Allocator
+    {
+        ~Allocator()
+        {
+            while(!freelist_.empty())
+            {
+                delete freelist_.top();
+                freelist_.pop();
+            }
+        }
+
+        SeedRgVoxel * create(Diff_type const & location, Diff_type const & nearest,
+                             COST const & cost, int const & count, int const & label)
+        {
+            if(!freelist_.empty())
+            {
+                SeedRgVoxel * res = freelist_.top();
+                freelist_.pop();
+                res->set(location, nearest, cost, count, label);
+                return res;
+            }
+
+            return new SeedRgVoxel(location, nearest, cost, count, label);
+        }
+
+        void dismiss(SeedRgVoxel * p)
+        {
+            freelist_.push(p);
+        }
+
+        std::stack<SeedRgVoxel<COST,Diff_type> *> freelist_;
+    };
+};
+
+} // namespace detail
+
+/** \addtogroup SeededRegionGrowing
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                    seededRegionGrowing3D             */
+/*                                                      */
+/********************************************************/
+
+/** \brief Three-dimensional Region Segmentation by means of Seeded Region Growing.
+
+    This algorithm implements seeded region growing as described in
+
+    The seed image is a partly segmented multi-dimensional array which contains uniquely
+    labeled regions (the seeds) and unlabeled voxels (the candidates, label 0).
+    Seed regions can be as large as you wish and as small as one voxel. If
+    there are no candidates, the algorithm will simply copy the seed array
+    into the output array. Otherwise it will aggregate the candidates into
+    the existing regions so that a cost function is minimized.
+    Candidates are taken from the neighborhood of the already assigned pixels, 
+    where the type of neighborhood is determined by parameter <tt>neighborhood</tt>
+    which can take the values <tt>NeighborCode3DSix()</tt> (the default) 
+    or <tt>NeighborCode3DTwentySix()</tt>. The algorithm basically works as follows 
+    (illustrated for 6-neighborhood, but 26-neighborhood works in the same way):
+
+    <ol>
+
+    <li> Find all candidate pixels that are 6-adjacent to a seed region.
+    Calculate the cost for aggregating each candidate into its adjacent region
+    and put the candidates into a priority queue.
+
+    <li> While( priority queue is not empty)
+
+        <ol>
+
+        <li> Take the candidate with least cost from the queue. If it has not
+        already been merged, merge it with it's adjacent region.
+
+        <li> Put all candidates that are 4-adjacent to the pixel just processed
+        into the priority queue.
+
+        </ol>
+
+    </ol>
+
+    <tt>SRGType</tt> can take the following values:
+    
+    <DL>
+    <DT><tt>CompleteGrow</tt> <DD> produce a complete tesselation of the volume (default).
+    <DT><tt>KeepContours</tt> <DD> keep a 1-voxel wide unlabeled contour between all regions.
+    <DT><tt>StopAtThreshold</tt> <DD> stop when the boundary indicator values exceed the 
+                             threshold given by parameter <tt>max_cost</tt>.
+    <DT><tt>KeepContours | StopAtThreshold</tt> <DD> keep 1-voxel wide contour and stop at given <tt>max_cost</tt>.
+    </DL>
+
+    The cost is determined jointly by the source array and the
+    region statistics functor. The source array contains feature values for each
+    pixel which will be used by the region statistics functor to calculate and
+    update statistics for each region and to calculate the cost for each
+    candidate. The <TT>RegionStatisticsArray</TT> must be compatible to the
+    \ref ArrayOfRegionStatistics functor and contains an <em> array</em> of
+    statistics objects for each region. The indices must correspond to the
+    labels of the seed regions. The statistics for the initial regions must have
+    been calculated prior to calling <TT>seededRegionGrowing3D()</TT>
+
+    For each candidate
+    <TT>x</TT> that is adjacent to region <TT>i</TT>, the algorithm will call
+    <TT>stats[i].cost(as(x))</TT> to get the cost (where <TT>x</TT> is a <TT>SrcImageIterator</TT>
+    and <TT>as</TT> is
+    the SrcAccessor). When a candidate has been merged with a region, the
+    statistics are updated by calling <TT>stats[i].operator()(as(x))</TT>. Since
+    the <TT>RegionStatisticsArray</TT> is passed by reference, this will overwrite
+    the original statistics.
+
+    If a candidate could be merged into more than one regions with identical
+    cost, the algorithm will favour the nearest region. If <tt>StopAtThreshold</tt> is active, 
+    and the cost of the current candidate at any point in the algorithm exceeds the optional 
+    <tt>max_cost</tt> value (which defaults to <tt>NumericTraits<double>::max()</tt>), 
+    region growing is aborted, and all voxels not yet assigned to a region remain unlabeled.
+
+    In some cases, the cost only depends on the feature value of the current
+    voxel. Then the update operation will simply be a no-op, and the <TT>cost()</TT>
+    function returns its argument. This behavior is implemented by the
+    \ref SeedRgDirectValueFunctor.
+
+    <b> Declarations:</b>
+
+    pass 3D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class TS, class AS,
+                  class T2, class S2,
+                  class RegionStatisticsArray, class Neighborhood>
+        void
+        seededRegionGrowing3D(MultiArrayView<3, T1, S1> const & src,
+                              MultiArrayView<3, TS, AS> const & seeds,
+                              MultiArrayView<3, T2, S2>         labels,
+                              RegionStatisticsArray &           stats, 
+                              SRGType                           srgType = CompleteGrow,
+                              Neighborhood                      neighborhood = NeighborCode3DSix(),
+                              double                            max_cost = NumericTraits<double>::max());
+    }
+    \endcode
+
+    \deprecatedAPI{seededRegionGrowing3D}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class Shape, class SrcAccessor,
+                  class SeedImageIterator, class SeedAccessor,
+                  class DestImageIterator, class DestAccessor,
+                  class RegionStatisticsArray, class Neighborhood>
+        void 
+        seededRegionGrowing3D(SrcImageIterator srcul, Shape shape, SrcAccessor as,
+                              SeedImageIterator seedsul, SeedAccessor aseeds,
+                              DestImageIterator destul, DestAccessor ad,
+                              RegionStatisticsArray & stats, 
+                              SRGType srgType = CompleteGrow,
+                              Neighborhood neighborhood = NeighborCode3DSix(),
+                              double max_cost = NumericTraits<double>::max());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class Shape, class SrcAccessor,
+                  class SeedImageIterator, class SeedAccessor,
+                  class DestImageIterator, class DestAccessor,
+                  class RegionStatisticsArray, class Neighborhood>
+        void
+        seededRegionGrowing3D(triple<SrcImageIterator, Shape, SrcAccessor> src,
+                              pair<SeedImageIterator, SeedAccessor> seeds,
+                              pair<DestImageIterator, DestAccessor> dest,
+                              RegionStatisticsArray & stats, 
+                              SRGType srgType = CompleteGrow,
+                              Neighborhood neighborhood = NeighborCode3DSix(), 
+                              double max_cost = NumericTraits<double>::max());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/seededregiongrowing3d.hxx\><br>
+    Namespace: vigra
+    
+    See \ref seededRegionGrowing() for an example
+*/
+doxygen_overloaded_function(template <...> void seededRegionGrowing3D)
+
+template <class SrcImageIterator, class Diff_type, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestImageIterator, class DestAccessor,
+          class RegionStatisticsArray, class Neighborhood>
+void 
+seededRegionGrowing3D(SrcImageIterator srcul, Diff_type shape, SrcAccessor as,
+                      SeedImageIterator seedsul, SeedAccessor aseeds,
+                      DestImageIterator destul, DestAccessor ad,
+                      RegionStatisticsArray & stats, 
+                      SRGType srgType,
+                      Neighborhood,
+                      double max_cost)
+{
+    //SrcImageIterator srclr = srcul + shape;
+    //int w = srclr.x - srcul.x;
+    int w = shape[0];
+    //int h = srclr.y - srcul.y;
+    int h = shape[1];
+    //int d = srclr.z - srcul.z;
+    int d = shape[2];
+    int count = 0;
+
+    SrcImageIterator isy = srcul, isx = srcul, isz = srcul;  // iterators for the src image
+
+    typedef typename RegionStatisticsArray::value_type RegionStatistics;
+    typedef typename PromoteTraits<typename RegionStatistics::cost_type, double>::Promote CostType;
+    typedef detail::SeedRgVoxel<CostType, Diff_type> Voxel;
+
+    typename Voxel::Allocator allocator;
+
+    typedef std::priority_queue< Voxel *,
+                                 std::vector<Voxel *>,
+                                 typename Voxel::Compare >  SeedRgVoxelHeap;
+    typedef MultiArray<3, int> IVolume;
+    typedef IVolume::traverser Traverser;
+
+    // copy seed image in an image with border
+    Diff_type regionshape = shape + Diff_type(2,2,2);
+    IVolume regions(regionshape);
+    Traverser ir = regions.traverser_begin();
+    ir = ir + Diff_type(1,1,1);
+    
+    //IVolume::Iterator iry, irx, irz;
+   Traverser iry, irx, irz;
+
+    //initImageBorder(destImageRange(regions), 1, SRGWatershedLabel);
+    initMultiArrayBorder(destMultiArrayRange(regions), 1, SRGWatershedLabel); 
+    
+    copyMultiArray(seedsul, Diff_type(w,h,d), aseeds, ir, AccessorTraits<int>::default_accessor());
+
+    // allocate and init memory for the results
+
+    SeedRgVoxelHeap pheap;
+    int cneighbor;
+
+    typedef typename Neighborhood::Direction Direction;
+    int directionCount = Neighborhood::DirectionCount;
+
+    Diff_type pos(0,0,0);
+
+    for(isz=srcul, irz=ir, pos[2]=0; pos[2]<d;
+            pos[2]++, isz.dim2()++, irz.dim2()++)
+    {
+        //std::cerr << "Z = " << pos[2] << std::endl;
+
+        for(isy=isz, iry=irz, pos[1]=0; pos[1]<h;
+            pos[1]++, isy.dim1()++, iry.dim1()++)
+        {
+            //std::cerr << "Y = " << pos[1] << std::endl;
+            
+            for(isx=isy, irx=iry, pos[0]=0; pos[0]<w;
+                pos[0]++, isx.dim0()++, irx.dim0()++)
+            {
+                //std::cerr << "X = " << pos[0] << std::endl;
+                
+                if(*irx == 0)
+                {
+                    // find candidate pixels for growing and fill heap
+                    for(int i=0; i<directionCount; i++)
+                    {
+                        cneighbor = *(irx + Neighborhood::diff((Direction)i));
+                        if(cneighbor > 0)
+                        {
+                            CostType cost = stats[cneighbor].cost(as(isx));
+
+                            Voxel * voxel =
+                                allocator.create(pos, pos+Neighborhood::diff((Direction)i), cost, count++, cneighbor);
+                            pheap.push(voxel);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    // perform region growing
+    while(pheap.size() != 0)
+    {
+        Voxel * voxel = pheap.top();
+        pheap.pop();
+
+        Diff_type pos = voxel->location_;
+        Diff_type nearest = voxel->nearest_;
+        int lab = voxel->label_;
+        CostType cost = voxel->cost_;
+
+        allocator.dismiss(voxel);
+
+        if((srgType & StopAtThreshold) != 0 && cost > max_cost)
+            break;
+
+        irx = ir + pos;
+        isx = srcul + pos;
+
+        if(*irx) // already labelled region / watershed?
+            continue;
+
+        if((srgType & KeepContours) != 0)
+        {
+            for(int i=0; i<directionCount; i++)
+            {
+                cneighbor = * (irx + Neighborhood::diff((Direction)i));
+                if((cneighbor>0) && (cneighbor != lab))
+                {
+                    lab = SRGWatershedLabel;
+                    break;
+                }
+            }
+        }
+
+        *irx = lab;
+
+        if((srgType & KeepContours) == 0 || lab > 0)
+        {
+            // update statistics
+            stats[*irx](as(isx));
+
+            // search neighborhood
+            // second pass: find new candidate pixels
+            for(int i=0; i<directionCount; i++)
+            {
+                if(*(irx + Neighborhood::diff((Direction)i)) == 0)
+                {
+                    CostType cost = stats[lab].cost(as(isx, Neighborhood::diff((Direction)i)));
+
+                    Voxel * new_voxel =
+                        allocator.create(pos+Neighborhood::diff((Direction)i), nearest, cost, count++, lab);
+                    pheap.push(new_voxel);
+                }
+            }
+        }
+    }
+    
+    // free temporary memory
+    while(pheap.size() != 0)
+    {
+        allocator.dismiss(pheap.top());
+        pheap.pop();
+    }
+
+    // write result
+    transformMultiArray(ir, Diff_type(w,h,d), AccessorTraits<int>::default_accessor(), 
+                        destul, ad, detail::UnlabelWatersheds());
+}
+
+template <class SrcImageIterator, class Diff_type, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestImageIterator, class DestAccessor,
+          class RegionStatisticsArray, class Neighborhood >
+inline void
+seededRegionGrowing3D(SrcImageIterator srcul, Diff_type shape, SrcAccessor as,
+                      SeedImageIterator seedsul, SeedAccessor aseeds,
+                      DestImageIterator destul, DestAccessor ad,
+                      RegionStatisticsArray & stats, SRGType srgType, Neighborhood n)
+{
+    seededRegionGrowing3D( srcul, shape, as, seedsul, aseeds, 
+                           destul, ad, stats, srgType, n, NumericTraits<double>::max());
+}
+
+template <class SrcImageIterator, class Diff_type, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestImageIterator, class DestAccessor,
+          class RegionStatisticsArray >
+inline void
+seededRegionGrowing3D(SrcImageIterator srcul, Diff_type shape, SrcAccessor as,
+                      SeedImageIterator seedsul, SeedAccessor aseeds,
+                      DestImageIterator destul, DestAccessor ad,
+                      RegionStatisticsArray & stats, SRGType srgType)
+{
+    seededRegionGrowing3D( srcul, shape, as, seedsul, aseeds, 
+                           destul, ad, stats, srgType, NeighborCode3DSix());
+}
+
+template <class SrcImageIterator, class Diff_type, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestImageIterator, class DestAccessor,
+          class RegionStatisticsArray >
+inline void
+seededRegionGrowing3D(SrcImageIterator srcul, Diff_type shape, SrcAccessor as,
+                      SeedImageIterator seedsul, SeedAccessor aseeds,
+                      DestImageIterator destul, DestAccessor ad,
+                      RegionStatisticsArray & stats)
+{
+    seededRegionGrowing3D( srcul, shape, as, seedsul, aseeds, destul, ad, 
+                           stats, CompleteGrow);
+}
+
+template <class SrcImageIterator, class Shape, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestImageIterator, class DestAccessor,
+          class RegionStatisticsArray, class Neighborhood>
+inline void
+seededRegionGrowing3D(triple<SrcImageIterator, Shape, SrcAccessor> img1,
+                      pair<SeedImageIterator, SeedAccessor> img3,
+                      pair<DestImageIterator, DestAccessor> img4,
+                      RegionStatisticsArray & stats, 
+                      SRGType srgType, Neighborhood n, double max_cost)
+{
+    seededRegionGrowing3D(img1.first, img1.second, img1.third,
+                          img3.first, img3.second,
+                          img4.first, img4.second,
+                          stats, srgType, n, max_cost);
+}
+
+template <class SrcImageIterator, class Shape, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestImageIterator, class DestAccessor,
+          class RegionStatisticsArray, class Neighborhood>
+inline void
+seededRegionGrowing3D(triple<SrcImageIterator, Shape, SrcAccessor> img1,
+                      pair<SeedImageIterator, SeedAccessor> img3,
+                      pair<DestImageIterator, DestAccessor> img4,
+                      RegionStatisticsArray & stats, 
+                      SRGType srgType, Neighborhood n)
+{
+    seededRegionGrowing3D(img1.first, img1.second, img1.third,
+                          img3.first, img3.second,
+                          img4.first, img4.second,
+                          stats, srgType, n, NumericTraits<double>::max());
+}
+
+template <class SrcImageIterator, class Shape, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestImageIterator, class DestAccessor,
+          class RegionStatisticsArray>
+inline void
+seededRegionGrowing3D(triple<SrcImageIterator, Shape, SrcAccessor> img1,
+                      pair<SeedImageIterator, SeedAccessor> img3,
+                      pair<DestImageIterator, DestAccessor> img4,
+                      RegionStatisticsArray & stats, SRGType srgType)
+{
+    seededRegionGrowing3D(img1.first, img1.second, img1.third,
+                          img3.first, img3.second,
+                          img4.first, img4.second,
+                          stats, srgType, NeighborCode3DSix());
+}
+
+template <class SrcImageIterator, class Shape, class SrcAccessor,
+          class SeedImageIterator, class SeedAccessor,
+          class DestImageIterator, class DestAccessor,
+          class RegionStatisticsArray>
+inline void
+seededRegionGrowing3D(triple<SrcImageIterator, Shape, SrcAccessor> img1,
+                      pair<SeedImageIterator, SeedAccessor> img3,
+                      pair<DestImageIterator, DestAccessor> img4,
+                      RegionStatisticsArray & stats)
+{
+    seededRegionGrowing3D(img1.first, img1.second, img1.third,
+                          img3.first, img3.second,
+                          img4.first, img4.second,
+                          stats);
+}
+
+template <class T1, class S1,
+          class TS, class AS,
+          class T2, class S2,
+          class RegionStatisticsArray, class Neighborhood>
+inline void
+seededRegionGrowing3D(MultiArrayView<3, T1, S1> const & img1,
+                      MultiArrayView<3, TS, AS> const & img3,
+                      MultiArrayView<3, T2, S2> img4,
+                      RegionStatisticsArray & stats, 
+                      SRGType srgType, Neighborhood n, double max_cost)
+{
+    vigra_precondition(img1.shape() == img3.shape(),
+        "seededRegionGrowing3D(): shape mismatch between input and output.");
+    seededRegionGrowing3D(srcMultiArrayRange(img1),
+                          srcMultiArray(img3),
+                          destMultiArray(img4),
+                          stats, srgType, n, max_cost);
+}
+
+template <class T1, class S1,
+          class TS, class AS,
+          class T2, class S2,
+          class RegionStatisticsArray, class Neighborhood>
+inline void
+seededRegionGrowing3D(MultiArrayView<3, T1, S1> const & img1,
+                      MultiArrayView<3, TS, AS> const & img3,
+                      MultiArrayView<3, T2, S2> img4,
+                      RegionStatisticsArray & stats, 
+                      SRGType srgType, Neighborhood n)
+{
+    vigra_precondition(img1.shape() == img3.shape(),
+        "seededRegionGrowing3D(): shape mismatch between input and output.");
+    seededRegionGrowing3D(srcMultiArrayRange(img1),
+                          srcMultiArray(img3),
+                          destMultiArray(img4),
+                          stats, srgType, n, NumericTraits<double>::max());
+}
+
+template <class T1, class S1,
+          class TS, class AS,
+          class T2, class S2,
+          class RegionStatisticsArray>
+inline void
+seededRegionGrowing3D(MultiArrayView<3, T1, S1> const & img1,
+                      MultiArrayView<3, TS, AS> const & img3,
+                      MultiArrayView<3, T2, S2> img4,
+                      RegionStatisticsArray & stats, SRGType srgType)
+{
+    vigra_precondition(img1.shape() == img3.shape(),
+        "seededRegionGrowing3D(): shape mismatch between input and output.");
+    seededRegionGrowing3D(srcMultiArrayRange(img1),
+                          srcMultiArray(img3),
+                          destMultiArray(img4),
+                          stats, srgType, NeighborCode3DSix());
+}
+
+template <class T1, class S1,
+          class TS, class AS,
+          class T2, class S2,
+          class RegionStatisticsArray>
+inline void
+seededRegionGrowing3D(MultiArrayView<3, T1, S1> const & img1,
+                      MultiArrayView<3, TS, AS> const & img3,
+                      MultiArrayView<3, T2, S2> img4,
+                      RegionStatisticsArray & stats)
+{
+    vigra_precondition(img1.shape() == img3.shape(),
+        "seededRegionGrowing3D(): shape mismatch between input and output.");
+    seededRegionGrowing3D(srcMultiArrayRange(img1),
+                          srcMultiArray(img3),
+                          destMultiArray(img4),
+                          stats);
+}
+
+} // namespace vigra
+
+#endif // VIGRA_SEEDEDREGIONGROWING_HXX
+
diff --git a/include/vigra/separableconvolution.hxx b/include/vigra/separableconvolution.hxx
new file mode 100644
index 0000000..3ae5781
--- /dev/null
+++ b/include/vigra/separableconvolution.hxx
@@ -0,0 +1,2584 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_SEPARABLECONVOLUTION_HXX
+#define VIGRA_SEPARABLECONVOLUTION_HXX
+
+#include <cmath>
+#include "utilities.hxx"
+#include "numerictraits.hxx"
+#include "imageiteratoradapter.hxx"
+#include "bordertreatment.hxx"
+#include "gaussians.hxx"
+#include "array_vector.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+template <class ARITHTYPE>
+class Kernel1D;
+
+/********************************************************/
+/*                                                      */
+/*            internalConvolveLineOptimistic            */
+/*                                                      */
+/********************************************************/
+
+// This function assumes that the input array is actually larger than
+// the range [is, iend), so that it can safely access values outside
+// this range. This is useful if (1) we work on a small ROI, or 
+// (2) we enlarge the input by copying with border treatment.
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+void internalConvolveLineOptimistic(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                                    DestIterator id, DestAccessor da,
+                                    KernelIterator kernel, KernelAccessor ka,
+                                    int kleft, int kright)
+{
+    typedef typename PromoteTraits<
+            typename SrcAccessor::value_type,
+            typename KernelAccessor::value_type>::Promote SumType;
+
+    int w = std::distance( is, iend );
+    int kw = kright - kleft + 1;
+    for(int x=0; x<w; ++x, ++is, ++id)
+    {
+        SrcIterator iss = is + (-kright);
+        KernelIterator ik = kernel + kright;
+        SumType sum = NumericTraits<SumType>::zero();
+
+        for(int k = 0; k < kw; ++k, --ik, ++iss)
+        {
+            sum += ka(ik) * sa(iss);
+        }
+
+        da.set(detail::RequiresExplicitCast<typename
+                      DestAccessor::value_type>::cast(sum), id);
+    }
+}
+
+namespace detail {
+
+// dest array must have size = stop - start + kright - kleft
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void 
+copyLineWithBorderTreatment(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                            DestIterator id, DestAccessor da,
+                            int start, int stop,
+                            int kleft, int kright,
+                            BorderTreatmentMode borderTreatment)
+{
+    int w = std::distance( is, iend );
+    int leftBorder = start - kright;
+    int rightBorder = stop - kleft;
+    int copyEnd = std::min(w, rightBorder);
+    
+    if(leftBorder < 0)
+    {
+        switch(borderTreatment)
+        {
+            case BORDER_TREATMENT_WRAP:
+            {
+                for(; leftBorder<0; ++leftBorder, ++id)
+                    da.set(sa(iend, leftBorder), id);
+                break;
+            }
+            case BORDER_TREATMENT_AVOID:
+            {
+                // nothing to do
+                break;
+            }
+            case BORDER_TREATMENT_REFLECT:
+            {
+                for(; leftBorder<0; ++leftBorder, ++id)
+                    da.set(sa(is, -leftBorder), id);
+                break;
+            }
+            case BORDER_TREATMENT_REPEAT:
+            {
+                for(; leftBorder<0; ++leftBorder, ++id)
+                    da.set(sa(is), id);
+                break;
+            }
+            case BORDER_TREATMENT_CLIP:
+            {
+                vigra_precondition(false,
+                             "copyLineWithBorderTreatment() internal error: not applicable to BORDER_TREATMENT_CLIP.");
+                break;
+            }
+            case BORDER_TREATMENT_ZEROPAD:
+            {
+                for(; leftBorder<0; ++leftBorder, ++id)
+                    da.set(NumericTraits<typename DestAccessor::value_type>::zero(), id);
+                break;
+            }
+            default:
+            {
+                vigra_precondition(false,
+                             "copyLineWithBorderTreatment(): Unknown border treatment mode.");
+            }
+        }
+    }
+    
+    SrcIterator iss = is + leftBorder;
+    vigra_invariant( leftBorder < copyEnd,
+        "copyLineWithBorderTreatment(): assertion failed.");
+    for(; leftBorder<copyEnd; ++leftBorder, ++id, ++iss)
+        da.set(sa(iss), id);
+    
+    if(copyEnd < rightBorder)
+    {
+        switch(borderTreatment)
+        {
+            case BORDER_TREATMENT_WRAP:
+            {
+                for(; copyEnd<rightBorder; ++copyEnd, ++id, ++is)
+                    da.set(sa(is), id);
+                break;
+            }
+            case BORDER_TREATMENT_AVOID:
+            {
+                // nothing to do
+                break;
+            }
+            case BORDER_TREATMENT_REFLECT:
+            {
+                iss -= 2;
+                for(; copyEnd<rightBorder; ++copyEnd, ++id, --iss)
+                    da.set(sa(iss), id);
+                break;
+            }
+            case BORDER_TREATMENT_REPEAT:
+            {
+                --iss;
+                for(; copyEnd<rightBorder; ++copyEnd, ++id)
+                    da.set(sa(iss), id);
+                break;
+            }
+            case BORDER_TREATMENT_CLIP:
+            {
+                vigra_precondition(false,
+                             "copyLineWithBorderTreatment() internal error: not applicable to BORDER_TREATMENT_CLIP.");
+                break;
+            }
+            case BORDER_TREATMENT_ZEROPAD:
+            {
+                for(; copyEnd<rightBorder; ++copyEnd, ++id)
+                    da.set(NumericTraits<typename DestAccessor::value_type>::zero(), id);
+                break;
+            }
+            default:
+            {
+                vigra_precondition(false,
+                             "copyLineWithBorderTreatment(): Unknown border treatment mode.");
+            }
+        }
+    }
+}
+
+} // namespace detail
+
+/********************************************************/
+/*                                                      */
+/*                internalConvolveLineWrap              */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+void internalConvolveLineWrap(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                              DestIterator id, DestAccessor da,
+                              KernelIterator kernel, KernelAccessor ka,
+                              int kleft, int kright,
+                              int start = 0, int stop = 0)
+{
+    int w = std::distance( is, iend );
+
+    typedef typename PromoteTraits<
+            typename SrcAccessor::value_type,
+            typename KernelAccessor::value_type>::Promote SumType;
+
+    SrcIterator ibegin = is;
+    
+    if(stop == 0)
+        stop = w;
+    is += start;
+
+    for(int x=start; x<stop; ++x, ++is, ++id)
+    {
+        KernelIterator ik = kernel + kright;
+        SumType sum = NumericTraits<SumType>::zero();
+
+        if(x < kright)
+        {
+            int x0 = x - kright;
+            SrcIterator iss = iend + x0;
+
+            for(; x0; ++x0, --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+
+            iss = ibegin;
+            if(w-x <= -kleft)
+            {
+                SrcIterator isend = iend;
+                for(; iss != isend ; --ik, ++iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+
+                int x0 = -kleft - w + x + 1;
+                iss = ibegin;
+
+                for(; x0; --x0, --ik, ++iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+            }
+            else
+            {
+                SrcIterator isend = is + (1 - kleft);
+                for(; iss != isend ; --ik, ++iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+            }
+        }
+        else if(w-x <= -kleft)
+        {
+            SrcIterator iss = is + (-kright);
+            SrcIterator isend = iend;
+            for(; iss != isend ; --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+
+            int x0 = -kleft - w + x + 1;
+            iss = ibegin;
+
+            for(; x0; --x0, --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+        }
+        else
+        {
+            SrcIterator iss = is - kright;
+            SrcIterator isend = is + (1 - kleft);
+            for(; iss != isend ; --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+        }
+
+        da.set(detail::RequiresExplicitCast<typename
+                      DestAccessor::value_type>::cast(sum), id);
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*                internalConvolveLineClip              */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor,
+          class Norm>
+void internalConvolveLineClip(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                              DestIterator id, DestAccessor da,
+                              KernelIterator kernel, KernelAccessor ka,
+                              int kleft, int kright, Norm norm,
+                              int start = 0, int stop = 0)
+{
+    int w = std::distance( is, iend );
+
+    typedef typename PromoteTraits<
+            typename SrcAccessor::value_type,
+            typename KernelAccessor::value_type>::Promote SumType;
+
+    SrcIterator ibegin = is;
+    
+    if(stop == 0)
+        stop = w;
+    is += start;
+    
+    for(int x=start; x<stop; ++x, ++is, ++id)
+    {
+        KernelIterator ik = kernel + kright;
+        SumType sum = NumericTraits<SumType>::zero();
+
+        if(x < kright)
+        {
+            int x0 = x - kright;
+            Norm clipped = NumericTraits<Norm>::zero();
+
+            for(; x0; ++x0, --ik)
+            {
+                clipped += ka(ik);
+            }
+
+            SrcIterator iss = ibegin;
+            if(w-x <= -kleft)
+            {
+                SrcIterator isend = iend;
+                for(; iss != isend ; --ik, ++iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+
+                int x0 = -kleft - w + x + 1;
+
+                for(; x0; --x0, --ik)
+                {
+                    clipped += ka(ik);
+                }
+            }
+            else
+            {
+                SrcIterator isend = is + (1 - kleft);
+                for(; iss != isend ; --ik, ++iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+            }
+            
+            sum = norm / (norm - clipped) * sum;
+        }
+        else if(w-x <= -kleft)
+        {
+            SrcIterator iss = is + (-kright);
+            SrcIterator isend = iend;
+            for(; iss != isend ; --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+
+            Norm clipped = NumericTraits<Norm>::zero();
+
+            int x0 = -kleft - w + x + 1;
+
+            for(; x0; --x0, --ik)
+            {
+                clipped += ka(ik);
+            }
+
+            sum = norm / (norm - clipped) * sum;
+        }
+        else
+        {
+            SrcIterator iss = is + (-kright);
+            SrcIterator isend = is + (1 - kleft);
+            for(; iss != isend ; --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+        }
+        
+        da.set(detail::RequiresExplicitCast<typename
+                      DestAccessor::value_type>::cast(sum), id);
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*             internalConvolveLineZeropad              */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+void internalConvolveLineZeropad(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                                 DestIterator id, DestAccessor da,
+                                 KernelIterator kernel, KernelAccessor ka,
+                                 int kleft, int kright, 
+                                 int start = 0, int stop = 0)
+{
+    int w = std::distance( is, iend );
+
+    typedef typename PromoteTraits<
+            typename SrcAccessor::value_type,
+            typename KernelAccessor::value_type>::Promote SumType;
+
+    SrcIterator ibegin = is;
+    
+    if(stop == 0)
+        stop = w;
+    is += start;
+    
+    for(int x=start; x<stop; ++x, ++is, ++id)
+    {
+        SumType sum = NumericTraits<SumType>::zero();
+
+        if(x < kright)
+        {
+            KernelIterator ik = kernel + x;
+            SrcIterator iss = ibegin;
+            
+            if(w-x <= -kleft)
+            {
+                SrcIterator isend = iend;
+                for(; iss != isend ; --ik, ++iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+            }
+            else
+            {
+                SrcIterator isend = is + (1 - kleft);
+                for(; iss != isend ; --ik, ++iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+            }
+        }
+        else if(w-x <= -kleft)
+        {
+            KernelIterator ik = kernel + kright;
+            SrcIterator iss = is + (-kright);
+            SrcIterator isend = iend;
+            for(; iss != isend ; --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+        }
+        else
+        {
+            KernelIterator ik = kernel + kright;
+            SrcIterator iss = is + (-kright);
+            SrcIterator isend = is + (1 - kleft);
+            for(; iss != isend ; --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+        }
+        
+        da.set(detail::RequiresExplicitCast<typename
+                      DestAccessor::value_type>::cast(sum), id);
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*             internalConvolveLineReflect              */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+void internalConvolveLineReflect(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                              DestIterator id, DestAccessor da,
+                              KernelIterator kernel, KernelAccessor ka,
+                              int kleft, int kright,
+                              int start = 0, int stop = 0)
+{
+    int w = std::distance( is, iend );
+
+    typedef typename PromoteTraits<
+            typename SrcAccessor::value_type,
+            typename KernelAccessor::value_type>::Promote SumType;
+
+    SrcIterator ibegin = is;
+    
+    if(stop == 0)
+        stop = w;
+    is += start;
+    
+    for(int x=start; x<stop; ++x, ++is, ++id)
+    {
+        KernelIterator ik = kernel + kright;
+        SumType sum = NumericTraits<SumType>::zero();
+
+        if(x < kright)
+        {
+            int x0 = x - kright;
+            SrcIterator iss = ibegin - x0;
+
+            for(; x0; ++x0, --ik, --iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+
+            if(w-x <= -kleft)
+            {
+                SrcIterator isend = iend;
+                for(; iss != isend ; --ik, ++iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+
+                int x0 = -kleft - w + x + 1;
+                iss = iend - 2;
+
+                for(; x0; --x0, --ik, --iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+            }
+            else
+            {
+                SrcIterator isend = is + (1 - kleft);
+                for(; iss != isend ; --ik, ++iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+            }
+        }
+        else if(w-x <= -kleft)
+        {
+            SrcIterator iss = is + (-kright);
+            SrcIterator isend = iend;
+            for(; iss != isend ; --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+
+            int x0 = -kleft - w + x + 1;
+            iss = iend - 2;
+
+            for(; x0; --x0, --ik, --iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+        }
+        else
+        {
+            SrcIterator iss = is + (-kright);
+            SrcIterator isend = is + (1 - kleft);
+            for(; iss != isend ; --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+        }
+
+        da.set(detail::RequiresExplicitCast<typename
+                      DestAccessor::value_type>::cast(sum), id);
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*             internalConvolveLineRepeat               */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+void internalConvolveLineRepeat(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                              DestIterator id, DestAccessor da,
+                              KernelIterator kernel, KernelAccessor ka,
+                              int kleft, int kright,
+                              int start = 0, int stop = 0)
+{
+    int w = std::distance( is, iend );
+
+    typedef typename PromoteTraits<
+            typename SrcAccessor::value_type,
+            typename KernelAccessor::value_type>::Promote SumType;
+
+    SrcIterator ibegin = is;
+    
+    if(stop == 0)
+        stop = w;
+    is += start;
+
+    for(int x=start; x<stop; ++x, ++is, ++id)
+    {
+        KernelIterator ik = kernel + kright;
+        SumType sum = NumericTraits<SumType>::zero();
+
+        if(x < kright)
+        {
+            int x0 = x - kright;
+            SrcIterator iss = ibegin;
+
+            for(; x0; ++x0, --ik)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+
+            if(w-x <= -kleft)
+            {
+                SrcIterator isend = iend;
+                for(; iss != isend ; --ik, ++iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+
+                int x0 = -kleft - w + x + 1;
+                iss = iend - 1;
+
+                for(; x0; --x0, --ik)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+            }
+            else
+            {
+                SrcIterator isend = is + (1 - kleft);
+                for(; iss != isend ; --ik, ++iss)
+                {
+                    sum += ka(ik) * sa(iss);
+                }
+            }
+        }
+        else if(w-x <= -kleft)
+        {
+            SrcIterator iss = is + (-kright);
+            SrcIterator isend = iend;
+            for(; iss != isend ; --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+
+            int x0 = -kleft - w + x + 1;
+            iss = iend - 1;
+
+            for(; x0; --x0, --ik)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+        }
+        else
+        {
+            SrcIterator iss = is + (-kright);
+            SrcIterator isend = is + (1 - kleft);
+            for(; iss != isend ; --ik, ++iss)
+            {
+                sum += ka(ik) * sa(iss);
+            }
+        }
+
+        da.set(detail::RequiresExplicitCast<typename
+                      DestAccessor::value_type>::cast(sum), id);
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*              internalConvolveLineAvoid               */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+void internalConvolveLineAvoid(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                              DestIterator id, DestAccessor da,
+                              KernelIterator kernel, KernelAccessor ka,
+                              int kleft, int kright,
+                              int start = 0, int stop = 0)
+{
+    int w = std::distance( is, iend );
+    if(start < stop) // we got a valid subrange
+    {
+        if(w + kleft < stop)
+            stop = w + kleft;
+        if(start < kright)
+        {
+            id += kright - start;
+            start = kright;
+        }
+    }
+    else
+    {
+        id += kright;
+        start = kright;
+        stop = w + kleft;
+    }
+
+    typedef typename PromoteTraits<
+            typename SrcAccessor::value_type,
+            typename KernelAccessor::value_type>::Promote SumType;
+
+    is += start;
+
+    for(int x=start; x<stop; ++x, ++is, ++id)
+    {
+        KernelIterator ik = kernel + kright;
+        SumType sum = NumericTraits<SumType>::zero();
+
+        SrcIterator iss = is + (-kright);
+        SrcIterator isend = is + (1 - kleft);
+        for(; iss != isend ; --ik, ++iss)
+        {
+            sum += ka(ik) * sa(iss);
+        }
+
+        da.set(detail::RequiresExplicitCast<typename
+                      DestAccessor::value_type>::cast(sum), id);
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*         Separable convolution functions              */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup SeparableConvolution One-dimensional and separable convolution functions
+
+    Perform 1D convolution and separable filtering in 2 dimensions.
+
+    These generic convolution functions implement
+    the standard convolution operation for a wide range of images and
+    signals that fit into the required interface. They need a suitable
+    kernel to operate.
+*/
+//@{
+
+/** \brief Performs a 1-dimensional convolution of the source signal using the given
+    kernel.
+
+    The KernelIterator must point to the center iterator, and
+    the kernel's size is given by its left (kleft <= 0) and right
+    (kright >= 0) borders. The signal must always be larger than the kernel.
+    At those positions where the kernel does not completely fit
+    into the signal's range, the specified \ref BorderTreatmentMode is
+    applied.
+
+    The signal's value_type (SrcAccessor::value_type) must be a
+    linear space over the kernel's value_type (KernelAccessor::value_type),
+    i.e. addition of source values, multiplication with kernel values,
+    and NumericTraits must be defined.
+    The kernel's value_type must be an algebraic field,
+    i.e. the arithmetic operations (+, -, *, /) and NumericTraits must
+    be defined.
+    
+    If <tt>start</tt> and <tt>stop</tt> are non-zero, the relation
+    <tt>0 <= start < stop <= width</tt> must hold (where <tt>width</tt>
+    is the length of the input array). The convolution is then restricted to that 
+    subrange, and it is assumed that the output array only refers to that
+    subrange (i.e. <tt>id</tt> points to the element corresponding to 
+    <tt>start</tt>). If <tt>start</tt> and <tt>stop</tt> are both zero 
+    (the default), the entire array is convolved.
+
+    <b> Declarations:</b>
+
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void convolveLine(SrcIterator is, SrcIterator isend, SrcAccessor sa,
+                          DestIterator id, DestAccessor da,
+                          KernelIterator ik, KernelAccessor ka,
+                          int kleft, int kright, BorderTreatmentMode border,
+                          int start = 0, int stop = 0 )
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void convolveLine(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                          pair<DestIterator, DestAccessor> dest,
+                          tuple5<KernelIterator, KernelAccessor,
+                                 int, int, BorderTreatmentMode> kernel,
+                           int start = 0, int stop = 0)
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/separableconvolution.hxx\><br/>
+    Namespace: vigra
+
+
+    \code
+    std::vector<float> src, dest;
+    ...
+
+    // define binomial filter of size 5
+    static float kernel[] =
+           { 1.0/16.0, 4.0/16.0, 6.0/16.0, 4.0/16.0, 1.0/16.0};
+
+    typedef vigra::StandardAccessor<float> FAccessor;
+    typedef vigra::StandardAccessor<float> KernelAccessor;
+
+
+    vigra::convolveLine(src.begin(), src.end(), FAccessor(), dest.begin(), FAccessor(),
+             kernel+2, KernelAccessor(), -2, 2, BORDER_TREATMENT_REFLECT);
+    //       ^^^^^^^^  this is the center of the kernel
+
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+    RandomAccessIterator is, isend;
+    RandomAccessIterator id;
+    RandomAccessIterator ik;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    KernelAccessor kernel_accessor;
+
+    NumericTraits<SrcAccessor::value_type>::RealPromote s = src_accessor(is);
+
+    s = s + s;
+    s = kernel_accessor(ik) * s;
+
+    dest_accessor.set(
+        NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id);
+
+    \endcode
+
+    If border == BORDER_TREATMENT_CLIP:
+
+    \code
+    NumericTraits<KernelAccessor::value_type>::RealPromote k = kernel_accessor(ik);
+
+    k = k + k;
+    k = k - k;
+    k = k * k;
+    k = k / k;
+
+    \endcode
+
+    <b> Preconditions:</b>
+
+    \code
+    kleft <= 0
+    kright >= 0
+    iend - is >= kright + kleft + 1
+    \endcode
+
+    If border == BORDER_TREATMENT_CLIP: Sum of kernel elements must be
+    != 0.
+*/
+doxygen_overloaded_function(template <...> void convolveLine)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+void convolveLine(SrcIterator is, SrcIterator iend, SrcAccessor sa,
+                  DestIterator id, DestAccessor da,
+                  KernelIterator ik, KernelAccessor ka,
+                  int kleft, int kright, BorderTreatmentMode border,
+                  int start = 0, int stop = 0)
+{
+    vigra_precondition(kleft <= 0,
+                 "convolveLine(): kleft must be <= 0.\n");
+    vigra_precondition(kright >= 0,
+                 "convolveLine(): kright must be >= 0.\n");
+
+    //    int w = iend - is;
+    int w = std::distance( is, iend );
+
+    vigra_precondition(w >= std::max(kright, -kleft) + 1,
+                 "convolveLine(): kernel longer than line.\n");
+                 
+    if(stop != 0)
+        vigra_precondition(0 <= start && start < stop && stop <= w,
+                        "convolveLine(): invalid subrange (start, stop).\n");
+
+    typedef typename PromoteTraits<
+            typename SrcAccessor::value_type,
+            typename KernelAccessor::value_type>::Promote SumType;
+    ArrayVector<SumType> a(iend - is); 
+    switch(border)
+    {
+      case BORDER_TREATMENT_WRAP:
+      {
+        internalConvolveLineWrap(is, iend, sa, id, da, ik, ka, kleft, kright, start, stop);
+        break;
+      }
+      case BORDER_TREATMENT_AVOID:
+      {
+        internalConvolveLineAvoid(is, iend, sa, id, da, ik, ka, kleft, kright, start, stop);
+        break;
+      }
+      case BORDER_TREATMENT_REFLECT:
+      {
+        internalConvolveLineReflect(is, iend, sa, id, da, ik, ka, kleft, kright, start, stop);
+        break;
+      }
+      case BORDER_TREATMENT_REPEAT:
+      {
+        internalConvolveLineRepeat(is, iend, sa, id, da, ik, ka, kleft, kright, start, stop);
+        break;
+      }
+      case BORDER_TREATMENT_CLIP:
+      {
+        // find norm of kernel
+        typedef typename KernelAccessor::value_type KT;
+        KT norm = NumericTraits<KT>::zero();
+        KernelIterator iik = ik + kleft;
+        for(int i=kleft; i<=kright; ++i, ++iik)
+            norm += ka(iik);
+
+        vigra_precondition(norm != NumericTraits<KT>::zero(),
+                     "convolveLine(): Norm of kernel must be != 0"
+                     " in mode BORDER_TREATMENT_CLIP.\n");
+
+        internalConvolveLineClip(is, iend, sa, id, da, ik, ka, kleft, kright, norm, start, stop);
+        break;
+      }
+      case BORDER_TREATMENT_ZEROPAD:
+      {
+        internalConvolveLineZeropad(is, iend, sa, id, da, ik, ka, kleft, kright, start, stop);
+        break;
+      }
+      default:
+      {
+        vigra_precondition(0,
+                     "convolveLine(): Unknown border treatment mode.\n");
+      }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+inline
+void convolveLine(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                  pair<DestIterator, DestAccessor> dest,
+                  tuple5<KernelIterator, KernelAccessor,
+                         int, int, BorderTreatmentMode> kernel,
+                  int start = 0, int stop = 0)
+{
+    convolveLine(src.first, src.second, src.third,
+                 dest.first, dest.second,
+                 kernel.first, kernel.second,
+                 kernel.third, kernel.fourth, kernel.fifth, start, stop);
+}
+
+/********************************************************/
+/*                                                      */
+/*                      separableConvolveX              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs a 1 dimensional convolution in x direction.
+
+    It calls \ref convolveLine() for every row of the image. See \ref convolveLine() 
+    for more information about required interfaces and vigra_preconditions.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class T3>
+        void
+        separableConvolveX(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, T2, S2> dest,
+                           Kernel1D<T3> const & kernel);
+    }
+    \endcode
+
+    \deprecatedAPI{separableConvolveX}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void separableConvolveX(SrcImageIterator supperleft,
+                                SrcImageIterator slowerright, SrcAccessor sa,
+                                DestImageIterator dupperleft, DestAccessor da,
+                                KernelIterator ik, KernelAccessor ka,
+                                int kleft, int kright, BorderTreatmentMode border)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void separableConvolveX(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                                pair<DestImageIterator, DestAccessor> dest,
+                                tuple5<KernelIterator, KernelAccessor,
+                                             int, int, BorderTreatmentMode> kernel)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/separableconvolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);
+    ...
+
+    // define Gaussian kernel with std. deviation 3.0
+    Kernel1D<double> kernel;
+    kernel.initGaussian(3.0);
+
+    // apply 1D filter along the x-axis
+    separableConvolveX(src, dest, kernel);
+    \endcode
+
+    \deprecatedUsage{separableConvolveX}
+    \code
+    vigra::FImage src(w,h), dest(w,h);
+    ...
+
+    // define Gaussian kernel with std. deviation 3.0
+    vigra::Kernel1D<double> kernel;
+    kernel.initGaussian(3.0);
+
+    // apply 1D filter along the x-axis
+    vigra::separableConvolveX(srcImageRange(src), destImage(dest), kernel1d(kernel));
+    \endcode
+    \deprecatedEnd
+    
+    <b>Preconditions:</b>
+    
+    <ul>
+    <li> The x-axis must be longer than the kernel radius: <tt>w > std::max(kernel.right(), -kernel.left())</tt>.
+    <li> If <tt>border == BORDER_TREATMENT_CLIP</tt>: The sum of kernel elements must be != 0.
+    </ul>
+*/
+doxygen_overloaded_function(template <...> void separableConvolveX)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+void separableConvolveX(SrcIterator supperleft,
+                        SrcIterator slowerright, SrcAccessor sa,
+                        DestIterator dupperleft, DestAccessor da,
+                        KernelIterator ik, KernelAccessor ka,
+                        int kleft, int kright, BorderTreatmentMode border)
+{
+    vigra_precondition(kleft <= 0,
+                 "separableConvolveX(): kleft must be <= 0.\n");
+    vigra_precondition(kright >= 0,
+                 "separableConvolveX(): kright must be >= 0.\n");
+
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+
+    vigra_precondition(w >= std::max(kright, -kleft) + 1,
+                 "separableConvolveX(): kernel longer than line\n");
+
+    int y;
+
+    for(y=0; y<h; ++y, ++supperleft.y, ++dupperleft.y)
+    {
+        typename SrcIterator::row_iterator rs = supperleft.rowIterator();
+        typename DestIterator::row_iterator rd = dupperleft.rowIterator();
+
+        convolveLine(rs, rs+w, sa, rd, da,
+                     ik, ka, kleft, kright, border);
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+inline void
+separableConvolveX(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   tuple5<KernelIterator, KernelAccessor,
+                           int, int, BorderTreatmentMode> kernel)
+{
+    separableConvolveX(src.first, src.second, src.third,
+                       dest.first, dest.second,
+                       kernel.first, kernel.second,
+                       kernel.third, kernel.fourth, kernel.fifth);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class T3>
+inline void
+separableConvolveX(MultiArrayView<2, T1, S1> const & src,
+                   MultiArrayView<2, T2, S2> dest,
+                   Kernel1D<T3> const & kernel)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "separableConvolveX(): shape mismatch between input and output.");
+    separableConvolveX(srcImageRange(src),
+                       destImage(dest), kernel1d(kernel));
+}
+
+/********************************************************/
+/*                                                      */
+/*                      separableConvolveY              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs a 1 dimensional convolution in y direction.
+
+    It calls \ref convolveLine() for every column of the image. See \ref convolveLine() 
+    for more information about required interfaces and vigra_preconditions.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class T3>
+        void
+        separableConvolveY(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, T2, S2> dest,
+                           Kernel1D<T3> const & kernel);
+    }
+    \endcode
+
+    \deprecatedAPI{separableConvolveY}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void separableConvolveY(SrcImageIterator supperleft,
+                                SrcImageIterator slowerright, SrcAccessor sa,
+                                DestImageIterator dupperleft, DestAccessor da,
+                                KernelIterator ik, KernelAccessor ka,
+                                int kleft, int kright, BorderTreatmentMode border)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void separableConvolveY(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                                pair<DestImageIterator, DestAccessor> dest,
+                                tuple5<KernelIterator, KernelAccessor,
+                                             int, int, BorderTreatmentMode> kernel)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/separableconvolution.hxx\><br/>
+    Namespace: vigra
+
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);
+    ...
+
+    // define Gaussian kernel with std. deviation 3.0
+    Kernel1D kernel;
+    kernel.initGaussian(3.0);
+
+    // apply 1D filter along the y-axis
+    separableConvolveY(src, dest, kernel);
+    \endcode
+
+    \deprecatedUsage{separableConvolveY}
+    \code
+    vigra::FImage src(w,h), dest(w,h);
+    ...
+
+    // define Gaussian kernel with std. deviation 3.0
+    vigra::Kernel1D kernel;
+    kernel.initGaussian(3.0);
+
+    vigra::separableConvolveY(srcImageRange(src), destImage(dest), kernel1d(kernel));
+    \endcode
+    \deprecatedEnd
+    
+    <b>Preconditions:</b>
+    
+    <ul>
+    <li> The y-axis must be longer than the kernel radius: <tt>h > std::max(kernel.right(), -kernel.left())</tt>.
+    <li> If <tt>border == BORDER_TREATMENT_CLIP</tt>: The sum of kernel elements must be != 0.
+    </ul>
+*/
+doxygen_overloaded_function(template <...> void separableConvolveY)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+void separableConvolveY(SrcIterator supperleft,
+                        SrcIterator slowerright, SrcAccessor sa,
+                        DestIterator dupperleft, DestAccessor da,
+                        KernelIterator ik, KernelAccessor ka,
+                        int kleft, int kright, BorderTreatmentMode border)
+{
+    vigra_precondition(kleft <= 0,
+                 "separableConvolveY(): kleft must be <= 0.\n");
+    vigra_precondition(kright >= 0,
+                 "separableConvolveY(): kright must be >= 0.\n");
+
+    int w = slowerright.x - supperleft.x;
+    int h = slowerright.y - supperleft.y;
+
+    vigra_precondition(h >= std::max(kright, -kleft) + 1,
+                 "separableConvolveY(): kernel longer than line\n");
+
+    int x;
+
+    for(x=0; x<w; ++x, ++supperleft.x, ++dupperleft.x)
+    {
+        typename SrcIterator::column_iterator cs = supperleft.columnIterator();
+        typename DestIterator::column_iterator cd = dupperleft.columnIterator();
+
+        convolveLine(cs, cs+h, sa, cd, da,
+                     ik, ka, kleft, kright, border);
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+inline void
+separableConvolveY(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator, DestAccessor> dest,
+                   tuple5<KernelIterator, KernelAccessor,
+                         int, int, BorderTreatmentMode> kernel)
+{
+    separableConvolveY(src.first, src.second, src.third,
+                       dest.first, dest.second,
+                       kernel.first, kernel.second,
+                       kernel.third, kernel.fourth, kernel.fifth);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class T3>
+inline void
+separableConvolveY(MultiArrayView<2, T1, S1> const & src,
+                   MultiArrayView<2, T2, S2> dest,
+                   Kernel1D<T3> const & kernel)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "separableConvolveY(): shape mismatch between input and output.");
+    separableConvolveY(srcImageRange(src),
+                       destImage(dest), kernel1d(kernel));
+}
+
+//@}
+
+/********************************************************/
+/*                                                      */
+/*                      Kernel1D                        */
+/*                                                      */
+/********************************************************/
+
+/** \brief Generic 1 dimensional convolution kernel.
+
+    This kernel may be used for convolution of 1 dimensional signals or for
+    separable convolution of multidimensional signals.
+
+    Convolution functions access the kernel via a 1 dimensional random access
+    iterator which they get by calling \ref center(). This iterator
+    points to the center of the kernel. The kernel's size is given by its left() (<=0)
+    and right() (>= 0) methods. The desired border treatment mode is
+    returned by borderTreatment().
+
+    The different init functions create a kernel with the specified
+    properties. The kernel's value_type must be a linear space, i.e. it
+    must define multiplication with doubles and NumericTraits.
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/separableconvolution.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);
+    ...
+
+    // define Gaussian kernel with std. deviation 3.0
+    Kernel1D kernel;
+    kernel.initGaussian(3.0);
+
+    // apply 1D kernel along the x-axis
+    separableConvolveX(src, dest, kernel);
+    \endcode
+
+    \deprecatedUsage{Kernel1D}
+    The kernel defines a factory function kernel1d() to create an argument object
+    (see \ref KernelArgumentObjectFactories).
+    \code
+    vigra::FImage src(w,h), dest(w,h);
+    ...
+
+    // define Gaussian kernel with std. deviation 3.0
+    vigra::Kernel1D kernel;
+    kernel.initGaussian(3.0);
+
+    vigra::separableConvolveX(srcImageRange(src), destImage(dest), kernel1d(kernel));
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    value_type v = vigra::NumericTraits<value_type>::one(); // if norm is not
+                                                            // given explicitly
+    double d;
+
+    v = d * v;
+    \endcode
+    \deprecatedEnd
+*/
+
+template <class ARITHTYPE = double>
+class Kernel1D
+{
+  public:
+    typedef ArrayVector<ARITHTYPE> InternalVector;
+
+        /** the kernel's value type
+        */
+    typedef typename InternalVector::value_type value_type;
+
+        /** the kernel's reference type
+        */
+    typedef typename InternalVector::reference reference;
+
+        /** the kernel's const reference type
+        */
+    typedef typename InternalVector::const_reference const_reference;
+
+        /** deprecated -- use Kernel1D::iterator
+        */
+    typedef typename InternalVector::iterator Iterator;
+
+        /** 1D random access iterator over the kernel's values
+        */
+    typedef typename InternalVector::iterator iterator;
+
+        /** const 1D random access iterator over the kernel's values
+        */
+    typedef typename InternalVector::const_iterator const_iterator;
+
+        /** the kernel's accessor
+        */
+    typedef StandardAccessor<ARITHTYPE> Accessor;
+
+        /** the kernel's const accessor
+        */
+    typedef StandardConstAccessor<ARITHTYPE> ConstAccessor;
+
+    struct InitProxy
+    {
+        InitProxy(Iterator i, int count, value_type & norm)
+        : iter_(i), base_(i),
+          count_(count), sum_(count),
+          norm_(norm)
+        {}
+
+        ~InitProxy() 
+#ifndef _MSC_VER
+             throw(PreconditionViolation)
+#endif
+        {
+            vigra_precondition(count_ == 1 || count_ == sum_,
+                  "Kernel1D::initExplicitly(): "
+                  "Wrong number of init values.");
+        }
+
+        InitProxy & operator,(value_type const & v)
+        {
+            if(sum_ == count_) 
+                norm_ = *iter_;
+
+            norm_ += v;
+
+            --count_;
+
+            if(count_ > 0)
+            {
+                ++iter_;
+                *iter_ = v;
+            }
+            return *this;
+        }
+
+        Iterator iter_, base_;
+        int count_, sum_;
+        value_type & norm_;
+    };
+
+    static value_type one() { return NumericTraits<value_type>::one(); }
+
+        /** Default constructor.
+            Creates a kernel of size 1 which would copy the signal
+            unchanged.
+        */
+    Kernel1D()
+    : kernel_(),
+      left_(0),
+      right_(0),
+      border_treatment_(BORDER_TREATMENT_REFLECT),
+      norm_(one())
+    {
+        kernel_.push_back(norm_);
+    }
+
+        /** Copy constructor.
+        */
+    Kernel1D(Kernel1D const & k)
+    : kernel_(k.kernel_),
+      left_(k.left_),
+      right_(k.right_),
+      border_treatment_(k.border_treatment_),
+      norm_(k.norm_)
+    {}
+
+        /** Construct from kernel with different element type, e.g. double => FixedPoint16.
+        */
+    template <class U>
+    Kernel1D(Kernel1D<U> const & k)
+    : kernel_(k.center()+k.left(), k.center()+k.right()+1),
+      left_(k.left()),
+      right_(k.right()),
+      border_treatment_(k.borderTreatment()),
+      norm_(k.norm())
+    {}
+    
+        /** Copy assignment.
+        */
+    Kernel1D & operator=(Kernel1D const & k)
+    {
+        if(this != &k)
+        {
+            left_ = k.left_;
+            right_ = k.right_;
+            border_treatment_ = k.border_treatment_;
+            norm_ = k.norm_;
+            kernel_ = k.kernel_;
+        }
+        return *this;
+    }
+
+        /** Initialization.
+            This initializes the kernel with the given constant. The norm becomes
+            v*size().
+
+            Instead of a single value an initializer list of length size()
+            can be used like this:
+
+            \code
+            vigra::Kernel1D<float> roberts_gradient_x;
+
+            roberts_gradient_x.initExplicitly(0, 1) = 1.0, -1.0;
+            \endcode
+
+            In this case, the norm will be set to the sum of the init values.
+            An initializer list of wrong length will result in a run-time error.
+        */
+    InitProxy operator=(value_type const & v)
+    {
+        int size = right_ - left_ + 1;
+        for(unsigned int i=0; i<kernel_.size(); ++i) kernel_[i] = v;
+        norm_ = (double)size*v;
+
+        return InitProxy(kernel_.begin(), size, norm_);
+    }
+
+        /** Destructor.
+        */
+    ~Kernel1D()
+    {}
+
+        /**
+            Init as a sampled Gaussian function. The radius of the kernel is
+            always 3*std_dev. '<tt>norm</tt>' denotes the sum of all bins of the kernel
+            (i.e. the kernel is corrected for the normalization error introduced
+             by windowing the Gaussian to a finite interval). However,
+            if <tt>norm</tt> is 0.0, the kernel is normalized to 1 by the analytic
+            expression for the Gaussian, and <b>no</b> correction for the windowing
+            error is performed. If <tt>windowRatio = 0.0</tt>, the radius of the filter
+            window is <tt>radius = round(3.0 * std_dev)</tt>, otherwise it is 
+            <tt>radius = round(windowRatio * std_dev)</tt> (where <tt>windowRatio > 0.0</tt>
+            is required).
+            
+            Precondition:
+            \code
+            std_dev >= 0.0
+            \endcode
+
+            Postconditions:
+            \code
+            1. left()  == -(int)(3.0*std_dev + 0.5)
+            2. right() ==  (int)(3.0*std_dev + 0.5)
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == norm
+            \endcode
+        */
+    void initGaussian(double std_dev, value_type norm, double windowRatio = 0.0);
+
+        /** Init as a Gaussian function with norm 1.
+         */
+    void initGaussian(double std_dev)
+    {
+        initGaussian(std_dev, one());
+    }
+
+
+        /**
+            Init as Lindeberg's discrete analog of the Gaussian function. The radius of the kernel is
+            always 3*std_dev. 'norm' denotes the sum of all bins of the kernel.
+
+            Precondition:
+            \code
+            std_dev >= 0.0
+            \endcode
+
+            Postconditions:
+            \code
+            1. left()  == -(int)(3.0*std_dev + 0.5)
+            2. right() ==  (int)(3.0*std_dev + 0.5)
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == norm
+            \endcode
+        */
+    void initDiscreteGaussian(double std_dev, value_type norm);
+
+        /** Init as a Lindeberg's discrete analog of the Gaussian function
+            with norm 1.
+         */
+    void initDiscreteGaussian(double std_dev)
+    {
+        initDiscreteGaussian(std_dev, one());
+    }
+
+        /**
+            Init as a Gaussian derivative of order '<tt>order</tt>'.
+            The radius of the kernel is always <tt>3*std_dev + 0.5*order</tt>.
+            '<tt>norm</tt>' denotes the norm of the kernel so that the
+            following condition is fulfilled:
+
+            \f[ \sum_{i=left()}^{right()}
+                         \frac{(-i)^{order}kernel[i]}{order!} = norm
+            \f]
+
+            Thus, the kernel will be corrected for the error introduced
+            by windowing the Gaussian to a finite interval. However,
+            if <tt>norm</tt> is 0.0, the kernel is normalized to 1 by the analytic
+            expression for the Gaussian derivative, and <b>no</b> correction for the
+            windowing error is performed. If <tt>windowRatio = 0.0</tt>, the radius 
+            of the filter window is <tt>radius = round(3.0 * std_dev + 0.5 * order)</tt>, 
+            otherwise it is <tt>radius = round(windowRatio * std_dev)</tt> (where 
+            <tt>windowRatio > 0.0</tt> is required).
+
+            Preconditions:
+            \code
+            1. std_dev >= 0.0
+            2. order   >= 1
+            \endcode
+
+            Postconditions:
+            \code
+            1. left()  == -(int)(3.0*std_dev + 0.5*order + 0.5)
+            2. right() ==  (int)(3.0*std_dev + 0.5*order + 0.5)
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == norm
+            \endcode
+        */
+    void initGaussianDerivative(double std_dev, int order, value_type norm, double windowRatio = 0.0);
+
+        /** Init as a Gaussian derivative with norm 1.
+         */
+    void initGaussianDerivative(double std_dev, int order)
+    {
+        initGaussianDerivative(std_dev, order, one());
+    }
+
+        /**
+            Init an optimal 3-tap smoothing filter.
+            The filter values are 
+            
+            \code
+            [0.216, 0.568, 0.216]
+            \endcode
+            
+            These values are optimal in the sense that the 3x3 filter obtained by separable application
+            of this filter is the best possible 3x3 approximation to a Gaussian filter.
+            The equivalent Gaussian has sigma = 0.680.
+ 
+            Postconditions:
+            \code
+            1. left()  == -1
+            2. right() ==  1
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+        */
+    void initOptimalSmoothing3()
+    {
+        this->initExplicitly(-1, 1) = 0.216, 0.568, 0.216;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+        /**
+            Init an optimal 3-tap smoothing filter to be used in the context of first derivative computation.
+            This filter must be used in conjunction with the symmetric difference filter (see initSymmetricDifference()), 
+            such that the difference filter is applied along one dimension, and the smoothing filter along the other.
+            The filter values are 
+            
+            \code
+            [0.224365, 0.55127, 0.224365]
+            \endcode
+            
+            These values are optimal in the sense that the 3x3 filter obtained by combining 
+            this filter with the symmetric difference is the best possible 3x3 approximation to a 
+            Gaussian first derivative filter. The equivalent Gaussian has sigma = 0.675.
+ 
+            Postconditions:
+            \code
+            1. left()  == -1
+            2. right() ==  1
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+        */
+    void initOptimalFirstDerivativeSmoothing3()
+    {
+        this->initExplicitly(-1, 1) = 0.224365, 0.55127, 0.224365;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+        /**
+            Init an optimal 3-tap smoothing filter to be used in the context of second derivative computation.
+            This filter must be used in conjunction with the 3-tap second difference filter (see initSecondDifference3()), 
+            such that the difference filter is applied along one dimension, and the smoothing filter along the other.
+            The filter values are 
+            
+            \code
+            [0.13, 0.74, 0.13]
+            \endcode
+            
+            These values are optimal in the sense that the 3x3 filter obtained by combining 
+            this filter with the 3-tap second difference is the best possible 3x3 approximation to a 
+            Gaussian second derivative filter. The equivalent Gaussian has sigma = 0.433.
+ 
+            Postconditions:
+            \code
+            1. left()  == -1
+            2. right() ==  1
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+        */
+    void initOptimalSecondDerivativeSmoothing3()
+    {
+        this->initExplicitly(-1, 1) = 0.13, 0.74, 0.13;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+        /**
+            Init an optimal 5-tap smoothing filter.
+            The filter values are 
+            
+            \code
+            [0.03134, 0.24, 0.45732, 0.24, 0.03134]
+            \endcode
+            
+            These values are optimal in the sense that the 5x5 filter obtained by separable application
+            of this filter is the best possible 5x5 approximation to a Gaussian filter.
+            The equivalent Gaussian has sigma = 0.867.
+ 
+            Postconditions:
+            \code
+            1. left()  == -2
+            2. right() ==  2
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+        */
+    void initOptimalSmoothing5()
+    {
+        this->initExplicitly(-2, 2) = 0.03134, 0.24, 0.45732, 0.24, 0.03134;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+        /**
+            Init an optimal 5-tap smoothing filter to be used in the context of first derivative computation.
+           This filter must be used in conjunction with the optimal 5-tap first derivative filter 
+           (see initOptimalFirstDerivative5()),  such that the derivative filter is applied along one dimension, 
+           and the smoothing filter along the other. The filter values are 
+            
+            \code
+            [0.04255, 0.241, 0.4329, 0.241, 0.04255]
+            \endcode
+            
+            These values are optimal in the sense that the 5x5 filter obtained by combining 
+            this filter with the optimal 5-tap first derivative is the best possible 5x5 approximation to a 
+            Gaussian first derivative filter. The equivalent Gaussian has sigma = 0.906.
+ 
+            Postconditions:
+            \code
+            1. left()  == -2
+            2. right() ==  2
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+        */
+    void initOptimalFirstDerivativeSmoothing5()
+    {
+        this->initExplicitly(-2, 2) = 0.04255, 0.241, 0.4329, 0.241, 0.04255;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+        /**
+            Init an optimal 5-tap smoothing filter to be used in the context of second derivative computation.
+           This filter must be used in conjunction with the optimal 5-tap second derivative filter 
+           (see initOptimalSecondDerivative5()), such that the derivative filter is applied along one dimension, 
+           and the smoothing filter along the other. The filter values are 
+            
+            \code
+            [0.0243, 0.23556, 0.48028, 0.23556, 0.0243]
+            \endcode
+            
+            These values are optimal in the sense that the 5x5 filter obtained by combining 
+            this filter with the optimal 5-tap second derivative is the best possible 5x5 approximation to a 
+            Gaussian second derivative filter. The equivalent Gaussian has sigma = 0.817.
+ 
+            Postconditions:
+            \code
+            1. left()  == -2
+            2. right() ==  2
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+        */
+    void initOptimalSecondDerivativeSmoothing5()
+    {
+        this->initExplicitly(-2, 2) = 0.0243, 0.23556, 0.48028, 0.23556, 0.0243;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+        /**
+            Init a 5-tap filter as defined by Peter Burt in the context of pyramid creation.
+            The filter values are
+            
+            \code
+            [a, 0.25, 0.5-2*a, 0.25, a]
+            \endcode
+            
+            The default <tt>a = 0.04785</tt> is optimal in the sense that it minimizes the difference
+            to a true Gaussian filter (which would have sigma = 0.975). For other values of <tt>a</tt>, the scale 
+            of the most similar Gaussian can be approximated by
+            
+            \code
+            sigma = 5.1 * a + 0.731
+            \endcode
+ 
+            Preconditions:
+            \code
+            0 <= a <= 0.125
+            \endcode
+
+            Postconditions:
+            \code
+            1. left()  == -2
+            2. right() ==  2
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+        */
+    void initBurtFilter(double a = 0.04785)
+    {
+        vigra_precondition(a >= 0.0 && a <= 0.125,
+            "Kernel1D::initBurtFilter(): 0 <= a <= 0.125 required.");
+        this->initExplicitly(-2, 2) = a, 0.25, 0.5 - 2.0*a, 0.25, a;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+        /**
+            Init as a Binomial filter. 'norm' denotes the sum of all bins
+            of the kernel.
+
+            Precondition:
+            \code
+            radius   >= 0
+            \endcode
+
+            Postconditions:
+            \code
+            1. left()  == -radius
+            2. right() ==  radius
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == norm
+            \endcode
+        */
+    void initBinomial(int radius, value_type norm);
+
+        /** Init as a Binomial filter with norm 1.
+         */
+    void initBinomial(int radius)
+    {
+        initBinomial(radius, one());
+    }
+
+        /**
+            Init as an Averaging filter. 'norm' denotes the sum of all bins
+            of the kernel. The window size is (2*radius+1) * (2*radius+1)
+
+            Precondition:
+            \code
+            radius   >= 0
+            \endcode
+
+            Postconditions:
+            \code
+            1. left()  == -radius
+            2. right() ==  radius
+            3. borderTreatment() == BORDER_TREATMENT_CLIP
+            4. norm() == norm
+            \endcode
+        */
+    void initAveraging(int radius, value_type norm);
+
+        /** Init as an Averaging filter with norm 1.
+         */
+    void initAveraging(int radius)
+    {
+        initAveraging(radius, one());
+    }
+
+        /**
+            Init as a symmetric gradient filter of the form
+            <TT>[ 0.5 * norm, 0.0 * norm, -0.5 * norm]</TT>
+           
+            <b>Deprecated</b>. Use initSymmetricDifference() instead.
+
+            Postconditions:
+            \code
+            1. left()  == -1
+            2. right() ==  1
+            3. borderTreatment() == BORDER_TREATMENT_REPEAT
+            4. norm() == norm
+            \endcode
+        */
+    void initSymmetricGradient(value_type norm )
+    {
+        initSymmetricDifference(norm);
+        setBorderTreatment(BORDER_TREATMENT_REPEAT);
+    }
+
+        /** Init as a symmetric gradient filter with norm 1.
+           
+           <b>Deprecated</b>. Use initSymmetricDifference() instead.
+         */
+    void initSymmetricGradient()
+    {
+        initSymmetricGradient(one());
+    }
+
+        /** Init as the 2-tap forward difference filter.
+             The filter values are
+             
+            \code
+            [1.0, -1.0]
+            \endcode
+             
+            (note that filters are reflected by the convolution algorithm,
+             and we get a forward difference after reflection).
+
+            Postconditions:
+            \code
+            1. left()  == -1
+            2. right() ==  0
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+          */
+    void initForwardDifference()
+    {
+        this->initExplicitly(-1, 0) = 1.0, -1.0;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+        /** Init as the 2-tap backward difference filter.
+            The filter values are
+             
+            \code
+            [1.0, -1.0]
+            \endcode
+             
+            (note that filters are reflected by the convolution algorithm,
+             and we get a forward difference after reflection).
+
+            Postconditions:
+            \code
+            1. left()  == 0
+            2. right() ==  1
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+          */
+    void initBackwardDifference()
+    {
+        this->initExplicitly(0, 1) = 1.0, -1.0;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+    void initSymmetricDifference(value_type norm );
+
+        /** Init as the 3-tap symmetric difference filter
+            The filter values are
+             
+            \code
+            [0.5, 0, -0.5]
+            \endcode
+
+            Postconditions:
+            \code
+            1. left()  == -1
+            2. right() ==  1
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+          */
+    void initSymmetricDifference()
+    {
+        initSymmetricDifference(one());
+    }
+
+        /**
+            Init the 3-tap second difference filter.
+            The filter values are
+             
+            \code
+            [1, -2, 1]
+            \endcode
+
+            Postconditions:
+            \code
+            1. left()  == -1
+            2. right() ==  1
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1
+            \endcode
+        */
+    void initSecondDifference3()
+    {
+        this->initExplicitly(-1, 1) = 1.0, -2.0, 1.0;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+    
+        /**
+            Init an optimal 5-tap first derivative filter.
+            This filter must be used in conjunction with the corresponding 5-tap smoothing filter 
+            (see initOptimalFirstDerivativeSmoothing5()), such that the derivative filter is applied along one dimension,
+            and the smoothing filter along the other.
+            The filter values are 
+            
+            \code
+            [0.1, 0.3, 0.0, -0.3, -0.1]
+            \endcode
+            
+            These values are optimal in the sense that the 5x5 filter obtained by combining 
+            this filter with the corresponding 5-tap smoothing filter is the best possible 5x5 approximation to a 
+            Gaussian first derivative filter. The equivalent Gaussian has sigma = 0.906.
+            
+            If the filter is instead separably combined with itself, an almost optimal approximation of the
+            mixed second Gaussian derivative at scale sigma = 0.899 results.
+ 
+            Postconditions:
+            \code
+            1. left()  == -2
+            2. right() ==  2
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+        */
+    void initOptimalFirstDerivative5()
+    {
+        this->initExplicitly(-2, 2) = 0.1, 0.3, 0.0, -0.3, -0.1;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+    
+        /**
+            Init an optimal 5-tap second derivative filter.
+            This filter must be used in conjunction with the corresponding 5-tap smoothing filter 
+            (see initOptimalSecondDerivativeSmoothing5()), such that the derivative filter is applied along one dimension,
+            and the smoothing filter along the other.
+            The filter values are 
+            
+            \code
+            [0.22075, 0.117, -0.6755, 0.117, 0.22075]
+            \endcode
+            
+            These values are optimal in the sense that the 5x5 filter obtained by combining 
+            this filter with the corresponding 5-tap smoothing filter is the best possible 5x5 approximation to a 
+            Gaussian second derivative filter. The equivalent Gaussian has sigma = 0.817.
+ 
+            Postconditions:
+            \code
+            1. left()  == -2
+            2. right() ==  2
+            3. borderTreatment() == BORDER_TREATMENT_REFLECT
+            4. norm() == 1.0
+            \endcode
+        */
+    void initOptimalSecondDerivative5()
+    {
+        this->initExplicitly(-2, 2) = 0.22075, 0.117, -0.6755, 0.117, 0.22075;
+        this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
+    }
+
+        /** Init the kernel by an explicit initializer list.
+            The left and right boundaries of the kernel must be passed.
+            A comma-separated initializer list is given after the assignment
+            operator. This function is used like this:
+
+            \code
+            // define horizontal Roberts filter
+            vigra::Kernel1D<float> roberts_gradient_x;
+
+            roberts_gradient_x.initExplicitly(0, 1) = 1.0, -1.0;
+            \endcode
+
+            The norm is set to the sum of the initializer values. If the wrong number of
+            values is given, a run-time error results. It is, however, possible to give
+            just one initializer. This creates an averaging filter with the given constant:
+
+            \code
+            vigra::Kernel1D<float> average5x1;
+
+            average5x1.initExplicitly(-2, 2) = 1.0/5.0;
+            \endcode
+
+            Here, the norm is set to value*size().
+
+            <b> Preconditions:</b>
+
+            \code
+
+            1. left <= 0
+            2. right >= 0
+            3. the number of values in the initializer list
+               is 1 or equals the size of the kernel.
+            \endcode
+        */
+    Kernel1D & initExplicitly(int left, int right)
+    {
+        vigra_precondition(left <= 0,
+                     "Kernel1D::initExplicitly(): left border must be <= 0.");
+        vigra_precondition(right >= 0,
+                     "Kernel1D::initExplicitly(): right border must be >= 0.");
+
+        right_ = right;
+        left_ = left;
+
+        kernel_.resize(right - left + 1);
+
+        return *this;
+    }
+
+        /** Get iterator to center of kernel
+
+            Postconditions:
+            \code
+
+            center()[left()] ... center()[right()] are valid kernel positions
+            \endcode
+        */
+    iterator center()
+    {
+        return kernel_.begin() - left();
+    }
+
+    const_iterator center() const
+    {
+        return kernel_.begin() - left();
+    }
+
+        /** Access kernel value at specified location.
+
+            Preconditions:
+            \code
+
+            left() <= location <= right()
+            \endcode
+        */
+    reference operator[](int location)
+    {
+        return kernel_[location - left()];
+    }
+
+    const_reference operator[](int location) const
+    {
+        return kernel_[location - left()];
+    }
+
+        /** left border of kernel (inclusive), always <= 0
+        */
+    int left() const { return left_; }
+
+        /** right border of kernel (inclusive), always >= 0
+        */
+    int right() const { return right_; }
+
+        /** size of kernel (right() - left() + 1)
+        */
+    int size() const { return right_ - left_ + 1; }
+
+        /** current border treatment mode
+        */
+    BorderTreatmentMode borderTreatment() const
+    { return border_treatment_; }
+
+        /** Set border treatment mode.
+        */
+    void setBorderTreatment( BorderTreatmentMode new_mode)
+    { border_treatment_ = new_mode; }
+
+        /** norm of kernel
+        */
+    value_type norm() const { return norm_; }
+
+        /** set a new norm and normalize kernel, use the normalization formula
+            for the given <tt>derivativeOrder</tt>.
+        */
+    void
+    normalize(value_type norm, unsigned int derivativeOrder = 0, double offset = 0.0);
+
+        /** normalize kernel to norm 1.
+        */
+    void
+    normalize()
+    {
+        normalize(one());
+    }
+
+        /** get a const accessor
+        */
+    ConstAccessor accessor() const { return ConstAccessor(); }
+
+        /** get an accessor
+        */
+    Accessor accessor() { return Accessor(); }
+
+  private:
+    InternalVector kernel_;
+    int left_, right_;
+    BorderTreatmentMode border_treatment_;
+    value_type norm_;
+};
+
+template <class ARITHTYPE>
+void Kernel1D<ARITHTYPE>::normalize(value_type norm,
+                          unsigned int derivativeOrder,
+                          double offset)
+{
+    typedef typename NumericTraits<value_type>::RealPromote TmpType;
+
+    // find kernel sum
+    Iterator k = kernel_.begin();
+    TmpType sum = NumericTraits<TmpType>::zero();
+
+    if(derivativeOrder == 0)
+    {
+        for(; k < kernel_.end(); ++k)
+        {
+            sum += *k;
+        }
+    }
+    else
+    {
+        unsigned int faculty = 1;
+        for(unsigned int i = 2; i <= derivativeOrder; ++i)
+            faculty *= i;
+        for(double x = left() + offset; k < kernel_.end(); ++x, ++k)
+        {
+            sum = TmpType(sum + *k * VIGRA_CSTD::pow(-x, int(derivativeOrder)) / faculty);
+        }
+    }
+
+    vigra_precondition(sum != NumericTraits<value_type>::zero(),
+                    "Kernel1D<ARITHTYPE>::normalize(): "
+                    "Cannot normalize a kernel with sum = 0");
+    // normalize
+    sum = norm / sum;
+    k = kernel_.begin();
+    for(; k != kernel_.end(); ++k)
+    {
+        *k = *k * sum;
+    }
+
+    norm_ = norm;
+}
+
+/***********************************************************************/
+
+template <class ARITHTYPE>
+void
+Kernel1D<ARITHTYPE>::initGaussian(double std_dev,
+                                  value_type norm, 
+                                  double windowRatio)
+{
+    vigra_precondition(std_dev >= 0.0,
+              "Kernel1D::initGaussian(): Standard deviation must be >= 0.");
+    vigra_precondition(windowRatio >= 0.0,
+              "Kernel1D::initGaussian(): windowRatio must be >= 0.");
+
+    if(std_dev > 0.0)
+    {
+        Gaussian<ARITHTYPE> gauss((ARITHTYPE)std_dev);
+
+        // first calculate required kernel sizes
+        int radius;
+        if (windowRatio == 0.0)
+            radius = (int)(3.0 * std_dev + 0.5);
+        else
+            radius = (int)(windowRatio * std_dev + 0.5);
+        if(radius == 0)
+            radius = 1;
+
+        // allocate the kernel
+        kernel_.erase(kernel_.begin(), kernel_.end());
+        kernel_.reserve(radius*2+1);
+
+        for(ARITHTYPE x = -(ARITHTYPE)radius; x <= (ARITHTYPE)radius; ++x)
+        {
+            kernel_.push_back(gauss(x));
+        }
+        left_ = -radius;
+        right_ = radius;
+    }
+    else
+    {
+        kernel_.erase(kernel_.begin(), kernel_.end());
+        kernel_.push_back(1.0);
+        left_ = 0;
+        right_ = 0;
+    }
+
+    if(norm != 0.0)
+        normalize(norm);
+    else
+        norm_ = 1.0;
+
+    // best border treatment for Gaussians is BORDER_TREATMENT_REFLECT
+    border_treatment_ = BORDER_TREATMENT_REFLECT;
+}
+
+/***********************************************************************/
+
+template <class ARITHTYPE>
+void
+Kernel1D<ARITHTYPE>::initDiscreteGaussian(double std_dev,
+                                          value_type norm)
+{
+    vigra_precondition(std_dev >= 0.0,
+              "Kernel1D::initDiscreteGaussian(): Standard deviation must be >= 0.");
+
+    if(std_dev > 0.0)
+    {
+        // first calculate required kernel sizes
+        int radius = (int)(3.0*std_dev + 0.5);
+        if(radius == 0)
+            radius = 1;
+
+        double f = 2.0 / std_dev / std_dev;
+
+        // allocate the working array
+        int maxIndex = (int)(2.0 * (radius + 5.0 * VIGRA_CSTD::sqrt((double)radius)) + 0.5);
+        InternalVector warray(maxIndex+1);
+        warray[maxIndex] = 0.0;
+        warray[maxIndex-1] = 1.0;
+
+        for(int i = maxIndex-2; i >= radius; --i)
+        {
+            warray[i] = warray[i+2] + f * (i+1) * warray[i+1];
+            if(warray[i] > 1.0e40)
+            {
+                warray[i+1] /= warray[i];
+                warray[i] = 1.0;
+            }
+        }
+
+        // the following rescaling ensures that the numbers stay in a sensible range
+        // during the rest of the iteration, so no other rescaling is needed
+        double er = VIGRA_CSTD::exp(-radius*radius / (2.0*std_dev*std_dev));
+        warray[radius+1] = er * warray[radius+1] / warray[radius];
+        warray[radius] = er;
+
+        for(int i = radius-1; i >= 0; --i)
+        {
+            warray[i] = warray[i+2] + f * (i+1) * warray[i+1];
+            er += warray[i];
+        }
+
+        double scale = norm / (2*er - warray[0]);
+
+        initExplicitly(-radius, radius);
+        iterator c = center();
+
+        for(int i=0; i<=radius; ++i)
+        {
+            c[i] = c[-i] = warray[i] * scale;
+        }
+    }
+    else
+    {
+        kernel_.erase(kernel_.begin(), kernel_.end());
+        kernel_.push_back(norm);
+        left_ = 0;
+        right_ = 0;
+    }
+
+    norm_ = norm;
+
+    // best border treatment for Gaussians is BORDER_TREATMENT_REFLECT
+    border_treatment_ = BORDER_TREATMENT_REFLECT;
+}
+
+/***********************************************************************/
+
+template <class ARITHTYPE>
+void
+Kernel1D<ARITHTYPE>::initGaussianDerivative(double std_dev,
+                                            int order,
+                                            value_type norm, 
+                                            double windowRatio)
+{
+    vigra_precondition(order >= 0,
+              "Kernel1D::initGaussianDerivative(): Order must be >= 0.");
+
+    if(order == 0)
+    {
+        initGaussian(std_dev, norm, windowRatio);
+        return;
+    }
+    
+    vigra_precondition(std_dev > 0.0,
+              "Kernel1D::initGaussianDerivative(): "
+              "Standard deviation must be > 0.");
+    vigra_precondition(windowRatio >= 0.0,
+              "Kernel1D::initGaussianDerivative(): windowRatio must be >= 0.");
+
+    Gaussian<ARITHTYPE> gauss((ARITHTYPE)std_dev, order);
+
+    // first calculate required kernel sizes
+    int radius;
+    if(windowRatio == 0.0)
+        radius = (int)(3.0 * std_dev + 0.5 * order + 0.5);
+    else
+        radius = (int)(windowRatio * std_dev + 0.5);
+    if(radius == 0)
+        radius = 1;
+
+    // allocate the kernels
+    kernel_.clear();
+    kernel_.reserve(radius*2+1);
+
+    // fill the kernel and calculate the DC component
+    // introduced by truncation of the Gaussian
+    ARITHTYPE dc = 0.0;
+    for(ARITHTYPE x = -(ARITHTYPE)radius; x <= (ARITHTYPE)radius; ++x)
+    {
+        kernel_.push_back(gauss(x));
+        dc += kernel_[kernel_.size()-1];
+    }
+    dc = ARITHTYPE(dc / (2.0*radius + 1.0));
+
+    // remove DC, but only if kernel correction is permitted by a non-zero
+    // value for norm
+    if(norm != 0.0)
+    {
+        for(unsigned int i=0; i < kernel_.size(); ++i)
+        {
+            kernel_[i] -= dc;
+        }
+    }
+
+    left_ = -radius;
+    right_ = radius;
+
+    if(norm != 0.0)
+        normalize(norm, order);
+    else
+        norm_ = 1.0;
+
+    // best border treatment for Gaussian derivatives is
+    // BORDER_TREATMENT_REFLECT
+    border_treatment_ = BORDER_TREATMENT_REFLECT;
+}
+
+/***********************************************************************/
+
+template <class ARITHTYPE>
+void
+Kernel1D<ARITHTYPE>::initBinomial(int radius,
+                                  value_type norm)
+{
+    vigra_precondition(radius > 0,
+              "Kernel1D::initBinomial(): Radius must be > 0.");
+
+    // allocate the kernel
+    InternalVector(radius*2+1).swap(kernel_);
+    typename InternalVector::iterator x = kernel_.begin() + radius;
+
+    // fill kernel
+    x[radius] = norm;
+    for(int j=radius-1; j>=-radius; --j)
+    {
+        x[j] = 0.5 * x[j+1];
+        for(int i=j+1; i<radius; ++i)
+        {
+            x[i] = 0.5 * (x[i] + x[i+1]);
+        }
+        x[radius] *= 0.5;
+    }
+
+    left_ = -radius;
+    right_ = radius;
+    norm_ = norm;
+
+    // best border treatment for Binomial is BORDER_TREATMENT_REFLECT
+    border_treatment_ = BORDER_TREATMENT_REFLECT;
+}
+
+/***********************************************************************/
+
+template <class ARITHTYPE>
+void
+Kernel1D<ARITHTYPE>::initAveraging(int radius,
+                                   value_type norm)
+{
+    vigra_precondition(radius > 0,
+              "Kernel1D::initAveraging(): Radius must be > 0.");
+
+    // calculate scaling
+    double scale = 1.0 / (radius * 2 + 1);
+
+    // normalize
+    kernel_.erase(kernel_.begin(), kernel_.end());
+    kernel_.reserve(radius*2+1);
+
+    for(int i=0; i<=radius*2+1; ++i)
+    {
+        kernel_.push_back(scale * norm);
+    }
+
+    left_ = -radius;
+    right_ = radius;
+    norm_ = norm;
+
+    // best border treatment for Averaging is BORDER_TREATMENT_CLIP
+    border_treatment_ = BORDER_TREATMENT_CLIP;
+}
+
+/***********************************************************************/
+
+template <class ARITHTYPE>
+void
+Kernel1D<ARITHTYPE>::initSymmetricDifference(value_type norm)
+{
+    kernel_.erase(kernel_.begin(), kernel_.end());
+    kernel_.reserve(3);
+
+    kernel_.push_back(ARITHTYPE(0.5 * norm));
+    kernel_.push_back(ARITHTYPE(0.0 * norm));
+    kernel_.push_back(ARITHTYPE(-0.5 * norm));
+
+    left_ = -1;
+    right_ = 1;
+    norm_ = norm;
+
+    // best border treatment for symmetric difference is
+    // BORDER_TREATMENT_REFLECT
+    border_treatment_ = BORDER_TREATMENT_REFLECT;
+}
+
+/**************************************************************/
+/*                                                            */
+/*         Argument object factories for Kernel1D             */
+/*                                                            */
+/*     (documentation: see vigra/convolution.hxx)             */
+/*                                                            */
+/**************************************************************/
+
+template <class KernelIterator, class KernelAccessor>
+inline
+tuple5<KernelIterator, KernelAccessor, int, int, BorderTreatmentMode>
+kernel1d(KernelIterator ik, KernelAccessor ka,
+       int kleft, int kright, BorderTreatmentMode border)
+{
+    return
+      tuple5<KernelIterator, KernelAccessor, int, int, BorderTreatmentMode>(
+                                                ik, ka, kleft, kright, border);
+}
+
+template <class T>
+inline
+tuple5<typename Kernel1D<T>::const_iterator, typename Kernel1D<T>::ConstAccessor,
+       int, int, BorderTreatmentMode>
+kernel1d(Kernel1D<T> const & k)
+
+{
+    return
+        tuple5<typename Kernel1D<T>::const_iterator, typename Kernel1D<T>::ConstAccessor,
+               int, int, BorderTreatmentMode>(
+                                     k.center(),
+                                     k.accessor(),
+                                     k.left(), k.right(),
+                                     k.borderTreatment());
+}
+
+template <class T>
+inline
+tuple5<typename Kernel1D<T>::const_iterator, typename Kernel1D<T>::ConstAccessor,
+       int, int, BorderTreatmentMode>
+kernel1d(Kernel1D<T> const & k, BorderTreatmentMode border)
+
+{
+    return
+        tuple5<typename Kernel1D<T>::const_iterator, typename Kernel1D<T>::ConstAccessor,
+               int, int, BorderTreatmentMode>(
+                                     k.center(),
+                                     k.accessor(),
+                                     k.left(), k.right(),
+                                     border);
+}
+
+
+} // namespace vigra
+
+#endif // VIGRA_SEPARABLECONVOLUTION_HXX
diff --git a/include/vigra/sifImport.hxx b/include/vigra/sifImport.hxx
new file mode 100644
index 0000000..77a66cf
--- /dev/null
+++ b/include/vigra/sifImport.hxx
@@ -0,0 +1,248 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2010 by Joachim Schleicher and Ullrich Koethe        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+/*                                                          
+ *  Opens an Andor .sif file as MultiImageView.             
+ *  The width, height and number of images are extracted    
+ *  from the ASCII encoded variable length header.          
+ *                                                          
+ *  Based on the Java-Code from                             
+ *  http://rsb.info.nih.gov/ij/plugins/open-sif.html        
+ *  written by                                              
+ *  L. Stirling Churchman (stirling at stanford.edu)        
+ *  Philippe Carl (pcarl at uni-muenster.de)                
+ *  Yoshiyuki Arai (arai at phys1.med.osaka-u.ac.jp)        
+ *                                                          
+ *  Currently tested SIF versions: 4.16.12005.0             
+ *                                 4.16.30001.0             
+ *                                 4. 6.    3.0             
+*/
+
+#ifndef VIGRA_SIFIMPORT_HXX
+#define VIGRA_SIFIMPORT_HXX
+
+#include <fstream>
+#include <cstring>
+#include <cstddef>
+#include <vector> 
+#include "multi_array.hxx"
+#include "array_vector.hxx"
+
+namespace vigra {
+ 
+ 
+ /** \addtogroup VigraSIFImport Import of Images from Andor Cameras
+
+    Read an Andor SIF file into a MultiArrayView.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                   SIFImportInfo                      */
+/*                                                      */
+/********************************************************/
+/** \brief Extracts image properties from an Andor SIF file header.
+
+See \ref readSIF() for a usage example. This object must be
+used to read the image header of an Andor SIF file
+and enquire its properties.
+
+<b>\#include</b> \<vigra/sifImport.hxx\><br>
+Namespace: vigra
+*/
+class SIFImportInfo
+{
+    public:
+        /** Construct SIFImportInfo object.
+
+            The header of the Andor SIF file \a filename is accessed to 
+            read the image properties. 
+            
+            \code
+            SIFImportInfo info(filename);
+            \endcode
+         */
+        VIGRA_EXPORT SIFImportInfo(const char* filename);
+
+        /** Get the width in pixels.
+         */
+        VIGRA_EXPORT int width() const;
+
+        /** Get the height in pixels.
+         */
+        VIGRA_EXPORT int height() const;
+
+        /** Get the stacksize, that is the number of 
+            images contained in the dataset.
+         */
+        VIGRA_EXPORT int stacksize() const;
+
+        /** Get the number of dimensions of the dataset represented by this info object.
+         */
+        VIGRA_EXPORT MultiArrayIndex numDimensions() const;
+
+        /** Get the shape of the dataset represented by this info object.
+         */
+        VIGRA_EXPORT ArrayVector<size_t> const & shape() const;
+
+        /** Get the shape (length) of the dataset along dimension \a dim.
+         */
+        VIGRA_EXPORT MultiArrayIndex shapeOfDimension(const int dim) const;
+
+        /** Get the offset to the beginning of the actual data.
+            Everything before this point belongs to the 
+            variable length header.
+         */
+        VIGRA_EXPORT std::ptrdiff_t getOffset() const;
+
+        /** Get the filename of this SIF object.
+         */
+        VIGRA_EXPORT const char * getFileName() const;
+
+        /** Output all information such as shutter, Temperature etc. 
+           as human readable output.
+          
+        <b> Usage:</b>
+        
+        <b>\#include</b> \<vigra/sifImport.hxx\><br>
+        Namespace: vigra
+        
+        \code
+        SIFImportInfo info(filename);
+        std::cout << info << std::endl; // print infos to the console
+
+        \endcode
+         */
+        VIGRA_EXPORT friend std::ostream& operator<<(std::ostream& os, const SIFImportInfo& info);
+
+    private:
+        const char* m_filename;
+        ArrayVector<size_t> m_dims;
+        std::ptrdiff_t m_offset;
+        int mod;
+        int left, right, bottom, top;
+        int xbin, ybin, xres, yres;
+        int headerlen;
+        double readout;
+        double temperature1, temperature2;
+        long long d;
+        std::string cycleTime, temperature, exposureTime, EMGain,
+        verticalShiftSpeed, version, model, originalFilename, preAmpGain;   
+        size_t filesize;
+    
+};
+
+
+
+
+    /** \brief Read the image data specified by the given \ref vigra::SIFImportInfo object
+                and write them into the given 'array'.
+                
+    The array must have the correct number of dimensions and shape for the dataset 
+    represented by 'info'. 
+    
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        void 
+        readSIF(const SIFImportInfo &info, MultiArrayView<3, float> array);
+    }
+    \endcode
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/sifImport.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    SIFImportInfo info(filename);
+
+    // create a 3D array of appropriate size
+    typedef MultiArray<3, float>::difference_type Shape;
+    MultiArray<3, float> in(Shape(info.width(), info.height(), info.stacksize()));
+
+    readSIF(info, in); 
+    \endcode
+*/
+VIGRA_EXPORT void readSIF(const SIFImportInfo &info, MultiArrayView<3, float> array);
+
+template <unsigned int N, class T, class S>
+void readSIF(const SIFImportInfo &info, MultiArrayView<N, T, S> array)
+{
+    vigra_precondition(false, "readSIF(): Destination array must be MultiArrayView<3, float>.");
+}
+
+inline void readSIF(const SIFImportInfo &info, MultiArrayView<3, float, UnstridedArrayTag> array)
+{
+    readSIF(info, MultiArrayView<3, float>(array));
+}
+
+/**
+    \brief Read parts of the image data from an Andor SIF file specified with an SIFImportInfo object
+    and write them into the MultiArray array.
+    
+    \code
+    SIFImportInfo info(filename);
+
+    // create a 3D array of appropriate size
+    MultiArray<3, float> in(Shape3(info.width(), info.height(), 1));
+
+    readBlock(info, Shape3(0,0,0), Shape3(w,h,1), im); // read the first frame only
+
+    \endcode
+*/
+VIGRA_EXPORT void readSIFBlock(const SIFImportInfo &info, Shape3 offset, Shape3 shape, MultiArrayView<3, float> array);
+
+template <unsigned int N, class T, class S>
+void readSIFBlock(const SIFImportInfo &info, Shape3 offset, Shape3 shape, MultiArrayView<N, T, S> array)
+{
+    vigra_precondition(false, "readSIFBlock(): Destination array must be MultiArrayView<3, float>.");
+}
+
+inline void readSIFBlock(const SIFImportInfo &info, Shape3 offset, Shape3 shape, MultiArrayView<3, float, UnstridedArrayTag> array)
+{
+    readSIFBlock(info, offset, shape, MultiArrayView<3, float>(array));
+}
+
+VIGRA_EXPORT std::ostream& operator<<(std::ostream& os, const SIFImportInfo& info);
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_SIFIMPORT_HXX
diff --git a/include/vigra/singular_value_decomposition.hxx b/include/vigra/singular_value_decomposition.hxx
new file mode 100644
index 0000000..86ddff3
--- /dev/null
+++ b/include/vigra/singular_value_decomposition.hxx
@@ -0,0 +1,565 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 2007 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_SINGULAR_VALUE_DECOMPOSITION_HXX
+#define VIGRA_SINGULAR_VALUE_DECOMPOSITION_HXX
+
+#include "matrix.hxx"
+#include "array_vector.hxx"
+
+
+namespace vigra
+{
+
+namespace linalg
+{
+
+   /** Singular Value Decomposition.
+       \ingroup MatrixAlgebra
+
+   For an m-by-n matrix \a A with m >= n, the singular value decomposition is
+   an m-by-n orthogonal matrix \a U, an n-by-n diagonal matrix S, and
+   an n-by-n orthogonal matrix \a V so that A = U*S*V'.
+
+   To save memory, this functions stores the matrix \a S in a column vector of
+   appropriate length (a diagonal matrix can be obtained by <tt>diagonalMatrix(S)</tt>).
+   The singular values, sigma[k] = S(k, 0), are ordered so that
+   sigma[0] >= sigma[1] >= ... >= sigma[n-1].
+
+   The singular value decomposition always exists, so this function will
+   never fail (except if the shapes of the argument matrices don't match).
+   The effective numerical rank of A is returned.
+
+    (Adapted from JAMA, a Java Matrix Library, developed jointly
+    by the Mathworks and NIST; see  http://math.nist.gov/javanumerics/jama).
+
+    <b>\#include</b> \<vigra/singular_value_decomposition.hxx\> or<br>
+    <b>\#include</b> \<vigra/linear_algebra.hxx\><br>
+    Namespaces: vigra and vigra::linalg
+   */
+template <class T, class C1, class C2, class C3, class C4>
+unsigned int
+singularValueDecomposition(MultiArrayView<2, T, C1> const & A,
+    MultiArrayView<2, T, C2> &U, MultiArrayView<2, T, C3> &S, MultiArrayView<2, T, C4> &V)
+{
+    typedef T Real;
+
+    const MultiArrayIndex rows = rowCount(A);
+    const MultiArrayIndex cols = columnCount(A);
+    vigra_precondition(rows >= cols,
+       "singularValueDecomposition(): Input matrix A must be rectangular with rowCount >= columnCount.");
+    vigra_precondition(rowCount(S) == cols && columnCount(S) == 1,
+       "singularValueDecomposition(): Output S must be column vector with rowCount == columnCount(A).");
+    vigra_precondition(rowCount(U) == rows && columnCount(U) == cols,
+       "singularValueDecomposition(): Output matrix U must have the same dimensions as input matrix A.");
+    vigra_precondition(rowCount(V) == cols && columnCount(V) == cols,
+       "singularValueDecomposition(): Output matrix V must be square with n = columnCount(A).");
+
+    MultiArrayIndex m = rows;
+    MultiArrayIndex n = cols;
+    MultiArrayIndex nu = n;
+
+    U.init(0.0);
+    S.init(0.0);
+    V.init(0.0);
+
+    ArrayVector<Real> e((unsigned int)n);
+    ArrayVector<Real> work((unsigned int)m);
+    Matrix<Real> a(A);
+    MultiArrayView<1, T, C3> s = S.bindOuter(0);
+
+    MultiArrayIndex i=0, j=0, k=0;
+
+    // Reduce a to bidiagonal form, storing the diagonal elements
+    // in s and the super-diagonal elements in e.
+    MultiArrayIndex nct = std::min(m-1,n);
+    MultiArrayIndex nrt = std::max((MultiArrayIndex)0,n-2);
+    for (k = 0; k < std::max(nct,nrt); ++k)
+    {
+        if (k < nct)
+        {
+            // Compute the transformation for the k-th column and
+            // place the k-th diagonal in s(k).
+            // Compute 2-norm of k-th column without under/overflow.
+            s(k) = 0.0;
+            for (i = k; i < m; ++i)
+            {
+               s(k) = hypot(s(k), a(i, k));
+            }
+            if (s(k) != 0.0)
+            {
+                if (a(k, k) < 0.0)
+                {
+                    s(k) = -s(k);
+                }
+                for (i = k; i < m; ++i)
+                {
+                   a(i, k) /= s(k);
+                }
+                a(k, k) += 1.0;
+            }
+            s(k) = -s(k);
+        }
+        for (j = k+1; j < n; ++j)
+        {
+            if ((k < nct) && (s(k) != 0.0))
+            {
+                // Apply the transformation.
+                Real t(0.0);
+                for (i = k; i < m; ++i)
+                {
+                    t += a(i, k)*a(i, j);
+                }
+                t = -t/a(k, k);
+                for (i = k; i < m; ++i)
+                {
+                    a(i, j) += t*a(i, k);
+                }
+            }
+
+            // Place the k-th row of a into e for the
+            // subsequent calculation of the row transformation.
+
+            e[j] = a(k, j);
+        }
+        if (k < nct)
+        {
+            // Place the transformation in U for subsequent back
+            // multiplication.
+
+            for (i = k; i < m; ++i)
+            {
+                U(i, k) = a(i, k);
+            }
+        }
+        if (k < nrt)
+        {
+            // Compute the k-th row transformation and place the
+            // k-th super-diagonal in e[k].
+            // Compute 2-norm without under/overflow.
+            e[k] = 0;
+            for (i = k+1; i < n; ++i)
+            {
+               e[k] = hypot(e[k],e[i]);
+            }
+            if (e[k] != 0.0)
+            {
+                if (e[k+1] < 0.0)
+                {
+                    e[k] = -e[k];
+                }
+                for (i = k+1; i < n; ++i)
+                {
+                    e[i] /= e[k];
+                }
+                e[k+1] += 1.0;
+            }
+            e[k] = -e[k];
+            if ((k+1 < m) & (e[k] != 0.0))
+            {
+                // Apply the transformation.
+                for (i = k+1; i < m; ++i)
+                {
+                    work[i] = 0.0;
+                }
+                for (j = k+1; j < n; ++j)
+                {
+                    for (i = k+1; i < m; ++i)
+                    {
+                        work[i] += e[j]*a(i, j);
+                    }
+                }
+                for (j = k+1; j < n; ++j)
+                {
+                    Real t(-e[j]/e[k+1]);
+                    for (i = k+1; i < m; ++i)
+                    {
+                        a(i, j) += t*work[i];
+                    }
+                }
+            }
+            // Place the transformation in V for subsequent
+            // back multiplication.
+            for (i = k+1; i < n; ++i)
+            {
+                V(i, k) = e[i];
+            }
+        }
+    }
+
+    // Set up the final bidiagonal matrix of order p.
+
+    MultiArrayIndex p = n;
+    if (nct < n)
+    {
+        s(nct) = a(nct, nct);
+    }
+    if (m < p)
+    {
+        s(p-1) = 0.0;
+    }
+    if (nrt+1 < p)
+    {
+        e[nrt] = a(nrt, p-1);
+    }
+    e[p-1] = 0.0;
+
+    // Generate U.
+    for (j = nct; j < nu; ++j)
+    {
+        for (i = 0; i < m; ++i)
+        {
+            U(i, j) = 0.0;
+        }
+        U(j, j) = 1.0;
+    }
+    for (k = nct-1; k >= 0; --k)
+    {
+        if (s(k) != 0.0)
+        {
+            for (j = k+1; j < nu; ++j)
+            {
+                Real t(0.0);
+                for (i = k; i < m; ++i)
+                {
+                    t += U(i, k)*U(i, j);
+                }
+                t = -t/U(k, k);
+                for (i = k; i < m; ++i)
+                {
+                    U(i, j) += t*U(i, k);
+                }
+            }
+            for (i = k; i < m; ++i )
+            {
+                U(i, k) = -U(i, k);
+            }
+            U(k, k) = 1.0 + U(k, k);
+            for (i = 0; i < k-1; ++i)
+            {
+                U(i, k) = 0.0;
+            }
+        }
+        else
+        {
+            for (i = 0; i < m; ++i)
+            {
+                U(i, k) = 0.0;
+            }
+            U(k, k) = 1.0;
+        }
+    }
+
+    // Generate V.
+    for (k = n-1; k >= 0; --k)
+    {
+        if ((k < nrt) & (e[k] != 0.0))
+        {
+            for (j = k+1; j < nu; ++j)
+            {
+                Real t(0.0);
+                for (i = k+1; i < n; ++i)
+                {
+                    t += V(i, k)*V(i, j);
+                }
+                t = -t/V(k+1, k);
+                for (i = k+1; i < n; ++i)
+                {
+                    V(i, j) += t*V(i, k);
+                }
+            }
+        }
+        for (i = 0; i < n; ++i)
+        {
+            V(i, k) = 0.0;
+        }
+        V(k, k) = 1.0;
+    }
+
+    // Main iteration loop for the singular values.
+
+    MultiArrayIndex pp = p-1;
+    int iter = 0;
+    Real eps = NumericTraits<Real>::epsilon()*2.0;
+    while (p > 0)
+    {
+        MultiArrayIndex k=0;
+        int kase=0;
+
+        // Here is where a test for too many iterations would go.
+
+        // This section of the program inspects for
+        // negligible elements in the s and e arrays.  On
+        // completion the variables kase and k are set as follows.
+
+        // kase = 1     if s(p) and e[k-1] are negligible and k<p
+        // kase = 2     if s(k) is negligible and k<p
+        // kase = 3     if e[k-1] is negligible, k<p, and
+        //              s(k), ..., s(p) are not negligible (qr step).
+        // kase = 4     if e(p-1) is negligible (convergence).
+
+        for (k = p-2; k >= -1; --k)
+        {
+            if (k == -1)
+            {
+                break;
+            }
+            if (abs(e[k]) <= eps*(abs(s(k)) + abs(s(k+1))))
+            {
+                e[k] = 0.0;
+                break;
+            }
+        }
+        if (k == p-2)
+        {
+            kase = 4;
+        }
+        else
+        {
+            MultiArrayIndex ks;
+            for (ks = p-1; ks >= k; --ks)
+            {
+                if (ks == k)
+                {
+                    break;
+                }
+                Real t( (ks != p ? abs(e[ks]) : 0.) +
+                        (ks != k+1 ? abs(e[ks-1]) : 0.));
+                if (abs(s(ks)) <= eps*t)
+                {
+                    s(ks) = 0.0;
+                    break;
+                }
+            }
+            if (ks == k)
+            {
+               kase = 3;
+            }
+            else if (ks == p-1)
+            {
+               kase = 1;
+            }
+            else
+            {
+               kase = 2;
+               k = ks;
+            }
+        }
+        ++k;
+
+        // Perform the task indicated by kase.
+
+        switch (kase)
+        {
+          case 1: // Deflate negligible s(p).
+          {
+              Real f(e[p-2]);
+              e[p-2] = 0.0;
+              for (j = p-2; j >= k; --j)
+              {
+                  Real t( hypot(s(j),f));
+                  Real cs(s(j)/t);
+                  Real sn(f/t);
+                  s(j) = t;
+                  if (j != k)
+                  {
+                      f = -sn*e[j-1];
+                      e[j-1] = cs*e[j-1];
+                  }
+                  for (i = 0; i < n; ++i)
+                  {
+                      t = cs*V(i, j) + sn*V(i, p-1);
+                      V(i, p-1) = -sn*V(i, j) + cs*V(i, p-1);
+                      V(i, j) = t;
+                  }
+              }
+              break;
+          }
+          case 2: // Split at negligible s(k).
+          {
+              Real f(e[k-1]);
+              e[k-1] = 0.0;
+              for (j = k; j < p; ++j)
+              {
+                  Real t(hypot(s(j),f));
+                  Real cs( s(j)/t);
+                  Real sn(f/t);
+                  s(j) = t;
+                  f = -sn*e[j];
+                  e[j] = cs*e[j];
+                  for (i = 0; i < m; ++i)
+                  {
+                      t = cs*U(i, j) + sn*U(i, k-1);
+                      U(i, k-1) = -sn*U(i, j) + cs*U(i, k-1);
+                      U(i, j) = t;
+                  }
+              }
+              break;
+          }
+          case 3: // Perform one qr step.
+          {
+              // Calculate the shift.
+              Real scale = std::max(std::max(std::max(std::max(
+                      abs(s(p-1)),abs(s(p-2))),abs(e[p-2])),
+                      abs(s(k))),abs(e[k]));
+              Real sp = s(p-1)/scale;
+              Real spm1 = s(p-2)/scale;
+              Real epm1 = e[p-2]/scale;
+              Real sk = s(k)/scale;
+              Real ek = e[k]/scale;
+              Real b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
+              Real c = (sp*epm1)*(sp*epm1);
+              Real shift = 0.0;
+              if ((b != 0.0) || (c != 0.0))
+              {
+                  shift = VIGRA_CSTD::sqrt(b*b + c);
+                  if (b < 0.0)
+                  {
+                      shift = -shift;
+                  }
+                  shift = c/(b + shift);
+              }
+              Real f = (sk + sp)*(sk - sp) + shift;
+              Real g = sk*ek;
+
+              // Chase zeros.
+              for (j = k; j < p-1; ++j)
+              {
+                  Real t = hypot(f,g);
+                  Real cs = f/t;
+                  Real sn = g/t;
+                  if (j != k)
+                  {
+                      e[j-1] = t;
+                  }
+                  f = cs*s(j) + sn*e[j];
+                  e[j] = cs*e[j] - sn*s(j);
+                  g = sn*s(j+1);
+                  s(j+1) = cs*s(j+1);
+                  for (i = 0; i < n; ++i)
+                  {
+                      t = cs*V(i, j) + sn*V(i, j+1);
+                      V(i, j+1) = -sn*V(i, j) + cs*V(i, j+1);
+                      V(i, j) = t;
+                  }
+                  t = hypot(f,g);
+                  cs = f/t;
+                  sn = g/t;
+                  s(j) = t;
+                  f = cs*e[j] + sn*s(j+1);
+                  s(j+1) = -sn*e[j] + cs*s(j+1);
+                  g = sn*e[j+1];
+                  e[j+1] = cs*e[j+1];
+                  if (j < m-1)
+                  {
+                      for (i = 0; i < m; ++i)
+                      {
+                          t = cs*U(i, j) + sn*U(i, j+1);
+                          U(i, j+1) = -sn*U(i, j) + cs*U(i, j+1);
+                          U(i, j) = t;
+                      }
+                  }
+              }
+              e[p-2] = f;
+              iter = iter + 1;
+              break;
+          }
+          case 4:  // Convergence.
+          {
+              // Make the singular values positive.
+              if (s(k) <= 0.0)
+              {
+                  s(k) = (s(k) < 0.0 ? -s(k) : 0.0);
+                  for (i = 0; i <= pp; ++i)
+                  {
+                      V(i, k) = -V(i, k);
+                  }
+              }
+
+              // Order the singular values.
+
+              while (k < pp)
+              {
+                  if (s(k) >= s(k+1))
+                  {
+                      break;
+                  }
+                  Real t = s(k);
+                  s(k) = s(k+1);
+                  s(k+1) = t;
+                  if (k < n-1)
+                  {
+                      for (i = 0; i < n; ++i)
+                      {
+                           t = V(i, k+1); V(i, k+1) = V(i, k); V(i, k) = t;
+                      }
+                  }
+                  if (k < m-1)
+                  {
+                      for (i = 0; i < m; ++i)
+                      {
+                          t = U(i, k+1); U(i, k+1) = U(i, k); U(i, k) = t;
+                      }
+                  }
+                  ++k;
+              }
+              iter = 0;
+              --p;
+              break;
+          }
+          default:
+              vigra_fail("vigra::svd(): Internal error.");
+        }
+    }
+    Real tol = std::max(m,n)*s(0)*eps;
+    unsigned int rank = 0;
+    for (MultiArrayIndex i = 0; i < n; ++i)
+    {
+        if (s(i) > tol)
+        {
+            ++rank;
+        }
+    }
+    return rank; // effective rank
+}
+
+} // namespace linalg
+
+using linalg::singularValueDecomposition;
+
+} // namespace vigra
+
+#endif // VIGRA_SINGULAR_VALUE_DECOMPOSITION_HXX
diff --git a/include/vigra/sized_int.hxx b/include/vigra/sized_int.hxx
new file mode 100644
index 0000000..4674348
--- /dev/null
+++ b/include/vigra/sized_int.hxx
@@ -0,0 +1,212 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_SIZED_INT_HXX
+#define VIGRA_SIZED_INT_HXX
+
+#include "metaprogramming.hxx"
+#include <limits>
+
+#if   SHRT_MAX  == 0x7FL
+# define VIGRA_BITSOF_SHORT 8
+#elif SHRT_MAX  == 0x7FFFL
+# define VIGRA_BITSOF_SHORT 16
+#elif SHRT_MAX  == 0x7FFFFFFFL
+# define VIGRA_BITSOF_SHORT 32
+#elif SHRT_MAX  > 0xFFFFFFFFL
+# define VIGRA_BITSOF_SHORT 64
+#else
+# define VIGRA_BITSOF_SHORT -1
+#endif
+
+#if   INT_MAX  == 0x7FL
+# define VIGRA_BITSOF_INT 8
+#elif INT_MAX  == 0x7FFFL
+# define VIGRA_BITSOF_INT 16
+#elif INT_MAX  == 0x7FFFFFFFL
+# define VIGRA_BITSOF_INT 32
+#elif INT_MAX  > 0xFFFFFFFFL
+# define VIGRA_BITSOF_INT 64
+#else
+# define VIGRA_BITSOF_INT -1
+#endif
+
+#if   LONG_MAX  == 0x7FL
+# define VIGRA_BITSOF_LONG 8
+#elif LONG_MAX  == 0x7FFFL
+# define VIGRA_BITSOF_LONG 16
+#elif LONG_MAX  == 0x7FFFFFFFL
+# define VIGRA_BITSOF_LONG 32
+#elif LONG_MAX  > 0xFFFFFFFFL
+# define VIGRA_BITSOF_LONG 64
+#else
+# define VIGRA_BITSOF_LONG -1
+#endif
+
+#if   LLONG_MAX  == 0x7FL
+# define VIGRA_BITSOF_LONG_LONG 8
+#elif LLONG_MAX  == 0x7FFFL
+# define VIGRA_BITSOF_LONG_LONG 16
+#elif LLONG_MAX  == 0x7FFFFFFFL
+# define VIGRA_BITSOF_LONG_LONG 32
+#elif LLONG_MAX  > 0xFFFFFFFFL
+# define VIGRA_BITSOF_LONG_LONG 64
+#else
+# define VIGRA_BITSOF_LONG_LONG -1
+#endif
+
+namespace vigra {
+
+class Int_type_not_supported_on_this_platform {};
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+namespace detail {
+
+template<class T, class NEXT>
+struct IntTypeList
+{
+    enum { size = sizeof(T)*8 };
+    typedef T type;
+    typedef NEXT next;
+};
+
+template<int SIZE, class LIST>
+struct SelectIntegerType
+{
+    typedef typename 
+       IfBool<(SIZE == LIST::size), 
+           typename LIST::type,
+           typename SelectIntegerType<SIZE, typename LIST::next>::type >::type
+       type;
+};
+
+template<int SIZE>
+struct SelectIntegerType<SIZE, Int_type_not_supported_on_this_platform>
+{
+    typedef Int_type_not_supported_on_this_platform type;
+};
+
+template<class LIST>
+struct SelectBiggestIntegerType
+{
+    enum { cursize = static_cast<int>(LIST::size), 
+           nextsize = static_cast<int>(SelectBiggestIntegerType<typename LIST::next>::size),
+           size = (cursize < nextsize) ? nextsize : cursize };
+    typedef typename 
+       IfBool<(cursize < nextsize), 
+           typename SelectBiggestIntegerType<typename LIST::next>::type,
+           typename LIST::type>::type
+       type;
+};
+
+template<>
+struct SelectBiggestIntegerType<Int_type_not_supported_on_this_platform>
+{
+    enum { size = 0 };
+    typedef Int_type_not_supported_on_this_platform type;
+};
+
+typedef IntTypeList<signed char, 
+        IntTypeList<signed short,
+        IntTypeList<signed int,
+        IntTypeList<signed long,
+        IntTypeList<signed long long,
+        Int_type_not_supported_on_this_platform > > > > > SignedIntTypes;
+typedef IntTypeList<unsigned char, 
+        IntTypeList<unsigned short,
+        IntTypeList<unsigned int,
+        IntTypeList<unsigned long,
+        IntTypeList<unsigned long long,
+        Int_type_not_supported_on_this_platform > > > > > UnsignedIntTypes;
+
+} // namespace detail
+
+/** \addtogroup FixedSizeInt Fixed Size Integer Types
+
+    Since the C++ standard does only specify minimal sizes for the built-in 
+    integer types, one cannot rely on them to have a specific size. But
+    pixel types with a specific size are often required in image processing,
+    especially when reading or writing binary files. The VIGRA typedefs
+    are guaranteed to have exactly the correct size. If the system
+    does not provide a suitable type, the typedef will evaluate to
+    <tt>Int_type_not_supported_on_this_platform</tt>.
+*/
+//@{
+
+    /// 8-bit signed int
+typedef detail::SelectIntegerType<8,  detail::SignedIntTypes>::type Int8;
+    /// 16-bit signed int
+typedef detail::SelectIntegerType<16, detail::SignedIntTypes>::type Int16;
+    /// 32-bit signed int
+typedef detail::SelectIntegerType<32, detail::SignedIntTypes>::type Int32;
+    /// 64-bit signed int
+typedef detail::SelectIntegerType<64, detail::SignedIntTypes>::type Int64;
+    /// 8-bit unsigned int
+typedef detail::SelectIntegerType<8,  detail::UnsignedIntTypes>::type UInt8;
+    /// 16-bit unsigned int
+typedef detail::SelectIntegerType<16, detail::UnsignedIntTypes>::type UInt16;
+    /// 32-bit unsigned int
+typedef detail::SelectIntegerType<32, detail::UnsignedIntTypes>::type UInt32;
+    /// 64-bit unsigned int
+typedef detail::SelectIntegerType<64, detail::UnsignedIntTypes>::type UInt64;
+
+    /// the biggest signed integer type of the system
+typedef detail::SelectBiggestIntegerType<detail::SignedIntTypes>::type   IntBiggest;
+    /// the biggest unsigned integer type of the system
+typedef detail::SelectBiggestIntegerType<detail::UnsignedIntTypes>::type UIntBiggest;
+
+//@}
+
+#else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+typedef signed char    Int8;
+typedef signed short   Int16;
+typedef signed int     Int32;
+typedef Int_type_not_supported_on_this_platform Int64;
+typedef unsigned char  UInt8;
+typedef unsigned short UInt16;
+typedef unsigned int   UInt32;
+typedef Int_type_not_supported_on_this_platform UInt64;
+
+typedef Int32  IntBiggest;
+typedef UInt32 UIntBiggest;
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+} // namespace vigra
+
+#endif /* VIGRA_SIZED_INT_HXX */
diff --git a/include/vigra/slanted_edge_mtf.hxx b/include/vigra/slanted_edge_mtf.hxx
new file mode 100644
index 0000000..2195e18
--- /dev/null
+++ b/include/vigra/slanted_edge_mtf.hxx
@@ -0,0 +1,735 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2006 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_SLANTED_EDGE_MTF_HXX
+#define VIGRA_SLANTED_EDGE_MTF_HXX
+
+#include <algorithm>
+#include "array_vector.hxx"
+#include "basicgeometry.hxx"
+#include "edgedetection.hxx"
+#include "fftw3.hxx"
+#include "functorexpression.hxx"
+#include "linear_solve.hxx"
+#include "mathutil.hxx"
+#include "numerictraits.hxx"
+#include "separableconvolution.hxx"
+#include "static_assert.hxx"
+#include "stdimage.hxx"
+#include "transformimage.hxx"
+#include "utilities.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup SlantedEdgeMTF Camera MTF Estimation
+    Determine the magnitude transfer function (MTF) of a camera using the slanted edge method.
+*/
+//@{ 
+                                    
+/********************************************************/
+/*                                                      */
+/*                  SlantedEdgeMTFOptions               */
+/*                                                      */
+/********************************************************/
+
+/** \brief Pass options to one of the \ref slantedEdgeMTF() functions.
+
+    <tt>SlantedEdgeMTFOptions</tt>  is an argument objects that holds various optional
+    parameters used by the \ref slantedEdgeMTF() functions. If a parameter is not explicitly
+    set, a suitable default will be used. Changing the defaults is only necessary if you can't 
+    obtain good input data, but absolutely need an MTF estimate.
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/slanted_edge_mtf.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    MultiArray<2, float> src(w,h);
+    std::vector<vigra::TinyVector<double, 2> > mtf;
+    
+    ...
+    slantedEdgeMTF(src, mtf,
+                   SlantedEdgeMTFOptions().mtfSmoothingScale(1.0));
+    
+    // print the frequency / attenuation pairs found
+    for(int k=0; k<result.size(); ++k)
+        std::cout << "frequency: " << mtf[k][0] << ", estimated attenuation: " << mtf[k][1] << std::endl;
+    \endcode
+*/
+
+class SlantedEdgeMTFOptions
+{
+  public:
+        /** Initialize all options with default values.
+        */
+    SlantedEdgeMTFOptions()
+    : minimum_number_of_lines(20),
+      desired_edge_width(10),
+      minimum_edge_width(5),
+      mtf_smoothing_scale(2.0)
+    {}
+
+        /** Minimum number of pixels the edge must cross.
+        
+            The longer the edge the more accurate the resulting MTF estimate. If you don't have good
+            data, but absolutely have to compute an MTF, you may force a lower value here.<br>
+            Default: 20
+        */
+    SlantedEdgeMTFOptions & minimumNumberOfLines(unsigned int n)
+    {
+        minimum_number_of_lines = n;
+        return *this;
+    }
+
+        /** Desired number of pixels perpendicular to the edge.
+        
+            The larger the regions to either side of the edge, 
+            the more accurate the resulting MTF estimate. If you don't have good
+            data, but absolutely have to compute an MTF, you may force a lower value here.<br>
+            Default: 10
+        */
+    SlantedEdgeMTFOptions & desiredEdgeWidth(unsigned int n)
+    {
+        desired_edge_width = n;
+        return *this;
+    }
+
+        /** Minimum acceptable number of pixels perpendicular to the edge.
+        
+            The larger the regions to either side of the edge, 
+            the more accurate the resulting MTF estimate. If you don't have good
+            data, but absolutely have to compute an MTF, you may force a lower value here.<br>
+            Default: 5
+        */
+    SlantedEdgeMTFOptions & minimumEdgeWidth(unsigned int n)
+    {
+        minimum_edge_width = n;
+        return *this;
+    }
+
+        /** Amount of smoothing of the computed MTF.
+        
+            If the data is noisy, so will be the MTF. Thus, some smoothing is useful.<br>
+            Default: 2.0
+        */
+    SlantedEdgeMTFOptions & mtfSmoothingScale(double scale)
+    {
+        vigra_precondition(scale >= 0.0,
+            "SlantedEdgeMTFOptions: MTF smoothing scale must not be < 0.");
+        mtf_smoothing_scale = scale;
+        return *this;
+    }
+
+    unsigned int minimum_number_of_lines, desired_edge_width, minimum_edge_width;
+    double mtf_smoothing_scale;
+};
+
+//@}
+
+namespace detail {
+
+struct SortEdgelsByStrength
+{
+    bool operator()(Edgel const & l, Edgel const & r) const
+    {
+        return l.strength > r.strength;
+    }
+};
+
+    /* Make sure that the edge runs vertically, intersects the top and bottom border
+       of the image, and white is on the left.
+    */
+template <class SrcIterator, class SrcAccessor, class DestImage>
+unsigned int
+prepareSlantedEdgeInput(SrcIterator sul, SrcIterator slr, SrcAccessor src, DestImage & res,
+                        SlantedEdgeMTFOptions const & options)
+{
+    unsigned int w = slr.x - sul.x;
+    unsigned int h = slr.y - sul.y;
+
+    // find rough estimate of the edge
+    ArrayVector<Edgel> edgels;
+    cannyEdgelList(sul, slr, src, edgels, 2.0);
+    std::sort(edgels.begin(), edgels.end(), SortEdgelsByStrength());
+
+    double x = 0.0, y = 0.0, x2 = 0.0, y2 = 0.0, xy = 0.0;
+    unsigned int c = std::min(w, h);
+
+    for(unsigned int k = 0; k < c; ++k)
+    {
+        x += edgels[k].x;
+        y += edgels[k].y;
+        x2 += sq(edgels[k].x);
+        xy += edgels[k].x*edgels[k].y;
+        y2 += sq(edgels[k].y);
+    }
+    double xc = x / c, yc = y / c;
+    x2 = x2 / c - sq(xc);
+    xy = xy / c - xc*yc;
+    y2 = y2 / c - sq(yc);
+    double angle = 0.5*VIGRA_CSTD::atan2(2*xy, x2 - y2);
+
+    DestImage tmp;
+    // rotate image when slope is less than +-45 degrees
+    if(VIGRA_CSTD::fabs(angle) < M_PI / 4.0)
+    {
+        xc = yc;
+        yc = w - xc - 1;
+        std::swap(w, h);
+        tmp.resize(w, h);
+        rotateImage(srcIterRange(sul, slr, src), destImage(tmp), 90);
+        angle += M_PI / 2.0;
+    }
+    else
+    {
+        tmp.resize(w, h);
+        copyImage(srcIterRange(sul, slr, src), destImage(tmp));
+        if(angle < 0.0)
+            angle += M_PI;
+    }
+    // angle is now between pi/4 and 3*pi/4
+    double slope = VIGRA_CSTD::tan(M_PI/2.0 - angle);
+    vigra_precondition(slope != 0.0,
+          "slantedEdgeMTF(): Input edge is not slanted");
+
+    // trim image so that the edge only intersects the top and bottom border
+    unsigned int minimumNumberOfLines = options.minimum_number_of_lines, //20,
+                 edgeWidth = options.desired_edge_width, // 10
+                 minimumEdgeWidth = options.minimum_edge_width; // 5
+
+    int y0 = 0, y1 = h;
+    for(; edgeWidth >= minimumEdgeWidth; --edgeWidth)
+    {
+        y0 = int(VIGRA_CSTD::floor((edgeWidth - xc) / slope + yc + 0.5));
+        y1 = int(VIGRA_CSTD::floor((w - edgeWidth - 1 - xc) / slope + yc + 0.5));
+        if(slope < 0.0)
+            std::swap(y0, y1);
+        if(y1 - y0 >= (int)minimumNumberOfLines)
+            break;
+    }
+
+    vigra_precondition(edgeWidth >= minimumEdgeWidth,
+        "slantedEdgeMTF(): Input edge is too slanted or image is too small");
+
+    y0 = std::max(y0, 0);
+    y1 = std::min(y1+1, (int)h);
+
+    res.resize(w, y1-y0);
+
+    // ensure that white is on the left
+    if(tmp(0,0) < tmp(w-1, h-1))
+    {
+        rotateImage(srcIterRange(tmp.upperLeft() + Diff2D(0, y0), tmp.upperLeft() + Diff2D(w, y1), tmp.accessor()),
+                    destImage(res), 180);
+    }
+    else
+    {
+        copyImage(srcImageRange(tmp), destImage(res));
+    }
+    return edgeWidth;
+}
+
+template <class Image>
+void slantedEdgeShadingCorrection(Image & i, unsigned int edgeWidth)
+{
+    using namespace functor;
+
+    // after prepareSlantedEdgeInput(), the white region is on the left
+    // find a plane that approximates the logarithm of the white ROI
+
+    transformImage(srcImageRange(i), destImage(i), log(Arg1() + Param(1.0)));
+
+    unsigned int w = i.width(),
+                 h = i.height();
+
+    Matrix<double> m(3,3), r(3, 1), l(3, 1);
+    for(unsigned int y = 0; y < h; ++y)
+    {
+        for(unsigned int x = 0; x < edgeWidth; ++x)
+        {
+            l(0,0) = x;
+            l(1,0) = y;
+            l(2,0) = 1.0;
+            m += outer(l);
+            r += i(x,y)*l;
+        }
+    }
+
+    linearSolve(m, r, l);
+    double a = l(0,0),
+           b = l(1,0),
+           c = l(2,0);
+
+    // subtract the plane and go back to the non-logarithmic representation
+    for(unsigned int y = 0; y < h; ++y)
+    {
+        for(unsigned int x = 0; x < w; ++x)
+        {
+            i(x, y) = VIGRA_CSTD::exp(i(x,y) - a*x - b*y - c);
+        }
+    }
+}
+
+template <class Image, class BackInsertable>
+void slantedEdgeSubpixelShift(Image const & img, BackInsertable & centers, double & angle,
+                              SlantedEdgeMTFOptions const & options)
+{
+    unsigned int w = img.width();
+    unsigned int h = img.height();
+
+    Image grad(w, h);
+    Kernel1D<double> kgrad;
+    kgrad.initGaussianDerivative(1.0, 1);
+
+    separableConvolveX(srcImageRange(img), destImage(grad), kernel1d(kgrad));
+
+    int desiredEdgeWidth = (int)options.desired_edge_width;
+    double sy = 0.0, sx = 0.0, syy = 0.0, sxy = 0.0;
+    for(unsigned int y = 0; y < h; ++y)
+    {
+        double a = 0.0,
+               b = 0.0;
+        for(unsigned int x = 0; x < w; ++x)
+        {
+            a += x*grad(x,y);
+            b += grad(x,y);
+        }
+        int c = int(a / b);
+        // c is biased because the numbers of black and white pixels differ
+        // repeat the analysis with a symmetric window around the edge
+        a = 0.0;
+        b = 0.0;
+        int ew = desiredEdgeWidth;
+        if(c-desiredEdgeWidth < 0)
+            ew = c;
+        if(c + ew + 1 >= (int)w)
+            ew = w - c - 1;
+        for(int x = c-ew; x < c+ew+1; ++x)
+        {
+            a += x*grad(x,y);
+            b += grad(x,y);
+        }
+        double sc = a / b;
+        sy += y;
+        sx += sc;
+        syy += sq(y);
+        sxy += sc*y;
+    }
+    // fit a line to the subpixel locations
+    double a = (h * sxy - sx * sy) / (h * syy - sq(sy));
+    double b = (sx * syy - sxy * sy) / (h * syy - sq(sy));
+
+    // compute the regularized subpixel values of the edge location
+    angle = VIGRA_CSTD::atan(a);
+    for(unsigned int y = 0; y < h; ++y)
+    {
+        centers.push_back(a * y + b);
+    }
+}
+
+template <class Image, class Vector>
+void slantedEdgeCreateOversampledLine(Image const & img, Vector const & centers,
+                                      Image & result)
+{
+    unsigned int w = img.width();
+    unsigned int h = img.height();
+    unsigned int w2 = std::min(std::min(int(centers[0]), int(centers[h-1])),
+                               std::min(int(w - centers[0]) - 1, int(w - centers[h-1]) - 1));
+    unsigned int ww = 8*w2;
+
+    Image r(ww, 1), s(ww, 1);
+    for(unsigned int y = 0; y < h; ++y)
+    {
+        int x0 = int(centers[y]) - w2;
+        int x1 = int((VIGRA_CSTD::ceil(centers[y]) - centers[y])*4);
+        for(; x1 < (int)ww; x1 += 4)
+        {
+            r(x1, 0) += img(x0, y);
+            ++s(x1, 0);
+            ++x0;
+        }
+    }
+
+    for(unsigned int x = 0; x < ww; ++x)
+    {
+        vigra_precondition(s(x,0) > 0.0,
+           "slantedEdgeMTF(): Input edge is not slanted enough");
+        r(x,0) /= s(x,0);
+    }
+
+    result.resize(ww-1, 1);
+    for(unsigned int x = 0; x < ww-1; ++x)
+    {
+        result(x,0) = r(x+1,0) - r(x,0);
+    }
+}
+
+template <class Image, class BackInsertable>
+void slantedEdgeMTFImpl(Image const & i, BackInsertable & mtf, double angle,
+                        SlantedEdgeMTFOptions const & options)
+{
+    unsigned int w = i.width();
+    unsigned int h = i.height();
+
+    double slantCorrection = VIGRA_CSTD::cos(angle);
+    int desiredEdgeWidth = 4*options.desired_edge_width;
+
+    Image magnitude;
+
+    if(w - 2*desiredEdgeWidth < 64)
+    {
+        FFTWComplexImage otf(w, h);
+        fourierTransform(srcImageRange(i), destImage(otf));
+
+        magnitude.resize(w, h);
+        for(unsigned int y = 0; y < h; ++y)
+        {
+            for(unsigned int x = 0; x < w; ++x)
+            {
+                magnitude(x, y) = norm(otf(x, y));
+            }
+        }
+    }
+    else
+    {
+        w -= 2*desiredEdgeWidth;
+        FFTWComplexImage otf(w, h);
+        fourierTransform(srcImageRange(i, Rect2D(Point2D(desiredEdgeWidth, 0), Size2D(w, h))),
+                         destImage(otf));
+
+        // create an image where the edge is skipped - presumably it only contains the
+        // noise which can then be subtracted
+        Image noise(w,h);
+        copyImage(srcImageRange(i, Rect2D(Point2D(0,0), Size2D(w/2, h))),
+                  destImage(noise));
+        copyImage(srcImageRange(i, Rect2D(Point2D(i.width()-w/2, 0), Size2D(w/2, h))),
+                  destImage(noise, Point2D(w/2, 0)));
+        FFTWComplexImage fnoise(w, h);
+        fourierTransform(srcImageRange(noise), destImage(fnoise));
+
+        // subtract the noise power spectrum from the total power spectrum
+        magnitude.resize(w, h);
+        for(unsigned int y = 0; y < h; ++y)
+        {
+            for(unsigned int x = 0; x < w; ++x)
+            {
+                magnitude(x, y) = VIGRA_CSTD::sqrt(std::max(0.0, squaredNorm(otf(x, y))-squaredNorm(fnoise(x, y))));
+            }
+        }
+    }
+
+    Kernel1D<double> gauss;
+    gauss.initGaussian(options.mtf_smoothing_scale);
+    Image smooth(w,h);
+    separableConvolveX(srcImageRange(magnitude), destImage(smooth), kernel1d(gauss));
+
+    unsigned int ww = w/4;
+    double maxVal = smooth(0,0),
+           minVal = maxVal;
+    for(unsigned int k = 1; k < ww; ++k)
+    {
+        if(smooth(k,0) >= 0.0 && smooth(k,0) < minVal)
+            minVal = smooth(k,0);
+    }
+    double norm = maxVal-minVal;
+
+    typedef typename BackInsertable::value_type Result;
+    mtf.push_back(Result(0.0, 1.0));
+    for(unsigned int k = 1; k < ww; ++k)
+    {
+        double n = (smooth(k,0) - minVal)/norm*sq(M_PI*k/w/VIGRA_CSTD::sin(M_PI*k/w));
+        double xx = 4.0*k/w/slantCorrection;
+        if(n < 0.0 || xx > 1.0)
+            break;
+        mtf.push_back(Result(xx, n));
+    }
+}
+
+} // namespace detail
+
+/** \addtogroup SlantedEdgeMTF Camera MTF Estimation
+    Determine the magnitude transfer function (MTF) of a camera using the slanted edge method.
+*/
+//@{ 
+                                    
+/********************************************************/
+/*                                                      */
+/*                     slantedEdgeMTF                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Determine the magnitude transfer function of the camera.
+
+    This operator estimates the magnitude transfer function (MTF) of a camera by means of the 
+    slanted edge method described in:
+    
+    ISO Standard No. 12233: <i>"Photography - Electronic still picture cameras - Resolution measurements"</i>, 2000
+    
+    The input must be an image that contains a single step edge with bright pixels on one side and dark pixels on 
+    the other. However, the intensity values must be neither saturated nor zero. The algorithms computes the MTF
+    from the Fourier transform of the edge's derivative. Thus, if the actual MTF is anisotropic, the estimated 
+    MTF does actually only apply in the direction perpendicular to the edge - several edges at different 
+    orientations are required to estimate an anisotropic MTF.
+    
+    The algorithm returns a sequence of frequency / attenuation pairs. The frequency axis is normalized so that the
+    Nyquist frequency of the original image is 0.5. Since the edge's derivative is computed with subpixel accuracy,
+    the attenuation can usually be computed for frequencies significantly above the Nyquist frequency as well. The 
+    MTF estimate ends at either the first zero crossing of the MTF or at frequency 1, whichever comes earlier.
+    
+    The present implementation improves the original slanted edge algorithm according to ISO 12233 in a number of
+    ways:
+    
+    <ul>
+    <li> The edge is not required to run nearly vertically or horizontally (i.e. with a slant of approximately 5 degrees).
+         The algorithm will automatically compute the edge's actual angle and adjust estimates accordingly. 
+         However, it is still necessary for the edge to be somewhat slanted, because subpixel-accurate estimation 
+         of the derivative is impossible otherwise (i.e. the edge position perpendicular to the edge direction must 
+         differ by at least 1 pixel between the two ends of the edge). 
+         
+    <li> Our implementation uses a more accurate subpixel derivative algorithm. In addition, we first perform a shading 
+         correction in order to reduce possible derivative bias due to nonuniform illumination.
+
+    <li> If the input image is large enough (i.e. there are at least 20 pixels on either side of the edge over
+         the edge's entire length), our algorithm attempts to subtract the estimated noise power spectrum
+         from the estimated MTF.
+    </ul>
+    
+    The source value type <TT>T1</TT> must be a scalar type which is convertible to <tt>double</tt>.
+    The result is written into the \a result sequence, which must be back-insertable (supports <tt>push_back()</tt>)
+    and whose <tt>value_type</tt> must be constructible 
+    from two <tt>double</tt> values. Algorithm options can be set via the \a options object 
+    (see \ref vigra::NoiseNormalizationOptions for details).
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1, class BackInsertable>
+        void
+        slantedEdgeMTF(MultiArrayView<2, T1, S1> const & src, BackInsertable & mtf,
+                       SlantedEdgeMTFOptions const & options = SlantedEdgeMTFOptions());
+    }
+    \endcode
+    
+    \deprecatedAPI{slantedEdgeMTF}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void
+        slantedEdgeMTF(SrcIterator sul, SrcIterator slr, SrcAccessor src, BackInsertable & mtf,
+                       SlantedEdgeMTFOptions const & options = SlantedEdgeMTFOptions());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor, class BackInsertable>
+        void
+        slantedEdgeMTF(triple<SrcIterator, SrcIterator, SrcAccessor> src, BackInsertable & mtf,
+                       SlantedEdgeMTFOptions const & options = SlantedEdgeMTFOptions())
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/slanted_edge_mtf.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h);
+    std::vector<vigra::TinyVector<double, 2> > mtf;
+    
+    ...
+    // keep all options at their default values
+    slantedEdgeMTF(src, mtf);
+    
+    // print the frequency / attenuation pairs found
+    for(int k=0; k<result.size(); ++k)
+        std::cout << "frequency: " << mtf[k][0] << ", estimated attenuation: " << mtf[k][1] << std::endl;
+    \endcode
+
+    \deprecatedUsage{slantedEdgeMTF}
+    \code
+    vigra::BImage src(w,h);
+    std::vector<vigra::TinyVector<double, 2> > mtf;
+    
+    ...
+    vigra::slantedEdgeMTF(srcImageRange(src), mtf);
+    
+    // print the frequency / attenuation pairs found
+    for(int k=0; k<result.size(); ++k)
+        std::cout << "frequency: " << mtf[k][0] << ", estimated attenuation: " << mtf[k][1] << std::endl;
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator upperleft, lowerright;
+    SrcAccessor src;
+    
+    typedef SrcAccessor::value_type SrcType;
+    typedef NumericTraits<SrcType>::isScalar isScalar;
+    assert(isScalar::asBool == true);
+    
+    double value = src(uperleft);
+    
+    BackInsertable result;
+    typedef BackInsertable::value_type ResultType;    
+    double intensity, variance;
+    result.push_back(ResultType(intensity, variance));
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void slantedEdgeMTF)
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+void
+slantedEdgeMTF(SrcIterator sul, SrcIterator slr, SrcAccessor src, BackInsertable & mtf,
+               SlantedEdgeMTFOptions const & options = SlantedEdgeMTFOptions())
+{
+    DImage preparedInput;
+    unsigned int edgeWidth = detail::prepareSlantedEdgeInput(sul, slr, src, preparedInput, options);
+    detail::slantedEdgeShadingCorrection(preparedInput, edgeWidth);
+
+    ArrayVector<double> centers;
+    double angle = 0.0;
+    detail::slantedEdgeSubpixelShift(preparedInput, centers, angle, options);
+
+    DImage oversampledLine;
+    detail::slantedEdgeCreateOversampledLine(preparedInput, centers, oversampledLine);
+
+    detail::slantedEdgeMTFImpl(oversampledLine, mtf, angle, options);
+}
+
+template <class SrcIterator, class SrcAccessor, class BackInsertable>
+inline void
+slantedEdgeMTF(triple<SrcIterator, SrcIterator, SrcAccessor> src, BackInsertable & mtf,
+               SlantedEdgeMTFOptions const & options = SlantedEdgeMTFOptions())
+{
+    slantedEdgeMTF(src.first, src.second, src.third, mtf, options);
+}
+
+template <class T1, class S1, class BackInsertable>
+inline void
+slantedEdgeMTF(MultiArrayView<2, T1, S1> const & src, BackInsertable & mtf,
+               SlantedEdgeMTFOptions const & options = SlantedEdgeMTFOptions())
+{
+    slantedEdgeMTF(srcImageRange(src), mtf, options);
+}
+
+/********************************************************/
+/*                                                      */
+/*                     mtfFitGaussian                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Fit a Gaussian function to a given MTF.
+
+    This function expects a sequence of frequency / attenuation pairs as produced by \ref slantedEdgeMTF()
+    and finds the best fitting Gaussian point spread function (Gaussian functions are good approximations 
+    of the PSF of many real cameras). It returns the standard deviation (scale) of this function. The algorithm
+    computes the standard deviation by means of a linear least square on the logarithm of the MTF, i.e.
+    an algebraic fit rather than a Euclidean fit - thus, the resulting Gaussian may not be the one that 
+    intuitively fits the data optimally.
+    
+    <b> Declaration:</b>
+    
+    \code
+    namespace vigra {
+        template <class Vector>
+        double mtfFitGaussian(Vector const & mtf);
+    }
+    \endcode
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/slanted_edge_mtf.hxx\><br>
+    Namespace: vigra
+    
+    \code
+    MultiArray<2, float> src(w,h);
+    std::vector<vigra::TinyVector<double, 2> > mtf;
+    
+    ...
+    slantedEdgeMTF(src, mtf);
+    double scale = vigra::mtfFitGaussian(mtf)
+    
+    std::cout << "The camera PSF is approximately a Gaussian at scale " << scale << std::endl;
+    \endcode
+
+    <b> Required Interface:</b>
+    
+    \code
+    Vector mtf;
+    int numberOfMeasurements = mtf.size()
+    
+    double frequency = mtf[0][0];
+    double attenuation = mtf[0][1];
+    \endcode
+*/
+template <class Vector>
+double mtfFitGaussian(Vector const & mtf)
+{
+    double minVal = mtf[0][1];
+    for(unsigned int k = 1; k < mtf.size(); ++k)
+    {
+        if(mtf[k][1] < minVal)
+            minVal = mtf[k][1];
+    }
+    double x2 = 0.0,
+           xy = 0.0;
+    for(unsigned int k = 1; k < mtf.size(); ++k)
+    {
+        if(mtf[k][1] <= 0.0)
+            break;
+        double x = mtf[k][0],
+               y = VIGRA_CSTD::sqrt(-VIGRA_CSTD::log(mtf[k][1])/2.0)/M_PI;
+        x2 += vigra::sq(x);
+        xy += x*y;
+        if(mtf[k][1] == minVal)
+            break;
+    }
+    return xy / x2;
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_SLANTED_EDGE_MTF_HXX
diff --git a/include/vigra/slic.hxx b/include/vigra/slic.hxx
new file mode 100644
index 0000000..b0864d3
--- /dev/null
+++ b/include/vigra/slic.hxx
@@ -0,0 +1,489 @@
+/************************************************************************/
+/*                                                                      */
+/*    Copyright 2012-2013 by Ullrich Koethe and Thorsten Beier          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_SLIC_HXX
+#define VIGRA_SLIC_HXX
+
+#include "multi_array.hxx"
+#include "multi_convolution.hxx"
+#include "multi_labeling.hxx"
+#include "numerictraits.hxx"
+#include "accumulator.hxx"
+#include "array_vector.hxx"
+
+namespace vigra {
+
+/** \addtogroup SeededRegionGrowing
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                  generateSlicSeeds                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Generate seeds for SLIC superpixel computation in arbitrary dimensions.
+
+    The source array \a src must be a scalar boundary indicator such as the gradient 
+    magnitude. Seeds are initially placed on a regular Cartesian grid with spacing
+    \a seedDist und then moved to the point with smallest boundary indicator within
+    a search region of radius \a searchRadius around the initial position. The resulting
+    points are then marked in the output array \a seeds by consecutive labels.
+    
+    The function returns the number of selected seeds, which equals the largest seed label 
+    because labeling starts at 1.
+
+    <b> Declaration:</b>
+
+    use arbitrary-dimensional arrays:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T, class S1,
+                                  class Label, class S2>
+        unsigned int 
+        generateSlicSeeds(MultiArrayView<N, T, S1> const & src,
+                          MultiArrayView<N, Label, S2>     seeds,
+                          unsigned int                     seedDist,
+                          unsigned int                     searchRadius = 1);
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/slic.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, RGBValue<float> > src(Shape2(w, h));
+    ... // fill src image
+    
+    // transform image to Lab color space
+    transformImage(srcImageRange(src), destImage(src), RGBPrime2LabFunctor<float>());
+    
+    // compute image gradient magnitude at scale 1.0 as a boundary indicator
+    MultiArray<2, float> grad(src.shape());
+    gaussianGradientMagnitude(srcImageRange(src), destImage(grad), 1.0);
+    
+    MultiArray<2, unsigned int>  seeds(src.shape());
+    int seedDistance = 15;
+    
+    // place seeds on a grid with distance 15, but then move it to the lowest gradient
+    // poistion in a 3x3 window
+    generateSlicSeeds(grad, seeds, seedDistance);
+    \endcode
+
+    For more details and examples see slicSuperpixels().
+*/
+doxygen_overloaded_function(template <...> unsigned int generateSlicSeeds)
+
+template <unsigned int N, class T, class S1,
+                          class Label, class S2>
+unsigned int 
+generateSlicSeeds(MultiArrayView<N, T, S1> const & boundaryIndicatorImage,
+                  MultiArrayView<N, Label, S2>     seeds,
+                  unsigned int                     seedDist,
+                  unsigned int                     searchRadius = 1)
+{
+    typedef typename MultiArrayShape<N>::type   Shape;
+
+    seeds.init(0);
+    Shape shape(boundaryIndicatorImage.shape()),
+          seedShape(floor(shape / double(seedDist))),
+          offset((shape - (seedShape - Shape(1))*seedDist) / 2);
+    
+    unsigned int label = 0;
+    MultiCoordinateIterator<N> iter(seedShape),
+                               end = iter.getEndIterator();
+    for(; iter != end; ++iter)
+    {
+        // define search window around current seed center
+        Shape center = (*iter)*seedDist + offset;
+        Shape startCoord = max(Shape(0), center-Shape(searchRadius));
+        Shape endCoord   = min(center+Shape(searchRadius+1), shape);
+        
+        // find the coordinate of minimum boundary indicator in window
+        using namespace acc;
+        AccumulatorChain<CoupledArrays<N, T>,
+                         Select<WeightArg<1>, Coord<ArgMinWeight> > > a;
+        extractFeatures(boundaryIndicatorImage.subarray(startCoord, endCoord), a);
+
+        // add seed at minimum position, if not already occupied
+        Shape minCoord = get<Coord<ArgMinWeight> >(a) + startCoord;
+        if(seeds[minCoord] == 0)
+            seeds[minCoord] = ++label;
+    }
+    return label;
+}
+
+/** \brief Options object for slicSuperpixels().
+
+    <b> Usage:</b>
+
+    see slicSuperpixels() for detailed examples.
+*/
+struct SlicOptions
+{
+        /** \brief Create options object with default settings.
+
+            Defaults are: perform 10 iterations, determine a size limit for superpixels automatically.
+        */
+    SlicOptions()
+    : iter(10),
+      sizeLimit(0)
+    {}
+    
+        /** \brief Number of iterations.
+
+            Default: 10
+        */
+    SlicOptions & iterations(unsigned int i)
+    {
+        iter = i;
+        return *this;
+    }
+    
+        /** \brief Minimum superpixel size.
+        
+            If you set this to 1, no size filtering will be performed.
+
+            Default: 0 (determine size limit automatically as <tt>average size / 4</tt>)
+        */
+    SlicOptions & minSize(unsigned int s)
+    {
+        sizeLimit = s;
+        return *this;
+    }
+    
+    unsigned int iter;
+    unsigned int sizeLimit;
+};
+
+namespace detail {
+
+template <unsigned int N, class T, class Label>
+class Slic
+{
+  public: 
+    // 
+    typedef MultiArrayView<N, T>                    DataImageType;
+    typedef MultiArrayView<N, Label>                LabelImageType; 
+    typedef typename DataImageType::difference_type ShapeType;
+    typedef typename PromoteTraits<
+                   typename NormTraits<T>::NormType,
+                   typename NormTraits<MultiArrayIndex>::NormType
+             >::Promote                             DistanceType;
+
+    Slic(DataImageType dataImage, 
+         LabelImageType labelImage, 
+         DistanceType intensityScaling, 
+         int maxRadius, 
+         SlicOptions const & options = SlicOptions());
+    
+    unsigned int execute();
+
+  private:
+    void updateAssigments();
+    unsigned int postProcessing();
+    
+    typedef MultiArray<N,DistanceType>  DistanceImageType;
+
+    ShapeType                       shape_;
+    DataImageType                   dataImage_;
+    LabelImageType                  labelImage_;
+    DistanceImageType               distance_;
+    int                             max_radius_;
+    DistanceType                    normalization_;
+    SlicOptions                     options_;
+    
+    typedef acc::Select<acc::DataArg<1>, acc::LabelArg<2>, acc::Mean, acc::RegionCenter> Statistics;
+    typedef acc::AccumulatorChainArray<CoupledArrays<N, T, Label>, Statistics> RegionFeatures;
+    RegionFeatures clusters_;
+};
+
+
+
+template <unsigned int N, class T, class Label>
+Slic<N, T, Label>::Slic(
+    DataImageType         dataImage, 
+    LabelImageType        labelImage,
+    DistanceType          intensityScaling,
+    int                   maxRadius,
+    SlicOptions const &   options)
+:   shape_(dataImage.shape()),
+    dataImage_(dataImage),
+    labelImage_(labelImage),
+    distance_(shape_),
+    max_radius_(maxRadius),
+    normalization_(sq(intensityScaling) / sq(max_radius_)),
+    options_(options)
+{
+    clusters_.ignoreLabel(0);
+}
+
+template <unsigned int N, class T, class Label>
+unsigned int Slic<N, T, Label>::execute()
+{
+    // Do SLIC
+    for(size_t i=0; i<options_.iter; ++i)
+    {
+        // update mean for each cluster
+        clusters_.reset();
+        extractFeatures(dataImage_, labelImage_, clusters_);
+        
+        // update which pixels get assigned to which cluster
+        updateAssigments();
+    }
+
+    return postProcessing();
+}
+
+template <unsigned int N, class T, class Label>
+void
+Slic<N, T, Label>::updateAssigments()
+{
+    using namespace acc;
+    distance_.init(NumericTraits<DistanceType>::max());
+    for(unsigned int c=1; c<=clusters_.maxRegionLabel(); ++c)
+    {
+        if(get<Count>(clusters_, c) == 0) // label doesn't exist
+            continue;
+            
+        typedef typename LookupTag<RegionCenter, RegionFeatures>::value_type CenterType;
+        CenterType center = get<RegionCenter>(clusters_, c);
+
+        // get ROI limits around region center
+        ShapeType pixelCenter(round(center)), 
+                  startCoord(max(ShapeType(0), pixelCenter - ShapeType(max_radius_))), 
+                  endCoord(min(shape_, pixelCenter + ShapeType(max_radius_+1)));
+        center -= startCoord; // need center relative to ROI
+        
+        // setup iterators for ROI
+        typedef typename CoupledArrays<N, T, Label, DistanceType>::IteratorType Iterator;
+        Iterator iter = createCoupledIterator(dataImage_, labelImage_, distance_).
+                            restrictToSubarray(startCoord, endCoord),
+                 end = iter.getEndIterator();
+        
+        // only pixels within the ROI can be assigned to a cluster
+        for(; iter != end; ++iter)
+        {
+            // compute distance between cluster center and pixel
+            DistanceType spatialDist   = squaredNorm(center-iter.point());
+            DistanceType colorDist     = squaredNorm(get<Mean>(clusters_, c)-iter.template get<1>());
+            DistanceType dist =  colorDist + normalization_*spatialDist;
+            // update label?
+            if(dist < iter.template get<3>())
+            {
+                iter.template get<2>() = static_cast<Label>(c);
+                iter.template get<3>() = dist;
+            }
+        }
+    }
+}
+
+template <unsigned int N, class T, class Label>
+unsigned int 
+Slic<N, T, Label>::postProcessing()
+{
+    // get rid of regions below a size limit
+    MultiArray<N,Label> tmpLabelImage(labelImage_);
+    unsigned int maxLabel = labelMultiArray(tmpLabelImage, labelImage_, DirectNeighborhood);
+    
+    unsigned int sizeLimit = options_.sizeLimit == 0
+                                 ? (unsigned int)(0.25 * labelImage_.size() / maxLabel)
+                                 : options_.sizeLimit;
+    if(sizeLimit == 1)
+        return maxLabel;
+        
+    // determine region size
+    using namespace acc;
+    AccumulatorChainArray<CoupledArrays<N, Label>, Select<LabelArg<1>, Count> > sizes;
+    extractFeatures(labelImage_, sizes);
+        
+    typedef GridGraph<N, undirected_tag> Graph;
+    Graph graph(labelImage_.shape(), DirectNeighborhood);
+    
+    typedef typename Graph::NodeIt        graph_scanner;
+    typedef typename Graph::OutBackArcIt  neighbor_iterator;
+
+    ArrayVector<Label> regions(maxLabel+1);
+
+    // make sure that all regions exceed the sizeLimit
+    for (graph_scanner node(graph); node != lemon::INVALID; ++node) 
+    {
+        Label label = labelImage_[*node];
+        
+        if(regions[label] > 0)
+            continue;   // already processed
+            
+        regions[label] = label;
+        
+        if(get<Count>(sizes, label) < sizeLimit)
+        {
+            // region is too small => merge into an existing neighbor
+            for (neighbor_iterator arc(graph, node); arc != lemon::INVALID; ++arc)
+            {
+                regions[label] = regions[labelImage_[graph.target(*arc)]];
+                break;
+            }
+        }
+    }
+    
+    // make labels contiguous after possible merging
+    maxLabel = 0; 
+    for(unsigned int i=1; i<=maxLabel; ++i)
+    {
+        if(regions[i] == i)
+        {
+                regions[i] = (Label)++maxLabel;
+        }
+        else
+        {
+                regions[i] = regions[regions[i]]; 
+        }
+    }
+
+    // update labels
+    for (graph_scanner node(graph); node != lemon::INVALID; ++node) 
+    {
+        labelImage_[*node] = regions[labelImage_[*node]];
+    }
+    
+    return maxLabel;
+}
+
+} // namespace detail
+
+
+/** \brief Compute SLIC superpixels in arbitrary dimensions.
+
+    This function implements the algorithm described in 
+    
+    R. Achanta et al.: <em>"SLIC Superpixels Compared to State-of-the-Art 
+    Superpixel Methods"</em>, IEEE Trans. Patt. Analysis Mach. Intell. 34(11):2274-2281, 2012
+    
+    The value type <tt>T</tt> of the source array \a src must provide the necessary functionality 
+    to compute averages and squared distances (i.e. it must fulfill the requirements of a 
+    \ref LinearSpace and support squaredNorm(T const &)). This is true for all scalar types as well as
+    \ref vigra::TinyVector and \ref vigra::RGBValue. The output array \a labels will be filled
+    with labels designating membership of each point in one of the superpixel regions.
+    
+    The output array can optionally contain seeds (which will be overwritten by the output) 
+    to give you full control over seed placement. If \a labels is empty, seeds will be created
+    automatically by an internal call to generateSlicSeeds(). 
+    
+    The parameter \a seedDistance specifies the radius of the window around each seed (or, more
+    precisely, around the present regions centers) where the algorithm looks for potential members 
+    of the corresponding superpixel. It thus places an upper limit on the superpixel size. When seeds
+    are computed automatically, this parameter also determines the grid spacing for seed placement.
+    
+    The parameter \a intensityScaling is used to normalize (i.e. divide) the color/intensity difference 
+    before it is compared with the spatial distance. This corresponds to parameter <i>m</i> in equation
+    (2) of the paper.
+    
+    The options object can be used to specify the number of iterations (<tt>SlicOptions::iterations()</tt>)
+    and an explicit minimal superpixel size (<tt>SlicOptions::minSize()</tt>). By default, the algorithm 
+    merges all regions that are smaller than 1/4 of the average superpixel size.
+    
+    The function returns the number of superpixels, which equals the largest label 
+    because labeling starts at 1.
+
+    <b> Declaration:</b>
+
+    use arbitrary-dimensional arrays:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T, class S1,
+                                  class Label, class S2,
+                  class DistanceType>
+        unsigned int 
+        slicSuperpixels(MultiArrayView<N, T, S1> const &  src,
+                        MultiArrayView<N, Label, S2>      labels,
+                        DistanceType                      intensityScaling,
+                        unsigned int                      seedDistance, 
+                        SlicOptions const &               options = SlicOptions());
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/slic.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, RGBValue<float> > src(Shape2(w, h));
+    ... // fill src image
+    
+    // transform image to Lab color space
+    transformMultiArray(srcMultiArrayRange(src), destMultiArray(src), RGBPrime2LabFunctor<float>());    
+    
+    MultiArray<2, unsigned int>  labels(src.shape());
+    int seedDistance = 15;
+    double intensityScaling = 20.0;
+    
+    // compute seeds automatically, perform 40 iterations, and scale intensity differences
+    // down to 1/20 before comparing with spatial distances
+    slicSuperpixels(src, labels, intensityScaling, seedDistance, SlicOptions().iterations(40));
+    \endcode
+    
+    This works for arbitrary-dimensional arrays.
+*/
+doxygen_overloaded_function(template <...> unsigned int slicSuperpixels)
+
+template <unsigned int N, class T, class S1,
+                          class Label, class S2,
+          class DistanceType>
+unsigned int 
+slicSuperpixels(MultiArrayView<N, T, S1> const &  src,
+                MultiArrayView<N, Label, S2>      labels,
+                DistanceType                      intensityScaling,
+                unsigned int                      seedDistance, 
+                SlicOptions const &               options = SlicOptions())
+{
+    if(!labels.any())
+    {
+        typedef typename NormTraits<T>::NormType TmpType;
+        MultiArray<N, TmpType> grad(src.shape());
+        gaussianGradientMagnitude(src, grad, 1.0);
+        generateSlicSeeds(grad, labels, seedDistance);
+    }
+    return detail::Slic<N, T, Label>(src, labels, intensityScaling, seedDistance, options).execute();
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_SLIC_HXX
diff --git a/include/vigra/splineimageview.hxx b/include/vigra/splineimageview.hxx
new file mode 100644
index 0000000..996b36d
--- /dev/null
+++ b/include/vigra/splineimageview.hxx
@@ -0,0 +1,1882 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_SPLINEIMAGEVIEW_HXX
+#define VIGRA_SPLINEIMAGEVIEW_HXX
+
+#include "mathutil.hxx"
+#include "recursiveconvolution.hxx"
+#include "splines.hxx"
+#include "array_vector.hxx"
+#include "basicimage.hxx"
+#include "copyimage.hxx"
+#include "tinyvector.hxx"
+#include "fixedpoint.hxx"
+#include "multi_array.hxx"
+
+namespace vigra {
+
+/********************************************************/
+/*                                                      */
+/*                    SplineImageView                   */
+/*                                                      */
+/********************************************************/
+/** \brief Create a continuous view onto a discrete image using splines.
+
+    This class is very useful if image values or derivatives at arbitrary
+    real-valued coordinates are needed. Access at such coordinates is implemented by
+    interpolating the given discrete image values with a spline of the
+    specified <tt>ORDER</TT>. Continuous derivatives are available up to
+    degree <tt>ORDER-1</TT>. If the requested coordinates are near the image border,
+    reflective boundary conditions are applied. In principle, this class can also be used
+    for image resizing, but here the functions from the <tt>resize...</tt> family are
+    more efficient, since they exploit the regularity of the sampling grid.
+
+    The <tt>SplineImageView</tt> template is explicitly specialized to make it as efficient as possible.
+    In particular, unnecessary copying of the image is avoided when the iterators passed
+    in the constructor originate from a \ref vigra::BasicImage. In addition, these specializations
+    provide function <tt>unchecked(...)</tt> that do not perform bounds checking. If the original image
+    is not a variant of \ref vigra::BasicImage, one can customize the internal representation by
+    using \ref vigra::SplineImageView0 or \ref vigra::SplineImageView1.
+
+    <b>Usage:</b>
+
+    <b>\#include</b> \<vigra/splineimageview.hxx\><br>
+    Namespace: vigra
+
+    \code
+    BImage img(w,h);
+    ... // fill img
+
+    // construct spline view for quadratic interpolation
+    SplineImageView<2, double> spi2(srcImageRange(img));
+
+    double x = ..., y = ...;
+    double v2 = spi2(x, y);
+
+    // construct spline view for linear interpolation
+    SplineImageView<1, UInt32> spi1(srcImageRange(img));
+
+    UInt32 v1 = spi1(x, y);
+
+    FixedPoint<16, 15> fx(...), fy(...);
+    UInt32 vf = spi1.unchecked(fx, fy); // caller is sure that (fx, fy) are valid coordinates
+    \endcode
+*/
+template <int ORDER, class VALUETYPE>
+class SplineImageView
+{
+    typedef typename NumericTraits<VALUETYPE>::RealPromote InternalValue;
+
+  public:
+
+        /** The view's value type (return type of access and derivative functions).
+        */
+    typedef VALUETYPE value_type;
+
+        /** The view's squared norm type (return type of g2() etc.).
+        */
+    typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType;
+
+        /** The view's size type.
+        */
+    typedef Size2D size_type;
+
+        /** The view's difference type.
+        */
+    typedef TinyVector<double, 2> difference_type;
+
+        /** The order of the spline used.
+        */
+    enum StaticOrder { order = ORDER };
+
+        /** The type of the internal image holding the spline coefficients.
+        */
+    typedef BasicImage<InternalValue> InternalImage;
+
+  private:
+    typedef typename InternalImage::traverser InternalTraverser;
+    typedef typename InternalTraverser::row_iterator InternalRowIterator;
+    typedef typename InternalTraverser::column_iterator InternalColumnIterator;
+    typedef BSpline<ORDER, double> Spline;
+
+    enum { ksize_ = ORDER + 1, kcenter_ = ORDER / 2 };
+
+  public:
+
+        /** Construct SplineImageView for a 2D MultiArrayView.
+
+            If <tt>skipPrefiltering = true</tt> (default: <tt>false</tt>), the recursive
+            prefilter of the cardinal spline function is not applied, resulting
+            in an approximating (smoothing) rather than interpolating spline. This is
+            especially useful if customized prefilters are to be applied.
+        */
+    template <class U, class S>
+    SplineImageView(MultiArrayView<2, U, S> const & s, bool skipPrefiltering = false)
+    : w_(s.shape(0)), h_(s.shape(1)), w1_(w_-1), h1_(h_-1),
+      x0_(kcenter_), x1_(w_ - kcenter_ - 2), y0_(kcenter_), y1_(h_ - kcenter_ - 2),
+      image_(w_, h_),
+      x_(-1.0), y_(-1.0),
+      u_(-1.0), v_(-1.0)
+    {
+        copyImage(srcImageRange(s), destImage(image_));
+        if(!skipPrefiltering)
+            init();
+    }
+
+        /** Construct SplineImageView for an image given by \ref ImageIterators and \ref DataAccessors.
+
+            If <tt>skipPrefiltering = true</tt> (default: <tt>false</tt>), the recursive
+            prefilter of the cardinal spline function is not applied, resulting
+            in an approximating (smoothing) rather than interpolating spline. This is
+            especially useful if customized prefilters are to be applied.
+        */
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa, bool skipPrefiltering = false)
+    : w_(iend.x - is.x), h_(iend.y - is.y), w1_(w_-1), h1_(h_-1),
+      x0_(kcenter_), x1_(w_ - kcenter_ - 2), y0_(kcenter_), y1_(h_ - kcenter_ - 2),
+      image_(w_, h_),
+      x_(-1.0), y_(-1.0),
+      u_(-1.0), v_(-1.0)
+    {
+        copyImage(srcIterRange(is, iend, sa), destImage(image_));
+        if(!skipPrefiltering)
+            init();
+    }
+
+        /** Construct SplineImageView for an image given by  \ref ArgumentObjectFactories.
+
+            If <tt>skipPrefiltering = true</tt> (default: <tt>false</tt>), the recursive
+            prefilter of the cardinal spline function is not applied, resulting
+            in an approximating (smoothing) rather than interpolating spline. This is
+            especially useful if customized prefilters are to be applied.
+        */
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView(triple<SrcIterator, SrcIterator, SrcAccessor> s, bool skipPrefiltering = false)
+    : w_(s.second.x - s.first.x), h_(s.second.y - s.first.y), w1_(w_-1), h1_(h_-1),
+      x0_(kcenter_), x1_(w_ - kcenter_ - 2), y0_(kcenter_), y1_(h_ - kcenter_ - 2),
+      image_(w_, h_),
+      x_(-1.0), y_(-1.0),
+      u_(-1.0), v_(-1.0)
+    {
+        copyImage(srcIterRange(s.first, s.second, s.third), destImage(image_));
+        if(!skipPrefiltering)
+            init();
+    }
+
+        /** Access interpolated function at real-valued coordinate <tt>(x, y)</tt>.
+            If <tt>(x, y)</tt> is near the image border or outside the image, the value
+            is calculated with reflective boundary conditions. An exception is thrown if the
+            coordinate is outside the first reflection.
+        */
+    value_type operator()(double x, double y) const;
+
+        /** Access derivative of order <tt>(dx, dy)</tt> at real-valued coordinate <tt>(x, y)</tt>.
+            If <tt>(x, y)</tt> is near the image border or outside the image, the value
+            is calculated with reflective boundary conditions. An exception is thrown if the
+            coordinate is outside the first reflection.
+        */
+    value_type operator()(double x, double y, unsigned int dx, unsigned int dy) const;
+
+        /** Access 1st derivative in x-direction at real-valued coordinate <tt>(x, y)</tt>.
+            Equivalent to <tt>splineView(x, y, 1, 0)</tt>.
+        */
+    value_type dx(double x, double y) const
+        { return operator()(x, y, 1, 0); }
+
+        /** Access 1st derivative in y-direction at real-valued coordinate <tt>(x, y)</tt>.
+            Equivalent to <tt>splineView(x, y, 0, 1)</tt>.
+        */
+    value_type dy(double x, double y) const
+        { return operator()(x, y, 0, 1); }
+
+        /** Access 2nd derivative in x-direction at real-valued coordinate <tt>(x, y)</tt>.
+            Equivalent to <tt>splineView(x, y, 2, 0)</tt>.
+        */
+    value_type dxx(double x, double y) const
+        { return operator()(x, y, 2, 0); }
+
+        /** Access mixed 2nd derivative at real-valued coordinate <tt>(x, y)</tt>.
+            Equivalent to <tt>splineView(x, y, 1, 1)</tt>.
+        */
+    value_type dxy(double x, double y) const
+        { return operator()(x, y, 1, 1); }
+
+        /** Access 2nd derivative in y-direction at real-valued coordinate <tt>(x, y)</tt>.
+            Equivalent to <tt>splineView(x, y, 0, 2)</tt>.
+        */
+    value_type dyy(double x, double y) const
+        { return operator()(x, y, 0, 2); }
+
+        /** Access 3rd derivative in x-direction at real-valued coordinate <tt>(x, y)</tt>.
+            Equivalent to <tt>splineView(x, y, 3, 0)</tt>.
+        */
+    value_type dx3(double x, double y) const
+        { return operator()(x, y, 3, 0); }
+
+        /** Access 3rd derivative in y-direction at real-valued coordinate <tt>(x, y)</tt>.
+            Equivalent to <tt>splineView(x, y, 0, 3)</tt>.
+        */
+    value_type dy3(double x, double y) const
+        { return operator()(x, y, 0, 3); }
+
+        /** Access mixed 3rd derivative dxxy at real-valued coordinate <tt>(x, y)</tt>.
+            Equivalent to <tt>splineView(x, y, 2, 1)</tt>.
+        */
+    value_type dxxy(double x, double y) const
+        { return operator()(x, y, 2, 1); }
+
+        /** Access mixed 3rd derivative dxyy at real-valued coordinate <tt>(x, y)</tt>.
+            Equivalent to <tt>splineView(x, y, 1, 2)</tt>.
+        */
+    value_type dxyy(double x, double y) const
+        { return operator()(x, y, 1, 2); }
+
+        /** Access interpolated function at real-valued coordinate <tt>d</tt>.
+            Equivalent to <tt>splineView(d[0], d[1])</tt>.
+        */
+    value_type operator()(difference_type const & d) const
+        { return operator()(d[0], d[1]); }
+
+        /** Access derivative of order <tt>(dx, dy)</tt> at real-valued coordinate <tt>d</tt>.
+            Equivalent to <tt>splineView(d[0], d[1], dx, dy)</tt>.
+        */
+    value_type operator()(difference_type const & d, unsigned int dx, unsigned int dy) const
+        { return operator()(d[0], d[1], dx, dy); }
+
+        /** Access 1st derivative in x-direction at real-valued coordinate <tt>d</tt>.
+            Equivalent to <tt>splineView.dx(d[0], d[1])</tt>.
+        */
+    value_type dx(difference_type const & d) const
+        { return dx(d[0], d[1]); }
+
+        /** Access 1st derivative in y-direction at real-valued coordinate <tt>d</tt>.
+            Equivalent to <tt>splineView.dy(d[0], d[1])</tt>.
+        */
+    value_type dy(difference_type const & d) const
+        { return dy(d[0], d[1]); }
+
+        /** Access 2nd derivative in x-direction at real-valued coordinate <tt>d</tt>.
+            Equivalent to <tt>splineView.dxx(d[0], d[1])</tt>.
+        */
+    value_type dxx(difference_type const & d) const
+        { return dxx(d[0], d[1]); }
+
+        /** Access mixed 2nd derivative at real-valued coordinate <tt>d</tt>.
+            Equivalent to <tt>splineView.dxy(d[0], d[1])</tt>.
+        */
+    value_type dxy(difference_type const & d) const
+        { return dxy(d[0], d[1]); }
+
+        /** Access 2nd derivative in y-direction at real-valued coordinate <tt>d</tt>.
+            Equivalent to <tt>splineView.dyy(d[0], d[1])</tt>.
+        */
+    value_type dyy(difference_type const & d) const
+        { return dyy(d[0], d[1]); }
+
+        /** Access 3rd derivative in x-direction at real-valued coordinate <tt>d</tt>.
+            Equivalent to <tt>splineView.dx3(d[0], d[1])</tt>.
+        */
+    value_type dx3(difference_type const & d) const
+        { return dx3(d[0], d[1]); }
+
+        /** Access 3rd derivative in y-direction at real-valued coordinate <tt>d</tt>.
+            Equivalent to <tt>splineView.dy3(d[0], d[1])</tt>.
+        */
+    value_type dy3(difference_type const & d) const
+        { return dy3(d[0], d[1]); }
+
+        /** Access mixed 3rd derivative dxxy at real-valued coordinate <tt>d</tt>.
+            Equivalent to <tt>splineView.dxxy(d[0], d[1])</tt>.
+        */
+    value_type dxxy(difference_type const & d) const
+        { return dxxy(d[0], d[1]); }
+
+        /** Access mixed 3rd derivative dxyy at real-valued coordinate <tt>d</tt>.
+            Equivalent to <tt>splineView.dxyy(d[0], d[1])</tt>.
+        */
+    value_type dxyy(difference_type const & d) const
+        { return dxyy(d[0], d[1]); }
+
+        /** Access gradient squared magnitude at real-valued coordinate <tt>(x, y)</tt>.
+        */
+    SquaredNormType g2(double x, double y) const;
+
+        /** Access 1st derivative in x-direction of gradient squared magnitude
+            at real-valued coordinate <tt>(x, y)</tt>.
+        */
+    SquaredNormType g2x(double x, double y) const;
+
+        /** Access 1st derivative in y-direction of gradient squared magnitude
+            at real-valued coordinate <tt>(x, y)</tt>.
+        */
+    SquaredNormType g2y(double x, double y) const;
+
+        /** Access 2nd derivative in x-direction of gradient squared magnitude
+            at real-valued coordinate <tt>(x, y)</tt>.
+        */
+    SquaredNormType g2xx(double x, double y) const;
+
+        /** Access mixed 2nd derivative of gradient squared magnitude
+            at real-valued coordinate <tt>(x, y)</tt>.
+        */
+    SquaredNormType g2xy(double x, double y) const;
+
+        /** Access 2nd derivative in y-direction of gradient squared magnitude
+            at real-valued coordinate <tt>(x, y)</tt>.
+        */
+    SquaredNormType g2yy(double x, double y) const;
+
+        /** Access gradient squared magnitude at real-valued coordinate <tt>d</tt>.
+        */
+    SquaredNormType g2(difference_type const & d) const
+        { return g2(d[0], d[1]); }
+
+        /** Access 1st derivative in x-direction of gradient squared magnitude
+            at real-valued coordinate <tt>d</tt>.
+        */
+    SquaredNormType g2x(difference_type const & d) const
+        { return g2x(d[0], d[1]); }
+
+        /** Access 1st derivative in y-direction of gradient squared magnitude
+            at real-valued coordinate <tt>d</tt>.
+        */
+    SquaredNormType g2y(difference_type const & d) const
+        { return g2y(d[0], d[1]); }
+
+        /** Access 2nd derivative in x-direction of gradient squared magnitude
+            at real-valued coordinate <tt>d</tt>.
+        */
+    SquaredNormType g2xx(difference_type const & d) const
+        { return g2xx(d[0], d[1]); }
+
+        /** Access mixed 2nd derivative of gradient squared magnitude
+            at real-valued coordinate <tt>d</tt>.
+        */
+    SquaredNormType g2xy(difference_type const & d) const
+        { return g2xy(d[0], d[1]); }
+
+        /** Access 2nd derivative in y-direction of gradient squared magnitude
+            at real-valued coordinate <tt>d</tt>.
+        */
+    SquaredNormType g2yy(difference_type const & d) const
+        { return g2yy(d[0], d[1]); }
+
+        /** The width of the image.
+            <tt>0 <= x <= width()-1</tt> is required for all access functions.
+        */
+    unsigned int width() const
+        { return w_; }
+
+        /** The height of the image.
+            <tt>0 <= y <= height()-1</tt> is required for all access functions.
+        */
+    unsigned int height() const
+        { return h_; }
+
+        /** The size of the image.
+            <tt>0 <= x <= size().x-1</tt> and <tt>0 <= y <= size().y-1</tt>
+            are required for all access functions.
+        */
+    size_type size() const
+        { return size_type(w_, h_); }
+
+        /** The shape of the image.
+            Same as size(), except for the return type.
+        */
+    TinyVector<unsigned int, 2> shape() const
+        { return TinyVector<unsigned int, 2>(w_, h_); }
+
+        /** The internal image holding the spline coefficients.
+        */
+    InternalImage const & image() const
+    {
+        return image_;
+    }
+
+        /** Get the array of polynomial coefficients for the facet containing
+            the point <tt>(x, y)</tt>. The array <tt>res</tt> must have
+            dimension <tt>(ORDER+1)x(ORDER+1)</tt>. From these coefficients, the
+            value of the interpolated function can be calculated by the following
+            algorithm
+
+            \code
+            SplineImageView<ORDER, float> view(...);
+            double x = ..., y = ...;
+            double dx, dy;
+
+            // calculate the local facet coordinates of x and y
+            if(ORDER % 2)
+            {
+                // odd order => facet coordinates between 0 and 1
+                dx = x - floor(x);
+                dy = y - floor(y);
+            }
+            else
+            {
+                // even order => facet coordinates between -0.5 and 0.5
+                dx = x - floor(x + 0.5);
+                dy = y - floor(y + 0.5);
+            }
+
+            BasicImage<float> coefficients;
+            view.coefficientArray(x, y, coefficients);
+
+            float f_x_y = 0.0;
+            for(int ny = 0; ny < ORDER + 1; ++ny)
+                for(int nx = 0; nx < ORDER + 1; ++nx)
+                    f_x_y += pow(dx, nx) * pow(dy, ny) * coefficients(nx, ny);
+
+            assert(abs(f_x_y - view(x, y)) < 1e-6);
+            \endcode
+        */
+    template <class Array>
+    void coefficientArray(double x, double y, Array & res) const;
+
+        /** Check if x is in the original image range.
+            Equivalent to <tt>0 <= x <= width()-1</tt>.
+        */
+    bool isInsideX(double x) const
+    {
+        return x >= 0.0 && x <= width()-1.0;
+    }
+
+        /** Check if y is in the original image range.
+            Equivalent to <tt>0 <= y <= height()-1</tt>.
+        */
+    bool isInsideY(double y) const
+    {
+        return y >= 0.0 && y <= height()-1.0;
+    }
+
+        /** Check if x and y are in the original image range.
+            Equivalent to <tt>0 <= x <= width()-1</tt> and <tt>0 <= y <= height()-1</tt>.
+        */
+    bool isInside(double x, double y) const
+    {
+        return isInsideX(x) && isInsideY(y);
+    }
+
+        /** Check if x and y are in the valid range. Points outside the original image range are computed
+            by reflective boundary conditions, but only within the first reflection.
+            Equivalent to <tt>-width() + ORDER/2 + 2 < x < 2*width() - ORDER/2 - 2</tt> and
+            <tt>-height() + ORDER/2 + 2 < y < 2*height() - ORDER/2 - 2</tt>.
+        */
+    bool isValid(double x, double y) const
+    {
+        return x < w1_ + x1_ && x > -x1_ && y < h1_ + y1_ && y > -y1_;
+    }
+
+        /** Check whether the points <tt>(x0, y0)</tt> and <tt>(x1, y1)</tt> are in
+            the same spline facet. For odd order splines, facets span the range
+            <tt>(floor(x), floor(x)+1) x (floor(y), floor(y)+1)</tt> (i.e. we have
+            integer facet borders), whereas even order splines have facet between
+            half integer values
+            <tt>(floor(x)-0.5, floor(x)+0.5) x (floor(y)-0.5, floor(y)+0.5)</tt>.
+        */
+    bool sameFacet(double x0, double y0, double x1, double y1) const
+    {
+         x0 = VIGRA_CSTD::floor((ORDER % 2) ? x0 : x0 + 0.5);
+         y0 = VIGRA_CSTD::floor((ORDER % 2) ? y0 : y0 + 0.5);
+         x1 = VIGRA_CSTD::floor((ORDER % 2) ? x1 : x1 + 0.5);
+         y1 = VIGRA_CSTD::floor((ORDER % 2) ? y1 : y1 + 0.5);
+         return x0 == x1 && y0 == y1;
+    }
+
+  protected:
+
+    void init();
+    void calculateIndices(double x, double y) const;
+    void coefficients(double t, double * const & c) const;
+    void derivCoefficients(double t, unsigned int d, double * const & c) const;
+    value_type convolve() const;
+
+    unsigned int w_, h_;
+    int w1_, h1_;
+    double x0_, x1_, y0_, y1_;
+    InternalImage image_;
+    Spline k_;
+    mutable double x_, y_, u_, v_, kx_[ksize_], ky_[ksize_];
+    mutable int ix_[ksize_], iy_[ksize_];
+};
+
+template <int ORDER, class VALUETYPE>
+void SplineImageView<ORDER, VALUETYPE>::init()
+{
+    ArrayVector<double> const & b = k_.prefilterCoefficients();
+
+    for(unsigned int i=0; i<b.size(); ++i)
+    {
+        recursiveFilterX(srcImageRange(image_), destImage(image_), b[i], BORDER_TREATMENT_REFLECT);
+        recursiveFilterY(srcImageRange(image_), destImage(image_), b[i], BORDER_TREATMENT_REFLECT);
+    }
+}
+
+namespace detail
+{
+
+template <int i>
+struct SplineImageViewUnrollLoop1
+{
+    template <class Array>
+    static void exec(int c0, Array c)
+    {
+        SplineImageViewUnrollLoop1<i-1>::exec(c0, c);
+        c[i] = c0 + i;
+    }
+};
+
+template <>
+struct SplineImageViewUnrollLoop1<0>
+{
+    template <class Array>
+    static void exec(int c0, Array c)
+    {
+        c[0] = c0;
+    }
+};
+
+template <int i, class ValueType>
+struct SplineImageViewUnrollLoop2
+{
+    template <class Array1, class RowIterator, class Array2>
+    static ValueType
+    exec(Array1 k, RowIterator r, Array2 x)
+    {
+        return ValueType(k[i] * r[x[i]]) + SplineImageViewUnrollLoop2<i-1, ValueType>::exec(k, r, x);
+    }
+};
+
+template <class ValueType>
+struct SplineImageViewUnrollLoop2<0, ValueType>
+{
+    template <class Array1, class RowIterator, class Array2>
+    static ValueType
+    exec(Array1 k, RowIterator r, Array2 x)
+    {
+        return ValueType(k[0] * r[x[0]]);
+    }
+};
+
+} // namespace detail
+
+template <int ORDER, class VALUETYPE>
+void
+SplineImageView<ORDER, VALUETYPE>::calculateIndices(double x, double y) const
+{
+    if(x == x_ && y == y_)
+        return;   // still in cache
+
+    if(x > x0_ && x < x1_ && y > y0_ && y < y1_)
+    {
+        detail::SplineImageViewUnrollLoop1<ORDER>::exec(
+                                (ORDER % 2) ? int(x - kcenter_) : int(x + 0.5 - kcenter_), ix_);
+        detail::SplineImageViewUnrollLoop1<ORDER>::exec(
+                                (ORDER % 2) ? int(y - kcenter_) : int(y + 0.5 - kcenter_), iy_);
+
+        u_ = x - ix_[kcenter_];
+        v_ = y - iy_[kcenter_];
+    }
+    else
+    {
+        vigra_precondition(isValid(x,y),
+                    "SplineImageView::calculateIndices(): coordinates out of range.");
+
+        int xCenter = (ORDER % 2) ?
+                      (int)VIGRA_CSTD::floor(x) :
+                      (int)VIGRA_CSTD::floor(x + 0.5);
+        int yCenter = (ORDER % 2) ?
+                      (int)VIGRA_CSTD::floor(y) :
+                      (int)VIGRA_CSTD::floor(y + 0.5);
+
+        if(x >= x1_)
+        {
+            for(int i = 0; i < ksize_; ++i)
+                ix_[i] = w1_ - vigra::abs(w1_ - xCenter - (i - kcenter_));
+        }
+        else
+        {
+            for(int i = 0; i < ksize_; ++i)
+                ix_[i] = vigra::abs(xCenter - (kcenter_ - i));
+        }
+        if(y >= y1_)
+        {
+            for(int i = 0; i < ksize_; ++i)
+                iy_[i] = h1_ - vigra::abs(h1_ - yCenter - (i - kcenter_));
+        }
+        else
+        {
+            for(int i = 0; i < ksize_; ++i)
+                iy_[i] = vigra::abs(yCenter - (kcenter_ - i));
+        }
+        u_ = x - xCenter;
+        v_ = y - yCenter;
+    }
+    x_ = x;
+    y_ = y;
+}
+
+template <int ORDER, class VALUETYPE>
+void SplineImageView<ORDER, VALUETYPE>::coefficients(double t, double * const & c) const
+{
+    t += kcenter_;
+    for(int i = 0; i<ksize_; ++i)
+        c[i] = k_(t-i);
+}
+
+template <int ORDER, class VALUETYPE>
+void SplineImageView<ORDER, VALUETYPE>::derivCoefficients(double t,
+                                               unsigned int d, double * const & c) const
+{
+    t += kcenter_;
+    for(int i = 0; i<ksize_; ++i)
+        c[i] = k_(t-i, d);
+}
+
+template <int ORDER, class VALUETYPE>
+VALUETYPE SplineImageView<ORDER, VALUETYPE>::convolve() const
+{
+    typedef typename NumericTraits<VALUETYPE>::RealPromote RealPromote;
+    RealPromote sum;
+    sum = RealPromote(
+      ky_[0]*detail::SplineImageViewUnrollLoop2<ORDER, RealPromote>::exec(kx_, image_.rowBegin(iy_[0]), ix_));
+
+    for(int j=1; j<ksize_; ++j)
+    {
+        sum += RealPromote(
+          ky_[j]*detail::SplineImageViewUnrollLoop2<ORDER, RealPromote>::exec(kx_, image_.rowBegin(iy_[j]), ix_));
+    }
+    return detail::RequiresExplicitCast<VALUETYPE>::cast(sum);
+}
+
+template <int ORDER, class VALUETYPE>
+template <class Array>
+void
+SplineImageView<ORDER, VALUETYPE>::coefficientArray(double x, double y, Array & res) const
+{
+    typedef typename Array::value_type ResType;
+    typename Spline::WeightMatrix const & weights = Spline::weights();
+    ResType tmp[ksize_][ksize_];
+
+    calculateIndices(x, y);
+    for(int j=0; j<ksize_; ++j)
+    {
+        for(int i=0; i<ksize_; ++i)
+        {
+            tmp[i][j] = ResType();
+            for(int k=0; k<ksize_; ++k)
+            {
+                tmp[i][j] += weights[i][k]*image_(ix_[k], iy_[j]);
+            }
+       }
+    }
+    for(int j=0; j<ksize_; ++j)
+    {
+        for(int i=0; i<ksize_; ++i)
+        {
+            res(i,j) = ResType();
+            for(int k=0; k<ksize_; ++k)
+            {
+                res(i,j) += weights[j][k]*tmp[i][k];
+            }
+        }
+    }
+}
+
+template <int ORDER, class VALUETYPE>
+VALUETYPE SplineImageView<ORDER, VALUETYPE>::operator()(double x, double y) const
+{
+    calculateIndices(x, y);
+    coefficients(u_, kx_);
+    coefficients(v_, ky_);
+    return convolve();
+}
+
+template <int ORDER, class VALUETYPE>
+VALUETYPE SplineImageView<ORDER, VALUETYPE>::operator()(double x, double y,
+                                                 unsigned int dx, unsigned int dy) const
+{
+    calculateIndices(x, y);
+    derivCoefficients(u_, dx, kx_);
+    derivCoefficients(v_, dy, ky_);
+    return convolve();
+}
+
+template <int ORDER, class VALUETYPE>
+typename SplineImageView<ORDER, VALUETYPE>::SquaredNormType
+SplineImageView<ORDER, VALUETYPE>::g2(double x, double y) const
+{
+    return squaredNorm(dx(x,y)) + squaredNorm(dy(x,y));
+}
+
+template <int ORDER, class VALUETYPE>
+typename SplineImageView<ORDER, VALUETYPE>::SquaredNormType
+SplineImageView<ORDER, VALUETYPE>::g2x(double x, double y) const
+{
+    return SquaredNormType(2.0)*(dot(dx(x,y), dxx(x,y)) + dot(dy(x,y), dxy(x,y)));
+}
+
+template <int ORDER, class VALUETYPE>
+typename SplineImageView<ORDER, VALUETYPE>::SquaredNormType
+SplineImageView<ORDER, VALUETYPE>::g2y(double x, double y) const
+{
+    return SquaredNormType(2.0)*(dot(dx(x,y), dxy(x,y)) + dot(dy(x,y), dyy(x,y)));
+}
+
+template <int ORDER, class VALUETYPE>
+typename SplineImageView<ORDER, VALUETYPE>::SquaredNormType
+SplineImageView<ORDER, VALUETYPE>::g2xx(double x, double y) const
+{
+    return SquaredNormType(2.0)*(squaredNorm(dxx(x,y)) + dot(dx(x,y), dx3(x,y)) + 
+                                 squaredNorm(dxy(x,y)) + dot(dy(x,y), dxxy(x,y)));
+}
+
+template <int ORDER, class VALUETYPE>
+typename SplineImageView<ORDER, VALUETYPE>::SquaredNormType
+SplineImageView<ORDER, VALUETYPE>::g2yy(double x, double y) const
+{
+    return SquaredNormType(2.0)*(squaredNorm(dxy(x,y)) + dot(dx(x,y), dxyy(x,y)) + 
+                                 squaredNorm(dyy(x,y)) + dot(dy(x,y), dy3(x,y)));
+}
+
+template <int ORDER, class VALUETYPE>
+typename SplineImageView<ORDER, VALUETYPE>::SquaredNormType
+SplineImageView<ORDER, VALUETYPE>::g2xy(double x, double y) const
+{
+    return SquaredNormType(2.0)*(dot(dx(x,y), dxxy(x,y)) + dot(dy(x,y), dxyy(x,y)) + 
+                                 dot(dxy(x,y), dxx(x,y) + dyy(x,y)));
+}
+
+/********************************************************/
+/*                                                      */
+/*                    SplineImageView0                  */
+/*                                                      */
+/********************************************************/
+template <class VALUETYPE, class INTERNAL_INDEXER>
+class SplineImageView0Base
+{
+    typedef typename INTERNAL_INDEXER::value_type InternalValue;
+  public:
+    typedef VALUETYPE value_type;
+    typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType;
+    typedef Size2D size_type;
+    typedef TinyVector<double, 2> difference_type;
+    enum StaticOrder { order = 0 };
+
+  public:
+
+    SplineImageView0Base(unsigned int w, unsigned int h)
+    : w_(w), h_(h)
+    {}
+
+    SplineImageView0Base(int w, int h, INTERNAL_INDEXER i)
+    : w_(w), h_(h), internalIndexer_(i)
+    {}
+
+    template <unsigned IntBits1, unsigned FractionalBits1,
+              unsigned IntBits2, unsigned FractionalBits2>
+    value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
+                         FixedPoint<IntBits2, FractionalBits2> y) const
+    {
+        return internalIndexer_(round(x), round(y));
+    }
+
+    template <unsigned IntBits1, unsigned FractionalBits1,
+              unsigned IntBits2, unsigned FractionalBits2>
+    value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
+                         FixedPoint<IntBits2, FractionalBits2> y,
+                         unsigned int dx, unsigned int dy) const
+    {
+        if((dx != 0) || (dy != 0))
+            return NumericTraits<VALUETYPE>::zero();
+        return unchecked(x, y);
+    }
+
+    value_type unchecked(double x, double y) const
+    {
+        return internalIndexer_((int)(x + 0.5), (int)(y + 0.5));
+    }
+
+    value_type unchecked(double x, double y, unsigned int dx, unsigned int dy) const
+    {
+        if((dx != 0) || (dy != 0))
+            return NumericTraits<VALUETYPE>::zero();
+        return unchecked(x, y);
+    }
+
+    value_type operator()(double x, double y) const
+    {
+        int ix, iy;
+        if(x < 0.0)
+        {
+            ix = (int)(-x + 0.5);
+            vigra_precondition(ix <= (int)w_ - 1,
+                    "SplineImageView::operator(): coordinates out of range.");
+        }
+        else
+        {
+            ix = (int)(x + 0.5);
+            if(ix >= (int)w_)
+            {
+                ix = 2*w_-2-ix;
+                vigra_precondition(ix >= 0,
+                        "SplineImageView::operator(): coordinates out of range.");
+            }
+        }
+        if(y < 0.0)
+        {
+            iy = (int)(-y + 0.5);
+            vigra_precondition(iy <= (int)h_ - 1,
+                    "SplineImageView::operator(): coordinates out of range.");
+        }
+        else
+        {
+            iy = (int)(y + 0.5);
+            if(iy >= (int)h_)
+            {
+                iy = 2*h_-2-iy;
+                vigra_precondition(iy >= 0,
+                        "SplineImageView::operator(): coordinates out of range.");
+            }
+        }
+        return internalIndexer_(ix, iy);
+    }
+
+    value_type operator()(double x, double y, unsigned int dx, unsigned int dy) const
+    {
+        if((dx != 0) || (dy != 0))
+            return NumericTraits<VALUETYPE>::zero();
+        return operator()(x, y);
+    }
+
+    value_type dx(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dy(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxx(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxy(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dyy(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dx3(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dy3(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxxy(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxyy(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type operator()(difference_type const & d) const
+        { return operator()(d[0], d[1]); }
+
+    value_type operator()(difference_type const & d, unsigned int dx, unsigned int dy) const
+        { return operator()(d[0], d[1], dx, dy); }
+
+    value_type dx(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dy(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxx(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxy(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dyy(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dx3(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dy3(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxxy(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxyy(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    SquaredNormType g2(double x, double y) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2x(double x, double y) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2y(double x, double y) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2xx(double x, double y) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2xy(double x, double y) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2yy(double x, double y) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2(difference_type const & d) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2x(difference_type const & d) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2y(difference_type const & d) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2xx(difference_type const & d) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2xy(difference_type const & d) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2yy(difference_type const & d) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    unsigned int width() const
+        { return w_; }
+
+    unsigned int height() const
+        { return h_; }
+
+    size_type size() const
+        { return size_type(w_, h_); }
+
+    TinyVector<unsigned int, 2> shape() const
+        { return TinyVector<unsigned int, 2>(w_, h_); }
+
+    template <class Array>
+    void coefficientArray(double x, double y, Array & res) const
+    {
+        res(0, 0) = operator()(x,y);
+    }
+
+    bool isInsideX(double x) const
+    {
+        return x >= 0.0 && x <= width() - 1.0;
+    }
+
+    bool isInsideY(double y) const
+    {
+        return y >= 0.0 && y <= height() - 1.0;
+    }
+
+    bool isInside(double x, double y) const
+    {
+        return isInsideX(x) && isInsideY(y);
+    }
+
+    bool isValid(double x, double y) const
+    {
+        return x < 2.0*w_-2.0 && x > 1.0-w_ && y < 2.0*h_-2.0 && y > 1.0-h_;
+    }
+
+    bool sameFacet(double x0, double y0, double x1, double y1) const
+    {
+         x0 = VIGRA_CSTD::floor(x0 + 0.5);
+         y0 = VIGRA_CSTD::floor(y0 + 0.5);
+         x1 = VIGRA_CSTD::floor(x1 + 0.5);
+         y1 = VIGRA_CSTD::floor(y1 + 0.5);
+         return x0 == x1 && y0 == y1;
+    }
+
+  protected:
+    unsigned int w_, h_;
+    INTERNAL_INDEXER internalIndexer_;
+};
+
+/** \brief Create an image view for nearest-neighbor interpolation.
+
+    This class behaves like \ref vigra::SplineImageView<0, ...>, but one can pass
+    an additional template argument that determined the internal representation of the image.
+    If this is equal to the argument type passed in the constructor, the image is not copied.
+    By default, this works for \ref vigra::BasicImage, \ref vigra::BasicImageView,
+    \ref vigra::MultiArray<2, ...>, and \ref vigra::MultiArrayView<2, ...>.
+
+*/
+template <class VALUETYPE, class INTERNAL_TRAVERSER = typename BasicImage<VALUETYPE>::const_traverser>
+class SplineImageView0
+: public SplineImageView0Base<VALUETYPE, INTERNAL_TRAVERSER>
+{
+    typedef SplineImageView0Base<VALUETYPE, INTERNAL_TRAVERSER> Base;
+  public:
+    typedef typename Base::value_type value_type;
+    typedef typename Base::SquaredNormType SquaredNormType;
+    typedef typename Base::size_type size_type;
+    typedef typename Base::difference_type difference_type;
+    enum StaticOrder { order = Base::order };
+    typedef BasicImage<VALUETYPE> InternalImage;
+
+  protected:
+    typedef typename IteratorTraits<INTERNAL_TRAVERSER>::mutable_iterator InternalTraverser;
+    typedef typename IteratorTraits<InternalTraverser>::DefaultAccessor InternalAccessor;
+    typedef typename IteratorTraits<INTERNAL_TRAVERSER>::const_iterator InternalConstTraverser;
+    typedef typename IteratorTraits<InternalConstTraverser>::DefaultAccessor InternalConstAccessor;
+
+  public:
+
+        /* when traverser and accessor types passed to the constructor are the same as the corresponding
+           internal types, we need not copy the image (speed up)
+        */
+    SplineImageView0(InternalTraverser is, InternalTraverser iend, InternalAccessor sa)
+    : Base(iend.x - is.x, iend.y - is.y, is)
+    {}
+
+    SplineImageView0(triple<InternalTraverser, InternalTraverser, InternalAccessor> s)
+    : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
+    {}
+
+    SplineImageView0(InternalConstTraverser is, InternalConstTraverser iend, InternalConstAccessor sa)
+    : Base(iend.x - is.x, iend.y - is.y, is)
+    {}
+
+    SplineImageView0(triple<InternalConstTraverser, InternalConstTraverser, InternalConstAccessor> s)
+    : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
+    {}
+
+    template<class T, class SU>
+    SplineImageView0(MultiArrayView<2, T, SU> const & i)
+    : Base(i.shape(0), i.shape(1)),
+      image_(i.shape(0), i.shape(1))
+    {
+        for(unsigned int y=0; y<this->height(); ++y)
+            for(unsigned int x=0; x<this->width(); ++x)
+                image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast(i(x,y));
+        this->internalIndexer_ = image_.upperLeft();
+    }
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView0(SrcIterator is, SrcIterator iend, SrcAccessor sa)
+    : Base(iend.x - is.x, iend.y - is.y),
+      image_(iend - is)
+    {
+        copyImage(srcIterRange(is, iend, sa), destImage(image_));
+        this->internalIndexer_ = image_.upperLeft();
+    }
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView0(triple<SrcIterator, SrcIterator, SrcAccessor> s)
+    : Base(s.second.x - s.first.x, s.second.y - s.first.y),
+      image_(s.second - s.first)
+    {
+        copyImage(s, destImage(image_));
+        this->internalIndexer_ = image_.upperLeft();
+    }
+
+    InternalImage const & image() const
+        { return image_; }
+
+  protected:
+    InternalImage image_;
+};
+
+template <class VALUETYPE, class StridedOrUnstrided>
+class SplineImageView0<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> >
+: public SplineImageView0Base<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> >
+{
+    typedef SplineImageView0Base<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> > Base;
+  public:
+    typedef typename Base::value_type value_type;
+    typedef typename Base::SquaredNormType SquaredNormType;
+    typedef typename Base::size_type size_type;
+    typedef typename Base::difference_type difference_type;
+    enum StaticOrder { order = Base::order };
+    typedef BasicImage<VALUETYPE> InternalImage;
+
+  protected:
+    typedef MultiArrayView<2, VALUETYPE, StridedOrUnstrided> InternalIndexer;
+
+  public:
+
+        /* when traverser and accessor types passed to the constructor are the same as the corresponding
+           internal types, we need not copy the image (speed up)
+        */
+    SplineImageView0(InternalIndexer const & i)
+    : Base(i.shape(0), i.shape(1), i)
+    {}
+
+    template<class T, class SU>
+    SplineImageView0(MultiArrayView<2, T, SU> const & i)
+    : Base(i.shape(0), i.shape(1)),
+      image_(i.shape(0), i.shape(1))
+    {
+        for(unsigned int y=0; y<this->height(); ++y)
+            for(unsigned int x=0; x<this->width(); ++x)
+                image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast(i(x,y));
+        this->internalIndexer_ = InternalIndexer(typename InternalIndexer::difference_type(this->width(), this->height()),
+                                                 image_.data());
+    }
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView0(SrcIterator is, SrcIterator iend, SrcAccessor sa)
+    : Base(iend.x - is.x, iend.y - is.y),
+      image_(iend-is)
+    {
+        copyImage(srcIterRange(is, iend, sa), destImage(image_));
+        this->internalIndexer_ = InternalIndexer(typename InternalIndexer::difference_type(this->width(), this->height()),
+                                                 image_.data());
+    }
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView0(triple<SrcIterator, SrcIterator, SrcAccessor> s)
+    : Base(s.second.x - s.first.x, s.second.y - s.first.y),
+      image_(s.second - s.first)
+    {
+        copyImage(s, destImage(image_));
+        this->internalIndexer_ = InternalIndexer(typename InternalIndexer::difference_type(this->width(), this->height()),
+                                                 image_.data());
+    }
+
+    InternalImage const & image() const
+        { return image_; }
+
+  protected:
+    InternalImage image_;
+};
+
+template <class VALUETYPE>
+class SplineImageView<0, VALUETYPE>
+: public SplineImageView0<VALUETYPE>
+{
+    typedef SplineImageView0<VALUETYPE> Base;
+  public:
+    typedef typename Base::value_type value_type;
+    typedef typename Base::SquaredNormType SquaredNormType;
+    typedef typename Base::size_type size_type;
+    typedef typename Base::difference_type difference_type;
+    enum StaticOrder { order = Base::order };
+    typedef typename Base::InternalImage InternalImage;
+
+  protected:
+    typedef typename Base::InternalTraverser InternalTraverser;
+    typedef typename Base::InternalAccessor InternalAccessor;
+    typedef typename Base::InternalConstTraverser InternalConstTraverser;
+    typedef typename Base::InternalConstAccessor InternalConstAccessor;
+
+public:
+
+        /* when traverser and accessor types passed to the constructor are the same as the corresponding
+           internal types, we need not copy the image (speed up)
+        */
+    SplineImageView(InternalTraverser is, InternalTraverser iend, InternalAccessor sa, bool /* unused */ = false)
+    : Base(is, iend, sa)
+    {}
+
+    SplineImageView(triple<InternalTraverser, InternalTraverser, InternalAccessor> s, bool /* unused */ = false)
+    : Base(s)
+    {}
+
+    SplineImageView(InternalConstTraverser is, InternalConstTraverser iend, InternalConstAccessor sa, bool /* unused */ = false)
+    : Base(is, iend, sa)
+    {}
+
+    SplineImageView(triple<InternalConstTraverser, InternalConstTraverser, InternalConstAccessor> s, bool /* unused */ = false)
+    : Base(s)
+    {}
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa, bool /* unused */ = false)
+    : Base(is, iend, sa)
+    {
+        copyImage(srcIterRange(is, iend, sa), destImage(this->image_));
+    }
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView(triple<SrcIterator, SrcIterator, SrcAccessor> s, bool /* unused */ = false)
+    : Base(s)
+    {
+        copyImage(s, destImage(this->image_));
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                    SplineImageView1                  */
+/*                                                      */
+/********************************************************/
+template <class VALUETYPE, class INTERNAL_INDEXER>
+class SplineImageView1Base
+{
+    typedef typename INTERNAL_INDEXER::value_type InternalValue;
+  public:
+    typedef VALUETYPE value_type;
+    typedef Size2D size_type;
+    typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType;
+    typedef TinyVector<double, 2> difference_type;
+    enum StaticOrder { order = 1 };
+
+  public:
+
+    SplineImageView1Base(unsigned int w, unsigned int h)
+    : w_(w), h_(h)
+    {}
+
+    SplineImageView1Base(int w, int h, INTERNAL_INDEXER i)
+    : w_(w), h_(h), internalIndexer_(i)
+    {}
+
+    template <unsigned IntBits1, unsigned FractionalBits1,
+              unsigned IntBits2, unsigned FractionalBits2>
+    value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
+                         FixedPoint<IntBits2, FractionalBits2> y) const
+    {
+        int ix = floor(x);
+        FixedPoint<0, FractionalBits1> tx = frac(x - FixedPoint<IntBits1, FractionalBits1>(ix));
+        FixedPoint<0, FractionalBits1> dtx = dual_frac(tx);
+        if(ix == (int)w_ - 1)
+        {
+            --ix;
+            tx.value = FixedPoint<0, FractionalBits1>::ONE;
+            dtx.value = 0;
+        }
+        int iy = floor(y);
+        FixedPoint<0, FractionalBits2> ty = frac(y - FixedPoint<IntBits2, FractionalBits2>(iy));
+        FixedPoint<0, FractionalBits2> dty = dual_frac(ty);
+        if(iy == (int)h_ - 1)
+        {
+            --iy;
+            ty.value = FixedPoint<0, FractionalBits2>::ONE;
+            dty.value = 0;
+        }
+        return fixed_point_cast<value_type>(
+                    dty*(dtx*fixedPoint(internalIndexer_(ix,iy)) +
+                                   tx*fixedPoint(internalIndexer_(ix+1,iy))) +
+                    ty *(dtx*fixedPoint(internalIndexer_(ix,iy+1)) +
+                                   tx*fixedPoint(internalIndexer_(ix+1,iy+1))));
+    }
+
+    template <unsigned IntBits1, unsigned FractionalBits1,
+              unsigned IntBits2, unsigned FractionalBits2>
+    value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
+                         FixedPoint<IntBits2, FractionalBits2> y,
+                         unsigned int dx, unsigned int dy) const
+    {
+        int ix = floor(x);
+        FixedPoint<0, FractionalBits1> tx = frac(x - FixedPoint<IntBits1, FractionalBits1>(ix));
+        FixedPoint<0, FractionalBits1> dtx = dual_frac(tx);
+        if(ix == (int)w_ - 1)
+        {
+            --ix;
+            tx.value = FixedPoint<0, FractionalBits1>::ONE;
+            dtx.value = 0;
+        }
+        int iy = floor(y);
+        FixedPoint<0, FractionalBits2> ty = frac(y - FixedPoint<IntBits2, FractionalBits2>(iy));
+        FixedPoint<0, FractionalBits2> dty = dual_frac(ty);
+        if(iy == (int)h_ - 1)
+        {
+            --iy;
+            ty.value = FixedPoint<0, FractionalBits2>::ONE;
+            dty.value = 0;
+        }
+        switch(dx)
+        {
+          case 0:
+              switch(dy)
+              {
+                case 0:
+                    return fixed_point_cast<value_type>(
+                                dty*(dtx*fixedPoint(internalIndexer_(ix,iy)) +
+                                               tx*fixedPoint(internalIndexer_(ix+1,iy))) +
+                                ty *(dtx*fixedPoint(internalIndexer_(ix,iy+1)) +
+                                               tx*fixedPoint(internalIndexer_(ix+1,iy+1))));
+                case 1:
+                    return fixed_point_cast<value_type>(
+                           (dtx*fixedPoint(internalIndexer_(ix,iy+1)) + tx*fixedPoint(internalIndexer_(ix+1,iy+1))) -
+                           (dtx*fixedPoint(internalIndexer_(ix,iy)) + tx*fixedPoint(internalIndexer_(ix+1,iy))));
+                default:
+                    return NumericTraits<VALUETYPE>::zero();
+              }
+          case 1:
+              switch(dy)
+              {
+                case 0:
+                    return fixed_point_cast<value_type>(
+                                dty*(fixedPoint(internalIndexer_(ix+1,iy)) - fixedPoint(internalIndexer_(ix,iy))) +
+                                ty *(fixedPoint(internalIndexer_(ix+1,iy+1)) - fixedPoint(internalIndexer_(ix,iy+1))));
+                case 1:
+                    return detail::RequiresExplicitCast<value_type>::cast(
+                                (internalIndexer_(ix+1,iy+1) - internalIndexer_(ix,iy+1)) -
+                                (internalIndexer_(ix+1,iy) - internalIndexer_(ix,iy)));
+                default:
+                    return NumericTraits<VALUETYPE>::zero();
+              }
+          default:
+              return NumericTraits<VALUETYPE>::zero();
+        }
+    }
+
+    value_type unchecked(double x, double y) const
+    {
+        int ix = (int)std::floor(x);
+        if(ix == (int)w_ - 1)
+            --ix;
+        double tx = x - ix;
+        int iy = (int)std::floor(y);
+        if(iy == (int)h_ - 1)
+            --iy;
+        double ty = y - iy;
+        return NumericTraits<value_type>::fromRealPromote(
+                   (1.0-ty)*((1.0-tx)*internalIndexer_(ix,iy) + tx*internalIndexer_(ix+1,iy)) +
+                    ty *((1.0-tx)*internalIndexer_(ix,iy+1) + tx*internalIndexer_(ix+1,iy+1)));
+    }
+
+    value_type unchecked(double x, double y, unsigned int dx, unsigned int dy) const
+    {
+        int ix = (int)std::floor(x);
+        if(ix == (int)w_ - 1)
+            --ix;
+        double tx = x - ix;
+        int iy = (int)std::floor(y);
+        if(iy == (int)h_ - 1)
+            --iy;
+        double ty = y - iy;
+        switch(dx)
+        {
+          case 0:
+              switch(dy)
+              {
+                case 0:
+                    return detail::RequiresExplicitCast<value_type>::cast(
+                               (1.0-ty)*((1.0-tx)*internalIndexer_(ix,iy) + tx*internalIndexer_(ix+1,iy)) +
+                                ty *((1.0-tx)*internalIndexer_(ix,iy+1) + tx*internalIndexer_(ix+1,iy+1)));
+                case 1:
+                    return detail::RequiresExplicitCast<value_type>::cast(
+                               ((1.0-tx)*internalIndexer_(ix,iy+1) + tx*internalIndexer_(ix+1,iy+1)) -
+                               ((1.0-tx)*internalIndexer_(ix,iy) + tx*internalIndexer_(ix+1,iy)));
+                default:
+                    return NumericTraits<VALUETYPE>::zero();
+              }
+          case 1:
+              switch(dy)
+              {
+                case 0:
+                    return detail::RequiresExplicitCast<value_type>::cast(
+                               (1.0-ty)*(internalIndexer_(ix+1,iy) - internalIndexer_(ix,iy)) +
+                                ty *(internalIndexer_(ix+1,iy+1) - internalIndexer_(ix,iy+1)));
+                case 1:
+                    return detail::RequiresExplicitCast<value_type>::cast(
+                              (internalIndexer_(ix+1,iy+1) - internalIndexer_(ix,iy+1)) -
+                              (internalIndexer_(ix+1,iy) - internalIndexer_(ix,iy)));
+                default:
+                    return NumericTraits<VALUETYPE>::zero();
+              }
+          default:
+              return NumericTraits<VALUETYPE>::zero();
+        }
+    }
+
+    value_type operator()(double x, double y) const
+    {
+        return operator()(x, y, 0, 0);
+    }
+
+    value_type operator()(double x, double y, unsigned int dx, unsigned int dy) const
+    {
+        value_type mul = NumericTraits<value_type>::one();
+        if(x < 0.0)
+        {
+            x = -x;
+            vigra_precondition(x <= w_ - 1.0,
+                    "SplineImageView::operator(): coordinates out of range.");
+            if(dx % 2)
+                mul = -mul;
+        }
+        else if(x > w_ - 1.0)
+        {
+            x = 2.0*w_-2.0-x;
+            vigra_precondition(x >= 0.0,
+                    "SplineImageView::operator(): coordinates out of range.");
+            if(dx % 2)
+                mul = -mul;
+        }
+        if(y < 0.0)
+        {
+            y = -y;
+            vigra_precondition(y <= h_ - 1.0,
+                    "SplineImageView::operator(): coordinates out of range.");
+            if(dy % 2)
+                mul = -mul;
+        }
+        else if(y > h_ - 1.0)
+        {
+            y = 2.0*h_-2.0-y;
+            vigra_precondition(y >= 0.0,
+                    "SplineImageView::operator(): coordinates out of range.");
+            if(dy % 2)
+                mul = -mul;
+        }
+        return mul*unchecked(x, y, dx, dy);
+    }
+
+    value_type dx(double x, double y) const
+        { return operator()(x, y, 1, 0); }
+
+    value_type dy(double x, double y) const
+        { return operator()(x, y, 0, 1); }
+
+    value_type dxx(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxy(double x, double y) const
+        { return operator()(x, y, 1, 1); }
+
+    value_type dyy(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dx3(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dy3(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxxy(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxyy(double x, double y) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type operator()(difference_type const & d) const
+        { return operator()(d[0], d[1]); }
+
+    value_type operator()(difference_type const & d, unsigned int dx, unsigned int dy) const
+        { return operator()(d[0], d[1], dx, dy); }
+
+    value_type dx(difference_type const & d) const
+        { return operator()(d[0], d[1], 1, 0); }
+
+    value_type dy(difference_type const & d) const
+        { return operator()(d[0], d[1], 0, 1); }
+
+    value_type dxx(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxy(difference_type const & d) const
+        { return operator()(d[0], d[1], 1, 1); }
+
+    value_type dyy(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dx3(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dy3(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxxy(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    value_type dxyy(difference_type const & d) const
+        { return NumericTraits<VALUETYPE>::zero(); }
+
+    SquaredNormType g2(double x, double y) const
+        { return squaredNorm(dx(x,y)) + squaredNorm(dy(x,y)); }
+
+    SquaredNormType g2x(double x, double y) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2y(double x, double y) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2xx(double x, double y) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2xy(double x, double y) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2yy(double x, double y) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2(difference_type const & d) const
+        { return g2(d[0], d[1]); }
+
+    SquaredNormType g2x(difference_type const & d) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2y(difference_type const & d) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2xx(difference_type const & d) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2xy(difference_type const & d) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    SquaredNormType g2yy(difference_type const & d) const
+        { return NumericTraits<SquaredNormType>::zero(); }
+
+    unsigned int width() const
+        { return w_; }
+
+    unsigned int height() const
+        { return h_; }
+
+    size_type size() const
+        { return size_type(w_, h_); }
+
+    TinyVector<unsigned int, 2> shape() const
+        { return TinyVector<unsigned int, 2>(w_, h_); }
+
+    template <class Array>
+    void coefficientArray(double x, double y, Array & res) const;
+
+    void calculateIndices(double x, double y, int & ix, int & iy, int & ix1, int & iy1) const;
+
+    bool isInsideX(double x) const
+    {
+        return x >= 0.0 && x <= width() - 1.0;
+    }
+
+    bool isInsideY(double y) const
+    {
+        return y >= 0.0 && y <= height() - 1.0;
+    }
+
+    bool isInside(double x, double y) const
+    {
+        return isInsideX(x) && isInsideY(y);
+    }
+
+    bool isValid(double x, double y) const
+    {
+        return x < 2.0*w_-2.0 && x > 1.0-w_ && y < 2.0*h_-2.0 && y > 1.0-h_;
+    }
+
+    bool sameFacet(double x0, double y0, double x1, double y1) const
+    {
+         x0 = VIGRA_CSTD::floor(x0);
+         y0 = VIGRA_CSTD::floor(y0);
+         x1 = VIGRA_CSTD::floor(x1);
+         y1 = VIGRA_CSTD::floor(y1);
+         return x0 == x1 && y0 == y1;
+    }
+
+  protected:
+    unsigned int w_, h_;
+    INTERNAL_INDEXER internalIndexer_;
+};
+
+template <class VALUETYPE, class INTERNAL_INDEXER>
+template <class Array>
+void SplineImageView1Base<VALUETYPE, INTERNAL_INDEXER>::coefficientArray(double x, double y, Array & res) const
+{
+    int ix, iy, ix1, iy1;
+    calculateIndices(x, y, ix, iy, ix1, iy1);
+    res(0,0) = internalIndexer_(ix,iy);
+    res(1,0) = internalIndexer_(ix1,iy) - internalIndexer_(ix,iy);
+    res(0,1) = internalIndexer_(ix,iy1) - internalIndexer_(ix,iy);
+    res(1,1) = internalIndexer_(ix,iy) - internalIndexer_(ix1,iy) -
+               internalIndexer_(ix,iy1) + internalIndexer_(ix1,iy1);
+}
+
+template <class VALUETYPE, class INTERNAL_INDEXER>
+void SplineImageView1Base<VALUETYPE, INTERNAL_INDEXER>::calculateIndices(double x, double y, int & ix, int & iy, int & ix1, int & iy1) const
+{
+    if(x < 0.0)
+    {
+        x = -x;
+        vigra_precondition(x <= w_ - 1.0,
+                "SplineImageView::calculateIndices(): coordinates out of range.");
+        ix = (int)VIGRA_CSTD::ceil(x);
+        ix1 = ix - 1;
+    }
+    else if(x >= w_ - 1.0)
+    {
+        x = 2.0*w_-2.0-x;
+        vigra_precondition(x > 0.0,
+                "SplineImageView::calculateIndices(): coordinates out of range.");
+        ix = (int)VIGRA_CSTD::ceil(x);
+        ix1 = ix - 1;
+    }
+    else
+    {
+        ix = (int)VIGRA_CSTD::floor(x);
+        ix1 = ix + 1;
+    }
+    if(y < 0.0)
+    {
+        y = -y;
+        vigra_precondition(y <= h_ - 1.0,
+                "SplineImageView::calculateIndices(): coordinates out of range.");
+        iy = (int)VIGRA_CSTD::ceil(y);
+        iy1 = iy - 1;
+    }
+    else if(y >= h_ - 1.0)
+    {
+        y = 2.0*h_-2.0-y;
+        vigra_precondition(y > 0.0,
+                "SplineImageView::calculateIndices(): coordinates out of range.");
+        iy = (int)VIGRA_CSTD::ceil(y);
+        iy1 = iy - 1;
+    }
+    else
+    {
+        iy = (int)VIGRA_CSTD::floor(y);
+        iy1 = iy + 1;
+    }
+}
+
+/** \brief Create an image view for bi-linear interpolation.
+
+    This class behaves like \ref vigra::SplineImageView<1, ...>, but one can pass
+    an additional template argument that determined the internal representation of the image.
+    If this is equal to the argument type passed in the constructor, the image is not copied.
+    By default, this works for \ref vigra::BasicImage, \ref vigra::BasicImageView,
+    \ref vigra::MultiArray<2, ...>, and \ref vigra::MultiArrayView<2, ...>.
+
+    In addition to the function provided by  \ref vigra::SplineImageView, there are functions
+    <tt>unchecked(x,y)</tt> and <tt>unchecked(x,y, xorder, yorder)</tt> which improve speed by
+    not applying bounds checking and reflective border treatment (<tt>isInside(x, y)</tt> must
+    be <tt>true</tt>), but otherwise behave identically to their checked counterparts.
+    In addition, <tt>x</tt> and <tt>y</tt> can have type \ref vigra::FixedPoint instead of
+    <tt>double</tt>.
+*/
+template <class VALUETYPE, class INTERNAL_TRAVERSER = typename BasicImage<VALUETYPE>::const_traverser>
+class SplineImageView1
+: public SplineImageView1Base<VALUETYPE, INTERNAL_TRAVERSER>
+{
+    typedef SplineImageView1Base<VALUETYPE, INTERNAL_TRAVERSER> Base;
+  public:
+    typedef typename Base::value_type value_type;
+    typedef typename Base::SquaredNormType SquaredNormType;
+    typedef typename Base::size_type size_type;
+    typedef typename Base::difference_type difference_type;
+    enum StaticOrder { order = Base::order };
+    typedef BasicImage<VALUETYPE> InternalImage;
+
+  protected:
+    typedef typename IteratorTraits<INTERNAL_TRAVERSER>::mutable_iterator InternalTraverser;
+    typedef typename IteratorTraits<InternalTraverser>::DefaultAccessor InternalAccessor;
+    typedef typename IteratorTraits<INTERNAL_TRAVERSER>::const_iterator InternalConstTraverser;
+    typedef typename IteratorTraits<InternalConstTraverser>::DefaultAccessor InternalConstAccessor;
+
+  public:
+
+        /* when traverser and accessor types passed to the constructor are the same as the corresponding
+           internal types, we need not copy the image (speed up)
+        */
+    SplineImageView1(InternalTraverser is, InternalTraverser iend, InternalAccessor sa)
+    : Base(iend.x - is.x, iend.y - is.y, is)
+    {}
+
+    SplineImageView1(triple<InternalTraverser, InternalTraverser, InternalAccessor> s)
+    : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
+    {}
+
+    SplineImageView1(InternalConstTraverser is, InternalConstTraverser iend, InternalConstAccessor sa)
+    : Base(iend.x - is.x, iend.y - is.y, is)
+    {}
+
+    SplineImageView1(triple<InternalConstTraverser, InternalConstTraverser, InternalConstAccessor> s)
+    : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
+    {}
+
+    template<class T, class SU>
+    SplineImageView1(MultiArrayView<2, T, SU> const & i)
+    : Base(i.shape(0), i.shape(1)),
+      image_(i.shape(0), i.shape(1))
+    {
+        for(unsigned int y=0; y<this->height(); ++y)
+            for(unsigned int x=0; x<this->width(); ++x)
+                image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast(i(x,y));
+        this->internalIndexer_ = image_.upperLeft();
+    }
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView1(SrcIterator is, SrcIterator iend, SrcAccessor sa)
+    : Base(iend.x - is.x, iend.y - is.y),
+      image_(iend - is)
+    {
+        copyImage(srcIterRange(is, iend, sa), destImage(image_));
+        this->internalIndexer_ = image_.upperLeft();
+    }
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView1(triple<SrcIterator, SrcIterator, SrcAccessor> s)
+    : Base(s.second.x - s.first.x, s.second.y - s.first.y),
+      image_(s.second - s.first)
+    {
+        copyImage(s, destImage(image_));
+        this->internalIndexer_ = image_.upperLeft();
+    }
+
+    InternalImage const & image() const
+        { return image_; }
+
+  protected:
+    InternalImage image_;
+};
+
+template <class VALUETYPE, class StridedOrUnstrided>
+class SplineImageView1<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> >
+: public SplineImageView1Base<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> >
+{
+    typedef SplineImageView1Base<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> > Base;
+  public:
+    typedef typename Base::value_type value_type;
+    typedef typename Base::SquaredNormType SquaredNormType;
+    typedef typename Base::size_type size_type;
+    typedef typename Base::difference_type difference_type;
+    enum StaticOrder { order = Base::order };
+    typedef BasicImage<VALUETYPE> InternalImage;
+
+  protected:
+    typedef MultiArrayView<2, VALUETYPE, StridedOrUnstrided> InternalIndexer;
+
+  public:
+
+        /* when traverser and accessor types passed to the constructor are the same as the corresponding
+           internal types, we need not copy the image (speed up)
+        */
+    SplineImageView1(InternalIndexer const & i)
+    : Base(i.shape(0), i.shape(1), i)
+    {}
+
+    template<class T, class SU>
+    SplineImageView1(MultiArrayView<2, T, SU> const & i)
+    : Base(i.shape(0), i.shape(1)),
+      image_(i.shape(0), i.shape(1))
+    {
+        copyImage(srcImageRange(i), destImage(image_));
+        // for(unsigned int y=0; y<this->height(); ++y)
+            // for(unsigned int x=0; x<this->width(); ++x)
+                // image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast(i(x,y));
+        this->internalIndexer_ = InternalIndexer(typename InternalIndexer::difference_type(this->width(), this->height()),
+                                                 image_.data());
+    }
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView1(SrcIterator is, SrcIterator iend, SrcAccessor sa)
+    : Base(iend.x - is.x, iend.y - is.y),
+      image_(iend-is)
+    {
+        copyImage(srcIterRange(is, iend, sa), destImage(image_));
+        this->internalIndexer_ = InternalIndexer(typename InternalIndexer::difference_type(this->width(), this->height()),
+                                                 image_.data());
+    }
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView1(triple<SrcIterator, SrcIterator, SrcAccessor> s)
+    : Base(s.second.x - s.first.x, s.second.y - s.first.y),
+      image_(s.second - s.first)
+    {
+        copyImage(s, destImage(image_));
+        this->internalIndexer_ = InternalIndexer(typename InternalIndexer::difference_type(this->width(), this->height()),
+                                                 image_.data());
+    }
+
+    InternalImage const & image() const
+        { return image_; }
+
+  protected:
+    InternalImage image_;
+};
+
+template <class VALUETYPE>
+class SplineImageView<1, VALUETYPE>
+: public SplineImageView1<VALUETYPE>
+{
+    typedef SplineImageView1<VALUETYPE> Base;
+  public:
+    typedef typename Base::value_type value_type;
+    typedef typename Base::SquaredNormType SquaredNormType;
+    typedef typename Base::size_type size_type;
+    typedef typename Base::difference_type difference_type;
+    enum StaticOrder { order = Base::order };
+    typedef typename Base::InternalImage InternalImage;
+
+  protected:
+    typedef typename Base::InternalTraverser InternalTraverser;
+    typedef typename Base::InternalAccessor InternalAccessor;
+    typedef typename Base::InternalConstTraverser InternalConstTraverser;
+    typedef typename Base::InternalConstAccessor InternalConstAccessor;
+
+public:
+
+        /* when traverser and accessor types passed to the constructor are the same as the corresponding
+           internal types, we need not copy the image (speed up)
+        */
+    SplineImageView(InternalTraverser is, InternalTraverser iend, InternalAccessor sa, bool /* unused */ = false)
+    : Base(is, iend, sa)
+    {}
+
+    SplineImageView(triple<InternalTraverser, InternalTraverser, InternalAccessor> s, bool /* unused */ = false)
+    : Base(s)
+    {}
+
+    SplineImageView(InternalConstTraverser is, InternalConstTraverser iend, InternalConstAccessor sa, bool /* unused */ = false)
+    : Base(is, iend, sa)
+    {}
+
+    SplineImageView(triple<InternalConstTraverser, InternalConstTraverser, InternalConstAccessor> s, bool /* unused */ = false)
+    : Base(s)
+    {}
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa, bool /* unused */ = false)
+    : Base(is, iend, sa)
+    {
+        copyImage(srcIterRange(is, iend, sa), destImage(this->image_));
+    }
+
+    template <class SrcIterator, class SrcAccessor>
+    SplineImageView(triple<SrcIterator, SrcIterator, SrcAccessor> s, bool /* unused */ = false)
+    : Base(s)
+    {
+        copyImage(s, destImage(this->image_));
+    }
+    
+    template<class T, class SU>
+    SplineImageView(MultiArrayView<2, T, SU> const & i, bool /* unused */ = false)
+    : Base(i)
+    {}
+};
+
+} // namespace vigra
+
+
+#endif /* VIGRA_SPLINEIMAGEVIEW_HXX */
diff --git a/include/vigra/splines.hxx b/include/vigra/splines.hxx
new file mode 100644
index 0000000..4e79ade
--- /dev/null
+++ b/include/vigra/splines.hxx
@@ -0,0 +1,1385 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_SPLINES_HXX
+#define VIGRA_SPLINES_HXX
+
+#include <cmath>
+#include "config.hxx"
+#include "mathutil.hxx"
+#include "polynomial.hxx"
+#include "array_vector.hxx"
+#include "fixedpoint.hxx"
+
+namespace vigra {
+
+namespace autodiff {
+
+template <class T, int N>
+class DualVector;
+
+} // namespace autodiff
+
+/** \addtogroup MathFunctions Mathematical Functions
+*/
+//@{
+/* B-Splines of arbitrary order and interpolating Catmull/Rom splines.
+
+    <b>\#include</b> \<vigra/splines.hxx\><br>
+    Namespace: vigra
+*/
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+/** Basic interface of the spline functors.
+
+    Implements the spline functions defined by the recursion
+
+    \f[ B_0(x) = \left\{ \begin{array}{ll}
+                                  1 & -\frac{1}{2} \leq x < \frac{1}{2} \\
+                                  0 & \mbox{otherwise}
+                        \end{array}\right.
+    \f]
+
+    and
+
+    \f[ B_n(x) = B_0(x) * B_{n-1}(x)
+    \f]
+
+    where * denotes convolution, and <i>n</i> is the spline order given by the
+    template parameter <tt>ORDER</tt>. These spline classes can be used as
+    unary and binary functors, as kernels for \ref resamplingConvolveImage(),
+    and as arguments for \ref vigra::SplineImageView. Note that the spline order
+    is given as a template argument.
+
+    <b>\#include</b> \<vigra/splines.hxx\><br>
+    Namespace: vigra
+*/
+template <int ORDER, class T = double>
+class BSplineBase
+{
+  public:
+
+        /** the value type if used as a kernel in \ref resamplingConvolveImage().
+        */
+    typedef T            value_type;
+        /** the functor's unary argument type
+        */
+    typedef T            argument_type;
+        /** the functor's first binary argument type
+        */
+    typedef T            first_argument_type;
+        /** the functor's second binary argument type
+        */
+    typedef unsigned int second_argument_type;
+        /** the functor's result type (unary and binary)
+        */
+    typedef T            result_type;
+        /** the spline order
+        */
+    enum StaticOrder { order = ORDER };
+
+        /** Create functor for given derivative of the spline. The spline's order
+            is specified spline by the template argument <TT>ORDER</tt>.
+        */
+    explicit BSplineBase(unsigned int derivativeOrder = 0)
+    : s1_(derivativeOrder)
+    {}
+
+        /** Unary function call.
+            Returns the value of the spline with the derivative order given in the
+            constructor. Note that only derivatives up to <tt>ORDER-1</tt> are
+            continuous, and derivatives above <tt>ORDER+1</tt> are zero.
+        */
+    result_type operator()(argument_type x) const
+    {
+        return exec(x, derivativeOrder());
+    }
+
+        /** Binary function call.
+            The given derivative order is added to the derivative order
+            specified in the constructor. Note that only derivatives up to <tt>ORDER-1</tt> are
+            continuous, and derivatives above <tt>ORDER+1</tt> are zero.
+        */
+    result_type operator()(first_argument_type x, second_argument_type derivative_order) const
+    {
+         return exec(x, derivativeOrder() + derivative_order);
+    }
+
+        /** Index operator. Same as unary function call.
+        */
+    value_type operator[](value_type x) const
+        { return operator()(x); }
+
+        /** Get the required filter radius for a discrete approximation of the
+            spline. Always equal to <tt>(ORDER + 1) / 2.0</tt>.
+        */
+    double radius() const
+        { return (ORDER + 1) * 0.5; }
+
+        /** Get the derivative order of the Gaussian.
+        */
+    unsigned int derivativeOrder() const
+        { return s1_.derivativeOrder(); }
+
+        /** Get the prefilter coefficients required for interpolation.
+            To interpolate with a B-spline, \ref resamplingConvolveImage()
+            can be used. However, the image to be interpolated must be
+            pre-filtered using \ref recursiveFilterX() and \ref recursiveFilterY()
+            with the filter coefficients given by this function. The length of the array
+            corresponds to how many times the above recursive filtering
+            has to be applied (zero length means no prefiltering necessary).
+        */
+    ArrayVector<double> const & prefilterCoefficients() const
+    {
+        return prefilterCoefficients_;
+    }
+
+    typedef ArrayVector<ArrayVector<T> > WeightMatrix;
+
+        /** Get the coefficients to transform spline coefficients into
+            the coefficients of the corresponding polynomial.
+            Currently internally used in SplineImageView; needs more
+            documentation ???
+        */
+    static WeightMatrix const & weights()
+    {
+        return weightMatrix_;
+    }
+
+  protected:
+    result_type exec(first_argument_type x, second_argument_type derivative_order) const;
+    
+        // factory function for the prefilter coefficients array
+    static ArrayVector<double> calculatePrefilterCoefficients();
+
+        // factory function for the weight matrix
+    static WeightMatrix calculateWeightMatrix();
+
+    BSplineBase<ORDER-1, T> s1_;
+    static ArrayVector<double> prefilterCoefficients_;
+    static WeightMatrix weightMatrix_;
+};
+
+template <int ORDER, class T>
+ArrayVector<double> BSplineBase<ORDER, T>::prefilterCoefficients_(BSplineBase<ORDER, T>::calculatePrefilterCoefficients());
+
+template <int ORDER, class T>
+typename BSplineBase<ORDER, T>::WeightMatrix BSplineBase<ORDER, T>::weightMatrix_(calculateWeightMatrix());
+
+template <int ORDER, class T>
+typename BSplineBase<ORDER, T>::result_type
+BSplineBase<ORDER, T>::exec(first_argument_type x, second_argument_type derivative_order) const
+{
+    if(derivative_order == 0)
+    {
+        T n12 = (ORDER + 1.0) / 2.0;
+        return ((n12 + x) * s1_(x + 0.5) + (n12 - x) * s1_(x - 0.5)) / ORDER;
+    }
+    else
+    {
+        --derivative_order;
+        return s1_(x + 0.5, derivative_order) - s1_(x - 0.5, derivative_order);
+    }
+}
+
+template <int ORDER, class T>
+ArrayVector<double> 
+BSplineBase<ORDER, T>::calculatePrefilterCoefficients()
+{
+    ArrayVector<double> res;
+    if(ORDER > 1)
+    {
+        const int r = ORDER / 2;
+        StaticPolynomial<2*r, double> p(2*r);
+        BSplineBase spline;
+        for(int i = 0; i <= 2*r; ++i)
+            p[i] = spline(T(i-r));
+        ArrayVector<double> roots;
+        polynomialRealRoots(p, roots);
+        for(unsigned int i = 0; i < roots.size(); ++i)
+            if(VIGRA_CSTD::fabs(roots[i]) < 1.0)
+                res.push_back(roots[i]);
+    }
+    return res;
+}
+
+template <int ORDER, class T>
+typename BSplineBase<ORDER, T>::WeightMatrix
+BSplineBase<ORDER, T>::calculateWeightMatrix()
+{
+    WeightMatrix res(ORDER+1, ArrayVector<T>(ORDER+1));
+    double faculty = 1.0;
+    for(int d = 0; d <= ORDER; ++d)
+    {
+        if(d > 1)
+            faculty *= d;
+        double x = ORDER / 2; // (note: integer division)
+        BSplineBase spline;
+        for(int i = 0; i <= ORDER; ++i, --x)
+            res[d][i] = spline(x, d) / faculty;
+    }
+    return res;
+}
+
+/********************************************************/
+/*                                                      */
+/*                     BSpline<N, T>                    */
+/*                                                      */
+/********************************************************/
+
+/** Spline functors for arbitrary orders.
+
+    Provides the interface of \ref vigra::BSplineBase with a more convenient
+    name -- see there for more documentation.
+*/
+template <int ORDER, class T = double>
+class BSpline
+: public BSplineBase<ORDER, T>
+{
+  public:
+        /** Constructor forwarded to the base class constructor..
+        */
+    explicit BSpline(unsigned int derivativeOrder = 0)
+    : BSplineBase<ORDER, T>(derivativeOrder)
+    {}
+};
+
+/********************************************************/
+/*                                                      */
+/*                     BSpline<0, T>                    */
+/*                                                      */
+/********************************************************/
+
+template <class T>
+class BSplineBase<0, T>
+{
+  public:
+
+    typedef T            value_type;
+    typedef T            argument_type;
+    typedef T            first_argument_type;
+    typedef unsigned int second_argument_type;
+    typedef T            result_type;
+    enum StaticOrder { order = 0 };
+
+    explicit BSplineBase(unsigned int derivativeOrder = 0)
+    : derivativeOrder_(derivativeOrder)
+    {}
+
+    result_type operator()(argument_type x) const
+    {
+         return exec(x, derivativeOrder_);
+    }
+
+    template <unsigned int IntBits, unsigned int FracBits>
+    FixedPoint<IntBits, FracBits> operator()(FixedPoint<IntBits, FracBits> x) const
+    {
+        typedef FixedPoint<IntBits, FracBits> Value;
+        return x.value < Value::ONE_HALF && -Value::ONE_HALF <= x.value
+                   ? Value(Value::ONE, FPNoShift)
+                   : Value(0, FPNoShift);
+    }
+
+    template <class U, int N>
+    autodiff::DualVector<U, N> operator()(autodiff::DualVector<U, N> const & x) const
+    {
+        return x < 0.5 && -0.5 <= x 
+                   ? autodiff::DualVector<U, N>(1.0)
+                   : autodiff::DualVector<U, N>(0.0);
+    }
+
+    result_type operator()(first_argument_type x, second_argument_type derivative_order) const
+    {
+         return exec(x, derivativeOrder_ + derivative_order);
+    }
+
+    value_type operator[](value_type x) const
+        { return operator()(x); }
+
+    double radius() const
+        { return 0.5; }
+
+    unsigned int derivativeOrder() const
+        { return derivativeOrder_; }
+
+    ArrayVector<double> const & prefilterCoefficients() const
+    {
+        return prefilterCoefficients_;
+    }
+
+    typedef T WeightMatrix[1][1];
+  
+    static WeightMatrix const & weights()
+    {
+        return weightMatrix_;
+    }
+
+  protected:
+    result_type exec(first_argument_type x, second_argument_type derivative_order) const
+    {
+        if(derivative_order == 0)
+            return x < 0.5 && -0.5 <= x ?
+                     1.0
+                   : 0.0;
+        else
+            return 0.0;
+    }
+
+    unsigned int derivativeOrder_;
+    static ArrayVector<double> prefilterCoefficients_;
+    static WeightMatrix weightMatrix_;
+};
+
+template <class T>
+ArrayVector<double> BSplineBase<0, T>::prefilterCoefficients_;
+
+template <class T>
+typename BSplineBase<0, T>::WeightMatrix BSplineBase<0, T>::weightMatrix_ = {{ 1.0 }};
+
+/********************************************************/
+/*                                                      */
+/*                     BSpline<1, T>                    */
+/*                                                      */
+/********************************************************/
+
+template <class T>
+class BSpline<1, T>
+{
+  public:
+
+    typedef T            value_type;
+    typedef T            argument_type;
+    typedef T            first_argument_type;
+    typedef unsigned int second_argument_type;
+    typedef T            result_type;
+    enum  StaticOrder { order = 1 };
+
+    explicit BSpline(unsigned int derivativeOrder = 0)
+    : derivativeOrder_(derivativeOrder)
+    {}
+
+    result_type operator()(argument_type x) const
+    {
+        return exec(x, derivativeOrder_);
+    }
+
+    template <unsigned int IntBits, unsigned int FracBits>
+    FixedPoint<IntBits, FracBits> operator()(FixedPoint<IntBits, FracBits> x) const
+    {
+        typedef FixedPoint<IntBits, FracBits> Value;
+        int v = abs(x.value);
+        return v < Value::ONE ?
+                Value(Value::ONE - v, FPNoShift)
+                : Value(0, FPNoShift);
+    }
+
+    template <class U, int N>
+    autodiff::DualVector<U, N> operator()(autodiff::DualVector<U, N> x) const
+    {
+        x = abs(x);
+        return x < 1.0 
+                    ? 1.0 - x
+                    : autodiff::DualVector<U, N>(0.0);
+    }
+
+    result_type operator()(first_argument_type x, second_argument_type derivative_order) const
+    {
+         return exec(x, derivativeOrder_ + derivative_order);
+    }
+
+    value_type operator[](value_type x) const
+        { return operator()(x); }
+
+    double radius() const
+        { return 1.0; }
+
+    unsigned int derivativeOrder() const
+        { return derivativeOrder_; }
+
+    ArrayVector<double> const & prefilterCoefficients() const
+    {
+        return prefilterCoefficients_;
+    }
+
+    typedef T WeightMatrix[2][2];
+
+    static WeightMatrix const & weights()
+    {
+        return weightMatrix_;
+    }
+
+  protected:
+    T exec(T x, unsigned int derivative_order) const;
+
+    unsigned int derivativeOrder_;
+    static ArrayVector<double> prefilterCoefficients_;
+    static WeightMatrix weightMatrix_;
+};
+
+template <class T>
+ArrayVector<double> BSpline<1, T>::prefilterCoefficients_;
+
+template <class T>
+typename BSpline<1, T>::WeightMatrix BSpline<1, T>::weightMatrix_ = {{ 1.0, 0.0}, {-1.0, 1.0}};
+
+template <class T>
+T BSpline<1, T>::exec(T x, unsigned int derivative_order) const
+{
+    switch(derivative_order)
+    {
+        case 0:
+        {
+            x = VIGRA_CSTD::fabs(x);
+            return x < 1.0 ?
+                    1.0 - x
+                    : 0.0;
+        }
+        case 1:
+        {
+            return x < 0.0 ?
+                     -1.0 <= x ?
+                          1.0
+                     : 0.0
+                   : x < 1.0 ?
+                       -1.0
+                     : 0.0;
+        }
+        default:
+            return 0.0;
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*                     BSpline<2, T>                    */
+/*                                                      */
+/********************************************************/
+
+template <class T>
+class BSpline<2, T>
+{
+  public:
+
+    typedef T            value_type;
+    typedef T            argument_type;
+    typedef T            first_argument_type;
+    typedef unsigned int second_argument_type;
+    typedef T            result_type;
+    enum StaticOrder { order = 2 };
+
+    explicit BSpline(unsigned int derivativeOrder = 0)
+    : derivativeOrder_(derivativeOrder)
+    {}
+
+    result_type operator()(argument_type x) const
+    {
+        return exec(x, derivativeOrder_);
+    }
+
+    template <unsigned int IntBits, unsigned int FracBits>
+    FixedPoint<IntBits, FracBits> operator()(FixedPoint<IntBits, FracBits> x) const
+    {
+        typedef FixedPoint<IntBits, FracBits> Value;
+        enum { ONE_HALF = Value::ONE_HALF, THREE_HALVES = ONE_HALF * 3, THREE_QUARTERS = THREE_HALVES / 2,
+               PREMULTIPLY_SHIFT1 = FracBits <= 16 ? 0 : FracBits - 16,
+               PREMULTIPLY_SHIFT2 = FracBits - 1 <= 16 ? 0 : FracBits - 17,
+               POSTMULTIPLY_SHIFT1 = FracBits - 2*PREMULTIPLY_SHIFT1,
+               POSTMULTIPLY_SHIFT2 = FracBits - 2*PREMULTIPLY_SHIFT2  };
+        int v = abs(x.value);
+        return v == ONE_HALF
+                   ? Value(ONE_HALF, FPNoShift)
+                   : v <= ONE_HALF
+                       ? Value(THREE_QUARTERS -
+                               (int)(sq((unsigned)v >> PREMULTIPLY_SHIFT2) >> POSTMULTIPLY_SHIFT2), FPNoShift)
+                       : v < THREE_HALVES
+                            ? Value((int)(sq((unsigned)(THREE_HALVES-v) >> PREMULTIPLY_SHIFT1) >> (POSTMULTIPLY_SHIFT1 + 1)), FPNoShift)
+                            : Value(0, FPNoShift);
+    }
+
+    template <class U, int N>
+    autodiff::DualVector<U, N> operator()(autodiff::DualVector<U, N> x) const
+    {
+        x = abs(x);
+        return x < 0.5 
+                   ? 0.75 - x*x
+                   : x < 1.5 
+                        ? 0.5 * sq(1.5 - x)
+                        : autodiff::DualVector<U, N>(0.0);
+    }
+
+    result_type operator()(first_argument_type x, second_argument_type derivative_order) const
+    {
+         return exec(x, derivativeOrder_ + derivative_order);
+    }
+
+    result_type dx(argument_type x) const
+        { return operator()(x, 1); }
+
+    value_type operator[](value_type x) const
+        { return operator()(x); }
+
+    double radius() const
+        { return 1.5; }
+
+    unsigned int derivativeOrder() const
+        { return derivativeOrder_; }
+
+    ArrayVector<double> const & prefilterCoefficients() const
+    {
+        return prefilterCoefficients_;
+    }
+
+    typedef T WeightMatrix[3][3];
+
+    static WeightMatrix const & weights()
+    {
+        return weightMatrix_;
+    }
+
+  protected:
+    result_type exec(first_argument_type x, second_argument_type derivative_order) const;
+
+    unsigned int derivativeOrder_;
+    static ArrayVector<double> prefilterCoefficients_;
+    static WeightMatrix weightMatrix_;
+};
+
+template <class T>
+ArrayVector<double> BSpline<2, T>::prefilterCoefficients_(1, 2.0*M_SQRT2 - 3.0);
+
+template <class T>
+typename BSpline<2, T>::WeightMatrix BSpline<2, T>::weightMatrix_ = 
+                           {{ 0.125, 0.75, 0.125},
+                            {-0.5, 0.0, 0.5},
+                            { 0.5, -1.0, 0.5}};
+
+template <class T>
+typename BSpline<2, T>::result_type
+BSpline<2, T>::exec(first_argument_type x, second_argument_type derivative_order) const
+{
+    switch(derivative_order)
+    {
+        case 0:
+        {
+            x = VIGRA_CSTD::fabs(x);
+            return x < 0.5 ?
+                    0.75 - x*x
+                    : x < 1.5 ?
+                        0.5 * sq(1.5 - x)
+                    : 0.0;
+        }
+        case 1:
+        {
+            return x >= -0.5 ?
+                     x <= 0.5 ?
+                       -2.0 * x
+                     : x < 1.5 ?
+                         x - 1.5
+                       : 0.0
+                   : x > -1.5 ?
+                       x + 1.5
+                     : 0.0;
+        }
+        case 2:
+        {
+            return x >= -0.5 ?
+                     x < 0.5 ?
+                         -2.0
+                     : x < 1.5 ?
+                         1.0
+                       : 0.0
+                   : x >= -1.5 ?
+                       1.0
+                     : 0.0;
+        }
+        default:
+            return 0.0;
+    }
+}
+
+/********************************************************/
+/*                                                      */
+/*                     BSpline<3, T>                    */
+/*                                                      */
+/********************************************************/
+
+template <class T>
+class BSpline<3, T>
+{
+  public:
+
+    typedef T            value_type;
+    typedef T            argument_type;
+    typedef T            first_argument_type;
+    typedef unsigned int second_argument_type;
+    typedef T            result_type;
+    enum StaticOrder { order = 3 };
+
+    explicit BSpline(unsigned int derivativeOrder = 0)
+    : derivativeOrder_(derivativeOrder)
+    {}
+
+    result_type operator()(argument_type x) const
+    {
+        return exec(x, derivativeOrder_);
+    }
+
+    template <unsigned int IntBits, unsigned int FracBits>
+    FixedPoint<IntBits, FracBits> operator()(FixedPoint<IntBits, FracBits> x) const
+    {
+        typedef FixedPoint<IntBits, FracBits> Value;
+        enum { ONE = Value::ONE, TWO = 2 * ONE, TWO_THIRDS = TWO / 3, ONE_SIXTH = ONE / 6,
+               PREMULTIPLY_SHIFT = FracBits <= 16 ? 0 : FracBits - 16,
+               POSTMULTIPLY_SHIFT = FracBits - 2*PREMULTIPLY_SHIFT };
+        int v = abs(x.value);
+        return v == ONE
+                   ? Value(ONE_SIXTH, FPNoShift)
+                   : v < ONE
+                       ? Value(TWO_THIRDS +
+                               (((int)(sq((unsigned)v >> PREMULTIPLY_SHIFT) >> (POSTMULTIPLY_SHIFT + PREMULTIPLY_SHIFT))
+                                       * (((v >> 1) - ONE) >> PREMULTIPLY_SHIFT)) >> POSTMULTIPLY_SHIFT), FPNoShift)
+                       : v < TWO
+                            ? Value((int)((sq((unsigned)(TWO-v) >> PREMULTIPLY_SHIFT) >> (POSTMULTIPLY_SHIFT + PREMULTIPLY_SHIFT))
+                                      * ((unsigned)(TWO-v) >> PREMULTIPLY_SHIFT) / 6) >> POSTMULTIPLY_SHIFT, FPNoShift)
+                            : Value(0, FPNoShift);
+    }
+
+    template <class U, int N>
+    autodiff::DualVector<U, N> operator()(autodiff::DualVector<U, N> x) const
+    {
+        x = abs(x);
+        if(x < 1.0)
+        {
+            return 2.0/3.0 + x*x*(-1.0 + 0.5*x);
+        }
+        else if(x < 2.0)
+        {
+            x = 2.0 - x;
+            return x*x*x/6.0;
+        }
+        else
+            return autodiff::DualVector<U, N>(0.0);
+    }
+
+    result_type operator()(first_argument_type x, second_argument_type derivative_order) const
+    {
+         return exec(x, derivativeOrder_ + derivative_order);
+    }
+
+    result_type dx(argument_type x) const
+        { return operator()(x, 1); }
+
+    result_type dxx(argument_type x) const
+        { return operator()(x, 2); }
+
+    value_type operator[](value_type x) const
+        { return operator()(x); }
+
+    double radius() const
+        { return 2.0; }
+
+    unsigned int derivativeOrder() const
+        { return derivativeOrder_; }
+
+    ArrayVector<double> const & prefilterCoefficients() const
+    {
+        return prefilterCoefficients_;
+    }
+
+    typedef T WeightMatrix[4][4];
+
+    static WeightMatrix const & weights()
+    {
+        return weightMatrix_;
+    }
+
+  protected:
+    result_type exec(first_argument_type x, second_argument_type derivative_order) const;
+
+    unsigned int derivativeOrder_;
+    static ArrayVector<double> prefilterCoefficients_;
+    static WeightMatrix weightMatrix_;
+};
+
+template <class T>
+ArrayVector<double> BSpline<3, T>::prefilterCoefficients_(1, VIGRA_CSTD::sqrt(3.0) - 2.0);
+
+template <class T>
+typename BSpline<3, T>::WeightMatrix BSpline<3, T>::weightMatrix_ = 
+                           {{ 1.0 / 6.0, 2.0 / 3.0, 1.0 / 6.0, 0.0},
+                            {-0.5, 0.0, 0.5, 0.0},
+                            { 0.5, -1.0, 0.5, 0.0},
+                            {-1.0 / 6.0, 0.5, -0.5, 1.0 / 6.0}};
+
+template <class T>
+typename BSpline<3, T>::result_type
+BSpline<3, T>::exec(first_argument_type x, second_argument_type derivative_order) const
+{
+    switch(derivative_order)
+    {
+        case 0:
+        {
+            x = VIGRA_CSTD::fabs(x);
+            if(x < 1.0)
+            {
+                return 2.0/3.0 + x*x*(-1.0 + 0.5*x);
+            }
+            else if(x < 2.0)
+            {
+                x = 2.0 - x;
+                return x*x*x/6.0;
+            }
+            else
+                return 0.0;
+        }
+        case 1:
+        {
+            double s = x < 0.0 ?
+                         -1.0
+                       :  1.0;
+            x = VIGRA_CSTD::fabs(x);
+            return x < 1.0 ?
+                     s*x*(-2.0 + 1.5*x)
+                   : x < 2.0 ?
+                       -0.5*s*sq(2.0 - x)
+                     : 0.0;
+        }
+        case 2:
+        {
+            x = VIGRA_CSTD::fabs(x);
+            return x < 1.0 ?
+                     3.0*x - 2.0
+                   : x < 2.0 ?
+                       2.0 - x
+                     : 0.0;
+        }
+        case 3:
+        {
+            return x < 0.0 ?
+                     x < -1.0 ?
+                       x < -2.0 ?
+                         0.0
+                       : 1.0
+                     : -3.0
+                   : x < 1.0 ?
+                       3.0
+                     : x < 2.0 ?
+                         -1.0
+                       : 0.0;
+        }
+        default:
+            return 0.0;
+    }
+}
+
+typedef BSpline<3, double> CubicBSplineKernel;
+
+/********************************************************/
+/*                                                      */
+/*                     BSpline<4, T>                    */
+/*                                                      */
+/********************************************************/
+
+template <class T>
+class BSpline<4, T>
+{
+  public:
+
+    typedef T            value_type;
+    typedef T            argument_type;
+    typedef T            first_argument_type;
+    typedef unsigned int second_argument_type;
+    typedef T            result_type;
+    enum StaticOrder { order = 4 };
+
+    explicit BSpline(unsigned int derivativeOrder = 0)
+    : derivativeOrder_(derivativeOrder)
+    {}
+
+    result_type operator()(argument_type x) const
+    {
+        return exec(x, derivativeOrder_);
+    }
+
+    result_type operator()(first_argument_type x, second_argument_type derivative_order) const
+    {
+         return exec(x, derivativeOrder_ + derivative_order);
+    }
+
+    template <class U, int N>
+    autodiff::DualVector<U, N> operator()(autodiff::DualVector<U, N> x) const
+    {
+        x = abs(x);
+        if(x <= 0.5)
+        {
+            return 115.0/192.0 + x*x*(-0.625 + x*x*0.25);
+        }
+        else if(x < 1.5)
+        {
+            return (55.0/16.0 + x*(1.25 + x*(-7.5 + x*(5.0 - x)))) / 6.0;
+        }
+        else if(x < 2.5)
+        {
+            x = 2.5 - x;
+            return sq(x*x) / 24.0;
+        }
+        else
+            return autodiff::DualVector<U, N>(0.0);
+    }
+
+    result_type dx(argument_type x) const
+        { return operator()(x, 1); }
+
+    result_type dxx(argument_type x) const
+        { return operator()(x, 2); }
+
+    result_type dx3(argument_type x) const
+        { return operator()(x, 3); }
+
+    value_type operator[](value_type x) const
+        { return operator()(x); }
+
+    double radius() const
+        { return 2.5; }
+
+    unsigned int derivativeOrder() const
+        { return derivativeOrder_; }
+
+    ArrayVector<double> const & prefilterCoefficients() const
+    {
+        return prefilterCoefficients_;
+    }
+
+    typedef T WeightMatrix[5][5];
+
+    static WeightMatrix const & weights()
+    {
+        return weightMatrix_;
+    }
+
+  protected:
+    result_type exec(first_argument_type x, second_argument_type derivative_order) const;
+
+    static ArrayVector<double> calculatePrefilterCoefficients()
+    {
+        ArrayVector<double> b(2);
+        // -19 + 4*sqrt(19) + 2*sqrt(2*(83 - 19*sqrt(19)))
+        b[0] = -0.361341225900220177092212841325;
+        // -19 - 4*sqrt(19) + 2*sqrt(2*(83 + 19*sqrt(19)))
+        b[1] = -0.013725429297339121360331226939;
+        return b;
+    }
+
+    unsigned int derivativeOrder_;
+    static ArrayVector<double> prefilterCoefficients_;
+    static WeightMatrix weightMatrix_;
+};
+
+template <class T>
+ArrayVector<double> BSpline<4, T>::prefilterCoefficients_(calculatePrefilterCoefficients());
+
+template <class T>
+typename BSpline<4, T>::WeightMatrix BSpline<4, T>::weightMatrix_ = 
+                           {{ 1.0/384.0, 19.0/96.0, 115.0/192.0, 19.0/96.0, 1.0/384.0},
+                            {-1.0/48.0, -11.0/24.0, 0.0, 11.0/24.0, 1.0/48.0},
+                            { 1.0/16.0, 1.0/4.0, -5.0/8.0, 1.0/4.0, 1.0/16.0},
+                            {-1.0/12.0, 1.0/6.0, 0.0, -1.0/6.0, 1.0/12.0},
+                            { 1.0/24.0, -1.0/6.0, 0.25, -1.0/6.0, 1.0/24.0}};
+
+template <class T>
+typename BSpline<4, T>::result_type
+BSpline<4, T>::exec(first_argument_type x, second_argument_type derivative_order) const
+{
+    switch(derivative_order)
+    {
+        case 0:
+        {
+            x = VIGRA_CSTD::fabs(x);
+            if(x <= 0.5)
+            {
+                return 115.0/192.0 + x*x*(-0.625 + x*x*0.25);
+            }
+            else if(x < 1.5)
+            {
+                return (55.0/16.0 + x*(1.25 + x*(-7.5 + x*(5.0 - x)))) / 6.0;
+            }
+            else if(x < 2.5)
+            {
+                x = 2.5 - x;
+                return sq(x*x) / 24.0;
+            }
+            else
+                return 0.0;
+        }
+        case 1:
+        {
+            double s = x < 0.0 ?
+                          -1.0 :
+                           1.0;
+            x = VIGRA_CSTD::fabs(x);
+            if(x <= 0.5)
+            {
+                return s*x*(-1.25 + x*x);
+            }
+            else if(x < 1.5)
+            {
+                return s*(5.0 + x*(-60.0 + x*(60.0 - 16.0*x))) / 24.0;
+            }
+            else if(x < 2.5)
+            {
+                x = 2.5 - x;
+                return s*x*x*x / -6.0;
+            }
+            else
+                return 0.0;
+        }
+        case 2:
+        {
+            x = VIGRA_CSTD::fabs(x);
+            if(x <= 0.5)
+            {
+                return -1.25 + 3.0*x*x;
+            }
+            else if(x < 1.5)
+            {
+                return -2.5 + x*(5.0 - 2.0*x);
+            }
+            else if(x < 2.5)
+            {
+                x = 2.5 - x;
+                return x*x / 2.0;
+            }
+            else
+                return 0.0;
+        }
+        case 3:
+        {
+            double s = x < 0.0 ?
+                          -1.0 :
+                           1.0;
+            x = VIGRA_CSTD::fabs(x);
+            if(x <= 0.5)
+            {
+                return s*x*6.0;
+            }
+            else if(x < 1.5)
+            {
+                return s*(5.0 - 4.0*x);
+            }
+            else if(x < 2.5)
+            {
+                return s*(x - 2.5);
+            }
+            else
+                return 0.0;
+        }
+        case 4:
+        {
+            return x < 0.0
+                     ? x < -2.5
+                         ? 0.0
+                         : x < -1.5
+                             ? 1.0
+                             : x < -0.5
+                                 ? -4.0
+                                 : 6.0
+                     : x < 0.5 
+                         ? 6.0
+                         : x < 1.5
+                             ? -4.0
+                             : x < 2.5
+                                 ? 1.0
+                                 : 0.0;
+        }
+        default:
+            return 0.0;
+    }
+}
+
+typedef BSpline<4, double> QuarticBSplineKernel;
+
+/********************************************************/
+/*                                                      */
+/*                     BSpline<5, T>                    */
+/*                                                      */
+/********************************************************/
+
+template <class T>
+class BSpline<5, T>
+{
+  public:
+
+    typedef T            value_type;
+    typedef T            argument_type;
+    typedef T            first_argument_type;
+    typedef unsigned int second_argument_type;
+    typedef T            result_type;
+    enum StaticOrder { order = 5 };
+
+    explicit BSpline(unsigned int derivativeOrder = 0)
+    : derivativeOrder_(derivativeOrder)
+    {}
+
+    result_type operator()(argument_type x) const
+    {
+        return exec(x, derivativeOrder_);
+    }
+
+    result_type operator()(first_argument_type x, second_argument_type derivative_order) const
+    {
+         return exec(x, derivativeOrder_ + derivative_order);
+    }
+
+    template <class U, int N>
+    autodiff::DualVector<U, N> operator()(autodiff::DualVector<U, N> x) const
+    {
+        x = abs(x);
+        if(x <= 1.0)
+        {
+            return 0.55 + x*x*(-0.5 + x*x*(0.25 - x/12.0));
+        }
+        else if(x < 2.0)
+        {
+            return 17.0/40.0 + x*(0.625 + x*(-1.75 + x*(1.25 + x*(-0.375 + x/24.0))));
+        }
+        else if(x < 3.0)
+        {
+            x = 3.0 - x;
+            return x*sq(x*x) / 120.0;
+        }
+        else
+            return autodiff::DualVector<U, N>(0.0);
+    }
+
+    result_type dx(argument_type x) const
+        { return operator()(x, 1); }
+
+    result_type dxx(argument_type x) const
+        { return operator()(x, 2); }
+
+    result_type dx3(argument_type x) const
+        { return operator()(x, 3); }
+
+    result_type dx4(argument_type x) const
+        { return operator()(x, 4); }
+
+    value_type operator[](value_type x) const
+        { return operator()(x); }
+
+    double radius() const
+        { return 3.0; }
+
+    unsigned int derivativeOrder() const
+        { return derivativeOrder_; }
+
+    ArrayVector<double> const & prefilterCoefficients() const
+    {
+        return prefilterCoefficients_;
+    }
+
+    typedef T WeightMatrix[6][6];
+
+    static WeightMatrix const & weights()
+    {
+        return weightMatrix_;
+    }
+
+  protected:
+    result_type exec(first_argument_type x, second_argument_type derivative_order) const;
+
+    static ArrayVector<double> calculatePrefilterCoefficients()
+    {
+        ArrayVector<double> b(2);
+        // -(13/2) + sqrt(105)/2 + sqrt(1/2*((135 - 13*sqrt(105))))
+        b[0] = -0.430575347099973791851434783493;
+        // (1/2)*((-13) - sqrt(105) + sqrt(2*((135 + 13*sqrt(105)))))
+        b[1] = -0.043096288203264653822712376822;
+        return b;
+    }
+
+    unsigned int derivativeOrder_;
+    static ArrayVector<double> prefilterCoefficients_;
+    static WeightMatrix weightMatrix_;
+};
+
+template <class T>
+ArrayVector<double> BSpline<5, T>::prefilterCoefficients_(calculatePrefilterCoefficients());
+
+template <class T>
+typename BSpline<5, T>::WeightMatrix BSpline<5, T>::weightMatrix_ = 
+                           {{ 1.0/120.0, 13.0/60.0, 11.0/20.0, 13.0/60.0, 1.0/120.0, 0.0},
+                            {-1.0/24.0, -5.0/12.0, 0.0, 5.0/12.0, 1.0/24.0, 0.0},
+                            { 1.0/12.0, 1.0/6.0, -0.5, 1.0/6.0, 1.0/12.0, 0.0},
+                            {-1.0/12.0, 1.0/6.0, 0.0, -1.0/6.0, 1.0/12.0, 0.0},
+                            { 1.0/24.0, -1.0/6.0, 0.25, -1.0/6.0, 1.0/24.0, 0.0},
+                            {-1.0/120.0, 1.0/24.0, -1.0/12.0, 1.0/12.0, -1.0/24.0, 1.0/120.0}};
+
+template <class T>
+typename BSpline<5, T>::result_type
+BSpline<5, T>::exec(first_argument_type x, second_argument_type derivative_order) const
+{
+    switch(derivative_order)
+    {
+        case 0:
+        {
+            x = VIGRA_CSTD::fabs(x);
+            if(x <= 1.0)
+            {
+                return 0.55 + x*x*(-0.5 + x*x*(0.25 - x/12.0));
+            }
+            else if(x < 2.0)
+            {
+                return 17.0/40.0 + x*(0.625 + x*(-1.75 + x*(1.25 + x*(-0.375 + x/24.0))));
+            }
+            else if(x < 3.0)
+            {
+                x = 3.0 - x;
+                return x*sq(x*x) / 120.0;
+            }
+            else
+                return 0.0;
+        }
+        case 1:
+        {
+            double s = x < 0.0 ?
+                          -1.0 :
+                           1.0;
+            x = VIGRA_CSTD::fabs(x);
+            if(x <= 1.0)
+            {
+                return s*x*(-1.0 + x*x*(1.0 - 5.0/12.0*x));
+            }
+            else if(x < 2.0)
+            {
+                return s*(0.625 + x*(-3.5 + x*(3.75 + x*(-1.5 + 5.0/24.0*x))));
+            }
+            else if(x < 3.0)
+            {
+                x = 3.0 - x;
+                return s*sq(x*x) / -24.0;
+            }
+            else
+                return 0.0;
+        }
+        case 2:
+        {
+            x = VIGRA_CSTD::fabs(x);
+            if(x <= 1.0)
+            {
+                return -1.0 + x*x*(3.0 -5.0/3.0*x);
+            }
+            else if(x < 2.0)
+            {
+                return -3.5 + x*(7.5 + x*(-4.5 + 5.0/6.0*x));
+            }
+            else if(x < 3.0)
+            {
+                x = 3.0 - x;
+                return x*x*x / 6.0;
+            }
+            else
+                return 0.0;
+        }
+        case 3:
+        {
+            double s = x < 0.0 ?
+                          -1.0 :
+                           1.0;
+            x = VIGRA_CSTD::fabs(x);
+            if(x <= 1.0)
+            {
+                return s*x*(6.0 - 5.0*x);
+            }
+            else if(x < 2.0)
+            {
+                return s*(7.5 + x*(-9.0 + 2.5*x));
+            }
+            else if(x < 3.0)
+            {
+                x = 3.0 - x;
+                return -0.5*s*x*x;
+            }
+            else
+                return 0.0;
+        }
+        case 4:
+        {
+            x = VIGRA_CSTD::fabs(x);
+            if(x <= 1.0)
+            {
+                return 6.0 - 10.0*x;
+            }
+            else if(x < 2.0)
+            {
+                return -9.0 + 5.0*x;
+            }
+            else if(x < 3.0)
+            {
+                return 3.0 - x;
+            }
+            else
+                return 0.0;
+        }
+        case 5:
+        {
+            return x < 0.0 ?
+                     x < -2.0 ?
+                       x < -3.0 ?
+                         0.0
+                       : 1.0
+                     : x < -1.0 ?
+                         -5.0
+                       : 10.0
+                   : x < 2.0 ?
+                       x < 1.0 ?
+                         -10.0
+                       : 5.0
+                     : x < 3.0 ?
+                         -1.0
+                       : 0.0;
+        }
+        default:
+            return 0.0;
+    }
+}
+
+typedef BSpline<5, double> QuinticBSplineKernel;
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+/********************************************************/
+/*                                                      */
+/*                      CatmullRomSpline                */
+/*                                                      */
+/********************************************************/
+
+/** Interpolating 3-rd order splines.
+
+    Implements the Catmull/Rom cardinal function
+
+    \f[ f(x) = \left\{ \begin{array}{ll}
+                                  \frac{3}{2}x^3 - \frac{5}{2}x^2 + 1 & |x| \leq 1 \\
+                                  -\frac{1}{2}x^3 + \frac{5}{2}x^2 -4x + 2 & |x| \leq 2 \\
+                                  0 & \mbox{otherwise}
+                        \end{array}\right.
+    \f]
+
+    It can be used as a functor, and as a kernel for
+    \ref resamplingConvolveImage() to create a differentiable interpolant
+    of an image. However, it should be noted that a twice differentiable
+    interpolant can be created with only slightly more effort by recursive
+    prefiltering followed by convolution with a 3rd order B-spline.
+
+    <b>\#include</b> \<vigra/splines.hxx\><br>
+    Namespace: vigra
+*/
+template <class T = double>
+class CatmullRomSpline
+{
+public:
+        /** the kernel's value type
+        */
+    typedef T value_type;
+        /** the unary functor's argument type
+        */
+    typedef T argument_type;
+        /** the unary functor's result type
+        */
+    typedef T result_type;
+        /** the splines polynomial order
+        */
+    enum StaticOrder { order = 3 };
+
+        /** function (functor) call
+        */
+    result_type operator()(argument_type x) const;
+
+        /** index operator -- same as operator()
+        */
+    T operator[] (T x) const
+        { return operator()(x); }
+
+        /** Radius of the function's support.
+            Needed for  \ref resamplingConvolveImage(), always 2.
+        */
+    int radius() const
+        {return 2;}
+
+        /** Derivative order of the function: always 0.
+        */
+    unsigned int derivativeOrder() const
+        { return 0; }
+
+        /** Prefilter coefficients for compatibility with \ref vigra::BSpline.
+            (array has zero length, since prefiltering is not necessary).
+        */
+    ArrayVector<double> const & prefilterCoefficients() const
+    {
+        return prefilterCoefficients_;
+    }
+    
+  protected:
+    static ArrayVector<double> prefilterCoefficients_;
+};
+
+template <class T>
+ArrayVector<double> CatmullRomSpline<T>::prefilterCoefficients_;
+
+template <class T>
+typename CatmullRomSpline<T>::result_type
+CatmullRomSpline<T>::operator()(argument_type x) const
+{
+    x = VIGRA_CSTD::fabs(x);
+    if (x <= 1.0)
+    {
+        return 1.0 + x * x * (-2.5 + 1.5 * x);
+    }
+    else if (x >= 2.0)
+    {
+        return 0.0;
+    }
+    else
+    {
+        return 2.0 + x * (-4.0 + x * (2.5 - 0.5 * x));
+    }
+}
+
+
+//@}
+
+} // namespace vigra
+
+
+#endif /* VIGRA_SPLINES_HXX */
diff --git a/include/vigra/static_assert.hxx b/include/vigra/static_assert.hxx
new file mode 100644
index 0000000..a673909
--- /dev/null
+++ b/include/vigra/static_assert.hxx
@@ -0,0 +1,133 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2004-2005 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_STATIC_ASSERT_HXX
+#define VIGRA_STATIC_ASSERT_HXX
+
+// based on the static assertion design in boost::mpl (see www.boost.org)
+
+#define VIGRA_PREPROCESSOR_CONCATENATE(a, b) VIGRA_PREPROCESSOR_CONCATENATE_IMPL(a, b)
+#define VIGRA_PREPROCESSOR_CONCATENATE_IMPL(a, b) a ## b
+
+namespace vigra {
+
+namespace staticAssert {
+
+template <bool Predicate>
+struct AssertBool;
+
+template <>
+struct AssertBool<true>
+{
+    typedef int type;
+    typedef void * not_type;
+};
+
+template <>
+struct AssertBool<false>
+{
+    typedef void * type;
+    typedef int not_type;
+};
+
+template <class T>
+struct Assert;
+
+template <>
+struct Assert<VigraTrueType>
+{
+    typedef int type;
+    typedef void * not_type;
+};
+
+template <>
+struct Assert<VigraFalseType>
+{
+    typedef void * type;
+    typedef int not_type;
+};
+
+struct failure{};
+struct success {};
+inline int check( success ) { return 0; }
+
+template< typename Predicate >
+failure ************ (Predicate::************ 
+      assertImpl( void (*)(Predicate), typename Predicate::not_type )
+    );
+
+template< typename Predicate >
+success
+assertImpl( void (*)(Predicate), typename Predicate::type );
+
+/* Usage:
+
+1. Define an assertion class, derived from vigra::staticAssert::Assert,
+   whose name serves as an error message:
+   
+    template <int N>
+    struct FixedPoint_overflow_error__More_than_31_bits_requested
+    : vigra::staticAssert::AssertBool<(N < 32)>
+    {};
+
+2. Call VIGRA_STATIC_ASSERT() with the assertion class:
+
+    template <int N>
+    void test()
+    {
+        // signal error if N > 31
+        VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_requested<N>));
+    }
+    
+TODO: provide more assertion base classes for other (non boolean) types of tests
+*/
+#if !defined(__GNUC__) || __GNUC__ > 2
+#define VIGRA_STATIC_ASSERT(Predicate) \
+enum { \
+    VIGRA_PREPROCESSOR_CONCATENATE(vigra_assertion_in_line_, __LINE__) = sizeof( \
+         staticAssert::check( \
+              staticAssert::assertImpl( (void (*) Predicate)0, 1 ) \
+            ) \
+        ) \
+}
+#else
+#define VIGRA_STATIC_ASSERT(Predicate)
+#endif
+
+} // namespace staticAssert
+
+} // namespace vigra
+
+#endif // VIGRA_STATIC_ASSERT_HXX
diff --git a/include/vigra/stdconvolution.hxx b/include/vigra/stdconvolution.hxx
new file mode 100644
index 0000000..af229d3
--- /dev/null
+++ b/include/vigra/stdconvolution.hxx
@@ -0,0 +1,1347 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_STDCONVOLUTION_HXX
+#define VIGRA_STDCONVOLUTION_HXX
+
+#include <cmath>
+#include "stdimage.hxx"
+#include "bordertreatment.hxx"
+#include "separableconvolution.hxx"
+#include "utilities.hxx"
+#include "sized_int.hxx"
+#include "multi_iterator.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+template <class ARITHTYPE>
+class Kernel2D;
+
+/** \addtogroup CommonConvolutionFilters
+*/
+//@{
+
+    // documentation is in convolution.hxx
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+void convolveImage(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
+                   DestIterator dest_ul, DestAccessor dest_acc,
+                   KernelIterator ki, KernelAccessor ak,
+                   Diff2D kul, Diff2D klr, BorderTreatmentMode border)
+{
+    vigra_precondition((border == BORDER_TREATMENT_CLIP    ||
+                        border == BORDER_TREATMENT_AVOID   ||
+                        border == BORDER_TREATMENT_REFLECT ||
+                        border == BORDER_TREATMENT_REPEAT  ||
+                        border == BORDER_TREATMENT_WRAP    ||
+                        border == BORDER_TREATMENT_ZEROPAD),
+                       "convolveImage():\n"
+                       "  Border treatment must be one of follow treatments:\n"
+                       "  - BORDER_TREATMENT_CLIP\n"
+                       "  - BORDER_TREATMENT_AVOID\n"
+                       "  - BORDER_TREATMENT_REFLECT\n"
+                       "  - BORDER_TREATMENT_REPEAT\n"
+                       "  - BORDER_TREATMENT_WRAP\n"
+                       "  - BORDER_TREATMENT_ZEROPAD\n");
+
+    vigra_precondition(kul.x <= 0 && kul.y <= 0,
+                       "convolveImage(): coordinates of "
+                       "kernel's upper left must be <= 0.");
+    vigra_precondition(klr.x >= 0 && klr.y >= 0,
+                       "convolveImage(): coordinates of "
+                       "kernel's lower right must be >= 0.");
+
+    // use traits to determine SumType as to prevent possible overflow
+    typedef typename
+        PromoteTraits<typename SrcAccessor::value_type,
+                      typename KernelAccessor::value_type>::Promote SumType;
+    typedef typename
+        NumericTraits<typename KernelAccessor::value_type>::RealPromote KernelSumType;
+    typedef typename DestAccessor::value_type DestType;
+
+    // calculate width and height of the image
+    int w = src_lr.x - src_ul.x;
+    int h = src_lr.y - src_ul.y;
+
+    // calculate width and height of the kernel
+    int kernel_width  = klr.x - kul.x + 1;
+    int kernel_height = klr.y - kul.y + 1;
+
+    vigra_precondition(w >= std::max(klr.x, -kul.x) + 1 && h >= std::max(klr.y, -kul.y) + 1,
+                       "convolveImage(): kernel larger than image.");
+
+    KernelSumType norm = KernelSumType();
+    if(border == BORDER_TREATMENT_CLIP)
+    {
+        // calculate the sum of the kernel elements for renormalization
+        KernelIterator yk  = ki + klr;
+
+        // determine sum within kernel (= norm)
+        for(int y = 0; y < kernel_height; ++y, --yk.y)
+        {
+            KernelIterator xk  = yk;
+            for(int x = 0; x < kernel_width; ++x, --xk.x)
+            {
+                norm += ak(xk);
+            }
+        }
+        vigra_precondition(norm != NumericTraits<KernelSumType>::zero(),
+            "convolveImage(): Cannot use BORDER_TREATMENT_CLIP with a DC-free kernel");
+    }
+
+    DestIterator yd = dest_ul;
+    SrcIterator ys = src_ul;
+
+    // iterate over the interior part
+    for(int y=0; y<h; ++y, ++ys.y, ++yd.y)
+    {
+        // create x iterators
+        DestIterator xd(yd);
+        SrcIterator xs(ys);
+
+        for(int x=0; x < w; ++x, ++xs.x, ++xd.x)
+        {
+            // init the sum
+            SumType sum = NumericTraits<SumType>::zero();
+            KernelIterator ykernel  = ki + klr;
+            
+            if(x >= klr.x && y >= klr.y && x < w + kul.x && y < h + kul.y)
+            {
+                // kernel is entirely inside the image
+                SrcIterator yys = xs - klr;
+                SrcIterator yyend = xs - kul;
+
+                for(; yys.y <= yyend.y; ++yys.y, --ykernel.y)
+                {
+                    typename SrcIterator::row_iterator xxs = yys.rowIterator();
+                    typename SrcIterator::row_iterator xxe = xxs + kernel_width;
+                    typename KernelIterator::row_iterator xkernel= ykernel.rowIterator();
+
+                    for(; xxs < xxe; ++xxs, --xkernel)
+                    {
+                        sum += ak(xkernel) * src_acc(xxs);
+                    }
+                }
+            }
+            else if(border == BORDER_TREATMENT_REPEAT)
+            {
+                Diff2D diff;
+                for(int yk = klr.y; yk >= kul.y; --yk, --ykernel.y)
+                {
+                    diff.y = std::min(std::max(y - yk, 0), h-1);
+                    typename KernelIterator::row_iterator xkernel  = ykernel.rowIterator();
+
+                    for(int xk = klr.x; xk >= kul.x; --xk, --xkernel)
+                    {
+                        diff.x = std::min(std::max(x - xk, 0), w-1);
+                        sum += ak(xkernel) * src_acc(src_ul, diff);
+                    }
+                }
+            }
+            else if(border == BORDER_TREATMENT_REFLECT)
+            {
+                Diff2D diff;
+                for(int yk = klr.y; yk >= kul.y; --yk , --ykernel.y)
+                {
+                    diff.y = abs(y - yk);
+                    if(diff.y >= h)
+                        diff.y = 2*h - 2 - diff.y;
+                    typename KernelIterator::row_iterator xkernel  = ykernel.rowIterator();
+
+                    for(int xk = klr.x; xk >= kul.x; --xk, --xkernel)
+                    {
+                        diff.x = abs(x - xk);
+                        if(diff.x >= w)
+                            diff.x = 2*w - 2 - diff.x;
+                        sum += ak(xkernel) * src_acc(src_ul, diff);
+                    }
+                }
+            }
+            else if(border == BORDER_TREATMENT_WRAP)
+            {
+                Diff2D diff;
+                for(int yk = klr.y; yk >= kul.y; --yk, --ykernel.y)
+                {
+                    diff.y = (y - yk + h) % h;
+                    typename KernelIterator::row_iterator xkernel  = ykernel.rowIterator();
+
+                    for(int xk = klr.x; xk >= kul.x; --xk, --xkernel)
+                    {
+                        diff.x = (x - xk + w) % w;
+                        sum += ak(xkernel) * src_acc(src_ul, diff);
+                    }
+                }
+            }
+            else if(border == BORDER_TREATMENT_CLIP)
+            {
+                KernelSumType ksum = NumericTraits<KernelSumType>::zero();
+                Diff2D diff;
+                for(int yk = klr.y; yk >= kul.y; --yk, --ykernel.y)
+                {
+                    diff.y = y - yk;
+                    if(diff.y < 0 || diff.y >= h)
+                        continue;
+                    typename KernelIterator::row_iterator xkernel  = ykernel.rowIterator();
+
+                    for(int xk = klr.x; xk >= kul.x; --xk, --xkernel)
+                    {
+                        diff.x = x - xk;
+                        if(diff.x < 0 || diff.x >= w)
+                            continue;
+                        ksum += ak(xkernel);
+                        sum += ak(xkernel) * src_acc(src_ul, diff);
+                    }
+                }
+                
+                sum *= norm / ksum;
+            }
+            else if(border == BORDER_TREATMENT_ZEROPAD)
+            {
+                Diff2D diff;
+                for(int yk = klr.y; yk >= kul.y; --yk, --ykernel.y)
+                {
+                    diff.y = y - yk;
+                    if(diff.y < 0 || diff.y >= h)
+                        continue;
+                    typename KernelIterator::row_iterator xkernel  = ykernel.rowIterator();
+
+                    for(int xk = klr.x; xk >= kul.x; --xk, --xkernel)
+                    {
+                        diff.x = x - xk;
+                        if(diff.x < 0 || diff.x >= w)
+                            continue;
+                        sum += ak(xkernel) * src_acc(src_ul, diff);
+                    }
+                }
+            }
+            else if(border == BORDER_TREATMENT_AVOID)
+            {
+                continue;
+            }
+
+            // store convolution result in destination pixel
+            dest_acc.set(detail::RequiresExplicitCast<DestType>::cast(sum), xd);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class KernelIterator, class KernelAccessor>
+inline void
+convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+              pair<DestIterator, DestAccessor> dest,
+              tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D,
+              BorderTreatmentMode> kernel)
+{
+    convolveImage(src.first, src.second, src.third,
+                  dest.first, dest.second,
+                  kernel.first, kernel.second, kernel.third,
+                  kernel.fourth, kernel.fifth);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class T3>
+inline void
+convolveImage(MultiArrayView<2, T1, S1> const & src,
+              MultiArrayView<2, T2, S2> dest,
+              Kernel2D<T3> const & kernel)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "convolveImage(): shape mismatch between input and output.");
+    convolveImage(srcImageRange(src),
+                  destImage(dest),
+                  kernel2d(kernel));
+}
+
+/** \brief Performs a 2-dimensional normalized convolution, i.e. convolution with a mask image.
+
+    This functions computes
+    <a href ="http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/PIRODDI1/NormConv/NormConv.html">normalized
+    convolution</a> as defined in
+    Knutsson, H. and Westin, C-F.: <i>Normalized and differential convolution:
+    Methods for Interpolation and Filtering of incomplete and uncertain data</i>.
+    Proc. of the IEEE Conf. on Computer Vision and Pattern Recognition, 1993, 515-523.
+
+    The mask image must be binary and encodes which pixels of the original image
+    are valid. It is used as follows:
+    Only pixel under the mask are used in the calculations. Whenever a part of the
+    kernel lies outside the mask, it is ignored, and the kernel is renormalized to its
+    original norm (analogous to the CLIP \ref BorderTreatmentMode). Thus, a useful convolution
+    result is computed whenever <i>at least one valid pixel is within the current window</i>
+    Thus, destination pixels not under the mask still receive a value if they are <i>near</i>
+    the mask. Therefore, this algorithm is useful as an interpolator of sparse input data.
+    If you are only interested in the destination values under the mask, you can perform
+    a subsequent \ref copyImageIf().
+
+    The KernelIterator must point to the center of the kernel, and
+    the kernel's size is given by its upper left (x and y of distance <= 0) and
+    lower right (distance >= 0) corners. The image must always be larger than the
+    kernel. At those positions where the kernel does not completely fit
+    into the image, the specified \ref BorderTreatmentMode is
+    applied. Only BORDER_TREATMENT_CLIP and BORDER_TREATMENT_AVOID are currently
+    supported.
+
+    The images's pixel type (SrcAccessor::value_type) must be a
+    linear space over the kernel's value_type (KernelAccessor::value_type),
+    i.e. addition of source values, multiplication with kernel values,
+    and NumericTraits must be defined.
+    The kernel's value_type must be an algebraic field,
+    i.e. the arithmetic operations (+, -, *, /) and NumericTraits must
+    be defined.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class TM, class SM,
+                  class T3>
+        void
+        normalizedConvolveImage(MultiArrayView<2, T1, S1> const & src,
+                                MultiArrayView<2, TM, SM> const & mask,
+                                MultiArrayView<2, T2, S2> dest,
+                                Kernel2D<T3> const & kernel);
+    }
+    \endcode
+
+    \deprecatedAPI{normalizedConvolveImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void
+        normalizedConvolveImage(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
+                                MaskIterator mul, MaskAccessor am,
+                                DestIterator dest_ul, DestAccessor dest_acc,
+                                KernelIterator ki, KernelAccessor ak,
+                                Diff2D kul, Diff2D klr, BorderTreatmentMode border);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void normalizedConvolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                     pair<MaskIterator, MaskAccessor> mask,
+                                     pair<DestIterator, DestAccessor> dest,
+                                     tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D,
+                                     BorderTreatmentMode> kernel);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/stdconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float>          src(w,h), dest(w,h);
+    MultiArray<2, unsigned char>  mask(w,h);
+    ...
+    // define 3x3 binomial filter
+    vigra::Kernel2D<float> binom;
+    binom.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) =   // upper left and lower right
+                         0.0625, 0.125, 0.0625,
+                         0.125,  0.25,  0.125,
+                         0.0625, 0.125, 0.0625;
+
+    normalizedConvolveImage(src, mask, dest, binom);
+    \endcode
+
+    \deprecatedUsage{normalizedConvolveImage}
+    \code
+    vigra::FImage src(w,h), dest(w,h);
+    vigra::CImage mask(w,h);
+    ...
+
+    // define 3x3 binomial filter
+    vigra::Kernel2D<float> binom;
+
+    binom.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) =   // upper left and lower right
+                         0.0625, 0.125, 0.0625,
+                         0.125,  0.25,  0.125,
+                         0.0625, 0.125, 0.0625;
+
+    vigra::normalizedConvolveImage(srcImageRange(src), maskImage(mask), destImage(dest), kernel2d(binom));
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator src_ul, src_lr;
+    ImageIterator mul;
+    ImageIterator dest_ul;
+    ImageIterator ik;
+
+    SrcAccessor src_accessor;
+    MaskAccessor mask_accessor;
+    DestAccessor dest_accessor;
+    KernelAccessor kernel_accessor;
+
+    NumericTraits<SrcAccessor::value_type>::RealPromote s = src_accessor(src_ul);
+
+    s = s + s;
+    s = kernel_accessor(ik) * s;
+    s -= s;
+
+    if(mask_accessor(mul)) ...;
+
+    dest_accessor.set(
+    NumericTraits<DestAccessor::value_type>::fromRealPromote(s), dest_ul);
+
+    NumericTraits<KernelAccessor::value_type>::RealPromote k = kernel_accessor(ik);
+
+    k += k;
+    k -= k;
+    k = k / k;
+
+    \endcode
+    \deprecatedEnd
+
+    <b> Preconditions:</b>
+
+    <ul>
+    <li> The image must be longer than the kernel radius: <tt>w > std::max(kernel.lowerRight().x, -kernel.upperLeft().x)</tt> and 
+         <tt>h > std::max(kernel.lowerRight().y, -kernel.upperLeft().y)</tt>.
+    <li> The sum of kernel elements must be != 0.
+    <li> <tt>border == BORDER_TREATMENT_CLIP || border == BORDER_TREATMENT_AVOID</tt>
+    </ul>
+*/
+doxygen_overloaded_function(template <...> void normalizedConvolveImage)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class MaskIterator, class MaskAccessor,
+          class KernelIterator, class KernelAccessor>
+void
+normalizedConvolveImage(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
+                        MaskIterator mul, MaskAccessor am,
+                        DestIterator dest_ul, DestAccessor dest_acc,
+                        KernelIterator ki, KernelAccessor ak,
+                        Diff2D kul, Diff2D klr, BorderTreatmentMode border)
+{
+    vigra_precondition((border == BORDER_TREATMENT_CLIP  ||
+                        border == BORDER_TREATMENT_AVOID),
+                       "normalizedConvolveImage(): "
+                       "Border treatment must be BORDER_TREATMENT_CLIP or BORDER_TREATMENT_AVOID.");
+
+    vigra_precondition(kul.x <= 0 && kul.y <= 0,
+                       "normalizedConvolveImage(): left borders must be <= 0.");
+    vigra_precondition(klr.x >= 0 && klr.y >= 0,
+                       "normalizedConvolveImage(): right borders must be >= 0.");
+
+    // use traits to determine SumType as to prevent possible overflow
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote SumType;
+    typedef typename
+        NumericTraits<typename KernelAccessor::value_type>::RealPromote KSumType;
+    typedef
+        NumericTraits<typename DestAccessor::value_type> DestTraits;
+
+    // calculate width and height of the image
+    int w = src_lr.x - src_ul.x;
+    int h = src_lr.y - src_ul.y;
+    int kernel_width = klr.x - kul.x + 1;
+    int kernel_height = klr.y - kul.y + 1;
+
+    int x,y;
+    int ystart = (border == BORDER_TREATMENT_AVOID) ?  klr.y : 0;
+    int yend   = (border == BORDER_TREATMENT_AVOID) ? h+kul.y : h;
+    int xstart = (border == BORDER_TREATMENT_AVOID) ?  klr.x : 0;
+    int xend   = (border == BORDER_TREATMENT_AVOID) ? w+kul.x : w;
+
+    // create y iterators
+    DestIterator yd = dest_ul + Diff2D(xstart, ystart);
+    SrcIterator ys = src_ul + Diff2D(xstart, ystart);
+    MaskIterator ym = mul + Diff2D(xstart, ystart);
+
+    KSumType norm = ak(ki);
+    int xx, yy;
+    KernelIterator yk  = ki + klr;
+    for(yy=0; yy<kernel_height; ++yy, --yk.y)
+    {
+        KernelIterator xk  = yk;
+
+        for(xx=0; xx<kernel_width; ++xx, --xk.x)
+        {
+            norm += ak(xk);
+        }
+    }
+    norm -= ak(ki);
+
+
+    for(y=ystart; y < yend; ++y, ++ys.y, ++yd.y, ++ym.y)
+    {
+        // create x iterators
+        DestIterator xd(yd);
+        SrcIterator xs(ys);
+        MaskIterator xm(ym);
+
+        for(x=xstart; x < xend; ++x, ++xs.x, ++xd.x, ++xm.x)
+        {
+            // how much of the kernel fits into the image ?
+            int x0, y0, x1, y1;
+
+            y0 = (y<klr.y) ? -y : -klr.y;
+            y1 = (h-y-1<-kul.y) ? h-y-1 : -kul.y;
+            x0 = (x<klr.x) ? -x : -klr.x;
+            x1 = (w-x-1<-kul.x) ? w-x-1 : -kul.x;
+
+            bool first = true;
+            // init the sum
+            SumType sum = NumericTraits<SumType>::zero();
+            KSumType ksum = NumericTraits<KSumType>::zero();
+
+            SrcIterator yys = xs + Diff2D(x0, y0);
+            MaskIterator yym = xm + Diff2D(x0, y0);
+            KernelIterator yk  = ki - Diff2D(x0, y0);
+
+            int kernel_width, kernel_height;
+            kernel_width = x1 - x0 + 1;
+            kernel_height = y1 - y0 + 1;
+            for(yy=0; yy<kernel_height; ++yy, ++yys.y, --yk.y, ++yym.y)
+            {
+                typename SrcIterator::row_iterator xxs = yys.rowIterator();
+                typename SrcIterator::row_iterator xxend = xxs + kernel_width;
+                typename MaskIterator::row_iterator xxm = yym.rowIterator();
+                typename KernelIterator::row_iterator xk  = yk.rowIterator();
+
+                for(xx=0; xxs < xxend; ++xxs, --xk, ++xxm)
+                {
+                    if(!am(xxm)) continue;
+
+                    if(first)
+                    {
+                        sum = detail::RequiresExplicitCast<SumType>::cast(ak(xk) * src_acc(xxs));
+                        ksum = ak(xk);
+                        first = false;
+                    }
+                    else
+                    {
+                        sum = detail::RequiresExplicitCast<SumType>::cast(sum + ak(xk) * src_acc(xxs));
+                        ksum += ak(xk);
+                    }
+                }
+            }
+            // store average in destination pixel
+            if(ksum != NumericTraits<KSumType>::zero())
+            {
+                dest_acc.set(DestTraits::fromRealPromote(
+                             detail::RequiresExplicitCast<SumType>::cast((norm / ksum) * sum)), xd);
+            }
+        }
+    }
+}
+
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class MaskIterator, class MaskAccessor,
+          class KernelIterator, class KernelAccessor>
+inline void
+normalizedConvolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        pair<MaskIterator, MaskAccessor> mask,
+                        pair<DestIterator, DestAccessor> dest,
+                        tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D,
+                        BorderTreatmentMode> kernel)
+{
+    normalizedConvolveImage(src.first, src.second, src.third,
+                            mask.first, mask.second,
+                            dest.first, dest.second,
+                            kernel.first, kernel.second, kernel.third,
+                            kernel.fourth, kernel.fifth);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class TM, class SM,
+          class T3>
+inline void
+normalizedConvolveImage(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, TM, SM> const & mask,
+                        MultiArrayView<2, T2, S2> dest,
+                        Kernel2D<T3> const & kernel)
+{
+    vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
+        "normalizedConvolveImage(): shape mismatch between input and output.");
+    normalizedConvolveImage(srcImageRange(src),
+                            maskImage(mask),
+                            destImage(dest),
+                            kernel2d(kernel));
+}
+
+/** \brief Deprecated name of 2-dimensional normalized convolution, i.e. convolution with a mask image.
+
+    See \ref normalizedConvolveImage() for documentation.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void
+        convolveImageWithMask(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
+                              MaskIterator mul, MaskAccessor am,
+                              DestIterator dest_ul, DestAccessor dest_acc,
+                              KernelIterator ki, KernelAccessor ak,
+                              Diff2D kul, Diff2D klr, BorderTreatmentMode border);
+    }
+    \endcode
+
+    \deprecatedAPI{convolveImageWithMask}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void
+        convolveImageWithMask(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
+                              MaskIterator mul, MaskAccessor am,
+                              DestIterator dest_ul, DestAccessor dest_acc,
+                              KernelIterator ki, KernelAccessor ak,
+                              Diff2D kul, Diff2D klr, BorderTreatmentMode border);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class MaskIterator, class MaskAccessor,
+                  class DestIterator, class DestAccessor,
+                  class KernelIterator, class KernelAccessor>
+        void convolveImageWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                   pair<MaskIterator, MaskAccessor> mask,
+                                   pair<DestIterator, DestAccessor> dest,
+                                   tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D,
+                                   BorderTreatmentMode> kernel);
+    }
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void convolveImageWithMask)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class MaskIterator, class MaskAccessor,
+          class KernelIterator, class KernelAccessor>
+inline void
+convolveImageWithMask(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
+                      MaskIterator mul, MaskAccessor am,
+                      DestIterator dest_ul, DestAccessor dest_acc,
+                      KernelIterator ki, KernelAccessor ak,
+                      Diff2D kul, Diff2D klr, BorderTreatmentMode border)
+{
+    normalizedConvolveImage(src_ul, src_lr, src_acc,
+                            mul, am,
+                            dest_ul, dest_acc,
+                            ki, ak, kul, klr, border);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class MaskIterator, class MaskAccessor,
+          class KernelIterator, class KernelAccessor>
+inline
+void convolveImageWithMask(
+                           triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                           pair<MaskIterator, MaskAccessor> mask,
+                           pair<DestIterator, DestAccessor> dest,
+                           tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D,
+                           BorderTreatmentMode> kernel)
+{
+    normalizedConvolveImage(src.first, src.second, src.third,
+                            mask.first, mask.second,
+                            dest.first, dest.second,
+                            kernel.first, kernel.second, kernel.third,
+                            kernel.fourth, kernel.fifth);
+}
+
+//@}
+
+/********************************************************/
+/*                                                      */
+/*                      Kernel2D                        */
+/*                                                      */
+/********************************************************/
+
+/** \brief Generic 2 dimensional convolution kernel.
+
+    This kernel may be used for convolution of 2 dimensional signals.
+
+    Convolution functions access the kernel via an ImageIterator
+    which they get by calling \ref center(). This iterator
+    points to the center of the kernel. The kernel's size is given by its upperLeft()
+    (upperLeft().x <= 0, upperLeft().y <= 0)
+    and lowerRight() (lowerRight().x >= 0, lowerRight().y >= 0) methods.
+    The desired border treatment mode is returned by borderTreatment().
+
+    The different init functions create a kernel with the specified
+    properties. The requirements for the kernel's value_type depend
+    on the init function used. At least NumericTraits must be defined.
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/stdconvolution.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), dest(w,h);
+    ...
+
+    // define horizontal Sobel filter
+    vigra::Kernel2D<float> sobel;
+    sobel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) =  // upper left and lower right
+                         0.125, 0.0, -0.125,
+                         0.25,  0.0, -0.25,
+                         0.125, 0.0, -0.125;
+
+    convolveImage(src, dest, sobel);
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+    value_type v = NumericTraits<value_type>::one();
+    \endcode
+
+    See also the init functions.
+*/
+template <class ARITHTYPE = double>
+class Kernel2D
+{
+public:
+        /** the kernel's value type
+         */
+    typedef ARITHTYPE value_type;
+
+        /** 2D random access iterator over the kernel's values
+         */
+    typedef typename BasicImage<value_type>::traverser Iterator;
+
+        /** const 2D random access iterator over the kernel's values
+         */
+    typedef typename BasicImage<value_type>::const_traverser ConstIterator;
+
+        /** the kernel's accessor
+         */
+    typedef typename BasicImage<value_type>::Accessor Accessor;
+
+        /** the kernel's const accessor
+         */
+    typedef typename BasicImage<value_type>::ConstAccessor ConstAccessor;
+
+    struct InitProxy
+    {
+        typedef typename
+        BasicImage<value_type>::ScanOrderIterator Iterator;
+
+        InitProxy(Iterator i, int count, value_type & norm)
+            : iter_(i), base_(i),
+              count_(count), sum_(count),
+              norm_(norm)
+        {}
+
+        ~InitProxy()
+        {
+            vigra_precondition(count_ == 1 || count_ == sum_,
+                               "Kernel2D::initExplicitly(): "
+                               "Too few init values.");
+        }
+
+        InitProxy & operator,(value_type const & v)
+        {
+            if(count_ == sum_)  norm_ = *iter_;
+
+            --count_;
+            vigra_precondition(count_ > 0,
+                               "Kernel2D::initExplicitly(): "
+                               "Too many init values.");
+
+            norm_ += v;
+
+            ++iter_;
+            *iter_ = v;
+
+            return *this;
+        }
+
+        Iterator iter_, base_;
+        int count_, sum_;
+        value_type & norm_;
+    };
+
+    static value_type one() { return NumericTraits<value_type>::one(); }
+
+        /** Default constructor.
+            Creates a kernel of size 1x1 which would copy the signal
+            unchanged.
+        */
+    Kernel2D()
+        : kernel_(1, 1, one()),
+          left_(0, 0),
+          right_(0, 0),
+          norm_(one()),
+          border_treatment_(BORDER_TREATMENT_REFLECT)
+    {}
+
+        /** Copy constructor.
+         */
+    Kernel2D(Kernel2D const & k)
+        : kernel_(k.kernel_),
+          left_(k.left_),
+          right_(k.right_),
+          norm_(k.norm_),
+          border_treatment_(k.border_treatment_)
+    {}
+
+        /** Copy assignment.
+         */
+    Kernel2D & operator=(Kernel2D const & k)
+    {
+        if(this != &k)
+        {
+        kernel_ = k.kernel_;
+            left_ = k.left_;
+            right_ = k.right_;
+            norm_ = k.norm_;
+        border_treatment_ = k.border_treatment_;
+        }
+        return *this;
+    }
+
+        /** Initialization.
+            This initializes the kernel with the given constant. The norm becomes
+            v*width()*height().
+
+            Instead of a single value an initializer list of length width()*height()
+            can be used like this:
+
+            \code
+            vigra::Kernel2D<float> binom;
+
+            binom.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) =
+            0.0625, 0.125, 0.0625,
+            0.125,  0.25,  0.125,
+            0.0625, 0.125, 0.0625;
+            \endcode
+
+            In this case, the norm will be set to the sum of the init values.
+            An initializer list of wrong length will result in a run-time error.
+        */
+    InitProxy operator=(value_type const & v)
+    {
+        int size = (right_.x - left_.x + 1) *
+                   (right_.y - left_.y + 1);
+        kernel_ = v;
+        norm_ = (double)size*v;
+
+        return InitProxy(kernel_.begin(), size, norm_);
+    }
+
+        /** Destructor.
+         */
+    ~Kernel2D()
+    {}
+
+        /** Init the 2D kernel as the cartesian product of two 1D kernels
+            of type \ref Kernel1D. The norm becomes the product of the two original
+            norms.
+
+            <b> Required Interface:</b>
+
+            The kernel's value_type must be a linear algebra.
+
+            \code
+            vigra::Kernel2D<...>::value_type v;
+            v = v * v;
+            \endcode
+        */
+    void initSeparable(Kernel1D<value_type> const & kx,
+                             Kernel1D<value_type> const & ky)
+    {
+        left_ = Diff2D(kx.left(), ky.left());
+        right_ = Diff2D(kx.right(), ky.right());
+        int w = right_.x - left_.x + 1;
+        int h = right_.y - left_.y + 1;
+        kernel_.resize(w, h);
+
+        norm_ = kx.norm() * ky.norm();
+
+        typedef typename Kernel1D<value_type>::const_iterator KIter;
+        typename Kernel1D<value_type>::Accessor ka;
+
+        KIter kiy = ky.center() + left_.y;
+        Iterator iy = center() + left_;
+
+        for(int y=left_.y; y<=right_.y; ++y, ++kiy, ++iy.y)
+        {
+            KIter kix = kx.center() + left_.x;
+            Iterator ix = iy;
+            for(int x=left_.x; x<=right_.x; ++x, ++kix, ++ix.x)
+            {
+                *ix = ka(kix) * ka(kiy);
+            }
+        }
+    }
+
+        /** Init the 2D kernel as the cartesian product of two 1D kernels
+            given explicitly by iterators and sizes. The norm becomes the
+            sum of the resulting kernel values.
+
+            <b> Required Interface:</b>
+
+            The kernel's value_type must be a linear algebra.
+
+            \code
+            vigra::Kernel2D<...>::value_type v;
+            v = v * v;
+            v += v;
+            \endcode
+
+            <b> Preconditions:</b>
+
+            \code
+            xleft <= 0;
+            xright >= 0;
+            yleft <= 0;
+            yright >= 0;
+            \endcode
+        */
+    template <class KernelIterator>
+    void initSeparable(KernelIterator kxcenter, int xleft, int xright,
+                             KernelIterator kycenter, int yleft, int yright)
+    {
+        vigra_precondition(xleft <= 0 && yleft <= 0,
+                           "Kernel2D::initSeparable(): left borders must be <= 0.");
+        vigra_precondition(xright >= 0 && yright >= 0,
+                           "Kernel2D::initSeparable(): right borders must be >= 0.");
+
+        left_ = Point2D(xleft, yleft);
+        right_ = Point2D(xright, yright);
+
+        int w = right_.x - left_.x + 1;
+        int h = right_.y - left_.y + 1;
+        kernel_.resize(w, h);
+
+        KernelIterator kiy = kycenter + left_.y;
+        Iterator iy = center() + left_;
+
+        for(int y=left_.y; y<=right_.y; ++y, ++kiy, ++iy.y)
+        {
+            KernelIterator kix = kxcenter + left_.x;
+            Iterator ix = iy;
+            for(int x=left_.x; x<=right_.x; ++x, ++kix, ++ix.x)
+            {
+                *ix = *kix * *kiy;
+            }
+        }
+
+        typename BasicImage<value_type>::iterator i = kernel_.begin();
+        typename BasicImage<value_type>::iterator iend = kernel_.end();
+        norm_ = *i;
+        ++i;
+
+        for(; i!= iend; ++i)
+        {
+            norm_ += *i;
+        }
+    }
+
+        /** \brief Init as a 2D box filter with given radius.
+        
+            The function returns a reference to the kernel.
+         */    
+    void initAveraging(int radius)
+    {
+        Kernel1D<value_type> avg;
+        avg.initAveraging(radius);
+        return initSeparable(avg, avg);
+    }
+    
+        /** \brief Init as a 2D Gaussian function with given standard deviation and norm.
+        
+            The function returns a reference to the kernel.
+         */    
+    void initGaussian(double std_dev, value_type norm)
+    {
+        Kernel1D<value_type> gauss;
+        gauss.initGaussian(std_dev, norm);
+        return initSeparable(gauss, gauss);
+    }
+
+        /** \brief Init as a 2D Gaussian function with given standard deviation and unit norm.
+        
+            The function returns a reference to the kernel.
+         */
+    void initGaussian(double std_dev)
+    {
+        return initGaussian(std_dev, NumericTraits<value_type>::one());
+    }
+
+        /** Init the 2D kernel as a circular averaging filter. The norm will be
+            calculated as
+            <TT>NumericTraits<value_type>::one() / (number of non-zero kernel values)</TT>.
+            The kernel's value_type must be a linear space.
+        
+            <b> Required Interface:</b>
+
+            \code
+            value_type v = vigra::NumericTraits<value_type>::one();
+
+            double d;
+            v = d * v;
+            \endcode
+
+            <b> Precondition:</b>
+
+            \code
+            radius > 0;
+            \endcode
+        */
+    void initDisk(int radius)
+    {
+        vigra_precondition(radius > 0,
+                           "Kernel2D::initDisk(): radius must be > 0.");
+
+        left_ = Point2D(-radius, -radius);
+        right_ = Point2D(radius, radius);
+        int w = right_.x - left_.x + 1;
+        int h = right_.y - left_.y + 1;
+        kernel_.resize(w, h);
+        norm_ = NumericTraits<value_type>::one();
+
+        kernel_ = NumericTraits<value_type>::zero();
+        double count = 0.0;
+
+        Iterator k = center();
+        double r2 = (double)radius*radius;
+
+        int i;
+        for(i=0; i<= radius; ++i)
+        {
+            double r = (double) i - 0.5;
+            int w = (int)(VIGRA_CSTD::sqrt(r2 - r*r) + 0.5);
+            for(int j=-w; j<=w; ++j)
+            {
+                k(j, i) = NumericTraits<value_type>::one();
+                k(j, -i) = NumericTraits<value_type>::one();
+                count += (i != 0) ? 2.0 : 1.0;
+            }
+        }
+
+        count = 1.0 / count;
+
+        for(int y=-radius; y<=radius; ++y)
+        {
+            for(int x=-radius; x<=radius; ++x)
+            {
+                k(x,y) = count * k(x,y);
+            }
+        }
+    }
+
+        /** Init the kernel by an explicit initializer list.
+            The upper left and lower right corners (inclusive) of the kernel must be passed
+            either as <tt>Shape2</tt> or <tt>Diff2D</tt> objects. A comma-separated initializer 
+            list for the kernel's weights is given after the assignment operator like this:
+
+            \code
+            // define horizontal Sobel filter
+            vigra::Kernel2D<float> sobel;
+
+            sobel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) =
+            0.125, 0.0, -0.125,
+            0.25,  0.0, -0.25,
+            0.125, 0.0, -0.125;
+            \endcode
+
+            The norm is set to the sum of the initializer values. If the wrong number of
+            values is given, a run-time error results. It is, however, possible to give
+            just one initializer. This creates an averaging filter with the given constant:
+
+            \code
+            vigra::Kernel2D<float> average3x3;
+
+            average3x3.initExplicitly(Shape2(-1,-1), Shape2(1,1)) = 1.0/9.0;
+            \endcode
+
+            Here, the norm is set to value*width()*height().
+
+            <b> Preconditions:</b>
+
+            \code
+            1. upperleft.x <= 0;
+            2. upperleft.y <= 0;
+            3. lowerright.x >= 0;
+            4. lowerright.y >= 0;
+            5. the number of values in the initializer list
+            is 1 or equals the size of the kernel.
+            \endcode
+        */
+    Kernel2D & initExplicitly(Shape2 const & upperleft, Shape2 const & lowerright)
+    {
+        vigra_precondition(upperleft[0] <= 0 && upperleft[1] <= 0,
+                           "Kernel2D::initExplicitly(): left borders must be <= 0.");
+        vigra_precondition(lowerright[0] >= 0 && lowerright[1] >= 0,
+                           "Kernel2D::initExplicitly(): right borders must be >= 0.");
+
+        left_ = Point2D(upperleft[0], upperleft[1]);
+        right_ = Point2D(lowerright[0], lowerright[1]);
+
+        int w = right_.x - left_.x + 1;
+        int h = right_.y - left_.y + 1;
+        kernel_.resize(w, h);
+
+        return *this;
+    }
+
+    Kernel2D & initExplicitly(Diff2D const & upperleft, Diff2D const & lowerright)
+    {
+        return initExplicitly(Shape2(upperleft), Shape2(lowerright));
+    }
+
+        /** Coordinates of the upper left corner of the kernel.
+         */
+    Point2D upperLeft() const { return left_; }
+
+        /** Coordinates of the lower right corner of the kernel.
+         */
+    Point2D lowerRight() const { return right_; }
+
+        /** Width of the kernel.
+         */
+    int width() const { return right_.x - left_.x + 1; }
+
+        /** Height of the kernel.
+         */
+    int height() const { return right_.y - left_.y + 1; }
+
+        /** ImageIterator that points to the center of the kernel (coordinate (0,0)).
+         */
+    Iterator center() { return kernel_.upperLeft() - left_; }
+
+        /** ImageIterator that points to the center of the kernel (coordinate (0,0)).
+         */
+    ConstIterator center() const { return kernel_.upperLeft() - left_; }
+
+        /** Access kernel entry at given position.
+         */
+    value_type & operator()(int x, int y)
+    { return kernel_[Diff2D(x,y) - left_]; }
+
+        /** Read kernel entry at given position.
+         */
+    value_type operator()(int x, int y) const
+    { return kernel_[Diff2D(x,y) - left_]; }
+
+        /** Access kernel entry at given position.
+         */
+    value_type & operator[](Diff2D const & d)
+    { return kernel_[d - left_]; }
+
+        /** Read kernel entry at given position.
+         */
+    value_type operator[](Diff2D const & d) const
+    { return kernel_[d - left_]; }
+
+        /** Norm of the kernel (i.e. sum of its elements).
+         */
+    value_type norm() const { return norm_; }
+
+        /** The kernels default accessor.
+         */
+    Accessor accessor() { return Accessor(); }
+
+        /** The kernels default const accessor.
+         */
+    ConstAccessor accessor() const { return ConstAccessor(); }
+
+        /** Normalize the kernel to the given value. (The norm is the sum of all kernel
+            elements.) The kernel's value_type must be a division algebra or
+            algebraic field.
+
+            <b> Required Interface:</b>
+
+            \code
+            value_type v = vigra::NumericTraits<value_type>::one(); // if norm is not
+                                                                    // given explicitly
+
+            v += v;
+            v = v * v;
+            v = v / v;
+            \endcode
+        */
+    void normalize(value_type norm)
+    {
+        typename BasicImage<value_type>::iterator i = kernel_.begin();
+        typename BasicImage<value_type>::iterator iend = kernel_.end();
+        typename NumericTraits<value_type>::RealPromote sum = *i;
+        ++i;
+
+        for(; i!= iend; ++i)
+        {
+            sum += *i;
+        }
+
+        sum = norm / sum;
+        i = kernel_.begin();
+        for(; i != iend; ++i)
+        {
+            *i = *i * sum;
+        }
+
+        norm_ = norm;
+    }
+
+        /** Normalize the kernel to norm 1.
+         */
+    void normalize()
+    {
+        normalize(one());
+    }
+
+        /** current border treatment mode
+         */
+    BorderTreatmentMode borderTreatment() const
+    { return border_treatment_; }
+
+        /** Set border treatment mode.
+            Only <TT>BORDER_TREATMENT_CLIP</TT> and <TT>BORDER_TREATMENT_AVOID</TT> are currently
+            allowed.
+        */
+    void setBorderTreatment( BorderTreatmentMode new_mode)
+    {
+        vigra_precondition((new_mode == BORDER_TREATMENT_CLIP    ||
+                            new_mode == BORDER_TREATMENT_AVOID   ||
+                            new_mode == BORDER_TREATMENT_REFLECT ||
+                            new_mode == BORDER_TREATMENT_REPEAT  ||
+                            new_mode == BORDER_TREATMENT_WRAP),
+                           "convolveImage():\n"
+                           "  Border treatment must be one of follow treatments:\n"
+                           "  - BORDER_TREATMENT_CLIP\n"
+                           "  - BORDER_TREATMENT_AVOID\n"
+                           "  - BORDER_TREATMENT_REFLECT\n"
+                           "  - BORDER_TREATMENT_REPEAT\n"
+                           "  - BORDER_TREATMENT_WRAP\n");
+
+        border_treatment_ = new_mode;
+    }
+
+
+private:
+    BasicImage<value_type> kernel_;
+    Point2D left_, right_;
+    value_type norm_;
+    BorderTreatmentMode border_treatment_;
+};
+
+/**************************************************************/
+/*                                                            */
+/*         Argument object factories for Kernel2D             */
+/*                                                            */
+/*     (documentation: see vigra/convolution.hxx)             */
+/*                                                            */
+/**************************************************************/
+
+template <class KernelIterator, class KernelAccessor>
+inline
+tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D, BorderTreatmentMode>
+kernel2d(KernelIterator ik, KernelAccessor ak, Diff2D kul, Diff2D klr,
+         BorderTreatmentMode border)
+
+{
+    return
+        tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D, BorderTreatmentMode> (
+                                                             ik, ak, kul, klr, border);
+}
+
+template <class T>
+inline
+tuple5<typename Kernel2D<T>::ConstIterator,
+       typename Kernel2D<T>::ConstAccessor,
+       Diff2D, Diff2D, BorderTreatmentMode>
+kernel2d(Kernel2D<T> const & k)
+
+{
+    return
+        tuple5<typename Kernel2D<T>::ConstIterator,
+               typename Kernel2D<T>::ConstAccessor,
+               Diff2D, Diff2D, BorderTreatmentMode>(
+            k.center(),
+            k.accessor(),
+            k.upperLeft(), k.lowerRight(),
+            k.borderTreatment());
+}
+
+template <class T>
+inline
+tuple5<typename Kernel2D<T>::ConstIterator,
+       typename Kernel2D<T>::ConstAccessor,
+       Diff2D, Diff2D, BorderTreatmentMode>
+kernel2d(Kernel2D<T> const & k, BorderTreatmentMode border)
+
+{
+    return
+        tuple5<typename Kernel2D<T>::ConstIterator,
+               typename Kernel2D<T>::ConstAccessor,
+               Diff2D, Diff2D, BorderTreatmentMode>(
+            k.center(),
+            k.accessor(),
+            k.upperLeft(), k.lowerRight(),
+            border);
+}
+
+
+} // namespace vigra
+
+#endif // VIGRA_STDCONVOLUTION_HXX
diff --git a/include/vigra/stdimage.hxx b/include/vigra/stdimage.hxx
new file mode 100644
index 0000000..b6622d7
--- /dev/null
+++ b/include/vigra/stdimage.hxx
@@ -0,0 +1,333 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_STDIMAGE_HXX
+#define VIGRA_STDIMAGE_HXX
+
+#include "sized_int.hxx"
+#include "tuple.hxx"
+#include "basicimage.hxx"
+#include "iteratortraits.hxx"
+#include "accessor.hxx"
+#include "rgbvalue.hxx"
+
+namespace vigra { 
+
+/** \addtogroup StandardImageTypes Standard Image Types
+
+    \brief The most common instantiations of the \ref vigra::BasicImage template
+*/
+//@{
+
+    /** Byte (8-bit unsigned) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<UInt8> BImage;
+
+    /** Byte (8-bit unsigned) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<UInt8> UInt8Image;
+
+    /** Signed byte (8-bit signed) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<Int8> Int8Image;
+
+    /** Short integer (16-bit signed) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<Int16> SImage;
+
+    /** Short integer (16-bit unsigned) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<UInt16> UInt16Image;
+
+    /** Short integer (16-bit signed) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<Int16> Int16Image;
+
+    /** Integer (32-bit signed) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<Int32> IImage;
+
+    /** Integer (32-bit unsigned) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<UInt32> UInt32Image;
+
+    /** Integer (32-bit signed) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<Int32> Int32Image;
+
+    /** Float (float) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<float> FImage;
+
+
+    /** Double (double) image.
+        It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAccessor and 
+        their const counterparts to access the data.
+   
+       <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+ */
+typedef BasicImage<double> DImage;
+
+
+    /** Byte (3x 8-bit unsigned) RGB image.
+        The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt8>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<RGBValue<UInt8> > BRGBImage;
+
+    /** Byte (3x 8-bit unsigned) RGB image.
+        The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt8>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<RGBValue<UInt8> > UInt8RGBImage;
+
+    /** Byte (3x 8-bit signed) RGB image.
+        The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt8>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<RGBValue<Int8> > Int8RGBImage;
+
+    /** Short (3x 16-bit signed) RGB image.
+        The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int16>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<RGBValue<Int16> > SRGBImage;
+
+    /** Short (3x 16-bit unsigned) RGB image.
+        The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int16>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<RGBValue<UInt16> > UInt16RGBImage;
+
+    /** Short (3x 16-bit signed) RGB image.
+        The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int16>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<RGBValue<Int16> > Int16RGBImage;
+
+    /** Integer (3x 32-bit signed) RGB image.
+        The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int32>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<RGBValue<Int32> > IRGBImage;
+
+    /** Integer (3x 32-bit unsigned) RGB image.
+        The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int32>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<RGBValue<UInt32> > UInt32RGBImage;
+
+    /** Integer (3x 32-bit signed) RGB image.
+        The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int32>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<RGBValue<Int32> > Int32RGBImage;
+
+
+    /** Floating-point (3x float) RGB image.
+        The pixel type is \ref vigra::RGBValue "vigra::RGBValue<float>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<RGBValue<float> > FRGBImage;
+
+
+    /** Double-precision floating-point (3x double) RGB image.
+        The pixel type is \ref vigra::RGBValue "vigra::RGBValue<double>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<RGBValue<double> > DRGBImage;
+
+    /** Floating-point TinyVector image.
+        The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float, 2>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<TinyVector<float, 2> > FVector2Image; 
+
+    /** Floating-point TinyVector image.
+        The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float, 3>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<TinyVector<float, 3> > FVector3Image; 
+
+    /** Floating-point TinyVector image.
+        The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float, 4>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<TinyVector<float, 4> > FVector4Image; 
+
+    /** Floating-point TinyVector image.
+        The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double, 2>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<TinyVector<double, 2> > DVector2Image; 
+
+    /** Floating-point TinyVector image.
+        The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double, 3>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+//typedef BasicImage<TinyVector<double, 3> > DVector3Image; 
+typedef BasicImage<TinyVector<double, 3> > DVector3Image; 
+
+    /** Floating-point TinyVector image.
+        The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double, 4>".
+        It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccessor and 
+        their const counterparts to access the data.
+        
+        <b>\#include</b> \<vigra/stdimage.hxx\><br>
+        Namespace: vigra
+    */
+typedef BasicImage<TinyVector<double, 4> > DVector4Image; 
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_STDIMAGE_HXX
diff --git a/include/vigra/stdimagefunctions.hxx b/include/vigra/stdimagefunctions.hxx
new file mode 100644
index 0000000..8471c51
--- /dev/null
+++ b/include/vigra/stdimagefunctions.hxx
@@ -0,0 +1,76 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+ 
+#ifndef VIGRA_STDIMAGEFUNCTIONS_HXX
+#define VIGRA_STDIMAGEFUNCTIONS_HXX
+
+/** \page PointOperators Point Operators 
+
+    <UL style="list-style-image:url(documents/bullet.gif)">
+    <LI> \ref InitAlgo
+         <BR>    <em>init images or image borders </em>
+    <LI> \ref InspectAlgo
+         <BR>    <em>Apply read-only functor to every pixel</em>
+    <LI> \ref InspectFunctor
+         <BR>    <em>Functors which report image statistics</em>
+    <LI> \ref CopyAlgo
+         <BR>    <em>Copy images or regions</em>
+    <LI> \ref TransformAlgo
+         <BR>    <em>apply functor to calculate a pixelwise transformation of one image</em>
+    <LI> \ref TransformFunctor
+         <BR>    <em>frequently used unary transformation functors</em>
+    <LI> \ref CombineAlgo
+         <BR>    <em>apply functor to calculate a pixelwise transformation from several image</em>
+    <LI> \ref CombineFunctor
+         <BR>    <em>frequently used binary transformations functors</em>
+    <LI> \ref MultiPointoperators
+         <BR>    <em>Point operators on multi-dimensional arrays</em>
+    </UL>
+    
+    <b>\#include</b> \<vigra/stdimagefunctions.hxx\><br>
+    Namespace: vigra
+        
+    see also: \ref FunctorExpressions "Automatic Functor Creation"
+*/
+
+#include "initimage.hxx"
+#include "inspectimage.hxx"
+#include "copyimage.hxx"
+#include "transformimage.hxx"
+#include "combineimages.hxx"
+#include "resizeimage.hxx"
+
+#endif // VIGRA_STDIMAGEFUNCTIONS_HXX
diff --git a/include/vigra/symmetry.hxx b/include/vigra/symmetry.hxx
new file mode 100644
index 0000000..62a4708
--- /dev/null
+++ b/include/vigra/symmetry.hxx
@@ -0,0 +1,312 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_SYMMETRY_HXX
+#define VIGRA_SYMMETRY_HXX
+
+#include "utilities.hxx"
+#include "numerictraits.hxx"
+#include "stdimage.hxx"
+#include "convolution.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup SymmetryDetection Symmetry Detection
+    Measure the local symmetry at each pixel.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                 radialSymmetryTransform              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Find centers of radial symmetry in an image.
+
+    This algorithm implements the Fast Radial Symmetry Transform according to
+    [G. Loy, A. Zelinsky: <em> "A Fast Radial Symmetry Transform for Detecting
+    Points of Interest"</em>, in: A. Heyden et al. (Eds.): Proc. of 7th European
+    Conf. on Computer Vision, Part 1, pp. 358-368, Springer LNCS 2350, 2002].
+    Minima of the algorithm response mark dark blobs, maxima correspond to light blobs.
+    The "radial strictness parameter" is fixed at <TT>alpha</tt> = 2.0, the
+    spatial spreading of the raw response is done by a Gaussian convolution
+    at <tt>0.25*scale</TT> (these values are recommendations from the paper).
+    Loy and Zelinsky additionally propose to add the operator response from several
+    scales (see usage example below).
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        radialSymmetryTransform(MultiArrayView<2, T1, S1> const & src,
+                                MultiArrayView<2, T2, S2> dest,
+                                double scale);
+    }
+    \endcode
+
+    \deprecatedAPI{radialSymmetryTransform}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void
+        radialSymmetryTransform(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+                                DestIterator dul, DestAccessor ad,
+                                double scale)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        inline
+        void radialSymmetryTransform(
+               triple<SrcIterator, SrcIterator, SrcAccessor> src,
+               pair<DestIterator, DestAccessor> dest,
+               double scale)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/symmetry.hxx\><br>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, unsigned char>  src(w,h), centers(w,h);
+    MultiArray<2, float>          symmetry(w,h);
+
+    // use edge detection filters at various scales
+    for(double scale = 2.0; scale <= 8.0; scale *= 2.0)
+    {
+        MultiArray<2, float> tmp(w,h);
+
+        // find centers of symmetry
+        radialSymmetryTransform(src, tmp, scale);
+
+        symmetry += tmp;
+    }
+
+    // mark centers of symmetry
+    centers.init(128);
+    localMinima(symmetry, centers, 0);
+    localMaxima(symmetry, centers, 255);
+    \endcode
+
+    \deprecatedUsage{radialSymmetryTransform}
+    \code
+    vigra::BImage src(w,h), centers(w,h);
+    vigra::FImage symmetry(w,h);
+
+    // empty result image
+    centers.init(128);
+    symmetry.init(0.0);
+
+    // input width of edge detection filter
+    for(double scale = 2.0; scale <= 8.0; scale *= 2.0)
+    {
+        vigra::FImage tmp(w,h);
+
+        // find centers of symmetry
+        radialSymmetryTransform(srcImageRange(src), destImage(tmp), scale);
+
+        combineTwoImages(srcImageRange(symmetry), srcImage(tmp), destImage(symmetry),
+                         std::plus<float>());
+    }
+
+    localMinima(srcImageRange(symmetry), destImage(centers), 0);
+    localMaxima(srcImageRange(symmetry), destImage(centers), 255);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    // SrcAccessor::value_type must be a built-in type
+    SrcAccessor::value_type u = src_accessor(src_upperleft);
+
+    dest_accessor.set(u, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void radialSymmetryTransform)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void
+radialSymmetryTransform(SrcIterator sul, SrcIterator slr, SrcAccessor as,
+               DestIterator dul, DestAccessor ad,
+        double scale)
+{
+    vigra_precondition(scale > 0.0,
+                 "radialSymmetryTransform(): Scale must be > 0");
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    if(w <= 0 || h <= 0) return;
+
+    typedef typename
+        NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+
+    typedef BasicImage<TmpType> TmpImage;
+    typedef typename TmpImage::Iterator TmpIterator;
+
+    TmpImage gx(w,h);
+    TmpImage gy(w,h);
+    IImage   orientationCounter(w,h);
+    TmpImage magnitudeAccumulator(w,h);
+
+    gaussianGradient(srcIterRange(sul, slr, as),
+                     destImage(gx), destImage(gy),
+                     scale);
+
+    orientationCounter.init(0);
+    magnitudeAccumulator.init(NumericTraits<TmpType>::zero());
+
+    TmpIterator gxi = gx.upperLeft();
+    TmpIterator gyi = gy.upperLeft();
+    int y;
+    for(y=0; y<h; ++y, ++gxi.y, ++gyi.y)
+    {
+        typename TmpIterator::row_iterator gxr = gxi.rowIterator();
+        typename TmpIterator::row_iterator gyr = gyi.rowIterator();
+
+        for(int x = 0; x<w; ++x, ++gxr, ++gyr)
+        {
+            double angle = VIGRA_CSTD::atan2(-*gyr, *gxr);
+            double magnitude = VIGRA_CSTD::sqrt(*gxr * *gxr + *gyr * *gyr);
+
+            if(magnitude < NumericTraits<TmpType>::epsilon()*10.0)
+                continue;
+
+            int dx = NumericTraits<int>::fromRealPromote(scale * VIGRA_CSTD::cos(angle));
+            int dy = NumericTraits<int>::fromRealPromote(scale * VIGRA_CSTD::sin(angle));
+
+            int xx = x + dx;
+            int yy = y - dy;
+
+            if(xx >= 0 && xx < w && yy >= 0 && yy < h)
+            {
+                orientationCounter(xx, yy) += 1;
+                magnitudeAccumulator(xx, yy) += detail::RequiresExplicitCast<TmpType>::cast(magnitude);
+            }
+
+            xx = x - dx;
+            yy = y + dy;
+
+            if(xx >= 0 && xx < w && yy >= 0 && yy < h)
+            {
+                orientationCounter(xx, yy) -= 1;
+                magnitudeAccumulator(xx, yy) -= detail::RequiresExplicitCast<TmpType>::cast(magnitude);
+            }
+        }
+    }
+
+    int maxOrientation = 0;
+    TmpType maxMagnitude = NumericTraits<TmpType>::zero();
+
+    for(y=0; y<h; ++y)
+    {
+        for(int x = 0; x<w; ++x)
+        {
+            int o = VIGRA_CSTD::abs(orientationCounter(x,y));
+
+            if(o > maxOrientation)
+                maxOrientation = o;
+
+            TmpType m = VIGRA_CSTD::abs(magnitudeAccumulator(x,y));
+
+            if(m > maxMagnitude)
+                maxMagnitude = m;
+        }
+    }
+
+    for(y=0; y<h; ++y)
+    {
+        for(int x = 0; x<w; ++x)
+        {
+            double o = (double)orientationCounter(x, y) / maxOrientation;
+            magnitudeAccumulator(x, y) = detail::RequiresExplicitCast<TmpType>::cast(o * o * magnitudeAccumulator(x, y) / maxMagnitude);
+        }
+    }
+
+    gaussianSmoothing(srcImageRange(magnitudeAccumulator), destIter(dul, ad), 0.25*scale);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+radialSymmetryTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        pair<DestIterator, DestAccessor> dest,
+                        double scale)
+{
+    radialSymmetryTransform(src.first, src.second, src.third,
+                            dest.first, dest.second,
+                            scale);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+radialSymmetryTransform(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, T2, S2> dest,
+                        double scale)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "radialSymmetryTransform(): shape mismatch between input and output.");
+    radialSymmetryTransform(srcImageRange(src),
+                            destImage(dest),
+                            scale);
+}
+
+//@}
+
+} // namespace vigra
+
+
+#endif /* VIGRA_SYMMETRY_HXX */
diff --git a/include/vigra/tensorutilities.hxx b/include/vigra/tensorutilities.hxx
new file mode 100644
index 0000000..8489d1a
--- /dev/null
+++ b/include/vigra/tensorutilities.hxx
@@ -0,0 +1,616 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_TENSORUTILITIES_HXX
+#define VIGRA_TENSORUTILITIES_HXX
+
+#include <cmath>
+#include "utilities.hxx"
+#include "mathutil.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup TensorImaging Tensor Image Processing
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                      vectorToTensor                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the tensor (outer) product of a 2D vector with itself.
+
+    This function is useful to transform vector images into a tensor representation 
+    that can be used as input to tensor based processing and analysis functions
+    (e.g. tensor smoothing). The input pixel type must be vectors of length 2, whereas
+    the output must contain vectors of length 3 which will represent the tensor components
+    in the order t11, t12 (== t21 due to symmetry), t22.
+    
+    <b>Note:</b> In order to account for the left-handedness of the image coordinate system,
+    the second tensor component (t12) can be negated by setting <tt>negateComponent2 = false</tt>.
+    Angles will then be interpreted counter-clockwise rather than clockwise. By default,
+    this behavior is switched off.
+    
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        vectorToTensor(MultiArrayView<2, T1, S1> const & src,
+                       MultiArrayView<2, T2, S2> dest,
+                       bool negateComponent2 = false);
+    }
+    \endcode
+
+    \deprecatedAPI{vectorToTensor}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void vectorToTensor(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                            DestIterator dul, DestAccessor dest,
+                            bool negateComponent2 = false);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void vectorToTensor(triple<SrcIterator, SrcIterator, SrcAccessor> s,
+                            pair<DestIterator, DestAccessor> d,
+                            bool negateComponent2 = false);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/tensorutilities.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float>                  img(w,h);
+    MultiArray<2, TinyVector<float, 2> >  gradient(w,h);
+    MultiArray<2, TinyVector<float, 3> >  tensor(w,h);
+    ...
+    
+    gaussianGradient(img, gradient, 2.0);
+    vectorToTensor(gradient, tensor);
+    \endcode
+
+    \deprecatedUsage{vectorToTensor}
+    \code
+    FImage img(w,h);
+    FVector2Image gradient(w,h);
+    FVector3Image tensor(w,h);
+    
+    gaussianGradient(srcImageRange(img), destImage(gradient), 2.0);
+    vectorToTensor(srcImageRange(gradient), destImage(tensor));
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void vectorToTensor)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void vectorToTensor(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                    DestIterator dul, DestAccessor dest,
+                    bool negateComponent2)
+{
+    vigra_precondition(src.size(sul) == 2,
+                       "vectorToTensor(): input image must have 2 bands.");
+    vigra_precondition(dest.size(dul) == 3,
+                       "vectorToTensor(): output image must have 3 bands.");
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    for(int y=0; y<h; ++y, ++sul.y, ++dul.y)
+    {
+        typename SrcIterator::row_iterator s = sul.rowIterator();
+        typename SrcIterator::row_iterator send = s + w;
+        typename DestIterator::row_iterator d = dul.rowIterator();
+        if(negateComponent2)
+        {
+            for(; s < send; ++s, ++d)
+            {
+                dest.setComponent(sq(src.getComponent(s, 0)), d, 0);
+                dest.setComponent(-src.getComponent(s, 0)*src.getComponent(s, 1), d, 1);
+                               // ^ negative sign to turn left-handed into right-handed coordinates
+                dest.setComponent(sq(src.getComponent(s, 1)), d, 2);
+            }
+        }
+        else
+        {
+            for(; s < send; ++s, ++d)
+            {
+                dest.setComponent(sq(src.getComponent(s, 0)), d, 0);
+                dest.setComponent(src.getComponent(s, 0)*src.getComponent(s, 1), d, 1);
+                dest.setComponent(sq(src.getComponent(s, 1)), d, 2);
+            }
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline
+void vectorToTensor(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                    DestIterator dul, DestAccessor dest)
+{
+    vectorToTensor(sul, slr, src, dul, dest, false);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+vectorToTensor(triple<SrcIterator, SrcIterator, SrcAccessor> s,
+               pair<DestIterator, DestAccessor> d,
+               bool negateComponent2)
+{
+    vectorToTensor(s.first, s.second, s.third, d.first, d.second, negateComponent2);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+vectorToTensor(triple<SrcIterator, SrcIterator, SrcAccessor> s,
+               pair<DestIterator, DestAccessor> d)
+{
+    vectorToTensor(s.first, s.second, s.third, d.first, d.second, false);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+vectorToTensor(MultiArrayView<2, T1, S1> const & src,
+               MultiArrayView<2, T2, S2> dest,
+               bool negateComponent2 = false)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "vectorToTensor(): shape mismatch between input and output.");
+    vectorToTensor(srcImageRange(src), destImage(dest), negateComponent2);
+}
+
+/********************************************************/
+/*                                                      */
+/*               tensorEigenRepresentation              */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate eigen representation of a symmetric 2x2 tensor.
+
+    This function turns a 3-band image representing the tensor components
+    t11, t12 (== t21 due to symmetry), t22 into the a 3-band image holding the eigen
+    representation e1, e2, and angle, where e1 \> e2. When the tensor is
+    defined in a left-handed coordinate system (the default on images), the angle will
+    then be given in clockwise orientation, starting at the x-axis. Otherwise, it
+    will be given in counter-clockwise orientation.
+    
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        tensorEigenRepresentation(MultiArrayView<2, T1, S1> const & src,
+                                  MultiArrayView<2, T2, S2> dest);
+    }
+    \endcode
+
+    \deprecatedAPI{tensorEigenRepresentation}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void tensorEigenRepresentation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                       DestIterator dul, DestAccessor dest);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void tensorEigenRepresentation(triple<SrcIterator, SrcIterator, SrcAccessor> s,
+                                       pair<DestIterator, DestAccessor> d);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/tensorutilities.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, TinyVector<float, 3> >  tensor(w,h),
+                                          eigen(w,h);
+    
+    tensorEigenRepresentation(tensor, eigen);
+    \endcode
+
+    \deprecatedUsage{tensorEigenRepresentation}
+    \code
+    FVector3Image tensor(w,h);
+    FVector3Image eigen(w,h);
+    
+    tensorEigenRepresentation(srcImageRange(tensor), destImage(eigen));
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void tensorEigenRepresentation)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void tensorEigenRepresentation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                               DestIterator dul, DestAccessor dest)
+{
+    vigra_precondition(src.size(sul) == 3,
+                       "tensorEigenRepresentation(): input image must have 3 bands.");
+    vigra_precondition(dest.size(dul) == 3,
+                       "tensorEigenRepresentation(): output image must have 3 bands.");
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    for(int y=0; y<h; ++y, ++sul.y, ++dul.y)
+    {
+        typename SrcIterator::row_iterator s = sul.rowIterator();
+        typename SrcIterator::row_iterator send = s + w;
+        typename DestIterator::row_iterator d = dul.rowIterator();
+        for(; s < send; ++s, ++d)
+        {
+            typedef typename 
+               NumericTraits<typename SrcAccessor::component_type>::RealPromote TmpType;
+            TmpType d1 = src.getComponent(s,0) + src.getComponent(s,2);
+            TmpType d2 = src.getComponent(s,0) - src.getComponent(s,2);
+            TmpType d3 = TmpType(2.0) * src.getComponent(s,1);
+            TmpType d4 = (TmpType)hypot(d2, d3);
+            
+            dest.setComponent(0.5 * (d1 + d4), d, 0); // large EV
+            dest.setComponent(0.5 * (d1 - d4), d, 1); // small EV
+            if(d2==0.0 && d3==0.0)
+            {
+                dest.setComponent(0, d, 2); // orientation
+            }
+            else
+            {
+                dest.setComponent(0.5 * VIGRA_CSTD::atan2(d3, d2), d, 2); // orientation
+            }
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+tensorEigenRepresentation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                          pair<DestIterator, DestAccessor> dest)
+{
+    tensorEigenRepresentation(src.first, src.second, src.third, dest.first, dest.second);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+tensorEigenRepresentation(MultiArrayView<2, T1, S1> const & src,
+                          MultiArrayView<2, T2, S2> dest)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "tensorEigenRepresentation(): shape mismatch between input and output.");
+    tensorEigenRepresentation(srcImageRange(src), destImage(dest));
+}
+
+/********************************************************/
+/*                                                      */
+/*                      tensorTrace                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate the trace of a 2x2 tensor.
+
+    This function turns a 3-band image representing the tensor components
+    t11, t12 (== t21 due to symmetry), t22 into the a 1-band image holding the 
+    tensor trace t11 + t22.
+    
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2>
+        void
+        tensorTrace(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest);
+    }
+    \endcode
+
+    \deprecatedAPI{tensorTrace}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void tensorTrace(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                         DestIterator dul, DestAccessor dest);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        void tensorTrace(triple<SrcIterator, SrcIterator, SrcAccessor> s,
+                         pair<DestIterator, DestAccessor> d);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/tensorutilities.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, TinyVector<float, 3> >  tensor(w,h);
+    MultiArray<2, float>                  trace(w,h);
+    
+    tensorTrace(tensor, trace);
+    \endcode
+
+    \deprecatedUsage{tensorTrace}
+    \code
+    FVector3Image tensor(w,h);
+    FImage trace(w,h);
+    
+    tensorTrace(srcImageRange(tensor), destImage(trace));
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void tensorTrace)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void tensorTrace(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                 DestIterator dul, DestAccessor dest)
+{
+    vigra_precondition(src.size(sul) == 3,
+                       "tensorTrace(): input image must have 3 bands.");
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    for(int y=0; y<h; ++y, ++sul.y, ++dul.y)
+    {
+        typename SrcIterator::row_iterator s = sul.rowIterator();
+        typename SrcIterator::row_iterator send = s + w;
+        typename DestIterator::row_iterator d = dul.rowIterator();
+        for(; s < send; ++s, ++d)
+        {
+            dest.set(src.getComponent(s,0) + src.getComponent(s,2), d);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline void
+tensorTrace(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+            pair<DestIterator, DestAccessor> dest)
+{
+    tensorTrace(src.first, src.second, src.third, dest.first, dest.second);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline void
+tensorTrace(MultiArrayView<2, T1, S1> const & src,
+            MultiArrayView<2, T2, S2> dest)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "tensorTrace(): shape mismatch between input and output.");
+    tensorTrace(srcImageRange(src), destImage(dest));
+}
+
+/********************************************************/
+/*                                                      */
+/*                  tensorToEdgeCorner                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Decompose a symmetric 2x2 tensor into its edge and corner parts.
+
+    This function turns a 3-band image representing the tensor components
+    t11, t12 (== t21 due to symmetry), t22 into the a 2-band image holding 
+    the tensor's edgeness (difference of the tensor's 
+    eigenvalues) and orientation, and a 1-band image representing its corner part 
+    (equal to the twice the small eigen value). The original tensor must be 
+    positive definite and defined in a right-handed coordinate system (e.g.
+    the tensor resulting from \ref boundaryTensor()).
+    
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T21, class S21,
+                  class T22, class S22>
+        void
+        tensorToEdgeCorner(MultiArrayView<2, T1, S1> const & src,
+                           MultiArrayView<2, T21, S21> edge,
+                           MultiArrayView<2, T22, S22> corner);
+    }
+    \endcode
+
+    \deprecatedAPI{tensorToEdgeCorner}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator1, class DestAccessor1,
+                  class DestIterator2, class DestAccessor2>
+        void tensorToEdgeCorner(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                                DestIterator1 edgeul, DestAccessor1 edge,
+                                DestIterator2 cornerul, DestAccessor2 corner);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator1, class DestAccessor1,
+                  class DestIterator2, class DestAccessor2>
+        void tensorToEdgeCorner(triple<SrcIterator, SrcIterator, SrcAccessor> s,
+                                pair<DestIterator1, DestAccessor1> edge,
+                                pair<DestIterator2, DestAccessor2> corner);
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/tensorutilities.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, TinyVector<float, 3> >  tensor(w,h);
+    MultiArray<2, TinyVector<float, 2> >  edgePart(w,h);
+    MultiArray<2, float>                  cornerPart(w,h);
+    ...
+    
+    tensorTrace(tensor, edgePart, cornerPart);
+    \endcode
+
+    \deprecatedUsage{tensorToEdgeCorner}
+    \code
+    FVector3Image tensor(w,h);
+    FVector2Image edgePart(w,h);
+    FImage cornerPart(w,h);
+    
+    tensorTrace(srcImageRange(tensor), destImage(edgePart), destImage(cornerPart));
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void tensorToEdgeCorner)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator1, class DestAccessor1,
+          class DestIterator2, class DestAccessor2>
+void tensorToEdgeCorner(SrcIterator sul, SrcIterator slr, SrcAccessor src,
+                        DestIterator1 edgeul, DestAccessor1 edge,
+                        DestIterator2 cornerul, DestAccessor2 corner)
+{
+    vigra_precondition(src.size(sul) == 3,
+                       "tensorToEdgeCorner(): input image must have 3 bands.");
+    vigra_precondition(edge.size(edgeul) == 2,
+                       "tensorToEdgeCorner(): edge image must have 2 bands.");
+
+    int w = slr.x - sul.x;
+    int h = slr.y - sul.y;
+
+    for(int y=0; y<h; ++y, ++sul.y, ++edgeul.y, ++cornerul.y)
+    {
+        typename SrcIterator::row_iterator s = sul.rowIterator();
+        typename SrcIterator::row_iterator send = s + w;
+        typename DestIterator1::row_iterator e = edgeul.rowIterator();
+        typename DestIterator2::row_iterator c = cornerul.rowIterator();
+        for(; s < send; ++s, ++e, ++c)
+        {
+            typedef typename 
+               NumericTraits<typename SrcAccessor::component_type>::RealPromote TmpType;
+            TmpType d1 = src.getComponent(s,0) + src.getComponent(s,2);
+            TmpType d2 = src.getComponent(s,0) - src.getComponent(s,2);
+            TmpType d3 = 2.0 * src.getComponent(s,1);
+            TmpType d4 = (TmpType)hypot(d2, d3);
+            
+            edge.setComponent(d4, e, 0); // edgeness = difference of EVs
+            if(d2 == 0.0 && d3 == 0.0)
+            {
+                edge.setComponent(0.0, e, 1); // orientation
+            }
+            else
+            {
+                edge.setComponent(0.5 * VIGRA_CSTD::atan2(d3, d2), e, 1); // orientation
+            }
+            corner.set(d1 - d4, c); // cornerness = 2 * small EV
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator1, class DestAccessor1,
+          class DestIterator2, class DestAccessor2>
+inline void
+tensorToEdgeCorner(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                   pair<DestIterator1, DestAccessor1> edge,
+                   pair<DestIterator2, DestAccessor2> corner)
+{
+    tensorToEdgeCorner(src.first, src.second, src.third, 
+                       edge.first, edge.second, corner.first, corner.second);
+}
+
+template <class T1, class S1,
+          class T21, class S21,
+          class T22, class S22>
+inline void
+tensorToEdgeCorner(MultiArrayView<2, T1, S1> const & src,
+                   MultiArrayView<2, T21, S21> edge,
+                   MultiArrayView<2, T22, S22> corner)
+{
+    vigra_precondition(src.shape() == edge.shape(),
+        "tensorToEdgeCorner(): shape mismatch between input and output.");
+    tensorToEdgeCorner(srcImageRange(src), 
+                       destImage(edge), destImage(corner));
+}
+
+//@}
+
+} // namespace vigra
+
+#endif /* VIGRA_TENSORUTILITIES_HXX */
diff --git a/include/vigra/tiff.hxx b/include/vigra/tiff.hxx
new file mode 100644
index 0000000..7399189
--- /dev/null
+++ b/include/vigra/tiff.hxx
@@ -0,0 +1,2028 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+#ifndef VIGRA_TIFF_HXX
+#define VIGRA_TIFF_HXX
+
+#include "utilities.hxx"
+#include "numerictraits.hxx"
+#include "rgbvalue.hxx"
+#include "multi_shape.hxx"
+
+extern "C"
+{
+#include <tiff.h>
+#include <tiffio.h>
+}
+
+namespace vigra {
+
+typedef TIFF TiffImage;
+
+/** \defgroup TIFFImpex Import/export of the TIFF format
+
+    TIFF conversion and file export/import.
+    
+    Normally, you need not call the TIFF functions directly. They are
+    available much more conveniently via \ref importImage() and \ref exportImage() 
+    
+    TIFF (Tagged Image File Format) is a very versatile image format - 
+    one can store different pixel types (byte, integer, float, double) and
+    color models (black and white, RGB, mapped RGB, other color systems). 
+    For more details and information on how to create a TIFF image,
+    refer to the TIFF documentation at 
+    <a href="http://www.libtiff.org/">http://www.libtiff.org/</a> for details.
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                     importTiffImage                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Read a given TIFF image.
+
+    This function calls \ref tiffToScalarImage() or \ref tiffToRGBImage(), depending on 
+    the destinations's value_type. Usually, it is better to use \ref importImage().
+    importTiffImage() should only be used if explicit access to the TIFF object
+    <tt>TiffImage</tt> is required.
+
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S>
+        void
+        importTiffImage(TiffImage * tiff, MultiArrayView<2, T, S> dest);
+    }
+    \endcode
+    
+    \deprecatedAPI{importTiffImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        void
+        importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        void
+        importTiffImage(TiffImage * tiff, pair<ImageIterator, Accessor> dest)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/tiff.hxx\><br/>
+    Namespace: vigra
+    
+    \code
+    uint32 w, h;
+    TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r");
+    TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
+    TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
+    
+    MultiArray<2, unsigned char> img(w,h);
+    
+    importTiffImage(tiff, img);
+    
+    TIFFClose(tiff);
+    \endcode
+    
+    <b> Required Interface:</b>
+    
+    see \ref tiffToScalarImage() and \ref tiffToRGBImage()
+    
+    <b> Preconditions:</b>
+    
+    see \ref tiffToScalarImage() and \ref tiffToRGBImage()
+    
+*/
+doxygen_overloaded_function(template <...> void importTiffImage)
+
+template <class ImageIterator, class Accessor>
+inline void
+importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a)
+{
+    typedef typename 
+        NumericTraits<typename Accessor::value_type>::isScalar
+        isScalar;
+    importTiffImage(tiff, iter, a, isScalar());
+}
+
+template <class ImageIterator, class Accessor>
+inline void
+importTiffImage(TiffImage * tiff, pair<ImageIterator, Accessor> dest)
+{
+    importTiffImage(tiff, dest.first, dest.second);
+}
+
+template <class T, class S>
+inline void
+importTiffImage(TiffImage * tiff, MultiArrayView<2, T, S> dest)
+{
+    importTiffImage(tiff, destImage(dest));
+}
+
+template <class ImageIterator, class Accessor>
+inline void
+importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a, VigraTrueType)
+{
+    tiffToScalarImage(tiff, iter, a);
+}
+
+template <class ImageIterator, class Accessor>
+inline void
+importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a, VigraFalseType)
+{
+    tiffToRGBImage(tiff, iter, a);
+}
+
+/********************************************************/
+/*                                                      */
+/*                    tiffToScalarImage                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Convert single-band TiffImage to scalar image.
+
+    Note that unexpected results can occur when the destination pixel type is weaker than the pixel type
+    in the file (e.g. when a <tt>float</tt> file is imported into a <tt>unsigned char</tt> image).
+
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        void
+        tiffToScalarImage(TiffImage * tiff, ImageIterator iter, Accessor a)
+    }
+    \endcode
+    
+    \deprecatedAPI{tiffToScalarImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        void
+        tiffToScalarImage(TiffImage * tiff, ImageIterator iter, Accessor a)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        void
+        tiffToScalarImage(TiffImage * tiff, pair<ImageIterator, Accessor> dest)
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/tiff.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    uint32 w, h;
+    uint16 photometric;
+    TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r");
+    TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
+    TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
+    TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometric);
+        
+    if(photometric != PHOTOMETRIC_MINISWHITE &&
+       photometric != PHOTOMETRIC_MINISBLACK)
+    {
+        // not a scalar image - handle error
+    }
+    
+    MultiArray<2, unsigned char> img(w,h);
+    
+    tiffToScalarImage(tiff, img);
+    
+    TIFFClose(tiff);
+    \endcode
+
+    \deprecatedUsage{tiffToScalarImage}
+    \code
+    uint32 w, h;
+    uint16 photometric;
+    
+    TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r");
+    TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
+    TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
+    TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometric);
+        
+    if(photometric != PHOTOMETRIC_MINISWHITE &&
+       photometric != PHOTOMETRIC_MINISBLACK)
+    {
+        // not a scalar image - handle error
+    }
+    
+    vigra::BImage img(w,h);
+    
+    vigra::tiffToScalarImage(tiff, destImage(img));
+    
+    TIFFClose(tiff);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator upperleft;
+    <unsigned char, short, long, float, double> value;
+    
+    Accessor accessor;
+               
+    accessor.set(value, upperleft);
+    \endcode
+    \deprecatedEnd
+    
+    <b> Preconditions:</b>
+    
+    The output array must have the correct shape.
+    
+    \code
+    uint16 sampleFormat, samplesPerPixel, bitsPerSample, photometric;
+           
+    TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat);
+    TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel);
+    TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
+    TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
+
+    sampleFormat != SAMPLEFORMAT_VOID
+    samplesPerPixel == 1
+    photometric == PHOTOMETRIC_MINISWHITE || photometric == PHOTOMETRIC_MINISBLACK
+    bitsPerSample == 1 || 
+       bitsPerSample == 8 || 
+       bitsPerSample == 16 || 
+       bitsPerSample == 32 || 
+       bitsPerSample == 64
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void tiffToScalarImage)
+
+template <class ImageIterator, class Accessor>
+void
+tiffToScalarImage(TiffImage * tiff, ImageIterator iter, Accessor a)
+{
+    vigra_precondition(tiff != 0, 
+             "tiffToScalarImage(TiffImage *, ScalarImageIterator): " 
+             "NULL pointer to input data.");
+    
+    uint16 sampleFormat = 1, bitsPerSample, 
+           fillorder, samplesPerPixel, photometric;
+    uint32 w,h;
+    
+    TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat);
+    TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
+    TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel);
+    TIFFGetField(tiff, TIFFTAG_FILLORDER, &fillorder);
+    TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
+    TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
+    TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
+    
+    vigra_precondition(photometric == PHOTOMETRIC_MINISWHITE ||
+                 photometric == PHOTOMETRIC_MINISBLACK, 
+             "tiffToScalarImage(TiffImage *, ScalarImageIterator): " 
+             "Image isn't grayscale.");
+    
+    vigra_precondition(samplesPerPixel == 1, 
+             "tiffToScalarImage(TiffImage *, ScalarImageIterator): " 
+             "Image is multiband, not scalar.");
+    
+    vigra_precondition(sampleFormat != SAMPLEFORMAT_VOID,
+             "tiffToScalarImage(TiffImage *, ScalarImageIterator): " 
+             "undefined pixeltype (SAMPLEFORMAT_VOID).");
+
+    ImageIterator yd(iter);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    int offset, scale, max, min;
+    if(photometric == PHOTOMETRIC_MINISWHITE)
+    {
+        min = 255;
+        max = 0;
+        scale = -1;
+        offset = 255;
+    }
+    else
+    {
+        scale = 1;
+        offset = 0;
+        min = 0;
+        max = 255;
+    }
+    
+    try{
+        switch(sampleFormat)
+        {
+          case SAMPLEFORMAT_UINT:
+          {
+            switch (bitsPerSample)
+            {
+              case 1:
+              {
+                for(unsigned int y=0; y<h; ++y, ++yd.y)
+                {
+                    TIFFReadScanline(tiff, buf, y);
+                    ImageIterator xd(yd);
+
+                    for(unsigned int x=0; x<w; ++x, ++xd.x)
+                    {
+                        if(fillorder == FILLORDER_MSB2LSB)
+                        {
+                            a.set(((((uint8 *)buf)[x/8] >> (7 - x%8)) & 1) ? max : min, xd);
+                        }
+                        else
+                        {
+                            a.set(((((uint8 *)buf)[x/8] >> (x%8)) & 1) ? max : min, xd);
+                        }
+                    }
+                }
+                break;
+              }
+              case 8:
+              {
+                for(unsigned int y=0; y<h; ++y, ++yd.y)
+                {
+                    TIFFReadScanline(tiff, buf, y);
+                    ImageIterator xd(yd);
+
+                    for(unsigned int x=0; x<w; ++x, ++xd.x)
+                    {
+                        a.set(offset + scale*((uint8 *)buf)[x], xd);
+                    }
+                }
+                break;
+              }
+              case 16:
+              {
+                for(unsigned int y=0; y<h; ++y, ++yd.y)
+                {
+                    TIFFReadScanline(tiff, buf, y);
+                    ImageIterator xd(yd);
+
+                    for(unsigned int x=0; x<w; ++x, ++xd.x)
+                    {
+                        a.set(((uint16 *)buf)[x], xd);
+                    }
+                }
+                break;
+              }
+              case 32:
+              {
+                for(unsigned int y=0; y<h; ++y, ++yd.y)
+                {
+                    TIFFReadScanline(tiff, buf, y);
+                    ImageIterator xd(yd);
+
+                    for(unsigned int x=0; x<w; ++x, ++xd.x)
+                    {
+                        a.set(((uint32 *)buf)[x], xd);
+                    }
+                }
+                break;
+              }
+              default:
+                vigra_fail("tiffToScalarImage(TiffImage *, ScalarImageIterator): "
+                     "unsupported number of bits per pixel");
+            }
+            break;
+          }
+          case SAMPLEFORMAT_INT:
+          {
+            switch (bitsPerSample)
+            {
+              case 1:
+              {
+                for(unsigned int y=0; y<h; ++y, ++yd.y)
+                {
+                    TIFFReadScanline(tiff, buf, y);
+                    ImageIterator xd(yd);
+
+                    for(unsigned int x=0; x<w; ++x, ++xd.x)
+                    {
+                        if(fillorder == FILLORDER_MSB2LSB)
+                        {
+                            a.set(((((int8 *)buf)[x/8] >> (7 - x%8)) & 1) ? max : min, xd);
+                        }
+                        else
+                        {
+                            a.set(((((int8 *)buf)[x/8] >> (x%8)) & 1) ? max : min, xd);
+                        }
+                    }
+                }
+                break;
+              }
+              case 8:
+              {
+                for(unsigned int y=0; y<h; ++y, ++yd.y)
+                {
+                    TIFFReadScanline(tiff, buf, y);
+                    ImageIterator xd(yd);
+
+                    for(unsigned int x=0; x<w; ++x, ++xd.x)
+                    {
+                        a.set(offset + scale*((uint8 *)buf)[x], xd);
+                    }
+                }
+                break;
+              }
+              case 16:
+              {
+                for(unsigned int y=0; y<h; ++y, ++yd.y)
+                {
+                    TIFFReadScanline(tiff, buf, y);
+                    ImageIterator xd(yd);
+
+                    for(unsigned int x=0; x<w; ++x, ++xd.x)
+                    {
+                        a.set(((int16 *)buf)[x], xd);
+                    }
+                }
+                break;
+              }
+              case 32:
+              {
+                for(unsigned int y=0; y<h; ++y, ++yd.y)
+                {
+                    TIFFReadScanline(tiff, buf, y);
+                    ImageIterator xd(yd);
+
+                    for(unsigned int x=0; x<w; ++x, ++xd.x)
+                    {
+                        a.set(((int32 *)buf)[x], xd);
+                    }
+                }
+                break;
+              }
+              default:
+                vigra_fail("tiffToScalarImage(TiffImage *, ScalarImageIterator): "
+                     "unsupported number of bits per pixel");
+            }
+            break;
+          }
+          case SAMPLEFORMAT_IEEEFP:
+          {
+            switch (bitsPerSample)
+            {
+              case sizeof(float)*8:
+              {
+                for(unsigned int y=0; y<h; ++y, ++yd.y)
+                {
+                    TIFFReadScanline(tiff, buf, y);
+                    ImageIterator xd(yd);
+
+                    for(unsigned int x=0; x<w; ++x, ++xd.x)
+                    {
+                        a.set(((float *)buf)[x], xd);
+                    }
+                }
+                break;
+              }
+              case sizeof(double)*8:
+              {
+                for(unsigned int y=0; y<h; ++y, ++yd.y)
+                {
+                    TIFFReadScanline(tiff, buf, y);
+                    ImageIterator xd(yd);
+
+                    for(unsigned int x=0; x<w; ++x, ++xd.x)
+                    {
+                        a.set(((double *)buf)[x], xd);
+                    }
+                }
+                break;
+              }
+              default:
+                vigra_fail("tiffToScalarImage(TiffImage *, ScalarImageIterator): "
+                     "unsupported number of bits per pixel");
+            }
+            break;
+          }
+          default:
+          {
+            // should never happen
+            vigra_fail("tiffToScalarImage(TiffImage *, ScalarImageIterator): " 
+                 "internal error.");
+          }
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <class ImageIterator, class Accessor>
+void
+tiffToScalarImage(TiffImage * tiff, pair<ImageIterator, Accessor> dest)
+{
+    tiffToScalarImage(tiff, dest.first, dest.second);
+}
+
+/********************************************************/
+/*                                                      */
+/*                      tiffToRGBImage                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Import a RGB (3-band or color-mapped) TiffImage 
+    into a RGB image.
+
+    Note that unexpected results can occur when the destination pixel type is weaker than the pixel type
+    in the file (e.g. when a <tt>float</tt> file is imported into a <tt>unsigned char</tt> image).
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class RGBImageIterator, class RGBAccessor>
+        void
+        tiffToRGBImage(TiffImage * tiff, RGBImageIterator iter, RGBAccessor a)
+    }
+    \endcode
+    
+    \deprecatedAPI{tiffToRGBImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class RGBImageIterator, class RGBAccessor>
+        void
+        tiffToRGBImage(TiffImage * tiff, RGBImageIterator iter, RGBAccessor a)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class RGBImageIterator, class RGBAccessor>
+        void
+        tiffToRGBImage(TiffImage * tiff, pair<RGBImageIterator, RGBAccessor> dest)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/tiff.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    uint32 w, h;
+    uint16 photometric
+    TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r");
+    TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
+    TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
+    TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometric);
+        
+    if(photometric != PHOTOMETRIC_RGB &&
+       photometric != PHOTOMETRIC_PALETTE)
+    {
+        // not an RGB image - handle error
+    }
+    
+    MultiArray<2, RGBValue<unsigned char> > img(w, h);
+    
+    tiffToRGBImage(tiff, img);
+    
+    TIFFClose(tiff);
+    \endcode
+
+    \deprecatedUsage{tiffToRGBImage}
+    \code
+    uint32 w, h;
+    uint16 photometric
+    TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r");
+    TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
+    TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
+    TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometric);
+        
+    if(photometric != PHOTOMETRIC_RGB &&
+       photometric != PHOTOMETRIC_PALETTE)
+    {
+        // not an RGB image - handle error
+    }
+    
+    vigra::BRGBImage img(w, h);
+    
+    vigra::tiffToRGBImage(tiff, destImage(img));
+    
+    TIFFClose(tiff);
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator upperleft;
+    <unsigned char, short, long, float, double> rvalue, gvalue, bvalue;
+    
+    RGBAccessor accessor;
+                           
+    accessor.setRed(rvalue, upperleft);
+    accessor.setGreen(gvalue, upperleft);
+    accessor.setBlue(bvalue, upperleft);
+    \endcode
+    \deprecatedEnd
+    
+    <b> Preconditions:</b>
+    
+    The destination image must have the appropriate size.
+    
+    \code
+    uint16 sampleFormat, samplesPerPixel, bitsPerSample, photometric;
+           
+    TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat);
+    TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel);
+    TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
+    TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
+
+    sampleFormat != SAMPLEFORMAT_VOID
+    samplesPerPixel == 3 // unless photometric == PHOTOMETRIC_PALETTE
+    photometric == PHOTOMETRIC_RGB ||
+       photometric == PHOTOMETRIC_PALETTE
+    bitsPerSample == 1 || 
+       bitsPerSample == 8 || 
+       bitsPerSample == 16 || 
+       bitsPerSample == 32 || 
+       bitsPerSample == 64
+    \endcode
+*/
+doxygen_overloaded_function(template <...> void tiffToRGBImage)
+
+template <class RGBImageIterator, class RGBAccessor>
+void
+tiffToRGBImage(TiffImage * tiff, RGBImageIterator iter, RGBAccessor a)
+{
+    vigra_precondition(tiff != 0,
+              "tiffToRGBImage(TiffImage *, RGBImageIterator): " 
+          "NULL pointer to input data.");
+    
+    uint16 sampleFormat = 1, bitsPerSample, 
+           samplesPerPixel, planarConfig, photometric;
+    uint32 w,h;
+    
+    TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat);
+    TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
+    TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel);
+    TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
+    TIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planarConfig);
+    TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
+    TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
+    
+    vigra_precondition(photometric == PHOTOMETRIC_RGB ||
+                 photometric == PHOTOMETRIC_PALETTE, 
+             "tiffToRGBImage(TiffImage *, RGBImageIterator): " 
+             "Image isn't RGB.");
+    
+    vigra_precondition(sampleFormat != SAMPLEFORMAT_VOID,
+             "tiffToRGBImage(TiffImage *, RGBImageIterator): " 
+             "undefined pixeltype (SAMPLEFORMAT_VOID).");
+        
+    RGBImageIterator yd(iter);
+    
+    switch (photometric)
+    {
+      case PHOTOMETRIC_PALETTE:
+      {
+        uint32 * raster = new uint32[w*h];
+        try
+        {
+            if (!TIFFReadRGBAImage(tiff, w, h, raster, 0)) 
+            {
+                vigra_fail(
+                  "tiffToRGBImage(TiffImage *, RGBImageIterator): " 
+                  "unable to read image data.");
+            }
+          
+            for(unsigned int y=0; y<h; ++y, ++yd.y)
+            {
+                typename RGBImageIterator::row_iterator rowit = yd.rowIterator();
+                typename RGBImageIterator::row_iterator rowend = rowit + w;
+                for(int x=0; rowit<rowend; ++rowit,++x )
+                {
+                    uint32 rast = raster[x+y*w];
+                    a.setRGB(TIFFGetR(rast),TIFFGetG(rast),TIFFGetB(rast),rowit);
+                }
+            }
+        }
+        catch(...)
+        {
+            delete[] raster;
+            throw;
+        }
+        delete[] raster;
+        break;
+      }
+      case PHOTOMETRIC_RGB:
+      {
+        vigra_precondition(samplesPerPixel == 3,
+                 "tiffToRGBImage(TiffImage *, RGBImageIterator): " 
+                 "number of samples per pixel must be 3.");
+        
+        int bufsize = TIFFScanlineSize(tiff);
+        tdata_t * bufr = new tdata_t[bufsize];
+        tdata_t * bufg = new tdata_t[bufsize];
+        tdata_t * bufb = new tdata_t[bufsize];
+        
+        int offset = (planarConfig == PLANARCONFIG_CONTIG) ? 3 : 1;
+        
+        try
+        {
+            switch(sampleFormat)
+            {
+              case SAMPLEFORMAT_UINT:
+              {
+                switch (bitsPerSample)
+                {
+                  case 8:
+                  {
+                    for(unsigned int y=0; y<h; ++y, ++yd.y)
+                    {
+                        uint8 *pr, *pg, *pb;
+                        
+                        if(planarConfig == PLANARCONFIG_CONTIG)
+                        {
+                            TIFFReadScanline(tiff, bufr, y);
+                            pr = (uint8 *)bufr;
+                            pg = pr+1;
+                            pb = pg+1;
+                        }
+                        else
+                        {
+                            TIFFReadScanline(tiff, bufr, y, 0);
+                            TIFFReadScanline(tiff, bufg, y, 1);
+                            TIFFReadScanline(tiff, bufb, y, 2);
+                            pr = (uint8 *)bufr;
+                            pg = (uint8 *)bufg;
+                            pb = (uint8 *)bufb;
+                        }
+                        
+                        typename RGBImageIterator::row_iterator rowit = yd.rowIterator();
+                        typename RGBImageIterator::row_iterator rowend = rowit + w;
+                        for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset)
+                            a.setRGB(*pr,*pg, *pb, rowit);
+                    }
+                    break;
+                  }
+                  case 16:
+                  {
+                    for(unsigned int y=0; y<h; ++y, ++yd.y)
+                    {
+                        uint16 *pr, *pg, *pb;
+                        
+                        if(planarConfig == PLANARCONFIG_CONTIG)
+                        {
+                            TIFFReadScanline(tiff, bufr, y);
+                            pr = (uint16 *)bufr;
+                            pg = pr+1;
+                            pb = pg+1;
+                        }
+                        else
+                        {
+                            TIFFReadScanline(tiff, bufr, y, 0);
+                            TIFFReadScanline(tiff, bufg, y, 1);
+                            TIFFReadScanline(tiff, bufb, y, 2);
+                            pr = (uint16 *)bufr;
+                            pg = (uint16 *)bufg;
+                            pb = (uint16 *)bufb;
+                        }
+                        
+                        typename RGBImageIterator::row_iterator rowit = yd.rowIterator();
+                        typename RGBImageIterator::row_iterator rowend = rowit + w;
+                        for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset)
+                            a.setRGB(*pr,*pg, *pb, rowit);
+                    }
+                    break;
+                  }
+                  case 32:
+                  {
+                    for(unsigned int y=0; y<h; ++y, ++yd.y)
+                    {
+                        uint32 *pr, *pg, *pb;
+                        
+                        if(planarConfig == PLANARCONFIG_CONTIG)
+                        {
+                            TIFFReadScanline(tiff, bufr, y);
+                            pr = (uint32 *)bufr;
+                            pg = pr+1;
+                            pb = pg+1;
+                        }
+                        else
+                        {
+                            TIFFReadScanline(tiff, bufr, y, 0);
+                            TIFFReadScanline(tiff, bufg, y, 1);
+                            TIFFReadScanline(tiff, bufb, y, 2);
+                            pr = (uint32 *)bufr;
+                            pg = (uint32 *)bufg;
+                            pb = (uint32 *)bufb;
+                        }
+                                                                        
+                        typename RGBImageIterator::row_iterator rowit = yd.rowIterator();
+                        typename RGBImageIterator::row_iterator rowend = rowit + w;
+                        for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset)
+                            a.setRGB(*pr,*pg, *pb, rowit);
+                    }
+                    break;
+                  }
+                  default:
+                  {
+                    vigra_fail("tiffToRGBImage(TiffImage *, RGBImageIterator): "
+                         "unsupported number of bits per pixel");
+                  }
+                }
+                break;
+              }
+              case SAMPLEFORMAT_INT:
+              {
+                switch (bitsPerSample)
+                {
+                  case 8:
+                  {
+                    for(unsigned int y=0; y<h; ++y, ++yd.y)
+                    {
+                        int8 *pr, *pg, *pb;
+                        
+                        if(planarConfig == PLANARCONFIG_CONTIG)
+                        {
+                            TIFFReadScanline(tiff, bufr, y);
+                            pr = (int8 *)bufr;
+                            pg = pr+1;
+                            pb = pg+1;
+                        }
+                        else
+                        {
+                            TIFFReadScanline(tiff, bufr, y, 0);
+                            TIFFReadScanline(tiff, bufg, y, 1);
+                            TIFFReadScanline(tiff, bufb, y, 2);
+                            pr = (int8 *)bufr;
+                            pg = (int8 *)bufg;
+                            pb = (int8 *)bufb;
+                        }
+                        
+                        typename RGBImageIterator::row_iterator rowit = yd.rowIterator();
+                        typename RGBImageIterator::row_iterator rowend = rowit + w;
+                        for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset)
+                            a.setRGB(*pr,*pg, *pb, rowit);
+                    }
+                    break;
+                  }
+                  case 16:
+                  {
+                    for(unsigned int y=0; y<h; ++y, ++yd.y)
+                    {
+                        int16 *pr, *pg, *pb;
+                        
+                        if(planarConfig == PLANARCONFIG_CONTIG)
+                        {
+                            TIFFReadScanline(tiff, bufr, y);
+                            pr = (int16 *)bufr;
+                            pg = pr+1;
+                            pb = pg+1;
+                        }
+                        else
+                        {
+                            TIFFReadScanline(tiff, bufr, y, 0);
+                            TIFFReadScanline(tiff, bufg, y, 1);
+                            TIFFReadScanline(tiff, bufb, y, 2);
+                            pr = (int16 *)bufr;
+                            pg = (int16 *)bufg;
+                            pb = (int16 *)bufb;
+                        }
+                        typename RGBImageIterator::row_iterator rowit = yd.rowIterator();
+                        typename RGBImageIterator::row_iterator rowend = rowit + w;
+                        for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset)
+                            a.setRGB(*pr,*pg, *pb, rowit);
+                    }
+                    break;
+                  }
+                  case 32:
+                  {
+                    for(unsigned int y=0; y<h; ++y, ++yd.y)
+                    {
+                        int32 *pr, *pg, *pb;
+                        
+                        if(planarConfig == PLANARCONFIG_CONTIG)
+                        {
+                            TIFFReadScanline(tiff, bufr, y);
+                            pr = (int32 *)bufr;
+                            pg = pr+1;
+                            pb = pg+1;
+                        }
+                        else
+                        {
+                            TIFFReadScanline(tiff, bufr, y, 0);
+                            TIFFReadScanline(tiff, bufg, y, 1);
+                            TIFFReadScanline(tiff, bufb, y, 2);
+                            pr = (int32 *)bufr;
+                            pg = (int32 *)bufg;
+                            pb = (int32 *)bufb;
+                        }
+
+                        typename RGBImageIterator::row_iterator rowit = yd.rowIterator();
+                        typename RGBImageIterator::row_iterator rowend = rowit + w;
+                        for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset)
+                            a.setRGB(*pr,*pg, *pb, rowit);
+                    }
+                    break;
+                  }
+                  default:
+                    vigra_fail("tiffToRGBImage(TiffImage *, RGBImageIterator): "
+                         "unsupported number of bits per pixel");
+                }
+                break;
+              }
+              case SAMPLEFORMAT_IEEEFP:
+              {
+                switch (bitsPerSample)
+                {
+                  case sizeof(float)*8:
+                  {
+                    for(unsigned int y=0; y<h; ++y, ++yd.y)
+                    {
+                        float *pr, *pg, *pb;
+                        
+                        if(planarConfig == PLANARCONFIG_CONTIG)
+                        {
+                            TIFFReadScanline(tiff, bufr, y);
+                            pr = (float *)bufr;
+                            pg = pr+1;
+                            pb = pg+1;
+                        }
+                        else
+                        {
+                            TIFFReadScanline(tiff, bufr, y, 0);
+                            TIFFReadScanline(tiff, bufg, y, 1);
+                            TIFFReadScanline(tiff, bufb, y, 2);
+                            pr = (float *)bufr;
+                            pg = (float *)bufg;
+                            pb = (float *)bufb;
+                        }
+                        
+                        typename RGBImageIterator::row_iterator rowit = yd.rowIterator();
+                        typename RGBImageIterator::row_iterator rowend = rowit + w;
+                        for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset)
+                            a.setRGB(*pr,*pg, *pb, rowit);
+                    }
+                    break;
+                  }
+                  case sizeof(double)*8:
+                  {
+                    for(unsigned int y=0; y<h; ++y, ++yd.y)
+                    {
+                        double *pr, *pg, *pb;
+                        
+                        if(planarConfig == PLANARCONFIG_CONTIG)
+                        {
+                            TIFFReadScanline(tiff, bufr, y);
+                            pr = (double *)bufr;
+                            pg = pr+1;
+                            pb = pg+1;
+                        }
+                        else
+                        {
+                            TIFFReadScanline(tiff, bufr, y, 0);
+                            TIFFReadScanline(tiff, bufg, y, 1);
+                            TIFFReadScanline(tiff, bufb, y, 2);
+                            pr = (double *)bufr;
+                            pg = (double *)bufg;
+                            pb = (double *)bufb;
+                        }
+                        
+                        typename RGBImageIterator::row_iterator rowit = yd.rowIterator();
+                        typename RGBImageIterator::row_iterator rowend = rowit + w;
+                        for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset)
+                            a.setRGB(*pr,*pg, *pb, rowit);
+                    }
+                    break;
+                  }
+                  default:
+                    vigra_fail("tiffToRGBImage(TiffImage *, RGBImageIterator): "
+                         "unsupported number of bits per pixel");
+                }
+                break;
+              }
+              default:
+              {
+                // should never happen
+                vigra_fail("tiffToRGBImage(TiffImage *, RGBImageIterator): " 
+                     "internal error.");
+              }
+          }
+        }
+        catch(...)
+        {
+            delete[] bufr;
+            delete[] bufg;
+            delete[] bufb;
+            throw;
+        }
+        delete[] bufr;
+        delete[] bufg;
+        delete[] bufb;
+        
+        break;
+      }
+      default:
+      {
+        // should never happen
+        vigra_fail(
+          "tiffToRGBImage(TiffImage *, RGBImageIterator): " 
+          "internal error.");
+      }
+    }
+}
+
+template <class ImageIterator, class VectorComponentAccessor>
+void
+tiffToRGBImage(TiffImage * tiff, pair<ImageIterator, VectorComponentAccessor> dest)
+{
+    tiffToRGBImage(tiff, dest.first, dest.second);
+}
+
+template <class T>
+struct CreateTiffImage;
+
+/********************************************************/
+/*                                                      */
+/*                     createTiffImage                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Create a TiffImage from the given iterator range.
+
+    Type and size of the TiffImage are determined by the input image. 
+    Currently, the function can create scalar images and RGB images of type 
+    unsigned char, short, int, float, and double.
+   
+    Usually, it is better to use \ref exportImage(). createTiffImage() should only be used if explicit access to the TIFF object
+    <tt>TiffImage</tt> is required.    
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T, class S>
+        void
+        createTiffImage(MultiArrayView<2, T, S> const & src, TiffImage * tiff);
+    }
+    \endcode
+    
+    \deprecatedAPI{createTiffImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        TiffImage *
+        createTiffImage(ImageIterator upperleft, ImageIterator lowerright, 
+                        Accessor a)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        TiffImage *
+        createTiffImage(triple<ImageIterator, ImageIterator, Accessor> src)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/tiff.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> img(width, height);
+    
+    ...
+    
+    TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w");
+
+    createTiffImage(img, tiff);
+
+    TIFFClose(tiff);   // implicitly writes the image to the disk
+    \endcode
+
+    \deprecatedUsage{createTiffImage}
+    \code
+    vigra::BImage img(width, height);
+    
+    ...
+    
+    TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w");
+
+    vigra::createTiffImage(srcImageRange(img), tiff);
+
+    TIFFClose(tiff);   // implicitly writes the image to the disk
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator upperleft;
+    Accessor accessor;
+                           
+    accessor(upperleft);   // result written into TiffImage
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void createTiffImage)
+
+template <class ImageIterator, class Accessor>
+inline void
+createTiffImage(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+{
+    CreateTiffImage<typename Accessor::value_type>::
+        exec(upperleft, lowerright, a, tiff);
+}
+
+template <class ImageIterator, class Accessor>
+inline void
+createTiffImage(triple<ImageIterator, ImageIterator, Accessor> src, TiffImage * tiff)
+{
+    createTiffImage(src.first, src.second, src.third, tiff);
+}
+
+template <class T, class S>
+inline void
+createTiffImage(MultiArrayView<2, T, S> const & src, TiffImage * tiff)
+{
+    createTiffImage(srcImageRange(src), tiff);
+}
+
+/********************************************************/
+/*                                                      */
+/*                createScalarTiffImage                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Create a single-band TiffImage from the given scalar image.
+
+    Type and size of the TiffImage are determined by the input image 
+    (may be one of unsigned char, short, int, float, or double).
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        TiffImage *
+        createScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 
+                  Accessor a)
+    }
+    \endcode
+    
+    \deprecatedAPI{createScalarTiffImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        TiffImage *
+        createScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 
+                  Accessor a)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class ImageIterator, class Accessor>
+        TiffImage *
+        createScalarTiffImage(triple<ImageIterator, ImageIterator, Accessor> src)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/tiff.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> img(width, height);
+    ...
+   
+    TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w");
+
+    createScalarTiffImage(img, tiff);
+
+    TIFFClose(tiff);   // implicitly writes the image to the disk
+    \endcode
+
+    \deprecatedUsage{createScalarTiffImage}
+    \code
+    vigra::BImage img(width, height);
+    ...
+    
+    TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w");
+
+    vigra::createScalarTiffImage(srcImageRange(img), tiff);
+
+    TIFFClose(tiff);   // implicitly writes the image to the disk
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator upperleft;
+    Accessor accessor;
+                           
+    accessor(upperleft);   // result written into TiffImage
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void createScalarTiffImage)
+
+template <class ImageIterator, class Accessor>
+inline void
+createScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+{
+    CreateTiffImage<typename Accessor::value_type>::
+        exec(upperleft, lowerright, a, tiff);
+}
+
+template <class ImageIterator, class Accessor>
+inline void
+createScalarTiffImage(triple<ImageIterator, ImageIterator, Accessor> src, TiffImage * tiff)
+{
+    createScalarTiffImage(src.first, src.second, src.third, tiff);
+}
+
+template <class ImageIterator, class Accessor>
+void
+createBScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 
+                                 Accessor a, TiffImage * tiff)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
+    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
+    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8);
+    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
+    TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    ImageIterator ys(upperleft);
+    
+    try
+    {
+        for(int y=0; y<h; ++y, ++ys.y)
+        {
+            uint8 * p = (uint8 *)buf;
+            ImageIterator xs(ys);
+            
+            for(int x=0; x<w; ++x, ++xs.x)
+            {
+                p[x] = a(xs);
+            }
+            TIFFWriteScanline(tiff, buf, y);
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <class ImageIterator, class Accessor>
+void
+createShortScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 
+                                 Accessor a, TiffImage * tiff)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
+    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
+    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 16);
+    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
+    TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
+    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    ImageIterator ys(upperleft);
+    
+    try
+    {
+        for(int y=0; y<h; ++y, ++ys.y)
+        {
+            int16 * p = (int16 *)buf;
+            ImageIterator xs(ys);
+            
+            for(int x=0; x<w; ++x, ++xs.x)
+            {
+                p[x] = a(xs);
+            }
+            TIFFWriteScanline(tiff, buf, y);
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <class ImageIterator, class Accessor>
+void
+createUShortScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 
+                                 Accessor a, TiffImage * tiff)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
+    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
+    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 16);
+    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
+    TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    ImageIterator ys(upperleft);
+    
+    try
+    {
+        for(int y=0; y<h; ++y, ++ys.y)
+        {
+            uint16 * p = (uint16 *)buf;
+            ImageIterator xs(ys);
+            
+            for(int x=0; x<w; ++x, ++xs.x)
+            {
+                p[x] = a(xs);
+            }
+            TIFFWriteScanline(tiff, buf, y);
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <class ImageIterator, class Accessor>
+void
+createIScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 
+                                 Accessor a, TiffImage * tiff)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
+    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
+    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 32);
+    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
+    TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
+    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    ImageIterator ys(upperleft);
+    
+    try
+    {
+        for(int y=0; y<h; ++y, ++ys.y)
+        {
+            int32 * p = (int32 *)buf;
+            ImageIterator xs(ys);
+            
+            for(int x=0; x<w; ++x, ++xs.x)
+            {
+                p[x] = a(xs);
+            }
+            TIFFWriteScanline(tiff, buf, y);
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <class ImageIterator, class Accessor>
+void
+createFScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 
+                                 Accessor a, TiffImage * tiff)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
+    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
+    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(float)*8);
+    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
+    TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
+    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    ImageIterator ys(upperleft);
+    
+    try
+    {
+        for(int y=0; y<h; ++y, ++ys.y)
+        {
+            float * p = (float *)buf;
+            ImageIterator xs(ys);
+            
+            for(int x=0; x<w; ++x, ++xs.x)
+            {
+                p[x] = a(xs);
+            }
+            TIFFWriteScanline(tiff, buf, y);
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <class ImageIterator, class Accessor>
+void
+createDScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 
+                                 Accessor a, TiffImage * tiff)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
+    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
+    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(double)*8);
+    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
+    TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
+    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    ImageIterator ys(upperleft);
+    
+    try
+    {
+        for(int y=0; y<h; ++y, ++ys.y)
+        {
+            double * p = (double *)buf;
+            ImageIterator xs(ys);
+            
+            for(int x=0; x<w; ++x, ++xs.x)
+            {
+                p[x] = a(xs);
+            }
+            TIFFWriteScanline(tiff, buf, y);
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <>
+struct CreateTiffImage<unsigned char>
+{
+    template <class ImageIterator, class Accessor>
+    static void
+    exec(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+    {
+        createBScalarTiffImage(upperleft, lowerright, a, tiff);
+    }
+};
+
+template <>
+struct CreateTiffImage<short>
+{
+    template <class ImageIterator, class Accessor>
+    static void
+    exec(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+    {
+        createShortScalarTiffImage(upperleft, lowerright, a, tiff);
+    }
+};
+
+template <>
+struct CreateTiffImage<unsigned short>
+{
+    template <class ImageIterator, class Accessor>
+    static void
+    exec(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+    {
+        createUShortScalarTiffImage(upperleft, lowerright, a, tiff);
+    }
+};
+
+template <>
+struct CreateTiffImage<int>
+{
+    template <class ImageIterator, class Accessor>
+    static void
+    exec(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+    {
+        createIScalarTiffImage(upperleft, lowerright, a, tiff);
+    }
+};
+
+template <>
+struct CreateTiffImage<float>
+{
+    template <class ImageIterator, class Accessor>
+    static void
+    exec(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+    {
+        createFScalarTiffImage(upperleft, lowerright, a, tiff);
+    }
+};
+
+template <>
+struct CreateTiffImage<double>
+{
+    template <class ImageIterator, class Accessor>
+    static void
+    exec(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+    {
+        createDScalarTiffImage(upperleft, lowerright, a, tiff);
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                  createRGBTiffImage                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Create a 3-band TiffImage from the given RGB image.
+
+    Type and size of the TiffImage are determined by the input image 
+    (may be one of unsigned char, int, float, or double).
+    
+    <b> Declarations:</b>
+    
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class RGBImageIterator, class RGBAccessor>
+        TiffImage *
+        createRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright,
+                   RGBAccessor a)
+                }
+    \endcode
+    
+    \deprecatedAPI{createRGBTiffImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class RGBImageIterator, class RGBAccessor>
+        TiffImage *
+        createRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright,
+                   RGBAccessor a)
+                }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class RGBImageIterator, class RGBAccessor>
+        TiffImage *
+        createRGBTiffImage(triple<RGBImageIterator, RGBImageIterator, RGBAccessor> src)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/tiff.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, RGBValue<unsigned char> > img(width, height);
+    ...
+    
+    TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w");
+
+    createRGBTiffImage(img, tiff);
+
+    TIFFClose(tiff);   // implicitly writes the image to the disk
+    \endcode
+
+    \deprecatedUsage{createRGBTiffImage}
+    \code
+    vigra::BRGBImage img(width, height);
+    ...
+    
+    TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w");
+
+    vigra::createRGBTiffImage(srcImageRange(img), tiff);
+
+    TIFFClose(tiff);   // implicitly writes the image to the disk
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    ImageIterator upperleft;
+    RGBAccessor accessor;
+                           
+    accessor.red(upperleft);     // result written into TiffImage
+    accessor.green(upperleft);   // result written into TiffImage
+    accessor.blue(upperleft);    // result written into TiffImage
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> void createRGBTiffImage)
+
+template <class RGBImageIterator, class RGBAccessor>
+inline void
+createRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright,
+                   RGBAccessor a, TiffImage * tiff)
+{
+    CreateTiffImage<typename RGBAccessor::value_type>::
+        exec(upperleft, lowerright, a, tiff);
+}
+
+template <class RGBImageIterator, class RGBAccessor>
+inline void
+createRGBTiffImage(triple<RGBImageIterator, RGBImageIterator, RGBAccessor> src, TiffImage * tiff)
+{
+    createRGBTiffImage(src.first, src.second, src.third, tiff);
+}
+
+template <class RGBImageIterator, class RGBAccessor>
+void
+createBRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 
+                                   RGBAccessor a, TiffImage * tiff)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
+    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
+    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8);
+    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3);
+    TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    RGBImageIterator ys(upperleft);
+    
+    try
+    {
+        for(int y=0; y<h; ++y, ++ys.y)
+        {
+            uint8 * pr = (uint8 *)buf;
+            uint8 * pg = pr+1;
+            uint8 * pb = pg+1;
+            
+            RGBImageIterator xs(ys);
+            
+            for(int x=0; x<w; ++x, ++xs.x, pr+=3, pg+=3, pb+=3)
+            {
+                *pr = a.red(xs);
+                *pg = a.green(xs);
+                *pb = a.blue(xs);
+            }
+            TIFFWriteScanline(tiff, buf, y);
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <class RGBImageIterator, class RGBAccessor>
+void
+createShortRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 
+                                   RGBAccessor a, TiffImage * tiff)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
+    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
+    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 16);
+    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3);
+    TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
+    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    RGBImageIterator ys(upperleft);
+    
+    try
+    {
+        for(int y=0; y<h; ++y, ++ys.y)
+        {
+            uint16 * pr = (uint16 *)buf;
+            uint16 * pg = pr+1;
+            uint16 * pb = pg+1;
+            
+            RGBImageIterator xs(ys);
+            
+            for(int x=0; x<w; ++x, ++xs.x, pr+=3, pg+=3, pb+=3)
+            {
+                *pr = a.red(xs);
+                *pg = a.green(xs);
+                *pb = a.blue(xs);
+            }
+            TIFFWriteScanline(tiff, buf, y);
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <class RGBImageIterator, class RGBAccessor>
+void
+createIRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 
+                                   RGBAccessor a, TiffImage * tiff)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
+    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
+    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 32);
+    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3);
+    TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
+    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    RGBImageIterator ys(upperleft);
+    
+    try
+    {
+        for(int y=0; y<h; ++y, ++ys.y)
+        {
+            uint32 * pr = (uint32 *)buf;
+            uint32 * pg = pr+1;
+            uint32 * pb = pg+1;
+            
+            RGBImageIterator xs(ys);
+            
+            for(int x=0; x<w; ++x, ++xs.x, pr+=3, pg+=3, pb+=3)
+            {
+                *pr = a.red(xs);
+                *pg = a.green(xs);
+                *pb = a.blue(xs);
+            }
+            TIFFWriteScanline(tiff, buf, y);
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <class RGBImageIterator, class RGBAccessor>
+void
+createFRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 
+                                   RGBAccessor a, TiffImage * tiff)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
+    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
+    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(float)*8);
+    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3);
+    TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
+    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    RGBImageIterator ys(upperleft);
+    
+    try
+    {
+        for(int y=0; y<h; ++y, ++ys.y)
+        {
+            float * pr = (float *)buf;
+            float * pg = pr+1;
+            float * pb = pg+1;
+            
+            RGBImageIterator xs(ys);
+            
+            for(int x=0; x<w; ++x, ++xs.x, pr+=3, pg+=3, pb+=3)
+            {
+                *pr = a.red(xs);
+                *pg = a.green(xs);
+                *pb = a.blue(xs);
+            }
+            TIFFWriteScanline(tiff, buf, y);
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <class RGBImageIterator, class RGBAccessor>
+void
+createDRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 
+                                   RGBAccessor a, TiffImage * tiff)
+{
+    int w = lowerright.x - upperleft.x;
+    int h = lowerright.y - upperleft.y;
+    
+    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
+    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
+    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(double)*8);
+    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3);
+    TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
+    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+    
+    int bufsize = TIFFScanlineSize(tiff);
+    tdata_t * buf = new tdata_t[bufsize];
+    
+    RGBImageIterator ys(upperleft);
+    
+    try
+    {
+        for(int y=0; y<h; ++y, ++ys.y)
+        {
+            double * pr = (double *)buf;
+            double * pg = pr+1;
+            double * pb = pg+1;
+            
+            RGBImageIterator xs(ys);
+            
+            for(int x=0; x<w; ++x, ++xs.x, pr+=3, pg+=3, pb+=3)
+            {
+                *pr = a.red(xs);
+                *pg = a.green(xs);
+                *pb = a.blue(xs);
+            }
+            TIFFWriteScanline(tiff, buf, y);
+        }
+    }
+    catch(...)
+    {
+        delete[] buf;
+        throw;
+    }
+    delete[] buf;
+}
+
+template <>
+struct CreateTiffImage<RGBValue<unsigned char> >
+{
+    template <class ImageIterator, class Accessor>
+    static void
+    exec(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+    {
+        createBRGBTiffImage(upperleft, lowerright, a, tiff);
+    }
+};
+
+template <>
+struct CreateTiffImage<RGBValue<short> >
+{
+    template <class ImageIterator, class Accessor>
+    static void
+    exec(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+    {
+        createShortRGBTiffImage(upperleft, lowerright, a, tiff);
+    }
+};
+
+template <>
+struct CreateTiffImage<RGBValue<int> >
+{
+    template <class ImageIterator, class Accessor>
+    static void
+    exec(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+    {
+        createIRGBTiffImage(upperleft, lowerright, a, tiff);
+    }
+};
+
+template <>
+struct CreateTiffImage<RGBValue<float> >
+{
+    template <class ImageIterator, class Accessor>
+    static void
+    exec(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+    {
+        createFRGBTiffImage(upperleft, lowerright, a, tiff);
+    }
+};
+
+template <>
+struct CreateTiffImage<RGBValue<double> >
+{
+    template <class ImageIterator, class Accessor>
+    static void
+    exec(ImageIterator upperleft, ImageIterator lowerright, 
+                      Accessor a, TiffImage * tiff)
+    {
+        createDRGBTiffImage(upperleft, lowerright, a, tiff);
+    }
+};
+
+//@}
+
+} // namespace vigra
+
+
+#endif /* VIGRA_TIFF_HXX */
diff --git a/include/vigra/timing.hxx b/include/vigra/timing.hxx
new file mode 100644
index 0000000..12c4549
--- /dev/null
+++ b/include/vigra/timing.hxx
@@ -0,0 +1,374 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2008-2011 by Ullrich Koethe                  */
+/*       Cognitive Systems Group, University of Hamburg, Germany        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_TIMING_HXX
+#define VIGRA_TIMING_HXX
+#ifndef VIGRA_NO_TIMING
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+/** \page TimingMacros  Timing macros for runtime measurements
+
+<b>\#include</b> \<vigra/timing.hxx\>
+
+These macros allow to perform execution speed measurements. Results are reported
+in <i>milliseconds</i>.
+However, note that timings below 1 msec are generally subject to round-off errors. 
+Under LINUX, you can \#define VIGRA_HIRES_TIMING to get better
+accuracy, but this requires linking against librt.
+
+Basic usage:
+\code
+   void time_it()
+   {
+       USETICTOC
+  
+       TIC
+        ...    code to be timed
+       TOC
+        ...    untimed code
+       TIC
+        ...    other code to be timed
+       TOC
+   }
+\endcode
+
+Instead of TOC, which outputs the time difference to std::cerr, 
+you may use TOCN (the time difference in <i>msec</i> as a double)
+or TOCS (the time difference as a std::string). 
+
+Alternatively, you can perform nested timing like so:
+\code
+   void time_it()
+   {
+       USE_NESTED_TICTOC
+  
+       TICPUSH
+        ...         code to be timed
+           TICPUSH
+            ...         nested code to be timed
+           TOC          print time for nested code
+        ...         more code to be timed
+       TOC          print total time
+   }
+\endcode
+  
+*/
+
+/** \file timing.hxx  Timing macros for runtime measurements
+
+  This header defines timing macros for runtime measurements. See \ref TimingMacros for examples.
+
+  \def USETICTOC
+  Enable timing using TIC/TOC* pairs. This macro defines temporary storage for the timing data, so it needs to precede the TIC/TOC macros in their context.
+  \hideinitializer
+
+  \def USE_NESTED_TICTOC
+  Enable timing using TICPUSH/TOC* pairs. This macro defines temporary storage for the timing data, so it needs to precede the TIC/TOC macros in their context.
+  \hideinitializer
+
+  \def TIC
+  Start timing. Requires USE_TICTOC to be defined in the current context.
+  \hideinitializer
+
+  \def TOC
+  Stop timing and output result (the time difference w.r.t. the last TIC or TICPUSH 
+  instance) to std::cerr.
+  \hideinitializer
+
+  \def TICPUSH
+  Start timing, possibly a nested block of code within some other timed code block.
+  Requires USE_NESTED_TICTOC to be defined once in the current context.
+  \hideinitializer
+
+  \def TOCN
+  Stop timing. This macro evaluates to the time difference (w.r.t. the last TIC 
+  or TICPUSH) in msec as a double.
+  \hideinitializer
+  
+  \def TOCS
+  Stop timing. This macro evaluates to the time difference (w.r.t. the last TIC 
+  or TICPUSH) as a std::string (including units). 
+  \hideinitializer
+
+  \def TICTOCLOOP_BEGIN(inner_repetitions,outer_repetitions)
+  Executes the code block up to TICTOCLOOP_END outer_repetitions x
+  inner_repetitions times. The measurement is averaged over the
+  inner_repetitions, and the best result of the outer_repetitions is 
+  reported to std::cerr.
+  \hideinitializer
+
+  \def TICTOCLOOP_END
+  Ends the timing loop started with the TICTOCLOOP_BEGIN macro
+  and outputs the result.
+  \hideinitializer
+*/
+
+
+#ifdef _WIN32
+
+    #include "windows.h"
+
+    namespace {
+
+    inline double queryTimerUnit()
+    {
+        LARGE_INTEGER frequency;
+        QueryPerformanceFrequency(&frequency);
+        return 1000.0 / frequency.QuadPart;
+    }
+    
+    static const double timerUnit = queryTimerUnit();
+
+    inline double tic_toc_diff_num(LARGE_INTEGER const & tic)
+    {
+        LARGE_INTEGER toc;
+        QueryPerformanceCounter(&toc);
+        return ((toc.QuadPart - tic.QuadPart) * timerUnit);
+    }
+
+    inline std::string tic_toc_diff_string(LARGE_INTEGER const & tic)
+    {
+        double diff = tic_toc_diff_num(tic); 
+        std::stringstream s;
+        s << diff << " msec";
+        return s.str();
+    }
+
+    inline void tic_toc_diff(LARGE_INTEGER const & tic)
+    {
+        double diff = tic_toc_diff_num(tic);
+        std::cerr << diff << " msec" << std::endl;
+    }
+
+    inline double tic_toc_diff_num(std::vector<LARGE_INTEGER> & tic)
+    {
+        double res = tic_toc_diff_num(tic.back());
+        tic.pop_back();
+        return res;
+    }
+
+    inline std::string tic_toc_diff_string(std::vector<LARGE_INTEGER> & tic)
+    {
+        std::string res = tic_toc_diff_string(tic.back());
+        tic.pop_back();
+        return res;
+    }
+
+    inline void tic_toc_diff(std::vector<LARGE_INTEGER> & tic)
+    {
+        tic_toc_diff(tic.back());
+        tic.pop_back();
+    }
+
+    } // unnamed namespace
+    
+    #define USETICTOC LARGE_INTEGER tic_timer;
+    #define USE_NESTED_TICTOC std::vector<LARGE_INTEGER> tic_timer;
+    #define TIC QueryPerformanceCounter(&tic_timer);
+    #define TICPUSH tic_timer.push_back(LARGE_INTEGER());\
+                    QueryPerformanceCounter(&(tic_timer.back()));
+    #define TOC  tic_toc_diff       (tic_timer);
+    #define TOCN tic_toc_diff_num   (tic_timer)
+    #define TOCS tic_toc_diff_string(tic_timer)
+
+#else
+
+    #if defined(VIGRA_HIRES_TIMING) && !defined(__CYGWIN__)
+        // requires linking against librt
+    
+        #include <time.h>
+
+        namespace {
+
+        inline double tic_toc_diff_num(timespec const & tic)
+        {
+            timespec toc;
+            clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &toc);
+            return ((toc.tv_sec*1000.0 + toc.tv_nsec/1000000.0) -
+                  (tic.tv_sec*1000.0 + tic.tv_nsec/1000000.0));
+        }
+
+        inline std::string tic_toc_diff_string(timespec const & tic)
+        {
+            double diff = tic_toc_diff_num(tic); 
+            std::stringstream s;
+            s << diff << " msec";
+            return s.str();
+        }
+
+        inline void tic_toc_diff(timespec const & tic)
+        {
+            std::cerr << tic_toc_diff_string(tic) << std::endl;
+        }
+        
+        inline double tic_toc_diff_num(std::vector<timespec> & tic)
+        {
+            double res = tic_toc_diff_num(tic.back());
+            tic.pop_back();
+            return res;
+        }
+
+        inline std::string tic_toc_diff_string(std::vector<timespec> & tic)
+        {
+            std::string res = tic_toc_diff_string(tic.back());
+            tic.pop_back();
+            return res;
+        }
+
+        inline void tic_toc_diff(std::vector<timespec> & tic)
+        {
+            tic_toc_diff(tic.back());
+            tic.pop_back();
+        }
+
+        } // unnamed namespace
+
+        #define USETICTOC timespec tic_timer;
+        #define TIC clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tic_timer);
+        #define TOC  tic_toc_diff       (tic_timer);
+        #define TOCN tic_toc_diff_num   (tic_timer)
+        #define TOCS tic_toc_diff_string(tic_timer)
+        #define USE_NESTED_TICTOC std::vector<timespec> tic_timer;
+        #define TICPUSH tic_timer.push_back(timespec());\
+                        clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(tic_timer.back()));
+
+    #else
+    
+        #include <sys/time.h>
+
+        namespace {
+
+        inline double tic_toc_diff_num(timeval const & tic)
+        {
+            timeval toc;
+            gettimeofday(&toc, NULL);
+            return  ((toc.tv_sec*1000.0 + toc.tv_usec/1000.0) -
+                        (tic.tv_sec*1000.0 + tic.tv_usec/1000.0));
+        }
+        
+        inline std::string tic_toc_diff_string(timeval const & tic)
+        {
+            double diff = tic_toc_diff_num(tic); 
+            std::stringstream s;
+            s << diff << " msec";
+            return s.str();
+        }
+        
+        inline void tic_toc_diff(timeval const & tic)
+        {
+            std::cerr << tic_toc_diff_string(tic)<< std::endl;
+        }
+
+        inline double tic_toc_diff_num(std::vector<timeval> & tic)
+        {
+            double res = tic_toc_diff_num(tic.back());
+            tic.pop_back();
+            return res;
+        }
+
+        inline std::string tic_toc_diff_string(std::vector<timeval> & tic)
+        {
+            std::string res = tic_toc_diff_string(tic.back());
+            tic.pop_back();
+            return res;
+        }
+
+        inline void tic_toc_diff(std::vector<timeval> & tic)
+        {
+            tic_toc_diff(tic.back());
+            tic.pop_back();
+        }
+
+        } // unnamed namespace
+
+        #define USETICTOC timeval tic_timer;
+        #define TIC  gettimeofday       (&tic_timer, NULL);
+        #define TOC  tic_toc_diff       (tic_timer);
+        #define TOCN tic_toc_diff_num   (tic_timer)
+        #define TOCS tic_toc_diff_string(tic_timer)
+        #define USE_NESTED_TICTOC std::vector<timeval> tic_timer;
+        #define TICPUSH tic_timer.push_back(timeval());\
+                        gettimeofday(&(tic_timer.back()), NULL);
+
+    #endif // VIGRA_HIRES_TIMING
+
+#endif // _WIN32
+
+// TICTOCLOOP runs the body inner_repetitions times, and minimizes the result over a number of outer_repetitions runs,
+//  outputting the final minimal average to std::cerr
+// We enclose the loop in a dummy do { ... } while(false) in order to make this a true single statement 
+//  (instead of just a scope).
+#define TICTOCLOOP_BEGIN(inner_repetitions,outer_repetitions) \
+    do { \
+    USETICTOC \
+        double tictoc_best_, tictoc_inner_repetitions_=inner_repetitions; size_t tictoc_outer_repetitions_=outer_repetitions; \
+        for (size_t tictoccounter_=0; tictoccounter_<tictoc_outer_repetitions_; ++tictoccounter_) { \
+        TIC \
+        for (size_t tictocinnercounter_=0; tictocinnercounter_<inner_repetitions; ++tictocinnercounter_) { \
+
+        
+#define TICTOCLOOP_END \
+                } \
+        const double tictoc_cur_ = TOCN; \
+                if ((tictoccounter_==0) || (tictoc_cur_ < tictoc_best_)) \
+            tictoc_best_ = tictoc_cur_; \
+        } \
+        std::cerr << tictoc_best_/tictoc_inner_repetitions_ \
+             << " msec (best-of-" << tictoc_outer_repetitions_ << ")" << std::endl; \
+    } while(false);
+
+
+
+#else // NDEBUG
+
+#define USETICTOC 
+#define TIC
+#define TOC
+#define TOCN 0.0
+#define TICS ""
+#define USE_NESTED_TICTOC
+#define TICPUSH
+#define TICTOCLOOP_BEGIN(inner_repetitions,outer_repetitions)  do {
+#define TICTOCLOOP_END } while(false);
+#endif // NDEBUG
+
+
+
+#endif // VIGRA_TIMING_HXX
diff --git a/include/vigra/tinyvector.hxx b/include/vigra/tinyvector.hxx
new file mode 100644
index 0000000..1f9d53f
--- /dev/null
+++ b/include/vigra/tinyvector.hxx
@@ -0,0 +1,2051 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_TINYVECTOR_HXX
+#define VIGRA_TINYVECTOR_HXX
+
+namespace lemon {
+
+struct Invalid;
+
+} // namespace lemon
+
+#include <cmath>    // abs(double)
+#include <cstdlib>  // abs(int)
+#include <iosfwd>   // ostream
+#include <algorithm>
+#include "config.hxx"
+#include "error.hxx"
+#include "metaprogramming.hxx"
+#include "numerictraits.hxx"
+#include "memory.hxx"
+#include "mathutil.hxx"
+#include "diff2d.hxx"
+
+#ifdef VIGRA_CHECK_BOUNDS
+#define VIGRA_ASSERT_INSIDE(diff) \
+  vigra_precondition(diff >= 0, "Index out of bounds");\
+  vigra_precondition(diff < SIZE, "Index out of bounds");
+#else
+#define VIGRA_ASSERT_INSIDE(diff)
+#endif
+
+namespace vigra {
+
+// mask cl.exe shortcomings [begin]
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4503 )
+#endif
+
+using VIGRA_CSTD::abs;
+using VIGRA_CSTD::ceil;
+using VIGRA_CSTD::floor;
+using VIGRA_CSTD::sqrt;
+
+
+template <class V1, int SIZE, class D1, class D2>
+class TinyVectorBase;
+
+template <class V1, int SIZE, class D1, class D2>
+inline
+typename TinyVectorBase<V1, SIZE, D1, D2>::SquaredNormType
+squaredNorm(TinyVectorBase<V1, SIZE, D1, D2> const & t);
+
+
+namespace detail {
+
+#define VIGRA_EXEC_LOOP(NAME, OPER) \
+    template <class T1, class T2>  \
+    static void NAME(T1 * left, T2 const * right)  \
+    {  \
+        for(int i=0; i<LEVEL; ++i)  \
+            (left[i]) OPER (right[i]);  \
+    }
+
+#define VIGRA_EXEC_LOOP_MINMAX(NAME, OPER) \
+    template <class T1, class T2>  \
+    static void NAME(T1 * left, T2 const * right)  \
+    {  \
+        for(int i=0; i<LEVEL; ++i)  \
+            if(left[i] OPER right[i]) \
+                left[i] = right[i];  \
+    }
+
+#define VIGRA_EXEC_LOOP_SCALAR(NAME, OPER) \
+    template <class T1, class T2>  \
+    static void NAME(T1 * left, T2 right)  \
+    {  \
+        for(int i=0; i<LEVEL; ++i)  \
+            (left[i]) = detail::RequiresExplicitCast<T1>::cast((left[i]) OPER (right));  \
+    }
+
+template <int LEVEL>
+struct ExecLoop
+{
+    template <class T1, class T2>
+    static void assignCast(T1 * left, T2 const * right)
+    {
+        for(int i=0; i<LEVEL; ++i)
+            left[i] = detail::RequiresExplicitCast<T1>::cast(right[i]);
+    }
+
+    template <class T1, class T2>
+    static void reverseAssign(T1 * left, T2 const * right)
+    {
+        for(int i=0; i<LEVEL; ++i)
+            left[i] = right[-i];
+    }
+
+    template <class T1, class T2>
+    static void assignScalar(T1 * left, T2 right)
+    {
+        for(int i=0; i<LEVEL; ++i)
+            left[i] = detail::RequiresExplicitCast<T1>::cast(right);
+    }
+
+    template <class T1, class T2>
+    static void power(T1 * left, T2 right)
+    {
+        for(int i=0; i<LEVEL; ++i)
+            left[i] = detail::RequiresExplicitCast<T1>::cast(pow(left, right));
+    }
+
+    VIGRA_EXEC_LOOP(assign, =)
+    VIGRA_EXEC_LOOP(add, +=)
+    VIGRA_EXEC_LOOP(sub, -=)
+    VIGRA_EXEC_LOOP(mul, *=)
+    VIGRA_EXEC_LOOP(div, /=)
+    VIGRA_EXEC_LOOP(mod, %=)
+    VIGRA_EXEC_LOOP(neg, = -)
+    VIGRA_EXEC_LOOP(abs, = vigra::abs)
+    VIGRA_EXEC_LOOP(floor, = vigra::floor)
+    VIGRA_EXEC_LOOP(ceil, = vigra::ceil)
+    VIGRA_EXEC_LOOP(round, = vigra::round)
+    VIGRA_EXEC_LOOP(sqrt, = vigra::sqrt)
+    VIGRA_EXEC_LOOP(fromPromote, = NumericTraits<T1>::fromPromote)
+    VIGRA_EXEC_LOOP(fromRealPromote, = NumericTraits<T1>::fromRealPromote)
+    VIGRA_EXEC_LOOP_SCALAR(mulScalar, *)
+    VIGRA_EXEC_LOOP_SCALAR(divScalar, /)
+    
+    VIGRA_EXEC_LOOP_MINMAX(min, >)
+    VIGRA_EXEC_LOOP_MINMAX(max, <)
+
+    template <class T>
+    static T const & minimum(T const * p)
+    {
+        return *std::min_element(p, p+LEVEL);
+    }
+
+    template <class T>
+    static T const & maximum(T const * p)
+    {
+        return *std::max_element(p, p+LEVEL);
+    }
+
+    template <class T>
+    static bool all(T const * p, T const & zero)
+    {
+        for(int i=0; i<LEVEL; ++i)
+            if(p[i] == zero)
+                return false;
+        return true;
+    }
+
+    template <class T>
+    static bool any(T const * p, T const & zero)
+    {
+        for(int i=0; i<LEVEL; ++i)
+            if(p[i] != zero)
+                return true;
+        return false;
+    }
+
+    template <class T1, class T2>
+    static bool notEqual(T1 const * left, T2 const * right)
+    {
+        for(int i=0; i<LEVEL; ++i)
+            if(left[i] != right[i])
+                return true;
+        return false;
+    }
+
+    template <class T1, class T2>
+    static bool less(T1 const * left, T2 const * right)
+    {
+        for(int i=0; i<LEVEL; ++i)
+        {
+            if(left[i] < right[i])
+                return true;
+            if(right[i] < left[i])
+                return false;
+        }
+        return false;
+    }
+    
+    template <class T>
+    static bool closeAtTolerance(T const * left, T const * right, T epsilon)
+    {
+        bool res = true;
+        for(int i=0; i<LEVEL; ++i)
+        {
+            res = res && vigra::closeAtTolerance(left[i], right[i], epsilon);
+        }
+        return res;
+    }
+    
+    template <class T>
+    static typename NumericTraits<T>::Promote
+    dot(T const * d)
+    {
+        typename NumericTraits<T>::Promote  res(*d * *d);
+        for(int i=1; i<LEVEL; ++i)
+            res += d[i] * d[i];
+        return res;
+    }
+
+    template <class T1, class T2>
+    static typename PromoteTraits<T1, T2>::Promote
+    dot(T1 const * left, T2 const * right)
+    {
+        typename PromoteTraits<T1, T2>::Promote res(*left * *right);
+        for(int i=1; i<LEVEL; ++i)
+            res += left[i] * right[i];
+        return res;
+    }
+
+    template <class T>
+    static typename NormTraits<T>::SquaredNormType
+    squaredNorm(T const * d)
+    {
+        typename NormTraits<T>::SquaredNormType  res = vigra::squaredNorm(*d);
+        for(int i=1; i<LEVEL; ++i)
+            res += vigra::squaredNorm(d[i]);
+        return res;
+    }
+};
+
+template <int LEVEL>
+struct UnrollScalarResult
+{
+    template <class T>
+    static typename NumericTraits<T>::Promote
+    dot(T const * d)
+    {
+        return *d * *d + UnrollScalarResult<LEVEL-1>::dot(d+1);
+    }
+
+    template <class T1, class T2>
+    static typename PromoteTraits<T1, T2>::Promote
+    dot(T1 const * left, T2 const * right)
+    {
+        return *left * *right + UnrollScalarResult<LEVEL-1>::dot(left+1, right+1);
+    }
+    
+    template <class T>
+    static typename NormTraits<T>::SquaredNormType
+    squaredNorm(T const * d)
+    {
+        return vigra::squaredNorm(*d) + UnrollScalarResult<LEVEL-1>::squaredNorm(d+1);
+    }
+
+    static std::ptrdiff_t
+    squaredNorm(std::ptrdiff_t const * d)
+    {
+        return (*d)*(*d) + UnrollScalarResult<LEVEL-1>::squaredNorm(d+1);
+    }
+    
+    template <class T>
+    static T const & minimum(T const * p)
+    {
+        T const & m = UnrollScalarResult<LEVEL - 1>::minimum(p+1);
+        return *p < m
+                    ? *p
+                    : m;
+    }
+
+    template <class T>
+    static T const & maximum(T const * p)
+    {
+        T const & m = UnrollScalarResult<LEVEL - 1>::maximum(p+1);
+        return *p > m
+                    ? *p
+                    : m;
+    }
+
+    template <class T>
+    static bool all(T const * p, T const & zero)
+    {
+        return *p != zero && UnrollScalarResult<LEVEL - 1>::all(p+1, zero);
+    }
+
+    template <class T>
+    static bool any(T const * p, T const & zero)
+    {
+        return *p != zero || UnrollScalarResult<LEVEL - 1>::any(p+1, zero);
+    }
+};
+
+template <>
+struct UnrollScalarResult<1>
+{
+    template <class T>
+    static typename NumericTraits<T>::Promote
+    dot(T const * d)
+    {
+        return *d * *d ;
+    }
+
+    template <class T1, class T2>
+    static typename PromoteTraits<T1, T2>::Promote
+    dot(T1 const * left, T2 const * right)
+    {
+        return *left * *right;
+    }
+
+    template <class T>
+    static typename NormTraits<T>::SquaredNormType
+    squaredNorm(T const * d)
+    {
+        return vigra::squaredNorm(*d);
+    }
+
+    static std::ptrdiff_t
+    squaredNorm(std::ptrdiff_t const * d)
+    {
+        return (*d)*(*d);
+    }
+
+    template <class T>
+    static T const & minimum(T const * p)
+    {
+        return *p;
+    }
+
+    template <class T>
+    static T const & maximum(T const * p)
+    {
+        return *p;
+    }
+
+    template <class T>
+    static bool all(T const * p, T const & zero)
+    {
+        return *p != zero;
+    }
+
+    template <class T>
+    static bool any(T const * p, T const & zero)
+    {
+        return *p != zero;
+    }
+};
+
+#undef VIGRA_EXEC_LOOP
+#undef VIGRA_EXEC_LOOP_MINMAX
+#undef VIGRA_EXEC_LOOP_SCALAR
+
+#define VIGRA_UNROLL_LOOP(NAME, OPER) \
+    template <class T1, class T2>  \
+    static void NAME(T1 * left, T2 const * right)  \
+    {  \
+        (*left) OPER (*right);  \
+        UnrollLoop<LEVEL-1>::NAME(left+1, right+1); \
+    }
+
+#define VIGRA_UNROLL_LOOP_MINMAX(NAME, OPER) \
+    template <class T1, class T2>  \
+    static void NAME(T1 * left, T2 const * right)  \
+    {  \
+        if(*left OPER *right) \
+            *left = *right;  \
+        UnrollLoop<LEVEL-1>::NAME(left+1, right+1); \
+    }
+
+#define VIGRA_UNROLL_LOOP_SCALAR(NAME, OPER) \
+    template <class T1, class T2>  \
+    static void NAME(T1 * left, T2 right)  \
+    {  \
+        (*left) = detail::RequiresExplicitCast<T1>::cast((*left) OPER (right));  \
+        UnrollLoop<LEVEL-1>::NAME(left+1, right); \
+    }
+
+
+template <int LEVEL>
+struct UnrollLoop
+{
+    template <class T1, class T2>
+    static void reverseAssign(T1 * left, T2 const * right)
+    {
+        *left = *right;
+        UnrollLoop<LEVEL-1>::reverseAssign(left+1, right-1);
+    }
+
+    template <class T1, class T2>
+    static void assignCast(T1 * left, T2 const * right)
+    {
+        *left = detail::RequiresExplicitCast<T1>::cast(*right);
+        UnrollLoop<LEVEL-1>::assignCast(left+1, right+1);
+    }
+
+    template <class T1, class T2>
+    static void assignScalar(T1 * left, T2 right)
+    {
+        *left = detail::RequiresExplicitCast<T1>::cast(right);
+        UnrollLoop<LEVEL-1>::assignScalar(left+1, right);
+    }
+
+    template <class T1, class T2>
+    static void power(T1 * left, T2 right)
+    {
+        *left = detail::RequiresExplicitCast<T1>::cast(pow(*left, right));
+        UnrollLoop<LEVEL-1>::power(left+1, right);
+    }
+
+    VIGRA_UNROLL_LOOP(assign, =)
+    VIGRA_UNROLL_LOOP(add, +=)
+    VIGRA_UNROLL_LOOP(sub, -=)
+    VIGRA_UNROLL_LOOP(mul, *=)
+    VIGRA_UNROLL_LOOP(div, /=)
+    VIGRA_UNROLL_LOOP(mod, %=)
+    VIGRA_UNROLL_LOOP(neg, = -)
+    VIGRA_UNROLL_LOOP(abs, = vigra::abs)
+    VIGRA_UNROLL_LOOP(floor, = vigra::floor)
+    VIGRA_UNROLL_LOOP(ceil, = vigra::ceil)
+    VIGRA_UNROLL_LOOP(round, = vigra::round)
+    VIGRA_UNROLL_LOOP(sqrt, = vigra::sqrt)
+    VIGRA_UNROLL_LOOP(fromPromote, = NumericTraits<T1>::fromPromote)
+    VIGRA_UNROLL_LOOP(fromRealPromote, = NumericTraits<T1>::fromRealPromote)
+    VIGRA_UNROLL_LOOP_SCALAR(mulScalar, *)
+    VIGRA_UNROLL_LOOP_SCALAR(divScalar, /)
+    
+    VIGRA_UNROLL_LOOP_MINMAX(min, >)
+    VIGRA_UNROLL_LOOP_MINMAX(max, <)
+
+    template <class T>
+    static T const & minimum(T const * p)
+    {
+        return UnrollScalarResult<LEVEL>::minimum(p);
+    }
+
+    template <class T>
+    static T const & maximum(T const * p)
+    {
+        return UnrollScalarResult<LEVEL>::maximum(p);
+    }
+
+    template <class T>
+    static bool all(T const * p, T const & zero)
+    {
+        return UnrollScalarResult<LEVEL>::all(p, zero);
+    }
+
+    template <class T>
+    static bool any(T const * p, T const & zero)
+    {
+        return UnrollScalarResult<LEVEL>::any(p, zero);
+    }
+
+    template <class T1, class T2>
+    static bool notEqual(T1 const * left, T2 const * right)
+    {
+        return (*left != *right) || UnrollLoop<LEVEL - 1>::notEqual(left+1, right+1);
+    }
+
+    template <class T1, class T2>
+    static bool less(T1 const * left, T2 const * right)
+    {
+        if(*left < *right)
+            return true;
+        if(*right < *left)
+            return false;
+        return UnrollLoop<LEVEL - 1>::less(left+1, right+1);
+    }
+
+    template <class T>
+    static bool closeAtTolerance(T const * left, T const * right, T epsilon)
+    {
+        return vigra::closeAtTolerance(*left, *right, epsilon) && 
+                  UnrollLoop<LEVEL - 1>::closeAtTolerance(left+1, right+1, epsilon);
+    }
+    
+    template <class T>
+    static typename NumericTraits<T>::Promote
+    dot(T const * d)
+    {
+        return UnrollScalarResult<LEVEL>::dot(d);
+    }
+
+    template <class T1, class T2>
+    static typename PromoteTraits<T1, T2>::Promote
+    dot(T1 const * left, T2 const * right)
+    {
+        return UnrollScalarResult<LEVEL>::dot(left, right);
+    }
+
+    template <class T>
+    static typename NormTraits<T>::SquaredNormType
+    squaredNorm(T const * d)
+    {
+        return UnrollScalarResult<LEVEL>::squaredNorm(d);
+    }
+};
+
+#undef VIGRA_UNROLL_LOOP
+#undef VIGRA_UNROLL_LOOP_MINMAX
+#undef VIGRA_UNROLL_LOOP_SCALAR
+
+template <>
+struct UnrollLoop<0>
+{
+    template <class T1, class T2>
+    static void reverseAssign(T1, T2) {}
+    template <class T1, class T2>
+    static void assignCast(T1, T2) {}
+    template <class T1, class T2>
+    static void assign(T1, T2) {}
+    template <class T1, class T2>
+    static void assignScalar(T1, T2) {}
+    template <class T1, class T2>
+    static void power(T1, T2) {}
+    template <class T1, class T2>
+    static void add(T1, T2) {}
+    template <class T1, class T2>
+    static void sub(T1, T2) {}
+    template <class T1, class T2>
+    static void mul(T1, T2) {}
+    template <class T1, class T2>
+    static void mulScalar(T1, T2) {}
+    template <class T1, class T2>
+    static void div(T1, T2) {}
+    template <class T1, class T2>
+    static void mod(T1, T2) {}
+    template <class T1, class T2>
+    static void divScalar(T1, T2) {}
+    template <class T1, class T2>
+    static void fromPromote(T1, T2) {}
+    template <class T1, class T2>
+    static void fromRealPromote(T1, T2) {}
+    template <class T1, class T2>
+    static void neg(T1, T2) {}
+    template <class T1, class T2>
+    static void abs(T1, T2) {}
+    template <class T1, class T2>
+    static void floor(T1, T2) {}
+    template <class T1, class T2>
+    static void ceil(T1, T2) {}
+    template <class T1, class T2>
+    static void round(T1, T2) {}
+    template <class T1, class T2>
+    static void sqrt(T1, T2) {}
+    template <class T1, class T2>
+    static bool notEqual(T1, T2) { return false; }
+    template <class T1, class T2>
+    static bool less(T1, T2) { return false; }
+    template <class T1, class T2>
+    static void min(T1, T2) {}
+    template <class T1, class T2>
+    static void max(T1, T2) {}
+    template <class T>
+    static T minimum(T const *) { return NumericTraits<T>::max(); }
+    template <class T>
+    static T maximum(T const *) { return NumericTraits<T>::min(); }
+    template <class T>
+    static bool all(T const *, T const &) { return true; }
+    template <class T>
+    static bool any(T const *, T const &) { return false; }
+    template <class T>
+    static bool closeAtTolerance(T const *, T const *, T) { return true; }
+};
+
+template <int SIZE>
+struct LoopType
+{
+    static const int MaxUnrollSize = 5;
+    typedef typename IfBool<(SIZE <= MaxUnrollSize), UnrollLoop<SIZE>, ExecLoop<SIZE> >::type type;
+
+};
+
+struct DontInit {};
+
+inline DontInit dontInit() {return DontInit(); }
+
+} // namespace detail
+
+template <class T, int SIZE>
+class TinyVector;
+
+template <class T, int SIZE>
+class TinyVectorView;
+
+/********************************************************/
+/*                                                      */
+/*                    TinyVectorBase                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Base class for fixed size vectors.
+
+    This class contains functionality shared by
+    \ref TinyVector and \ref TinyVectorView, and enables these classes
+    to be freely mixed within expressions. It is typically not used directly.
+
+    <b>\#include</b> \<vigra/tinyvector.hxx\><br>
+    Namespace: vigra
+**/
+template <class VALUETYPE, int SIZE, class DATA, class DERIVED>
+class TinyVectorBase
+{
+    TinyVectorBase(TinyVectorBase const &); // do not use
+
+    TinyVectorBase & operator=(TinyVectorBase const & other); // do not use
+
+  protected:
+
+    typedef typename detail::LoopType<SIZE>::type Loop;
+
+    TinyVectorBase()
+    {}
+
+  public:
+        /** STL-compatible definition of valuetype
+        */
+    typedef VALUETYPE value_type;
+
+        /** reference (return of operator[]).
+        */
+    typedef VALUETYPE & reference;
+
+        /** const reference (return of operator[] const).
+        */
+    typedef VALUETYPE const & const_reference;
+
+        /** pointer (return of operator->).
+        */
+    typedef VALUETYPE * pointer;
+
+        /** const pointer (return of operator-> const).
+        */
+    typedef VALUETYPE const * const_pointer;
+
+        /** STL-compatible definition of iterator
+        */
+    typedef value_type * iterator;
+
+        /** STL-compatible definition of const iterator
+        */
+    typedef value_type const * const_iterator;
+
+        /** STL-compatible definition of size_type
+        */
+    typedef unsigned int size_type;
+
+        /** STL-compatible definition of difference_type
+        */
+    typedef std::ptrdiff_t difference_type;
+
+        /** the scalar type for the outer product
+        */
+    typedef double scalar_multiplier;
+
+        /** the vector's squared norm type
+        */
+    typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType;
+
+        /** the vector's norm type
+        */
+    typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
+
+        /** the vector's size
+        */
+    enum { static_size = SIZE };
+
+        /** Initialize from another sequence (must have length SIZE!)
+        */
+    template <class Iterator>
+    void init(Iterator i, Iterator end)
+    {
+        vigra_precondition(end-i == SIZE,
+            "TinyVector::init(): Sequence has wrong size.");
+        Loop::assignCast(data_, i);
+    }
+
+        /** Initialize with constant value
+        */
+    void init(value_type initial)
+    {
+        Loop::assignScalar(data_, initial);
+    }
+
+        /** Component-wise add-assignment
+        */
+    template <class T1, class D1, class D2>
+    DERIVED & operator+=(TinyVectorBase<T1, SIZE, D1, D2> const & r)
+    {
+        Loop::add(data_, r.begin());
+        return static_cast<DERIVED &>(*this);
+    }
+
+        /** Component-wise subtract-assignment
+        */
+    template <class T1, class D1, class D2>
+    DERIVED & operator-=(TinyVectorBase<T1, SIZE, D1, D2> const & r)
+    {
+        Loop::sub(data_, r.begin());
+        return static_cast<DERIVED &>(*this);
+    }
+
+        /** Component-wise multiply-assignment
+        */
+    template <class T1, class D1, class D2>
+    DERIVED & operator*=(TinyVectorBase<T1, SIZE, D1, D2> const & r)
+    {
+        Loop::mul(data_, r.begin());
+        return static_cast<DERIVED &>(*this);
+    }
+
+        /** Component-wise divide-assignment
+        */
+    template <class T1, class D1, class D2>
+    DERIVED & operator/=(TinyVectorBase<T1, SIZE, D1, D2> const & r)
+    {
+        Loop::div(data_, r.begin());
+        return static_cast<DERIVED &>(*this);
+    }
+
+        /** Component-wise modulo-assignment
+        */
+    template <class T1, class D1, class D2>
+    DERIVED & operator%=(TinyVectorBase<T1, SIZE, D1, D2> const & r)
+    {
+        Loop::mod(data_, r.begin());
+        return static_cast<DERIVED &>(*this);
+    }
+
+        /** Component-wise scalar multiply-assignment
+        */
+    DERIVED & operator*=(double r)
+    {
+        Loop::mulScalar(data_, r);
+        return static_cast<DERIVED &>(*this);
+    }
+
+        /** Component-wise scalar divide-assignment
+        */
+    DERIVED & operator/=(double r)
+    {
+        Loop::divScalar(data_, r);
+        return static_cast<DERIVED &>(*this);
+    }
+
+        /** Calculate magnitude.
+        */
+    NormType magnitude() const
+    {
+         return sqrt(static_cast<typename
+              SquareRootTraits<SquaredNormType>::SquareRootArgument>(squaredMagnitude()));
+    }
+
+        /** Calculate squared magnitude.
+        */
+    SquaredNormType squaredMagnitude() const
+    {
+        return Loop::squaredNorm(data_);
+    }
+
+        /** Return the minimal element.
+        */
+    VALUETYPE const & minimum() const
+    {
+        return Loop::minimum(data_);
+    }
+
+        /** Return the maximal element.
+        */
+    VALUETYPE const & maximum() const
+    {
+        return Loop::maximum(data_);
+    }
+    
+        /** Check that all elements of this vector are non-zero (or 'true' if T is bool).
+        */
+    bool all() const
+    {
+        return Loop::all(data_, VALUETYPE());
+    }
+    
+        /** Check that at least one element of this vector is non-zero (or 'true' if T is bool).
+        */
+    bool any() const
+    {
+        return Loop::any(data_, VALUETYPE());
+    }
+
+        /** Access component by index.
+        */
+    reference operator[](difference_type i)
+    {
+        VIGRA_ASSERT_INSIDE(i);
+        return data_[i];
+    }
+
+        /** Get component by index.
+        */
+    const_reference operator[](difference_type i) const
+    {
+        VIGRA_ASSERT_INSIDE(i);
+        return data_[i];
+    }
+
+        /** Get random access iterator to begin of vector.
+        */
+    iterator begin() { return data_; }
+        /** Get random access iterator past-the-end of vector.
+        */
+    iterator end() { return data_ + SIZE; }
+
+        /** Get const random access iterator to begin of vector.
+        */
+    const_iterator begin() const { return data_; }
+
+        /** Get const random access iterator past-the-end of vector.
+        */
+    const_iterator end() const { return data_ + SIZE; }
+    
+        /** Get a view to the subarray with length <tt>(TO-FROM)</tt> starting at <tt>FROM</tt>.
+            The bounds must fullfill <tt>0 <= FROM < TO <= SIZE</tt>, but this is only
+            checked when <tt>VIGRA_CHECK_BOUNDS</tt> is \#define'd.
+        */
+    template <int FROM, int TO>
+    TinyVectorView<VALUETYPE, TO-FROM> subarray() const
+    {
+#ifdef VIGRA_CHECK_BOUNDS
+        vigra_precondition(FROM >= 0, "Index out of bounds");
+        vigra_precondition(FROM < TO, "Index out of bounds");
+        vigra_precondition(TO <=SIZE, "Index out of bounds");
+#endif
+        return TinyVectorView<VALUETYPE, TO-FROM>(data_+FROM);
+    }
+
+        /** Size of TinyVector vector always equals the template parameter SIZE.
+        */
+    size_type size() const { return SIZE; }
+
+    pointer data() { return data_; }
+
+    const_pointer data() const { return data_; }
+    
+    static TinyVector<VALUETYPE, SIZE> unitVector(int k)
+    {
+        VIGRA_ASSERT_INSIDE(k);
+        TinyVector<VALUETYPE, SIZE> ret;
+        ret[k] = 1;
+        return ret;
+    }
+
+  protected:
+  
+    DATA data_;
+};
+
+/** \brief Class for fixed size vectors.
+    \ingroup RangesAndPoints
+
+    This class contains an array of size SIZE of the specified VALUETYPE.
+    The interface conforms to STL vector, except that there are no functions
+    that change the size of a TinyVector.
+
+    \ref TinyVectorOperators "Arithmetic operations"
+    on TinyVectors are defined as component-wise applications of these
+    operations. Addition and subtraction of two TinyVectors
+    (+=, -=, +, -, unary -), multiplication and division of an
+    TinyVector with a double, and NumericTraits/PromoteTraits are defined,
+    so that TinyVector fulfills the requirements of \ref LinearAlgebraConcept "Linear Algebra".
+
+    VIGRA algorithms typically use \ref vigra::VectorAccessor to access
+    TinyVectors as a whole, or specific components of them.
+
+    See also:<br>
+    <UL style="list-style-image:url(documents/bullet.gif)">
+        <LI> \ref vigra::TinyVectorBase
+        <LI> \ref vigra::TinyVectorView
+        <LI> \ref TinyVectorTraits
+        <LI> \ref TinyVectorOperators
+    </UL>
+
+    <b>\#include</b> \<vigra/tinyvector.hxx\><br>
+    Namespace: vigra
+**/
+template <class T, int SIZE>
+class TinyVector
+: public TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> >
+{
+    typedef TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> > BaseType;
+    typedef typename BaseType::Loop Loop;
+
+  public:
+
+    typedef typename BaseType::value_type value_type;
+    typedef typename BaseType::reference reference;
+    typedef typename BaseType::const_reference const_reference;
+    typedef typename BaseType::pointer pointer;
+    typedef typename BaseType::const_pointer const_pointer;
+    typedef typename BaseType::iterator iterator;
+    typedef typename BaseType::const_iterator const_iterator;
+    typedef typename BaseType::size_type size_type;
+    typedef typename BaseType::difference_type difference_type;
+    typedef typename BaseType::scalar_multiplier scalar_multiplier;
+    typedef typename BaseType::SquaredNormType SquaredNormType;
+    typedef typename BaseType::NormType NormType;
+    
+    enum ReverseCopyTag { ReverseCopy };
+
+        /** Construction with constant value.
+        
+            Initializes all vector elements with the given value.
+        */
+    explicit TinyVector(value_type const & initial)
+    : BaseType()
+    {
+        Loop::assignScalar(BaseType::begin(), initial);
+    }
+
+        /** Construction from lemon::Invalid.
+        
+            Initializes all vector elements with -1.
+        */
+    TinyVector(lemon::Invalid const &)
+    : BaseType()
+    {
+        Loop::assignScalar(BaseType::begin(), -1);
+    }
+
+        /** Construction with Diff2D.
+        
+            Use only when <tt>SIZE == 2</tt>.
+        */
+    explicit TinyVector(Diff2D const & initial)
+    : BaseType()
+    {
+        BaseType::data_[0] = detail::RequiresExplicitCast<T>::cast(initial.x);
+        BaseType::data_[1] = detail::RequiresExplicitCast<T>::cast(initial.y);
+    }
+
+        /** Construction with explicit values.
+            Call only if SIZE == 2
+        */
+    TinyVector(value_type const & i1, value_type const & i2)
+    : BaseType()
+    {
+        BaseType::data_[0] = i1;
+        BaseType::data_[1] = i2;
+    }
+
+        /** Construction with explicit values.
+            Call only if SIZE == 3
+        */
+    TinyVector(value_type const & i1, value_type const & i2, value_type const & i3)
+    : BaseType()
+    {
+        BaseType::data_[0] = i1;
+        BaseType::data_[1] = i2;
+        BaseType::data_[2] = i3;
+    }
+
+        /** Construction with explicit values.
+            Call only if SIZE == 4
+        */
+    TinyVector(value_type const & i1, value_type const & i2,
+               value_type const & i3, value_type const & i4)
+    : BaseType()
+    {
+        BaseType::data_[0] = i1;
+        BaseType::data_[1] = i2;
+        BaseType::data_[2] = i3;
+        BaseType::data_[3] = i4;
+    }
+
+        /** Construction with explicit values.
+            Call only if SIZE == 5
+        */
+    TinyVector(value_type const & i1, value_type const & i2,
+               value_type const & i3, value_type const & i4,
+               value_type const & i5)
+    : BaseType()
+    {
+        BaseType::data_[0] = i1;
+        BaseType::data_[1] = i2;
+        BaseType::data_[2] = i3;
+        BaseType::data_[3] = i4;
+        BaseType::data_[4] = i5;
+    }
+    
+       /** Default constructor (initializes all elements with zero).
+        */
+    TinyVector()
+    : BaseType()
+    {
+        Loop::assignScalar(BaseType::data_, value_type());
+    }
+
+        /** Construct without initializing the vector elements.
+        */
+    explicit TinyVector(SkipInitializationTag)
+    : BaseType()
+    {}
+
+    explicit TinyVector(detail::DontInit)
+    : BaseType()
+    {}
+
+        /** Copy constructor.
+        */
+    TinyVector(TinyVector const & r)
+    : BaseType()
+    {
+        Loop::assign(BaseType::data_, r.data_);
+    }
+
+        /** Constructor from C array.
+        */
+    template <class U>
+    explicit TinyVector(U const * data)
+    : BaseType()
+    {
+        Loop::assign(BaseType::data_, data);
+    }
+
+        /** Constructor by reverse copy from C array.
+            
+            Usage:
+            \code
+            TinyVector<int, 3> v(1,2,3);
+            TinyVector<int, 3> reversed(v.begin(), TinyVector<int, 3>::ReverseCopy);
+            \endcode
+        */
+    explicit TinyVector(const_pointer data, ReverseCopyTag)
+    : BaseType()
+    {
+        Loop::reverseAssign(BaseType::data_, data+SIZE-1);
+    }
+
+        /** Copy with type conversion.
+        */
+    template <class U, class DATA, class DERIVED>
+    TinyVector(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r)
+    : BaseType()
+    {
+        Loop::assignCast(BaseType::data_, r.begin());
+    }
+
+        /** Copy assignment.
+        */
+    TinyVector & operator=(TinyVector const & r)
+    {
+        Loop::assign(BaseType::data_, r.data_);
+        return *this;
+    }
+
+        /** Copy assignment with type conversion.
+        */
+    template <class U, class DATA, class DERIVED>
+    TinyVector & operator=(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r)
+    {
+        Loop::assignCast(BaseType::data_, r.begin());
+        return *this;
+    }
+
+        /** Assignment from Diff2D.
+        
+            Use only when <tt>SIZE == 2</tt>.
+        */
+    TinyVector & operator=(Diff2D const & r)
+    {
+        BaseType::data_[0] = detail::RequiresExplicitCast<T>::cast(r.x);
+        BaseType::data_[1] = detail::RequiresExplicitCast<T>::cast(r.y);
+        return *this;
+    }
+
+        /** Assignment from scalar. Will set all entries to the given value.
+        */
+    TinyVector & operator=(value_type const & v)
+    {
+        Loop::assignScalar(BaseType::begin(), v);
+        return *this;
+    }
+
+        /** Copy from a TinyVector with a different number of elements.
+        
+            Only the first <tt>min(SIZE, USIZE)</tt> elements are copied.
+        */
+    template <class U, int USIZE, class DATA, class DERIVED>
+    TinyVector & copy(TinyVectorBase<U, USIZE, DATA, DERIVED> const & r)
+    {
+        static const int minSize = USIZE < SIZE
+                                        ? USIZE
+                                        : SIZE;
+        
+        typedef typename detail::LoopType<minSize>::type MinLoop;
+        MinLoop::assignCast(BaseType::data_, r.begin());
+        return *this;
+    }
+};
+
+/** \brief Wrapper for fixed size vectors.
+
+    This class wraps an array of size SIZE of the specified VALUETYPE.
+    Thus, the array can be accessed with an interface similar to
+    that of std::vector (except that there are no functions
+    that change the size of a TinyVectorView). The TinyVectorView
+    does <em>not</em> assume ownership of the given memory.
+
+    \ref TinyVectorOperators "Arithmetic operations"
+    on TinyVectorViews are defined as component-wise applications of these
+    operations. Addition and subtraction of two TinyVectorViews
+    (+=, -=, +, -, unary -), multiplication and division of an
+    TinyVectorViews with a double, and NumericTraits/PromoteTraits are defined,
+    so that TinyVectorView fulfills the requirements of \ref LinearAlgebraConcept "Linear Algebra".
+
+    VIGRA algorithms typically use \ref vigra::VectorAccessor to access
+    TinyVectorViews as a whole, or specific components of them.
+
+    <b>See also:</b>
+    <ul>
+        <li> \ref vigra::TinyVectorBase
+        <li> \ref vigra::TinyVector
+        <li> \ref TinyVectorTraits
+        <li> \ref TinyVectorOperators
+    </ul>
+
+    <b>\#include</b> \<vigra/tinyvector.hxx\><br>
+    Namespace: vigra
+**/
+template <class T, int SIZE>
+class TinyVectorView
+: public TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> >
+{
+    typedef TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> > BaseType;
+    typedef typename BaseType::Loop Loop;
+
+  public:
+
+    typedef typename BaseType::value_type value_type;
+    typedef typename BaseType::reference reference;
+    typedef typename BaseType::const_reference const_reference;
+    typedef typename BaseType::pointer pointer;
+    typedef typename BaseType::const_pointer const_pointer;
+    typedef typename BaseType::iterator iterator;
+    typedef typename BaseType::const_iterator const_iterator;
+    typedef typename BaseType::size_type size_type;
+    typedef typename BaseType::difference_type difference_type;
+    typedef typename BaseType::scalar_multiplier scalar_multiplier;
+    typedef typename BaseType::SquaredNormType SquaredNormType;
+    typedef typename BaseType::NormType NormType;
+
+        /** Default constructor
+            (pointer to wrapped data is NULL).
+        */
+    TinyVectorView()
+    : BaseType()
+    {
+        BaseType::data_ = 0;
+    }
+
+        /** Construct view for given data array
+        */
+    TinyVectorView(const_pointer data)
+    : BaseType()
+    {
+        BaseType::data_ = const_cast<pointer>(data);
+    }
+
+        /** Copy constructor (shallow copy).
+        */
+    TinyVectorView(TinyVectorView const & other)
+    : BaseType()
+    {
+        BaseType::data_ = const_cast<pointer>(other.data_);
+    }
+
+        /** Construct view from other TinyVector.
+        */
+    template <class DATA, class DERIVED>
+    TinyVectorView(TinyVectorBase<T, SIZE, DATA, DERIVED> const & other)
+    : BaseType()
+    {
+        BaseType::data_ = const_cast<pointer>(other.data());
+    }
+
+        /** Copy the data (not the pointer) of the rhs.
+        */
+   TinyVectorView & operator=(TinyVectorView const & r)
+    {
+        Loop::assign(BaseType::data_, r.begin());
+        return *this;
+    }
+
+        /** Copy the data of the rhs with cast.
+        */
+    template <class U, class DATA, class DERIVED>
+    TinyVectorView & operator=(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r)
+    {
+        Loop::assignCast(BaseType::data_, r.begin());
+        return *this;
+    }
+};
+
+/********************************************************/
+/*                                                      */
+/*                     TinyVector Comparison            */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup TinyVectorOperators Functions for TinyVector
+
+    \brief Implement basic arithmetic and equality for TinyVector.
+
+    These functions fulfill the requirements of a Linear Space (vector space).
+    Return types are determined according to \ref TinyVectorTraits.
+
+    <b>\#include</b> \<vigra/tinyvector.hxx\><br>
+    Namespace: vigra
+*/
+//@{
+    /// component-wise equal
+template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
+inline bool
+operator==(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+           TinyVectorBase<V2, SIZE, D3, D4> const & r)
+{
+    return !(l != r);
+}
+
+    /// component-wise not equal
+template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
+inline bool
+operator!=(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+           TinyVectorBase<V2, SIZE, D3, D4> const & r)
+{
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    return ltype::notEqual(l.begin(), r.begin());
+}
+
+    /// lexicographical comparison
+template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
+inline bool
+operator<(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+          TinyVectorBase<V2, SIZE, D3, D4> const & r)
+{
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    return ltype::less(l.begin(), r.begin());
+}
+
+template <class V, int SIZE, class D1, class D2, class D3, class D4>
+bool 
+closeAtTolerance(TinyVectorBase<V, SIZE, D1, D2> const & l,
+                 TinyVectorBase<V, SIZE, D3, D4> const & r, 
+                 V epsilon = NumericTraits<V>::epsilon())
+{
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    return ltype::closeAtTolerance(l.begin(), r.begin(), epsilon);
+}
+
+template <class V, int SIZE>
+bool 
+closeAtTolerance(TinyVector<V, SIZE> const & l,
+                 TinyVector<V, SIZE> const & r, 
+                 V epsilon = NumericTraits<V>::epsilon())
+{
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    return ltype::closeAtTolerance(l.begin(), r.begin(), epsilon);
+}
+
+/********************************************************/
+/*                                                      */
+/*                     TinyVector Output                */
+/*                                                      */
+/********************************************************/
+
+    /// stream output
+template <class V1, int SIZE, class DATA, class DERIVED>
+std::ostream &
+operator<<(std::ostream & out, TinyVectorBase<V1, SIZE, DATA, DERIVED> const & l)
+{
+    out << "(";
+    int i;
+    for(i=0; i<SIZE-1; ++i)
+        out << l[i] << ", ";
+    out << l[i] << ")";
+    return out;
+}
+//@}
+
+/********************************************************/
+/*                                                      */
+/*                      TinyVector-Traits               */
+/*                                                      */
+/********************************************************/
+
+/** \page TinyVectorTraits Numeric and Promote Traits of TinyVector
+    The numeric and promote traits for TinyVectors follow
+    the general specifications for \ref NumericPromotionTraits.
+    They are implemented in terms of the traits of the basic types by
+    partial template specialization:
+
+    \code
+
+    template <class T, int SIZE>
+    struct NumericTraits<TinyVector<T, SIZE> >
+    {
+        typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
+        typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
+
+        typedef typename NumericTraits<T>::isIntegral isIntegral;
+        typedef VigraFalseType isScalar;
+        typedef typename NumericTraits<T>::isSigned isSigned;
+
+        // etc.
+    };
+
+    template <class T, int SIZE>
+    struct NormTraits<TinyVector<T, SIZE> >
+    {
+        typedef TinyVector<T, SIZE> Type;
+        typedef typename Type::SquaredNormType    SquaredNormType;
+        typedef typename Type::NormType           NormType;
+    };
+
+    template <class T1, class T2, SIZE>
+    struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> >
+    {
+        typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
+    };
+    \endcode
+
+    <b>\#include</b> \<vigra/tinyvector.hxx\><br>
+    Namespace: vigra
+
+    On compilers that don't support partial template specialization (e.g.
+    MS VisualC++), the traits classes are explicitly specialized for
+    <TT>TinyVector<VALUETYPE, SIZE></TT> with
+    <TT>VALUETYPE = unsigned char | int | float | double</TT> and <TT>SIZE = 2 | 3 | 4</TT>.
+
+*/
+
+#if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
+
+template <class T, int SIZE>
+struct NumericTraits<TinyVector<T, SIZE> >
+{
+    typedef TinyVector<T, SIZE> Type;
+    typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
+    typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
+    typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;
+    typedef T ValueType;
+
+    typedef typename NumericTraits<T>::isIntegral isIntegral;
+    typedef VigraFalseType isScalar;
+    typedef typename NumericTraits<T>::isSigned isSigned;
+    typedef VigraTrueType isOrdered;
+    typedef VigraFalseType isComplex;
+
+    static TinyVector<T, SIZE> zero()
+    {
+        return TinyVector<T, SIZE>(NumericTraits<T>::zero());
+    }
+    static TinyVector<T, SIZE> one()
+    {
+        return TinyVector<T, SIZE>(NumericTraits<T>::one());
+    }
+    static TinyVector<T, SIZE> nonZero()
+    {
+        return TinyVector<T, SIZE>(NumericTraits<T>::nonZero());
+    }
+
+    static TinyVector<T, SIZE> min()
+    {
+        return TinyVector<T, SIZE>(NumericTraits<T>::min());
+    }
+    static TinyVector<T, SIZE> max()
+    {
+        return TinyVector<T, SIZE>(NumericTraits<T>::max());
+    }
+
+    template <class D1, class D2>
+    static Promote toPromote(TinyVectorBase<T, SIZE, D1, D2> const & v)
+    {
+        return Promote(v);
+    }
+
+    template <class D1, class D2>
+    static RealPromote toRealPromote(TinyVectorBase<T, SIZE, D1, D2> const & v)
+    {
+        return RealPromote(v);
+    }
+
+    template <class D1, class D2>
+    static TinyVector<T, SIZE>
+    fromPromote(TinyVectorBase<typename NumericTraits<T>::Promote, SIZE, D1, D2> const & v)
+    {
+        TinyVector<T, SIZE> res(detail::dontInit());
+        typedef typename detail::LoopType<SIZE>::type ltype;
+        ltype::fromPromote(res.begin(), v.begin());
+        return res;
+    }
+
+    template <class D1, class D2>
+    static TinyVector<T, SIZE>
+    fromRealPromote(TinyVectorBase<typename NumericTraits<T>::RealPromote, SIZE, D1, D2> const & v)
+    {
+        TinyVector<T, SIZE> res(detail::dontInit());
+        typedef typename detail::LoopType<SIZE>::type ltype;
+        ltype::fromRealPromote(res.begin(), v.begin());
+        return res;
+    }
+};
+
+template <class T, int SIZE>
+struct NumericTraits<TinyVectorView<T, SIZE> >
+: public NumericTraits<TinyVector<T, SIZE> >
+{
+    typedef TinyVector<T, SIZE> Type;
+    typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
+    typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
+    typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;
+    typedef T ValueType;
+
+    typedef typename NumericTraits<T>::isIntegral isIntegral;
+    typedef VigraFalseType isScalar;
+    typedef typename NumericTraits<T>::isSigned isSigned;
+    typedef VigraFalseType isOrdered;
+    typedef VigraFalseType isComplex;
+};
+
+template <class T, int SIZE>
+struct NormTraits<TinyVector<T, SIZE> >
+{
+    typedef TinyVector<T, SIZE> Type;
+    typedef typename Type::SquaredNormType    SquaredNormType;
+    typedef typename Type::NormType           NormType;
+};
+
+template <class T, int SIZE>
+struct NormTraits<TinyVectorView<T, SIZE> >
+{
+    typedef TinyVector<T, SIZE> Type;
+    typedef typename Type::SquaredNormType    SquaredNormType;
+    typedef typename Type::NormType           NormType;
+};
+
+template <class T1, class T2, int SIZE>
+struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> >
+{
+    typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
+};
+
+template <class T1, class T2, int SIZE>
+struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVectorView<T2, SIZE> >
+{
+    typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
+};
+
+template <class T1, class T2, int SIZE>
+struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVector<T2, SIZE> >
+{
+    typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
+};
+
+template <class T1, class T2, int SIZE>
+struct PromoteTraits<TinyVector<T1, SIZE>, TinyVectorView<T2, SIZE> >
+{
+    typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
+};
+
+template <class T, int SIZE>
+struct PromoteTraits<TinyVector<T, SIZE>, double >
+{
+    typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
+};
+
+template <class T, int SIZE>
+struct PromoteTraits<double, TinyVector<T, SIZE> >
+{
+    typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
+};
+
+template <class T, int SIZE>
+struct PromoteTraits<TinyVectorView<T, SIZE>, double >
+{
+    typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
+};
+
+template <class T, int SIZE>
+struct PromoteTraits<double, TinyVectorView<T, SIZE> >
+{
+    typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
+};
+
+template<class T, int SIZE>
+struct CanSkipInitialization<TinyVectorView<T, SIZE> >
+{
+    typedef typename CanSkipInitialization<T>::type type;
+    static const bool value = type::asBool;
+};
+
+template<class T, int SIZE>
+struct CanSkipInitialization<TinyVector<T, SIZE> >
+{
+    typedef typename CanSkipInitialization<T>::type type;
+    static const bool value = type::asBool;
+};
+
+
+
+#else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+
+#define TINYVECTOR_NUMTRAITS(T, SIZE) \
+template<>\
+struct NumericTraits<TinyVector<T, SIZE> >\
+{\
+    typedef TinyVector<T, SIZE> Type;\
+    typedef TinyVector<NumericTraits<T>::Promote, SIZE> Promote;\
+    typedef TinyVector<NumericTraits<T>::RealPromote, SIZE> RealPromote;\
+    typedef TinyVector<NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;\
+    typedef T ValueType; \
+    typedef NumericTraits<T>::isIntegral isIntegral;\
+    typedef VigraFalseType isScalar;\
+    typedef NumericTraits<T>::isSigned isSigned; \
+    typedef VigraFalseType isOrdered;\
+    typedef VigraFalseType isComplex;\
+    \
+    static TinyVector<T, SIZE> zero() { \
+        return TinyVector<T, SIZE>(NumericTraits<T>::zero()); \
+    }\
+    static TinyVector<T, SIZE> one() { \
+        return TinyVector<T, SIZE>(NumericTraits<T>::one()); \
+    }\
+    static TinyVector<T, SIZE> nonZero() { \
+        return TinyVector<T, SIZE>(NumericTraits<T>::nonZero()); \
+    }\
+    \
+    static Promote toPromote(TinyVector<T, SIZE> const & v) { \
+        return Promote(v); \
+    }\
+    static RealPromote toRealPromote(TinyVector<T, SIZE> const & v) { \
+        return RealPromote(v); \
+    }\
+    static TinyVector<T, SIZE> fromPromote(Promote const & v) { \
+        TinyVector<T, SIZE> res;\
+        TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\
+        Promote::const_iterator s = v.begin();\
+        for(; d != dend; ++d, ++s)\
+            *d = NumericTraits<T>::fromPromote(*s);\
+        return res;\
+    }\
+    static TinyVector<T, SIZE> fromRealPromote(RealPromote const & v) {\
+        TinyVector<T, SIZE> res;\
+        TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\
+        RealPromote::const_iterator s = v.begin();\
+        for(; d != dend; ++d, ++s)\
+            *d = NumericTraits<T>::fromRealPromote(*s);\
+        return res;\
+    }\
+}; \
+template<>\
+struct NormTraits<TinyVector<T, SIZE> >\
+{\
+    typedef TinyVector<T, SIZE> Type;\
+    typedef Type::SquaredNormType           SquaredNormType; \
+    typedef Type::NormType NormType; \
+};
+
+#define TINYVECTOR_PROMTRAITS1(type1, SIZE) \
+template<> \
+struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type1, SIZE> > \
+{ \
+    typedef TinyVector<PromoteTraits<type1, type1>::Promote, SIZE> Promote; \
+    static Promote toPromote(TinyVector<type1, SIZE> const & v) { \
+        return static_cast<Promote>(v); } \
+};
+
+#define TINYVECTOR_PROMTRAITS2(type1, type2, SIZE) \
+template<> \
+struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type2, SIZE> > \
+{ \
+    typedef TinyVector<PromoteTraits<type1, type2>::Promote, SIZE> Promote; \
+    static Promote toPromote(TinyVector<type1, SIZE> const & v) { \
+        return static_cast<Promote>(v); } \
+    static Promote toPromote(TinyVector<type2, SIZE> const & v) { \
+       return static_cast<Promote>(v); } \
+};
+
+#define TINYVECTOR_TRAITS(SIZE) \
+TINYVECTOR_NUMTRAITS(unsigned char, SIZE)\
+TINYVECTOR_NUMTRAITS(int, SIZE)\
+TINYVECTOR_NUMTRAITS(float, SIZE)\
+TINYVECTOR_NUMTRAITS(double, SIZE)\
+TINYVECTOR_PROMTRAITS1(unsigned char, SIZE)\
+TINYVECTOR_PROMTRAITS1(int, SIZE)\
+TINYVECTOR_PROMTRAITS1(float, SIZE)\
+TINYVECTOR_PROMTRAITS1(double, SIZE)\
+TINYVECTOR_PROMTRAITS2(float, unsigned char, SIZE)\
+TINYVECTOR_PROMTRAITS2(unsigned char, float, SIZE)\
+TINYVECTOR_PROMTRAITS2(int, unsigned char, SIZE)\
+TINYVECTOR_PROMTRAITS2(unsigned char, int, SIZE)\
+TINYVECTOR_PROMTRAITS2(int, float, SIZE)\
+TINYVECTOR_PROMTRAITS2(float, int, SIZE)\
+TINYVECTOR_PROMTRAITS2(double, unsigned char, SIZE)\
+TINYVECTOR_PROMTRAITS2(unsigned char, double, SIZE)\
+TINYVECTOR_PROMTRAITS2(int, double, SIZE)\
+TINYVECTOR_PROMTRAITS2(double, int, SIZE)\
+TINYVECTOR_PROMTRAITS2(double, float, SIZE)\
+TINYVECTOR_PROMTRAITS2(float, double, SIZE)
+
+TINYVECTOR_TRAITS(2)
+TINYVECTOR_TRAITS(3)
+TINYVECTOR_TRAITS(4)
+
+#undef TINYVECTOR_NUMTRAITS
+#undef TINYVECTOR_PROMTRAITS1
+#undef TINYVECTOR_PROMTRAITS2
+#undef TINYVECTOR_TRAITS
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+
+/********************************************************/
+/*                                                      */
+/*                      TinyVector-Arithmetic           */
+/*                                                      */
+/********************************************************/
+
+/** \addtogroup TinyVectorOperators
+ */
+//@{
+
+    /// component-wise addition
+template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
+inline
+typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
+operator+(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+          TinyVectorBase<V2, SIZE, D3, D4> const & r)
+{
+    return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) += r;
+}
+
+    /// component-wise subtraction
+template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
+inline
+typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
+operator-(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+          TinyVectorBase<V2, SIZE, D3, D4> const & r)
+{
+    return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) -= r;
+}
+
+    /// component-wise multiplication
+template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
+inline
+typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
+operator*(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+          TinyVectorBase<V2, SIZE, D3, D4> const & r)
+{
+    return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) *= r;
+}
+
+    /// component-wise division
+template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
+inline
+typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
+operator/(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+          TinyVectorBase<V2, SIZE, D3, D4> const & r)
+{
+    return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) /= r;
+}
+
+    /// component-wise modulo
+template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
+inline
+typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
+operator%(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+          TinyVectorBase<V2, SIZE, D3, D4> const & r)
+{
+    return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) %= r;
+}
+
+    /// component-wise left scalar multiplication
+template <class V, int SIZE, class D1, class D2>
+inline
+typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
+operator*(double v, TinyVectorBase<V, SIZE, D1, D2> const & r)
+{
+    return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(r) *= v;
+}
+
+    /// component-wise right scalar multiplication
+template <class V, int SIZE, class D1, class D2>
+inline
+typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
+operator*(TinyVectorBase<V, SIZE, D1, D2> const & l, double v)
+{
+    return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) *= v;
+}
+
+    /// component-wise scalar division
+template <class V, int SIZE, class D1, class D2>
+inline
+typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
+operator/(TinyVectorBase<V, SIZE, D1, D2> const & l, double v)
+{
+    return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) /= v;
+}
+
+    /// component-wise scalar division without type promotion
+template <class V, int SIZE, class D1, class D2>
+inline
+TinyVector<V, SIZE>
+div(TinyVectorBase<V, SIZE, D1, D2> const & l, V v)
+{
+    TinyVector<V, SIZE> result(l);
+    typedef typename detail::LoopType<SIZE>::type Loop;
+    Loop::divScalar(result.data(), v);
+    return result;
+}
+
+
+    /** Unary negation (construct TinyVector with negative values)
+    */
+template <class V, int SIZE, class D1, class D2>
+inline
+TinyVector<V, SIZE>
+operator-(TinyVectorBase<V, SIZE, D1, D2> const & v)
+{
+    TinyVector<V, SIZE> res(detail::dontInit());
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    ltype::neg(res.begin(), v.begin());
+    return res;
+}
+
+    /// component-wise absolute value
+template <class V, int SIZE, class D1, class D2>
+inline
+TinyVector<V, SIZE>
+abs(TinyVectorBase<V, SIZE, D1, D2> const & v)
+{
+    TinyVector<V, SIZE> res(detail::dontInit());
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    ltype::abs(res.begin(), v.begin());
+    return res;
+}
+
+    /** Apply ceil() function to each vector component.
+    */
+template <class V, int SIZE, class D1, class D2>
+inline
+TinyVector<V, SIZE>
+ceil(TinyVectorBase<V, SIZE, D1, D2> const & v)
+{
+    TinyVector<V, SIZE> res(detail::dontInit());
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    ltype::ceil(res.begin(), v.begin());
+    return res;
+}
+
+    /** Apply floor() function to each vector component.
+    */
+template <class V, int SIZE, class D1, class D2>
+inline
+TinyVector<V, SIZE>
+floor(TinyVectorBase<V, SIZE, D1, D2> const & v)
+{
+    TinyVector<V, SIZE> res(detail::dontInit());
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    ltype::floor(res.begin(), v.begin());
+    return res;
+}
+
+    /** Apply round() function to each vector component.
+    */
+template <class V, int SIZE, class D1, class D2>
+inline
+TinyVector<V, SIZE>
+round(TinyVectorBase<V, SIZE, D1, D2> const & v)
+{
+    TinyVector<V, SIZE> res(detail::dontInit());
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    ltype::round(res.begin(), v.begin());
+    return res;
+}
+
+    /** Apply sqrt() function to each vector component.
+    */
+template <class V, int SIZE, class D1, class D2>
+inline
+TinyVector<V, SIZE>
+sqrt(TinyVectorBase<V, SIZE, D1, D2> const & v)
+{
+    TinyVector<V, SIZE> res(detail::dontInit());
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    ltype::sqrt(res.begin(), v.begin());
+    return res;
+}
+
+using std::pow;
+
+    /** Apply pow() function to each vector component.
+    */
+template <class V, int SIZE, class D1, class D2, class E>
+inline
+TinyVector<V, SIZE>
+pow(TinyVectorBase<V, SIZE, D1, D2> const & v, E exponent)
+{
+    TinyVector<V, SIZE> res(v);
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    ltype::power(res.begin(), exponent);
+    return res;
+}
+
+    /// cross product
+template <class V1, class D1, class D2, class V2, class D3, class D4>
+inline
+TinyVector<typename PromoteTraits<V1, V2>::Promote, 3>
+cross(TinyVectorBase<V1, 3, D1, D2> const & r1,
+      TinyVectorBase<V2, 3, D3, D4> const & r2)
+{
+    typedef TinyVector<typename PromoteTraits<V1, V2>::Promote, 3>
+            Res;
+    return  Res(r1[1]*r2[2] - r1[2]*r2[1],
+                r1[2]*r2[0] - r1[0]*r2[2],
+                r1[0]*r2[1] - r1[1]*r2[0]);
+}
+
+    /// dot product
+template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
+inline
+typename PromoteTraits<V1, V2>::Promote
+dot(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+    TinyVectorBase<V2, SIZE, D3, D4> const & r)
+{
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    return ltype::dot(l.begin(), r.begin());
+}
+
+    /// sum of the vector's elements
+template <class V, int SIZE, class D1, class D2>
+inline
+typename NumericTraits<V>::Promote
+sum(TinyVectorBase<V, SIZE, D1, D2> const & l)
+{
+    typename NumericTraits<V>::Promote res = l[0];
+    for(int k=1; k<SIZE; ++k)
+        res += l[k];
+    return res;
+}
+
+    /// cumulative sum of the vector's elements
+template <class V, int SIZE, class D1, class D2>
+inline
+TinyVector<typename NumericTraits<V>::Promote, SIZE>
+cumsum(TinyVectorBase<V, SIZE, D1, D2> const & l)
+{
+    TinyVector<typename NumericTraits<V>::Promote, SIZE> res(l);
+    for(int k=1; k<SIZE; ++k)
+        res[k] += res[k-1];
+    return res;
+}
+
+    /// product of the vector's elements
+template <class V, int SIZE, class D1, class D2>
+inline
+typename NumericTraits<V>::Promote
+prod(TinyVectorBase<V, SIZE, D1, D2> const & l)
+{
+    typename NumericTraits<V>::Promote res = l[0];
+    for(int k=1; k<SIZE; ++k)
+        res *= l[k];
+    return res;
+}
+
+    /// cumulative product of the vector's elements
+template <class V, int SIZE, class D1, class D2>
+inline
+TinyVector<typename NumericTraits<V>::Promote, SIZE>
+cumprod(TinyVectorBase<V, SIZE, D1, D2> const & l)
+{
+    TinyVector<typename NumericTraits<V>::Promote, SIZE> res(l);
+    for(int k=1; k<SIZE; ++k)
+        res[k] *= res[k-1];
+    return res;
+}
+
+using std::min;
+
+    /// element-wise minimum
+template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
+inline
+TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE>
+min(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+    TinyVectorBase<V2, SIZE, D3, D4> const & r)
+{
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE> res(l);
+    ltype::min(res.begin(), r.begin());
+    return res;
+}
+
+// we also have to overload min for like-typed argument to prevent match of std::min()
+template <class V1, int SIZE, class D1, class D2>
+inline
+TinyVector<V1, SIZE>
+min(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+    TinyVectorBase<V1, SIZE, D1, D2> const & r)
+{
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    TinyVector<V1, SIZE> res(l);
+    ltype::min(res.begin(), r.begin());
+    return res;
+}
+
+template <class V1, int SIZE>
+inline
+TinyVector<V1, SIZE>
+min(TinyVector<V1, SIZE> const & l,
+    TinyVector<V1, SIZE> const & r)
+{
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    TinyVector<V1, SIZE> res(l);
+    ltype::min(res.begin(), r.begin());
+    return res;
+}
+
+    /// minimum element
+template <class V, int SIZE, class D1, class D2>
+inline
+V const &
+min(TinyVectorBase<V, SIZE, D1, D2> const & l)
+{
+    return l.minimum();
+}
+
+using std::max;
+
+    /// element-wise maximum
+template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
+inline
+TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE>
+max(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+    TinyVectorBase<V2, SIZE, D3, D4> const & r)
+{
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE> res(l);
+    ltype::max(res.begin(), r.begin());
+    return res;
+}
+
+// we also have to overload max for like-typed argument to prevent match of std::max()
+template <class V1, int SIZE, class D1, class D2>
+inline
+TinyVector<V1, SIZE>
+max(TinyVectorBase<V1, SIZE, D1, D2> const & l,
+    TinyVectorBase<V1, SIZE, D1, D2> const & r)
+{
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    TinyVector<V1, SIZE> res(l);
+    ltype::max(res.begin(), r.begin());
+    return res;
+}
+
+template <class V1, int SIZE>
+inline
+TinyVector<V1, SIZE>
+max(TinyVector<V1, SIZE> const & l,
+    TinyVector<V1, SIZE> const & r)
+{
+    typedef typename detail::LoopType<SIZE>::type ltype;
+    TinyVector<V1, SIZE> res(l);
+    ltype::max(res.begin(), r.begin());
+    return res;
+}
+
+    /// maximum element
+template <class V, int SIZE, class D1, class D2>
+inline
+V const &
+max(TinyVectorBase<V, SIZE, D1, D2> const & l)
+{
+    return l.maximum();
+}
+
+    /// squared norm
+template <class V1, int SIZE, class D1, class D2>
+inline
+typename TinyVectorBase<V1, SIZE, D1, D2>::SquaredNormType
+squaredNorm(TinyVectorBase<V1, SIZE, D1, D2> const & t)
+{
+    return t.squaredMagnitude();
+}
+
+    /// squared norm
+template <class V, int SIZE>
+inline
+typename TinyVector<V, SIZE>::SquaredNormType
+squaredNorm(TinyVector<V, SIZE> const & t)
+{
+    return t.squaredMagnitude();
+}
+
+using std::reverse;
+
+    /// reversed copy
+template <class V, int SIZE>
+inline
+TinyVector<V, SIZE>
+reverse(TinyVector<V, SIZE> const & t)
+{
+    return TinyVector<V, SIZE>(t.begin(), TinyVector<V, SIZE>::ReverseCopy);
+}
+
+//@}
+
+// mask cl.exe shortcomings [end]
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+} // namespace vigra
+#undef VIGRA_ASSERT_INSIDE
+#endif // VIGRA_TINYVECTOR_HXX
diff --git a/include/vigra/transformimage.hxx b/include/vigra/transformimage.hxx
new file mode 100644
index 0000000..f584b94
--- /dev/null
+++ b/include/vigra/transformimage.hxx
@@ -0,0 +1,1664 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_TRANSFORMIMAGE_HXX
+#define VIGRA_TRANSFORMIMAGE_HXX
+
+#include "utilities.hxx"
+#include "numerictraits.hxx"
+#include "iteratortraits.hxx"
+#include "rgbvalue.hxx"
+#include "functortraits.hxx"
+#include "inspectimage.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+/** \addtogroup TransformAlgo Algorithms to Transform Images
+    Apply functor to calculate a pixelwise transformation of one image
+
+    @{
+*/
+
+/********************************************************/
+/*                                                      */
+/*                      transformLine                   */
+/*                                                      */
+/********************************************************/
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor, class Functor>
+void
+transformLine(SrcIterator s,
+              SrcIterator send, SrcAccessor src,
+              DestIterator d, DestAccessor dest,
+              Functor const & f)
+{
+    for(; s != send; ++s, ++d)
+        dest.set(f(src(s)), d);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class MaskIterator, class MaskAccessor,
+          class DestIterator, class DestAccessor,
+          class Functor>
+void
+transformLineIf(SrcIterator s,
+                SrcIterator send, SrcAccessor src,
+                MaskIterator m, MaskAccessor mask,
+                DestIterator d, DestAccessor dest,
+                Functor const & f)
+{
+    for(; s != send; ++s, ++d, ++m)
+        if(mask(m))
+            dest.set(f(src(s)), d);
+}
+
+/********************************************************/
+/*                                                      */
+/*                      transformImage                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply unary point transformation to each pixel.
+
+    After the introduction of arithmetic and algebraic \ref MultiMathModule "array experessions",
+    this function is rarely needed. Moreover, \ref transformMultiArray() provides the 
+    same functionality for arbitrary dimensional arrays.
+
+    The transformation given by the functor is applied to every source
+    pixel and the result written into the corresponding destination pixel.
+    Note that the unary functors of the STL can be used in addition to
+    the functors specifically defined in \ref TransformFunctor.
+    Creation of new functors is easiest by using \ref FunctorExpressions.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+              class T2, class S2, class Functor>
+        void
+        transformImage(MultiArrayView<2, T1, S1> const & src,
+                       MultiArrayView<2, T2, S2> dest,
+                       Functor const & f);
+    }
+    \endcode
+
+    \deprecatedAPI{transformImage}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor, class Functor>
+        void
+        transformImage(SrcImageIterator src_upperleft,
+               SrcImageIterator src_lowerright, SrcAccessor sa,
+               DestImageIterator dest_upperleft, DestAccessor da,
+               Functor const & f)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor, class Functor>
+        void
+        transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+               pair<DestImageIterator, DestAccessor> dest,
+               Functor const & f)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/transformimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    #include <cmath>         // for sqrt()
+    MultiArray<2, float>  src(100, 200),
+                          dest(100, 200);
+    ...
+    
+    transformImage(src, dest, &std::sqrt );
+    \endcode
+
+    \deprecatedUsage{transformImage}
+    \code
+    #include <cmath>         // for sqrt()
+    FImage  src(100, 200),
+            dest(100, 200);
+
+    vigra::transformImage(srcImageRange(src),
+                          destImage(dest),
+                          (double(*)(double))&std::sqrt );
+
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator      dest_upperleft;
+    SrcImageIterator::row_iterator sx = src_upperleft.rowIterator();
+    DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    Functor functor;
+
+    dest_accessor.set(functor(src_accessor(sx)), dx);
+
+    \endcode
+    \deprecatedEnd
+    
+    \see TransformFunctor, MultiMathModule, \ref FunctorExpressions
+*/
+doxygen_overloaded_function(template <...> void transformImage)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor, class Functor>
+void
+transformImage(SrcImageIterator src_upperleft,
+               SrcImageIterator src_lowerright, SrcAccessor sa,
+               DestImageIterator dest_upperleft, DestAccessor da,
+               Functor const & f)
+{
+    int w = src_lowerright.x - src_upperleft.x;
+
+    for(; src_upperleft.y < src_lowerright.y; ++src_upperleft.y, ++dest_upperleft.y)
+    {
+        transformLine(src_upperleft.rowIterator(),
+                      src_upperleft.rowIterator() + w, sa,
+                      dest_upperleft.rowIterator(), da, f);
+    }
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+      class DestImageIterator, class DestAccessor, class Functor>
+inline void
+transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+               pair<DestImageIterator, DestAccessor> dest,
+               Functor const & f)
+{
+    transformImage(src.first, src.second, src.third,
+                   dest.first, dest.second, f);
+}
+
+template <class T1, class S1,
+      class T2, class S2, class Functor>
+inline void
+transformImage(MultiArrayView<2, T1, S1> const & src,
+               MultiArrayView<2, T2, S2> dest,
+               Functor const & f)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "transformImage(): shape mismatch between input and output.");
+    transformImage(srcImageRange(src),
+                   destImage(dest), f);
+}
+
+/********************************************************/
+/*                                                      */
+/*                   transformImageIf                   */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply unary point transformation to each pixel within the ROI
+    (i.e., where the mask is non-zero).
+
+    After the introduction of arithmetic and algebraic \ref MultiMathModule "array experessions",
+    this function is rarely needed. Moreover, \ref combineTwoMultiArrays() provides the 
+    same functionality for arbitrary dimensional arrays.
+
+    The transformation given by the functor is applied to every source
+    pixel in the ROI (i.e. when the return value of the mask's accessor
+    is not zero)
+    and the result is written into the corresponding destination pixel.
+    The function uses accessors to access the pixel data.
+    Note that the unary functors of the STL can be used in addition to
+    the functors specifically defined in \ref TransformFunctor.
+    Creation of new functors is easiest by using \ref FunctorExpressions.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class TM, class SM,
+                  class T2, class S2,
+                  class Functor>
+        void
+        transformImageIf(MultiArrayView<2, T1, S1> const & src,
+                         MultiArrayView<2, TM, SM> const & mask,
+                         MultiArrayView<2, T2, S2> dest,
+                         Functor const & f);
+    }
+    \endcode
+
+    \deprecatedAPI{transformImageIf}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class MaskImageIterator, class MaskAccessor,
+                  class DestImageIterator, clas DestAccessor,
+                  class Functor>
+        void
+        transformImageIf(SrcImageIterator src_upperleft,
+                         SrcImageIterator src_lowerright, SrcAccessor sa,
+                         MaskImageIterator mask_upperleft, MaskAccessor ma,
+                         DestImageIterator dest_upperleft, DestAccessor da,
+                         Functor const & f)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class MaskImageIterator, class MaskAccessor,
+                  class DestImageIterator, clas DestAccessor,
+                  class Functor>
+        void
+        transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                         pair<MaskImageIterator, MaskAccessor> mask,
+                         pair<DestImageIterator, DestAccessor> dest,
+                         Functor const & f)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/transformimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    #include <cmath>         // for sqrt()
+    
+    MultiArray<2, unsigned char>  mask(100, 200),
+    MultiArray<2, float>          src(100, 200),
+                                  dest(100, 200);
+    ... // fill src and mask
+    
+    transformImageIf(src, mask, dest, &std::sqrt );
+    \endcode
+
+    \deprecatedUsage{transformImageIf}
+    \code
+    #include <cmath>         // for sqrt()
+
+    vigra::transformImageIf(srcImageRange(src),
+                            maskImage(mask),
+                            destImage(dest),
+                            (double(*)(double))&std::sqrt );
+
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator src_upperleft, src_lowerright;
+    DestImageIterator  dest_upperleft;
+    MaskImageIterator mask_upperleft;
+    SrcImageIterator::row_iterator sx = src_upperleft.rowIterator();
+    MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator();
+    DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    MaskAccessor mask_accessor;
+    Functor functor;
+
+    if(mask_accessor(mx))
+       dest_accessor.set(functor(src_accessor(sx)), dx);
+
+    \endcode
+    \deprecatedEnd
+    
+    \see TransformFunctor, MultiMathModule, \ref FunctorExpressions
+*/
+doxygen_overloaded_function(template <...> void transformImageIf)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class MaskImageIterator, class MaskAccessor,
+          class DestImageIterator, class DestAccessor,
+          class Functor>
+void
+transformImageIf(SrcImageIterator src_upperleft,
+                 SrcImageIterator src_lowerright, SrcAccessor sa,
+                 MaskImageIterator mask_upperleft, MaskAccessor ma,
+                 DestImageIterator dest_upperleft, DestAccessor da,
+                 Functor const & f)
+{
+    int w = src_lowerright.x - src_upperleft.x;
+
+    for(; src_upperleft.y < src_lowerright.y;
+             ++src_upperleft.y, ++mask_upperleft.y, ++dest_upperleft.y)
+    {
+        transformLineIf(src_upperleft.rowIterator(),
+                        src_upperleft.rowIterator() + w, sa,
+                        mask_upperleft.rowIterator(), ma,
+                        dest_upperleft.rowIterator(), da, f);
+    }
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class MaskImageIterator, class MaskAccessor,
+          class DestImageIterator, class DestAccessor,
+          class Functor>
+inline void
+transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                 pair<MaskImageIterator, MaskAccessor> mask,
+                 pair<DestImageIterator, DestAccessor> dest,
+                 Functor const & f)
+{
+    transformImageIf(src.first, src.second, src.third,
+                     mask.first, mask.second,
+                     dest.first, dest.second, f);
+}
+
+template <class T1, class S1,
+          class TM, class SM,
+          class T2, class S2,
+          class Functor>
+inline void
+transformImageIf(MultiArrayView<2, T1, S1> const & src,
+                 MultiArrayView<2, TM, SM> const & mask,
+                 MultiArrayView<2, T2, S2> dest,
+                 Functor const & f)
+{
+    vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
+        "transformImageIf(): shape mismatch between input and output.");
+    transformImageIf(srcImageRange(src),
+                     maskImage(mask),
+                     destImage(dest), f);
+}
+
+/********************************************************/
+/*                                                      */
+/*               gradientBasedTransform                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Calculate a function of the image gradient.
+
+    The gradient and the function represented by <TT>Functor f</TT>
+    are calculated in one go: for each location, the symmetric
+    difference in x- and y-directions (asymmetric difference at the
+    image borders) are passed to the given functor, and the result is
+    written to the destination image. Functors to be used with this
+    function include \ref MagnitudeFunctor and \ref
+    RGBGradientMagnitudeFunctor.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2, 
+                  class Functor>
+        void
+        gradientBasedTransform(MultiArrayView<2, T1, S1> const & src,
+                               MultiArrayView<2, T2, S2> dest, 
+                               Functor const & grad);
+    }
+    \endcode
+
+    \deprecatedAPI{gradientBasedTransform}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor, class Functor>
+        void
+        gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor sa,
+                               DestImageIterator destul, DestAccessor da, Functor const & f)
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcImageIterator, class SrcAccessor,
+                  class DestImageIterator, class DestAccessor, class Functor>
+        void
+        gradientBasedTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                               pair<DestImageIterator, DestAccessor> dest, Functor const & const & f)
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/transformimage.hxx\><br/>
+    Namespace: vigra
+
+    \code
+    MultiArray<2, float> src(w,h), magnitude(w,h);
+    ...
+
+    gradientBasedTransform(src, magnitude,
+                           MagnitudeFunctor<float>());
+    \endcode
+
+    \deprecatedUsage{gradientBasedTransform}
+    \code
+    vigra::FImage src(w,h), magnitude(w,h);
+    ...
+
+    gradientBasedTransform(srcImageRange(src), destImage(magnitude),
+                                vigra::MagnitudeFunctor<float>());
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcImageIterator is, isend;
+    DestImageIterator id;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    typename NumericTraits<typename SrcAccessor::value_type>::RealPromote
+        diffx, diffy;
+
+    diffx = src_accessor(is, Diff2D(-1,0)) - src_accessor(is, Diff2D(1,0));
+    diffy = src_accessor(is, Diff2D(0,-1)) - src_accessor(is, Diff2D(0,1));
+
+    Functor f;
+
+    dest_accessor.set(f(diffx, diffy), id);
+
+    \endcode
+    \deprecatedEnd
+    
+    \see TransformFunctor, MultiMathModule, \ref FunctorExpressions
+*/
+doxygen_overloaded_function(template <...> void gradientBasedTransform)
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor, class Functor>
+void
+gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor sa,
+                       DestImageIterator destul, DestAccessor da, Functor const & grad)
+{
+    int w = srclr.x - srcul.x;
+    int h = srclr.y - srcul.y;
+    int x,y;
+
+    SrcImageIterator sy = srcul;
+    DestImageIterator dy = destul;
+
+    const Diff2D left(-1,0);
+    const Diff2D right(1,0);
+    const Diff2D top(0,-1);
+    const Diff2D bottom(0,1);
+
+    typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
+    TmpType diffx, diffy;
+
+    SrcImageIterator sx = sy;
+    DestImageIterator dx = dy;
+
+    diffx = sa(sx) - sa(sx, right);
+    diffy = sa(sx) - sa(sx, bottom);
+    da.set(grad(diffx, diffy), dx);
+
+    for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
+    {
+        diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
+        diffy = sa(sx) - sa(sx, bottom);
+        da.set(grad(diffx, diffy), dx);
+    }
+
+    diffx = sa(sx, left) - sa(sx);
+    diffy = sa(sx) - sa(sx, bottom);
+    da.set(grad(diffx, diffy), dx);
+
+    ++sy.y;
+    ++dy.y;
+
+    for(y=2; y<h; ++y, ++sy.y, ++dy.y)
+    {
+        sx = sy;
+        dx = dy;
+
+        diffx = sa(sx) - sa(sx, right);
+        diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
+        da.set(grad(diffx, diffy), dx);
+
+        for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
+        {
+            diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
+            diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
+            da.set(grad(diffx, diffy), dx);
+        }
+
+        diffx = sa(sx, left) - sa(sx);
+        diffy = (sa(sx, top) - sa(sx, bottom)) / TmpType(2.0);
+        da.set(grad(diffx, diffy), dx);
+    }
+
+    sx = sy;
+    dx = dy;
+
+    diffx = sa(sx) - sa(sx, right);
+    diffy = sa(sx, top) - sa(sx);
+    da.set(grad(diffx, diffy), dx);
+
+    for(x=2, ++sx.x, ++dx.x; x<w; ++x, ++sx.x, ++dx.x)
+    {
+        diffx = (sa(sx, left) - sa(sx, right)) / TmpType(2.0);
+        diffy = sa(sx, top) - sa(sx);
+        da.set(grad(diffx, diffy), dx);
+    }
+
+    diffx = sa(sx, left) - sa(sx);
+    diffy = sa(sx, top) - sa(sx);
+    da.set(grad(diffx, diffy), dx);
+}
+
+template <class SrcImageIterator, class SrcAccessor,
+          class DestImageIterator, class DestAccessor, class Functor>
+inline void
+gradientBasedTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
+                       pair<DestImageIterator, DestAccessor> dest, Functor const & grad)
+{
+    gradientBasedTransform(src.first, src.second, src.third,
+                           dest.first, dest.second, grad);
+}
+
+template <class T1, class S1,
+          class T2, class S2, class Functor>
+inline void
+gradientBasedTransform(MultiArrayView<2, T1, S1> const & src,
+                       MultiArrayView<2, T2, S2> dest, Functor const & grad)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "gradientBasedTransform(): shape mismatch between input and output.");
+    gradientBasedTransform(srcImageRange(src),
+                           destImage(dest), grad);
+}
+
+/** @} */
+/** \addtogroup TransformFunctor Functors to Transform Images
+
+    Note that the unary functors of the STL can also be used in
+    connection with \ref transformImage().
+*/
+//@{
+
+template <class DestValueType, class Multiplier = double>
+class LinearIntensityTransform
+{
+  public:
+        /* the functors argument type (actually, since
+           <tt>operator()</tt> is a template, much more types are possible)
+        */
+    typedef DestValueType argument_type;
+
+        /* the functors result type
+        */
+    typedef DestValueType result_type;
+
+        /* \deprecated use argument_type and result_type
+        */
+    typedef DestValueType value_type;
+
+        /* type of the offset (used in internal calculations to prevent
+            overflows and minimize round-off errors).
+        */
+    typedef typename
+            NumericTraits<DestValueType>::RealPromote argument_promote;
+
+        /* type of the scale factor
+        */
+    typedef Multiplier scalar_multiplier_type;
+
+        /* init scale and offset
+        */
+    LinearIntensityTransform(scalar_multiplier_type scale, argument_promote offset)
+    : scale_(scale), offset_(offset)
+    {}
+
+        /* calculate transform
+        */
+    template <class SrcValueType>
+    result_type operator()(SrcValueType const & s) const
+    {
+        return NumericTraits<result_type>::fromRealPromote(scale_ * (s + offset_));
+    }
+
+  private:
+
+    scalar_multiplier_type scale_;
+    argument_promote offset_;
+};
+
+template <class DestValueType, class Multiplier>
+class FunctorTraits<LinearIntensityTransform<DestValueType, Multiplier> >
+: public FunctorTraitsBase<LinearIntensityTransform<DestValueType, Multiplier> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+template <class DestValueType, class Multiplier = double>
+class ScalarIntensityTransform
+{
+  public:
+        /* the functors argument type (actually, since
+           <tt>operator()</tt> is a template, much more types are possible)
+        */
+    typedef DestValueType argument_type;
+
+        /* the functors result type
+        */
+    typedef DestValueType result_type;
+
+        /* \deprecated use argument_type and result_type
+        */
+    typedef DestValueType value_type;
+
+        /* type of the scale factor
+        */
+    typedef Multiplier scalar_multiplier_type;
+
+        /* init scale
+        */
+    ScalarIntensityTransform(scalar_multiplier_type scale)
+    : scale_(scale)
+    {}
+
+        /* calculate transform
+        */
+    template <class SrcValueType>
+    result_type operator()(SrcValueType const & s) const
+    {
+        return NumericTraits<result_type>::fromRealPromote(scale_ * s);
+    }
+
+  private:
+    scalar_multiplier_type scale_;
+};
+
+template <class DestValueType, class Multiplier>
+class FunctorTraits<ScalarIntensityTransform<DestValueType, Multiplier> >
+: public FunctorTraitsBase<ScalarIntensityTransform<DestValueType, Multiplier> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/********************************************************/
+/*                                                      */
+/*              linearIntensityTransform                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Apply a linear transform to the source pixel values
+
+    Factory function for a functor that linearly transforms the
+    source pixel values. The functor applies the transform
+    '<TT>destvalue = scale * (srcvalue + offset)</TT>' to every pixel.
+    This can, for example, be used to transform images into the visible
+    range 0...255 or to invert an image.
+
+    If you leave out the second parameter / offset, you will get an
+    optimized version of the functor which only scales by the given
+    factor, however you have to make the template parameter (pixel
+    type) explicit then.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+
+    <b> Declaration:</b>
+
+    \code
+    namespace vigra {
+        template <class Multiplier, class DestValueType>
+        LinearIntensityTransform<DestValueType, Multiplier>
+        linearIntensityTransform(Multiplier scale, DestValueType offset);
+
+        template <class DestValueType, class Multiplier>
+        ScalarIntensityTransform<DestValueType, Multiplier>
+        linearIntensityTransform(Multiplier scale);
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/transformimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::IImage src(width, height);
+    vigra::BImage dest(width, height);
+    ...
+    vigra::FindMinMax<IImage::PixelType> minmax;   // functor to find range
+
+    vigra::inspectImage(srcImageRange(src), minmax); // find original range
+
+    // transform to range 0...255
+    vigra::transformImage(srcImageRange(src), destImage(dest),
+                          linearIntensityTransform(
+                            255.0 / (minmax.max - minmax.min), // scaling
+                          - minmax.min));                    // offset
+    \endcode
+
+    The one-parameter version can be used like this:
+
+    \code
+    // scale from 0..255 to 0..1.0
+    FImage dest(src.size());
+
+    vigra::transformImage(srcImageRange(src), destImage(dest),
+                          linearIntensityTransform<float>(1.0 / 255));
+    \endcode
+
+    <b> Required Interface:</b>
+
+    The source and destination value types must be models of \ref LinearSpace in both cases.
+
+*/
+template <class Multiplier, class DestValueType>
+LinearIntensityTransform<DestValueType, Multiplier>
+linearIntensityTransform(Multiplier scale, DestValueType offset)
+{
+    return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset);
+}
+
+template <class DestValueType, class Multiplier>
+ScalarIntensityTransform<DestValueType, Multiplier>
+linearIntensityTransform(Multiplier scale)
+{
+    return ScalarIntensityTransform<DestValueType, Multiplier>(scale);
+}
+
+/********************************************************/
+/*                                                      */
+/*                   linearRangeMapping                 */
+/*                                                      */
+/********************************************************/
+
+/** \brief Map a source intensity range linearly to a destination range.
+
+    Factory function for a functor that linearly transforms the
+    source pixel values. The functor applies the transform
+    '<TT>destvalue = scale * (srcvalue + offset)</TT>' to every pixel,
+    where <tt>scale = (dest_max - dest_min) / (src_max - src_min)</tt>
+    and <tt>offset = dest_min / scale - src_min</tt>. As a result,
+    the pixel values <tt>src_max</tt>, <tt>src_min</tt> in the source image
+    are mapped onto <tt>dest_max</tt>, <tt>dest_min</tt> respectively.
+    This works for scalar as well as vector pixel types. Instead of 
+    <tt>src_min</tt> and <tt>src_max</tt>, you may also pass a functor
+    \ref FindMinMax. 
+
+    <b> Declaration:</b>
+
+    \code
+    namespace vigra {
+        template <class SrcValueType, class DestValueType>
+        LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
+        linearRangeMapping(SrcValueType src_min, SrcValueType src_max,
+                           DestValueType dest_min, DestValueType dest_max );
+
+                           template <class SrcValueType, class DestValueType>
+        LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
+        linearRangeMapping(SrcValueType src_min, SrcValueType src_max,
+                           DestValueType dest_min, DestValueType dest_max );
+    }
+    \endcode
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/transformimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::IImage src(width, height);
+    vigra::BImage dest(width, height);
+    ...
+    vigra::FindMinMax<IImage::PixelType> minmax;   // functor to find range
+
+    vigra::inspectImage(srcImageRange(src), minmax); // find original range
+
+    // transform to range 0...255
+    vigra::transformImage(srcImageRange(src), destImage(dest),
+                          linearRangeMapping(
+                            minmax.min, minmax.max,  // src range
+                            0, 255)                  // dest range
+                          );
+
+    // equivalent, but shorter
+    vigra::transformImage(srcImageRange(src), destImage(dest),
+                          linearRangeMapping(
+                            minmax,                 // src range
+                            0, 255)                 // dest range
+                          );
+    \endcode
+
+    <b> Required Interface:</b>
+
+    The source and destination value types must be models of \ref LinearSpace in both cases.
+
+*/
+template <class SrcValueType, class DestValueType>
+LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
+linearRangeMapping(SrcValueType src_min, SrcValueType src_max,
+                   DestValueType dest_min, DestValueType dest_max )
+{
+    return linearRangeMapping(src_min, src_max, dest_min, dest_max,
+            typename NumericTraits<DestValueType>::isScalar());
+}
+
+template <class SrcValueType, class DestValueType>
+LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
+linearRangeMapping(FindMinMax<SrcValueType> const & src,
+                   DestValueType dest_min, DestValueType dest_max )
+{
+    return linearRangeMapping(src.min, src.max, dest_min, dest_max,
+            typename NumericTraits<DestValueType>::isScalar());
+}
+
+template <class SrcValueType, class DestValueType>
+LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
+linearRangeMapping(
+    SrcValueType src_min, SrcValueType src_max,
+    DestValueType dest_min, DestValueType dest_max,
+    VigraTrueType /* isScalar */ )
+{
+    typedef typename NumericTraits<DestValueType>::RealPromote Multiplier;
+    Multiplier diff = src_max - src_min;
+    Multiplier scale = diff == NumericTraits<Multiplier>::zero()
+                     ? NumericTraits<Multiplier>::one()
+                     : (dest_max - dest_min) / diff;
+    return LinearIntensityTransform<DestValueType, Multiplier>(
+                                   scale, dest_min / scale - src_min );
+}
+
+template <class SrcValueType, class DestValueType>
+LinearIntensityTransform<DestValueType, typename NumericTraits<DestValueType>::RealPromote>
+linearRangeMapping(
+    SrcValueType src_min, SrcValueType src_max,
+    DestValueType dest_min, DestValueType dest_max,
+    VigraFalseType /* isScalar */ )
+{
+    typedef typename NumericTraits<DestValueType>::RealPromote Multiplier;
+    typedef typename Multiplier::value_type MComponent;
+    Multiplier scale(dest_max), offset(dest_max);
+    for(unsigned int i=0; i<src_min.size(); ++i)
+    {
+        MComponent diff = src_max[i] - src_min[i];
+        scale[i] = diff == NumericTraits<MComponent>::zero()
+                     ? NumericTraits<MComponent>::one()
+                     : (dest_max[i] - dest_min[i]) / diff;
+        offset[i] = dest_min[i] / scale[i] - src_min[i];
+    }
+    return LinearIntensityTransform<DestValueType, Multiplier>(scale, offset);
+}
+
+/********************************************************/
+/*                                                      */
+/*                      Threshold                       */
+/*                                                      */
+/********************************************************/
+
+/** \brief Threshold an image.
+
+    If a source pixel is above or equal the lower and below
+    or equal the higher threshold (i.e. within the closed interval
+    [lower, higher]) the destination pixel is set to 'yesresult',
+    otherwise to 'noresult'.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/transformimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage src(width, height), dest(width, height);
+    ...
+    vigra::transformImage(src.upperLeft(), src.lowerRight(), src.accessor(),
+       dest.upperLeft(), dest.accessor(),
+       vigra::Threshold<
+          vigra::BImage::PixelType, vigra::BImage::PixelType>(10, 100, 0, 255));
+
+    \endcode
+
+    <b> Required Interface:</b>
+
+    \code
+
+    SrcValueType   src;
+    DestValueType  dest, yesresult, noresult;
+
+    dest = ((src < lower) || (higher < src)) ? noresult : yesresult;
+
+    \endcode
+
+*/
+template <class SrcValueType, class DestValueType>
+class Threshold
+{
+   public:
+
+        /** the functor's argument type
+        */
+    typedef SrcValueType argument_type;
+
+        /** the functor's result type
+        */
+    typedef DestValueType result_type;
+
+        /** init thresholds and return values
+        */
+    Threshold(argument_type lower, argument_type higher,
+              result_type noresult, result_type yesresult)
+    : lower_(lower), higher_(higher),
+      yesresult_(yesresult), noresult_(noresult)
+    {}
+
+        /** calculate transform
+        */
+    result_type operator()(argument_type s) const
+    {
+        return ((s < lower_) || (higher_ < s)) ? noresult_ : yesresult_;
+    }
+
+  private:
+
+    argument_type lower_, higher_;
+    result_type yesresult_, noresult_;
+};
+
+template <class SrcValueType, class DestValueType>
+class FunctorTraits<Threshold<SrcValueType, DestValueType> >
+: public FunctorTraitsBase<Threshold<SrcValueType, DestValueType> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/********************************************************/
+/*                                                      */
+/*                BrightnessContrastFunctor             */
+/*                                                      */
+/********************************************************/
+
+/** \brief Adjust brightness and contrast of an image.
+
+    This functor applies a gamma correction to each pixel in order to
+    modify the brightness of the image. To the result of the gamma
+    correction, another transform is applied that modifies the
+    contrast. The brightness and contrast parameters must be
+    positive. Values greater than 1 will increase image brightness or
+    contrast respectively, values smaller than 1 decrease them.  A
+    value of exactly 1 will have no effect.  If contrast is set to 1,
+    the result is equivalent to that of the GammaFunctor with gamma =
+    1./brightness.
+
+    For \ref RGBValue "RGBValue's", the transforms are applied
+    component-wise. The pixel values are assumed to lie between the
+    given minimum and maximum values (in case of RGB, this is again
+    understood component-wise). In case of <TT>unsigned char</TT>, min
+    and max default to 0 and 255 respectively.  Precisely, the
+    following transform is applied to each <em> PixelValue</em>:
+
+    \f[
+    \begin{array}{rcl}
+    V_1 & = & \frac{PixelValue - min}{max - min} \\
+    V_2 & = & V_1^\frac{1}{brightness} \\
+    V_3 & = & 2 V_2 - 1 \\
+    V_4 & = & \left\lbrace
+        \begin{array}{l}
+         V_3^\frac{1}{contrast} \mbox{\rm \quad if  } V_3 \ge 0 \\
+         - (-V_3)^\frac{1}{contrast} \mbox{\rm \quad otherwise}
+        \end{array} \right. \\
+    Result & = & \frac{V_4 + 1}{2} (max - min) + min
+    \end{array}
+    \f]
+
+    If the <TT>PixelType</TT> is <TT>unsigned char</TT>, a look-up-table is used
+    for faster computation.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/transformimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage bimage(width, height);
+    double brightness, contrast;
+    ...
+    vigra::transformImage(srcImageRange(bimage), destImage(bimage),
+       vigra::BrightnessContrastFunctor<unsigned char>(brightness, contrast));
+
+
+
+    vigra::FImage fimage(width, height);
+    ...
+
+    vigra::FindMinMax<float> minmax;
+    vigra::inspectImage(srcImageRange(fimage), minmax);
+
+    vigra::transformImage(srcImageRange(fimage), destImage(fimage),
+       vigra::BrightnessContrastFunctor<float>(brightness, contrast, minmax.min, minmax.max));
+
+
+    \endcode
+
+    <b> Required Interface:</b>
+
+    Scalar types: must be a linear algebra (+, - *, NumericTraits),
+    strict weakly ordered (<), and <TT>pow()</TT> must be defined.
+
+    RGB values: the component type must meet the above requirements.
+*/
+template <class PixelType>
+class BrightnessContrastFunctor
+{
+    typedef typename
+        NumericTraits<PixelType>::RealPromote promote_type;
+
+ public:
+
+        /** the functor's argument type
+        */
+    typedef PixelType argument_type;
+
+        /** the functor's result type
+        */
+    typedef PixelType result_type;
+
+        /** \deprecated use argument_type and result_type
+        */
+    typedef PixelType value_type;
+
+        /** Init functor for argument range <TT>[min, max]</TT>.
+            <TT>brightness</TT> and <TT>contrast</TT> values > 1 will
+            increase brightness and contrast, < 1 will decrease them, and == 1 means
+            no change.
+        */
+    BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
+                              argument_type const & min, argument_type const & max)
+    : b_(1.0/brightness),
+      c_(1.0/contrast),
+      min_(min),
+      diff_(max - min),
+      zero_(NumericTraits<promote_type>::zero()),
+      one_(NumericTraits<promote_type>::one())
+    {}
+
+        /** Calculate modified gray or color value
+        */
+    result_type operator()(argument_type const & v) const
+    {
+        promote_type v1 = (v - min_) / diff_;
+        promote_type brighter = VIGRA_CSTD::pow(v1, b_);
+        promote_type v2 = 2.0 * brighter - one_;
+        promote_type contrasted = (v2 < zero_) ?
+                                     -VIGRA_CSTD::pow(-v2, c_) :
+                                      VIGRA_CSTD::pow(v2, c_);
+        return result_type(0.5 * diff_ * (contrasted + one_) + min_);
+    }
+
+  private:
+    promote_type b_, c_;
+    argument_type min_;
+    promote_type diff_, zero_, one_;
+};
+
+template <>
+class BrightnessContrastFunctor<unsigned char>
+{
+    typedef NumericTraits<unsigned char>::RealPromote promote_type;
+     unsigned char lut[256];
+
+ public:
+
+    typedef unsigned char value_type;
+
+    BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
+                              value_type const & min = 0, value_type const & max = 255)
+    {
+        BrightnessContrastFunctor<promote_type> f(brightness, contrast, min, max);
+
+        for(int i = min; i <= max; ++i)
+        {
+            lut[i] = static_cast<unsigned char>(f(i)+0.5);
+        }
+    }
+
+    value_type operator()(value_type const & v) const
+    {
+
+        return lut[v];
+    }
+};
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class ComponentType>
+class BrightnessContrastFunctor<RGBValue<ComponentType> >
+{
+    typedef typename
+        NumericTraits<ComponentType>::RealPromote promote_type;
+    BrightnessContrastFunctor<ComponentType> red, green, blue;
+
+ public:
+
+    typedef RGBValue<ComponentType> value_type;
+
+    BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
+                              value_type const & min, value_type const & max)
+    : red(brightness, contrast, min.red(), max.red()),
+      green(brightness, contrast, min.green(), max.green()),
+      blue(brightness, contrast, min.blue(), max.blue())
+    {}
+
+    value_type operator()(value_type const & v) const
+    {
+
+        return value_type(red(v.red()), green(v.green()), blue(v.blue()));
+    }
+};
+
+#else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <>
+class BrightnessContrastFunctor<RGBValue<int> >
+{
+    typedef NumericTraits<int>::RealPromote promote_type;
+    BrightnessContrastFunctor<int> red, green, blue;
+
+ public:
+
+    typedef RGBValue<int> value_type;
+
+    BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
+                              value_type const & min, value_type const & max)
+    : red(brightness, contrast, min.red(), max.red()),
+      green(brightness, contrast, min.green(), max.green()),
+      blue(brightness, contrast, min.blue(), max.blue())
+    {}
+
+    value_type operator()(value_type const & v) const
+    {
+
+        return value_type(red(v.red()), green(v.green()), blue(v.blue()));
+    }
+};
+
+template <>
+class BrightnessContrastFunctor<RGBValue<float> >
+{
+    typedef NumericTraits<float>::RealPromote promote_type;
+    BrightnessContrastFunctor<float> red, green, blue;
+
+ public:
+
+    typedef RGBValue<float> value_type;
+
+    BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
+                              value_type const & min, value_type const & max)
+    : red(brightness, contrast, min.red(), max.red()),
+      green(brightness, contrast, min.green(), max.green()),
+      blue(brightness, contrast, min.blue(), max.blue())
+    {}
+
+    value_type operator()(value_type const & v) const
+    {
+
+        return value_type(red(v.red()), green(v.green()), blue(v.blue()));
+    }
+};
+
+template <class PixelType>
+class FunctorTraits<BrightnessContrastFunctor<PixelType> >
+: public FunctorTraitsBase<BrightnessContrastFunctor<PixelType> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <>
+class BrightnessContrastFunctor<RGBValue<unsigned char> >
+{
+    typedef NumericTraits<unsigned char>::RealPromote promote_type;
+    BrightnessContrastFunctor<unsigned char> red, green, blue;
+
+ public:
+
+    typedef RGBValue<unsigned char> value_type;
+
+    BrightnessContrastFunctor(promote_type brightness, promote_type contrast,
+       value_type const & min = value_type(0,0,0),
+       value_type const & max = value_type(255, 255, 255))
+    : red(brightness, contrast, min.red(), max.red()),
+      green(brightness, contrast, min.green(), max.green()),
+      blue(brightness, contrast, min.blue(), max.blue())
+    {}
+
+    value_type operator()(value_type const & v) const
+    {
+
+        return value_type(red(v.red()), green(v.green()), blue(v.blue()));
+    }
+};
+
+
+
+/********************************************************/
+/*                                                      */
+/*                     GammaFunctor                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Perform gamma correction of an image.
+
+    This functor applies a gamma correction to each pixel in order to
+    modify the brightness of the image.  Gamma values smaller than 1
+    will increase image brightness, whereas values greater than 1
+    decrease it. A value of gamma = 1 will have no effect.  (See also
+    BrightnessContrastFunctor, which additionally changes the
+    contrast.)
+
+    For \ref RGBValue "RGBValue's", the transforms are applied
+    component-wise.  For ease of use, the pixel values are assumed to
+    lie between the given minimum and maximum values (in case of RGB,
+    this is again understood component-wise). In case of <TT>unsigned
+    char</TT>, min and max default to 0 and 255 respectively.
+    Precisely, the following transform is applied to each <em>
+    PixelValue</em>:
+
+    \f[
+    \begin{array}{rcl}
+    V_1 & = & \frac{PixelValue - min}{max - min} \\
+    V_2 & = & V_1^{gamma} \\
+    Result & = & V_2 (max - min) + min
+    \end{array}
+    \f]
+
+    If the <TT>PixelType</TT> is <TT>unsigned char</TT>, a
+    look-up-table is used for faster computation.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/transformimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    vigra::BImage bimage(width, height);
+    double gamma;
+    ...
+    vigra::transformImage(srcImageRange(bimage), destImage(bimage),
+       vigra::GammaFunctor<unsigned char>(gamma));
+
+
+
+    vigra::FImage fimage(width, height);
+    ...
+
+    vigra::FindMinMax<float> minmax;
+    vigra::inspectImage(srcImageRange(fimage), minmax);
+
+    vigra::transformImage(srcImageRange(fimage), destImage(fimage),
+       vigra::GammaFunctor<float>(gamma, minmax.min, minmax.max));
+
+    \endcode
+
+    <b> Required Interface:</b>
+
+    Scalar types: must be a linear algebra (+, - *, NumericTraits),
+    strict weakly ordered (<), and <TT>pow()</TT> must be defined.
+
+    RGB values: the component type must meet the above requirements.
+*/
+template <class PixelType>
+class GammaFunctor
+{
+    typedef typename
+        NumericTraits<PixelType>::RealPromote promote_type;
+
+ public:
+
+        /** the functor's argument type
+        */
+    typedef PixelType argument_type;
+
+        /** the functor's result type
+        */
+    typedef PixelType result_type;
+
+        /** \deprecated use argument_type and result_type
+        */
+    typedef PixelType value_type;
+
+        /** Init functor for argument range <TT>[min, max]</TT>.
+            <TT>gamma</TT> values < 1 will increase brightness, > 1
+            will decrease it (gamma == 1 means no change).
+        */
+    GammaFunctor(double gamma,
+                 argument_type const & min, argument_type const & max)
+    : gamma_((promote_type)gamma),
+      min_(min),
+      diff_(max - min),
+      zero_(NumericTraits<promote_type>::zero()),
+      one_(NumericTraits<promote_type>::one())
+    {}
+
+        /** Calculate modified gray or color value
+        */
+    result_type operator()(argument_type const & v) const
+    {
+        promote_type v1 = (v - min_) / diff_;
+        promote_type brighter = VIGRA_CSTD::pow(v1, gamma_);
+        return result_type(diff_ * brighter + min_);
+    }
+
+  private:
+    promote_type gamma_;
+    argument_type min_;
+    promote_type diff_, zero_, one_;
+};
+
+template <>
+class GammaFunctor<unsigned char>
+{
+    typedef NumericTraits<unsigned char>::RealPromote promote_type;
+     unsigned char lut[256];
+
+ public:
+
+    typedef unsigned char value_type;
+
+    GammaFunctor(promote_type gamma,
+                 value_type const & min = 0, value_type const & max = 255)
+    {
+        GammaFunctor<promote_type> f(gamma, min, max);
+
+        for(int i = min; i <= max; ++i)
+        {
+            lut[i] = static_cast<unsigned char>(f(i)+0.5);
+        }
+    }
+
+    value_type operator()(value_type const & v) const
+    {
+
+        return lut[v];
+    }
+};
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class ComponentType>
+class GammaFunctor<RGBValue<ComponentType> >
+{
+    typedef typename
+        NumericTraits<ComponentType>::RealPromote promote_type;
+    GammaFunctor<ComponentType> red, green, blue;
+
+ public:
+
+    typedef RGBValue<ComponentType> value_type;
+
+    GammaFunctor(promote_type gamma,
+                 value_type const & min, value_type const & max)
+    : red(gamma, min.red(), max.red()),
+      green(gamma, min.green(), max.green()),
+      blue(gamma, min.blue(), max.blue())
+    {}
+
+    value_type operator()(value_type const & v) const
+    {
+        return value_type(red(v.red()), green(v.green()), blue(v.blue()));
+    }
+};
+
+#else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <>
+class GammaFunctor<RGBValue<int> >
+{
+    typedef NumericTraits<int>::RealPromote promote_type;
+    GammaFunctor<int> red, green, blue;
+
+ public:
+
+    typedef RGBValue<int> value_type;
+
+    GammaFunctor(promote_type gamma,
+                 value_type const & min, value_type const & max)
+    : red(gamma, min.red(), max.red()),
+      green(gamma, min.green(), max.green()),
+      blue(gamma, min.blue(), max.blue())
+    {}
+
+    value_type operator()(value_type const & v) const
+    {
+        return value_type(red(v.red()), green(v.green()), blue(v.blue()));
+    }
+};
+
+template <>
+class GammaFunctor<RGBValue<float> >
+{
+    typedef NumericTraits<float>::RealPromote promote_type;
+    GammaFunctor<float> red, green, blue;
+
+ public:
+
+    typedef RGBValue<float> value_type;
+
+    GammaFunctor(promote_type gamma,
+                 value_type const & min, value_type const & max)
+    : red(gamma, min.red(), max.red()),
+      green(gamma, min.green(), max.green()),
+      blue(gamma, min.blue(), max.blue())
+    {}
+
+    value_type operator()(value_type const & v) const
+    {
+        return value_type(red(v.red()), green(v.green()), blue(v.blue()));
+    }
+};
+
+template <class PixelType>
+class FunctorTraits<GammaFunctor<PixelType> >
+: public FunctorTraitsBase<GammaFunctor<PixelType> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <>
+class GammaFunctor<RGBValue<unsigned char> >
+{
+    typedef NumericTraits<unsigned char>::RealPromote promote_type;
+    GammaFunctor<unsigned char> red, green, blue;
+
+ public:
+    typedef RGBValue<unsigned char> value_type;
+
+    GammaFunctor(promote_type gamma,
+                 value_type const & min = value_type(0,0,0),
+                 value_type const & max = value_type(255, 255, 255))
+    : red(gamma, min.red(), max.red()),
+      green(gamma, min.green(), max.green()),
+      blue(gamma, min.blue(), max.blue())
+    {}
+
+    value_type operator()(value_type const & v) const
+    {
+        return value_type(red(v.red()), green(v.green()), blue(v.blue()));
+    }
+};
+
+
+/********************************************************/
+/*                                                      */
+/*                     VectorNormFunctor                */
+/*                                                      */
+/********************************************************/
+
+/** \brief A functor for computing the vector norm
+
+    Calculate the magnitude or norm from a given vector-valued
+    entity. The vector type will typically be some sort of
+    ref vigra::TinyVector. If the vector is represented by a pair of
+    scalar-valued images, use \ref vigra::MagnitudeFunctor instead.
+
+    At least, the vector type is required to have a function
+    '<em>result</em><TT> = dot(v,v)</TT>'.
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/transformimage.hxx\><br>
+    Namespace: vigra
+
+    \code
+    typedef vigra::TinyVector<float, 2> Vector;
+    vigra::BasicImage<Vector> grad(width, height);
+    vigra::FImage magn(width,height);
+    ...
+    vigra::transformImage(srcImageRange(grad), destImage(magn),
+                          VectorNormFunctor<float>()
+                          );
+    \endcode
+
+    \see vigra::TinyVector, dot(), vigra::MagnitudeFunctor
+*/
+template <class ValueType>
+class VectorNormFunctor
+{
+public:
+  /** the functor's argument type
+   */
+  typedef ValueType argument_type;
+
+  /** the functor's result type
+   */
+  typedef typename NumericTraits<typename ValueType::value_type>::RealPromote result_type;
+
+  /** calculate transform '<TT>sqrt(v1*v1 + v2*v2 + ...)</TT>'.
+   */
+  result_type operator()( const argument_type &a ) const
+  {
+    return VIGRA_CSTD::sqrt( dot(a,a) );
+  }
+};    //-- class VectorNormFunctor
+
+template <class ValueType>
+class FunctorTraits<VectorNormFunctor<ValueType> >
+: public FunctorTraitsBase<VectorNormFunctor<ValueType> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+/** \brief A functor for computing the squared vector norm
+
+    Calculate the squared magnitude or norm from a given
+    vector-valued entity. The vector type will typically be some
+    sort of TinyVector.
+
+    At least, the vector type is required to have a function
+    '<em>result</em><TT> = dot(v,v)</TT>'.
+
+    For an example of its usage see VectorNormFunctor
+
+    <b> Traits defined:</b>
+
+    <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
+
+    \see TinyVector, dot()
+*/
+template <class ValueType>
+class VectorNormSqFunctor
+{
+public:
+  /** the functor's argument type
+   */
+  typedef ValueType argument_type;
+
+  /** the functor's result type
+   */
+  typedef typename NumericTraits<typename ValueType::value_type>::RealPromote result_type;
+
+  /** calculate transform '<TT>v1*v1 + v2*v2 + ...</TT>'.
+   */
+  result_type operator()( const argument_type &a ) const
+  {
+    return dot(a,a);
+  }
+};    //-- class VectorNormSqFunctor
+
+template <class ValueType>
+class FunctorTraits<VectorNormSqFunctor<ValueType> >
+: public FunctorTraitsBase<VectorNormSqFunctor<ValueType> >
+{
+  public:
+    typedef VigraTrueType isUnaryFunctor;
+};
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_TRANSFORMIMAGE_HXX
diff --git a/include/vigra/tuple.hxx b/include/vigra/tuple.hxx
new file mode 100644
index 0000000..eb07723
--- /dev/null
+++ b/include/vigra/tuple.hxx
@@ -0,0 +1,181 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_TUPLE_HXX
+#define VIGRA_TUPLE_HXX
+
+#include <utility>    // for pair
+
+namespace vigra {
+
+/** \page TupleTypes Tuple Types
+
+    pair, triple, tuple4, tuple5
+
+    <b>\#include</b> \<vigra/utilities.hxx\><br>
+    Namespace: vigra
+
+    VIGRA defines tuple types \p vigra::triple, \p vigra::tuple4, \p vigra::tuple5.
+    In addition, \p std::pair is imported into namespace vigra from the C++ standard
+    library. All these types are defined similarly:
+
+    <ul>
+
+    <li> They are parameterized by the respective number of types. For each tuple,
+    a constructor is defined that takes that many arguments, e.g.:
+    \code
+    template <class First, class Second, class Third>
+    class Triple { ... };
+    \endcode
+    </li>
+    <li> A number of \p typedef's tells the types stored in the tuple:
+
+    \code
+    typedef ... first_type;
+    typedef ... second_type;
+    typedef ... third_type;  // triple, tuple4, tuple5 only
+    typedef ... forth_type;  // tuple4, tuple5 only
+    typedef ... fifth_type;  // tuple5 only
+    \endcode
+    </li>
+    <li> Items are stored in the following public attributes:
+
+    \code
+
+    first;
+    second;
+    third;  // triple, tuple4, tuple5 only
+    forth;  // tuple4, tuple5 only
+    fifth;  // tuple5 only
+
+    \endcode
+    </li>
+    </ul>
+
+
+*/
+
+/********************************************************/
+/*                                                      */
+/*                          pair                        */
+/*                                                      */
+/********************************************************/
+
+using std::pair;
+
+/********************************************************/
+/*                                                      */
+/*                          triple                      */
+/*                                                      */
+/********************************************************/
+
+template <class T1, class T2, class T3>
+struct triple {
+    typedef T1 first_type;
+    typedef T2 second_type;
+    typedef T3 third_type;
+
+    T1 first;
+    T2 second;
+    T3 third;
+    triple() {}
+    triple(const T1& a, const T2& b, const T3& c)
+    : first(a), second(b), third(c) {}
+};
+
+template <class T1, class T2, class T3>
+triple<T1,T2,T3> make_triple( T1 t1, T2 t2, T3 t3 )
+{ return triple<T1,T2,T3>( t1, t2, t3 ); }
+
+/********************************************************/
+/*                                                      */
+/*                          tuple4                      */
+/*                                                      */
+/********************************************************/
+
+template <class T1, class T2, class T3, class T4>
+struct tuple4 {
+    typedef T1 first_type;
+    typedef T2 second_type;
+    typedef T3 third_type;
+    typedef T4 fourth_type;
+
+    T1 first;
+    T2 second;
+    T3 third;
+    T4 fourth;
+    tuple4() {}
+    tuple4(const T1& a, const T2& b, const T3& c, const T4& d)
+    : first(a), second(b), third(c), fourth(d) {}
+};
+
+template <class T1, class T2, class T3, class T4>
+tuple4<T1,T2,T3,T4> make_tuple4( T1 t1, T2 t2, T3 t3, T4 t4 )
+{ return tuple4<T1,T2,T3,T4>( t1, t2, t3, t4 ); }
+
+/********************************************************/
+/*                                                      */
+/*                          tuple5                      */
+/*                                                      */
+/********************************************************/
+
+template <class T1, class T2, class T3, class T4, class T5>
+struct tuple5 {
+    typedef T1 first_type;
+    typedef T2 second_type;
+    typedef T3 third_type;
+    typedef T4 fourth_type;
+    typedef T5 fifth_type;
+
+    T1 first;
+    T2 second;
+    T3 third;
+    T4 fourth;
+    T5 fifth;
+    tuple5() {}
+    tuple5(const T1& a, const T2& b, const T3& c, const T4& d, const T5& e)
+    : first(a), second(b), third(c), fourth(d), fifth(e) {}
+};
+
+template <class T1, class T2, class T3, class T4, class T5>
+tuple5<T1,T2,T3,T4,T5> make_tuple5( T1 t1, T2 t2, T3 t3, T4 t4, T5 t5 )
+{ return tuple5<T1,T2,T3,T4,T5>( t1, t2, t3, t4, t5 ); }
+
+
+} // namespace vigra
+
+
+
+#endif /* VIGRA_TUPLE_HXX */
diff --git a/include/vigra/tv_filter.hxx b/include/vigra/tv_filter.hxx
new file mode 100644
index 0000000..17b4462
--- /dev/null
+++ b/include/vigra/tv_filter.hxx
@@ -0,0 +1,767 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2012 by Frank Lenzen &                     */
+/*                                           Ullrich Koethe             */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_TV_FILTER_HXX
+#define VIGRA_TV_FILTER_HXX
+
+#include <iostream>
+#include <cmath>
+#include "config.hxx"
+#include "impex.hxx"
+#include "separableconvolution.hxx"
+#include "multi_array.hxx"
+#include "multi_math.hxx"
+#include "eigensystem.hxx"
+#include "convolution.hxx"
+#include "fixedpoint.hxx"
+#include "project2ellipse.hxx"
+
+#ifndef VIGRA_MIXED_2ND_DERIVATIVES
+#define VIGRA_MIXED_2ND_DERIVATIVES 1
+#endif
+
+#define setZeroX(A) A.subarray(Shape2(width-1,0),Shape2(width,height))*=0;
+#define setZeroY(A) A.subarray(Shape2(0,height-1),Shape2(width,height))*=0;
+
+namespace vigra{
+  
+
+
+/** \addtogroup NonLinearDiffusion
+*/
+
+//@{
+
+/********************************************************/
+/*                                                      */
+/*           totalVariationFilter                       */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs standard Total Variation Regularization
+
+The algorithm minimizes
+    
+\f[
+       \min_u \int_\Omega \frac{1}{2} (u-f)^2\;dx + \alpha TV(u)\qquad\qquad (1)
+\f]
+where <em>\f$ f=f(x)\f$</em> are the two dimensional noisy data,
+<em> \f$ u=u(x)\f$</em> are the smoothed data,<em>\f$ \alpha \ge 0 \f$</em>
+is the filter parameter and <em>\f$ TV(u)\f$ </em> is the total variation semi-norm.
+        
+<b> Declarations:</b>
+   
+\code
+namespace vigra {
+      template <class stride1,class stride2>
+      void totalVariationFilter(MultiArrayView<2,double,stride1> data, 
+                                MultiArrayView<2,double,stride2> out,
+                                double alpha, 
+                                int steps, 
+                                double eps=0);
+      void totalVariationFilter(MultiArrayView<2,double,stride1> data,
+                                MultiArrayView<2,double,stride2> weight,
+                                MultiArrayView<2,double,stride3> out,
+                                double alpha, 
+                                int steps, 
+                                double eps=0);
+}
+\endcode
+            
+\ref totalVariationFilter() implements a primal-dual algorithm to solve (1).
+     
+Input:
+     <table>     
+     <tr><td><em>data</em>:  </td><td> input data to be smoothed. </td></tr>
+     <tr><td><em>alpha</em>: </td><td> smoothing parameter.</td></tr>
+     <tr><td><em>steps</em>: </td><td> maximal number of iteration steps. </td></tr>
+     <tr><td><em>eps</em>:   </td><td> The algorithm stops, if the primal-dual gap is below the threshold <em>eps</em>.
+     </table>
+     
+     Output:
+     
+     <em>out</em> contains the filtered data.
+    
+     In addition, a point-wise weight (\f$ \ge 0 \f$) for the data term can be provided (overloaded function).
+    
+    <b> Usage:</b>
+    
+    <b>\#include</b> \<vigra/tv_filter.hxx\>
+    
+    \code
+    MultiArray<2,double> data(Shape2(width,height));  // to be initialized
+    MultiArray<2,double> out(Shape2(width,height));
+    MultiArray<2,double> weight(Shape2(width,height))); //optional argument in overloaded function, to be initialized if used
+    int steps;        // to be initialized
+    double alpha,eps; // to be initialized
+    
+    totalVariationFilter(data,out,alpha,steps,eps);
+    \endcode
+    or
+    \code
+    totalVariationFilter(data,weight,out,alpha,steps,eps);
+    \endcode
+  
+ */
+doxygen_overloaded_function(template <...> void totalVariationFilter)
+
+template <class stride1,class stride2>
+void totalVariationFilter(MultiArrayView<2,double,stride1> data,MultiArrayView<2,double,stride2> out, double alpha, int steps, double eps=0){
+
+  using namespace multi_math;
+  int width=data.shape(0),height=data.shape(1);
+  
+  MultiArray<2,double> temp1(data.shape()),temp2(data.shape()),vx(data.shape()),vy(data.shape()),u_bar(data.shape());
+  Kernel1D<double> Lx,LTx;
+  Lx.initExplicitly(-1,0)=1,-1;                       // = Right sided finite differences for d/dx and d/dy
+  Lx.setBorderTreatment(BORDER_TREATMENT_REFLECT);   //   with hom. Neumann boundary conditions
+  LTx.initExplicitly(0,1)=-1,1;                     //  = Left sided finite differences for -d/dx  and -d/dy
+  LTx.setBorderTreatment(BORDER_TREATMENT_ZEROPAD);  //   with hom. Dirichlet b. c.
+
+  out=data;
+  u_bar=data;
+  
+  double tau=1.0 / std::max(alpha,1.) / std::sqrt(8.0) * 0.06;
+  double sigma=1.0 / std::sqrt(8.0) / 0.06;
+    
+  for (int i=0;i<steps;i++){
+  
+    separableConvolveX(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroX(temp1);
+    vx+=(sigma*temp1);
+    separableConvolveY(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroY(temp1);
+    vy+=(sigma*temp1);
+    
+    //project to constraint set
+    for (int y=0;y<data.shape(1);y++){
+      for (int x=0;x<data.shape(0);x++){
+        double l=hypot(vx(x,y),vy(x,y));
+        if (l>1){
+          vx(x,y)/=l;
+          vy(x,y)/=l;
+        }
+      }
+    }
+    
+    separableConvolveX(srcImageRange(vx),destImage(temp1),kernel1d(LTx));
+    separableConvolveY(srcImageRange(vy),destImage(temp2),kernel1d(LTx));
+    u_bar=out;
+    out-=tau*(out-data+alpha*(temp1+temp2));
+    u_bar=2*out-u_bar;   //cf. Chambolle/Pock and Popov's algorithm
+    
+    
+    //stopping criterion
+    if (eps>0){
+      separableConvolveX(srcImageRange(out),destImage(temp1),kernel1d(Lx));setZeroX(temp1);
+      separableConvolveY(srcImageRange(out),destImage(temp2),kernel1d(Lx));setZeroY(temp2);
+      
+      double f_primal=0,f_dual=0;
+      for (int y=0;y<data.shape(1);y++){
+        for (int x=0;x<data.shape(0);x++){
+          f_primal+=.5*(out(x,y)-data(x,y))*(out(x,y)-data(x,y))+alpha*hypot(temp1(x,y),temp2(x,y));
+        }
+      }
+      separableConvolveX(srcImageRange(vx),destImage(temp1),kernel1d(LTx));
+      separableConvolveY(srcImageRange(vy),destImage(temp2),kernel1d(LTx));
+      for (int y=0;y<data.shape(1);y++){
+        for (int x=0;x<data.shape(0);x++){
+          double divv=temp1(x,y)+temp2(x,y);
+          f_dual+=-.5*alpha*alpha*(divv*divv)+alpha*data(x,y)*divv;
+        }
+      }
+      if (f_primal>0 && (f_primal-f_dual)/f_primal<eps){
+        break;
+      }
+    }
+  }
+}
+
+template <class stride1,class stride2, class stride3>
+void totalVariationFilter(MultiArrayView<2,double,stride1> data,MultiArrayView<2,double,stride2> weight, MultiArrayView<2,double,stride3> out,double alpha, int steps, double eps=0){
+
+  using namespace multi_math;
+  int width=data.shape(0),height=data.shape(1);
+  
+  MultiArray<2,double> temp1(data.shape()),temp2(data.shape()),vx(data.shape()),vy(data.shape()),u_bar(data.shape());
+  Kernel1D<double> Lx,LTx; 
+  Lx.initExplicitly(-1,0)=1,-1;                       // = Right sided finite differences for d/dx and d/dy
+  Lx.setBorderTreatment(BORDER_TREATMENT_REFLECT);   //   with hom. Neumann boundary conditions
+  LTx.initExplicitly(0,1)=-1,1;                     //  = Left sided finite differences for -d/dx  and -d/dy
+  LTx.setBorderTreatment(BORDER_TREATMENT_ZEROPAD);  //   with hom. Dirichlet b. c.
+  
+  out=data;
+  u_bar=data;
+  
+  double tau=1.0 / std::max(alpha,1.) / std::sqrt(8.0) * 0.06;
+  double sigma=1.0 / std::sqrt(8.0) / 0.06;
+  
+  for (int i=0;i<steps;i++){
+    separableConvolveX(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroX(temp1);
+    vx+=(sigma*temp1);
+    separableConvolveY(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroY(temp1);
+    vy+=(sigma*temp1);
+    
+    //project to constraint set
+    for (int y=0;y<data.shape(1);y++){
+      for (int x=0;x<data.shape(0);x++){
+        double l=hypot(vx(x,y),vy(x,y));
+        if (l>1){
+          vx(x,y)/=l;
+          vy(x,y)/=l;
+        }
+      }
+    }
+    
+    separableConvolveX(srcImageRange(vx),destImage(temp1),kernel1d(LTx));
+    separableConvolveY(srcImageRange(vy),destImage(temp2),kernel1d(LTx));
+    u_bar=out;
+    out-=tau*(weight*(out-data)+alpha*(temp1+temp2));
+    u_bar=2*out-u_bar;
+    
+    
+    //stopping criterion
+    if (eps>0){
+      separableConvolveX(srcImageRange(out),destImage(temp1),kernel1d(Lx));setZeroX(temp1);
+      separableConvolveY(srcImageRange(out),destImage(temp2),kernel1d(Lx));setZeroY(temp2);
+      
+      double f_primal=0,f_dual=0;
+      for (int y=0;y<data.shape(1);y++){
+        for (int x=0;x<data.shape(0);x++){
+          f_primal+=.5*weight(x,y)*(out(x,y)-data(x,y))*(out(x,y)-data(x,y))+alpha*hypot(temp1(x,y),temp2(x,y));
+        }
+      }
+      separableConvolveX(srcImageRange(vx),destImage(temp1),kernel1d(LTx));
+      separableConvolveY(srcImageRange(vy),destImage(temp2),kernel1d(LTx));
+      for (int y=0;y<data.shape(1);y++){
+        for (int x=0;x<data.shape(0);x++){
+          double divv=temp1(x,y)+temp2(x,y);
+          f_dual+=-.5*alpha*alpha*(weight(x,y)*divv*divv)+alpha*data(x,y)*divv;
+        }
+      }
+      if (f_primal>0 && (f_primal-f_dual)/f_primal<eps){
+        break;
+      }
+    }
+  }
+}
+//<!--\f$ \alpha(x)=\beta(x)=\beta_{par}\f$ in homogeneous regions without edges,
+//and \f$ \alpha(x)=\alpha_{par}\f$ at edges.-->
+
+
+/********************************************************/
+/*                                                      */
+/*         getAnisotropy                                */
+/*                                                      */
+/********************************************************/
+
+/** \brief Sets up directional data for anisotropic regularization
+
+This routine provides a two-dimensional normalized vector field \f$ v \f$, which is normal to edges in the given data,
+found as the eigenvector of the structure tensor belonging to the largest eigenvalue.
+\f$ v \f$ is encoded by a scalar field \f$ \varphi \f$ of angles, i.e. 
+\f$ v(x)=(\cos(\varphi(x)),\sin(\varphi(x)))^\top \f$.
+
+In addition, two scalar fields \f$ \alpha \f$ and  \f$ \beta \f$ are generated from
+scalar parameters \f$ \alpha_{par}\f$ and \f$ \beta_{par}\f$, such that
+<center>
+<table>
+<tr> <td>\f$ \alpha(x)= \alpha_{par}\f$ at edges,</td></tr>
+<tr> <td>\f$ \alpha(x)= \beta_{par}\f$ in homogeneous regions,</td></tr>
+<tr> <td>\f$ \beta(x)=\beta_{par}\f$ .</td></tr>
+</table>
+</center>
+
+<b> Declarations:</b>
+
+\code
+namespace vigra {
+void getAnisotropy(MultiArrayView<2,double,stride1> data,
+                   MultiArrayView<2,double,stride2> phi,
+                   MultiArrayView<2,double,stride3> alpha, 
+                   MultiArrayView<2,double,stride4> beta, 
+                   double alpha_par, 
+                   double beta_par, 
+                   double sigma_par, 
+                   double rho_par, 
+                   double K_par);
+}
+\endcode
+
+Output:
+<table>
+  <tr><td>Three scalar fields <em>phi</em>, <em>alpha</em> and <em>beta</em>.</td></tr>
+</table>
+
+Input:
+<table>
+<tr><td><em>data</em>:</td><td>two-dimensional scalar field.</td></tr>
+<tr><td><em>alpha_par,beta_par</em>:</td><td>two positive values for setting up the scalar fields alpha and beta</tr>
+<tr><td><em>sigma_par</em>:</td><td> non-negative parameter for presmoothing the data.</td></tr>
+<tr><td> <em>rho_par</em>:</td><td> non-negative parameter for presmoothing the structure tensor.</td></tr>
+<tr><td><em>K_par</em>:</td><td> positive edge sensitivity parameter.</td></tr>
+ </table>
+ 
+(see \ref anisotropicTotalVariationFilter() and \ref secondOrderTotalVariationFilter() for usage in an application).
+*/
+doxygen_overloaded_function(template <...> void getAnisotropy)
+
+template <class stride1,class stride2,class stride3,class stride4>
+void getAnisotropy(MultiArrayView<2,double,stride1> data,MultiArrayView<2,double,stride2> phi,
+                    MultiArrayView<2,double,stride3> alpha, MultiArrayView<2,double,stride4> beta, 
+                    double alpha_par, double beta_par, double sigma_par, double rho_par, double K_par){
+  
+  using namespace multi_math;
+  int width=data.shape(0),height=data.shape(1);
+  
+  MultiArray<2,double> smooth(data.shape()),tmp(data.shape());
+  vigra::Kernel1D<double> gauss;
+
+  
+  gauss.initGaussian(sigma_par);
+  separableConvolveX(srcImageRange(data), destImage(tmp), kernel1d(gauss));
+  separableConvolveY(srcImageRange(tmp), destImage(smooth), kernel1d(gauss));
+  
+  MultiArray<2,double> stxx(data.shape()),stxy(data.shape()),styy(data.shape());
+  
+  // calculate Structure Tensor at inner scale = sigma and outer scale = rho
+  vigra::structureTensor(srcImageRange(smooth),destImage(stxx), destImage(stxy), destImage(styy),1.,1.);
+  
+  gauss.initGaussian(rho_par);
+  separableConvolveX(srcImageRange(stxx), destImage(tmp), kernel1d(gauss));
+  separableConvolveY(srcImageRange(tmp), destImage(stxx), kernel1d(gauss));
+  separableConvolveX(srcImageRange(stxy), destImage(tmp), kernel1d(gauss));
+  separableConvolveY(srcImageRange(tmp), destImage(stxy), kernel1d(gauss));
+  separableConvolveX(srcImageRange(styy), destImage(tmp), kernel1d(gauss));
+  separableConvolveY(srcImageRange(tmp), destImage(styy), kernel1d(gauss));
+  
+  MultiArray<2,double> matrix(Shape2(2,2)),ev(Shape2(2,2)),ew(Shape2(2,1));
+  
+   for (int y=0;y<data.shape(1);y++){
+    for (int x=0;x<data.shape(0);x++){
+      
+      matrix(0,0)=stxx(x,y);
+      matrix(1,1)=styy(x,y);
+      matrix(0,1)=stxy(x,y);
+      matrix(1,0)=stxy(x,y);
+      vigra::linalg::detail::symmetricEigensystem2x2(matrix,ew,ev);
+      
+      phi(x,y)=std::atan2(ev(1,0),ev(0,0));
+      double coherence=ew(0,0)-ew(1,0); 
+      double c=std::min(K_par*coherence,1.);
+      alpha(x,y)=alpha_par*c+(1-c)*beta_par;
+      beta(x,y)=beta_par;
+      }
+  }
+}
+
+/********************************************************/
+/*                                                      */
+/*   anisotropicTotalVariationFilter                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs Anisotropic Total Variation Regularization
+
+The algorithm minimizes
+\f[
+\min_u \int_\Omega \frac{1}{2} (u-f)^2 + \sqrt{\nabla u^\top A \nabla u}\;dx\qquad\qquad(2)
+\f]
+
+where <em> \f$ f=f(x)\f$ </em> are the noisy data, <em> \f$ u=u(x)\f$ </em> are the smoothed data,<em>\f$ \nabla u \f$ </em>
+is the image gradient in the sense of Total Variation and <em>\f$ A \f$ </em> is a locally varying symmetric, positive definite  2x2 matrix.
+
+Matrix <em>\f$ A \f$ </em> is described by providing  for each data point a normalized eigenvector (via angle \f$ \phi \f$)
+and two eigenvalues \f$ \alpha>0 \f$ and \f$ \beta>0 \f$.
+
+\ref getAnisotropy() can be use to set up such data \f$ \phi,\alpha,\beta \f$ by providing a vector field normal to edges.
+
+<b> Declarations:</b>
+
+\code
+namespace vigra {
+  template <class stride1,class stride2,class stride3,class stride4,class stride5,class stride6>
+  void anisotropicTotalVariationFilter(MultiArrayView<2,double,stride1> data,
+                                       MultiArrayView<2,double,stride2> weight,
+                                       MultiArrayView<2,double,stride3> phi,
+                                       MultiArrayView<2,double,stride4> alpha, 
+                                       MultiArrayView<2,double,stride5> beta,
+                                       MultiArrayView<2,double,stride6> out,
+                                       int steps);
+}
+\endcode
+
+\ref anisotropicTotalVariationFilter() implements a primal-dual algorithm to solve (2).
+
+Input:
+<table>
+<tr><td><em>data</em>:</td><td>input data to be filtered. </td></tr>
+<tr><td><em>steps</em>:</td><td>iteration steps.</td></tr>
+<tr><td><em>weight</em> :</td><td>a point-wise weight (\f$ \ge 0 \f$ ) for the data term.</td></tr>
+<tr><td><em>phi</em>,<em>alpha</em> and <em>beta</em> :</td><td> describe matrix \f$ A \f$, see above.</td></tr>
+</table>
+
+Output:
+<table>
+<tr><td><em>out</em> :</td><td>contains filtered data.</td></tr>
+</table>
+
+<b> Usage:</b>
+
+E.g. with a solution-dependent adaptivity cf. [1], by updating the matrix \f$ A=A(u)\f$
+in an outer loop:
+
+<b>\#include</b> \<vigra/tv_filter.hxx\>
+
+\code 
+MultiArray<2,double> data(Shape2(width,height)); //to be initialized
+MultiArray<2,double> out (Shape2(width,height));
+MultiArray<2,double> weight(Shape2(width,height));  //to be initialized
+MultiArray<2,double> phi  (Shape2(width,height));
+MultiArray<2,double> alpha(Shape2(width,height));
+MultiArray<2,double> beta (Shape2(width,height)); 
+double alpha0,beta0,sigma,rho,K;  //to be initialized
+int outer_steps,inner_steps;//to be initialized
+
+out=data; // data serves as initial value
+
+for (int i=0;i<outer_steps;i++){
+  getAnisotropy(out,phi,alpha,beta,alpha0,beta0,sigma,rho,K);  // sets phi, alpha, beta
+  anisotropicTotalVariationFilter(data,weight,phi,alpha,beta,out,inner_steps);
+  }
+\endcode
+
+[1] Frank Lenzen, Florian Becker, Jan Lellmann, Stefania Petra and Christoph Schnörr, A Class of Quasi-Variational Inequalities for Adaptive Image Denoising and Decomposition, Computational Optimization and Applications, Springer, 2012.
+*/
+doxygen_overloaded_function(template <...>  void anisotropicTotalVariationFilter)
+
+template <class stride1,class stride2,class stride3,class stride4,class stride5,class stride6>
+void anisotropicTotalVariationFilter(MultiArrayView<2,double,stride1> data,MultiArrayView<2,double,stride2> weight, 
+                    MultiArrayView<2,double,stride3> phi,MultiArrayView<2,double,stride4> alpha,
+                    MultiArrayView<2,double,stride5> beta,MultiArrayView<2,double,stride6> out,
+                    int steps){
+  
+  using namespace multi_math;
+  int width=data.shape(0),height=data.shape(1);
+  
+  MultiArray<2,double> temp1(data.shape()),temp2(data.shape()),vx(data.shape()),vy(data.shape()),u_bar(data.shape());
+  MultiArray<2,double> rx(data.shape()),ry(data.shape());
+  
+  Kernel1D<double> Lx,LTx;
+  Lx.initExplicitly(-1,0)=1,-1;                       // = Right sided finite differences for d/dx and d/dy
+  Lx.setBorderTreatment(BORDER_TREATMENT_REFLECT);   //   with hom. Neumann boundary conditions
+  LTx.initExplicitly(0,1)=-1,1;                     //  = Left sided finite differences for -d/dx  and -d/dy
+  LTx.setBorderTreatment(BORDER_TREATMENT_ZEROPAD);  //   with hom. Dirichlet b. c.
+  
+  u_bar=out;
+  
+  double m=0;
+  for (int y=0;y<data.shape(1);y++){
+    for (int x=0;x<data.shape(0);x++){
+      m=std::max(m,alpha(x,y));
+      m=std::max(m,beta (x,y));
+    }
+  }  
+  m=std::max(m,1.);
+  double tau=.9/m/std::sqrt(8.)*0.06;  
+  double sigma=.9/m/std::sqrt(8.)/0.06;
+  
+    
+  for (int i=0;i<steps;i++){
+    separableConvolveX(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroX(temp1);
+    vx+=(sigma*temp1);
+    separableConvolveY(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroY(temp1);
+    vy+=(sigma*temp1);
+    
+    //project to constraint set
+    for (int y=0;y<data.shape(1);y++){
+      for (int x=0;x<data.shape(0);x++){
+        double e1,e2,skp1,skp2;
+
+        e1=std::cos(phi(x,y));
+        e2=std::sin(phi(x,y));
+        skp1=vx(x,y)*e1+vy(x,y)*e2;
+        skp2=vx(x,y)*(-e2)+vy(x,y)*e1;
+        vigra::detail::projectEllipse2D (skp1,skp2,alpha(x,y),beta(x,y),0.001,100);
+        
+        vx(x,y)=skp1*e1-skp2*e2;
+        vy(x,y)=skp1*e2+skp2*e1;
+      }
+    }
+    
+    separableConvolveX(srcImageRange(vx),destImage(temp1),kernel1d(LTx));
+    separableConvolveY(srcImageRange(vy),destImage(temp2),kernel1d(LTx));
+    u_bar=out;
+    out-=tau*(weight*(out-data)+(temp1+temp2));
+    u_bar=2*out-u_bar;   //cf. Chambolle/Pock and Popov's algorithm
+  }
+}
+
+/********************************************************/
+/*                                                      */
+/*   secondOrderTotalVariationFilter                    */
+/*                                                      */
+/********************************************************/
+
+/** \brief Performs Anisotropic Total Variation Regularization
+
+The algorithm minimizes
+
+\f[
+\min_u \int_\Omega \frac{1}{2} (u-f)^2 + \sqrt{\nabla u^\top A \nabla u}  + \gamma |Hu|_F\;dx \qquad\qquad (3)
+\f]
+where <em> \f$ f=f(x)\f$ </em> are the noisy data, <em> \f$ u=u(x)\f$ </em> are the smoothed data,<em>\f$ \nabla u \f$ </em>
+is the image gradient in the sense of Total Variation, <em>\f$ A \f$ </em> is a locally varying 
+symmetric, positive-definite  2x2 matrix and <em>\f$ |Hu|_F \f$</em> is the Frobenius norm of the Hessian of \f$ u \f$.
+
+Matrix <em>\f$ A \f$ </em> is described by providing  for each data point a normalized eigenvector (via angle \f$ \phi \f$)
+and two eigenvalues \f$ \alpha>0 \f$ and \f$ \beta>0 \f$.
+\ref getAnisotropy() can be use to set up such data \f$ \phi,\alpha, \beta \f$ by providing a vector field normal to edges.
+
+\f$ \gamma>0 \f$ is the locally varying regularization parameter for second order.
+
+<b> Declarations:</b>
+
+\code
+namespace vigra {
+  template <class stride1,class stride2,...,class stride9>
+  void secondOrderTotalVariationFilter(MultiArrayView<2,double,stride1> data, 
+                                       MultiArrayView<2,double,stride2> weight,
+                                       MultiArrayView<2,double,stride3> phi,
+                                       MultiArrayView<2,double,stride4> alpha,
+                                       MultiArrayView<2,double,stride5> beta,
+                                       MultiArrayView<2,double,stride6> gamma,
+                                       MultiArrayView<2,double,stride7> xedges,
+                                       MultiArrayView<2,double,stride8> yedges,
+                                       MultiArrayView<2,double,stride9> out,
+                                       int steps);
+}
+\endcode
+
+\ref secondOrderTotalVariationFilter() implements a primal-dual algorithm to solve (3).
+
+Input:
+<table>
+<tr><td><em>data</em>: </td><td> the input data to be filtered. </td></tr>
+<tr><td><em>steps</em> : </td><td> number of iteration steps.</td></tr>
+<tr><td><em>out</em> : </td><td>contains the filtered data.</td></tr>
+<tr><td><em>weight</em> : </td><td> point-wise weight (\f$ \ge 0\f$ ) for the data term.</td></tr>
+<tr><td><em>phi</em>,<em>alpha</em>,<em>beta</em>: </td><td> describe matrix \f$ A\f$, see above.</td></tr>
+<tr><td><em> xedges </em> and <em> yedges </em>: </td><td> binary arrays indicating the
+presence of horizontal (between (x,y) and (x+1,y)) and vertical edges (between (x,y) and (x,y+1)). 
+These data are considered in the calculation of \f$ Hu\f$, such that
+finite differences across edges are artificially set to zero to avoid second order smoothing over edges.</td></tr>
+</table>
+
+<b> Usage:</b>
+
+E.g. with a solution-dependent adaptivity (cf.[1]), by updating the matrix \f$ A=A(u)\f$
+in an outer loop:
+
+<b>\#include</b> \<vigra/tv_filter.hxx\>
+
+\code 
+MultiArray<2,double> data(Shape2(width,height)); //to be initialized
+MultiArray<2,double> out(Shape2(width,height));
+MultiArray<2,double> weight(Shape2(width,height))); //to be initialized
+MultiArray<2,double> phi(Shape2(width,height);
+MultiArray<2,double> alpha(Shape2(width,height);
+MultiArray<2,double> beta(Shape2(width,height)); 
+MultiArray<2,double> gamma(Shape2(width,height));  //to be initialized
+MultiArray<2,double> xedges(Shape2(width,height));  //to be initialized
+MultiArray<2,double> yedges(Shape2(width,height));  //to be initialized
+
+
+double alpha0,beta0,sigma,rho,K;  //to be initialized
+int outer_steps,inner_steps;//to be initialized
+
+out=data; // data serves as initial value
+
+for (int i=0;i<outer_steps;i++){
+  
+  getAnisotropy(out,phi,alpha,beta,alpha0,beta0,sigma,rho,K);  // sets phi, alpha, beta
+  secondOrderTotalVariationFilter(data,weight,phi,alpha,beta,gamma,xedges,yedges,out,inner_steps);
+}
+\endcode
+
+
+[1] Frank Lenzen, Florian Becker, Jan Lellmann, Stefania Petra and Christoph Schnörr, A Class of Quasi-Variational Inequalities for Adaptive Image Denoising and Decomposition, Computational Optimization and Applications, Springer, 2012.
+*/
+doxygen_overloaded_function(template <...> void secondOrderTotalVariationFilter)
+
+template <class stride1,class stride2,class stride3,class stride4,class stride5,class stride6,class stride7,class stride8,class stride9>
+void secondOrderTotalVariationFilter(MultiArrayView<2,double,stride1> data, 
+                            MultiArrayView<2,double,stride2> weight,MultiArrayView<2,double,stride3> phi,
+                            MultiArrayView<2,double,stride4> alpha,MultiArrayView<2,double,stride5> beta,
+                            MultiArrayView<2,double,stride6> gamma,
+                            MultiArrayView<2,double,stride7> xedges,MultiArrayView<2,double,stride8> yedges,
+		            MultiArrayView<2,double,stride9> out,
+                            int steps){
+  
+  using namespace multi_math;
+  int width=data.shape(0),height=data.shape(1);
+  
+  MultiArray<2,double> temp1(data.shape()),temp2(data.shape()),vx(data.shape()),vy(data.shape()),u_bar(data.shape());
+  MultiArray<2,double> rx(data.shape()),ry(data.shape());
+  MultiArray<2,double> wx(data.shape()),wy(data.shape()),wz(data.shape());
+  
+  
+  Kernel1D<double> Lx,LTx;
+  Lx.initExplicitly(-1,0)=1,-1;                       // = Right sided finite differences for d/dx and d/dy
+  Lx.setBorderTreatment(BORDER_TREATMENT_REFLECT);   //   with hom. Neumann boundary conditions
+  LTx.initExplicitly(0,1)=-1,1;                     //  = Left sided finite differences for -d/dx  and -d/dy
+  LTx.setBorderTreatment(BORDER_TREATMENT_ZEROPAD);  //   with hom. Dirichlet b. c.
+  
+  u_bar=out;
+  
+  double m=0;
+  for (int y=0;y<data.shape(1);y++){
+    for (int x=0;x<data.shape(0);x++){
+      m=std::max(m,alpha(x,y));
+      m=std::max(m,beta (x,y));
+      m=std::max(m,gamma(x,y));
+     }
+  }  
+  m=std::max(m,1.);
+  double tau=.1/m;//std::sqrt(8)*0.06;  
+  double sigma=.1;//m;/std::sqrt(8)/0.06;
+  
+  //std::cout<<"tau= "<<tau<<std::endl;
+  
+  for (int i=0;i<steps;i++){
+    
+    separableConvolveX(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroX(temp1);
+    vx+=(sigma*temp1);
+    separableConvolveY(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroY(temp1);
+    vy+=(sigma*temp1);
+    
+    
+    // update wx
+    separableConvolveX(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroX(temp1);
+    temp1*=xedges;
+    separableConvolveX(srcImageRange(temp1),destImage(temp2),kernel1d(LTx));
+    wx-=sigma*temp2;//(-Lx'*(xedges.*(Lx*u)));
+    
+    //update wy
+    separableConvolveY(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroY(temp1);
+    temp1*=yedges;
+    separableConvolveY(srcImageRange(temp1),destImage(temp2),kernel1d(LTx));
+    wy-=sigma*temp2;//(-Ly'*(yedges.*(Ly*u)));
+    
+    
+    //update wz
+    #if (VIGRA_MIXED_2ND_DERIVATIVES)
+    separableConvolveY(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroY(temp1);
+    temp1*=yedges;
+    separableConvolveX(srcImageRange(temp1),destImage(temp2),kernel1d(LTx));
+    wz-=sigma*temp2;//-Lx'*(yedges.*(Ly*u))
+    
+    separableConvolveX(srcImageRange(u_bar),destImage(temp1),kernel1d(Lx));setZeroX(temp1);
+    temp1*=xedges;
+    separableConvolveY(srcImageRange(temp1),destImage(temp2),kernel1d(LTx));
+    wz-=sigma*temp2;//-Ly'*(xedges.*(Lx*u)));
+    
+    #endif
+    
+    
+    //project to constraint sets
+    for (int y=0;y<data.shape(1);y++){
+      for (int x=0;x<data.shape(0);x++){
+        double e1,e2,skp1,skp2;
+        
+        //project v
+        e1=std::cos(phi(x,y));
+        e2=std::sin(phi(x,y));
+        skp1=vx(x,y)*e1+vy(x,y)*e2;
+        skp2=vx(x,y)*(-e2)+vy(x,y)*e1;
+        vigra::detail::projectEllipse2D (skp1,skp2,alpha(x,y),beta(x,y),0.001,100);
+        vx(x,y)=skp1*e1-skp2*e2;
+        vy(x,y)=skp1*e2+skp2*e1;
+        
+        //project w
+        double l=sqrt(wx(x,y)*wx(x,y)+wy(x,y)*wy(x,y)+wz(x,y)*wz(x,y));
+        if (l>gamma(x,y)){
+          wx(x,y)=gamma(x,y)*wx(x,y)/l;
+          wy(x,y)=gamma(x,y)*wy(x,y)/l;  
+          #if (VIGRA_MIXED_2ND_DERIVATIVES)
+          wz(x,y)=gamma(x,y)*wz(x,y)/l;
+          #endif
+        }
+      }
+    }
+    
+    separableConvolveX(srcImageRange(vx),destImage(temp1),kernel1d(LTx));
+    separableConvolveY(srcImageRange(vy),destImage(temp2),kernel1d(LTx));
+    
+    u_bar=out;
+    out-=tau*(weight*(out-data)+temp1+temp2);
+    
+    
+    // update wx
+    separableConvolveX(srcImageRange(wx),destImage(temp1),kernel1d(Lx));setZeroX(temp1);
+    temp1*=xedges;
+    separableConvolveX(srcImageRange(temp1),destImage(temp2),kernel1d(LTx));
+    out+=tau*temp2; // (-1)^2
+    
+    
+    //update wy
+    separableConvolveY(srcImageRange(wy),destImage(temp1),kernel1d(Lx));setZeroY(temp1);
+    temp1*=yedges;
+    separableConvolveY(srcImageRange(temp1),destImage(temp2),kernel1d(LTx));
+    out+=tau*temp2; 
+    
+    //update wz
+    #if (VIGRA_MIXED_2ND_DERIVATIVES)
+    
+    separableConvolveY(srcImageRange(wz),destImage(temp1),kernel1d(Lx));setZeroY(temp1);
+    temp1*=yedges;
+    separableConvolveX(srcImageRange(temp1),destImage(temp2),kernel1d(LTx));
+    out+=tau*temp2;
+    
+    separableConvolveX(srcImageRange(wz),destImage(temp1),kernel1d(Lx));setZeroX(temp1);
+    temp1*=xedges;
+    separableConvolveY(srcImageRange(temp1),destImage(temp2),kernel1d(LTx));
+    out+=tau*temp2;
+    
+    #endif
+    
+    u_bar=2*out-u_bar;   //cf. Chambolle/Pock and Popov's algorithm
+    
+  }
+}
+
+//@}
+} // closing namespace vigra
+
+#endif // VIGRA_TV_FILTER_HXX
\ No newline at end of file
diff --git a/include/vigra/type_lists.hxx b/include/vigra/type_lists.hxx
new file mode 100644
index 0000000..bdaf0c5
--- /dev/null
+++ b/include/vigra/type_lists.hxx
@@ -0,0 +1,1929 @@
+/************************************************************************/
+/*                                                                      */
+/*    Copyright 2011-2012 by Markus Nullmeier and Ullrich Koethe        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_TYPE_LISTS_HXX
+#define VIGRA_TYPE_LISTS_HXX
+
+#include <iostream>
+#include <typeinfo>
+#include <utility>
+#include <algorithm>
+#include "metaprogramming.hxx"
+#include "bit_array.hxx"
+#include "error.hxx"
+
+namespace vigra {
+
+// mask cl.exe shortcomings [begin]
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4503 )
+#endif
+
+namespace type_lists {
+
+    struct nil; // end-of-list marker.
+    template <class T>
+    struct nil_t;
+    
+    // type lists of size >= 1.
+
+    template <class A, class B = nil> struct cons
+    {
+        typedef A first;
+        typedef B rest;
+    };
+
+    template <class X, class A, class B> struct if_nil
+    {
+        typedef B type;
+    };
+    template <class A, class B> struct if_nil <nil, A, B>
+    {
+        typedef A type;
+    };
+
+    // truncate type list L (using class NIL as ending marker)
+    // at the first occurence of type X
+    template <class X, class L, class NIL = nil> struct truncate
+    {
+        typedef cons<typename L::first,
+                     typename truncate<X, typename L::rest, NIL>::type> type;
+    };
+    template <class L, class NIL> struct truncate<typename L::first, L, NIL>
+    {
+        typedef nil type; // do the actual truncation
+    };
+    template <class X, class NIL> struct truncate<X, NIL, NIL>
+    {
+        typedef nil type;
+    };
+
+    template <class NIL, class A = NIL, class B = NIL, class C = NIL,
+                         class D = NIL, class E = NIL, class F = NIL,
+                         class G = NIL, class H = NIL, class I = NIL,
+                         class J = NIL, class K = NIL, class L = NIL,
+                         class M = NIL, class N = NIL, class O = NIL,
+                         class P = NIL, class Q = NIL, class R = NIL,
+                         class S = NIL, class T = NIL, class U = NIL,
+                         class V = NIL, class W = NIL, class X = NIL,
+                         class Y = NIL, class Z = NIL>
+    struct make_list_nil {
+        typedef typename truncate<NIL, cons<A, cons<B, cons<C, cons<D, cons<E,
+                                       cons<F, cons<G, cons<H, cons<I, cons<J,
+                                       cons<K, cons<L, cons<M, cons<N, cons<O,
+                                       cons<P, cons<Q, cons<R, cons<S, cons<T,
+                                       cons<U, cons<V, cons<W, cons<X, cons<Y,
+                                       cons<Z, NIL> > > > > > > > > > > > > > >
+                                       > > > > > > > > > > >, NIL>::type type;
+    };
+
+    template <class A = nil, class B = nil, class C = nil, class D = nil,
+              class E = nil, class F = nil, class G = nil, class H = nil,
+              class I = nil, class J = nil, class K = nil, class L = nil,
+              class M = nil, class N = nil, class O = nil, class P = nil,
+              class Q = nil, class R = nil, class S = nil, class T = nil,
+              class U = nil, class V = nil, class W = nil, class X = nil,
+              class Y = nil, class Z = nil>
+
+    struct make_list {
+        typedef typename make_list_nil<nil, A, B, C, D, E, F, G, H, I,
+                                            J, K, L, M, N, O, P, Q, R,
+                                            S, T, U, V, W, X, Y, Z
+                                      >::type type;
+    };
+
+    template <class T_, template<class> class A = nil_t,
+                        template<class> class B = nil_t,
+                        template<class> class C = nil_t,
+                        template<class> class D = nil_t,
+                        template<class> class E = nil_t,
+                        template<class> class F = nil_t,
+                        template<class> class G = nil_t,
+                        template<class> class H = nil_t,
+                        template<class> class I = nil_t,
+                        template<class> class J = nil_t,
+                        template<class> class K = nil_t,
+                        template<class> class L = nil_t,
+                        template<class> class M = nil_t,
+                        template<class> class N = nil_t,
+                        template<class> class O = nil_t,
+                        template<class> class P = nil_t,
+                        template<class> class Q = nil_t,
+                        template<class> class R = nil_t,
+                        template<class> class S = nil_t,
+                        template<class> class T = nil_t,
+                        template<class> class U = nil_t,
+                        template<class> class V = nil_t,
+                        template<class> class W = nil_t,
+                        template<class> class X = nil_t,
+                        template<class> class Y = nil_t,
+                        template<class> class Z = nil_t>
+    struct make_list_template {
+        typedef typename make_list_nil<nil_t<T_>,
+                                       A<T_>, B<T_>, C<T_>, D<T_>, E<T_>,
+                                       F<T_>, G<T_>, H<T_>, I<T_>, J<T_>,
+                                       K<T_>, L<T_>, M<T_>, N<T_>, O<T_>,
+                                       P<T_>, Q<T_>, R<T_>, S<T_>, T<T_>,
+                                       U<T_>, V<T_>, W<T_>, X<T_>, Y<T_>,
+                                       Z<T_> >::type type;
+    };
+
+    // a means to partially compensate for the lack of templated typedefs.
+    template <template<class, class> class BASE, class T_,
+                                                template<class> class A = nil_t,
+                                                template<class> class B = nil_t,
+                                                template<class> class C = nil_t,
+                                                template<class> class D = nil_t,
+                                                template<class> class E = nil_t,
+                                                template<class> class F = nil_t,
+                                                template<class> class G = nil_t,
+                                                template<class> class H = nil_t,
+                                                template<class> class I = nil_t,
+                                                template<class> class J = nil_t,
+                                                template<class> class K = nil_t,
+                                                template<class> class L = nil_t,
+                                                template<class> class M = nil_t,
+                                                template<class> class N = nil_t,
+                                                template<class> class O = nil_t,
+                                                template<class> class P = nil_t,
+                                                template<class> class Q = nil_t,
+                                                template<class> class R = nil_t,
+                                                template<class> class S = nil_t,
+                                                template<class> class T = nil_t,
+                                                template<class> class U = nil_t,
+                                                template<class> class V = nil_t,
+                                                template<class> class W = nil_t,
+                                                template<class> class X = nil_t,
+                                                template<class> class Y = nil_t,
+                                                template<class> class Z = nil_t>
+    struct use_template_list
+        : public BASE<T_, typename make_list_template<T_, A, B, C, D, E, F, G,
+                                                          H, I, J, K, L, M, N,
+                                                          O, P, Q, R, S, T, U,
+                                                          V, W, X, Y, Z>::type>
+    {};
+
+    // use first and rest only when possible:
+    template <class T>
+    struct has_first_rest : public sfinae_test<T, has_first_rest>
+    {
+        template <class U>
+        has_first_rest(U*, typename U::first* = 0, typename U::rest* = 0);
+    };
+    template <bool P, class A>
+    struct cond_cons_rest;
+    template <class A>
+    struct cond_cons_rest<false, A>
+    {
+        typedef void* type;
+    };
+    template <class A>
+    struct cond_cons_rest<true, A>
+    {
+        typedef typename A::rest type;
+    };
+    // test if a type is a list in the above sense.
+    template <class A> struct is_list
+    {
+        static const bool value = is_list<typename
+                      cond_cons_rest<has_first_rest<A>::value, A>::type>::value;
+    };
+    template <> struct is_list<nil>
+    {
+        static const bool value = true;
+    };
+    template <> struct is_list<void*>
+    {
+        static const bool value = false;
+    };
+
+    template <class A> struct list_guard
+    {
+        typedef typename IfBool<is_list<A>::value, A, nil>::type type;
+    };
+
+    template <class A> struct size
+    {
+        static const unsigned of = size<typename A::rest>::of + 1;
+    };
+    template <> struct size<nil>
+    {
+        static const unsigned of = 0;
+    };
+
+    template <class X, class L> struct append
+    {
+        typedef cons<typename L::first,
+                     typename append<X, typename L::rest>::type> type;
+    };
+    template <class X> struct append<X, nil>
+    {
+        typedef cons<X, nil> type;
+    };
+    template <> struct append<nil, nil>
+    {
+        typedef nil type;
+    };
+
+    template <class L, class R = nil> struct reverse
+    {
+        typedef typename reverse<typename L::rest,
+                                 cons<typename L::first, R> >::type type;
+    };
+    template <class R> struct reverse<nil, R>
+    {
+        typedef R type;
+    };
+
+    template <template<class> class P, class Q, class L>
+    struct max_value
+    {
+        static const bool is_nil = false;
+        static const Q first_value = P<typename L::first>::value;
+        typedef max_value<P, Q, typename L::rest> rest_type;
+        static const Q rest_value = rest_type::value;
+        static const bool gt = first_value > rest_value || rest_type::is_nil;
+        static const Q value = gt * first_value + !gt * rest_value;
+    };
+    template <template<class> class P, class Q>
+    struct max_value<P, Q, nil>
+    {
+        static const Q value = 0;
+        static const bool is_nil = true;
+    };
+
+    // remove the all occurences of type X in type list L
+    template <class X, class L> struct remove // recursion
+    {
+        typedef cons<typename L::first,
+                     typename remove<X, typename L::rest>::type> type;
+    };
+    template <class L> struct remove<typename L::first, L> // actual removal
+    {
+        typedef typename remove<typename L::first, typename L::rest>::type type;
+    };
+    template <class X> struct remove<X, nil> // list end
+    {
+        typedef nil type;
+    };
+
+    // remove the all occurences of type list L where predicate P equals value
+    template <template<class> class P, class L, bool value = true>
+    struct remove_if
+    {
+        typedef typename
+            IfBool<
+                value == P<typename L::first>::value, typename
+                remove_if<P, typename L::rest, value>::type,
+                cons<typename
+                    L::first, typename
+                    remove_if<P, typename L::rest, value>::type
+                >
+            >::type type;
+    };
+    template <template<class> class P, bool value>
+    struct remove_if<P, nil, value>
+    {
+        typedef nil type;
+    };
+
+    template <template<class> class P, class L>
+    struct remove_if_not
+    {
+        typedef typename remove_if<P, L, false>::type type;
+    };
+
+    template <class X, class L> struct contains
+    {
+        static const bool value = contains<X, typename L::rest>::value;
+    };
+    template <class L> struct contains<typename L::first, L>
+    {
+        static const bool value = true;
+    };
+    template <class X> struct contains<X, nil>
+    {
+        static const bool value = false;
+    };
+
+    // simple, unstable merge
+    template <class X, class L> struct merge
+    {
+        typedef typename L::first first;
+        typedef typename
+            merge<
+                    typename IfBool<contains<first, X>::value,
+                               X,
+                               cons<first, X>
+                          >::type,
+                    typename L::rest
+                 >::type type;
+    };
+    template <class X> struct merge<X, nil>
+    {
+        typedef X type;
+    };
+
+    // simple, unstable unique
+    template <class L> struct unique
+    {
+        typedef typename merge<nil, L>::type type;
+    };
+
+    template <class T_, template<class> class A = nil_t,
+                        template<class> class B = nil_t,
+                        template<class> class C = nil_t,
+                        template<class> class D = nil_t,
+                        template<class> class E = nil_t,
+                        template<class> class F = nil_t,
+                        template<class> class G = nil_t,
+                        template<class> class H = nil_t,
+                        template<class> class I = nil_t,
+                        template<class> class J = nil_t,
+                        template<class> class K = nil_t,
+                        template<class> class L = nil_t,
+                        template<class> class M = nil_t,
+                        template<class> class N = nil_t,
+                        template<class> class O = nil_t,
+                        template<class> class P = nil_t,
+                        template<class> class Q = nil_t,
+                        template<class> class R = nil_t,
+                        template<class> class S = nil_t,
+                        template<class> class T = nil_t,
+                        template<class> class U = nil_t,
+                        template<class> class V = nil_t,
+                        template<class> class W = nil_t,
+                        template<class> class X = nil_t,
+                        template<class> class Y = nil_t,
+                        template<class> class Z = nil_t>
+    struct implies_template
+    {
+        typedef typename make_list_template<T_, A, B, C, D, E, F, G, H, I, J, K,
+                                                L, M, N, O, P, Q, R, S, T, U, V,
+                                                W, X, Y, Z>::type implies_types;
+    };
+
+    template <class T_, template<class> class A = nil_t,
+                        template<class> class B = nil_t,
+                        template<class> class C = nil_t,
+                        template<class> class D = nil_t,
+                        template<class> class E = nil_t,
+                        template<class> class F = nil_t,
+                        template<class> class G = nil_t,
+                        template<class> class H = nil_t,
+                        template<class> class I = nil_t,
+                        template<class> class J = nil_t,
+                        template<class> class K = nil_t,
+                        template<class> class L = nil_t,
+                        template<class> class M = nil_t,
+                        template<class> class N = nil_t,
+                        template<class> class O = nil_t,
+                        template<class> class P = nil_t,
+                        template<class> class Q = nil_t,
+                        template<class> class R = nil_t,
+                        template<class> class S = nil_t,
+                        template<class> class T = nil_t,
+                        template<class> class U = nil_t,
+                        template<class> class V = nil_t,
+                        template<class> class W = nil_t,
+                        template<class> class X = nil_t,
+                        template<class> class Y = nil_t,
+                        template<class> class Z = nil_t>
+    struct follows_template
+    {
+        typedef typename make_list_template<T_, A, B, C, D, E, F, G, H, I, J, K,
+                                                L, M, N, O, P, Q, R, S, T, U, V,
+                                                W, X, Y, Z>::type follows_types;
+    };
+
+    template <class T_, template<class> class A = nil_t,
+                        template<class> class B = nil_t,
+                        template<class> class C = nil_t,
+                        template<class> class D = nil_t,
+                        template<class> class E = nil_t,
+                        template<class> class F = nil_t,
+                        template<class> class G = nil_t,
+                        template<class> class H = nil_t,
+                        template<class> class I = nil_t,
+                        template<class> class J = nil_t,
+                        template<class> class K = nil_t,
+                        template<class> class L = nil_t,
+                        template<class> class M = nil_t,
+                        template<class> class N = nil_t,
+                        template<class> class O = nil_t,
+                        template<class> class P = nil_t,
+                        template<class> class Q = nil_t,
+                        template<class> class R = nil_t,
+                        template<class> class S = nil_t,
+                        template<class> class T = nil_t,
+                        template<class> class U = nil_t,
+                        template<class> class V = nil_t,
+                        template<class> class W = nil_t,
+                        template<class> class X = nil_t,
+                        template<class> class Y = nil_t,
+                        template<class> class Z = nil_t>
+    struct depends_on_template
+    {
+        typedef typename make_list_template<T_, A, B, C, D, E, F, G, H, I, J, K,
+                                                L, M, N, O, P, Q, R, S, T, U, V,
+                                                W, X, Y, Z>::type depends_on;
+    };
+
+    template <class T_u, template<class> class A = nil_t,
+                         template<class> class B = nil_t,
+                         template<class> class C = nil_t,
+                         template<class> class D = nil_t,
+                         template<class> class E = nil_t,
+                         template<class> class F = nil_t,
+                         template<class> class G = nil_t,
+                         template<class> class H = nil_t,
+                         template<class> class I = nil_t,
+                         template<class> class J = nil_t,
+                         template<class> class K = nil_t,
+                         template<class> class L = nil_t,
+                         template<class> class M = nil_t,
+                         template<class> class N = nil_t,
+                         template<class> class O = nil_t,
+                         template<class> class P = nil_t,
+                         template<class> class Q = nil_t,
+                         template<class> class R = nil_t,
+                         template<class> class S = nil_t,
+                         template<class> class T = nil_t,
+                         template<class> class U = nil_t,
+                         template<class> class V = nil_t,
+                         template<class> class W = nil_t,
+                         template<class> class X = nil_t,
+                         template<class> class Y = nil_t,
+                         template<class> class Z = nil_t>
+    struct uses_template
+        : public implies_template<T_u, A, B, C, D, E, F, G, H, I, J, K, L, M,
+                                       N, O, P, Q, R, S, T, U, V, W, X, Y, Z>,
+          public depends_on_template<T_u, A, B, C, D, E, F, G, H, I, J, K, L, M,
+                                       N, O, P, Q, R, S, T, U, V, W, X, Y, Z>
+    {
+        template <template<class> class A_ = nil_t,
+                  template<class> class B_ = nil_t,
+                  template<class> class C_ = nil_t,
+                  template<class> class D_ = nil_t,
+                  template<class> class E_ = nil_t,
+                  template<class> class F_ = nil_t,
+                  template<class> class G_ = nil_t,
+                  template<class> class H_ = nil_t,
+                  template<class> class I_ = nil_t,
+                  template<class> class J_ = nil_t,
+                  template<class> class K_ = nil_t,
+                  template<class> class L_ = nil_t,
+                  template<class> class M_ = nil_t,
+                  template<class> class N_ = nil_t,
+                  template<class> class O_ = nil_t,
+                  template<class> class P_ = nil_t,
+                  template<class> class Q_ = nil_t,
+                  template<class> class R_ = nil_t,
+                  template<class> class S_ = nil_t,
+                  template<class> class T_ = nil_t,
+                  template<class> class U_ = nil_t,
+                  template<class> class V_ = nil_t,
+                  template<class> class W_ = nil_t,
+                  template<class> class X_ = nil_t,
+                  template<class> class Y_ = nil_t,
+                  template<class> class Z_ = nil_t>
+        struct follows
+            : public uses_template
+            , public follows_template<T_u, A_, B_, C_, D_, E_, F_, G_, H_, I_,
+                                           J_, K_, L_, M_, N_, O_, P_, Q_, R_,
+                                           S_, T_, U_, V_, W_, X_, Y_, Z_> {};
+
+        template <template<class> class A_ = nil_t,
+                  template<class> class B_ = nil_t,
+                  template<class> class C_ = nil_t,
+                  template<class> class D_ = nil_t,
+                  template<class> class E_ = nil_t,
+                  template<class> class F_ = nil_t,
+                  template<class> class G_ = nil_t,
+                  template<class> class H_ = nil_t,
+                  template<class> class I_ = nil_t,
+                  template<class> class J_ = nil_t,
+                  template<class> class K_ = nil_t,
+                  template<class> class L_ = nil_t,
+                  template<class> class M_ = nil_t,
+                  template<class> class N_ = nil_t,
+                  template<class> class O_ = nil_t,
+                  template<class> class P_ = nil_t,
+                  template<class> class Q_ = nil_t,
+                  template<class> class R_ = nil_t,
+                  template<class> class S_ = nil_t,
+                  template<class> class T_ = nil_t,
+                  template<class> class U_ = nil_t,
+                  template<class> class V_ = nil_t,
+                  template<class> class W_ = nil_t,
+                  template<class> class X_ = nil_t,
+                  template<class> class Y_ = nil_t,
+                  template<class> class Z_ = nil_t>
+        struct implies
+            : public uses_template
+        {
+            typedef typename
+                merge<typename
+                    uses_template::implies_types, typename
+                    implies_template<T_u, A_, B_, C_, D_, E_, F_, G_, H_, I_,
+                                          J_, K_, L_, M_, N_, O_, P_, Q_, R_,
+                                          S_, T_, U_, V_, W_, X_, Y_, Z_>
+                        ::implies_types
+                >::type
+            implies_types;
+        };
+    };
+
+    // for_all() helper class.
+    template <template<class> class EXEC, class L> struct for_exec
+    {
+        template <class TX>
+        static void all(TX & tx)
+        {
+            EXEC<typename L::first>::exec(tx);
+            for_exec<EXEC, typename L::rest>::all(tx);
+        }
+    };
+    template <template<class> class EXEC> struct for_exec<EXEC, nil>
+    {
+        template <class TX> static void all(TX &) {}
+    };
+    // for_all on type lists.
+    // for all types T in the list L,
+    // calls the static member function EXEC<T>::exec(TX & tx).
+    template <class L, template<class> class EXEC, class TX>
+    inline void for_all(TX & tx)
+    {
+        for_exec<EXEC, L>::all(tx);
+    }
+
+    template <class T>
+    struct has_depends_on : public sfinae_test<T, has_depends_on>
+    {
+        template <class U> has_depends_on(U*, typename U::depends_on* = 0);
+    };
+    template <class T>
+    struct has_implies : public sfinae_test<T, has_implies>
+    {
+        template <class U> has_implies(U*, typename U::implies_types* = 0);
+    };
+    template <class T>
+    struct has_follows : public sfinae_test<T, has_follows>
+    {
+        template <class U> has_follows(U*, typename U::follows_types* = 0);
+    };
+
+    // use empty list in case of lacking / faulty depends_on or implies_types:
+    template <bool P, class T>
+    struct depends_on_guard;
+    template <class T>
+    struct depends_on_guard<false, T>
+    {
+        typedef nil type;
+    };
+    template <class T>
+    struct depends_on_guard<true, T>
+    {
+        typedef typename list_guard<typename T::depends_on>::type type;
+    };
+    template <class T>
+    struct get_pure_depends_on
+    {
+        typedef typename depends_on_guard<has_depends_on<T>::value, T>::type
+            type;
+    };
+
+    template <bool P, class T>
+    struct follows_guard;
+    template <class T>
+    struct follows_guard<false, T>
+    {
+        typedef nil type;
+    };
+    template <class T>
+    struct follows_guard<true, T>
+    {
+        typedef typename list_guard<typename T::follows_types>::type type;
+    };
+    template <class T>
+    struct get_follows
+    {
+        typedef typename follows_guard<has_follows<T>::value, T>::type
+            type;
+    };
+
+    template <class T>
+    struct get_depends_on
+    {
+        typedef typename merge<typename get_pure_depends_on<T>::type,
+                               typename get_follows<T>::type       >::type type;
+    };
+
+    template <bool P, class T>
+    struct implies_guard;
+    template <class T>
+    struct implies_guard<false, T>
+    {
+        typedef nil type;
+    };
+    template <class T>
+    struct implies_guard<true, T>
+    {
+        typedef typename list_guard<typename T::implies_types>::type type;
+    };
+    template <class T>
+    struct get_implies
+    {
+        typedef typename implies_guard<has_implies<T>::value, T>::type
+            type;
+    };
+
+    template <class L> struct implies_expand
+    {
+        typedef typename L::first first;
+        typedef typename L::rest  rest;
+        typedef
+            cons<first, typename
+                        merge<typename
+                              implies_expand<rest>::type, typename
+                              implies_expand<typename
+                                  get_implies<first>
+        ::type>::type>::type> type;
+    };
+    template <> struct implies_expand<nil>
+    {
+        typedef nil type;
+    };
+
+    // for_all with type list == T::depends_on (if any.)
+    template <class T, template<class> class EXEC, class TX>
+    inline void for_all_used(TX & tx)
+    {
+        for_all<typename get_pure_depends_on<T>::type, EXEC>(tx);
+    }
+
+    template <class X, class T>
+    struct contains_dependent
+    {
+        static const bool value
+            = contains<X, typename get_depends_on<T>::type>::value;
+    };
+
+    template <class X, class XL> struct is_independent_on
+    {
+        static const bool value
+            = ChooseBool<contains_dependent<X, typename XL::first>,
+                            VigraFalseType,
+                            is_independent_on<X, typename XL::rest>
+                        >::value;
+    };
+    template <class X> struct is_independent_on<X, nil>
+    {
+        static const bool value = true;
+    };
+
+    template <class XL, class YL = XL> struct get_independent
+    {
+        typedef typename YL::first YL_first;
+        typedef typename
+        IfBool<is_independent_on<YL_first, XL>::value,
+                          YL_first,
+                          typename get_independent<XL, typename YL::rest>::type
+              >::type type;
+    };
+    template <class XL> struct get_independent<XL, nil>
+    {
+        typedef nil type;
+    };
+
+    // the output is a list of types in reverse order, starting with the
+    // most depedent types.
+    template <class L> struct topo_sort
+    {
+        typedef typename get_independent<L>::type indep;
+        typedef typename
+        if_nil<indep,
+                  nil,
+                  cons<indep,
+                      typename topo_sort<typename remove<indep, L>::type>::type
+                      >
+              >::type type;
+    };
+    template <> struct topo_sort<nil>
+    {
+        typedef nil type;
+    };
+
+    // Topological sort -- the input is a list of types (see below),
+    // each of which may, optionally, have an embedded typedef 'depends_on'
+    // set to a singly-linked-list of types declared
+    // using vigra::type_lists::cons, such as
+    // cons<type_a, cons<type_b, cons<type_c> > >
+    // (a one-parameter cons will add the trailing nil automatically),
+    // -- the output is a list of types with increasing dependence,
+    // starting with the indepedent types.
+    // Types that should be said lists -- but are in fact not -- are silently
+    // replaced by empty lists.
+
+    template <class L> struct topological_sort
+    {
+        typedef typename
+            reverse<typename
+                topo_sort<typename
+                    unique<typename
+                        list_guard<L>
+        ::type>::type>::type>::type type;
+    };
+
+    template <class L> struct topological_sort_expanded
+    {
+        typedef typename
+            topological_sort<typename
+                implies_expand<L>
+        ::type>::type type;
+    };
+
+    template <class V, unsigned pos = 0>
+    class cond_val : public V
+    {
+        typedef V load_type;
+    protected:
+        bool is_set_;
+    public:
+        cond_val() : is_set_(false) {}
+        const V & val() const { return *this; }
+              V & val()       { return *this; }
+
+        template <class TUPLE>
+        bool is_set(const TUPLE &) const
+        {
+            return is_set_;
+        }
+
+        template <class TUPLE>
+        void set(TUPLE &)
+        {
+            is_set_ = true;
+        }
+        template <class TUPLE>
+        void set(const V & v, TUPLE & tuple)
+        {
+            set(tuple);
+            val() = v;
+        }
+        friend std::ostream & operator<<(std::ostream & os, const cond_val & x)
+        {
+            if (x.is_set_)
+                os << x.val(x);
+            else
+                os << "<nil>";
+            return os;
+        }
+    };
+
+    template <class V, unsigned pos>
+    class bit_cond_val : public V
+    {
+        typedef V load_type;
+    public:
+        const V & val() const { return *this; }
+              V & val()       { return *this; }
+
+        template <class TUPLE>
+        bool is_set(const TUPLE & tuple) const
+        {
+            return tuple.template is_bit_set<pos>();
+        }
+
+        template <class TUPLE>
+        void set(TUPLE & tuple)
+        {
+            tuple.template set_bit<pos>();
+        }
+        template <class TUPLE>
+        void set(const V & v, TUPLE & tuple)
+        {
+            set(tuple);
+            val() = v;
+        }
+    };
+
+    // no templated virtual functions in C++ ...
+    //
+    // simple_member_dispatch: sample base and polymorphic adapter classes
+    // for cond_virtual_tuple / etc.
+    // -- the names 'member_base_type' and 'load_type' of the templates,
+    // and also their parameter types, are fixed.
+    // -- note that the member_base_type template of any "member_dispatch"
+    // class can not directly serve as a base class for any member type that
+    // is used within the tuple, since the signatures of most of the
+    // virtual functions that are usually needed necessarily require the
+    // type of the tuple itself.
+    //
+    struct simple_member_dispatch
+    {
+        template <class ACX, class T>
+        struct member_base_type
+        {
+            virtual void operator()() {}
+            virtual void operator()(ACX &, const T &) {}
+            virtual void operator()(const ACX &, const ACX &, const ACX &) {}
+            virtual void call(ACX &, const T &, unsigned) {}
+            virtual ~member_base_type() {}
+        };
+        template <class ACX, class T, class V>
+        struct load_type : public member_base_type<ACX, T>, public V
+        {
+            load_type() {}
+            load_type(const V & v) : V(v) {}
+            void operator()()
+            {
+                V::operator()();
+            }
+            void operator()(ACX & x, const T & v)
+            {
+                V::operator()(x, v);
+            }
+            void operator()(const ACX & z, const ACX & x, const ACX & y)
+            {
+                V::operator()(z, x, y);
+            }
+            void call(ACX & x, const T & v, unsigned n)
+            {
+                V::call(x, v, n);
+            }
+        };
+    };
+
+    // polymorphic (conditional) tuple entry, modelled after cond_val
+    template <class ACX, class T,  class Z, class V>
+    class tuple_entry
+    {
+        typedef typename Z::template load_type<ACX, T, V> load_type;
+        typedef load_type*                                ptr_type;
+
+    protected:
+        ptr_type p;
+        
+    public:
+        tuple_entry() : p(0) {}
+        template <class TUPLE>
+        bool is_set(const TUPLE &) const { return p != 0; }
+
+    protected:
+        void make_load()
+        {
+            if (!p)
+                p = new load_type;
+        }
+        void assign(const V & v)
+        {
+            ptr_type tmp = new load_type(v);
+            delete p;
+            p = tmp;
+        }
+        void check_pointer() const
+        {
+            if (!p)
+                vigra_fail("tuple_entry::operator V &: unused tuple entry "
+                           "type V = [" + std::string(typeid(V).name()) + "], "
+                           "use set() to create an entry.");
+        }
+    public:
+        operator const V & () const
+        {
+            check_pointer();
+            return *p;
+        }
+        operator V & ()
+        {
+            check_pointer();
+            return *p;
+        }
+
+        template <class TUPLE> // not neccearily identical to ACX
+        void set(TUPLE & tuple)
+        {
+            make_load();
+        }
+        template <class TUPLE>
+        void set(const V & v, TUPLE & tuple)
+        {
+            set(tuple);
+            assign(v);
+        }
+
+        tuple_entry & operator=(tuple_entry const & e)
+        {
+            ptr_type tmp = new load_type(*e.p);
+            delete p;
+            p = tmp;
+            return *this;
+        }
+        tuple_entry(tuple_entry const & e)
+            : p(0)
+        {
+            if (e.p) // properly care for empty original
+                p = new load_type(*e.p);
+        }
+        ~tuple_entry()
+        {
+            delete p;
+        }
+        friend std::ostream & operator<<(std::ostream & os,
+                                                          const tuple_entry & x)
+        {
+            if (x.p)
+                os << x.val(x);
+            else
+                os << "<nil>";
+            return os;
+        }
+    };
+
+    // pos is the position of type V in the type list of the tuple
+    template <class ACX, class T, class Z, class V, unsigned pos>
+    struct cond_tuple_entry : public tuple_entry<ACX, T, Z, V>
+    {
+        template <class TUPLE> // not quite identical to ACX
+        void set(TUPLE & tuple)
+        {
+            this->make_load();
+            tuple.template add<V>(this->p, pos);
+        }
+        template <class TUPLE>
+        void reassign(TUPLE & tuple)
+        {
+            if (this->p)
+                tuple.reassign(this->p, pos);
+        }
+        template <class TUPLE>
+        void set(const V & v, TUPLE & tuple)
+        {
+            set(tuple);
+            this->assign(v);
+        }
+    };
+   
+    // helper classes for tuples
+    
+    template <unsigned pos, class X>
+    struct at_finder
+    {
+        typedef at_finder<pos - 1, typename X::rest_type> next_type;
+        typedef typename next_type::type type;
+        static
+        type & at(X & x)
+        {
+            return next_type::at(x.rest);
+        }
+    };
+    template <class X>
+    struct at_finder<0, X>
+    {
+        typedef typename X::first_type type;
+        static
+        type & at(X & x) {
+            return x.first;
+        }
+    };
+
+    template <class T, class X>
+    struct sub_finder
+    {
+        typedef typename X::rest_type rest_type;
+        typedef sub_finder<T, rest_type>
+                next_type;
+        typedef typename next_type::type type;
+        static type & object(X & x)
+        {
+            return next_type::object(x.rest);
+        }
+        static const type & const_object(const X & x)
+        {
+            return next_type::const_object(x.rest);
+        }
+    };
+    template <class X>
+    struct sub_finder<typename X::finder_type, X>
+    {
+        typedef X type;
+        static type & object(X & x)
+        {
+            return x;
+        }
+        static const type & const_object(const X & x)
+        {
+            return x;
+        }
+    };
+
+    template <class T, class X>
+    struct ref_finder
+    {
+        typedef          sub_finder<T, X>         finder;
+        typedef typename finder::type::first_type type;
+        static
+        type & ref(X & x)
+        {
+            return finder::object(x).first;
+        }
+        static
+        const type & ref(const X & x)
+        {
+            return finder::const_object(x).first;
+        }
+    };
+
+    struct binder_0
+    {
+        template <class F>
+        void operator()(F & first)
+        {
+            first();
+        }
+        template <class F>
+        void call(F & first)
+        {
+            first.call();
+        }
+    };
+    template <class A>
+    struct binder_1
+    {
+        A v;
+        binder_1(A v_) : v(v_) {}
+        template <class F>
+        void operator()(F & first)
+        {
+            first(v);
+        }
+        template <class F>
+        void call(F & first)
+        {
+            first.call(v);
+        }
+    };
+    template <class A, class B>
+    struct binder_2
+    {
+        A v;
+        B w;
+        binder_2(A v_, B w_) : v(v_), w(w_) {}
+        template <class F>
+        void operator()(F & first)
+        {
+            first(v, w);
+        }
+        template <class F>
+        void call(F & first)
+        {
+            first.call(v, w);
+        }
+    };
+    template <class A, class B, class C>
+    struct binder_3
+    {
+        A v;
+        B w;
+        C x;
+        binder_3(A v_, B w_, C x_) : v(v_), w(w_), x(x_) {}
+        template <class F>
+        void operator()(F & first)
+        {
+            first(v, w, x);
+        }
+        template <class F>
+        void call(F & first)
+        {
+            first.call(v, w, x);
+        }
+    };
+
+    // mechanism for iterative application of operator() to a tuple
+    template <template <class> class TEST>
+    struct exec_op_plain
+    {
+        template <class TUPLE, class B, class TBASE>
+        static void exec(TUPLE & tuple, B & binder, const TBASE & z)
+        {
+            binder(tuple.first);
+            tuple.rest.exec_bound_op(binder, z);
+        }
+        template <class TUPLE, class B, class TBASE>
+        static void call(TUPLE & tuple, B & binder, const TBASE & z)
+        {
+            typedef typename TUPLE::ref_finder_type ref_finder_type;
+            if (TEST<ref_finder_type>::value)
+                binder.call(static_cast<ref_finder_type &> (tuple.first));
+            tuple.rest.call_bound_op(binder, z);
+        }
+    };
+
+    // policy classes for tuples
+    struct plain_global_data
+    {
+        void reassign() {}
+    };
+    
+    struct plain_chooser // this policy does effectively nothing.
+    {
+        template <class V, unsigned pos = 0>
+        struct use
+        {
+             typedef V type;
+        };
+
+        template <class, template <class> class TEST>
+        struct exec_op : public exec_op_plain<TEST> {};
+
+        // "M" & "S" -> bug in cl.exe's parser.
+        template <template<class, class, template<class> class M, unsigned>
+                  class, class, template<class> class S, unsigned>
+        struct global_data : public plain_global_data
+        {
+            typedef global_data global_data_type;
+        };
+        template <class QV, class TUPLE>
+        static bool is_set(const QV &, const TUPLE &) { return true; }
+        template <class QV, class TUPLE>
+        static void set(QV &, TUPLE &) {}
+    };
+
+                        // this policy uses the cond_val template to annotate
+                        // each tuple member with a bool that steers conditional
+                        // execution of each member's operator(), if called via
+                        // the tuple's operator().
+    struct cond_chooser_plain : public plain_chooser
+    {
+        template <class V, unsigned pos = 0>
+        struct use
+        {
+            typedef cond_val<V, pos> type;
+        };
+
+        template <class, template <class> class TEST>
+        struct exec_op
+        {
+            template <class TUPLE, class B, class TBASE>
+            static void exec(TUPLE & tuple, B & binder, const TBASE & z)
+            {
+                typedef typename TUPLE::ref_finder_type ref_finder_type;
+                if (tuple.first.is_set(z))
+                    binder(static_cast<ref_finder_type &>(tuple.first));
+                tuple.rest.exec_bound_op(binder, z);
+            }
+            template <class TUPLE, class B, class TBASE>
+            static void call(TUPLE & tuple, B & binder, const TBASE & z)
+            {
+                typedef typename TUPLE::ref_finder_type ref_finder_type;
+                if (TEST<ref_finder_type>::value)
+                    if (tuple.first.is_set(z))
+                        binder.call(static_cast<ref_finder_type &>
+                                                                 (tuple.first));
+                tuple.rest.call_bound_op(binder, z);
+            }
+        };
+
+        template <class QV, class TUPLE>
+        static bool is_set(const QV & qv, const TUPLE & t)
+        {
+            return qv.is_set(t);
+        }
+        template <class QV, class TUPLE>
+        static void set(QV & qv, TUPLE & t)
+        {
+            qv.set(t);
+        }
+    };
+    
+    // start the machinery for cond_chooser that produces nested 'if's
+
+    template <class X, class T, class L = typename get_pure_depends_on<T>::type>
+    struct depends_on_deep
+    {
+        static const bool value =
+            depends_on_deep<X, T, typename L::rest>::value   // iterate list
+            || depends_on_deep<X, typename L::first>::value; // indirect dep.
+    };
+    template <class T, class L>
+    struct depends_on_deep<typename L::first, T, L>
+    {
+        static const bool value = true;
+    };
+    template <class X, class T>
+    struct depends_on_deep<X, T, nil>
+    {
+        static const bool value = false;
+    };
+
+    template <class T, class R>
+    struct first_depends_on
+    {
+        static const bool value
+            =  depends_on_deep<typename R::first, T>::value;
+    };
+    template <class T>
+    struct first_depends_on<T, nil>
+    {
+        static const bool value = false;
+    };
+
+    template <class RRL, class R>
+    struct first_depends_on_all_of
+    {
+        static const bool value
+            = ChooseBool<
+                  first_depends_on<typename
+                      RRL::first,
+                      R
+                  >,
+                  first_depends_on_all_of<typename RRL::rest, R>,
+                  VigraFalseType
+              >::value;
+    };
+    template <class R> // end of list RRL: 'success'
+    struct first_depends_on_all_of<nil, R>
+    {
+        static const bool value = true;
+    };
+    template <class RRL> // 'invalid' input (e.g., at end of cond_op recursion)
+    struct first_depends_on_all_of<RRL, nil>
+    {
+        static const bool value = false;
+    };
+    template <> // 'invalid' input (e.g., at end of cond_op recursion)
+    struct first_depends_on_all_of<nil, nil>
+    {
+        static const bool value = false;
+    };
+
+    // helper structs for cond_op:
+    struct null_exec
+    {
+        template <class TUPLE, class B, class TBASE>
+        static void exec(TUPLE &, B &, const TBASE &) {}
+        template <class TUPLE, class B, class TBASE>
+        static void call(TUPLE &, B &, const TBASE &) {}
+        typedef nil iter_leftover_type;
+    };
+    template <bool cond, class EX>
+    struct if_then
+    {
+        template <class TUPLE, class B, class TBASE>
+        static void exec(TUPLE & t, B & b, const TBASE & z)
+        {
+            IfBool<cond, EX, null_exec>::type::exec(t, b, z);
+        }
+        template <class TUPLE, class B, class TBASE>
+        static void call(TUPLE & t, B & b, const TBASE & z)
+        {
+            IfBool<cond, EX, null_exec>::type::call(t, b, z);
+        }
+    };
+    template <class ZL, template <class> class TEST, class RRL>
+    struct cond_op_inner;
+    
+    template <class ZL, template <class> class TEST, class RRL = nil>
+    struct cond_op
+    {
+        typedef typename ZL::first             first_type;
+        typedef typename ZL::rest              rest_type;
+        typedef          cons<first_type, RRL> next_rr_list;
+
+        static const bool recurse_deep
+            = first_depends_on<first_type, rest_type>::value;
+        typedef cond_op<rest_type, TEST, next_rr_list>
+            deep_type;
+
+        typedef typename IfBool<recurse_deep, typename
+                                deep_type::iter_leftover_type,
+                                rest_type
+                               >::type
+            deep_leftover_type;
+
+        static const bool iterate
+            = first_depends_on_all_of<RRL, deep_leftover_type>::value;
+
+        typedef cond_op_inner<deep_leftover_type, TEST, RRL>
+            iter_type;
+
+        // the type list left over from the deep first recursion of exec()
+        // and the iteration step: the recursion patterns of both the type
+        // 'iter_leftover_type' and the function 'exec()' must match.
+        typedef typename IfBool<iterate, typename
+                                iter_type::iter_leftover_type,
+                                deep_leftover_type
+                               >::type
+            iter_leftover_type;
+
+        // the code generation templates
+        template <class TUPLE, class B, class TBASE>
+        static void exec(TUPLE & tuple, B & binder, const TBASE & z)
+        {
+            if (tuple.first.is_set(z))
+            {
+                binder(tuple.first);
+                if_then<recurse_deep, deep_type>::exec(tuple.rest, binder, z);
+            }
+            if_then<iterate, iter_type>::exec(tuple, binder, z);
+        }
+        template <class TUPLE, class B, class TBASE>
+        static void call(TUPLE & tuple, B & binder, const TBASE & z)
+        {
+            if (tuple.first.is_set(z))
+            {
+                typedef typename TUPLE::ref_finder_type ref_finder_type;
+                if (TEST<ref_finder_type>::value)
+                    binder.call(static_cast<ref_finder_type &> (tuple.first));
+                    
+                if_then<recurse_deep, deep_type>::call(tuple.rest, binder, z);
+            }
+            if_then<iterate, iter_type>::call(tuple, binder, z);
+        }
+    };
+    template <template <class> class TEST, class RRL> // end of type list ZL
+    struct cond_op<nil, TEST, RRL> : public null_exec {};
+
+    template <template <class> class TEST, class RRL> // end of type list ZL
+    struct cond_op_inner<nil, TEST, RRL> : public null_exec {};
+
+    template <class ZL, template <class> class TEST, class RRL>
+    struct cond_op_inner
+    {
+        typedef cond_op<ZL, TEST, RRL> exec_type;
+        typedef typename exec_type::iter_leftover_type iter_leftover_type;
+
+        template <class TUPLE, class B, class TBASE>
+        static void exec(TUPLE & tuple, B & binder, const TBASE & z)
+        {
+            exec_type::
+                exec(sub_finder<typename ZL::first, TUPLE>::object(tuple),
+                     binder,
+                     z);
+        }
+        template <class TUPLE, class B, class TBASE>
+        static void call(TUPLE & tuple, B & binder, const TBASE & z)
+        {
+            exec_type::
+                call(sub_finder<typename ZL::first, TUPLE>::object(tuple),
+                     binder,
+                     z);
+        }
+    };
+
+    struct cond_chooser : public cond_chooser_plain
+    {
+        template <class ZL, template <class> class TEST>
+        struct exec_op : public cond_op<ZL, TEST> {};
+    };
+
+    struct bit_cond_chooser : public cond_chooser
+    {
+        template <class V, unsigned pos>
+        struct use
+        {
+            typedef bit_cond_val<V, pos> type;
+        };
+
+        // cl.exe wants this -- maybe it is right.
+        template <template<class, class, template<class> class M, unsigned>
+                  class, class, template<class> class S, unsigned>
+        struct global_data : public plain_global_data
+        {
+            typedef global_data global_data_type;
+        };
+        template <template<class, class, template<class> class M, unsigned>
+                  class TBASE, class ITL, template<class> class TEST>
+        struct global_data<TBASE, ITL, TEST, 0> : public plain_global_data
+        {
+            // typedef to catch our copy constructor and assignment operator:
+            typedef global_data global_data_type;
+
+            BitArray<size<ITL>::of> bit_set;
+
+            void clear() { bit_set.clear(); }
+            template <unsigned pos>
+            void set_bit() { bit_set.template set<pos>(); }
+            template <unsigned pos>
+            bool is_bit_set() const { return bit_set.template test<pos>(); }
+        };
+    };
+
+    template <class ACX, class T, class Z>
+    struct virtual_chooser: public cond_chooser_plain
+    {
+        template <class V, unsigned pos = 0>
+        struct use
+        {
+            typedef tuple_entry<ACX, T, Z, V> type;
+        };
+    };
+
+    template <class T> struct set_exec
+    {
+        template <class ACX>
+        static void exec(ACX & x)
+        {
+            x.template set<T>();
+        }
+    };
+
+    template <class ACX, class T, class Z>
+    struct cond_virtual_chooser: public cond_chooser_plain
+    {
+        template <class V, unsigned pos = 0>
+        struct use
+        {
+            typedef cond_tuple_entry<ACX, T, Z, V, pos> type;
+        };
+
+        template <class, template <class> class TEST>
+        struct exec_op
+        {
+            template <class TUPLE, class B, class TBASE>
+            static void exec(TUPLE & tuple, B & binder, const TBASE &)
+            {
+                for (unsigned i = 0; i != tuple.execs.size; ++i)
+                    binder(*tuple.execs.pointers[i]);
+            }
+            template <class TUPLE, class B, class TBASE>
+            static void call(TUPLE & tuple, B & binder, const TBASE &)
+            {
+                for (unsigned i = 0; i != tuple.callers.size; ++i)
+                    binder.call(*tuple.callers.pointers[i]);
+            }
+        };
+        // cl.exe wants this -- maybe it is right.
+        template <template<class, class, template<class> class M, unsigned>
+                  class, class, template<class> class S, unsigned>
+        struct global_data : public plain_global_data
+        {
+            typedef global_data global_data_type;
+        };
+
+        template <class ITL>
+        struct global_data_pointers // weak pointers
+        {
+            typedef typename Z::template member_base_type<ACX, T>* pointer_type;
+            static const unsigned array_len = size<ITL>::of;
+
+            unsigned     orders  [array_len]; // consciously use two arrays
+            unsigned     size;
+            pointer_type pointers[array_len];
+
+            void clear()
+            {
+                size = 0;
+            }
+            global_data_pointers()
+            {
+                clear();
+            }
+            unsigned* end(unsigned* = 0)
+            {
+                return orders + size;
+            }
+            pointer_type* end(pointer_type*)
+            {
+                return pointers + size;
+            }
+            template <class E>
+            void make_room(E* i)
+            {
+                std::copy_backward(i, end(i), end(i) + 1);
+            }
+            typedef std::pair<unsigned*, pointer_type*> finder;
+            bool find(unsigned pos, finder & found)
+            {
+                found.first  = std::lower_bound(orders, end(), pos);
+                found.second = pointers + (found.first - orders);
+                return found.first != end() && *found.first == pos;
+            }
+            void add(pointer_type p, unsigned pos)
+            {
+                // merge pointer according to its topological sort order
+                finder found;
+                if (find(pos, found))
+                    return;
+                make_room(found.first);
+                make_room(found.second);
+                ++size;
+                *found.first  = pos;
+                *found.second = p;
+            }
+            void reassign(pointer_type p, unsigned pos)
+            {
+                // replace pointers -- the present values still belong to
+                // the old tuple object that was copied from
+                finder found;
+                if (find(pos, found))
+                    *found.second = p;
+            }
+        };
+        template <template<class, class, template<class> class M, unsigned>
+                  class TBASE, class ITL, template<class> class TEST>
+        struct global_data<TBASE, ITL, TEST, 0>
+        {
+            // typedef to catch our copy constructor and assignment operator:
+            typedef global_data global_data_type;
+            // the derived class:
+            typedef TBASE<ITL, cond_virtual_chooser, TEST, 0> crtp_type;
+
+            typedef global_data_pointers<ITL>        ptrs_type;
+            typedef typename ptrs_type::pointer_type pointer_type;
+            ptrs_type callers;
+            ptrs_type execs;
+
+            template <class V>
+            void add(pointer_type p, unsigned pos)
+            {
+                execs.add(p, pos);
+                if (TEST<V>::value)
+                    callers.add(p, pos);
+            }
+            void reassign(pointer_type p, unsigned pos)
+            {
+                execs.  reassign(p, pos);
+                callers.reassign(p, pos);
+            }
+
+            template <class V>
+            struct reassign_op
+            {
+                static void exec(crtp_type & tuple)
+                {
+                    tuple.template ref<V>().reassign(tuple);
+                }
+            };
+
+            void reassign()
+            {
+                for_all<ITL, reassign_op>(static_cast<crtp_type &>(*this));
+            }
+        };
+    };
+
+
+    template <class ITL, class Q = plain_chooser,
+              template<class> class TEST = true_test, unsigned index = 0>
+    struct tuple_base
+        : public Q::template global_data<tuple_base, ITL, TEST, index>
+    {
+        typedef typename tuple_base::global_data_type global_data_base_type;
+        typedef nil derived_type; // dummy declaration for static_cast_2<>
+        typedef tuple_base tuple_type;
+        typedef ITL        list_type;
+
+        // use the original types from the list to find tuple members via ref():
+        typedef typename ITL::first                            finder_type;
+        typedef typename ITL::rest                             rest_list_type;
+
+        typedef tuple_base<rest_list_type, Q, TEST, index + 1> rest_type;
+
+        // use policy class Q to annotate the types of the type list ITL
+        // for use as members of the tuple:
+        // -- the actually stored type
+        typedef typename ITL::first                            ref_finder_type;
+        typedef typename Q::template use<ref_finder_type,
+                                         index>::type          first_type;
+        first_type first;
+        rest_type  rest;
+
+        template <class T>
+        struct has_element
+        {
+            static const bool value = contains<T, ITL>::value;
+        };
+
+        template <unsigned pos>
+        typename at_finder<pos, tuple_base>::type & at()
+        {
+            return at_finder<pos, tuple_base>::at(*this);
+        }
+
+        template <class T>
+        struct ref_returns
+        {
+            typedef ref_finder<T, tuple_base>     finder;
+            typedef typename finder::type         ref_finder_type;
+            typedef       ref_finder_type &       type;
+            typedef const ref_finder_type & const_type;
+        };
+        template <class T>
+        typename ref_returns<T>::type
+        ref()
+        {
+            return ref_returns<T>::finder::ref(*this);
+        }
+        template <class T>
+        typename ref_returns<T>::const_type
+        ref() const
+        {
+            return ref_returns<T>::finder::ref(*this);
+        }
+
+        template <class V>
+        bool is_set() const
+        {
+            return Q::template is_set(this->template ref<V>(), *this);
+        }
+        template <class RV>
+        void set_if_not(RV & rv)
+        {
+            if (! Q::template is_set(rv, *this))
+                Q::template set(rv, *this);
+        }
+        // recursively set all the cond_val::is_set bits of the depended-on
+        // types, or, respectively, take equivalent action.
+        template <class V>
+        void set()
+        {
+            set_if_not(this->template ref<V>());
+            for_all_used<V, set_exec>(*this);
+        }
+        // transfer the set bits of *this to another tuple t2:
+        // (ITL must be a subset of ITL2.)
+        template <class ITL2, class Q2, template<class> class TEST2>
+        void transfer_set_to(tuple_base<ITL2, Q2, TEST2> & t2) const
+        {
+            if (is_set<ref_finder_type>())
+                t2.template set<ref_finder_type>();
+            rest.transfer_set_to(t2);
+        }
+
+        // policy-based application of operator()
+        template <class B, class TBASE>
+        void exec_bound_op(B & binder, const TBASE & z)
+        {
+            Q::template exec_op<list_type, true_test>::exec(*this, binder, z);
+        }
+        template <class B>
+        void exec_bound(B & binder)
+        {
+            exec_bound_op(binder, *this);
+        }
+
+        void operator()()
+        {
+            binder_0 binder;
+            exec_bound(binder);
+        }
+
+        template <class A>
+        void operator()(const A & v)
+        {
+            binder_1<const A &> binder(v);
+            exec_bound(binder);
+        }
+        template <class A>
+        void operator()(A & v)
+        {
+            binder_1<A &> binder(v);
+            exec_bound(binder);
+        }
+        template <class A>
+        void operator()(A & v) const
+        {
+            binder_1<A &> binder(v);
+            exec_bound(binder);
+        }
+
+        template <class A, class B>
+        void operator()(const A & v, const B & w)
+        {
+            binder_2<const A &, const B &> binder(v, w);
+            exec_bound(binder);
+        }
+        template <class A, class B>
+        void operator()(A & v, const B & w)
+        {
+            binder_2<A &, const B &> binder(v, w);
+            exec_bound(binder);
+        }
+        template <class A, class B>
+        void operator()(A & v, const B & w) const
+        {
+            binder_2<A &, const B &> binder(v, w);
+            exec_bound(binder);
+        }
+
+        template <class A, class B, class C>
+        void operator()(const A & v, const B & w, const C & x)
+        {
+            binder_3<const A &, const B &, const C &> binder(v, w, x);
+            exec_bound(binder);
+        }
+        template <class A, class B, class C>
+        void operator()(A & v, const B & w, const C & x)
+        {
+            binder_3<A &, const B &, const C &> binder(v, w, x);
+            exec_bound(binder);
+        }
+        template <class A, class B, class C>
+        void operator()(A & v, const B & w, const C & x) const
+        {
+            binder_3<A &, const B &, const C &> binder(v, w, x);
+            exec_bound(binder);
+        }
+
+        // policy-based application of call()
+        template <class B, class TBASE>
+        void call_bound_op(B & binder, const TBASE & z)
+        {
+            Q::template exec_op<list_type, TEST>::call(*this, binder, z);
+        }
+        template <class B>
+        void call_bound(B & binder)
+        {
+            call_bound_op(binder, *this);
+        }
+
+        template <class A, class B>
+        void call(const A & v, const B & w)
+        {
+            binder_2<const A &, const B &> binder(v, w);
+            call_bound(binder);
+        }
+        template <class A, class B>
+        void call(A & v, const B & w)
+        {
+            binder_2<A &, const B &> binder(v, w);
+            call_bound(binder);
+        }
+        template <class A, class B>
+        void call(A & v, const B & w) const
+        {
+            binder_2<A &, const B &> binder(v, w);
+            call_bound(binder);
+        }
+
+        template <class A, class B, class C>
+        void call(const A & v, const B & w, const C & x)
+        {
+            binder_3<const A &, const B &, const C &> binder(v, w, x);
+            call_bound(binder);
+        }
+        template <class A, class B, class C>
+        void call(A & v, const B & w, const C & x)
+        {
+            binder_3<A &, const B &, const C &> binder(v, w, x);
+            call_bound(binder);
+        }
+        template <class A, class B, class C>
+        void call(A & v, const B & w, const C & x) const
+        {
+            binder_3<A &, const B &, const C &> binder(v, w, x);
+            call_bound(binder);
+        }
+
+        // the possible reassign() of global data requires handmade copies here
+        tuple_base() {}
+        tuple_base(const tuple_base & x)
+            : global_data_base_type(x), first(x.first), rest(x.rest)
+        {
+            this->reassign();
+        }
+        tuple_base & operator=(const tuple_base & x)
+        {
+            global_data_base_type::operator=(x);
+            first = x.first;
+            rest  = x.rest;
+            this->reassign();
+            return *this;
+        }
+    };
+    template <class Q, template <class> class TEST, unsigned index>
+    struct tuple_base<nil, Q, TEST, index>
+    {
+        template <class>
+        struct has_element
+        {
+            static const bool value = false;
+        };
+        template <class B, class TBASE>
+        void exec_bound_op(B &, const TBASE &) {}
+        template <class B, class TBASE>
+        void call_bound_op(B &, const TBASE &) {}
+        template <class ITL2, class Q2, template<class> class TEST2>
+        void transfer_set_to(tuple_base<ITL2, Q2, TEST2> &) const {}
+    };
+
+    template <class V, class L, class A, class B>
+    struct choose_tuple
+    {
+        static const bool value = contains<V, L>::value;
+        typedef typename IfBool<value, A, B>::type type;
+        static type & at(A & a, B & b)
+        {
+            return choose_type<value>::at(a, b);
+        }
+        static const type & at(const A & a, const B & b)
+        {
+            return choose_type<value>::at(a, b);
+        }
+
+        typedef typename type::template ref_returns<V>::      type
+            ref_type;
+        typedef typename type::template ref_returns<V>::const_type
+            const_ref_type;
+
+        ref_type
+        static ref(A & a, B & b)
+        {
+            return at(a, b).template ref<V>();
+        }
+        const_ref_type
+        static ref(const A & a, const B & b)
+        {
+            return at(a, b).template ref<V>();
+        }
+    };
+
+    template <class ITL, template<class> class TEST = true_test>
+    struct tuple : public tuple_base<ITL, plain_chooser, TEST> {};
+
+    template <class ITL, template<class> class TEST = true_test>
+    struct cond_tuple_plain
+        : public tuple_base<ITL, cond_chooser_plain, TEST> {};
+
+    template <class ITL, template<class> class TEST = true_test>
+    struct cond_tuple : public tuple_base<ITL, cond_chooser, TEST> {};
+
+    template <class ITL, template<class> class TEST = true_test>
+    struct bit_cond_tuple : public tuple_base<ITL, bit_cond_chooser, TEST> {};
+
+    template <class ITL, class ACX, class T, class Z,
+              template<class> class TEST = true_test>
+    struct virtual_tuple_base
+        : public tuple_base<ITL, virtual_chooser<ACX, T, Z>, TEST> {};
+
+    template <template <class, class> class ACXTT, class T,
+              class Z = simple_member_dispatch>
+    struct virtual_tuple
+    {
+        template <class ITL, template<class> class TEST = true_test>
+        struct type
+            : public virtual_tuple_base<ITL, ACXTT<T, ITL>, T, Z, TEST> {};
+    };
+
+    template <class ITL, class ACX, class T, class Z,
+              template<class> class TEST = true_test>
+    struct cond_virtual_tuple_base
+        : public tuple_base<ITL, cond_virtual_chooser<ACX, T, Z>, TEST>
+    {
+        typedef ACX derived_type;
+    };
+
+    template <template <class, class> class ACXTT, class T,
+              class Z = simple_member_dispatch>
+    struct cond_virtual_tuple
+    {
+        template <class ITL, template<class> class TEST = true_test>
+        struct type
+            : public cond_virtual_tuple_base<ITL, ACXTT<T, ITL>, T, Z, TEST> {};
+    };
+
+} // namespace type_lists
+
+// mask cl.exe shortcomings [end]
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+} // namespace vigra
+
+#endif // VIGRA_TYPE_LISTS_HXX
diff --git a/include/vigra/union_find.hxx b/include/vigra/union_find.hxx
new file mode 100644
index 0000000..7721f58
--- /dev/null
+++ b/include/vigra/union_find.hxx
@@ -0,0 +1,152 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2008-2009 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_UNION_FIND_HXX
+#define VIGRA_UNION_FIND_HXX
+
+#include "config.hxx"
+#include "error.hxx"
+#include "array_vector.hxx"
+
+namespace vigra {
+
+namespace detail {
+
+template <class T>
+class UnionFindArray
+{
+    typedef typename ArrayVector<T>::difference_type IndexType;
+    mutable ArrayVector<T> labels_;
+    
+  public:
+    UnionFindArray(T next_free_label = 1)
+    {
+        for(T k=0; k <= next_free_label; ++k)
+            labels_.push_back(k);
+    }
+    
+    T nextFreeLabel() const
+    {
+        return labels_.back();
+    }
+    
+    T find(T label) const
+    {
+        T root = label;
+        while(root != labels_[(IndexType)root])
+            root = labels_[(IndexType)root];
+        // path compression
+        while(label != root)
+        {
+            T next = labels_[(IndexType)label];
+            labels_[(IndexType)label] = root;
+            label = next;
+        }
+        return root;
+    } 
+    
+    T makeUnion(T l1, T l2)
+    {
+        l1 = find(l1);
+        l2 = find(l2);
+        if(l1 <= l2)
+        {
+            labels_[(IndexType)l2] = l1;
+            return l1;
+        }
+        else
+        {
+            labels_[(IndexType)l1] = l2;
+            return l2;
+        }
+    }
+    
+    T finalizeLabel(T label)
+    {
+        if(label == (T)labels_.size()-1)
+        {
+            // indeed a new region
+            vigra_invariant(label < NumericTraits<T>::max(),
+                    "connected components: Need more labels than can be represented in the destination type.");
+            // create new back entry
+            labels_.push_back((T)labels_.size());
+        }
+        else
+        {
+            // no new label => reset the back entry of the label array
+            labels_.back() = (T)labels_.size()-1;
+        }
+        return label;
+    }
+    
+    T makeNewLabel() 
+    {
+        T label = labels_.back();
+        vigra_invariant(label < NumericTraits<T>::max(),
+          "connected components: Need more labels than can be represented in the destination type.");
+        labels_.push_back((T)labels_.size());
+        return label;
+    }
+    
+    unsigned int makeContiguous()
+    {
+        // compress trees
+        unsigned int count = 0; 
+        for(IndexType i=0; i<(IndexType)(labels_.size()-1); ++i)
+        {
+            if(labels_[i] == i)
+            {
+                    labels_[i] = (T)count++;
+            }
+            else
+            {
+                    labels_[i] = labels_[(IndexType)labels_[i]]; 
+            }
+        }
+        return count-1;   
+    }
+    
+    T operator[](T label) const
+    {
+        return labels_[(IndexType)label];
+    }
+};
+
+} // namespace detail
+
+} // namespace vigra
+
+#endif // VIGRA_UNION_FIND_HXX
diff --git a/include/vigra/unittest.hxx b/include/vigra/unittest.hxx
new file mode 100755
index 0000000..b9fecf5
--- /dev/null
+++ b/include/vigra/unittest.hxx
@@ -0,0 +1,1170 @@
+/************************************************************************/
+/*                                                                      */
+/* a simple unit test framework, similar to Kent Beck's JUnit           */
+/*                                                                      */
+/*               Copyright 2002-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_UNIT_TEST_HPP
+#define VIGRA_UNIT_TEST_HPP
+
+#include <vector>
+#include <string>
+#include <new>                // for bad_alloc
+#include <typeinfo>           // for bad_cast, bad_typeid
+#include <exception>          // for exception, bad_exception
+#include <stdexcept>
+#include <iostream>
+#include <limits>
+#include <cfloat>
+#include <cmath>
+#include "vigra/config.hxx"
+#include "vigra/error.hxx"
+
+#ifdef VIGRA_NO_WORKING_STRINGSTREAM 
+#include <strstream>
+#define VIGRA_SSTREAM std::strstream
+#define VIGRA_SSTREAM_STR(s) ((s << char()), std::string(s.str()))
+#else
+#include <sstream>
+#define VIGRA_SSTREAM std::basic_stringstream<char>
+#define VIGRA_SSTREAM_STR(s) s.str()
+#endif
+
+
+#ifdef _MSC_VER
+
+#include <wtypes.h>
+#include <winbase.h>
+#include <excpt.h>
+
+#ifdef min
+#undef min
+#endif
+#ifdef max
+#undef max
+#endif
+#ifdef DIFFERENCE
+#undef DIFFERENCE
+#endif
+#ifdef RGB
+#undef RGB
+#endif
+
+#elif defined(__CYGWIN__)
+
+#define VIGRA_CANT_CATCH_SIGNALS
+
+#elif defined(__unix) || defined(unix)
+
+#include <unistd.h>
+#include <signal.h>
+#include <sys/signal.h>
+#include <setjmp.h>
+
+#else
+
+#define VIGRA_CANT_CATCH_SIGNALS
+
+#endif
+
+#define VIGRA_TEST_CASE(function)  vigra::create_test_case(function, #function "()")
+
+#define testCase VIGRA_TEST_CASE
+
+#define VIGRA_TEST_SUITE(testsuite)  ( new testsuite )
+
+#define VIGRA_CHECKPOINT(message) \
+    vigra::detail::checkpoint_impl(message, __FILE__, __LINE__)
+
+#define VIGRA_ASSERT(predicate) \
+    vigra::detail::should_impl((predicate), #predicate, __FILE__, __LINE__)
+
+#define should VIGRA_ASSERT
+
+#define VIGRA_ASSERT_MESSAGE(predicate, message) \
+    vigra::detail::should_impl((predicate), message, __FILE__, __LINE__)
+
+#define shouldMsg VIGRA_ASSERT_MESSAGE
+
+#define shouldEqual(left, right) \
+    vigra::detail::equal_impl(left, right, #left " == " #right, __FILE__, __LINE__)
+
+#define shouldEqualMessage(left, right, message) \
+    vigra::detail::equal_impl(left, right, message "\n" #left " == " #right, __FILE__, __LINE__)
+
+#define shouldEqualTolerance(left, right, eps) \
+    vigra::detail::tolerance_equal_impl(left, right, eps, #left " == " #right, __FILE__, __LINE__)
+
+#define shouldEqualToleranceMessage(left, right, eps, message) \
+    vigra::detail::tolerance_equal_impl(left, right, eps, message "\n" #left " == " #right, __FILE__, __LINE__)
+
+#define shouldEqualSequence(begin1, end1, begin2) \
+    vigra::detail::sequence_equal_impl(begin1, end1, begin2, __FILE__, __LINE__)
+
+#define shouldEqualSequenceTolerance(begin1, end1, begin2, eps) \
+    vigra::detail::sequence_equal_tolerance_impl(begin1, end1, begin2, eps, __FILE__, __LINE__)
+
+#define VIGRA_ERROR(message) \
+    vigra::detail::should_impl(false, message, __FILE__, __LINE__)
+
+#define failTest VIGRA_ERROR
+
+namespace vigra {
+
+class test_suite;
+
+namespace detail {
+
+struct errstream
+{
+    VIGRA_SSTREAM buf;
+    std::string str() { return VIGRA_SSTREAM_STR(buf); }
+    template <class T>
+    errstream & operator<<(T t) { buf << t;  return *this; }
+};
+
+inline std::string & exception_checkpoint()
+{
+    static std::string test_checkpoint_;
+    return test_checkpoint_;
+}
+
+//  A separate reporting function was requested during formal review.
+inline void report_exception( detail::errstream & os,
+                       const char * name, const char * info )
+{
+    os << "Unexpected " << name << " " << info << "\n";
+    if(exception_checkpoint().size() > 0)
+    {
+        os << "Last checkpoint: " << exception_checkpoint() << "\n";
+    }
+}
+
+enum {
+    unexpected_exception = -1,
+    os_exception = -2,
+    memory_access_violation = -3,
+    destructor_failure = -4
+};
+
+inline bool critical_error(int i)
+{ return i <= memory_access_violation; }
+
+inline bool unexpected_error(int i)
+{ return i < 0; }
+
+#ifndef VIGRA_CANT_CATCH_SIGNALS
+
+#ifdef _MSC_VER
+
+inline long handle_signal_here(long code)
+{
+    switch (code)
+    {
+        case EXCEPTION_ACCESS_VIOLATION:
+        case EXCEPTION_INT_DIVIDE_BY_ZERO:
+            return EXCEPTION_EXECUTE_HANDLER;
+        default:
+            return EXCEPTION_CONTINUE_SEARCH;
+    }
+}
+
+template< class Generator >  // Generator is function object returning int
+int catch_signals( Generator function_object, detail::errstream & err, int timeout )
+{
+    int result = 0;
+    int code;
+    __try
+    {
+        result = function_object();
+    }
+    __except (handle_signal_here(code = GetExceptionCode()))
+    {
+        switch (code)
+        {
+            case EXCEPTION_ACCESS_VIOLATION:
+                report_exception(err, "operating system exception:", "memory access violation");
+                result = memory_access_violation;
+                break;
+            case EXCEPTION_INT_DIVIDE_BY_ZERO:
+                report_exception(err, "operating system exception:", "integer divide by zero");
+                result = os_exception;
+                break;
+            default:
+                report_exception(err, "operating system exception:", "unrecognized exception or signal");
+                result = os_exception;
+        }
+    }
+    return result;
+
+}
+
+
+#elif defined(__unix)
+
+extern "C" {
+
+inline jmp_buf & unit_test_jump_buffer()
+{
+    static jmp_buf unit_test_jump_buffer_;
+    return unit_test_jump_buffer_;
+}
+
+static void unit_test_signal_handler(int sig)
+{
+    longjmp(unit_test_jump_buffer(), sig);
+}
+
+} // extern "C"
+
+template< class Generator >  // Generator is function object returning int
+int catch_signals( Generator function_object, detail::errstream & err, int timeout)
+{
+    volatile int sigtype;
+    int result;
+
+#if defined(linux) || defined(__linux)
+    signal(SIGFPE, &unit_test_signal_handler);
+    signal(SIGTRAP, &unit_test_signal_handler);
+    signal(SIGSEGV, &unit_test_signal_handler);
+    signal(SIGBUS, &unit_test_signal_handler);
+#else
+    sigset(SIGFPE, &unit_test_signal_handler);
+    sigset(SIGTRAP, &unit_test_signal_handler);
+    sigset(SIGSEGV, &unit_test_signal_handler);
+    sigset(SIGBUS, &unit_test_signal_handler);
+#endif
+
+    if(timeout)
+    {
+#if defined(linux) || defined(__linux)
+        signal(SIGALRM, &unit_test_signal_handler);
+#else
+        sigset(SIGALRM, &unit_test_signal_handler);
+#endif
+        alarm(timeout);
+    }
+
+    sigtype = setjmp(unit_test_jump_buffer());
+    if(sigtype == 0)
+    {
+       result = function_object();
+    }
+    else
+    {
+        switch(sigtype)
+        {
+            case SIGALRM:
+                report_exception(err, "signal:", "SIGALRM (timeout while executing function)");
+                result = os_exception;
+                break;
+            case SIGTRAP:
+                report_exception(err, "signal:", "SIGTRAP (perhaps integer divide by zero)");
+                result = os_exception;
+                break;
+            case SIGFPE:
+                report_exception(err, "signal:", "SIGFPE (arithmetic exception)");
+                result = os_exception;
+                break;
+            case SIGSEGV:
+            case SIGBUS:
+                report_exception(err, "signal:", "memory access violation");
+                result = memory_access_violation;
+                break;
+            default:
+                report_exception(err, "signal:", "unrecognized signal");
+                result = os_exception;
+        }
+    }
+
+    if(timeout)
+    {
+        alarm(0);
+#if defined(linux) || defined(__linux)
+#else
+        sigrelse(SIGALRM);
+#endif
+    }
+
+#if defined(linux) || defined(__linux)
+#else
+    sigrelse(SIGFPE);
+    sigrelse(SIGTRAP);
+    sigrelse(SIGSEGV);
+    sigrelse(SIGBUS);
+#endif
+
+    return result;
+}
+
+#endif  /* _MSC_VER || __unix */
+
+#else  /* VIGRA_CANT_CATCH_SIGNALS */
+
+template< class Generator >  // Generator is function object returning int
+int catch_signals( Generator function_object, detail::errstream & err , int)
+{
+     return function_object();
+}
+
+#endif /* VIGRA_CANT_CATCH_SIGNALS */
+
+} // namespace detail
+
+template< class Generator >  // Generator is function object returning int
+int catch_exceptions( Generator function_object, detail::errstream & err, int timeout )
+{
+    int result = detail::unexpected_exception;
+
+    try
+    {
+        result = detail::catch_signals(function_object, err, timeout);
+    }
+
+    //  As a result of hard experience with strangely interleaved output
+    //  under some compilers, there is a lot of use of endl in the code below
+    //  where a simple '\n' might appear to do.
+
+    //  The rules for catch & arguments are a bit different from function
+    //  arguments (ISO 15.3 paragraphs 18 & 19). Apparently const isn't
+    //  required, but it doesn't hurt and some programmers ask for it.
+
+    catch ( vigra::ContractViolation & ex )
+      { detail::report_exception( err, "Contract exception: ", ex.what() ); }
+    catch ( const char * ex )
+      { detail::report_exception( err, "string exception: ", ex ); }
+    catch ( const std::string & ex )
+      { detail::report_exception( err, "string exception: ", ex.c_str() ); }
+
+    //  std:: exceptions
+    catch ( const std::bad_alloc & ex )
+      { detail::report_exception( err, "exception: std::bad_alloc:", ex.what() ); }
+
+# if !defined(__BORLANDC__) || __BORLANDC__ > 0x0551
+    catch ( const std::bad_cast & ex )
+      { detail::report_exception( err, "exception: std::bad_cast:", ex.what() ); }
+    catch ( const std::bad_typeid & ex )
+      { detail::report_exception( err, "exception: std::bad_typeid:", ex.what() ); }
+# else
+    catch ( const std::bad_cast & ex )
+      { detail::report_exception( err, "exception: std::bad_cast", "" ); }
+    catch ( const std::bad_typeid & ex )
+      { detail::report_exception( err, "exception: std::bad_typeid", "" ); }
+# endif
+
+    catch ( const std::bad_exception & ex )
+      { detail::report_exception( err, "exception: std::bad_exception:", ex.what() ); }
+    catch ( const std::domain_error & ex )
+      { detail::report_exception( err, "exception: std::domain_error:", ex.what() ); }
+    catch ( const std::invalid_argument & ex )
+      { detail::report_exception( err, "exception: std::invalid_argument:", ex.what() ); }
+    catch ( const std::length_error & ex )
+      { detail::report_exception( err, "exception: std::length_error:", ex.what() ); }
+    catch ( const std::out_of_range & ex )
+      { detail::report_exception( err, "exception: std::out_of_range:", ex.what() ); }
+    catch ( const std::range_error & ex )
+      { detail::report_exception( err, "exception: std::range_error:", ex.what() ); }
+    catch ( const std::overflow_error & ex )
+      { detail::report_exception( err, "exception: std::overflow_error:", ex.what() ); }
+    catch ( const std::underflow_error & ex )
+      { detail::report_exception( err, "exception: std::underflow_error:", ex.what() ); }
+    catch ( const std::logic_error & ex )
+      { detail::report_exception( err, "exception: std::logic_error:", ex.what() ); }
+    catch ( const std::runtime_error & ex )
+      { detail::report_exception( err, "exception: std::runtime_error:", ex.what() ); }
+   catch ( const std::exception & ex )
+      { detail::report_exception( err, "exception: std::exception:", ex.what() ); }
+
+    catch ( ... )
+      { 
+        detail::report_exception( err, "unknown exception", "" );
+        throw;
+      }
+
+    return result;
+} // catch_exceptions
+
+template< class Generator >  // Generator is function object returning int
+inline
+int catch_exceptions( Generator function_object, detail::errstream & err)
+{
+    return catch_exceptions(function_object, err, 0);
+}
+
+namespace detail {
+
+struct unit_test_failed
+: public std::exception
+{
+    unit_test_failed(std::string const & message)
+    : what_(message)
+    {}
+
+    virtual ~unit_test_failed() throw()
+    {
+    }
+
+    virtual const char * what() const throw()
+    {
+        return what_.c_str();
+    }
+
+    std::string what_;
+};
+
+inline void
+checkpoint_impl(const char * message, const char * file, int line)
+{
+    detail::errstream buf;
+    buf << message << " (" << file <<":" << line << ")";
+    exception_checkpoint() = buf.str();
+}
+
+inline void
+should_impl(bool predicate, const char * message, const char * file, int line)
+{
+    checkpoint_impl(message, file, line);
+    if(!predicate)
+    {
+        detail::errstream buf;
+        buf << message << " (" << file <<":" << line << ")";
+        throw unit_test_failed(buf.str()); 
+    } 
+}
+
+template <class Iter1, class Iter2>
+void 
+sequence_equal_impl(Iter1 i1, Iter1 end1, Iter2 i2, const char * file, int line)
+{
+    for(int counter = 0; i1 != end1; ++i1, ++i2, ++counter)
+    {
+        if(*i1 != *i2)
+        {
+            detail::errstream buf;
+            buf << "Sequence items differ at index " << counter <<
+                   " ["<< *i1 << " != " << *i2 << "]";
+            should_impl(false, buf.str().c_str(), file, line); 
+        }
+    }
+}
+
+/******************Floating point comparison********************************/
+/**
+* See Knuth "The art of computer programming" (Vol II, Ch.4.2)
+*/
+struct ScalarType {};
+struct VectorType {};
+
+template<class T>
+struct FloatTraits
+{
+    typedef VectorType ScalarOrVector;
+};
+
+template<>
+struct FloatTraits<float>
+{
+    typedef ScalarType ScalarOrVector;
+    static float epsilon() { return FLT_EPSILON; }
+    static float smallestPositive() { return FLT_MIN; }
+    static float min() { return -FLT_MAX; }
+    static float max() { return FLT_MAX; }
+};
+
+template<>
+struct FloatTraits<double>
+{
+    typedef ScalarType ScalarOrVector;
+    static double epsilon() { return DBL_EPSILON; }
+    static double smallestPositive() { return DBL_MIN; }
+    static double min() { return -DBL_MAX; }
+    static double max() { return DBL_MAX; }
+};
+
+template<>
+struct FloatTraits<long double>
+{
+    typedef ScalarType ScalarOrVector;
+    static long double epsilon() { return LDBL_EPSILON; }
+    static long double smallestPositive() { return LDBL_MIN; }
+    static long double min() { return -LDBL_MAX; }
+    static long double max() { return LDBL_MAX; }
+};
+
+template<class FPT>
+inline
+FPT fpt_abs( FPT arg )
+{
+    return arg < 0 ? -arg : arg;
+}
+
+
+/***********************************************************************/
+
+// both f1 and f2 are unsigned here
+template<class FPT>
+inline
+FPT safe_fpt_division( FPT f1, FPT f2 )
+{
+        /*  ist f1 das absolute minimum (in diesem Fall einfach nur sehr kleine Zahl)
+        *   aber nicht null (1.65242e-28) und f2 = 0,
+        *   dann tritt die erste Bedingung in Kraft 0<1 && 1.65242e-28 > 0*1.79769e+308 (max)
+        *   deshalb schlaegt es fehl sogar wenn min closed at tolarance zu 0 ist ???
+        *   Der Vergleich aller Zahlen closed at tolarance zu 0 wuerden fehlschlagen;
+        *   Sie umzudrehen bringt nichts, denn diese Funktion wird symetrisch fuer beide
+        *   angewendet wird.
+        *   0 mit 0 zu Vergleichen bereitet keine Probleme.
+        *   Ausweg: evl. eine extra Behandlung der F = 0 ???
+        */
+    return  ((f2 < 1) && (f1 > (f2 *    FloatTraits<FPT>::max()))) ? 
+            FloatTraits<FPT>::max() :
+            ((((f2 > 1) && (f1 < (f2 * FloatTraits<FPT>::smallestPositive())))
+              || (f1 == 0)) ? 0 : f1/f2 );
+        /*  Die Multiplikation mit max in 1.ten Bedingung und mit min in der 2.ten ist eine Absicherung gegen
+        *   die Owerflow bzw Underflow ???
+        */
+}
+
+/***********************************************************************/
+
+template<class FPT>
+class close_at_tolerance {
+public:
+    explicit    close_at_tolerance( FPT tolerance, bool strong_test = true )
+        : m_strong_test( strong_test ),
+          m_tolerance( tolerance ) {}
+
+    explicit    close_at_tolerance( int number_of_rounding_errors, bool strong_test = true )
+        : m_strong_test( strong_test ),
+          m_tolerance( FloatTraits<FPT>::epsilon() * number_of_rounding_errors / 2.0 ) {}
+
+    bool        operator()( FPT left, FPT right ) const
+    {
+        if (left == 0 && right != 0)
+        {
+                return (fpt_abs(right) <= m_tolerance);
+        }
+        if (right == 0 && left != 0)
+        {
+                return (fpt_abs(left) <= m_tolerance);
+        }
+        FPT diff = fpt_abs( left - right );
+        FPT d1   = safe_fpt_division( diff, fpt_abs( right ) );
+        FPT d2   = safe_fpt_division( diff, fpt_abs( left ) );
+
+        return m_strong_test ? (d1 <= m_tolerance && d2 <= m_tolerance)
+                                : (d1 <= m_tolerance || d2 <= m_tolerance);
+    }
+
+private:
+    bool        m_strong_test;
+    FPT         m_tolerance;
+};
+
+/*****************end of float comparison***********************************/
+
+template <class T1, class T2, class T3>
+void
+tolerance_equal_impl(T1 left, T2 right, T3 epsilon, 
+                     const char * message, const char * file, int line, ScalarType)
+{
+    detail::errstream buf;
+    buf << message << " [" << left << " != " << right << "]";
+
+    close_at_tolerance<T3> fcomparator( epsilon );
+    bool compare = fcomparator ( (T3)left , (T3)right );
+    should_impl(compare, buf.str().c_str(), file, line);
+
+}
+
+template <class T1, class T2, class T3>
+void
+tolerance_equal_impl(T1 left, T2 right, T3 epsilon, 
+                     const char * message, const char * file, int line, VectorType)
+{
+    detail::errstream buf;
+    buf << message << " [" << left << " != " << right << "]";
+
+    bool compare = true;
+    for(unsigned int i=0; i<epsilon.size(); ++i)
+    {
+        close_at_tolerance<typename T3::value_type> fcomparator( epsilon[i] );
+        compare = compare && fcomparator ( left[i] , right[i] );
+    }
+    should_impl(compare, buf.str().c_str(), file, line);
+}
+
+template <class T1, class T2, class T3>
+void
+tolerance_equal_impl(T1 left, T2 right, T3 epsilon, const char * message, const char * file, int line)
+{
+    tolerance_equal_impl(left, right, epsilon, 
+                         message, file, line, typename FloatTraits<T3>::ScalarOrVector());
+}
+
+template <class Iter1, class Iter2, class T>
+void 
+sequence_equal_tolerance_impl(Iter1 i1, Iter1 end1, Iter2 i2, T epsilon, const char * file, int line)
+{
+    for(int counter = 0; i1 != end1; ++i1, ++i2, ++counter)
+    {
+        detail::errstream buf;
+        buf << "Sequence items differ at index " << counter;
+        tolerance_equal_impl(*i1, *i2, epsilon, buf.str().c_str(), file, line, typename FloatTraits<T>::ScalarOrVector()); 
+    }
+}
+
+template <class Left, class Right>
+void
+equal_impl(Left left, Right right, const char * message, const char * file, int line)
+{
+    detail::errstream buf;
+    buf << message << " [" << left << " != " << right << "]";
+    should_impl(left == right, buf.str().c_str(), file, line);
+}
+
+template <class Left, class Right>
+void
+equal_impl(Left * left, Right * right, const char * message, const char * file, int line)
+{
+    detail::errstream buf;
+    buf << message << " [" << (void*)left << " != " << (void*)right << "]";
+    should_impl(left == right, buf.str().c_str(), file, line);
+}
+
+inline void
+equal_impl(double left, double right, const char * message, const char * file, int line)
+{
+    tolerance_equal_impl(left, right, 1.0e-16, message, file, line);
+}
+
+inline void
+equal_impl(float left, float right, const char * message, const char * file, int line)
+{
+    tolerance_equal_impl(left, right, 1.0e-6f, message, file, line);
+}
+
+inline void
+equal_impl(float left, double right, const char * message, const char * file, int line)
+{
+    tolerance_equal_impl(left, right, 1.0e-6f, message, file, line);
+}
+
+inline void
+equal_impl(double left, float right, const char * message, const char * file, int line)
+{
+    tolerance_equal_impl(left, right, 1.0e-6f, message, file, line);
+}
+
+class test_case
+{
+  public:
+
+    test_case(char const * name = "Unnamed")
+    : name_(name), timeout(0)
+    {}
+
+    virtual ~test_case() {}
+
+    virtual int run() { return run(std::vector<std::string>()); }
+    virtual int run(std::vector<std::string> const & testsToBeRun) = 0;
+    virtual void do_init() {}
+    virtual void do_run() {}
+    virtual void do_destroy() {}
+
+    virtual char const * name() { return name_.c_str(); }
+    virtual int size() const { return 1; }
+    
+    virtual int numberOfTestsToRun(std::vector<std::string> const & testsToBeRun) const
+    {
+        if(testsToBeRun.empty()) // empty list => run all tests
+            return 1;
+        for(unsigned int k=0; k<testsToBeRun.size(); ++k)
+            if(this->name_.find(testsToBeRun[k]) != std::string::npos)
+                return 1;
+        return 0;
+    }
+
+    std::string name_;
+    std::string report_;
+    int timeout;
+};
+
+
+} // namespace detail
+
+std::vector<std::string> testsToBeExecuted(int argc, char ** argv)
+{
+    std::vector<std::string> res;
+    for(int i=1; i < argc; ++i)
+        res.push_back(std::string(argv[i]));
+    return res;
+}
+
+class test_suite
+: public detail::test_case
+{
+  public:
+    using detail::test_case::run;
+    
+    test_suite(char const * name = "TopLevel")
+    : detail::test_case(name),
+      size_(0)
+    {}
+
+    virtual ~test_suite()
+    {
+        for(unsigned int i=0; i != testcases_.size(); ++i)
+            delete testcases_[i];
+    }
+
+    virtual void add(detail::test_case * t, int timeout = 0)
+    {
+        t->timeout = timeout;
+        testcases_.push_back(t);
+        size_ += t->size();
+    }
+    
+    virtual int run(std::vector<std::string> const & testsToBeRun)
+    {
+        int size = numberOfTestsToRun(testsToBeRun);
+        
+        std::vector<std::string> testsToBeRunRecursive = 
+                   size < this->size()
+                       ? testsToBeRun                 // run selectively
+                       : std::vector<std::string>();  // run all
+
+        int failed = 0;
+        report_ = std::string("Entering test suite ") + name() + "\n";
+
+        for(unsigned int i=0; i != testcases_.size(); ++i)
+        {
+            int result = testcases_[i]->run(testsToBeRunRecursive);
+            report_ += testcases_[i]->report_;
+
+            if(detail::critical_error(result))
+            {
+                report_ += std::string("\nFatal error - aborting test suite ") + name() + ".\n";
+                return result;
+            }
+            else if(detail::unexpected_error(result))
+                failed++;
+            else
+                failed += result;
+        }
+
+        if(failed)
+        {
+            detail::errstream buf;
+            buf << "\n" << failed << " of " << size <<
+                " tests failed in test suite " << name() << "\n";
+            report_ += buf.str();
+        }
+        else
+        {
+            detail::errstream buf;
+            buf << "All (" << size <<
+               ") tests passed in test suite " << name() << "\n";
+            report_ += buf.str();
+        }
+
+        report_ += std::string("Leaving test suite ") + name() + "\n";
+
+        return failed;
+    }
+    
+    virtual int numberOfTestsToRun(std::vector<std::string> const & testsToBeRun) const
+    {
+        if(detail::test_case::numberOfTestsToRun(testsToBeRun) > 0)
+            return this->size();
+        int size = 0;
+        for(unsigned int i=0; i != testcases_.size(); ++i)
+            size += testcases_[i]->numberOfTestsToRun(testsToBeRun);
+        return size;
+    }
+
+    virtual int size() const { return size_; }
+    virtual std::string report() { return report_; }
+
+    std::vector<detail::test_case *> testcases_;
+    int size_;
+};
+
+namespace detail {
+
+struct test_case_init_functor
+{
+    detail::errstream & buf_;
+    test_case * test_case_;
+
+    test_case_init_functor(detail::errstream & b, test_case * tc)
+    : buf_(b), test_case_(tc)
+    {}
+
+    int operator()()
+    {
+        try
+        {
+            test_case_->do_init();
+            return 0;
+        }
+        catch(unit_test_failed & e)
+        {
+            buf_ << "Assertion failed: " << e.what() << "\n";
+            return 1;
+        }
+    }
+};
+
+struct test_case_run_functor
+{
+    detail::errstream & buf_;
+    test_case * test_case_;
+
+    test_case_run_functor(detail::errstream & b, test_case * tc)
+    : buf_(b), test_case_(tc)
+    {}
+
+    int operator()()
+    {
+        try
+        {
+            test_case_->do_run();
+            return 0;
+        }
+        catch(unit_test_failed & e)
+        {
+            buf_ << "Assertion failed: " << e.what() << "\n";
+            return 1;
+        }
+    }
+};
+
+struct test_case_destroy_functor
+{
+    detail::errstream & buf_;
+    test_case *  test_case_;
+
+    test_case_destroy_functor(detail::errstream & b, test_case * tc)
+    : buf_(b), test_case_(tc)
+    {}
+
+    int operator()()
+    {
+        try
+        {
+            test_case_->do_destroy();
+            return 0;
+        }
+        catch(unit_test_failed & e)
+        {
+            buf_ << "Assertion failed: " << e.what() << "\n";
+            return 1;
+        }
+    }
+};
+
+template <class TESTCASE>
+class class_test_case
+: public test_case
+{
+  public:
+    using test_case::run;
+    
+    class_test_case(void (TESTCASE::*fct)(), char const * name)
+    : test_case(name),
+      fct_(fct),
+      testcase_(0)
+    {}
+
+    virtual ~class_test_case()
+    {
+        delete testcase_;
+    }
+
+    virtual void do_init()
+    {
+        testcase_ = new TESTCASE;
+    }
+
+    int init()
+    {
+        exception_checkpoint() = "";
+        report_ = "";
+        int failed = 0;
+
+        detail::errstream buf;
+        buf << "\nFailure in initialization of " << name() << "\n";
+        if(testcase_ != 0)
+        {
+            buf << "Test case failed to clean up after previous run.\n";
+            failed = 1;
+        }
+        else
+        {
+            failed = catch_exceptions(
+                detail::test_case_init_functor(buf, this), buf, timeout);
+        }
+
+        if(failed)
+        {
+            report_ += buf.str();
+        }
+
+        return failed;
+    }
+
+    virtual void do_run()
+    {
+        if(testcase_ != 0)
+            (testcase_->*fct_)();
+    }
+
+    virtual int run(std::vector<std::string> const & testsToBeRun)
+    {
+        if(numberOfTestsToRun(testsToBeRun) == 0)
+            return 0;
+
+        int failed = init();
+
+        if(failed)
+            return failed;
+
+        detail::errstream buf;
+        buf << "\nFailure in " << name() << "\n";
+
+        failed = catch_exceptions(
+            detail::test_case_run_functor(buf, this), buf, timeout);
+        if(failed)
+            report_ += buf.str();
+
+        if(critical_error(failed))
+            return failed;
+
+        int destruction_failed = destroy();
+
+        return destruction_failed ?
+                destruction_failed :
+                failed;
+    }
+
+    virtual void do_destroy()
+    {
+        delete testcase_;
+        testcase_ = 0;
+    }
+
+    int destroy()
+    {
+        detail::errstream buf;
+        buf << "\nFailure in destruction of " << "\n";
+
+        int failed = catch_exceptions(
+            detail::test_case_destroy_functor(buf, this), buf, timeout);
+        if(failed)
+        {
+            report_ += buf.str();
+            return destructor_failure;
+        }
+        else
+        {
+            return 0;
+        }
+    }
+
+    void (TESTCASE::*fct_)();
+    TESTCASE * testcase_;
+};
+
+class function_test_case
+: public test_case
+{
+  public:
+    using test_case::run;
+
+    function_test_case(void (*fct)(), char const * name)
+    : test_case(name),
+      fct_(fct)
+    {}
+
+    virtual void do_run()
+    {
+        (*fct_)();
+    }
+
+    virtual int run(std::vector<std::string> const & testsToBeRun)
+    {
+        if(numberOfTestsToRun(testsToBeRun) == 0)
+            return 0;
+
+        report_ = "";
+        exception_checkpoint() = "";
+
+        detail::errstream buf;
+        buf << "\nFailure in " << name() << "\n";
+
+        int failed = catch_exceptions(
+            detail::test_case_run_functor(buf, this), buf, timeout);
+        if(failed)
+        {
+            report_ += buf.str();
+        }
+
+        return failed;
+    }
+
+    void (*fct_)();
+};
+
+template <class FCT>
+struct test_functor
+{
+    virtual ~test_functor() {}
+    virtual void operator()() = 0;
+    
+    FCT clone() const 
+        { return FCT(static_cast<FCT const &>(*this)); }
+};
+    
+template <class FCT>
+class functor_test_case
+: public test_case
+{
+  public:
+    using test_case::run;
+    
+    functor_test_case(FCT const & fct, char const * name)
+    : test_case(name),
+      fct_(fct)
+    {}
+    
+    virtual void do_run()
+    {
+        fct_();
+    }
+    
+    virtual int run(std::vector<std::string> const & testsToBeRun)
+    {
+        if(numberOfTestsToRun(testsToBeRun) == 0)
+            return 0;
+
+        report_ = "";
+        exception_checkpoint() = "";
+        
+        detail::errstream buf;
+        buf << "\nFailure in " << name() << "\n";
+        
+        int failed = catch_exceptions(
+            detail::test_case_run_functor(buf, this), buf, timeout);
+        if(failed)
+        {
+            report_ += buf.str();
+        }
+
+        return failed;
+    }
+    
+    FCT fct_;
+};
+    
+} // namespace detail
+
+template <class TESTCASE>
+inline
+detail::test_case *
+create_test_case(void (TESTCASE::*fct)(), char const * name)
+{
+    if(*name == '&') ++name;
+    return new detail::class_test_case<TESTCASE>(fct, name);
+}
+
+inline
+detail::test_case *
+create_test_case(void (*fct)(), char const * name)
+{
+    if(*name == '&') ++name;
+    return new detail::function_test_case(fct, name);
+}
+
+template <class FCT>
+inline 
+detail::test_case * 
+create_test_case(detail::test_functor<FCT> const & fct, char const * name)
+{
+    if(*name == '&') ++name;
+    return new detail::functor_test_case<FCT>(fct.clone(), name);
+}
+
+} // namespace vigra
+
+
+#if !defined(__GNUC__) || __GNUC__ >= 3
+
+// provide more convenient output functions, used like:
+// std::cerr << 1, 2, 3, 4, "\n";
+template <class E, class T, class V>
+inline
+std::basic_ostream<E,T> & operator,(std::basic_ostream<E,T> & o, V const & t)
+{
+    return (o << ' ' << t);
+}
+
+template <class E, class T>
+inline
+std::basic_ostream<E,T> & operator,(std::basic_ostream<E,T> & o, 
+              std::basic_ostream<E,T> & (*t)(std::basic_ostream<E,T> &))
+{
+    return (o << t);
+}
+
+#else
+
+template <class V>
+inline
+std::ostream & operator,(std::ostream & o, V const & t)
+{
+    return (o << ' ' << t);
+}
+
+inline
+std::ostream & operator,(std::ostream & o, 
+              std::ostream & (*t)(std::ostream &))
+{
+    return (o << t);
+}
+
+#endif
+
+
+#endif /* VIGRA_UNIT_TEST_HPP */
diff --git a/include/vigra/unsupervised_decomposition.hxx b/include/vigra/unsupervised_decomposition.hxx
new file mode 100644
index 0000000..78a2849
--- /dev/null
+++ b/include/vigra/unsupervised_decomposition.hxx
@@ -0,0 +1,384 @@
+/************************************************************************/
+/*                                                                      */
+/*    Copyright 2008-2011 by Michael Hanselmann and Ullrich Koethe      */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_UNSUPERVISED_DECOMPOSITION_HXX
+#define VIGRA_UNSUPERVISED_DECOMPOSITION_HXX
+
+#include <numeric>
+#include "mathutil.hxx"
+#include "matrix.hxx"
+#include "singular_value_decomposition.hxx"
+#include "random.hxx"
+
+namespace vigra
+{
+
+/** \addtogroup Unsupervised_Decomposition Unsupervised Decomposition
+
+    Unsupervised matrix decomposition methods.
+**/
+//@{
+
+/*****************************************************************/
+/*                                                               */
+/*              principle component analysis (PCA)               */
+/*                                                               */
+/*****************************************************************/
+
+   /** \brief Decompose a matrix according to the PCA algorithm. 
+
+        This function implements the PCA algorithm (principle component analysis).
+
+        \arg features must be a matrix with shape <tt>(numFeatures * numSamples)</tt>, which is
+        decomposed into the matrices 
+        \arg fz with shape <tt>(numFeatures * numComponents)</tt> and
+        \arg zv with shape <tt>(numComponents * numSamples)</tt>
+        
+        such that
+        \f[
+            \mathrm{features} \approx \mathrm{fz} * \mathrm{zv}
+        \f]
+        (this formula requires that the features have been centered around the mean by
+        <tt>\ref linalg::prepareRows (features, features, ZeroMean)</tt>).
+       
+        The shape parameter <tt>numComponents</tt> determines the complexity of 
+        the decomposition model and therefore the approximation quality (if
+        <tt>numComponents == numFeatures</tt>, the representation becomes exact). 
+        Intuitively, <tt>fz</tt> is a projection matrix from the reduced space
+        into the original space, and <tt>zv</tt> is  the reduced representation
+        of the data, using just <tt>numComponents</tt> features.
+
+        <b>Declaration:</b>
+        
+        <b>\#include</b> \<vigra/unsupervised_decomposition.hxx\>
+
+        \code
+        namespace vigra {
+        
+            template <class U, class C1, class C2, class C3>
+            void
+            principleComponents(MultiArrayView<2, U, C1> const & features,
+                                MultiArrayView<2, U, C2> fz, 
+                                MultiArrayView<2, U, C3> zv);
+        }
+        \endcode
+        
+        <b>Usage:</b>
+        \code
+        Matrix<double> data(numFeatures, numSamples);
+        ... // fill the input matrix
+        
+        int numComponents = 3;
+        Matrix<double> fz(numFeatures, numComponents),
+                       zv(numComponents, numSamples);
+                       
+        // center the data
+        prepareRows(data, data, ZeroMean);
+        
+        // compute the reduced representation
+        principleComponents(data, fz, zv);
+        
+        Matrix<double> model = fz*zv;
+        double meanSquaredError = squaredNorm(data - model) / numSamples;
+        \endcode
+   */
+template <class T, class C1, class C2, class C3>
+void
+principleComponents(MultiArrayView<2, T, C1> const & features,
+                    MultiArrayView<2, T, C2> fz, 
+                    MultiArrayView<2, T, C3> zv)
+{
+    using namespace linalg; // activate matrix multiplication and arithmetic functions
+
+    int numFeatures = rowCount(features);
+    int numSamples = columnCount(features);
+    int numComponents = columnCount(fz);
+    vigra_precondition(numSamples >= numFeatures,
+      "principleComponents(): The number of samples has to be larger than the number of features.");
+    vigra_precondition(numFeatures >= numComponents && numComponents >= 1,
+      "principleComponents(): The number of features has to be larger or equal to the number of components in which the feature matrix is decomposed.");
+    vigra_precondition(rowCount(fz) == numFeatures,
+      "principleComponents(): The output matrix fz has to be of dimension numFeatures*numComponents.");
+    vigra_precondition(columnCount(zv) == numSamples && rowCount(zv) == numComponents,
+      "principleComponents(): The output matrix zv has to be of dimension numComponents*numSamples.");
+
+    Matrix<T> U(numSamples, numFeatures), S(numFeatures, 1), V(numFeatures, numFeatures);
+    singularValueDecomposition(features.transpose(), U, S, V);
+    
+    for(int k=0; k<numComponents; ++k)
+    {
+        rowVector(zv, k) = columnVector(U, k).transpose() * S(k, 0);
+        columnVector(fz, k) = columnVector(V, k);
+    }
+}
+
+/*****************************************************************/
+/*                                                               */
+/*         probabilistic latent semantic analysis (pLSA)         */
+/*         see T Hofmann, Probabilistic Latent Semantic          */
+/*         Indexing for details                                  */
+/*                                                               */
+/*****************************************************************/
+
+   /** \brief Option object for the \ref pLSA algorithm. 
+   */
+class PLSAOptions
+{
+  public:
+        /** Initialize all options with default values.
+        */
+    PLSAOptions()
+    : min_rel_gain(1e-4),
+      max_iterations(50),
+      normalized_component_weights(true)
+    {}
+
+        /** Maximum number of iterations which is performed by the pLSA algorithm.
+
+            default: 50
+        */
+    PLSAOptions & maximumNumberOfIterations(unsigned int n)
+    {
+        vigra_precondition(n >= 1,
+            "PLSAOptions::maximumNumberOfIterations(): number must be a positive integer.");
+        max_iterations = n;
+        return *this;
+    }
+
+        /** Minimum relative gain which is required for the algorithm to continue the iterations.
+
+            default: 1e-4
+        */
+    PLSAOptions & minimumRelativeGain(double g)
+    {
+        vigra_precondition(g >= 0.0,
+            "PLSAOptions::minimumRelativeGain(): number must be positive or zero.");
+        min_rel_gain = g;
+        return *this;
+    }
+    
+        /** Normalize the entries of the zv result array.
+        
+            If true, the columns of zv sum to one. Otherwise, they have the same
+            column sum as the original feature matrix.
+            
+            default: true
+        */
+    PLSAOptions & normalizedComponentWeights(bool v = true)
+    {
+        normalized_component_weights = v;
+        return *this;
+    }
+
+    double min_rel_gain;
+    int max_iterations;
+    bool normalized_component_weights;
+};
+
+   /** \brief Decompose a matrix according to the pLSA algorithm. 
+
+        This function implements the pLSA algorithm (probabilistic latent semantic analysis) 
+        proposed in
+
+        T. Hofmann: <a href="http://www.cs.brown.edu/people/th/papers/Hofmann-UAI99.pdf">
+        <i>"Probabilistic Latent Semantic Analysis"</i></a>,
+        in: UAI'99, Proc. 15th Conf. on Uncertainty in Artificial Intelligence,
+        pp. 289-296, Morgan Kaufmann, 1999
+
+        \arg features must be a matrix with shape <tt>(numFeatures * numSamples)</tt> and 
+        non-negative entries, which is decomposed into the matrices 
+        \arg fz with shape <tt>(numFeatures * numComponents)</tt> and
+        \arg zv with shape <tt>(numComponents * numSamples)</tt>
+        
+        such that
+        \f[
+            \mathrm{features} \approx \mathrm{fz} * \mathrm{zv}
+        \f]
+        (this formula applies when pLSA is called with 
+        <tt>PLSAOptions.normalizedComponentWeights(false)</tt>. Otherwise, you must
+        normalize the features by calling <tt>\ref linalg::prepareColumns (features, features, UnitSum)</tt>
+        to make the formula hold).
+       
+        The shape parameter <tt>numComponents</tt> determines the complexity of 
+        the decomposition model and therefore the approximation quality. 
+        Intuitively, features are a set of words, and the samples a set of 
+        documents. The entries of the <tt>features</tt> matrix denote the relative 
+        frequency of the words in each document. The components represents a 
+        (presumably small) set of topics. The matrix <tt>fz</tt> encodes the 
+        relative frequency of words in the different topics, and the matrix  
+        <tt>zv</tt> encodes to what extend each topic explains the content of each 
+        document.
+
+        The option object determines the iteration termination conditions and the output
+        normalization. In addition, you may pass a random number generator to pLSA()
+        which is used to create the initial solution.
+
+        <b>Declarations:</b>
+        
+        <b>\#include</b> \<vigra/unsupervised_decomposition.hxx\>
+
+        \code
+        namespace vigra {
+        
+            template <class U, class C1, class C2, class C3, class Random>
+            void
+            pLSA(MultiArrayView<2, U, C1> const & features,
+                 MultiArrayView<2, U, C2> & fz, 
+                 MultiArrayView<2, U, C3> & zv,
+                 Random const& random,
+                 PLSAOptions const & options = PLSAOptions());
+                 
+            template <class U, class C1, class C2, class C3>
+            void
+            pLSA(MultiArrayView<2, U, C1> const & features, 
+                 MultiArrayView<2, U, C2> & fz, 
+                 MultiArrayView<2, U, C3> & zv,
+                 PLSAOptions const & options = PLSAOptions());
+        }
+        \endcode
+        
+        <b>Usage:</b>
+        \code
+        Matrix<double> words(numWords, numDocuments);
+        ... // fill the input matrix
+        
+        int numTopics = 3;
+        Matrix<double> fz(numWords, numTopics),
+                       zv(numTopics, numDocuments);
+                       
+        pLSA(words, fz, zv, PLSAOptions().normalizedComponentWeights(false));
+        
+        Matrix<double> model = fz*zv;
+        double meanSquaredError = (words - model).squaredNorm() / numDocuments;
+        \endcode
+   */
+doxygen_overloaded_function(template <...> void pLSA)
+
+
+template <class U, class C1, class C2, class C3, class Random>
+void
+pLSA(MultiArrayView<2, U, C1> const & features,
+     MultiArrayView<2, U, C2> fz, 
+     MultiArrayView<2, U, C3> zv,
+     Random const& random,
+     PLSAOptions const & options = PLSAOptions())
+{
+    using namespace linalg; // activate matrix multiplication and arithmetic functions
+
+    int numFeatures = rowCount(features);
+    int numSamples = columnCount(features);
+    int numComponents = columnCount(fz);
+    vigra_precondition(numFeatures >= numComponents && numComponents >= 1,
+      "pLSA(): The number of features has to be larger or equal to the number of components in which the feature matrix is decomposed.");
+    vigra_precondition(rowCount(fz) == numFeatures,
+      "pLSA(): The output matrix fz has to be of dimension numFeatures*numComponents.");
+    vigra_precondition(columnCount(zv) == numSamples && rowCount(zv) == numComponents,
+      "pLSA(): The output matrix zv has to be of dimension numComponents*numSamples.");
+
+    // random initialization of result matrices, subsequent normalization
+    UniformRandomFunctor<Random> randf(random);
+    initMultiArray(destMultiArrayRange(fz), randf);
+    initMultiArray(destMultiArrayRange(zv), randf);
+    prepareColumns(fz, fz, UnitSum);
+    prepareColumns(zv, zv, UnitSum);
+
+    // init vars
+    double eps = 1.0/NumericTraits<U>::max(); // epsilon > 0
+    double lastChange = NumericTraits<U>::max(); // infinity
+    double err = 0;
+    double err_old;
+    int iteration = 0;
+
+    // expectation maximization (EM) algorithm
+    Matrix<U> columnSums(1, numSamples);
+    features.sum(columnSums);
+    Matrix<U> expandedSums = ones<U>(numFeatures, 1) * columnSums;
+    
+    while(iteration < options.max_iterations && (lastChange > options.min_rel_gain))
+    {
+        Matrix<U> fzv = fz*zv;
+        
+        //if(iteration%25 == 0)
+        //{
+            //std::cout << "iteration: " << iteration << std::endl;
+            //std::cout << "last relative change: " << lastChange << std::endl;
+        //}
+
+        Matrix<U> factor = features / pointWise(fzv + (U)eps);
+        zv *= (fz.transpose() * factor);
+        fz *= (factor * zv.transpose());
+        prepareColumns(fz, fz, UnitSum);
+        prepareColumns(zv, zv, UnitSum);
+
+        // check relative change in least squares model fit
+        Matrix<U> model = expandedSums * pointWise(fzv);
+        err_old = err;
+        err = (features - model).squaredNorm();
+        //std::cout << "error: " << err << std::endl;
+        lastChange = abs((err-err_old) / (U)(err + eps));
+        //std::cout << "lastChange: " << lastChange << std::endl;
+         
+        iteration += 1;
+    }
+    //std::cout << "Terminated after " << iteration << " iterations." << std::endl;
+    //std::cout << "Last relative change was " << lastChange << "." << std::endl;
+    
+    if(!options.normalized_component_weights)
+    {
+        // undo the normalization
+        for(int k=0; k<numSamples; ++k)
+            columnVector(zv, k) *= columnSums(0, k);
+    }
+}
+
+template <class U, class C1, class C2, class C3>
+inline void
+pLSA(MultiArrayView<2, U, C1> const & features, 
+     MultiArrayView<2, U, C2> & fz, 
+     MultiArrayView<2, U, C3> & zv,
+     PLSAOptions const & options = PLSAOptions())
+{
+    RandomNumberGenerator<> generator(RandomSeed);
+    pLSA(features, fz, zv, generator, options);
+}
+
+//@}
+
+} // namespace vigra
+
+
+#endif // VIGRA_UNSUPERVISED_DECOMPOSITION_HXX
+
diff --git a/include/vigra/utilities.hxx b/include/vigra/utilities.hxx
new file mode 100644
index 0000000..f482302
--- /dev/null
+++ b/include/vigra/utilities.hxx
@@ -0,0 +1,163 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_BASICS_HXX
+#define VIGRA_BASICS_HXX
+
+#include "config.hxx"
+#include "error.hxx"
+#include "metaprogramming.hxx"
+#include "tuple.hxx"
+#include "diff2d.hxx"
+#include "mathutil.hxx"
+#include <string>
+#include <sstream>
+#include <cctype>
+
+namespace vigra {
+
+/** Convert a value to a string. Available for integral and floating point types
+    and void *.
+*/
+doxygen_overloaded_function(template <class T> std::string asString(T t))
+
+#define VIGRA_AS_STRING(T) \
+inline std::string asString(T t) \
+{ \
+    std::stringstream s; \
+    s << t; \
+    return s.str(); \
+}
+
+VIGRA_AS_STRING(bool)
+VIGRA_AS_STRING(signed char)
+VIGRA_AS_STRING(unsigned char)
+VIGRA_AS_STRING(signed short)
+VIGRA_AS_STRING(unsigned short)
+VIGRA_AS_STRING(signed long)
+VIGRA_AS_STRING(unsigned long)
+VIGRA_AS_STRING(signed long long)
+VIGRA_AS_STRING(unsigned long long)
+VIGRA_AS_STRING(signed int)
+VIGRA_AS_STRING(unsigned int)
+VIGRA_AS_STRING(float)
+VIGRA_AS_STRING(double)
+VIGRA_AS_STRING(long double)
+VIGRA_AS_STRING(void *)
+
+#undef VIGRA_AS_STRING
+
+template <class T>
+std::string & operator<<(std::string & s, T const & t)
+{
+    std::stringstream ss;
+    ss << t; 
+    return s += ss.str();
+}
+
+    /** Convert string to lower case.
+    */
+inline std::string tolower(std::string s)
+{
+    for(unsigned int k=0; k<s.size(); ++k)
+        s[k] = (std::string::value_type)std::tolower(s[k]);
+    return s;
+}
+
+inline std::string tolower(const char * s)
+{
+    return tolower(std::string(s));
+}
+
+    /** Convert string to lower case and remove any white space characters.
+    */
+inline std::string normalizeString(std::string const & s)
+{
+    std::string res;
+    
+    for(unsigned int k=0; k<s.size(); ++k)
+    {
+        if(std::isspace(s[k]))
+            continue;
+        res += (std::string::value_type)std::tolower(s[k]);
+    }
+    return res;
+}
+
+inline std::string normalizeString(const char * s)
+{
+    return normalizeString(std::string(s));
+}
+
+} // namespace vigra
+
+namespace std {
+
+template <class T1, class T2>
+ostream & operator<<(ostream & s, std::pair<T1, T2> const & p)
+{
+    s << "(" << p.first << ", " << p.second << ")";
+    return s;
+}
+
+}
+
+/** \page Utilities Utilities
+    Basic helper functionality needed throughout.
+
+    <UL style="list-style-image:url(documents/bullet.gif)">
+    <LI> \ref vigra::ArrayVector
+         <BR>   <em>replacement for std::vector (always uses consecutive memory)</em>
+    <LI> \ref vigra::BucketQueue and \ref vigra::MappedBucketQueue
+         <BR>   <em>efficient priority queues for integer priorities</em>
+    <LI> \ref RangesAndPoints
+         <BR>   <em>2-D and N-D positions, extents, and boxes</em>
+    <LI> \ref PixelNeighborhood
+         <BR>   <em>4- and 8-neighborhood definitions and circulators</em>
+    <LI> \ref VoxelNeighborhood
+         <BR>   <em>6- and 26-neighborhood definitions and circulators</em>
+    <LI> \ref vigra::IteratorAdaptor
+         <BR>   <em>Quickly create STL-compatible 1D iterator adaptors</em>
+    <LI> \ref TupleTypes
+         <BR>   <em>pair, triple, tuple4, tuple5</em>
+    <LI> \ref MathConstants
+         <BR>   <em>M_PI, M_SQRT2</em>
+    <LI> \ref TimingMacros
+         <BR>   <em>Macros for taking execution speed measurements</em>
+    </UL>
+*/
+
+#endif // VIGRA_BASICS_HXX
diff --git a/include/vigra/voxelneighborhood.hxx b/include/vigra/voxelneighborhood.hxx
new file mode 100644
index 0000000..dedc947
--- /dev/null
+++ b/include/vigra/voxelneighborhood.hxx
@@ -0,0 +1,1652 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2006-2007 by F. Heinrich, B. Seppke, Ullrich Koethe    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_VOXELNEIGHBORHOOD_HXX
+#define VIGRA_VOXELNEIGHBORHOOD_HXX
+
+#include "tinyvector.hxx"
+#include "pixelneighborhood.hxx"
+
+namespace vigra {
+
+/** \addtogroup VoxelNeighborhood Utilities to manage voxel neighborhoods
+
+    6- and 26-neighborhood definitions and circulators.
+
+    <b>\#include</b> \<vigra/voxelneighborhood.hxx\><br>
+
+    <b>See also:</b> \ref vigra::NeighborhoodCirculator
+ */
+//@{
+
+    /// 3-dimensional difference vector
+    typedef vigra::TinyVector<int, 3> Diff3D;
+
+/********************************************************/
+/*                                                      */
+/*                      AtVolumeBorder                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Encode whether a voxel is near the volume border.
+
+        //    This enum is used with \ref isAtVolumeBorder() and
+        //    \ref vigra::RestrictedNeighborhoodCirculator.
+
+        //<b>\#include</b> \<vigra/voxelneighborhood.hxx\><br>
+        //Namespace: vigra
+*/
+
+typedef AtImageBorder AtVolumeBorder;
+
+
+/** \brief Find out whether a voxel is at the volume border.
+
+    This function checks if \a x == 0 or \a x == \a width - 1 and
+    \a y == 0 or \a y == \a height - 1 and so on and returns the appropriate value
+    of \ref vigra::AtVolumeBorder, or zero when the voxel is not at te volume border.
+    The behavior of the function is undefined if (x,y,z) is not inside the volume.
+*/
+inline AtVolumeBorder isAtVolumeBorder(int x, int y, int z, int width, int height, int depth)
+{
+    return static_cast<AtVolumeBorder>((x == 0
+                                         ? LeftBorder
+                                         : x == width-1
+                                             ? RightBorder
+                                             : NotAtBorder) |
+                                       (y == 0
+                                         ? TopBorder
+                                         : y == height-1
+                                             ? BottomBorder
+                                             : NotAtBorder) |
+                                       (z == 0
+                                         ? FrontBorder
+                                         : z == depth-1
+                                             ? RearBorder
+                                             : NotAtBorder));
+}
+
+inline AtVolumeBorder isAtVolumeBorder(Diff3D const & p, Diff3D const & shape)
+{
+    return isAtVolumeBorder(p[0], p[1], p[2], shape[0], shape[1], shape[2]);
+}
+
+/** \brief Find out whether a voxel is at a scan-order relevant volume border.
+    This function checks if \a x == 0 or \a y == 0 or \a z == \a 0 and returns the
+        appropriate value of \ref vigra::AtVolumeBorder, or zero when the voxel is
+        not at te volume border.
+    The behavior of the function is undefined if (x,y,z) is not inside the volume.
+*/
+inline AtVolumeBorder isAtVolumeBorderCausal(int x, int y, int z, int width, int height, int /* depth */)
+{
+    return static_cast<AtVolumeBorder>((x == 0
+                                         ? LeftBorder
+                                         : x == width-1
+                                             ? RightBorder
+                                             : NotAtBorder) |
+                                       (y == 0
+                                         ? TopBorder
+                                         : y == height-1
+                                             ? BottomBorder
+                                             : NotAtBorder) |
+                                       (z == 0
+                                         ? FrontBorder
+                                         : NotAtBorder));
+}
+/** TODO: Write new comment \brief Find out whether a voxel is at a scan-order relevant volume border.
+    This function checks if \a x == 0 or \a y == 0 or \a z == \a 0 and returns the
+        appropriate value of \ref vigra::AtVolumeBorder, or zero when the voxel is
+        not at te volume border.
+    The behavior of the function is undefined if (x,y,z) is not inside the volume.
+*/
+inline AtVolumeBorder isAtVolumeBorderAntiCausal(int x, int y, int z, int width, int height, int depth)
+{
+    return static_cast<AtVolumeBorder>((x == 0
+                                         ? LeftBorder
+                                         : x == width-1
+                                             ? RightBorder
+                                             : NotAtBorder) |
+                                       (y == 0
+                                         ? TopBorder
+                                         : y == height-1
+                                             ? BottomBorder
+                                             : NotAtBorder) |
+                                       (z == depth-1
+                                         ? RearBorder
+                                         : NotAtBorder));
+}
+
+/********************************************************/
+/*                                                      */
+/*                   Neighborhood3DSix                  */
+/*                                                      */
+/********************************************************/
+
+/** 3D 6-Neighborhood. */
+namespace Neighborhood3DSix
+{
+
+/** \brief Encapsulation of direction management of neighbors for a 3D 6-neighborhood.
+*/
+class NeighborCode3D
+{
+    public:
+
+    typedef Diff3D difference_type;
+
+    /** provides enumeration of all directions.
+        DirectionCount may be used for portable loop termination conditions.
+    */
+    enum Direction {
+        Error = -1,
+        InFront= 0,
+        North,
+        West ,
+        Behind,
+        South,
+        East,
+        DirectionCount,
+        CausalFirst = InFront,
+        CausalLast  = West,
+        AntiCausalFirst = Behind,
+        AntiCausalLast  = East,
+
+        InitialDirection = InFront,
+        OppositeDirPrefix = 1,
+        OppositeOffset = 3
+    };
+
+    template <int DUMMY>
+    struct StaticData
+    {
+        static unsigned int b[];
+        static unsigned int c[];
+        static Direction bd[43][6];
+        static Direction bc[43][3];
+        static Diff3D d[];
+        static Diff3D rd[][6];
+    };
+
+    static unsigned int directionBit(Direction d)
+    {
+        return StaticData<0>::b[d];
+    };
+
+
+    /** The number of valid neighbors if the current center is at the volume border.
+    */
+    static unsigned int nearBorderDirectionCount(AtVolumeBorder b)
+    {
+        return StaticData<0>::c[b];
+    }
+
+    /** The valid direction codes when the center is at the volume border.
+        \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
+    */
+    static Direction nearBorderDirections(AtVolumeBorder b, int index)
+    {
+        return StaticData<0>::bd[b][index];
+    }
+
+    /** The valid direction three codes in anti causal direction (means: look back in scanline
+        direction)when the center is at the volume border.
+        Should be used with isAtVolumeBorderCausal to determine the Directions, as this
+        avoids using of the nonesense border ids (e.g. 0,1,8,9...) of this table.
+        \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
+    */
+    static Direction nearBorderDirectionsCausal(AtVolumeBorder b, int index)
+    {
+        return StaticData<0>::bc[b][index];
+    }
+
+    /** transform direction code into corresponding Diff3D offset.
+        (note: there is no bounds checking on the code you pass.)
+    */
+    static Diff3D const & diff(Direction code)
+    {
+        return StaticData<0>::d[code];
+    }
+
+    /** Equivalent to <tt>diff(static_cast<Direction>(code))</tt>.
+        (note: there is no bounds checking on the code you pass.)
+    */
+    static Diff3D const & diff(int code) { return diff(static_cast<Direction>(code)); }
+
+    /**  Equivalent to <tt>diff(code)[dim]</tt> */
+    static int diff(Direction code, int dim) { return diff(code)[dim]; }
+
+    /** Get the relative offset from one neighbor to the other.
+        For example, <tt>relativeDiff(East, West) == multi_differencetype(-2,0,0)</tt>.
+        (note: there is no bounds checking on the code you pass.)
+    */
+    static Diff3D const & relativeDiff(Direction fromCode, Direction toCode)
+    {
+        return StaticData<0>::rd[fromCode][toCode];
+    }
+
+    /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
+        (note: there is no bounds checking on the code you pass.)
+    */
+    static Diff3D const & relativeDiff(int fromCode, int toCode)
+    {
+        return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
+    }
+
+    /**  X-component of diff() */
+    static int dX(Direction code) { return diff(code)[0]; }
+    /**  Y-component of diff() */
+    static int dY(Direction code) { return diff(code)[1]; }
+    /**  Z-component of diff() */
+    static int dZ(Direction code) { return diff(code)[2]; }
+
+    /**  X-component of diff() */
+    static int dX(int code) { return diff(code)[0]; }
+    /**  Y-component of diff() */
+    static int dY(int code) { return diff(code)[1]; }
+    /**  Z-component of diff() */
+    static int dZ(int code) { return diff(code)[2]; }
+
+
+    /** transform Diff3D offset into corresponding direction code.
+        The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
+        is not in the 3DSix-Neighborhood.
+    */
+    static Direction code(Diff3D const & diff)
+    {
+        switch(diff[0]) {
+            case  0:
+            {
+                switch(diff[1]) {
+                    case 0:
+                        switch(diff[2]) {
+                            case 1:
+                                return Behind;
+                            case -1:
+                                return InFront;
+                            default:
+                                return Error;
+                        }
+
+                    case 1:
+                        return (diff[2] == 0) ? South : Error;
+                    case -1:
+                        return (diff[2] == 0) ? North : Error;
+                    default:
+                        return Error;
+                }
+        }
+        case -1:
+            return ((diff[1] == 0) && (diff[2] == 0)) ? West : Error;
+        case  1:
+            return ((diff[1] == 0) && (diff[2] == 0)) ? East : Error;
+        }
+        return Error;
+    }
+
+    /** Check whether a code refers to a diagonal direction.
+        Useful if you want to abstract the differences between 6- and 26-neighborhood.
+        Always <tt>false</tt> for 6-neighborhood.
+    */
+    static bool isDiagonal(Direction) { return false; }
+
+    static Diff3D const & right()           { return diff(East); }          /**<  Offset to the right neighbor */
+    static Diff3D const & top()             { return diff(North); }         /**<  Offset to the top neighbor */
+    static Diff3D const & left()            { return diff(West); }          /**<  Offset to the left neighbor */
+    static Diff3D const & bottom()          { return diff(South); }         /**<  Offset to the bottom neighbor */
+    static Diff3D const & rear()            { return diff(Behind); }        /**<  Offset to the rear neighbor */
+    static Diff3D const & front()           { return diff(InFront); }       /**<  Offset to the neighbor in front */
+
+    static Diff3D const & east()            { return diff(East); }          /**<  Offset to the east neighbor */
+    static Diff3D const & north()           { return diff(North); }         /**<  Offset to the north neighbor */
+    static Diff3D const & west()            { return diff(West); }          /**<  Offset to the west neighbor */
+    static Diff3D const & south()           { return diff(South); }         /**<  Offset to the south neighbor */
+    static Diff3D const & behind()          { return diff(Behind); }        /**<  Offset to the rear neighbor */
+    static Diff3D const & infront()         { return diff(InFront); }       /**<  Offset to the neighbor in front */
+
+}; // class Neighborhood3DSix
+
+
+/** Export NeighborCode3D::Direction into the scope of namespace Neighborhood3DSix.
+*/
+typedef NeighborCode3D::Direction Direction;
+
+static const Direction East           = NeighborCode3D::East;               /**<  Export NeighborCode3D::East to namespace Neighborhood3DSix */
+static const Direction North          = NeighborCode3D::North;              /**<  Export NeighborCode3D::North to namespace Neighborhood3DSix */
+static const Direction West           = NeighborCode3D::West;               /**<  Export NeighborCode3D::West to namespace Neighborhood3DSix */
+static const Direction South          = NeighborCode3D::South;              /**<  Export NeighborCode3D::South to namespace Neighborhood3DSix */
+static const Direction Behind         = NeighborCode3D::Behind;             /**<  Export NeighborCode3D::Behind to namespace Neighborhood3DSix */
+static const Direction InFront        = NeighborCode3D::InFront;            /**<  Export NeighborCode3D::InFront to namespace Neighborhood3DSix */
+static const Direction DirectionCount = NeighborCode3D::DirectionCount;     /**<  Export NeighborCode3D::DirectionCount to namespace Neighborhood3DSix */
+
+template <int DUMMY>
+unsigned int NeighborCode3D::StaticData<DUMMY>::b[] = { 
+                                    1 << InFront,
+                                    1 << North,
+                                    1 << West,
+                                    1 << Behind,
+                                    1 << South,
+                                    1 << East
+                                  };
+
+template <int DUMMY>
+unsigned int NeighborCode3D::StaticData<DUMMY>::c[] = { 
+                                    6, 5, 5, 0, 5, 4, 4, 0, 5, 4,
+                                    4, 0, 0, 0, 0, 0, 5, 4, 4, 0,
+                                    4, 3, 3, 0, 4, 3, 3, 0, 0, 0,
+                                    0, 0, 5, 4, 4, 0, 4, 3, 3, 0,
+                                    4, 3, 3};
+
+template <int DUMMY>
+Direction NeighborCode3D::StaticData<DUMMY>::bd[43][6] = {
+                { InFront, North, West, Behind, South, East},   // 0 - NotAtBorder
+                { InFront, North, West, Behind, South, Error},  // 1 - AtRightBorder
+                { InFront, North, Behind, South, East, Error},  // 2 - AtLeftBorder
+                { Error, Error, Error, Error, Error, Error},
+                { InFront, West, Behind, South, East, Error},   // 4 - AtTopBorder
+                { InFront, West, Behind, South, Error, Error},  // 5 - AtTopRightBorder
+                { InFront, Behind, South, East, Error, Error},  // 6 - AtTopLeftBorder
+                { Error, Error, Error, Error, Error, Error},
+                { InFront, North, West, Behind, East, Error},   // 8 - AtBottomBorder
+                { InFront, North, West, Behind, Error, Error},  // 9 - AtBottomRightBorder
+                { InFront, North, Behind, East, Error, Error},  //10- AtBottomLeftBorder
+                { Error, Error, Error, Error, Error, Error},
+                { Error, Error, Error, Error, Error, Error},
+                { Error, Error, Error, Error, Error, Error},
+                { Error, Error, Error, Error, Error, Error},
+                { Error, Error, Error, Error, Error, Error},
+                { North, West, Behind, South, East, Error},     //16 - AtFrontBorder
+                { North, West, Behind, South, Error, Error},    //17 - AtFrontRightBorder
+                { North, Behind, South, East, Error, Error},    //18 - AtFrontLeftBorder
+                { Error, Error, Error, Error, Error, Error},
+                { West, Behind, South, East, Error,  Error},    //20 - AtTopFrontBorder
+                { West, Behind, South, Error, Error, Error},    //21 - AtTopRightFrontBorder
+                { Behind, South, East, Error, Error,  Error},   //22 - AtTopLeftFrontBorder
+                { Error, Error, Error, Error, Error, Error},
+                { North, West, Behind, East, Error, Error},     //24 - AtBottomFrontBorder
+                { North, West, Behind, Error, Error, Error},    //25 - AtBottomRightFrontBorder
+                { North, Behind, East, Error, Error, Error},    //26 - AtBottomLeftFrontBorder
+                { Error, Error, Error, Error, Error, Error},
+                { Error, Error, Error, Error, Error, Error},
+                { Error, Error, Error, Error, Error, Error},
+                { Error, Error, Error, Error, Error, Error},
+                { Error, Error, Error, Error, Error, Error},
+                { InFront, North, West, South, East,Error},     //32 - AtRearBorder
+                { InFront, North, West, South, Error, Error},   //33 - AtRearRightBorder
+                { InFront, North, South, East, Error, Error},   //34 - AtRearLeftBorder
+                { Error, Error, Error, Error, Error, Error},
+                { InFront, West, South, East, Error, Error},    //36 - AtTopRearBorder
+                { InFront, West, South, Error, Error, Error},   //37 - AtTopRightRearBorder
+                { InFront, South, East, Error, Error, Error},   //38 - AtTopLeftRearBorder
+                { Error, Error, Error, Error, Error, Error},
+                { InFront, North, West, East, Error, Error},    //40 - AtBottomRearBorder
+                { InFront, North, West, Error, Error, Error},   //41 - AtBottomRightRearBorder
+                { InFront, North, East, Error, Error, Error}    //42 - AtBottomLeftRearBorder
+               };
+               
+template <int DUMMY>
+Direction NeighborCode3D::StaticData<DUMMY>::bc[43][3] = {
+            { InFront, North, West},                    // 0 - NotAtBorder
+            { InFront, North, West},                    // 1 - AtRightBorder
+            { InFront, North, Error},                   // 2 - AtLeftBorder
+            { Error, Error, Error},
+            { InFront, West, Error},                    // 4 - AtTopBorder
+            { InFront, West, Error},                    // 5 - AtTopRightBorder
+            { InFront, Error,Error},                    // 6 - AtTopLeftBorder
+            { Error, Error, Error},
+            { InFront, North, West},                    // 8 - AtBottomBorder
+            { InFront, North, West},                    // 9 - AtBottomRightBorder
+            { InFront, North, Error},                   //10- AtBottomLeftBorder
+            { Error, Error, Error},
+            { Error, Error, Error},
+            { Error, Error, Error},
+            { Error, Error, Error},
+            { Error, Error, Error},
+            { North, West, Error},                      //16 - AtFrontBorder
+            { North, West, Error},                      //17 - AtFrontRightBorder
+            { North, Error, Error},                     //18 - AtFrontLeftBorder
+            { Error, Error, Error},
+            { West, Error, Error},                      //20 - AtTopFrontBorder
+            { West, Error, Error},                      //21 - AtTopRightFrontBorder
+            { Error, Error,  Error},                    //22 - AtTopLeftFrontBorder
+            { Error, Error, Error},
+            { North, West, Error},                      //24 - AtBottomFrontBorder
+            { North, West, Error},                      //25 - AtBottomRightFrontBorder
+            { North, Error, Error},                     //26 - AtBottomLeftFrontBorder
+            { Error, Error, Error},
+            { Error, Error, Error},
+            { Error, Error, Error},
+            { Error, Error, Error},
+            { Error, Error, Error},
+            { InFront, North, West},                    //32 - AtRearBorder
+            { InFront, North, West},                    //33 - AtRearRightBorder
+            { InFront, North, Error},                   //34 - AtRearLeftBorder
+            { Error, Error, Error},
+            { InFront, West, Error},                    //36 - AtTopRearBorder
+            { InFront, West, Error},                    //37 - AtTopRightRearBorder
+            { InFront, Error, Error},                   //38 - AtTopLeftRearBorder
+            { Error, Error, Error},
+            { InFront, North, West},                    //40 - AtBottomRearBorder
+            { InFront, North, West},                    //41 - AtBottomRightRearBorder
+            { InFront, North, Error}                    //42 - AtBottomLeftRearBorder
+        };
+               
+template <int DUMMY>
+Diff3D NeighborCode3D::StaticData<DUMMY>::d[] = {
+                    Diff3D(  0,  0, -1),  //InFront
+                    Diff3D(  0, -1,  0),  //North
+                    Diff3D( -1,  0,  0),  //West
+                    Diff3D(  0,  0,  1),  //Behind
+                    Diff3D(  0,  1,  0),  //South
+                    Diff3D(  1,  0,  0)   //East
+                };
+                
+template <int DUMMY>
+Diff3D NeighborCode3D::StaticData<DUMMY>::rd[][6] = {
+//     InFront      -      North         -           West     -         Behind     -      South        -        East
+{ Diff3D( 0, 0, 0), Diff3D(0, -1, 1), Diff3D(-1, 0, 1), Diff3D( 0, 0, 2), Diff3D( 0, 1, 1),  Diff3D( 1, 0, 1)}, //InFront
+{ Diff3D( 0, 1,-1), Diff3D( 0, 0, 0), Diff3D(-1, 1, 0), Diff3D( 0, 1, 1), Diff3D( 0, 2, 0),  Diff3D( 1, 1, 0)}, //North
+{ Diff3D( 1, 0,-1), Diff3D( 1,-1, 0), Diff3D( 0, 0, 0), Diff3D( 1, 0, 1), Diff3D( 1, 1, 0),  Diff3D( 2, 0, 0)}, //West
+{ Diff3D( 0, 0,-2), Diff3D( 0,-1,-1), Diff3D(-1, 0,-1), Diff3D( 0, 0, 0), Diff3D( 0, 1,-1),  Diff3D( 1, 0,-1)}, //Behind
+{ Diff3D( 0,-1,-1), Diff3D( 0,-2, 0), Diff3D(-1,-1, 0), Diff3D( 0,-1, 1), Diff3D( 0, 0, 0),  Diff3D( 1,-1, 0)}, //South
+{ Diff3D(-1, 0,-1), Diff3D(-1,-1, 0), Diff3D(-2, 0, 0), Diff3D(-1, 0, 1), Diff3D(-1, 1, 0), Diff3D( 0, 0, 0) }  //East
+};
+        
+}//namespace Neighborhood3DSix
+
+/** Export \ref vigra::Neighborhood3DSix::NeighborCode3D into the scope of namespace vigra.
+*/
+typedef Neighborhood3DSix::NeighborCode3D NeighborCode3DSix;
+
+/********************************************************/
+/*                                                      */
+/*                   Neighborhood3DTwentySix            */
+/*                                                      */
+/********************************************************/
+/** 3D 26-Neighborhood. */
+namespace Neighborhood3DTwentySix
+{
+
+/** \brief Encapsulation of direction management of neighbors for a 3D 26-neighborhood.
+*/
+class NeighborCode3D
+{
+    public:
+
+    typedef Diff3D difference_type;
+
+   /** provides enumeration of all directions.
+       DirectionCount may be used for portable loop termination conditions.
+     */
+    enum Direction {
+        Error = -1,
+            InFrontNorthWest = 0,
+            InFrontNorth,
+            InFrontNorthEast,
+            InFrontWest,
+        InFront,
+            InFrontEast,
+            InFrontSouthWest,
+            InFrontSouth,
+            InFrontSouthEast,
+
+            NorthWest,
+            North,
+            NorthEast,
+        West,
+            East,
+            SouthWest,
+            South,
+            SouthEast,
+
+            BehindNorthWest,
+            BehindNorth,
+            BehindNorthEast,
+            BehindWest,
+        Behind,
+            BehindEast,
+            BehindSouthWest,
+            BehindSouth,
+            BehindSouthEast,
+
+        DirectionCount,
+            CausalFirst = InFrontNorthWest,
+            CausalLast  = West,
+            AntiCausalFirst = BehindSouthEast,
+            AntiCausalLast  = East,
+
+            InitialDirection = InFrontNorthWest,
+            OppositeDirPrefix = -1,
+            OppositeOffset = 25
+    };
+
+    template <int DUMMY>
+    struct StaticData
+    {
+        static unsigned int b[];
+        static unsigned int c[];
+        static Direction bd[43][26];
+        static Direction bc[43][13];
+        static Diff3D d[];
+    };
+
+    static unsigned int directionBit(Direction d)
+    {
+        return StaticData<0>::b[d];
+    };
+
+
+
+    /** The number of valid neighbors if the current center is at the volume border.
+    */
+    static unsigned int nearBorderDirectionCount(AtVolumeBorder b)
+    {
+        return StaticData<0>::c[b];
+    }
+
+    /** The valid direction codes when the center is at the volume border.
+        \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
+    */
+    static Direction nearBorderDirections(AtVolumeBorder b, int index)
+    {
+        return StaticData<0>::bd[b][index];
+    }
+
+    /** The valid direction three codes in anti causal direction (means: look back in scanline
+        direction)when the center is at the volume border.
+            Should be used with isAtVolumeBorderCausal to determine the Directions, as this
+            avoids using of the nonesense border ids (e.g. 0,1,8,9...) of this table.
+        \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
+     */
+    static Direction nearBorderDirectionsCausal(AtVolumeBorder b, int index)
+    {
+        return StaticData<0>::bc[b][index];
+    }
+
+    /** transform direction code into corresponding Diff3D offset.
+        (note: there is no bounds checking on the code you pass.)
+    */
+    static Diff3D const & diff(Direction code)
+    {
+        return StaticData<0>::d[code];
+    }
+
+    /** Equivalent to <tt>diff(static_cast<Direction>(code))</tt>.
+        (note: there is no bounds checking on the code you pass.)
+    */
+    static Diff3D const & diff(int code) { return diff(static_cast<Direction>(code)); }
+
+    /**  Equivalent to <tt>diff(code)[dim]</tt> */
+    static int diff(Direction code, int dim) { return diff(code)[dim]; }
+
+    /** Get the relative offset from one neighbor to the other.
+    For example, <tt>relativeDiff(East, West) == multi_differencetype(-2,0,0)</tt>.
+    (note: there is no bounds checking on the code you pass.)
+    */
+    static Diff3D const relativeDiff(Direction fromCode, Direction toCode)
+    {
+        //Uncomment the following lines may cause the program to crash because of insufficient
+        //static allocatable memory on the stack
+        /*
+            static Diff3D d[][] = {
+                //   InFront-NW    ---     InFront-N   ---     InFront-NE  ---    Infront-W    ---     InFront     ---   InFront-E     ---   InFront-SW    ---      InFront-S  ---   InFront-SE    ---    NorthWest   ---       North      ---    NorthEast    ---      West      ---       East       ---    SouthWest    ---    South        ---     SouthEast  ---     Behind-NW    ---     Behind-N    ---      Behind-NE  ---     Behind-W    ---      Behind     ---    Behind-E     ---    Behind-SW  [...]
+                {    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2,  1,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0),    Diff3D( 2, 2,  0),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0,  1,  1),    Diff3D( 2,  1,  1),    Diff3D( 0,  2,  1),    Diff3D( 1,  2,  1),    Diff3D( 2,  2,  1),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2),    Diff3D( 2,  0,  2),    Diff3D( 0,   [...]
+                {    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0),    Diff3D( 1, 2,  0),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1,  1,  1),    Diff3D( 1,  1,  1),    Diff3D(-1,  2,  1),    Diff3D( 0,  2,  1),    Diff3D( 1,  2,  1),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2),    Diff3D(-1,   [...]
+                {    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D(-2,  2,  0),    Diff3D(-1,  2,  0),    Diff3D( 0, 2,  0),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2,  1,  1),    Diff3D( 0,  1,  1),    Diff3D(-2,  2,  1),    Diff3D(-1,  2,  1),    Diff3D( 0,  2,  1),    Diff3D(-2,  0,  2),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2),    Diff3D(-2,   [...]
+                {    Diff3D(0,  -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2, 1,  0),    Diff3D( 0, -1,  1),    Diff3D( 1, -1,  1),    Diff3D( 2, -1,  1),    Diff3D( 0,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0,  1,  1),    Diff3D( 1,  1,  1),    Diff3D( 2,  1,  1),    Diff3D( 0, -1,  2),    Diff3D( 1, -1,  2),    Diff3D( 2, -1,  2),    Diff3D( 0,   [...]
+                {    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D( 1, 1,  0),    Diff3D(-1, -1,  1),    Diff3D( 0, -1,  1),    Diff3D( 1, -1,  1),    Diff3D(-1,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1,  1,  1),    Diff3D( 0,  1,  1),    Diff3D( 1,  1,  1),    Diff3D(-1, -1,  2),    Diff3D( 0, -1,  2),    Diff3D( 1, -1,  2),    Diff3D(-1,   [...]
+                {    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0, 1,  0),    Diff3D(-2, -1,  1),    Diff3D(-1, -1,  1),    Diff3D( 0, -1,  1),    Diff3D(-2,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2,  1,  1),    Diff3D(-1,  1,  1),    Diff3D( 0,  1,  1),    Diff3D(-2, -1,  2),    Diff3D(-1, -1,  2),    Diff3D( 0, -1,  2),    Diff3D(-2,   [...]
+                {    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D( 2, -2,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2, 0,  0),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D( 2, -2,  1),    Diff3D( 0, -1,  1),    Diff3D( 2, -1,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0, -2,  2),    Diff3D( 1, -2,  2),    Diff3D( 2, -2,  2),    Diff3D( 0, - [...]
+                {    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1, 0,  0),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D(-1, -1,  1),    Diff3D( 1, -1,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1, -2,  2),    Diff3D( 0, -2,  2),    Diff3D( 1, -2,  2),    Diff3D(-1, - [...]
+                {    Diff3D(-2, -2,  0),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0, 0,  0),    Diff3D(-2, -2,  1),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D(-2, -1,  1),    Diff3D( 0, -1,  1),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2, -2,  2),    Diff3D(-1, -2,  2),    Diff3D( 0, -2,  2),    Diff3D(-2, - [...]
+                {    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D( 2,  1, -1),    Diff3D( 0,  2, -1),    Diff3D( 1,  2, -1),    Diff3D( 2, 2, -1),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 2,  1,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0),    Diff3D( 2,  2,  0),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0,   [...]
+                {    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D(-1,  2, -1),    Diff3D( 0,  2, -1),    Diff3D( 1, 2, -1),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 1,  1,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1,   [...]
+                {    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D(-2,  2, -1),    Diff3D(-1,  2, -1),    Diff3D( 0, 2, -1),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D( 0,  1,  0),    Diff3D(-2,  2,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2,   [...]
+                {    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D( 2, 1, -1),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2,  1,  0),    Diff3D( 0, -1,  1),    Diff3D( 1, -1,  1),    Diff3D( 2, -1,  1),    Diff3D( 0,   [...]
+                {    Diff3D(-2, -1, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D(-1,  1, -1),    Diff3D( 0, 1, -1),    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D(-2, -1,  1),    Diff3D(-1, -1,  1),    Diff3D( 0, -1,  1),    Diff3D(-2,   [...]
+                {    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D( 2, -2, -1),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2, 0, -1),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D( 2, -2,  0),    Diff3D( 0, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D( 2, -2,  1),    Diff3D( 0, - [...]
+                {    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1, 0, -1),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D(-1, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D(-1, - [...]
+                {    Diff3D(-2, -2, -1),    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D(-2, -1, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0, 0, -1),    Diff3D(-2, -2,  0),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D(-2, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2, -2,  1),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D(-2, - [...]
+                {    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D( 2,  0, -2),    Diff3D( 0,  1, -2),    Diff3D( 1,  1, -2),    Diff3D( 2,  1, -2),    Diff3D( 0,  2, -2),    Diff3D( 1,  2, -2),    Diff3D( 2, 2, -2),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 2,  1, -1),    Diff3D( 0,  2, -1),    Diff3D( 1,  2, -1),    Diff3D( 2,  2, -1),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,   [...]
+                {    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D(-1,  1, -2),    Diff3D( 0,  1, -2),    Diff3D( 1,  1, -2),    Diff3D(-1,  2, -2),    Diff3D( 0,  2, -2),    Diff3D( 1, 2, -2),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1,  1, -1),    Diff3D( 1,  1, -1),    Diff3D(-1,  2, -1),    Diff3D( 0,  2, -1),    Diff3D( 1,  2, -1),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,   [...]
+                {    Diff3D(-2,  0, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D(-2,  1, -2),    Diff3D(-1,  1, -2),    Diff3D( 0,  1, -2),    Diff3D(-2,  2, -2),    Diff3D(-1,  2, -2),    Diff3D( 0, 2, -2),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D( 0,  1, -1),    Diff3D(-2,  2, -1),    Diff3D(-1,  2, -1),    Diff3D( 0,  2, -1),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,   [...]
+                {    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D( 2, -1, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D( 2,  0, -2),    Diff3D( 0,  1, -2),    Diff3D( 1,  1, -2),    Diff3D( 2, 1, -2),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D( 2,  1, -1),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,   [...]
+                {    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D(-1,  1, -2),    Diff3D( 0,  1, -2),    Diff3D( 1, 1, -2),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D(-1,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,   [...]
+                {    Diff3D(-2, -1, -2),    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D(-2,  0, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D(-2,  1, -2),    Diff3D(-1,  1, -2),    Diff3D( 0, 1, -2),    Diff3D(-2, -1, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,   [...]
+                {    Diff3D( 0, -2, -2),    Diff3D( 1, -2, -2),    Diff3D( 2, -2, -2),    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D( 2, -1, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D( 2, 0, -2),    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D( 2, -2, -1),    Diff3D( 0, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D( 2, -2,  0),    Diff3D( 0, - [...]
+                {    Diff3D(-1, -2, -2),    Diff3D( 0, -2, -2),    Diff3D( 1, -2, -2),    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D( 1, 0, -2),    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D(-1, -1, -1),    Diff3D( 1, -1, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D(-1, - [...]
+                {    Diff3D(-2, -2, -2),    Diff3D(-1, -2, -2),    Diff3D( 0, -2, -2),    Diff3D(-2, -1, -2),    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D(-2,  0, -2),    Diff3D(-1,  0, -2),    Diff3D( 0, 0, -2),    Diff3D(-2, -2, -1),    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D(-2, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2, -2,  0),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D(-2, - [...]
+            };
+            return d[fromCode][toCode];
+        */
+        return diff(toCode)-diff(fromCode);
+    }
+
+   /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
+       (note: there is no bounds checking on the code you pass.)
+   */
+    static Diff3D const relativeDiff(int fromCode, int toCode)
+    {
+        return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
+    }
+
+    /**  X-component of diff() */
+    static int dX(Direction code) { return diff(code)[0]; }
+    /**  Y-component of diff() */
+    static int dY(Direction code) { return diff(code)[1]; }
+    /**  Z-component of diff() */
+    static int dZ(Direction code) { return diff(code)[2]; }
+
+    /**  X-component of diff() */
+    static int dX(int code) { return diff(code)[0]; }
+    /**  Y-component of diff() */
+    static int dY(int code) { return diff(code)[1]; }
+    /**  Z-component of diff() */
+    static int dZ(int code) { return diff(code)[2]; }
+
+    /** transform 6-neighborhood code into 26-neighborhood code.
+     */
+    static Direction code(Neighborhood3DSix::Direction d)
+    {
+        switch (d){
+            case Neighborhood3DSix::InFront :
+                    return InFront;
+            case Neighborhood3DSix::North :
+                    return North;
+            case Neighborhood3DSix::West :
+                    return West;
+            case Neighborhood3DSix::East :
+                    return East;
+            case Neighborhood3DSix::South :
+                    return South;
+            case Neighborhood3DSix::Behind :
+                    return Behind;
+            default:
+                vigra_fail("NeighborCode3D::code(): Internal error -- invalid direction code.");
+        }
+        return Error;
+    }
+
+    /** transform Diff3D offset into corresponding direction code.
+       The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
+       is not in the 3DTwentySix-Neighborhood.
+    */
+    static Direction code(Diff3D const & diff)
+    {
+        switch(diff[0]){
+            case -1:
+                switch(diff[1]){
+                    case -1:
+                        switch(diff[2]){
+                            case -1: return InFrontNorthWest; // ( -1, -1, -1)
+                            case  0: return NorthWest;        // ( -1, -1,  0)
+                            case  1: return BehindNorthWest;  // ( -1, -1,  1)
+                        }
+                    case  0:
+                        switch(diff[2]){
+                            case -1: return InFrontWest;      // ( -1,  0, -1)
+                            case  0: return West;             // ( -1,  0,  0)
+                            case  1: return BehindWest;       // ( -1,  0,  1)
+                        }
+                    case  1:
+                        switch(diff[2]){
+                            case -1: return InFrontSouthWest; // ( -1,  1, -1)
+                            case  0: return SouthWest;        // ( -1,  1,  0)
+                            case  1: return BehindSouthWest;  // ( -1,  1,  1)
+                        }
+                }
+            case  0:
+                switch(diff[1]){
+                    case -1:
+                        switch(diff[2]){
+                            case -1: return InFrontNorth;     // (  0,  0, -1)
+                            case  0: return North;            // (  0, -1,  0)
+                            case  1: return BehindNorth;      // (  0, -1,  1)
+                        }
+                    case  0:
+                        switch(diff[2]){
+                            case -1: return InFront;          // (  0,  0, -1)
+                            case  1: return Behind;           // (  0,  0,  1)
+                        }
+                    case  1:
+                        switch(diff[2]){
+                            case -1: return InFrontSouth;     // (  0,  1, -1)
+                            case  0: return South;            // (  0,  1,  0)
+                            case  1: return BehindSouth;      // (  0,  1,  1)
+                        }
+                }
+            case  1:
+                switch(diff[1]){
+                    case -1:
+                        switch(diff[2]){
+                            case -1: return InFrontNorthEast;  // (  1, -1, -1)
+                            case  0: return NorthEast;         // (  1, -1,  0)
+                            case  1: return BehindNorthEast;   // (  1, -1,  1)
+                        }
+                    case  0:
+                        switch(diff[2]){
+                            case -1: return InFrontEast;       // (  1,  0, -1)
+                            case  0: return East;              // (  1,  0,  0)
+                            case  1: return BehindEast;        // (  1,  0,  1)
+                        }
+                    case  1:
+                        switch(diff[2]){
+                            case -1: return InFrontSouthEast;  // (  1,  1, -1)
+                            case  0: return SouthEast;         // (  1,  1,  0)
+                            case  1: return BehindSouthEast;   // (  1,  1,  1)
+                        }
+                }
+        }
+        return Error; // better safe than sorry
+    }
+
+    /** Check whether a code refers to a diagonal direction.
+        Useful if you want to abstract the differences between 6- and 26-neighborhood.
+        Always <tt>false</tt> for 6-neighborhood.
+    */
+    static bool isDiagonal(Direction dir) {
+        Diff3D d = diff(dir);
+        if (abs(d[0])+abs(d[1])+abs(d[2])==1)
+            return false;
+        else
+            return true;
+    }
+
+    static Diff3D const & frontTopLeft()        { return diff(InFrontNorthWest); }    /**<  Offset to the front-top-left neighbor */
+    static Diff3D const & frontTop()            { return diff(InFrontNorth); }        /**<  Offset to the front-top neighbor */
+    static Diff3D const & frontTopRight()       { return diff(InFrontNorthEast); }    /**<  Offset to the front-top-right neighbor */
+    static Diff3D const & frontLeft()           { return diff(InFrontWest); }         /**<  Offset to the front-left neighbor */
+    static Diff3D const & front()               { return diff(InFront); }             /**<  Offset to the front neighbor */
+    static Diff3D const & frontRight()          { return diff(InFrontEast); }         /**<  Offset to the front-right neighbor */
+    static Diff3D const & frontBottomLeft()     { return diff(InFrontSouthWest); }    /**<  Offset to the front-bottom-left neighbor */
+    static Diff3D const & frontBottom()         { return diff(InFrontSouth); }        /**<  Offset to the front-bottom neighbor */
+    static Diff3D const & frontBottomRight()    { return diff(InFrontSouthEast); }    /**<  Offset to the front-bottom-right neighbor */
+
+    static Diff3D const & topLeft()             { return diff(NorthWest); }           /**<  Offset to the top-left neighbor */
+    static Diff3D const & top()                 { return diff(North); }               /**<  Offset to the top neighbor */
+    static Diff3D const & topRight()            { return diff(NorthEast); }           /**<  Offset to the top-right neighbor */
+    static Diff3D const & left()                { return diff(West); }                /**<  Offset to the left neighbor */
+    static Diff3D const & right()               { return diff(East); }                /**<  Offset to the right neighbor */
+    static Diff3D const & bottomLeft()          { return diff(SouthWest); }           /**<  Offset to the bottom-left neighbor */
+    static Diff3D const & bottom()              { return diff(South); }               /**<  Offset to the bottom neighbor */
+    static Diff3D const & bottomRight()         { return diff(SouthEast); }           /**<  Offset to the bottom-right neighbor */
+
+    static Diff3D const & rearTopLeft()         { return diff(BehindNorthWest); }     /**<  Offset to the rear-top-left neighbor */
+    static Diff3D const & rearTop()             { return diff(BehindNorth); }         /**<  Offset to the rear-top neighbor */
+    static Diff3D const & rearTopRight()        { return diff(BehindNorthEast); }     /**<  Offset to the rear-top-right neighbor */
+    static Diff3D const & rearLeft()            { return diff(BehindWest); }          /**<  Offset to the rear-left neighbor */
+    static Diff3D const & rear()                { return diff(Behind); }              /**<  Offset to the rear neighbor */
+    static Diff3D const & rearRight()           { return diff(BehindEast); }          /**<  Offset to the rear-right neighbor */
+    static Diff3D const & rearBottomLeft()      { return diff(BehindSouthWest); }     /**<  Offset to the rear-bottom-left neighbor */
+    static Diff3D const & rearBottom()          { return diff(BehindSouth); }         /**<  Offset to the rear-bottom neighbor */
+    static Diff3D const & rearBottomRight()     { return diff(BehindSouthEast); }     /**<  Offset to the rear-bottom-right neighbor */
+
+    //----- other namings
+
+    static Diff3D const & infrontNorthWest()    { return diff(InFrontNorthWest); }    /**<  Offset to the infront-north-west neighbor */
+    static Diff3D const & infrontNorth()        { return diff(InFrontNorth); }        /**<  Offset to the infront-north neighbor */
+    static Diff3D const & infrontNorthEast()    { return diff(InFrontNorthEast); }    /**<  Offset to the infront-north-east neighbor */
+    static Diff3D const & infrontWest()         { return diff(InFrontWest); }         /**<  Offset to the infront-west neighbor */
+    static Diff3D const & infront()             { return diff(InFront); }             /**<  Offset to the infront neighbor */
+    static Diff3D const & infrontEast()         { return diff(InFrontEast); }         /**<  Offset to the infront-east neighbor */
+    static Diff3D const & infrontSouthWest()    { return diff(InFrontSouthWest); }    /**<  Offset to the infront-south-west neighbor */
+    static Diff3D const & infrontSouth()        { return diff(InFrontSouth); }        /**<  Offset to the infront-south neighbor */
+    static Diff3D const & infrontSouthEast()    { return diff(InFrontSouthEast); }    /**<  Offset to the infront-south-east neighbor */
+
+    static Diff3D const & northWest()           { return diff(NorthWest); }            /**<  Offset to the north-west neighbor */
+    static Diff3D const & north()               { return diff(North); }                /**<  Offset to the north neighbor */
+    static Diff3D const & northEast()           { return diff(NorthEast); }            /**<  Offset to the north-east neighbor */
+    static Diff3D const & west()                { return diff(West); }                 /**<  Offset to the west neighbor */
+    static Diff3D const & east()                { return diff(East); }                 /**<  Offset to the right neighbor */
+    static Diff3D const & southWest()           { return diff(SouthWest); }            /**<  Offset to the south-west neighbor */
+    static Diff3D const & south()               { return diff(South); }                /**<  Offset to the south neighbor */
+    static Diff3D const & southEast()           { return diff(SouthEast); }            /**<  Offset to the south-east neighbor */
+
+    static Diff3D const & behindNorthWest()     { return diff(BehindNorthWest); }      /**<  Offset to the behind-north-west neighbor */
+    static Diff3D const & behindNorth()         { return diff(BehindNorth); }          /**<  Offset to the behind-north neighbor */
+    static Diff3D const & behindNorthEast()     { return diff(BehindNorthEast); }      /**<  Offset to the behind-north-east neighbor */
+    static Diff3D const & behindEast()          { return diff(BehindWest); }           /**<  Offset to the behind-west neighbor */
+    static Diff3D const & behind()              { return diff(Behind); }               /**<  Offset to the behind neighbor */
+    static Diff3D const & behindWest()          { return diff(BehindEast); }           /**<  Offset to the behind-right neighbor */
+    static Diff3D const & behindSouthWest()     { return diff(BehindSouthWest); }      /**<  Offset to the behind-south-west neighbor */
+    static Diff3D const & behindSouth()         { return diff(BehindSouth); }          /**<  Offset to the behind-south neighbor */
+    static Diff3D const & behindSouthEast()     { return diff(BehindSouthEast); }      /**<  Offset to the behind-south-east neighbor */
+}; // class Neighborhood3D
+
+
+/** Export NeighborCode3D::Direction into the scope of namespace Neighborhood3DSix.
+ */
+typedef NeighborCode3D::Direction Direction;
+
+static const Direction InFrontNorthWest   = NeighborCode3D::InFrontNorthWest;     /**<  Export NeighborCode3D::InFrontNorthWest to namespace Neighborhood3DTwentySix */
+static const Direction InFrontNorth       = NeighborCode3D::InFrontNorth;         /**<  Export NeighborCode3D::InFrontNorth to namespace Neighborhood3DTwentySix */
+static const Direction InFrontNorthEast   = NeighborCode3D::InFrontNorthEast;     /**<  Export NeighborCode3D::InFrontNorthEast to namespace Neighborhood3DTwentySix */
+static const Direction InFrontWest        = NeighborCode3D::InFrontWest;          /**<  Export NeighborCode3D::InFrontWest to namespace Neighborhood3DTwentySix */
+static const Direction InFront            = NeighborCode3D::InFront;              /**<  Export NeighborCode3D::InFront to namespace Neighborhood3DTwentySix */
+static const Direction InFrontEast        = NeighborCode3D::InFrontEast;          /**<  Export NeighborCode3D::InFrontEast to namespace Neighborhood3DTwentySix */
+static const Direction InFrontSouthWest   = NeighborCode3D::InFrontSouthWest;     /**<  Export NeighborCode3D::InFrontSouthWest to namespace Neighborhood3DTwentySix */
+static const Direction InFrontSouth       = NeighborCode3D::InFrontSouth;         /**<  Export NeighborCode3D::InFrontSouth to namespace Neighborhood3DTwentySix */
+static const Direction InFrontSouthEast   = NeighborCode3D::InFrontSouthEast;     /**<  Export NeighborCode3D::InFrontSouthEast to namespace Neighborhood3DTwentySix */
+
+static const Direction NorthWest          = NeighborCode3D::NorthWest;            /**<  Export NeighborCode3D::NorthWest to namespace Neighborhood3DTwentySix */
+static const Direction North              = NeighborCode3D::North;                /**<  Export NeighborCode3D::North to namespace Neighborhood3DTwentySix */
+static const Direction NorthEast          = NeighborCode3D::NorthEast;            /**<  Export NeighborCode3D::NorthEast to namespace Neighborhood3DTwentySix */
+static const Direction West               = NeighborCode3D::West;                 /**<  Export NeighborCode3D::West to namespace Neighborhood3DTwentySix */
+static const Direction East               = NeighborCode3D::East;                 /**<  Export NeighborCode3D::East to namespace Neighborhood3DTwentySix */
+static const Direction SouthWest          = NeighborCode3D::SouthWest;            /**<  Export NeighborCode3D::SouthWest to namespace Neighborhood3DTwentySix */
+static const Direction South              = NeighborCode3D::South;                /**<  Export NeighborCode3D::South to namespace Neighborhood3DTwentySix */
+static const Direction SouthEast          = NeighborCode3D::SouthEast;            /**<  Export NeighborCode3D::SouthEast to namespace Neighborhood3DTwentySix */
+
+static const Direction BehindNorthWest    = NeighborCode3D::BehindNorthWest;      /**<  Export NeighborCode3D::BehindNorthWest to namespace Neighborhood3DTwentySix */
+static const Direction BehindNorth        = NeighborCode3D::BehindNorth;          /**<  Export NeighborCode3D::BehindNorth to namespace Neighborhood3DTwentySix */
+static const Direction BehindNorthEast    = NeighborCode3D::BehindNorthEast;      /**<  Export NeighborCode3D::BehindNorthEast to namespace Neighborhood3DTwentySix */
+static const Direction BehindWest         = NeighborCode3D::BehindWest;           /**<  Export NeighborCode3D::BehindWest to namespace Neighborhood3DTwentySix */
+static const Direction Behind             = NeighborCode3D::Behind;               /**<  Export NeighborCode3D::Behind to namespace Neighborhood3DTwentySix */
+static const Direction BehindEast         = NeighborCode3D::BehindEast;           /**<  Export NeighborCode3D::BehindEast to namespace Neighborhood3DTwentySix */
+static const Direction BehindSouthWest    = NeighborCode3D::BehindSouthWest;      /**<  Export NeighborCode3D::BehindSouthWest to namespace Neighborhood3DTwentySix */
+static const Direction BehindSouth        = NeighborCode3D::BehindSouth;          /**<  Export NeighborCode3D::BehindSouth to namespace Neighborhood3DTwentySix */
+static const Direction BehindSouthEast    = NeighborCode3D::BehindSouthEast;      /**<  Export NeighborCode3D::BehindSouthEast to namespace Neighborhood3DTwentySix */
+
+static const Direction DirectionCount     = NeighborCode3D::DirectionCount;       /**<  Export NeighborCode3D::DirectionCount to namespace Neighborhood3DTwentySix */
+
+template <int DUMMY>
+unsigned int NeighborCode3D::StaticData<DUMMY>::b[] = {
+                1 <<  InFrontNorthWest,
+                1 <<  InFrontNorth,
+                1 <<  InFrontNorthEast,
+                1 <<  InFrontWest,
+                1 <<  InFront,
+                1 <<  InFrontEast,
+                1 <<  InFrontSouthWest,
+                1 <<  InFrontSouth,
+                1 <<  InFrontSouthEast,
+
+                1 <<  NorthWest,
+                1 <<  North,
+                1 <<  NorthEast,
+                1 <<  West,
+                1 <<  East,
+                1 <<  SouthWest,
+                1 <<  South,
+                1 <<  SouthEast,
+
+                1 <<  BehindNorthWest,
+                1 <<  BehindNorth,
+                1 <<  BehindNorthEast,
+                1 <<  BehindWest,
+                1 <<  Behind,
+                1 <<  BehindEast,
+                1 <<  BehindSouthWest,
+                1 <<  BehindSouth,
+                1 <<  BehindSouthEast
+            };
+            
+template <int DUMMY>
+unsigned int NeighborCode3D::StaticData<DUMMY>::c[] = { 
+                                    26, 17, 17,  0, 17, 11, 11,  0, 17, 11,
+                                    11,  0,  0,  0,  0,  0, 17, 11, 11,  0,
+                                    11,  7,  7,  0, 11,  7,  7,  0,  0,  0,
+                                     0,  0, 17, 11, 11,  0, 11,  7,  7,  0,
+                                    11,  7,  7};
+
+template <int DUMMY>
+Direction NeighborCode3D::StaticData<DUMMY>::bd[43][26] = {
+//0 - NotAtBorder
+{    InFrontNorthWest,   InFrontNorth,   InFrontNorthEast,
+    InFrontWest,        InFront,        InFrontEast,
+    InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,
+
+    NorthWest, North, NorthEast,
+    West,             East,
+    SouthWest, South, SouthEast,
+
+    BehindNorthWest, BehindNorth, BehindNorthEast,
+    BehindWest,      Behind,      BehindEast,
+    BehindSouthWest, BehindSouth, BehindSouthEast},
+//1 - AtRightBorder
+{   InFrontNorthWest, InFrontNorth, /*InFrontNorthEast,*/
+    InFrontWest,      InFront,      /*InFrontEast,*/
+    InFrontSouthWest, InFrontSouth, /*InFrontSouthEast,*/
+
+    NorthWest, North, /*NorthEast,*/
+    West,             /*East,*/
+    SouthWest, South, /*SouthEast,*/
+
+    BehindNorthWest, BehindNorth, /*BehindNorthEast,*/
+    BehindWest,      Behind,      /*BehindEast,*/
+    BehindSouthWest, BehindSouth, /*BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//2 - AtLeftBorder
+{   /*InFrontNorthWest,*/   InFrontNorth, InFrontNorthEast,
+    /*InFrontWest,*/       InFront,      InFrontEast,
+    /*InFrontSouthWest,*/   InFrontSouth, InFrontSouthEast,
+
+    /*NorthWest,*/ North, NorthEast,
+    /*West,*/            East,
+    /*SouthWest,*/ South, SouthEast,
+
+    /*BehindNorthWest,*/ BehindNorth, BehindNorthEast,
+    /*BehindWest,*/     Behind,      BehindEast,
+    /*BehindSouthWest,*/ BehindSouth, BehindSouthEast,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//3 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error,        Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//4 - AtTopBorder
+{   /*InFrontNorthWest, InFrontNorth, InFrontNorthEast,*/
+    InFrontWest,        InFront,      InFrontEast,
+    InFrontSouthWest, InFrontSouth,   InFrontSouthEast,
+
+    /*NorthWest, North, NorthEast,*/
+    West,             East,
+    SouthWest, South, SouthEast,
+
+    /*BehindNorthWest, BehindNorth, BehindNorthEast,*/
+    BehindWest,                 Behind,                 BehindEast,
+    BehindSouthWest, BehindSouth, BehindSouthEast,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//5 - AtTopRightBorder
+{   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,*/
+    InFrontWest,        InFront,        /*InFrontEast,*/
+    InFrontSouthWest, InFrontSouth,     /*InFrontSouthEast,*/
+
+    /*NorthWest, North, NorthEast,*/
+    West,             /*East,*/
+    SouthWest, South, /*SouthEast,*/
+
+    /*BehindNorthWest, BehindNorth, BehindNorthEast,*/
+    BehindWest,        Behind,      /*BehindEast,*/
+    BehindSouthWest, BehindSouth,   /*BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//6 - AtTopLeftBorder
+{   /*InFrontNorthWest,     InFrontNorth,   InFrontNorthEast,*/
+    /*InFrontWest,*/        InFront,        InFrontEast,
+    /*InFrontSouthWest,*/   InFrontSouth,   InFrontSouthEast,
+
+    /*NorthWest,    North,  NorthEast,*/
+    /*West,*/               East,
+    /*SouthWest,*/  South,  SouthEast,
+
+    /*BehindNorthWest,      BehindNorth, BehindNorthEast,*/
+    /*BehindWest, */        Behind,      BehindEast,
+    /*BehindSouthWest,*/    BehindSouth, BehindSouthEast,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//7 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//8 - AtBottomBorder
+{   InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
+    InFrontWest,      InFront,         InFrontEast,
+    /*InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
+
+    NorthWest,      North,  NorthEast,
+    West,                   East,
+    /*SouthWest,    South,  SouthEast,*/
+
+    BehindNorthWest,    BehindNorth, BehindNorthEast,
+    BehindWest,         Behind,      BehindEast,
+    /*BehindSouthWest,  BehindSouth, BehindSouthEast*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//9 - AtBottomRightBorder
+{   InFrontNorthWest, InFrontNorth,    /*InFrontNorthEast,*/
+    InFrontWest,      InFront,         /*InFrontEast,*/
+    /*InFrontSouthWest, InFrontSouth,  InFrontSouthEast,*/
+
+    NorthWest, North,   /*NorthEast,*/
+    West,               /*East,*/
+    /*SouthWest, South, SouthEast,*/
+
+    BehindNorthWest, BehindNorth,   /*BehindNorthEast,*/
+    BehindWest,      Behind,        /*BehindEast,*/
+    /*BehindSouthWest, BehindSouth, BehindSouthEast*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//10 - AtBottomLeftBorder
+{   /*InFrontNorthWest,*/   InFrontNorth,   InFrontNorthEast,
+    /*InFrontWest,*/        InFront,        InFrontEast,
+    /*InFrontSouthWest,     InFrontSouth,   InFrontSouthEast,*/
+
+    /*NorthWest,*/  North,  NorthEast,
+    /*West,*/               East,
+    /*SouthWest,    South,  SouthEast,*/
+
+    /*BehindNorthWest,*/ BehindNorth,   BehindNorthEast,
+    /*BehindWest,*/      Behind,        BehindEast,
+    /*BehindSouthWest, BehindSouth,     BehindSouthEast*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//11 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//12 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//13 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//14 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//15 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//16 - AtFrontBorder
+{   /*InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
+    InFrontWest,        InFront,         InFrontEast,
+    InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
+
+    NorthWest, North, NorthEast,
+    West,             East,
+    SouthWest, South, SouthEast,
+
+    BehindNorthWest, BehindNorth, BehindNorthEast,
+    BehindWest,      Behind,      BehindEast,
+    BehindSouthWest, BehindSouth, BehindSouthEast,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//17 - AtFrontRightBorder
+{   /*InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
+    InFrontWest,              InFront,                 InFrontEast,
+    InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
+
+    NorthWest, North, /*NorthEast,*/
+    West,             /*East,*/
+    SouthWest, South, /*SouthEast,*/
+
+    BehindNorthWest, BehindNorth, /*BehindNorthEast,*/
+    BehindWest,      Behind,      /*BehindEast,*/
+    BehindSouthWest, BehindSouth, /*BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//18 - AtFrontLeftBorder
+{   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,
+    InFrontWest,        InFront,        InFrontEast,
+    InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,*/
+
+    /*NorthWest,*/ North, NorthEast,
+    /*West,*/             East,
+    /*SouthWest,*/ South, SouthEast,
+
+    /*BehindNorthWest,*/ BehindNorth, BehindNorthEast,
+    /*BehindWest,*/      Behind,      BehindEast,
+    /*BehindSouthWest,*/ BehindSouth, BehindSouthEast,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//19 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//20 - AtTopFrontBorder
+{   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,
+    InFrontWest,        InFront,        InFrontEast,
+    InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,*/
+
+    /*NorthWest,    North,  NorthEast,*/
+    West,                   East,
+    SouthWest,      South,  SouthEast,
+
+    /*BehindNorthWest,  BehindNorth,    BehindNorthEast,*/
+    BehindWest,         Behind,         BehindEast,
+    BehindSouthWest,    BehindSouth,    BehindSouthEast,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//21 - AtTopRightFrontBorder
+{   /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
+    InFrontWest,        InFront,       InFrontEast,
+    InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
+
+    /*NorthWest, North, NorthEast,*/
+    West,               /*East,*/
+    SouthWest,   South, /*SouthEast,*/
+
+    /*BehindNorthWest, BehindNorth, BehindNorthEast,*/
+    BehindWest,        Behind,      /*BehindEast,*/
+    BehindSouthWest, BehindSouth,   /*BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error},
+//22 - AtTopLeftFrontBorder
+{   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,
+    InFrontWest,        InFront,        InFrontEast,
+    InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,*/
+
+    /*NorthWest,    North, NorthEast,*/
+    /*West,*/              East,
+    /*SouthWest,*/  South, SouthEast,
+
+    /*BehindNorthWest,      BehindNorth, BehindNorthEast,*/
+    /*BehindWest,*/         Behind,      BehindEast,
+    /*BehindSouthWest,*/    BehindSouth, BehindSouthEast,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error},
+//23 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//24 - AtBottomFrontBorder
+{   /*InFrontNorthWest, InFrontNorth, InFrontNorthEast,
+    InFrontWest,        InFront,      InFrontEast,
+    InFrontSouthWest,   InFrontSouth, InFrontSouthEast,*/
+
+    NorthWest,      North, NorthEast,
+    West,                  East,
+    /*SouthWest,    South, SouthEast,*/
+
+    BehindNorthWest,    BehindNorth, BehindNorthEast,
+    BehindWest,         Behind,      BehindEast,
+    /*BehindSouthWest,  BehindSouth, BehindSouthEast*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//25 - AtBottomRightFrontBorder
+{   /*InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
+    InFrontWest,        InFront,         InFrontEast,
+    InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
+
+    NorthWest,      North,  /*NorthEast,*/
+    West,                   /* East,*/
+    /*SouthWest,    South,  SouthEast,*/
+
+    BehindNorthWest,    BehindNorth, /*BehindNorthEast,*/
+    BehindWest,         Behind,      /*BehindEast,*/
+    /*BehindSouthWest,  BehindSouth, BehindSouthEast*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error},
+//26 - AtBottomLeftFrontBorder
+{ /*InFrontNorthWest, InFrontNorth, InFrontNorthEast,
+    InFrontWest,      InFront,      InFrontEast,
+    InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
+
+    /*NorthWest,*/ North, NorthEast,
+    /*West,*/             East,
+    /*SouthWest,   South, SouthEast,*/
+
+    /*BehindNorthWest,*/ BehindNorth, BehindNorthEast,
+    /*BehindWest,*/      Behind,      BehindEast,
+    /*BehindSouthWest,   BehindSouth, BehindSouthEast*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error},
+//27 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//28 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//29 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//30 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//31 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//32 - AtRearBorder
+{   InFrontNorthWest, InFrontNorth, InFrontNorthEast,
+    InFrontWest,      InFront,      InFrontEast,
+    InFrontSouthWest, InFrontSouth, InFrontSouthEast,
+
+    NorthWest, North, NorthEast,
+    West,             East,
+    SouthWest, South, SouthEast,
+
+    /*BehindNorthWest, BehindNorth, BehindNorthEast,
+    BehindWest,        Behind,      BehindEast,
+    BehindSouthWest,   BehindSouth, BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//33 - AtRearRightBorder
+{   InFrontNorthWest, InFrontNorth, /*InFrontNorthEast,*/
+    InFrontWest,      InFront,      /*InFrontEast,*/
+    InFrontSouthWest, InFrontSouth, /*InFrontSouthEast,*/
+
+    NorthWest, North, /*NorthEast,*/
+    West,             /*East,*/
+    SouthWest, South, /*SouthEast,*/
+
+    /*BehindNorthWest, BehindNorth, BehindNorthEast,
+    BehindWest,        Behind,      BehindEast,
+    BehindSouthWest,   BehindSouth, BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//34 - AtRearLeftBorder
+{   /*InFrontNorthWest,*/ InFrontNorth, InFrontNorthEast,
+    /*InFrontWest,*/      InFront,      InFrontEast,
+    /*InFrontSouthWest,*/ InFrontSouth, InFrontSouthEast,
+
+    /*NorthWest,*/ North, NorthEast,
+    /*West,*/             East,
+    /*SouthWest,*/ South, SouthEast,
+
+    /*BehindNorthWest, BehindNorth,   BehindNorthEast,
+    BehindWest,        Behind,        BehindEast,
+    BehindSouthWest,   BehindSouth,   BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//35 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//36 - AtTopRearBorder
+{   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,*/
+    InFrontWest,        InFront,        InFrontEast,
+    InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,
+
+    /*NorthWest,    North, NorthEast,*/
+    West,                  East,
+    SouthWest,      South, SouthEast,
+
+    /*BehindNorthWest, BehindNorth,   BehindNorthEast,
+    BehindWest,        Behind,        BehindEast,
+    BehindSouthWest,   BehindSouth,   BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//37 - AtTopRightRearBorder
+{   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,*/
+    InFrontWest,        InFront,        /*InFrontEast,*/
+    InFrontSouthWest,   InFrontSouth,   /*InFrontSouthEast,*/
+
+    /*NorthWest, North, NorthEast,*/
+    West,               /*East,*/
+    SouthWest,   South, /*SouthEast,*/
+
+    /*BehindNorthWest,  BehindNorth, BehindNorthEast,
+    BehindWest,         Behind,      BehindEast,
+    BehindSouthWest,    BehindSouth, BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error},
+//38 - AtTopLeftRearBorder
+{   /*InFrontNorthWest,     InFrontNorth,    InFrontNorthEast,*/
+    /*InFrontWest,*/        InFront,         InFrontEast,
+    /*InFrontSouthWest,*/   InFrontSouth,   InFrontSouthEast,
+
+    /*NorthWest,    North,  NorthEast,*/
+    /*West,*/               East,
+    /*SouthWest,*/  South,  SouthEast,
+
+    /*BehindNorthWest,  BehindNorth,    BehindNorthEast,
+    BehindWest,         Behind,         BehindEast,
+    BehindSouthWest,    BehindSouth,    BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error},
+//39 - Nothin'
+{   Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//40 - AtBottomRearBorder
+{   InFrontNorthWest,   InFrontNorth,   InFrontNorthEast,
+    InFrontWest,        InFront,        InFrontEast,
+    /*InFrontSouthWest, InFrontSouth,   InFrontSouthEast,*/
+
+    NorthWest,      North, NorthEast,
+    West,                  East,
+    /*SouthWest,    South, SouthEast,*/
+
+    /*BehindNorthWest,  BehindNorth, BehindNorthEast,
+    BehindWest,         Behind,      BehindEast,
+    BehindSouthWest,    BehindSouth, BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error},
+//41 - AtBottomRightRearBorder
+{   InFrontNorthWest,   InFrontNorth, /*InFrontNorthEast,*/
+    InFrontWest,        InFront,      /*InFrontEast,*/
+    /*InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
+
+    NorthWest,   North, /*NorthEast,*/
+    West,               /*East,*/
+    /*SouthWest, South, SouthEast,*/
+
+    /*BehindNorthWest, BehindNorth, BehindNorthEast,
+    BehindWest,        Behind,      BehindEast,
+    BehindSouthWest,   BehindSouth, BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error},
+//42 - AtBottomLeftRearBorder
+{   /*InFrontNorthWest,*/   InFrontNorth,   InFrontNorthEast,
+    /*InFrontWest,*/        InFront,        InFrontEast,
+    /*InFrontSouthWest,     InFrontSouth,   InFrontSouthEast,*/
+
+    /*NorthWest,*/  North,  NorthEast,
+    /*West,*/               East,
+    /*SouthWest,    South,  SouthEast,*/
+
+    /*BehindNorthWest,  BehindNorth, BehindNorthEast,
+    BehindWest,         Behind,      BehindEast,
+    BehindSouthWest,    BehindSouth, BehindSouthEast,*/
+    Error, Error, Error, Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error, Error, Error,
+    Error, Error, Error, Error}
+};
+               
+template <int DUMMY>
+Direction NeighborCode3D::StaticData<DUMMY>::bc[43][13] = {
+//0 - NotAtBorder -----> should never be used
+    { InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
+      InFrontWest,      InFront,         InFrontEast,
+      InFrontSouthWest, InFrontSouth,    InFrontSouthEast,
+
+      NorthWest,        North,           NorthEast,
+      West},
+//1 - AtRightBorder 
+    { InFrontNorthWest, InFrontNorth,    /* InFrontNorthEast, */
+      InFrontWest,      InFront,         /* InFrontEast, */
+      InFrontSouthWest, InFrontSouth,    /* InFrontSouthEast, */
+
+      NorthWest,        North,           /* NorthEast, */
+      West,
+      Error, Error, Error, Error},
+//2 - AtLeftBorder
+    { /*InFrontNorthWest,*/ InFrontNorth,InFrontNorthEast,
+      /*InFrontWest,*/  InFront,         InFrontEast,
+      /*InFrontSouthWest,*/InFrontSouth, InFrontSouthEast,
+
+      /*NorthWest,*/    North,           NorthEast,
+      /*West*/
+      Error, Error, Error, Error, Error},
+//3 - Nothin'
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//4 - AtTopBorder
+    { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,*/
+      InFrontWest,       InFront,        InFrontEast,
+      InFrontSouthWest,  InFrontSouth,   InFrontSouthEast,
+
+      /*NorthWest,       North,          NorthEast,*/
+      West,
+      Error, Error, Error, Error, Error, Error},
+//5 - AtTopRightBorder
+    { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,*/
+      InFrontWest,       InFront,        /*InFrontEast,*/
+      InFrontSouthWest,  InFrontSouth,   /*InFrontSouthEast,*/
+
+      /*NorthWest, North, NorthEast,*/
+      West,
+      Error, Error, Error, Error, Error, Error, Error, Error},
+//6 - AtTopLeftBorder
+    { /*InFrontNorthWest,InFrontNorth,    InFrontNorthEast,*/
+      /*InFrontWest,*/   InFront,         InFrontEast,
+      /*InFrontSouthWest,*/InFrontSouth,  InFrontSouthEast,
+
+      /*NorthWest,       North,           NorthEast,*/
+      /*West,*/
+      Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//7 - Nothin'
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//8 - AtBottomBorder 
+    { InFrontNorthWest,  InFrontNorth,    InFrontNorthEast,
+      InFrontWest,       InFront,         InFrontEast,
+      /* InFrontSouthWest,  InFrontSouth,    InFrontSouthEast, */
+
+      NorthWest,         North,           NorthEast,
+      West,
+      Error, Error, Error},
+//9 - AtBottomRightBorder 
+    { InFrontNorthWest, InFrontNorth,    /* InFrontNorthEast, */
+      InFrontWest,      InFront,         /* InFrontEast, */
+      /* InFrontSouthWest, InFrontSouth,    InFrontSouthEast, */
+
+      NorthWest,        North,           /* NorthEast, */
+      West,
+      Error, Error, Error,Error, Error, Error},
+//10 - AtBottomLeftBorder
+    { /*InFrontNorthWest,*/InFrontNorth, InFrontNorthEast,
+      /*InFrontWest,*/  InFront,         InFrontEast,
+      /*InFrontSouthWest, InFrontSouth, InFrontSouthEast, */
+
+      /*NorthWest,*/    North,           NorthEast,
+      /*West*/
+      Error, Error, Error, Error, Error, Error, Error},
+//11 - Nothin'
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//12 - Nothin'
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//13 - Nothin'
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//14 - Nothin'
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//15 - Nothin'
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//16 - AtFrontBorder
+    { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
+      InFrontWest,      InFront,         InFrontEast,
+      InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
+
+      NorthWest,        North,           NorthEast,
+      West,
+      Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//17 - AtFrontRightBorder
+    { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
+      InFrontWest,      InFront,         InFrontEast,
+      InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
+
+      NorthWest,        North,           /*NorthEast,*/
+      West,
+      Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//18 - AtFrontLeftBorder
+    { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
+      InFrontWest,      InFront,         InFrontEast,
+      InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
+
+      /*NorthWest,*/    North,           NorthEast,
+      /*West,*/
+      Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//19 - Nothin'
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//20 - AtTopFrontBorder
+    { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
+      InFrontWest,      InFront,         InFrontEast,
+      InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
+
+      /*NorthWest, North, NorthEast,*/
+      West,
+      Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//21 - AtTopRightFrontBorder
+    { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
+      InFrontWest,        InFront,       InFrontEast,
+      InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
+
+      /*NorthWest,        North,         NorthEast,*/
+      West,
+      Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//22 - AtTopLeftFrontBorder
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//23 - Nothin
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//24 - AtBottomFrontBorder
+    { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
+      InFrontWest,        InFront,       InFrontEast,
+      InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
+
+      NorthWest,          North,         NorthEast,
+      West,
+      Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//25 - AtBottomRightFrontBorder
+    { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
+      InFrontWest,        InFront,       InFrontEast,
+      InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
+
+      NorthWest,          North,         /*NorthEast,*/
+      West,
+      Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//26 - AtBottomLeftFrontBorder
+    { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
+      InFrontWest,        InFront,       InFrontEast,
+      InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
+
+      /*NorthWest,*/      North,         NorthEast,
+      /* West, */
+      Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//27 - Nothin
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//28 - Nothin
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//29 - Nothin
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//30 - Nothin
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//31 - Nothin
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//32 - AtRearBorder
+    { InFrontNorthWest,   InFrontNorth,  InFrontNorthEast,
+      InFrontWest,        InFront,       InFrontEast,
+      InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
+
+      NorthWest,          North,         NorthEast,
+      West},
+//33 - AtRearRightBorder
+    { InFrontNorthWest,   InFrontNorth,  InFrontNorthEast,
+      InFrontWest,        InFront,       InFrontEast,
+      InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
+
+      NorthWest,          North,         NorthEast,
+      West},
+//34 - AtRearLeftBorder
+    { /*InFrontNorthWest,*/InFrontNorth, InFrontNorthEast,
+      /*InFrontWest,*/    InFront,       InFrontEast,
+      /*InFrontSouthWest,*/InFrontSouth, InFrontSouthEast,
+
+      /*NorthWest,*/      North,         NorthEast,
+      /*West*/
+      Error, Error, Error, Error, Error},
+//35 - Nothin
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//36 - AtTopRearBorder
+    { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,*/
+      InFrontWest,        InFront,       InFrontEast,
+      InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
+
+      /*NorthWest,        North,         NorthEast,*/
+      West,
+      Error, Error, Error, Error, Error, Error},
+//37 - AtTopRightRearBorder
+    { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,*/
+      InFrontWest,        InFront,       /*InFrontEast,*/
+      InFrontSouthWest,   InFrontSouth,  /*InFrontSouthEast,*/
+
+      /*NorthWest,        North,         NorthEast,*/
+      West,
+      Error, Error, Error, Error, Error, Error, Error, Error},
+//38 - AtTopLeftRearBorder
+    { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,*/
+      /*InFrontWest,*/    InFront,       InFrontEast,
+      /*InFrontSouthWest,*/InFrontSouth, InFrontSouthEast,
+
+      /*NorthWest, North, NorthEast,*/
+      /*West,*/
+      Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//39 - Nothin
+    { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
+//40 - AtBottomRearBorder
+    { InFrontNorthWest,   InFrontNorth,  InFrontNorthEast,
+      InFrontWest,        InFront,       InFrontEast,
+      InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
+
+      NorthWest,          North,         NorthEast,
+      West},
+//41 - AtBottomRightRearBorder
+    { InFrontNorthWest,  InFrontNorth,   InFrontNorthEast,
+      InFrontWest,       InFront,        InFrontEast,
+      InFrontSouthWest,  InFrontSouth,   InFrontSouthEast,
+
+      NorthWest,         North,          NorthEast,
+      West},
+//42 - AtBottomLeftRearBorder
+    { /*InFrontNorthWest,*/InFrontNorth, InFrontNorthEast,
+      /*InFrontWest,*/   InFront,        InFrontEast,
+      /*InFrontSouthWest,InFrontSouth,   InFrontSouthEast,*/
+
+      /*NorthWest,*/     North,          NorthEast,
+      /*West*/
+      Error, Error, Error, Error, Error, Error, Error}
+};
+               
+template <int DUMMY>
+Diff3D NeighborCode3D::StaticData<DUMMY>::d[] = {
+                                Diff3D( -1, -1, -1),  //InFrontNorthWest
+                                Diff3D(  0, -1, -1),  //InFrontNorth
+                                Diff3D(  1, -1, -1),  //InFrontNorthEast
+                                Diff3D( -1,  0, -1),  //InFrontWest
+                                Diff3D(  0,  0, -1),  //InFront
+                                Diff3D(  1,  0, -1),  //InFrontEast
+                                Diff3D( -1,  1, -1),  //InFrontSouthWest
+                                Diff3D(  0,  1, -1),  //InFrontSouth
+                                Diff3D(  1,  1, -1),  //InFrontSouthEast
+
+                                Diff3D( -1, -1,  0),  //NorthWest
+                                Diff3D(  0, -1,  0),  //North
+                                Diff3D(  1, -1,  0),  //NorthEast
+                                Diff3D( -1,  0,  0),  //West
+                                Diff3D(  1,  0,  0),  //East
+                                Diff3D( -1,  1,  0),  //SouthWest
+                                Diff3D(  0,  1,  0),  //South
+                                Diff3D(  1,  1,  0),  //SouthEast
+
+                                Diff3D( -1, -1,  1),  //BehindNorthWest
+                                Diff3D(  0, -1,  1),  //BehindNorth
+                                Diff3D(  1, -1,  1),  //BehindNorthEast
+                                Diff3D( -1,  0,  1),  //BehindWest
+                                Diff3D(  0,  0,  1),  //Behind
+                                Diff3D(  1,  0,  1),  //BehindEast
+                                Diff3D( -1,  1,  1),  //BehindSouthWest
+                                Diff3D(  0,  1,  1),  //BehindSouth
+                                Diff3D(  1,  1,  1),  //BehindSouthEast
+                            };
+        
+}//namespace Neighborhood3DTwentySix
+
+/** Export \ref vigra::Neighborhood3DTwentySix::NeighborCode3D into the scope of namespace vigra.
+ */
+typedef Neighborhood3DTwentySix::NeighborCode3D NeighborCode3DTwentySix;
+
+//@}
+
+} // namespace vigra
+
+#endif /* VIGRA_VOXELNEIGHBORHOOD_HXX */
diff --git a/include/vigra/watersheds.hxx b/include/vigra/watersheds.hxx
new file mode 100644
index 0000000..288ccfb
--- /dev/null
+++ b/include/vigra/watersheds.hxx
@@ -0,0 +1,1498 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2005 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_WATERSHEDS_HXX
+#define VIGRA_WATERSHEDS_HXX
+
+#include <functional>
+#include "mathutil.hxx"
+#include "stdimage.hxx"
+#include "pixelneighborhood.hxx"
+#include "localminmax.hxx"
+#include "labelimage.hxx"
+#include "seededregiongrowing.hxx"
+#include "functorexpression.hxx"
+#include "union_find.hxx"
+#include "multi_shape.hxx"
+
+namespace vigra {
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+unsigned int watershedLabeling(SrcIterator upperlefts,
+                        SrcIterator lowerrights, SrcAccessor sa,
+                        DestIterator upperleftd, DestAccessor da,
+                        Neighborhood)
+{
+    typedef typename DestAccessor::value_type LabelType;
+
+    int w = lowerrights.x - upperlefts.x;
+    int h = lowerrights.y - upperlefts.y;
+    int x,y;
+
+    SrcIterator ys(upperlefts);
+    SrcIterator xs(ys);
+    DestIterator yd(upperleftd);
+    DestIterator xd(yd);
+
+    // temporary image to store region labels
+    detail::UnionFindArray<LabelType> labels;
+
+    // initialize the neighborhood circulators
+    NeighborOffsetCirculator<Neighborhood> ncstart(Neighborhood::CausalFirst);
+    NeighborOffsetCirculator<Neighborhood> ncstartBorder(Neighborhood::North);
+    NeighborOffsetCirculator<Neighborhood> ncend(Neighborhood::CausalLast);
+    ++ncend;
+    NeighborOffsetCirculator<Neighborhood> ncendBorder(Neighborhood::North);
+    ++ncendBorder;
+
+    // pass 1: scan image from upper left to lower right
+    // to find connected components
+
+    // Each component will be represented by a tree of pixels. Each
+    // pixel contains the scan order address of its parent in the
+    // tree.  In order for pass 2 to work correctly, the parent must
+    // always have a smaller scan order address than the child.
+    // Therefore, we can merge trees only at their roots, because the
+    // root of the combined tree must have the smallest scan order
+    // address among all the tree's pixels/ nodes.  The root of each
+    // tree is distinguished by pointing to itself (it contains its
+    // own scan order address). This condition is enforced whenever a
+    // new region is found or two regions are merged
+    da.set(labels.finalizeLabel(labels.nextFreeLabel()), xd);
+
+    ++xs.x;
+    ++xd.x;
+    for(x = 1; x != w; ++x, ++xs.x, ++xd.x)
+    {
+        if((sa(xs) & Neighborhood::directionBit(Neighborhood::West)) ||
+           (sa(xs, Neighborhood::west()) & Neighborhood::directionBit(Neighborhood::East)))
+        {
+            da.set(da(xd, Neighborhood::west()), xd);
+        }
+        else
+        {
+            da.set(labels.finalizeLabel(labels.nextFreeLabel()), xd);
+        }
+    }
+
+    ++ys.y;
+    ++yd.y;
+    for(y = 1; y != h; ++y, ++ys.y, ++yd.y)
+    {
+        xs = ys;
+        xd = yd;
+
+        for(x = 0; x != w; ++x, ++xs.x, ++xd.x)
+        {
+            NeighborOffsetCirculator<Neighborhood> nc(x == w-1
+                                                        ? ncstartBorder
+                                                        : ncstart);
+            NeighborOffsetCirculator<Neighborhood> nce(x == 0
+                                                         ? ncendBorder
+                                                         : ncend);
+            LabelType currentLabel = labels.nextFreeLabel();
+            for(; nc != nce; ++nc)
+            {
+                if((sa(xs) & nc.directionBit()) || (sa(xs, *nc) & nc.oppositeDirectionBit()))
+                {
+                    currentLabel = labels.makeUnion(da(xd,*nc), currentLabel);
+                }
+            }
+            da.set(labels.finalizeLabel(currentLabel), xd);
+        }
+    }
+
+    unsigned int count = labels.makeContiguous();
+
+    // pass 2: assign one label to each region (tree)
+    // so that labels form a consecutive sequence 1, 2, ...
+    yd = upperleftd;
+    for(y=0; y != h; ++y, ++yd.y)
+    {
+        DestIterator xd(yd);
+        for(x = 0; x != w; ++x, ++xd.x)
+        {
+            da.set(labels[da(xd)], xd);
+        }
+    }
+    return count;
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+unsigned int watershedLabeling(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                               pair<DestIterator, DestAccessor> dest,
+                               Neighborhood neighborhood)
+{
+    return watershedLabeling(src.first, src.second, src.third,
+                             dest.first, dest.second, neighborhood);
+}
+
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void prepareWatersheds(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+                      DestIterator upperleftd, DestAccessor da,
+                      FourNeighborCode)
+{
+    int w = lowerrights.x - upperlefts.x;
+    int h = lowerrights.y - upperlefts.y;
+    int x,y;
+
+    SrcIterator ys(upperlefts);
+    SrcIterator xs(ys);
+
+    DestIterator yd = upperleftd;
+
+    for(y = 0; y != h; ++y, ++ys.y, ++yd.y)
+    {
+        xs = ys;
+        DestIterator xd = yd;
+
+        for(x = 0; x != w; ++x, ++xs.x, ++xd.x)
+        {
+            AtImageBorder atBorder = isAtImageBorder(x,y,w,h);
+            typename SrcAccessor::value_type v = sa(xs);
+            // the following choice causes minima to point
+            // to their lowest neighbor -- would this be better???
+            // typename SrcAccessor::value_type v = NumericTraits<typename SrcAccessor::value_type>::max();
+            int o = 0; // means center is minimum
+            if(atBorder == NotAtBorder)
+            {
+                NeighborhoodCirculator<SrcIterator, FourNeighborCode>  c(xs), cend(c);
+                do {
+                    if(sa(c) <= v)
+                    {
+                        v = sa(c);
+                        o = c.directionBit();
+                    }
+                }
+                while(++c != cend);
+            }
+            else
+            {
+                RestrictedNeighborhoodCirculator<SrcIterator, FourNeighborCode>  c(xs, atBorder), cend(c);
+                do {
+                    if(sa(c) <= v)
+                    {
+                        v = sa(c);
+                        o = c.directionBit();
+                    }
+                }
+                while(++c != cend);
+            }
+            da.set(o, xd);
+        }
+    }
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+void prepareWatersheds(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+                      DestIterator upperleftd, DestAccessor da,
+                      EightNeighborCode)
+{
+    int w = lowerrights.x - upperlefts.x;
+    int h = lowerrights.y - upperlefts.y;
+    int x,y;
+
+    SrcIterator ys(upperlefts);
+    SrcIterator xs(ys);
+
+    DestIterator yd = upperleftd;
+
+    for(y = 0; y != h; ++y, ++ys.y, ++yd.y)
+    {
+        xs = ys;
+        DestIterator xd = yd;
+
+        for(x = 0; x != w; ++x, ++xs.x, ++xd.x)
+        {
+            AtImageBorder atBorder = isAtImageBorder(x,y,w,h);
+            typename SrcAccessor::value_type v = sa(xs);
+            // the following choice causes minima to point
+            // to their lowest neighbor -- would this be better???
+            // typename SrcAccessor::value_type v = NumericTraits<typename SrcAccessor::value_type>::max();
+            int o = 0; // means center is minimum
+            if(atBorder == NotAtBorder)
+            {
+                // handle diagonal and principal neighbors separately
+                // so that principal neighbors are preferred when there are
+                // candidates with equal strength
+                NeighborhoodCirculator<SrcIterator, EightNeighborCode>
+                                      c(xs, EightNeighborCode::NorthEast);
+                for(int i = 0; i < 4; ++i, c += 2)
+                {
+                    if(sa(c) <= v)
+                    {
+                        v = sa(c);
+                        o = c.directionBit();
+                    }
+                }
+                --c;
+                for(int i = 0; i < 4; ++i, c += 2)
+                {
+                    if(sa(c) <= v)
+                    {
+                        v = sa(c);
+                        o = c.directionBit();
+                    }
+                }
+            }
+            else
+            {
+                RestrictedNeighborhoodCirculator<SrcIterator, EightNeighborCode>
+                             c(xs, atBorder), cend(c);
+                do
+                {
+                    if(!c.isDiagonal())
+                        continue;
+                    if(sa(c) <= v)
+                    {
+                        v = sa(c);
+                        o = c.directionBit();
+                    }
+                }
+                while(++c != cend);
+                do
+                {
+                    if(c.isDiagonal())
+                        continue;
+                    if(sa(c) <= v)
+                    {
+                        v = sa(c);
+                        o = c.directionBit();
+                    }
+                }
+                while(++c != cend);
+            }
+            da.set(o, xd);
+        }
+    }
+}
+
+/** \addtogroup SeededRegionGrowing Region Segmentation Algorithms
+    Region growing, watersheds, and voronoi tesselation
+*/
+//@{
+
+    /**\brief Options object for generateWatershedSeeds().
+     *
+        <b> Usage:</b>
+
+        <b>\#include</b> \<vigra/watersheds.hxx\><br>
+        Namespace: vigra
+        
+        \code
+        MultiArray<2, float>  boundary_indicator(w, h);
+        MultiArray<2, int>    seeds(boundary_indicator.shape());
+        
+        // detect all minima in 'boundary_indicator' that are below gray level 22
+        generateWatershedSeeds(boundary_indicator, seeds,
+                               SeedOptions().minima().threshold(22.0));
+        \endcode
+     */
+class SeedOptions
+{
+public:
+    enum DetectMinima { LevelSets, Minima, ExtendedMinima, Unspecified };
+    
+    double thresh;
+    DetectMinima mini;
+    
+        /**\brief Construct default options object.
+         *
+            Defaults are: detect minima without thresholding (i.e. all minima).
+         */
+    SeedOptions()
+    : thresh(NumericTraits<double>::max()),
+      mini(Minima)
+    {}
+    
+        /** Generate seeds at minima.
+        
+            Default: true
+         */
+    SeedOptions & minima()
+    {
+        mini = Minima;
+        return *this;
+    }
+    
+        /** Generate seeds at minima and minimal plateaus.
+        
+            Default: false
+         */
+    SeedOptions & extendedMinima()
+    {
+        mini = ExtendedMinima;
+        return *this;
+    }
+    
+        /** Generate seeds as level sets.
+        
+            Note that you must also set a threshold to define which level set is to be used.<br>
+            Default: false
+         */
+    SeedOptions & levelSets()
+    {
+        mini = LevelSets;
+        return *this;
+    }
+    
+        /** Generate seeds as level sets at given threshold.
+        
+            Equivalent to <tt>SeedOptions().levelSet().threshold(threshold)</tt><br>
+            Default: false
+         */
+    SeedOptions & levelSets(double threshold)
+    {
+        mini = LevelSets;
+        thresh = threshold;
+        return *this;
+    }
+    
+        /** Set threshold.
+        
+            The threshold will be used by both the minima and level set variants
+            of seed generation.<br>
+            Default: no thresholding
+         */
+    SeedOptions & threshold(double threshold)
+    {
+        thresh = threshold;
+        return *this;
+    }
+    
+        // check whether the threshold has been set for the target type T
+    template <class T>
+    bool thresholdIsValid() const
+    {
+        return thresh < double(NumericTraits<T>::max());
+    }
+    
+        // indicate that this option object is invalid (for internal use in watersheds)
+    SeedOptions & unspecified()
+    {
+        mini = Unspecified;
+        return *this;
+    }
+};
+
+/** \brief Generate seeds for watershed computation and seeded region growing.
+
+    The source image is a boundary indicator such as the gradient magnitude
+    or the trace of the \ref boundaryTensor(). Seeds are generally generated
+    at locations where the boundaryness (i.e. the likelihood of the point being on the
+    boundary) is very small. In particular, seeds can be placed by either
+    looking for local minima (possibly including minimal plateaus) of the boundaryness,
+    of by looking at level sets (i.e. regions where the boundaryness is below a threshold).
+    Both methods can also be combined, so that only minima below a threshold are returned.
+    The particular seeding strategy is specified by the <tt>options</tt> object 
+    (see \ref SeedOptions).
+    
+    The pixel type of the input image must be <tt>LessThanComparable</tt>.
+    The pixel type of the output image must be large enough to hold the labels for all seeds.
+    (typically, you will use <tt>UInt32</tt>). The function will label seeds by consecutive integers
+    (starting from 1) and returns the largest label it used.
+    
+    Pass \ref vigra::NeighborhoodType "IndirectNeighborhood" or \ref vigra::NeighborhoodType "DirectNeighborhood" 
+    (first form of the function) 
+    or \ref vigra::EightNeighborCode or \ref vigra::FourNeighborCode (second and third forms) to determine the 
+    neighborhood where pixel values are compared. 
+
+    <b> Declarations:</b>
+
+    use arbitrary-dimensional arrays:
+    \code
+    namespace vigra {
+        template <unsigned int N, class T, class S1,
+                                  class Label, class S2>
+        Label
+        generateWatershedSeeds(MultiArrayView<N, T, S1> const & data,
+                               MultiArrayView<N, Label, S2> seeds,
+                               NeighborhoodType neighborhood = IndirectNeighborhood,
+                               SeedOptions const & options = SeedOptions());
+    }
+    \endcode
+
+    \deprecatedAPI{generateWatershedSeeds}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class Neighborhood = EightNeighborCode>
+        unsigned int
+        generateWatershedSeeds(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+                               DestIterator upperleftd, DestAccessor da, 
+                               Neighborhood neighborhood = EightNeighborCode(),
+                               SeedOptions const & options = SeedOptions());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class Neighborhood = EightNeighborCode>
+        unsigned int
+        generateWatershedSeeds(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                               pair<DestIterator, DestAccessor> dest, 
+                               Neighborhood neighborhood = EightNeighborCode(),
+                               SeedOptions const & options = SeedOptions());
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/multi_watersheds.hxx\> (MultiArray variant)<br>
+    <b>\#include</b> \<vigra/watersheds.hxx\> (deprecated variants)<br>
+    Namespace: vigra
+
+    For detailed examples see \ref watershedsMultiArray() and \ref watershedsRegionGrowing().
+*/
+doxygen_overloaded_function(template <...> unsigned int generateWatershedSeeds)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+unsigned int
+generateWatershedSeeds(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+                       DestIterator upperleftd, DestAccessor da, 
+                       Neighborhood neighborhood,
+                       SeedOptions const & options = SeedOptions())
+{
+    using namespace functor;
+    typedef typename SrcAccessor::value_type SrcType;
+    
+    vigra_precondition(options.mini != SeedOptions::LevelSets || 
+                       options.thresholdIsValid<SrcType>(),
+        "generateWatershedSeeds(): SeedOptions.levelSets() must be specified with threshold.");
+    
+    Diff2D shape = lowerrights - upperlefts;
+    BImage seeds(shape);
+    
+    if(options.mini == SeedOptions::LevelSets)
+    {
+        transformImage(srcIterRange(upperlefts, lowerrights, sa),
+                       destImage(seeds),
+                       ifThenElse(Arg1() <= Param(options.thresh), Param(1), Param(0)));
+    }
+    else
+    {
+        LocalMinmaxOptions lm_options;
+        lm_options.neighborhood(Neighborhood::DirectionCount)
+                  .markWith(1.0)
+                  .allowAtBorder()
+                  .allowPlateaus(options.mini == SeedOptions::ExtendedMinima);
+        if(options.thresholdIsValid<SrcType>())
+            lm_options.threshold(options.thresh);
+            
+        localMinima(srcIterRange(upperlefts, lowerrights, sa), destImage(seeds),
+                    lm_options);
+    }
+    
+    return labelImageWithBackground(srcImageRange(seeds), destIter(upperleftd, da), 
+                                    Neighborhood::DirectionCount == 8, 0);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline unsigned int
+generateWatershedSeeds(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+                       DestIterator upperleftd, DestAccessor da, 
+                       SeedOptions const & options = SeedOptions())
+{
+    return generateWatershedSeeds(upperlefts, lowerrights, sa, upperleftd, da, 
+                                   EightNeighborCode(), options);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+inline unsigned int
+generateWatershedSeeds(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                       pair<DestIterator, DestAccessor> dest, 
+                       Neighborhood neighborhood,
+                       SeedOptions const & options = SeedOptions())
+{
+    return generateWatershedSeeds(src.first, src.second, src.third,
+                                   dest.first, dest.second,    
+                                   neighborhood, options);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline unsigned int
+generateWatershedSeeds(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                       pair<DestIterator, DestAccessor> dest, 
+                       SeedOptions const & options = SeedOptions())
+{
+    return generateWatershedSeeds(src.first, src.second, src.third,
+                                   dest.first, dest.second,    
+                                   EightNeighborCode(), options);
+}
+
+/********************************************************/
+/*                                                      */
+/*                 watershedsUnionFind                  */
+/*                                                      */
+/********************************************************/
+
+/** \brief Region segmentation by means of the union-find watershed algorithm.
+
+    Note: This function is largely obsolete, \ref watershedsMultiArray() should be
+    preferred unless top speed is required.
+    
+    This function implements the union-find version of the watershed algorithms
+    described as algorithm 4.7 in
+
+    J. Roerdink, R. Meijster: <em>"The watershed transform: definitions, algorithms,
+    and parallelization strategies"</em>, Fundamenta Informaticae, 41:187-228, 2000
+
+    The source image is a boundary indicator such as the gaussianGradientMagnitude()
+    or the trace of the \ref boundaryTensor(). Local minima of the boundary indicator
+    are used as region seeds, and all other pixels are recursively assigned to the same
+    region as their lowest neighbor. Pass \ref vigra::EightNeighborCode or
+    \ref vigra::FourNeighborCode to determine the neighborhood where pixel values
+    are compared. The pixel type of the input image must be <tt>LessThanComparable</tt>.
+    The function uses accessors.
+
+    Note that VIGRA provides an alternative implementation of the watershed transform via
+    \ref watershedsRegionGrowing(). It is slower, but offers many more configuration options.
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class Neighborhood>
+        unsigned int
+        watershedsUnionFind(MultiArrayView<2, T1, S1> const & src,
+                            MultiArrayView<2, T2, S2> dest, 
+                            Neighborhood neighborhood = EightNeighborCode());
+    }
+    \endcode
+
+    \deprecatedAPI{watershedsUnionFind}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class Neighborhood = EightNeighborCode>
+        unsigned int
+        watershedsUnionFind(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+                            DestIterator upperleftd, DestAccessor da,
+                            Neighborhood neighborhood = EightNeighborCode())
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class Neighborhood = EightNeighborCode>
+        unsigned int
+        watershedsUnionFind(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                            pair<DestIterator, DestAccessor> dest,
+                            Neighborhood neighborhood = EightNeighborCode())
+    }
+    \endcode
+    \deprecatedEnd
+
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/watersheds.hxx\><br>
+    Namespace: vigra
+
+    Example: watersheds of the gradient magnitude.
+
+    \code
+    MultiArray<2, float> in(w,h);
+    ... // read input data
+
+    // compute gradient magnitude as boundary indicator
+    MultiArray<2, float> gradMag(w, h);
+    gaussianGradientMagnitude(src, gradMag, 3.0);
+
+    // the pixel type of the destination image must be large enough to hold
+    // numbers up to 'max_region_label' to prevent overflow
+    MultiArray<2, unsigned int> labeling(w,h);
+    unsigned int max_region_label = watershedsUnionFind(gradMag, labeling);
+    \endcode
+
+    \deprecatedUsage{watershedsUnionFind}
+    Example: watersheds of the gradient magnitude.
+
+    \code
+    vigra::BImage in(w,h);
+    ... // read input data
+
+    // compute gradient magnitude as boundary indicator
+    vigra::FImage gradMag(w, h);
+    gaussianGradientMagnitude(srcImageRange(src), destImage(gradMag), 3.0);
+
+    // the pixel type of the destination image must be large enough to hold
+    // numbers up to 'max_region_label' to prevent overflow
+    vigra::IImage labeling(w,h);
+    int max_region_label = watershedsUnionFind(srcImageRange(gradMag), destImage(labeling));
+
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator src_upperleft, src_lowerright;
+    DestIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    // compare src values
+    src_accessor(src_upperleft) <= src_accessor(src_upperleft)
+
+    // set result
+    int label;
+    dest_accessor.set(label, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> unsigned int watershedsUnionFind)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+unsigned int
+watershedsUnionFind(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+                    DestIterator upperleftd, DestAccessor da, 
+                    Neighborhood neighborhood)
+{
+    SImage orientationImage(lowerrights - upperlefts);
+
+    prepareWatersheds(upperlefts, lowerrights, sa,
+                     orientationImage.upperLeft(), orientationImage.accessor(), neighborhood);
+    return watershedLabeling(orientationImage.upperLeft(), orientationImage.lowerRight(), orientationImage.accessor(),
+                             upperleftd, da, neighborhood);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline unsigned int
+watershedsUnionFind(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+           DestIterator upperleftd, DestAccessor da)
+{
+    return watershedsUnionFind(upperlefts, lowerrights, sa, upperleftd, da, EightNeighborCode());
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+inline unsigned int
+watershedsUnionFind(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    pair<DestIterator, DestAccessor> dest, Neighborhood neighborhood)
+{
+    return watershedsUnionFind(src.first, src.second, src.third, 
+                               dest.first, dest.second, neighborhood);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline unsigned int
+watershedsUnionFind(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                    pair<DestIterator, DestAccessor> dest)
+{
+    return watershedsUnionFind(src.first, src.second, src.third, 
+                               dest.first, dest.second);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class Neighborhood>
+inline unsigned int
+watershedsUnionFind(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest, Neighborhood neighborhood)
+{
+    return watershedsUnionFind(srcImageRange(src), 
+                               destImage(dest), neighborhood);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline unsigned int
+watershedsUnionFind(MultiArrayView<2, T1, S1> const & src,
+                    MultiArrayView<2, T2, S2> dest)
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "watershedsUnionFind(): shape mismatch between input and output.");
+    return watershedsUnionFind(srcImageRange(src), 
+                               destImage(dest));
+}
+
+/** \brief Options object for watershed algorithms.
+
+    <b> Usage:</b>
+
+    see \ref watershedsMultiArray() and watershedsRegionGrowing() for detailed examples.
+*/
+class WatershedOptions
+{
+  public:
+    enum Method { RegionGrowing, UnionFind };
+  
+    double max_cost, bias;
+    SRGType terminate;
+    Method method;
+    unsigned int biased_label, bucket_count;
+    SeedOptions seed_options;
+    
+    
+    
+        /** \brief Create options object with default settings.
+
+            Defaults are: perform complete grow (all pixels are assigned to regions),
+            use standard algorithm, assume that the destination image already contains 
+            region seeds.
+        */
+    WatershedOptions()
+    : max_cost(0.0),
+      bias(1.0),
+      terminate(CompleteGrow),
+      method(RegionGrowing),
+      biased_label(0),
+      bucket_count(0),
+      seed_options(SeedOptions().unspecified())
+    {}    
+    
+        /** \brief Perform complete grow.
+
+            That is, all pixels are assigned to regions, without explicit contours
+            in between.
+            
+            Default: true
+        */
+    WatershedOptions & completeGrow()
+    {
+        terminate = SRGType(CompleteGrow | (terminate & StopAtThreshold));
+        return *this;
+    }
+    
+        /** \brief Keep one-pixel wide contour between regions.
+        
+            Note that this option is unsupported by the turbo algorithm.
+
+            Default: false
+        */
+    WatershedOptions & keepContours()
+    {
+        terminate = SRGType(KeepContours | (terminate & StopAtThreshold));
+        return *this;
+    }
+    
+        /** \brief Set \ref SRGType explicitly.
+        
+            Default: CompleteGrow
+        */
+    WatershedOptions & srgType(SRGType type)
+    {
+        terminate = type;
+        return *this;
+    }
+    
+        /** \brief Stop region growing when the boundaryness exceeds the threshold.
+        
+            This option may be combined with completeGrow() and keepContours().
+        
+            Default: no early stopping
+        */
+    WatershedOptions & stopAtThreshold(double threshold)
+    {
+        terminate = SRGType(terminate | StopAtThreshold);
+        max_cost = threshold;
+        return *this;
+    }
+    
+        /** \brief Use a simpler, but faster region growing algorithm.
+        
+            The algorithm internally uses a \ref BucketQueue to determine
+            the processing order of the pixels. This is only useful,
+            when the input boundary indicator image contains integers
+            in the range <tt>[0, ..., bucket_count-1]</tt>. Since
+            these boundary indicators are typically represented as
+            UInt8 images, the default <tt>bucket_count</tt> is 256.
+        
+            Default: don't use the turbo algorithm
+        */
+    WatershedOptions & turboAlgorithm(unsigned int bucket_count = 256)
+    {
+        this->bucket_count = bucket_count;
+        method = RegionGrowing;
+        return *this;
+    }
+    
+        /** \brief Specify seed options.
+        
+            In this case, watershedsRegionGrowing() assumes that the destination
+            image does not yet contain seeds. It will therefore call 
+            generateWatershedSeeds() and pass on the seed options.
+        
+            Default: don't compute seeds (i.e. assume that destination image already
+            contains seeds).
+        */
+    WatershedOptions & seedOptions(SeedOptions const & s)
+    {
+        seed_options = s;
+        return *this;
+    }
+    
+        /** \brief Bias the cost of the specified region by the given factor.
+        
+            In certain applications, one region (typically the background) should
+            be preferred in region growing. This is most easily achieved
+            by adjusting the assignment cost for that region as <tt>factor*cost</tt>,
+            with a factor slightly below 1.
+        
+            Default: don't bias any region.
+        */
+    WatershedOptions & biasLabel(unsigned int label, double factor)
+    {
+        biased_label = label;
+        bias = factor;
+        return *this;
+    }
+    
+        /** \brief Specify the algorithm to be used.
+        
+            Possible values are <tt>WatershedOptions::RegionGrowing</tt> and
+            <tt>WatershedOptions::UnionFind</tt>. The latter algorithm is fastest
+            but doesn't support seeds and any of the other options.
+        
+            Default: RegionGrowing.
+        */
+    WatershedOptions & useMethod(Method method)
+    {
+        this->method = method;
+        return *this;
+    }
+    
+        /** \brief Use region-growing watershed.
+        
+            Use this method when you want to specify seeds explicitly (seeded watersheds) 
+            or use any of the other options.
+        
+            Default: true.
+        */
+    WatershedOptions & regionGrowing()
+    {
+        method = RegionGrowing;
+        return *this;
+    }
+    
+        /** \brief Use union-find watershed.
+        
+            This is the fasted method, but it doesn't support seeds and any of the other 
+            options (they will be silently ignored).
+        
+            Default: false.
+        */
+    WatershedOptions & unionFind()
+    {
+        method = UnionFind;
+        return *this;
+    }
+};
+
+namespace detail {
+
+template <class CostType, class LabelType>
+class WatershedStatistics
+{
+  public:
+  
+    typedef SeedRgDirectValueFunctor<CostType> value_type;
+    typedef value_type & reference;
+    typedef value_type const & const_reference;
+    
+    typedef CostType  first_argument_type;
+    typedef LabelType second_argument_type;
+    typedef LabelType argument_type;
+    
+    WatershedStatistics()
+    {}
+
+    void resize(unsigned int)
+    {}
+
+    void reset()
+    {}
+
+        /** update regions statistics (do nothing in the watershed algorithm)
+        */
+    template <class T1, class T2>
+    void operator()(first_argument_type const &, second_argument_type const &) 
+    {}
+
+        /** ask for maximal index (label) allowed
+        */
+    LabelType maxRegionLabel() const
+        { return size() - 1; }
+
+        /** ask for array size (i.e. maxRegionLabel() + 1)
+        */
+    LabelType size() const
+        { return NumericTraits<LabelType>::max(); }
+
+        /** read the statistics functor for a region via its label
+        */
+    const_reference operator[](argument_type label) const
+        { return stats; }
+
+        /** access the statistics functor for a region via its label
+        */
+    reference operator[](argument_type label)
+        { return stats; }
+
+    value_type stats;
+};
+
+template <class Value>
+class SeedRgBiasedValueFunctor
+{
+  public:
+    double bias;
+
+        /* the functor's argument type
+        */
+    typedef Value argument_type;
+
+        /* the functor's result type (unused, only necessary for
+            use of SeedRgDirectValueFunctor in \ref vigra::ArrayOfRegionStatistics
+        */
+    typedef Value result_type;
+
+        /* the return type of the cost() function
+        */
+    typedef Value cost_type;
+    
+    SeedRgBiasedValueFunctor(double b = 1.0)
+    : bias(b)
+    {}
+
+        /* Do nothing (since we need not update region statistics).
+        */
+    void operator()(argument_type const &) const {}
+
+        /* Return scaled argument
+        */
+    cost_type cost(argument_type const & v) const
+    {
+        return cost_type(bias*v);
+    }
+};
+
+template <class CostType, class LabelType>
+class BiasedWatershedStatistics
+{
+  public:
+  
+    typedef SeedRgBiasedValueFunctor<CostType> value_type;
+    typedef value_type & reference;
+    typedef value_type const & const_reference;
+    
+    typedef CostType  first_argument_type;
+    typedef LabelType second_argument_type;
+    typedef LabelType argument_type;
+    
+    BiasedWatershedStatistics(LabelType biasedLabel, double bias)
+    : biased_label(biasedLabel),
+      biased_stats(bias)
+    {}
+
+    void resize(unsigned int)
+    {}
+
+    void reset()
+    {}
+
+        /** update regions statistics (do nothing in the watershed algorithm)
+        */
+    template <class T1, class T2>
+    void operator()(first_argument_type const &, second_argument_type const &) 
+    {}
+
+        /** ask for maximal index (label) allowed
+        */
+    LabelType maxRegionLabel() const
+        { return size() - 1; }
+
+        /** ask for array size (i.e. maxRegionLabel() + 1)
+        */
+    LabelType size() const
+        { return NumericTraits<LabelType>::max(); }
+
+        /** read the statistics functor for a region via its label
+        */
+    const_reference operator[](argument_type label) const
+    { 
+        return (label == biased_label)
+                    ? biased_stats
+                    : stats; 
+    }
+
+        /** access the statistics functor for a region via its label
+        */
+    reference operator[](argument_type label)
+    { 
+        return (label == biased_label)
+                    ? biased_stats
+                    : stats; 
+    }
+
+    LabelType biased_label;
+    value_type stats, biased_stats;
+};
+
+} // namespace detail
+
+/** \brief Region segmentation by means of a flooding-based watershed algorithm.
+
+    Note: This function is largely obsolete, \ref watershedsMultiArray() should be
+    preferred unless top speed is required.
+    
+    This function implements variants of the watershed algorithm
+    described in
+
+    L. Vincent and P. Soille: <em>"Watersheds in digital spaces: An efficient algorithm
+    based on immersion simulations"</em>, IEEE Trans. Patt. Analysis Mach. Intell. 13(6):583-598, 1991
+
+    The source image is a boundary indicator such as the gaussianGradientMagnitude()
+    or the trace of the \ref boundaryTensor(), and the destination is a label image
+    designating membership of each point in one of the regions. Plateaus in the boundary
+    indicator (i.e. regions of constant gray value) are handled via a Euclidean distance
+    transform by default.
+    
+    By default, the destination image is assumed to hold seeds for a seeded watershed 
+    transform. Seeds may, for example, be created by means of generateWatershedSeeds(). 
+    Note that the seeds will be overridden with the final watershed segmentation.
+    
+    Alternatively, you may provide \ref SeedOptions in order to instruct 
+    watershedsRegionGrowing() to generate its own seeds (it will call generateWatershedSeeds()
+    internally). In that case, the destination image should be zero-initialized.
+    
+    You can specify the neighborhood system to be used by passing \ref FourNeighborCode 
+    or \ref EightNeighborCode (default).
+    
+    Further options to be specified via \ref WatershedOptions are:
+    
+    <ul>
+    <li> Whether to keep a 1-pixel-wide contour (with label 0) between regions or 
+         perform complete grow (i.e. all pixels are assigned to a region).
+    <li> Whether to stop growing when the boundaryness exceeds a threshold (remaining
+         pixels keep label 0).
+    <li> Whether to use a faster, but less powerful algorithm ("turbo algorithm"). It
+         is faster because it orders pixels by means of a \ref BucketQueue (therefore,
+         the boundary indicator must contain integers in the range 
+         <tt>[0, ..., bucket_count-1]</tt>, where <tt>bucket_count</tt> is specified in
+         the options object), it only supports complete growing (no contour between regions
+         is possible), and it handles plateaus in a simplistic way. It also saves some
+         memory because it allocates less temporary storage.
+    <li> Whether one region (label) is to be preferred or discouraged by biasing its cost 
+         with a given factor (smaller than 1 for preference, larger than 1 for discouragement).
+    </ul>
+
+    Note that VIGRA provides an alternative implementation of the watershed transform via
+    \ref watershedsUnionFind(). 
+
+    <b> Declarations:</b>
+
+    pass 2D array views:
+    \code
+    namespace vigra {
+        template <class T1, class S1,
+                  class T2, class S2,
+                  class Neighborhood = EightNeighborCode>
+        unsigned int
+        watershedsRegionGrowing(MultiArrayView<2, T1, S1> const & src,
+                                MultiArrayView<2, T2, S2> dest, 
+                                Neighborhood neighborhood = EightNeighborCode(),
+                                WatershedOptions const & options = WatershedOptions());
+
+        template <class T1, class S1,
+                  class T2, class S2>
+        unsigned int
+        watershedsRegionGrowing(MultiArrayView<2, T1, S1> const & src,
+                                MultiArrayView<2, T2, S2> dest, 
+                                WatershedOptions const & options = WatershedOptions());
+    }
+    \endcode
+
+    \deprecatedAPI{watershedsRegionGrowing}
+    pass \ref ImageIterators and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class Neighborhood = EightNeighborCode>
+        unsigned int
+        watershedsRegionGrowing(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+                                DestIterator upperleftd, DestAccessor da, 
+                                Neighborhood neighborhood = EightNeighborCode(),
+                                WatershedOptions const & options = WatershedOptions());
+
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        unsigned int
+        watershedsRegionGrowing(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+                                DestIterator upperleftd, DestAccessor da, 
+                                WatershedOptions const & options = WatershedOptions());
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor,
+                  class Neighborhood = EightNeighborCode>
+        unsigned int
+        watershedsRegionGrowing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                pair<DestIterator, DestAccessor> dest, 
+                                Neighborhood neighborhood = EightNeighborCode(),
+                                WatershedOptions const & options = WatershedOptions());
+                                
+        template <class SrcIterator, class SrcAccessor,
+                  class DestIterator, class DestAccessor>
+        unsigned int
+        watershedsRegionGrowing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                                pair<DestIterator, DestAccessor> dest, 
+                                WatershedOptions const & options = WatershedOptions());
+    }
+    \endcode
+    \deprecatedEnd
+    
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/watersheds.hxx\><br>
+    Namespace: vigra
+
+    Example: watersheds of the gradient magnitude.
+
+    \code
+    MultiArray<2, float> src(w, h);
+    ... // read input data
+    
+    // compute gradient magnitude at scale 1.0 as a boundary indicator
+    MultiArray<2, float> gradMag(w, h);
+    gaussianGradientMagnitude(src, gradMag, 1.0);
+
+    // example 1
+    {
+        // the pixel type of the destination image must be large enough to hold
+        // numbers up to 'max_region_label' to prevent overflow
+        MultiArray<2, unsigned int> labeling(w, h);
+        
+        // call watershed algorithm for 4-neighborhood, leave a 1-pixel boundary between regions,
+        // and autogenerate seeds from all gradient minima where the magnitude is below 2.0
+        unsigned int max_region_label = 
+              watershedsRegionGrowing(gradMag, labeling,
+                                      FourNeighborCode(),
+                                      WatershedOptions().keepContours()
+                                           .seedOptions(SeedOptions().minima().threshold(2.0)));
+    }
+    
+    // example 2
+    {
+        MultiArray<2, unsigned int> labeling(w, h);
+        
+        // compute seeds beforehand (use connected components of all pixels 
+        // where the gradient  is below 4.0)
+        unsigned int max_region_label = 
+              generateWatershedSeeds(gradMag, labeling,
+                                     SeedOptions().levelSets(4.0));
+        
+        // quantize the gradient image to 256 gray levels
+        MultiArray<2, unsigned char> gradMag256(w, h);
+        FindMinMax<float> minmax; 
+        inspectImage(gradMag, minmax); // find original range
+        transformImage(gradMag, gradMag256,
+                       linearRangeMapping(minmax, 0, 255));
+        
+        // call the turbo algorithm with 256 bins, using 8-neighborhood
+        watershedsRegionGrowing(gradMag256, labeling,
+                                WatershedOptions().turboAlgorithm(256));
+    }
+    
+    // example 3
+    {
+       MultiArray<2, unsigned int> labeling(w, h);
+        
+        .. // get seeds from somewhere, e.g. an interactive labeling program,
+           // make sure that label 1 corresponds to the background
+        
+        // bias the watershed algorithm so that the background is preferred
+        // by reducing the cost for label 1 to 90%
+        watershedsRegionGrowing(gradMag, labeling,
+                                WatershedOptions().biasLabel(1, 0.9));
+    }
+    \endcode
+
+    \deprecatedUsage{watershedsRegionGrowing}
+    \code
+    vigra::BImage src(w, h);
+    ... // read input data
+    
+    // compute gradient magnitude at scale 1.0 as a boundary indicator
+    vigra::FImage gradMag(w, h);
+    gaussianGradientMagnitude(srcImageRange(src), destImage(gradMag), 1.0);
+
+    // example 1
+    {
+        // the pixel type of the destination image must be large enough to hold
+        // numbers up to 'max_region_label' to prevent overflow
+        vigra::IImage labeling(w, h);
+        
+        // call watershed algorithm for 4-neighborhood, leave a 1-pixel boundary between regions,
+        // and autogenerate seeds from all gradient minima where the magnitude is below 2.0
+        unsigned int max_region_label = 
+              watershedsRegionGrowing(srcImageRange(gradMag), destImage(labeling),
+                                      FourNeighborCode(),
+                                      WatershedOptions().keepContours()
+                                           .seedOptions(SeedOptions().minima().threshold(2.0)));
+    }
+    
+    // example 2
+    {
+        vigra::IImage labeling(w, h);
+        
+        // compute seeds beforehand (use connected components of all pixels 
+        // where the gradient  is below 4.0)
+        unsigned int max_region_label = 
+              generateWatershedSeeds(srcImageRange(gradMag), destImage(labeling),
+                                     SeedOptions().levelSets(4.0));
+        
+        // quantize the gradient image to 256 gray levels
+        vigra::BImage gradMag256(w, h);
+        vigra::FindMinMax<float> minmax; 
+        inspectImage(srcImageRange(gradMag), minmax); // find original range
+        transformImage(srcImageRange(gradMag), destImage(gradMag256),
+                       linearRangeMapping(minmax, 0, 255));
+        
+        // call the turbo algorithm with 256 bins, using 8-neighborhood
+        watershedsRegionGrowing(srcImageRange(gradMag256), destImage(labeling),
+                                WatershedOptions().turboAlgorithm(256));
+    }
+    
+    // example 3
+    {
+        vigra::IImage labeling(w, h);
+        
+        .. // get seeds from somewhere, e.g. an interactive labeling program,
+           // make sure that label 1 corresponds to the background
+        
+        // bias the watershed algorithm so that the background is preferred
+        // by reducing the cost for label 1 to 90%
+        watershedsRegionGrowing(srcImageRange(gradMag), destImage(labeling),
+                                WatershedOptions().biasLabel(1, 0.9));
+    }
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator src_upperleft, src_lowerright;
+    DestIterator dest_upperleft;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+
+    // compare src values
+    src_accessor(src_upperleft) <= src_accessor(src_upperleft)
+
+    // set result
+    int label;
+    dest_accessor.set(label, dest_upperleft);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> unsigned int watershedsRegionGrowing)
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+unsigned int
+watershedsRegionGrowing(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+                        DestIterator upperleftd, DestAccessor da, 
+                        Neighborhood neighborhood,
+                        WatershedOptions const & options = WatershedOptions())
+{
+    typedef typename SrcAccessor::value_type ValueType; 
+    typedef typename DestAccessor::value_type LabelType; 
+    
+    unsigned int max_region_label = 0;
+    
+    if(options.seed_options.mini != SeedOptions::Unspecified)
+    {
+        // we are supposed to compute seeds
+        max_region_label = 
+            generateWatershedSeeds(srcIterRange(upperlefts, lowerrights, sa), 
+                                   destIter(upperleftd, da),
+                                   neighborhood, options.seed_options);
+    }
+    
+    if(options.biased_label != 0)
+    {
+        // create a statistics functor for biased region growing
+        detail::BiasedWatershedStatistics<ValueType, LabelType> 
+                                 regionstats(options.biased_label, options.bias);
+
+        // perform region growing, starting from the seeds computed above
+        if(options.bucket_count == 0)
+        {
+            max_region_label = 
+            seededRegionGrowing(srcIterRange(upperlefts, lowerrights, sa),
+                                srcIter(upperleftd, da),
+                                destIter(upperleftd, da), 
+                                regionstats, options.terminate, neighborhood, options.max_cost);
+        }
+        else
+        {
+            max_region_label = 
+            fastSeededRegionGrowing(srcIterRange(upperlefts, lowerrights, sa),
+                                    destIter(upperleftd, da), 
+                                    regionstats, options.terminate, 
+                                    neighborhood, options.max_cost, options.bucket_count);
+        }
+    }
+    else
+    {
+        // create a statistics functor for region growing
+        detail::WatershedStatistics<ValueType, LabelType> regionstats;
+
+        // perform region growing, starting from the seeds computed above
+        if(options.bucket_count == 0)
+        {
+            max_region_label = 
+            seededRegionGrowing(srcIterRange(upperlefts, lowerrights, sa),
+                                srcIter(upperleftd, da),
+                                destIter(upperleftd, da), 
+                                regionstats, options.terminate, neighborhood, options.max_cost);
+        }
+        else
+        {
+            max_region_label = 
+            fastSeededRegionGrowing(srcIterRange(upperlefts, lowerrights, sa),
+                                    destIter(upperleftd, da), 
+                                    regionstats, options.terminate, 
+                                    neighborhood, options.max_cost, options.bucket_count);
+        }
+    }
+    
+    return max_region_label;
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline unsigned int
+watershedsRegionGrowing(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
+                        DestIterator upperleftd, DestAccessor da, 
+                        WatershedOptions const & options = WatershedOptions())
+{
+    return watershedsRegionGrowing(upperlefts, lowerrights, sa, upperleftd,  da,
+                                   EightNeighborCode(), options);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor,
+          class Neighborhood>
+inline unsigned int
+watershedsRegionGrowing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        pair<DestIterator, DestAccessor> dest, 
+                        Neighborhood neighborhood,
+                        WatershedOptions const & options = WatershedOptions())
+{
+    return watershedsRegionGrowing(src.first, src.second, src.third,
+                                   dest.first, dest.second,    
+                                   neighborhood, options);
+}
+
+template <class SrcIterator, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline unsigned int
+watershedsRegionGrowing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
+                        pair<DestIterator, DestAccessor> dest, 
+                        WatershedOptions const & options = WatershedOptions())
+{
+    return watershedsRegionGrowing(src.first, src.second, src.third,
+                                   dest.first, dest.second,    
+                                   EightNeighborCode(), options);
+}
+
+template <class T1, class S1,
+          class T2, class S2,
+          class Neighborhood>
+inline unsigned int
+watershedsRegionGrowing(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, T2, S2> dest, 
+                        Neighborhood neighborhood,
+                        WatershedOptions const & options = WatershedOptions())
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "watershedsRegionGrowing(): shape mismatch between input and output.");
+    return watershedsRegionGrowing(srcImageRange(src),
+                                   destImage(dest),    
+                                   neighborhood, options);
+}
+
+template <class T1, class S1,
+          class T2, class S2>
+inline unsigned int
+watershedsRegionGrowing(MultiArrayView<2, T1, S1> const & src,
+                        MultiArrayView<2, T2, S2> dest, 
+                        WatershedOptions const & options = WatershedOptions())
+{
+    vigra_precondition(src.shape() == dest.shape(),
+        "watershedsRegionGrowing(): shape mismatch between input and output.");
+    return watershedsRegionGrowing(srcImageRange(src),
+                                   destImage(dest),    
+                                   EightNeighborCode(), options);
+}
+
+//@}
+
+} // namespace vigra
+
+#endif // VIGRA_WATERSHEDS_HXX
diff --git a/include/vigra/watersheds3d.hxx b/include/vigra/watersheds3d.hxx
new file mode 100644
index 0000000..0ef3258
--- /dev/null
+++ b/include/vigra/watersheds3d.hxx
@@ -0,0 +1,460 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2006-2007 by F. Heinrich, B. Seppke, Ullrich Koethe    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_watersheds3D_HXX
+#define VIGRA_watersheds3D_HXX
+
+#include "voxelneighborhood.hxx"
+#include "multi_array.hxx"
+#include "multi_localminmax.hxx"
+#include "labelvolume.hxx"
+#include "seededregiongrowing3d.hxx"
+#include "watersheds.hxx"
+
+namespace vigra
+{
+
+template <class SrcIterator, class SrcAccessor, class SrcShape,
+          class DestIterator, class DestAccessor, class Neighborhood3D>
+int preparewatersheds3D( SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                         DestIterator d_Iter, DestAccessor da, Neighborhood3D)
+{
+    //basically needed for iteration and border-checks
+    int w = srcShape[0], h = srcShape[1], d = srcShape[2];
+    int x,y,z, local_min_count=0;
+        
+    //declare and define Iterators for all three dims at src
+    SrcIterator zs = s_Iter;
+    SrcIterator ys(zs);
+    SrcIterator xs(ys);
+        
+    //Declare Iterators for all three dims at dest
+    DestIterator zd = d_Iter;
+        
+    for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
+    {
+        ys = zs;
+        DestIterator yd(zd);
+        
+        for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
+        {
+            xs = ys;
+            DestIterator xd(yd);
+
+            for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
+            {
+                AtVolumeBorder atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+                typename SrcAccessor::value_type v = sa(xs);
+                // the following choice causes minima to point
+                // to their lowest neighbor -- would this be better???
+                // typename SrcAccessor::value_type v = NumericTraits<typename SrcAccessor::value_type>::max();
+                int o = 0; // means center is minimum
+                typename SrcAccessor::value_type my_v = v;
+                if(atBorder == NotAtBorder)
+                {
+                    NeighborhoodCirculator<SrcIterator, Neighborhood3D>  c(xs), cend(c);
+                    
+                    do {
+                        if(sa(c) < v)
+                        {  
+                            v = sa(c);
+                            o = c.directionBit();
+                        }
+                        else if(sa(c) == my_v && my_v == v)
+                        {
+                            o =  o | c.directionBit();
+                        }
+                    }
+                    while(++c != cend);
+                }
+                else
+                {
+                    RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood3D>  c(xs, atBorder), cend(c);
+                    do {
+                        if(sa(c) < v)
+                        {  
+                            v = sa(c);
+                            o = c.directionBit();
+                        }
+                        else if(sa(c) == my_v && my_v == v)
+                        {
+                            o =  o | c.directionBit();
+                        }
+                    }
+                    while(++c != cend);
+                }
+                if (o==0) local_min_count++; 
+                da.set(o, xd);
+            }//end x-iteration
+        }//end y-iteration
+    }//end z-iteration
+    return local_min_count;
+}
+
+template <class SrcIterator, class SrcAccessor,class SrcShape,
+          class DestIterator, class DestAccessor,
+          class Neighborhood3D>
+unsigned int watershedLabeling3D( SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                                  DestIterator d_Iter, DestAccessor da,
+                                  Neighborhood3D)
+{
+    typedef typename DestAccessor::value_type LabelType;
+    
+    //basically needed for iteration and border-checks
+    int w = srcShape[0], h = srcShape[1], d = srcShape[2];
+    int x,y,z;
+        
+    //declare and define Iterators for all three dims at src
+    SrcIterator zs = s_Iter;
+    DestIterator zd = d_Iter;
+        
+    // temporary image to store region labels
+    detail::UnionFindArray<LabelType> labels;
+    
+    // initialize the neighborhood traversers
+    NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
+    NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
+    ++nce;
+    // pass 1: scan image from upper left front to lower right back
+    // to find connected components
+
+    // Each component will be represented by a tree of pixels. Each
+    // pixel contains the scan order address of its parent in the
+    // tree.  In order for pass 2 to work correctly, the parent must
+    // always have a smaller scan order address than the child.
+    // Therefore, we can merge trees only at their roots, because the
+    // root of the combined tree must have the smallest scan order
+    // address among all the tree's pixels/ nodes.  The root of each
+    // tree is distinguished by pointing to itself (it contains its
+    // own scan order address). This condition is enforced whenever a
+    // new region is found or two regions are merged
+    for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
+    {
+        SrcIterator ys = zs;
+        DestIterator yd = zd;
+
+        for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
+        {
+            SrcIterator xs = ys;
+            DestIterator xd = yd;
+
+            for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
+            {
+                LabelType currentLabel = labels.nextFreeLabel(); // default: new region    
+
+                //check whether there is a special border treatment to be used or not
+                AtVolumeBorder atBorder = isAtVolumeBorderCausal(x,y,z,w,h,d);
+                    
+                //We are not at the border!
+                if(atBorder == NotAtBorder)
+                {
+
+                    nc = NeighborOffsetCirculator<Neighborhood3D>(Neighborhood3D::CausalFirst);
+                
+                    do
+                    {            
+                        //   Direction of NTraversr       Neighbor's direction bit is pointing
+                        // = Direction of voxel           towards us?
+                        if((sa(xs) & nc.directionBit()) || (sa(xs,*nc) & nc.oppositeDirectionBit()))
+                        {
+                            currentLabel = labels.makeUnion(da(xd,*nc), currentLabel);
+                        }
+                        ++nc;
+                    }while(nc!=nce);
+                }
+                //we are at a border - handle this!!
+                else
+                {
+                    nc = NeighborOffsetCirculator<Neighborhood3D>(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
+                    int j=0;
+                    while(nc.direction() != Neighborhood3D::Error)
+                    {
+                        //   Direction of NTraversr       Neighbor's direction bit is pointing
+                        // = Direction of voxel           towards us?
+                        if((sa(xs) & nc.directionBit()) || (sa(xs,*nc) & nc.oppositeDirectionBit()))
+                        {
+                            currentLabel = labels.makeUnion(da(xd,*nc), currentLabel);
+                        }
+                        nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
+                    }
+                }
+                da.set(labels.finalizeLabel(currentLabel), xd);
+            }
+        }
+    }
+
+    unsigned int count = labels.makeContiguous();
+    
+    // pass 2: assign one label to each region (tree)
+    // so that labels form a consecutive sequence 1, 2, ...
+    zd = d_Iter;
+    for(z=0; z != d; ++z, ++zd.dim2())
+    {
+        DestIterator yd(zd);
+
+        for(y=0; y != h; ++y, ++yd.dim1())
+        {
+            DestIterator xd(yd);
+
+            for(x = 0; x != w; ++x, ++xd.dim0())
+            {
+                da.set(labels[da(xd)], xd);
+            }
+        }
+    }
+    return count;
+}
+
+
+/** \addtogroup SeededRegionGrowing
+*/
+//@{
+
+/********************************************************/
+/*                                                      */
+/*                     watersheds3D                     */
+/*                                                      */
+/********************************************************/
+
+/** \brief Region Segmentation by means of the watershed algorithm.
+
+    This function is deprecated, use \ref watershedsMultiArray() instead.
+    
+    <b> Declarations:</b>
+
+    \deprecatedAPI{watersheds3D}
+    pass \ref MultiIteratorPage "MultiIterators" and \ref DataAccessors :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                  class DestIterator, class DestAccessor,
+                  class Neighborhood3D>
+        unsigned int watersheds3D(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                                  DestIterator d_Iter, DestAccessor da,
+                                  Neighborhood3D neighborhood3D);
+    }
+    \endcode
+    use argument objects in conjunction with \ref ArgumentObjectFactories :
+    \code
+    namespace vigra {
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                  class DestIterator, class DestAccessor,
+                  class Neighborhood3D>
+        unsigned int watersheds3D(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                                  pair<DestIterator, DestAccessor> dest,
+                                  Neighborhood3D neighborhood3D);
+    }
+    \endcode
+
+    use with 3D-Six-Neighborhood:
+    \code
+    namespace vigra {    
+    
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                  class DestIterator, class DestAccessor>
+        unsigned int watersheds3DSix(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                                     pair<DestIterator, DestAccessor> dest);
+                                    
+    }
+    \endcode
+
+    use with 3D-TwentySix-Neighborhood:
+    \code
+    namespace vigra {    
+    
+        template <class SrcIterator, class SrcAccessor,class SrcShape,
+                  class DestIterator, class DestAccessor>
+        unsigned int watersheds3DTwentySix(triple<SrcIterator, SrcShape, SrcAccessor> src,
+                                           pair<DestIterator, DestAccessor> dest);
+                                    
+    }
+    \endcode
+    \deprecatedEnd
+    
+    This function implements the union-find version of the watershed algorithms
+    as described in
+
+    J. Roerdink, R. Meijster: <em>"The watershed transform: definitions, algorithms,
+    and parallelization strategies"</em>, Fundamenta Informaticae, 41:187-228, 2000
+
+    The source volume is a boundary indicator such as the gradient magnitude
+    of the trace of the \ref boundaryTensor(). Local minima of the boundary indicator
+    are used as region seeds, and all other voxels are recursively assigned to the same 
+    region as their lowest neighbor. Pass \ref vigra::NeighborCode3DSix or 
+    \ref vigra::NeighborCode3DTwentySix to determine the neighborhood where voxel values 
+    are compared. The voxel type of the input volume must be <tt>LessThanComparable</tt>.
+    
+    <b> Usage:</b>
+
+    <b>\#include</b> \<vigra/watersheds3D.hxx\><br>
+    Namespace: vigra
+
+    Example: watersheds3D of the gradient magnitude.
+
+    \code
+    Shape3 shape(w, h, d);
+    
+    MultiArray<3, float> src(shape), grad(shape);
+    ...
+    
+    double scale = 1;
+    gaussianGradientMagnitude(src, grad, scale);
+    
+    MultiArray<3, int> labels(shape);
+    
+    // find 6-connected regions
+    int max_region_label = watersheds3DSix(grad, labels);
+
+    // find 26-connected regions
+    max_region_label = watersheds3DTwentySix(grad, labels);
+    \endcode
+
+    \deprecatedUsage{watersheds3D}
+    \code
+    typedef vigra::MultiArray<3,int> IntVolume;
+    typedef vigra::MultiArray<3,double> DVolume;
+    DVolume src(DVolume::difference_type(w,h,d));
+    IntVolume dest(IntVolume::difference_type(w,h,d));
+
+    float gauss=1;
+
+    vigra::MultiArray<3, vigra::TinyVector<float,3> > temp(IntVolume::difference_type(w,h,d));
+    vigra::gaussianGradientMultiArray(srcMultiArrayRange(vol),destMultiArray(temp),gauss);
+
+    IntVolume::iterator temp_iter=temp.begin();
+    for(DVolume::iterator iter=src.begin(); iter!=src.end(); ++iter, ++temp_iter)
+        *iter = norm(*temp_iter);
+    
+    // find 6-connected regions
+    int max_region_label = vigra::watersheds3DSix(srcMultiArrayRange(src), destMultiArray(dest));
+
+    // find 26-connected regions
+    max_region_label = vigra::watersheds3DTwentySix(srcMultiArrayRange(src), destMultiArray(dest));
+    
+    \endcode
+    <b> Required Interface:</b>
+    \code
+    SrcIterator src_begin;
+    SrcShape src_shape;
+    DestIterator dest_begin;
+
+    SrcAccessor src_accessor;
+    DestAccessor dest_accessor;
+    
+    // compare src values
+    src_accessor(src_begin) <= src_accessor(src_begin)
+
+    // set result
+    int label;
+    dest_accessor.set(label, dest_begin);
+    \endcode
+    \deprecatedEnd
+*/
+doxygen_overloaded_function(template <...> unsigned int watersheds3D)
+
+template <class SrcIterator, class SrcAccessor, class SrcShape,
+          class DestIterator, class DestAccessor,
+          class Neighborhood3D>
+unsigned int watersheds3D( SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
+                           DestIterator d_Iter, DestAccessor da, Neighborhood3D neighborhood3D)
+{
+    //create temporary volume to store the DAG of directions to minima
+    if ((int)Neighborhood3D::DirectionCount>7){  //If we have 3D-TwentySix Neighborhood
+        
+        vigra::MultiArray<3,int> orientationVolume(srcShape);
+
+        preparewatersheds3D( s_Iter, srcShape, sa, 
+                             destMultiArray(orientationVolume).first, destMultiArray(orientationVolume).second,
+                             neighborhood3D);
+     
+        return watershedLabeling3D( srcMultiArray(orientationVolume).first, srcShape, srcMultiArray(orientationVolume).second,
+                                    d_Iter, da,
+                                    neighborhood3D);
+    }
+    else{
+                
+        vigra::MultiArray<3,unsigned char> orientationVolume(srcShape);
+
+        preparewatersheds3D( s_Iter, srcShape, sa, 
+                              destMultiArray(orientationVolume).first, destMultiArray(orientationVolume).second,
+                              neighborhood3D);
+     
+        return watershedLabeling3D( srcMultiArray(orientationVolume).first, srcShape, srcMultiArray(orientationVolume).second,
+                                    d_Iter, da,
+                                    neighborhood3D);
+    }
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline unsigned int watersheds3DSix( triple<SrcIterator, SrcShape, SrcAccessor> src, 
+                                     pair<DestIterator, DestAccessor> dest)
+{
+    return watersheds3D(src.first, src.second, src.third, dest.first, dest.second, NeighborCode3DSix());
+}
+
+template <class SrcIterator, class SrcShape, class SrcAccessor,
+          class DestIterator, class DestAccessor>
+inline unsigned int watersheds3DTwentySix( triple<SrcIterator, SrcShape, SrcAccessor> src, 
+                                           pair<DestIterator, DestAccessor> dest)
+{
+    return watersheds3D(src.first, src.second, src.third, dest.first, dest.second, NeighborCode3DTwentySix());
+}
+
+template <unsigned int N, class T1, class S1,
+                          class T2, class S2>
+inline unsigned int 
+watersheds3DSix(MultiArrayView<N, T1, S1> const & source, 
+                MultiArrayView<N, T2, S2> dest)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "watersheds3DSix(): shape mismatch between input and output.");
+    return watersheds3DSix(srcMultiArrayRange(source), destMultiArray(dest));
+}
+
+template <unsigned int N, class T1, class S1,
+          class T2, class S2>
+inline unsigned int
+watersheds3DTwentySix(MultiArrayView<N, T1, S1> const & source, 
+                      MultiArrayView<N, T2, S2> dest)
+{
+    vigra_precondition(source.shape() == dest.shape(),
+        "watersheds3DTwentySix(): shape mismatch between input and output.");
+    return watersheds3DTwentySix(srcMultiArrayRange(source), destMultiArray(dest));
+}
+
+}//namespace vigra
+
+#endif //VIGRA_watersheds3D_HXX
diff --git a/include/vigra/wigner-matrix.hxx b/include/vigra/wigner-matrix.hxx
new file mode 100644
index 0000000..b08c9e2
--- /dev/null
+++ b/include/vigra/wigner-matrix.hxx
@@ -0,0 +1,321 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2009-2010 by Ullrich Koethe and Janis Fehr          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_WIGNER_MATRIX_HXX
+#define VIGRA_WIGNER_MATRIX_HXX
+
+#include <complex>
+#include "config.hxx"
+#include "error.hxx"
+#include "utilities.hxx"
+#include "mathutil.hxx"
+#include "array_vector.hxx"
+#include "matrix.hxx"
+#include "tinyvector.hxx"
+#include "quaternion.hxx"
+#include "clebsch-gordan.hxx"
+
+namespace vigra {
+
+    /**
+     *  \class WignerMatrix 
+     *  \brief computation of Wigner D matrix + rotation functions 
+     *         in SH,VH and R�
+     *
+     * All rotations in Euler zyz' convention   
+     *
+     * WARNING: not thread safe! use a new instance of WignerMatrix
+     * for each thread!!!
+     */
+template <class Real>
+class WignerMatrix
+{   
+  public:
+  
+    // FIXME: should we rather use FFTWComplex?
+    typedef std::complex<Real> Complex;
+    typedef ArrayVector<ArrayVector<ArrayVector<Complex> > > NestedArray;
+    
+         /** \brief constructor
+          * 
+          * \param l_max    maximum expansion band (used to pre-compute 
+          *         the D matrix)
+          *
+          */
+    WignerMatrix(int l_max);
+    
+         /** \brief Compute D with fixed theta = pi/2, phi=0, psi=0.
+          *
+          * \param band expansion band
+          *
+             FIXME: compute_D(l, 0.0, M_PI / 2.0, 0.0) creates the transposed matrix!
+          */
+    void compute_D(int band);
+
+         /** \brief Compute D for arbitrary rotations.
+          *
+          * \param l        expansion band
+          * \param phi  rotation angle  
+          * \param theta    rotation angle
+          * \param psi  rotation angle
+          *
+          */
+    void compute_D(int l, Real phi, Real theta, Real psi);
+
+         /** \brief  Get the (n,m) entry of D.
+          *
+          * \param l        expansion band
+          * \param n        
+          * \param m    
+          */
+    Complex get_D(int l, int n, int m) const
+    {
+        if (l>0)
+        {
+            std::string message = std::string("WignerMatrix::get_D(): index out of bounds: l=");
+            message << l << " l_max=" << D.size() << " m=" << m << " n=" << n << "\n";
+                                  
+            vigra_precondition(l < D.size() && m+l <= 2*l+1 &&
+                               n+l <= 2*l+1 && m+l >= 0 && n+l >= 0,
+                               message.c_str());
+            return D[l](n+l, m+l);
+        }
+        else 
+        {
+            return Complex(Real(1.0));
+        }
+    }
+
+         /** \brief Return the rotation matrix D for the lth band.
+          *
+          * \param l        expansion band
+          */
+    Matrix<Complex> const & get_D(int l) const
+    {
+        std::string message = std::string("WignerMatrix::get_D(): index out of bounds: l=");
+        message << l << " l_max=" << l_max << "\n";
+                              
+        vigra_precondition(l > 0 && l <= l_max, message.c_str());
+        return D[l];
+    }
+
+         /** \brief Rotate in PH.
+          *
+          * \param PH       input PH expansion 
+          * \param phi      rotation angle
+          * \param theta    rotation angle
+          * \param psi      rotation angle
+          *
+          * \retval PHresult PH expansion   
+          */
+    void rotatePH(NestedArray const & PH, Real phi, Real theta, Real psi,
+                  NestedArray & PHresult);
+
+
+  private:
+    // FIXME: is function is not called (and cannot be called from outside the class)
+    TinyVector<double,3> 
+    rot(TinyVector<double,3> const & vec, TinyVector<double,3> const & axis, double angle)
+    {
+        typedef Quaternion<double> Q;
+        Q qr = Q::createRotation(angle, axis),
+          qv(0.0, vec);
+        return (qr * qv * conj(qr)).v();
+    }
+
+    int l_max;
+    int cg1cnt;
+    ArrayVector<double> CGcoeff;
+    ArrayVector<Matrix<Complex> > D;
+};
+
+template <class Real>
+WignerMatrix<Real>::WignerMatrix(int band)
+: l_max(0),
+  cg1cnt(0)
+{
+    //precompute clebschGordan coeffs
+    for (int l = 2; l <= band+1; l++)
+    {
+        for(int m = -l; m <= l ; m++)
+        {
+            for(int n = -l; n <= l ; n++)
+            {
+                for (int m2 = -1; m2 <= 1; m2++)
+                {
+                    for (int n2 = -1; n2 <= 1; n2++)
+                    {
+                        int m1 = m-m2;
+                        int n1 = n-n2;
+                        if (m1 > -l && m1 < l && n1 > -l && n1 < l)
+                        {
+                            CGcoeff.push_back((clebschGordan(l-1,m1,1,m2,l,m))*(clebschGordan(l-1,n1,1,n2,l,n)));
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+template <class Real>
+void
+WignerMatrix<Real>::compute_D(int l, Real phi, Real theta, Real psi)
+{
+    double s = std::sin(theta);
+    double c = std::cos(theta);
+    
+    Complex i(0.0, 1.0);
+    Complex eiphi = std::exp(i*phi);
+    Complex emiphi = std::exp(-i*phi);
+    Complex eipsi = std::exp(i*psi);
+    Complex emipsi = std::exp(-i*psi);
+    
+    if (D.size() < (std::size_t)(l+1)) 
+        D.resize(l+1);
+    D[1].reshape(MultiArrayShape<2>::type(3,3));
+    
+    D[1](0,0) = emipsi * Complex(Real(0.5*(1.0+c))) * emiphi;
+    D[1](0,1) = Complex(Real(-s/M_SQRT2)) * emiphi;
+    D[1](0,2) = eipsi * Complex(Real(0.5*(1.0-c))) * emiphi;
+    D[1](1,0) = emipsi * Complex(Real(s/M_SQRT2));
+    D[1](1,1) = Complex(Real(c));
+    D[1](1,2) = eipsi * Complex(Real(-s/M_SQRT2));
+    D[1](2,0) = emipsi * Complex(Real(0.5*(1.0-c))) * eiphi; 
+    D[1](2,1) = Complex(Real(s/M_SQRT2)) * eiphi;
+    D[1](2,2) = eipsi * Complex(Real(0.5*(1.0+c))) * eiphi;
+
+    l_max = 1;
+    cg1cnt = 0;
+    if(l > 1)
+        compute_D( l);
+}
+
+
+template <class Real>
+void
+WignerMatrix<Real>::compute_D(int l)
+{
+    if (D.size() < (std::size_t)(l+1) ) 
+    {
+        D.resize(l+1);
+        l_max = 0;
+    }
+
+    if (l==1)
+    {
+        //precompute D0 =1 and D1 = (90 degree rot)
+        // FIXME: signs are inconsistent with above explicit formula for 
+        //        theta = pi/2, phi=0, psi=0 (sine terms should be negated)
+        D[1].reshape(MultiArrayShape<2>::type(3,3));
+        D[1](0,0) = Real(0.5);
+        D[1](0,1) = Real(0.5*M_SQRT2);
+        D[1](0,2) = Real(0.5);
+        D[1](1,0) = Real(-0.5*M_SQRT2);
+        D[1](1,1) = Real(0.0);
+        D[1](1,2) = Real(0.5*M_SQRT2);
+        D[1](2,0) = Real(0.5);
+        D[1](2,1) = Real(-0.5*M_SQRT2);
+        D[1](2,2) = Real(0.5);
+        l_max = 1;
+        cg1cnt = 0;
+    }
+    else
+    {
+        //compute D2-Dl_max recursive
+        if (l>l_max+1)
+        {
+            compute_D(l-1);
+        }
+
+        D[l].reshape(MultiArrayShape<2>::type(2*l+1,2*l+1));
+        D[l].init(Real(0.0));      
+        
+        for(int m = -l; m <= l ; m++)
+        {
+            for(int n = -l; n <= l ; n++)
+            {
+                for (int m2 = -1; m2 <= 1; m2++)
+                {
+                    for (int n2 = -1; n2 <= 1; n2++)
+                    {
+                        int m1 = m-m2;
+                        int n1 = n-n2;
+                        if ((m1 > -l) && (m1 < l) && (n1 > -l) && (n1 < l))
+                        {
+                            D[l](m+l,n+l) += D[1](m2+1,n2+1) * D[l-1](m1+l-1,n1+l-1) * Real(CGcoeff[cg1cnt++]);
+                        }
+                    }
+                }
+            }
+        }
+
+        l_max = l;
+    }
+}
+
+template <class Real>
+void 
+WignerMatrix<Real>::rotatePH(NestedArray const & PH, Real phi, Real theta, Real psi,
+                             NestedArray & PHresult)
+{
+    int band = PH[1].size()-1;
+    compute_D(band, phi, theta, psi);
+
+    PHresult.resize(PH.size());
+
+    for(int n=1; n<=band; n++)
+    {
+        PHresult[n].resize(band+1);
+        for (int l=0; l<=band; l++)
+        {
+            PHresult[n][l].resize(2*band+1);
+            for(int m=-l; m<=l; m++)
+            {
+                Complex tmp = 0;
+                for (int h=-l; h<=l; h++)
+                {
+                    tmp += get_D(l,h,m) * PH[n][l][h+l];
+                }
+
+                PHresult[n][l][m+l] = tmp;
+            }
+        }
+    }
+}
+
+} // namespace vigra 
+
+#endif // VIGRA_WIGNER_MATRIX_HXX
diff --git a/include/vigra/windows.h b/include/vigra/windows.h
new file mode 100644
index 0000000..5bfa061
--- /dev/null
+++ b/include/vigra/windows.h
@@ -0,0 +1,59 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002-2003 by Ullrich Koethe                  */
+/*       Cognitive Systems Group, University of Hamburg, Germany        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_WINDOWS_H
+#define VIGRA_WINDOWS_H
+
+// prevent the global namespace to become polluted with
+// badly named Windows macros
+
+#if defined(_WIN32)
+# define VC_EXTRALEAN
+# ifndef NOMINMAX
+#  define NOMINMAX
+#  define _VIGRA_UNDEFINE_NOMINMAX
+# endif
+# include <windows.h>
+# ifdef _VIGRA_UNDEFINE_NOMINMAX
+#  undef NOMINMAX
+#  undef _VIGRA_UNDEFINE_NOMINMAX
+# endif
+# ifdef DIFFERENCE
+#  undef DIFFERENCE
+# endif
+#endif
+
+#endif /* VIGRA_WINDOWS_H */
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..c6b54dd
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,2 @@
+ADD_SUBDIRECTORY(impex)
+ADD_SUBDIRECTORY(examples)
diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt
new file mode 100644
index 0000000..cb78217
--- /dev/null
+++ b/src/examples/CMakeLists.txt
@@ -0,0 +1,24 @@
+SET(TARGETS 
+    convert
+    subimage
+    invert
+    invert_explicitly
+    resize
+    smooth
+    palette
+    profile
+    pyramid
+    edge
+    boundarytensor
+    watershed
+    weightedWatersheds
+    voronoi
+    total_variation)
+
+ADD_CUSTOM_TARGET(examples)
+
+FOREACH(TARGET ${TARGETS})
+    ADD_EXECUTABLE(example_${TARGET} EXCLUDE_FROM_ALL ${TARGET}.cxx)
+    ADD_DEPENDENCIES(examples example_${TARGET})
+    TARGET_LINK_LIBRARIES(example_${TARGET} vigraimpex)
+ENDFOREACH(TARGET)
diff --git a/src/examples/aniso_tv.par b/src/examples/aniso_tv.par
new file mode 100644
index 0000000..79c24a8
--- /dev/null
+++ b/src/examples/aniso_tv.par
@@ -0,0 +1,14 @@
+input_file  cameraman_noise.png
+output_file result_aniso_tv.png
+mode    3
+outer_steps   5
+inner_steps   500
+alpha   0.01
+beta    .3
+sigma   0.1
+rho     0.5
+edge_factor 500
+write_outer_steps 0
+histogram_stretch 0
+
+...do not change order or insert additional items above...
\ No newline at end of file
diff --git a/src/examples/block.tif b/src/examples/block.tif
new file mode 100644
index 0000000..d13c120
Binary files /dev/null and b/src/examples/block.tif differ
diff --git a/src/examples/boundarytensor.cxx b/src/examples/boundarytensor.cxx
new file mode 100644
index 0000000..c24f0e1
--- /dev/null
+++ b/src/examples/boundarytensor.cxx
@@ -0,0 +1,115 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2004 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/tensorutilities.hxx>
+#include <vigra/boundarytensor.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra; 
+
+int main(int argc, char ** argv)
+{
+    if(argc != 2)
+    {
+        std::cout << "Usage: " << argv[0] << " infile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        std::cout << "creates: boundarystrength.tif, cornerstrength.tif" << std::endl;
+        
+        return 1;
+    }
+    
+    try
+    {
+        ImageImportInfo info(argv[1]);
+        int w = info.width(), h = info.height();
+        
+        // create image of appropriate size for boundary tensor
+        MultiArray<2, TinyVector<float, 3> > boundarytensor(w, h);
+        
+        // input scale of the bandpass to be used
+        double scale;
+        std::cout << "Operator scale ? ";
+        std::cin >> scale;
+        
+        if(info.isGrayscale())
+        {
+            MultiArray<2, float> in(w, h);
+            importImage(info, in);
+
+            boundaryTensor(in, boundarytensor, scale);
+        }
+        else if(info.isColor())
+        {
+            MultiArray<2, RGBValue<float> > in(w, h);
+            importImage(info, in);
+            
+            // calculate the boundary tensor for every channel and add the results
+            MultiArray<2, TinyVector<float, 3> > bandtensor(w, h);
+            for(int b=0; b<3; ++b)
+            {
+                boundaryTensor(in.bindElementChannel(b), bandtensor, scale);
+                
+                boundarytensor += bandtensor;
+            }
+        }
+        else
+        {
+            std::cerr << "Sorry, can only operate on gray and color images.\n";
+            return 1;
+        }
+        
+        MultiArray<2, float> boundarystrength(w, h), cornerness(w, h);
+        MultiArray<2, TinyVector<float, 2> > edgeness(w,h);
+        
+        // compute the total boundary strength in each pixel
+        tensorTrace(boundarytensor, boundarystrength);
+        
+        // decompose the boundary strength into corner and edge parts (where edge part also contains an orientation)
+        tensorToEdgeCorner(boundarytensor, edgeness, cornerness);
+
+        exportImage(boundarystrength, ImageExportInfo("boundarystrength.tif").setPixelType("UINT8"));
+        exportImage(cornerness, ImageExportInfo("cornerstrength.tif").setPixelType("UINT8"));
+    }
+    catch (std::exception & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/cameraman.png b/src/examples/cameraman.png
new file mode 100644
index 0000000..bcfe71d
Binary files /dev/null and b/src/examples/cameraman.png differ
diff --git a/src/examples/cameraman_noise.png b/src/examples/cameraman_noise.png
new file mode 100644
index 0000000..3d8ff2d
Binary files /dev/null and b/src/examples/cameraman_noise.png differ
diff --git a/src/examples/convert.cxx b/src/examples/convert.cxx
new file mode 100644
index 0000000..9c684ed
--- /dev/null
+++ b/src/examples/convert.cxx
@@ -0,0 +1,93 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra; 
+
+
+int main(int argc, char ** argv)
+{
+    if(argc != 3)
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    try
+    {
+        // read image given as first argument
+        // file type is determined automatically
+        ImageImportInfo info(argv[1]);
+        
+        if(info.isGrayscale())
+        {
+            // create a gray scale image of appropriate size
+            MultiArray<2, UInt8> in(info.width(), info.height());
+            
+            // import the image just read
+            importImage(info, in);
+            
+            // write the image to the file given as second argument
+            // the file type will be determined from the file name's extension
+            exportImage(in, ImageExportInfo(argv[2]));
+        }
+        else
+        {
+            // create a RGB image of appropriate size
+            MultiArray<2, RGBValue<UInt8> > in(info.width(), info.height());
+            
+            // import the image just read
+            importImage(info, in);
+            
+            // write the image to the file given as second argument
+            // the file type will be determined from the file name's extension
+            exportImage(in, ImageExportInfo(argv[2]));
+        }
+    }
+    catch (std::exception & e)
+    {
+        // catch any errors that might have occurred and print their reason
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/edge.cxx b/src/examples/edge.cxx
new file mode 100644
index 0000000..1868961
--- /dev/null
+++ b/src/examples/edge.cxx
@@ -0,0 +1,108 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/edgedetection.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra; 
+
+
+int main(int argc, char ** argv)
+{
+    if(argc != 3)
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    try
+    {
+        ImageImportInfo info(argv[1]);
+        
+        vigra_precondition(info.isGrayscale(), "Sorry, cannot operate on color images");
+        
+        MultiArray<2, UInt8> in(info.shape());
+
+        importImage(info, in);
+
+        // input width of edge detection filter
+        int which;
+        std::cout << "Use Canny or Shen-Castan detector (1 or 2) ? ";
+        std::cin >> which;
+
+        // input width of edge detection filter
+        double scale;
+        std::cout << "Operator scale ? ";
+        std::cin >> scale;
+
+        // input threshold for gradient magnitude
+        double threshold;
+        std::cout << "Gradient threshold ? ";
+        std::cin >> threshold;
+    
+        // create output image of appropriate size
+        MultiArray<2, UInt8> out(info.shape());
+        
+        // paint output image white
+        out = 255;
+        
+        if(which == 2)
+        {
+            // call Shen-Castan edge detection algorithm
+            // edges will be marked black
+            differenceOfExponentialEdgeImage(in, out, scale, threshold, 0);
+        }
+        else
+        {
+            // call Canny edge detection algorithm
+            // edges will be marked black
+            cannyEdgeImage(in, out, scale, threshold, 0);
+        }
+        
+        exportImage(out, ImageExportInfo(argv[2]));
+    }
+    catch (std::exception & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/house.tif b/src/examples/house.tif
new file mode 100644
index 0000000..1188bfa
Binary files /dev/null and b/src/examples/house.tif differ
diff --git a/src/examples/invert.cxx b/src/examples/invert.cxx
new file mode 100644
index 0000000..6a23d6f
--- /dev/null
+++ b/src/examples/invert.cxx
@@ -0,0 +1,124 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/stdimagefunctions.hxx>
+#include <vigra/multi_math.hxx>
+#include <vigra/impex.hxx>
+#include <string.h>
+
+using namespace vigra; 
+
+
+int main(int argc, char ** argv)
+{
+    if(argc != 3)
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    try
+    {
+        ImageImportInfo info(argv[1]);
+        
+        if(info.isGrayscale())
+        {
+            MultiArray<2, UInt8> in(info.width(), info.height()),
+                                 out(info.width(), info.height());
+           
+            importImage(info, in);
+            
+            // create an inverted image by applying the expression
+            //       newvalue = -1 * (oldvalue - 255)
+            // to each pixel
+            transformImage(in, out,
+                           linearIntensityTransform(-1, -255));
+            
+            // the same can be achieved using array expressions
+            using namespace multi_math;   // activate array expressions
+            out = 255 - in;
+            
+            if(strcmp(argv[2], "-") == 0)
+            {
+                // write stdout
+                exportImage(out, ImageExportInfo(argv[2]).setFileType(info.getFileType()));
+            }
+            else
+            {
+                exportImage(out, ImageExportInfo(argv[2]));
+            }
+        }
+        else
+        {
+            MultiArray<2, RGBValue<UInt8> > in(info.width(), info.height()),
+                                            out(info.width(), info.height());
+           
+            importImage(info, in);
+            
+            // create a negative image by applying the expression
+            //       newvalue = -1 * (oldvalue + RGBValue<int>(-255, -255, -255))
+            // to each pixel
+            transformImage(in, out,
+                           linearIntensityTransform(-1, RGBValue<int>(-255)));
+            
+            // the same can be achieved using array expressions
+            using namespace multi_math;   // activate array expressions
+            out = RGBValue<int>(255) - in;
+            
+            if(strcmp(argv[2], "-") == 0)
+            {
+                // write stdout
+                exportImage(out, 
+                 ImageExportInfo(argv[2]).setFileType(info.getFileType()));
+            }
+            else
+            {
+                exportImage(out, ImageExportInfo(argv[2]));
+            }
+        }
+    }
+    catch (std::exception & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/invert_explicitly.cxx b/src/examples/invert_explicitly.cxx
new file mode 100644
index 0000000..b96c382
--- /dev/null
+++ b/src/examples/invert_explicitly.cxx
@@ -0,0 +1,149 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+
+#include <iostream>
+#include "vigra/stdimage.hxx"
+#include "vigra/stdimagefunctions.hxx"
+#include "vigra/impex.hxx"
+
+using namespace vigra; 
+
+
+int main(int argc, char ** argv)
+{
+    if(argc != 3)
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << vigra::impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    try
+    {
+        vigra::ImageImportInfo info(argv[1]);
+        
+        if(info.isGrayscale())
+        {
+            vigra::BImage in(info.width(), info.height());
+            vigra::BImage out(info.width(), info.height());
+           
+            importImage(info, destImage(in));
+            
+            // create image iterator that points to upper left corner 
+            // of source image
+            vigra::BImage::Iterator sy = in.upperLeft();
+            
+            // create image iterator that points past the lower right corner of
+            // source image (similarly to the past-the-end iterator in the STL)
+            vigra::BImage::Iterator send = in.lowerRight();
+            
+            // create image iterator that points to upper left corner 
+            // of destination image
+            vigra::BImage::Iterator dy = out.upperLeft();
+            
+            // iterate down the first column of the images
+            for(; sy.y != send.y; ++sy.y, ++dy.y)
+            {
+                // create image iterator that points to the first 
+                // pixel of the current row of the source image
+                vigra::BImage::Iterator sx = sy;
+
+                // create image iterator that points to the first 
+                // pixel of the current row of the destination image
+                vigra::BImage::Iterator dx = dy;
+                
+                // iterate across current row
+                for(; sx.x != send.x; ++sx.x, ++dx.x)
+                {
+                    // calculate negative gray value
+                    *dx = 255 - *sx;
+                }
+            }
+            
+            exportImage(srcImageRange(out), vigra::ImageExportInfo(argv[2]));
+        }
+        else
+        {
+            vigra::BRGBImage in(info.width(), info.height());
+            vigra::BRGBImage out(info.width(), info.height());
+           
+            importImage(info, destImage(in));
+            
+            vigra::RGBValue<int> offset(255, 255, 255);
+            
+            // create image iterator that points to upper left corner 
+            // of source image
+            vigra::BRGBImage::Iterator sy = in.upperLeft();
+            
+            // create image iterator that points past the lower right corner of
+            // source image (similarly to the past-the-end iterator in the STL)
+            vigra::BRGBImage::Iterator send = in.lowerRight();
+            
+            // create image iterator that points to upper left corner 
+            // of destination image
+            vigra::BRGBImage::Iterator dy = out.upperLeft();
+            
+            // iterate down the first column of the images
+            for(; sy.y != send.y; ++sy.y, ++dy.y)
+            {
+                // create image iterator that points to the first 
+                // pixel of the current row of the source image
+                vigra::BRGBImage::Iterator sx = sy;
+
+                // create image iterator that points to the first 
+                // pixel of the current row of the destination image
+                vigra::BRGBImage::Iterator dx = dy;
+                
+                // iterate across current row
+                for(; sx.x != send.x; ++sx.x, ++dx.x)
+                {
+                    // calculate negative color
+                    *dx = offset - *sx;
+                }
+            }
+            
+            exportImage(srcImageRange(out), vigra::ImageExportInfo(argv[2]));
+        }
+    }
+    catch (vigra::StdException & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/lenna.bmp b/src/examples/lenna.bmp
new file mode 100644
index 0000000..fb75b5d
Binary files /dev/null and b/src/examples/lenna.bmp differ
diff --git a/src/examples/lenna_color.gif b/src/examples/lenna_color.gif
new file mode 100644
index 0000000..36515b6
Binary files /dev/null and b/src/examples/lenna_color.gif differ
diff --git a/src/examples/lenna_color_small.gif b/src/examples/lenna_color_small.gif
new file mode 100644
index 0000000..dc43241
Binary files /dev/null and b/src/examples/lenna_color_small.gif differ
diff --git a/src/examples/lenna_gray.gif b/src/examples/lenna_gray.gif
new file mode 100644
index 0000000..e8faa53
Binary files /dev/null and b/src/examples/lenna_gray.gif differ
diff --git a/src/examples/lenna_small.gif b/src/examples/lenna_small.gif
new file mode 100644
index 0000000..0009766
Binary files /dev/null and b/src/examples/lenna_small.gif differ
diff --git a/src/examples/lenna_stripes.gif b/src/examples/lenna_stripes.gif
new file mode 100644
index 0000000..8ae9413
Binary files /dev/null and b/src/examples/lenna_stripes.gif differ
diff --git a/src/examples/lenna_sub.gif b/src/examples/lenna_sub.gif
new file mode 100644
index 0000000..dbc79ab
Binary files /dev/null and b/src/examples/lenna_sub.gif differ
diff --git a/src/examples/lenna_transposed.gif b/src/examples/lenna_transposed.gif
new file mode 100644
index 0000000..4dc8dbf
Binary files /dev/null and b/src/examples/lenna_transposed.gif differ
diff --git a/src/examples/oi.JPG b/src/examples/oi.JPG
new file mode 100644
index 0000000..5d99496
Binary files /dev/null and b/src/examples/oi.JPG differ
diff --git a/src/examples/oi.png b/src/examples/oi.png
new file mode 100644
index 0000000..f5a31a0
Binary files /dev/null and b/src/examples/oi.png differ
diff --git a/src/examples/oi_small.jpg b/src/examples/oi_small.jpg
new file mode 100644
index 0000000..eb6f1c6
Binary files /dev/null and b/src/examples/oi_small.jpg differ
diff --git a/src/examples/palette.cxx b/src/examples/palette.cxx
new file mode 100644
index 0000000..f3bc802
--- /dev/null
+++ b/src/examples/palette.cxx
@@ -0,0 +1,294 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <stdio.h>
+#include <iostream>
+#include <algorithm>
+#include <vigra/multi_array.hxx>
+#include <vigra/stdimagefunctions.hxx>
+#include <vigra/impex.hxx>
+#include <vigra/colorconversions.hxx>
+
+using namespace vigra;
+
+template<class Polar2Cartesian, class Cartesian2RGB, class RGB2RGBPrime>
+void createColorVsSaturation(MultiArray<2, RGBValue<UInt8> > & result, double brightness, 
+                 Polar2Cartesian polar2Cartesian, Cartesian2RGB cartesian2RGB, RGB2RGBPrime rgb2RGBPrime)
+{
+    int w = result.width(); 
+    int h = result.height();
+    
+    for(int y=0; y<h; ++y)
+    {
+        for(int x=0; x<w; ++x)
+        {
+            double saturation = (float)x / (w-1);
+            double color = (float)y / (h-1) * 360.0;
+            
+            RGBValue<float> rgb = cartesian2RGB(
+               polar2Cartesian(color, brightness, saturation));
+                        
+            if(saturation > 1.0 ||
+               rgb.red() < 0.0 || rgb.red() > 255.0 ||
+               rgb.green() < 0.0 || rgb.green() > 255.0 ||
+               rgb.blue() < 0.0 || rgb.blue() > 255.0)
+            {
+                result(x,y) = RGBValue<unsigned char>(170.0);
+            }
+            else
+            {
+                result(x,y) = rgb2RGBPrime(rgb);
+            }
+        }
+    }
+}
+
+template<class Polar2Cartesian, class Cartesian2RGB, class RGB2RGBPrime>
+void createColorVsBrightness(MultiArray<2, RGBValue<UInt8> > & result, double saturation, 
+                 Polar2Cartesian polar2Cartesian, Cartesian2RGB cartesian2RGB, RGB2RGBPrime rgb2RGBPrime)
+{
+    int w = result.width(); 
+    int h = result.height();
+    
+    for(int y=0; y<h; ++y)
+    {
+        for(int x=0; x<w; ++x)
+        {
+            double brightness = (float)x / (w-1);
+            double color = (float)y / (h-1) * 360.0;
+            
+            RGBValue<float> rgb = cartesian2RGB(
+               polar2Cartesian(color, brightness, saturation));
+            
+            if(saturation > 1.0 ||
+               rgb.red() < 0.0 || rgb.red() > 255.0 ||
+               rgb.green() < 0.0 || rgb.green() > 255.0 ||
+               rgb.blue() < 0.0 || rgb.blue() > 255.0)
+            {
+                result(x,y) = RGBValue<unsigned char>(170.0);
+            }
+            else
+            {
+                result(x,y) = rgb2RGBPrime(rgb);
+            }
+        }
+    }
+}
+
+template<class Polar2Cartesian, class Cartesian2RGB, class RGB2RGBPrime>
+void createSaturationVsBrightness(MultiArray<2, RGBValue<UInt8> > & result, double color, 
+                 Polar2Cartesian polar2Cartesian, Cartesian2RGB cartesian2RGB, RGB2RGBPrime rgb2RGBPrime)
+{
+    int w = result.width(); 
+    int h = result.height();
+    
+    for(int y=0; y<h; ++y)
+    {
+        for(int x=0; x<w; ++x)
+        {
+            double brightness = (float)x / (w-1);
+            double saturation = (float)y / (h-1);
+            
+            RGBValue<float> rgb = cartesian2RGB(
+               polar2Cartesian(color, brightness, saturation));
+            
+            if(saturation > 1.0 ||
+               rgb.red() < 0.0 || rgb.red() > 255.0 ||
+               rgb.green() < 0.0 || rgb.green() > 255.0 ||
+               rgb.blue() < 0.0 || rgb.blue() > 255.0)
+            {
+                result(x,y) = RGBValue<unsigned char>(170.0);
+            }
+            else
+            {
+                result(x,y) = rgb2RGBPrime(rgb);
+            }
+        }
+    }
+}
+
+template<class Polar2Cartesian, class Cartesian2RGB, class RGB2RGBPrime>
+void createColorCircle(MultiArray<2, RGBValue<UInt8> > & result, double brightness, 
+                 Polar2Cartesian polar2Cartesian, Cartesian2RGB cartesian2RGB, RGB2RGBPrime rgb2RGBPrime)
+{
+    int w = result.width(); 
+    int h = result.height();
+    
+    for(int y=0; y<h; ++y)
+    {
+        for(int x=0; x<w; ++x)
+        {
+            double dx = x/128.0 - 1.0;
+            double dy = -y/128.0 + 1.0;
+            double color = 180.0/M_PI*std::atan2(dy,dx);
+            double saturation = std::sqrt(dx*dx+dy*dy);
+            
+            RGBValue<float> rgb = cartesian2RGB(
+               polar2Cartesian(color, brightness, saturation));
+            
+            if(saturation > 1.0 ||
+               rgb.red() < 0.0 || rgb.red() > 255.0 ||
+               rgb.green() < 0.0 || rgb.green() > 255.0 ||
+               rgb.blue() < 0.0 || rgb.blue() > 255.0)
+            {
+                result(x,y) = RGBValue<unsigned char>(170.0);
+            }
+            else
+            {
+                result(x,y) = rgb2RGBPrime(rgb);
+            }
+        }
+    }
+}
+
+void write(char const * colorspace, char const * diagram, int i, MultiArray<2, RGBValue<UInt8> > const & img)
+{
+    char buf[1000];
+    if(i < 10)
+        sprintf(buf, "%s_%s_0%d.gif", colorspace, diagram, i);
+    else
+        sprintf(buf, "%s_%s_%d.gif", colorspace, diagram, i);
+    exportImage(img, ImageExportInfo(buf));
+    std::cout << "Wrote " << buf << std::endl;
+}
+
+template<class Polar2Cartesian, class Cartesian2RGB, class RGB2RGBPrime>
+void createColorSpaceSlices(char const * colorspace,
+    Polar2Cartesian polar2Cartesian, Cartesian2RGB cartesian2RGB, RGB2RGBPrime rgb2RGBPrime)
+{
+    int w = 257; 
+    int h = 257;
+    int Ymax = 10;
+    
+    for(int i=0; i<=Ymax; ++i)
+    {
+
+        MultiArray<2, RGBValue<UInt8> > result(w, h);
+
+        createColorVsSaturation(result, (float)i/Ymax, 
+                        polar2Cartesian, cartesian2RGB, rgb2RGBPrime);
+        write(colorspace, "ColorVsSaturation", i, result);
+
+        createColorVsBrightness(result, (float)i/Ymax, 
+                        polar2Cartesian, cartesian2RGB, rgb2RGBPrime);
+        write(colorspace, "ColorVsBrightness", i, result);
+
+        createSaturationVsBrightness(result, (float)i/Ymax*360.0, 
+                        polar2Cartesian, cartesian2RGB, rgb2RGBPrime);
+        write(colorspace, "SaturationVsBrightness", i, result);
+
+        createColorCircle(result, (float)i/Ymax, 
+                        polar2Cartesian, cartesian2RGB, rgb2RGBPrime);
+        write(colorspace, "ColorCircle", i, result);
+    }
+}
+
+void usage(char const * prog)
+{
+    std::cerr << "Usage: " << prog << " colorspace\n"
+                 "with colorspace in [lab luv ypbpr ycbcr yiq yuv]\n\n";
+    std::cerr << "This programm calculates slices through the given color space\n"
+                 "Images are named 'lab_SaturationVsBrightness_01.gif' etc.\n"
+                 "where the first part of the name designates the colorspace used,\n"
+                 "the second part says what is varied on the image\n"
+                 "and the number codes the value of the quantity that is kept\n"
+                 "constant in the image - 01 in the example means that the color\n"
+                 "angle is 36 degrees = 1 * 360 degrees / 10\n";
+}
+
+int main(int argc, char ** argv)
+{
+    if(argc <2)
+    {
+        usage(argv[0]);
+        return 1;
+    }
+    
+    try
+    {
+        typedef TinyVector<float, 3> (*PolarFct)(double, double, double);
+        std::string colorspace(argv[1]);
+        
+        if(colorspace == "lab")
+        {
+            createColorSpaceSlices("lab", 
+                         (PolarFct)&polar2Lab, Lab2RGBFunctor<float>(),
+                         RGB2RGBPrimeFunctor<float, unsigned char>());
+        }
+        else if(colorspace == "luv")
+        {
+            createColorSpaceSlices("luv", 
+                         (PolarFct)&polar2Luv, Luv2RGBFunctor<float>(),
+                         RGB2RGBPrimeFunctor<float, unsigned char>());
+        }
+        else if(colorspace == "ypbpr")
+        {
+            createColorSpaceSlices("ypbpr", 
+                         (PolarFct)&polar2YPrimePbPr, YPrimePbPr2RGBPrimeFunctor<float>(),
+                         &NumericTraits<RGBValue<unsigned char> >::fromRealPromote);
+        }
+        else if(colorspace == "ycbcr")
+        {
+            createColorSpaceSlices("ycbcr", 
+                         (PolarFct)&polar2YPrimeCbCr, YPrimeCbCr2RGBPrimeFunctor<float>(),
+                         &NumericTraits<RGBValue<unsigned char> >::fromRealPromote);
+        }
+        else if(colorspace == "yiq")
+        {
+            createColorSpaceSlices("yiq", 
+                         (PolarFct)&polar2YPrimeIQ, YPrimeIQ2RGBPrimeFunctor<float>(),
+                         &NumericTraits<RGBValue<unsigned char> >::fromRealPromote);
+        }
+        else if(colorspace == "yuv")
+        {
+            createColorSpaceSlices("yuv", 
+                         (PolarFct)&polar2YPrimeUV, YPrimeUV2RGBPrimeFunctor<float>(),
+                         &NumericTraits<RGBValue<unsigned char> >::fromRealPromote);
+        }
+        else
+        {
+            std::cerr << "Unknown colorspace: " << colorspace << std::endl;
+            usage(argv[0]);
+            return 1;
+        }
+    }
+    catch (std::exception & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/profile.cxx b/src/examples/profile.cxx
new file mode 100644
index 0000000..55ce1ac
--- /dev/null
+++ b/src/examples/profile.cxx
@@ -0,0 +1,106 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+
+#include <iostream>
+#include <vigra/stdimage.hxx>
+#include <vigra/imageiteratoradapter.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra; 
+
+
+int main(int argc, char ** argv)
+{
+    if(argc != 2)
+    {
+        std::cout << "Usage: " << argv[0] << " infile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    try
+    {
+        ImageImportInfo info(argv[1]);
+        
+        vigra_precondition(info.isGrayscale(), "Sorry, cannot operate on color images");
+        
+        int w = info.width();
+        int h = info.height();
+            
+        
+        BImage in(w, h);
+        importImage(info, destImage(in));
+        
+        int length = (w < h) ? h : w;
+
+        // create output image of appropriate size
+        BImage out(length, 256);
+        
+        
+        // paint output image white
+        out = 255;
+
+        // create line iterator that iterates along the image diagonal
+        LineIterator<BImage::Iterator> line(in.upperLeft(), in.lowerRight());
+         
+        // create line iterator that marks the end of iteration
+        LineIterator<BImage::Iterator> end(in.lowerRight(), in.lowerRight());
+
+        // create image iterator that points to the first pixel of the last
+        // row of the destination image
+        BImage::Iterator column = out.upperLeft() + Diff2D(0, 255);
+        
+        // iterate along the line and across the destination image
+        for(; line != end; ++line, ++column.x)
+        {
+            BImage::Iterator row(column);
+            // paint all pixels black whose coordinates are smaller than the
+            // current gray value along the diagonal
+            for(int y=0; y <= *line; ++y, --row.y)  *row = 0;
+        }
+        
+        std::cout << "Writing profile.gif" << std::endl;
+        exportImage(srcImageRange(out), ImageExportInfo("profile.gif"));
+    }
+    catch (std::exception & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/pyramid.cxx b/src/examples/pyramid.cxx
new file mode 100644
index 0000000..ade9b6c
--- /dev/null
+++ b/src/examples/pyramid.cxx
@@ -0,0 +1,134 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+
+#include <iostream>
+#include <stdio.h>
+#include "vigra/stdimage.hxx"
+#include "vigra/convolution.hxx"
+#include "vigra/resizeimage.hxx"
+#include "vigra/impex.hxx"
+
+using namespace vigra; 
+
+// Gaussian reduction to next pyramid level
+template <class Image>
+void reduceToNextLevel(Image & in, Image & out)
+{    
+    // image size at current level
+    int width = in.width();
+    int height = in.height();
+    
+    // image size at next smaller level
+    int newwidth = (width + 1) / 2;
+    int newheight = (height + 1) / 2;
+    
+    // resize result image to appropriate size
+    out.resize(newwidth, newheight);
+    
+    // define a Gaussian kernel (size 5x1)
+    vigra::Kernel1D<double> filter;
+    filter.initExplicitly(-2, 2) = 0.05, 0.25, 0.4, 0.25, 0.05;
+    
+    vigra::BasicImage<typename Image::value_type> tmpimage1(width, height);
+    vigra::BasicImage<typename Image::value_type> tmpimage2(width, height);
+    
+    // smooth (band limit) input image
+    separableConvolveX(srcImageRange(in),
+                       destImage(tmpimage1), kernel1d(filter));
+    separableConvolveY(srcImageRange(tmpimage1),
+                       destImage(tmpimage2), kernel1d(filter));
+                       
+    // downsample smoothed image
+    resizeImageNoInterpolation(srcImageRange(tmpimage2), destImageRange(out));
+    
+}
+
+int main(int argc, char ** argv)
+{
+    if(argc != 3)
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << vigra::impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    try
+    {
+        vigra::ImageImportInfo info(argv[1]);
+        
+        if(info.isGrayscale())
+        {
+            vigra::BImage levels[4];
+        
+            levels[0].resize(info.width(), info.height());
+           
+            importImage(info, destImage(levels[0]));
+            
+            for(int i=1; i<4; ++i)
+            {
+                // reduce gray image 3 times
+                reduceToNextLevel(levels[i-1], levels[i]);
+
+            }
+            
+            exportImage(srcImageRange(levels[3]), vigra::ImageExportInfo(argv[2]));
+        }
+        else
+        {
+            vigra::BRGBImage levels[4];
+        
+            levels[0].resize(info.width(), info.height());
+           
+            importImage(info, destImage(levels[0]));
+            
+            for(int i=1; i<4; ++i)
+            {
+                // reduce color image 3 times
+                reduceToNextLevel(levels[i-1], levels[i]);
+            }
+            
+            exportImage(srcImageRange(levels[3]), vigra::ImageExportInfo(argv[2]));
+        }
+    }
+    catch (vigra::StdException & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/resize.cxx b/src/examples/resize.cxx
new file mode 100644
index 0000000..7348b49
--- /dev/null
+++ b/src/examples/resize.cxx
@@ -0,0 +1,164 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/rgbvalue.hxx>
+#include <vigra/resizeimage.hxx>
+#include <vigra/impex.hxx>
+
+template<class ImageType>
+bool resizeImageFile(const vigra::ImageImportInfo &info, const vigra::Shape2 &newSize,
+                     int method, const char *outputFilename)
+{
+    // create a gray scale image of appropriate size
+    ImageType in(info.shape());
+    ImageType out(newSize);
+
+    // import the image just read
+    importImage(info, destImage(in));
+
+    using vigra::BSpline;
+
+    switch(method)
+    {
+      case 0:
+        // equiv. to resizeImageSplineInterpolation with BSpline<0, double>:
+        resizeImageNoInterpolation(in, out);
+        break;
+      case 1:
+        // equiv. to resizeImageSplineInterpolation with BSpline<1, double>:
+        resizeImageLinearInterpolation(in, out);
+        break;
+      case 2:
+        resizeImageSplineInterpolation(in, out,
+                                       BSpline<2, double>());
+        break;
+      case 3:
+        resizeImageSplineInterpolation(in, out,
+                                       BSpline<3, double>());
+        break;
+      case 4:
+        resizeImageSplineInterpolation(in, out,
+                                       BSpline<4, double>());
+        break;
+      case 5:
+        resizeImageSplineInterpolation(in, out,
+                                       BSpline<5, double>());
+        break;
+      case 6:
+        resizeImageSplineInterpolation(in, out,
+                                       BSpline<6, double>());
+        break;
+      case 7:
+        resizeImageSplineInterpolation(in, out,
+                                       BSpline<7, double>());
+        break;
+      default:
+        std::cerr << "Invalid method " << method << " (must be 0..7)!\n";
+        return false;
+    }
+
+    // write the image to the file given as second argument
+    // the file type will be determined from the file name's extension
+    exportImage(out, vigra::ImageExportInfo(outputFilename));
+    return true;
+}
+
+int main(int argc, char ** argv)
+{
+    using namespace vigra;
+    
+    if((argc < 3) || (argc > 5))
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile [factor] [method]" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        std::cout << "If factor or method are not provided, you will be asked for\nthem on the command line." << std::endl;
+
+        return 1;
+    }
+
+    try
+    {
+        // read image given as first argument
+        // file type is determined automatically
+        ImageImportInfo info(argv[1]);
+
+        double sizefactor;
+        if(argc > 3)
+        {
+            sizefactor = atof(argv[3]);
+        }
+        else
+        {
+            std::cerr << "Resize factor ? ";
+            std::cin >> sizefactor;
+        }
+
+        int method;
+        if(argc > 4)
+        {
+            method = atoi(argv[4]);
+        }
+        else
+        {
+            std::cerr << "Method (0: pixel repetition, 1: linear, 2-7: spline) ? ";
+            std::cin >> method;
+        }
+
+        // calculate new image size
+        Shape2 newSize((info.shape() - Shape2(1,1)) * sizefactor + Shape2(1,1));
+
+        if(info.isGrayscale())
+        {
+            if(!resizeImageFile<MultiArray<2, UInt8> >(info, newSize, method, argv[2]))
+                return 1;
+        }
+        else
+        {
+            if(!resizeImageFile<MultiArray<2, RGBValue<UInt8> > >(info, newSize, method, argv[2]))
+                return 1;
+        }
+    }
+    catch (std::exception & e)
+    {
+        // catch any errors that might have occurred and print their reason
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/src/examples/second_order_tv.par b/src/examples/second_order_tv.par
new file mode 100644
index 0000000..39ced3c
--- /dev/null
+++ b/src/examples/second_order_tv.par
@@ -0,0 +1,15 @@
+input_file  cameraman_noise.png
+output_file result_second_order.png
+mode         4
+outer_steps  5
+inner_steps  200
+alpha        0.05
+beta        .5
+gamma        0.01
+sigma        0.1
+rho          0.5
+edge_factor  1000
+write_outer_steps  0
+histogram_stretch 0
+
+...do not change order or insert additional items above...
\ No newline at end of file
diff --git a/src/examples/smooth.cxx b/src/examples/smooth.cxx
new file mode 100644
index 0000000..cef21b7
--- /dev/null
+++ b/src/examples/smooth.cxx
@@ -0,0 +1,150 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/convolution.hxx>
+#include <vigra/nonlineardiffusion.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra; 
+
+
+int main(int argc, char ** argv)
+{
+    if(argc != 3)
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    // Type of smoothing: 
+    int type;
+    std::cout << "Type of smoothing (1 = Gauss, 2 = Exponential, 3 = nonlinear) ? ";
+    std::cin >> type;
+    
+    // input width of smoothing filter 
+    double scale;
+    std::cout << "Amount of smoothing (operator scale) ? ";
+    std::cin >> scale;
+    
+    double edge_threshold;
+    if(type == 3)
+    {
+        std::cout << "Edge threshold ? ";
+        std::cin >> edge_threshold;
+    }
+    
+    try
+    {
+        ImageImportInfo info(argv[1]);
+        
+        if(info.isGrayscale())
+        {
+            MultiArray<2, UInt8> in(info.width(), info.height());
+            MultiArray<2, float> out(info.width(), info.height());
+           
+            importImage(info, destImage(in));
+            
+            switch(type)
+            {
+              case 2:
+              {
+                // apply recursive filter (exponential filter) to gray image
+                recursiveSmoothX(in, out, scale);
+                recursiveSmoothY(out, out, scale);
+                break;
+              }
+              case 3:
+              {
+                // apply nonlinear diffusion to gray image
+                nonlinearDiffusion(in, out,
+                   DiffusivityFunctor<float>(edge_threshold), scale);
+                break;
+              }
+              default:
+              {
+                gaussianSmoothing(in, out, scale);
+              }
+            }
+            
+            exportImage(out, ImageExportInfo(argv[2]));
+        }
+        else
+        {
+            MultiArray<2, RGBValue<UInt8> > in(info.shape());
+            MultiArray<2, RGBValue<float> > out(info.shape());
+           
+            importImage(info, in);
+            
+            switch(type)
+            {
+              case 2:
+              {
+                // apply recursive filter (exponential filter) to color image
+                recursiveSmoothX(in, out, scale);
+                recursiveSmoothY(out, out, scale);
+                break;
+              }
+              case 3:
+              {
+                // apply nonlinear diffusion to color image, one band at a time
+                for(int band = 0; band<3; ++band)
+                {
+                    nonlinearDiffusion(in.bindElementChannel(band), out.bindElementChannel(band),
+                                       DiffusivityFunctor<float>(edge_threshold), scale);
+                }
+                break;
+              }
+              default:
+              {
+                gaussianSmoothing(in, out, scale);
+              }
+            }
+            
+            exportImage(out, ImageExportInfo(argv[2]));
+        }
+    }
+    catch (std::exception & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/subimage.cxx b/src/examples/subimage.cxx
new file mode 100644
index 0000000..a166e59
--- /dev/null
+++ b/src/examples/subimage.cxx
@@ -0,0 +1,95 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+ 
+
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/stdimagefunctions.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra; 
+
+int main(int argc, char ** argv)
+{
+    if(argc != 3)
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    try
+    {
+        ImageImportInfo info(argv[1]);
+        
+        // define upper left and lower right corners of a 
+        // subimage (region of interest)
+        int sub_x0 = info.width() / 4;
+        int sub_y0 = info.height() / 4;
+        int sub_x1 = info.width() - sub_x0;
+        int sub_y1 = info.height() - sub_y0;
+            
+        if(info.isGrayscale())
+        {
+            MultiArray<2, UInt8> in(info.width(), info.height());
+            
+            importImage(info, in);
+            
+            // create an array view for the desired subregion
+            MultiArrayView<2, UInt8> out = in.subarray(Shape2(sub_x0, sub_y0), Shape2(sub_x1, sub_y1));
+            
+            exportImage(out, ImageExportInfo(argv[2]));
+        }
+        else
+        {
+            MultiArray<2, RGBValue<UInt8> > in(info.width(), info.height());
+            
+            importImage(info, in);
+            
+            // create an array view for the desired subregion
+            MultiArrayView<2, RGBValue<UInt8> > out = in.subarray(Shape2(sub_x0, sub_y0), Shape2(sub_x1, sub_y1));
+            
+            exportImage(out, ImageExportInfo(argv[2]));
+        }
+    }
+    catch (std::exception & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/total_variation.cxx b/src/examples/total_variation.cxx
new file mode 100644
index 0000000..f5ef026
--- /dev/null
+++ b/src/examples/total_variation.cxx
@@ -0,0 +1,285 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2012 by Frank Lenzen &                     */
+/*                                           Ullrich Koethe             */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <vigra/multi_array.hxx>
+#include <vigra/stdimagefunctions.hxx>
+#include <vigra/impex.hxx>
+#include <vigra/tv_filter.hxx>
+
+#ifdef _MSC_VER
+#define strcasecmp _stricmp
+#endif
+
+using namespace vigra; 
+
+
+// Read a string from file <file>.
+void read_string(FILE *file,const char *name, char* out){
+    char dummy[80];
+    int s=fscanf(file,"%s %s ",dummy,out);
+    if (s==EOF || s<2){
+        std::cout<<"Could not read from file.\n";
+        exit(0); 
+    }
+    else if (strcasecmp(name,dummy)!=0){
+        std::cout<<"Found parameter "<<dummy<<" instead of "<<name<<"\n";
+        exit(0);
+    }
+    else
+    std::cout<<"Parameter "<<name<<" = "<<out<<std::endl;
+}
+
+// read a flota-value from file <file>
+float read_value(FILE *file,const char *name){
+    char dummy[80];
+    char dummy2[80];
+    float f=0;
+
+    int s=fscanf(file,"%s %s ",dummy,dummy2); 
+
+
+    if (s==EOF || s<2){
+        std::cout<<"Could not read from file.\n";
+        exit(0); 
+    }
+    else if (strcasecmp(name,dummy)!=0){
+        std::cout<<"Found parameter "<<dummy<<" instead of "<<name<<"\n";
+        exit(0);
+    }
+    else{
+        f=atof(dummy2);
+        std::cout<<"Parameter "<<name<<" = "<<f<<std::endl;
+    }
+    return f;
+}
+
+
+int main(int argc, char ** argv)
+{
+
+    using namespace multi_math;
+
+    if(argc <2)
+    {
+        std::cout << "Usage: " << argv[0] << " parameterfile" << std::endl;
+        std::cout << "(supported formats for images: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+
+    try
+    {   
+        char infile[80],outfile[80];
+        double alpha0=0.01*sqrt(255.0),beta0=0.1*sqrt(255.0),sigma=0.1,rho=.5,K=10,eps=0,gamma0=0;
+        int mode,inner_steps=200,outer_steps=5,write_steps=0;
+        
+        FILE *file=fopen(argv[1],"r");         // open parameter file 
+        if (!file){
+            std::cout<<"Cannot open file "<<argv[1]<<std::endl;
+            return 1;
+        }
+        read_string(file,"input_file",infile);    // read name of input file (an image)
+        read_string(file,"output_file",outfile);  // read name of output file (an image)
+        mode=(int)read_value(file,"mode");        // read mode:  1- standard Total Variation
+        //             2- Anisotropic Total Variation
+        //             3- Anisotropic Total Variation with Higher Order term
+        
+        // further parameters depend on mode					      
+        switch(mode){
+        case 1:
+        case 2:
+            inner_steps=1000;                 // read number of iteration steps
+            alpha0=read_value(file,"alpha");  // read alpha
+            eps=read_value(file,"epsilon");   // read eps
+            break;
+        case 3:
+            outer_steps=(int)read_value(file,"outer_steps"); // read number of outer iteration steps
+            inner_steps=(int)read_value(file,"inner_steps"); // read number of inner iteration steps
+            alpha0=read_value(file,"alpha");  // read alpha
+            beta0=read_value(file,"beta");    // read beta 
+            sigma=read_value(file,"sigma");   // read sigma
+            rho=read_value(file,"rho");       // read rho
+            K=read_value(file,"edge_factor"); // read parameter K (edge sensitivity)
+            write_steps=(int)read_value(file,"write_outer_steps"); //read flag for writing intermediate result after each outer iteration
+            break;  
+            
+        case 4:
+            outer_steps=(int)read_value(file,"outer_steps"); // read number of outer iteration steps
+            inner_steps=(int)read_value(file,"inner_steps"); // read number of inner iteration steps
+            alpha0=read_value(file,"alpha"); // read alpha
+            beta0=read_value(file,"beta");   // read beta 
+            gamma0=read_value(file,"gamma"); // read gamma
+            sigma=read_value(file,"sigma");  // read sigma
+            rho=read_value(file,"rho");      // read rho
+            K=read_value(file,"edge_factor");// read parameter K (edge sensitivity)
+            write_steps=(int)read_value(file,"write_outer_steps");//read flag for writing intermediate result after each outer iteration
+            break;
+        default:
+            std::cout<<"Unknown mode "<<mode<<std::endl;
+        }
+        int stretch=(int)read_value(file,"histogram_stretch");        // flag for histogram stretching: 0 -no, 1 -yes
+        
+        
+        
+        ImageImportInfo info(infile); // get information about input image
+        
+        
+        
+        if(info.isGrayscale())
+        {
+            MultiArray<2,double> data(info.shape());
+            MultiArray<2,double> out(info.shape()); 
+            MultiArray<2,double> weight(info.shape());  
+            
+            
+            for (int y=0;y<data.shape(1);y++){
+                for (int x=0;x<data.shape(0);x++){
+                    weight(x,y)=1;                         // set weight to 1 (needed for anisotropicTotalVariationFilter and
+                    // higherOrderTotalVariationFilter
+                }
+            }
+            importImage(info, destImage(data));        // read image data
+            data=data*(1/255.);                        // scale to [0,1] (smoothing parameters are tuned to this scaling)
+            
+            //------------------------------------
+            //     Choose specific TV Filter
+            //------------------------------------
+            switch(mode){
+            case 1:
+                std::cout<<"Standard TV filter"<<std::endl;
+                totalVariationFilter(data,out,alpha0,inner_steps,eps);
+                break;
+            case 2: 
+                std::cout<<"Weighted TV filter"<<std::endl;
+                totalVariationFilter(data,out,weight,alpha0,inner_steps,eps);
+                break;
+            case 3:{
+                    std::cout<<"Anisotropic TV filter"<<std::endl;
+                    
+                    MultiArray<2,double> phi(info.shape());
+                    MultiArray<2,double> alpha(info.shape());
+                    MultiArray<2,double> beta(info.shape()); 
+                    
+                    out=data;   //'data' serves as initial value
+                    
+                    for (int i=0;i<outer_steps;i++){   // Outer loop to update anisotropic data 
+                        std::cout<<"outer step "<<i<<"\n";
+                        
+                        getAnisotropy(out,phi,alpha,beta,alpha0,beta0,sigma,rho,K);  // get anisotropic data
+                        anisotropicTotalVariationFilter(data,weight,phi,alpha,beta,out,inner_steps); //perform smoothing 
+                        
+                        if(write_steps){
+                            char dummy[80];
+                            sprintf(dummy,"output_step_%03d.png",i);
+                            std::cout<<"Writing temp file\n";
+                            if (stretch)
+                            exportImage(out, ImageExportInfo(dummy)); //exportImage performes histogramm stretching
+                            else{
+                                MultiArray<2,unsigned char>  buffer(info.shape());
+                                buffer=max(min(out*255+0.5,0.),255.);                              //scaling back to [0,255], clipping, cast to uint8
+                                exportImage(buffer, ImageExportInfo(dummy));
+                            }  
+                        }
+                    }
+                    break;
+                }
+                
+            case 4:{
+                    std::cout<<"Second order TV filter"<<std::endl;
+                    
+                    MultiArray<2,double> phi(info.shape());
+                    MultiArray<2,double> alpha(info.shape());
+                    MultiArray<2,double> beta(info.shape());  
+                    MultiArray<2,double> gamma(info.shape()); 
+                    MultiArray<2,double> xedges(info.shape()); 
+                    MultiArray<2,double> yedges(info.shape()); 
+                    
+                    for (int y=0;y<data.shape(1);y++){  // set data needed for second order term
+                        for (int x=0;x<data.shape(0);x++){
+                            gamma(x,y)=gamma0;
+                            xedges(x,y)=1;
+                            yedges(x,y)=1;
+                        }
+                    }
+                    
+                    out=data;  //'data' serves as initial value
+                    
+                    for (int i=0;i<outer_steps;i++){// Outer loop to update anisotropic data 
+                        std::cout<<"outer step "<<i<<"\n";
+                        
+                        getAnisotropy(out,phi,alpha,beta,alpha0,beta0,sigma,rho,K); // get anisotropic data
+                        secondOrderTotalVariationFilter(data,weight,phi,alpha,beta,gamma,xedges,yedges,out,inner_steps);//perform smoothing 
+                        
+                        if(write_steps){
+                            char dummy[80];
+                            sprintf(dummy,"output_step_%03d.png",i);
+                            std::cout<<"Writing temp file\n"; 
+                            if (stretch)
+                            exportImage(out, ImageExportInfo(dummy));
+                            else{
+                                MultiArray<2,unsigned char>  buffer(info.shape());
+                                buffer=max(min(out*255+0.5,0.),255.);                              //scaling back to [0,255], clipping, cast to uint8
+                                exportImage(buffer, ImageExportInfo(dummy));
+                            }  
+                        }
+                    }
+                }
+            }
+            //-------------------------------------
+            if (stretch)
+            exportImage(out, ImageExportInfo(outfile));  //write result to file
+            else{
+                MultiArray<2,unsigned char>  buffer(info.shape());
+                buffer=min(max(out*255.+0.5,0.),255.);                              //scaling back to [0,255], clipping, cast to uint8
+                exportImage(buffer, ImageExportInfo(outfile));
+            }
+        }
+        else
+        {
+            std::cout<<"Color images are currently not supported !\n";
+        }
+    }
+    catch (std::exception & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/src/examples/tutorial/cameraman.png b/src/examples/tutorial/cameraman.png
new file mode 100644
index 0000000..bcfe71d
Binary files /dev/null and b/src/examples/tutorial/cameraman.png differ
diff --git a/src/examples/tutorial/chess_smoothed.gif b/src/examples/tutorial/chess_smoothed.gif
new file mode 100644
index 0000000..eb4f1e8
Binary files /dev/null and b/src/examples/tutorial/chess_smoothed.gif differ
diff --git a/src/examples/tutorial/composite.cxx b/src/examples/tutorial/composite.cxx
new file mode 100755
index 0000000..205556e
--- /dev/null
+++ b/src/examples/tutorial/composite.cxx
@@ -0,0 +1,68 @@
+#include <vigra/multi_array.hxx>
+#include <vigra/impex.hxx>
+#include <vigra/multi_math.hxx>
+#include <vigra/basicgeometry.hxx>
+
+using namespace vigra;
+
+
+int main (int argc, char ** argv) 
+{
+    // read image given as first argument
+    vigra::ImageImportInfo info(argv[1]);
+    
+    int w = info.width(),
+        h = info.height();
+
+    // process grayscale image
+    if (info.isGrayscale()) 
+    {
+        // instantiate arrays for image data and for composite image of appropriate size
+        vigra::MultiArray<2, UInt8> imageArray(info.shape());
+        vigra::MultiArray<2, UInt8> exportArray(2*info.shape());
+
+        // copy image data into array
+        importImage(info, imageArray);
+
+        // topleft corner of composite image contains the original image
+        exportArray.subarray(Shape2(0,0), info.shape()) = imageArray;
+
+        // topright corner contains the vertically reflected image
+        MultiArrayView<2, UInt8> topright = exportArray.subarray(Shape2(w,0), Shape2(2*w, h));
+        reflectImage(imageArray, topright, vertical);
+
+        // reflect the upperhalf horizontally to the lowerhalf
+        MultiArrayView<2, UInt8> upperhalf = exportArray.subarray(Shape2(0,0), Shape2(2*w, h));
+        MultiArrayView<2, UInt8> lowerhalf = exportArray.subarray(Shape2(0,h), 2*info.shape());
+        reflectImage(upperhalf, lowerhalf, horizontal);
+
+        // write image data to the file given as second argument
+        exportImage(exportArray, ImageExportInfo(argv[2]));
+    }
+    // process color image
+    else 
+    {
+        // instantiate arrays for image data and for composite image of appropriate size
+        MultiArray<2, RGBValue<UInt8> > imageArray(info.shape());
+        MultiArray<2, RGBValue<UInt8> > exportArray(2*info.shape());
+
+        // copy image data into array
+        importImage(info, imageArray);
+
+        // topleft corner of composite image contains the original image
+        exportArray.subarray(Shape2(0,0), info.shape()) = imageArray;
+
+        // topright corner contains the vertically reflected image
+        MultiArrayView<2, RGBValue<UInt8> > topright = exportArray.subarray(Shape2(w,0), Shape2(2*w, h));
+        reflectImage(imageArray, topright, vertical);
+
+        // reflect the upperhalf horizontally to the lowerhalf
+        MultiArrayView<2, RGBValue<UInt8> > upperhalf = exportArray.subarray(Shape2(0,0), Shape2(2*w, h));
+        MultiArrayView<2, RGBValue<UInt8> > lowerhalf = exportArray.subarray(Shape2(0,h), 2*info.shape());
+        reflectImage(upperhalf, lowerhalf, horizontal);
+
+        // write image data to the file given as second argument
+        exportImage(exportArray, ImageExportInfo(argv[2]));
+    }
+    return 0;
+}
diff --git a/src/examples/tutorial/conv1.gif b/src/examples/tutorial/conv1.gif
new file mode 100644
index 0000000..fad4d6f
Binary files /dev/null and b/src/examples/tutorial/conv1.gif differ
diff --git a/src/examples/tutorial/conv2.gif b/src/examples/tutorial/conv2.gif
new file mode 100644
index 0000000..a866083
Binary files /dev/null and b/src/examples/tutorial/conv2.gif differ
diff --git a/src/examples/tutorial/conv3.gif b/src/examples/tutorial/conv3.gif
new file mode 100644
index 0000000..402e89c
Binary files /dev/null and b/src/examples/tutorial/conv3.gif differ
diff --git a/src/examples/tutorial/conv4.gif b/src/examples/tutorial/conv4.gif
new file mode 100644
index 0000000..5d6f531
Binary files /dev/null and b/src/examples/tutorial/conv4.gif differ
diff --git a/src/examples/tutorial/dissolve.cxx b/src/examples/tutorial/dissolve.cxx
new file mode 100644
index 0000000..7adb8d3
--- /dev/null
+++ b/src/examples/tutorial/dissolve.cxx
@@ -0,0 +1,62 @@
+#include <vigra/multi_array.hxx>
+#include <vigra/impex.hxx>
+#include <vigra/multi_math.hxx>
+#include <iostream>
+
+using namespace vigra;
+
+int main (int argc, char ** argv) 
+{
+    if(argc != 4)
+    {
+        std::cout << "Usage: " << argv[0] << " infile1 infile2 outfile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    try 
+    {
+        // read the images given as first and second argument
+        ImageImportInfo info1(argv[1]),
+                        info2(argv[2]);
+        
+        // for simplicity, we always use RGB images, even when the inputs are grayscale
+        // (in which case all three channels will be equal)
+        MultiArray<2, RGBValue<UInt8> > imageArray1(info1.shape()),
+                                        imageArray2(info2.shape());
+        
+        importImage(info1, imageArray1);
+        importImage(info2, imageArray2);
+        
+        // calculate size of dissolved image (take the minimum along both axes)
+        Shape2 resultShape = min(info1.shape(), info2.shape());
+        
+        // instantiate array of appropriate size for the dissolved image
+        MultiArray<2, RGBValue<UInt8> > exportArray(resultShape);
+
+        // create subviews for dissolving
+        // the middle parts of the two images will be dissolved
+        Shape2 start1 = (info1.shape() - resultShape) / 2,
+               end1   = start1 + resultShape;
+        MultiArray<2, RGBValue<UInt8> > subImageArray1 = imageArray1.subarray(start1, end1);
+
+        Shape2 start2 = (info2.shape() - resultShape) / 2,
+               end2   = start2 + resultShape;
+        MultiArray<2, RGBValue<UInt8> > subImageArray2 = imageArray2.subarray(start2, end2);
+
+        // dissolve images
+        using namespace multi_math;
+        exportArray = 0.5*subImageArray1 + 0.5*subImageArray2;
+
+        // write image data to the file given as third argument
+        exportImage(exportArray, ImageExportInfo(argv[3]));
+    }
+    catch (std::exception & e) 
+    {
+        // catch any errors that might have occurred and print their reason
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    return 0;
+}
diff --git a/src/examples/tutorial/dissolved.gif b/src/examples/tutorial/dissolved.gif
new file mode 100644
index 0000000..f225cce
Binary files /dev/null and b/src/examples/tutorial/dissolved.gif differ
diff --git a/src/examples/tutorial/dissolved_color.gif b/src/examples/tutorial/dissolved_color.gif
new file mode 100644
index 0000000..d4492b5
Binary files /dev/null and b/src/examples/tutorial/dissolved_color.gif differ
diff --git a/src/examples/tutorial/imageExportInfo_tutorial.cxx b/src/examples/tutorial/imageExportInfo_tutorial.cxx
new file mode 100644
index 0000000..b87e5c7
--- /dev/null
+++ b/src/examples/tutorial/imageExportInfo_tutorial.cxx
@@ -0,0 +1,34 @@
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/stdimage.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra; 
+
+int main(int argc, char ** argv) 
+{
+    // instantiate array for image data of size 160x160 pixels
+    MultiArray<2, UInt8> imageArray(Shape2(160,160));
+
+    // create a black (0) and white (255) checker-board image
+    for (int y = 0; y < imageArray.shape(1); y++) 
+    {
+        // note that the inner loop should go over the first (x-) axis
+        // because elements along the first axis are consecutive in memory
+        for (int x = 0; x < imageArray.shape(0); x++) 
+        {
+            if ((x%20)/10 == (y%20)/10)
+                imageArray(x,y) = 0;
+            else
+                imageArray(x,y) = 255; 
+        }
+    }
+
+    // write image data to "testimage.jpg" and set compression to 70%
+    exportImage(imageArray, ImageExportInfo("testimage.jpg").setCompression("JPEG QUALITY=70"));
+    
+    // if you don't want to set any options in ImageExportInfo, you can simply write
+    exportImage(imageArray, "testimage.gif");
+
+    return 0;
+}
diff --git a/src/examples/tutorial/imageIO_tutorial.cxx b/src/examples/tutorial/imageIO_tutorial.cxx
new file mode 100644
index 0000000..f00b41c
--- /dev/null
+++ b/src/examples/tutorial/imageIO_tutorial.cxx
@@ -0,0 +1,53 @@
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/stdimage.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra;
+
+int main(int argc, char ** argv) 
+{
+    if(argc != 3)
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(grayscale only, supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    try 
+    {
+        char * in_filename  = argv[1];
+        char * out_filename = argv[2];
+        
+        // read image header information from in_filename
+        ImageImportInfo imageInfo(in_filename);
+
+        // instantiate array for image data
+        MultiArray<2, UInt8> imageArray(imageInfo.shape());
+
+        // copy image data from file into array
+        importImage(imageInfo, imageArray);
+        
+        // if you don't need the information from ImageImportInfo, you can also
+        // simply pass the filename (this will resize imageArray internally!)
+        importImage(in_filename, imageArray);
+
+        // set every second horizontal line to black
+        for (int i = 0; i<imageInfo.height(); i+=2) 
+        {
+            imageArray.bind<1>(i) = 0;   
+        }
+
+        // write image data to the file given as second argument
+        exportImage(imageArray, ImageExportInfo(out_filename));
+    }
+    catch (std::exception & e) 
+    {
+        // catch any errors that might have occurred and print their reason
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/src/examples/tutorial/imageImportInfo_tutorial.cxx b/src/examples/tutorial/imageImportInfo_tutorial.cxx
new file mode 100644
index 0000000..25b42ec
--- /dev/null
+++ b/src/examples/tutorial/imageImportInfo_tutorial.cxx
@@ -0,0 +1,37 @@
+#include <iostream>
+#include <vigra/impex.hxx>
+
+int main(int argc, char ** argv) 
+{
+   if(argc != 2)
+    {
+        std::cout << "Usage: " << argv[0] << " infile" << std::endl;
+        std::cout << "(supported formats: " << vigra::impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    try
+    {
+        // read image given as first command-line argument
+        vigra::ImageImportInfo imageInfo(argv[1]);
+
+        // print some information:
+        std::cout << "Image information:\n";
+        std::cout << "  file format: " << imageInfo.getFileType() << std::endl;
+        std::cout << "  width:       " << imageInfo.width() << std::endl;
+        std::cout << "  height:      " << imageInfo.height() << std::endl;
+        std::cout << "  pixel type:  " << imageInfo.getPixelType() << std::endl;
+        std::cout << "  color image: ";
+        if (imageInfo.isColor())    std::cout << "yes (";
+        else                        std::cout << "no  (";
+        std::cout << "number of channels: " << imageInfo.numBands() << ")\n";
+    }
+    catch (std::exception & e) 
+    {
+        // catch any errors that might have occurred (e.g. "file not found") and print their reason
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    return 0;
+}
diff --git a/src/examples/tutorial/invert_tutorial.cxx b/src/examples/tutorial/invert_tutorial.cxx
new file mode 100644
index 0000000..6515c9a
--- /dev/null
+++ b/src/examples/tutorial/invert_tutorial.cxx
@@ -0,0 +1,66 @@
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/impex.hxx>
+#include <vigra/multi_math.hxx>
+
+using namespace vigra;
+
+int main (int argc, char ** argv)
+{
+    if(argc != 3)
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+    
+    try
+    {
+        // use multi_math functions
+        using namespace multi_math;
+        
+        // read image given as first argument
+        ImageImportInfo info(argv[1]);
+
+        // process grayscale image
+        if (info.isGrayscale()) 
+        {
+            // instantiate array for image data
+            MultiArray<2, UInt8> imageArray(info.shape());
+            
+            // import image data into array
+            importImage(info, imageArray);
+            
+            // invert image
+            imageArray = 255-imageArray;
+            
+            // write image data to the file given as second argument
+            exportImage(imageArray, ImageExportInfo(argv[2]));
+        }
+        // process color image
+        else 
+        {
+            // instantiate array for image data
+            MultiArray<2, RGBValue<UInt8> > imageArray(info.shape());
+            
+            // copy image data into array
+            importImage(info, imageArray);
+            
+            // invert image
+            RGBValue<UInt8> temp(255,255,255);
+            imageArray = temp - imageArray;
+            
+            // write image data to the file given as second argument
+            exportImage(imageArray, ImageExportInfo(argv[2]));
+        }
+    }
+    catch (std::exception & e) 
+    {
+        // catch any errors that might have occurred (e.g. "file not found") and print their reason
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/src/examples/tutorial/lenna_color.gif b/src/examples/tutorial/lenna_color.gif
new file mode 100644
index 0000000..36515b6
Binary files /dev/null and b/src/examples/tutorial/lenna_color.gif differ
diff --git a/src/examples/tutorial/lenna_color_small.gif b/src/examples/tutorial/lenna_color_small.gif
new file mode 100644
index 0000000..dc43241
Binary files /dev/null and b/src/examples/tutorial/lenna_color_small.gif differ
diff --git a/src/examples/tutorial/lenna_composite_color.gif b/src/examples/tutorial/lenna_composite_color.gif
new file mode 100644
index 0000000..a8bcdd5
Binary files /dev/null and b/src/examples/tutorial/lenna_composite_color.gif differ
diff --git a/src/examples/tutorial/lenna_gray.gif b/src/examples/tutorial/lenna_gray.gif
new file mode 100644
index 0000000..e8faa53
Binary files /dev/null and b/src/examples/tutorial/lenna_gray.gif differ
diff --git a/src/examples/tutorial/lenna_inverted_color.gif b/src/examples/tutorial/lenna_inverted_color.gif
new file mode 100644
index 0000000..816c9c8
Binary files /dev/null and b/src/examples/tutorial/lenna_inverted_color.gif differ
diff --git a/src/examples/tutorial/lenna_small.gif b/src/examples/tutorial/lenna_small.gif
new file mode 100644
index 0000000..0009766
Binary files /dev/null and b/src/examples/tutorial/lenna_small.gif differ
diff --git a/src/examples/tutorial/lenna_smoothed.gif b/src/examples/tutorial/lenna_smoothed.gif
new file mode 100644
index 0000000..345b03c
Binary files /dev/null and b/src/examples/tutorial/lenna_smoothed.gif differ
diff --git a/src/examples/tutorial/mirror_tutorial.cxx b/src/examples/tutorial/mirror_tutorial.cxx
new file mode 100644
index 0000000..dc03bcd
--- /dev/null
+++ b/src/examples/tutorial/mirror_tutorial.cxx
@@ -0,0 +1,60 @@
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/basicgeometry.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra; 
+
+int main(int argc, char ** argv) 
+{
+    if(argc != 3) 
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(grayscale only, supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+
+    // choose axis to mirror about
+    std::cout << "How to mirror image?\n";
+    std::cout << "1 - top to bottom (= about horizontal axis)\n";
+    std::cout << "2 - left to right (= about vertical axis)\n";
+    int mode;
+    std::cin >> mode;
+
+    try 
+    {
+        ImageImportInfo info(argv[1]);
+        
+        MultiArray<2, UInt8> imageArray(info.shape());
+        importImage(info, imageArray);
+        
+        MultiArray<2, UInt8> newImageArray(info.shape());
+
+        if(mode == 1)
+        {
+            // mirror the image horizontally 
+            // (for didactic reasons, we implement this variant explicitly,
+            //  note that info.height()-1 is equal to the last y-index)
+            for (int y=0; y<info.height(); y++) 
+            {           
+                newImageArray.bind<1>(y) = imageArray.bind<1>(info.height()-1-y);
+            }
+        }
+        else
+        {
+            // mirror the image vertically
+            reflectImage(imageArray, newImageArray, vertical);
+        }
+        
+        exportImage(newImageArray, ImageExportInfo(argv[2]));
+    }
+    catch (std::exception & e) 
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
+
diff --git a/src/examples/tutorial/oi.JPG b/src/examples/tutorial/oi.JPG
new file mode 100644
index 0000000..5d99496
Binary files /dev/null and b/src/examples/tutorial/oi.JPG differ
diff --git a/src/examples/tutorial/oi_small.jpg b/src/examples/tutorial/oi_small.jpg
new file mode 100644
index 0000000..eb6f1c6
Binary files /dev/null and b/src/examples/tutorial/oi_small.jpg differ
diff --git a/src/examples/tutorial/smooth_convolve.cxx b/src/examples/tutorial/smooth_convolve.cxx
new file mode 100644
index 0000000..253dfaa
--- /dev/null
+++ b/src/examples/tutorial/smooth_convolve.cxx
@@ -0,0 +1,116 @@
+#include <vigra/multi_array.hxx>
+#include <vigra/impex.hxx>
+#include <vigra/convolution.hxx>
+#include <iostream>
+
+using namespace vigra;
+
+int main (int argc, char ** argv) 
+{
+    if(argc != 3) 
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+
+    try
+    {
+        // read image given as first argument
+        ImageImportInfo info(argv[1]);
+
+        // choose convolving mode
+        std::cout << "Which mode of convolution?\n";
+        std::cout << "1 - disk average\n";
+        std::cout << "2 - corners of a 3x3-box\n";
+        std::cout << "3 - Gaussian filter\n";
+        std::cout << "4 - separable Gaussian filter (x- and x-dimension separately)\n";
+        int mode;
+        std::cin >> mode;
+        
+        // instantiate convolution kernels
+        Kernel2D<double> kernel2dim;
+        Kernel1D<double> kernel1dim;
+        
+        // initialize kernel
+        switch(mode) 
+        {
+            case 1: 
+                // homogenous averaging within a disk of radius 2
+                kernel2dim.initDisk(2); 
+                break;
+            case 2: 
+                // strange custom-made filter: averaging the corners of a 3x3-box
+                kernel2dim.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = 
+                        0.25, 0.0, 0.25, 
+                        0.0,  0.0, 0.0,
+                        0.25, 0.0, 0.25; 
+                        break;
+            case 3: 
+                // gaussian convolution
+                kernel2dim.initGaussian(1.5);
+                break;
+            case 4: 
+                // separable gaussian convolution
+                kernel1dim.initGaussian(1.5);
+                break;
+            default:
+                vigra_precondition(false, "mode must be between 1 and 4.");
+        }
+           
+        // process grayscale image
+        if (info.isGrayscale()) 
+        {
+            // instantiate arrays for image data and for smoothed image of appropriate size
+            MultiArray<2, float> imageArray(info.shape()),
+                                 exportArray(info.shape());
+
+            // copy image data into array
+            importImage(info, imageArray);
+
+            // convolve image
+            if (mode == 4) 
+            {
+                 convolveImage(imageArray, exportArray, kernel1dim, kernel1dim);
+            }
+            else 
+            {
+                convolveImage(imageArray, exportArray, kernel2dim);
+            }
+
+            // write image data to the file given as second argument
+            exportImage(exportArray, ImageExportInfo(argv[2]));
+        }
+        // process color image
+        else 
+        {
+            // instantiate arrays for image data and for smoothed image of appropriate size
+            MultiArray<2, RGBValue<float> > imageArray(info.shape());
+            MultiArray<2, RGBValue<float> > exportArray(info.shape());
+
+            // copy image data into array
+            importImage(info, imageArray);
+
+            // convolve image
+            if (mode == 4) 
+            {
+                 convolveImage(imageArray, exportArray, kernel1dim, kernel1dim);
+            }
+            else 
+            {
+                convolveImage(imageArray, exportArray, kernel2dim);
+            }
+
+            // write image data to the file given as second argument
+            exportImage(exportArray, ImageExportInfo(argv[2]));
+        }
+    }
+    catch (std::exception & e) 
+    {
+        // catch any errors that might have occurred and print their reason
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    return 0;
+}
diff --git a/src/examples/tutorial/smooth_explicitly.cxx b/src/examples/tutorial/smooth_explicitly.cxx
new file mode 100644
index 0000000..f9bb2d2
--- /dev/null
+++ b/src/examples/tutorial/smooth_explicitly.cxx
@@ -0,0 +1,92 @@
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra;
+
+int main (int argc, char ** argv) 
+{
+    if(argc != 3) 
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        return 1;
+    }
+    
+    try 
+    {
+        // Read the header information of the input image.
+        ImageImportInfo info(argv[1]);
+
+        if (info.isGrayscale())  // Process grayscale image.
+        {   
+            // Instantiate arrays of appropriate size for the original and smoothed image.
+            MultiArray<2, float> inputImage(info.shape()),
+                                 resultImage(info.shape());
+            
+            // Read the input data.
+            importImage(info, inputImage);
+
+            // Smooth image by calculating the mean of a 5x5 window around each pixel.
+            Shape2 current; // the coordinate of the current pixel
+            for(current[1] = 0; current[1] < inputImage.shape(1); ++current[1])
+            {
+                for (current[0] = 0; current[0] < inputImage.shape(0); ++current[0])
+                {
+                    // Compute the corners of the current smoothing window.
+                    // Note:
+                    //    * Near the image border, not all pixels in a 5x5 window are within
+                    //      the image. The max() and min() operations make sure that the
+                    //      window is appropriately truncated (for example, max(Shape2(0), ...) 
+                    //      sets negative coordinates to zero).
+                    //    * By convention, the lower right corner 'windowStop' must be outside the
+                    //      window. Therefore, we have to add 'Shape2(3)' (a vector of 3s) to 'current'. 
+                    //      In contrast, the upper left corner 'windowStart' must be inside the window, 
+                    //      so we only subtract 'Shape2(2)' (a vector of 2s) from 'current'. 
+                    Shape2 windowStart = max(Shape2(0),          current - Shape2(2));
+                    Shape2 windowStop  = min(inputImage.shape(), current + Shape2(3));
+                    
+                    // Create a view to the current window.
+                    MultiArrayView<2, float> window = inputImage.subarray(windowStart, windowStop);
+                    
+                    // Compute and store the average of the current window.
+                    resultImage[current] = window.sum<float>() / window.size();
+                }
+            }
+
+            // Write the result image to the file given as second argument.
+            exportImage(resultImage, ImageExportInfo(argv[2]));
+        }
+        else // process color image
+        {
+            // Everything as before, but the pixel type is now RGBValue<float>
+            MultiArray<2, RGBValue<float> > inputImage(info.shape());
+            MultiArray<2, RGBValue<float> > resultImage(info.shape());
+             
+            importImage(info, inputImage);
+
+            Shape2 current;
+            for(current[1] = 0; current[1] < inputImage.shape(1); ++current[1])
+            {
+                for (current[0] = 0; current[0] < inputImage.shape(0); ++current[0])
+                {
+                    Shape2 windowStart = max(Shape2(0),          current - Shape2(2));
+                    Shape2 windowStop  = min(inputImage.shape(), current + Shape2(3));
+                    
+                    MultiArrayView<2, RGBValue<float> > window = inputImage.subarray(windowStart, windowStop);
+                    
+                    resultImage[current] = window.sum<RGBValue<float> >() / window.size();
+                }
+            }
+
+            exportImage(resultImage, ImageExportInfo(argv[2]));
+        }
+        return 0;
+    }
+    catch (std::exception & e) 
+    {
+        // Catch any errors that might have occurred and print their reason.
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+}
diff --git a/src/examples/tutorial/subimage_tutorial.cxx b/src/examples/tutorial/subimage_tutorial.cxx
new file mode 100644
index 0000000..ea53914
--- /dev/null
+++ b/src/examples/tutorial/subimage_tutorial.cxx
@@ -0,0 +1,70 @@
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/stdimage.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra; 
+
+
+int main(int argc, char ** argv) 
+{
+    if(argc != 3) 
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+        
+        return 1;
+    }
+
+    try 
+    {
+        // read image given as first argument
+        // file type is determined automatically
+        ImageImportInfo info(argv[1]);
+        
+        if(info.isGrayscale()) 
+        {
+            // read image from file
+			MultiArray<2, UInt8> imageArray(info.shape());
+			importImage(info, imageArray);
+
+            // we want to cut out the center of the original image, such that the 
+            // size of the remaining image is half the original
+            Shape2 upperLeft  = info.shape() / 4,
+                   lowerRight = info.shape() - upperLeft;
+        
+            // create subimage around center for output
+            MultiArrayView<2, UInt8> subimage = imageArray.subarray(upperLeft, lowerRight);
+            
+            // write the subimage to the file provided as second command line argument
+            // the file type will be determined from the file name's extension
+            exportImage(subimage, ImageExportInfo(argv[2]));
+        }
+        else 
+        {
+            // read image from file
+			MultiArray<2, RGBValue<UInt8> > imageArray(Shape2(info.shape()));
+			importImage(info, imageArray);
+
+            // we want to cut out the center of the original image, such that the 
+            // size of the remaining image is half the original
+            Shape2 upperLeft  = info.shape() / 4,
+                   lowerRight = info.shape() - upperLeft;
+        
+            // create subimage around center for output
+            MultiArrayView<2, RGBValue<UInt8> > subimage = imageArray.subarray(upperLeft, lowerRight);
+            
+            // write the subimage to the file provided as second command line argument
+            // the file type will be determined from the file name's extension
+            exportImage(subimage, ImageExportInfo(argv[2]));
+        }
+    }
+    catch (std::exception & e)
+    {
+        // catch any errors that might have occurred and print their reason
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/tutorial/testimage.gif b/src/examples/tutorial/testimage.gif
new file mode 100644
index 0000000..a8a736f
Binary files /dev/null and b/src/examples/tutorial/testimage.gif differ
diff --git a/src/examples/tutorial/transpose.cxx b/src/examples/tutorial/transpose.cxx
new file mode 100644
index 0000000..0f85801
--- /dev/null
+++ b/src/examples/tutorial/transpose.cxx
@@ -0,0 +1,76 @@
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/linear_algebra.hxx>
+
+using namespace vigra;
+
+template <class T>
+void print(MultiArrayView<2, T> array) 
+{
+    for(int y=0; y<array.shape(1); ++y)
+    {
+        for(int x=0; x<array.shape(0); ++x)
+            std::cout << array(x, y) << "  ";
+        std::cout << "\n";
+	}
+}
+
+int main (int argc, char ** argv)
+{
+    // create array
+    MultiArray<2, int> base_array(Shape2(4,4));
+    
+    // init array such that pixel values are equal to their x coordinate
+    for (int i = 0; i < base_array.size(); i++) 
+    {
+        base_array[i] = i % base_array.shape(0);
+    }
+
+    std::cout << "base_array:\n";
+    print(base_array);
+
+    // create a transposed array and a transposed view
+    MultiArray<2, int> transarray = base_array.transpose();
+    MultiArrayView<2, int> transarrayView = base_array.transpose();
+
+    std::cout << "transarray:\n";
+    print(transarray);
+    std::cout << "transArrayView:\n";
+    print(transarrayView);
+
+    // set transarray to 5    
+    transarray = 5;
+    std::cout << "base_array after setting transarray to 5\n(no change, since transarray is a copy):\n";
+    print(base_array);
+
+    // set transarrayView to 5
+    transarrayView = 5;
+    std::cout << "base_array after setting transarrayView to 5\n(base_array changes because transarrayView is a view):\n";
+    print(base_array);
+
+    // transposing a 5D array
+    // instantiate 5D array
+    MultiArray<5, int> array5D(Shape5(1,2,3,4,5));
+
+    // print the shape of the original array
+    std::cout << "Shape of array5D: " << array5D.shape() << "\n";
+
+    // transpose array
+    MultiArrayView<5, int> arrayview5D = array5D.transpose();
+
+    // print the shape of transposed array
+    std::cout << "Shape of array5D view after default transpose(): " << arrayview5D.shape() << "\n";
+    
+    // transpose to an explicitly specified axis permutation
+    MultiArrayView<5, int> arrayview5D_permuted = array5D.transpose(Shape5(2,1,3,4,0));
+
+    // print the shape of transposed array
+    std::cout << "Shape of array5D view after user-defined transpose(): " << arrayview5D_permuted.shape() << "\n";
+    std::cout << "    (applied permutation 2 => 0, 1 => 1, 3 => 2, 4 => 3, 0 => 4 to the axes)\n";
+
+    return 0;
+}
+
+
+
+
diff --git a/src/examples/tutorial/transpose_image_tutorial.cxx b/src/examples/tutorial/transpose_image_tutorial.cxx
new file mode 100644
index 0000000..5111661
--- /dev/null
+++ b/src/examples/tutorial/transpose_image_tutorial.cxx
@@ -0,0 +1,53 @@
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/impex.hxx>
+#include <vigra/basicgeometry.hxx>
+
+using namespace vigra; 
+
+int main(int argc, char ** argv)
+{
+    if(argc != 3) 
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(grayscale images only, supported formats: " << impexListFormats() << ")" << std::endl;
+        return 1;
+    }
+    
+    // choose diagonal for transpose
+    std::cout << "Transpose about which diagonal?\n";
+    std::cout << "1 - major\n";
+    std::cout << "2 - minor\n";
+    int mode;
+    std::cin >> mode;
+
+    try 
+    {
+        // read image given as first command line argument
+        MultiArray<2, UInt8> imageArray;
+        importImage(argv[1], imageArray);
+
+        if(mode == 1)
+        {
+            // when transposing about the major diagonal, we can simply
+            // write a transposed view to the file given as second argument
+            exportImage(imageArray.transpose(), argv[2]);
+        }
+        else
+        {
+            // when transposing about the minor diagonal, we need a new
+            // image with reversed shape to hold the transposed data
+            MultiArray<2, UInt8> transposed(reverse(imageArray.shape()));
+            transposeImage(imageArray, transposed, minor);
+            exportImage(transposed, argv[2]);
+        }
+    }
+    catch (std::exception & e) 
+    {
+        // catch any errors that might have occurred and print their reason
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/src/examples/tv.par b/src/examples/tv.par
new file mode 100644
index 0000000..82d2e72
--- /dev/null
+++ b/src/examples/tv.par
@@ -0,0 +1,8 @@
+input_file  cameraman_noise.png
+output_file result_standard_tv.png
+mode    1
+alpha   0.5
+epsilon     0.00001
+histogram_stretch 0
+
+...do not change order or insert additional items above...
\ No newline at end of file
diff --git a/src/examples/voronoi.cxx b/src/examples/voronoi.cxx
new file mode 100644
index 0000000..0435f9c
--- /dev/null
+++ b/src/examples/voronoi.cxx
@@ -0,0 +1,107 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+ 
+
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/random.hxx>
+#include <vigra/distancetransform.hxx>
+#include <vigra/labelimage.hxx>
+#include <vigra/seededregiongrowing.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra; 
+
+int main(int argc, char ** argv)
+{
+    try
+    {
+        int number_of_points = 25;
+        int size = 512;
+        
+        // create input image
+        MultiArray<2, float> in(size, size);
+        
+        MersenneTwister random;
+        for(int i=1; i<=number_of_points; ++i)
+        {
+            // mark a number of points 
+            int x = random.uniformInt(size);
+            int y = random.uniformInt(size);
+            
+            // label each point with a unique number
+            in(x,y) = i;
+        }
+        
+        // create output image and paint it white
+        MultiArray<2, int> out(size, size);
+        out = 255;
+        
+        // in the output image, paint the points black which were 
+        // marked in the input image
+        initImageIf(out, in, 0);
+        
+        // create image to hold the distance transform
+        MultiArray<2, float> distances(size, size);
+        
+        // calculate Euclidean distance transform
+        // all pixels with value 0 are considered background
+        distanceTransform(in, distances, 0, 2);
+        
+        exportImage(distances, ImageExportInfo("distances.gif"));
+        std::cout << "Wrote distance transform (distances.gif)" << std::endl;
+        
+        // initialize statistics functor for region growing
+        ArrayOfRegionStatistics<SeedRgDirectValueFunctor<float> > statistics(number_of_points);
+
+        // perform region growing, starting at the points marked in the input
+        // image; as the feature (first source) image contains the distances,
+        // the will calculate the voronoi regions of these points
+        seededRegionGrowing(distances, in, in, statistics);
+        
+        // in the output image, mark the borders of the voronoi regions black 
+        regionImageToEdgeImage(in, out, 0);
+
+        exportImage(out, ImageExportInfo("voronoi.gif"));
+        std::cout << "Wrote voronoi diagram (voronoi.gif)" << std::endl;
+    }
+    catch (std::exception & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+    
+    return 0;
+}
diff --git a/src/examples/watershed.cxx b/src/examples/watershed.cxx
new file mode 100644
index 0000000..e2b3e70
--- /dev/null
+++ b/src/examples/watershed.cxx
@@ -0,0 +1,143 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#include <iostream>
+#include <vigra/multi_array.hxx>
+#include <vigra/stdimagefunctions.hxx>
+#include <vigra/multi_convolution.hxx>
+#include <vigra/multi_watersheds.hxx>
+#include <vigra/impex.hxx>
+
+using namespace vigra; 
+
+template <class InImage, class OutImage>
+void watershedSegmentation(InImage & in, OutImage & out, double scale)
+{
+    // compute the gradient magnitude as a suitable boundary indicator
+    MultiArray<2, float> gradient(in.shape());
+    gaussianGradientMagnitude(in, gradient, scale);
+    
+    // Compute watershed segmentation using a region growing algorithm with 4-neighborhood.
+    // Use option object to ask the watershed algorithm to compute seeds automatically at 
+    // minima of the boundary indicator.
+    MultiArray<2, unsigned int> labeling(in.shape());
+    unsigned int max_region_label = 
+        watershedsMultiArray(gradient, labeling, DirectNeighborhood,
+                             WatershedOptions().seedOptions(SeedOptions().minima()));
+
+    // Initialize a functor to determine the average gray-value or color
+    // for each region (catchment basin) just found.
+    // define a temporary type that can hold floating point values
+    typedef typename NumericTraits<typename InImage::value_type>::RealPromote
+        TmpType;
+    ArrayOfRegionStatistics<FindAverage<TmpType> > averages(max_region_label);
+
+    // calculate the averages
+    inspectTwoImages(in, labeling, averages);
+
+    // write the averages into the destination image (the functor 'averages'
+    // acts as a look-up table)
+    transformImage(labeling, out, averages);
+
+    // mark the watersheds (region boundaries) black
+    regionImageToEdgeImage(labeling, out,
+                           NumericTraits<typename OutImage::value_type>::zero());
+}
+
+
+int main(int argc, char ** argv)
+{
+    if(argc != 3)
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
+
+        return 1;
+    }
+
+    try
+    {
+        ImageImportInfo info(argv[1]);
+
+        // input width of gradient filter
+        double scale = 1.0;
+        std::cout << "Scale for gradient calculation ? ";
+        std::cin >> scale;
+
+        if(info.isGrayscale())
+        {
+            int w = info.width();
+            int h = info.height();
+
+            MultiArray<2, UInt8> in(w, h), out(w, h);
+            
+            importImage(info, in);
+
+            // perform watershed segmentation on gray image
+            // note that the watershed algorithm usually results in an
+            // oversegmentation (i.e., too many regions), but its boundary
+            // localization is quite good
+            watershedSegmentation(in, out, scale);
+
+            std::cout << "Writing " << argv[2] << std::endl;
+            exportImage(out, ImageExportInfo(argv[2]));
+        }
+        else
+        {
+            int w = info.width();
+            int h = info.height();
+
+            MultiArray<2, RGBValue<UInt8> > in(w, h),  out(w, h);
+            importImage(info, in);
+
+            // perform watershed segmentation on color image
+            // note that the watershed algorithm usually results in an
+            // oversegmentation (i.e., too many regions), but its boundary
+            // localization is quite good
+            watershedSegmentation(in, out, scale);
+
+            std::cout << "Writing " << argv[2] << std::endl;
+            exportImage(out, ImageExportInfo(argv[2]));
+        }
+    }
+    catch (std::exception & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/src/examples/weightedWatersheds.cxx b/src/examples/weightedWatersheds.cxx
new file mode 100644
index 0000000..f079694
--- /dev/null
+++ b/src/examples/weightedWatersheds.cxx
@@ -0,0 +1,204 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2002 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#include <iostream>
+#include "vigra/stdimage.hxx"
+#include "vigra/stdimagefunctions.hxx"
+#include "vigra/functorexpression.hxx"
+#include "vigra/resizeimage.hxx"
+#include "vigra/convolution.hxx"
+#include "vigra/localminmax.hxx"
+#include "vigra/labelimage.hxx"
+#include "vigra/seededregiongrowing.hxx"
+#include "vigra/impex.hxx"
+
+using namespace vigra; 
+
+// define a functor that calsulates the squared magnitude of the gradient
+// given the x- and y- components of the gradient
+struct GradientSquaredMagnitudeFunctor
+{
+    float operator()(float const & g1, float const & g2) const
+    {
+        return g1 * g1 + g2 * g2;
+    }
+
+    float operator()(vigra::RGBValue<float> const & rg1, vigra::RGBValue<float> const & rg2) const
+    {
+        float g1 = rg1.squaredMagnitude();
+        float g2 = rg2.squaredMagnitude();
+
+        return g1 + g2;
+    }
+};
+
+// generic implementation of the watershed algorithm
+template <class InImage, class OutImage>
+void weightedWatershedSegmentation(InImage & in, OutImage & out, double scale, unsigned int oversampling = 1)
+{
+    using namespace vigra::functor;
+    
+    typedef typename vigra::NumericTraits<typename InImage::value_type>::RealPromote
+        TmpType;
+
+    vigra_precondition(oversampling > 0,
+       "weightedWatershedSegmentation(): oversampling must not be zero.");
+    
+    int w = oversampling*(in.width() - 1) + 1;
+    int h = oversampling*(in.height() - 1) + 1;
+
+    vigra::BasicImage<TmpType> gradientx(w, h);
+    vigra::BasicImage<TmpType> gradienty(w, h);
+    vigra::FImage gradientmag(w, h);
+
+    // calculate the x- and y-components of the image gradient at given scale
+    // optionally enlarge the image before
+    if(oversampling > 1)
+    {
+        vigra::BasicImage<TmpType> big(w, h);
+        resizeImageSplineInterpolation(srcImageRange(in), destImageRange(big));
+        gaussianGradient(srcImageRange(big), destImage(gradientx), destImage(gradienty), scale*oversampling);
+    }
+    else
+    {
+        gaussianGradient(srcImageRange(in), destImage(gradientx), destImage(gradienty), scale);
+    }
+    
+    // transform components into gradient magnitude
+    combineTwoImages(srcImageRange(gradientx), srcImage(gradienty),
+                     destImage(gradientmag), GradientSquaredMagnitudeFunctor());
+
+    vigra::IImage labels(w, h);
+    labels = 0;
+
+    // find the local minima of the gradient magnitude
+    // (might be larger than one pixel)
+    extendedLocalMinima(srcImageRange(gradientmag), destImage(labels), 1);
+
+    // label the minima just found
+    int max_region_label =
+        labelImageWithBackground(srcImageRange(labels), destImage(labels),
+                                 false, 0);
+
+    // create a statistics functor for region growing
+    vigra::ArrayOfRegionStatistics<vigra::SeedRgDirectValueFunctor<float> >
+                                          gradstat(max_region_label);
+
+    // perform region growing, starting from the minima of the gradient magnitude;
+    // as the feature (first input) image contains the gradient magnitude,
+    // this calculates the catchment basin of each minimum
+    seededRegionGrowing(srcImageRange(gradientmag), srcImage(labels),
+                        destImage(labels), gradstat, KeepContours);
+
+    out.resize(w,h);
+    
+    // set boundary pixels to the corresponding gradient value, non-boundary pixels to zero
+    combineTwoImages(srcImageRange(gradientmag), srcImage(labels),
+                     destImage(out), 
+                     ifThenElse(Arg2()==Param(0), sqrt(Arg1()), Param(0.0)));
+}
+
+
+int main(int argc, char ** argv)
+{
+    if(argc != 3)
+    {
+        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
+        std::cout << "(supported formats: " << vigra::impexListFormats() << ")" << std::endl;
+
+        return 1;
+    }
+
+    try
+    {
+        vigra::ImageImportInfo info(argv[1]);
+
+        // input width of gradient filter
+        double scale = 1.0;
+        unsigned int oversampling = 1;
+        std::cout << "Scale for gradient calculation ? ";
+        std::cin >> scale;
+        std::cout << "Oversampling ? ";
+        std::cin >> oversampling;
+
+        if(info.isGrayscale())
+        {
+            int w = info.width();
+            int h = info.height();
+
+            vigra::BImage in(w, h);
+            importImage(info, destImage(in));
+
+            vigra::FImage out;
+
+            // perform watershed segmentation on gray image
+            // note that the watershed algorithm usually results in an
+            // oversegmentation (i.e., too many regions), but its boundary
+            // localization is quite good
+            weightedWatershedSegmentation(in, out, scale, oversampling);
+
+            std::cout << "Writing " << argv[2] << std::endl;
+            exportImage(srcImageRange(out), vigra::ImageExportInfo(argv[2]));
+        }
+        else
+        {
+            int w = info.width();
+            int h = info.height();
+
+            vigra::BRGBImage in(w, h);
+            importImage(info, destImage(in));
+
+            vigra::FImage out;
+
+
+            // perform watershed segmentation on color image
+            // note that the watershed algorithm usually results in an
+            // oversegmentation (i.e., too many regions), but its boundary
+            // localization is quite good
+            weightedWatershedSegmentation(in, out, scale, oversampling);
+
+            std::cout << "Writing " << argv[2] << std::endl;
+            exportImage(srcImageRange(out), vigra::ImageExportInfo(argv[2]));
+        }
+    }
+    catch (vigra::StdException & e)
+    {
+        std::cout << e.what() << std::endl;
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/src/images/conv1.gif b/src/images/conv1.gif
new file mode 100644
index 0000000..fad4d6f
Binary files /dev/null and b/src/images/conv1.gif differ
diff --git a/src/images/conv2.gif b/src/images/conv2.gif
new file mode 100644
index 0000000..a866083
Binary files /dev/null and b/src/images/conv2.gif differ
diff --git a/src/images/conv3.gif b/src/images/conv3.gif
new file mode 100644
index 0000000..402e89c
Binary files /dev/null and b/src/images/conv3.gif differ
diff --git a/src/images/conv4.gif b/src/images/conv4.gif
new file mode 100644
index 0000000..5d6f531
Binary files /dev/null and b/src/images/conv4.gif differ
diff --git a/src/images/dissolved.gif b/src/images/dissolved.gif
new file mode 100644
index 0000000..f225cce
Binary files /dev/null and b/src/images/dissolved.gif differ
diff --git a/src/images/dissolved_color.gif b/src/images/dissolved_color.gif
new file mode 100644
index 0000000..d4492b5
Binary files /dev/null and b/src/images/dissolved_color.gif differ
diff --git a/src/images/lenna_color.gif b/src/images/lenna_color.gif
new file mode 100644
index 0000000..36515b6
Binary files /dev/null and b/src/images/lenna_color.gif differ
diff --git a/src/images/lenna_color_small.gif b/src/images/lenna_color_small.gif
new file mode 100644
index 0000000..dc43241
Binary files /dev/null and b/src/images/lenna_color_small.gif differ
diff --git a/src/images/lenna_composite_color.gif b/src/images/lenna_composite_color.gif
new file mode 100644
index 0000000..a8bcdd5
Binary files /dev/null and b/src/images/lenna_composite_color.gif differ
diff --git a/src/images/lenna_gray.gif b/src/images/lenna_gray.gif
new file mode 100644
index 0000000..e8faa53
Binary files /dev/null and b/src/images/lenna_gray.gif differ
diff --git a/src/images/lenna_inverted.gif b/src/images/lenna_inverted.gif
new file mode 100644
index 0000000..82b8dd6
Binary files /dev/null and b/src/images/lenna_inverted.gif differ
diff --git a/src/images/lenna_mirror_horizontal.gif b/src/images/lenna_mirror_horizontal.gif
new file mode 100644
index 0000000..10be4a9
Binary files /dev/null and b/src/images/lenna_mirror_horizontal.gif differ
diff --git a/src/images/lenna_mirror_vertical.gif b/src/images/lenna_mirror_vertical.gif
new file mode 100644
index 0000000..17eeebc
Binary files /dev/null and b/src/images/lenna_mirror_vertical.gif differ
diff --git a/src/images/lenna_small.gif b/src/images/lenna_small.gif
new file mode 100644
index 0000000..0009766
Binary files /dev/null and b/src/images/lenna_small.gif differ
diff --git a/src/images/lenna_smoothed.gif b/src/images/lenna_smoothed.gif
new file mode 100644
index 0000000..345b03c
Binary files /dev/null and b/src/images/lenna_smoothed.gif differ
diff --git a/src/images/lenna_stripes.gif b/src/images/lenna_stripes.gif
new file mode 100644
index 0000000..8ae9413
Binary files /dev/null and b/src/images/lenna_stripes.gif differ
diff --git a/src/images/lenna_sub.gif b/src/images/lenna_sub.gif
new file mode 100644
index 0000000..454487d
Binary files /dev/null and b/src/images/lenna_sub.gif differ
diff --git a/src/images/lenna_transposed_major.gif b/src/images/lenna_transposed_major.gif
new file mode 100644
index 0000000..4dc8dbf
Binary files /dev/null and b/src/images/lenna_transposed_major.gif differ
diff --git a/src/images/lenna_transposed_minor.gif b/src/images/lenna_transposed_minor.gif
new file mode 100644
index 0000000..aa025e3
Binary files /dev/null and b/src/images/lenna_transposed_minor.gif differ
diff --git a/src/images/oi.JPG b/src/images/oi.JPG
new file mode 100644
index 0000000..5d99496
Binary files /dev/null and b/src/images/oi.JPG differ
diff --git a/src/images/oi_small.jpg b/src/images/oi_small.jpg
new file mode 100644
index 0000000..eb6f1c6
Binary files /dev/null and b/src/images/oi_small.jpg differ
diff --git a/src/images/testimage.gif b/src/images/testimage.gif
new file mode 100644
index 0000000..a8a736f
Binary files /dev/null and b/src/images/testimage.gif differ
diff --git a/src/images/testimage.jpg b/src/images/testimage.jpg
new file mode 100644
index 0000000..22d0512
Binary files /dev/null and b/src/images/testimage.jpg differ
diff --git a/src/impex/CMakeLists.txt b/src/impex/CMakeLists.txt
new file mode 100644
index 0000000..80aa035
--- /dev/null
+++ b/src/impex/CMakeLists.txt
@@ -0,0 +1,89 @@
+IF(JPEG_FOUND)
+  ADD_DEFINITIONS(-DHasJPEG)
+  INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR})
+ENDIF(JPEG_FOUND)
+
+IF(PNG_FOUND)
+  ADD_DEFINITIONS(-DHasPNG)
+  INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR})
+ENDIF(PNG_FOUND)
+
+IF(TIFF_FOUND)
+  ADD_DEFINITIONS(-DHasTIFF)
+  INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR})
+ENDIF(TIFF_FOUND)
+
+IF(OPENEXR_FOUND)
+  ADD_DEFINITIONS(-DHasEXR)
+  INCLUDE_DIRECTORIES(${OPENEXR_INCLUDE_DIR})
+ENDIF(OPENEXR_FOUND)
+
+IF(HDF5_FOUND)
+  ADD_DEFINITIONS(-DHasHDF5 ${HDF5_CPPFLAGS})
+  INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIR})
+ENDIF(HDF5_FOUND)
+
+IF (MSVC OR MINGW)
+    IF(NOT VIGRA_STATIC_LIB)
+        ADD_DEFINITIONS(-DVIGRA_DLL)
+    ENDIF()
+ELSEIF(CMAKE_COMPILER_IS_GNUCXX)
+    IF(VIGRA_STATIC_LIB)
+        ADD_DEFINITIONS(-fPIC -DPIC)
+    ENDIF()
+ENDIF ()
+
+ADD_LIBRARY(vigraimpex ${LIBTYPE}
+    bmp.cxx
+    byteorder.cxx
+    codecmanager.cxx
+    exr.cxx
+    gif.cxx
+    hdr.cxx
+    hdf5impex.cxx
+    hdf5_rf_impex.cxx
+    iccjpeg.c
+    imageinfo.cxx
+    jpeg.cxx
+    png.cxx
+    pnm.cxx
+    rgbe.c
+    sifImport.cxx
+    sun.cxx
+    tiff.cxx
+    viff.cxx
+    void_vector.cxx)
+
+set(SOVERSION 5)  # increment this after changing the vigraimpex library
+IF(MACOSX)
+    SET_TARGET_PROPERTIES(vigraimpex PROPERTIES VERSION ${SOVERSION}.${vigra_version} 
+                         SOVERSION ${SOVERSION} INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
+ELSE()
+    SET_TARGET_PROPERTIES(vigraimpex PROPERTIES VERSION ${SOVERSION}.${vigra_version} SOVERSION ${SOVERSION})
+ENDIF() 
+
+IF(JPEG_FOUND)
+  TARGET_LINK_LIBRARIES(vigraimpex ${JPEG_LIBRARIES})
+ENDIF(JPEG_FOUND)
+
+IF(PNG_FOUND)
+  TARGET_LINK_LIBRARIES(vigraimpex ${PNG_LIBRARIES})
+ENDIF(PNG_FOUND)
+
+IF(TIFF_FOUND)
+  TARGET_LINK_LIBRARIES(vigraimpex ${TIFF_LIBRARIES})
+ENDIF(TIFF_FOUND)
+
+IF(OPENEXR_FOUND)
+  TARGET_LINK_LIBRARIES(vigraimpex ${OPENEXR_LIBRARIES})
+ENDIF(OPENEXR_FOUND)
+
+IF(HDF5_FOUND)
+  TARGET_LINK_LIBRARIES(vigraimpex ${HDF5_LIBRARIES})
+ENDIF(HDF5_FOUND)
+
+INSTALL(TARGETS vigraimpex
+        EXPORT vigra-targets
+        RUNTIME DESTINATION bin 
+        LIBRARY DESTINATION lib${LIB_SUFFIX} 
+        ARCHIVE DESTINATION lib${LIB_SUFFIX})
diff --git a/src/impex/auto_file.hxx b/src/impex/auto_file.hxx
new file mode 100644
index 0000000..66a5941
--- /dev/null
+++ b/src/impex/auto_file.hxx
@@ -0,0 +1,84 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEX_AUTO_FILE_HXX
+#define VIGRA_IMPEX_AUTO_FILE_HXX
+
+#include <string>
+#include <cstdio>
+#include "vigra/error.hxx"
+
+namespace vigra
+{
+    // resource aquisition is initialisation
+
+    struct auto_file
+    {
+        FILE * m_file;
+
+        auto_file( const char * name, const char * mode )
+        : m_file(0)
+        {
+            m_file = VIGRA_CSTD::fopen( name, mode );
+            if(!m_file)
+            {
+                std::string msg("Unable to open file '");
+                msg += name;
+                msg += "'.";
+                vigra_precondition(0, msg.c_str());
+            }
+        }
+
+        ~auto_file()
+        {
+            if(m_file)
+                VIGRA_CSTD::fclose(m_file);
+        }
+
+        FILE * get()
+        {
+            return m_file;
+        }
+
+    private:
+
+        // this can not be default constructed, copy constructed or assigned
+        auto_file();
+        auto_file( const auto_file & );
+        auto_file & operator=( const auto_file & );
+    };
+}
+
+#endif // VIGRA_IMPEX_AUTO_FILE_HXX
diff --git a/src/impex/bmp.cxx b/src/impex/bmp.cxx
new file mode 100644
index 0000000..c1458d5
--- /dev/null
+++ b/src/impex/bmp.cxx
@@ -0,0 +1,1120 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002-2004 by Gunnar Kedenburg                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <fstream>
+#include "vigra/config.hxx"
+#include "vigra/sized_int.hxx"
+#include "error.hxx"
+#include "void_vector.hxx"
+#include "byteorder.hxx"
+#include "bmp.hxx"
+
+// Windows Bitmap 3.0
+
+#define BMP_RLE8 1
+#define BMP_RLE4 2
+
+namespace vigra {
+
+CodecDesc BmpCodecFactory::getCodecDesc() const
+{
+    CodecDesc desc;
+
+    // init file type
+    desc.fileType = "BMP";
+
+    // init pixel types
+    desc.pixelTypes.resize(1);
+    desc.pixelTypes[0] = "UINT8";
+
+    // init compression types
+    desc.compressionTypes.resize(1);
+    desc.compressionTypes[0] = "RLE";
+
+    // init magic strings
+    desc.magicStrings.resize(1);
+    desc.magicStrings[0].resize(2);
+    desc.magicStrings[0][0] = 'B';
+    desc.magicStrings[0][1] = 'M';
+
+    // init file extensions
+    desc.fileExtensions.resize(1);
+    desc.fileExtensions[0] = "bmp";
+
+    desc.bandNumbers.resize(2);
+    desc.bandNumbers[0] = 1;
+    desc.bandNumbers[1] = 3;
+
+    return desc;
+}
+
+VIGRA_UNIQUE_PTR<Decoder> BmpCodecFactory::getDecoder() const
+{
+    return VIGRA_UNIQUE_PTR<Decoder>( new BmpDecoder() );
+}
+
+VIGRA_UNIQUE_PTR<Encoder> BmpCodecFactory::getEncoder() const
+{
+    return VIGRA_UNIQUE_PTR<Encoder>( new BmpEncoder() );
+}
+
+struct BmpFileHeader
+{
+    // attributes
+
+    // the magic number
+    UInt16 magic;
+    // size of the whole file
+    UInt32 size;
+    // offset (from this field) to the data
+    UInt32 offset;
+
+    // ctor
+
+    BmpFileHeader();
+
+    // methods
+
+    void from_stream( std::ifstream & stream, byteorder & bo );
+    void to_stream( std::ofstream & stream, byteorder & bo );
+};
+
+BmpFileHeader::BmpFileHeader()
+{
+    // "BM"
+    magic = 0x4D42;
+}
+
+void BmpFileHeader::from_stream( std::ifstream & stream, byteorder & bo )
+{
+    UInt16 filemagic;
+    read_field( stream, bo, filemagic );
+    vigra_precondition( filemagic == magic, "magic value is incorrect." );
+    read_field( stream, bo, size );
+    stream.seekg( 4, std::ios::cur );
+    read_field( stream, bo, offset );
+}
+
+void BmpFileHeader::to_stream( std::ofstream & stream, byteorder & bo )
+{
+    write_field( stream, bo, magic );
+    write_field( stream, bo, size );
+    for( unsigned int i = 0; i < 4; ++i )
+        stream.put(0); // clear reserved fields
+    write_field( stream, bo, offset );
+}
+
+struct BmpInfoHeader
+{
+    // attributes
+
+    // size of this header in the file
+    UInt32 info_size;
+    // image dimensions
+    Int32 width, height;
+    // number of planes, always set to one
+    UInt16 planes;
+    // bits per pixel
+    UInt16 bit_count;
+    // compression type
+    UInt32 compression;
+    // image size in bytes, may be zero for 24 bpp images
+    UInt32 image_size;
+    // image resolution
+    Int32 x_pixels_per_meter, y_pixels_per_meter;
+    // number of used colors, may be zero
+    UInt32 clr_used;
+    // number of important colors, may be zero
+    UInt32 clr_important;
+
+    // methods
+
+    void from_stream( std::ifstream & stream, byteorder & bo );
+    void to_stream( std::ofstream & stream, byteorder & bo );
+};
+
+void BmpInfoHeader::from_stream( std::ifstream & stream, byteorder & bo )
+{
+    const UInt32 info_impl_size = 40;
+    read_field( stream, bo, info_size );
+    vigra_precondition( info_size >= info_impl_size,
+                        "info header has a wrong size" );
+    read_field( stream, bo, width );
+    vigra_precondition( width > 0, "width must be > 0" );
+    read_field( stream, bo, height );
+    vigra_precondition( height > 0, "height must be > 0" );
+    read_field( stream, bo, planes );
+    vigra_precondition( planes == 1, "planes must be 1" );
+    read_field( stream, bo, bit_count );
+    vigra_precondition( bit_count == 1 || bit_count == 4 || bit_count == 8
+                        || bit_count == 24, "illegal bit count" );
+    read_field( stream, bo, compression );
+    read_field( stream, bo, image_size );
+    if(image_size == 0)
+    {
+        image_size = height * width * ((bit_count == 24) ? 3 : 1);
+    }
+    read_field( stream, bo, x_pixels_per_meter );
+    read_field( stream, bo, y_pixels_per_meter );
+    read_field( stream, bo, clr_used );
+    const unsigned int max_colors = 1 << bit_count;
+    vigra_precondition( clr_used <= max_colors,
+                        "used colors field invalid" );
+    read_field( stream, bo, clr_important );
+    vigra_precondition( clr_important <= max_colors,
+                        "important colors field invalid" );
+    // skip any padding
+    stream.seekg( info_size - info_impl_size, std::ios::cur );
+}
+
+void BmpInfoHeader::to_stream( std::ofstream & stream, byteorder & bo )
+{
+    write_field( stream, bo, info_size );
+    write_field( stream, bo, width );
+    write_field( stream, bo, height );
+    write_field( stream, bo, planes = 1 );
+    write_field( stream, bo, bit_count );
+    write_field( stream, bo, compression );
+    write_field( stream, bo, image_size );
+    write_field( stream, bo, x_pixels_per_meter );
+    write_field( stream, bo, y_pixels_per_meter );
+    write_field( stream, bo, clr_used );
+    write_field( stream, bo, clr_important );
+}
+
+struct BmpDecoderImpl
+{
+    // attributes
+
+    // data source
+    std::ifstream stream;
+
+    // bmp headers
+    BmpFileHeader file_header;
+    BmpInfoHeader info_header;
+
+    // image containers
+    void_vector< UInt8 > pixels;
+    void_vector< UInt8 > map;
+
+    int scanline;
+
+    // this flag is figured out from the info header's bit_count
+    // field and the colormap, if there is one.
+    bool grayscale;
+
+    // the data is read when the first scanline is requested.
+    bool data_read;
+
+    // methods
+
+    void read_data ();
+    void read_colormap ();
+    void read_1bit_data ();
+    void read_rle4_data ();
+    void read_4bit_data ();
+    void read_rle8_data ();
+    void read_8bit_data ();
+    void read_rgb_data ();
+
+    // ctor
+
+    BmpDecoderImpl( const std::string & filename );
+};
+
+
+// reads the header.
+BmpDecoderImpl::BmpDecoderImpl( const std::string & filename )
+    :
+#ifdef VIGRA_NEED_BIN_STREAMS
+      stream (filename.c_str (), std::ios::binary),
+#else
+      stream (filename.c_str ()),
+#endif
+      scanline(-1)
+{
+    if( !stream.good() )
+    {
+        std::string msg("Unable to open file '");
+        msg += filename;
+        msg += "'.";
+        vigra_precondition(0, msg.c_str());
+    }
+    byteorder bo( "little endian" );
+
+    // read the header
+    file_header.from_stream( stream, bo );
+    info_header.from_stream( stream, bo );
+
+    // read the map, if there is one, to determine if this is a grayscale
+    // or rgb image.
+    grayscale = false; // default is rgb
+    if (info_header.bit_count != 24)
+        read_colormap ();
+
+    data_read = false;
+}
+
+void BmpDecoderImpl::read_data ()
+{
+    // read (and eventually map) the bands
+    switch (info_header.bit_count) {
+    case 1:
+        read_1bit_data ();
+        break;
+    case 4:
+        if (info_header.compression) {
+            read_rle4_data ();
+        } else {
+            read_4bit_data ();
+        } break;
+    case 8:
+        if (info_header.compression) {
+            read_rle8_data ();
+        } else {
+            read_8bit_data ();
+        } break;
+    case 24:
+        read_rgb_data ();
+        break;
+    }
+    data_read = true;
+}
+
+void BmpDecoderImpl::read_colormap ()
+{
+    const unsigned int num_colors = 1 << info_header.bit_count;
+    map.resize( 3 * num_colors );
+    grayscale = true;
+    for ( unsigned int i = 0; i < num_colors; ++i ) {
+        map[ 3 * i + 2 ] = stream.get();
+        map[ 3 * i + 1 ] = stream.get();
+        map[ 3 * i     ] = stream.get();
+        stream.get(); // skip unused byte
+        grayscale = grayscale && ( map[ 3 * i ] == map[ 3 * i + 1 ] );
+        grayscale = grayscale && ( map[ 3 * i + 1 ] == map[ 3 * i + 2 ] );
+    }
+}
+
+void BmpDecoderImpl::read_1bit_data ()
+{
+    // these are sizes for the final image
+    const unsigned int ncomp = grayscale ? 1 : 3;
+    const unsigned int line_size = info_header.width * ncomp;
+    const unsigned int image_size = info_header.height * line_size;
+    int c = 0;
+
+    // seek to the data
+    stream.seekg( file_header.offset, std::ios::beg );
+
+    // make room for the pixels
+    pixels.resize(image_size);
+
+    // padding after each line (must end on a 32-bit boundary)
+    unsigned int pad_size = ( ( info_header.width + 7 ) / 8 ) % 4;
+    if ( pad_size > 0 )
+        pad_size = 4 - pad_size;
+
+    // setup the base pointer at one line after the end
+    UInt8 * base = pixels.data() + image_size;
+    UInt8 * mover = base;
+
+    // read scanlines from bottom to top
+    for ( int y = info_header.height - 1; y >= 0; --y ) {
+
+        // set the base pointer to the beginning of the line to be read
+        base -= line_size;
+        mover = base;
+
+        // read the line from left to right
+        for ( int x = 0; x < info_header.width; ++x ) {
+
+            // eventually get a new byte from the stream
+            if ( x % 8 == 0 )
+                c = stream.get();
+
+            // get the color bit
+            const UInt8 index = ( c >> ( 7 - ( x % 8 ) ) ) & 0x01;
+
+            // map and assign the pixel
+            const UInt8 * map_base = map.data() + 3 * index;
+            for ( unsigned int i = 0; i < ncomp; ++i )
+                mover[i] = map_base[i];
+            mover += ncomp;
+        }
+
+        // advance to the next 32 bit boundary
+        stream.seekg( pad_size, std::ios::cur );
+    }
+}
+
+void BmpDecoderImpl::read_4bit_data ()
+{
+    // these are sizes for the final image
+    const unsigned int ncomp = grayscale ? 1 : 3;
+    const unsigned int line_size = info_header.width * ncomp;
+    const unsigned int image_size = info_header.height * line_size;
+    int c = 0;
+
+    // seek to the data
+    stream.seekg( file_header.offset, std::ios::beg );
+
+    // make room for the pixels
+    pixels.resize(image_size);
+
+    // padding after each line (must end on a 32-bit boundary)
+    unsigned int pad_size = ( ( info_header.width + 1 ) / 2 ) % 4;
+    if ( pad_size > 0 )
+        pad_size = 4 - pad_size;
+
+    // setup the base pointer at one line after the end
+    UInt8 * base = pixels.data() + image_size;
+    UInt8 * mover = base;
+
+    // read scanlines from bottom to top
+    for ( int y = info_header.height - 1; y >= 0; --y ) {
+
+        // set the base pointer to the beginning of the line to be read
+        base -= line_size;
+        mover = base;
+
+        // read the line from left to right
+        for ( int x = 0; x < info_header.width; ++x ) {
+
+            // eventually get a new byte from the stream
+            if ( x % 2 == 0 )
+                c = stream.get();
+
+            // get the color index
+            const UInt8 index = ( c >> ( 1 - ( x % 2 ) ) ) & 0x0f;
+
+            // map and assign the pixel
+            const UInt8 * map_base = map.data() + 3 * index;
+            for ( unsigned int i = 0; i < ncomp; ++i )
+                mover[i] = map_base[i];
+            mover += ncomp;
+        }
+
+        // advance to the next 32 bit boundary
+        stream.seekg( pad_size, std::ios::cur );
+    }
+}
+
+void BmpDecoderImpl::read_rle4_data ()
+{
+    // these are sizes for the final image
+    const unsigned int ncomp = grayscale ? 1 : 3;
+    const unsigned int line_size = info_header.width * ncomp;
+    const unsigned int image_size = info_header.height * line_size;
+
+    // seek to the data
+    stream.seekg (file_header.offset, std::ios::beg);
+
+    // make room for the pixels
+    pixels.resize (image_size);
+
+    // setup the base pointer at the beginning of the last line.
+    UInt8 * base = pixels.data() + image_size - line_size;
+    UInt8 * mover = base;
+
+    // set the image's background color to black.
+    VIGRA_CSTD::memset (pixels.data (), 0, image_size);
+
+    // read the rle codes one by one.
+    int c1, c2;
+    bool painting = true;
+
+    int x = 0;
+    int y = 0;
+
+    while (painting) {
+
+        c1 = stream.get ();
+        c2 = stream.get ();
+
+        if (c1 == 0x00) {
+
+            // escape sequences
+            switch (c2) {
+            case 0x00:
+                {
+                    // end of line
+
+                    // finished painting this line, move the pointer to
+                    // the beginning of the previous line, which is the
+                    // next bmp line.
+                    // we need to go back to the beginning of this line,
+                    // and another additional line back.
+                    mover -= line_size + ncomp*x;
+
+                    // so we are at the beginning of the next bmp line.
+                    x = 0;
+                    ++y;
+
+                    break;
+                }
+            case 0x01:
+                {
+                    // end of bitmap
+                    painting = false;
+                    break;
+                }
+            case 0x02:
+                {
+                    // "delta" movement
+
+                    // handle the end-of-line case.
+                    if (x == info_header.width) {
+                        mover -= line_size + ncomp*x;
+                        x = 0;
+                        ++y;
+                    }
+
+                    unsigned int dx = stream.get ();
+                    unsigned int dy = stream.get ();
+                    int nx = x + dx;
+
+                    // x movement.
+                    if (nx > info_header.width) {
+                        dy += nx / info_header.width + 1;
+                        nx %= info_header.width;
+                    }
+                    mover += ncomp*(nx-x);
+                    x = nx;
+
+                    // y movement.
+                    if (dy != 0) {
+                        mover -= line_size*dy;
+                        y += dy;
+                    }
+
+                    break;
+                }
+            default:
+
+                // absolute mode. paint the following c2 nibbles.
+                // then, eventually skip one byte to respect 16 bit boundaries.
+                int k = 0;
+
+                while (true) {
+                    const int c = stream.get ();
+
+                    // the high-order and lower-order nibbles
+                    const int nh = (c & 0xf0) >> 4;
+                    const int nl = (c & 0x0f);
+
+                    // paint the the higher-order nibble.
+                    const UInt8 *map_base_h = map.data () + 3*nh;
+                    unsigned int j;
+                    for (j = 0; j < ncomp; ++j)
+                        mover [j] = map_base_h [j];
+                    mover += ncomp;
+                    if (++k >= c2)
+                        break;
+
+                    // paint the lower-order nibble.
+                    const UInt8 *map_base_l = map.data () + 3*nl;
+                    for (j = 0; j < ncomp; ++j)
+                        mover [j] = map_base_l [j];
+                    mover += ncomp;
+                    if (++k >= c2)
+                        break;
+                }
+
+                if (c2 % 2)
+                    stream.get ();
+            }
+
+        } else {
+
+            // plain rle: repeat the next byte mapped, c1 times.
+            // a line break may not happen here.
+            for (int i = 0; i < c1; ++i) {
+                // the high-order and lower-order nibbles
+                const int nh = (c2 & 0xf0) >> 4;
+                const int nl = (c2 & 0x0f);
+                // paint the higher-order nibble.
+                const UInt8 *map_base_h = map.data () + 3*nh;
+                unsigned int j;
+                for (j = 0; j < ncomp; ++j)
+                    mover [j] = map_base_h [j];
+                mover += ncomp;
+                // paint the lower-order nibble.
+                const UInt8 *map_base_l = map.data () + 3*nl;
+                for (j = 0; j < ncomp; ++j)
+                    mover [j] = map_base_l [j];
+                mover += ncomp;
+            }
+            x += c1;
+        }
+    }
+}
+
+void BmpDecoderImpl::read_8bit_data ()
+{
+    // these are sizes for the final image
+    const unsigned int ncomp = grayscale ? 1 : 3;
+    const unsigned int line_size = info_header.width * ncomp;
+    const unsigned int image_size = info_header.height * line_size;
+
+    // seek to the data
+    stream.seekg( file_header.offset, std::ios::beg );
+
+    // make room for the pixels
+    pixels.resize(image_size);
+
+    // padding after each line (must end on a 32-bit boundary)
+    unsigned int pad_size = info_header.width % 4;
+    if ( pad_size > 0 )
+        pad_size = 4 - pad_size;
+
+    // setup the base pointer at one line after the end
+    UInt8 * base = pixels.data() + image_size;
+    UInt8 * mover = base;
+
+    // read scanlines from bottom to top
+    for ( int y = info_header.height - 1; y >= 0; --y ) {
+
+        // set the base pointer to the beginning of the line to be read
+        base -= line_size;
+        mover = base;
+
+        // read the line from left to right
+        for ( int x = 0; x < info_header.width; ++x ) {
+
+            // get the color byte
+            const int index = stream.get();
+
+            // map and assign the pixel
+            const UInt8 * map_base = map.data() + 3 * index;
+            for ( unsigned int i = 0; i < ncomp; ++i )
+                mover[i] = map_base[i];
+            mover += ncomp;
+        }
+
+        // advance to the next 32 bit boundary
+        stream.seekg( pad_size, std::ios::cur );
+    }
+}
+
+void BmpDecoderImpl::read_rle8_data ()
+{
+    // these are sizes for the final image
+    const unsigned int ncomp = grayscale ? 1 : 3;
+    const unsigned int line_size = info_header.width * ncomp;
+    const unsigned int image_size = info_header.height * line_size;
+
+    // seek to the data
+    stream.seekg (file_header.offset, std::ios::beg);
+
+    // make room for the pixels
+    pixels.resize (image_size);
+
+    // setup the base pointer at the beginning of the last line.
+    UInt8 * base = pixels.data() + image_size - line_size;
+    UInt8 * mover = base;
+
+    // set the image's background color to black.
+    VIGRA_CSTD::memset (pixels.data (), 0, image_size);
+
+    // read the rle codes one by one.
+    int c1, c2;
+    bool painting = true;
+
+    int x = 0;
+    int y = 0;
+
+    while (painting) {
+
+        c1 = stream.get ();
+        c2 = stream.get ();
+
+        if (c1 == 0x00) {
+
+            // escape sequences
+            switch (c2) {
+            case 0x00:
+                {
+                    // end of line
+
+                    // finished painting this line, move the pointer to
+                    // the beginning of the previous line, which is the
+                    // next bmp line.
+                    // we need to go back to the beginning of this line,
+                    // and another additional line back.
+                    mover -= line_size + ncomp*x;
+
+                    // so we are at the beginning of the next bmp line.
+                    x = 0;
+                    ++y;
+
+                    break;
+                }
+            case 0x01:
+                {
+                    // end of bitmap
+                    painting = false;
+                    break;
+                }
+            case 0x02:
+                {
+                    // "delta" movement
+
+                    // handle the end-of-line case.
+                    if (x == info_header.width) {
+                        mover -= line_size + ncomp*x;
+                        x = 0;
+                        ++y;
+                    }
+
+                    unsigned int dx = stream.get ();
+                    unsigned int dy = stream.get ();
+                    int nx = x + dx;
+
+                    // x movement.
+                    if (nx > info_header.width) {
+                        dy += nx / info_header.width + 1;
+                        nx %= info_header.width;
+                    }
+                    mover += ncomp*(nx-x);
+                    x = nx;
+
+                    // y movement.
+                    if (dy != 0) {
+                        mover -= line_size*dy;
+                        y += dy;
+                    }
+                    break;
+                }
+            default:
+
+                // absolute mode. paint the following c2 bytes.
+                // then, eventually skip one byte to respect 16 bit boundaries.
+                for (int k = 0; k < c2; ++k) {
+                    const int c = stream.get ();
+                    const UInt8 *map_base = map.data () + 3*c;
+                    for (unsigned int j = 0; j < ncomp; ++j)
+                        mover [j] = map_base [j];
+                    mover += ncomp;
+                }
+                if (c2 % 2)
+                    stream.get ();
+            }
+
+        } else {
+
+            // plain rle: repeat c2 mapped, c1 times.
+            // a line break may not happen here.
+            for (int i = 0; i < c1; ++i) {
+                const UInt8 *map_base = map.data () + 3*c2;
+                for (unsigned int j = 0; j < ncomp; ++j)
+                    mover [j] = map_base [j];
+                mover += ncomp;
+            }
+            x += c1;
+        }
+    }
+}
+
+void BmpDecoderImpl::read_rgb_data ()
+{
+    const unsigned int line_size = 3 * info_header.width;
+    const unsigned int image_size = info_header.height * line_size;
+
+    // seek to the data
+    stream.seekg( file_header.offset, std::ios::beg );
+
+    // make room for the pixels
+    pixels.resize(image_size);
+
+    // padding after each scanline.
+    // citing Kevin D. Quitt's mail to wotsit.org:
+    // In RGB encoding (no compression), when using 8 bits per pixel, lines
+    // must start on a long-word boundary (i.e., low two bits zero).
+    const unsigned int pad_size = (line_size % 4) ? 4 - (line_size % 4) : 0;
+
+    // setup the base pointer at one line after the end
+    UInt8 * base = pixels.data() + image_size;
+    UInt8 * mover;
+
+    // read scanlines from bottom to top
+    for ( int y = info_header.height - 1; y >= 0; --y ) {
+
+        // set the base pointer to the beginning of the line to be read
+        base -= line_size;
+        mover = base;
+
+        // read the line from left to right
+        for ( int x = 0; x < info_header.width; ++x ) {
+            mover[2] = stream.get(); // B
+            mover[1] = stream.get(); // G
+            mover[0] = stream.get(); // R
+            mover += 3;
+        }
+
+        // advance to the next 32 bit boundary
+        stream.seekg( pad_size, std::ios::cur );
+    }
+}
+
+void BmpDecoder::init( const std::string & filename )
+{
+    pimpl = new BmpDecoderImpl( filename.c_str() );
+}
+
+BmpDecoder::~BmpDecoder()
+{
+    delete pimpl;
+}
+
+std::string BmpDecoder::getFileType() const
+{
+    return "BMP";
+}
+
+unsigned int BmpDecoder::getWidth() const
+{
+    return pimpl->info_header.width;
+}
+
+unsigned int BmpDecoder::getHeight() const
+{
+    return pimpl->info_header.height;
+}
+
+unsigned int BmpDecoder::getNumBands() const
+{
+    return pimpl->grayscale ? 1 : 3;
+}
+
+std::string BmpDecoder::getPixelType() const
+{
+    return "UINT8";
+}
+
+unsigned int BmpDecoder::getOffset() const
+{
+    return pimpl->grayscale ? 1 : 3;
+}
+
+const void * BmpDecoder::currentScanlineOfBand( unsigned int band ) const
+{
+    if (!pimpl->data_read)
+        pimpl->read_data ();
+    return pimpl->pixels.data() + band
+        + pimpl->scanline * ( pimpl->grayscale ? 1 : 3 )
+        * pimpl->info_header.width;
+}
+
+void BmpDecoder::nextScanline()
+{
+    ++(pimpl->scanline);
+}
+
+void BmpDecoder::close() {}
+
+void BmpDecoder::abort() {}
+
+struct BmpEncoderImpl
+{
+    // attributes
+
+    // bmp headers
+    BmpFileHeader file_header;
+    BmpInfoHeader info_header;
+
+    // output stream
+    byteorder bo;
+    std::ofstream stream;
+
+    // image container
+    void_vector< UInt8 > pixels;
+
+    int scanline;
+
+    // this flag is set when the number of bands is set to one
+    bool grayscale;
+
+    // finalized settings
+    bool finalized;
+
+    // ctor
+
+    BmpEncoderImpl( const std::string & );
+
+    // methods
+
+    void finalize();
+    void write();
+    void write_colormap();
+    void write_8bit_data();
+    void write_rgb_data();
+};
+
+BmpEncoderImpl::BmpEncoderImpl( const std::string & filename )
+    : bo( "little endian" ),
+#ifdef VIGRA_NEED_BIN_STREAMS
+      stream( filename.c_str(), std::ios::binary ),
+#else
+      stream( filename.c_str() ),
+#endif
+      scanline(0), finalized(false)
+{
+    if( !stream.good() )
+    {
+        std::string msg("Unable to open file '");
+        msg += filename;
+        msg += "'.";
+        vigra_precondition(0, msg.c_str());
+    }
+}
+
+void BmpEncoderImpl::finalize()
+{
+    if ( grayscale ) {
+
+        unsigned int line_size = 3 * info_header.width;
+        unsigned int pad_size = info_header.width % 4;
+        if ( pad_size > 0 )
+            pad_size = 4 - pad_size;
+        line_size += pad_size;
+        const unsigned int cmap_size = 4 * 256;
+        file_header.size = 10 + 40 + cmap_size
+            + line_size * info_header.height;
+        file_header.offset = 10 + 40 + 4 + cmap_size;
+        info_header.info_size = 40;
+        info_header.planes = 1;
+        info_header.bit_count = 8;
+        info_header.compression = 0;
+        info_header.image_size = line_size * info_header.height;
+        info_header.x_pixels_per_meter = 0;
+        info_header.y_pixels_per_meter = 0;
+        info_header.clr_used = 256;
+        info_header.clr_important = 256;
+
+    } else {
+
+        // write the header fields
+        file_header.size = 10 + 40
+            + 3 * info_header.width * info_header.height;
+        file_header.offset = 10 + 40 + 4;
+        info_header.info_size = 40;
+        info_header.planes = 1;
+        info_header.bit_count = 24;
+        info_header.compression = 0;
+        info_header.image_size = 0;
+        info_header.x_pixels_per_meter = 0;
+        info_header.y_pixels_per_meter = 0;
+        info_header.clr_used = 0;
+        info_header.clr_important = 0;
+    }
+
+    // resize the vector, now that width and height are clear
+    pixels.resize( ( grayscale ? 1 : 3 ) * info_header.width * info_header.height );
+
+    // ok, finalize.
+    finalized = true;
+}
+
+void BmpEncoderImpl::write()
+{
+    // write the headers
+    file_header.to_stream( stream, bo );
+    info_header.to_stream( stream, bo );
+
+    if (grayscale) {
+        write_colormap();
+        write_8bit_data();
+    } else {
+        write_rgb_data();
+    }
+}
+
+void BmpEncoderImpl::write_colormap()
+{
+    const unsigned int num_colors = 256;
+    for ( unsigned int i = 0; i < num_colors; ++i ) {
+        const int c = i;
+        stream.put(c);
+        stream.put(c);
+        stream.put(c);
+        stream.put(0); // skip unused byte
+    }
+}
+
+void BmpEncoderImpl::write_8bit_data()
+{
+    const unsigned int line_size = info_header.width;
+    const unsigned int image_size = info_header.height * line_size;
+    unsigned int pad_size = info_header.width % 4;
+    if ( pad_size > 0 )
+        pad_size = 4 - pad_size;
+
+    UInt8 * base = pixels.data() + image_size;
+    UInt8 * mover = base;
+
+    // write scanlines, the scanlines are already in bottom-to-top
+    // order.
+    for ( int y = 0; y < info_header.height; ++y ) {
+
+        // set the base pointer to the beginning of the line to be read
+        base -= line_size;
+        mover = base;
+
+        // write the line from left to right
+        for ( int x = 0; x < info_header.width; ++x ) {
+            stream.put(*mover);
+            ++mover;
+        }
+
+        // pad
+        for ( unsigned int p = 0; p < pad_size; ++p )
+            stream.put(0);
+    }
+}
+
+void BmpEncoderImpl::write_rgb_data()
+{
+    const unsigned int line_size = 3 * info_header.width;
+    const unsigned int image_size = info_header.height * line_size;
+    const unsigned int pad_size = (line_size % 4) ? 4 - (line_size % 4) : 0;
+
+    UInt8 * base = pixels.data() + image_size;
+    UInt8 * mover = base;
+
+    // write scanlines, the scanlines are already in bottom-to-top
+    // order.
+    for ( int y = 0; y < info_header.height; ++y ) {
+
+        // set the base pointer to the beginning of the line to be read
+        base -= line_size;
+        mover = base;
+
+        // write the line from left to right
+        for ( int x = 0; x < info_header.width; ++x ) {
+            stream.put(mover[2]); // B
+            stream.put(mover[1]); // G
+            stream.put(mover[0]); // R
+            mover += 3;
+        }
+
+        // pad
+        for ( unsigned int p = 0; p < pad_size; ++p )
+        stream.put(0);
+    }
+}
+
+void BmpEncoder::init( const std::string & filename )
+{
+    pimpl = new BmpEncoderImpl(filename);
+}
+
+BmpEncoder::~BmpEncoder()
+{
+    delete pimpl;
+}
+
+std::string BmpEncoder::getFileType() const
+{
+    return "BMP";
+}
+
+void BmpEncoder::setWidth( unsigned int width )
+{
+    VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+    pimpl->info_header.width = width;
+}
+
+void BmpEncoder::setHeight( unsigned int height )
+{
+    VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+    pimpl->info_header.height = height;
+}
+
+void BmpEncoder::setNumBands( unsigned int bands )
+{
+    VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+    vigra_precondition( ( bands == 1 ) || ( bands == 3 ),
+                        "bmp supports only rgb and grayscale images" );
+    pimpl->grayscale = ( bands == 1 );
+}
+
+void BmpEncoder::setCompressionType( const std::string & /* comp */, int /* quality */)
+{
+    VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+}
+
+void BmpEncoder::setPixelType( const std::string & pixelType )
+{
+    VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+    vigra_precondition( pixelType == "UINT8",
+                        "bmp supports only the UINT8 pixeltype" );
+}
+
+unsigned int BmpEncoder::getOffset() const
+{
+    return pimpl->grayscale ? 1 : 3;
+}
+
+void BmpEncoder::finalizeSettings()
+{
+    VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+    pimpl->finalize();
+}
+
+void * BmpEncoder::currentScanlineOfBand( unsigned int band )
+{
+    if (pimpl->grayscale) {
+        const unsigned int row_stride = pimpl->info_header.width;
+        return pimpl->pixels.data() + ( row_stride * pimpl->scanline );
+    } else {
+        const unsigned int row_stride = 3 * pimpl->info_header.width;
+        return pimpl->pixels.data() + ( row_stride * pimpl->scanline ) + band;
+    }
+}
+
+void BmpEncoder::nextScanline()
+{
+    ++(pimpl->scanline);
+}
+
+void BmpEncoder::close()
+{
+    pimpl->write();
+}
+
+void BmpEncoder::abort() {}
+}
diff --git a/src/impex/bmp.hxx b/src/impex/bmp.hxx
new file mode 100644
index 0000000..5711618
--- /dev/null
+++ b/src/impex/bmp.hxx
@@ -0,0 +1,107 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEX_BMP_HXX
+#define VIGRA_IMPEX_BMP_HXX
+
+#include "vigra/codec.hxx"
+
+// Windows Bitmap 3.0
+
+namespace vigra {
+
+    struct BmpDecoderImpl;
+    struct BmpEncoderImpl;
+
+    struct BmpCodecFactory : public CodecFactory
+    {
+        CodecDesc getCodecDesc() const;
+        VIGRA_UNIQUE_PTR<Decoder> getDecoder() const;
+        VIGRA_UNIQUE_PTR<Encoder> getEncoder() const;
+    };
+
+    class BmpDecoder : public Decoder
+    {
+        BmpDecoderImpl * pimpl;
+
+    public:
+
+        BmpDecoder() : pimpl(0) {}
+
+        ~BmpDecoder();
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        std::string getPixelType() const;
+
+        unsigned int getWidth() const;
+        unsigned int getHeight() const;
+        unsigned int getNumBands() const;
+        unsigned int getOffset() const;
+
+        const void * currentScanlineOfBand( unsigned int ) const;
+        void nextScanline();
+    };
+
+    class BmpEncoder : public Encoder
+    {
+        BmpEncoderImpl * pimpl;
+
+    public:
+        BmpEncoder() : pimpl(0) {}
+
+        ~BmpEncoder();
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        unsigned int getOffset() const;
+
+        void setWidth( unsigned int );
+        void setHeight( unsigned int );
+        void setNumBands( unsigned int );
+        void setCompressionType( const std::string &, int = -1 );
+        void setPixelType( const std::string & );
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int );
+        void nextScanline();
+    };
+}
+
+#endif // VIGRA_IMPEX_BMP_HXX
diff --git a/src/impex/byteorder.cxx b/src/impex/byteorder.cxx
new file mode 100644
index 0000000..55a5b9d
--- /dev/null
+++ b/src/impex/byteorder.cxx
@@ -0,0 +1,87 @@
+/************************************************************************/
+/*                                                                      */
+/*      Copyright 2002-2004 by Ullrich Koethe and Gunnar Kedenburg      */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <algorithm>
+#include <stdexcept>
+#include "byteorder.hxx"
+#include "vigra/sized_int.hxx"
+
+namespace vigra
+{
+    const byteorder::host byteorder::m_host;
+
+    byteorder::host::host()
+    {
+        // byteorder check: if the first byte is the least significant,
+        // we have little endian byteorder.
+        UIntBiggest testint = 0x01;
+        UInt8 * testchar = reinterpret_cast< UInt8 * >(&testint);
+        if ( testchar[0] == 0x01 )
+            m_string = "little endian";
+        else
+            m_string = "big endian";
+    }
+
+    const std::string & byteorder::host::get() const
+    {
+        return m_string;
+    }
+
+    const std::string & byteorder::get_host_byteorder() const
+    {
+        return m_host.get();
+    }
+
+    byteorder::byteorder()
+    {
+        set( m_host.get() );
+    }
+
+    byteorder::byteorder( const std::string & s )
+    {
+        set(s);
+    }
+
+    const std::string & byteorder::get() const
+    {
+        return m_string;
+    }
+
+    void byteorder::set( const std::string & s )
+    {
+        m_string = s;
+        native = get_host_byteorder() == s;
+    }
+}
diff --git a/src/impex/byteorder.hxx b/src/impex/byteorder.hxx
new file mode 100644
index 0000000..41b8e53
--- /dev/null
+++ b/src/impex/byteorder.hxx
@@ -0,0 +1,181 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_BYTEORDER_HXX
+#define VIGRA_BYTEORDER_HXX
+
+#include <vector>
+#include <memory>
+#include <string>
+#include <fstream>
+#include <algorithm>
+#include "vigra/sized_int.hxx"
+
+namespace vigra
+{
+    class byteorder
+    {
+        class host
+        {
+            std::string m_string;
+
+        public:
+            
+            // ctor, dtor
+
+            host();
+
+            // methods
+
+            const std::string & get() const;
+        };
+
+        // attributes
+
+        static const host m_host;
+
+        // data byte order, can be changed
+
+        std::string m_string;
+        bool native;
+
+        // delegation methods
+
+        template< class T >
+        void reversebytes( T & x ) const
+        {
+            const size_t n = sizeof(T);
+            UInt8 t[n];
+            UInt8 * c = reinterpret_cast< UInt8 * >(&x);
+            size_t i;
+            for( i = 0; i < n; ++i )
+                t[i] = c[ n - 1 - i ];
+            for( i = 0; i < n; ++i )
+                c[i] = t[i];
+        }
+
+    public:
+
+        // ctor, dtor
+
+        byteorder(); // uses the host byteorder
+        byteorder( const std::string & );
+
+        // methods
+
+        void set( const std::string & );
+        const std::string & get() const;
+        const std::string & get_host_byteorder() const;
+
+        template< class T >
+        void convert_to_host( T & x ) const
+        {
+            if (!native)
+                reversebytes(x);
+        }
+
+        template< class T >
+        void convert_to_host( T * x, size_t num ) const
+        {
+            if (!native)
+                for( size_t i = 0; i < num; ++i )
+                    reversebytes(x[i]);
+        }
+
+        template< class T >
+        void convert_from_host( T & x ) const
+        {
+            if (!native)
+                reversebytes(x);
+        }
+
+        template< class T >
+        void convert_from_host( T * x, size_t num ) const
+        {
+            if (!native)
+                for( size_t i = 0; i < num; ++i )
+                    reversebytes(x[i]);
+        }
+
+        void convert_to_host( char & ) const {}
+        void convert_to_host( Int8 & ) const {}
+        void convert_to_host( UInt8 & ) const {}
+
+        void convert_to_host( char * , size_t) const {}
+        void convert_to_host( Int8 * , size_t) const {}
+        void convert_to_host( UInt8 * , size_t) const {}
+
+        void convert_from_host( char & ) const {}
+        void convert_from_host( Int8 & ) const {}
+        void convert_from_host( UInt8 & ) const {}
+
+        void convert_from_host( char * , size_t) const {}
+        void convert_from_host( Int8 * , size_t) const {}
+        void convert_from_host( UInt8 * , size_t) const {}
+    };
+
+    template< class T >
+    void read_field( std::ifstream & stream, const byteorder & bo, T & x )
+    {
+        stream.read( reinterpret_cast< char * >(&x), sizeof(T) );
+        bo.convert_to_host(x);
+    }
+
+    template< class T >
+    void read_array( std::ifstream & stream, const byteorder & bo, T * x,
+                     size_t num )
+    {
+        stream.read( reinterpret_cast< char * >(x), static_cast<std::streamsize>(sizeof(T) * num) );
+        bo.convert_to_host( x, num );
+    }
+
+    template< class T >
+    void write_field( std::ofstream & stream, const byteorder & bo, T t )
+    {
+        bo.convert_from_host(t);
+        stream.write( reinterpret_cast< char * >(&t), sizeof(T) );
+    }
+
+    template< class T >
+    void write_array( std::ofstream & stream, const byteorder & bo,
+                      const T * x, size_t num )
+    {
+        for( size_t i = 0; i < num; ++i )
+            write_field( stream, bo, x[i] );
+    }
+
+} // namespace vigra
+
+#endif // VIGRA_BYTEORDER_HXX
diff --git a/src/impex/codecmanager.cxx b/src/impex/codecmanager.cxx
new file mode 100644
index 0000000..6468819
--- /dev/null
+++ b/src/impex/codecmanager.cxx
@@ -0,0 +1,393 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2001-2002 by Gunnar Kedenburg                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <fstream>
+#include <algorithm>
+#include <cctype> // std::tolower
+#ifdef DEBUG
+#include <iostream>
+#endif
+
+#include "vigra/config.hxx"
+#include "vigra/error.hxx"
+#include "codecmanager.hxx"
+
+// the codecs
+#include "jpeg.hxx"
+#include "tiff.hxx"
+#include "viff.hxx"
+#include "sun.hxx"
+#include "png.hxx"
+#include "pnm.hxx"
+#include "bmp.hxx"
+#include "gif.hxx"
+#include "hdr.hxx"
+#include "exr.hxx"
+
+namespace vigra
+{
+    // singleton pattern
+    CodecManager & CodecManager::manager()
+    {
+        static CodecManager manager;
+        return manager;
+    }
+
+    CodecManager::CodecManager()
+    {
+#ifdef HasPNG
+        import( new PngCodecFactory() );
+#endif
+#ifdef HasJPEG
+        import( new JPEGCodecFactory() );
+#endif
+#ifdef HasTIFF
+        import( new TIFFCodecFactory() );
+#endif
+#ifdef HasEXR
+        import( new ExrCodecFactory() );
+#endif
+        import( new SunCodecFactory() );
+        import( new PnmCodecFactory() );
+        import( new ViffCodecFactory() );
+        import( new BmpCodecFactory() );
+        import( new GIFCodecFactory() );
+        import( new HDRCodecFactory() );
+    }
+
+    CodecManager::~CodecManager() {
+       // release previously allocated codecs
+       // (use erase ideom similar to
+       // S. Meyers' "Effective STL", Item 9)
+       for (std::map< std::string, CodecFactory * >::iterator i
+             = factoryMap.begin();
+            i != factoryMap.end();
+            /* nothing */ ) {
+         delete (*i).second;
+         factoryMap.erase(i++);
+       }
+    }
+
+    // add an encoder to the stores
+    void CodecManager::import( CodecFactory * cf )
+    {
+        CodecDesc desc = cf->getCodecDesc();
+
+        // fill extension map
+        const std::vector<std::string> & ext = desc.fileExtensions;
+        typedef std::vector<std::string>::const_iterator iter_type;
+        for( iter_type iter = ext.begin(); iter < ext.end(); ++iter )
+            extensionMap[*iter] = desc.fileType;
+
+        // fill magic vector
+        for( VIGRA_CSTD::size_t i = 0; i < desc.magicStrings.size(); ++i )
+            magicStrings.push_back( std::pair<std::vector<char>, std::string>
+                                    ( desc.magicStrings[i],desc.fileType ) );
+        // fill factory map
+        factoryMap[desc.fileType] = cf;
+    }
+
+    // find out which pixel types a given codec supports
+    std::vector<std::string>
+    CodecManager::queryCodecPixelTypes( const std::string & filetype ) const
+    {
+        std::map< std::string, CodecFactory * >::const_iterator result
+            = factoryMap.find( filetype );
+        std::string message("queryCodecPixelTypes(): codec '");
+        message += filetype + "' does not exist";
+        vigra_precondition( result != factoryMap.end(), message.c_str());
+
+        return result->second->getCodecDesc().pixelTypes;
+    }
+
+    // find out which pixel types a given codec supports
+    std::vector<int>
+    CodecManager::queryCodecBandNumbers( const std::string & filetype ) const
+    {
+        std::map< std::string, CodecFactory * >::const_iterator result
+            = factoryMap.find( filetype );
+        vigra_precondition( result != factoryMap.end(),
+        "the codec that was queried for its pixeltype does not exist" );
+
+        return result->second->getCodecDesc().bandNumbers;
+    }
+
+    // find out if a given file type is supported
+    bool CodecManager::fileTypeSupported( const std::string & fileType )
+    {
+        std::map< std::string, CodecFactory * >::const_iterator search
+            = factoryMap.find( fileType );
+        return ( search != factoryMap.end() );
+    }
+
+    // find out which file types are supported
+    std::vector<std::string> CodecManager::supportedFileTypes()
+    {
+        std::vector<std::string> fileTypes;
+        std::map< std::string, CodecFactory * >::const_iterator iter
+            = factoryMap.begin();
+        while ( iter != factoryMap.end() ) {
+            fileTypes.push_back( iter->first );
+            ++iter;
+        }
+        std::sort(fileTypes.begin(), fileTypes.end());
+        return fileTypes;
+    }
+
+    // find out which file extensions are supported
+    std::vector<std::string> CodecManager::supportedFileExtensions()
+    {
+        std::vector<std::string> fileExtensions;
+        std::map< std::string, std::string >::const_iterator iter
+            = extensionMap.begin();
+        while ( iter != extensionMap.end() ) {
+            fileExtensions.push_back( iter->first );
+            ++iter;
+        }
+        std::sort(fileExtensions.begin(), fileExtensions.end());
+        return fileExtensions;
+    }
+
+    std::string
+    CodecManager::getFileTypeByMagicString( const std::string & filename )
+        const
+    {
+        // support for reading the magic string from stdin has been dropped
+        // it was not guaranteed to work by the Standard
+
+        // get the magic string
+        const unsigned int magiclen = 4;
+        char fmagic[magiclen];
+#ifdef VIGRA_NEED_BIN_STREAMS
+        std::ifstream stream(filename.c_str(), std::ios::binary);
+#else
+        std::ifstream stream(filename.c_str());
+#endif
+        if(!stream.good())
+        {
+            std::string msg("Unable to open file '");
+            msg += filename;
+            msg += "'.";
+            vigra_precondition(0, msg.c_str());
+        }
+        stream.read( fmagic, magiclen );
+        stream.close();
+
+        // compare with the known magic strings
+        typedef std::vector< std::pair< std::vector<char>, std::string > >
+            magic_type;
+        for( magic_type::const_iterator iter = magicStrings.begin();
+             iter < magicStrings.end(); ++iter ) {
+            const std::vector<char> & magic = iter->first;
+            if ( std::equal( magic.begin(), magic.end(), fmagic ) )
+                return iter->second;
+        }
+
+        // did not find a matching string
+        return std::string();
+    }
+
+    // look up decoder from the list, then return it
+    VIGRA_UNIQUE_PTR<Decoder>
+    CodecManager::getDecoder( const std::string & filename,
+                              const std::string & filetype,
+                              unsigned int imageindex ) const
+    {
+        std::string fileType = filetype;
+
+        if ( fileType == "undefined" ) {
+
+            fileType = getFileTypeByMagicString(filename);
+            vigra_precondition( !fileType.empty(),
+                                "did not find a matching file type." );
+
+#ifdef DEBUG
+            std::cerr << "detected " << fileType
+                      << " file format by magicstring of " << filename
+                      << std::endl;
+#endif
+        }
+
+        // return a codec factory by the file type
+        std::map< std::string, CodecFactory * >::const_iterator search
+            = factoryMap.find(fileType);
+        vigra_precondition( search != factoryMap.end(),
+        "did not find a matching codec for the given filetype" );
+
+        // okay, we can return a decoder
+        VIGRA_UNIQUE_PTR<Decoder> dec = search->second->getDecoder();
+        dec->init(filename, imageindex);
+        return dec;
+    }
+
+    // look up encoder from the list, then return it
+    std::string
+    CodecManager::getEncoderType( const std::string & filename,
+                                  const std::string & fType,
+                                  const std::string & mode ) const
+    {
+        std::string fileType = fType;
+
+        if ( fileType == "" || fileType == "undefined" ) {
+            // look up the file type by the file extension
+            std::string ext
+                = filename.substr( filename.find_last_of(".") + 1 );
+            std::transform( ext.begin(), ext.end(), ext.begin(), (int (*)(int))&std::tolower );
+            std::map< std::string, std::string >::const_iterator search
+                = extensionMap.find(ext);
+            vigra_precondition( search != extensionMap.end(),
+            "did not find a matching codec for the given file extension" );
+            // at this point, we have found a valid fileType
+            fileType = search->second;
+        }
+
+        return fileType;
+    }
+
+    // look up encoder from the list, then return it
+    VIGRA_UNIQUE_PTR<Encoder>
+    CodecManager::getEncoder( const std::string & filename,
+                              const std::string & fType,
+                              const std::string & mode ) const
+    {
+        std::string fileType = getEncoderType(filename, fType);
+
+        // return a codec factory by the file type
+        std::map< std::string, CodecFactory * >::const_iterator search
+            = factoryMap.find( fileType );
+        vigra_precondition( search != factoryMap.end(),
+        "did not find a matching codec for the given filetype" );
+
+        // okay, we can return an encoder
+        VIGRA_UNIQUE_PTR<Encoder> enc = search->second->getEncoder();
+        enc->init(filename, mode);
+        return enc;
+    }
+
+    // get a decoder
+    VIGRA_UNIQUE_PTR<Decoder>
+    getDecoder( const std::string & filename, const std::string & filetype, unsigned int imageindex )
+    {
+        return codecManager().getDecoder( filename, filetype, imageindex );
+    }
+
+    // get an encoder type
+    std::string
+    getEncoderType( const std::string & filename, const std::string & filetype )
+    {
+        return codecManager().getEncoderType( filename, filetype );
+    }
+
+    // get an encoder
+    VIGRA_UNIQUE_PTR<Encoder>
+    getEncoder( const std::string & filename, const std::string & filetype, const std::string & mode )
+    {
+        return codecManager().getEncoder( filename, filetype, mode );
+    }
+
+    std::vector<std::string>
+    queryCodecPixelTypes( const std::string & codecname )
+    {
+        return codecManager().queryCodecPixelTypes(codecname);
+    }
+
+
+    // return true if downcasting is required, false otherwise
+    bool negotiatePixelType( std::string const & codecname,
+                 std::string const & srcPixeltype, std::string & destPixeltype )
+    {
+        std::vector<std::string> ptypes
+            = codecManager().queryCodecPixelTypes(codecname);
+
+        std::vector<std::string>::iterator pend;
+        if(destPixeltype != "")
+        {
+            pend = std::find(ptypes.begin(), ptypes.end(), destPixeltype);
+            if(pend == ptypes.end())
+            {
+                std::string msg("exportImage(): file type ");
+                msg += codecname + " does not support requested pixel type "
+                                          + destPixeltype + ".";
+                vigra_precondition(false, msg.c_str());
+            }
+            ++pend;
+        }
+        else
+        {
+            pend = ptypes.end();
+        }
+
+        std::vector<std::string>::const_iterator result
+                                   = std::find( ptypes.begin(), pend, srcPixeltype );
+
+        if( result == pend)
+        {
+            if(destPixeltype == "")
+                destPixeltype = "UINT8";
+            // must always downcast
+            return true;
+        }
+        else
+        {
+            if(destPixeltype == "")
+                destPixeltype = srcPixeltype;
+            // don't downcast
+            return false;
+        }
+    }
+
+    bool isPixelTypeSupported( const std::string & codecname,
+                               const std::string & pixeltype )
+    {
+        std::vector<std::string> ptypes
+            = codecManager().queryCodecPixelTypes(codecname);
+        std::vector<std::string>::const_iterator result
+            = std::find( ptypes.begin(), ptypes.end(), pixeltype );
+        return ( result != ptypes.end() );
+    }
+
+    bool isBandNumberSupported( const std::string & codecname,
+                                int bands )
+    {
+        std::vector<int> bandNumbers
+            = codecManager().queryCodecBandNumbers(codecname);
+        if(bandNumbers[0] == 0)
+            return true; // any band number supported
+        std::vector<int>::const_iterator result
+            = std::find( bandNumbers.begin(), bandNumbers.end(), bands );
+        return ( result != bandNumbers.end() );
+    }
+
+} // namespace vigra
diff --git a/src/impex/codecmanager.hxx b/src/impex/codecmanager.hxx
new file mode 100644
index 0000000..daf0b62
--- /dev/null
+++ b/src/impex/codecmanager.hxx
@@ -0,0 +1,116 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2001 by Gunnar Kedenburg                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEX_CODECMANAGER_HXX
+#define VIGRA_IMPEX_CODECMANAGER_HXX
+
+#include <map>
+#include <memory>
+#include "vigra/codec.hxx"
+
+namespace vigra
+{
+    // the codec manager object is the global codec store
+    // from which codecs can be allocated.
+
+    class CodecManager
+    {
+        // the codec store
+        std::vector<std::pair<std::vector<char>, std::string> > magicStrings;
+        std::map< std::string, std::string > extensionMap;
+        std::map< std::string, CodecFactory * > factoryMap;
+
+    public:
+
+        // singleton pattern
+        static CodecManager & manager();
+
+        // add an encoder to the stores
+        void import( CodecFactory * cf );
+
+        // find out if a given file type is supported
+        bool fileTypeSupported( const std::string & fileType );
+
+        std::vector<std::string>
+        queryCodecPixelTypes( const std::string & codecName ) const;
+
+        std::vector<int>
+        queryCodecBandNumbers( const std::string & codecName ) const;
+
+        // find out which file types are supported
+        std::vector<std::string> supportedFileTypes();
+
+        // find out which file extensions are supported
+        std::vector<std::string> supportedFileExtensions();
+
+        // look up decoder from the list, then return it
+        VIGRA_UNIQUE_PTR<Decoder>
+        getDecoder( const std::string & fileName,
+                    const std::string & fileType = "undefined",
+                    unsigned int imageIndex = 0 ) const;
+
+        // look up encoder type from the list
+        std::string
+        getEncoderType( const std::string & fileName,
+                        const std::string & fileType = "undefined",
+                        const std::string & mode = "w" ) const;
+
+        // look up encoder from the list, then return it
+        VIGRA_UNIQUE_PTR<Encoder>
+        getEncoder( const std::string & fileName,
+                    const std::string & fileType = "undefined",
+                    const std::string & mode = "w" ) const;
+
+        // try to figure out the correct file type
+        std::string getFileTypeByMagicString( const std::string & filename ) const;
+
+    private:
+
+        // this will only be called by the singleton pattern
+        CodecManager();
+
+        ~CodecManager();
+
+    }; // class CodecManager
+
+    // singleton pattern
+    inline CodecManager & codecManager()
+    {
+        return CodecManager::manager();
+    }
+
+} // namespace vigra
+
+#endif // VIGRA_IMPEX_CODECMANAGER_HXX
diff --git a/src/impex/error.hxx b/src/impex/error.hxx
new file mode 100644
index 0000000..9da37f8
--- /dev/null
+++ b/src/impex/error.hxx
@@ -0,0 +1,44 @@
+/************************************************************************/
+/*                                                                      */
+/*      Copyright 2002-2004 by Ullrich Koethe and Gunnar Kedenburg      */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEX_ERROR_HXX
+#define VIGRA_IMPEX_ERROR_HXX
+
+#include "vigra/error.hxx"
+
+#define VIGRA_IMPEX_FINALIZED(p) { if (p) \
+    vigra_precondition( false, "encoder settings were already finalized" ); }
+
+#endif // VIGRA_IMPEX_ERROR_HXX
diff --git a/src/impex/exr.cxx b/src/impex/exr.cxx
new file mode 100644
index 0000000..e6be88a
--- /dev/null
+++ b/src/impex/exr.cxx
@@ -0,0 +1,509 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2007 by Pablo d'Angelo                       */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        koethe at informatik.uni-hamburg.de          or                  */
+/*        vigra at kogs1.informatik.uni-hamburg.de                         */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifdef HasEXR
+
+#include "vigra/config.hxx"
+#include "vigra/sized_int.hxx"
+#include "void_vector.hxx"
+#include "auto_file.hxx"
+#include "exr.hxx"
+#include "byteorder.hxx"
+#include "error.hxx"
+#include <stdexcept>
+#include <iostream>
+
+#include <ImfRgbaFile.h>
+#include <ImfCRgbaFile.h>
+#include <ImfStandardAttributes.h>
+#include <ImfStringAttribute.h>
+#include <ImfMatrixAttribute.h>
+#include <ImfArray.h>
+
+using namespace Imf;
+using namespace Imath;
+
+namespace vigra {
+
+    CodecDesc ExrCodecFactory::getCodecDesc() const
+    {
+        CodecDesc desc;
+
+        // init file type
+        desc.fileType = "EXR";
+
+        // init pixel types
+        desc.pixelTypes.resize(1);
+        desc.pixelTypes[0] = "FLOAT";
+
+        // init compression types
+#if defined(IMF_B44_COMPRESSION) && defined(IMF_B44A_COMPRESSION)
+        desc.compressionTypes.resize(7);
+#else
+        desc.compressionTypes.resize(5);
+#endif
+        desc.compressionTypes[0] = "NONE";
+        desc.compressionTypes[1] = "ZIP";
+        desc.compressionTypes[2] = "RLE";
+        desc.compressionTypes[3] = "PIZ";
+        desc.compressionTypes[4] = "PXR24";
+#if defined(IMF_B44_COMPRESSION) && defined(IMF_B44A_COMPRESSION)
+        desc.compressionTypes[5] = "B44";
+        desc.compressionTypes[6] = "B44A";
+#endif
+
+        // init magic strings
+        desc.magicStrings.resize(1);
+        desc.magicStrings[0].resize(4);
+        desc.magicStrings[0][0] = '\x76';
+        desc.magicStrings[0][1] = '\x2f';
+        desc.magicStrings[0][2] = '\x31';
+        desc.magicStrings[0][3] = '\x01';
+
+        // init file extensions
+        desc.fileExtensions.resize(1);
+        desc.fileExtensions[0] = "exr";
+
+        desc.bandNumbers.resize(1);
+        desc.bandNumbers[0] = 4;
+
+        return desc;
+    }
+
+    VIGRA_UNIQUE_PTR<Decoder> ExrCodecFactory::getDecoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Decoder>( new ExrDecoder() );
+    }
+
+    VIGRA_UNIQUE_PTR<Encoder> ExrCodecFactory::getEncoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Encoder>( new ExrEncoder() );
+    }
+
+    struct ExrDecoderImpl
+    {
+        std::string filename;
+        // data source
+        // auto_file file;
+
+        // this is where libopenexr stores its state
+        RgbaInputFile file;
+
+        // data container
+        ArrayVector<Rgba> pixels;
+        ArrayVector<float> bands;
+
+        // scanline counter
+        int scanline;
+
+        int width;
+        int height;
+
+        int components;
+        int extra_components;
+        Diff2D position;
+        Size2D canvasSize;
+
+        float x_resolution, y_resolution;
+
+        // ctor, dtor
+        ExrDecoderImpl( const std::string & filename );
+        ~ExrDecoderImpl();
+
+        // methods
+        void init();
+        void nextScanline();
+    };
+
+    ExrDecoderImpl::ExrDecoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        : file( filename.c_str() ),
+#else
+        : file( filename.c_str() ),
+#endif
+          bands(0),
+          scanline(-1), width(0), height(0),
+          components(4), extra_components(1),
+          x_resolution(0), y_resolution(0)
+    {
+    }
+
+    ExrDecoderImpl::~ExrDecoderImpl()
+    {
+    }
+
+    void ExrDecoderImpl::init()
+    {
+        // setup framebuffer
+        Box2i dw = file.header().dataWindow();
+        width  = dw.max.x - dw.min.x + 1;
+        height = dw.max.y - dw.min.y + 1;
+
+        position.x = dw.min.x;
+        scanline = dw.min.y;
+        position.y = dw.min.y;
+
+        dw = file.header().displayWindow();
+        canvasSize.x = dw.max.x+1;
+        canvasSize.y = dw.max.y+1;
+
+        // allocate data buffers
+        pixels.resize(width);
+        bands.resize(4*width);
+    }
+
+    void ExrDecoderImpl::nextScanline()
+    {
+        file.setFrameBuffer (pixels.data() - position.x - scanline * width, 1, width);
+        file.readPixels (scanline, scanline);
+        scanline++;
+        // convert scanline to float
+        float * dest = bands.begin();
+        for (int i=0; i < width; i++) {
+            *dest++ = pixels[i].r;
+            *dest++ = pixels[i].g;
+            *dest++ = pixels[i].b;
+            *dest++ = pixels[i].a;
+        }
+    }
+
+    void ExrDecoder::init( const std::string & filename )
+    {
+        pimpl = new ExrDecoderImpl(filename);
+        pimpl->init();
+    }
+
+    ExrDecoder::~ExrDecoder()
+    {
+        delete pimpl;
+    }
+
+    std::string ExrDecoder::getFileType() const
+    {
+        return "EXR";
+    }
+
+    unsigned int ExrDecoder::getWidth() const
+    {
+        return pimpl->width;
+    }
+
+    unsigned int ExrDecoder::getHeight() const
+    {
+        return pimpl->height;
+    }
+
+    unsigned int ExrDecoder::getNumBands() const
+    {
+        return pimpl->components;
+    }
+
+    unsigned int ExrDecoder::getNumExtraBands() const
+    {
+        return pimpl->extra_components;
+    }
+
+    float ExrDecoder::getXResolution() const
+    {
+        return pimpl->x_resolution;
+    }
+
+    float ExrDecoder::getYResolution() const
+    {
+        return pimpl->y_resolution;
+    }
+
+    Diff2D ExrDecoder::getPosition() const
+    {
+        return pimpl->position;
+    }
+
+    Size2D ExrDecoder::getCanvasSize() const
+    {
+        return pimpl->canvasSize;
+    }
+
+    std::string ExrDecoder::getPixelType() const
+    {
+        return "FLOAT";
+    }
+
+    unsigned int ExrDecoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    const void * ExrDecoder::currentScanlineOfBand( unsigned int band ) const
+    {
+        return pimpl->bands.begin() + band;
+    }
+
+    void ExrDecoder::nextScanline()
+    {
+        pimpl->nextScanline();
+    }
+
+    void ExrDecoder::close() {}
+
+    void ExrDecoder::abort() {}
+
+    struct ExrEncoderImpl
+    {
+        std::string filename;
+        // data sink
+        RgbaOutputFile *file;
+
+        // data container
+        ArrayVector<float> bands;
+        ArrayVector<Rgba> pixels;
+
+        // image header fields
+        int width, height, components;
+        int extra_components;
+        int bit_depth, color_type;
+        Compression exrcomp;
+
+        // scanline counter
+        int scanline;
+
+        // state
+        bool finalized;
+
+        // image layer position
+        Diff2D position;
+        Size2D canvasSize;
+
+        // resolution
+        float x_resolution, y_resolution;
+
+        // ctor, dtor
+        ExrEncoderImpl( const std::string & filename );
+        ~ExrEncoderImpl();
+
+        // methods
+        void nextScanline();
+        void finalize();
+        void setCompressionType( const std::string &, int );
+        void close();
+    };
+
+    ExrEncoderImpl::ExrEncoderImpl( const std::string & filename )
+        : filename(filename), file(0), bands(0),
+          exrcomp(PIZ_COMPRESSION), scanline(0), finalized(false),
+          x_resolution(0), y_resolution(0)
+    {
+    }
+
+    ExrEncoderImpl::~ExrEncoderImpl()
+    {
+        if (file)
+            delete file;
+    }
+
+    void ExrEncoderImpl::finalize()
+    {
+        // prepare the bands
+        bands.resize( 4 * width );
+        pixels.resize(width);
+
+        // set proper position
+        Imath::Box2i displayWindow;
+        if (canvasSize.x < width + position.x ||
+            canvasSize.y < height + position.y)
+        {
+            displayWindow.min.x = 0;
+            displayWindow.min.y = 0;
+            displayWindow.max.x = width+position.x -1;
+            displayWindow.max.y = height+position.y-1;
+        } else {
+            displayWindow.min.x = 0;
+            displayWindow.min.y = 0;
+            displayWindow.max.x = canvasSize.x -1;
+            displayWindow.max.y = canvasSize.y -1;
+        }
+        Imath::Box2i dataWindow (Imath::V2i (position.x , position.y),
+                                 Imath::V2i (width+position.x -1, height+position.y-1));
+        Header header(displayWindow, dataWindow, 1, Imath::V2f(0, 0), 1, INCREASING_Y, exrcomp);
+        file = new RgbaOutputFile(filename.c_str(), header, WRITE_RGBA);
+        // enter finalized state
+        finalized = true;
+    }
+
+    void ExrEncoderImpl::nextScanline()
+    {
+        // check if there are scanlines left at all, eventually write one
+        if ( scanline < height ) {
+            float * src = bands.data();
+            for (int i=0; i < width; i++) {
+                // convert to half
+                pixels[i].r = *src++;
+                pixels[i].g = *src++;
+                pixels[i].b = *src++;
+                pixels[i].a = *src++;
+            }
+            file->setFrameBuffer (pixels.begin() - position.x -(scanline+position.y)*width, 1, width);
+            file->writePixels (1);
+        }
+        scanline++;
+    }
+
+    void ExrEncoderImpl::setCompressionType( const std::string & comp, int quality){
+       if (comp == "NONE")
+           exrcomp = NO_COMPRESSION;
+       else if (comp == "ZIP")
+           exrcomp = ZIP_COMPRESSION;
+       else if (comp == "RLE" || comp == "RunLength")
+           exrcomp = RLE_COMPRESSION;
+       else if (comp == "PIZ")
+           exrcomp = PIZ_COMPRESSION;
+       else if (comp == "PXR24")
+           exrcomp = PXR24_COMPRESSION;
+#if defined(IMF_B44_COMPRESSION) && defined(IMF_B44A_COMPRESSION)
+       else if (comp == "B44")
+           exrcomp = B44_COMPRESSION;
+       else if (comp == "B44A")
+           exrcomp = B44A_COMPRESSION;
+#endif
+    }
+
+    void ExrEncoderImpl::close()
+    {
+        delete file;
+        file = 0;
+    }
+
+    void ExrEncoder::init( const std::string & filename )
+    {
+        pimpl = new ExrEncoderImpl(filename);
+    }
+
+    ExrEncoder::~ExrEncoder()
+    {
+        delete pimpl;
+    }
+
+    std::string ExrEncoder::getFileType() const
+    {
+        return "EXR";
+    }
+
+    void ExrEncoder::setWidth( unsigned int width )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->width = width;
+    }
+
+    void ExrEncoder::setHeight( unsigned int height )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->height = height;
+    }
+
+    void ExrEncoder::setNumBands( unsigned int bands )
+    {
+        if ( bands != 4 )
+            vigra_fail( "internal error: number of components not supported." );
+        pimpl->components = bands;
+    }
+
+    void ExrEncoder::setCompressionType( const std::string & comp,
+                                         int quality )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->setCompressionType(comp, quality);
+    }
+
+    void ExrEncoder::setPosition( const Diff2D & pos )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->position = pos;
+    }
+
+    void ExrEncoder::setCanvasSize( const Size2D & size )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->canvasSize = size;
+    }
+
+    void ExrEncoder::setXResolution( float xres )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->x_resolution = xres;
+    }
+
+    void ExrEncoder::setYResolution( float yres )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->y_resolution = yres;
+    }
+
+    void ExrEncoder::setPixelType( const std::string & pixelType )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        if ( pixelType != "FLOAT" )
+            vigra_fail( "internal error: pixeltype not supported." );
+    }
+
+    unsigned int ExrEncoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    void ExrEncoder::finalizeSettings()
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->finalize();
+    }
+
+    void * ExrEncoder::currentScanlineOfBand( unsigned int band )
+    {
+        return pimpl->bands.begin() + band;
+    }
+
+    void ExrEncoder::nextScanline()
+    {
+        // write scanline
+        pimpl->nextScanline();
+    }
+
+    void ExrEncoder::close()
+    {
+        pimpl->close();
+    }
+
+    void ExrEncoder::abort() {}
+}
+
+#endif // HasEXR
diff --git a/src/impex/exr.hxx b/src/impex/exr.hxx
new file mode 100644
index 0000000..a78aaf4
--- /dev/null
+++ b/src/impex/exr.hxx
@@ -0,0 +1,123 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2007 by Pablo d'Angelo                       */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    ( Version 1.5.0, Dec 07 2006 )                                    */
+/*    The VIGRA Website is                                              */
+/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        koethe at informatik.uni-hamburg.de          or                  */
+/*        vigra at kogs1.informatik.uni-hamburg.de                         */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEX_EXR_HXX
+#define VIGRA_IMPEX_EXR_HXX
+
+#include "vigra/codec.hxx"
+
+// EXR - OpenEXR
+
+namespace vigra {
+
+    struct ExrDecoderImpl;
+    struct ExrEncoderImpl;
+
+    struct ExrCodecFactory : public CodecFactory
+    {
+        CodecDesc getCodecDesc() const;
+        VIGRA_UNIQUE_PTR<Decoder> getDecoder() const;
+        VIGRA_UNIQUE_PTR<Encoder> getEncoder() const;
+    };
+
+    class ExrDecoder : public Decoder
+    {
+        ExrDecoderImpl * pimpl;
+
+    public:
+
+        ExrDecoder() : pimpl(0) {}
+
+        ~ExrDecoder();
+
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        std::string getPixelType() const;
+
+        unsigned int getWidth() const;
+        unsigned int getHeight() const;
+        unsigned int getNumBands() const;
+        unsigned int getNumExtraBands() const;
+        float getXResolution() const;
+        float getYResolution() const;
+        Diff2D getPosition() const;
+        Size2D getCanvasSize() const;
+
+        unsigned int getOffset() const;
+
+        const void * currentScanlineOfBand( unsigned int ) const;
+        void nextScanline();
+    };
+
+    class ExrEncoder : public Encoder
+    {
+        ExrEncoderImpl * pimpl;
+
+    public:
+
+        ExrEncoder() : pimpl(0) {}
+
+        ~ExrEncoder();
+
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        unsigned int getOffset() const;
+
+        void setWidth( unsigned int );
+        void setHeight( unsigned int );
+        void setNumBands( unsigned int );
+        void setCompressionType( const std::string &, int = -1 );
+        void setPixelType( const std::string & );
+
+        void setPosition( const Diff2D & pos );
+        void setCanvasSize( const Size2D & pos );
+        void setXResolution( float xres );
+        void setYResolution( float yres );
+
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int );
+        void nextScanline();
+    };
+}
+
+#endif // VIGRA_IMPEX_EXR_HXX
diff --git a/src/impex/gif.cxx b/src/impex/gif.cxx
new file mode 100644
index 0000000..ea0d70a
--- /dev/null
+++ b/src/impex/gif.cxx
@@ -0,0 +1,1076 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Ullrich Koethe                       */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <fstream>
+#include <stdexcept>
+#include <vector>
+#include <algorithm>
+#include "vigra/config.hxx"
+#include "vigra/sized_int.hxx"
+#include "error.hxx"
+#include "byteorder.hxx"
+#include "void_vector.hxx"
+#include "gif.hxx"
+
+#define BitSet(byte,bit)  (((byte) & (bit)) == (bit))
+
+namespace vigra {
+
+namespace {
+
+    int read_data_block(std::ifstream & stream, void_vector<UInt8> & data)
+    {
+        int count;
+
+        count = stream.get();
+        if(!stream.good())
+            return -1;
+        if(count == 0)
+            return 0;
+        data.resize(count);
+        stream.read( reinterpret_cast< char * >(data.begin()), count);
+        if(!stream.good())
+            return -1;
+        return count;
+    }
+
+    struct ColorCluster
+    {
+        UInt8 cmin[3], cmax[3];
+        std::vector<UInt8 *> entries;
+        mutable int largest_dim, largest_diff;
+
+        typedef UInt8 rgb[3];
+
+        struct ColorSorter
+        {
+            int dim;
+
+            ColorSorter(int d)
+            : dim(d)
+            {}
+
+            bool operator()(UInt8 * l, UInt8 * r) const
+            {
+                return l[dim] < r[dim];
+            }
+        };
+
+        ColorCluster()
+        : largest_dim(-1)
+        {
+            reset_minmax();
+        }
+
+        void add(UInt8 * entry)
+        {
+            entries.push_back(entry);
+
+            update_minmax(entry);
+        }
+
+        void reset_minmax()
+        {
+            for(int i=0; i<3; ++i)
+            {
+                cmin[i] = 255;
+                cmax[i] = 0;
+            }
+
+            largest_dim = -1;
+        }
+
+        void update_minmax(UInt8 * entry)
+        {
+            for(int i=0; i<3; ++i)
+            {
+                if(entry[i] < cmin[i])
+                    cmin[i] = entry[i];
+                if(cmax[i] < entry[i])
+                    cmax[i] = entry[i];
+            }
+
+            largest_dim = -1;
+        }
+
+        void update_largest() const
+        {
+            if(largest_dim >= 0)
+                return;
+            largest_diff = cmax[0] - cmin[0];
+            largest_dim = 0;
+
+            for(int i=1; i<3; ++i)
+            {
+                if(largest_diff < cmax[i] - cmin[i])
+                {
+                    largest_dim = i;
+                    largest_diff = cmax[i] - cmin[i];
+                }
+            }
+        }
+
+        bool operator<(ColorCluster const & o) const
+        {
+            update_largest();
+            o.update_largest();
+            return largest_diff < o.largest_diff;
+        }
+
+        void split(ColorCluster & o)
+        {
+            update_largest();
+            std::sort(entries.begin(), entries.end(), ColorSorter(largest_dim));
+
+            std::vector<UInt8 *> old_list;
+            old_list.swap(entries);
+            reset_minmax();
+
+            UInt32 i = 0;
+            for(; i<old_list.size()/2; ++i)
+            {
+                add(old_list[i]);
+            }
+            for(; i<old_list.size(); ++i)
+            {
+                o.add(old_list[i]);
+            }
+        }
+
+        void average(UInt8 * color) const
+        {
+            UIntBiggest r = 0, g = 0, b = 0;
+
+            for(size_t i=0; i<entries.size(); ++i)
+            {
+                r += entries[i][0];
+                g += entries[i][1];
+                b += entries[i][2];
+            }
+
+            color[0] = (UInt8)(r / entries.size());
+            color[1] = (UInt8)(g / entries.size());
+            color[2] = (UInt8)(b / entries.size());
+        }
+
+        size_t size() const
+        {
+            return entries.size();
+        }
+    };
+
+
+    void find_color_clusters(void_vector<UInt8> & data,
+            std::vector<ColorCluster> & clusters, void_vector<UInt8> & colors)
+    {
+        size_t count = clusters.size();
+        size_t size = data.size() / 3;
+        size_t i, current;
+        for(i=0; i<size; ++i)
+        {
+            clusters[0].add(data.begin()+3*i);
+        }
+
+        for(current = 1; current < count; ++current)
+        {
+            size_t largest_index = 0;
+            for(i=1; i<current; ++i)
+            {
+                if(clusters[largest_index] < clusters[i])
+                {
+                    largest_index = i;
+                }
+            }
+            if(clusters[largest_index].size() == 1)
+                break;
+            clusters[largest_index].split(clusters[current]);
+        }
+
+        for(i=0; i<count; ++i)
+        {
+            if(clusters[i].size() == 0)
+            {
+                colors[3*i] = colors[3*i+1] = colors[3*i+2] = 0;
+            }
+            else
+            {
+                clusters[i].average(colors.begin() + 3*i);
+            }
+        }
+    }
+
+    void find_color_indices(void_vector<UInt8> & data,
+           std::vector<ColorCluster> & clusters, void_vector<UInt8> & indices)
+    {
+        size_t count = clusters.size();
+        UInt8 * base = data.begin();
+
+        size_t i;
+        for(i=0; i<count; ++i)
+        {
+            for(size_t j=0; j<clusters[i].size(); ++j)
+            {
+                size_t offset = (clusters[i].entries[j] - base) / 3;
+                indices[offset] = static_cast<UInt8>(i);
+            }
+        }
+    }
+} // anonymous namespace
+
+    CodecDesc GIFCodecFactory::getCodecDesc() const
+    {
+        CodecDesc desc;
+
+        // init file type
+        desc.fileType = "GIF";
+
+        // init pixel types
+        desc.pixelTypes.resize(1);
+        desc.pixelTypes[0] = "UINT8";
+
+        // init compression types
+        desc.compressionTypes.resize(0);
+
+        // init magic strings
+        desc.magicStrings.resize(1);
+        desc.magicStrings[0].resize(4);
+        desc.magicStrings[0][0] = 'G';
+        desc.magicStrings[0][1] = 'I';
+        desc.magicStrings[0][2] = 'F';
+        desc.magicStrings[0][3] = '8';
+
+        // init file extensions
+        desc.fileExtensions.resize(1);
+        desc.fileExtensions[0] = "gif";
+
+        desc.bandNumbers.resize(2);
+        desc.bandNumbers[0] = 1;
+        desc.bandNumbers[1] = 3;
+
+        return desc;
+    }
+
+    VIGRA_UNIQUE_PTR<Decoder> GIFCodecFactory::getDecoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Decoder>( new GIFDecoder() );
+    }
+
+    VIGRA_UNIQUE_PTR<Encoder> GIFCodecFactory::getEncoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Encoder>( new GIFEncoder() );
+    }
+
+    struct GIFHeader
+    {
+        // attributes
+
+        UInt16 width, height, maplength;
+        UInt8  bits_per_pixel;
+        bool  global_colormap, interlace;
+
+        // methods
+
+        void global_from_stream( std::ifstream & stream, const byteorder & bo );
+        bool local_from_stream( std::ifstream & stream, const byteorder & bo );
+        void global_to_stream( std::ofstream & stream, const byteorder & bo );
+        void local_to_stream( std::ofstream & stream, const byteorder & bo );
+    };
+
+    void GIFHeader::global_from_stream( std::ifstream & stream, const byteorder & bo )
+    {
+        UInt8 flag, c, background;
+        read_field( stream, bo, width );
+        read_field( stream, bo, height );
+        read_field( stream, bo, flag );
+        read_field( stream, bo, background );
+        read_field( stream, bo, c );
+        global_colormap = BitSet(flag, 0x80);
+        if(global_colormap)
+        {
+            bits_per_pixel = (flag & 0x07)+1;
+            maplength = 3*( 1 << bits_per_pixel);
+        }
+    }
+
+    void GIFHeader::global_to_stream( std::ofstream & stream, const byteorder & bo )
+    {
+        write_field( stream, bo, width );
+        write_field( stream, bo, height );
+        write_field( stream, bo, (UInt8)0xf7 );
+        write_field( stream, bo, (UInt8)0 );  // background
+        write_field( stream, bo, (UInt8)0 );  // must be zero
+    }
+
+    bool GIFHeader::local_from_stream( std::ifstream & stream, const byteorder & bo )
+    {
+        UInt8 c, flag;
+        for ( ; ; )
+        {
+            c = stream.get();
+            if(!stream.good() || c == ';')
+                return false;
+            if(c == '!')
+            {
+                void_vector<UInt8> extensions;
+
+                // read and ignore extension data
+                read_field( stream, bo, c );
+                while (read_data_block(stream, extensions) > 0) /* empty */;
+            }
+            if(c == ',')
+                break;
+        }
+
+        UInt16 x,y;
+
+        read_field( stream, bo, x );
+        read_field( stream, bo, y );
+        read_field( stream, bo, width );
+        read_field( stream, bo, height );
+        read_field( stream, bo, flag );
+        interlace=BitSet(flag,0x40);
+        if(BitSet(flag,0x80))
+        {
+            global_colormap = false;
+            bits_per_pixel = (flag & 0x07)+1;
+            maplength = 3*( 1 << bits_per_pixel);
+        }
+        return true;
+    }
+
+    void GIFHeader::local_to_stream( std::ofstream & stream, const byteorder & bo )
+    {
+        write_field( stream, bo, ',' );
+        write_field( stream, bo, (UInt16)0 ); // x
+        write_field( stream, bo, (UInt16)0 ); // y
+        write_field( stream, bo, width );
+        write_field( stream, bo, height );
+        write_field( stream, bo, (UInt8)0); // use global colormap, no interlace
+   }
+
+    struct GIFDecoderImpl
+    {
+        // attributes
+
+        GIFHeader header;
+        std::ifstream stream;
+        byteorder bo;
+        void_vector< UInt8 > maps, bands;
+        UInt32 components;
+        UInt8 * scanline;
+
+        // methods
+
+        void decodeGIF();
+
+        // ctor
+
+        GIFDecoderImpl( const std::string & filename );
+    };
+
+    GIFDecoderImpl::GIFDecoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        : stream( filename.c_str(), std::ios::binary ),
+#else
+        : stream( filename.c_str() ),
+#endif
+          bo("little endian"),
+          maps(0),
+          bands(0),
+          scanline(0)
+    {
+        if(!stream.good())
+        {
+            std::string msg("Unable to open file '");
+            msg += filename;
+            msg += "'.";
+            vigra_precondition(0, msg.c_str());
+        }
+
+        // read the magic number
+        char buf[6];
+        read_array( stream, bo, buf, 6 );
+        std::string magic(6, (std::string::value_type)0);
+
+        std::copy(buf, buf + 6, magic.begin());
+        vigra_precondition( magic == "GIF87a" || magic == "GIF89a",
+                            "the stored magic number is invalid" );
+
+        // read the header
+        header.global_from_stream( stream, bo );
+
+        // read the global color map, if there is one
+        if (header.global_colormap)
+        {
+            // read the maps
+            maps.resize(header.maplength);
+            read_array( stream, bo, maps.data(), header.maplength );
+        }
+
+        if(!header.local_from_stream( stream, bo ))
+        {
+            std::string msg("Unable to read file '");
+            msg += filename;
+            msg += "'.";
+            vigra_precondition(0, msg.c_str());
+        }
+
+        // read the local color map, if there is one
+        if (!header.global_colormap)
+        {
+            // read the maps
+            maps.resize(header.maplength);
+            read_array( stream, bo, maps.data(), header.maplength );
+        }
+
+        // check if image is Gray or RGB
+        int i=0;
+        components = 1;
+        for(; i < header.maplength/3; ++i)
+        {
+            if(maps[3*i] != maps[3*i+1] || maps[3*i] != maps[3*i+2])
+            {
+                components = 3;
+                break;
+            }
+        }
+    }
+
+    void GIFDecoderImpl::decodeGIF()
+    {
+        #define MaxStackSize  4096
+        #define NullCode  (-1)
+
+        int
+            available,
+            clear,
+            code_mask,
+            code_size,
+            end_of_information,
+            in_code,
+            old_code;
+
+        register int
+            bits,
+            code,
+            count;
+
+        register unsigned long
+        datum;
+
+        void_vector<Int16> prefix(MaxStackSize);
+        void_vector<UInt8> suffix(MaxStackSize);
+        void_vector<UInt8> pixel_stack(MaxStackSize+1);
+        void_vector<UInt8> packet(256);
+        void_vector<UInt16> indices(header.width*header.height);
+
+        register UInt8 *c;
+        register UInt16 *p = indices.begin();
+
+        UInt8
+        data_size,
+        first,
+        *top_stack;
+
+        /*
+        Initialize GIF data stream decoder.
+        */
+        data_size = stream.get();
+        clear=1 << data_size;
+        end_of_information=clear+1;
+        available=clear+2;
+        old_code=NullCode;
+        code_size=data_size+1;
+        code_mask=(1 << code_size)-1;
+        for (code=0; code < clear; code++)
+        {
+            prefix[code]=0;
+            suffix[code]=code;
+        }
+        /*
+        Decode GIF pixel stream.
+        */
+        datum=0;
+        bits=0;
+        c=0;
+        count=0;
+        first=0;
+        top_stack=pixel_stack.begin();
+        while (p < indices.end())
+        {
+            if (top_stack == pixel_stack.begin())
+            {
+                if (bits < code_size)
+                {
+                    /*
+                      Load bytes until there is enough bits for a code.
+                    */
+                    if (count == 0)
+                    {
+                        /*
+                          Read a new data block.
+                        */
+                        count=read_data_block(stream, packet);
+                        if (count <= 0)
+                          break;
+                        c=packet.begin();
+                    }
+                    datum+=(*c) << bits;
+                    bits+=8;
+                    c++;
+                    count--;
+                    continue;
+                }
+                /*
+                  Get the next code.
+                */
+                code=datum & code_mask;
+                datum>>=code_size;
+                bits-=code_size;
+                /*
+                  Interpret the code
+                */
+                if ((code > available) || (code == end_of_information))
+                  break;
+                if (code == clear)
+                {
+                    /*
+                      Reset decoder.
+                    */
+                    code_size=data_size+1;
+                    code_mask=(1 << code_size)-1;
+                    available=clear+2;
+                    old_code=NullCode;
+                    continue;
+                }
+                if (old_code == NullCode)
+                {
+                    *top_stack++=suffix[code];
+                    old_code=code;
+                    first=code;
+                    continue;
+                }
+                in_code=code;
+                if (code == available)
+                {
+                    *top_stack++=first;
+                    code=old_code;
+                }
+                while (code > clear)
+                {
+                  *top_stack++=suffix[code];
+                  code=prefix[code];
+                }
+                first=suffix[code];
+                /*
+                  Add a new string to the string table,
+                */
+                if (available >= MaxStackSize)
+                  break;
+                *top_stack++=first;
+                prefix[available]=old_code;
+                suffix[available]=first;
+                available++;
+                if (((available & code_mask) == 0) && (available < MaxStackSize))
+                {
+                    code_size++;
+                    code_mask+=available;
+                }
+                old_code=in_code;
+            }
+            /*
+              Pop a pixel off the pixel stack.
+            */
+            top_stack--;
+            *p++ =(UInt16) *top_stack;
+        }
+
+        // decode intelaced image
+        if (header.interlace)
+        {
+            void_vector<UInt16> non_interlaced(header.width*header.height);
+
+            int pass, x, y;
+
+            register UInt16 *q;
+
+            static int
+              interlace_rate[4] = { 8, 8, 4, 2 },
+              interlace_start[4] = { 0, 4, 2, 1 };
+
+            p=indices.begin();
+            for (pass=0; pass < 4; pass++)
+            {
+              y=interlace_start[pass];
+              while (y < header.height)
+              {
+                q=non_interlaced.begin()+(y*header.width);
+                for (x=0; x < header.width; x++)
+                {
+                  *q=(*p);
+                  p++;
+                  q++;
+                }
+                y+=interlace_rate[pass];
+              }
+            }
+
+            swap_void_vector( indices, non_interlaced );
+            header.interlace = false;
+        }
+
+        // apply colormap
+        bands.resize(header.width*header.height*components);
+        for(int i=0; i<header.width*header.height; ++i)
+        {
+            if(components == 1)
+            {
+                bands[i] = maps[3*indices[i]];
+            }
+            else
+            {
+                bands[3*i] = maps[3*indices[i]];
+                bands[3*i+1] = maps[3*indices[i]+1];
+                bands[3*i+2] = maps[3*indices[i]+2];
+            }
+        }
+    }
+
+    void GIFDecoder::init( const std::string & filename )
+    {
+        pimpl = new GIFDecoderImpl( filename );
+    }
+
+    GIFDecoder::~GIFDecoder()
+    {
+        delete pimpl;
+    }
+
+    std::string GIFDecoder::getFileType() const
+    {
+        return "GIF";
+    }
+
+    unsigned int GIFDecoder::getWidth() const
+    {
+        return pimpl->header.width;
+    }
+
+    unsigned int GIFDecoder::getHeight() const
+    {
+        return pimpl->header.height;
+    }
+
+    unsigned int GIFDecoder::getNumBands() const
+    {
+        return pimpl->components;
+    }
+
+    std::string GIFDecoder::getPixelType() const
+    {
+        return "UINT8";
+    }
+
+    unsigned int GIFDecoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    const void * GIFDecoder::currentScanlineOfBand( unsigned int band ) const
+    {
+        return pimpl->scanline + band;
+    }
+
+    void GIFDecoder::nextScanline()
+    {
+        if (pimpl->scanline)
+            pimpl->scanline += getWidth()*getNumBands();
+        else
+        {
+            pimpl->decodeGIF();
+            pimpl->scanline = pimpl->bands.begin();
+        }
+    }
+
+    void GIFDecoder::close() {}
+    void GIFDecoder::abort() {}
+
+    struct GIFEncoderImpl
+    {
+        // attributes
+
+        GIFHeader header;
+        std::ofstream stream;
+        byteorder bo;
+        void_vector< UInt8 > bands;
+        void_vector< UInt8 > maps;
+        void_vector< UInt8 > indices;
+        UInt32 components;
+        UInt8 *scanline;
+        bool finalized;
+
+        // methods
+
+        void finalize();
+        void writeHeader();
+        void writeColormap();
+        void writeImageData();
+        void reduceTo256Colors();
+        void outputEncodedData(void_vector< UInt8 > &);
+
+        // ctor
+
+        GIFEncoderImpl( const std::string & filename );
+    };
+
+    GIFEncoderImpl::GIFEncoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        : stream( filename.c_str(), std::ios::binary ),
+#else
+        : stream( filename.c_str() ),
+#endif
+          bo("little endian"),
+          bands(0),
+          maps(0),
+          indices(0),
+          scanline(0),
+          finalized(false)
+    {
+        if(!stream.good())
+        {
+            std::string msg("Unable to open file '");
+            msg += filename;
+            msg += "'.";
+            vigra_precondition(0, msg.c_str());
+        }
+        // write the magic number
+        write_array( stream, bo, "GIF87a", 6 );
+    }
+
+    void GIFEncoderImpl::finalize()
+    {
+        // color depth
+        vigra_precondition( components == 1 || components == 3,
+                            "number of bands is not supported" );
+    }
+
+    void GIFEncoderImpl::writeHeader()
+    {
+        // write the header
+        header.global_to_stream( stream, bo );
+        writeColormap();
+        header.local_to_stream( stream, bo );
+    }
+
+    void GIFEncoderImpl::writeColormap()
+    {
+        write_array( stream, bo, maps.data(), header.maplength );
+    }
+
+    void GIFEncoderImpl::writeImageData()
+    {
+        stream.put(header.bits_per_pixel); // code size
+        if(components == 3)
+        {
+            outputEncodedData(indices);
+        }
+        else
+        {
+            outputEncodedData(bands);
+        }
+        stream.put(0);   // end of raster stream
+        stream.put(';'); // GIF terminator
+    }
+
+    void GIFEncoderImpl::reduceTo256Colors()
+    {
+        header.bits_per_pixel = 8;
+        header.maplength = 3*256;
+
+        maps.resize(header.maplength);
+        if(components == 3)
+        {
+            std::vector<ColorCluster> clusters(256);
+            find_color_clusters(bands, clusters, maps);
+            indices.resize(header.width*header.height);
+            find_color_indices(bands, clusters, indices);
+        }
+        else
+        {
+            for(int i=0; i<256; ++i)
+            {
+                maps[3*i] = maps[3*i+1] = maps[3*i+2] = i;
+            }
+        }
+    }
+
+    void GIFEncoderImpl::outputEncodedData(void_vector<UInt8> & indices)
+    {
+        #define MaxCode(number_bits)  ((1 << (number_bits))-1)
+        #define MaxHashTable  5003
+        #define MaxGIFBits  12
+        #if defined(HasLZW)
+        #define MaxGIFTable  (1 << MaxGIFBits)
+        #else
+        #define MaxGIFTable  max_code
+        #endif
+        #define GIFOutputCode(code) \
+        { \
+          /*  \
+            Emit a code. \
+          */ \
+          if (bits > 0) \
+            datum|=((long) code << bits); \
+          else \
+            datum=(long) code; \
+          bits+=number_bits; \
+          while (bits >= 8) \
+          { \
+            /*  \
+              Add a character to current packet. \
+            */ \
+            packet[byte_count++]=(UInt8) (datum & 0xff); \
+            if (byte_count >= 254) \
+              { \
+                stream.put(byte_count); \
+                stream.write(reinterpret_cast< char * >(packet.begin()),byte_count); \
+                byte_count=0; \
+              } \
+            datum>>=8; \
+            bits-=8; \
+          } \
+          if (free_code > max_code)  \
+            { \
+              number_bits++; \
+              if (number_bits == MaxGIFBits) \
+                max_code=MaxGIFTable; \
+              else \
+                max_code=MaxCode(number_bits); \
+            } \
+        }
+
+        int
+          bits,
+          byte_count,
+          number_bits,
+          data_size = header.bits_per_pixel;
+        UInt32  i;
+
+        long
+          datum;
+
+        register int k;
+
+        register UInt8 *p;
+
+        void_vector<Int16> hash_code(MaxHashTable);
+        void_vector<Int16> hash_prefix(MaxHashTable);
+        void_vector<Int16> hash_suffix(MaxHashTable);
+
+        Int16
+          clear_code,
+          end_of_information_code,
+          free_code,
+          index,
+          max_code,
+          waiting_code;
+
+        void_vector<UInt8> packet(256);
+
+        /*
+          Initialize GIF encoder.
+        */
+        number_bits=data_size+1;
+        max_code=MaxCode(number_bits);
+        clear_code=((Int16) 1 << data_size);
+        end_of_information_code=clear_code+1;
+        free_code=clear_code+2;
+        byte_count=0;
+        datum=0;
+        bits=0;
+        for (i=0; i < MaxHashTable; i++)
+          hash_code[i]=0;
+        GIFOutputCode(clear_code);
+        /*
+          Encode pixels.
+        */
+        p=indices.begin();
+        waiting_code=*p;
+        for (i=0; i < indices.size(); i++)
+        {
+          if(i > 0)
+          {
+            /*
+              Probe hash table.
+            */
+            index=*p & 0xff;
+            k=(int) ((int) index << (MaxGIFBits-8))+waiting_code;
+            if (k >= MaxHashTable)
+              k-=MaxHashTable;
+            GIFOutputCode(waiting_code);
+            if (free_code < MaxGIFTable)
+            {
+                hash_code[k]=free_code++;
+                hash_prefix[k]=waiting_code;
+                hash_suffix[k]=index;
+            }
+            else
+            {
+                /*
+                  Fill the hash table with empty entries.
+                */
+                for (k=0; k < MaxHashTable; k++)
+                  hash_code[k]=0;
+                /*
+                  Reset compressor and issue a clear code.
+                */
+                free_code=clear_code+2;
+                GIFOutputCode(clear_code);
+                number_bits=data_size+1;
+                max_code=MaxCode(number_bits);
+            }
+            waiting_code=index;
+          }
+          p++;
+        }
+        /*
+          Flush out the buffered code.
+        */
+        GIFOutputCode(waiting_code);
+        GIFOutputCode(end_of_information_code);
+        if (bits > 0)
+        {
+            /*
+              Add a character to current packet.
+            */
+            packet[byte_count++]=(UInt8) (datum & 0xff);
+            if (byte_count >= 254)
+            {
+                stream.put(byte_count);
+                stream.write(reinterpret_cast< char * >(packet.begin()),byte_count);
+                byte_count=0;
+            }
+        }
+        /*
+          Flush accumulated data.
+        */
+        if (byte_count > 0)
+        {
+                stream.put(byte_count);
+                stream.write(reinterpret_cast< char * >(packet.begin()),byte_count);
+        }
+    }
+
+    void GIFEncoder::init( const std::string & filename )
+    {
+        pimpl = new GIFEncoderImpl(filename);
+    }
+
+    GIFEncoder::~GIFEncoder()
+    {
+        delete pimpl;
+    }
+
+    std::string GIFEncoder::getFileType() const
+    {
+        return "GIF";
+    }
+
+    void GIFEncoder::setWidth( unsigned int width )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->header.width = width;
+    }
+
+    void GIFEncoder::setHeight( unsigned int height )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->header.height = height;
+    }
+
+    void GIFEncoder::setNumBands( unsigned int numBands )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->components = numBands;
+    }
+
+    void GIFEncoder::setCompressionType( const std::string & /* comp */, int /* quality */)
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+    }
+
+    void GIFEncoder::setPixelType( const std::string & pixeltype )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        vigra_precondition( pixeltype == "UINT8",
+                            "GIFEncoder::setPixelType(): "
+                            "GIF raster supports only the UINT8 pixeltype" );
+    }
+
+    unsigned int GIFEncoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    void GIFEncoder::finalizeSettings()
+    {
+        pimpl->finalize();
+        pimpl->finalized = true;
+    }
+
+    void * GIFEncoder::currentScanlineOfBand( unsigned int band )
+    {
+        if (!pimpl->scanline)
+        {
+            pimpl->bands.resize(pimpl->header.width*pimpl->header.height*pimpl->components);
+            pimpl->scanline = pimpl->bands.begin();
+        }
+         return pimpl->scanline + band;
+    }
+
+    void GIFEncoder::nextScanline()
+    {
+        pimpl->scanline += pimpl->header.width*pimpl->components;
+    }
+
+    void GIFEncoder::close()
+    {
+        pimpl->reduceTo256Colors();
+        pimpl->writeHeader();
+        pimpl->writeImageData();
+    }
+
+    void GIFEncoder::abort() {}
+}
diff --git a/src/impex/gif.hxx b/src/impex/gif.hxx
new file mode 100644
index 0000000..840786c
--- /dev/null
+++ b/src/impex/gif.hxx
@@ -0,0 +1,108 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Ullrich Koethe                       */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEX_GIF_HXX
+#define VIGRA_IMPEX_GIF_HXX
+
+#include "vigra/codec.hxx"
+
+// GIF format
+
+namespace vigra {
+
+    struct GIFDecoderImpl;
+    struct GIFEncoderImpl;
+
+    struct GIFCodecFactory : public CodecFactory
+    {
+        CodecDesc getCodecDesc() const;
+        VIGRA_UNIQUE_PTR<Decoder> getDecoder() const;
+        VIGRA_UNIQUE_PTR<Encoder> getEncoder() const;
+    };
+
+    class GIFDecoder : public Decoder
+    {
+        GIFDecoderImpl * pimpl;
+
+    public:
+
+        GIFDecoder() : pimpl(0) {}
+
+        ~GIFDecoder();
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        std::string getPixelType() const;
+
+        unsigned int getWidth() const;
+        unsigned int getHeight() const;
+        unsigned int getNumBands() const;
+        unsigned int getOffset() const;
+
+        const void * currentScanlineOfBand( unsigned int ) const;
+        void nextScanline();
+    };
+
+    class GIFEncoder : public Encoder
+    {
+        GIFEncoderImpl * pimpl;
+
+    public:
+
+        GIFEncoder() : pimpl(0) {}
+
+        ~GIFEncoder();
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        unsigned int getOffset() const;
+
+        void setWidth( unsigned int );
+        void setHeight( unsigned int );
+        void setNumBands( unsigned int );
+        void setCompressionType( const std::string &, int = -1 );
+        void setPixelType( const std::string & );
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int );
+        void nextScanline();
+    };
+}
+
+#endif // VIGRA_IMPEX_GIF_HXX
diff --git a/src/impex/hdf5_rf_impex.cxx b/src/impex/hdf5_rf_impex.cxx
new file mode 100644
index 0000000..807fc84
--- /dev/null
+++ b/src/impex/hdf5_rf_impex.cxx
@@ -0,0 +1,120 @@
+/************************************************************************/
+/*                                                                      */
+/*             Copyright 2009-2010 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifdef HasHDF5
+
+#include "vigra/random_forest_hdf5_impex.hxx"
+#include "vigra/multi_array.hxx"
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+namespace vigra {
+
+namespace detail {
+
+struct padded_number_string_data : public std::ostringstream
+{
+    unsigned w;
+};
+padded_number_string::padded_number_string(int n)
+    : padded_number(new padded_number_string_data())
+{
+    (*padded_number) << (n - 1);
+    padded_number->w = padded_number->str().size();
+}
+std::string padded_number_string::operator()(int k) const
+{
+    padded_number->str("");
+    (*padded_number) << std::setw(padded_number->w) << std::setfill('0') << k;
+    return padded_number->str();
+}
+padded_number_string::~padded_number_string()
+{
+    delete padded_number;
+}
+
+void options_import_HDF5(HDF5File & h5context,
+                        RandomForestOptions & opt,
+                        const std::string & name)
+{
+    h5context.cd(name);
+    rf_import_HDF5_to_map(h5context, opt);
+    h5context.cd_up();
+}
+
+void options_export_HDF5(HDF5File & h5context, RandomForestOptions const & opt,
+                         const std::string & name)
+{
+    h5context.cd_mk(name);
+    rf_export_map_to_HDF5(h5context, opt);
+    h5context.cd_up();
+}
+
+void dt_import_HDF5(HDF5File & h5context, detail::DecisionTree & tree,
+                            const std::string & name)
+{
+    // check if ext_param was written(?) and read it if not
+    if (tree.ext_param_.actual_msample_ == 0)
+    {
+        problemspec_import_HDF5(h5context, tree.ext_param_, rf_hdf5_ext_param);
+        tree.classCount_ = tree.ext_param_.class_count_;
+    }
+    h5context.cd(name);
+    // read topology
+    h5context.readAndResize(rf_hdf5_topology, tree.topology_);
+    // read parameters
+    h5context.readAndResize(rf_hdf5_parameters, tree.parameters_);
+    h5context.cd_up();
+}
+
+void dt_export_HDF5(HDF5File & h5context,
+                    detail::DecisionTree const & tree,
+                    const std::string & name)
+{
+    // make the folder for the tree.
+    h5context.cd_mk(name);
+    // write down topology
+    h5context.write(rf_hdf5_topology, tree.topology_);
+    // write down parameters
+    h5context.write(rf_hdf5_parameters, tree.parameters_);
+    h5context.cd_up();
+}
+
+} // namespace detail
+} // namespace vigra
+
+#endif // HasHDF5
diff --git a/src/impex/hdf5impex.cxx b/src/impex/hdf5impex.cxx
new file mode 100644
index 0000000..af0107c
--- /dev/null
+++ b/src/impex/hdf5impex.cxx
@@ -0,0 +1,219 @@
+/************************************************************************/
+/*                                                                      */
+/*             Copyright 2009-2010 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifdef HasHDF5
+
+#include "vigra/hdf5impex.hxx"
+#include "vigra/multi_array.hxx"
+#include <iostream>
+#include <cstring>
+#include <cstdio>
+
+namespace vigra {
+
+HDF5ImportInfo::HDF5ImportInfo(const char* filePath, const char* pathInFile)
+{
+    m_file_handle = HDF5Handle(H5Fopen(filePath, H5F_ACC_RDONLY, H5P_DEFAULT),
+                               &H5Fclose, "HDF5ImportInfo(): Unable to open file.");
+
+
+    m_dataset_handle = HDF5Handle(H5Dopen(m_file_handle, pathInFile, H5P_DEFAULT),
+                                  &H5Dclose, "HDF5ImportInfo(): Unable to open dataset.");
+
+
+    //DataSet dset = m_file.openDataSet(datasetname);
+    m_filename = filePath;
+    m_path = pathInFile;
+    HDF5Handle dataspace_handle(H5Dget_space(m_dataset_handle),
+                                &H5Sclose, "HDF5ImportInfo(): could not access dataset dataspace.");
+    m_dimensions = H5Sget_simple_extent_ndims(dataspace_handle);
+    //m_dimensions = dset.getSpace().getSimpleExtentNdims();
+    
+    //why?
+    //vigra_precondition( m_dimensions>=2, "HDF5ImportInfo(): Number of dimensions is lower than 2. Not an image!" );
+
+    hid_t datatype = H5Dget_type(m_dataset_handle);
+    H5T_class_t dataclass = H5Tget_class(datatype);
+    size_t datasize  = H5Tget_size(datatype);
+    H5T_sign_t datasign  = H5Tget_sign(datatype);
+
+    if(dataclass == H5T_FLOAT)
+    {
+        if(datasize == 4)
+            m_pixeltype = "FLOAT";
+        else if(datasize == 8)
+            m_pixeltype = "DOUBLE";
+    }
+    else if(dataclass == H5T_INTEGER)   
+    {
+        if(datasign == H5T_SGN_NONE)
+        {
+            if(datasize ==  1)
+                m_pixeltype = "UINT8";
+            else if(datasize == 2)
+                m_pixeltype = "UINT16";
+            else if(datasize == 4)
+                m_pixeltype = "UINT32";
+            else if(datasize == 8)
+                m_pixeltype = "UINT64";
+        }
+        else
+        {
+            if(datasize ==  1)
+                m_pixeltype = "INT8";
+            else if(datasize == 2)
+                m_pixeltype = "INT16";
+            else if(datasize == 4)
+                m_pixeltype = "INT32";
+            else if(datasize == 8)
+                m_pixeltype = "INT64";
+        }
+    }
+
+    ArrayVector<hsize_t>::size_type ndims = ArrayVector<hsize_t>::size_type(m_dimensions);
+    m_dims.resize(ndims);
+    ArrayVector<hsize_t> size(ndims);
+    ArrayVector<hsize_t> maxdims(ndims);
+    H5Sget_simple_extent_dims(dataspace_handle, size.data(), maxdims.data());
+    //dset.getSpace().getSimpleExtentDims(size, NULL);
+    // invert the dimensions to guarantee c-order
+    for(ArrayVector<hsize_t>::size_type i=0; i<ndims; i++) {
+        m_dims[i] = size[ndims-1-i];
+        //std::cout << "m_dims[" << i << "]=" << m_dims[i] << std::endl;
+    }
+}
+
+HDF5ImportInfo::~HDF5ImportInfo()
+{}
+
+
+HDF5ImportInfo::PixelType HDF5ImportInfo::pixelType() const
+{
+   const std::string pixeltype=HDF5ImportInfo::getPixelType();
+   if (pixeltype == "UINT8")
+       return HDF5ImportInfo::UINT8;
+   if (pixeltype == "UINT16")
+     return HDF5ImportInfo::UINT16;
+   if (pixeltype == "UINT32")
+     return HDF5ImportInfo::UINT32;
+   if (pixeltype == "UINT64")
+     return HDF5ImportInfo::UINT64;
+   if (pixeltype == "INT8")
+       return HDF5ImportInfo::INT8;
+   if (pixeltype == "INT16")
+     return HDF5ImportInfo::INT16;
+   if (pixeltype == "INT32")
+     return HDF5ImportInfo::INT32;
+   if (pixeltype == "INT64")
+     return HDF5ImportInfo::INT64;
+   if (pixeltype == "FLOAT")
+     return HDF5ImportInfo::FLOAT;
+   if (pixeltype == "DOUBLE")
+     return HDF5ImportInfo::DOUBLE;
+   vigra_fail( "internal error: unknown pixel type" );
+   return HDF5ImportInfo::PixelType();
+}
+
+const char * HDF5ImportInfo::getPixelType() const
+{
+    return m_pixeltype.c_str();
+}
+
+MultiArrayIndex HDF5ImportInfo::shapeOfDimension(const int dim) const 
+{ 
+    return MultiArrayIndex(m_dims[dim]); 
+}
+
+MultiArrayIndex HDF5ImportInfo::numDimensions() const 
+{ 
+    return MultiArrayIndex(m_dimensions); 
+}
+
+const std::string & HDF5ImportInfo::getPathInFile() const 
+{ 
+    return m_path; 
+}
+
+const std::string & HDF5ImportInfo::getFilePath() const 
+{ 
+    return m_filename; 
+}
+
+hid_t HDF5ImportInfo::getH5FileHandle() const 
+{ 
+    return m_file_handle; 
+}
+
+hid_t HDF5ImportInfo::getDatasetHandle() const 
+{ 
+    return m_dataset_handle; 
+}
+
+H5O_type_t HDF5_get_type(hid_t loc_id, const char* name)
+{
+    // get information about object
+    H5O_info_t infobuf;
+    H5Oget_info_by_name(loc_id, name, &infobuf, H5P_DEFAULT);
+    return infobuf.type;
+}
+
+// helper friend function for callback ls_inserter_callback()
+void HDF5_ls_insert(void* operator_data, const std::string & x)
+{
+    static_cast<HDF5File::ls_closure*>(operator_data)->insert(x);
+}
+// callback function for ls(), called via HDF5File::H5Literate()
+// see http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2
+// for as to why.
+extern "C"
+herr_t HDF5_ls_inserter_callback(hid_t loc_id, const char* name,
+                                 const H5L_info_t*, void* operator_data)
+{
+    H5O_type_t h5_type = HDF5_get_type(loc_id, name);
+    // add name to list if object is a dataset or a group
+    if (h5_type == H5O_TYPE_GROUP)
+    {
+        HDF5_ls_insert(operator_data, name + std::string("/"));
+    }
+    if (h5_type == H5O_TYPE_DATASET)
+    {
+        HDF5_ls_insert(operator_data, name);
+    }
+    return 0;
+}
+
+} // namespace vigra
+
+#endif // HasHDF5
diff --git a/src/impex/hdr.cxx b/src/impex/hdr.cxx
new file mode 100644
index 0000000..9d7631e
--- /dev/null
+++ b/src/impex/hdr.cxx
@@ -0,0 +1,390 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2001-2002 by Pablo d'Angelo                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include "vigra/sized_int.hxx"
+#include "error.hxx"
+#include "hdr.hxx"
+#include "auto_file.hxx"
+#include "void_vector.hxx"
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include "rgbe.h"
+
+extern "C"
+{
+#include "rgbe.h"
+}
+
+namespace vigra {
+
+    CodecDesc HDRCodecFactory::getCodecDesc() const
+    {
+        CodecDesc desc;
+
+        // init file type
+        desc.fileType = "HDR";
+
+        // init pixel types
+        desc.pixelTypes.resize(1);
+        desc.pixelTypes[0] = "FLOAT";
+
+        // init compression types
+        desc.compressionTypes.resize(1);
+        desc.compressionTypes[0] = "NONE";
+
+        // init magic strings
+        desc.magicStrings.resize(1);
+        desc.magicStrings[0].resize(4);
+        desc.magicStrings[0][0] = '#';
+        desc.magicStrings[0][1] = '?';
+        desc.magicStrings[0][2] = 'R';
+        desc.magicStrings[0][3] = 'A';
+
+        // init file extensions
+        desc.fileExtensions.resize(1);
+        desc.fileExtensions[0] = "hdr";
+
+        desc.bandNumbers.resize(1);
+        desc.bandNumbers[0] = 3;
+
+        return desc;
+    }
+
+    VIGRA_UNIQUE_PTR<Decoder> HDRCodecFactory::getDecoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Decoder>( new HDRDecoder() );
+    }
+
+    VIGRA_UNIQUE_PTR<Encoder> HDRCodecFactory::getEncoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Encoder>( new HDREncoder() );
+    }
+
+    class HDRCodecImpl
+    {
+
+    protected:
+
+        std::string pixeltype;
+
+        vigra_rgbe_header_info rgbe_h;
+
+        int width, height;
+        int samples_per_pixel;
+
+    public:
+
+        HDRCodecImpl();
+        ~HDRCodecImpl();
+    };
+
+    HDRCodecImpl::HDRCodecImpl()
+        : pixeltype("FLOAT")
+    {
+        samples_per_pixel = 3;
+    }
+
+    HDRCodecImpl::~HDRCodecImpl()
+    {
+    }
+
+    class HDRDecoderImpl : public HDRCodecImpl
+    {
+        friend class HDRDecoder;
+
+        // data sink
+        auto_file infile;
+#ifdef DEBUG_HDR
+        auto_file dbgFile;
+#endif
+
+        // image container
+        void_vector<float> scanline;
+        int scanline_idx;
+
+    public:
+
+        HDRDecoderImpl( const std::string & filename );
+        ~HDRDecoderImpl();
+
+        const void * currentScanlineOfBand( unsigned int band ) const;
+        void nextScanline();
+
+
+    };
+
+    HDRDecoderImpl::HDRDecoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        // Returns the layer
+    : infile( filename.c_str(), "rb" )
+#else
+    : infile( filename.c_str(), "r" )
+#endif
+{
+        // read width and height
+        VIGRA_RGBE_ReadHeader(infile.get() ,&width,&height,&rgbe_h);
+
+        scanline.resize(samples_per_pixel*width);
+        scanline_idx = 0;
+    }
+
+
+    HDRDecoderImpl::~HDRDecoderImpl()
+    {
+    }
+
+
+    const void *
+    HDRDecoderImpl::currentScanlineOfBand( unsigned int band ) const
+    {
+        return &(scanline[band]);
+    }
+
+    void HDRDecoderImpl::nextScanline()
+    {
+        auto_file & f = const_cast<auto_file &>(infile);
+        VIGRA_RGBE_ReadPixels_RLE(f.get(), scanline.data(), width, 1);
+#ifdef DEBUG_HDR
+        for (int i=0; i < width; i++) {
+            fprintf(dbgFile.get(), "%f ", scanline[i]);
+        }
+        fprintf(dbgFile.get(), "\n");
+#endif
+    }
+
+    void HDRDecoder::init( const std::string & filename )
+    {
+        pimpl = new HDRDecoderImpl(filename);
+    }
+
+    HDRDecoder::~HDRDecoder()
+    {
+        delete pimpl;
+    }
+
+    std::string HDRDecoder::getFileType() const
+    {
+        return "HDR";
+    }
+
+    unsigned int HDRDecoder::getWidth() const
+    {
+        return pimpl->width;
+    }
+
+    unsigned int HDRDecoder::getHeight() const
+    {
+        return pimpl->height;
+    }
+
+    unsigned int HDRDecoder::getNumBands() const
+    {
+        return pimpl->samples_per_pixel;
+    }
+
+    std::string HDRDecoder::getPixelType() const
+    {
+        return pimpl->pixeltype;
+    }
+
+    unsigned int HDRDecoder::getOffset() const
+    {
+        return pimpl->samples_per_pixel;
+    }
+
+    const void * HDRDecoder::currentScanlineOfBand( unsigned int band ) const
+    {
+        return pimpl->currentScanlineOfBand(band);
+    }
+
+    void HDRDecoder::nextScanline()
+    {
+        pimpl->nextScanline();
+    }
+
+    void HDRDecoder::close() {}
+    void HDRDecoder::abort() {}
+
+    // this encoder always writes interleaved tiff files
+    class HDREncoderImpl : public HDRCodecImpl
+    {
+        friend class HDREncoder;
+
+        // data sink
+        auto_file file;
+
+        // image container
+        void_vector<float> scanline;
+        bool finalized;
+
+    public:
+        // ctor, dtor
+
+        HDREncoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        // Returns the layer
+            : file( filename.c_str(), "wb" ),
+#else
+            : file( filename.c_str(), "w" ),
+#endif
+              finalized(false)
+        {
+        }
+
+        // methods
+
+        void setCompressionType( const std::string &, int );
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int band )
+        {
+            return scanline.data() + band;
+        }
+
+        void nextScanline()
+        {
+            // save one scanline
+            if (VIGRA_RGBE_WritePixels_RLE(file.get(), scanline.begin(), width, 1) != VIGRA_RGBE_RETURN_SUCCESS)
+            {
+                vigra_fail("HDREncoder: Could not write scanline");
+            }
+        }
+    };
+
+    void HDREncoderImpl::setCompressionType( const std::string & /* comp */, int /* quality */)
+    {
+    }
+
+    void HDREncoderImpl::finalizeSettings()
+    {
+        rgbe_h.valid=-1;
+        strcpy(rgbe_h.programtype,"RADIANCE");
+        rgbe_h.gamma=1.0;
+        rgbe_h.exposure=1.0;
+
+        scanline.resize(samples_per_pixel*width);
+
+        if (VIGRA_RGBE_WriteHeader(file.get(), width, height, &rgbe_h) != VIGRA_RGBE_RETURN_SUCCESS ) {
+            vigra_fail("HDREncoder: Could not write header");
+        }
+        finalized = true;
+    }
+
+    void HDREncoder::init( const std::string & filename )
+    {
+        pimpl = new HDREncoderImpl(filename);
+    }
+
+    HDREncoder::~HDREncoder()
+    {
+        delete pimpl;
+    }
+
+    std::string HDREncoder::getFileType() const
+    {
+        return "HDR";
+    }
+
+    unsigned int HDREncoder::getOffset() const
+    {
+        return pimpl->samples_per_pixel;
+    }
+
+    void HDREncoder::setWidth( unsigned int width )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->width = width;
+    }
+
+    void HDREncoder::setHeight( unsigned int height )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->height = height;
+    }
+
+    void HDREncoder::setNumBands( unsigned int bands )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        if (bands != 3) {
+            vigra_fail("HDREncoder: can only save 3 channel images");
+        }
+        pimpl->samples_per_pixel = 3;
+    }
+
+    void HDREncoder::setCompressionType( const std::string & /* comp */, int /* quality */)
+    {
+    }
+
+    void HDREncoder::setPixelType( const std::string & pixeltype )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        if ( pixeltype != "FLOAT" )
+            vigra_fail( "internal error: pixeltype not supported." );
+        pimpl->pixeltype = "FLOAT";
+    }
+
+    void HDREncoder::setPosition( const vigra::Diff2D &)
+    {
+    }
+
+    void HDREncoder::setXResolution( float )
+    {
+    }
+
+    void HDREncoder::setYResolution( float )
+    {
+    }
+
+    void HDREncoder::finalizeSettings()
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->finalizeSettings();
+    }
+
+    void * HDREncoder::currentScanlineOfBand( unsigned int band )
+    {
+        return pimpl->currentScanlineOfBand(band);
+    }
+
+    void HDREncoder::nextScanline()
+    {
+        pimpl->nextScanline();
+    }
+
+    void HDREncoder::close() {}
+    void HDREncoder::abort() {}
+}
+
diff --git a/src/impex/hdr.hxx b/src/impex/hdr.hxx
new file mode 100644
index 0000000..955cc92
--- /dev/null
+++ b/src/impex/hdr.hxx
@@ -0,0 +1,117 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2001 by Pablo d'Angelo                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_IMPEX_HDR_HXX
+#define VIGRA_IMPEX_HDR_HXX
+
+#include <vector>
+#include "vigra/diff2d.hxx"
+#include "vigra/codec.hxx"
+
+namespace vigra {
+
+    struct HDRCodecFactory : public CodecFactory
+    {
+        CodecDesc getCodecDesc() const;
+        VIGRA_UNIQUE_PTR<Decoder> getDecoder() const;
+        VIGRA_UNIQUE_PTR<Encoder> getEncoder() const;
+    };
+
+    class HDRDecoderImpl;
+    class HDREncoderImpl;
+
+    class HDRDecoder : public Decoder
+    {
+        HDRDecoderImpl * pimpl;
+
+    public:
+
+        HDRDecoder() : pimpl(0) {}
+
+        ~HDRDecoder();
+
+        std::string getFileType() const;
+        unsigned int getWidth() const;
+        unsigned int getHeight() const;
+        unsigned int getNumBands() const;
+
+        const void * currentScanlineOfBand( unsigned int ) const;
+        void nextScanline();
+
+        std::string getPixelType() const;
+        unsigned int getOffset() const;
+
+        void init( const std::string & );
+        void close();
+        void abort();
+    };
+
+    class HDREncoder : public Encoder
+    {
+        HDREncoderImpl * pimpl;
+
+    public:
+
+        HDREncoder() : pimpl(0) {}
+
+        ~HDREncoder();
+
+        std::string getFileType() const;
+        void setWidth( unsigned int );
+        void setHeight( unsigned int );
+        void setNumBands( unsigned int );
+
+        void setCompressionType( const std::string &, int = -1 );
+        void setPixelType( const std::string & );
+
+        void setPosition( const vigra::Diff2D & pos );
+        void setXResolution( float xres );
+        void setYResolution( float yres );
+
+        unsigned int getOffset() const;
+
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int );
+        void nextScanline();
+
+        void init( const std::string & );
+        void close();
+        void abort();
+    };
+}
+
+#endif // VIGRA_IMPEX_HDR_HXX
diff --git a/src/impex/iccjpeg.c b/src/impex/iccjpeg.c
new file mode 100644
index 0000000..76229fe
--- /dev/null
+++ b/src/impex/iccjpeg.c
@@ -0,0 +1,289 @@
+/************************************************************************/
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/*
+ * iccprofile.c
+ *
+ * This file provides code to read and write International Color Consortium
+ * (ICC) device profiles embedded in JFIF JPEG image files.  The ICC has
+ * defined a standard format for including such data in JPEG "APP2" markers.
+ * The code given here does not know anything about the internal structure
+ * of the ICC profile data; it just knows how to put the profile data into
+ * a JPEG file being written, or get it back out when reading.
+ *
+ * This code depends on new features added to the IJG JPEG library as of
+ * IJG release 6b; it will not compile or work with older IJG versions.
+ *
+ * NOTE: this code would need surgery to work on 16-bit-int machines
+ * with ICC profiles exceeding 64K bytes in size.  If you need to do that,
+ * change all the "unsigned int" variables to "INT32".  You'll also need
+ * to find a malloc() replacement that can allocate more than 64K.
+ *
+ * This file has been taken from the little cms project and is licensed under the MIT
+ * license.
+ */
+
+#ifdef HasJPEG
+
+#include <stdlib.h>         /* define malloc() */
+#include <stdio.h>          /* define FILE */
+#include "iccjpeg.h"
+
+
+/*
+ * Since an ICC profile can be larger than the maximum size of a JPEG marker
+ * (64K), we need provisions to split it into multiple markers.  The format
+ * defined by the ICC specifies one or more APP2 markers containing the
+ * following data:
+ *  Identifying string  ASCII "ICC_PROFILE\0"  (12 bytes)
+ *  Marker sequence number  1 for first APP2, 2 for next, etc (1 byte)
+ *  Number of markers   Total number of APP2's used (1 byte)
+ *      Profile data        (remainder of APP2 data)
+ * Decoders should use the marker sequence numbers to reassemble the profile,
+ * rather than assuming that the APP2 markers appear in the correct sequence.
+ */
+
+#define ICC_MARKER  (JPEG_APP0 + 2) /* JPEG marker code for ICC */
+#define ICC_OVERHEAD_LEN  14        /* size of non-profile data in APP2 */
+#define MAX_BYTES_IN_MARKER  65533  /* maximum data len of a JPEG marker */
+#define MAX_DATA_BYTES_IN_MARKER  (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)
+
+
+/*
+ * This routine writes the given ICC profile data into a JPEG file.
+ * It *must* be called AFTER calling jpeg_start_compress() and BEFORE
+ * the first call to jpeg_write_scanlines().
+ * (This ordering ensures that the APP2 marker(s) will appear after the
+ * SOI and JFIF or Adobe markers, but before all else.)
+ */
+
+void
+write_icc_profile (j_compress_ptr cinfo,
+           const JOCTET *icc_data_ptr,
+           unsigned int icc_data_len)
+{
+  unsigned int num_markers; /* total number of markers we'll write */
+  int cur_marker = 1;       /* per spec, counting starts at 1 */
+  unsigned int length;      /* number of bytes to write in this marker */
+
+  /* Calculate the number of markers we'll need, rounding up of course */
+  num_markers = icc_data_len / MAX_DATA_BYTES_IN_MARKER;
+  if (num_markers * MAX_DATA_BYTES_IN_MARKER != icc_data_len)
+    num_markers++;
+
+  while (icc_data_len > 0) {
+    /* length of profile to put in this marker */
+    length = icc_data_len;
+    if (length > MAX_DATA_BYTES_IN_MARKER)
+      length = MAX_DATA_BYTES_IN_MARKER;
+    icc_data_len -= length;
+
+    /* Write the JPEG marker header (APP2 code and marker length) */
+    jpeg_write_m_header(cinfo, ICC_MARKER,
+            (unsigned int) (length + ICC_OVERHEAD_LEN));
+
+    /* Write the marker identifying string "ICC_PROFILE" (null-terminated).
+     * We code it in this less-than-transparent way so that the code works
+     * even if the local character set is not ASCII.
+     */
+    jpeg_write_m_byte(cinfo, 0x49);
+    jpeg_write_m_byte(cinfo, 0x43);
+    jpeg_write_m_byte(cinfo, 0x43);
+    jpeg_write_m_byte(cinfo, 0x5F);
+    jpeg_write_m_byte(cinfo, 0x50);
+    jpeg_write_m_byte(cinfo, 0x52);
+    jpeg_write_m_byte(cinfo, 0x4F);
+    jpeg_write_m_byte(cinfo, 0x46);
+    jpeg_write_m_byte(cinfo, 0x49);
+    jpeg_write_m_byte(cinfo, 0x4C);
+    jpeg_write_m_byte(cinfo, 0x45);
+    jpeg_write_m_byte(cinfo, 0x0);
+
+    /* Add the sequencing info */
+    jpeg_write_m_byte(cinfo, cur_marker);
+    jpeg_write_m_byte(cinfo, (int) num_markers);
+
+    /* Add the profile data */
+    while (length--) {
+      jpeg_write_m_byte(cinfo, *icc_data_ptr);
+      icc_data_ptr++;
+    }
+    cur_marker++;
+  }
+}
+
+
+/*
+ * Prepare for reading an ICC profile
+ */
+
+void
+setup_read_icc_profile (j_decompress_ptr cinfo)
+{
+  /* Tell the library to keep any APP2 data it may find */
+  jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF);
+}
+
+
+/*
+ * Handy subroutine to test whether a saved marker is an ICC profile marker.
+ */
+
+static boolean
+marker_is_icc (jpeg_saved_marker_ptr marker)
+{
+  return
+    marker->marker == ICC_MARKER &&
+    marker->data_length >= ICC_OVERHEAD_LEN &&
+    /* verify the identifying string */
+    GETJOCTET(marker->data[0]) == 0x49 &&
+    GETJOCTET(marker->data[1]) == 0x43 &&
+    GETJOCTET(marker->data[2]) == 0x43 &&
+    GETJOCTET(marker->data[3]) == 0x5F &&
+    GETJOCTET(marker->data[4]) == 0x50 &&
+    GETJOCTET(marker->data[5]) == 0x52 &&
+    GETJOCTET(marker->data[6]) == 0x4F &&
+    GETJOCTET(marker->data[7]) == 0x46 &&
+    GETJOCTET(marker->data[8]) == 0x49 &&
+    GETJOCTET(marker->data[9]) == 0x4C &&
+    GETJOCTET(marker->data[10]) == 0x45 &&
+    GETJOCTET(marker->data[11]) == 0x0;
+}
+
+
+/*
+ * See if there was an ICC profile in the JPEG file being read;
+ * if so, reassemble and return the profile data.
+ *
+ * TRUE is returned if an ICC profile was found, FALSE if not.
+ * If TRUE is returned, *icc_data_ptr is set to point to the
+ * returned data, and *icc_data_len is set to its length.
+ *
+ * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc()
+ * and must be freed by the caller with free() when the caller no longer
+ * needs it.  (Alternatively, we could write this routine to use the
+ * IJG library's memory allocator, so that the data would be freed implicitly
+ * at jpeg_finish_decompress() time.  But it seems likely that many apps
+ * will prefer to have the data stick around after decompression finishes.)
+ *
+ * NOTE: if the file contains invalid ICC APP2 markers, we just silently
+ * return FALSE.  You might want to issue an error message instead.
+ */
+
+boolean
+read_icc_profile (j_decompress_ptr cinfo,
+          JOCTET **icc_data_ptr,
+          unsigned int *icc_data_len)
+{
+  jpeg_saved_marker_ptr marker;
+  int num_markers = 0;
+  int seq_no;
+  JOCTET *icc_data;
+  unsigned int total_length;
+#define MAX_SEQ_NO  255     /* sufficient since marker numbers are bytes */
+  char marker_present[MAX_SEQ_NO+1];      /* 1 if marker found */
+  unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */
+  unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */
+
+  *icc_data_ptr = NULL;     /* avoid confusion if FALSE return */
+  *icc_data_len = 0;
+
+  /* This first pass over the saved markers discovers whether there are
+   * any ICC markers and verifies the consistency of the marker numbering.
+   */
+
+  for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++)
+    marker_present[seq_no] = 0;
+
+  for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
+    if (marker_is_icc(marker)) {
+      if (num_markers == 0)
+    num_markers = GETJOCTET(marker->data[13]);
+      else if (num_markers != GETJOCTET(marker->data[13]))
+    return FALSE;       /* inconsistent num_markers fields */
+      seq_no = GETJOCTET(marker->data[12]);
+      if (seq_no <= 0 || seq_no > num_markers)
+    return FALSE;       /* bogus sequence number */
+      if (marker_present[seq_no])
+    return FALSE;       /* duplicate sequence numbers */
+      marker_present[seq_no] = 1;
+      data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
+    }
+  }
+
+  if (num_markers == 0)
+    return FALSE;
+
+  /* Check for missing markers, count total space needed,
+   * compute offset of each marker's part of the data.
+   */
+
+  total_length = 0;
+  for (seq_no = 1; seq_no <= num_markers; seq_no++) {
+    if (marker_present[seq_no] == 0)
+      return FALSE;     /* missing sequence number */
+    data_offset[seq_no] = total_length;
+    total_length += data_length[seq_no];
+  }
+
+  if (total_length <= 0)
+    return FALSE;       /* found only empty markers? */
+
+  /* Allocate space for assembled data */
+  icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET));
+  if (icc_data == NULL)
+    return FALSE;       /* oops, out of memory */
+
+  /* and fill it in */
+  for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
+    if (marker_is_icc(marker)) {
+      JOCTET FAR *src_ptr;
+      JOCTET *dst_ptr;
+      unsigned int length;
+      seq_no = GETJOCTET(marker->data[12]);
+      dst_ptr = icc_data + data_offset[seq_no];
+      src_ptr = marker->data + ICC_OVERHEAD_LEN;
+      length = data_length[seq_no];
+      while (length--) {
+    *dst_ptr++ = *src_ptr++;
+      }
+    }
+  }
+
+  *icc_data_ptr = icc_data;
+  *icc_data_len = total_length;
+
+  return TRUE;
+}
+
+#endif
diff --git a/src/impex/iccjpeg.h b/src/impex/iccjpeg.h
new file mode 100644
index 0000000..44545eb
--- /dev/null
+++ b/src/impex/iccjpeg.h
@@ -0,0 +1,84 @@
+/*
+ * iccprofile.h
+ *
+ * This file provides code to read and write International Color Consortium
+ * (ICC) device profiles embedded in JFIF JPEG image files.  The ICC has
+ * defined a standard format for including such data in JPEG "APP2" markers.
+ * The code given here does not know anything about the internal structure
+ * of the ICC profile data; it just knows how to put the profile data into
+ * a JPEG file being written, or get it back out when reading.
+ *
+ * This code depends on new features added to the IJG JPEG library as of
+ * IJG release 6b; it will not compile or work with older IJG versions.
+ *
+ * NOTE: this code would need surgery to work on 16-bit-int machines
+ * with ICC profiles exceeding 64K bytes in size.  See iccprofile.c
+ * for details.
+ *
+ * This file has been taken from the little cms project and is licensed under the MIT
+ * license.
+ */
+
+#ifndef VIGRA_ICCJPEG_H
+#define VIGRA_ICCJPEG_H
+
+#ifdef HasJPEG
+
+#include <stdio.h>      /* needed to define "FILE", "NULL" */
+# include <jpeglib.h>
+
+/*
+ * This routine writes the given ICC profile data into a JPEG file.
+ * It *must* be called AFTER calling jpeg_start_compress() and BEFORE
+ * the first call to jpeg_write_scanlines().
+ * (This ordering ensures that the APP2 marker(s) will appear after the
+ * SOI and JFIF or Adobe markers, but before all else.)
+ */
+
+extern void write_icc_profile JPP((j_compress_ptr cinfo,
+                   const JOCTET *icc_data_ptr,
+                   unsigned int icc_data_len));
+
+
+/*
+ * Reading a JPEG file that may contain an ICC profile requires two steps:
+ *
+ * 1. After jpeg_create_decompress() but before jpeg_read_header(),
+ *    call setup_read_icc_profile().  This routine tells the IJG library
+ *    to save in memory any APP2 markers it may find in the file.
+ *
+ * 2. After jpeg_read_header(), call read_icc_profile() to find out
+ *    whether there was a profile and obtain it if so.
+ */
+
+
+/*
+ * Prepare for reading an ICC profile
+ */
+
+extern void setup_read_icc_profile JPP((j_decompress_ptr cinfo));
+
+
+/*
+ * See if there was an ICC profile in the JPEG file being read;
+ * if so, reassemble and return the profile data.
+ *
+ * TRUE is returned if an ICC profile was found, FALSE if not.
+ * If TRUE is returned, *icc_data_ptr is set to point to the
+ * returned data, and *icc_data_len is set to its length.
+ *
+ * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc()
+ * and must be freed by the caller with free() when the caller no longer
+ * needs it.  (Alternatively, we could write this routine to use the
+ * IJG library's memory allocator, so that the data would be freed implicitly
+ * at jpeg_finish_decompress() time.  But it seems likely that many apps
+ * will prefer to have the data stick around after decompression finishes.)
+ */
+
+extern boolean read_icc_profile JPP((j_decompress_ptr cinfo,
+                     JOCTET **icc_data_ptr,
+                     unsigned int *icc_data_len));
+
+#endif
+
+#endif
diff --git a/src/impex/imageinfo.cxx b/src/impex/imageinfo.cxx
new file mode 100644
index 0000000..a48f295
--- /dev/null
+++ b/src/impex/imageinfo.cxx
@@ -0,0 +1,1220 @@
+/************************************************************************/
+/*                                                                      */
+/*    Copyright 2002-2013 by Gunnar Kedenburg and Ullrich Koethe        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+/* Modifications by Pablo d'Angelo
+ * updated to vigra 1.4 by Douglas Wilkins
+ * as of 18 Febuary 2006:
+ *  - Added UINT16 and UINT32 pixel types.
+ *  - Added support for obtaining extra bands beyond RGB.
+ *  - Added support for a position field that indicates the start of this
+ *    image relative to some global origin.
+ *  - Added support for x and y resolution fields.
+ *  - Added support for ICC profiles
+ */
+
+#include <iostream>
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <string>
+#include <sstream>
+#include <fstream>
+#include <vector>
+#include <iterator>
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "vigra/array_vector.hxx"
+#include "vigra/imageinfo.hxx"
+#include "codecmanager.hxx"
+#include "vigra/multi_impex.hxx"
+#include "vigra/sifImport.hxx"
+
+#if defined(_MSC_VER)
+#  include "vigra/windows.h"
+#  include <io.h>
+#else
+#  include <dirent.h>
+#  include <unistd.h>
+#endif
+
+#ifdef HasHDF5
+# include "vigra/hdf5impex.hxx"
+#endif
+
+namespace vigra
+{
+
+namespace detail
+{
+
+struct NumberCompare
+{
+    bool operator()(std::string const & l, std::string const & r) const
+    {
+        return atoi(l.c_str()) < atoi(r.c_str());
+    }
+};
+
+bool splitString(
+    const std::string &s, char separator, std::string &a, std::string &b,
+    bool reverse = false)
+{
+    std::size_t splitPos = (reverse ? s.rfind(separator) : s.find(separator));
+    if(splitPos >= s.size())
+        return false;
+    a = std::string(s.begin(), s.begin() + splitPos);
+    b = std::string(s.begin() + splitPos + 1, s.end());
+    return true;
+}
+
+std::string trimString(const std::string &s)
+{
+    unsigned int begin = 0;
+    while(begin < s.size() && ((s[begin] == ' ') || (s[begin] == '\t')))
+        ++begin;
+    std::size_t end = s.size();
+    while(end > 0 && ((s[end-1] == ' ') || (s[end-1] == '\t')))
+        --end;
+    return std::string(s.begin() + begin, s.begin() + end);
+}
+
+} // namespace detail
+
+
+// find filenames matching the pattern "<path>/base[0-9]+ext"
+#ifdef _WIN32
+void splitPathFromFilename(const std::string &pathAndName,
+                           std::string &path, std::string &name)
+{
+    // on Windows, both '/' and '\' are valid path separators
+    // note: std::basic_string.rfind() may return 'unsigned int', so explicitely cast to 'int'
+    int split = std::max(static_cast<int>(pathAndName.rfind('/')), static_cast<int>(pathAndName.rfind('\\')));
+    if(split == static_cast<int>(std::string::npos))
+    {
+        path = ".";
+        name = pathAndName;
+    }
+    else
+    {
+        for(int i=0; i<split; ++i)
+        {
+            if(pathAndName[i] == '/')
+                path += '\\';
+            else
+                path += pathAndName[i];
+        }
+        name.append(pathAndName, split+1, pathAndName.size() - split - 1);
+    }
+}
+
+VIGRA_EXPORT void findImageSequence(const std::string &name_base,
+                       const std::string &name_ext,
+                       std::vector<std::string> & numbers)
+{
+    // find out how many images we have
+    BOOL            fFinished;
+    HANDLE          hList;
+    TCHAR           szDir[MAX_PATH+1];
+    WIN32_FIND_DATA FileData;
+
+    std::string path, base;
+    splitPathFromFilename(name_base, path, base);
+
+    std::vector<std::string> result;
+    char numbuf[21], extbuf[1024];
+    std::string pattern = base + "%20[0-9]%1023s";
+
+    // Get the proper directory path
+    sprintf(szDir, "%s\\%s*%s", path.c_str(), base.c_str(), name_ext.c_str());
+
+    // Get the first file
+    hList = FindFirstFile(szDir, &FileData);
+    if (hList == INVALID_HANDLE_VALUE)
+    {
+        std::string message("importVolume(): No files matching '");
+        message = message + szDir + "'.";
+        vigra_fail(message.c_str());
+    }
+    else
+    {
+        // Traverse through the directory structure
+        fFinished = FALSE;
+        while (!fFinished)
+        {
+            if(sscanf(FileData.cFileName, pattern.c_str(), numbuf, extbuf) == 2)
+            {
+                if(strcmp(name_ext.c_str(), extbuf) == 0)
+                {
+                    std::string num(numbuf);
+                    std::string name = name_base + num + name_ext;
+                    // skip matching files names that are not images
+                    if(isImage(name.c_str()))
+                        result.push_back(num);
+                }
+            }
+            if (!FindNextFile(hList, &FileData))
+            {
+                if (GetLastError() == ERROR_NO_MORE_FILES)
+                {
+                    fFinished = TRUE;
+                }
+            }
+        }
+    }
+
+    FindClose(hList);
+
+    std::sort(result.begin(), result.end(), detail::NumberCompare());
+    numbers.swap(result);
+}
+
+#else // _WIN32
+
+void splitPathFromFilename(const std::string &pathAndName,
+                           std::string &path, std::string &name)
+{
+    int split = pathAndName.rfind('/');
+    if(split == -1)
+    {
+        path = ".";
+        name = pathAndName;
+    }
+    else
+    {
+        path.append(pathAndName, 0, split);
+        name.append(pathAndName, split+1, pathAndName.size() - split - 1);
+    }
+}
+
+void findImageSequence(const std::string &name_base,
+                       const std::string &name_ext,
+                       std::vector<std::string> & numbers)
+{
+    // find out how many images we have
+    std::string path, base;
+    splitPathFromFilename(name_base, path, base);
+
+    DIR * dir = opendir(path.c_str());
+    if(!dir)
+    {
+        std::string message("importVolume(): Unable to open directory '");
+        message = message + path + "'.";
+        vigra_fail(message.c_str());
+    }
+
+    std::vector<std::string> result;
+    dirent * dp;
+    errno = 0;
+    char numbuf[21], extbuf[1024];
+    std::string pattern = base + "%20[0-9]%1023s";
+    while ((dp = readdir(dir)) != NULL)
+    {
+        if(sscanf(dp->d_name, pattern.c_str(), numbuf, extbuf) == 2)
+        {
+            if(strcmp(name_ext.c_str(), extbuf) == 0)
+            {
+                std::string num(numbuf);
+                std::string name = name_base + num + name_ext;
+                // skip matching files names that are not images
+                if(isImage(name.c_str()))
+                    result.push_back(num);
+            }
+        }
+    }
+
+    closedir(dir);
+
+    vigra_precondition(errno == 0,
+          "importVolume(): I/O error while searching for images.");
+
+    std::sort(result.begin(), result.end(), detail::NumberCompare());
+    numbers.swap(result);
+}
+
+#endif // _WIN32
+
+// build a string from a sequence.
+#if defined(_MSC_VER) && (_MSC_VER < 1300)
+template <class iterator>
+std::string stringify (const iterator &start, const iterator &end)
+{
+    return stringifyImpl(start, end, *start);
+}
+
+template <class iterator, class Value>
+std::string stringifyImpl (const iterator &start, const iterator &end, Value const &)
+{
+    std::ostringstream out;
+    // do not place a space character after the last sequence element.
+    std::copy (start, end - 1,
+               std::ostream_iterator <Value> (out, " "));
+    out << *(end-1);
+    return out.str ();
+}
+
+#else
+
+template <class iterator>
+std::string stringify (const iterator &start, const iterator &end)
+{
+    typedef typename std::iterator_traits<iterator>::value_type value_type;
+    std::ostringstream out;
+    // do not place a space character after the last sequence element.
+    std::copy (start, end - 1,
+               std::ostream_iterator <value_type> (out, " "));
+    out << *(end-1);
+    return out.str ();
+}
+
+#endif // _MSC_VER < 1300
+
+void validate_filetype( std::string filetype )
+{
+    vigra_precondition( codecManager().fileTypeSupported(filetype),
+                        "given file type is not supported" );
+}
+
+std::string impexListFormats()
+{
+    std::vector<std::string> ft = codecManager().supportedFileTypes();
+    return stringify( ft.begin(), ft.end() );
+}
+
+std::string impexListExtensions()
+{
+    std::vector<std::string> ft = codecManager().supportedFileExtensions();
+    return stringify( ft.begin(), ft.end() );
+}
+
+bool isImage(char const * filename)
+{
+#ifdef _MSC_VER
+    return _access(filename, 0) != -1 && CodecManager::manager().getFileTypeByMagicString(filename) != "";
+#else
+    return access(filename, F_OK) == 0 && CodecManager::manager().getFileTypeByMagicString(filename) != "";
+#endif
+}
+
+// class ImageExportInfo
+
+ImageExportInfo::ImageExportInfo( const char * filename, const char * mode )
+    : m_filename(filename), m_mode(mode),
+      m_x_res(0), m_y_res(0),
+      fromMin_(0.0), fromMax_(0.0), toMin_(0.0), toMax_(0.0)
+{}
+
+ImageExportInfo::~ImageExportInfo()
+{
+}
+
+ImageExportInfo & ImageExportInfo::setFileType( const char * filetype )
+{
+    m_filetype = filetype;
+    return *this;
+}
+
+ImageExportInfo & ImageExportInfo::setForcedRangeMapping(double fromMin, double fromMax,
+                                                     double toMin, double toMax)
+{
+    fromMin_ = fromMin;
+    fromMax_ = fromMax;
+    toMin_ = toMin;
+    toMax_ = toMax;
+    return *this;
+}
+
+bool ImageExportInfo::hasForcedRangeMapping() const
+{
+    return (fromMax_ > fromMin_) || (toMax_ > toMin_);
+}
+
+double ImageExportInfo::getFromMin() const
+{
+    return fromMin_;
+}
+
+double ImageExportInfo::getFromMax() const
+{
+    return fromMax_;
+}
+
+double ImageExportInfo::getToMin() const
+{
+    return toMin_;
+}
+
+double ImageExportInfo::getToMax() const
+{
+    return toMax_;
+}
+
+ImageExportInfo & ImageExportInfo::setCompression( const char * comp )
+{
+    m_comp = comp;
+    return *this;
+}
+
+ImageExportInfo & ImageExportInfo::setFileName(const char * name)
+{
+    m_filename = name;
+    return *this;
+}
+
+const char * ImageExportInfo::getFileName() const
+{
+    return m_filename.c_str();
+}
+
+const char * ImageExportInfo::getMode() const
+{
+    return m_mode.c_str();
+}
+
+const char * ImageExportInfo::getFileType() const
+{
+    return m_filetype.c_str();
+}
+
+ImageExportInfo & ImageExportInfo::setPixelType( const char * s )
+{
+    m_pixeltype = s;
+    return *this;
+}
+
+const char * ImageExportInfo::getPixelType() const
+{
+    return m_pixeltype.c_str();
+}
+
+const char * ImageExportInfo::getCompression() const
+{
+    return m_comp.c_str();
+}
+
+float ImageExportInfo::getXResolution() const
+{
+    return m_x_res;
+}
+
+float ImageExportInfo::getYResolution() const
+{
+    return m_y_res;
+}
+
+ImageExportInfo & ImageExportInfo::setXResolution( float val )
+{
+    m_x_res = val;
+    return *this;
+}
+
+ImageExportInfo & ImageExportInfo::setYResolution( float val )
+{
+    m_y_res = val;
+    return *this;
+}
+
+ImageExportInfo & ImageExportInfo::setPosition(const vigra::Diff2D & pos)
+{
+    m_pos = pos;
+    return *this;
+}
+
+vigra::Size2D ImageExportInfo::getCanvasSize() const
+{
+    return m_canvas_size ;
+}
+
+ImageExportInfo & ImageExportInfo::setCanvasSize(const Size2D & size)
+{
+    m_canvas_size = size;
+    return *this;
+}
+
+vigra::Diff2D ImageExportInfo::getPosition() const
+{
+    return m_pos;
+}
+
+const ImageExportInfo::ICCProfile & ImageExportInfo::getICCProfile() const
+{
+    return m_icc_profile;
+}
+
+ImageExportInfo & ImageExportInfo::setICCProfile(
+    const ImageExportInfo::ICCProfile &profile)
+{
+    m_icc_profile = profile;
+    return *this;
+}
+
+// return an encoder for a given ImageExportInfo object
+VIGRA_UNIQUE_PTR<Encoder> encoder( const ImageExportInfo & info )
+{
+    VIGRA_UNIQUE_PTR<Encoder> enc;
+
+    std::string filetype = info.getFileType();
+    if ( filetype != "" ) {
+        validate_filetype(filetype);
+        VIGRA_UNIQUE_PTR<Encoder> enc2 = getEncoder( std::string( info.getFileName() ), filetype, std::string( info.getMode() ) );
+        std::swap(enc, enc2);
+    } else {
+        VIGRA_UNIQUE_PTR<Encoder> enc2 = getEncoder( std::string( info.getFileName() ), "undefined", std::string( info.getMode() ) );
+        std::swap(enc, enc2);
+    }
+
+    std::string comp = info.getCompression();
+    if ( comp != "" ) {
+
+        // check for quality parameter of JPEG compression
+        int quality = 0;
+
+        // possibility 1: quality specified as "JPEG QUALITY=N" or "JPEG-ARITH QUALITY=N"
+        // possibility 2 (deprecated): quality specified as just a number "10"
+        std::string sq(" QUALITY="), parsed_comp;
+        std::string::size_type pos = comp.rfind(sq), start = 0;
+
+        if(pos != std::string::npos)
+        {
+            start = pos + sq.size();
+            parsed_comp = comp.substr(0, pos);
+        }
+
+        std::istringstream compstream(comp.substr(start));
+        compstream >> quality;
+        if ( quality != 0 )
+        {
+            if(parsed_comp == "")
+                parsed_comp = "JPEG";
+             enc->setCompressionType( parsed_comp, quality );
+        }
+        else
+        {
+            // leave any other compression type to the codec
+            enc->setCompressionType(comp);
+        }
+    }
+
+    std::string pixel_type = info.getPixelType();
+    if ( pixel_type != "" ) {
+        if(!isPixelTypeSupported( enc->getFileType(), pixel_type ))
+        {
+            std::string msg("exportImage(): file type ");
+            msg += enc->getFileType() + " does not support requested pixel type "
+                                      + pixel_type + ".";
+            vigra_precondition(false, msg.c_str());
+        }
+        enc->setPixelType(pixel_type);
+    }
+
+    // set other properties
+    enc->setXResolution(info.getXResolution());
+    enc->setYResolution(info.getYResolution());
+    enc->setPosition(info.getPosition());
+    enc->setCanvasSize(info.getCanvasSize());
+
+    if ( info.getICCProfile().size() > 0 ) {
+        enc->setICCProfile(info.getICCProfile());
+    }
+
+    return enc;
+}
+
+// class ImageImportInfo
+
+ImageImportInfo::ImageImportInfo( const char * filename, unsigned int imageIndex )
+    : m_filename(filename), m_image_index(imageIndex)
+{
+    readHeader_();
+}
+
+ImageImportInfo::~ImageImportInfo() {
+}
+
+const char * ImageImportInfo::getFileName() const
+{
+    return m_filename.c_str();
+}
+
+const char * ImageImportInfo::getFileType() const
+{
+    return m_filetype.c_str();
+}
+
+const char * ImageImportInfo::getPixelType() const
+{
+    return m_pixeltype.c_str();
+}
+
+ImageImportInfo::PixelType ImageImportInfo::pixelType() const
+{
+    const std::string pixeltype=ImageImportInfo::getPixelType();
+   if (pixeltype == "UINT8")
+     return UINT8;
+   if (pixeltype == "INT16")
+     return INT16;
+   if (pixeltype == "UINT16")
+     return UINT16;
+   if (pixeltype == "INT32")
+     return INT32;
+   if (pixeltype == "UINT32")
+     return UINT32;
+   if (pixeltype == "FLOAT")
+     return FLOAT;
+   if (pixeltype == "DOUBLE")
+     return DOUBLE;
+   vigra_fail( "internal error: unknown pixel type" );
+   return ImageImportInfo::PixelType();
+}
+
+int ImageImportInfo::width() const
+{
+    return m_width;
+}
+
+int ImageImportInfo::height() const
+{
+    return m_height;
+}
+
+int ImageImportInfo::numBands() const
+{
+    return m_num_bands;
+}
+
+int ImageImportInfo::numExtraBands() const
+{
+    return m_num_extra_bands;
+}
+
+int ImageImportInfo::numImages() const
+{
+    return m_num_images;
+}
+
+void ImageImportInfo::setImageIndex(int index)
+{
+    m_image_index = index;
+    readHeader_();
+}
+
+int ImageImportInfo::getImageIndex() const
+{
+    return m_image_index;
+}
+
+Size2D ImageImportInfo::size() const
+{
+    return Size2D( m_width, m_height );
+}
+
+MultiArrayShape<2>::type ImageImportInfo::shape() const
+{
+    return MultiArrayShape<2>::type( m_width, m_height );
+}
+
+bool ImageImportInfo::isGrayscale() const
+{
+    return (m_num_bands - m_num_extra_bands) == 1;
+}
+
+bool ImageImportInfo::isColor() const
+{
+    return (m_num_bands - m_num_extra_bands) == 3;
+}
+
+bool ImageImportInfo::isByte() const
+{
+    return m_pixeltype == "UINT8";
+}
+
+Diff2D ImageImportInfo::getPosition() const
+{
+    return m_pos;
+}
+
+Size2D ImageImportInfo::getCanvasSize() const
+{
+    return m_canvas_size;
+}
+
+float ImageImportInfo::getXResolution() const
+{
+    return m_x_res;
+}
+
+float ImageImportInfo::getYResolution() const
+{
+    return m_y_res;
+}
+
+const ImageImportInfo::ICCProfile & ImageImportInfo::getICCProfile() const
+{
+    return m_icc_profile;
+}
+
+void ImageImportInfo::readHeader_()
+{
+    VIGRA_UNIQUE_PTR<Decoder> decoder = getDecoder(m_filename, "undefined", m_image_index);
+    m_num_images = decoder->getNumImages();
+
+    m_filetype = decoder->getFileType();
+    m_pixeltype = decoder->getPixelType();
+    m_width = decoder->getWidth();
+    m_height = decoder->getHeight();
+    m_num_bands = decoder->getNumBands();
+    m_num_extra_bands = decoder->getNumExtraBands();
+    m_pos = decoder->getPosition();
+    m_canvas_size = decoder->getCanvasSize();
+    m_x_res = decoder->getXResolution();
+    m_y_res = decoder->getYResolution();
+
+    m_icc_profile = decoder->getICCProfile();
+
+    decoder->abort(); // there probably is no better way than this
+}
+
+// return a decoder for a given ImageImportInfo object
+VIGRA_UNIQUE_PTR<Decoder> decoder( const ImageImportInfo & info )
+{
+    std::string filetype = info.getFileType();
+    validate_filetype(filetype);
+    return getDecoder( std::string( info.getFileName() ), filetype, info.getImageIndex() );
+}
+
+// class VolumeExportInfo
+
+VolumeExportInfo::VolumeExportInfo( const char * filename ) :
+        m_x_res(0), m_y_res(0), m_z_res(0),
+        m_filetype("MULTIPAGE"),
+        m_filename_base(filename), m_filename_ext(".tif"),
+        fromMin_(0.0), fromMax_(0.0), toMin_(0.0), toMax_(0.0)
+{
+}
+
+VolumeExportInfo::VolumeExportInfo( const char * name_base, const char * name_ext ) :
+        m_x_res(0), m_y_res(0), m_z_res(0),
+        m_filename_base(name_base), m_filename_ext(name_ext),
+        fromMin_(0.0), fromMax_(0.0), toMin_(0.0), toMax_(0.0)
+{
+    if(m_filename_ext == "")
+    {
+        m_filename_ext = ".tif";
+        m_filetype = "MULTIPAGE";
+    }
+}
+
+VolumeExportInfo::~VolumeExportInfo()
+{
+}
+
+VolumeExportInfo & VolumeExportInfo::setFileType( const char * filetype )
+{
+    m_filetype = filetype;
+    return *this;
+}
+
+VolumeExportInfo & VolumeExportInfo::setForcedRangeMapping(double fromMin, double fromMax,
+                                                     double toMin, double toMax)
+{
+    fromMin_ = fromMin;
+    fromMax_ = fromMax;
+    toMin_ = toMin;
+    toMax_ = toMax;
+    return *this;
+}
+
+bool VolumeExportInfo::hasForcedRangeMapping() const
+{
+    return (fromMax_ > fromMin_) || (toMax_ > toMin_);
+}
+
+double VolumeExportInfo::getFromMin() const
+{
+    return fromMin_;
+}
+
+double VolumeExportInfo::getFromMax() const
+{
+    return fromMax_;
+}
+
+double VolumeExportInfo::getToMin() const
+{
+    return toMin_;
+}
+
+double VolumeExportInfo::getToMax() const
+{
+    return toMax_;
+}
+
+VolumeExportInfo & VolumeExportInfo::setCompression( const char * comp )
+{
+    m_comp = comp;
+    return *this;
+}
+
+VolumeExportInfo & VolumeExportInfo::setFileNameExt(const char * name_ext)
+{
+    m_filename_ext = name_ext;
+    return *this;
+}
+
+const char * VolumeExportInfo::getFileNameExt() const
+{
+    return m_filename_ext.c_str();
+}
+
+VolumeExportInfo & VolumeExportInfo::setFileNameBase(const char * name_base)
+{
+    m_filename_base = name_base;
+    return *this;
+}
+
+const char * VolumeExportInfo::getFileNameBase() const
+{
+    return m_filename_base.c_str();
+}
+
+const char * VolumeExportInfo::getFileType() const
+{
+    return m_filetype.c_str();
+}
+
+VolumeExportInfo & VolumeExportInfo::setPixelType( const char * s )
+{
+    m_pixeltype = s;
+    return *this;
+}
+
+const char * VolumeExportInfo::getPixelType() const
+{
+    return m_pixeltype.c_str();
+}
+
+const char * VolumeExportInfo::getCompression() const
+{
+    return m_comp.c_str();
+}
+
+float VolumeExportInfo::getXResolution() const
+{
+    return m_x_res;
+}
+
+float VolumeExportInfo::getYResolution() const
+{
+    return m_y_res;
+}
+
+VolumeExportInfo & VolumeExportInfo::setXResolution( float val )
+{
+    m_x_res = val;
+    return *this;
+}
+
+VolumeExportInfo & VolumeExportInfo::setYResolution( float val )
+{
+    m_y_res = val;
+    return *this;
+}
+
+VolumeExportInfo & VolumeExportInfo::setZResolution( float val )
+{
+    m_z_res = val;
+    return *this;
+}
+
+VolumeExportInfo & VolumeExportInfo::setPosition(const vigra::Diff2D & pos)
+{
+    m_pos = pos;
+    return *this;
+}
+
+vigra::Diff2D VolumeExportInfo::getPosition() const
+{
+    return m_pos;
+}
+
+const VolumeExportInfo::ICCProfile & VolumeExportInfo::getICCProfile() const
+{
+    return m_icc_profile;
+}
+
+VolumeExportInfo & VolumeExportInfo::setICCProfile(
+    const VolumeExportInfo::ICCProfile &profile)
+{
+    m_icc_profile = profile;
+    return *this;
+}
+
+VolumeImportInfo::VolumeImportInfo(const std::string &filename)
+: shape_(0, 0, 0),
+  resolution_(1.f, 1.f, 1.f),
+  numBands_(0)
+{
+    std::string message;
+    
+#if 0 // defined(HasHDF5)
+    // Deactivate this code because it effectively forces multi_impex.hxx to be compiled with HDF5 only.
+    
+    // try reading from HDF5
+    // (do this first because it uses mangled 'filename/dataset_name' format)
+    {
+        // split the filename into external (true filename) and internal (dataset name) part
+        // FIXME: at present, the delimiter must be the extension '.h5' or '.hdf5' - define a more robust rule
+        std::string name, datasetName;
+        std::size_t ext = filename.rfind(".h5");
+        if(ext != std::string::npos)
+        {
+            name = filename.substr(0, ext+3);
+            datasetName = filename.substr(ext+3); 
+        }
+        else
+        {
+            ext = filename.rfind(".hdf5");
+            if(ext != std::string::npos)
+            {
+                name = filename.substr(0, ext+5);
+                datasetName = filename.substr(ext+5); 
+            }
+            else
+            {
+                name = filename;
+            }
+        }
+        
+        if(H5Fis_hdf5(name.c_str()))
+        {
+            message = std::string("VolumeImportInfo(): File '");
+            message += name + "' is HDF5, but filename doesn't contain an internal dataset path.";
+            vigra_precondition(datasetName.size() > 0, message.c_str());
+
+            HDF5File hdf5file(name, HDF5File::OpenReadOnly);
+            
+            message = std::string("VolumeImportInfo(): Dataset '");
+            message += datasetName + "' not found in HDF5 file '" + name + "'.";
+            vigra_precondition(hdf5file.existsDataset(datasetName), message.c_str());
+            
+            ArrayVector<hsize_t> shape(hdf5file.getDatasetShape(datasetName));
+            message = std::string("VolumeImportInfo(): Dataset '");
+            message += datasetName + "' in HDF5 file '" + name + "' is not a volume.";
+            vigra_precondition(shape.size() == 3 || shape.size() == 4, message.c_str());
+            
+            shape_[0] = shape[0];
+            shape_[1] = shape[1];
+            shape_[2] = shape[2];
+            pixelType_ = hdf5file.getDatasetType(datasetName);
+            numBands_ = shape.size() == 4
+                            ? shape[3]
+                            : 1;
+            baseName_ = name;
+            extension_ = datasetName;
+            fileType_ = "HDF5";
+            return;
+        }
+    }
+#endif // HasHDF5
+
+    // check if file exists
+    message = std::string("VolumeImportInfo(): File '");
+    message += filename + "' not found.";
+#ifdef _MSC_VER
+    vigra_precondition(_access(filename.c_str(), 0) != -1, message.c_str());
+#else
+    vigra_precondition(access(filename.c_str(), F_OK) == 0, message.c_str());
+#endif
+
+    // try Andor SIF format
+    {
+        std::string magic_string;
+        {
+            std::ifstream siffile (filename.c_str());
+            if( !siffile.is_open() )
+            {
+                message = std::string("VolumeImportInfo(): Unable to open file '");
+                message += filename + "'.";
+                vigra_precondition(false, message.c_str());
+            }    
+            
+            getline(siffile, magic_string);
+        }
+        if(magic_string == "Andor Technology Multi-Channel File")
+        {
+            SIFImportInfo info(filename.c_str());
+            shape_[0] = info.shapeOfDimension(0);
+            shape_[1] = info.shapeOfDimension(1);
+            shape_[2] = info.shapeOfDimension(2);
+            pixelType_ = "FLOAT";
+            numBands_ = 1;
+            baseName_ = filename;
+            fileType_ = "SIF";
+            return;            
+        }
+    }
+    
+    // try multi-page TIFF or image stack
+    if(isImage(filename.c_str()))
+    {
+        ImageImportInfo info(filename.c_str());
+        shape_[0] = info.width();
+        shape_[1] = info.height();
+        resolution_[1] = -1.f; // assume images to be right-handed
+        pixelType_ = info.getPixelType();
+        numBands_ = info.numBands();
+        
+        if(info.numImages() > 1)
+        {
+            // must be a multi-page TIFF
+            splitPathFromFilename(filename, path_, name_);
+            baseName_ = filename;
+            fileType_ = "MULTIPAGE";
+            shape_[2] = info.numImages();
+            return;
+        }
+        else
+        {
+            // try image stack loading
+            std::string::const_reverse_iterator
+                numBeginIt(filename.rbegin()), numEndIt(numBeginIt);
+
+            do
+            {
+                numEndIt = std::find_if(numBeginIt, filename.rend(),(int (*)(int)) &isdigit);
+                numBeginIt = std::find_if(numEndIt, filename.rend(), not1(std::ptr_fun((int (*)(int))&isdigit)));
+
+                if(numEndIt != filename.rend())
+                {
+                    std::string
+                        baseName(filename.begin(),
+                                 filename.begin() + (filename.rend()-numBeginIt)),
+                        extension(filename.begin() + (filename.rend()-numEndIt),
+                                  filename.end());
+
+                    std::vector<std::string> numbers;
+
+                    findImageSequence(baseName, extension, numbers);
+                    if(numbers.size() > 0)
+                    {
+                        splitPathFromFilename(baseName, path_, name_);
+                        baseName_ = baseName;
+                        extension_ = extension;
+                        shape_[2] = numbers.size();
+                        std::swap(numbers, numbers_);
+                        fileType_ = "STACK";
+                        return;
+                    }
+                }
+            }
+            while(numEndIt != filename.rend());
+        }
+        
+        message = std::string("VolumeImportInfo(): File '");
+        message += filename + "' is neither a multi-page TIFF nor a valid image stack.";
+        vigra_precondition(false, message.c_str());
+    }
+    
+    {
+        static std::string pixelTypes[] = { std::string("UNSIGNED_CHAR"), 
+                                            std::string("UNSIGNED_BYTE"), 
+                                            std::string("UINT8"), 
+                                            std::string("INT16"), 
+                                            std::string("UINT16"), 
+                                            std::string("INT32"), 
+                                            std::string("UINT32"), 
+                                            std::string("FLOAT"), 
+                                            std::string("DOUBLE"), 
+                                            std::string() };
+        
+        // try .info file loading
+        std::ifstream stream(filename.c_str());
+
+        while(stream.good())
+        {
+            char rawline[1024];
+            stream.getline(rawline, 1024);
+
+            // split off comments starting with '#':
+            std::string line, comment;
+            if(!detail::splitString(rawline, '#', line, comment))
+                line = rawline;
+
+            std::string key, value;
+            if(detail::splitString(line, '=', key, value))
+            {
+                key = detail::trimString(key);
+                value = detail::trimString(value);
+
+                if(key == "width")
+                    shape_[0] = atoi(value.c_str());
+                else if(key == "height")
+                    shape_[1] = atoi(value.c_str());
+                else if(key == "depth")
+                    shape_[2] = atoi(value.c_str());
+                else if(key == "datatype")
+                {
+                    std::string * type = pixelTypes;
+                    while(*type != "")
+                    {
+                        if(*type == value)
+                        {
+                            pixelType_ = value;
+                            break;
+                        }
+                        ++type;
+                    }
+                    vigra_precondition(*type != "",
+                        "VolumeImportInfo(): Invalid datatype '" + value +"' in .info file.");
+                    if(pixelType_ == "UNSIGNED_CHAR" || pixelType_ == "UNSIGNED_BYTE")
+                        pixelType_ = "UINT8";
+                }
+                else if(key == "description")
+                    description_ = value;
+                else if(key == "name")
+                    name_ = value;
+                else if(key == "filename")
+                    rawFilename_ = value;
+                else
+                {
+                    std::cerr << "VolumeImportInfo(): WARNING: Unknown key '" << key
+                              << "' (value '" << value << "') in info file!\n";
+                }
+            }
+            else
+            {
+                if(line[0]) // non-empty line?
+                    std::cerr << "VolumeImportInfo(): WARNING: could not parse line '" << line << "'!\n";
+            }
+        }
+
+        if((shape_[0]*shape_[1]*shape_[2] > 0) && (rawFilename_.size() > 0))
+        {
+            numBands_ = 1;
+
+            baseName_ = filename;
+            if(name_.size() > 0)
+            {
+                std::string nameDummy;
+                splitPathFromFilename(baseName_, path_, nameDummy);
+            }
+            else
+            {
+                splitPathFromFilename(baseName_, path_, name_);
+            }
+            fileType_ = "RAW";
+            return;
+        }
+    }
+
+    message = std::string("VolumeImportInfo(): Unable to load file '");
+    message += filename + "' - not a recognized format.";
+    vigra_precondition(false, message.c_str());
+}
+
+VolumeImportInfo::VolumeImportInfo(const std::string &baseName, const std::string &extension)
+: shape_(0, 0, 0),
+  resolution_(1.f, 1.f, 1.f),
+  numBands_(0)
+{
+    std::vector<std::string> numbers;
+    findImageSequence(baseName, extension, numbers);
+
+    std::string message("VolumeImportInfo(): No files matching '");
+    message += baseName + "[0-9]+" + extension + "' found.";
+    vigra_precondition(numbers.size() > 0, message.c_str());
+
+    getVolumeInfoFromFirstSlice(baseName + numbers[0] + extension);
+
+    splitPathFromFilename(baseName, path_, name_);
+    baseName_ = baseName;
+    extension_ = extension;
+    shape_[2] = numbers.size();
+    std::swap(numbers, numbers_);
+    fileType_ = "STACK";
+}
+
+void VolumeImportInfo::getVolumeInfoFromFirstSlice(const std::string &filename)
+{
+    ImageImportInfo info(filename.c_str());
+    shape_[0] = info.width();
+    shape_[1] = info.height();
+    resolution_[1] = -1.f; // assume images to be right-handed
+    pixelType_ = info.pixelType();
+    numBands_ = info.numBands();
+}
+
+VolumeImportInfo::ShapeType VolumeImportInfo::shape() const { return shape_; }
+VolumeImportInfo::Resolution VolumeImportInfo::resolution() const { return resolution_; }
+VolumeImportInfo::PixelType VolumeImportInfo::pixelType() const
+{
+    const std::string pixeltype=VolumeImportInfo::getPixelType();
+   if (pixeltype == "UINT8")
+       return ImageImportInfo::UINT8;
+   if (pixeltype == "INT16")
+     return ImageImportInfo::INT16;
+   if (pixeltype == "UINT16")
+     return ImageImportInfo::UINT16;
+   if (pixeltype == "INT32")
+     return ImageImportInfo::INT32;
+   if (pixeltype == "UINT32")
+     return ImageImportInfo::UINT32;
+   if (pixeltype == "FLOAT")
+     return ImageImportInfo::FLOAT;
+   if (pixeltype == "DOUBLE")
+     return ImageImportInfo::DOUBLE;
+   vigra_fail( "internal error: unknown pixel type" );
+   return VolumeImportInfo::PixelType();
+}
+const char * VolumeImportInfo::getPixelType() const
+{
+    return pixelType_.c_str();
+}
+const char * VolumeImportInfo::getFileType() const
+{
+    return fileType_.c_str();
+}
+MultiArrayIndex VolumeImportInfo::numBands() const { return numBands_; }
+bool VolumeImportInfo::isGrayscale() const { return numBands_ == 1; }
+bool VolumeImportInfo::isColor() const { return numBands_ > 1; }
+MultiArrayIndex VolumeImportInfo::width() const { return shape_[0]; }
+MultiArrayIndex VolumeImportInfo::height() const { return shape_[1]; }
+MultiArrayIndex VolumeImportInfo::depth() const { return shape_[2]; }
+const std::string & VolumeImportInfo::name() const { return name_; }
+const std::string & VolumeImportInfo::description() const { return description_; }
+
+} // namespace vigra
diff --git a/src/impex/jpeg.cxx b/src/impex/jpeg.cxx
new file mode 100644
index 0000000..b0710a3
--- /dev/null
+++ b/src/impex/jpeg.cxx
@@ -0,0 +1,527 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2001-2002 by Gunnar Kedenburg                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+/* Modifications by Pablo d'Angelo
+ * as of 4 March 2006:
+ *  - Added support for x and y resolution fields.
+ *  - Added ICC support.
+ */
+
+#ifdef HasJPEG
+
+#include <stdexcept>
+#include <csetjmp>
+#include "vigra/config.hxx"
+#include "void_vector.hxx"
+#include "error.hxx"
+#include "auto_file.hxx"
+#include "jpeg.hxx"
+
+extern "C" {
+
+#include <jpeglib.h>
+#include "iccjpeg.h"
+
+} // extern "C"
+
+namespace {
+
+struct JPEGCodecErrorManager
+{
+    jpeg_error_mgr pub;
+    std::jmp_buf buf;
+};
+
+} // namespace
+
+extern "C"
+{
+
+static void JPEGCodecLongjumper( j_common_ptr info )
+{
+    (*info->err->output_message)(info);
+    JPEGCodecErrorManager * error = reinterpret_cast< JPEGCodecErrorManager * >(info->err);
+    std::longjmp( error->buf, 1 );
+}
+
+} // extern "C"
+
+namespace vigra
+{
+    CodecDesc JPEGCodecFactory::getCodecDesc() const
+    {
+        CodecDesc desc;
+
+        // init file type
+        desc.fileType = "JPEG";
+
+        // init pixel types
+        desc.pixelTypes.resize(1);
+        desc.pixelTypes[0] = "UINT8";
+
+        // init compression types
+        desc.compressionTypes.resize(1);
+        desc.compressionTypes[0] = "JPEG";
+
+        // init magic strings
+        desc.magicStrings.resize(1);
+        desc.magicStrings[0].resize(3);
+        desc.magicStrings[0][0] = '\377';
+        desc.magicStrings[0][1] = '\330';
+        desc.magicStrings[0][2] = '\377';
+
+        // init file extensions
+        desc.fileExtensions.resize(2);
+        desc.fileExtensions[0] = "jpg";
+        desc.fileExtensions[1] = "jpeg";
+
+        desc.bandNumbers.resize(2);
+        desc.bandNumbers[0] = 1;
+        desc.bandNumbers[1] = 3;
+
+        return desc;
+    }
+
+    VIGRA_UNIQUE_PTR<Decoder> JPEGCodecFactory::getDecoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Decoder>( new JPEGDecoder() );
+    }
+
+    VIGRA_UNIQUE_PTR<Encoder> JPEGCodecFactory::getEncoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Encoder>( new JPEGEncoder() );
+    }
+
+    class JPEGCodecImpl
+    {
+        // extend the jpeg_error_mgr by a jump buffer
+
+    public:
+
+        // attributes
+
+        JPEGCodecErrorManager err;
+
+    };
+
+    class JPEGDecoderImplBase : public JPEGCodecImpl
+    {
+    public:
+
+        // attributes
+        jpeg_decompress_struct info;
+
+        JPEGDecoderImplBase()
+        {
+            // create the decompression struct
+            jpeg_create_decompress(&info);
+        }
+
+        virtual ~JPEGDecoderImplBase()
+        {
+            // delete the decompression struct
+            jpeg_destroy_decompress(&info);
+        }
+    };
+
+    class JPEGEncoderImplBase : public JPEGCodecImpl
+    {
+    public:
+
+        // attributes
+        jpeg_compress_struct info;
+
+        JPEGEncoderImplBase()
+        {
+            // create the decompression struct
+            jpeg_create_compress(&info);
+        }
+
+        virtual ~JPEGEncoderImplBase()
+        {
+            // delete the decompression struct
+            jpeg_destroy_compress(&info);
+        }
+    };
+
+    struct JPEGDecoderImpl : public JPEGDecoderImplBase
+    {
+        // attributes
+
+        auto_file file;
+        void_vector<JSAMPLE> bands;
+        unsigned int width, height, components, scanline;
+
+        // icc profile, if available
+        UInt32 iccProfileLength;
+        const unsigned char *iccProfilePtr;
+
+        // ctor, dtor
+        JPEGDecoderImpl( const std::string & filename );
+        ~JPEGDecoderImpl();
+
+        // methods
+
+        void init();
+    };
+
+    JPEGDecoderImpl::JPEGDecoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        : file( filename.c_str(), "rb" ),
+#else
+        : file( filename.c_str(), "r" ),
+#endif
+          bands(0), scanline(0), iccProfileLength(0), iccProfilePtr(NULL)
+    {
+        // setup setjmp() error handling
+        info.err = jpeg_std_error( ( jpeg_error_mgr * ) &err );
+        err.pub.error_exit = &JPEGCodecLongjumper;
+
+        // setup the data source
+        if (setjmp(err.buf)) {
+            vigra_fail( "error in jpeg_stdio_src()" );
+        }
+        jpeg_stdio_src( &info, file.get() );
+        // prepare for icc profile
+        setup_read_icc_profile(&info);
+    }
+
+    void JPEGDecoderImpl::init()
+    {
+        // read the header
+        if (setjmp(err.buf))
+            vigra_fail( "error in jpeg_read_header()" );
+        jpeg_read_header( &info, TRUE );
+
+        // extract ICC profile
+        JOCTET *iccBuf;
+        unsigned int iccLen;
+        if (read_icc_profile(&info, &iccBuf, &iccLen)) {
+            iccProfileLength = iccLen;
+            iccProfilePtr = iccBuf;
+        }
+
+        // start the decompression
+        if (setjmp(err.buf))
+            vigra_fail( "error in jpeg_start_decompress()" );
+        jpeg_start_decompress(&info);
+
+        // transfer interesting header information
+        width = info.output_width;
+        height = info.output_height;
+        components = info.output_components;
+
+        // alloc memory for a single scanline
+        bands.resize( width * components );
+
+        // set colorspace
+        info.jpeg_color_space = components == 1 ? JCS_GRAYSCALE : JCS_RGB;
+    }
+
+    JPEGDecoderImpl::~JPEGDecoderImpl()
+    {
+        if (iccProfilePtr && iccProfileLength)
+            free((void *)iccProfilePtr);
+    }
+
+    void JPEGDecoder::init( const std::string & filename )
+    {
+        pimpl = new JPEGDecoderImpl(filename);
+        pimpl->init();
+        if(pimpl->iccProfileLength)
+        {
+            Decoder::ICCProfile iccData(
+                pimpl->iccProfilePtr,
+                pimpl->iccProfilePtr + pimpl->iccProfileLength);
+            iccProfile_.swap(iccData);
+        }
+    }
+
+    JPEGDecoder::~JPEGDecoder()
+    {
+        delete pimpl;
+    }
+
+    std::string JPEGDecoder::getFileType() const
+    {
+        return "JPEG";
+    }
+
+    unsigned int JPEGDecoder::getWidth() const
+    {
+        return pimpl->width;
+    }
+
+    unsigned int JPEGDecoder::getHeight() const
+    {
+        return pimpl->height;
+    }
+
+    unsigned int JPEGDecoder::getNumBands() const
+    {
+        return pimpl->components;
+    }
+
+    std::string JPEGDecoder::getPixelType() const
+    {
+        return "UINT8";
+    }
+
+    unsigned int JPEGDecoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    const void * JPEGDecoder::currentScanlineOfBand( unsigned int band ) const
+    {
+        return pimpl->bands.data() + band;
+    }
+
+    void JPEGDecoder::nextScanline()
+    {
+        // check if there are scanlines left at all, eventually read one
+        JSAMPLE * band = pimpl->bands.data();
+        if ( pimpl->info.output_scanline < pimpl->info.output_height ) {
+            if (setjmp(pimpl->err.buf))
+                vigra_fail( "error in jpeg_read_scanlines()" );
+            jpeg_read_scanlines( &pimpl->info, &band, 1 );
+        }
+    }
+
+    void JPEGDecoder::close()
+    {
+        // finish any pending decompression
+        if (setjmp(pimpl->err.buf))
+            vigra_fail( "error in jpeg_finish_decompress()" );
+        jpeg_finish_decompress(&pimpl->info);
+    }
+
+    void JPEGDecoder::abort() {}
+
+    struct JPEGEncoderImpl : public JPEGEncoderImplBase
+    {
+        // attributes
+
+        auto_file file;
+        void_vector<JSAMPLE> bands;
+        unsigned int width, height, components, scanline;
+        int quality;
+
+        // icc profile, if available
+        Encoder::ICCProfile iccProfile;
+
+        // state
+        bool finalized;
+
+        // ctor, dtor
+
+        JPEGEncoderImpl( const std::string & filename );
+        ~JPEGEncoderImpl();
+
+        // methods
+
+        void finalize();
+    };
+
+    JPEGEncoderImpl::JPEGEncoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        : file( filename.c_str(), "wb" ),
+#else
+        : file( filename.c_str(), "w" ),
+#endif
+          scanline(0), quality(-1), finalized(false)
+    {
+        // setup setjmp() error handling
+        info.err = jpeg_std_error( ( jpeg_error_mgr * ) &err );
+        err.pub.error_exit = &JPEGCodecLongjumper;
+
+        // setup the data dest
+        if (setjmp(err.buf)) {
+            vigra_fail( "error in jpeg_stdio_dest()" );
+        }
+        jpeg_stdio_dest( &info, file.get() );
+    }
+
+    JPEGEncoderImpl::~JPEGEncoderImpl()
+    {
+    }
+
+    void JPEGEncoderImpl::finalize()
+    {
+        VIGRA_IMPEX_FINALIZED(finalized);
+
+        // alloc memory for a single scanline
+        bands.resize( width * components );
+        finalized = true;
+
+        // init the compression
+        info.image_width = width;
+        info.image_height = height;
+        info.input_components = components;
+
+        // rgb or gray can be assumed here
+        info.in_color_space = components == 1 ? JCS_GRAYSCALE : JCS_RGB;
+        info.X_density = 100;
+        info.Y_density = 100;
+
+        // set defaults based upon the set values
+        if (setjmp(err.buf))
+            vigra_fail( "error in jpeg_set_defaults()" );
+        jpeg_set_defaults(&info);
+
+        // set the quality level
+        if ( quality != -1 ) {
+            if (setjmp(err.buf))
+                vigra_fail( "error in jpeg_set_quality()" );
+            jpeg_set_quality( &info, quality, TRUE );
+        }
+
+        // enhance the quality a little bit
+        for ( unsigned int i = 0; i < MAX_COMPONENTS; ++i ) {
+            info.comp_info[i].h_samp_factor = 1;
+            info.comp_info[i].v_samp_factor = 1;
+        }
+#ifdef ENTROPY_OPT_SUPPORTED
+        info.optimize_coding = TRUE;
+#endif
+        info.dct_method = JDCT_FLOAT;
+
+        // start the compression
+        if (setjmp(err.buf))
+            vigra_fail( "error in jpeg_start_compress()" );
+        jpeg_start_compress( &info, TRUE );
+
+        if (iccProfile.size()) {
+            write_icc_profile(&info, iccProfile.begin(), (unsigned int)iccProfile.size());
+        }
+    }
+
+    void JPEGEncoder::init( const std::string & filename )
+    {
+        pimpl = new JPEGEncoderImpl(filename);
+    }
+
+    JPEGEncoder::~JPEGEncoder()
+    {
+        delete pimpl;
+    }
+
+    std::string JPEGEncoder::getFileType() const
+    {
+        return "JPEG";
+    }
+
+    void JPEGEncoder::setWidth( unsigned int width )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->width = width;
+    }
+
+    void JPEGEncoder::setHeight( unsigned int height )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->height = height;
+    }
+
+    void JPEGEncoder::setNumBands( unsigned int bands )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->components = bands;
+    }
+
+    void JPEGEncoder::setCompressionType( const std::string & comp,
+                                          int quality )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        if ( comp == "LOSSLESS" )
+            vigra_fail( "lossless encoding is not supported by your jpeg library." );
+        if ( comp == "JPEG_ARITH" )
+#ifdef C_ARITH_CODING_SUPPORTED
+            pimpl->info.arith_code = TRUE;
+#else
+            vigra_fail( "arithmetic encoding is not supported by your jpeg library." );
+#endif
+        pimpl->quality = quality;
+    }
+
+    void JPEGEncoder::setPixelType( const std::string & pixelType )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        if ( pixelType != "UINT8" )
+            vigra_precondition( false, "only UINT8 pixels are supported." );
+    }
+
+    unsigned int JPEGEncoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    void JPEGEncoder::setICCProfile(const ICCProfile & data)
+    {
+        pimpl->iccProfile = data;
+    }
+
+    void JPEGEncoder::finalizeSettings()
+    {
+        pimpl->finalize();
+    }
+
+    void * JPEGEncoder::currentScanlineOfBand( unsigned int band )
+    {
+        return pimpl->bands.data() + band;
+    }
+
+    void JPEGEncoder::nextScanline()
+    {
+        // check if there are scanlines left at all, eventually write one
+        JSAMPLE * band = pimpl->bands.data();
+        if ( pimpl->info.next_scanline < pimpl->info.image_height ) {
+            if (setjmp(pimpl->err.buf))
+                vigra_fail( "error in jpeg_write_scanlines()" );
+            jpeg_write_scanlines( &pimpl->info, &band, 1 );
+        }
+    }
+
+    void JPEGEncoder::close()
+    {
+        // finish any pending compression
+        if (setjmp(pimpl->err.buf))
+            vigra_fail( "error in jpeg_finish_compress()" );
+        jpeg_finish_compress( &pimpl->info );
+    }
+
+    void JPEGEncoder::abort() {}
+}
+
+#endif // HasJPEG
diff --git a/src/impex/jpeg.hxx b/src/impex/jpeg.hxx
new file mode 100644
index 0000000..2b32437
--- /dev/null
+++ b/src/impex/jpeg.hxx
@@ -0,0 +1,113 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEX_JPEG_HXX
+#define VIGRA_IMPEX_JPEG_HXX
+
+#include <vector>
+#include "vigra/codec.hxx"
+
+namespace vigra {
+
+    struct JPEGCodecFactory : public CodecFactory
+    {
+        CodecDesc getCodecDesc() const;
+        VIGRA_UNIQUE_PTR<Decoder> getDecoder() const;
+        VIGRA_UNIQUE_PTR<Encoder> getEncoder() const;
+    };
+
+    struct JPEGDecoderImpl;
+    struct JPEGEncoderImpl;
+
+    class JPEGDecoder : public Decoder
+    {
+        JPEGDecoderImpl * pimpl;
+
+    public:
+
+        JPEGDecoder() : pimpl(0) {}
+
+        ~JPEGDecoder();
+
+        std::string getFileType() const;
+        unsigned int getWidth() const;
+        unsigned int getHeight() const;
+        unsigned int getNumBands() const;
+
+        const void * currentScanlineOfBand( unsigned int ) const;
+        void nextScanline();
+
+        std::string getPixelType() const;
+        unsigned int getOffset() const;
+
+        void init( const std::string & );
+        void close();
+        void abort();
+
+    };
+
+    class JPEGEncoder : public Encoder
+    {
+        JPEGEncoderImpl * pimpl;
+
+    public:
+
+        JPEGEncoder() : pimpl(0) {}
+
+        ~JPEGEncoder();
+
+        std::string getFileType() const;
+        void setWidth( unsigned int );
+        void setHeight( unsigned int );
+        void setNumBands( unsigned int );
+
+        void setICCProfile(const ICCProfile & data);
+
+        void setCompressionType( const std::string &, int = -1 );
+        void setPixelType( const std::string & );
+        unsigned int getOffset() const;
+
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int );
+        void nextScanline();
+
+        void init( const std::string & );
+        void close();
+        void abort();
+    };
+}
+
+#endif // VIGRA_IMPEX_JPEG_HXX
diff --git a/src/impex/png.cxx b/src/impex/png.cxx
new file mode 100644
index 0000000..92373aa
--- /dev/null
+++ b/src/impex/png.cxx
@@ -0,0 +1,780 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2001-2002 by Gunnar Kedenburg                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+/* Modifications by Pablo d'Angelo
+ * updated to vigra 1.4 by Douglas Wilkins
+ * as of 18 Febuary 2006:
+ *  - Changed INT16 -> UINT16 pixel type.
+ *  - Added support for obtaining extra bands beyond RGB.
+ *  - Added support for a position field that indicates the start of this
+ *    image relative to some global origin.
+ *  - Added support for x and y resolution fields.
+ */
+
+#ifdef HasPNG
+
+#include "vigra/config.hxx"
+#include "vigra/sized_int.hxx"
+#include "void_vector.hxx"
+#include "auto_file.hxx"
+#include "png.hxx"
+#include "byteorder.hxx"
+#include "error.hxx"
+#include <stdexcept>
+#include <iostream>
+
+extern "C"
+{
+#include <png.h>
+}
+
+#if PNG_LIBPNG_VER < 10201
+#error "please update your libpng to at least 1.2.1"
+#endif
+
+// TODO: per-scanline reading/writing
+
+namespace {
+    std::string png_error_message;
+}
+
+extern "C" {
+
+// called on fatal errors
+static void PngError( png_structp png_ptr, png_const_charp error_msg )
+{
+    png_error_message = std::string(error_msg);
+    longjmp( png_jmpbuf(png_ptr), 1 );
+}
+
+// called on non-fatal errors
+static void PngWarning( png_structp, png_const_charp warning_msg )
+{
+    std::cerr << warning_msg << std::endl;
+}
+
+} // extern "C"
+
+namespace vigra {
+
+    CodecDesc PngCodecFactory::getCodecDesc() const
+    {
+        CodecDesc desc;
+
+        // init file type
+        desc.fileType = "PNG";
+
+        // init pixel types
+        desc.pixelTypes.resize(2);
+        desc.pixelTypes[0] = "UINT8";
+        desc.pixelTypes[1] = "UINT16";
+
+        // init compression types
+        desc.compressionTypes.resize(1);
+        desc.compressionTypes[0] = "LOSSLESS";
+
+        // init magic strings
+        desc.magicStrings.resize(1);
+        desc.magicStrings[0].resize(4);
+        desc.magicStrings[0][0] = '\x89';
+        desc.magicStrings[0][1] = 'P';
+        desc.magicStrings[0][2] = 'N';
+        desc.magicStrings[0][3] = 'G';
+
+        // init file extensions
+        desc.fileExtensions.resize(1);
+        desc.fileExtensions[0] = "png";
+
+        desc.bandNumbers.resize(4);
+        desc.bandNumbers[0] = 1;
+        desc.bandNumbers[1] = 2;
+        desc.bandNumbers[2] = 3;
+        desc.bandNumbers[3] = 4;
+
+        return desc;
+    }
+
+    VIGRA_UNIQUE_PTR<Decoder> PngCodecFactory::getDecoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Decoder>( new PngDecoder() );
+    }
+
+    VIGRA_UNIQUE_PTR<Encoder> PngCodecFactory::getEncoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Encoder>( new PngEncoder() );
+    }
+
+    struct PngDecoderImpl
+    {
+        // data source
+        auto_file file;
+
+        // data container
+        void_vector_base bands;
+
+        // this is where libpng stores its state
+        png_structp png;
+        png_infop info;
+
+        // image header fields
+        png_uint_32 width, height, components;
+        png_uint_32 extra_components;
+        Diff2D position;
+        int bit_depth, color_type;
+
+        // icc profile, if available
+        // the memory is owned by libpng
+        UInt32 iccProfileLength;
+        const unsigned char *iccProfilePtr;
+
+        // scanline counter
+        int scanline;
+
+        float x_resolution, y_resolution;
+
+        // number of passes needed during reading each scanline
+        int interlace_method, n_interlace_passes;
+
+        // number of channels in png (or what libpng get_channels returns)
+        int n_channels;
+
+        // size of one row
+        int rowsize;
+        void_vector<unsigned char> row_data;
+
+        // ctor, dtor
+        PngDecoderImpl( const std::string & filename );
+        ~PngDecoderImpl();
+
+        // methods
+        void init();
+        void nextScanline();
+    };
+
+    PngDecoderImpl::PngDecoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        // Returns the layer
+        : file( filename.c_str(), "rb" ),
+#else
+        : file( filename.c_str(), "r" ),
+#endif
+          bands(0), iccProfileLength(0), iccProfilePtr(0),
+          scanline(-1), x_resolution(0), y_resolution(0),
+          n_interlace_passes(0), n_channels(0)
+    {
+        png_error_message = "";
+        // check if the file is a png file
+        const unsigned int sig_size = 8;
+        png_byte sig[sig_size];
+        std::size_t readCount = std::fread( sig, sig_size, 1, file.get() );
+        const int no_png = png_sig_cmp( sig, 0, sig_size );
+        vigra_precondition( (readCount == 1) && !no_png, "given file is not a png file.");
+
+        // create png read struct with user defined handlers
+        png = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL,
+                                      &PngError, &PngWarning );
+        vigra_postcondition( png != 0, "could not create the read struct." );
+
+        // create info struct
+        if (setjmp(png_jmpbuf(png))) {
+            png_destroy_read_struct( &png, &info, NULL );
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_create_info_struct(): ").c_str() );
+        }
+        info = png_create_info_struct(png);
+        vigra_postcondition( info != 0, "could not create the info struct." );
+
+        // init png i/o
+        if (setjmp(png_jmpbuf(png))) {
+            png_destroy_read_struct( &png, &info, NULL );
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_init_io(): ").c_str() );
+        }
+        png_init_io( png, file.get() );
+
+        // specify that the signature was already read
+        if (setjmp(png_jmpbuf(png))) {
+            png_destroy_read_struct( &png, &info, NULL );
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_set_sig_bytes(): ").c_str() );
+        }
+        png_set_sig_bytes( png, sig_size );
+
+    }
+
+    PngDecoderImpl::~PngDecoderImpl()
+    {
+        png_destroy_read_struct( &png, &info, NULL );
+    }
+
+    void PngDecoderImpl::init()
+    {
+        // read all chunks up to the image data
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_read_info(): ").c_str() );
+        png_read_info( png, info );
+
+        // pull over the header fields
+        int interlace_method, compression_method, filter_method;
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_get_IHDR(): ").c_str() );
+        png_get_IHDR( png, info, &width, &height, &bit_depth, &color_type,
+                      &interlace_method, &compression_method, &filter_method );
+
+        // check whether byteorder must be swapped (png files are big-endian)
+        byteorder bo;
+        if(bit_depth == 16 && bo.get_host_byteorder() == "little endian")
+        {
+            png_set_swap(png);
+        }
+
+        // transform palette to rgb
+        if ( color_type == PNG_COLOR_TYPE_PALETTE) {
+            if (setjmp(png_jmpbuf(png)))
+                vigra_postcondition( false, png_error_message.insert(0, "error in png_palette_to_rgb(): ").c_str() );
+            png_set_palette_to_rgb(png);
+            color_type = PNG_COLOR_TYPE_RGB;
+            bit_depth = 8;
+        }
+
+        // expand gray values to at least one byte size
+        if ( color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8 ) {
+            if (setjmp(png_jmpbuf(png)))
+                vigra_postcondition(false,
+                                    png_error_message.insert(0, "error in png_set_expand_gray_1_2_4_to_8(): ").c_str());
+            png_set_expand_gray_1_2_4_to_8(png);
+            bit_depth = 8;
+        }
+
+
+#if 0
+        // strip alpha channel
+        if ( color_type & PNG_COLOR_MASK_ALPHA ) {
+            if (setjmp(png_jmpbuf(png)))
+                vigra_postcondition( false, png_error_message.insert(0, "error in png_set_strip_alpha(): ").c_str() );
+            png_set_strip_alpha(png);
+            color_type ^= PNG_COLOR_MASK_ALPHA;
+        }
+#endif /* #if 0 */
+
+
+        // find out the number of components
+        switch (color_type) {
+        case PNG_COLOR_TYPE_GRAY:
+            components = 1;
+            extra_components = 0;
+            break;
+        case PNG_COLOR_TYPE_GRAY_ALPHA:
+            components = 2;
+            extra_components = 1;
+            break;
+        case PNG_COLOR_TYPE_RGB:
+            components = 3;
+            extra_components = 0;
+            break;
+        case PNG_COLOR_TYPE_RGB_ALPHA:
+            components = 4;
+            extra_components = 1;
+            break;
+        default:
+            vigra_fail( "internal error: illegal color type." );
+        }
+
+        // read resolution
+        x_resolution = png_get_x_pixels_per_meter( png, info ) * 0.0254f;
+        y_resolution = png_get_y_pixels_per_meter( png, info ) * 0.0254f;
+
+        // read offset
+        position.x = png_get_x_offset_pixels( png, info );
+        position.y = png_get_y_offset_pixels( png, info );
+
+        // read icc profile
+#if (PNG_LIBPNG_VER > 10008) && defined(PNG_READ_iCCP_SUPPORTED)
+        char * dummyName;
+        int dummyCompType;
+#if (PNG_LIBPNG_VER < 10500)
+        char * profilePtr;
+#else
+        png_byte * profilePtr;
+#endif
+        png_uint_32 profileLen;
+        if (png_get_valid( png, info, PNG_INFO_iCCP )) {
+            png_get_iCCP(png, info, &dummyName, &dummyCompType, &profilePtr, &profileLen) ;
+            iccProfilePtr = (unsigned char *) profilePtr;
+            iccProfileLength = profileLen;
+        }
+#endif
+
+#if 0
+        // gamma correction changes the pixels, this is unwanted.
+
+        // image gamma
+        double image_gamma = 0.45455;
+        if ( png_get_valid( png, info, PNG_INFO_gAMA ) ) {
+            if (setjmp(png_jmpbuf(png)))
+                vigra_postcondition( false, png_error_message.insert(0, "error in png_get_gAMA(): ").c_str() );
+            png_get_gAMA( png, info, &image_gamma );
+        }
+
+        // screen gamma
+        double screen_gamma = 2.2;
+
+        // set gamma correction
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_set_gamma(): ").c_str() );
+        png_set_gamma( png, screen_gamma, image_gamma );
+#endif
+
+        // interlace handling, get number of read passes needed
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false,png_error_message.insert(0, "error in png_set_interlace_handling(): ").c_str());
+        n_interlace_passes = png_set_interlace_handling(png);
+
+        // update png library state to reflect any changes that were made
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_read_update_info(): ").c_str() );
+        png_read_update_info( png, info );
+
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false,png_error_message.insert(0, "error in png_get_channels(): ").c_str());
+        n_channels = png_get_channels(png, info);
+
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false,png_error_message.insert(0, "error in png_get_rowbytes(): ").c_str());
+        rowsize = png_get_rowbytes(png, info);
+
+        // allocate data buffers
+        row_data.resize(rowsize);
+    }
+
+    void PngDecoderImpl::nextScanline()
+    {
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false,png_error_message.insert(0, "error in png_read_row(): ").c_str());        
+        for (int i=0; i < n_interlace_passes; i++) 
+        {
+            png_read_row(png, row_data.begin(), NULL);
+        }
+    }
+
+    void PngDecoder::init( const std::string & filename )
+    {
+        pimpl = new PngDecoderImpl(filename);
+        pimpl->init();
+        if(pimpl->iccProfileLength)
+        {
+            Decoder::ICCProfile iccData(
+                pimpl->iccProfilePtr,
+                pimpl->iccProfilePtr + pimpl->iccProfileLength);
+            iccProfile_.swap(iccData);
+        }
+    }
+
+    PngDecoder::~PngDecoder()
+    {
+        delete pimpl;
+    }
+
+    std::string PngDecoder::getFileType() const
+    {
+        return "PNG";
+    }
+
+    unsigned int PngDecoder::getWidth() const
+    {
+        return pimpl->width;
+    }
+
+    unsigned int PngDecoder::getHeight() const
+    {
+        return pimpl->height;
+    }
+
+    unsigned int PngDecoder::getNumBands() const
+    {
+        return pimpl->components;
+    }
+
+    unsigned int PngDecoder::getNumExtraBands() const
+    {
+        return pimpl->extra_components;
+    }
+
+    float PngDecoder::getXResolution() const
+    {
+        return pimpl->x_resolution;
+    }
+
+    float PngDecoder::getYResolution() const
+    {
+        return pimpl->y_resolution;
+    }
+
+    Diff2D PngDecoder::getPosition() const
+    {
+        return pimpl->position;
+    }
+
+    std::string PngDecoder::getPixelType() const
+    {
+        switch (pimpl->bit_depth) {
+        case 8:
+            return "UINT8";
+        case 16:
+            return "UINT16";
+        default:
+            vigra_fail( "internal error: illegal pixel type." );
+        }
+        return "";
+    }
+
+    unsigned int PngDecoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    const void * PngDecoder::currentScanlineOfBand( unsigned int band ) const
+    {
+        switch (pimpl->bit_depth) {
+        case 8:
+            {
+                return pimpl->row_data.begin() + band;
+            }
+        case 16:
+            {
+                return pimpl->row_data.begin() + 2*band;
+            }
+        default:
+            vigra_fail( "internal error: illegal bit depth." );
+        }
+        return 0;
+    }
+
+    void PngDecoder::nextScanline()
+    {
+        pimpl->nextScanline();
+    }
+
+    void PngDecoder::close() {}
+
+    void PngDecoder::abort() {}
+
+    struct PngEncoderImpl
+    {
+        // data sink
+        auto_file file;
+
+        // data container
+        void_vector_base bands;
+
+        // this is where libpng stores its state
+        png_structp png;
+        png_infop info;
+
+        // image header fields
+        png_uint_32 width, height, components;
+        png_uint_32 extra_components;
+        int bit_depth, color_type;
+
+        // icc profile, if available
+        Encoder::ICCProfile iccProfile;
+
+        // scanline counter
+        int scanline;
+
+        // state
+        bool finalized;
+
+        // image layer position
+        Diff2D position;
+
+        // resolution
+        float x_resolution, y_resolution;
+
+        // ctor, dtor
+        PngEncoderImpl( const std::string & filename );
+        ~PngEncoderImpl();
+
+        // methods
+        void finalize();
+        void write();
+    };
+
+    PngEncoderImpl::PngEncoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        : file( filename.c_str(), "wb" ),
+#else
+        : file( filename.c_str(), "w" ),
+#endif
+          bands(0),
+          scanline(0), finalized(false),
+          x_resolution(0), y_resolution(0)
+    {
+        png_error_message = "";
+        // create png struct with user defined handlers
+        png = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL,
+                                       &PngError, &PngWarning );
+        vigra_postcondition( png != 0, "could not create the write struct." );
+
+        // create info struct
+        if (setjmp(png_jmpbuf(png))) {
+            png_destroy_write_struct( &png, &info );
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_info_struct(): ").c_str() );
+        }
+        info = png_create_info_struct(png);
+        if ( !info ) {
+            png_destroy_write_struct( &png, &info );
+            vigra_postcondition( false, png_error_message.insert(0, "could not create the info struct.: ").c_str() );
+        }
+
+        // init png i/o
+        if (setjmp(png_jmpbuf(png))) {
+            png_destroy_write_struct( &png, &info );
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_init_io(): ").c_str() );
+        }
+        png_init_io( png, file.get() );
+    }
+
+    PngEncoderImpl::~PngEncoderImpl()
+    {
+        png_destroy_write_struct( &png, &info );
+    }
+
+    void PngEncoderImpl::finalize()
+    {
+        // write the IHDR
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_set_IHDR(): ").c_str() );
+        png_set_IHDR( png, info, width, height, bit_depth, color_type,
+                      PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
+                      PNG_FILTER_TYPE_DEFAULT );
+
+        // set resolution
+        if (x_resolution > 0 && y_resolution > 0) {
+            if (setjmp(png_jmpbuf(png)))
+                vigra_postcondition( false, png_error_message.insert(0, "error in png_set_pHYs(): ").c_str() );
+            png_set_pHYs(png, info, (png_uint_32) (x_resolution / 0.0254 + 0.5),
+                         (png_uint_32) (y_resolution / 0.0254 + 0.5),
+                         PNG_RESOLUTION_METER);
+        }
+
+        // set offset
+        if (position.x > 0 && position.y > 0) {
+            if (setjmp(png_jmpbuf(png)))
+                vigra_postcondition( false, png_error_message.insert(0, "error in png_set_oFFs(): ").c_str() );
+            png_set_oFFs(png, info, position.x, position.y, PNG_OFFSET_PIXEL);
+        }
+
+#if (PNG_LIBPNG_VER > 10008) && defined(PNG_WRITE_iCCP_SUPPORTED)
+        // set icc profile
+        if (iccProfile.size() > 0) {
+            png_set_iCCP(png, info, (png_charp)("icc"), 0,
+#if (PNG_LIBPNG_VER < 10500)
+                         (png_charp)iccProfile.begin(), (png_uint_32)iccProfile.size());
+#else
+                         (png_byte*)iccProfile.begin(), (png_uint_32)iccProfile.size());
+#endif
+        }
+#endif
+
+        // write the info struct
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_write_info(): ").c_str() );
+        png_write_info( png, info );
+
+        // prepare the bands
+        bands.resize( ( bit_depth >> 3 ) * width * components * height );
+
+        // enter finalized state
+        finalized = true;
+    }
+
+    void PngEncoderImpl::write()
+    {
+        // prepare row pointers
+        png_uint_32 row_stride = ( bit_depth >> 3 ) * width * components;
+        void_vector<png_byte *>  row_pointers(height);
+        typedef void_vector<png_byte> vector_type;
+        vector_type & cbands = static_cast< vector_type & >(bands);
+        png_byte * mover = cbands.data();
+        for( png_uint_32 i = 0; i < height; ++i ) {
+            row_pointers[i] = mover;
+            mover += row_stride;
+        }
+
+        // check whether byteorder must be swapped (png files must be big-endian)
+        byteorder bo;
+        if(bit_depth == 16 && bo.get_host_byteorder() == "little endian")
+        {
+            png_set_swap(png);
+        }
+
+        // write the whole image
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_write_image(): ").c_str() );
+        png_write_image( png, row_pointers.begin() );
+        if (setjmp(png_jmpbuf(png)))
+            vigra_postcondition( false, png_error_message.insert(0, "error in png_write_end(): ").c_str() );
+        png_write_end(png, info);
+    }
+
+    void PngEncoder::init( const std::string & filename )
+    {
+        pimpl = new PngEncoderImpl(filename);
+    }
+
+    PngEncoder::~PngEncoder()
+    {
+        delete pimpl;
+    }
+
+    std::string PngEncoder::getFileType() const
+    {
+        return "PNG";
+    }
+
+    void PngEncoder::setWidth( unsigned int width )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->width = width;
+    }
+
+    void PngEncoder::setHeight( unsigned int height )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->height = height;
+    }
+
+    void PngEncoder::setNumBands( unsigned int bands )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        if ( bands == 1 )
+            pimpl->color_type = PNG_COLOR_TYPE_GRAY;
+        else if ( bands == 2 )
+            pimpl->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+        else if ( bands == 3 )
+            pimpl->color_type = PNG_COLOR_TYPE_RGB;
+        else if ( bands == 4 )
+            pimpl->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+        else
+            vigra_fail( "internal error: number of components not supported." );
+        pimpl->components = bands;
+    }
+
+    void PngEncoder::setCompressionType( const std::string & /* comp */, int /* quality */)
+    {
+        // nothing is settable => do nothing
+    }
+
+    void PngEncoder::setPosition( const Diff2D & pos )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->position = pos;
+    }
+
+    void PngEncoder::setXResolution( float xres )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->x_resolution = xres;
+    }
+
+    void PngEncoder::setYResolution( float yres )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->y_resolution = yres;
+    }
+
+    void PngEncoder::setPixelType( const std::string & pixelType )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        if ( pixelType == "UINT8" )
+            pimpl->bit_depth = 8;
+        else if ( pixelType == "UINT16" )
+            pimpl->bit_depth = 16;
+        else
+            vigra_fail( "internal error: pixeltype not supported." );
+    }
+
+    unsigned int PngEncoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    void PngEncoder::setICCProfile(const ICCProfile & data)
+    {
+        pimpl->iccProfile = data;
+    }
+
+    void PngEncoder::finalizeSettings()
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->finalize();
+    }
+
+    void * PngEncoder::currentScanlineOfBand( unsigned int band )
+    {
+        const unsigned int index = pimpl->width * pimpl->components
+            * pimpl->scanline + band;
+        switch (pimpl->bit_depth) {
+        case 8:
+            {
+                typedef void_vector< UInt8 > bands_type;
+                bands_type & bands
+                    = static_cast< bands_type & >(pimpl->bands);
+                return bands.data() + index;
+            }
+        case 16:
+            {
+                typedef void_vector<Int16> bands_type;
+                bands_type & bands
+                    = static_cast< bands_type & >(pimpl->bands);
+                return bands.data() + index;
+            }
+        default:
+            vigra_fail( "internal error: illegal bit depth." );
+        }
+        return 0;
+    }
+
+    void PngEncoder::nextScanline()
+    {
+        ++(pimpl->scanline);
+    }
+
+    void PngEncoder::close()
+    {
+        pimpl->write();
+    }
+
+    void PngEncoder::abort() {}
+}
+
+#endif // HasPNG
diff --git a/src/impex/png.hxx b/src/impex/png.hxx
new file mode 100644
index 0000000..7597490
--- /dev/null
+++ b/src/impex/png.hxx
@@ -0,0 +1,131 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+/* Modifications by Pablo d'Angelo
+ * updated to vigra 1.4 by Douglas Wilkins
+ * as of 18 Febuary 2006:
+ *  - Added UINT16 pixel types.
+ *  - Added support for obtaining extra bands beyond RGB.
+ *  - Added support for a position field that indicates the start of this
+ *    image relative to some global origin.
+ *  - Added support for x and y resolution fields.
+ *  - Added support for ICC profiles
+ */
+
+#ifndef VIGRA_IMPEX_PNG_HXX
+#define VIGRA_IMPEX_PNG_HXX
+
+#include "vigra/codec.hxx"
+
+// PNG - Portable Network Graphics
+
+namespace vigra {
+
+    struct PngDecoderImpl;
+    struct PngEncoderImpl;
+
+    struct PngCodecFactory : public CodecFactory
+    {
+        CodecDesc getCodecDesc() const;
+        VIGRA_UNIQUE_PTR<Decoder> getDecoder() const;
+        VIGRA_UNIQUE_PTR<Encoder> getEncoder() const;
+    };
+
+    class PngDecoder : public Decoder
+    {
+        PngDecoderImpl * pimpl;
+
+    public:
+
+        PngDecoder() : pimpl(0) {}
+
+        ~PngDecoder();
+
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        std::string getPixelType() const;
+
+        unsigned int getWidth() const;
+        unsigned int getHeight() const;
+        unsigned int getNumBands() const;
+        unsigned int getNumExtraBands() const;
+    float getXResolution() const;
+    float getYResolution() const;
+        Diff2D getPosition() const;
+
+        unsigned int getOffset() const;
+
+        const void * currentScanlineOfBand( unsigned int ) const;
+        void nextScanline();
+    };
+
+    class PngEncoder : public Encoder
+    {
+        PngEncoderImpl * pimpl;
+
+    public:
+
+        PngEncoder() : pimpl(0) {}
+
+        ~PngEncoder();
+
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        unsigned int getOffset() const;
+
+        void setWidth( unsigned int );
+        void setHeight( unsigned int );
+        void setNumBands( unsigned int );
+        void setCompressionType( const std::string &, int = -1 );
+        void setPixelType( const std::string & );
+
+        void setPosition( const Diff2D & pos );
+        void setXResolution( float xres );
+        void setYResolution( float yres );
+
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int );
+        void nextScanline();
+        void setICCProfile(const ICCProfile & data);
+    };
+}
+
+#endif // VIGRA_IMPEX_PNG_HXX
diff --git a/src/impex/pnm.cxx b/src/impex/pnm.cxx
new file mode 100644
index 0000000..9cf39d2
--- /dev/null
+++ b/src/impex/pnm.cxx
@@ -0,0 +1,827 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002-2004 by Gunnar Kedenburg                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <cmath>
+#include <cctype>
+// under Solaris, this is a macro leading to syntax errors:
+#undef isspace
+#include <iostream>
+#include <fstream>
+#include "vigra/config.hxx"
+#include "vigra/sized_int.hxx"
+#include "error.hxx"
+#include "void_vector.hxx"
+#include "pnm.hxx"
+#include "byteorder.hxx"
+
+namespace vigra {
+
+    CodecDesc PnmCodecFactory::getCodecDesc() const
+    {
+        CodecDesc desc;
+
+        // init file type
+        desc.fileType = "PNM";
+
+        // init pixel types
+        desc.pixelTypes.resize(2);
+        desc.pixelTypes[0] = "UINT8";
+        desc.pixelTypes[1] = "UINT16";
+
+        // init compression types
+        desc.compressionTypes.resize(3);
+        desc.compressionTypes[0] = "ASCII";
+        desc.compressionTypes[1] = "RAW";
+        desc.compressionTypes[2] = "BILEVEL";
+
+        // init magic strings
+        desc.magicStrings.resize(6);
+        desc.magicStrings[0].resize(2);
+        desc.magicStrings[0][0] = 'P';
+        desc.magicStrings[0][1] = '1';
+        desc.magicStrings[1].resize(2);
+        desc.magicStrings[1][0] = 'P';
+        desc.magicStrings[1][1] = '2';
+        desc.magicStrings[2].resize(2);
+        desc.magicStrings[2][0] = 'P';
+        desc.magicStrings[2][1] = '3';
+        desc.magicStrings[3].resize(2);
+        desc.magicStrings[3][0] = 'P';
+        desc.magicStrings[3][1] = '4';
+        desc.magicStrings[4].resize(2);
+        desc.magicStrings[4][0] = 'P';
+        desc.magicStrings[4][1] = '5';
+        desc.magicStrings[5].resize(2);
+        desc.magicStrings[5][0] = 'P';
+        desc.magicStrings[5][1] = '6';
+
+        // init file extensions
+        desc.fileExtensions.resize(4);
+        desc.fileExtensions[0] = "pnm";
+        desc.fileExtensions[1] = "pbm";
+        desc.fileExtensions[2] = "pgm";
+        desc.fileExtensions[3] = "ppm";
+
+        desc.bandNumbers.resize(2);
+        desc.bandNumbers[0] = 1;
+        desc.bandNumbers[1] = 3;
+
+        return desc;
+    }
+
+    VIGRA_UNIQUE_PTR<Decoder> PnmCodecFactory::getDecoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Decoder>( new PnmDecoder() );
+    }
+
+    VIGRA_UNIQUE_PTR<Encoder> PnmCodecFactory::getEncoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Encoder>( new PnmEncoder() );
+    }
+
+    struct PnmDecoderImpl
+    {
+        // data source
+        std::ifstream stream;
+
+        // image container
+        void_vector_base bands;
+
+        // data storage
+        bool raw, bilevel;
+
+        // image dimensions
+        unsigned int width, height, components;
+
+        // pixel type
+        std::string pixeltype;
+
+        // skip whitespace
+        void skip_whitespace();
+
+        // scanline reading
+        void read_bilevel_ascii_scanline();
+        void read_ascii_scanline();
+        void read_bilevel_raw_scanline();
+        void read_raw_scanline();
+
+        void read_raw_scanline_uchar();
+        void read_raw_scanline_ushort();
+        void read_raw_scanline_uint();
+
+        // skip whitespace and comment blocks
+        void skip();
+
+        // ctor
+        PnmDecoderImpl( const std::string & );
+    };
+
+    void PnmDecoderImpl::skip_whitespace()
+    {
+        while ( std::isspace( stream.peek() ) )
+            stream.get();
+    }
+
+    void PnmDecoderImpl::skip()
+    {
+        // skip whitespace
+        skip_whitespace();
+
+        // skip comments
+        while ( stream.peek() == '#' ) {
+            // skip line
+            while( stream.peek() != '\n' )
+                stream.get();
+            // skip whitespace
+            skip_whitespace();
+        }
+    }
+
+    void PnmDecoderImpl::read_bilevel_ascii_scanline()
+    {
+        // cast the bands to the correct type
+        typedef void_vector< UInt8 > vector_type;
+        vector_type & cbands = static_cast< vector_type & >(bands);
+
+        // read and store
+        for( unsigned int i = 0; i < width * components; ++i ) {
+            skip_whitespace();
+            cbands[i] = ( stream.get() - '0' ) * 255;
+        }
+    }
+
+    void PnmDecoderImpl::read_ascii_scanline()
+    {
+        // XXX implement this also for other pixel types than unsigned char
+
+        // cast the bands to the correct type
+        typedef void_vector< UInt8 > vector_type;
+        vector_type & cbands = static_cast< vector_type & >(bands);
+
+        // read and store
+        int x;
+        for( unsigned int i = 0; i < width * components; ++i ) {
+            skip_whitespace();
+            stream >> x;
+            cbands[i] = x;
+        }
+    }
+
+    void PnmDecoderImpl::read_bilevel_raw_scanline()
+    {
+        // cast the bands to the correct type
+        typedef void_vector< UInt8 > vector_type;
+        vector_type & cbands = static_cast< vector_type & >(bands);
+
+        // read and store
+        UInt8 buf = 0;
+        const unsigned int size = width / 8;  // XXX wrong assumption
+        for( unsigned int i = 0; i < size; ++i ) {
+            stream.read( reinterpret_cast< char * >(&buf), 1 );
+            for( unsigned int j = 0; j < 8; ++j )
+                cbands[ 8 * i + j ] = ( ( buf >> j ) & 1 ) * 255;
+        }
+    }
+
+    void PnmDecoderImpl::read_raw_scanline()
+    {
+        if ( pixeltype == std::string("UINT8") ) {
+            read_raw_scanline_uchar();
+        }
+        if ( pixeltype == std::string("UINT16") ) {
+            read_raw_scanline_ushort();
+        }
+        if ( pixeltype == std::string("UINT32") ) {
+            read_raw_scanline_uint();
+        }
+    }
+
+    void PnmDecoderImpl::read_raw_scanline_uchar()
+    {
+        // cast the bands to the correct type
+        typedef void_vector< UInt8 > vector_type;
+        vector_type & cbands = static_cast< vector_type & >(bands);
+
+        // read and store
+        stream.read( reinterpret_cast< char * >(cbands.data()),
+                     width * components );
+    }
+
+    void PnmDecoderImpl::read_raw_scanline_ushort()
+    {
+        // cast the bands to the correct type
+        typedef void_vector< UInt16 > vector_type;
+        vector_type & cbands = static_cast< vector_type & >(bands);
+
+        // read and store, need to swap bytes.
+        byteorder bo( "big endian" );
+        read_array( stream, bo, reinterpret_cast< UInt16 * >(cbands.data()),
+                    width * components );
+    }
+
+    void PnmDecoderImpl::read_raw_scanline_uint()
+    {
+        // cast the bands to the correct type
+        typedef void_vector< UInt32 > vector_type;
+        vector_type & cbands = static_cast< vector_type & >(bands);
+
+        byteorder bo( "big endian" );
+        read_array( stream, bo, reinterpret_cast< UInt32 * >(cbands.data()),
+                    width * components );
+    }
+
+    // reads the header.
+    PnmDecoderImpl::PnmDecoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        : stream( filename.c_str(), std::ios::binary )
+#else
+        : stream( filename.c_str() )
+#endif
+    {
+        long maxval = 1;
+        char type;
+
+        if(!stream.good())
+        {
+            std::string msg("Unable to open file '");
+            msg += filename;
+            msg += "'.";
+            vigra_precondition(0, msg.c_str());
+        }
+
+        // read the pnm header
+        vigra_postcondition( stream.get() == 'P', "bad magic number" );
+
+        // read the type, find out if the file is raw or ascii
+        type = stream.get();
+
+        switch (type) {
+        case '1': // plain bitmap
+            raw = false;
+            bilevel = true;
+            components = 1;
+            maxval = 1;
+            pixeltype = "UINT8";
+            break;
+        case '2': // plain graymap
+            raw = false;
+            bilevel = false;
+            components = 1;
+            break;
+        case '3': // plain pixmap
+            raw = false;
+            bilevel = false;
+            components = 3;
+            break;
+        case '4': // raw bitmap
+            raw = true;
+            bilevel = true;
+            components = 1;
+            maxval = 1;
+            pixeltype = "UINT8";
+            break;
+        case '5': // raw graymap
+            raw = true;
+            bilevel = false;
+            components = 1;
+            maxval = 255;
+            pixeltype = "UINT8";
+            break;
+        case '6': // raw pixmap
+            raw = true;
+            bilevel = false;
+            components = 3;
+            maxval = 255;
+            pixeltype = "UINT8";
+            break;
+        default:
+            vigra_precondition( false, "unknown magic number in file" );
+        }
+
+        // read width, height and maxval
+        skip();
+        stream >> width;
+        skip();
+        stream >> height;
+
+        // bitmaps implicitly have maxval 1
+        if ( type != '1' && type != '4' ) {
+            skip();
+            stream >> maxval;
+        }
+
+        // select a pixeltype depending on maxval
+        int bits = 0;
+        do
+        {
+            ++bits;
+            maxval >>= 1;
+        }
+        while(maxval > 0);
+
+        vigra_precondition( bits >= 0, "the file's maxval field is corrupt" );
+        if ( bits <= 8 )
+            pixeltype = "UINT8";
+        else if ( bits <= 16 )
+            pixeltype = "UINT16";
+        else if ( bits <= 32 )
+            pixeltype = "UINT32";
+        else
+            vigra_precondition( false,
+                                "the file's maxval field is too large" );
+
+        // adjust the buffer size
+        if ( pixeltype == "UINT8" )
+            bands.resize( width * components );
+        else if ( pixeltype == "UINT16" )
+            bands.resize( width * components * 2 );
+        else if ( pixeltype == "UINT32" )
+            bands.resize( width * components * 4 );
+
+#ifdef DEBUG
+        // print stats
+        std::cerr << width << "x" << height << "x" << components
+                  << "x " << pixeltype << std::endl;
+#endif
+
+        // advance to the beginning of the "data section"
+        if (raw == false)
+          skip();
+        else
+        {
+#if defined(__GNUC__) && __GNUC__ == 2
+          typedef streamoff streamOffset;
+#else
+          typedef std::ifstream::off_type streamOffset;
+#endif
+          {
+              UInt32 seekOffset = width * height * components;
+              if ( pixeltype == "UINT8" )
+                  seekOffset *= 1;
+              else if ( pixeltype == "UINT16" )
+                  seekOffset *= 2;
+              else if ( pixeltype == "UINT32" )
+                  seekOffset *= 4;
+
+              stream.seekg( -static_cast<streamOffset>(seekOffset), std::ios::end );
+          }
+        }
+    }
+
+    void PnmDecoder::init( const std::string & filename )
+    {
+        pimpl = new PnmDecoderImpl( filename.c_str() );
+    }
+
+    PnmDecoder::~PnmDecoder()
+    {
+        delete pimpl;
+    }
+
+    std::string PnmDecoder::getFileType() const
+    {
+        return "PNM";
+    }
+
+    unsigned int PnmDecoder::getWidth() const
+    {
+        return pimpl->width;
+    }
+
+    unsigned int PnmDecoder::getHeight() const
+    {
+        return pimpl->height;
+    }
+
+    unsigned int PnmDecoder::getNumBands() const
+    {
+        return pimpl->components;
+    }
+
+    std::string PnmDecoder::getPixelType() const
+    {
+        return pimpl->pixeltype;
+    }
+
+    unsigned int PnmDecoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    const void * PnmDecoder::currentScanlineOfBand( unsigned int band ) const
+    {
+        if ( pimpl->pixeltype == "UINT8" ) {
+            typedef void_vector< UInt8 > bands_type;
+            const bands_type & bands
+                = static_cast< const bands_type & >(pimpl->bands);
+            return bands.data() + band;
+        } else if ( pimpl->pixeltype == "UINT16" ) {
+            typedef void_vector<UInt16> bands_type;
+            const bands_type & bands
+                = static_cast< const bands_type & >(pimpl->bands);
+            return bands.data() + band;
+        } else if ( pimpl->pixeltype == "UINT32" ) {
+            typedef void_vector<UInt32> bands_type;
+            const bands_type & bands
+                = static_cast< const bands_type & >(pimpl->bands);
+            return bands.data() + band;
+        }
+        vigra_precondition( false, "internal error: unknown pixeltype" );
+        return 0; // this is not reached
+    }
+
+    void PnmDecoder::nextScanline()
+    {
+        if ( pimpl->raw ) {
+            if ( pimpl->bilevel ) pimpl->read_bilevel_raw_scanline();
+            else pimpl->read_raw_scanline();
+        } else {
+            if ( pimpl->bilevel ) pimpl->read_bilevel_ascii_scanline();
+            else pimpl->read_ascii_scanline();
+        }
+    }
+
+    void PnmDecoder::close()
+    {}
+
+    void PnmDecoder::abort()
+    {}
+
+    struct PnmEncoderImpl
+    {
+        // data source
+        std::ofstream stream;
+
+        // image container
+        void_vector_base bands;
+
+        // raw data storage
+        bool raw, bilevel;
+
+        // finalized settings
+        bool finalized;
+
+        // image dimensions
+        unsigned int width, height, components;
+        unsigned int maxval;
+
+        // current scanline number
+        unsigned int scanline;
+
+        // pixel type
+        std::string pixeltype;
+
+        // writing
+        void write_bilevel_ascii();
+        void write_ascii();
+        void write_bilevel_raw();
+        void write_raw();
+
+        // ctor
+        PnmEncoderImpl( const std::string & );
+    };
+
+    PnmEncoderImpl::PnmEncoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        : stream( filename.c_str(), std::ios::binary ),
+#else
+        : stream( filename.c_str() ),
+#endif
+          raw(true), bilevel(false), finalized(false), scanline(0)
+    {
+        if(!stream.good())
+        {
+            std::string msg("Unable to open file '");
+            msg += filename;
+            msg += "'.";
+            vigra_precondition(0, msg.c_str());
+        }
+    }
+
+    void PnmEncoder::init( const std::string & filename )
+    {
+        pimpl = new PnmEncoderImpl(filename);
+    }
+
+    PnmEncoder::~PnmEncoder()
+    {
+        delete pimpl;
+    }
+
+    std::string PnmEncoder::getFileType() const
+    {
+        return "PNM";
+    }
+
+    void PnmEncoder::setWidth( unsigned int width )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->width = width;
+    }
+
+    void PnmEncoder::setHeight( unsigned int height )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->height = height;
+    }
+
+    void PnmEncoder::setNumBands( unsigned int bands )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->components = bands;
+    }
+
+    void PnmEncoder::setCompressionType( const std::string & comp, int /* quality */)
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        if ( comp == "ASCII" )
+            pimpl->raw = false;
+        else if ( comp == "RAW" )
+            pimpl->raw = true;
+        else if ( comp == "BILEVEL" )
+            pimpl->bilevel = true;
+    }
+
+    void PnmEncoder::setPixelType( const std::string & pixelType )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->pixeltype = pixelType;
+    }
+
+    unsigned int PnmEncoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    void PnmEncoder::finalizeSettings()
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->finalized = true;
+
+        if ( pimpl->pixeltype == "INT32" )
+          pimpl->raw = false;
+
+        // write magic number
+        pimpl->stream << "P";
+        if ( pimpl->components == 1 ) {
+            if ( pimpl->bilevel ) {
+                // bitmap
+                pimpl->stream << (pimpl->raw ? "4" : "1");
+            } else {
+                // graymap
+                pimpl->stream << (pimpl->raw ? "5" : "2");
+            }
+        } else if ( pimpl->components == 3 ) {
+            // pixmap
+            pimpl->stream << (pimpl->raw ? "6" : "3");
+        } else
+            vigra_precondition( false, "number of bands is not supported" );
+        pimpl->stream << "\n";
+
+        // write advertisement
+        pimpl->stream << "# generated by the VIGRA library\n";
+
+        // write width and height
+        pimpl->stream << pimpl->width << " " << pimpl->height << std::endl;
+
+        // allocate image memory
+        if ( pimpl->pixeltype == "UINT8" )
+            pimpl->bands.resize( pimpl->height * pimpl->width
+                                 * pimpl->components );
+        else if ( pimpl->pixeltype == "UINT16" )
+            pimpl->bands.resize( 2 * pimpl->height * pimpl->width
+                                 * pimpl->components );
+        else if ( pimpl->pixeltype == "UINT32" )
+            pimpl->bands.resize( 4 * pimpl->height * pimpl->width
+                                 * pimpl->components );
+    }
+
+    void * PnmEncoder::currentScanlineOfBand( unsigned int band )
+    {
+        const unsigned int row_stride = pimpl->width * pimpl->components;
+        if ( pimpl->pixeltype == "UINT8" ) {
+            typedef void_vector< UInt8 > bands_type;
+            bands_type & bands
+                = static_cast< bands_type & >(pimpl->bands);
+            return bands.data() + pimpl->scanline * row_stride + band;
+        } else if ( pimpl->pixeltype == "UINT16" ) {
+            typedef void_vector<UInt16> bands_type;
+            bands_type & bands
+                = static_cast< bands_type & >(pimpl->bands);
+            return bands.data() + pimpl->scanline * row_stride + band;
+        } else if ( pimpl->pixeltype == "UINT32" ) {
+            typedef void_vector<UInt32> bands_type;
+            bands_type & bands
+                = static_cast< bands_type & >(pimpl->bands);
+            return bands.data() + pimpl->scanline * row_stride + band;
+        }
+        vigra_postcondition( false, "internal error" );
+        return 0;
+    }
+
+    void PnmEncoderImpl::write_bilevel_ascii()
+    {
+        // cast the bands to the correct type
+        typedef void_vector< UInt8 > vector_type;
+        vector_type & cbands = static_cast< vector_type & >(bands);
+
+        // write and store
+        UInt8 * iter = cbands.data();
+        for( unsigned int i = 0; i < height; ++i ) {
+            for ( unsigned int j = 0; j < width; ++j ) {
+                for ( unsigned int k = 0; k < components; ++k ) {
+                    const int value = *iter / 255;
+                    ++iter;
+                    stream << value + '0' << " ";
+                }
+                stream << " "; // separate pixels with an extra space
+            }
+            stream << std::endl; // separate lines with a newline
+        }
+    }
+
+    void PnmEncoderImpl::write_ascii()
+    {
+        if ( pixeltype == "UINT8" ) {
+
+          typedef void_vector< UInt8 > vector_type;
+          vector_type & cbands = static_cast< vector_type & >(bands);
+          UInt8 * iter = cbands.data();
+          for( unsigned int i = 0; i < height; ++i ) {
+            for ( unsigned int j = 0; j < width; ++j ) {
+              for ( unsigned int k = 0; k < components; ++k ) {
+                const int value = *iter;
+                ++iter;
+                stream << value << " ";
+              }
+              stream << " "; // separate pixels with an extra space
+            }
+            stream << std::endl; // separate lines with a newline
+          }
+
+        } else if ( pixeltype == "UINT16" ) {
+
+          typedef void_vector<UInt16> vector_type;
+          vector_type & cbands = static_cast< vector_type & >(bands);
+          UInt16 * iter = cbands.data();
+          for( unsigned int i = 0; i < height; ++i ) {
+            for ( unsigned int j = 0; j < width; ++j ) {
+              for ( unsigned int k = 0; k < components; ++k ) {
+                const int value = *iter;
+                ++iter;
+                stream << value << " ";
+              }
+              stream << " "; // separate pixels with an extra space
+            }
+            stream << std::endl; // separate lines with a newline
+          }
+
+        } else if ( pixeltype == "UINT32" ) {
+
+          typedef void_vector<UInt32> vector_type;
+          vector_type & cbands = static_cast< vector_type & >(bands);
+          UInt32 * iter = cbands.data();
+          for( unsigned int i = 0; i < height; ++i ) {
+            for ( unsigned int j = 0; j < width; ++j ) {
+              for ( unsigned int k = 0; k < components; ++k ) {
+                const int value = *iter;
+                ++iter;
+                stream << value << " ";
+              }
+              stream << " "; // separate pixels with an extra space
+            }
+            stream << std::endl; // separate lines with a newline
+          }
+
+        }
+
+        // cast the bands to the correct type
+        typedef void_vector< UInt8 > vector_type;
+        vector_type & cbands = static_cast< vector_type & >(bands);
+
+        // write and store
+        int x;
+        for( unsigned int i = 0; i < width * components; ++i ) {
+            x = cbands[i];
+            stream << x << " ";
+        }
+    }
+
+    void PnmEncoderImpl::write_bilevel_raw()
+    {
+        // cast the bands to the correct type
+        vigra_fail("PNM write bilevel raw is not implemented, sorry.");
+    }
+
+    void PnmEncoderImpl::write_raw()
+    {
+        if ( pixeltype == "UINT8" ) {
+
+            // cast the bands to the correct type
+            typedef void_vector< UInt8 > vector_type;
+            vector_type & cbands = static_cast< vector_type & >(bands);
+
+            // write and store
+            stream.write( reinterpret_cast< char * >(cbands.data()),
+                          height * width * components );
+
+        } else if ( pixeltype == "UINT16" ) {
+
+            // cast the bands to the correct type
+            typedef void_vector<UInt16> vector_type;
+            vector_type & cbands = static_cast< vector_type & >(bands);
+
+            // write and store
+            byteorder bo( "big endian" );
+
+            write_array( stream, bo, cbands.data(),
+                         height * width * components );
+        } else {
+          vigra_postcondition( false, "internal error" );
+        }
+    }
+
+    void PnmEncoder::nextScanline()
+    {
+        ++(pimpl->scanline);
+    }
+
+    void PnmEncoder::close()
+    {
+        if (!pimpl->bilevel) {
+
+            // find out maxval and print it into the stream
+            UInt32 maxval = 0;
+            if ( pimpl->pixeltype == "UINT8" ) {
+                void_vector< UInt8 > & cbands
+                    = static_cast< void_vector< UInt8 > & >
+                    (pimpl->bands);
+                for( UInt8 * iter = cbands.begin();
+                     iter < cbands.end(); ++iter )
+                    if ( *iter > maxval ) maxval = *iter;
+            } else if ( pimpl->pixeltype == "UINT16" ) {
+                void_vector<UInt16> & cbands
+                    = static_cast< void_vector<UInt16> & >(pimpl->bands);
+                for( UInt16 * iter = cbands.begin();
+                     iter < cbands.end(); ++iter )
+                    if ( *iter > maxval ) maxval = *iter;
+            } else if ( pimpl->pixeltype == "UINT32" ) {
+                void_vector<UInt32> & cbands
+                    = static_cast< void_vector<UInt32> & >(pimpl->bands);
+                for( UInt32 * iter = cbands.begin();
+                     iter < cbands.end(); ++iter )
+                    if ( *iter > maxval ) maxval = *iter;
+            }
+            pimpl->stream << maxval << std::endl;
+
+            // print the data
+            if ( pimpl->raw )
+                pimpl->write_raw();
+            else
+                pimpl->write_ascii();
+
+        } else {
+
+            // print the data
+            if ( pimpl->raw )
+                pimpl->write_bilevel_raw();
+            else
+                pimpl->write_bilevel_ascii();
+        }
+    }
+
+    void PnmEncoder::abort() {}
+
+} // namespace vigra
diff --git a/src/impex/pnm.hxx b/src/impex/pnm.hxx
new file mode 100644
index 0000000..524eb04
--- /dev/null
+++ b/src/impex/pnm.hxx
@@ -0,0 +1,110 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEX_PNM_HXX
+#define VIGRA_IMPEX_PNM_HXX
+
+#include "vigra/codec.hxx"
+
+// PNM - Portable Network Graphics
+
+namespace vigra {
+
+    struct PnmDecoderImpl;
+    struct PnmEncoderImpl;
+
+    struct PnmCodecFactory : public CodecFactory
+    {
+        CodecDesc getCodecDesc() const;
+        VIGRA_UNIQUE_PTR<Decoder> getDecoder() const;
+        VIGRA_UNIQUE_PTR<Encoder> getEncoder() const;
+    };
+
+    class PnmDecoder : public Decoder
+    {
+        PnmDecoderImpl * pimpl;
+
+    public:
+
+        PnmDecoder() : pimpl(0) {}
+
+        ~PnmDecoder();
+
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        std::string getPixelType() const;
+
+        unsigned int getWidth() const;
+        unsigned int getHeight() const;
+        unsigned int getNumBands() const;
+        unsigned int getOffset() const;
+
+        const void * currentScanlineOfBand( unsigned int ) const;
+        void nextScanline();
+    };
+
+    class PnmEncoder : public Encoder
+    {
+        PnmEncoderImpl * pimpl;
+
+    public:
+
+        PnmEncoder() : pimpl(0) {}
+
+        ~PnmEncoder();
+
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        unsigned int getOffset() const;
+
+        void setWidth( unsigned int );
+        void setHeight( unsigned int );
+        void setNumBands( unsigned int );
+        void setCompressionType( const std::string &, int = -1 );
+        void setPixelType( const std::string & );
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int );
+        void nextScanline();
+    };
+}
+
+#endif // VIGRA_IMPEX_PNM_HXX
diff --git a/src/impex/rgbe.c b/src/impex/rgbe.c
new file mode 100644
index 0000000..ac9829e
--- /dev/null
+++ b/src/impex/rgbe.c
@@ -0,0 +1,547 @@
+/************************************************************************/
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include "rgbe.h"
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+/* This file contains code to read and write four byte rgbe file format
+ developed by Greg Ward.  It handles the conversions between rgbe and
+ pixels consisting of floats.  The data is assumed to be an array of floats.
+ By default there are three floats per pixel in the order red, green, blue.
+ (RGBE_DATA_??? values control this.)  Only the mimimal header reading and 
+ writing is implemented.  Each routine does error checking and will return
+ a status value as defined below.  This code is intended as a skeleton so
+ feel free to modify it to suit your needs.
+
+ (Place notice here if you modified the code.)
+ posted to http://www.graphics.cornell.edu/~bjw/
+ written by Bruce Walter  (bjw at graphics.cornell.edu)  5/26/95
+ based on code written by Greg Ward
+*/
+
+/* offsets to red, green, and blue components in a data (float) pixel */
+#define RGBE_DATA_RED    0
+#define RGBE_DATA_GREEN  1
+#define RGBE_DATA_BLUE   2
+/* number of floats per pixel */
+#define RGBE_DATA_SIZE   3
+
+enum rgbe_error_codes {
+  rgbe_read_error,
+  rgbe_write_error,
+  rgbe_format_error,
+  rgbe_memory_error,
+};
+
+/* default error routine.  change this to change error handling */
+static int rgbe_error(int rgbe_error_code, char *msg)
+{
+  switch (rgbe_error_code) {
+  case rgbe_read_error:
+    perror("RGBE read error");
+    break;
+  case rgbe_write_error:
+    perror("RGBE write error");
+    break;
+  case rgbe_format_error:
+    fprintf(stderr,"RGBE bad file format: %s\n",msg);
+    break;
+  default:
+  case rgbe_memory_error:
+    fprintf(stderr,"RGBE error: %s\n",msg);
+  }
+  return VIGRA_RGBE_RETURN_FAILURE;
+}
+
+/* standard conversion from float pixels to rgbe pixels */
+/* note: you can remove the "inline"s if your compiler complains about it */
+INLINE void 
+VIGRA_float2rgbe(unsigned char rgbe[4], float red, float green, float blue)
+{
+  double v;
+  int e;
+
+  v = red;
+  if (green > v) v = green;
+  if (blue > v) v = blue;
+  if (v < 1e-32) {
+    rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
+  }
+  else {
+    v = frexp(v,&e) * 256.0/v;
+    rgbe[0] = (unsigned char) (red * v);
+    rgbe[1] = (unsigned char) (green * v);
+    rgbe[2] = (unsigned char) (blue * v);
+    rgbe[3] = (unsigned char) (e + 128);
+  }
+}
+
+/* standard conversion from rgbe to float pixels */
+/* note: Ward uses ldexp(col+0.5,exp-(128+8)).  However we wanted pixels */
+/*       in the range [0,1] to map back into the range [0,1].            */
+INLINE void 
+VIGRA_rgbe2float(float *red, float *green, float *blue, unsigned char rgbe[4])
+{
+  float f;
+
+  if (rgbe[3]) {   /*nonzero pixel*/
+    f = (float)ldexp(1.0,rgbe[3]-(int)(128+8));
+    *red = rgbe[0] * f;
+    *green = rgbe[1] * f;
+    *blue = rgbe[2] * f;
+  }
+  else
+    *red = *green = *blue = 0.0;
+}
+
+/* default minimal header. modify if you want more information in header */
+int VIGRA_RGBE_WriteHeader(FILE *fp, int width, int height, vigra_rgbe_header_info *info)
+{
+  char *programtype = "RGBE";
+
+  if (info && (info->valid & VIGRA_RGBE_VALID_PROGRAMTYPE))
+    programtype = info->programtype;
+  if (fprintf(fp,"#?%s\n",programtype) < 0)
+    return rgbe_error(rgbe_write_error,NULL);
+  /* The #? is to identify file type, the programtype is optional. */
+  if (info && (info->valid & VIGRA_RGBE_VALID_GAMMA)) {
+    if (fprintf(fp,"GAMMA=%g\n",info->gamma) < 0)
+      return rgbe_error(rgbe_write_error,NULL);
+  }
+  if (info && (info->valid & VIGRA_RGBE_VALID_EXPOSURE)) {
+    if (fprintf(fp,"EXPOSURE=%g\n",info->exposure) < 0)
+      return rgbe_error(rgbe_write_error,NULL);
+  }
+  if (fprintf(fp,"FORMAT=32-bit_rle_rgbe\n\n") < 0)
+    return rgbe_error(rgbe_write_error,NULL);
+  if (fprintf(fp, "-Y %d +X %d\n", height, width) < 0)
+    return rgbe_error(rgbe_write_error,NULL);
+  return VIGRA_RGBE_RETURN_SUCCESS;
+}
+
+/* minimal header reading.  modify if you want to parse more information */
+int VIGRA_RGBE_ReadHeader(FILE *fp, int *width, int *height, vigra_rgbe_header_info *info)
+{
+  char buf[128];
+  float tempf;
+  int i;
+
+  if (info) {
+    info->valid = 0;
+    info->programtype[0] = 0;
+    info->gamma = info->exposure = 1.0;
+  }
+  if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == NULL)
+    return rgbe_error(rgbe_read_error,NULL);
+
+  if ((buf[0] != '#')||(buf[1] != '?')) {
+    /* if you want to require the magic token then uncomment the next line */
+    /*return rgbe_error(rgbe_format_error,"bad initial token"); */
+  }
+  else if (info) {
+    info->valid |= VIGRA_RGBE_VALID_PROGRAMTYPE;
+    for(i=0;i<sizeof(info->programtype)-1;i++) {
+      if ((buf[i+2] == 0) || isspace(buf[i+2]))
+    break;
+      info->programtype[i] = buf[i+2];
+    }
+    info->programtype[i] = 0;
+    if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0)
+      return rgbe_error(rgbe_read_error,NULL);
+  }
+
+  for(;;) {
+    if ((buf[0] == 0)||(buf[0] == '\n'))
+      return rgbe_error(rgbe_format_error,"no FORMAT specifier found");
+    else if (strcmp(buf,"FORMAT=32-bit_rle_rgbe\n") == 0)
+      break;       /* format found so break out of loop */
+    else if (info && (sscanf(buf,"GAMMA=%g",&tempf) == 1)) {
+      info->gamma = tempf;
+      info->valid |= VIGRA_RGBE_VALID_GAMMA;
+    }
+    else if (info && (sscanf(buf,"EXPOSURE=%g",&tempf) == 1)) {
+      info->exposure = tempf;
+      info->valid |= VIGRA_RGBE_VALID_EXPOSURE;
+    }
+    if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0)
+      return rgbe_error(rgbe_read_error,NULL);
+  }
+
+#if 0
+  if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0)
+    return rgbe_error(rgbe_read_error,NULL);
+  if (strcmp(buf,"\n") != 0)
+    return rgbe_error(rgbe_format_error,
+              "missing blank line after FORMAT specifier");
+#endif
+
+  for(;;) {
+    if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0)
+      return rgbe_error(rgbe_read_error,NULL);
+
+    if (sscanf(buf,"-Y %d +X %d",height,width) == 2)
+      break;
+  }
+
+  return VIGRA_RGBE_RETURN_SUCCESS;
+}
+
+/* simple write routine that does not use run length encoding */
+/* These routines can be made faster by allocating a larger buffer and
+   fread-ing and fwrite-ing the data in larger chunks */
+int VIGRA_RGBE_WritePixels(FILE *fp, float *data, int numpixels)
+{
+  unsigned char rgbe[4];
+
+  while (numpixels-- > 0) {
+    VIGRA_float2rgbe(rgbe,data[RGBE_DATA_RED],
+           data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]);
+    data += RGBE_DATA_SIZE;
+    if (fwrite(rgbe, sizeof(rgbe), 1, fp) < 1)
+      return rgbe_error(rgbe_write_error,NULL);
+  }
+  return VIGRA_RGBE_RETURN_SUCCESS;
+}
+
+/* simple read routine.  will not correctly handle run length encoding */
+int VIGRA_RGBE_ReadPixels(FILE *fp, float *data, int numpixels)
+{
+  unsigned char rgbe[4];
+
+  while(numpixels-- > 0) {
+    if (fread(rgbe, sizeof(rgbe), 1, fp) < 1)
+      return rgbe_error(rgbe_read_error,NULL);
+    VIGRA_rgbe2float(&data[RGBE_DATA_RED],&data[RGBE_DATA_GREEN],
+           &data[RGBE_DATA_BLUE],rgbe);
+    data += RGBE_DATA_SIZE;
+  }
+  return VIGRA_RGBE_RETURN_SUCCESS;
+}
+
+
+int VIGRA_RGBE_ReadPixels_Raw(FILE *fp, unsigned char *data, unsigned int numpixels)
+{
+  if (fread(data, 4, numpixels, fp) < numpixels)
+    return rgbe_error(rgbe_read_error,NULL);
+
+  return VIGRA_RGBE_RETURN_SUCCESS;
+}
+
+
+
+/* The code below is only needed for the run-length encoded files. */
+/* Run length encoding adds considerable complexity but does */
+/* save some space.  For each scanline, each channel (r,g,b,e) is */
+/* encoded separately for better compression. */
+
+static int RGBE_WriteBytes_RLE(FILE *fp, unsigned char *data, int numbytes)
+{
+#define MINRUNLENGTH 4
+  int cur, beg_run, run_count, old_run_count, nonrun_count;
+  unsigned char buf[2];
+
+  cur = 0;
+  while(cur < numbytes) {
+    beg_run = cur;
+    /* find next run of length at least 4 if one exists */
+    run_count = old_run_count = 0;
+    while((run_count < MINRUNLENGTH) && (beg_run < numbytes)) {
+      beg_run += run_count;
+      old_run_count = run_count;
+      run_count = 1;
+      while( (beg_run + run_count < numbytes) && (run_count < 127)
+             && (data[beg_run] == data[beg_run + run_count]))
+    run_count++;
+    }
+    /* if data before next big run is a short run then write it as such */
+    if ((old_run_count > 1)&&(old_run_count == beg_run - cur)) {
+      buf[0] = 128 + old_run_count;   /*write short run*/
+      buf[1] = data[cur];
+      if (fwrite(buf,sizeof(buf[0])*2,1,fp) < 1)
+    return rgbe_error(rgbe_write_error,NULL);
+      cur = beg_run;
+    }
+    /* write out bytes until we reach the start of the next run */
+    while(cur < beg_run) {
+      nonrun_count = beg_run - cur;
+      if (nonrun_count > 128) 
+    nonrun_count = 128;
+      buf[0] = nonrun_count;
+      if (fwrite(buf,sizeof(buf[0]),1,fp) < 1)
+    return rgbe_error(rgbe_write_error,NULL);
+      if (fwrite(&data[cur],sizeof(data[0])*nonrun_count,1,fp) < 1)
+    return rgbe_error(rgbe_write_error,NULL);
+      cur += nonrun_count;
+    }
+    /* write out next run if one was found */
+    if (run_count >= MINRUNLENGTH) {
+      buf[0] = 128 + run_count;
+      buf[1] = data[beg_run];
+      if (fwrite(buf,sizeof(buf[0])*2,1,fp) < 1)
+    return rgbe_error(rgbe_write_error,NULL);
+      cur += run_count;
+    }
+  }
+  return VIGRA_RGBE_RETURN_SUCCESS;
+#undef MINRUNLENGTH
+}
+
+int VIGRA_RGBE_WritePixels_RLE(FILE *fp, float *data, int scanline_width,
+             int num_scanlines)
+{
+  unsigned char rgbe[4];
+  unsigned char *buffer;
+  int i, err;
+
+  if ((scanline_width < 8)||(scanline_width > 0x7fff))
+    /* run length encoding is not allowed so write flat*/
+    return VIGRA_RGBE_WritePixels(fp,data,scanline_width*num_scanlines);
+  buffer = (unsigned char *)malloc(sizeof(unsigned char)*4*scanline_width);
+  if (buffer == NULL) 
+    /* no buffer space so write flat */
+    return VIGRA_RGBE_WritePixels(fp,data,scanline_width*num_scanlines);
+  while(num_scanlines-- > 0) {
+    rgbe[0] = 2;
+    rgbe[1] = 2;
+    rgbe[2] = scanline_width >> 8;
+    rgbe[3] = scanline_width & 0xFF;
+    if (fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) {
+      free(buffer);
+      return rgbe_error(rgbe_write_error,NULL);
+    }
+    for(i=0;i<scanline_width;i++) {
+      VIGRA_float2rgbe(rgbe,data[RGBE_DATA_RED],
+         data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]);
+      buffer[i] = rgbe[0];
+      buffer[i+scanline_width] = rgbe[1];
+      buffer[i+2*scanline_width] = rgbe[2];
+      buffer[i+3*scanline_width] = rgbe[3];
+      data += RGBE_DATA_SIZE;
+    }
+    /* write out each of the four channels separately run length encoded */
+    /* first red, then green, then blue, then exponent */
+    for(i=0;i<4;i++) {
+      if ((err = RGBE_WriteBytes_RLE(fp,&buffer[i*scanline_width],
+                     scanline_width)) != VIGRA_RGBE_RETURN_SUCCESS) {
+    free(buffer);
+    return err;
+      }
+    }
+  }
+  free(buffer);
+  return VIGRA_RGBE_RETURN_SUCCESS;
+}
+      
+int VIGRA_RGBE_ReadPixels_RLE(FILE *fp, float *data, int scanline_width,
+            int num_scanlines)
+{
+  unsigned char rgbe[4], *scanline_buffer, *ptr, *ptr_end;
+  int i, count;
+  unsigned char buf[2];
+
+  if ((scanline_width < 8)||(scanline_width > 0x7fff))
+    /* run length encoding is not allowed so read flat*/
+    return VIGRA_RGBE_ReadPixels(fp,data,scanline_width*num_scanlines);
+  scanline_buffer = NULL;
+  /* read in each successive scanline */
+  while(num_scanlines > 0) {
+    if (fread(rgbe,sizeof(rgbe),1,fp) < 1) {
+      free(scanline_buffer);
+      return rgbe_error(rgbe_read_error,NULL);
+    }
+    if ((rgbe[0] != 2)||(rgbe[1] != 2)||(rgbe[2] & 0x80)) {
+      /* this file is not run length encoded */
+      VIGRA_rgbe2float(&data[0],&data[1],&data[2],rgbe);
+      data += RGBE_DATA_SIZE;
+      free(scanline_buffer);
+      return VIGRA_RGBE_ReadPixels(fp,data,scanline_width*num_scanlines-1);
+    }
+    if ((((int)rgbe[2])<<8 | rgbe[3]) != scanline_width) {
+      free(scanline_buffer);
+      return rgbe_error(rgbe_format_error,"wrong scanline width");
+    }
+    if (scanline_buffer == NULL)
+      scanline_buffer = (unsigned char *)
+    malloc(sizeof(unsigned char)*4*scanline_width);
+    if (scanline_buffer == NULL) 
+      return rgbe_error(rgbe_memory_error,"unable to allocate buffer space");
+    
+    ptr = &scanline_buffer[0];
+    /* read each of the four channels for the scanline into the buffer */
+    for(i=0;i<4;i++) {
+      ptr_end = &scanline_buffer[(i+1)*scanline_width];
+      while(ptr < ptr_end) {
+    if (fread(buf,sizeof(buf[0])*2,1,fp) < 1) {
+      free(scanline_buffer);
+      return rgbe_error(rgbe_read_error,NULL);
+    }
+    if (buf[0] > 128) {
+      /* a run of the same value */
+      count = buf[0]-128;
+      if ((count == 0)||(count > ptr_end - ptr)) {
+        free(scanline_buffer);
+        return rgbe_error(rgbe_format_error,"bad scanline data");
+      }
+      while(count-- > 0)
+        *ptr++ = buf[1];
+    }
+    else {
+      /* a non-run */
+      count = buf[0];
+      if ((count == 0)||(count > ptr_end - ptr)) {
+        free(scanline_buffer);
+        return rgbe_error(rgbe_format_error,"bad scanline data");
+      }
+      *ptr++ = buf[1];
+      if (--count > 0) {
+        if (fread(ptr,sizeof(*ptr)*count,1,fp) < 1) {
+          free(scanline_buffer);
+          return rgbe_error(rgbe_read_error,NULL);
+        }
+        ptr += count;
+      }
+    }
+      }
+    }
+    /* now convert data from buffer into floats */
+    for(i=0;i<scanline_width;i++) {
+      rgbe[0] = scanline_buffer[i];
+      rgbe[1] = scanline_buffer[i+scanline_width];
+      rgbe[2] = scanline_buffer[i+2*scanline_width];
+      rgbe[3] = scanline_buffer[i+3*scanline_width];
+      VIGRA_rgbe2float(&data[RGBE_DATA_RED],&data[RGBE_DATA_GREEN],
+         &data[RGBE_DATA_BLUE],rgbe);
+      data += RGBE_DATA_SIZE;
+    }
+    num_scanlines--;
+  }
+  free(scanline_buffer);
+  return VIGRA_RGBE_RETURN_SUCCESS;
+}
+
+
+int VIGRA_RGBE_ReadPixels_Raw_RLE(FILE *fp, unsigned char *data, int scanline_width,
+            int num_scanlines)
+{
+  unsigned char rgbe[4], *scanline_buffer, *ptr, *ptr_end;
+  int i, count;
+  unsigned char buf[2];
+
+  if ((scanline_width < 8)||(scanline_width > 0x7fff))
+    /* run length encoding is not allowed so read flat*/
+    return VIGRA_RGBE_ReadPixels_Raw(fp,data,scanline_width*num_scanlines);
+
+  scanline_buffer = NULL;
+  /* read in each successive scanline */
+  while(num_scanlines > 0) {
+    if (fread(rgbe,sizeof(rgbe),1,fp) < 1) {
+      free(scanline_buffer);
+      return rgbe_error(rgbe_read_error,NULL);
+    }
+
+    if ((rgbe[0] != 2)||(rgbe[1] != 2)||(rgbe[2] & 0x80)) {
+      /* this file is not run length encoded */
+      data[0] = rgbe[0];
+      data[1] = rgbe[1];
+      data[2] = rgbe[2];
+      data[3] = rgbe[3];
+      data += RGBE_DATA_SIZE;
+      free(scanline_buffer);
+      return VIGRA_RGBE_ReadPixels_Raw(fp,data,scanline_width*num_scanlines-1);
+    }
+
+    if ((((int)rgbe[2])<<8 | rgbe[3]) != scanline_width) {
+      free(scanline_buffer);
+      return rgbe_error(rgbe_format_error,"wrong scanline width");
+    }
+
+    if (scanline_buffer == NULL)
+      scanline_buffer = (unsigned char *) malloc(sizeof(unsigned char)*4*scanline_width);
+
+    if (scanline_buffer == NULL) 
+      return rgbe_error(rgbe_memory_error,"unable to allocate buffer space");
+    
+    ptr = &scanline_buffer[0];
+    /* read each of the four channels for the scanline into the buffer */
+    for(i=0;i<4;i++) {
+      ptr_end = &scanline_buffer[(i+1)*scanline_width];
+      while(ptr < ptr_end) {
+        if (fread(buf,sizeof(buf[0])*2,1,fp) < 1) {
+          free(scanline_buffer);
+          return rgbe_error(rgbe_read_error,NULL);
+        }
+        if (buf[0] > 128) {
+          /* a run of the same value */
+          count = buf[0]-128;
+          if ((count == 0)||(count > ptr_end - ptr)) {
+            free(scanline_buffer);
+            return rgbe_error(rgbe_format_error,"bad scanline data");
+          }
+          while(count-- > 0)
+            *ptr++ = buf[1];
+        }
+        else {
+          /* a non-run */
+          count = buf[0];
+          if ((count == 0)||(count > ptr_end - ptr)) {
+            free(scanline_buffer);
+            return rgbe_error(rgbe_format_error,"bad scanline data");
+          }
+          *ptr++ = buf[1];
+          if (--count > 0) {
+            if (fread(ptr,sizeof(*ptr)*count,1,fp) < 1) {
+              free(scanline_buffer);
+              return rgbe_error(rgbe_read_error,NULL);
+            }
+            ptr += count;
+          }
+        }
+      }
+    }
+    /* copy byte data to output */
+    for(i=0;i<scanline_width;i++) {
+      data[0] = scanline_buffer[i];
+      data[1] = scanline_buffer[i+scanline_width];
+      data[2] = scanline_buffer[i+2*scanline_width];
+      data[3] = scanline_buffer[i+3*scanline_width];
+      data += 4;
+    }
+    num_scanlines--;
+  }
+  free(scanline_buffer);
+  return VIGRA_RGBE_RETURN_SUCCESS;
+}
+
diff --git a/src/impex/rgbe.h b/src/impex/rgbe.h
new file mode 100644
index 0000000..527f64a
--- /dev/null
+++ b/src/impex/rgbe.h
@@ -0,0 +1,78 @@
+#ifndef _H_RGBE
+#define _H_RGBE
+/* THIS CODE CARRIES NO GUARANTEE OF USABILITY OR FITNESS FOR ANY PURPOSE.
+ * WHILE THE AUTHORS HAVE TRIED TO ENSURE THE PROGRAM WORKS CORRECTLY,
+ * IT IS STRICTLY USE AT YOUR OWN RISK.  */
+
+/* utility for reading and writing Ward's rgbe image format.
+   See rgbe.txt file for more details.
+*/
+
+/* changes by Pablo d'Angelo <pablo.dangelo at web.de>:
+ * Added vigra_ prefix to all exported symbols
+ */
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+  int valid;            /* indicate which fields are valid */
+  char programtype[16]; /* listed at beginning of file to identify it 
+                         * after "#?".  defaults to "RGBE" */ 
+  float gamma;          /* image has already been gamma corrected with 
+                         * given gamma.  defaults to 1.0 (no correction) */
+  float exposure;       /* a value of 1.0 in an image corresponds to
+             * <exposure> watts/steradian/m^2. 
+             * defaults to 1.0 */
+} vigra_rgbe_header_info;
+
+/* flags indicating which fields in an rgbe_header_info are valid */
+#define VIGRA_RGBE_VALID_PROGRAMTYPE 0x01
+#define VIGRA_RGBE_VALID_GAMMA       0x02
+#define VIGRA_RGBE_VALID_EXPOSURE    0x04
+
+/* return codes for rgbe routines */
+#define VIGRA_RGBE_RETURN_SUCCESS 0
+#define VIGRA_RGBE_RETURN_FAILURE -1
+
+/* read or write headers */
+/* you may set rgbe_header_info to null if you want to */
+int VIGRA_RGBE_WriteHeader(FILE *fp, int width, int height, vigra_rgbe_header_info *info);
+int VIGRA_RGBE_ReadHeader(FILE *fp, int *width, int *height, vigra_rgbe_header_info *info);
+
+/* read or write pixels */
+/* can read or write pixels in chunks of any size including single pixels*/
+int VIGRA_RGBE_WritePixels(FILE *fp, float *data, int numpixels);
+int VIGRA_RGBE_ReadPixels(FILE *fp, float *data, int numpixels);
+
+/* read or write run length encoded files */
+/* must be called to read or write whole scanlines */
+int VIGRA_RGBE_WritePixels_RLE(FILE *fp, float *data, int scanline_width,
+             int num_scanlines);
+int VIGRA_RGBE_ReadPixels_RLE(FILE *fp, float *data, int scanline_width,
+            int num_scanlines);
+
+int VIGRA_RGBE_ReadPixels_Raw_RLE(FILE *fp, unsigned char *data, int scanline_width,
+            int num_scanlines);
+
+#ifdef _CPLUSPLUS
+/* define if your compiler understands inline commands */
+#define INLINE inline
+#else
+#define INLINE
+#endif
+
+INLINE void VIGRA_float2rgbe(unsigned char rgbe[4], float red, float green, float blue);
+INLINE void VIGRA_rgbe2float(float *red, float *green, float *blue, unsigned char rgbe[4]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _H_RGBE */
+
+
+
diff --git a/src/impex/sifImport.cxx b/src/impex/sifImport.cxx
new file mode 100644
index 0000000..96da9de
--- /dev/null
+++ b/src/impex/sifImport.cxx
@@ -0,0 +1,304 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2010 by Joachim Schleicher and Ullrich Koethe        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+/*                                                          
+ *  Opens an Andor .sif file as MultiImageView.             
+ *  The width, height and number of images are extracted    
+ *  from the ASCII encoded variable length header.          
+ *                                                          
+ *  Based on the Java-Code from                             
+ *  http://rsb.info.nih.gov/ij/plugins/open-sif.html        
+ *  written by                                              
+ *  L. Stirling Churchman (stirling at stanford.edu)        
+ *  Philippe Carl (pcarl at uni-muenster.de)                
+ *  Yoshiyuki Arai (arai at phys1.med.osaka-u.ac.jp)        
+ *                                                          
+ *  Currently tested SIF versions: 4.16.12005.0             
+ *                                 4.16.30001.0             
+ *                                 4. 6.    3.0             
+ *                                 4. 6.    0.0             
+*/
+
+
+
+#include "vigra/sifImport.hxx"
+#include "vigra/utilities.hxx"
+#include "byteorder.hxx"
+
+namespace vigra {
+
+// private helper functions
+namespace helper {
+std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
+    std::stringstream ss(s);
+    std::string item;
+    while(std::getline(ss, item, delim)) {
+        elems.push_back(item);
+    }
+    return elems;
+}
+
+
+std::vector<std::string> split(const std::string &s, char delim) {
+    std::vector<std::string> elems;
+    return split(s, delim, elems);
+}
+
+class BadConversion : public std::runtime_error {
+ public:
+   BadConversion(std::string const& s)
+     : std::runtime_error(s)
+     { }
+};
+ 
+inline double convertToDouble(std::string const& s) {
+   std::istringstream i(s);
+   double x;
+   if (!(i >> x))
+     throw BadConversion("convertToDouble(\"" + s + "\")");
+   return x;
+} 
+
+inline int convertToInt(std::string const& s) {
+   std::istringstream i(s);
+   int x;
+   if (!(i >> x))
+     throw BadConversion("convertToDouble(\"" + s + "\")");
+   return x;
+} 
+
+}// namespace helper
+ 
+/********************************************************/
+/*                                                      */
+/*                   SIFImportInfo                      */
+/*                                                      */
+/********************************************************/
+
+int SIFImportInfo::width() const {    return m_dims[0]; }
+int SIFImportInfo::height() const {    return m_dims[1]; }
+int SIFImportInfo::stacksize() const {    return m_dims[2]; }
+std::ptrdiff_t SIFImportInfo::getOffset() const {    return m_offset; }
+const char * SIFImportInfo::getFileName() const  {    return m_filename;    }    
+
+MultiArrayIndex SIFImportInfo::numDimensions() const { return 3; } // alway 3D data
+ArrayVector<size_t> const & SIFImportInfo::shape() const {return m_dims; }
+MultiArrayIndex SIFImportInfo::shapeOfDimension(const int dim) const { return m_dims[dim]; }
+
+
+
+SIFImportInfo::SIFImportInfo(const char* filename) :
+    m_filename(filename), m_dims(3), m_offset(0), headerlen(32)
+{
+
+    // some initialisations
+    left = 1, right = 512, bottom = 1, top = 512;
+    xbin = 1, ybin = 1;
+    xres = 1, yres = 1;
+    
+    std::ifstream siffile (filename);
+    if( !siffile.is_open() )
+    {
+        std::string msg("Unable to open file '");
+        msg += filename;
+        msg += "'. File not found.";
+        vigra_precondition(0, msg.c_str());
+    }    
+    int spool = 0;    //If Data is Spooled one, spool is set to 1
+    for(int i=0;i<headerlen+spool+1;i++) {
+        std::string str;
+        getline(siffile, str);
+#ifdef DEBUG
+        std::std::cout << str << std::std::endl;
+#endif
+        if(i==0) {
+            vigra_precondition(str=="Andor Technology Multi-Channel File", "The file is not a valid sif File.");
+        }
+        if(i==2) { // Extract parameters such as temperature, exposureTime and so on. 
+            std::vector<std::string> tokens = helper::split(str, ' ');
+            // TODO
+            //~ d = new Date(Long.parseLong(tokens[4])*1000); // Date is recorded as seconds counted from 1970.1.1 00:00:00
+            temperature1 = helper::convertToDouble(tokens[5]);
+            exposureTime = tokens[12];
+            cycleTime = tokens[13];
+            readout = 1/helper::convertToDouble(tokens[18])/1e+6;
+            EMGain = tokens[21];
+            verticalShiftSpeed = tokens[41];
+            preAmpGain = tokens[43];
+            temperature2 = helper::convertToDouble(tokens[47]);
+            if(tokens.size() > 57) {
+                version = tokens[54]+"."+tokens[55]+"."+tokens[56]+"."+tokens[57];
+            }
+            if(temperature1 == -999) 
+                // If the temperature is unstable, temperature1 value is -999 and unstable temperature value is recored in temperature2
+                temperature = asString(temperature2) + " (Unstable)";
+            else
+                temperature = asString(temperature1);
+        }
+        if(i==3) {
+            model = str; // Model of EMCCD camera
+        }
+        if(i==5) {
+            originalFilename = str; // Read original filename
+        }
+        if(i==7) { // If the Data is spooled one, "spool" value is set to 1
+            std::vector<std::string> tokens = helper::split(str, ' ');
+            if(tokens.size() >= 1 && tokens[0]=="Spooled") {
+                spool=1;
+            }
+        }
+        if(i > 7 && i < headerlen-12) 
+        {
+            if(str.size() == 17 && 
+                 str.substr(0,6)=="65539 " && 
+                 str[6] == 0x01 && str[7] == 0x20 && str[8] == 0x00) 
+            { // seems to be always ten lines before the dimensions-line 
+                 headerlen = i+12;
+            }
+        }
+        if(i==(headerlen-2)) { // Read size of stack (frame length)
+            std::string str2 = str.substr ( 0, 12 );
+            if(str2 == "Pixel number") str = str.substr(12); // drop "Pixel number" as first letters
+            std::vector<std::string> tokens = helper::split(str, ' ');
+            vigra_precondition(tokens.size() >= 6, "format error. Not able to read stacksize.");
+            yres = helper::convertToInt(tokens[2]);
+            xres = helper::convertToInt(tokens[3]);
+            m_dims[2] = helper::convertToInt(tokens[5]);
+            
+        }
+        if(i==(headerlen-1)) { // Read information about the size and bin
+            std::vector<std::string> tokens = helper::split(str, ' ');
+            vigra_precondition(tokens.size() >= 7, "format error. Not able to read image dimensions.");
+            left = helper::convertToInt(tokens[1]);
+            top = helper::convertToInt(tokens[2]);
+            right = helper::convertToInt(tokens[3]);
+            bottom = helper::convertToInt(tokens[4]);
+            xbin = helper::convertToInt(tokens[5]);
+            ybin = helper::convertToInt(tokens[6]);
+        }
+    }
+    
+    // determine filesize
+    siffile.seekg (0, std::ios::end); // goto the end
+    filesize = siffile.tellg();
+    siffile.seekg (0, std::ios::beg);  // goto the beginning
+    filesize -= siffile.tellg();
+
+    // Estimate the offset value (header length)
+    for (int i = 0; i < (headerlen+stacksize()); i++){
+        while(siffile.get() != 10) {
+            m_offset++;
+        }
+        m_offset++;
+    }
+    if(siffile.get() == '0' && siffile.get() == 10) { // Newer sif version
+        m_offset += 2;
+    }
+    siffile.close();
+    
+    // Calc the width and the height value of the ROI
+    size_t width=0, height=0;
+    width = right-left+1;
+    mod = width % xbin;
+    width = (width-mod)/ybin;
+    height = top-bottom+1;
+    mod = height % ybin;
+    height = (height-mod)/xbin;
+    m_dims[0] = width;
+    m_dims[1] = height;
+
+    size_t data_size = (size_t)width * height * 4 * stacksize();
+    vigra_precondition(m_offset + data_size + 8 == filesize, "error reading sif file: data with header should be equal to filesize. ");
+    
+
+
+}
+
+// this function only works for MultiArrayView<3, float> so we don't use a template here.
+void readSIF(const SIFImportInfo &info, MultiArrayView<3, float> array) 
+{
+    readSIFBlock(info, Shape3(0,0,0), Shape3(info.width(), info.height(), info.stacksize()), array);
+}
+
+void readSIFBlock(const SIFImportInfo &info, Shape3 offset, Shape3 shape, MultiArrayView<3, float> array)
+{
+    vigra_precondition(array.isUnstrided(), "readSIFBlock(): Destination array must have consecutive memory.");
+    vigra_precondition(sizeof(float) == 4, "SIF files can only be read into MultiArrayView<float32>. On your machine a float has more than 4 bytes.");
+    vigra_precondition(offset[0]==0 && shape[0]==info.width() && offset[1]==0 && shape[1]==info.height(), "readSIFBlock(): only complete frames implemented.");
+    float * memblock =  array.data();        // here we assume that MultiArray hat float32 values as the sif raw data!!
+
+    std::ifstream file (info.getFileName(), std::ios::in|std::ios::binary);
+    vigra_precondition(file.is_open(), "Unable to open sif file");
+
+    byteorder bo = byteorder("little endian");  // SIF file is little-endian
+
+    std::ptrdiff_t pos = file.tellg();        // pointer to beginning of the file
+    file.seekg(pos+info.getOffset()+offset[2]*info.width()*info.height()*4);
+    read_array( file, bo, memblock, shape[0]*shape[1]*shape[2] );
+    file.close();
+}
+
+std::ostream& operator<<(std::ostream& os, const SIFImportInfo& info)
+{
+    // output
+    os << "\n" <<
+        "SIF Image Information: " <<
+        "\nOriginal Filename:\t" << info.originalFilename <<
+        "\nDate and Time:\t" << info.d <<
+        "\nSoftware Version:\t" << info.version <<
+        "\nCamera Model:\t\t\t" << info.model <<
+        "\nTemperature (C):\t\t"        << info.temperature <<
+        "\nExposure Time (s):\t\t"    << info.exposureTime <<
+        "\nCycle Time (s):\t\t\t" << info.cycleTime <<
+        "\nPixel Readout Rate (MHz):\t" << info.readout <<
+        "\nHorizontal Camera Resolution:\t"    << info.xres <<
+        "\nVertical Camera Resolution:\t"        << info.yres <<
+        "\nImage width:\t\t"          << info.width() <<
+        "\nImage Height:\t\t"        << info.height() <<
+        "\nHorizontal Binning:\t"    << info.xbin <<
+        "\nVertical Binning:\t"        << info.ybin <<
+        "\nEM Gain level:\t"        << info.EMGain <<
+        "\nVertical Shift Speed (s):\t" << info.verticalShiftSpeed <<
+        "\nPre-Amplifier Gain:\t" << info.preAmpGain <<
+        "\nStacksize: \t\t\t" << info.stacksize() <<
+        "\nFilesize: \t\t\t" << info.filesize <<
+        "\nOffset to Image Data: \t" << info.m_offset <<
+        "\n";    
+        
+    return os;
+}
+
+} // namespace vigra
diff --git a/src/impex/sun.cxx b/src/impex/sun.cxx
new file mode 100644
index 0000000..f6380d1
--- /dev/null
+++ b/src/impex/sun.cxx
@@ -0,0 +1,520 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <fstream>
+#include <stdexcept>
+#include "vigra/config.hxx"
+#include "vigra/sized_int.hxx"
+#include "error.hxx"
+#include "byteorder.hxx"
+#include "void_vector.hxx"
+#include "sun.hxx"
+
+// magic number
+#define RAS_MAGIC         0x59A66A95
+#define RAS_MAGIC_REVERSE 0x956AA659
+
+// raster map type
+#define RMT_NONE       0
+#define RMT_EQUAL_RGB  1
+#define RMT_RAW        2
+
+// raster type
+#define RT_OLD         0
+#define RT_STANDARD    1
+#define RT_ENCODED     2
+#define RT_FORMAT_RGB  3
+
+namespace vigra {
+
+    CodecDesc SunCodecFactory::getCodecDesc() const
+    {
+        CodecDesc desc;
+
+        // init file type
+        desc.fileType = "SUN";
+
+        // init pixel types
+        desc.pixelTypes.resize(1);
+        desc.pixelTypes[0] = "UINT8";
+
+        // init compression types
+        desc.compressionTypes.resize(0);
+
+        // init magic strings
+        desc.magicStrings.resize(1);
+        desc.magicStrings[0].resize(4);
+        desc.magicStrings[0][0] = '\x59';
+        desc.magicStrings[0][1] = '\xA6';
+        desc.magicStrings[0][2] = '\x6A';
+        desc.magicStrings[0][3] = '\x95';
+
+        // init file extensions
+        desc.fileExtensions.resize(1);
+        desc.fileExtensions[0] = "ras";
+
+        desc.bandNumbers.resize(2);
+        desc.bandNumbers[0] = 1;
+        desc.bandNumbers[1] = 3;
+        
+        return desc;
+    }
+
+    VIGRA_UNIQUE_PTR<Decoder> SunCodecFactory::getDecoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Decoder>( new SunDecoder() );
+    }
+
+    VIGRA_UNIQUE_PTR<Encoder> SunCodecFactory::getEncoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Encoder>( new SunEncoder() );
+    }
+
+    struct SunHeader
+    {
+        typedef UInt32 field_type;
+
+        // attributes
+
+        field_type width, height, depth, length, type, maptype, maplength;
+
+        // methods
+
+        void from_stream( std::ifstream & stream, const byteorder & bo );
+        void to_stream( std::ofstream & stream, const byteorder & bo );
+    };
+
+    void SunHeader::from_stream( std::ifstream & stream, const byteorder & bo )
+    {
+        read_field( stream, bo, width );
+        read_field( stream, bo, height );
+        read_field( stream, bo, depth );
+        read_field( stream, bo, length );
+        read_field( stream, bo, type );
+        read_field( stream, bo, maptype );
+        read_field( stream, bo, maplength );
+    }
+
+    void SunHeader::to_stream( std::ofstream & stream, const byteorder & bo )
+    {
+        write_field( stream, bo, width );
+        write_field( stream, bo, height );
+        write_field( stream, bo, depth );
+        write_field( stream, bo, length );
+        write_field( stream, bo, type );
+        write_field( stream, bo, maptype );
+        write_field( stream, bo, maplength );
+    }
+
+    struct SunDecoderImpl
+    {
+        // attributes
+
+        SunHeader header;
+        std::ifstream stream;
+        byteorder bo;
+        void_vector< UInt8 > maps, bands;
+        UInt32 components, row_stride;
+        bool recode;
+
+        // methods
+
+        void read_scanline();
+
+        // ctor
+
+        SunDecoderImpl( const std::string & filename );
+    };
+
+    SunDecoderImpl::SunDecoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        : stream( filename.c_str(), std::ios::binary ), 
+#else
+        : stream( filename.c_str() ), 
+#endif
+          bo ("big endian"), 
+          maps (0), 
+          bands (0),
+          recode (false)
+    {
+        if (!stream.good ())
+        {
+            std::string msg ("Unable to open file '");
+            msg += filename;
+            msg += "'.";
+            vigra_precondition (0, msg.c_str ());
+        }
+        
+        // read the magic number, adjust byte order if necessary
+        SunHeader::field_type magic;
+        read_field (stream, bo, magic);
+        if (magic == RAS_MAGIC_REVERSE)
+            bo.set("little endian");
+        else
+            vigra_precondition
+                (magic == RAS_MAGIC, "the stored magic number is invalid");
+
+        // read the header
+        header.from_stream (stream, bo);
+
+        // byte encoded files are not supported
+        vigra_precondition (header.type != RT_ENCODED,
+                            "ras byte encoding is not supported");
+
+        // calculate the row stride and adjust the bands vector
+        // row stride is rounded up to the next multiple of 16 bits
+        row_stride = (2*header.width*(header.depth/8)+1)/2;
+        bands.resize (row_stride);
+
+        // read the color map, if there is one
+        if (header.maptype != RMT_NONE) {
+            vigra_precondition
+                (header.maplength != 0,
+                 "mapping requested, but color maps have zero length");
+            maps.resize (header.maplength);
+            read_array (stream, bo, maps.data (), header.maplength);
+        }
+
+        // compute the header length, if it is not set.
+        if (header.length == 0)
+            header.length = header.height * row_stride;
+
+        // find out if recoding is necessary.
+        if (header.maptype != RMT_NONE || header.depth == 1)
+            recode = true;
+        else
+            recode = false;
+
+        // find out the number of components.
+        if (header.depth == 24 || header.maptype == RMT_EQUAL_RGB)
+            components = 3;
+        else
+            components = 1;
+
+        // sanity check on the depth
+        vigra_precondition
+            (header.depth == 1 || header.depth == 8 || header.depth == 24,
+             "unsupported color depth");
+    }
+
+    void SunDecoderImpl::read_scanline()
+    {
+        // read the scanline
+        read_array (stream, bo, bands.data (), row_stride);
+
+        // recode if necessary
+        if (recode) {
+
+            void_vector <UInt8> recode_bands;
+
+            if (header.depth == 1) {
+
+                // expand to UInt8.
+                recode_bands.resize (header.width);
+                for (unsigned int i = 0; i < header.width; ++i) {
+
+                    // there are eight pixels in each byte.
+                    const UInt8 b = bands [i/8];
+                    recode_bands [i] = b >> i%8 & 0x01;
+                }
+
+                // commit.
+                swap_void_vector (recode_bands, bands);
+            }
+
+            // color map the scanline.
+            if (header.maptype == RMT_EQUAL_RGB) {
+
+                // map from UInt8 to rgb
+                recode_bands.resize (3*header.width);
+                const unsigned int mapstride = header.maplength/3;
+                UInt8 *recode_mover = recode_bands.data ();
+                for (unsigned int i = 0; i < header.width; ++i) {
+                    // find out the pointer to the red color
+                    UInt8 *map_mover = maps.data () + bands [i];
+                    // red
+                    *recode_mover++ = *map_mover;
+                    map_mover += mapstride;
+                    // green
+                    *recode_mover++ = *map_mover;
+                    map_mover += mapstride;
+                    // blue
+                    *recode_mover++ = *map_mover;
+                }
+                
+            } else if (header.maptype == RMT_RAW) {
+
+                // map from UInt8 to UInt8
+                recode_bands.resize (header.width);
+                for (unsigned int i = 0; i < header.width; ++i)
+                    recode_bands [i] = maps [bands [i]];
+            }
+
+            // commit.
+            swap_void_vector (recode_bands, bands);
+        }
+
+        // swap the color components of a BGR image to RGB.
+        // i really don't know the exact condition for this.
+        if (header.type == RT_STANDARD && header.maptype != RMT_EQUAL_RGB
+            && components == 3) {
+
+            void_vector <UInt8> recode_bands (3*header.width);
+            for (unsigned int i = 0; i < header.width; ++i) {
+                recode_bands [3*i]   = bands [3*i+2];
+                recode_bands [3*i+1] = bands [3*i+1];
+                recode_bands [3*i+2] = bands [3*i];
+            }
+
+            // commit.
+            swap_void_vector (recode_bands, bands);
+        }
+    }
+
+    void SunDecoder::init( const std::string & filename )
+    {
+        pimpl = new SunDecoderImpl( filename );
+    }
+
+    SunDecoder::~SunDecoder()
+    {
+        delete pimpl;
+    }
+
+    std::string SunDecoder::getFileType() const
+    {
+        return "SUN";
+    }
+
+    unsigned int SunDecoder::getWidth() const
+    {
+        return pimpl->header.width;
+    }
+
+    unsigned int SunDecoder::getHeight() const
+    {
+        return pimpl->header.height;
+    }
+
+    unsigned int SunDecoder::getNumBands() const
+    {
+        return pimpl->components;
+    }
+
+    std::string SunDecoder::getPixelType() const
+    {
+        return "UINT8";
+    }
+
+    unsigned int SunDecoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    const void * SunDecoder::currentScanlineOfBand( unsigned int band ) const
+    {
+        return pimpl->bands.data() + band;
+    }
+
+    void SunDecoder::nextScanline()
+    {
+        pimpl->read_scanline();
+    }
+
+    void SunDecoder::close() {}
+    void SunDecoder::abort() {}
+
+    struct SunEncoderImpl
+    {
+        // attributes
+
+        SunHeader header;
+        std::ofstream stream;
+        byteorder bo;
+        void_vector< UInt8 > bands;
+        UInt32 components, row_stride;
+        bool finalized;
+
+        // methods
+
+        void finalize();
+        void write_scanline();
+
+        // ctor
+
+        SunEncoderImpl( const std::string & filename );
+    };
+
+    SunEncoderImpl::SunEncoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+        : stream( filename.c_str(), std::ios::binary ), 
+#else
+        : stream( filename.c_str() ), 
+#endif
+          bo("big endian"),
+          bands(0), finalized(false)
+    {
+        if(!stream.good())
+        {
+            std::string msg("Unable to open file '");
+            msg += filename;
+            msg += "'.";
+            vigra_precondition(0, msg.c_str());
+        }
+        // write the magic number
+        SunHeader::field_type magic = RAS_MAGIC;
+        write_field( stream, bo, magic );
+    }
+
+    void SunEncoderImpl::finalize()
+    {
+        // color depth
+        vigra_precondition( components == 1 || components == 3,
+                            "number of bands is not supported" );
+
+        header.depth = components << 3;
+
+        // calculate the row stride and adjust the bands vector
+        // row stride is rounded up to the next multiple of 16 bits
+        row_stride = ( 2 * header.width * ( header.depth / 8 ) + 1 ) / 2;
+        bands.resize(row_stride);
+
+        // set bands memory to zero
+        for ( unsigned int i = 0; i < row_stride; ++i )
+            bands[i] = 0;
+
+        // set the band length
+        header.length = header.height * row_stride;
+
+        // standard format
+        header.type = RT_STANDARD;
+
+        // no colormap
+        header.maptype = RMT_NONE;
+        header.maplength = 0;
+
+        // write the header
+        header.to_stream( stream, bo );
+    }
+
+    void SunEncoderImpl::write_scanline()
+    {
+        if ( components == 3 ) {
+            // rgb -> bgr
+            void_vector< UInt8 > recode_bands(bands.size());
+            for ( unsigned int i = 0; i < header.width; ++i ) {
+                recode_bands[ 3 * i ] = bands[ 3 * i + 2 ];
+                recode_bands[ 3 * i + 1 ] = bands[ 3 * i + 1 ];
+                recode_bands[ 3 * i + 2 ] = bands[ 3 * i ];
+            }
+            swap_void_vector( recode_bands, bands );
+        }
+        write_array( stream, bo, bands.data(), row_stride );
+    }
+
+    void SunEncoder::init( const std::string & filename )
+    {
+        pimpl = new SunEncoderImpl(filename);
+    }
+
+    SunEncoder::~SunEncoder()
+    {
+        delete pimpl;
+    }
+
+    std::string SunEncoder::getFileType() const
+    {
+        return "SUN";
+    }
+
+    void SunEncoder::setWidth( unsigned int width )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->header.width = width;
+    }
+
+    void SunEncoder::setHeight( unsigned int height )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->header.height = height;
+    }
+
+    void SunEncoder::setNumBands( unsigned int numBands )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->components = numBands;
+    }
+
+    void SunEncoder::setCompressionType( const std::string & /* comp */, int /* quality */)
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+    }
+
+    void SunEncoder::setPixelType( const std::string & pixeltype )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        vigra_precondition( pixeltype == "UINT8",
+                            "SunEncoder::setPixelType(): "
+                            "SUN raster supports only the UINT8 pixeltype" );
+    }
+
+    unsigned int SunEncoder::getOffset() const
+    {
+        return pimpl->components;
+    }
+
+    void SunEncoder::finalizeSettings()
+    {
+        pimpl->finalize();
+        pimpl->finalized = true;
+    }
+
+    void * SunEncoder::currentScanlineOfBand( unsigned int band )
+    {
+        return pimpl->bands.data() + band;
+    }
+
+    void SunEncoder::nextScanline()
+    {
+        pimpl->write_scanline();
+    }
+
+    void SunEncoder::close()
+    {
+        nextScanline();
+    }
+
+    void SunEncoder::abort() {}
+}
diff --git a/src/impex/sun.hxx b/src/impex/sun.hxx
new file mode 100644
index 0000000..d39615c
--- /dev/null
+++ b/src/impex/sun.hxx
@@ -0,0 +1,108 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEX_SUN_HXX
+#define VIGRA_IMPEX_SUN_HXX
+
+#include "vigra/codec.hxx"
+
+// SUN Rasterfile format
+
+namespace vigra {
+
+    struct SunDecoderImpl;
+    struct SunEncoderImpl;
+
+    struct SunCodecFactory : public CodecFactory
+    {
+        CodecDesc getCodecDesc() const;
+        VIGRA_UNIQUE_PTR<Decoder> getDecoder() const;
+        VIGRA_UNIQUE_PTR<Encoder> getEncoder() const;
+    };
+
+    class SunDecoder : public Decoder
+    {
+        SunDecoderImpl * pimpl;
+
+    public:
+
+        SunDecoder() : pimpl(0) {}
+
+        ~SunDecoder();
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        std::string getPixelType() const;
+
+        unsigned int getWidth() const;
+        unsigned int getHeight() const;
+        unsigned int getNumBands() const;
+        unsigned int getOffset() const;
+
+        const void * currentScanlineOfBand( unsigned int ) const;
+        void nextScanline();
+    };
+
+    class SunEncoder : public Encoder
+    {
+        SunEncoderImpl * pimpl;
+
+    public:
+
+        SunEncoder() : pimpl(0) {}
+
+        ~SunEncoder();
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        unsigned int getOffset() const;
+
+        void setWidth( unsigned int );
+        void setHeight( unsigned int );
+        void setNumBands( unsigned int );
+        void setCompressionType( const std::string &, int = -1 );
+        void setPixelType( const std::string & );
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int );
+        void nextScanline();
+    };
+}
+
+#endif // VIGRA_IMPEX_SUN_HXX
diff --git a/src/impex/tiff.cxx b/src/impex/tiff.cxx
new file mode 100644
index 0000000..d6e73d8
--- /dev/null
+++ b/src/impex/tiff.cxx
@@ -0,0 +1,1075 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2001-2002 by Gunnar Kedenburg                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+/* Modifications by Pablo d'Angelo
+ * updated to vigra 1.4 by Douglas Wilkins
+ * as of 18 Febuary 2006:
+ *  - Added UINT16 and UINT32 pixel types.
+ *  - Added support for obtaining extra bands beyond RGB.
+ *  - Added support for a position field that indicates the start of this
+ *    image relative to some global origin.
+ *  - Added support for x and y resolution fields.
+ *
+ * Modification by Andrew Mihal, 27 October 2004:
+ *  - Modified encoder to better estimate the number of rows per strip.
+ *  - Modified decoder to use the scanline interface - the strip-based
+ *    interface hogs memory when the rows/strip value is large.
+ *  - Added support for ICC profiles
+ * Andrew Mihal's modifications are covered by the VIGRA license.
+ */
+
+#ifdef HasTIFF
+
+#ifdef _MSC_VER
+// NB (jbeda): tiffio.h is going to include this anyway.  Let's include
+// it now so that we can control how it comes in.  Namely, we want
+// to get our version that doesn't set the evil min/max macros.
+#include "vigra/windows.h"
+#endif
+
+#include "vigra/sized_int.hxx"
+#include "error.hxx"
+#include "tiff.hxx"
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+
+extern "C"
+{
+
+#include <tiff.h>
+#include <tiffio.h>
+#include <tiffvers.h>
+
+static void vigraWarningHandler(char* module, char* fmt, va_list ap)
+{
+    static const std::string ignore("Unknown field with tag");
+    if(ignore.compare(0, ignore.size(), fmt, ignore.size()) == 0)
+        return;
+    
+    if (module != NULL)
+    {
+        static const std::string ignore("TIFFFetchNormalTag");
+        if(ignore.compare(module) == 0)
+            return;
+            
+        fprintf(stderr, "%s: ", module);
+    }
+    
+    fprintf(stderr, "Warning, ");
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, ".\n");
+}
+
+} // extern "C"
+
+namespace vigra {
+
+    CodecDesc TIFFCodecFactory::getCodecDesc() const
+    {
+        CodecDesc desc;
+
+        // init file type
+        desc.fileType = "TIFF";
+
+        // init pixel types
+        desc.pixelTypes.resize(9);
+        desc.pixelTypes[0] = "BILEVEL";
+        desc.pixelTypes[1] = "UINT8";
+        desc.pixelTypes[2] = "INT8";
+        desc.pixelTypes[3] = "UINT16";
+        desc.pixelTypes[4] = "INT16";
+        desc.pixelTypes[5] = "UINT32";
+        desc.pixelTypes[6] = "INT32";
+        desc.pixelTypes[7] = "FLOAT";
+        desc.pixelTypes[8] = "DOUBLE";
+
+        // init compression types
+        desc.compressionTypes.resize(6);
+        desc.compressionTypes[0] = "NONE";
+        desc.compressionTypes[1] = "RLE";
+        desc.compressionTypes[2] = "PACKBITS";
+        desc.compressionTypes[3] = "JPEG";
+        desc.compressionTypes[4] = "LZW";
+        desc.compressionTypes[5] = "DEFLATE";
+
+        // init magic strings
+#if TIFFLIB_VERSION > 20070712
+        desc.magicStrings.resize(3);
+#else
+        desc.magicStrings.resize(2);
+#endif
+        desc.magicStrings[0].resize(4);
+        desc.magicStrings[0][0] = '\115';
+        desc.magicStrings[0][1] = '\115';
+        desc.magicStrings[0][2] = '\000';
+        desc.magicStrings[0][3] = '\052';
+        desc.magicStrings[1].resize(4);
+        desc.magicStrings[1][0] = '\111';
+        desc.magicStrings[1][1] = '\111';
+        desc.magicStrings[1][2] = '\052';
+        desc.magicStrings[1][3] = '\000';
+#if TIFFLIB_VERSION > 20070712
+        // magic for bigtiff
+        desc.magicStrings[2].resize(4);
+        desc.magicStrings[2][0] = '\111';
+        desc.magicStrings[2][1] = '\111';
+        desc.magicStrings[2][2] = '\053';
+        desc.magicStrings[2][3] = '\000';
+#endif
+
+        // init file extensions
+        desc.fileExtensions.resize(2);
+        desc.fileExtensions[0] = "tif";
+        desc.fileExtensions[1] = "tiff";
+
+        desc.bandNumbers.resize(4);
+        desc.bandNumbers[0] = 1;
+        desc.bandNumbers[1] = 2;
+        desc.bandNumbers[2] = 3;
+        desc.bandNumbers[3] = 4;
+
+        return desc;
+    }
+
+    VIGRA_UNIQUE_PTR<Decoder> TIFFCodecFactory::getDecoder() const
+    {
+        // use 'NULL' to silence all warnings
+        TIFFSetWarningHandler((TIFFErrorHandler)&vigraWarningHandler);
+
+        return VIGRA_UNIQUE_PTR<Decoder>( new TIFFDecoder() );
+    }
+
+    VIGRA_UNIQUE_PTR<Encoder> TIFFCodecFactory::getEncoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Encoder>( new TIFFEncoder() );
+    }
+
+    class TIFFCodecImpl
+    {
+
+    protected:
+
+        std::string pixeltype;
+
+        TIFF * tiff;
+        tdata_t * stripbuffer;
+        tstrip_t strip;
+
+        uint32 stripindex, stripheight;
+        uint32 width, height;
+        uint16 samples_per_pixel, bits_per_sample,
+            photometric, planarconfig, fillorder, extra_samples_per_pixel;
+        float x_resolution, y_resolution;
+        Diff2D position;
+        Size2D canvasSize;
+
+        Decoder::ICCProfile iccProfile;
+
+    public:
+
+        TIFFCodecImpl();
+        ~TIFFCodecImpl();
+    };
+
+    TIFFCodecImpl::TIFFCodecImpl()
+        : pixeltype("undefined")
+    {
+        tiff = 0;
+        stripbuffer = 0;
+        strip = 0;
+        stripindex = 0;
+        planarconfig = PLANARCONFIG_CONTIG;
+        x_resolution = 0;
+        y_resolution = 0;
+        extra_samples_per_pixel = 0;
+   }
+
+    TIFFCodecImpl::~TIFFCodecImpl()
+    {
+        if ( planarconfig == PLANARCONFIG_SEPARATE ) {
+            if ( stripbuffer != 0 ) {
+                for( unsigned int i = 0; i < samples_per_pixel; ++i )
+                    if ( stripbuffer[i] != 0 )
+                        _TIFFfree(stripbuffer[i]);
+                delete[] stripbuffer;
+            }
+        } else {
+            if ( stripbuffer != 0 ) {
+                if ( stripbuffer[0] != 0 )
+                    _TIFFfree(stripbuffer[0]);
+                delete[] stripbuffer;
+            }
+        }
+
+        if ( tiff != 0 )
+            TIFFClose(tiff);
+    }
+
+    class TIFFDecoderImpl : public TIFFCodecImpl
+    {
+        friend class TIFFDecoder;
+
+        unsigned int scanline;
+
+        std::string get_pixeltype_by_sampleformat() const;
+        std::string get_pixeltype_by_datatype() const;
+
+    public:
+
+        TIFFDecoderImpl( const std::string & filename );
+
+        void init( unsigned int imageIndex );
+
+        unsigned int getNumImages();
+        void setImageIndex( unsigned int index );
+        unsigned int getImageIndex();
+
+        const void * currentScanlineOfBand( unsigned int band ) const;
+        void nextScanline();
+    };
+
+    TIFFDecoderImpl::TIFFDecoderImpl( const std::string & filename )
+    {
+        tiff = TIFFOpen( filename.c_str(), "r" );
+
+        if ( !tiff ) {
+            std::string msg("Unable to open file '");
+            msg += filename;
+            msg += "'.";
+            vigra_precondition(0, msg.c_str());
+        }
+
+        scanline = 0;
+    }
+
+    std::string TIFFDecoderImpl::get_pixeltype_by_sampleformat() const
+    {
+        uint16 sampleformat;
+
+        if ( TIFFGetField( tiff, TIFFTAG_SAMPLEFORMAT, &sampleformat ) ) {
+
+            switch (sampleformat) {
+
+            case SAMPLEFORMAT_UINT:
+                // added by dangelo, support for UINT 16 & 32 bit
+                switch (bits_per_sample) {
+                case 8:
+                    return "UINT8";
+                case 16:
+                    return "UINT16";
+                case 32:
+                    return "UINT32";
+                }
+                break;
+
+            case SAMPLEFORMAT_INT:
+                switch (bits_per_sample) {
+                case 8:
+                    return "INT8";
+                case 16:
+                    return "INT16";
+                case 32:
+                    return "INT32";
+                }
+                break;
+
+            case SAMPLEFORMAT_IEEEFP:
+                switch (bits_per_sample) {
+                case 32:
+                    return "FLOAT";
+                case 64:
+                    return "DOUBLE";
+                }
+                break;
+            }
+        }
+        return "undefined";
+    }
+
+    std::string TIFFDecoderImpl::get_pixeltype_by_datatype() const
+    {
+        uint16 datatype;
+
+        if ( TIFFGetField( tiff, TIFFTAG_DATATYPE, &datatype ) ) {
+            // dangelo: correct parsing of INT/UINT (given in tiff.h)
+            switch (datatype) {
+            case TIFF_BYTE:
+                return "UINT8";
+            case TIFF_SBYTE:
+                return "INT8";
+            case TIFF_SHORT:
+                return "UINT16";
+            case TIFF_SSHORT:
+                return "INT16";
+            case TIFF_LONG:
+                return "UINT32";
+            case TIFF_SLONG:
+                return "INT32";
+            case TIFF_FLOAT:
+                return "FLOAT";
+            case TIFF_DOUBLE:
+                return "DOUBLE";
+            }
+        }
+
+        return "undefined";
+    }
+
+    void TIFFDecoderImpl::init(unsigned int imageIndex)
+    {
+        // set image directory, if necessary:
+        if (imageIndex != TIFFCurrentDirectory(tiff))
+        {
+            if (!TIFFSetDirectory( tiff, (tdir_t)(imageIndex)) )
+                vigra_fail( "Invalid TIFF image index" );
+        }
+
+        // read width and height
+        TIFFGetField( tiff, TIFFTAG_IMAGEWIDTH, &width );
+        TIFFGetField( tiff, TIFFTAG_IMAGELENGTH, &height );
+
+        // check for tiled TIFFs
+        uint32 tileWidth, tileHeight;
+        if( TIFFGetField( tiff, TIFFTAG_TILEWIDTH, &tileWidth ) &&
+            TIFFGetField( tiff, TIFFTAG_TILELENGTH, &tileHeight ) )
+            vigra_precondition( (tileWidth == width) && (tileHeight == height),
+                                "TIFFDecoderImpl::init(): "
+                                "Cannot read tiled TIFFs (not implemented)." );
+
+        // find out strip heights
+        stripheight = 1; // now using scanline interface instead of strip interface
+
+        // get samples_per_pixel
+        samples_per_pixel = 0;
+        extra_samples_per_pixel = 0;
+        if ( !TIFFGetFieldDefaulted( tiff, TIFFTAG_SAMPLESPERPIXEL,
+                                     &samples_per_pixel ) )
+            vigra_fail( "TIFFDecoderImpl::init(): Samples per pixel not set."
+                        " A suitable default was not found." );
+
+        // read extra samples (# of alpha channels)
+        uint16 *extra_sample_types=0;
+        if (TIFFGetField( tiff, TIFFTAG_EXTRASAMPLES,
+                          &extra_samples_per_pixel, &extra_sample_types )!=1)
+        {
+            extra_samples_per_pixel=0;
+        }
+
+        if (extra_samples_per_pixel > 0) {
+            for (int i=0; i< extra_samples_per_pixel; i++) {
+                if (extra_sample_types[i] ==  EXTRASAMPLE_ASSOCALPHA)
+                {
+                    std::cerr << "WARNING: TIFFDecoderImpl::init(): associated alpha treated"
+                                 " as unassociated alpha!" << std::endl;
+                }
+            }
+        }
+
+        // get photometric
+        if ( !TIFFGetFieldDefaulted( tiff, TIFFTAG_PHOTOMETRIC,
+                                     &photometric ) )
+            vigra_fail( "TIFFDecoderImpl::init(): Photometric tag is not set."
+                        " A suitable default was not found." );
+
+        // check photometric preconditions
+        switch ( photometric )
+        {
+            case PHOTOMETRIC_MINISWHITE:
+            case PHOTOMETRIC_MINISBLACK:
+            case PHOTOMETRIC_PALETTE:
+            {
+                if ( samples_per_pixel - extra_samples_per_pixel != 1 )
+                vigra_fail("TIFFDecoderImpl::init():"
+                                " Photometric tag does not fit the number of"
+                                " samples per pixel." );
+                break;
+            }
+            case PHOTOMETRIC_RGB:
+            {
+                if ( samples_per_pixel > 3 && extra_samples_per_pixel == 0 ) {
+                    // file probably lacks the extra_samples tag
+                    extra_samples_per_pixel = samples_per_pixel - 3;
+                }
+                if ( samples_per_pixel - extra_samples_per_pixel != 3 )
+                    vigra_fail("TIFFDecoderImpl::init():"
+                                    " Photometric tag does not fit the number of"
+                                    " samples per pixel." );
+                break;
+            }
+            case PHOTOMETRIC_LOGL:
+            case PHOTOMETRIC_LOGLUV:
+            {
+                uint16 tiffcomp;
+                TIFFGetFieldDefaulted( tiff, TIFFTAG_COMPRESSION, &tiffcomp );
+                if (tiffcomp != COMPRESSION_SGILOG && tiffcomp != COMPRESSION_SGILOG24)
+                    vigra_fail("TIFFDecoderImpl::init():"
+                                    " Only SGILOG compression is supported for"
+                                    " LogLuv TIFF."
+                    );
+                TIFFSetField(tiff, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
+                break;
+            }
+        }
+
+        // get planarconfig
+        if ( samples_per_pixel > 1 ) {
+            if ( !TIFFGetFieldDefaulted( tiff, TIFFTAG_PLANARCONFIG,
+                                         &planarconfig ) )
+                vigra_fail( "TIFFDecoderImpl::init(): Planarconfig is not"
+                            " set. A suitable default was not found." );
+        }
+
+        // get bits per pixel
+        if ( !TIFFGetField( tiff, TIFFTAG_BITSPERSAMPLE, &bits_per_sample ) )
+        {
+            std::cerr << "Warning: no TIFFTAG_BITSPERSAMPLE, using 8 bits per sample.\n";
+            bits_per_sample = 8;
+        }
+        // get pixeltype
+        if ( bits_per_sample != 1 ) {
+
+            // try the sampleformat tag
+            pixeltype = get_pixeltype_by_sampleformat();
+
+            if ( pixeltype == "undefined" ) {
+
+                // try the (obsolete) datatype tag
+                pixeltype = get_pixeltype_by_datatype();
+
+                if ( pixeltype == "undefined" ) {
+                    // ERROR: no useable pixeltype found..
+                    // imagemagick can write files without it..
+                    // try to guess a suitable one here.
+                    switch(bits_per_sample)
+                    {
+                        case 8:
+                            pixeltype = "UINT8";
+                            break;
+                        case 16:
+                            pixeltype = "UINT16";
+                            break;
+                        case 32:
+                            pixeltype = "UINT32"; // prefer int over float
+                            break;
+                        case 64:
+                            pixeltype =  "DOUBLE";
+                            break;
+                        default:
+                            vigra_fail( "TIFFDecoderImpl::init(): Sampleformat or Datatype tag undefined and guessing sampletype from Bits per Sample failed." );
+                            break;
+                    }
+                    if(bits_per_sample != 8) // issue the warning only for non-trivial cases
+                        std::cerr << "Warning: no TIFFTAG_SAMPLEFORMAT or TIFFTAG_DATATYPE, "
+                                     "guessing pixeltype '" << pixeltype << "'.\n";
+                }
+            }
+
+        } else {
+
+            // if each sample is 1 bit long
+            pixeltype = "BILEVEL";
+
+            // get fillorder
+            if ( !TIFFGetField( tiff, TIFFTAG_FILLORDER, &fillorder ) )
+                fillorder = FILLORDER_MSB2LSB;
+        }
+
+        // make sure the LogLuv has correct pixeltype because only float is supported
+        if (photometric == PHOTOMETRIC_LOGLUV) {
+            pixeltype = "FLOAT";
+            samples_per_pixel = 3;
+        }
+
+        // other fields
+        uint16 u16value;
+        uint32 u32value;
+        float unitLength = 1.0f;
+        if (TIFFGetField( tiff, TIFFTAG_RESOLUTIONUNIT, &u16value )) {
+            switch (u16value) {
+            case RESUNIT_NONE:
+                unitLength = 1.0f;
+                break;
+            case RESUNIT_INCH:
+                unitLength = 1.0f;
+                break;
+            case RESUNIT_CENTIMETER:
+                unitLength = 1.0f/2.54f;
+                break;
+            default:
+                vigra_fail("Unknown resolution unit");
+            }
+        }
+
+        float fvalue;
+        if (TIFFGetField( tiff, TIFFTAG_XRESOLUTION, &fvalue )) {
+            x_resolution = fvalue / unitLength;
+        }
+
+        if (TIFFGetField( tiff, TIFFTAG_YRESOLUTION, &fvalue )) {
+            y_resolution = fvalue / unitLength;
+        }
+
+        // XPosition
+        if (TIFFGetField( tiff, TIFFTAG_XPOSITION, &fvalue )) {
+            fvalue = fvalue * x_resolution;
+            position.x = (int)floor(fvalue + 0.5);
+        }
+        // YPosition
+        if (TIFFGetField( tiff, TIFFTAG_YPOSITION, &fvalue )) {
+            fvalue = fvalue * y_resolution;
+            position.y = (int)floor(fvalue + 0.5);
+        }
+
+        // canvas size
+        if (TIFFGetField( tiff, TIFFTAG_PIXAR_IMAGEFULLWIDTH, &u32value )) {
+            canvasSize.x = u32value;
+        }
+        if (TIFFGetField( tiff, TIFFTAG_PIXAR_IMAGEFULLLENGTH, &u32value )) {
+            canvasSize.y = u32value;
+        }
+
+        if ((uint32)canvasSize.x < position.x + width || (uint32)canvasSize.y < position.y + height)
+        {
+            canvasSize.x = canvasSize.y = 0;
+        }
+
+        // ICC Profile
+        UInt32 iccProfileLength = 0;
+        const unsigned char *iccProfilePtr = NULL;
+        if(TIFFGetField(tiff, TIFFTAG_ICCPROFILE,
+                        &iccProfileLength, &iccProfilePtr)
+           && iccProfileLength)
+        {
+            Decoder::ICCProfile iccData(
+                iccProfilePtr, iccProfilePtr + iccProfileLength);
+            iccProfile.swap(iccData);
+        }
+
+        // allocate data buffers
+        const unsigned int stripsize = TIFFScanlineSize(tiff);
+        if ( planarconfig == PLANARCONFIG_SEPARATE ) {
+            stripbuffer = new tdata_t[samples_per_pixel];
+            for( unsigned int i = 0; i < samples_per_pixel; ++i ) {
+                stripbuffer[i] = 0;
+            }
+            for( unsigned int i = 0; i < samples_per_pixel; ++i ) {
+                stripbuffer[i] = _TIFFmalloc(stripsize);
+                if(stripbuffer[i] == 0)
+                    throw std::bad_alloc();
+            }
+        } else {
+            stripbuffer = new tdata_t[1];
+            stripbuffer[0] = 0;
+            stripbuffer[0] = _TIFFmalloc(stripsize);
+            if(stripbuffer[0] == 0)
+                throw std::bad_alloc();
+        }
+
+        // let the codec read a new strip
+        stripindex = stripheight;
+    }
+
+    const void *
+    TIFFDecoderImpl::currentScanlineOfBand( unsigned int band ) const
+    {
+        if ( bits_per_sample == 1 ) {
+            UInt8 * const buf
+                = static_cast< UInt8 * >(stripbuffer[0]);
+            // XXX probably wrong
+            return buf + ( stripindex * width ) / 8;
+        } else {
+            if ( planarconfig == PLANARCONFIG_SEPARATE ) {
+                UInt8 * const buf
+                    = static_cast< UInt8 * >(stripbuffer[band]);
+                return buf + ( stripindex * width ) * ( bits_per_sample / 8 );
+            } else {
+                UInt8 * const buf
+                    = static_cast< UInt8 * >(stripbuffer[0]);
+                return buf + ( band + stripindex * width * samples_per_pixel )
+                    * ( bits_per_sample / 8 );
+            }
+        }
+    }
+
+    void TIFFDecoderImpl::nextScanline()
+    {
+        // eventually read a new strip
+        if ( ++stripindex >= stripheight ) {
+            stripindex = 0;
+
+            if ( planarconfig == PLANARCONFIG_SEPARATE ) {
+                const tsize_t size = TIFFScanlineSize(tiff);
+                for( unsigned int i = 0; i < samples_per_pixel; ++i )
+                    TIFFReadScanline(tiff, stripbuffer[i], scanline++, size);
+            } else {
+                TIFFReadScanline( tiff, stripbuffer[0], scanline++, 0);
+            }
+
+            // XXX handle bilevel images
+
+            // invert grayscale images that interpret 0 as white
+            if ( photometric == PHOTOMETRIC_MINISWHITE &&
+                 samples_per_pixel == 1 && pixeltype == "UINT8" ) {
+
+                UInt8 * buf = static_cast< UInt8 * >(stripbuffer[0]);
+                const unsigned int n = TIFFScanlineSize(tiff);
+
+                // invert every pixel
+                for ( unsigned int i = 0; i < n; ++i, ++buf )
+                    *buf = 0xff - *buf;
+            }
+        }
+    }
+
+    void TIFFDecoder::init( const std::string & filename, unsigned int imageIndex=0 )
+    {
+        pimpl = new TIFFDecoderImpl(filename);
+        pimpl->init(imageIndex);
+        iccProfile_ = pimpl->iccProfile;
+    }
+
+    TIFFDecoder::~TIFFDecoder()
+    {
+        delete pimpl;
+    }
+
+    std::string TIFFDecoder::getFileType() const
+    {
+        return "TIFF";
+    }
+
+    unsigned int TIFFDecoder::getWidth() const
+    {
+        return pimpl->width;
+    }
+
+    unsigned int TIFFDecoder::getHeight() const
+    {
+        return pimpl->height;
+    }
+
+    unsigned int TIFFDecoder::getNumBands() const
+    {
+        return pimpl->samples_per_pixel;
+    }
+
+    unsigned int TIFFDecoder::getNumExtraBands() const
+    {
+        return pimpl->extra_samples_per_pixel;
+    }
+
+    unsigned int TIFFDecoder::getNumImages() const
+    {
+        return pimpl->getNumImages();
+    }
+
+    void TIFFDecoder::setImageIndex(unsigned int imageIndex)
+    {
+        pimpl->setImageIndex(imageIndex);
+    }
+
+    unsigned int TIFFDecoder::getImageIndex() const
+    {
+        return pimpl->getImageIndex();
+    }
+
+    vigra::Diff2D TIFFDecoder::getPosition() const
+    {
+        return pimpl->position;
+    }
+
+    vigra::Size2D TIFFDecoder::getCanvasSize() const
+    {
+        return pimpl->canvasSize;
+    }
+
+    float TIFFDecoder::getXResolution() const
+    {
+        return pimpl->x_resolution;
+    }
+
+    float TIFFDecoder::getYResolution() const
+    {
+        return pimpl->y_resolution;
+    }
+
+    std::string TIFFDecoder::getPixelType() const
+    {
+        return pimpl->pixeltype;
+    }
+
+    unsigned int TIFFDecoder::getOffset() const
+    {
+        return pimpl->planarconfig == PLANARCONFIG_SEPARATE ?
+            1 : pimpl->samples_per_pixel;
+    }
+
+    unsigned int
+    TIFFDecoderImpl::getNumImages()
+    {
+        unsigned int currIndex = getImageIndex();
+        TIFFSetDirectory(tiff, 0);
+        int numPages = 1;
+        while (TIFFReadDirectory(tiff)) numPages++;
+        TIFFSetDirectory(tiff, currIndex);
+        return numPages;
+    }
+
+    void
+    TIFFDecoderImpl::setImageIndex( unsigned int imageIndex )
+    {
+        init(imageIndex);
+    }
+
+    unsigned int
+    TIFFDecoderImpl::getImageIndex()
+    {
+        return TIFFCurrentDirectory(tiff);
+    }
+
+    const void * TIFFDecoder::currentScanlineOfBand( unsigned int band ) const
+    {
+        return pimpl->currentScanlineOfBand(band);
+    }
+
+    void TIFFDecoder::nextScanline()
+    {
+        pimpl->nextScanline();
+    }
+
+    void TIFFDecoder::close() {}
+    void TIFFDecoder::abort() {}
+
+    // this encoder always writes interleaved tiff files
+    class TIFFEncoderImpl : public TIFFCodecImpl
+    {
+        friend class TIFFEncoder;
+
+        // attributes
+
+        unsigned short tiffcomp;
+        bool finalized;
+
+    public:
+
+        // ctor, dtor
+
+        TIFFEncoderImpl( const std::string & filename, const std::string & mode )
+            : tiffcomp(COMPRESSION_LZW), finalized(false)
+        {
+            tiff = TIFFOpen( filename.c_str(), mode.c_str() );
+            if (!tiff)
+            {
+                std::string msg("Unable to open file '");
+                msg += filename;
+                msg += "'.";
+                vigra_precondition( false, msg.c_str() );
+            }
+
+            planarconfig = PLANARCONFIG_CONTIG;
+        }
+
+        // methods
+
+        void setCompressionType( const std::string &, int );
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int band ) const
+        {
+            const unsigned int atomicbytes = bits_per_sample >> 3;
+            UInt8 * buf = ( UInt8 * ) stripbuffer[0];
+            return buf + atomicbytes *
+                ( width * samples_per_pixel * stripindex + band );
+        }
+
+        void nextScanline()
+        {
+            // compute the number of rows in the current strip
+            unsigned int rows = ( strip + 1 ) * stripheight > height ?
+                height - strip * stripheight : stripheight;
+
+            if ( ++stripindex >= rows ) {
+
+                // write next strip
+                stripindex = 0;
+
+                int success = TIFFWriteEncodedStrip( tiff, strip++, stripbuffer[0],
+                                       TIFFVStripSize( tiff, rows ) );
+                if(success == -1 && tiffcomp != COMPRESSION_NONE)
+                {
+                    throw Encoder::TIFFCompressionException(); // retry without compression
+                }
+
+                vigra_postcondition(success != -1,
+                        "exportImage(): Unable to write TIFF data.");
+            }
+        }
+    };
+
+    void TIFFEncoderImpl::setCompressionType( const std::string & comp,
+                                              int quality = -1 )
+    {
+        // if any compression type is set that we do not support,
+        // the expected behavior is to do nothing
+        if ( comp == "NONE" )
+            tiffcomp = COMPRESSION_NONE;
+        else if ( ( comp == "JPEG" ) && ( quality != -1 ) )
+            tiffcomp = COMPRESSION_OJPEG;
+        else if ( comp == "RLE" || comp == "RunLength")
+            tiffcomp = COMPRESSION_CCITTRLE;
+        else if ( comp == "PACKBITS")
+            tiffcomp = COMPRESSION_PACKBITS;
+        else if ( comp == "LZW" )
+            tiffcomp = COMPRESSION_LZW;
+        else if ( comp == "DEFLATE" )
+            tiffcomp = COMPRESSION_DEFLATE;
+    }
+
+    void TIFFEncoderImpl::finalizeSettings()
+    {
+        // decide if we should write Grey, or RGB files
+        // all additional channels are treated as extra samples
+        if (samples_per_pixel < 3) {
+            extra_samples_per_pixel = samples_per_pixel - 1;
+        } else {
+            extra_samples_per_pixel = samples_per_pixel - 3;
+        }
+
+        // set some fields
+        TIFFSetField( tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
+        TIFFSetField( tiff, TIFFTAG_IMAGEWIDTH, width );
+        TIFFSetField( tiff, TIFFTAG_IMAGELENGTH, height );
+        // TIFFDefaultStripSize tries for 8kb strips! Laughable!
+        // This will do a 1MB strip for 8-bit images,
+        // 2MB strip for 16-bit, and so forth.
+        unsigned int estimate =
+            (unsigned int)std::max(static_cast<UIntBiggest>(1),
+                                  (static_cast<UIntBiggest>(1)<<20) / (width * samples_per_pixel));
+        TIFFSetField( tiff, TIFFTAG_ROWSPERSTRIP,
+                      stripheight = TIFFDefaultStripSize( tiff, estimate ) );
+        TIFFSetField( tiff, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel );
+        TIFFSetField( tiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT );
+        TIFFSetField( tiff, TIFFTAG_COMPRESSION, tiffcomp );
+
+        // subfile descriptor
+        TIFFSetField( tiff, TIFFTAG_SUBFILETYPE, 0);
+
+        // set pixel type
+        if ( pixeltype == "BILEVEL" ) {
+            // no sampleformat applies for bilevel
+            bits_per_sample = 1;
+        } else if ( pixeltype == "UINT8" ) {
+            TIFFSetField( tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT );
+            bits_per_sample = 8;
+        } else if ( pixeltype == "INT16" ) {
+            TIFFSetField( tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT );
+            bits_per_sample = 16;
+        } else if ( pixeltype == "UINT16" ) {
+            TIFFSetField( tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT );
+            bits_per_sample = 16;
+        } else if ( pixeltype == "INT32" ) {
+            TIFFSetField( tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT );
+            bits_per_sample = 32;
+        } else if ( pixeltype == "UINT32" ) {
+            TIFFSetField( tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT );
+            bits_per_sample = 32;
+        } else if ( pixeltype == "FLOAT" ) {
+            TIFFSetField( tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP );
+            bits_per_sample = 32;
+        } else if ( pixeltype == "DOUBLE" ) {
+            TIFFSetField( tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP );
+            bits_per_sample = 64;
+        }
+        TIFFSetField( tiff, TIFFTAG_BITSPERSAMPLE, bits_per_sample );
+
+       if (extra_samples_per_pixel > 0) {
+              uint16 * types = new  uint16[extra_samples_per_pixel];
+           for ( int i=0; i < extra_samples_per_pixel; i++ ) {
+              types[i] = EXTRASAMPLE_UNASSALPHA;
+            }
+            TIFFSetField( tiff, TIFFTAG_EXTRASAMPLES, extra_samples_per_pixel,
+                          types );
+                delete[] types;
+        }
+
+        // set photometric
+        if ( samples_per_pixel - extra_samples_per_pixel == 1 )
+            TIFFSetField( tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK );
+        else if ( samples_per_pixel - extra_samples_per_pixel == 3 )
+            TIFFSetField( tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB );
+
+        // set resolution
+        if ( x_resolution > 0) {
+            TIFFSetField( tiff, TIFFTAG_XRESOLUTION, x_resolution );
+        }
+        if ( y_resolution > 0 ) {
+            TIFFSetField( tiff, TIFFTAG_YRESOLUTION, y_resolution );
+        }
+        if (x_resolution > 0 || y_resolution > 0) {
+            TIFFSetField( tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH );
+        }
+
+        // save position, if available
+        if (position.x >= 0 && position.y >= 0 &&
+            x_resolution > 0 && y_resolution > 0)
+        {
+            TIFFSetField( tiff, TIFFTAG_XPOSITION, position.x / x_resolution);
+            TIFFSetField( tiff, TIFFTAG_YPOSITION, position.y / y_resolution);
+        }
+
+        if ((uint32)canvasSize.x >= position.x + width
+            && (uint32)canvasSize.y >= position.y + height)
+        {
+            TIFFSetField( tiff, TIFFTAG_PIXAR_IMAGEFULLWIDTH, canvasSize.x);
+            TIFFSetField( tiff, TIFFTAG_PIXAR_IMAGEFULLLENGTH, canvasSize.y);
+        }
+
+        // Set ICC profile, if available.
+        if (iccProfile.size()) {
+            TIFFSetField(tiff, TIFFTAG_ICCPROFILE,
+                         iccProfile.size(), iccProfile.begin());
+        }
+
+        // alloc memory
+        stripbuffer = new tdata_t[1];
+        stripbuffer[0] = 0;
+        stripbuffer[0] = _TIFFmalloc( TIFFStripSize(tiff) );
+        if(stripbuffer[0] == 0)
+            throw std::bad_alloc();
+
+        finalized = true;
+    }
+
+    void TIFFEncoder::init( const std::string & filename, const std::string & mode )
+    {
+        pimpl = new TIFFEncoderImpl(filename, mode);
+    }
+
+    TIFFEncoder::~TIFFEncoder()
+    {
+        delete pimpl;
+    }
+
+    std::string TIFFEncoder::getFileType() const
+    {
+        return "TIFF";
+    }
+
+    void TIFFEncoder::setWidth( unsigned int width )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->width = width;
+    }
+
+    void TIFFEncoder::setHeight( unsigned int height )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->height = height;
+    }
+
+    void TIFFEncoder::setNumBands( unsigned int bands )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->samples_per_pixel = bands;
+    }
+
+    void TIFFEncoder::setCompressionType( const std::string & comp,
+                                          int quality )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->setCompressionType( comp, quality );
+    }
+
+    void TIFFEncoder::setPixelType( const std::string & pixeltype )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->pixeltype = pixeltype;
+    }
+
+    void TIFFEncoder::setPosition( const vigra::Diff2D & pos )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->position = pos;
+    }
+
+    void TIFFEncoder::setCanvasSize( const vigra::Size2D & size )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->canvasSize = size;
+    }
+
+    void TIFFEncoder::setXResolution( float xres )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->x_resolution = xres;
+    }
+
+    void TIFFEncoder::setYResolution( float yres )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->y_resolution = yres;
+    }
+
+    unsigned int TIFFEncoder::getOffset() const
+    {
+        return pimpl->samples_per_pixel;
+    }
+
+    void TIFFEncoder::finalizeSettings()
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->finalizeSettings();
+    }
+
+    void * TIFFEncoder::currentScanlineOfBand( unsigned int band )
+    {
+        return pimpl->currentScanlineOfBand(band);
+    }
+
+    void TIFFEncoder::nextScanline()
+    {
+        pimpl->nextScanline();
+    }
+
+    void TIFFEncoder::setICCProfile(const ICCProfile & data)
+    {
+        pimpl->iccProfile = data;
+    }
+
+    void TIFFEncoder::close() {}
+    void TIFFEncoder::abort() {}
+}
+
+#endif // HasTIFF
diff --git a/src/impex/tiff.hxx b/src/impex/tiff.hxx
new file mode 100644
index 0000000..c5d7a33
--- /dev/null
+++ b/src/impex/tiff.hxx
@@ -0,0 +1,151 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 1998-2001 by Gunnar Kedenburg                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+/* Modifications by Pablo d'Angelo
+ * updated to vigra 1.4 by Douglas Wilkins
+ * as of 18 Febuary 2006:
+ *  - Added support for obtaining extra bands beyond RGB.
+ *  - Added support for a position field that indicates the start of this
+ *    image relative to some global origin.
+ *  - Added support for x and y resolution fields.
+ * Modifications by Andrew Mihal, as of 16 October 2004
+ *  - Added include for vigra/diff2d.hxx
+ *  - Added support for ICC profiles
+ */
+
+#ifndef VIGRA_IMPEX_TIFF_HXX
+#define VIGRA_IMPEX_TIFF_HXX
+
+#include <vector>
+#include "vigra/diff2d.hxx"
+#include "vigra/codec.hxx"
+
+namespace vigra {
+
+    struct TIFFCodecFactory : public CodecFactory
+    {
+        CodecDesc getCodecDesc() const;
+        VIGRA_UNIQUE_PTR<Decoder> getDecoder() const;
+        VIGRA_UNIQUE_PTR<Encoder> getEncoder() const;
+    };
+
+    class TIFFDecoderImpl;
+    class TIFFEncoderImpl;
+
+    class TIFFDecoder : public Decoder
+    {
+        TIFFDecoderImpl * pimpl;
+
+    public:
+
+        TIFFDecoder() : pimpl(0) {}
+
+        ~TIFFDecoder();
+
+        std::string getFileType() const;
+        unsigned int getWidth() const;
+        unsigned int getHeight() const;
+        unsigned int getNumBands() const;
+
+        unsigned int getNumExtraBands() const;
+
+        unsigned int getNumImages() const;
+        void setImageIndex(unsigned int);
+        unsigned int getImageIndex() const;
+
+        Diff2D getPosition() const;
+        Size2D getCanvasSize() const;
+        float getXResolution() const;
+        float getYResolution() const;
+
+        const void * currentScanlineOfBand( unsigned int ) const;
+        void nextScanline();
+
+        std::string getPixelType() const;
+        unsigned int getOffset() const;
+
+        void init( const std::string &, unsigned int );
+        void init( const std::string & fileName)
+        {
+            init(fileName, 0);
+        }
+
+        void close();
+        void abort();
+    };
+
+    class TIFFEncoder : public Encoder
+    {
+        TIFFEncoderImpl * pimpl;
+
+    public:
+
+        TIFFEncoder() : pimpl(0) {}
+
+        ~TIFFEncoder();
+
+        std::string getFileType() const;
+        void setWidth( unsigned int );
+        void setHeight( unsigned int );
+        void setNumBands( unsigned int );
+
+        void setCompressionType( const std::string &, int = -1 );
+        void setPixelType( const std::string & );
+
+        void setPosition( const vigra::Diff2D & pos );
+        void setCanvasSize( const Size2D & pos );
+        void setXResolution( float xres );
+        void setYResolution( float yres );
+
+        unsigned int getOffset() const;
+
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int );
+        void nextScanline();
+
+        void setICCProfile(const ICCProfile & data);
+
+        void init( const std::string &, const std::string & );
+        void init( const std::string & fileName)
+        {
+            init(fileName, "w");
+        }
+
+        void close();
+        void abort();
+    };
+}
+
+#endif // VIGRA_IMPEX_TIFF_HXX
diff --git a/src/impex/viff.cxx b/src/impex/viff.cxx
new file mode 100644
index 0000000..03dbbf1
--- /dev/null
+++ b/src/impex/viff.cxx
@@ -0,0 +1,1090 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <fstream>
+#include "vigra/config.hxx"
+#include "vigra/sized_int.hxx"
+#include "error.hxx"
+#include "byteorder.hxx"
+#include "void_vector.hxx"
+#include "viff.hxx"
+
+// VIFF definitions from the specification
+// TODO: support complex types
+
+/* definitions for version number,
+   char release; */
+#define XV_IMAGE_VER_NUM    3   /* Version 3 (3.1) */
+
+/* definitions for release number,
+   char version; */
+#define XV_IMAGE_REL_NUM    1   /* Release 1   */
+
+/* definitions for subimage information,
+   long startx, starty; */
+#define VFF_NOTSUB          ~0  /* a negative number indicates that
+                       the image is not a subimage  */
+
+/* definitions for machine dependencies,
+   char machine_dep; */
+#define VFF_DEP_IEEEORDER       0x2 /* IEEE byte ordering */
+#define VFF_DEP_DECORDER        0x4 /* DEC (VAX) byte ordering */
+#define VFF_DEP_NSORDER     0x8 /* NS32000 byte ordering */
+#define VFF_DEP_CRAYORDER   0xA /* Cray byte size and ordering */
+
+#define VFF_DEP_BIGENDIAN   VFF_DEP_IEEEORDER
+#define VFF_DEP_LITENDIAN   VFF_DEP_NSORDER
+
+
+/* definitions for data storage type,
+   unsigned long data_storage_type; */
+#define VFF_TYP_BIT     0   /* pixels are on or off (binary image)*/
+                                        /* Note: This is an X11 XBitmap 
+                       with bits packed into a byte and
+                       padded to a byte */
+#define VFF_TYP_1_BYTE      1   /* pixels are byte (unsigned char) */
+#define VFF_TYP_2_BYTE      2   /* pixels are two byte (short int) */
+#define VFF_TYP_4_BYTE      4   /* pixels are four byte (integer) */
+#define VFF_TYP_FLOAT       5   /* pixels are float (single precision)*/
+#define VFF_TYP_COMPLEX     6   /* pixels are complex float */
+#define VFF_TYP_DOUBLE      9   /* pixels are float (double precision)*/
+
+#define VFF_TYP_DCOMPLEX    10  /* double complex */
+
+/* definitions for data encoding scheme on disk - i.e. it may be
+   compressed using RLE, or uncompressed (RAW).
+   unsigned long data_encode_scheme; */
+#define VFF_DES_RAW     0   /* Raw - no compression */
+#define VFF_DES_COMPRESS    1   /* Compressed using ALZ */
+#define VFF_DES_RLE     2   /* Compressed using RLE */
+#define VFF_DES_TRANSFORM   3   /* Transform based compression */
+#define VFF_DES_CCITT       4   /* CCITT standard compression */
+#define VFF_DES_ADPCM       5   /* ADPCM compression */
+#define VFF_DES_GENERIC     6   /* User-specified compression */
+
+/* definitions for map data or cells storage type,
+   unsigned long map_storage_type; */
+#define VFF_MAPTYP_NONE     0   /* No cell type is assigned  */
+#define VFF_MAPTYP_1_BYTE   1   /* cells are byte (unsigned char)    */
+#define VFF_MAPTYP_2_BYTE   2   /* cells are two byte (short int) */
+#define VFF_MAPTYP_4_BYTE   4   /* cells are four byte (integer) */
+#define VFF_MAPTYP_FLOAT    5   /* cells are float (single precision) */
+#define VFF_MAPTYP_COMPLEX  6   /* cells are complex FLOAT */
+#define VFF_MAPTYP_DOUBLE   7   /* cells are float (double precision) */
+
+/* definitions for mapping schemes,
+   unsigned long map_scheme; */
+#define VFF_MS_NONE     0   /* No mapping is to be done, and no
+                       maps are to be stored. */
+#define VFF_MS_ONEPERBAND   1   /* Each data band has its own map */
+#define VFF_MS_CYCLE        2   /* An array of maps is selected in order
+                       by groups of maps_per_cycle, allowing
+                       "rotating the color map" */
+#define VFF_MS_SHARED       3   /* All data band share the same map */
+#define VFF_MS_GROUP        4   /* All data bands are "grouped" 
+                       together to point into one map */
+/* definitions for enabling the map,
+   unsigned long map_enable; */
+#define VFF_MAP_OPTIONAL    1   /* The data is valid without being
+                       sent thru the color map. If a
+                       map is defined, the data may 
+                       optionally be sent thru it. */
+#define VFF_MAP_FORCE       2   /* The data MUST be sent thru the map
+                       to be interpreted */
+
+/* definitions for color map models,
+   unsigned long color_space_model; */
+
+/*  the models use the following convention:
+    ntsc: national television systems committee
+    cie:  Commission Internationale de L'Eclairage
+    ucs:  universal chromaticity scale
+    RGB:  red band, green band, blue band
+    CMY:  cyan band, magenta band, yellow band
+    YIQ:  luminance, I and Q represent chrominance
+    HSV:  hue, saturation, value
+    IHS:  intensity, hue, saturation
+    XYZ:
+    UVW:  
+    SOW:  
+    Lab:
+    Luv:
+
+    For more information on how to interpret the combined meaning of the
+    colorspace fields, see the document in $KHOROS_HOME/manual/viff_format,
+    which contains detailed descriptions on the fields along with numerous
+    examples of proper use.  */
+
+#define VFF_CM_NONE 0
+#define VFF_CM_ntscRGB  1
+#define VFF_CM_ntscCMY  2
+#define VFF_CM_ntscYIQ  3
+#define VFF_CM_HSV  4
+#define VFF_CM_HLS  5
+#define VFF_CM_IHS  6
+#define VFF_CM_cieRGB   7
+#define VFF_CM_cieXYZ   8
+#define VFF_CM_cieUVW   9
+#define VFF_CM_cieucsUVW    10
+#define VFF_CM_cieucsSOW    11
+#define VFF_CM_cieucsLab    12
+#define VFF_CM_cieucsLuv    13
+#define VFF_CM_GENERIC      14  /* the color space is user defined */
+#define VFF_CM_genericRGB   15  /* an RGB image but not conforming
+                       to any standard */
+
+/* definitions for location type,
+   unsigned long location_type; */
+#define VFF_LOC_IMPLICIT    1   /*  The location of image pixels
+                        or vector data is given by using
+                        the implied 2D array given by
+                        row_size and col_size.  */
+#define VFF_LOC_EXPLICIT    2   /*  The location of the image pixels
+                        or the vectors is explicit */
+
+namespace vigra {
+    
+    template< class T1, class T2 >
+    class colormap
+    {
+    public:
+        typedef T1 domain_type;
+        typedef T2 value_type;
+        typedef void_vector<value_type> vector_type;
+
+    private:
+        // size of lookup tables
+        const unsigned int m_numTableElements;
+
+        // number of lookup tables
+        const unsigned int m_numTables;
+
+        // number of bands in each lookup table
+        const unsigned int m_numTableBands;
+
+        // lookup tables
+        vector_type m_tables;
+
+    public:
+        colormap( const unsigned int numTableElements,
+                  const unsigned int numTables,
+                  const unsigned int numTableBands )
+            : m_numTableElements(numTableElements),
+              m_numTables(numTables), m_numTableBands(numTableBands),
+              m_tables( numTableElements * numTableBands )
+        {
+            vigra_precondition( ( numTables == 1 ) || ( numTableBands == 1 ),
+                                "numTables or numTableBands must be 1" );
+        }
+
+        inline unsigned int getNumTables() const
+        {
+            return m_numTables;
+        }
+
+        inline unsigned int getNumElements() const
+        {
+            return m_numTableElements;
+        }
+
+        // initialize a single table, data array must have the correct length
+        void initialize( const value_type * data, const unsigned int table )
+        {
+            vigra_precondition( table < m_numTables,
+                                "table number out of range" );
+            const unsigned int stride = m_numTableBands * m_numTableElements;
+            std::copy( data, data + stride, m_tables.data() + stride * table );
+        }
+
+        // map a single value
+        value_type operator()( const domain_type index,
+                               const unsigned int band = 0 ) const
+        {
+            vigra_precondition( index < m_numTableElements,
+                                "index out of range" );
+            if ( m_numTables == 1 ) {
+                // map bands with a single (interleaved or not) table
+                vigra_precondition( band < m_numTableBands,
+                                    "band out of range" );
+                return m_tables[ m_numTableElements * band + index ];
+            } else {
+                // map bands with multiple, non-interleaved tables
+                vigra_precondition( band < m_numTables, "band out of range" );
+                const unsigned int stride
+                    = m_numTableBands * m_numTableElements;
+                return m_tables[ stride * band + index ];
+            }
+        }
+    };
+
+
+    // this function encapsulates the colormap functor
+    template< class storage_type, class map_storage_type >
+    void map_multiband( void_vector<map_storage_type> & dest,
+                        unsigned int & dest_bands,
+                        const void_vector<storage_type> & src,
+                        unsigned int src_bands, unsigned int src_width, unsigned int src_height,
+                        const void_vector<map_storage_type> & maps,
+                        unsigned int map_bands, unsigned int map_width, unsigned int map_height )
+    {
+        vigra_precondition(src_bands == 1u,
+               "map_multiband(): Source image must have one band.");
+        
+        typedef colormap< storage_type, map_storage_type > colormap_type;
+        const unsigned int num_pixels = src_width * src_height;
+
+        // build the color map
+        const unsigned int map_band_size = map_width * map_height;
+        colormap_type colormap( map_height, map_bands, map_width );
+        for ( unsigned int i = 0; i < map_bands; ++i )
+            colormap.initialize( maps.data() + map_band_size * i, i );
+
+        // map each pixel
+        const unsigned int band_size = src_width * src_height;
+        dest_bands = map_bands * map_width;
+        dest.resize( band_size * dest_bands );
+        if ( map_width > 1 ) {
+            // interleaved maps => there is only one band in the image
+            for( unsigned int bandnum = 0; bandnum < dest_bands; ++bandnum )
+                for( unsigned int i = 0; i < num_pixels; ++i )
+                    dest[ bandnum * band_size + i ]
+                        = colormap( src[i], bandnum );
+        } else {
+            // non-interleaved bands => map can be used per band
+            for( unsigned int bandnum = 0; bandnum < dest_bands; ++bandnum )
+                for( unsigned int i = 0; i < num_pixels; ++i )
+                    dest[ bandnum * band_size + i ]
+                        = colormap( src[ bandnum * band_size + i ], bandnum );
+        }
+    }
+
+    CodecDesc ViffCodecFactory::getCodecDesc() const
+    {
+        CodecDesc desc;
+
+        // init file type
+        desc.fileType = "VIFF";
+
+        // init pixel types
+        desc.pixelTypes.resize(5);
+        desc.pixelTypes[0] = "UINT8";
+        desc.pixelTypes[1] = "INT16";
+        desc.pixelTypes[2] = "INT32";
+        desc.pixelTypes[3] = "FLOAT";
+        desc.pixelTypes[4] = "DOUBLE";
+
+        // init compression types
+        desc.compressionTypes.resize(0);
+
+        // init magic strings
+        desc.magicStrings.resize(1);
+        desc.magicStrings[0].resize(2);
+        desc.magicStrings[0][0] = '\253'; // XV_FILE_MAGIC_NUM
+        desc.magicStrings[0][1] = '\1';   // XV_FILE_TYPE_XVIFF
+
+        // init file extensions
+        desc.fileExtensions.resize(1);
+        desc.fileExtensions[0] = "xv";
+
+        desc.bandNumbers.resize(1);
+        desc.bandNumbers[0] = 0;
+        
+        return desc;
+    }
+
+    VIGRA_UNIQUE_PTR<Decoder> ViffCodecFactory::getDecoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Decoder>( new ViffDecoder() );
+    }
+
+    VIGRA_UNIQUE_PTR<Encoder> ViffCodecFactory::getEncoder() const
+    {
+        return VIGRA_UNIQUE_PTR<Encoder>( new ViffEncoder() );
+    }
+
+    class ViffHeader
+    {
+    public:
+        typedef UInt32 field_type;
+
+        field_type row_size, col_size, num_data_bands, data_storage_type,
+            data_encode_scheme, map_scheme, map_storage_type, map_row_size,
+            map_col_size;
+
+        void from_stream( std::ifstream & stream, byteorder & bo );
+        void to_stream( std::ofstream & stream, byteorder & bo ) const;
+    };
+
+    void ViffHeader::from_stream( std::ifstream & stream, byteorder & bo )
+    {
+        // scratch variables for values that do not need to be saved
+        field_type scratch;
+
+        // skip the magic number and the file type
+        stream.seekg( 2, std::ios::cur );
+
+        // check the release number
+        vigra_precondition( stream.get() == XV_IMAGE_REL_NUM,
+                            "file format release unsupported" );
+
+        // check the version number
+        vigra_precondition( stream.get() == XV_IMAGE_VER_NUM,
+                            "file format version unsupported" );
+
+        // check the endianness
+        const char machine_dep = stream.get();
+        if ( machine_dep == VFF_DEP_BIGENDIAN )
+            bo.set("big endian");
+        else if ( machine_dep == VFF_DEP_LITENDIAN )
+            bo.set("little endian");
+        else vigra_fail( "endianness unsupported" );
+
+        // skip the comments
+        stream.seekg( 0x208, std::ios::beg );
+
+        // read the row size
+        read_field( stream, bo, row_size );
+
+        // read the col size
+        read_field( stream, bo, col_size );
+
+        // skip subrow size, subimage (x,y) and pixelsize (x,y)
+        stream.seekg( 20, std::ios::cur );
+
+        read_field( stream, bo, scratch );
+        vigra_precondition( scratch != VFF_LOC_EXPLICIT,
+                            "explicit locations are unsupported" );
+
+        // skip location dim field (only used for explicit locations)
+        stream.seekg( 4, std::ios::cur );
+
+        // check number of images
+        read_field( stream, bo, scratch );
+        vigra_precondition( scratch < 2,
+                            "multiple images are unsupported" );
+
+        read_field( stream, bo, num_data_bands );
+
+        read_field( stream, bo, data_storage_type );
+        vigra_precondition( data_storage_type != VFF_TYP_BIT,
+                            "bit storage type unsupported" );
+        vigra_precondition( data_storage_type != VFF_TYP_COMPLEX,
+                            "complex storage type unsupported" );
+        vigra_precondition( data_storage_type != VFF_TYP_DCOMPLEX,
+                            "double complex storage type unsupported" );
+
+        read_field( stream, bo, data_encode_scheme );
+        vigra_precondition( data_encode_scheme == VFF_DES_RAW,
+                            "data compression unsupported" );
+
+        read_field( stream, bo, map_scheme );
+        vigra_precondition( map_scheme != VFF_MS_CYCLE,
+                            "map cycling unsupported" );
+
+        // only read the map fields if mapping is actually used
+        if ( map_scheme != VFF_MS_NONE ) {
+
+            read_field( stream, bo, map_storage_type );
+            vigra_precondition( map_storage_type != VFF_MAPTYP_COMPLEX,
+                                "complex storage type unsupported" );
+            vigra_precondition( map_storage_type != VFF_MAPTYP_NONE,
+                                "invalid maptype" );
+
+            read_field( stream, bo, map_row_size );
+            read_field( stream, bo, map_col_size );
+        }
+            
+        // seek behind the header. (skip colorspace and pointers)
+        stream.seekg( 1024, std::ios::beg );
+    }
+
+#if  __GNUC__ == 2
+    #define VIGRA_STREAM_CHAR_TYPE char
+#else
+    #define VIGRA_STREAM_CHAR_TYPE std::ofstream::char_type
+#endif
+
+    void ViffHeader::to_stream( std::ofstream & stream, byteorder & bo ) const
+    {
+        field_type scratch, null = 0;
+
+        // magic number
+        stream.put((VIGRA_STREAM_CHAR_TYPE)0xAB);
+            
+        // file type
+        stream.put((VIGRA_STREAM_CHAR_TYPE)0x01);
+
+        // file format release number
+        stream.put(XV_IMAGE_REL_NUM);
+
+        // file format version number
+        stream.put(XV_IMAGE_VER_NUM);
+
+        // set the byte order
+        if ( bo.get_host_byteorder() == "big endian" )
+        {
+            bo.set("big endian" );
+            stream.put(VFF_DEP_BIGENDIAN);
+        }
+        else 
+        {
+            bo.set("little endian" );
+            stream.put(VFF_DEP_LITENDIAN);
+        }
+
+        // pad, then zero out the comments
+        unsigned int i;
+        for(i = 0; i < 515; ++i )
+            stream.put(0);
+
+        // image size
+        write_field( stream, bo, row_size );
+        write_field( stream, bo, col_size );
+
+        // zero out five fields
+        for( i = 0; i < 20; ++i )
+            stream.put(0);
+
+        // using implicit locations
+        write_field( stream, bo, scratch = VFF_LOC_IMPLICIT );
+
+        // zero out one field
+        write_field( stream, bo, null );
+
+        // set number of images
+        write_field( stream, bo, scratch = 1 );
+
+        // image data format
+        write_field( stream, bo, num_data_bands );
+        write_field( stream, bo, data_storage_type );
+        write_field( stream, bo, scratch = VFF_DES_RAW );
+
+        // no color mapping
+        write_field( stream, bo, scratch = VFF_MS_NONE );
+        write_field( stream, bo, scratch = VFF_MAPTYP_NONE );
+
+        // zero out five fields
+        for( i = 0; i < 20; ++i )
+            stream.put(0);
+
+        // colorspace
+        scratch = num_data_bands == 3 ? VFF_CM_genericRGB: VFF_CM_NONE;
+        write_field( stream, bo, scratch );
+
+        // zero out the last bytes of the header
+        int offset = 1024 - stream.tellp();
+        vigra_precondition( offset >= 0,
+                            "machine is incapable to read viff" );
+        for( int j = 0; j < offset; ++j )
+            stream.put(0);
+    }
+
+    struct ViffDecoderImpl
+    {
+        unsigned int width, height, components, map_width,
+            map_height, num_maps;
+        std::string pixelType;
+        int current_scanline;
+
+        ViffHeader header;
+        void_vector_base maps, bands;
+
+        ViffDecoderImpl( const std::string & filename );
+
+        void read_maps( std::ifstream & stream, byteorder & bo );
+        void read_bands( std::ifstream & stream, byteorder & bo );
+        void color_map();
+    };
+
+    ViffDecoderImpl::ViffDecoderImpl( const std::string & filename )
+        : pixelType("undefined"), current_scanline(-1)
+    {
+#ifdef VIGRA_NEED_BIN_STREAMS
+        std::ifstream stream( filename.c_str(), std::ios::binary );
+#else
+        std::ifstream stream( filename.c_str() );
+#endif
+        
+        if(!stream.good())
+        {
+            std::string msg("Unable to open file '");
+            msg += filename;
+            msg += "'.";
+            vigra_precondition(0, msg.c_str());
+        }
+        byteorder bo( "big endian" );
+
+        // get header
+        header.from_stream( stream, bo );
+        width = header.row_size;
+        height = header.col_size;
+        components = header.num_data_bands;
+
+        // read data and eventually map it
+        if ( header.map_scheme != VFF_MS_NONE )
+            read_maps( stream, bo );
+        read_bands( stream, bo );
+        if ( header.map_scheme != VFF_MS_NONE )
+            color_map();
+    }
+
+    void ViffDecoderImpl::read_maps( std::ifstream & stream, byteorder & bo )
+    {
+        const bool shared_map = ( header.map_scheme == VFF_MS_SHARED );
+        num_maps = shared_map ? 1 : header.num_data_bands;
+        map_width = header.map_row_size;
+        map_height = header.map_col_size;
+        const unsigned int maps_size = map_width * map_height * num_maps;
+
+        if ( header.map_storage_type == VFF_MAPTYP_1_BYTE ) {
+            typedef void_vector<UInt8> maps_type;
+            maps_type & castmaps = static_cast< maps_type & >(maps);
+            castmaps.resize(maps_size);
+            read_array( stream, bo, castmaps.data(), maps_size );
+        } else if ( header.map_storage_type == VFF_MAPTYP_2_BYTE ) {
+            typedef void_vector<Int16> maps_type;
+            maps_type & castmaps = static_cast< maps_type & >(maps);
+            castmaps.resize(maps_size);
+            read_array( stream, bo, castmaps.data(), maps_size );
+        } else if ( header.map_storage_type == VFF_MAPTYP_4_BYTE ) {
+            typedef void_vector<Int32> maps_type;
+            maps_type & castmaps = static_cast< maps_type & >(maps);
+            castmaps.resize(maps_size);
+            read_array( stream, bo, castmaps.data(), maps_size );
+        } else if ( header.map_storage_type == VFF_MAPTYP_FLOAT ) {
+            typedef void_vector<float> maps_type;
+            maps_type & castmaps = static_cast< maps_type & >(maps);
+            castmaps.resize(maps_size);
+            read_array( stream, bo, castmaps.data(), maps_size );
+        } else
+            vigra_precondition( false, "map storage type unsupported" );
+    }
+
+    void ViffDecoderImpl::read_bands( std::ifstream & stream, byteorder & bo )
+    {
+        const unsigned int bands_size = width * height * components;
+
+        if ( header.data_storage_type == VFF_TYP_1_BYTE ) {
+            typedef void_vector<UInt8> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(bands);
+            castbands.resize(bands_size);
+            read_array( stream, bo, castbands.data(), bands_size );
+            pixelType = "UINT8";
+        } else if ( header.data_storage_type == VFF_TYP_2_BYTE ) {
+            typedef void_vector<Int16> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(bands);
+            castbands.resize(bands_size);
+            read_array( stream, bo, castbands.data(), bands_size );
+            pixelType = "INT16";
+        } else if ( header.data_storage_type == VFF_TYP_4_BYTE ) {
+            typedef void_vector<Int32> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(bands);
+            castbands.resize(bands_size);
+            read_array( stream, bo, castbands.data(), bands_size );
+            pixelType = "INT32";
+        } else if ( header.data_storage_type == VFF_TYP_FLOAT ) {
+            typedef void_vector<float> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(bands);
+            castbands.resize(bands_size);
+            read_array( stream, bo, castbands.data(), bands_size );
+            pixelType = "FLOAT";
+        } else if ( header.data_storage_type == VFF_TYP_DOUBLE ) {
+            typedef void_vector<double> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(bands);
+            castbands.resize(bands_size);
+            read_array( stream, bo, castbands.data(), bands_size );
+            pixelType = "DOUBLE";
+        } else
+            vigra_precondition( false, "storage type unsupported" );
+    }
+
+    void ViffDecoderImpl::color_map()
+    {
+        void_vector_base temp_bands;
+        unsigned int temp_num_bands;
+
+        if ( header.map_storage_type == VFF_MAPTYP_1_BYTE ) {
+            typedef UInt8 map_storage_type;
+
+            if ( header.data_storage_type == VFF_TYP_1_BYTE ) {
+                typedef UInt8 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+
+            } else if ( header.data_storage_type == VFF_TYP_2_BYTE ) {
+                typedef UInt16 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+
+            } else if ( header.data_storage_type == VFF_TYP_4_BYTE ) {
+                typedef UInt32 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+
+            } else
+                vigra_precondition( false, "storage type unsupported" );
+
+            pixelType = "UINT8";
+
+        } else if ( header.map_storage_type == VFF_MAPTYP_2_BYTE ) {
+            typedef UInt16 map_storage_type;
+
+            if ( header.data_storage_type == VFF_TYP_1_BYTE ) {
+                typedef UInt8 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+
+            } else if ( header.data_storage_type == VFF_TYP_2_BYTE ) {
+                typedef UInt16 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+
+            } else if ( header.data_storage_type == VFF_TYP_4_BYTE ) {
+                typedef UInt32 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+
+            } else
+                vigra_precondition( false, "storage type unsupported" );
+
+            pixelType = "INT16";
+
+        } else if ( header.map_storage_type == VFF_MAPTYP_4_BYTE ) {
+            typedef UInt32 map_storage_type;
+
+            if ( header.data_storage_type == VFF_TYP_1_BYTE ) {
+                typedef UInt8 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+
+            } else if ( header.data_storage_type == VFF_TYP_2_BYTE ) {
+                typedef UInt16 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+
+            } else if ( header.data_storage_type == VFF_TYP_4_BYTE ) {
+                typedef UInt32 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+
+            } else
+                vigra_precondition( false, "storage type unsupported" );
+
+            pixelType = "INT32";
+
+        } else if ( header.map_storage_type == VFF_MAPTYP_FLOAT ) {
+            typedef float map_storage_type;
+
+            if ( header.data_storage_type == VFF_TYP_1_BYTE ) {
+                typedef UInt8 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+
+            } else if ( header.data_storage_type == VFF_TYP_2_BYTE ) {
+                typedef UInt16 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+
+            } else if ( header.data_storage_type == VFF_TYP_4_BYTE ) {
+                typedef UInt32 storage_type;
+                typedef void_vector<storage_type> bands_type;
+                typedef void_vector<map_storage_type> maps_type;
+                map_multiband( static_cast< maps_type & >(temp_bands),
+                               temp_num_bands,
+                               static_cast< const bands_type & >(bands),
+                               components, width, height,
+                               static_cast< const maps_type & >(maps),
+                               num_maps, map_width, map_height );
+ 
+            } else
+                vigra_precondition( false, "storage type unsupported" );
+
+            pixelType = "FLOAT";
+
+        } else
+            vigra_precondition( false, "map storage type unsupported" );
+
+        swap_void_vector( bands, temp_bands );
+        components = temp_num_bands;
+    }
+
+    void ViffDecoder::init( const std::string & filename )
+    {
+        pimpl = new ViffDecoderImpl(filename);
+    }
+
+    ViffDecoder::~ViffDecoder()
+    {
+        delete pimpl;
+    }
+
+    std::string ViffDecoder::getFileType() const
+    {
+        return "VIFF";
+    }
+
+    unsigned int ViffDecoder::getWidth() const
+    {
+        return pimpl->width;
+    }
+
+    unsigned int ViffDecoder::getHeight() const
+    {
+        return pimpl->height;
+    }
+
+    unsigned int ViffDecoder::getNumBands() const
+    {
+        return pimpl->components;
+    }
+
+    std::string ViffDecoder::getPixelType() const
+    {
+        return pimpl->pixelType;
+    }
+
+    unsigned int ViffDecoder::getOffset() const
+    {
+        return 1; // this is multiband data
+    }
+
+    const void * ViffDecoder::currentScanlineOfBand( unsigned int band ) const
+    {
+        const unsigned int index = pimpl->width
+            * ( pimpl->height * band + pimpl->current_scanline );
+        if ( pimpl->pixelType == "UINT8" ) {
+            typedef void_vector<UInt8> bands_type;
+            const bands_type & bands
+                = static_cast< const bands_type & >(pimpl->bands);
+            return bands.data() + index;
+        } else if ( pimpl->pixelType == "INT16" ) {
+            typedef void_vector<Int16> bands_type;
+            const bands_type & bands
+                = static_cast< const bands_type & >(pimpl->bands);
+            return bands.data() + index;
+        } else if ( pimpl->pixelType == "INT32" ) {
+            typedef void_vector<Int32> bands_type;
+            const bands_type & bands
+                = static_cast< const bands_type & >(pimpl->bands);
+            return bands.data() + index;
+        } else if ( pimpl->pixelType == "FLOAT" ) {
+            typedef void_vector<float> bands_type;
+            const bands_type & bands
+                = static_cast< const bands_type & >(pimpl->bands);
+            return bands.data() + index;
+        } else if ( pimpl->pixelType == "DOUBLE" ) {
+            typedef void_vector<double> bands_type;
+            const bands_type & bands
+                = static_cast< const bands_type & >(pimpl->bands);
+            return bands.data() + index;
+        } else {
+            vigra_fail( "PixelType was not set correctly" );
+            return 0;
+        }
+    }
+
+    void ViffDecoder::nextScanline()
+    {
+        ++(pimpl->current_scanline);
+    }
+
+    void ViffDecoder::close() {}
+    void ViffDecoder::abort() {}
+
+    // VIFF Encoder
+
+    struct ViffEncoderImpl
+    {
+        std::ofstream stream;
+        byteorder bo;
+        std::string pixelType;
+        int current_scanline;
+        bool finalized;
+
+        ViffHeader header;
+        void_vector_base bands;
+
+        ViffEncoderImpl( const std::string & filename )
+#ifdef VIGRA_NEED_BIN_STREAMS
+            : stream( filename.c_str(), std::ios::binary ), 
+#else
+            : stream( filename.c_str() ), 
+#endif
+              bo( "big endian" ),
+              pixelType("undefined"), current_scanline(0), finalized(false)
+        {
+            if(!stream.good())
+            {
+                std::string msg("Unable to open file '");
+                msg += filename;
+                msg += "'.";
+                vigra_precondition(false, msg);
+            }
+        }
+
+    };
+
+    void ViffEncoder::init( const std::string & filename )
+    {
+        pimpl = new ViffEncoderImpl(filename);
+    }
+
+    ViffEncoder::~ViffEncoder()
+    {
+        delete pimpl;
+    }
+
+    std::string ViffEncoder::getFileType() const
+    {
+        return "VIFF";
+    }
+
+    void ViffEncoder::setWidth( unsigned int width )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->header.row_size = static_cast<ViffHeader::field_type>(width);
+    }
+
+    void ViffEncoder::setHeight( unsigned int height )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->header.col_size = static_cast<ViffHeader::field_type>(height);
+    }
+
+    void ViffEncoder::setNumBands( unsigned int numBands )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->header.num_data_bands = static_cast<ViffHeader::field_type>(numBands);
+    }
+
+    void ViffEncoder::setCompressionType( const std::string & /* comp */, int /* quality */)
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+    }
+
+    void ViffEncoder::setPixelType( const std::string & pixelType )
+    {
+        VIGRA_IMPEX_FINALIZED(pimpl->finalized);
+        pimpl->pixelType = pixelType;
+        if ( pixelType == "UINT8" )
+            pimpl->header.data_storage_type = VFF_TYP_1_BYTE;
+        else if ( pixelType == "INT16" )
+            pimpl->header.data_storage_type = VFF_TYP_2_BYTE;
+        else if ( pixelType == "INT32" )
+            pimpl->header.data_storage_type = VFF_TYP_4_BYTE;
+        else if ( pixelType == "FLOAT" )
+            pimpl->header.data_storage_type = VFF_TYP_FLOAT;
+        else if ( pixelType == "DOUBLE" )
+            pimpl->header.data_storage_type = VFF_TYP_DOUBLE;
+    }
+
+    unsigned int ViffEncoder::getOffset() const
+    {
+        return 1;
+    }
+
+    void ViffEncoder::finalizeSettings()
+    {
+        pimpl->header.to_stream( pimpl->stream, pimpl->bo );
+
+        const unsigned int bands_size = pimpl->header.row_size
+            * pimpl->header.col_size * pimpl->header.num_data_bands;
+
+        if ( pimpl->header.data_storage_type == VFF_TYP_1_BYTE ) {
+            typedef void_vector<UInt8> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(pimpl->bands);
+            castbands.resize(bands_size);
+        } else if ( pimpl->header.data_storage_type == VFF_TYP_2_BYTE ) {
+            typedef void_vector<Int16> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(pimpl->bands);
+            castbands.resize(bands_size);
+        } else if ( pimpl->header.data_storage_type == VFF_TYP_4_BYTE ) {
+            typedef void_vector<Int32> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(pimpl->bands);
+            castbands.resize(bands_size);
+        } else if ( pimpl->header.data_storage_type == VFF_TYP_FLOAT ) {
+            typedef void_vector<float> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(pimpl->bands);
+            castbands.resize(bands_size);
+        } else if ( pimpl->header.data_storage_type == VFF_TYP_DOUBLE ) {
+            typedef void_vector<double> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(pimpl->bands);
+            castbands.resize(bands_size);
+        } else
+            vigra_precondition( false, "storage type unsupported" );
+
+        pimpl->finalized = true;
+    }
+
+    void * ViffEncoder::currentScanlineOfBand( unsigned int band )
+    {
+        const unsigned int index = pimpl->header.row_size
+            * ( pimpl->header.col_size * band + pimpl->current_scanline );
+        if ( pimpl->pixelType == "UINT8" ) {
+            typedef void_vector<UInt8> bands_type;
+             bands_type & bands = static_cast<  bands_type & >(pimpl->bands);
+            return bands.data() + index;
+        } else if ( pimpl->pixelType == "INT16" ) {
+            typedef void_vector<Int16> bands_type;
+             bands_type & bands = static_cast<  bands_type & >(pimpl->bands);
+            return bands.data() + index;
+        } else if ( pimpl->pixelType == "INT32" ) {
+            typedef void_vector<Int32> bands_type;
+             bands_type & bands = static_cast<  bands_type & >(pimpl->bands);
+            return bands.data() + index;
+        } else if ( pimpl->pixelType == "FLOAT" ) {
+            typedef void_vector<float> bands_type;
+             bands_type & bands = static_cast<  bands_type & >(pimpl->bands);
+            return bands.data() + index;
+        } else if ( pimpl->pixelType == "DOUBLE" ) {
+            typedef void_vector<double> bands_type;
+             bands_type & bands = static_cast<  bands_type & >(pimpl->bands);
+            return bands.data() + index;
+        } else {
+            vigra_postcondition( false, "PixelType was not set correctly" );
+            return 0;
+        }
+    }
+
+    void ViffEncoder::nextScanline()
+    {
+        ++(pimpl->current_scanline);
+    }
+
+    void ViffEncoder::close()
+    {
+        // write bands to disk
+        const unsigned int bands_size = pimpl->header.row_size
+            * pimpl->header.col_size * pimpl->header.num_data_bands;
+
+        if ( pimpl->header.data_storage_type == VFF_TYP_1_BYTE ) {
+            typedef void_vector<UInt8> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(pimpl->bands);
+            write_array( pimpl->stream, pimpl->bo,
+                         castbands.data(), bands_size );
+        } else if ( pimpl->header.data_storage_type == VFF_TYP_2_BYTE ) {
+            typedef void_vector<Int16> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(pimpl->bands);
+            write_array( pimpl->stream, pimpl->bo,
+                         castbands.data(), bands_size );
+        } else if ( pimpl->header.data_storage_type == VFF_TYP_4_BYTE ) {
+            typedef void_vector<Int32> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(pimpl->bands);
+            write_array( pimpl->stream, pimpl->bo,
+                         castbands.data(), bands_size );
+        } else if ( pimpl->header.data_storage_type == VFF_TYP_FLOAT ) {
+            typedef void_vector<float> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(pimpl->bands);
+            write_array( pimpl->stream, pimpl->bo,
+                         castbands.data(), bands_size );
+        } else if ( pimpl->header.data_storage_type == VFF_TYP_DOUBLE ) {
+            typedef void_vector<double> bands_type;
+            bands_type & castbands = static_cast< bands_type & >(pimpl->bands);
+            write_array( pimpl->stream, pimpl->bo,
+                         castbands.data(), bands_size );
+        } else
+            vigra_precondition( false, "storage type unsupported" );
+    }
+
+    void ViffEncoder::abort() {}
+
+} // namespace vigra
diff --git a/src/impex/viff.hxx b/src/impex/viff.hxx
new file mode 100644
index 0000000..51af718
--- /dev/null
+++ b/src/impex/viff.hxx
@@ -0,0 +1,108 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_IMPEX_VIFF_HXX
+#define VIGRA_IMPEX_VIFF_HXX
+
+#include "vigra/codec.hxx"
+
+// VIFF - Khoros Visualization/Image File Format
+
+namespace vigra {
+
+    struct ViffCodecFactory : public CodecFactory
+    {
+        CodecDesc getCodecDesc() const;
+        VIGRA_UNIQUE_PTR<Decoder> getDecoder() const;
+        VIGRA_UNIQUE_PTR<Encoder> getEncoder() const;
+    };
+
+    struct ViffDecoderImpl;
+    struct ViffEncoderImpl;
+
+    class ViffDecoder : public Decoder
+    {
+        ViffDecoderImpl * pimpl;
+
+    public:
+
+        ViffDecoder() : pimpl(0) {}
+
+        ~ViffDecoder();
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        std::string getPixelType() const;
+
+        unsigned int getWidth() const;
+        unsigned int getHeight() const;
+        unsigned int getNumBands() const;
+        unsigned int getOffset() const;
+
+        const void * currentScanlineOfBand( unsigned int ) const;
+        void nextScanline();
+    };
+
+    class ViffEncoder : public Encoder
+    {
+        ViffEncoderImpl * pimpl;
+
+    public:
+
+        ViffEncoder() : pimpl(0) {}
+
+        ~ViffEncoder();
+        void init( const std::string & );
+        void close();
+        void abort();
+
+        std::string getFileType() const;
+        unsigned int getOffset() const;
+
+        void setWidth( unsigned int );
+        void setHeight( unsigned int );
+        void setNumBands( unsigned int );
+        void setCompressionType( const std::string &, int = -1 );
+        void setPixelType( const std::string & );
+        void finalizeSettings();
+
+        void * currentScanlineOfBand( unsigned int );
+        void nextScanline();
+    };
+}
+
+#endif // VIGRA_IMPEX_VIFF_HXX
diff --git a/src/impex/void_vector.cxx b/src/impex/void_vector.cxx
new file mode 100644
index 0000000..cb8f0e9
--- /dev/null
+++ b/src/impex/void_vector.cxx
@@ -0,0 +1,46 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include "void_vector.hxx"
+
+namespace vigra
+{
+    void swap_void_vector( void_vector_base & left, void_vector_base & right )
+    {
+        std::swap( left.m_data, right.m_data );
+        std::swap( left.m_size, right.m_size );
+        std::swap( left.m_capacity, right.m_capacity );
+    }
+}
diff --git a/src/impex/void_vector.hxx b/src/impex/void_vector.hxx
new file mode 100644
index 0000000..9bd4583
--- /dev/null
+++ b/src/impex/void_vector.hxx
@@ -0,0 +1,266 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2002 by Gunnar Kedenburg                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_IMPEX_VOIDVECTOR
+#define VIGRA_IMPEX_VOIDVECTOR
+
+// use this only for pod types
+
+#include <algorithm>
+#include <cstring>
+#include "vigra/config.hxx"
+
+namespace vigra
+{
+
+    // void_vector_base does not support iteration or subscripting
+    // (because the payload is not typed)
+    class void_vector_base
+    {
+        friend void swap_void_vector( void_vector_base & left, void_vector_base & right);
+
+        typedef void_vector_base this_type;
+
+    protected:
+
+    typedef size_t size_type;
+        void * m_data;
+        size_type m_size, m_capacity;
+
+    public:
+        void_vector_base()
+            : m_data(0), m_size(0), m_capacity(0)
+        {}
+
+        void_vector_base( size_type size )
+            : m_data(0), m_size(size), m_capacity(size)
+        {
+            if (m_capacity)
+                m_data = ::operator new(m_capacity);
+        }
+    
+        void_vector_base( size_type size , size_t capacity)
+            : m_data(0), m_size(size), m_capacity(capacity)
+        {
+            if (m_capacity)
+                m_data = ::operator new(m_capacity);
+        }
+    
+        void_vector_base( this_type const & rhs )
+            : m_size(rhs.m_size), m_capacity(rhs.m_capacity)
+        {
+            m_data = ::operator new(rhs.m_capacity);
+            VIGRA_CSTD::memcpy( m_data, rhs.m_data, m_size );
+        }
+    
+        ~void_vector_base()
+        {
+            if(m_data)
+                ::operator delete(m_data);
+        }
+    
+        this_type & operator=( this_type const & rhs )
+        {
+            if ( this == &rhs ) return *this;
+            ::operator delete(m_data);
+            m_capacity = rhs.m_capacity;
+            m_size = rhs.m_size;
+            m_data = ::operator new(m_capacity);
+            VIGRA_CSTD::memcpy( m_data, rhs.m_data, m_size );
+            return *this;
+        }
+    
+        void append( this_type const & rhs )
+        {
+            size_type new_size = m_size + rhs.m_size;
+            if ( m_capacity < new_size )
+                reserve( m_capacity + rhs.m_capacity );
+            VIGRA_CSTD::memcpy( static_cast< unsigned char * >
+                         (m_data) + m_size, rhs.m_data, rhs.m_size );
+            m_size = new_size;
+        }
+
+        inline void reserve()
+        {
+            reserve( 2 * m_capacity );
+        }
+
+        void reserve( size_type new_capacity )
+        {
+            if ( new_capacity <= m_capacity ) return;
+            void * new_data = ::operator new(new_capacity);
+            VIGRA_CSTD::memcpy( new_data, m_data, m_size );
+            ::operator delete(m_data);
+            m_data = new_data;
+            m_capacity = new_capacity;
+        }
+
+        inline void resize( size_type new_size )
+        {
+            reserve(new_size);
+            m_size = m_capacity;
+        }
+
+        inline const void * data() const
+        {
+            return m_data;
+        }
+
+        inline void * data()
+        {
+            return m_data;
+        }
+
+        inline size_type size() const
+        {
+            return m_size;
+        }
+    
+        inline size_type capacity() const
+        {
+            return m_capacity;
+        }
+    
+        inline void clear()
+        {
+            m_size = 0;
+        }
+    };
+
+
+    template< class T >
+    class void_vector : public void_vector_base
+    {
+        typedef void_vector<T> this_type;
+
+    public:
+        typedef T value_type;
+        typedef value_type * iterator;
+        typedef value_type const * const_iterator;
+    
+    public:
+        void_vector()
+            : void_vector_base( 0, 20 * sizeof(value_type) )
+        {}
+
+        void_vector( size_type size )
+            : void_vector_base( size * sizeof(value_type) )
+        {}
+
+        this_type & operator=( this_type const & rhs )
+        {
+            void_vector_base::operator=(rhs);
+            return *this;
+        }
+
+        inline const value_type * data() const
+        {
+            return static_cast< const value_type * >
+                ( void_vector_base::data() );
+        }
+
+        inline value_type * data()
+        {
+            return static_cast< value_type * >
+                ( void_vector_base::data() );
+        }
+
+        inline const_iterator begin() const
+        {
+            return data();
+        }
+
+        inline iterator begin()
+        {
+            return data();
+        }
+
+        inline const_iterator end() const
+        {
+            return data() + size();
+        }
+    
+        inline iterator end()
+        {
+            return data() + size();
+        }
+    
+        void push_back( value_type const & t )
+        {
+            if ( size() == capacity() ) reserve();
+            data()[m_size++] = t;
+        }
+    
+        value_type & operator[]( size_type i )
+        {
+            return data()[i];
+        }
+    
+        value_type const & operator[]( size_type i ) const
+        {
+            return data()[i];
+        }
+
+        void reserve()
+        {
+            void_vector_base::reserve();
+        }
+
+        void reserve( size_type new_capacity )
+        {
+            void_vector_base::reserve( sizeof(value_type) * new_capacity );
+        }
+
+        void resize( size_type new_size )
+        {
+            void_vector_base::resize( sizeof(value_type) * new_size );
+        }
+
+        size_type size() const
+        {
+            return m_size / sizeof(value_type);
+        }
+
+        size_type capacity() const
+        {
+            return m_capacity / sizeof(value_type);
+        }
+    };
+
+    void swap_void_vector( void_vector_base & left, void_vector_base & right );
+}
+
+#endif // VIGRA_IMPEX_VOIDVECTOR
diff --git a/src/matlab/RandomForestProgressVisitor.hxx b/src/matlab/RandomForestProgressVisitor.hxx
new file mode 100644
index 0000000..9b91159
--- /dev/null
+++ b/src/matlab/RandomForestProgressVisitor.hxx
@@ -0,0 +1,40 @@
+#ifndef RANDOMFORESTPROGRESSVISITOR_HXX
+#define RANDOMFORESTPROGRESSVISITOR_HXX
+
+
+#include <iostream>
+#include <iomanip>
+
+#include <vigra/random_forest.hxx>
+//#include <vigra/random_forest_hdf5_impex.hxx>
+
+#include <vigra/timing.hxx>
+namespace vigra
+{
+namespace rf
+{
+namespace visitors
+{
+class MatlabRandomForestProgressVisitor : public VisitorBase {
+    public:
+    MatlabRandomForestProgressVisitor() : VisitorBase() {}
+
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(RF& rf, PR & pr,  SM & sm, ST & st, int index){
+        mexPrintf("%d of %d learned\n", index, rf.options().tree_count_); 
+    }
+    
+    template<class RF, class PR>
+    void visit_at_end(RF const & rf, PR const & pr) {
+        mexPrintf("all trees learned\n");
+    }
+    
+    template<class RF, class PR>
+    void visit_at_beginning(RF const & rf, PR const & pr) {
+        mexPrintf("growing random forest, which will have %d trees\n", rf.options().tree_count_);
+    }
+};
+}
+}
+}
+#endif //RANDOMFORESTPROGRESSVISITOR_HXX
diff --git a/src/matlab/buildVigraExtensions.m b/src/matlab/buildVigraExtensions.m
new file mode 100644
index 0000000..061b02c
--- /dev/null
+++ b/src/matlab/buildVigraExtensions.m
@@ -0,0 +1,227 @@
+% buildVigraExtensions(OUTDIR, TARGET, options)
+%
+% Makefile that compiles the VIGRA MEX functions and installs them into the specified 
+% OUTDIR, along with corresponding documentation.
+% Afterward installation, you may call
+%
+%    help vigraIndex
+% 
+% to get a list of the installed functions.
+% 
+% Arguments
+%   - OUTDIR: directory for compiled files (default '.', i.e. this directory)
+%   - TARGET (default: 'all'): 
+%     - 'all':    builds all the files in the folder
+%     - 'test':   see below
+%     - 'clean':  remove all mex compiled files from the folder
+%   - options:    struct('flags', 'additional compile flags') 
+%                 (if needed, see comments in the failing files for help)
+%
+% Special command to compile the unit tests (don't call this directly -- use testVigraExtensions()):
+%    buildVigraExtensions('test-routines', 'test')
+function buildVigraExtensions(OUTDIR, TARGET, options)
+
+if nargin == 0 || isempty(OUTDIR)
+    OUTDIR = '.';
+end
+
+if nargin <= 1 || isempty(TARGET)
+    TARGET = 'all';
+end
+
+if nargin <= 2 || isempty(options)
+    flags = '';
+else
+    flags = options.flags;
+end
+
+if exist('octave_config_info')
+    isOctave = 1;
+else
+    isOctave = 0;
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%          MAKE ALL            %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+if strcmp( TARGET, 'all' )
+    SRCDIR = '.';
+
+    if isdir(OUTDIR) == 0
+         disp([OUTDIR ' does not exist. Creating.']);
+         mkdir(OUTDIR)
+    end
+    
+    if strcmp(OUTDIR, '.') == 0
+        currentPath = pwd;
+        cd(OUTDIR);
+        disp(['Appending ' pwd ' to path']);
+        path(path, pwd);
+        cd(currentPath);
+        copyfile('vigraIndex.m', OUTDIR);
+    end
+end
+
+if strcmp( TARGET, 'test' )
+    SRCDIR = OUTDIR;
+end
+
+if strcmp( TARGET, 'all' ) || strcmp( TARGET, 'test' )
+
+    % by default source files have .cpp extension
+    include_dir = '../../include';
+    cpp_files = dir([SRCDIR '/*.cpp']);
+    for i=1:length( cpp_files )
+        
+        % extract name
+        cpp_file = cpp_files(i);
+        cpp_filename = cpp_file.name;
+        functionName = cpp_filename(1:end-4);
+        
+        % extract the mexfile name that would be generated by "mex ccp_filename"
+        % NOTE: you can also use [pathstr, name, ext, versn] = fileparts(filename) 
+        mex_filename = [OUTDIR '/' functionName '.' mexext ];
+        mex_file     = dir( mex_filename );
+        
+        % file not already compiled OR file compiled is outdated
+        ver = version;
+        if str2double(ver(end- 5:end-2)) < 2008
+            if ~isempty( cpp_file )
+                cpp_file.datenum = datenum(cpp_file.date, 0);
+            end
+            if ~isempty( mex_file )
+                mex_file.datenum = datenum(mex_file.date, 0);
+            end
+        end
+        if isempty( mex_file ) || ( cpp_file.datenum > mex_file.datenum )
+
+            text1 = '';
+            disp(cpp_filename)
+            f = fopen([SRCDIR '/' cpp_filename]);
+            line1 = fgetl(f);
+            while ischar(line1)
+                text1 = sprintf('%s\n%s', text1, line1);
+                line1 = fgetl(f);
+            end
+            fclose(f);
+            if strcmp(flags, '')
+                [match1 comment1] = regexp(text1, '/\*\*\s*ADDITIONAL_BUILD_FLAGS\s*(.*?)\*/', 'match', 'tokens', 'ignorecase');
+                if ~isempty(match1)
+                    lines = regexp(comment1{1}{1}, '^(.*?)$', 'lineanchors', 'match');
+                    flags = lines{1};
+                end
+            end
+            % compile
+            disp(['compiling: ' cpp_filename ] );
+            try
+                if isOctave
+                    disp(['mex -I' include_dir ' ' flags ' -o ' mex_filename ' ' SRCDIR '/' cpp_filename]);
+                    eval(['mex -I' include_dir ' ' flags ' -o ' mex_filename ' ' SRCDIR '/' cpp_filename]);
+                else
+                    disp(['mex -O -I' include_dir ' ' flags ' -outdir ''' OUTDIR ''' ' SRCDIR '/' cpp_filename]);
+                    eval(['mex -O -I' include_dir ' ' flags ' -outdir ''' OUTDIR ''' ' SRCDIR '/' cpp_filename]);
+                end
+            catch ME
+                disp(['Call ''help ' functionName ''' to see possible compiler flags.'])
+                disp(' ')
+            end
+    
+            
+            m_filename = [functionName '.m' ];
+            if strcmp( TARGET, 'all' ) % build documentation from C++ comment
+                text = '';
+                f = fopen(cpp_filename);
+                line = fgetl(f);
+                while ischar(line)
+                    text = sprintf('%s\n%s', text, line);
+                    line = fgetl(f);
+                end
+                fclose(f);
+                [match comment] = regexp(text, '/\*\*\s*MATLAB\s*(.*?)\*/', 'match', 'tokens', 'ignorecase');
+                if isempty(match)  % documentation string not found
+                    disp(['No comment found, cannot create documentation for ' m_filename]);
+                    continue;      % cannot create documentation
+                end
+
+                [match func] = regexp(comment{1}{1}, ['(^\s*function [^\n]*' functionName '[^\n]*)'], 'lineanchors', 'match', 'tokens');
+                if isempty(match)  % 'function' line not found
+                    disp(['No MATLAB function found, cannot create documentation for ' m_filename]);
+                    continue;      % cannot create documentation
+                end
+
+                m_file = func{1}{1};
+                lines = regexp(comment{1}{1}, '[^\n]*\n', 'match');
+                for k=1:length(lines)
+                    line = lines{k};
+                    m_file = sprintf('%s\n%% %s', m_file, line(1:end-1));
+                end
+                m_file = sprintf('%s\n%% \n  %s', m_file, 'error(''mex-file missing. Call buildVigraExtensions(INSTALL_PATH) to create it.'')');
+                disp(['creating: ' m_filename]);
+                fopen([OUTDIR '/' m_filename], 'w');
+                fprintf(f, '%s', m_file);
+                fclose(f);
+            end
+        else
+            continue;
+        end
+    end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%          MAKE CLEAN          %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+elseif strcmp( TARGET, 'clean')
+    % use mexext to determine for which architecture source have been built
+    mex_files = dir( [OUTDIR '/*.' mexext]);
+    
+    % delete those files one by one and notify deletion
+    for i=1:length( mex_files )
+        mex_function = strrep(mex_files(i).name, ['.' mexext], '');
+        clear( mex_function);
+        mex_filename = [OUTDIR '/' mex_files(i).name];
+        disp(['deleting ' mex_filename]);
+        delete( mex_filename );
+        m_filename = strrep(mex_filename, mexext, 'm');
+        if ~isempty(dir( m_filename ) )
+            disp(['deleting ' m_filename]);
+            delete( m_filename ); 
+        end     
+    end
+end
+
+disp('Make done!');
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  Copyright 2003-2008 by Ullrich Koethe    
+%  Based on make.m by Andrea Tagliasacchi
+%                                                                
+% This file is part of the VIGRA computer vision library.        
+% The VIGRA Website is                                           
+%     http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/   
+% Please direct questions, bug reports, and contributions to     
+%     ullrich.koethe at iwr.uni-heidelberg.de    or                 
+%     vigra at informatik.uni-hamburg.de                            
+%                                                                
+% Permission is hereby granted, free of charge, to any person    
+% obtaining a copy of this software and associated documentation 
+% files (the "Software"), to deal in the Software without        
+% restriction, including without limitation the rights to use,   
+% copy, modify, merge, publish, distribute, sublicense, and/or   
+% sell copies of the Software, and to permit persons to whom the 
+% Software is furnished to do so, subject to the following       
+% conditions:                                                    
+%                                                                
+% The above copyright notice and this permission notice shall be 
+% included in all copies or substantial portions of the          
+% Software.                                                      
+%                                                                
+% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND 
+% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND       
+% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    
+% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,   
+% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING   
+% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR  
+% OTHER DEALINGS IN THE SOFTWARE.                                
+% 
+
diff --git a/src/matlab/cellimage.hxx b/src/matlab/cellimage.hxx
new file mode 100644
index 0000000..f959a37
--- /dev/null
+++ b/src/matlab/cellimage.hxx
@@ -0,0 +1,272 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2003-2009 by Hans Meine and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef CELLIMAGE_HXX
+#define CELLIMAGE_HXX
+
+#include <vigra/basicimage.hxx>
+#include <vigra/pixelneighborhood.hxx>
+#include <functional>
+
+namespace vigra {
+
+namespace cellimage {
+
+enum CellType { CellTypeRegion = 0,
+                CellTypeLine = 1,
+                CellTypeVertex = 2,
+                CellTypeError = 3,
+                CellTypeVertexOrLine = 4,
+                CellTypeErrorOrLine = 5 };
+
+// -------------------------------------------------------------------
+//                          CellPixel, CellImage
+// -------------------------------------------------------------------
+typedef unsigned int CellLabel;
+
+struct CellPixel
+{
+private:
+    CellLabel typeLabel_;
+
+    friend struct CellPixelSerializer;
+
+public:
+    CellPixel() {}
+    CellPixel(CellType type, CellLabel label = 0)
+    : typeLabel_((label << 2) | type)
+    {}
+
+    inline CellType type() const
+        { return (CellType)(typeLabel_ & 3); }
+    inline void setType(CellType type)
+        { typeLabel_ = (label() << 2) | type; }
+    inline void setType(CellType type, CellLabel label)
+        { typeLabel_ = label << 2 | type; }
+
+    inline CellLabel label() const
+        { return typeLabel_ >> 2; }
+    inline void setLabel(CellLabel label)
+        { typeLabel_ = label << 2 | type(); }
+    inline void setLabel(CellLabel label, CellType type)
+        { typeLabel_ = label << 2 | type; }
+
+    bool operator==(CellPixel const & rhs) const
+        { return typeLabel_ == rhs.typeLabel_; }
+
+    bool operator!=(CellPixel const & rhs) const
+        { return typeLabel_ != rhs.typeLabel_; }
+};
+
+typedef BasicImage<CellPixel> CellImage;
+
+typedef vigra::NeighborhoodCirculator<CellImage::Iterator, EightNeighborCode>
+    CellImageEightCirculator;
+
+// -------------------------------------------------------------------
+//                     CellPixel Serialization
+// -------------------------------------------------------------------
+struct CellPixelSerializer
+{
+    int operator()(CellPixel const &p) const
+    {
+        return p.typeLabel_;
+    }
+
+    CellPixel operator()(int i) const
+    {
+        CellPixel result;
+        result.typeLabel_ = i;
+        return result;
+    }
+};
+
+// -------------------------------------------------------------------
+//                   CellPixel/CellImage Accessors
+// -------------------------------------------------------------------
+template<class VALUE_TYPE = CellType>
+struct TypeAccessor
+{
+    typedef VALUE_TYPE value_type;
+    typedef VALUE_TYPE result_type;
+
+    template<class Iterator>
+    value_type operator()(const Iterator &it) const
+    {
+        return it->type();
+    }
+
+    template<class Iterator>
+    void set(value_type type, const Iterator &it) const
+    {
+        it->setType(type);
+    }
+};
+
+typedef TypeAccessor<unsigned char> TypeAsByteAccessor;
+
+typedef TypeAccessor<> CellTypeAccessor;
+
+struct LabelAccessor
+{
+    typedef CellLabel value_type;
+
+    template<class Iterator>
+    CellLabel operator()(const Iterator &it) const
+    {
+        return it->label();
+    }
+
+    template<class Iterator>
+    void set(CellLabel label, const Iterator &it) const
+    {
+        it->setLabel(label);
+    }
+};
+
+template<CellType type>
+struct LabelWriter
+{
+    typedef CellLabel value_type;
+
+    template<class Iterator>
+    void set(CellLabel label, const Iterator &it) const
+    {
+        it->setLabel(label, type);
+    }
+};
+
+template<CellType type>
+struct CellTypeEquals : public std::unary_function<CellType, bool>
+{
+    bool operator()(CellType t) const
+    {
+        return t == type;
+    }
+
+    template<class Iterator>
+    bool operator()(const Iterator &it) const
+    {
+        return it->type() == type;
+    }
+};
+
+struct CellMask : public std::unary_function<vigra::cellimage::CellPixel, bool>
+{
+    vigra::cellimage::CellPixel maskPixel_;
+
+    CellMask(vigra::cellimage::CellPixel maskPixel)
+    : maskPixel_(maskPixel)
+    {}
+
+    template<class Iterator>
+    bool operator()(const Iterator &it) const
+    {
+        return *it == maskPixel_;
+    }
+};
+
+// -------------------------------------------------------------------
+//                        RelabelFunctor (unused!)
+// -------------------------------------------------------------------
+template<class VALUETYPE>
+struct RelabelFunctor
+{
+    typedef VALUETYPE value_type;
+    typedef VALUETYPE argument_type;
+    typedef VALUETYPE result_type;
+
+    RelabelFunctor(VALUETYPE oldValue, VALUETYPE newValue)
+        : oldValue_(oldValue),
+          newValue_(newValue)
+    {}
+
+    VALUETYPE operator()(VALUETYPE value) const
+    {
+        return (value == oldValue_) ? newValue_ : value;
+    }
+
+    VALUETYPE oldValue_, newValue_;
+};
+
+// -------------------------------------------------------------------
+//                              inspectCell
+// -------------------------------------------------------------------
+// thinking about "typename IteratorTraits<EndIterator>::DefaultAccessor":
+// is not needed since we're not implementing srcCellRange here, but
+// algorithms.
+// srcCellRange can not be implemented that easy, because most VIGRA
+// functions expect an ImageIterator, not a std::iterator
+template <class EndIterator, class Accessor, class Functor>
+void inspectCell(EndIterator endIterator, Accessor a, Functor & f)
+{
+    for(; endIterator.inRange(); ++endIterator)
+        f(a(endIterator));
+}
+
+template <class EndIterator, class Functor>
+void inspectCell(EndIterator endIterator, Functor & f)
+{
+    for(; endIterator.inRange(); ++endIterator)
+        f(*endIterator);
+}
+
+// -------------------------------------------------------------------
+//                             transformCell
+// -------------------------------------------------------------------
+template <class SrcEndIterator, class SrcAccessor,
+          class DestEndIterator, class DestAccessor, class Functor>
+void transformCell(SrcEndIterator srcEndIterator, SrcAccessor sa,
+                   DestEndIterator destEndIterator, DestAccessor da,
+                   Functor const & f)
+{
+    for(; srcEndIterator.inRange(); ++srcEndIterator, ++destEndIterator)
+        da.set(f(sa(srcEndIterator)), destEndIterator);
+}
+
+template <class SrcEndIterator, class DestEndIterator, class Functor>
+void transformCell(SrcEndIterator srcEndIterator,
+                   DestEndIterator destEndIterator,
+                   Functor const & f)
+{
+    for(; srcEndIterator.inRange(); ++srcEndIterator, ++destEndIterator)
+        *destEndIterator = f(*srcEndIterator);
+}
+
+} // namespace cellimage
+
+} // namespace vigra
+
+#endif // CELLIMAGE_HXX
diff --git a/src/matlab/doc/tutorial_reference.pdf b/src/matlab/doc/tutorial_reference.pdf
new file mode 100644
index 0000000..91a6a9b
Binary files /dev/null and b/src/matlab/doc/tutorial_reference.pdf differ
diff --git a/src/matlab/doc/tutorial_reference.tex b/src/matlab/doc/tutorial_reference.tex
new file mode 100644
index 0000000..62e0d6e
--- /dev/null
+++ b/src/matlab/doc/tutorial_reference.tex
@@ -0,0 +1,366 @@
+\documentclass[a4paper,10pt]{article}
+
+\usepackage[margin=4cm]{geometry}
+\usepackage{color}
+\usepackage{listings}
+\definecolor{darkgreen}{rgb}{0,0.5,0}
+\lstset{language=C++,
+	basicstyle=\scriptsize\sffamily,
+	tabsize=4,
+        keywordstyle=\color{blue}\bfseries,
+        identifierstyle=\color{black}, 
+	commentstyle =\color{darkgreen},
+        showstringspaces=false,
+        numbers=left,
+	frame=left}
+
+% Title Page
+\title{How to use the C++ Interface to Matlab}
+\author{Rahul Nair}
+
+
+\begin{document}
+\maketitle
+
+
+
+\section{Before we start (Things worth knowing)}
+Matlab always employs Copy on demand. In assignments of the for a = b as well as when arguments are passed to functions.Only references or pointers are passed. Only if subsequently the assigned array is changed, matlab will copy the data.
+
+This also applies to mex functions. Matlab does not copy the data but only provides pointers to the memory, where the data is managed. Note that copy on demand is not enforced while using mexFunctions. So it is (as of version 2008) quite possible to manipulate data passed as function parameters in place. (Though most probably not really recommended, as this is not default matlab behaviour)
+
+
+To avoid copying large amount of data while using the C++ Interface, but still having the comfort of using Classes and Objects, VIGRA provides View classes. These are basically enhanced pointers to external memory providing methods that work on it.
+
+It would be advisible to have a look at the functions already written as much of the following will most probably be
+easier to understand.
+
+\section{The Gateway function}
+The mexFunction(...) gateway is replaced by the vigraMexFunction(...) gateway. The mexFunction still exists - but is in matlab.hxx. It only creates the InputArray and OutputArray objects and subsequently calls vigraMexFunction(...)
+
+\textbf{Note:} if for some reason you do not want to use a custom mexFunction it is possible to override default behavior by \verb+#define+ CUSTOM\_MEX\_FUNCTION before \verb+#include+ matlab.hxx
+
+The two main classes needed for using the interface are vigra::matlab::InputArray and vigra::matlab::OutputArray.
+These two classes take the plhs prhs and nlhs nrhs parameters of the classical mexFunction and provide methods that simplify access of data.
+
+The job of the vigraMexFunction is to call the right template-instance of the \verb+vigraMain<>(..)+ function. 
+Typechecking of the inputs etc should be done here.
+
+
+	
+	Note: vigra contains typedefs of kind UInt8 ... UInt64, Int8 ... Int64
+\begin{lstlisting}[caption={The first parameter of the Function can be of type double or of type UInt8  }]
+void vigraMexFunction(	vigra::matlab::OutputArray outputs, 
+                        vigra::matlab::InputArray inputs)
+{
+	switch(inputs.typeOf(0)) 
+	//switch on the type of the first parameter
+	//calls mxClassID to get the a number corresponding to the type
+	{
+	case mxUINT8_CLASS:
+		vigraMain<UInt8>(outputs, inputs);     break;
+	case mxDOUBLE_CLASS:
+		vigraMain<double>(outputs, inputs);     break;
+	default:
+		mexErrMsgTxt("Type of input at position 0 not supported");
+	}
+}
+\end{lstlisting}
+\begin{lstlisting}[caption={Using Macros - This only works if vigraMain takes only one template parameter.}]
+void vigraMexFunction(vigra::matlab::OutputArray outputs, 
+                      vigra::matlab::InputArray inputs)
+{
+	switch(inputs.typeOf("someOption")) 
+	//switch on the type of the field "someOption" of the options 
+	//struct.
+	//calls mxClassID to get the a number corresponding to the type
+	{
+		ALLOW_UINT_16_64	//switch cases for int16 to int64
+		ALLOW_INT_8_32		//switch cases for int8 to int32
+		ALLOW_FD		//allow float and double
+		default:
+			mexErrMsgTxt("Type of input at position 0 not supported");
+	}
+}
+\end{lstlisting}
+
+\section{The vigraMain function}
+The \verb+vigraMain(...)+ function contains the C++ code that actually has to be 
+run. First the View objects should look at the right data. Also space should 
+be allocated for the output arrays.
+
+\begin{lstlisting}[caption={Examples}]
+1.
+/*Make a View of Type T (the template type of vigraMain) and let it look at the 
+first parameter supplied. v_required() indicates that an mexErrMsgTxt() is thrown 
+if no argument is supplied at position 0 (or an empty array)*/
+BasicImageView<T>   in      =   inputs.getImage<T>(0, v_required());
+
+2.
+/*Second Argument is Scalar and copied into "scale" v_default(1.0) indicates that 
+if no argument is supplied the default value 1.0 is used. the last two arguments 
+are the range constraints on scale a mexErrMsgTxt is thrown if the value is out 
+of bounds*/
+double scale   =   inputs.getScalarMinMax<double>(1, v_default(1.0), 0.0, "inf");
+
+3.
+//Create an Image of type double at output position 0 with the size of in
+BasicImageView<double> out  =   
+	outputs.createImage<double>(0, v_required(), in.width(), in.height());
+
+4.
+/*Same thing as 2. without constraints. v_optional() indicates that this variable 
+does not have a default value. v_optional(bool check) sets check to true if the 
+variable has been set, false otherwise.*/
+bool	hasBackground;
+T	backgroundValue = 
+		inputs.getScalar<T>("backgroundValue", v_optional(hasBackground));	
+
+5.
+/*creates a scalar at the secon output if second output has been asked for 
+(v_optional()) and copies max_region_label into it*/
+outputs.createScalar<int> (1, v_optional(), max_region_label);
+\end{lstlisting}
+
+After space is allocated and the Views point to the right memory - the actual code can be executed.
+
+\section{matlab::InputArray and matlab::OutputArray}
+These are wrapper classes for plhs nlhs, prhs nrhs respectively. \textbf{InputArray checks 
+whether the last mxArray* in prhs is a matlab struct array} - If yes it is an
+options struct and loaded. What followes is a listing of public methods and attributes
+
+\textbf{Place posOrName} denotes an object of type std::string or an int. If it is std::string
+the options struct is searched for a field with name posOrNum. if it is an then 
+the argument at the given position is used. 
+
+\textbf{ReqType} is one of the objects described in the next section.
+
+\textbf{Note:} If you are not using matlab::InputArray or matlab::OutputArray, still you may use
+the non-member get and create functions  which take a mxArray* as first parameter. 
+Note that these functions do not check for constraints or whether the mxArray* is pointing to any
+memory. Look into matlab.hxx for further details.
+
+\begin{lstlisting}[caption={matlab::InputArray}]
+	matlab::ConstStructArray options_ 
+		/*The options Struct. See Documentation of ConstStructArray for more 
+		information.*/
+	mxArray* & operator[](Place posOrName)
+		/*Access reference to the mxArray* at certain place.*/
+	size_type size()
+		/*returns nrhs*/
+	bool isValid(Place posOrName)
+		/*returns true if a Argument was supplied at place posOrNum.*/
+	bool isEmpty(Place posOrName)
+		/*return true if Array at place posOrNum is empty.*/
+	mxClassID typeOf(place posOrName)
+		/*return type of mxArray* at place posOrNum;*/
+
+    template <class Place, class ReqType>
+    int getEnum(Place posOrName, ReqType req, std::map<std::string, int> const & converter)
+		/*get String and convert into Enumerationtype
+		 See Note after the listing for usage*/
+
+	template <class T,class place, class ReqType>
+	T getString(place posOrName, ReqType req)
+		/*get String at place posOrName. */
+
+
+	template <class T,class place, class ReqType>
+	T getScalar(place posOrName, ReqType req)
+		/*get Scalar value at place posOrName. */
+    
+	template<class T, class place, class reqClass, 
+                                       class minClass, class maxClass>
+	T getScalarMinMax(place posOrName, reqClass req, 
+                                           minClass min_, maxClass max_)
+		/*get Scalar value constrained by range defined by min_ and max_
+		min_ and max_ can also be "inf"*/
+	
+	template <class T, class place, class reqClass, class iteratorType>
+	T getScalarVals(place posOrName, reqClass req, 
+                                         iteratorType begin_, iteratorType end_)
+		/*get Scalar value constrained by the values in the iterator range 
+		given by begin_ and end_*/
+
+	template <class T, class place, class reqClass, class iteratorType>
+	T getScalarVals2D3D(place posOrName, reqClass req, 
+                                       iteratorType begin2D_, iteratorType end2D_,
+		                       iteratorType begin3D_, iteratorType end3D_,
+		                                                        int dimVar)
+		/*get Scalar value constrained by range begin2D_, end2D_ in cas dimVar 
+		is 2 else constrained by range begin3D_, end3D_*/
+
+	template <class place, class reqClass>
+	bool getBool(place posOrName, reqClass req)
+		/*get logical value.*/
+
+
+	template <unsigned int N, class T, class place, class reqClass>
+	MultiArrayView<N,T> getMultiArray(place posOrName, reqClass req)
+		/*get MultiArrayView with dim N and Type T*/
+	
+	template < class T, class place, class reqClass>
+	BasicImageView<T> getImage(place posOrName, reqClass req)
+		/*get BasicImageView with Type T*/
+
+	template<class T,unsigned int sze, class place, class reqClass>
+	TinyVectorView< T, sze> getTinyVector(place posOrName, reqClass req)
+		/*get TinyVectorView of Type T and size sze*/
+
+	template< unsigned int sze, class place, class reqClass>
+	TinyVectorView<MultiArrayIndex, sze> getShape(place posOrName, reqClass req)
+		/*get MutliarrayShape size sze*/
+
+	template< class place, class reqClass>
+	int getDimOfInput(place posOrName, reqClass req)
+		/*get Dimension of Input at place posOrName*/
+
+	template<class place, class reqClass>
+	ConstCellArray getCellArray(int pos, reqClass req)
+		/*get a Object of type ConstCellArray
+		  NOTE: CellArray may not be in the struct!!!*/
+\end{lstlisting}
+
+\subsection{Using the getEnum method}
+\begin{lstlisting}
+VIGRA_CREATE_ENUM_AND_STD_MAP4(MapName, Corner, Foerstner, Rohr, Beaudet);
+int  method  =   inputs.getEnum(2,  v_default(Corner), MapName);
+\end{lstlisting}
+The first command is a macro. const int variables with names.
+Corner, Foerstner, Rohr and Beaudet. Also it creates a std::map MapName that maps the 
+corresponding strings to the constants
+the method variable is then initialized with the getEnum method. 
+
+
+
+\begin{lstlisting}[caption={matlab::OutputArray}]
+	mxArray* & operator[](int pos)
+		Access reference to the mxArray* at certain place.
+	size_type size()
+		returns nlhs
+	bool isValid(int pos)
+		returns true if a Output was required at position pos.
+	bool isEmpty(int pos)
+		return true if Array at place posOrNum is empty.	
+
+	template <unsigned int DIM, class T, class ReqType>
+	MultiArrayView<DIM, T> createMultiArray(int pos,ReqType req,
+                                            const TinyVector<int, DIM>  & shape)
+		/*create MultiArrayView of dimension Dim and type T and allocate 
+		enough space for shape*/
+
+	template <class T, class ReqType>
+	BasicImageView<T> createImage(int pos, ReqType req,
+                                    mwSize width, mwSize height)
+
+	template <class T, class ReqType>
+	BasicImageView<T> createImage(  int pos, ReqType req,
+                                  typename MultiArrayShape<2>::type const & shape)
+
+	template <class T, class ReqType>
+	T* createScalar(int pos, ReqType req)
+		/*allocate memory for a scalar and return pointer to it.*/
+
+	template <class T, class ReqType>
+	void createScalar(int pos, ReqType req, T val)
+		/*allocate memory for a scalar and copy val into it.*/
+
+	template <class ReqType>
+	ConstCellArray createCellArray(int pos, ReqType req, mwSize sze)
+\end{lstlisting}
+
+\section{The Required/Optional/Default objects}
+The createType and getType functions always take an object of type Required, 
+\verb+DefaultImpl<T>+,  \verb+DefaultImplVoid+ or \verb+bool+ as second argument 
+Use the factory methods \verb+v_required()+, \verb+v_default()+ and 
+\verb+v_optional+ to create these objects:
+
+\begin{lstlisting}[caption={Behavior of the get/set functions with the factory objects}]
+	v_required(void)
+		/*generates an error message if the argument was not supplied.*/
+	v_optional()
+		/*does nothing. If argument was not supplied default 
+		constructor is called.*/
+	v_optional(bool flag)
+		/*same as above. Only that flag is set if argument was supplied. 
+		flag is false otherwise.*/
+	
+	/*Additionally when in use with the get method:*/
+	
+	v_default(defaultVal)
+		/*returns defaultVal if no argument supplied.*/
+	v_default(defaultVal2D, defaultVal3D, dimSwitch)
+		/*if dimSwitch == 2 use defaultVal2D else use defaultVal3D*/
+\end{lstlisting}
+
+\textbf{Note:} 	If you need to know whether an Object was set even if you used \\*\verb+v_default(defaultval)+
+	Explicitly create the \verb+DefaultImpl<T>+ object (Only if using the first method):
+
+\begin{lstlisting}[caption={Finding out whether a default object was set}]	
+//create a default MultiArray
+MultiArray<3, T> in(SomeShape);
+//Create defaultImpl object
+DefaultImpl<typename MultiArrayView<3,T> > 
+				defaultMultiArrayView(MultiArrayView<3,T>(in));
+MultiArrayView<3,T> Arg = 
+		 inputs.getMultiArray<3,T>(0,v_default(defaultMultiArrayView));
+
+//first way of checking whether Argument  was supplied:
+if(defaultMultiArrayView.garbage == true) 
+	std::cout << "it has been set";
+
+/*second way of checking whether Argument was supplied- only works with the 
+View classes, not with scalars:*/
+if(in.data() == Arg.data()) 
+	std::cout << "it has not been set";
+\end{lstlisting}
+\section{Build and Test scripts}
+Use \verb+buildVigraExtensions+ and \verb+testVigraExtensions+ to build all mex files and to test the 
+matlab.hxx interface.
+
+\textbf{Note:} The test script calls buildVigraExtensions to create the test mex files located
+in the test subdirectory
+
+\section{other classes}
+The ConstStructArray object is used to store the options.
+It should not be necessary to manipulate the ConstStructArray directly.
+\begin{lstlisting}[caption = {ConstStructArray (Options)}
+	ConstStructArray(mxArray* matPointer)
+		/*Constructor.*/
+	operator[](std::string fieldName)
+		/*access mxArray* which is stored in the StructArray with 
+		fieldName.*/
+	isValid()
+		/*is true if ConstStructArray points to a valid matPointer*/
+	isValid(std::string)
+		/*true if field with name specified in string exists*/
+\end{lstlisting}
+
+
+	This is just some experimental code but quite handy if you have make 
+	and handle sparse arrays. Basically just a wrapper class to a stl::map;
+\begin{lstlisting}[caption = {Sparse array}]
+    template<class T>
+    class SparseArray
+    private:
+        std::map<TinyVector<int,2>, T,ShapeCmp> data;
+        int width, length;
+    public:
+        SparseArray(int i = 1 , int j = 1)
+	    //calls assign;
+        void assign(int i = 1, int j = 1)
+	    /*set intrinsic size of the SparseArray - only needed when using map
+	    To MxArray.*/
+
+    	T& operator()(int i, int j){
+    	const T get(int i, int j){
+	    //get and set element;
+	    //Any better idea? i would like to unify the get and operator() 
+	    //functions.
+	    // Problem is that  operator() always passes a reference or creates 
+	    //one.
+
+	void mapToMxArray(mxArray * & in)
+	    //Creates a sparse mxArray and copies data into it.
+\end{lstlisting}
+\end{document}          
diff --git a/src/matlab/random_forest_impex.hxx b/src/matlab/random_forest_impex.hxx
new file mode 100644
index 0000000..f72c1cc
--- /dev/null
+++ b/src/matlab/random_forest_impex.hxx
@@ -0,0 +1,113 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 2008 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+#ifndef VIGRA_RANDOM_FOREST_IMPEX_HXX
+#define VIGRA_RANDOM_FOREST_IMPEX_HXX
+
+#include <set>
+#include <memory>
+#include <vigra/matlab.hxx>
+#include <vigra/random_forest.hxx>
+
+namespace vigra {
+namespace matlab {
+
+template<class T>
+void importRandomForest(vigra::RandomForest<T> &rf,ConstCellArray cells)
+{
+    // read RF parameters
+    MultiArrayView<1, UInt32> e_param = getArray<UInt32>(cells[0]);
+    rf.ext_param_.unserialize(e_param.data(), e_param.data()+ e_param.size());
+
+    MultiArrayView<1, UInt32> opt = getArray<UInt32>(cells[1]);
+    rf.options_.unserialize(opt.data(), opt.data()+ opt.size());
+
+
+    rf.trees_.resize(rf.options_.tree_count_, rf.ext_param_);
+    // for all decision trees
+    for(UInt32 k=0; k<rf.options_.tree_count_; ++k)
+    {
+        
+        // read int tree array
+        MultiArrayView<1, Int32> tree = getArray<Int32>(cells[2*k+2]);
+        rf.tree(k).topology_.resize(tree.size());
+        std::copy(tree.traverser_begin(), tree.traverser_end(),
+                  rf.tree(k).topology_.begin());
+
+        
+        MultiArrayView<1, double> weight = getArray<double>(cells[2*k+3]);
+        rf.tree(k).parameters_.resize(weight.size());
+        std::copy(weight.traverser_begin(), weight.traverser_end(),
+                  rf.tree(k).parameters_.begin());
+    }
+}
+
+template <class T>
+void
+exportRandomForest(RandomForest<T> const & rf, CellArray cells)
+{
+    // write RF parameters
+    int parameterCount = rf.ext_param_.serialized_size();
+    MultiArrayView<1, UInt32> parameters = createArray<UInt32>(parameterCount, cells[0]);
+    rf.ext_param_.serialize(parameters.data(), parameters.data()+parameterCount);
+
+
+    int optCount = rf.options_.serialized_size();
+    MultiArrayView<1, UInt32> opt = createArray<UInt32>(optCount, cells[1]);
+    rf.options_.serialize(opt.data(), opt.data() + optCount);
+
+    // for all decision trees
+    for(int k=0; k<rf.options_.tree_count_; ++k)
+    {
+        // write int topology array
+        MultiArrayView<1, Int32> tree =
+            createArray<Int32>(rf.tree(k).topology_.size(), cells[2*k+2]);
+        std::copy(rf.tree(k).topology_.begin(),
+                  rf.tree(k).topology_.end(),
+                  tree.data());
+
+        // write double parameters array
+        MultiArrayView<1, double> weights =
+            createArray<double>(rf.tree(k).parameters_.size(), cells[2*k+3]);
+        std::copy(rf.tree(k).parameters_.begin(),
+                  rf.tree(k).parameters_.end(),
+                  weights.data());
+    }
+}
+
+}} // namespace vigra::matlab
+
+#endif // VIGRA_RANDOM_FOREST_IMPEX_HXX
diff --git a/src/matlab/test-routines/vigraTestConstrScalar.cpp b/src/matlab/test-routines/vigraTestConstrScalar.cpp
new file mode 100644
index 0000000..312b0e0
--- /dev/null
+++ b/src/matlab/test-routines/vigraTestConstrScalar.cpp
@@ -0,0 +1,78 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/***************************************************************************************************
+**         INCLUDES AND DEFS                                                                      **
+****************************************************************************************************/
+
+#include <vigra/matlab.hxx>
+using namespace vigra;
+using namespace matlab;
+
+
+
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+
+    bool        Bool        =   inputs.getBool(0, v_required());
+    double      MinMaxS     =   inputs.getScalarMinMax<double>(1, v_required(), 2.0, 3.0);
+    double      vals1[]     =   {2, 4};
+    double      vals2[]     =   {3, 5};
+    double      ValsC       =   inputs.getScalarVals<double>(2, v_required(), vals1, vals1+2);
+    double      Vals2D3DC   =   inputs.getScalarVals2D3D<double>(3, v_required(), vals2, vals2 +2,
+                                                                                vals1, vals1 +2, MinMaxS);
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+
+
+
+}
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    vigraMain(outputs, inputs);
+}
+/** MATLAB
+NODOC
+
+*/
+
diff --git a/src/matlab/test-routines/vigraTestCopy.cpp b/src/matlab/test-routines/vigraTestCopy.cpp
new file mode 100644
index 0000000..2fd58c5
--- /dev/null
+++ b/src/matlab/test-routines/vigraTestCopy.cpp
@@ -0,0 +1,100 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/***************************************************************************************************
+**         INCLUDES AND DEFS                                                                      **
+****************************************************************************************************/
+
+#include <vigra/matlab.hxx>
+#include <vigra/copyimage.hxx>
+#include <vigra/multi_pointoperators.hxx>
+#include <iostream>
+using namespace vigra;
+using namespace matlab;
+
+
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+
+    MultiArrayView<3, T>        Vol         =   inputs.getMultiArray<3, T>(0, v_required());
+    BasicImageView<T>           Img         =   inputs.getImage<T>(1, v_required());
+    TinyVectorView<T, 2>        TinyVec     =   inputs.getTinyVector<T, 2>(2, v_required());
+    T                           Scalar      =   inputs.getScalar<T>(3, v_required());
+    ConstCellArray              Cell        =   inputs.getCellArray(4, v_required());
+
+    MultiArrayView<3,T>         outVol      =   outputs.createMultiArray<3, T>(0, v_required(), Vol.shape());
+    BasicImageView<T>           outImg      =   outputs.createImage<T>(1, v_required(), Img.width(), Img.height());
+    MultiArrayShape<2>::type    newShape3 (2, 1);
+    MultiArrayView<2, T>        outTiny     =   outputs.createMultiArray<2, T>(2, v_required(), newShape3);
+    T*                          outScal     =   outputs.createScalar<T>(3, v_required());
+    ConstCellArray              OutCell     =   outputs.createCellArray(5, v_required(), Cell.size()+1);
+
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+    vigra::copyMultiArray(srcMultiArrayRange(Vol), destMultiArray(outVol));
+    outVol(0,0,0) = outVol(0,0,0)+1;
+    vigra::copyImage(srcImageRange(Img), destImage(outImg));
+    outImg(0,0) = outImg(0,0)+1;
+    outTiny(0,0) = TinyVec[0] +1;
+    outTiny(1,0) = TinyVec[1];
+    outputs.createScalar<T>(4, v_required(), 42);
+    *outScal = Scalar+1;
+
+
+}
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+   switch(inputs.typeOf(0))
+   {
+       ALLOW_FD;
+       ALLOW_INT;
+       ALLOW_UINT;
+       default:
+            mexErrMsgTxt("Invalid Type");
+   }
+}
+/** MATLAB
+NODOC
+vigraBjoernsFunc1903(ProbMap, Thres);
+*/
diff --git a/src/matlab/test-routines/vigraTestCopyMixed.cpp b/src/matlab/test-routines/vigraTestCopyMixed.cpp
new file mode 100644
index 0000000..735193a
--- /dev/null
+++ b/src/matlab/test-routines/vigraTestCopyMixed.cpp
@@ -0,0 +1,97 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/***************************************************************************************************
+**         INCLUDES AND DEFS                                                                      **
+****************************************************************************************************/
+
+#include <vigra/matlab.hxx>
+#include <vigra/copyimage.hxx>
+#include <vigra/multi_pointoperators.hxx>
+using namespace vigra;
+using namespace matlab;
+
+
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    MultiArrayView<3, T>        Vol         =   inputs.getMultiArray<3, T>(0, v_required());
+    BasicImageView<T>           Img         =   inputs.getImage<T>(1, v_required());
+    TinyVectorView<T, 2>        TinyVec     =   inputs.getTinyVector<T, 2>("field2", v_required());
+    T                           Scalar      =   inputs.getScalar<T>("field3", v_required());
+    //ConstCellArray              Cell        =   inputs.getCellArray("field4", v_required());
+
+    MultiArrayView<3,T>         outVol      =   outputs.createMultiArray<3, T>(0, v_required(), Vol.shape());
+    BasicImageView<T>           outImg      =   outputs.createImage<T>(1, v_required(), Img.width(), Img.height());
+    MultiArrayShape<2>::type    newShape3 (2, 1);
+    MultiArrayView<2, T>        outTiny     =   outputs.createMultiArray<2, T>(2, v_required(), newShape3);
+    T*                          outScal     =   outputs.createScalar<T>(3, v_required());
+    //ConstCellArray              OutCell     =   outputs.createCellArray(5, v_required(), Cell.size()+1);
+
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+    vigra::copyMultiArray(srcMultiArrayRange(Vol), destMultiArray(outVol));
+    outVol(0,0,0) = outVol(0,0,0)+1;
+    vigra::copyImage(srcImageRange(Img), destImage(outImg));
+    outImg(0,0) = outImg(0,0)+1;
+    outTiny(0,0) = TinyVec[0]+1;
+    outTiny(1,0) = TinyVec[1];
+    outputs.createScalar<T>(4, v_required(), 42);
+    *outScal = Scalar+1;
+
+}
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+   switch(inputs.typeOf(0))
+   {
+       ALLOW_FD;
+       ALLOW_INT;
+       ALLOW_UINT;
+       default:
+            mexErrMsgTxt("Invalid Type");
+   }
+}
+/** MATLAB
+NODOC
+vigraBjoernsFunc1903(ProbMap, Thres);
+*/
diff --git a/src/matlab/test-routines/vigraTestCopyOpt.cpp b/src/matlab/test-routines/vigraTestCopyOpt.cpp
new file mode 100644
index 0000000..bd20ff4
--- /dev/null
+++ b/src/matlab/test-routines/vigraTestCopyOpt.cpp
@@ -0,0 +1,97 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/***************************************************************************************************
+**         INCLUDES AND DEFS                                                                      **
+****************************************************************************************************/
+
+#include <vigra/matlab.hxx>
+#include <vigra/copyimage.hxx>
+#include <vigra/multi_pointoperators.hxx>
+using namespace vigra;
+using namespace matlab;
+
+
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    MultiArrayView<3, T>        Vol         =   inputs.getMultiArray<3, T>("field0", v_required());
+    BasicImageView<T>           Img         =   inputs.getImage<T>("field1", v_required());
+    TinyVectorView<T, 2>        TinyVec     =   inputs.getTinyVector<T, 2>("field2", v_required());
+    T                           Scalar      =   inputs.getScalar<T>("field3", v_required());
+    //ConstCellArray              Cell        =   inputs.getCellArray("field4", v_required());
+
+    MultiArrayView<3,T>         outVol      =   outputs.createMultiArray<3, T>(0, v_required(), Vol.shape());
+    BasicImageView<T>           outImg      =   outputs.createImage<T>(1, v_required(), Img.width(), Img.height());
+    MultiArrayShape<2>::type    newShape3 (2, 1);
+    MultiArrayView<2, T>        outTiny     =   outputs.createMultiArray<2, T>(2, v_required(), newShape3);
+    T*                          outScal     =   outputs.createScalar<T>(3, v_required());
+    //ConstCellArray              OutCell     =   outputs.createCellArray(5, v_required(), Cell.size()+1);
+
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+    vigra::copyMultiArray(srcMultiArrayRange(Vol), destMultiArray(outVol));
+    outVol(0,0,0) = outVol(0,0,0)+1;
+    vigra::copyImage(srcImageRange(Img), destImage(outImg));
+    outImg(0,0) = outImg(0,0)+1;
+    outTiny(0,0) = TinyVec[0]+1;
+    outTiny(1,0) = TinyVec[1];
+    outputs.createScalar<T>(4, v_required(), 42);
+    *outScal = Scalar+1;
+
+}
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+   switch(inputs.typeOf("field0"))
+   {
+       ALLOW_FD;
+       ALLOW_INT;
+       ALLOW_UINT;
+       default:
+            mexErrMsgTxt("Invalid Type");
+   }
+}
+/** MATLAB
+NODOC
+vigraBjoernsFunc1903(ProbMap, Thres);
+*/
diff --git a/src/matlab/test-routines/vigraTestDefault.cpp b/src/matlab/test-routines/vigraTestDefault.cpp
new file mode 100644
index 0000000..9e35305
--- /dev/null
+++ b/src/matlab/test-routines/vigraTestDefault.cpp
@@ -0,0 +1,83 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/***************************************************************************************************
+**         INCLUDES AND DEFS                                                                      **
+****************************************************************************************************/
+
+#include <vigra/matlab.hxx>
+#include <vigra/multi_pointoperators.hxx>
+
+using namespace vigra;
+using namespace matlab;
+
+
+
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    MultiArrayShape<2>::type    newShape3 (3, 3);
+    MultiArray<2,double> defMultArray(newShape3);
+    MultiArrayView<2,double>         in3D   = inputs.getMultiArray<2,double>(2, v_default(MultiArrayView<2, double>(defMultArray)));
+    
+    bool dimWasGiven;
+    double                   aga            = inputs.getScalar<double>(0, v_default(2, dimWasGiven));
+    double                   sgs            = inputs.getScalar<double>(1, aga == 2 ? v_default(2) : v_default(3));
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+
+    MultiArrayView<2,double>   out3D       = outputs.createMultiArray<2,double>(2, v_required(), in3D.shape());
+    vigra::copyMultiArray(srcMultiArrayRange(in3D), destMultiArray(out3D));
+
+    outputs.createScalar<double>(0, v_required(), aga);
+    outputs.createScalar<double>(1, v_required(), sgs);
+    outputs.createScalar<int>(3, v_required(), dimWasGiven);
+}
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    vigraMain(outputs, inputs);
+}
+/** MATLAB
+NODOC
+
+*/
+
diff --git a/src/matlab/test-routines/vigraTestEnum.cpp b/src/matlab/test-routines/vigraTestEnum.cpp
new file mode 100644
index 0000000..38f306d
--- /dev/null
+++ b/src/matlab/test-routines/vigraTestEnum.cpp
@@ -0,0 +1,74 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/***************************************************************************************************
+**         INCLUDES AND DEFS                                                                      **
+****************************************************************************************************/
+
+#include <vigra/matlab.hxx>
+using namespace vigra;
+using namespace matlab;
+
+
+
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+
+    VIGRA_CREATE_ENUM_AND_STD_MAP3(MapName, first, second, third);
+    double        method      = double(inputs.getEnum(0, v_required() , MapName ));
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+
+    outputs.createScalar<double>(0, v_required(), method);
+
+
+}
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    vigraMain(outputs, inputs);
+}
+/** MATLAB
+NODOC
+
+*/
+
diff --git a/src/matlab/test-routines/vigraTestOptional.cpp b/src/matlab/test-routines/vigraTestOptional.cpp
new file mode 100644
index 0000000..421c3a8
--- /dev/null
+++ b/src/matlab/test-routines/vigraTestOptional.cpp
@@ -0,0 +1,94 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/***************************************************************************************************
+**         INCLUDES AND DEFS                                                                      **
+****************************************************************************************************/
+
+#include <vigra/matlab.hxx>
+#include <vigra/multi_pointoperators.hxx>
+
+using namespace vigra;
+using namespace matlab;
+
+
+
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+
+
+    MultiArrayView<2,double>         in3D   = inputs.getMultiArray<2,double>(1, v_optional());
+    bool agaIsSet;
+    double                   aga            = inputs.getScalar<double>(0, v_optional(agaIsSet));
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+
+    MultiArrayShape<2>::type    newShape3 (3, 3);
+    if(in3D.data() != 0)
+    {
+        MultiArrayView<2,double>   out3D = outputs.createMultiArray<2,double>(1, v_optional(), in3D.shape());
+        if(out3D.data() != 0)
+            vigra::copyMultiArray(srcMultiArrayRange(in3D), destMultiArray(out3D));
+    }
+    else
+    {
+        MultiArrayView<2,double>   out3D = outputs.createMultiArray<2,double>(1, v_optional(), newShape3);
+    }
+
+
+    outputs.createScalar<int>(2, v_optional(), agaIsSet);
+    
+    if(agaIsSet)
+        outputs.createScalar<double>(0, v_optional(), aga);
+    else
+        outputs.createScalar<double>(0, v_optional(), 2);
+}
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    vigraMain(outputs, inputs);
+}
+/** MATLAB
+NODOC
+
+*/
+
diff --git a/src/matlab/test-routines/vigraTestString.cpp b/src/matlab/test-routines/vigraTestString.cpp
new file mode 100644
index 0000000..6389d74
--- /dev/null
+++ b/src/matlab/test-routines/vigraTestString.cpp
@@ -0,0 +1,80 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/***************************************************************************************************
+**         INCLUDES AND DEFS                                                                      **
+****************************************************************************************************/
+
+#include <vigra/matlab.hxx>
+#include <string>
+using namespace vigra;
+using namespace matlab;
+
+
+
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+
+    std::string   method      = inputs.getString(0, v_default("bla"));
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+    int out = 0;
+
+    if(method == std::string("bla"))
+        out = 1;
+    else if (method == std::string("user"))
+        out = 2;
+
+    outputs.createScalar<double>(0, v_required(), out);
+
+
+}
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    vigraMain(outputs, inputs);
+}
+/** MATLAB
+NODOC
+
+*/
+
diff --git a/src/matlab/testVigraExtensions.m b/src/matlab/testVigraExtensions.m
new file mode 100644
index 0000000..810f3c3
--- /dev/null
+++ b/src/matlab/testVigraExtensions.m
@@ -0,0 +1,740 @@
+function testVigraExtensions()
+% unit tests for the VIGRA-MATLAB gateway ($VIGRA/include/vigra/matlab.hxx) 
+%
+% call testVigraExtensions() in the source directory to compile and run tests
+%
+   disp('Compiling VIGRA test programms...');
+    buildVigraExtensions('test-routines', 'test')
+    
+    disp('Done. Running tests...');
+    currentPath = pwd;
+    cd('test-routines');
+    
+    numSuccess = 0;
+    numTest = 0;
+    
+    disp('Testing: Loading/Creation of Input, Output');
+    disp('         Input and Output Position (in Signature)');
+    disp('         Typechecking of input');
+    numSuccess = numSuccess + test_copy();
+    numTest = numTest +1;
+    
+    disp('Testing: Loading/Creation of Input, Output');
+    disp('         Input and Output Position (in Option Struct)');
+    numSuccess = numSuccess + test_copy_option();
+    numTest = numTest +1;
+  
+    disp('Testing: Loading/Creation of Input, Output');
+    disp('         Input and Output Position (in Option Struct and Signature)');
+    numSuccess = numSuccess + test_copy_mixed();
+    numTest = numTest +1;
+ 
+    
+    
+    
+    disp('Testing: v_required');
+    disp('         Argument Missing');
+    numSuccess = numSuccess + test_v_required_in();
+    numTest = numTest +1;
+     
+    disp('Testing: v_required');
+    disp('         Argument Empty');
+    numSuccess = numSuccess + test_v_required_in_empty();
+    numTest = numTest +1;
+    
+    disp('Testing: v_required');
+    disp('         Output Argument Missing');
+    numSuccess = numSuccess + test_v_required_out();
+    numTest = numTest +1;
+    
+    disp('Testing: v_optional');
+    disp('         Input Argument');
+    numSuccess = numSuccess + test_v_optional_in();
+    numTest = numTest +1;
+    
+    disp('Testing: v_optional');
+    disp('         Output Argument ');    
+    numSuccess = numSuccess + test_v_optional_out();
+    numTest = numTest +1;
+    
+    disp('Testing: v_default');
+    disp('         Input Argument');
+    numSuccess = numSuccess + test_v_default_in();  
+    numTest = numTest +1;
+    
+    
+    
+    
+    disp('Testing: ConstraintScalar');
+    numSuccess = numSuccess + test_constr_scalar();
+    numTest = numTest +1;
+    
+    disp('Testing: Enum');
+    numSuccess = numSuccess + test_enum();
+    numTest = numTest +1;
+    
+    disp('Testing: String');
+    numSuccess = numSuccess + test_string();
+    numTest = numTest +1;
+    
+    disp([num2str(numSuccess) ' of ' num2str(numTest) ' Tests successful.']);
+    cd(currentPath);
+return    
+
+function success = test_copy_impl(handle)
+    tMA     = handle(ones(3,3,3));
+    tI      = handle(ones(3,3));
+    tS      = handle(1);
+    tV      = handle([1;1]);
+    tC      = cell(4,1);
+    success = true;
+    
+    [rMA, rI,rV rS, rS42, rC] = vigraTestCopy(tMA, tI,tV, tS, tC);
+    if rMA(1) == handle(2)
+        rMA(1) = 1;
+    else
+        rMA(1) = 2;
+    end
+    if rI(1) == handle(2)
+        rI(1) = 1;
+    else
+        rI(1) = 2;
+    end
+    if rV(1) == handle(2)
+        rV(1) = 1;
+    else
+        rV(1) = 2;
+    end
+    if rS(1) == handle(2)
+        rS(1) = 1;
+    else
+        rS(1) = 2;
+    end
+    
+    if ~strcmp(func2str(handle), class(rMA))
+        success = false;
+        disp(['...Output Class ' class(rMa) ' and  Input Class ' func2str(handle) ' do not match']);
+    end
+    
+    if ~isequal(rMA, tMA);
+        success = false;
+        disp(['...Error in Loading/Saving MultiArray of Type ' class(tMA)]);
+    end
+
+    if ~isequal(rI, tI);
+        success = false;
+        disp(['...Error in Loading/Saving BasicImage of Type' class(tMA)]);
+    end
+    
+    if ~isequal(rV, tV);
+        success = false;
+        disp(['...Error in Loading/Saving TinyVector of Type' class(tMA)]);
+    end
+        
+    if rS ~= tS;
+        success = false;
+        disp(['...Error in Loading/Saving Scalar of Type' class(tMA) ' (Using pointers)']);
+    end
+    
+    if rS42  ~= handle(42)
+        success = false;
+        disp(['...Error in Saving Scalar of Type' class(tMA)]);
+    end
+    
+    if size(tC,1) ~= size(rC, 1) -1
+        success = false;
+        disp('...Error in Loading ConstCellArray');
+    end
+    
+
+return
+
+function success =  test_copy()
+        success = false(10,1);
+        success(1) = test_copy_impl(@double);
+        success(2) = test_copy_impl(@single);
+        success(3) = test_copy_impl(@uint8);
+        success(4) = test_copy_impl(@uint16);
+        success(5) = test_copy_impl(@uint32);
+        success(6) = test_copy_impl(@uint64);
+        success(7) = test_copy_impl(@int8);
+        success(8) = test_copy_impl(@int16);
+        success(9) = test_copy_impl(@int32);
+        success(10) = test_copy_impl(@int64);
+        success = isequal(success, true(10,1));
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end        
+return
+
+
+function success =  test_copy_option()
+    tMA     = ones(3,3,3);
+    tI      = ones(3,3);
+    tS      = 1;
+    tV      = [1;1];
+    success = true;
+    
+    [rMA, rI,rV rS, rS42] = vigraTestCopyOpt(struct('field0',tMA, 'field1', tI,'field2', tV,'field3', tS));
+    if rMA(1) == 2
+        rMA(1) = 1;
+    else
+        rMA(1) = 2;
+    end
+    if rI(1) == 2
+        rI(1) = 1;
+    else
+        rI(1) = 2;
+    end
+    if rV(1) == 2
+        rV(1) = 1;
+    else
+        rV(1) = 2;
+    end
+    if rS(1) == 2
+        rS(1) = 1;
+    else
+        rS(1) = 2;
+    end
+
+    
+    if ~isequal(rMA, tMA);
+        success = false;
+        disp(['...Error in Loading/Saving MultiArray of Type ' class(tMA)]);
+    end
+
+    if ~isequal(rI, tI);
+        success = false;
+        disp(['...Error in Loading/Saving BasicImage of Type' class(tMA)]);
+    end
+    
+    if ~isequal(rV, tV);
+        success = false;
+        disp(['...Error in Loading/Saving TinyVector of Type' class(tMA)]);
+    end
+        
+    if rS ~= tS;
+        success = false;
+        disp(['...Error in Loading/Saving Scalar of Type' class(tMA) ' (Using pointers)']);
+    end
+    
+    if rS42  ~= 42
+        success = false;
+        disp(['...Error in Saving Scalar of Type' class(tMA)]);
+    end
+
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end
+    disp(' ');  
+return
+
+function success =  test_copy_mixed()
+    tMA     = ones(3,3,3);
+    tI      = ones(3,3);
+    tS      = 1;
+    tV      = [1;1];
+    success = true;
+    
+    [rMA, rI,rV rS, rS42] = vigraTestCopyMixed(tMA, tI, struct('field2', tV,'field3', tS));
+    if rMA(1) == 2
+        rMA(1) = 1;
+    else
+        rMA(1) = 2;
+    end
+    if rI(1) == 2
+        rI(1) = 1;
+    else
+        rI(1) = 2;
+    end
+    if rV(1) == 2
+        rV(1) = 1;
+    else
+        rV(1) = 2;
+    end
+    if rS(1) == 2
+        rS(1) = 1;
+    else
+        rS(1) = 2;
+    end
+
+    
+    if ~isequal(rMA, tMA);
+        success = false;
+        disp(['...Error in Loading/Saving MultiArray of Type ' class(tMA)]);
+    end
+
+    if ~isequal(rI, tI);
+        success = false;
+        disp(['...Error in Loading/Saving BasicImage of Type' class(tMA)]);
+    end
+    
+    if ~isequal(rV, tV);
+        success = false;
+        disp(['...Error in Loading/Saving TinyVector of Type' class(tMA)]);
+    end
+        
+    if rS ~= tS;
+        success = false;
+        disp(['...Error in Loading/Saving Scalar of Type' class(tMA) ' (Using pointers)']);
+    end
+    
+    if rS42  ~= 42
+        success = false;
+        disp(['...Error in Saving Scalar of Type' class(tMA)]);
+    end
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end
+    disp(' ');    
+return
+
+
+function success = test_v_required_in()
+    tMA     = handle(ones(3,3,3));
+    tI      = handle(ones(3,3));
+    tS      = handle(1);
+    tV      = handle([1;1]);
+    success = false;
+    try
+        [rMA, rI,rV rS, rS42, rC] = vigraTestCopy(tMA, tI,tV, tS);
+        disp('...Error - v_required not throwing exception if argument not given');
+    catch
+        success = true;
+    end
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end   
+    disp(' ');    
+return;
+   
+
+function success = test_v_required_in_empty()
+    tMA     = handle(ones(3,3,3));
+    tI      = handle(ones(3,3));
+    tS      = handle(1);
+    tV      = handle([1;1]);
+    tC      = cell(4,1);
+    success = false;
+    try    
+        [rMA, rI,rV rS, rS42, rC] = vigraTestCopy(tMA, tI,tV, [], tC);
+        disp('...Error - v_required not throwing exception if in argument empty');
+    catch
+        success = true;
+    end
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end    
+    disp(' ');    
+return;
+
+
+function success = test_v_required_out()
+    tMA     = handle(ones(3,3,3));
+    tI      = handle(ones(3,3));
+    tS      = handle(1);
+    tV      = handle([1;1]);
+    tC      = cell(4,1);
+    success = false;
+    try       
+        [rMA, rI,rV rS, rS42] = vigraTestCopy(tMA, tI,tV, tS);
+        disp('...Error - v_required not throwing exception if out argument not given');
+    catch
+        success = true;
+    end
+    
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end    
+    disp(' ');
+return;
+    
+function success = test_enum()
+
+    success = true;
+    f = vigraTestEnum('first');
+    if f ~= 1
+        success = false;
+        disp('...Error - Enumvalue wrong');       
+    end
+        
+    s = vigraTestEnum('second');
+    if s ~= 2
+        success = false;
+        disp('...Error - Enumvalue wrong');       
+    end
+    
+    t = vigraTestEnum('third');
+    if t ~= 3
+        success = false;
+        disp('...Error - Enumvalue wrong');       
+    end
+    if success == true
+        success = false;
+        try
+
+            t = vigraTestEnum('forth');
+            disp('...Error - no Error thrown if Enum does not exist');
+        catch
+            success = true;
+        end
+    end
+ 
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end
+    disp(' ');
+return;
+    
+function success = test_constr_scalar()
+    success = false(11, 1);
+    %ok
+    try
+        vigraTestConstrScalar(1, 3, 2, 2);
+        success(1) = true;
+    catch
+        disp('...Error - Exception thrown with valid input')
+    end
+    
+    %ok
+    try
+        vigraTestConstrScalar(false, 3,2,2);
+        success(2) = true;
+    catch
+        disp('...Error  Exception thrown with valid logical input-')
+    end
+    
+    %notok
+    try
+        vigraTestConstrScalar(3, 3,2,2);
+        disp('...Error - No Exception thrown with invalid logical input')    
+    catch
+        success(3) = true;
+    end    
+    
+    
+    %notok
+    try
+        vigraTestConstrScalar(1, 4, 2, 2);
+        disp('...Error - No Exception thrown with MinMax Constrained Scalar (Max exceeded)')
+    catch
+        success(4) = true;
+    end    
+    
+    %notok
+    try
+        vigraTestConstrScalar(1, 1, 2, 2);    
+        disp('...Error - No Exception thrown with MinMax Constrained Scalar (Min exceeded)')    
+    catch
+        success(5) = true;
+    end    
+
+    
+    %ok
+    try
+        vigraTestConstrScalar(1, 3, 4, 2);
+        success(6) = true;
+    catch
+        disp('...Error - Exception thrown with Valid Vals Constrained Scalar')
+    end
+    
+    %notok
+    try
+        vigraTestConstrScalar(1, 3, 5, 2);
+        disp('...Error - No Exception raised with invalid Vals Constrained Scalar')    
+    catch
+        success(7) = true;
+    end    
+
+    
+    %ok
+    try    
+        vigraTestConstrScalar(1, 3, 2, 4);
+        success(8) = true;
+    catch
+        disp('...Error - Exception thrown with Valid 2D3D Vals Constrained Scalar (3D)')
+    end
+    
+    %ok
+    try        
+        vigraTestConstrScalar(1, 2, 2, 3);
+        success(9) = true;
+    catch
+        disp('...Error - Exception thrown with Valid 2D3D Vals Constrained Scalar (2D)')
+    end
+    
+    %ok
+    try        
+        vigraTestConstrScalar(1, 2, 2, 5);
+        success(10) = true;
+    catch
+        disp('...Error - Exception thrown with Valid 2D3D Vals Constrained Scalar (2D)')
+    end
+    
+    %notok
+    try
+        vigraTestConstrScalar(1, 2, 2, 4);
+        disp('...Error - No Exception raised with invalid 2D3D Vals Constrained Scalar (2D)')    
+    catch
+        success(11) = true;
+    end    
+
+    %notok
+    try
+        vigraTestConstrScalar(true, 3, 2, 5);
+        disp('...Error - No Exception raised with invalid 2D3D Vals Constrained Scalar (3D)')    
+    catch
+        success(12) = true;
+    end       
+    
+    success = isequal(success, true(12, 1));
+
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end
+    disp(' ');    
+return
+
+
+function success = test_v_default_in()
+    [a b c d] = vigraTestDefault();
+    success = true;
+    if a ~= 2
+        success = false;
+        disp('...Error - Wrong default value for Scalar input');
+    end
+    
+    if b ~= 2
+        success = false;
+        disp('...Error - Wrong 2D 3D default value (2D)');
+    end
+    
+    if ~isequal(zeros(3,3), c)
+        success = false;
+        disp('...Error - Wrong default Array');
+    end
+    
+    if d ~= 0
+        success = false;
+        disp('...Error - Did not detection that optional input was not given');
+    end
+
+    [a b c d] = vigraTestDefault(3);
+    if a ~= 3
+        success = false;
+        disp('...Error - Wrong set value for first input');
+    end
+    
+    if b ~= 3
+        success = false;
+        disp('...Error - Wrong 2D 3D default value (3D)');
+    end
+    
+    if ~isequal(zeros(3,3), c)
+        success = false;
+        disp('...Error - Wrong default Array');
+    end
+    
+    if d ~= 1
+        success = false;
+        disp('...Error - Did not detection that optional input was given');
+    end
+
+    [a b c d] = vigraTestDefault(3, 7, ones(3,2));
+    if a ~= 3
+        success = false;
+        disp('...Error - Wrong set value for first input');
+    end
+    
+    if b ~= 7
+        success = false;
+        disp('...Error - Wrong 2D 3D default value (3D)');
+    end
+    
+    if ~isequal(ones(3,2), c)
+        success = false;
+        disp('...Error - Wrong default Array');
+    end    
+    
+    if d ~= 1
+        success = false;
+        disp('...Error - Did not detection that optional input was given');
+    end
+
+
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end
+    disp(' ');    
+return
+
+
+function success = test_v_optional_in()
+    success = false(2,1);
+    try
+        [a b d]  = vigraTestOptional(3, ones(3,3));
+        success(1) = true;
+        if a~= 3
+            success(2) = false;
+            disp('...Error - Error wrong value for Scalar input when Optional Parameter not supplied')
+        end
+        
+        if ~isequal(b, ones(3,3))
+            success(2) = false;
+            disp('...Error - Error wrong value for Array input when Optional Parameter not supplied')
+        end                
+
+        if d ~= 1
+            success = false;
+            disp('...Error - Did not detection that optional input was given');
+        end
+    catch
+        disp('...Error - Exception Thrown when Optional Parameter supplied');
+    end
+    
+    try
+        [a b d] = vigraTestOptional();
+        success(2) = true;
+        if a~= 2
+            success(2) = false;
+            disp('...Error - Error wrong value for Scalar input when Optional Parameter not supplied')
+        end
+        
+        if ~isequal(b, zeros(3,3))
+            success(2) = false;
+            disp('...Error - Error wrong value for Array input when Optional Parameter not supplied')
+        end        
+
+        if d ~= 0
+            success = false;
+            disp('...Error - Did not detection that optional input was not given');
+        end
+    catch
+        disp('...Error - Exception thrown when Optional Parameter not supplied');
+    end
+    
+    success = isequal(success, true(2,1));
+ 
+
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end
+    disp(' ');     
+return
+
+
+function success = test_v_optional_out()
+    success = false(2,1);
+    try
+        [a b]  = vigraTestOptional(3, ones(3,3));
+        success(1) = true;
+        if a~= 3
+            success(2) = false;
+            disp('...Error - Error wrong value for Scalar input when Optional Parameter not supplied')
+        end
+        
+        if ~isequal(b, ones(3,3))
+            success(2) = false;
+            disp('...Error - Error wrong value for Array input when Optional Parameter not supplied')
+        end                
+    catch
+        disp('...Error - Exception Thrown when Optional Output Parameter supplied');
+    end
+    
+    try
+        vigraTestOptional();
+        success(2) = true;    
+    catch
+        disp('...Error - Exception thrown when Optional Output Parameter not supplied');
+    end
+    
+    success = isequal(success, true(2,1));
+ 
+
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end
+    disp(' ');     
+return
+
+
+function success = test_string()
+    success = true;
+    a = vigraTestString();
+    b = vigraTestString('user');
+    
+    if a ~= 1
+        disp('...Error -default String not loaded');
+        success = false;
+    end
+
+        
+    if b ~= 2
+        disp('...Error -user supplied string not loaded');
+        success = false;
+    end
+ 
+    if success
+        disp('                                                             Success');
+    else
+        disp('                                                             Fail');
+    end    
+    disp(' ');
+return
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% 
+%  Copyright 2003-2008 by Rahul Nair and Ullrich Koethe    
+%                                                                
+% This file is part of the VIGRA computer vision library.        
+% The VIGRA Website is                                           
+%     http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/   
+% Please direct questions, bug reports, and contributions to     
+%     ullrich.koethe at iwr.uni-heidelberg.de    or                 
+%     vigra at informatik.uni-hamburg.de                            
+%                                                                
+% Permission is hereby granted, free of charge, to any person    
+% obtaining a copy of this software and associated documentation 
+% files (the "Software"), to deal in the Software without        
+% restriction, including without limitation the rights to use,   
+% copy, modify, merge, publish, distribute, sublicense, and/or   
+% sell copies of the Software, and to permit persons to whom the 
+% Software is furnished to do so, subject to the following       
+% conditions:                                                    
+%                                                                
+% The above copyright notice and this permission notice shall be 
+% included in all copies or substantial portions of the          
+% Software.                                                      
+%                                                                
+% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND 
+% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND       
+% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    
+% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,   
+% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING   
+% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR  
+% OTHER DEALINGS IN THE SOFTWARE.                                
+% 
+
diff --git a/src/matlab/vigraAdjacency.cpp b/src/matlab/vigraAdjacency.cpp
new file mode 100644
index 0000000..1e99199
--- /dev/null
+++ b/src/matlab/vigraAdjacency.cpp
@@ -0,0 +1,328 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/*++++++++++++++++++++INCLUDES+and+Definitions++++++++++++++++++++++++*/
+
+#include <string>
+#include <set>
+#include <vigra/matlab.hxx>
+#include <vigra/contourcirculator.hxx>
+#include <vigra/pixelneighborhood.hxx>
+#include <vigra/diff2d.hxx>
+#include <vigra/cellconfigurations.hxx>
+#include <vigra/inspectimage.hxx>
+#include <vigra/multi_pointoperators.hxx>
+
+using namespace vigra;
+using namespace matlab;
+
+
+#define cP2_(a, b) cP<a, b>::value
+template <class T>
+static void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs)
+{
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    //Change these as for your needs.
+    typedef UInt32 outType;
+    typedef double seedType;
+
+    //Load Input Image
+    MultiArrayView<3,T>         in3D        = inputs.getMultiArray<3,T>(0, v_required());
+    BasicImageView<T>           in          = makeBasicImageView(in3D.bindOuter(0));
+    int                         numOfDim    = inputs.getDimOfInput(0, v_required());
+
+
+    SparseArray<Int32>            adj_matrix;
+    bool                        IsSet_maxRegion;
+    UInt32                          max_region_label    = inputs.getScalar<UInt32> ("max_region_label", v_optional(IsSet_maxRegion));
+    if(!IsSet_maxRegion)
+    {
+        FindMinMax<T> minmax;
+        inspectMultiArray(srcMultiArrayRange(in3D), minmax);
+        max_region_label = static_cast<UInt32>(minmax.max);
+        adj_matrix.assign(max_region_label, max_region_label);
+    }
+
+    bool                        hasWatershedPixel   = inputs.getBool("hasWatershedPixel", v_default(false));
+
+    //Get Crack options
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+    // cantorPair maps 2 integers bijectively onto one dimension. (see Wikipedia Cantor pair Function)
+    switch(cantorPair(numOfDim, hasWatershedPixel))
+    {
+        //in case <XX, 0 (crackedges)> the Pixel/Voxel underneath,
+        //    on the right (and behind) are considered for neighborhood.
+        //in case<IMAGE, 1>  the cell configuration around current pixel is compared to
+        //    the ones in cellconfigurations.h (Configuration are Freeman coded (see PhD thesis, Chap 5.7)
+        // if current configuration is of Type Line then adjacent pixels are considered as neighbors.
+        // in case<VOLUME, 1> the number of adjacent regions are counted. the regions are considered
+        //    adjacent if only two such regions exist
+        case cP2_(IMAGE, 0):
+        {
+
+            ImageIterator<T> upleft = in.upperLeft();
+            ImageIterator<T> downright = in.lowerRight();
+            Diff2D size = downright - upleft;
+            for(int y = 0; y < size.y-1; ++y){
+                for(int x = 0; x< size.x-1; ++x){
+                    adj_matrix(upleft(x,y)-1, upleft(x+1, y)-1)++;
+                    adj_matrix(upleft(x,y)-1, upleft(x, y+1)-1)++;
+                    adj_matrix(upleft(x+1, y)-1, upleft(x,y)-1)++;
+                    adj_matrix(upleft(x, y+1)-1, upleft(x,y)-1)++;
+                }
+            }
+
+            for(int x = 0; x < size.x-1; ++x){
+                adj_matrix(upleft(x, size.y-1)-1, upleft(x+1, size.y-1)-1)++;
+                adj_matrix(upleft(x+1, size.y-1)-1, upleft(x, size.y-1)-1)++;
+            }
+            for(int y = 0; y < size.y-1; ++y){
+                adj_matrix(upleft(size.x-1, y)-1, upleft(size.x-1, y+1)-1)++;
+                adj_matrix(upleft(size.x-1, y+1)-1, upleft(size.x-1, y)-1)++;
+            }
+            break;
+        }
+        case cP2_(VOLUME, 0):
+        {
+
+            MultiArrayShape<3>::type sze = in3D.shape();
+            for(int ii = 0; ii < sze[0]-1; ii++){
+                for(int jj = 0; jj < sze[1]-1; jj++){
+                    for(int kk = 0; kk < sze[2]-1; kk++){
+                        adj_matrix(in3D(ii,jj,kk)-1, in3D(ii+1,jj,kk)-1)++;
+                        adj_matrix(in3D(ii,jj,kk)-1, in3D(ii,jj+1,kk)-1)++;
+                        adj_matrix(in3D(ii,jj,kk)-1, in3D(ii,jj,kk+1)-1)++;
+
+                        adj_matrix(in3D(ii+1,jj,kk)-1, in3D(ii,jj,kk)-1)++;
+                        adj_matrix(in3D(ii,jj+1,kk)-1, in3D(ii,jj,kk)-1)++;
+                        adj_matrix(in3D(ii,jj,kk+1)-1, in3D(ii,jj,kk)-1)++;
+                    }
+                }
+            }
+            for(int jj = 0; jj < sze[1]-1; jj++){
+                for(int kk = 0; kk < sze[2]-1; kk++){
+                    adj_matrix(in3D(sze[0]-1,jj,kk)-1, in3D(sze[0]-1,jj+1,kk)-1)++;
+                    adj_matrix(in3D(sze[0]-1,jj,kk)-1, in3D(sze[0]-1,jj,kk+1)-1)++;
+
+                    adj_matrix(in3D(sze[0]-1,jj+1,kk)-1, in3D(sze[0]-1,jj,kk)-1)++;
+                    adj_matrix(in3D(sze[0]-1,jj,kk+1)-1, in3D(sze[0]-1,jj,kk)-1)++;
+                }
+            }
+            for(int ii = 0; ii < sze[0]-1; ii++){
+                for(int kk = 0; kk < sze[2]-1; kk++){
+                    adj_matrix(in3D(ii,sze[1]-1,kk)-1, in3D(ii+1,sze[1]-1,kk)-1)++;
+                    adj_matrix(in3D(ii,sze[1]-1,kk)-1, in3D(ii,sze[1]-1,kk+1)-1)++;
+
+                    adj_matrix(in3D(ii+1,sze[1]-1,kk)-1, in3D(ii,sze[1]-1,kk)-1)++;
+                    adj_matrix(in3D(ii,sze[1]-1,kk+1)-1, in3D(ii,sze[1]-1,kk)-1)++;
+                }
+            }
+            for(int jj = 0; jj < sze[1]-1; jj++){
+                for(int ii = 0; ii <sze[0] -1; ii++){
+                    adj_matrix(in3D(ii,jj,sze[2]-1)-1, in3D(ii,jj+1,sze[2]-1)-1)++;
+                    adj_matrix(in3D(ii,jj,sze[2]-1)-1, in3D(ii+1,jj,sze[2]-1)-1)++;
+
+                    adj_matrix(in3D(ii,jj+1,sze[2]-1)-1, in3D(ii,jj,sze[2]-1)-1)++;
+                    adj_matrix(in3D(ii+1,jj,sze[2]-1)-1, in3D(ii,jj,sze[2]-1)-1)++;
+                }
+            }
+
+            for(int ii = 0; ii < sze[0]-1; ii++){
+                adj_matrix(in3D(ii,sze[1]-1,sze[2]-1)-1, in3D(ii+1,sze[1]-1,sze[2]-1)-1)++;
+                adj_matrix(in3D(ii+1,sze[1]-1,sze[2]-1)-1, in3D(ii,sze[1]-1,sze[2]-1)-1)++;
+            }
+            for(int jj = 0; jj < sze[1]-1; jj++){
+                adj_matrix(in3D(sze[0]-1,jj,sze[2]-1)-1, in3D(sze[0]-1,jj+1,sze[2]-1)-1)++;
+                adj_matrix(in3D(sze[0]-1,jj+1,sze[2]-1)-1, in3D(sze[0]-1,jj,sze[2]-1)-1)++;
+            }
+            for(int kk = 0; kk < sze[2]-1; kk++){
+                adj_matrix(in3D(sze[0]-1,sze[1]-1,kk)-1, in3D(sze[0]-1,sze[1]-1,kk+1)-1)++;
+                adj_matrix(in3D(sze[0]-1,sze[1]-1,kk+1)-1, in3D(sze[0]-1,sze[1]-1,kk)-1)++;
+            }
+            break;
+        }
+        case cP2_(IMAGE, 1):
+        {
+            ImageIterator<T> upleft = in.upperLeft();
+            ImageIterator<T> downright = in.lowerRight();
+            Diff2D size = downright - upleft;
+            for(int y = 1; y < size.y-1; ++y){
+                for(int x = 1; x< size.x-1; ++x){
+                    if(upleft(x,y) == 0){
+                        NeighborhoodCirculator<typename BasicImageView<T>::Iterator, EightNeighborCode>
+                                                            circulator(upleft+ Diff2D(x, y));
+                        //circulator += 2;
+                        NeighborhoodCirculator<typename BasicImageView<T>::Iterator, EightNeighborCode>
+                                                            end(circulator);
+                        unsigned char BitField = 0;
+                        std::set<T> regions;
+
+                        do{
+                            if(*circulator == 0){
+                                BitField = BitField >> 1;
+                                BitField = BitField | 0x80;
+                            }else{
+                                regions.insert(*circulator);
+                                BitField = BitField >> 1;
+                                BitField = BitField | 0x00;
+                            }
+                        }while(++circulator != end);
+
+                        if(cellimage::cellConfigurations[(int)BitField] == cellimage::CellTypeLine){
+                            if(regions.size() == 2){
+                                typename std::set<T>::const_iterator iter = regions.begin();
+                                adj_matrix(*iter-1,*(iter++)-1)++;
+                            }
+                        }
+                    }
+
+                    std::ostringstream  oight;
+                }
+            }
+        }
+            break;
+        case cP2_(VOLUME, 1):
+        {
+            char ne[26*3] =     {   1,  -1, 0,
+            1,  -1, 1,
+            0,  -1, 1,
+            -1, -1, 1,
+            -1, -1, 0,
+            -1, -1, -1,
+            0,  -1, -1,
+            1,  -1, -1,
+            1,  0,  0,
+            1,  0,  1,
+            0,  0,  1,
+            -1, 0,  1,
+            -1, 0,  0,
+            -1, 0,  -1,
+            0,  0,  -1,
+            1,  0,  -1,
+            1,  1,  0,
+            1,  1,  1,
+            0,  1,  1,
+            -1, 1,  1,
+            -1, 1,  0,
+            -1, 1,  -1,
+            0,  1,  -1,
+            1,  1,  -1,
+            0,  1,  0,
+            0,  -1, 0}  ;
+            std::set<T> regions;
+            MultiArrayShape<3>::type sze = in3D.shape();
+            for(int ii = 1; ii < sze[0]-1; ii++)
+            {
+                for(int jj = 1; jj < sze[1]-1; jj++)
+                {
+                    for(int kk = 1; kk < sze[2]-1; kk++)
+                    {
+                        if(in3D(ii,jj,kk) == 0)
+                        {
+
+
+                            regions.clear();
+
+                            for(int ll = 0; ll < 26; ll++){
+                                if(in3D(ii+ne[ll*3], jj+ne[ll*3+1], kk+ne[ll*3+2]) != 0 ){
+                                    regions.insert((in3D(ii+ne[ll*3], jj+ne[ll*3+1], kk+ne[ll*3+2])));
+                                }
+                            }
+
+                        if(regions.size() == 2)
+                            {
+                                typename std::set<T>::const_iterator iter = regions.begin();
+                                adj_matrix(*iter-1,*(iter++)-1)++;
+                            }
+                        }
+                    }
+                }
+            }
+
+            break;
+        }
+    }
+    for(int ii = 0; ii < max_region_label; ii++){
+        for(int jj = ii; jj < max_region_label; jj++){
+            if(ii == jj)adj_matrix(ii,ii) = 1;
+            else if(adj_matrix.get(ii, jj) != 0)
+                adj_matrix(jj,ii) = adj_matrix.get(ii,jj);
+            else if(adj_matrix.get(jj, ii) != 0)
+                    adj_matrix(ii, jj) = adj_matrix.get(jj, ii);
+        }
+    }
+    adj_matrix.mapToMxArray(outputs[0]);
+}
+
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    switch(inputs.typeOf(0))
+    {
+        ALLOW_FD
+        ALLOW_UINT_8_64
+        ALLOW_INT_8_64
+        default:
+            mexErrMsgTxt("Type of input 0 not supported");
+    }
+}
+/** MATLAB
+function D = vigraAdjacency(inputArray)
+function D = vigraAdjacency(inputArray, options);
+
+D = vigraAdjacency(inputArray) computes the Adjacencymatrix of Label images.
+D = vigraAdjacency(inputImage, options)  does the same with user options.
+options is a struct with possible fields: "hasWatershedPixel"
+
+D               is a sparse matrix of size max_region_label x max_region_label.
+                The entries in D correlate to the length of region borders.
+                (Images with and without watershedPixels return different values)
+inputArray          must be a Image or a Volume with regions labeled with positive whole numbers
+                0 denotes watershed Pixels.
+hasWatershedPixel:  it is advised to set this attribute. Otherwise the Function searches for 0 in the
+                image.
+
+Usage:
+    opt = struct('method' ,value);
+    out = vigraAdjacency(in, opt);
+
+*/
diff --git a/src/matlab/vigraBoundaryTensor.cpp b/src/matlab/vigraBoundaryTensor.cpp
new file mode 100644
index 0000000..a039616
--- /dev/null
+++ b/src/matlab/vigraBoundaryTensor.cpp
@@ -0,0 +1,106 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/*++++++++++++++++++++INCLUDES+and+Definitions++++++++++++++++++++++++*/
+
+#include <vigra/matlab.hxx>
+#include <string>
+#include <vigra/boundarytensor.hxx>
+
+
+using namespace vigra;
+using namespace matlab;
+
+
+
+
+
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    BasicImageView<T>   in      =   inputs.getImage<T>(0, v_required());
+    double              scale   =   inputs.getScalarMinMax<double>(1, v_default(1.0), 0.0, "inf");
+
+    MultiArrayView<3,T> res     =   outputs.createMultiArray<3,T>   (0, v_required(), 
+                                                   MultiArrayShape<3>::type(3, in.width(), in.height()));
+    
+    vigra_precondition(sizeof(TinyVector<T, 3>) == sizeof(T)*res.stride(1),
+           "vigraBoundaryTensor(): Internal error (unsuitable memory layout).");
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+
+    BasicImageView<TinyVector<T, 3> >  out(reinterpret_cast<TinyVector<T, 3> *>(res.data()),
+                                            in.width(), in.height());
+    boundaryTensor(srcImageRange(in), destImage(out), scale);
+}
+
+
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    //Add classes as you feel
+    switch(inputs.typeOf(0))
+    {
+        ALLOW_FD
+        default:
+            mexErrMsgTxt("Type of input 0 not supported");
+    }
+}
+
+
+/** MATLAB
+function out = vigraBoundaryTensor(inputImage)
+function out = vigraBoundaryTensor(inputImage, scale);
+
+inputImage - 2D scalar input array
+scale      - 1.0 (default), a positive floating point scale
+             parameter for boundary tensor computation
+             
+out        - output boundary tensor image
+             the first dimension holds the boundary tensor entries
+                 B11(y,x) = out(1,y,x)
+                 B21(y,x) = B12(y,x) = out(2,y,x)
+                 B22(y,x) = out(3,y,x)
+
+Usage:
+    out = vigraBoundaryTensor(in, 2.0);
+*/
diff --git a/src/matlab/vigraConnectedComponents.cpp b/src/matlab/vigraConnectedComponents.cpp
new file mode 100644
index 0000000..be7ce5a
--- /dev/null
+++ b/src/matlab/vigraConnectedComponents.cpp
@@ -0,0 +1,206 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/*++++++++++++++++++++INCLUDES+and+Definitions++++++++++++++++++++++++*/
+
+//#define VIGRA_CHECK_BOUNDS
+#include <vigra/matlab.hxx>
+#include <vigra/labelimage.hxx>
+#include <vigra/labelvolume.hxx>
+#include <vigra/matlab_FLEXTYPE.hxx>
+
+
+//this could be a typedef but if you want outType to be the same type as inType then you can just
+//set outType to T
+
+
+using namespace vigra;
+using namespace matlab;
+
+
+
+//#define RN_DEBUG
+#define cP3_(a, b , c) cP3<a, b, c>::value
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ***************************************************************************************************/
+    typedef UInt32 OutputType;
+    MultiArrayView<3,T> in3D        =       inputs.getMultiArray<3,T>(0, v_required());
+    BasicImageView<T>   in          =       makeBasicImageView(in3D.bindOuter(0));
+    Int32               numOfDim    =       inputs.getDimOfInput(0, v_required());
+
+    Int32               v2Dconn[2]  = {8, 4};
+    Int32               v3Dconn[2]  = {26, 6};
+    Int32               connectivity= inputs.getScalarVals2D3D<Int32>("conn", 
+                                                                      numOfDim == 2 ? v_default(8) : v_default(26),
+                                                                      v2Dconn, v2Dconn+2,
+                                                                      v3Dconn, v3Dconn+2,
+                                                                      numOfDim);
+    /*{
+        if(numOfDim == 2 && connectivity!= 8 && connectivity != 4)
+            mexErrMsgTxt("Connectivity for 2D data must be 8 or 4");
+        else if(numOfDim == 3 && connectivity!= 26 && connectivity != 6)
+            mexErrMsgTxt("Connectivity for 3D data must be 26 or 6");
+    }*/
+
+
+    bool                    hasBackground;
+    T                       backgroundValue = inputs.getScalar<T>("backgroundValue", v_optional(hasBackground));
+
+    MultiArrayView<3,OutputType>     out3D  = outputs.createMultiArray      <3,OutputType>   (0, v_required(), in3D.shape());
+    BasicImageView<OutputType>       out(out3D.data(), in3D.shape(0), in3D.shape(1));
+
+    Int32                     max_region_label = (hasBackground == true)? 1: 0;
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+    #ifdef RN_DEBUG
+    mexPrintf("---%d---%d---%d---", max_region_label, numOfDim, connectivity);
+    #endif
+    switch(cantorPair(hasBackground , numOfDim, connectivity)){
+        //cP is the templated version o f the cantorPair function first value is Dimension of Inputimage, second the connectivity setting
+        //Code is basically the code on the VIGRA-reference page
+        case cP3_(0, IMAGE, 8):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("0, IMAGE, 8");
+            #endif
+            max_region_label = labelImage(srcImageRange(in), destImage(out), true);
+            break;
+        case cP3_(0, IMAGE, 4):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("0, IMAGE, 4");
+            #endif
+            max_region_label = labelImage(srcImageRange(in), destImage(out), false);
+            break;
+        case cP3_(0, VOLUME, 6):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("0, VOLUME, 26");
+            #endif
+            max_region_label = labelVolumeSix(srcMultiArrayRange(in3D), destMultiArray(out3D));
+            break;
+        case cP3_(0, VOLUME, 26):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("0, VOLUME, 6");
+            #endif
+            max_region_label = labelVolume(srcMultiArrayRange(in3D), destMultiArray(out3D), NeighborCode3DTwentySix());
+            break;
+        case cP3_(1, IMAGE, 8):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("1, IMAGE, 8");
+            #endif
+            max_region_label = labelImageWithBackground(srcImageRange(in), destImage(out), true, backgroundValue);
+            break;
+        case cP3_(1, IMAGE, 4):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("1, IMAGE, 4");
+            #endif
+            max_region_label = labelImageWithBackground(srcImageRange(in), destImage(out), false, backgroundValue);
+            break;
+        case cP3_(1, VOLUME, 26):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("1, VOLUME, 26");
+            #endif
+            max_region_label = labelVolumeWithBackground(srcMultiArrayRange(in3D), destMultiArray(out3D),
+                                                                                        NeighborCode3DTwentySix(), backgroundValue);
+            break;
+        case cP3_(1, VOLUME, 6):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("1, VOLUME, 6");
+            #endif
+            max_region_label = labelVolumeWithBackground(srcMultiArrayRange(in3D), destMultiArray(out3D),
+                                                                                        NeighborCode3DSix(), backgroundValue);
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("DONE");
+            #endif
+            break;
+        default:
+            mexErrMsgTxt("Something went wrong");
+    }
+
+    outputs.createScalar<int> (1, v_optional(), max_region_label);
+}
+
+
+
+/***************************************************************************************************
+**           VIGRA GATEWAY                                                                        **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    //Add classes as you feel
+    switch(inputs.typeOf(0))
+    {
+        ALLOW_FD
+        ALLOW_UINT_8_64
+        ALLOW_INT_8_64
+        default:
+            mexErrMsgTxt("Type of input 0 not supported");
+    }
+}
+
+
+/*+++++++++++++++++++++++MexEntryFunc++++++++++++++++++++++++++++++++*/
+/* Gatewayfunction - see matlab.hxx for details.
+/* if a certain class is NOT supported - you will have to copy the
+/* body of the callMexFunctor function and edit it here.
+/* Supports (u)int[8|16|32|64], float and double.
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/** MATLAB
+function D = vigraConnectedComponents(inputArray)
+function D = vigraConnectedComponents(inputArray, options);
+
+D = vigraConnectedComponents(inputArray) performs connected components labeling
+        using the default options.
+D = vigraConnectedComponents(inputImage, options)  does the same with user options.
+
+inputArray - a 2D or 3D array of numeric type
+
+options    - is a struct with the following possible fields:
+    'conn':            The neighborhood to be used
+                       2D: 4 (default) or  8
+                       3D: 6 (default) or 26
+    'backgroundValue': Specify the value of a background region not to be labeled (will be labeled 0
+                       in the result array, even when it doesn't form a single connected component).
+                       If this option in not present, the entire image/volume will be labeled.
+
+Usage:
+    opt = struct('conn', 8);
+    out = vigraConnectedComponents(in, opt);
+
+*/
diff --git a/src/matlab/vigraCorner.cpp b/src/matlab/vigraCorner.cpp
new file mode 100644
index 0000000..cecf15b
--- /dev/null
+++ b/src/matlab/vigraCorner.cpp
@@ -0,0 +1,122 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/*++++++++++++++++++++INCLUDES+and+Definitions++++++++++++++++++++++++*/
+
+#include <vigra/matlab.hxx>
+#include <string>
+#include <vigra/cornerdetection.hxx>
+
+
+using namespace vigra;
+using namespace matlab;
+
+
+
+
+
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    BasicImageView<T>   in      =   inputs.getImage<T>(0, v_required());
+    double              scale   =   inputs.getScalarMinMax<double>(1, v_default(1.0), 0.0, "inf");
+
+    VIGRA_CREATE_ENUM_AND_STD_MAP4(MapName, Corner, Foerstner, Rohr, Beaudet);
+    int             method  =   inputs.getEnum(2,  v_default(Corner), MapName);
+
+    BasicImageView<double> out  =   outputs.createImage<double>(0, v_required(), in.width(), in.height());
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+    switch(method){
+        case Corner:
+            cornerResponseFunction (srcImageRange(in), destImage(out), scale);
+            break;
+        case Foerstner:
+            foerstnerCornerDetector (srcImageRange(in), destImage(out), scale);
+            break;
+        case Rohr:
+            rohrCornerDetector (srcImageRange(in), destImage(out), scale);
+            break;
+        case Beaudet:
+            beaudetCornerDetector (srcImageRange(in), destImage(out), scale);
+            break;
+        default:
+            mexErrMsgTxt("Some Error occured");
+    }
+
+}
+
+
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    //Add classes as you feel
+    switch(inputs.typeOf(0))
+    {
+        ALLOW_FD
+        ALLOW_UINT_8_64
+        ALLOW_INT_8_64
+        default:
+            mexErrMsgTxt("Type of input 0 not supported");
+    }
+}
+
+
+/** MATLAB
+function D = vigraCorner(inputImage)
+function D = vigraCorner(inputImage, options);
+
+D = vigraCorner(inputArray) does Corner detection.
+D = vigraCorner(inputImage, options)  does the same with user options.
+
+inputImage - 2D input array
+options    - struct with following possible fields:
+   'method':  'Corner' (default, corenr response function according to Harris), 'Beaudet', 'Foerstner', 'Rohr'
+              Use corresponding method to detect corners (see vigra reference for more details).
+   'scale':   1.0 (default), any positive floating point value
+              scale parameter for corner feature computation
+
+Usage:
+    opt = struct('method' ,value);
+    out = vigraCorner(in, opt);
+
+*/
diff --git a/src/matlab/vigraDistance.cpp b/src/matlab/vigraDistance.cpp
new file mode 100644
index 0000000..ddd7d62
--- /dev/null
+++ b/src/matlab/vigraDistance.cpp
@@ -0,0 +1,224 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/*++++++++++++++++++++INCLUDES+and+Definitions++++++++++++++++++++++++*/
+
+#include <vigra/matlab.hxx>
+#include <string>
+#include <vigra/distancetransform.hxx>
+#include <vigra/multi_distance.hxx>
+#include <functional>
+
+//this could be a typedef but if you want outType to be the same type as inType then you can just
+//set outType to T
+
+
+using namespace vigra;
+using namespace matlab;
+
+
+
+
+//#define RN_DEBUG
+#define cP2_(a, b) cP<(int)a, b>::value
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    //Load input Image
+    MultiArrayView<3,T>         in3D        = inputs.getMultiArray<3,T>(0, v_required());
+    BasicImageView<T>           in          = makeBasicImageView(in3D.bindOuter(0));
+    int                         numOfDim    = inputs.getDimOfInput(0, v_required());
+
+    //Load Method Option
+    VIGRA_CREATE_ENUM_AND_STD_MAP3(MapName, MULT, MULT_SQUARED, IMAG_DIST_TRANS);
+    int         method      = inputs.getEnum("method", v_default(MULT), MapName );
+
+
+    //Load backgroundValue/Mode/norm
+    int                 norm                = inputs.getScalarMinMax<int>("norm", v_default(2), 0, 2);
+    T                   backgroundValue     = inputs.getScalar<T>("backgroundValue", v_default(0));
+    int                 backgroundMode      = inputs.getScalarMinMax<int>("backgroundMode", v_default(1), 0, 2);
+
+    //Load Pitch
+    TinyVector<double, 3>       defaultPitch3D(1,1, 1);
+    TinyVector<double, 2>       defaultPitch(1,1);
+    TinyVectorView<double, 2>   pitch       =  inputs.getTinyVector<double, 2> ( "pitch", v_default(defaultPitch));
+    TinyVectorView<double, 3>   pitch3D     = (numOfDim == 3)?
+                                                inputs.getTinyVector<double, 3> ( "pitch", v_default(defaultPitch3D))
+                                            :   vigra::TinyVectorView<double, 3>(defaultPitch3D);
+
+
+    //This is a cheap way of checking whether pitch option has been set - if not the pointers of pitch and defaultPitch
+    //should be the same;
+    //Some more errorchecking
+    if(method == IMAG_DIST_TRANS)
+    {
+        if  (numOfDim == VOLUME)
+                mexErrMsgTxt("vigraDistance(): method 'IMAG_DIST_TRANS' requires 2D data.");
+        if  (pitch.data() != defaultPitch.data())
+                mexErrMsgTxt("vigraDistance(): 'IMAG_DIST_TRANS' does not support 'pitch' Option");
+        if  (backgroundMode != 1)
+                mexErrMsgTxt("vigraDistance(): method 'IMAG_DIST_TRANS' requires 'backgroundMode' = 1.");
+    }
+    else
+    {
+        if  (backgroundValue != 0)
+                mexErrMsgTxt("vigraDistance(): methods 'MULT' and 'MULT_SQUARED' require 'backgroundValue' = 0.");
+        if  (norm != 2)
+                mexErrMsgTxt("vigraDistance(): methods 'MULT' and 'MULT_SQUARED' require 'norm' = 2.");
+    }
+
+    //Allocate Memory for output
+    typedef double outType;
+    MultiArrayView<3,outType>   out3D       = outputs.createMultiArray      <3,outType>   (0, v_required(), in3D.shape());
+    BasicImageView<outType>     out(out3D.data(), in3D.shape(0), in3D.shape(1));
+
+    MultiArray<3, outType>      tmp3D(in3D.shape());
+    bool                        computeSignedDist  = (backgroundMode == 2);
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+
+    // catorPair maps 2 integers bijectively onto one dimension. (see Wikipedia Cantor pair Function)
+    using namespace vigra::functor;
+
+    switch(cantorPair(computeSignedDist, method))
+    {
+        //In this case function pointers may have been more elegant.
+        case cP2_(false, MULT):
+                separableMultiDistance(srcMultiArrayRange(in3D), destMultiArray(out3D), backgroundMode == 1, pitch3D);
+                break;
+        case cP2_(true, MULT):
+            separableMultiDistSquared(srcMultiArrayRange(in3D), destMultiArray(out3D), 0, pitch3D);
+            separableMultiDistSquared(srcMultiArrayRange(in3D), destMultiArray(tmp3D), 1, pitch3D);
+            combineTwoMultiArrays(
+                        srcMultiArrayRange(tmp3D),
+                        srcMultiArray(out3D),
+                        destMultiArray(out3D),
+                        ifThenElse(Arg1() > Param(0.0), sqrt(Arg1())-Param(0.5), Param(0.5)-sqrt(Arg2())));
+            break;
+        case cP2_(0, MULT_SQUARED):
+            separableMultiDistSquared(srcMultiArrayRange(in3D), destMultiArray(out3D), backgroundMode == 1);
+            break;
+        case cP2_(1, MULT_SQUARED):
+            separableMultiDistSquared(srcMultiArrayRange(in3D), destMultiArray(out3D), 0);
+            separableMultiDistSquared(srcMultiArrayRange(in3D), destMultiArray(tmp3D), 1);
+            combineTwoMultiArrays(
+                        srcMultiArrayRange(tmp3D),
+                        srcMultiArray(out3D),
+                        destMultiArray(out3D),
+                        ifThenElse(Arg1() > Param(0.0), sq(sqrt(Arg1())-Param(0.5)), -sq(sqrt(Arg2())-Param(0.5))));
+            break;
+        case cP2_(0, IMAG_DIST_TRANS):
+            distanceTransform(srcImageRange(in), destImage(out),backgroundValue, norm);
+            break;
+        default:
+            mexErrMsgTxt("Precondition checking not complete - something went wrong");
+    }
+
+}
+
+/***************************************************************************************************
+**           VIGRA GATEWAY                                                                        **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    //Add classes as you feel
+    switch(inputs.typeOf(0))
+    {
+        ALLOW_FD
+        ALLOW_UINT_8_64
+        ALLOW_INT_8_64
+        default:
+            mexErrMsgTxt("Type of input 0 not supported");
+    }
+}
+
+/*+++++++++++++++++++++++MexEntryFunc++++++++++++++++++++++++++++++++*/
+/* Gatewayfunction - see matlab.hxx for details.
+/* if a certain class is NOT supported - you will have to copy the
+/* body of the callMexFunctor function and edit it here.
+/* Supports (u)int[8|16|32|64], float and double.
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/** MATLAB
+function D = vigraDistance(inputArray)
+function D = vigraDistance(inputArray, options);
+
+D = vigraDistance(inputArray) computes the distance transform using the default options.
+D = vigraDistance(inputImage, options)  does the same with user options.
+
+inputArray  - a 2D or 3D array of numeric type
+options     - a struct with the following possible fields (default will be used
+              if field is not present)
+    'method':          'MULT'(default), 'MULT_SQUARED', 'IMAG_DIST_TRANS'
+                       MULT and MULT_SQUARED are the faster and newer distance transform
+                       methods defined with VIGRA-Multiarrays (vigra::seperableMultiDist....).
+                       MULT_SQUARED returns the squared values of MULT.
+                       IMAG_DIST_TRANS is defined with BasicImage (vigra::distanceTransform) and
+                       less accurate. Use it only if you explicitely need the 'backgroundValue'
+                       or 'norm' options.
+    'backgroundValue': 0 (default) , arbitrary value (only supported by IMAG_DIST_TRANS)
+                       This option defines the background value. In MULT and MULT_SQUARED, the
+                       'backgroundValue' is always 0, but see option 'backgroundMode'.
+    'backgroundMode':  0 , 1 (default) , 2:
+                       This option is only used with methods MULT and MULT_SQUARED.
+                       In method IMAG_DIST_TRANS, the distance of background points
+                         (according to 'backgroundValue' above) to the nearest
+                         non-background is computed.
+                       If 'backgroundMode' is 1, then the (squared) distance of all background
+                         points to the nearest object is calculated.
+                       If 'backgroundMode' is 0, the (squared) distance of all object
+                         points to the nearest background is calculated.
+                       If 'backgroundMode' is 2, the signed (squared) distance of all points
+                         to the contour will be calculated, such that negative values are
+                         inside the objects, positive ones in the background. IMAG_DIST_TRANS
+    'norm':            2 (default, Euclidean distance), 1 (L1 distance), 0 (L-infinity distance).
+                       Defines the norm used to calculate the distance.
+                       Only supported by method IMAG_DIST_TRANS
+    'pitch':           2D: [1.0, 1.0] (default), arbitrary int32-Array of length 2.
+                       3D: [1.0, 1.0, 1.0] (default), arbitrary int32-Array of length 3.
+                       Define the pixel distance if data has non-uniform resolution.
+                       Only supported by methods MULT and MULT_SQUARED.
+
+Usage:
+    opt = struct('method' ,'IMAGE_DIST_TRANS' , 'backgroundValue', 10 , 'norm' , 0);
+    out = vigraDistance(in, opt);
+
+*/
+
diff --git a/src/matlab/vigraExporthdf5RF.cpp b/src/matlab/vigraExporthdf5RF.cpp
new file mode 100644
index 0000000..e3b20e5
--- /dev/null
+++ b/src/matlab/vigraExporthdf5RF.cpp
@@ -0,0 +1,100 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <set>
+#include <vigra/matlab.hxx>
+
+#define HasHDF5
+#include "random_forest_impex.hxx"
+#include <vigra/random_forest_hdf5_impex.hxx>
+
+using namespace vigra;
+using namespace matlab;
+using namespace rf;
+using namespace visitors;
+
+
+
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /* INPUT */
+    if (inputs.size() != 2)
+        mexErrMsgTxt("Two inputs required.");
+
+    // get RF object
+   RandomForest<> rf;
+   matlab::importRandomForest(rf, matlab::getCellArray(inputs[0]));
+   std::string filename = inputs.getString(1, v_required());
+   std::string groupname = inputs.getString(2, v_default(std::string("")));
+   vigra::rf_export_HDF5(rf, filename, groupname );
+}
+
+
+
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+inline void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    vigraMain(outputs, inputs);
+};
+
+/**ADDITIONAL_BUILD_FLAGS
+-lhdf5 -lhdf5_hl
+*/
+
+/** MATLAB
+function vigraExporthdf5RF(rf, filename, groupname);
+
+Export a previously trained Random Forest to a hdf5 file
+
+    RF        - MATLAB cell array representing the random forest classifier
+   filename  - name of hdf5 file
+
+   groupname    - optional: name of group which shoud be used as the base
+                path
+ *
+
+to compile on Linux:
+--------------------
+  mex vigraExporthdf5RF.cpp -I../../include -lhdf5 -lhdf5_hl
+
+to compile on Windows:
+----------------------
+  mex vigraExporthdf5RF.cpp -I../../include -I[HDF5PATH]/include -L[HDF5PATH]/lib -lhdf5dll -lhdf5_hldll -D_HDF5USEDLL_ -DHDF5CPP_USEDLL
+
+hdf5 1.6.x or hdf5 1.8.x must be installed. 
+*/
diff --git a/src/matlab/vigraImporthdf5RF.cpp b/src/matlab/vigraImporthdf5RF.cpp
new file mode 100644
index 0000000..5937c49
--- /dev/null
+++ b/src/matlab/vigraImporthdf5RF.cpp
@@ -0,0 +1,100 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <set>
+#include <vigra/matlab.hxx>
+
+#define HasHDF5
+#include "random_forest_impex.hxx"
+#include <vigra/random_forest_hdf5_impex.hxx>
+
+using namespace vigra;
+using namespace matlab;
+using namespace rf;
+using namespace visitors;
+
+
+
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /* INPUT */
+    if (inputs.size() != 1)
+        mexErrMsgTxt("One inputs required.");
+
+    // get RF object
+   RandomForest<> rf;
+   std::string filename = inputs.getString(0, v_required());
+   std::string groupname = inputs.getString(1, v_default(std::string("")));
+   vigra::rf_import_HDF5(rf, filename, groupname );
+   matlab::exportRandomForest(rf, matlab::createCellArray(2*rf.options_.tree_count_+2, outputs[0]));
+}
+
+
+
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+inline void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    vigraMain(outputs, inputs);
+};
+
+
+/**ADDITIONAL_BUILD_FLAGS
+-lhdf5 -lhdf5_hl
+*/
+
+/** MATLAB
+function rf = vigraImporthdf5RF( filename, groupname);
+
+Import a previously trained Random Forest from  a hdf5 file
+
+    rf        - MATLAB cell array representing the random forest classifier
+   filename  - name of hdf5 file
+
+   groupname    - optional: name of group which shoud be used as the base
+                    path
+
+to compile on Linux:
+--------------------
+  mex vigraImporthdf5RF.cpp -I../../include -lhdf5 -lhdf5_hl
+
+to compile on Windows:
+----------------------
+  mex vigraImporthdf5RF.cpp -I../../include -I[HDF5PATH]/include -L[HDF5PATH]/lib -lhdf5dll -lhdf5_hldll -D_HDF5USEDLL_ -DHDF5CPP_USEDLL
+
+hdf5 1.6.x or hdf5 1.8.x must be installed. 
+*/
diff --git a/src/matlab/vigraIndex.m b/src/matlab/vigraIndex.m
new file mode 100644
index 0000000..e30494f
--- /dev/null
+++ b/src/matlab/vigraIndex.m
@@ -0,0 +1,55 @@
+function vigraIndex()
+%Listing of vigra functions imported to Matlab:
+% 
+%vigraRadialSymmetry        :   Radial Symmetry Transform    
+%vigraDistance              :   2D and 3D Distance Transform    
+%vigraWatershed             :   2D and 3D Watershed Transform   
+%vigraResize2               :   2D Spline Interpolated Resize   
+%vigraResize3               :   3D Spline Interpolated Resize   
+%vigraAdjacency             :   Create Adjacency Matrix         
+%vigraConnectedComponents   :   Calculate Connected Comp.       
+%vigraCorner                :   2D Corner Detector              
+%vigralearnRF               :   Learn a random forest          
+%vigraPredictProbabiliesRF  :   predict Probabilites of RF     
+%vigraPredictLabelsRF       :   predict Labels RF           
+%
+%use testVigraExtensions to test the matlab.hxx interface
+%if testVigraExtensions is successful and you still encounter problems
+%then probably your C++ code is buggy.
+return
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  Copyright 2003-2008 by Ullrich Koethe    
+%  Based on make.m by Andrea Tagliasacchi
+%                                                                
+% This file is part of the VIGRA computer vision library.        
+% The VIGRA Website is                                           
+%     http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/   
+% Please direct questions, bug reports, and contributions to     
+%     ullrich.koethe at iwr.uni-heidelberg.de    or                 
+%     vigra at informatik.uni-hamburg.de                            
+%                                                                
+% Permission is hereby granted, free of charge, to any person    
+% obtaining a copy of this software and associated documentation 
+% files (the "Software"), to deal in the Software without        
+% restriction, including without limitation the rights to use,   
+% copy, modify, merge, publish, distribute, sublicense, and/or   
+% sell copies of the Software, and to permit persons to whom the 
+% Software is furnished to do so, subject to the following       
+% conditions:                                                    
+%                                                                
+% The above copyright notice and this permission notice shall be 
+% included in all copies or substantial portions of the          
+% Software.                                                      
+%                                                                
+% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND 
+% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND       
+% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    
+% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,   
+% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING   
+% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR  
+% OTHER DEALINGS IN THE SOFTWARE.                                
+% 
+
diff --git a/src/matlab/vigraLearnRF.cpp b/src/matlab/vigraLearnRF.cpp
new file mode 100644
index 0000000..a5ca443
--- /dev/null
+++ b/src/matlab/vigraLearnRF.cpp
@@ -0,0 +1,190 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/*++++++++++++++++++++INCLUDES+and+Definitions++++++++++++++++++++++++*/
+
+#include <iostream>
+#include <set>
+#include <string>
+#include <vigra/matlab.hxx>
+#include "random_forest_impex.hxx"
+#include "RandomForestProgressVisitor.hxx"
+
+
+using namespace vigra;
+using namespace matlab;
+using namespace vigra::rf;
+using namespace vigra::rf::visitors;
+
+typedef double inputType;   // input feature type
+typedef double inputLType;  // input label type
+
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+
+    vigra::RandomForestOptions  options;
+    vigra::ProblemSpec<inputLType>  ext_param;
+    options.sample_with_replacement(inputs.getBool("sample_with_replacement", 
+                                                   v_default(true)));
+    
+    if(inputs.getBool("sample_classes_individually", v_default(false)))
+        options.use_stratification(vigra::RF_EQUAL);
+    options.min_split_node_size(static_cast<int>(inputs
+            .getScalarMinMax<double>("min_split_node_size",
+                                     v_default(1.0), 
+                                     0.0, "inf")));
+    options.tree_count(static_cast<int>(inputs
+            .getScalarMinMax<double>(2,v_default(255.0), 0.0, "inf")));
+    if(inputs.hasData("mtry"))
+    {
+        if(inputs.typeOf("mtry") == mxCHAR_CLASS)
+        {
+            std::map<std::string, int> map_;
+                map_["RF_LOG"]  = int(RF_LOG);
+                map_["RF_SQRT"] = int(RF_SQRT);
+                map_["RF_ALL"]  = int(RF_ALL);
+            RF_OptionTag method  = RF_OptionTag(inputs.getEnum("mtry", v_default(RF_LOG), map_));
+        }
+        else
+        {
+            options
+                .features_per_node(int(inputs.getScalar<double>("mtry",v_default(0))));
+        }
+    }
+
+    double training_set_size 
+        = inputs.getScalar<double>("training_set_size",v_default(0));
+    if(training_set_size != 0)
+    {
+        options.samples_per_tree(int(training_set_size));
+    }
+    else
+    {
+        options.samples_per_tree(inputs
+            .getScalarMinMax<double>("training_set_proportion",
+                                     v_default(1.0), 0.0, 1.0));
+    }
+    MultiArrayView<2, inputLType>  labels 
+        = inputs.getMultiArray<2, inputLType>(1, v_required());
+    MultiArrayView<2, inputType>  features 
+        = inputs.getMultiArray<2, inputType>(0, v_required());
+    MultiArrayView<1, inputType>  weights 
+        = inputs.getMultiArray<1, inputType>("weights", v_optional());
+
+    if(weights.size() != 0)
+        ext_param.class_weights(weights.data(), weights.data() + weights.size());
+
+    double var_imp_rep
+        = inputs.getScalar<double>("importance_repetition",v_default(10));
+    
+    VariableImportanceVisitor   var_imp(static_cast<int>(var_imp_rep));
+    OOB_Error                   oob_err;
+    MatlabRandomForestProgressVisitor progress;
+    if(!outputs.isValid(2))
+        var_imp.deactivate();
+
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+
+    RandomForest<inputLType> rf(options, ext_param);    
+    rf.learn(features, labels, create_visitor(var_imp, progress, oob_err));
+
+    matlab::exportRandomForest(rf, matlab::createCellArray(2*options.tree_count_+2, outputs[0]));
+
+    outputs.createScalar<double> (1, v_optional(), oob_err.oob_breiman);
+    MultiArrayView<2, double> vari 
+        = outputs.createMultiArray<2, double>(2, v_optional(), 
+                            MultiArrayShape<2>::type(var_imp
+                                                      .variable_importance_
+                                                      .shape()));
+    if(vari.size() != 0)
+        vari = var_imp.variable_importance_;
+}
+
+
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+inline void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    vigraMain(outputs, inputs);
+}
+
+
+/** MATLAB
+function RF = vigraLearnRF(features, labels) Trains a randomForest with Default TreeCount and options
+function RF = vigraLearnRF(features, labels, treeCount)  does the same treeCount number of trees and default options.
+function RF = vigraLearnRF(features, labels, treeCount, options)  does the same with user options.
+function [RF oob] = vigraLearnRF(...)                Outputs the oob error estimate
+function [RF oob var_imp] = vigraLearnRF(...)       Outputs variable importance.
+
+features    - A Nxp Matrix with N samples containing p features
+labels      - A Nx1 Matrix with the corresponding Training labels
+treeCount   - default: 255. An Integral Scalar Value > 0 - Number of Trees to be used in the Random Forest.
+options     - a struct with the following possible fields (default will be used
+              if field is not present)
+    'sample_with_replacement'       logical, default : true
+    'sample_classes_individually'   logical, default : false
+    'min_split_node_size'           Scalar, default: 1.0 - controls size pruning of the tree while training.
+    'mtry'                          Scalar or String, 
+                                    default: floor(sqrt(number of features)) ('RF_SQRT')
+                                    if a Scalar value is specified it is taken as the 
+                                    absolute value. Otherwise use one of the Tokens
+                                    'RF_SQRT', 'RF_LOG' or 'RF_ALL'
+
+    'training_set_size'             Scalar, default: Not used
+    'training_set_proportion'       Scalar, default: 1.0
+                                    The last two options exclude each other. if training_set_size always overrides
+                                    training_set_proportional, if set.
+                                    Controls the number of samples drawn to train an individual tree.
+    'weights'
+                                    Array containing training weights for each class. The size of the array is
+                                    not checked so you may get wierd errors if you do not enforce the size constraints.
+var_imp     - A FeatureCount x ClassCount +2 Matrix. 
+                                    The last column is the variable importance based on mean decrease in impurity
+                                    over all trees the end -1 column is the permutation based variable importance
+                                    Columns 1 - ClassCount are the class wise permutation based variable importance
+                                    scores.
+
+//not yet supported
+oob_data    - A NxNumberOfTrees Matrix. oob_data(i, j) = 0 if ith sample was not in the test set for the jth tree
+                                                       = 1 if ith sample was correctly classified in jth tree
+                                                       = 2 if ith sample was misclassified int jth tree
+*/
diff --git a/src/matlab/vigraLeastAngleRegression.cpp b/src/matlab/vigraLeastAngleRegression.cpp
new file mode 100644
index 0000000..b54ed76
--- /dev/null
+++ b/src/matlab/vigraLeastAngleRegression.cpp
@@ -0,0 +1,137 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/***************************************************************************************************
+**         INCLUDES AND DEFS                                                                      **
+****************************************************************************************************/
+
+#include <vigra/matlab.hxx>
+#include <vigra/symmetry.hxx>
+#include <vigra/regression.hxx>
+//#include <vigra/multi_pointoperators.hxx>
+
+using namespace vigra;
+using namespace matlab;
+using namespace linalg;
+
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    typedef double OutputType;
+
+    MultiArray<2, T>   A    =   inputs.getMultiArray<2, T>(0, v_required());
+    MultiArray<2, T>   b    =   inputs.getMultiArray<2, T>(1, v_required());
+
+    int max_solution_count      =   inputs.getScalarMinMax<int>("max_solution_count",v_default(0), 0, "inf");
+    std::string mode            =   inputs.getString("mode", v_default(std::string("lasso")));
+
+
+    ArrayVector<ArrayVector<int> > activeSets;
+    ArrayVector<Matrix<OutputType> > lsq_solutions;
+    ArrayVector<Matrix<OutputType> > lasso_solutions;
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+
+    // normalize the input
+
+    int n = columnCount(A);
+    Matrix<double> offset(1,n), scaling(1,n);
+        prepareColumns(A, A, offset, scaling, linalg::DataPreparationGoals(ZeroMean|UnitVariance));
+        prepareColumns(b, b, linalg::DataPreparationGoals(ZeroMean));
+
+    unsigned int numSolutions = leastAngleRegression(A, b, activeSets, lasso_solutions, lsq_solutions,
+                                                LeastAngleRegressionOptions()
+                                                .maxSolutionCount(max_solution_count)
+                                                .setMode(mode)
+                                );
+
+    MultiArrayView<2, OutputType> dense_lsq = outputs.createMultiArray<2, OutputType>(0,v_required(),
+                                                    MultiArrayShape<2>::type(columnCount(A), numSolutions));
+    MultiArrayView<2, OutputType> dense_lasso = outputs.createMultiArray<2, OutputType>(1,v_optional(),
+                                                    MultiArrayShape<2>::type(columnCount(A), numSolutions));
+    for (MultiArrayIndex k = 0; k < numSolutions; ++k)
+    {
+        for (unsigned int i = 0; i < activeSets[k].size(); ++i)
+        {
+            dense_lsq(activeSets[k][i], k) = lsq_solutions[k](i,0)*scaling(0, activeSets[k][i]);
+        }
+    }
+
+    // Optional Output.
+    if(dense_lasso.data() != 0)
+    {
+        for (MultiArrayIndex k = 0; k < numSolutions; ++k)
+        {
+            for (unsigned int i = 0; i < activeSets[k].size(); ++i)
+            {
+                dense_lasso(activeSets[k][i], k) = lasso_solutions[k](i,0)*scaling(0, activeSets[k][i]);
+            }
+        }
+    }
+
+}
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    //Add classes as you feel
+    switch(inputs.typeOf(0))
+    {
+        ALLOW_D
+        default:
+            mexErrMsgTxt("Type of input at position 0 not supported");
+    }
+}
+/** MATLAB
+function dense_lsq = vigraLeastAngleRegression(A, b)
+function dense_lsq = vigraLeastAngleRegression(A, b, options);
+function [dense_lsq dense_lasso] = vigraLeastAngleRegression(...);
+
+Solves Equations of Type A*x = b using L1 regularisation
+The columns of dense_lsq are the least squares Solutions in the
+    (iterations?) of the Lasso
+Columns of dense_lasso are...
+
+options    - a struct with following possible fields:
+    'mode':    default 'lasso', nnlasso (non negative lasso), lars (least angle regression)
+    'max_solution_count':   default: Unused, Integral value > 0
+
+
+*/
diff --git a/src/matlab/vigraPredictIndividually.cpp b/src/matlab/vigraPredictIndividually.cpp
new file mode 100644
index 0000000..e787f24
--- /dev/null
+++ b/src/matlab/vigraPredictIndividually.cpp
@@ -0,0 +1,97 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <set>
+#include <vigra/matlab.hxx>
+#include "random_forest_impex.hxx"
+
+using namespace vigra;
+using namespace matlab;
+using namespace rf;
+using namespace visitors;
+
+
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /* INPUT */
+    if (inputs.size() != 2)
+        mexErrMsgTxt("Two inputs required.");
+
+    // get RF object
+    RandomForest<> rf; 
+    matlab::importRandomForest(rf, matlab::getCellArray(inputs[0]));
+
+    // get feature matrix
+    MultiArrayView<2, double> features = inputs.getMultiArray<2, double> ( 1, v_required());
+    if(rf.ext_param_.column_count_ != columnCount(features))
+        mexErrMsgTxt("Feature array has wrong number of columns.");
+
+    /* OUTPUT */
+    MultiArrayView<3, double> probs = outputs.createMultiArray<3, double>(0, v_required(),
+                                                                MultiArrayShape<3>::type(rowCount(features), 
+                                                                                         rf.ext_param_.class_count_, rf.tree_count()));
+    ArrayVector<double>::const_iterator weights;
+
+    double totalWeight = 0.0;
+    for(int k=0; k< rf.tree_count(); ++k)
+    for(int ii = 0; ii < features.shape(0); ++ii)
+    {
+    //get weights predicted by single tree
+        weights = rf.trees_[k].predict(rowVector(features, ii));
+        for(int jj = 0; jj < rf.ext_param_.class_count_; ++jj)
+          probs(ii, jj, k) = weights[jj] * (*(weights-1)); 
+    }
+}
+
+
+
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+inline void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    vigraMain(outputs, inputs);
+}
+/** Matlab
+function probs = vigraPredictProbabilitiesRF(RF, features)
+
+Use a previously trained random forest classifier to predict labels for the given data
+    RF        - MATLAB cell array representing the random forest classifier
+    features  - M x N matrix, where M is the number of samples, N the number of features
+
+    probs     - M x L matrix holding the predicted probabilities for each of
+                the L possible labels
+*/
diff --git a/src/matlab/vigraPredictLabelsRF.cpp b/src/matlab/vigraPredictLabelsRF.cpp
new file mode 100644
index 0000000..e1f927b
--- /dev/null
+++ b/src/matlab/vigraPredictLabelsRF.cpp
@@ -0,0 +1,89 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <set>
+#include <vigra/matlab.hxx>
+#include "random_forest_impex.hxx"
+
+using namespace vigra;
+using namespace matlab;
+using namespace rf;
+using namespace visitors;
+
+
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /* INPUT */
+    if (inputs.size() != 2)
+        mexErrMsgTxt("Two inputs required.");
+
+    // get RF object
+   RandomForest<> rf;
+   matlab::importRandomForest(rf, matlab::getCellArray(inputs[0]));
+
+    // get feature matrix
+    MultiArrayView<2, double> features = inputs.getMultiArray<2, double> ( 1, v_required());
+    if(rf.ext_param_.column_count_ != columnCount(features))
+        mexErrMsgTxt("Feature array has wrong number of columns.");
+
+    /* OUTPUT */
+    MultiArrayView<2, double> probs = outputs.createMultiArray<2, double>(0, v_required(),
+                                                                TinyVector<UInt32, 2>(rowCount(features), 1));
+
+    rf.predictLabels(features, probs);
+
+}
+
+
+
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+inline void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    vigraMain(outputs, inputs);
+};
+
+/** MATLAB
+function labels = vigraPredictLabelsRF(RF, features)
+
+Use a previously trained random forest classifier to predict labels for the given data
+    RF        - MATLAB cell array representing the random forest classifier
+    features  - M x N matrix, where M is the number of samples, N the number of features
+
+    labels    - M x 1 matrix holding the predicted labels
+
+*/
diff --git a/src/matlab/vigraPredictProbabilitiesRF.cpp b/src/matlab/vigraPredictProbabilitiesRF.cpp
new file mode 100644
index 0000000..bfb1b57
--- /dev/null
+++ b/src/matlab/vigraPredictProbabilitiesRF.cpp
@@ -0,0 +1,89 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <set>
+#include <vigra/matlab.hxx>
+#include "random_forest_impex.hxx"
+
+using namespace vigra;
+using namespace matlab;
+using namespace rf;
+using namespace visitors;
+
+
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /* INPUT */
+    if (inputs.size() != 2)
+        mexErrMsgTxt("Two inputs required.");
+
+    // get RF object
+    RandomForest<> rf; 
+    matlab::importRandomForest(rf, matlab::getCellArray(inputs[0]));
+
+    // get feature matrix
+    MultiArrayView<2, double> features = inputs.getMultiArray<2, double> ( 1, v_required());
+    if(rf.ext_param_.column_count_ != columnCount(features))
+        mexErrMsgTxt("Feature array has wrong number of columns.");
+
+    /* OUTPUT */
+    MultiArrayView<2, double> probs = outputs.createMultiArray<2, double>(0, v_required(),
+                                                                MultiArrayShape<2>::type(rowCount(features), 
+                                                                                         rf.ext_param_.class_count_));
+
+    rf.predictProbabilities(features, probs);
+
+}
+
+
+
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+inline void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    vigraMain(outputs, inputs);
+}
+/** Matlab
+function probs = vigraPredictProbabilitiesRF(RF, features)
+
+Use a previously trained random forest classifier to predict labels for the given data
+    RF        - MATLAB cell array representing the random forest classifier
+    features  - M x N matrix, where M is the number of samples, N the number of features
+
+    probs     - M x L matrix holding the predicted probabilities for each of
+                the L possible labels
+*/
diff --git a/src/matlab/vigraRadialSymmetry.cpp b/src/matlab/vigraRadialSymmetry.cpp
new file mode 100644
index 0000000..5836bf1
--- /dev/null
+++ b/src/matlab/vigraRadialSymmetry.cpp
@@ -0,0 +1,95 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/***************************************************************************************************
+**         INCLUDES AND DEFS                                                                      **
+****************************************************************************************************/
+
+#include <vigra/matlab.hxx>
+#include <vigra/symmetry.hxx>
+
+using namespace vigra;
+using namespace matlab;
+
+
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    BasicImageView<T>   in      =   inputs.getImage<T>(0, v_required());
+    double              scale   =   inputs.getScalarMinMax<double>(1, v_default(1.0), 0.0, "inf");
+
+    BasicImageView<double> out  =   outputs.createImage<double>(0, v_required(), in.width(), in.height());
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+    radialSymmetryTransform(srcImageRange(in), destImage(out), scale);
+
+}
+
+/***************************************************************************************************
+**         VIGRA GATEWAY                                                                          **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    //Add classes as you feel
+    switch(inputs.typeOf(0))
+    {
+        ALLOW_D
+        default:
+            mexErrMsgTxt("Type of input at position 0 not supported");
+    }
+}
+/** MATLAB
+function D = vigraRadialSymmetry(inputImage)
+function D = vigraradialSymmetry(inputImage, options);
+
+D = vigraRadialSymmetry(inputImage) computes the Fast Radial Symmetry Transform
+            using default options, see vigra::RadialSymmetryTransform for more information.
+D = vigraRadialSymmetry(inputImage, options)  does the same with user options.
+
+inputImage - 2D input array
+options    - a struct with following possible fields:
+    'scale':    1.0 (default), any positive floating point value
+                scale parameter for the vigraRadialSymmetry
+
+
+Usage:
+    opt = struct('method' ,value);
+    out = vigraRadialSymmetry(in, opt);
+
+*/
diff --git a/src/matlab/vigraResize2.cpp b/src/matlab/vigraResize2.cpp
new file mode 100644
index 0000000..22630fb
--- /dev/null
+++ b/src/matlab/vigraResize2.cpp
@@ -0,0 +1,187 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/*++++++++++++++++++++INCLUDES+and+Definitions++++++++++++++++++++++++*/
+
+#include <vigra/matlab.hxx>
+
+#include <vigra/resizeimage.hxx>
+
+
+
+using namespace vigra;
+using namespace matlab;
+
+/*+++++++++++++++++++User data structure+++++++++++++++++++++++++++++*/
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+//This is not using base_data as base class. because input is 4D.
+
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* This function does all the work
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+//#define RN_DEBUG
+#define cP2_(a, b) cP<(int)a, b>::value
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    //Load input Image
+    MultiArrayView<3,T>         in3D        = inputs.getMultiArray<3,T>(0, v_required());
+
+    //Load Method Option
+    VIGRA_CREATE_ENUM_AND_STD_MAP3(MapName, BSpline, Catmull, Coscot)
+    int method = inputs.getEnum("method", v_default(BSpline), MapName );
+
+
+    //Load spline Order option
+    Int32                         splineOrder = (method == BSpline)?
+                                          inputs.getScalarMinMax<int>("splineOrder", v_default(3),0, 5)
+                                        : 0;
+    //Load new Shape
+    TinyVector<double, 2>       defaultShape(2*in3D.shape(0) -1, 2*in3D.shape(1)-1);
+    TinyVectorView<double, 2>   newShape  = inputs.getTinyVector<double, 2> ( 1, v_default(defaultShape));
+    MultiArrayShape<3>::type    newShape3      (Int32(newShape[0]), Int32(newShape[1]), in3D.shape(2));
+
+
+    //Allocate Memory for output
+    MultiArrayView<3,T>         out3D     = outputs.createMultiArray<3,T>   (0, v_required(), newShape3);
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+    // cantorPair maps 2 integers bijectively onto one dimension. (see Wikipedia Cantor pair Function)
+    for(int k=0; k<in3D.shape(2); ++k)
+    {
+
+        BasicImageView<T> ink = makeBasicImageView(in3D.bindOuter(k));
+        BasicImageView<T> outk = makeBasicImageView(out3D.bindOuter(k));
+
+        switch(cantorPair(method, splineOrder))
+        {
+        case cP2_(BSpline, 0):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("BSpline 0");
+            #endif
+            resizeImageNoInterpolation(srcImageRange(ink), destImageRange(outk));
+            break;
+        case cP2_(BSpline, 1):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("BSpline 1");
+            #endif
+            resizeImageLinearInterpolation(srcImageRange(ink), destImageRange(outk));
+            break;
+        case cP2_(BSpline, 2):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("BSpline 2");
+            #endif
+            resizeImageSplineInterpolation(srcImageRange(ink), destImageRange(outk), vigra::BSpline<2>());
+            break;
+        case cP2_(BSpline, 3):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("BSpline 3");
+            #endif
+            resizeImageSplineInterpolation(srcImageRange(ink), destImageRange(outk), vigra::BSpline<3>());
+            break;
+        case cP2_(BSpline, 4):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("BSpline 4");
+            #endif
+            resizeImageSplineInterpolation(srcImageRange(ink), destImageRange(outk), vigra::BSpline<4>());
+            break;
+        case cP2_(BSpline, 5):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("BSpline 5");
+            #endif
+            resizeImageSplineInterpolation(srcImageRange(ink), destImageRange(outk), vigra::BSpline<5>());
+            break;
+        case cP2_(Catmull, 0):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("Catmull 0");
+            #endif
+            resizeImageCatmullRomInterpolation(srcImageRange(ink), destImageRange(outk));
+            break;
+        case cP2_(Coscot, 0):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("Coscot 0");
+            #endif
+            resizeImageCoscotInterpolation(srcImageRange(ink), destImageRange(outk));
+            break;
+        default:
+            mexErrMsgTxt("Internal Error");
+        }
+    }
+
+}
+
+
+/***************************************************************************************************
+**           VIGRA GATEWAY                                                                        **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    //Add classes as you feel
+    switch(inputs.typeOf(0))
+    {
+        ALLOW_D
+        default:
+            mexErrMsgTxt("Type of input 0 not supported");
+    }
+}
+
+
+/** MATLAB
+function resized = vigraResize2(original)
+function resized = vigraResize2(original, newShape)
+function resized = vigraResize2(original, newShape, options)
+
+D = vigraResize2(inputImage)   # resizes original image data with default options.
+D = vigraResize2(inputImage, [200 300], options)  # does the same with user options.
+
+    original    - Array with original 2D image data
+                    (gray scale or multi-band/RGB, numeric type)
+    newShape    - standard Array of length 2 that gives the new shape
+                    (default: 2*size(original)-1 )
+    options
+        splineOrder - order of interpolation
+            (0 <= splineOrder <= 5, default: 3, i.e. cubic splines)
+            this option is only used for method 'BSpline'
+        method - 'BSpline' (default), 'Coscot' or 'Catmull'
+*/
diff --git a/src/matlab/vigraResize3.cpp b/src/matlab/vigraResize3.cpp
new file mode 100644
index 0000000..55eb4c7
--- /dev/null
+++ b/src/matlab/vigraResize3.cpp
@@ -0,0 +1,163 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+
+
+#include <vigra/matlab.hxx>
+#include <vigra/matlab_FLEXTYPE.hxx>
+#include <string>
+#include <vigra/multi_resize.hxx>
+#include <iostream>
+
+
+//this could be a typedef but if you want outType to be the same type as inType then you can just
+//set outType to T
+
+
+
+using namespace vigra;
+using namespace matlab;
+
+/*+++++++++++++++++++User data structure+++++++++++++++++++++++++++++*/
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+//This is not using base_data as base class. because input is 4D.
+
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* This function does all the work
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+//#define RN_DEBUG
+#define cP2_(a, b) cP<(int)a, b>::value
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    //Options
+
+    MultiArrayView<4,T>         in4D        = inputs.getMultiArray<4,T>(0, v_required());
+
+    VIGRA_CREATE_ENUM_AND_STD_MAP2(MapName, BSpline, Catmull)
+    int method = inputs.getEnum("method", v_default(BSpline), MapName );
+
+ //   Methods1 method2 = inputs.getEnum<Methods1>("method1", Optional(BSpline11));
+
+
+    Int32                        splineOrder = (method == BSpline)?
+                                          inputs.getScalarMinMax<int>("splineOrder", v_default(3),0, 5)
+                                        : 0;
+
+    TinyVector<double, 3>       defaultShape(2*in4D.shape(0) -1, 2*in4D.shape(1)-1, 2*in4D.shape(2)-1);
+    TinyVectorView<double, 3>   newShape  = inputs.getTinyVector<double, 3> ( 1, v_default(defaultShape));
+    MultiArrayShape<4>::type    newShape4      (Int32(newShape[0]), Int32(newShape[1]), Int32(newShape[2]), in4D.shape(3));
+
+
+    MultiArrayView<4,T> out4D           = outputs.createMultiArray      <4,T>   (0, v_required(), newShape4);
+    // contorPair maps 2 integers bijectively onto one dimension. (see Wikipedia Cantor pair Function)
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+        for(int k=0; k<in4D.shape(3); ++k)
+        {
+            MultiArrayView<3, T> ink = in4D.bindOuter(k);
+            MultiArrayView<3, T> outk = out4D.bindOuter(k);
+            switch(cantorPair(method, splineOrder))
+            {
+            case cP2_(BSpline, 0):
+                resizeMultiArraySplineInterpolation(srcMultiArrayRange(ink), destMultiArrayRange(outk), vigra::BSpline<0>());
+                break;
+            case cP2_(BSpline, 1):
+                resizeMultiArraySplineInterpolation(srcMultiArrayRange(ink), destMultiArrayRange(outk),  vigra::BSpline<1>());
+                break;
+            case cP2_(BSpline, 2):
+                resizeMultiArraySplineInterpolation(srcMultiArrayRange(ink), destMultiArrayRange(outk),  vigra::BSpline<2>());
+                break;
+            case cP2_(BSpline, 3):
+                resizeMultiArraySplineInterpolation(srcMultiArrayRange(ink), destMultiArrayRange(outk),  vigra::BSpline<3>());
+                break;
+            case cP2_(BSpline, 4):
+                resizeMultiArraySplineInterpolation(srcMultiArrayRange(ink), destMultiArrayRange(outk),  vigra::BSpline<4>());
+                break;
+            case cP2_(BSpline, 5):
+                resizeMultiArraySplineInterpolation(srcMultiArrayRange(ink), destMultiArrayRange(outk),  vigra::BSpline<5>());
+                break;
+            case cP2_(Catmull, 0):
+                resizeMultiArraySplineInterpolation(srcMultiArrayRange(ink), destMultiArrayRange(outk),  vigra::CatmullRomSpline<double>());
+                break;
+             default:
+                mexErrMsgTxt("Something went terribily wrong - Internal error");
+            }
+        }
+}
+
+
+
+/***************************************************************************************************
+**           VIGRA GATEWAY                                                                        **
+****************************************************************************************************/
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    //Add classes as you feel
+    switch(inputs.typeOf(0))
+    {
+        ALLOW_D
+        default:
+            mexErrMsgTxt("Type of input 0 not supported");
+    }
+}
+
+
+/** MATLAB
+function resized = vigraResize3(original)
+function resized = vigraResize3(original, newShape)
+function resized = vigraResize3(original, newShape, options)
+
+D = vigraResize3(inputVolume)   # resizes original volume data with default options.
+D = vigraResize3(inputVolume, [200 300 100], options)  # does the same with user options.
+
+    original    - Array with original 3D volume data
+                    (gray scale or multi-band/RGB, numeric type)
+    newShape    - Array of length 3 that gives the new shape
+                    (default: 2*size(original)-1 )
+    options
+        splineOrder - order of interpolation
+            (0 <= splineOrder <= 5, default: 3, i.e. cubic splines)
+            this option is only used for method 'BSpline'
+        method - 'BSpline' (default) or 'Catmull'
+*/
diff --git a/src/matlab/vigraWatershed.cpp b/src/matlab/vigraWatershed.cpp
new file mode 100644
index 0000000..86c5e27
--- /dev/null
+++ b/src/matlab/vigraWatershed.cpp
@@ -0,0 +1,242 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+/*++++++++++++++++++++INCLUDES+and+Definitions++++++++++++++++++++++++*/
+
+
+#include <vigra/matlab.hxx>
+
+#include <vigra/watersheds.hxx>
+#include <vigra/watersheds3d.hxx>
+
+#include <vigra/seededregiongrowing.hxx>
+#include <vigra/seededregiongrowing3d.hxx>
+
+
+
+using namespace vigra;
+using namespace matlab;
+
+
+//#define RN_DEBUG
+#define cP3_(a, b , c) cP3<a, b, c>::value
+template <class T>
+void vigraMain(matlab::OutputArray outputs, matlab::InputArray inputs){
+    /***************************************************************************************************
+    **              INIT PART                                                                         **
+    ****************************************************************************************************/
+    //Change these as for your needs.
+    typedef UInt32 outType;
+    typedef UInt32 seedType;
+
+    //Load Input Image
+    MultiArrayView<3,T>         in3D        = inputs.getMultiArray<3,T>(0, v_required());
+    BasicImageView<T>           in          = makeBasicImageView(in3D.bindOuter(0));
+    Int32                       numOfDim    = inputs.getDimOfInput(0, v_required());
+
+    //Load seed if provided
+    enum Methods{UNION = 0, SEED = 1} ;
+    Methods                            method       = UNION;
+    MultiArrayView<3,seedType>         seed3D       = inputs.getMultiArray<3,seedType>("seeds", v_optional());
+    BasicImageView<seedType>           seed         = makeBasicImageView(seed3D.bindOuter(0));
+    if(seed3D.data()!= 0 && !(seed3D.shape() == in3D.shape()))
+        mexErrMsgTxt("Seed Array and Input Array Dimension/ Number of Value Mismatch");
+    if(seed3D.data()!= 0 )  method = SEED;
+
+
+    //Get right connectivity options
+    Int32  v2Dconn[2]   = {8, 4};
+    Int32  v3Dconn[2]   = {26, 6};
+    Int32  connectivity = (method == UNION)
+                            ? inputs.getScalarVals2D3D<int>("conn",
+                                                            numOfDim == 2 ? v_default(8) : v_default(26),
+                                                            v2Dconn, v2Dconn+2,
+                                                            v3Dconn, v3Dconn+2,
+                                                            numOfDim)
+                            : inputs.getScalarVals2D3D<int>("conn",
+                                                             numOfDim == 2 ? v_default(4) : v_default(6),
+                                                            v2Dconn+1, v2Dconn+2,
+                                                            v3Dconn+1, v3Dconn+2,
+                                                            numOfDim);
+    //Get Crack options
+    VIGRA_CREATE_ENUM_AND_STD_MAP2(CrackMap, complete_grow, keep_contours);
+    int                         crack           = inputs.getEnum("crack", v_default(complete_grow), CrackMap);
+    SRGType                     SRGcrack        = (crack == complete_grow)? vigra::CompleteGrow : vigra::KeepContours;
+
+
+    double                      CostThreshold   =  inputs.getScalar<double>("CostThreshold", v_default(-1.0));
+    if(CostThreshold >= 0.0)
+        SRGcrack = (SRGType)(SRGcrack | StopAtThreshold);
+
+    //Allocate space for outputArray.
+    MultiArrayView<3,outType>   out3D           = outputs.createMultiArray      <3,outType>   (0, v_required(), in3D.shape());
+    BasicImageView<outType>     out(out3D.data(), in3D.shape(0), in3D.shape(1));
+    // contorPair maps 2 integers bijectively onto one dimension. (see Wikipedia Cantor pair Function)
+
+    UInt32 max_region_label = 0;
+
+
+    /***************************************************************************************************
+    **              CODE PART                                                                         **
+    ****************************************************************************************************/
+    // contorPair maps 2 integers bijectively onto one dimension. (see Wikipedia Cantor pair Function)
+    switch(cantorPair(method, numOfDim, connectivity)){
+        //cP is the templated version o f the cantorPair function first value is Dimension of Inputimage, second the connectivity setting
+        //Code is basically the code on the VIGRA-reference page
+        case cP3_(UNION, IMAGE, 8):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("UNION IMAGE 8");
+            #endif
+            max_region_label = watersheds(srcImageRange(in), destImage(out));
+
+            break;
+        case cP3_(UNION, IMAGE, 4):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("UNION IMAGE 4");
+            #endif
+            max_region_label = watersheds(srcImageRange(in), destImage(out), FourNeighborCode());
+
+            break;
+        case cP3_(UNION, VOLUME, 26):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("UNION VOLUME 26");
+            #endif
+            max_region_label = watersheds3DTwentySix(srcMultiArrayRange(in3D), destMultiArray(out3D));
+
+            break;
+        case cP3_(UNION, VOLUME, 6):
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("UNION VOLUME 6");
+            #endif
+            max_region_label = watersheds3DSix(srcMultiArrayRange(in3D), destMultiArray(out3D));
+
+            break;
+        case cP3_(SEED, IMAGE, 4):
+        {
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("SEED IMAGE 4");
+            #endif
+            //find maximimum of seed Image
+            FindMinMax<seedType> minmax;   // init functor
+            inspectImage(srcImageRange(seed), minmax);
+            max_region_label = static_cast<UInt32>(minmax.max);
+
+            ArrayOfRegionStatistics<vigra::SeedRgDirectValueFunctor<seedType> >
+                                            gradstat(max_region_label);
+
+            seededRegionGrowing(    srcImageRange(in),
+                                    srcImage(seed),
+                                    destImage(out),
+                                    gradstat,SRGcrack, FourNeighborCode(), CostThreshold );
+            break;
+        }
+        case cP3_(SEED, VOLUME, 6):
+        {
+            #ifdef RN_DEBUG
+            mexWarnMsgTxt("SEED VOLUME 6");
+            #endif
+            FindMinMax<seedType> minmax;
+            inspectMultiArray(srcMultiArrayRange(seed3D), minmax);
+            max_region_label = static_cast<UInt32>(minmax.max);
+
+            ArrayOfRegionStatistics<vigra::SeedRgDirectValueFunctor<seedType> >
+                                            gradstat(max_region_label);
+
+            seededRegionGrowing3D(  srcMultiArrayRange(in3D),
+                                    srcMultiArray(seed3D),
+                                    destMultiArray(out3D),
+                                    gradstat, SRGcrack, NeighborCode3DSix(), CostThreshold);
+            break;
+        }
+        default:
+            mexErrMsgTxt("Something went horribily wrong - Internal error");
+    }
+    outputs.createScalar(1,v_optional(), max_region_label);
+}
+
+
+void vigraMexFunction(vigra::matlab::OutputArray outputs, vigra::matlab::InputArray inputs)
+{
+    //Add classes as you feel
+    switch(inputs.typeOf(0))
+    {
+        ALLOW_FD;
+        ALLOW_UINT;
+    ALLOW_INT;
+        default:
+            mexErrMsgTxt("Type of input 0 not supported");
+    }
+}
+
+/** MATLAB
+function L = vigraWatershed(inputArray)
+function L = vigraWatershed(inputArray, options);
+
+L = vigraWatershed(inputArray);
+        Uses the union find algorithm to compute a label matrix identifying
+        the watershed regions of the inputArray (which may be 2 or 3 dimensional).
+        The elements of L are Int32 values greater than 0. Boundaries are
+        represented by crack edges, i.e. there are no explicit watershed pixels.
+
+options = struct('seeds', seedImage, 'crack' = 'keepContours');
+L = vigraWatershed(inputImage, options);
+        Uses seeded region growing to compute a label matrix identifying
+        the watershed regions of the inputArray (which may be 2 or 3 dimensional).
+        The elements of L are Int32 values greater than 0. Boundaries are
+        represented by explicit watershed pixels, i.e. there is a one-pixel
+        thick boundary between every pair of regions.
+
+inputArray - a 2D or 3D array of type 'single' or 'double'
+
+options    - is a struct with the following possible fields
+    'seeds':    An Array of same size as inputArray. If supplied, seeded region growing
+                shall be used. If not, the union find algorithm will be used. As of now,
+                the seed array has to be of same type as the input array - this will be changed in the next update.
+    'conn':     2D: 4 (default),  8 (only supported by the union find algorithm)
+                3D: 6 (default), 26 (only supported by the union find algorithm)
+                While using seeded region growing, only the default values can be used.
+    'crack':    'completeGrow' (default), 'keepContours' (only supported by seeded region growing and 2D Images)
+                Choose whether to keep watershed pixels or not. While using union find,
+                only the default value can be used.
+    'CostThreshold':  -1.0 (default) - any double value.
+                If, at any point in the algorithm, the cost of the current candidate exceeds the optional
+                max_cost value (which defaults to -1), region growing is aborted, and all voxels not yet
+                assigned to a region remain unlabeled.
+Usage:
+    opt = struct('fieldname' ,'value',....);
+    out = vigraWatershed(in, opt);
+*/
+
+
diff --git a/src/regression.cpp b/src/regression.cpp
new file mode 100644
index 0000000..620893f
--- /dev/null
+++ b/src/regression.cpp
@@ -0,0 +1,30 @@
+#define HasHDF5
+#include "../include/vigra/random_forest.hxx"
+#include "../test/classifier/test_visitors.hxx"
+using namespace vigra;
+int main()
+{
+    vigra::TestVisitor testVisitor;
+    RandomForest<double, RegressionTag> rf(RandomForestOptions().tree_count(1));
+    Matrix<double> feat(100, 2);
+    int ss = 0;
+    Matrix<double> resp(100, 1);
+    Matrix<double> resp2(100, 1);
+    for(int ii = 0; ii < 10; ++ ii)
+    {
+        for(int jj = 0; jj < 10; ++jj)
+        {
+            feat(ss, 0 ) = ii;
+            feat(ss, 1 ) = jj;
+            resp(ss, 0) = ii +  jj;
+            ++ss;
+        }
+    }
+    rf.learn(feat, resp, create_visitor(testVisitor), RegressionSplit());
+    rf.predictRaw(feat, resp2);
+    for(int ii = 0; ii < 100; ++ii)
+    {
+        std::cerr << resp(ii, 0) << " " << resp2(ii, 0) << std::endl;
+    }
+    //shoudEqual(resp, resp2)
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..4b97958
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,37 @@
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+INCLUDE(VigraAddTest)
+
+ADD_SUBDIRECTORY(error)
+ADD_SUBDIRECTORY(impex)
+ADD_SUBDIRECTORY(utilities)
+ADD_SUBDIRECTORY(pixeltypes)
+ADD_SUBDIRECTORY(colorspaces)
+ADD_SUBDIRECTORY(classifier)
+ADD_SUBDIRECTORY(imgproc)
+ADD_SUBDIRECTORY(functorexpression)
+ADD_SUBDIRECTORY(convolution)
+ADD_SUBDIRECTORY(morphology)
+ADD_SUBDIRECTORY(fourier)
+ADD_SUBDIRECTORY(math)
+ADD_SUBDIRECTORY(optimization)
+ADD_SUBDIRECTORY(tensorimaging)
+ADD_SUBDIRECTORY(simpleanalysis)
+ADD_SUBDIRECTORY(image)
+ADD_SUBDIRECTORY(multiarray)
+ADD_SUBDIRECTORY(multiconvolution)
+ADD_SUBDIRECTORY(voxelneighborhood)
+ADD_SUBDIRECTORY(volumelabeling)
+ADD_SUBDIRECTORY(watersheds3d)
+ADD_SUBDIRECTORY(multidistance)
+ADD_SUBDIRECTORY(multimorphology)
+ADD_SUBDIRECTORY(seededRegionGrowing3d)
+ADD_SUBDIRECTORY(sampler)
+ADD_SUBDIRECTORY(hdf5impex)
+ADD_SUBDIRECTORY(sifImport)
+ADD_SUBDIRECTORY(features)
+ADD_SUBDIRECTORY(unsupervised)
+ADD_SUBDIRECTORY(coordinateiterator)
+ADD_SUBDIRECTORY(objectfeatures)
+ADD_SUBDIRECTORY(slic2d)
+ADD_SUBDIRECTORY(gridgraph)
diff --git a/test/checkUnitTests.py b/test/checkUnitTests.py
new file mode 100644
index 0000000..9b46c53
--- /dev/null
+++ b/test/checkUnitTests.py
@@ -0,0 +1,24 @@
+def hook(ui, repo, **args):
+    import os
+    repoPath = repo.url()[5:] + '/' # cut-off 'file:' prefix
+    testSuccessFile = repoPath + 'test/testSuccess'
+    if not os.path.exists(testSuccessFile):
+        print "File 'test/testSuccess' is missing. Run the test suite before committing."
+        return True
+    testTime = os.path.getmtime(testSuccessFile)
+    stat = repo.status()
+    files = stat[0]+stat[1]  # added or modified files
+    modified = []
+    for file in files:
+        if file[-4:] not in ['.cxx', '.hxx']:
+            continue
+        fileTime =  os.path.getmtime(repoPath+file)
+        if fileTime > testTime:
+            modified.append(file)
+    if len(modified) > 0:
+        print "Run the test suite before committing. The following files are untested:" 
+        for file in modified:
+            print '   ',file
+        return True
+    return False
+    
diff --git a/test/classifier/CMakeLists.txt b/test/classifier/CMakeLists.txt
new file mode 100755
index 0000000..8b7476a
--- /dev/null
+++ b/test/classifier/CMakeLists.txt
@@ -0,0 +1,14 @@
+if(HDF5_FOUND)
+    INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIR})
+  
+    ADD_DEFINITIONS(${HDF5_CPPFLAGS} -DHasHDF5)
+    VIGRA_ADD_TEST(test_classifier test.cxx LIBRARIES vigraimpex ${HDF5_LIBRARIES})
+else()
+    MESSAGE(STATUS "** WARNING: test_classifier::RFHDF5Test() will not be executed")
+    VIGRA_ADD_TEST(test_classifier test.cxx )
+endif()
+
+VIGRA_ADD_TEST(classifier_speed_comparison speed_comparison.cxx)
+
+add_subdirectory(data)
+
diff --git a/test/classifier/data/CMakeLists.txt b/test/classifier/data/CMakeLists.txt
new file mode 100644
index 0000000..ed89cfd
--- /dev/null
+++ b/test/classifier/data/CMakeLists.txt
@@ -0,0 +1,7 @@
+
+#       message(status "Current Source: ${CMAKE_CURRENT_SOURCE_DIR}") 
+#       message(status "Current Bin: ${CMAKE_CURRENT_BINARY_DIR}") 
+#       configure_file(${CMAKE_CURRENT_SOURCE_DIR}/oldClassifier.log 
+#                      ${CMAKE_CURRENT_BINARY_DIR}/oldClassifier.log
+#                      COPYONLY)
+VIGRA_COPY_TEST_DATA(oldClassifier.log oldsetTest.log)
diff --git a/test/classifier/data/RF_common.hxx b/test/classifier/data/RF_common.hxx
new file mode 100644
index 0000000..aab5faf
--- /dev/null
+++ b/test/classifier/data/RF_common.hxx
@@ -0,0 +1,171 @@
+#ifndef RF_TEST_COMMON
+#define RF_TEST_COMMON
+
+
+//#include "pina_indians_var_imp.hxx"
+
+#include "SPECTF_features.hxx"
+#include "SPECTF_labels.hxx"
+#include "ecoli_features.hxx"
+#include "ecoli_labels.hxx"
+#include "glass_features.hxx"
+#include "glass_labels.hxx"
+#include "ionosphere_features.hxx"
+#include "ionosphere_labels.hxx"
+#include "iris_features.hxx"
+#include "iris_labels.hxx"
+//#include "letter_recognition_features.hxx"
+//#include "letter_recognition_labels.hxx"
+//#include "madelon_features.hxx"
+//#include "madelon_labels.hxx"
+//#include "magic04_features.hxx"
+//#include "magic04_labels.hxx"
+//#include "page_blocks_features.hxx"
+//#include "page_blocks_labels.hxx"
+#include "pina_indians_diabetes_features.hxx"
+#include "pina_indians_diabetes_labels.hxx"
+#include "segmentation_features.hxx"
+#include "segmentation_labels.hxx"
+//#include "shuttle_features.hxx"
+//#include "shuttle_labels.hxx"
+//#include "spambase_features.hxx"
+//#include "spambase_labels.hxx"
+#include "wine_features.hxx"
+#include "wine_labels.hxx"
+#include "wpbc_features.hxx"
+#include "wpbc_labels.hxx"
+//#include "yeast_features.hxx"
+//#include "yeast_labels.hxx"
+
+//#include "SPECTF_resultsRFDT.hxx"
+//#include "SPECTF_resultsRFm1.hxx"
+//#include "SPECTF_resultsRFdef.hxx"
+//#include "SPECTF_resultsRFbagging.hxx"
+//
+//#include "ecoli_resultsRFDT.hxx"
+//#include "ecoli_resultsRFm1.hxx"
+//#include "ecoli_resultsRFdef.hxx"
+//#include "ecoli_resultsRFbagging.hxx"
+//
+//#include "glass_resultsRFDT.hxx"
+//#include "glass_resultsRFm1.hxx"
+//#include "glass_resultsRFdef.hxx"
+//#include "glass_resultsRFbagging.hxx"
+//
+//#include "ionosphere_resultsRFDT.hxx"
+//#include "ionosphere_resultsRFm1.hxx"
+//#include "ionosphere_resultsRFdef.hxx"
+//#include "ionosphere_resultsRFbagging.hxx"
+//
+//#include "iris_resultsRFDT.hxx"
+//#include "iris_resultsRFm1.hxx"
+//#include "iris_resultsRFdef.hxx"
+//#include "iris_resultsRFbagging.hxx"
+//
+//#include "pina_indians_diabetes_resultsRFDT.hxx"
+//#include "pina_indians_diabetes_resultsRFm1.hxx"
+//#include "pina_indians_diabetes_resultsRFdef.hxx"
+//#include "pina_indians_diabetes_resultsRFbagging.hxx"
+//
+//#include "segmentation_resultsRFDT.hxx"
+//#include "segmentation_resultsRFm1.hxx"
+//#include "segmentation_resultsRFdef.hxx"
+//#include "segmentation_resultsRFbagging.hxx"
+//
+//#include "wine_resultsRFDT.hxx"
+//#include "wine_resultsRFm1.hxx"
+//#include "wine_resultsRFdef.hxx"
+//#include "wine_resultsRFbagging.hxx"
+
+//#include "wpbc_resultsRFDT.hxx"
+//#include "wpbc_resultsRFm1.hxx"
+//#include "wpbc_resultsRFdef.hxx"
+//#include "wpbc_resultsRFbagging.hxx"
+//;
+enum DataSetNames
+{
+    SPECTF,
+    ecoli,
+    glass,
+    ionosphere,
+    iris,
+    /*letter_recognition,*/
+    /*madelon,*/
+    /*magic04,*/
+    /*page_blocks,*/
+    pina_indians_diabetes,
+    segmentation,
+    /*shuttle,*/
+    /*spambase,*/
+    wine
+    //wpbc
+    /*yeast*/
+};
+double _statistics[] = {0.347468, 0.00964554,
+                        0.233222, 0.00376475,
+                        0.356637, 0.00546409,
+                        0.126234, 0.00313297,
+                        0.0632961, 0.00275075,
+                        0.313567, 0.00252546,
+                        0.176406, 0.00497856,
+                        0.0964343, 0.00397317};
+int dataNumFeats[] =
+{
+                            44,
+                             7,
+                             9,
+                            34,
+                             4,
+                            /*16,*/
+                           /*501,*/
+                            /*10,*/
+                            /*10,*/
+                             8,
+                            19,
+                             /*9,*/
+                           /*57,*/
+                            13,
+                            //32
+                             /*8*/
+};
+
+int dataNumSamps[] =
+{
+                              80,
+                             336,
+                             214,
+                             351,
+                             150,
+                           /*20000,*/
+                            /*2000,*/
+                           /*19020,*/
+                            /*5473,*/
+                             768,
+                             210,
+                           /*43500,*/
+                            /*4601,*/
+                             178,
+                             //194
+                            /*1484*/
+};
+
+struct _twotuple{
+    typedef int* type;
+    int* classes;
+    int sze;
+    int* begin(){
+        return classes;
+    }
+    int* end(){
+        return classes+sze;
+    }
+
+    int size(){
+        return sze;
+    }
+    _twotuple(int* a, int s):
+        classes(a),sze(s)
+    {}
+};
+
+#endif
diff --git a/test/classifier/data/RF_data.hxx b/test/classifier/data/RF_data.hxx
new file mode 100644
index 0000000..7945671
--- /dev/null
+++ b/test/classifier/data/RF_data.hxx
@@ -0,0 +1,142 @@
+#ifndef RF_DATA
+#define RF_DATA
+
+#include <vector>
+#include <vigra/multi_array.hxx>
+#include <iostream>
+#include <string>
+#include "RF_common.hxx"
+
+#define LOAD_DATA(name)\
+    {\
+            int a = 0;\
+            vigra::MultiArrayShape<2>::type LabelSize(1, dataNumSamps[name]);\
+            vigra::MultiArrayShape<2>::type FeatureSize(dataNumFeats[name], dataNumSamps[name]);\
+            vigra::MultiArrayShape<2>::type PredictSize(dataNumSamps[name], name##_size);\
+            _labels.push_back(LabelType(LabelSize, name##_labels).transpose());\
+            _features.push_back(FeatureType(FeatureSize, name##_features).transpose());\
+            _ClassIter.push_back(_twotuple(name##_Classes, name##_size));\
+            _names.push_back(#name);\
+            _RFres.push_back(ManagedLabelType(PredictSize, a));\
+    }
+
+
+struct RF_Test_Training_Data
+{
+    typedef vigra::MultiArrayView<2,int, vigra::StridedArrayTag> LabelType;
+    typedef vigra::MultiArrayView<2,double, vigra::StridedArrayTag> FeatureType;
+    typedef vigra::MultiArray<2,double> ManagedLabelType;
+    typedef int* ClassIterType;
+
+    vigra::MultiArrayView<2, double, vigra::StridedArrayTag> _oobRange;
+    std::vector<LabelType> _labels;
+    std::vector<FeatureType> _features;
+    std::vector<_twotuple> _ClassIter;
+    std::vector<std::string> _names;
+    std::vector<ManagedLabelType> _RFres;
+
+    RF_Test_Training_Data()
+    {
+        _oobRange = vigra::MultiArrayView<2, double>( vigra::MultiArrayShape<2>::type(2, this->size()),
+                                                    _statistics                                     ).transpose();
+        _labels.reserve(this->size());
+        _features.reserve(this->size());
+        _ClassIter.reserve(this->size());
+        _names.reserve(this->size());
+        _RFres.reserve(this->size());
+        LOAD_DATA(SPECTF)
+        LOAD_DATA(ecoli)
+        LOAD_DATA(glass)
+        LOAD_DATA(ionosphere)
+        LOAD_DATA(iris)
+        //LOAD_DATA(letter_recognition)
+        //LOAD_DATA(madelon)
+        //LOAD_DATA(magic04)
+        //LOAD_DATA(page_blocks)
+        LOAD_DATA(pina_indians_diabetes)
+        LOAD_DATA(segmentation)
+        //LOAD_DATA(shuttle)
+        //LOAD_DATA(spambase)
+        LOAD_DATA(wine)
+        //LOAD_DATA(wpbc)
+        //LOAD_DATA(yeast)
+/*
+        std::cout << (int)_features[0].shape(0) << " " << _features[0].shape(1);
+        std::cout << "Press Enter to continue...." << std::endl;
+        std::cin.ignore(INT_MAX, '\n');
+        std::cin.get();
+
+
+        for(int ii = 0; ii < features(1).shape(0); ++ii)
+        {
+            for(int jj = 0; jj < features(1).shape(1); ++jj){
+                std::cout << features(1).operator()(ii, jj) << ",\t";
+            }
+            std::cout << std::endl;
+        }
+        std::cout << std::endl <<std::endl;
+        for(int ii = 0; ii < labels(1).shape(0); ++ii)
+        {
+            for(int jj = 0; jj < labels(1).shape(1); ++jj){
+                std::cout << labels(1).operator()(ii, jj) << ",\t";
+            }
+            std::cout << std::endl;
+        }*/
+    }
+
+    LabelType& labels(int index)
+    {
+        vigra_precondition(index > 0 || index < this->size(),
+            "index out of bounds");
+        return _labels[index];
+    }
+
+    double oobError(int index)
+    {
+        vigra_precondition(index > 0 || index < this->size(),
+            "index out of bounds");
+        return _oobRange(index, 0);
+    }
+
+    double oobSTD(int index)
+    {
+        vigra_precondition(index > 0 || index < this->size(),
+            "index out of bounds");
+        return _oobRange(index, 1);
+    }
+
+    FeatureType& features(int index)
+    {
+        vigra_precondition(index > 0 || index < this->size(),
+            "index out of bounds");
+        return _features[index];
+    }
+
+    _twotuple ClassIter(int index)
+    {
+        vigra_precondition(index > 0 || index < this->size(),
+            "index out of bounds");
+        return _ClassIter[index];
+    }
+
+    const std::string names(int index)
+    {
+        vigra_precondition(index > 0 || index < this->size(),
+            "index out of bounds");
+        return _names[index];
+    }
+
+    ManagedLabelType& RFres(int index)
+    {
+        vigra_precondition(index > 0 || index < this->size(),
+            "index out of bounds");
+        return _RFres[index];
+    }
+
+    int size()
+    {
+        return 16-8;
+    }
+};
+
+#endif //RF_DATA
diff --git a/test/classifier/data/SPECTF_features.hxx b/test/classifier/data/SPECTF_features.hxx
new file mode 100644
index 0000000..e52ec5c
--- /dev/null
+++ b/test/classifier/data/SPECTF_features.hxx
@@ -0,0 +1,85 @@
+#ifndef SPECTF_FEATURES
+#define SPECTF_FEATURES
+double SPECTF_features[] = {
+59,52,70,67,73,66,72,61,58,52,72,71,70,77,66,65,67,55,61,57,68,66,72,74,63,64,56,54,67,54,76,74,65,67,66,56,62,56,72,62,74,74,64,67,
+72,62,69,67,78,82,74,65,69,63,70,70,72,74,70,71,72,75,66,65,73,78,74,79,74,69,69,70,71,69,72,70,62,65,65,71,63,60,69,73,67,71,56,58,
+71,62,70,64,67,64,79,65,70,69,72,71,68,65,61,61,73,71,75,74,80,74,54,47,53,37,77,68,72,59,72,68,60,60,73,70,66,65,64,55,61,41,51,46,
+69,71,70,78,61,63,67,65,59,59,66,69,71,75,65,58,60,55,62,59,67,66,74,74,64,60,57,54,70,73,69,76,62,64,61,61,66,65,72,73,68,68,59,63,
+70,66,61,66,61,58,69,69,72,68,62,71,71,71,63,59,74,75,70,69,83,77,73,70,41,37,39,40,58,46,75,73,65,66,67,69,70,66,70,64,60,55,49,41,
+57,69,68,75,69,74,73,71,57,61,72,74,73,69,61,58,60,55,71,62,79,70,77,71,65,63,69,55,61,68,75,74,63,64,63,58,69,67,79,77,72,70,61,65,
+69,66,62,75,67,71,72,76,69,70,66,69,71,80,66,64,71,77,65,61,72,67,71,69,65,57,69,65,68,65,76,73,63,64,69,70,72,72,69,68,70,73,63,59,
+61,60,60,62,64,72,68,67,74,68,76,70,74,71,76,74,74,70,75,66,69,62,65,60,66,65,68,59,64,59,72,65,55,56,66,66,66,60,60,58,60,67,49,52,
+65,62,67,68,65,67,71,71,64,56,73,72,68,69,56,57,67,62,74,66,80,76,80,78,53,47,48,36,68,65,74,73,60,60,67,63,74,63,77,79,68,70,59,56,
+74,73,72,79,66,61,76,66,65,64,78,74,62,57,48,36,62,50,67,63,79,70,61,57,52,36,69,49,55,65,74,73,58,60,64,62,73,69,62,67,60,56,53,46,
+70,69,60,62,58,60,71,77,69,69,73,68,68,70,69,65,76,75,63,64,67,74,56,60,54,44,68,69,68,68,74,73,61,59,68,67,64,68,64,76,64,61,54,49,
+67,66,65,77,66,70,72,72,72,67,76,72,73,76,74,71,74,73,69,61,78,70,76,73,70,70,62,51,70,68,79,77,75,68,72,71,69,63,65,61,73,73,64,67,
+76,69,78,73,68,67,75,70,77,70,79,73,79,75,74,71,76,68,81,79,77,78,75,76,66,76,65,67,67,57,68,75,50,62,62,59,47,49,75,65,74,70,51,48,
+70,69,67,66,68,60,76,77,70,67,71,71,79,79,70,64,77,76,63,54,68,65,72,67,59,52,56,50,67,61,74,72,67,59,68,66,73,68,74,68,77,69,65,62,
+78,73,68,74,68,69,63,74,68,67,73,73,66,71,64,67,66,68,61,66,75,71,60,62,64,66,65,67,66,62,74,75,61,61,63,66,68,65,71,62,69,67,61,59,
+67,51,73,65,69,56,72,63,64,56,68,67,70,62,70,58,68,62,65,59,77,69,68,59,64,55,65,60,70,60,72,65,58,51,66,59,71,62,74,60,76,65,62,56,
+70,54,66,66,76,46,74,58,68,52,81,58,67,58,68,32,73,59,76,51,82,57,76,54,58,30,69,41,59,59,67,73,62,55,60,55,65,56,65,44,73,36,51,28,
+63,63,69,72,67,62,65,57,68,53,68,71,73,78,64,58,61,54,70,61,72,67,72,68,57,55,61,53,66,60,76,77,73,66,66,58,75,70,77,67,78,68,64,58,
+62,56,66,57,74,75,68,59,65,59,74,66,71,65,67,69,66,66,71,72,80,74,71,63,62,72,62,66,66,61,73,68,59,59,63,62,73,73,76,67,77,71,62,58,
+80,74,82,77,74,74,73,77,64,61,73,73,73,72,62,66,66,68,63,61,69,75,70,75,59,64,63,69,66,66,70,77,62,62,60,65,67,66,74,71,66,71,59,62,
+63,58,66,55,56,58,69,74,44,48,63,60,76,67,73,73,58,66,68,63,72,74,70,72,77,75,70,71,71,67,75,73,60,59,71,70,65,62,70,69,71,70,58,61,
+70,65,65,62,68,67,77,74,62,61,66,61,69,74,64,62,71,71,74,70,77,78,69,70,67,65,67,70,49,48,73,71,65,73,73,73,75,71,73,72,73,70,65,64,
+61,63,58,62,56,60,67,75,61,57,64,71,56,59,66,62,73,76,71,75,83,84,69,71,69,69,69,71,49,43,59,64,56,61,64,72,70,73,69,70,65,68,65,62,
+70,64,52,58,75,89,70,72,26,30,46,55,54,59,40,40,39,37,35,17,59,52,66,72,23,46,8,31,17,20,49,72,61,70,31,13,40,23,31,30,57,67,41,57,
+75,71,54,51,53,50,68,69,46,55,11,12,43,48,61,60,73,77,46,45,68,59,65,73,54,60,55,66,54,41,53,52,58,63,72,65,33,23,64,54,36,46,45,52,
+77,61,62,68,62,58,72,68,77,71,76,77,72,75,62,57,77,74,61,58,72,76,69,68,56,53,57,54,69,70,73,79,65,70,66,68,67,66,71,67,60,60,53,57,
+75,72,75,79,72,68,79,77,69,66,73,77,67,73,57,58,69,69,67,65,77,68,69,65,58,54,68,60,67,66,75,78,63,66,68,64,72,69,73,61,52,44,34,37,
+78,76,71,72,65,71,75,74,70,64,65,76,65,73,59,57,65,65,73,73,81,80,68,66,59,44,62,63,62,59,71,74,59,60,64,61,77,76,62,67,44,42,44,30,
+69,68,75,74,78,72,75,72,61,57,72,71,75,72,70,68,68,62,62,66,67,67,74,78,64,68,62,62,64,63,75,77,66,67,69,65,62,63,64,59,74,75,63,67,
+72,66,75,67,61,59,64,63,61,67,75,76,66,48,61,56,69,68,68,68,68,75,69,67,68,71,70,68,48,47,74,79,63,75,62,62,64,67,56,52,69,83,59,73,
+64,64,70,75,70,71,74,71,59,60,62,68,70,66,69,72,69,69,61,63,56,60,62,66,69,71,62,63,67,65,62,58,52,51,67,66,61,56,64,65,71,73,57,63,
+72,63,68,62,72,63,79,61,57,49,76,75,55,57,43,37,54,52,57,56,78,78,57,55,35,37,57,57,41,35,67,70,75,72,53,46,63,62,53,43,38,35,32,26,
+79,78,66,63,69,62,78,70,72,71,73,78,75,65,68,62,76,71,68,68,72,71,52,48,23,26,66,59,66,66,72,74,56,58,67,63,66,69,70,74,34,33,11,12,
+66,81,75,72,69,67,74,81,67,73,76,75,69,64,58,57,74,74,56,62,74,78,55,50,37,38,65,73,61,61,73,73,61,63,67,66,60,71,46,58,35,37,24,20,
+65,66,71,72,67,75,76,83,70,74,70,76,70,68,63,71,69,76,72,73,76,80,69,68,57,59,59,56,62,68,75,73,65,61,69,73,66,70,63,65,65,67,53,42,
+71,75,76,74,71,68,67,68,69,75,75,74,59,58,71,69,70,74,74,72,71,78,69,72,69,72,63,61,59,70,72,75,61,66,70,71,59,64,64,60,72,61,55,63,
+70,66,66,68,71,69,64,61,68,67,50,53,73,71,73,63,71,73,80,81,82,82,67,71,52,47,67,64,66,67,66,75,58,62,65,65,71,67,70,71,67,64,52,53,
+73,76,68,74,56,59,73,76,54,48,75,78,47,53,25,19,60,56,56,54,80,79,47,53,19,14,58,50,67,71,63,54,49,48,66,65,62,58,57,72,31,30,15,11,
+68,76,79,78,63,73,68,78,64,71,73,77,67,71,58,57,61,63,52,64,64,74,53,72,36,44,52,54,49,56,73,81,65,80,53,60,63,70,58,64,52,57,49,50,
+68,64,65,68,63,64,77,73,75,72,80,77,70,71,61,61,73,68,63,62,76,73,69,69,48,59,62,44,66,59,75,74,64,64,63,61,70,69,74,67,51,48,45,45,
+62,67,64,70,59,58,67,74,60,66,68,68,73,71,60,63,64,74,64,65,74,77,69,73,59,58,58,67,65,69,78,76,61,62,64,67,72,74,71,71,71,69,66,61,
+62,67,68,70,65,70,73,77,69,70,69,73,71,74,71,71,76,75,66,67,73,73,70,74,63,67,58,68,66,69,78,79,69,70,71,73,72,71,73,77,72,76,64,66,
+59,68,69,67,69,59,78,73,66,65,77,73,74,66,66,55,71,66,69,68,75,73,80,79,69,65,69,66,68,65,75,71,59,61,65,64,73,71,81,75,74,65,69,66,
+75,75,70,77,67,75,75,75,67,66,74,73,68,72,64,70,76,70,67,63,74,75,72,68,69,68,75,69,71,74,75,76,63,70,71,69,66,63,70,73,66,68,58,59,
+77,79,79,77,74,76,76,81,65,68,66,66,74,73,72,68,67,73,63,62,72,67,76,69,68,64,64,61,69,68,73,75,70,66,64,70,70,70,73,76,79,73,65,63,
+68,64,74,80,76,72,78,75,67,64,75,80,78,77,66,64,67,67,70,60,78,82,70,68,63,60,64,60,54,56,70,73,59,65,55,58,50,51,73,70,69,65,42,41,
+76,73,74,76,60,69,76,76,68,69,78,79,57,62,69,69,67,66,73,69,80,81,58,68,75,69,73,70,58,65,79,76,74,71,66,64,65,62,78,68,75,68,62,60,
+61,76,71,68,77,69,77,69,64,75,71,81,75,72,71,69,70,73,61,71,69,79,64,65,62,66,61,65,71,68,67,71,59,64,66,65,60,68,74,71,69,68,63,59,
+67,65,77,74,67,66,67,70,65,64,75,78,66,74,62,60,65,65,73,72,75,76,74,81,66,65,65,63,63,67,76,80,63,64,63,64,73,72,76,75,72,74,65,64,
+71,61,74,74,76,74,69,56,68,78,71,78,58,64,70,72,71,68,72,71,79,78,67,68,63,60,67,67,76,74,67,79,67,71,71,64,70,74,83,76,74,73,54,54,
+64,70,71,69,72,70,75,78,61,66,69,68,68,70,71,70,75,76,73,72,80,78,79,81,74,70,72,79,73,75,77,73,65,64,72,72,59,62,71,74,68,67,58,57,
+76,75,68,78,71,72,72,75,61,65,67,70,67,75,60,58,63,67,59,63,67,72,74,73,56,56,52,52,67,68,73,78,65,68,61,67,69,74,77,75,74,70,63,61,
+74,73,72,75,63,62,67,67,73,74,75,79,70,71,64,67,65,69,79,78,81,80,71,73,60,62,69,67,69,69,75,75,66,67,67,66,71,73,66,69,62,65,55,56,
+65,67,69,76,62,68,65,66,65,64,74,73,60,75,66,63,64,62,73,65,77,74,69,69,66,59,68,59,69,69,76,79,65,63,60,60,69,64,69,74,69,70,62,57,
+59,75,70,76,62,70,65,74,65,67,75,76,70,73,63,61,74,67,78,69,75,73,70,68,67,64,79,68,70,75,76,77,59,63,72,69,64,64,65,72,61,61,51,55,
+76,72,73,69,67,73,74,72,60,65,73,66,66,73,68,67,69,70,60,58,66,76,69,75,65,64,63,60,74,71,77,79,61,68,71,70,62,63,73,76,62,69,52,59,
+71,75,78,78,68,67,75,72,67,68,72,75,74,74,67,66,66,67,66,66,78,80,73,75,67,72,67,67,67,65,77,78,61,64,63,66,51,57,77,67,78,76,60,59,
+80,76,75,75,69,68,74,75,77,77,76,78,74,70,66,65,67,75,74,73,74,77,68,67,61,58,60,67,61,63,75,75,66,62,59,61,77,74,69,67,65,66,61,58,
+68,70,66,72,63,71,77,82,61,63,61,62,61,65,65,62,72,77,69,73,72,78,74,77,69,69,77,74,64,63,66,70,58,60,65,69,75,77,77,77,69,77,65,64,
+67,57,73,78,63,68,72,73,61,59,59,76,71,72,69,66,70,68,65,77,79,68,71,75,62,66,70,78,68,69,70,76,65,65,66,67,62,72,69,72,70,68,60,59,
+72,74,67,69,69,70,74,81,66,70,73,78,69,80,65,65,70,77,69,70,73,79,64,68,56,58,67,64,68,68,69,74,62,67,66,70,73,77,74,77,71,72,63,65,
+62,71,78,84,64,68,72,74,53,57,71,70,71,72,54,53,63,67,54,57,71,71,70,74,54,57,54,57,62,64,75,72,62,65,60,64,64,67,72,77,62,62,61,65,
+69,78,74,76,70,67,69,73,68,75,75,76,71,77,58,61,66,70,67,72,76,72,56,62,56,61,57,62,67,73,76,74,58,63,64,68,66,76,70,72,64,68,60,56,
+59,65,53,60,72,74,67,69,64,67,64,65,71,70,68,71,72,70,70,70,75,78,72,71,71,71,67,64,67,71,71,74,62,66,72,73,57,57,64,71,70,69,53,49,
+66,67,63,70,69,70,73,72,61,62,68,68,70,71,71,67,71,69,65,65,76,78,71,70,65,64,68,71,70,71,73,74,58,63,68,71,70,72,77,79,79,79,66,66,
+62,66,66,68,73,76,68,71,62,62,63,68,74,75,63,68,71,68,58,58,65,66,65,76,64,70,63,60,70,72,71,77,67,69,72,71,63,63,70,72,75,79,62,59,
+71,71,69,71,65,65,76,73,67,66,69,79,76,76,63,62,74,71,58,66,76,78,78,74,68,66,69,68,68,68,71,74,59,57,65,66,73,71,78,74,68,70,57,55,
+63,61,75,72,68,71,69,70,64,56,70,75,76,73,70,72,76,73,68,68,79,76,68,76,66,73,58,68,72,75,72,75,65,61,66,67,58,57,72,72,68,71,57,58,
+74,81,80,78,70,69,74,77,69,71,73,76,68,68,62,61,68,68,67,70,74,80,68,74,57,62,57,65,61,65,71,76,63,65,67,67,70,74,63,72,68,70,61,64,
+69,64,73,72,49,70,66,71,57,56,64,62,76,74,65,62,63,58,63,63,75,76,78,80,75,77,51,62,74,68,77,77,70,68,68,64,59,58,69,66,74,75,62,59,
+70,64,68,67,76,68,76,69,67,64,69,65,62,65,70,67,74,68,65,65,74,75,64,69,63,63,64,64,56,61,62,68,66,66,62,58,57,48,75,64,79,74,59,58,
+65,68,70,78,65,72,72,74,64,69,71,73,72,68,62,62,65,62,72,75,79,78,72,76,66,67,62,61,68,76,72,78,65,64,67,63,64,67,67,77,66,66,59,57,
+64,53,74,70,65,63,70,70,57,57,64,64,73,74,65,59,65,63,63,62,72,73,79,76,75,68,60,58,69,66,72,76,64,65,63,65,63,65,75,80,74,67,71,67,
+70,71,71,74,68,66,72,70,66,69,74,72,70,69,64,66,73,72,75,73,81,81,76,75,71,70,74,82,69,72,76,74,60,56,66,66,64,64,73,72,66,63,54,58,
+72,70,75,80,73,70,76,73,66,56,72,70,73,75,67,65,69,69,73,72,81,77,80,79,67,64,64,66,69,68,70,75,63,59,66,63,74,77,81,78,79,75,65,66,
+70,75,72,72,67,71,71,78,63,67,73,76,71,74,59,61,67,64,74,71,77,77,70,72,61,61,62,58,63,69,76,75,64,65,66,67,68,70,70,71,64,67,56,54,
+59,57,67,71,66,68,68,70,56,62,77,61,67,71,75,71,67,64,62,54,64,75,71,72,76,79,75,70,71,77,71,69,56,54,62,64,56,53,71,68,64,63,56,56,
+67,64,73,75,77,77,74,70,65,62,74,75,65,67,68,70,66,69,67,60,74,75,62,64,66,71,62,61,64,69,73,76,64,66,61,64,65,60,68,75,74,80,67,68,
+68,65,72,72,47,74,76,74,67,66,71,69,69,67,63,64,68,68,70,74,77,77,73,60,49,48,42,69,70,69,76,79,63,66,64,69,71,73,73,75,68,56,58,44,
+66,54,69,66,69,69,75,72,63,62,68,66,68,70,71,68,70,69,66,68,73,72,65,73,67,63,60,57,70,68,75,75,65,67,69,65,65,64,67,69,71,68,59,59
+};
+#endif
diff --git a/test/classifier/data/SPECTF_labels.hxx b/test/classifier/data/SPECTF_labels.hxx
new file mode 100644
index 0000000..a0bfdfa
--- /dev/null
+++ b/test/classifier/data/SPECTF_labels.hxx
@@ -0,0 +1,89 @@
+#ifndef SPECTF_LABELS
+#define SPECTF_LABELS
+
+int SPECTF_labels[] = {
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0
+};
+
+int SPECTF_Classes[] = {0,1};
+int SPECTF_size = 2;
+#endif
diff --git a/test/classifier/data/ecoli_features.hxx b/test/classifier/data/ecoli_features.hxx
new file mode 100644
index 0000000..0cc72bf
--- /dev/null
+++ b/test/classifier/data/ecoli_features.hxx
@@ -0,0 +1,341 @@
+#ifndef ECOLI_FEATURES
+#define ECOLI_FEATURES
+double ecoli_features[] = {
+0.49,0.29,0.48,0.5,0.56,0.24,0.35,
+0.07,0.4,0.48,0.5,0.54,0.35,0.44,
+0.56,0.4,0.48,0.5,0.49,0.37,0.46,
+0.59,0.49,0.48,0.5,0.52,0.45,0.36,
+0.23,0.32,0.48,0.5,0.55,0.25,0.35,
+0.67,0.39,0.48,0.5,0.36,0.38,0.46,
+0.29,0.28,0.48,0.5,0.44,0.23,0.34,
+0.21,0.34,0.48,0.5,0.51,0.28,0.39,
+0.2,0.44,0.48,0.5,0.46,0.51,0.57,
+0.42,0.4,0.48,0.5,0.56,0.18,0.3,
+0.42,0.24,0.48,0.5,0.57,0.27,0.37,
+0.25,0.48,0.48,0.5,0.44,0.17,0.29,
+0.39,0.32,0.48,0.5,0.46,0.24,0.35,
+0.51,0.5,0.48,0.5,0.46,0.32,0.35,
+0.22,0.43,0.48,0.5,0.48,0.16,0.28,
+0.25,0.4,0.48,0.5,0.46,0.44,0.52,
+0.34,0.45,0.48,0.5,0.38,0.24,0.35,
+0.44,0.27,0.48,0.5,0.55,0.52,0.58,
+0.23,0.4,0.48,0.5,0.39,0.28,0.38,
+0.41,0.57,0.48,0.5,0.39,0.21,0.32,
+0.4,0.45,0.48,0.5,0.38,0.22,0,
+0.31,0.23,0.48,0.5,0.73,0.05,0.14,
+0.51,0.54,0.48,0.5,0.41,0.34,0.43,
+0.3,0.16,0.48,0.5,0.56,0.11,0.23,
+0.36,0.39,0.48,0.5,0.48,0.22,0.23,
+0.29,0.37,0.48,0.5,0.48,0.44,0.52,
+0.25,0.4,0.48,0.5,0.47,0.33,0.42,
+0.21,0.51,0.48,0.5,0.5,0.32,0.41,
+0.43,0.37,0.48,0.5,0.53,0.35,0.44,
+0.43,0.39,0.48,0.5,0.47,0.31,0.41,
+0.53,0.38,0.48,0.5,0.44,0.26,0.36,
+0.34,0.33,0.48,0.5,0.38,0.35,0.44,
+0.56,0.51,0.48,0.5,0.34,0.37,0.46,
+0.4,0.29,0.48,0.5,0.42,0.35,0.44,
+0.24,0.35,0.48,0.5,0.31,0.19,0.31,
+0.36,0.54,0.48,0.5,0.41,0.38,0.46,
+0.29,0.52,0.48,0.5,0.42,0.29,0.39,
+0.65,0.47,0.48,0.5,0.59,0.3,0.4,
+0.32,0.42,0.48,0.5,0.35,0.28,0.38,
+0.38,0.46,0.48,0.5,0.48,0.22,0.29,
+0.33,0.45,0.48,0.5,0.52,0.32,0.41,
+0.3,0.37,0.48,0.5,0.59,0.41,0.49,
+0.4,0.5,0.48,0.5,0.45,0.39,0.47,
+0.28,0.38,0.48,0.5,0.5,0.33,0.42,
+0.61,0.45,0.48,0.5,0.48,0.35,0.41,
+0.17,0.38,0.48,0.5,0.45,0.42,0.5,
+0.44,0.35,0.48,0.5,0.55,0.55,0.61,
+0.43,0.4,0.48,0.5,0.39,0.28,0.39,
+0.42,0.35,0.48,0.5,0.58,0.15,0.27,
+0.23,0.33,0.48,0.5,0.43,0.33,0.43,
+0.37,0.52,0.48,0.5,0.42,0.42,0.36,
+0.29,0.3,0.48,0.5,0.45,0.03,0.17,
+0.22,0.36,0.48,0.5,0.35,0.39,0.47,
+0.23,0.58,0.48,0.5,0.37,0.53,0.59,
+0.47,0.47,0.48,0.5,0.22,0.16,0.26,
+0.54,0.47,0.48,0.5,0.28,0.33,0.42,
+0.51,0.37,0.48,0.5,0.35,0.36,0.45,
+0.4,0.35,0.48,0.5,0.45,0.33,0.42,
+0.44,0.34,0.48,0.5,0.3,0.33,0.43,
+0.42,0.38,0.48,0.5,0.54,0.34,0.43,
+0.44,0.56,0.48,0.5,0.5,0.46,0.54,
+0.52,0.36,0.48,0.5,0.41,0.28,0.38,
+0.36,0.41,0.48,0.5,0.48,0.47,0.54,
+0.18,0.3,0.48,0.5,0.46,0.24,0.35,
+0.47,0.29,0.48,0.5,0.51,0.33,0.43,
+0.24,0.43,0.48,0.5,0.54,0.52,0.59,
+0.25,0.37,0.48,0.5,0.41,0.33,0.42,
+0.52,0.57,0.48,0.5,0.42,0.47,0.54,
+0.25,0.37,0.48,0.5,0.43,0.26,0.36,
+0.35,0.48,0.48,0.5,0.56,0.4,0.48,
+0.26,0.26,0.48,0.5,0.34,0.25,0.35,
+0.44,0.51,0.48,0.5,0.47,0.26,0.36,
+0.37,0.5,0.48,0.5,0.42,0.36,0.45,
+0.44,0.42,0.48,0.5,0.42,0.25,0.2,
+0.24,0.43,0.48,0.5,0.37,0.28,0.38,
+0.42,0.3,0.48,0.5,0.48,0.26,0.36,
+0.48,0.42,0.48,0.5,0.45,0.25,0.35,
+0.41,0.48,0.48,0.5,0.51,0.44,0.51,
+0.44,0.28,0.48,0.5,0.43,0.27,0.37,
+0.29,0.41,0.48,0.5,0.48,0.38,0.46,
+0.34,0.28,0.48,0.5,0.41,0.35,0.44,
+0.41,0.43,0.48,0.5,0.45,0.31,0.41,
+0.29,0.47,0.48,0.5,0.41,0.23,0.34,
+0.34,0.55,0.48,0.5,0.58,0.31,0.41,
+0.36,0.56,0.48,0.5,0.43,0.45,0.53,
+0.4,0.46,0.48,0.5,0.52,0.49,0.56,
+0.5,0.49,0.48,0.5,0.49,0.46,0.53,
+0.52,0.44,0.48,0.5,0.37,0.36,0.42,
+0.5,0.51,0.48,0.5,0.27,0.23,0.34,
+0.53,0.42,0.48,0.5,0.16,0.29,0.39,
+0.34,0.46,0.48,0.5,0.52,0.35,0.44,
+0.4,0.42,0.48,0.5,0.37,0.27,0.27,
+0.41,0.43,0.48,0.5,0.5,0.24,0.25,
+0.3,0.45,0.48,0.5,0.36,0.21,0.32,
+0.31,0.47,0.48,0.5,0.29,0.28,0.39,
+0.64,0.76,0.48,0.5,0.45,0.35,0.38,
+0.35,0.37,0.48,0.5,0.3,0.34,0.43,
+0.57,0.54,0.48,0.5,0.37,0.28,0.33,
+0.65,0.55,0.48,0.5,0.34,0.37,0.28,
+0.51,0.46,0.48,0.5,0.58,0.31,0.41,
+0.38,0.4,0.48,0.5,0.63,0.25,0.35,
+0.24,0.57,0.48,0.5,0.63,0.34,0.43,
+0.38,0.26,0.48,0.5,0.54,0.16,0.28,
+0.33,0.47,0.48,0.5,0.53,0.18,0.29,
+0.24,0.34,0.48,0.5,0.38,0.3,0.4,
+0.26,0.5,0.48,0.5,0.44,0.32,0.41,
+0.44,0.49,0.48,0.5,0.39,0.38,0.4,
+0.43,0.32,0.48,0.5,0.33,0.45,0.52,
+0.49,0.43,0.48,0.5,0.49,0.3,0.4,
+0.47,0.28,0.48,0.5,0.56,0.2,0.25,
+0.32,0.33,0.48,0.5,0.6,0.06,0.2,
+0.34,0.35,0.48,0.5,0.51,0.49,0.56,
+0.35,0.34,0.48,0.5,0.46,0.3,0.27,
+0.38,0.3,0.48,0.5,0.43,0.29,0.39,
+0.38,0.44,0.48,0.5,0.43,0.2,0.31,
+0.41,0.51,0.48,0.5,0.58,0.2,0.31,
+0.34,0.42,0.48,0.5,0.41,0.34,0.43,
+0.51,0.49,0.48,0.5,0.53,0.14,0.26,
+0.25,0.51,0.48,0.5,0.37,0.42,0.5,
+0.29,0.28,0.48,0.5,0.5,0.42,0.5,
+0.25,0.26,0.48,0.5,0.39,0.32,0.42,
+0.24,0.41,0.48,0.5,0.49,0.23,0.34,
+0.17,0.39,0.48,0.5,0.53,0.3,0.39,
+0.04,0.31,0.48,0.5,0.41,0.29,0.39,
+0.61,0.36,0.48,0.5,0.49,0.35,0.44,
+0.34,0.51,0.48,0.5,0.44,0.37,0.46,
+0.28,0.33,0.48,0.5,0.45,0.22,0.33,
+0.4,0.46,0.48,0.5,0.42,0.35,0.44,
+0.23,0.34,0.48,0.5,0.43,0.26,0.37,
+0.37,0.44,0.48,0.5,0.42,0.39,0.47,
+0,0.38,0.48,0.5,0.42,0.48,0.55,
+0.39,0.31,0.48,0.5,0.38,0.34,0.43,
+0.3,0.44,0.48,0.5,0.49,0.22,0.33,
+0.27,0.3,0.48,0.5,0.71,0.28,0.39,
+0.17,0.52,0.48,0.5,0.49,0.37,0.46,
+0.36,0.42,0.48,0.5,0.53,0.32,0.41,
+0.3,0.37,0.48,0.5,0.43,0.18,0.3,
+0.26,0.4,0.48,0.5,0.36,0.26,0.37,
+0.4,0.41,0.48,0.5,0.55,0.22,0.33,
+0.22,0.34,0.48,0.5,0.42,0.29,0.39,
+0.44,0.35,0.48,0.5,0.44,0.52,0.59,
+0.27,0.42,0.48,0.5,0.37,0.38,0.43,
+0.16,0.43,0.48,0.5,0.54,0.27,0.37,
+0.06,0.61,0.48,0.5,0.49,0.92,0.37,
+0.44,0.52,0.48,0.5,0.43,0.47,0.54,
+0.63,0.47,0.48,0.5,0.51,0.82,0.84,
+0.23,0.48,0.48,0.5,0.59,0.88,0.89,
+0.34,0.49,0.48,0.5,0.58,0.85,0.8,
+0.43,0.4,0.48,0.5,0.58,0.75,0.78,
+0.46,0.61,0.48,0.5,0.48,0.86,0.87,
+0.27,0.35,0.48,0.5,0.51,0.77,0.79,
+0.52,0.39,0.48,0.5,0.65,0.71,0.73,
+0.29,0.47,0.48,0.5,0.71,0.65,0.69,
+0.55,0.47,0.48,0.5,0.57,0.78,0.8,
+0.12,0.67,0.48,0.5,0.74,0.58,0.63,
+0.4,0.5,0.48,0.5,0.65,0.82,0.84,
+0.73,0.36,0.48,0.5,0.53,0.91,0.92,
+0.84,0.44,0.48,0.5,0.48,0.71,0.74,
+0.48,0.45,0.48,0.5,0.6,0.78,0.8,
+0.54,0.49,0.48,0.5,0.4,0.87,0.88,
+0.48,0.41,0.48,0.5,0.51,0.9,0.88,
+0.5,0.66,0.48,0.5,0.31,0.92,0.92,
+0.72,0.46,0.48,0.5,0.51,0.66,0.7,
+0.47,0.55,0.48,0.5,0.58,0.71,0.75,
+0.33,0.56,0.48,0.5,0.33,0.78,0.8,
+0.64,0.58,0.48,0.5,0.48,0.78,0.73,
+0.54,0.57,0.48,0.5,0.56,0.81,0.83,
+0.47,0.59,0.48,0.5,0.52,0.76,0.79,
+0.63,0.5,0.48,0.5,0.59,0.85,0.86,
+0.49,0.42,0.48,0.5,0.53,0.79,0.81,
+0.31,0.5,0.48,0.5,0.57,0.84,0.85,
+0.74,0.44,0.48,0.5,0.55,0.88,0.89,
+0.33,0.45,0.48,0.5,0.45,0.88,0.89,
+0.45,0.4,0.48,0.5,0.61,0.74,0.77,
+0.71,0.4,0.48,0.5,0.71,0.7,0.74,
+0.5,0.37,0.48,0.5,0.66,0.64,0.69,
+0.66,0.53,0.48,0.5,0.59,0.66,0.66,
+0.6,0.61,0.48,0.5,0.54,0.67,0.71,
+0.83,0.37,0.48,0.5,0.61,0.71,0.74,
+0.34,0.51,0.48,0.5,0.67,0.9,0.9,
+0.63,0.54,0.48,0.5,0.65,0.79,0.81,
+0.7,0.4,0.48,0.5,0.56,0.86,0.83,
+0.6,0.5,1,0.5,0.54,0.77,0.8,
+0.16,0.51,0.48,0.5,0.33,0.39,0.48,
+0.74,0.7,0.48,0.5,0.66,0.65,0.69,
+0.2,0.46,0.48,0.5,0.57,0.78,0.81,
+0.89,0.55,0.48,0.5,0.51,0.72,0.76,
+0.7,0.46,0.48,0.5,0.56,0.78,0.73,
+0.12,0.43,0.48,0.5,0.63,0.7,0.74,
+0.61,0.52,0.48,0.5,0.54,0.67,0.52,
+0.33,0.37,0.48,0.5,0.46,0.65,0.69,
+0.63,0.65,0.48,0.5,0.66,0.67,0.71,
+0.41,0.51,0.48,0.5,0.53,0.75,0.78,
+0.34,0.67,0.48,0.5,0.52,0.76,0.79,
+0.58,0.34,0.48,0.5,0.56,0.87,0.81,
+0.59,0.56,0.48,0.5,0.55,0.8,0.82,
+0.51,0.4,0.48,0.5,0.57,0.62,0.67,
+0.5,0.57,0.48,0.5,0.71,0.61,0.66,
+0.6,0.46,0.48,0.5,0.45,0.81,0.83,
+0.37,0.47,0.48,0.5,0.39,0.76,0.79,
+0.58,0.55,0.48,0.5,0.57,0.7,0.74,
+0.36,0.47,0.48,0.5,0.51,0.69,0.72,
+0.39,0.41,0.48,0.5,0.52,0.72,0.75,
+0.35,0.51,0.48,0.5,0.61,0.71,0.74,
+0.31,0.44,0.48,0.5,0.5,0.79,0.82,
+0.61,0.66,0.48,0.5,0.46,0.87,0.88,
+0.48,0.49,0.48,0.5,0.52,0.77,0.71,
+0.11,0.5,0.48,0.5,0.58,0.72,0.68,
+0.31,0.36,0.48,0.5,0.58,0.94,0.94,
+0.68,0.51,0.48,0.5,0.71,0.75,0.78,
+0.69,0.39,0.48,0.5,0.57,0.76,0.79,
+0.52,0.54,0.48,0.5,0.62,0.76,0.79,
+0.46,0.59,0.48,0.5,0.36,0.76,0.23,
+0.36,0.45,0.48,0.5,0.38,0.79,0.17,
+0,0.51,0.48,0.5,0.35,0.67,0.44,
+0.1,0.49,0.48,0.5,0.41,0.67,0.21,
+0.3,0.51,0.48,0.5,0.42,0.61,0.34,
+0.61,0.47,0.48,0.5,0,0.8,0.32,
+0.63,0.75,0.48,0.5,0.64,0.73,0.66,
+0.71,0.52,0.48,0.5,0.64,1,0.99,
+0.85,0.53,0.48,0.5,0.53,0.52,0.35,
+0.63,0.49,0.48,0.5,0.54,0.76,0.79,
+0.75,0.55,1,1,0.4,0.47,0.3,
+0.7,0.39,1,0.5,0.51,0.82,0.84,
+0.72,0.42,0.48,0.5,0.65,0.77,0.79,
+0.79,0.41,0.48,0.5,0.66,0.81,0.83,
+0.83,0.48,0.48,0.5,0.65,0.76,0.79,
+0.69,0.43,0.48,0.5,0.59,0.74,0.77,
+0.79,0.36,0.48,0.5,0.46,0.82,0.7,
+0.78,0.33,0.48,0.5,0.57,0.77,0.79,
+0.75,0.37,0.48,0.5,0.64,0.7,0.74,
+0.59,0.29,0.48,0.5,0.64,0.75,0.77,
+0.67,0.37,0.48,0.5,0.54,0.64,0.68,
+0.66,0.48,0.48,0.5,0.54,0.7,0.74,
+0.64,0.46,0.48,0.5,0.48,0.73,0.76,
+0.76,0.71,0.48,0.5,0.5,0.71,0.75,
+0.84,0.49,0.48,0.5,0.55,0.78,0.74,
+0.77,0.55,0.48,0.5,0.51,0.78,0.74,
+0.81,0.44,0.48,0.5,0.42,0.67,0.68,
+0.58,0.6,0.48,0.5,0.59,0.73,0.76,
+0.63,0.42,0.48,0.5,0.48,0.77,0.8,
+0.62,0.42,0.48,0.5,0.58,0.79,0.81,
+0.86,0.39,0.48,0.5,0.59,0.89,0.9,
+0.81,0.53,0.48,0.5,0.57,0.87,0.88,
+0.87,0.49,0.48,0.5,0.61,0.76,0.79,
+0.47,0.46,0.48,0.5,0.62,0.74,0.77,
+0.76,0.41,0.48,0.5,0.5,0.59,0.62,
+0.7,0.53,0.48,0.5,0.7,0.86,0.87,
+0.64,0.45,0.48,0.5,0.67,0.61,0.66,
+0.81,0.52,0.48,0.5,0.57,0.78,0.8,
+0.73,0.26,0.48,0.5,0.57,0.75,0.78,
+0.49,0.61,1,0.5,0.56,0.71,0.74,
+0.88,0.42,0.48,0.5,0.52,0.73,0.75,
+0.84,0.54,0.48,0.5,0.75,0.92,0.7,
+0.63,0.51,0.48,0.5,0.64,0.72,0.76,
+0.86,0.55,0.48,0.5,0.63,0.81,0.83,
+0.79,0.54,0.48,0.5,0.5,0.66,0.68,
+0.57,0.38,0.48,0.5,0.06,0.49,0.33,
+0.78,0.44,0.48,0.5,0.45,0.73,0.68,
+0.78,0.68,0.48,0.5,0.83,0.4,0.29,
+0.63,0.69,0.48,0.5,0.65,0.41,0.28,
+0.67,0.88,0.48,0.5,0.73,0.5,0.25,
+0.61,0.75,0.48,0.5,0.51,0.33,0.33,
+0.67,0.84,0.48,0.5,0.74,0.54,0.37,
+0.74,0.9,0.48,0.5,0.57,0.53,0.29,
+0.73,0.84,0.48,0.5,0.86,0.58,0.29,
+0.75,0.76,0.48,0.5,0.83,0.57,0.3,
+0.77,0.57,0.48,0.5,0.88,0.53,0.2,
+0.74,0.78,0.48,0.5,0.75,0.54,0.15,
+0.68,0.76,0.48,0.5,0.84,0.45,0.27,
+0.56,0.68,0.48,0.5,0.77,0.36,0.45,
+0.65,0.51,0.48,0.5,0.66,0.54,0.33,
+0.52,0.81,0.48,0.5,0.72,0.38,0.38,
+0.64,0.57,0.48,0.5,0.7,0.33,0.26,
+0.6,0.76,1,0.5,0.77,0.59,0.52,
+0.69,0.59,0.48,0.5,0.77,0.39,0.21,
+0.63,0.49,0.48,0.5,0.79,0.45,0.28,
+0.71,0.71,0.48,0.5,0.68,0.43,0.36,
+0.68,0.63,0.48,0.5,0.73,0.4,0.3,
+0.77,0.57,1,0.5,0.37,0.54,0.01,
+0.66,0.49,1,0.5,0.54,0.56,0.36,
+0.71,0.46,1,0.5,0.52,0.59,0.3,
+0.67,0.55,1,0.5,0.66,0.58,0.16,
+0.68,0.49,1,0.5,0.62,0.55,0.28,
+0.74,0.49,0.48,0.5,0.42,0.54,0.36,
+0.7,0.61,0.48,0.5,0.56,0.52,0.43,
+0.66,0.86,0.48,0.5,0.34,0.41,0.36,
+0.73,0.78,0.48,0.5,0.58,0.51,0.31,
+0.65,0.57,0.48,0.5,0.47,0.47,0.51,
+0.72,0.86,0.48,0.5,0.17,0.55,0.21,
+0.67,0.7,0.48,0.5,0.46,0.45,0.33,
+0.67,0.81,0.48,0.5,0.54,0.49,0.23,
+0.67,0.61,0.48,0.5,0.51,0.37,0.38,
+0.63,1,0.48,0.5,0.35,0.51,0.49,
+0.57,0.59,0.48,0.5,0.39,0.47,0.33,
+0.71,0.71,0.48,0.5,0.4,0.54,0.39,
+0.66,0.74,0.48,0.5,0.31,0.38,0.43,
+0.67,0.81,0.48,0.5,0.25,0.42,0.25,
+0.64,0.72,0.48,0.5,0.49,0.42,0.19,
+0.68,0.82,0.48,0.5,0.38,0.65,0.56,
+0.32,0.39,0.48,0.5,0.53,0.28,0.38,
+0.7,0.64,0.48,0.5,0.47,0.51,0.47,
+0.63,0.57,0.48,0.5,0.49,0.7,0.2,
+0.74,0.82,0.48,0.5,0.49,0.49,0.41,
+0.63,0.86,0.48,0.5,0.39,0.47,0.34,
+0.63,0.83,0.48,0.5,0.4,0.39,0.19,
+0.63,0.71,0.48,0.5,0.6,0.4,0.39,
+0.71,0.86,0.48,0.5,0.4,0.54,0.32,
+0.68,0.78,0.48,0.5,0.43,0.44,0.42,
+0.64,0.84,0.48,0.5,0.37,0.45,0.4,
+0.74,0.47,0.48,0.5,0.5,0.57,0.42,
+0.75,0.84,0.48,0.5,0.35,0.52,0.33,
+0.63,0.65,0.48,0.5,0.39,0.44,0.35,
+0.69,0.67,0.48,0.5,0.3,0.39,0.24,
+0.7,0.71,0.48,0.5,0.42,0.84,0.85,
+0.69,0.8,0.48,0.5,0.46,0.57,0.26,
+0.64,0.66,0.48,0.5,0.41,0.39,0.2,
+0.63,0.8,0.48,0.5,0.46,0.31,0.29,
+0.66,0.71,0.48,0.5,0.41,0.5,0.35,
+0.69,0.59,0.48,0.5,0.46,0.44,0.52,
+0.68,0.67,0.48,0.5,0.49,0.4,0.34,
+0.64,0.78,0.48,0.5,0.5,0.36,0.38,
+0.62,0.78,0.48,0.5,0.47,0.49,0.54,
+0.76,0.73,0.48,0.5,0.44,0.39,0.39,
+0.64,0.81,0.48,0.5,0.37,0.39,0.44,
+0.29,0.39,0.48,0.5,0.52,0.4,0.48,
+0.62,0.83,0.48,0.5,0.46,0.36,0.4,
+0.56,0.54,0.48,0.5,0.43,0.37,0.3,
+0.69,0.66,0.48,0.5,0.41,0.5,0.25,
+0.69,0.65,0.48,0.5,0.63,0.48,0.41,
+0.43,0.59,0.48,0.5,0.52,0.49,0.56,
+0.74,0.56,0.48,0.5,0.47,0.68,0.3,
+0.71,0.57,0.48,0.5,0.48,0.35,0.32,
+0.61,0.6,0.48,0.5,0.44,0.39,0.38,
+0.59,0.61,0.48,0.5,0.42,0.42,0.37,
+0.74,0.74,0.48,0.5,0.31,0.53,0.52
+};
+#endif
diff --git a/test/classifier/data/ecoli_labels.hxx b/test/classifier/data/ecoli_labels.hxx
new file mode 100644
index 0000000..497c171
--- /dev/null
+++ b/test/classifier/data/ecoli_labels.hxx
@@ -0,0 +1,344 @@
+#ifndef ECOLI_LABELS
+#define ECOLI_LABELS
+int ecoli_labels[] = {
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+4,
+4,
+3,
+3,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+7,
+7,
+7,
+7,
+7,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8,
+8
+};
+
+int ecoli_Classes[] = {1, 2 , 3,4,5,6,7,8};
+int ecoli_size = 8;
+#endif
diff --git a/test/classifier/data/glass_features.hxx b/test/classifier/data/glass_features.hxx
new file mode 100644
index 0000000..7d44cae
--- /dev/null
+++ b/test/classifier/data/glass_features.hxx
@@ -0,0 +1,219 @@
+#ifndef GLASS_FEATURES
+#define GLASS_FEATURES
+double glass_features[] = {
+1.521,13.64,4.49,1.1,71.78,0.06,8.75,0,0,
+1.5176,13.89,3.6,1.36,72.73,0.48,7.83,0,0,
+1.5162,13.53,3.55,1.54,72.99,0.39,7.78,0,0,
+1.5177,13.21,3.69,1.29,72.61,0.57,8.22,0,0,
+1.5174,13.27,3.62,1.24,73.08,0.55,8.07,0,0,
+1.516,12.79,3.61,1.62,72.97,0.64,8.07,0,0.26,
+1.5174,13.3,3.6,1.14,73.09,0.58,8.17,0,0,
+1.5176,13.15,3.61,1.05,73.24,0.57,8.24,0,0,
+1.5192,14.04,3.58,1.37,72.08,0.56,8.3,0,0,
+1.5175,13,3.6,1.36,72.99,0.57,8.4,0,0.11,
+1.5157,12.72,3.46,1.56,73.2,0.67,8.09,0,0.24,
+1.5176,12.8,3.66,1.27,73.01,0.6,8.56,0,0,
+1.5159,12.88,3.43,1.4,73.28,0.69,8.05,0,0.24,
+1.5175,12.86,3.56,1.27,73.21,0.54,8.38,0,0.17,
+1.5176,12.61,3.59,1.31,73.29,0.58,8.5,0,0,
+1.5176,12.81,3.54,1.23,73.24,0.58,8.39,0,0,
+1.5178,12.68,3.67,1.16,73.11,0.61,8.7,0,0,
+1.522,14.36,3.85,0.89,71.36,0.15,9.15,0,0,
+1.5191,13.9,3.73,1.18,72.12,0.06,8.89,0,0,
+1.5173,13.02,3.54,1.69,72.73,0.54,8.44,0,0.07,
+1.5175,12.82,3.55,1.49,72.75,0.54,8.52,0,0.19,
+1.5197,14.77,3.75,0.29,72.02,0.03,9,0,0,
+1.5174,12.78,3.62,1.29,72.79,0.59,8.7,0,0,
+1.5175,12.81,3.57,1.35,73.02,0.62,8.59,0,0,
+1.5172,13.38,3.5,1.15,72.85,0.5,8.43,0,0,
+1.5176,12.98,3.54,1.21,73,0.65,8.53,0,0,
+1.5179,13.21,3.48,1.41,72.64,0.59,8.43,0,0,
+1.5172,12.87,3.48,1.33,73.04,0.56,8.43,0,0,
+1.5177,12.56,3.52,1.43,73.15,0.57,8.54,0,0,
+1.5178,13.08,3.49,1.28,72.86,0.6,8.49,0,0,
+1.5177,12.65,3.56,1.3,73.08,0.61,8.69,0,0.14,
+1.5175,12.84,3.5,1.14,73.27,0.56,8.55,0,0,
+1.5177,12.85,3.48,1.23,72.97,0.61,8.56,0.09,0.22,
+1.5175,12.57,3.47,1.38,73.39,0.6,8.55,0,0.06,
+1.5178,12.69,3.54,1.34,72.95,0.57,8.75,0,0,
+1.5157,13.29,3.45,1.21,72.74,0.56,8.57,0,0,
+1.5191,13.89,3.53,1.32,71.81,0.51,8.78,0.11,0,
+1.518,12.74,3.48,1.35,72.96,0.64,8.68,0,0,
+1.5221,14.21,3.82,0.47,71.77,0.11,9.57,0,0,
+1.5221,14.21,3.82,0.47,71.77,0.11,9.57,0,0,
+1.5179,12.79,3.5,1.12,73.03,0.64,8.77,0,0,
+1.5175,12.71,3.42,1.2,73.2,0.59,8.64,0,0,
+1.5178,13.21,3.39,1.33,72.76,0.59,8.59,0,0,
+1.5221,13.73,3.84,0.72,71.76,0.17,9.74,0,0,
+1.5179,12.73,3.43,1.19,72.95,0.62,8.76,0,0.3,
+1.519,13.49,3.48,1.35,71.95,0.55,9,0,0,
+1.5187,13.19,3.37,1.18,72.72,0.57,8.83,0,0.16,
+1.5267,13.99,3.7,0.71,71.57,0.02,9.82,0,0.1,
+1.5222,13.21,3.77,0.79,71.99,0.13,10.02,0,0,
+1.519,13.58,3.35,1.23,72.08,0.59,8.91,0,0,
+1.5232,13.72,3.72,0.51,71.75,0.09,10.06,0,0.16,
+1.5193,13.2,3.33,1.28,72.36,0.6,9.14,0,0.11,
+1.5181,13.43,2.87,1.19,72.84,0.55,9.03,0,0,
+1.5184,13.14,2.84,1.28,72.85,0.55,9.07,0,0,
+1.5178,13.21,2.81,1.29,72.98,0.51,9.02,0,0.09,
+1.5177,12.45,2.71,1.29,73.7,0.56,9.06,0,0.24,
+1.5122,12.99,3.47,1.12,72.98,0.62,8.35,0,0.31,
+1.5182,12.87,3.48,1.29,72.95,0.6,8.43,0,0,
+1.5175,13.48,3.74,1.17,72.99,0.59,8.03,0,0,
+1.5175,13.39,3.66,1.19,72.79,0.57,8.27,0,0.11,
+1.5191,13.6,3.62,1.11,72.64,0.14,8.76,0,0,
+1.5198,13.81,3.58,1.32,71.72,0.12,8.67,0.69,0,
+1.5217,13.51,3.86,0.88,71.79,0.23,9.54,0,0.11,
+1.5223,14.17,3.81,0.78,71.35,0,9.69,0,0,
+1.5217,13.48,3.74,0.9,72.01,0.18,9.61,0,0.07,
+1.521,13.69,3.59,1.12,71.96,0.09,9.4,0,0,
+1.5215,13.05,3.65,0.87,72.22,0.19,9.85,0,0.17,
+1.5215,13.05,3.65,0.87,72.32,0.19,9.85,0,0.17,
+1.5215,13.12,3.58,0.9,72.2,0.23,9.82,0,0.16,
+1.523,13.31,3.58,0.82,71.99,0.12,10.17,0,0.03,
+1.5157,14.86,3.67,1.74,71.87,0.16,7.36,0,0.12,
+1.5185,13.64,3.87,1.27,71.96,0.54,8.32,0,0.32,
+1.5159,13.09,3.59,1.52,73.1,0.67,7.83,0,0,
+1.5163,13.34,3.57,1.57,72.87,0.61,7.89,0,0,
+1.516,13.02,3.56,1.54,73.11,0.72,7.9,0,0,
+1.5159,13.02,3.58,1.51,73.12,0.69,7.96,0,0,
+1.5165,13.44,3.61,1.54,72.39,0.66,8.03,0,0,
+1.5163,13,3.58,1.54,72.83,0.61,8.04,0,0,
+1.5161,13.92,3.52,1.25,72.88,0.37,7.94,0,0.14,
+1.5159,12.82,3.52,1.9,72.86,0.69,7.97,0,0,
+1.5159,12.86,3.52,2.12,72.66,0.69,7.97,0,0,
+1.5159,13.25,3.45,1.43,73.17,0.61,7.86,0,0,
+1.5165,13.41,3.55,1.25,72.81,0.68,8.1,0,0,
+1.5159,13.09,3.52,1.55,72.87,0.68,8.05,0,0.09,
+1.5141,14.25,3.09,2.08,72.28,1.1,7.08,0,0,
+1.5163,13.36,3.58,1.49,72.72,0.45,8.21,0,0,
+1.5157,13.24,3.49,1.47,73.25,0.38,8.03,0,0,
+1.5165,13.4,3.49,1.52,72.65,0.67,8.08,0,0.1,
+1.5162,13.01,3.5,1.48,72.89,0.6,8.12,0,0,
+1.5164,12.55,3.48,1.87,73.23,0.63,8.08,0,0.09,
+1.5184,12.93,3.74,1.11,72.28,0.64,8.96,0,0.22,
+1.516,12.9,3.44,1.45,73.06,0.44,8.27,0,0,
+1.5159,13.12,3.41,1.58,73.26,0.07,8.39,0,0.19,
+1.5159,13.24,3.34,1.47,73.1,0.39,8.22,0,0,
+1.5163,12.71,3.33,1.49,73.28,0.67,8.24,0,0,
+1.5186,13.36,3.43,1.43,72.26,0.51,8.6,0,0,
+1.5184,13.02,3.62,1.06,72.34,0.64,9.13,0,0.15,
+1.5174,12.2,3.25,1.16,73.55,0.62,8.9,0,0.24,
+1.5169,12.67,2.88,1.71,73.21,0.73,8.54,0,0,
+1.5181,12.96,2.96,1.43,72.92,0.6,8.79,0.14,0,
+1.5166,12.75,2.85,1.44,73.27,0.57,8.79,0.11,0.22,
+1.5173,12.35,2.72,1.63,72.87,0.7,9.23,0,0,
+1.5182,12.62,2.76,0.83,73.81,0.35,9.42,0,0.2,
+1.5272,13.8,3.15,0.66,70.57,0.08,11.64,0,0,
+1.5241,13.83,2.9,1.17,71.15,0.08,10.79,0,0,
+1.5248,11.45,0,1.88,72.19,0.81,13.24,0,0.34,
+1.5312,10.73,0,2.1,69.81,0.58,13.3,3.15,0.28,
+1.5339,12.3,0,1,70.16,0.12,16.19,0,0.24,
+1.5222,14.43,0,1,72.67,0.1,11.52,0,0.08,
+1.5182,13.72,0,0.56,74.45,0,10.99,0,0,
+1.5266,11.23,0,0.77,73.21,0,14.68,0,0,
+1.5274,11.02,0,0.75,73.08,0,14.96,0,0,
+1.5278,12.64,0,0.67,72.02,0.06,14.4,0,0,
+1.5189,13.46,3.83,1.26,72.55,0.57,8.21,0,0.14,
+1.5185,13.1,3.97,1.19,72.44,0.6,8.43,0,0,
+1.5185,13.41,3.89,1.33,72.38,0.51,8.28,0,0,
+1.5183,13.24,3.9,1.41,72.33,0.55,8.31,0,0.1,
+1.5171,13.72,3.68,1.81,72.06,0.64,7.88,0,0,
+1.5167,13.3,3.64,1.53,72.53,0.65,8.03,0,0.29,
+1.5165,13.56,3.57,1.47,72.45,0.64,7.96,0,0,
+1.5184,13.25,3.76,1.32,72.4,0.58,8.42,0,0,
+1.5166,12.93,3.54,1.62,72.96,0.64,8.03,0,0.21,
+1.5169,13.23,3.54,1.48,72.84,0.56,8.1,0,0,
+1.5171,13.48,3.48,1.71,72.52,0.62,7.99,0,0,
+1.5218,13.2,3.68,1.15,72.75,0.54,8.52,0,0,
+1.5187,12.93,3.66,1.56,72.51,0.58,8.55,0,0.12,
+1.5167,12.94,3.61,1.26,72.75,0.56,8.6,0,0,
+1.5208,13.78,2.28,1.43,71.99,0.49,9.85,0,0.17,
+1.5207,13.55,2.09,1.67,72.18,0.53,9.57,0.27,0.17,
+1.5202,13.98,1.35,1.63,71.76,0.39,10.56,0,0.18,
+1.5218,13.75,1.01,1.36,72.19,0.33,11.14,0,0,
+1.5261,13.7,0,1.36,71.24,0.19,13.44,0,0.1,
+1.5181,13.43,3.98,1.18,72.49,0.58,8.15,0,0,
+1.518,13.71,3.93,1.54,71.81,0.54,8.21,0,0.15,
+1.5181,13.33,3.85,1.25,72.78,0.52,8.12,0,0,
+1.5179,13.19,3.9,1.3,72.33,0.55,8.44,0,0.28,
+1.5181,13,3.8,1.08,73.07,0.56,8.38,0,0.12,
+1.5171,12.89,3.62,1.57,72.96,0.61,8.11,0,0,
+1.5167,12.79,3.52,1.54,73.36,0.66,7.9,0,0,
+1.5167,12.87,3.56,1.64,73.14,0.65,7.99,0,0,
+1.5169,13.33,3.54,1.61,72.54,0.68,8.11,0,0,
+1.5185,13.2,3.63,1.07,72.83,0.57,8.41,0.09,0.17,
+1.5166,12.85,3.51,1.44,73.01,0.68,8.23,0.06,0.25,
+1.5171,13,3.47,1.79,72.72,0.66,8.18,0,0,
+1.5166,12.99,3.18,1.23,72.97,0.58,8.81,0,0.24,
+1.5184,12.85,3.67,1.24,72.57,0.62,8.68,0,0.35,
+1.5177,13.65,3.66,1.11,72.77,0.11,8.6,0,0,
+1.5161,13.33,3.53,1.34,72.67,0.56,8.33,0,0,
+1.5167,13.24,3.57,1.38,72.7,0.56,8.44,0,0.1,
+1.5164,12.16,3.52,1.35,72.89,0.57,8.53,0,0,
+1.5167,13.14,3.45,1.76,72.48,0.6,8.38,0,0.17,
+1.5213,14.32,3.9,0.83,71.5,0,9.49,0,0,
+1.5178,13.64,3.65,0.65,73,0.06,8.93,0,0,
+1.5161,13.42,3.4,1.22,72.69,0.59,8.32,0,0,
+1.5169,12.86,3.58,1.31,72.61,0.61,8.79,0,0,
+1.5165,13.04,3.4,1.26,73.01,0.52,8.58,0,0,
+1.5166,13.41,3.39,1.28,72.64,0.52,8.65,0,0,
+1.5212,14.03,3.76,0.58,71.79,0.11,9.65,0,0,
+1.5178,13.53,3.41,1.52,72.04,0.58,8.79,0,0,
+1.518,13.5,3.36,1.63,71.94,0.57,8.81,0,0.09,
+1.5183,13.33,3.34,1.54,72.14,0.56,8.99,0,0,
+1.5193,13.64,3.54,0.75,72.65,0.16,8.89,0.15,0.24,
+1.5221,14.19,3.78,0.91,71.36,0.23,9.14,0,0.37,
+1.5151,14.01,2.68,3.5,69.89,1.68,5.87,2.2,0,
+1.5192,12.73,1.85,1.86,72.69,0.6,10.09,0,0,
+1.5217,11.56,1.88,1.56,72.86,0.47,11.41,0,0,
+1.5215,11.03,1.71,1.56,73.44,0.58,11.62,0,0,
+1.5197,12.64,0,1.65,73.75,0.38,11.53,0,0,
+1.5167,12.86,0,1.83,73.88,0.97,10.17,0,0,
+1.5199,13.27,0,1.76,73.03,0.47,11.32,0,0,
+1.5237,13.44,0,1.58,72.22,0.32,12.24,0,0,
+1.5132,13.02,0,3.04,70.48,6.21,6.96,0,0,
+1.5132,13,0,3.02,70.7,6.21,6.93,0,0,
+1.5204,13.38,0,1.4,72.25,0.33,12.5,0,0,
+1.5206,12.85,1.61,2.17,72.18,0.76,9.7,0.24,0.51,
+1.5212,12.97,0.33,1.51,73.39,0.13,11.27,0,0.28,
+1.5191,14,2.39,1.56,72.37,0,9.57,0,0,
+1.5194,13.79,2.41,1.19,72.76,0,9.77,0,0,
+1.5183,14.46,2.24,1.62,72.38,0,9.26,0,0,
+1.5185,14.09,2.19,1.66,72.67,0,9.32,0,0,
+1.513,14.4,1.74,1.54,74.55,0,7.59,0,0,
+1.5189,14.99,0.78,1.74,72.5,0,9.95,0,0,
+1.5192,14.15,0,2.09,72.74,0,10.88,0,0,
+1.5197,14.56,0,0.56,73.48,0,11.22,0,0,
+1.5111,17.38,0,0.34,75.41,0,6.65,0,0,
+1.5113,13.69,3.2,1.81,72.81,1.76,5.43,1.19,0,
+1.5184,14.32,3.26,2.22,71.25,1.46,5.79,1.63,0,
+1.5232,13.44,3.34,1.23,72.38,0.6,8.83,0,0,
+1.5225,14.86,2.2,2.06,70.26,0.76,9.76,0,0,
+1.5236,15.79,1.83,1.31,70.43,0.31,8.61,1.68,0,
+1.5161,13.88,1.78,1.79,73.1,0,8.67,0.76,0,
+1.516,14.85,0,2.38,73.28,0,8.76,0.64,0.09,
+1.5162,14.2,0,2.79,73.46,0.04,9.04,0.4,0.09,
+1.5172,14.75,0,2,73.02,0,8.53,1.59,0.08,
+1.5168,14.56,0,1.98,73.29,0,8.52,1.57,0.07,
+1.5154,14.14,0,2.68,73.39,0.08,9.07,0.61,0.05,
+1.5156,13.87,0,2.54,73.23,0.14,9.41,0.81,0.01,
+1.5173,14.7,0,2.34,73.28,0,8.95,0.66,0,
+1.5153,14.38,0,2.66,73.1,0.04,9.08,0.64,0,
+1.5161,15.01,0,2.51,73.05,0.05,8.83,0.53,0,
+1.5151,15.15,0,2.25,73.5,0,8.34,0.63,0,
+1.5165,11.95,0,1.19,75.18,2.7,8.93,0,0,
+1.5151,14.85,0,2.42,73.72,0,8.39,0.56,0,
+1.5166,14.8,0,1.99,73.11,0,8.28,1.71,0,
+1.5162,14.95,0,2.27,73.3,0,8.71,0.67,0,
+1.5173,14.95,0,1.8,72.99,0,8.61,1.55,0,
+1.5165,14.94,0,1.87,73.11,0,8.67,1.38,0,
+1.5183,14.39,0,1.82,72.86,1.41,6.47,2.88,0,
+1.5164,14.37,0,2.74,72.85,0,9.45,0.54,0,
+1.5162,14.14,0,2.88,72.61,0.08,9.18,1.06,0,
+1.5169,14.92,0,1.99,73.06,0,8.4,1.59,0,
+1.5207,14.36,0,2.02,73.42,0,8.44,1.64,0,
+1.5165,14.38,0,1.94,73.61,0,8.48,1.57,0,
+1.5171,14.23,0,2.08,73.36,0,8.62,1.67,0
+};
+#endif
diff --git a/test/classifier/data/glass_labels.hxx b/test/classifier/data/glass_labels.hxx
new file mode 100644
index 0000000..1c9553a
--- /dev/null
+++ b/test/classifier/data/glass_labels.hxx
@@ -0,0 +1,222 @@
+#ifndef GLASS_LABELS
+#define GLASS_LABELS
+int glass_labels[] = {
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7
+};
+
+int glass_Classes[] = {1, 2 , 3,5,6,7};
+int glass_size = 6;
+#endif
diff --git a/test/classifier/data/ionosphere_features.hxx b/test/classifier/data/ionosphere_features.hxx
new file mode 100644
index 0000000..8a5ee87
--- /dev/null
+++ b/test/classifier/data/ionosphere_features.hxx
@@ -0,0 +1,356 @@
+#ifndef IONOSPHERE_FEATURES
+#define IONOSPHERE_FEATURES
+double ionosphere_features[] = {
+1,0,0.99539,-0.05889,0.85243,0.02306,0.83398,-0.37708,1,0.0376,0.85243,-0.17755,0.59755,-0.44945,0.60536,-0.38223,0.84356,-0.38542,0.58212,-0.32192,0.56971,-0.29674,0.36946,-0.47357,0.56811,-0.51171,0.41078,-0.46168,0.21266,-0.3409,0.42267,-0.54487,0.18641,-0.453,
+1,0,1,-0.18829,0.93035,-0.36156,-0.10868,-0.93597,1,-0.04549,0.50874,-0.67743,0.34432,-0.69707,-0.51685,-0.97515,0.05499,-0.62237,0.33109,-1,-0.13151,-0.453,-0.18056,-0.35734,-0.20332,-0.26569,-0.20468,-0.18401,-0.1904,-0.11593,-0.16626,-0.06288,-0.13738,-0.02447,
+1,0,1,-0.03365,1,0.00485,1,-0.12062,0.88965,0.01198,0.73082,0.05346,0.85443,0.00827,0.54591,0.00299,0.83775,-0.13644,0.75535,-0.0854,0.70887,-0.27502,0.43385,-0.12062,0.57528,-0.4022,0.58984,-0.22145,0.431,-0.17365,0.60436,-0.2418,0.56045,-0.38238,
+1,0,1,-0.45161,1,1,0.71216,-1,0,0,0,0,0,0,-1,0.14516,0.54094,-0.3933,-1,-0.54467,-0.69975,1,0,0,1,0.90695,0.51613,1,1,-0.20099,0.25682,1,-0.32382,1,
+1,0,1,-0.02401,0.9414,0.06531,0.92106,-0.23255,0.77152,-0.16399,0.52798,-0.20275,0.56409,-0.00712,0.34395,-0.27457,0.5294,-0.2178,0.45107,-0.17813,0.05982,-0.35575,0.02309,-0.52879,0.03286,-0.65158,0.1329,-0.53206,0.02431,-0.62197,-0.05707,-0.59573,-0.04608,-0.65697,
+1,0,0.02337,-0.00592,-0.09924,-0.11949,-0.00763,-0.11824,0.14706,0.06637,0.03786,-0.06302,0,0,-0.04572,-0.1554,-0.00343,-0.10196,-0.11575,-0.05414,0.01838,0.03669,0.01519,0.00888,0.03513,-0.01535,-0.0324,0.09223,-0.07859,0.00732,0,0,-0.00039,0.12011,
+1,0,0.97588,-0.10602,0.94601,-0.208,0.92806,-0.2835,0.85996,-0.27342,0.79766,-0.47929,0.78225,-0.50764,0.74628,-0.61436,0.57945,-0.68086,0.37852,-0.73641,0.36324,-0.76562,0.31898,-0.79753,0.22792,-0.81634,0.13659,-0.8251,0.04606,-0.82395,-0.04262,-0.81318,-0.13832,-0.80975,
+0,0,0,0,0,0,1,-1,0,0,-1,-1,0,0,0,0,1,1,-1,-1,0,0,0,0,1,1,1,1,0,0,1,1,0,0,
+1,0,0.96355,-0.07198,1,-0.14333,1,-0.21313,1,-0.36174,0.9257,-0.43569,0.9451,-0.40668,0.90392,-0.46381,0.98305,-0.35257,0.84537,-0.6602,0.75346,-0.60589,0.69637,-0.64225,0.85106,-0.6544,0.57577,-0.69712,0.25435,-0.63919,0.45114,-0.72779,0.38895,-0.7342,
+1,0,-0.01864,-0.08459,0,0,0,0,0.1147,-0.2681,-0.45663,-0.38172,0,0,-0.33656,0.38602,-0.37133,0.15018,0.63728,0.22115,0,0,0,0,-0.14803,-0.01326,0.20645,-0.02294,0,0,0.16595,0.24086,-0.08208,0.38065,
+1,0,1,0.06655,1,-0.18388,1,-0.2732,1,-0.43107,1,-0.41349,0.96232,-0.51874,0.90711,-0.59017,0.8923,-0.66474,0.69876,-0.70997,0.70645,-0.7632,0.63081,-0.80544,0.55867,-0.89128,0.47211,-0.865,0.40303,-0.83675,0.30996,-0.89093,0.22995,-0.89158,
+1,0,1,-0.5421,1,-1,1,-1,1,0.36217,1,-0.41119,1,1,1,-1,1,-0.29354,1,-0.93599,1,1,1,1,1,-0.40888,1,-0.62745,1,-1,1,-1,1,-1,
+1,0,1,-0.16316,1,-0.10169,0.99999,-0.15197,1,-0.19277,0.94055,-0.35151,0.95735,-0.29785,0.93719,-0.34412,0.94486,-0.28106,0.90137,-0.43383,0.86043,-0.47308,0.82987,-0.5122,0.8408,-0.47137,0.76224,-0.5837,0.65723,-0.68794,0.68714,-0.64537,0.64727,-0.67226,
+1,0,1,-0.86701,1,0.2228,0.85492,-0.39896,1,-0.1209,1,0.35147,1,0.07772,1,-0.14767,1,-1,1,-1,0.61831,0.15803,1,0.62349,1,-0.17012,1,0.35924,1,-0.66494,1,0.88428,1,-0.18826,
+1,0,1,0.0738,1,0.0342,1,-0.05563,1,0.08764,1,0.19651,1,0.20328,1,0.12785,1,0.10561,1,0.27087,1,0.44758,1,0.4175,1,0.20033,1,0.36743,0.95603,0.48641,1,0.32492,1,0.46712,
+1,0,0.50932,-0.93996,1,0.26708,-0.0352,-1,1,-1,0.43685,-1,0,0,-1,-0.34265,-0.37681,0.03623,1,-1,0,0,0,0,-0.16253,0.92236,0.39752,0.26501,0,0,1,0.23188,0,0,
+1,0,0.99645,0.06468,1,-0.01236,0.97811,0.02498,0.96112,0.02312,0.99274,0.07808,0.89323,0.10346,0.94212,0.05269,0.88809,0.1112,0.86104,0.08631,0.81633,0.1183,0.83668,0.14442,0.81329,0.13412,0.79476,0.13638,0.7911,0.15379,0.77122,0.1593,0.70941,0.12015,
+0,0,0,0,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,
+1,0,0.67065,0.02528,0.66626,0.05031,0.57197,0.18761,0.08776,0.34081,0.63621,0.12131,0.62099,0.14285,0.78637,0.10976,0.58373,0.18151,0.14395,0.41224,0.53888,0.21326,0.5142,0.22625,0.48838,0.23724,0.46167,0.24618,0.43433,0.25306,0.40663,0.25792,1,0.33036,
+0,0,1,-1,0,0,0,0,1,1,1,-1,-0.71875,1,0,0,-1,1,1,1,-1,1,1,0.5625,-1,1,1,1,1,-1,1,1,1,1,
+1,0,1,-0.00612,1,-0.09834,1,-0.07649,1,-0.10605,1,-0.11073,1,-0.39489,1,-0.15616,0.92124,-0.31884,0.86473,-0.34534,0.91693,-0.44072,0.9606,-0.46866,0.81874,-0.40372,0.82681,-0.42231,0.75784,-0.38231,0.80448,-0.40575,0.74354,-0.45039,
+0,0,1,1,0,0,0,0,-1,-1,0,0,0,0,-1,-1,-1,-1,-1,1,-1,1,0,0,0,0,1,-1,-1,1,-1,1,-1,1,
+1,0,0.96071,0.07088,1,0.04296,1,0.09313,0.90169,-0.05144,0.89263,0.0258,0.8325,-0.06142,0.87534,0.09831,0.76544,0.0028,0.75206,-0.05295,0.65961,-0.07905,0.64158,-0.05929,0.55677,-0.07705,0.58051,-0.02205,0.49664,-0.01251,0.5131,-0.00015,0.52099,-0.00182,
+0,0,-1,1,0,0,0,0,-1,1,1,1,0,0,0,0,1,-1,-1,1,1,1,0,0,-1,-1,1,-1,1,1,-1,1,0,0,
+1,0,1,-0.06182,1,0.02942,1,-0.05131,1,-0.01707,1,-0.11726,0.84493,-0.05202,0.93392,-0.06598,0.6917,-0.07379,0.65731,-0.20367,0.9491,-0.31558,0.80852,-0.31654,0.84932,-0.34838,0.72529,-0.29174,0.73094,-0.38576,0.54356,-0.26284,0.64207,-0.39487,
+1,0,1,0.5782,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-0.62796,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,
+1,0,1,-0.08714,1,-0.17263,0.86635,-0.81779,0.94817,0.61053,0.95473,-0.41382,0.88486,-0.31736,0.87937,-0.23433,0.81051,-0.6218,0.12245,-1,0.90284,0.11053,0.62357,-0.78547,0.55389,-0.82868,0.48136,-0.86583,0.4065,-0.89674,0.32984,-0.92128,-0.13341,-1,
+0,0,-1,-1,0,0,-1,1,1,-0.375,0,0,0,0,0,0,1,-1,-1,-1,1,-1,0,0,1,-1,-1,1,-1,-1,0,0,-1,1,
+1,0,1,0.0838,1,0.17387,1,-0.13308,0.98172,0.6452,1,0.47904,1,0.59113,1,0.70758,1,0.82777,1,0.95099,1,1,0.98042,1,0.91624,1,0.83899,1,0.74822,1,0.64358,1,0.52479,1,
+0,0,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,0,0,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,
+1,0,1,-0.14236,1,-0.16256,1,-0.23656,1,-0.07514,1,-0.2501,1,-0.26161,1,-0.21975,1,-0.38606,1,-0.46162,1,-0.35519,1,-0.59661,1,-0.47643,0.9882,-0.49687,1,-0.7582,1,-0.75761,1,-0.84437,
+1,0,1,-1,1,1,1,-1,1,-1,1,-1,1,-0.0184,1,-1,1,1,1,-0.85583,1,1,1,-1,0,0,1,1,1,-0.79141,1,1,1,1,
+1,0,0.88208,-0.14639,0.93408,-0.11057,0.921,-0.1645,0.88307,-0.17036,0.88462,-0.31809,0.85269,-0.31463,0.82116,-0.35924,0.80681,-0.33632,0.75243,-0.47022,0.70555,-0.47153,0.6615,-0.50085,0.61297,-0.48086,0.56804,-0.54629,0.50179,-0.59854,0.47075,-0.57377,0.42189,-0.58086,
+1,0,0.71253,-0.02595,0.41287,-0.23067,0.98019,-0.09473,0.99709,-0.10236,1,-0.10951,0.58965,1,0.83726,-1,0.8227,-0.17863,0.8076,-0.28257,-0.25914,0.9273,0.51933,0.05456,0.65493,-0.20392,0.93124,-0.41307,0.63811,-0.21901,0.86136,-0.87354,-0.23186,-1,
+1,0,1,-0.15899,0.72314,0.27686,0.83443,-0.58388,1,-0.28207,1,-0.49863,0.79962,-0.12527,0.76837,0.14638,1,0.39337,1,0.2659,0.96354,-0.01891,0.92599,-0.91338,1,0.14803,1,-0.11582,1,-0.11129,1,0.53372,1,-0.57758,
+1,0,0.66161,-1,1,1,1,-0.67321,0.80893,-0.40446,1,-1,1,-0.89375,1,0.73393,0.17589,0.70982,1,0.78036,1,0.85268,1,-1,1,0.85357,1,-0.08571,0.95982,-0.3625,1,0.65268,1,0.34732,
+1,0,1,0.00433,1,-0.01209,1,-0.0296,1,-0.07014,0.97839,-0.06256,1,-0.06544,0.97261,-0.07917,0.92561,-0.13665,0.94184,-0.14327,0.99589,-0.14248,0.94815,-0.13565,0.89469,-0.20851,0.89067,-0.17909,0.85644,-0.18552,0.83777,-0.20101,0.83867,-0.20766,
+0,0,1,1,1,-1,0,0,0,0,-1,-1,0,0,0,0,-1,1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,0,0,
+1,0,0.91241,0.04347,0.94191,0.0228,0.94705,0.05345,0.93582,0.01321,0.91911,0.06348,0.92766,0.12067,0.92048,0.06211,0.88899,0.12722,0.83744,0.14439,0.80983,0.11849,0.77041,0.14222,0.75755,0.11299,0.7355,0.13282,0.66387,0.153,0.70925,0.10754,0.65258,0.11447,
+1,0,1,0.02461,0.99672,0.04861,0.97545,0.07143,0.61745,-1,0.91036,0.11147,0.88462,0.5364,0.82077,0.14137,0.76929,0.15189,1,0.41003,0.6585,0.16371,0.60138,0.16516,0.54446,0.1639,0.48867,0.16019,0.43481,0.15436,0.38352,0.14677,1,1,
+1,0,1,0.06538,1,0.20746,1,0.26281,0.93051,0.32213,0.86773,0.39039,0.75474,0.50082,0.79555,0.52321,0.65954,0.60756,0.57619,0.62999,0.47807,0.67135,0.40553,0.6884,0.34384,0.72082,0.27712,0.72386,0.19296,0.70682,0.11372,0.72688,0.0699,0.71444,
+1,0,-1,-1,1,1,1,-0.14375,0,0,-1,1,1,1,0.17917,-1,-1,-1,0.0875,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,0,0,
+1,0,0.90932,0.08791,0.86528,0.16888,1,0.16598,0.55187,0.68154,0.70207,0.36719,0.16286,0.42739,0.5762,0.46086,0.51067,0.49618,0.31639,0.12967,0.37824,0.54462,0.31274,0.55826,0.24856,0.56527,0.18626,0.56605,0.12635,0.56101,0.06927,0.55061,0.12137,0.67739,
+1,0,-0.64286,-1,1,0.82857,1,-1,1,-0.23393,1,0.96161,1,-0.37679,1,-1,1,0.13839,1,-1,1,-0.03393,-0.84286,1,0.5375,0.85714,1,1,1,-1,1,-1,1,-1,
+1,0,0.99025,-0.05785,0.99793,-0.13009,0.98663,-0.1943,0.99374,-0.25843,0.92738,-0.3013,0.92651,-0.37965,0.89812,-0.43796,0.84922,-0.52064,0.87433,-0.57075,0.79016,-0.59839,0.74725,-0.64615,0.68282,-0.68479,0.65247,-0.73174,0.6101,-0.75353,0.54752,-0.80278,0.49195,-0.83245,
+0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,-0.375,-1,-1,-1,0,0,0,0,-1,-1,-1,-1,-1,1,1,0,0,0,
+1,0,1,-0.0373,1,-0.07383,0.99601,-0.11039,0.99838,-0.09931,0.98941,-0.13814,0.96674,-0.21695,0.95288,-0.25099,0.91236,-0.344,0.90581,-0.32152,0.89991,-0.34691,0.87874,-0.37643,0.86213,-0.4299,0.83172,-0.43122,0.81433,-0.42593,0.77919,-0.47977,0.75115,-0.50152,
+1,0,0.94598,-0.02685,-1,0.26131,-0.36393,0.35639,0.69258,-0.63427,1,-0.03353,-0.2902,-0.0055,-0.54852,0.15452,0.91921,-0.4627,1,-0.50424,-0.29735,-0.31454,-0.73864,0.37361,0.83872,-0.46734,0.52208,-0.5813,1,-0.61393,-0.09634,0.20477,-0.06117,0.41913,
+1,0,0.98166,0.00874,0.98103,-0.03818,0.97565,-0.05699,0.95947,-0.06971,0.99004,-0.04507,0.94713,-0.11102,0.93369,-0.1279,0.94217,-0.11583,0.79682,-0.192,0.88274,-0.17387,0.86257,-0.18739,0.88487,-0.19689,0.81813,-0.21136,0.78546,-0.23864,0.76911,-0.23095,0.74323,-0.23902,
+1,0,0,0,1,0.51724,0,0,0.10991,-1,0,0,0,0,-1,-0.22414,-0.55711,-0.83297,0.7694,0.63147,0,0,0.53448,0.35668,-0.90302,0.44828,1,-1,-1,0.81573,0,0,0,0,
+1,0,0.84134,-0.18362,0.43644,0.02919,0.93421,-0.00267,0.87947,0.13795,0.81121,-0.01789,0.88559,0.54991,0.91714,-0.57486,0.75,-0.2952,0.86676,-0.20104,1,1,0.4661,-0.1629,0.90066,-0.02778,0.93358,-0.01158,0.61582,-0.32298,0.84463,-0.25706,0.93323,-0.01425,
+0,0,1,1,1,-1,0,0,0,0,1,1,1,1,-1,-1,1,-1,-1,1,0,0,1,-1,1,-1,1,1,-1,-1,0,0,0,0,
+1,0,1,1,1,1,0.9101,1,-0.2697,1,-0.83152,1,-1,1,-1,0.72526,-1,-0.57779,-1,-0.42052,-1,-1,-0.52838,-1,0.90014,-1,1,-1,1,-1,1,-0.34686,1,0.34845,
+1,0,-0.67935,-1,-1,1,1,0.63317,0.03515,-1,-1,-1,1,1,0.88683,-1,-1,1,0.8384,1,1,-1,-1,-1,-0.18856,1,1,-1,-1,-1,-1,1,1,0.33611,
+1,0,0.95659,0.08143,0.97487,-0.05667,0.97165,-0.08484,0.96097,-0.06561,0.94717,0.01279,0.95436,-0.16795,0.94612,-0.19497,0.9963,-0.32268,0.90343,-0.35902,0.91428,-0.27316,0.9014,-0.29807,0.99899,-0.40747,0.87244,-0.34586,0.92059,-0.30619,0.83951,-0.39061,0.82166,-0.41173,
+1,0,0.08333,-0.20685,-1,1,-1,1,0.71875,0.47173,-0.82143,-0.62723,-1,-1,-1,1,-0.02753,0.59152,-0.42113,-0.42113,-0.74628,-1,-1,-0.46801,-1,0.2381,1,-1,-1,-0.38914,-1,-1,-1,0.61458,
+1,0,1,-0.02259,1,-0.04494,1,-0.06682,1,-0.08799,1,0.56173,1,-0.12738,1,-0.14522,1,0.32407,1,-0.17639,0.99484,-0.18949,0.95601,-0.20081,1,-0.92284,0.8728,-0.21793,0.8292,-0.2237,0.78479,-0.22765,0.73992,-0.22981,
+0,0,-1,1,1,-1,-1,1,0,0,1,1,-1,-0.1875,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,1,0,0,-1,-1,
+1,0,1,0.05812,0.94525,0.07418,0.99952,0.13231,1,-0.01911,0.94846,0.07033,0.95713,0.14644,0.94862,0.11224,0.90896,0.20119,0.96741,0.16265,0.99695,0.14258,0.90784,0.1641,0.91667,0.22431,0.88423,0.23571,0.88568,0.22511,0.78324,0.29576,0.83574,0.31166,
+1,0,0.17188,-1,-1,1,0,0,0,0,-1,1,0,0,-0.61354,-0.67708,0.80521,0.36146,0.51979,0.14375,0,0,-1,-0.27083,-0.84792,0.9625,1,1,-1,0.67708,0,0,0,0,
+1,0,1,0.09771,1,0.12197,1,0.22574,0.98602,0.09237,0.9493,0.19211,0.92992,0.24288,0.89241,0.28343,0.85529,0.26721,0.83656,0.33129,0.83393,0.31698,0.74829,0.39597,0.76193,0.34658,0.68452,0.42746,0.62764,0.46031,0.56791,0.47033,0.54252,0.50903,
+1,0,0.01667,-0.35625,0,0,0,0,0,0,0,0,0,0,0.12292,-0.55,0.22813,0.82813,1,-0.42292,0,0,0.08333,-1,-0.10625,-0.16667,1,-0.76667,-1,0.18854,0,0,1,-0.27292,
+1,0,1,0.16801,0.99352,0.16334,0.94616,0.33347,0.91759,0.2261,0.91408,0.37107,0.8425,0.46899,0.81011,0.49225,0.78473,0.48311,0.65091,0.56977,0.56553,0.58071,0.55586,0.6472,0.48311,0.55236,0.43317,0.69129,0.35684,0.76147,0.33921,0.66844,0.22101,0.78685,
+1,0,0.63816,1,0.20833,-1,1,1,0.87719,0.30921,-0.66886,1,-0.05921,0.58772,0.01754,0.05044,-0.51535,-1,0.14254,-0.03289,0.32675,-0.4386,-1,1,0.80921,-1,1,-0.0614,1,1,0.20614,-1,1,1,
+1,0,1,-0.41457,1,0.76131,0.8706,0.18593,1,-0.09925,0.93844,0.4799,0.65452,-0.1608,1,0.00879,0.97613,-0.50126,0.80025,-0.24497,0.88065,-0.19095,1,-0.12312,0.93593,0.10678,0.9289,-0.07249,1,-0.27387,0.4397,0.19849,0.51382,-0.05402,
+1,0,0.84783,0.10598,1,0.3913,1,-1,0.66938,0.08424,1,0.27038,1,0.60598,1,0.35507,1,0.02672,0.58424,-0.43025,1,0.63496,0.8913,0.26585,0.91033,-0.33333,1,0.15942,0.37681,-0.01947,1,0.22464,1,0.37409,
+1,0,1,0.28046,1,0.02477,1,0.07764,1,0.04317,0.98762,0.33266,1,0.05489,1,0.04384,0.9575,-0.24598,0.84371,-0.08668,1,0.0415,0.99933,0.27376,1,-0.39056,0.96414,-0.02174,0.86747,0.2336,0.94578,-0.22021,0.80355,-0.07329,
+0,0,1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,1,-1,1,0.65625,0,0,1,-1,
+1,0,1,0.67784,0.81309,0.82021,0.43019,1,0.20619,0.80541,-0.43872,1,-0.79135,0.77092,-1,0.40268,-0.39046,-0.58634,-0.97907,-0.42822,-0.73083,-0.76339,-0.37671,-0.97491,0.41366,-1,0.41778,-0.93296,0.25773,-1,0.9357,-0.35222,0.98816,0.03446,
+1,0,1,1,1,-1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,1,1,1,1,1,0.5,0,0,1,-1,1,-1,
+1,0,1,0.03529,1,0.18281,1,0.26968,1,0.25068,1,0.28778,1,0.38643,1,0.31674,1,0.65701,1,0.53846,1,0.61267,1,0.59457,0.89593,0.68326,0.89502,0.71374,0.85611,0.67149,0.74389,0.85611,0.71493,0.75837,
+0,0,1,-1,1,1,-1,-1,1,-1,0,0,0,0,-1,1,1,-1,1,-1,-0.75,1,1,-1,1,-1,1,-1,-1,-1,0,0,1,-1,
+1,0,0.96087,0.0862,0.9676,0.19279,0.96026,0.27451,0.98044,0.35052,0.92867,0.46281,0.86265,0.52517,0.8282,0.58794,0.73242,0.69065,0.69003,0.7314,0.54473,0.6882,0.48339,0.76197,0.40615,0.74689,0.33401,0.83796,0.24944,0.86061,0.13756,0.86835,0.09048,0.86285,
+1,0,0.69444,0.38889,0,0,-0.32937,0.69841,0,0,0,0,0,0,0.20635,-0.24206,0.21032,0.19444,0.46429,0.78175,0,0,0,0,0.73413,0.27381,0.7619,0.63492,0,0,0,0,0,0,
+1,0,1,0.0507,1,0.10827,1,0.19498,1,0.28453,1,0.34826,1,0.38261,0.94575,0.42881,0.89126,0.50391,0.75906,0.58801,0.80644,0.59962,0.79578,0.62758,0.66643,0.63942,0.59417,0.69435,0.49538,0.72684,0.47027,0.71689,0.33381,0.75243,
+0,0,1,1,0,0,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,1,-1,1,1,0,0,1,-1,
+1,0,1,0.04078,1,0.11982,1,0.16159,1,0.27921,0.98703,0.30889,0.92745,0.37639,0.91118,0.39749,0.81939,0.46059,0.78619,0.46994,0.794,0.56282,0.70331,0.58129,0.67077,0.59723,0.58903,0.6099,0.53952,0.60932,0.45312,0.63636,0.40442,0.62658,
+0,0,1,1,1,-1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,
+1,0,1,0.24168,1,0.4859,1,0.72973,1,1,1,1,1,1,1,0.77128,1,1,1,1,0.74468,1,0.89647,1,0.64628,1,0.38255,1,0.10819,1,-0.1737,1,-0.81383,1,
+0,0,1,1,1,-1,1,1,-1,1,0,0,1,1,0,0,0,0,-1,1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,1,
+1,0,1,-0.06604,1,0.62937,1,0.09557,1,0.2028,1,-1,1,-0.40559,1,-0.15851,1,0.04895,1,-0.61538,1,-0.26573,1,-1,1,-0.58042,1,-0.81372,1,-1,1,-0.78555,1,-0.48252,
+0,0,1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,1,1,-1,
+1,0,0.92277,0.07804,0.92679,0.16251,0.89702,0.24618,0.84111,0.35197,0.78801,0.42196,0.70716,0.46983,0.70796,0.56476,0.60459,0.642,0.51247,0.64924,0.39903,0.66975,0.34232,0.68343,0.23693,0.76146,0.18765,0.73885,0.09694,0.71038,0.02735,0.77072,-0.04023,0.69509,
+1,0,0.68198,-0.17314,0.82332,0.21908,0.46643,0.32862,0.25795,0.58304,1,-0.15194,0.0106,0.44523,0.0106,0.38869,0.18681,0.41168,0.10567,0.36353,0.04325,0.30745,-0.00083,0.24936,-0.02862,0.19405,-0.04314,0.14481,-0.04779,0.10349,-0.04585,0.07064,-0.04013,0.04586,
+1,0,0.74852,-0.02811,0.6568,-0.05178,0.80621,0.02811,0.85947,0.02515,0.63462,0.08728,0.71598,0.0784,0.73077,0.05178,0.7855,-0.27811,0.65976,-0.01479,0.78698,0.06953,0.34615,-0.18639,0.65385,0.02811,0.61009,-0.06637,0.5355,-0.21154,0.59024,-0.14053,0.56361,0.02959,
+1,0,0.39179,-0.06343,0.97464,0.04328,1,1,0.35821,0.15299,0.54478,0.1306,0.61567,-0.8209,0.57836,0.6791,0.66791,-0.10448,0.46642,-0.11567,0.65574,0.14792,0.83209,0.45522,0.47015,0.16418,0.49309,0.1463,0.32463,-0.02612,0.39118,0.13521,0.34411,0.12755,
+1,0,0.67547,0.04528,0.76981,-0.10566,0.77358,0.03774,0.66038,-0.04528,0.64528,0.01132,0.66792,-0.13962,0.72075,-0.02264,0.76981,0.08679,0.61887,-0.07925,0.75849,-0.23774,0.73962,-0.14717,0.84906,-0.15094,0.73886,-0.05801,0.66792,0.02264,0.86415,0.03774,0.73208,0.00755,
+1,0,0.72727,-0.05,0.89241,0.03462,1,0.72727,0.66364,-0.05909,0.48182,-0.16818,0.81809,0.09559,0.56818,1,0.50455,0.21818,0.66818,0.1,1,-0.3,0.98636,-1,0.57273,0.32727,0.56982,0.14673,0.42273,0.08182,0.48927,0.14643,1,1,
+1,0,0.57647,-0.01569,0.40392,0,0.38431,0.12941,0.4,-0.05882,0.56471,0.14118,0.46667,0.08235,0.52549,-0.0549,0.58039,0.01569,0.50196,0,0.45882,0.06667,0.58039,0.08235,0.49804,0.00392,0.48601,0.10039,0.46275,0.08235,0.45098,0.23529,0.43137,0.17255,
+1,0,0.41932,0.12482,0.35,0.125,0.23182,0.27955,-0.03636,0.44318,0.04517,0.36194,-0.19091,0.33636,-0.1335,0.27322,0.02727,0.40455,-0.34773,0.12727,-0.20028,0.05078,-0.18636,0.36364,-0.14003,-0.04802,-0.09971,-0.07114,-1,-1,-0.02916,-0.07464,-0.00526,-0.06314,
+1,0,0.88305,-0.21996,1,0.36373,0.82403,0.19206,0.85086,0.05901,0.90558,-0.04292,0.85193,0.25,0.77897,0.25322,0.69206,0.5794,0.7103,0.39056,0.73176,0.27575,1,0.34871,0.5676,0.52039,0.69811,0.53235,0.80901,0.58584,0.43026,0.70923,0.52361,0.54185,
+1,0,0.84557,-0.0858,-0.31745,-0.80553,-0.08961,-0.56435,0.80648,0.04576,0.89514,-0.00763,-0.18494,0.63966,-0.20019,-0.68065,0.85701,-0.11344,0.77979,-0.15729,-0.06959,0.5081,-0.34128,0.80934,0.78932,-0.03718,0.70882,-0.25288,0.77884,-0.14109,-0.21354,-0.7817,-0.18494,-0.59867,
+1,0,0.7087,-0.24783,0.64348,0.04348,0.45217,0.38261,0.65217,0.18261,0.5,0.26957,0.57826,-0.23043,0.50435,0.37826,0.38696,-0.42609,0.36087,-0.26087,0.26957,0.11739,0.53246,-0.03845,0.31304,-0.12174,0.4993,-0.04264,0.48348,-0.04448,0.64348,-0.25217,0.50435,0.14783,
+1,0,-0.5418,0.14861,-0.33746,0.73375,0.52012,-0.13932,0.31889,-0.06811,0.20743,-0.1517,0.47368,0.08978,0.56347,-0.1548,0.16409,0.45201,0.33746,0.03406,0.50464,0.07121,-0.63777,-0.6161,1,0.65635,0.41348,-0.40116,-0.1517,0.11146,0.02399,0.5582,0.52632,-0.08978,
+1,0,0.29202,0.13582,0.45331,0.16808,0.51783,-0.00509,0.52632,0.20883,0.52462,-0.16638,0.47368,-0.04754,0.55518,0.03905,0.81664,-0.22411,0.42445,-0.04244,0.34975,0.06621,0.28183,-0.20883,0.51731,-0.03176,0.50369,-0.03351,0.34635,0.09847,0.70798,-0.01868,0.39559,-0.03226,
+1,0,0.79157,0.16851,0,0,0.56541,0.06874,0.39468,1,0.38359,0.99557,-0.02439,0.53215,0.23725,0.1286,-0.02661,0.95122,-0.50998,0.84922,-0.102,0.38803,-0.42572,0.23725,-0.91574,0.8071,-0.34146,0.88248,-1,0.69401,-1,0.1286,0,0,
+1,0,0.90116,0.16607,0.79299,0.37379,0.7299,0.50515,0.59784,0.72997,0.44303,0.81152,0.24412,0.87493,0.06438,0.85038,-0.12611,0.87396,-0.28739,0.79617,-0.46635,0.65924,-0.57135,0.53805,-0.68159,0.39951,-0.71844,0.25835,-0.72369,0.11218,-0.71475,-0.05525,-0.67699,-0.19904,
+1,0,0.97714,0.19049,0.82683,0.46259,0.71771,0.58732,0.47968,0.84278,0.31409,0.92643,0.10289,0.93945,-0.13254,0.8429,-0.3202,0.91624,-0.52145,0.79525,-0.68274,0.49508,-0.77408,0.33537,-0.85376,0.17849,-0.83314,-0.01358,-0.82366,-0.19321,-0.67289,-0.33662,-0.59943,-0.497,
+1,0,-1,-1,0,0,0.50814,-0.78502,0.60586,0.32899,-1,-0.41368,0,0,0,0,1,-0.2671,0.36482,-0.63518,0.97068,-1,-1,-1,1,-0.59609,-1,-1,-1,-1,1,-1,0,0,
+1,0,0.74084,0.04974,0.79074,0.02543,0.78575,0.03793,0.6623,0.09948,0.67801,0.31152,0.75934,0.07348,0.74695,0.08442,0.70681,-0.07853,0.63613,0,0.70021,0.11355,0.68183,0.12185,0.67016,0.15445,0.64158,0.13608,0.65707,0.17539,0.59759,0.14697,0.57455,0.15114,
+1,0,1,-1,0,0,0.77941,-0.99265,0.80882,0.55147,-0.41912,-0.94853,0,0,0,0,0.72059,-0.77206,0.73529,-0.60294,0,0,0.18382,-1,-1,-1,-1,-1,1,-1,1,-1,0,0,
+1,0,1,0.01709,0.96215,-0.03142,1,-0.03436,1,-0.05071,0.99026,-0.07092,0.99173,-0.09002,1,-0.15727,1,-0.14257,0.9831,-0.11813,1,-0.18519,1,-0.19272,0.98971,-0.22083,0.9649,-0.20243,0.94599,-0.17123,0.96436,-0.22561,0.87011,-0.23296,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,0,0,0,0,0,0,
+1,0,0.95704,-0.12095,0.63318,-0.1269,0.96365,-0.18242,0.97026,0.0846,0.92003,-0.01124,0.83543,-0.24719,1,-0.31395,0.99273,-0.21216,0.98678,-0.21018,1,-0.27165,0.93126,-0.39458,1,-0.19233,0.88793,-0.31565,0.81428,-0.23728,0.89095,-0.31857,0.69531,-0.41573,
+1,0,0.28409,-0.31818,0,0,0.68182,-1,0.30682,0.95833,0.64394,0.06439,0.34848,-0.84848,0,0,0.59091,-0.35985,0.45076,-0.80682,0,0,0,0,0.24242,0.17803,1,-0.23864,0.06061,-0.48485,0.16288,-0.70076,0,0,
+1,0,0.9449,-0.49311,1,-0.03692,0.98898,-0.87052,0.90083,0.66942,1,-0.10104,1,-0.12493,1,-0.15017,1,-0.17681,1,-0.20491,1,-0.23452,1,-0.26571,1,-0.29852,1,-0.33304,1,-0.36931,1,-0.4074,1,-0.44739,
+1,0,0,0,0,0,0,0,0,0,0.62195,1,0,0,0,0,0.36585,-0.71951,0.56098,-1,0,0,0,0,0,0,1,0.10976,0,0,0,0,0,0,
+1,0,0.99449,0.00526,0.84082,-0.11313,0.88237,-0.16431,0.99061,-0.06257,0.96484,-0.07496,0.85221,0.02966,0.87161,-0.20848,0.93881,-0.12977,0.98298,-0.08935,0.89876,0.00075,0.87836,-0.05882,0.93368,-0.19872,0.87579,-0.17806,0.94294,-0.16581,0.80253,-0.25741,0.76586,-0.27794,
+1,0,0.10135,0.10811,0,0,0,0,0.5473,0.82432,0.31081,1,0,0,0,0,0.37162,-1,0.33108,-1,0,0,0,0,-0.42568,-1,1,-1,0.55405,-0.23649,0,0,0,0,
+1,0,1,-0.57224,0.9915,-0.73371,0.89518,-0.9745,1,-0.35818,1,-0.23229,0.6289,-0.86402,1,-0.57535,1,-0.79603,0.76771,-0.88952,0.96601,-1,0.7012,-0.74896,0.61946,-0.76904,0.53777,-0.77986,0.8102,-1,1,-1,0.30445,-0.76112,
+1,0,0.65909,-0.62879,0,0,0,0,0.77273,1,1,-0.2803,0,0,0,0,0.62121,-0.22727,0.84091,-1,1,-1,0,0,0,0,1,-0.93939,-0.12879,-0.93182,0,0,0,0,
+1,0,0.86284,0.1931,0.8092,0.41149,0.67203,0.55785,0.54559,0.69962,0.36705,0.81533,0.19617,0.85671,-0.04061,0.86284,-0.17241,0.75785,-0.341,0.65747,-0.48199,0.56092,-0.6023,0.40996,-0.59234,0.25747,-0.63038,0.08818,-0.57241,-0.07816,-0.54866,-0.19923,-0.42912,-0.31954,
+1,0,0.42,-0.61,0,0,1,-1,0.9,1,0.43,0.64,0,0,0,0,0.67,-0.29,0.84,-1,0,0,0,0,0.21,0.68,1,0.22,0,0,0,0,0,0,
+1,0,1,0.23395,0.91404,0.52013,0.7802,0.72144,0.4766,0.84222,0.27639,0.9173,0.09467,0.88248,-0.2198,0.91404,-0.34168,0.75517,-0.5136,0.64527,-0.64527,0.44614,-0.74102,0.29162,-0.70838,0.03591,-0.71731,-0.11943,-0.64962,-0.28183,-0.51251,-0.44505,-0.37432,-0.53319,
+1,0,0.91353,0.81586,-0.72973,1,-0.39466,0.55735,0.05405,0.2973,-0.18599,-0.10241,-0.03158,-0.0897,0.01401,-0.03403,0.01108,-0.00537,0.00342,0.00097,0.00048,0.00075,-3e-05,0.00019,-3e-05,2e-05,-1e-05,0,0,0,0,0,0,0,
+1,0,0.21429,-0.09524,0.33333,0.07143,0.19048,0.19048,0.2381,0.09524,0.40476,0.02381,0.30952,-0.04762,0.30952,-0.04762,0.28571,-0.11905,0.33333,0.04762,0.30952,0,0.21429,-0.11905,0.35714,-0.04762,0.22109,-0.0229,0.19048,0,0.16997,-0.02034,0.14694,-0.01877,
+1,0,1,-0.14754,1,0.04918,0.57377,-0.01639,0.65574,0.01639,0.85246,-0.03279,0.72131,0,0.68852,-0.16393,0.19672,-0.14754,0.65558,-0.17176,0.67213,0.03279,1,-0.29508,0.31148,-0.34426,0.52385,-0.20325,0.32787,-0.03279,0.27869,-0.44262,0.4918,-0.06557,
+1,0,0.98182,0,0.88627,0.03131,0.86249,0.04572,0.8,0,0.69091,0.04545,0.79343,0.08436,0.77118,0.09579,0.62727,0.25455,0.68182,0.12727,0.70674,0.12608,0.68604,0.13493,0.74545,0.22727,0.64581,0.15088,0.67273,0.02727,0.60715,0.16465,0.5884,0.17077,
+1,0,0.39286,0.52381,-0.78824,0.11342,-0.16628,-0.76378,0.66667,0.0119,0.82143,0.40476,-0.6723,0.30729,-0.34797,-0.63668,0.46429,0.15476,0.54762,0.05952,-0.5183,0.44961,-0.47651,-0.47594,0.32143,0.70238,0.51971,0.38848,0.57143,0.39286,-0.54891,-0.29915,0.25441,-0.55837,
+1,0,0.86889,-0.07111,1,-0.02494,1,-0.06889,0.87778,0.00222,0.83556,-0.06444,1,-0.07287,1,-0.2,0.86889,0.05333,0.88,-0.03778,1,-0.11526,1,-0.18667,0.84444,0.03556,1,-0.14162,0.82222,-0.14667,1,-0.15609,1,-0.44222,
+1,0,0.43636,-0.12727,0.58182,-0.14545,0.18182,-0.67273,0.34545,-0.03636,0.29091,-0.05455,0.29091,0.29091,0.36364,-0.41818,0.2,-0.01818,0.36364,0.05455,0.12727,0.49091,0.61818,0.16364,0.32727,0.16364,0.41098,-0.07027,0.34545,-0.05455,0.12727,-0.36364,0.29091,-0.29091,
+1,0,1,-0.92453,1,0.75472,0.49057,-0.0566,0.62264,0,1,-0.00054,0.45283,0.07547,0.62264,-0.0566,0.98878,-0.00085,0.5283,0,0.5283,0.07547,0.9519,-0.00112,1,0.79245,0.92192,-0.00128,0.9434,-1,1,0.43396,0.43396,-0.11321,
+1,0,0.7381,0.83333,-0.7619,-0.2381,0.33333,-0.14286,0.45238,-0.14286,-0.67285,0.12808,0.33333,0,0.28571,-0.07143,-0.38214,0.51163,0.2381,0.02381,0.45238,0.04762,0.16667,-0.2619,-0.57255,-0.10234,0.24889,-0.51079,1,0,-0.66667,-0.04762,0.2619,0.02381,
+1,0,0.4375,0.04167,0.58333,-0.10417,0.39583,0,0.33333,-0.0625,0.47917,0,0.29167,0.10417,0.54167,0.02083,0.4375,-0.22917,0.35417,-0.22917,0.33333,0.08333,0.25,0.1875,0.39583,-0.1875,0.44012,-0.10064,0.41667,-0.08333,0.58333,-0.3125,0.33333,-0.0625,
+1,0,1,1,0,0,0,0,0,0,0.47744,-0.89098,-0.51504,0.45489,-0.95489,0.28571,0.64662,1,0,0,0,0,0.6203,0.20301,-1,-1,1,-1,1,1,0,0,0,0,
+1,0,0.95217,0.06595,0.93614,0.1303,0.90996,0.19152,0.84881,-0.49962,0.90023,0.6132,0.77937,0.34328,0.72254,0.37988,0.66145,0.40844,0.95472,0.59862,0.53258,0.44088,0.46773,0.44511,0.4044,0.44199,0.34374,0.43221,0.9033,1,0.23405,0.3962,0.18632,0.37191,
+1,0,0.5984,0.40332,0.82809,0.80521,0.76001,0.70709,0.8401,-0.10984,0.97311,0.07981,0.95824,-0.85727,0.91962,0.88444,0.95452,-0.05206,0.88673,0.18135,0.98484,-0.69594,0.8667,-0.85755,0.28604,-0.30063,1,0.17076,0.62958,0.42677,0.87757,0.81007,0.81979,0.68822,
+1,0,0.95882,0.10129,1,-0.01918,0.98313,0.02555,0.96974,-0.09316,0.98955,-0.02716,0.9798,-0.03096,1,-0.05343,1,-0.05179,0.9384,0.01557,0.9762,-0.09284,0.97889,-0.05318,0.91567,-0.15675,0.95677,-0.06995,0.90978,0.01307,1,-0.10797,0.93144,-0.06888,
+1,0,0,0,-0.33672,0.85388,0,0,0.68869,-1,0.97078,0.31385,-0.26048,-0.59212,-0.30241,0.65565,0.94155,0.16391,0,0,0,0,-0.18043,-1,0,0,1,-1,0,0,0.04447,0.61881,0,0,
+1,0,0.96933,0.00876,1,0.00843,0.98658,-0.00763,0.97868,-0.02844,0.9982,-0.0351,1,-0.01271,1,-0.02581,1,-0.01175,0.98485,0.00025,1,-0.02612,1,-0.04744,0.96019,-0.04527,0.99188,-0.03473,0.9702,-0.02478,1,-0.03855,0.9842,-0.04112,
+1,0,0,0,0.98919,-0.22703,0.18919,-0.05405,0,0,0.93243,0.07297,1,-0.2,1,0.07027,1,-0.11351,0,0,1,-0.21081,1,-0.41622,0,0,1,-0.17568,0,0,1,-0.25946,0.28919,-0.15676,
+1,0,0.64122,0.01403,0.34146,-0.02439,0.52751,0.03466,0.19512,0.12195,0.43313,0.04755,0.21951,0.04878,0.29268,0,0.36585,0,0.31707,0.07317,0.26829,0.12195,0.23698,0.05813,0.21951,0.09756,0.19304,0.05641,0.1741,0.05504,0.19512,0,0.17073,0.07317,
+1,0,1,1,1,-1,0,0,0,0,1,1,1,-1,1,1,1,-1,0,0,0,0,1,-0.27778,0,0,1,-1,1,1,1,-1,0,0,
+1,0,0.34694,0.20408,0.46939,0.2449,0.40816,0.20408,0.46939,0.44898,0.30612,0.59184,0.12245,0.55102,0,0.5102,-0.06122,0.55102,-0.20408,0.55102,-0.28571,0.44898,-0.28571,0.32653,-0.61224,0.22449,-0.46579,0.14895,-0.59184,0.18367,-0.34694,0,-0.26531,-0.2449,
+1,0,0,0,1,-1,0,0,0,0,1,1,1,-0.25342,1,0.23288,1,-1,0,0,0,0,1,1,0,0,1,-1,0,0,1,-1,0,0,
+1,0,0.89706,0.38235,0.91176,0.375,0.74265,0.67647,0.45588,0.77941,0.19118,0.88971,-0.02206,0.86029,-0.20588,0.82353,-0.375,0.67647,-0.5,0.47794,-0.73529,0.38235,-0.86029,0.08824,-0.74265,-0.125,-0.67925,-0.24131,-0.55147,-0.42647,-0.44118,-0.50735,-0.28676,-0.56618,
+1,0,-1,0.28105,0.22222,0.15033,-0.75693,-0.70984,-0.30719,0.71242,-1,1,-0.81699,0.33987,-0.79085,-0.02614,-0.98039,-0.83007,-0.60131,-0.54248,-0.04575,-0.83007,0.94118,-0.94118,-1,-0.43137,0.74385,0.09176,-1,0.05229,0.18301,0.02614,-0.40201,-0.48241,
+1,0,0.26667,-0.1,0.53333,0,0.33333,-0.13333,0.36667,0.11667,0.56667,0.01667,0.71667,0.08333,0.7,-0.06667,0.53333,0.2,0.41667,-0.01667,0.31667,0.2,0.7,0,0.25,0.13333,0.46214,0.05439,0.4,0.03333,0.46667,0.03333,0.41667,-0.05,
+1,0,-0.26667,0.4,-0.27303,0.12159,-0.17778,-0.04444,0.06192,-0.06879,0.04461,0.02575,-0.00885,0.02726,-0.01586,-0.00166,-0.00093,-0.00883,0.0047,-0.00153,0.00138,0.00238,-0.00114,0.00102,-0.00069,-0.0005,0.00019,-0.00043,0.00026,5e-05,0,0.00015,-8e-05,2e-05,
+1,0,1,-0.37838,0.64865,0.2973,0.64865,-0.24324,0.86486,0.18919,1,-0.27027,0.51351,0,0.62162,-0.05405,0.32432,-0.21622,0.71833,-0.17666,0.62162,0.05405,0.75676,0.13514,0.35135,-0.2973,0.61031,-0.22163,0.58478,-0.23027,0.72973,-0.59459,0.51351,-0.24324,
+1,0,0.94531,-0.03516,-1,-0.33203,-1,-0.01563,0.97266,0.01172,0.93359,-0.01953,-1,0.16406,-1,-0.00391,0.95313,-0.03516,0.92188,-0.02734,-0.99219,0.11719,-0.93359,0.34766,0.95703,-0.00391,0.82041,0.13758,0.90234,-0.06641,-1,-0.1875,-1,-0.34375,
+1,0,0.95202,0.02254,0.93757,-0.01272,0.93526,0.01214,0.96705,-0.01734,0.96936,0.0052,0.95665,-0.03064,0.9526,-0.00405,0.9948,-0.02659,0.99769,0.01792,0.93584,-0.04971,0.93815,-0.0237,0.97052,-0.04451,0.96215,-0.01647,0.97399,0.01908,0.95434,-0.0341,0.95838,0.00809,
+1,0,1,-0.05529,1,-1,0.5,-0.11111,0.36111,-0.22222,1,-0.25712,0.16667,-0.11111,1,-0.3466,1,-0.38853,1,-0.42862,0,-0.25,1,-0.50333,1,-0.27778,1,-0.57092,1,-0.27778,1,-0.63156,1,-0.65935,
+1,0,0.31034,-0.10345,0.24138,-0.10345,0.2069,-0.06897,0.07405,-0.05431,0.03649,-0.03689,0.01707,-0.02383,0.00741,-0.01482,0.00281,-0.00893,0.00078,-0.00523,-3e-05,-0.00299,-0.00028,-0.00166,-0.00031,-0.0009,-0.00025,-0.00048,-0.00018,-0.00024,-0.00012,-0.00012,-8e-05,-6e-05,
+1,0,0.62745,-0.07843,0.72549,0,0.60784,-0.07843,0.62745,-0.11765,0.68627,-0.11765,0.66667,-0.13725,0.64706,-0.09804,0.54902,-0.11765,0.54902,-0.21569,0.58824,-0.19608,0.66667,-0.23529,0.45098,-0.2549,0.52409,-0.24668,0.56863,-0.31373,0.43137,-0.21569,0.47059,-0.27451,
+1,0,0.25,0.16667,0.46667,0.26667,0.19036,0.23966,0.07766,0.19939,0.0107,0.14922,-0.02367,0.10188,-0.03685,0.06317,-0.03766,0.03458,-0.0323,0.01532,-0.02474,0.00357,-0.01726,-0.00273,-0.01097,-0.00539,-0.00621,-0.00586,-0.00294,-0.0052,-0.00089,-0.00408,0.00025,-0.00291,
+1,0,-0.65625,0.15625,0.0625,0,0,0.0625,0.625,0.0625,0.1875,0,-0.03125,0.09375,0.0625,0,0.15625,-0.15625,0.4375,-0.375,0,-0.09375,0,0,0.03125,-0.46875,0.03125,0,-0.71875,0.03125,-0.03125,0,0,0.09375,
+1,0,1,-0.01081,1,-0.02703,1,-0.06486,0.95135,-0.01622,0.98919,-0.03243,0.98919,0.08649,1,-0.06486,0.95135,0.09189,0.97838,-0.00541,1,0.06486,1,0.04324,0.97838,0.09189,0.98556,0.01251,1,-0.03243,1,0.02703,1,-0.07027,
+1,0,0.85271,0.05426,1,0.08069,1,1,0.91473,-0.00775,0.83721,0.03876,1,0.27153,1,1,0.81395,0.04651,0.90698,0.11628,1,0.5067,1,-1,0.8062,0.03876,1,0.71613,0.84496,0.06977,1,0.87317,1,1,
+1,0,0.90374,-0.01604,1,0.08021,1,0.01604,0.93048,0.00535,0.93583,-0.01604,1,0,1,0.06417,1,0.04813,0.91444,0.04278,0.96791,0.02139,0.9893,-0.01604,0.96257,0.05348,0.96974,0.04452,0.87701,0.0107,1,0.09091,0.97861,0.06417,
+1,0,-0.205,0.2875,0.23,0.1,0.2825,0.3175,0.3225,0.35,0.36285,-0.34617,0.0925,0.275,-0.095,0.21,-0.0875,0.235,-0.34187,0.31408,-0.48,-0.08,0.29908,0.33176,-0.58,-0.24,0.3219,-0.28475,-0.47,0.185,-0.27104,-0.31228,0.40445,0.0305,
+1,0,0.6,0.03333,0.63333,0.06667,0.7,0.06667,0.7,0,0.63333,0,0.8,0,0.73333,0,0.7,0.1,0.66667,0.1,0.73333,-0.03333,0.76667,0,0.63333,0.13333,0.65932,0.10168,0.6,0.13333,0.6,0.16667,0.63333,0.16667,
+1,0,0.05866,-0.00838,0.06704,0.00838,0,-0.01117,0.00559,-0.03911,0.01676,-0.07542,-0.00559,0.05307,0.06425,-0.03352,0,0.09497,-0.06425,0.07542,-0.04749,0.02514,0.02793,-0.00559,0.00838,0.00559,0.10335,-0.00838,0.03073,-0.00279,0.04469,0,0.04749,-0.03352,
+1,0,0.94653,0.28713,0.72554,0.67248,0.47564,0.82455,0.01267,0.89109,-0.24871,0.84475,-0.47644,0.56079,-0.75881,0.41743,-0.66455,0.07208,-0.65426,-0.19525,-0.52475,-0.44,-0.30851,-0.55089,-0.04119,-0.64792,0.16085,-0.5642,0.36752,-0.41901,0.46059,-0.22535,0.50376,-0.0598,
+1,0,0.0546,0.01437,-0.02586,0.04598,0.01437,0.04598,-0.07759,0.00862,0.01724,-0.06609,-0.03736,0.0431,-0.08333,-0.04598,-0.09483,0.08046,-0.04023,0.05172,0.02011,0.02299,-0.03736,-0.01149,0.03161,-0.00862,0.00862,0.01724,0.02586,0.01149,0.02586,0.01149,-0.04598,-0.00575,
+1,0,0.72414,-0.01084,0.79704,0.01084,0.8,0.00197,0.79015,0.01084,0.78424,-0.00985,0.8335,0.03251,0.85123,0.01675,0.80099,-0.00788,0.79113,-0.02956,0.75961,0.0335,0.74778,0.05517,0.72611,-0.01478,0.78041,0.00612,0.74089,-0.05025,0.82956,0.02956,0.79015,0.00788,
+1,0,0.03852,0.02568,0.00428,0,0.01997,-0.01997,0.0214,-0.04993,-0.0485,-0.01284,0.01427,-0.02282,0,-0.03281,-0.04708,-0.02853,-0.01712,0.03566,0.0214,0.00428,0.05136,-0.02282,0.05136,0.01854,0.03994,0.01569,0.01997,0.00713,-0.02568,-0.01854,-0.01427,0.01997,
+1,0,0.4709,0.22751,0.42328,0.33598,0.25661,0.47619,0.01852,0.49471,-0.02116,0.53968,-0.34127,0.31217,-0.4127,0.3254,-0.51587,0.06878,-0.5,-0.1164,-0.14815,-0.1455,-0.14815,-0.38095,-0.2328,0.00265,0.03574,-0.31739,0.15873,-0.21693,0.24868,-0.24339,0.2672,0.04233,
+1,0,0.08696,0.00686,0.13959,-0.04119,0.10526,-0.08238,0.12586,-0.06178,0.23341,-0.01144,0.12357,0.0778,0.14645,-0.13501,0.29062,-0.04805,0.18993,0.07323,0.1167,0,0.11213,-0.00229,0.15103,-0.10297,0.08467,0.01373,0.11213,-0.06636,0.09611,-0.07323,0.1167,-0.06865,
+1,0,0.94333,0.38574,0.48263,0.64534,0.21572,0.77514,-0.55941,0.64899,-0.73675,0.42048,-0.76051,0,-0.62706,-0.31079,-0.38391,-0.62157,-0.12797,-0.69287,0.49909,-0.6362,0.71481,-0.3766,0.73857,-0.05484,0.60098,0.30384,0.45521,0.60512,0.02742,0.54479,-0.21572,0.50457,
+1,0,0.01975,0.00705,0.0409,-0.00846,0.02116,0.01128,0.01128,0.04372,0.00282,0.00141,0.01975,-0.03103,-0.01975,0.06065,-0.0409,0.0268,-0.02398,-0.00423,0.04372,-0.02539,0.01834,0,0,-0.01269,0.01834,-0.01128,0.00564,-0.01551,-0.01693,-0.02398,0.00705,0,
+1,0,0.85736,0.00075,0.81927,-0.05676,0.77521,-0.04182,0.84317,0.09037,0.86258,0.11949,0.88051,-0.06124,0.78342,0.0351,0.83719,-0.06796,0.8357,-0.1419,0.88125,0.01195,0.90515,0.0224,0.79686,-0.01942,0.82383,-0.03678,0.88125,-0.06423,0.73936,-0.01942,0.79089,-0.09186,
+1,0,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,
+1,0,0.85209,0.39252,0.38887,0.76432,0.08858,0.98903,-0.42625,0.88744,-0.76229,0.4998,-0.93092,0.10768,-0.859,-0.31044,-0.6603,-0.55262,-0.1926,-0.86063,0.28444,-0.80496,0.64649,-0.3523,0.77814,-0.23324,0.71698,0.21343,0.3783,0.5831,0.19667,0.66315,-0.11215,0.64933,
+1,0,1,1,1,0.5125,0.625,-1,1,1,0.025,0.03125,1,1,0,0,1,-1,1,1,1,1,0.3125,1,1,1,1,1,1,1,-0.94375,1,0,0,
+1,0,1,0.54902,0.62745,1,0.01961,1,-0.4902,0.92157,-0.82353,0.58824,-1,0.11765,-0.96078,-0.33333,-0.64706,-0.68627,-0.23529,-0.86275,0.35294,-1,0.7451,-0.72549,0.92157,-0.21569,0.92874,0.21876,0.72549,0.56863,0.23529,0.90196,-0.11765,0.90196,
+1,0,0,0,-1,-1,-1,1,0,0,-1,1,1,1,1,-1,0,0,0,0,-1,-1,-1,1,1,0.4375,1,-1,0,0,-1,-1,-1,1,
+1,0,0.44444,0.44444,0.53695,0.90763,-0.22222,1,-0.33333,0.88889,-1,0.33333,-1,-0.11111,-1,-0.22222,-0.66667,-0.77778,0.55556,-1,-0.22222,-0.77778,0.77778,-0.22222,0.33333,0,0.9212,0.45019,0.57454,0.84353,0.22222,1,-0.55556,1,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
+1,0,1,0,1,0,0.5,0.5,0.75,0,0.91201,0.12094,0.89067,0.1421,0.86922,0.16228,0.75,0.25,0.75,0.5,0.75,0,1,-0.25,0.5,0.5,0.73944,0.26388,0.75,0.25,0.69635,0.29074,0.67493,0.30293,
+0,0,-1,1,1,1,0,0,1,-1,1,-1,1,-1,-1,-1,0,0,-1,-1,0,0,0,0,-1,-1,1,-1,1,1,-1,-1,0,0,
+1,0,1,0,1,0,0.66667,0.11111,1,-0.11111,0.88889,-0.11111,1,-0.22222,0.77778,0,0.77778,0,1,-0.11111,0.77778,-0.11111,0.66667,-0.11111,0.66667,0,0.90347,-0.05352,1,0.11111,0.88889,-0.11111,1,0,
+0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,0,0,1,0.75,0,0,0,0,-1,1,0,0,1,-1,-1,-1,1,1,0,0,
+1,0,1,0.45455,1,-0.45455,1,0.09091,1,-0.09091,1,0,1,-0.27273,1,-0.18182,1,0.09091,1,0,1,-0.36364,1,0.09091,1,-0.09091,1,-0.04914,1,0.45455,1,-0.27273,1,-0.18182,
+1,0,0.62121,-0.63636,0,0,0,0,0.3447,0.28788,0.42803,0.39394,-0.07576,0.51894,0.36364,0.31439,-0.53788,0.32955,0.12121,-0.14773,0.01894,-0.53409,-0.57576,0.17803,0.29167,-0.27273,0.25758,-0.57576,0.43182,0.24242,0.18182,-0.02273,0.17045,-0.41667,
+1,0,1,0.11765,1,0.23529,1,0.41176,1,0.05882,1,0.23529,1,0.11765,1,0.47059,1,-0.05882,1,-0.11765,1,0.35294,1,0.41176,1,-0.11765,1,0.20225,1,0.05882,1,0.35294,1,0.23529,
+1,0,0,0,-1,-0.62766,1,0.51064,0.07979,-0.23404,-1,-0.3617,0.12766,-0.59043,1,-1,0,0,0.82979,-0.07979,-0.25,1,0.17021,-0.70745,0,0,-0.19149,-0.46809,-0.2234,-0.48936,0.74468,0.90426,-0.67553,0.45745,
+1,0,0.91667,0.29167,0.83333,-0.16667,0.70833,0.25,0.875,-0.08333,0.91667,0.04167,0.83333,0.125,0.70833,0,0.875,0.04167,1,0.08333,0.66667,-0.08333,0.75,0.16667,0.83333,-0.125,0.83796,0.05503,1,0.20833,0.70833,0,0.70833,0.04167,
+1,0,0.1859,-0.16667,0,0,0,0,0,0,0,0,0.11538,-0.19071,0,0,0,0,0,0,0,0,-0.05128,-0.06571,0.07853,0.08974,0.17308,-0.10897,0.125,0.09615,0.02564,-0.04808,0.16827,0.19551,
+1,0,1,-0.08183,1,-0.11326,0.99246,-0.29802,1,-0.33075,0.96662,-0.34281,0.85788,-0.47265,0.91904,-0.4817,0.73084,-0.65224,0.68131,-0.63544,0.8245,-0.78316,0.58829,-0.74785,0.67033,-0.96296,0.48757,-0.85669,0.37941,-0.83893,0.24117,-0.88846,0.29221,-0.89621,
+1,0,1,1,-1,1,-1,-0.82456,0.34649,0.21053,0.46053,0.07018,0.22807,0.05702,0.35088,0.34649,0.72807,-0.03947,0.22807,0.5307,0,0,-0.29825,-0.16228,1,-0.66667,1,-1,1,-0.24561,0.35088,0.20175,0.82895,0.07895,
+1,0,1,0.24077,0.99815,0.00369,0.80244,-0.30133,0.89919,-0.23486,0.70643,-0.24077,0.73855,-0.30539,0.71492,-0.36078,0.47194,-0.61189,0.40473,-0.55059,0.61041,-0.39328,0.53176,-0.32681,0.23966,-0.52142,0.29208,-0.4839,0.12777,-0.39143,0.15657,-0.51329,0.18353,-0.46603,
+0,0,-1,1,1,-1,0,0,0,0,1,-1,1,1,0,0,1,-1,0,0,0,0,1,1,-1,1,1,-1,-1,1,-1,-1,0,0,
+1,0,0.92247,-0.19448,0.96419,-0.17674,0.87024,-0.22602,0.81702,-0.2707,0.79271,-0.28909,0.70302,-0.49639,0.63338,-0.49967,0.37254,-0.70729,0.2707,-0.72109,0.40506,-0.54172,0.33509,-0.59691,0.1475,-0.63601,0.09312,-0.59589,-0.07162,-0.54928,-0.0184,-0.54074,-0.07457,-0.47898,
+1,0,-1,-1,-0.50694,1,1,-1,1,0.53819,0,0,0.23958,-1,1,1,0,0,1,1,1,1,0,0,-0.71528,1,0.33333,-1,1,-1,0.69792,-1,0.47569,1,
+1,0,0.84177,0.4346,0.5,0.7616,0.09916,0.9346,-0.37764,0.88186,-0.72363,0.61181,-0.93882,0.19409,-0.86709,-0.25527,-0.62869,-0.65612,-0.25105,-0.85654,0.16245,-0.86498,0.51477,-0.66878,0.74895,-0.28903,0.77937,0.07933,0.64135,0.42827,0.31435,0.62447,-0.00422,0.69409,
+1,0,1,1,0,0,1,-1,-1,-1,1,1,1,-1,0,0,1,-1,1,1,0,0,1,-1,-1,-1,1,1,-1,1,-1,1,0,0,
+1,0,1,0.63548,1,1,0.77123,1,-0.33333,1,-1,1,0,1,-1,1,-1,0,-1,-0.66667,-1,-0.92536,-1,-0.33333,-0.33333,-1,0.19235,-1,1,-1,0,-1,1,-0.66667,
+0,0,-1,1,-1,-1,0,0,-1,1,1,-1,-1,-1,-1,1,0,0,-1,-1,-1,1,0,0,1,-1,1,1,1,-1,1,1,0,0,
+1,0,1,0.06843,1,0.14211,1,0.22108,1,-0.125,1,0.39495,1,0.48981,1,0.58986,-0.375,1,1,0,1,0.92001,1,1,1,1,1,1,1,0.25,1,1,1,1,
+0,0,-1,-1,0,0,0,0,0,0,0,0,0,0,1,-1,0,0,-1,-1,0,0,1,1,1,-1,1,-1,0,0,0,0,0,0,
+1,0,0.64947,-0.07896,0.58264,-0.1438,-0.13129,-0.21384,0.29796,0.04403,0.38096,-0.26339,0.28931,-0.31997,0.03459,-0.18947,0.20269,-0.29441,0.15196,-0.29052,0.09513,-0.31525,0.06556,-0.26795,0.03004,-0.25124,-0.00046,-0.2321,-0.02612,-0.21129,-0.04717,-0.1895,0.01336,-0.27201,
+1,0,0,0,0,0,0,0,0,0,1,-0.33333,0.16667,0.26042,0,0,0,0,0,0,-0.19792,-0.21875,-0.16667,0.90625,-1,0.5,0.04167,0.75,-0.22917,-1,-0.125,-0.27083,-0.19792,-0.9375,
+1,0,1,0.05149,0.99363,0.10123,0.96142,0.14756,0.95513,-0.26496,0.66026,0.54701,0.80426,0.25283,0.73781,0.2738,0.66775,0.28714,0.59615,0.29304,0.52494,0.292,0.45582,0.28476,0.39023,0.27226,0.3293,0.25553,0.27381,0.23568,0.22427,0.21378,0.18086,0.19083,
+1,0,1,-0.09524,-1,-1,-1,-1,1,0.31746,0.81349,0.7619,-1,-1,-1,1,0.47364,1,1,1,0.68839,-1,-1,-1,0.82937,0.36508,1,1,1,0.50794,-1,-0.3254,-1,0.72831,
+1,0,0.93669,-0.0019,0.60761,0.43204,0.92314,-0.40129,0.93123,0.16828,0.96197,0.09061,0.99676,0.08172,0.91586,0.05097,0.84628,-0.25324,0.87379,-0.14482,0.84871,0.26133,0.75081,-0.03641,0.84547,-0.02589,0.87293,-0.02302,0.98544,0.09385,0.78317,-0.10194,0.85841,-0.14725,
+1,0,1,-1,1,1,1,1,1,-0.5,1,1,1,1,1,1,0,0,1,1,1,1,1,-1,1,1,1,0.625,1,-0.75,-0.75,1,1,1,
+1,0,1,0.23058,1,-0.78509,1,-0.10401,1,0.15414,1,0.2782,0.9812,-0.06861,1,0.0661,0.95802,-0.18954,0.83584,-0.15633,0.974,0.03728,0.99624,0.09242,1,-0.01253,0.96238,-0.04597,0.91165,0.03885,1,-0.13722,0.96523,-0.11717,
+1,0,0.36876,-1,-1,-1,-0.07661,1,1,0.95041,0.74597,-0.3871,-1,-0.79313,-0.09677,1,0.48684,0.46502,0.31755,-0.27461,-0.14343,-0.20188,-0.11976,0.06895,0.03021,0.06639,0.03443,-0.01186,-0.00403,-0.01672,-0.00761,0.00108,0.00015,0.00325,
+1,0,0.79847,0.38265,0.80804,-0.16964,1,-0.07653,0.98151,-0.07398,0.70217,0.20663,0.99745,0.02105,0.98214,0.02487,1,-0.13074,0.95663,0.07717,1,0.00191,0.90306,0.30804,1,-0.14541,1,-0.00394,0.75638,0.07908,1,-0.1875,1,-0.0574,
+0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,-1,0,0,1,1,1,-1,1,1,1,0,1,1,1,-1,0,0,
+1,0,1,-0.28428,1,-0.25346,0.94623,-0.35094,1,-0.30566,0.92736,-0.49057,0.90818,-0.44119,0.75723,-0.58899,0.69748,-0.58019,0.59623,-0.57579,0.68459,-0.70975,0.54465,-0.87327,0.49214,-0.73333,0.35504,-0.76054,0.26352,-0.78239,0.16604,-0.73145,0.13994,-0.7,
+1,0,0,0,0,0,0,0,-0.85,-1,0,0,1,-1,0,0,-1,-1,-1,-1,1,-1,-0.6,-1,1,1,-1,-0.2,1,-1,0,1,0,0,
+1,0,1,0.09091,0.95455,-0.09091,0.77273,0,1,0,0.95455,0,1,0.04545,0.90909,-0.04545,1,0,1,0,0.86364,0.09091,0.77273,0.09091,0.90909,0.04545,0.91541,0.02897,0.95455,0.09091,0.86364,-0.09091,0.86364,0.04545,
+0,0,0,0,-1,1,1,1,-1,-1,0,0,-1,-1,-1,-0.3125,-1,-1,1,-1,1,-1,0,0,1,-1,-1,-1,0,0,1,-1,0,0,
+1,0,0.91176,-0.08824,0.97059,0.17647,0.82353,0.08824,0.91176,-0.02941,0.97059,-0.17647,0.97059,0.14706,0.94118,0.02941,1,0,1,0,0.76471,0.11765,0.88235,0.02941,0.85294,0.02941,0.92663,0.026,0.94118,-0.11765,0.97059,0.05882,0.91176,0.05882,
+1,0,-1,1,-1,0.15244,0.28354,1,-1,1,-1,-1,1,1,-1,-0.23476,0.28301,-1,1,1,-0.31402,-1,-1,-1,1,-1,-1,-0.03578,1,-1,-1,-0.32317,0.14939,1,
+1,0,0.47368,-0.10526,0.83781,0.01756,0.83155,0.02615,0.68421,-0.05263,0.68421,0,0.79856,0.05028,0.78315,0.05756,0.84211,0.47368,1,0.05263,0.7255,0.07631,0.70301,0.08141,0.42105,0.21053,0.65419,0.08968,0.52632,-0.21053,0.6015,0.09534,0.57418,0.09719,
+1,0,-0.00641,-0.5,0,0,-0.01923,1,0,0,0,0,0,0,0,0,0,0,0.3141,0.92949,-0.35256,0.74359,-0.34615,-0.80769,0,0,-0.61538,-0.51282,0,0,0,0,0,0,
+1,0,1,0.45455,1,0.54545,0.81818,0.63636,1,-0.09091,1,0,0.81818,-0.45455,0.63636,0.27273,1,-0.63636,1,-0.27273,0.90909,-0.45455,1,0.0775,1,-0.09091,1,0.08867,1,0.36364,1,0.63636,0.72727,0.27273,
+0,0,-1,-1,1,-1,-1,1,0,0,1,-1,1,-1,0,0,0,0,0,0,-1,1,1,-1,-1,1,1,1,0,0,1,0.5,0,0,
+1,0,0.45455,0.09091,0.63636,0.09091,0.27273,0.18182,0.63636,0,0.36364,-0.09091,0.45455,-0.09091,0.48612,-0.01343,0.63636,-0.18182,0.45455,0,0.36364,-0.09091,0.27273,0.18182,0.36364,-0.09091,0.34442,-0.01768,0.27273,0,0.36364,0,0.28985,-0.01832,
+1,0,-1,-0.59677,0,0,-1,0.64516,-0.87097,1,0,0,0,0,0,0,0,0,0,0,-1,-1,0,0,0.29839,0.23387,1,0.51613,0,0,0,0,0,0,
+1,0,1,0.14286,1,0.71429,1,0.71429,1,-0.14286,0.85714,-0.14286,1,0.02534,1,0,0.42857,-0.14286,1,0.03617,1,-0.28571,1,0,0.28571,-0.28571,1,0.04891,1,0.05182,1,0.57143,1,0,
+0,0,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,1,1,
+1,0,0.87032,0.46972,0.53945,0.82161,0.1038,0.95275,-0.38033,0.87916,-0.73939,0.58226,-0.92099,0.16731,-0.82417,-0.24942,-0.59383,-0.63342,-0.24012,-0.82881,0.18823,-0.78699,0.51557,-0.5743,0.69274,-0.24843,0.69097,0.10484,0.52798,0.39762,0.25974,0.56573,-0.06739,0.57552,
+0,0,1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,1,1,1,-1,
+1,0,0.92657,0.04174,0.89266,0.15766,0.86098,0.19791,0.83675,0.36526,0.80619,0.40198,0.76221,0.40552,0.66586,0.4836,0.60101,0.51752,0.53392,0.5218,0.48435,0.54212,0.42546,0.55684,0.3334,0.55274,0.26978,0.54214,0.22307,0.53448,0.14312,0.49124,0.11573,0.46571,
+0,0,1,1,1,-1,1,-1,1,1,0,0,1,-1,0,0,0,0,0,0,-1,1,1,1,0,0,1,1,0,0,-1,-1,0,0,
+1,0,0.93537,0.13645,0.93716,0.25359,0.85705,0.38779,0.79039,0.47127,0.72352,0.59942,0.6526,0.75,0.5083,0.73586,0.41629,0.82742,0.25539,0.85952,0.13712,0.85615,0.00494,0.88869,-0.07361,0.7978,-0.20995,0.78004,-0.33169,0.71454,-0.38532,0.64363,-0.47419,0.55835,
+0,0,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,0,1,-1,1,-1,-1,1,-1,1,
+1,0,0.80627,0.13069,0.73061,0.24323,0.64615,0.19038,0.36923,0.45577,0.44793,0.46439,0.25,0.57308,0.25192,0.37115,0.15215,0.51877,-0.09808,0.575,-0.03462,0.42885,-0.08856,0.44424,-0.14943,0.40006,-0.1994,0.34976,-0.23832,0.29541,-0.26634,0.23896,-0.23846,0.31154,
+0,0,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,
+1,0,0.97467,0.13082,0.9412,0.20036,0.88783,0.32248,0.89009,0.32711,0.8555,0.45217,0.72298,0.52284,0.69946,0.5882,0.58548,0.66893,0.48869,0.70398,0.44245,0.68159,0.35289,0.75622,0.26832,0.7621,0.16813,0.78541,0.07497,0.80439,-0.02962,0.77702,-0.10289,0.74242,
+0,0,0,0,1,1,0,0,1,1,0,0,1,-1,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,0,0,-1,1,0,0,
+1,0,0.92308,0.15451,0.86399,0.29757,0.72582,0.3679,0.70588,0.5683,0.57449,0.62719,0.4327,0.74676,0.31705,0.67697,0.19128,0.76818,0.04686,0.76171,-0.12064,0.76969,-0.18479,0.71327,-0.29291,0.65708,-0.38798,0.58553,-0.46799,0.50131,-0.53146,0.40732,-0.56231,0.35095,
+0,0,0,0,1,1,1,1,0,0,0,0,-1,-1,0,0,-1,-1,0,0,0,0,1,1,0,0,1,1,0,0,-1,1,0,0,
+1,0,0.88804,0.38138,0.65926,0.69431,0.29148,0.87892,-0.06726,0.90135,-0.39597,0.80441,-0.64574,0.56502,-0.8296,0.26906,-0.7894,-0.08205,-0.6278,-0.30942,-0.46637,-0.55605,-0.16449,-0.64338,0.09562,-0.61055,0.30406,-0.48392,0.43227,-0.29838,0.47029,-0.09461,0.42152,0.12556,
+0,0,1,-1,1,1,1,1,1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,1,1,
+1,0,0.73523,-0.38293,0.80151,0.10278,0.78826,0.15266,0.5558,0.05252,1,0.21225,0.71947,0.28954,0.68798,0.32925,0.49672,0.17287,0.64333,-0.02845,0.57399,0.42528,0.5312,0.44872,0.9453,0.57549,0.44174,0.482,0.12473,1,0.3507,0.49721,0.30588,0.49831,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,
+1,0,0.94649,0.00892,0.97287,-0.0026,0.98922,0.00372,0.95801,0.01598,0.94054,0.0353,0.97213,0.04719,0.98625,0.01858,0.94277,0.07135,0.98551,-0.00706,0.9777,0.0498,0.96358,0.07098,0.93274,0.08101,0.95243,0.04356,0.97473,0.00818,0.97845,0.07061,1,-0.0026,
+0,0,1,1,-1,-1,-1,-1,0,0,0,0,-1,-1,0,0,0,0,0,0,-1,1,1,1,0,0,1,-1,0,0,-1,-1,-1,-1,
+1,0,0.50466,-0.169,0.71442,0.01513,0.71063,0.02258,0.68065,0.01282,0.34615,0.05594,0.6905,0.04393,0.68101,0.05058,0.67023,0.05692,0.63403,-0.04662,0.64503,0.06856,0.63077,0.07381,0.84033,0.18065,0.59935,0.08304,0.38228,0.0676,0.56466,0.09046,0.54632,0.09346,
+1,0,0.68729,1,0.91973,-0.76087,0.81773,0.04348,0.76087,0.10702,0.86789,0.73746,0.70067,0.18227,0.7592,0.13712,0.93478,-0.25084,0.70736,0.18729,0.64883,0.24582,0.60201,0.77425,1,-0.53846,0.89262,0.22216,0.7107,0.53846,1,-0.06522,0.56522,0.23913,
+1,0,0.76296,-0.07778,1,-0.2963,1,-0.85741,0.8,0.06111,0.45556,-0.42778,1,-0.12581,1,-0.83519,0.49259,0.01852,0.82222,-0.05926,0.98215,-0.19938,1,0.22037,0.6963,-0.26481,0.92148,-0.24549,0.78889,0.02037,0.87492,-0.27105,1,-0.57037,
+1,0,0.38521,0.15564,0.41245,0.07393,0.26459,0.24125,0.23346,0.1323,0.19455,0.25292,0.24514,0.36965,0.08949,0.22957,-0.03891,0.36965,0.05058,0.24903,0.24903,0.09728,0.07782,0.29961,-0.02494,0.28482,-0.06024,0.26256,-0.14786,0.14786,-0.09339,0.31128,-0.19066,0.28794,
+1,0,0.5754,-0.03175,0.75198,-0.05357,0.61508,-0.0119,0.53968,0.03373,0.61706,0.09921,0.59127,-0.02381,0.62698,0.0119,0.70833,0.02579,0.60317,0.01587,0.47817,-0.02778,0.59127,0.0377,0.5,0.03968,0.61291,-0.01237,0.61706,-0.13492,0.68849,-0.01389,0.625,-0.03175,
+1,0,0.06404,-0.15271,-0.04433,0.05911,0.08374,-0.02463,-0.01478,0.18719,0.06404,0,0.12315,-0.09852,0.05911,0,0.0197,-0.02956,-0.12808,-0.2069,0.06897,0.01478,0.06897,0.02956,0.07882,0.16256,0.28079,-0.04926,-0.05911,-0.0936,0.04433,0.05419,0.07389,-0.10837,
+1,0,0.61857,0.1085,0.70694,-0.06935,0.70358,0.01678,0.74273,0.00224,0.71029,0.15772,0.71588,-0.00224,0.79754,0.066,0.83669,-0.16555,0.6868,-0.0906,0.62528,-0.01342,0.60962,0.11745,0.71253,-0.09508,0.69845,-0.01673,0.63311,0.0481,0.78859,-0.05145,0.65213,-0.04698,
+1,0,0.25316,0.35949,0,0,-0.2962,-1,0,0,0.07595,-0.07342,0,0,0,0,0,0,0,0,0.00759,0.68101,-0.2,0.33671,-0.1038,0.35696,0.0557,-1,0,0,0.06329,-1,0,0,
+1,0,0.88103,-0.00857,0.89818,-0.02465,0.94105,-0.01822,0.89175,-0.12755,0.82208,-0.10932,0.88853,0.01179,0.90782,-0.13719,0.87138,-0.06109,0.90782,-0.02358,0.87996,-0.14577,0.82851,-0.12433,0.90139,-0.19507,0.88245,-0.14903,0.84352,-0.12862,0.88424,-0.18542,0.91747,-0.16827,
+1,0,0.42708,-0.5,0,0,0,0,0.46458,0.51042,0.58958,0.02083,0,0,0,0,0.16458,-0.45417,0.59167,-0.18333,0,0,0,0,0.9875,-0.40833,-1,-1,-0.27917,-0.75625,0,0,0,0,
+1,0,0.88853,0.01631,0.92007,0.01305,0.92442,0.01359,0.89179,-0.10223,0.90103,-0.08428,0.9304,-0.01033,0.93094,-0.08918,0.86025,-0.05057,0.89451,-0.04024,0.88418,-0.12126,0.88907,-0.11909,0.8298,-0.14138,0.86453,-0.11808,0.85536,-0.13051,0.83524,-0.12452,0.86786,-0.12235,
+1,0,0,0,1,0.12889,0.88444,-0.02,0,0,1,-0.42444,1,0.19556,1,-0.05333,1,-0.81556,0,0,1,-0.04,1,-0.18667,0,0,1,-1,0,0,1,0.11778,0.90667,-0.09556,
+1,0,0.81143,0.03714,0.85143,-0.00143,0.79,0.00714,0.79571,-0.04286,0.87571,0,0.85571,-0.06714,0.86429,0.00286,0.82857,-0.05429,0.81,-0.11857,0.76857,-0.08429,0.84286,-0.05,0.77,-0.06857,0.81598,-0.08669,0.82571,-0.10429,0.81429,-0.05,0.82143,-0.15143,
+1,0,0,0,0,0,0,0,0,0,0,0,-1,1,1,0.55172,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,
+1,0,0.4987,0.01818,0.43117,-0.0961,0.50649,-0.04156,0.5013,0.0961,0.44675,0.05974,0.55844,-0.11948,0.51688,-0.03636,0.52727,-0.05974,0.55325,-0.01039,0.48571,-0.03377,0.49091,-0.01039,0.59221,0,0.53215,-0.0328,0.43117,0.03377,0.54545,-0.05455,0.58961,-0.08571,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,0,0,0,0,0,0,
+1,0,1,0.5,1,0.25,0.25,1,0.16851,0.9118,-0.13336,0.80454,-0.34107,0.60793,-0.4382,0.37856,-0.43663,0.16709,-0.36676,0.00678,-0.26477,-0.09025,-0.16178,-0.12964,-0.07782,-0.12744,-0.02089,-0.10242,0.01033,-0.07036,0.02224,-0.04142,0.02249,-0.02017,
+1,0,0,0,0,0,1,1,-1,-1,0,0,1,-0.11111,0,0,0,0,-1,1,1,1,1,-1,0,0,1,-1,0,0,0,0,1,1,
+1,0,0.87048,0.38027,0.64099,0.69212,0.31347,0.86625,-0.03933,0.9074,-0.42173,0.79346,-0.70561,0.5156,-0.81049,0.22735,-0.81136,-0.12539,-0.67474,-0.38102,-0.38334,-0.62861,-0.13013,-0.70762,0.15552,-0.66421,0.38544,-0.51568,0.52573,-0.29897,0.56239,-0.05938,0.5146,0.16645,
+1,0,0,0,0,0,0,0,-1,1,0,0,1,0.37333,-0.12,-0.12,0,0,-1,-1,0,0,1,-1,0,0,1,0.22667,0,0,0,0,0,0,
+1,0,0.88179,0.43491,0.59573,0.77655,0.19672,0.94537,-0.24103,0.92544,-0.62526,0.71257,-0.86443,0.33652,-0.92384,-0.05338,-0.77356,-0.44707,-0.4695,-0.73285,-0.10237,-0.82217,0.26384,-0.7757,0.55984,-0.5591,0.72147,-0.24433,0.72478,0.09599,0.58137,0.38915,0.34749,0.57656,
+1,0,0.32834,0.0252,0.15236,0.21278,0.14919,0.74003,-0.25706,0.92324,-0.10312,0.1938,-0.61352,0.25786,-0.94053,-0.05409,-0.13117,-0.14329,-0.30315,-0.44615,-0.11409,-0.85597,0.02668,-0.22786,0.27942,-0.06295,0.33737,-0.11876,0.27657,-0.11409,0.15078,0.13296,0.12197,0.20468,
+1,0,0.83427,0.39121,0.5404,0.78579,0.12326,0.89402,-0.33221,0.83578,-0.70086,0.59564,-0.86622,0.21909,-0.84442,-0.24164,-0.59714,-0.61894,-0.19354,-0.87787,0.12439,-0.89064,0.51109,-0.72454,0.79143,-0.27734,0.83008,0.08718,0.66592,0.49079,0.37542,0.70011,-0.03983,0.79444,
+1,0,0.62335,-0.0349,0.59085,0.00481,0.60409,-0.07461,0.63177,0.00963,0.62455,-0.07461,0.67028,0.0722,0.62936,-0.08424,0.67509,0.09146,0.67148,0,0.58965,0.10108,0.5006,0.03129,0.65945,0.14079,0.60463,0.02019,0.51384,0.04452,0.61733,-0.00963,0.61372,-0.09146,
+1,0,0.74449,-0.0239,0.70772,0.03309,0.72243,0.16912,0.79228,0.07721,0.81434,0.43934,0.63787,0.00551,0.70772,0.21691,1,0.06066,0.61029,0.05147,0.67463,0.04228,0.52022,-0.25,0.72978,-0.15809,0.61727,0.07124,0.30882,0.0864,0.55916,0.07458,0.60294,0.21691,
+1,0,0.61538,0.18923,0.78157,0.0178,0.77486,0.02647,0.65077,-0.10308,0.77538,0.08,0.73961,0.0506,0.72322,0.05776,0.68615,-0.08923,0.61692,0.16308,0.66233,0.07573,0.63878,0.08041,0.60154,-0.07231,0.58803,0.08767,0.55077,0.25692,0.53389,0.09207,0.50609,0.09322,
+1,0,0.68317,0.05375,0.84803,0.00202,0.84341,0.00301,0.843,0.09901,0.75813,0.04102,0.81892,0.00585,0.80738,0.00673,0.80622,-0.12447,0.77935,-0.03536,0.76365,0.00909,0.74635,0.00978,0.79632,-0.04243,0.70824,0.01096,0.62235,0.11598,0.66624,0.0119,0.64407,0.01227,
+1,0,0.5,0,0.38696,0.10435,0.4913,0.06522,0.46957,-0.03913,0.35652,-0.12609,0.45652,0.04783,0.50435,0.02609,0.35652,0.19565,0.42174,0.14783,0.42174,-0.02609,0.32174,-0.11304,0.47391,-0.0087,0.41789,0.06908,0.38696,0.03913,0.35217,0.14783,0.44783,0.17391,
+1,0,0.7983,0.09417,0.78129,0.20656,0.71628,0.28068,0.6932,0.41252,0.65917,0.50122,0.57898,0.60814,0.4921,0.58445,0.33354,0.67861,0.29587,0.63548,0.09599,0.68104,0.02066,0.72236,-0.08748,0.63183,-0.11925,0.60696,-0.18226,0.56015,-0.25516,0.51701,-0.27339,0.42467,
+1,0,1,0.09802,1,0.25101,0.9839,0.33044,0.80365,0.5302,0.74977,0.60297,0.56937,0.71942,0.55311,0.74079,0.29452,0.82193,0.21137,0.79777,0.09709,0.82162,-0.01734,0.7987,-0.15144,0.75596,-0.22839,0.69187,-0.31713,0.60948,-0.40291,0.54522,-0.42815,0.44534,
+1,0,0.8941,0.13425,0.87001,0.31543,0.78896,0.43388,0.63388,0.59975,0.54003,0.71016,0.39699,0.76161,0.24266,0.79523,0.09134,0.79598,-0.09159,0.76261,-0.20201,0.66926,-0.30263,0.6261,-0.40552,0.50489,-0.46215,0.40753,-0.50314,0.27252,-0.52823,0.19172,-0.48808,0.05972,
+1,0,0.94631,0.17498,0.90946,0.33143,0.85096,0.4996,0.73678,0.63842,0.59215,0.73838,0.48698,0.83614,0.30459,0.90665,0.17959,0.93429,-0.00701,0.93109,-0.1888,0.89383,-0.33023,0.82492,-0.46534,0.76482,-0.58563,0.66335,-0.67929,0.52564,-0.75321,0.42488,-0.8121,0.26092,
+1,0,0.91767,0.18198,0.8609,0.35543,0.72873,0.45747,0.60425,0.69865,0.50376,0.74922,0.361,0.81795,0.15664,0.83558,0.00396,0.8521,-0.1639,0.77853,-0.35996,0.76193,-0.43087,0.65385,-0.5314,0.53886,-0.60328,0.40972,-0.64511,0.27338,-0.6571,0.13667,-0.64056,0.05394,
+1,0,0.76627,0.21106,0.63935,0.38112,0.48409,0.525,0.15,0.22273,0.13753,0.59565,-0.07727,0.44545,0,0.48636,-0.27491,0.42014,-0.56136,0.36818,-0.36591,0.18864,-0.40533,0.07588,-0.38483,-0.03229,-0.33942,-0.12486,-0.2754,-0.19714,-0.19962,-0.24648,-0.11894,-0.27218,
+1,0,0.5894,-0.60927,0.8543,0.55298,0.81126,0.07285,0.56623,0.16225,0.32781,0.24172,0.50331,0.12252,0.63907,0.19868,0.71854,0.42715,0.54305,0.13907,0.65232,0.27815,0.68874,0.07285,0.51872,0.26653,0.49013,0.27687,0.46216,0.28574,0.43484,0.29324,0.40821,0.29942,
+1,0,1,0.11385,0.70019,-0.12144,0.81594,0.09677,0.71157,0.01139,0.56167,-0.0778,0.6907,0.12524,0.58634,0.03985,0.53131,-0.03416,0.6945,0.16888,0.72676,0.07211,0.32068,0.05882,0.53321,0.37381,0.4909,0.17951,0.1518,0.32448,0.44141,0.18897,0.56167,0.1518,
+1,0,0.84843,0.06794,0.80562,-0.02299,0.77031,-0.03299,0.66725,-0.0662,0.59582,-0.07666,0.6726,-0.05771,0.6426,-0.06438,0.39199,0.0453,0.71254,0.01394,0.5597,-0.08039,0.5343,-0.08453,0.47038,-0.22822,0.48659,-0.09128,0.52613,-0.08537,0.44277,-0.09621,0.42223,-0.09808,
+1,0,1,0.08013,0.96775,-0.00482,0.96683,-0.00722,0.8798,-0.03923,1,0.01419,0.96186,-0.01436,0.95947,-0.01671,0.98497,0.01002,0.91152,-0.08848,0.95016,-0.02364,0.94636,-0.02591,0.98164,0.02003,0.93772,-0.03034,1,-0.05843,0.92774,-0.03464,0.92226,-0.03673,
+1,0,0.47938,-0.12371,0.42784,-0.12371,0.70103,-0.39175,0.73196,0.07216,0.26289,-0.21649,0.49485,0.15979,0.45361,-0.11856,0.42268,0.06186,0.5,-0.2732,0.54639,0.18557,0.42268,0.08247,0.70619,0.19588,0.53396,-0.12447,0.15464,-0.26289,0.47423,0.04124,0.45361,-0.51546,
+1,0,0.6351,-0.04388,0.7653,0.02968,0.61432,0.36028,0.65358,-0.00462,0.64203,0.08314,0.79446,-0.43418,0.72517,0.54965,0.59584,0.13857,0.6351,0.2194,0.63279,-0.25404,0.70951,0.15359,0.64665,0.23095,0.68775,0.17704,0.61663,0.07621,0.66316,0.19841,0.69053,0.36721,
+1,0,0.50112,-0.03596,0.61124,0.01348,0.58876,0.01573,0.58876,0.02472,0.66742,-0.00449,0.71685,-0.04719,0.66517,0.00899,0.57303,0.02472,0.64719,-0.07416,0.56854,0.14157,0.57528,-0.03596,0.46517,0.04944,0.56588,0.00824,0.4764,-0.03596,0.54607,0.10562,0.60674,-0.0809,
+1,0,0.71521,-0.00647,0.66667,-0.04207,0.63107,-0.05178,0.77994,0.08091,0.67314,0.09709,0.64725,0.15858,0.60194,-0.01942,0.54369,-0.04531,0.46926,-0.10032,0.64725,0.14887,0.39159,0.21683,0.52427,-0.05502,0.45105,0.0004,0.31392,-0.06796,0.49191,-0.1068,0.30421,-0.05178,
+1,0,0.68148,0.1037,0.77037,0.03457,0.65185,0.08148,0.60988,-0.00494,0.79012,0.11852,0.59753,0.04938,0.62469,0.0963,0.78272,-0.17531,0.73827,-0.10864,0.48642,0.00988,0.60988,0.08148,0.66667,-0.1284,0.63773,-0.02451,0.76543,0.02222,0.61235,-0.0716,0.51358,-0.04691,
+1,0,0.60678,-0.02712,0.67119,0.04068,0.52881,-0.04407,0.50508,0.03729,0.70508,-0.07797,0.57966,-0.02034,0.5322,0.07797,0.64068,0.11864,0.56949,-0.02373,0.5322,0.00678,0.71525,-0.0339,0.52881,-0.0339,0.57262,0.0075,0.58644,-0.00339,0.58983,-0.02712,0.50169,0.0678,
+1,0,0.49515,0.09709,0.29612,0.05825,0.34951,0,0.57282,-0.02427,0.58252,0.02427,0.33495,0.04854,0.52427,0.00485,0.47087,-0.1068,0.43204,0.00485,0.34951,0.05825,0.18932,0.25728,0.31068,-0.15049,0.36547,0.03815,0.3932,0.17476,0.26214,0,0.37379,-0.01942,
+1,0,0.98822,0.02187,0.93102,0.341,0.83904,0.35222,0.74706,0.48906,0.73584,0.51879,0.55076,0.60179,0.4313,0.66237,0.318,0.70443,0.28379,0.68873,0.07515,0.73696,0.06338,0.71284,-0.16489,0.69714,-0.16556,0.6051,-0.16209,0.55805,-0.34717,0.44195,-0.33483,0.37465,
+1,0,0.97905,0.1581,0.90112,0.35237,0.82039,0.48561,0.7176,0.64888,0.58827,0.73743,0.40349,0.83156,0.2514,0.84804,0.047,0.85475,-0.12193,0.79749,-0.2618,0.80754,-0.37835,0.71676,-0.51034,0.58324,-0.57587,0.4604,-0.61899,0.30796,-0.65754,0.18345,-0.64134,0.02968,
+1,0,0.99701,0.21677,0.91966,0.4703,0.76902,0.62415,0.53312,0.7812,0.36774,0.88291,0.10107,0.83312,-0.06827,0.89274,-0.28269,0.72073,-0.43707,0.61688,-0.55769,0.4812,-0.65,0.35534,-0.64658,0.15908,-0.66651,0.02277,-0.64872,-0.13462,-0.54615,-0.22949,-0.47201,-0.35032,
+1,0,0.94331,0.19959,0.96132,0.40803,0.80514,0.56569,0.56687,0.7083,0.41836,0.8323,0.14939,0.89489,0.05167,0.93682,-0.24742,0.83939,-0.42811,0.75554,-0.50251,0.62563,-0.65515,0.50428,-0.68851,0.30912,-0.77097,0.15619,-0.75406,-0.04399,-0.75199,-0.17921,-0.66932,-0.34367,
+1,0,0.93972,0.28082,0.80486,0.52821,0.58167,0.73151,0.34961,0.80511,0.10797,0.90403,-0.20015,0.89335,-0.3973,0.82163,-0.58835,0.62867,-0.76305,0.40368,-0.81262,0.18888,-0.81317,-0.04284,-0.75273,-0.26883,-0.63237,-0.46438,-0.46422,-0.61446,-0.26389,-0.70835,-0.08937,-0.71273,
+1,0,0.89835,0.35157,0.67333,0.62233,0.43898,0.94353,-0.03643,0.8051,-0.22838,0.75334,-0.25137,0.48816,-0.57377,0.28415,-0.6675,0.10591,-0.47359,-0.06193,-0.81056,-0.06011,-0.33197,-0.47592,-0.12897,-0.5362,0.07158,-0.51925,0.24321,-0.43478,0.36586,-0.30057,0.42805,0.13297,
+1,0,0.29073,0.10025,0.23308,0.17293,0.03759,0.34336,0.1203,0.26316,0.06266,0.21303,-0.04725,0.12767,-0.06333,0.07907,-0.06328,0.04097,-0.05431,0.01408,-0.04166,-0.0028,-0.02876,-0.01176,-0.01755,-0.01505,-0.00886,-0.01475,-0.0028,-0.0125,0.00096,-0.00948,0.0029,-0.00647,
+1,0,0.58459,-0.35526,1,0.35338,0.75376,-0.00564,0.82519,0.19361,0.50188,-0.27632,0.65977,0.06391,0.69737,0.14662,0.72368,-0.42669,0.76128,0.04511,0.66917,0.20489,0.84774,-0.40977,0.6485,-0.04699,0.56836,-0.10571,0.5282,-0.13346,0.15602,-0.12218,0.44767,-0.10309,
+1,0,0.83609,0.13215,0.72171,0.06059,0.65829,0.08315,0.23888,0.12961,0.43837,0.2033,0.49418,0.12686,0.44747,0.13507,0.29352,0.02922,0.48158,0.15756,0.32835,0.14616,0.29495,0.14638,0.26436,0.1453,0.23641,0.14314,0.26429,0.16137,0.18767,0.13632,0.16655,0.13198,
+1,0,0.9408,0.11933,0.85738,0.01038,0.85124,0.01546,0.76966,-0.00278,0.84459,0.10916,0.83289,0.03027,0.8268,0.03506,0.74838,0.01943,0.80019,0.02405,0.80862,0.04901,0.80259,0.05352,0.77336,0.0222,0.79058,0.06235,0.85939,0.09251,0.77863,0.0709,0.77269,0.07508,
+1,0,0.87111,0.04326,0.79946,0.18297,0.99009,0.29292,0.89455,-0.08337,0.88598,-0.02028,0.90446,-0.26724,0.8941,0.19964,0.88644,-0.04642,0.84452,-0.00991,0.97882,-0.34024,0.78954,-0.25101,0.86661,-0.09193,0.85967,-0.02908,0.78774,-0.04101,0.75935,0.21812,0.88238,0.09193,
+1,0,0.74916,0.02549,0.98994,0.09792,0.75855,0.12877,0.74313,-0.09188,0.95842,0.02482,0.97921,-0.00469,0.9611,0.10195,0.91482,0.03756,0.71026,0.02683,0.81221,-0.08048,1,0,0.71764,-0.01207,0.82271,0.02552,0.72435,-0.01073,0.90409,0.11066,0.72837,0.0275,
+1,0,0.47337,0.19527,0.06213,-0.18343,0.62316,0.01006,0.45562,-0.04438,0.56509,0.01775,0.44675,0.27515,0.71598,-0.03846,0.55621,0.12426,0.4142,0.11538,0.52767,0.02842,0.51183,-0.10651,0.47929,-0.02367,0.46514,0.03259,0.5355,0.25148,0.31953,-0.14497,0.34615,-0.00296,
+1,0,0.59887,0.14689,0.69868,-0.13936,0.85122,-0.13936,0.80979,0.02448,0.50471,0.02825,0.6742,-0.0452,0.80791,-0.13748,0.51412,-0.24482,0.81544,-0.14313,0.70245,-0.00377,0.33333,0.06215,0.56121,-0.33145,0.61444,-0.16837,0.52731,-0.02072,0.53861,-0.31262,0.6742,-0.22034,
+1,0,0.84713,-0.03397,0.86412,-0.08493,0.81953,0,0.73673,-0.07643,0.71975,-0.13588,0.74947,-0.11677,0.77495,-0.18684,0.78132,-0.21231,0.61996,-0.10191,0.79193,-0.15711,0.89384,-0.03397,0.84926,-0.26115,0.74115,-0.23312,0.66242,-0.22293,0.72611,-0.37792,0.65817,-0.24841,
+1,0,0.87772,-0.08152,0.83424,0.07337,0.84783,0.04076,0.77174,-0.02174,0.77174,-0.05707,0.82337,-0.10598,0.67935,-0.00543,0.88043,-0.20924,0.83424,0.03261,0.86413,-0.05978,0.97283,-0.27989,0.85054,-0.1875,0.83705,-0.10211,0.8587,-0.03261,0.78533,-0.1087,0.79076,-0.00543,
+1,0,0.74704,-0.13241,0.53755,0.16996,0.72727,0.09486,0.69565,-0.11067,0.66798,-0.23518,0.87945,-0.1917,0.73715,0.0415,0.63043,-0.00395,0.63636,-0.11858,0.79249,-0.25296,0.66403,-0.28656,0.67194,-0.10474,0.61847,-0.12041,0.60079,-0.20949,0.37549,0.06917,0.61067,-0.01383,
+1,0,0.46785,0.11308,0.5898,0.00665,0.55432,0.06874,0.47894,-0.13969,0.52993,0.0133,0.63858,-0.16186,0.67849,-0.03326,0.54545,-0.13525,0.52993,-0.04656,0.47894,-0.19512,0.50776,-0.13525,0.41463,-0.20177,0.5393,-0.11455,0.59867,-0.02882,0.53659,-0.11752,0.56319,-0.04435,
+1,0,0.88116,0.27475,0.72125,0.42881,0.61559,0.63662,0.38825,0.90502,0.09831,0.96128,-0.20097,0.892,-0.35737,0.775,-0.65114,0.6221,-0.78768,0.45535,-0.81856,0.19095,-0.83943,-0.08079,-0.78334,-0.26356,-0.67557,-0.45511,-0.54732,-0.60858,-0.30512,-0.667,-0.19312,-0.75597,
+1,0,0.93147,0.29282,0.79917,0.55756,0.59952,0.71596,0.26203,0.92651,0.04636,0.96748,-0.23237,0.9513,-0.55926,0.81018,-0.73329,0.62385,-0.90995,0.362,-0.92254,0.0604,-0.93618,-0.19838,-0.83192,-0.46906,-0.65165,-0.69556,-0.41223,-0.85725,-0.1359,-0.93953,0.10007,-0.94823,
+1,0,0.88241,0.30634,0.73232,0.57816,0.34109,0.58527,0.05717,1,-0.09238,0.92118,-0.62403,0.71996,-0.69767,0.32558,-0.81422,0.41195,-1,-0.00775,-0.78973,-0.41085,-0.76901,-0.45478,-0.57242,-0.67605,-0.3161,-0.81876,-0.02979,-0.86841,0.25392,-0.82127,0.00194,-0.81686,
+1,0,0.83479,0.28993,0.69256,0.47702,0.49234,0.68381,0.21991,0.86761,-0.08096,0.85011,-0.35558,0.77681,-0.52735,0.58425,-0.7035,0.31291,-0.75821,0.03939,-0.71225,-0.15317,-0.58315,-0.39168,-0.37199,-0.52954,-0.1695,-0.60863,0.08425,-0.61488,0.25164,-0.48468,0.40591,-0.35339,
+1,0,0.9287,0.33164,0.76168,0.62349,0.49305,0.84266,0.21592,0.95193,-0.13956,0.96167,-0.47202,0.8359,-0.70747,0.6549,-0.87474,0.3675,-0.91814,0.05595,-0.89824,-0.26173,-0.73969,-0.54069,-0.50757,-0.74735,-0.22323,-0.86122,0.0781,-0.87159,0.36021,-0.78057,0.59407,-0.6027,
+1,0,0.83367,0.31456,0.65541,0.57671,0.34962,0.70677,0.17293,0.78947,-0.18976,0.79886,-0.41729,0.66541,-0.68421,0.47744,-0.74725,0.19492,-0.7218,-0.04887,-0.6203,-0.28195,-0.49165,-0.53463,-0.26577,-0.66014,-0.0153,-0.69706,0.22708,-0.64428,0.431,-0.51206,0.64662,-0.30075,
+1,0,0.98455,-0.02736,0.98058,-0.04104,1,-0.07635,0.9872,0.01456,0.95278,-0.02604,0.985,-0.07458,0.99382,-0.07149,0.97396,-0.09532,0.97264,-0.12224,0.99294,-0.05252,0.95278,-0.08914,0.97352,-0.08341,0.96653,-0.12912,0.93469,-0.14916,0.97132,-0.15755,0.96778,-0.188,
+1,0,0.94052,-0.01531,0.9417,0.01001,0.94994,-0.01472,0.95878,-0.0106,0.94641,-0.0371,0.97173,-0.01767,0.97055,-0.03887,0.95465,-0.04064,0.9523,-0.04711,0.94229,-0.02179,0.92815,-0.04417,0.92049,-0.04476,0.92695,-0.05827,0.90342,-0.07479,0.91991,-0.07244,0.92049,-0.0742,
+1,0,0.97032,-0.14384,0.91324,-0.00228,0.96575,-0.17123,0.9863,0.18265,0.91781,0.00228,0.93607,-0.08447,0.91324,-0.00228,0.86758,-0.08676,0.97032,-0.21233,1,0.10274,0.92009,-0.05251,0.92466,0.06849,0.94043,-0.09252,0.97032,-0.20091,0.85388,-0.08676,0.96575,-0.21918,
+1,0,0.52542,-0.0339,0.94915,0.08475,0.52542,-0.16949,0.30508,-0.01695,0.50847,-0.13559,0.64407,0.28814,0.83051,-0.35593,0.54237,0.01695,0.55932,0.0339,0.59322,0.30508,0.86441,0.05085,0.40678,0.15254,0.67287,-0.00266,0.66102,-0.0339,0.83051,-0.15254,0.76271,-0.10169,
+1,0,0.33333,-0.25,0.44444,0.22222,0.38889,0.16667,0.41667,0.13889,0.5,-0.11111,0.54911,-0.08443,0.58333,0.33333,0.55556,0.02778,0.25,-0.19444,0.47222,-0.05556,0.52778,-0.02778,0.38889,0.08333,0.41543,-0.14256,0.19444,-0.13889,0.36924,-0.14809,0.08333,-0.5,
+1,0,0.51207,1,1,0.5381,0.71178,0.80833,0.45622,0.46427,0.33081,1,0.21249,1,-0.17416,1,-0.33081,0.98722,-0.61382,1,-0.52674,0.71699,-0.885,0.47894,-1,0.35175,-1,0.09569,-1,-0.16713,-1,-0.42226,-0.91903,-0.65557,
+1,0,0.75564,0.49638,0.8355,0.54301,0.54916,0.72063,0.35225,0.70792,0.13469,0.94749,-0.09818,0.93778,-0.37604,0.82223,-0.52742,0.71161,-0.68358,0.67989,-0.70163,0.24956,-0.79147,0.02995,-0.98988,-0.29099,-0.70352,-0.32792,-0.63312,-0.19185,-0.34131,-0.60454,-0.19609,-0.62956,
+1,0,0.83789,0.42904,0.72113,0.58385,0.45625,0.78115,0.1647,0.82732,-0.13012,0.86947,-0.46177,0.78497,-0.59435,0.5207,-0.7847,0.26529,-0.84014,0.03928,-0.62041,-0.31351,-0.47412,-0.48905,-0.37298,-0.67796,-0.05054,-0.62691,0.1469,-0.45911,0.37093,-0.39167,0.48319,-0.24313,
+1,0,0.93658,0.35107,0.75254,0.6564,0.45571,0.88576,0.15323,0.95776,-0.21775,0.96301,-0.56535,0.83397,-0.78751,0.58045,-0.93104,0.2602,-0.93641,-0.06418,-0.87028,-0.40949,-0.65079,-0.67464,-0.36799,-0.84951,-0.04578,-0.91221,0.2733,-0.85762,0.54827,-0.69613,0.74828,-0.44173,
+1,0,0.92436,0.36924,0.71976,0.6842,0.29303,0.94078,-0.11108,0.76527,-0.31605,0.92453,-0.66616,0.78766,-0.92145,0.42314,-0.94315,0.09585,-1,0.03191,-0.66431,-0.66278,-0.4601,-0.78174,-0.13486,-0.88082,0.19765,-0.85137,0.48904,-0.70247,0.69886,-0.46048,0.76066,-0.13194,
+1,0,1,0.16195,1,-0.05558,1,0.01373,1,-0.12352,1,-0.01511,1,-0.01731,1,-0.06374,1,-0.07157,1,0.059,1,-0.10108,1,-0.02685,1,-0.22978,1,-0.06823,1,0.08299,1,-0.14194,1,-0.07439,
+1,0,0.95559,-0.00155,0.86421,-0.13244,0.94982,-0.00461,0.82809,-0.51171,0.92441,0.10368,1,-0.14247,0.99264,-0.02542,0.95853,-0.15518,0.84013,0.61739,1,-0.16321,0.87492,-0.08495,0.85741,-0.01664,0.84132,-0.01769,0.82427,-0.01867,0.80634,-0.01957,0.78761,-0.02039,
+1,0,0.79378,0.29492,0.64064,0.52312,0.41319,0.68158,0.14177,0.83548,-0.16831,0.78772,-0.42911,0.72328,-0.57165,0.41471,-0.75436,0.16755,-0.69977,-0.09856,-0.57695,-0.23503,-0.40637,-0.38287,-0.17437,-0.5254,0.01523,-0.48707,0.1903,-0.38059,0.31008,-0.23199,0.34572,-0.08036,
+1,0,0.88085,0.35232,0.68389,0.65128,0.34816,0.79784,0.05832,0.90842,-0.29784,0.8649,-0.62635,0.6959,-0.77106,0.39309,-0.85803,0.08408,-0.81641,-0.24017,-0.64579,-0.50022,-0.39766,-0.68337,-0.11147,-0.75533,0.17041,-0.71504,0.40675,-0.57649,0.56626,-0.36765,0.62765,-0.13305,
+1,0,0.89589,0.39286,0.66129,0.71804,0.29521,0.90824,-0.04787,0.94415,-0.45725,0.84605,-0.7766,0.58511,-0.92819,0.25133,-0.92282,-0.15315,-0.76064,-0.48404,-0.50931,-0.76197,-0.14895,-0.88591,0.21581,-0.85703,0.53229,-0.68593,0.74846,-0.40656,0.83142,-0.07029,0.76862,0.27926,
+1,0,1,-0.24051,1,-0.20253,0.87342,-0.10127,0.88608,0.01266,1,0.11392,0.92405,0.06329,0.8481,-0.03797,0.63291,-0.36709,0.87342,-0.01266,0.93671,0.06329,1,0.25316,0.62025,-0.37975,0.84637,-0.0554,1,-0.06329,0.53165,0.02532,0.83544,-0.02532,
+1,0,0.7479,0.0084,0.83312,0.01659,0.82638,0.02469,0.86555,0.01681,0.60504,0.05882,0.79093,0.04731,0.77441,0.05407,0.64706,0.19328,0.84034,0.04202,0.71285,0.07122,0.68895,0.07577,0.66387,0.08403,0.63728,0.08296,0.61345,0.01681,0.58187,0.08757,0.5533,0.08891,
+1,0,0.85013,0.01809,0.92211,0.01456,0.92046,0.0218,0.92765,0.0801,0.87597,0.1137,0.91161,0.0432,0.90738,0.05018,0.87339,0.02842,0.95866,0,0.89097,0.07047,0.8843,0.07697,0.83721,0.10853,0.86923,0.0895,0.87597,0.08786,0.85198,0.10134,0.84258,0.10698,
+1,0,1,-0.01179,1,-0.00343,1,-0.01565,1,-0.01565,1,-0.02809,1,-0.02187,0.99828,-0.03087,0.99528,-0.03238,0.99314,-0.03452,1,-0.03881,1,-0.05039,1,-0.04931,0.99842,-0.05527,0.994,-0.06304,0.99057,-0.06497,0.98971,-0.06668,
+1,0,0.89505,-0.03168,0.87525,0.05545,0.89505,0.01386,0.92871,0.02772,0.91287,-0.0099,0.94059,-0.01584,0.91881,0.03366,0.93663,0,0.94257,0.01386,0.90495,0.00792,0.88713,-0.01782,0.89307,0.02376,0.89002,0.01611,0.88119,0.00198,0.87327,0.04158,0.86733,0.02376,
+1,0,0.90071,0.01773,1,-0.01773,0.90071,0.00709,0.84752,0.05674,1,0.03546,0.97872,0.01064,0.97518,0.03546,1,-0.03191,0.89716,-0.03191,0.8617,0.07801,1,0.0922,0.90071,0.0461,0.94305,0.03247,0.94681,0.02482,1,0.01064,0.93617,0.02128,
+1,0,0.39394,-0.24242,0.62655,0.0127,0.45455,0.09091,0.63636,0.09091,0.21212,-0.21212,0.57576,0.15152,0.39394,0,0.56156,0.04561,0.51515,0.0303,0.78788,0.18182,0.30303,-0.15152,0.48526,0.05929,0.46362,0.06142,0.33333,-0.0303,0.41856,0.0641,0.39394,0.24242,
+1,0,0.86689,0.3595,0.72014,0.66667,0.37201,0.83049,0.08646,0.85893,-0.24118,0.86121,-0.51763,0.67577,-0.68714,0.41524,-0.77019,0.09898,-0.69397,-0.13652,-0.49488,-0.42207,-0.32537,-0.57679,-0.02844,-0.59954,0.1536,-0.53127,0.32309,-0.37088,0.46189,-0.19681,0.40956,0.0182,
+1,0,0.89563,0.37917,0.67311,0.69438,0.35916,0.88696,-0.04193,0.93345,-0.38875,0.84414,-0.67274,0.62078,-0.8268,0.30356,-0.8615,-0.05365,-0.73564,-0.34275,-0.51778,-0.62443,-0.23428,-0.73855,0.06911,-0.73856,0.33531,-0.62296,0.52414,-0.42086,0.61217,-0.17343,0.60073,0.0866,
+1,0,0.90547,0.41113,0.65354,0.74761,0.29921,0.95905,-0.13342,0.9782,-0.52236,0.83263,-0.79657,0.55086,-0.96631,0.15192,-0.93001,-0.25554,-0.71863,-0.59379,-0.41546,-0.85205,-0.0225,-0.93788,0.36318,-0.85368,0.67538,-0.61959,0.85977,-0.28123,0.88654,0.098,0.75495,0.46301,
+1,0,1,1,0.367,0.06158,0.12993,0.92713,-0.27586,0.93596,-0.31527,0.37685,-0.87192,0.36946,-0.92857,-0.08867,-0.38916,-0.34236,-0.46552,-0.82512,-0.05419,-0.93596,0.25616,-0.20443,0.73792,-0.4595,0.85471,-0.06831,1,1,0.3867,0.00246,0.17758,0.7979,
+1,0,1,0.51515,0.45455,0.33333,0.06061,0.36364,-0.32104,0.73062,-0.45455,0.48485,-0.57576,0,-0.57576,-0.12121,-0.33333,-0.48485,-0.09091,-0.84848,0.48485,-0.57576,0.57576,-0.42424,1,-0.39394,0.72961,0.12331,0.9697,0.57576,0.24242,0.36364,0.09091,0.33333,
+1,0,0.8811,0,0.94817,-0.02744,0.93598,-0.0122,0.90244,0.01829,0.90244,0.01829,0.93902,0.00915,0.95732,0.00305,1,0.02744,0.94207,-0.0122,0.90854,0.02439,0.91463,0.05488,0.99695,0.04878,0.89666,0.02226,0.90854,0.00915,1,0.05488,0.97561,-0.0122,
+1,0,0.82624,0.08156,0.79078,-0.08156,0.90426,-0.01773,0.92908,0.01064,0.80142,0.08865,0.94681,-0.00709,0.94326,0,0.93262,0.20213,0.95035,-0.00709,0.91489,0.00709,0.80496,0.07092,0.91135,0.15957,0.89527,0.08165,0.7766,0.06738,0.92553,0.18085,0.92553,0,
+1,0,0.74468,0.10638,0.88706,0.00982,0.88542,0.01471,0.87234,-0.01418,0.7305,0.10638,0.87657,0.02912,0.87235,0.03382,0.95745,0.07801,0.95035,0.04255,0.85597,0.04743,0.84931,0.05178,0.87234,0.11348,0.83429,0.06014,0.74468,-0.03546,0.8171,0.068,0.80774,0.07173,
+1,0,0.87578,0.03727,0.89951,0.00343,0.8921,0.0051,0.86335,0,0.95031,0.07453,0.87021,0.00994,0.86303,0.01151,0.83851,-0.06211,0.85714,0.02484,0.84182,0.01603,0.83486,0.01749,0.79503,-0.04348,0.82111,0.02033,0.81988,0.08696,0.80757,0.02308,0.80088,0.02441,
+1,0,0.97513,0.0071,0.98579,0.01954,1,0.01954,0.9929,0.01599,0.95737,0.02309,0.97158,0.03552,1,0.0373,0.97869,0.02131,0.98579,0.05684,0.97158,0.04796,0.94494,0.05506,0.98401,0.03552,0.9754,0.06477,0.94849,0.08171,0.99112,0.06217,0.98934,0.09947,
+1,0,1,0.01105,1,0.01105,1,0.0232,0.99448,-0.01436,0.99448,-0.00221,0.98343,0.0232,1,0.00884,0.97569,0.00773,0.97901,0.01657,0.98011,0.00663,0.98122,0.02099,0.97127,-0.00663,0.98033,0.016,0.97901,0.01547,0.98564,0.02099,0.98674,0.02762,
+1,0,1,-0.01342,1,0.01566,1,-0.00224,1,0.06264,0.97763,0.04474,0.95973,0.02908,1,0.06488,0.98881,0.03356,1,0.03579,0.99776,0.09396,0.95749,0.07383,1,0.10067,0.99989,0.08763,0.99105,0.08501,1,0.10067,1,0.10067,
+1,0,0.8842,0.36724,0.67123,0.67382,0.39613,0.86399,0.02424,0.93182,-0.35148,0.83713,-0.60316,0.58842,-0.78658,0.38778,-0.83285,-0.00642,-0.69318,-0.32963,-0.52504,-0.53924,-0.27377,-0.68126,0.00806,-0.69774,0.26028,-0.60678,0.44569,-0.43383,0.54209,-0.21542,0.56286,0.02823,
+1,0,0.90147,0.41786,0.64131,0.75725,0.3044,0.95148,-0.20449,0.96534,-0.55483,0.81191,-0.81857,0.50949,-0.96986,0.10345,-0.91456,-0.31412,-0.70163,-0.65461,-0.32354,-0.88999,0.05865,-0.94172,0.44483,-0.82154,0.74105,-0.55231,0.89415,-0.18725,0.87893,0.20359,0.70555,0.54852,
+1,0,0.32789,0.11042,0.1597,0.29308,0.1402,0.74485,-0.25131,0.91993,-0.16503,0.26664,-0.63714,0.24865,-0.9765,-0.00337,-0.23227,-0.19909,-0.30522,-0.48886,-0.14426,-0.89991,0.09345,-0.28916,0.28307,-0.1856,0.39599,-0.11498,0.31005,0.05614,0.21443,0.2054,0.13376,0.26422,
+1,0,0.65845,0.43617,0.44681,0.74804,0.05319,0.85106,-0.32027,0.82139,-0.68253,0.52408,-0.84211,0.07111,-0.82811,-0.28723,-0.47032,-0.71725,-0.04759,-0.86002,0.23292,-0.76316,0.56663,-0.52128,0.743,-0.18645,0.74758,0.23713,0.45185,0.59071,0.20549,0.76764,-0.18533,0.74356,
+1,0,0.19466,0.05725,0.04198,0.25191,-0.10557,0.48866,-0.18321,-0.18321,-0.41985,0.06107,-0.4542,0.0916,-0.16412,-0.30534,-0.10305,-0.39695,0.18702,-0.17557,0.34012,-0.11953,0.28626,-0.16031,0.21645,0.24692,0.03913,0.31092,-0.03817,0.26336,-0.16794,0.16794,-0.30153,-0.33588,
+1,0,0.98002,0.00075,1,0,0.98982,-0.00075,0.94721,0.02394,0.977,0.0213,0.97888,0.03073,0.9917,0.02338,0.93929,0.05713,0.93552,0.05279,0.97738,0.05524,1,0.06241,0.94155,0.08107,0.96709,0.07255,0.95701,0.08088,0.9819,0.08126,0.97247,0.08616,
+1,0,0.82254,-0.07572,0.80462,0.00231,0.87514,-0.01214,0.86821,-0.07514,0.72832,-0.11734,0.84624,0.05029,0.83121,-0.07399,0.74798,0.06705,0.78324,0.06358,0.86763,-0.0237,0.78844,-0.06012,0.74451,-0.0237,0.76717,-0.02731,0.74046,-0.0763,0.70058,-0.0422,0.78439,0.01214,
+1,0,0.35346,-0.13768,0.69387,-0.02423,0.68195,-0.03574,0.55717,-0.06119,0.61836,-0.10467,0.62099,-0.06527,0.59361,-0.07289,0.42271,-0.26409,0.58213,0.04992,0.49736,-0.08771,0.46241,-0.08989,0.45008,-0.00564,0.39146,-0.09038,0.35588,-0.10306,0.32232,-0.08637,0.28943,-0.083,
+1,0,0.76046,0.01092,0.86335,0.00258,0.85821,0.00384,0.79988,0.02304,0.81504,0.12068,0.83096,0.00744,0.81815,0.00854,0.82777,-0.06974,0.76531,0.03881,0.76979,0.01148,0.75071,0.01232,0.77138,-0.00303,0.70886,0.01375,0.66161,0.00849,0.66298,0.01484,0.63887,0.01525,
+1,0,0.66667,-0.01366,0.97404,0.06831,0.4959,0.50137,0.75683,-0.00273,0.65164,-0.14071,0.40164,-0.48907,0.39208,0.58743,0.76776,0.31831,0.78552,0.11339,0.47541,-0.44945,1,0.00683,0.60656,0.06967,0.68656,0.17088,0.87568,0.07787,0.55328,0.2459,0.13934,0.48087,
+1,0,0.83508,0.08298,0.73739,-0.14706,0.84349,-0.05567,0.90441,-0.04622,0.89391,0.1313,0.81197,0.06723,0.79307,-0.08929,1,-0.02101,0.96639,0.06618,0.87605,0.01155,0.77521,0.06618,0.95378,-0.04202,0.83479,0.00123,1,0.12815,0.8666,-0.10714,0.90546,-0.04307,
+1,0,0.95113,0.00419,0.95183,-0.02723,0.93438,-0.0192,0.9459,0.01606,0.9651,0.03281,0.94171,0.0733,0.94625,-0.01326,0.97173,0.0014,0.94834,0.06038,0.9267,0.08412,0.93124,0.10087,0.9452,0.01361,0.93522,0.04925,0.93159,0.08168,0.94066,-0.00035,0.91483,0.04712,
+1,0,0.94701,-0.00034,0.93207,-0.03227,0.95177,-0.03431,0.95584,0.02446,0.94124,0.01766,0.92595,0.04688,0.93954,-0.01461,0.94837,0.02004,0.93784,0.01393,0.91406,0.07677,0.8947,0.06148,0.93988,0.03193,0.92489,0.02542,0.9212,0.02242,0.92459,0.00442,0.92697,-0.00577,
+1,0,0.90608,-0.01657,0.98122,-0.01989,0.95691,-0.03646,0.85746,0.0011,0.89724,-0.03315,0.89061,-0.01436,0.90608,-0.0453,0.91381,-0.00884,0.80773,-0.12928,0.88729,0.01215,0.92155,-0.0232,0.9105,-0.02099,0.89147,-0.0776,0.82983,-0.17238,0.96022,-0.03757,0.87403,-0.16243,
+1,0,0.8471,0.13533,0.73638,-0.06151,0.87873,0.0826,0.88928,-0.09139,0.78735,0.06678,0.80668,-0.00351,0.79262,-0.01054,0.85764,-0.04569,0.8717,-0.03515,0.81722,-0.0949,0.71002,0.04394,0.86467,-0.15114,0.81147,-0.04822,0.78207,-0.00703,0.75747,-0.06678,0.85764,-0.06151
+};
+#endif
diff --git a/test/classifier/data/ionosphere_labels.hxx b/test/classifier/data/ionosphere_labels.hxx
new file mode 100644
index 0000000..cd49dac
--- /dev/null
+++ b/test/classifier/data/ionosphere_labels.hxx
@@ -0,0 +1,359 @@
+#ifndef IONOSPHERE_LABELS
+#define IONOSPHERE_LABELS
+int ionosphere_labels[] = {
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2
+};
+
+int ionosphere_Classes[] = {1, 2};
+int ionosphere_size = 2;
+#endif
diff --git a/test/classifier/data/iris_features.hxx b/test/classifier/data/iris_features.hxx
new file mode 100644
index 0000000..fe9d45f
--- /dev/null
+++ b/test/classifier/data/iris_features.hxx
@@ -0,0 +1,156 @@
+#ifndef IRIS_FEATURES
+#define IRIS_FEATURES
+double iris_features[] = {
+5.1,3.5,1.4,0.2,
+4.9,3,1.4,0.2,
+4.7,3.2,1.3,0.2,
+4.6,3.1,1.5,0.2,
+5,3.6,1.4,0.2,
+5.4,3.9,1.7,0.4,
+4.6,3.4,1.4,0.3,
+5,3.4,1.5,0.2,
+4.4,2.9,1.4,0.2,
+4.9,3.1,1.5,0.1,
+5.4,3.7,1.5,0.2,
+4.8,3.4,1.6,0.2,
+4.8,3,1.4,0.1,
+4.3,3,1.1,0.1,
+5.8,4,1.2,0.2,
+5.7,4.4,1.5,0.4,
+5.4,3.9,1.3,0.4,
+5.1,3.5,1.4,0.3,
+5.7,3.8,1.7,0.3,
+5.1,3.8,1.5,0.3,
+5.4,3.4,1.7,0.2,
+5.1,3.7,1.5,0.4,
+4.6,3.6,1,0.2,
+5.1,3.3,1.7,0.5,
+4.8,3.4,1.9,0.2,
+5,3,1.6,0.2,
+5,3.4,1.6,0.4,
+5.2,3.5,1.5,0.2,
+5.2,3.4,1.4,0.2,
+4.7,3.2,1.6,0.2,
+4.8,3.1,1.6,0.2,
+5.4,3.4,1.5,0.4,
+5.2,4.1,1.5,0.1,
+5.5,4.2,1.4,0.2,
+4.9,3.1,1.5,0.2,
+5,3.2,1.2,0.2,
+5.5,3.5,1.3,0.2,
+4.9,3.6,1.4,0.1,
+4.4,3,1.3,0.2,
+5.1,3.4,1.5,0.2,
+5,3.5,1.3,0.3,
+4.5,2.3,1.3,0.3,
+4.4,3.2,1.3,0.2,
+5,3.5,1.6,0.6,
+5.1,3.8,1.9,0.4,
+4.8,3,1.4,0.3,
+5.1,3.8,1.6,0.2,
+4.6,3.2,1.4,0.2,
+5.3,3.7,1.5,0.2,
+5,3.3,1.4,0.2,
+7,3.2,4.7,1.4,
+6.4,3.2,4.5,1.5,
+6.9,3.1,4.9,1.5,
+5.5,2.3,4,1.3,
+6.5,2.8,4.6,1.5,
+5.7,2.8,4.5,1.3,
+6.3,3.3,4.7,1.6,
+4.9,2.4,3.3,1,
+6.6,2.9,4.6,1.3,
+5.2,2.7,3.9,1.4,
+5,2,3.5,1,
+5.9,3,4.2,1.5,
+6,2.2,4,1,
+6.1,2.9,4.7,1.4,
+5.6,2.9,3.6,1.3,
+6.7,3.1,4.4,1.4,
+5.6,3,4.5,1.5,
+5.8,2.7,4.1,1,
+6.2,2.2,4.5,1.5,
+5.6,2.5,3.9,1.1,
+5.9,3.2,4.8,1.8,
+6.1,2.8,4,1.3,
+6.3,2.5,4.9,1.5,
+6.1,2.8,4.7,1.2,
+6.4,2.9,4.3,1.3,
+6.6,3,4.4,1.4,
+6.8,2.8,4.8,1.4,
+6.7,3,5,1.7,
+6,2.9,4.5,1.5,
+5.7,2.6,3.5,1,
+5.5,2.4,3.8,1.1,
+5.5,2.4,3.7,1,
+5.8,2.7,3.9,1.2,
+6,2.7,5.1,1.6,
+5.4,3,4.5,1.5,
+6,3.4,4.5,1.6,
+6.7,3.1,4.7,1.5,
+6.3,2.3,4.4,1.3,
+5.6,3,4.1,1.3,
+5.5,2.5,4,1.3,
+5.5,2.6,4.4,1.2,
+6.1,3,4.6,1.4,
+5.8,2.6,4,1.2,
+5,2.3,3.3,1,
+5.6,2.7,4.2,1.3,
+5.7,3,4.2,1.2,
+5.7,2.9,4.2,1.3,
+6.2,2.9,4.3,1.3,
+5.1,2.5,3,1.1,
+5.7,2.8,4.1,1.3,
+6.3,3.3,6,2.5,
+5.8,2.7,5.1,1.9,
+7.1,3,5.9,2.1,
+6.3,2.9,5.6,1.8,
+6.5,3,5.8,2.2,
+7.6,3,6.6,2.1,
+4.9,2.5,4.5,1.7,
+7.3,2.9,6.3,1.8,
+6.7,2.5,5.8,1.8,
+7.2,3.6,6.1,2.5,
+6.5,3.2,5.1,2,
+6.4,2.7,5.3,1.9,
+6.8,3,5.5,2.1,
+5.7,2.5,5,2,
+5.8,2.8,5.1,2.4,
+6.4,3.2,5.3,2.3,
+6.5,3,5.5,1.8,
+7.7,3.8,6.7,2.2,
+7.7,2.6,6.9,2.3,
+6,2.2,5,1.5,
+6.9,3.2,5.7,2.3,
+5.6,2.8,4.9,2,
+7.7,2.8,6.7,2,
+6.3,2.7,4.9,1.8,
+6.7,3.3,5.7,2.1,
+7.2,3.2,6,1.8,
+6.2,2.8,4.8,1.8,
+6.1,3,4.9,1.8,
+6.4,2.8,5.6,2.1,
+7.2,3,5.8,1.6,
+7.4,2.8,6.1,1.9,
+7.9,3.8,6.4,2,
+6.4,2.8,5.6,2.2,
+6.3,2.8,5.1,1.5,
+6.1,2.6,5.6,1.4,
+7.7,3,6.1,2.3,
+6.3,3.4,5.6,2.4,
+6.4,3.1,5.5,1.8,
+6,3,4.8,1.8,
+6.9,3.1,5.4,2.1,
+6.7,3.1,5.6,2.4,
+6.9,3.1,5.1,2.3,
+5.8,2.7,5.1,1.9,
+6.8,3.2,5.9,2.3,
+6.7,3.3,5.7,2.5,
+6.7,3,5.2,2.3,
+6.3,2.5,5,1.9,
+6.5,3,5.2,2,
+6.2,3.4,5.4,2.3,
+5.9,3,5.1,1.8
+
+};
+#endif
diff --git a/test/classifier/data/iris_labels.hxx b/test/classifier/data/iris_labels.hxx
new file mode 100644
index 0000000..c376464
--- /dev/null
+++ b/test/classifier/data/iris_labels.hxx
@@ -0,0 +1,160 @@
+#ifndef IRIS_LABELS
+#define IRIS_LABELS
+int iris_labels[] = {
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3
+
+};
+
+int iris_Classes[] = {1, 2 , 3};
+int iris_size = 3;
+
+#endif
diff --git a/test/classifier/data/oldClassifier.log b/test/classifier/data/oldClassifier.log
new file mode 100644
index 0000000..01a6854
--- /dev/null
+++ b/test/classifier/data/oldClassifier.log
@@ -0,0 +1,61218 @@
+minGini: 11.508771 - 24
+Region.size: 80
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 23 
+RightChild.size: 57
+RightChild.ClassCounts: 41 16 
+
+minGini: 9.283018 - 23
+Region.size: 57
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 53
+RightChild.ClassCounts: 41 12 
+
+minGini: 7.380000 - 29
+Region.size: 53
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 50
+RightChild.ClassCounts: 41 9 
+
+minGini: 6.404761 - 21
+Region.size: 50
+LeftChild.size: 8
+LeftChild.ClassCounts: 4 4 
+RightChild.size: 42
+RightChild.ClassCounts: 37 5 
+
+minGini: 3.600000 - 14
+Region.size: 42
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 
+RightChild.size: 35
+RightChild.ClassCounts: 33 2 
+
+minGini: 0.970588 - 32
+Region.size: 35
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 34
+RightChild.ClassCounts: 33 1 
+
+minGini: 0.666666 - 7
+Region.size: 34
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 31
+RightChild.ClassCounts: 31 0 
+
+minGini: 0.000000 - 41
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.750000 - 19
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 15
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.800000 - 11
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 11
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 0 finished.
+
+minGini: 13.939393 - 25
+Region.size: 80
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 66
+RightChild.ClassCounts: 46 20 
+
+minGini: 12.052631 - 21
+Region.size: 66
+LeftChild.size: 28
+LeftChild.ClassCounts: 14 14 
+RightChild.size: 38
+RightChild.ClassCounts: 32 6 
+
+minGini: 3.866666 - 8
+Region.size: 38
+LeftChild.size: 30
+LeftChild.ClassCounts: 28 2 
+RightChild.size: 8
+RightChild.ClassCounts: 4 4 
+
+minGini: 0.000000 - 3
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 33
+Region.size: 30
+LeftChild.size: 28
+LeftChild.ClassCounts: 28 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 5.090909 - 1
+Region.size: 28
+LeftChild.size: 22
+LeftChild.ClassCounts: 8 14 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 2.181818 - 39
+Region.size: 22
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 11
+RightChild.ClassCounts: 8 3 
+
+minGini: 0.750000 - 35
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 25
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+
+
+Tree Number: 1 finished.
+
+minGini: 15.685534 - 19
+Region.size: 80
+LeftChild.size: 27
+LeftChild.ClassCounts: 3 24 
+RightChild.size: 53
+RightChild.ClassCounts: 30 23 
+
+minGini: 9.275362 - 29
+Region.size: 53
+LeftChild.size: 30
+LeftChild.ClassCounts: 10 20 
+RightChild.size: 23
+RightChild.ClassCounts: 20 3 
+
+minGini: 0.952380 - 13
+Region.size: 23
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 21
+RightChild.ClassCounts: 20 1 
+
+minGini: 0.000000 - 7
+Region.size: 21
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 
+
+minGini: 5.185185 - 26
+Region.size: 30
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 27
+RightChild.ClassCounts: 7 20 
+
+minGini: 2.608695 - 30
+Region.size: 27
+LeftChild.size: 23
+LeftChild.ClassCounts: 3 20 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.952380 - 35
+Region.size: 23
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 21
+RightChild.ClassCounts: 1 20 
+
+minGini: 0.000000 - 38
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 20 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.960000 - 42
+Region.size: 27
+LeftChild.size: 25
+LeftChild.ClassCounts: 1 24 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 29
+Region.size: 25
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 24 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 2 finished.
+
+minGini: 16.533333 - 21
+Region.size: 80
+LeftChild.size: 15
+LeftChild.ClassCounts: 1 14 
+RightChild.size: 65
+RightChild.ClassCounts: 39 26 
+
+minGini: 11.536796 - 8
+Region.size: 65
+LeftChild.size: 44
+LeftChild.ClassCounts: 34 10 
+RightChild.size: 21
+RightChild.ClassCounts: 5 16 
+
+minGini: 2.266666 - 30
+Region.size: 21
+LeftChild.size: 15
+LeftChild.ClassCounts: 1 14 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.000000 - 35
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 1
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.578947 - 5
+Region.size: 44
+LeftChild.size: 38
+LeftChild.ClassCounts: 34 4 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 1.888888 - 24
+Region.size: 38
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 36
+RightChild.ClassCounts: 34 2 
+
+minGini: 0.971428 - 16
+Region.size: 36
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 35
+RightChild.ClassCounts: 34 1 
+
+minGini: 0.000000 - 28
+Region.size: 35
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 34
+RightChild.ClassCounts: 34 0 
+
+minGini: 0.000000 - 29
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 3 finished.
+
+minGini: 11.904388 - 43
+Region.size: 80
+LeftChild.size: 22
+LeftChild.ClassCounts: 2 20 
+RightChild.size: 58
+RightChild.ClassCounts: 45 13 
+
+minGini: 8.000000 - 2
+Region.size: 58
+LeftChild.size: 9
+LeftChild.ClassCounts: 3 6 
+RightChild.size: 49
+RightChild.ClassCounts: 42 7 
+
+minGini: 2.800000 - 38
+Region.size: 49
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 45
+RightChild.ClassCounts: 42 3 
+
+minGini: 2.175000 - 15
+Region.size: 45
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 40
+RightChild.ClassCounts: 39 1 
+
+minGini: 0.000000 - 6
+Region.size: 40
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 39
+RightChild.ClassCounts: 39 0 
+
+minGini: 0.666666 - 27
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 11
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.750000 - 39
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 34
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 31
+Region.size: 22
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 20 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 4 finished.
+
+minGini: 13.359375 - 39
+Region.size: 80
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 
+RightChild.size: 64
+RightChild.ClassCounts: 45 19 
+
+minGini: 10.326923 - 8
+Region.size: 64
+LeftChild.size: 52
+LeftChild.ClassCounts: 42 10 
+RightChild.size: 12
+RightChild.ClassCounts: 3 9 
+
+minGini: 0.900000 - 28
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.500000 - 18
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 19
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 6.000000 - 3
+Region.size: 52
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 49
+RightChild.ClassCounts: 42 7 
+
+minGini: 3.652173 - 22
+Region.size: 49
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 46
+RightChild.ClassCounts: 42 4 
+
+minGini: 1.909090 - 0
+Region.size: 46
+LeftChild.size: 44
+LeftChild.ClassCounts: 42 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.976744 - 17
+Region.size: 44
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 43
+RightChild.ClassCounts: 42 1 
+
+minGini: 0.500000 - 4
+Region.size: 43
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 41
+RightChild.ClassCounts: 41 0 
+
+minGini: 0.000000 - 15
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 5 finished.
+
+minGini: 15.971014 - 35
+Region.size: 80
+LeftChild.size: 23
+LeftChild.ClassCounts: 4 19 
+RightChild.size: 57
+RightChild.ClassCounts: 38 19 
+
+minGini: 10.027777 - 38
+Region.size: 57
+LeftChild.size: 12
+LeftChild.ClassCounts: 3 9 
+RightChild.size: 45
+RightChild.ClassCounts: 35 10 
+
+minGini: 3.333333 - 29
+Region.size: 45
+LeftChild.size: 15
+LeftChild.ClassCounts: 5 10 
+RightChild.size: 30
+RightChild.ClassCounts: 30 0 
+
+minGini: 0.909090 - 22
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 18
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 26
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.809523 - 37
+Region.size: 23
+LeftChild.size: 21
+LeftChild.ClassCounts: 2 19 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.428571 - 18
+Region.size: 21
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 
+
+minGini: 0.666666 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 15
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 6 finished.
+
+minGini: 15.272727 - 43
+Region.size: 80
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 66
+RightChild.ClassCounts: 42 24 
+
+minGini: 11.017500 - 29
+Region.size: 66
+LeftChild.size: 16
+LeftChild.ClassCounts: 3 13 
+RightChild.size: 50
+RightChild.ClassCounts: 39 11 
+
+minGini: 6.798336 - 20
+Region.size: 50
+LeftChild.size: 13
+LeftChild.ClassCounts: 6 7 
+RightChild.size: 37
+RightChild.ClassCounts: 33 4 
+
+minGini: 1.885714 - 21
+Region.size: 37
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 35
+RightChild.ClassCounts: 33 2 
+
+minGini: 1.333333 - 37
+Region.size: 35
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 29
+RightChild.ClassCounts: 29 0 
+
+minGini: 0.000000 - 31
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 1.500000 - 26
+Region.size: 13
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.666666 - 19
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 8
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.200000 - 11
+Region.size: 16
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 0.000000 - 38
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+
+
+Tree Number: 7 finished.
+
+minGini: 15.029862 - 23
+Region.size: 80
+LeftChild.size: 21
+LeftChild.ClassCounts: 2 19 
+RightChild.size: 59
+RightChild.ClassCounts: 39 20 
+
+minGini: 10.697674 - 37
+Region.size: 59
+LeftChild.size: 43
+LeftChild.ClassCounts: 23 20 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 
+
+minGini: 3.407407 - 27
+Region.size: 43
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 
+RightChild.size: 27
+RightChild.ClassCounts: 23 4 
+
+minGini: 1.840000 - 28
+Region.size: 27
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 25
+RightChild.ClassCounts: 23 2 
+
+minGini: 0.000000 - 24
+Region.size: 25
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 23
+RightChild.ClassCounts: 23 0 
+
+minGini: 0.950000 - 11
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 1 19 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 4
+Region.size: 20
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 19 
+
+
+
+Tree Number: 8 finished.
+
+minGini: 14.748991 - 27
+Region.size: 80
+LeftChild.size: 21
+LeftChild.ClassCounts: 1 20 
+RightChild.size: 59
+RightChild.ClassCounts: 37 22 
+
+minGini: 8.479166 - 39
+Region.size: 59
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 48
+RightChild.ClassCounts: 37 11 
+
+minGini: 6.773626 - 2
+Region.size: 48
+LeftChild.size: 13
+LeftChild.ClassCounts: 6 7 
+RightChild.size: 35
+RightChild.ClassCounts: 31 4 
+
+minGini: 1.717741 - 0
+Region.size: 35
+LeftChild.size: 31
+LeftChild.ClassCounts: 30 1 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 13
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 33
+Region.size: 31
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 30
+RightChild.ClassCounts: 30 0 
+
+minGini: 0.857142 - 10
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 21
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 4
+Region.size: 21
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 9 finished.
+
+minGini: 15.346855 - 23
+Region.size: 80
+LeftChild.size: 51
+LeftChild.ClassCounts: 15 36 
+RightChild.size: 29
+RightChild.ClassCounts: 23 6 
+
+minGini: 1.789855 - 21
+Region.size: 29
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 23
+RightChild.ClassCounts: 22 1 
+
+minGini: 0.000000 - 42
+Region.size: 23
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 22
+RightChild.ClassCounts: 22 0 
+
+minGini: 0.000000 - 33
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 8.195924 - 25
+Region.size: 51
+LeftChild.size: 22
+LeftChild.ClassCounts: 1 21 
+RightChild.size: 29
+RightChild.ClassCounts: 14 15 
+
+minGini: 2.500000 - 29
+Region.size: 29
+LeftChild.size: 18
+LeftChild.ClassCounts: 3 15 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 0.937500 - 35
+Region.size: 18
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 16
+RightChild.ClassCounts: 1 15 
+
+minGini: 0.500000 - 13
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 39
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 29
+Region.size: 22
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 21 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 10 finished.
+
+minGini: 12.338709 - 40
+Region.size: 80
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 
+RightChild.size: 62
+RightChild.ClassCounts: 45 17 
+
+minGini: 7.500000 - 39
+Region.size: 62
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 54
+RightChild.ClassCounts: 45 9 
+
+minGini: 5.527173 - 24
+Region.size: 54
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 46
+RightChild.ClassCounts: 42 4 
+
+minGini: 2.800000 - 11
+Region.size: 46
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 45
+RightChild.ClassCounts: 42 3 
+
+minGini: 1.909090 - 5
+Region.size: 45
+LeftChild.size: 44
+LeftChild.ClassCounts: 42 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.976744 - 2
+Region.size: 44
+LeftChild.size: 43
+LeftChild.ClassCounts: 42 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 27
+Region.size: 43
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 40
+RightChild.ClassCounts: 40 0 
+
+minGini: 0.000000 - 29
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 2
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+
+
+Tree Number: 11 finished.
+
+minGini: 16.262753 - 24
+Region.size: 80
+LeftChild.size: 27
+LeftChild.ClassCounts: 5 22 
+RightChild.size: 53
+RightChild.ClassCounts: 34 19 
+
+minGini: 6.785964 - 7
+Region.size: 53
+LeftChild.size: 15
+LeftChild.ClassCounts: 2 13 
+RightChild.size: 38
+RightChild.ClassCounts: 32 6 
+
+minGini: 3.555555 - 23
+Region.size: 38
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 36
+RightChild.ClassCounts: 32 4 
+
+minGini: 2.742857 - 13
+Region.size: 36
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 35
+RightChild.ClassCounts: 32 3 
+
+minGini: 1.882352 - 28
+Region.size: 35
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 34
+RightChild.ClassCounts: 32 2 
+
+minGini: 1.468750 - 39
+Region.size: 34
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 32
+RightChild.ClassCounts: 31 1 
+
+minGini: 0.833333 - 35
+Region.size: 32
+LeftChild.size: 26
+LeftChild.ClassCounts: 26 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 39
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 30
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.928571 - 20
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 1 13 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 25
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 
+
+minGini: 0.000000 - 33
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.947368 - 11
+Region.size: 27
+LeftChild.size: 8
+LeftChild.ClassCounts: 4 4 
+RightChild.size: 19
+RightChild.ClassCounts: 1 18 
+
+minGini: 0.000000 - 37
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 38
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+
+
+Tree Number: 12 finished.
+
+minGini: 14.211017 - 27
+Region.size: 80
+LeftChild.size: 17
+LeftChild.ClassCounts: 1 16 
+RightChild.size: 63
+RightChild.ClassCounts: 44 19 
+
+minGini: 8.842741 - 38
+Region.size: 63
+LeftChild.size: 32
+LeftChild.ClassCounts: 14 18 
+RightChild.size: 31
+RightChild.ClassCounts: 30 1 
+
+minGini: 0.000000 - 0
+Region.size: 31
+LeftChild.size: 30
+LeftChild.ClassCounts: 30 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.445887 - 30
+Region.size: 32
+LeftChild.size: 21
+LeftChild.ClassCounts: 5 16 
+RightChild.size: 11
+RightChild.ClassCounts: 9 2 
+
+minGini: 0.000000 - 17
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.875000 - 8
+Region.size: 21
+LeftChild.size: 8
+LeftChild.ClassCounts: 5 3 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.750000 - 9
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 30
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 29
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 13 finished.
+
+minGini: 16.201298 - 40
+Region.size: 80
+LeftChild.size: 14
+LeftChild.ClassCounts: 1 13 
+RightChild.size: 66
+RightChild.ClassCounts: 42 24 
+
+minGini: 8.716981 - 7
+Region.size: 66
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 
+RightChild.size: 53
+RightChild.ClassCounts: 42 11 
+
+minGini: 5.944444 - 9
+Region.size: 53
+LeftChild.size: 8
+LeftChild.ClassCounts: 2 6 
+RightChild.size: 45
+RightChild.ClassCounts: 40 5 
+
+minGini: 3.516042 - 34
+Region.size: 45
+LeftChild.size: 34
+LeftChild.ClassCounts: 33 1 
+RightChild.size: 11
+RightChild.ClassCounts: 7 4 
+
+minGini: 0.000000 - 8
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 0
+Region.size: 34
+LeftChild.size: 33
+LeftChild.ClassCounts: 33 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 28
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 18
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 14 finished.
+
+minGini: 16.042319 - 13
+Region.size: 80
+LeftChild.size: 22
+LeftChild.ClassCounts: 2 20 
+RightChild.size: 58
+RightChild.ClassCounts: 33 25 
+
+minGini: 11.118421 - 8
+Region.size: 58
+LeftChild.size: 38
+LeftChild.ClassCounts: 28 10 
+RightChild.size: 20
+RightChild.ClassCounts: 5 15 
+
+minGini: 1.733333 - 2
+Region.size: 20
+LeftChild.size: 15
+LeftChild.ClassCounts: 1 14 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 16
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 41
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.242424 - 2
+Region.size: 38
+LeftChild.size: 33
+LeftChild.ClassCounts: 28 5 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 2.675824 - 9
+Region.size: 33
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 
+RightChild.size: 26
+RightChild.ClassCounts: 25 1 
+
+minGini: 0.000000 - 34
+Region.size: 26
+LeftChild.size: 25
+LeftChild.ClassCounts: 25 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 31
+Region.size: 22
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 20 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 15 finished.
+
+minGini: 17.669345 - 24
+Region.size: 80
+LeftChild.size: 13
+LeftChild.ClassCounts: 1 12 
+RightChild.size: 67
+RightChild.ClassCounts: 34 33 
+
+minGini: 13.799407 - 9
+Region.size: 67
+LeftChild.size: 23
+LeftChild.ClassCounts: 5 18 
+RightChild.size: 44
+RightChild.ClassCounts: 29 15 
+
+minGini: 2.714285 - 39
+Region.size: 44
+LeftChild.size: 16
+LeftChild.ClassCounts: 2 14 
+RightChild.size: 28
+RightChild.ClassCounts: 27 1 
+
+minGini: 0.000000 - 5
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 27 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 36
+Region.size: 16
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.000000 - 23
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.651785 - 25
+Region.size: 23
+LeftChild.size: 16
+LeftChild.ClassCounts: 1 15 
+RightChild.size: 7
+RightChild.ClassCounts: 4 3 
+
+minGini: 0.000000 - 11
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 3
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 16 finished.
+
+minGini: 15.910447 - 24
+Region.size: 80
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 
+RightChild.size: 67
+RightChild.ClassCounts: 41 26 
+
+minGini: 12.337662 - 7
+Region.size: 67
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 56
+RightChild.ClassCounts: 40 16 
+
+minGini: 9.230769 - 41
+Region.size: 56
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 52
+RightChild.ClassCounts: 40 12 
+
+minGini: 8.000000 - 12
+Region.size: 52
+LeftChild.size: 50
+LeftChild.ClassCounts: 40 10 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 5.468750 - 2
+Region.size: 50
+LeftChild.size: 18
+LeftChild.ClassCounts: 9 9 
+RightChild.size: 32
+RightChild.ClassCounts: 31 1 
+
+minGini: 0.800000 - 9
+Region.size: 32
+LeftChild.size: 27
+LeftChild.ClassCounts: 27 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.636363 - 30
+Region.size: 18
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 11
+RightChild.ClassCounts: 2 9 
+
+minGini: 0.000000 - 42
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.500000 - 30
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 17 finished.
+
+minGini: 11.661016 - 25
+Region.size: 80
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 21 
+RightChild.size: 59
+RightChild.ClassCounts: 43 16 
+
+minGini: 7.442307 - 31
+Region.size: 59
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 52
+RightChild.ClassCounts: 43 9 
+
+minGini: 6.666666 - 13
+Region.size: 52
+LeftChild.size: 49
+LeftChild.ClassCounts: 42 7 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 5.250000 - 15
+Region.size: 49
+LeftChild.size: 48
+LeftChild.ClassCounts: 42 6 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 3.545454 - 38
+Region.size: 48
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 44
+RightChild.ClassCounts: 41 3 
+
+minGini: 1.906976 - 19
+Region.size: 44
+LeftChild.size: 43
+LeftChild.ClassCounts: 41 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.976190 - 17
+Region.size: 43
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 42
+RightChild.ClassCounts: 41 1 
+
+minGini: 0.800000 - 24
+Region.size: 42
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 37
+RightChild.ClassCounts: 37 0 
+
+minGini: 0.000000 - 10
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 39
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 18 finished.
+
+minGini: 15.109375 - 9
+Region.size: 80
+LeftChild.size: 16
+LeftChild.ClassCounts: 2 14 
+RightChild.size: 64
+RightChild.ClassCounts: 45 19 
+
+minGini: 9.495670 - 21
+Region.size: 64
+LeftChild.size: 22
+LeftChild.ClassCounts: 8 14 
+RightChild.size: 42
+RightChild.ClassCounts: 37 5 
+
+minGini: 1.897435 - 38
+Region.size: 42
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 39
+RightChild.ClassCounts: 37 2 
+
+minGini: 0.973684 - 20
+Region.size: 39
+LeftChild.size: 38
+LeftChild.ClassCounts: 37 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 34
+Region.size: 38
+LeftChild.size: 34
+LeftChild.ClassCounts: 34 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 35
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.666666 - 22
+Region.size: 22
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 12
+RightChild.ClassCounts: 8 4 
+
+minGini: 0.888888 - 2
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 9
+RightChild.ClassCounts: 8 1 
+
+minGini: 0.000000 - 23
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.666666 - 39
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 17
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 19 finished.
+
+minGini: 14.335497 - 27
+Region.size: 80
+LeftChild.size: 14
+LeftChild.ClassCounts: 2 12 
+RightChild.size: 66
+RightChild.ClassCounts: 49 17 
+
+minGini: 9.150862 - 24
+Region.size: 66
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 58
+RightChild.ClassCounts: 48 10 
+
+minGini: 6.109090 - 31
+Region.size: 58
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 55
+RightChild.ClassCounts: 48 7 
+
+minGini: 4.528301 - 42
+Region.size: 55
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 53
+RightChild.ClassCounts: 48 5 
+
+minGini: 2.823529 - 16
+Region.size: 53
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 51
+RightChild.ClassCounts: 48 3 
+
+minGini: 1.920000 - 33
+Region.size: 51
+LeftChild.size: 50
+LeftChild.ClassCounts: 48 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.979591 - 6
+Region.size: 50
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 49
+RightChild.ClassCounts: 48 1 
+
+minGini: 0.000000 - 32
+Region.size: 49
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 48
+RightChild.ClassCounts: 48 0 
+
+minGini: 0.000000 - 26
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.666666 - 40
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 30
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 20 finished.
+
+minGini: 14.276363 - 38
+Region.size: 80
+LeftChild.size: 25
+LeftChild.ClassCounts: 2 23 
+RightChild.size: 55
+RightChild.ClassCounts: 36 19 
+
+minGini: 9.108870 - 29
+Region.size: 55
+LeftChild.size: 24
+LeftChild.ClassCounts: 9 15 
+RightChild.size: 31
+RightChild.ClassCounts: 27 4 
+
+minGini: 1.862068 - 35
+Region.size: 31
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 29
+RightChild.ClassCounts: 27 2 
+
+minGini: 0.000000 - 16
+Region.size: 29
+LeftChild.size: 27
+LeftChild.ClassCounts: 27 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 3.600000 - 6
+Region.size: 24
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 15
+RightChild.ClassCounts: 9 6 
+
+minGini: 2.250000 - 20
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 12
+RightChild.ClassCounts: 9 3 
+
+minGini: 1.500000 - 5
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.750000 - 38
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 37
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.958333 - 36
+Region.size: 25
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 24
+RightChild.ClassCounts: 1 23 
+
+minGini: 0.000000 - 26
+Region.size: 24
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 23 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 21 finished.
+
+minGini: 13.938977 - 38
+Region.size: 80
+LeftChild.size: 23
+LeftChild.ClassCounts: 1 22 
+RightChild.size: 57
+RightChild.ClassCounts: 37 20 
+
+minGini: 10.591269 - 2
+Region.size: 57
+LeftChild.size: 21
+LeftChild.ClassCounts: 8 13 
+RightChild.size: 36
+RightChild.ClassCounts: 29 7 
+
+minGini: 3.509677 - 21
+Region.size: 36
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 31
+RightChild.ClassCounts: 28 3 
+
+minGini: 1.866666 - 10
+Region.size: 31
+LeftChild.size: 30
+LeftChild.ClassCounts: 28 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.965517 - 5
+Region.size: 30
+LeftChild.size: 29
+LeftChild.ClassCounts: 28 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 5
+Region.size: 29
+LeftChild.size: 25
+LeftChild.ClassCounts: 25 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 34
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 26
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.611111 - 34
+Region.size: 21
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 18
+RightChild.ClassCounts: 5 13 
+
+minGini: 2.437500 - 30
+Region.size: 18
+LeftChild.size: 16
+LeftChild.ClassCounts: 3 13 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.733333 - 34
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 2 13 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.928571 - 29
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 1 13 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 17
+Region.size: 14
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 26
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.800000 - 21
+Region.size: 23
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 20
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+
+
+Tree Number: 22 finished.
+
+minGini: 13.329573 - 29
+Region.size: 80
+LeftChild.size: 42
+LeftChild.ClassCounts: 10 32 
+RightChild.size: 38
+RightChild.ClassCounts: 31 7 
+
+minGini: 4.052083 - 7
+Region.size: 38
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 32
+RightChild.ClassCounts: 29 3 
+
+minGini: 1.870967 - 39
+Region.size: 32
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 31
+RightChild.ClassCounts: 29 2 
+
+minGini: 0.000000 - 8
+Region.size: 31
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 29
+RightChild.ClassCounts: 29 0 
+
+minGini: 0.000000 - 35
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 4.282828 - 13
+Region.size: 42
+LeftChild.size: 33
+LeftChild.ClassCounts: 3 30 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 
+
+minGini: 0.000000 - 16
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.100000 - 33
+Region.size: 33
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 23 
+RightChild.size: 10
+RightChild.ClassCounts: 3 7 
+
+minGini: 0.875000 - 21
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.500000 - 11
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 41
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 23 finished.
+
+minGini: 14.211017 - 21
+Region.size: 80
+LeftChild.size: 17
+LeftChild.ClassCounts: 1 16 
+RightChild.size: 63
+RightChild.ClassCounts: 44 19 
+
+minGini: 9.907707 - 28
+Region.size: 63
+LeftChild.size: 29
+LeftChild.ClassCounts: 13 16 
+RightChild.size: 34
+RightChild.ClassCounts: 31 3 
+
+minGini: 1.878787 - 14
+Region.size: 34
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 33
+RightChild.ClassCounts: 31 2 
+
+minGini: 1.000000 - 38
+Region.size: 33
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 29
+RightChild.ClassCounts: 29 0 
+
+minGini: 0.000000 - 16
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 4.446078 - 39
+Region.size: 29
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 11 
+RightChild.size: 17
+RightChild.ClassCounts: 12 5 
+
+minGini: 1.714285 - 19
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 12 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.923076 - 35
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 12 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 18
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 
+
+minGini: 0.000000 - 9
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 24 finished.
+
+minGini: 12.179104 - 40
+Region.size: 80
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 
+RightChild.size: 67
+RightChild.ClassCounts: 51 16 
+
+minGini: 8.359090 - 29
+Region.size: 67
+LeftChild.size: 12
+LeftChild.ClassCounts: 3 9 
+RightChild.size: 55
+RightChild.ClassCounts: 48 7 
+
+minGini: 4.528301 - 16
+Region.size: 55
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 53
+RightChild.ClassCounts: 48 5 
+
+minGini: 2.823529 - 27
+Region.size: 53
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 51
+RightChild.ClassCounts: 48 3 
+
+minGini: 1.978723 - 17
+Region.size: 51
+LeftChild.size: 47
+LeftChild.ClassCounts: 46 1 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 0
+Region.size: 47
+LeftChild.size: 46
+LeftChild.ClassCounts: 46 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 37
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+
+
+Tree Number: 25 finished.
+
+minGini: 15.190476 - 27
+Region.size: 80
+LeftChild.size: 24
+LeftChild.ClassCounts: 2 22 
+RightChild.size: 56
+RightChild.ClassCounts: 34 22 
+
+minGini: 7.333333 - 29
+Region.size: 56
+LeftChild.size: 33
+LeftChild.ClassCounts: 11 22 
+RightChild.size: 23
+RightChild.ClassCounts: 23 0 
+
+minGini: 3.437500 - 34
+Region.size: 33
+LeftChild.size: 16
+LeftChild.ClassCounts: 11 5 
+RightChild.size: 17
+RightChild.ClassCounts: 0 17 
+
+minGini: 1.875000 - 36
+Region.size: 16
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 8
+RightChild.ClassCounts: 3 5 
+
+minGini: 0.000000 - 18
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.666666 - 1
+Region.size: 24
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 21 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 9
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 26 finished.
+
+minGini: 13.085714 - 39
+Region.size: 80
+LeftChild.size: 35
+LeftChild.ClassCounts: 5 30 
+RightChild.size: 45
+RightChild.ClassCounts: 33 12 
+
+minGini: 5.487980 - 9
+Region.size: 45
+LeftChild.size: 13
+LeftChild.ClassCounts: 4 9 
+RightChild.size: 32
+RightChild.ClassCounts: 29 3 
+
+minGini: 1.870967 - 4
+Region.size: 32
+LeftChild.size: 31
+LeftChild.ClassCounts: 29 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 25
+Region.size: 31
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 29
+RightChild.ClassCounts: 29 0 
+
+minGini: 1.714285 - 14
+Region.size: 13
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 7
+RightChild.ClassCounts: 4 3 
+
+minGini: 0.000000 - 23
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 2.298850 - 36
+Region.size: 35
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 29
+RightChild.ClassCounts: 1 28 
+
+minGini: 0.000000 - 11
+Region.size: 29
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 28 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 9
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 27 finished.
+
+minGini: 11.370967 - 35
+Region.size: 80
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 
+RightChild.size: 62
+RightChild.ClassCounts: 47 15 
+
+minGini: 8.245614 - 43
+Region.size: 62
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 57
+RightChild.ClassCounts: 47 10 
+
+minGini: 5.320754 - 4
+Region.size: 57
+LeftChild.size: 53
+LeftChild.ClassCounts: 47 6 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.918367 - 39
+Region.size: 53
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 49
+RightChild.ClassCounts: 47 2 
+
+minGini: 1.644927 - 25
+Region.size: 49
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 46
+RightChild.ClassCounts: 45 1 
+
+minGini: 0.500000 - 36
+Region.size: 46
+LeftChild.size: 44
+LeftChild.ClassCounts: 44 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 35
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 19
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 28 finished.
+
+minGini: 12.937500 - 29
+Region.size: 80
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 
+RightChild.size: 64
+RightChild.ClassCounts: 46 18 
+
+minGini: 10.733333 - 40
+Region.size: 64
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 60
+RightChild.ClassCounts: 46 14 
+
+minGini: 7.725000 - 2
+Region.size: 60
+LeftChild.size: 20
+LeftChild.ClassCounts: 9 11 
+RightChild.size: 40
+RightChild.ClassCounts: 37 3 
+
+minGini: 1.897435 - 13
+Region.size: 40
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 39
+RightChild.ClassCounts: 37 2 
+
+minGini: 0.973684 - 27
+Region.size: 39
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 38
+RightChild.ClassCounts: 37 1 
+
+minGini: 0.000000 - 31
+Region.size: 38
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 37
+RightChild.ClassCounts: 37 0 
+
+minGini: 0.916666 - 29
+Region.size: 20
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 11 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.000000 - 1
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 29 finished.
+
+minGini: 13.757869 - 21
+Region.size: 80
+LeftChild.size: 21
+LeftChild.ClassCounts: 3 18 
+RightChild.size: 59
+RightChild.ClassCounts: 44 15 
+
+minGini: 7.620098 - 4
+Region.size: 59
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 51
+RightChild.ClassCounts: 43 8 
+
+minGini: 5.265306 - 4
+Region.size: 51
+LeftChild.size: 49
+LeftChild.ClassCounts: 43 6 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.804347 - 27
+Region.size: 49
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 46
+RightChild.ClassCounts: 43 3 
+
+minGini: 1.911111 - 8
+Region.size: 46
+LeftChild.size: 45
+LeftChild.ClassCounts: 43 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.977272 - 0
+Region.size: 45
+LeftChild.size: 44
+LeftChild.ClassCounts: 43 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 13
+Region.size: 44
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 43
+RightChild.ClassCounts: 43 0 
+
+minGini: 0.000000 - 23
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 21
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+
+
+Tree Number: 30 finished.
+
+minGini: 12.606568 - 29
+Region.size: 80
+LeftChild.size: 27
+LeftChild.ClassCounts: 2 25 
+RightChild.size: 53
+RightChild.ClassCounts: 38 15 
+
+minGini: 7.124285 - 23
+Region.size: 53
+LeftChild.size: 25
+LeftChild.ClassCounts: 11 14 
+RightChild.size: 28
+RightChild.ClassCounts: 27 1 
+
+minGini: 0.000000 - 7
+Region.size: 28
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 27
+RightChild.ClassCounts: 27 0 
+
+minGini: 4.000000 - 3
+Region.size: 25
+LeftChild.size: 15
+LeftChild.ClassCounts: 3 12 
+RightChild.size: 10
+RightChild.ClassCounts: 8 2 
+
+minGini: 0.666666 - 2
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 25
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.923076 - 38
+Region.size: 15
+LeftChild.size: 13
+LeftChild.ClassCounts: 1 12 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 34
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.428571 - 36
+Region.size: 27
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 5 
+RightChild.size: 20
+RightChild.ClassCounts: 0 20 
+
+minGini: 0.000000 - 39
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 31 finished.
+
+SPECTF
+minGini: 179.929166 - 6
+Region.size: 336
+LeftChild.size: 240
+LeftChild.ClassCounts: 153 8 0 1 3 22 11 42 
+RightChild.size: 96
+RightChild.ClassCounts: 0 59 1 2 34 0 0 0 
+
+minGini: 27.993006 - 0
+Region.size: 96
+LeftChild.size: 44
+LeftChild.ClassCounts: 0 43 0 0 1 0 0 0 
+RightChild.size: 52
+RightChild.ClassCounts: 0 16 1 2 33 0 0 0 
+
+minGini: 22.208333 - 5
+Region.size: 52
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 12 1 2 33 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 20.794425 - 4
+Region.size: 48
+LeftChild.size: 41
+LeftChild.ClassCounts: 0 8 1 2 30 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 4 0 0 3 0 0 0 
+
+minGini: 1.600000 - 5
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 1 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 15.800000 - 2
+Region.size: 41
+LeftChild.size: 40
+LeftChild.ClassCounts: 0 8 0 2 30 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 14.978354 - 0
+Region.size: 40
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 2 5 0 0 0 
+RightChild.size: 33
+RightChild.ClassCounts: 0 8 0 0 25 0 0 0 
+
+minGini: 10.720000 - 0
+Region.size: 33
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 4 0 0 4 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 4 0 0 21 0 0 0 
+
+minGini: 5.619047 - 4
+Region.size: 25
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 2 0 0 2 0 0 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 2 0 0 19 0 0 0 
+
+minGini: 3.222222 - 5
+Region.size: 21
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 1 0 0 17 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 1.600000 - 5
+Region.size: 18
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 0 0 4 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 0 0 13 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 1.600000 - 1
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 2 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 4 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.666666 - 1
+Region.size: 44
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 38 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 5 0 0 1 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 79.856615 - 0
+Region.size: 240
+LeftChild.size: 167
+LeftChild.ClassCounts: 149 8 0 0 3 3 0 4 
+RightChild.size: 73
+RightChild.ClassCounts: 4 0 0 1 0 19 11 38 
+
+minGini: 27.486792 - 4
+Region.size: 73
+LeftChild.size: 53
+LeftChild.ClassCounts: 4 0 0 1 0 1 9 38 
+RightChild.size: 20
+RightChild.ClassCounts: 0 0 0 0 0 18 2 0 
+
+minGini: 0.000000 - 2
+Region.size: 20
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 0 0 0 0 18 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 0 
+
+minGini: 10.772727 - 2
+Region.size: 53
+LeftChild.size: 44
+LeftChild.ClassCounts: 4 0 0 1 0 1 0 38 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 0 0 9 0 
+
+minGini: 7.508771 - 1
+Region.size: 44
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 0 0 1 0 0 0 2 
+RightChild.size: 38
+RightChild.ClassCounts: 1 0 0 0 0 1 0 36 
+
+minGini: 3.276190 - 4
+Region.size: 38
+LeftChild.size: 35
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 34 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 1 0 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 1.500000 - 5
+Region.size: 35
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 3 
+RightChild.size: 31
+RightChild.ClassCounts: 0 0 0 0 0 0 0 31 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 2.500000 - 1
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 0 0 1 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 1 0 0 0 2 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 21.025000 - 5
+Region.size: 167
+LeftChild.size: 160
+LeftChild.ClassCounts: 149 1 0 0 3 3 0 4 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 0 0 
+
+minGini: 15.426751 - 4
+Region.size: 160
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 157
+RightChild.ClassCounts: 149 1 0 0 0 3 0 4 
+
+minGini: 6.960264 - 1
+Region.size: 157
+LeftChild.size: 151
+LeftChild.ClassCounts: 149 1 0 0 0 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 3 0 3 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 3 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 3.625000 - 1
+Region.size: 151
+LeftChild.size: 135
+LeftChild.ClassCounts: 135 0 0 0 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 14 1 0 0 0 0 0 1 
+
+minGini: 1.866666 - 6
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 15
+RightChild.ClassCounts: 14 1 0 0 0 0 0 0 
+
+minGini: 1.500000 - 5
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 0 finished.
+
+minGini: 201.752795 - 1
+Region.size: 336
+LeftChild.size: 255
+LeftChild.ClassCounts: 143 65 3 3 23 2 5 11 
+RightChild.size: 81
+RightChild.ClassCounts: 0 10 0 0 5 17 0 49 
+
+minGini: 31.398897 - 4
+Region.size: 81
+LeftChild.size: 64
+LeftChild.ClassCounts: 0 6 0 0 5 4 0 49 
+RightChild.size: 17
+RightChild.ClassCounts: 0 4 0 0 0 13 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 17
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 0 0 0 0 13 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 17.838383 - 0
+Region.size: 64
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 5 0 0 3 0 0 1 
+RightChild.size: 55
+RightChild.ClassCounts: 0 1 0 0 2 4 0 48 
+
+minGini: 10.702127 - 0
+Region.size: 55
+LeftChild.size: 47
+LeftChild.ClassCounts: 0 1 0 0 0 2 0 44 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 2 2 0 4 
+
+minGini: 2.000000 - 5
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 4 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 2 2 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 3.826086 - 6
+Region.size: 47
+LeftChild.size: 46
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 44 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 1.333333 - 5
+Region.size: 46
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 1 
+RightChild.size: 43
+RightChild.ClassCounts: 0 0 0 0 0 0 0 43 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 1.666666 - 4
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 0 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 92.603235 - 6
+Region.size: 255
+LeftChild.size: 174
+LeftChild.ClassCounts: 143 10 1 1 1 2 5 11 
+RightChild.size: 81
+RightChild.ClassCounts: 0 55 2 2 22 0 0 0 
+
+minGini: 34.531645 - 2
+Region.size: 81
+LeftChild.size: 79
+LeftChild.ClassCounts: 0 55 0 2 22 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 0 
+
+minGini: 19.131362 - 0
+Region.size: 79
+LeftChild.size: 58
+LeftChild.ClassCounts: 0 51 0 2 5 0 0 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 4 0 0 17 0 0 0 
+
+minGini: 1.888888 - 1
+Region.size: 21
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 1 0 0 17 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 1.500000 - 1
+Region.size: 18
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 0 0 3 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 14 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 10.454545 - 0
+Region.size: 58
+LeftChild.size: 36
+LeftChild.ClassCounts: 0 36 0 0 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 15 0 2 5 0 0 0 
+
+minGini: 8.166666 - 4
+Region.size: 22
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 14 0 2 2 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 0 3 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 5.000000 - 4
+Region.size: 18
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 4 0 2 2 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 0 0 0 0 0 0 
+
+minGini: 4.000000 - 0
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 0 2 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 0 0 1 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 46.595238 - 2
+Region.size: 174
+LeftChild.size: 168
+LeftChild.ClassCounts: 143 10 0 1 1 2 0 11 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 1 0 0 0 5 0 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 0 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 33.187500 - 0
+Region.size: 168
+LeftChild.size: 160
+LeftChild.ClassCounts: 143 10 0 0 1 2 0 4 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 1 0 0 0 7 
+
+minGini: 0.000000 - 0
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 7 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 16.786666 - 5
+Region.size: 160
+LeftChild.size: 150
+LeftChild.ClassCounts: 143 2 0 0 1 2 0 2 
+RightChild.size: 10
+RightChild.ClassCounts: 0 8 0 0 0 0 0 2 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 12.065217 - 0
+Region.size: 150
+LeftChild.size: 138
+LeftChild.ClassCounts: 135 2 0 0 0 0 0 1 
+RightChild.size: 12
+RightChild.ClassCounts: 8 0 0 0 1 2 0 1 
+
+minGini: 3.111111 - 5
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 8 0 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 1 2 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 0 0 0 0 0 0 
+
+minGini: 5.288888 - 0
+Region.size: 138
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 0 0 0 0 0 0 
+RightChild.size: 135
+RightChild.ClassCounts: 133 1 0 0 0 0 0 1 
+
+minGini: 3.818181 - 5
+Region.size: 135
+LeftChild.size: 102
+LeftChild.ClassCounts: 102 0 0 0 0 0 0 0 
+RightChild.size: 33
+RightChild.ClassCounts: 31 1 0 0 0 0 0 1 
+
+minGini: 3.694444 - 0
+Region.size: 33
+LeftChild.size: 9
+LeftChild.ClassCounts: 8 0 0 0 0 0 0 1 
+RightChild.size: 24
+RightChild.ClassCounts: 23 1 0 0 0 0 0 0 
+
+minGini: 1.857142 - 5
+Region.size: 24
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 0 0 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 13 1 0 0 0 0 0 0 
+
+minGini: 1.666666 - 6
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 0 0 0 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+
+
+Tree Number: 1 finished.
+
+minGini: 172.661046 - 6
+Region.size: 336
+LeftChild.size: 219
+LeftChild.ClassCounts: 139 7 3 1 0 18 2 49 
+RightChild.size: 117
+RightChild.ClassCounts: 0 76 1 1 39 0 0 0 
+
+minGini: 31.476449 - 0
+Region.size: 117
+LeftChild.size: 69
+LeftChild.ClassCounts: 0 63 0 1 5 0 0 0 
+RightChild.size: 48
+RightChild.ClassCounts: 0 13 1 0 34 0 0 0 
+
+minGini: 17.757142 - 0
+Region.size: 48
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 9 1 0 10 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 0 4 0 0 24 0 0 0 
+
+minGini: 5.090909 - 0
+Region.size: 28
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 0 0 0 17 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 4 0 0 7 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 7 0 0 0 
+
+minGini: 6.606060 - 0
+Region.size: 20
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 2 0 0 9 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 7 1 0 1 0 0 0 
+
+minGini: 1.750000 - 4
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 7 0 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 9 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 7.611940 - 2
+Region.size: 69
+LeftChild.size: 67
+LeftChild.ClassCounts: 0 63 0 1 3 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 7.315789 - 6
+Region.size: 67
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 29 0 0 0 0 0 0 
+RightChild.size: 38
+RightChild.ClassCounts: 0 34 0 1 3 0 0 0 
+
+minGini: 5.823529 - 5
+Region.size: 38
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 2 0 0 2 0 0 0 
+RightChild.size: 34
+RightChild.ClassCounts: 0 32 0 1 1 0 0 0 
+
+minGini: 3.538461 - 6
+Region.size: 34
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 11 0 1 1 0 0 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 21 0 0 0 0 0 0 
+
+minGini: 1.000000 - 0
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 1 1 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 93.243717 - 5
+Region.size: 219
+LeftChild.size: 121
+LeftChild.ClassCounts: 107 0 0 0 0 7 0 7 
+RightChild.size: 98
+RightChild.ClassCounts: 32 7 3 1 0 11 2 42 
+
+minGini: 44.334637 - 0
+Region.size: 98
+LeftChild.size: 39
+LeftChild.ClassCounts: 31 5 0 0 0 0 0 3 
+RightChild.size: 59
+RightChild.ClassCounts: 1 2 3 1 0 11 2 39 
+
+minGini: 17.776515 - 4
+Region.size: 59
+LeftChild.size: 48
+LeftChild.ClassCounts: 1 2 3 1 0 1 1 39 
+RightChild.size: 11
+RightChild.ClassCounts: 0 0 0 0 0 10 1 0 
+
+minGini: 1.333333 - 5
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 0 0 8 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 2 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 0 
+
+minGini: 7.950000 - 1
+Region.size: 48
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 2 3 1 0 0 1 0 
+RightChild.size: 40
+RightChild.ClassCounts: 0 0 0 0 0 1 0 39 
+
+minGini: 1.666666 - 0
+Region.size: 40
+LeftChild.size: 34
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 34 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 1 0 5 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 3.600000 - 6
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 2 0 1 0 0 1 0 
+
+minGini: 2.000000 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 0 1 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 1 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 0 
+
+minGini: 8.944444 - 6
+Region.size: 39
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 36
+RightChild.ClassCounts: 31 2 0 0 0 0 0 3 
+
+minGini: 7.257142 - 5
+Region.size: 36
+LeftChild.size: 35
+LeftChild.ClassCounts: 31 1 0 0 0 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 6.367521 - 0
+Region.size: 35
+LeftChild.size: 26
+LeftChild.ClassCounts: 25 0 0 0 0 0 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 6 1 0 0 0 0 0 2 
+
+minGini: 3.000000 - 0
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 0 0 0 0 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 1.666666 - 4
+Region.size: 26
+LeftChild.size: 20
+LeftChild.ClassCounts: 20 0 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 0 0 
+
+minGini: 12.105952 - 1
+Region.size: 121
+LeftChild.size: 105
+LeftChild.ClassCounts: 104 0 0 0 0 0 0 1 
+RightChild.size: 16
+RightChild.ClassCounts: 3 0 0 0 0 7 0 6 
+
+minGini: 7.846153 - 0
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 3 0 0 0 0 7 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 5.380952 - 1
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 0 0 0 0 6 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 2 0 0 0 0 1 0 3 
+
+minGini: 1.500000 - 4
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 1 0 3 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 6 0 0 
+
+minGini: 1.920000 - 4
+Region.size: 105
+LeftChild.size: 80
+LeftChild.ClassCounts: 80 0 0 0 0 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 24 0 0 0 0 0 0 1 
+
+minGini: 1.833333 - 5
+Region.size: 25
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 0 0 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 11 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 2 finished.
+
+minGini: 183.369152 - 6
+Region.size: 336
+LeftChild.size: 236
+LeftChild.ClassCounts: 145 11 1 1 0 23 5 50 
+RightChild.size: 100
+RightChild.ClassCounts: 0 62 0 2 34 0 0 2 
+
+minGini: 35.294685 - 0
+Region.size: 100
+LeftChild.size: 54
+LeftChild.ClassCounts: 0 47 0 2 5 0 0 0 
+RightChild.size: 46
+RightChild.ClassCounts: 0 15 0 0 29 0 0 2 
+
+minGini: 19.813519 - 1
+Region.size: 46
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 8 0 0 25 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 7 0 0 4 0 0 2 
+
+minGini: 5.090909 - 5
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 7 0 0 4 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 2.666666 - 0
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 2 0 0 4 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 4 0 0 0 
+
+minGini: 10.110294 - 0
+Region.size: 33
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 7 0 0 10 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 1 0 0 15 0 0 0 
+
+minGini: 1.600000 - 4
+Region.size: 16
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 0 0 11 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 0 0 4 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.750000 - 5
+Region.size: 17
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 9 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 7 0 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 10.943396 - 1
+Region.size: 54
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 53
+RightChild.ClassCounts: 0 47 0 2 4 0 0 0 
+
+minGini: 10.181395 - 0
+Region.size: 53
+LeftChild.size: 43
+LeftChild.ClassCounts: 0 40 0 0 3 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 7 0 2 1 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 2 1 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 0 
+
+minGini: 4.615384 - 5
+Region.size: 43
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 10 0 0 3 0 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 0 30 0 0 0 0 0 0 
+
+minGini: 3.133333 - 1
+Region.size: 13
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 9 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 93.721915 - 5
+Region.size: 236
+LeftChild.size: 130
+LeftChild.ClassCounts: 121 0 0 0 0 4 0 5 
+RightChild.size: 106
+RightChild.ClassCounts: 24 11 1 1 0 19 5 45 
+
+minGini: 58.067415 - 4
+Region.size: 106
+LeftChild.size: 89
+LeftChild.ClassCounts: 24 11 1 1 0 2 5 45 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 0 0 0 17 0 0 
+
+minGini: 34.457142 - 1
+Region.size: 89
+LeftChild.size: 40
+LeftChild.ClassCounts: 24 7 1 1 0 0 5 2 
+RightChild.size: 49
+RightChild.ClassCounts: 0 4 0 0 0 2 0 43 
+
+minGini: 9.394871 - 6
+Region.size: 49
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 2 0 0 0 2 0 6 
+RightChild.size: 39
+RightChild.ClassCounts: 0 2 0 0 0 0 0 37 
+
+minGini: 0.000000 - 0
+Region.size: 39
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 37
+RightChild.ClassCounts: 0 0 0 0 0 0 0 37 
+
+minGini: 3.000000 - 0
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 2 0 6 
+
+minGini: 0.000000 - 0
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 6 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 17.333333 - 6
+Region.size: 40
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 3 1 1 0 0 5 1 
+RightChild.size: 28
+RightChild.ClassCounts: 23 4 0 0 0 0 0 1 
+
+minGini: 3.760000 - 0
+Region.size: 28
+LeftChild.size: 25
+LeftChild.ClassCounts: 23 1 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 3.404761 - 0
+Region.size: 25
+LeftChild.size: 21
+LeftChild.ClassCounts: 20 0 0 0 0 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 0 0 0 0 0 
+
+minGini: 1.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 1.600000 - 6
+Region.size: 21
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 1 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 5.777777 - 5
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 0 1 1 0 0 5 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 3.666666 - 2
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 0 1 0 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 1 0 0 0 5 0 
+
+minGini: 0.000000 - 3
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 0 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 16.535418 - 5
+Region.size: 130
+LeftChild.size: 63
+LeftChild.ClassCounts: 62 0 0 0 0 0 0 1 
+RightChild.size: 67
+RightChild.ClassCounts: 59 0 0 0 0 4 0 4 
+
+minGini: 4.000000 - 1
+Region.size: 67
+LeftChild.size: 59
+LeftChild.ClassCounts: 59 0 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 4 0 4 
+
+minGini: 0.000000 - 4
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 4 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 0 0 
+
+minGini: 1.882352 - 4
+Region.size: 63
+LeftChild.size: 46
+LeftChild.ClassCounts: 46 0 0 0 0 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 16 0 0 0 0 0 0 1 
+
+minGini: 1.500000 - 4
+Region.size: 17
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 0 0 0 0 0 0 
+
+minGini: 1.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+
+
+Tree Number: 3 finished.
+
+minGini: 173.213937 - 5
+Region.size: 336
+LeftChild.size: 212
+LeftChild.ClassCounts: 148 3 1 2 0 16 0 42 
+RightChild.size: 124
+RightChild.ClassCounts: 0 68 3 0 38 9 1 5 
+
+minGini: 63.828703 - 6
+Region.size: 124
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 2 0 0 0 9 1 4 
+RightChild.size: 108
+RightChild.ClassCounts: 0 66 3 0 38 0 0 1 
+
+minGini: 31.012692 - 0
+Region.size: 108
+LeftChild.size: 53
+LeftChild.ClassCounts: 0 51 0 0 2 0 0 0 
+RightChild.size: 55
+RightChild.ClassCounts: 0 15 3 0 36 0 0 1 
+
+minGini: 22.288888 - 1
+Region.size: 55
+LeftChild.size: 45
+LeftChild.ClassCounts: 0 8 3 0 34 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 7 0 0 2 0 0 1 
+
+minGini: 1.333333 - 5
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 2 0 0 1 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 12.952380 - 2
+Region.size: 45
+LeftChild.size: 42
+LeftChild.ClassCounts: 0 8 0 0 34 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 0 
+
+minGini: 9.898989 - 1
+Region.size: 42
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 5 0 0 4 0 0 0 
+RightChild.size: 33
+RightChild.ClassCounts: 0 3 0 0 30 0 0 0 
+
+minGini: 4.800000 - 0
+Region.size: 33
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 3 0 0 12 0 0 0 
+RightChild.size: 18
+RightChild.ClassCounts: 0 0 0 0 18 0 0 0 
+
+minGini: 3.750000 - 1
+Region.size: 15
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 7 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 3 0 0 5 0 0 0 
+
+minGini: 1.666666 - 6
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 1 0 0 5 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 1.666666 - 0
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 5 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 0 0 
+
+minGini: 3.384615 - 4
+Region.size: 53
+LeftChild.size: 40
+LeftChild.ClassCounts: 0 40 0 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 11 0 0 2 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 13
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 4.000000 - 4
+Region.size: 16
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 2 0 0 0 0 1 4 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 0 9 0 0 
+
+minGini: 1.600000 - 4
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 0 1 4 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 0 
+
+minGini: 79.056105 - 5
+Region.size: 212
+LeftChild.size: 111
+LeftChild.ClassCounts: 104 0 0 0 0 3 0 4 
+RightChild.size: 101
+RightChild.ClassCounts: 44 3 1 2 0 13 0 38 
+
+minGini: 39.999186 - 0
+Region.size: 101
+LeftChild.size: 41
+LeftChild.ClassCounts: 37 3 0 0 0 1 0 0 
+RightChild.size: 60
+RightChild.ClassCounts: 7 0 1 2 0 12 0 38 
+
+minGini: 24.423076 - 1
+Region.size: 60
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 0 0 2 0 0 0 0 
+RightChild.size: 52
+RightChild.ClassCounts: 1 0 1 0 0 12 0 38 
+
+minGini: 5.707317 - 4
+Region.size: 52
+LeftChild.size: 41
+LeftChild.ClassCounts: 1 0 1 0 0 1 0 38 
+RightChild.size: 11
+RightChild.ClassCounts: 0 0 0 0 0 11 0 0 
+
+minGini: 3.850000 - 2
+Region.size: 41
+LeftChild.size: 40
+LeftChild.ClassCounts: 1 0 0 0 0 1 0 38 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 1.948717 - 5
+Region.size: 40
+LeftChild.size: 39
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 38 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 1.750000 - 5
+Region.size: 39
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 7 
+RightChild.size: 31
+RightChild.ClassCounts: 0 0 0 0 0 0 0 31 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 0 0 7 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 0 
+
+minGini: 5.550000 - 1
+Region.size: 41
+LeftChild.size: 40
+LeftChild.ClassCounts: 37 3 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 4.714285 - 1
+Region.size: 40
+LeftChild.size: 26
+LeftChild.ClassCounts: 26 0 0 0 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 11 3 0 0 0 0 0 0 
+
+minGini: 3.750000 - 6
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 5 3 0 0 0 0 0 0 
+
+minGini: 1.666666 - 4
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 0 0 0 0 0 0 
+
+minGini: 1.600000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 0 0 0 0 0 0 
+
+minGini: 1.333333 - 5
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 9.172330 - 1
+Region.size: 111
+LeftChild.size: 103
+LeftChild.ClassCounts: 101 0 0 0 0 0 0 2 
+RightChild.size: 8
+RightChild.ClassCounts: 3 0 0 0 0 3 0 2 
+
+minGini: 2.400000 - 5
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 3 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 1 0 2 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 3.724137 - 4
+Region.size: 103
+LeftChild.size: 74
+LeftChild.ClassCounts: 74 0 0 0 0 0 0 0 
+RightChild.size: 29
+RightChild.ClassCounts: 27 0 0 0 0 0 0 2 
+
+minGini: 3.200000 - 1
+Region.size: 29
+LeftChild.size: 10
+LeftChild.ClassCounts: 8 0 0 0 0 0 0 2 
+RightChild.size: 19
+RightChild.ClassCounts: 19 0 0 0 0 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 2 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 4 finished.
+
+minGini: 164.076285 - 5
+Region.size: 336
+LeftChild.size: 201
+LeftChild.ClassCounts: 141 0 0 2 0 14 2 42 
+RightChild.size: 135
+RightChild.ClassCounts: 0 83 1 2 40 0 4 5 
+
+minGini: 50.903211 - 0
+Region.size: 135
+LeftChild.size: 76
+LeftChild.ClassCounts: 0 67 0 2 6 0 0 1 
+RightChild.size: 59
+RightChild.ClassCounts: 0 16 1 0 34 0 4 4 
+
+minGini: 29.620879 - 1
+Region.size: 59
+LeftChild.size: 52
+LeftChild.ClassCounts: 0 13 1 0 34 0 4 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 3 0 0 0 0 0 4 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 0 4 
+
+minGini: 20.408510 - 2
+Region.size: 52
+LeftChild.size: 47
+LeftChild.ClassCounts: 0 13 0 0 34 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 1 0 0 0 4 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 4 0 
+
+minGini: 16.189090 - 0
+Region.size: 47
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 10 0 0 12 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 3 0 0 22 0 0 0 
+
+minGini: 4.500000 - 0
+Region.size: 25
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 0 0 0 13 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 3 0 0 9 0 0 0 
+
+minGini: 1.500000 - 6
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 3 0 0 1 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 8 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 8.178571 - 4
+Region.size: 22
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 9 0 0 5 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 1 0 0 7 0 0 0 
+
+minGini: 1.333333 - 5
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 0 2 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 5 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 1.666666 - 0
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 1 0 0 5 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 15.729729 - 2
+Region.size: 76
+LeftChild.size: 74
+LeftChild.ClassCounts: 0 66 0 2 5 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 13.761904 - 5
+Region.size: 74
+LeftChild.size: 42
+LeftChild.ClassCounts: 0 34 0 2 5 0 0 1 
+RightChild.size: 32
+RightChild.ClassCounts: 0 32 0 0 0 0 0 0 
+
+minGini: 9.433333 - 6
+Region.size: 42
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 29 0 0 0 0 0 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 5 0 2 5 0 0 0 
+
+minGini: 4.250000 - 5
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 5 0 2 1 0 0 0 
+
+minGini: 3.200000 - 1
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 2 0 2 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 2 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 30
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 29
+RightChild.ClassCounts: 0 29 0 0 0 0 0 0 
+
+minGini: 38.362454 - 0
+Region.size: 201
+LeftChild.size: 137
+LeftChild.ClassCounts: 135 0 0 0 0 1 0 1 
+RightChild.size: 64
+RightChild.ClassCounts: 6 0 0 2 0 13 2 41 
+
+minGini: 18.807692 - 4
+Region.size: 64
+LeftChild.size: 52
+LeftChild.ClassCounts: 6 0 0 2 0 1 2 41 
+RightChild.size: 12
+RightChild.ClassCounts: 0 0 0 0 0 12 0 0 
+
+minGini: 15.560000 - 6
+Region.size: 52
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 0 
+RightChild.size: 50
+RightChild.ClassCounts: 6 0 0 2 0 1 0 41 
+
+minGini: 12.208333 - 0
+Region.size: 50
+LeftChild.size: 48
+LeftChild.ClassCounts: 6 0 0 0 0 1 0 41 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 0 
+
+minGini: 6.747368 - 1
+Region.size: 48
+LeftChild.size: 10
+LeftChild.ClassCounts: 6 0 0 0 0 0 0 4 
+RightChild.size: 38
+RightChild.ClassCounts: 0 0 0 0 0 1 0 37 
+
+minGini: 1.000000 - 0
+Region.size: 38
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 1 
+RightChild.size: 36
+RightChild.ClassCounts: 0 0 0 0 0 0 0 36 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 3.428571 - 1
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 1.600000 - 6
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 3.584848 - 0
+Region.size: 137
+LeftChild.size: 132
+LeftChild.ClassCounts: 131 0 0 0 0 1 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 0 0 0 0 0 0 1 
+
+minGini: 1.000000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 132
+LeftChild.size: 130
+LeftChild.ClassCounts: 130 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 1 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 5 finished.
+
+minGini: 200.672426 - 0
+Region.size: 336
+LeftChild.size: 194
+LeftChild.ClassCounts: 127 56 0 0 1 5 0 5 
+RightChild.size: 142
+RightChild.ClassCounts: 3 34 4 1 38 12 2 48 
+
+minGini: 88.327903 - 0
+Region.size: 142
+LeftChild.size: 107
+LeftChild.ClassCounts: 3 32 4 0 11 8 2 47 
+RightChild.size: 35
+RightChild.ClassCounts: 0 2 0 1 27 4 0 1 
+
+minGini: 6.724137 - 5
+Region.size: 35
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 1 0 4 0 1 
+RightChild.size: 29
+RightChild.ClassCounts: 0 2 0 0 27 0 0 0 
+
+minGini: 3.111111 - 5
+Region.size: 29
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 2 0 0 7 0 0 0 
+RightChild.size: 20
+RightChild.ClassCounts: 0 0 0 0 20 0 0 0 
+
+minGini: 2.000000 - 5
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 0 0 2 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 1 0 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 48.284210 - 5
+Region.size: 107
+LeftChild.size: 57
+LeftChild.ClassCounts: 3 0 0 0 0 8 2 44 
+RightChild.size: 50
+RightChild.ClassCounts: 0 32 4 0 11 0 0 3 
+
+minGini: 24.458333 - 1
+Region.size: 50
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 48
+RightChild.ClassCounts: 0 32 4 0 9 0 0 3 
+
+minGini: 22.062500 - 4
+Region.size: 48
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 7 4 0 2 0 0 3 
+RightChild.size: 32
+RightChild.ClassCounts: 0 25 0 0 7 0 0 0 
+
+minGini: 9.677419 - 5
+Region.size: 32
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 0 25 0 0 6 0 0 0 
+
+minGini: 9.000000 - 6
+Region.size: 31
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 0 18 0 0 6 0 0 0 
+
+minGini: 8.400000 - 0
+Region.size: 24
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 14 0 0 6 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 6.000000 - 1
+Region.size: 20
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 6 0 0 6 0 0 0 
+
+minGini: 4.000000 - 5
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 6 0 0 3 0 0 0 
+
+minGini: 3.000000 - 0
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 5 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 0 0 
+
+minGini: 6.833333 - 2
+Region.size: 16
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 7 0 0 2 0 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 0 0 
+
+minGini: 3.111111 - 6
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 9
+RightChild.ClassCounts: 0 7 0 0 2 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 0 2 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 9.224489 - 4
+Region.size: 57
+LeftChild.size: 49
+LeftChild.ClassCounts: 3 0 0 0 0 0 2 44 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 8 0 0 
+
+minGini: 5.154545 - 1
+Region.size: 49
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 0 0 0 0 0 2 1 
+RightChild.size: 44
+RightChild.ClassCounts: 1 0 0 0 0 0 0 43 
+
+minGini: 1.500000 - 5
+Region.size: 44
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 3 
+RightChild.size: 40
+RightChild.ClassCounts: 0 0 0 0 0 0 0 40 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 1.333333 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 24.539175 - 5
+Region.size: 194
+LeftChild.size: 139
+LeftChild.ClassCounts: 127 2 0 0 0 5 0 5 
+RightChild.size: 55
+RightChild.ClassCounts: 0 54 0 0 1 0 0 0 
+
+minGini: 1.857142 - 5
+Region.size: 55
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 13 0 0 1 0 0 0 
+RightChild.size: 41
+RightChild.ClassCounts: 0 41 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 16.266233 - 4
+Region.size: 139
+LeftChild.size: 132
+LeftChild.ClassCounts: 125 2 0 0 0 0 0 5 
+RightChild.size: 7
+RightChild.ClassCounts: 2 0 0 0 0 5 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 5 0 0 
+
+minGini: 12.113725 - 6
+Region.size: 132
+LeftChild.size: 102
+LeftChild.ClassCounts: 101 0 0 0 0 0 0 1 
+RightChild.size: 30
+RightChild.ClassCounts: 24 2 0 0 0 0 0 4 
+
+minGini: 9.076923 - 6
+Region.size: 30
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 2 
+RightChild.size: 26
+RightChild.ClassCounts: 22 2 0 0 0 0 0 2 
+
+minGini: 3.666666 - 1
+Region.size: 26
+LeftChild.size: 24
+LeftChild.ClassCounts: 22 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 3.428571 - 5
+Region.size: 24
+LeftChild.size: 14
+LeftChild.ClassCounts: 12 2 0 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 0 0 0 0 0 0 
+
+minGini: 2.400000 - 0
+Region.size: 14
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 0 0 0 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 1.500000 - 0
+Region.size: 102
+LeftChild.size: 98
+LeftChild.ClassCounts: 98 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 6 finished.
+
+minGini: 174.637500 - 6
+Region.size: 336
+LeftChild.size: 240
+LeftChild.ClassCounts: 159 12 2 3 0 12 3 49 
+RightChild.size: 96
+RightChild.ClassCounts: 0 57 4 2 32 0 0 1 
+
+minGini: 36.827301 - 0
+Region.size: 96
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 36 0 0 1 0 0 0 
+RightChild.size: 59
+RightChild.ClassCounts: 0 21 4 2 31 0 0 1 
+
+minGini: 30.992628 - 4
+Region.size: 59
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 7 4 2 23 0 0 1 
+RightChild.size: 22
+RightChild.ClassCounts: 0 14 0 0 8 0 0 0 
+
+minGini: 8.888888 - 4
+Region.size: 22
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 10 0 0 8 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 6.153846 - 5
+Region.size: 18
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 5 0 0 8 0 0 0 
+
+minGini: 4.444444 - 4
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 5 0 0 4 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 4 0 0 0 
+
+minGini: 1.600000 - 5
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 0 0 4 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 4 0 0 0 
+
+minGini: 16.560344 - 6
+Region.size: 37
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 5 0 2 22 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 2 4 0 1 0 0 1 
+
+minGini: 2.933333 - 4
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 4 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 8.592592 - 0
+Region.size: 29
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 3 0 2 22 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 6.583333 - 0
+Region.size: 27
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 2 1 0 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 0 3 0 0 21 0 0 0 
+
+minGini: 4.555555 - 4
+Region.size: 24
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 1 0 0 17 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 2 0 0 4 0 0 0 
+
+minGini: 1.600000 - 4
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 0 0 4 0 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 1.600000 - 4
+Region.size: 18
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 0 0 4 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 0 0 13 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 0 
+
+minGini: 1.666666 - 1
+Region.size: 37
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 31 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 5 0 0 1 0 0 0 
+
+minGini: 1.333333 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 68.855555 - 1
+Region.size: 240
+LeftChild.size: 180
+LeftChild.ClassCounts: 157 9 2 3 0 0 3 6 
+RightChild.size: 60
+RightChild.ClassCounts: 2 3 0 0 0 12 0 43 
+
+minGini: 24.109090 - 1
+Region.size: 60
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 0 0 0 3 0 1 
+RightChild.size: 55
+RightChild.ClassCounts: 2 2 0 0 0 9 0 42 
+
+minGini: 18.113207 - 5
+Region.size: 55
+LeftChild.size: 53
+LeftChild.ClassCounts: 2 0 0 0 0 9 0 42 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 7.459595 - 4
+Region.size: 53
+LeftChild.size: 44
+LeftChild.ClassCounts: 2 0 0 0 0 1 0 41 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 0 8 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 8 0 0 
+
+minGini: 5.138211 - 4
+Region.size: 44
+LeftChild.size: 41
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 39 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 1 0 2 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 1.333333 - 5
+Region.size: 41
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 1 
+RightChild.size: 38
+RightChild.ClassCounts: 0 0 0 0 0 0 0 38 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 31.918128 - 5
+Region.size: 180
+LeftChild.size: 171
+LeftChild.ClassCounts: 157 4 2 3 0 0 1 4 
+RightChild.size: 9
+RightChild.ClassCounts: 0 5 0 0 0 0 2 2 
+
+minGini: 2.000000 - 4
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 2 2 
+
+minGini: 1.333333 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 2 1 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 0 
+
+minGini: 18.405923 - 0
+Region.size: 171
+LeftChild.size: 164
+LeftChild.ClassCounts: 157 4 0 0 0 0 0 3 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 2 3 0 0 1 1 
+
+minGini: 2.500000 - 6
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 2 0 0 0 1 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 3 0 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 13.270908 - 4
+Region.size: 164
+LeftChild.size: 17
+LeftChild.ClassCounts: 15 2 0 0 0 0 0 0 
+RightChild.size: 147
+RightChild.ClassCounts: 142 2 0 0 0 0 0 3 
+
+minGini: 9.240000 - 5
+Region.size: 147
+LeftChild.size: 97
+LeftChild.ClassCounts: 97 0 0 0 0 0 0 0 
+RightChild.size: 50
+RightChild.ClassCounts: 45 2 0 0 0 0 0 3 
+
+minGini: 7.035460 - 6
+Region.size: 50
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 2 
+RightChild.size: 47
+RightChild.ClassCounts: 44 2 0 0 0 0 0 1 
+
+minGini: 5.435483 - 0
+Region.size: 47
+LeftChild.size: 31
+LeftChild.ClassCounts: 30 0 0 0 0 0 0 1 
+RightChild.size: 16
+RightChild.ClassCounts: 14 2 0 0 0 0 0 0 
+
+minGini: 3.200000 - 5
+Region.size: 16
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 8 2 0 0 0 0 0 0 
+
+minGini: 2.000000 - 6
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 1.666666 - 1
+Region.size: 31
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 0 0 0 0 0 0 1 
+RightChild.size: 25
+RightChild.ClassCounts: 25 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 17
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+
+
+Tree Number: 7 finished.
+
+minGini: 192.342098 - 0
+Region.size: 336
+LeftChild.size: 179
+LeftChild.ClassCounts: 132 40 0 0 2 0 0 5 
+RightChild.size: 157
+RightChild.ClassCounts: 9 30 1 2 28 24 4 59 
+
+minGini: 111.050420 - 0
+Region.size: 157
+LeftChild.size: 140
+LeftChild.ClassCounts: 9 27 1 0 16 24 4 59 
+RightChild.size: 17
+RightChild.ClassCounts: 0 3 0 2 12 0 0 0 
+
+minGini: 3.666666 - 5
+Region.size: 17
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 3 0 2 1 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 0 0 0 11 0 0 0 
+
+minGini: 1.333333 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 2 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 0 
+
+minGini: 79.112246 - 4
+Region.size: 140
+LeftChild.size: 73
+LeftChild.ClassCounts: 7 6 1 0 3 0 1 55 
+RightChild.size: 67
+RightChild.ClassCounts: 2 21 0 0 13 24 3 4 
+
+minGini: 30.686379 - 5
+Region.size: 67
+LeftChild.size: 31
+LeftChild.ClassCounts: 2 0 0 0 0 24 1 4 
+RightChild.size: 36
+RightChild.ClassCounts: 0 21 0 0 13 0 2 0 
+
+minGini: 13.371428 - 4
+Region.size: 36
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 13 0 0 0 0 2 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 8 0 0 13 0 0 0 
+
+minGini: 6.117647 - 6
+Region.size: 21
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 4 0 0 13 0 0 0 
+
+minGini: 4.875000 - 1
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 3 0 0 13 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 1.857142 - 4
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 1 0 0 13 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 1 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 0 0 0 12 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 0 0 0 0 0 0 
+
+minGini: 8.551724 - 5
+Region.size: 31
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 0 0 0 24 1 4 
+
+minGini: 3.000000 - 4
+Region.size: 29
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 1 1 4 
+RightChild.size: 23
+RightChild.ClassCounts: 0 0 0 0 0 23 0 0 
+
+minGini: 1.000000 - 0
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 1 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 0 4 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 22.491978 - 1
+Region.size: 73
+LeftChild.size: 22
+LeftChild.ClassCounts: 6 5 1 0 2 0 1 7 
+RightChild.size: 51
+RightChild.ClassCounts: 1 1 0 0 1 0 0 48 
+
+minGini: 3.880000 - 5
+Region.size: 51
+LeftChild.size: 50
+LeftChild.ClassCounts: 1 0 0 0 1 0 0 48 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 2.958333 - 5
+Region.size: 50
+LeftChild.size: 48
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 47 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 1 0 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.882352 - 0
+Region.size: 48
+LeftChild.size: 17
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 16 
+RightChild.size: 31
+RightChild.ClassCounts: 0 0 0 0 0 0 0 31 
+
+minGini: 1.500000 - 4
+Region.size: 17
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 13 
+RightChild.size: 4
+RightChild.ClassCounts: 1 0 0 0 0 0 0 3 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 11.647058 - 5
+Region.size: 22
+LeftChild.size: 17
+LeftChild.ClassCounts: 6 0 1 0 2 0 1 7 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 0 0 
+
+minGini: 8.666666 - 1
+Region.size: 17
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 0 0 0 2 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 2 0 1 0 0 0 1 7 
+
+minGini: 4.111111 - 0
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 7 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 1 0 0 0 1 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 0 0 7 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 20.924225 - 5
+Region.size: 179
+LeftChild.size: 141
+LeftChild.ClassCounts: 132 4 0 0 0 0 0 5 
+RightChild.size: 38
+RightChild.ClassCounts: 0 36 0 0 2 0 0 0 
+
+minGini: 3.111111 - 4
+Region.size: 38
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 29 0 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 7 0 0 2 0 0 0 
+
+minGini: 2.000000 - 1
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 2 0 0 2 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 13.467625 - 1
+Region.size: 141
+LeftChild.size: 139
+LeftChild.ClassCounts: 132 4 0 0 0 0 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 11.231601 - 0
+Region.size: 139
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 0 0 0 0 0 0 
+RightChild.size: 132
+RightChild.ClassCounts: 128 1 0 0 0 0 0 3 
+
+minGini: 7.380392 - 4
+Region.size: 132
+LeftChild.size: 102
+LeftChild.ClassCounts: 101 1 0 0 0 0 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 27 0 0 0 0 0 0 3 
+
+minGini: 4.200000 - 4
+Region.size: 30
+LeftChild.size: 10
+LeftChild.ClassCounts: 7 0 0 0 0 0 0 3 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 0 0 0 0 0 0 
+
+minGini: 1.666666 - 5
+Region.size: 102
+LeftChild.size: 96
+LeftChild.ClassCounts: 96 0 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 0 0 
+
+minGini: 2.400000 - 5
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 8 finished.
+
+minGini: 169.589701 - 6
+Region.size: 336
+LeftChild.size: 246
+LeftChild.ClassCounts: 159 5 2 0 0 18 7 55 
+RightChild.size: 90
+RightChild.ClassCounts: 0 62 1 0 25 0 0 2 
+
+minGini: 25.552269 - 0
+Region.size: 90
+LeftChild.size: 53
+LeftChild.ClassCounts: 0 50 0 0 3 0 0 0 
+RightChild.size: 37
+RightChild.ClassCounts: 0 12 1 0 22 0 0 2 
+
+minGini: 15.166666 - 6
+Region.size: 37
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 5 0 0 20 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 7 1 0 2 0 0 2 
+
+minGini: 4.600000 - 1
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 7 1 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 1.750000 - 4
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 7 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 0 0 
+
+minGini: 6.515151 - 1
+Region.size: 25
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 3 0 0 19 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 4.615384 - 1
+Region.size: 22
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 9 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 3 0 0 10 0 0 0 
+
+minGini: 3.333333 - 1
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 2 0 0 10 0 0 0 
+
+minGini: 2.857142 - 0
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 2 0 0 5 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 5 0 0 0 
+
+minGini: 5.217391 - 5
+Region.size: 53
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 20 0 0 3 0 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 0 30 0 0 0 0 0 0 
+
+minGini: 3.636363 - 1
+Region.size: 23
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 20 0 0 2 0 0 0 
+
+minGini: 3.200000 - 0
+Region.size: 22
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 0 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 8 0 0 2 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 70.780708 - 0
+Region.size: 246
+LeftChild.size: 161
+LeftChild.ClassCounts: 150 5 0 0 0 2 0 4 
+RightChild.size: 85
+RightChild.ClassCounts: 9 0 2 0 0 16 7 51 
+
+minGini: 31.411231 - 4
+Region.size: 85
+LeftChild.size: 69
+LeftChild.ClassCounts: 9 0 2 0 0 1 6 51 
+RightChild.size: 16
+RightChild.ClassCounts: 0 0 0 0 0 15 1 0 
+
+minGini: 1.000000 - 4
+Region.size: 16
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 1 1 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 0 14 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 0 
+
+minGini: 18.098039 - 1
+Region.size: 69
+LeftChild.size: 18
+LeftChild.ClassCounts: 8 0 2 0 0 0 5 3 
+RightChild.size: 51
+RightChild.ClassCounts: 1 0 0 0 0 1 1 48 
+
+minGini: 3.880000 - 2
+Region.size: 51
+LeftChild.size: 50
+LeftChild.ClassCounts: 1 0 0 0 0 1 0 48 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 0 
+
+minGini: 2.958333 - 1
+Region.size: 50
+LeftChild.size: 48
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 47 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 1 0 1 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 1.913043 - 4
+Region.size: 48
+LeftChild.size: 23
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 22 
+RightChild.size: 25
+RightChild.ClassCounts: 0 0 0 0 0 0 0 25 
+
+minGini: 1.666666 - 1
+Region.size: 23
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 17 
+RightChild.size: 6
+RightChild.ClassCounts: 1 0 0 0 0 0 0 5 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 0 0 5 
+
+minGini: 9.402597 - 4
+Region.size: 18
+LeftChild.size: 11
+LeftChild.ClassCounts: 6 0 2 0 0 0 0 3 
+RightChild.size: 7
+RightChild.ClassCounts: 2 0 0 0 0 0 5 0 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 0 5 0 
+
+minGini: 2.400000 - 5
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 2 0 0 0 0 3 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 11.641025 - 5
+Region.size: 161
+LeftChild.size: 156
+LeftChild.ClassCounts: 150 0 0 0 0 2 0 4 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 0 0 
+
+minGini: 7.792207 - 4
+Region.size: 156
+LeftChild.size: 154
+LeftChild.ClassCounts: 150 0 0 0 0 0 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 5.882352 - 1
+Region.size: 154
+LeftChild.size: 153
+LeftChild.ClassCounts: 150 0 0 0 0 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 5.550000 - 5
+Region.size: 153
+LeftChild.size: 113
+LeftChild.ClassCounts: 113 0 0 0 0 0 0 0 
+RightChild.size: 40
+RightChild.ClassCounts: 37 0 0 0 0 0 0 3 
+
+minGini: 0.000000 - 5
+Region.size: 40
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 37
+RightChild.ClassCounts: 37 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 9 finished.
+
+minGini: 166.164077 - 5
+Region.size: 336
+LeftChild.size: 194
+LeftChild.ClassCounts: 145 2 1 0 1 14 0 31 
+RightChild.size: 142
+RightChild.ClassCounts: 0 80 0 1 35 9 5 12 
+
+minGini: 72.421428 - 6
+Region.size: 142
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 5 0 0 0 9 5 11 
+RightChild.size: 112
+RightChild.ClassCounts: 0 75 0 1 35 0 0 1 
+
+minGini: 29.333333 - 0
+Region.size: 112
+LeftChild.size: 82
+LeftChild.ClassCounts: 0 70 0 1 10 0 0 1 
+RightChild.size: 30
+RightChild.ClassCounts: 0 5 0 0 25 0 0 0 
+
+minGini: 6.666666 - 6
+Region.size: 30
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 5 0 0 10 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 0 0 0 15 0 0 0 
+
+minGini: 3.750000 - 0
+Region.size: 15
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 7 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 5 0 0 3 0 0 0 
+
+minGini: 1.500000 - 1
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 0 3 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 19.269230 - 0
+Region.size: 82
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 30 0 0 0 0 0 0 
+RightChild.size: 52
+RightChild.ClassCounts: 0 40 0 1 10 0 0 1 
+
+minGini: 15.306122 - 0
+Region.size: 52
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 49
+RightChild.ClassCounts: 0 40 0 1 7 0 0 1 
+
+minGini: 12.382978 - 1
+Region.size: 49
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 47
+RightChild.ClassCounts: 0 40 0 1 5 0 0 1 
+
+minGini: 10.652173 - 1
+Region.size: 47
+LeftChild.size: 46
+LeftChild.ClassCounts: 0 40 0 1 5 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 10.176470 - 1
+Region.size: 46
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 0 0 0 0 0 0 
+RightChild.size: 34
+RightChild.ClassCounts: 0 28 0 1 5 0 0 0 
+
+minGini: 7.187500 - 1
+Region.size: 34
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 32
+RightChild.ClassCounts: 0 28 0 1 3 0 0 0 
+
+minGini: 6.470588 - 6
+Region.size: 32
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 13 0 1 3 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 0 0 0 0 0 0 
+
+minGini: 5.484848 - 6
+Region.size: 17
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 10 0 0 1 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 3 0 1 2 0 0 0 
+
+minGini: 2.500000 - 1
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 1 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 0 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 12.857142 - 4
+Region.size: 30
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 5 0 0 0 0 5 11 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 0 9 0 0 
+
+minGini: 8.975000 - 4
+Region.size: 21
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 4 0 0 0 0 1 11 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 0 0 0 0 4 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 4 0 
+
+minGini: 1.833333 - 0
+Region.size: 16
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 0 0 0 0 0 1 11 
+
+minGini: 0.000000 - 2
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 11 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 0 
+
+minGini: 34.207222 - 1
+Region.size: 194
+LeftChild.size: 144
+LeftChild.ClassCounts: 140 2 1 0 1 0 0 0 
+RightChild.size: 50
+RightChild.ClassCounts: 5 0 0 0 0 14 0 31 
+
+minGini: 22.666666 - 5
+Region.size: 50
+LeftChild.size: 45
+LeftChild.ClassCounts: 4 0 0 0 0 10 0 31 
+RightChild.size: 5
+RightChild.ClassCounts: 1 0 0 0 0 4 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 0 0 
+
+minGini: 7.085714 - 4
+Region.size: 45
+LeftChild.size: 35
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 31 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 0 0 0 10 0 0 
+
+minGini: 5.741935 - 6
+Region.size: 35
+LeftChild.size: 31
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 29 
+RightChild.size: 4
+RightChild.ClassCounts: 2 0 0 0 0 0 0 2 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 2.931034 - 4
+Region.size: 31
+LeftChild.size: 29
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 28 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 1.333333 - 5
+Region.size: 29
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 2 
+RightChild.size: 26
+RightChild.ClassCounts: 0 0 0 0 0 0 0 26 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 5.902097 - 4
+Region.size: 144
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 143
+RightChild.ClassCounts: 140 2 1 0 0 0 0 0 
+
+minGini: 3.943661 - 2
+Region.size: 143
+LeftChild.size: 142
+LeftChild.ClassCounts: 140 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 3.652173 - 6
+Region.size: 142
+LeftChild.size: 119
+LeftChild.ClassCounts: 119 0 0 0 0 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 21 2 0 0 0 0 0 0 
+
+minGini: 1.909090 - 5
+Region.size: 23
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 21 1 0 0 0 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 22
+LeftChild.size: 20
+LeftChild.ClassCounts: 20 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 10 finished.
+
+minGini: 182.379166 - 6
+Region.size: 336
+LeftChild.size: 240
+LeftChild.ClassCounts: 148 14 3 0 1 24 2 48 
+RightChild.size: 96
+RightChild.ClassCounts: 0 61 2 0 32 0 0 1 
+
+minGini: 43.510638 - 2
+Region.size: 96
+LeftChild.size: 94
+LeftChild.ClassCounts: 0 61 0 0 32 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 0 
+
+minGini: 42.415850 - 4
+Region.size: 94
+LeftChild.size: 55
+LeftChild.ClassCounts: 0 39 0 0 15 0 0 1 
+RightChild.size: 39
+RightChild.ClassCounts: 0 22 0 0 17 0 0 0 
+
+minGini: 11.428571 - 0
+Region.size: 39
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 20 0 0 5 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 2 0 0 12 0 0 0 
+
+minGini: 2.400000 - 6
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 2 0 0 3 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 9 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 6.666666 - 5
+Region.size: 25
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 10 0 0 5 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 0 0 0 0 0 0 
+
+minGini: 2.857142 - 6
+Region.size: 15
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 2 0 0 5 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 4 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 21.744680 - 5
+Region.size: 55
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 0 0 
+RightChild.size: 47
+RightChild.ClassCounts: 0 31 0 0 15 0 0 1 
+
+minGini: 16.047272 - 6
+Region.size: 47
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 11 0 0 14 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 20 0 0 1 0 0 1 
+
+minGini: 2.900000 - 4
+Region.size: 22
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 1 
+RightChild.size: 20
+RightChild.ClassCounts: 0 19 0 0 1 0 0 0 
+
+minGini: 1.600000 - 4
+Region.size: 20
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 10.476190 - 4
+Region.size: 25
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 11 0 0 10 0 0 0 
+
+minGini: 5.714285 - 0
+Region.size: 21
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 4 0 0 10 0 0 0 
+
+minGini: 4.606060 - 4
+Region.size: 14
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 1 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 2 0 0 9 0 0 0 
+
+minGini: 1.800000 - 6
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 1 0 0 9 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 0 2 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 7 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 79.560191 - 1
+Region.size: 240
+LeftChild.size: 172
+LeftChild.ClassCounts: 147 11 3 0 1 3 2 5 
+RightChild.size: 68
+RightChild.ClassCounts: 1 3 0 0 0 21 0 43 
+
+minGini: 31.701587 - 0
+Region.size: 68
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 2 
+RightChild.size: 63
+RightChild.ClassCounts: 1 0 0 0 0 21 0 41 
+
+minGini: 24.294339 - 5
+Region.size: 63
+LeftChild.size: 53
+LeftChild.ClassCounts: 1 0 0 0 0 13 0 39 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 0 0 0 8 0 2 
+
+minGini: 1.333333 - 6
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 2 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 7 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 3.805860 - 4
+Region.size: 53
+LeftChild.size: 39
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 38 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 0 13 0 1 
+
+minGini: 1.600000 - 0
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 4 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 0 9 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 0 0 
+
+minGini: 1.882352 - 4
+Region.size: 39
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 22 
+RightChild.size: 17
+RightChild.ClassCounts: 1 0 0 0 0 0 0 16 
+
+minGini: 1.000000 - 5
+Region.size: 17
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 1 
+RightChild.size: 15
+RightChild.ClassCounts: 0 0 0 0 0 0 0 15 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 39.070658 - 2
+Region.size: 172
+LeftChild.size: 167
+LeftChild.ClassCounts: 147 11 0 0 1 3 0 5 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 3 0 0 0 2 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 0 
+
+minGini: 18.507492 - 5
+Region.size: 167
+LeftChild.size: 154
+LeftChild.ClassCounts: 147 1 0 0 1 2 0 3 
+RightChild.size: 13
+RightChild.ClassCounts: 0 10 0 0 0 1 0 2 
+
+minGini: 2.818181 - 5
+Region.size: 13
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 0 10 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 11.686274 - 0
+Region.size: 154
+LeftChild.size: 153
+LeftChild.ClassCounts: 147 1 0 0 1 1 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 10.569444 - 0
+Region.size: 153
+LeftChild.size: 144
+LeftChild.ClassCounts: 141 1 0 0 0 0 0 2 
+RightChild.size: 9
+RightChild.ClassCounts: 6 0 0 0 1 1 0 1 
+
+minGini: 2.714285 - 6
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 1 1 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 5.461538 - 6
+Region.size: 144
+LeftChild.size: 118
+LeftChild.ClassCounts: 118 0 0 0 0 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 23 1 0 0 0 0 0 2 
+
+minGini: 3.680000 - 5
+Region.size: 26
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 23 0 0 0 0 0 0 2 
+
+minGini: 2.666666 - 6
+Region.size: 25
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 2 
+RightChild.size: 19
+RightChild.ClassCounts: 19 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 11 finished.
+
+minGini: 170.911826 - 6
+Region.size: 336
+LeftChild.size: 226
+LeftChild.ClassCounts: 149 7 0 0 0 21 4 45 
+RightChild.size: 110
+RightChild.ClassCounts: 0 66 1 1 42 0 0 0 
+
+minGini: 49.155127 - 4
+Region.size: 110
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 30 1 0 6 0 0 0 
+RightChild.size: 73
+RightChild.ClassCounts: 0 36 0 1 36 0 0 0 
+
+minGini: 34.646489 - 6
+Region.size: 73
+LeftChild.size: 59
+LeftChild.ClassCounts: 0 25 0 1 33 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 11 0 0 3 0 0 0 
+
+minGini: 1.833333 - 1
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 11 0 0 1 0 0 0 
+
+minGini: 1.500000 - 1
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 26.647465 - 5
+Region.size: 59
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 17 0 0 11 0 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 0 8 0 1 22 0 0 0 
+
+minGini: 11.386554 - 6
+Region.size: 31
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 2 0 0 15 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 6 0 1 7 0 0 0 
+
+minGini: 5.636363 - 5
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 3 0 1 7 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 4.285714 - 0
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 3 0 1 3 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 4 0 0 0 
+
+minGini: 1.500000 - 4
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 3 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 1.875000 - 1
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 1 0 0 15 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 0 0 0 15 0 0 0 
+
+minGini: 9.005128 - 0
+Region.size: 28
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 13 0 0 2 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 4 0 0 9 0 0 0 
+
+minGini: 3.272727 - 1
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 2 0 0 9 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 9 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 0 0 0 0 0 0 
+
+minGini: 7.235294 - 6
+Region.size: 37
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 34
+RightChild.ClassCounts: 0 30 1 0 3 0 0 0 
+
+minGini: 5.454545 - 2
+Region.size: 34
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 30 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 3.750000 - 0
+Region.size: 33
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 30 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 3.000000 - 0
+Region.size: 32
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 24 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 6 0 0 2 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 66.193760 - 1
+Region.size: 226
+LeftChild.size: 168
+LeftChild.ClassCounts: 148 4 0 0 0 4 4 8 
+RightChild.size: 58
+RightChild.ClassCounts: 1 3 0 0 0 17 0 37 
+
+minGini: 27.357142 - 2
+Region.size: 58
+LeftChild.size: 56
+LeftChild.ClassCounts: 1 3 0 0 0 15 0 37 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 25.360000 - 1
+Region.size: 56
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 3 
+RightChild.size: 50
+RightChild.ClassCounts: 1 0 0 0 0 15 0 34 
+
+minGini: 8.923076 - 4
+Region.size: 50
+LeftChild.size: 39
+LeftChild.ClassCounts: 1 0 0 0 0 4 0 34 
+RightChild.size: 11
+RightChild.ClassCounts: 0 0 0 0 0 11 0 0 
+
+minGini: 3.442857 - 5
+Region.size: 39
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 0 0 0 0 3 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 0 0 0 0 0 1 0 34 
+
+minGini: 1.600000 - 0
+Region.size: 35
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 30 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 1 0 4 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 0 4 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 3 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 31.061728 - 4
+Region.size: 168
+LeftChild.size: 162
+LeftChild.ClassCounts: 147 4 0 0 0 0 3 8 
+RightChild.size: 6
+RightChild.ClassCounts: 1 0 0 0 0 4 1 0 
+
+minGini: 1.600000 - 4
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 0 0 0 0 4 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 0 0 
+
+minGini: 18.809216 - 0
+Region.size: 162
+LeftChild.size: 155
+LeftChild.ClassCounts: 147 4 0 0 0 0 0 4 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 0 3 4 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 0 
+
+minGini: 11.492170 - 6
+Region.size: 155
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 3 0 0 0 0 0 1 
+RightChild.size: 149
+RightChild.ClassCounts: 145 1 0 0 0 0 0 3 
+
+minGini: 7.277777 - 5
+Region.size: 149
+LeftChild.size: 113
+LeftChild.ClassCounts: 113 0 0 0 0 0 0 0 
+RightChild.size: 36
+RightChild.ClassCounts: 32 1 0 0 0 0 0 3 
+
+minGini: 5.600000 - 6
+Region.size: 36
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 35
+RightChild.ClassCounts: 32 1 0 0 0 0 0 2 
+
+minGini: 4.757575 - 4
+Region.size: 35
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 0 0 
+RightChild.size: 33
+RightChild.ClassCounts: 31 0 0 0 0 0 0 2 
+
+minGini: 2.935483 - 0
+Region.size: 33
+LeftChild.size: 31
+LeftChild.ClassCounts: 30 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 1.333333 - 4
+Region.size: 31
+LeftChild.size: 28
+LeftChild.ClassCounts: 28 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+
+
+Tree Number: 12 finished.
+
+minGini: 170.046941 - 6
+Region.size: 336
+LeftChild.size: 222
+LeftChild.ClassCounts: 148 8 2 2 0 16 2 44 
+RightChild.size: 114
+RightChild.ClassCounts: 0 70 1 2 40 0 0 1 
+
+minGini: 36.169580 - 0
+Region.size: 114
+LeftChild.size: 88
+LeftChild.ClassCounts: 0 68 1 2 16 0 0 1 
+RightChild.size: 26
+RightChild.ClassCounts: 0 2 0 0 24 0 0 0 
+
+minGini: 3.384615 - 1
+Region.size: 26
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 2 0 0 11 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 0 0 13 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 0 0 11 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 29.715447 - 5
+Region.size: 88
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 2 0 0 4 0 0 0 
+RightChild.size: 82
+RightChild.ClassCounts: 0 66 1 2 12 0 0 1 
+
+minGini: 25.414634 - 5
+Region.size: 82
+LeftChild.size: 41
+LeftChild.ClassCounts: 0 29 0 2 10 0 0 0 
+RightChild.size: 41
+RightChild.ClassCounts: 0 37 1 0 2 0 0 1 
+
+minGini: 6.307692 - 0
+Region.size: 41
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 28 0 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 9 1 0 2 0 0 1 
+
+minGini: 4.833333 - 4
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 9 1 0 2 0 0 0 
+
+minGini: 3.272727 - 2
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 9 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 1.800000 - 4
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 9 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.333333 - 5
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 1 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 15.635000 - 0
+Region.size: 41
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 15 0 0 1 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 14 0 2 9 0 0 0 
+
+minGini: 10.555555 - 6
+Region.size: 25
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 0 
+RightChild.size: 18
+RightChild.ClassCounts: 0 7 0 2 9 0 0 0 
+
+minGini: 9.066666 - 0
+Region.size: 18
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 7 0 2 6 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 6.545454 - 0
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 3 0 2 6 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 4.571428 - 1
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 3 0 2 2 0 0 0 
+
+minGini: 2.400000 - 0
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 3 0 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 0 
+
+minGini: 1.333333 - 2
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 96.038095 - 4
+Region.size: 222
+LeftChild.size: 210
+LeftChild.ClassCounts: 148 8 2 2 0 4 2 44 
+RightChild.size: 12
+RightChild.ClassCounts: 0 0 0 0 0 12 0 0 
+
+minGini: 70.193439 - 5
+Region.size: 210
+LeftChild.size: 123
+LeftChild.ClassCounts: 116 0 0 0 0 2 0 5 
+RightChild.size: 87
+RightChild.ClassCounts: 32 8 2 2 0 2 2 39 
+
+minGini: 43.796825 - 6
+Region.size: 87
+LeftChild.size: 45
+LeftChild.ClassCounts: 4 2 2 2 0 2 2 31 
+RightChild.size: 42
+RightChild.ClassCounts: 28 6 0 0 0 0 0 8 
+
+minGini: 13.111111 - 0
+Region.size: 42
+LeftChild.size: 36
+LeftChild.ClassCounts: 28 6 0 0 0 0 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 0 0 6 
+
+minGini: 9.134545 - 1
+Region.size: 36
+LeftChild.size: 25
+LeftChild.ClassCounts: 23 0 0 0 0 0 0 2 
+RightChild.size: 11
+RightChild.ClassCounts: 5 6 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 0 0 
+
+minGini: 3.428571 - 0
+Region.size: 25
+LeftChild.size: 14
+LeftChild.ClassCounts: 12 0 0 0 0 0 0 2 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 0 0 0 0 0 0 
+
+minGini: 2.000000 - 6
+Region.size: 14
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 2 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 19.906976 - 3
+Region.size: 45
+LeftChild.size: 43
+LeftChild.ClassCounts: 4 2 0 2 0 2 2 31 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 0 
+
+minGini: 17.458128 - 4
+Region.size: 43
+LeftChild.size: 29
+LeftChild.ClassCounts: 2 2 0 0 0 0 0 25 
+RightChild.size: 14
+RightChild.ClassCounts: 2 0 0 2 0 2 2 6 
+
+minGini: 7.000000 - 1
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 0 0 2 0 0 2 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 2 0 6 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 6 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 2.000000 - 5
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 2 0 0 2 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 0 
+
+minGini: 2.000000 - 1
+Region.size: 29
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 0 0 0 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 0 0 0 0 0 0 25 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 7.598290 - 1
+Region.size: 123
+LeftChild.size: 117
+LeftChild.ClassCounts: 115 0 0 0 0 0 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 1 0 0 0 0 2 0 3 
+
+minGini: 1.500000 - 0
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 0 0 0 0 0 0 3 
+
+minGini: 1.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 1.982758 - 0
+Region.size: 117
+LeftChild.size: 116
+LeftChild.ClassCounts: 115 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 1.916666 - 4
+Region.size: 116
+LeftChild.size: 92
+LeftChild.ClassCounts: 92 0 0 0 0 0 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 23 0 0 0 0 0 0 1 
+
+minGini: 1.500000 - 4
+Region.size: 24
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 1 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 0 0 0 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+
+
+Tree Number: 13 finished.
+
+minGini: 174.007778 - 6
+Region.size: 336
+LeftChild.size: 223
+LeftChild.ClassCounts: 133 10 1 0 1 29 3 46 
+RightChild.size: 113
+RightChild.ClassCounts: 0 84 1 1 27 0 0 0 
+
+minGini: 40.671409 - 6
+Region.size: 113
+LeftChild.size: 72
+LeftChild.ClassCounts: 0 47 0 1 24 0 0 0 
+RightChild.size: 41
+RightChild.ClassCounts: 0 37 1 0 3 0 0 0 
+
+minGini: 3.846153 - 4
+Region.size: 41
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 37 1 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 1.947368 - 0
+Region.size: 39
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 37 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.666666 - 0
+Region.size: 38
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 32 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 5 1 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 0 0 
+
+minGini: 31.093048 - 1
+Region.size: 72
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 15 0 0 2 0 0 0 
+RightChild.size: 55
+RightChild.ClassCounts: 0 32 0 1 22 0 0 0 
+
+minGini: 22.857142 - 1
+Region.size: 55
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 0 0 
+RightChild.size: 49
+RightChild.ClassCounts: 0 32 0 1 16 0 0 0 
+
+minGini: 18.521531 - 0
+Region.size: 49
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 29 0 1 8 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 3 0 0 8 0 0 0 
+
+minGini: 3.428571 - 6
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 3 0 0 4 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 4 0 0 0 
+
+minGini: 12.141025 - 6
+Region.size: 38
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 23 0 0 3 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 6 0 1 5 0 0 0 
+
+minGini: 1.714285 - 6
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 6 0 1 0 0 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 1 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 3.680000 - 4
+Region.size: 26
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 23 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 3.111111 - 6
+Region.size: 25
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 0 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 7 0 0 2 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 0 0 
+
+minGini: 1.875000 - 1
+Region.size: 17
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 15 0 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 0 0 0 0 0 0 
+
+minGini: 90.138009 - 5
+Region.size: 223
+LeftChild.size: 119
+LeftChild.ClassCounts: 111 0 0 0 0 5 0 3 
+RightChild.size: 104
+RightChild.ClassCounts: 22 10 1 0 1 24 3 43 
+
+minGini: 63.536231 - 6
+Region.size: 104
+LeftChild.size: 69
+LeftChild.ClassCounts: 1 6 1 0 1 22 3 35 
+RightChild.size: 35
+RightChild.ClassCounts: 21 4 0 0 0 2 0 8 
+
+minGini: 17.212121 - 2
+Region.size: 35
+LeftChild.size: 33
+LeftChild.ClassCounts: 21 4 0 0 0 0 0 8 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 13.646616 - 5
+Region.size: 33
+LeftChild.size: 14
+LeftChild.ClassCounts: 13 1 0 0 0 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 8 3 0 0 0 0 0 8 
+
+minGini: 7.076923 - 0
+Region.size: 19
+LeftChild.size: 13
+LeftChild.ClassCounts: 8 3 0 0 0 0 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 0 0 6 
+
+minGini: 4.363636 - 1
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 8 3 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 3.000000 - 0
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 0 0 0 0 0 0 
+
+minGini: 1.500000 - 1
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 0 0 0 0 0 0 
+
+minGini: 37.069124 - 5
+Region.size: 69
+LeftChild.size: 62
+LeftChild.ClassCounts: 1 0 1 0 1 22 3 34 
+RightChild.size: 7
+RightChild.ClassCounts: 0 6 0 0 0 0 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 31.189655 - 2
+Region.size: 62
+LeftChild.size: 58
+LeftChild.ClassCounts: 1 0 0 0 1 22 0 34 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 1 0 0 0 3 0 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 25.941558 - 0
+Region.size: 58
+LeftChild.size: 44
+LeftChild.ClassCounts: 1 0 0 0 1 12 0 30 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 0 10 0 4 
+
+minGini: 1.600000 - 4
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 4 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 0 9 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 3.812500 - 4
+Region.size: 44
+LeftChild.size: 32
+LeftChild.ClassCounts: 1 0 0 0 1 0 0 30 
+RightChild.size: 12
+RightChild.ClassCounts: 0 0 0 0 0 12 0 0 
+
+minGini: 1.935483 - 4
+Region.size: 32
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 1 0 0 0 0 0 0 30 
+
+minGini: 1.333333 - 0
+Region.size: 31
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 2 
+RightChild.size: 28
+RightChild.ClassCounts: 0 0 0 0 0 0 0 28 
+
+minGini: 1.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 12.265306 - 0
+Region.size: 119
+LeftChild.size: 98
+LeftChild.ClassCounts: 97 0 0 0 0 0 0 1 
+RightChild.size: 21
+RightChild.ClassCounts: 14 0 0 0 0 5 0 2 
+
+minGini: 3.500000 - 4
+Region.size: 21
+LeftChild.size: 16
+LeftChild.ClassCounts: 14 0 0 0 0 0 0 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 5 0 0 
+
+minGini: 1.866666 - 1
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 14 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 1.000000 - 5
+Region.size: 15
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 1.956521 - 6
+Region.size: 98
+LeftChild.size: 52
+LeftChild.ClassCounts: 52 0 0 0 0 0 0 0 
+RightChild.size: 46
+RightChild.ClassCounts: 45 0 0 0 0 0 0 1 
+
+minGini: 1.818181 - 4
+Region.size: 46
+LeftChild.size: 35
+LeftChild.ClassCounts: 35 0 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 10 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 14 finished.
+
+minGini: 196.623895 - 0
+Region.size: 336
+LeftChild.size: 195
+LeftChild.ClassCounts: 134 54 0 0 0 5 0 2 
+RightChild.size: 141
+RightChild.ClassCounts: 6 33 2 2 40 19 1 38 
+
+minGini: 84.015310 - 5
+Region.size: 141
+LeftChild.size: 68
+LeftChild.ClassCounts: 6 0 1 2 4 19 1 35 
+RightChild.size: 73
+RightChild.ClassCounts: 0 33 1 0 36 0 0 3 
+
+minGini: 20.976489 - 0
+Region.size: 73
+LeftChild.size: 44
+LeftChild.ClassCounts: 0 32 1 0 8 0 0 3 
+RightChild.size: 29
+RightChild.ClassCounts: 0 1 0 0 28 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 29
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 0 0 0 28 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 16.047619 - 6
+Region.size: 44
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 42
+RightChild.ClassCounts: 0 32 1 0 8 0 0 1 
+
+minGini: 13.360000 - 6
+Region.size: 42
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 17 0 0 0 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 15 1 0 8 0 0 1 
+
+minGini: 8.361111 - 4
+Region.size: 25
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 13 1 0 1 0 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 0 2 0 0 7 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 0 0 
+
+minGini: 1.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 2.000000 - 0
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 1 0 1 0 0 1 
+
+minGini: 1.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 1 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 25.764705 - 4
+Region.size: 68
+LeftChild.size: 51
+LeftChild.ClassCounts: 6 0 1 2 4 2 1 35 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 0 0 0 17 0 0 
+
+minGini: 21.493506 - 5
+Region.size: 51
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 0 0 0 0 0 0 2 
+RightChild.size: 44
+RightChild.ClassCounts: 1 0 1 2 4 2 1 33 
+
+minGini: 14.900000 - 0
+Region.size: 44
+LeftChild.size: 40
+LeftChild.ClassCounts: 1 0 0 0 3 2 1 33 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 1 2 1 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 1 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 9.157894 - 4
+Region.size: 40
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 38
+RightChild.ClassCounts: 1 0 0 0 1 2 1 33 
+
+minGini: 5.771428 - 1
+Region.size: 38
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 0 0 1 0 1 0 
+RightChild.size: 35
+RightChild.ClassCounts: 0 0 0 0 0 2 0 33 
+
+minGini: 1.333333 - 1
+Region.size: 35
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 32 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 2 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 1.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 1 0 1 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 0 0 0 0 0 0 2 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 71.003367 - 4
+Region.size: 195
+LeftChild.size: 162
+LeftChild.ClassCounts: 128 32 0 0 0 0 0 2 
+RightChild.size: 33
+RightChild.ClassCounts: 6 22 0 0 0 5 0 0 
+
+minGini: 9.428571 - 1
+Region.size: 33
+LeftChild.size: 28
+LeftChild.ClassCounts: 6 22 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 5 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 28
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 22 0 0 0 0 0 0 
+
+minGini: 39.660000 - 1
+Region.size: 162
+LeftChild.size: 150
+LeftChild.ClassCounts: 128 21 0 0 0 0 0 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 11 0 0 0 0 0 1 
+
+minGini: 1.600000 - 6
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 16.934306 - 6
+Region.size: 150
+LeftChild.size: 137
+LeftChild.ClassCounts: 128 8 0 0 0 0 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 0 0 0 0 0 0 
+
+minGini: 13.105494 - 6
+Region.size: 137
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 0 0 0 0 0 0 
+RightChild.size: 130
+RightChild.ClassCounts: 125 4 0 0 0 0 0 1 
+
+minGini: 8.796875 - 0
+Region.size: 130
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 0 0 
+RightChild.size: 128
+RightChild.ClassCounts: 124 3 0 0 0 0 0 1 
+
+minGini: 3.952380 - 5
+Region.size: 128
+LeftChild.size: 126
+LeftChild.ClassCounts: 124 1 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 3.483606 - 0
+Region.size: 126
+LeftChild.size: 122
+LeftChild.ClassCounts: 121 1 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 1.818181 - 5
+Region.size: 122
+LeftChild.size: 111
+LeftChild.ClassCounts: 111 0 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 0 0 0 0 0 0 
+
+minGini: 1.500000 - 5
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 0 0 0 0 0 0 
+
+minGini: 1.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+
+
+Tree Number: 15 finished.
+
+minGini: 172.931777 - 5
+Region.size: 336
+LeftChild.size: 226
+LeftChild.ClassCounts: 136 3 4 0 1 21 3 58 
+RightChild.size: 110
+RightChild.ClassCounts: 0 81 0 1 22 2 0 4 
+
+minGini: 42.611111 - 4
+Region.size: 110
+LeftChild.size: 108
+LeftChild.ClassCounts: 0 81 0 1 22 0 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 28.330959 - 0
+Region.size: 108
+LeftChild.size: 77
+LeftChild.ClassCounts: 0 71 0 1 4 0 0 1 
+RightChild.size: 31
+RightChild.ClassCounts: 0 10 0 0 18 0 0 3 
+
+minGini: 13.333333 - 6
+Region.size: 31
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 6 0 0 18 0 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 11.290909 - 0
+Region.size: 27
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 2 0 0 1 0 0 2 
+RightChild.size: 22
+RightChild.ClassCounts: 0 4 0 0 17 0 0 1 
+
+minGini: 4.541666 - 1
+Region.size: 22
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 4 0 0 2 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 0 0 0 15 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 15
+RightChild.ClassCounts: 0 0 0 0 15 0 0 0 
+
+minGini: 1.600000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 10.843454 - 1
+Region.size: 77
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 33 0 1 4 0 0 0 
+RightChild.size: 39
+RightChild.ClassCounts: 0 38 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 39
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 38
+RightChild.ClassCounts: 0 38 0 0 0 0 0 0 
+
+minGini: 8.173913 - 4
+Region.size: 38
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 0 0 0 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 18 0 1 4 0 0 0 
+
+minGini: 3.394736 - 0
+Region.size: 23
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 18 0 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 1 3 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 1.600000 - 4
+Region.size: 19
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 72.750549 - 1
+Region.size: 226
+LeftChild.size: 156
+LeftChild.ClassCounts: 133 3 4 0 1 3 3 9 
+RightChild.size: 70
+RightChild.ClassCounts: 3 0 0 0 0 18 0 49 
+
+minGini: 26.742424 - 5
+Region.size: 70
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 0 0 0 0 1 0 0 
+RightChild.size: 66
+RightChild.ClassCounts: 0 0 0 0 0 17 0 49 
+
+minGini: 22.787878 - 0
+Region.size: 66
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 0 0 0 0 4 0 29 
+RightChild.size: 33
+RightChild.ClassCounts: 0 0 0 0 0 13 0 20 
+
+minGini: 1.857142 - 4
+Region.size: 33
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 19 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 0 13 0 1 
+
+minGini: 1.333333 - 4
+Region.size: 14
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 0 0 0 0 0 11 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 33
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 29 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 26.839034 - 0
+Region.size: 156
+LeftChild.size: 142
+LeftChild.ClassCounts: 133 3 0 0 1 2 0 3 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 4 0 0 1 3 6 
+
+minGini: 4.750000 - 6
+Region.size: 14
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 4 0 0 1 3 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 0 0 6 
+
+minGini: 1.500000 - 3
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 1 3 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 0 
+
+minGini: 15.390070 - 4
+Region.size: 142
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 141
+RightChild.ClassCounts: 133 3 0 0 0 2 0 3 
+
+minGini: 12.942028 - 5
+Region.size: 141
+LeftChild.size: 138
+LeftChild.ClassCounts: 132 3 0 0 0 0 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 1 0 0 0 0 2 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 10.889203 - 1
+Region.size: 138
+LeftChild.size: 113
+LeftChild.ClassCounts: 111 0 0 0 0 0 0 2 
+RightChild.size: 25
+RightChild.ClassCounts: 21 3 0 0 0 0 0 1 
+
+minGini: 5.416666 - 0
+Region.size: 25
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 21 2 0 0 0 0 0 1 
+
+minGini: 4.444444 - 4
+Region.size: 24
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 0 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 6 2 0 0 0 0 0 1 
+
+minGini: 1.333333 - 4
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 3.840000 - 0
+Region.size: 113
+LeftChild.size: 50
+LeftChild.ClassCounts: 48 0 0 0 0 0 0 2 
+RightChild.size: 63
+RightChild.ClassCounts: 63 0 0 0 0 0 0 0 
+
+minGini: 3.555555 - 0
+Region.size: 50
+LeftChild.size: 45
+LeftChild.ClassCounts: 44 0 0 0 0 0 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 4 0 0 0 0 0 0 1 
+
+minGini: 1.000000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 1.818181 - 6
+Region.size: 45
+LeftChild.size: 34
+LeftChild.ClassCounts: 34 0 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 10 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 16 finished.
+
+minGini: 175.708333 - 6
+Region.size: 336
+LeftChild.size: 240
+LeftChild.ClassCounts: 153 12 0 1 1 20 7 46 
+RightChild.size: 96
+RightChild.ClassCounts: 0 64 1 1 29 0 0 1 
+
+minGini: 40.750000 - 1
+Region.size: 96
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 15 1 0 16 0 0 0 
+RightChild.size: 64
+RightChild.ClassCounts: 0 49 0 1 13 0 0 1 
+
+minGini: 22.095118 - 6
+Region.size: 64
+LeftChild.size: 47
+LeftChild.ClassCounts: 0 33 0 1 13 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 16 0 0 0 0 0 1 
+
+minGini: 1.333333 - 4
+Region.size: 17
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 1 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 17.266666 - 5
+Region.size: 47
+LeftChild.size: 42
+LeftChild.ClassCounts: 0 32 0 1 9 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 0 0 4 0 0 0 
+
+minGini: 1.500000 - 6
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 0 3 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 14.190476 - 4
+Region.size: 42
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 13 0 1 7 0 0 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 19 0 0 2 0 0 0 
+
+minGini: 2.857142 - 6
+Region.size: 21
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 5 0 0 2 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 7.666666 - 4
+Region.size: 21
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 13 0 1 4 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 5.125000 - 6
+Region.size: 18
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 13 0 1 2 0 0 0 
+
+minGini: 1.857142 - 0
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 13 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 1.500000 - 0
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 0 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 9.181818 - 0
+Region.size: 32
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 0 0 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 5 1 0 16 0 0 0 
+
+minGini: 7.619047 - 2
+Region.size: 22
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 5 0 0 16 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 6.400000 - 5
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 4 0 0 16 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 5.714285 - 6
+Region.size: 20
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 4 0 0 10 0 0 0 
+
+minGini: 1.818181 - 6
+Region.size: 14
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 1 0 0 10 0 0 0 
+
+minGini: 1.500000 - 6
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 7 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 0 3 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 108.383928 - 5
+Region.size: 240
+LeftChild.size: 128
+LeftChild.ClassCounts: 114 0 0 0 0 4 0 10 
+RightChild.size: 112
+RightChild.ClassCounts: 39 12 0 1 1 16 7 36 
+
+minGini: 61.420963 - 6
+Region.size: 112
+LeftChild.size: 69
+LeftChild.ClassCounts: 3 11 0 1 1 15 7 31 
+RightChild.size: 43
+RightChild.ClassCounts: 36 1 0 0 0 1 0 5 
+
+minGini: 10.523809 - 2
+Region.size: 43
+LeftChild.size: 42
+LeftChild.ClassCounts: 36 1 0 0 0 0 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 10.138888 - 5
+Region.size: 42
+LeftChild.size: 18
+LeftChild.ClassCounts: 17 0 0 0 0 0 0 1 
+RightChild.size: 24
+RightChild.ClassCounts: 19 1 0 0 0 0 0 4 
+
+minGini: 1.900000 - 0
+Region.size: 24
+LeftChild.size: 20
+LeftChild.ClassCounts: 19 1 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 0 4 
+
+minGini: 1.500000 - 6
+Region.size: 20
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 0 0 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 0 0 0 0 0 0 
+
+minGini: 1.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 1.818181 - 6
+Region.size: 18
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 10 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 40.741935 - 2
+Region.size: 69
+LeftChild.size: 62
+LeftChild.ClassCounts: 3 11 0 1 1 15 0 31 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 0 7 0 
+
+minGini: 25.208333 - 4
+Region.size: 62
+LeftChild.size: 48
+LeftChild.ClassCounts: 3 11 0 1 1 1 0 31 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 0 14 0 0 
+
+minGini: 16.344537 - 0
+Region.size: 48
+LeftChild.size: 14
+LeftChild.ClassCounts: 3 9 0 0 0 0 0 2 
+RightChild.size: 34
+RightChild.ClassCounts: 0 2 0 1 1 1 0 29 
+
+minGini: 5.139784 - 4
+Region.size: 34
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 1 0 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 0 0 0 1 0 1 0 29 
+
+minGini: 1.933333 - 1
+Region.size: 31
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 0 0 1 0 0 0 29 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 30
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 29 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 4.571428 - 4
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 3 2 0 0 0 0 0 2 
+
+minGini: 2.000000 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 10.699665 - 1
+Region.size: 128
+LeftChild.size: 115
+LeftChild.ClassCounts: 113 0 0 0 0 0 0 2 
+RightChild.size: 13
+RightChild.ClassCounts: 1 0 0 0 0 4 0 8 
+
+minGini: 4.380952 - 6
+Region.size: 13
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 4 0 2 
+RightChild.size: 7
+RightChild.ClassCounts: 1 0 0 0 0 0 0 6 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 0 0 6 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 4 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 3.859649 - 1
+Region.size: 115
+LeftChild.size: 57
+LeftChild.ClassCounts: 55 0 0 0 0 0 0 2 
+RightChild.size: 58
+RightChild.ClassCounts: 58 0 0 0 0 0 0 0 
+
+minGini: 2.666666 - 1
+Region.size: 57
+LeftChild.size: 51
+LeftChild.ClassCounts: 51 0 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 4 0 0 0 0 0 0 2 
+
+minGini: 1.333333 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+
+
+Tree Number: 17 finished.
+
+minGini: 197.378168 - 0
+Region.size: 336
+LeftChild.size: 218
+LeftChild.ClassCounts: 135 70 0 0 2 2 0 9 
+RightChild.size: 118
+RightChild.ClassCounts: 5 13 3 1 31 15 1 49 
+
+minGini: 67.807125 - 4
+Region.size: 118
+LeftChild.size: 44
+LeftChild.ClassCounts: 2 0 2 0 2 0 1 37 
+RightChild.size: 74
+RightChild.ClassCounts: 3 13 1 1 29 15 0 12 
+
+minGini: 38.262565 - 6
+Region.size: 74
+LeftChild.size: 31
+LeftChild.ClassCounts: 3 0 0 1 0 15 0 12 
+RightChild.size: 43
+RightChild.ClassCounts: 0 13 1 0 29 0 0 0 
+
+minGini: 15.805429 - 0
+Region.size: 43
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 12 1 0 13 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 1 0 0 16 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 17
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 0 2 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 14 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 11.363636 - 1
+Region.size: 26
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 8 1 0 13 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 9.700000 - 5
+Region.size: 22
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 6 1 0 13 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 8.606060 - 0
+Region.size: 20
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 2 0 0 9 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 4 1 0 4 0 0 0 
+
+minGini: 4.000000 - 1
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 4 1 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 2.666666 - 2
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 4 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 1.600000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 1 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.800000 - 1
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 1 0 0 9 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 9 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 7.882352 - 4
+Region.size: 31
+LeftChild.size: 17
+LeftChild.ClassCounts: 3 0 0 1 0 1 0 12 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 0 14 0 0 
+
+minGini: 3.571428 - 5
+Region.size: 17
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 1 0 1 0 12 
+
+minGini: 1.846153 - 1
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 0 0 1 0 0 0 12 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 1.500000 - 5
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 9 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 1 0 0 0 3 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 7.088803 - 1
+Region.size: 44
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 0 2 0 2 0 0 1 
+RightChild.size: 37
+RightChild.ClassCounts: 0 0 0 0 0 0 1 36 
+
+minGini: 0.000000 - 0
+Region.size: 37
+LeftChild.size: 36
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 36 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 0 
+
+minGini: 3.200000 - 0
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 2 0 2 0 0 1 
+
+minGini: 1.333333 - 3
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 99.547209 - 1
+Region.size: 218
+LeftChild.size: 199
+LeftChild.ClassCounts: 135 56 0 0 0 0 0 8 
+RightChild.size: 19
+RightChild.ClassCounts: 0 14 0 0 2 2 0 1 
+
+minGini: 3.866666 - 4
+Region.size: 19
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 14 0 0 0 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 2 2 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 15.104895 - 5
+Region.size: 199
+LeftChild.size: 143
+LeftChild.ClassCounts: 135 0 0 0 0 0 0 8 
+RightChild.size: 56
+RightChild.ClassCounts: 0 56 0 0 0 0 0 0 
+
+minGini: 13.530582 - 4
+Region.size: 143
+LeftChild.size: 103
+LeftChild.ClassCounts: 102 0 0 0 0 0 0 1 
+RightChild.size: 40
+RightChild.ClassCounts: 33 0 0 0 0 0 0 7 
+
+minGini: 9.545454 - 1
+Region.size: 40
+LeftChild.size: 22
+LeftChild.ClassCounts: 15 0 0 0 0 0 0 7 
+RightChild.size: 18
+RightChild.ClassCounts: 18 0 0 0 0 0 0 0 
+
+minGini: 3.111111 - 1
+Region.size: 22
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 0 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 2 0 0 0 0 0 0 7 
+
+minGini: 0.000000 - 0
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 0 0 7 
+
+minGini: 1.714285 - 0
+Region.size: 103
+LeftChild.size: 96
+LeftChild.ClassCounts: 96 0 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 0 0 0 0 0 0 1 
+
+minGini: 1.333333 - 0
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+
+
+Tree Number: 18 finished.
+
+minGini: 193.809689 - 0
+Region.size: 336
+LeftChild.size: 175
+LeftChild.ClassCounts: 133 32 0 0 2 1 0 7 
+RightChild.size: 161
+RightChild.ClassCounts: 10 33 0 2 35 21 8 52 
+
+minGini: 97.706729 - 5
+Region.size: 161
+LeftChild.size: 90
+LeftChild.ClassCounts: 10 0 0 1 2 21 8 48 
+RightChild.size: 71
+RightChild.ClassCounts: 0 33 0 1 33 0 0 4 
+
+minGini: 38.866987 - 4
+Region.size: 71
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 16 0 1 11 0 0 4 
+RightChild.size: 39
+RightChild.ClassCounts: 0 17 0 0 22 0 0 0 
+
+minGini: 14.666666 - 6
+Region.size: 39
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 0 0 
+RightChild.size: 33
+RightChild.ClassCounts: 0 11 0 0 22 0 0 0 
+
+minGini: 11.733333 - 5
+Region.size: 33
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 0 8 0 0 22 0 0 0 
+
+minGini: 6.857142 - 0
+Region.size: 30
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 8 0 0 6 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 0 0 0 16 0 0 0 
+
+minGini: 3.200000 - 6
+Region.size: 14
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 8 0 0 2 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 0 0 0 0 0 0 
+
+minGini: 13.939393 - 0
+Region.size: 32
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 14 0 1 2 0 0 4 
+RightChild.size: 11
+RightChild.ClassCounts: 0 2 0 0 9 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 0 8 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 8.210526 - 0
+Region.size: 21
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 14 0 1 2 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 6.909090 - 0
+Region.size: 19
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 6 0 1 2 0 0 2 
+
+minGini: 5.750000 - 5
+Region.size: 11
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 3 0 1 2 0 0 2 
+
+minGini: 4.500000 - 1
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 2 0 0 2 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 1 0 0 0 2 
+
+minGini: 1.333333 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 0 0 0 2 
+
+minGini: 1.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 48.575000 - 2
+Region.size: 90
+LeftChild.size: 80
+LeftChild.ClassCounts: 10 0 0 1 2 19 0 48 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 0 0 0 2 8 0 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 0 8 0 
+
+minGini: 24.698412 - 4
+Region.size: 80
+LeftChild.size: 63
+LeftChild.ClassCounts: 10 0 0 1 2 2 0 48 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 0 0 0 17 0 0 
+
+minGini: 10.265306 - 1
+Region.size: 63
+LeftChild.size: 14
+LeftChild.ClassCounts: 10 0 0 1 2 0 0 1 
+RightChild.size: 49
+RightChild.ClassCounts: 0 0 0 0 0 2 0 47 
+
+minGini: 3.200000 - 4
+Region.size: 49
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 39 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 0 0 0 2 0 8 
+
+minGini: 1.777777 - 5
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 0 1 0 8 
+
+minGini: 1.500000 - 4
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 3 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 0 0 5 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 3.818181 - 0
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 10 0 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 1 1 0 0 1 
+
+minGini: 1.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 1 0 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 4
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 0 0 0 0 0 0 
+
+minGini: 20.827998 - 5
+Region.size: 175
+LeftChild.size: 142
+LeftChild.ClassCounts: 133 1 0 0 0 1 0 7 
+RightChild.size: 33
+RightChild.ClassCounts: 0 31 0 0 2 0 0 0 
+
+minGini: 3.529411 - 6
+Region.size: 33
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 15 0 0 2 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 16 0 0 0 0 0 0 
+
+minGini: 2.400000 - 4
+Region.size: 17
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 3 0 0 2 0 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 12.887290 - 1
+Region.size: 142
+LeftChild.size: 139
+LeftChild.ClassCounts: 133 1 0 0 0 0 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 1 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 10.931034 - 0
+Region.size: 139
+LeftChild.size: 58
+LeftChild.ClassCounts: 52 1 0 0 0 0 0 5 
+RightChild.size: 81
+RightChild.ClassCounts: 81 0 0 0 0 0 0 0 
+
+minGini: 10.355555 - 6
+Region.size: 58
+LeftChild.size: 40
+LeftChild.ClassCounts: 38 0 0 0 0 0 0 2 
+RightChild.size: 18
+RightChild.ClassCounts: 14 1 0 0 0 0 0 3 
+
+minGini: 5.550000 - 0
+Region.size: 18
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 5 0 0 0 0 0 0 3 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 40
+LeftChild.size: 38
+LeftChild.ClassCounts: 38 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+
+
+Tree Number: 19 finished.
+
+minGini: 202.579604 - 1
+Region.size: 336
+LeftChild.size: 254
+LeftChild.ClassCounts: 136 71 1 3 29 2 5 7 
+RightChild.size: 82
+RightChild.ClassCounts: 3 10 0 0 2 15 0 52 
+
+minGini: 35.741248 - 6
+Region.size: 82
+LeftChild.size: 73
+LeftChild.ClassCounts: 3 3 0 0 0 15 0 52 
+RightChild.size: 9
+RightChild.ClassCounts: 0 7 0 0 2 0 0 0 
+
+minGini: 1.750000 - 1
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 7 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 17.838709 - 4
+Region.size: 73
+LeftChild.size: 62
+LeftChild.ClassCounts: 3 3 0 0 0 4 0 52 
+RightChild.size: 11
+RightChild.ClassCounts: 0 0 0 0 0 11 0 0 
+
+minGini: 14.500000 - 0
+Region.size: 62
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 60
+RightChild.ClassCounts: 3 1 0 0 0 4 0 52 
+
+minGini: 12.785714 - 0
+Region.size: 60
+LeftChild.size: 28
+LeftChild.ClassCounts: 3 1 0 0 0 4 0 20 
+RightChild.size: 32
+RightChild.ClassCounts: 0 0 0 0 0 0 0 32 
+
+minGini: 9.708333 - 1
+Region.size: 28
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 15 
+RightChild.size: 12
+RightChild.ClassCounts: 3 0 0 0 0 4 0 5 
+
+minGini: 3.750000 - 4
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 5 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 0 0 5 
+
+minGini: 0.000000 - 4
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 0 0 0 0 0 0 15 
+
+minGini: 148.802785 - 1
+Region.size: 254
+LeftChild.size: 42
+LeftChild.ClassCounts: 37 2 0 0 3 0 0 0 
+RightChild.size: 212
+RightChild.ClassCounts: 99 69 1 3 26 2 5 7 
+
+minGini: 117.907894 - 0
+Region.size: 212
+LeftChild.size: 152
+LeftChild.ClassCounts: 95 54 0 0 1 0 0 2 
+RightChild.size: 60
+RightChild.ClassCounts: 4 15 1 3 25 2 5 5 
+
+minGini: 38.541666 - 5
+Region.size: 60
+LeftChild.size: 12
+LeftChild.ClassCounts: 4 0 0 0 0 2 4 2 
+RightChild.size: 48
+RightChild.ClassCounts: 0 15 1 3 25 0 1 3 
+
+minGini: 25.866666 - 1
+Region.size: 48
+LeftChild.size: 45
+LeftChild.ClassCounts: 0 15 1 3 25 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 20.194331 - 0
+Region.size: 45
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 13 1 3 8 0 1 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 2 0 0 17 0 0 0 
+
+minGini: 2.666666 - 1
+Region.size: 19
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 2 0 0 4 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 0 0 13 0 0 0 
+
+minGini: 2.000000 - 6
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 0 0 2 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 14.404761 - 0
+Region.size: 26
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 4 1 3 6 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 9 0 0 2 0 1 0 
+
+minGini: 3.272727 - 5
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 9 0 0 2 0 0 0 
+
+minGini: 2.400000 - 1
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 3 0 0 2 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 6.416666 - 1
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 1 0 5 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 4 0 3 1 0 0 0 
+
+minGini: 3.428571 - 6
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 4 0 3 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 2.400000 - 6
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 2 0 3 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 3 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 5 0 0 0 
+
+minGini: 5.000000 - 5
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 2 4 2 
+
+minGini: 2.666666 - 4
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 2 4 0 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 4 0 
+
+minGini: 9.660000 - 5
+Region.size: 152
+LeftChild.size: 100
+LeftChild.ClassCounts: 95 2 0 0 1 0 0 2 
+RightChild.size: 52
+RightChild.ClassCounts: 0 52 0 0 0 0 0 0 
+
+minGini: 9.105263 - 5
+Region.size: 100
+LeftChild.size: 62
+LeftChild.ClassCounts: 62 0 0 0 0 0 0 0 
+RightChild.size: 38
+RightChild.ClassCounts: 33 2 0 0 1 0 0 2 
+
+minGini: 5.104761 - 4
+Region.size: 38
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 1 0 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 33 0 0 0 0 0 0 2 
+
+minGini: 3.000000 - 5
+Region.size: 35
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 0 0 0 0 0 0 2 
+RightChild.size: 27
+RightChild.ClassCounts: 27 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 2.400000 - 0
+Region.size: 42
+LeftChild.size: 37
+LeftChild.ClassCounts: 37 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 2 0 0 3 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+
+
+Tree Number: 20 finished.
+
+minGini: 186.322811 - 5
+Region.size: 336
+LeftChild.size: 218
+LeftChild.ClassCounts: 132 1 0 0 1 26 13 45 
+RightChild.size: 118
+RightChild.ClassCounts: 0 70 0 1 42 1 1 3 
+
+minGini: 47.236363 - 0
+Region.size: 118
+LeftChild.size: 88
+LeftChild.ClassCounts: 0 64 0 1 18 1 1 3 
+RightChild.size: 30
+RightChild.ClassCounts: 0 6 0 0 24 0 0 0 
+
+minGini: 6.857142 - 6
+Region.size: 30
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 4 0 0 24 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 5.333333 - 0
+Region.size: 28
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 0 0 0 16 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 4 0 0 8 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 8 0 0 0 
+
+minGini: 33.742504 - 2
+Region.size: 88
+LeftChild.size: 81
+LeftChild.ClassCounts: 0 63 0 1 14 0 0 3 
+RightChild.size: 7
+RightChild.ClassCounts: 0 1 0 0 4 1 1 0 
+
+minGini: 2.000000 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 0 1 1 0 
+
+minGini: 1.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 27.424908 - 1
+Region.size: 81
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 27 0 0 12 0 0 0 
+RightChild.size: 42
+RightChild.ClassCounts: 0 36 0 1 2 0 0 3 
+
+minGini: 8.769230 - 1
+Region.size: 42
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 35 0 1 2 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 0 0 0 2 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 5.631578 - 6
+Region.size: 39
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 38
+RightChild.ClassCounts: 0 35 0 1 2 0 0 0 
+
+minGini: 5.264705 - 1
+Region.size: 38
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 3 0 1 0 0 0 0 
+RightChild.size: 34
+RightChild.ClassCounts: 0 32 0 0 2 0 0 0 
+
+minGini: 3.433333 - 4
+Region.size: 34
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 29 0 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.818181 - 4
+Region.size: 30
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 19 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 10 0 0 1 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 12.365079 - 1
+Region.size: 39
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 17 0 0 1 0 0 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 10 0 0 11 0 0 0 
+
+minGini: 5.866666 - 6
+Region.size: 21
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 4 0 0 11 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 0 0 
+
+minGini: 2.666666 - 4
+Region.size: 15
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 4 0 0 2 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 9 0 0 0 
+
+minGini: 1.600000 - 1
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 4 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 18
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 82.958758 - 1
+Region.size: 218
+LeftChild.size: 166
+LeftChild.ClassCounts: 132 1 0 0 1 7 13 12 
+RightChild.size: 52
+RightChild.ClassCounts: 0 0 0 0 0 19 0 33 
+
+minGini: 21.318181 - 1
+Region.size: 52
+LeftChild.size: 44
+LeftChild.ClassCounts: 0 0 0 0 0 13 0 31 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 6 0 2 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 6 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 14.374736 - 6
+Region.size: 44
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 0 0 0 0 12 0 13 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 0 0 0 1 0 18 
+
+minGini: 1.500000 - 5
+Region.size: 19
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 3 
+RightChild.size: 15
+RightChild.ClassCounts: 0 0 0 0 0 0 0 15 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 9.866666 - 1
+Region.size: 25
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 0 0 0 0 10 0 5 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 0 0 0 2 0 8 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 8 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 15
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 5 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 0 0 0 10 0 0 
+
+minGini: 36.327397 - 5
+Region.size: 166
+LeftChild.size: 146
+LeftChild.ClassCounts: 132 1 0 0 1 3 0 9 
+RightChild.size: 20
+RightChild.ClassCounts: 0 0 0 0 0 4 13 3 
+
+minGini: 7.666666 - 1
+Region.size: 20
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 18
+RightChild.ClassCounts: 0 0 0 0 0 4 13 1 
+
+minGini: 1.600000 - 2
+Region.size: 18
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 4 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 0 0 0 0 13 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 4 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 20.850889 - 0
+Region.size: 146
+LeftChild.size: 129
+LeftChild.ClassCounts: 124 1 0 0 0 0 0 4 
+RightChild.size: 17
+RightChild.ClassCounts: 8 0 0 0 1 3 0 5 
+
+minGini: 7.571428 - 4
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 8 0 0 0 1 0 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 0 0 
+
+minGini: 5.800000 - 4
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 4 0 0 0 1 0 0 5 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 0 0 
+
+minGini: 1.600000 - 4
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 0 0 0 1 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 0 0 5 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 8.980582 - 6
+Region.size: 129
+LeftChild.size: 103
+LeftChild.ClassCounts: 102 0 0 0 0 0 0 1 
+RightChild.size: 26
+RightChild.ClassCounts: 22 1 0 0 0 0 0 3 
+
+minGini: 3.409090 - 5
+Region.size: 26
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 3 
+RightChild.size: 22
+RightChild.ClassCounts: 21 1 0 0 0 0 0 0 
+
+minGini: 1.500000 - 0
+Region.size: 22
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 0 0 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 1.960784 - 5
+Region.size: 103
+LeftChild.size: 51
+LeftChild.ClassCounts: 50 0 0 0 0 0 0 1 
+RightChild.size: 52
+RightChild.ClassCounts: 52 0 0 0 0 0 0 0 
+
+minGini: 1.800000 - 6
+Region.size: 51
+LeftChild.size: 41
+LeftChild.ClassCounts: 41 0 0 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 9 0 0 0 0 0 0 1 
+
+minGini: 1.333333 - 1
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 21 finished.
+
+minGini: 182.767676 - 6
+Region.size: 336
+LeftChild.size: 237
+LeftChild.ClassCounts: 147 9 1 0 0 20 6 54 
+RightChild.size: 99
+RightChild.ClassCounts: 0 55 1 1 41 0 0 1 
+
+minGini: 32.568648 - 0
+Region.size: 99
+LeftChild.size: 74
+LeftChild.ClassCounts: 0 54 1 1 17 0 0 1 
+RightChild.size: 25
+RightChild.ClassCounts: 0 1 0 0 24 0 0 0 
+
+minGini: 1.750000 - 5
+Region.size: 25
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 1 0 0 7 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 0 0 17 0 0 0 
+
+minGini: 1.600000 - 1
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 0 0 4 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 25.842424 - 0
+Region.size: 74
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 29 0 0 1 0 0 0 
+RightChild.size: 44
+RightChild.ClassCounts: 0 25 1 1 16 0 0 1 
+
+minGini: 15.701863 - 4
+Region.size: 44
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 19 1 1 1 0 0 1 
+RightChild.size: 21
+RightChild.ClassCounts: 0 6 0 0 15 0 0 0 
+
+minGini: 7.500000 - 0
+Region.size: 21
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 6 0 0 10 0 0 0 
+
+minGini: 5.866666 - 0
+Region.size: 16
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 4 0 0 2 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 2 0 0 8 0 0 0 
+
+minGini: 1.777777 - 6
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 1 0 0 8 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 1.333333 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 0 2 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 5.454545 - 4
+Region.size: 23
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 22
+RightChild.ClassCounts: 0 19 1 1 1 0 0 0 
+
+minGini: 4.875000 - 5
+Region.size: 22
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 4 0 1 1 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 15 1 0 0 0 0 0 
+
+minGini: 1.000000 - 2
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 1 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 1.818181 - 4
+Region.size: 30
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 19 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 10 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 0 0 0 0 0 0 
+
+minGini: 75.606557 - 1
+Region.size: 237
+LeftChild.size: 176
+LeftChild.ClassCounts: 147 9 1 0 0 4 6 9 
+RightChild.size: 61
+RightChild.ClassCounts: 0 0 0 0 0 16 0 45 
+
+minGini: 3.829787 - 4
+Region.size: 61
+LeftChild.size: 47
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 45 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 0 14 0 0 
+
+minGini: 2.666666 - 5
+Region.size: 47
+LeftChild.size: 41
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 41 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 2 0 4 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 38.502564 - 0
+Region.size: 176
+LeftChild.size: 156
+LeftChild.ClassCounts: 144 7 0 0 0 0 0 5 
+RightChild.size: 20
+RightChild.ClassCounts: 3 2 1 0 0 4 6 4 
+
+minGini: 11.252747 - 2
+Region.size: 20
+LeftChild.size: 13
+LeftChild.ClassCounts: 3 2 0 0 0 4 0 4 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 1 0 0 0 6 0 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 0 6 0 
+
+minGini: 7.777777 - 5
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 3 0 0 0 0 4 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 0 0 0 0 0 2 
+
+minGini: 1.333333 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 0 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 2.400000 - 4
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 21.522257 - 0
+Region.size: 156
+LeftChild.size: 11
+LeftChild.ClassCounts: 8 3 0 0 0 0 0 0 
+RightChild.size: 145
+RightChild.ClassCounts: 136 4 0 0 0 0 0 5 
+
+minGini: 13.454545 - 5
+Region.size: 145
+LeftChild.size: 143
+LeftChild.ClassCounts: 136 2 0 0 0 0 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 12.573291 - 6
+Region.size: 143
+LeftChild.size: 115
+LeftChild.ClassCounts: 113 0 0 0 0 0 0 2 
+RightChild.size: 28
+RightChild.ClassCounts: 23 2 0 0 0 0 0 3 
+
+minGini: 6.052173 - 6
+Region.size: 28
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 3 
+RightChild.size: 23
+RightChild.ClassCounts: 21 2 0 0 0 0 0 0 
+
+minGini: 3.111111 - 4
+Region.size: 23
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 0 0 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 3.798951 - 1
+Region.size: 115
+LeftChild.size: 104
+LeftChild.ClassCounts: 103 0 0 0 0 0 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 10 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 0 0 0 0 0 0 
+
+minGini: 1.894736 - 4
+Region.size: 104
+LeftChild.size: 85
+LeftChild.ClassCounts: 85 0 0 0 0 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 18 0 0 0 0 0 0 1 
+
+minGini: 1.666666 - 5
+Region.size: 19
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 0 0 0 0 0 0 1 
+
+minGini: 1.333333 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 1.500000 - 4
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+
+
+Tree Number: 22 finished.
+
+minGini: 185.180147 - 5
+Region.size: 336
+LeftChild.size: 230
+LeftChild.ClassCounts: 141 5 2 4 1 22 4 51 
+RightChild.size: 106
+RightChild.ClassCounts: 0 62 2 1 39 0 0 2 
+
+minGini: 50.781229 - 5
+Region.size: 106
+LeftChild.size: 89
+LeftChild.ClassCounts: 0 46 2 1 38 0 0 2 
+RightChild.size: 17
+RightChild.ClassCounts: 0 16 0 0 1 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 22.839231 - 0
+Region.size: 89
+LeftChild.size: 46
+LeftChild.ClassCounts: 0 42 0 0 4 0 0 0 
+RightChild.size: 43
+RightChild.ClassCounts: 0 4 2 1 34 0 0 2 
+
+minGini: 12.292682 - 2
+Region.size: 43
+LeftChild.size: 41
+LeftChild.ClassCounts: 0 4 0 1 34 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 0 
+
+minGini: 8.923076 - 4
+Region.size: 41
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 39
+RightChild.ClassCounts: 0 4 0 1 34 0 0 0 
+
+minGini: 7.461538 - 5
+Region.size: 39
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 4 0 0 9 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 0 0 1 25 0 0 0 
+
+minGini: 1.600000 - 1
+Region.size: 26
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 0 0 0 21 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 1 4 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 1 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 3.272727 - 0
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 2 0 0 9 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 2.000000 - 1
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 7 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 0 0 2 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 6.441176 - 0
+Region.size: 46
+LeftChild.size: 34
+LeftChild.ClassCounts: 0 33 0 0 1 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 9 0 0 3 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 34
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 33 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 97.773442 - 5
+Region.size: 230
+LeftChild.size: 116
+LeftChild.ClassCounts: 107 0 0 0 0 6 0 3 
+RightChild.size: 114
+RightChild.ClassCounts: 34 5 2 4 1 16 4 48 
+
+minGini: 57.286445 - 0
+Region.size: 114
+LeftChild.size: 46
+LeftChild.ClassCounts: 34 5 0 0 1 0 0 6 
+RightChild.size: 68
+RightChild.ClassCounts: 0 0 2 4 0 16 4 42 
+
+minGini: 17.384615 - 4
+Region.size: 68
+LeftChild.size: 52
+LeftChild.ClassCounts: 0 0 2 4 0 0 4 42 
+RightChild.size: 16
+RightChild.ClassCounts: 0 0 0 0 0 16 0 0 
+
+minGini: 9.951219 - 1
+Region.size: 52
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 2 4 0 0 3 2 
+RightChild.size: 41
+RightChild.ClassCounts: 0 0 0 0 0 0 1 40 
+
+minGini: 1.333333 - 1
+Region.size: 41
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 2 
+RightChild.size: 38
+RightChild.ClassCounts: 0 0 0 0 0 0 0 38 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 4.571428 - 0
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 2 0 0 0 3 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 4 0 0 0 0 
+
+minGini: 2.000000 - 4
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 13.502439 - 4
+Region.size: 46
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 4 0 0 1 0 0 0 
+RightChild.size: 41
+RightChild.ClassCounts: 34 1 0 0 0 0 0 6 
+
+minGini: 9.420000 - 4
+Region.size: 41
+LeftChild.size: 25
+LeftChild.ClassCounts: 24 1 0 0 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 10 0 0 0 0 0 0 6 
+
+minGini: 4.000000 - 4
+Region.size: 16
+LeftChild.size: 9
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 6 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 0 0 0 0 0 0 
+
+minGini: 3.000000 - 5
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 6
+RightChild.ClassCounts: 3 0 0 0 0 0 0 3 
+
+minGini: 2.400000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 2 0 0 0 0 0 0 3 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 1.714285 - 1
+Region.size: 25
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 0 0 0 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 8.526406 - 1
+Region.size: 116
+LeftChild.size: 105
+LeftChild.ClassCounts: 104 0 0 0 0 0 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 3 0 0 0 0 6 0 2 
+
+minGini: 4.444444 - 5
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 0 0 0 0 6 0 2 
+
+minGini: 1.714285 - 0
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 0 0 0 0 6 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 1.000000 - 0
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 5 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 1 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 1.818181 - 0
+Region.size: 105
+LeftChild.size: 94
+LeftChild.ClassCounts: 94 0 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 10 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+
+
+Tree Number: 23 finished.
+
+minGini: 171.482142 - 5
+Region.size: 336
+LeftChild.size: 224
+LeftChild.ClassCounts: 152 2 0 0 1 17 1 51 
+RightChild.size: 112
+RightChild.ClassCounts: 0 65 3 1 34 5 1 3 
+
+minGini: 47.425760 - 0
+Region.size: 112
+LeftChild.size: 86
+LeftChild.ClassCounts: 0 63 3 1 14 2 1 2 
+RightChild.size: 26
+RightChild.ClassCounts: 0 2 0 0 20 3 0 1 
+
+minGini: 5.136363 - 6
+Region.size: 26
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 3 0 1 
+RightChild.size: 22
+RightChild.ClassCounts: 0 2 0 0 20 0 0 0 
+
+minGini: 1.904761 - 5
+Region.size: 22
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 1 0 0 20 0 0 0 
+
+minGini: 1.600000 - 1
+Region.size: 21
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 0 0 4 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 0 0 0 16 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 0 0 
+
+minGini: 34.008032 - 1
+Region.size: 86
+LeftChild.size: 83
+LeftChild.ClassCounts: 0 63 3 1 14 0 1 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 2 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 30.629847 - 5
+Region.size: 83
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 24 0 0 11 0 1 1 
+RightChild.size: 46
+RightChild.ClassCounts: 0 39 3 1 3 0 0 0 
+
+minGini: 11.674603 - 4
+Region.size: 46
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 13 3 0 2 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 0 26 0 1 1 0 0 0 
+
+minGini: 3.647058 - 1
+Region.size: 28
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 15 0 1 1 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 0 0 0 0 0 0 
+
+minGini: 1.875000 - 1
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 15 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 1.600000 - 0
+Region.size: 16
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 3.466666 - 0
+Region.size: 18
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 13 0 0 2 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 0 
+
+minGini: 2.000000 - 5
+Region.size: 15
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 2 0 0 2 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 12.239766 - 6
+Region.size: 37
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 17 0 0 0 0 1 1 
+RightChild.size: 18
+RightChild.ClassCounts: 0 7 0 0 11 0 0 0 
+
+minGini: 3.384615 - 1
+Region.size: 18
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 2 0 0 11 0 0 0 
+
+minGini: 2.400000 - 4
+Region.size: 13
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 0 8 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 2 0 0 3 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 1 
+RightChild.size: 17
+RightChild.ClassCounts: 0 17 0 0 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 0 
+
+minGini: 56.847401 - 1
+Region.size: 224
+LeftChild.size: 171
+LeftChild.ClassCounts: 151 2 0 0 1 5 1 11 
+RightChild.size: 53
+RightChild.ClassCounts: 1 0 0 0 0 12 0 40 
+
+minGini: 18.884615 - 6
+Region.size: 53
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 52
+RightChild.ClassCounts: 1 0 0 0 0 11 0 40 
+
+minGini: 15.436692 - 5
+Region.size: 52
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 0 0 0 0 5 0 3 
+RightChild.size: 43
+RightChild.ClassCounts: 0 0 0 0 0 6 0 37 
+
+minGini: 0.000000 - 4
+Region.size: 43
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 37 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 6 0 0 
+
+minGini: 4.285714 - 6
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 0 0 0 0 3 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 1.500000 - 0
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 3 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 0 0 0 0 0 0 3 
+
+minGini: 1.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 23.903448 - 0
+Region.size: 171
+LeftChild.size: 145
+LeftChild.ClassCounts: 142 2 0 0 0 0 0 1 
+RightChild.size: 26
+RightChild.ClassCounts: 9 0 0 0 1 5 1 10 
+
+minGini: 15.045454 - 6
+Region.size: 26
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 3 1 0 
+RightChild.size: 22
+RightChild.ClassCounts: 9 0 0 0 1 2 0 10 
+
+minGini: 9.180952 - 4
+Region.size: 22
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 0 0 0 1 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 3 0 0 0 0 2 0 10 
+
+minGini: 3.818181 - 4
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 10 
+RightChild.size: 4
+RightChild.ClassCounts: 2 0 0 0 0 2 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 0 0 0 0 0 10 
+
+minGini: 1.500000 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 0 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 3 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 0 
+
+minGini: 4.652278 - 0
+Region.size: 145
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 0 0 0 0 0 0 
+RightChild.size: 139
+RightChild.ClassCounts: 138 0 0 0 0 0 0 1 
+
+minGini: 1.913043 - 6
+Region.size: 139
+LeftChild.size: 116
+LeftChild.ClassCounts: 116 0 0 0 0 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 22 0 0 0 0 0 0 1 
+
+minGini: 1.000000 - 6
+Region.size: 23
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 1 
+RightChild.size: 21
+RightChild.ClassCounts: 21 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 24 finished.
+
+minGini: 191.574410 - 5
+Region.size: 336
+LeftChild.size: 217
+LeftChild.ClassCounts: 130 5 2 1 0 22 3 54 
+RightChild.size: 119
+RightChild.ClassCounts: 0 63 1 0 45 2 3 5 
+
+minGini: 64.713043 - 1
+Region.size: 119
+LeftChild.size: 115
+LeftChild.ClassCounts: 0 63 1 0 45 0 3 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 2 0 2 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 56.515567 - 6
+Region.size: 115
+LeftChild.size: 91
+LeftChild.ClassCounts: 0 42 0 0 43 0 3 3 
+RightChild.size: 24
+RightChild.ClassCounts: 0 21 1 0 2 0 0 0 
+
+minGini: 1.909090 - 0
+Region.size: 24
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 21 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 22
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 21 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 46.428428 - 6
+Region.size: 91
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 22 0 0 9 0 3 3 
+RightChild.size: 54
+RightChild.ClassCounts: 0 20 0 0 34 0 0 0 
+
+minGini: 20.906593 - 6
+Region.size: 54
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 5 0 0 23 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 15 0 0 11 0 0 0 
+
+minGini: 11.250000 - 1
+Region.size: 26
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 0 15 0 0 9 0 0 0 
+
+minGini: 8.475524 - 4
+Region.size: 24
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 11 0 0 2 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 4 0 0 7 0 0 0 
+
+minGini: 1.600000 - 6
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 4 0 0 1 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 6 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 5.307692 - 0
+Region.size: 28
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 3 0 0 23 0 0 0 
+
+minGini: 4.751879 - 4
+Region.size: 26
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 2 0 0 5 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 1 0 0 18 0 0 0 
+
+minGini: 1.714285 - 4
+Region.size: 19
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 0 0 12 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 1 0 0 6 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 1 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 5 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.666666 - 6
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 1 0 0 5 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 17.117647 - 2
+Region.size: 37
+LeftChild.size: 34
+LeftChild.ClassCounts: 0 22 0 0 9 0 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 0 
+
+minGini: 14.903846 - 5
+Region.size: 34
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 3 0 0 5 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 19 0 0 4 0 0 3 
+
+minGini: 8.250000 - 6
+Region.size: 26
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 24
+RightChild.ClassCounts: 0 19 0 0 4 0 0 1 
+
+minGini: 3.000000 - 0
+Region.size: 24
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 1 0 0 4 0 0 1 
+
+minGini: 1.600000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 0 0 4 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 88.877551 - 5
+Region.size: 217
+LeftChild.size: 98
+LeftChild.ClassCounts: 94 0 0 0 0 3 0 1 
+RightChild.size: 119
+RightChild.ClassCounts: 36 5 2 1 0 19 3 53 
+
+minGini: 56.304927 - 1
+Region.size: 119
+LeftChild.size: 50
+LeftChild.ClassCounts: 35 5 2 1 0 1 0 6 
+RightChild.size: 69
+RightChild.ClassCounts: 1 0 0 0 0 18 3 47 
+
+minGini: 27.461538 - 6
+Region.size: 69
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 0 0 0 0 12 3 11 
+RightChild.size: 43
+RightChild.ClassCounts: 1 0 0 0 0 6 0 36 
+
+minGini: 9.180180 - 0
+Region.size: 43
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 0 0 0 0 3 0 2 
+RightChild.size: 37
+RightChild.ClassCounts: 0 0 0 0 0 3 0 34 
+
+minGini: 0.000000 - 4
+Region.size: 37
+LeftChild.size: 34
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 34 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 10.739393 - 1
+Region.size: 26
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 0 0 0 0 10 3 2 
+RightChild.size: 11
+RightChild.ClassCounts: 0 0 0 0 0 2 0 9 
+
+minGini: 1.800000 - 6
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 9 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 9 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 3.333333 - 2
+Region.size: 15
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 0 0 0 10 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 0 
+
+minGini: 1.333333 - 1
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 2 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 0 9 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 19.030303 - 0
+Region.size: 50
+LeftChild.size: 44
+LeftChild.ClassCounts: 35 5 0 0 0 1 0 3 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 2 1 0 0 0 3 
+
+minGini: 1.333333 - 1
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 2 1 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 11.939393 - 1
+Region.size: 44
+LeftChild.size: 33
+LeftChild.ClassCounts: 30 0 0 0 0 1 0 2 
+RightChild.size: 11
+RightChild.ClassCounts: 5 5 0 0 0 0 0 1 
+
+minGini: 1.666666 - 6
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 0 0 0 0 0 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 3.750000 - 0
+Region.size: 33
+LeftChild.size: 32
+LeftChild.ClassCounts: 30 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 3.272727 - 5
+Region.size: 32
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 0 0 0 0 0 0 2 
+RightChild.size: 21
+RightChild.ClassCounts: 21 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 4.978260 - 0
+Region.size: 98
+LeftChild.size: 92
+LeftChild.ClassCounts: 91 0 0 0 0 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 3 0 0 0 0 3 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 3 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 1.945945 - 0
+Region.size: 92
+LeftChild.size: 37
+LeftChild.ClassCounts: 36 0 0 0 0 0 0 1 
+RightChild.size: 55
+RightChild.ClassCounts: 55 0 0 0 0 0 0 0 
+
+minGini: 1.857142 - 4
+Region.size: 37
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 0 0 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 13 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+
+
+Tree Number: 25 finished.
+
+minGini: 210.421621 - 0
+Region.size: 336
+LeftChild.size: 185
+LeftChild.ClassCounts: 119 54 0 0 5 4 0 3 
+RightChild.size: 151
+RightChild.ClassCounts: 5 24 2 2 37 19 12 50 
+
+minGini: 91.696126 - 1
+Region.size: 151
+LeftChild.size: 80
+LeftChild.ClassCounts: 4 20 2 2 37 2 10 3 
+RightChild.size: 71
+RightChild.ClassCounts: 1 4 0 0 0 17 2 47 
+
+minGini: 12.196190 - 4
+Region.size: 71
+LeftChild.size: 50
+LeftChild.ClassCounts: 1 0 0 0 0 0 2 47 
+RightChild.size: 21
+RightChild.ClassCounts: 0 4 0 0 0 17 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 21
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 0 0 0 0 17 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 1.958333 - 2
+Region.size: 50
+LeftChild.size: 48
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 47 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 0 
+
+minGini: 1.904761 - 4
+Region.size: 48
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 27 
+RightChild.size: 21
+RightChild.ClassCounts: 1 0 0 0 0 0 0 20 
+
+minGini: 0.000000 - 4
+Region.size: 21
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 20
+RightChild.ClassCounts: 0 0 0 0 0 0 0 20 
+
+minGini: 43.391849 - 6
+Region.size: 80
+LeftChild.size: 22
+LeftChild.ClassCounts: 4 0 2 1 0 2 10 3 
+RightChild.size: 58
+RightChild.ClassCounts: 0 20 0 1 37 0 0 0 
+
+minGini: 26.407407 - 5
+Region.size: 58
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 0 
+RightChild.size: 54
+RightChild.ClassCounts: 0 20 0 1 33 0 0 0 
+
+minGini: 23.960784 - 6
+Region.size: 54
+LeftChild.size: 51
+LeftChild.ClassCounts: 0 17 0 1 33 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 21.516923 - 0
+Region.size: 51
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 12 0 1 12 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 5 0 0 21 0 0 0 
+
+minGini: 6.428571 - 0
+Region.size: 26
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 0 0 12 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 5 0 0 9 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 9 0 0 0 
+
+minGini: 10.300000 - 6
+Region.size: 25
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 0 
+RightChild.size: 20
+RightChild.ClassCounts: 0 7 0 1 12 0 0 0 
+
+minGini: 7.857142 - 6
+Region.size: 20
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 7 0 1 6 0 0 0 
+
+minGini: 6.181818 - 5
+Region.size: 14
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 4 0 1 6 0 0 0 
+
+minGini: 4.800000 - 5
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 4 0 0 6 0 0 0 
+
+minGini: 3.428571 - 6
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 4 0 0 3 0 0 0 
+
+minGini: 1.600000 - 0
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 1 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 10.333333 - 2
+Region.size: 22
+LeftChild.size: 10
+LeftChild.ClassCounts: 4 0 0 1 0 2 0 3 
+RightChild.size: 12
+RightChild.ClassCounts: 0 0 2 0 0 0 10 0 
+
+minGini: 0.000000 - 5
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 0 0 0 0 10 0 
+
+minGini: 3.666666 - 4
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 1 0 2 0 3 
+
+minGini: 1.333333 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 1 0 2 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 79.294862 - 1
+Region.size: 185
+LeftChild.size: 87
+LeftChild.ClassCounts: 75 10 0 0 1 0 0 1 
+RightChild.size: 98
+RightChild.ClassCounts: 44 44 0 0 4 4 0 2 
+
+minGini: 21.612040 - 5
+Region.size: 98
+LeftChild.size: 52
+LeftChild.ClassCounts: 44 2 0 0 0 4 0 2 
+RightChild.size: 46
+RightChild.ClassCounts: 0 42 0 0 4 0 0 0 
+
+minGini: 6.117647 - 5
+Region.size: 46
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 13 0 0 4 0 0 0 
+RightChild.size: 29
+RightChild.ClassCounts: 0 29 0 0 0 0 0 0 
+
+minGini: 1.857142 - 5
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 13 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 6.492753 - 1
+Region.size: 52
+LeftChild.size: 46
+LeftChild.ClassCounts: 44 2 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 4 0 2 
+
+minGini: 1.333333 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 3 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 1 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 2.400000 - 4
+Region.size: 46
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 0 0 0 0 0 0 
+RightChild.size: 41
+RightChild.ClassCounts: 41 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 3.791866 - 5
+Region.size: 87
+LeftChild.size: 76
+LeftChild.ClassCounts: 75 0 0 0 0 0 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 0 10 0 0 1 0 0 0 
+
+minGini: 1.500000 - 4
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 0 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 1.933333 - 1
+Region.size: 76
+LeftChild.size: 46
+LeftChild.ClassCounts: 46 0 0 0 0 0 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 29 0 0 0 0 0 0 1 
+
+minGini: 1.666666 - 4
+Region.size: 30
+LeftChild.size: 24
+LeftChild.ClassCounts: 24 0 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 0 0 0 0 0 0 1 
+
+minGini: 1.333333 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+
+
+Tree Number: 26 finished.
+
+minGini: 191.337602 - 0
+Region.size: 336
+LeftChild.size: 207
+LeftChild.ClassCounts: 143 58 0 0 2 0 0 4 
+RightChild.size: 129
+RightChild.ClassCounts: 8 25 1 2 23 19 4 47 
+
+minGini: 73.462278 - 5
+Region.size: 129
+LeftChild.size: 79
+LeftChild.ClassCounts: 8 0 0 2 0 19 4 46 
+RightChild.size: 50
+RightChild.ClassCounts: 0 25 1 0 23 0 0 1 
+
+minGini: 20.868055 - 1
+Region.size: 50
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 3 1 0 14 0 0 0 
+RightChild.size: 32
+RightChild.ClassCounts: 0 22 0 0 9 0 0 1 
+
+minGini: 8.236363 - 0
+Region.size: 32
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 20 0 0 2 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 2 0 0 7 0 0 1 
+
+minGini: 1.750000 - 0
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 0 7 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 1 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 3.200000 - 5
+Region.size: 22
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 8 0 0 2 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 1.500000 - 6
+Region.size: 18
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 0 0 0 14 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 1 0 0 0 0 0 
+
+minGini: 1.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 0 
+
+minGini: 24.918032 - 4
+Region.size: 79
+LeftChild.size: 61
+LeftChild.ClassCounts: 8 0 0 2 0 1 4 46 
+RightChild.size: 18
+RightChild.ClassCounts: 0 0 0 0 0 18 0 0 
+
+minGini: 17.953658 - 1
+Region.size: 61
+LeftChild.size: 20
+LeftChild.ClassCounts: 7 0 0 2 0 0 4 7 
+RightChild.size: 41
+RightChild.ClassCounts: 1 0 0 0 0 1 0 39 
+
+minGini: 3.714285 - 1
+Region.size: 41
+LeftChild.size: 21
+LeftChild.ClassCounts: 1 0 0 0 0 1 0 19 
+RightChild.size: 20
+RightChild.ClassCounts: 0 0 0 0 0 0 0 20 
+
+minGini: 1.000000 - 1
+Region.size: 21
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 19 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 1 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 10.868686 - 5
+Region.size: 20
+LeftChild.size: 11
+LeftChild.ClassCounts: 7 0 0 0 0 0 0 4 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 2 0 0 4 3 
+
+minGini: 2.400000 - 2
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 2 0 0 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 4 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 2.666666 - 4
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 4 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 0 0 
+
+minGini: 1.600000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 0 0 0 0 0 0 4 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 0 4 
+
+minGini: 21.051913 - 6
+Region.size: 207
+LeftChild.size: 152
+LeftChild.ClassCounts: 143 5 0 0 0 0 0 4 
+RightChild.size: 55
+RightChild.ClassCounts: 0 53 0 0 2 0 0 0 
+
+minGini: 2.857142 - 1
+Region.size: 55
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 48 0 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 5 0 0 2 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 14.836689 - 0
+Region.size: 152
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 0 0 0 0 0 0 
+RightChild.size: 149
+RightChild.ClassCounts: 142 3 0 0 0 0 0 4 
+
+minGini: 9.714285 - 5
+Region.size: 149
+LeftChild.size: 147
+LeftChild.ClassCounts: 142 1 0 0 0 0 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 8.900406 - 6
+Region.size: 147
+LeftChild.size: 123
+LeftChild.ClassCounts: 122 0 0 0 0 0 0 1 
+RightChild.size: 24
+RightChild.ClassCounts: 20 1 0 0 0 0 0 3 
+
+minGini: 3.727272 - 5
+Region.size: 24
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 22
+RightChild.ClassCounts: 20 1 0 0 0 0 0 1 
+
+minGini: 3.454545 - 5
+Region.size: 22
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 9 1 0 0 0 0 0 1 
+
+minGini: 2.800000 - 5
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 1 0 0 0 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 0 0 0 0 0 
+
+minGini: 1.500000 - 4
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 1.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 1.966101 - 6
+Region.size: 123
+LeftChild.size: 64
+LeftChild.ClassCounts: 64 0 0 0 0 0 0 0 
+RightChild.size: 59
+RightChild.ClassCounts: 58 0 0 0 0 0 0 1 
+
+minGini: 1.600000 - 6
+Region.size: 59
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 1 
+RightChild.size: 54
+RightChild.ClassCounts: 54 0 0 0 0 0 0 0 
+
+minGini: 1.000000 - 0
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+
+
+Tree Number: 27 finished.
+
+minGini: 176.817650 - 0
+Region.size: 336
+LeftChild.size: 205
+LeftChild.ClassCounts: 153 42 0 0 4 3 0 3 
+RightChild.size: 131
+RightChild.ClassCounts: 6 28 0 1 27 13 1 55 
+
+minGini: 74.121596 - 4
+Region.size: 131
+LeftChild.size: 71
+LeftChild.ClassCounts: 5 8 0 0 6 0 0 52 
+RightChild.size: 60
+RightChild.ClassCounts: 1 20 0 1 21 13 1 3 
+
+minGini: 29.961489 - 5
+Region.size: 60
+LeftChild.size: 19
+LeftChild.ClassCounts: 1 0 0 1 0 13 1 3 
+RightChild.size: 41
+RightChild.ClassCounts: 0 20 0 0 21 0 0 0 
+
+minGini: 10.370370 - 0
+Region.size: 41
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 20 0 0 7 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 14 0 0 0 
+
+minGini: 8.000000 - 5
+Region.size: 27
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 20 0 0 5 0 0 0 
+
+minGini: 6.875000 - 5
+Region.size: 25
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 11 0 0 5 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 0 0 0 0 0 
+
+minGini: 1.666666 - 1
+Region.size: 16
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 1 0 0 5 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 0 0 0 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 4.000000 - 4
+Region.size: 19
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 0 0 1 0 0 1 3 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 0 0 0 13 0 0 
+
+minGini: 2.800000 - 0
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 0 0 0 0 0 1 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 0 0 0 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 20.039787 - 6
+Region.size: 71
+LeftChild.size: 58
+LeftChild.ClassCounts: 5 2 0 0 0 0 0 51 
+RightChild.size: 13
+RightChild.ClassCounts: 0 6 0 0 6 0 0 1 
+
+minGini: 4.444444 - 0
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 2 0 0 6 0 0 1 
+
+minGini: 3.000000 - 6
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 2 0 0 6 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 1.714285 - 0
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 1 0 0 6 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 9.107142 - 4
+Region.size: 58
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 56
+RightChild.ClassCounts: 5 0 0 0 0 0 0 51 
+
+minGini: 8.728132 - 4
+Region.size: 56
+LeftChild.size: 47
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 44 
+RightChild.size: 9
+RightChild.ClassCounts: 2 0 0 0 0 0 0 7 
+
+minGini: 0.000000 - 6
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 7 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 1.500000 - 5
+Region.size: 47
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 1 
+RightChild.size: 43
+RightChild.ClassCounts: 0 0 0 0 0 0 0 43 
+
+minGini: 1.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 24.589147 - 6
+Region.size: 205
+LeftChild.size: 162
+LeftChild.ClassCounts: 153 3 0 0 0 3 0 3 
+RightChild.size: 43
+RightChild.ClassCounts: 0 39 0 0 4 0 0 0 
+
+minGini: 5.571428 - 2
+Region.size: 43
+LeftChild.size: 42
+LeftChild.ClassCounts: 0 39 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 4.615384 - 4
+Region.size: 42
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 29 0 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 10 0 0 3 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 0 0 0 0 0 0 
+
+minGini: 9.576923 - 1
+Region.size: 162
+LeftChild.size: 156
+LeftChild.ClassCounts: 153 2 0 0 0 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 1 0 0 0 3 0 2 
+
+minGini: 1.333333 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 3 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 0 0 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 5.651515 - 1
+Region.size: 156
+LeftChild.size: 132
+LeftChild.ClassCounts: 131 0 0 0 0 0 0 1 
+RightChild.size: 24
+RightChild.ClassCounts: 22 2 0 0 0 0 0 0 
+
+minGini: 2.909090 - 4
+Region.size: 24
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 21 1 0 0 0 0 0 0 
+
+minGini: 1.500000 - 6
+Region.size: 22
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 1.960000 - 0
+Region.size: 132
+LeftChild.size: 50
+LeftChild.ClassCounts: 49 0 0 0 0 0 0 1 
+RightChild.size: 82
+RightChild.ClassCounts: 82 0 0 0 0 0 0 0 
+
+minGini: 1.600000 - 0
+Region.size: 50
+LeftChild.size: 45
+LeftChild.ClassCounts: 45 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 0 0 0 0 0 0 1 
+
+minGini: 1.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 28 finished.
+
+minGini: 163.277777 - 5
+Region.size: 336
+LeftChild.size: 228
+LeftChild.ClassCounts: 154 4 0 0 1 19 5 45 
+RightChild.size: 108
+RightChild.ClassCounts: 0 71 0 0 35 0 0 2 
+
+minGini: 45.833097 - 5
+Region.size: 108
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 1 0 0 6 0 0 0 
+RightChild.size: 101
+RightChild.ClassCounts: 0 70 0 0 29 0 0 2 
+
+minGini: 30.198973 - 0
+Region.size: 101
+LeftChild.size: 82
+LeftChild.ClassCounts: 0 67 0 0 13 0 0 2 
+RightChild.size: 19
+RightChild.ClassCounts: 0 3 0 0 16 0 0 0 
+
+minGini: 4.363636 - 0
+Region.size: 19
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 0 8 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 3 0 0 8 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 11
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 8 0 0 0 
+
+minGini: 20.860759 - 2
+Region.size: 82
+LeftChild.size: 79
+LeftChild.ClassCounts: 0 67 0 0 10 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 0 
+
+minGini: 17.473684 - 0
+Region.size: 79
+LeftChild.size: 41
+LeftChild.ClassCounts: 0 41 0 0 0 0 0 0 
+RightChild.size: 38
+RightChild.ClassCounts: 0 26 0 0 10 0 0 2 
+
+minGini: 15.529411 - 5
+Region.size: 38
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 11 0 0 8 0 0 2 
+RightChild.size: 17
+RightChild.ClassCounts: 0 15 0 0 2 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 17
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 6.472727 - 1
+Region.size: 21
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 2 0 0 8 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 9 0 0 0 0 0 2 
+
+minGini: 0.000000 - 4
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 0 0 0 0 0 
+
+minGini: 1.777777 - 5
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 1 0 0 8 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 0 2 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 6 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 6 0 0 0 
+
+minGini: 84.172169 - 5
+Region.size: 228
+LeftChild.size: 141
+LeftChild.ClassCounts: 129 0 0 0 0 2 0 10 
+RightChild.size: 87
+RightChild.ClassCounts: 25 4 0 0 1 17 5 35 
+
+minGini: 45.666666 - 4
+Region.size: 87
+LeftChild.size: 72
+LeftChild.ClassCounts: 25 4 0 0 1 2 5 35 
+RightChild.size: 15
+RightChild.ClassCounts: 0 0 0 0 0 15 0 0 
+
+minGini: 23.862500 - 0
+Region.size: 72
+LeftChild.size: 32
+LeftChild.ClassCounts: 25 4 0 0 1 0 0 2 
+RightChild.size: 40
+RightChild.ClassCounts: 0 0 0 0 0 2 5 33 
+
+minGini: 3.771428 - 2
+Region.size: 40
+LeftChild.size: 35
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 33 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 0 5 0 
+
+minGini: 3.272727 - 6
+Region.size: 35
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 9 
+RightChild.size: 24
+RightChild.ClassCounts: 0 0 0 0 0 0 0 24 
+
+minGini: 0.000000 - 4
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 9 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 8.866666 - 0
+Region.size: 32
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 25 2 0 0 1 0 0 2 
+
+minGini: 6.500000 - 6
+Region.size: 30
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 1 
+RightChild.size: 28
+RightChild.ClassCounts: 25 2 0 0 0 0 0 1 
+
+minGini: 5.005847 - 4
+Region.size: 28
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 0 0 0 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 18 0 0 0 0 0 0 1 
+
+minGini: 1.333333 - 5
+Region.size: 19
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 1 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 15.533884 - 1
+Region.size: 141
+LeftChild.size: 121
+LeftChild.ClassCounts: 119 0 0 0 0 0 0 2 
+RightChild.size: 20
+RightChild.ClassCounts: 10 0 0 0 0 2 0 8 
+
+minGini: 8.800000 - 4
+Region.size: 20
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 5 0 0 0 0 2 0 8 
+
+minGini: 4.727272 - 0
+Region.size: 15
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 1 0 0 0 0 2 0 8 
+
+minGini: 3.083333 - 5
+Region.size: 11
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 2 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 1 0 0 0 0 0 0 7 
+
+minGini: 1.333333 - 1
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 1 0 0 0 0 0 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 0 0 
+
+minGini: 3.875000 - 1
+Region.size: 121
+LeftChild.size: 64
+LeftChild.ClassCounts: 62 0 0 0 0 0 0 2 
+RightChild.size: 57
+RightChild.ClassCounts: 57 0 0 0 0 0 0 0 
+
+minGini: 3.636363 - 4
+Region.size: 64
+LeftChild.size: 42
+LeftChild.ClassCounts: 42 0 0 0 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 20 0 0 0 0 0 0 2 
+
+minGini: 2.666666 - 4
+Region.size: 22
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 2 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 0 0 
+
+
+
+Tree Number: 29 finished.
+
+minGini: 200.777315 - 0
+Region.size: 336
+LeftChild.size: 177
+LeftChild.ClassCounts: 124 46 0 0 1 1 0 5 
+RightChild.size: 159
+RightChild.ClassCounts: 14 34 0 0 35 19 4 53 
+
+minGini: 97.144261 - 1
+Region.size: 159
+LeftChild.size: 76
+LeftChild.ClassCounts: 12 26 0 0 33 0 3 2 
+RightChild.size: 83
+RightChild.ClassCounts: 2 8 0 0 2 19 1 51 
+
+minGini: 24.584126 - 4
+Region.size: 83
+LeftChild.size: 63
+LeftChild.ClassCounts: 2 6 0 0 2 1 1 51 
+RightChild.size: 20
+RightChild.ClassCounts: 0 2 0 0 0 18 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 20
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 0 0 0 0 18 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 13.668181 - 5
+Region.size: 63
+LeftChild.size: 55
+LeftChild.ClassCounts: 2 1 0 0 0 1 1 50 
+RightChild.size: 8
+RightChild.ClassCounts: 0 5 0 0 2 0 0 1 
+
+minGini: 2.500000 - 0
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 0 2 0 0 1 
+
+minGini: 1.333333 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 7.592592 - 2
+Region.size: 55
+LeftChild.size: 54
+LeftChild.ClassCounts: 2 1 0 0 0 1 0 50 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 0 
+
+minGini: 5.735849 - 1
+Region.size: 54
+LeftChild.size: 53
+LeftChild.ClassCounts: 2 1 0 0 0 0 0 50 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 3.846153 - 6
+Region.size: 53
+LeftChild.size: 52
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 50 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 3.600000 - 4
+Region.size: 52
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 32 
+RightChild.size: 20
+RightChild.ClassCounts: 2 0 0 0 0 0 0 18 
+
+minGini: 2.857142 - 0
+Region.size: 20
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 5 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 0 0 0 0 0 13 
+
+minGini: 0.000000 - 4
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 0 0 5 
+
+minGini: 38.807017 - 6
+Region.size: 76
+LeftChild.size: 19
+LeftChild.ClassCounts: 12 0 0 0 2 0 3 2 
+RightChild.size: 57
+RightChild.ClassCounts: 0 26 0 0 31 0 0 0 
+
+minGini: 24.439024 - 1
+Region.size: 57
+LeftChild.size: 41
+LeftChild.ClassCounts: 0 14 0 0 27 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 12 0 0 4 0 0 0 
+
+minGini: 3.333333 - 0
+Region.size: 16
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 11 0 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 0 3 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 1 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 16.615384 - 0
+Region.size: 41
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 39
+RightChild.ClassCounts: 0 12 0 0 27 0 0 0 
+
+minGini: 14.709677 - 1
+Region.size: 39
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 12 0 0 19 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 8 0 0 0 
+
+minGini: 12.000000 - 4
+Region.size: 31
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 12 0 0 12 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 7 0 0 0 
+
+minGini: 10.863157 - 0
+Region.size: 24
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 0 0 4 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 11 0 0 8 0 0 0 
+
+minGini: 6.875000 - 6
+Region.size: 19
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 11 0 0 5 0 0 0 
+
+minGini: 4.714285 - 0
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 11 0 0 3 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 3.750000 - 5
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 5 0 0 3 0 0 0 
+
+minGini: 1.500000 - 0
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 0 3 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 6.500000 - 2
+Region.size: 19
+LeftChild.size: 16
+LeftChild.ClassCounts: 12 0 0 0 2 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 0 
+
+minGini: 3.428571 - 4
+Region.size: 16
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 12 0 0 0 0 0 0 2 
+
+minGini: 2.000000 - 1
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 0 0 0 0 0 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 0 2 
+
+minGini: 26.168978 - 6
+Region.size: 177
+LeftChild.size: 137
+LeftChild.ClassCounts: 124 7 0 0 0 1 0 5 
+RightChild.size: 40
+RightChild.ClassCounts: 0 39 0 0 1 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 40
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 39 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 17.127819 - 5
+Region.size: 137
+LeftChild.size: 133
+LeftChild.ClassCounts: 124 3 0 0 0 1 0 5 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 0 
+
+minGini: 14.435114 - 1
+Region.size: 133
+LeftChild.size: 131
+LeftChild.ClassCounts: 124 3 0 0 0 0 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 1 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 12.596739 - 5
+Region.size: 131
+LeftChild.size: 115
+LeftChild.ClassCounts: 111 0 0 0 0 0 0 4 
+RightChild.size: 16
+RightChild.ClassCounts: 13 3 0 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 16
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 0 0 0 0 0 0 
+
+minGini: 7.360000 - 1
+Region.size: 115
+LeftChild.size: 50
+LeftChild.ClassCounts: 46 0 0 0 0 0 0 4 
+RightChild.size: 65
+RightChild.ClassCounts: 65 0 0 0 0 0 0 0 
+
+minGini: 2.666666 - 1
+Region.size: 50
+LeftChild.size: 44
+LeftChild.ClassCounts: 44 0 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 2 0 0 0 0 0 0 4 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 0 4 
+
+
+
+Tree Number: 30 finished.
+
+minGini: 182.681214 - 6
+Region.size: 336
+LeftChild.size: 230
+LeftChild.ClassCounts: 132 10 2 2 0 30 1 53 
+RightChild.size: 106
+RightChild.ClassCounts: 0 76 0 1 26 0 0 3 
+
+minGini: 29.535390 - 0
+Region.size: 106
+LeftChild.size: 87
+LeftChild.ClassCounts: 0 73 0 1 10 0 0 3 
+RightChild.size: 19
+RightChild.ClassCounts: 0 3 0 0 16 0 0 0 
+
+minGini: 4.200000 - 1
+Region.size: 19
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 3 0 0 7 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 9 0 0 0 
+
+minGini: 2.400000 - 1
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 3 0 0 2 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 0 
+
+minGini: 22.939873 - 4
+Region.size: 87
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 3 
+RightChild.size: 79
+RightChild.ClassCounts: 0 68 0 1 10 0 0 0 
+
+minGini: 16.269946 - 0
+Region.size: 79
+LeftChild.size: 47
+LeftChild.ClassCounts: 0 46 0 0 1 0 0 0 
+RightChild.size: 32
+RightChild.ClassCounts: 0 22 0 1 9 0 0 0 
+
+minGini: 11.278431 - 5
+Region.size: 32
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 8 0 1 8 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 14 0 0 1 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 1 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 0 
+
+minGini: 4.727272 - 4
+Region.size: 17
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 2 0 1 8 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 0 0 
+
+minGini: 1.777777 - 6
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 1 8 0 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 1 2 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 0 
+
+minGini: 1.875000 - 0
+Region.size: 47
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 31 0 0 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 15 0 0 1 0 0 0 
+
+minGini: 1.666666 - 4
+Region.size: 16
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 5 0 0 1 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 86.049513 - 0
+Region.size: 230
+LeftChild.size: 143
+LeftChild.ClassCounts: 125 8 0 0 0 4 0 6 
+RightChild.size: 87
+RightChild.ClassCounts: 7 2 2 2 0 26 1 47 
+
+minGini: 48.106280 - 1
+Region.size: 87
+LeftChild.size: 18
+LeftChild.ClassCounts: 5 2 2 2 0 3 1 3 
+RightChild.size: 69
+RightChild.ClassCounts: 2 0 0 0 0 23 0 44 
+
+minGini: 7.500000 - 4
+Region.size: 69
+LeftChild.size: 48
+LeftChild.ClassCounts: 2 0 0 0 0 2 0 44 
+RightChild.size: 21
+RightChild.ClassCounts: 0 0 0 0 0 21 0 0 
+
+minGini: 4.454545 - 5
+Region.size: 48
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 0 0 0 0 1 0 1 
+RightChild.size: 44
+RightChild.ClassCounts: 0 0 0 0 0 1 0 43 
+
+minGini: 1.500000 - 4
+Region.size: 44
+LeftChild.size: 40
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 40 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 1 0 3 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 1.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 1 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 0 
+
+minGini: 11.866666 - 4
+Region.size: 18
+LeftChild.size: 15
+LeftChild.ClassCounts: 5 2 2 2 0 0 1 3 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 0 0 
+
+minGini: 9.692307 - 3
+Region.size: 15
+LeftChild.size: 13
+LeftChild.ClassCounts: 5 2 0 2 0 0 1 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 0 
+
+minGini: 6.523809 - 0
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 2 0 0 1 3 
+
+minGini: 1.333333 - 6
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 2 0 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 0 3 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 0 
+
+minGini: 2.000000 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 20.681818 - 1
+Region.size: 143
+LeftChild.size: 132
+LeftChild.ClassCounts: 125 5 0 0 0 0 0 2 
+RightChild.size: 11
+RightChild.ClassCounts: 0 3 0 0 0 4 0 4 
+
+minGini: 3.428571 - 0
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 4 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 0 
+
+minGini: 12.553142 - 0
+Region.size: 132
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 0 0 0 0 0 0 
+RightChild.size: 125
+RightChild.ClassCounts: 120 3 0 0 0 0 0 2 
+
+minGini: 8.869505 - 1
+Region.size: 125
+LeftChild.size: 112
+LeftChild.ClassCounts: 110 1 0 0 0 0 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 10 2 0 0 0 0 0 1 
+
+minGini: 3.333333 - 0
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 10 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 0 1 
+
+minGini: 2.000000 - 4
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+minGini: 3.872340 - 0
+Region.size: 112
+LeftChild.size: 47
+LeftChild.ClassCounts: 45 1 0 0 0 0 0 1 
+RightChild.size: 65
+RightChild.ClassCounts: 65 0 0 0 0 0 0 0 
+
+minGini: 3.698717 - 4
+Region.size: 47
+LeftChild.size: 39
+LeftChild.ClassCounts: 38 1 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 7 0 0 0 0 0 0 1 
+
+minGini: 1.000000 - 6
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 39
+LeftChild.size: 36
+LeftChild.ClassCounts: 36 0 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 0 
+
+
+
+Tree Number: 31 finished.
+
+ecoli
+minGini: 143.941099 - 1
+Region.size: 214
+LeftChild.size: 185
+LeftChild.ClassCounts: 60 67 25 21 7 5 
+RightChild.size: 29
+RightChild.ClassCounts: 2 1 0 0 2 24 
+
+minGini: 4.420000 - 2
+Region.size: 29
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 0 0 0 1 24 
+RightChild.size: 4
+RightChild.ClassCounts: 2 1 0 0 1 0 
+
+minGini: 1.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 25
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 24
+RightChild.ClassCounts: 0 0 0 0 0 24 
+
+minGini: 124.496969 - 6
+Region.size: 185
+LeftChild.size: 165
+LeftChild.ClassCounts: 60 61 25 7 7 5 
+RightChild.size: 20
+RightChild.ClassCounts: 0 6 0 14 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 20
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 14 0 0 
+
+minGini: 105.930069 - 2
+Region.size: 165
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 3 0 7 7 5 
+RightChild.size: 143
+RightChild.ClassCounts: 60 58 25 0 0 0 
+
+minGini: 80.274870 - 3
+Region.size: 143
+LeftChild.size: 101
+LeftChild.ClassCounts: 53 28 20 0 0 0 
+RightChild.size: 42
+RightChild.ClassCounts: 7 30 5 0 0 0 
+
+minGini: 15.944444 - 1
+Region.size: 42
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 0 0 0 0 
+RightChild.size: 36
+RightChild.ClassCounts: 3 28 5 0 0 0 
+
+minGini: 10.842105 - 5
+Region.size: 36
+LeftChild.size: 19
+LeftChild.ClassCounts: 3 11 5 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 17 0 0 0 0 
+
+minGini: 9.000000 - 0
+Region.size: 19
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 3 6 5 0 0 0 
+
+minGini: 7.700000 - 3
+Region.size: 14
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 2 3 5 0 0 0 
+
+minGini: 3.750000 - 4
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 3 5 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 1.500000 - 8
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 1 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 56.943486 - 1
+Region.size: 101
+LeftChild.size: 29
+LeftChild.ClassCounts: 23 3 3 0 0 0 
+RightChild.size: 72
+RightChild.ClassCounts: 30 25 17 0 0 0 
+
+minGini: 42.515151 - 5
+Region.size: 72
+LeftChild.size: 66
+LeftChild.ClassCounts: 30 19 17 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 37.692165 - 6
+Region.size: 66
+LeftChild.size: 31
+LeftChild.ClassCounts: 12 16 3 0 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 18 3 14 0 0 0 
+
+minGini: 15.750000 - 6
+Region.size: 35
+LeftChild.size: 32
+LeftChild.ClassCounts: 18 0 14 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 12.000000 - 8
+Region.size: 32
+LeftChild.size: 27
+LeftChild.ClassCounts: 18 0 9 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 
+
+minGini: 7.729411 - 5
+Region.size: 27
+LeftChild.size: 10
+LeftChild.ClassCounts: 3 0 7 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 15 0 2 0 0 0 
+
+minGini: 2.857142 - 2
+Region.size: 17
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 0 2 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 0 0 0 0 
+
+minGini: 1.333333 - 2
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 0 2 0 0 0 
+
+minGini: 1.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 3.111111 - 6
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 2 0 7 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 7 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 12.241666 - 4
+Region.size: 31
+LeftChild.size: 16
+LeftChild.ClassCounts: 1 12 3 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 11 4 0 0 0 0 
+
+minGini: 3.384615 - 3
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 11 2 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 4.800000 - 4
+Region.size: 16
+LeftChild.size: 10
+LeftChild.ClassCounts: 1 9 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 3 3 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 5.180000 - 4
+Region.size: 29
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 3 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 23 2 0 0 0 0 
+
+minGini: 2.913043 - 4
+Region.size: 25
+LeftChild.size: 23
+LeftChild.ClassCounts: 22 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 23
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 22 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 9.466666 - 4
+Region.size: 22
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 7 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 3 0 0 7 5 
+
+minGini: 4.200000 - 7
+Region.size: 15
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 3 0 0 7 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 5 
+
+minGini: 1.750000 - 4
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 1 0 0 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 7 0 
+
+
+
+Tree Number: 0 finished.
+
+minGini: 126.588663 - 2
+Region.size: 214
+LeftChild.size: 61
+LeftChild.ClassCounts: 0 11 0 13 4 33 
+RightChild.size: 153
+RightChild.ClassCounts: 76 63 11 0 0 3 
+
+minGini: 67.544047 - 0
+Region.size: 153
+LeftChild.size: 48
+LeftChild.ClassCounts: 5 38 3 0 0 2 
+RightChild.size: 105
+RightChild.ClassCounts: 71 25 8 0 0 1 
+
+minGini: 46.212121 - 1
+Region.size: 105
+LeftChild.size: 66
+LeftChild.ClassCounts: 53 13 0 0 0 0 
+RightChild.size: 39
+RightChild.ClassCounts: 18 12 8 0 0 1 
+
+minGini: 20.121212 - 2
+Region.size: 39
+LeftChild.size: 33
+LeftChild.ClassCounts: 18 6 8 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 17.380952 - 2
+Region.size: 33
+LeftChild.size: 12
+LeftChild.ClassCounts: 3 5 3 0 0 1 
+RightChild.size: 21
+RightChild.ClassCounts: 15 1 5 0 0 0 
+
+minGini: 6.300000 - 0
+Region.size: 21
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 1 3 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 14 0 2 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 5.250000 - 3
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 3 0 0 1 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 1.500000 - 1
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 15.282051 - 0
+Region.size: 66
+LeftChild.size: 39
+LeftChild.ClassCounts: 38 1 0 0 0 0 
+RightChild.size: 27
+RightChild.ClassCounts: 15 12 0 0 0 0 
+
+minGini: 6.000000 - 2
+Region.size: 27
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 4 12 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 16
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 39
+LeftChild.size: 38
+LeftChild.ClassCounts: 38 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 11.516279 - 0
+Region.size: 48
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 0 0 0 0 2 
+RightChild.size: 43
+RightChild.ClassCounts: 2 38 3 0 0 0 
+
+minGini: 7.768817 - 2
+Region.size: 43
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 8 3 0 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 1 30 0 0 0 0 
+
+minGini: 1.600000 - 1
+Region.size: 31
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 0 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 3.250000 - 4
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 3 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 0 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 23.200466 - 6
+Region.size: 61
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 0 0 4 2 33 
+RightChild.size: 22
+RightChild.ClassCounts: 0 11 0 9 2 0 
+
+minGini: 8.266666 - 4
+Region.size: 22
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 4 0 9 2 0 
+
+minGini: 5.444444 - 6
+Region.size: 15
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 3 0 1 2 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 1 0 8 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 8 0 0 
+
+minGini: 2.400000 - 8
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 3 0 0 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+minGini: 5.611111 - 4
+Region.size: 39
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 3 0 0 
+RightChild.size: 36
+RightChild.ClassCounts: 0 0 0 1 2 33 
+
+minGini: 2.941176 - 0
+Region.size: 36
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 1 1 0 
+RightChild.size: 34
+RightChild.ClassCounts: 0 0 0 0 1 33 
+
+minGini: 1.000000 - 2
+Region.size: 34
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 0 0 0 0 32 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 1 1 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+
+
+Tree Number: 1 finished.
+
+minGini: 132.880602 - 3
+Region.size: 214
+LeftChild.size: 112
+LeftChild.ClassCounts: 71 20 16 0 2 3 
+RightChild.size: 102
+RightChild.ClassCounts: 10 48 4 11 7 22 
+
+minGini: 59.050543 - 3
+Region.size: 102
+LeftChild.size: 73
+LeftChild.ClassCounts: 10 44 4 8 4 3 
+RightChild.size: 29
+RightChild.ClassCounts: 0 4 0 3 3 19 
+
+minGini: 9.869565 - 6
+Region.size: 29
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 1 0 3 0 19 
+RightChild.size: 6
+RightChild.ClassCounts: 0 3 0 0 3 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 
+
+minGini: 1.500000 - 1
+Region.size: 23
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 0 3 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 0 0 0 19 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 3 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 37.367965 - 1
+Region.size: 73
+LeftChild.size: 66
+LeftChild.ClassCounts: 10 44 4 8 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 4 3 
+
+minGini: 0.000000 - 3
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 
+
+minGini: 28.606060 - 5
+Region.size: 66
+LeftChild.size: 33
+LeftChild.ClassCounts: 7 14 4 8 0 0 
+RightChild.size: 33
+RightChild.ClassCounts: 3 30 0 0 0 0 
+
+minGini: 1.935483 - 0
+Region.size: 33
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 1 30 0 0 0 0 
+
+minGini: 1.750000 - 1
+Region.size: 31
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 0 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 23 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 16.027777 - 6
+Region.size: 33
+LeftChild.size: 24
+LeftChild.ClassCounts: 7 13 4 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 1 0 8 0 0 
+
+minGini: 1.000000 - 8
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 7 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 1 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 11.800000 - 6
+Region.size: 24
+LeftChild.size: 20
+LeftChild.ClassCounts: 7 12 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 3 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 8.200000 - 5
+Region.size: 20
+LeftChild.size: 10
+LeftChild.ClassCounts: 6 4 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 1 8 1 0 0 0 
+
+minGini: 2.750000 - 4
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.600000 - 5
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 56.040535 - 4
+Region.size: 112
+LeftChild.size: 71
+LeftChild.ClassCounts: 36 19 13 0 1 2 
+RightChild.size: 41
+RightChild.ClassCounts: 35 1 3 0 1 1 
+
+minGini: 7.017543 - 5
+Region.size: 41
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 2 0 1 0 
+RightChild.size: 38
+RightChild.ClassCounts: 35 1 1 0 0 1 
+
+minGini: 5.161904 - 3
+Region.size: 38
+LeftChild.size: 35
+LeftChild.ClassCounts: 33 1 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 2 0 1 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 3.435483 - 8
+Region.size: 35
+LeftChild.size: 31
+LeftChild.ClassCounts: 30 0 0 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 31
+LeftChild.size: 30
+LeftChild.ClassCounts: 30 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 39.016666 - 8
+Region.size: 71
+LeftChild.size: 56
+LeftChild.ClassCounts: 33 8 12 0 1 2 
+RightChild.size: 15
+RightChild.ClassCounts: 3 11 1 0 0 0 
+
+minGini: 4.285714 - 6
+Region.size: 15
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 3 3 1 0 0 0 
+
+minGini: 1.500000 - 6
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 27.371428 - 6
+Region.size: 56
+LeftChild.size: 21
+LeftChild.ClassCounts: 6 6 9 0 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 27 2 3 0 1 2 
+
+minGini: 10.403225 - 1
+Region.size: 35
+LeftChild.size: 31
+LeftChild.ClassCounts: 26 2 0 0 1 2 
+RightChild.size: 4
+RightChild.ClassCounts: 1 0 3 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 5.517241 - 6
+Region.size: 31
+LeftChild.size: 29
+LeftChild.ClassCounts: 26 0 0 0 1 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 4.000000 - 4
+Region.size: 29
+LeftChild.size: 22
+LeftChild.ClassCounts: 22 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 4 0 0 0 1 2 
+
+minGini: 1.333333 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 1 2 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 8.571428 - 3
+Region.size: 21
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 6 8 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 0 1 0 0 0 
+
+minGini: 1.500000 - 5
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 1.777777 - 0
+Region.size: 14
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 1 8 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 1.500000 - 5
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 3 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+
+
+Tree Number: 2 finished.
+
+minGini: 142.861813 - 6
+Region.size: 214
+LeftChild.size: 67
+LeftChild.ClassCounts: 12 44 0 2 4 5 
+RightChild.size: 147
+RightChild.ClassCounts: 63 33 12 12 7 20 
+
+minGini: 82.156738 - 2
+Region.size: 147
+LeftChild.size: 68
+LeftChild.ClassCounts: 4 25 0 12 7 20 
+RightChild.size: 79
+RightChild.ClassCounts: 59 8 12 0 0 0 
+
+minGini: 28.162698 - 3
+Region.size: 79
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 0 5 0 0 0 
+RightChild.size: 72
+RightChild.ClassCounts: 57 8 7 0 0 0 
+
+minGini: 23.594202 - 0
+Region.size: 72
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 2 0 0 0 
+RightChild.size: 69
+RightChild.ClassCounts: 56 8 5 0 0 0 
+
+minGini: 18.544444 - 2
+Region.size: 69
+LeftChild.size: 60
+LeftChild.ClassCounts: 53 4 3 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 3 4 2 0 0 0 
+
+minGini: 2.400000 - 1
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 0 2 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 11.084745 - 8
+Region.size: 60
+LeftChild.size: 59
+LeftChild.ClassCounts: 53 3 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 8.578947 - 3
+Region.size: 59
+LeftChild.size: 57
+LeftChild.ClassCounts: 53 2 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 7.019047 - 3
+Region.size: 57
+LeftChild.size: 15
+LeftChild.ClassCounts: 12 1 2 0 0 0 
+RightChild.size: 42
+RightChild.ClassCounts: 41 1 0 0 0 0 
+
+minGini: 1.333333 - 3
+Region.size: 42
+LeftChild.size: 39
+LeftChild.ClassCounts: 39 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 3.200000 - 6
+Region.size: 15
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 1 2 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 0 0 0 0 
+
+minGini: 2.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 33.525000 - 7
+Region.size: 68
+LeftChild.size: 48
+LeftChild.ClassCounts: 4 24 0 12 7 1 
+RightChild.size: 20
+RightChild.ClassCounts: 0 1 0 0 0 19 
+
+minGini: 0.000000 - 1
+Region.size: 20
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 0 0 0 19 
+
+minGini: 26.166666 - 0
+Region.size: 48
+LeftChild.size: 36
+LeftChild.ClassCounts: 4 12 0 12 7 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 0 0 0 0 
+
+minGini: 19.678571 - 5
+Region.size: 36
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 1 0 0 7 0 
+RightChild.size: 28
+RightChild.ClassCounts: 4 11 0 12 0 1 
+
+minGini: 9.285714 - 2
+Region.size: 28
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 1 0 12 0 1 
+RightChild.size: 14
+RightChild.ClassCounts: 4 10 0 0 0 0 
+
+minGini: 2.666666 - 8
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 0 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 0 0 12 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.333333 - 2
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 0 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 5 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+minGini: 28.129032 - 7
+Region.size: 67
+LeftChild.size: 62
+LeftChild.ClassCounts: 12 44 0 2 4 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 5 
+
+minGini: 21.126559 - 2
+Region.size: 62
+LeftChild.size: 11
+LeftChild.ClassCounts: 4 1 0 2 4 0 
+RightChild.size: 51
+RightChild.ClassCounts: 8 43 0 0 0 0 
+
+minGini: 9.955555 - 4
+Region.size: 51
+LeftChild.size: 45
+LeftChild.ClassCounts: 4 41 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 5.142857 - 3
+Region.size: 45
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 0 0 0 0 
+RightChild.size: 42
+RightChild.ClassCounts: 2 40 0 0 0 0 
+
+minGini: 3.578947 - 4
+Region.size: 42
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 23 0 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 2 17 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 17 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 4.000000 - 2
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 1 0 2 4 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 2 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+
+
+Tree Number: 3 finished.
+
+minGini: 139.650633 - 3
+Region.size: 214
+LeftChild.size: 177
+LeftChild.ClassCounts: 73 69 15 5 9 6 
+RightChild.size: 37
+RightChild.ClassCounts: 0 4 0 7 4 22 
+
+minGini: 16.363636 - 6
+Region.size: 37
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 4 0 7 0 22 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 4 0 
+
+minGini: 10.207692 - 7
+Region.size: 33
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 4 0 6 0 3 
+RightChild.size: 20
+RightChild.ClassCounts: 0 0 0 1 0 19 
+
+minGini: 0.000000 - 4
+Region.size: 20
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 0 0 0 19 
+
+minGini: 4.800000 - 0
+Region.size: 13
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 4 0 6 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 
+
+minGini: 2.666666 - 6
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 4 0 2 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 4 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 107.291649 - 2
+Region.size: 177
+LeftChild.size: 34
+LeftChild.ClassCounts: 0 15 0 5 9 5 
+RightChild.size: 143
+RightChild.ClassCounts: 73 54 15 0 0 1 
+
+minGini: 68.775885 - 0
+Region.size: 143
+LeftChild.size: 46
+LeftChild.ClassCounts: 7 31 8 0 0 0 
+RightChild.size: 97
+RightChild.ClassCounts: 66 23 7 0 0 1 
+
+minGini: 39.683636 - 8
+Region.size: 97
+LeftChild.size: 75
+LeftChild.ClassCounts: 58 10 6 0 0 1 
+RightChild.size: 22
+RightChild.ClassCounts: 8 13 1 0 0 0 
+
+minGini: 7.571428 - 8
+Region.size: 22
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 8 5 1 0 0 0 
+
+minGini: 3.142857 - 2
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 1 5 1 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 1 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 25.962264 - 1
+Region.size: 75
+LeftChild.size: 22
+LeftChild.ClassCounts: 22 0 0 0 0 0 
+RightChild.size: 53
+RightChild.ClassCounts: 36 10 6 0 0 1 
+
+minGini: 23.872463 - 5
+Region.size: 53
+LeftChild.size: 30
+LeftChild.ClassCounts: 24 2 4 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 12 8 2 0 0 1 
+
+minGini: 9.589285 - 5
+Region.size: 23
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 11 2 2 0 0 1 
+
+minGini: 5.000000 - 3
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 11 2 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 1.833333 - 2
+Region.size: 14
+LeftChild.size: 12
+LeftChild.ClassCounts: 11 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 1.000000 - 2
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 6.857142 - 6
+Region.size: 30
+LeftChild.size: 28
+LeftChild.ClassCounts: 24 0 4 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 4.909090 - 0
+Region.size: 28
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 0 3 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 21 0 1 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 22
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 1 0 0 0 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 17.321428 - 6
+Region.size: 46
+LeftChild.size: 32
+LeftChild.ClassCounts: 6 26 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 1 5 8 0 0 0 
+
+minGini: 4.727272 - 6
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 2 8 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 3.200000 - 1
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 2 2 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 6 0 0 0 
+
+minGini: 2.000000 - 3
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 2 0 0 0 
+
+minGini: 1.333333 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 1 0 0 0 
+
+minGini: 1.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 7.764705 - 0
+Region.size: 32
+LeftChild.size: 17
+LeftChild.ClassCounts: 6 11 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 0 0 0 0 
+
+minGini: 5.939393 - 6
+Region.size: 17
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 2 9 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 16.285714 - 1
+Region.size: 34
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 14 0 5 0 2 
+RightChild.size: 13
+RightChild.ClassCounts: 0 1 0 0 9 3 
+
+minGini: 1.500000 - 0
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 9 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 0 0 3 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 
+
+minGini: 7.368421 - 4
+Region.size: 21
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 14 0 5 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 5.454545 - 2
+Region.size: 19
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 6 0 5 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 5 0 0 
+
+
+
+Tree Number: 4 finished.
+
+minGini: 139.635979 - 1
+Region.size: 214
+LeftChild.size: 173
+LeftChild.ClassCounts: 67 71 20 11 2 2 
+RightChild.size: 41
+RightChild.ClassCounts: 6 0 1 0 12 22 
+
+minGini: 17.243697 - 2
+Region.size: 41
+LeftChild.size: 34
+LeftChild.ClassCounts: 0 0 0 0 12 22 
+RightChild.size: 7
+RightChild.ClassCounts: 6 0 1 0 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 8.497777 - 0
+Region.size: 34
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 0 0 0 4 21 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 8 1 
+
+minGini: 0.000000 - 6
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 8 0 
+
+minGini: 4.300000 - 2
+Region.size: 25
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 0 0 0 1 19 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 3 2 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 0.000000 - 6
+Region.size: 20
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 0 0 0 19 
+
+minGini: 105.636316 - 2
+Region.size: 173
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 11 0 11 2 2 
+RightChild.size: 147
+RightChild.ClassCounts: 67 60 20 0 0 0 
+
+minGini: 80.790476 - 5
+Region.size: 147
+LeftChild.size: 105
+LeftChild.ClassCounts: 56 30 19 0 0 0 
+RightChild.size: 42
+RightChild.ClassCounts: 11 30 1 0 0 0 
+
+minGini: 14.121212 - 0
+Region.size: 42
+LeftChild.size: 33
+LeftChild.ClassCounts: 5 27 1 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 6 3 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 7.571428 - 6
+Region.size: 33
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 19 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 5 8 1 0 0 0 
+
+minGini: 4.571428 - 8
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 6 1 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 59.333333 - 8
+Region.size: 105
+LeftChild.size: 93
+LeftChild.ClassCounts: 54 22 17 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 2 8 2 0 0 0 
+
+minGini: 4.250000 - 6
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 1 2 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.333333 - 3
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 46.711751 - 2
+Region.size: 93
+LeftChild.size: 82
+LeftChild.ClassCounts: 52 13 17 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 2 9 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 39.107692 - 6
+Region.size: 82
+LeftChild.size: 65
+LeftChild.ClassCounts: 35 13 17 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 17 0 0 0 0 0 
+
+minGini: 33.372549 - 4
+Region.size: 65
+LeftChild.size: 51
+LeftChild.ClassCounts: 21 13 17 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 0 0 0 0 
+
+minGini: 29.811111 - 6
+Region.size: 51
+LeftChild.size: 15
+LeftChild.ClassCounts: 9 6 0 0 0 0 
+RightChild.size: 36
+RightChild.ClassCounts: 12 7 17 0 0 0 
+
+minGini: 20.129032 - 4
+Region.size: 36
+LeftChild.size: 31
+LeftChild.ClassCounts: 12 7 12 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 
+
+minGini: 15.728070 - 1
+Region.size: 31
+LeftChild.size: 12
+LeftChild.ClassCounts: 7 5 0 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 5 2 12 0 0 0 
+
+minGini: 7.022727 - 3
+Region.size: 19
+LeftChild.size: 8
+LeftChild.ClassCounts: 5 0 3 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 2 9 0 0 0 
+
+minGini: 2.000000 - 4
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 2 2 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 7 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 2.933333 - 2
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 0 2 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 3.111111 - 3
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 0 0 0 0 
+
+minGini: 2.400000 - 3
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 15
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 0 0 0 0 
+
+minGini: 12.300000 - 5
+Region.size: 26
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 11 0 5 2 2 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 6 0 0 
+
+minGini: 8.500000 - 4
+Region.size: 20
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 3 0 5 2 2 
+
+minGini: 5.333333 - 3
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 5 2 2 
+
+minGini: 2.000000 - 6
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 2 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 5 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+
+
+Tree Number: 5 finished.
+
+minGini: 129.271978 - 7
+Region.size: 214
+LeftChild.size: 182
+LeftChild.ClassCounts: 72 73 12 13 9 3 
+RightChild.size: 32
+RightChild.ClassCounts: 0 2 0 2 0 28 
+
+minGini: 2.000000 - 7
+Region.size: 32
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 0 0 0 0 28 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 0 2 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 111.349537 - 0
+Region.size: 182
+LeftChild.size: 54
+LeftChild.ClassCounts: 7 35 7 5 0 0 
+RightChild.size: 128
+RightChild.ClassCounts: 65 38 5 8 9 3 
+
+minGini: 70.735672 - 6
+Region.size: 128
+LeftChild.size: 90
+LeftChild.ClassCounts: 61 23 4 0 1 1 
+RightChild.size: 38
+RightChild.ClassCounts: 4 15 1 8 8 2 
+
+minGini: 21.490196 - 3
+Region.size: 38
+LeftChild.size: 21
+LeftChild.ClassCounts: 4 14 1 0 2 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 1 0 8 6 2 
+
+minGini: 4.727272 - 5
+Region.size: 17
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 1 0 8 0 2 
+
+minGini: 1.777777 - 4
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 9
+RightChild.ClassCounts: 0 1 0 8 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 8 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 7.000000 - 0
+Region.size: 21
+LeftChild.size: 10
+LeftChild.ClassCounts: 4 3 1 0 2 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 0 0 0 0 
+
+minGini: 5.000000 - 4
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 1 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 0 0 2 0 
+
+minGini: 1.333333 - 3
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 
+
+minGini: 0.000000 - 8
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 31.574074 - 4
+Region.size: 90
+LeftChild.size: 36
+LeftChild.ClassCounts: 12 18 4 0 1 1 
+RightChild.size: 54
+RightChild.ClassCounts: 49 5 0 0 0 0 
+
+minGini: 7.258358 - 2
+Region.size: 54
+LeftChild.size: 47
+LeftChild.ClassCounts: 45 2 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 4 3 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 1.956521 - 1
+Region.size: 47
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 46
+RightChild.ClassCounts: 45 1 0 0 0 0 
+
+minGini: 1.777777 - 6
+Region.size: 46
+LeftChild.size: 9
+LeftChild.ClassCounts: 8 1 0 0 0 0 
+RightChild.size: 37
+RightChild.ClassCounts: 37 0 0 0 0 0 
+
+minGini: 1.000000 - 8
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 17.714285 - 5
+Region.size: 36
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 0 0 0 1 0 
+RightChild.size: 29
+RightChild.ClassCounts: 6 18 4 0 0 1 
+
+minGini: 9.378947 - 2
+Region.size: 29
+LeftChild.size: 10
+LeftChild.ClassCounts: 6 1 2 0 0 1 
+RightChild.size: 19
+RightChild.ClassCounts: 0 17 2 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 17 0 0 0 0 
+
+minGini: 3.047619 - 3
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 2 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 0 0 0 
+
+minGini: 25.027355 - 8
+Region.size: 54
+LeftChild.size: 47
+LeftChild.ClassCounts: 2 33 7 5 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 17.407239 - 3
+Region.size: 47
+LeftChild.size: 13
+LeftChild.ClassCounts: 1 5 7 0 0 0 
+RightChild.size: 34
+RightChild.ClassCounts: 1 28 0 5 0 0 
+
+minGini: 5.548387 - 4
+Region.size: 34
+LeftChild.size: 31
+LeftChild.ClassCounts: 1 28 0 2 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 3 0 0 
+
+minGini: 1.931034 - 5
+Region.size: 31
+LeftChild.size: 29
+LeftChild.ClassCounts: 1 28 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 
+
+minGini: 1.500000 - 6
+Region.size: 29
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 0 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 25 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 1.750000 - 6
+Region.size: 13
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 1 0 7 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 7 0 0 0 
+
+
+
+Tree Number: 6 finished.
+
+minGini: 129.662111 - 7
+Region.size: 214
+LeftChild.size: 187
+LeftChild.ClassCounts: 73 81 19 7 5 2 
+RightChild.size: 27
+RightChild.ClassCounts: 0 2 0 3 0 22 
+
+minGini: 2.400000 - 7
+Region.size: 27
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 0 0 0 0 22 
+RightChild.size: 5
+RightChild.ClassCounts: 0 2 0 3 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 3 0 0 
+
+minGini: 107.710743 - 3
+Region.size: 187
+LeftChild.size: 121
+LeftChild.ClassCounts: 65 37 14 1 2 2 
+RightChild.size: 66
+RightChild.ClassCounts: 8 44 5 6 3 0 
+
+minGini: 29.630434 - 3
+Region.size: 66
+LeftChild.size: 46
+LeftChild.ClassCounts: 4 38 2 1 1 0 
+RightChild.size: 20
+RightChild.ClassCounts: 4 6 3 5 2 0 
+
+minGini: 11.375000 - 3
+Region.size: 20
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 6 3 5 2 0 
+
+minGini: 8.923076 - 3
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 6 3 2 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 3 0 0 
+
+minGini: 6.000000 - 2
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 2 2 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 6 3 0 0 0 
+
+minGini: 1.500000 - 3
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 3 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 1 2 0 
+
+minGini: 1.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 1 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 12.077519 - 4
+Region.size: 46
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 2 0 0 0 
+RightChild.size: 43
+RightChild.ClassCounts: 4 37 0 1 1 0 
+
+minGini: 9.000000 - 6
+Region.size: 43
+LeftChild.size: 42
+LeftChild.ClassCounts: 4 37 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 7.219512 - 1
+Region.size: 42
+LeftChild.size: 41
+LeftChild.ClassCounts: 4 37 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 6.000000 - 2
+Region.size: 41
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 25 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 4 12 0 0 0 0 
+
+minGini: 1.846153 - 1
+Region.size: 16
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 1 12 0 0 0 0 
+
+minGini: 1.500000 - 0
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 64.927272 - 6
+Region.size: 121
+LeftChild.size: 110
+LeftChild.ClassCounts: 65 27 14 0 2 2 
+RightChild.size: 11
+RightChild.ClassCounts: 0 10 0 1 0 0 
+
+minGini: 1.333333 - 5
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 1 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 57.415559 - 0
+Region.size: 110
+LeftChild.size: 17
+LeftChild.ClassCounts: 2 6 5 0 2 2 
+RightChild.size: 93
+RightChild.ClassCounts: 63 21 9 0 0 0 
+
+minGini: 39.135623 - 3
+Region.size: 93
+LeftChild.size: 14
+LeftChild.ClassCounts: 6 0 8 0 0 0 
+RightChild.size: 79
+RightChild.ClassCounts: 57 21 1 0 0 0 
+
+minGini: 27.866935 - 0
+Region.size: 79
+LeftChild.size: 31
+LeftChild.ClassCounts: 29 2 0 0 0 0 
+RightChild.size: 48
+RightChild.ClassCounts: 28 19 1 0 0 0 
+
+minGini: 9.043643 - 6
+Region.size: 48
+LeftChild.size: 17
+LeftChild.ClassCounts: 1 16 0 0 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 27 3 1 0 0 0 
+
+minGini: 1.928571 - 1
+Region.size: 31
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 27 0 1 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 27 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 1.333333 - 2
+Region.size: 31
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 0 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 28 0 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 3.200000 - 2
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 2 0 8 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 8 0 0 0 
+
+minGini: 9.766666 - 3
+Region.size: 17
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 6 1 0 2 2 
+RightChild.size: 5
+RightChild.ClassCounts: 1 0 4 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 
+
+minGini: 4.914285 - 3
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 0 0 0 2 2 
+RightChild.size: 7
+RightChild.ClassCounts: 0 6 1 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 0 0 0 0 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+
+
+Tree Number: 7 finished.
+
+minGini: 137.618343 - 2
+Region.size: 214
+LeftChild.size: 61
+LeftChild.ClassCounts: 0 13 0 15 13 20 
+RightChild.size: 153
+RightChild.ClassCounts: 67 67 17 0 0 2 
+
+minGini: 70.634879 - 3
+Region.size: 153
+LeftChild.size: 98
+LeftChild.ClassCounts: 62 23 13 0 0 0 
+RightChild.size: 55
+RightChild.ClassCounts: 5 44 4 0 0 2 
+
+minGini: 14.801393 - 6
+Region.size: 55
+LeftChild.size: 41
+LeftChild.ClassCounts: 1 38 0 0 0 2 
+RightChild.size: 14
+RightChild.ClassCounts: 4 6 4 0 0 0 
+
+minGini: 5.600000 - 6
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 0 1 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 6 3 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 1.948717 - 6
+Region.size: 41
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 39
+RightChild.ClassCounts: 1 38 0 0 0 0 
+
+minGini: 1.500000 - 1
+Region.size: 39
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 0 0 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 0 35 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 46.960365 - 0
+Region.size: 98
+LeftChild.size: 16
+LeftChild.ClassCounts: 4 5 7 0 0 0 
+RightChild.size: 82
+RightChild.ClassCounts: 58 18 6 0 0 0 
+
+minGini: 33.113924 - 0
+Region.size: 82
+LeftChild.size: 79
+LeftChild.ClassCounts: 58 15 6 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 26.702702 - 8
+Region.size: 79
+LeftChild.size: 74
+LeftChild.ClassCounts: 58 10 6 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 24.797843 - 1
+Region.size: 74
+LeftChild.size: 53
+LeftChild.ClassCounts: 43 10 0 0 0 0 
+RightChild.size: 21
+RightChild.ClassCounts: 15 0 6 0 0 0 
+
+minGini: 5.000000 - 4
+Region.size: 21
+LeftChild.size: 18
+LeftChild.ClassCounts: 15 0 3 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 3.428571 - 3
+Region.size: 18
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 0 3 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 0 0 0 0 
+
+minGini: 1.500000 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 0 3 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 8.958333 - 2
+Region.size: 53
+LeftChild.size: 48
+LeftChild.ClassCounts: 43 5 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 7.319148 - 7
+Region.size: 48
+LeftChild.size: 47
+LeftChild.ClassCounts: 43 4 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 5.151515 - 4
+Region.size: 47
+LeftChild.size: 44
+LeftChild.ClassCounts: 42 2 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 3.619047 - 6
+Region.size: 44
+LeftChild.size: 21
+LeftChild.ClassCounts: 19 2 0 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 23 0 0 0 0 0 
+
+minGini: 1.900000 - 6
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 19 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 5.833333 - 0
+Region.size: 16
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 5 7 0 0 0 
+
+minGini: 4.444444 - 1
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 5 4 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 39.451612 - 4
+Region.size: 61
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 11 0 9 8 2 
+RightChild.size: 31
+RightChild.ClassCounts: 0 2 0 6 5 18 
+
+minGini: 10.826086 - 1
+Region.size: 31
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 2 0 6 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 0 0 0 5 18 
+
+minGini: 1.894736 - 4
+Region.size: 23
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 0 0 0 1 18 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 4 0 
+
+minGini: 0.000000 - 7
+Region.size: 19
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 18
+RightChild.ClassCounts: 0 0 0 0 0 18 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 6 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 12.636363 - 5
+Region.size: 30
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 0 8 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 11 0 9 0 2 
+
+minGini: 8.256410 - 0
+Region.size: 22
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 1 0 7 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 0 10 0 2 0 1 
+
+minGini: 3.200000 - 5
+Region.size: 13
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 2 0 2 0 1 
+
+minGini: 1.333333 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 2 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 
+
+minGini: 1.750000 - 5
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 0 1 0 7 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 1 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 6 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+
+
+Tree Number: 8 finished.
+
+minGini: 140.979591 - 7
+Region.size: 214
+LeftChild.size: 196
+LeftChild.ClassCounts: 69 70 23 23 7 4 
+RightChild.size: 18
+RightChild.ClassCounts: 0 0 0 0 0 18 
+
+minGini: 129.678571 - 6
+Region.size: 196
+LeftChild.size: 56
+LeftChild.ClassCounts: 10 38 1 6 1 0 
+RightChild.size: 140
+RightChild.ClassCounts: 59 32 22 17 6 4 
+
+minGini: 88.195637 - 3
+Region.size: 140
+LeftChild.size: 89
+LeftChild.ClassCounts: 55 16 14 0 2 2 
+RightChild.size: 51
+RightChild.ClassCounts: 4 16 8 17 4 2 
+
+minGini: 32.543478 - 0
+Region.size: 51
+LeftChild.size: 28
+LeftChild.ClassCounts: 4 9 8 2 4 1 
+RightChild.size: 23
+RightChild.ClassCounts: 0 7 0 15 0 1 
+
+minGini: 5.196078 - 2
+Region.size: 23
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 2 0 15 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 5 0 0 0 1 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 1.875000 - 5
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 1 0 15 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.666666 - 3
+Region.size: 16
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 1 0 5 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 0 10 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 5 0 0 
+
+minGini: 16.142857 - 1
+Region.size: 28
+LeftChild.size: 14
+LeftChild.ClassCounts: 4 8 0 2 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 1 8 0 4 1 
+
+minGini: 3.377777 - 2
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 4 1 
+RightChild.size: 9
+RightChild.ClassCounts: 0 1 8 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 8 0 0 0 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 3.200000 - 2
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 8 0 2 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 
+
+minGini: 45.811244 - 2
+Region.size: 89
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 3 0 0 2 1 
+RightChild.size: 83
+RightChild.ClassCounts: 55 13 14 0 0 1 
+
+minGini: 38.550000 - 6
+Region.size: 83
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 80
+RightChild.ClassCounts: 55 13 11 0 0 1 
+
+minGini: 34.586666 - 0
+Region.size: 80
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 2 3 0 0 0 
+RightChild.size: 75
+RightChild.ClassCounts: 55 11 8 0 0 1 
+
+minGini: 29.402735 - 3
+Region.size: 75
+LeftChild.size: 47
+LeftChild.ClassCounts: 29 10 8 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 26 1 0 0 0 1 
+
+minGini: 1.925925 - 2
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 26 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 27
+LeftChild.size: 26
+LeftChild.ClassCounts: 26 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 22.870588 - 1
+Region.size: 47
+LeftChild.size: 17
+LeftChild.ClassCounts: 9 8 0 0 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 20 2 8 0 0 0 
+
+minGini: 11.111111 - 0
+Region.size: 30
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 27
+RightChild.ClassCounts: 20 2 5 0 0 0 
+
+minGini: 8.000000 - 6
+Region.size: 27
+LeftChild.size: 25
+LeftChild.ClassCounts: 20 0 5 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 5.882352 - 1
+Region.size: 25
+LeftChild.size: 17
+LeftChild.ClassCounts: 16 0 1 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 4 0 4 0 0 0 
+
+minGini: 2.666666 - 4
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 1.600000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 0 1 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 7
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 3.272727 - 2
+Region.size: 17
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 1.800000 - 1
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 2.400000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 3 0 0 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+minGini: 19.080000 - 3
+Region.size: 56
+LeftChild.size: 50
+LeftChild.ClassCounts: 10 38 1 0 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 6 0 0 
+
+minGini: 10.833333 - 4
+Region.size: 50
+LeftChild.size: 36
+LeftChild.ClassCounts: 1 34 1 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 9 4 0 0 1 0 
+
+minGini: 1.600000 - 4
+Region.size: 14
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 1.942857 - 0
+Region.size: 36
+LeftChild.size: 35
+LeftChild.ClassCounts: 0 34 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 35
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 34
+RightChild.ClassCounts: 0 34 0 0 0 0 
+
+
+
+Tree Number: 9 finished.
+
+minGini: 132.665028 - 2
+Region.size: 214
+LeftChild.size: 66
+LeftChild.ClassCounts: 0 12 0 15 10 29 
+RightChild.size: 148
+RightChild.ClassCounts: 57 75 15 0 0 1 
+
+minGini: 74.899304 - 3
+Region.size: 148
+LeftChild.size: 95
+LeftChild.ClassCounts: 49 33 13 0 0 0 
+RightChild.size: 53
+RightChild.ClassCounts: 8 42 2 0 0 1 
+
+minGini: 11.944444 - 8
+Region.size: 53
+LeftChild.size: 44
+LeftChild.ClassCounts: 2 40 1 0 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 6 2 1 0 0 0 
+
+minGini: 3.000000 - 4
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 0 0 0 0 
+
+minGini: 1.714285 - 4
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 5.674418 - 0
+Region.size: 44
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 43
+RightChild.ClassCounts: 2 40 1 0 0 0 
+
+minGini: 5.274509 - 1
+Region.size: 43
+LeftChild.size: 34
+LeftChild.ClassCounts: 1 33 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 7 1 0 0 0 
+
+minGini: 1.750000 - 3
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 0 0 0 0 
+
+minGini: 1.333333 - 5
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.600000 - 3
+Region.size: 34
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 29 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 50.141666 - 8
+Region.size: 95
+LeftChild.size: 80
+LeftChild.ClassCounts: 47 21 12 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 2 12 1 0 0 0 
+
+minGini: 3.428571 - 0
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 2 12 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 3.000000 - 4
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 2 6 0 0 0 0 
+
+minGini: 1.714285 - 3
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 0.000000 - 7
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 37.066666 - 6
+Region.size: 80
+LeftChild.size: 20
+LeftChild.ClassCounts: 4 13 3 0 0 0 
+RightChild.size: 60
+RightChild.ClassCounts: 43 8 9 0 0 0 
+
+minGini: 22.352941 - 3
+Region.size: 60
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 2 5 0 0 0 
+RightChild.size: 51
+RightChild.ClassCounts: 41 6 4 0 0 0 
+
+minGini: 15.657142 - 1
+Region.size: 51
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 0 0 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 25 6 4 0 0 0 
+
+minGini: 10.080000 - 6
+Region.size: 35
+LeftChild.size: 10
+LeftChild.ClassCounts: 2 4 4 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 23 2 0 0 0 0 
+
+minGini: 1.916666 - 5
+Region.size: 25
+LeftChild.size: 24
+LeftChild.ClassCounts: 23 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 24
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 2.666666 - 2
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 0 4 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 
+
+minGini: 2.857142 - 6
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 0 5 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 
+
+minGini: 7.272727 - 2
+Region.size: 20
+LeftChild.size: 11
+LeftChild.ClassCounts: 4 4 3 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 0 0 0 
+
+minGini: 4.000000 - 6
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 4 4 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 32.432330 - 6
+Region.size: 66
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 0 0 4 5 29 
+RightChild.size: 28
+RightChild.ClassCounts: 0 12 0 11 5 0 
+
+minGini: 10.051282 - 1
+Region.size: 28
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 2 0 11 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 10 0 0 5 0 
+
+minGini: 1.666666 - 6
+Region.size: 15
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 1 0 0 5 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.833333 - 4
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 1 0 11 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 0 0 11 0 0 
+
+minGini: 10.228571 - 5
+Region.size: 38
+LeftChild.size: 35
+LeftChild.ClassCounts: 0 0 0 1 5 29 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 3 0 0 
+
+minGini: 5.241935 - 2
+Region.size: 35
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 0 0 0 2 29 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 1 3 0 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 2.000000 - 7
+Region.size: 31
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 2 2 
+RightChild.size: 27
+RightChild.ClassCounts: 0 0 0 0 0 27 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+
+
+Tree Number: 10 finished.
+
+minGini: 137.609195 - 3
+Region.size: 214
+LeftChild.size: 174
+LeftChild.ClassCounts: 67 75 18 6 5 3 
+RightChild.size: 40
+RightChild.ClassCounts: 0 5 1 9 2 23 
+
+minGini: 14.122762 - 5
+Region.size: 40
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 0 0 0 2 21 
+RightChild.size: 17
+RightChild.ClassCounts: 0 5 1 9 0 2 
+
+minGini: 6.939393 - 2
+Region.size: 17
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 2 0 9 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 3 1 0 0 2 
+
+minGini: 1.333333 - 2
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 1 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 0.000000 - 0
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 9 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 23
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 2 1 
+RightChild.size: 20
+RightChild.ClassCounts: 0 0 0 0 0 20 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 96.134053 - 0
+Region.size: 174
+LeftChild.size: 57
+LeftChild.ClassCounts: 5 44 6 0 2 0 
+RightChild.size: 117
+RightChild.ClassCounts: 62 31 12 6 3 3 
+
+minGini: 62.112371 - 6
+Region.size: 117
+LeftChild.size: 97
+LeftChild.ClassCounts: 62 18 12 0 2 3 
+RightChild.size: 20
+RightChild.ClassCounts: 0 13 0 6 1 0 
+
+minGini: 3.560439 - 3
+Region.size: 20
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 12 0 0 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 1 0 6 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 6 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 13
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 1 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 48.882758 - 8
+Region.size: 97
+LeftChild.size: 87
+LeftChild.ClassCounts: 60 14 8 0 2 3 
+RightChild.size: 10
+RightChild.ClassCounts: 2 4 4 0 0 0 
+
+minGini: 2.666666 - 0
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 36.318534 - 0
+Region.size: 87
+LeftChild.size: 34
+LeftChild.ClassCounts: 33 0 1 0 0 0 
+RightChild.size: 53
+RightChild.ClassCounts: 27 14 7 0 2 3 
+
+minGini: 25.540000 - 5
+Region.size: 53
+LeftChild.size: 25
+LeftChild.ClassCounts: 21 0 2 0 2 0 
+RightChild.size: 28
+RightChild.ClassCounts: 6 14 5 0 0 3 
+
+minGini: 13.428571 - 4
+Region.size: 28
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 0 5 0 0 1 
+RightChild.size: 21
+RightChild.ClassCounts: 5 14 0 0 0 2 
+
+minGini: 7.368421 - 0
+Region.size: 21
+LeftChild.size: 19
+LeftChild.ClassCounts: 5 14 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 5.833333 - 3
+Region.size: 19
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 5 7 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 0 0 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 3.200000 - 5
+Region.size: 25
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 0 2 0 2 0 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 0 0 0 0 
+
+minGini: 1.333333 - 3
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 34
+LeftChild.size: 33
+LeftChild.ClassCounts: 33 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 18.690909 - 5
+Region.size: 57
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 
+RightChild.size: 55
+RightChild.ClassCounts: 5 44 6 0 0 0 
+
+minGini: 16.877551 - 0
+Region.size: 55
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 0 0 0 0 
+RightChild.size: 49
+RightChild.ClassCounts: 2 41 6 0 0 0 
+
+minGini: 9.244019 - 4
+Region.size: 49
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 5 6 0 0 0 
+RightChild.size: 38
+RightChild.ClassCounts: 2 36 0 0 0 0 
+
+minGini: 2.400000 - 3
+Region.size: 38
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 0 0 0 0 
+RightChild.size: 33
+RightChild.ClassCounts: 0 33 0 0 0 0 
+
+minGini: 1.333333 - 8
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 6 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+
+
+Tree Number: 11 finished.
+
+minGini: 135.962347 - 1
+Region.size: 214
+LeftChild.size: 172
+LeftChild.ClassCounts: 59 74 15 18 1 5 
+RightChild.size: 42
+RightChild.ClassCounts: 3 2 1 0 6 30 
+
+minGini: 9.076923 - 7
+Region.size: 42
+LeftChild.size: 13
+LeftChild.ClassCounts: 3 2 1 0 6 1 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 0 0 0 29 
+
+minGini: 5.800000 - 4
+Region.size: 13
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 0 1 0 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 0 2 0 0 6 0 
+
+minGini: 0.000000 - 8
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 1 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 102.943643 - 6
+Region.size: 172
+LeftChild.size: 63
+LeftChild.ClassCounts: 9 46 1 4 0 3 
+RightChild.size: 109
+RightChild.ClassCounts: 50 28 14 14 1 2 
+
+minGini: 61.140871 - 2
+Region.size: 109
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 10 0 14 1 1 
+RightChild.size: 83
+RightChild.ClassCounts: 50 18 14 0 0 1 
+
+minGini: 43.000000 - 6
+Region.size: 83
+LeftChild.size: 70
+LeftChild.ClassCounts: 37 18 14 0 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 0 0 0 0 
+
+minGini: 35.636363 - 3
+Region.size: 70
+LeftChild.size: 55
+LeftChild.ClassCounts: 36 8 10 0 0 1 
+RightChild.size: 15
+RightChild.ClassCounts: 1 10 4 0 0 0 
+
+minGini: 4.444444 - 1
+Region.size: 15
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 2 4 0 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 24.898809 - 5
+Region.size: 55
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 0 5 0 0 0 
+RightChild.size: 48
+RightChild.ClassCounts: 34 8 5 0 0 1 
+
+minGini: 18.272727 - 3
+Region.size: 48
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 3 1 0 0 0 
+RightChild.size: 44
+RightChild.ClassCounts: 34 5 4 0 0 1 
+
+minGini: 13.034920 - 0
+Region.size: 44
+LeftChild.size: 9
+LeftChild.ClassCounts: 3 2 4 0 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 31 3 0 0 0 1 
+
+minGini: 1.937500 - 2
+Region.size: 35
+LeftChild.size: 32
+LeftChild.ClassCounts: 31 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 32
+LeftChild.size: 31
+LeftChild.ClassCounts: 31 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 3.428571 - 2
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 0 4 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.600000 - 8
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 0 4 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 1.000000 - 2
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 10.380952 - 6
+Region.size: 26
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 5 0 14 1 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 6.676470 - 3
+Region.size: 21
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 3 0 0 0 1 
+RightChild.size: 17
+RightChild.ClassCounts: 0 2 0 14 1 0 
+
+minGini: 1.333333 - 1
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 0 0 14 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 21.593220 - 3
+Region.size: 63
+LeftChild.size: 59
+LeftChild.ClassCounts: 9 46 1 0 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 4 0 0 
+
+minGini: 15.817610 - 2
+Region.size: 59
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 0 1 0 0 3 
+RightChild.size: 53
+RightChild.ClassCounts: 7 46 0 0 0 0 
+
+minGini: 9.019607 - 0
+Region.size: 53
+LeftChild.size: 51
+LeftChild.ClassCounts: 5 46 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 7.500000 - 2
+Region.size: 51
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 31 0 0 0 0 
+RightChild.size: 20
+RightChild.ClassCounts: 5 15 0 0 0 0 
+
+minGini: 3.529411 - 1
+Region.size: 20
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 2 15 0 0 0 0 
+
+minGini: 1.875000 - 6
+Region.size: 17
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 1 15 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 0 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 2 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+
+
+Tree Number: 12 finished.
+
+minGini: 138.253479 - 1
+Region.size: 214
+LeftChild.size: 175
+LeftChild.ClassCounts: 79 62 17 9 1 7 
+RightChild.size: 39
+RightChild.ClassCounts: 3 5 1 0 7 23 
+
+minGini: 16.076923 - 3
+Region.size: 39
+LeftChild.size: 13
+LeftChild.ClassCounts: 3 2 1 0 6 1 
+RightChild.size: 26
+RightChild.ClassCounts: 0 3 0 0 1 22 
+
+minGini: 3.409090 - 5
+Region.size: 26
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 0 0 0 1 21 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 0 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 1.000000 - 4
+Region.size: 22
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 1 1 
+RightChild.size: 20
+RightChild.ClassCounts: 0 0 0 0 0 20 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 6.727272 - 3
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 3 0 1 0 6 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 3.214285 - 2
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 6 1 
+RightChild.size: 4
+RightChild.ClassCounts: 3 0 1 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 103.916715 - 0
+Region.size: 175
+LeftChild.size: 59
+LeftChild.ClassCounts: 11 34 8 1 0 5 
+RightChild.size: 116
+RightChild.ClassCounts: 68 28 9 8 1 2 
+
+minGini: 57.862706 - 6
+Region.size: 116
+LeftChild.size: 101
+LeftChild.ClassCounts: 68 20 9 1 1 2 
+RightChild.size: 15
+RightChild.ClassCounts: 0 8 0 7 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 15
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 7 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 0 0 0 0 
+
+minGini: 44.886597 - 3
+Region.size: 101
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 
+RightChild.size: 97
+RightChild.ClassCounts: 68 20 5 1 1 2 
+
+minGini: 40.194139 - 3
+Region.size: 97
+LeftChild.size: 91
+LeftChild.ClassCounts: 68 18 2 0 1 2 
+RightChild.size: 6
+RightChild.ClassCounts: 0 2 3 1 0 0 
+
+minGini: 1.333333 - 2
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 1 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 30.254320 - 8
+Region.size: 91
+LeftChild.size: 81
+LeftChild.ClassCounts: 66 11 1 0 1 2 
+RightChild.size: 10
+RightChild.ClassCounts: 2 7 1 0 0 0 
+
+minGini: 3.111111 - 0
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 7 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 2.000000 - 8
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 21.222535 - 2
+Region.size: 81
+LeftChild.size: 71
+LeftChild.ClassCounts: 62 5 1 0 1 2 
+RightChild.size: 10
+RightChild.ClassCounts: 4 6 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 14.392156 - 7
+Region.size: 71
+LeftChild.size: 68
+LeftChild.ClassCounts: 61 3 1 0 1 2 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 0 0 0 0 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 12.484848 - 1
+Region.size: 68
+LeftChild.size: 44
+LeftChild.ClassCounts: 42 2 0 0 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 19 1 1 0 1 2 
+
+minGini: 4.400000 - 2
+Region.size: 24
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 0 0 1 2 
+RightChild.size: 20
+RightChild.ClassCounts: 19 0 1 0 0 0 
+
+minGini: 1.600000 - 0
+Region.size: 20
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 0 1 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 2.952380 - 2
+Region.size: 44
+LeftChild.size: 42
+LeftChild.ClassCounts: 41 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 1.714285 - 4
+Region.size: 42
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 0 0 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 35 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 30.451690 - 2
+Region.size: 59
+LeftChild.size: 23
+LeftChild.ClassCounts: 9 7 1 1 0 5 
+RightChild.size: 36
+RightChild.ClassCounts: 2 27 7 0 0 0 
+
+minGini: 3.724137 - 3
+Region.size: 36
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 7 0 0 0 
+RightChild.size: 29
+RightChild.ClassCounts: 2 27 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 29
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 27 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 8.571428 - 2
+Region.size: 23
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 7 1 1 0 5 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 0 0 0 0 
+
+minGini: 4.800000 - 2
+Region.size: 14
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 4 
+RightChild.size: 10
+RightChild.ClassCounts: 0 7 1 1 0 1 
+
+minGini: 2.750000 - 7
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 7 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 1 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 1 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+
+
+Tree Number: 13 finished.
+
+minGini: 135.198168 - 3
+Region.size: 214
+LeftChild.size: 130
+LeftChild.ClassCounts: 78 33 12 1 5 1 
+RightChild.size: 84
+RightChild.ClassCounts: 4 34 4 11 9 22 
+
+minGini: 42.427884 - 5
+Region.size: 84
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 1 0 0 9 22 
+RightChild.size: 52
+RightChild.ClassCounts: 4 33 4 11 0 0 
+
+minGini: 23.968102 - 6
+Region.size: 52
+LeftChild.size: 33
+LeftChild.ClassCounts: 4 26 0 3 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 7 4 8 0 0 
+
+minGini: 9.066666 - 1
+Region.size: 19
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 3 4 8 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 4.363636 - 4
+Region.size: 15
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 3 0 8 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 8 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 6.879310 - 6
+Region.size: 33
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 0 0 3 0 0 
+RightChild.size: 29
+RightChild.ClassCounts: 3 26 0 0 0 0 
+
+minGini: 4.703703 - 1
+Region.size: 29
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 
+RightChild.size: 27
+RightChild.ClassCounts: 2 25 0 0 0 0 
+
+minGini: 3.571428 - 5
+Region.size: 27
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 0 0 0 0 
+RightChild.size: 21
+RightChild.ClassCounts: 1 20 0 0 0 0 
+
+minGini: 1.666666 - 2
+Region.size: 21
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 3 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 1.800000 - 7
+Region.size: 32
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 1 0 0 9 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 0 0 0 0 22 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 9 0 
+
+minGini: 66.150000 - 6
+Region.size: 130
+LeftChild.size: 120
+LeftChild.ClassCounts: 78 25 12 0 4 1 
+RightChild.size: 10
+RightChild.ClassCounts: 0 8 0 1 1 0 
+
+minGini: 1.777777 - 3
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 8 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 1.500000 - 4
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 0 0 1 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 53.705961 - 6
+Region.size: 120
+LeftChild.size: 23
+LeftChild.ClassCounts: 6 14 1 0 2 0 
+RightChild.size: 97
+RightChild.ClassCounts: 72 11 11 0 2 1 
+
+minGini: 34.621568 - 0
+Region.size: 97
+LeftChild.size: 12
+LeftChild.ClassCounts: 3 2 7 0 0 0 
+RightChild.size: 85
+RightChild.ClassCounts: 69 9 4 0 2 1 
+
+minGini: 24.457831 - 2
+Region.size: 85
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 
+RightChild.size: 83
+RightChild.ClassCounts: 69 9 4 0 0 1 
+
+minGini: 20.204545 - 5
+Region.size: 83
+LeftChild.size: 72
+LeftChild.ClassCounts: 64 3 4 0 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 5 6 0 0 0 0 
+
+minGini: 1.666666 - 4
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 13.014084 - 8
+Region.size: 72
+LeftChild.size: 71
+LeftChild.ClassCounts: 64 2 4 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 12.357710 - 1
+Region.size: 71
+LeftChild.size: 37
+LeftChild.ClassCounts: 36 1 0 0 0 0 
+RightChild.size: 34
+RightChild.ClassCounts: 28 1 4 0 0 1 
+
+minGini: 3.800000 - 4
+Region.size: 34
+LeftChild.size: 30
+LeftChild.ClassCounts: 28 1 0 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 30
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 0 1 
+RightChild.size: 28
+RightChild.ClassCounts: 28 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 1.500000 - 2
+Region.size: 37
+LeftChild.size: 33
+LeftChild.ClassCounts: 33 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 3.666666 - 4
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 3 2 1 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 1 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 9.733333 - 2
+Region.size: 23
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 1 0 2 0 
+RightChild.size: 20
+RightChild.ClassCounts: 6 14 0 0 0 0 
+
+minGini: 5.066666 - 3
+Region.size: 20
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 2 13 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 15
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+
+
+Tree Number: 14 finished.
+
+minGini: 138.994535 - 6
+Region.size: 214
+LeftChild.size: 61
+LeftChild.ClassCounts: 8 45 0 3 1 4 
+RightChild.size: 153
+RightChild.ClassCounts: 66 28 15 10 9 25 
+
+minGini: 93.639006 - 1
+Region.size: 153
+LeftChild.size: 127
+LeftChild.ClassCounts: 65 27 15 10 6 4 
+RightChild.size: 26
+RightChild.ClassCounts: 1 1 0 0 3 21 
+
+minGini: 6.751879 - 4
+Region.size: 26
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 1 0 0 2 3 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 0 0 1 18 
+
+minGini: 0.000000 - 6
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 0 0 0 0 18 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 2.500000 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 1 0 0 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 
+
+minGini: 1.000000 - 3
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 74.005852 - 0
+Region.size: 127
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 9 9 1 0 4 
+RightChild.size: 104
+RightChild.ClassCounts: 65 18 6 9 6 0 
+
+minGini: 51.210256 - 0
+Region.size: 104
+LeftChild.size: 39
+LeftChild.ClassCounts: 36 1 2 0 0 0 
+RightChild.size: 65
+RightChild.ClassCounts: 29 17 4 9 6 0 
+
+minGini: 36.322654 - 3
+Region.size: 65
+LeftChild.size: 46
+LeftChild.ClassCounts: 29 12 4 0 1 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 5 0 9 5 0 
+
+minGini: 6.428571 - 5
+Region.size: 19
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 5 0 9 0 0 
+
+minGini: 3.272727 - 6
+Region.size: 14
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 2 0 9 0 0 
+
+minGini: 1.800000 - 1
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 1 0 9 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 9 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 16.539473 - 2
+Region.size: 46
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 7 0 0 1 0 
+RightChild.size: 38
+RightChild.ClassCounts: 29 5 4 0 0 0 
+
+minGini: 8.562500 - 8
+Region.size: 38
+LeftChild.size: 32
+LeftChild.ClassCounts: 29 2 1 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 3 3 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 3.806451 - 4
+Region.size: 32
+LeftChild.size: 31
+LeftChild.ClassCounts: 29 1 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 3.425925 - 6
+Region.size: 31
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 0 0 0 0 
+RightChild.size: 27
+RightChild.ClassCounts: 26 0 1 0 0 0 
+
+minGini: 1.500000 - 3
+Region.size: 27
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 0 1 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 23 0 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 3.789473 - 5
+Region.size: 39
+LeftChild.size: 38
+LeftChild.ClassCounts: 36 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.945945 - 4
+Region.size: 38
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 37
+RightChild.ClassCounts: 36 0 1 0 0 0 
+
+minGini: 1.750000 - 2
+Region.size: 37
+LeftChild.size: 29
+LeftChild.ClassCounts: 29 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 7 0 1 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 0 0 0 0 
+
+minGini: 8.569230 - 2
+Region.size: 23
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 8 0 1 0 4 
+RightChild.size: 10
+RightChild.ClassCounts: 0 1 9 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 9 0 0 0 
+
+minGini: 1.600000 - 2
+Region.size: 13
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 1 0 4 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 0 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 1 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 14.701923 - 6
+Region.size: 61
+LeftChild.size: 13
+LeftChild.ClassCounts: 5 0 0 3 1 4 
+RightChild.size: 48
+RightChild.ClassCounts: 3 45 0 0 0 0 
+
+minGini: 3.829787 - 3
+Region.size: 48
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 47
+RightChild.ClassCounts: 2 45 0 0 0 0 
+
+minGini: 1.333333 - 8
+Region.size: 47
+LeftChild.size: 44
+LeftChild.ClassCounts: 0 44 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 5.095238 - 3
+Region.size: 13
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 0 0 0 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 3 0 4 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 3 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 
+
+minGini: 0.000000 - 3
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 
+
+
+
+Tree Number: 15 finished.
+
+minGini: 138.938801 - 3
+Region.size: 214
+LeftChild.size: 123
+LeftChild.ClassCounts: 67 36 13 2 3 2 
+RightChild.size: 91
+RightChild.ClassCounts: 2 41 8 12 6 22 
+
+minGini: 45.169230 - 1
+Region.size: 91
+LeftChild.size: 65
+LeftChild.ClassCounts: 2 39 8 12 4 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 2 0 0 2 22 
+
+minGini: 3.200000 - 7
+Region.size: 26
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 2 0 0 2 1 
+RightChild.size: 21
+RightChild.ClassCounts: 0 0 0 0 0 21 
+
+minGini: 1.333333 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 31.123983 - 4
+Region.size: 65
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 6 8 7 3 0 
+RightChild.size: 41
+RightChild.ClassCounts: 2 33 0 5 1 0 
+
+minGini: 5.438095 - 0
+Region.size: 41
+LeftChild.size: 35
+LeftChild.ClassCounts: 2 33 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 5 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 5 0 0 
+
+minGini: 1.941176 - 2
+Region.size: 35
+LeftChild.size: 34
+LeftChild.ClassCounts: 1 33 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 1.000000 - 8
+Region.size: 34
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 32 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 13.052631 - 4
+Region.size: 24
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 5 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 6 8 2 3 0 
+
+minGini: 7.977777 - 6
+Region.size: 19
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 1 8 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 5 0 2 3 0 
+
+minGini: 2.857142 - 5
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 5 0 2 0 0 
+
+minGini: 1.666666 - 5
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 5 0 1 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 1 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 8 0 0 0 
+
+minGini: 65.209766 - 2
+Region.size: 123
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 11 0 2 3 1 
+RightChild.size: 106
+RightChild.ClassCounts: 67 25 13 0 0 1 
+
+minGini: 49.611368 - 0
+Region.size: 106
+LeftChild.size: 17
+LeftChild.ClassCounts: 4 4 9 0 0 0 
+RightChild.size: 89
+RightChild.ClassCounts: 63 21 4 0 0 1 
+
+minGini: 29.756962 - 2
+Region.size: 89
+LeftChild.size: 79
+LeftChild.ClassCounts: 63 13 2 0 0 1 
+RightChild.size: 10
+RightChild.ClassCounts: 0 8 2 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 22.205479 - 7
+Region.size: 79
+LeftChild.size: 73
+LeftChild.ClassCounts: 62 9 1 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 1 4 1 0 0 0 
+
+minGini: 1.600000 - 4
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 16.246973 - 5
+Region.size: 73
+LeftChild.size: 59
+LeftChild.ClassCounts: 54 3 1 0 0 1 
+RightChild.size: 14
+RightChild.ClassCounts: 8 6 0 0 0 0 
+
+minGini: 1.777777 - 4
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 8 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 0 0 0 0 
+
+minGini: 7.620689 - 4
+Region.size: 59
+LeftChild.size: 58
+LeftChild.ClassCounts: 54 2 1 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 6.750000 - 1
+Region.size: 58
+LeftChild.size: 56
+LeftChild.ClassCounts: 53 2 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 5.228282 - 2
+Region.size: 56
+LeftChild.size: 45
+LeftChild.ClassCounts: 44 0 0 0 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 9 2 0 0 0 0 
+
+minGini: 1.800000 - 2
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 9 1 0 0 0 0 
+
+minGini: 1.500000 - 4
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.800000 - 5
+Region.size: 45
+LeftChild.size: 35
+LeftChild.ClassCounts: 35 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 9 0 0 0 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 6.454545 - 6
+Region.size: 17
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 1 1 9 0 0 0 
+
+minGini: 1.800000 - 3
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 1 9 0 0 0 
+
+minGini: 1.500000 - 0
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 3 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 6.266666 - 3
+Region.size: 17
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 11 0 0 3 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 
+
+minGini: 3.166666 - 6
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 2 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 11 0 0 1 0 
+
+minGini: 1.666666 - 5
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 5 0 0 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 0 0 1 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+
+
+Tree Number: 16 finished.
+
+minGini: 123.519504 - 7
+Region.size: 214
+LeftChild.size: 181
+LeftChild.ClassCounts: 66 77 16 13 6 3 
+RightChild.size: 33
+RightChild.ClassCounts: 0 0 0 1 0 32 
+
+minGini: 0.000000 - 3
+Region.size: 33
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 0 0 0 0 32 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 108.230303 - 2
+Region.size: 181
+LeftChild.size: 55
+LeftChild.ClassCounts: 2 31 0 13 6 3 
+RightChild.size: 126
+RightChild.ClassCounts: 64 46 16 0 0 0 
+
+minGini: 61.182692 - 0
+Region.size: 126
+LeftChild.size: 48
+LeftChild.ClassCounts: 9 30 9 0 0 0 
+RightChild.size: 78
+RightChild.ClassCounts: 55 16 7 0 0 0 
+
+minGini: 27.983942 - 8
+Region.size: 78
+LeftChild.size: 59
+LeftChild.ClassCounts: 49 5 5 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 6 11 2 0 0 0 
+
+minGini: 5.600000 - 4
+Region.size: 19
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 6 2 2 0 0 0 
+
+minGini: 2.000000 - 1
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 2 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 16.153846 - 1
+Region.size: 59
+LeftChild.size: 20
+LeftChild.ClassCounts: 20 0 0 0 0 0 
+RightChild.size: 39
+RightChild.ClassCounts: 29 5 5 0 0 0 
+
+minGini: 13.220779 - 5
+Region.size: 39
+LeftChild.size: 28
+LeftChild.ClassCounts: 24 0 4 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 5 5 1 0 0 0 
+
+minGini: 4.250000 - 2
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 5 2 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 3.142857 - 0
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 1 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 2.500000 - 4
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 1 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 1.333333 - 8
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 5.714285 - 5
+Region.size: 28
+LeftChild.size: 14
+LeftChild.ClassCounts: 10 0 4 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 0 0 0 0 
+
+minGini: 1.818181 - 4
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 10 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 18.218181 - 6
+Region.size: 48
+LeftChild.size: 33
+LeftChild.ClassCounts: 6 27 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 3 3 9 0 0 0 
+
+minGini: 4.500000 - 3
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 3 9 0 0 0 
+
+minGini: 1.500000 - 1
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 3 1 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 8 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 5.314285 - 1
+Region.size: 33
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 0 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 2 26 0 0 0 0 
+
+minGini: 2.400000 - 5
+Region.size: 28
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 0 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 23 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 28.841397 - 3
+Region.size: 55
+LeftChild.size: 24
+LeftChild.ClassCounts: 2 19 0 0 2 1 
+RightChild.size: 31
+RightChild.ClassCounts: 0 12 0 13 4 2 
+
+minGini: 17.260869 - 3
+Region.size: 31
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 6 2 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 12 0 7 2 2 
+
+minGini: 9.338461 - 3
+Region.size: 23
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 11 0 1 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 1 0 6 1 2 
+
+minGini: 2.500000 - 1
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 6 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 0 1 2 
+
+minGini: 1.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 1.833333 - 4
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 11 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 1.714285 - 4
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 6 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 6 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 7.733333 - 3
+Region.size: 24
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 2 10 0 0 2 1 
+
+minGini: 6.428571 - 4
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 1 10 0 0 2 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 4.923076 - 0
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 1 10 0 0 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 4.000000 - 8
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 4 0 0 2 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 1.600000 - 5
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 0 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+
+
+Tree Number: 17 finished.
+
+minGini: 129.125334 - 5
+Region.size: 214
+LeftChild.size: 41
+LeftChild.ClassCounts: 3 5 3 0 7 23 
+RightChild.size: 173
+RightChild.ClassCounts: 63 89 10 8 0 3 
+
+minGini: 75.811497 - 3
+Region.size: 173
+LeftChild.size: 88
+LeftChild.ClassCounts: 58 23 6 0 0 1 
+RightChild.size: 85
+RightChild.ClassCounts: 5 66 4 8 0 2 
+
+minGini: 27.822649 - 2
+Region.size: 85
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 6 0 7 0 0 
+RightChild.size: 72
+RightChild.ClassCounts: 5 60 4 1 0 2 
+
+minGini: 18.705882 - 5
+Region.size: 72
+LeftChild.size: 68
+LeftChild.ClassCounts: 5 59 4 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 1 0 2 
+
+minGini: 1.333333 - 7
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 14.685284 - 6
+Region.size: 68
+LeftChild.size: 49
+LeftChild.ClassCounts: 3 46 0 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 2 13 4 0 0 0 
+
+minGini: 2.666666 - 2
+Region.size: 19
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 2 0 4 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 5.000000 - 4
+Region.size: 49
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 31 0 0 0 0 
+RightChild.size: 18
+RightChild.ClassCounts: 3 15 0 0 0 0 
+
+minGini: 3.200000 - 8
+Region.size: 18
+LeftChild.size: 15
+LeftChild.ClassCounts: 1 14 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 0 0 0 0 
+
+minGini: 3.111111 - 1
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 2 0 7 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 7 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 37.294532 - 8
+Region.size: 88
+LeftChild.size: 81
+LeftChild.ClassCounts: 58 17 5 0 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 0 6 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 30.779220 - 0
+Region.size: 81
+LeftChild.size: 77
+LeftChild.ClassCounts: 58 13 5 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 27.154929 - 0
+Region.size: 77
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 1 3 0 0 1 
+RightChild.size: 71
+RightChild.ClassCounts: 57 12 2 0 0 0 
+
+minGini: 21.091362 - 3
+Region.size: 71
+LeftChild.size: 43
+LeftChild.ClassCounts: 30 11 2 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 27 1 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 27 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 15.800000 - 2
+Region.size: 43
+LeftChild.size: 40
+LeftChild.ClassCounts: 30 8 2 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 12.363636 - 0
+Region.size: 40
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 12 8 2 0 0 0 
+
+minGini: 3.428571 - 5
+Region.size: 22
+LeftChild.size: 14
+LeftChild.ClassCounts: 12 0 2 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 0 0 0 0 
+
+minGini: 1.846153 - 6
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 12 0 1 0 0 0 
+
+minGini: 1.500000 - 5
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 0 1 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 0 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 2.500000 - 6
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 3 0 0 1 
+
+minGini: 1.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 1 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 12.888888 - 7
+Region.size: 41
+LeftChild.size: 18
+LeftChild.ClassCounts: 3 5 3 0 7 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 0 0 0 0 23 
+
+minGini: 8.833333 - 2
+Region.size: 18
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 5 0 0 7 0 
+RightChild.size: 6
+RightChild.ClassCounts: 3 0 3 0 0 0 
+
+minGini: 1.500000 - 1
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 0 1 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 3.314285 - 4
+Region.size: 12
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 1 0 0 6 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 1 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+
+
+Tree Number: 18 finished.
+
+minGini: 128.228708 - 7
+Region.size: 214
+LeftChild.size: 182
+LeftChild.ClassCounts: 84 57 14 9 13 5 
+RightChild.size: 32
+RightChild.ClassCounts: 0 3 0 0 0 29 
+
+minGini: 0.000000 - 0
+Region.size: 32
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 0 0 0 0 29 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 110.870588 - 5
+Region.size: 182
+LeftChild.size: 17
+LeftChild.ClassCounts: 3 1 0 0 13 0 
+RightChild.size: 165
+RightChild.ClassCounts: 81 56 14 9 0 5 
+
+minGini: 83.620106 - 3
+Region.size: 165
+LeftChild.size: 103
+LeftChild.ClassCounts: 71 16 11 1 0 4 
+RightChild.size: 62
+RightChild.ClassCounts: 10 40 3 8 0 1 
+
+minGini: 23.890909 - 6
+Region.size: 62
+LeftChild.size: 55
+LeftChild.ClassCounts: 10 40 3 1 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 7 0 0 
+
+minGini: 21.890109 - 1
+Region.size: 55
+LeftChild.size: 13
+LeftChild.ClassCounts: 6 7 0 0 0 0 
+RightChild.size: 42
+RightChild.ClassCounts: 4 33 3 1 0 1 
+
+minGini: 13.150000 - 4
+Region.size: 42
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 1 0 1 
+RightChild.size: 40
+RightChild.ClassCounts: 4 33 3 0 0 0 
+
+minGini: 9.137254 - 6
+Region.size: 40
+LeftChild.size: 34
+LeftChild.ClassCounts: 3 31 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 1 2 3 0 0 0 
+
+minGini: 2.400000 - 3
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 2 3 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 4.800000 - 2
+Region.size: 34
+LeftChild.size: 15
+LeftChild.ClassCounts: 3 12 0 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 19 0 0 0 0 
+
+minGini: 1.500000 - 6
+Region.size: 15
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 13
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 
+
+minGini: 46.033096 - 0
+Region.size: 103
+LeftChild.size: 94
+LeftChild.ClassCounts: 69 13 11 1 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 2 3 0 0 0 4 
+
+minGini: 2.400000 - 3
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 36.016260 - 0
+Region.size: 94
+LeftChild.size: 12
+LeftChild.ClassCounts: 4 2 6 0 0 0 
+RightChild.size: 82
+RightChild.ClassCounts: 65 11 5 1 0 0 
+
+minGini: 25.553246 - 8
+Region.size: 82
+LeftChild.size: 77
+LeftChild.ClassCounts: 64 8 4 1 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 3 1 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 19.554794 - 2
+Region.size: 77
+LeftChild.size: 73
+LeftChild.ClassCounts: 63 5 4 1 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 16.305555 - 3
+Region.size: 73
+LeftChild.size: 72
+LeftChild.ClassCounts: 63 5 4 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 14.619718 - 7
+Region.size: 72
+LeftChild.size: 71
+LeftChild.ClassCounts: 63 5 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 13.720930 - 4
+Region.size: 71
+LeftChild.size: 43
+LeftChild.ClassCounts: 35 5 3 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 28 0 0 0 0 0 
+
+minGini: 11.492307 - 6
+Region.size: 43
+LeftChild.size: 13
+LeftChild.ClassCounts: 7 4 2 0 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 28 1 1 0 0 0 
+
+minGini: 3.520000 - 3
+Region.size: 30
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 0 1 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 24 1 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 25
+LeftChild.size: 24
+LeftChild.ClassCounts: 24 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 5.090909 - 5
+Region.size: 13
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 7 4 0 0 0 0 
+
+minGini: 3.111111 - 1
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 0 0 0 0 
+
+minGini: 2.000000 - 4
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 4.444444 - 3
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 2 6 0 0 0 
+
+minGini: 3.000000 - 8
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 2 6 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 2.000000 - 6
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 2 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.857142 - 4
+Region.size: 17
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 1 0 0 13 0 
+
+minGini: 1.666666 - 3
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 1 0 0 5 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 8 0 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+
+
+Tree Number: 19 finished.
+
+minGini: 130.117054 - 7
+Region.size: 214
+LeftChild.size: 185
+LeftChild.ClassCounts: 64 83 17 13 7 1 
+RightChild.size: 29
+RightChild.ClassCounts: 1 2 0 1 0 25 
+
+minGini: 5.116666 - 5
+Region.size: 29
+LeftChild.size: 24
+LeftChild.ClassCounts: 1 0 0 0 0 23 
+RightChild.size: 5
+RightChild.ClassCounts: 0 2 0 1 0 2 
+
+minGini: 1.333333 - 2
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 1 0 2 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 24
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 0 0 0 0 23 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 108.836037 - 3
+Region.size: 185
+LeftChild.size: 113
+LeftChild.ClassCounts: 58 36 13 2 3 1 
+RightChild.size: 72
+RightChild.ClassCounts: 6 47 4 11 4 0 
+
+minGini: 32.477611 - 4
+Region.size: 72
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 5 0 0 
+RightChild.size: 67
+RightChild.ClassCounts: 6 47 4 6 4 0 
+
+minGini: 26.478927 - 2
+Region.size: 67
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 2 0 6 1 0 
+RightChild.size: 58
+RightChild.ClassCounts: 6 45 4 0 3 0 
+
+minGini: 17.236363 - 5
+Region.size: 58
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 
+RightChild.size: 55
+RightChild.ClassCounts: 6 45 4 0 0 0 
+
+minGini: 16.031830 - 5
+Region.size: 55
+LeftChild.size: 26
+LeftChild.ClassCounts: 4 18 4 0 0 0 
+RightChild.size: 29
+RightChild.ClassCounts: 2 27 0 0 0 0 
+
+minGini: 2.857142 - 1
+Region.size: 29
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 5 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 22 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 9.066666 - 2
+Region.size: 26
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 16 4 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 0 0 0 0 
+
+minGini: 1.333333 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 4.444444 - 5
+Region.size: 20
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 5 4 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 1.714285 - 3
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 6 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 6 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 62.051679 - 2
+Region.size: 113
+LeftChild.size: 27
+LeftChild.ClassCounts: 5 17 0 2 3 0 
+RightChild.size: 86
+RightChild.ClassCounts: 53 19 13 0 0 1 
+
+minGini: 37.069767 - 6
+Region.size: 86
+LeftChild.size: 43
+LeftChild.ClassCounts: 15 18 10 0 0 0 
+RightChild.size: 43
+RightChild.ClassCounts: 38 1 3 0 0 1 
+
+minGini: 8.141025 - 0
+Region.size: 43
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 1 1 0 0 0 
+RightChild.size: 39
+RightChild.ClassCounts: 36 0 2 0 0 1 
+
+minGini: 5.307692 - 1
+Region.size: 39
+LeftChild.size: 26
+LeftChild.ClassCounts: 25 0 0 0 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 11 0 2 0 0 0 
+
+minGini: 1.833333 - 0
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 11 0 1 0 0 0 
+
+minGini: 1.500000 - 2
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 26
+LeftChild.size: 25
+LeftChild.ClassCounts: 25 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 1.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 19.856410 - 0
+Region.size: 43
+LeftChild.size: 13
+LeftChild.ClassCounts: 1 2 10 0 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 14 16 0 0 0 0 
+
+minGini: 3.500000 - 2
+Region.size: 30
+LeftChild.size: 16
+LeftChild.ClassCounts: 14 2 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 0 0 0 0 
+
+minGini: 2.000000 - 4
+Region.size: 16
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 0 0 0 0 
+
+minGini: 1.333333 - 8
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 3.333333 - 3
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 2 10 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 10 0 0 0 
+
+minGini: 9.302631 - 3
+Region.size: 27
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 16 0 0 3 0 
+RightChild.size: 8
+RightChild.ClassCounts: 5 1 0 2 0 0 
+
+minGini: 1.333333 - 5
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 2 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 3.208333 - 3
+Region.size: 19
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 0 2 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 15 0 0 1 0 
+
+minGini: 1.666666 - 6
+Region.size: 16
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 5 0 0 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+
+
+Tree Number: 20 finished.
+
+minGini: 141.402310 - 5
+Region.size: 214
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 4 1 0 12 16 
+RightChild.size: 181
+RightChild.ClassCounts: 70 74 16 10 0 11 
+
+minGini: 113.374331 - 7
+Region.size: 181
+LeftChild.size: 170
+LeftChild.ClassCounts: 70 72 16 9 0 3 
+RightChild.size: 11
+RightChild.ClassCounts: 0 2 0 1 0 8 
+
+minGini: 1.777777 - 7
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 1 0 8 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 0 7 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 1 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 99.235016 - 5
+Region.size: 170
+LeftChild.size: 129
+LeftChild.ClassCounts: 65 43 15 4 0 2 
+RightChild.size: 41
+RightChild.ClassCounts: 5 29 1 5 0 1 
+
+minGini: 11.895238 - 4
+Region.size: 41
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 5 0 1 
+RightChild.size: 35
+RightChild.ClassCounts: 5 29 1 0 0 0 
+
+minGini: 7.214285 - 0
+Region.size: 35
+LeftChild.size: 28
+LeftChild.ClassCounts: 1 26 1 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 4 3 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 2.000000 - 3
+Region.size: 28
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 1 1 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 25 0 0 0 0 
+
+minGini: 1.000000 - 8
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 5 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 70.323897 - 8
+Region.size: 129
+LeftChild.size: 98
+LeftChild.ClassCounts: 60 22 12 2 0 2 
+RightChild.size: 31
+RightChild.ClassCounts: 5 21 3 2 0 0 
+
+minGini: 13.484848 - 5
+Region.size: 31
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 3 2 2 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 3 18 1 0 0 0 
+
+minGini: 5.017543 - 4
+Region.size: 22
+LeftChild.size: 19
+LeftChild.ClassCounts: 1 17 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.888888 - 5
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 1 17 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 1.600000 - 6
+Region.size: 18
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 4.571428 - 4
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 3 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 
+
+minGini: 3.200000 - 0
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 1 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 2.000000 - 0
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 0 2 0 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 0 1 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 48.042635 - 0
+Region.size: 98
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 8 3 0 0 0 
+RightChild.size: 86
+RightChild.ClassCounts: 59 14 9 2 0 2 
+
+minGini: 34.883367 - 2
+Region.size: 86
+LeftChild.size: 23
+LeftChild.ClassCounts: 6 7 6 2 0 2 
+RightChild.size: 63
+RightChild.ClassCounts: 53 7 3 0 0 0 
+
+minGini: 16.146341 - 4
+Region.size: 63
+LeftChild.size: 22
+LeftChild.ClassCounts: 22 0 0 0 0 0 
+RightChild.size: 41
+RightChild.ClassCounts: 31 7 3 0 0 0 
+
+minGini: 8.548611 - 2
+Region.size: 41
+LeftChild.size: 32
+LeftChild.ClassCounts: 29 0 3 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 2 7 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 
+
+minGini: 2.400000 - 2
+Region.size: 32
+LeftChild.size: 27
+LeftChild.ClassCounts: 27 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 2 0 3 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 11.000000 - 1
+Region.size: 23
+LeftChild.size: 16
+LeftChild.ClassCounts: 6 0 6 2 0 2 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 
+
+minGini: 5.600000 - 4
+Region.size: 16
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 6 0 0 2 0 2 
+
+minGini: 4.444444 - 4
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 6 0 0 1 0 2 
+
+minGini: 1.714285 - 1
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 0 0 1 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 0 0 0 
+
+minGini: 3.400000 - 8
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 1 8 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 1.777777 - 4
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 0 0 0 0 
+
+minGini: 10.698529 - 0
+Region.size: 33
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 0 0 0 1 15 
+RightChild.size: 17
+RightChild.ClassCounts: 0 4 1 0 11 1 
+
+minGini: 3.433333 - 3
+Region.size: 17
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 4 1 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 0 0 0 11 1 
+
+minGini: 0.000000 - 4
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 0 0 11 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 0 0 0 0 15 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+
+
+Tree Number: 21 finished.
+
+minGini: 125.239142 - 7
+Region.size: 214
+LeftChild.size: 185
+LeftChild.ClassCounts: 72 76 14 15 4 4 
+RightChild.size: 29
+RightChild.ClassCounts: 0 1 0 0 0 28 
+
+minGini: 0.000000 - 4
+Region.size: 29
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 0 0 0 0 0 28 
+
+minGini: 105.349333 - 0
+Region.size: 185
+LeftChild.size: 60
+LeftChild.ClassCounts: 9 47 1 2 0 1 
+RightChild.size: 125
+RightChild.ClassCounts: 63 29 13 13 4 3 
+
+minGini: 74.668598 - 4
+Region.size: 125
+LeftChild.size: 73
+LeftChild.ClassCounts: 23 24 13 7 3 3 
+RightChild.size: 52
+RightChild.ClassCounts: 40 5 0 6 1 0 
+
+minGini: 9.209523 - 6
+Region.size: 52
+LeftChild.size: 42
+LeftChild.ClassCounts: 40 2 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 3 0 6 1 0 
+
+minGini: 1.500000 - 6
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 3 0 0 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 6 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 2.857142 - 0
+Region.size: 42
+LeftChild.size: 35
+LeftChild.ClassCounts: 35 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 0 0 0 0 
+
+minGini: 1.666666 - 8
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 47.878648 - 2
+Region.size: 73
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 11 7 7 3 3 
+RightChild.size: 42
+RightChild.ClassCounts: 23 13 6 0 0 0 
+
+minGini: 19.102974 - 1
+Region.size: 42
+LeftChild.size: 19
+LeftChild.ClassCounts: 7 12 0 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 16 1 6 0 0 0 
+
+minGini: 6.700000 - 7
+Region.size: 23
+LeftChild.size: 20
+LeftChild.ClassCounts: 16 1 3 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 5.066666 - 6
+Region.size: 20
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 1 2 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 14 0 1 0 0 0 
+
+minGini: 1.000000 - 2
+Region.size: 15
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 1.333333 - 3
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 6.000000 - 5
+Region.size: 19
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 4 12 0 0 0 0 
+
+minGini: 1.846153 - 2
+Region.size: 16
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 1 12 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 0 0 0 0 
+
+minGini: 17.589743 - 3
+Region.size: 31
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 10 0 1 0 2 
+RightChild.size: 18
+RightChild.ClassCounts: 0 1 7 6 3 1 
+
+minGini: 6.727272 - 6
+Region.size: 18
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 7 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 1 0 6 3 1 
+
+minGini: 2.800000 - 1
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 6 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 0 0 3 1 
+
+minGini: 1.000000 - 4
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 1.818181 - 5
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 10 0 1 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 1.000000 - 4
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 1 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 14.506738 - 8
+Region.size: 60
+LeftChild.size: 53
+LeftChild.ClassCounts: 3 46 1 2 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 0 0 0 
+
+minGini: 8.813333 - 2
+Region.size: 53
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 2 0 1 
+RightChild.size: 50
+RightChild.ClassCounts: 3 46 1 0 0 0 
+
+minGini: 6.857142 - 5
+Region.size: 50
+LeftChild.size: 8
+LeftChild.ClassCounts: 2 6 0 0 0 0 
+RightChild.size: 42
+RightChild.ClassCounts: 1 40 1 0 0 0 
+
+minGini: 3.647058 - 4
+Region.size: 42
+LeftChild.size: 17
+LeftChild.ClassCounts: 1 15 1 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 25 0 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 17
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 1 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 2.000000 - 1
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 1 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+
+
+Tree Number: 22 finished.
+
+minGini: 131.096719 - 7
+Region.size: 214
+LeftChild.size: 189
+LeftChild.ClassCounts: 76 76 12 13 11 1 
+RightChild.size: 25
+RightChild.ClassCounts: 1 1 0 1 0 22 
+
+minGini: 2.913043 - 4
+Region.size: 25
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 1 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 1 0 0 0 0 22 
+
+minGini: 0.000000 - 2
+Region.size: 23
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 0 0 0 0 22 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 105.332324 - 3
+Region.size: 189
+LeftChild.size: 113
+LeftChild.ClassCounts: 69 28 10 1 4 1 
+RightChild.size: 76
+RightChild.ClassCounts: 7 48 2 12 7 0 
+
+minGini: 34.825974 - 0
+Region.size: 76
+LeftChild.size: 55
+LeftChild.ClassCounts: 7 43 0 3 2 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 5 2 9 5 0 
+
+minGini: 8.769230 - 4
+Region.size: 21
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 5 2 1 5 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 8 0 0 
+
+minGini: 5.809523 - 2
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 1 0 1 5 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 4 2 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 1.000000 - 5
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 1 0 0 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 15.764705 - 0
+Region.size: 55
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 2 2 0 
+RightChild.size: 51
+RightChild.ClassCounts: 7 43 0 1 0 0 
+
+minGini: 8.538961 - 8
+Region.size: 51
+LeftChild.size: 44
+LeftChild.ClassCounts: 2 41 0 1 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 5.350000 - 0
+Region.size: 44
+LeftChild.size: 40
+LeftChild.ClassCounts: 1 38 0 1 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 0 0 0 0 
+
+minGini: 1.000000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.948717 - 6
+Region.size: 40
+LeftChild.size: 39
+LeftChild.ClassCounts: 1 38 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 1.818181 - 2
+Region.size: 39
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 28 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 1 10 0 0 0 0 
+
+minGini: 1.600000 - 3
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+minGini: 54.826153 - 2
+Region.size: 113
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 7 0 1 4 1 
+RightChild.size: 100
+RightChild.ClassCounts: 69 21 10 0 0 0 
+
+minGini: 42.625000 - 0
+Region.size: 100
+LeftChild.size: 16
+LeftChild.ClassCounts: 5 5 6 0 0 0 
+RightChild.size: 84
+RightChild.ClassCounts: 64 16 4 0 0 0 
+
+minGini: 28.148148 - 1
+Region.size: 84
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 81
+RightChild.ClassCounts: 64 13 4 0 0 0 
+
+minGini: 22.452054 - 2
+Region.size: 81
+LeftChild.size: 73
+LeftChild.ClassCounts: 62 7 4 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 2 6 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 17.518808 - 2
+Region.size: 73
+LeftChild.size: 44
+LeftChild.ClassCounts: 42 1 1 0 0 0 
+RightChild.size: 29
+RightChild.ClassCounts: 20 6 3 0 0 0 
+
+minGini: 10.411111 - 8
+Region.size: 29
+LeftChild.size: 20
+LeftChild.ClassCounts: 17 1 2 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 3 5 1 0 0 0 
+
+minGini: 1.500000 - 6
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 0 1 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 4.703296 - 0
+Region.size: 20
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 0 2 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 12 1 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 44
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 
+RightChild.size: 42
+RightChild.ClassCounts: 42 0 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 5.454545 - 0
+Region.size: 16
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 5 6 0 0 0 
+
+minGini: 3.000000 - 1
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 2 6 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 3.333333 - 5
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 7 0 1 0 1 
+
+minGini: 1.000000 - 4
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 1 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+
+
+Tree Number: 23 finished.
+
+minGini: 136.372340 - 7
+Region.size: 214
+LeftChild.size: 188
+LeftChild.ClassCounts: 66 78 14 17 9 4 
+RightChild.size: 26
+RightChild.ClassCounts: 0 1 0 3 0 22 
+
+minGini: 1.500000 - 4
+Region.size: 26
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 0 3 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 0 0 0 0 22 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 3 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 112.613026 - 3
+Region.size: 188
+LeftChild.size: 116
+LeftChild.ClassCounts: 61 34 13 0 4 4 
+RightChild.size: 72
+RightChild.ClassCounts: 5 44 1 17 5 0 
+
+minGini: 28.367666 - 4
+Region.size: 72
+LeftChild.size: 59
+LeftChild.ClassCounts: 5 44 1 6 3 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 0 11 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 0 11 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+minGini: 18.048979 - 2
+Region.size: 59
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 2 0 6 2 0 
+RightChild.size: 49
+RightChild.ClassCounts: 5 42 1 0 1 0 
+
+minGini: 11.107744 - 3
+Region.size: 49
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 26 1 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 5 16 0 0 1 0 
+
+minGini: 7.230769 - 3
+Region.size: 22
+LeftChild.size: 13
+LeftChild.ClassCounts: 5 7 0 0 1 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 0 0 0 
+
+minGini: 4.600000 - 1
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 2 7 0 0 1 0 
+
+minGini: 1.750000 - 3
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 7 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 1.714285 - 0
+Region.size: 27
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 20 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 6 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 4.000000 - 2
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 2 0 2 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 4 0 0 
+
+minGini: 2.000000 - 0
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 0 2 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 62.215419 - 2
+Region.size: 116
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 12 0 0 4 2 
+RightChild.size: 98
+RightChild.ClassCounts: 61 22 13 0 0 2 
+
+minGini: 48.417582 - 2
+Region.size: 98
+LeftChild.size: 91
+LeftChild.ClassCounts: 61 17 11 0 0 2 
+RightChild.size: 7
+RightChild.ClassCounts: 0 5 2 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 41.492957 - 4
+Region.size: 91
+LeftChild.size: 20
+LeftChild.ClassCounts: 20 0 0 0 0 0 
+RightChild.size: 71
+RightChild.ClassCounts: 41 17 11 0 0 2 
+
+minGini: 36.587096 - 5
+Region.size: 71
+LeftChild.size: 40
+LeftChild.ClassCounts: 16 14 10 0 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 25 3 1 0 0 2 
+
+minGini: 6.203703 - 1
+Region.size: 31
+LeftChild.size: 27
+LeftChild.ClassCounts: 25 2 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 1 0 0 2 
+
+minGini: 1.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 27
+LeftChild.size: 25
+LeftChild.ClassCounts: 25 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 22.514285 - 2
+Region.size: 40
+LeftChild.size: 35
+LeftChild.ClassCounts: 16 9 10 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 19.235294 - 3
+Region.size: 35
+LeftChild.size: 18
+LeftChild.ClassCounts: 6 9 3 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 10 0 7 0 0 0 
+
+minGini: 5.090909 - 4
+Region.size: 17
+LeftChild.size: 11
+LeftChild.ClassCounts: 4 0 7 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 7 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 8.400000 - 0
+Region.size: 18
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 6 2 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 6 3 1 0 0 0 
+
+minGini: 3.250000 - 4
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 6 1 1 0 0 0 
+
+minGini: 1.000000 - 3
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 2.000000 - 0
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 2 2 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 5.428571 - 0
+Region.size: 18
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 2 2 
+RightChild.size: 14
+RightChild.ClassCounts: 0 12 0 0 2 0 
+
+minGini: 1.846153 - 2
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 12 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 1.777777 - 8
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 8 0 0 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+
+
+Tree Number: 24 finished.
+
+minGini: 130.701724 - 3
+Region.size: 214
+LeftChild.size: 174
+LeftChild.ClassCounts: 75 66 13 3 13 4 
+RightChild.size: 40
+RightChild.ClassCounts: 0 7 0 2 1 30 
+
+minGini: 6.000000 - 7
+Region.size: 40
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 7 0 2 1 1 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 0 0 0 29 
+
+minGini: 2.500000 - 0
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 2 1 1 
+
+minGini: 1.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 1 1 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 101.388429 - 3
+Region.size: 174
+LeftChild.size: 121
+LeftChild.ClassCounts: 69 33 11 0 4 4 
+RightChild.size: 53
+RightChild.ClassCounts: 6 33 2 3 9 0 
+
+minGini: 18.136363 - 5
+Region.size: 53
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 9 0 
+RightChild.size: 44
+RightChild.ClassCounts: 6 33 2 3 0 0 
+
+minGini: 13.463414 - 6
+Region.size: 44
+LeftChild.size: 41
+LeftChild.ClassCounts: 6 33 2 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 3 0 0 
+
+minGini: 10.472972 - 6
+Region.size: 41
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 0 0 0 0 
+RightChild.size: 37
+RightChild.ClassCounts: 3 32 2 0 0 0 
+
+minGini: 6.741935 - 1
+Region.size: 37
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 0 0 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 0 29 2 0 0 0 
+
+minGini: 3.111111 - 1
+Region.size: 31
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 22 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 7 2 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 62.608910 - 6
+Region.size: 121
+LeftChild.size: 20
+LeftChild.ClassCounts: 3 14 1 0 2 0 
+RightChild.size: 101
+RightChild.ClassCounts: 66 19 10 0 2 4 
+
+minGini: 47.511378 - 8
+Region.size: 101
+LeftChild.size: 83
+LeftChild.ClassCounts: 61 10 6 0 2 4 
+RightChild.size: 18
+RightChild.ClassCounts: 5 9 4 0 0 0 
+
+minGini: 6.428571 - 1
+Region.size: 18
+LeftChild.size: 14
+LeftChild.ClassCounts: 5 9 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 
+
+minGini: 3.377777 - 6
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 0 0 0 0 
+
+minGini: 1.500000 - 4
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 27.378082 - 2
+Region.size: 83
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 5 0 0 2 3 
+RightChild.size: 73
+RightChild.ClassCounts: 61 5 6 0 0 1 
+
+minGini: 17.943661 - 6
+Region.size: 73
+LeftChild.size: 71
+LeftChild.ClassCounts: 61 3 6 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 14.647321 - 0
+Region.size: 71
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 0 4 0 0 0 
+RightChild.size: 64
+RightChild.ClassCounts: 58 3 2 0 0 1 
+
+minGini: 8.907103 - 5
+Region.size: 64
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 0 2 0 0 0 
+RightChild.size: 61
+RightChild.ClassCounts: 57 3 0 0 0 1 
+
+minGini: 7.022988 - 0
+Region.size: 61
+LeftChild.size: 58
+LeftChild.ClassCounts: 55 3 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 0 0 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 5.230174 - 8
+Region.size: 58
+LeftChild.size: 47
+LeftChild.ClassCounts: 46 1 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 9 2 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.875000 - 5
+Region.size: 47
+LeftChild.size: 31
+LeftChild.ClassCounts: 31 0 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 15 1 0 0 0 0 
+
+minGini: 1.666666 - 3
+Region.size: 16
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 1.500000 - 4
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 4.250000 - 4
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 8
+RightChild.ClassCounts: 0 5 0 0 2 1 
+
+minGini: 2.500000 - 0
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 0 0 2 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 6.509803 - 1
+Region.size: 20
+LeftChild.size: 17
+LeftChild.ClassCounts: 2 14 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 0 0 0 2 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 2.500000 - 2
+Region.size: 17
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 1 1 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 0 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+
+
+Tree Number: 25 finished.
+
+minGini: 123.399038 - 7
+Region.size: 214
+LeftChild.size: 182
+LeftChild.ClassCounts: 75 70 18 12 3 4 
+RightChild.size: 32
+RightChild.ClassCounts: 0 1 0 0 0 31 
+
+minGini: 0.000000 - 8
+Region.size: 32
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 0 0 0 0 31 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 107.496562 - 2
+Region.size: 182
+LeftChild.size: 53
+LeftChild.ClassCounts: 3 29 2 12 3 4 
+RightChild.size: 129
+RightChild.ClassCounts: 72 41 16 0 0 0 
+
+minGini: 69.593301 - 4
+Region.size: 129
+LeftChild.size: 19
+LeftChild.ClassCounts: 17 1 1 0 0 0 
+RightChild.size: 110
+RightChild.ClassCounts: 55 40 15 0 0 0 
+
+minGini: 55.338827 - 5
+Region.size: 110
+LeftChild.size: 84
+LeftChild.ClassCounts: 50 19 15 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 5 21 0 0 0 0 
+
+minGini: 5.136363 - 8
+Region.size: 26
+LeftChild.size: 22
+LeftChild.ClassCounts: 2 20 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 2.000000 - 3
+Region.size: 22
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 0 0 0 0 
+RightChild.size: 18
+RightChild.ClassCounts: 0 18 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 43.168831 - 3
+Region.size: 84
+LeftChild.size: 77
+LeftChild.ClassCounts: 50 15 12 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 4 3 0 0 0 
+
+minGini: 1.500000 - 1
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 3 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 30.985655 - 0
+Region.size: 77
+LeftChild.size: 16
+LeftChild.ClassCounts: 3 3 10 0 0 0 
+RightChild.size: 61
+RightChild.ClassCounts: 47 12 2 0 0 0 
+
+minGini: 18.932900 - 6
+Region.size: 61
+LeftChild.size: 28
+LeftChild.ClassCounts: 17 11 0 0 0 0 
+RightChild.size: 33
+RightChild.ClassCounts: 30 1 2 0 0 0 
+
+minGini: 1.935483 - 5
+Region.size: 33
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 30 1 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 31
+LeftChild.size: 30
+LeftChild.ClassCounts: 30 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 7.571428 - 4
+Region.size: 28
+LeftChild.size: 14
+LeftChild.ClassCounts: 4 10 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 13 1 0 0 0 0 
+
+minGini: 1.714285 - 1
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 0 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 3.333333 - 4
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 2 10 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 0 0 0 0 
+
+minGini: 6.142857 - 6
+Region.size: 16
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 3 1 10 0 0 0 
+
+minGini: 4.177777 - 2
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 0 2 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 1 8 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 8 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 1.888888 - 6
+Region.size: 19
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 18
+RightChild.ClassCounts: 17 0 1 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 18
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 1 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 29.089080 - 2
+Region.size: 53
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 11 0 12 2 4 
+RightChild.size: 24
+RightChild.ClassCounts: 3 18 2 0 1 0 
+
+minGini: 8.095238 - 2
+Region.size: 24
+LeftChild.size: 21
+LeftChild.ClassCounts: 3 17 0 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 2 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 5.833333 - 2
+Region.size: 21
+LeftChild.size: 12
+LeftChild.ClassCounts: 3 8 0 0 1 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 0 0 0 
+
+minGini: 3.666666 - 8
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 2 0 0 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 1.333333 - 2
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 14.515789 - 3
+Region.size: 29
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 7 0 0 0 3 
+RightChild.size: 19
+RightChild.ClassCounts: 0 4 0 12 2 1 
+
+minGini: 7.529411 - 5
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 4 0 12 0 1 
+
+minGini: 3.346153 - 1
+Region.size: 17
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 1 0 12 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 0 0 0 1 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 0 12 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 3.000000 - 1
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 3 0 0 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 3 
+
+
+
+Tree Number: 26 finished.
+
+minGini: 137.689301 - 3
+Region.size: 214
+LeftChild.size: 113
+LeftChild.ClassCounts: 58 31 20 0 2 2 
+RightChild.size: 101
+RightChild.ClassCounts: 5 53 3 7 12 21 
+
+minGini: 46.046345 - 1
+Region.size: 101
+LeftChild.size: 68
+LeftChild.ClassCounts: 5 51 3 7 0 2 
+RightChild.size: 33
+RightChild.ClassCounts: 0 2 0 0 12 19 
+
+minGini: 8.523076 - 2
+Region.size: 33
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 0 0 0 2 18 
+RightChild.size: 13
+RightChild.ClassCounts: 0 2 0 0 10 1 
+
+minGini: 1.818181 - 5
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 0 0 10 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 1.500000 - 6
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 3 1 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 7 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 2.000000 - 1
+Region.size: 20
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 2 2 
+RightChild.size: 16
+RightChild.ClassCounts: 0 0 0 0 0 16 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 21.820689 - 2
+Region.size: 68
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 3 0 7 0 0 
+RightChild.size: 58
+RightChild.ClassCounts: 5 48 3 0 0 2 
+
+minGini: 14.250000 - 7
+Region.size: 58
+LeftChild.size: 56
+LeftChild.ClassCounts: 5 48 3 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 12.051209 - 6
+Region.size: 56
+LeftChild.size: 37
+LeftChild.ClassCounts: 1 36 0 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 4 12 3 0 0 0 
+
+minGini: 5.833333 - 2
+Region.size: 19
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 11 1 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 4 1 2 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 2 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 1.600000 - 5
+Region.size: 12
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 1 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 1.000000 - 8
+Region.size: 37
+LeftChild.size: 35
+LeftChild.ClassCounts: 0 35 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 7 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 61.053801 - 0
+Region.size: 113
+LeftChild.size: 18
+LeftChild.ClassCounts: 1 3 12 0 0 2 
+RightChild.size: 95
+RightChild.ClassCounts: 57 28 8 0 2 0 
+
+minGini: 43.564705 - 6
+Region.size: 95
+LeftChild.size: 85
+LeftChild.ClassCounts: 57 19 8 0 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 9 0 0 1 0 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 37.364661 - 4
+Region.size: 85
+LeftChild.size: 57
+LeftChild.ClassCounts: 31 18 7 0 1 0 
+RightChild.size: 28
+RightChild.ClassCounts: 26 1 1 0 0 0 
+
+minGini: 1.925925 - 6
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 26 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 27
+LeftChild.size: 26
+LeftChild.ClassCounts: 26 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 22.384615 - 6
+Region.size: 57
+LeftChild.size: 18
+LeftChild.ClassCounts: 3 15 0 0 0 0 
+RightChild.size: 39
+RightChild.ClassCounts: 28 3 7 0 1 0 
+
+minGini: 12.833333 - 5
+Region.size: 39
+LeftChild.size: 36
+LeftChild.ClassCounts: 28 0 7 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 11.071428 - 6
+Region.size: 36
+LeftChild.size: 8
+LeftChild.ClassCounts: 4 0 4 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 24 0 3 0 1 0 
+
+minGini: 5.481481 - 8
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 24 0 2 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 5.000000 - 5
+Region.size: 27
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 0 0 0 1 0 
+RightChild.size: 24
+RightChild.ClassCounts: 22 0 2 0 0 0 
+
+minGini: 3.111111 - 0
+Region.size: 24
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 0 2 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 0.000000 - 3
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 
+
+minGini: 1.500000 - 0
+Region.size: 18
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 4.857142 - 4
+Region.size: 18
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 11 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 1 3 1 0 0 2 
+
+minGini: 2.500000 - 2
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 0 1 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+
+
+Tree Number: 27 finished.
+
+minGini: 126.000768 - 7
+Region.size: 214
+LeftChild.size: 186
+LeftChild.ClassCounts: 65 85 15 12 6 3 
+RightChild.size: 28
+RightChild.ClassCounts: 0 1 0 1 0 26 
+
+minGini: 1.925925 - 2
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 1 0 0 0 26 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 27
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 0 0 0 0 26 
+
+minGini: 107.636125 - 3
+Region.size: 186
+LeftChild.size: 109
+LeftChild.ClassCounts: 58 35 11 1 3 1 
+RightChild.size: 77
+RightChild.ClassCounts: 7 50 4 11 3 2 
+
+minGini: 34.104669 - 6
+Region.size: 77
+LeftChild.size: 54
+LeftChild.ClassCounts: 7 44 1 2 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 6 3 9 3 2 
+
+minGini: 12.681818 - 1
+Region.size: 23
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 3 0 9 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 3 3 0 3 2 
+
+minGini: 5.250000 - 4
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 3 3 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 
+
+minGini: 2.400000 - 2
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 3 0 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 1.800000 - 8
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 1 0 9 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 9 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 12.942917 - 8
+Region.size: 54
+LeftChild.size: 43
+LeftChild.ClassCounts: 1 39 1 2 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 6 5 0 0 0 0 
+
+minGini: 1.714285 - 1
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 3.853658 - 0
+Region.size: 43
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 
+RightChild.size: 41
+RightChild.ClassCounts: 1 39 1 0 0 0 
+
+minGini: 2.948717 - 1
+Region.size: 41
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 
+RightChild.size: 39
+RightChild.ClassCounts: 0 38 1 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 39
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 
+RightChild.size: 37
+RightChild.ClassCounts: 0 37 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 62.228431 - 5
+Region.size: 109
+LeftChild.size: 24
+LeftChild.ClassCounts: 6 11 4 0 3 0 
+RightChild.size: 85
+RightChild.ClassCounts: 52 24 7 1 0 1 
+
+minGini: 41.156453 - 4
+Region.size: 85
+LeftChild.size: 59
+LeftChild.ClassCounts: 29 22 7 1 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 23 2 0 0 0 1 
+
+minGini: 2.916666 - 1
+Region.size: 26
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 0 1 
+RightChild.size: 24
+RightChild.ClassCounts: 23 1 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 24
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 23 0 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 28.800000 - 2
+Region.size: 59
+LeftChild.size: 50
+LeftChild.ClassCounts: 29 13 7 1 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 0 0 0 
+
+minGini: 24.257575 - 8
+Region.size: 50
+LeftChild.size: 44
+LeftChild.ClassCounts: 29 8 6 1 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 5 1 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 17.650000 - 5
+Region.size: 44
+LeftChild.size: 40
+LeftChild.ClassCounts: 29 4 6 1 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 15.684210 - 2
+Region.size: 40
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 1 0 0 
+RightChild.size: 38
+RightChild.ClassCounts: 29 3 6 0 0 0 
+
+minGini: 5.437500 - 0
+Region.size: 38
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 0 0 0 
+RightChild.size: 32
+RightChild.ClassCounts: 29 3 0 0 0 0 
+
+minGini: 4.941176 - 5
+Region.size: 32
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 0 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 14 3 0 0 0 0 
+
+minGini: 1.866666 - 2
+Region.size: 17
+LeftChild.size: 15
+LeftChild.ClassCounts: 14 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 9.514285 - 2
+Region.size: 24
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 11 0 0 3 0 
+RightChild.size: 10
+RightChild.ClassCounts: 6 0 4 0 0 0 
+
+minGini: 3.000000 - 4
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 1.333333 - 2
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 0 2 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 1.833333 - 1
+Region.size: 14
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 11 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+minGini: 0.000000 - 6
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 0 0 0 0 
+
+
+
+Tree Number: 28 finished.
+
+minGini: 129.265217 - 3
+Region.size: 214
+LeftChild.size: 184
+LeftChild.ClassCounts: 69 83 12 9 8 3 
+RightChild.size: 30
+RightChild.ClassCounts: 0 3 0 3 0 24 
+
+minGini: 5.192307 - 1
+Region.size: 30
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 0 3 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 2 0 0 0 24 
+
+minGini: 1.920000 - 2
+Region.size: 26
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 1 0 0 0 24 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.666666 - 4
+Region.size: 25
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 1 0 0 0 5 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 0 0 0 19 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 3 0 0 
+
+minGini: 102.173643 - 6
+Region.size: 184
+LeftChild.size: 55
+LeftChild.ClassCounts: 7 46 1 0 1 0 
+RightChild.size: 129
+RightChild.ClassCounts: 62 37 11 9 7 3 
+
+minGini: 79.111111 - 5
+Region.size: 129
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 2 0 0 7 0 
+RightChild.size: 120
+RightChild.ClassCounts: 62 35 11 9 0 3 
+
+minGini: 70.388888 - 0
+Region.size: 120
+LeftChild.size: 48
+LeftChild.ClassCounts: 32 6 10 0 0 0 
+RightChild.size: 72
+RightChild.ClassCounts: 30 29 1 9 0 3 
+
+minGini: 38.235294 - 2
+Region.size: 72
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 11 0 9 0 1 
+RightChild.size: 51
+RightChild.ClassCounts: 30 18 1 0 0 2 
+
+minGini: 21.470588 - 3
+Region.size: 51
+LeftChild.size: 17
+LeftChild.ClassCounts: 16 1 0 0 0 0 
+RightChild.size: 34
+RightChild.ClassCounts: 14 17 1 0 0 2 
+
+minGini: 11.585964 - 0
+Region.size: 34
+LeftChild.size: 19
+LeftChild.ClassCounts: 3 16 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 11 1 1 0 0 2 
+
+minGini: 4.318181 - 1
+Region.size: 15
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 1 0 0 0 2 
+RightChild.size: 11
+RightChild.ClassCounts: 10 0 1 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 1.333333 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 0 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+minGini: 3.000000 - 4
+Region.size: 19
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 7.872727 - 8
+Region.size: 21
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 2 0 7 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 0 9 0 2 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 
+
+minGini: 3.111111 - 7
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 2 0 7 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 1.750000 - 6
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 1 0 7 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 7 0 0 
+
+minGini: 19.090909 - 1
+Region.size: 48
+LeftChild.size: 44
+LeftChild.ClassCounts: 32 6 6 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 
+
+minGini: 17.089324 - 3
+Region.size: 44
+LeftChild.size: 27
+LeftChild.ClassCounts: 22 5 0 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 10 1 6 0 0 0 
+
+minGini: 7.200000 - 1
+Region.size: 17
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 10 1 4 0 0 0 
+
+minGini: 4.923076 - 3
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 10 1 2 0 0 0 
+
+minGini: 3.133333 - 2
+Region.size: 13
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 0 2 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 0 0 0 0 
+
+minGini: 5.894736 - 0
+Region.size: 27
+LeftChild.size: 8
+LeftChild.ClassCounts: 4 4 0 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 18 1 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.600000 - 0
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 0 0 0 0 
+
+minGini: 1.000000 - 8
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 7 0 
+
+minGini: 13.888888 - 2
+Region.size: 55
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 54
+RightChild.ClassCounts: 7 46 1 0 0 0 
+
+minGini: 13.163043 - 2
+Region.size: 54
+LeftChild.size: 8
+LeftChild.ClassCounts: 2 5 1 0 0 0 
+RightChild.size: 46
+RightChild.ClassCounts: 5 41 0 0 0 0 
+
+minGini: 7.802150 - 0
+Region.size: 46
+LeftChild.size: 31
+LeftChild.ClassCounts: 1 30 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 4 11 0 0 0 0 
+
+minGini: 3.318181 - 3
+Region.size: 15
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 1 10 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 31
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 0 30 0 0 0 0 
+
+minGini: 1.666666 - 8
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 5 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+
+
+Tree Number: 29 finished.
+
+minGini: 132.502471 - 3
+Region.size: 214
+LeftChild.size: 118
+LeftChild.ClassCounts: 64 34 13 1 3 3 
+RightChild.size: 96
+RightChild.ClassCounts: 6 54 3 8 7 18 
+
+minGini: 43.769230 - 7
+Region.size: 96
+LeftChild.size: 78
+LeftChild.ClassCounts: 6 53 3 7 7 2 
+RightChild.size: 18
+RightChild.ClassCounts: 0 1 0 1 0 16 
+
+minGini: 1.882352 - 7
+Region.size: 18
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 0 0 1 0 16 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.000000 - 7
+Region.size: 17
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 0 0 0 0 15 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 1 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 
+
+minGini: 31.178571 - 6
+Region.size: 78
+LeftChild.size: 56
+LeftChild.ClassCounts: 6 48 0 1 1 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 5 3 6 6 2 
+
+minGini: 13.684210 - 2
+Region.size: 22
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 5 0 6 6 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 
+
+minGini: 8.000000 - 5
+Region.size: 19
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 5 0 6 0 2 
+
+minGini: 5.333333 - 4
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 5 0 2 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 4 0 0 
+
+minGini: 2.000000 - 5
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 2 0 2 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 
+
+minGini: 11.125000 - 6
+Region.size: 56
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 3 0 1 1 0 
+RightChild.size: 48
+RightChild.ClassCounts: 3 45 0 0 0 0 
+
+minGini: 5.059829 - 6
+Region.size: 48
+LeftChild.size: 39
+LeftChild.ClassCounts: 1 38 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 2 7 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 
+
+minGini: 1.500000 - 1
+Region.size: 39
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 0 0 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 0 35 0 0 0 0 
+
+minGini: 1.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 3.000000 - 3
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 0 0 0 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 0 1 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 63.406966 - 6
+Region.size: 118
+LeftChild.size: 107
+LeftChild.ClassCounts: 64 24 13 0 3 3 
+RightChild.size: 11
+RightChild.ClassCounts: 0 10 0 1 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 57.054385 - 6
+Region.size: 107
+LeftChild.size: 12
+LeftChild.ClassCounts: 3 8 0 0 1 0 
+RightChild.size: 95
+RightChild.ClassCounts: 61 16 13 0 2 3 
+
+minGini: 46.917448 - 8
+Region.size: 95
+LeftChild.size: 82
+LeftChild.ClassCounts: 58 10 9 0 2 3 
+RightChild.size: 13
+RightChild.ClassCounts: 3 6 4 0 0 0 
+
+minGini: 4.000000 - 0
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 3 6 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 
+
+minGini: 2.400000 - 1
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 36.149509 - 1
+Region.size: 82
+LeftChild.size: 48
+LeftChild.ClassCounts: 38 9 1 0 0 0 
+RightChild.size: 34
+RightChild.ClassCounts: 20 1 8 0 2 3 
+
+minGini: 15.651515 - 4
+Region.size: 34
+LeftChild.size: 22
+LeftChild.ClassCounts: 18 0 3 0 0 1 
+RightChild.size: 12
+RightChild.ClassCounts: 2 1 5 0 2 2 
+
+minGini: 6.250000 - 2
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 2 2 
+RightChild.size: 8
+RightChild.ClassCounts: 2 1 5 0 0 0 
+
+minGini: 2.857142 - 4
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 2 0 5 0 0 0 
+
+minGini: 1.333333 - 3
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 0 1 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+minGini: 3.228070 - 4
+Region.size: 22
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 2 0 0 1 
+RightChild.size: 19
+RightChild.ClassCounts: 18 0 1 0 0 0 
+
+minGini: 1.714285 - 6
+Region.size: 19
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 0 1 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 
+
+minGini: 13.286713 - 4
+Region.size: 48
+LeftChild.size: 22
+LeftChild.ClassCounts: 13 8 1 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 25 1 0 0 0 0 
+
+minGini: 1.500000 - 8
+Region.size: 26
+LeftChild.size: 22
+LeftChild.ClassCounts: 22 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 6.769230 - 4
+Region.size: 22
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 4 8 1 0 0 0 
+
+minGini: 4.000000 - 6
+Region.size: 13
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 4 2 1 0 0 0 
+
+minGini: 1.333333 - 2
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 4.200000 - 0
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 0 0 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 2 8 0 0 0 0 
+
+minGini: 1.777777 - 6
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 0 0 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+
+
+Tree Number: 30 finished.
+
+minGini: 130.591419 - 3
+Region.size: 214
+LeftChild.size: 119
+LeftChild.ClassCounts: 71 32 10 1 3 2 
+RightChild.size: 95
+RightChild.ClassCounts: 4 48 3 14 5 21 
+
+minGini: 42.016908 - 7
+Region.size: 95
+LeftChild.size: 72
+LeftChild.ClassCounts: 4 47 3 13 5 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 1 0 1 0 21 
+
+minGini: 1.909090 - 6
+Region.size: 23
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 0 0 1 0 21 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.000000 - 2
+Region.size: 22
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 0 0 0 0 20 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 1 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 
+
+minGini: 23.354518 - 2
+Region.size: 72
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 2 0 13 4 0 
+RightChild.size: 53
+RightChild.ClassCounts: 4 45 3 0 1 0 
+
+minGini: 11.989010 - 8
+Region.size: 53
+LeftChild.size: 39
+LeftChild.ClassCounts: 1 37 0 0 1 0 
+RightChild.size: 14
+RightChild.ClassCounts: 3 8 3 0 0 0 
+
+minGini: 6.857142 - 1
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 4 3 0 0 0 
+
+minGini: 1.500000 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 3 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 1.500000 - 7
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 
+
+minGini: 1.947368 - 1
+Region.size: 39
+LeftChild.size: 38
+LeftChild.ClassCounts: 1 37 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 
+
+minGini: 1.777777 - 6
+Region.size: 38
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 29 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 0 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 
+
+minGini: 3.457142 - 1
+Region.size: 19
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 1 0 13 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 0 0 4 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 0 0 13 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 
+
+minGini: 58.748936 - 2
+Region.size: 119
+LeftChild.size: 25
+LeftChild.ClassCounts: 5 14 0 1 3 2 
+RightChild.size: 94
+RightChild.ClassCounts: 66 18 10 0 0 0 
+
+minGini: 39.700000 - 8
+Region.size: 94
+LeftChild.size: 90
+LeftChild.ClassCounts: 66 15 9 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 1 0 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 
+
+minGini: 35.386363 - 1
+Region.size: 90
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 
+RightChild.size: 88
+RightChild.ClassCounts: 66 15 7 0 0 0 
+
+minGini: 31.968253 - 1
+Region.size: 88
+LeftChild.size: 25
+LeftChild.ClassCounts: 25 0 0 0 0 0 
+RightChild.size: 63
+RightChild.ClassCounts: 41 15 7 0 0 0 
+
+minGini: 25.446315 - 4
+Region.size: 63
+LeftChild.size: 25
+LeftChild.ClassCounts: 24 0 1 0 0 0 
+RightChild.size: 38
+RightChild.ClassCounts: 17 15 6 0 0 0 
+
+minGini: 19.058823 - 0
+Region.size: 38
+LeftChild.size: 21
+LeftChild.ClassCounts: 12 3 6 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 5 12 0 0 0 0 
+
+minGini: 5.833333 - 1
+Region.size: 17
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 5 7 0 0 0 0 
+
+minGini: 3.750000 - 4
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 5 3 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 
+
+minGini: 7.777777 - 1
+Region.size: 21
+LeftChild.size: 12
+LeftChild.ClassCounts: 10 2 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 2 1 6 0 0 0 
+
+minGini: 1.714285 - 2
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 1 6 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 6 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 0 0 0 0 
+
+minGini: 1.750000 - 3
+Region.size: 25
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 0 1 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 17 0 0 0 0 0 
+
+minGini: 1.000000 - 4
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 1 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 
+
+minGini: 13.060606 - 0
+Region.size: 25
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 1 2 
+RightChild.size: 22
+RightChild.ClassCounts: 5 14 0 1 2 0 
+
+minGini: 9.285714 - 2
+Region.size: 22
+LeftChild.size: 14
+LeftChild.ClassCounts: 5 6 0 1 2 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 0 0 0 0 
+
+minGini: 4.444444 - 5
+Region.size: 14
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 6 0 1 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 
+
+minGini: 2.500000 - 6
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 0 1 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 1 2 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 1 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 2 
+
+
+
+Tree Number: 31 finished.
+
+glass
+minGini: 42.090221 - 4
+Region.size: 351
+LeftChild.size: 80
+LeftChild.ClassCounts: 78 2 
+RightChild.size: 271
+RightChild.ClassCounts: 49 222 
+
+minGini: 28.729411 - 5
+Region.size: 271
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 255
+RightChild.ClassCounts: 33 222 
+
+minGini: 15.790794 - 7
+Region.size: 255
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 239
+RightChild.ClassCounts: 17 222 
+
+minGini: 12.280851 - 2
+Region.size: 239
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 235
+RightChild.ClassCounts: 13 222 
+
+minGini: 11.145114 - 23
+Region.size: 235
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 232
+RightChild.ClassCounts: 11 221 
+
+minGini: 9.690617 - 21
+Region.size: 232
+LeftChild.size: 169
+LeftChild.ClassCounts: 2 167 
+RightChild.size: 63
+RightChild.ClassCounts: 9 54 
+
+minGini: 5.608851 - 3
+Region.size: 63
+LeftChild.size: 19
+LeftChild.ClassCounts: 8 11 
+RightChild.size: 44
+RightChild.ClassCounts: 1 43 
+
+minGini: 0.000000 - 13
+Region.size: 44
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 43
+RightChild.ClassCounts: 0 43 
+
+minGini: 2.933333 - 6
+Region.size: 19
+LeftChild.size: 15
+LeftChild.ClassCounts: 4 11 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 16
+Region.size: 15
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 1.494011 - 15
+Region.size: 169
+LeftChild.size: 167
+LeftChild.ClassCounts: 1 166 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 30
+Region.size: 167
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 163
+RightChild.ClassCounts: 0 163 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 10
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.636363 - 14
+Region.size: 80
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 69
+RightChild.ClassCounts: 69 0 
+
+minGini: 0.000000 - 27
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 0 finished.
+
+minGini: 52.468750 - 2
+Region.size: 351
+LeftChild.size: 63
+LeftChild.ClassCounts: 63 0 
+RightChild.size: 288
+RightChild.ClassCounts: 69 219 
+
+minGini: 34.415567 - 26
+Region.size: 288
+LeftChild.size: 245
+LeftChild.ClassCounts: 33 212 
+RightChild.size: 43
+RightChild.ClassCounts: 36 7 
+
+minGini: 4.666666 - 21
+Region.size: 43
+LeftChild.size: 21
+LeftChild.ClassCounts: 14 7 
+RightChild.size: 22
+RightChild.ClassCounts: 22 0 
+
+minGini: 3.500000 - 4
+Region.size: 21
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 14
+RightChild.ClassCounts: 7 7 
+
+minGini: 0.875000 - 9
+Region.size: 14
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 14
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 23.159663 - 3
+Region.size: 245
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 238
+RightChild.ClassCounts: 26 212 
+
+minGini: 19.125541 - 28
+Region.size: 238
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 231
+RightChild.ClassCounts: 20 211 
+
+minGini: 15.732456 - 33
+Region.size: 231
+LeftChild.size: 228
+LeftChild.ClassCounts: 17 211 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 14.726102 - 27
+Region.size: 228
+LeftChild.size: 68
+LeftChild.ClassCounts: 12 56 
+RightChild.size: 160
+RightChild.ClassCounts: 5 155 
+
+minGini: 4.280481 - 7
+Region.size: 160
+LeftChild.size: 147
+LeftChild.ClassCounts: 2 145 
+RightChild.size: 13
+RightChild.ClassCounts: 3 10 
+
+minGini: 0.909090 - 4
+Region.size: 13
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 11
+RightChild.ClassCounts: 1 10 
+
+minGini: 0.000000 - 10
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.993150 - 25
+Region.size: 147
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 146
+RightChild.ClassCounts: 1 145 
+
+minGini: 0.937500 - 26
+Region.size: 146
+LeftChild.size: 16
+LeftChild.ClassCounts: 1 15 
+RightChild.size: 130
+RightChild.ClassCounts: 0 130 
+
+minGini: 0.000000 - 17
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 
+
+minGini: 7.753846 - 27
+Region.size: 68
+LeftChild.size: 65
+LeftChild.ClassCounts: 9 56 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 6.222222 - 6
+Region.size: 65
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 63
+RightChild.ClassCounts: 7 56 
+
+minGini: 4.421052 - 25
+Region.size: 63
+LeftChild.size: 44
+LeftChild.ClassCounts: 0 44 
+RightChild.size: 19
+RightChild.ClassCounts: 7 12 
+
+minGini: 1.555555 - 16
+Region.size: 19
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 
+
+minGini: 0.000000 - 14
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 22
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+
+
+Tree Number: 1 finished.
+
+minGini: 64.684335 - 27
+Region.size: 351
+LeftChild.size: 44
+LeftChild.ClassCounts: 42 2 
+RightChild.size: 307
+RightChild.ClassCounts: 88 219 
+
+minGini: 39.362356 - 6
+Region.size: 307
+LeftChild.size: 47
+LeftChild.ClassCounts: 44 3 
+RightChild.size: 260
+RightChild.ClassCounts: 44 216 
+
+minGini: 26.341463 - 13
+Region.size: 260
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 246
+RightChild.ClassCounts: 30 216 
+
+minGini: 14.918128 - 21
+Region.size: 246
+LeftChild.size: 228
+LeftChild.ClassCounts: 14 214 
+RightChild.size: 18
+RightChild.ClassCounts: 16 2 
+
+minGini: 1.333333 - 13
+Region.size: 18
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 
+
+minGini: 0.666666 - 30
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 14
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 10.882882 - 3
+Region.size: 228
+LeftChild.size: 222
+LeftChild.ClassCounts: 10 212 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.666666 - 17
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 8
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 8.633484 - 7
+Region.size: 222
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 221
+RightChild.ClassCounts: 9 212 
+
+minGini: 7.709090 - 24
+Region.size: 221
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 220
+RightChild.ClassCounts: 8 212 
+
+minGini: 7.364752 - 24
+Region.size: 220
+LeftChild.size: 78
+LeftChild.ClassCounts: 7 71 
+RightChild.size: 142
+RightChild.ClassCounts: 1 141 
+
+minGini: 0.750000 - 26
+Region.size: 142
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 138
+RightChild.ClassCounts: 0 138 
+
+minGini: 0.000000 - 9
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.671052 - 6
+Region.size: 78
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 76
+RightChild.ClassCounts: 5 71 
+
+minGini: 4.204761 - 20
+Region.size: 76
+LeftChild.size: 70
+LeftChild.ClassCounts: 3 67 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 21
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 2.317708 - 6
+Region.size: 70
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 64
+RightChild.ClassCounts: 1 63 
+
+minGini: 0.952380 - 25
+Region.size: 64
+LeftChild.size: 43
+LeftChild.ClassCounts: 0 43 
+RightChild.size: 21
+RightChild.ClassCounts: 1 20 
+
+minGini: 0.000000 - 10
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 20 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 26
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.976744 - 20
+Region.size: 47
+LeftChild.size: 43
+LeftChild.ClassCounts: 42 1 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 15
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.750000 - 21
+Region.size: 43
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 39
+RightChild.ClassCounts: 39 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.333333 - 16
+Region.size: 44
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 38
+RightChild.ClassCounts: 38 0 
+
+minGini: 0.666666 - 17
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 2 finished.
+
+minGini: 52.181818 - 2
+Region.size: 351
+LeftChild.size: 76
+LeftChild.ClassCounts: 76 0 
+RightChild.size: 275
+RightChild.ClassCounts: 70 205 
+
+minGini: 36.959804 - 7
+Region.size: 275
+LeftChild.size: 38
+LeftChild.ClassCounts: 32 6 
+RightChild.size: 237
+RightChild.ClassCounts: 38 199 
+
+minGini: 21.417040 - 4
+Region.size: 237
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 223
+RightChild.ClassCounts: 24 199 
+
+minGini: 13.369742 - 26
+Region.size: 223
+LeftChild.size: 201
+LeftChild.ClassCounts: 9 192 
+RightChild.size: 22
+RightChild.ClassCounts: 15 7 
+
+minGini: 2.500000 - 33
+Region.size: 22
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 18
+RightChild.ClassCounts: 15 3 
+
+minGini: 1.875000 - 29
+Region.size: 18
+LeftChild.size: 8
+LeftChild.ClassCounts: 5 3 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.750000 - 3
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 19
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 7.680000 - 23
+Region.size: 201
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 200
+RightChild.ClassCounts: 8 192 
+
+minGini: 7.253333 - 19
+Region.size: 200
+LeftChild.size: 150
+LeftChild.ClassCounts: 2 148 
+RightChild.size: 50
+RightChild.ClassCounts: 6 44 
+
+minGini: 2.808510 - 10
+Region.size: 50
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 47
+RightChild.ClassCounts: 3 44 
+
+minGini: 1.643939 - 6
+Region.size: 47
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 44
+RightChild.ClassCounts: 1 43 
+
+minGini: 0.833333 - 7
+Region.size: 44
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 38
+RightChild.ClassCounts: 0 38 
+
+minGini: 0.000000 - 32
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 28
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.897435 - 2
+Region.size: 150
+LeftChild.size: 39
+LeftChild.ClassCounts: 2 37 
+RightChild.size: 111
+RightChild.ClassCounts: 0 111 
+
+minGini: 0.666666 - 13
+Region.size: 39
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 36
+RightChild.ClassCounts: 0 36 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 4.172619 - 27
+Region.size: 38
+LeftChild.size: 14
+LeftChild.ClassCounts: 9 5 
+RightChild.size: 24
+RightChild.ClassCounts: 23 1 
+
+minGini: 0.900000 - 23
+Region.size: 24
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 0.000000 - 23
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.428571 - 11
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 5 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 25
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+
+
+Tree Number: 3 finished.
+
+minGini: 43.686629 - 6
+Region.size: 351
+LeftChild.size: 70
+LeftChild.ClassCounts: 68 2 
+RightChild.size: 281
+RightChild.ClassCounts: 51 230 
+
+minGini: 27.479641 - 25
+Region.size: 281
+LeftChild.size: 22
+LeftChild.ClassCounts: 21 1 
+RightChild.size: 259
+RightChild.ClassCounts: 30 229 
+
+minGini: 19.236000 - 4
+Region.size: 259
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 250
+RightChild.ClassCounts: 21 229 
+
+minGini: 15.825203 - 13
+Region.size: 250
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 246
+RightChild.ClassCounts: 17 229 
+
+minGini: 13.193415 - 15
+Region.size: 246
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 243
+RightChild.ClassCounts: 14 229 
+
+minGini: 11.402489 - 23
+Region.size: 243
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 241
+RightChild.ClassCounts: 12 229 
+
+minGini: 9.581589 - 9
+Region.size: 241
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 239
+RightChild.ClassCounts: 10 229 
+
+minGini: 9.274550 - 6
+Region.size: 239
+LeftChild.size: 73
+LeftChild.ClassCounts: 7 66 
+RightChild.size: 166
+RightChild.ClassCounts: 3 163 
+
+minGini: 2.689655 - 10
+Region.size: 166
+LeftChild.size: 137
+LeftChild.ClassCounts: 0 137 
+RightChild.size: 29
+RightChild.ClassCounts: 3 26 
+
+minGini: 0.000000 - 2
+Region.size: 29
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 
+
+minGini: 5.366666 - 7
+Region.size: 73
+LeftChild.size: 30
+LeftChild.ClassCounts: 7 23 
+RightChild.size: 43
+RightChild.ClassCounts: 0 43 
+
+minGini: 4.107142 - 11
+Region.size: 30
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 28
+RightChild.ClassCounts: 5 23 
+
+minGini: 1.840000 - 7
+Region.size: 28
+LeftChild.size: 25
+LeftChild.ClassCounts: 2 23 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 27
+Region.size: 25
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 23 
+
+minGini: 0.500000 - 14
+Region.size: 22
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 
+
+minGini: 0.000000 - 11
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.200000 - 16
+Region.size: 70
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 65
+RightChild.ClassCounts: 65 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 4 finished.
+
+minGini: 65.298784 - 7
+Region.size: 351
+LeftChild.size: 53
+LeftChild.ClassCounts: 49 4 
+RightChild.size: 298
+RightChild.ClassCounts: 87 211 
+
+minGini: 51.595022 - 33
+Region.size: 298
+LeftChild.size: 272
+LeftChild.ClassCounts: 64 208 
+RightChild.size: 26
+RightChild.ClassCounts: 23 3 
+
+minGini: 2.250000 - 32
+Region.size: 26
+LeftChild.size: 12
+LeftChild.ClassCounts: 9 3 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 1.200000 - 9
+Region.size: 12
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.000000 - 26
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 22.317596 - 4
+Region.size: 272
+LeftChild.size: 39
+LeftChild.ClassCounts: 39 0 
+RightChild.size: 233
+RightChild.ClassCounts: 25 208 
+
+minGini: 17.653597 - 26
+Region.size: 233
+LeftChild.size: 211
+LeftChild.ClassCounts: 13 198 
+RightChild.size: 22
+RightChild.ClassCounts: 12 10 
+
+minGini: 2.307692 - 32
+Region.size: 22
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 13
+RightChild.ClassCounts: 3 10 
+
+minGini: 0.000000 - 15
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 10.421052 - 13
+Region.size: 211
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 209
+RightChild.ClassCounts: 11 198 
+
+minGini: 7.689320 - 2
+Region.size: 209
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 206
+RightChild.ClassCounts: 8 198 
+
+minGini: 6.489326 - 5
+Region.size: 206
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 203
+RightChild.ClassCounts: 6 197 
+
+minGini: 5.565353 - 33
+Region.size: 203
+LeftChild.size: 39
+LeftChild.ClassCounts: 4 35 
+RightChild.size: 164
+RightChild.ClassCounts: 2 162 
+
+minGini: 1.750000 - 26
+Region.size: 164
+LeftChild.size: 16
+LeftChild.ClassCounts: 2 14 
+RightChild.size: 148
+RightChild.ClassCounts: 0 148 
+
+minGini: 0.000000 - 30
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.933333 - 30
+Region.size: 39
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 24 
+RightChild.size: 15
+RightChild.ClassCounts: 4 11 
+
+minGini: 0.000000 - 16
+Region.size: 15
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 0.000000 - 24
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 3.116666 - 21
+Region.size: 53
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 48
+RightChild.ClassCounts: 46 2 
+
+minGini: 1.555555 - 5
+Region.size: 48
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 39
+RightChild.ClassCounts: 39 0 
+
+minGini: 0.000000 - 19
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 32
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 5 finished.
+
+minGini: 60.403264 - 6
+Region.size: 351
+LeftChild.size: 60
+LeftChild.ClassCounts: 57 3 
+RightChild.size: 291
+RightChild.ClassCounts: 79 212 
+
+minGini: 43.037593 - 7
+Region.size: 291
+LeftChild.size: 25
+LeftChild.ClassCounts: 25 0 
+RightChild.size: 266
+RightChild.ClassCounts: 54 212 
+
+minGini: 34.355731 - 17
+Region.size: 266
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 253
+RightChild.ClassCounts: 41 212 
+
+minGini: 30.248739 - 19
+Region.size: 253
+LeftChild.size: 168
+LeftChild.ClassCounts: 12 156 
+RightChild.size: 85
+RightChild.ClassCounts: 29 56 
+
+minGini: 10.712121 - 2
+Region.size: 85
+LeftChild.size: 30
+LeftChild.ClassCounts: 23 7 
+RightChild.size: 55
+RightChild.ClassCounts: 6 49 
+
+minGini: 1.812925 - 32
+Region.size: 55
+LeftChild.size: 49
+LeftChild.ClassCounts: 1 48 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 7
+Region.size: 49
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 48 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.031746 - 5
+Region.size: 30
+LeftChild.size: 21
+LeftChild.ClassCounts: 19 2 
+RightChild.size: 9
+RightChild.ClassCounts: 4 5 
+
+minGini: 0.000000 - 9
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.950000 - 28
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 19 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 16
+Region.size: 20
+LeftChild.size: 17
+LeftChild.ClassCounts: 17 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 21
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 8.509090 - 2
+Region.size: 168
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 165
+RightChild.ClassCounts: 9 156 
+
+minGini: 6.699386 - 3
+Region.size: 165
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 163
+RightChild.ClassCounts: 7 156 
+
+minGini: 4.844720 - 5
+Region.size: 163
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 161
+RightChild.ClassCounts: 5 156 
+
+minGini: 4.671052 - 18
+Region.size: 161
+LeftChild.size: 76
+LeftChild.ClassCounts: 5 71 
+RightChild.size: 85
+RightChild.ClassCounts: 0 85 
+
+minGini: 3.809523 - 7
+Region.size: 76
+LeftChild.size: 21
+LeftChild.ClassCounts: 5 16 
+RightChild.size: 55
+RightChild.ClassCounts: 0 55 
+
+minGini: 2.916666 - 30
+Region.size: 21
+LeftChild.size: 12
+LeftChild.ClassCounts: 5 7 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.833333 - 29
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 32
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 2.314814 - 32
+Region.size: 60
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 54
+RightChild.ClassCounts: 53 1 
+
+minGini: 0.857142 - 21
+Region.size: 54
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 47
+RightChild.ClassCounts: 47 0 
+
+minGini: 0.500000 - 5
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 13
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 23
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+
+
+Tree Number: 6 finished.
+
+minGini: 52.225982 - 6
+Region.size: 351
+LeftChild.size: 67
+LeftChild.ClassCounts: 63 4 
+RightChild.size: 284
+RightChild.ClassCounts: 62 222 
+
+minGini: 34.608365 - 13
+Region.size: 284
+LeftChild.size: 21
+LeftChild.ClassCounts: 21 0 
+RightChild.size: 263
+RightChild.ClassCounts: 41 222 
+
+minGini: 24.072289 - 2
+Region.size: 263
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 249
+RightChild.ClassCounts: 27 222 
+
+minGini: 15.790794 - 31
+Region.size: 249
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 239
+RightChild.ClassCounts: 17 222 
+
+minGini: 13.169491 - 4
+Region.size: 239
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 236
+RightChild.ClassCounts: 14 222 
+
+minGini: 7.721739 - 7
+Region.size: 236
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 230
+RightChild.ClassCounts: 8 222 
+
+minGini: 7.267136 - 23
+Region.size: 230
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 5 
+RightChild.size: 223
+RightChild.ClassCounts: 6 217 
+
+minGini: 4.887387 - 13
+Region.size: 223
+LeftChild.size: 222
+LeftChild.ClassCounts: 5 217 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.927601 - 3
+Region.size: 222
+LeftChild.size: 221
+LeftChild.ClassCounts: 4 217 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.750000 - 11
+Region.size: 221
+LeftChild.size: 64
+LeftChild.ClassCounts: 4 60 
+RightChild.size: 157
+RightChild.ClassCounts: 0 157 
+
+minGini: 1.733333 - 16
+Region.size: 64
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 60
+RightChild.ClassCounts: 1 59 
+
+minGini: 0.875000 - 16
+Region.size: 60
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 52
+RightChild.ClassCounts: 0 52 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.000000 - 9
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 19
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 3.304347 - 4
+Region.size: 67
+LeftChild.size: 44
+LeftChild.ClassCounts: 44 0 
+RightChild.size: 23
+RightChild.ClassCounts: 19 4 
+
+minGini: 2.222222 - 15
+Region.size: 23
+LeftChild.size: 9
+LeftChild.ClassCounts: 5 4 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 0.800000 - 10
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 27
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+
+
+Tree Number: 7 finished.
+
+minGini: 50.661971 - 2
+Region.size: 351
+LeftChild.size: 67
+LeftChild.ClassCounts: 67 0 
+RightChild.size: 284
+RightChild.ClassCounts: 66 218 
+
+minGini: 33.081712 - 4
+Region.size: 284
+LeftChild.size: 27
+LeftChild.ClassCounts: 27 0 
+RightChild.size: 257
+RightChild.ClassCounts: 39 218 
+
+minGini: 24.146678 - 29
+Region.size: 257
+LeftChild.size: 243
+LeftChild.ClassCounts: 26 217 
+RightChild.size: 14
+RightChild.ClassCounts: 13 1 
+
+minGini: 0.000000 - 16
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 15.764957 - 15
+Region.size: 243
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 234
+RightChild.ClassCounts: 17 217 
+
+minGini: 10.469298 - 3
+Region.size: 234
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 228
+RightChild.ClassCounts: 11 217 
+
+minGini: 7.715555 - 13
+Region.size: 228
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 225
+RightChild.ClassCounts: 8 217 
+
+minGini: 6.781250 - 5
+Region.size: 225
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 224
+RightChild.ClassCounts: 7 217 
+
+minGini: 5.838565 - 28
+Region.size: 224
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 223
+RightChild.ClassCounts: 6 217 
+
+minGini: 4.887387 - 15
+Region.size: 223
+LeftChild.size: 222
+LeftChild.ClassCounts: 5 217 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.506611 - 6
+Region.size: 222
+LeftChild.size: 19
+LeftChild.ClassCounts: 3 16 
+RightChild.size: 203
+RightChild.ClassCounts: 2 201 
+
+minGini: 1.495024 - 33
+Region.size: 203
+LeftChild.size: 201
+LeftChild.ClassCounts: 1 200 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 26
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.974358 - 17
+Region.size: 201
+LeftChild.size: 39
+LeftChild.ClassCounts: 1 38 
+RightChild.size: 162
+RightChild.ClassCounts: 0 162 
+
+minGini: 0.000000 - 17
+Region.size: 39
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 38 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.941176 - 5
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 17
+RightChild.ClassCounts: 1 16 
+
+minGini: 0.000000 - 26
+Region.size: 17
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 16 
+
+
+
+Tree Number: 8 finished.
+
+minGini: 54.246575 - 2
+Region.size: 351
+LeftChild.size: 59
+LeftChild.ClassCounts: 59 0 
+RightChild.size: 292
+RightChild.ClassCounts: 72 220 
+
+minGini: 38.477353 - 5
+Region.size: 292
+LeftChild.size: 30
+LeftChild.ClassCounts: 28 2 
+RightChild.size: 262
+RightChild.ClassCounts: 44 218 
+
+minGini: 30.269123 - 30
+Region.size: 262
+LeftChild.size: 63
+LeftChild.ClassCounts: 28 35 
+RightChild.size: 199
+RightChild.ClassCounts: 16 183 
+
+minGini: 8.601037 - 26
+Region.size: 199
+LeftChild.size: 176
+LeftChild.ClassCounts: 3 173 
+RightChild.size: 23
+RightChild.ClassCounts: 13 10 
+
+minGini: 2.307692 - 3
+Region.size: 23
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 13
+RightChild.ClassCounts: 3 10 
+
+minGini: 0.909090 - 3
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 8
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 2.643545 - 25
+Region.size: 176
+LeftChild.size: 173
+LeftChild.ClassCounts: 2 171 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 22
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.923076 - 19
+Region.size: 173
+LeftChild.size: 52
+LeftChild.ClassCounts: 2 50 
+RightChild.size: 121
+RightChild.ClassCounts: 0 121 
+
+minGini: 1.750000 - 30
+Region.size: 52
+LeftChild.size: 16
+LeftChild.ClassCounts: 2 14 
+RightChild.size: 36
+RightChild.ClassCounts: 0 36 
+
+minGini: 1.333333 - 17
+Region.size: 16
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 12
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 10.881410 - 7
+Region.size: 63
+LeftChild.size: 24
+LeftChild.ClassCounts: 19 5 
+RightChild.size: 39
+RightChild.ClassCounts: 9 30 
+
+minGini: 3.146103 - 9
+Region.size: 39
+LeftChild.size: 11
+LeftChild.ClassCounts: 8 3 
+RightChild.size: 28
+RightChild.ClassCounts: 1 27 
+
+minGini: 0.000000 - 3
+Region.size: 28
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 27
+RightChild.ClassCounts: 0 27 
+
+minGini: 0.888888 - 18
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 9
+RightChild.ClassCounts: 8 1 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 2.277777 - 26
+Region.size: 24
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 18
+RightChild.ClassCounts: 17 1 
+
+minGini: 0.750000 - 5
+Region.size: 18
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 18
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.636363 - 12
+Region.size: 30
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 11
+RightChild.ClassCounts: 9 2 
+
+minGini: 0.666666 - 16
+Region.size: 11
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.000000 - 18
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 9 finished.
+
+minGini: 61.076158 - 0
+Region.size: 351
+LeftChild.size: 49
+LeftChild.ClassCounts: 49 0 
+RightChild.size: 302
+RightChild.ClassCounts: 85 217 
+
+minGini: 33.642923 - 4
+Region.size: 302
+LeftChild.size: 52
+LeftChild.ClassCounts: 49 3 
+RightChild.size: 250
+RightChild.ClassCounts: 36 214 
+
+minGini: 18.290598 - 7
+Region.size: 250
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 234
+RightChild.ClassCounts: 20 214 
+
+minGini: 8.633484 - 15
+Region.size: 234
+LeftChild.size: 221
+LeftChild.ClassCounts: 8 213 
+RightChild.size: 13
+RightChild.ClassCounts: 12 1 
+
+minGini: 0.000000 - 9
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 4.885321 - 31
+Region.size: 221
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 218
+RightChild.ClassCounts: 5 213 
+
+minGini: 3.926267 - 28
+Region.size: 218
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 217
+RightChild.ClassCounts: 4 213 
+
+minGini: 2.958333 - 2
+Region.size: 217
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 216
+RightChild.ClassCounts: 3 213 
+
+minGini: 1.981395 - 13
+Region.size: 216
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 215
+RightChild.ClassCounts: 2 213 
+
+minGini: 1.953097 - 30
+Region.size: 215
+LeftChild.size: 191
+LeftChild.ClassCounts: 1 190 
+RightChild.size: 24
+RightChild.ClassCounts: 1 23 
+
+minGini: 0.000000 - 23
+Region.size: 24
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 23 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.857142 - 7
+Region.size: 191
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 
+RightChild.size: 184
+RightChild.ClassCounts: 0 184 
+
+minGini: 0.000000 - 30
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 2.357142 - 28
+Region.size: 52
+LeftChild.size: 38
+LeftChild.ClassCounts: 38 0 
+RightChild.size: 14
+RightChild.ClassCounts: 11 3 
+
+minGini: 0.916666 - 9
+Region.size: 14
+LeftChild.size: 12
+LeftChild.ClassCounts: 11 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.500000 - 28
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.000000 - 16
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 10 finished.
+
+minGini: 57.082352 - 30
+Region.size: 351
+LeftChild.size: 96
+LeftChild.ClassCounts: 64 32 
+RightChild.size: 255
+RightChild.ClassCounts: 43 212 
+
+minGini: 23.949790 - 17
+Region.size: 255
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 239
+RightChild.ClassCounts: 27 212 
+
+minGini: 13.132743 - 4
+Region.size: 239
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 226
+RightChild.ClassCounts: 14 212 
+
+minGini: 5.834862 - 3
+Region.size: 226
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 218
+RightChild.ClassCounts: 6 212 
+
+minGini: 3.217437 - 31
+Region.size: 218
+LeftChild.size: 209
+LeftChild.ClassCounts: 1 208 
+RightChild.size: 9
+RightChild.ClassCounts: 5 4 
+
+minGini: 1.333333 - 7
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.666666 - 10
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 11
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 2
+Region.size: 209
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 208
+RightChild.ClassCounts: 0 208 
+
+minGini: 10.497354 - 15
+Region.size: 96
+LeftChild.size: 54
+LeftChild.ClassCounts: 52 2 
+RightChild.size: 42
+RightChild.ClassCounts: 12 30 
+
+minGini: 0.967741 - 6
+Region.size: 42
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 31
+RightChild.ClassCounts: 1 30 
+
+minGini: 0.000000 - 21
+Region.size: 31
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 30
+RightChild.ClassCounts: 0 30 
+
+minGini: 1.733333 - 17
+Region.size: 54
+LeftChild.size: 15
+LeftChild.ClassCounts: 13 2 
+RightChild.size: 39
+RightChild.ClassCounts: 39 0 
+
+minGini: 0.928571 - 31
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 14
+RightChild.ClassCounts: 13 1 
+
+minGini: 0.000000 - 23
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+
+
+Tree Number: 11 finished.
+
+minGini: 57.440740 - 26
+Region.size: 351
+LeftChild.size: 270
+LeftChild.ClassCounts: 61 209 
+RightChild.size: 81
+RightChild.ClassCounts: 69 12 
+
+minGini: 8.800000 - 4
+Region.size: 81
+LeftChild.size: 36
+LeftChild.ClassCounts: 36 0 
+RightChild.size: 45
+RightChild.ClassCounts: 33 12 
+
+minGini: 6.461538 - 32
+Region.size: 45
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 26
+RightChild.ClassCounts: 14 12 
+
+minGini: 4.000000 - 33
+Region.size: 26
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 18
+RightChild.ClassCounts: 6 12 
+
+minGini: 1.714285 - 19
+Region.size: 18
+LeftChild.size: 14
+LeftChild.ClassCounts: 2 12 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.923076 - 19
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 13
+RightChild.ClassCounts: 1 12 
+
+minGini: 0.000000 - 6
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 
+
+minGini: 33.365789 - 32
+Region.size: 270
+LeftChild.size: 80
+LeftChild.ClassCounts: 46 34 
+RightChild.size: 190
+RightChild.ClassCounts: 15 175 
+
+minGini: 12.115384 - 26
+Region.size: 190
+LeftChild.size: 78
+LeftChild.ClassCounts: 15 63 
+RightChild.size: 112
+RightChild.ClassCounts: 0 112 
+
+minGini: 9.028571 - 3
+Region.size: 78
+LeftChild.size: 15
+LeftChild.ClassCounts: 9 6 
+RightChild.size: 63
+RightChild.ClassCounts: 6 57 
+
+minGini: 2.850000 - 15
+Region.size: 63
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 60
+RightChild.ClassCounts: 3 57 
+
+minGini: 1.200000 - 4
+Region.size: 60
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 55
+RightChild.ClassCounts: 0 55 
+
+minGini: 0.000000 - 23
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 2.400000 - 32
+Region.size: 15
+LeftChild.size: 10
+LeftChild.ClassCounts: 4 6 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.800000 - 14
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 19
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 8.626373 - 17
+Region.size: 80
+LeftChild.size: 52
+LeftChild.ClassCounts: 44 8 
+RightChild.size: 28
+RightChild.ClassCounts: 2 26 
+
+minGini: 0.000000 - 7
+Region.size: 28
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 
+
+minGini: 4.459574 - 12
+Region.size: 52
+LeftChild.size: 47
+LeftChild.ClassCounts: 43 4 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 9
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 2.906976 - 3
+Region.size: 47
+LeftChild.size: 43
+LeftChild.ClassCounts: 41 2 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 17
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.733333 - 6
+Region.size: 43
+LeftChild.size: 28
+LeftChild.ClassCounts: 28 0 
+RightChild.size: 15
+RightChild.ClassCounts: 13 2 
+
+minGini: 0.000000 - 6
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+
+
+Tree Number: 12 finished.
+
+minGini: 61.985760 - 8
+Region.size: 351
+LeftChild.size: 94
+LeftChild.ClassCounts: 62 32 
+RightChild.size: 257
+RightChild.ClassCounts: 51 206 
+
+minGini: 23.245571 - 4
+Region.size: 257
+LeftChild.size: 27
+LeftChild.ClassCounts: 26 1 
+RightChild.size: 230
+RightChild.ClassCounts: 25 205 
+
+minGini: 14.361739 - 26
+Region.size: 230
+LeftChild.size: 202
+LeftChild.ClassCounts: 8 194 
+RightChild.size: 28
+RightChild.ClassCounts: 17 11 
+
+minGini: 4.928571 - 3
+Region.size: 28
+LeftChild.size: 14
+LeftChild.ClassCounts: 12 2 
+RightChild.size: 14
+RightChild.ClassCounts: 5 9 
+
+minGini: 1.636363 - 29
+Region.size: 14
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 11
+RightChild.ClassCounts: 2 9 
+
+minGini: 0.000000 - 3
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.500000 - 5
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.000000 - 21
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 4.874371 - 6
+Region.size: 202
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 199
+RightChild.ClassCounts: 5 194 
+
+minGini: 4.773809 - 32
+Region.size: 199
+LeftChild.size: 192
+LeftChild.ClassCounts: 4 188 
+RightChild.size: 7
+RightChild.ClassCounts: 1 6 
+
+minGini: 0.000000 - 17
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.952879 - 13
+Region.size: 192
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 191
+RightChild.ClassCounts: 3 188 
+
+minGini: 1.978947 - 3
+Region.size: 191
+LeftChild.size: 190
+LeftChild.ClassCounts: 2 188 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.827898 - 5
+Region.size: 190
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 184
+RightChild.ClassCounts: 1 183 
+
+minGini: 0.967741 - 29
+Region.size: 184
+LeftChild.size: 31
+LeftChild.ClassCounts: 1 30 
+RightChild.size: 153
+RightChild.ClassCounts: 0 153 
+
+minGini: 0.750000 - 31
+Region.size: 31
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 27 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 18
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 18
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 23
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 3
+Region.size: 27
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 13
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 9.973308 - 5
+Region.size: 94
+LeftChild.size: 53
+LeftChild.ClassCounts: 51 2 
+RightChild.size: 41
+RightChild.ClassCounts: 11 30 
+
+minGini: 1.875000 - 3
+Region.size: 41
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 32
+RightChild.ClassCounts: 2 30 
+
+minGini: 0.000000 - 16
+Region.size: 32
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 30 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.500000 - 7
+Region.size: 53
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 2 
+RightChild.size: 45
+RightChild.ClassCounts: 45 0 
+
+minGini: 0.666666 - 16
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 26
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 13 finished.
+
+minGini: 48.513422 - 2
+Region.size: 351
+LeftChild.size: 53
+LeftChild.ClassCounts: 53 0 
+RightChild.size: 298
+RightChild.ClassCounts: 61 237 
+
+minGini: 38.734770 - 19
+Region.size: 298
+LeftChild.size: 281
+LeftChild.ClassCounts: 45 236 
+RightChild.size: 17
+RightChild.ClassCounts: 16 1 
+
+minGini: 0.000000 - 26
+Region.size: 17
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 
+
+minGini: 29.123584 - 19
+Region.size: 281
+LeftChild.size: 16
+LeftChild.ClassCounts: 14 2 
+RightChild.size: 265
+RightChild.ClassCounts: 31 234 
+
+minGini: 24.808416 - 25
+Region.size: 265
+LeftChild.size: 258
+LeftChild.ClassCounts: 26 232 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.666666 - 20
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 33
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 20.275094 - 22
+Region.size: 258
+LeftChild.size: 66
+LeftChild.ClassCounts: 19 47 
+RightChild.size: 192
+RightChild.ClassCounts: 7 185 
+
+minGini: 5.811518 - 31
+Region.size: 192
+LeftChild.size: 191
+LeftChild.ClassCounts: 6 185 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 5.485714 - 12
+Region.size: 191
+LeftChild.size: 70
+LeftChild.ClassCounts: 6 64 
+RightChild.size: 121
+RightChild.ClassCounts: 0 121 
+
+minGini: 3.270833 - 25
+Region.size: 70
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 64
+RightChild.ClassCounts: 2 62 
+
+minGini: 0.984126 - 15
+Region.size: 64
+LeftChild.size: 63
+LeftChild.ClassCounts: 1 62 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.875000 - 7
+Region.size: 63
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 55
+RightChild.ClassCounts: 0 55 
+
+minGini: 0.000000 - 7
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 33
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 4.250000 - 4
+Region.size: 66
+LeftChild.size: 22
+LeftChild.ClassCounts: 18 4 
+RightChild.size: 44
+RightChild.ClassCounts: 1 43 
+
+minGini: 0.000000 - 3
+Region.size: 44
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 43
+RightChild.ClassCounts: 0 43 
+
+minGini: 1.800000 - 8
+Region.size: 22
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 20
+RightChild.ClassCounts: 18 2 
+
+minGini: 1.333333 - 4
+Region.size: 20
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.000000 - 32
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.933333 - 8
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 15
+RightChild.ClassCounts: 14 1 
+
+minGini: 0.000000 - 18
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+
+
+Tree Number: 14 finished.
+
+minGini: 45.904022 - 4
+Region.size: 351
+LeftChild.size: 68
+LeftChild.ClassCounts: 67 1 
+RightChild.size: 283
+RightChild.ClassCounts: 56 227 
+
+minGini: 20.794210 - 26
+Region.size: 283
+LeftChild.size: 227
+LeftChild.ClassCounts: 12 215 
+RightChild.size: 56
+RightChild.ClassCounts: 44 12 
+
+minGini: 6.857142 - 13
+Region.size: 56
+LeftChild.size: 28
+LeftChild.ClassCounts: 28 0 
+RightChild.size: 28
+RightChild.ClassCounts: 16 12 
+
+minGini: 3.000000 - 18
+Region.size: 28
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 16
+RightChild.ClassCounts: 4 12 
+
+minGini: 0.923076 - 21
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 1 12 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 12
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 
+
+minGini: 9.386771 - 25
+Region.size: 227
+LeftChild.size: 223
+LeftChild.ClassCounts: 9 214 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 8.345470 - 8
+Region.size: 223
+LeftChild.size: 99
+LeftChild.ClassCounts: 8 91 
+RightChild.size: 124
+RightChild.ClassCounts: 1 123 
+
+minGini: 0.000000 - 24
+Region.size: 124
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 123
+RightChild.ClassCounts: 0 123 
+
+minGini: 5.628865 - 8
+Region.size: 99
+LeftChild.size: 97
+LeftChild.ClassCounts: 6 91 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 5.142857 - 2
+Region.size: 97
+LeftChild.size: 42
+LeftChild.ClassCounts: 6 36 
+RightChild.size: 55
+RightChild.ClassCounts: 0 55 
+
+minGini: 3.695014 - 11
+Region.size: 42
+LeftChild.size: 11
+LeftChild.ClassCounts: 5 6 
+RightChild.size: 31
+RightChild.ClassCounts: 1 30 
+
+minGini: 0.750000 - 22
+Region.size: 31
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 27
+RightChild.ClassCounts: 0 27 
+
+minGini: 0.000000 - 9
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.500000 - 27
+Region.size: 11
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 8
+RightChild.ClassCounts: 2 6 
+
+minGini: 0.000000 - 22
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.857142 - 5
+Region.size: 68
+LeftChild.size: 61
+LeftChild.ClassCounts: 61 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 15 finished.
+
+minGini: 41.610108 - 4
+Region.size: 351
+LeftChild.size: 74
+LeftChild.ClassCounts: 74 0 
+RightChild.size: 277
+RightChild.ClassCounts: 51 226 
+
+minGini: 30.306513 - 17
+Region.size: 277
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 261
+RightChild.ClassCounts: 35 226 
+
+minGini: 24.913385 - 2
+Region.size: 261
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 254
+RightChild.ClassCounts: 28 226 
+
+minGini: 18.373983 - 23
+Region.size: 254
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 246
+RightChild.ClassCounts: 20 226 
+
+minGini: 14.066390 - 5
+Region.size: 246
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 241
+RightChild.ClassCounts: 15 226 
+
+minGini: 11.394957 - 7
+Region.size: 241
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 238
+RightChild.ClassCounts: 12 226 
+
+minGini: 10.150862 - 13
+Region.size: 238
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 
+RightChild.size: 232
+RightChild.ClassCounts: 9 223 
+
+minGini: 7.984140 - 13
+Region.size: 232
+LeftChild.size: 227
+LeftChild.ClassCounts: 7 220 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.000000 - 33
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 3.928571 - 9
+Region.size: 227
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 224
+RightChild.ClassCounts: 4 220 
+
+minGini: 3.465757 - 2
+Region.size: 224
+LeftChild.size: 17
+LeftChild.ClassCounts: 3 14 
+RightChild.size: 207
+RightChild.ClassCounts: 1 206 
+
+minGini: 0.982758 - 23
+Region.size: 207
+LeftChild.size: 58
+LeftChild.ClassCounts: 1 57 
+RightChild.size: 149
+RightChild.ClassCounts: 0 149 
+
+minGini: 0.666666 - 3
+Region.size: 58
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 55
+RightChild.ClassCounts: 0 55 
+
+minGini: 0.000000 - 14
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 2
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 11
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+
+
+Tree Number: 16 finished.
+
+minGini: 50.339594 - 26
+Region.size: 351
+LeftChild.size: 277
+LeftChild.ClassCounts: 50 227 
+RightChild.size: 74
+RightChild.ClassCounts: 63 11 
+
+minGini: 7.218750 - 2
+Region.size: 74
+LeftChild.size: 42
+LeftChild.ClassCounts: 42 0 
+RightChild.size: 32
+RightChild.ClassCounts: 21 11 
+
+minGini: 4.190909 - 9
+Region.size: 32
+LeftChild.size: 10
+LeftChild.ClassCounts: 2 8 
+RightChild.size: 22
+RightChild.ClassCounts: 19 3 
+
+minGini: 1.500000 - 11
+Region.size: 22
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 
+
+minGini: 1.200000 - 23
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 15
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.888888 - 31
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 
+
+minGini: 0.000000 - 32
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 33.227991 - 22
+Region.size: 277
+LeftChild.size: 117
+LeftChild.ClassCounts: 44 73 
+RightChild.size: 160
+RightChild.ClassCounts: 6 154 
+
+minGini: 3.898734 - 15
+Region.size: 160
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 158
+RightChild.ClassCounts: 4 154 
+
+minGini: 2.942675 - 18
+Region.size: 158
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 157
+RightChild.ClassCounts: 3 154 
+
+minGini: 2.742907 - 8
+Region.size: 157
+LeftChild.size: 16
+LeftChild.ClassCounts: 2 14 
+RightChild.size: 141
+RightChild.ClassCounts: 1 140 
+
+minGini: 0.960000 - 28
+Region.size: 141
+LeftChild.size: 25
+LeftChild.ClassCounts: 1 24 
+RightChild.size: 116
+RightChild.ClassCounts: 0 116 
+
+minGini: 0.000000 - 28
+Region.size: 25
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 24 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 16
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 19.165789 - 16
+Region.size: 117
+LeftChild.size: 60
+LeftChild.ClassCounts: 7 53 
+RightChild.size: 57
+RightChild.ClassCounts: 37 20 
+
+minGini: 2.608695 - 4
+Region.size: 57
+LeftChild.size: 34
+LeftChild.ClassCounts: 34 0 
+RightChild.size: 23
+RightChild.ClassCounts: 3 20 
+
+minGini: 0.000000 - 12
+Region.size: 23
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 20
+RightChild.ClassCounts: 0 20 
+
+minGini: 1.927272 - 11
+Region.size: 60
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 55
+RightChild.ClassCounts: 2 53 
+
+minGini: 0.000000 - 20
+Region.size: 55
+LeftChild.size: 53
+LeftChild.ClassCounts: 0 53 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 17 finished.
+
+minGini: 57.023097 - 27
+Region.size: 351
+LeftChild.size: 44
+LeftChild.ClassCounts: 42 2 
+RightChild.size: 307
+RightChild.ClassCounts: 72 235 
+
+minGini: 46.286001 - 3
+Region.size: 307
+LeftChild.size: 19
+LeftChild.ClassCounts: 17 2 
+RightChild.size: 288
+RightChild.ClassCounts: 55 233 
+
+minGini: 22.799675 - 4
+Region.size: 288
+LeftChild.size: 34
+LeftChild.ClassCounts: 32 2 
+RightChild.size: 254
+RightChild.ClassCounts: 23 231 
+
+minGini: 14.085365 - 5
+Region.size: 254
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 246
+RightChild.ClassCounts: 15 231 
+
+minGini: 11.407407 - 13
+Region.size: 246
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 243
+RightChild.ClassCounts: 12 231 
+
+minGini: 9.411087 - 15
+Region.size: 243
+LeftChild.size: 239
+LeftChild.ClassCounts: 9 230 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 30
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 7.435805 - 26
+Region.size: 239
+LeftChild.size: 228
+LeftChild.ClassCounts: 5 223 
+RightChild.size: 11
+RightChild.ClassCounts: 4 7 
+
+minGini: 0.000000 - 13
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 4.630928 - 8
+Region.size: 228
+LeftChild.size: 44
+LeftChild.ClassCounts: 4 40 
+RightChild.size: 184
+RightChild.ClassCounts: 1 183 
+
+minGini: 0.980392 - 4
+Region.size: 184
+LeftChild.size: 133
+LeftChild.ClassCounts: 0 133 
+RightChild.size: 51
+RightChild.ClassCounts: 1 50 
+
+minGini: 0.000000 - 9
+Region.size: 51
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 50
+RightChild.ClassCounts: 0 50 
+
+minGini: 1.904761 - 8
+Region.size: 44
+LeftChild.size: 42
+LeftChild.ClassCounts: 2 40 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.333333 - 2
+Region.size: 42
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 36
+RightChild.ClassCounts: 0 36 
+
+minGini: 0.000000 - 17
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.428571 - 32
+Region.size: 34
+LeftChild.size: 27
+LeftChild.ClassCounts: 27 0 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.666666 - 30
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 28
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.200000 - 8
+Region.size: 19
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.428571 - 18
+Region.size: 44
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 37
+RightChild.ClassCounts: 37 0 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 18 finished.
+
+minGini: 51.834459 - 2
+Region.size: 351
+LeftChild.size: 55
+LeftChild.ClassCounts: 55 0 
+RightChild.size: 296
+RightChild.ClassCounts: 67 229 
+
+minGini: 37.393775 - 5
+Region.size: 296
+LeftChild.size: 29
+LeftChild.ClassCounts: 26 3 
+RightChild.size: 267
+RightChild.ClassCounts: 41 226 
+
+minGini: 20.048387 - 4
+Region.size: 267
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 248
+RightChild.ClassCounts: 22 226 
+
+minGini: 14.066390 - 0
+Region.size: 248
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 241
+RightChild.ClassCounts: 15 226 
+
+minGini: 10.489451 - 7
+Region.size: 241
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 237
+RightChild.ClassCounts: 11 226 
+
+minGini: 10.044374 - 19
+Region.size: 237
+LeftChild.size: 166
+LeftChild.ClassCounts: 3 163 
+RightChild.size: 71
+RightChild.ClassCounts: 8 63 
+
+minGini: 4.632352 - 23
+Region.size: 71
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 68
+RightChild.ClassCounts: 5 63 
+
+minGini: 2.863636 - 19
+Region.size: 68
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 66
+RightChild.ClassCounts: 3 63 
+
+minGini: 0.000000 - 6
+Region.size: 66
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 63
+RightChild.ClassCounts: 0 63 
+
+minGini: 1.975757 - 21
+Region.size: 166
+LeftChild.size: 165
+LeftChild.ClassCounts: 2 163 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.921948 - 22
+Region.size: 165
+LeftChild.size: 151
+LeftChild.ClassCounts: 1 150 
+RightChild.size: 14
+RightChild.ClassCounts: 1 13 
+
+minGini: 0.000000 - 8
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.982758 - 5
+Region.size: 151
+LeftChild.size: 58
+LeftChild.ClassCounts: 1 57 
+RightChild.size: 93
+RightChild.ClassCounts: 0 93 
+
+minGini: 0.000000 - 5
+Region.size: 58
+LeftChild.size: 57
+LeftChild.ClassCounts: 0 57 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.158333 - 9
+Region.size: 29
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 24
+RightChild.ClassCounts: 23 1 
+
+minGini: 0.833333 - 18
+Region.size: 24
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 18
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 25
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 19 finished.
+
+minGini: 42.655115 - 4
+Region.size: 351
+LeftChild.size: 61
+LeftChild.ClassCounts: 59 2 
+RightChild.size: 290
+RightChild.ClassCounts: 49 241 
+
+minGini: 21.849775 - 26
+Region.size: 290
+LeftChild.size: 241
+LeftChild.ClassCounts: 13 228 
+RightChild.size: 49
+RightChild.ClassCounts: 36 13 
+
+minGini: 5.958333 - 32
+Region.size: 49
+LeftChild.size: 25
+LeftChild.ClassCounts: 25 0 
+RightChild.size: 24
+RightChild.ClassCounts: 11 13 
+
+minGini: 1.733333 - 3
+Region.size: 24
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 15
+RightChild.ClassCounts: 2 13 
+
+minGini: 0.000000 - 17
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 8.658227 - 15
+Region.size: 241
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 237
+RightChild.ClassCounts: 9 228 
+
+minGini: 6.791489 - 23
+Region.size: 237
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 235
+RightChild.ClassCounts: 7 228 
+
+minGini: 6.345493 - 3
+Region.size: 235
+LeftChild.size: 233
+LeftChild.ClassCounts: 6 227 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 23
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 5.336977 - 17
+Region.size: 233
+LeftChild.size: 195
+LeftChild.ClassCounts: 1 194 
+RightChild.size: 38
+RightChild.ClassCounts: 5 33 
+
+minGini: 1.428571 - 2
+Region.size: 38
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 31
+RightChild.ClassCounts: 0 31 
+
+minGini: 0.000000 - 7
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.973684 - 2
+Region.size: 195
+LeftChild.size: 38
+LeftChild.ClassCounts: 1 37 
+RightChild.size: 157
+RightChild.ClassCounts: 0 157 
+
+minGini: 0.500000 - 27
+Region.size: 38
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 36
+RightChild.ClassCounts: 0 36 
+
+minGini: 0.000000 - 21
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.692307 - 20
+Region.size: 61
+LeftChild.size: 13
+LeftChild.ClassCounts: 11 2 
+RightChild.size: 48
+RightChild.ClassCounts: 48 0 
+
+minGini: 0.000000 - 20
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 20 finished.
+
+minGini: 51.725373 - 6
+Region.size: 351
+LeftChild.size: 58
+LeftChild.ClassCounts: 55 3 
+RightChild.size: 293
+RightChild.ClassCounts: 62 231 
+
+minGini: 31.146067 - 3
+Region.size: 293
+LeftChild.size: 26
+LeftChild.ClassCounts: 26 0 
+RightChild.size: 267
+RightChild.ClassCounts: 36 231 
+
+minGini: 24.972972 - 0
+Region.size: 267
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 259
+RightChild.ClassCounts: 28 231 
+
+minGini: 14.943415 - 4
+Region.size: 259
+LeftChild.size: 16
+LeftChild.ClassCounts: 14 2 
+RightChild.size: 243
+RightChild.ClassCounts: 14 229 
+
+minGini: 8.659663 - 15
+Region.size: 243
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 238
+RightChild.ClassCounts: 9 229 
+
+minGini: 7.539215 - 22
+Region.size: 238
+LeftChild.size: 204
+LeftChild.ClassCounts: 2 202 
+RightChild.size: 34
+RightChild.ClassCounts: 7 27 
+
+minGini: 1.820105 - 23
+Region.size: 34
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 27
+RightChild.ClassCounts: 1 26 
+
+minGini: 0.000000 - 2
+Region.size: 27
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 
+
+minGini: 0.000000 - 19
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 1.661691 - 13
+Region.size: 204
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 201
+RightChild.ClassCounts: 1 200 
+
+minGini: 0.956521 - 26
+Region.size: 201
+LeftChild.size: 23
+LeftChild.ClassCounts: 1 22 
+RightChild.size: 178
+RightChild.ClassCounts: 0 178 
+
+minGini: 0.000000 - 24
+Region.size: 23
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 22 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 9
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 12
+Region.size: 16
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 2.437500 - 23
+Region.size: 58
+LeftChild.size: 16
+LeftChild.ClassCounts: 13 3 
+RightChild.size: 42
+RightChild.ClassCounts: 42 0 
+
+minGini: 1.589743 - 13
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 12 1 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.666666 - 5
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.000000 - 30
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 21 finished.
+
+minGini: 69.158649 - 8
+Region.size: 351
+LeftChild.size: 69
+LeftChild.ClassCounts: 53 16 
+RightChild.size: 282
+RightChild.ClassCounts: 79 203 
+
+minGini: 31.823117 - 26
+Region.size: 282
+LeftChild.size: 214
+LeftChild.ClassCounts: 24 190 
+RightChild.size: 68
+RightChild.ClassCounts: 55 13 
+
+minGini: 8.552631 - 9
+Region.size: 68
+LeftChild.size: 38
+LeftChild.ClassCounts: 25 13 
+RightChild.size: 30
+RightChild.ClassCounts: 30 0 
+
+minGini: 6.814285 - 31
+Region.size: 38
+LeftChild.size: 10
+LeftChild.ClassCounts: 3 7 
+RightChild.size: 28
+RightChild.ClassCounts: 22 6 
+
+minGini: 3.428571 - 8
+Region.size: 28
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 14
+RightChild.ClassCounts: 8 6 
+
+minGini: 2.000000 - 30
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 0.000000 - 3
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 7
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 18.909952 - 9
+Region.size: 214
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 211
+RightChild.ClassCounts: 21 190 
+
+minGini: 9.500000 - 2
+Region.size: 211
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 200
+RightChild.ClassCounts: 10 190 
+
+minGini: 8.851402 - 16
+Region.size: 200
+LeftChild.size: 71
+LeftChild.ClassCounts: 9 62 
+RightChild.size: 129
+RightChild.ClassCounts: 1 128 
+
+minGini: 0.888888 - 25
+Region.size: 129
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 120
+RightChild.ClassCounts: 0 120 
+
+minGini: 0.000000 - 11
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 5.252459 - 18
+Region.size: 71
+LeftChild.size: 61
+LeftChild.ClassCounts: 3 58 
+RightChild.size: 10
+RightChild.ClassCounts: 6 4 
+
+minGini: 1.333333 - 29
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 11
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.649425 - 24
+Region.size: 61
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 58
+RightChild.ClassCounts: 1 57 
+
+minGini: 0.928571 - 5
+Region.size: 58
+LeftChild.size: 14
+LeftChild.ClassCounts: 1 13 
+RightChild.size: 44
+RightChild.ClassCounts: 0 44 
+
+minGini: 0.000000 - 9
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 9
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 4.869565 - 5
+Region.size: 69
+LeftChild.size: 46
+LeftChild.ClassCounts: 46 0 
+RightChild.size: 23
+RightChild.ClassCounts: 7 16 
+
+minGini: 1.777777 - 22
+Region.size: 23
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 18
+RightChild.ClassCounts: 2 16 
+
+minGini: 0.000000 - 3
+Region.size: 18
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 16 
+
+
+
+Tree Number: 22 finished.
+
+minGini: 47.022212 - 6
+Region.size: 351
+LeftChild.size: 62
+LeftChild.ClassCounts: 58 4 
+RightChild.size: 289
+RightChild.ClassCounts: 53 236 
+
+minGini: 29.718518 - 2
+Region.size: 289
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 270
+RightChild.ClassCounts: 34 236 
+
+minGini: 24.228136 - 5
+Region.size: 270
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 263
+RightChild.ClassCounts: 27 236 
+
+minGini: 13.179340 - 7
+Region.size: 263
+LeftChild.size: 17
+LeftChild.ClassCounts: 15 2 
+RightChild.size: 246
+RightChild.ClassCounts: 12 234 
+
+minGini: 8.666666 - 19
+Region.size: 246
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 243
+RightChild.ClassCounts: 9 234 
+
+minGini: 8.147752 - 23
+Region.size: 243
+LeftChild.size: 184
+LeftChild.ClassCounts: 2 182 
+RightChild.size: 59
+RightChild.ClassCounts: 7 52 
+
+minGini: 4.163522 - 8
+Region.size: 59
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 53
+RightChild.ClassCounts: 3 50 
+
+minGini: 1.714285 - 11
+Region.size: 53
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 
+RightChild.size: 46
+RightChild.ClassCounts: 0 46 
+
+minGini: 0.000000 - 23
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.994535 - 31
+Region.size: 184
+LeftChild.size: 183
+LeftChild.ClassCounts: 1 182 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 15
+Region.size: 183
+LeftChild.size: 179
+LeftChild.ClassCounts: 0 179 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 33
+Region.size: 17
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 
+
+minGini: 3.111111 - 4
+Region.size: 62
+LeftChild.size: 44
+LeftChild.ClassCounts: 44 0 
+RightChild.size: 18
+RightChild.ClassCounts: 14 4 
+
+minGini: 1.333333 - 26
+Region.size: 18
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 
+
+minGini: 0.000000 - 28
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+
+
+Tree Number: 23 finished.
+
+minGini: 49.649601 - 4
+Region.size: 351
+LeftChild.size: 66
+LeftChild.ClassCounts: 63 3 
+RightChild.size: 285
+RightChild.ClassCounts: 59 226 
+
+minGini: 31.053435 - 13
+Region.size: 285
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 262
+RightChild.ClassCounts: 36 226 
+
+minGini: 24.913385 - 3
+Region.size: 262
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 254
+RightChild.ClassCounts: 28 226 
+
+minGini: 21.730639 - 23
+Region.size: 254
+LeftChild.size: 243
+LeftChild.ClassCounts: 21 222 
+RightChild.size: 11
+RightChild.ClassCounts: 7 4 
+
+minGini: 1.555555 - 32
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.666666 - 15
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 32
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 14.050632 - 33
+Region.size: 243
+LeftChild.size: 237
+LeftChild.ClassCounts: 15 222 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 13.169491 - 9
+Region.size: 237
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 236
+RightChild.ClassCounts: 14 222 
+
+minGini: 12.624344 - 22
+Region.size: 236
+LeftChild.size: 202
+LeftChild.ClassCounts: 8 194 
+RightChild.size: 34
+RightChild.ClassCounts: 6 28 
+
+minGini: 1.797619 - 6
+Region.size: 34
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 28
+RightChild.ClassCounts: 1 27 
+
+minGini: 0.000000 - 20
+Region.size: 28
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 27
+RightChild.ClassCounts: 0 27 
+
+minGini: 0.000000 - 15
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 7.251338 - 3
+Region.size: 202
+LeftChild.size: 36
+LeftChild.ClassCounts: 5 31 
+RightChild.size: 166
+RightChild.ClassCounts: 3 163 
+
+minGini: 2.642126 - 20
+Region.size: 166
+LeftChild.size: 163
+LeftChild.ClassCounts: 2 161 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 32
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.793670 - 3
+Region.size: 163
+LeftChild.size: 158
+LeftChild.ClassCounts: 1 157 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.888888 - 2
+Region.size: 158
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 149
+RightChild.ClassCounts: 0 149 
+
+minGini: 0.000000 - 25
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.735294 - 12
+Region.size: 36
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 34
+RightChild.ClassCounts: 3 31 
+
+minGini: 1.878787 - 13
+Region.size: 34
+LeftChild.size: 33
+LeftChild.ClassCounts: 2 31 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.750000 - 20
+Region.size: 33
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 17 
+RightChild.size: 16
+RightChild.ClassCounts: 2 14 
+
+minGini: 0.000000 - 8
+Region.size: 16
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 2.250000 - 29
+Region.size: 66
+LeftChild.size: 54
+LeftChild.ClassCounts: 54 0 
+RightChild.size: 12
+RightChild.ClassCounts: 9 3 
+
+minGini: 1.200000 - 16
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 30
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+
+
+Tree Number: 24 finished.
+
+minGini: 63.123028 - 0
+Region.size: 351
+LeftChild.size: 34
+LeftChild.ClassCounts: 34 0 
+RightChild.size: 317
+RightChild.ClassCounts: 87 230 
+
+minGini: 52.602843 - 20
+Region.size: 317
+LeftChild.size: 114
+LeftChild.ClassCounts: 59 55 
+RightChild.size: 203
+RightChild.ClassCounts: 28 175 
+
+minGini: 14.659685 - 2
+Region.size: 203
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 191
+RightChild.ClassCounts: 16 175 
+
+minGini: 10.349462 - 3
+Region.size: 191
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 186
+RightChild.ClassCounts: 11 175 
+
+minGini: 8.559782 - 15
+Region.size: 186
+LeftChild.size: 184
+LeftChild.ClassCounts: 9 175 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 6.730769 - 13
+Region.size: 184
+LeftChild.size: 182
+LeftChild.ClassCounts: 7 175 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 5.725308 - 10
+Region.size: 182
+LeftChild.size: 20
+LeftChild.ClassCounts: 5 15 
+RightChild.size: 162
+RightChild.ClassCounts: 2 160 
+
+minGini: 1.493750 - 5
+Region.size: 162
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 160
+RightChild.ClassCounts: 1 159 
+
+minGini: 0.000000 - 9
+Region.size: 160
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 159
+RightChild.ClassCounts: 0 159 
+
+minGini: 0.000000 - 12
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.937500 - 22
+Region.size: 20
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 16
+RightChild.ClassCounts: 1 15 
+
+minGini: 0.000000 - 19
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 15.197368 - 20
+Region.size: 114
+LeftChild.size: 76
+LeftChild.ClassCounts: 21 55 
+RightChild.size: 38
+RightChild.ClassCounts: 38 0 
+
+minGini: 8.640079 - 6
+Region.size: 76
+LeftChild.size: 17
+LeftChild.ClassCounts: 14 3 
+RightChild.size: 59
+RightChild.ClassCounts: 7 52 
+
+minGini: 2.836363 - 24
+Region.size: 59
+LeftChild.size: 55
+LeftChild.ClassCounts: 3 52 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 1.200000 - 5
+Region.size: 55
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 50
+RightChild.ClassCounts: 0 50 
+
+minGini: 0.000000 - 9
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.750000 - 3
+Region.size: 17
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 33
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+
+
+Tree Number: 25 finished.
+
+minGini: 65.614919 - 9
+Region.size: 351
+LeftChild.size: 308
+LeftChild.ClassCounts: 86 222 
+RightChild.size: 43
+RightChild.ClassCounts: 39 4 
+
+minGini: 2.933333 - 18
+Region.size: 43
+LeftChild.size: 15
+LeftChild.ClassCounts: 11 4 
+RightChild.size: 28
+RightChild.ClassCounts: 28 0 
+
+minGini: 0.800000 - 29
+Region.size: 15
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.000000 - 33
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 32.673798 - 4
+Region.size: 308
+LeftChild.size: 50
+LeftChild.ClassCounts: 49 1 
+RightChild.size: 258
+RightChild.ClassCounts: 37 221 
+
+minGini: 24.060483 - 23
+Region.size: 258
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 248
+RightChild.ClassCounts: 27 221 
+
+minGini: 20.831967 - 15
+Region.size: 248
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 244
+RightChild.ClassCounts: 23 221 
+
+minGini: 16.592355 - 26
+Region.size: 244
+LeftChild.size: 223
+LeftChild.ClassCounts: 12 211 
+RightChild.size: 21
+RightChild.ClassCounts: 11 10 
+
+minGini: 2.307692 - 28
+Region.size: 21
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 13
+RightChild.ClassCounts: 3 10 
+
+minGini: 0.000000 - 27
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 10.892307 - 20
+Region.size: 223
+LeftChild.size: 130
+LeftChild.ClassCounts: 12 118 
+RightChild.size: 93
+RightChild.ClassCounts: 0 93 
+
+minGini: 8.030197 - 20
+Region.size: 130
+LeftChild.size: 123
+LeftChild.ClassCounts: 7 116 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.833333 - 8
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 4.793388 - 2
+Region.size: 123
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 121
+RightChild.ClassCounts: 5 116 
+
+minGini: 4.365546 - 30
+Region.size: 121
+LeftChild.size: 119
+LeftChild.ClassCounts: 4 115 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 8
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.390384 - 3
+Region.size: 119
+LeftChild.size: 15
+LeftChild.ClassCounts: 3 12 
+RightChild.size: 104
+RightChild.ClassCounts: 1 103 
+
+minGini: 0.947368 - 6
+Region.size: 104
+LeftChild.size: 19
+LeftChild.ClassCounts: 1 18 
+RightChild.size: 85
+RightChild.ClassCounts: 0 85 
+
+minGini: 0.000000 - 10
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.923076 - 17
+Region.size: 15
+LeftChild.size: 13
+LeftChild.ClassCounts: 1 12 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.800000 - 6
+Region.size: 13
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 0.000000 - 22
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.900000 - 31
+Region.size: 50
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 40
+RightChild.ClassCounts: 40 0 
+
+minGini: 0.500000 - 11
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 11
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 26 finished.
+
+minGini: 50.396852 - 26
+Region.size: 351
+LeftChild.size: 251
+LeftChild.ClassCounts: 44 207 
+RightChild.size: 100
+RightChild.ClassCounts: 83 17 
+
+minGini: 11.927272 - 18
+Region.size: 100
+LeftChild.size: 55
+LeftChild.ClassCounts: 53 2 
+RightChild.size: 45
+RightChild.ClassCounts: 30 15 
+
+minGini: 6.964285 - 7
+Region.size: 45
+LeftChild.size: 17
+LeftChild.ClassCounts: 17 0 
+RightChild.size: 28
+RightChild.ClassCounts: 13 15 
+
+minGini: 4.011111 - 27
+Region.size: 28
+LeftChild.size: 18
+LeftChild.ClassCounts: 4 14 
+RightChild.size: 10
+RightChild.ClassCounts: 9 1 
+
+minGini: 0.666666 - 9
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.933333 - 29
+Region.size: 18
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 15
+RightChild.ClassCounts: 1 14 
+
+minGini: 0.000000 - 30
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 1.555555 - 10
+Region.size: 55
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 46
+RightChild.ClassCounts: 46 0 
+
+minGini: 0.000000 - 28
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 19.886462 - 2
+Region.size: 251
+LeftChild.size: 22
+LeftChild.ClassCounts: 22 0 
+RightChild.size: 229
+RightChild.ClassCounts: 22 207 
+
+minGini: 16.560000 - 30
+Region.size: 229
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 225
+RightChild.ClassCounts: 18 207 
+
+minGini: 9.366197 - 6
+Region.size: 225
+LeftChild.size: 12
+LeftChild.ClassCounts: 10 2 
+RightChild.size: 213
+RightChild.ClassCounts: 8 205 
+
+minGini: 6.321182 - 24
+Region.size: 213
+LeftChild.size: 203
+LeftChild.ClassCounts: 4 199 
+RightChild.size: 10
+RightChild.ClassCounts: 4 6 
+
+minGini: 0.000000 - 10
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 3.589743 - 3
+Region.size: 203
+LeftChild.size: 39
+LeftChild.ClassCounts: 4 35 
+RightChild.size: 164
+RightChild.ClassCounts: 0 164 
+
+minGini: 1.721428 - 16
+Region.size: 39
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 35
+RightChild.ClassCounts: 1 34 
+
+minGini: 0.000000 - 3
+Region.size: 35
+LeftChild.size: 34
+LeftChild.ClassCounts: 0 34 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 21
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 22
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 27 finished.
+
+minGini: 61.337621 - 27
+Region.size: 351
+LeftChild.size: 33
+LeftChild.ClassCounts: 32 1 
+RightChild.size: 318
+RightChild.ClassCounts: 81 237 
+
+minGini: 49.759453 - 21
+Region.size: 318
+LeftChild.size: 293
+LeftChild.ClassCounts: 59 234 
+RightChild.size: 25
+RightChild.ClassCounts: 22 3 
+
+minGini: 2.280701 - 17
+Region.size: 25
+LeftChild.size: 19
+LeftChild.ClassCounts: 18 1 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.000000 - 3
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.833333 - 16
+Region.size: 19
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 0.000000 - 11
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 32.799561 - 6
+Region.size: 293
+LeftChild.size: 44
+LeftChild.ClassCounts: 32 12 
+RightChild.size: 249
+RightChild.ClassCounts: 27 222 
+
+minGini: 16.438461 - 4
+Region.size: 249
+LeftChild.size: 15
+LeftChild.ClassCounts: 12 3 
+RightChild.size: 234
+RightChild.ClassCounts: 15 219 
+
+minGini: 12.271551 - 11
+Region.size: 234
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 232
+RightChild.ClassCounts: 13 219 
+
+minGini: 10.679400 - 27
+Region.size: 232
+LeftChild.size: 188
+LeftChild.ClassCounts: 3 185 
+RightChild.size: 44
+RightChild.ClassCounts: 10 34 
+
+minGini: 1.888888 - 16
+Region.size: 44
+LeftChild.size: 36
+LeftChild.ClassCounts: 2 34 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.971428 - 9
+Region.size: 36
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 35
+RightChild.ClassCounts: 1 34 
+
+minGini: 0.000000 - 27
+Region.size: 35
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 34
+RightChild.ClassCounts: 0 34 
+
+minGini: 2.783556 - 9
+Region.size: 188
+LeftChild.size: 19
+LeftChild.ClassCounts: 2 17 
+RightChild.size: 169
+RightChild.ClassCounts: 1 168 
+
+minGini: 0.950000 - 15
+Region.size: 169
+LeftChild.size: 20
+LeftChild.ClassCounts: 1 19 
+RightChild.size: 149
+RightChild.ClassCounts: 0 149 
+
+minGini: 0.000000 - 26
+Region.size: 20
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 19 
+
+minGini: 0.000000 - 4
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 17 
+
+minGini: 1.583333 - 20
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 12
+RightChild.ClassCounts: 11 1 
+
+minGini: 0.500000 - 15
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.000000 - 33
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 25
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 4.845315 - 21
+Region.size: 44
+LeftChild.size: 17
+LeftChild.ClassCounts: 6 11 
+RightChild.size: 27
+RightChild.ClassCounts: 26 1 
+
+minGini: 0.666666 - 15
+Region.size: 27
+LeftChild.size: 24
+LeftChild.ClassCounts: 24 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 2
+Region.size: 17
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 0.500000 - 15
+Region.size: 33
+LeftChild.size: 31
+LeftChild.ClassCounts: 31 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 16
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 28 finished.
+
+minGini: 43.143859 - 4
+Region.size: 351
+LeftChild.size: 66
+LeftChild.ClassCounts: 66 0 
+RightChild.size: 285
+RightChild.ClassCounts: 53 232 
+
+minGini: 30.411985 - 0
+Region.size: 285
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 
+RightChild.size: 267
+RightChild.ClassCounts: 35 232 
+
+minGini: 21.750000 - 17
+Region.size: 267
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 256
+RightChild.ClassCounts: 24 232 
+
+minGini: 17.121104 - 26
+Region.size: 256
+LeftChild.size: 233
+LeftChild.ClassCounts: 12 221 
+RightChild.size: 23
+RightChild.ClassCounts: 12 11 
+
+minGini: 4.208333 - 8
+Region.size: 23
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 15
+RightChild.ClassCounts: 5 10 
+
+minGini: 1.666666 - 3
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 12
+RightChild.ClassCounts: 2 10 
+
+minGini: 0.909090 - 7
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 11
+RightChild.ClassCounts: 1 10 
+
+minGini: 0.000000 - 15
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 20
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 9.396288 - 21
+Region.size: 233
+LeftChild.size: 229
+LeftChild.ClassCounts: 9 220 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 28
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 6.590000 - 28
+Region.size: 229
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 225
+RightChild.ClassCounts: 6 219 
+
+minGini: 3.709276 - 5
+Region.size: 225
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 221
+RightChild.ClassCounts: 3 218 
+
+minGini: 1.981818 - 19
+Region.size: 221
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 220
+RightChild.ClassCounts: 2 218 
+
+minGini: 1.862068 - 30
+Region.size: 220
+LeftChild.size: 29
+LeftChild.ClassCounts: 2 27 
+RightChild.size: 191
+RightChild.ClassCounts: 0 191 
+
+minGini: 0.964285 - 2
+Region.size: 29
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 28
+RightChild.ClassCounts: 1 27 
+
+minGini: 0.000000 - 10
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 27 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 8
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 16
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+
+
+Tree Number: 29 finished.
+
+minGini: 63.625386 - 30
+Region.size: 351
+LeftChild.size: 101
+LeftChild.ClassCounts: 69 32 
+RightChild.size: 250
+RightChild.ClassCounts: 53 197 
+
+minGini: 26.498855 - 26
+Region.size: 250
+LeftChild.size: 208
+LeftChild.ClassCounts: 21 187 
+RightChild.size: 42
+RightChild.ClassCounts: 32 10 
+
+minGini: 6.666666 - 0
+Region.size: 42
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 30
+RightChild.ClassCounts: 20 10 
+
+minGini: 5.238095 - 29
+Region.size: 30
+LeftChild.size: 21
+LeftChild.ClassCounts: 17 4 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 0.000000 - 17
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 2.400000 - 11
+Region.size: 21
+LeftChild.size: 10
+LeftChild.ClassCounts: 6 4 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 1.333333 - 5
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.800000 - 18
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 13
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 13.886138 - 26
+Region.size: 208
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 202
+RightChild.ClassCounts: 15 187 
+
+minGini: 9.223949 - 33
+Region.size: 202
+LeftChild.size: 193
+LeftChild.ClassCounts: 8 185 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 
+
+minGini: 0.000000 - 9
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 6.744791 - 19
+Region.size: 193
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 192
+RightChild.ClassCounts: 7 185 
+
+minGini: 5.534391 - 3
+Region.size: 192
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 189
+RightChild.ClassCounts: 5 184 
+
+minGini: 3.914893 - 2
+Region.size: 189
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 188
+RightChild.ClassCounts: 4 184 
+
+minGini: 3.703703 - 25
+Region.size: 188
+LeftChild.size: 54
+LeftChild.ClassCounts: 4 50 
+RightChild.size: 134
+RightChild.ClassCounts: 0 134 
+
+minGini: 2.179591 - 29
+Region.size: 54
+LeftChild.size: 49
+LeftChild.ClassCounts: 1 48 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 9
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.909090 - 9
+Region.size: 49
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 38
+RightChild.ClassCounts: 0 38 
+
+minGini: 0.000000 - 21
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 19
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 14.505533 - 7
+Region.size: 101
+LeftChild.size: 46
+LeftChild.ClassCounts: 45 1 
+RightChild.size: 55
+RightChild.ClassCounts: 24 31 
+
+minGini: 6.975000 - 26
+Region.size: 55
+LeftChild.size: 40
+LeftChild.ClassCounts: 9 31 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 
+
+minGini: 0.900000 - 4
+Region.size: 40
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 30
+RightChild.ClassCounts: 0 30 
+
+minGini: 0.000000 - 10
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.900000 - 26
+Region.size: 46
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 36
+RightChild.ClassCounts: 36 0 
+
+minGini: 0.500000 - 8
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 29
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 30 finished.
+
+minGini: 64.700112 - 22
+Region.size: 351
+LeftChild.size: 128
+LeftChild.ClassCounts: 68 60 
+RightChild.size: 223
+RightChild.ClassCounts: 40 183 
+
+minGini: 19.639024 - 0
+Region.size: 223
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 
+RightChild.size: 205
+RightChild.ClassCounts: 22 183 
+
+minGini: 14.713567 - 27
+Region.size: 205
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 199
+RightChild.ClassCounts: 16 183 
+
+minGini: 10.976439 - 9
+Region.size: 199
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 2 
+RightChild.size: 191
+RightChild.ClassCounts: 10 181 
+
+minGini: 8.573684 - 9
+Region.size: 191
+LeftChild.size: 190
+LeftChild.ClassCounts: 9 181 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 6.556451 - 15
+Region.size: 190
+LeftChild.size: 186
+LeftChild.ClassCounts: 6 180 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 19
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 4.864864 - 11
+Region.size: 186
+LeftChild.size: 185
+LeftChild.ClassCounts: 5 180 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.913043 - 33
+Region.size: 185
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 184
+RightChild.ClassCounts: 4 180 
+
+minGini: 2.977777 - 20
+Region.size: 184
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 180
+RightChild.ClassCounts: 2 178 
+
+minGini: 1.428571 - 16
+Region.size: 180
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 5 
+RightChild.size: 173
+RightChild.ClassCounts: 0 173 
+
+minGini: 0.000000 - 26
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 33
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 11.351351 - 5
+Region.size: 128
+LeftChild.size: 54
+LeftChild.ClassCounts: 54 0 
+RightChild.size: 74
+RightChild.ClassCounts: 14 60 
+
+minGini: 3.771505 - 5
+Region.size: 74
+LeftChild.size: 62
+LeftChild.ClassCounts: 3 59 
+RightChild.size: 12
+RightChild.ClassCounts: 11 1 
+
+minGini: 0.500000 - 25
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.000000 - 20
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 13
+Region.size: 62
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 59
+RightChild.ClassCounts: 0 59 
+
+
+
+Tree Number: 31 finished.
+
+ionosphere
+minGini: 40.800000 - 3
+Region.size: 150
+LeftChild.size: 65
+LeftChild.ClassCounts: 65 0 0 
+RightChild.size: 85
+RightChild.ClassCounts: 0 51 34 
+
+minGini: 9.342891 - 3
+Region.size: 85
+LeftChild.size: 54
+LeftChild.ClassCounts: 0 50 4 
+RightChild.size: 31
+RightChild.ClassCounts: 0 1 30 
+
+minGini: 1.333333 - 0
+Region.size: 31
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 2 
+RightChild.size: 28
+RightChild.ClassCounts: 0 0 28 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 
+
+minGini: 5.333333 - 3
+Region.size: 54
+LeftChild.size: 42
+LeftChild.ClassCounts: 0 42 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 8 4 
+
+minGini: 4.114285 - 1
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 2 3 
+RightChild.size: 7
+RightChild.ClassCounts: 0 6 1 
+
+minGini: 1.500000 - 3
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 1 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+minGini: 1.333333 - 0
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 1 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 0 finished.
+
+minGini: 52.000000 - 3
+Region.size: 150
+LeftChild.size: 46
+LeftChild.ClassCounts: 46 0 0 
+RightChild.size: 104
+RightChild.ClassCounts: 0 52 52 
+
+minGini: 15.344262 - 2
+Region.size: 104
+LeftChild.size: 43
+LeftChild.ClassCounts: 0 43 0 
+RightChild.size: 61
+RightChild.ClassCounts: 0 9 52 
+
+minGini: 4.500000 - 3
+Region.size: 61
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 9 3 
+RightChild.size: 49
+RightChild.ClassCounts: 0 0 49 
+
+minGini: 3.272727 - 1
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 0 9 2 
+
+minGini: 2.857142 - 1
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 5 2 
+
+minGini: 1.666666 - 0
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 5 1 
+
+minGini: 1.333333 - 1
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 1 finished.
+
+minGini: 48.979591 - 2
+Region.size: 150
+LeftChild.size: 52
+LeftChild.ClassCounts: 52 0 0 
+RightChild.size: 98
+RightChild.ClassCounts: 0 50 48 
+
+minGini: 14.625000 - 2
+Region.size: 98
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 45 3 
+RightChild.size: 50
+RightChild.ClassCounts: 0 5 45 
+
+minGini: 5.382059 - 0
+Region.size: 50
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 4 3 
+RightChild.size: 43
+RightChild.ClassCounts: 0 1 42 
+
+minGini: 1.333333 - 3
+Region.size: 43
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 2 
+RightChild.size: 40
+RightChild.ClassCounts: 0 0 40 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 
+
+minGini: 0.000000 - 0
+Region.size: 48
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 45
+RightChild.ClassCounts: 0 45 0 
+
+
+
+Tree Number: 2 finished.
+
+minGini: 47.979166 - 3
+Region.size: 150
+LeftChild.size: 54
+LeftChild.ClassCounts: 54 0 0 
+RightChild.size: 96
+RightChild.ClassCounts: 0 49 47 
+
+minGini: 9.466086 - 2
+Region.size: 96
+LeftChild.size: 50
+LeftChild.ClassCounts: 0 47 3 
+RightChild.size: 46
+RightChild.ClassCounts: 0 2 44 
+
+minGini: 2.857142 - 3
+Region.size: 46
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 2 5 
+RightChild.size: 39
+RightChild.ClassCounts: 0 0 39 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+minGini: 2.400000 - 3
+Region.size: 50
+LeftChild.size: 45
+LeftChild.ClassCounts: 0 45 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 2 3 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+
+
+Tree Number: 3 finished.
+
+minGini: 48.265306 - 2
+Region.size: 150
+LeftChild.size: 52
+LeftChild.ClassCounts: 52 0 0 
+RightChild.size: 98
+RightChild.ClassCounts: 0 55 43 
+
+minGini: 7.457627 - 3
+Region.size: 98
+LeftChild.size: 59
+LeftChild.ClassCounts: 0 55 4 
+RightChild.size: 39
+RightChild.ClassCounts: 0 0 39 
+
+minGini: 3.428571 - 2
+Region.size: 59
+LeftChild.size: 52
+LeftChild.ClassCounts: 0 52 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 3 4 
+
+minGini: 1.500000 - 3
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 4 finished.
+
+minGini: 58.871036 - 0
+Region.size: 150
+LeftChild.size: 53
+LeftChild.ClassCounts: 48 5 0 
+RightChild.size: 97
+RightChild.ClassCounts: 2 42 53 
+
+minGini: 36.731735 - 0
+Region.size: 97
+LeftChild.size: 24
+LeftChild.ClassCounts: 1 21 2 
+RightChild.size: 73
+RightChild.ClassCounts: 1 21 51 
+
+minGini: 5.749056 - 2
+Region.size: 73
+LeftChild.size: 20
+LeftChild.ClassCounts: 1 19 0 
+RightChild.size: 53
+RightChild.ClassCounts: 0 2 51 
+
+minGini: 3.624113 - 1
+Region.size: 53
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 1 5 
+RightChild.size: 47
+RightChild.ClassCounts: 0 1 46 
+
+minGini: 1.600000 - 2
+Region.size: 47
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 4 
+RightChild.size: 42
+RightChild.ClassCounts: 0 0 42 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 
+
+minGini: 0.000000 - 2
+Region.size: 20
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 19 0 
+
+minGini: 1.909090 - 2
+Region.size: 24
+LeftChild.size: 22
+LeftChild.ClassCounts: 1 21 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 
+
+minGini: 0.000000 - 1
+Region.size: 22
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 21 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 53
+LeftChild.size: 48
+LeftChild.ClassCounts: 48 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 
+
+
+
+Tree Number: 5 finished.
+
+minGini: 49.252525 - 2
+Region.size: 150
+LeftChild.size: 51
+LeftChild.ClassCounts: 51 0 0 
+RightChild.size: 99
+RightChild.ClassCounts: 0 46 53 
+
+minGini: 5.632653 - 3
+Region.size: 99
+LeftChild.size: 49
+LeftChild.ClassCounts: 0 46 3 
+RightChild.size: 50
+RightChild.ClassCounts: 0 0 50 
+
+minGini: 5.280000 - 3
+Region.size: 49
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 24 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 22 3 
+
+minGini: 4.941176 - 0
+Region.size: 25
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 14 3 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 0 
+
+minGini: 1.500000 - 2
+Region.size: 17
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 3 
+
+minGini: 1.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+
+
+Tree Number: 6 finished.
+
+minGini: 48.888888 - 2
+Region.size: 150
+LeftChild.size: 51
+LeftChild.ClassCounts: 51 0 0 
+RightChild.size: 99
+RightChild.ClassCounts: 0 44 55 
+
+minGini: 3.859649 - 2
+Region.size: 99
+LeftChild.size: 42
+LeftChild.ClassCounts: 0 42 0 
+RightChild.size: 57
+RightChild.ClassCounts: 0 2 55 
+
+minGini: 3.600000 - 2
+Region.size: 57
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 2 18 
+RightChild.size: 37
+RightChild.ClassCounts: 0 0 37 
+
+minGini: 2.888888 - 0
+Region.size: 20
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 1 17 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+minGini: 1.500000 - 3
+Region.size: 18
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 3 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 14 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+
+
+Tree Number: 7 finished.
+
+minGini: 45.913043 - 3
+Region.size: 150
+LeftChild.size: 58
+LeftChild.ClassCounts: 58 0 0 
+RightChild.size: 92
+RightChild.ClassCounts: 0 44 48 
+
+minGini: 5.779669 - 3
+Region.size: 92
+LeftChild.size: 45
+LeftChild.ClassCounts: 0 43 2 
+RightChild.size: 47
+RightChild.ClassCounts: 0 1 46 
+
+minGini: 1.666666 - 0
+Region.size: 47
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 1 5 
+RightChild.size: 41
+RightChild.ClassCounts: 0 0 41 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 2.666666 - 1
+Region.size: 45
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 4 2 
+RightChild.size: 39
+RightChild.ClassCounts: 0 39 0 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 
+
+
+
+Tree Number: 8 finished.
+
+minGini: 51.923809 - 3
+Region.size: 150
+LeftChild.size: 45
+LeftChild.ClassCounts: 45 0 0 
+RightChild.size: 105
+RightChild.ClassCounts: 0 58 47 
+
+minGini: 16.253968 - 2
+Region.size: 105
+LeftChild.size: 63
+LeftChild.ClassCounts: 0 56 7 
+RightChild.size: 42
+RightChild.ClassCounts: 0 2 40 
+
+minGini: 2.000000 - 0
+Region.size: 42
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 2 2 
+RightChild.size: 38
+RightChild.ClassCounts: 0 0 38 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+minGini: 10.838709 - 0
+Region.size: 63
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 62
+RightChild.ClassCounts: 0 56 6 
+
+minGini: 9.448275 - 1
+Region.size: 62
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 2 2 
+RightChild.size: 58
+RightChild.ClassCounts: 0 54 4 
+
+minGini: 5.714285 - 2
+Region.size: 58
+LeftChild.size: 44
+LeftChild.ClassCounts: 0 44 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 10 4 
+
+minGini: 1.600000 - 3
+Region.size: 14
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 4 
+
+minGini: 1.333333 - 0
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 2 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 
+
+
+
+Tree Number: 9 finished.
+
+minGini: 47.876288 - 2
+Region.size: 150
+LeftChild.size: 53
+LeftChild.ClassCounts: 53 0 0 
+RightChild.size: 97
+RightChild.ClassCounts: 0 43 54 
+
+minGini: 10.800000 - 2
+Region.size: 97
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 37 0 
+RightChild.size: 60
+RightChild.ClassCounts: 0 6 54 
+
+minGini: 7.791666 - 3
+Region.size: 60
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 5 7 
+RightChild.size: 48
+RightChild.ClassCounts: 0 1 47 
+
+minGini: 1.777777 - 0
+Region.size: 48
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 1 8 
+RightChild.size: 39
+RightChild.ClassCounts: 0 0 39 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 8 
+
+minGini: 1.750000 - 2
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 1 7 
+
+minGini: 1.333333 - 3
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 2 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 
+
+
+
+Tree Number: 10 finished.
+
+minGini: 51.000000 - 2
+Region.size: 150
+LeftChild.size: 48
+LeftChild.ClassCounts: 48 0 0 
+RightChild.size: 102
+RightChild.ClassCounts: 0 51 51 
+
+minGini: 11.048355 - 2
+Region.size: 102
+LeftChild.size: 55
+LeftChild.ClassCounts: 0 50 5 
+RightChild.size: 47
+RightChild.ClassCounts: 0 1 46 
+
+minGini: 1.333333 - 3
+Region.size: 47
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 2 
+RightChild.size: 44
+RightChild.ClassCounts: 0 0 44 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 
+
+minGini: 6.755555 - 2
+Region.size: 55
+LeftChild.size: 45
+LeftChild.ClassCounts: 0 44 1 
+RightChild.size: 10
+RightChild.ClassCounts: 0 6 4 
+
+minGini: 1.714285 - 3
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 6 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 
+
+minGini: 1.500000 - 3
+Region.size: 45
+LeftChild.size: 41
+LeftChild.ClassCounts: 0 41 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 11 finished.
+
+minGini: 44.000000 - 3
+Region.size: 150
+LeftChild.size: 62
+LeftChild.ClassCounts: 62 0 0 
+RightChild.size: 88
+RightChild.ClassCounts: 0 44 44 
+
+minGini: 8.979591 - 2
+Region.size: 88
+LeftChild.size: 49
+LeftChild.ClassCounts: 0 44 5 
+RightChild.size: 39
+RightChild.ClassCounts: 0 0 39 
+
+minGini: 5.951219 - 2
+Region.size: 49
+LeftChild.size: 41
+LeftChild.ClassCounts: 0 40 1 
+RightChild.size: 8
+RightChild.ClassCounts: 0 4 4 
+
+minGini: 1.600000 - 0
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 1 
+
+minGini: 1.333333 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 1 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+minGini: 1.000000 - 3
+Region.size: 41
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 39 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+
+
+Tree Number: 12 finished.
+
+minGini: 46.659574 - 3
+Region.size: 150
+LeftChild.size: 56
+LeftChild.ClassCounts: 56 0 0 
+RightChild.size: 94
+RightChild.ClassCounts: 0 43 51 
+
+minGini: 14.226647 - 2
+Region.size: 94
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 36 1 
+RightChild.size: 57
+RightChild.ClassCounts: 0 7 50 
+
+minGini: 7.955555 - 3
+Region.size: 57
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 6 6 
+RightChild.size: 45
+RightChild.ClassCounts: 0 1 44 
+
+minGini: 1.600000 - 0
+Region.size: 45
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 4 
+RightChild.size: 40
+RightChild.ClassCounts: 0 0 40 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 
+
+minGini: 4.000000 - 0
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 3 6 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 
+
+minGini: 1.714285 - 2
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 1 6 
+
+minGini: 0.000000 - 3
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 1.833333 - 1
+Region.size: 37
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 11 1 
+RightChild.size: 25
+RightChild.ClassCounts: 0 25 0 
+
+minGini: 0.000000 - 3
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 13 finished.
+
+minGini: 50.099009 - 2
+Region.size: 150
+LeftChild.size: 49
+LeftChild.ClassCounts: 49 0 0 
+RightChild.size: 101
+RightChild.ClassCounts: 0 55 46 
+
+minGini: 5.812698 - 3
+Region.size: 101
+LeftChild.size: 56
+LeftChild.ClassCounts: 0 54 2 
+RightChild.size: 45
+RightChild.ClassCounts: 0 1 44 
+
+minGini: 1.777777 - 3
+Region.size: 45
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 1 8 
+RightChild.size: 36
+RightChild.ClassCounts: 0 0 36 
+
+minGini: 1.333333 - 2
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 2 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 6 
+
+minGini: 1.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 3.673469 - 3
+Region.size: 56
+LeftChild.size: 49
+LeftChild.ClassCounts: 0 48 1 
+RightChild.size: 7
+RightChild.ClassCounts: 0 6 1 
+
+minGini: 1.500000 - 1
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 
+
+minGini: 0.000000 - 2
+Region.size: 49
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 48 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 14 finished.
+
+minGini: 51.456310 - 2
+Region.size: 150
+LeftChild.size: 47
+LeftChild.ClassCounts: 47 0 0 
+RightChild.size: 103
+RightChild.ClassCounts: 0 50 53 
+
+minGini: 14.756226 - 2
+Region.size: 103
+LeftChild.size: 50
+LeftChild.ClassCounts: 0 46 4 
+RightChild.size: 53
+RightChild.ClassCounts: 0 4 49 
+
+minGini: 7.013953 - 0
+Region.size: 53
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 2 8 
+RightChild.size: 43
+RightChild.ClassCounts: 0 2 41 
+
+minGini: 0.000000 - 2
+Region.size: 43
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 41
+RightChild.ClassCounts: 0 0 41 
+
+minGini: 1.333333 - 3
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 1 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 7 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+minGini: 3.428571 - 3
+Region.size: 50
+LeftChild.size: 43
+LeftChild.ClassCounts: 0 43 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 3 4 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 
+
+
+
+Tree Number: 15 finished.
+
+minGini: 48.380000 - 2
+Region.size: 150
+LeftChild.size: 50
+LeftChild.ClassCounts: 50 0 0 
+RightChild.size: 100
+RightChild.ClassCounts: 0 59 41 
+
+minGini: 7.653635 - 2
+Region.size: 100
+LeftChild.size: 61
+LeftChild.ClassCounts: 0 58 3 
+RightChild.size: 39
+RightChild.ClassCounts: 0 1 38 
+
+minGini: 1.600000 - 0
+Region.size: 39
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 4 
+RightChild.size: 34
+RightChild.ClassCounts: 0 0 34 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 4.000000 - 2
+Region.size: 61
+LeftChild.size: 52
+LeftChild.ClassCounts: 0 52 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 6 3 
+
+minGini: 0.000000 - 0
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 
+
+
+
+Tree Number: 16 finished.
+
+minGini: 49.386138 - 2
+Region.size: 150
+LeftChild.size: 49
+LeftChild.ClassCounts: 49 0 0 
+RightChild.size: 101
+RightChild.ClassCounts: 0 58 43 
+
+minGini: 9.267984 - 2
+Region.size: 101
+LeftChild.size: 55
+LeftChild.ClassCounts: 0 54 1 
+RightChild.size: 46
+RightChild.ClassCounts: 0 4 42 
+
+minGini: 3.428571 - 3
+Region.size: 46
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 4 3 
+RightChild.size: 39
+RightChild.ClassCounts: 0 0 39 
+
+minGini: 0.000000 - 3
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 
+
+minGini: 1.882352 - 0
+Region.size: 55
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 38 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 16 1 
+
+minGini: 1.333333 - 2
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 1 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+
+
+Tree Number: 17 finished.
+
+minGini: 51.057692 - 3
+Region.size: 150
+LeftChild.size: 46
+LeftChild.ClassCounts: 46 0 0 
+RightChild.size: 104
+RightChild.ClassCounts: 0 59 45 
+
+minGini: 16.363636 - 2
+Region.size: 104
+LeftChild.size: 49
+LeftChild.ClassCounts: 0 49 0 
+RightChild.size: 55
+RightChild.ClassCounts: 0 10 45 
+
+minGini: 10.945945 - 2
+Region.size: 55
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 9 9 
+RightChild.size: 37
+RightChild.ClassCounts: 0 1 36 
+
+minGini: 1.714285 - 0
+Region.size: 37
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 1 6 
+RightChild.size: 30
+RightChild.ClassCounts: 0 0 30 
+
+minGini: 1.500000 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 3 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+minGini: 4.500000 - 0
+Region.size: 18
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 
+RightChild.size: 12
+RightChild.ClassCounts: 0 9 3 
+
+minGini: 0.000000 - 3
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+
+
+Tree Number: 18 finished.
+
+minGini: 44.934782 - 3
+Region.size: 150
+LeftChild.size: 58
+LeftChild.ClassCounts: 58 0 0 
+RightChild.size: 92
+RightChild.ClassCounts: 0 39 53 
+
+minGini: 5.571428 - 2
+Region.size: 92
+LeftChild.size: 42
+LeftChild.ClassCounts: 0 39 3 
+RightChild.size: 50
+RightChild.ClassCounts: 0 0 50 
+
+minGini: 0.000000 - 3
+Region.size: 42
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 39 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+
+
+Tree Number: 19 finished.
+
+minGini: 55.279279 - 3
+Region.size: 150
+LeftChild.size: 39
+LeftChild.ClassCounts: 39 0 0 
+RightChild.size: 111
+RightChild.ClassCounts: 0 59 52 
+
+minGini: 11.070779 - 2
+Region.size: 111
+LeftChild.size: 55
+LeftChild.ClassCounts: 0 54 1 
+RightChild.size: 56
+RightChild.ClassCounts: 0 5 51 
+
+minGini: 6.153846 - 2
+Region.size: 56
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 5 8 
+RightChild.size: 43
+RightChild.ClassCounts: 0 0 43 
+
+minGini: 1.666666 - 3
+Region.size: 13
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 5 1 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 7 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 
+
+minGini: 1.875000 - 1
+Region.size: 55
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 15 1 
+RightChild.size: 39
+RightChild.ClassCounts: 0 39 0 
+
+minGini: 0.000000 - 2
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 20 finished.
+
+minGini: 68.730769 - 0
+Region.size: 150
+LeftChild.size: 52
+LeftChild.ClassCounts: 41 10 1 
+RightChild.size: 98
+RightChild.ClassCounts: 3 41 54 
+
+minGini: 11.245186 - 2
+Region.size: 98
+LeftChild.size: 41
+LeftChild.ClassCounts: 3 38 0 
+RightChild.size: 57
+RightChild.ClassCounts: 0 3 54 
+
+minGini: 0.000000 - 3
+Region.size: 57
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 54
+RightChild.ClassCounts: 0 0 54 
+
+minGini: 0.000000 - 1
+Region.size: 41
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 38 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 
+
+minGini: 1.818181 - 3
+Region.size: 52
+LeftChild.size: 41
+LeftChild.ClassCounts: 41 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 10 1 
+
+minGini: 0.000000 - 2
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 21 finished.
+
+minGini: 49.920000 - 2
+Region.size: 150
+LeftChild.size: 50
+LeftChild.ClassCounts: 50 0 0 
+RightChild.size: 100
+RightChild.ClassCounts: 0 48 52 
+
+minGini: 1.962264 - 2
+Region.size: 100
+LeftChild.size: 47
+LeftChild.ClassCounts: 0 47 0 
+RightChild.size: 53
+RightChild.ClassCounts: 0 1 52 
+
+minGini: 1.714285 - 2
+Region.size: 53
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 1 6 
+RightChild.size: 46
+RightChild.ClassCounts: 0 0 46 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+
+
+Tree Number: 22 finished.
+
+minGini: 52.495238 - 3
+Region.size: 150
+LeftChild.size: 45
+LeftChild.ClassCounts: 45 0 0 
+RightChild.size: 105
+RightChild.ClassCounts: 0 52 53 
+
+minGini: 38.442307 - 0
+Region.size: 105
+LeftChild.size: 40
+LeftChild.ClassCounts: 0 33 7 
+RightChild.size: 65
+RightChild.ClassCounts: 0 19 46 
+
+minGini: 7.360000 - 2
+Region.size: 65
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 0 
+RightChild.size: 50
+RightChild.ClassCounts: 0 4 46 
+
+minGini: 3.428571 - 3
+Region.size: 50
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 4 3 
+RightChild.size: 43
+RightChild.ClassCounts: 0 0 43 
+
+minGini: 1.500000 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 3 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+minGini: 10.733333 - 1
+Region.size: 40
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 0 
+RightChild.size: 30
+RightChild.ClassCounts: 0 23 7 
+
+minGini: 1.750000 - 3
+Region.size: 30
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 22 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 1 7 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 7 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+
+
+Tree Number: 23 finished.
+
+minGini: 46.234042 - 2
+Region.size: 150
+LeftChild.size: 56
+LeftChild.ClassCounts: 56 0 0 
+RightChild.size: 94
+RightChild.ClassCounts: 0 53 41 
+
+minGini: 5.678571 - 3
+Region.size: 94
+LeftChild.size: 56
+LeftChild.ClassCounts: 0 53 3 
+RightChild.size: 38
+RightChild.ClassCounts: 0 0 38 
+
+minGini: 1.500000 - 2
+Region.size: 56
+LeftChild.size: 52
+LeftChild.ClassCounts: 0 52 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 3 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+
+
+Tree Number: 24 finished.
+
+minGini: 49.354838 - 2
+Region.size: 150
+LeftChild.size: 93
+LeftChild.ClassCounts: 45 45 3 
+RightChild.size: 57
+RightChild.ClassCounts: 0 0 57 
+
+minGini: 5.625000 - 2
+Region.size: 93
+LeftChild.size: 45
+LeftChild.ClassCounts: 45 0 0 
+RightChild.size: 48
+RightChild.ClassCounts: 0 45 3 
+
+minGini: 1.956521 - 0
+Region.size: 48
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 46
+RightChild.ClassCounts: 0 45 1 
+
+minGini: 1.000000 - 3
+Region.size: 46
+LeftChild.size: 44
+LeftChild.ClassCounts: 0 44 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 25 finished.
+
+minGini: 45.217391 - 3
+Region.size: 150
+LeftChild.size: 58
+LeftChild.ClassCounts: 58 0 0 
+RightChild.size: 92
+RightChild.ClassCounts: 0 52 40 
+
+minGini: 5.765662 - 3
+Region.size: 92
+LeftChild.size: 51
+LeftChild.ClassCounts: 0 50 1 
+RightChild.size: 41
+RightChild.ClassCounts: 0 2 39 
+
+minGini: 3.333333 - 3
+Region.size: 41
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 2 10 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 29 
+
+minGini: 0.000000 - 2
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 10 
+
+minGini: 1.900000 - 3
+Region.size: 51
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 31 0 
+RightChild.size: 20
+RightChild.ClassCounts: 0 19 1 
+
+minGini: 1.000000 - 1
+Region.size: 20
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 
+RightChild.size: 18
+RightChild.ClassCounts: 0 18 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 26 finished.
+
+minGini: 48.371134 - 3
+Region.size: 150
+LeftChild.size: 53
+LeftChild.ClassCounts: 53 0 0 
+RightChild.size: 97
+RightChild.ClassCounts: 0 46 51 
+
+minGini: 38.968992 - 0
+Region.size: 97
+LeftChild.size: 43
+LeftChild.ClassCounts: 0 31 12 
+RightChild.size: 54
+RightChild.ClassCounts: 0 15 39 
+
+minGini: 1.875000 - 3
+Region.size: 54
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 15 1 
+RightChild.size: 38
+RightChild.ClassCounts: 0 0 38 
+
+minGini: 1.333333 - 3
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+minGini: 3.768817 - 2
+Region.size: 43
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 30 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 1 11 
+
+minGini: 1.600000 - 0
+Region.size: 12
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 7 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 4 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 
+
+minGini: 0.000000 - 3
+Region.size: 31
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 30 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 27 finished.
+
+minGini: 48.371134 - 2
+Region.size: 150
+LeftChild.size: 53
+LeftChild.ClassCounts: 53 0 0 
+RightChild.size: 97
+RightChild.ClassCounts: 0 51 46 
+
+minGini: 14.590986 - 2
+Region.size: 97
+LeftChild.size: 49
+LeftChild.ClassCounts: 0 46 3 
+RightChild.size: 48
+RightChild.ClassCounts: 0 5 43 
+
+minGini: 3.750000 - 3
+Region.size: 48
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 5 3 
+RightChild.size: 40
+RightChild.ClassCounts: 0 0 40 
+
+minGini: 1.500000 - 3
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 1.500000 - 3
+Region.size: 49
+LeftChild.size: 45
+LeftChild.ClassCounts: 0 45 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 3 
+
+minGini: 1.333333 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 2 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+
+
+Tree Number: 28 finished.
+
+minGini: 50.769230 - 2
+Region.size: 150
+LeftChild.size: 46
+LeftChild.ClassCounts: 46 0 0 
+RightChild.size: 104
+RightChild.ClassCounts: 0 44 60 
+
+minGini: 16.152295 - 3
+Region.size: 104
+LeftChild.size: 47
+LeftChild.ClassCounts: 0 41 6 
+RightChild.size: 57
+RightChild.ClassCounts: 0 3 54 
+
+minGini: 2.400000 - 2
+Region.size: 57
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 3 2 
+RightChild.size: 52
+RightChild.ClassCounts: 0 0 52 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 
+
+minGini: 8.913043 - 0
+Region.size: 47
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 46
+RightChild.ClassCounts: 0 41 5 
+
+minGini: 7.288888 - 0
+Region.size: 46
+LeftChild.size: 45
+LeftChild.ClassCounts: 0 41 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+minGini: 1.600000 - 2
+Region.size: 45
+LeftChild.size: 40
+LeftChild.ClassCounts: 0 40 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 4 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+
+
+Tree Number: 29 finished.
+
+minGini: 44.494382 - 3
+Region.size: 150
+LeftChild.size: 61
+LeftChild.ClassCounts: 61 0 0 
+RightChild.size: 89
+RightChild.ClassCounts: 0 44 45 
+
+minGini: 14.304878 - 3
+Region.size: 89
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 42 6 
+RightChild.size: 41
+RightChild.ClassCounts: 0 2 39 
+
+minGini: 3.111111 - 0
+Region.size: 41
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 2 7 
+RightChild.size: 32
+RightChild.ClassCounts: 0 0 32 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 7 
+
+minGini: 8.622222 - 0
+Region.size: 48
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 2 
+RightChild.size: 45
+RightChild.ClassCounts: 0 41 4 
+
+minGini: 6.720000 - 1
+Region.size: 45
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 21 4 
+RightChild.size: 20
+RightChild.ClassCounts: 0 20 0 
+
+minGini: 5.090909 - 0
+Region.size: 25
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 7 4 
+
+minGini: 0.000000 - 2
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 
+
+
+
+Tree Number: 30 finished.
+
+minGini: 52.495238 - 2
+Region.size: 150
+LeftChild.size: 45
+LeftChild.ClassCounts: 45 0 0 
+RightChild.size: 105
+RightChild.ClassCounts: 0 52 53 
+
+minGini: 11.066326 - 3
+Region.size: 105
+LeftChild.size: 56
+LeftChild.ClassCounts: 0 51 5 
+RightChild.size: 49
+RightChild.ClassCounts: 0 1 48 
+
+minGini: 1.750000 - 0
+Region.size: 49
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 1 7 
+RightChild.size: 41
+RightChild.ClassCounts: 0 0 41 
+
+minGini: 1.333333 - 3
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 7.418181 - 0
+Region.size: 56
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 55
+RightChild.ClassCounts: 0 51 4 
+
+minGini: 1.600000 - 2
+Region.size: 55
+LeftChild.size: 50
+LeftChild.ClassCounts: 0 50 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 4 
+
+minGini: 1.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+
+
+Tree Number: 31 finished.
+
+iris
+minGini: 162.540627 - 2
+Region.size: 768
+LeftChild.size: 628
+LeftChild.ClassCounts: 450 178 
+RightChild.size: 140
+RightChild.ClassCounts: 71 69 
+
+minGini: 30.024251 - 5
+Region.size: 140
+LeftChild.size: 38
+LeftChild.ClassCounts: 31 7 
+RightChild.size: 102
+RightChild.ClassCounts: 40 62 
+
+minGini: 16.904761 - 1
+Region.size: 102
+LeftChild.size: 42
+LeftChild.ClassCounts: 30 12 
+RightChild.size: 60
+RightChild.ClassCounts: 10 50 
+
+minGini: 7.627118 - 6
+Region.size: 60
+LeftChild.size: 59
+LeftChild.ClassCounts: 9 50 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 6.035117 - 2
+Region.size: 59
+LeftChild.size: 13
+LeftChild.ClassCounts: 6 7 
+RightChild.size: 46
+RightChild.ClassCounts: 3 43 
+
+minGini: 1.976190 - 7
+Region.size: 46
+LeftChild.size: 42
+LeftChild.ClassCounts: 1 41 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.800000 - 2
+Region.size: 42
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 37
+RightChild.ClassCounts: 0 37 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 1
+Region.size: 13
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 6.266666 - 6
+Region.size: 42
+LeftChild.size: 27
+LeftChild.ClassCounts: 24 3 
+RightChild.size: 15
+RightChild.ClassCounts: 6 9 
+
+minGini: 2.000000 - 0
+Region.size: 15
+LeftChild.size: 9
+LeftChild.ClassCounts: 6 3 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 2.340000 - 7
+Region.size: 27
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 25
+RightChild.ClassCounts: 23 2 
+
+minGini: 1.621212 - 5
+Region.size: 25
+LeftChild.size: 22
+LeftChild.ClassCounts: 21 1 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 22
+LeftChild.size: 21
+LeftChild.ClassCounts: 21 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.466666 - 0
+Region.size: 38
+LeftChild.size: 30
+LeftChild.ClassCounts: 29 1 
+RightChild.size: 8
+RightChild.ClassCounts: 2 6 
+
+minGini: 0.000000 - 0
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.800000 - 1
+Region.size: 30
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 25
+RightChild.ClassCounts: 25 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 105.637820 - 1
+Region.size: 628
+LeftChild.size: 406
+LeftChild.ClassCounts: 347 59 
+RightChild.size: 222
+RightChild.ClassCounts: 103 119 
+
+minGini: 53.977743 - 3
+Region.size: 222
+LeftChild.size: 84
+LeftChild.ClassCounts: 47 37 
+RightChild.size: 138
+RightChild.ClassCounts: 56 82 
+
+minGini: 26.579166 - 1
+Region.size: 138
+LeftChild.size: 90
+LeftChild.ClassCounts: 51 39 
+RightChild.size: 48
+RightChild.ClassCounts: 5 43 
+
+minGini: 3.659574 - 2
+Region.size: 48
+LeftChild.size: 47
+LeftChild.ClassCounts: 4 43 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.475609 - 5
+Region.size: 47
+LeftChild.size: 41
+LeftChild.ClassCounts: 1 40 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 
+
+minGini: 0.750000 - 1
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 41
+LeftChild.size: 40
+LeftChild.ClassCounts: 0 40 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 20.035714 - 2
+Region.size: 90
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 84
+RightChild.ClassCounts: 51 33 
+
+minGini: 15.369863 - 5
+Region.size: 84
+LeftChild.size: 73
+LeftChild.ClassCounts: 51 22 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 12.858974 - 3
+Region.size: 73
+LeftChild.size: 34
+LeftChild.ClassCounts: 17 17 
+RightChild.size: 39
+RightChild.ClassCounts: 34 5 
+
+minGini: 3.416666 - 7
+Region.size: 39
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 36
+RightChild.ClassCounts: 33 3 
+
+minGini: 1.714285 - 0
+Region.size: 36
+LeftChild.size: 29
+LeftChild.ClassCounts: 29 0 
+RightChild.size: 7
+RightChild.ClassCounts: 4 3 
+
+minGini: 0.750000 - 6
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 7.028846 - 6
+Region.size: 34
+LeftChild.size: 26
+LeftChild.ClassCounts: 16 10 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 4.736842 - 5
+Region.size: 26
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 19
+RightChild.ClassCounts: 9 10 
+
+minGini: 2.769230 - 7
+Region.size: 19
+LeftChild.size: 13
+LeftChild.ClassCounts: 9 4 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 1.636363 - 5
+Region.size: 13
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 11
+RightChild.ClassCounts: 9 2 
+
+minGini: 1.200000 - 2
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 18.311688 - 2
+Region.size: 84
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 77
+RightChild.ClassCounts: 47 30 
+
+minGini: 15.267857 - 1
+Region.size: 77
+LeftChild.size: 56
+LeftChild.ClassCounts: 41 15 
+RightChild.size: 21
+RightChild.ClassCounts: 6 15 
+
+minGini: 2.500000 - 7
+Region.size: 21
+LeftChild.size: 18
+LeftChild.ClassCounts: 3 15 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.875000 - 6
+Region.size: 18
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.000000 - 2
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 7.534782 - 5
+Region.size: 56
+LeftChild.size: 46
+LeftChild.ClassCounts: 39 7 
+RightChild.size: 10
+RightChild.ClassCounts: 2 8 
+
+minGini: 0.000000 - 2
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 5.515151 - 3
+Region.size: 46
+LeftChild.size: 33
+LeftChild.ClassCounts: 26 7 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 5.279411 - 2
+Region.size: 33
+LeftChild.size: 17
+LeftChild.ClassCounts: 12 5 
+RightChild.size: 16
+RightChild.ClassCounts: 14 2 
+
+minGini: 0.933333 - 6
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 15
+RightChild.ClassCounts: 14 1 
+
+minGini: 0.666666 - 7
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 3.076923 - 1
+Region.size: 17
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 13
+RightChild.ClassCounts: 8 5 
+
+minGini: 1.600000 - 2
+Region.size: 13
+LeftChild.size: 10
+LeftChild.ClassCounts: 8 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.888888 - 5
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 8 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 2
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 46.892736 - 5
+Region.size: 406
+LeftChild.size: 137
+LeftChild.ClassCounts: 135 2 
+RightChild.size: 269
+RightChild.ClassCounts: 212 57 
+
+minGini: 42.543847 - 4
+Region.size: 269
+LeftChild.size: 120
+LeftChild.ClassCounts: 82 38 
+RightChild.size: 149
+RightChild.ClassCounts: 130 19 
+
+minGini: 14.816233 - 3
+Region.size: 149
+LeftChild.size: 105
+LeftChild.ClassCounts: 99 6 
+RightChild.size: 44
+RightChild.ClassCounts: 31 13 
+
+minGini: 6.409090 - 6
+Region.size: 44
+LeftChild.size: 22
+LeftChild.ClassCounts: 21 1 
+RightChild.size: 22
+RightChild.ClassCounts: 10 12 
+
+minGini: 3.000000 - 1
+Region.size: 22
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 16
+RightChild.ClassCounts: 4 12 
+
+minGini: 1.714285 - 3
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 2 12 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 14
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 5
+Region.size: 22
+LeftChild.size: 21
+LeftChild.ClassCounts: 21 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.257281 - 7
+Region.size: 105
+LeftChild.size: 103
+LeftChild.ClassCounts: 98 5 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.601898 - 7
+Region.size: 103
+LeftChild.size: 77
+LeftChild.ClassCounts: 75 2 
+RightChild.size: 26
+RightChild.ClassCounts: 23 3 
+
+minGini: 2.283333 - 1
+Region.size: 26
+LeftChild.size: 20
+LeftChild.ClassCounts: 19 1 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.800000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.500000 - 2
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.833333 - 7
+Region.size: 20
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.428571 - 6
+Region.size: 77
+LeftChild.size: 70
+LeftChild.ClassCounts: 70 0 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.833333 - 3
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 2
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 22.354166 - 1
+Region.size: 120
+LeftChild.size: 48
+LeftChild.ClassCounts: 43 5 
+RightChild.size: 72
+RightChild.ClassCounts: 39 33 
+
+minGini: 16.842857 - 1
+Region.size: 72
+LeftChild.size: 42
+LeftChild.ClassCounts: 27 15 
+RightChild.size: 30
+RightChild.ClassCounts: 12 18 
+
+minGini: 6.634615 - 2
+Region.size: 30
+LeftChild.size: 26
+LeftChild.ClassCounts: 9 17 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 3.115151 - 7
+Region.size: 26
+LeftChild.size: 11
+LeftChild.ClassCounts: 8 3 
+RightChild.size: 15
+RightChild.ClassCounts: 1 14 
+
+minGini: 0.500000 - 0
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.888888 - 1
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 9
+RightChild.ClassCounts: 8 1 
+
+minGini: 0.500000 - 6
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 6.964285 - 6
+Region.size: 42
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 28
+RightChild.ClassCounts: 13 15 
+
+minGini: 4.438502 - 0
+Region.size: 28
+LeftChild.size: 17
+LeftChild.ClassCounts: 12 5 
+RightChild.size: 11
+RightChild.ClassCounts: 1 10 
+
+minGini: 0.750000 - 1
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.500000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.714285 - 5
+Region.size: 17
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 14
+RightChild.ClassCounts: 12 2 
+
+minGini: 0.666666 - 1
+Region.size: 14
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.152173 - 1
+Region.size: 48
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 46
+RightChild.ClassCounts: 42 4 
+
+minGini: 3.295454 - 0
+Region.size: 46
+LeftChild.size: 44
+LeftChild.ClassCounts: 41 3 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.569105 - 7
+Region.size: 44
+LeftChild.size: 41
+LeftChild.ClassCounts: 39 2 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.975000 - 3
+Region.size: 41
+LeftChild.size: 40
+LeftChild.ClassCounts: 39 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.900000 - 1
+Region.size: 40
+LeftChild.size: 30
+LeftChild.ClassCounts: 30 0 
+RightChild.size: 10
+RightChild.ClassCounts: 9 1 
+
+minGini: 0.000000 - 3
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.913043 - 3
+Region.size: 137
+LeftChild.size: 46
+LeftChild.ClassCounts: 44 2 
+RightChild.size: 91
+RightChild.ClassCounts: 91 0 
+
+minGini: 1.200000 - 0
+Region.size: 46
+LeftChild.size: 41
+LeftChild.ClassCounts: 41 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+
+
+Tree Number: 0 finished.
+
+minGini: 148.639920 - 7
+Region.size: 768
+LeftChild.size: 371
+LeftChild.ClassCounts: 312 59 
+RightChild.size: 397
+RightChild.ClassCounts: 189 208 
+
+minGini: 91.100191 - 5
+Region.size: 397
+LeftChild.size: 79
+LeftChild.ClassCounts: 60 19 
+RightChild.size: 318
+RightChild.ClassCounts: 129 189 
+
+minGini: 66.615440 - 1
+Region.size: 318
+LeftChild.size: 82
+LeftChild.ClassCounts: 58 24 
+RightChild.size: 236
+RightChild.ClassCounts: 71 165 
+
+minGini: 47.858746 - 7
+Region.size: 236
+LeftChild.size: 213
+LeftChild.ClassCounts: 58 155 
+RightChild.size: 23
+RightChild.ClassCounts: 13 10 
+
+minGini: 4.117647 - 6
+Region.size: 23
+LeftChild.size: 17
+LeftChild.ClassCounts: 7 10 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 1.666666 - 6
+Region.size: 17
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 12
+RightChild.ClassCounts: 2 10 
+
+minGini: 0.000000 - 5
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 40.636162 - 0
+Region.size: 213
+LeftChild.size: 46
+LeftChild.ClassCounts: 5 41 
+RightChild.size: 167
+RightChild.ClassCounts: 53 114 
+
+minGini: 32.341365 - 7
+Region.size: 167
+LeftChild.size: 83
+LeftChild.ClassCounts: 39 44 
+RightChild.size: 84
+RightChild.ClassCounts: 14 70 
+
+minGini: 9.914956 - 6
+Region.size: 84
+LeftChild.size: 22
+LeftChild.ClassCounts: 9 13 
+RightChild.size: 62
+RightChild.ClassCounts: 5 57 
+
+minGini: 4.042105 - 3
+Region.size: 62
+LeftChild.size: 57
+LeftChild.ClassCounts: 3 54 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.640000 - 7
+Region.size: 57
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 32 
+RightChild.size: 25
+RightChild.ClassCounts: 3 22 
+
+minGini: 2.181818 - 0
+Region.size: 25
+LeftChild.size: 11
+LeftChild.ClassCounts: 3 8 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 1.500000 - 7
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.750000 - 5
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.500000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 3.965811 - 2
+Region.size: 22
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 13
+RightChild.ClassCounts: 8 5 
+
+minGini: 0.833333 - 6
+Region.size: 13
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.500000 - 6
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 16.375558 - 1
+Region.size: 83
+LeftChild.size: 61
+LeftChild.ClassCounts: 37 24 
+RightChild.size: 22
+RightChild.ClassCounts: 2 20 
+
+minGini: 0.952380 - 7
+Region.size: 22
+LeftChild.size: 21
+LeftChild.ClassCounts: 1 20 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 3
+Region.size: 21
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 17
+RightChild.ClassCounts: 0 17 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 13.607769 - 0
+Region.size: 61
+LeftChild.size: 42
+LeftChild.ClassCounts: 29 13 
+RightChild.size: 19
+RightChild.ClassCounts: 8 11 
+
+minGini: 3.657142 - 4
+Region.size: 19
+LeftChild.size: 14
+LeftChild.ClassCounts: 4 10 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.666666 - 3
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.650000 - 6
+Region.size: 14
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.750000 - 3
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 6.642857 - 2
+Region.size: 42
+LeftChild.size: 14
+LeftChild.ClassCounts: 5 9 
+RightChild.size: 28
+RightChild.ClassCounts: 24 4 
+
+minGini: 2.666666 - 5
+Region.size: 28
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 12
+RightChild.ClassCounts: 8 4 
+
+minGini: 1.600000 - 5
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 10
+RightChild.ClassCounts: 8 2 
+
+minGini: 1.000000 - 4
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.350000 - 0
+Region.size: 14
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 10
+RightChild.ClassCounts: 2 8 
+
+minGini: 1.200000 - 1
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.666666 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 3.400000 - 5
+Region.size: 46
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 
+RightChild.size: 40
+RightChild.ClassCounts: 2 38 
+
+minGini: 1.639639 - 3
+Region.size: 40
+LeftChild.size: 37
+LeftChild.ClassCounts: 1 36 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 6
+Region.size: 37
+LeftChild.size: 35
+LeftChild.ClassCounts: 0 35 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 2
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 15.417721 - 1
+Region.size: 82
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 79
+RightChild.ClassCounts: 58 21 
+
+minGini: 13.894594 - 6
+Region.size: 79
+LeftChild.size: 74
+LeftChild.ClassCounts: 57 17 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 12.493150 - 5
+Region.size: 74
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 73
+RightChild.ClassCounts: 57 16 
+
+minGini: 11.239436 - 0
+Region.size: 73
+LeftChild.size: 71
+LeftChild.ClassCounts: 57 14 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 10.478744 - 3
+Region.size: 71
+LeftChild.size: 52
+LeftChild.ClassCounts: 45 7 
+RightChild.size: 19
+RightChild.ClassCounts: 12 7 
+
+minGini: 3.000000 - 5
+Region.size: 19
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 16
+RightChild.ClassCounts: 12 4 
+
+minGini: 2.358974 - 1
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 11 2 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.000000 - 4
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 4.137681 - 6
+Region.size: 52
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 46
+RightChild.ClassCounts: 43 3 
+
+minGini: 2.654761 - 7
+Region.size: 46
+LeftChild.size: 42
+LeftChild.ClassCounts: 40 2 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.723684 - 2
+Region.size: 42
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 38
+RightChild.ClassCounts: 37 1 
+
+minGini: 0.857142 - 1
+Region.size: 38
+LeftChild.size: 31
+LeftChild.ClassCounts: 31 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.500000 - 6
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.800000 - 5
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 12.567032 - 4
+Region.size: 79
+LeftChild.size: 65
+LeftChild.ClassCounts: 54 11 
+RightChild.size: 14
+RightChild.ClassCounts: 6 8 
+
+minGini: 2.666666 - 2
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 12
+RightChild.ClassCounts: 4 8 
+
+minGini: 0.000000 - 1
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 1.890572 - 1
+Region.size: 65
+LeftChild.size: 54
+LeftChild.ClassCounts: 53 1 
+RightChild.size: 11
+RightChild.ClassCounts: 1 10 
+
+minGini: 0.000000 - 7
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.900000 - 7
+Region.size: 54
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 44
+RightChild.ClassCounts: 44 0 
+
+minGini: 0.666666 - 6
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 40.436898 - 5
+Region.size: 371
+LeftChild.size: 335
+LeftChild.ClassCounts: 299 36 
+RightChild.size: 36
+RightChild.ClassCounts: 13 23 
+
+minGini: 5.366666 - 4
+Region.size: 36
+LeftChild.size: 30
+LeftChild.ClassCounts: 7 23 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 4.666666 - 5
+Region.size: 30
+LeftChild.size: 21
+LeftChild.ClassCounts: 7 14 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 2.423076 - 5
+Region.size: 21
+LeftChild.size: 13
+LeftChild.ClassCounts: 1 12 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 1.000000 - 3
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 3
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 29.428591 - 5
+Region.size: 335
+LeftChild.size: 177
+LeftChild.ClassCounts: 173 4 
+RightChild.size: 158
+RightChild.ClassCounts: 126 32 
+
+minGini: 16.595759 - 6
+Region.size: 158
+LeftChild.size: 137
+LeftChild.ClassCounts: 122 15 
+RightChild.size: 21
+RightChild.ClassCounts: 4 17 
+
+minGini: 2.933333 - 3
+Region.size: 21
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 15
+RightChild.ClassCounts: 4 11 
+
+minGini: 1.714285 - 1
+Region.size: 15
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 0.800000 - 0
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 12.954381 - 7
+Region.size: 137
+LeftChild.size: 97
+LeftChild.ClassCounts: 83 14 
+RightChild.size: 40
+RightChild.ClassCounts: 39 1 
+
+minGini: 0.833333 - 1
+Region.size: 40
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 34
+RightChild.ClassCounts: 34 0 
+
+minGini: 0.666666 - 2
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 9.983086 - 2
+Region.size: 97
+LeftChild.size: 11
+LeftChild.ClassCounts: 5 6 
+RightChild.size: 86
+RightChild.ClassCounts: 78 8 
+
+minGini: 6.634920 - 5
+Region.size: 86
+LeftChild.size: 14
+LeftChild.ClassCounts: 10 4 
+RightChild.size: 72
+RightChild.ClassCounts: 68 4 
+
+minGini: 3.551820 - 4
+Region.size: 72
+LeftChild.size: 21
+LeftChild.ClassCounts: 18 3 
+RightChild.size: 51
+RightChild.ClassCounts: 50 1 
+
+minGini: 0.900000 - 6
+Region.size: 51
+LeftChild.size: 41
+LeftChild.ClassCounts: 41 0 
+RightChild.size: 10
+RightChild.ClassCounts: 9 1 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.800000 - 3
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 18 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.947368 - 4
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 18 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 3
+Region.size: 19
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 
+
+minGini: 0.500000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.650000 - 7
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.428571 - 5
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.833333 - 1
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 3.822222 - 0
+Region.size: 177
+LeftChild.size: 87
+LeftChild.ClassCounts: 87 0 
+RightChild.size: 90
+RightChild.ClassCounts: 86 4 
+
+minGini: 3.701508 - 3
+Region.size: 90
+LeftChild.size: 32
+LeftChild.ClassCounts: 29 3 
+RightChild.size: 58
+RightChild.ClassCounts: 57 1 
+
+minGini: 0.800000 - 7
+Region.size: 58
+LeftChild.size: 53
+LeftChild.ClassCounts: 53 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.437500 - 7
+Region.size: 32
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 16
+RightChild.ClassCounts: 13 3 
+
+minGini: 1.733333 - 4
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 13 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.928571 - 6
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 13 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 7
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.500000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 1 finished.
+
+minGini: 155.485050 - 5
+Region.size: 768
+LeftChild.size: 196
+LeftChild.ClassCounts: 178 18 
+RightChild.size: 572
+RightChild.ClassCounts: 333 239 
+
+minGini: 114.435252 - 1
+Region.size: 572
+LeftChild.size: 307
+LeftChild.ClassCounts: 238 69 
+RightChild.size: 265
+RightChild.ClassCounts: 95 170 
+
+minGini: 59.125614 - 0
+Region.size: 265
+LeftChild.size: 190
+LeftChild.ClassCounts: 78 112 
+RightChild.size: 75
+RightChild.ClassCounts: 17 58 
+
+minGini: 11.385714 - 5
+Region.size: 75
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 70
+RightChild.ClassCounts: 13 57 
+
+minGini: 8.857142 - 1
+Region.size: 70
+LeftChild.size: 14
+LeftChild.ClassCounts: 7 7 
+RightChild.size: 56
+RightChild.ClassCounts: 6 50 
+
+minGini: 4.575757 - 2
+Region.size: 56
+LeftChild.size: 12
+LeftChild.ClassCounts: 4 8 
+RightChild.size: 44
+RightChild.ClassCounts: 2 42 
+
+minGini: 1.777777 - 3
+Region.size: 44
+LeftChild.size: 18
+LeftChild.ClassCounts: 2 16 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 
+
+minGini: 1.000000 - 5
+Region.size: 18
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 6
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 2.333333 - 3
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 38.390977 - 1
+Region.size: 190
+LeftChild.size: 133
+LeftChild.ClassCounts: 72 61 
+RightChild.size: 57
+RightChild.ClassCounts: 6 51 
+
+minGini: 4.553571 - 4
+Region.size: 57
+LeftChild.size: 56
+LeftChild.ClassCounts: 5 51 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.643939 - 6
+Region.size: 56
+LeftChild.size: 44
+LeftChild.ClassCounts: 1 43 
+RightChild.size: 12
+RightChild.ClassCounts: 4 8 
+
+minGini: 0.000000 - 3
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 0.875000 - 5
+Region.size: 44
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 36
+RightChild.ClassCounts: 0 36 
+
+minGini: 0.666666 - 2
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 30.380745 - 3
+Region.size: 133
+LeftChild.size: 44
+LeftChild.ClassCounts: 15 29 
+RightChild.size: 89
+RightChild.ClassCounts: 57 32 
+
+minGini: 19.532634 - 3
+Region.size: 89
+LeftChild.size: 78
+LeftChild.ClassCounts: 53 25 
+RightChild.size: 11
+RightChild.ClassCounts: 4 7 
+
+minGini: 1.714285 - 4
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 14.868385 - 1
+Region.size: 78
+LeftChild.size: 11
+LeftChild.ClassCounts: 3 8 
+RightChild.size: 67
+RightChild.ClassCounts: 50 17 
+
+minGini: 11.719954 - 1
+Region.size: 67
+LeftChild.size: 18
+LeftChild.ClassCounts: 17 1 
+RightChild.size: 49
+RightChild.ClassCounts: 33 16 
+
+minGini: 8.809523 - 1
+Region.size: 49
+LeftChild.size: 28
+LeftChild.ClassCounts: 14 14 
+RightChild.size: 21
+RightChild.ClassCounts: 19 2 
+
+minGini: 1.200000 - 6
+Region.size: 21
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 6.300000 - 4
+Region.size: 28
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 2 
+RightChild.size: 20
+RightChild.ClassCounts: 8 12 
+
+minGini: 4.000000 - 2
+Region.size: 20
+LeftChild.size: 10
+LeftChild.ClassCounts: 2 8 
+RightChild.size: 10
+RightChild.ClassCounts: 6 4 
+
+minGini: 1.333333 - 2
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.800000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.888888 - 3
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 7
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.000000 - 3
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.666666 - 7
+Region.size: 18
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.888888 - 7
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 
+
+minGini: 0.750000 - 7
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 9.166253 - 5
+Region.size: 44
+LeftChild.size: 13
+LeftChild.ClassCounts: 7 6 
+RightChild.size: 31
+RightChild.ClassCounts: 8 23 
+
+minGini: 4.870833 - 1
+Region.size: 31
+LeftChild.size: 16
+LeftChild.ClassCounts: 7 9 
+RightChild.size: 15
+RightChild.ClassCounts: 1 14 
+
+minGini: 0.500000 - 6
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.433333 - 5
+Region.size: 16
+LeftChild.size: 10
+LeftChild.ClassCounts: 2 8 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.888888 - 0
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 
+
+minGini: 0.750000 - 5
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.555555 - 0
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.666666 - 6
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 49.186666 - 5
+Region.size: 307
+LeftChild.size: 300
+LeftChild.ClassCounts: 238 62 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 45.920000 - 0
+Region.size: 300
+LeftChild.size: 250
+LeftChild.ClassCounts: 210 40 
+RightChild.size: 50
+RightChild.ClassCounts: 28 22 
+
+minGini: 9.333333 - 6
+Region.size: 50
+LeftChild.size: 42
+LeftChild.ClassCounts: 28 14 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 7.583333 - 5
+Region.size: 42
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 36
+RightChild.ClassCounts: 27 9 
+
+minGini: 5.625000 - 7
+Region.size: 36
+LeftChild.size: 12
+LeftChild.ClassCounts: 6 6 
+RightChild.size: 24
+RightChild.ClassCounts: 21 3 
+
+minGini: 2.318181 - 6
+Region.size: 24
+LeftChild.size: 22
+LeftChild.ClassCounts: 20 2 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.614035 - 5
+Region.size: 22
+LeftChild.size: 19
+LeftChild.ClassCounts: 18 1 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.666666 - 2
+Region.size: 19
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.000000 - 1
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 0.000000 - 1
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.666666 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 27.764423 - 7
+Region.size: 250
+LeftChild.size: 208
+LeftChild.ClassCounts: 189 19 
+RightChild.size: 42
+RightChild.ClassCounts: 21 21 
+
+minGini: 9.535714 - 3
+Region.size: 42
+LeftChild.size: 28
+LeftChild.ClassCounts: 11 17 
+RightChild.size: 14
+RightChild.ClassCounts: 10 4 
+
+minGini: 1.333333 - 6
+Region.size: 14
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 3.863636 - 6
+Region.size: 28
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 22
+RightChild.ClassCounts: 5 17 
+
+minGini: 3.238095 - 1
+Region.size: 22
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 21
+RightChild.ClassCounts: 4 17 
+
+minGini: 2.550000 - 6
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 3 17 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.100000 - 1
+Region.size: 20
+LeftChild.size: 10
+LeftChild.ClassCounts: 3 7 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 15.938916 - 2
+Region.size: 208
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 203
+RightChild.ClassCounts: 187 16 
+
+minGini: 14.248717 - 1
+Region.size: 203
+LeftChild.size: 125
+LeftChild.ClassCounts: 120 5 
+RightChild.size: 78
+RightChild.ClassCounts: 67 11 
+
+minGini: 7.934210 - 6
+Region.size: 78
+LeftChild.size: 76
+LeftChild.ClassCounts: 67 9 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 7.635135 - 1
+Region.size: 76
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 74
+RightChild.ClassCounts: 66 8 
+
+minGini: 5.165195 - 3
+Region.size: 74
+LeftChild.size: 13
+LeftChild.ClassCounts: 7 6 
+RightChild.size: 61
+RightChild.ClassCounts: 59 2 
+
+minGini: 1.777777 - 2
+Region.size: 61
+LeftChild.size: 18
+LeftChild.ClassCounts: 16 2 
+RightChild.size: 43
+RightChild.ClassCounts: 43 0 
+
+minGini: 1.200000 - 2
+Region.size: 18
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.500000 - 5
+Region.size: 13
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 8
+RightChild.ClassCounts: 2 6 
+
+minGini: 0.666666 - 6
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.423076 - 3
+Region.size: 125
+LeftChild.size: 117
+LeftChild.ClassCounts: 114 3 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.000000 - 3
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 2.807655 - 5
+Region.size: 117
+LeftChild.size: 95
+LeftChild.ClassCounts: 94 1 
+RightChild.size: 22
+RightChild.ClassCounts: 20 2 
+
+minGini: 0.952380 - 5
+Region.size: 22
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 21
+RightChild.ClassCounts: 20 1 
+
+minGini: 0.833333 - 6
+Region.size: 21
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.909090 - 6
+Region.size: 95
+LeftChild.size: 11
+LeftChild.ClassCounts: 10 1 
+RightChild.size: 84
+RightChild.ClassCounts: 84 0 
+
+minGini: 0.750000 - 2
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 15.837775 - 2
+Region.size: 196
+LeftChild.size: 128
+LeftChild.ClassCounts: 121 7 
+RightChild.size: 68
+RightChild.ClassCounts: 57 11 
+
+minGini: 8.186046 - 7
+Region.size: 68
+LeftChild.size: 25
+LeftChild.ClassCounts: 25 0 
+RightChild.size: 43
+RightChild.ClassCounts: 32 11 
+
+minGini: 7.218750 - 7
+Region.size: 43
+LeftChild.size: 32
+LeftChild.ClassCounts: 21 11 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 6.657004 - 5
+Region.size: 32
+LeftChild.size: 9
+LeftChild.ClassCounts: 4 5 
+RightChild.size: 23
+RightChild.ClassCounts: 17 6 
+
+minGini: 3.238095 - 4
+Region.size: 23
+LeftChild.size: 21
+LeftChild.ClassCounts: 17 4 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.550000 - 0
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 17 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.944444 - 1
+Region.size: 20
+LeftChild.size: 18
+LeftChild.ClassCounts: 17 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.800000 - 5
+Region.size: 18
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.666666 - 3
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.800000 - 6
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.042140 - 1
+Region.size: 128
+LeftChild.size: 115
+LeftChild.ClassCounts: 113 2 
+RightChild.size: 13
+RightChild.ClassCounts: 8 5 
+
+minGini: 0.000000 - 0
+Region.size: 13
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 1.936951 - 6
+Region.size: 115
+LeftChild.size: 96
+LeftChild.ClassCounts: 95 1 
+RightChild.size: 19
+RightChild.ClassCounts: 18 1 
+
+minGini: 0.875000 - 7
+Region.size: 19
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 0.500000 - 3
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 0
+Region.size: 96
+LeftChild.size: 92
+LeftChild.ClassCounts: 92 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+
+
+Tree Number: 2 finished.
+
+minGini: 141.804765 - 1
+Region.size: 768
+LeftChild.size: 376
+LeftChild.ClassCounts: 323 53 
+RightChild.size: 392
+RightChild.ClassCounts: 170 222 
+
+minGini: 84.416399 - 1
+Region.size: 392
+LeftChild.size: 288
+LeftChild.ClassCounts: 155 133 
+RightChild.size: 104
+RightChild.ClassCounts: 15 89 
+
+minGini: 12.077922 - 3
+Region.size: 104
+LeftChild.size: 77
+LeftChild.ClassCounts: 15 62 
+RightChild.size: 27
+RightChild.ClassCounts: 0 27 
+
+minGini: 11.708711 - 0
+Region.size: 77
+LeftChild.size: 19
+LeftChild.ClassCounts: 6 13 
+RightChild.size: 58
+RightChild.ClassCounts: 9 49 
+
+minGini: 6.810810 - 5
+Region.size: 58
+LeftChild.size: 37
+LeftChild.ClassCounts: 9 28 
+RightChild.size: 21
+RightChild.ClassCounts: 0 21 
+
+minGini: 5.659090 - 5
+Region.size: 37
+LeftChild.size: 33
+LeftChild.ClassCounts: 6 27 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 3.878571 - 1
+Region.size: 33
+LeftChild.size: 28
+LeftChild.ClassCounts: 3 25 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.851851 - 7
+Region.size: 28
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 27
+RightChild.ClassCounts: 2 25 
+
+minGini: 1.555555 - 2
+Region.size: 27
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 
+RightChild.size: 9
+RightChild.ClassCounts: 2 7 
+
+minGini: 0.666666 - 0
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.345238 - 4
+Region.size: 19
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 11 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.833333 - 7
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 1
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 63.413078 - 7
+Region.size: 288
+LeftChild.size: 57
+LeftChild.ClassCounts: 50 7 
+RightChild.size: 231
+RightChild.ClassCounts: 105 126 
+
+minGini: 54.170521 - 6
+Region.size: 231
+LeftChild.size: 194
+LeftChild.ClassCounts: 98 96 
+RightChild.size: 37
+RightChild.ClassCounts: 7 30 
+
+minGini: 4.285714 - 1
+Region.size: 37
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 35
+RightChild.ClassCounts: 5 30 
+
+minGini: 2.727272 - 6
+Region.size: 35
+LeftChild.size: 33
+LeftChild.ClassCounts: 3 30 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.875000 - 5
+Region.size: 33
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 32
+RightChild.ClassCounts: 2 30 
+
+minGini: 1.692307 - 5
+Region.size: 32
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 19 
+RightChild.size: 13
+RightChild.ClassCounts: 2 11 
+
+minGini: 0.916666 - 1
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 11 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 45.556318 - 0
+Region.size: 194
+LeftChild.size: 26
+LeftChild.ClassCounts: 5 21 
+RightChild.size: 168
+RightChild.ClassCounts: 93 75 
+
+minGini: 39.330379 - 2
+Region.size: 168
+LeftChild.size: 158
+LeftChild.ClassCounts: 92 66 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 34.660225 - 5
+Region.size: 158
+LeftChild.size: 23
+LeftChild.ClassCounts: 22 1 
+RightChild.size: 135
+RightChild.ClassCounts: 70 65 
+
+minGini: 32.158808 - 6
+Region.size: 135
+LeftChild.size: 31
+LeftChild.ClassCounts: 10 21 
+RightChild.size: 104
+RightChild.ClassCounts: 60 44 
+
+minGini: 21.935580 - 7
+Region.size: 104
+LeftChild.size: 89
+LeftChild.ClassCounts: 58 31 
+RightChild.size: 15
+RightChild.ClassCounts: 2 13 
+
+minGini: 1.200000 - 1
+Region.size: 15
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.750000 - 7
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 19.135802 - 4
+Region.size: 89
+LeftChild.size: 81
+LeftChild.ClassCounts: 50 31 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 17.691608 - 0
+Region.size: 81
+LeftChild.size: 55
+LeftChild.ClassCounts: 39 16 
+RightChild.size: 26
+RightChild.ClassCounts: 11 15 
+
+minGini: 4.950000 - 1
+Region.size: 26
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 20
+RightChild.ClassCounts: 11 9 
+
+minGini: 3.882352 - 3
+Region.size: 20
+LeftChild.size: 17
+LeftChild.ClassCounts: 11 6 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 3.097222 - 2
+Region.size: 17
+LeftChild.size: 9
+LeftChild.ClassCounts: 4 5 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.666666 - 6
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.550000 - 2
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 8.460000 - 4
+Region.size: 55
+LeftChild.size: 25
+LeftChild.ClassCounts: 24 1 
+RightChild.size: 30
+RightChild.ClassCounts: 15 15 
+
+minGini: 6.150000 - 0
+Region.size: 30
+LeftChild.size: 20
+LeftChild.ClassCounts: 7 13 
+RightChild.size: 10
+RightChild.ClassCounts: 8 2 
+
+minGini: 0.000000 - 5
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.545454 - 7
+Region.size: 20
+LeftChild.size: 11
+LeftChild.ClassCounts: 7 4 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.000000 - 2
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.833333 - 6
+Region.size: 25
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.666666 - 0
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.793103 - 0
+Region.size: 31
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 29
+RightChild.ClassCounts: 8 21 
+
+minGini: 4.666666 - 1
+Region.size: 29
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 27
+RightChild.ClassCounts: 6 21 
+
+minGini: 3.166666 - 2
+Region.size: 27
+LeftChild.size: 18
+LeftChild.ClassCounts: 1 17 
+RightChild.size: 9
+RightChild.ClassCounts: 5 4 
+
+minGini: 1.428571 - 6
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.000000 - 3
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.666666 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 18
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 17 
+
+minGini: 0.000000 - 0
+Region.size: 23
+LeftChild.size: 22
+LeftChild.ClassCounts: 22 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.428571 - 2
+Region.size: 26
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 19 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 4.892307 - 5
+Region.size: 57
+LeftChild.size: 52
+LeftChild.ClassCounts: 48 4 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 3.320000 - 3
+Region.size: 52
+LeftChild.size: 50
+LeftChild.ClassCounts: 47 3 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.500000 - 6
+Region.size: 50
+LeftChild.size: 32
+LeftChild.ClassCounts: 32 0 
+RightChild.size: 18
+RightChild.ClassCounts: 15 3 
+
+minGini: 1.764705 - 0
+Region.size: 18
+LeftChild.size: 17
+LeftChild.ClassCounts: 15 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.500000 - 6
+Region.size: 17
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 2 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.857142 - 7
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 3
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 37.946977 - 7
+Region.size: 376
+LeftChild.size: 255
+LeftChild.ClassCounts: 244 11 
+RightChild.size: 121
+RightChild.ClassCounts: 79 42 
+
+minGini: 25.198275 - 4
+Region.size: 121
+LeftChild.size: 116
+LeftChild.ClassCounts: 79 37 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 21.443181 - 5
+Region.size: 116
+LeftChild.size: 28
+LeftChild.ClassCounts: 28 0 
+RightChild.size: 88
+RightChild.ClassCounts: 51 37 
+
+minGini: 18.075949 - 7
+Region.size: 88
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 79
+RightChild.ClassCounts: 51 28 
+
+minGini: 16.172715 - 0
+Region.size: 79
+LeftChild.size: 31
+LeftChild.ClassCounts: 26 5 
+RightChild.size: 48
+RightChild.ClassCounts: 25 23 
+
+minGini: 10.808362 - 2
+Region.size: 48
+LeftChild.size: 41
+LeftChild.ClassCounts: 24 17 
+RightChild.size: 7
+RightChild.ClassCounts: 1 6 
+
+minGini: 0.000000 - 4
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 6.438461 - 6
+Region.size: 41
+LeftChild.size: 26
+LeftChild.ClassCounts: 21 5 
+RightChild.size: 15
+RightChild.ClassCounts: 3 12 
+
+minGini: 1.714285 - 5
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 14
+RightChild.ClassCounts: 2 12 
+
+minGini: 1.000000 - 1
+Region.size: 14
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.625000 - 1
+Region.size: 26
+LeftChild.size: 24
+LeftChild.ClassCounts: 21 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.750000 - 7
+Region.size: 24
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 3.176767 - 0
+Region.size: 31
+LeftChild.size: 9
+LeftChild.ClassCounts: 5 4 
+RightChild.size: 22
+RightChild.ClassCounts: 21 1 
+
+minGini: 0.857142 - 7
+Region.size: 22
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.800000 - 5
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 10.201680 - 2
+Region.size: 255
+LeftChild.size: 238
+LeftChild.ClassCounts: 230 8 
+RightChild.size: 17
+RightChild.ClassCounts: 14 3 
+
+minGini: 0.933333 - 6
+Region.size: 17
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 15
+RightChild.ClassCounts: 14 1 
+
+minGini: 0.000000 - 2
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 7.119505 - 7
+Region.size: 238
+LeftChild.size: 182
+LeftChild.ClassCounts: 181 1 
+RightChild.size: 56
+RightChild.ClassCounts: 49 7 
+
+minGini: 2.978723 - 3
+Region.size: 56
+LeftChild.size: 47
+LeftChild.ClassCounts: 46 1 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 0.750000 - 0
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.833333 - 4
+Region.size: 47
+LeftChild.size: 41
+LeftChild.ClassCounts: 41 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.954545 - 3
+Region.size: 182
+LeftChild.size: 160
+LeftChild.ClassCounts: 160 0 
+RightChild.size: 22
+RightChild.ClassCounts: 21 1 
+
+minGini: 0.666666 - 3
+Region.size: 22
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 19
+RightChild.ClassCounts: 19 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 3 finished.
+
+minGini: 140.624367 - 1
+Region.size: 768
+LeftChild.size: 620
+LeftChild.ClassCounts: 459 161 
+RightChild.size: 148
+RightChild.ClassCounts: 26 122 
+
+minGini: 20.049560 - 7
+Region.size: 148
+LeftChild.size: 139
+LeftChild.ClassCounts: 21 118 
+RightChild.size: 9
+RightChild.ClassCounts: 5 4 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 16.511089 - 6
+Region.size: 139
+LeftChild.size: 17
+LeftChild.ClassCounts: 7 10 
+RightChild.size: 122
+RightChild.ClassCounts: 14 108 
+
+minGini: 11.069607 - 4
+Region.size: 122
+LeftChild.size: 102
+LeftChild.ClassCounts: 7 95 
+RightChild.size: 20
+RightChild.ClassCounts: 7 13 
+
+minGini: 1.733333 - 4
+Region.size: 20
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 15
+RightChild.ClassCounts: 2 13 
+
+minGini: 0.928571 - 5
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 1 13 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 4
+Region.size: 14
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 6.165413 - 3
+Region.size: 102
+LeftChild.size: 95
+LeftChild.ClassCounts: 5 90 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 4.582551 - 0
+Region.size: 95
+LeftChild.size: 13
+LeftChild.ClassCounts: 2 11 
+RightChild.size: 82
+RightChild.ClassCounts: 3 79 
+
+minGini: 2.357142 - 5
+Region.size: 82
+LeftChild.size: 14
+LeftChild.ClassCounts: 3 11 
+RightChild.size: 68
+RightChild.ClassCounts: 0 68 
+
+minGini: 0.000000 - 5
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 6
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.307692 - 0
+Region.size: 17
+LeftChild.size: 13
+LeftChild.ClassCounts: 3 10 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 1
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 108.714571 - 7
+Region.size: 620
+LeftChild.size: 382
+LeftChild.ClassCounts: 322 60 
+RightChild.size: 238
+RightChild.ClassCounts: 137 101 
+
+minGini: 51.646179 - 5
+Region.size: 238
+LeftChild.size: 39
+LeftChild.ClassCounts: 37 2 
+RightChild.size: 199
+RightChild.ClassCounts: 100 99 
+
+minGini: 45.148351 - 1
+Region.size: 199
+LeftChild.size: 17
+LeftChild.ClassCounts: 17 0 
+RightChild.size: 182
+RightChild.ClassCounts: 83 99 
+
+minGini: 43.341212 - 6
+Region.size: 182
+LeftChild.size: 124
+LeftChild.ClassCounts: 65 59 
+RightChild.size: 58
+RightChild.ClassCounts: 18 40 
+
+minGini: 10.370370 - 1
+Region.size: 58
+LeftChild.size: 54
+LeftChild.ClassCounts: 14 40 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 9.219512 - 0
+Region.size: 54
+LeftChild.size: 41
+LeftChild.ClassCounts: 14 27 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 8.060606 - 7
+Region.size: 41
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 33
+RightChild.ClassCounts: 14 19 
+
+minGini: 6.107142 - 5
+Region.size: 33
+LeftChild.size: 28
+LeftChild.ClassCounts: 9 19 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 5.115384 - 6
+Region.size: 28
+LeftChild.size: 26
+LeftChild.ClassCounts: 7 19 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 4.153846 - 5
+Region.size: 26
+LeftChild.size: 13
+LeftChild.ClassCounts: 1 12 
+RightChild.size: 13
+RightChild.ClassCounts: 6 7 
+
+minGini: 0.857142 - 5
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.500000 - 7
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.833333 - 1
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 26.299765 - 0
+Region.size: 124
+LeftChild.size: 63
+LeftChild.ClassCounts: 45 18 
+RightChild.size: 61
+RightChild.ClassCounts: 20 41 
+
+minGini: 12.017241 - 6
+Region.size: 61
+LeftChild.size: 58
+LeftChild.ClassCounts: 17 41 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 10.577777 - 1
+Region.size: 58
+LeftChild.size: 45
+LeftChild.ClassCounts: 17 28 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 8.878048 - 1
+Region.size: 45
+LeftChild.size: 41
+LeftChild.ClassCounts: 13 28 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 6.810810 - 7
+Region.size: 41
+LeftChild.size: 37
+LeftChild.ClassCounts: 9 28 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 6.000000 - 1
+Region.size: 37
+LeftChild.size: 27
+LeftChild.ClassCounts: 9 18 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 4.500000 - 2
+Region.size: 27
+LeftChild.size: 18
+LeftChild.ClassCounts: 9 9 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 2.250000 - 1
+Region.size: 18
+LeftChild.size: 12
+LeftChild.ClassCounts: 3 9 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 1.636363 - 6
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 11
+RightChild.ClassCounts: 2 9 
+
+minGini: 1.428571 - 7
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 
+
+minGini: 1.000000 - 0
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 11.387755 - 6
+Region.size: 63
+LeftChild.size: 49
+LeftChild.ClassCounts: 31 18 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 8.119047 - 4
+Region.size: 49
+LeftChild.size: 42
+LeftChild.ClassCounts: 31 11 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 5.027027 - 6
+Region.size: 42
+LeftChild.size: 37
+LeftChild.ClassCounts: 31 6 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 4.196078 - 3
+Region.size: 37
+LeftChild.size: 34
+LeftChild.ClassCounts: 30 4 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.727272 - 7
+Region.size: 34
+LeftChild.size: 33
+LeftChild.ClassCounts: 30 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.875000 - 0
+Region.size: 33
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 32
+RightChild.ClassCounts: 30 2 
+
+minGini: 1.818181 - 2
+Region.size: 32
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 22
+RightChild.ClassCounts: 20 2 
+
+minGini: 0.952380 - 0
+Region.size: 22
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 21
+RightChild.ClassCounts: 20 1 
+
+minGini: 0.750000 - 1
+Region.size: 21
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 17
+RightChild.ClassCounts: 17 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.721428 - 4
+Region.size: 39
+LeftChild.size: 35
+LeftChild.ClassCounts: 34 1 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.900000 - 6
+Region.size: 35
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 25
+RightChild.ClassCounts: 25 0 
+
+minGini: 0.000000 - 2
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 49.146055 - 7
+Region.size: 382
+LeftChild.size: 120
+LeftChild.ClassCounts: 112 8 
+RightChild.size: 262
+RightChild.ClassCounts: 210 52 
+
+minGini: 36.377952 - 5
+Region.size: 262
+LeftChild.size: 254
+LeftChild.ClassCounts: 210 44 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 33.225887 - 1
+Region.size: 254
+LeftChild.size: 116
+LeftChild.ClassCounts: 110 6 
+RightChild.size: 138
+RightChild.ClassCounts: 100 38 
+
+minGini: 23.912144 - 2
+Region.size: 138
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 129
+RightChild.ClassCounts: 99 30 
+
+minGini: 20.592000 - 5
+Region.size: 129
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 125
+RightChild.ClassCounts: 99 26 
+
+minGini: 19.550344 - 2
+Region.size: 125
+LeftChild.size: 74
+LeftChild.ClassCounts: 53 21 
+RightChild.size: 51
+RightChild.ClassCounts: 46 5 
+
+minGini: 4.107142 - 1
+Region.size: 51
+LeftChild.size: 28
+LeftChild.ClassCounts: 23 5 
+RightChild.size: 23
+RightChild.ClassCounts: 23 0 
+
+minGini: 2.653846 - 1
+Region.size: 28
+LeftChild.size: 26
+LeftChild.ClassCounts: 23 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.444444 - 6
+Region.size: 26
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 2 
+RightChild.size: 18
+RightChild.ClassCounts: 17 1 
+
+minGini: 0.000000 - 4
+Region.size: 18
+LeftChild.size: 17
+LeftChild.ClassCounts: 17 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 12.614555 - 1
+Region.size: 74
+LeftChild.size: 53
+LeftChild.ClassCounts: 44 9 
+RightChild.size: 21
+RightChild.ClassCounts: 9 12 
+
+minGini: 3.000000 - 5
+Region.size: 21
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 16
+RightChild.ClassCounts: 4 12 
+
+minGini: 1.333333 - 0
+Region.size: 16
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 6.890029 - 6
+Region.size: 53
+LeftChild.size: 22
+LeftChild.ClassCounts: 21 1 
+RightChild.size: 31
+RightChild.ClassCounts: 23 8 
+
+minGini: 4.800000 - 2
+Region.size: 31
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 20
+RightChild.ClassCounts: 12 8 
+
+minGini: 3.000000 - 3
+Region.size: 20
+LeftChild.size: 16
+LeftChild.ClassCounts: 12 4 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.714285 - 0
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 12 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 2
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 
+
+minGini: 0.750000 - 6
+Region.size: 22
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 18
+RightChild.ClassCounts: 18 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 6
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 5.095779 - 3
+Region.size: 116
+LeftChild.size: 88
+LeftChild.ClassCounts: 87 1 
+RightChild.size: 28
+RightChild.ClassCounts: 23 5 
+
+minGini: 2.653846 - 5
+Region.size: 28
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 26
+RightChild.ClassCounts: 23 3 
+
+minGini: 1.840000 - 0
+Region.size: 26
+LeftChild.size: 25
+LeftChild.ClassCounts: 23 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.666666 - 0
+Region.size: 25
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 12
+RightChild.ClassCounts: 10 2 
+
+minGini: 0.909090 - 7
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.666666 - 2
+Region.size: 11
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.875000 - 6
+Region.size: 88
+LeftChild.size: 80
+LeftChild.ClassCounts: 80 0 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.500000 - 7
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 6.078078 - 0
+Region.size: 120
+LeftChild.size: 111
+LeftChild.ClassCounts: 107 4 
+RightChild.size: 9
+RightChild.ClassCounts: 5 4 
+
+minGini: 1.333333 - 5
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 3
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 3.384615 - 5
+Region.size: 111
+LeftChild.size: 85
+LeftChild.ClassCounts: 85 0 
+RightChild.size: 26
+RightChild.ClassCounts: 22 4 
+
+minGini: 2.152380 - 6
+Region.size: 26
+LeftChild.size: 21
+LeftChild.ClassCounts: 20 1 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 5
+Region.size: 21
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 
+
+
+
+Tree Number: 4 finished.
+
+minGini: 165.768487 - 0
+Region.size: 768
+LeftChild.size: 606
+LeftChild.ClassCounts: 423 183 
+RightChild.size: 162
+RightChild.ClassCounts: 61 101 
+
+minGini: 32.912583 - 5
+Region.size: 162
+LeftChild.size: 31
+LeftChild.ClassCounts: 23 8 
+RightChild.size: 131
+RightChild.ClassCounts: 38 93 
+
+minGini: 24.799501 - 4
+Region.size: 131
+LeftChild.size: 104
+LeftChild.ClassCounts: 37 67 
+RightChild.size: 27
+RightChild.ClassCounts: 1 26 
+
+minGini: 0.800000 - 1
+Region.size: 27
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 22
+RightChild.ClassCounts: 0 22 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 20.721649 - 7
+Region.size: 104
+LeftChild.size: 97
+LeftChild.ClassCounts: 30 67 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 14.651898 - 1
+Region.size: 97
+LeftChild.size: 18
+LeftChild.ClassCounts: 15 3 
+RightChild.size: 79
+RightChild.ClassCounts: 15 64 
+
+minGini: 10.615032 - 6
+Region.size: 79
+LeftChild.size: 45
+LeftChild.ClassCounts: 14 31 
+RightChild.size: 34
+RightChild.ClassCounts: 1 33 
+
+minGini: 0.750000 - 2
+Region.size: 34
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 30 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 8.296992 - 4
+Region.size: 45
+LeftChild.size: 38
+LeftChild.ClassCounts: 9 29 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 4.762820 - 0
+Region.size: 38
+LeftChild.size: 26
+LeftChild.ClassCounts: 2 24 
+RightChild.size: 12
+RightChild.ClassCounts: 7 5 
+
+minGini: 1.555555 - 0
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.875000 - 3
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 5
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.666666 - 2
+Region.size: 26
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 23 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.764705 - 5
+Region.size: 18
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 17
+RightChild.ClassCounts: 15 2 
+
+minGini: 1.500000 - 1
+Region.size: 17
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.000000 - 2
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 4.758620 - 2
+Region.size: 31
+LeftChild.size: 29
+LeftChild.ClassCounts: 23 6 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 1
+Region.size: 29
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 100.870831 - 1
+Region.size: 606
+LeftChild.size: 345
+LeftChild.ClassCounts: 304 41 
+RightChild.size: 261
+RightChild.ClassCounts: 119 142 
+
+minGini: 59.428956 - 7
+Region.size: 261
+LeftChild.size: 73
+LeftChild.ClassCounts: 50 23 
+RightChild.size: 188
+RightChild.ClassCounts: 69 119 
+
+minGini: 42.101694 - 4
+Region.size: 188
+LeftChild.size: 177
+LeftChild.ClassCounts: 69 108 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 37.203947 - 7
+Region.size: 177
+LeftChild.size: 152
+LeftChild.ClassCounts: 49 103 
+RightChild.size: 25
+RightChild.ClassCounts: 20 5 
+
+minGini: 2.608695 - 1
+Region.size: 25
+LeftChild.size: 23
+LeftChild.ClassCounts: 20 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.181818 - 1
+Region.size: 23
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 11
+RightChild.ClassCounts: 8 3 
+
+minGini: 1.200000 - 6
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 28.442307 - 1
+Region.size: 152
+LeftChild.size: 100
+LeftChild.ClassCounts: 45 55 
+RightChild.size: 52
+RightChild.ClassCounts: 4 48 
+
+minGini: 2.916666 - 3
+Region.size: 52
+LeftChild.size: 48
+LeftChild.ClassCounts: 2 46 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.478260 - 6
+Region.size: 48
+LeftChild.size: 46
+LeftChild.ClassCounts: 1 45 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.916666 - 1
+Region.size: 46
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 11 
+RightChild.size: 34
+RightChild.ClassCounts: 0 34 
+
+minGini: 0.666666 - 6
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.500000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 21.076388 - 6
+Region.size: 100
+LeftChild.size: 64
+LeftChild.ClassCounts: 38 26 
+RightChild.size: 36
+RightChild.ClassCounts: 7 29 
+
+minGini: 5.142857 - 7
+Region.size: 36
+LeftChild.size: 15
+LeftChild.ClassCounts: 5 10 
+RightChild.size: 21
+RightChild.ClassCounts: 2 19 
+
+minGini: 0.000000 - 1
+Region.size: 21
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 19 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.700000 - 5
+Region.size: 15
+LeftChild.size: 10
+LeftChild.ClassCounts: 1 9 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.500000 - 1
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 11.982683 - 7
+Region.size: 64
+LeftChild.size: 42
+LeftChild.ClassCounts: 32 10 
+RightChild.size: 22
+RightChild.ClassCounts: 6 16 
+
+minGini: 2.526315 - 4
+Region.size: 22
+LeftChild.size: 19
+LeftChild.ClassCounts: 3 16 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.941176 - 2
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 17
+RightChild.ClassCounts: 1 16 
+
+minGini: 0.750000 - 6
+Region.size: 17
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 5.743589 - 5
+Region.size: 42
+LeftChild.size: 39
+LeftChild.ClassCounts: 32 7 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 2.742857 - 2
+Region.size: 39
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 35
+RightChild.ClassCounts: 32 3 
+
+minGini: 2.307692 - 6
+Region.size: 35
+LeftChild.size: 22
+LeftChild.ClassCounts: 22 0 
+RightChild.size: 13
+RightChild.ClassCounts: 10 3 
+
+minGini: 1.666666 - 2
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 10 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 11.939189 - 5
+Region.size: 73
+LeftChild.size: 36
+LeftChild.ClassCounts: 33 3 
+RightChild.size: 37
+RightChild.ClassCounts: 17 20 
+
+minGini: 7.034482 - 1
+Region.size: 37
+LeftChild.size: 29
+LeftChild.ClassCounts: 17 12 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 4.421052 - 4
+Region.size: 29
+LeftChild.size: 19
+LeftChild.ClassCounts: 7 12 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 2.545454 - 6
+Region.size: 19
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 11
+RightChild.ClassCounts: 7 4 
+
+minGini: 1.555555 - 5
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.200000 - 1
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.666666 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.100000 - 4
+Region.size: 36
+LeftChild.size: 10
+LeftChild.ClassCounts: 7 3 
+RightChild.size: 26
+RightChild.ClassCounts: 26 0 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 32.649253 - 5
+Region.size: 345
+LeftChild.size: 335
+LeftChild.ClassCounts: 301 34 
+RightChild.size: 10
+RightChild.ClassCounts: 3 7 
+
+minGini: 0.000000 - 7
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 28.388349 - 5
+Region.size: 335
+LeftChild.size: 129
+LeftChild.ClassCounts: 129 0 
+RightChild.size: 206
+RightChild.ClassCounts: 172 34 
+
+minGini: 26.872549 - 7
+Region.size: 206
+LeftChild.size: 102
+LeftChild.ClassCounts: 94 8 
+RightChild.size: 104
+RightChild.ClassCounts: 78 26 
+
+minGini: 18.461538 - 4
+Region.size: 104
+LeftChild.size: 78
+LeftChild.ClassCounts: 54 24 
+RightChild.size: 26
+RightChild.ClassCounts: 24 2 
+
+minGini: 1.692307 - 1
+Region.size: 26
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 13
+RightChild.ClassCounts: 11 2 
+
+minGini: 1.555555 - 4
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 
+
+minGini: 0.000000 - 5
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 13.783333 - 5
+Region.size: 78
+LeftChild.size: 48
+LeftChild.ClassCounts: 26 22 
+RightChild.size: 30
+RightChild.ClassCounts: 28 2 
+
+minGini: 1.428571 - 7
+Region.size: 30
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 1.200000 - 5
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 3
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 10.068796 - 5
+Region.size: 48
+LeftChild.size: 37
+LeftChild.ClassCounts: 24 13 
+RightChild.size: 11
+RightChild.ClassCounts: 2 9 
+
+minGini: 0.666666 - 7
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 6.768817 - 3
+Region.size: 37
+LeftChild.size: 31
+LeftChild.ClassCounts: 23 8 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 5.366666 - 5
+Region.size: 31
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 30
+RightChild.ClassCounts: 23 7 
+
+minGini: 4.678571 - 0
+Region.size: 30
+LeftChild.size: 14
+LeftChild.ClassCounts: 13 1 
+RightChild.size: 16
+RightChild.ClassCounts: 10 6 
+
+minGini: 2.727272 - 5
+Region.size: 16
+LeftChild.size: 11
+LeftChild.ClassCounts: 5 6 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 1.633333 - 0
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.500000 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 7
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 4
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 6.451127 - 1
+Region.size: 102
+LeftChild.size: 95
+LeftChild.ClassCounts: 90 5 
+RightChild.size: 7
+RightChild.ClassCounts: 4 3 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 4.396551 - 6
+Region.size: 95
+LeftChild.size: 87
+LeftChild.ClassCounts: 84 3 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 1.000000 - 1
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.719444 - 3
+Region.size: 87
+LeftChild.size: 72
+LeftChild.ClassCounts: 71 1 
+RightChild.size: 15
+RightChild.ClassCounts: 13 2 
+
+minGini: 0.928571 - 4
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 14
+RightChild.ClassCounts: 13 1 
+
+minGini: 0.000000 - 0
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.933333 - 0
+Region.size: 72
+LeftChild.size: 15
+LeftChild.ClassCounts: 14 1 
+RightChild.size: 57
+RightChild.ClassCounts: 57 0 
+
+minGini: 0.666666 - 4
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 5 finished.
+
+minGini: 145.434934 - 1
+Region.size: 768
+LeftChild.size: 307
+LeftChild.ClassCounts: 272 35 
+RightChild.size: 461
+RightChild.ClassCounts: 211 250 
+
+minGini: 103.726634 - 1
+Region.size: 461
+LeftChild.size: 323
+LeftChild.ClassCounts: 180 143 
+RightChild.size: 138
+RightChild.ClassCounts: 31 107 
+
+minGini: 22.018831 - 5
+Region.size: 138
+LeftChild.size: 28
+LeftChild.ClassCounts: 13 15 
+RightChild.size: 110
+RightChild.ClassCounts: 18 92 
+
+minGini: 13.959795 - 0
+Region.size: 110
+LeftChild.size: 72
+LeftChild.ClassCounts: 17 55 
+RightChild.size: 38
+RightChild.ClassCounts: 1 37 
+
+minGini: 0.900000 - 0
+Region.size: 38
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 28 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 11.305555 - 7
+Region.size: 72
+LeftChild.size: 36
+LeftChild.ClassCounts: 3 33 
+RightChild.size: 36
+RightChild.ClassCounts: 14 22 
+
+minGini: 6.215384 - 3
+Region.size: 36
+LeftChild.size: 26
+LeftChild.ClassCounts: 6 20 
+RightChild.size: 10
+RightChild.ClassCounts: 8 2 
+
+minGini: 0.888888 - 3
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 8 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.800000 - 3
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.500000 - 2
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.845238 - 7
+Region.size: 26
+LeftChild.size: 14
+LeftChild.ClassCounts: 1 13 
+RightChild.size: 12
+RightChild.ClassCounts: 5 7 
+
+minGini: 0.000000 - 0
+Region.size: 12
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.833333 - 7
+Region.size: 14
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 7
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 2.100000 - 6
+Region.size: 36
+LeftChild.size: 10
+LeftChild.ClassCounts: 3 7 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 
+
+minGini: 0.875000 - 2
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.666666 - 6
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 5.217391 - 7
+Region.size: 28
+LeftChild.size: 23
+LeftChild.ClassCounts: 8 15 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 4.275000 - 0
+Region.size: 23
+LeftChild.size: 8
+LeftChild.ClassCounts: 5 3 
+RightChild.size: 15
+RightChild.ClassCounts: 3 12 
+
+minGini: 1.875000 - 1
+Region.size: 15
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.833333 - 5
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.666666 - 6
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 71.646465 - 7
+Region.size: 323
+LeftChild.size: 73
+LeftChild.ClassCounts: 62 11 
+RightChild.size: 250
+RightChild.ClassCounts: 118 132 
+
+minGini: 59.783029 - 6
+Region.size: 250
+LeftChild.size: 152
+LeftChild.ClassCounts: 84 68 
+RightChild.size: 98
+RightChild.ClassCounts: 34 64 
+
+minGini: 21.122580 - 2
+Region.size: 98
+LeftChild.size: 93
+LeftChild.ClassCounts: 30 63 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 17.691176 - 5
+Region.size: 93
+LeftChild.size: 25
+LeftChild.ClassCounts: 15 10 
+RightChild.size: 68
+RightChild.ClassCounts: 15 53 
+
+minGini: 10.274509 - 7
+Region.size: 68
+LeftChild.size: 17
+LeftChild.ClassCounts: 8 9 
+RightChild.size: 51
+RightChild.ClassCounts: 7 44 
+
+minGini: 5.280000 - 5
+Region.size: 51
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 50
+RightChild.ClassCounts: 6 44 
+
+minGini: 4.780487 - 3
+Region.size: 50
+LeftChild.size: 41
+LeftChild.ClassCounts: 3 38 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 0.857142 - 3
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 7
+RightChild.ClassCounts: 1 6 
+
+minGini: 0.500000 - 5
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.304761 - 0
+Region.size: 41
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 35
+RightChild.ClassCounts: 1 34 
+
+minGini: 0.909090 - 6
+Region.size: 35
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 24
+RightChild.ClassCounts: 0 24 
+
+minGini: 0.000000 - 1
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.666666 - 2
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.666666 - 7
+Region.size: 17
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 12
+RightChild.ClassCounts: 8 4 
+
+minGini: 1.333333 - 5
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.666666 - 3
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 4.444444 - 7
+Region.size: 25
+LeftChild.size: 18
+LeftChild.ClassCounts: 8 10 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 2.493506 - 7
+Region.size: 18
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 11
+RightChild.ClassCounts: 2 9 
+
+minGini: 0.900000 - 1
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 1 9 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 3
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 35.436619 - 6
+Region.size: 152
+LeftChild.size: 142
+LeftChild.ClassCounts: 74 68 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 33.683035 - 7
+Region.size: 142
+LeftChild.size: 128
+LeftChild.ClassCounts: 62 66 
+RightChild.size: 14
+RightChild.ClassCounts: 12 2 
+
+minGini: 1.000000 - 0
+Region.size: 14
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.666666 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.500000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 30.588744 - 0
+Region.size: 128
+LeftChild.size: 84
+LeftChild.ClassCounts: 47 37 
+RightChild.size: 44
+RightChild.ClassCounts: 15 29 
+
+minGini: 9.441860 - 1
+Region.size: 44
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 43
+RightChild.ClassCounts: 14 29 
+
+minGini: 8.842105 - 5
+Region.size: 43
+LeftChild.size: 38
+LeftChild.ClassCounts: 14 24 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 7.932307 - 6
+Region.size: 38
+LeftChild.size: 25
+LeftChild.ClassCounts: 12 13 
+RightChild.size: 13
+RightChild.ClassCounts: 2 11 
+
+minGini: 0.000000 - 2
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 4.105263 - 7
+Region.size: 25
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 19
+RightChild.ClassCounts: 6 13 
+
+minGini: 3.058823 - 1
+Region.size: 19
+LeftChild.size: 17
+LeftChild.ClassCounts: 4 13 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.733333 - 5
+Region.size: 17
+LeftChild.size: 15
+LeftChild.ClassCounts: 2 13 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.928571 - 3
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 1 13 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 2
+Region.size: 14
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 17.546666 - 7
+Region.size: 84
+LeftChild.size: 75
+LeftChild.ClassCounts: 47 28 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 15.739495 - 0
+Region.size: 75
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 
+RightChild.size: 68
+RightChild.ClassCounts: 46 22 
+
+minGini: 12.940350 - 5
+Region.size: 68
+LeftChild.size: 30
+LeftChild.ClassCounts: 26 4 
+RightChild.size: 38
+RightChild.ClassCounts: 20 18 
+
+minGini: 7.440613 - 5
+Region.size: 38
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 29
+RightChild.ClassCounts: 19 10 
+
+minGini: 5.387254 - 4
+Region.size: 29
+LeftChild.size: 12
+LeftChild.ClassCounts: 5 7 
+RightChild.size: 17
+RightChild.ClassCounts: 14 3 
+
+minGini: 0.000000 - 2
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.833333 - 6
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.500000 - 2
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.857142 - 7
+Region.size: 30
+LeftChild.size: 28
+LeftChild.ClassCounts: 26 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.600000 - 6
+Region.size: 28
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 
+RightChild.size: 10
+RightChild.ClassCounts: 8 2 
+
+minGini: 1.000000 - 5
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.500000 - 2
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 7.897435 - 6
+Region.size: 73
+LeftChild.size: 34
+LeftChild.ClassCounts: 34 0 
+RightChild.size: 39
+RightChild.ClassCounts: 28 11 
+
+minGini: 6.160000 - 6
+Region.size: 39
+LeftChild.size: 25
+LeftChild.ClassCounts: 14 11 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 4.200000 - 0
+Region.size: 25
+LeftChild.size: 20
+LeftChild.ClassCounts: 14 6 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 2.000000 - 2
+Region.size: 20
+LeftChild.size: 9
+LeftChild.ClassCounts: 3 6 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 0.750000 - 3
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 28.490258 - 3
+Region.size: 307
+LeftChild.size: 229
+LeftChild.ClassCounts: 215 14 
+RightChild.size: 78
+RightChild.ClassCounts: 57 21 
+
+minGini: 13.353947 - 3
+Region.size: 78
+LeftChild.size: 40
+LeftChild.ClassCounts: 23 17 
+RightChild.size: 38
+RightChild.ClassCounts: 34 4 
+
+minGini: 2.756756 - 1
+Region.size: 38
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 37
+RightChild.ClassCounts: 34 3 
+
+minGini: 0.000000 - 4
+Region.size: 37
+LeftChild.size: 34
+LeftChild.ClassCounts: 34 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 7.885714 - 5
+Region.size: 40
+LeftChild.size: 35
+LeftChild.ClassCounts: 23 12 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 5.366666 - 2
+Region.size: 35
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 30
+RightChild.ClassCounts: 23 7 
+
+minGini: 4.666666 - 5
+Region.size: 30
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 21
+RightChild.ClassCounts: 14 7 
+
+minGini: 1.750000 - 6
+Region.size: 21
+LeftChild.size: 16
+LeftChild.ClassCounts: 14 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.933333 - 1
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 14 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 12.103554 - 7
+Region.size: 229
+LeftChild.size: 152
+LeftChild.ClassCounts: 150 2 
+RightChild.size: 77
+RightChild.ClassCounts: 65 12 
+
+minGini: 9.780602 - 3
+Region.size: 77
+LeftChild.size: 59
+LeftChild.ClassCounts: 52 7 
+RightChild.size: 18
+RightChild.ClassCounts: 13 5 
+
+minGini: 2.222222 - 4
+Region.size: 18
+LeftChild.size: 9
+LeftChild.ClassCounts: 4 5 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 6
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 5.558823 - 5
+Region.size: 59
+LeftChild.size: 25
+LeftChild.ClassCounts: 25 0 
+RightChild.size: 34
+RightChild.ClassCounts: 27 7 
+
+minGini: 3.500000 - 1
+Region.size: 34
+LeftChild.size: 20
+LeftChild.ClassCounts: 20 0 
+RightChild.size: 14
+RightChild.ClassCounts: 7 7 
+
+minGini: 2.916666 - 2
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 12
+RightChild.ClassCounts: 5 7 
+
+minGini: 2.250000 - 7
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 2 6 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 6
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.940298 - 4
+Region.size: 152
+LeftChild.size: 85
+LeftChild.ClassCounts: 85 0 
+RightChild.size: 67
+RightChild.ClassCounts: 65 2 
+
+minGini: 0.984848 - 4
+Region.size: 67
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 66
+RightChild.ClassCounts: 65 1 
+
+minGini: 0.857142 - 6
+Region.size: 66
+LeftChild.size: 59
+LeftChild.ClassCounts: 59 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.666666 - 7
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 6 finished.
+
+minGini: 155.044262 - 7
+Region.size: 768
+LeftChild.size: 280
+LeftChild.ClassCounts: 238 42 
+RightChild.size: 488
+RightChild.ClassCounts: 280 208 
+
+minGini: 110.969441 - 5
+Region.size: 488
+LeftChild.size: 170
+LeftChild.ClassCounts: 128 42 
+RightChild.size: 318
+RightChild.ClassCounts: 152 166 
+
+minGini: 76.987012 - 2
+Region.size: 318
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 308
+RightChild.ClassCounts: 152 156 
+
+minGini: 70.882249 - 6
+Region.size: 308
+LeftChild.size: 186
+LeftChild.ClassCounts: 113 73 
+RightChild.size: 122
+RightChild.ClassCounts: 39 83 
+
+minGini: 23.919769 - 3
+Region.size: 122
+LeftChild.size: 77
+LeftChild.ClassCounts: 16 61 
+RightChild.size: 45
+RightChild.ClassCounts: 23 22 
+
+minGini: 9.589743 - 2
+Region.size: 45
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 39
+RightChild.ClassCounts: 17 22 
+
+minGini: 8.233333 - 4
+Region.size: 39
+LeftChild.size: 24
+LeftChild.ClassCounts: 14 10 
+RightChild.size: 15
+RightChild.ClassCounts: 3 12 
+
+minGini: 1.714285 - 5
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 14
+RightChild.ClassCounts: 2 12 
+
+minGini: 1.333333 - 2
+Region.size: 14
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.666666 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 4.666666 - 2
+Region.size: 24
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 21
+RightChild.ClassCounts: 14 7 
+
+minGini: 1.750000 - 7
+Region.size: 21
+LeftChild.size: 16
+LeftChild.ClassCounts: 14 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.933333 - 6
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 14 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 7
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 8.591549 - 6
+Region.size: 77
+LeftChild.size: 71
+LeftChild.ClassCounts: 10 61 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 4.410394 - 1
+Region.size: 71
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 62
+RightChild.ClassCounts: 3 59 
+
+minGini: 2.640000 - 1
+Region.size: 62
+LeftChild.size: 25
+LeftChild.ClassCounts: 3 22 
+RightChild.size: 37
+RightChild.ClassCounts: 0 37 
+
+minGini: 1.833333 - 7
+Region.size: 25
+LeftChild.size: 24
+LeftChild.ClassCounts: 2 22 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.956521 - 5
+Region.size: 24
+LeftChild.size: 23
+LeftChild.ClassCounts: 1 22 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 2
+Region.size: 23
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 20 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.875000 - 1
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.500000 - 5
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 41.632211 - 0
+Region.size: 186
+LeftChild.size: 26
+LeftChild.ClassCounts: 8 18 
+RightChild.size: 160
+RightChild.ClassCounts: 105 55 
+
+minGini: 33.987279 - 4
+Region.size: 160
+LeftChild.size: 146
+LeftChild.ClassCounts: 101 45 
+RightChild.size: 14
+RightChild.ClassCounts: 4 10 
+
+minGini: 1.333333 - 7
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 0.800000 - 2
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 26.250000 - 1
+Region.size: 146
+LeftChild.size: 38
+LeftChild.ClassCounts: 38 0 
+RightChild.size: 108
+RightChild.ClassCounts: 63 45 
+
+minGini: 24.545454 - 0
+Region.size: 108
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 99
+RightChild.ClassCounts: 54 45 
+
+minGini: 22.541666 - 4
+Region.size: 99
+LeftChild.size: 72
+LeftChild.ClassCounts: 33 39 
+RightChild.size: 27
+RightChild.ClassCounts: 21 6 
+
+minGini: 3.514285 - 3
+Region.size: 27
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 
+RightChild.size: 20
+RightChild.ClassCounts: 18 2 
+
+minGini: 1.200000 - 4
+Region.size: 20
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.750000 - 4
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 16.557231 - 1
+Region.size: 72
+LeftChild.size: 49
+LeftChild.ClassCounts: 27 22 
+RightChild.size: 23
+RightChild.ClassCounts: 6 17 
+
+minGini: 3.464285 - 2
+Region.size: 23
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 
+RightChild.size: 16
+RightChild.ClassCounts: 2 14 
+
+minGini: 1.000000 - 3
+Region.size: 16
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 9.589743 - 1
+Region.size: 49
+LeftChild.size: 39
+LeftChild.ClassCounts: 17 22 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 8.596774 - 6
+Region.size: 39
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 2 
+RightChild.size: 31
+RightChild.ClassCounts: 11 20 
+
+minGini: 5.915384 - 0
+Region.size: 31
+LeftChild.size: 26
+LeftChild.ClassCounts: 7 19 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 2.590909 - 7
+Region.size: 26
+LeftChild.size: 22
+LeftChild.ClassCounts: 3 19 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 2.100000 - 5
+Region.size: 22
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 10
+RightChild.ClassCounts: 3 7 
+
+minGini: 1.200000 - 3
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 7
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 3.037500 - 3
+Region.size: 26
+LeftChild.size: 16
+LeftChild.ClassCounts: 1 15 
+RightChild.size: 10
+RightChild.ClassCounts: 7 3 
+
+minGini: 0.875000 - 2
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 3
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.800000 - 6
+Region.size: 16
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 29.848370 - 0
+Region.size: 170
+LeftChild.size: 114
+LeftChild.ClassCounts: 94 20 
+RightChild.size: 56
+RightChild.ClassCounts: 34 22 
+
+minGini: 10.234993 - 5
+Region.size: 56
+LeftChild.size: 27
+LeftChild.ClassCounts: 23 4 
+RightChild.size: 29
+RightChild.ClassCounts: 11 18 
+
+minGini: 3.913043 - 7
+Region.size: 29
+LeftChild.size: 23
+LeftChild.ClassCounts: 5 18 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 3.333333 - 5
+Region.size: 23
+LeftChild.size: 15
+LeftChild.ClassCounts: 5 10 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 2.727272 - 1
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 5 6 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.958333 - 1
+Region.size: 27
+LeftChild.size: 24
+LeftChild.ClassCounts: 23 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 7
+Region.size: 24
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 23
+RightChild.ClassCounts: 23 0 
+
+minGini: 13.750000 - 1
+Region.size: 114
+LeftChild.size: 50
+LeftChild.ClassCounts: 50 0 
+RightChild.size: 64
+RightChild.ClassCounts: 44 20 
+
+minGini: 12.770370 - 1
+Region.size: 64
+LeftChild.size: 54
+LeftChild.ClassCounts: 40 14 
+RightChild.size: 10
+RightChild.ClassCounts: 4 6 
+
+minGini: 0.800000 - 1
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 3
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 9.022556 - 0
+Region.size: 54
+LeftChild.size: 19
+LeftChild.ClassCounts: 10 9 
+RightChild.size: 35
+RightChild.ClassCounts: 30 5 
+
+minGini: 2.727272 - 6
+Region.size: 35
+LeftChild.size: 33
+LeftChild.ClassCounts: 30 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.550000 - 6
+Region.size: 33
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 20
+RightChild.ClassCounts: 17 3 
+
+minGini: 1.789473 - 6
+Region.size: 20
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 19
+RightChild.ClassCounts: 17 2 
+
+minGini: 1.428571 - 1
+Region.size: 19
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.857142 - 4
+Region.size: 19
+LeftChild.size: 14
+LeftChild.ClassCounts: 10 4 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 2.000000 - 5
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 8
+RightChild.ClassCounts: 4 4 
+
+minGini: 0.800000 - 3
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 29.071133 - 5
+Region.size: 280
+LeftChild.size: 156
+LeftChild.ClassCounts: 154 2 
+RightChild.size: 124
+RightChild.ClassCounts: 84 40 
+
+minGini: 24.162406 - 5
+Region.size: 124
+LeftChild.size: 105
+LeftChild.ClassCounts: 78 27 
+RightChild.size: 19
+RightChild.ClassCounts: 6 13 
+
+minGini: 2.400000 - 6
+Region.size: 19
+LeftChild.size: 10
+LeftChild.ClassCounts: 6 4 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 1.500000 - 1
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 17.160000 - 1
+Region.size: 105
+LeftChild.size: 100
+LeftChild.ClassCounts: 78 22 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 16.015254 - 1
+Region.size: 100
+LeftChild.size: 47
+LeftChild.ClassCounts: 42 5 
+RightChild.size: 53
+RightChild.ClassCounts: 36 17 
+
+minGini: 10.446428 - 5
+Region.size: 53
+LeftChild.size: 32
+LeftChild.ClassCounts: 18 14 
+RightChild.size: 21
+RightChild.ClassCounts: 18 3 
+
+minGini: 1.800000 - 0
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 18 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.947368 - 2
+Region.size: 20
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 19
+RightChild.ClassCounts: 18 1 
+
+minGini: 0.857142 - 3
+Region.size: 19
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.500000 - 2
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 7.200000 - 2
+Region.size: 32
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 30
+RightChild.ClassCounts: 18 12 
+
+minGini: 5.239819 - 3
+Region.size: 30
+LeftChild.size: 17
+LeftChild.ClassCounts: 14 3 
+RightChild.size: 13
+RightChild.ClassCounts: 4 9 
+
+minGini: 2.222222 - 1
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 4 5 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.800000 - 6
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 3
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.714285 - 3
+Region.size: 17
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.750000 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.500000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 3.790697 - 2
+Region.size: 47
+LeftChild.size: 43
+LeftChild.ClassCounts: 40 3 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.666666 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.402439 - 5
+Region.size: 43
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 41
+RightChild.ClassCounts: 39 2 
+
+minGini: 0.975000 - 4
+Region.size: 41
+LeftChild.size: 40
+LeftChild.ClassCounts: 39 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.875000 - 1
+Region.size: 40
+LeftChild.size: 32
+LeftChild.ClassCounts: 32 0 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.764705 - 1
+Region.size: 156
+LeftChild.size: 139
+LeftChild.ClassCounts: 139 0 
+RightChild.size: 17
+RightChild.ClassCounts: 15 2 
+
+minGini: 0.000000 - 1
+Region.size: 17
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 
+
+
+
+Tree Number: 7 finished.
+
+minGini: 164.648979 - 6
+Region.size: 768
+LeftChild.size: 639
+LeftChild.ClassCounts: 450 189 
+RightChild.size: 129
+RightChild.ClassCounts: 55 74 
+
+minGini: 27.685567 - 3
+Region.size: 129
+LeftChild.size: 97
+LeftChild.ClassCounts: 51 46 
+RightChild.size: 32
+RightChild.ClassCounts: 4 28 
+
+minGini: 3.051851 - 3
+Region.size: 32
+LeftChild.size: 27
+LeftChild.ClassCounts: 2 25 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.625000 - 6
+Region.size: 27
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 24
+RightChild.ClassCounts: 1 23 
+
+minGini: 0.750000 - 7
+Region.size: 24
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 20
+RightChild.ClassCounts: 0 20 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 17.835000 - 7
+Region.size: 97
+LeftChild.size: 25
+LeftChild.ClassCounts: 24 1 
+RightChild.size: 72
+RightChild.ClassCounts: 27 45 
+
+minGini: 13.200000 - 1
+Region.size: 72
+LeftChild.size: 27
+LeftChild.ClassCounts: 18 9 
+RightChild.size: 45
+RightChild.ClassCounts: 9 36 
+
+minGini: 2.769230 - 6
+Region.size: 45
+LeftChild.size: 39
+LeftChild.ClassCounts: 3 36 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 1.500000 - 5
+Region.size: 39
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 33 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 
+
+minGini: 0.750000 - 2
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 4.650000 - 2
+Region.size: 27
+LeftChild.size: 15
+LeftChild.ClassCounts: 13 2 
+RightChild.size: 12
+RightChild.ClassCounts: 5 7 
+
+minGini: 0.875000 - 3
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.666666 - 2
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.333333 - 7
+Region.size: 15
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.888888 - 5
+Region.size: 25
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 9
+RightChild.ClassCounts: 8 1 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 129.023852 - 2
+Region.size: 639
+LeftChild.size: 542
+LeftChild.ClassCounts: 400 142 
+RightChild.size: 97
+RightChild.ClassCounts: 50 47 
+
+minGini: 23.083333 - 7
+Region.size: 97
+LeftChild.size: 33
+LeftChild.ClassCounts: 22 11 
+RightChild.size: 64
+RightChild.ClassCounts: 28 36 
+
+minGini: 9.748987 - 1
+Region.size: 64
+LeftChild.size: 26
+LeftChild.ClassCounts: 21 5 
+RightChild.size: 38
+RightChild.ClassCounts: 7 31 
+
+minGini: 4.869565 - 3
+Region.size: 38
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 
+RightChild.size: 23
+RightChild.ClassCounts: 7 16 
+
+minGini: 3.809523 - 7
+Region.size: 23
+LeftChild.size: 21
+LeftChild.ClassCounts: 5 16 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.500000 - 7
+Region.size: 21
+LeftChild.size: 10
+LeftChild.ClassCounts: 5 5 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 0.000000 - 5
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.954545 - 5
+Region.size: 26
+LeftChild.size: 22
+LeftChild.ClassCounts: 21 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.875000 - 6
+Region.size: 22
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.000000 - 7
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 3.384615 - 5
+Region.size: 33
+LeftChild.size: 26
+LeftChild.ClassCounts: 22 4 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 2.152380 - 6
+Region.size: 26
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 21
+RightChild.ClassCounts: 20 1 
+
+minGini: 0.750000 - 3
+Region.size: 21
+LeftChild.size: 17
+LeftChild.ClassCounts: 17 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.500000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 94.299945 - 5
+Region.size: 542
+LeftChild.size: 177
+LeftChild.ClassCounts: 166 11 
+RightChild.size: 365
+RightChild.ClassCounts: 234 131 
+
+minGini: 60.246575 - 1
+Region.size: 365
+LeftChild.size: 219
+LeftChild.ClassCounts: 186 33 
+RightChild.size: 146
+RightChild.ClassCounts: 48 98 
+
+minGini: 28.716176 - 6
+Region.size: 146
+LeftChild.size: 136
+LeftChild.ClassCounts: 39 97 
+RightChild.size: 10
+RightChild.ClassCounts: 9 1 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 25.321146 - 7
+Region.size: 136
+LeftChild.size: 92
+LeftChild.ClassCounts: 35 57 
+RightChild.size: 44
+RightChild.ClassCounts: 4 40 
+
+minGini: 3.433551 - 5
+Region.size: 44
+LeftChild.size: 17
+LeftChild.ClassCounts: 3 14 
+RightChild.size: 27
+RightChild.ClassCounts: 1 26 
+
+minGini: 0.833333 - 2
+Region.size: 27
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 21
+RightChild.ClassCounts: 0 21 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.933333 - 7
+Region.size: 17
+LeftChild.size: 15
+LeftChild.ClassCounts: 1 14 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.800000 - 4
+Region.size: 15
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 19.043478 - 2
+Region.size: 92
+LeftChild.size: 23
+LeftChild.ClassCounts: 2 21 
+RightChild.size: 69
+RightChild.ClassCounts: 33 36 
+
+minGini: 14.604729 - 1
+Region.size: 69
+LeftChild.size: 32
+LeftChild.ClassCounts: 22 10 
+RightChild.size: 37
+RightChild.ClassCounts: 11 26 
+
+minGini: 6.035294 - 6
+Region.size: 37
+LeftChild.size: 17
+LeftChild.ClassCounts: 9 8 
+RightChild.size: 20
+RightChild.ClassCounts: 2 18 
+
+minGini: 0.947368 - 6
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 1 18 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.378787 - 1
+Region.size: 17
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 11
+RightChild.ClassCounts: 4 7 
+
+minGini: 1.333333 - 2
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.666666 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 4.866396 - 6
+Region.size: 32
+LeftChild.size: 19
+LeftChild.ClassCounts: 17 2 
+RightChild.size: 13
+RightChild.ClassCounts: 5 8 
+
+minGini: 1.428571 - 3
+Region.size: 13
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.944444 - 3
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 17 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.875000 - 7
+Region.size: 18
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 1.555555 - 5
+Region.size: 23
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 7 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 0.875000 - 5
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 22.749822 - 7
+Region.size: 219
+LeftChild.size: 136
+LeftChild.ClassCounts: 132 4 
+RightChild.size: 83
+RightChild.ClassCounts: 54 29 
+
+minGini: 16.896616 - 6
+Region.size: 83
+LeftChild.size: 76
+LeftChild.ClassCounts: 53 23 
+RightChild.size: 7
+RightChild.ClassCounts: 1 6 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 14.183333 - 3
+Region.size: 76
+LeftChild.size: 60
+LeftChild.ClassCounts: 37 23 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 
+
+minGini: 10.542124 - 1
+Region.size: 60
+LeftChild.size: 21
+LeftChild.ClassCounts: 20 1 
+RightChild.size: 39
+RightChild.ClassCounts: 17 22 
+
+minGini: 7.707894 - 5
+Region.size: 39
+LeftChild.size: 19
+LeftChild.ClassCounts: 4 15 
+RightChild.size: 20
+RightChild.ClassCounts: 13 7 
+
+minGini: 1.780219 - 1
+Region.size: 20
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 
+RightChild.size: 13
+RightChild.ClassCounts: 12 1 
+
+minGini: 0.666666 - 5
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 1.764705 - 5
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 17
+RightChild.ClassCounts: 2 15 
+
+minGini: 0.937500 - 4
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 1 15 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 0
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 
+
+minGini: 0.000000 - 1
+Region.size: 21
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 
+
+minGini: 2.933333 - 2
+Region.size: 136
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 135
+RightChild.ClassCounts: 132 3 
+
+minGini: 2.842592 - 5
+Region.size: 135
+LeftChild.size: 108
+LeftChild.ClassCounts: 107 1 
+RightChild.size: 27
+RightChild.ClassCounts: 25 2 
+
+minGini: 1.706521 - 1
+Region.size: 27
+LeftChild.size: 23
+LeftChild.ClassCounts: 22 1 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.833333 - 1
+Region.size: 23
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 17
+RightChild.ClassCounts: 17 0 
+
+minGini: 0.500000 - 6
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.916666 - 0
+Region.size: 108
+LeftChild.size: 12
+LeftChild.ClassCounts: 11 1 
+RightChild.size: 96
+RightChild.ClassCounts: 96 0 
+
+minGini: 0.750000 - 7
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 9.509595 - 0
+Region.size: 177
+LeftChild.size: 132
+LeftChild.ClassCounts: 129 3 
+RightChild.size: 45
+RightChild.ClassCounts: 37 8 
+
+minGini: 5.293233 - 7
+Region.size: 45
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 
+RightChild.size: 38
+RightChild.ClassCounts: 34 4 
+
+minGini: 3.250000 - 4
+Region.size: 38
+LeftChild.size: 36
+LeftChild.ClassCounts: 33 3 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.500000 - 1
+Region.size: 36
+LeftChild.size: 30
+LeftChild.ClassCounts: 30 0 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 2.469230 - 1
+Region.size: 132
+LeftChild.size: 130
+LeftChild.ClassCounts: 128 2 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.866803 - 2
+Region.size: 130
+LeftChild.size: 122
+LeftChild.ClassCounts: 121 1 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.500000 - 5
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.974358 - 5
+Region.size: 122
+LeftChild.size: 39
+LeftChild.ClassCounts: 38 1 
+RightChild.size: 83
+RightChild.ClassCounts: 83 0 
+
+minGini: 0.000000 - 6
+Region.size: 39
+LeftChild.size: 38
+LeftChild.ClassCounts: 38 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 8 finished.
+
+minGini: 156.552336 - 0
+Region.size: 768
+LeftChild.size: 358
+LeftChild.ClassCounts: 289 69 
+RightChild.size: 410
+RightChild.ClassCounts: 231 179 
+
+minGini: 79.965405 - 1
+Region.size: 410
+LeftChild.size: 218
+LeftChild.ClassCounts: 169 49 
+RightChild.size: 192
+RightChild.ClassCounts: 62 130 
+
+minGini: 39.132227 - 5
+Region.size: 192
+LeftChild.size: 39
+LeftChild.ClassCounts: 22 17 
+RightChild.size: 153
+RightChild.ClassCounts: 40 113 
+
+minGini: 26.292252 - 3
+Region.size: 153
+LeftChild.size: 106
+LeftChild.ClassCounts: 38 68 
+RightChild.size: 47
+RightChild.ClassCounts: 2 45 
+
+minGini: 1.800000 - 6
+Region.size: 47
+LeftChild.size: 20
+LeftChild.ClassCounts: 2 18 
+RightChild.size: 27
+RightChild.ClassCounts: 0 27 
+
+minGini: 1.500000 - 7
+Region.size: 20
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 8
+RightChild.ClassCounts: 2 6 
+
+minGini: 0.666666 - 4
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.500000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 22.800000 - 5
+Region.size: 106
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 95
+RightChild.ClassCounts: 38 57 
+
+minGini: 21.651162 - 2
+Region.size: 95
+LeftChild.size: 43
+LeftChild.ClassCounts: 12 31 
+RightChild.size: 52
+RightChild.ClassCounts: 26 26 
+
+minGini: 9.745185 - 1
+Region.size: 52
+LeftChild.size: 27
+LeftChild.ClassCounts: 20 7 
+RightChild.size: 25
+RightChild.ClassCounts: 6 19 
+
+minGini: 2.590909 - 3
+Region.size: 25
+LeftChild.size: 22
+LeftChild.ClassCounts: 3 19 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.944444 - 2
+Region.size: 22
+LeftChild.size: 18
+LeftChild.ClassCounts: 1 17 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.800000 - 1
+Region.size: 18
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.500000 - 0
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.333333 - 2
+Region.size: 27
+LeftChild.size: 24
+LeftChild.ClassCounts: 20 4 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.818181 - 6
+Region.size: 24
+LeftChild.size: 22
+LeftChild.ClassCounts: 20 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.450000 - 1
+Region.size: 22
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 20
+RightChild.ClassCounts: 19 1 
+
+minGini: 0.857142 - 5
+Region.size: 20
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 0.750000 - 2
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 6.452380 - 2
+Region.size: 43
+LeftChild.size: 22
+LeftChild.ClassCounts: 11 11 
+RightChild.size: 21
+RightChild.ClassCounts: 1 20 
+
+minGini: 0.833333 - 3
+Region.size: 21
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 3.196581 - 2
+Region.size: 22
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 13
+RightChild.ClassCounts: 10 3 
+
+minGini: 0.909090 - 6
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 10 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 3
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 8.333333 - 2
+Region.size: 39
+LeftChild.size: 27
+LeftChild.ClassCounts: 12 15 
+RightChild.size: 12
+RightChild.ClassCounts: 10 2 
+
+minGini: 0.909090 - 1
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.000000 - 7
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 5.166666 - 4
+Region.size: 27
+LeftChild.size: 18
+LeftChild.ClassCounts: 5 13 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 
+
+minGini: 0.000000 - 4
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.623376 - 6
+Region.size: 18
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 
+RightChild.size: 11
+RightChild.ClassCounts: 1 10 
+
+minGini: 0.500000 - 7
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.800000 - 1
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 33.845826 - 6
+Region.size: 218
+LeftChild.size: 209
+LeftChild.ClassCounts: 168 41 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 
+
+minGini: 0.000000 - 6
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 30.724721 - 5
+Region.size: 209
+LeftChild.size: 53
+LeftChild.ClassCounts: 52 1 
+RightChild.size: 156
+RightChild.ClassCounts: 116 40 
+
+minGini: 28.255267 - 6
+Region.size: 156
+LeftChild.size: 131
+LeftChild.ClassCounts: 103 28 
+RightChild.size: 25
+RightChild.ClassCounts: 13 12 
+
+minGini: 4.421052 - 5
+Region.size: 25
+LeftChild.size: 19
+LeftChild.ClassCounts: 7 12 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 1.773809 - 1
+Region.size: 19
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 12
+RightChild.ClassCounts: 1 11 
+
+minGini: 0.800000 - 0
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.500000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 20.828740 - 2
+Region.size: 131
+LeftChild.size: 127
+LeftChild.ClassCounts: 102 25 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 18.096774 - 0
+Region.size: 127
+LeftChild.size: 124
+LeftChild.ClassCounts: 102 22 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 16.847819 - 6
+Region.size: 124
+LeftChild.size: 79
+LeftChild.ClassCounts: 59 20 
+RightChild.size: 45
+RightChild.ClassCounts: 43 2 
+
+minGini: 0.977272 - 3
+Region.size: 45
+LeftChild.size: 44
+LeftChild.ClassCounts: 43 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.923076 - 0
+Region.size: 44
+LeftChild.size: 31
+LeftChild.ClassCounts: 31 0 
+RightChild.size: 13
+RightChild.ClassCounts: 12 1 
+
+minGini: 0.000000 - 7
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 
+
+minGini: 13.323680 - 5
+Region.size: 79
+LeftChild.size: 37
+LeftChild.ClassCounts: 22 15 
+RightChild.size: 42
+RightChild.ClassCounts: 37 5 
+
+minGini: 3.863636 - 3
+Region.size: 42
+LeftChild.size: 22
+LeftChild.ClassCounts: 17 5 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 
+
+minGini: 3.192982 - 5
+Region.size: 22
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 19
+RightChild.ClassCounts: 16 3 
+
+minGini: 1.777777 - 6
+Region.size: 19
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 18
+RightChild.ClassCounts: 16 2 
+
+minGini: 1.636363 - 1
+Region.size: 18
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 11
+RightChild.ClassCounts: 9 2 
+
+minGini: 0.900000 - 1
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 10
+RightChild.ClassCounts: 9 1 
+
+minGini: 0.500000 - 2
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 6.756410 - 4
+Region.size: 37
+LeftChild.size: 24
+LeftChild.ClassCounts: 10 14 
+RightChild.size: 13
+RightChild.ClassCounts: 12 1 
+
+minGini: 0.750000 - 6
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 4.488888 - 7
+Region.size: 24
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 15
+RightChild.ClassCounts: 9 6 
+
+minGini: 1.636363 - 5
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.900000 - 3
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 7
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 3
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.916666 - 6
+Region.size: 53
+LeftChild.size: 41
+LeftChild.ClassCounts: 41 0 
+RightChild.size: 12
+RightChild.ClassCounts: 11 1 
+
+minGini: 0.500000 - 5
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 41.005770 - 1
+Region.size: 358
+LeftChild.size: 317
+LeftChild.ClassCounts: 279 38 
+RightChild.size: 41
+RightChild.ClassCounts: 10 31 
+
+minGini: 4.386554 - 5
+Region.size: 41
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 34
+RightChild.ClassCounts: 4 30 
+
+minGini: 2.677248 - 5
+Region.size: 34
+LeftChild.size: 27
+LeftChild.ClassCounts: 1 26 
+RightChild.size: 7
+RightChild.ClassCounts: 3 4 
+
+minGini: 0.750000 - 1
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 27
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 
+
+minGini: 0.000000 - 3
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 31.624455 - 3
+Region.size: 317
+LeftChild.size: 218
+LeftChild.ClassCounts: 203 15 
+RightChild.size: 99
+RightChild.ClassCounts: 76 23 
+
+minGini: 15.181818 - 6
+Region.size: 99
+LeftChild.size: 55
+LeftChild.ClassCounts: 50 5 
+RightChild.size: 44
+RightChild.ClassCounts: 26 18 
+
+minGini: 9.243243 - 1
+Region.size: 44
+LeftChild.size: 37
+LeftChild.ClassCounts: 19 18 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 7.548387 - 3
+Region.size: 37
+LeftChild.size: 31
+LeftChild.ClassCounts: 13 18 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 6.474789 - 7
+Region.size: 31
+LeftChild.size: 17
+LeftChild.ClassCounts: 10 7 
+RightChild.size: 14
+RightChild.ClassCounts: 3 11 
+
+minGini: 0.916666 - 5
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 12
+RightChild.ClassCounts: 1 11 
+
+minGini: 0.666666 - 5
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.230769 - 2
+Region.size: 17
+LeftChild.size: 13
+LeftChild.ClassCounts: 6 7 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 2.545454 - 1
+Region.size: 13
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 11
+RightChild.ClassCounts: 4 7 
+
+minGini: 2.000000 - 6
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 4 4 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.333333 - 1
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.666666 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.500000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 3.703703 - 4
+Region.size: 55
+LeftChild.size: 54
+LeftChild.ClassCounts: 50 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.857142 - 1
+Region.size: 54
+LeftChild.size: 40
+LeftChild.ClassCounts: 40 0 
+RightChild.size: 14
+RightChild.ClassCounts: 10 4 
+
+minGini: 0.909090 - 1
+Region.size: 14
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.500000 - 5
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 12.606382 - 5
+Region.size: 218
+LeftChild.size: 124
+LeftChild.ClassCounts: 124 0 
+RightChild.size: 94
+RightChild.ClassCounts: 79 15 
+
+minGini: 10.786199 - 7
+Region.size: 94
+LeftChild.size: 68
+LeftChild.ClassCounts: 63 5 
+RightChild.size: 26
+RightChild.ClassCounts: 16 10 
+
+minGini: 5.000000 - 6
+Region.size: 26
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 20
+RightChild.ClassCounts: 10 10 
+
+minGini: 4.047619 - 0
+Region.size: 20
+LeftChild.size: 14
+LeftChild.ClassCounts: 5 9 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 2.250000 - 1
+Region.size: 14
+LeftChild.size: 12
+LeftChild.ClassCounts: 3 9 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.555555 - 6
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 2
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.761194 - 6
+Region.size: 68
+LeftChild.size: 67
+LeftChild.ClassCounts: 63 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.938461 - 2
+Region.size: 67
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 65
+RightChild.ClassCounts: 63 2 
+
+minGini: 1.839901 - 1
+Region.size: 65
+LeftChild.size: 58
+LeftChild.ClassCounts: 57 1 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.750000 - 2
+Region.size: 58
+LeftChild.size: 54
+LeftChild.ClassCounts: 54 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 9 finished.
+
+minGini: 151.815651 - 5
+Region.size: 768
+LeftChild.size: 297
+LeftChild.ClassCounts: 256 41 
+RightChild.size: 471
+RightChild.ClassCounts: 260 211 
+
+minGini: 112.096996 - 0
+Region.size: 471
+LeftChild.size: 360
+LeftChild.ClassCounts: 218 142 
+RightChild.size: 111
+RightChild.ClassCounts: 42 69 
+
+minGini: 19.749687 - 1
+Region.size: 111
+LeftChild.size: 17
+LeftChild.ClassCounts: 16 1 
+RightChild.size: 94
+RightChild.ClassCounts: 26 68 
+
+minGini: 17.692592 - 7
+Region.size: 94
+LeftChild.size: 54
+LeftChild.ClassCounts: 20 34 
+RightChild.size: 40
+RightChild.ClassCounts: 6 34 
+
+minGini: 3.600000 - 4
+Region.size: 40
+LeftChild.size: 15
+LeftChild.ClassCounts: 6 9 
+RightChild.size: 25
+RightChild.ClassCounts: 0 25 
+
+minGini: 2.727272 - 6
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 6 5 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.500000 - 5
+Region.size: 11
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.857142 - 1
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 11.333333 - 4
+Region.size: 54
+LeftChild.size: 51
+LeftChild.ClassCounts: 17 34 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 8.691935 - 1
+Region.size: 51
+LeftChild.size: 31
+LeftChild.ClassCounts: 16 15 
+RightChild.size: 20
+RightChild.ClassCounts: 1 19 
+
+minGini: 0.833333 - 3
+Region.size: 20
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 0.500000 - 0
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 5.771929 - 1
+Region.size: 31
+LeftChild.size: 19
+LeftChild.ClassCounts: 6 13 
+RightChild.size: 12
+RightChild.ClassCounts: 10 2 
+
+minGini: 0.000000 - 2
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 3.058823 - 7
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 17
+RightChild.ClassCounts: 4 13 
+
+minGini: 0.800000 - 6
+Region.size: 17
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.750000 - 7
+Region.size: 17
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 66.553246 - 1
+Region.size: 360
+LeftChild.size: 220
+LeftChild.ClassCounts: 174 46 
+RightChild.size: 140
+RightChild.ClassCounts: 44 96 
+
+minGini: 28.170940 - 6
+Region.size: 140
+LeftChild.size: 104
+LeftChild.ClassCounts: 40 64 
+RightChild.size: 36
+RightChild.ClassCounts: 4 32 
+
+minGini: 2.167741 - 4
+Region.size: 36
+LeftChild.size: 31
+LeftChild.ClassCounts: 1 30 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 0
+Region.size: 31
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 30 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 21.153409 - 7
+Region.size: 104
+LeftChild.size: 16
+LeftChild.ClassCounts: 13 3 
+RightChild.size: 88
+RightChild.ClassCounts: 27 61 
+
+minGini: 17.548611 - 2
+Region.size: 88
+LeftChild.size: 72
+LeftChild.ClassCounts: 26 46 
+RightChild.size: 16
+RightChild.ClassCounts: 1 15 
+
+minGini: 0.500000 - 7
+Region.size: 16
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 15.783251 - 5
+Region.size: 72
+LeftChild.size: 14
+LeftChild.ClassCounts: 2 12 
+RightChild.size: 58
+RightChild.ClassCounts: 24 34 
+
+minGini: 12.621118 - 2
+Region.size: 58
+LeftChild.size: 35
+LeftChild.ClassCounts: 10 25 
+RightChild.size: 23
+RightChild.ClassCounts: 14 9 
+
+minGini: 3.214285 - 7
+Region.size: 23
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 14
+RightChild.ClassCounts: 5 9 
+
+minGini: 0.900000 - 6
+Region.size: 14
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.740000 - 7
+Region.size: 35
+LeftChild.size: 25
+LeftChild.ClassCounts: 3 22 
+RightChild.size: 10
+RightChild.ClassCounts: 7 3 
+
+minGini: 0.750000 - 6
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.833333 - 6
+Region.size: 25
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 24
+RightChild.ClassCounts: 2 22 
+
+minGini: 1.636363 - 0
+Region.size: 24
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 
+RightChild.size: 11
+RightChild.ClassCounts: 2 9 
+
+minGini: 0.900000 - 1
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 1 9 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 5
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.923076 - 1
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 13
+RightChild.ClassCounts: 1 12 
+
+minGini: 0.666666 - 5
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.589743 - 6
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 12 1 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 5
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 31.261157 - 7
+Region.size: 220
+LeftChild.size: 151
+LeftChild.ClassCounts: 135 16 
+RightChild.size: 69
+RightChild.ClassCounts: 39 30 
+
+minGini: 15.872222 - 6
+Region.size: 69
+LeftChild.size: 60
+LeftChild.ClassCounts: 31 29 
+RightChild.size: 9
+RightChild.ClassCounts: 8 1 
+
+minGini: 0.500000 - 0
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 13.839285 - 1
+Region.size: 60
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 56
+RightChild.ClassCounts: 31 25 
+
+minGini: 12.431818 - 4
+Region.size: 56
+LeftChild.size: 44
+LeftChild.ClassCounts: 28 16 
+RightChild.size: 12
+RightChild.ClassCounts: 3 9 
+
+minGini: 0.000000 - 5
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 8.242424 - 1
+Region.size: 44
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 33
+RightChild.ClassCounts: 17 16 
+
+minGini: 6.333333 - 7
+Region.size: 33
+LeftChild.size: 12
+LeftChild.ClassCounts: 10 2 
+RightChild.size: 21
+RightChild.ClassCounts: 7 14 
+
+minGini: 3.309090 - 3
+Region.size: 21
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 10
+RightChild.ClassCounts: 6 4 
+
+minGini: 0.800000 - 5
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 2
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.333333 - 5
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.666666 - 3
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 13.424175 - 5
+Region.size: 151
+LeftChild.size: 60
+LeftChild.ClassCounts: 48 12 
+RightChild.size: 91
+RightChild.ClassCounts: 87 4 
+
+minGini: 2.900000 - 2
+Region.size: 91
+LeftChild.size: 90
+LeftChild.ClassCounts: 87 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.839285 - 5
+Region.size: 90
+LeftChild.size: 56
+LeftChild.ClassCounts: 53 3 
+RightChild.size: 34
+RightChild.ClassCounts: 34 0 
+
+minGini: 1.927272 - 5
+Region.size: 56
+LeftChild.size: 55
+LeftChild.ClassCounts: 53 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.981481 - 6
+Region.size: 55
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 54
+RightChild.ClassCounts: 53 1 
+
+minGini: 0.928571 - 5
+Region.size: 54
+LeftChild.size: 14
+LeftChild.ClassCounts: 13 1 
+RightChild.size: 40
+RightChild.ClassCounts: 40 0 
+
+minGini: 0.750000 - 0
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 6.900000 - 1
+Region.size: 60
+LeftChild.size: 40
+LeftChild.ClassCounts: 38 2 
+RightChild.size: 20
+RightChild.ClassCounts: 10 10 
+
+minGini: 3.737373 - 4
+Region.size: 20
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 7 
+RightChild.size: 11
+RightChild.ClassCounts: 8 3 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.666666 - 7
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.500000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 5
+Region.size: 40
+LeftChild.size: 37
+LeftChild.ClassCounts: 37 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 30.544383 - 1
+Region.size: 297
+LeftChild.size: 262
+LeftChild.ClassCounts: 238 24 
+RightChild.size: 35
+RightChild.ClassCounts: 18 17 
+
+minGini: 6.678571 - 5
+Region.size: 35
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 28
+RightChild.ClassCounts: 11 17 
+
+minGini: 4.958333 - 7
+Region.size: 28
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 24
+RightChild.ClassCounts: 7 17 
+
+minGini: 4.434782 - 2
+Region.size: 24
+LeftChild.size: 23
+LeftChild.ClassCounts: 6 17 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.866666 - 1
+Region.size: 23
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 20
+RightChild.ClassCounts: 4 16 
+
+minGini: 2.526315 - 4
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 3 16 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.777777 - 5
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 2 16 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.555555 - 0
+Region.size: 18
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 9
+RightChild.ClassCounts: 2 7 
+
+minGini: 1.200000 - 0
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.666666 - 7
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 19.661842 - 0
+Region.size: 262
+LeftChild.size: 159
+LeftChild.ClassCounts: 156 3 
+RightChild.size: 103
+RightChild.ClassCounts: 82 21 
+
+minGini: 14.761904 - 3
+Region.size: 103
+LeftChild.size: 96
+LeftChild.ClassCounts: 80 16 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 11.586206 - 6
+Region.size: 96
+LeftChild.size: 38
+LeftChild.ClassCounts: 38 0 
+RightChild.size: 58
+RightChild.ClassCounts: 42 16 
+
+minGini: 10.455000 - 7
+Region.size: 58
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 50
+RightChild.ClassCounts: 39 11 
+
+minGini: 6.816666 - 5
+Region.size: 50
+LeftChild.size: 30
+LeftChild.ClassCounts: 28 2 
+RightChild.size: 20
+RightChild.ClassCounts: 11 9 
+
+minGini: 2.769230 - 1
+Region.size: 20
+LeftChild.size: 13
+LeftChild.ClassCounts: 4 9 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 2.000000 - 6
+Region.size: 13
+LeftChild.size: 8
+LeftChild.ClassCounts: 4 4 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 7
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.000000 - 1
+Region.size: 30
+LeftChild.size: 26
+LeftChild.ClassCounts: 26 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 2.718750 - 5
+Region.size: 159
+LeftChild.size: 127
+LeftChild.ClassCounts: 127 0 
+RightChild.size: 32
+RightChild.ClassCounts: 29 3 
+
+minGini: 2.162962 - 1
+Region.size: 32
+LeftChild.size: 27
+LeftChild.ClassCounts: 26 1 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.833333 - 3
+Region.size: 27
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 21
+RightChild.ClassCounts: 21 0 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+
+
+Tree Number: 10 finished.
+
+minGini: 149.822665 - 5
+Region.size: 768
+LeftChild.size: 310
+LeftChild.ClassCounts: 264 46 
+RightChild.size: 458
+RightChild.ClassCounts: 271 187 
+
+minGini: 96.718096 - 1
+Region.size: 458
+LeftChild.size: 288
+LeftChild.ClassCounts: 209 79 
+RightChild.size: 170
+RightChild.ClassCounts: 62 108 
+
+minGini: 36.594703 - 0
+Region.size: 170
+LeftChild.size: 121
+LeftChild.ClassCounts: 54 67 
+RightChild.size: 49
+RightChild.ClassCounts: 8 41 
+
+minGini: 5.333333 - 1
+Region.size: 49
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 
+RightChild.size: 42
+RightChild.ClassCounts: 4 38 
+
+minGini: 2.780487 - 0
+Region.size: 42
+LeftChild.size: 41
+LeftChild.ClassCounts: 3 38 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.875000 - 6
+Region.size: 41
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 33
+RightChild.ClassCounts: 0 33 
+
+minGini: 0.833333 - 4
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 28.194690 - 2
+Region.size: 121
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 113
+RightChild.ClassCounts: 54 59 
+
+minGini: 25.858533 - 7
+Region.size: 113
+LeftChild.size: 67
+LeftChild.ClassCounts: 40 27 
+RightChild.size: 46
+RightChild.ClassCounts: 14 32 
+
+minGini: 8.956521 - 1
+Region.size: 46
+LeftChild.size: 23
+LeftChild.ClassCounts: 10 13 
+RightChild.size: 23
+RightChild.ClassCounts: 4 19 
+
+minGini: 0.950000 - 6
+Region.size: 23
+LeftChild.size: 20
+LeftChild.ClassCounts: 1 19 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.750000 - 1
+Region.size: 20
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 3.669230 - 1
+Region.size: 23
+LeftChild.size: 10
+LeftChild.ClassCounts: 1 9 
+RightChild.size: 13
+RightChild.ClassCounts: 9 4 
+
+minGini: 2.222222 - 1
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 9
+RightChild.ClassCounts: 5 4 
+
+minGini: 0.800000 - 1
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 12.179089 - 1
+Region.size: 67
+LeftChild.size: 46
+LeftChild.ClassCounts: 35 11 
+RightChild.size: 21
+RightChild.ClassCounts: 5 16 
+
+minGini: 0.833333 - 5
+Region.size: 21
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 
+
+minGini: 0.000000 - 3
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 7.565922 - 0
+Region.size: 46
+LeftChild.size: 29
+LeftChild.ClassCounts: 25 4 
+RightChild.size: 17
+RightChild.ClassCounts: 10 7 
+
+minGini: 3.050000 - 2
+Region.size: 17
+LeftChild.size: 12
+LeftChild.ClassCounts: 9 3 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.500000 - 5
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.750000 - 2
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 2.678571 - 1
+Region.size: 29
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 28
+RightChild.ClassCounts: 25 3 
+
+minGini: 1.851851 - 3
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 25 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.428571 - 4
+Region.size: 27
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 55.467857 - 2
+Region.size: 288
+LeftChild.size: 8
+LeftChild.ClassCounts: 2 6 
+RightChild.size: 280
+RightChild.ClassCounts: 207 73 
+
+minGini: 50.746212 - 1
+Region.size: 280
+LeftChild.size: 88
+LeftChild.ClassCounts: 79 9 
+RightChild.size: 192
+RightChild.ClassCounts: 128 64 
+
+minGini: 38.798593 - 5
+Region.size: 192
+LeftChild.size: 181
+LeftChild.ClassCounts: 127 54 
+RightChild.size: 11
+RightChild.ClassCounts: 1 10 
+
+minGini: 0.500000 - 0
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 36.757912 - 1
+Region.size: 181
+LeftChild.size: 14
+LeftChild.ClassCounts: 6 8 
+RightChild.size: 167
+RightChild.ClassCounts: 121 46 
+
+minGini: 30.053549 - 7
+Region.size: 167
+LeftChild.size: 103
+LeftChild.ClassCounts: 86 17 
+RightChild.size: 64
+RightChild.ClassCounts: 35 29 
+
+minGini: 14.067460 - 2
+Region.size: 64
+LeftChild.size: 28
+LeftChild.ClassCounts: 10 18 
+RightChild.size: 36
+RightChild.ClassCounts: 25 11 
+
+minGini: 5.484615 - 6
+Region.size: 36
+LeftChild.size: 26
+LeftChild.ClassCounts: 22 4 
+RightChild.size: 10
+RightChild.ClassCounts: 3 7 
+
+minGini: 1.714285 - 0
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.800000 - 7
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 2.545454 - 5
+Region.size: 26
+LeftChild.size: 11
+LeftChild.ClassCounts: 7 4 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 
+
+minGini: 0.800000 - 1
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.854166 - 0
+Region.size: 28
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 11 
+RightChild.size: 16
+RightChild.ClassCounts: 9 7 
+
+minGini: 1.636363 - 6
+Region.size: 16
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.900000 - 5
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 10
+RightChild.ClassCounts: 9 1 
+
+minGini: 0.666666 - 0
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.800000 - 6
+Region.size: 12
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 13.200000 - 3
+Region.size: 103
+LeftChild.size: 98
+LeftChild.ClassCounts: 84 14 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 10.888888 - 6
+Region.size: 98
+LeftChild.size: 63
+LeftChild.ClassCounts: 59 4 
+RightChild.size: 35
+RightChild.ClassCounts: 25 10 
+
+minGini: 5.949074 - 6
+Region.size: 35
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 27
+RightChild.ClassCounts: 22 5 
+
+minGini: 2.640000 - 7
+Region.size: 27
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 25
+RightChild.ClassCounts: 22 3 
+
+minGini: 1.621212 - 6
+Region.size: 25
+LeftChild.size: 22
+LeftChild.ClassCounts: 21 1 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.750000 - 4
+Region.size: 22
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.750000 - 3
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.696428 - 6
+Region.size: 63
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 
+RightChild.size: 56
+RightChild.ClassCounts: 55 1 
+
+minGini: 0.500000 - 7
+Region.size: 56
+LeftChild.size: 54
+LeftChild.ClassCounts: 54 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 2.400000 - 1
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 6 4 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.500000 - 2
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 5.675000 - 6
+Region.size: 88
+LeftChild.size: 80
+LeftChild.ClassCounts: 76 4 
+RightChild.size: 8
+RightChild.ClassCounts: 3 5 
+
+minGini: 0.750000 - 6
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.947368 - 3
+Region.size: 80
+LeftChild.size: 76
+LeftChild.ClassCounts: 74 2 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.882352 - 6
+Region.size: 76
+LeftChild.size: 34
+LeftChild.ClassCounts: 32 2 
+RightChild.size: 42
+RightChild.ClassCounts: 42 0 
+
+minGini: 0.969696 - 2
+Region.size: 34
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 33
+RightChild.ClassCounts: 32 1 
+
+minGini: 0.857142 - 3
+Region.size: 33
+LeftChild.size: 26
+LeftChild.ClassCounts: 26 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.857142 - 6
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 5
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 33.474137 - 0
+Region.size: 310
+LeftChild.size: 252
+LeftChild.ClassCounts: 231 21 
+RightChild.size: 58
+RightChild.ClassCounts: 33 25 
+
+minGini: 10.519368 - 5
+Region.size: 58
+LeftChild.size: 41
+LeftChild.ClassCounts: 30 11 
+RightChild.size: 17
+RightChild.ClassCounts: 3 14 
+
+minGini: 1.750000 - 7
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 2 14 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.200000 - 0
+Region.size: 16
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 0.750000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 3.529411 - 1
+Region.size: 41
+LeftChild.size: 34
+LeftChild.ClassCounts: 30 4 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.800000 - 2
+Region.size: 34
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 29
+RightChild.ClassCounts: 29 0 
+
+minGini: 0.500000 - 0
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 16.618447 - 7
+Region.size: 252
+LeftChild.size: 226
+LeftChild.ClassCounts: 215 11 
+RightChild.size: 26
+RightChild.ClassCounts: 16 10 
+
+minGini: 2.526315 - 3
+Region.size: 26
+LeftChild.size: 19
+LeftChild.ClassCounts: 16 3 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 1.714285 - 2
+Region.size: 19
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 
+
+minGini: 0.750000 - 7
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 9.626010 - 1
+Region.size: 226
+LeftChild.size: 212
+LeftChild.ClassCounts: 205 7 
+RightChild.size: 14
+RightChild.ClassCounts: 10 4 
+
+minGini: 1.714285 - 5
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 7
+RightChild.ClassCounts: 3 4 
+
+minGini: 0.000000 - 3
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 6.171448 - 6
+Region.size: 212
+LeftChild.size: 181
+LeftChild.ClassCounts: 179 2 
+RightChild.size: 31
+RightChild.ClassCounts: 26 5 
+
+minGini: 3.495454 - 3
+Region.size: 31
+LeftChild.size: 11
+LeftChild.ClassCounts: 7 4 
+RightChild.size: 20
+RightChild.ClassCounts: 19 1 
+
+minGini: 0.000000 - 0
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.333333 - 0
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.916666 - 5
+Region.size: 181
+LeftChild.size: 133
+LeftChild.ClassCounts: 133 0 
+RightChild.size: 48
+RightChild.ClassCounts: 46 2 
+
+minGini: 1.692307 - 1
+Region.size: 48
+LeftChild.size: 35
+LeftChild.ClassCounts: 35 0 
+RightChild.size: 13
+RightChild.ClassCounts: 11 2 
+
+minGini: 1.333333 - 4
+Region.size: 13
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.800000 - 0
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 11 finished.
+
+minGini: 155.584338 - 5
+Region.size: 768
+LeftChild.size: 190
+LeftChild.ClassCounts: 176 14 
+RightChild.size: 578
+RightChild.ClassCounts: 322 256 
+
+minGini: 112.786760 - 1
+Region.size: 578
+LeftChild.size: 338
+LeftChild.ClassCounts: 253 85 
+RightChild.size: 240
+RightChild.ClassCounts: 69 171 
+
+minGini: 45.487175 - 5
+Region.size: 240
+LeftChild.size: 133
+LeftChild.ClassCounts: 53 80 
+RightChild.size: 107
+RightChild.ClassCounts: 16 91 
+
+minGini: 12.109223 - 7
+Region.size: 107
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 103
+RightChild.ClassCounts: 13 90 
+
+minGini: 10.677626 - 1
+Region.size: 103
+LeftChild.size: 54
+LeftChild.ClassCounts: 11 43 
+RightChild.size: 49
+RightChild.ClassCounts: 2 47 
+
+minGini: 0.000000 - 4
+Region.size: 49
+LeftChild.size: 47
+LeftChild.ClassCounts: 0 47 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 8.113207 - 4
+Region.size: 54
+LeftChild.size: 53
+LeftChild.ClassCounts: 10 43 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 7.179166 - 7
+Region.size: 53
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 48
+RightChild.ClassCounts: 7 41 
+
+minGini: 4.805555 - 3
+Region.size: 48
+LeftChild.size: 12
+LeftChild.ClassCounts: 5 7 
+RightChild.size: 36
+RightChild.ClassCounts: 2 34 
+
+minGini: 1.470588 - 0
+Region.size: 36
+LeftChild.size: 34
+LeftChild.ClassCounts: 1 33 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.800000 - 2
+Region.size: 34
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 29
+RightChild.ClassCounts: 0 29 
+
+minGini: 0.500000 - 2
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.428571 - 2
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.833333 - 2
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 29.054852 - 7
+Region.size: 133
+LeftChild.size: 79
+LeftChild.ClassCounts: 41 38 
+RightChild.size: 54
+RightChild.ClassCounts: 12 42 
+
+minGini: 8.307692 - 3
+Region.size: 54
+LeftChild.size: 39
+LeftChild.ClassCounts: 12 27 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 
+
+minGini: 5.558823 - 3
+Region.size: 39
+LeftChild.size: 34
+LeftChild.ClassCounts: 7 27 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 4.216666 - 7
+Region.size: 34
+LeftChild.size: 30
+LeftChild.ClassCounts: 4 26 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 3.129186 - 7
+Region.size: 30
+LeftChild.size: 19
+LeftChild.ClassCounts: 1 18 
+RightChild.size: 11
+RightChild.ClassCounts: 3 8 
+
+minGini: 1.600000 - 2
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 2 8 
+
+minGini: 0.888888 - 0
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 1
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 0.000000 - 1
+Region.size: 19
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 18
+RightChild.ClassCounts: 0 18 
+
+minGini: 13.899259 - 1
+Region.size: 79
+LeftChild.size: 54
+LeftChild.ClassCounts: 38 16 
+RightChild.size: 25
+RightChild.ClassCounts: 3 22 
+
+minGini: 1.714285 - 7
+Region.size: 25
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 
+RightChild.size: 7
+RightChild.ClassCounts: 3 4 
+
+minGini: 0.800000 - 3
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 10.092307 - 1
+Region.size: 54
+LeftChild.size: 15
+LeftChild.ClassCounts: 7 8 
+RightChild.size: 39
+RightChild.ClassCounts: 31 8 
+
+minGini: 4.444444 - 7
+Region.size: 39
+LeftChild.size: 18
+LeftChild.ClassCounts: 10 8 
+RightChild.size: 21
+RightChild.ClassCounts: 21 0 
+
+minGini: 3.083333 - 2
+Region.size: 18
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 12
+RightChild.ClassCounts: 9 3 
+
+minGini: 0.750000 - 3
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 7
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.888888 - 4
+Region.size: 15
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.750000 - 6
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.500000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 54.176408 - 7
+Region.size: 338
+LeftChild.size: 164
+LeftChild.ClassCounts: 151 13 
+RightChild.size: 174
+RightChild.ClassCounts: 102 72 
+
+minGini: 38.663847 - 0
+Region.size: 174
+LeftChild.size: 88
+LeftChild.ClassCounts: 64 24 
+RightChild.size: 86
+RightChild.ClassCounts: 38 48 
+
+minGini: 19.714285 - 5
+Region.size: 86
+LeftChild.size: 72
+LeftChild.ClassCounts: 36 36 
+RightChild.size: 14
+RightChild.ClassCounts: 2 12 
+
+minGini: 1.428571 - 2
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 5 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 15.107142 - 5
+Region.size: 72
+LeftChild.size: 56
+LeftChild.ClassCounts: 22 34 
+RightChild.size: 16
+RightChild.ClassCounts: 14 2 
+
+minGini: 0.933333 - 0
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 14 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 7.727272 - 1
+Region.size: 56
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 44
+RightChild.ClassCounts: 10 34 
+
+minGini: 5.100000 - 2
+Region.size: 44
+LeftChild.size: 40
+LeftChild.ClassCounts: 6 34 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 3.428571 - 3
+Region.size: 40
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 26 
+RightChild.size: 14
+RightChild.ClassCounts: 6 8 
+
+minGini: 2.400000 - 7
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 6 4 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.857142 - 5
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 7
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 12.508634 - 1
+Region.size: 88
+LeftChild.size: 49
+LeftChild.ClassCounts: 46 3 
+RightChild.size: 39
+RightChild.ClassCounts: 18 21 
+
+minGini: 8.181818 - 4
+Region.size: 39
+LeftChild.size: 33
+LeftChild.ClassCounts: 18 15 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 6.000000 - 2
+Region.size: 33
+LeftChild.size: 22
+LeftChild.ClassCounts: 8 14 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.750000 - 4
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 3.111111 - 6
+Region.size: 22
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 18
+RightChild.ClassCounts: 4 14 
+
+minGini: 2.222222 - 2
+Region.size: 18
+LeftChild.size: 9
+LeftChild.ClassCounts: 4 5 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.000000 - 6
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 2.608695 - 5
+Region.size: 49
+LeftChild.size: 26
+LeftChild.ClassCounts: 26 0 
+RightChild.size: 23
+RightChild.ClassCounts: 20 3 
+
+minGini: 2.274509 - 7
+Region.size: 23
+LeftChild.size: 17
+LeftChild.ClassCounts: 16 1 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.666666 - 6
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 1
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 10.125000 - 5
+Region.size: 164
+LeftChild.size: 160
+LeftChild.ClassCounts: 150 10 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 8.490566 - 0
+Region.size: 160
+LeftChild.size: 159
+LeftChild.ClassCounts: 150 9 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 8.129032 - 5
+Region.size: 159
+LeftChild.size: 66
+LeftChild.ClassCounts: 66 0 
+RightChild.size: 93
+RightChild.ClassCounts: 84 9 
+
+minGini: 7.808823 - 4
+Region.size: 93
+LeftChild.size: 25
+LeftChild.ClassCounts: 25 0 
+RightChild.size: 68
+RightChild.ClassCounts: 59 9 
+
+minGini: 7.441176 - 1
+Region.size: 68
+LeftChild.size: 34
+LeftChild.ClassCounts: 27 7 
+RightChild.size: 34
+RightChild.ClassCounts: 32 2 
+
+minGini: 0.666666 - 5
+Region.size: 34
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 31
+RightChild.ClassCounts: 31 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.700000 - 1
+Region.size: 34
+LeftChild.size: 30
+LeftChild.ClassCounts: 27 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.629629 - 5
+Region.size: 30
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 27
+RightChild.ClassCounts: 26 1 
+
+minGini: 0.900000 - 6
+Region.size: 27
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 17
+RightChild.ClassCounts: 17 0 
+
+minGini: 0.000000 - 4
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 8.457142 - 1
+Region.size: 190
+LeftChild.size: 175
+LeftChild.ClassCounts: 170 5 
+RightChild.size: 15
+RightChild.ClassCounts: 6 9 
+
+minGini: 1.636363 - 7
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 2 9 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 7
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 4.731182 - 1
+Region.size: 175
+LeftChild.size: 82
+LeftChild.ClassCounts: 82 0 
+RightChild.size: 93
+RightChild.ClassCounts: 88 5 
+
+minGini: 4.488888 - 1
+Region.size: 93
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 90
+RightChild.ClassCounts: 86 4 
+
+minGini: 3.542857 - 0
+Region.size: 90
+LeftChild.size: 55
+LeftChild.ClassCounts: 55 0 
+RightChild.size: 35
+RightChild.ClassCounts: 31 4 
+
+minGini: 3.206521 - 5
+Region.size: 35
+LeftChild.size: 12
+LeftChild.ClassCounts: 9 3 
+RightChild.size: 23
+RightChild.ClassCounts: 22 1 
+
+minGini: 0.500000 - 2
+Region.size: 23
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 21
+RightChild.ClassCounts: 21 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.900000 - 5
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 12 finished.
+
+minGini: 156.636184 - 7
+Region.size: 768
+LeftChild.size: 391
+LeftChild.ClassCounts: 313 78 
+RightChild.size: 377
+RightChild.ClassCounts: 184 193 
+
+minGini: 83.052231 - 1
+Region.size: 377
+LeftChild.size: 101
+LeftChild.ClassCounts: 78 23 
+RightChild.size: 276
+RightChild.ClassCounts: 106 170 
+
+minGini: 61.567251 - 0
+Region.size: 276
+LeftChild.size: 162
+LeftChild.ClassCounts: 78 84 
+RightChild.size: 114
+RightChild.ClassCounts: 28 86 
+
+minGini: 18.146788 - 7
+Region.size: 114
+LeftChild.size: 109
+LeftChild.ClassCounts: 23 86 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 16.015277 - 6
+Region.size: 109
+LeftChild.size: 45
+LeftChild.ClassCounts: 17 28 
+RightChild.size: 64
+RightChild.ClassCounts: 6 58 
+
+minGini: 4.603174 - 7
+Region.size: 64
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 63
+RightChild.ClassCounts: 5 58 
+
+minGini: 3.802272 - 5
+Region.size: 63
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 55
+RightChild.ClassCounts: 2 53 
+
+minGini: 1.692307 - 7
+Region.size: 55
+LeftChild.size: 13
+LeftChild.ClassCounts: 2 11 
+RightChild.size: 42
+RightChild.ClassCounts: 0 42 
+
+minGini: 0.666666 - 3
+Region.size: 13
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 9.060344 - 7
+Region.size: 45
+LeftChild.size: 29
+LeftChild.ClassCounts: 7 22 
+RightChild.size: 16
+RightChild.ClassCounts: 10 6 
+
+minGini: 2.857142 - 5
+Region.size: 16
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 14
+RightChild.ClassCounts: 10 4 
+
+minGini: 0.909090 - 6
+Region.size: 14
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.500000 - 3
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.110000 - 5
+Region.size: 29
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 25
+RightChild.ClassCounts: 4 21 
+
+minGini: 2.484848 - 2
+Region.size: 25
+LeftChild.size: 22
+LeftChild.ClassCounts: 2 20 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.555555 - 7
+Region.size: 22
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 7 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.875000 - 3
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 4
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 35.411199 - 5
+Region.size: 162
+LeftChild.size: 26
+LeftChild.ClassCounts: 23 3 
+RightChild.size: 136
+RightChild.ClassCounts: 55 81 
+
+minGini: 30.076103 - 6
+Region.size: 136
+LeftChild.size: 63
+LeftChild.ClassCounts: 35 28 
+RightChild.size: 73
+RightChild.ClassCounts: 20 53 
+
+minGini: 12.913533 - 0
+Region.size: 73
+LeftChild.size: 38
+LeftChild.ClassCounts: 5 33 
+RightChild.size: 35
+RightChild.ClassCounts: 15 20 
+
+minGini: 6.964285 - 2
+Region.size: 35
+LeftChild.size: 28
+LeftChild.ClassCounts: 9 19 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.666666 - 7
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 4.916666 - 2
+Region.size: 28
+LeftChild.size: 16
+LeftChild.ClassCounts: 8 8 
+RightChild.size: 12
+RightChild.ClassCounts: 1 11 
+
+minGini: 0.000000 - 4
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.076923 - 3
+Region.size: 16
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 13
+RightChild.ClassCounts: 5 8 
+
+minGini: 2.181818 - 2
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 3 8 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.541666 - 4
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.500000 - 2
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.375000 - 1
+Region.size: 38
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 
+RightChild.size: 32
+RightChild.ClassCounts: 2 30 
+
+minGini: 1.666666 - 2
+Region.size: 32
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 20 
+RightChild.size: 12
+RightChild.ClassCounts: 2 10 
+
+minGini: 0.000000 - 2
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.750000 - 6
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 12.755555 - 6
+Region.size: 63
+LeftChild.size: 45
+LeftChild.ClassCounts: 19 26 
+RightChild.size: 18
+RightChild.ClassCounts: 16 2 
+
+minGini: 0.000000 - 4
+Region.size: 18
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 8.695187 - 7
+Region.size: 45
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 34
+RightChild.ClassCounts: 10 24 
+
+minGini: 6.000000 - 7
+Region.size: 34
+LeftChild.size: 32
+LeftChild.ClassCounts: 8 24 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 5.419354 - 3
+Region.size: 32
+LeftChild.size: 31
+LeftChild.ClassCounts: 7 24 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.421052 - 1
+Region.size: 31
+LeftChild.size: 19
+LeftChild.ClassCounts: 7 12 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 
+
+minGini: 3.529411 - 6
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 17
+RightChild.ClassCounts: 5 12 
+
+minGini: 2.400000 - 1
+Region.size: 17
+LeftChild.size: 15
+LeftChild.ClassCounts: 3 12 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.200000 - 1
+Region.size: 15
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 2
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 1
+Region.size: 26
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 16.545454 - 1
+Region.size: 101
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 99
+RightChild.ClassCounts: 78 21 
+
+minGini: 15.607142 - 6
+Region.size: 99
+LeftChild.size: 36
+LeftChild.ClassCounts: 33 3 
+RightChild.size: 63
+RightChild.ClassCounts: 45 18 
+
+minGini: 8.181818 - 6
+Region.size: 63
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 55
+RightChild.ClassCounts: 45 10 
+
+minGini: 6.016483 - 5
+Region.size: 55
+LeftChild.size: 42
+LeftChild.ClassCounts: 39 3 
+RightChild.size: 13
+RightChild.ClassCounts: 6 7 
+
+minGini: 2.100000 - 6
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 10
+RightChild.ClassCounts: 3 7 
+
+minGini: 0.750000 - 6
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.500000 - 3
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.625000 - 5
+Region.size: 42
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 
+RightChild.size: 24
+RightChild.ClassCounts: 21 3 
+
+minGini: 1.826086 - 6
+Region.size: 24
+LeftChild.size: 23
+LeftChild.ClassCounts: 21 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.954545 - 7
+Region.size: 23
+LeftChild.size: 22
+LeftChild.ClassCounts: 21 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.857142 - 1
+Region.size: 22
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.500000 - 3
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.400000 - 3
+Region.size: 36
+LeftChild.size: 15
+LeftChild.ClassCounts: 12 3 
+RightChild.size: 21
+RightChild.ClassCounts: 21 0 
+
+minGini: 1.714285 - 5
+Region.size: 15
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 7
+RightChild.ClassCounts: 4 3 
+
+minGini: 0.000000 - 7
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 44.346923 - 1
+Region.size: 391
+LeftChild.size: 354
+LeftChild.ClassCounts: 308 46 
+RightChild.size: 37
+RightChild.ClassCounts: 5 32 
+
+minGini: 2.628787 - 2
+Region.size: 37
+LeftChild.size: 33
+LeftChild.ClassCounts: 2 31 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.968750 - 5
+Region.size: 33
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 32
+RightChild.ClassCounts: 1 31 
+
+minGini: 0.888888 - 3
+Region.size: 32
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 23 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 
+
+minGini: 0.666666 - 3
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 38.276534 - 3
+Region.size: 354
+LeftChild.size: 249
+LeftChild.ClassCounts: 228 21 
+RightChild.size: 105
+RightChild.ClassCounts: 80 25 
+
+minGini: 17.886847 - 5
+Region.size: 105
+LeftChild.size: 94
+LeftChild.ClassCounts: 75 19 
+RightChild.size: 11
+RightChild.ClassCounts: 5 6 
+
+minGini: 0.833333 - 1
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 13.637037 - 6
+Region.size: 94
+LeftChild.size: 54
+LeftChild.ClassCounts: 49 5 
+RightChild.size: 40
+RightChild.ClassCounts: 26 14 
+
+minGini: 7.222222 - 0
+Region.size: 40
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 36
+RightChild.ClassCounts: 26 10 
+
+minGini: 6.133333 - 1
+Region.size: 36
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 30
+RightChild.ClassCounts: 24 6 
+
+minGini: 4.074074 - 6
+Region.size: 30
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 27
+RightChild.ClassCounts: 23 4 
+
+minGini: 2.933333 - 3
+Region.size: 27
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 15
+RightChild.ClassCounts: 11 4 
+
+minGini: 0.916666 - 5
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 12
+RightChild.ClassCounts: 11 1 
+
+minGini: 0.800000 - 7
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 3.377272 - 5
+Region.size: 54
+LeftChild.size: 10
+LeftChild.ClassCounts: 6 4 
+RightChild.size: 44
+RightChild.ClassCounts: 43 1 
+
+minGini: 0.941176 - 0
+Region.size: 44
+LeftChild.size: 17
+LeftChild.ClassCounts: 16 1 
+RightChild.size: 27
+RightChild.ClassCounts: 27 0 
+
+minGini: 0.666666 - 4
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.800000 - 0
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 15.490627 - 1
+Region.size: 249
+LeftChild.size: 221
+LeftChild.ClassCounts: 212 9 
+RightChild.size: 28
+RightChild.ClassCounts: 16 12 
+
+minGini: 4.791443 - 3
+Region.size: 28
+LeftChild.size: 17
+LeftChild.ClassCounts: 6 11 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.500000 - 7
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.916666 - 1
+Region.size: 17
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 11 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 2
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 7.709090 - 0
+Region.size: 221
+LeftChild.size: 220
+LeftChild.ClassCounts: 212 8 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 7.165109 - 5
+Region.size: 220
+LeftChild.size: 214
+LeftChild.ClassCounts: 208 6 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 5.576839 - 5
+Region.size: 214
+LeftChild.size: 154
+LeftChild.ClassCounts: 153 1 
+RightChild.size: 60
+RightChild.ClassCounts: 55 5 
+
+minGini: 3.728813 - 6
+Region.size: 60
+LeftChild.size: 59
+LeftChild.ClassCounts: 55 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.980000 - 2
+Region.size: 59
+LeftChild.size: 50
+LeftChild.ClassCounts: 49 1 
+RightChild.size: 9
+RightChild.ClassCounts: 6 3 
+
+minGini: 1.500000 - 0
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.500000 - 5
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.947368 - 3
+Region.size: 50
+LeftChild.size: 19
+LeftChild.ClassCounts: 18 1 
+RightChild.size: 31
+RightChild.ClassCounts: 31 0 
+
+minGini: 0.500000 - 2
+Region.size: 19
+LeftChild.size: 17
+LeftChild.ClassCounts: 17 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.977777 - 5
+Region.size: 154
+LeftChild.size: 45
+LeftChild.ClassCounts: 44 1 
+RightChild.size: 109
+RightChild.ClassCounts: 109 0 
+
+minGini: 0.750000 - 6
+Region.size: 45
+LeftChild.size: 41
+LeftChild.ClassCounts: 41 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+
+
+Tree Number: 13 finished.
+
+minGini: 154.864761 - 5
+Region.size: 768
+LeftChild.size: 168
+LeftChild.ClassCounts: 157 11 
+RightChild.size: 600
+RightChild.ClassCounts: 357 243 
+
+minGini: 137.469592 - 3
+Region.size: 600
+LeftChild.size: 165
+LeftChild.ClassCounts: 69 96 
+RightChild.size: 435
+RightChild.ClassCounts: 288 147 
+
+minGini: 89.097273 - 0
+Region.size: 435
+LeftChild.size: 351
+LeftChild.ClassCounts: 256 95 
+RightChild.size: 84
+RightChild.ClassCounts: 32 52 
+
+minGini: 14.444444 - 1
+Region.size: 84
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 72
+RightChild.ClassCounts: 20 52 
+
+minGini: 10.607692 - 6
+Region.size: 72
+LeftChild.size: 20
+LeftChild.ClassCounts: 13 7 
+RightChild.size: 52
+RightChild.ClassCounts: 7 45 
+
+minGini: 5.511363 - 1
+Region.size: 52
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 44
+RightChild.ClassCounts: 4 40 
+
+minGini: 2.971428 - 3
+Region.size: 44
+LeftChild.size: 35
+LeftChild.ClassCounts: 1 34 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 0.750000 - 1
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 0
+Region.size: 35
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 33 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 3.058823 - 5
+Region.size: 20
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 17
+RightChild.ClassCounts: 13 4 
+
+minGini: 1.673076 - 4
+Region.size: 17
+LeftChild.size: 13
+LeftChild.ClassCounts: 12 1 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 0
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 47.680213 - 1
+Region.size: 351
+LeftChild.size: 236
+LeftChild.ClassCounts: 213 23 
+RightChild.size: 115
+RightChild.ClassCounts: 43 72 
+
+minGini: 24.705882 - 2
+Region.size: 115
+LeftChild.size: 64
+LeftChild.ClassCounts: 16 48 
+RightChild.size: 51
+RightChild.ClassCounts: 27 24 
+
+minGini: 10.431818 - 1
+Region.size: 51
+LeftChild.size: 44
+LeftChild.ClassCounts: 27 17 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 8.105747 - 1
+Region.size: 44
+LeftChild.size: 29
+LeftChild.ClassCounts: 13 16 
+RightChild.size: 15
+RightChild.ClassCounts: 14 1 
+
+minGini: 0.857142 - 6
+Region.size: 15
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.000000 - 4
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 4.550000 - 2
+Region.size: 29
+LeftChild.size: 20
+LeftChild.ClassCounts: 13 7 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 3.230769 - 6
+Region.size: 20
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 13
+RightChild.ClassCounts: 6 7 
+
+minGini: 0.875000 - 7
+Region.size: 13
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 10.148571 - 0
+Region.size: 64
+LeftChild.size: 50
+LeftChild.ClassCounts: 8 42 
+RightChild.size: 14
+RightChild.ClassCounts: 8 6 
+
+minGini: 2.000000 - 4
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 1.200000 - 5
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 5.250000 - 3
+Region.size: 50
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 48
+RightChild.ClassCounts: 6 42 
+
+minGini: 4.311111 - 6
+Region.size: 48
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 45
+RightChild.ClassCounts: 4 41 
+
+minGini: 3.434873 - 5
+Region.size: 45
+LeftChild.size: 28
+LeftChild.ClassCounts: 1 27 
+RightChild.size: 17
+RightChild.ClassCounts: 3 14 
+
+minGini: 0.000000 - 4
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.500000 - 7
+Region.size: 28
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 20.046511 - 4
+Region.size: 236
+LeftChild.size: 172
+LeftChild.ClassCounts: 161 11 
+RightChild.size: 64
+RightChild.ClassCounts: 52 12 
+
+minGini: 8.000000 - 6
+Region.size: 64
+LeftChild.size: 50
+LeftChild.ClassCounts: 45 5 
+RightChild.size: 14
+RightChild.ClassCounts: 7 7 
+
+minGini: 0.875000 - 4
+Region.size: 14
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.500000 - 4
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 4.107142 - 4
+Region.size: 50
+LeftChild.size: 28
+LeftChild.ClassCounts: 23 5 
+RightChild.size: 22
+RightChild.ClassCounts: 22 0 
+
+minGini: 3.407407 - 5
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 23 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 3.000000 - 1
+Region.size: 27
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 16
+RightChild.ClassCounts: 12 4 
+
+minGini: 0.923076 - 7
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 12 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.666666 - 3
+Region.size: 13
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 8.523529 - 7
+Region.size: 172
+LeftChild.size: 170
+LeftChild.ClassCounts: 161 9 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 7.621301 - 5
+Region.size: 170
+LeftChild.size: 169
+LeftChild.ClassCounts: 161 8 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 6.879679 - 6
+Region.size: 169
+LeftChild.size: 136
+LeftChild.ClassCounts: 134 2 
+RightChild.size: 33
+RightChild.ClassCounts: 27 6 
+
+minGini: 2.700000 - 6
+Region.size: 33
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 30
+RightChild.ClassCounts: 27 3 
+
+minGini: 2.400000 - 7
+Region.size: 30
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 
+RightChild.size: 15
+RightChild.ClassCounts: 12 3 
+
+minGini: 1.583333 - 4
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 12
+RightChild.ClassCounts: 11 1 
+
+minGini: 0.666666 - 5
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.777777 - 7
+Region.size: 136
+LeftChild.size: 118
+LeftChild.ClassCounts: 118 0 
+RightChild.size: 18
+RightChild.ClassCounts: 16 2 
+
+minGini: 1.200000 - 3
+Region.size: 18
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 37.635912 - 5
+Region.size: 165
+LeftChild.size: 144
+LeftChild.ClassCounts: 67 77 
+RightChild.size: 21
+RightChild.ClassCounts: 2 19 
+
+minGini: 0.950000 - 6
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 1 19 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.888888 - 5
+Region.size: 20
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 0.000000 - 5
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 33.404411 - 5
+Region.size: 144
+LeftChild.size: 136
+LeftChild.ClassCounts: 59 77 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 31.591666 - 0
+Region.size: 136
+LeftChild.size: 120
+LeftChild.ClassCounts: 47 73 
+RightChild.size: 16
+RightChild.ClassCounts: 12 4 
+
+minGini: 2.109090 - 0
+Region.size: 16
+LeftChild.size: 11
+LeftChild.ClassCounts: 10 1 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.666666 - 7
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 26.739968 - 6
+Region.size: 120
+LeftChild.size: 101
+LeftChild.ClassCounts: 45 56 
+RightChild.size: 19
+RightChild.ClassCounts: 2 17 
+
+minGini: 1.428571 - 6
+Region.size: 19
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 22.707905 - 7
+Region.size: 101
+LeftChild.size: 55
+LeftChild.ClassCounts: 32 23 
+RightChild.size: 46
+RightChild.ClassCounts: 13 33 
+
+minGini: 8.250000 - 5
+Region.size: 46
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 44
+RightChild.ClassCounts: 11 33 
+
+minGini: 4.342105 - 1
+Region.size: 44
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 38
+RightChild.ClassCounts: 5 33 
+
+minGini: 2.632352 - 7
+Region.size: 38
+LeftChild.size: 34
+LeftChild.ClassCounts: 2 32 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.764705 - 5
+Region.size: 34
+LeftChild.size: 17
+LeftChild.ClassCounts: 2 15 
+RightChild.size: 17
+RightChild.ClassCounts: 0 17 
+
+minGini: 0.000000 - 2
+Region.size: 17
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 10.736434 - 0
+Region.size: 55
+LeftChild.size: 12
+LeftChild.ClassCounts: 2 10 
+RightChild.size: 43
+RightChild.ClassCounts: 30 13 
+
+minGini: 8.552631 - 0
+Region.size: 43
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 38
+RightChild.ClassCounts: 25 13 
+
+minGini: 7.878787 - 5
+Region.size: 38
+LeftChild.size: 33
+LeftChild.ClassCounts: 20 13 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 6.826923 - 5
+Region.size: 33
+LeftChild.size: 20
+LeftChild.ClassCounts: 15 5 
+RightChild.size: 13
+RightChild.ClassCounts: 5 8 
+
+minGini: 0.833333 - 6
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 3.300000 - 1
+Region.size: 20
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 10
+RightChild.ClassCounts: 6 4 
+
+minGini: 1.583333 - 1
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.500000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 1
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 9.271428 - 0
+Region.size: 168
+LeftChild.size: 98
+LeftChild.ClassCounts: 98 0 
+RightChild.size: 70
+RightChild.ClassCounts: 59 11 
+
+minGini: 4.609375 - 1
+Region.size: 70
+LeftChild.size: 64
+LeftChild.ClassCounts: 59 5 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 3.647435 - 6
+Region.size: 64
+LeftChild.size: 52
+LeftChild.ClassCounts: 51 1 
+RightChild.size: 12
+RightChild.ClassCounts: 8 4 
+
+minGini: 0.800000 - 0
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.956521 - 2
+Region.size: 52
+LeftChild.size: 29
+LeftChild.ClassCounts: 29 0 
+RightChild.size: 23
+RightChild.ClassCounts: 22 1 
+
+minGini: 0.750000 - 7
+Region.size: 23
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+
+
+Tree Number: 14 finished.
+
+minGini: 134.921635 - 1
+Region.size: 768
+LeftChild.size: 571
+LeftChild.ClassCounts: 455 116 
+RightChild.size: 197
+RightChild.ClassCounts: 62 135 
+
+minGini: 37.706896 - 5
+Region.size: 197
+LeftChild.size: 29
+LeftChild.ClassCounts: 20 9 
+RightChild.size: 168
+RightChild.ClassCounts: 42 126 
+
+minGini: 29.597492 - 0
+Region.size: 168
+LeftChild.size: 110
+LeftChild.ClassCounts: 36 74 
+RightChild.size: 58
+RightChild.ClassCounts: 6 52 
+
+minGini: 4.537815 - 0
+Region.size: 58
+LeftChild.size: 51
+LeftChild.ClassCounts: 3 48 
+RightChild.size: 7
+RightChild.ClassCounts: 3 4 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 2.470588 - 2
+Region.size: 51
+LeftChild.size: 17
+LeftChild.ClassCounts: 3 14 
+RightChild.size: 34
+RightChild.ClassCounts: 0 34 
+
+minGini: 1.595238 - 1
+Region.size: 17
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 14
+RightChild.ClassCounts: 1 13 
+
+minGini: 0.500000 - 0
+Region.size: 14
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 20.560224 - 1
+Region.size: 110
+LeftChild.size: 68
+LeftChild.ClassCounts: 32 36 
+RightChild.size: 42
+RightChild.ClassCounts: 4 38 
+
+minGini: 3.304347 - 4
+Region.size: 42
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 19 
+RightChild.size: 23
+RightChild.ClassCounts: 4 19 
+
+minGini: 1.809523 - 5
+Region.size: 23
+LeftChild.size: 21
+LeftChild.ClassCounts: 2 19 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 4
+Region.size: 21
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 19 
+
+minGini: 14.400000 - 1
+Region.size: 68
+LeftChild.size: 60
+LeftChild.ClassCounts: 24 36 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 12.436363 - 0
+Region.size: 60
+LeftChild.size: 55
+LeftChild.ClassCounts: 19 36 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 10.795454 - 2
+Region.size: 55
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 44
+RightChild.ClassCounts: 19 25 
+
+minGini: 9.370588 - 7
+Region.size: 44
+LeftChild.size: 34
+LeftChild.ClassCounts: 18 16 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 7.200000 - 2
+Region.size: 34
+LeftChild.size: 30
+LeftChild.ClassCounts: 18 12 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 2.633484 - 1
+Region.size: 30
+LeftChild.size: 17
+LeftChild.ClassCounts: 16 1 
+RightChild.size: 13
+RightChild.ClassCounts: 2 11 
+
+minGini: 0.000000 - 4
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.800000 - 3
+Region.size: 17
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 
+
+minGini: 0.500000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 5.151960 - 1
+Region.size: 29
+LeftChild.size: 12
+LeftChild.ClassCounts: 11 1 
+RightChild.size: 17
+RightChild.ClassCounts: 9 8 
+
+minGini: 3.214285 - 1
+Region.size: 17
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 14
+RightChild.ClassCounts: 9 5 
+
+minGini: 2.250000 - 2
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 12
+RightChild.ClassCounts: 9 3 
+
+minGini: 1.555555 - 4
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 8 1 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.750000 - 3
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 87.328398 - 7
+Region.size: 571
+LeftChild.size: 250
+LeftChild.ClassCounts: 226 24 
+RightChild.size: 321
+RightChild.ClassCounts: 229 92 
+
+minGini: 59.414323 - 5
+Region.size: 321
+LeftChild.size: 72
+LeftChild.ClassCounts: 70 2 
+RightChild.size: 249
+RightChild.ClassCounts: 159 90 
+
+minGini: 54.481507 - 4
+Region.size: 249
+LeftChild.size: 199
+LeftChild.ClassCounts: 138 61 
+RightChild.size: 50
+RightChild.ClassCounts: 21 29 
+
+minGini: 9.441860 - 6
+Region.size: 50
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 43
+RightChild.ClassCounts: 14 29 
+
+minGini: 8.117647 - 2
+Region.size: 43
+LeftChild.size: 9
+LeftChild.ClassCounts: 6 3 
+RightChild.size: 34
+RightChild.ClassCounts: 8 26 
+
+minGini: 4.193548 - 3
+Region.size: 34
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 31
+RightChild.ClassCounts: 5 26 
+
+minGini: 3.333333 - 7
+Region.size: 31
+LeftChild.size: 15
+LeftChild.ClassCounts: 5 10 
+RightChild.size: 16
+RightChild.ClassCounts: 0 16 
+
+minGini: 2.727272 - 1
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 5 6 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.857142 - 2
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 7
+RightChild.ClassCounts: 1 6 
+
+minGini: 0.000000 - 7
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 39.835051 - 5
+Region.size: 199
+LeftChild.size: 194
+LeftChild.ClassCounts: 138 56 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 36.885154 - 1
+Region.size: 194
+LeftChild.size: 75
+LeftChild.ClassCounts: 65 10 
+RightChild.size: 119
+RightChild.ClassCounts: 73 46 
+
+minGini: 26.873232 - 3
+Region.size: 119
+LeftChild.size: 99
+LeftChild.ClassCounts: 56 43 
+RightChild.size: 20
+RightChild.ClassCounts: 17 3 
+
+minGini: 1.789473 - 5
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 17 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.333333 - 2
+Region.size: 19
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 20.049321 - 2
+Region.size: 99
+LeftChild.size: 65
+LeftChild.ClassCounts: 27 38 
+RightChild.size: 34
+RightChild.ClassCounts: 29 5 
+
+minGini: 3.376344 - 1
+Region.size: 34
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 31
+RightChild.ClassCounts: 28 3 
+
+minGini: 1.866666 - 5
+Region.size: 31
+LeftChild.size: 30
+LeftChild.ClassCounts: 28 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.555555 - 5
+Region.size: 30
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 21
+RightChild.ClassCounts: 21 0 
+
+minGini: 0.666666 - 7
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.500000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 14.136792 - 0
+Region.size: 65
+LeftChild.size: 12
+LeftChild.ClassCounts: 9 3 
+RightChild.size: 53
+RightChild.ClassCounts: 18 35 
+
+minGini: 10.000000 - 1
+Region.size: 53
+LeftChild.size: 49
+LeftChild.ClassCounts: 14 35 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 8.936170 - 7
+Region.size: 49
+LeftChild.size: 47
+LeftChild.ClassCounts: 12 35 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 7.963369 - 5
+Region.size: 47
+LeftChild.size: 26
+LeftChild.ClassCounts: 10 16 
+RightChild.size: 21
+RightChild.ClassCounts: 2 19 
+
+minGini: 1.500000 - 5
+Region.size: 21
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 
+RightChild.size: 8
+RightChild.ClassCounts: 2 6 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 4.015037 - 4
+Region.size: 26
+LeftChild.size: 19
+LeftChild.ClassCounts: 4 15 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.800000 - 2
+Region.size: 19
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 0.000000 - 3
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.900000 - 6
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 10
+RightChild.ClassCounts: 9 1 
+
+minGini: 0.500000 - 4
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 6.319444 - 6
+Region.size: 75
+LeftChild.size: 72
+LeftChild.ClassCounts: 65 7 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 5.397913 - 4
+Region.size: 72
+LeftChild.size: 61
+LeftChild.ClassCounts: 58 3 
+RightChild.size: 11
+RightChild.ClassCounts: 7 4 
+
+minGini: 0.000000 - 4
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 2.250000 - 5
+Region.size: 61
+LeftChild.size: 49
+LeftChild.ClassCounts: 49 0 
+RightChild.size: 12
+RightChild.ClassCounts: 9 3 
+
+minGini: 1.500000 - 5
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.750000 - 3
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.485714 - 4
+Region.size: 72
+LeftChild.size: 70
+LeftChild.ClassCounts: 69 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 5
+Region.size: 70
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 66
+RightChild.ClassCounts: 66 0 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 19.737931 - 5
+Region.size: 250
+LeftChild.size: 145
+LeftChild.ClassCounts: 142 3 
+RightChild.size: 105
+RightChild.ClassCounts: 84 21 
+
+minGini: 15.811764 - 3
+Region.size: 105
+LeftChild.size: 20
+LeftChild.ClassCounts: 12 8 
+RightChild.size: 85
+RightChild.ClassCounts: 72 13 
+
+minGini: 10.229508 - 3
+Region.size: 85
+LeftChild.size: 24
+LeftChild.ClassCounts: 24 0 
+RightChild.size: 61
+RightChild.ClassCounts: 48 13 
+
+minGini: 8.949152 - 5
+Region.size: 61
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 59
+RightChild.ClassCounts: 48 11 
+
+minGini: 8.275862 - 1
+Region.size: 59
+LeftChild.size: 58
+LeftChild.ClassCounts: 48 10 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 6.967741 - 6
+Region.size: 58
+LeftChild.size: 31
+LeftChild.ClassCounts: 30 1 
+RightChild.size: 27
+RightChild.ClassCounts: 18 9 
+
+minGini: 5.040000 - 1
+Region.size: 27
+LeftChild.size: 25
+LeftChild.ClassCounts: 18 7 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 3.913043 - 0
+Region.size: 25
+LeftChild.size: 23
+LeftChild.ClassCounts: 18 5 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 3.437500 - 6
+Region.size: 23
+LeftChild.size: 16
+LeftChild.ClassCounts: 11 5 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 2.357142 - 4
+Region.size: 16
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 14
+RightChild.ClassCounts: 11 3 
+
+minGini: 1.500000 - 2
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 5
+Region.size: 31
+LeftChild.size: 30
+LeftChild.ClassCounts: 30 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.400000 - 2
+Region.size: 20
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 15
+RightChild.ClassCounts: 12 3 
+
+minGini: 1.200000 - 5
+Region.size: 15
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.666666 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.801459 - 1
+Region.size: 145
+LeftChild.size: 124
+LeftChild.ClassCounts: 123 1 
+RightChild.size: 21
+RightChild.ClassCounts: 19 2 
+
+minGini: 0.950000 - 6
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 19 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 7
+Region.size: 20
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.972222 - 1
+Region.size: 124
+LeftChild.size: 88
+LeftChild.ClassCounts: 88 0 
+RightChild.size: 36
+RightChild.ClassCounts: 35 1 
+
+minGini: 0.833333 - 1
+Region.size: 36
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 30
+RightChild.ClassCounts: 30 0 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 15 finished.
+
+minGini: 153.661907 - 7
+Region.size: 768
+LeftChild.size: 309
+LeftChild.ClassCounts: 263 46 
+RightChild.size: 459
+RightChild.ClassCounts: 240 219 
+
+minGini: 108.699043 - 3
+Region.size: 459
+LeftChild.size: 209
+LeftChild.ClassCounts: 135 74 
+RightChild.size: 250
+RightChild.ClassCounts: 105 145 
+
+minGini: 56.965609 - 7
+Region.size: 250
+LeftChild.size: 211
+LeftChild.ClassCounts: 100 111 
+RightChild.size: 39
+RightChild.ClassCounts: 5 34 
+
+minGini: 1.888888 - 0
+Region.size: 39
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 36
+RightChild.ClassCounts: 2 34 
+
+minGini: 1.470588 - 1
+Region.size: 36
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 34
+RightChild.ClassCounts: 1 33 
+
+minGini: 0.000000 - 7
+Region.size: 34
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 33 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 50.305418 - 2
+Region.size: 211
+LeftChild.size: 203
+LeftChild.ClassCounts: 92 111 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 39.328764 - 1
+Region.size: 203
+LeftChild.size: 121
+LeftChild.ClassCounts: 78 43 
+RightChild.size: 82
+RightChild.ClassCounts: 14 68 
+
+minGini: 9.853658 - 1
+Region.size: 82
+LeftChild.size: 41
+LeftChild.ClassCounts: 13 28 
+RightChild.size: 41
+RightChild.ClassCounts: 1 40 
+
+minGini: 0.900000 - 3
+Region.size: 41
+LeftChild.size: 10
+LeftChild.ClassCounts: 1 9 
+RightChild.size: 31
+RightChild.ClassCounts: 0 31 
+
+minGini: 0.500000 - 6
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 8.232804 - 0
+Region.size: 41
+LeftChild.size: 14
+LeftChild.ClassCounts: 2 12 
+RightChild.size: 27
+RightChild.ClassCounts: 11 16 
+
+minGini: 5.434065 - 0
+Region.size: 27
+LeftChild.size: 13
+LeftChild.ClassCounts: 8 5 
+RightChild.size: 14
+RightChild.ClassCounts: 3 11 
+
+minGini: 1.200000 - 4
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.750000 - 3
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 2.305555 - 4
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 
+
+minGini: 0.875000 - 7
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 6
+Region.size: 14
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 25.540810 - 6
+Region.size: 121
+LeftChild.size: 73
+LeftChild.ClassCounts: 55 18 
+RightChild.size: 48
+RightChild.ClassCounts: 23 25 
+
+minGini: 10.218750 - 5
+Region.size: 48
+LeftChild.size: 16
+LeftChild.ClassCounts: 12 4 
+RightChild.size: 32
+RightChild.ClassCounts: 11 21 
+
+minGini: 4.666666 - 3
+Region.size: 32
+LeftChild.size: 27
+LeftChild.ClassCounts: 6 21 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 2.625000 - 1
+Region.size: 27
+LeftChild.size: 24
+LeftChild.ClassCounts: 3 21 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 2.147368 - 1
+Region.size: 24
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 19
+RightChild.ClassCounts: 1 18 
+
+minGini: 0.750000 - 1
+Region.size: 19
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 15 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 2
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.800000 - 6
+Region.size: 16
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 12.497169 - 6
+Region.size: 73
+LeftChild.size: 53
+LeftChild.ClassCounts: 36 17 
+RightChild.size: 20
+RightChild.ClassCounts: 19 1 
+
+minGini: 0.000000 - 0
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 10.137931 - 4
+Region.size: 53
+LeftChild.size: 24
+LeftChild.ClassCounts: 12 12 
+RightChild.size: 29
+RightChild.ClassCounts: 24 5 
+
+minGini: 2.668831 - 0
+Region.size: 29
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 
+RightChild.size: 22
+RightChild.ClassCounts: 21 1 
+
+minGini: 0.800000 - 3
+Region.size: 22
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 17
+RightChild.ClassCounts: 17 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 4.888888 - 3
+Region.size: 24
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 15
+RightChild.ClassCounts: 5 10 
+
+minGini: 0.000000 - 6
+Region.size: 15
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.000000 - 1
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 45.739053 - 7
+Region.size: 209
+LeftChild.size: 169
+LeftChild.ClassCounts: 101 68 
+RightChild.size: 40
+RightChild.ClassCounts: 34 6 
+
+minGini: 1.500000 - 5
+Region.size: 40
+LeftChild.size: 32
+LeftChild.ClassCounts: 32 0 
+RightChild.size: 8
+RightChild.ClassCounts: 2 6 
+
+minGini: 0.666666 - 1
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 38.644385 - 3
+Region.size: 169
+LeftChild.size: 136
+LeftChild.ClassCounts: 74 62 
+RightChild.size: 33
+RightChild.ClassCounts: 27 6 
+
+minGini: 4.105263 - 2
+Region.size: 33
+LeftChild.size: 19
+LeftChild.ClassCounts: 13 6 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 3.000000 - 3
+Region.size: 19
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 12
+RightChild.ClassCounts: 6 6 
+
+minGini: 0.000000 - 4
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 23.984375 - 1
+Region.size: 136
+LeftChild.size: 64
+LeftChild.ClassCounts: 53 11 
+RightChild.size: 72
+RightChild.ClassCounts: 21 51 
+
+minGini: 13.366071 - 5
+Region.size: 72
+LeftChild.size: 16
+LeftChild.ClassCounts: 9 7 
+RightChild.size: 56
+RightChild.ClassCounts: 12 44 
+
+minGini: 7.200000 - 1
+Region.size: 56
+LeftChild.size: 30
+LeftChild.ClassCounts: 12 18 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 
+
+minGini: 5.863636 - 7
+Region.size: 30
+LeftChild.size: 22
+LeftChild.ClassCounts: 6 16 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 3.000000 - 2
+Region.size: 22
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 12
+RightChild.ClassCounts: 6 6 
+
+minGini: 2.000000 - 5
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 1.200000 - 1
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 2.250000 - 1
+Region.size: 16
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 12
+RightChild.ClassCounts: 9 3 
+
+minGini: 1.500000 - 1
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 
+
+minGini: 0.750000 - 6
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 8.048780 - 5
+Region.size: 64
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 41
+RightChild.ClassCounts: 30 11 
+
+minGini: 7.333333 - 1
+Region.size: 41
+LeftChild.size: 33
+LeftChild.ClassCounts: 22 11 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 5.923076 - 5
+Region.size: 33
+LeftChild.size: 20
+LeftChild.ClassCounts: 10 10 
+RightChild.size: 13
+RightChild.ClassCounts: 12 1 
+
+minGini: 0.000000 - 5
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 4.117647 - 5
+Region.size: 20
+LeftChild.size: 17
+LeftChild.ClassCounts: 10 7 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 2.916666 - 6
+Region.size: 17
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 12
+RightChild.ClassCounts: 5 7 
+
+minGini: 2.222222 - 6
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 9
+RightChild.ClassCounts: 5 4 
+
+minGini: 1.550000 - 5
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.500000 - 2
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 35.360351 - 3
+Region.size: 309
+LeftChild.size: 251
+LeftChild.ClassCounts: 227 24 
+RightChild.size: 58
+RightChild.ClassCounts: 36 22 
+
+minGini: 12.686792 - 0
+Region.size: 58
+LeftChild.size: 53
+LeftChild.ClassCounts: 35 18 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 10.716666 - 7
+Region.size: 53
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 48
+RightChild.ClassCounts: 34 14 
+
+minGini: 6.977777 - 1
+Region.size: 48
+LeftChild.size: 30
+LeftChild.ClassCounts: 27 3 
+RightChild.size: 18
+RightChild.ClassCounts: 7 11 
+
+minGini: 2.933333 - 4
+Region.size: 18
+LeftChild.size: 15
+LeftChild.ClassCounts: 4 11 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 2.000000 - 2
+Region.size: 15
+LeftChild.size: 8
+LeftChild.ClassCounts: 4 4 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 1.333333 - 2
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.437500 - 1
+Region.size: 30
+LeftChild.size: 16
+LeftChild.ClassCounts: 13 3 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 1.733333 - 2
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 15
+RightChild.ClassCounts: 13 2 
+
+minGini: 0.928571 - 6
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 14
+RightChild.ClassCounts: 13 1 
+
+minGini: 0.000000 - 1
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 17.187911 - 1
+Region.size: 251
+LeftChild.size: 197
+LeftChild.ClassCounts: 192 5 
+RightChild.size: 54
+RightChild.ClassCounts: 35 19 
+
+minGini: 8.158333 - 6
+Region.size: 54
+LeftChild.size: 24
+LeftChild.ClassCounts: 23 1 
+RightChild.size: 30
+RightChild.ClassCounts: 12 18 
+
+minGini: 4.421052 - 4
+Region.size: 30
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 19
+RightChild.ClassCounts: 12 7 
+
+minGini: 0.000000 - 0
+Region.size: 19
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 12
+RightChild.ClassCounts: 12 0 
+
+minGini: 0.000000 - 4
+Region.size: 24
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 4.548701 - 3
+Region.size: 197
+LeftChild.size: 176
+LeftChild.ClassCounts: 174 2 
+RightChild.size: 21
+RightChild.ClassCounts: 18 3 
+
+minGini: 1.611111 - 6
+Region.size: 21
+LeftChild.size: 18
+LeftChild.ClassCounts: 17 1 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 1
+Region.size: 18
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.994285 - 0
+Region.size: 176
+LeftChild.size: 175
+LeftChild.ClassCounts: 174 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.950000 - 6
+Region.size: 175
+LeftChild.size: 155
+LeftChild.ClassCounts: 155 0 
+RightChild.size: 20
+RightChild.ClassCounts: 19 1 
+
+minGini: 0.500000 - 0
+Region.size: 20
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 16 finished.
+
+minGini: 155.518427 - 0
+Region.size: 768
+LeftChild.size: 592
+LeftChild.ClassCounts: 440 152 
+RightChild.size: 176
+RightChild.ClassCounts: 72 104 
+
+minGini: 40.272727 - 3
+Region.size: 176
+LeftChild.size: 88
+LeftChild.ClassCounts: 46 42 
+RightChild.size: 88
+RightChild.ClassCounts: 26 62 
+
+minGini: 16.611312 - 6
+Region.size: 88
+LeftChild.size: 47
+LeftChild.ClassCounts: 20 27 
+RightChild.size: 41
+RightChild.ClassCounts: 6 35 
+
+minGini: 3.950000 - 2
+Region.size: 41
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 36
+RightChild.ClassCounts: 3 33 
+
+minGini: 0.000000 - 1
+Region.size: 36
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 33
+RightChild.ClassCounts: 0 33 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 9.896103 - 0
+Region.size: 47
+LeftChild.size: 14
+LeftChild.ClassCounts: 2 12 
+RightChild.size: 33
+RightChild.ClassCounts: 18 15 
+
+minGini: 4.500000 - 4
+Region.size: 33
+LeftChild.size: 24
+LeftChild.ClassCounts: 18 6 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 3.230769 - 3
+Region.size: 24
+LeftChild.size: 13
+LeftChild.ClassCounts: 7 6 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 2.100000 - 1
+Region.size: 13
+LeftChild.size: 10
+LeftChild.ClassCounts: 7 3 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.875000 - 6
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.000000 - 2
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 1.200000 - 7
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 16.518598 - 5
+Region.size: 88
+LeftChild.size: 35
+LeftChild.ClassCounts: 29 6 
+RightChild.size: 53
+RightChild.ClassCounts: 17 36 
+
+minGini: 7.826086 - 7
+Region.size: 53
+LeftChild.size: 46
+LeftChild.ClassCounts: 10 36 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 5.860465 - 1
+Region.size: 46
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 43
+RightChild.ClassCounts: 7 36 
+
+minGini: 5.358974 - 4
+Region.size: 43
+LeftChild.size: 39
+LeftChild.ClassCounts: 5 34 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 3.742857 - 2
+Region.size: 39
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 35
+RightChild.ClassCounts: 3 32 
+
+minGini: 2.526315 - 5
+Region.size: 35
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 
+RightChild.size: 19
+RightChild.ClassCounts: 3 16 
+
+minGini: 1.777777 - 6
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 2 16 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.000000 - 6
+Region.size: 18
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 3.230769 - 6
+Region.size: 35
+LeftChild.size: 22
+LeftChild.ClassCounts: 22 0 
+RightChild.size: 13
+RightChild.ClassCounts: 7 6 
+
+minGini: 2.300000 - 5
+Region.size: 13
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.857142 - 2
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.666666 - 2
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 108.105170 - 7
+Region.size: 592
+LeftChild.size: 326
+LeftChild.ClassCounts: 269 57 
+RightChild.size: 266
+RightChild.ClassCounts: 171 95 
+
+minGini: 52.381780 - 1
+Region.size: 266
+LeftChild.size: 105
+LeftChild.ClassCounts: 91 14 
+RightChild.size: 161
+RightChild.ClassCounts: 80 81 
+
+minGini: 34.397941 - 5
+Region.size: 161
+LeftChild.size: 57
+LeftChild.ClassCounts: 43 14 
+RightChild.size: 104
+RightChild.ClassCounts: 37 67 
+
+minGini: 22.533591 - 5
+Region.size: 104
+LeftChild.size: 86
+LeftChild.ClassCounts: 35 51 
+RightChild.size: 18
+RightChild.ClassCounts: 2 16 
+
+minGini: 1.333333 - 4
+Region.size: 18
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 17.653846 - 6
+Region.size: 86
+LeftChild.size: 78
+LeftChild.ClassCounts: 27 51 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 14.826923 - 1
+Region.size: 78
+LeftChild.size: 52
+LeftChild.ClassCounts: 25 27 
+RightChild.size: 26
+RightChild.ClassCounts: 2 24 
+
+minGini: 1.500000 - 6
+Region.size: 26
+LeftChild.size: 8
+LeftChild.ClassCounts: 2 6 
+RightChild.size: 18
+RightChild.ClassCounts: 0 18 
+
+minGini: 0.666666 - 2
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 11.489361 - 4
+Region.size: 52
+LeftChild.size: 47
+LeftChild.ClassCounts: 20 27 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 8.935483 - 7
+Region.size: 47
+LeftChild.size: 16
+LeftChild.ClassCounts: 12 4 
+RightChild.size: 31
+RightChild.ClassCounts: 8 23 
+
+minGini: 4.758620 - 2
+Region.size: 31
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 29
+RightChild.ClassCounts: 6 23 
+
+minGini: 4.000000 - 2
+Region.size: 29
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 18
+RightChild.ClassCounts: 6 12 
+
+minGini: 2.727272 - 3
+Region.size: 18
+LeftChild.size: 11
+LeftChild.ClassCounts: 6 5 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 2.109090 - 4
+Region.size: 16
+LeftChild.size: 11
+LeftChild.ClassCounts: 10 1 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.666666 - 7
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 7
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.500000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 8.509925 - 7
+Region.size: 57
+LeftChild.size: 31
+LeftChild.ClassCounts: 18 13 
+RightChild.size: 26
+RightChild.ClassCounts: 25 1 
+
+minGini: 0.875000 - 7
+Region.size: 26
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 18
+RightChild.ClassCounts: 18 0 
+
+minGini: 0.666666 - 0
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 4.500000 - 7
+Region.size: 31
+LeftChild.size: 24
+LeftChild.ClassCounts: 18 6 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 2.369747 - 0
+Region.size: 24
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 5 
+RightChild.size: 17
+RightChild.ClassCounts: 16 1 
+
+minGini: 0.666666 - 1
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.833333 - 3
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 10.888888 - 7
+Region.size: 105
+LeftChild.size: 90
+LeftChild.ClassCounts: 82 8 
+RightChild.size: 15
+RightChild.ClassCounts: 9 6 
+
+minGini: 0.900000 - 7
+Region.size: 15
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 10
+RightChild.ClassCounts: 9 1 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 6.621428 - 2
+Region.size: 90
+LeftChild.size: 70
+LeftChild.ClassCounts: 67 3 
+RightChild.size: 20
+RightChild.ClassCounts: 15 5 
+
+minGini: 1.764705 - 4
+Region.size: 20
+LeftChild.size: 17
+LeftChild.ClassCounts: 15 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.333333 - 1
+Region.size: 17
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.000000 - 7
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.942028 - 1
+Region.size: 70
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 69
+RightChild.ClassCounts: 67 2 
+
+minGini: 0.985294 - 1
+Region.size: 69
+LeftChild.size: 68
+LeftChild.ClassCounts: 67 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.937500 - 5
+Region.size: 68
+LeftChild.size: 52
+LeftChild.ClassCounts: 52 0 
+RightChild.size: 16
+RightChild.ClassCounts: 15 1 
+
+minGini: 0.000000 - 5
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 
+
+minGini: 40.616783 - 5
+Region.size: 326
+LeftChild.size: 286
+LeftChild.ClassCounts: 251 35 
+RightChild.size: 40
+RightChild.ClassCounts: 18 22 
+
+minGini: 6.812030 - 1
+Region.size: 40
+LeftChild.size: 21
+LeftChild.ClassCounts: 15 6 
+RightChild.size: 19
+RightChild.ClassCounts: 3 16 
+
+minGini: 1.200000 - 5
+Region.size: 19
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 3.600000 - 1
+Region.size: 21
+LeftChild.size: 15
+LeftChild.ClassCounts: 9 6 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 2.000000 - 0
+Region.size: 15
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 0.857142 - 6
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.666666 - 0
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 26.842805 - 4
+Region.size: 286
+LeftChild.size: 279
+LeftChild.ClassCounts: 250 29 
+RightChild.size: 7
+RightChild.ClassCounts: 1 6 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 22.688665 - 1
+Region.size: 279
+LeftChild.size: 238
+LeftChild.ClassCounts: 224 14 
+RightChild.size: 41
+RightChild.ClassCounts: 26 15 
+
+minGini: 7.222222 - 2
+Region.size: 41
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 36
+RightChild.ClassCounts: 26 10 
+
+minGini: 4.222222 - 1
+Region.size: 36
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 7 
+RightChild.size: 27
+RightChild.ClassCounts: 24 3 
+
+minGini: 1.846153 - 1
+Region.size: 27
+LeftChild.size: 26
+LeftChild.ClassCounts: 24 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.428571 - 2
+Region.size: 26
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 19
+RightChild.ClassCounts: 19 0 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 7
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 11.565217 - 6
+Region.size: 238
+LeftChild.size: 230
+LeftChild.ClassCounts: 220 10 
+RightChild.size: 8
+RightChild.ClassCounts: 4 4 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 8.987278 - 3
+Region.size: 230
+LeftChild.size: 211
+LeftChild.ClassCounts: 205 6 
+RightChild.size: 19
+RightChild.ClassCounts: 15 4 
+
+minGini: 1.764705 - 0
+Region.size: 19
+LeftChild.size: 17
+LeftChild.ClassCounts: 15 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.433333 - 3
+Region.size: 17
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 15
+RightChild.ClassCounts: 14 1 
+
+minGini: 0.800000 - 6
+Region.size: 15
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.500000 - 2
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.702479 - 4
+Region.size: 211
+LeftChild.size: 121
+LeftChild.ClassCounts: 115 6 
+RightChild.size: 90
+RightChild.ClassCounts: 90 0 
+
+minGini: 5.096390 - 1
+Region.size: 121
+LeftChild.size: 93
+LeftChild.ClassCounts: 92 1 
+RightChild.size: 28
+RightChild.ClassCounts: 23 5 
+
+minGini: 2.916666 - 5
+Region.size: 28
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 12
+RightChild.ClassCounts: 7 5 
+
+minGini: 0.875000 - 2
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.950000 - 0
+Region.size: 93
+LeftChild.size: 73
+LeftChild.ClassCounts: 73 0 
+RightChild.size: 20
+RightChild.ClassCounts: 19 1 
+
+minGini: 0.888888 - 1
+Region.size: 20
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 9
+RightChild.ClassCounts: 8 1 
+
+minGini: 0.000000 - 4
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 17 finished.
+
+minGini: 162.771826 - 7
+Region.size: 768
+LeftChild.size: 375
+LeftChild.ClassCounts: 292 83 
+RightChild.size: 393
+RightChild.ClassCounts: 190 203 
+
+minGini: 94.854860 - 6
+Region.size: 393
+LeftChild.size: 154
+LeftChild.ClassCounts: 92 62 
+RightChild.size: 239
+RightChild.ClassCounts: 98 141 
+
+minGini: 49.375192 - 4
+Region.size: 239
+LeftChild.size: 155
+LeftChild.ClassCounts: 85 70 
+RightChild.size: 84
+RightChild.ClassCounts: 13 71 
+
+minGini: 9.934210 - 4
+Region.size: 84
+LeftChild.size: 76
+LeftChild.ClassCounts: 9 67 
+RightChild.size: 8
+RightChild.ClassCounts: 4 4 
+
+minGini: 0.000000 - 3
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 7.372405 - 4
+Region.size: 76
+LeftChild.size: 13
+LeftChild.ClassCounts: 4 9 
+RightChild.size: 63
+RightChild.ClassCounts: 5 58 
+
+minGini: 3.741935 - 5
+Region.size: 63
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 62
+RightChild.ClassCounts: 4 58 
+
+minGini: 3.350000 - 6
+Region.size: 62
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 60
+RightChild.ClassCounts: 3 57 
+
+minGini: 2.700000 - 2
+Region.size: 60
+LeftChild.size: 30
+LeftChild.ClassCounts: 3 27 
+RightChild.size: 30
+RightChild.ClassCounts: 0 30 
+
+minGini: 2.357142 - 5
+Region.size: 30
+LeftChild.size: 14
+LeftChild.ClassCounts: 3 11 
+RightChild.size: 16
+RightChild.ClassCounts: 0 16 
+
+minGini: 1.692307 - 3
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 2 11 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.333333 - 7
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.666666 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.636363 - 0
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 2 9 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.333333 - 3
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.800000 - 3
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 35.081904 - 4
+Region.size: 155
+LeftChild.size: 105
+LeftChild.ClassCounts: 47 58 
+RightChild.size: 50
+RightChild.ClassCounts: 38 12 
+
+minGini: 7.120000 - 1
+Region.size: 50
+LeftChild.size: 25
+LeftChild.ClassCounts: 24 1 
+RightChild.size: 25
+RightChild.ClassCounts: 14 11 
+
+minGini: 3.933823 - 0
+Region.size: 25
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 17
+RightChild.ClassCounts: 13 4 
+
+minGini: 2.380952 - 3
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 12 2 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 6
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.666666 - 1
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.875000 - 3
+Region.size: 25
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 17
+RightChild.ClassCounts: 17 0 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 20.838613 - 5
+Region.size: 105
+LeftChild.size: 32
+LeftChild.ClassCounts: 25 7 
+RightChild.size: 73
+RightChild.ClassCounts: 22 51 
+
+minGini: 13.826086 - 5
+Region.size: 73
+LeftChild.size: 50
+LeftChild.ClassCounts: 20 30 
+RightChild.size: 23
+RightChild.ClassCounts: 2 21 
+
+minGini: 0.000000 - 0
+Region.size: 23
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 21 
+
+minGini: 7.500000 - 1
+Region.size: 50
+LeftChild.size: 32
+LeftChild.ClassCounts: 20 12 
+RightChild.size: 18
+RightChild.ClassCounts: 0 18 
+
+minGini: 5.468599 - 6
+Region.size: 32
+LeftChild.size: 23
+LeftChild.ClassCounts: 18 5 
+RightChild.size: 9
+RightChild.ClassCounts: 2 7 
+
+minGini: 0.666666 - 3
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.571428 - 0
+Region.size: 23
+LeftChild.size: 21
+LeftChild.ClassCounts: 18 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.400000 - 2
+Region.size: 21
+LeftChild.size: 15
+LeftChild.ClassCounts: 12 3 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 1.714285 - 5
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 14
+RightChild.ClassCounts: 12 2 
+
+minGini: 0.666666 - 2
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.466666 - 6
+Region.size: 32
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 27
+RightChild.ClassCounts: 24 3 
+
+minGini: 1.846153 - 1
+Region.size: 27
+LeftChild.size: 26
+LeftChild.ClassCounts: 24 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.600000 - 0
+Region.size: 26
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 10
+RightChild.ClassCounts: 8 2 
+
+minGini: 0.666666 - 3
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 35.194630 - 5
+Region.size: 154
+LeftChild.size: 149
+LeftChild.ClassCounts: 92 57 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 33.527725 - 4
+Region.size: 149
+LeftChild.size: 133
+LeftChild.ClassCounts: 87 46 
+RightChild.size: 16
+RightChild.ClassCounts: 5 11 
+
+minGini: 1.428571 - 7
+Region.size: 16
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.833333 - 3
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 29.072000 - 6
+Region.size: 133
+LeftChild.size: 125
+LeftChild.ClassCounts: 79 46 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 27.421487 - 6
+Region.size: 125
+LeftChild.size: 121
+LeftChild.ClassCounts: 79 42 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 25.323732 - 3
+Region.size: 121
+LeftChild.size: 93
+LeftChild.ClassCounts: 54 39 
+RightChild.size: 28
+RightChild.ClassCounts: 25 3 
+
+minGini: 2.287878 - 1
+Region.size: 28
+LeftChild.size: 22
+LeftChild.ClassCounts: 21 1 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.666666 - 2
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 2
+Region.size: 22
+LeftChild.size: 21
+LeftChild.ClassCounts: 21 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 19.842391 - 7
+Region.size: 93
+LeftChild.size: 24
+LeftChild.ClassCounts: 21 3 
+RightChild.size: 69
+RightChild.ClassCounts: 33 36 
+
+minGini: 15.096774 - 7
+Region.size: 69
+LeftChild.size: 62
+LeftChild.ClassCounts: 26 36 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 13.654188 - 6
+Region.size: 62
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 51
+RightChild.ClassCounts: 25 26 
+
+minGini: 11.645962 - 6
+Region.size: 51
+LeftChild.size: 23
+LeftChild.ClassCounts: 15 8 
+RightChild.size: 28
+RightChild.ClassCounts: 10 18 
+
+minGini: 3.913043 - 1
+Region.size: 28
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 23
+RightChild.ClassCounts: 5 18 
+
+minGini: 2.977777 - 5
+Region.size: 23
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 18
+RightChild.ClassCounts: 2 16 
+
+minGini: 1.200000 - 6
+Region.size: 18
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 4.285714 - 7
+Region.size: 23
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 21
+RightChild.ClassCounts: 15 6 
+
+minGini: 3.066666 - 1
+Region.size: 21
+LeftChild.size: 15
+LeftChild.ClassCounts: 13 2 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 7
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.600000 - 5
+Region.size: 15
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 10
+RightChild.ClassCounts: 8 2 
+
+minGini: 0.888888 - 4
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 8 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 7
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 1.826086 - 5
+Region.size: 24
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 23
+RightChild.ClassCounts: 21 2 
+
+minGini: 1.200000 - 5
+Region.size: 23
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.666666 - 0
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 51.109886 - 1
+Region.size: 375
+LeftChild.size: 283
+LeftChild.ClassCounts: 251 32 
+RightChild.size: 92
+RightChild.ClassCounts: 41 51 
+
+minGini: 17.238791 - 5
+Region.size: 92
+LeftChild.size: 38
+LeftChild.ClassCounts: 28 10 
+RightChild.size: 54
+RightChild.ClassCounts: 13 41 
+
+minGini: 7.479699 - 7
+Region.size: 54
+LeftChild.size: 35
+LeftChild.ClassCounts: 3 32 
+RightChild.size: 19
+RightChild.ClassCounts: 10 9 
+
+minGini: 3.214285 - 0
+Region.size: 19
+LeftChild.size: 14
+LeftChild.ClassCounts: 5 9 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 2.208333 - 3
+Region.size: 14
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.500000 - 5
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.357142 - 1
+Region.size: 35
+LeftChild.size: 14
+LeftChild.ClassCounts: 3 11 
+RightChild.size: 21
+RightChild.ClassCounts: 0 21 
+
+minGini: 1.200000 - 3
+Region.size: 14
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.666666 - 5
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 3.575000 - 7
+Region.size: 38
+LeftChild.size: 30
+LeftChild.ClassCounts: 27 3 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.000000 - 0
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.181818 - 5
+Region.size: 30
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 11
+RightChild.ClassCounts: 8 3 
+
+minGini: 1.600000 - 1
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 8 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.333333 - 1
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.666666 - 2
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 23.602272 - 5
+Region.size: 283
+LeftChild.size: 275
+LeftChild.ClassCounts: 250 25 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.666666 - 3
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 21.897810 - 0
+Region.size: 275
+LeftChild.size: 274
+LeftChild.ClassCounts: 250 24 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 19.388461 - 6
+Region.size: 274
+LeftChild.size: 260
+LeftChild.ClassCounts: 243 17 
+RightChild.size: 14
+RightChild.ClassCounts: 7 7 
+
+minGini: 1.555555 - 1
+Region.size: 14
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 5
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 15.111718 - 5
+Region.size: 260
+LeftChild.size: 139
+LeftChild.ClassCounts: 137 2 
+RightChild.size: 121
+RightChild.ClassCounts: 106 15 
+
+minGini: 11.579831 - 2
+Region.size: 121
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 119
+RightChild.ClassCounts: 106 13 
+
+minGini: 11.087147 - 1
+Region.size: 119
+LeftChild.size: 71
+LeftChild.ClassCounts: 67 4 
+RightChild.size: 48
+RightChild.ClassCounts: 39 9 
+
+minGini: 6.291666 - 4
+Region.size: 48
+LeftChild.size: 24
+LeftChild.ClassCounts: 16 8 
+RightChild.size: 24
+RightChild.ClassCounts: 23 1 
+
+minGini: 0.000000 - 5
+Region.size: 24
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 23
+RightChild.ClassCounts: 23 0 
+
+minGini: 4.867132 - 7
+Region.size: 24
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 13
+RightChild.ClassCounts: 7 6 
+
+minGini: 2.100000 - 5
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 10
+RightChild.ClassCounts: 7 3 
+
+minGini: 0.750000 - 2
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.500000 - 3
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 3.569696 - 6
+Region.size: 71
+LeftChild.size: 60
+LeftChild.ClassCounts: 58 2 
+RightChild.size: 11
+RightChild.ClassCounts: 9 2 
+
+minGini: 0.000000 - 4
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.732142 - 2
+Region.size: 60
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 56
+RightChild.ClassCounts: 55 1 
+
+minGini: 0.916666 - 3
+Region.size: 56
+LeftChild.size: 12
+LeftChild.ClassCounts: 11 1 
+RightChild.size: 44
+RightChild.ClassCounts: 44 0 
+
+minGini: 0.000000 - 3
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.891891 - 0
+Region.size: 139
+LeftChild.size: 102
+LeftChild.ClassCounts: 102 0 
+RightChild.size: 37
+RightChild.ClassCounts: 35 2 
+
+minGini: 1.777777 - 2
+Region.size: 37
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 18
+RightChild.ClassCounts: 16 2 
+
+minGini: 1.000000 - 2
+Region.size: 18
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 18 finished.
+
+minGini: 133.130198 - 1
+Region.size: 768
+LeftChild.size: 486
+LeftChild.ClassCounts: 401 85 
+RightChild.size: 282
+RightChild.ClassCounts: 95 187 
+
+minGini: 59.632161 - 7
+Region.size: 282
+LeftChild.size: 238
+LeftChild.ClassCounts: 69 169 
+RightChild.size: 44
+RightChild.ClassCounts: 26 18 
+
+minGini: 9.100000 - 3
+Region.size: 44
+LeftChild.size: 40
+LeftChild.ClassCounts: 26 14 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 7.942857 - 5
+Region.size: 40
+LeftChild.size: 35
+LeftChild.ClassCounts: 25 10 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.971264 - 1
+Region.size: 35
+LeftChild.size: 29
+LeftChild.ClassCounts: 24 5 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 7
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.437500 - 6
+Region.size: 29
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 16
+RightChild.ClassCounts: 11 5 
+
+minGini: 1.692307 - 5
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 11 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.200000 - 6
+Region.size: 13
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 44.936393 - 5
+Region.size: 238
+LeftChild.size: 47
+LeftChild.ClassCounts: 26 21 
+RightChild.size: 191
+RightChild.ClassCounts: 43 148 
+
+minGini: 31.073103 - 6
+Region.size: 191
+LeftChild.size: 75
+LeftChild.ClassCounts: 27 48 
+RightChild.size: 116
+RightChild.ClassCounts: 16 100 
+
+minGini: 13.043478 - 5
+Region.size: 116
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 115
+RightChild.ClassCounts: 15 100 
+
+minGini: 12.533333 - 1
+Region.size: 115
+LeftChild.size: 55
+LeftChild.ClassCounts: 11 44 
+RightChild.size: 60
+RightChild.ClassCounts: 4 56 
+
+minGini: 2.847457 - 4
+Region.size: 60
+LeftChild.size: 59
+LeftChild.ClassCounts: 3 56 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.429824 - 2
+Region.size: 59
+LeftChild.size: 57
+LeftChild.ClassCounts: 2 55 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.333333 - 7
+Region.size: 57
+LeftChild.size: 51
+LeftChild.ClassCounts: 0 51 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 6.039215 - 4
+Region.size: 55
+LeftChild.size: 51
+LeftChild.ClassCounts: 7 44 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 5.280000 - 1
+Region.size: 51
+LeftChild.size: 50
+LeftChild.ClassCounts: 6 44 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.408088 - 0
+Region.size: 50
+LeftChild.size: 16
+LeftChild.ClassCounts: 5 11 
+RightChild.size: 34
+RightChild.ClassCounts: 1 33 
+
+minGini: 0.875000 - 5
+Region.size: 34
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.603174 - 4
+Region.size: 16
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 
+
+minGini: 0.666666 - 0
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.750000 - 5
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 12.281650 - 1
+Region.size: 75
+LeftChild.size: 37
+LeftChild.ClassCounts: 23 14 
+RightChild.size: 38
+RightChild.ClassCounts: 4 34 
+
+minGini: 3.208333 - 1
+Region.size: 38
+LeftChild.size: 32
+LeftChild.ClassCounts: 2 30 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 7
+Region.size: 32
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 30 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 6.969696 - 3
+Region.size: 37
+LeftChild.size: 33
+LeftChild.ClassCounts: 23 10 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 5.454545 - 3
+Region.size: 33
+LeftChild.size: 22
+LeftChild.ClassCounts: 12 10 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 4.736842 - 6
+Region.size: 22
+LeftChild.size: 19
+LeftChild.ClassCounts: 9 10 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 3.155555 - 2
+Region.size: 19
+LeftChild.size: 10
+LeftChild.ClassCounts: 2 8 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.200000 - 5
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.666666 - 4
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 9.387096 - 1
+Region.size: 47
+LeftChild.size: 31
+LeftChild.ClassCounts: 22 9 
+RightChild.size: 16
+RightChild.ClassCounts: 4 12 
+
+minGini: 1.714285 - 4
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 2 12 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 2
+Region.size: 14
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 5.008547 - 5
+Region.size: 31
+LeftChild.size: 18
+LeftChild.ClassCounts: 16 2 
+RightChild.size: 13
+RightChild.ClassCounts: 6 7 
+
+minGini: 1.555555 - 0
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 9
+RightChild.ClassCounts: 2 7 
+
+minGini: 0.875000 - 2
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.437500 - 3
+Region.size: 18
+LeftChild.size: 16
+LeftChild.ClassCounts: 15 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.857142 - 6
+Region.size: 16
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 67.180553 - 0
+Region.size: 486
+LeftChild.size: 284
+LeftChild.ClassCounts: 253 31 
+RightChild.size: 202
+RightChild.ClassCounts: 148 54 
+
+minGini: 38.962206 - 2
+Region.size: 202
+LeftChild.size: 142
+LeftChild.ClassCounts: 99 43 
+RightChild.size: 60
+RightChild.ClassCounts: 49 11 
+
+minGini: 6.749326 - 1
+Region.size: 60
+LeftChild.size: 53
+LeftChild.ClassCounts: 47 6 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 
+
+minGini: 0.833333 - 0
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 6
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.519230 - 0
+Region.size: 53
+LeftChild.size: 52
+LeftChild.ClassCounts: 47 5 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 3.482993 - 5
+Region.size: 52
+LeftChild.size: 49
+LeftChild.ClassCounts: 46 3 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.703921 - 0
+Region.size: 49
+LeftChild.size: 34
+LeftChild.ClassCounts: 33 1 
+RightChild.size: 15
+RightChild.ClassCounts: 13 2 
+
+minGini: 0.928571 - 6
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 13 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 7
+Region.size: 14
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.800000 - 6
+Region.size: 34
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 29
+RightChild.ClassCounts: 29 0 
+
+minGini: 0.666666 - 2
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 25.879629 - 5
+Region.size: 142
+LeftChild.size: 34
+LeftChild.ClassCounts: 34 0 
+RightChild.size: 108
+RightChild.ClassCounts: 65 43 
+
+minGini: 21.706987 - 7
+Region.size: 108
+LeftChild.size: 25
+LeftChild.ClassCounts: 24 1 
+RightChild.size: 83
+RightChild.ClassCounts: 41 42 
+
+minGini: 17.056526 - 1
+Region.size: 83
+LeftChild.size: 39
+LeftChild.ClassCounts: 28 11 
+RightChild.size: 44
+RightChild.ClassCounts: 13 31 
+
+minGini: 6.964285 - 1
+Region.size: 44
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 
+RightChild.size: 28
+RightChild.ClassCounts: 13 15 
+
+minGini: 4.952380 - 6
+Region.size: 28
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 21
+RightChild.ClassCounts: 13 8 
+
+minGini: 3.058823 - 7
+Region.size: 21
+LeftChild.size: 17
+LeftChild.ClassCounts: 13 4 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.714285 - 7
+Region.size: 17
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 5.548275 - 6
+Region.size: 39
+LeftChild.size: 29
+LeftChild.ClassCounts: 25 4 
+RightChild.size: 10
+RightChild.ClassCounts: 3 7 
+
+minGini: 1.500000 - 7
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 
+
+minGini: 0.750000 - 3
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 2.769230 - 6
+Region.size: 29
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 13
+RightChild.ClassCounts: 9 4 
+
+minGini: 2.222222 - 0
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 9
+RightChild.ClassCounts: 5 4 
+
+minGini: 0.000000 - 1
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.900000 - 2
+Region.size: 25
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 
+
+minGini: 0.000000 - 5
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 25.635711 - 3
+Region.size: 284
+LeftChild.size: 193
+LeftChild.ClassCounts: 183 10 
+RightChild.size: 91
+RightChild.ClassCounts: 70 21 
+
+minGini: 14.795295 - 5
+Region.size: 91
+LeftChild.size: 37
+LeftChild.ClassCounts: 23 14 
+RightChild.size: 54
+RightChild.ClassCounts: 47 7 
+
+minGini: 5.527173 - 4
+Region.size: 54
+LeftChild.size: 46
+LeftChild.ClassCounts: 42 4 
+RightChild.size: 8
+RightChild.ClassCounts: 5 3 
+
+minGini: 0.000000 - 4
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 3.238095 - 2
+Region.size: 46
+LeftChild.size: 21
+LeftChild.ClassCounts: 17 4 
+RightChild.size: 25
+RightChild.ClassCounts: 25 0 
+
+minGini: 2.222222 - 6
+Region.size: 21
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 9
+RightChild.ClassCounts: 5 4 
+
+minGini: 0.800000 - 7
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 6.432352 - 5
+Region.size: 37
+LeftChild.size: 20
+LeftChild.ClassCounts: 17 3 
+RightChild.size: 17
+RightChild.ClassCounts: 6 11 
+
+minGini: 1.500000 - 6
+Region.size: 17
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 2 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 1.200000 - 6
+Region.size: 20
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 7.514509 - 7
+Region.size: 193
+LeftChild.size: 167
+LeftChild.ClassCounts: 165 2 
+RightChild.size: 26
+RightChild.ClassCounts: 18 8 
+
+minGini: 4.800000 - 2
+Region.size: 26
+LeftChild.size: 20
+LeftChild.ClassCounts: 12 8 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 2.666666 - 1
+Region.size: 20
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 12
+RightChild.ClassCounts: 4 8 
+
+minGini: 0.888888 - 5
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 
+
+minGini: 0.666666 - 5
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.800000 - 6
+Region.size: 167
+LeftChild.size: 20
+LeftChild.ClassCounts: 18 2 
+RightChild.size: 147
+RightChild.ClassCounts: 147 0 
+
+minGini: 0.666666 - 1
+Region.size: 20
+LeftChild.size: 17
+LeftChild.ClassCounts: 17 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 19 finished.
+
+minGini: 141.243259 - 1
+Region.size: 768
+LeftChild.size: 650
+LeftChild.ClassCounts: 487 163 
+RightChild.size: 118
+RightChild.ClassCounts: 24 94 
+
+minGini: 15.587777 - 5
+Region.size: 118
+LeftChild.size: 18
+LeftChild.ClassCounts: 11 7 
+RightChild.size: 100
+RightChild.ClassCounts: 13 87 
+
+minGini: 9.843317 - 2
+Region.size: 100
+LeftChild.size: 93
+LeftChild.ClassCounts: 9 84 
+RightChild.size: 7
+RightChild.ClassCounts: 4 3 
+
+minGini: 0.000000 - 7
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 7.742793 - 1
+Region.size: 93
+LeftChild.size: 11
+LeftChild.ClassCounts: 3 8 
+RightChild.size: 82
+RightChild.ClassCounts: 6 76 
+
+minGini: 5.121428 - 1
+Region.size: 82
+LeftChild.size: 70
+LeftChild.ClassCounts: 3 67 
+RightChild.size: 12
+RightChild.ClassCounts: 3 9 
+
+minGini: 0.000000 - 1
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 2.483870 - 7
+Region.size: 70
+LeftChild.size: 62
+LeftChild.ClassCounts: 1 61 
+RightChild.size: 8
+RightChild.ClassCounts: 2 6 
+
+minGini: 0.857142 - 6
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.928571 - 4
+Region.size: 62
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 48 
+RightChild.size: 14
+RightChild.ClassCounts: 1 13 
+
+minGini: 0.000000 - 1
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.000000 - 4
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 2.933333 - 1
+Region.size: 18
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 15
+RightChild.ClassCounts: 11 4 
+
+minGini: 2.636363 - 4
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.900000 - 2
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 10
+RightChild.ClassCounts: 9 1 
+
+minGini: 0.666666 - 0
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 111.272846 - 5
+Region.size: 650
+LeftChild.size: 177
+LeftChild.ClassCounts: 170 7 
+RightChild.size: 473
+RightChild.ClassCounts: 317 156 
+
+minGini: 93.080785 - 7
+Region.size: 473
+LeftChild.size: 239
+LeftChild.ClassCounts: 197 42 
+RightChild.size: 234
+RightChild.ClassCounts: 120 114 
+
+minGini: 55.821428 - 5
+Region.size: 234
+LeftChild.size: 192
+LeftChild.ClassCounts: 108 84 
+RightChild.size: 42
+RightChild.ClassCounts: 12 30 
+
+minGini: 6.450000 - 1
+Region.size: 42
+LeftChild.size: 22
+LeftChild.ClassCounts: 11 11 
+RightChild.size: 20
+RightChild.ClassCounts: 1 19 
+
+minGini: 0.833333 - 3
+Region.size: 20
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.277777 - 2
+Region.size: 22
+LeftChild.size: 18
+LeftChild.ClassCounts: 7 11 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.916666 - 6
+Region.size: 18
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 12
+RightChild.ClassCounts: 1 11 
+
+minGini: 0.000000 - 7
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 43.193208 - 1
+Region.size: 192
+LeftChild.size: 23
+LeftChild.ClassCounts: 22 1 
+RightChild.size: 169
+RightChild.ClassCounts: 86 83 
+
+minGini: 38.869848 - 6
+Region.size: 169
+LeftChild.size: 142
+LeftChild.ClassCounts: 81 61 
+RightChild.size: 27
+RightChild.ClassCounts: 5 22 
+
+minGini: 2.640000 - 1
+Region.size: 27
+LeftChild.size: 25
+LeftChild.ClassCounts: 3 22 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.150000 - 1
+Region.size: 25
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 20
+RightChild.ClassCounts: 1 19 
+
+minGini: 0.000000 - 4
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 19 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 33.798561 - 0
+Region.size: 142
+LeftChild.size: 139
+LeftChild.ClassCounts: 81 58 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 31.310028 - 7
+Region.size: 139
+LeftChild.size: 122
+LeftChild.ClassCounts: 65 57 
+RightChild.size: 17
+RightChild.ClassCounts: 16 1 
+
+minGini: 0.750000 - 1
+Region.size: 17
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 29.399209 - 7
+Region.size: 122
+LeftChild.size: 99
+LeftChild.ClassCounts: 57 42 
+RightChild.size: 23
+RightChild.ClassCounts: 8 15 
+
+minGini: 3.866071 - 2
+Region.size: 23
+LeftChild.size: 16
+LeftChild.ClassCounts: 3 13 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 1.200000 - 5
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.750000 - 4
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.714285 - 6
+Region.size: 16
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 22.868181 - 1
+Region.size: 99
+LeftChild.size: 55
+LeftChild.ClassCounts: 26 29 
+RightChild.size: 44
+RightChild.ClassCounts: 31 13 
+
+minGini: 7.698841 - 5
+Region.size: 44
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 5 
+RightChild.size: 37
+RightChild.ClassCounts: 29 8 
+
+minGini: 4.800000 - 5
+Region.size: 37
+LeftChild.size: 17
+LeftChild.ClassCounts: 17 0 
+RightChild.size: 20
+RightChild.ClassCounts: 12 8 
+
+minGini: 3.428571 - 4
+Region.size: 20
+LeftChild.size: 14
+LeftChild.ClassCounts: 6 8 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 2.400000 - 3
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 6 4 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.333333 - 0
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 3
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 11.713178 - 1
+Region.size: 55
+LeftChild.size: 12
+LeftChild.ClassCounts: 10 2 
+RightChild.size: 43
+RightChild.ClassCounts: 16 27 
+
+minGini: 8.307692 - 7
+Region.size: 43
+LeftChild.size: 39
+LeftChild.ClassCounts: 12 27 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 6.171428 - 2
+Region.size: 39
+LeftChild.size: 35
+LeftChild.ClassCounts: 8 27 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 3.351851 - 3
+Region.size: 35
+LeftChild.size: 27
+LeftChild.ClassCounts: 2 25 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.000000 - 3
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.000000 - 6
+Region.size: 27
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 23 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.666666 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.909090 - 2
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 10 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 6
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 0
+Region.size: 23
+LeftChild.size: 20
+LeftChild.ClassCounts: 20 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 31.855319 - 5
+Region.size: 239
+LeftChild.size: 235
+LeftChild.ClassCounts: 197 38 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 21.521974 - 2
+Region.size: 235
+LeftChild.size: 16
+LeftChild.ClassCounts: 1 15 
+RightChild.size: 219
+RightChild.ClassCounts: 196 23 
+
+minGini: 17.900269 - 6
+Region.size: 219
+LeftChild.size: 212
+LeftChild.ClassCounts: 194 18 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 
+
+minGini: 0.000000 - 4
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 16.006286 - 0
+Region.size: 212
+LeftChild.size: 46
+LeftChild.ClassCounts: 38 8 
+RightChild.size: 166
+RightChild.ClassCounts: 156 10 
+
+minGini: 9.094936 - 3
+Region.size: 166
+LeftChild.size: 158
+LeftChild.ClassCounts: 150 8 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.666666 - 2
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 7.307816 - 7
+Region.size: 158
+LeftChild.size: 86
+LeftChild.ClassCounts: 85 1 
+RightChild.size: 72
+RightChild.ClassCounts: 65 7 
+
+minGini: 5.988083 - 3
+Region.size: 72
+LeftChild.size: 19
+LeftChild.ClassCounts: 15 4 
+RightChild.size: 53
+RightChild.ClassCounts: 50 3 
+
+minGini: 1.923076 - 2
+Region.size: 53
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 52
+RightChild.ClassCounts: 50 2 
+
+minGini: 1.636363 - 0
+Region.size: 52
+LeftChild.size: 41
+LeftChild.ClassCounts: 41 0 
+RightChild.size: 11
+RightChild.ClassCounts: 9 2 
+
+minGini: 0.900000 - 4
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 2
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.545454 - 7
+Region.size: 19
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 11
+RightChild.ClassCounts: 7 4 
+
+minGini: 1.555555 - 6
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.200000 - 5
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.916666 - 7
+Region.size: 86
+LeftChild.size: 12
+LeftChild.ClassCounts: 11 1 
+RightChild.size: 74
+RightChild.ClassCounts: 74 0 
+
+minGini: 0.500000 - 3
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 5.181818 - 2
+Region.size: 46
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 44
+RightChild.ClassCounts: 38 6 
+
+minGini: 4.600000 - 2
+Region.size: 44
+LeftChild.size: 40
+LeftChild.ClassCounts: 36 4 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.714285 - 1
+Region.size: 40
+LeftChild.size: 33
+LeftChild.ClassCounts: 33 0 
+RightChild.size: 7
+RightChild.ClassCounts: 3 4 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 1
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 
+
+minGini: 6.405442 - 5
+Region.size: 177
+LeftChild.size: 147
+LeftChild.ClassCounts: 144 3 
+RightChild.size: 30
+RightChild.ClassCounts: 26 4 
+
+minGini: 2.545454 - 6
+Region.size: 30
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 11
+RightChild.ClassCounts: 7 4 
+
+minGini: 0.000000 - 3
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 2.843518 - 6
+Region.size: 147
+LeftChild.size: 120
+LeftChild.ClassCounts: 119 1 
+RightChild.size: 27
+RightChild.ClassCounts: 25 2 
+
+minGini: 1.428571 - 1
+Region.size: 27
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 
+
+minGini: 0.666666 - 4
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.800000 - 2
+Region.size: 120
+LeftChild.size: 115
+LeftChild.ClassCounts: 115 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 20 finished.
+
+minGini: 135.193127 - 1
+Region.size: 768
+LeftChild.size: 514
+LeftChild.ClassCounts: 416 98 
+RightChild.size: 254
+RightChild.ClassCounts: 83 171 
+
+minGini: 51.496229 - 7
+Region.size: 254
+LeftChild.size: 33
+LeftChild.ClassCounts: 22 11 
+RightChild.size: 221
+RightChild.ClassCounts: 61 160 
+
+minGini: 40.543802 - 1
+Region.size: 221
+LeftChild.size: 123
+LeftChild.ClassCounts: 48 75 
+RightChild.size: 98
+RightChild.ClassCounts: 13 85 
+
+minGini: 8.807239 - 7
+Region.size: 98
+LeftChild.size: 85
+LeftChild.ClassCounts: 6 79 
+RightChild.size: 13
+RightChild.ClassCounts: 7 6 
+
+minGini: 0.000000 - 1
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 5.056832 - 6
+Region.size: 85
+LeftChild.size: 27
+LeftChild.ClassCounts: 5 22 
+RightChild.size: 58
+RightChild.ClassCounts: 1 57 
+
+minGini: 0.833333 - 5
+Region.size: 58
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 52
+RightChild.ClassCounts: 0 52 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.384615 - 1
+Region.size: 27
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 26
+RightChild.ClassCounts: 4 22 
+
+minGini: 2.640000 - 6
+Region.size: 26
+LeftChild.size: 25
+LeftChild.ClassCounts: 3 22 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.833333 - 0
+Region.size: 25
+LeftChild.size: 24
+LeftChild.ClassCounts: 2 22 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.000000 - 0
+Region.size: 24
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 20
+RightChild.ClassCounts: 0 20 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 27.120951 - 0
+Region.size: 123
+LeftChild.size: 89
+LeftChild.ClassCounts: 42 47 
+RightChild.size: 34
+RightChild.ClassCounts: 6 28 
+
+minGini: 4.285714 - 4
+Region.size: 34
+LeftChild.size: 21
+LeftChild.ClassCounts: 6 15 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 3.157894 - 7
+Region.size: 21
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 19
+RightChild.ClassCounts: 4 15 
+
+minGini: 1.683333 - 1
+Region.size: 19
+LeftChild.size: 15
+LeftChild.ClassCounts: 1 14 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.666666 - 0
+Region.size: 15
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 20.307692 - 1
+Region.size: 89
+LeftChild.size: 50
+LeftChild.ClassCounts: 30 20 
+RightChild.size: 39
+RightChild.ClassCounts: 12 27 
+
+minGini: 6.338709 - 6
+Region.size: 39
+LeftChild.size: 31
+LeftChild.ClassCounts: 6 25 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.000000 - 3
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 2.000000 - 1
+Region.size: 31
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 22 
+RightChild.size: 9
+RightChild.ClassCounts: 6 3 
+
+minGini: 0.857142 - 2
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.000000 - 3
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 7.193347 - 0
+Region.size: 50
+LeftChild.size: 13
+LeftChild.ClassCounts: 1 12 
+RightChild.size: 37
+RightChild.ClassCounts: 29 8 
+
+minGini: 5.491176 - 6
+Region.size: 37
+LeftChild.size: 20
+LeftChild.ClassCounts: 13 7 
+RightChild.size: 17
+RightChild.ClassCounts: 16 1 
+
+minGini: 0.750000 - 3
+Region.size: 17
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.733333 - 3
+Region.size: 20
+LeftChild.size: 15
+LeftChild.ClassCounts: 13 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.928571 - 7
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 13 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.833333 - 6
+Region.size: 14
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 4
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 5.238095 - 3
+Region.size: 33
+LeftChild.size: 12
+LeftChild.ClassCounts: 4 8 
+RightChild.size: 21
+RightChild.ClassCounts: 18 3 
+
+minGini: 1.800000 - 6
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 18 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.947368 - 3
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 18 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.888888 - 2
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 7
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 73.814862 - 5
+Region.size: 514
+LeftChild.size: 147
+LeftChild.ClassCounts: 143 4 
+RightChild.size: 367
+RightChild.ClassCounts: 273 94 
+
+minGini: 65.843948 - 7
+Region.size: 367
+LeftChild.size: 177
+LeftChild.ClassCounts: 151 26 
+RightChild.size: 190
+RightChild.ClassCounts: 122 68 
+
+minGini: 38.652294 - 4
+Region.size: 190
+LeftChild.size: 158
+LeftChild.ClassCounts: 113 45 
+RightChild.size: 32
+RightChild.ClassCounts: 9 23 
+
+minGini: 5.366666 - 3
+Region.size: 32
+LeftChild.size: 30
+LeftChild.ClassCounts: 7 23 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 4.533333 - 0
+Region.size: 30
+LeftChild.size: 15
+LeftChild.ClassCounts: 1 14 
+RightChild.size: 15
+RightChild.ClassCounts: 6 9 
+
+minGini: 2.250000 - 7
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 12
+RightChild.ClassCounts: 3 9 
+
+minGini: 0.900000 - 6
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.666666 - 7
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.500000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 7
+Region.size: 15
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 29.784295 - 5
+Region.size: 158
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 
+RightChild.size: 151
+RightChild.ClassCounts: 112 39 
+
+minGini: 26.874920 - 0
+Region.size: 151
+LeftChild.size: 126
+LeftChild.ClassCounts: 100 26 
+RightChild.size: 25
+RightChild.ClassCounts: 12 13 
+
+minGini: 4.952380 - 2
+Region.size: 25
+LeftChild.size: 21
+LeftChild.ClassCounts: 8 13 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 3.733333 - 5
+Region.size: 21
+LeftChild.size: 15
+LeftChild.ClassCounts: 8 7 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 2.916666 - 4
+Region.size: 15
+LeftChild.size: 12
+LeftChild.ClassCounts: 5 7 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.555555 - 1
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 9
+RightChild.ClassCounts: 2 7 
+
+minGini: 0.875000 - 6
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.666666 - 6
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 19.805720 - 7
+Region.size: 126
+LeftChild.size: 109
+LeftChild.ClassCounts: 90 19 
+RightChild.size: 17
+RightChild.ClassCounts: 10 7 
+
+minGini: 2.857142 - 0
+Region.size: 17
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 14
+RightChild.ClassCounts: 10 4 
+
+minGini: 1.714285 - 5
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.750000 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 15.218816 - 0
+Region.size: 109
+LeftChild.size: 43
+LeftChild.ClassCounts: 39 4 
+RightChild.size: 66
+RightChild.ClassCounts: 51 15 
+
+minGini: 9.381818 - 5
+Region.size: 66
+LeftChild.size: 55
+LeftChild.ClassCounts: 47 8 
+RightChild.size: 11
+RightChild.ClassCounts: 4 7 
+
+minGini: 0.875000 - 0
+Region.size: 11
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.000000 - 3
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 6.456521 - 5
+Region.size: 55
+LeftChild.size: 9
+LeftChild.ClassCounts: 6 3 
+RightChild.size: 46
+RightChild.ClassCounts: 41 5 
+
+minGini: 3.516883 - 6
+Region.size: 46
+LeftChild.size: 11
+LeftChild.ClassCounts: 7 4 
+RightChild.size: 35
+RightChild.ClassCounts: 34 1 
+
+minGini: 0.000000 - 6
+Region.size: 35
+LeftChild.size: 34
+LeftChild.ClassCounts: 34 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.800000 - 7
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.666666 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 5
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 3.200000 - 3
+Region.size: 43
+LeftChild.size: 20
+LeftChild.ClassCounts: 16 4 
+RightChild.size: 23
+RightChild.ClassCounts: 23 0 
+
+minGini: 2.400000 - 6
+Region.size: 20
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 10
+RightChild.ClassCounts: 6 4 
+
+minGini: 1.333333 - 1
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 7
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.666666 - 1
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 19.369426 - 2
+Region.size: 177
+LeftChild.size: 157
+LeftChild.ClassCounts: 141 16 
+RightChild.size: 20
+RightChild.ClassCounts: 10 10 
+
+minGini: 2.307692 - 4
+Region.size: 20
+LeftChild.size: 13
+LeftChild.ClassCounts: 3 10 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 1.566666 - 3
+Region.size: 13
+LeftChild.size: 10
+LeftChild.ClassCounts: 1 9 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 6
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 13.399507 - 1
+Region.size: 157
+LeftChild.size: 70
+LeftChild.ClassCounts: 69 1 
+RightChild.size: 87
+RightChild.ClassCounts: 72 15 
+
+minGini: 11.337062 - 0
+Region.size: 87
+LeftChild.size: 22
+LeftChild.ClassCounts: 14 8 
+RightChild.size: 65
+RightChild.ClassCounts: 58 7 
+
+minGini: 5.909604 - 2
+Region.size: 65
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 59
+RightChild.ClassCounts: 54 5 
+
+minGini: 4.166666 - 1
+Region.size: 59
+LeftChild.size: 30
+LeftChild.ClassCounts: 25 5 
+RightChild.size: 29
+RightChild.ClassCounts: 29 0 
+
+minGini: 3.174603 - 0
+Region.size: 30
+LeftChild.size: 21
+LeftChild.ClassCounts: 20 1 
+RightChild.size: 9
+RightChild.ClassCounts: 5 4 
+
+minGini: 1.333333 - 5
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.800000 - 7
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.750000 - 6
+Region.size: 21
+LeftChild.size: 17
+LeftChild.ClassCounts: 17 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 3
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 4.000000 - 2
+Region.size: 22
+LeftChild.size: 16
+LeftChild.ClassCounts: 8 8 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 3.000000 - 4
+Region.size: 16
+LeftChild.size: 8
+LeftChild.ClassCounts: 2 6 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.000000 - 4
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.000000 - 3
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.666666 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.909090 - 7
+Region.size: 70
+LeftChild.size: 59
+LeftChild.ClassCounts: 59 0 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.500000 - 1
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.638888 - 0
+Region.size: 147
+LeftChild.size: 144
+LeftChild.ClassCounts: 142 2 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.826086 - 7
+Region.size: 144
+LeftChild.size: 138
+LeftChild.ClassCounts: 137 1 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.980392 - 0
+Region.size: 138
+LeftChild.size: 87
+LeftChild.ClassCounts: 87 0 
+RightChild.size: 51
+RightChild.ClassCounts: 50 1 
+
+minGini: 0.857142 - 7
+Region.size: 51
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 44
+RightChild.ClassCounts: 44 0 
+
+minGini: 0.666666 - 4
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 21 finished.
+
+minGini: 134.815296 - 1
+Region.size: 768
+LeftChild.size: 523
+LeftChild.ClassCounts: 411 112 
+RightChild.size: 245
+RightChild.ClassCounts: 63 182 
+
+minGini: 34.479487 - 5
+Region.size: 245
+LeftChild.size: 50
+LeftChild.ClassCounts: 35 15 
+RightChild.size: 195
+RightChild.ClassCounts: 28 167 
+
+minGini: 22.389937 - 7
+Region.size: 195
+LeftChild.size: 36
+LeftChild.ClassCounts: 12 24 
+RightChild.size: 159
+RightChild.ClassCounts: 16 143 
+
+minGini: 13.868095 - 2
+Region.size: 159
+LeftChild.size: 75
+LeftChild.ClassCounts: 3 72 
+RightChild.size: 84
+RightChild.ClassCounts: 13 71 
+
+minGini: 8.765432 - 0
+Region.size: 84
+LeftChild.size: 81
+LeftChild.ClassCounts: 10 71 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 7.620184 - 6
+Region.size: 81
+LeftChild.size: 22
+LeftChild.ClassCounts: 7 15 
+RightChild.size: 59
+RightChild.ClassCounts: 3 56 
+
+minGini: 2.677272 - 1
+Region.size: 59
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 55
+RightChild.ClassCounts: 2 53 
+
+minGini: 1.750000 - 5
+Region.size: 55
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 39 
+RightChild.size: 16
+RightChild.ClassCounts: 2 14 
+
+minGini: 0.000000 - 4
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.750000 - 0
+Region.size: 22
+LeftChild.size: 20
+LeftChild.ClassCounts: 5 15 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.916666 - 1
+Region.size: 20
+LeftChild.size: 12
+LeftChild.ClassCounts: 5 7 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 2.100000 - 7
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 10
+RightChild.ClassCounts: 3 7 
+
+minGini: 1.200000 - 2
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.666666 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.769230 - 2
+Region.size: 75
+LeftChild.size: 39
+LeftChild.ClassCounts: 3 36 
+RightChild.size: 36
+RightChild.ClassCounts: 0 36 
+
+minGini: 1.894736 - 3
+Region.size: 39
+LeftChild.size: 38
+LeftChild.ClassCounts: 2 36 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.600000 - 7
+Region.size: 38
+LeftChild.size: 10
+LeftChild.ClassCounts: 2 8 
+RightChild.size: 28
+RightChild.ClassCounts: 0 28 
+
+minGini: 0.888888 - 0
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 2
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 6.545454 - 3
+Region.size: 36
+LeftChild.size: 25
+LeftChild.ClassCounts: 5 20 
+RightChild.size: 11
+RightChild.ClassCounts: 7 4 
+
+minGini: 0.875000 - 6
+Region.size: 11
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.750000 - 4
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.750000 - 4
+Region.size: 25
+LeftChild.size: 20
+LeftChild.ClassCounts: 1 19 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.833333 - 2
+Region.size: 20
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 8.686371 - 4
+Region.size: 50
+LeftChild.size: 29
+LeftChild.ClassCounts: 25 4 
+RightChild.size: 21
+RightChild.ClassCounts: 10 11 
+
+minGini: 1.692307 - 1
+Region.size: 21
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 13
+RightChild.ClassCounts: 2 11 
+
+minGini: 1.333333 - 3
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.840000 - 1
+Region.size: 29
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 25
+RightChild.ClassCounts: 23 2 
+
+minGini: 1.621212 - 1
+Region.size: 25
+LeftChild.size: 22
+LeftChild.ClassCounts: 21 1 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.875000 - 2
+Region.size: 22
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 79.461981 - 0
+Region.size: 523
+LeftChild.size: 399
+LeftChild.ClassCounts: 342 57 
+RightChild.size: 124
+RightChild.ClassCounts: 69 55 
+
+minGini: 24.983687 - 5
+Region.size: 124
+LeftChild.size: 30
+LeftChild.ClassCounts: 28 2 
+RightChild.size: 94
+RightChild.ClassCounts: 41 53 
+
+minGini: 21.678160 - 2
+Region.size: 94
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 87
+RightChild.ClassCounts: 41 46 
+
+minGini: 18.871794 - 7
+Region.size: 87
+LeftChild.size: 78
+LeftChild.ClassCounts: 32 46 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 16.260380 - 6
+Region.size: 78
+LeftChild.size: 49
+LeftChild.ClassCounts: 27 22 
+RightChild.size: 29
+RightChild.ClassCounts: 5 24 
+
+minGini: 3.611111 - 6
+Region.size: 29
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 18
+RightChild.ClassCounts: 5 13 
+
+minGini: 2.222222 - 6
+Region.size: 18
+LeftChild.size: 9
+LeftChild.ClassCounts: 5 4 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 0.800000 - 2
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.500000 - 7
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 9.774774 - 7
+Region.size: 49
+LeftChild.size: 12
+LeftChild.ClassCounts: 2 10 
+RightChild.size: 37
+RightChild.ClassCounts: 25 12 
+
+minGini: 5.917647 - 1
+Region.size: 37
+LeftChild.size: 20
+LeftChild.ClassCounts: 18 2 
+RightChild.size: 17
+RightChild.ClassCounts: 7 10 
+
+minGini: 3.750000 - 3
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 6 10 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.307692 - 5
+Region.size: 16
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 13
+RightChild.ClassCounts: 3 10 
+
+minGini: 1.666666 - 2
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 12
+RightChild.ClassCounts: 2 10 
+
+minGini: 1.400000 - 7
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 1 9 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 4
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.947368 - 0
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 18 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.833333 - 6
+Region.size: 19
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 3
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.500000 - 7
+Region.size: 30
+LeftChild.size: 8
+LeftChild.ClassCounts: 6 2 
+RightChild.size: 22
+RightChild.ClassCounts: 22 0 
+
+minGini: 1.000000 - 5
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 45.478286 - 5
+Region.size: 399
+LeftChild.size: 169
+LeftChild.ClassCounts: 163 6 
+RightChild.size: 230
+RightChild.ClassCounts: 179 51 
+
+minGini: 36.514728 - 6
+Region.size: 230
+LeftChild.size: 215
+LeftChild.ClassCounts: 174 41 
+RightChild.size: 15
+RightChild.ClassCounts: 5 10 
+
+minGini: 2.500000 - 3
+Region.size: 15
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 10
+RightChild.ClassCounts: 5 5 
+
+minGini: 1.428571 - 0
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.666666 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 30.919480 - 1
+Region.size: 215
+LeftChild.size: 105
+LeftChild.ClassCounts: 96 9 
+RightChild.size: 110
+RightChild.ClassCounts: 78 32 
+
+minGini: 20.483104 - 4
+Region.size: 110
+LeftChild.size: 49
+LeftChild.ClassCounts: 27 22 
+RightChild.size: 61
+RightChild.ClassCounts: 51 10 
+
+minGini: 6.897435 - 6
+Region.size: 61
+LeftChild.size: 48
+LeftChild.ClassCounts: 44 4 
+RightChild.size: 13
+RightChild.ClassCounts: 7 6 
+
+minGini: 2.100000 - 6
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 10
+RightChild.ClassCounts: 7 3 
+
+minGini: 0.875000 - 4
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.000000 - 4
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.913043 - 2
+Region.size: 48
+LeftChild.size: 46
+LeftChild.ClassCounts: 44 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.428571 - 0
+Region.size: 46
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 39
+RightChild.ClassCounts: 39 0 
+
+minGini: 0.833333 - 3
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 3
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 10.744186 - 3
+Region.size: 49
+LeftChild.size: 43
+LeftChild.ClassCounts: 21 22 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 9.660606 - 3
+Region.size: 43
+LeftChild.size: 33
+LeftChild.ClassCounts: 19 14 
+RightChild.size: 10
+RightChild.ClassCounts: 2 8 
+
+minGini: 0.888888 - 2
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 
+
+minGini: 0.000000 - 5
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 7.000000 - 3
+Region.size: 33
+LeftChild.size: 28
+LeftChild.ClassCounts: 14 14 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 5.478260 - 2
+Region.size: 28
+LeftChild.size: 23
+LeftChild.ClassCounts: 9 14 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 3.111111 - 1
+Region.size: 23
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 18
+RightChild.ClassCounts: 4 14 
+
+minGini: 2.470588 - 5
+Region.size: 18
+LeftChild.size: 17
+LeftChild.ClassCounts: 3 14 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.100000 - 7
+Region.size: 17
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 10
+RightChild.ClassCounts: 3 7 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 6.524271 - 5
+Region.size: 105
+LeftChild.size: 103
+LeftChild.ClassCounts: 96 7 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 6.143564 - 7
+Region.size: 103
+LeftChild.size: 101
+LeftChild.ClassCounts: 95 6 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 5.307368 - 6
+Region.size: 101
+LeftChild.size: 25
+LeftChild.ClassCounts: 21 4 
+RightChild.size: 76
+RightChild.ClassCounts: 74 2 
+
+minGini: 1.857142 - 1
+Region.size: 76
+LeftChild.size: 48
+LeftChild.ClassCounts: 48 0 
+RightChild.size: 28
+RightChild.ClassCounts: 26 2 
+
+minGini: 1.428571 - 6
+Region.size: 28
+LeftChild.size: 21
+LeftChild.ClassCounts: 21 0 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.833333 - 4
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.954545 - 6
+Region.size: 25
+LeftChild.size: 22
+LeftChild.ClassCounts: 21 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.750000 - 6
+Region.size: 22
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 18
+RightChild.ClassCounts: 18 0 
+
+minGini: 0.500000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.499782 - 5
+Region.size: 169
+LeftChild.size: 135
+LeftChild.ClassCounts: 133 2 
+RightChild.size: 34
+RightChild.ClassCounts: 30 4 
+
+minGini: 1.333333 - 7
+Region.size: 34
+LeftChild.size: 28
+LeftChild.ClassCounts: 28 0 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.882352 - 0
+Region.size: 135
+LeftChild.size: 101
+LeftChild.ClassCounts: 101 0 
+RightChild.size: 34
+RightChild.ClassCounts: 32 2 
+
+minGini: 1.600000 - 7
+Region.size: 34
+LeftChild.size: 10
+LeftChild.ClassCounts: 8 2 
+RightChild.size: 24
+RightChild.ClassCounts: 24 0 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 22 finished.
+
+minGini: 142.954703 - 1
+Region.size: 768
+LeftChild.size: 656
+LeftChild.ClassCounts: 482 174 
+RightChild.size: 112
+RightChild.ClassCounts: 18 94 
+
+minGini: 14.468085 - 4
+Region.size: 112
+LeftChild.size: 94
+LeftChild.ClassCounts: 12 82 
+RightChild.size: 18
+RightChild.ClassCounts: 6 12 
+
+minGini: 1.714285 - 3
+Region.size: 18
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 14
+RightChild.ClassCounts: 2 12 
+
+minGini: 0.666666 - 6
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 7.865353 - 7
+Region.size: 94
+LeftChild.size: 87
+LeftChild.ClassCounts: 7 80 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 5.971291 - 5
+Region.size: 87
+LeftChild.size: 11
+LeftChild.ClassCounts: 3 8 
+RightChild.size: 76
+RightChild.ClassCounts: 4 72 
+
+minGini: 2.880000 - 6
+Region.size: 76
+LeftChild.size: 75
+LeftChild.ClassCounts: 3 72 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.611111 - 3
+Region.size: 75
+LeftChild.size: 72
+LeftChild.ClassCounts: 2 70 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.809523 - 1
+Region.size: 72
+LeftChild.size: 21
+LeftChild.ClassCounts: 2 19 
+RightChild.size: 51
+RightChild.ClassCounts: 0 51 
+
+minGini: 1.000000 - 4
+Region.size: 21
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 17 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.875000 - 3
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.500000 - 1
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 118.623723 - 0
+Region.size: 656
+LeftChild.size: 465
+LeftChild.ClassCounts: 377 88 
+RightChild.size: 191
+RightChild.ClassCounts: 105 86 
+
+minGini: 42.548288 - 6
+Region.size: 191
+LeftChild.size: 121
+LeftChild.ClassCounts: 81 40 
+RightChild.size: 70
+RightChild.ClassCounts: 24 46 
+
+minGini: 13.714285 - 4
+Region.size: 70
+LeftChild.size: 35
+LeftChild.ClassCounts: 6 29 
+RightChild.size: 35
+RightChild.ClassCounts: 18 17 
+
+minGini: 6.536231 - 5
+Region.size: 35
+LeftChild.size: 23
+LeftChild.ClassCounts: 16 7 
+RightChild.size: 12
+RightChild.ClassCounts: 2 10 
+
+minGini: 0.909090 - 5
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 0
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.300000 - 4
+Region.size: 23
+LeftChild.size: 18
+LeftChild.ClassCounts: 15 3 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.937500 - 6
+Region.size: 18
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 16
+RightChild.ClassCounts: 15 1 
+
+minGini: 0.800000 - 4
+Region.size: 16
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 4.166666 - 3
+Region.size: 35
+LeftChild.size: 14
+LeftChild.ClassCounts: 5 9 
+RightChild.size: 21
+RightChild.ClassCounts: 1 20 
+
+minGini: 0.857142 - 0
+Region.size: 21
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.900000 - 1
+Region.size: 14
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.666666 - 1
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.500000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 25.994909 - 4
+Region.size: 121
+LeftChild.size: 104
+LeftChild.ClassCounts: 73 31 
+RightChild.size: 17
+RightChild.ClassCounts: 8 9 
+
+minGini: 2.957142 - 4
+Region.size: 17
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 
+RightChild.size: 10
+RightChild.ClassCounts: 7 3 
+
+minGini: 0.000000 - 2
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 20.194430 - 5
+Region.size: 104
+LeftChild.size: 25
+LeftChild.ClassCounts: 23 2 
+RightChild.size: 79
+RightChild.ClassCounts: 50 29 
+
+minGini: 14.551724 - 7
+Region.size: 79
+LeftChild.size: 29
+LeftChild.ClassCounts: 10 19 
+RightChild.size: 50
+RightChild.ClassCounts: 40 10 
+
+minGini: 7.111111 - 2
+Region.size: 50
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 45
+RightChild.ClassCounts: 38 7 
+
+minGini: 5.468750 - 3
+Region.size: 45
+LeftChild.size: 32
+LeftChild.ClassCounts: 25 7 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 3.268571 - 1
+Region.size: 32
+LeftChild.size: 25
+LeftChild.ClassCounts: 23 2 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.456521 - 0
+Region.size: 25
+LeftChild.size: 23
+LeftChild.ClassCounts: 22 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.833333 - 1
+Region.size: 23
+LeftChild.size: 17
+LeftChild.ClassCounts: 17 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.666666 - 7
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.115384 - 4
+Region.size: 29
+LeftChild.size: 26
+LeftChild.ClassCounts: 7 19 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 2.590909 - 2
+Region.size: 26
+LeftChild.size: 22
+LeftChild.ClassCounts: 3 19 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 1.614035 - 7
+Region.size: 22
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 19
+RightChild.ClassCounts: 1 18 
+
+minGini: 0.000000 - 1
+Region.size: 19
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 18
+RightChild.ClassCounts: 0 18 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.555555 - 0
+Region.size: 25
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 62.449696 - 1
+Region.size: 465
+LeftChild.size: 300
+LeftChild.ClassCounts: 274 26 
+RightChild.size: 165
+RightChild.ClassCounts: 103 62 
+
+minGini: 35.515517 - 2
+Region.size: 165
+LeftChild.size: 20
+LeftChild.ClassCounts: 5 15 
+RightChild.size: 145
+RightChild.ClassCounts: 98 47 
+
+minGini: 26.682828 - 7
+Region.size: 145
+LeftChild.size: 90
+LeftChild.ClassCounts: 74 16 
+RightChild.size: 55
+RightChild.ClassCounts: 24 31 
+
+minGini: 10.430107 - 0
+Region.size: 55
+LeftChild.size: 24
+LeftChild.ClassCounts: 4 20 
+RightChild.size: 31
+RightChild.ClassCounts: 20 11 
+
+minGini: 5.393333 - 6
+Region.size: 31
+LeftChild.size: 25
+LeftChild.ClassCounts: 19 6 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 3.433333 - 5
+Region.size: 25
+LeftChild.size: 15
+LeftChild.ClassCounts: 14 1 
+RightChild.size: 10
+RightChild.ClassCounts: 5 5 
+
+minGini: 1.875000 - 4
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.833333 - 7
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 0.952380 - 5
+Region.size: 24
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 21
+RightChild.ClassCounts: 1 20 
+
+minGini: 0.000000 - 5
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 20 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 8.887195 - 5
+Region.size: 90
+LeftChild.size: 82
+LeftChild.ClassCounts: 73 9 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.500000 - 6
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 7.503030 - 0
+Region.size: 82
+LeftChild.size: 55
+LeftChild.ClassCounts: 52 3 
+RightChild.size: 27
+RightChild.ClassCounts: 21 6 
+
+minGini: 3.428571 - 5
+Region.size: 27
+LeftChild.size: 14
+LeftChild.ClassCounts: 8 6 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 1.600000 - 3
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 8 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.000000 - 5
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.589743 - 6
+Region.size: 55
+LeftChild.size: 52
+LeftChild.ClassCounts: 50 2 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.857142 - 2
+Region.size: 52
+LeftChild.size: 28
+LeftChild.ClassCounts: 26 2 
+RightChild.size: 24
+RightChild.ClassCounts: 24 0 
+
+minGini: 1.200000 - 7
+Region.size: 28
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.916666 - 5
+Region.size: 20
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 11 
+RightChild.size: 8
+RightChild.ClassCounts: 4 4 
+
+minGini: 0.800000 - 6
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.500000 - 5
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 23.351720 - 6
+Region.size: 300
+LeftChild.size: 269
+LeftChild.ClassCounts: 249 20 
+RightChild.size: 31
+RightChild.ClassCounts: 25 6 
+
+minGini: 4.200000 - 4
+Region.size: 31
+LeftChild.size: 20
+LeftChild.ClassCounts: 14 6 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 3.131313 - 2
+Region.size: 20
+LeftChild.size: 9
+LeftChild.ClassCounts: 4 5 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.000000 - 5
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 0.000000 - 1
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 16.786516 - 5
+Region.size: 269
+LeftChild.size: 267
+LeftChild.ClassCounts: 249 18 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 16.418082 - 3
+Region.size: 267
+LeftChild.size: 58
+LeftChild.ClassCounts: 50 8 
+RightChild.size: 209
+RightChild.ClassCounts: 199 10 
+
+minGini: 9.135910 - 0
+Region.size: 209
+LeftChild.size: 148
+LeftChild.ClassCounts: 145 3 
+RightChild.size: 61
+RightChild.ClassCounts: 54 7 
+
+minGini: 5.400000 - 5
+Region.size: 61
+LeftChild.size: 60
+LeftChild.ClassCounts: 54 6 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.133333 - 5
+Region.size: 60
+LeftChild.size: 30
+LeftChild.ClassCounts: 29 1 
+RightChild.size: 30
+RightChild.ClassCounts: 25 5 
+
+minGini: 2.670807 - 5
+Region.size: 30
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 
+RightChild.size: 23
+RightChild.ClassCounts: 22 1 
+
+minGini: 0.833333 - 3
+Region.size: 23
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 17
+RightChild.ClassCounts: 17 0 
+
+minGini: 0.666666 - 5
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.750000 - 3
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.916666 - 3
+Region.size: 30
+LeftChild.size: 12
+LeftChild.ClassCounts: 11 1 
+RightChild.size: 18
+RightChild.ClassCounts: 18 0 
+
+minGini: 0.666666 - 5
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.820000 - 5
+Region.size: 148
+LeftChild.size: 98
+LeftChild.ClassCounts: 98 0 
+RightChild.size: 50
+RightChild.ClassCounts: 47 3 
+
+minGini: 2.720588 - 1
+Region.size: 50
+LeftChild.size: 16
+LeftChild.ClassCounts: 14 2 
+RightChild.size: 34
+RightChild.ClassCounts: 33 1 
+
+minGini: 0.833333 - 7
+Region.size: 34
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 28
+RightChild.ClassCounts: 28 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 3
+Region.size: 16
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 5.252777 - 5
+Region.size: 58
+LeftChild.size: 40
+LeftChild.ClassCounts: 39 1 
+RightChild.size: 18
+RightChild.ClassCounts: 11 7 
+
+minGini: 0.916666 - 2
+Region.size: 18
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 12
+RightChild.ClassCounts: 11 1 
+
+minGini: 0.500000 - 1
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.923076 - 5
+Region.size: 40
+LeftChild.size: 27
+LeftChild.ClassCounts: 27 0 
+RightChild.size: 13
+RightChild.ClassCounts: 12 1 
+
+minGini: 0.000000 - 7
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 23 finished.
+
+minGini: 137.952922 - 1
+Region.size: 768
+LeftChild.size: 504
+LeftChild.ClassCounts: 408 96 
+RightChild.size: 264
+RightChild.ClassCounts: 93 171 
+
+minGini: 53.053721 - 5
+Region.size: 264
+LeftChild.size: 68
+LeftChild.ClassCounts: 43 25 
+RightChild.size: 196
+RightChild.ClassCounts: 50 146 
+
+minGini: 36.095238 - 5
+Region.size: 196
+LeftChild.size: 175
+LeftChild.ClassCounts: 40 135 
+RightChild.size: 21
+RightChild.ClassCounts: 10 11 
+
+minGini: 3.644230 - 5
+Region.size: 21
+LeftChild.size: 13
+LeftChild.ClassCounts: 9 4 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.000000 - 7
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 1.636363 - 0
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.900000 - 4
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 6
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 29.869281 - 5
+Region.size: 175
+LeftChild.size: 85
+LeftChild.ClassCounts: 26 59 
+RightChild.size: 90
+RightChild.ClassCounts: 14 76 
+
+minGini: 9.609195 - 3
+Region.size: 90
+LeftChild.size: 87
+LeftChild.ClassCounts: 11 76 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 7.978915 - 6
+Region.size: 87
+LeftChild.size: 83
+LeftChild.ClassCounts: 8 75 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 6.476190 - 1
+Region.size: 83
+LeftChild.size: 42
+LeftChild.ClassCounts: 8 34 
+RightChild.size: 41
+RightChild.ClassCounts: 0 41 
+
+minGini: 5.257142 - 6
+Region.size: 42
+LeftChild.size: 7
+LeftChild.ClassCounts: 4 3 
+RightChild.size: 35
+RightChild.ClassCounts: 4 31 
+
+minGini: 2.735294 - 0
+Region.size: 35
+LeftChild.size: 34
+LeftChild.ClassCounts: 3 31 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.875000 - 2
+Region.size: 34
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 26 
+RightChild.size: 8
+RightChild.ClassCounts: 3 5 
+
+minGini: 1.200000 - 5
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.750000 - 6
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.500000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 16.286666 - 5
+Region.size: 85
+LeftChild.size: 75
+LeftChild.ClassCounts: 19 56 
+RightChild.size: 10
+RightChild.ClassCounts: 7 3 
+
+minGini: 1.555555 - 1
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 7 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 7
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 12.070668 - 6
+Region.size: 75
+LeftChild.size: 47
+LeftChild.ClassCounts: 18 29 
+RightChild.size: 28
+RightChild.ClassCounts: 1 27 
+
+minGini: 0.000000 - 4
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 27 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 8.950191 - 6
+Region.size: 47
+LeftChild.size: 18
+LeftChild.ClassCounts: 2 16 
+RightChild.size: 29
+RightChild.ClassCounts: 16 13 
+
+minGini: 5.318181 - 6
+Region.size: 29
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 22
+RightChild.ClassCounts: 9 13 
+
+minGini: 3.214285 - 4
+Region.size: 22
+LeftChild.size: 14
+LeftChild.ClassCounts: 9 5 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 1.428571 - 3
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 5 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.833333 - 6
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 3
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.333333 - 6
+Region.size: 18
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 
+
+minGini: 0.800000 - 5
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 14.065408 - 7
+Region.size: 68
+LeftChild.size: 53
+LeftChild.ClassCounts: 29 24 
+RightChild.size: 15
+RightChild.ClassCounts: 14 1 
+
+minGini: 0.666666 - 1
+Region.size: 15
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 11.744680 - 6
+Region.size: 53
+LeftChild.size: 47
+LeftChild.ClassCounts: 23 24 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 9.088095 - 1
+Region.size: 47
+LeftChild.size: 35
+LeftChild.ClassCounts: 22 13 
+RightChild.size: 12
+RightChild.ClassCounts: 1 11 
+
+minGini: 0.500000 - 5
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 6.964285 - 0
+Region.size: 35
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 28
+RightChild.ClassCounts: 15 13 
+
+minGini: 6.240000 - 1
+Region.size: 28
+LeftChild.size: 25
+LeftChild.ClassCounts: 12 13 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 5.142857 - 2
+Region.size: 25
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 21
+RightChild.ClassCounts: 12 9 
+
+minGini: 4.237500 - 3
+Region.size: 21
+LeftChild.size: 16
+LeftChild.ClassCounts: 11 5 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 2.233333 - 6
+Region.size: 16
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.750000 - 7
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.500000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 73.553411 - 1
+Region.size: 504
+LeftChild.size: 230
+LeftChild.ClassCounts: 209 21 
+RightChild.size: 274
+RightChild.ClassCounts: 199 75 
+
+minGini: 50.146156 - 5
+Region.size: 274
+LeftChild.size: 59
+LeftChild.ClassCounts: 57 2 
+RightChild.size: 215
+RightChild.ClassCounts: 142 73 
+
+minGini: 45.951169 - 4
+Region.size: 215
+LeftChild.size: 124
+LeftChild.ClassCounts: 71 53 
+RightChild.size: 91
+RightChild.ClassCounts: 71 20 
+
+minGini: 14.036036 - 6
+Region.size: 91
+LeftChild.size: 54
+LeftChild.ClassCounts: 48 6 
+RightChild.size: 37
+RightChild.ClassCounts: 23 14 
+
+minGini: 4.974074 - 0
+Region.size: 37
+LeftChild.size: 27
+LeftChild.ClassCounts: 22 5 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.000000 - 3
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.018181 - 6
+Region.size: 27
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 22
+RightChild.ClassCounts: 20 2 
+
+minGini: 1.200000 - 4
+Region.size: 22
+LeftChild.size: 17
+LeftChild.ClassCounts: 17 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 3.570000 - 6
+Region.size: 54
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 50
+RightChild.ClassCounts: 47 3 
+
+minGini: 1.918367 - 0
+Region.size: 50
+LeftChild.size: 49
+LeftChild.ClassCounts: 47 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.833333 - 6
+Region.size: 49
+LeftChild.size: 42
+LeftChild.ClassCounts: 41 1 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.000000 - 4
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.833333 - 2
+Region.size: 42
+LeftChild.size: 36
+LeftChild.ClassCounts: 36 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 24.733862 - 5
+Region.size: 124
+LeftChild.size: 70
+LeftChild.ClassCounts: 27 43 
+RightChild.size: 54
+RightChild.ClassCounts: 44 10 
+
+minGini: 6.769230 - 6
+Region.size: 54
+LeftChild.size: 52
+LeftChild.ClassCounts: 44 8 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 5.280000 - 4
+Region.size: 52
+LeftChild.size: 50
+LeftChild.ClassCounts: 44 6 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 4.661122 - 2
+Region.size: 50
+LeftChild.size: 13
+LeftChild.ClassCounts: 9 4 
+RightChild.size: 37
+RightChild.ClassCounts: 35 2 
+
+minGini: 1.555555 - 5
+Region.size: 37
+LeftChild.size: 28
+LeftChild.ClassCounts: 28 0 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.800000 - 7
+Region.size: 13
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 15.030000 - 5
+Region.size: 70
+LeftChild.size: 50
+LeftChild.ClassCounts: 24 26 
+RightChild.size: 20
+RightChild.ClassCounts: 3 17 
+
+minGini: 1.789473 - 6
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 2 17 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.944444 - 2
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 1 17 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.500000 - 4
+Region.size: 18
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 10.867132 - 7
+Region.size: 50
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 39
+RightChild.ClassCounts: 15 24 
+
+minGini: 6.350649 - 6
+Region.size: 39
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 28
+RightChild.ClassCounts: 6 22 
+
+minGini: 2.626086 - 0
+Region.size: 28
+LeftChild.size: 23
+LeftChild.ClassCounts: 2 21 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.954545 - 3
+Region.size: 23
+LeftChild.size: 22
+LeftChild.ClassCounts: 1 21 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 6
+Region.size: 22
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.900000 - 1
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 7
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.333333 - 5
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.800000 - 7
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.781481 - 7
+Region.size: 59
+LeftChild.size: 54
+LeftChild.ClassCounts: 53 1 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.833333 - 5
+Region.size: 54
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 48
+RightChild.ClassCounts: 48 0 
+
+minGini: 0.666666 - 1
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 17.166153 - 5
+Region.size: 230
+LeftChild.size: 199
+LeftChild.ClassCounts: 188 11 
+RightChild.size: 31
+RightChild.ClassCounts: 21 10 
+
+minGini: 5.442982 - 4
+Region.size: 31
+LeftChild.size: 19
+LeftChild.ClassCounts: 16 3 
+RightChild.size: 12
+RightChild.ClassCounts: 5 7 
+
+minGini: 2.100000 - 7
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 10
+RightChild.ClassCounts: 3 7 
+
+minGini: 1.555555 - 3
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 9
+RightChild.ClassCounts: 2 7 
+
+minGini: 0.875000 - 2
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 1.933333 - 7
+Region.size: 19
+LeftChild.size: 15
+LeftChild.ClassCounts: 14 1 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.500000 - 0
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 8.588832 - 4
+Region.size: 199
+LeftChild.size: 197
+LeftChild.ClassCounts: 188 9 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 8.129032 - 7
+Region.size: 197
+LeftChild.size: 104
+LeftChild.ClassCounts: 104 0 
+RightChild.size: 93
+RightChild.ClassCounts: 84 9 
+
+minGini: 7.643181 - 2
+Region.size: 93
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 88
+RightChild.ClassCounts: 81 7 
+
+minGini: 6.057692 - 0
+Region.size: 88
+LeftChild.size: 52
+LeftChild.ClassCounts: 45 7 
+RightChild.size: 36
+RightChild.ClassCounts: 36 0 
+
+minGini: 4.859574 - 6
+Region.size: 52
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 47
+RightChild.ClassCounts: 43 4 
+
+minGini: 2.575757 - 7
+Region.size: 47
+LeftChild.size: 44
+LeftChild.ClassCounts: 42 2 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.830115 - 0
+Region.size: 44
+LeftChild.size: 37
+LeftChild.ClassCounts: 36 1 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.666666 - 2
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.875000 - 5
+Region.size: 37
+LeftChild.size: 29
+LeftChild.ClassCounts: 29 0 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.750000 - 7
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 4
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 24 finished.
+
+minGini: 149.863780 - 7
+Region.size: 768
+LeftChild.size: 417
+LeftChild.ClassCounts: 341 76 
+RightChild.size: 351
+RightChild.ClassCounts: 179 172 
+
+minGini: 81.363108 - 5
+Region.size: 351
+LeftChild.size: 110
+LeftChild.ClassCounts: 78 32 
+RightChild.size: 241
+RightChild.ClassCounts: 101 140 
+
+minGini: 53.971864 - 4
+Region.size: 241
+LeftChild.size: 174
+LeftChild.ClassCounts: 88 86 
+RightChild.size: 67
+RightChild.ClassCounts: 13 54 
+
+minGini: 9.138461 - 7
+Region.size: 67
+LeftChild.size: 65
+LeftChild.ClassCounts: 11 54 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 6.196721 - 3
+Region.size: 65
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 61
+RightChild.ClassCounts: 7 54 
+
+minGini: 5.365454 - 3
+Region.size: 61
+LeftChild.size: 50
+LeftChild.ClassCounts: 3 47 
+RightChild.size: 11
+RightChild.ClassCounts: 4 7 
+
+minGini: 2.000000 - 5
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 4 4 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.800000 - 0
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.500000 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.310606 - 7
+Region.size: 50
+LeftChild.size: 44
+LeftChild.ClassCounts: 1 43 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.000000 - 7
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.909090 - 4
+Region.size: 44
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 33 
+RightChild.size: 11
+RightChild.ClassCounts: 1 10 
+
+minGini: 0.000000 - 5
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 38.513960 - 4
+Region.size: 174
+LeftChild.size: 135
+LeftChild.ClassCounts: 56 79 
+RightChild.size: 39
+RightChild.ClassCounts: 32 7 
+
+minGini: 5.040000 - 4
+Region.size: 39
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 
+RightChild.size: 25
+RightChild.ClassCounts: 18 7 
+
+minGini: 2.622807 - 3
+Region.size: 25
+LeftChild.size: 19
+LeftChild.ClassCounts: 17 2 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.200000 - 3
+Region.size: 19
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 31.173715 - 6
+Region.size: 135
+LeftChild.size: 106
+LeftChild.ClassCounts: 50 56 
+RightChild.size: 29
+RightChild.ClassCounts: 6 23 
+
+minGini: 3.407407 - 2
+Region.size: 29
+LeftChild.size: 27
+LeftChild.ClassCounts: 4 23 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.500000 - 2
+Region.size: 27
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 24
+RightChild.ClassCounts: 2 22 
+
+minGini: 1.428571 - 5
+Region.size: 24
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 17 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 
+
+minGini: 0.000000 - 7
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 18.396212 - 1
+Region.size: 106
+LeftChild.size: 40
+LeftChild.ClassCounts: 33 7 
+RightChild.size: 66
+RightChild.ClassCounts: 17 49 
+
+minGini: 11.392241 - 7
+Region.size: 66
+LeftChild.size: 58
+LeftChild.ClassCounts: 12 46 
+RightChild.size: 8
+RightChild.ClassCounts: 5 3 
+
+minGini: 0.750000 - 6
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 8.217391 - 2
+Region.size: 58
+LeftChild.size: 46
+LeftChild.ClassCounts: 6 40 
+RightChild.size: 12
+RightChild.ClassCounts: 6 6 
+
+minGini: 2.228571 - 7
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 
+
+minGini: 0.666666 - 7
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 4.666666 - 1
+Region.size: 46
+LeftChild.size: 27
+LeftChild.ClassCounts: 6 21 
+RightChild.size: 19
+RightChild.ClassCounts: 0 19 
+
+minGini: 4.250000 - 7
+Region.size: 27
+LeftChild.size: 15
+LeftChild.ClassCounts: 5 10 
+RightChild.size: 12
+RightChild.ClassCounts: 1 11 
+
+minGini: 0.000000 - 2
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.909090 - 7
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 2
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.550000 - 0
+Region.size: 40
+LeftChild.size: 20
+LeftChild.ClassCounts: 13 7 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 
+
+minGini: 1.733333 - 7
+Region.size: 20
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 15
+RightChild.ClassCounts: 13 2 
+
+minGini: 1.428571 - 6
+Region.size: 15
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 20.367436 - 6
+Region.size: 110
+LeftChild.size: 101
+LeftChild.ClassCounts: 76 25 
+RightChild.size: 9
+RightChild.ClassCounts: 2 7 
+
+minGini: 0.000000 - 7
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 17.175621 - 3
+Region.size: 101
+LeftChild.size: 43
+LeftChild.ClassCounts: 26 17 
+RightChild.size: 58
+RightChild.ClassCounts: 50 8 
+
+minGini: 6.140350 - 3
+Region.size: 58
+LeftChild.size: 57
+LeftChild.ClassCounts: 50 7 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.186274 - 5
+Region.size: 57
+LeftChild.size: 51
+LeftChild.ClassCounts: 47 4 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 
+
+minGini: 0.750000 - 3
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.500000 - 3
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.281376 - 7
+Region.size: 51
+LeftChild.size: 38
+LeftChild.ClassCounts: 37 1 
+RightChild.size: 13
+RightChild.ClassCounts: 10 3 
+
+minGini: 0.909090 - 7
+Region.size: 13
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.750000 - 7
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.833333 - 0
+Region.size: 38
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 32
+RightChild.ClassCounts: 32 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 9.189189 - 1
+Region.size: 43
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 37
+RightChild.ClassCounts: 20 17 
+
+minGini: 7.426724 - 1
+Region.size: 37
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 7 
+RightChild.size: 29
+RightChild.ClassCounts: 19 10 
+
+minGini: 4.736842 - 7
+Region.size: 29
+LeftChild.size: 19
+LeftChild.ClassCounts: 9 10 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 3.107142 - 1
+Region.size: 19
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 12
+RightChild.ClassCounts: 3 9 
+
+minGini: 0.750000 - 5
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 1
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 0
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 58.764563 - 0
+Region.size: 417
+LeftChild.size: 412
+LeftChild.ClassCounts: 341 71 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 55.998737 - 6
+Region.size: 412
+LeftChild.size: 324
+LeftChild.ClassCounts: 282 42 
+RightChild.size: 88
+RightChild.ClassCounts: 59 29 
+
+minGini: 14.287135 - 1
+Region.size: 88
+LeftChild.size: 67
+LeftChild.ClassCounts: 54 13 
+RightChild.size: 21
+RightChild.ClassCounts: 5 16 
+
+minGini: 3.214285 - 3
+Region.size: 21
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 14
+RightChild.ClassCounts: 5 9 
+
+minGini: 2.250000 - 5
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 12
+RightChild.ClassCounts: 3 9 
+
+minGini: 0.000000 - 1
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 9.596396 - 1
+Region.size: 67
+LeftChild.size: 30
+LeftChild.ClassCounts: 28 2 
+RightChild.size: 37
+RightChild.ClassCounts: 26 11 
+
+minGini: 7.000000 - 4
+Region.size: 37
+LeftChild.size: 12
+LeftChild.ClassCounts: 6 6 
+RightChild.size: 25
+RightChild.ClassCounts: 20 5 
+
+minGini: 2.500000 - 5
+Region.size: 25
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 
+RightChild.size: 10
+RightChild.ClassCounts: 5 5 
+
+minGini: 1.875000 - 6
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 8
+RightChild.ClassCounts: 5 3 
+
+minGini: 1.200000 - 3
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.666666 - 4
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.400000 - 5
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 4 6 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.583333 - 5
+Region.size: 10
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 3
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.428571 - 3
+Region.size: 30
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 1.200000 - 0
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 
+
+minGini: 0.666666 - 2
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 32.768814 - 2
+Region.size: 324
+LeftChild.size: 317
+LeftChild.ClassCounts: 281 36 
+RightChild.size: 7
+RightChild.ClassCounts: 1 6 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 30.027649 - 5
+Region.size: 317
+LeftChild.size: 100
+LeftChild.ClassCounts: 100 0 
+RightChild.size: 217
+RightChild.ClassCounts: 181 36 
+
+minGini: 28.952380 - 5
+Region.size: 217
+LeftChild.size: 196
+LeftChild.ClassCounts: 168 28 
+RightChild.size: 21
+RightChild.ClassCounts: 13 8 
+
+minGini: 3.666666 - 1
+Region.size: 21
+LeftChild.size: 12
+LeftChild.ClassCounts: 10 2 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 0.000000 - 5
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.909090 - 2
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.500000 - 3
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 21.049122 - 1
+Region.size: 196
+LeftChild.size: 190
+LeftChild.ClassCounts: 167 23 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.500000 - 5
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 18.270476 - 0
+Region.size: 190
+LeftChild.size: 175
+LeftChild.ClassCounts: 159 16 
+RightChild.size: 15
+RightChild.ClassCounts: 8 7 
+
+minGini: 2.545454 - 1
+Region.size: 15
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 11
+RightChild.ClassCounts: 4 7 
+
+minGini: 1.333333 - 2
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 13.706896 - 2
+Region.size: 175
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 174
+RightChild.ClassCounts: 159 15 
+
+minGini: 13.002421 - 1
+Region.size: 174
+LeftChild.size: 118
+LeftChild.ClassCounts: 113 5 
+RightChild.size: 56
+RightChild.ClassCounts: 46 10 
+
+minGini: 7.617391 - 6
+Region.size: 56
+LeftChild.size: 46
+LeftChild.ClassCounts: 40 6 
+RightChild.size: 10
+RightChild.ClassCounts: 6 4 
+
+minGini: 0.800000 - 1
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.288888 - 5
+Region.size: 46
+LeftChild.size: 10
+LeftChild.ClassCounts: 6 4 
+RightChild.size: 36
+RightChild.ClassCounts: 34 2 
+
+minGini: 1.428571 - 3
+Region.size: 36
+LeftChild.size: 29
+LeftChild.ClassCounts: 29 0 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.800000 - 7
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 3
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 4.690476 - 3
+Region.size: 118
+LeftChild.size: 112
+LeftChild.ClassCounts: 108 4 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 3.579797 - 2
+Region.size: 112
+LeftChild.size: 90
+LeftChild.ClassCounts: 89 1 
+RightChild.size: 22
+RightChild.ClassCounts: 19 3 
+
+minGini: 2.181818 - 7
+Region.size: 22
+LeftChild.size: 11
+LeftChild.ClassCounts: 8 3 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 1.500000 - 7
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.944444 - 6
+Region.size: 90
+LeftChild.size: 72
+LeftChild.ClassCounts: 72 0 
+RightChild.size: 18
+RightChild.ClassCounts: 17 1 
+
+minGini: 0.666666 - 1
+Region.size: 18
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 25 finished.
+
+minGini: 158.740483 - 5
+Region.size: 768
+LeftChild.size: 182
+LeftChild.ClassCounts: 168 14 
+RightChild.size: 586
+RightChild.ClassCounts: 313 273 
+
+minGini: 131.920645 - 7
+Region.size: 586
+LeftChild.size: 138
+LeftChild.ClassCounts: 112 26 
+RightChild.size: 448
+RightChild.ClassCounts: 201 247 
+
+minGini: 87.635033 - 1
+Region.size: 448
+LeftChild.size: 212
+LeftChild.ClassCounts: 146 66 
+RightChild.size: 236
+RightChild.ClassCounts: 55 181 
+
+minGini: 40.777142 - 1
+Region.size: 236
+LeftChild.size: 161
+LeftChild.ClassCounts: 46 115 
+RightChild.size: 75
+RightChild.ClassCounts: 9 66 
+
+minGini: 6.328767 - 2
+Region.size: 75
+LeftChild.size: 73
+LeftChild.ClassCounts: 7 66 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 5.500000 - 1
+Region.size: 73
+LeftChild.size: 72
+LeftChild.ClassCounts: 6 66 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.734375 - 6
+Region.size: 72
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 64
+RightChild.ClassCounts: 3 61 
+
+minGini: 2.617495 - 7
+Region.size: 64
+LeftChild.size: 53
+LeftChild.ClassCounts: 1 52 
+RightChild.size: 11
+RightChild.ClassCounts: 2 9 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.875000 - 1
+Region.size: 53
+LeftChild.size: 45
+LeftChild.ClassCounts: 0 45 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.750000 - 0
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.500000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 30.988172 - 6
+Region.size: 161
+LeftChild.size: 155
+LeftChild.ClassCounts: 41 114 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 27.968992 - 6
+Region.size: 155
+LeftChild.size: 129
+LeftChild.ClassCounts: 41 88 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 
+
+minGini: 26.009420 - 3
+Region.size: 129
+LeftChild.size: 69
+LeftChild.ClassCounts: 14 55 
+RightChild.size: 60
+RightChild.ClassCounts: 27 33 
+
+minGini: 11.647058 - 1
+Region.size: 60
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 51
+RightChild.ClassCounts: 18 33 
+
+minGini: 9.637651 - 1
+Region.size: 51
+LeftChild.size: 38
+LeftChild.ClassCounts: 9 29 
+RightChild.size: 13
+RightChild.ClassCounts: 9 4 
+
+minGini: 1.333333 - 3
+Region.size: 13
+LeftChild.size: 6
+LeftChild.ClassCounts: 2 4 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.666666 - 4
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.070769 - 6
+Region.size: 38
+LeftChild.size: 13
+LeftChild.ClassCounts: 7 6 
+RightChild.size: 25
+RightChild.ClassCounts: 2 23 
+
+minGini: 0.666666 - 2
+Region.size: 25
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 22
+RightChild.ClassCounts: 0 22 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.875000 - 6
+Region.size: 13
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.000000 - 3
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 10.497386 - 7
+Region.size: 69
+LeftChild.size: 28
+LeftChild.ClassCounts: 9 19 
+RightChild.size: 41
+RightChild.ClassCounts: 5 36 
+
+minGini: 3.429824 - 5
+Region.size: 41
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 38
+RightChild.ClassCounts: 3 35 
+
+minGini: 2.526315 - 0
+Region.size: 38
+LeftChild.size: 19
+LeftChild.ClassCounts: 3 16 
+RightChild.size: 19
+RightChild.ClassCounts: 0 19 
+
+minGini: 1.777777 - 2
+Region.size: 19
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 18
+RightChild.ClassCounts: 2 16 
+
+minGini: 1.555555 - 6
+Region.size: 18
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 7 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 1.000000 - 1
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 2.590909 - 2
+Region.size: 28
+LeftChild.size: 22
+LeftChild.ClassCounts: 3 19 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 1.809523 - 4
+Region.size: 22
+LeftChild.size: 21
+LeftChild.ClassCounts: 2 19 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.600000 - 2
+Region.size: 21
+LeftChild.size: 10
+LeftChild.ClassCounts: 2 8 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 0.888888 - 3
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 0
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 41.381586 - 6
+Region.size: 212
+LeftChild.size: 157
+LeftChild.ClassCounts: 121 36 
+RightChild.size: 55
+RightChild.ClassCounts: 25 30 
+
+minGini: 10.434782 - 3
+Region.size: 55
+LeftChild.size: 46
+LeftChild.ClassCounts: 16 30 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 8.293040 - 3
+Region.size: 46
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 39
+RightChild.ClassCounts: 10 29 
+
+minGini: 6.551724 - 4
+Region.size: 39
+LeftChild.size: 29
+LeftChild.ClassCounts: 10 19 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 5.300000 - 4
+Region.size: 29
+LeftChild.size: 24
+LeftChild.ClassCounts: 6 18 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.571428 - 2
+Region.size: 24
+LeftChild.size: 21
+LeftChild.ClassCounts: 3 18 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.800000 - 3
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 2 18 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 7
+Region.size: 20
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 17
+RightChild.ClassCounts: 0 17 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 24.809143 - 1
+Region.size: 157
+LeftChild.size: 53
+LeftChild.ClassCounts: 51 2 
+RightChild.size: 104
+RightChild.ClassCounts: 70 34 
+
+minGini: 20.383530 - 5
+Region.size: 104
+LeftChild.size: 43
+LeftChild.ClassCounts: 21 22 
+RightChild.size: 61
+RightChild.ClassCounts: 49 12 
+
+minGini: 7.200000 - 7
+Region.size: 61
+LeftChild.size: 31
+LeftChild.ClassCounts: 31 0 
+RightChild.size: 30
+RightChild.ClassCounts: 18 12 
+
+minGini: 4.366071 - 3
+Region.size: 30
+LeftChild.size: 16
+LeftChild.ClassCounts: 5 11 
+RightChild.size: 14
+RightChild.ClassCounts: 13 1 
+
+minGini: 0.000000 - 5
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.933333 - 7
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 4 11 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.357142 - 5
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 14
+RightChild.ClassCounts: 3 11 
+
+minGini: 0.000000 - 2
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 7.764705 - 6
+Region.size: 43
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 34
+RightChild.ClassCounts: 12 22 
+
+minGini: 5.866666 - 0
+Region.size: 34
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 30
+RightChild.ClassCounts: 8 22 
+
+minGini: 2.640000 - 6
+Region.size: 30
+LeftChild.size: 25
+LeftChild.ClassCounts: 3 22 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 2.307692 - 7
+Region.size: 25
+LeftChild.size: 13
+LeftChild.ClassCounts: 3 10 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 
+
+minGini: 1.566666 - 5
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.000000 - 7
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.646666 - 3
+Region.size: 53
+LeftChild.size: 50
+LeftChild.ClassCounts: 49 1 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.800000 - 0
+Region.size: 50
+LeftChild.size: 45
+LeftChild.ClassCounts: 45 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.500000 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 13.504901 - 1
+Region.size: 138
+LeftChild.size: 102
+LeftChild.ClassCounts: 97 5 
+RightChild.size: 36
+RightChild.ClassCounts: 15 21 
+
+minGini: 6.666666 - 3
+Region.size: 36
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 27
+RightChild.ClassCounts: 15 12 
+
+minGini: 4.000000 - 2
+Region.size: 27
+LeftChild.size: 18
+LeftChild.ClassCounts: 6 12 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 1.750000 - 3
+Region.size: 18
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 12
+RightChild.ClassCounts: 1 11 
+
+minGini: 0.750000 - 1
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 4.340000 - 6
+Region.size: 102
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 100
+RightChild.ClassCounts: 96 4 
+
+minGini: 3.640332 - 0
+Region.size: 100
+LeftChild.size: 26
+LeftChild.ClassCounts: 23 3 
+RightChild.size: 74
+RightChild.ClassCounts: 73 1 
+
+minGini: 0.750000 - 3
+Region.size: 74
+LeftChild.size: 70
+LeftChild.ClassCounts: 70 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.666666 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.958333 - 3
+Region.size: 26
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 24
+RightChild.ClassCounts: 23 1 
+
+minGini: 0.916666 - 5
+Region.size: 24
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 12
+RightChild.ClassCounts: 11 1 
+
+minGini: 0.833333 - 3
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.500000 - 3
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 11.302083 - 7
+Region.size: 182
+LeftChild.size: 128
+LeftChild.ClassCounts: 126 2 
+RightChild.size: 54
+RightChild.ClassCounts: 42 12 
+
+minGini: 0.976744 - 1
+Region.size: 54
+LeftChild.size: 43
+LeftChild.ClassCounts: 42 1 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 0.916666 - 2
+Region.size: 43
+LeftChild.size: 12
+LeftChild.ClassCounts: 11 1 
+RightChild.size: 31
+RightChild.ClassCounts: 31 0 
+
+minGini: 0.000000 - 4
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.692307 - 1
+Region.size: 128
+LeftChild.size: 115
+LeftChild.ClassCounts: 115 0 
+RightChild.size: 13
+RightChild.ClassCounts: 11 2 
+
+minGini: 0.916666 - 0
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 11 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.500000 - 7
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 26 finished.
+
+minGini: 157.909320 - 7
+Region.size: 768
+LeftChild.size: 378
+LeftChild.ClassCounts: 302 76 
+RightChild.size: 390
+RightChild.ClassCounts: 206 184 
+
+minGini: 93.203216 - 6
+Region.size: 390
+LeftChild.size: 162
+LeftChild.ClassCounts: 105 57 
+RightChild.size: 228
+RightChild.ClassCounts: 101 127 
+
+minGini: 43.215153 - 1
+Region.size: 228
+LeftChild.size: 136
+LeftChild.ClassCounts: 87 49 
+RightChild.size: 92
+RightChild.ClassCounts: 14 78 
+
+minGini: 10.749819 - 5
+Region.size: 92
+LeftChild.size: 19
+LeftChild.ClassCounts: 7 12 
+RightChild.size: 73
+RightChild.ClassCounts: 7 66 
+
+minGini: 5.987704 - 6
+Region.size: 73
+LeftChild.size: 12
+LeftChild.ClassCounts: 3 9 
+RightChild.size: 61
+RightChild.ClassCounts: 4 57 
+
+minGini: 2.597701 - 4
+Region.size: 61
+LeftChild.size: 58
+LeftChild.ClassCounts: 2 56 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.846153 - 4
+Region.size: 58
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 32 
+RightChild.size: 26
+RightChild.ClassCounts: 2 24 
+
+minGini: 0.960000 - 5
+Region.size: 26
+LeftChild.size: 25
+LeftChild.ClassCounts: 1 24 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.833333 - 5
+Region.size: 25
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 19
+RightChild.ClassCounts: 0 19 
+
+minGini: 0.000000 - 2
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.555555 - 4
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.750000 - 1
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 2.545454 - 6
+Region.size: 19
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 11
+RightChild.ClassCounts: 7 4 
+
+minGini: 0.000000 - 5
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 29.093750 - 0
+Region.size: 136
+LeftChild.size: 128
+LeftChild.ClassCounts: 86 42 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 26.389380 - 7
+Region.size: 128
+LeftChild.size: 113
+LeftChild.ClassCounts: 71 42 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 
+
+minGini: 22.400000 - 5
+Region.size: 113
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 90
+RightChild.ClassCounts: 48 42 
+
+minGini: 21.486166 - 7
+Region.size: 90
+LeftChild.size: 46
+LeftChild.ClassCounts: 20 26 
+RightChild.size: 44
+RightChild.ClassCounts: 28 16 
+
+minGini: 9.397894 - 3
+Region.size: 44
+LeftChild.size: 25
+LeftChild.ClassCounts: 13 12 
+RightChild.size: 19
+RightChild.ClassCounts: 15 4 
+
+minGini: 2.416666 - 5
+Region.size: 19
+LeftChild.size: 16
+LeftChild.ClassCounts: 14 2 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.500000 - 6
+Region.size: 16
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.857142 - 1
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.254385 - 6
+Region.size: 25
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 19
+RightChild.ClassCounts: 12 7 
+
+minGini: 3.000000 - 6
+Region.size: 19
+LeftChild.size: 16
+LeftChild.ClassCounts: 12 4 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 2.400000 - 3
+Region.size: 16
+LeftChild.size: 15
+LeftChild.ClassCounts: 12 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.583333 - 1
+Region.size: 15
+LeftChild.size: 12
+LeftChild.ClassCounts: 11 1 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 0.000000 - 7
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 8.538888 - 1
+Region.size: 46
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 36
+RightChild.ClassCounts: 11 25 
+
+minGini: 6.518518 - 0
+Region.size: 36
+LeftChild.size: 27
+LeftChild.ClassCounts: 11 16 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 
+
+minGini: 4.869565 - 1
+Region.size: 27
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 23
+RightChild.ClassCounts: 7 16 
+
+minGini: 2.100000 - 5
+Region.size: 23
+LeftChild.size: 10
+LeftChild.ClassCounts: 7 3 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 6
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 33.059847 - 2
+Region.size: 162
+LeftChild.size: 38
+LeftChild.ClassCounts: 14 24 
+RightChild.size: 124
+RightChild.ClassCounts: 91 33 
+
+minGini: 21.466562 - 7
+Region.size: 124
+LeftChild.size: 61
+LeftChild.ClassCounts: 54 7 
+RightChild.size: 63
+RightChild.ClassCounts: 37 26 
+
+minGini: 10.800000 - 1
+Region.size: 63
+LeftChild.size: 30
+LeftChild.ClassCounts: 26 4 
+RightChild.size: 33
+RightChild.ClassCounts: 11 22 
+
+minGini: 6.346153 - 7
+Region.size: 33
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 26
+RightChild.ClassCounts: 11 15 
+
+minGini: 4.950000 - 6
+Region.size: 26
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 20
+RightChild.ClassCounts: 11 9 
+
+minGini: 3.191919 - 6
+Region.size: 20
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 9
+RightChild.ClassCounts: 2 7 
+
+minGini: 0.666666 - 6
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.200000 - 6
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.846153 - 6
+Region.size: 30
+LeftChild.size: 26
+LeftChild.ClassCounts: 24 2 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.458333 - 5
+Region.size: 26
+LeftChild.size: 24
+LeftChild.ClassCounts: 23 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 5
+Region.size: 24
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.400000 - 2
+Region.size: 61
+LeftChild.size: 60
+LeftChild.ClassCounts: 54 6 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 4.920000 - 4
+Region.size: 60
+LeftChild.size: 50
+LeftChild.ClassCounts: 47 3 
+RightChild.size: 10
+RightChild.ClassCounts: 7 3 
+
+minGini: 0.875000 - 4
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.500000 - 7
+Region.size: 50
+LeftChild.size: 32
+LeftChild.ClassCounts: 32 0 
+RightChild.size: 18
+RightChild.ClassCounts: 15 3 
+
+minGini: 2.000000 - 3
+Region.size: 18
+LeftChild.size: 9
+LeftChild.ClassCounts: 6 3 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.857142 - 6
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.666666 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 6.000000 - 6
+Region.size: 38
+LeftChild.size: 32
+LeftChild.ClassCounts: 8 24 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 3.428571 - 1
+Region.size: 32
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 28
+RightChild.ClassCounts: 4 24 
+
+minGini: 1.708333 - 5
+Region.size: 28
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 24
+RightChild.ClassCounts: 1 23 
+
+minGini: 0.000000 - 6
+Region.size: 24
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 23 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 44.568452 - 1
+Region.size: 378
+LeftChild.size: 336
+LeftChild.ClassCounts: 293 43 
+RightChild.size: 42
+RightChild.ClassCounts: 9 33 
+
+minGini: 4.342105 - 5
+Region.size: 42
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 38
+RightChild.ClassCounts: 5 33 
+
+minGini: 3.187739 - 3
+Region.size: 38
+LeftChild.size: 9
+LeftChild.ClassCounts: 4 5 
+RightChild.size: 29
+RightChild.ClassCounts: 1 28 
+
+minGini: 0.750000 - 7
+Region.size: 29
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 25 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 33.778131 - 1
+Region.size: 336
+LeftChild.size: 277
+LeftChild.ClassCounts: 255 22 
+RightChild.size: 59
+RightChild.ClassCounts: 38 21 
+
+minGini: 10.230769 - 2
+Region.size: 59
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 52
+RightChild.ClassCounts: 38 14 
+
+minGini: 7.276595 - 2
+Region.size: 52
+LeftChild.size: 47
+LeftChild.ClassCounts: 38 9 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 5.913919 - 6
+Region.size: 47
+LeftChild.size: 21
+LeftChild.ClassCounts: 13 8 
+RightChild.size: 26
+RightChild.ClassCounts: 25 1 
+
+minGini: 0.833333 - 0
+Region.size: 26
+LeftChild.size: 20
+LeftChild.ClassCounts: 20 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 3.058823 - 6
+Region.size: 21
+LeftChild.size: 17
+LeftChild.ClassCounts: 13 4 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 1.673076 - 1
+Region.size: 17
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 13
+RightChild.ClassCounts: 12 1 
+
+minGini: 0.000000 - 3
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 16.813186 - 5
+Region.size: 277
+LeftChild.size: 273
+LeftChild.ClassCounts: 255 18 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 15.278734 - 6
+Region.size: 273
+LeftChild.size: 239
+LeftChild.ClassCounts: 230 9 
+RightChild.size: 34
+RightChild.ClassCounts: 25 9 
+
+minGini: 5.625000 - 7
+Region.size: 34
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 24
+RightChild.ClassCounts: 15 9 
+
+minGini: 4.235294 - 4
+Region.size: 24
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 17
+RightChild.ClassCounts: 8 9 
+
+minGini: 3.716666 - 4
+Region.size: 17
+LeftChild.size: 12
+LeftChild.ClassCounts: 7 5 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.428571 - 2
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 
+
+minGini: 0.666666 - 2
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 7.731092 - 0
+Region.size: 239
+LeftChild.size: 238
+LeftChild.ClassCounts: 230 8 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 7.378640 - 5
+Region.size: 238
+LeftChild.size: 135
+LeftChild.ClassCounts: 135 0 
+RightChild.size: 103
+RightChild.ClassCounts: 95 8 
+
+minGini: 5.831578 - 5
+Region.size: 103
+LeftChild.size: 8
+LeftChild.ClassCounts: 4 4 
+RightChild.size: 95
+RightChild.ClassCounts: 91 4 
+
+minGini: 2.623188 - 6
+Region.size: 95
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 92
+RightChild.ClassCounts: 90 2 
+
+minGini: 1.777777 - 6
+Region.size: 92
+LeftChild.size: 74
+LeftChild.ClassCounts: 74 0 
+RightChild.size: 18
+RightChild.ClassCounts: 16 2 
+
+minGini: 1.636363 - 0
+Region.size: 18
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 1.200000 - 4
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.000000 - 3
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.800000 - 6
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 27 finished.
+
+minGini: 160.582377 - 5
+Region.size: 768
+LeftChild.size: 227
+LeftChild.ClassCounts: 197 30 
+RightChild.size: 541
+RightChild.ClassCounts: 290 251 
+
+minGini: 126.524595 - 0
+Region.size: 541
+LeftChild.size: 410
+LeftChild.ClassCounts: 248 162 
+RightChild.size: 131
+RightChild.ClassCounts: 42 89 
+
+minGini: 20.715517 - 1
+Region.size: 131
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 
+RightChild.size: 116
+RightChild.ClassCounts: 27 89 
+
+minGini: 18.416010 - 1
+Region.size: 116
+LeftChild.size: 79
+LeftChild.ClassCounts: 26 53 
+RightChild.size: 37
+RightChild.ClassCounts: 1 36 
+
+minGini: 0.916666 - 3
+Region.size: 37
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 25 
+RightChild.size: 12
+RightChild.ClassCounts: 1 11 
+
+minGini: 0.000000 - 6
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 15.763546 - 6
+Region.size: 79
+LeftChild.size: 21
+LeftChild.ClassCounts: 12 9 
+RightChild.size: 58
+RightChild.ClassCounts: 14 44 
+
+minGini: 9.428571 - 7
+Region.size: 58
+LeftChild.size: 56
+LeftChild.ClassCounts: 12 44 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 8.588888 - 1
+Region.size: 56
+LeftChild.size: 20
+LeftChild.ClassCounts: 1 19 
+RightChild.size: 36
+RightChild.ClassCounts: 11 25 
+
+minGini: 6.438461 - 0
+Region.size: 36
+LeftChild.size: 10
+LeftChild.ClassCounts: 6 4 
+RightChild.size: 26
+RightChild.ClassCounts: 5 21 
+
+minGini: 2.222222 - 7
+Region.size: 26
+LeftChild.size: 9
+LeftChild.ClassCounts: 5 4 
+RightChild.size: 17
+RightChild.ClassCounts: 0 17 
+
+minGini: 1.714285 - 7
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.750000 - 3
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.800000 - 7
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.666666 - 4
+Region.size: 20
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 17 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.214285 - 6
+Region.size: 21
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 6 
+RightChild.size: 14
+RightChild.ClassCounts: 11 3 
+
+minGini: 1.575757 - 5
+Region.size: 14
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.750000 - 6
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 7 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 95.762376 - 5
+Region.size: 410
+LeftChild.size: 404
+LeftChild.ClassCounts: 248 156 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 76.865632 - 1
+Region.size: 404
+LeftChild.size: 261
+LeftChild.ClassCounts: 202 59 
+RightChild.size: 143
+RightChild.ClassCounts: 46 97 
+
+minGini: 28.107240 - 1
+Region.size: 143
+LeftChild.size: 73
+LeftChild.ClassCounts: 34 39 
+RightChild.size: 70
+RightChild.ClassCounts: 12 58 
+
+minGini: 7.030303 - 6
+Region.size: 70
+LeftChild.size: 66
+LeftChild.ClassCounts: 8 58 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 6.095238 - 5
+Region.size: 66
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 63
+RightChild.ClassCounts: 6 57 
+
+minGini: 4.833333 - 7
+Region.size: 63
+LeftChild.size: 54
+LeftChild.ClassCounts: 3 51 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 0.000000 - 6
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 2.526315 - 5
+Region.size: 54
+LeftChild.size: 19
+LeftChild.ClassCounts: 3 16 
+RightChild.size: 35
+RightChild.ClassCounts: 0 35 
+
+minGini: 0.941176 - 5
+Region.size: 19
+LeftChild.size: 17
+LeftChild.ClassCounts: 1 16 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.666666 - 1
+Region.size: 17
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 16.604746 - 3
+Region.size: 73
+LeftChild.size: 26
+LeftChild.ClassCounts: 7 19 
+RightChild.size: 47
+RightChild.ClassCounts: 27 20 
+
+minGini: 8.935483 - 7
+Region.size: 47
+LeftChild.size: 31
+LeftChild.ClassCounts: 23 8 
+RightChild.size: 16
+RightChild.ClassCounts: 4 12 
+
+minGini: 1.714285 - 1
+Region.size: 16
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 14
+RightChild.ClassCounts: 2 12 
+
+minGini: 0.666666 - 2
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 4.670833 - 1
+Region.size: 31
+LeftChild.size: 15
+LeftChild.ClassCounts: 8 7 
+RightChild.size: 16
+RightChild.ClassCounts: 15 1 
+
+minGini: 0.000000 - 2
+Region.size: 16
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 15
+RightChild.ClassCounts: 15 0 
+
+minGini: 3.076923 - 5
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 13
+RightChild.ClassCounts: 8 5 
+
+minGini: 2.181818 - 4
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 8 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 1.500000 - 7
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.750000 - 0
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 3.652777 - 6
+Region.size: 26
+LeftChild.size: 8
+LeftChild.ClassCounts: 5 3 
+RightChild.size: 18
+RightChild.ClassCounts: 2 16 
+
+minGini: 0.941176 - 7
+Region.size: 18
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 17
+RightChild.ClassCounts: 1 16 
+
+minGini: 0.000000 - 5
+Region.size: 17
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 16 
+
+minGini: 0.833333 - 0
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 5
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 40.211327 - 7
+Region.size: 261
+LeftChild.size: 172
+LeftChild.ClassCounts: 151 21 
+RightChild.size: 89
+RightChild.ClassCounts: 51 38 
+
+minGini: 19.950000 - 2
+Region.size: 89
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 80
+RightChild.ClassCounts: 42 38 
+
+minGini: 17.546772 - 5
+Region.size: 80
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 69
+RightChild.ClassCounts: 41 28 
+
+minGini: 14.933333 - 6
+Region.size: 69
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 60
+RightChild.ClassCounts: 32 28 
+
+minGini: 13.745454 - 5
+Region.size: 60
+LeftChild.size: 55
+LeftChild.ClassCounts: 27 28 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 11.545454 - 6
+Region.size: 55
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 44
+RightChild.ClassCounts: 26 18 
+
+minGini: 9.818181 - 2
+Region.size: 44
+LeftChild.size: 22
+LeftChild.ClassCounts: 10 12 
+RightChild.size: 22
+RightChild.ClassCounts: 16 6 
+
+minGini: 2.803571 - 0
+Region.size: 22
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 14
+RightChild.ClassCounts: 13 1 
+
+minGini: 0.000000 - 1
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 0.833333 - 2
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 3
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 2.545454 - 4
+Region.size: 22
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 11
+RightChild.ClassCounts: 9 2 
+
+minGini: 0.900000 - 3
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 0.666666 - 6
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 5
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 
+
+minGini: 16.387368 - 6
+Region.size: 172
+LeftChild.size: 93
+LeftChild.ClassCounts: 91 2 
+RightChild.size: 79
+RightChild.ClassCounts: 60 19 
+
+minGini: 11.464285 - 3
+Region.size: 79
+LeftChild.size: 63
+LeftChild.ClassCounts: 54 9 
+RightChild.size: 16
+RightChild.ClassCounts: 6 10 
+
+minGini: 0.000000 - 1
+Region.size: 16
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 10 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 6.967741 - 7
+Region.size: 63
+LeftChild.size: 62
+LeftChild.ClassCounts: 54 8 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 6.259740 - 6
+Region.size: 62
+LeftChild.size: 55
+LeftChild.ClassCounts: 50 5 
+RightChild.size: 7
+RightChild.ClassCounts: 4 3 
+
+minGini: 0.800000 - 1
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 4
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 4.218750 - 5
+Region.size: 55
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 32
+RightChild.ClassCounts: 27 5 
+
+minGini: 3.863636 - 6
+Region.size: 32
+LeftChild.size: 22
+LeftChild.ClassCounts: 17 5 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 2.550000 - 2
+Region.size: 22
+LeftChild.size: 20
+LeftChild.ClassCounts: 17 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.000000 - 2
+Region.size: 20
+LeftChild.size: 9
+LeftChild.ClassCounts: 6 3 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 
+
+minGini: 1.200000 - 1
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 2 3 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.870967 - 1
+Region.size: 93
+LeftChild.size: 62
+LeftChild.ClassCounts: 62 0 
+RightChild.size: 31
+RightChild.ClassCounts: 29 2 
+
+minGini: 0.966666 - 2
+Region.size: 31
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 30
+RightChild.ClassCounts: 29 1 
+
+minGini: 0.888888 - 4
+Region.size: 30
+LeftChild.size: 9
+LeftChild.ClassCounts: 8 1 
+RightChild.size: 21
+RightChild.ClassCounts: 21 0 
+
+minGini: 0.000000 - 1
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 22.773441 - 7
+Region.size: 227
+LeftChild.size: 118
+LeftChild.ClassCounts: 116 2 
+RightChild.size: 109
+RightChild.ClassCounts: 81 28 
+
+minGini: 19.668290 - 5
+Region.size: 109
+LeftChild.size: 21
+LeftChild.ClassCounts: 20 1 
+RightChild.size: 88
+RightChild.ClassCounts: 61 27 
+
+minGini: 17.563636 - 7
+Region.size: 88
+LeftChild.size: 55
+LeftChild.ClassCounts: 43 12 
+RightChild.size: 33
+RightChild.ClassCounts: 18 15 
+
+minGini: 4.900000 - 7
+Region.size: 33
+LeftChild.size: 15
+LeftChild.ClassCounts: 3 12 
+RightChild.size: 18
+RightChild.ClassCounts: 15 3 
+
+minGini: 0.937500 - 6
+Region.size: 18
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 16
+RightChild.ClassCounts: 15 1 
+
+minGini: 0.875000 - 2
+Region.size: 16
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.500000 - 2
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.583333 - 5
+Region.size: 15
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 11 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 3
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 7.500000 - 1
+Region.size: 55
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 32
+RightChild.ClassCounts: 20 12 
+
+minGini: 5.554655 - 2
+Region.size: 32
+LeftChild.size: 19
+LeftChild.ClassCounts: 8 11 
+RightChild.size: 13
+RightChild.ClassCounts: 12 1 
+
+minGini: 0.000000 - 1
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 3.141025 - 6
+Region.size: 19
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 13
+RightChild.ClassCounts: 3 10 
+
+minGini: 0.909090 - 1
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 10 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.800000 - 1
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.500000 - 0
+Region.size: 21
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.824404 - 1
+Region.size: 118
+LeftChild.size: 112
+LeftChild.ClassCounts: 111 1 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.958333 - 0
+Region.size: 112
+LeftChild.size: 88
+LeftChild.ClassCounts: 88 0 
+RightChild.size: 24
+RightChild.ClassCounts: 23 1 
+
+minGini: 0.000000 - 6
+Region.size: 24
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 28 finished.
+
+minGini: 161.860795 - 7
+Region.size: 768
+LeftChild.size: 352
+LeftChild.ClassCounts: 279 73 
+RightChild.size: 416
+RightChild.ClassCounts: 208 208 
+
+minGini: 99.082082 - 0
+Region.size: 416
+LeftChild.size: 229
+LeftChild.ClassCounts: 137 92 
+RightChild.size: 187
+RightChild.ClassCounts: 71 116 
+
+minGini: 34.939759 - 1
+Region.size: 187
+LeftChild.size: 21
+LeftChild.ClassCounts: 21 0 
+RightChild.size: 166
+RightChild.ClassCounts: 50 116 
+
+minGini: 31.105882 - 6
+Region.size: 166
+LeftChild.size: 51
+LeftChild.ClassCounts: 27 24 
+RightChild.size: 115
+RightChild.ClassCounts: 23 92 
+
+minGini: 16.428571 - 7
+Region.size: 115
+LeftChild.size: 112
+LeftChild.ClassCounts: 20 92 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 15.666666 - 6
+Region.size: 112
+LeftChild.size: 100
+LeftChild.ClassCounts: 15 85 
+RightChild.size: 12
+RightChild.ClassCounts: 5 7 
+
+minGini: 0.833333 - 1
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 5 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 11.861861 - 1
+Region.size: 100
+LeftChild.size: 63
+LeftChild.ClassCounts: 14 49 
+RightChild.size: 37
+RightChild.ClassCounts: 1 36 
+
+minGini: 0.500000 - 2
+Region.size: 37
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 35
+RightChild.ClassCounts: 0 35 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 9.545454 - 7
+Region.size: 63
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 19 
+RightChild.size: 44
+RightChild.ClassCounts: 14 30 
+
+minGini: 8.060606 - 5
+Region.size: 44
+LeftChild.size: 33
+LeftChild.ClassCounts: 14 19 
+RightChild.size: 11
+RightChild.ClassCounts: 0 11 
+
+minGini: 6.160000 - 6
+Region.size: 33
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 25
+RightChild.ClassCounts: 14 11 
+
+minGini: 4.666666 - 7
+Region.size: 25
+LeftChild.size: 21
+LeftChild.ClassCounts: 14 7 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 3.567307 - 6
+Region.size: 21
+LeftChild.size: 13
+LeftChild.ClassCounts: 11 2 
+RightChild.size: 8
+RightChild.ClassCounts: 3 5 
+
+minGini: 0.750000 - 6
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.200000 - 3
+Region.size: 13
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 
+
+minGini: 0.666666 - 7
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 8.598461 - 6
+Region.size: 51
+LeftChild.size: 25
+LeftChild.ClassCounts: 6 19 
+RightChild.size: 26
+RightChild.ClassCounts: 21 5 
+
+minGini: 3.300000 - 5
+Region.size: 26
+LeftChild.size: 6
+LeftChild.ClassCounts: 3 3 
+RightChild.size: 20
+RightChild.ClassCounts: 18 2 
+
+minGini: 1.000000 - 2
+Region.size: 20
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.750000 - 2
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.500000 - 3
+Region.size: 25
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 17 
+RightChild.size: 8
+RightChild.ClassCounts: 6 2 
+
+minGini: 0.000000 - 2
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 43.719454 - 1
+Region.size: 229
+LeftChild.size: 92
+LeftChild.ClassCounts: 80 12 
+RightChild.size: 137
+RightChild.ClassCounts: 57 80 
+
+minGini: 31.340296 - 3
+Region.size: 137
+LeftChild.size: 53
+LeftChild.ClassCounts: 30 23 
+RightChild.size: 84
+RightChild.ClassCounts: 27 57 
+
+minGini: 17.378048 - 2
+Region.size: 84
+LeftChild.size: 82
+LeftChild.ClassCounts: 25 57 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 13.344444 - 6
+Region.size: 82
+LeftChild.size: 10
+LeftChild.ClassCounts: 9 1 
+RightChild.size: 72
+RightChild.ClassCounts: 16 56 
+
+minGini: 11.586206 - 2
+Region.size: 72
+LeftChild.size: 58
+LeftChild.ClassCounts: 16 42 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 8.902494 - 6
+Region.size: 58
+LeftChild.size: 49
+LeftChild.ClassCounts: 9 40 
+RightChild.size: 9
+RightChild.ClassCounts: 7 2 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 6.601449 - 4
+Region.size: 49
+LeftChild.size: 46
+LeftChild.ClassCounts: 7 39 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.419354 - 1
+Region.size: 46
+LeftChild.size: 31
+LeftChild.ClassCounts: 7 24 
+RightChild.size: 15
+RightChild.ClassCounts: 0 15 
+
+minGini: 4.683333 - 4
+Region.size: 31
+LeftChild.size: 15
+LeftChild.ClassCounts: 1 14 
+RightChild.size: 16
+RightChild.ClassCounts: 6 10 
+
+minGini: 0.857142 - 1
+Region.size: 16
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.500000 - 2
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 1
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 0.000000 - 4
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 11.744680 - 3
+Region.size: 53
+LeftChild.size: 47
+LeftChild.ClassCounts: 24 23 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 8.413043 - 1
+Region.size: 47
+LeftChild.size: 23
+LeftChild.ClassCounts: 18 5 
+RightChild.size: 24
+RightChild.ClassCounts: 6 18 
+
+minGini: 4.114285 - 2
+Region.size: 24
+LeftChild.size: 10
+LeftChild.ClassCounts: 1 9 
+RightChild.size: 14
+RightChild.ClassCounts: 5 9 
+
+minGini: 1.636363 - 5
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 2 9 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.900000 - 5
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.666666 - 2
+Region.size: 10
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.500000 - 5
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 3.333333 - 7
+Region.size: 23
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 15
+RightChild.ClassCounts: 10 5 
+
+minGini: 1.875000 - 7
+Region.size: 15
+LeftChild.size: 8
+LeftChild.ClassCounts: 3 5 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.833333 - 2
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.500000 - 5
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 8.901900 - 1
+Region.size: 92
+LeftChild.size: 59
+LeftChild.ClassCounts: 57 2 
+RightChild.size: 33
+RightChild.ClassCounts: 23 10 
+
+minGini: 5.488095 - 0
+Region.size: 33
+LeftChild.size: 12
+LeftChild.ClassCounts: 5 7 
+RightChild.size: 21
+RightChild.ClassCounts: 18 3 
+
+minGini: 2.400000 - 2
+Region.size: 21
+LeftChild.size: 15
+LeftChild.ClassCounts: 12 3 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 1.500000 - 5
+Region.size: 15
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 
+
+minGini: 0.000000 - 7
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.555555 - 2
+Region.size: 12
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 7 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.000000 - 3
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.982758 - 6
+Region.size: 59
+LeftChild.size: 58
+LeftChild.ClassCounts: 57 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.875000 - 6
+Region.size: 58
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 50
+RightChild.ClassCounts: 50 0 
+
+minGini: 0.000000 - 7
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 44.842067 - 5
+Region.size: 352
+LeftChild.size: 187
+LeftChild.ClassCounts: 182 5 
+RightChild.size: 165
+RightChild.ClassCounts: 97 68 
+
+minGini: 33.706293 - 6
+Region.size: 165
+LeftChild.size: 143
+LeftChild.ClassCounts: 95 48 
+RightChild.size: 22
+RightChild.ClassCounts: 2 20 
+
+minGini: 1.555555 - 2
+Region.size: 22
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 7 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 
+
+minGini: 0.875000 - 1
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 8
+RightChild.ClassCounts: 1 7 
+
+minGini: 0.000000 - 5
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 30.971055 - 6
+Region.size: 143
+LeftChild.size: 17
+LeftChild.ClassCounts: 15 2 
+RightChild.size: 126
+RightChild.ClassCounts: 80 46 
+
+minGini: 18.404524 - 1
+Region.size: 126
+LeftChild.size: 79
+LeftChild.ClassCounts: 68 11 
+RightChild.size: 47
+RightChild.ClassCounts: 12 35 
+
+minGini: 7.159090 - 3
+Region.size: 47
+LeftChild.size: 44
+LeftChild.ClassCounts: 9 35 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 6.029411 - 0
+Region.size: 44
+LeftChild.size: 34
+LeftChild.ClassCounts: 4 30 
+RightChild.size: 10
+RightChild.ClassCounts: 5 5 
+
+minGini: 0.833333 - 3
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 2.545454 - 7
+Region.size: 34
+LeftChild.size: 11
+LeftChild.ClassCounts: 4 7 
+RightChild.size: 23
+RightChild.ClassCounts: 0 23 
+
+minGini: 1.555555 - 4
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 7 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 3
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 7.896666 - 5
+Region.size: 79
+LeftChild.size: 75
+LeftChild.ClassCounts: 67 8 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 6.117647 - 6
+Region.size: 75
+LeftChild.size: 41
+LeftChild.ClassCounts: 41 0 
+RightChild.size: 34
+RightChild.ClassCounts: 26 8 
+
+minGini: 3.871212 - 5
+Region.size: 34
+LeftChild.size: 12
+LeftChild.ClassCounts: 5 7 
+RightChild.size: 22
+RightChild.ClassCounts: 21 1 
+
+minGini: 0.833333 - 4
+Region.size: 22
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 4
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 1.428571 - 2
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 7
+RightChild.ClassCounts: 5 2 
+
+minGini: 1.000000 - 3
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.666666 - 6
+Region.size: 17
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 4.640583 - 2
+Region.size: 187
+LeftChild.size: 13
+LeftChild.ClassCounts: 11 2 
+RightChild.size: 174
+RightChild.ClassCounts: 171 3 
+
+minGini: 2.726470 - 6
+Region.size: 174
+LeftChild.size: 170
+LeftChild.ClassCounts: 168 2 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.944444 - 3
+Region.size: 170
+LeftChild.size: 72
+LeftChild.ClassCounts: 70 2 
+RightChild.size: 98
+RightChild.ClassCounts: 98 0 
+
+minGini: 1.826086 - 4
+Region.size: 72
+LeftChild.size: 49
+LeftChild.ClassCounts: 49 0 
+RightChild.size: 23
+RightChild.ClassCounts: 21 2 
+
+minGini: 0.954545 - 7
+Region.size: 23
+LeftChild.size: 22
+LeftChild.ClassCounts: 21 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.857142 - 0
+Region.size: 22
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 
+RightChild.size: 7
+RightChild.ClassCounts: 6 1 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 1.000000 - 7
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 29 finished.
+
+minGini: 147.703030 - 1
+Region.size: 768
+LeftChild.size: 660
+LeftChild.ClassCounts: 476 184 
+RightChild.size: 108
+RightChild.ClassCounts: 18 90 
+
+minGini: 14.228571 - 7
+Region.size: 108
+LeftChild.size: 105
+LeftChild.ClassCounts: 16 89 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 11.633333 - 1
+Region.size: 105
+LeftChild.size: 30
+LeftChild.ClassCounts: 11 19 
+RightChild.size: 75
+RightChild.ClassCounts: 5 70 
+
+minGini: 4.491341 - 2
+Region.size: 75
+LeftChild.size: 33
+LeftChild.ClassCounts: 4 29 
+RightChild.size: 42
+RightChild.ClassCounts: 1 41 
+
+minGini: 0.750000 - 7
+Region.size: 42
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 38 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 1.870967 - 0
+Region.size: 33
+LeftChild.size: 31
+LeftChild.ClassCounts: 2 29 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.733333 - 1
+Region.size: 31
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 
+RightChild.size: 15
+RightChild.ClassCounts: 2 13 
+
+minGini: 0.666666 - 1
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 5.629629 - 6
+Region.size: 30
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 27
+RightChild.ClassCounts: 8 19 
+
+minGini: 3.958333 - 7
+Region.size: 27
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 24
+RightChild.ClassCounts: 5 19 
+
+minGini: 1.809523 - 1
+Region.size: 24
+LeftChild.size: 21
+LeftChild.ClassCounts: 2 19 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.447368 - 3
+Region.size: 21
+LeftChild.size: 19
+LeftChild.ClassCounts: 1 18 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.800000 - 2
+Region.size: 19
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 
+
+minGini: 0.666666 - 5
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 118.151515 - 7
+Region.size: 660
+LeftChild.size: 330
+LeftChild.ClassCounts: 287 43 
+RightChild.size: 330
+RightChild.ClassCounts: 189 141 
+
+minGini: 77.198044 - 7
+Region.size: 330
+LeftChild.size: 293
+LeftChild.ClassCounts: 157 136 
+RightChild.size: 37
+RightChild.ClassCounts: 32 5 
+
+minGini: 2.301075 - 1
+Region.size: 37
+LeftChild.size: 31
+LeftChild.ClassCounts: 30 1 
+RightChild.size: 6
+RightChild.ClassCounts: 2 4 
+
+minGini: 0.666666 - 2
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.666666 - 0
+Region.size: 31
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 28
+RightChild.ClassCounts: 28 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 65.204522 - 5
+Region.size: 293
+LeftChild.size: 39
+LeftChild.ClassCounts: 37 2 
+RightChild.size: 254
+RightChild.ClassCounts: 120 134 
+
+minGini: 59.003553 - 4
+Region.size: 254
+LeftChild.size: 208
+LeftChild.ClassCounts: 111 97 
+RightChild.size: 46
+RightChild.ClassCounts: 9 37 
+
+minGini: 5.886363 - 1
+Region.size: 46
+LeftChild.size: 44
+LeftChild.ClassCounts: 7 37 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 5.056910 - 3
+Region.size: 44
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 41
+RightChild.ClassCounts: 5 36 
+
+minGini: 3.632183 - 6
+Region.size: 41
+LeftChild.size: 12
+LeftChild.ClassCounts: 4 8 
+RightChild.size: 29
+RightChild.ClassCounts: 1 28 
+
+minGini: 0.833333 - 6
+Region.size: 29
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 23 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 3
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 12
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 48.598115 - 6
+Region.size: 208
+LeftChild.size: 164
+LeftChild.ClassCounts: 98 66 
+RightChild.size: 44
+RightChild.ClassCounts: 13 31 
+
+minGini: 7.548387 - 6
+Region.size: 44
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 
+RightChild.size: 31
+RightChild.ClassCounts: 13 18 
+
+minGini: 6.000000 - 6
+Region.size: 31
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 27
+RightChild.ClassCounts: 9 18 
+
+minGini: 5.464285 - 6
+Region.size: 27
+LeftChild.size: 20
+LeftChild.ClassCounts: 5 15 
+RightChild.size: 7
+RightChild.ClassCounts: 4 3 
+
+minGini: 1.200000 - 6
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.666666 - 1
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 3.076923 - 1
+Region.size: 20
+LeftChild.size: 13
+LeftChild.ClassCounts: 5 8 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 1.428571 - 3
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.666666 - 7
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.000000 - 2
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 35.634660 - 2
+Region.size: 164
+LeftChild.size: 122
+LeftChild.ClassCounts: 62 60 
+RightChild.size: 42
+RightChild.ClassCounts: 36 6 
+
+minGini: 4.000000 - 1
+Region.size: 42
+LeftChild.size: 24
+LeftChild.ClassCounts: 24 0 
+RightChild.size: 18
+RightChild.ClassCounts: 12 6 
+
+minGini: 2.400000 - 5
+Region.size: 18
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 15
+RightChild.ClassCounts: 12 3 
+
+minGini: 0.750000 - 5
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 27.627580 - 1
+Region.size: 122
+LeftChild.size: 23
+LeftChild.ClassCounts: 19 4 
+RightChild.size: 99
+RightChild.ClassCounts: 43 56 
+
+minGini: 21.913043 - 4
+Region.size: 99
+LeftChild.size: 92
+LeftChild.ClassCounts: 36 56 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 20.764044 - 5
+Region.size: 92
+LeftChild.size: 89
+LeftChild.ClassCounts: 33 56 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 17.968115 - 0
+Region.size: 89
+LeftChild.size: 69
+LeftChild.ClassCounts: 19 50 
+RightChild.size: 20
+RightChild.ClassCounts: 14 6 
+
+minGini: 3.187500 - 2
+Region.size: 20
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 16
+RightChild.ClassCounts: 13 3 
+
+minGini: 1.589743 - 5
+Region.size: 16
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 13
+RightChild.ClassCounts: 12 1 
+
+minGini: 0.000000 - 5
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 11.643877 - 7
+Region.size: 69
+LeftChild.size: 20
+LeftChild.ClassCounts: 11 9 
+RightChild.size: 49
+RightChild.ClassCounts: 8 41 
+
+minGini: 5.884057 - 2
+Region.size: 49
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 46
+RightChild.ClassCounts: 6 40 
+
+minGini: 4.494929 - 6
+Region.size: 46
+LeftChild.size: 17
+LeftChild.ClassCounts: 5 12 
+RightChild.size: 29
+RightChild.ClassCounts: 1 28 
+
+minGini: 0.000000 - 1
+Region.size: 29
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 28 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.714285 - 6
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 2 12 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.923076 - 5
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 13
+RightChild.ClassCounts: 1 12 
+
+minGini: 0.000000 - 5
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 4.235294 - 3
+Region.size: 20
+LeftChild.size: 17
+LeftChild.ClassCounts: 8 9 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 2.666666 - 0
+Region.size: 17
+LeftChild.size: 12
+LeftChild.ClassCounts: 8 4 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 1.625000 - 7
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 2
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 1.697368 - 0
+Region.size: 23
+LeftChild.size: 19
+LeftChild.ClassCounts: 18 1 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.750000 - 1
+Region.size: 19
+LeftChild.size: 15
+LeftChild.ClassCounts: 15 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.666666 - 0
+Region.size: 39
+LeftChild.size: 27
+LeftChild.ClassCounts: 27 0 
+RightChild.size: 12
+RightChild.ClassCounts: 10 2 
+
+minGini: 0.000000 - 5
+Region.size: 12
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 
+
+minGini: 35.454620 - 2
+Region.size: 330
+LeftChild.size: 52
+LeftChild.ClassCounts: 36 16 
+RightChild.size: 278
+RightChild.ClassCounts: 251 27 
+
+minGini: 23.265120 - 6
+Region.size: 278
+LeftChild.size: 142
+LeftChild.ClassCounts: 137 5 
+RightChild.size: 136
+RightChild.ClassCounts: 114 22 
+
+minGini: 15.610256 - 2
+Region.size: 136
+LeftChild.size: 130
+LeftChild.ClassCounts: 113 17 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 
+
+minGini: 0.000000 - 3
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+minGini: 13.547826 - 3
+Region.size: 130
+LeftChild.size: 15
+LeftChild.ClassCounts: 9 6 
+RightChild.size: 115
+RightChild.ClassCounts: 104 11 
+
+minGini: 9.428571 - 2
+Region.size: 115
+LeftChild.size: 77
+LeftChild.ClassCounts: 66 11 
+RightChild.size: 38
+RightChild.ClassCounts: 38 0 
+
+minGini: 7.135135 - 5
+Region.size: 77
+LeftChild.size: 74
+LeftChild.ClassCounts: 66 8 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 6.511627 - 6
+Region.size: 74
+LeftChild.size: 31
+LeftChild.ClassCounts: 31 0 
+RightChild.size: 43
+RightChild.ClassCounts: 35 8 
+
+minGini: 4.375000 - 6
+Region.size: 43
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 40
+RightChild.ClassCounts: 35 5 
+
+minGini: 3.382352 - 7
+Region.size: 40
+LeftChild.size: 34
+LeftChild.ClassCounts: 32 2 
+RightChild.size: 6
+RightChild.ClassCounts: 3 3 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 1.636363 - 3
+Region.size: 34
+LeftChild.size: 23
+LeftChild.ClassCounts: 23 0 
+RightChild.size: 11
+RightChild.ClassCounts: 9 2 
+
+minGini: 1.333333 - 6
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 
+RightChild.size: 6
+RightChild.ClassCounts: 4 2 
+
+minGini: 1.000000 - 2
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.666666 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.727272 - 1
+Region.size: 15
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 11
+RightChild.ClassCounts: 5 6 
+
+minGini: 2.000000 - 0
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 9
+RightChild.ClassCounts: 3 6 
+
+minGini: 0.857142 - 6
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 7
+RightChild.ClassCounts: 1 6 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 2.935714 - 5
+Region.size: 142
+LeftChild.size: 140
+LeftChild.ClassCounts: 137 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.756575 - 1
+Region.size: 140
+LeftChild.size: 123
+LeftChild.ClassCounts: 122 1 
+RightChild.size: 17
+RightChild.ClassCounts: 15 2 
+
+minGini: 1.000000 - 1
+Region.size: 17
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 2 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.900000 - 2
+Region.size: 123
+LeftChild.size: 113
+LeftChild.ClassCounts: 113 0 
+RightChild.size: 10
+RightChild.ClassCounts: 9 1 
+
+minGini: 0.000000 - 2
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 5.187500 - 5
+Region.size: 52
+LeftChild.size: 36
+LeftChild.ClassCounts: 33 3 
+RightChild.size: 16
+RightChild.ClassCounts: 3 13 
+
+minGini: 1.589743 - 3
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 1 12 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 7
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 12 
+
+minGini: 0.000000 - 1
+Region.size: 36
+LeftChild.size: 33
+LeftChild.ClassCounts: 33 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+
+
+Tree Number: 30 finished.
+
+minGini: 138.222206 - 1
+Region.size: 768
+LeftChild.size: 665
+LeftChild.ClassCounts: 505 160 
+RightChild.size: 103
+RightChild.ClassCounts: 21 82 
+
+minGini: 15.088259 - 3
+Region.size: 103
+LeftChild.size: 38
+LeftChild.ClassCounts: 14 24 
+RightChild.size: 65
+RightChild.ClassCounts: 7 58 
+
+minGini: 5.804878 - 3
+Region.size: 65
+LeftChild.size: 41
+LeftChild.ClassCounts: 7 34 
+RightChild.size: 24
+RightChild.ClassCounts: 0 24 
+
+minGini: 5.066137 - 7
+Region.size: 41
+LeftChild.size: 14
+LeftChild.ClassCounts: 5 9 
+RightChild.size: 27
+RightChild.ClassCounts: 2 25 
+
+minGini: 1.460000 - 0
+Region.size: 27
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 25
+RightChild.ClassCounts: 1 24 
+
+minGini: 0.000000 - 2
+Region.size: 25
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 24 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 2
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 2.250000 - 6
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 12
+RightChild.ClassCounts: 3 9 
+
+minGini: 1.555555 - 3
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 
+
+minGini: 0.666666 - 2
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 3
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 7
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 5.667692 - 5
+Region.size: 38
+LeftChild.size: 13
+LeftChild.ClassCounts: 10 3 
+RightChild.size: 25
+RightChild.ClassCounts: 4 21 
+
+minGini: 1.333333 - 2
+Region.size: 25
+LeftChild.size: 6
+LeftChild.ClassCounts: 4 2 
+RightChild.size: 19
+RightChild.ClassCounts: 0 19 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 0.909090 - 6
+Region.size: 13
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 11
+RightChild.ClassCounts: 10 1 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 110.992126 - 1
+Region.size: 665
+LeftChild.size: 242
+LeftChild.ClassCounts: 224 18 
+RightChild.size: 423
+RightChild.ClassCounts: 281 142 
+
+minGini: 86.378968 - 5
+Region.size: 423
+LeftChild.size: 88
+LeftChild.ClassCounts: 82 6 
+RightChild.size: 335
+RightChild.ClassCounts: 199 136 
+
+minGini: 75.087062 - 5
+Region.size: 335
+LeftChild.size: 301
+LeftChild.ClassCounts: 192 109 
+RightChild.size: 34
+RightChild.ClassCounts: 7 27 
+
+minGini: 4.860215 - 4
+Region.size: 34
+LeftChild.size: 31
+LeftChild.ClassCounts: 5 26 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 3.466666 - 6
+Region.size: 31
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 30
+RightChild.ClassCounts: 4 26 
+
+minGini: 1.857142 - 1
+Region.size: 30
+LeftChild.size: 28
+LeftChild.ClassCounts: 2 26 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.962962 - 7
+Region.size: 28
+LeftChild.size: 27
+LeftChild.ClassCounts: 1 26 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.750000 - 1
+Region.size: 27
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 
+RightChild.size: 23
+RightChild.ClassCounts: 0 23 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 63.661329 - 0
+Region.size: 301
+LeftChild.size: 229
+LeftChild.ClassCounts: 164 65 
+RightChild.size: 72
+RightChild.ClassCounts: 28 44 
+
+minGini: 10.545454 - 6
+Region.size: 72
+LeftChild.size: 39
+LeftChild.ClassCounts: 26 13 
+RightChild.size: 33
+RightChild.ClassCounts: 2 31 
+
+minGini: 0.968750 - 6
+Region.size: 33
+LeftChild.size: 32
+LeftChild.ClassCounts: 1 31 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.888888 - 1
+Region.size: 32
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 23
+RightChild.ClassCounts: 0 23 
+
+minGini: 0.000000 - 1
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 7.168571 - 5
+Region.size: 39
+LeftChild.size: 25
+LeftChild.ClassCounts: 13 12 
+RightChild.size: 14
+RightChild.ClassCounts: 13 1 
+
+minGini: 0.750000 - 0
+Region.size: 14
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.500000 - 5
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 4.533333 - 1
+Region.size: 25
+LeftChild.size: 10
+LeftChild.ClassCounts: 2 8 
+RightChild.size: 15
+RightChild.ClassCounts: 11 4 
+
+minGini: 0.916666 - 6
+Region.size: 15
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 12
+RightChild.ClassCounts: 11 1 
+
+minGini: 0.500000 - 4
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.888888 - 0
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.000000 - 7
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 43.347369 - 3
+Region.size: 229
+LeftChild.size: 66
+LeftChild.ClassCounts: 35 31 
+RightChild.size: 163
+RightChild.ClassCounts: 129 34 
+
+minGini: 23.429126 - 7
+Region.size: 163
+LeftChild.size: 103
+LeftChild.ClassCounts: 93 10 
+RightChild.size: 60
+RightChild.ClassCounts: 36 24 
+
+minGini: 11.727272 - 6
+Region.size: 60
+LeftChild.size: 44
+LeftChild.ClassCounts: 32 12 
+RightChild.size: 16
+RightChild.ClassCounts: 4 12 
+
+minGini: 2.000000 - 1
+Region.size: 16
+LeftChild.size: 8
+LeftChild.ClassCounts: 4 4 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 
+
+minGini: 0.800000 - 6
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 
+
+minGini: 7.575000 - 1
+Region.size: 44
+LeftChild.size: 24
+LeftChild.ClassCounts: 21 3 
+RightChild.size: 20
+RightChild.ClassCounts: 11 9 
+
+minGini: 3.437500 - 1
+Region.size: 20
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 16
+RightChild.ClassCounts: 11 5 
+
+minGini: 2.836363 - 7
+Region.size: 16
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 5
+RightChild.ClassCounts: 2 3 
+
+minGini: 0.000000 - 0
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+minGini: 0.000000 - 4
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 2.147368 - 2
+Region.size: 24
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 
+RightChild.size: 19
+RightChild.ClassCounts: 18 1 
+
+minGini: 0.800000 - 0
+Region.size: 19
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 1 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 8.205882 - 6
+Region.size: 103
+LeftChild.size: 102
+LeftChild.ClassCounts: 93 9 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 7.884719 - 7
+Region.size: 102
+LeftChild.size: 55
+LeftChild.ClassCounts: 53 2 
+RightChild.size: 47
+RightChild.ClassCounts: 40 7 
+
+minGini: 5.217391 - 6
+Region.size: 47
+LeftChild.size: 46
+LeftChild.ClassCounts: 40 6 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 3.195195 - 7
+Region.size: 46
+LeftChild.size: 9
+LeftChild.ClassCounts: 4 5 
+RightChild.size: 37
+RightChild.ClassCounts: 36 1 
+
+minGini: 0.833333 - 4
+Region.size: 37
+LeftChild.size: 31
+LeftChild.ClassCounts: 31 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.500000 - 1
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.800000 - 1
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 
+
+minGini: 0.000000 - 2
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 1.777777 - 1
+Region.size: 55
+LeftChild.size: 37
+LeftChild.ClassCounts: 37 0 
+RightChild.size: 18
+RightChild.ClassCounts: 16 2 
+
+minGini: 1.666666 - 4
+Region.size: 18
+LeftChild.size: 12
+LeftChild.ClassCounts: 10 2 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.909090 - 4
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 10 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.750000 - 6
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 
+RightChild.size: 7
+RightChild.ClassCounts: 7 0 
+
+minGini: 0.000000 - 2
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 14.923611 - 2
+Region.size: 66
+LeftChild.size: 48
+LeftChild.ClassCounts: 21 27 
+RightChild.size: 18
+RightChild.ClassCounts: 14 4 
+
+minGini: 2.975000 - 0
+Region.size: 18
+LeftChild.size: 8
+LeftChild.ClassCounts: 7 1 
+RightChild.size: 10
+RightChild.ClassCounts: 7 3 
+
+minGini: 1.523809 - 1
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 1 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.750000 - 0
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+minGini: 0.500000 - 1
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 9.415966 - 6
+Region.size: 48
+LeftChild.size: 14
+LeftChild.ClassCounts: 11 3 
+RightChild.size: 34
+RightChild.ClassCounts: 10 24 
+
+minGini: 6.296296 - 7
+Region.size: 34
+LeftChild.size: 27
+LeftChild.ClassCounts: 10 17 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 
+
+minGini: 5.135294 - 2
+Region.size: 27
+LeftChild.size: 17
+LeftChild.ClassCounts: 9 8 
+RightChild.size: 10
+RightChild.ClassCounts: 1 9 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 1.636363 - 1
+Region.size: 17
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 9
+RightChild.ClassCounts: 9 0 
+
+minGini: 1.875000 - 1
+Region.size: 14
+LeftChild.size: 6
+LeftChild.ClassCounts: 6 0 
+RightChild.size: 8
+RightChild.ClassCounts: 5 3 
+
+minGini: 0.833333 - 1
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 4.715897 - 2
+Region.size: 88
+LeftChild.size: 13
+LeftChild.ClassCounts: 9 4 
+RightChild.size: 75
+RightChild.ClassCounts: 73 2 
+
+minGini: 1.733333 - 1
+Region.size: 75
+LeftChild.size: 15
+LeftChild.ClassCounts: 13 2 
+RightChild.size: 60
+RightChild.ClassCounts: 60 0 
+
+minGini: 1.000000 - 6
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 2 
+
+minGini: 0.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 1.636363 - 5
+Region.size: 13
+LeftChild.size: 11
+LeftChild.ClassCounts: 9 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0.000000 - 0
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 9 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 13.709422 - 1
+Region.size: 242
+LeftChild.size: 7
+LeftChild.ClassCounts: 2 5 
+RightChild.size: 235
+RightChild.ClassCounts: 222 13 
+
+minGini: 11.145114 - 0
+Region.size: 235
+LeftChild.size: 232
+LeftChild.ClassCounts: 221 11 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 9.909909 - 3
+Region.size: 232
+LeftChild.size: 121
+LeftChild.ClassCounts: 121 0 
+RightChild.size: 111
+RightChild.ClassCounts: 100 11 
+
+minGini: 8.916666 - 0
+Region.size: 111
+LeftChild.size: 108
+LeftChild.ClassCounts: 99 9 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 7.004139 - 6
+Region.size: 108
+LeftChild.size: 89
+LeftChild.ClassCounts: 86 3 
+RightChild.size: 19
+RightChild.ClassCounts: 13 6 
+
+minGini: 2.727272 - 7
+Region.size: 19
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 
+RightChild.size: 11
+RightChild.ClassCounts: 5 6 
+
+minGini: 1.428571 - 0
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 5 2 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 
+
+minGini: 0.833333 - 7
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 5 1 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 
+
+minGini: 2.775187 - 4
+Region.size: 89
+LeftChild.size: 70
+LeftChild.ClassCounts: 69 1 
+RightChild.size: 19
+RightChild.ClassCounts: 17 2 
+
+minGini: 0.666666 - 4
+Region.size: 19
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0.950000 - 3
+Region.size: 70
+LeftChild.size: 20
+LeftChild.ClassCounts: 19 1 
+RightChild.size: 50
+RightChild.ClassCounts: 50 0 
+
+minGini: 0.000000 - 2
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 19 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 
+
+
+
+Tree Number: 31 finished.
+
+pina_indians_diabetes
+minGini: 147.820224 - 11
+Region.size: 210
+LeftChild.size: 178
+LeftChild.ClassCounts: 27 28 28 25 35 0 35 
+RightChild.size: 32
+RightChild.ClassCounts: 0 0 0 0 0 32 0 
+
+minGini: 118.375287 - 1
+Region.size: 178
+LeftChild.size: 120
+LeftChild.ClassCounts: 27 28 28 2 0 0 35 
+RightChild.size: 58
+RightChild.ClassCounts: 0 0 0 23 35 0 0 
+
+minGini: 0.000000 - 9
+Region.size: 58
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 0 0 23 0 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 0 0 0 0 35 0 0 
+
+minGini: 72.875000 - 12
+Region.size: 120
+LeftChild.size: 80
+LeftChild.ClassCounts: 26 1 20 0 0 0 33 
+RightChild.size: 40
+RightChild.ClassCounts: 1 27 8 2 0 0 2 
+
+minGini: 11.520000 - 15
+Region.size: 40
+LeftChild.size: 25
+LeftChild.ClassCounts: 1 24 0 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 3 8 2 0 0 2 
+
+minGini: 4.571428 - 18
+Region.size: 15
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 8 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 3 0 2 0 0 2 
+
+minGini: 2.000000 - 8
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 2 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 
+
+minGini: 0.000000 - 16
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 
+
+minGini: 1.600000 - 11
+Region.size: 25
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 4 0 0 0 0 0 
+RightChild.size: 20
+RightChild.ClassCounts: 0 20 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 
+
+minGini: 39.630421 - 10
+Region.size: 80
+LeftChild.size: 43
+LeftChild.ClassCounts: 1 0 19 0 0 0 23 
+RightChild.size: 37
+RightChild.ClassCounts: 25 1 1 0 0 0 10 
+
+minGini: 8.800000 - 0
+Region.size: 37
+LeftChild.size: 30
+LeftChild.ClassCounts: 25 1 1 0 0 0 3 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 0 7 
+
+minGini: 4.720000 - 14
+Region.size: 30
+LeftChild.size: 25
+LeftChild.ClassCounts: 24 1 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 0 1 0 0 0 3 
+
+minGini: 1.500000 - 1
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 1 0 0 0 3 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 0.000000 - 13
+Region.size: 25
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 24 0 0 0 0 0 0 
+
+minGini: 17.588235 - 13
+Region.size: 43
+LeftChild.size: 34
+LeftChild.ClassCounts: 1 0 19 0 0 0 14 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 0 0 9 
+
+minGini: 12.973544 - 12
+Region.size: 34
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 0 19 0 0 0 8 
+RightChild.size: 7
+RightChild.ClassCounts: 1 0 0 0 0 0 6 
+
+minGini: 1.333333 - 15
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 4 
+RightChild.size: 3
+RightChild.ClassCounts: 1 0 0 0 0 0 2 
+
+minGini: 0.000000 - 8
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 
+
+minGini: 7.916666 - 8
+Region.size: 27
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 3 
+RightChild.size: 24
+RightChild.ClassCounts: 0 0 19 0 0 0 5 
+
+minGini: 5.978947 - 0
+Region.size: 24
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 2 0 0 0 3 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 17 0 0 0 2 
+
+minGini: 1.888888 - 1
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 0 17 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 1.666666 - 8
+Region.size: 18
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 5 0 0 0 1 
+RightChild.size: 12
+RightChild.ClassCounts: 0 0 12 0 0 0 0 
+
+minGini: 0.000000 - 11
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 9
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 
+
+
+
+Tree Number: 0 finished.
+
+minGini: 141.247058 - 15
+Region.size: 210
+LeftChild.size: 170
+LeftChild.ClassCounts: 28 33 25 0 26 25 33 
+RightChild.size: 40
+RightChild.ClassCounts: 0 0 0 40 0 0 0 
+
+minGini: 115.600000 - 16
+Region.size: 170
+LeftChild.size: 145
+LeftChild.ClassCounts: 28 33 25 0 26 0 33 
+RightChild.size: 25
+RightChild.ClassCounts: 0 0 0 0 0 25 0 
+
+minGini: 91.436597 - 16
+Region.size: 145
+LeftChild.size: 89
+LeftChild.ClassCounts: 28 3 23 0 2 0 33 
+RightChild.size: 56
+RightChild.ClassCounts: 0 30 2 0 24 0 0 
+
+minGini: 3.750000 - 1
+Region.size: 56
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 30 2 0 0 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 0 0 0 0 24 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 32
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 30 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 
+
+minGini: 50.223856 - 17
+Region.size: 89
+LeftChild.size: 72
+LeftChild.ClassCounts: 28 3 8 0 2 0 31 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 15 0 0 0 2 
+
+minGini: 2.857142 - 5
+Region.size: 17
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 0 10 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 5 0 0 0 2 
+
+minGini: 0.000000 - 16
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 0 
+
+minGini: 37.466666 - 7
+Region.size: 72
+LeftChild.size: 27
+LeftChild.ClassCounts: 4 0 1 0 0 0 22 
+RightChild.size: 45
+RightChild.ClassCounts: 24 3 7 0 2 0 9 
+
+minGini: 14.190476 - 18
+Region.size: 45
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 3 7 0 2 0 9 
+RightChild.size: 24
+RightChild.ClassCounts: 24 0 0 0 0 0 0 
+
+minGini: 11.125000 - 10
+Region.size: 21
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 0 5 
+RightChild.size: 16
+RightChild.ClassCounts: 0 3 7 0 2 0 4 
+
+minGini: 7.750000 - 8
+Region.size: 16
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 3 1 0 0 0 4 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 6 0 2 0 0 
+
+minGini: 0.000000 - 13
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 
+
+minGini: 3.000000 - 16
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 1 1 0 0 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 0 
+
+minGini: 0.000000 - 15
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 1.913043 - 13
+Region.size: 27
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 0 1 0 0 0 22 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 0 
+
+minGini: 0.000000 - 18
+Region.size: 23
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 0 0 0 0 0 22 
+
+
+
+Tree Number: 1 finished.
+
+minGini: 151.471628 - 9
+Region.size: 210
+LeftChild.size: 118
+LeftChild.ClassCounts: 39 4 19 37 0 0 19 
+RightChild.size: 92
+RightChild.ClassCounts: 0 27 5 0 35 24 1 
+
+minGini: 46.428344 - 17
+Region.size: 92
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 8 0 0 0 23 0 
+RightChild.size: 61
+RightChild.ClassCounts: 0 19 5 0 35 1 1 
+
+minGini: 25.788770 - 10
+Region.size: 61
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 13 0 0 3 0 1 
+RightChild.size: 44
+RightChild.ClassCounts: 0 6 5 0 32 1 0 
+
+minGini: 8.770833 - 0
+Region.size: 44
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 6 5 0 1 0 0 
+RightChild.size: 32
+RightChild.ClassCounts: 0 0 0 0 31 1 0 
+
+minGini: 0.000000 - 9
+Region.size: 32
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 0 0 0 31 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 1 0 
+
+minGini: 1.666666 - 14
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 5 0 1 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 0 
+
+minGini: 0.000000 - 13
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 
+
+minGini: 4.285714 - 17
+Region.size: 17
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 3 0 0 3 0 1 
+RightChild.size: 10
+RightChild.ClassCounts: 0 10 0 0 0 0 0 
+
+minGini: 1.500000 - 1
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 3 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 
+
+minGini: 0.000000 - 16
+Region.size: 31
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 0 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 0 0 0 0 23 0 
+
+minGini: 53.111111 - 15
+Region.size: 118
+LeftChild.size: 81
+LeftChild.ClassCounts: 39 4 19 0 0 0 19 
+RightChild.size: 37
+RightChild.ClassCounts: 0 0 0 37 0 0 0 
+
+minGini: 40.656394 - 10
+Region.size: 81
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 0 14 0 0 0 8 
+RightChild.size: 59
+RightChild.ClassCounts: 39 4 5 0 0 0 11 
+
+minGini: 15.078431 - 13
+Region.size: 59
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 2 5 0 0 0 10 
+RightChild.size: 42
+RightChild.ClassCounts: 39 2 0 0 0 0 1 
+
+minGini: 4.345945 - 5
+Region.size: 42
+LeftChild.size: 37
+LeftChild.ClassCounts: 36 0 0 0 0 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 3 2 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 
+
+minGini: 1.600000 - 0
+Region.size: 37
+LeftChild.size: 32
+LeftChild.ClassCounts: 32 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 0 0 0 0 0 1 
+
+minGini: 0.000000 - 11
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 3.333333 - 17
+Region.size: 17
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 2 0 0 0 0 10 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 0 
+
+minGini: 1.818181 - 15
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 1 0 0 0 0 10 
+
+minGini: 0.000000 - 13
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 0 0 0 0 0 10 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 4.957264 - 7
+Region.size: 22
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 2 0 0 0 7 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 12 0 0 0 1 
+
+minGini: 0.000000 - 10
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 12 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 1.333333 - 14
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 0 6 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 2 0 0 0 1 
+
+minGini: 0.000000 - 13
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 
+
+
+
+Tree Number: 2 finished.
+
+minGini: 148.905965 - 1
+Region.size: 210
+LeftChild.size: 142
+LeftChild.ClassCounts: 32 28 28 0 0 28 26 
+RightChild.size: 68
+RightChild.ClassCounts: 0 2 0 37 29 0 0 
+
+minGini: 3.741935 - 18
+Region.size: 68
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 2 0 0 29 0 0 
+RightChild.size: 37
+RightChild.ClassCounts: 0 0 0 37 0 0 0 
+
+minGini: 0.000000 - 16
+Region.size: 31
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 0 0 29 0 0 
+
+minGini: 93.586776 - 13
+Region.size: 142
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 0 0 0 0 21 0 
+RightChild.size: 121
+RightChild.ClassCounts: 32 28 28 0 0 7 26 
+
+minGini: 73.645030 - 10
+Region.size: 121
+LeftChild.size: 87
+LeftChild.ClassCounts: 32 3 26 0 0 0 26 
+RightChild.size: 34
+RightChild.ClassCounts: 0 25 2 0 0 7 0 
+
+minGini: 3.673076 - 10
+Region.size: 34
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 25 1 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 1 0 0 7 0 
+
+minGini: 0.000000 - 10
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 7 0 
+
+minGini: 0.000000 - 4
+Region.size: 26
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 25 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 54.125000 - 1
+Region.size: 87
+LeftChild.size: 80
+LeftChild.ClassCounts: 32 3 26 0 0 0 19 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 0 7 
+
+minGini: 35.270655 - 17
+Region.size: 80
+LeftChild.size: 54
+LeftChild.ClassCounts: 32 3 3 0 0 0 16 
+RightChild.size: 26
+RightChild.ClassCounts: 0 0 23 0 0 0 3 
+
+minGini: 4.000000 - 8
+Region.size: 26
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 6 0 0 0 3 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 17 0 0 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 
+
+minGini: 15.419548 - 18
+Region.size: 54
+LeftChild.size: 19
+LeftChild.ClassCounts: 1 3 1 0 0 0 14 
+RightChild.size: 35
+RightChild.ClassCounts: 31 0 2 0 0 0 2 
+
+minGini: 2.000000 - 17
+Region.size: 35
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 2 0 0 0 2 
+RightChild.size: 31
+RightChild.ClassCounts: 31 0 0 0 0 0 0 
+
+minGini: 0.000000 - 7
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 
+
+minGini: 6.176470 - 13
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 1 2 0 0 0 0 14 
+
+minGini: 1.866666 - 3
+Region.size: 17
+LeftChild.size: 15
+LeftChild.ClassCounts: 1 0 0 0 0 0 14 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 0 0 0 0 0 14 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+
+
+Tree Number: 3 finished.
+
+minGini: 146.169491 - 9
+Region.size: 210
+LeftChild.size: 177
+LeftChild.ClassCounts: 18 31 31 31 39 0 27 
+RightChild.size: 33
+RightChild.ClassCounts: 0 0 0 0 0 33 0 
+
+minGini: 115.205479 - 15
+Region.size: 177
+LeftChild.size: 146
+LeftChild.ClassCounts: 18 31 31 0 39 0 27 
+RightChild.size: 31
+RightChild.ClassCounts: 0 0 0 31 0 0 0 
+
+minGini: 92.770454 - 11
+Region.size: 146
+LeftChild.size: 80
+LeftChild.ClassCounts: 18 6 27 0 2 0 27 
+RightChild.size: 66
+RightChild.ClassCounts: 0 25 4 0 37 0 0 
+
+minGini: 13.866666 - 8
+Region.size: 66
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 21 0 0 0 0 0 
+RightChild.size: 45
+RightChild.ClassCounts: 0 4 4 0 37 0 0 
+
+minGini: 7.219512 - 13
+Region.size: 45
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 0 
+RightChild.size: 41
+RightChild.ClassCounts: 0 4 0 0 37 0 0 
+
+minGini: 4.942857 - 14
+Region.size: 41
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 3 0 0 3 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 0 1 0 0 34 0 0 
+
+minGini: 1.600000 - 7
+Region.size: 35
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 0 0 4 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 0 0 0 0 30 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 4 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 
+
+minGini: 49.965556 - 11
+Region.size: 80
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 0 1 0 0 0 12 
+RightChild.size: 67
+RightChild.ClassCounts: 18 6 26 0 2 0 15 
+
+minGini: 33.562352 - 13
+Region.size: 67
+LeftChild.size: 50
+LeftChild.ClassCounts: 2 6 26 0 2 0 14 
+RightChild.size: 17
+RightChild.ClassCounts: 16 0 0 0 0 0 1 
+
+minGini: 0.000000 - 16
+Region.size: 17
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 16
+RightChild.ClassCounts: 16 0 0 0 0 0 0 
+
+minGini: 22.666666 - 0
+Region.size: 50
+LeftChild.size: 35
+LeftChild.ClassCounts: 2 3 25 0 2 0 3 
+RightChild.size: 15
+RightChild.ClassCounts: 0 3 1 0 0 0 11 
+
+minGini: 1.833333 - 1
+Region.size: 15
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 1 0 0 0 11 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 0 0 0 0 0 11 
+
+minGini: 12.387096 - 1
+Region.size: 35
+LeftChild.size: 31
+LeftChild.ClassCounts: 2 1 25 0 0 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 0 0 2 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 
+
+minGini: 6.203703 - 15
+Region.size: 31
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 1 0 0 0 0 1 
+RightChild.size: 27
+RightChild.ClassCounts: 0 0 25 0 0 0 2 
+
+minGini: 2.857142 - 1
+Region.size: 27
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 0 20 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 5 0 0 0 2 
+
+minGini: 2.000000 - 18
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 2 0 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 
+
+minGini: 1.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 18
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 0 0 0 0 0 12 
+
+
+
+Tree Number: 4 finished.
+
+minGini: 144.352272 - 16
+Region.size: 210
+LeftChild.size: 176
+LeftChild.ClassCounts: 45 28 30 31 24 0 18 
+RightChild.size: 34
+RightChild.ClassCounts: 0 0 0 0 0 34 0 
+
+minGini: 116.797297 - 14
+Region.size: 176
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 0 0 28 0 0 0 
+RightChild.size: 148
+RightChild.ClassCounts: 45 28 30 3 24 0 18 
+
+minGini: 98.090090 - 15
+Region.size: 148
+LeftChild.size: 111
+LeftChild.ClassCounts: 45 28 6 0 24 0 8 
+RightChild.size: 37
+RightChild.ClassCounts: 0 0 24 3 0 0 10 
+
+minGini: 4.615384 - 18
+Region.size: 37
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 0 24 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 0 3 0 0 10 
+
+minGini: 0.000000 - 1
+Region.size: 13
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 0 0 0 0 0 10 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 3 0 0 0 
+
+minGini: 55.303571 - 14
+Region.size: 111
+LeftChild.size: 48
+LeftChild.ClassCounts: 40 1 1 0 0 0 6 
+RightChild.size: 63
+RightChild.ClassCounts: 5 27 5 0 24 0 2 
+
+minGini: 35.000000 - 13
+Region.size: 63
+LeftChild.size: 58
+LeftChild.ClassCounts: 0 27 5 0 24 0 2 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 0 
+
+minGini: 31.127272 - 6
+Region.size: 58
+LeftChild.size: 55
+LeftChild.ClassCounts: 0 27 2 0 24 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 15.373333 - 7
+Region.size: 55
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 22 1 0 0 0 2 
+RightChild.size: 30
+RightChild.ClassCounts: 0 5 1 0 24 0 0 
+
+minGini: 6.416666 - 17
+Region.size: 30
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 4 0 0 2 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 0 1 1 0 22 0 0 
+
+minGini: 1.000000 - 11
+Region.size: 24
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 0 0 0 22 0 0 
+
+minGini: 0.000000 - 13
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 
+
+minGini: 1.913043 - 15
+Region.size: 25
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 22 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 
+
+minGini: 0.000000 - 16
+Region.size: 23
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 0 22 0 0 0 0 0 
+
+minGini: 8.127764 - 10
+Region.size: 48
+LeftChild.size: 11
+LeftChild.ClassCounts: 4 0 1 0 0 0 6 
+RightChild.size: 37
+RightChild.ClassCounts: 36 1 0 0 0 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 37
+LeftChild.size: 36
+LeftChild.ClassCounts: 36 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 1.600000 - 11
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 4 0 1 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 0 6 
+
+minGini: 0.000000 - 8
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+
+
+Tree Number: 5 finished.
+
+minGini: 146.079096 - 10
+Region.size: 210
+LeftChild.size: 177
+LeftChild.ClassCounts: 43 25 27 30 23 0 29 
+RightChild.size: 33
+RightChild.ClassCounts: 0 0 0 0 0 33 0 
+
+minGini: 123.399626 - 9
+Region.size: 177
+LeftChild.size: 126
+LeftChild.ClassCounts: 43 2 22 30 0 0 29 
+RightChild.size: 51
+RightChild.ClassCounts: 0 23 5 0 23 0 0 
+
+minGini: 24.811688 - 15
+Region.size: 51
+LeftChild.size: 44
+LeftChild.ClassCounts: 0 23 0 0 21 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 5 0 2 0 0 
+
+minGini: 0.000000 - 16
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 0 
+
+minGini: 16.452991 - 5
+Region.size: 44
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 19 0 0 7 0 0 
+RightChild.size: 18
+RightChild.ClassCounts: 0 4 0 0 14 0 0 
+
+minGini: 1.600000 - 12
+Region.size: 18
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 4 0 0 1 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 0 0 13 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 
+
+minGini: 5.833333 - 8
+Region.size: 26
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 5 0 0 7 0 0 
+
+minGini: 2.857142 - 13
+Region.size: 12
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 5 0 0 2 0 0 
+
+minGini: 1.333333 - 0
+Region.size: 7
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 
+
+minGini: 0.000000 - 16
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 80.959183 - 9
+Region.size: 126
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 0 14 0 0 0 14 
+RightChild.size: 98
+RightChild.ClassCounts: 43 2 8 30 0 0 15 
+
+minGini: 36.500000 - 18
+Region.size: 98
+LeftChild.size: 68
+LeftChild.ClassCounts: 43 2 8 0 0 0 15 
+RightChild.size: 30
+RightChild.ClassCounts: 0 0 0 30 0 0 0 
+
+minGini: 16.040579 - 18
+Region.size: 68
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 2 7 0 0 0 14 
+RightChild.size: 45
+RightChild.ClassCounts: 43 0 1 0 0 0 1 
+
+minGini: 2.953488 - 1
+Region.size: 45
+LeftChild.size: 43
+LeftChild.ClassCounts: 42 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 1 0 0 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 15
+Region.size: 43
+LeftChild.size: 42
+LeftChild.ClassCounts: 42 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 5.190476 - 5
+Region.size: 23
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 1 0 0 0 0 13 
+RightChild.size: 9
+RightChild.ClassCounts: 0 1 7 0 0 0 1 
+
+minGini: 1.750000 - 1
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 7 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 8
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 7 0 0 0 0 
+
+minGini: 0.000000 - 13
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 0 0 0 0 13 
+
+minGini: 7.935828 - 7
+Region.size: 28
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 1 0 0 0 10 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 13 0 0 0 4 
+
+minGini: 4.444444 - 13
+Region.size: 17
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 8 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 5 0 0 0 4 
+
+minGini: 1.666666 - 16
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 5 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 
+
+minGini: 0.000000 - 13
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 18
+Region.size: 11
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 0 0 0 0 10 
+
+
+
+Tree Number: 6 finished.
+
+minGini: 145.254237 - 14
+Region.size: 210
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 0 0 33 0 0 0 
+RightChild.size: 177
+RightChild.ClassCounts: 25 24 20 1 35 26 46 
+
+minGini: 117.247863 - 9
+Region.size: 177
+LeftChild.size: 99
+LeftChild.ClassCounts: 25 6 20 1 1 0 46 
+RightChild.size: 78
+RightChild.ClassCounts: 0 18 0 0 34 26 0 
+
+minGini: 23.538461 - 12
+Region.size: 78
+LeftChild.size: 52
+LeftChild.ClassCounts: 0 18 0 0 34 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 0 0 0 0 26 0 
+
+minGini: 8.717948 - 8
+Region.size: 52
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 13 0 0 0 0 0 
+RightChild.size: 39
+RightChild.ClassCounts: 0 5 0 0 34 0 0 
+
+minGini: 3.777777 - 7
+Region.size: 39
+LeftChild.size: 36
+LeftChild.ClassCounts: 0 2 0 0 34 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 36
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 
+RightChild.size: 34
+RightChild.ClassCounts: 0 0 0 0 34 0 0 
+
+minGini: 56.585784 - 10
+Region.size: 99
+LeftChild.size: 48
+LeftChild.ClassCounts: 1 0 15 0 0 0 32 
+RightChild.size: 51
+RightChild.ClassCounts: 24 6 5 1 1 0 14 
+
+minGini: 19.398148 - 18
+Region.size: 51
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 6 3 0 1 0 14 
+RightChild.size: 27
+RightChild.ClassCounts: 24 0 2 1 0 0 0 
+
+minGini: 2.500000 - 13
+Region.size: 27
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 0 2 1 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 23 0 0 0 0 0 0 
+
+minGini: 1.000000 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 
+
+minGini: 5.400000 - 1
+Region.size: 24
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 0 0 0 0 0 14 
+RightChild.size: 10
+RightChild.ClassCounts: 0 6 3 0 1 0 0 
+
+minGini: 1.714285 - 14
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 6 0 0 1 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 0.000000 - 11
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 
+
+minGini: 14.333333 - 7
+Region.size: 48
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 0 1 0 0 0 23 
+RightChild.size: 24
+RightChild.ClassCounts: 1 0 14 0 0 0 9 
+
+minGini: 1.800000 - 18
+Region.size: 24
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 0 14 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 1 0 0 0 0 0 9 
+
+minGini: 0.000000 - 13
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 0 0 9 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 24
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 0 0 0 0 0 23 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+
+
+Tree Number: 7 finished.
+
+minGini: 149.211111 - 11
+Region.size: 210
+LeftChild.size: 180
+LeftChild.ClassCounts: 24 25 33 28 38 0 32 
+RightChild.size: 30
+RightChild.ClassCounts: 0 0 0 0 0 30 0 
+
+minGini: 123.077922 - 14
+Region.size: 180
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 0 0 26 0 0 0 
+RightChild.size: 154
+RightChild.ClassCounts: 24 25 33 2 38 0 32 
+
+minGini: 100.734042 - 16
+Region.size: 154
+LeftChild.size: 94
+LeftChild.ClassCounts: 24 5 28 2 3 0 32 
+RightChild.size: 60
+RightChild.ClassCounts: 0 20 5 0 35 0 0 
+
+minGini: 18.043478 - 8
+Region.size: 60
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 0 0 0 0 
+RightChild.size: 46
+RightChild.ClassCounts: 0 6 5 0 35 0 0 
+
+minGini: 10.243902 - 7
+Region.size: 46
+LeftChild.size: 41
+LeftChild.ClassCounts: 0 6 0 0 35 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 41
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 0 
+RightChild.size: 35
+RightChild.ClassCounts: 0 0 0 0 35 0 0 
+
+minGini: 57.731707 - 15
+Region.size: 94
+LeftChild.size: 12
+LeftChild.ClassCounts: 12 0 0 0 0 0 0 
+RightChild.size: 82
+RightChild.ClassCounts: 12 5 28 2 3 0 32 
+
+minGini: 43.756097 - 18
+Region.size: 82
+LeftChild.size: 41
+LeftChild.ClassCounts: 0 1 28 0 3 0 9 
+RightChild.size: 41
+RightChild.ClassCounts: 12 4 0 2 0 0 23 
+
+minGini: 11.666666 - 13
+Region.size: 41
+LeftChild.size: 30
+LeftChild.ClassCounts: 1 4 0 2 0 0 23 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 0 0 0 0 0 
+
+minGini: 4.583333 - 5
+Region.size: 30
+LeftChild.size: 24
+LeftChild.ClassCounts: 1 0 0 0 0 0 23 
+RightChild.size: 6
+RightChild.ClassCounts: 0 4 0 2 0 0 0 
+
+minGini: 0.000000 - 14
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 
+
+minGini: 1.600000 - 13
+Region.size: 24
+LeftChild.size: 5
+LeftChild.ClassCounts: 1 0 0 0 0 0 4 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 0 0 0 0 19 
+
+minGini: 0.000000 - 18
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+minGini: 7.764367 - 17
+Region.size: 41
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 1 0 0 3 0 8 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 28 0 0 0 1 
+
+minGini: 1.500000 - 11
+Region.size: 29
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 0 25 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 3 0 0 0 1 
+
+minGini: 0.000000 - 12
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 1.500000 - 18
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 0 0 0 8 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 0 0 3 0 0 
+
+minGini: 0.000000 - 15
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+
+
+Tree Number: 8 finished.
+
+minGini: 144.632183 - 18
+Region.size: 210
+LeftChild.size: 174
+LeftChild.ClassCounts: 23 32 28 0 28 30 33 
+RightChild.size: 36
+RightChild.ClassCounts: 0 0 0 36 0 0 0 
+
+minGini: 114.763888 - 11
+Region.size: 174
+LeftChild.size: 144
+LeftChild.ClassCounts: 23 32 28 0 28 0 33 
+RightChild.size: 30
+RightChild.ClassCounts: 0 0 0 0 0 30 0 
+
+minGini: 97.993006 - 17
+Region.size: 144
+LeftChild.size: 66
+LeftChild.ClassCounts: 0 26 6 0 28 0 6 
+RightChild.size: 78
+RightChild.ClassCounts: 23 6 22 0 0 0 27 
+
+minGini: 46.597402 - 0
+Region.size: 78
+LeftChild.size: 56
+LeftChild.ClassCounts: 22 4 20 0 0 0 10 
+RightChild.size: 22
+RightChild.ClassCounts: 1 2 2 0 0 0 17 
+
+minGini: 5.300000 - 18
+Region.size: 22
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 
+RightChild.size: 20
+RightChild.ClassCounts: 1 0 2 0 0 0 17 
+
+minGini: 1.888888 - 10
+Region.size: 20
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 18
+RightChild.ClassCounts: 1 0 0 0 0 0 17 
+
+minGini: 0.000000 - 18
+Region.size: 18
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 0 0 0 0 0 17 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+minGini: 25.904761 - 15
+Region.size: 56
+LeftChild.size: 35
+LeftChild.ClassCounts: 22 4 3 0 0 0 6 
+RightChild.size: 21
+RightChild.ClassCounts: 0 0 17 0 0 0 4 
+
+minGini: 3.578947 - 13
+Region.size: 21
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 0 17 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 
+
+minGini: 2.400000 - 1
+Region.size: 19
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 0 14 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 3 0 0 0 2 
+
+minGini: 0.000000 - 17
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 8.307692 - 18
+Region.size: 35
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 4 3 0 0 0 6 
+RightChild.size: 22
+RightChild.ClassCounts: 22 0 0 0 0 0 0 
+
+minGini: 4.800000 - 18
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 4 0 0 0 0 6 
+
+minGini: 1.600000 - 0
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 0 5 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 0 0 1 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 
+
+minGini: 18.315789 - 1
+Region.size: 66
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 26 6 0 0 0 6 
+RightChild.size: 28
+RightChild.ClassCounts: 0 0 0 0 28 0 0 
+
+minGini: 9.750000 - 7
+Region.size: 38
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 0 6 
+RightChild.size: 32
+RightChild.ClassCounts: 0 26 6 0 0 0 0 
+
+minGini: 0.000000 - 18
+Region.size: 32
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 0 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 0 0 0 0 0 
+
+
+
+Tree Number: 9 finished.
+
+minGini: 144.724137 - 9
+Region.size: 210
+LeftChild.size: 174
+LeftChild.ClassCounts: 25 31 26 28 32 0 32 
+RightChild.size: 36
+RightChild.ClassCounts: 0 0 0 0 0 36 0 
+
+minGini: 121.391228 - 9
+Region.size: 174
+LeftChild.size: 114
+LeftChild.ClassCounts: 24 7 24 28 0 0 31 
+RightChild.size: 60
+RightChild.ClassCounts: 1 24 2 0 32 0 1 
+
+minGini: 29.474285 - 11
+Region.size: 60
+LeftChild.size: 25
+LeftChild.ClassCounts: 1 15 0 0 8 0 1 
+RightChild.size: 35
+RightChild.ClassCounts: 0 9 2 0 24 0 0 
+
+minGini: 11.483870 - 9
+Region.size: 35
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 5 2 0 24 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 
+
+minGini: 7.333333 - 15
+Region.size: 31
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 3 0 0 24 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 2 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 27
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 0 0 0 0 24 0 0 
+
+minGini: 8.846153 - 16
+Region.size: 25
+LeftChild.size: 12
+LeftChild.ClassCounts: 1 3 0 0 7 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 0 12 0 0 1 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 12 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 
+
+minGini: 4.514285 - 0
+Region.size: 12
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 0 0 0 6 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 3 0 0 1 0 1 
+
+minGini: 1.500000 - 7
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 0 0 1 0 0 
+
+minGini: 0.000000 - 10
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 
+
+minGini: 0.000000 - 14
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 6 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+minGini: 60.860465 - 15
+Region.size: 114
+LeftChild.size: 86
+LeftChild.ClassCounts: 24 7 24 0 0 0 31 
+RightChild.size: 28
+RightChild.ClassCounts: 0 0 0 28 0 0 0 
+
+minGini: 52.542723 - 7
+Region.size: 86
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 0 1 0 0 0 14 
+RightChild.size: 71
+RightChild.ClassCounts: 24 7 23 0 0 0 17 
+
+minGini: 38.831168 - 9
+Region.size: 71
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 0 18 0 0 0 4 
+RightChild.size: 49
+RightChild.ClassCounts: 24 7 5 0 0 0 13 
+
+minGini: 25.857142 - 14
+Region.size: 49
+LeftChild.size: 35
+LeftChild.ClassCounts: 24 2 1 0 0 0 8 
+RightChild.size: 14
+RightChild.ClassCounts: 0 5 4 0 0 0 5 
+
+minGini: 4.444444 - 11
+Region.size: 14
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 0 5 
+RightChild.size: 9
+RightChild.ClassCounts: 0 5 4 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 0 0 0 0 
+
+minGini: 11.978260 - 0
+Region.size: 35
+LeftChild.size: 23
+LeftChild.ClassCounts: 20 1 1 0 0 0 1 
+RightChild.size: 12
+RightChild.ClassCounts: 4 1 0 0 0 0 7 
+
+minGini: 1.750000 - 13
+Region.size: 12
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 1 0 0 0 0 7 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 0 0 7 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 3.727272 - 5
+Region.size: 23
+LeftChild.size: 22
+LeftChild.ClassCounts: 20 1 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 1.000000 - 18
+Region.size: 22
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 0 0 1 
+RightChild.size: 20
+RightChild.ClassCounts: 20 0 0 0 0 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 1.894736 - 18
+Region.size: 22
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 0 18 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 
+
+minGini: 1.000000 - 6
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 1 0 0 0 1 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 17 0 0 0 0 
+
+minGini: 0.000000 - 9
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 1.714285 - 12
+Region.size: 15
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 1 0 0 0 6 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 0 8 
+
+minGini: 0.000000 - 7
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 0 6 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+
+
+Tree Number: 10 finished.
+
+minGini: 152.974945 - 14
+Region.size: 210
+LeftChild.size: 102
+LeftChild.ClassCounts: 35 4 18 22 2 0 21 
+RightChild.size: 108
+RightChild.ClassCounts: 2 44 4 0 32 23 3 
+
+minGini: 49.835294 - 10
+Region.size: 108
+LeftChild.size: 85
+LeftChild.ClassCounts: 2 44 4 0 32 0 3 
+RightChild.size: 23
+RightChild.ClassCounts: 0 0 0 0 0 23 0 
+
+minGini: 36.163636 - 8
+Region.size: 85
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 27 0 0 0 0 3 
+RightChild.size: 55
+RightChild.ClassCounts: 2 17 4 0 32 0 0 
+
+minGini: 24.166666 - 17
+Region.size: 55
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 
+RightChild.size: 48
+RightChild.ClassCounts: 2 10 4 0 32 0 0 
+
+minGini: 17.224347 - 16
+Region.size: 48
+LeftChild.size: 23
+LeftChild.ClassCounts: 2 10 3 0 8 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 0 1 0 24 0 0 
+
+minGini: 1.500000 - 12
+Region.size: 25
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 0 0 0 21 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 1 0 3 0 0 
+
+minGini: 0.000000 - 10
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 3 0 0 
+
+minGini: 7.466666 - 1
+Region.size: 23
+LeftChild.size: 15
+LeftChild.ClassCounts: 2 10 3 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 8 0 0 
+
+minGini: 3.318181 - 0
+Region.size: 15
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 0 3 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 1 10 0 0 0 0 0 
+
+minGini: 1.500000 - 17
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 1 3 0 0 0 0 0 
+
+minGini: 0.000000 - 9
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 10
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+minGini: 0.000000 - 11
+Region.size: 30
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 3 
+RightChild.size: 27
+RightChild.ClassCounts: 0 27 0 0 0 0 0 
+
+minGini: 54.875000 - 15
+Region.size: 102
+LeftChild.size: 80
+LeftChild.ClassCounts: 35 4 18 0 2 0 21 
+RightChild.size: 22
+RightChild.ClassCounts: 0 0 0 22 0 0 0 
+
+minGini: 45.150777 - 16
+Region.size: 80
+LeftChild.size: 29
+LeftChild.ClassCounts: 3 0 15 0 0 0 11 
+RightChild.size: 51
+RightChild.ClassCounts: 32 4 3 0 2 0 10 
+
+minGini: 14.360714 - 13
+Region.size: 51
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 1 3 0 2 0 10 
+RightChild.size: 35
+RightChild.ClassCounts: 32 3 0 0 0 0 0 
+
+minGini: 0.000000 - 9
+Region.size: 35
+LeftChild.size: 32
+LeftChild.ClassCounts: 32 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 
+
+minGini: 6.142857 - 8
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 1 3 0 0 0 10 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 
+
+minGini: 4.285714 - 11
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 1 3 0 0 0 3 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 0 7 
+
+minGini: 2.800000 - 15
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 3 0 0 0 1 
+
+minGini: 1.000000 - 8
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 0 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 0.000000 - 18
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 9.363636 - 1
+Region.size: 29
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 0 15 0 0 0 3 
+RightChild.size: 11
+RightChild.ClassCounts: 3 0 0 0 0 0 8 
+
+minGini: 0.000000 - 9
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 0 0 0 8 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 
+
+minGini: 1.500000 - 11
+Region.size: 18
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 1 0 0 0 3 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 14 0 0 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+
+
+Tree Number: 11 finished.
+
+minGini: 148.960893 - 12
+Region.size: 210
+LeftChild.size: 179
+LeftChild.ClassCounts: 30 28 31 34 26 0 30 
+RightChild.size: 31
+RightChild.ClassCounts: 0 0 0 0 0 31 0 
+
+minGini: 115.889655 - 15
+Region.size: 179
+LeftChild.size: 145
+LeftChild.ClassCounts: 30 28 31 0 26 0 30 
+RightChild.size: 34
+RightChild.ClassCounts: 0 0 0 34 0 0 0 
+
+minGini: 92.246235 - 10
+Region.size: 145
+LeftChild.size: 91
+LeftChild.ClassCounts: 30 3 28 0 0 0 30 
+RightChild.size: 54
+RightChild.ClassCounts: 0 25 3 0 26 0 0 
+
+minGini: 5.357142 - 1
+Region.size: 54
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 25 3 0 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 0 0 0 26 0 0 
+
+minGini: 0.000000 - 15
+Region.size: 28
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 25 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 46.468298 - 0
+Region.size: 91
+LeftChild.size: 62
+LeftChild.ClassCounts: 29 2 25 0 0 0 6 
+RightChild.size: 29
+RightChild.ClassCounts: 1 1 3 0 0 0 24 
+
+minGini: 6.481481 - 5
+Region.size: 29
+LeftChild.size: 27
+LeftChild.ClassCounts: 1 0 2 0 0 0 24 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 0 
+
+minGini: 0.000000 - 14
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 4.727272 - 6
+Region.size: 27
+LeftChild.size: 11
+LeftChild.ClassCounts: 1 0 2 0 0 0 8 
+RightChild.size: 16
+RightChild.ClassCounts: 0 0 0 0 0 0 16 
+
+minGini: 3.200000 - 10
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 0 2 0 0 0 8 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+minGini: 2.000000 - 11
+Region.size: 10
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 0 6 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 2 0 0 0 2 
+
+minGini: 0.000000 - 9
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 
+
+minGini: 12.848484 - 18
+Region.size: 62
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 2 25 0 0 0 6 
+RightChild.size: 29
+RightChild.ClassCounts: 29 0 0 0 0 0 0 
+
+minGini: 7.250000 - 17
+Region.size: 33
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 2 2 0 0 0 5 
+RightChild.size: 24
+RightChild.ClassCounts: 0 0 23 0 0 0 1 
+
+minGini: 1.333333 - 7
+Region.size: 24
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 2 0 0 0 1 
+RightChild.size: 21
+RightChild.ClassCounts: 0 0 21 0 0 0 0 
+
+minGini: 0.000000 - 11
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 2.857142 - 9
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 2 0 0 0 0 5 
+
+minGini: 0.000000 - 0
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+
+
+Tree Number: 12 finished.
+
+minGini: 148.217506 - 1
+Region.size: 210
+LeftChild.size: 145
+LeftChild.ClassCounts: 29 30 29 2 0 30 25 
+RightChild.size: 65
+RightChild.ClassCounts: 0 0 0 27 38 0 0 
+
+minGini: 0.000000 - 10
+Region.size: 65
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 0 0 27 0 0 0 
+RightChild.size: 38
+RightChild.ClassCounts: 0 0 0 0 38 0 0 
+
+minGini: 87.078260 - 16
+Region.size: 145
+LeftChild.size: 115
+LeftChild.ClassCounts: 29 30 29 2 0 0 25 
+RightChild.size: 30
+RightChild.ClassCounts: 0 0 0 0 0 30 0 
+
+minGini: 67.839477 - 11
+Region.size: 115
+LeftChild.size: 84
+LeftChild.ClassCounts: 29 4 24 2 0 0 25 
+RightChild.size: 31
+RightChild.ClassCounts: 0 26 5 0 0 0 0 
+
+minGini: 6.690476 - 10
+Region.size: 31
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 25 3 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 2 0 0 0 0 
+
+minGini: 0.000000 - 16
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 2.400000 - 8
+Region.size: 28
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 23 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 2 3 0 0 0 0 
+
+minGini: 0.000000 - 18
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+minGini: 52.651461 - 7
+Region.size: 84
+LeftChild.size: 23
+LeftChild.ClassCounts: 4 0 3 0 0 0 16 
+RightChild.size: 61
+RightChild.ClassCounts: 25 4 21 2 0 0 9 
+
+minGini: 38.421951 - 8
+Region.size: 61
+LeftChild.size: 20
+LeftChild.ClassCounts: 14 1 4 0 0 0 1 
+RightChild.size: 41
+RightChild.ClassCounts: 11 3 17 2 0 0 8 
+
+minGini: 18.230769 - 18
+Region.size: 41
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 0 15 0 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 11 3 2 2 0 0 8 
+
+minGini: 9.600000 - 15
+Region.size: 26
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 0 0 0 0 0 
+RightChild.size: 15
+RightChild.ClassCounts: 0 3 2 2 0 0 8 
+
+minGini: 6.600000 - 12
+Region.size: 15
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 1 1 0 0 0 8 
+RightChild.size: 5
+RightChild.ClassCounts: 0 2 1 2 0 0 0 
+
+minGini: 1.333333 - 11
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 1 2 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 2 0 0 0 
+
+minGini: 1.777777 - 17
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 1 0 0 0 0 8 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 1.333333 - 7
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 0 0 0 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 0 6 
+
+minGini: 0.000000 - 8
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 
+
+minGini: 3.466666 - 17
+Region.size: 20
+LeftChild.size: 15
+LeftChild.ClassCounts: 14 1 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 4 0 0 0 1 
+
+minGini: 0.000000 - 13
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 1.500000 - 14
+Region.size: 15
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 0 0 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 
+
+minGini: 7.607843 - 10
+Region.size: 23
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 0 3 0 0 0 14 
+RightChild.size: 6
+RightChild.ClassCounts: 4 0 0 0 0 0 2 
+
+minGini: 0.000000 - 12
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 
+
+minGini: 4.000000 - 12
+Region.size: 17
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 3 0 0 0 6 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 0 8 
+
+minGini: 0.000000 - 16
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 0 6 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+
+
+Tree Number: 13 finished.
+
+minGini: 152.641304 - 9
+Region.size: 210
+LeftChild.size: 184
+LeftChild.ClassCounts: 30 29 35 24 28 0 38 
+RightChild.size: 26
+RightChild.ClassCounts: 0 0 0 0 0 26 0 
+
+minGini: 127.537500 - 15
+Region.size: 184
+LeftChild.size: 160
+LeftChild.ClassCounts: 30 29 35 0 28 0 38 
+RightChild.size: 24
+RightChild.ClassCounts: 0 0 0 24 0 0 0 
+
+minGini: 108.307692 - 11
+Region.size: 160
+LeftChild.size: 104
+LeftChild.ClassCounts: 30 4 27 0 5 0 38 
+RightChild.size: 56
+RightChild.ClassCounts: 0 25 8 0 23 0 0 
+
+minGini: 15.210322 - 7
+Region.size: 56
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 24 0 0 1 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 0 1 8 0 22 0 0 
+
+minGini: 1.913043 - 13
+Region.size: 31
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 8 0 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 1 0 0 22 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 23
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 0 0 0 22 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 1.600000 - 7
+Region.size: 25
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 20 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 0 0 1 0 0 
+
+minGini: 0.000000 - 16
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 
+
+minGini: 62.456250 - 9
+Region.size: 104
+LeftChild.size: 40
+LeftChild.ClassCounts: 0 0 22 0 0 0 18 
+RightChild.size: 64
+RightChild.ClassCounts: 30 4 5 0 5 0 20 
+
+minGini: 36.269230 - 0
+Region.size: 64
+LeftChild.size: 52
+LeftChild.ClassCounts: 29 3 5 0 5 0 10 
+RightChild.size: 12
+RightChild.ClassCounts: 1 1 0 0 0 0 10 
+
+minGini: 1.818181 - 6
+Region.size: 12
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 1 0 0 0 0 10 
+
+minGini: 0.000000 - 1
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 0 0 0 0 0 10 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 22.290370 - 14
+Region.size: 52
+LeftChild.size: 25
+LeftChild.ClassCounts: 24 1 0 0 0 0 0 
+RightChild.size: 27
+RightChild.ClassCounts: 5 2 5 0 5 0 10 
+
+minGini: 14.411764 - 13
+Region.size: 27
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 2 5 0 0 0 10 
+RightChild.size: 10
+RightChild.ClassCounts: 5 0 0 0 5 0 0 
+
+minGini: 0.000000 - 18
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 5 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 0 
+
+minGini: 3.333333 - 17
+Region.size: 17
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 2 0 0 0 0 10 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 0 
+
+minGini: 1.333333 - 18
+Region.size: 12
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 0 0 0 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 0 0 9 
+
+minGini: 0.000000 - 18
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 25
+LeftChild.size: 24
+LeftChild.ClassCounts: 24 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 6.769230 - 13
+Region.size: 40
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 0 22 0 0 0 4 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 0 0 14 
+
+minGini: 4.304761 - 8
+Region.size: 26
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 2 0 0 0 3 
+RightChild.size: 21
+RightChild.ClassCounts: 0 0 20 0 0 0 1 
+
+minGini: 0.000000 - 10
+Region.size: 21
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 0 20 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 16
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 
+
+
+
+Tree Number: 14 finished.
+
+minGini: 150.548373 - 1
+Region.size: 210
+LeftChild.size: 146
+LeftChild.ClassCounts: 30 28 30 0 0 28 30 
+RightChild.size: 64
+RightChild.ClassCounts: 0 2 0 29 33 0 0 
+
+minGini: 3.741935 - 18
+Region.size: 64
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 0 0 0 33 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 0 2 0 29 0 0 0 
+
+minGini: 0.000000 - 13
+Region.size: 31
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 0 0 29 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+minGini: 88.474576 - 12
+Region.size: 146
+LeftChild.size: 118
+LeftChild.ClassCounts: 30 28 30 0 0 0 30 
+RightChild.size: 28
+RightChild.ClassCounts: 0 0 0 0 0 28 0 
+
+minGini: 66.751515 - 10
+Region.size: 118
+LeftChild.size: 88
+LeftChild.ClassCounts: 30 2 26 0 0 0 30 
+RightChild.size: 30
+RightChild.ClassCounts: 0 26 4 0 0 0 0 
+
+minGini: 0.000000 - 15
+Region.size: 30
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 26 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 0 
+
+minGini: 37.400000 - 18
+Region.size: 88
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 1 25 0 0 0 2 
+RightChild.size: 60
+RightChild.ClassCounts: 30 1 1 0 0 0 28 
+
+minGini: 19.555555 - 9
+Region.size: 60
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 0 1 0 0 0 17 
+RightChild.size: 42
+RightChild.ClassCounts: 30 1 0 0 0 0 11 
+
+minGini: 13.769230 - 15
+Region.size: 42
+LeftChild.size: 16
+LeftChild.ClassCounts: 16 0 0 0 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 14 1 0 0 0 0 11 
+
+minGini: 5.176470 - 1
+Region.size: 26
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 0 0 9 
+RightChild.size: 17
+RightChild.ClassCounts: 14 1 0 0 0 0 2 
+
+minGini: 1.333333 - 14
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 14 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 0 0 2 
+
+minGini: 1.000000 - 11
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 0 0 1 
+
+minGini: 0.000000 - 12
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 1.500000 - 1
+Region.size: 18
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 1 0 0 0 3 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 0 0 14 
+
+minGini: 0.000000 - 15
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 2.500000 - 17
+Region.size: 28
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 1 0 0 0 2 
+RightChild.size: 24
+RightChild.ClassCounts: 0 0 24 0 0 0 0 
+
+minGini: 1.000000 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 0 
+
+minGini: 0.000000 - 10
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+
+
+Tree Number: 15 finished.
+
+minGini: 145.977272 - 15
+Region.size: 210
+LeftChild.size: 176
+LeftChild.ClassCounts: 29 35 32 0 21 32 27 
+RightChild.size: 34
+RightChild.ClassCounts: 0 0 0 34 0 0 0 
+
+minGini: 124.381944 - 17
+Region.size: 176
+LeftChild.size: 144
+LeftChild.ClassCounts: 29 35 5 0 21 32 22 
+RightChild.size: 32
+RightChild.ClassCounts: 0 0 27 0 0 0 5 
+
+minGini: 7.368421 - 17
+Region.size: 32
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 0 14 0 0 0 5 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 13 0 0 0 0 
+
+minGini: 4.941176 - 9
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 14 0 0 0 3 
+
+minGini: 1.866666 - 1
+Region.size: 17
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 15
+RightChild.ClassCounts: 0 0 14 0 0 0 1 
+
+minGini: 0.000000 - 18
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 0 14 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 85.071428 - 16
+Region.size: 144
+LeftChild.size: 112
+LeftChild.ClassCounts: 29 35 5 0 21 0 22 
+RightChild.size: 32
+RightChild.ClassCounts: 0 0 0 0 0 32 0 
+
+minGini: 62.703296 - 1
+Region.size: 112
+LeftChild.size: 91
+LeftChild.ClassCounts: 29 35 5 0 0 0 22 
+RightChild.size: 21
+RightChild.ClassCounts: 0 0 0 0 21 0 0 
+
+minGini: 38.308565 - 18
+Region.size: 91
+LeftChild.size: 57
+LeftChild.ClassCounts: 0 35 4 0 0 0 18 
+RightChild.size: 34
+RightChild.ClassCounts: 29 0 1 0 0 0 4 
+
+minGini: 3.806451 - 10
+Region.size: 34
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 3 
+RightChild.size: 31
+RightChild.ClassCounts: 29 0 1 0 0 0 1 
+
+minGini: 2.500000 - 18
+Region.size: 31
+LeftChild.size: 4
+LeftChild.ClassCounts: 2 0 1 0 0 0 1 
+RightChild.size: 27
+RightChild.ClassCounts: 27 0 0 0 0 0 0 
+
+minGini: 1.000000 - 16
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 1 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 15
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 17.034739 - 16
+Region.size: 57
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 7 1 0 0 0 18 
+RightChild.size: 31
+RightChild.ClassCounts: 0 28 3 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 31
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 28 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 6.957575 - 1
+Region.size: 26
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 0 1 0 0 0 14 
+RightChild.size: 11
+RightChild.ClassCounts: 0 7 0 0 0 0 4 
+
+minGini: 0.000000 - 16
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 4 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 0 0 0 0 
+
+minGini: 0.000000 - 18
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 0 0 14 
+
+
+
+Tree Number: 16 finished.
+
+minGini: 147.117318 - 11
+Region.size: 210
+LeftChild.size: 179
+LeftChild.ClassCounts: 42 22 31 29 19 0 36 
+RightChild.size: 31
+RightChild.ClassCounts: 0 0 0 0 0 31 0 
+
+minGini: 117.560000 - 15
+Region.size: 179
+LeftChild.size: 150
+LeftChild.ClassCounts: 42 22 31 0 19 0 36 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 0 29 0 0 0 
+
+minGini: 98.961988 - 9
+Region.size: 150
+LeftChild.size: 114
+LeftChild.ClassCounts: 42 7 29 0 0 0 36 
+RightChild.size: 36
+RightChild.ClassCounts: 0 15 2 0 19 0 0 
+
+minGini: 9.760000 - 17
+Region.size: 36
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 0 0 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 4 2 0 19 0 0 
+
+minGini: 6.956521 - 9
+Region.size: 25
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 
+RightChild.size: 23
+RightChild.ClassCounts: 0 2 2 0 19 0 0 
+
+minGini: 3.619047 - 13
+Region.size: 23
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 2 0 0 19 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 21
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 0 0 19 0 0 
+
+minGini: 60.868421 - 10
+Region.size: 114
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 0 26 0 0 0 12 
+RightChild.size: 76
+RightChild.ClassCounts: 42 7 3 0 0 0 24 
+
+minGini: 28.654634 - 0
+Region.size: 76
+LeftChild.size: 53
+LeftChild.ClassCounts: 40 5 3 0 0 0 5 
+RightChild.size: 23
+RightChild.ClassCounts: 2 2 0 0 0 0 19 
+
+minGini: 3.619047 - 13
+Region.size: 23
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 2 0 0 0 0 19 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 
+
+minGini: 1.900000 - 15
+Region.size: 21
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 20
+RightChild.ClassCounts: 0 1 0 0 0 0 19 
+
+minGini: 1.000000 - 12
+Region.size: 20
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 0 0 0 0 0 18 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 0 0 1 
+
+minGini: 0.000000 - 8
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 12.120930 - 13
+Region.size: 53
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 4 2 0 0 0 4 
+RightChild.size: 43
+RightChild.ClassCounts: 40 1 1 0 0 0 1 
+
+minGini: 3.857142 - 10
+Region.size: 43
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 42
+RightChild.ClassCounts: 40 1 1 0 0 0 0 
+
+minGini: 1.951219 - 1
+Region.size: 42
+LeftChild.size: 41
+LeftChild.ClassCounts: 40 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 1.857142 - 18
+Region.size: 41
+LeftChild.size: 14
+LeftChild.ClassCounts: 13 0 1 0 0 0 0 
+RightChild.size: 27
+RightChild.ClassCounts: 27 0 0 0 0 0 0 
+
+minGini: 0.000000 - 18
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 4.000000 - 18
+Region.size: 10
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 4 0 0 0 0 4 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 4 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 
+
+minGini: 8.387096 - 13
+Region.size: 38
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 0 26 0 0 0 5 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 0 7 
+
+minGini: 6.933333 - 0
+Region.size: 31
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 0 26 0 0 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 1.925925 - 18
+Region.size: 30
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 0 26 0 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 
+
+minGini: 1.333333 - 6
+Region.size: 27
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 2 0 0 0 1 
+RightChild.size: 24
+RightChild.ClassCounts: 0 0 24 0 0 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+
+
+Tree Number: 17 finished.
+
+minGini: 142.280701 - 11
+Region.size: 210
+LeftChild.size: 171
+LeftChild.ClassCounts: 31 26 26 31 31 0 26 
+RightChild.size: 39
+RightChild.ClassCounts: 0 0 0 0 0 39 0 
+
+minGini: 119.193057 - 9
+Region.size: 171
+LeftChild.size: 121
+LeftChild.ClassCounts: 31 6 25 31 2 0 26 
+RightChild.size: 50
+RightChild.ClassCounts: 0 20 1 0 29 0 0 
+
+minGini: 12.051470 - 7
+Region.size: 50
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 15 0 0 1 0 0 
+RightChild.size: 34
+RightChild.ClassCounts: 0 5 1 0 28 0 0 
+
+minGini: 1.666666 - 1
+Region.size: 34
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 5 1 0 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 0 0 0 0 28 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 1.000000 - 12
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 0 0 1 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 
+
+minGini: 64.422222 - 15
+Region.size: 121
+LeftChild.size: 90
+LeftChild.ClassCounts: 31 6 25 0 2 0 26 
+RightChild.size: 31
+RightChild.ClassCounts: 0 0 0 31 0 0 0 
+
+minGini: 54.612980 - 10
+Region.size: 90
+LeftChild.size: 26
+LeftChild.ClassCounts: 0 0 17 0 0 0 9 
+RightChild.size: 64
+RightChild.ClassCounts: 31 6 8 0 2 0 17 
+
+minGini: 32.879765 - 14
+Region.size: 64
+LeftChild.size: 33
+LeftChild.ClassCounts: 27 1 1 0 0 0 4 
+RightChild.size: 31
+RightChild.ClassCounts: 4 5 7 0 2 0 13 
+
+minGini: 15.083333 - 18
+Region.size: 31
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 7 0 0 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 4 5 0 0 2 0 13 
+
+minGini: 9.482517 - 6
+Region.size: 24
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 1 0 0 0 0 12 
+RightChild.size: 11
+RightChild.ClassCounts: 4 4 0 0 2 0 1 
+
+minGini: 4.000000 - 8
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 4 0 0 0 2 0 1 
+
+minGini: 1.333333 - 18
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 2 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 2 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 8
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 0 0 0 0 12 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 3.793103 - 18
+Region.size: 33
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 4 
+RightChild.size: 29
+RightChild.ClassCounts: 27 1 1 0 0 0 0 
+
+minGini: 1.000000 - 13
+Region.size: 29
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 0 0 0 0 
+RightChild.size: 27
+RightChild.ClassCounts: 27 0 0 0 0 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 5.538461 - 9
+Region.size: 26
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 0 4 0 0 0 9 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 13 0 0 0 0 
+
+minGini: 0.000000 - 18
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 0 0 0 0 9 
+
+
+
+Tree Number: 18 finished.
+
+minGini: 146.327683 - 12
+Region.size: 210
+LeftChild.size: 177
+LeftChild.ClassCounts: 27 27 39 28 35 0 21 
+RightChild.size: 33
+RightChild.ClassCounts: 0 0 0 0 0 33 0 
+
+minGini: 121.340852 - 11
+Region.size: 177
+LeftChild.size: 114
+LeftChild.ClassCounts: 27 4 34 28 0 0 21 
+RightChild.size: 63
+RightChild.ClassCounts: 0 23 5 0 35 0 0 
+
+minGini: 21.442583 - 7
+Region.size: 63
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 17 0 0 2 0 0 
+RightChild.size: 44
+RightChild.ClassCounts: 0 6 5 0 33 0 0 
+
+minGini: 5.454545 - 1
+Region.size: 44
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 6 5 0 0 0 0 
+RightChild.size: 33
+RightChild.ClassCounts: 0 0 0 0 33 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 11
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 0 
+
+minGini: 1.333333 - 8
+Region.size: 19
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 2 0 0 
+
+minGini: 0.000000 - 10
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 2 0 0 
+
+minGini: 58.767441 - 15
+Region.size: 114
+LeftChild.size: 86
+LeftChild.ClassCounts: 27 4 34 0 0 0 21 
+RightChild.size: 28
+RightChild.ClassCounts: 0 0 0 28 0 0 0 
+
+minGini: 44.232608 - 9
+Region.size: 86
+LeftChild.size: 40
+LeftChild.ClassCounts: 1 0 29 0 0 0 10 
+RightChild.size: 46
+RightChild.ClassCounts: 26 4 5 0 0 0 11 
+
+minGini: 15.174193 - 18
+Region.size: 46
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 2 2 0 0 0 11 
+RightChild.size: 31
+RightChild.ClassCounts: 26 2 3 0 0 0 0 
+
+minGini: 3.714285 - 5
+Region.size: 31
+LeftChild.size: 28
+LeftChild.ClassCounts: 26 2 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 1.925925 - 17
+Region.size: 28
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 27
+RightChild.ClassCounts: 26 1 0 0 0 0 0 
+
+minGini: 1.600000 - 0
+Region.size: 27
+LeftChild.size: 22
+LeftChild.ClassCounts: 22 0 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 4 1 0 0 0 0 0 
+
+minGini: 0.000000 - 9
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 3.384615 - 18
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 2 0 0 0 0 11 
+
+minGini: 2.000000 - 8
+Region.size: 13
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 0 0 9 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 0 0 0 0 2 
+
+minGini: 0.000000 - 14
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 
+
+minGini: 12.777777 - 14
+Region.size: 40
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 0 0 0 0 0 3 
+RightChild.size: 36
+RightChild.ClassCounts: 0 0 29 0 0 0 7 
+
+minGini: 1.933333 - 18
+Region.size: 36
+LeftChild.size: 30
+LeftChild.ClassCounts: 0 0 29 0 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 0 6 
+
+minGini: 1.333333 - 0
+Region.size: 30
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 2 0 0 0 1 
+RightChild.size: 27
+RightChild.ClassCounts: 0 0 27 0 0 0 0 
+
+minGini: 0.000000 - 9
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 11
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+
+
+Tree Number: 19 finished.
+
+minGini: 142.187134 - 15
+Region.size: 210
+LeftChild.size: 171
+LeftChild.ClassCounts: 26 27 34 0 25 30 29 
+RightChild.size: 39
+RightChild.ClassCounts: 0 0 0 39 0 0 0 
+
+minGini: 112.439716 - 16
+Region.size: 171
+LeftChild.size: 141
+LeftChild.ClassCounts: 26 27 34 0 25 0 29 
+RightChild.size: 30
+RightChild.ClassCounts: 0 0 0 0 0 30 0 
+
+minGini: 89.786949 - 9
+Region.size: 141
+LeftChild.size: 89
+LeftChild.ClassCounts: 26 3 31 0 0 0 29 
+RightChild.size: 52
+RightChild.ClassCounts: 0 24 3 0 25 0 0 
+
+minGini: 17.662500 - 7
+Region.size: 52
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 18 0 0 2 0 0 
+RightChild.size: 32
+RightChild.ClassCounts: 0 6 3 0 23 0 0 
+
+minGini: 9.217391 - 13
+Region.size: 32
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 0 3 0 20 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 6 0 0 3 0 0 
+
+minGini: 0.000000 - 10
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 3 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 23
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 0 
+RightChild.size: 20
+RightChild.ClassCounts: 0 0 0 0 20 0 0 
+
+minGini: 1.894736 - 8
+Region.size: 20
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 18 0 0 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 19
+LeftChild.size: 18
+LeftChild.ClassCounts: 0 18 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 
+
+minGini: 48.933333 - 13
+Region.size: 89
+LeftChild.size: 75
+LeftChild.ClassCounts: 12 3 31 0 0 0 29 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 0 0 0 0 0 
+
+minGini: 42.883522 - 9
+Region.size: 75
+LeftChild.size: 64
+LeftChild.ClassCounts: 4 3 30 0 0 0 27 
+RightChild.size: 11
+RightChild.ClassCounts: 8 0 1 0 0 0 2 
+
+minGini: 1.333333 - 15
+Region.size: 11
+LeftChild.size: 8
+LeftChild.ClassCounts: 8 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 1 0 0 0 2 
+
+minGini: 0.000000 - 18
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 
+
+minGini: 31.718181 - 7
+Region.size: 64
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 0 4 0 0 0 16 
+RightChild.size: 44
+RightChild.ClassCounts: 4 3 26 0 0 0 11 
+
+minGini: 18.694736 - 18
+Region.size: 44
+LeftChild.size: 19
+LeftChild.ClassCounts: 0 1 18 0 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 4 2 8 0 0 0 11 
+
+minGini: 11.632352 - 16
+Region.size: 25
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 7 0 0 0 1 
+RightChild.size: 17
+RightChild.ClassCounts: 4 2 1 0 0 0 10 
+
+minGini: 6.428571 - 10
+Region.size: 17
+LeftChild.size: 14
+LeftChild.ClassCounts: 1 2 1 0 0 0 10 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 0 0 0 0 
+
+minGini: 4.923076 - 12
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 1 2 0 0 0 0 10 
+
+minGini: 3.333333 - 14
+Region.size: 13
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 2 0 0 0 0 10 
+
+minGini: 0.000000 - 1
+Region.size: 12
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 0 0 0 0 0 10 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+minGini: 1.000000 - 0
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 1 0 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 6 0 0 0 0 
+
+minGini: 0.000000 - 14
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 0.000000 - 15
+Region.size: 19
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 18
+RightChild.ClassCounts: 0 0 18 0 0 0 0 
+
+minGini: 1.600000 - 18
+Region.size: 20
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 4 0 0 0 1 
+RightChild.size: 15
+RightChild.ClassCounts: 0 0 0 0 0 0 15 
+
+minGini: 0.000000 - 11
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+
+
+Tree Number: 20 finished.
+
+minGini: 150.375690 - 15
+Region.size: 210
+LeftChild.size: 181
+LeftChild.ClassCounts: 34 23 31 0 33 32 28 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 0 29 0 0 0 
+
+minGini: 118.671140 - 9
+Region.size: 181
+LeftChild.size: 149
+LeftChild.ClassCounts: 34 23 31 0 33 0 28 
+RightChild.size: 32
+RightChild.ClassCounts: 0 0 0 0 0 32 0 
+
+minGini: 93.771609 - 12
+Region.size: 149
+LeftChild.size: 88
+LeftChild.ClassCounts: 34 1 27 0 0 0 26 
+RightChild.size: 61
+RightChild.ClassCounts: 0 22 4 0 33 0 2 
+
+minGini: 10.000000 - 1
+Region.size: 61
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 22 4 0 0 0 2 
+RightChild.size: 33
+RightChild.ClassCounts: 0 0 0 0 33 0 0 
+
+minGini: 5.252173 - 4
+Region.size: 28
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 21 0 0 0 0 2 
+RightChild.size: 5
+RightChild.ClassCounts: 0 1 4 0 0 0 0 
+
+minGini: 0.000000 - 10
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 0 
+
+minGini: 1.333333 - 15
+Region.size: 23
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 20 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 1 0 0 0 0 2 
+
+minGini: 0.000000 - 10
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 53.651195 - 14
+Region.size: 88
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 0 0 0 0 0 8 
+RightChild.size: 79
+RightChild.ClassCounts: 33 1 27 0 0 0 18 
+
+minGini: 48.173333 - 14
+Region.size: 79
+LeftChild.size: 25
+LeftChild.ClassCounts: 17 0 6 0 0 0 2 
+RightChild.size: 54
+RightChild.ClassCounts: 16 1 21 0 0 0 16 
+
+minGini: 31.440789 - 1
+Region.size: 54
+LeftChild.size: 16
+LeftChild.ClassCounts: 10 0 1 0 0 0 5 
+RightChild.size: 38
+RightChild.ClassCounts: 6 1 20 0 0 0 11 
+
+minGini: 11.900000 - 17
+Region.size: 38
+LeftChild.size: 20
+LeftChild.ClassCounts: 6 1 2 0 0 0 11 
+RightChild.size: 18
+RightChild.ClassCounts: 0 0 18 0 0 0 0 
+
+minGini: 5.252747 - 15
+Region.size: 20
+LeftChild.size: 7
+LeftChild.ClassCounts: 6 0 1 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 1 1 0 0 0 11 
+
+minGini: 1.833333 - 12
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 1 0 0 0 11 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 0.000000 - 18
+Region.size: 12
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 0 0 0 0 11 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 0.000000 - 10
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 0 0 0 0 
+
+minGini: 1.818181 - 9
+Region.size: 16
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 0 5 
+RightChild.size: 11
+RightChild.ClassCounts: 10 0 1 0 0 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 11
+LeftChild.size: 10
+LeftChild.ClassCounts: 10 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 3.000000 - 11
+Region.size: 25
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 6 0 0 0 2 
+RightChild.size: 17
+RightChild.ClassCounts: 17 0 0 0 0 0 0 
+
+minGini: 0.000000 - 16
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 0 0 0 0 2 
+
+minGini: 0.000000 - 0
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 0 8 
+
+
+
+Tree Number: 21 finished.
+
+minGini: 145.863636 - 16
+Region.size: 210
+LeftChild.size: 176
+LeftChild.ClassCounts: 27 30 28 39 29 0 23 
+RightChild.size: 34
+RightChild.ClassCounts: 0 0 0 0 0 34 0 
+
+minGini: 109.386861 - 18
+Region.size: 176
+LeftChild.size: 137
+LeftChild.ClassCounts: 27 30 28 0 29 0 23 
+RightChild.size: 39
+RightChild.ClassCounts: 0 0 0 39 0 0 0 
+
+minGini: 91.313537 - 13
+Region.size: 137
+LeftChild.size: 108
+LeftChild.ClassCounts: 4 30 28 0 29 0 17 
+RightChild.size: 29
+RightChild.ClassCounts: 23 0 0 0 0 0 6 
+
+minGini: 0.000000 - 9
+Region.size: 29
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 0 6 
+RightChild.size: 23
+RightChild.ClassCounts: 23 0 0 0 0 0 0 
+
+minGini: 53.822784 - 1
+Region.size: 108
+LeftChild.size: 79
+LeftChild.ClassCounts: 4 30 28 0 0 0 17 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 0 0 29 0 0 
+
+minGini: 40.872592 - 11
+Region.size: 79
+LeftChild.size: 54
+LeftChild.ClassCounts: 4 8 25 0 0 0 17 
+RightChild.size: 25
+RightChild.ClassCounts: 0 22 3 0 0 0 0 
+
+minGini: 0.000000 - 15
+Region.size: 25
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 22 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 29.815217 - 1
+Region.size: 54
+LeftChild.size: 46
+LeftChild.ClassCounts: 3 2 25 0 0 0 16 
+RightChild.size: 8
+RightChild.ClassCounts: 1 6 0 0 0 0 1 
+
+minGini: 1.000000 - 11
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 0 0 0 0 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 6 0 0 0 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 21.470967 - 17
+Region.size: 46
+LeftChild.size: 15
+LeftChild.ClassCounts: 3 2 2 0 0 0 8 
+RightChild.size: 31
+RightChild.ClassCounts: 0 0 23 0 0 0 8 
+
+minGini: 8.882352 - 5
+Region.size: 31
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 0 7 0 0 0 7 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 16 0 0 0 1 
+
+minGini: 1.000000 - 18
+Region.size: 17
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 0 15 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 1 0 0 0 1 
+
+minGini: 0.000000 - 9
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 0.000000 - 18
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 7 0 0 0 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 0 7 
+
+minGini: 5.600000 - 15
+Region.size: 15
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 2 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 0 2 0 0 0 8 
+
+minGini: 1.777777 - 6
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 1 0 0 0 8 
+
+minGini: 1.333333 - 7
+Region.size: 9
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 0 6 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 1 0 0 0 2 
+
+minGini: 0.000000 - 17
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+
+
+Tree Number: 22 finished.
+
+minGini: 139.559523 - 16
+Region.size: 210
+LeftChild.size: 168
+LeftChild.ClassCounts: 24 28 29 32 32 0 23 
+RightChild.size: 42
+RightChild.ClassCounts: 0 0 0 0 0 42 0 
+
+minGini: 116.660714 - 10
+Region.size: 168
+LeftChild.size: 112
+LeftChild.ClassCounts: 24 6 26 32 1 0 23 
+RightChild.size: 56
+RightChild.ClassCounts: 0 22 3 0 31 0 0 
+
+minGini: 5.280000 - 1
+Region.size: 56
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 22 3 0 0 0 0 
+RightChild.size: 31
+RightChild.ClassCounts: 0 0 0 0 31 0 0 
+
+minGini: 0.000000 - 7
+Region.size: 25
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 22 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 58.543209 - 14
+Region.size: 112
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 0 0 31 0 0 0 
+RightChild.size: 81
+RightChild.ClassCounts: 24 6 26 1 1 0 23 
+
+minGini: 42.811111 - 15
+Region.size: 81
+LeftChild.size: 45
+LeftChild.ClassCounts: 23 6 0 0 1 0 15 
+RightChild.size: 36
+RightChild.ClassCounts: 1 0 26 1 0 0 8 
+
+minGini: 5.259259 - 18
+Region.size: 36
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 0 26 0 0 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 1 0 0 1 0 0 7 
+
+minGini: 1.000000 - 16
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 0 0 7 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 1 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 
+
+minGini: 1.600000 - 0
+Region.size: 27
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 4 0 0 0 1 
+RightChild.size: 22
+RightChild.ClassCounts: 0 0 22 0 0 0 0 
+
+minGini: 0.000000 - 7
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 0 
+
+minGini: 22.714285 - 17
+Region.size: 45
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 1 0 6 
+RightChild.size: 38
+RightChild.ClassCounts: 23 6 0 0 0 0 9 
+
+minGini: 17.564102 - 12
+Region.size: 38
+LeftChild.size: 26
+LeftChild.ClassCounts: 19 0 0 0 0 0 7 
+RightChild.size: 12
+RightChild.ClassCounts: 4 6 0 0 0 0 2 
+
+minGini: 2.666666 - 18
+Region.size: 12
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 4 0 0 0 0 0 2 
+
+minGini: 0.000000 - 17
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 4
+RightChild.ClassCounts: 4 0 0 0 0 0 0 
+
+minGini: 5.882352 - 7
+Region.size: 26
+LeftChild.size: 9
+LeftChild.ClassCounts: 3 0 0 0 0 0 6 
+RightChild.size: 17
+RightChild.ClassCounts: 16 0 0 0 0 0 1 
+
+minGini: 1.666666 - 6
+Region.size: 17
+LeftChild.size: 11
+LeftChild.ClassCounts: 11 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 5 0 0 0 0 0 1 
+
+minGini: 0.000000 - 9
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 0 0 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 9
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 0 0 0 0 6 
+
+minGini: 0.000000 - 6
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 0 6 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 1 0 0 
+
+
+
+Tree Number: 23 finished.
+
+minGini: 149.425414 - 15
+Region.size: 210
+LeftChild.size: 181
+LeftChild.ClassCounts: 38 35 35 0 26 19 28 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 0 29 0 0 0 
+
+minGini: 121.241207 - 18
+Region.size: 181
+LeftChild.size: 137
+LeftChild.ClassCounts: 1 34 33 0 26 19 24 
+RightChild.size: 44
+RightChild.ClassCounts: 37 1 2 0 0 0 4 
+
+minGini: 9.190476 - 7
+Region.size: 44
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 42
+RightChild.ClassCounts: 37 1 2 0 0 0 2 
+
+minGini: 5.128205 - 17
+Region.size: 42
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 2 0 0 0 0 
+RightChild.size: 39
+RightChild.ClassCounts: 37 0 0 0 0 0 2 
+
+minGini: 2.000000 - 15
+Region.size: 39
+LeftChild.size: 35
+LeftChild.ClassCounts: 35 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 2 0 0 0 0 0 2 
+
+minGini: 0.000000 - 17
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 0 0 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 82.324324 - 1
+Region.size: 137
+LeftChild.size: 111
+LeftChild.ClassCounts: 1 34 33 0 0 19 24 
+RightChild.size: 26
+RightChild.ClassCounts: 0 0 0 0 26 0 0 
+
+minGini: 66.437500 - 13
+Region.size: 111
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 0 0 0 0 15 0 
+RightChild.size: 96
+RightChild.ClassCounts: 1 34 33 0 0 4 24 
+
+minGini: 47.889709 - 9
+Region.size: 96
+LeftChild.size: 47
+LeftChild.ClassCounts: 1 0 25 0 0 0 21 
+RightChild.size: 49
+RightChild.ClassCounts: 0 34 8 0 0 4 3 
+
+minGini: 11.529411 - 18
+Region.size: 49
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 2 8 0 0 4 3 
+RightChild.size: 32
+RightChild.ClassCounts: 0 32 0 0 0 0 0 
+
+minGini: 5.777777 - 8
+Region.size: 17
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 2 0 0 0 4 3 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 8 0 0 0 0 
+
+minGini: 2.400000 - 9
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 2 0 0 0 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 4 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+minGini: 10.637037 - 0
+Region.size: 47
+LeftChild.size: 27
+LeftChild.ClassCounts: 1 0 23 0 0 0 3 
+RightChild.size: 20
+RightChild.ClassCounts: 0 0 2 0 0 0 18 
+
+minGini: 2.666666 - 13
+Region.size: 20
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 0 0 0 0 0 14 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 2 0 0 0 4 
+
+minGini: 0.000000 - 15
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 4 
+
+minGini: 1.916666 - 7
+Region.size: 27
+LeftChild.size: 24
+LeftChild.ClassCounts: 1 0 23 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 0 0 0 0 3 
+
+minGini: 0.000000 - 18
+Region.size: 24
+LeftChild.size: 23
+LeftChild.ClassCounts: 0 0 23 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+
+
+Tree Number: 24 finished.
+
+minGini: 146.610169 - 18
+Region.size: 210
+LeftChild.size: 177
+LeftChild.ClassCounts: 22 27 31 0 28 39 30 
+RightChild.size: 33
+RightChild.ClassCounts: 0 0 0 33 0 0 0 
+
+minGini: 116.958333 - 13
+Region.size: 177
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 0 0 0 0 33 0 
+RightChild.size: 144
+RightChild.ClassCounts: 22 27 31 0 28 6 30 
+
+minGini: 89.189655 - 1
+Region.size: 144
+LeftChild.size: 116
+LeftChild.ClassCounts: 22 27 31 0 0 6 30 
+RightChild.size: 28
+RightChild.ClassCounts: 0 0 0 0 28 0 0 
+
+minGini: 69.992473 - 11
+Region.size: 116
+LeftChild.size: 79
+LeftChild.ClassCounts: 22 1 26 0 0 0 30 
+RightChild.size: 37
+RightChild.ClassCounts: 0 26 5 0 0 6 0 
+
+minGini: 8.379310 - 12
+Region.size: 37
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 26 3 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 2 0 0 6 0 
+
+minGini: 0.000000 - 7
+Region.size: 8
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 0 0 0 6 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 
+
+minGini: 0.000000 - 18
+Region.size: 29
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 26 0 0 0 0 0 
+
+minGini: 40.635897 - 15
+Region.size: 79
+LeftChild.size: 39
+LeftChild.ClassCounts: 22 1 2 0 0 0 14 
+RightChild.size: 40
+RightChild.ClassCounts: 0 0 24 0 0 0 16 
+
+minGini: 12.000000 - 7
+Region.size: 40
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 0 0 0 0 8 
+RightChild.size: 32
+RightChild.ClassCounts: 0 0 24 0 0 0 8 
+
+minGini: 10.666666 - 5
+Region.size: 32
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 0 16 0 0 0 8 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 8 0 0 0 0 
+
+minGini: 1.882352 - 18
+Region.size: 24
+LeftChild.size: 17
+LeftChild.ClassCounts: 0 0 16 0 0 0 1 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 0 0 0 0 7 
+
+minGini: 1.333333 - 6
+Region.size: 17
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 2 0 0 0 1 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 14 0 0 0 0 
+
+minGini: 0.000000 - 14
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 15.617142 - 14
+Region.size: 39
+LeftChild.size: 14
+LeftChild.ClassCounts: 13 1 0 0 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 9 0 2 0 0 0 14 
+
+minGini: 5.176470 - 9
+Region.size: 25
+LeftChild.size: 17
+LeftChild.ClassCounts: 1 0 2 0 0 0 14 
+RightChild.size: 8
+RightChild.ClassCounts: 8 0 0 0 0 0 0 
+
+minGini: 3.500000 - 15
+Region.size: 17
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 16
+RightChild.ClassCounts: 0 0 2 0 0 0 14 
+
+minGini: 0.000000 - 1
+Region.size: 16
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 0 0 0 0 0 14 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 0 0 0 0 0 
+
+
+
+Tree Number: 25 finished.
+
+minGini: 144.321839 - 10
+Region.size: 210
+LeftChild.size: 174
+LeftChild.ClassCounts: 24 34 22 32 30 0 32 
+RightChild.size: 36
+RightChild.ClassCounts: 0 0 0 0 0 36 0 
+
+minGini: 116.386206 - 14
+Region.size: 174
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 0 0 29 0 0 0 
+RightChild.size: 145
+RightChild.ClassCounts: 24 34 22 3 30 0 32 
+
+minGini: 95.651260 - 17
+Region.size: 145
+LeftChild.size: 68
+LeftChild.ClassCounts: 0 30 0 1 30 0 7 
+RightChild.size: 77
+RightChild.ClassCounts: 24 4 22 2 0 0 25 
+
+minGini: 51.027777 - 5
+Region.size: 77
+LeftChild.size: 72
+LeftChild.ClassCounts: 24 4 17 2 0 0 25 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 0 
+
+minGini: 42.375000 - 10
+Region.size: 72
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 0 14 0 0 0 10 
+RightChild.size: 48
+RightChild.ClassCounts: 24 4 3 2 0 0 15 
+
+minGini: 21.066666 - 0
+Region.size: 48
+LeftChild.size: 33
+LeftChild.ClassCounts: 24 2 3 0 0 0 4 
+RightChild.size: 15
+RightChild.ClassCounts: 0 2 0 2 0 0 11 
+
+minGini: 3.384615 - 17
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 2 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 0 2 0 0 0 0 11 
+
+minGini: 0.000000 - 13
+Region.size: 13
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 0 0 0 0 0 11 
+
+minGini: 5.777777 - 18
+Region.size: 33
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 2 3 0 0 0 4 
+RightChild.size: 24
+RightChild.ClassCounts: 24 0 0 0 0 0 0 
+
+minGini: 2.400000 - 11
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 0 0 0 0 4 
+RightChild.size: 5
+RightChild.ClassCounts: 0 2 3 0 0 0 0 
+
+minGini: 1.333333 - 7
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 2 1 0 0 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 3.500000 - 18
+Region.size: 24
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 0 14 0 0 0 2 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 0 8 
+
+minGini: 1.333333 - 10
+Region.size: 16
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 0 13 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 1 0 0 0 2 
+
+minGini: 0.000000 - 12
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 31.750000 - 15
+Region.size: 68
+LeftChild.size: 60
+LeftChild.ClassCounts: 0 30 0 0 30 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 1 0 0 7 
+
+minGini: 0.000000 - 6
+Region.size: 8
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 0 0 7 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 1 0 0 0 
+
+minGini: 13.846153 - 17
+Region.size: 60
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 21 0 0 0 0 0 
+RightChild.size: 39
+RightChild.ClassCounts: 0 9 0 0 30 0 0 
+
+minGini: 3.750000 - 7
+Region.size: 39
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 0 0 0 0 
+RightChild.size: 32
+RightChild.ClassCounts: 0 2 0 0 30 0 0 
+
+minGini: 3.272727 - 9
+Region.size: 32
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 2 0 0 9 0 0 
+RightChild.size: 21
+RightChild.ClassCounts: 0 0 0 0 21 0 0 
+
+minGini: 0.000000 - 11
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 9 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+
+
+Tree Number: 26 finished.
+
+minGini: 151.021978 - 9
+Region.size: 210
+LeftChild.size: 182
+LeftChild.ClassCounts: 33 34 28 30 22 0 35 
+RightChild.size: 28
+RightChild.ClassCounts: 0 0 0 0 0 28 0 
+
+minGini: 122.661538 - 1
+Region.size: 182
+LeftChild.size: 130
+LeftChild.ClassCounts: 33 34 28 0 0 0 35 
+RightChild.size: 52
+RightChild.ClassCounts: 0 0 0 30 22 0 0 
+
+minGini: 0.000000 - 15
+Region.size: 52
+LeftChild.size: 22
+LeftChild.ClassCounts: 0 0 0 0 22 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 0 0 0 30 0 0 0 
+
+minGini: 72.787990 - 11
+Region.size: 130
+LeftChild.size: 96
+LeftChild.ClassCounts: 33 4 24 0 0 0 35 
+RightChild.size: 34
+RightChild.ClassCounts: 0 30 4 0 0 0 0 
+
+minGini: 4.444444 - 0
+Region.size: 34
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 5 4 0 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 25 0 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 0 
+
+minGini: 56.283400 - 15
+Region.size: 96
+LeftChild.size: 57
+LeftChild.ClassCounts: 31 4 7 0 0 0 15 
+RightChild.size: 39
+RightChild.ClassCounts: 2 0 17 0 0 0 20 
+
+minGini: 14.400000 - 13
+Region.size: 39
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 9 0 0 0 0 
+RightChild.size: 30
+RightChild.ClassCounts: 2 0 8 0 0 0 20 
+
+minGini: 12.825396 - 16
+Region.size: 30
+LeftChild.size: 21
+LeftChild.ClassCounts: 1 0 8 0 0 0 12 
+RightChild.size: 9
+RightChild.ClassCounts: 1 0 0 0 0 0 8 
+
+minGini: 0.000000 - 5
+Region.size: 9
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 0 8 
+
+minGini: 7.529411 - 17
+Region.size: 21
+LeftChild.size: 17
+LeftChild.ClassCounts: 1 0 4 0 0 0 12 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 0 
+
+minGini: 1.846153 - 18
+Region.size: 17
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 0 0 0 0 
+RightChild.size: 13
+RightChild.ClassCounts: 1 0 0 0 0 0 12 
+
+minGini: 0.000000 - 9
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 0 0 0 0 12 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+minGini: 27.230769 - 11
+Region.size: 57
+LeftChild.size: 18
+LeftChild.ClassCounts: 18 0 0 0 0 0 0 
+RightChild.size: 39
+RightChild.ClassCounts: 13 4 7 0 0 0 15 
+
+minGini: 15.777142 - 15
+Region.size: 39
+LeftChild.size: 14
+LeftChild.ClassCounts: 13 0 1 0 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 4 6 0 0 0 15 
+
+minGini: 9.333333 - 5
+Region.size: 25
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 4 2 0 0 0 15 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 0 0 0 0 
+
+minGini: 5.777777 - 7
+Region.size: 21
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 0 0 0 0 12 
+RightChild.size: 9
+RightChild.ClassCounts: 0 4 2 0 0 0 3 
+
+minGini: 2.400000 - 16
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 2 0 0 0 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 
+
+minGini: 0.000000 - 9
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 
+
+minGini: 0.000000 - 5
+Region.size: 14
+LeftChild.size: 13
+LeftChild.ClassCounts: 13 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+
+
+Tree Number: 27 finished.
+
+minGini: 146.602272 - 9
+Region.size: 210
+LeftChild.size: 176
+LeftChild.ClassCounts: 32 30 28 29 29 0 28 
+RightChild.size: 34
+RightChild.ClassCounts: 0 0 0 0 0 34 0 
+
+minGini: 117.406779 - 1
+Region.size: 176
+LeftChild.size: 118
+LeftChild.ClassCounts: 32 30 28 0 0 0 28 
+RightChild.size: 58
+RightChild.ClassCounts: 0 0 0 29 29 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 58
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 0 0 0 29 0 0 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 0 29 0 0 0 
+
+minGini: 64.712901 - 12
+Region.size: 118
+LeftChild.size: 89
+LeftChild.ClassCounts: 32 3 26 0 0 0 28 
+RightChild.size: 29
+RightChild.ClassCounts: 0 27 2 0 0 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 29
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 27 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 
+
+minGini: 36.318658 - 18
+Region.size: 89
+LeftChild.size: 53
+LeftChild.ClassCounts: 0 3 26 0 0 0 24 
+RightChild.size: 36
+RightChild.ClassCounts: 32 0 0 0 0 0 4 
+
+minGini: 0.000000 - 18
+Region.size: 36
+LeftChild.size: 32
+LeftChild.ClassCounts: 32 0 0 0 0 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 0 0 4 
+
+minGini: 20.312121 - 0
+Region.size: 53
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 3 23 0 0 0 7 
+RightChild.size: 20
+RightChild.ClassCounts: 0 0 3 0 0 0 17 
+
+minGini: 0.000000 - 12
+Region.size: 20
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 0 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 0 0 0 0 17 
+
+minGini: 10.705882 - 10
+Region.size: 33
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 0 16 0 0 0 0 
+RightChild.size: 17
+RightChild.ClassCounts: 0 3 7 0 0 0 7 
+
+minGini: 4.200000 - 7
+Region.size: 17
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 0 0 0 0 7 
+RightChild.size: 10
+RightChild.ClassCounts: 0 3 7 0 0 0 0 
+
+minGini: 2.400000 - 7
+Region.size: 10
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 3 2 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 0 0 0 0 
+
+minGini: 0.000000 - 18
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 0 0 0 0 
+
+
+
+Tree Number: 28 finished.
+
+minGini: 147.310734 - 15
+Region.size: 210
+LeftChild.size: 177
+LeftChild.ClassCounts: 29 31 34 0 28 27 28 
+RightChild.size: 33
+RightChild.ClassCounts: 0 0 0 33 0 0 0 
+
+minGini: 119.826666 - 9
+Region.size: 177
+LeftChild.size: 150
+LeftChild.ClassCounts: 29 31 34 0 28 0 28 
+RightChild.size: 27
+RightChild.ClassCounts: 0 0 0 0 0 27 0 
+
+minGini: 100.431818 - 18
+Region.size: 150
+LeftChild.size: 40
+LeftChild.ClassCounts: 0 1 30 0 4 0 5 
+RightChild.size: 110
+RightChild.ClassCounts: 29 30 4 0 24 0 23 
+
+minGini: 60.934789 - 9
+Region.size: 110
+LeftChild.size: 57
+LeftChild.ClassCounts: 28 2 4 0 0 0 23 
+RightChild.size: 53
+RightChild.ClassCounts: 1 28 0 0 24 0 0 
+
+minGini: 1.931034 - 1
+Region.size: 53
+LeftChild.size: 29
+LeftChild.ClassCounts: 1 28 0 0 0 0 0 
+RightChild.size: 24
+RightChild.ClassCounts: 0 0 0 0 24 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 29
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 28
+RightChild.ClassCounts: 0 28 0 0 0 0 0 
+
+minGini: 25.674418 - 13
+Region.size: 57
+LeftChild.size: 43
+LeftChild.ClassCounts: 14 2 4 0 0 0 23 
+RightChild.size: 14
+RightChild.ClassCounts: 14 0 0 0 0 0 0 
+
+minGini: 13.443349 - 11
+Region.size: 43
+LeftChild.size: 29
+LeftChild.ClassCounts: 1 2 4 0 0 0 22 
+RightChild.size: 14
+RightChild.ClassCounts: 13 0 0 0 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 0 0 0 0 0 
+
+minGini: 10.071428 - 3
+Region.size: 29
+LeftChild.size: 28
+LeftChild.ClassCounts: 1 1 4 0 0 0 22 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 7.894736 - 0
+Region.size: 28
+LeftChild.size: 9
+LeftChild.ClassCounts: 1 1 3 0 0 0 4 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 1 0 0 0 18 
+
+minGini: 1.000000 - 18
+Region.size: 19
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 1 0 0 0 1 
+RightChild.size: 17
+RightChild.ClassCounts: 0 0 0 0 0 0 17 
+
+minGini: 0.000000 - 18
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 5.000000 - 5
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 1 0 2 0 0 0 4 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 1.600000 - 10
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 0 0 0 0 0 4 
+
+minGini: 1.000000 - 1
+Region.size: 5
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 0 0 0 0 3 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 0 0 0 0 1 
+
+minGini: 0.000000 - 17
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 7.090909 - 0
+Region.size: 40
+LeftChild.size: 29
+LeftChild.ClassCounts: 0 0 29 0 0 0 0 
+RightChild.size: 11
+RightChild.ClassCounts: 0 1 1 0 4 0 5 
+
+minGini: 3.142857 - 10
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 1 1 0 0 0 5 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 0 0 4 0 0 
+
+minGini: 1.666666 - 11
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 1 0 0 0 0 5 
+
+minGini: 0.000000 - 15
+Region.size: 6
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 0 0 0 0 5 
+
+
+
+Tree Number: 29 finished.
+
+minGini: 148.681564 - 10
+Region.size: 210
+LeftChild.size: 179
+LeftChild.ClassCounts: 32 28 24 27 33 0 35 
+RightChild.size: 31
+RightChild.ClassCounts: 0 0 0 0 0 31 0 
+
+minGini: 121.092105 - 15
+Region.size: 179
+LeftChild.size: 152
+LeftChild.ClassCounts: 32 28 24 0 33 0 35 
+RightChild.size: 27
+RightChild.ClassCounts: 0 0 0 27 0 0 0 
+
+minGini: 101.542517 - 17
+Region.size: 152
+LeftChild.size: 69
+LeftChild.ClassCounts: 0 23 4 0 33 0 9 
+RightChild.size: 83
+RightChild.ClassCounts: 32 5 20 0 0 0 26 
+
+minGini: 40.713103 - 13
+Region.size: 83
+LeftChild.size: 58
+LeftChild.ClassCounts: 8 5 20 0 0 0 25 
+RightChild.size: 25
+RightChild.ClassCounts: 24 0 0 0 0 0 1 
+
+minGini: 0.000000 - 11
+Region.size: 25
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 24
+RightChild.ClassCounts: 24 0 0 0 0 0 0 
+
+minGini: 31.587596 - 0
+Region.size: 58
+LeftChild.size: 43
+LeftChild.ClassCounts: 8 5 19 0 0 0 11 
+RightChild.size: 15
+RightChild.ClassCounts: 0 0 1 0 0 0 14 
+
+minGini: 0.000000 - 18
+Region.size: 15
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 0 0 0 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 0 0 0 0 0 14 
+
+minGini: 23.912820 - 15
+Region.size: 43
+LeftChild.size: 30
+LeftChild.ClassCounts: 8 5 7 0 0 0 10 
+RightChild.size: 13
+RightChild.ClassCounts: 0 0 12 0 0 0 1 
+
+minGini: 0.000000 - 18
+Region.size: 13
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 12 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 0 0 0 0 1 
+
+minGini: 16.204545 - 13
+Region.size: 30
+LeftChild.size: 22
+LeftChild.ClassCounts: 1 4 7 0 0 0 10 
+RightChild.size: 8
+RightChild.ClassCounts: 7 1 0 0 0 0 0 
+
+minGini: 1.333333 - 15
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 5 0 0 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 0 0 0 0 
+
+minGini: 0.000000 - 11
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 0 0 0 0 
+
+minGini: 10.363636 - 16
+Region.size: 22
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 2 0 0 0 9 
+RightChild.size: 11
+RightChild.ClassCounts: 1 4 5 0 0 0 1 
+
+minGini: 3.000000 - 18
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 0 0 0 0 
+RightChild.size: 6
+RightChild.ClassCounts: 1 4 0 0 0 0 1 
+
+minGini: 1.000000 - 1
+Region.size: 6
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 0 0 0 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 0 0 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 0 0 0 0 
+
+minGini: 1.333333 - 6
+Region.size: 11
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 2 0 0 0 1 
+RightChild.size: 8
+RightChild.ClassCounts: 0 0 0 0 0 0 8 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 0 0 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 
+
+minGini: 24.354838 - 7
+Region.size: 69
+LeftChild.size: 31
+LeftChild.ClassCounts: 0 20 2 0 0 0 9 
+RightChild.size: 38
+RightChild.ClassCounts: 0 3 2 0 33 0 0 
+
+minGini: 5.500000 - 18
+Region.size: 38
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 0 0 0 0 
+RightChild.size: 36
+RightChild.ClassCounts: 0 3 0 0 33 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 36
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 0 0 0 0 
+RightChild.size: 33
+RightChild.ClassCounts: 0 0 0 0 33 0 0 
+
+minGini: 3.272727 - 11
+Region.size: 31
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 2 0 0 0 9 
+RightChild.size: 20
+RightChild.ClassCounts: 0 20 0 0 0 0 0 
+
+minGini: 0.000000 - 7
+Region.size: 11
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 0 0 0 0 9 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 0 0 0 0 
+
+
+
+Tree Number: 30 finished.
+
+minGini: 147.107344 - 12
+Region.size: 210
+LeftChild.size: 177
+LeftChild.ClassCounts: 32 35 26 29 25 0 30 
+RightChild.size: 33
+RightChild.ClassCounts: 0 0 0 0 0 33 0 
+
+minGini: 124.193538 - 12
+Region.size: 177
+LeftChild.size: 125
+LeftChild.ClassCounts: 32 9 25 29 0 0 30 
+RightChild.size: 52
+RightChild.ClassCounts: 0 26 1 0 25 0 0 
+
+minGini: 1.925925 - 1
+Region.size: 52
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 26 1 0 0 0 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 0 0 0 25 0 0 
+
+minGini: 1.000000 - 8
+Region.size: 27
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 25 0 0 0 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 1 1 0 0 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 68.604166 - 15
+Region.size: 125
+LeftChild.size: 96
+LeftChild.ClassCounts: 32 9 25 0 0 0 30 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 0 29 0 0 0 
+
+minGini: 51.776057 - 15
+Region.size: 96
+LeftChild.size: 23
+LeftChild.ClassCounts: 22 1 0 0 0 0 0 
+RightChild.size: 73
+RightChild.ClassCounts: 10 8 25 0 0 0 30 
+
+minGini: 42.754098 - 7
+Region.size: 73
+LeftChild.size: 12
+LeftChild.ClassCounts: 0 0 0 0 0 0 12 
+RightChild.size: 61
+RightChild.ClassCounts: 10 8 25 0 0 0 18 
+
+minGini: 29.072072 - 10
+Region.size: 61
+LeftChild.size: 24
+LeftChild.ClassCounts: 0 0 22 0 0 0 2 
+RightChild.size: 37
+RightChild.ClassCounts: 10 8 3 0 0 0 16 
+
+minGini: 14.814814 - 13
+Region.size: 37
+LeftChild.size: 27
+LeftChild.ClassCounts: 0 8 3 0 0 0 16 
+RightChild.size: 10
+RightChild.ClassCounts: 10 0 0 0 0 0 0 
+
+minGini: 9.875000 - 7
+Region.size: 27
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 0 0 0 0 0 11 
+RightChild.size: 16
+RightChild.ClassCounts: 0 8 3 0 0 0 5 
+
+minGini: 6.200000 - 8
+Region.size: 16
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 0 0 0 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 2 3 0 0 0 5 
+
+minGini: 2.857142 - 5
+Region.size: 10
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 2 0 0 0 0 5 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 0 0 0 0 
+
+minGini: 0.000000 - 16
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 0 0 0 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 0 0 0 0 
+
+minGini: 1.333333 - 1
+Region.size: 24
+LeftChild.size: 21
+LeftChild.ClassCounts: 0 0 21 0 0 0 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 1 0 0 0 2 
+
+minGini: 0.000000 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 0 0 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 0 0 0 0 
+
+minGini: 0.000000 - 17
+Region.size: 23
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 0 0 0 0 
+RightChild.size: 22
+RightChild.ClassCounts: 22 0 0 0 0 0 0 
+
+
+
+Tree Number: 31 finished.
+
+segmentation
+minGini: 75.732394 - 6
+Region.size: 178
+LeftChild.size: 36
+LeftChild.ClassCounts: 0 0 36 
+RightChild.size: 142
+RightChild.ClassCounts: 69 68 5 
+
+minGini: 25.833333 - 0
+Region.size: 142
+LeftChild.size: 58
+LeftChild.ClassCounts: 0 58 0 
+RightChild.size: 84
+RightChild.ClassCounts: 69 10 5 
+
+minGini: 10.041170 - 12
+Region.size: 84
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 8 5 
+RightChild.size: 71
+RightChild.ClassCounts: 69 2 0 
+
+minGini: 0.000000 - 9
+Region.size: 71
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 69
+RightChild.ClassCounts: 69 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 13
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 
+RightChild.size: 8
+RightChild.ClassCounts: 0 8 0 
+
+
+
+Tree Number: 0 finished.
+
+minGini: 70.372093 - 12
+Region.size: 178
+LeftChild.size: 129
+LeftChild.ClassCounts: 7 67 55 
+RightChild.size: 49
+RightChild.ClassCounts: 49 0 0 
+
+minGini: 24.632034 - 9
+Region.size: 129
+LeftChild.size: 63
+LeftChild.ClassCounts: 1 61 1 
+RightChild.size: 66
+RightChild.ClassCounts: 6 6 54 
+
+minGini: 12.654545 - 10
+Region.size: 66
+LeftChild.size: 55
+LeftChild.ClassCounts: 2 1 52 
+RightChild.size: 11
+RightChild.ClassCounts: 4 5 2 
+
+minGini: 4.066666 - 6
+Region.size: 11
+LeftChild.size: 5
+LeftChild.ClassCounts: 3 0 2 
+RightChild.size: 6
+RightChild.ClassCounts: 1 5 0 
+
+minGini: 0.000000 - 0
+Region.size: 6
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+minGini: 0.000000 - 10
+Region.size: 5
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 
+
+minGini: 1.962264 - 11
+Region.size: 55
+LeftChild.size: 53
+LeftChild.ClassCounts: 0 1 52 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 
+
+minGini: 1.714285 - 7
+Region.size: 53
+LeftChild.size: 46
+LeftChild.ClassCounts: 0 0 46 
+RightChild.size: 7
+RightChild.ClassCounts: 0 1 6 
+
+minGini: 0.000000 - 4
+Region.size: 7
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 6 
+
+minGini: 1.967741 - 11
+Region.size: 63
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 62
+RightChild.ClassCounts: 1 61 0 
+
+minGini: 1.600000 - 12
+Region.size: 62
+LeftChild.size: 57
+LeftChild.ClassCounts: 0 57 0 
+RightChild.size: 5
+RightChild.ClassCounts: 1 4 0 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+
+
+Tree Number: 1 finished.
+
+minGini: 93.576940 - 8
+Region.size: 178
+LeftChild.size: 55
+LeftChild.ClassCounts: 2 16 37 
+RightChild.size: 123
+RightChild.ClassCounts: 48 66 9 
+
+minGini: 26.610079 - 12
+Region.size: 123
+LeftChild.size: 65
+LeftChild.ClassCounts: 0 60 5 
+RightChild.size: 58
+RightChild.ClassCounts: 48 6 4 
+
+minGini: 7.384615 - 9
+Region.size: 58
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 
+RightChild.size: 52
+RightChild.ClassCounts: 48 0 4 
+
+minGini: 3.840000 - 1
+Region.size: 52
+LeftChild.size: 50
+LeftChild.ClassCounts: 48 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 0 2 
+
+minGini: 0.000000 - 5
+Region.size: 50
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 48
+RightChild.ClassCounts: 48 0 0 
+
+minGini: 0.000000 - 9
+Region.size: 65
+LeftChild.size: 60
+LeftChild.ClassCounts: 0 60 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 
+
+minGini: 7.414634 - 9
+Region.size: 55
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 
+RightChild.size: 41
+RightChild.ClassCounts: 2 2 37 
+
+minGini: 3.280701 - 11
+Region.size: 41
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 1 37 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 0 
+
+minGini: 0.000000 - 4
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 38
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 37
+RightChild.ClassCounts: 0 0 37 
+
+
+
+Tree Number: 2 finished.
+
+minGini: 70.767977 - 0
+Region.size: 178
+LeftChild.size: 81
+LeftChild.ClassCounts: 0 71 10 
+RightChild.size: 97
+RightChild.ClassCounts: 55 8 34 
+
+minGini: 24.502613 - 3
+Region.size: 97
+LeftChild.size: 56
+LeftChild.ClassCounts: 50 5 1 
+RightChild.size: 41
+RightChild.ClassCounts: 5 3 33 
+
+minGini: 3.750000 - 6
+Region.size: 41
+LeftChild.size: 33
+LeftChild.ClassCounts: 0 0 33 
+RightChild.size: 8
+RightChild.ClassCounts: 5 3 0 
+
+minGini: 0.000000 - 9
+Region.size: 8
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 5
+RightChild.ClassCounts: 5 0 0 
+
+minGini: 1.960784 - 1
+Region.size: 56
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 
+RightChild.size: 51
+RightChild.ClassCounts: 50 0 1 
+
+minGini: 0.000000 - 12
+Region.size: 51
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 50
+RightChild.ClassCounts: 50 0 0 
+
+minGini: 3.771830 - 6
+Region.size: 81
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 1 9 
+RightChild.size: 71
+RightChild.ClassCounts: 0 70 1 
+
+minGini: 1.500000 - 6
+Region.size: 71
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 3 1 
+RightChild.size: 67
+RightChild.ClassCounts: 0 67 0 
+
+minGini: 0.000000 - 3
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+minGini: 0.000000 - 3
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 9 
+
+
+
+Tree Number: 3 finished.
+
+minGini: 78.546324 - 10
+Region.size: 178
+LeftChild.size: 57
+LeftChild.ClassCounts: 0 9 48 
+RightChild.size: 121
+RightChild.ClassCounts: 59 59 3 
+
+minGini: 11.169230 - 0
+Region.size: 121
+LeftChild.size: 56
+LeftChild.ClassCounts: 0 56 0 
+RightChild.size: 65
+RightChild.ClassCounts: 59 3 3 
+
+minGini: 3.000000 - 6
+Region.size: 65
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 3 3 
+RightChild.size: 59
+RightChild.ClassCounts: 59 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 6
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+minGini: 3.840000 - 9
+Region.size: 57
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 
+RightChild.size: 50
+RightChild.ClassCounts: 0 2 48 
+
+minGini: 0.000000 - 6
+Region.size: 50
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 0 48 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+
+
+Tree Number: 4 finished.
+
+minGini: 78.527564 - 11
+Region.size: 178
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 7 41 
+RightChild.size: 130
+RightChild.ClassCounts: 59 69 2 
+
+minGini: 42.256097 - 6
+Region.size: 130
+LeftChild.size: 48
+LeftChild.ClassCounts: 2 44 2 
+RightChild.size: 82
+RightChild.ClassCounts: 57 25 0 
+
+minGini: 9.193548 - 9
+Region.size: 82
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 20 0 
+RightChild.size: 62
+RightChild.ClassCounts: 57 5 0 
+
+minGini: 0.000000 - 12
+Region.size: 62
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 
+RightChild.size: 57
+RightChild.ClassCounts: 57 0 0 
+
+minGini: 5.702127 - 8
+Region.size: 48
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 47
+RightChild.ClassCounts: 2 44 1 
+
+minGini: 1.955555 - 12
+Region.size: 47
+LeftChild.size: 45
+LeftChild.ClassCounts: 0 44 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 
+
+minGini: 1.333333 - 8
+Region.size: 45
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 2 1 
+RightChild.size: 42
+RightChild.ClassCounts: 0 42 0 
+
+minGini: 0.000000 - 6
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+minGini: 3.111111 - 1
+Region.size: 48
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 7 2 
+RightChild.size: 39
+RightChild.ClassCounts: 0 0 39 
+
+minGini: 0.000000 - 11
+Region.size: 9
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 7
+RightChild.ClassCounts: 0 7 0 
+
+
+
+Tree Number: 5 finished.
+
+minGini: 68.348850 - 9
+Region.size: 178
+LeftChild.size: 58
+LeftChild.ClassCounts: 1 57 0 
+RightChild.size: 120
+RightChild.ClassCounts: 63 8 49 
+
+minGini: 14.197183 - 6
+Region.size: 120
+LeftChild.size: 49
+LeftChild.ClassCounts: 0 0 49 
+RightChild.size: 71
+RightChild.ClassCounts: 63 8 0 
+
+minGini: 5.078853 - 1
+Region.size: 71
+LeftChild.size: 9
+LeftChild.ClassCounts: 2 7 0 
+RightChild.size: 62
+RightChild.ClassCounts: 61 1 0 
+
+minGini: 0.000000 - 12
+Region.size: 62
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 61
+RightChild.ClassCounts: 61 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 
+
+minGini: 0.000000 - 11
+Region.size: 58
+LeftChild.size: 57
+LeftChild.ClassCounts: 0 57 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+
+
+Tree Number: 6 finished.
+
+minGini: 84.184782 - 10
+Region.size: 178
+LeftChild.size: 40
+LeftChild.ClassCounts: 0 5 35 
+RightChild.size: 138
+RightChild.ClassCounts: 67 64 7 
+
+minGini: 28.785714 - 9
+Region.size: 138
+LeftChild.size: 54
+LeftChild.ClassCounts: 0 54 0 
+RightChild.size: 84
+RightChild.ClassCounts: 67 10 7 
+
+minGini: 12.742857 - 5
+Region.size: 84
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 7 7 
+RightChild.size: 70
+RightChild.ClassCounts: 67 3 0 
+
+minGini: 0.000000 - 0
+Region.size: 70
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 67
+RightChild.ClassCounts: 67 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 14
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 0 7 
+
+minGini: 0.000000 - 11
+Region.size: 40
+LeftChild.size: 35
+LeftChild.ClassCounts: 0 0 35 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 
+
+
+
+Tree Number: 7 finished.
+
+minGini: 74.162958 - 6
+Region.size: 178
+LeftChild.size: 62
+LeftChild.ClassCounts: 0 9 53 
+RightChild.size: 116
+RightChild.ClassCounts: 54 61 1 
+
+minGini: 22.617647 - 9
+Region.size: 116
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 48 0 
+RightChild.size: 68
+RightChild.ClassCounts: 54 13 1 
+
+minGini: 3.600000 - 12
+Region.size: 68
+LeftChild.size: 15
+LeftChild.ClassCounts: 1 13 1 
+RightChild.size: 53
+RightChild.ClassCounts: 53 0 0 
+
+minGini: 1.857142 - 4
+Region.size: 15
+LeftChild.size: 14
+LeftChild.ClassCounts: 1 13 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+minGini: 1.333333 - 5
+Region.size: 14
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+minGini: 0.000000 - 9
+Region.size: 62
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 
+RightChild.size: 53
+RightChild.ClassCounts: 0 0 53 
+
+
+
+Tree Number: 8 finished.
+
+minGini: 82.055769 - 11
+Region.size: 178
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 9 39 
+RightChild.size: 130
+RightChild.ClassCounts: 69 58 3 
+
+minGini: 35.366883 - 6
+Region.size: 130
+LeftChild.size: 42
+LeftChild.ClassCounts: 0 39 3 
+RightChild.size: 88
+RightChild.ClassCounts: 69 19 0 
+
+minGini: 7.113006 - 12
+Region.size: 88
+LeftChild.size: 21
+LeftChild.ClassCounts: 3 18 0 
+RightChild.size: 67
+RightChild.ClassCounts: 66 1 0 
+
+minGini: 0.000000 - 3
+Region.size: 67
+LeftChild.size: 66
+LeftChild.ClassCounts: 66 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 3.428571 - 11
+Region.size: 21
+LeftChild.size: 7
+LeftChild.ClassCounts: 3 4 0 
+RightChild.size: 14
+RightChild.ClassCounts: 0 14 0 
+
+minGini: 0.000000 - 8
+Region.size: 7
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 
+
+minGini: 0.000000 - 6
+Region.size: 42
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 39
+RightChild.ClassCounts: 0 39 0 
+
+minGini: 7.255813 - 10
+Region.size: 48
+LeftChild.size: 43
+LeftChild.ClassCounts: 0 4 39 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 
+
+minGini: 5.794871 - 8
+Region.size: 43
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 2 37 
+RightChild.size: 4
+RightChild.ClassCounts: 0 2 2 
+
+minGini: 0.000000 - 11
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+minGini: 0.000000 - 2
+Region.size: 39
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 37
+RightChild.ClassCounts: 0 0 37 
+
+
+
+Tree Number: 9 finished.
+
+minGini: 70.960000 - 12
+Region.size: 178
+LeftChild.size: 128
+LeftChild.ClassCounts: 8 72 48 
+RightChild.size: 50
+RightChild.ClassCounts: 49 1 0 
+
+minGini: 0.000000 - 0
+Region.size: 50
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 49
+RightChild.ClassCounts: 49 0 0 
+
+minGini: 25.716662 - 9
+Region.size: 128
+LeftChild.size: 67
+LeftChild.ClassCounts: 2 65 0 
+RightChild.size: 61
+RightChild.ClassCounts: 6 7 48 
+
+minGini: 6.461538 - 11
+Region.size: 61
+LeftChild.size: 48
+LeftChild.ClassCounts: 0 0 48 
+RightChild.size: 13
+RightChild.ClassCounts: 6 7 0 
+
+minGini: 0.000000 - 0
+Region.size: 13
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 
+RightChild.size: 6
+RightChild.ClassCounts: 6 0 0 
+
+minGini: 2.857142 - 2
+Region.size: 67
+LeftChild.size: 60
+LeftChild.ClassCounts: 0 60 0 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 0 
+
+minGini: 0.000000 - 8
+Region.size: 7
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 
+
+
+
+Tree Number: 10 finished.
+
+minGini: 74.120669 - 6
+Region.size: 178
+LeftChild.size: 54
+LeftChild.ClassCounts: 0 7 47 
+RightChild.size: 124
+RightChild.ClassCounts: 60 64 0 
+
+minGini: 37.241379 - 4
+Region.size: 124
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 37 0 
+RightChild.size: 87
+RightChild.ClassCounts: 60 27 0 
+
+minGini: 3.870967 - 0
+Region.size: 87
+LeftChild.size: 25
+LeftChild.ClassCounts: 0 25 0 
+RightChild.size: 62
+RightChild.ClassCounts: 60 2 0 
+
+minGini: 0.000000 - 1
+Region.size: 62
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 60
+RightChild.ClassCounts: 60 0 0 
+
+minGini: 0.000000 - 9
+Region.size: 54
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 
+RightChild.size: 47
+RightChild.ClassCounts: 0 0 47 
+
+
+
+Tree Number: 11 finished.
+
+minGini: 78.018867 - 0
+Region.size: 178
+LeftChild.size: 72
+LeftChild.ClassCounts: 0 60 12 
+RightChild.size: 106
+RightChild.ClassCounts: 55 6 45 
+
+minGini: 29.396622 - 7
+Region.size: 106
+LeftChild.size: 65
+LeftChild.ClassCounts: 52 5 8 
+RightChild.size: 41
+RightChild.ClassCounts: 3 1 37 
+
+minGini: 1.500000 - 6
+Region.size: 41
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 0 37 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 
+
+minGini: 0.000000 - 12
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 
+
+minGini: 9.122807 - 10
+Region.size: 65
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 8 
+RightChild.size: 57
+RightChild.ClassCounts: 52 5 0 
+
+minGini: 3.851851 - 1
+Region.size: 57
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 54
+RightChild.ClassCounts: 52 2 0 
+
+minGini: 0.000000 - 10
+Region.size: 54
+LeftChild.size: 52
+LeftChild.ClassCounts: 52 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+minGini: 3.428571 - 6
+Region.size: 72
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 2 12 
+RightChild.size: 58
+RightChild.ClassCounts: 0 58 0 
+
+minGini: 0.000000 - 3
+Region.size: 14
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 12
+RightChild.ClassCounts: 0 0 12 
+
+
+
+Tree Number: 12 finished.
+
+minGini: 74.314823 - 6
+Region.size: 178
+LeftChild.size: 49
+LeftChild.ClassCounts: 0 3 46 
+RightChild.size: 129
+RightChild.ClassCounts: 52 71 6 
+
+minGini: 18.365063 - 12
+Region.size: 129
+LeftChild.size: 79
+LeftChild.ClassCounts: 3 70 6 
+RightChild.size: 50
+RightChild.ClassCounts: 49 1 0 
+
+minGini: 0.000000 - 7
+Region.size: 50
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 49
+RightChild.ClassCounts: 49 0 0 
+
+minGini: 7.648648 - 9
+Region.size: 79
+LeftChild.size: 74
+LeftChild.ClassCounts: 3 70 1 
+RightChild.size: 5
+RightChild.ClassCounts: 0 0 5 
+
+minGini: 6.000000 - 9
+Region.size: 74
+LeftChild.size: 61
+LeftChild.ClassCounts: 0 61 0 
+RightChild.size: 13
+RightChild.ClassCounts: 3 9 1 
+
+minGini: 1.500000 - 9
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 0 1 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 
+
+minGini: 0.000000 - 5
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 
+
+minGini: 1.957446 - 3
+Region.size: 49
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 47
+RightChild.ClassCounts: 0 1 46 
+
+minGini: 0.000000 - 9
+Region.size: 47
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 46
+RightChild.ClassCounts: 0 0 46 
+
+
+
+Tree Number: 13 finished.
+
+minGini: 67.685714 - 0
+Region.size: 178
+LeftChild.size: 80
+LeftChild.ClassCounts: 0 68 12 
+RightChild.size: 98
+RightChild.ClassCounts: 60 1 37 
+
+minGini: 3.913159 - 5
+Region.size: 98
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 1 36 
+RightChild.size: 61
+RightChild.ClassCounts: 60 0 1 
+
+minGini: 0.000000 - 11
+Region.size: 61
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 60
+RightChild.ClassCounts: 60 0 0 
+
+minGini: 0.000000 - 6
+Region.size: 37
+LeftChild.size: 36
+LeftChild.ClassCounts: 0 0 36 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 10.742857 - 5
+Region.size: 80
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 2 8 
+RightChild.size: 70
+RightChild.ClassCounts: 0 66 4 
+
+minGini: 1.600000 - 6
+Region.size: 70
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 4 
+RightChild.size: 65
+RightChild.ClassCounts: 0 65 0 
+
+minGini: 0.000000 - 10
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 8 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+
+
+Tree Number: 14 finished.
+
+minGini: 75.241989 - 11
+Region.size: 178
+LeftChild.size: 57
+LeftChild.ClassCounts: 0 8 49 
+RightChild.size: 121
+RightChild.ClassCounts: 60 60 1 
+
+minGini: 24.660606 - 9
+Region.size: 121
+LeftChild.size: 55
+LeftChild.ClassCounts: 4 51 0 
+RightChild.size: 66
+RightChild.ClassCounts: 56 9 1 
+
+minGini: 1.800000 - 12
+Region.size: 66
+LeftChild.size: 10
+LeftChild.ClassCounts: 0 9 1 
+RightChild.size: 56
+RightChild.ClassCounts: 56 0 0 
+
+minGini: 0.000000 - 0
+Region.size: 10
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 9 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+minGini: 5.666666 - 2
+Region.size: 55
+LeftChild.size: 54
+LeftChild.ClassCounts: 3 51 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+minGini: 3.849056 - 11
+Region.size: 54
+LeftChild.size: 53
+LeftChild.ClassCounts: 2 51 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+minGini: 2.857142 - 0
+Region.size: 53
+LeftChild.size: 46
+LeftChild.ClassCounts: 0 46 0 
+RightChild.size: 7
+RightChild.ClassCounts: 2 5 0 
+
+minGini: 1.666666 - 11
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 1 5 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+minGini: 1.000000 - 8
+Region.size: 6
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 0 
+
+minGini: 0.000000 - 9
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+minGini: 9.280632 - 1
+Region.size: 57
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 6 5 
+RightChild.size: 46
+RightChild.ClassCounts: 0 2 44 
+
+minGini: 1.955555 - 3
+Region.size: 46
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 45
+RightChild.ClassCounts: 0 1 44 
+
+minGini: 0.000000 - 4
+Region.size: 45
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 44
+RightChild.ClassCounts: 0 0 44 
+
+minGini: 2.857142 - 3
+Region.size: 11
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 
+RightChild.size: 7
+RightChild.ClassCounts: 0 2 5 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+
+
+Tree Number: 15 finished.
+
+minGini: 69.951219 - 9
+Region.size: 178
+LeftChild.size: 55
+LeftChild.ClassCounts: 0 55 0 
+RightChild.size: 123
+RightChild.ClassCounts: 66 12 45 
+
+minGini: 20.813664 - 6
+Region.size: 123
+LeftChild.size: 46
+LeftChild.ClassCounts: 0 1 45 
+RightChild.size: 77
+RightChild.ClassCounts: 66 11 0 
+
+minGini: 0.000000 - 12
+Region.size: 77
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 11 0 
+RightChild.size: 66
+RightChild.ClassCounts: 66 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 46
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 45
+RightChild.ClassCounts: 0 0 45 
+
+
+
+Tree Number: 16 finished.
+
+minGini: 81.054550 - 5
+Region.size: 178
+LeftChild.size: 119
+LeftChild.ClassCounts: 11 75 33 
+RightChild.size: 59
+RightChild.ClassCounts: 47 11 1 
+
+minGini: 16.807017 - 1
+Region.size: 59
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 57
+RightChild.ClassCounts: 47 9 1 
+
+minGini: 3.757446 - 9
+Region.size: 57
+LeftChild.size: 10
+LeftChild.ClassCounts: 1 9 0 
+RightChild.size: 47
+RightChild.ClassCounts: 46 0 1 
+
+minGini: 0.000000 - 9
+Region.size: 47
+LeftChild.size: 46
+LeftChild.ClassCounts: 46 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+minGini: 0.000000 - 5
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 9 0 
+
+minGini: 34.285714 - 10
+Region.size: 119
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 2 26 
+RightChild.size: 91
+RightChild.ClassCounts: 11 73 7 
+
+minGini: 20.870588 - 6
+Region.size: 91
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 0 6 
+RightChild.size: 85
+RightChild.ClassCounts: 11 73 1 
+
+minGini: 10.700000 - 0
+Region.size: 85
+LeftChild.size: 65
+LeftChild.ClassCounts: 0 65 0 
+RightChild.size: 20
+RightChild.ClassCounts: 11 8 1 
+
+minGini: 1.777777 - 12
+Region.size: 20
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 8 1 
+RightChild.size: 11
+RightChild.ClassCounts: 11 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+minGini: 0.000000 - 3
+Region.size: 28
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 26
+RightChild.ClassCounts: 0 0 26 
+
+
+
+Tree Number: 17 finished.
+
+minGini: 66.622751 - 12
+Region.size: 178
+LeftChild.size: 108
+LeftChild.ClassCounts: 1 69 38 
+RightChild.size: 70
+RightChild.ClassCounts: 61 2 7 
+
+minGini: 3.717741 - 11
+Region.size: 70
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 1 7 
+RightChild.size: 62
+RightChild.ClassCounts: 61 1 0 
+
+minGini: 0.000000 - 4
+Region.size: 62
+LeftChild.size: 61
+LeftChild.ClassCounts: 61 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 1.000000 - 7
+Region.size: 8
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 
+RightChild.size: 6
+RightChild.ClassCounts: 0 0 6 
+
+minGini: 0.000000 - 5
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+minGini: 30.962962 - 12
+Region.size: 108
+LeftChild.size: 54
+LeftChild.ClassCounts: 0 51 3 
+RightChild.size: 54
+RightChild.ClassCounts: 1 18 35 
+
+minGini: 5.666136 - 6
+Region.size: 54
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 2 35 
+RightChild.size: 17
+RightChild.ClassCounts: 1 16 0 
+
+minGini: 0.000000 - 0
+Region.size: 17
+LeftChild.size: 16
+LeftChild.ClassCounts: 0 16 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+minGini: 1.944444 - 8
+Region.size: 37
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 36
+RightChild.ClassCounts: 0 1 35 
+
+minGini: 0.000000 - 9
+Region.size: 36
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 35
+RightChild.ClassCounts: 0 0 35 
+
+minGini: 0.000000 - 9
+Region.size: 54
+LeftChild.size: 51
+LeftChild.ClassCounts: 0 51 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+
+
+Tree Number: 18 finished.
+
+minGini: 69.484377 - 0
+Region.size: 178
+LeftChild.size: 69
+LeftChild.ClassCounts: 0 61 8 
+RightChild.size: 109
+RightChild.ClassCounts: 69 8 32 
+
+minGini: 14.337662 - 11
+Region.size: 109
+LeftChild.size: 32
+LeftChild.ClassCounts: 0 0 32 
+RightChild.size: 77
+RightChild.ClassCounts: 69 8 0 
+
+minGini: 7.561643 - 5
+Region.size: 77
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 
+RightChild.size: 73
+RightChild.ClassCounts: 69 4 0 
+
+minGini: 0.000000 - 9
+Region.size: 73
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 
+RightChild.size: 69
+RightChild.ClassCounts: 69 0 0 
+
+minGini: 6.153846 - 11
+Region.size: 69
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 5 8 
+RightChild.size: 56
+RightChild.ClassCounts: 0 56 0 
+
+minGini: 0.000000 - 10
+Region.size: 13
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 0 8 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 
+
+
+
+Tree Number: 19 finished.
+
+minGini: 76.144530 - 12
+Region.size: 178
+LeftChild.size: 107
+LeftChild.ClassCounts: 4 62 41 
+RightChild.size: 71
+RightChild.ClassCounts: 59 5 7 
+
+minGini: 7.057575 - 6
+Region.size: 71
+LeftChild.size: 11
+LeftChild.ClassCounts: 0 4 7 
+RightChild.size: 60
+RightChild.ClassCounts: 59 1 0 
+
+minGini: 1.500000 - 5
+Region.size: 60
+LeftChild.size: 56
+LeftChild.ClassCounts: 56 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 3 1 0 
+
+minGini: 0.000000 - 10
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 0.000000 - 11
+Region.size: 11
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 0 7 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 
+
+minGini: 21.744343 - 9
+Region.size: 107
+LeftChild.size: 68
+LeftChild.ClassCounts: 4 59 5 
+RightChild.size: 39
+RightChild.ClassCounts: 0 3 36 
+
+minGini: 1.945945 - 3
+Region.size: 39
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 37
+RightChild.ClassCounts: 0 1 36 
+
+minGini: 0.000000 - 2
+Region.size: 37
+LeftChild.size: 36
+LeftChild.ClassCounts: 0 0 36 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 11.902071 - 8
+Region.size: 68
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 4 5 
+RightChild.size: 59
+RightChild.ClassCounts: 4 55 0 
+
+minGini: 4.444444 - 4
+Region.size: 59
+LeftChild.size: 50
+LeftChild.ClassCounts: 0 50 0 
+RightChild.size: 9
+RightChild.ClassCounts: 4 5 0 
+
+minGini: 0.000000 - 10
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 
+
+minGini: 1.600000 - 4
+Region.size: 9
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 
+RightChild.size: 5
+RightChild.ClassCounts: 0 4 1 
+
+minGini: 0.000000 - 6
+Region.size: 5
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 
+
+
+
+Tree Number: 20 finished.
+
+minGini: 69.283008 - 11
+Region.size: 178
+LeftChild.size: 66
+LeftChild.ClassCounts: 0 7 59 
+RightChild.size: 112
+RightChild.ClassCounts: 59 52 1 
+
+minGini: 39.511688 - 3
+Region.size: 112
+LeftChild.size: 35
+LeftChild.ClassCounts: 33 2 0 
+RightChild.size: 77
+RightChild.ClassCounts: 26 50 1 
+
+minGini: 13.546984 - 12
+Region.size: 77
+LeftChild.size: 46
+LeftChild.ClassCounts: 1 44 1 
+RightChild.size: 31
+RightChild.ClassCounts: 25 6 0 
+
+minGini: 0.000000 - 9
+Region.size: 31
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 
+RightChild.size: 25
+RightChild.ClassCounts: 25 0 0 
+
+minGini: 3.142857 - 1
+Region.size: 46
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 39 0 
+RightChild.size: 7
+RightChild.ClassCounts: 1 5 1 
+
+minGini: 1.000000 - 9
+Region.size: 7
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 0 1 
+
+minGini: 0.000000 - 7
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 0 1 
+
+minGini: 0.000000 - 1
+Region.size: 35
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 33
+RightChild.ClassCounts: 33 0 0 
+
+minGini: 1.966666 - 9
+Region.size: 66
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 
+RightChild.size: 60
+RightChild.ClassCounts: 0 1 59 
+
+minGini: 0.000000 - 8
+Region.size: 60
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 59
+RightChild.ClassCounts: 0 0 59 
+
+
+
+Tree Number: 21 finished.
+
+minGini: 73.209022 - 11
+Region.size: 178
+LeftChild.size: 45
+LeftChild.ClassCounts: 0 3 42 
+RightChild.size: 133
+RightChild.ClassCounts: 58 73 2 
+
+minGini: 24.547945 - 9
+Region.size: 133
+LeftChild.size: 60
+LeftChild.ClassCounts: 0 60 0 
+RightChild.size: 73
+RightChild.ClassCounts: 58 13 2 
+
+minGini: 3.466666 - 12
+Region.size: 73
+LeftChild.size: 15
+LeftChild.ClassCounts: 0 13 2 
+RightChild.size: 58
+RightChild.ClassCounts: 58 0 0 
+
+minGini: 0.000000 - 8
+Region.size: 15
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 13
+RightChild.ClassCounts: 0 13 0 
+
+minGini: 0.000000 - 8
+Region.size: 45
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 42
+RightChild.ClassCounts: 0 0 42 
+
+
+
+Tree Number: 22 finished.
+
+minGini: 81.347803 - 10
+Region.size: 178
+LeftChild.size: 43
+LeftChild.ClassCounts: 0 6 37 
+RightChild.size: 135
+RightChild.ClassCounts: 61 70 4 
+
+minGini: 26.178571 - 9
+Region.size: 135
+LeftChild.size: 63
+LeftChild.ClassCounts: 2 61 0 
+RightChild.size: 72
+RightChild.ClassCounts: 59 9 4 
+
+minGini: 12.878787 - 1
+Region.size: 72
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 
+RightChild.size: 66
+RightChild.ClassCounts: 59 3 4 
+
+minGini: 4.750000 - 12
+Region.size: 66
+LeftChild.size: 8
+LeftChild.ClassCounts: 1 3 4 
+RightChild.size: 58
+RightChild.ClassCounts: 58 0 0 
+
+minGini: 1.500000 - 0
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 1 3 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 
+
+minGini: 0.000000 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+minGini: 0.000000 - 2
+Region.size: 63
+LeftChild.size: 61
+LeftChild.ClassCounts: 0 61 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 
+
+minGini: 1.947368 - 11
+Region.size: 43
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 1 37 
+RightChild.size: 5
+RightChild.ClassCounts: 0 5 0 
+
+minGini: 0.000000 - 3
+Region.size: 38
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 37
+RightChild.ClassCounts: 0 0 37 
+
+
+
+Tree Number: 23 finished.
+
+minGini: 73.315354 - 10
+Region.size: 178
+LeftChild.size: 57
+LeftChild.ClassCounts: 0 6 51 
+RightChild.size: 121
+RightChild.ClassCounts: 52 66 3 
+
+minGini: 15.934426 - 0
+Region.size: 121
+LeftChild.size: 60
+LeftChild.ClassCounts: 0 60 0 
+RightChild.size: 61
+RightChild.ClassCounts: 52 6 3 
+
+minGini: 7.535714 - 4
+Region.size: 61
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 
+RightChild.size: 56
+RightChild.ClassCounts: 52 1 3 
+
+minGini: 1.500000 - 7
+Region.size: 56
+LeftChild.size: 52
+LeftChild.ClassCounts: 52 0 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 1 3 
+
+minGini: 0.000000 - 12
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 7.418181 - 4
+Region.size: 57
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 55
+RightChild.ClassCounts: 0 4 51 
+
+minGini: 0.000000 - 6
+Region.size: 55
+LeftChild.size: 51
+LeftChild.ClassCounts: 0 0 51 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 
+
+
+
+Tree Number: 24 finished.
+
+minGini: 65.584491 - 12
+Region.size: 178
+LeftChild.size: 110
+LeftChild.ClassCounts: 1 68 41 
+RightChild.size: 68
+RightChild.ClassCounts: 61 4 3 
+
+minGini: 5.718750 - 9
+Region.size: 68
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 4 0 
+RightChild.size: 64
+RightChild.ClassCounts: 61 0 3 
+
+minGini: 0.000000 - 6
+Region.size: 64
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 61
+RightChild.ClassCounts: 61 0 0 
+
+minGini: 10.881793 - 11
+Region.size: 110
+LeftChild.size: 46
+LeftChild.ClassCounts: 0 5 41 
+RightChild.size: 64
+RightChild.ClassCounts: 1 63 0 
+
+minGini: 1.714285 - 9
+Region.size: 64
+LeftChild.size: 57
+LeftChild.ClassCounts: 0 57 0 
+RightChild.size: 7
+RightChild.ClassCounts: 1 6 0 
+
+minGini: 0.000000 - 1
+Region.size: 7
+LeftChild.size: 6
+LeftChild.ClassCounts: 0 6 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+minGini: 3.750000 - 10
+Region.size: 46
+LeftChild.size: 38
+LeftChild.ClassCounts: 0 0 38 
+RightChild.size: 8
+RightChild.ClassCounts: 0 5 3 
+
+minGini: 1.500000 - 6
+Region.size: 8
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 1 3 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 
+
+minGini: 0.000000 - 11
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+
+
+Tree Number: 25 finished.
+
+minGini: 75.285714 - 9
+Region.size: 178
+LeftChild.size: 52
+LeftChild.ClassCounts: 0 52 0 
+RightChild.size: 126
+RightChild.ClassCounts: 57 15 54 
+
+minGini: 24.442509 - 6
+Region.size: 126
+LeftChild.size: 55
+LeftChild.ClassCounts: 0 1 54 
+RightChild.size: 71
+RightChild.ClassCounts: 57 14 0 
+
+minGini: 0.000000 - 12
+Region.size: 71
+LeftChild.size: 14
+LeftChild.ClassCounts: 0 14 0 
+RightChild.size: 57
+RightChild.ClassCounts: 57 0 0 
+
+minGini: 1.333333 - 12
+Region.size: 55
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 1 2 
+RightChild.size: 52
+RightChild.ClassCounts: 0 0 52 
+
+minGini: 0.000000 - 12
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+
+
+Tree Number: 26 finished.
+
+minGini: 72.852758 - 0
+Region.size: 178
+LeftChild.size: 95
+LeftChild.ClassCounts: 0 69 26 
+RightChild.size: 83
+RightChild.ClassCounts: 60 4 19 
+
+minGini: 7.614285 - 11
+Region.size: 83
+LeftChild.size: 20
+LeftChild.ClassCounts: 0 1 19 
+RightChild.size: 63
+RightChild.ClassCounts: 60 3 0 
+
+minGini: 0.000000 - 12
+Region.size: 63
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 60
+RightChild.ClassCounts: 60 0 0 
+
+minGini: 0.000000 - 4
+Region.size: 20
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 19
+RightChild.ClassCounts: 0 0 19 
+
+minGini: 7.327292 - 10
+Region.size: 95
+LeftChild.size: 28
+LeftChild.ClassCounts: 0 3 25 
+RightChild.size: 67
+RightChild.ClassCounts: 0 66 1 
+
+minGini: 1.500000 - 0
+Region.size: 67
+LeftChild.size: 63
+LeftChild.ClassCounts: 0 63 0 
+RightChild.size: 4
+RightChild.ClassCounts: 0 3 1 
+
+minGini: 0.000000 - 12
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 0 
+
+minGini: 0.000000 - 12
+Region.size: 28
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 25
+RightChild.ClassCounts: 0 0 25 
+
+
+
+Tree Number: 27 finished.
+
+minGini: 71.913591 - 12
+Region.size: 178
+LeftChild.size: 101
+LeftChild.ClassCounts: 5 60 36 
+RightChild.size: 77
+RightChild.ClassCounts: 66 6 5 
+
+minGini: 8.326797 - 11
+Region.size: 77
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 4 5 
+RightChild.size: 68
+RightChild.ClassCounts: 66 2 0 
+
+minGini: 0.000000 - 4
+Region.size: 68
+LeftChild.size: 66
+LeftChild.ClassCounts: 66 0 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+minGini: 0.000000 - 8
+Region.size: 9
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 0 5 
+RightChild.size: 4
+RightChild.ClassCounts: 0 4 0 
+
+minGini: 24.742398 - 6
+Region.size: 101
+LeftChild.size: 37
+LeftChild.ClassCounts: 0 5 32 
+RightChild.size: 64
+RightChild.ClassCounts: 5 55 4 
+
+minGini: 10.752542 - 11
+Region.size: 64
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 1 4 
+RightChild.size: 59
+RightChild.ClassCounts: 5 54 0 
+
+minGini: 6.153846 - 4
+Region.size: 59
+LeftChild.size: 46
+LeftChild.ClassCounts: 0 46 0 
+RightChild.size: 13
+RightChild.ClassCounts: 5 8 0 
+
+minGini: 1.777777 - 4
+Region.size: 13
+LeftChild.size: 4
+LeftChild.ClassCounts: 4 0 0 
+RightChild.size: 9
+RightChild.ClassCounts: 1 8 0 
+
+minGini: 0.000000 - 0
+Region.size: 9
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 8 0 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 0 
+
+minGini: 0.000000 - 12
+Region.size: 5
+LeftChild.size: 4
+LeftChild.ClassCounts: 0 0 4 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 3.750000 - 0
+Region.size: 37
+LeftChild.size: 8
+LeftChild.ClassCounts: 0 5 3 
+RightChild.size: 29
+RightChild.ClassCounts: 0 0 29 
+
+minGini: 0.000000 - 1
+Region.size: 8
+LeftChild.size: 5
+LeftChild.ClassCounts: 0 5 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 0 3 
+
+
+
+Tree Number: 28 finished.
+
+minGini: 78.135768 - 6
+Region.size: 178
+LeftChild.size: 39
+LeftChild.ClassCounts: 0 1 38 
+RightChild.size: 139
+RightChild.ClassCounts: 55 75 9 
+
+minGini: 21.689655 - 12
+Region.size: 139
+LeftChild.size: 81
+LeftChild.ClassCounts: 0 72 9 
+RightChild.size: 58
+RightChild.ClassCounts: 55 3 0 
+
+minGini: 1.964285 - 0
+Region.size: 58
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 0 
+RightChild.size: 56
+RightChild.ClassCounts: 55 1 0 
+
+minGini: 1.500000 - 0
+Region.size: 56
+LeftChild.size: 4
+LeftChild.ClassCounts: 3 1 0 
+RightChild.size: 52
+RightChild.ClassCounts: 52 0 0 
+
+minGini: 0.000000 - 11
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 0 
+
+minGini: 0.000000 - 11
+Region.size: 81
+LeftChild.size: 9
+LeftChild.ClassCounts: 0 0 9 
+RightChild.size: 72
+RightChild.ClassCounts: 0 72 0 
+
+minGini: 0.000000 - 1
+Region.size: 39
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 38
+RightChild.ClassCounts: 0 0 38 
+
+
+
+Tree Number: 29 finished.
+
+minGini: 70.868969 - 12
+Region.size: 178
+LeftChild.size: 114
+LeftChild.ClassCounts: 2 63 49 
+RightChild.size: 64
+RightChild.ClassCounts: 57 2 5 
+
+minGini: 5.766666 - 9
+Region.size: 64
+LeftChild.size: 60
+LeftChild.ClassCounts: 57 2 1 
+RightChild.size: 4
+RightChild.ClassCounts: 0 0 4 
+
+minGini: 2.965517 - 11
+Region.size: 60
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 1 1 
+RightChild.size: 58
+RightChild.ClassCounts: 57 1 0 
+
+minGini: 0.000000 - 0
+Region.size: 58
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 57
+RightChild.ClassCounts: 57 0 0 
+
+minGini: 0.000000 - 3
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 0 
+
+minGini: 14.535211 - 6
+Region.size: 114
+LeftChild.size: 43
+LeftChild.ClassCounts: 0 0 43 
+RightChild.size: 71
+RightChild.ClassCounts: 2 63 6 
+
+minGini: 9.441176 - 10
+Region.size: 71
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 68
+RightChild.ClassCounts: 2 63 3 
+
+minGini: 3.876923 - 11
+Region.size: 68
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 0 3 
+RightChild.size: 65
+RightChild.ClassCounts: 2 63 0 
+
+minGini: 3.111111 - 9
+Region.size: 65
+LeftChild.size: 56
+LeftChild.ClassCounts: 0 56 0 
+RightChild.size: 9
+RightChild.ClassCounts: 2 7 0 
+
+minGini: 0.000000 - 12
+Region.size: 9
+LeftChild.size: 7
+LeftChild.ClassCounts: 0 7 0 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 0 
+
+
+
+Tree Number: 30 finished.
+
+minGini: 70.628226 - 11
+Region.size: 178
+LeftChild.size: 53
+LeftChild.ClassCounts: 0 4 49 
+RightChild.size: 125
+RightChild.ClassCounts: 66 58 1 
+
+minGini: 7.628571 - 12
+Region.size: 125
+LeftChild.size: 55
+LeftChild.ClassCounts: 0 55 0 
+RightChild.size: 70
+RightChild.ClassCounts: 66 3 1 
+
+minGini: 3.911764 - 4
+Region.size: 70
+LeftChild.size: 68
+LeftChild.ClassCounts: 66 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 0 
+
+minGini: 1.970149 - 11
+Region.size: 68
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 0 1 
+RightChild.size: 67
+RightChild.ClassCounts: 66 1 0 
+
+minGini: 1.857142 - 8
+Region.size: 67
+LeftChild.size: 14
+LeftChild.ClassCounts: 13 1 0 
+RightChild.size: 53
+RightChild.ClassCounts: 53 0 0 
+
+minGini: 0.000000 - 1
+Region.size: 14
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 13
+RightChild.ClassCounts: 13 0 0 
+
+minGini: 5.538461 - 12
+Region.size: 53
+LeftChild.size: 13
+LeftChild.ClassCounts: 0 4 9 
+RightChild.size: 40
+RightChild.ClassCounts: 0 0 40 
+
+minGini: 1.800000 - 9
+Region.size: 13
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 0 
+RightChild.size: 10
+RightChild.ClassCounts: 0 1 9 
+
+minGini: 0.000000 - 1
+Region.size: 10
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 0 
+RightChild.size: 9
+RightChild.ClassCounts: 0 0 9 
+
+
+
+Tree Number: 31 finished.
+
+wine
diff --git a/test/classifier/data/oldsetTest.log b/test/classifier/data/oldsetTest.log
new file mode 100644
index 0000000..50515eb
--- /dev/null
+++ b/test/classifier/data/oldsetTest.log
@@ -0,0 +1,618 @@
+
+
+Tree Number: 0 finished.
+
+minGini: 0 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+
+
+Tree Number: 1 finished.
+
+minGini: 0 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+
+
+Tree Number: 2 finished.
+
+minGini: 0 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 3 finished.
+
+minGini: 0 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 4 finished.
+
+minGini: 0 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 5 finished.
+
+minGini: 0 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 6 finished.
+
+minGini: 0 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 3 0 
+
+
+
+Tree Number: 7 finished.
+
+minGini: 0 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 0 3 
+
+
+
+Tree Number: 8 finished.
+
+minGini: 0 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 9 finished.
+
+minGini: 0 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 10 finished.
+
+minGini: 0 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 0 3 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 11 finished.
+
+minGini: 0 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 3 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 12 finished.
+
+minGini: 0.5 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 13 finished.
+
+minGini: 0.5 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 14 finished.
+
+minGini: 0.5 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 15 finished.
+
+minGini: 0.5 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 16 finished.
+
+minGini: 0.5 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 17 finished.
+
+minGini: 0.5 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+minGini: 0 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 18 finished.
+
+minGini: 0.5 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+minGini: 0 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 19 finished.
+
+minGini: 0.5 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 20 finished.
+
+minGini: 0.666667 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 21 finished.
+
+minGini: 0.666667 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 22 finished.
+
+minGini: 0.666667 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 23 finished.
+
+minGini: 0.666667 - 0
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 24 finished.
+
+minGini: 0.666667 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 25 finished.
+
+minGini: 0.666667 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0 - 1
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 26 finished.
+
+minGini: 0.666667 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 27 finished.
+
+minGini: 0.666667 - 0
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0 - 1
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 28 finished.
+
+minGini: 0.666667 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 29 finished.
+
+minGini: 0.666667 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 30 finished.
+
+minGini: 0.666667 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 1 2 
+
+minGini: 0 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 2
+RightChild.ClassCounts: 0 2 
+
+
+
+Tree Number: 31 finished.
+
+minGini: 0.666667 - 1
+Region.size: 4
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 3
+RightChild.ClassCounts: 2 1 
+
+minGini: 0 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 2 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+
+
+Tree Number: 32 finished.
+
+minGini: 0.666667 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 33 finished.
+
+minGini: 0.666667 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 1 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0 - 0
+Region.size: 3
+LeftChild.size: 2
+LeftChild.ClassCounts: 0 2 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 34 finished.
+
+minGini: 0.666667 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 35 finished.
+
+minGini: 0.666667 - 1
+Region.size: 4
+LeftChild.size: 3
+LeftChild.ClassCounts: 2 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+minGini: 0 - 0
+Region.size: 3
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 2
+RightChild.ClassCounts: 2 0 
+
+
+
+Tree Number: 36 finished.
+
+minGini: 1 - 0
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0 - 1
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 37 finished.
+
+minGini: 1 - 1
+Region.size: 4
+LeftChild.size: 2
+LeftChild.ClassCounts: 1 1 
+RightChild.size: 2
+RightChild.ClassCounts: 1 1 
+
+minGini: 0 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 1 0 
+RightChild.size: 1
+RightChild.ClassCounts: 0 1 
+
+minGini: 0 - 0
+Region.size: 2
+LeftChild.size: 1
+LeftChild.ClassCounts: 0 1 
+RightChild.size: 1
+RightChild.ClassCounts: 1 0 
+
+
+
+Tree Number: 38 finished.
+
diff --git a/test/classifier/data/pina_indians_diabetes_features.hxx b/test/classifier/data/pina_indians_diabetes_features.hxx
new file mode 100644
index 0000000..a36af41
--- /dev/null
+++ b/test/classifier/data/pina_indians_diabetes_features.hxx
@@ -0,0 +1,774 @@
+#ifndef PINA_INDIANS_DIABETES_FEATURES
+#define PINA_INDIANS_DIABETES_FEATURES
+double pina_indians_diabetes_features[] = {
+6,148,72,35,0,33.6,0.627,50,
+1,85,66,29,0,26.6,0.351,31,
+8,183,64,0,0,23.3,0.672,32,
+1,89,66,23,94,28.1,0.167,21,
+0,137,40,35,168,43.1,2.288,33,
+5,116,74,0,0,25.6,0.201,30,
+3,78,50,32,88,31,0.248,26,
+10,115,0,0,0,35.3,0.134,29,
+2,197,70,45,543,30.5,0.158,53,
+8,125,96,0,0,0,0.232,54,
+4,110,92,0,0,37.6,0.191,30,
+10,168,74,0,0,38,0.537,34,
+10,139,80,0,0,27.1,1.441,57,
+1,189,60,23,846,30.1,0.398,59,
+5,166,72,19,175,25.8,0.587,51,
+7,100,0,0,0,30,0.484,32,
+0,118,84,47,230,45.8,0.551,31,
+7,107,74,0,0,29.6,0.254,31,
+1,103,30,38,83,43.3,0.183,33,
+1,115,70,30,96,34.6,0.529,32,
+3,126,88,41,235,39.3,0.704,27,
+8,99,84,0,0,35.4,0.388,50,
+7,196,90,0,0,39.8,0.451,41,
+9,119,80,35,0,29,0.263,29,
+11,143,94,33,146,36.6,0.254,51,
+10,125,70,26,115,31.1,0.205,41,
+7,147,76,0,0,39.4,0.257,43,
+1,97,66,15,140,23.2,0.487,22,
+13,145,82,19,110,22.2,0.245,57,
+5,117,92,0,0,34.1,0.337,38,
+5,109,75,26,0,36,0.546,60,
+3,158,76,36,245,31.6,0.851,28,
+3,88,58,11,54,24.8,0.267,22,
+6,92,92,0,0,19.9,0.188,28,
+10,122,78,31,0,27.6,0.512,45,
+4,103,60,33,192,24,0.966,33,
+11,138,76,0,0,33.2,0.42,35,
+9,102,76,37,0,32.9,0.665,46,
+2,90,68,42,0,38.2,0.503,27,
+4,111,72,47,207,37.1,1.39,56,
+3,180,64,25,70,34,0.271,26,
+7,133,84,0,0,40.2,0.696,37,
+7,106,92,18,0,22.7,0.235,48,
+9,171,110,24,240,45.4,0.721,54,
+7,159,64,0,0,27.4,0.294,40,
+0,180,66,39,0,42,1.893,25,
+1,146,56,0,0,29.7,0.564,29,
+2,71,70,27,0,28,0.586,22,
+7,103,66,32,0,39.1,0.344,31,
+7,105,0,0,0,0,0.305,24,
+1,103,80,11,82,19.4,0.491,22,
+1,101,50,15,36,24.2,0.526,26,
+5,88,66,21,23,24.4,0.342,30,
+8,176,90,34,300,33.7,0.467,58,
+7,150,66,42,342,34.7,0.718,42,
+1,73,50,10,0,23,0.248,21,
+7,187,68,39,304,37.7,0.254,41,
+0,100,88,60,110,46.8,0.962,31,
+0,146,82,0,0,40.5,1.781,44,
+0,105,64,41,142,41.5,0.173,22,
+2,84,0,0,0,0,0.304,21,
+8,133,72,0,0,32.9,0.27,39,
+5,44,62,0,0,25,0.587,36,
+2,141,58,34,128,25.4,0.699,24,
+7,114,66,0,0,32.8,0.258,42,
+5,99,74,27,0,29,0.203,32,
+0,109,88,30,0,32.5,0.855,38,
+2,109,92,0,0,42.7,0.845,54,
+1,95,66,13,38,19.6,0.334,25,
+4,146,85,27,100,28.9,0.189,27,
+2,100,66,20,90,32.9,0.867,28,
+5,139,64,35,140,28.6,0.411,26,
+13,126,90,0,0,43.4,0.583,42,
+4,129,86,20,270,35.1,0.231,23,
+1,79,75,30,0,32,0.396,22,
+1,0,48,20,0,24.7,0.14,22,
+7,62,78,0,0,32.6,0.391,41,
+5,95,72,33,0,37.7,0.37,27,
+0,131,0,0,0,43.2,0.27,26,
+2,112,66,22,0,25,0.307,24,
+3,113,44,13,0,22.4,0.14,22,
+2,74,0,0,0,0,0.102,22,
+7,83,78,26,71,29.3,0.767,36,
+0,101,65,28,0,24.6,0.237,22,
+5,137,108,0,0,48.8,0.227,37,
+2,110,74,29,125,32.4,0.698,27,
+13,106,72,54,0,36.6,0.178,45,
+2,100,68,25,71,38.5,0.324,26,
+15,136,70,32,110,37.1,0.153,43,
+1,107,68,19,0,26.5,0.165,24,
+1,80,55,0,0,19.1,0.258,21,
+4,123,80,15,176,32,0.443,34,
+7,81,78,40,48,46.7,0.261,42,
+4,134,72,0,0,23.8,0.277,60,
+2,142,82,18,64,24.7,0.761,21,
+6,144,72,27,228,33.9,0.255,40,
+2,92,62,28,0,31.6,0.13,24,
+1,71,48,18,76,20.4,0.323,22,
+6,93,50,30,64,28.7,0.356,23,
+1,122,90,51,220,49.7,0.325,31,
+1,163,72,0,0,39,1.222,33,
+1,151,60,0,0,26.1,0.179,22,
+0,125,96,0,0,22.5,0.262,21,
+1,81,72,18,40,26.6,0.283,24,
+2,85,65,0,0,39.6,0.93,27,
+1,126,56,29,152,28.7,0.801,21,
+1,96,122,0,0,22.4,0.207,27,
+4,144,58,28,140,29.5,0.287,37,
+3,83,58,31,18,34.3,0.336,25,
+0,95,85,25,36,37.4,0.247,24,
+3,171,72,33,135,33.3,0.199,24,
+8,155,62,26,495,34,0.543,46,
+1,89,76,34,37,31.2,0.192,23,
+4,76,62,0,0,34,0.391,25,
+7,160,54,32,175,30.5,0.588,39,
+4,146,92,0,0,31.2,0.539,61,
+5,124,74,0,0,34,0.22,38,
+5,78,48,0,0,33.7,0.654,25,
+4,97,60,23,0,28.2,0.443,22,
+4,99,76,15,51,23.2,0.223,21,
+0,162,76,56,100,53.2,0.759,25,
+6,111,64,39,0,34.2,0.26,24,
+2,107,74,30,100,33.6,0.404,23,
+5,132,80,0,0,26.8,0.186,69,
+0,113,76,0,0,33.3,0.278,23,
+1,88,30,42,99,55,0.496,26,
+3,120,70,30,135,42.9,0.452,30,
+1,118,58,36,94,33.3,0.261,23,
+1,117,88,24,145,34.5,0.403,40,
+0,105,84,0,0,27.9,0.741,62,
+4,173,70,14,168,29.7,0.361,33,
+9,122,56,0,0,33.3,1.114,33,
+3,170,64,37,225,34.5,0.356,30,
+8,84,74,31,0,38.3,0.457,39,
+2,96,68,13,49,21.1,0.647,26,
+2,125,60,20,140,33.8,0.088,31,
+0,100,70,26,50,30.8,0.597,21,
+0,93,60,25,92,28.7,0.532,22,
+0,129,80,0,0,31.2,0.703,29,
+5,105,72,29,325,36.9,0.159,28,
+3,128,78,0,0,21.1,0.268,55,
+5,106,82,30,0,39.5,0.286,38,
+2,108,52,26,63,32.5,0.318,22,
+10,108,66,0,0,32.4,0.272,42,
+4,154,62,31,284,32.8,0.237,23,
+0,102,75,23,0,0,0.572,21,
+9,57,80,37,0,32.8,0.096,41,
+2,106,64,35,119,30.5,1.4,34,
+5,147,78,0,0,33.7,0.218,65,
+2,90,70,17,0,27.3,0.085,22,
+1,136,74,50,204,37.4,0.399,24,
+4,114,65,0,0,21.9,0.432,37,
+9,156,86,28,155,34.3,1.189,42,
+1,153,82,42,485,40.6,0.687,23,
+8,188,78,0,0,47.9,0.137,43,
+7,152,88,44,0,50,0.337,36,
+2,99,52,15,94,24.6,0.637,21,
+1,109,56,21,135,25.2,0.833,23,
+2,88,74,19,53,29,0.229,22,
+17,163,72,41,114,40.9,0.817,47,
+4,151,90,38,0,29.7,0.294,36,
+7,102,74,40,105,37.2,0.204,45,
+0,114,80,34,285,44.2,0.167,27,
+2,100,64,23,0,29.7,0.368,21,
+0,131,88,0,0,31.6,0.743,32,
+6,104,74,18,156,29.9,0.722,41,
+3,148,66,25,0,32.5,0.256,22,
+4,120,68,0,0,29.6,0.709,34,
+4,110,66,0,0,31.9,0.471,29,
+3,111,90,12,78,28.4,0.495,29,
+6,102,82,0,0,30.8,0.18,36,
+6,134,70,23,130,35.4,0.542,29,
+2,87,0,23,0,28.9,0.773,25,
+1,79,60,42,48,43.5,0.678,23,
+2,75,64,24,55,29.7,0.37,33,
+8,179,72,42,130,32.7,0.719,36,
+6,85,78,0,0,31.2,0.382,42,
+0,129,110,46,130,67.1,0.319,26,
+5,143,78,0,0,45,0.19,47,
+5,130,82,0,0,39.1,0.956,37,
+6,87,80,0,0,23.2,0.084,32,
+0,119,64,18,92,34.9,0.725,23,
+1,0,74,20,23,27.7,0.299,21,
+5,73,60,0,0,26.8,0.268,27,
+4,141,74,0,0,27.6,0.244,40,
+7,194,68,28,0,35.9,0.745,41,
+8,181,68,36,495,30.1,0.615,60,
+1,128,98,41,58,32,1.321,33,
+8,109,76,39,114,27.9,0.64,31,
+5,139,80,35,160,31.6,0.361,25,
+3,111,62,0,0,22.6,0.142,21,
+9,123,70,44,94,33.1,0.374,40,
+7,159,66,0,0,30.4,0.383,36,
+11,135,0,0,0,52.3,0.578,40,
+8,85,55,20,0,24.4,0.136,42,
+5,158,84,41,210,39.4,0.395,29,
+1,105,58,0,0,24.3,0.187,21,
+3,107,62,13,48,22.9,0.678,23,
+4,109,64,44,99,34.8,0.905,26,
+4,148,60,27,318,30.9,0.15,29,
+0,113,80,16,0,31,0.874,21,
+1,138,82,0,0,40.1,0.236,28,
+0,108,68,20,0,27.3,0.787,32,
+2,99,70,16,44,20.4,0.235,27,
+6,103,72,32,190,37.7,0.324,55,
+5,111,72,28,0,23.9,0.407,27,
+8,196,76,29,280,37.5,0.605,57,
+5,162,104,0,0,37.7,0.151,52,
+1,96,64,27,87,33.2,0.289,21,
+7,184,84,33,0,35.5,0.355,41,
+2,81,60,22,0,27.7,0.29,25,
+0,147,85,54,0,42.8,0.375,24,
+7,179,95,31,0,34.2,0.164,60,
+0,140,65,26,130,42.6,0.431,24,
+9,112,82,32,175,34.2,0.26,36,
+12,151,70,40,271,41.8,0.742,38,
+5,109,62,41,129,35.8,0.514,25,
+6,125,68,30,120,30,0.464,32,
+5,85,74,22,0,29,1.224,32,
+5,112,66,0,0,37.8,0.261,41,
+0,177,60,29,478,34.6,1.072,21,
+2,158,90,0,0,31.6,0.805,66,
+7,119,0,0,0,25.2,0.209,37,
+7,142,60,33,190,28.8,0.687,61,
+1,100,66,15,56,23.6,0.666,26,
+1,87,78,27,32,34.6,0.101,22,
+0,101,76,0,0,35.7,0.198,26,
+3,162,52,38,0,37.2,0.652,24,
+4,197,70,39,744,36.7,2.329,31,
+0,117,80,31,53,45.2,0.089,24,
+4,142,86,0,0,44,0.645,22,
+6,134,80,37,370,46.2,0.238,46,
+1,79,80,25,37,25.4,0.583,22,
+4,122,68,0,0,35,0.394,29,
+3,74,68,28,45,29.7,0.293,23,
+4,171,72,0,0,43.6,0.479,26,
+7,181,84,21,192,35.9,0.586,51,
+0,179,90,27,0,44.1,0.686,23,
+9,164,84,21,0,30.8,0.831,32,
+0,104,76,0,0,18.4,0.582,27,
+1,91,64,24,0,29.2,0.192,21,
+4,91,70,32,88,33.1,0.446,22,
+3,139,54,0,0,25.6,0.402,22,
+6,119,50,22,176,27.1,1.318,33,
+2,146,76,35,194,38.2,0.329,29,
+9,184,85,15,0,30,1.213,49,
+10,122,68,0,0,31.2,0.258,41,
+0,165,90,33,680,52.3,0.427,23,
+9,124,70,33,402,35.4,0.282,34,
+1,111,86,19,0,30.1,0.143,23,
+9,106,52,0,0,31.2,0.38,42,
+2,129,84,0,0,28,0.284,27,
+2,90,80,14,55,24.4,0.249,24,
+0,86,68,32,0,35.8,0.238,25,
+12,92,62,7,258,27.6,0.926,44,
+1,113,64,35,0,33.6,0.543,21,
+3,111,56,39,0,30.1,0.557,30,
+2,114,68,22,0,28.7,0.092,25,
+1,193,50,16,375,25.9,0.655,24,
+11,155,76,28,150,33.3,1.353,51,
+3,191,68,15,130,30.9,0.299,34,
+3,141,0,0,0,30,0.761,27,
+4,95,70,32,0,32.1,0.612,24,
+3,142,80,15,0,32.4,0.2,63,
+4,123,62,0,0,32,0.226,35,
+5,96,74,18,67,33.6,0.997,43,
+0,138,0,0,0,36.3,0.933,25,
+2,128,64,42,0,40,1.101,24,
+0,102,52,0,0,25.1,0.078,21,
+2,146,0,0,0,27.5,0.24,28,
+10,101,86,37,0,45.6,1.136,38,
+2,108,62,32,56,25.2,0.128,21,
+3,122,78,0,0,23,0.254,40,
+1,71,78,50,45,33.2,0.422,21,
+13,106,70,0,0,34.2,0.251,52,
+2,100,70,52,57,40.5,0.677,25,
+7,106,60,24,0,26.5,0.296,29,
+0,104,64,23,116,27.8,0.454,23,
+5,114,74,0,0,24.9,0.744,57,
+2,108,62,10,278,25.3,0.881,22,
+0,146,70,0,0,37.9,0.334,28,
+10,129,76,28,122,35.9,0.28,39,
+7,133,88,15,155,32.4,0.262,37,
+7,161,86,0,0,30.4,0.165,47,
+2,108,80,0,0,27,0.259,52,
+7,136,74,26,135,26,0.647,51,
+5,155,84,44,545,38.7,0.619,34,
+1,119,86,39,220,45.6,0.808,29,
+4,96,56,17,49,20.8,0.34,26,
+5,108,72,43,75,36.1,0.263,33,
+0,78,88,29,40,36.9,0.434,21,
+0,107,62,30,74,36.6,0.757,25,
+2,128,78,37,182,43.3,1.224,31,
+1,128,48,45,194,40.5,0.613,24,
+0,161,50,0,0,21.9,0.254,65,
+6,151,62,31,120,35.5,0.692,28,
+2,146,70,38,360,28,0.337,29,
+0,126,84,29,215,30.7,0.52,24,
+14,100,78,25,184,36.6,0.412,46,
+8,112,72,0,0,23.6,0.84,58,
+0,167,0,0,0,32.3,0.839,30,
+2,144,58,33,135,31.6,0.422,25,
+5,77,82,41,42,35.8,0.156,35,
+5,115,98,0,0,52.9,0.209,28,
+3,150,76,0,0,21,0.207,37,
+2,120,76,37,105,39.7,0.215,29,
+10,161,68,23,132,25.5,0.326,47,
+0,137,68,14,148,24.8,0.143,21,
+0,128,68,19,180,30.5,1.391,25,
+2,124,68,28,205,32.9,0.875,30,
+6,80,66,30,0,26.2,0.313,41,
+0,106,70,37,148,39.4,0.605,22,
+2,155,74,17,96,26.6,0.433,27,
+3,113,50,10,85,29.5,0.626,25,
+7,109,80,31,0,35.9,1.127,43,
+2,112,68,22,94,34.1,0.315,26,
+3,99,80,11,64,19.3,0.284,30,
+3,182,74,0,0,30.5,0.345,29,
+3,115,66,39,140,38.1,0.15,28,
+6,194,78,0,0,23.5,0.129,59,
+4,129,60,12,231,27.5,0.527,31,
+3,112,74,30,0,31.6,0.197,25,
+0,124,70,20,0,27.4,0.254,36,
+13,152,90,33,29,26.8,0.731,43,
+2,112,75,32,0,35.7,0.148,21,
+1,157,72,21,168,25.6,0.123,24,
+1,122,64,32,156,35.1,0.692,30,
+10,179,70,0,0,35.1,0.2,37,
+2,102,86,36,120,45.5,0.127,23,
+6,105,70,32,68,30.8,0.122,37,
+8,118,72,19,0,23.1,1.476,46,
+2,87,58,16,52,32.7,0.166,25,
+1,180,0,0,0,43.3,0.282,41,
+12,106,80,0,0,23.6,0.137,44,
+1,95,60,18,58,23.9,0.26,22,
+0,165,76,43,255,47.9,0.259,26,
+0,117,0,0,0,33.8,0.932,44,
+5,115,76,0,0,31.2,0.343,44,
+9,152,78,34,171,34.2,0.893,33,
+7,178,84,0,0,39.9,0.331,41,
+1,130,70,13,105,25.9,0.472,22,
+1,95,74,21,73,25.9,0.673,36,
+1,0,68,35,0,32,0.389,22,
+5,122,86,0,0,34.7,0.29,33,
+8,95,72,0,0,36.8,0.485,57,
+8,126,88,36,108,38.5,0.349,49,
+1,139,46,19,83,28.7,0.654,22,
+3,116,0,0,0,23.5,0.187,23,
+3,99,62,19,74,21.8,0.279,26,
+5,0,80,32,0,41,0.346,37,
+4,92,80,0,0,42.2,0.237,29,
+4,137,84,0,0,31.2,0.252,30,
+3,61,82,28,0,34.4,0.243,46,
+1,90,62,12,43,27.2,0.58,24,
+3,90,78,0,0,42.7,0.559,21,
+9,165,88,0,0,30.4,0.302,49,
+1,125,50,40,167,33.3,0.962,28,
+13,129,0,30,0,39.9,0.569,44,
+12,88,74,40,54,35.3,0.378,48,
+1,196,76,36,249,36.5,0.875,29,
+5,189,64,33,325,31.2,0.583,29,
+5,158,70,0,0,29.8,0.207,63,
+5,103,108,37,0,39.2,0.305,65,
+4,146,78,0,0,38.5,0.52,67,
+4,147,74,25,293,34.9,0.385,30,
+5,99,54,28,83,34,0.499,30,
+6,124,72,0,0,27.6,0.368,29,
+0,101,64,17,0,21,0.252,21,
+3,81,86,16,66,27.5,0.306,22,
+1,133,102,28,140,32.8,0.234,45,
+3,173,82,48,465,38.4,2.137,25,
+0,118,64,23,89,0,1.731,21,
+0,84,64,22,66,35.8,0.545,21,
+2,105,58,40,94,34.9,0.225,25,
+2,122,52,43,158,36.2,0.816,28,
+12,140,82,43,325,39.2,0.528,58,
+0,98,82,15,84,25.2,0.299,22,
+1,87,60,37,75,37.2,0.509,22,
+4,156,75,0,0,48.3,0.238,32,
+0,93,100,39,72,43.4,1.021,35,
+1,107,72,30,82,30.8,0.821,24,
+0,105,68,22,0,20,0.236,22,
+1,109,60,8,182,25.4,0.947,21,
+1,90,62,18,59,25.1,1.268,25,
+1,125,70,24,110,24.3,0.221,25,
+1,119,54,13,50,22.3,0.205,24,
+5,116,74,29,0,32.3,0.66,35,
+8,105,100,36,0,43.3,0.239,45,
+5,144,82,26,285,32,0.452,58,
+3,100,68,23,81,31.6,0.949,28,
+1,100,66,29,196,32,0.444,42,
+5,166,76,0,0,45.7,0.34,27,
+1,131,64,14,415,23.7,0.389,21,
+4,116,72,12,87,22.1,0.463,37,
+4,158,78,0,0,32.9,0.803,31,
+2,127,58,24,275,27.7,1.6,25,
+3,96,56,34,115,24.7,0.944,39,
+0,131,66,40,0,34.3,0.196,22,
+3,82,70,0,0,21.1,0.389,25,
+3,193,70,31,0,34.9,0.241,25,
+4,95,64,0,0,32,0.161,31,
+6,137,61,0,0,24.2,0.151,55,
+5,136,84,41,88,35,0.286,35,
+9,72,78,25,0,31.6,0.28,38,
+5,168,64,0,0,32.9,0.135,41,
+2,123,48,32,165,42.1,0.52,26,
+4,115,72,0,0,28.9,0.376,46,
+0,101,62,0,0,21.9,0.336,25,
+8,197,74,0,0,25.9,1.191,39,
+1,172,68,49,579,42.4,0.702,28,
+6,102,90,39,0,35.7,0.674,28,
+1,112,72,30,176,34.4,0.528,25,
+1,143,84,23,310,42.4,1.076,22,
+1,143,74,22,61,26.2,0.256,21,
+0,138,60,35,167,34.6,0.534,21,
+3,173,84,33,474,35.7,0.258,22,
+1,97,68,21,0,27.2,1.095,22,
+4,144,82,32,0,38.5,0.554,37,
+1,83,68,0,0,18.2,0.624,27,
+3,129,64,29,115,26.4,0.219,28,
+1,119,88,41,170,45.3,0.507,26,
+2,94,68,18,76,26,0.561,21,
+0,102,64,46,78,40.6,0.496,21,
+2,115,64,22,0,30.8,0.421,21,
+8,151,78,32,210,42.9,0.516,36,
+4,184,78,39,277,37,0.264,31,
+0,94,0,0,0,0,0.256,25,
+1,181,64,30,180,34.1,0.328,38,
+0,135,94,46,145,40.6,0.284,26,
+1,95,82,25,180,35,0.233,43,
+2,99,0,0,0,22.2,0.108,23,
+3,89,74,16,85,30.4,0.551,38,
+1,80,74,11,60,30,0.527,22,
+2,139,75,0,0,25.6,0.167,29,
+1,90,68,8,0,24.5,1.138,36,
+0,141,0,0,0,42.4,0.205,29,
+12,140,85,33,0,37.4,0.244,41,
+5,147,75,0,0,29.9,0.434,28,
+1,97,70,15,0,18.2,0.147,21,
+6,107,88,0,0,36.8,0.727,31,
+0,189,104,25,0,34.3,0.435,41,
+2,83,66,23,50,32.2,0.497,22,
+4,117,64,27,120,33.2,0.23,24,
+8,108,70,0,0,30.5,0.955,33,
+4,117,62,12,0,29.7,0.38,30,
+0,180,78,63,14,59.4,2.42,25,
+1,100,72,12,70,25.3,0.658,28,
+0,95,80,45,92,36.5,0.33,26,
+0,104,64,37,64,33.6,0.51,22,
+0,120,74,18,63,30.5,0.285,26,
+1,82,64,13,95,21.2,0.415,23,
+2,134,70,0,0,28.9,0.542,23,
+0,91,68,32,210,39.9,0.381,25,
+2,119,0,0,0,19.6,0.832,72,
+2,100,54,28,105,37.8,0.498,24,
+14,175,62,30,0,33.6,0.212,38,
+1,135,54,0,0,26.7,0.687,62,
+5,86,68,28,71,30.2,0.364,24,
+10,148,84,48,237,37.6,1.001,51,
+9,134,74,33,60,25.9,0.46,81,
+9,120,72,22,56,20.8,0.733,48,
+1,71,62,0,0,21.8,0.416,26,
+8,74,70,40,49,35.3,0.705,39,
+5,88,78,30,0,27.6,0.258,37,
+10,115,98,0,0,24,1.022,34,
+0,124,56,13,105,21.8,0.452,21,
+0,74,52,10,36,27.8,0.269,22,
+0,97,64,36,100,36.8,0.6,25,
+8,120,0,0,0,30,0.183,38,
+6,154,78,41,140,46.1,0.571,27,
+1,144,82,40,0,41.3,0.607,28,
+0,137,70,38,0,33.2,0.17,22,
+0,119,66,27,0,38.8,0.259,22,
+7,136,90,0,0,29.9,0.21,50,
+4,114,64,0,0,28.9,0.126,24,
+0,137,84,27,0,27.3,0.231,59,
+2,105,80,45,191,33.7,0.711,29,
+7,114,76,17,110,23.8,0.466,31,
+8,126,74,38,75,25.9,0.162,39,
+4,132,86,31,0,28,0.419,63,
+3,158,70,30,328,35.5,0.344,35,
+0,123,88,37,0,35.2,0.197,29,
+4,85,58,22,49,27.8,0.306,28,
+0,84,82,31,125,38.2,0.233,23,
+0,145,0,0,0,44.2,0.63,31,
+0,135,68,42,250,42.3,0.365,24,
+1,139,62,41,480,40.7,0.536,21,
+0,173,78,32,265,46.5,1.159,58,
+4,99,72,17,0,25.6,0.294,28,
+8,194,80,0,0,26.1,0.551,67,
+2,83,65,28,66,36.8,0.629,24,
+2,89,90,30,0,33.5,0.292,42,
+4,99,68,38,0,32.8,0.145,33,
+4,125,70,18,122,28.9,1.144,45,
+3,80,0,0,0,0,0.174,22,
+6,166,74,0,0,26.6,0.304,66,
+5,110,68,0,0,26,0.292,30,
+2,81,72,15,76,30.1,0.547,25,
+7,195,70,33,145,25.1,0.163,55,
+6,154,74,32,193,29.3,0.839,39,
+2,117,90,19,71,25.2,0.313,21,
+3,84,72,32,0,37.2,0.267,28,
+6,0,68,41,0,39,0.727,41,
+7,94,64,25,79,33.3,0.738,41,
+3,96,78,39,0,37.3,0.238,40,
+10,75,82,0,0,33.3,0.263,38,
+0,180,90,26,90,36.5,0.314,35,
+1,130,60,23,170,28.6,0.692,21,
+2,84,50,23,76,30.4,0.968,21,
+8,120,78,0,0,25,0.409,64,
+12,84,72,31,0,29.7,0.297,46,
+0,139,62,17,210,22.1,0.207,21,
+9,91,68,0,0,24.2,0.2,58,
+2,91,62,0,0,27.3,0.525,22,
+3,99,54,19,86,25.6,0.154,24,
+3,163,70,18,105,31.6,0.268,28,
+9,145,88,34,165,30.3,0.771,53,
+7,125,86,0,0,37.6,0.304,51,
+13,76,60,0,0,32.8,0.18,41,
+6,129,90,7,326,19.6,0.582,60,
+2,68,70,32,66,25,0.187,25,
+3,124,80,33,130,33.2,0.305,26,
+6,114,0,0,0,0,0.189,26,
+9,130,70,0,0,34.2,0.652,45,
+3,125,58,0,0,31.6,0.151,24,
+3,87,60,18,0,21.8,0.444,21,
+1,97,64,19,82,18.2,0.299,21,
+3,116,74,15,105,26.3,0.107,24,
+0,117,66,31,188,30.8,0.493,22,
+0,111,65,0,0,24.6,0.66,31,
+2,122,60,18,106,29.8,0.717,22,
+0,107,76,0,0,45.3,0.686,24,
+1,86,66,52,65,41.3,0.917,29,
+6,91,0,0,0,29.8,0.501,31,
+1,77,56,30,56,33.3,1.251,24,
+4,132,0,0,0,32.9,0.302,23,
+0,105,90,0,0,29.6,0.197,46,
+0,57,60,0,0,21.7,0.735,67,
+0,127,80,37,210,36.3,0.804,23,
+3,129,92,49,155,36.4,0.968,32,
+8,100,74,40,215,39.4,0.661,43,
+3,128,72,25,190,32.4,0.549,27,
+10,90,85,32,0,34.9,0.825,56,
+4,84,90,23,56,39.5,0.159,25,
+1,88,78,29,76,32,0.365,29,
+8,186,90,35,225,34.5,0.423,37,
+5,187,76,27,207,43.6,1.034,53,
+4,131,68,21,166,33.1,0.16,28,
+1,164,82,43,67,32.8,0.341,50,
+4,189,110,31,0,28.5,0.68,37,
+1,116,70,28,0,27.4,0.204,21,
+3,84,68,30,106,31.9,0.591,25,
+6,114,88,0,0,27.8,0.247,66,
+1,88,62,24,44,29.9,0.422,23,
+1,84,64,23,115,36.9,0.471,28,
+7,124,70,33,215,25.5,0.161,37,
+1,97,70,40,0,38.1,0.218,30,
+8,110,76,0,0,27.8,0.237,58,
+11,103,68,40,0,46.2,0.126,42,
+11,85,74,0,0,30.1,0.3,35,
+6,125,76,0,0,33.8,0.121,54,
+0,198,66,32,274,41.3,0.502,28,
+1,87,68,34,77,37.6,0.401,24,
+6,99,60,19,54,26.9,0.497,32,
+0,91,80,0,0,32.4,0.601,27,
+2,95,54,14,88,26.1,0.748,22,
+1,99,72,30,18,38.6,0.412,21,
+6,92,62,32,126,32,0.085,46,
+4,154,72,29,126,31.3,0.338,37,
+0,121,66,30,165,34.3,0.203,33,
+3,78,70,0,0,32.5,0.27,39,
+2,130,96,0,0,22.6,0.268,21,
+3,111,58,31,44,29.5,0.43,22,
+2,98,60,17,120,34.7,0.198,22,
+1,143,86,30,330,30.1,0.892,23,
+1,119,44,47,63,35.5,0.28,25,
+6,108,44,20,130,24,0.813,35,
+2,118,80,0,0,42.9,0.693,21,
+10,133,68,0,0,27,0.245,36,
+2,197,70,99,0,34.7,0.575,62,
+0,151,90,46,0,42.1,0.371,21,
+6,109,60,27,0,25,0.206,27,
+12,121,78,17,0,26.5,0.259,62,
+8,100,76,0,0,38.7,0.19,42,
+8,124,76,24,600,28.7,0.687,52,
+1,93,56,11,0,22.5,0.417,22,
+8,143,66,0,0,34.9,0.129,41,
+6,103,66,0,0,24.3,0.249,29,
+3,176,86,27,156,33.3,1.154,52,
+0,73,0,0,0,21.1,0.342,25,
+11,111,84,40,0,46.8,0.925,45,
+2,112,78,50,140,39.4,0.175,24,
+3,132,80,0,0,34.4,0.402,44,
+2,82,52,22,115,28.5,1.699,25,
+6,123,72,45,230,33.6,0.733,34,
+0,188,82,14,185,32,0.682,22,
+0,67,76,0,0,45.3,0.194,46,
+1,89,24,19,25,27.8,0.559,21,
+1,173,74,0,0,36.8,0.088,38,
+1,109,38,18,120,23.1,0.407,26,
+1,108,88,19,0,27.1,0.4,24,
+6,96,0,0,0,23.7,0.19,28,
+1,124,74,36,0,27.8,0.1,30,
+7,150,78,29,126,35.2,0.692,54,
+4,183,0,0,0,28.4,0.212,36,
+1,124,60,32,0,35.8,0.514,21,
+1,181,78,42,293,40,1.258,22,
+1,92,62,25,41,19.5,0.482,25,
+0,152,82,39,272,41.5,0.27,27,
+1,111,62,13,182,24,0.138,23,
+3,106,54,21,158,30.9,0.292,24,
+3,174,58,22,194,32.9,0.593,36,
+7,168,88,42,321,38.2,0.787,40,
+6,105,80,28,0,32.5,0.878,26,
+11,138,74,26,144,36.1,0.557,50,
+3,106,72,0,0,25.8,0.207,27,
+6,117,96,0,0,28.7,0.157,30,
+2,68,62,13,15,20.1,0.257,23,
+9,112,82,24,0,28.2,1.282,50,
+0,119,0,0,0,32.4,0.141,24,
+2,112,86,42,160,38.4,0.246,28,
+2,92,76,20,0,24.2,1.698,28,
+6,183,94,0,0,40.8,1.461,45,
+0,94,70,27,115,43.5,0.347,21,
+2,108,64,0,0,30.8,0.158,21,
+4,90,88,47,54,37.7,0.362,29,
+0,125,68,0,0,24.7,0.206,21,
+0,132,78,0,0,32.4,0.393,21,
+5,128,80,0,0,34.6,0.144,45,
+4,94,65,22,0,24.7,0.148,21,
+7,114,64,0,0,27.4,0.732,34,
+0,102,78,40,90,34.5,0.238,24,
+2,111,60,0,0,26.2,0.343,23,
+1,128,82,17,183,27.5,0.115,22,
+10,92,62,0,0,25.9,0.167,31,
+13,104,72,0,0,31.2,0.465,38,
+5,104,74,0,0,28.8,0.153,48,
+2,94,76,18,66,31.6,0.649,23,
+7,97,76,32,91,40.9,0.871,32,
+1,100,74,12,46,19.5,0.149,28,
+0,102,86,17,105,29.3,0.695,27,
+4,128,70,0,0,34.3,0.303,24,
+6,147,80,0,0,29.5,0.178,50,
+4,90,0,0,0,28,0.61,31,
+3,103,72,30,152,27.6,0.73,27,
+2,157,74,35,440,39.4,0.134,30,
+1,167,74,17,144,23.4,0.447,33,
+0,179,50,36,159,37.8,0.455,22,
+11,136,84,35,130,28.3,0.26,42,
+0,107,60,25,0,26.4,0.133,23,
+1,91,54,25,100,25.2,0.234,23,
+1,117,60,23,106,33.8,0.466,27,
+5,123,74,40,77,34.1,0.269,28,
+2,120,54,0,0,26.8,0.455,27,
+1,106,70,28,135,34.2,0.142,22,
+2,155,52,27,540,38.7,0.24,25,
+2,101,58,35,90,21.8,0.155,22,
+1,120,80,48,200,38.9,1.162,41,
+11,127,106,0,0,39,0.19,51,
+3,80,82,31,70,34.2,1.292,27,
+10,162,84,0,0,27.7,0.182,54,
+1,199,76,43,0,42.9,1.394,22,
+8,167,106,46,231,37.6,0.165,43,
+9,145,80,46,130,37.9,0.637,40,
+6,115,60,39,0,33.7,0.245,40,
+1,112,80,45,132,34.8,0.217,24,
+4,145,82,18,0,32.5,0.235,70,
+10,111,70,27,0,27.5,0.141,40,
+6,98,58,33,190,34,0.43,43,
+9,154,78,30,100,30.9,0.164,45,
+6,165,68,26,168,33.6,0.631,49,
+1,99,58,10,0,25.4,0.551,21,
+10,68,106,23,49,35.5,0.285,47,
+3,123,100,35,240,57.3,0.88,22,
+8,91,82,0,0,35.6,0.587,68,
+6,195,70,0,0,30.9,0.328,31,
+9,156,86,0,0,24.8,0.23,53,
+0,93,60,0,0,35.3,0.263,25,
+3,121,52,0,0,36,0.127,25,
+2,101,58,17,265,24.2,0.614,23,
+2,56,56,28,45,24.2,0.332,22,
+0,162,76,36,0,49.6,0.364,26,
+0,95,64,39,105,44.6,0.366,22,
+4,125,80,0,0,32.3,0.536,27,
+5,136,82,0,0,0,0.64,69,
+2,129,74,26,205,33.2,0.591,25,
+3,130,64,0,0,23.1,0.314,22,
+1,107,50,19,0,28.3,0.181,29,
+1,140,74,26,180,24.1,0.828,23,
+1,144,82,46,180,46.1,0.335,46,
+8,107,80,0,0,24.6,0.856,34,
+13,158,114,0,0,42.3,0.257,44,
+2,121,70,32,95,39.1,0.886,23,
+7,129,68,49,125,38.5,0.439,43,
+2,90,60,0,0,23.5,0.191,25,
+7,142,90,24,480,30.4,0.128,43,
+3,169,74,19,125,29.9,0.268,31,
+0,99,0,0,0,25,0.253,22,
+4,127,88,11,155,34.5,0.598,28,
+4,118,70,0,0,44.5,0.904,26,
+2,122,76,27,200,35.9,0.483,26,
+6,125,78,31,0,27.6,0.565,49,
+1,168,88,29,0,35,0.905,52,
+2,129,0,0,0,38.5,0.304,41,
+4,110,76,20,100,28.4,0.118,27,
+6,80,80,36,0,39.8,0.177,28,
+10,115,0,0,0,0,0.261,30,
+2,127,46,21,335,34.4,0.176,22,
+9,164,78,0,0,32.8,0.148,45,
+2,93,64,32,160,38,0.674,23,
+3,158,64,13,387,31.2,0.295,24,
+5,126,78,27,22,29.6,0.439,40,
+10,129,62,36,0,41.2,0.441,38,
+0,134,58,20,291,26.4,0.352,21,
+3,102,74,0,0,29.5,0.121,32,
+7,187,50,33,392,33.9,0.826,34,
+3,173,78,39,185,33.8,0.97,31,
+10,94,72,18,0,23.1,0.595,56,
+1,108,60,46,178,35.5,0.415,24,
+5,97,76,27,0,35.6,0.378,52,
+4,83,86,19,0,29.3,0.317,34,
+1,114,66,36,200,38.1,0.289,21,
+1,149,68,29,127,29.3,0.349,42,
+5,117,86,30,105,39.1,0.251,42,
+1,111,94,0,0,32.8,0.265,45,
+4,112,78,40,0,39.4,0.236,38,
+1,116,78,29,180,36.1,0.496,25,
+0,141,84,26,0,32.4,0.433,22,
+2,175,88,0,0,22.9,0.326,22,
+2,92,52,0,0,30.1,0.141,22,
+3,130,78,23,79,28.4,0.323,34,
+8,120,86,0,0,28.4,0.259,22,
+2,174,88,37,120,44.5,0.646,24,
+2,106,56,27,165,29,0.426,22,
+2,105,75,0,0,23.3,0.56,53,
+4,95,60,32,0,35.4,0.284,28,
+0,126,86,27,120,27.4,0.515,21,
+8,65,72,23,0,32,0.6,42,
+2,99,60,17,160,36.6,0.453,21,
+1,102,74,0,0,39.5,0.293,42,
+11,120,80,37,150,42.3,0.785,48,
+3,102,44,20,94,30.8,0.4,26,
+1,109,58,18,116,28.5,0.219,22,
+9,140,94,0,0,32.7,0.734,45,
+13,153,88,37,140,40.6,1.174,39,
+12,100,84,33,105,30,0.488,46,
+1,147,94,41,0,49.3,0.358,27,
+1,81,74,41,57,46.3,1.096,32,
+3,187,70,22,200,36.4,0.408,36,
+6,162,62,0,0,24.3,0.178,50,
+4,136,70,0,0,31.2,1.182,22,
+1,121,78,39,74,39,0.261,28,
+3,108,62,24,0,26,0.223,25,
+0,181,88,44,510,43.3,0.222,26,
+8,154,78,32,0,32.4,0.443,45,
+1,128,88,39,110,36.5,1.057,37,
+7,137,90,41,0,32,0.391,39,
+0,123,72,0,0,36.3,0.258,52,
+1,106,76,0,0,37.5,0.197,26,
+6,190,92,0,0,35.5,0.278,66,
+2,88,58,26,16,28.4,0.766,22,
+9,170,74,31,0,44,0.403,43,
+9,89,62,0,0,22.5,0.142,33,
+10,101,76,48,180,32.9,0.171,63,
+2,122,70,27,0,36.8,0.34,27,
+5,121,72,23,112,26.2,0.245,30,
+1,126,60,0,0,30.1,0.349,47,
+1,93,70,31,0,30.4,0.315,23
+
+};
+#endif
diff --git a/test/classifier/data/pina_indians_diabetes_labels.hxx b/test/classifier/data/pina_indians_diabetes_labels.hxx
new file mode 100644
index 0000000..55d7ddb
--- /dev/null
+++ b/test/classifier/data/pina_indians_diabetes_labels.hxx
@@ -0,0 +1,777 @@
+#ifndef PINA_INDIANS_DIABETES_LABELS
+#define PINA_INDIANS_DIABETES_LABELS
+int pina_indians_diabetes_labels[] = {
+1,
+0,
+1,
+0,
+1,
+0,
+1,
+0,
+1,
+1,
+0,
+1,
+0,
+1,
+1,
+1,
+1,
+1,
+0,
+1,
+0,
+0,
+1,
+1,
+1,
+1,
+1,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+1,
+0,
+0,
+0,
+1,
+0,
+1,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+1,
+0,
+0,
+0,
+1,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+1,
+0,
+0,
+1,
+1,
+1,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+1,
+0,
+0,
+1,
+1,
+1,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+1,
+1,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+1,
+0,
+1,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+1,
+1,
+1,
+0,
+0,
+1,
+1,
+0,
+1,
+0,
+1,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+1,
+0,
+0,
+0,
+1,
+1,
+1,
+1,
+0,
+1,
+1,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+1,
+1,
+1,
+1,
+0,
+0,
+0,
+1,
+1,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+1,
+0,
+1,
+0,
+0,
+1,
+0,
+1,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+0,
+0,
+1,
+1,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+1,
+1,
+0,
+0,
+1,
+0,
+1,
+0,
+1,
+1,
+0,
+1,
+0,
+0,
+1,
+0,
+1,
+1,
+0,
+0,
+1,
+0,
+1,
+0,
+0,
+1,
+0,
+1,
+0,
+1,
+1,
+1,
+0,
+0,
+1,
+0,
+1,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+1,
+0,
+1,
+1,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+1,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+1,
+1,
+0,
+1,
+0,
+1,
+0,
+1,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+1,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+1,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+1,
+1,
+1,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+1,
+1,
+1,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+1,
+1,
+0,
+0,
+0,
+1,
+0,
+1,
+0,
+1,
+0,
+1,
+0,
+1,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+1,
+0,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+0,
+0,
+1,
+0,
+1,
+1,
+1,
+1,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+1,
+0,
+0,
+1,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+1,
+0,
+1,
+0,
+1,
+0,
+1,
+1,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+0,
+0,
+1,
+0,
+1,
+1,
+0,
+0,
+1,
+0,
+0,
+1,
+1,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+1,
+0,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+0,
+0,
+1,
+0,
+0,
+1,
+0,
+1,
+1,
+1,
+0,
+0,
+1,
+1,
+1,
+0,
+1,
+0,
+1,
+0,
+1,
+0,
+0,
+0,
+0,
+1,
+0
+
+};
+
+int pina_indians_diabetes_Classes[] = {0, 1};
+int pina_indians_diabetes_size = 2;
+#endif
diff --git a/test/classifier/data/segmentation_features.hxx b/test/classifier/data/segmentation_features.hxx
new file mode 100644
index 0000000..f19a845
--- /dev/null
+++ b/test/classifier/data/segmentation_features.hxx
@@ -0,0 +1,215 @@
+#ifndef SEGMENTATION_FEATURES
+#define SEGMENTATION_FEATURES
+double segmentation_features[] = {
+140,125,9,0,0,0.27778,0.062963,0.66667,0.31111,6.1852,7.3333,7.6667,3.5556,3.4444,4.4444,-7.8889,7.7778,0.54563,-1.1218,
+188,133,9,0,0,0.33333,0.26667,0.5,0.077778,6.6667,8.3333,7.7778,3.8889,5,3.3333,-8.3333,8.4444,0.53858,-0.92482,
+105,139,9,0,0,0.27778,0.10741,0.83333,0.52222,6.1111,7.5556,7.2222,3.5556,4.3333,3.3333,-7.6667,7.5556,0.53263,-0.96595,
+34,137,9,0,0,0.5,0.16667,1.1111,0.47407,5.8519,7.7778,6.4444,3.3333,5.7778,1.7778,-7.5556,7.7778,0.57363,-0.74427,
+39,111,9,0,0,0.72222,0.37407,0.88889,0.42963,6.037,7,7.6667,3.4444,2.8889,4.8889,-7.7778,7.8889,0.56292,-1.1758,
+16,128,9,0,0,0.5,0.077778,0.66667,0.31111,5.5556,6.8889,6.6667,3.1111,4,3.3333,-7.3333,7.1111,0.56151,-0.98581,
+26,67,9,0.11111,0,1,0.88889,2.4444,3.1852,20,19.556,25.889,14.556,-1.3333,17.667,-16.333,25.889,0.43694,-1.6232,
+14,110,9,0,0,1.7222,5.3519,2.6667,1.0222,17.926,18.889,21.444,13.444,2.8889,10.556,-13.444,21.444,0.36885,-1.3451,
+11,108,9,0,0,1.3333,0.8,1.3889,0.95185,17.667,19,21.111,12.889,4,10.333,-14.333,21.111,0.38876,-1.3021,
+85,101,9,0,0,1.3333,1.2889,1.2778,1.2185,21.296,21.222,26.778,15.889,-0.22222,16.444,-16.222,26.778,0.40479,-1.5586,
+18,145,9,0,0,0.38889,0.018518,0.61111,0.37407,3.9259,5.5556,4,2.2222,4.8889,0.22222,-5.1111,5.5556,0.60053,-0.57094,
+23,55,9,0,0,2.2222,3.6741,1.7778,0.78519,23.444,21.667,31.111,17.556,-5.3333,23,-17.667,31.111,0.43507,-1.7712,
+196,129,9,0,0,0.83333,0.43333,0.66667,0.17778,6.3333,7.8889,7.3333,3.7778,4.6667,3,-7.6667,8.2222,0.54012,-0.93278,
+80,116,9,0,0,1.5,1.6333,1.5556,0.87407,21.704,21.222,27.556,16.333,-1.4444,17.556,-16.111,27.556,0.40736,-1.6322,
+2,44,9,0,0,2.1667,2.3889,2.3889,1.5296,18.741,17.333,25.222,13.667,-4.2222,19.444,-15.222,25.222,0.45768,-1.7537,
+120,136,9,0,0,0.61111,0.41852,1,0.44444,6.2593,7.7778,7.2222,3.7778,4.5556,2.8889,-7.4444,8,0.52954,-0.92461,
+146,124,9,0,0,0.5,0.16667,0.38889,0.10741,6.037,7.4444,7.3333,3.3333,4.2222,3.8889,-8.1111,7.6667,0.56349,-1.0247,
+23,85,9,0,0,1.4444,1.0519,1.7778,0.96296,17.963,18.889,21.889,13.111,2.7778,11.778,-14.556,21.889,0.39975,-1.3869,
+138,116,9,0,0,0.61111,0.15185,0.44444,0.20741,6.4815,7.5556,8.2222,3.6667,3.2222,5.2222,-8.4444,8.3333,0.55917,-1.1911,
+229,124,9,0,0,0.88889,0.074074,0.88889,0.34074,5.8889,7.1111,7.1111,3.4444,3.6667,3.6667,-7.3333,7.5556,0.54586,-1.0377,
+22,116,9,0,0,0.38889,0.10741,0.33333,0.13333,5.6296,6.7778,7,3.1111,3.4444,4.1111,-7.5556,7.3333,0.5754,-1.0996,
+121,60,9,0,0,2.2778,2.3296,2.8889,2.8741,26.741,24.667,35.222,20.333,-6.2222,25.444,-19.222,35.222,0.4223,-1.7761,
+33,149,9,0,0,0.55556,0.25185,0.72222,0.15185,5.4444,4.1111,8.6667,3.5556,-4,9.6667,-5.6667,8.6667,0.57834,-1.9857,
+80,95,9,0,0,1.2222,1.0074,0.94444,0.55185,21.407,21.333,26.667,16.222,-0.22222,15.778,-15.556,26.667,0.39044,-1.5673,
+96,84,9,0,0,1.5,1.2778,1.6111,2.2852,23.852,23.556,30,18,-0.88889,18.444,-17.556,30,0.39879,-1.5989,
+145,102,9,0,0,0.88889,0.60741,2.6111,1.4852,23.074,22.111,29.778,17.333,-2.8889,20.111,-17.222,29.778,0.41776,-1.6854,
+18,138,9,0,0,0.88889,0.56296,0.83333,0.3,5.7407,7.3333,6.5556,3.3333,4.7778,2.4444,-7.2222,7.3333,0.54387,-0.86211,
+138,133,9,0,0,0.66667,0.44444,1.1667,0.21111,6.4444,7.7778,7.8889,3.6667,4,4.3333,-8.3333,8.2222,0.5582,-1.0777,
+121,113,9,0,0,1.7222,1.5296,2.9444,1.5296,20.259,20,25.444,15.333,-0.77778,15.556,-14.778,25.444,0.39659,-1.5856,
+95,57,9,0,0,1.8333,3.4111,2.1111,1.7185,26.296,24.667,34.444,19.778,-4.8889,24.444,-19.556,34.444,0.42569,-1.739,
+140,25,9,0,0,1,1.4667,1.1111,0.11852,128,117.78,142.33,123.89,-30.667,43,-12.333,142.33,0.1725,-2.3546,
+142,33,9,0,0,0.5,0.62361,0.5,0.3496,110.59,96.778,128.67,106.33,-41.444,54.222,-12.778,128.67,0.24778,-2.408,
+66,41,9,0,0,0.61111,0.32773,0.38889,0.32773,109.7,95.111,128.89,105.11,-43.778,57.556,-13.778,128.89,0.26205,-2.4047,
+165,99,9,0,0,0.88889,0.47407,0.77778,0.47407,93.407,79,118,83.222,-43.222,73.778,-30.556,118,0.33042,-2.2078,
+228,20,9,0,0,1.0556,0.49066,0.83333,0.75277,125,114,140.56,120.44,-33,46.667,-13.667,140.56,0.18889,-2.348,
+124,29,9,0,0,1,0.71111,1.0556,0.90742,128.44,119.22,142.89,123.22,-27.667,43.333,-15.667,142.89,0.16562,-2.2711,
+156,32,9,0,0,0.77777,0.16296,2.6111,1.0407,136.3,129.78,146.33,132.78,-19.556,30.111,-10.556,146.33,0.11306,-2.2808,
+21,90,9,0,0,0.66667,0.044444,0.77778,0.56296,113.48,105.89,128.56,106,-22.778,45.222,-22.444,128.56,0.1797,-2.0978,
+8,39,9,0.11111,0,1.3889,1.1296,1.8333,0.7,113.37,102.56,132,105.56,-32.444,55.889,-23.444,132,0.22295,-2.1982,
+122,11,9,0,0,1,0.31112,2.8889,5.0519,143.44,136.89,150.89,142.56,-19.667,22.333,-2.6667,150.89,0.092773,-2.5216,
+44,79,9,0,0,0.44444,0.34426,0.77778,0.40369,107.74,93.889,126.56,102.78,-41.556,56.444,-14.889,126.56,0.25808,-2.378,
+7,18,9,0,0,1.2778,0.72963,0.94445,0.37408,138.63,133.33,147.56,135,-15.889,26.778,-10.889,147.56,0.096352,-2.2146,
+188,42,9,0,0,0.77778,0.54433,1.6667,1.2649,108.93,95.667,126.22,104.89,-39.778,51.889,-12.111,126.22,0.24193,-2.4104,
+152,18,9,0,0,0.77778,0.45542,0.55556,0.27216,112.11,97.222,130.44,108.67,-44.667,55,-10.333,130.44,0.25467,-2.455,
+120,74,9,0,0,0.33333,0.088889,0.5,0.077778,101.85,89.111,123.22,93.222,-38.222,64.111,-25.889,123.22,0.27678,-2.2206,
+143,24,9,0,0,1.2778,0.90741,0.88889,1.1407,127.63,117.67,141.67,123.56,-29.889,42.111,-12.222,141.67,0.1694,-2.3493,
+181,27,9,0,0,0.72222,0.46296,0.5,0.25555,138.07,132.56,146.56,135.11,-16.556,25.444,-8.8889,146.56,0.096263,-2.2645,
+107,21,9,0,0,0.66666,0.5164,1.1667,0.40825,126.78,115.78,141.89,122.67,-33,45.333,-12.333,141.89,0.18402,-2.3704,
+226,83,9,0,0,0.88889,0.51852,1.0556,0.50741,90.63,74.556,116.89,80.444,-48.222,78.778,-30.556,116.89,0.36206,-2.2391,
+93,29,9,0,0,1.2222,1.2296,1.3889,1.5741,128.48,119,142.78,123.67,-28.444,42.889,-14.444,142.78,0.16648,-2.2978,
+60,52,9,0,0,0.72222,0.5963,0.77778,0.74074,111.63,101,129.22,104.67,-31.889,52.778,-20.889,129.22,0.21838,-2.2297,
+179,101,9,0,0,0.44445,0.38519,0.61111,0.32963,134.93,126.44,147.22,131.11,-25.444,36.889,-11.444,147.22,0.14111,-2.3287,
+112,30,9,0,0,0.55556,0.27216,1.2222,0.72008,113.26,100.78,130.11,108.89,-37.444,50.556,-13.111,130.11,0.22538,-2.3853,
+103,64,9,0,0,0.66667,0.69921,1.3333,0.91894,108.78,96.333,126.22,103.78,-37.333,52.333,-15,126.22,0.2368,-2.3554,
+174,50,9,0,0,1,0.76012,0.94445,0.95258,107.44,94.667,125.78,101.89,-38.333,55,-16.667,125.78,0.24734,-2.3373,
+80,40,9,0,0,0.61111,0.57413,0.72222,0.7722,110.7,96.222,129,106.89,-43.444,54.889,-11.444,129,0.25405,-2.4347,
+67,71,9,0,0,1.6667,0.88889,1.5,0.3,125.96,115.56,140.89,121.44,-31.222,44.778,-13.556,140.89,0.17967,-2.3398,
+92,56,9,0,0,0.44444,0.029629,0.83333,0.56667,126,115.89,140.67,121.44,-30.333,44,-13.667,140.67,0.17606,-2.3268,
+67,32,9,0,0,0.94444,1.0628,1.7778,1.3109,126.22,115.11,142.22,121.33,-33.333,48,-14.667,142.22,0.19063,-2.3337,
+125,46,9,0.11111,0,0.61111,0.61162,2.1667,0.78174,124.56,112.78,141,119.89,-35.333,49.333,-14,141,0.20012,-2.3577,
+101,121,9,0.11111,0,0.66667,0.84327,1.5,0.88819,3.4074,1.1111,6,3.1111,-6.8889,7.7778,-0.88889,6,0.84352,-2.5192,
+21,122,9,0,0,0.44444,0.40369,0.44444,0.40369,0.55556,0,1.2222,0.44444,-1.6667,2,-0.33333,1.2222,0.55556,-2.4446,
+45,89,9,0,0,0.77778,0.34074,0.77778,0.47407,2.2963,0.11111,6.4444,0.33333,-6.5556,12.444,-5.8889,6.4444,0.98611,-2.1239,
+18,87,9,0,0,1.5556,1.9626,1.8889,1.747,2.9259,1.2222,5.6667,1.8889,-5.1111,8.2222,-3.1111,5.6667,0.86277,-2.2295,
+52,102,9,0,0,0.72222,0.50741,0.83333,0.56667,2.8889,0.66667,6.3333,1.6667,-6.6667,10.333,-3.6667,6.3333,0.89974,-2.2617,
+54,91,9,0,0,1.4444,1.5407,0.83333,0.25556,3.2593,0.55556,8,1.2222,-8.1111,14.222,-6.1111,8,0.94481,-2.1867,
+80,87,9,0,0.11111,24.389,573,44.722,1386.3,67.444,58.778,79,64.556,-26,34.667,-8.6667,79,0.30628,-2.4221,
+140,124,9,0,0,1,0.44444,1.1111,1.0519,2.5185,0.22222,6.1111,1.2222,-6.8889,10.778,-3.8889,6.1111,0.97377,-2.2675,
+69,139,9,0,0,2.8333,1.7733,2.1111,1.6689,18.074,16,22.556,15.667,-6.2222,13.444,-7.2222,23.889,0.38661,-1.7028,
+9,80,9,0,0,2.9444,13.752,16.667,71.511,23.63,17.333,31.667,21.889,-18.889,24.111,-5.2222,31.667,0.51425,-2.4315,
+6,81,9,0,0.11111,4.1111,8.7407,5.7222,28.507,12.481,7.6667,18.889,10.889,-14.444,19.222,-4.7778,18.889,0.62816,-2.3886,
+74,129,9,0,0,0.22222,0.02963,0.11111,0.02963,0.51852,0,1.5556,0,-1.5556,3.1111,-1.5556,1.5556,1,-2.0944,
+41,75,9,0,0.11111,15.389,19.136,26.611,31.714,55,47.444,65.444,52.111,-22.667,31.333,-8.6667,65.444,0.2978,-2.3568,
+36,145,9,0,0,0.27778,0.1963,1.2778,2.063,0.85185,0.33333,1.4444,0.77778,-1.5556,1.7778,-0.22222,1.4444,0.25185,-2.531,
+94,144,9,0,0,0.44444,0.11852,0.5,0.16667,1.1481,0,3.4444,0,-3.4444,6.8889,-3.4444,3.4444,1,-2.0944,
+18,90,9,0,0,1.0556,0.37407,0.66667,0.22222,2.8148,0.55556,6.8889,1,-6.7778,12.222,-5.4444,6.8889,0.92615,-2.1643,
+68,103,9,0,0,0.66667,0.57778,1.1111,0.96296,2.1481,0.11111,5.6667,0.66667,-6.1111,10.556,-4.4444,5.6667,0.98765,-2.1855,
+45,108,9,0,0.11111,25.5,12.795,27.278,15.931,49.815,41.778,61.111,46.556,-24.111,33.889,-9.7778,61.111,0.35898,-2.3605,
+59,99,9,0,0,0.77778,0.82963,1,0.35556,2.037,0.11111,5.5556,0.44444,-5.7778,10.556,-4.7778,5.5556,0.98611,-2.1497,
+67,136,9,0,0,6.7222,3.7083,2.6667,3.1972,15.519,9,25.333,12.222,-19.556,29.444,-9.8889,25.333,0.66081,-2.3075,
+226,110,9,0,0,0.33333,0.088889,0.5,0.21111,1.6667,0.11111,4.4444,0.44444,-4.6667,8.3333,-3.6667,4.4444,0.97778,-2.156,
+231,124,9,0,0,3.4444,14.963,1.8333,6.4333,3,1.4444,5.8889,1.6667,-4.6667,8.6667,-4,5.8889,0.89537,-2.1189,
+103,125,9,0,0,0.94444,0.82776,0.83333,0.69121,1.7778,0.44444,3.8889,1,-4,6.3333,-2.3333,3.8889,0.92381,-2.2376,
+1,81,9,0,0,12.167,267.46,9.2222,205.36,21.333,14,30.556,19.444,-22,27.667,-5.6667,30.556,0.59528,-2.4384,
+230,124,9,0,0,0.27778,0.10741,0.27778,0.15185,0.66667,0,2,0,-2,4,-2,2,1,-2.0944,
+58,109,9,0,0,0.88889,0.25185,2.8333,1.6778,4.2963,1.4444,8.4444,3,-8.5556,12.444,-3.8889,8.4444,0.86448,-2.2838,
+59,120,9,0,0,2.1667,1.9861,1.4444,1.8698,19.074,10.556,33.111,13.556,-25.556,42.111,-16.556,33.111,0.68127,-2.2313,
+140,125,9,0,0,0.66667,0.22222,2.6667,3.7778,3.9259,1.5556,7.7778,2.4444,-7.1111,11.556,-4.4444,7.7778,0.8532,-2.2342,
+127,143,9,0,0,1.5,0.12222,0.88889,0.60741,4.1852,0.88889,9.4444,2.2222,-9.8889,15.778,-5.8889,9.4444,0.91538,-2.2574,
+23,129,9,0,0,0.5,0.077778,0.38889,0.15185,0.51852,0,1.5556,0,-1.5556,3.1111,-1.5556,1.5556,0.77778,-2.0944,
+191,119,9,0,0,1.1111,1.2939,0.94445,0.7722,39.852,36.222,48.222,35.111,-10.889,25.111,-14.222,48.222,0.27172,-2.006,
+219,80,9,0,0,1.2778,0.32963,0.66667,0.93333,39.704,36.333,48.222,34.556,-10.111,25.556,-15.444,48.222,0.28296,-1.9626,
+136,45,9,0,0,1.2222,1.5444,2.0556,1.5263,53.074,48.111,63.778,47.333,-14.889,32.111,-17.222,63.778,0.25937,-2.0459,
+66,160,9,0,0,3,4.0444,2.7778,0.42963,22.852,18.222,31.556,18.778,-13.889,26.111,-12.222,31.556,0.42601,-2.1387,
+190,105,9,0,0,1.8889,2.2963,2.1667,1.6778,45.741,41.222,56.333,39.667,-13.556,31.778,-18.222,56.333,0.29599,-1.9961,
+37,78,9,0,0,1,0.17778,2.5556,2.8741,43.815,41.111,51.889,38.444,-8.1111,24.222,-16.111,51.889,0.25892,-1.8861,
+198,127,9,0,0,2.4444,4.3852,8.5556,59.541,40.741,38,48.222,36,-8.2222,22.444,-14.222,48.222,0.249,-1.9083,
+191,101,9,0,0,1.1111,0.77936,1.1111,1.1863,45.037,39,57.111,39,-18.111,36.222,-18.111,57.111,0.32273,-2.0943,
+243,120,9,0,0,4.4444,4.3597,1.5556,1.8338,47.852,44.778,56.333,42.444,-9.2222,25.444,-16.222,56.333,0.24532,-1.9107,
+230,117,9,0,0,3.2778,0.92896,1.4444,0.86066,39.037,33.556,49.778,33.778,-16.444,32.222,-15.778,49.778,0.33503,-2.1062,
+151,89,9,0,0,8.3889,4.5773,0.72222,0.38968,31.704,27.333,41,26.778,-13.111,27.889,-14.778,41,0.35127,-2.0465,
+176,100,9,0,0,1.9444,0.77407,1.4444,0.65185,55.37,50.333,66.889,48.889,-15.111,34.556,-19.444,66.889,0.26862,-2.0062,
+118,126,9,0,0,0.66667,0.4,1.8333,2.1222,20.556,16.111,28.667,16.889,-13.333,24.333,-11,28.667,0.43708,-2.1588,
+42,57,9,0,0,1.3889,0.97563,1,0.36515,65.704,59.444,79.444,58.222,-18.778,41.222,-22.444,79.444,0.26678,-2.0307,
+217,148,9,0,0,2.0556,2.5519,1.0556,0.50741,29.074,21.444,41.556,24.222,-22.889,37.444,-14.556,41.556,0.48377,-2.238,
+14,146,9,0.11111,0,0.88889,0.47407,1.1111,0.74074,10.593,8,15.667,8.1111,-7.7778,15.222,-7.4444,15.667,0.48786,-2.1089,
+22,87,9,0,0,1.8889,1.259,1.1667,0.62361,64.037,55.778,80.333,56,-24.778,48.889,-24.111,80.333,0.3097,-2.1051,
+130,32,9,0,0,1.1111,1.047,0.83333,0.83666,59.481,54.222,70.889,53.333,-15.778,34.222,-18.444,70.889,0.249,-2.0424,
+162,159,9,0,0,2.1667,0.96032,2.2222,1.4555,26.111,25.222,29.556,23.556,-2.6667,10.333,-7.6667,29.556,0.20285,-1.8026,
+150,158,9,0,0,2.1667,1.6333,1.3889,0.41852,8.4444,7,12.222,6.1111,-4.3333,11.333,-7,12.222,0.50309,-1.9434,
+163,68,9,0,0,1.8333,2.2111,1.5556,0.96296,56.778,52,68.222,50.111,-14.333,34.333,-20,68.222,0.26505,-1.9843,
+187,80,9,0,0,1.3333,0.71111,1.3333,0.71111,40.519,37.778,47.667,36.111,-8.2222,21.444,-13.222,47.667,0.24473,-1.9427,
+140,73,9,0,0,1.7222,0.82776,0.77778,1.0037,46.296,45.667,51.111,42.111,-1.8889,14.444,-12.556,51.111,0.17616,-1.6816,
+236,117,9,0,0,0.77778,0.40369,1.2778,0.74287,45.889,39.556,58.444,39.667,-19,37.667,-18.667,58.444,0.33048,-2.0995,
+112,90,9,0,0,7.3889,6.9456,1.2778,0.87981,65.185,57.667,79.778,58.111,-22.556,43.778,-21.222,79.778,0.27835,-2.1088,
+197,121,9,0,0,21.667,17.363,0.94444,0.90472,41.037,37.444,49.444,36.222,-10.778,25.222,-14.444,49.444,0.28058,-1.9955,
+141,17,9,0.11111,0.22222,3.7222,4.4493,5,2.319,44.593,40.333,54,39.444,-12.778,28.222,-15.444,54,0.26819,-2.03,
+79,28,9,0,0,4.2778,3.7619,0.83333,0.65828,62.407,53.444,79.111,54.667,-26.889,50.111,-23.222,79.111,0.32456,-2.1445,
+169,102,9,0,0,1,0.35555,0.88889,0.2963,58.222,53.444,69.667,51.556,-14.333,34.333,-20,69.667,0.25976,-1.9856,
+208,65,9,0,0,1.3889,1.2368,26.444,25.537,56.704,52.667,64.444,53,-12.111,23.222,-11.111,64.444,0.19713,-1.9708,
+189,144,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+189,141,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+210,153,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+57,89,9,0,0,1.7222,1.3067,6.1667,4.7034,17,13,24.556,13.444,-12,22.667,-10.667,24.556,0.47749,-2.1297,
+243,94,9,0,0,0.66667,0.31111,0.22222,0.02963,1.1852,0.22222,3.2222,0.11111,-2.8889,6.1111,-3.2222,3.2222,0.97778,-2.0712,
+229,104,9,0,0,0.5,0.54772,2.8333,2.0412,19.778,16.333,26.111,16.889,-10.333,19,-8.6667,26.111,0.37553,-2.1506,
+226,131,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+196,95,9,0,0,1.7222,1.1238,1.3333,1.2649,7.6296,6.7778,10.778,5.3333,-2.5556,9.4444,-6.8889,10.778,0.51257,-1.7493,
+43,152,9,0,0,1.9444,1.7074,1.2222,0.82963,1.5185,1,2.8889,0.66667,-1.5556,4.1111,-2.5556,2.8889,0.64868,-1.9332,
+54,133,9,0,0,1.5556,1.0074,0.5,0.34444,5.3704,3.6667,9,3.4444,-5.1111,10.889,-5.7778,9,0.63047,-2.048,
+157,85,9,0,0,1.2222,1.2413,0.22222,0.17213,18.926,14.556,26.889,15.333,-13.111,23.889,-10.778,26.889,0.45902,-2.1609,
+96,94,9,0,0,0.72222,0.28519,0.44444,0.42963,20.222,16,28.778,15.889,-12.667,25.667,-13,28.778,0.45155,-2.0849,
+152,155,9,0,0,0.5,0.61111,10.778,131.81,7.2963,5.3333,11,5.5556,-5.8889,11.111,-5.2222,11,0.5,-2.1156,
+208,34,9,0,0,1.7222,1.731,0.44444,0.50185,14.444,10.778,21,11.556,-11,19.667,-8.6667,21,0.47996,-2.1624,
+222,62,9,0,0,0.27778,0.25092,0.66667,0.55777,6.4074,4.1111,11.444,3.6667,-6.8889,15.111,-8.2222,11.444,0.68081,-2.0342,
+123,152,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+20,134,9,0,0,0.66667,0.088889,0.61111,0.24074,2.963,1.1111,6.4444,1.3333,-5.5556,10.444,-4.8889,6.4444,0.82923,-2.1331,
+223,62,9,0,0,0.33333,0.29814,0.44444,0.50185,6.4444,4.1111,11.444,3.7778,-7,15,-8,11.444,0.67037,-2.0487,
+184,145,9,0,0,0.72222,0.61162,0.22222,0.27217,0.55556,0.33333,1.2222,0.11111,-0.66667,2,-1.3333,1.2222,0.52778,-1.9209,
+225,58,9,0,0,0.33333,0.42164,0.44444,0.34427,8.3333,5.5556,14.111,5.3333,-8.3333,17.333,-9,14.111,0.62222,-2.0686,
+58,113,9,0,0,3.4444,1.2232,0.72222,0.38968,20.852,16.889,28.444,17.222,-11.889,22.778,-10.889,28.444,0.41481,-2.1257,
+160,41,9,0,0,0.83333,0.80966,0.22222,0.17213,0.7037,0.55556,1.2222,0.33333,-0.44444,1.5556,-1.1111,1.2222,0.53704,-1.8451,
+160,110,9,0,0,0.83333,0.69121,0.44444,0.27217,31.63,27.222,39.333,28.333,-13.222,23.111,-9.8889,39.333,0.30744,-2.1872,
+186,12,9,0,0,0.44444,0.27217,2.3333,1.9664,6.2593,3.8889,11.333,3.5556,-7.1111,15.222,-8.1111,11.333,0.6873,-2.058,
+142,111,9,0,0,1.1111,0.45542,0.55556,0.34426,28.741,24.556,35.889,25.778,-12.556,21.444,-8.8889,35.889,0.31548,-2.2027,
+252,137,9,0,0,0.88889,0.54433,0.61111,0.71233,0.74074,0.33333,1.7778,0.11111,-1.2222,3.1111,-1.8889,1.7778,0.75,-2.0076,
+206,61,9,0,0,0.55556,0.40369,0.5,0.45947,7.0741,4.6667,12.222,4.3333,-7.2222,15.444,-8.2222,12.222,0.64589,-2.0487,
+239,93,9,0,0,3.4444,13.496,1.0556,0.86296,14.407,9.8889,22.889,10.444,-13.556,25.444,-11.889,22.889,0.577,-2.1375,
+207,115,9,0,0,1.0556,0.32963,0.16667,0.033333,1.2222,0.44444,2.8889,0.33333,-2.3333,5,-2.6667,2.8889,0.93333,-2.0655,
+90,134,9,0,0,0.38889,0.018519,0.94444,0.15185,2.1111,1,4.6667,0.66667,-3.3333,7.6667,-4.3333,4.6667,0.88148,-2.0131,
+86,197,9,0.11111,0.11111,1.6111,1.4517,1.2778,1.1039,63.222,56.222,77.778,55.667,-21,43.667,-22.667,77.778,0.28533,-2.068,
+4,189,9,0,0,2.0556,3.8852,11.722,114.6,26.444,23.444,33,22.889,-9,19.667,-10.667,33,0.27147,-2.101,
+134,187,9,0,0,1.8889,1.5154,2.1111,1.7847,59.37,52.667,74.111,51.333,-20.111,44.222,-24.111,74.111,0.30746,-2.0335,
+252,201,9,0,0,4.6111,5.4951,5.5556,5.7953,40.296,35.778,49,36.111,-13.556,26.111,-12.556,49,0.27537,-2.1758,
+219,176,9,0,0.11111,2.1111,1.8579,5.1111,2.8415,60.296,53.333,75.667,51.889,-20.889,46.111,-25.222,75.667,0.31446,-2.0306,
+205,190,9,0,0,1.2778,0.99815,1.6111,1.1238,49.481,44.778,60.667,43,-14.111,33.556,-19.444,60.667,0.29079,-1.9876,
+202,193,9,0,0,1.1111,0.75031,3.3889,2.4892,41.704,37.889,50.667,36.556,-11.444,26.889,-15.444,50.667,0.27839,-1.993,
+223,161,9,0,0,1.3889,3.0407,9,31.022,42.037,36,52.222,37.889,-18.111,30.556,-12.444,52.222,0.30842,-2.2823,
+87,196,9,0.11111,0,1.3333,0.86923,2.2222,1.6689,61.593,55,75.667,54.111,-19.778,42.222,-22.444,75.667,0.28753,-2.0487,
+105,193,9,0,0,3.2222,1.9052,2.8889,2.1773,60.111,53.111,75.111,52.111,-21,45,-24,75.111,0.30847,-2.0478,
+77,185,9,0,0,2.9444,7.663,6.2222,32.119,32.556,29.222,39.667,28.778,-10,21.333,-11.333,39.667,0.27036,-2.0853,
+88,180,9,0,0,1.5,0.9369,3.8333,2.8887,50.407,45.222,62.333,43.667,-15.556,35.778,-20.222,62.333,0.30092,-2.0087,
+214,161,9,0,0,3.7222,0.72963,11.5,18.922,40.444,35.333,49.667,36.333,-15.333,27.667,-12.333,49.667,0.29806,-2.1989,
+198,183,9,0,0,1.0556,1.1816,3.3889,1.5975,54.037,48.889,66.556,46.667,-15.444,37.556,-22.111,66.556,0.29862,-1.975,
+189,187,9,0,0,1.2222,1.0037,3.0556,2.389,48.519,44.111,59.889,41.556,-13.222,34.111,-20.889,59.889,0.30575,-1.9475,
+124,191,9,0,0,3.5,2.7386,3.2778,2.8001,59.741,52.889,74.778,51.556,-20.556,45.111,-24.556,74.778,0.31361,-2.0355,
+182,186,9,0.11111,0,3.6667,2.044,1.7778,1.2413,48.444,43.778,59.889,41.667,-14,34.333,-20.333,59.889,0.30452,-1.9731,
+151,163,9,0,0,2.0556,2.2852,18.167,41.989,40,34.556,48,37.444,-16.333,24,-7.6667,48.111,0.26385,-2.5175,
+112,197,9,0,0,4.2222,2.9938,4.9444,3.1228,50.333,44.667,62.222,44.111,-17,35.667,-18.667,62.222,0.29633,-2.0712,
+137,182,9,0,0,1.8333,3.8556,3.6111,9.2185,34.926,31.444,42.889,30.444,-10.444,23.889,-13.444,42.889,0.28576,-2.0011,
+4,201,9,0,0.22222,2.7222,1.6788,5.2222,3.1246,53.704,47.111,67.222,46.778,-19.778,40.556,-20.778,67.222,0.30886,-2.0752,
+235,196,9,0,0,1.6667,1.3333,2.2222,1.1483,47.259,41.778,58.556,41.444,-16.444,33.889,-17.444,58.556,0.29424,-2.0746,
+167,189,9,0,0,3.7778,2.2377,3.7778,1.5444,58.407,51.333,72.444,51.444,-21.222,42.111,-20.889,72.444,0.29552,-2.1013,
+250,176,9,0,0.11111,1.6111,1.0628,3.4444,1.6953,53.667,47.111,67.667,46.222,-19.667,42,-22.333,67.667,0.31814,-2.0523,
+244,194,9,0,0,1.7222,1.1434,2.2778,2.0376,49.741,44.444,61.667,43.111,-15.889,35.778,-19.889,61.667,0.30085,-2.0218,
+178,185,9,0,0,2.6111,1.8064,3.1111,2.2771,49.037,44,60.667,42.444,-15.111,34.889,-19.778,60.667,0.30004,-2.0062,
+229,195,9,0,0,4.1667,2.2779,4.1111,2.2476,47.704,42.444,58.889,41.778,-15.778,33.556,-17.778,58.889,0.29028,-2.0527,
+5,210,9,0,0.11111,2.1667,1.67,4.4444,2.6134,51.296,45.444,64.333,44.111,-17.556,39.111,-21.556,64.333,0.31757,-2.0209,
+118,180,9,0,0,1.9444,1.482,3.1111,1.0887,48.556,44.111,59,42.556,-13.333,31.333,-18,59,0.27882,-1.996,
+86,193,9,0,0,3.2778,1.6522,2.2222,1.8094,61.407,53.667,76.556,54,-23.222,45.444,-22.222,76.556,0.29958,-2.1094,
+204,156,9,0,0,0.5,0.27889,2,0.55777,23.704,17.333,25.444,28.333,-19.111,5.2222,13.889,28.333,0.38903,2.8649,
+71,180,9,0.11111,0,1.2222,0.56296,3,1.8667,22.333,18.333,21.444,27.222,-12,-2.6667,14.667,27.222,0.32738,2.4538,
+60,181,9,0.11111,0,1.6667,1.2,2.6667,2.0889,19.63,17.111,17.889,23.889,-7.5556,-5.2222,12.778,23.889,0.28569,2.1891,
+103,216,9,0,0,0.88889,0.65185,2.1667,1.1444,14.556,10.889,13.667,19.111,-11,-2.6667,13.667,19.111,0.4317,2.4475,
+89,221,9,0,0,1.3889,1.4852,1.4444,1.5852,14.074,10.667,12.444,19.111,-10.222,-4.8889,15.111,19.111,0.44601,2.3172,
+8,199,9,0,0,1.6667,0.78881,1.3889,0.71233,15,13.333,11.778,19.889,-5,-9.6667,14.667,19.889,0.40888,1.9053,
+200,250,9,0,0,2.2778,1.4207,1.4444,1.0256,9.2222,6.5556,7.3333,13.778,-8,-5.6667,13.667,13.778,0.56339,2.1929,
+163,166,9,0,0,1.7778,1.0963,2.4444,1.0519,16.963,12.333,16.333,22.222,-13.889,-1.8889,15.778,22.222,0.44621,2.5158,
+186,173,9,0,0,1.4444,0.82963,2.1111,1.9852,17.148,13.556,15.556,22.333,-10.778,-4.7778,15.556,22.333,0.39643,2.3327,
+2,245,9,0,0,1.8889,2.163,3.1667,3.2778,6.4074,6.2222,6,7,-0.55556,-1.2222,1.7778,7.2222,0.19105,1.7566,
+62,223,9,0,0,2.5,5.7222,1.6667,2.4444,6.6667,4.8889,4.6667,10.444,-5.3333,-6,11.333,10.444,0.59315,2.0466,
+242,183,9,0,0,1.5,0.9369,2.1667,1.7981,15.37,12.667,12.444,21,-8.1111,-8.7778,16.889,21,0.42024,2.0759,
+200,215,9,0,0,1.5556,0.95839,4.7222,2.6451,23.037,17.111,22.556,29.444,-17.778,-1.4444,19.222,29.444,0.42077,2.561,
+57,177,9,0,0,0.94444,0.55185,1.4444,1.7185,19.593,15.778,18.444,24.556,-11.444,-3.4444,14.889,24.556,0.35899,2.4133,
+63,220,9,0,0,3.0556,15.263,3.6667,6.0889,8.1852,6.5556,6.4444,11.556,-4.8889,-5.2222,10.111,11.556,0.48672,2.0931,
+117,224,9,0,0,3.0556,2.5597,3.0556,3.0215,20.259,15.444,17.778,27.556,-14.444,-7.4444,21.889,27.556,0.44152,2.3042,
+233,211,9,0.11111,0,2.6667,6.0889,1.6667,1.7333,15.444,12.444,15.222,18.667,-9,-0.66667,9.6667,18.667,0.33542,2.555,
+232,175,9,0,0,1.1667,0.62361,2.8333,2.1679,15.37,12.444,13.556,20.111,-8.7778,-5.4444,14.222,20.111,0.38741,2.2422,
+29,195,9,0,0,0.44444,0.40369,0.61111,0.68041,16.037,14.444,13.333,20.333,-4.7778,-8.1111,12.889,20.333,0.34231,1.943,
+63,201,9,0,0,1.4444,0.91852,0.94444,0.55185,7.7778,6.2222,5.5556,11.556,-4.6667,-6.6667,11.333,11.556,0.5432,1.983,
+93,236,9,0.11111,0,1.7778,2.6963,2,0.93333,12.519,9.5556,10.778,17.222,-8.8889,-5.2222,14.111,17.222,0.44725,2.2672,
+72,191,9,0.11111,0,1.2778,0.50741,3.1111,4.6074,15.185,12.111,14.889,18.556,-9.2222,-0.88889,10.111,18.556,0.35037,2.5453,
+52,170,9,0,0,0.55556,0.45542,0.94444,0.38968,25.444,20.111,25.333,30.889,-16,-0.33333,16.333,30.889,0.34911,2.604,
+233,184,9,0,0,0.5,0.077778,0.77778,0.78519,11.852,9.7778,9.8889,15.889,-6.2222,-5.8889,12.111,15.889,0.40556,2.1286,
+237,191,9,0,0,1,0.31111,1.5,1.0111,7.3333,5.3333,5.4444,11.222,-6,-5.6667,11.667,11.222,0.53582,2.1224,
+36,243,9,0.11111,0,1.8889,1.8519,2,0.71111,13.333,9.8889,12.111,18,-10.333,-3.6667,14,18,0.45223,2.3683,
+186,218,9,0,0,1.1667,0.74444,1.1667,0.65556,13.704,10.667,12.667,17.778,-9.1111,-3.1111,12.222,17.778,0.40135,2.3827,
+197,236,9,0,0,2.4444,6.8296,3.3333,7.6,16.074,13.111,16.667,18.444,-8.8889,1.7778,7.1111,18.556,0.29273,2.7898,
+208,240,9,0.11111,0,1.0556,0.86296,2.4444,5.0074,14.148,10.889,13,18.556,-9.7778,-3.4444,13.222,18.556,0.42162,2.3925,
+223,185,9,0,0,0.5,0.3496,2.3889,2.0808,12.963,11.556,9.7778,17.556,-4.2222,-9.5556,13.778,17.556,0.44542,1.8388
+};
+#endif
diff --git a/test/classifier/data/segmentation_labels.hxx b/test/classifier/data/segmentation_labels.hxx
new file mode 100644
index 0000000..25a7b3c
--- /dev/null
+++ b/test/classifier/data/segmentation_labels.hxx
@@ -0,0 +1,218 @@
+#ifndef SEGMENTATION_LABELS
+#define SEGMENTATION_LABELS
+int segmentation_labels[] = {
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+6,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+7,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+4
+};
+
+int segmentation_Classes[] = {1, 2 , 3, 4, 5, 6, 7};
+int segmentation_size = 7;
+#endif
diff --git a/test/classifier/data/wine_features.hxx b/test/classifier/data/wine_features.hxx
new file mode 100644
index 0000000..601398b
--- /dev/null
+++ b/test/classifier/data/wine_features.hxx
@@ -0,0 +1,183 @@
+#ifndef WINE_FEATURES
+#define WINE_FEATURES
+double wine_features[] = {
+14.23,1.71,2.43,15.6,127,2.8,3.06,0.28,2.29,5.64,1.04,3.92,1065,
+13.2,1.78,2.14,11.2,100,2.65,2.76,0.26,1.28,4.38,1.05,3.4,1050,
+13.16,2.36,2.67,18.6,101,2.8,3.24,0.3,2.81,5.68,1.03,3.17,1185,
+14.37,1.95,2.5,16.8,113,3.85,3.49,0.24,2.18,7.8,0.86,3.45,1480,
+13.24,2.59,2.87,21,118,2.8,2.69,0.39,1.82,4.32,1.04,2.93,735,
+14.2,1.76,2.45,15.2,112,3.27,3.39,0.34,1.97,6.75,1.05,2.85,1450,
+14.39,1.87,2.45,14.6,96,2.5,2.52,0.3,1.98,5.25,1.02,3.58,1290,
+14.06,2.15,2.61,17.6,121,2.6,2.51,0.31,1.25,5.05,1.06,3.58,1295,
+14.83,1.64,2.17,14,97,2.8,2.98,0.29,1.98,5.2,1.08,2.85,1045,
+13.86,1.35,2.27,16,98,2.98,3.15,0.22,1.85,7.22,1.01,3.55,1045,
+14.1,2.16,2.3,18,105,2.95,3.32,0.22,2.38,5.75,1.25,3.17,1510,
+14.12,1.48,2.32,16.8,95,2.2,2.43,0.26,1.57,5,1.17,2.82,1280,
+13.75,1.73,2.41,16,89,2.6,2.76,0.29,1.81,5.6,1.15,2.9,1320,
+14.75,1.73,2.39,11.4,91,3.1,3.69,0.43,2.81,5.4,1.25,2.73,1150,
+14.38,1.87,2.38,12,102,3.3,3.64,0.29,2.96,7.5,1.2,3,1547,
+13.63,1.81,2.7,17.2,112,2.85,2.91,0.3,1.46,7.3,1.28,2.88,1310,
+14.3,1.92,2.72,20,120,2.8,3.14,0.33,1.97,6.2,1.07,2.65,1280,
+13.83,1.57,2.62,20,115,2.95,3.4,0.4,1.72,6.6,1.13,2.57,1130,
+14.19,1.59,2.48,16.5,108,3.3,3.93,0.32,1.86,8.7,1.23,2.82,1680,
+13.64,3.1,2.56,15.2,116,2.7,3.03,0.17,1.66,5.1,0.96,3.36,845,
+14.06,1.63,2.28,16,126,3,3.17,0.24,2.1,5.65,1.09,3.71,780,
+12.93,3.8,2.65,18.6,102,2.41,2.41,0.25,1.98,4.5,1.03,3.52,770,
+13.71,1.86,2.36,16.6,101,2.61,2.88,0.27,1.69,3.8,1.11,4,1035,
+12.85,1.6,2.52,17.8,95,2.48,2.37,0.26,1.46,3.93,1.09,3.63,1015,
+13.5,1.81,2.61,20,96,2.53,2.61,0.28,1.66,3.52,1.12,3.82,845,
+13.05,2.05,3.22,25,124,2.63,2.68,0.47,1.92,3.58,1.13,3.2,830,
+13.39,1.77,2.62,16.1,93,2.85,2.94,0.34,1.45,4.8,0.92,3.22,1195,
+13.3,1.72,2.14,17,94,2.4,2.19,0.27,1.35,3.95,1.02,2.77,1285,
+13.87,1.9,2.8,19.4,107,2.95,2.97,0.37,1.76,4.5,1.25,3.4,915,
+14.02,1.68,2.21,16,96,2.65,2.33,0.26,1.98,4.7,1.04,3.59,1035,
+13.73,1.5,2.7,22.5,101,3,3.25,0.29,2.38,5.7,1.19,2.71,1285,
+13.58,1.66,2.36,19.1,106,2.86,3.19,0.22,1.95,6.9,1.09,2.88,1515,
+13.68,1.83,2.36,17.2,104,2.42,2.69,0.42,1.97,3.84,1.23,2.87,990,
+13.76,1.53,2.7,19.5,132,2.95,2.74,0.5,1.35,5.4,1.25,3,1235,
+13.51,1.8,2.65,19,110,2.35,2.53,0.29,1.54,4.2,1.1,2.87,1095,
+13.48,1.81,2.41,20.5,100,2.7,2.98,0.26,1.86,5.1,1.04,3.47,920,
+13.28,1.64,2.84,15.5,110,2.6,2.68,0.34,1.36,4.6,1.09,2.78,880,
+13.05,1.65,2.55,18,98,2.45,2.43,0.29,1.44,4.25,1.12,2.51,1105,
+13.07,1.5,2.1,15.5,98,2.4,2.64,0.28,1.37,3.7,1.18,2.69,1020,
+14.22,3.99,2.51,13.2,128,3,3.04,0.2,2.08,5.1,0.89,3.53,760,
+13.56,1.71,2.31,16.2,117,3.15,3.29,0.34,2.34,6.13,0.95,3.38,795,
+13.41,3.84,2.12,18.8,90,2.45,2.68,0.27,1.48,4.28,0.91,3,1035,
+13.88,1.89,2.59,15,101,3.25,3.56,0.17,1.7,5.43,0.88,3.56,1095,
+13.24,3.98,2.29,17.5,103,2.64,2.63,0.32,1.66,4.36,0.82,3,680,
+13.05,1.77,2.1,17,107,3,3,0.28,2.03,5.04,0.88,3.35,885,
+14.21,4.04,2.44,18.9,111,2.85,2.65,0.3,1.25,5.24,0.87,3.33,1080,
+14.38,3.59,2.28,16,102,3.25,3.17,0.27,2.19,4.9,1.04,3.44,1065,
+13.9,1.68,2.12,16,101,3.1,3.39,0.21,2.14,6.1,0.91,3.33,985,
+14.1,2.02,2.4,18.8,103,2.75,2.92,0.32,2.38,6.2,1.07,2.75,1060,
+13.94,1.73,2.27,17.4,108,2.88,3.54,0.32,2.08,8.9,1.12,3.1,1260,
+13.05,1.73,2.04,12.4,92,2.72,3.27,0.17,2.91,7.2,1.12,2.91,1150,
+13.83,1.65,2.6,17.2,94,2.45,2.99,0.22,2.29,5.6,1.24,3.37,1265,
+13.82,1.75,2.42,14,111,3.88,3.74,0.32,1.87,7.05,1.01,3.26,1190,
+13.77,1.9,2.68,17.1,115,3,2.79,0.39,1.68,6.3,1.13,2.93,1375,
+13.74,1.67,2.25,16.4,118,2.6,2.9,0.21,1.62,5.85,0.92,3.2,1060,
+13.56,1.73,2.46,20.5,116,2.96,2.78,0.2,2.45,6.25,0.98,3.03,1120,
+14.22,1.7,2.3,16.3,118,3.2,3,0.26,2.03,6.38,0.94,3.31,970,
+13.29,1.97,2.68,16.8,102,3,3.23,0.31,1.66,6,1.07,2.84,1270,
+13.72,1.43,2.5,16.7,108,3.4,3.67,0.19,2.04,6.8,0.89,2.87,1285,
+12.37,0.94,1.36,10.6,88,1.98,0.57,0.28,0.42,1.95,1.05,1.82,520,
+12.33,1.1,2.28,16,101,2.05,1.09,0.63,0.41,3.27,1.25,1.67,680,
+12.64,1.36,2.02,16.8,100,2.02,1.41,0.53,0.62,5.75,0.98,1.59,450,
+13.67,1.25,1.92,18,94,2.1,1.79,0.32,0.73,3.8,1.23,2.46,630,
+12.37,1.13,2.16,19,87,3.5,3.1,0.19,1.87,4.45,1.22,2.87,420,
+12.17,1.45,2.53,19,104,1.89,1.75,0.45,1.03,2.95,1.45,2.23,355,
+12.37,1.21,2.56,18.1,98,2.42,2.65,0.37,2.08,4.6,1.19,2.3,678,
+13.11,1.01,1.7,15,78,2.98,3.18,0.26,2.28,5.3,1.12,3.18,502,
+12.37,1.17,1.92,19.6,78,2.11,2,0.27,1.04,4.68,1.12,3.48,510,
+13.34,0.94,2.36,17,110,2.53,1.3,0.55,0.42,3.17,1.02,1.93,750,
+12.21,1.19,1.75,16.8,151,1.85,1.28,0.14,2.5,2.85,1.28,3.07,718,
+12.29,1.61,2.21,20.4,103,1.1,1.02,0.37,1.46,3.05,0.906,1.82,870,
+13.86,1.51,2.67,25,86,2.95,2.86,0.21,1.87,3.38,1.36,3.16,410,
+13.49,1.66,2.24,24,87,1.88,1.84,0.27,1.03,3.74,0.98,2.78,472,
+12.99,1.67,2.6,30,139,3.3,2.89,0.21,1.96,3.35,1.31,3.5,985,
+11.96,1.09,2.3,21,101,3.38,2.14,0.13,1.65,3.21,0.99,3.13,886,
+11.66,1.88,1.92,16,97,1.61,1.57,0.34,1.15,3.8,1.23,2.14,428,
+13.03,0.9,1.71,16,86,1.95,2.03,0.24,1.46,4.6,1.19,2.48,392,
+11.84,2.89,2.23,18,112,1.72,1.32,0.43,0.95,2.65,0.96,2.52,500,
+12.33,0.99,1.95,14.8,136,1.9,1.85,0.35,2.76,3.4,1.06,2.31,750,
+12.7,3.87,2.4,23,101,2.83,2.55,0.43,1.95,2.57,1.19,3.13,463,
+12,0.92,2,19,86,2.42,2.26,0.3,1.43,2.5,1.38,3.12,278,
+12.72,1.81,2.2,18.8,86,2.2,2.53,0.26,1.77,3.9,1.16,3.14,714,
+12.08,1.13,2.51,24,78,2,1.58,0.4,1.4,2.2,1.31,2.72,630,
+13.05,3.86,2.32,22.5,85,1.65,1.59,0.61,1.62,4.8,0.84,2.01,515,
+11.84,0.89,2.58,18,94,2.2,2.21,0.22,2.35,3.05,0.79,3.08,520,
+12.67,0.98,2.24,18,99,2.2,1.94,0.3,1.46,2.62,1.23,3.16,450,
+12.16,1.61,2.31,22.8,90,1.78,1.69,0.43,1.56,2.45,1.33,2.26,495,
+11.65,1.67,2.62,26,88,1.92,1.61,0.4,1.34,2.6,1.36,3.21,562,
+11.64,2.06,2.46,21.6,84,1.95,1.69,0.48,1.35,2.8,1,2.75,680,
+12.08,1.33,2.3,23.6,70,2.2,1.59,0.42,1.38,1.74,1.07,3.21,625,
+12.08,1.83,2.32,18.5,81,1.6,1.5,0.52,1.64,2.4,1.08,2.27,480,
+12,1.51,2.42,22,86,1.45,1.25,0.5,1.63,3.6,1.05,2.65,450,
+12.69,1.53,2.26,20.7,80,1.38,1.46,0.58,1.62,3.05,0.96,2.06,495,
+12.29,2.83,2.22,18,88,2.45,2.25,0.25,1.99,2.15,1.15,3.3,290,
+11.62,1.99,2.28,18,98,3.02,2.26,0.17,1.35,3.25,1.16,2.96,345,
+12.47,1.52,2.2,19,162,2.5,2.27,0.32,3.28,2.6,1.16,2.63,937,
+11.81,2.12,2.74,21.5,134,1.6,0.99,0.14,1.56,2.5,0.95,2.26,625,
+12.29,1.41,1.98,16,85,2.55,2.5,0.29,1.77,2.9,1.23,2.74,428,
+12.37,1.07,2.1,18.5,88,3.52,3.75,0.24,1.95,4.5,1.04,2.77,660,
+12.29,3.17,2.21,18,88,2.85,2.99,0.45,2.81,2.3,1.42,2.83,406,
+12.08,2.08,1.7,17.5,97,2.23,2.17,0.26,1.4,3.3,1.27,2.96,710,
+12.6,1.34,1.9,18.5,88,1.45,1.36,0.29,1.35,2.45,1.04,2.77,562,
+12.34,2.45,2.46,21,98,2.56,2.11,0.34,1.31,2.8,0.8,3.38,438,
+11.82,1.72,1.88,19.5,86,2.5,1.64,0.37,1.42,2.06,0.94,2.44,415,
+12.51,1.73,1.98,20.5,85,2.2,1.92,0.32,1.48,2.94,1.04,3.57,672,
+12.42,2.55,2.27,22,90,1.68,1.84,0.66,1.42,2.7,0.86,3.3,315,
+12.25,1.73,2.12,19,80,1.65,2.03,0.37,1.63,3.4,1,3.17,510,
+12.72,1.75,2.28,22.5,84,1.38,1.76,0.48,1.63,3.3,0.88,2.42,488,
+12.22,1.29,1.94,19,92,2.36,2.04,0.39,2.08,2.7,0.86,3.02,312,
+11.61,1.35,2.7,20,94,2.74,2.92,0.29,2.49,2.65,0.96,3.26,680,
+11.46,3.74,1.82,19.5,107,3.18,2.58,0.24,3.58,2.9,0.75,2.81,562,
+12.52,2.43,2.17,21,88,2.55,2.27,0.26,1.22,2,0.9,2.78,325,
+11.76,2.68,2.92,20,103,1.75,2.03,0.6,1.05,3.8,1.23,2.5,607,
+11.41,0.74,2.5,21,88,2.48,2.01,0.42,1.44,3.08,1.1,2.31,434,
+12.08,1.39,2.5,22.5,84,2.56,2.29,0.43,1.04,2.9,0.93,3.19,385,
+11.03,1.51,2.2,21.5,85,2.46,2.17,0.52,2.01,1.9,1.71,2.87,407,
+11.82,1.47,1.99,20.8,86,1.98,1.6,0.3,1.53,1.95,0.95,3.33,495,
+12.42,1.61,2.19,22.5,108,2,2.09,0.34,1.61,2.06,1.06,2.96,345,
+12.77,3.43,1.98,16,80,1.63,1.25,0.43,0.83,3.4,0.7,2.12,372,
+12,3.43,2,19,87,2,1.64,0.37,1.87,1.28,0.93,3.05,564,
+11.45,2.4,2.42,20,96,2.9,2.79,0.32,1.83,3.25,0.8,3.39,625,
+11.56,2.05,3.23,28.5,119,3.18,5.08,0.47,1.87,6,0.93,3.69,465,
+12.42,4.43,2.73,26.5,102,2.2,2.13,0.43,1.71,2.08,0.92,3.12,365,
+13.05,5.8,2.13,21.5,86,2.62,2.65,0.3,2.01,2.6,0.73,3.1,380,
+11.87,4.31,2.39,21,82,2.86,3.03,0.21,2.91,2.8,0.75,3.64,380,
+12.07,2.16,2.17,21,85,2.6,2.65,0.37,1.35,2.76,0.86,3.28,378,
+12.43,1.53,2.29,21.5,86,2.74,3.15,0.39,1.77,3.94,0.69,2.84,352,
+11.79,2.13,2.78,28.5,92,2.13,2.24,0.58,1.76,3,0.97,2.44,466,
+12.37,1.63,2.3,24.5,88,2.22,2.45,0.4,1.9,2.12,0.89,2.78,342,
+12.04,4.3,2.38,22,80,2.1,1.75,0.42,1.35,2.6,0.79,2.57,580,
+12.86,1.35,2.32,18,122,1.51,1.25,0.21,0.94,4.1,0.76,1.29,630,
+12.88,2.99,2.4,20,104,1.3,1.22,0.24,0.83,5.4,0.74,1.42,530,
+12.81,2.31,2.4,24,98,1.15,1.09,0.27,0.83,5.7,0.66,1.36,560,
+12.7,3.55,2.36,21.5,106,1.7,1.2,0.17,0.84,5,0.78,1.29,600,
+12.51,1.24,2.25,17.5,85,2,0.58,0.6,1.25,5.45,0.75,1.51,650,
+12.6,2.46,2.2,18.5,94,1.62,0.66,0.63,0.94,7.1,0.73,1.58,695,
+12.25,4.72,2.54,21,89,1.38,0.47,0.53,0.8,3.85,0.75,1.27,720,
+12.53,5.51,2.64,25,96,1.79,0.6,0.63,1.1,5,0.82,1.69,515,
+13.49,3.59,2.19,19.5,88,1.62,0.48,0.58,0.88,5.7,0.81,1.82,580,
+12.84,2.96,2.61,24,101,2.32,0.6,0.53,0.81,4.92,0.89,2.15,590,
+12.93,2.81,2.7,21,96,1.54,0.5,0.53,0.75,4.6,0.77,2.31,600,
+13.36,2.56,2.35,20,89,1.4,0.5,0.37,0.64,5.6,0.7,2.47,780,
+13.52,3.17,2.72,23.5,97,1.55,0.52,0.5,0.55,4.35,0.89,2.06,520,
+13.62,4.95,2.35,20,92,2,0.8,0.47,1.02,4.4,0.91,2.05,550,
+12.25,3.88,2.2,18.5,112,1.38,0.78,0.29,1.14,8.21,0.65,2,855,
+13.16,3.57,2.15,21,102,1.5,0.55,0.43,1.3,4,0.6,1.68,830,
+13.88,5.04,2.23,20,80,0.98,0.34,0.4,0.68,4.9,0.58,1.33,415,
+12.87,4.61,2.48,21.5,86,1.7,0.65,0.47,0.86,7.65,0.54,1.86,625,
+13.32,3.24,2.38,21.5,92,1.93,0.76,0.45,1.25,8.42,0.55,1.62,650,
+13.08,3.9,2.36,21.5,113,1.41,1.39,0.34,1.14,9.4,0.57,1.33,550,
+13.5,3.12,2.62,24,123,1.4,1.57,0.22,1.25,8.6,0.59,1.3,500,
+12.79,2.67,2.48,22,112,1.48,1.36,0.24,1.26,10.8,0.48,1.47,480,
+13.11,1.9,2.75,25.5,116,2.2,1.28,0.26,1.56,7.1,0.61,1.33,425,
+13.23,3.3,2.28,18.5,98,1.8,0.83,0.61,1.87,10.52,0.56,1.51,675,
+12.58,1.29,2.1,20,103,1.48,0.58,0.53,1.4,7.6,0.58,1.55,640,
+13.17,5.19,2.32,22,93,1.74,0.63,0.61,1.55,7.9,0.6,1.48,725,
+13.84,4.12,2.38,19.5,89,1.8,0.83,0.48,1.56,9.01,0.57,1.64,480,
+12.45,3.03,2.64,27,97,1.9,0.58,0.63,1.14,7.5,0.67,1.73,880,
+14.34,1.68,2.7,25,98,2.8,1.31,0.53,2.7,13,0.57,1.96,660,
+13.48,1.67,2.64,22.5,89,2.6,1.1,0.52,2.29,11.75,0.57,1.78,620,
+12.36,3.83,2.38,21,88,2.3,0.92,0.5,1.04,7.65,0.56,1.58,520,
+13.69,3.26,2.54,20,107,1.83,0.56,0.5,0.8,5.88,0.96,1.82,680,
+12.85,3.27,2.58,22,106,1.65,0.6,0.6,0.96,5.58,0.87,2.11,570,
+12.96,3.45,2.35,18.5,106,1.39,0.7,0.4,0.94,5.28,0.68,1.75,675,
+13.78,2.76,2.3,22,90,1.35,0.68,0.41,1.03,9.58,0.7,1.68,615,
+13.73,4.36,2.26,22.5,88,1.28,0.47,0.52,1.15,6.62,0.78,1.75,520,
+13.45,3.7,2.6,23,111,1.7,0.92,0.43,1.46,10.68,0.85,1.56,695,
+12.82,3.37,2.3,19.5,88,1.48,0.66,0.4,0.97,10.26,0.72,1.75,685,
+13.58,2.58,2.69,24.5,105,1.55,0.84,0.39,1.54,8.66,0.74,1.8,750,
+13.4,4.6,2.86,25,112,1.98,0.96,0.27,1.11,8.5,0.67,1.92,630,
+12.2,3.03,2.32,19,96,1.25,0.49,0.4,0.73,5.5,0.66,1.83,510,
+12.77,2.39,2.28,19.5,86,1.39,0.51,0.48,0.64,9.9,0.57,1.63,470,
+14.16,2.51,2.48,20,91,1.68,0.7,0.44,1.24,9.7,0.62,1.71,660,
+13.71,5.65,2.45,20.5,95,1.68,0.61,0.52,1.06,7.7,0.64,1.74,740,
+13.4,3.91,2.48,23,102,1.8,0.75,0.43,1.41,7.3,0.7,1.56,750,
+13.27,4.28,2.26,20,120,1.59,0.69,0.43,1.35,10.2,0.59,1.56,835,
+13.17,2.59,2.37,20,120,1.65,0.68,0.53,1.46,9.3,0.6,1.62,840,
+14.13,4.1,2.74,24.5,96,2.05,0.76,0.56,1.35,9.2,0.61,1.6,560
+};
+#endif
diff --git a/test/classifier/data/wine_labels.hxx b/test/classifier/data/wine_labels.hxx
new file mode 100644
index 0000000..3b3d612
--- /dev/null
+++ b/test/classifier/data/wine_labels.hxx
@@ -0,0 +1,186 @@
+#ifndef WINE_LABELS
+#define WINE_LABELS
+int wine_labels[] = {
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+2,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3,
+3
+};
+
+int wine_Classes[] = {1, 2 , 3};
+int wine_size = 3;
+#endif
diff --git a/test/classifier/data/wpbc_features.hxx b/test/classifier/data/wpbc_features.hxx
new file mode 100644
index 0000000..05c92fd
--- /dev/null
+++ b/test/classifier/data/wpbc_features.hxx
@@ -0,0 +1,198 @@
+#ifndef WPBC_FEATURES
+#define WPBC_FEATURES
+double wpbc_features[] = {
+18.02,
+27.6,
+117.5,
+1013,
+0.09489,
+0.1036,
+0.1086,
+0.07055,
+0.1865,
+0.06333,
+0.6249,
+1.89,
+3.972,
+71.55,
+0.004433,
+0.01421,
+0.03233,
+0.009854,
+0.01694,
+0.003495,
+21.63,
+37.08,
+139.7,
+1436,
+0.1195,
+0.1926,
+0.314,
+0.117,
+0.2677,
+0.08113,
+5,
+5,
+17.99,
+10.38,
+122.8,
+1001,
+0.1184,
+0.2776,
+0.3001,
+0.1471,
+0.2419,
+0.07871,
+1.095,
+0.9053,
+8.589,
+153.4,
+0.006399,
+0.04904,
+0.05373,
+0.01587,
+0.03003,
+0.006193,
+25.38,
+17.33,
+184.6,
+2019,
+0.1622,
+0.6656,
+0.7119,
+0.2654,
+0.4601,
+0.1189,
+3,
+2,
+21.37,
+17.44,
+137.5,
+1373,
+0.08836,
+0.1189,
+0.1255,
+0.0818,
+0.2333,
+0.0601,
+0.5854,
+0.6105,
+3.928,
+82.15,
+0.006167,
+0.03449,
+0.033,
+0.01805,
+0.03094,
+0.005039,
+24.9,
+20.98,
+159.1,
+1949,
+0.1188,
+0.3449,
+0.3414,
+0.2032,
+0.4334,
+0.09067,
+2.5,
+0,
+11.42,
+20.38,
+77.58,
+386.1,
+0.1425,
+0.2839,
+0.2414,
+0.1052,
+0.2597,
+0.09744,
+0.4956,
+1.156,
+3.445,
+27.23,
+0.00911,
+0.07458,
+0.05661,
+0.01867,
+0.05963,
+0.009208,
+14.91,
+26.5,
+98.87,
+567.7,
+0.2098,
+0.8663,
+0.6869,
+0.2575,
+0.6638,
+0.173,
+2,
+0,
+20.29,
+14.34,
+135.1,
+1297,
+0.1003,
+0.1328,
+0.198,
+0.1043,
+0.1809,
+0.05883,
+0.7572,
+0.7813,
+5.438,
+94.44,
+0.01149,
+0.02461,
+0.05688,
+0.01885,
+0.01756,
+0.005115,
+22.54,
+16.67,
+152.2,
+1575,
+0.1374,
+0.205,
+0.4,
+0.1625,
+0.2364,
+0.07678,
+3.5,
+0,
+12.75,
+15.29,
+84.6,
+502.7,
+0.1189,
+0.1569,
+0.1664,
+0.07666,
+0.1995,
+0.07164,
+0.3877,
+0.7402,
+2.999,
+30.85,
+0.007775,
+0.02987,
+0.04561,
+0.01357,
+0.01774,
+0.005114,
+15.51,
+20.37,
+107.3,
+733.2,
+0.1706,
+0.4196,
+0.5999,
+0.1709,
+0.3485,
+0.1179,
+2.5,
+0,
+13.71
+};
+#endif
diff --git a/test/classifier/data/wpbc_labels.hxx b/test/classifier/data/wpbc_labels.hxx
new file mode 100644
index 0000000..b5f2f86
--- /dev/null
+++ b/test/classifier/data/wpbc_labels.hxx
@@ -0,0 +1,202 @@
+#ifndef WPBC_LABELS
+#define WPBC_LABELS
+int wpbc_labels[] = {
+1,
+1,
+1,
+1,
+2,
+2,
+2,
+1,
+1,
+1,
+1,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+2,
+1,
+1,
+2,
+1,
+2,
+2,
+1,
+2,
+2,
+1,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+1,
+1,
+1,
+1,
+2,
+1,
+1,
+2,
+1,
+1,
+2,
+1,
+1,
+1,
+1,
+2,
+1,
+2,
+1,
+1,
+1,
+1,
+1,
+2,
+1,
+1,
+1,
+1,
+1,
+2,
+1,
+1,
+1,
+1,
+1,
+2,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+2,
+1,
+1,
+1,
+2,
+2,
+1,
+2,
+1,
+2,
+1,
+1,
+1,
+1,
+1,
+2,
+1,
+1,
+1,
+1,
+2,
+1,
+1,
+2,
+2,
+1,
+2,
+2,
+1,
+1,
+2,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+1,
+2,
+1,
+2,
+1,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+2,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+2,
+2,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1,
+1
+};
+
+int wpbc_Classes[] = {1, 2 };
+int wpbc_size = 2;
+#endif
diff --git a/test/classifier/speed_comparison.cxx b/test/classifier/speed_comparison.cxx
new file mode 100644
index 0000000..aa745d9
--- /dev/null
+++ b/test/classifier/speed_comparison.cxx
@@ -0,0 +1,48 @@
+//We need to undefine NDEBUG so that we have TIC, TOC available!
+#undef NDEBUG
+
+#include <vigra/timing.hxx>
+USETICTOC;
+#include <vigra/random_forest_deprec.hxx>
+#include <vigra/random_forest.hxx>
+
+using namespace vigra;
+
+
+
+int main(int argc, char ** argv)
+{
+    typedef MultiArrayShape<2>::type Shp;
+    MultiArray<2, double> features(Shp(1000, 50), 0.0);
+    MultiArray<2, int>    labels(Shp(1000, 1), 0);
+    ArrayVector<int> classes(2, 0);
+    classes[1] = 1; 
+
+    RandomMT19937 random(1); 
+    RandomMT19937 random_old(1); 
+
+
+    for(int ii = 0; ii < features.shape(0); ++ii)
+    {
+        labels(ii, 0) = random.uniform53() > 0.5; 
+        for(int jj = 0; jj < features.shape(1); ++jj)
+        {
+            features(ii, jj) = random.uniform53();
+        }
+    }
+    
+    RandomForest<int>    rf_new(RandomForestOptions().tree_count(255));
+    RandomForestDeprec<int> rf_old(classes.begin(), 
+                                   classes.end());
+    
+    std::cerr << "Learning New Random Forest:" << std::endl;
+    TIC;
+    rf_new.learn(features, labels, rf_default(), rf_default(), rf_default(), random);
+    TOC;
+    std::cerr << "Learning Old Random Forest:" << std::endl;
+    TIC;
+    rf_old.learn(features, labels, random_old); 
+    TOC;
+    return 0;
+
+}
diff --git a/test/classifier/test.cxx b/test/classifier/test.cxx
new file mode 100644
index 0000000..0212cd6
--- /dev/null
+++ b/test/classifier/test.cxx
@@ -0,0 +1,1085 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by Rahul Nair and Ullrich Koethe          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+#define CLASSIFIER_TEST 1
+#define HDF5 0
+#define CROSSVAL 0
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4244)
+#endif
+
+#include <iostream>
+#include <fstream>
+#include <functional>
+#include <cmath>
+#include <vigra/random_forest.hxx>
+#include <vigra/random_forest_deprec.hxx>
+#include <vigra/multi_math.hxx>
+#include <vigra/unittest.hxx>
+#include <vector>
+#include <limits>
+//#include "data/RF_results.hxx"
+#include "data/RF_data.hxx"
+#include "test_visitors.hxx"
+
+#if CROSSVAL
+#include <vigra/crossvalidation.hxx>
+#endif
+
+
+#include <stdlib.h>
+
+#ifdef HasHDF5
+# include <vigra/hdf5impex.hxx>
+# include <vigra/random_forest_hdf5_impex.hxx>
+# if HDF5
+#  include "vigra/dataset4.hxx"
+# endif
+#endif
+
+using namespace vigra;
+
+
+struct UnaryRandomFunctor
+{
+    double operator()(double)
+    {
+        return vigra::RandomTT800::global().uniform53();
+    }
+};
+
+
+struct ClassifierTest
+{
+    RF_Test_Training_Data data;
+    //RF_Test_Result_Data results;
+
+    ClassifierTest():
+        data()
+    {}
+
+
+/**     ClassifierTest::diffOnfiles()
+    Helper method to check whether two files are binary equal.
+**/
+    void diffOnfiles(std::string oldName, std::string newName)
+    {
+        std::ifstream oldRF(oldName.c_str());
+        if(oldRF.fail())
+            vigra_fail("files with old values not found");
+        std::ifstream newRF(newName.c_str());
+        if(newRF.fail())
+            vigra_fail("files with new values not found");
+        std::string oldS, newS;
+        int k = 0;
+        while(std::getline(newRF, newS) && std::getline(oldRF, oldS))
+        {
+
+            std::ostringstream s1;
+            s1 << "Error in line " << k << std::endl;
+            //shouldEqualMessage(newS, oldS, s1.str().c_str() );
+            vigra::detail::equal_impl(newS, oldS,s1.str().c_str(), __FILE__, __LINE__);
+            ++k;
+        }
+        //clean up garbage.
+        std::ofstream newRFclear(newName.c_str());
+        newRFclear.close();
+    }
+    
+/** Tests whether RF rejects Matrices containing Inf
+ */ 
+    void RF_InfCheck()
+    {
+        //Create Test output by Random Forest
+        typedef MultiArrayShape<2>::type Shp_t;
+        {
+            std::cerr << "RF_InfCheck(): checking contains_inf() and RF precondition on Inf\n";
+            MultiArray<2, double> dfeatures(Shp_t(10, 5));
+            MultiArray<2, float>  ffeatures(Shp_t(10, 5));
+            
+            for(int ii = 0; ii < 10; ++ii)
+            {
+                for(int jj = 0; jj < 5; ++jj)
+                {
+                    dfeatures(ii, jj) = (ii*jj+jj)%97;
+                    ffeatures(ii, jj) = (ii*jj+jj)%97;
+                }
+            }
+            shouldEqual(detail::contains_inf(dfeatures), false);
+            shouldEqual(detail::contains_inf(ffeatures), false);
+                    
+            dfeatures(2, 3) = std::numeric_limits<double>::infinity();
+            ffeatures(2, 3) = std::numeric_limits<double>::infinity();
+            
+            shouldEqual(detail::contains_inf(dfeatures), true);
+            shouldEqual(detail::contains_inf(ffeatures), true);
+            
+            for(int ii = 0; ii < 10; ++ii)
+            {
+                for(int jj = 0; jj < 5; ++jj)
+                {
+                    dfeatures(ii, jj) = std::numeric_limits<double>::infinity();
+                    ffeatures(ii, jj) = std::numeric_limits<double>::infinity();
+                }
+            }
+            
+            shouldEqual(detail::contains_inf(dfeatures), true);
+            shouldEqual(detail::contains_inf(ffeatures), true);
+        }
+        MultiArray<2, double> dfeatures(Shp_t(10, 5));
+        MultiArray<2, double> dlabels(Shp_t(10, 1));
+        for(int ii = 0; ii < 10; ++ii)
+        {
+            for(int jj = 0; jj < 5; ++jj)
+            {
+                dfeatures(ii, jj) = (ii*jj+jj)%97;
+            }
+            dlabels(ii, 0) = ii%2;
+        }
+        dlabels(9,0) = std::numeric_limits<double>::infinity();
+        RandomForest<> rf;
+        try
+        {
+            rf.learn(dfeatures, dlabels);
+            shouldEqual(0, 1);
+        }
+        catch( ... )
+        {
+        }
+        dfeatures(9,0) = dlabels(9,0);
+        dlabels(9,0) = 9%2;
+        try
+        {
+            rf.learn(dfeatures, dlabels);
+            shouldEqual(0, 1);
+        }
+        catch( ... )
+        {
+        }
+
+    }
+    
+    void RF_AlgorithmTest()
+    {
+        std::cerr << "WARNING: THIS TEST CURRENTLY ONLY CHECKS WHETHER ALGORITHMS COMPILE AND RUN WITHOUT ERROR...\n";
+        int ii = data.size() - 3; // this is the pina_indians dataset
+        std::cerr << "RF_AlgorithmTest()....";
+        
+        rf::algorithms::HClustering             linkage;
+        MultiArray<2, double>   distance;
+        std::cerr << "cluster_permutation_importance()....\n";
+        cluster_permutation_importance(data.features(ii), data.labels(ii), linkage, distance);
+        rf::algorithms::VariableSelectionResult  result1;
+        std::cerr << "forward_selection()....\n";
+        rf::algorithms::forward_selection(data.features(ii), data.labels(ii), result1);
+        rf::algorithms::VariableSelectionResult  result;
+        std::vector<int> r;
+        r.push_back(0);
+        r.push_back(1);
+        r.push_back(2);
+        r.push_back(3);
+        r.push_back(4);
+        r.push_back(5);
+        r.push_back(6);
+        r.push_back(7);
+        result.init(data.features(ii), data.labels(ii), r.begin(), r.end());
+        std::cerr << "rank_selection()....\n";
+        rf::algorithms::rank_selection(data.features(ii), data.labels(ii), result);
+        
+        rf::algorithms::VariableSelectionResult  result2;
+        std::cerr << "backward_elimination()....\n";
+        rf::algorithms::backward_elimination(data.features(ii), data.labels(ii), result2);
+        std::cerr << "DONE\n";
+    }
+    void RF_SpliceTest()
+    {
+        std::cerr << "RF_SpliceTest()....";
+
+        MultiArray<2, double> a(MultiArrayShape<2>::type(20, 10), 1);
+        for(int ii = 0; ii< 20; ii+=2)
+        {
+            for(int jj = 0; jj< 10; jj+=2)
+            {
+                a(ii, jj) = 3;
+            }
+        }
+        MultiArray<2, double> b(_spl_shp(_spl(0,2,20),_spl(0,2,10)));
+        copy_splice(_spl(0,2,20), _spl(0,2,10), a, b);
+
+        MultiArray<2, double> c(b.shape(), 3);
+        shouldEqual(b, c);
+        std::cerr << "DONE\n";
+    }
+
+    
+/** Check whether the ridge regression functor compiles and runs
+ */
+    void RFridgeRegressionTest()
+    {
+        std::cerr << "RF_ridgeRegressionTest()....";
+        std::cerr << "WARNING: THIS TEST CURRENTLY ONLY CHECKS WHETHER RIDGE REGRESSION COMPILES AND RUNS WITHOUT ERROR...";
+        int ii = data.size() - 3; // this is the pina_indians dataset
+        //the ridge split class
+        vigra::RandomForest<> rf(vigra::RandomForestOptions().tree_count(1));
+        vigra::GiniRidgeSplit ridgeSplit;
+        rf.learn(data.features(ii), data.labels(ii), rf_default(), ridgeSplit);
+        std::cerr << "DONE\n";
+    }
+    
+/** Tests whether RF rejects Matrices containing NaN
+ */ 
+    void RF_NanCheck()
+    {
+        //Create Test output by Random Forest
+        typedef MultiArrayShape<2>::type Shp_t;
+        {
+            std::cerr << "RF_NanCheck(): checking contains_nan() and RF precondition on NaN\n";
+            MultiArray<2, double> dfeatures(Shp_t(10, 5));
+            MultiArray<2, float>  ffeatures(Shp_t(10, 5));
+            for(int ii = 0; ii < 10; ++ii)
+            {
+                for(int jj = 0; jj < 5; ++jj)
+                {
+                    dfeatures(ii, jj) = (ii*jj+jj)%97;
+                    ffeatures(ii, jj) = (ii*jj+jj)%97;
+                }
+            }
+            shouldEqual(detail::contains_nan(dfeatures), false);
+            shouldEqual(detail::contains_nan(ffeatures), false);
+
+            dfeatures(2, 3) = std::numeric_limits<double>::quiet_NaN();
+            ffeatures(2, 3) = std::numeric_limits<float>::quiet_NaN();
+            
+            shouldEqual(detail::contains_nan(dfeatures), true);
+            shouldEqual(detail::contains_nan(ffeatures), true);
+            
+            for(int ii = 0; ii < 10; ++ii)
+            {
+                for(int jj = 0; jj < 5; ++jj)
+                {
+                    dfeatures(ii, jj) = std::numeric_limits<double>::quiet_NaN();
+                    ffeatures(ii, jj) = std::numeric_limits<double>::quiet_NaN();
+                }
+            }
+            
+            shouldEqual(detail::contains_nan(dfeatures), true);
+            shouldEqual(detail::contains_nan(ffeatures), true);
+            
+            for(int ii = 0; ii < 10; ++ii)
+            {
+                for(int jj = 0; jj < 5; ++jj)
+                {
+                    dfeatures(ii, jj) = (ii*jj+jj)%97;
+                    ffeatures(ii, jj) = (ii*jj+jj)%97;
+                }
+            }
+            shouldEqual(detail::contains_nan(dfeatures), false);
+            shouldEqual(detail::contains_nan(ffeatures), false);
+                    
+            dfeatures(2, 3) = std::numeric_limits<double>::signaling_NaN();
+            ffeatures(2, 3) = std::numeric_limits<double>::signaling_NaN();
+            
+            shouldEqual(detail::contains_nan(dfeatures), true);
+            shouldEqual(detail::contains_nan(ffeatures), true);
+            
+            for(int ii = 0; ii < 10; ++ii)
+            {
+                for(int jj = 0; jj < 5; ++jj)
+                {
+                    dfeatures(ii, jj) = std::numeric_limits<double>::signaling_NaN();
+                    ffeatures(ii, jj) = std::numeric_limits<double>::signaling_NaN();
+                }
+            }
+            
+            shouldEqual(detail::contains_nan(dfeatures), true);
+            shouldEqual(detail::contains_nan(ffeatures), true);
+        }
+        MultiArray<2, double> dfeatures(Shp_t(10, 5));
+        MultiArray<2, double> dlabels(Shp_t(10, 1));
+        for(int ii = 0; ii < 10; ++ii)
+        {
+            for(int jj = 0; jj < 5; ++jj)
+            {
+                dfeatures(ii, jj) = (ii*jj+jj)%97;
+            }
+            dlabels(ii, 0) = ii%2;
+        }
+
+        RandomForest<> rf_good;
+		rf_good.learn(dfeatures, dlabels);
+
+        dlabels(9,0) = std::numeric_limits<double>::quiet_NaN();
+       
+        try
+        {
+            RandomForest<> rf;
+			rf.learn(dfeatures, dlabels);
+            failTest("RandomForest::learn() didn't throw on NaN inputs.");
+        }
+		catch( PreconditionViolation const & p )
+        {
+			std::string expected("\nPrecondition violation!\nRandomForest(): Response contains NaNs");
+			std::string message(p.what());
+			shouldEqual(expected, message.substr(0, expected.size()));
+        }
+        dfeatures(9,0) = dlabels(9,0);
+        dlabels(9,0) = 9%2;
+        try
+        {
+            RandomForest<> rf;
+            rf.learn(dfeatures, dlabels);
+            failTest("RandomForest::learn() didn't throw on NaN inputs.");
+        }
+		catch( PreconditionViolation const & p )
+        {
+			std::string expected("\nPrecondition violation!\nRandomForest(): Feature matrix contains NaNs");
+			std::string message(p.what());
+			shouldEqual(expected, message.substr(0, expected.size()));
+        }
+
+		MultiArray<2, double> probs(Shape2(1,2), 1.0);
+
+		// probs for all classes must be zero for invlaid (NaN) input
+		rf_good.predictProbabilities(dfeatures.subarray(Shape2(9,0), Shape2(10,5)), probs);
+
+		using namespace multi_math;
+		should(all(probs == 0.0));
+
+		// predictLabels() on NaN inputs should return the 'nanLabel' if given, or throw otherwise.
+		MultiArray<2, double> rlabels(Shp_t(10, 1));
+        try
+        {
+            rf_good.predictLabels(dfeatures, rlabels);
+            failTest("RandomForest::predictLabels() didn't throw on NaN inputs.");
+        }
+		catch( PreconditionViolation const & p )
+        {
+			std::string expected("\nPrecondition violation!\nRandomForest::predictLabels(): NaN in feature matrix");
+			std::string message(p.what());
+			shouldEqual(expected, message.substr(0, expected.size()));
+        }
+		rf_good.predictLabels(dfeatures, rlabels, -9999.0);
+		shouldEqual(rlabels(9,0), -9999.0);
+		should(all(rlabels.subarray(Shape2(0,0), Shape2(9,1)) != -9999.0));
+    }
+    
+    
+    void RFSplitFunctorTest()
+    {
+        //Create Test output by Random Forest
+        {
+            vigra::TestVisitor testVisitor;
+            std::cerr << "RFSplitFunctorTest(): Learning on Datasets (Warning this checks whether Median and RandomSplit functors compile and run"
+                                                "if you plan to use it, please improve the test\n";
+            for(int ii = 0; ii < data.size() ; ii++)
+            {
+                vigra::RandomForest<>
+                    RF2(vigra::RandomForestOptions().tree_count(32));
+                vigra::RandomForest<int>
+                    RF3(vigra::RandomForestOptions().tree_count(5), vigra::ProblemSpec<int>().classes_(data.ClassIter(ii).begin(), data.ClassIter(ii).end()));
+
+                RF3.learn(  data.features(ii),
+                            data.labels(ii),
+                            rf_default(),
+                            rf::split::MedianSplit(),
+                            rf_default(),
+                            vigra::RandomMT19937(1));
+
+                RF2.learn(  data.features(ii),
+                            data.labels(ii),
+                            rf_default(),
+                            rf::split::RandomSplit(),
+                            rf_default(),
+                            vigra::RandomMT19937(1));
+            }
+        }
+        std::cerr << "DONE!\n\n";
+    }
+/**
+        ClassifierTest::RFdefaultTest():
+    Learns The Refactored Random Forest with a fixed Random Seed and default sampling Options on
+    various UCI data sets. A print Visitor outputs Node and Split Information into a file
+    (RandomForestNodeTest.log) This file is then compared with a similar file created with
+    the old (functional) RandomForest (oldClassifier.log). As long as the order, in which the
+    RND_ object is called is not changed the files should be binary identical and this Test
+    should always succeed.
+**/
+    void RFdefaultTest()
+    {
+        //Create Test output by Random Forest
+        {
+            vigra::TestVisitor testVisitor;
+            std::cerr << "RFdefaultTest(): Learning on Datasets\n";
+            for(int ii = 0; ii < data.size() ; ii++)
+            {
+                vigra::RandomForest<>
+                    RF2(vigra::RandomForestOptions().tree_count(32));
+                vigra::RandomForest<int>
+                    RF3(vigra::RandomForestOptions().tree_count(5), vigra::ProblemSpec<int>().classes_(data.ClassIter(ii).begin(), data.ClassIter(ii).end()));
+
+                RF3.learn(  data.features(ii),
+                            data.labels(ii),
+                            rf_default(),
+                            rf_default(),
+                            rf_default(),
+                            vigra::RandomMT19937(1));
+
+                RF2.learn(  data.features(ii),
+                            data.labels(ii),
+                            create_visitor(testVisitor),
+                            rf_default(),
+                            rf_default(),
+                            vigra::RandomMT19937(1));
+
+                testVisitor.fout <<  data.names(ii) << std::endl;
+                std::cerr << "[";
+                for(int ss = 0; ss < ii+1; ++ss)
+                    std::cerr << "#";
+                for(int ss = ii+1; ss < data.size(); ++ss)
+                    std::cerr << " ";
+                std::cerr << "] " << data.names(ii);
+                std::cerr << "\n";
+                
+                // just to ensure that using other label classes does 
+                // not destroy anything
+                shouldEqual(RF2.tree(0).topology_, RF3.tree(0).topology_);
+                
+                shouldEqual(data.features(ii).shape(0),
+                            RF2.ext_param_.row_count_);
+                shouldEqual(data.features(ii).shape(1),
+                            RF2.ext_param_.column_count_);
+                shouldEqual(data.ClassIter(ii).size(), 
+                            RF2.ext_param_.class_count_);
+            }
+        }
+        std::cerr << std::endl;
+        std::cerr << "RFdefaultTest(): Comparing with Working Version:";
+        //Cheap diff on old and new Classifier.
+        diffOnfiles("./data/oldClassifier.log", "RandomForestNodeTest.log");
+        std::cerr << "DONE!\n\n";
+    }
+
+    /** checks whether the agglomeration of data and conversion from internal
+     * to external labels is working 
+     */
+    void RFresponseTest()
+    {
+        int ii = 2; 
+        // learn on glass data set and predict: 
+        // this is interesting because there is no label with number 4
+        // in this dataset.
+        
+        // check whether agglomeration of probabilities is done properlyy
+        std::cerr << "RFresponseTest(): Learning on Datasets\n";
+        vigra::RandomForest<>
+            RF(vigra::RandomForestOptions().tree_count(2)); 
+
+        RF.learn( data.features(ii),
+                  data.labels(ii),
+                  rf_default(),
+                  rf_default(),
+                  rf_default(),
+                  vigra::RandomMT19937(1));
+        
+        typedef MultiArrayShape<2>::type Shp;
+        MultiArray<2, double> response(Shp(data.features(ii).shape(0),
+                                       data.ClassIter(ii).size()));
+        RF.predictProbabilities(data.features(ii), response);
+        for(int jj = 0; jj < response.shape(0); ++jj)
+        {
+            typedef ArrayVector<double>::iterator Iter;
+            ArrayVector<double> tmp(data.ClassIter(ii).size(), 0.0);
+            Iter a = RF.tree(0).predict(rowVector(data.features(ii),jj));
+            double totalWeight = 0.0;
+            std::transform(tmp.begin(), tmp.end(), 
+                           a, tmp.begin(), std::plus<double>());
+            totalWeight = std::accumulate(a, a + data.ClassIter(ii).size(),
+                                          totalWeight);
+            a = RF.tree(1).predict(rowVector(data.features(ii),jj));
+            std::transform(tmp.begin(), tmp.end(), 
+                           a, tmp.begin(), std::plus<double>());
+            totalWeight = std::accumulate(a, a + data.ClassIter(ii).size(),
+                                          totalWeight);
+            std::transform(tmp.begin(), tmp.end(),tmp.begin(), 
+                           std::bind2nd(std::divides<double>(), totalWeight));
+            MultiArrayView<2, double> 
+                should_resp(Shp(1, data.ClassIter(ii).size()), tmp.data());
+
+            shouldEqual(rowVector(response, jj), should_resp);
+        }
+        
+        StopAfterTree stopAfterTree(1);
+        StopIfMargin  stopIfMargin(0.5);
+        StopAfterVoteCount stopAfterVoteCount(0.5);
+        StopIfConverging   stopIfConverging(0.5);
+        RF.predictProbabilities(data.features(ii), response,stopAfterTree);
+        RF.predictProbabilities(data.features(ii), response,stopIfMargin);
+        RF.predictProbabilities(data.features(ii), response,stopAfterVoteCount);
+        RF.predictProbabilities(data.features(ii), response,stopIfConverging);
+        // to check whether labels are being currectly converted we use the
+        // property of the random forest to almost surely have 0 prediction
+        // error on the training data. with enough trees.
+        vigra::RandomForest<>
+            RF2(vigra::RandomForestOptions().tree_count(255)); 
+
+        RF2.learn( data.features(ii),
+                  data.labels(ii),
+                  rf_default(),
+                  rf_default(),
+                  rf_default(),
+                  vigra::RandomMT19937(1));
+        MultiArray<2, double> dble_labels(Shp(data.features(ii).shape(0),
+                                              1));
+        MultiArray<2, Int32>  int_labels(Shp(data.features(ii).shape(0),
+                                             1));
+
+        RF2.predictLabels(data.features(ii), dble_labels);
+        RF2.predictLabels(data.features(ii), int_labels);
+    
+        for(int jj = 0; jj< data.features(ii).shape(0); ++jj)
+        {
+            shouldEqualTolerance(dble_labels[jj], data.labels(ii)[jj], 0.01);
+            shouldEqualTolerance(int_labels[jj], data.labels(ii)[jj], 0.01);
+        }
+        std::cerr << "done \n";
+    }
+
+/** Learns The Refactored Random Forest with 100 trees 10 times and
+ *  calulates the mean oob error. The distribution of the oob error
+ *  is gaussian as a first approximation. The mean oob error should
+ *  thus be in a 3 sigma neighborhood of the oob error produced by the working
+ *  version of the Random Forest.
+ */
+    void RFoobTest()
+    {
+
+            std::cerr << "RFoobTest(): Learning each Datasets 10 times\n";
+            for(int ii = 0; ii <data.size() ; ii++)
+            {
+                double oob = 0.0;
+                for(int jj = 0; jj < 10; ++jj)
+                {
+                    rf::visitors::OOB_PerTreeError oob_v;
+                    vigra::RandomForest<> RF2(vigra::RandomForestOptions()
+                                                 .tree_count(100));
+
+                     RF2.learn(  data.features(ii), 
+                                 data.labels(ii),
+                                 rf::visitors::create_visitor(oob_v));
+                     oob += oob_v.oobError;
+                }
+                oob = oob/10;
+                oob = oob - data.oobError(ii);
+                oob = oob<0? -oob : oob;
+                std::ostringstream s1;
+                s1  << "Error - mean oobError exceeds 3 sigma bound:  " << oob
+                    << "<-->" <<  data.oobError(ii) << std::endl;
+                vigra::detail::should_impl(oob < 3* data.oobSTD(ii),
+                                           s1.str().c_str(),
+                                           __FILE__,
+                                           __LINE__);
+                std::cerr << "[";
+                for(int ss = 0; ss < ii+1; ++ss)
+                    std::cerr << "#";
+                for(int ss = ii+1; ss < data.size(); ++ss)
+                    std::cerr << " ";
+                std::cerr << "] " << data.names(ii);
+                std::cerr << "\n";
+            }
+            std::cerr << "done!\n";
+    }
+
+
+/**
+        ClassifierTest::RFsetTest():
+    Learns The Refactored Random Forest with 1200 Trees default options and random Seed for the
+    XOR problem. There are 30 distinct Trees possible. This test checks whether all solutions were
+    found.
+    Since there are only 4 samples and 2 features This test should work in the majority of cases.
+**/
+    void RFsetTest()
+    {
+        //xor dataset.
+        double features[] = {0, 0, 1, 1,
+                         0, 1, 0, 1};
+        int    labels[] = {1, 0, 0, 1};
+        std::cerr << "RFsetTest(): Learning 1200 Trees on XOR problem. ";
+        {
+            vigra::SetTestVisitor testVisitor;
+            vigra::RandomForest<> RF2(vigra::RandomForestOptions().tree_count(1200));
+            RF2.learn(  MultiArrayView<2, double>(MultiArrayShape<2>::type(4,2), features),
+                        MultiArrayView<2, int>(MultiArrayShape<2>::type(4,1), labels),
+                        create_visitor(testVisitor),
+                        rf_default(),
+                        rf_default(),
+                        vigra::RandomTT800::global());
+
+        }
+        std::cerr << "DONE!\n";
+        std::cerr << "RFsetTest(): Comparing with Working Version:";
+            diffOnfiles("data/oldsetTest.log", "setTest.log");
+        std::cerr << "DONE!\n\n";
+    }
+
+    void RFonlineTest()
+    {
+        //xor dataset.
+        double features[] = {0, 0, 1, 1,
+                         0, 1, 0, 1};
+        int    labels[] = {1, 0, 0, 1};
+        std::cerr << "RFsetTest(): Learning 1200 Trees on online problem. ";
+        {
+            vigra::SetTestVisitor testVisitor;
+            vigra::RandomForest<> RF2(vigra::RandomForestOptions().tree_count(1200).prepare_online_learning(true));
+            RF2.learn(  MultiArrayView<2, double>(MultiArrayShape<2>::type(4,2), features),
+                        MultiArrayView<2, int>(MultiArrayShape<2>::type(4,1), labels),
+                        create_visitor(testVisitor),
+                        rf_default(),
+                        rf_default(),
+                        vigra::RandomTT800::global());
+            RF2.onlineLearn( MultiArrayView<2, double>(MultiArrayShape<2>::type(4,2), features),
+                        MultiArrayView<2, int>(MultiArrayShape<2>::type(4,1), labels),  4);
+
+        }
+        std::cerr << "DONE!\n";
+    }
+
+/**
+        ClassifierTest::RFnoiseTest():
+    Learns The Refactored Random Forest with 100 Trees default options and random Seed for 64 dimensional
+    unformily distributed samples
+    oob error should be 0.5
+**/
+    void RFnoiseTest()
+    {
+        typedef vigra::MultiArrayShape<2>::type DiffT;
+        vigra::MultiArray<2, double> features(DiffT(50000, 8));
+        vigra::MultiArray<2, size_t> labels(DiffT(50000, 1), size_t(0));
+        labels.subarray(DiffT(25000,0), DiffT(50000,1)).init(1);
+        std::for_each(features.begin(), features.end(),UnaryRandomFunctor());
+        std::cerr << "RFnoiseTest(): Learning 100 Trees on Noise.";
+        vigra::RandomForest<> RF2(vigra::RandomForestOptions().tree_count(100));
+        rf::visitors::OOB_PerTreeError oob_v;
+        RF2.learn(features, labels,create_visitor(oob_v));
+        std::cerr << "DONE!\n";
+        std::cerr << "RFnoiseTest(): Comparing oob with 0.5:";
+        shouldEqualTolerance(oob_v.oobError, 0.5, 0.01);
+        std::cerr << "DONE!\n\n";
+    }
+
+    void RFvariableImportanceTest()
+    {
+        double pina_var_imp[] = 
+        {
+            0.017263, 0.040776, 0.003548, 0.003463, 0.005085, 0.015100, 0.005815, 0.019693, 
+            0.000555, 0.034199, 0.000093, 0.001263, 0.000669, 0.014896, 0.002777, 0.007323, 
+            0.017818, 0.074975, 0.003641, 0.004726, 0.005754, 0.029996, 0.008591, 0.027016, 
+            13.743281, 48.682308, 15.098506, 10.868249, 11.145719, 29.414823, 22.270783, 23.060834 
+        };
+
+        vigra::MultiArrayView<2, double> p_imp(MultiArrayShape<2>::type(8, 4), pina_var_imp);
+        vigra::MultiArray<2, double> zero(p_imp.shape(), 0.0);
+        //Create Test output by Random Forest
+        {
+            std::cerr << "RFvariableImportanceTest(): "
+                            "Learning on Datasets\n";
+
+            int ii = data.size() - 3; // this is the pina_indians dataset
+            {
+                vigra::rf::visitors::VariableImportanceVisitor var_imp;
+
+                vigra::RandomForest<>
+                    RF2(vigra::RandomForestOptions().tree_count(255));
+                RF2.learn(  data.features(ii),
+                            data.labels(ii),
+                            create_visitor(var_imp),
+                            rf_default(),
+                            rf_default(),
+                            vigra::RandomMT19937(1));
+                
+                var_imp.variable_importance_ -= p_imp;
+                for(int jj = 0; jj < p_imp.shape(0);  ++jj)
+                    for(int gg = 0; gg < p_imp.shape(1); ++gg)
+                        shouldEqualTolerance(var_imp
+                                               .variable_importance_(jj, gg)
+                                             , 0.0,0.0001);
+                std::cerr << std::endl;
+                std::cerr << "[";
+                for(int ss = 0; ss < ii+1; ++ss)
+                    std::cerr << "#";
+                for(int ss = ii+1; ss < data.size(); ++ss)
+                    std::cerr << " ";
+                std::cerr << "] " << data.names(ii);
+                std::cerr << "\n";
+            }
+        }
+        std::cerr << std::endl;
+        std::cerr << "DONE!\n\n";
+    }
+
+    void RFwrongLabelTest()
+    {
+        double rawfeatures [] = 
+        {
+            0, 1, 1, 1, 1,
+            0, 1, 1, 1, 1, 
+        };
+        double rawlabels [] =
+        {
+            0, 1, 1, 0, 0
+        };
+        typedef MultiArrayShape<2>::type Shp;
+        MultiArrayView<2, double> features(Shp(5, 2), rawfeatures);
+        MultiArrayView<2, double> labels(Shp(5, 1), rawlabels);
+       
+        RandomForest<> rf(RandomForestOptions().tree_count(10).sample_with_replacement(false));
+        rf.learn(features, labels);
+
+        MultiArray<2, double> prob(Shp(1, 2));
+        rf.predictProbabilities(rowVector(features, 2), prob);
+
+        shouldEqual(prob[0], prob[1]);
+        shouldEqual(prob[1], 0.5);
+
+    }
+#ifdef HasHDF5
+    void should_all(vigra::RandomForest<> & RF, vigra::RandomForest<> & R2)
+    {
+            should(RF.ext_param_ == R2.ext_param_);
+            should(RF.options_ == R2.options_);
+            should(RF.trees_.size() == R2.trees_.size());
+            for(int jj = 0; jj < int(RF.trees_.size()); ++jj)
+            {
+                 should(RF.trees_[jj].topology_ == R2.trees_[jj].topology_);
+
+                 should(RF.trees_[jj].parameters_ == R2.trees_[jj].parameters_);
+
+            }
+            should(RF.options_.tree_count_ == R2.options_.tree_count_);
+    }
+    /** checks whether hdf5 import export is working
+     */
+    void HDF5ImpexTest()
+    {
+
+            for(int ii = 0; ii <data.size() ; ii++)
+            {
+                std::cerr << "Running HDF5 Impex Test\n";
+                std::string filename = data.names(ii) + "_rf.hdf5";
+                std::string filename_b = data.names(ii) + "_b_rf.hdf5";
+                std::remove(filename.c_str());
+                vigra::RandomForest<> RF(vigra::RandomForestOptions()
+                                             .tree_count(100));
+
+                 RF.learn(data.features(ii), data.labels(ii));
+                 rf_export_HDF5(RF, filename);
+
+                 vigra::RandomForest<> RF2;
+                 rf_import_HDF5(RF2, filename);
+                 should_all(RF, RF2);
+
+                 vigra::RandomForest<> RF3;
+                 rf_import_HDF5(RF3, filename);
+                 should_all(RF, RF3);
+
+                 rf_export_HDF5(RF3, filename_b);
+
+                 vigra::RandomForest<> RF4;
+                 rf_import_HDF5(RF4, filename_b);
+                 should_all(RF, RF4);
+
+                 rf_export_HDF5(RF4, filename_b);
+
+                 vigra::RandomForest<> RF5;
+                 rf_import_HDF5(RF5, filename_b);
+                 should_all(RF, RF5);
+
+                 std::cerr << "[";
+                 for(int ss = 0; ss < ii+1; ++ss)
+                     std::cerr << "#";
+                 for(int ss = ii+1; ss < data.size(); ++ss)
+                     std::cerr << " ";
+                 std::cerr << "] " << data.names(ii);
+                 std::cerr << "\n";
+            }
+            std::cerr << "done!\n";
+    }
+#endif
+//};
+
+
+/** checks Regression RF
+ */
+
+    
+void RFRegressionTest()
+{
+    std::cerr << "RFRegressionTest().....\n";
+    typedef MultiArrayShape<2>::type Shp;
+    MultiArray<2, double> features(Shp(100,1));
+    MultiArray<2, double> response(Shp(100,1));
+    //MultiArray<2, double> response(Shp(100,1));
+    
+    //Populate the matrix with one coordinate
+    double x0= -50;
+    double dx=1;
+    for (int i=0;i<features.shape(0);++i){
+        features(i,0)=x0;
+        x0=x0+dx;
+    }
+    
+    //Popolate the matrix of labels (should not be called labels)
+    // linear function
+    
+    double a= 1;
+    double q= 0.0;
+    
+    for (int i=0;i<response.shape(0);++i){
+            response(i,0)=features(i,0)*a+q;
+            x0=x0+dx;
+    
+    }
+
+    
+    
+    vigra::RegressionSplit regsplit;
+    
+    //split class
+    vigra::RandomForest<double, RegressionTag> rf(vigra::RandomForestOptions().tree_count(1000));
+    //vigra::RandomForest<double, RegressionTag > rf(vigra::RandomForestOptions().tree_count(10));
+    vigra::RegressionSplit rsplit;
+    //vigra::GiniRidgeSplit rsplit;
+    rf.learn(features, response, rf_default(),rsplit);
+    
+    MultiArray<2, double> predicted(Shp(100,1));
+    
+    
+    rf.predictRaw(features,predicted);
+    //std::cerr << "DONE\n";
+    
+
+    for (int i=0; i<predicted.shape(0); ++i) {
+        shouldEqualTolerance(response(i, 0), predicted(i, 0), 1.0);
+    }
+        
+    std::cerr << "done!\n";
+        
+}
+
+    
+    void MultidimensionalRFRegressionTest()
+    {
+        std::cerr << "MultidimensioalRFRegressionTest().....\n";
+        typedef MultiArrayShape<2>::type Shp;
+        MultiArray<2, double> features(Shp(100,5));
+        MultiArray<2, double> response(Shp(100,5));
+        //MultiArray<2, double> response(Shp(100,1));
+        
+        //Populate the matrix with one coordinate
+        double x0= -50;
+        double dx=1;
+        for(int j = 0; j < 5; ++ j)
+        for (int i=0;i<features.shape(0);++i){
+            features(i,j)=x0;
+            x0=x0+dx;
+        }
+        
+        //Popolate the matrix of labels (should not be called labels)
+        // linear function
+        
+        double a= 1;
+        double q= 0.0;
+        
+        for(int j = 0; j < 5; ++ j)
+        for (int i=0;i<response.shape(0);++i){
+            response(i,j)=features(i,j)*a+q;
+            x0=x0+dx;
+            
+        }
+        
+        
+        
+        vigra::RegressionSplit regsplit;
+        
+        //split class
+        vigra::RandomForest<double, RegressionTag> rf(vigra::RandomForestOptions().tree_count(1000));
+        //vigra::RandomForest<double, RegressionTag > rf(vigra::RandomForestOptions().tree_count(10));
+        vigra::RegressionSplit rsplit;
+        //vigra::GiniRidgeSplit rsplit;
+        rf.learn(features, response, rf_default(),rsplit);
+        
+        MultiArray<2, double> predicted(Shp(100,5));
+        
+        
+        rf.predictRaw(features,predicted);
+        //std::cerr << "DONE\n";
+        //
+        for(int j = 0; j < 5; ++ j)
+        for (int i=0; i<predicted.shape(0); ++i) {
+            //std::cout << predicted(i, j) << std::endl;
+            shouldEqualTolerance(response(i, j), predicted(i, j), 1.0);
+        }
+        
+        std::cerr << "done!\n";
+        
+    }
+    
+    
+    
+    
+    
+};
+
+
+
+
+
+
+
+struct ClassifierTestSuite
+: public vigra::test_suite
+{
+    ClassifierTestSuite()
+    : vigra::test_suite("ClassifierTestSuite")
+    {
+        add( testCase( &ClassifierTest::RFdefaultTest));
+        add( testCase( &ClassifierTest::RFRegressionTest));
+        add( testCase( &ClassifierTest::MultidimensionalRFRegressionTest));
+#ifndef FAST
+        add( testCase( &ClassifierTest::RFsetTest));
+        add( testCase( &ClassifierTest::RFonlineTest));
+        add( testCase( &ClassifierTest::RFoobTest));
+        add( testCase( &ClassifierTest::RFnoiseTest));
+        add( testCase( &ClassifierTest::RFvariableImportanceTest));
+        add( testCase( &ClassifierTest::RF_NanCheck));
+        add( testCase( &ClassifierTest::RF_InfCheck));
+        add( testCase( &ClassifierTest::RF_SpliceTest));
+        add( testCase( &ClassifierTest::RF_AlgorithmTest));
+#endif
+        add( testCase( &ClassifierTest::RFresponseTest));
+        
+        add( testCase( &ClassifierTest::RFridgeRegressionTest));
+        add( testCase( &ClassifierTest::RFSplitFunctorTest));
+#ifdef HasHDF5
+        add( testCase( &ClassifierTest::HDF5ImpexTest));
+#endif
+         
+    }
+};
+
+
+#if CLASSIFIER_TEST
+int main(int argc, char ** argv)
+{
+    ClassifierTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+    return (failed != 0);
+}
+#endif
+
+#if CROSSVAL
+int main(int argc, char ** argv)
+{
+    RF_Test_Training_Data data;
+
+    std::vector<size_t> indices;
+    for(int ii = 1; ii < argc; ++ii)
+    {
+        indices.push_back(atoi(argv[ii]));
+    }
+           //int ii = 1;
+    for(int ii = 0; ii < data.size(); ii++)
+    {
+        if(indices.size() != 0)
+            if(find(indices.begin(), indices.end(), ii) == indices.end())
+                continue;
+        MultiArray<3, double> err(MultiArrayShape<3>::type(51, 4, 5));
+        for(int ss = 0; ss <= 50; ++ss)
+        {
+            for(int jj = 0; jj < 5; ++jj)
+            {
+                vigra::RandomForest<int> RF2(vigra::RandomForestOptions().setTreeCount(255).trainingSetSizeProportional(double(ss)*0.02));
+                vigra::RandomForest<int> RF(vigra::RandomForestOptions().setTreeCount(255).trainingSetSizeProportional(double(ss)*0.02).sampleWithReplacement(false));
+                TinyVector<double, 4> vc2 = crossvalidate( data.features(ii),
+                                                         data.labels(ii),
+                                                         RF2);
+                TinyVector<double, 4> vc = crossvalidate( data.features(ii),
+                                                         data.labels(ii),
+                                                         RF);
+                err(ss,0 ,jj) = vc[0];
+                err(ss,1 ,jj) = vc[3];
+                err(ss,2 ,jj) = vc2[0];
+                err(ss,3 ,jj) = vc2[3];
+                std::cerr << jj << " " << ss << " " << ii << std::endl;
+            }
+        }
+        std::string name = "gini_bootstrap_" + data.names(ii) + ".hdf5";
+        writeToHDF5File(name.c_str(), "results", err);
+    }
+
+}
+#endif
+
+#if HDF5
+int main(int argc, char ** argv)
+{
+    RF_Test_Training_Data data;
+
+    for(int ii = 0; ii < data.size(); ii++)
+    {
+        H5_dataset set_t(data.names(ii)+std::string(".h5"));
+        set_t.set_source("1","features", data.features(ii));
+        set_t.set_source("1","labels", data.labels(ii));
+    }
+
+    for(int ii = 0; ii < data.size(); ++ii)
+    {
+        H5_dataset set_t(data.names(ii)+std::string(".h5"));
+        std::set<std::string>   grpses = set_t.get_groups();
+        grpses.erase("labels");
+        std::string a = "labels";
+        std::set<std::string>  srces = set_t.get_sources();
+        MultiArray<2, double> feats(set_t.shape(srces.begin(), srces.end(), grpses.begin(), grpses.end()));
+        MultiArray<2, int> labels(set_t.shape(srces.begin(), srces.end(), &a, &a +1));
+        set_t.get_source("1","features", feats);
+        set_t.get_source("1","labels", labels);
+        std::cerr << (feats == data.features(ii)) <<    std::endl;
+        std::cerr << (labels == data.labels(ii)) << std::endl;
+    }
+}
+#endif
diff --git a/test/classifier/test_visitors.hxx b/test/classifier/test_visitors.hxx
new file mode 100644
index 0000000..2213272
--- /dev/null
+++ b/test/classifier/test_visitors.hxx
@@ -0,0 +1,241 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2008-2009 by  Ullrich Koethe and Rahul Nair         */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+#ifndef VIGRA_RF_TEST_VISITOR_HXX
+#define VIGRA_RF_TEST_VISITOR_HXX
+
+#include <vigra/random_forest.hxx>
+#include <fstream>
+#include <sstream>
+namespace vigra
+{
+
+    // create log output (as a text file) for debugging/testing
+class TestVisitor: public rf::visitors::VisitorBase
+{
+
+    public:
+    std::ofstream fout;
+    TestVisitor(std::string output = std::string("RandomForestNodeTest.log"))
+    :
+        fout(output.c_str())
+    {    }
+
+    //TODO split must be const
+    template<class Tree, class Split, class Region, class Feature_t, class Label_t>
+    void visit_after_split( Tree          & tree, 
+                            Split         & split,
+                            Region        & parent,
+                            Region        & leftChild,
+                            Region        & rightChild,
+                            Feature_t     & features,
+                            Label_t       & labels)
+    {
+        if(split.createNode().typeID() == i_ThresholdNode)
+        {
+            std::ostringstream s1;
+            s1.precision(10);
+            s1.setf(std::ios::fixed,std::ios::floatfield);
+            s1 << split.minGini();
+            fout   << "minGini: " << s1.str().substr(0, s1.str().size()-4) << " - " << split.bestSplitColumn() << std::endl;
+//            fout   << "Threshold: " << *(split.node_.parameters_begin() +1) << std::endl;
+            fout   << "Region.size: "      << parent.size() << std::endl;
+            fout   << "LeftChild.size: "  << leftChild.size() << std::endl;
+            fout   << "LeftChild.ClassCounts: ";
+            for(int ii = 0; ii < split.classCount(); ++ii)
+                fout << leftChild.classCounts()[ii] << " " ;
+            fout   << std::endl;
+            fout   << "RightChild.size: "   << rightChild.size() << std::endl;
+            fout   << "RightChild.ClassCounts: ";
+            for(int ii = 0; ii < split.classCount(); ++ii)
+                fout << rightChild.classCounts()[ii] << " " ;
+            fout   << std::endl;
+            fout   << std::endl;
+        }
+    }
+
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(    RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {
+        fout << std::endl << std::endl << "Tree Number: " << index << " finished." << std::endl << std::endl;
+    }
+
+    ~TestVisitor()
+    {
+        fout.close();
+    }
+};
+
+    // test that all possible trees are created when there are only 4 samples
+class SetTestVisitor: public rf::visitors::VisitorBase
+{
+    public:
+    std::ostringstream sout;
+    std::set<std::string> treesset;
+
+
+    template<class Tree, class Split, class Region, class Feature_t, class Label_t>
+    void visit_after_split( Tree          & tree, 
+                            Split         & split,
+                            Region        & parent,
+                            Region        & leftChild,
+                            Region        & rightChild,
+                            Feature_t     & features,
+                            Label_t       & labels)
+    {
+        if(split.createNode().typeID() == i_ThresholdNode)
+        {
+            sout   << "minGini: " << split.minGini() << " - " << split.bestSplitColumn() << std::endl;
+            sout   << "Region.size: "      << parent.size() << std::endl;
+            sout   << "LeftChild.size: "  << leftChild.size() << std::endl;
+            sout   << "LeftChild.ClassCounts: ";
+            for(int ii = 0; ii < split.classCount(); ++ii)
+                sout << leftChild.classCounts()[ii] << " " ;
+            sout   << std::endl;
+            sout   << "RightChild.size: "   << rightChild.size() << std::endl;
+            sout   << "RightChild.ClassCounts: ";
+            for(int ii = 0; ii < split.classCount(); ++ii)
+                sout << rightChild.classCounts()[ii] << " " ;
+            sout   << std::endl;
+            sout   << std::endl;
+        }
+    }
+
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(    RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {
+        treesset.insert(sout.str());
+        sout.str(std::string());
+    }
+
+    template<class RF, class PR>
+    void visit_at_end(RF & rf, PR & pr)
+    {
+        std::ofstream fout("setTest.log");
+        std::set<std::string>::iterator iter;
+        int k = 0;
+        for(iter = treesset.begin(); iter != treesset.end(); ++iter)
+        {
+            fout << *iter;
+            fout << std::endl << std::endl << "Tree Number: " << k << " finished." << std::endl << std::endl;
+            ++k;
+        }
+        fout.close();
+    }
+};
+
+    // comprehensive debug output
+template <class T1, class C1, class T2, class C2>
+class AllOutputVisitor: public rf::visitors::VisitorBase
+{
+    MultiArrayView<2, T1, C1> * features;
+    MultiArrayView<2, T2, C2> * labels;
+
+
+    public:
+    std::ofstream fout;
+    AllOutputVisitor(std::string output = std::string("RandomForestNodeTest.log"))
+    :
+        fout(output.c_str())
+    {    }
+
+    //TODO split must be const
+    template<class Tree, class Split, class Region, class Feature_t, class Label_t>
+    void visit_after_split( Tree          & tree, 
+                            Split         & split,
+                            Region        & parent,
+                            Region        & leftChild,
+                            Region        & rightChild,
+                            Feature_t     & features,
+                            Label_t       & labels)
+    {
+        if(split.createNode().typeID() == i_ThresholdNode)
+        {
+            fout   << "minGini: " << split.minGini << " - " << split.bestSplitColumn << std::endl;
+            fout   << "Threshold: " << *(split.node_.parameters_begin() +1) << std::endl;
+            fout   << "Region.size: "      << parent.size() << std::endl;
+            for(int ii = 0 ; ii < parent.size(); ++ii)
+            {
+                fout << "(" << parent[ii] << ", " << (*labels)[parent[ii]] << ", " << (*features)(parent[ii],split.bestSplitColumn) << ") ";
+                if(ii%4 == 0)fout << std::endl;
+            }
+            fout << std::endl;
+            fout   << "LeftChild.size: "  << leftChild.size() << std::endl;
+            fout   << "LeftChild.ClassCounts: ";
+            for(int ii = 0; ii < split.classCount(); ++ii)
+                fout << leftChild.classCounts()[ii] << " " ;
+            fout   << std::endl;
+            for(int ii = 0 ; ii < leftChild.size(); ++ii)
+            {
+                fout << "(" << leftChild[ii] << ", " << (*labels)[leftChild[ii]] << ", " << (*features)(leftChild[ii],split.bestSplitColumn) << ") ";
+                if(ii%4 == 0)fout << std::endl;
+            }
+            fout << std::endl;
+            fout   << "RightChild.size: "   << rightChild.size() << std::endl;
+            fout   << "RightChild.ClassCounts: ";
+            for(int ii = 0; ii < split.classCount(); ++ii)
+                fout << rightChild.classCounts()[ii] << " " ;
+            fout   << std::endl;
+            for(int ii = 0 ; ii < rightChild.size(); ++ii)
+            {
+            fout << "(" << rightChild[ii] << ", " << (*labels)[rightChild[ii]] << ", " << (*features)(rightChild[ii],split.bestSplitColumn) << ") ";
+                if(ii%4 == 0)fout << std::endl;
+            }
+            fout   << std::endl;
+        }
+    }
+
+    template<class RF, class PR, class SM, class ST>
+    void visit_after_tree(    RF& rf, PR & pr,  SM & sm, ST & st, int index)
+    {
+        fout << std::endl << std::endl << "Tree Number: " << index << " finished." << std::endl << std::endl;
+    }
+
+    void setDataSource(MultiArrayView<2, T1, C1> * feat, MultiArrayView<2, T2, C2> * label)
+    {
+        features = feat;
+        labels = label;
+    }
+
+
+    ~AllOutputVisitor()
+    {
+        fout.close();
+    }
+};
+
+
+} // namespace vigra
+
+#endif //VIGRA_RF_TEST_VISITOR_HXX
diff --git a/test/colorspaces/CMakeLists.txt b/test/colorspaces/CMakeLists.txt
new file mode 100644
index 0000000..5ce2632
--- /dev/null
+++ b/test/colorspaces/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_colorspaces test.cxx)
diff --git a/test/colorspaces/test.cxx b/test/colorspaces/test.cxx
new file mode 100755
index 0000000..929fc1b
--- /dev/null
+++ b/test/colorspaces/test.cxx
@@ -0,0 +1,480 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <algorithm>
+#include <iostream>
+#include "vigra/unittest.hxx"
+#include "vigra/colorconversions.hxx"
+
+using namespace vigra;
+
+struct ColorConversionsTest
+{
+    typedef vigra::RGBValue<double> RGB;
+    typedef vigra::TinyVector<double, 3> Color;
+    typedef vigra::TinyVector<float, 3> (*PolarFct)(Color const &);
+    enum { count = 15 };
+    RGB black, red, green, blue, cyan, magenta, 
+         yellow, white, gray, orange, violet, bordeaux, brown, bluegreen, darkgreen;
+    Color original[count], transformed[count], back[count];
+
+#if 0
+    tblack, tred, tgreen, tblue, tcyan, tmagenta, 
+         tyellow, twhite, tgray, torange, tviolet, tbordeaux, tbrown, tbluegreen;
+    FRGB bblack, bred, bgreen, bblue, bcyan, bmagenta, 
+         byellow, bwhite, bgray, borange, bviolet, bbordeaux, bbrown, bbluegreen;
+#endif /* #if 0 */
+
+    
+    ColorConversionsTest()
+    : black(0.0,0.0,0.0), 
+      red(255.0, 0.0, 0.0), 
+      green(0.0, 255.0, 0.0), 
+      blue(0.0, 0.0, 255.0), 
+      cyan(0.0, 255.0, 255.0), 
+      magenta(255.0, 0.0, 255.0), 
+      yellow(255.0, 255.0, 0.0), 
+      white(255.0, 255.0, 255.0), 
+      gray(128.0, 128.0, 128.0),
+      orange(255.0, 150.0, 0.0),
+      violet(200.0, 0.0, 255.0),
+      bordeaux(255.0, 0.0, 140.0),
+      brown(180.0, 90.0, 0.0),
+      bluegreen(0.0, 160.0, 178.0),
+      darkgreen(90.0, 170.0, 100.0)
+    {
+        original[0] = black;
+        original[1] = red;
+        original[2] = green;
+        original[3] = blue;
+        original[4] = cyan;
+        original[5] = magenta;
+        original[6] = yellow;
+        original[7] = white;
+        original[8] = gray;
+        original[9] = orange;
+        original[10] = violet;
+        original[11] = bordeaux;
+        original[12] = brown;
+        original[13] = bluegreen;
+        original[14] = darkgreen;
+    }
+   
+    static bool equalColors(Color const & c1, Color const & c2, double epsilon = 0.001)
+    {
+        return (c1 - c2).magnitude() < epsilon;
+    }
+    
+    static bool equalColors(Color * c1, Color * c1end, Color * c2, double epsilon = 0.001)
+    {
+        for(; c1 != c1end; ++c1, ++c2)
+        {
+            if(!equalColors(*c1, *c2, epsilon))
+                return false;
+        }
+        return true;
+    }
+    
+    static bool checkLimits(Color * c, Color * cend, 
+               Color const & min, Color const & max, double epsilon = 0.001)
+    {
+        for(; c != cend; ++c)
+        {
+            for(int i=0; i<3; ++i)
+                if(min[i] - (*c)[i] > epsilon || (*c)[i] - max[i] > epsilon)
+                    return false;
+        }
+        return true;
+    }
+    
+    static bool checkGray(Color const & c, double epsilon = 0.001)
+    {
+        return VIGRA_CSTD::fabs(c[1]) < epsilon && VIGRA_CSTD::fabs(c[2]) < epsilon;
+    }
+    
+    static void printColor(Color const & c)
+    {
+        std::cerr << "[" << c[0] << ", " << c[1] << ", " << c[2] << "]\n";
+    }
+    
+    static void printColors(Color * c, Color * cend)
+    {
+        for(; c != cend; ++c)
+        {
+            printColor(*c);
+        }
+    }
+    
+    void testRGBPrime2RGB()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2RGBFunctor<double, double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::RGB2RGBPrimeFunctor<double, double>());
+        
+        should(checkLimits(transformed, transformed+count, RGB(0.0,0.0,0.0), RGB(255.0,255.0,255.0)));
+        should(equalColors(original, original+count, back));
+        should(equalColors(transformed[count-1], RGB(25.202, 103.568, 31.8506)));
+    }
+    
+    void testsRGB2RGB()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::sRGB2RGBFunctor<double, double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::RGB2sRGBFunctor<double, double>());
+        
+        should(checkLimits(transformed, transformed+count, RGB(0.0,0.0,0.0), RGB(255.0,255.0,255.0)));
+        should(equalColors(original, original+count, back));
+        should(equalColors(transformed[count-1], RGB(26.0716, 102.504, 32.4966)));
+    }
+    
+    void testRGB2XYZ()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGB2XYZFunctor<double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::XYZ2RGBFunctor<double>());
+        
+        should(equalColors(original, original+count, back));
+        should(equalColors(transformed[count-1], RGB(0.454712, 0.580135, 0.458924)));
+    }
+    
+    void testRGBPrime2XYZ()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2XYZFunctor<double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::XYZ2RGBPrimeFunctor<double>());
+        
+        should(equalColors(original, original+count, back, 0.01));
+        should(equalColors(transformed[count-1], RGB(0.20853, 0.320495, 0.169008)));
+    }
+    
+    void testRGB2Lab()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGB2LabFunctor<double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::Lab2RGBFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,-86.1813,-107.862), RGB(100.0,98.2352,94.4758)));
+        should(equalColors(original, original+count, back));
+        should(checkGray(transformed[0]));
+        should(checkGray(transformed[7]));
+        should(checkGray(transformed[8]));
+        should(equalColors(transformed[count-1], RGB(80.7463, -25.9546, 16.8469)));
+    }    
+    
+    void testRGBPrime2Lab()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2LabFunctor<double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::Lab2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,-86.1813,-107.862), RGB(100.0,98.2352,94.4758)));
+        should(equalColors(original, original+count, back, 0.01));
+        should(checkGray(transformed[0]));
+        should(checkGray(transformed[7]));
+        should(checkGray(transformed[8]));
+        should(equalColors(transformed[count-1], RGB(63.3838, -40.6056, 29.3815)));
+    }    
+    
+    void testRGB2Luv()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGB2LuvFunctor<double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::Luv2RGBFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,-83.077,-134.101), RGB(100.0,175.015,107.393)));
+        should(equalColors(original, original+count, back));
+        should(checkGray(transformed[0]));
+        should(checkGray(transformed[7]));
+        should(checkGray(transformed[8]));
+        should(equalColors(transformed[count-1], RGB(80.7463, -26.4172, 28.6933)));
+    }
+    
+    void testRGBPrime2Luv()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2LuvFunctor<double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::Luv2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,-83.077,-134.101), RGB(100.0,175.015,107.393)));
+        should(equalColors(original, original+count, back, 0.01));
+        should(checkGray(transformed[0]));
+        should(checkGray(transformed[7]));
+        should(checkGray(transformed[8]));
+        should(equalColors(transformed[count-1], RGB(63.3838, -38.5724, 44.4313)));
+    }
+    
+    void testRGBPrime2YPrimePbPr()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2YPrimePbPrFunctor<double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::YPrimePbPr2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,-0.5,-0.5), RGB(1.0,0.5,0.5)));
+        should(equalColors(original, original+count, back));
+        should(checkGray(transformed[0]));
+        should(checkGray(transformed[7]));
+        should(checkGray(transformed[8]));
+        should(equalColors(transformed[count-1], RGB(0.541569, -0.0843182, -0.134542)));
+    }
+    
+    void testRGBPrime2YPrimeCbCr()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2YPrimeCbCrFunctor<double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::YPrimeCbCr2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(16.0,16.0,16.0), RGB(235.0,240.0,240.0)));
+        should(equalColors(original, original+count, back));
+        should(checkGray(transformed[0]-RGB(0.0,128.0,128.0)));
+        should(checkGray(transformed[7]-RGB(0.0,128.0,128.0)));
+        should(checkGray(transformed[8]-RGB(0.0,128.0,128.0)));
+        should(equalColors(transformed[count-1], RGB(134.604, 109.113, 97.8627)));
+    }
+    
+    void testRGBPrime2YPrimeIQ()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2YPrimeIQFunctor<double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::YPrimeIQ2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,-0.596,-0.523), RGB(1.0,0.596,0.523)));
+        should(equalColors(original, original+count, back));
+        should(checkGray(transformed[0]));
+        should(checkGray(transformed[7]));
+        should(checkGray(transformed[8]));
+        should(equalColors(transformed[count-1], RGB(0.541569, -0.0985882, -0.151882)));
+    }
+    
+    void testRGBPrime2YPrimeUV()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2YPrimeUVFunctor<double>());
+        std::transform(transformed, transformed+count, back, 
+                        vigra::YPrimeUV2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,-0.436,-0.615), RGB(1.0,0.436,0.615)));
+        should(equalColors(original, original+count, back));
+        should(checkGray(transformed[0]));
+        should(checkGray(transformed[7]));
+        should(checkGray(transformed[8]));
+        should(equalColors(transformed[count-1], RGB(0.541569, -0.0735254, -0.165463)));
+    }
+    
+    void testLabPolar()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2LabFunctor<double>());
+        std::transform(transformed, transformed+count, transformed, (PolarFct)&vigra::lab2Polar);
+        std::transform(transformed, transformed+count, back, (PolarFct)&vigra::polar2Lab);
+        std::transform(back, back+count, back,
+                        vigra::Lab2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,0.0,0.0), RGB(360.0,1.0, 1.0)));
+        should(equalColors(original, original+count, back, 0.3));
+        
+        should(transformed[0][2] < 0.001);
+        should(transformed[7][2] < 0.001);
+        should(transformed[8][2] < 0.001);
+        should(transformed[1][0] < 0.001 || transformed[1][0] > 359.999);
+        
+        should(equalColors(transformed[count-1], RGB(104.113, 0.633838, 0.374569)));
+    }
+    
+    void testLuvPolar()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2LuvFunctor<double>());
+        std::transform(transformed, transformed+count, transformed, (PolarFct)&vigra::luv2Polar);
+        std::transform(transformed, transformed+count, back, (PolarFct)&vigra::polar2Luv);
+        std::transform(back, back+count, back,
+                        vigra::Luv2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,0.0,0.0), RGB(360.0,1.0, 1.0)));
+        should(equalColors(original, original+count, back, 0.3));
+        
+        should(transformed[0][2] < 0.001);
+        should(transformed[7][2] < 0.001);
+        should(transformed[8][2] < 0.001);
+        should(transformed[1][0] < 0.001 || transformed[1][0] > 359.999);
+        
+        should(equalColors(transformed[count-1], RGB(118.79, 0.633838, 0.328633)));
+    }
+    
+    void testYPrimePbPrPolar()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2YPrimePbPrFunctor<double>());
+        std::transform(transformed, transformed+count, transformed, (PolarFct)&vigra::yPrimePbPr2Polar);
+        std::transform(transformed, transformed+count, back, (PolarFct)&vigra::polar2YPrimePbPr);
+        std::transform(back, back+count, back,
+                        vigra::YPrimePbPr2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,0.0,0.0), RGB(360.0,1.0, 1.0)));
+        should(equalColors(original, original+count, back, 0.3));
+        
+        should(transformed[0][2] < 0.001);
+        should(transformed[7][2] < 0.001);
+        should(transformed[8][2] < 0.001);
+        should(transformed[1][0] < 0.001 || transformed[1][0] > 359.999);
+        
+        should(equalColors(transformed[count-1], RGB(129.276, 0.541569, 0.297403)));
+    }
+    
+    void testYPrimeCbCrPolar()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2YPrimeCbCrFunctor<double>());
+        std::transform(transformed, transformed+count, transformed, (PolarFct)&vigra::yPrimeCbCr2Polar);
+        std::transform(transformed, transformed+count, back, (PolarFct)&vigra::polar2YPrimeCbCr);
+        std::transform(back, back+count, back,
+                        vigra::YPrimeCbCr2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,0.0,0.0), RGB(360.0,1.0, 1.0)));
+        should(equalColors(original, original+count, back, 0.3));
+        
+        should(transformed[0][2] < 0.001);
+        should(transformed[7][2] < 0.001);
+        should(transformed[8][2] < 0.001);
+        should(transformed[1][0] < 0.001 || transformed[1][0] > 359.999);
+        
+        should(equalColors(transformed[count-1], RGB(129.276, 0.541569, 0.297403)));
+    }
+    
+    void testYPrimeIQPolar()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2YPrimeIQFunctor<double>());
+        std::transform(transformed, transformed+count, transformed, (PolarFct)&vigra::yPrimeIQ2Polar);
+        std::transform(transformed, transformed+count, back, (PolarFct)&vigra::polar2YPrimeIQ);
+        std::transform(back, back+count, back,
+                        vigra::YPrimeIQ2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,0.0,0.0), RGB(360.0,1.0, 1.0)));
+        should(equalColors(original, original+count, back, 0.3));
+        
+        should(transformed[0][2] < 0.001);
+        should(transformed[7][2] < 0.001);
+        should(transformed[8][2] < 0.001);
+        should(transformed[1][0] < 0.001 || transformed[1][0] > 359.999);
+        
+        should(equalColors(transformed[count-1], RGB(142.569, 0.541569, 0.286246)));
+    }
+    
+    void testYPrimeUVPolar()
+    {
+        std::transform(original, original+count, transformed, 
+                        vigra::RGBPrime2YPrimeUVFunctor<double>());
+        std::transform(transformed, transformed+count, transformed, (PolarFct)&vigra::yPrimeUV2Polar);
+        std::transform(transformed, transformed+count, back, (PolarFct)&vigra::polar2YPrimeUV);
+        std::transform(back, back+count, back,
+                        vigra::YPrimeUV2RGBPrimeFunctor<double>());
+        
+        should(checkLimits(transformed, transformed+count, 
+               RGB(0.0,0.0,0.0), RGB(360.0,1.0, 1.0)));
+        should(equalColors(original, original+count, back, 0.3));
+
+        should(transformed[0][2] < 0.001);
+        should(transformed[7][2] < 0.001);
+        should(transformed[8][2] < 0.001);
+        should(transformed[1][0] < 0.001 || transformed[1][0] > 359.999);
+        
+        should(equalColors(transformed[count-1], RGB(142.585, 0.541569, 0.286346)));
+    }
+};
+
+
+struct ColorConversionsTestSuite
+: public vigra::test_suite
+{
+                           
+    ColorConversionsTestSuite()
+    : vigra::test_suite("ColorConversionsTest")
+    {
+        add( testCase(&ColorConversionsTest::testRGBPrime2RGB));
+        add( testCase(&ColorConversionsTest::testsRGB2RGB));
+        add( testCase(&ColorConversionsTest::testRGB2XYZ));
+        add( testCase(&ColorConversionsTest::testRGBPrime2XYZ));
+        add( testCase(&ColorConversionsTest::testRGB2Lab));
+        add( testCase(&ColorConversionsTest::testRGBPrime2Lab));
+        add( testCase(&ColorConversionsTest::testRGB2Luv));
+        add( testCase(&ColorConversionsTest::testRGBPrime2Luv));
+        add( testCase(&ColorConversionsTest::testRGBPrime2YPrimePbPr));
+        add( testCase(&ColorConversionsTest::testRGBPrime2YPrimeCbCr));
+        add( testCase(&ColorConversionsTest::testRGBPrime2YPrimeIQ));
+        add( testCase(&ColorConversionsTest::testRGBPrime2YPrimeUV));
+        add( testCase(&ColorConversionsTest::testLabPolar));
+        add( testCase(&ColorConversionsTest::testLuvPolar));
+        add( testCase(&ColorConversionsTest::testYPrimePbPrPolar));
+        add( testCase(&ColorConversionsTest::testYPrimeCbCrPolar));
+        add( testCase(&ColorConversionsTest::testYPrimeIQPolar));
+        add( testCase(&ColorConversionsTest::testYPrimeUVPolar));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    ColorConversionsTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+
+    return (failed != 0);
+}
+
diff --git a/test/convolution/CMakeLists.txt b/test/convolution/CMakeLists.txt
new file mode 100644
index 0000000..8adb8a4
--- /dev/null
+++ b/test/convolution/CMakeLists.txt
@@ -0,0 +1,3 @@
+VIGRA_ADD_TEST(test_convolution test.cxx LIBRARIES vigraimpex)
+
+VIGRA_COPY_TEST_DATA(lenna128.xv lenna_simple_sharpening_orig.xv lenna_gaussian_sharpening_orig.xv lenna128sepgrad.xv lennahessxx.xv lennastxx.xv lenna128recgrad.xv lenna128nonlinear.xv resampling.xv lennahessyy.xv lennastyy.xv lennahessxy.xv lennastxy.xv lenna128rgb.xv lenna128rgbsepgrad.xv lenna_level-2.xv lenna_level-1.xv lenna_level1.xv lenna_level2.xv lenna_levellap0.xv lenna_levellap1.xv lenna_levellap2.xv lennargbst.xv)
diff --git a/test/convolution/coscot.xv b/test/convolution/coscot.xv
new file mode 100755
index 0000000..bf7f949
Binary files /dev/null and b/test/convolution/coscot.xv differ
diff --git a/test/convolution/lenna128.xv b/test/convolution/lenna128.xv
new file mode 100644
index 0000000..11782b2
Binary files /dev/null and b/test/convolution/lenna128.xv differ
diff --git a/test/convolution/lenna128nonlinear.xv b/test/convolution/lenna128nonlinear.xv
new file mode 100644
index 0000000..559e83b
Binary files /dev/null and b/test/convolution/lenna128nonlinear.xv differ
diff --git a/test/convolution/lenna128recgrad.xv b/test/convolution/lenna128recgrad.xv
new file mode 100644
index 0000000..2159ed5
Binary files /dev/null and b/test/convolution/lenna128recgrad.xv differ
diff --git a/test/convolution/lenna128rgb.xv b/test/convolution/lenna128rgb.xv
new file mode 100644
index 0000000..44dc30b
Binary files /dev/null and b/test/convolution/lenna128rgb.xv differ
diff --git a/test/convolution/lenna128rgbsepgrad.xv b/test/convolution/lenna128rgbsepgrad.xv
new file mode 100644
index 0000000..d000c3c
Binary files /dev/null and b/test/convolution/lenna128rgbsepgrad.xv differ
diff --git a/test/convolution/lenna128sepgrad.xv b/test/convolution/lenna128sepgrad.xv
new file mode 100644
index 0000000..fcf0d76
Binary files /dev/null and b/test/convolution/lenna128sepgrad.xv differ
diff --git a/test/convolution/lenna_gaussian_sharpening_orig.xv b/test/convolution/lenna_gaussian_sharpening_orig.xv
new file mode 100644
index 0000000..e6eada7
Binary files /dev/null and b/test/convolution/lenna_gaussian_sharpening_orig.xv differ
diff --git a/test/convolution/lenna_level-1.xv b/test/convolution/lenna_level-1.xv
new file mode 100755
index 0000000..09d53cd
Binary files /dev/null and b/test/convolution/lenna_level-1.xv differ
diff --git a/test/convolution/lenna_level-2.xv b/test/convolution/lenna_level-2.xv
new file mode 100755
index 0000000..263b8de
Binary files /dev/null and b/test/convolution/lenna_level-2.xv differ
diff --git a/test/convolution/lenna_level1.xv b/test/convolution/lenna_level1.xv
new file mode 100755
index 0000000..ad3023a
Binary files /dev/null and b/test/convolution/lenna_level1.xv differ
diff --git a/test/convolution/lenna_level2.xv b/test/convolution/lenna_level2.xv
new file mode 100755
index 0000000..c4f12a1
Binary files /dev/null and b/test/convolution/lenna_level2.xv differ
diff --git a/test/convolution/lenna_levellap0.xv b/test/convolution/lenna_levellap0.xv
new file mode 100755
index 0000000..3ad02c9
Binary files /dev/null and b/test/convolution/lenna_levellap0.xv differ
diff --git a/test/convolution/lenna_levellap1.xv b/test/convolution/lenna_levellap1.xv
new file mode 100755
index 0000000..56c3dd4
Binary files /dev/null and b/test/convolution/lenna_levellap1.xv differ
diff --git a/test/convolution/lenna_levellap2.xv b/test/convolution/lenna_levellap2.xv
new file mode 100755
index 0000000..7a6518c
Binary files /dev/null and b/test/convolution/lenna_levellap2.xv differ
diff --git a/test/convolution/lenna_simple_sharpening_orig.xv b/test/convolution/lenna_simple_sharpening_orig.xv
new file mode 100644
index 0000000..1437a96
Binary files /dev/null and b/test/convolution/lenna_simple_sharpening_orig.xv differ
diff --git a/test/convolution/lennahessxx.xv b/test/convolution/lennahessxx.xv
new file mode 100644
index 0000000..b1be4b4
Binary files /dev/null and b/test/convolution/lennahessxx.xv differ
diff --git a/test/convolution/lennahessxy.xv b/test/convolution/lennahessxy.xv
new file mode 100644
index 0000000..b5d39a9
Binary files /dev/null and b/test/convolution/lennahessxy.xv differ
diff --git a/test/convolution/lennahessyy.xv b/test/convolution/lennahessyy.xv
new file mode 100644
index 0000000..424ba0e
Binary files /dev/null and b/test/convolution/lennahessyy.xv differ
diff --git a/test/convolution/lennargbst.xv b/test/convolution/lennargbst.xv
new file mode 100644
index 0000000..152a0b5
Binary files /dev/null and b/test/convolution/lennargbst.xv differ
diff --git a/test/convolution/lennastxx.xv b/test/convolution/lennastxx.xv
new file mode 100644
index 0000000..9e8ec68
Binary files /dev/null and b/test/convolution/lennastxx.xv differ
diff --git a/test/convolution/lennastxy.xv b/test/convolution/lennastxy.xv
new file mode 100644
index 0000000..839a0cd
Binary files /dev/null and b/test/convolution/lennastxy.xv differ
diff --git a/test/convolution/lennastyy.xv b/test/convolution/lennastyy.xv
new file mode 100644
index 0000000..8edd5f2
Binary files /dev/null and b/test/convolution/lennastyy.xv differ
diff --git a/test/convolution/resampling.xv b/test/convolution/resampling.xv
new file mode 100755
index 0000000..7ca208f
Binary files /dev/null and b/test/convolution/resampling.xv differ
diff --git a/test/convolution/test.cxx b/test/convolution/test.cxx
new file mode 100755
index 0000000..b8003ef
--- /dev/null
+++ b/test/convolution/test.cxx
@@ -0,0 +1,2521 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <cmath>
+#include <cstdio>
+#include "vigra/convolution.hxx"
+#include "vigra/unittest.hxx"
+#include "vigra/stdimage.hxx"
+#include "vigra/multi_array.hxx"
+#include "vigra/impex.hxx"
+#include "vigra/combineimages.hxx"
+#include "vigra/resampling_convolution.hxx"
+#include "vigra/imagecontainer.hxx"
+#include "vigra/tv_filter.hxx"
+#include "tv_test_data.hxx"
+
+using namespace vigra;
+
+vigra::DImage getSymmetricLine(bool transposed = false){
+    vigra::DImage src;
+    
+    if(transposed)
+        src.resize(1, 40);
+    else
+        src.resize(40, 1);
+
+    vigra::DImage::Accessor acc_src = src.accessor();
+    vigra::DImage::iterator iter_src = src.begin();
+
+    int i = 0;
+    for ( ; i < 20 ; i++, iter_src++){
+      acc_src.set(i + 0.25, iter_src);
+    }
+    i--;
+    for ( ; i >= 0 ; i--, iter_src++){
+      acc_src.set(i + 0.25, iter_src);
+    }
+    return src;
+}
+vigra::DImage getSymmetricImage(){
+    vigra::DImage src(10, 6);
+
+    vigra::DImage::Accessor acc_src = src.accessor();
+    vigra::DImage::iterator iter_src = src.begin();
+
+    int i = 0;
+    for(int y = 0; y < 6; y++){
+        int x = 0;
+        for ( ; x < 5 ; i++, x++, iter_src++){
+            acc_src.set(i + 0.25, iter_src);
+        }
+        i--;
+        for ( ; x < 10 ; i--, x++, iter_src++){
+            acc_src.set(i + 0.25, iter_src);
+        }
+        (y%2 == 0)? i += 3 : i+= 2;
+    }
+    return src;
+}
+
+vigra::DImage getUnsymmetricImage(){
+    vigra::DImage src(10, 6);
+
+    vigra::DImage::Accessor acc_src = src.accessor();
+    vigra::DImage::iterator iter_src = src.begin();
+
+    int i = 0;
+    for(int y = 0; y < 6; y++){
+        for (int x = 0 ; x < 10 ; i++, x++, iter_src++){
+            acc_src.set(i + 0.25, iter_src);
+        }
+        (y%2 == 0)? i++ : i+= 2;
+    }
+    return src;
+}
+
+struct ConvolutionTest
+{
+    typedef vigra::DImage Image;
+    typedef vigra::MultiArrayView<2, double> View;
+    typedef vigra::DRGBImage RGBImage;
+
+    ConvolutionTest()
+    : constimg(5,5), 
+      rampimg(5,1), 
+      sym_image(getSymmetricImage()), 
+      unsym_image(getUnsymmetricImage())
+    {
+        constimg.init(1.0);
+        
+        vigra::Kernel1D<double> binom1;
+        binom1.initBinomial(1);
+        sym_kernel.initSeparable(binom1, binom1);
+
+        unsym_kernel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = 1,   2,   4,
+                                                                  5,   11,  3,
+                                                                  6,   8,   7 ;
+        unsym_kernel.normalize(1);
+
+        line_kernel.initExplicitly(Diff2D(-2,0), Diff2D(2,0)) = 1, 4,   12,   4, 1 ;
+        line_kernel.normalize(1);
+        
+        ImageImportInfo info("lenna128.xv");
+
+        lenna.resize(info.width(), info.height());
+        importImage(info, destImage(lenna));
+
+        Image::ScanOrderIterator i = rampimg.begin();
+        Image::ScanOrderIterator end = rampimg.end();
+        Image::Accessor acc = rampimg.accessor();
+        
+        for(int k=0; i != end; ++i, ++k)
+        {
+            acc.set(k, i);
+        }
+    }
+
+    void borderCopyTest()
+    {
+        static const int size = 6, kleft = -2, kright = 3,
+                         ksize = kright - kleft,
+                         outsize = size + ksize;
+
+        int data[size] = {1, 2, 3, 4, 5, 6};
+        int out[outsize];
+
+        vigra::StandardValueAccessor<int> a;
+
+        // copy entire array
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               0, size, kleft, kright, vigra::BORDER_TREATMENT_WRAP);
+            int r[] = {4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2};
+            shouldEqualSequence(out, out+outsize, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               0, size, kleft, kright, vigra::BORDER_TREATMENT_REFLECT);
+            int r[] = {4, 3, 2, 1, 2, 3, 4, 5, 6, 5, 4};
+            shouldEqualSequence(out, out+outsize, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               0, size, kleft, kright, vigra::BORDER_TREATMENT_REPEAT);
+            int r[] = {1, 1, 1, 1, 2, 3, 4, 5, 6, 6, 6};
+            shouldEqualSequence(out, out+outsize, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               0, size, kleft, kright, vigra::BORDER_TREATMENT_AVOID);
+            int r[] = {1, 2, 3, 4, 5, 6};
+            shouldEqualSequence(out+kright, out+outsize+kleft, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               0, size, kleft, kright, vigra::BORDER_TREATMENT_ZEROPAD);
+            int r[] = {0, 0, 0, 1, 2, 3, 4, 5, 6, 0, 0};
+            shouldEqualSequence(out, out+outsize, r);
+        }
+
+        // copy with partial border treatment
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               1, size-1, kleft, kright, vigra::BORDER_TREATMENT_WRAP);
+            int r[] = {5, 6, 1, 2, 3, 4, 5, 6, 1};
+            shouldEqualSequence(out, out+outsize-2, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               1, size-1, kleft, kright, vigra::BORDER_TREATMENT_REFLECT);
+            int r[] = {3, 2, 1, 2, 3, 4, 5, 6, 5};
+            shouldEqualSequence(out, out+outsize-2, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               1, size-1, kleft, kright, vigra::BORDER_TREATMENT_REPEAT);
+            int r[] = {1, 1, 1, 2, 3, 4, 5, 6, 6};
+            shouldEqualSequence(out, out+outsize-2, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               1, size-1, kleft, kright, vigra::BORDER_TREATMENT_AVOID);
+            int r[] = {2, 3, 4, 5};
+            shouldEqualSequence(out+kright, out+outsize+kleft-2, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               1, size-1, kleft, kright, vigra::BORDER_TREATMENT_ZEROPAD);
+            int r[] = {0, 0, 1, 2, 3, 4, 5, 6, 0};
+            shouldEqualSequence(out, out+outsize-2, r);
+        }
+
+        // copy interior, no border treatment necessary
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               kright, size+kleft, kleft, kright, vigra::BORDER_TREATMENT_WRAP);
+            int r[] = {1, 2, 3, 4, 5, 6};
+            shouldEqualSequence(out, out+outsize-ksize, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               kright, size+kleft, kleft, kright, vigra::BORDER_TREATMENT_REFLECT);
+            int r[] = {1, 2, 3, 4, 5, 6};
+            shouldEqualSequence(out, out+outsize-ksize, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               kright, size+kleft, kleft, kright, vigra::BORDER_TREATMENT_REPEAT);
+            int r[] = {1, 2, 3, 4, 5, 6};
+            shouldEqualSequence(out, out+outsize-ksize, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               kright, size+kleft, kleft, kright, vigra::BORDER_TREATMENT_AVOID);
+            int r[] = {4};
+            shouldEqualSequence(out+kright, out+outsize+kleft-ksize, r);
+        }
+        {
+            vigra::detail::copyLineWithBorderTreatment(data, data+size, a, out, a,
+                                               kright, size+kleft, kleft, kright, vigra::BORDER_TREATMENT_ZEROPAD);
+            int r[] = {1, 2, 3, 4, 5, 6};
+            shouldEqualSequence(out, out+outsize-ksize, r);
+        }
+    }
+    
+    void initExplicitlyTest()
+    {
+        vigra::Kernel1D<double> k;
+        k.initExplicitly(-1,2) = 1,2,3,4;
+        
+        shouldEqual(k.left(), -1);
+        shouldEqual(k.right(), 2);
+        shouldEqual(k[-1], 1);
+        shouldEqual(k[0], 2);
+        shouldEqual(k[1], 3);
+        shouldEqual(k[2], 4);
+        
+        k.initExplicitly(-2,1) = -2;
+        shouldEqual(k.left(), -2);
+        shouldEqual(k.right(), 1);
+        shouldEqual(k[-2], -2);
+        shouldEqual(k[-1], -2);
+        shouldEqual(k[0], -2);
+        shouldEqual(k[1], -2);
+
+        try
+        {
+            k.initExplicitly(-1,1) = 1, 2;
+            failTest("no exception thrown");
+        }
+        catch(vigra::PreconditionViolation & c)
+        {
+            std::string expected("\nPrecondition violation!\nKernel1D::initExplicitly(): Wrong number of init values.");
+            std::string message(c.what());
+            should(0 == expected.compare(message.substr(0,expected.size())));
+        }
+
+        try
+        {
+            k.initExplicitly(-1,1) = 1, 2, 3, 4;
+            failTest("no exception thrown");
+        }
+        catch(vigra::PreconditionViolation & c)
+        {
+            std::string expected("\nPrecondition violation!\nKernel1D::initExplicitly(): Wrong number of init values.");
+            std::string message(c.what());
+            should(0 == expected.compare(message.substr(0,expected.size())));
+        }
+        try
+        {
+            k.initExplicitly(1,1) = 1, 2, 3, 4;
+            failTest("no exception thrown");
+        }
+        catch(vigra::PreconditionViolation & c)
+        {
+            std::string expected("\nPrecondition violation!\nKernel1D::initExplicitly(): left border must be <= 0.");
+            std::string message(c.what());
+            should(0 == expected.compare(message.substr(0,expected.size())));
+        }
+        try
+        {
+            k.initExplicitly(-1,-1) = 1, 2, 3, 4;
+            failTest("no exception thrown");
+        }
+        catch(vigra::PreconditionViolation & c)
+        {
+            std::string expected("\nPrecondition violation!\nKernel1D::initExplicitly(): right border must be >= 0.");
+            std::string message(c.what());
+            should(0 == expected.compare(message.substr(0,expected.size())));
+        }
+    }
+
+    void simpleSharpeningTest()
+    {
+        Image dest_lenna(lenna);
+        simpleSharpening(srcImageRange(lenna), destImage(dest_lenna), 0.8);
+
+        Image dest_correct;
+        ImageImportInfo info_correct("lenna_simple_sharpening_orig.xv");
+        dest_correct.resize(info_correct.width(), info_correct.height());
+        importImage(info_correct, destImage(dest_correct));
+
+        Image::iterator i_dest = dest_lenna.begin();
+        Image::iterator end_dest = dest_lenna.end();
+        Image::Accessor acc_dest = dest_lenna.accessor();
+        Image::iterator i_dest_correct = dest_correct.begin();
+        Image::Accessor acc_dest_correct = dest_correct.accessor();
+
+        for (; i_dest != end_dest; i_dest++, i_dest_correct++ ){
+            shouldEqualTolerance(acc_dest(i_dest) , acc_dest_correct(i_dest_correct), 1e-15);
+        }
+
+        dest_lenna.init(0.0);
+        simpleSharpening(View(lenna), View(dest_lenna), 0.8);
+
+        using namespace multi_math;
+        should(all(abs(View(dest_lenna) - View(dest_correct)) < 3e-13));
+    }
+
+    void gaussianSharpeningTest()
+    {
+        Image dest_lenna(lenna);
+        gaussianSharpening(srcImageRange(lenna), destImage(dest_lenna), 3., 0.7);
+
+        Image dest_correct;
+        ImageImportInfo info_correct("lenna_gaussian_sharpening_orig.xv");
+        dest_correct.resize(info_correct.width(), info_correct.height());
+        importImage(info_correct, destImage(dest_correct));
+
+        Image::iterator i_dest = dest_lenna.begin();
+        Image::iterator end_dest = dest_lenna.end();
+        Image::Accessor acc_dest = dest_lenna.accessor();
+        Image::iterator i_dest_correct = dest_correct.begin();
+        Image::Accessor acc_dest_correct = dest_correct.accessor();
+
+        for (; i_dest != end_dest; i_dest++, i_dest_correct++ )
+        {
+            shouldEqualTolerance(acc_dest(i_dest) , acc_dest_correct(i_dest_correct), 1e-6);
+        }
+
+        dest_lenna.init(0.0);
+        gaussianSharpening(View(lenna), View(dest_lenna), 3., 0.7);
+
+        using namespace multi_math;
+        should(all(abs(View(dest_lenna) - View(dest_correct)) < 1e-6));
+    }
+
+    void stdConvolutionTestOnConstImage()
+    {        
+        Image tmp_clip(constimg);
+        tmp_clip = 0.0;
+        Image tmp_wrap(constimg);
+        tmp_wrap = 0.0;
+        Image tmp_avoid(constimg);
+        tmp_avoid = 0.0;
+        Image tmp_repeat(constimg);
+        tmp_repeat = 0.0;
+        Image tmp_reflect(constimg);
+        tmp_reflect = 0.0;
+
+        sym_kernel.setBorderTreatment(BORDER_TREATMENT_CLIP);
+        convolveImage(View(constimg), View(tmp_clip), sym_kernel);
+
+        sym_kernel.setBorderTreatment(BORDER_TREATMENT_AVOID);
+        convolveImage(View(constimg), View(tmp_avoid), sym_kernel);
+        
+        sym_kernel.setBorderTreatment(BORDER_TREATMENT_WRAP);
+        convolveImage(View(constimg), View(tmp_wrap), sym_kernel);
+
+        sym_kernel.setBorderTreatment(BORDER_TREATMENT_REPEAT);
+        convolveImage(View(constimg), View(tmp_repeat), sym_kernel);
+
+        sym_kernel.setBorderTreatment(BORDER_TREATMENT_REFLECT);
+        convolveImage(View(constimg), View(tmp_reflect), sym_kernel);
+        
+        Image::ScanOrderIterator i_src = constimg.begin();
+        Image::ScanOrderIterator i_src_end = constimg.end();
+        Image::ScanOrderIterator i_clip = tmp_clip.begin();
+        Image::ScanOrderIterator i_avoid = tmp_avoid.begin();
+        Image::ScanOrderIterator i_wrap = tmp_wrap.begin();
+        Image::ScanOrderIterator i_repeat = tmp_repeat.begin();
+        Image::ScanOrderIterator i_reflect = tmp_reflect.begin();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(int y = 0; i_src != i_src_end; y++){
+            for(int x = 0; x < constimg.size().x; x++, ++i_src, ++i_clip, ++i_wrap, ++i_repeat, ++i_reflect, ++i_avoid){
+                should(acc(i_src) == acc(i_clip));
+                should(acc(i_src) == acc(i_wrap));
+                should(acc(i_src) == acc(i_repeat));
+                should(acc(i_src) == acc(i_reflect));
+                if(x != 0 && y != 0 && x != 4 && y != 4){
+                    should(acc(i_src) == acc(i_avoid)); 
+                }else{
+                    should(acc(i_avoid) == 0);
+                }
+            }
+        }
+
+
+        //@todo Import<->Export funktioniert nicht wie frueher???
+//         Image dest_lenna(lenna);
+//         convolveImage(srcImageRange(lenna), destImage(dest_lenna), kernel2d(sym_kernel, BORDER_TREATMENT_REFLECT));
+//         exportImage(srcImageRange(dest_lenna), ImageExportInfo("lenna_convolve_128x120.xv"));
+
+    }
+    
+
+    void stdConvolutionTestWithAvoid()
+    {
+        Image dest(sym_image);
+        dest.init(42.1);
+
+        convolveImage(srcImageRange(sym_image), destImage(dest), kernel2d(sym_kernel, BORDER_TREATMENT_AVOID));
+
+        Image::Iterator i_dest_2D = dest.upperLeft();
+        Image::ScanOrderIterator i_dest = dest.begin();
+        Image::ScanOrderIterator i_dest_end = dest.end();
+        Image::Accessor acc = dest.accessor();
+
+        //Kontrollierung der Randbehandlung und ein paar Pixel
+        //aus der Mitte.
+        should (acc(i_dest_2D + Diff2D(1,1)) == 3);
+        should (acc(i_dest_2D + Diff2D(8,2)) == 4.5);
+        for(int y = 0; i_dest != i_dest_end; y++){
+            for(int x = 0; x < dest.size().x; x++, ++i_dest){
+                if(x == 0 || y == 0 || x == 9 || y == 9){
+                    shouldEqual(acc(i_dest), 42.1);
+                }
+            }
+        }
+
+    }
+    
+
+    void stdConvolutionTestWithZeropad()
+    {
+        Image dest(sym_image.size()-Size2D(2,2)), ref(sym_image);
+        dest.init(42.1);
+        ref.init(33.2);
+
+        convolveImage(srcImageRange(sym_image, Rect2D(Point2D(1,1), sym_image.size()-Size2D(2,2))), 
+                      destImage(dest), kernel2d(sym_kernel, BORDER_TREATMENT_ZEROPAD));
+
+        initImageBorder(destImageRange(sym_image), 1, 0);
+        convolveImage(srcImageRange(sym_image), destImage(ref), kernel2d(sym_kernel, BORDER_TREATMENT_AVOID));
+
+        Image::Iterator i_dest_2D = dest.upperLeft();
+        Image::Iterator i_dest_end = dest.lowerRight();
+        Image::Iterator i_ref_2D = ref.upperLeft()+Size2D(1,1);
+        Image::Accessor acc = dest.accessor();
+
+        for(; i_dest_2D.y != i_dest_end.y; ++i_dest_2D.y, ++i_ref_2D.y)
+        {
+            Image::Iterator rd = i_dest_2D;
+            Image::Iterator rr = i_ref_2D;
+            for(; rd.x != i_dest_end.x; ++rd.x, ++rr.x)
+            {
+                shouldEqual(acc(rd), acc(rr));
+            }
+        }
+    }
+    
+    void stdConvolutionTestWithClip()
+    {
+        Image dest(sym_image);
+        dest.init(42.1);
+
+        convolveImage(srcImageRange(sym_image), destImage(dest), kernel2d(unsym_kernel, BORDER_TREATMENT_CLIP));
+
+        Image::Iterator i_dest_2D = dest.upperLeft();
+        Image::Accessor acc = dest.accessor();
+
+        //Kontrollierung der Randbehandlung und ein paar Pixel
+        //aus der Mitte.
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,0)), 0.88157,   1E-4);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(3,0)), 3.75,      1E-4);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,0)), 1.199999,  1E-4);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,2)), 3.5642913, 1E-4);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,5)), 7.5603463, 1E-4);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(3,5)), 10.225,    1E-4);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,5)), 7.6833271, 1E-4);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,2)), 3.3712039, 1E-4);
+
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(3,2)), 6.05852,   1E-4);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(6,4)), 9.14363,   1E-4);
+    }
+    
+    void stdConvolutionTestWithWrap()
+    {
+        Image dest(unsym_image);
+        dest.init(42.1);
+
+        convolveImage(srcImageRange(unsym_image), destImage(dest), kernel2d(unsym_kernel, BORDER_TREATMENT_WRAP));
+
+        Image::Iterator i_dest_2D = dest.upperLeft();
+        Image::Accessor acc = dest.accessor();
+
+        //Kontrollierung der Randbehandlung und ein paar Pixel
+        //aus der Mitte.
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,0)), 30.2926,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(3,0)), 30.3138,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,0)), 33.7606,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,2)), 25.9309,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,5)), 50.25,     1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(3,5)), 46.8032,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,5)), 46.7819,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,2)), 22.4628,   1E-5);
+
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(2,3)), 33.0798,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(6,4)), 48.4841,   1E-5);
+    }
+    
+    void stdConvolutionTestWithReflect()
+    {
+        Image dest(unsym_image);
+        dest.init(42.1);
+
+        convolveImage(srcImageRange(unsym_image), destImage(dest), kernel2d(unsym_kernel, BORDER_TREATMENT_REFLECT));
+
+        Image::Iterator i_dest_2D = dest.upperLeft();
+        Image::Accessor acc = dest.accessor();
+
+        //Kontrollierung der Randbehandlung und ein paar Pixel
+        //aus der Mitte.
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,0)), 7.35638,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(3,0)), 9.76064,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,0)), 15.25,     1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,2)), 27.9734,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,5)), 59.1436,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(3,5)), 53.6543,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,5)), 51.25,     1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,2)), 20.0798,   1E-5);
+
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(2,3)), 33.0798,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(6,4)), 48.4841,   1E-5);
+    }
+    
+    void stdConvolutionTestWithRepeat()
+    {
+        Image dest(unsym_image);
+        dest.init(42.1);
+
+        convolveImage(srcImageRange(unsym_image), destImage(dest), kernel2d(unsym_kernel, BORDER_TREATMENT_REPEAT));
+
+        Image::Iterator i_dest_2D = dest.upperLeft();
+        Image::Accessor acc = dest.accessor();
+
+        //Kontrollierung der Randbehandlung und ein paar Pixel
+        //aus der Mitte.
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,0)), 2.14362,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(3,0)), 4.84574,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,0)), 10.5904,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,2)), 28.2287,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(9,5)), 61.0372,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(3,5)), 55.2926,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,5)), 52.5904,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(0,2)), 19.7819,   1E-5);
+
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(2,3)), 33.0798,   1E-5);
+        shouldEqualTolerance (acc(i_dest_2D + Diff2D(6,4)), 48.4841,   1E-5);
+    }
+
+    void stdConvolutionTestFromWrapWithReflect()
+    {
+    
+        Image src_wrap(78, 1);
+        Image src_reflect(40, 1);
+        Image dest_wrap(src_wrap);
+        Image dest_reflect(src_reflect);
+
+        Image::Accessor acc_src_wrap = src_wrap.accessor();
+        Image::iterator iter_src_wrap = src_wrap.begin();
+        Image::Accessor acc_src_reflect = src_reflect.accessor();
+        Image::iterator iter_src_reflect = src_reflect.begin();
+
+        for (int i = 0 ; i < 40 ; i++, iter_src_wrap++, iter_src_reflect++){
+            acc_src_wrap.set(i + 0.25, iter_src_wrap);
+            acc_src_reflect.set(i + 0.25, iter_src_reflect);
+        }
+        for (int j = 38 ; j >= 1 ; j--, iter_src_wrap++){
+            acc_src_wrap.set( j + 0.25, iter_src_wrap);
+        }
+    
+        convolveImage(srcImageRange(src_wrap), destImage(dest_wrap), kernel2d(line_kernel, BORDER_TREATMENT_WRAP));
+        convolveImage(srcImageRange(src_reflect), destImage(dest_reflect), kernel2d(line_kernel, BORDER_TREATMENT_REFLECT));
+
+        Image::iterator iter_dest_wrap = dest_wrap.begin();
+        Image::Accessor acc_dest_wrap = dest_wrap.accessor();
+        Image::iterator iter_dest_reflect = dest_reflect.begin();
+        Image::iterator end_dest_reflect = dest_reflect.end();
+        Image::Accessor acc_dest_reflect = dest_reflect.accessor();
+
+        while(iter_dest_reflect != end_dest_reflect){
+            shouldEqualTolerance(acc_dest_wrap(iter_dest_wrap), acc_dest_reflect(iter_dest_reflect), 1e-6);
+            iter_dest_wrap++;
+            iter_dest_reflect++;
+        }
+    }
+  
+    void stdConvolutionTestFromRepeatWithAvoid()
+    {
+        Image src_avoid(40, 1);
+        src_avoid.init(2.47);
+        Image src_repeat(36, 1);
+    
+        Image dest_repeat(src_repeat);
+        Image dest_avoid(src_avoid);
+
+        Image::Accessor acc_src_avoid = src_avoid.accessor();
+        Image::iterator iter_src_avoid = src_avoid.begin();
+        Image::Accessor acc_src_repeat = src_repeat.accessor();
+        Image::iterator iter_src_repeat = src_repeat.begin();
+
+        int i = 0;
+        for ( ; i < 20 ; i++, iter_src_avoid++){
+            if(i > 1){
+                acc_src_repeat.set(i + 0.47, iter_src_repeat);
+                acc_src_avoid.set(i + 0.47, iter_src_avoid);
+                iter_src_repeat++;
+            }
+        }
+        i--;
+
+        for ( ; i >= 0 ; i--, iter_src_avoid++){
+            if(i > 1){
+                acc_src_repeat.set(i + 0.47, iter_src_repeat);
+                acc_src_avoid.set(i + 0.47, iter_src_avoid);
+                iter_src_repeat++;
+            }
+        }
+
+        convolveImage(srcImageRange(src_repeat), destImage(dest_repeat), kernel2d(line_kernel, BORDER_TREATMENT_REPEAT));
+        convolveImage(srcImageRange(src_avoid), destImage(dest_avoid), kernel2d(line_kernel, BORDER_TREATMENT_AVOID));
+
+        Image::Accessor acc_dest_repeat = dest_repeat.accessor();
+        Image::iterator dest_iter_repeat = dest_repeat.begin();
+
+        Image::Accessor acc_dest_avoid = dest_avoid.accessor();
+        Image::iterator dest_iter_avoid = dest_avoid.begin();
+
+        for (int i = 0 ; i < 39 ; i++, dest_iter_avoid++){
+            if (i < 2 || i > 37){
+                should(acc_dest_avoid(dest_iter_avoid) == 2.47);
+            }else{
+                shouldEqualTolerance(acc_dest_avoid(dest_iter_avoid) , acc_dest_repeat(dest_iter_repeat), 1e-15);
+                dest_iter_repeat++;
+            }
+        }
+    }
+  
+    /**
+     * Es wird die Positionierung der einzelnen 
+     * Punkte relativ zueinander getestet.
+     */
+    void stdConvolutionTestOfAllTreatmentsRelatively(){
+        Image src(40, 1);
+
+        Image::Accessor acc_src = src.accessor();
+        Image::iterator iter_src = src.begin();
+
+        int i = 0;
+        for ( ; i < 20 ; i++, iter_src++){
+            acc_src.set(i + 0.25, iter_src);
+        }
+        i--;
+        for ( ; i >= 0 ; i--, iter_src++){
+            acc_src.set(i + 0.25, iter_src);
+        }
+
+        Image dest_avoid(src);
+        Image dest_repeat(src);
+        Image dest_reflect(src);
+        Image dest_wrap(src);
+        Image dest_clip(src);
+
+        convolveImage(srcImageRange(src), destImage(dest_avoid), kernel2d(line_kernel, BORDER_TREATMENT_AVOID));
+        convolveImage(srcImageRange(src), destImage(dest_repeat), kernel2d(line_kernel, BORDER_TREATMENT_REPEAT));
+        convolveImage(srcImageRange(src), destImage(dest_reflect), kernel2d(line_kernel, BORDER_TREATMENT_REFLECT));
+        convolveImage(srcImageRange(src), destImage(dest_wrap), kernel2d(line_kernel, BORDER_TREATMENT_WRAP));
+        convolveImage(srcImageRange(src), destImage(dest_clip), kernel2d(line_kernel, BORDER_TREATMENT_CLIP));
+
+        iter_src = src.begin();
+        Image::iterator iter_dest_avoid = dest_avoid.begin();
+        Image::iterator iter_dest_repeat = dest_repeat.begin();
+        Image::iterator iter_dest_reflect = dest_reflect.begin();
+        Image::iterator iter_dest_wrap = dest_wrap.begin();
+        Image::iterator iter_dest_clip = dest_clip.begin();
+
+        for (int x = 0 ;  x < 40 ; x++){
+            if(x > 1 && x < 38 ){
+                shouldEqualTolerance(iter_dest_avoid[x], iter_dest_repeat[x], 1e-5);
+                shouldEqualTolerance(iter_dest_avoid[x], iter_dest_reflect[x], 1e-5);
+                shouldEqualTolerance(iter_dest_avoid[x], iter_dest_wrap[x], 1e-5);
+                shouldEqualTolerance(iter_dest_avoid[x], iter_dest_clip[x], 1e-5);
+            }else{
+                should(iter_dest_avoid[x] == iter_src[x]);
+                should(iter_dest_repeat[x] < iter_dest_reflect[x]);
+                should(iter_dest_repeat[x] < iter_dest_clip[x]);
+                if (x < 1 || x > 38){
+                    should(iter_dest_clip[x] < iter_dest_reflect[x]);
+                }
+                else{
+                    should(iter_dest_clip[x] > iter_dest_reflect[x]);
+                }
+            }
+        }
+
+    }
+
+    void separableConvolutionTest()
+    {
+        vigra::Kernel1D<double> binom;
+        binom.initBinomial(2);
+        
+        vigra::Kernel1D<double>::Iterator center = binom.center();
+        
+        should(center[0] == 0.375);
+        should(center[-1] == 0.25);
+        should(center[1] == 0.25);
+        should(center[-2] == 0.0625);
+        should(center[2] == 0.0625);
+        
+        binom.initBinomial(1);
+        
+        center = binom.center();
+        
+        should(center[0] == 0.5);
+        should(center[-1] == 0.25);
+        should(center[1] == 0.25);
+        
+        Image tmp1(constimg);
+        Image tmp2(constimg);
+        tmp2 = 0.0;
+        
+        separableConvolveX(srcImageRange(constimg), destImage(tmp1), kernel1d(binom));
+        separableConvolveY(srcImageRange(tmp1), destImage(tmp2), kernel1d(binom));
+        
+        Image::ScanOrderIterator i1 = constimg.begin();
+        Image::ScanOrderIterator i1end = constimg.end();
+        Image::ScanOrderIterator i2 = tmp2.begin();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(acc(i1) == acc(i2));
+        }
+    }
+    
+    void separableDerivativeRepeatTest()
+    {
+        vigra::Kernel1D<double> grad;
+        grad.initSymmetricGradient();
+        
+        Image tmp1(rampimg);
+        tmp1 = 0.0;
+        Image tmp2(constimg);
+        
+        separableConvolveX(srcImageRange(rampimg), destImage(tmp1), kernel1d(grad));
+        separableConvolveX(srcImageRange(constimg), destImage(tmp2), kernel1d(grad));
+        
+        Image::ScanOrderIterator i1 = tmp1.begin();
+        Image::ScanOrderIterator i2 = tmp2.begin();
+        Image::Accessor acc = tmp1.accessor();
+        
+        should(acc(i1) == 0.5);
+        should(acc(i2) == 0.0);
+        ++i1;
+        ++i2;
+        should(acc(i1) == 1.0);
+        should(acc(i2) == 0.0);
+        ++i1;
+        ++i2;
+        should(acc(i1) == 1.0);
+        should(acc(i2) == 0.0);
+        ++i1;
+        ++i2;
+        should(acc(i1) == 1.0);
+        should(acc(i2) == 0.0);
+        ++i1;
+        ++i2;
+        should(acc(i1) == 0.5);
+        should(acc(i2) == 0.0);
+    }
+    
+    void separableDerivativeReflectTest()
+    {
+        vigra::Kernel1D<double> grad;
+        grad.initSymmetricGradient();
+        grad.setBorderTreatment(vigra::BORDER_TREATMENT_REFLECT);
+        
+        Image tmp1(rampimg);
+        tmp1 = 1000.0;
+        
+        separableConvolveX(srcImageRange(rampimg), destImage(tmp1), kernel1d(grad));
+        
+        Image::ScanOrderIterator i1 = tmp1.begin();
+        Image::Accessor acc = tmp1.accessor();
+        
+        should(acc(i1) == 0.0);
+        ++i1;
+        should(acc(i1) == 1.0);
+        ++i1;
+        should(acc(i1) == 1.0);
+        ++i1;
+        should(acc(i1) == 1.0);
+        ++i1;
+        should(acc(i1) == 0.0);
+    }
+    
+    void separableDerivativeAvoidTest()
+    {
+        vigra::Kernel1D<double> grad;
+        grad.initSymmetricGradient();
+        grad.setBorderTreatment(vigra::BORDER_TREATMENT_AVOID);
+        
+        Image tmp1(rampimg);
+        tmp1 = 1000.0;
+        
+        separableConvolveX(srcImageRange(rampimg), destImage(tmp1), kernel1d(grad));
+        
+        Image::ScanOrderIterator i1 = tmp1.begin();
+        Image::Accessor acc = tmp1.accessor();
+        
+        should(acc(i1) == 1000.0);
+        ++i1;
+        should(acc(i1) == 1.0);
+        ++i1;
+        should(acc(i1) == 1.0);
+        ++i1;
+        should(acc(i1) == 1.0);
+        ++i1;
+        should(acc(i1) == 1000.0);
+    }
+    
+    void separableSmoothClipTest()
+    {
+        vigra::Kernel1D<double> binom;
+        binom.initBinomial(1);
+        binom.setBorderTreatment(vigra::BORDER_TREATMENT_CLIP);
+        
+        Image tmp1(rampimg);
+        tmp1 = 1000.0;
+        
+        separableConvolveX(srcImageRange(rampimg), destImage(tmp1), kernel1d(binom));
+        
+        Image::ScanOrderIterator i1 = tmp1.begin();
+        Image::Accessor acc = tmp1.accessor();
+        
+        should(acc(i1) == 1.0/3.0);
+        ++i1;
+        should(acc(i1) == 1.0);
+        ++i1;
+        should(acc(i1) == 2.0);
+        ++i1;
+        should(acc(i1) == 3.0);
+        ++i1;
+        should(acc(i1) == 11.0/3.0);
+    }
+    
+    void separableSmoothZeropadTest()
+    {
+        vigra::Kernel1D<double> binom;
+        binom.initBinomial(1);
+        binom.setBorderTreatment(vigra::BORDER_TREATMENT_ZEROPAD);
+
+        Image tmp1(rampimg);
+        tmp1 = 1000.0;
+        
+        separableConvolveX(srcImageRange(rampimg), destImage(tmp1), kernel1d(binom));
+        
+        Image::ScanOrderIterator i1 = tmp1.begin();
+        Image::Accessor acc = tmp1.accessor();
+
+        shouldEqual(acc(i1), 0.25);
+        ++i1;
+        shouldEqual(acc(i1), 1.0);
+        ++i1;
+        shouldEqual(acc(i1), 2.0);
+        ++i1;
+        shouldEqual(acc(i1), 3.0);
+        ++i1;
+        shouldEqual(acc(i1), 2.75);
+    }
+    
+    void separableSmoothWrapTest()
+    {
+        vigra::Kernel1D<double> binom;
+        binom.initBinomial(1);
+        binom.setBorderTreatment(vigra::BORDER_TREATMENT_WRAP);
+        
+        Image tmp1(rampimg);
+        tmp1 = 1000.0;
+        
+        separableConvolveX(srcImageRange(rampimg), destImage(tmp1), kernel1d(binom));
+        
+        Image::ScanOrderIterator i1 = tmp1.begin();
+        Image::Accessor acc = tmp1.accessor();
+        
+        should(acc(i1) == 1.25);
+        ++i1;
+        should(acc(i1) == 1.0);
+        ++i1;
+        should(acc(i1) == 2.0);
+        ++i1;
+        should(acc(i1) == 3.0);
+        ++i1;
+        should(acc(i1) == 2.75);
+    }
+    
+    void gaussianSmoothingTest()
+    {
+        double scale = 1.0;
+        vigra::Kernel1D<double> gauss;
+        gauss.initGaussian(scale);
+        gauss.setBorderTreatment(BORDER_TREATMENT_REFLECT);
+
+        Image tmp1(lenna.size()), tmp2(lenna.size()), tmp3(lenna.size());
+
+        separableConvolveX(srcImageRange(lenna), destImage(tmp1), kernel1d(gauss));
+        separableConvolveY(srcImageRange(tmp1), destImage(tmp2), kernel1d(gauss));
+        
+        gaussianSmoothing(srcImageRange(lenna), destImage(tmp1), scale);
+        
+        Image::ScanOrderIterator i1 = tmp1.begin();
+        Image::ScanOrderIterator i1end = tmp1.end();
+        Image::ScanOrderIterator i2 = tmp2.begin();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(acc(i1) == acc(i2));
+        }
+
+        tmp1 = 0.0;
+        separableConvolveX(View(lenna), View(tmp1), gauss);
+        separableConvolveY(View(tmp1), View(tmp3),  gauss);
+        gaussianSmoothing(View(lenna), View(tmp1), scale);
+        should(View(tmp1) == View(tmp2));
+        should(View(tmp1) == View(tmp3));
+
+        // test recursive approximation
+        Image recursive(lenna.size());
+        recursiveGaussianFilterX(srcImageRange(lenna), destImage(tmp2), scale);
+        recursiveGaussianFilterY(srcImageRange(tmp2), destImage(recursive), scale);
+
+        i1 = tmp1.begin();
+        i1end = tmp1.end();
+        i2 = recursive.begin();
+        
+        double sum = 0.0;
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            double diff = abs(acc(i1) - acc(i2));
+            sum += diff;
+            should(diff < 6.0);
+        }
+        should(sum / lenna.width() / lenna.height() < 0.5);
+
+        recursiveGaussianFilterX(View(lenna), View(tmp1), scale);
+        recursiveGaussianFilterY(View(tmp1), View(tmp2), scale);
+        should(View(recursive) == View(tmp2));
+    }
+    
+    void optimalSmoothing3Test()
+    {
+        vigra::Kernel1D<double> smooth3;
+        smooth3.initOptimalSmoothing3();
+
+        Image tmp1(lenna.size());
+        Image tmp2(lenna.size());
+
+        separableConvolveX(srcImageRange(lenna), destImage(tmp1), kernel1d(smooth3));
+        separableConvolveY(srcImageRange(tmp1), destImage(tmp2), kernel1d(smooth3));
+        
+        gaussianSmoothing(srcImageRange(lenna), destImage(tmp1), 0.68);
+        
+        Image::ScanOrderIterator i1 = tmp1.begin();
+        Image::ScanOrderIterator i1end = tmp1.end();
+        Image::ScanOrderIterator i2 = tmp2.begin();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            shouldEqualTolerance(acc(i1), acc(i2), 1e-2);
+        }
+    }
+    
+    void optimalSmoothing5Test()
+    {
+        vigra::Kernel1D<double> smooth5;
+        smooth5.initOptimalSmoothing5();
+
+        Image tmp1(lenna.size());
+        Image tmp2(lenna.size());
+
+        separableConvolveX(srcImageRange(lenna), destImage(tmp1), kernel1d(smooth5));
+        separableConvolveY(srcImageRange(tmp1), destImage(tmp2), kernel1d(smooth5));
+        
+        gaussianSmoothing(srcImageRange(lenna), destImage(tmp1), 0.867);
+        
+        Image::ScanOrderIterator i1 = tmp1.begin();
+        Image::ScanOrderIterator i1end = tmp1.end();
+        Image::ScanOrderIterator i2 = tmp2.begin();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            shouldEqualTolerance(acc(i1), acc(i2), 1e-2);
+        }
+    }
+    
+    void separableGradientTest()
+    {
+        Image sepgrad(lenna.size());
+        importImage(vigra::ImageImportInfo("lenna128sepgrad.xv"), destImage(sepgrad));
+        
+        vigra::Kernel1D<double> gauss;
+        gauss.initGaussian(1.0);
+        vigra::Kernel1D<double> grad;
+        grad.initGaussianDerivative(1.0, 1);
+
+        Image tmp1(lenna);
+        tmp1.init(0.0);
+        Image tmp2(lenna);
+        tmp2.init(0.0);
+        Image tmp3(lenna);
+
+        separableConvolveX(srcImageRange(lenna), destImage(tmp3), kernel1d(grad));
+        separableConvolveY(srcImageRange(tmp3), destImage(tmp1), kernel1d(gauss));
+        
+        separableConvolveX(srcImageRange(lenna), destImage(tmp3), kernel1d(gauss));
+        separableConvolveY(srcImageRange(tmp3), destImage(tmp2), kernel1d(grad));
+        
+        Image::ScanOrderIterator i1 = tmp1.begin();
+        Image::ScanOrderIterator i1end = tmp1.end();
+        Image::ScanOrderIterator i2 = tmp2.begin();
+        Image::ScanOrderIterator i = sepgrad.begin();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2, ++i)
+        {
+            double grad = VIGRA_CSTD::sqrt(acc(i1)*acc(i1)+acc(i2)*acc(i2));
+
+            shouldEqualTolerance(grad-acc(i), 0.0, 1e-12);
+        }
+
+        // compare with 2D convolution
+        vigra::Kernel2D<double> gradx;
+        gradx.initSeparable(grad, gauss);
+        Image nsgrad(lenna.size());
+        convolveImage(srcImageRange(lenna), destImage(nsgrad), kernel2d(gradx));
+
+        using namespace vigra::functor;
+
+        combineTwoImages(srcImageRange(nsgrad), srcImage(tmp1), destImage(nsgrad), Arg1() - Arg2());
+        Image zero(lenna.size(), 0.0);
+        shouldEqualSequenceTolerance(nsgrad.data(), nsgrad.data()+nsgrad.width()*nsgrad.height(), 
+                                     zero.data(), 1e-12);
+    }
+    
+    void gradientTest()
+    {
+        Image sepgrad(lenna.size());
+        importImage(vigra::ImageImportInfo("lenna128sepgrad.xv"), destImage(sepgrad));
+        
+        
+        Image tmpx(lenna.size());
+        Image tmpy(lenna.size());
+        Image mag(lenna.size());
+
+        gaussianGradient(View(lenna), View(tmpx), View(tmpy), 1.0);
+        gaussianGradientMagnitude(srcImageRange(lenna), destImage(mag), 1.0);
+
+        Image::ScanOrderIterator i1 = tmpx.begin();
+        Image::ScanOrderIterator i1end = tmpx.end();
+        Image::ScanOrderIterator i2 = tmpy.begin();
+        Image::ScanOrderIterator ig = mag.begin();
+        Image::ScanOrderIterator i = sepgrad.begin();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2, ++ig, ++i)
+        {
+            double grad = VIGRA_CSTD::sqrt(acc(i1)*acc(i1)+acc(i2)*acc(i2));
+            shouldEqualTolerance(grad-acc(i), 0.0, 1e-12);
+            shouldEqualTolerance(acc(ig)-acc(i), 0.0, 1e-12);
+        }
+    }
+    
+    void optimalGradient3Test()
+    {
+        Image tmp(lenna.size());
+        Image tmpx(lenna.size());
+        Image tmpy(lenna.size());
+
+        vigra::Kernel1D<double> diff;
+        diff.initSymmetricDifference();
+        vigra::Kernel1D<double> smooth3;
+        smooth3.initOptimalFirstDerivativeSmoothing3();
+
+        separableConvolveX(srcImageRange(lenna), destImage(tmp), kernel1d(diff));
+        separableConvolveY(srcImageRange(tmp), destImage(tmpx), kernel1d(smooth3));
+        
+        separableConvolveX(srcImageRange(lenna), destImage(tmp), kernel1d(smooth3));
+        separableConvolveY(srcImageRange(tmp), destImage(tmpy), kernel1d(diff));
+
+        double sum = 0.0, mi = 0.0, ma = 0.0;
+
+        Image::ScanOrderIterator i1 = tmpx.begin();
+        Image::ScanOrderIterator i1end = tmpx.end();
+        Image::ScanOrderIterator i2 = tmpy.begin();
+        Image::Accessor acc = constimg.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            double grad = VIGRA_CSTD::sqrt(acc(i1)*acc(i1)+acc(i2)*acc(i2));
+            sum += grad;
+            mi = std::min(mi, grad);
+            ma = std::max(ma, grad);
+        }
+        should(std::fabs(sum- 130000.0) < 1000.0);
+        shouldEqual(mi, 0.0);
+        should(std::fabs(ma - 68.0) < 1.0);
+    }
+    
+    void optimalLaplacian3Test()
+    {
+        Image tmp(lenna.size());
+        Image tmpx(lenna.size());
+        Image tmpy(lenna.size());
+
+        vigra::Kernel1D<double> diff;
+        diff.initSecondDifference3();
+        vigra::Kernel1D<double> smooth3;
+        smooth3.initOptimalSecondDerivativeSmoothing3();
+        
+        separableConvolveX(srcImageRange(lenna), destImage(tmp), kernel1d(diff));
+        separableConvolveY(srcImageRange(tmp), destImage(tmpx), kernel1d(smooth3));
+        
+        separableConvolveX(srcImageRange(lenna), destImage(tmp), kernel1d(smooth3));
+        separableConvolveY(srcImageRange(tmp), destImage(tmpy), kernel1d(diff));
+
+        double sum = 0.0, mi = 0.0, ma = 0.0;
+
+        Image::ScanOrderIterator i1 = tmpx.begin();
+        Image::ScanOrderIterator i1end = tmpx.end();
+        Image::ScanOrderIterator i2 = tmpy.begin();
+        Image::Accessor acc = constimg.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            double lap = acc(i1) + acc(i2);
+            sum += lap;
+            mi = std::min(mi, lap);
+            ma = std::max(ma, lap);
+        }
+        should(std::fabs(sum) < 90.0);
+        should(std::fabs(mi + 120.0) < 1.0);
+        should(std::fabs(ma - 117.0) < 1.0);
+    }
+        
+    void optimalGradient5Test()
+    {
+        Image tmp(lenna.size());
+        Image tmpx(lenna.size());
+        Image tmpy(lenna.size());
+        Image mag(lenna.size());
+
+        vigra::Kernel1D<double> diff;
+        diff.initOptimalFirstDerivative5();
+        vigra::Kernel1D<double> smooth5;
+        smooth5.initOptimalFirstDerivativeSmoothing5();
+        
+        separableConvolveX(srcImageRange(lenna), destImage(tmp), kernel1d(diff));
+        separableConvolveY(srcImageRange(tmp), destImage(tmpx), kernel1d(smooth5));
+        
+        separableConvolveX(srcImageRange(lenna), destImage(tmp), kernel1d(smooth5));
+        separableConvolveY(srcImageRange(tmp), destImage(tmpy), kernel1d(diff));
+
+        gaussianGradientMagnitude(srcImageRange(lenna), destImage(mag), 0.906);
+
+        for(int y=1; y<lenna.height()-1; ++y)
+        {
+            for(int x=1; x<lenna.width()-1; ++x)
+            {
+                double grad = vigra::hypot(tmpx(x,y), tmpy(x,y));
+                should(std::fabs(grad-mag(x,y)) < 2.0);
+            }
+        }
+    }
+    
+    void optimalLaplacian5Test()
+    {
+        Image tmp(lenna.size());
+        Image tmpx(lenna.size());
+        Image tmpy(lenna.size());
+        Image lap(lenna.size());
+        Image lap1(lenna.size());
+
+        vigra::Kernel1D<double> diff;
+        diff.initOptimalSecondDerivative5();
+        vigra::Kernel1D<double> smooth5;
+        smooth5.initOptimalSecondDerivativeSmoothing5();
+        
+        separableConvolveX(srcImageRange(lenna), destImage(tmp), kernel1d(diff));
+        separableConvolveY(srcImageRange(tmp), destImage(tmpx), kernel1d(smooth5));
+        
+        separableConvolveX(View(lenna), View(tmp), smooth5);
+        separableConvolveY(View(tmp), View(tmpy), diff);
+
+        laplacianOfGaussian(srcImageRange(lenna), destImage(lap), 0.817);
+        laplacianOfGaussian(View(lenna), View(lap1), 0.817);
+
+        for(int y=2; y<lenna.height()-2; ++y)
+        {
+            for(int x=2; x<lenna.width()-2; ++x)
+            {
+                double l = tmpx(x,y) + tmpy(x,y);
+                should(std::fabs(l-lap(x,y)) < 4.0);
+                shouldEqual(lap(x,y), lap1(x,y));
+            }
+        }
+    }
+    
+    void gradientRGBTest()
+    {
+        RGBImage input(lenna.size());
+        importImage(vigra::ImageImportInfo("lenna128rgb.xv"), destImage(input));
+        
+        Image sepgrad(lenna.size());
+        importImage(vigra::ImageImportInfo("lenna128rgbsepgrad.xv"), destImage(sepgrad));
+        
+        
+        RGBImage tmpx(lenna.size());
+        RGBImage tmpy(lenna.size());
+        Image mag(lenna.size());
+        Image resmag(lenna.size());
+
+        gaussianGradient(srcImageRange(input), destImage(tmpx), destImage(tmpy), 1.0);
+        gaussianGradientMagnitude(srcImageRange(input), destImage(mag), 1.0);
+        
+        RGBImage::ScanOrderIterator i1 = tmpx.begin();
+        RGBImage::ScanOrderIterator i1end = tmpx.end();
+        RGBImage::ScanOrderIterator i2 = tmpy.begin();
+        Image::ScanOrderIterator ig = mag.begin();
+        Image::ScanOrderIterator i = sepgrad.begin();
+        RGBImage::Accessor rgb = tmpx.accessor();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2, ++ig, ++i)
+        {
+            double grad = VIGRA_CSTD::sqrt(squaredNorm(rgb(i1))+squaredNorm(rgb(i2)));
+            shouldEqualTolerance(grad-acc(i), 0.0, 1e-12);
+            shouldEqualTolerance(acc(ig)-acc(i), 0.0, 1e-12);
+        }
+
+   }
+    
+    void hessianTest()
+    {
+        Image refxx(lenna.size());
+        Image refxy(lenna.size());
+        Image refyy(lenna.size());
+
+        importImage(vigra::ImageImportInfo("lennahessxx.xv"), destImage(refxx));
+        importImage(vigra::ImageImportInfo("lennahessyy.xv"), destImage(refyy));
+        importImage(vigra::ImageImportInfo("lennahessxy.xv"), destImage(refxy));
+        {
+            Image resxx(lenna.size());
+            Image resxy(lenna.size());
+            Image resyy(lenna.size());
+
+            hessianMatrixOfGaussian(srcImageRange(lenna), 
+                destImage(resxx), destImage(resxy), destImage(resyy), 1.0);
+            
+            Image::ScanOrderIterator i1 = resxx.begin();
+            Image::ScanOrderIterator i1end = resxx.end();
+            Image::ScanOrderIterator i2 = resyy.begin();
+            Image::ScanOrderIterator i3 = resxy.begin();
+            Image::ScanOrderIterator r1 = refxx.begin();
+            Image::ScanOrderIterator r2 = refyy.begin();
+            Image::ScanOrderIterator r3 = refxy.begin();
+            Image::Accessor acc = constimg.accessor();
+        
+        
+            for(; i1 != i1end; ++i1, ++i2, ++i3, ++r1, ++r2, ++r3)
+            {
+                shouldEqualTolerance(acc(i1)-acc(r1), 0.0, 1e-12);
+                shouldEqualTolerance(acc(i2)-acc(r2), 0.0, 1e-12);
+                shouldEqualTolerance(acc(i3)-acc(r3), 0.0, 1e-12);
+            }
+        }
+        {
+            Image resxx(lenna.size());
+            Image resxy(lenna.size());
+            Image resyy(lenna.size());
+
+            hessianMatrixOfGaussian(View(lenna), 
+                                    View(resxx), View(resxy), View(resyy), 1.0);
+            
+            Image::ScanOrderIterator i1 = resxx.begin();
+            Image::ScanOrderIterator i1end = resxx.end();
+            Image::ScanOrderIterator i2 = resyy.begin();
+            Image::ScanOrderIterator i3 = resxy.begin();
+            Image::ScanOrderIterator r1 = refxx.begin();
+            Image::ScanOrderIterator r2 = refyy.begin();
+            Image::ScanOrderIterator r3 = refxy.begin();
+            Image::Accessor acc = constimg.accessor();
+        
+        
+            for(; i1 != i1end; ++i1, ++i2, ++i3, ++r1, ++r2, ++r3)
+            {
+                shouldEqualTolerance(acc(i1)-acc(r1), 0.0, 1e-12);
+                shouldEqualTolerance(acc(i2)-acc(r2), 0.0, 1e-12);
+                shouldEqualTolerance(acc(i3)-acc(r3), 0.0, 1e-12);
+            }
+        }
+    }
+    
+    void structureTensorTest()
+    {
+        Image resxx(lenna.size());
+        Image resxy(lenna.size());
+        Image resyy(lenna.size());
+        Image refxx(lenna.size());
+        Image refxy(lenna.size());
+        Image refyy(lenna.size());
+        
+        typedef BasicImage<TinyVector<double, 3> > VectorImage;
+        VectorImage resst(lenna.size());
+
+        structureTensor(View(lenna), 
+                        View(resxx), View(resxy), View(resyy), 1.0, 2.0);
+
+        structureTensor(View(lenna), MultiArrayView<2, TinyVector<double, 3> >(resst), 1.0, 2.0);
+            
+        importImage(vigra::ImageImportInfo("lennastxx.xv"), destImage(refxx));
+        importImage(vigra::ImageImportInfo("lennastyy.xv"), destImage(refyy));
+        importImage(vigra::ImageImportInfo("lennastxy.xv"), destImage(refxy));
+        
+        Image::ScanOrderIterator i1 = resxx.begin();
+        Image::ScanOrderIterator i1end = resxx.end();
+        Image::ScanOrderIterator i2 = resxy.begin();
+        Image::ScanOrderIterator i3 = resyy.begin();
+        VectorImage::ScanOrderIterator i4 = resst.begin();
+        Image::ScanOrderIterator r1 = refxx.begin();
+        Image::ScanOrderIterator r2 = refxy.begin();
+        Image::ScanOrderIterator r3 = refyy.begin();
+        Image::Accessor acc = constimg.accessor();
+        VectorImage::Accessor vacc = resst.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2, ++i3, ++i4, ++r1, ++r2, ++r3)
+        {
+            shouldEqualTolerance(acc(i1), acc(r1), 1e-7);
+            shouldEqualTolerance(acc(i2), acc(r2), 1e-7);
+            shouldEqualTolerance(acc(i3), acc(r3), 1e-7);
+            shouldEqualTolerance(vacc(i4)[0], acc(r1), 1e-7);
+            shouldEqualTolerance(vacc(i4)[1], acc(r2), 1e-7);
+            shouldEqualTolerance(vacc(i4)[2], acc(r3), 1e-7);
+        }
+    }
+    
+    void structureTensorRGBTest()
+    {
+        RGBImage input(lenna.size());
+        importImage(vigra::ImageImportInfo("lenna128rgb.xv"), destImage(input));
+
+        typedef BasicImage<TinyVector<double, 3> > VectorImage;
+        VectorImage resst(lenna.size()), refst(lenna.size());
+
+        structureTensor(srcImageRange(lenna), destImage(resst), 1.0, 2.0);
+        
+        importImage(vigra::ImageImportInfo("lennargbst.xv"), destImage(refst));
+        
+        VectorImage::ScanOrderIterator i1 = resst.begin();
+        VectorImage::ScanOrderIterator i1end = resst.end();
+        VectorImage::ScanOrderIterator r1 = refst.begin();
+        VectorImage::Accessor vacc = resst.accessor();
+
+        for(; i1 != i1end; ++i1, ++r1)
+        {
+            shouldEqualTolerance(vacc(i1)[0], vacc(r1)[0], 1e-7);
+            shouldEqualTolerance(vacc(i1)[1], vacc(r1)[1], 1e-7);
+            shouldEqualTolerance(vacc(i1)[2], vacc(r1)[2], 1e-7);
+        }
+    }
+    
+    void stdConvolutionTest()
+    {
+        vigra::Kernel1D<double> binom1;
+        binom1.initBinomial(1);
+        
+        vigra::Kernel2D<double> binom2;
+        binom2.initSeparable(binom1, binom1);
+        
+        Image tmp1(constimg);
+        tmp1 = 0.0;
+
+        convolveImage(srcImageRange(constimg), destImage(tmp1), kernel2d(binom2));
+        
+        Image::ScanOrderIterator i1 = constimg.begin();
+        Image::ScanOrderIterator i1end = constimg.end();
+        Image::ScanOrderIterator i2 = tmp1.begin();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(acc(i1) == acc(i2));
+        }
+    }
+    
+    void stdVersusSeparableConvolutionTest()
+    {
+        
+        vigra::Kernel1D<double> gauss1;
+        gauss1.initGaussian(2.0);
+        
+        vigra::Kernel2D<double> gauss2;
+        gauss2.initSeparable(gauss1, gauss1);
+        
+        Image tmp1(lenna);
+        tmp1 = 0.0;
+
+        convolveImage(srcImageRange(lenna), destImage(tmp1), kernel2d(gauss2));
+        
+        Image tmp2(lenna);
+        Image tmp3(lenna);
+        tmp3 = 0.0;
+        
+        separableConvolveX(srcImageRange(lenna), destImage(tmp2), kernel1d(gauss1));
+        separableConvolveY(srcImageRange(tmp2), destImage(tmp3), kernel1d(gauss1));
+        
+        Image::Iterator y1 = tmp1.upperLeft() - gauss2.upperLeft();
+        Image::Iterator end = tmp1.lowerRight() - gauss2.lowerRight();
+        Image::Iterator y2 = tmp3.upperLeft() - gauss2.upperLeft();
+        Image::Accessor acc = tmp1.accessor();
+        
+        for(; y1.y != end.y; ++y1.y, ++y2.y)
+        {
+            Image::Iterator x1 = y1;
+            Image::Iterator x2 = y2;
+            for(; x1.x != end.x; ++x1.x, ++x2.x)
+            {
+                shouldEqualTolerance(acc(x1), acc(x2), 1e-7);
+            }
+        }
+    }
+    
+    void recursiveFilterTestWithAvoid()
+    {
+        Image src_const(25, 25);
+        Image dest(src_const);
+        src_const.init(42.1);
+        dest.init(1.12);
+
+        recursiveFilterX(srcImageRange(src_const), destImage(dest), VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_AVOID);
+
+        Image::Iterator is = src_const.upperLeft();
+        Image::Iterator tmp_src = src_const.upperLeft();
+        Image::Iterator isend = src_const.lowerRight();
+        Image::Iterator id = dest.upperLeft();
+        Image::Iterator tmp_dest = dest.upperLeft();
+        Image::Accessor acc = src_const.accessor();
+
+        for(int y = 0; is.y != isend.y; is.y++, id.y++, y++)
+        {
+            for (int x = 0 ; is.x != isend.x ; is.x++, id.x++, x++)
+            {
+                if (x < 11 || x > 13)
+                {
+                    should (acc(id) == 1.12);
+                }
+                else
+                {
+                    shouldEqualTolerance (acc(id) , acc(is), 1e-15);
+                }
+            }
+            is.x = tmp_src.x;
+            id.x = tmp_dest.x;
+        }
+
+        recursiveFilterY(srcImageRange(src_const), destImage(dest), 
+                         VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_AVOID);
+
+        is = src_const.upperLeft();
+        tmp_src = src_const.upperLeft();
+        isend = src_const.lowerRight();
+        id = dest.upperLeft();
+        tmp_dest = dest.upperLeft();
+        acc = src_const.accessor();
+
+        for(int y = 0; is.y != isend.y; is.y++, id.y++, y++)
+        {
+            for (int x = 0 ; is.x != isend.x ; is.x++, id.x++, x++)
+            {
+                if ((x > 10 && x < 14) || (y > 10 && y < 14))
+                {
+                    shouldEqualTolerance(acc(is) , acc(id), 1e-15);
+                }
+                else
+                {
+                    should(acc(id) == 1.12);
+                }
+            }
+            is.x = tmp_src.x;
+            id.x = tmp_dest.x;
+        }
+
+        // Hier wird an einem symmetrischen Bild /\ getestet 
+        // ob die korrekten Daten eingehalten wurden.
+
+        Image src(getSymmetricLine()), srct(getSymmetricLine(true));
+        dest = src;
+        Image destt(srct);
+
+        Image::value_type correct_data[40] = 
+            {0.25, 1.25, 2.25, 3.25, 4.25, 5.25, 6.25, 7.25, 8.25, 9.25, 
+             10.25, 11.249812, 12.249472, 13.248558, 14.246079, 15.239341, 
+             16.221025, 17.171238, 18.035903, 18.668023, 
+             18.668023, 18.035903, 17.171238, 16.221025, 15.239341, 
+             14.246079, 13.248558, 12.249472, 11.249812, 10.25, 9.25, 
+             8.25, 7.25, 6.25, 5.25, 4.25, 3.25, 2.25, 1.25, 0.25};
+
+        recursiveFilterX(View(src), View(dest), 
+                         VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_AVOID);
+        recursiveFilterY(View(srct), View(destt), 
+                         VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_AVOID);
+        Image::iterator dest_iter = dest.begin();
+        Image::iterator destt_iter = destt.begin();
+
+        for (int i = 0 ; i < 40; i++)
+        {
+            shouldEqualTolerance (correct_data[i], dest_iter[i], 1e-7);
+            shouldEqualTolerance (correct_data[i], destt_iter[i], 1e-7);
+        }
+
+    }// end of recursiveFilterTestWithAvoid
+
+    void recursiveFilterTestWithReflect()
+    {
+        Image src_const(25, 25);
+        Image dest(src_const);
+        src_const.init(42.1);
+        dest.init(1.12);
+
+        recursiveFilterX(srcImageRange(src_const), destImage(dest), 
+                     VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_REFLECT);
+
+        Image::Iterator is = src_const.upperLeft();
+        Image::Iterator tmp_src = src_const.upperLeft();
+        Image::Iterator isend = src_const.lowerRight();
+        Image::Iterator id = dest.upperLeft();
+        Image::Iterator tmp_dest = dest.upperLeft();
+        Image::Accessor acc = src_const.accessor();
+
+        for(int y = 0; is.y != isend.y; is.y++, id.y++, y++)
+        {
+            for (int x = 0 ; is.x != isend.x ; is.x++, id.x++, x++)
+            {
+                shouldEqualTolerance (acc(id) , acc(is), 1e-15);
+            }
+            is.x = tmp_src.x;
+            id.x = tmp_dest.x;
+        }
+
+        recursiveFilterY(srcImageRange(dest), destImage(dest), 
+                   VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_REFLECT);
+
+        is = src_const.upperLeft();
+        tmp_src = src_const.upperLeft();
+        isend = src_const.lowerRight();
+        id = dest.upperLeft();
+        tmp_dest = dest.upperLeft();
+        acc = src_const.accessor();
+
+        for(int y = 0; is.y != isend.y; is.y++, id.y++, y++)
+        {
+            for (int x = 0 ; is.x != isend.x ; is.x++, id.x++, x++)
+            {
+                shouldEqualTolerance(acc(is) , acc(id), 1e-15);
+            }
+            is.x = tmp_src.x;
+            id.x = tmp_dest.x;
+        }
+
+        // Hier wird an einem symmetrischen Bild /\ (Groesse 40x1)  getestet 
+        // ob die korrekten Daten eingehalten wurden.
+
+        Image src(getSymmetricLine());
+        dest = src;
+        recursiveFilterX(srcImageRange(src), destImage(dest), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_REFLECT);
+        Image::value_type correct_data[40] = 
+           {1.10091101909, 1.56303266253, 2.36515826013, 3.29236429975, 4.26558480098, 
+            5.25573290944, 6.25210788209, 7.25077235463, 8.25027572885, 9.25007858906, 
+            10.2499668097, 11.2498189802, 12.2494745341, 13.2485593473, 14.2460793794, 
+            15.2393409851, 16.2210251818, 17.171238053, 18.0359027479, 18.6680232997, 
+            18.6680232997, 18.0359027479, 17.171238053, 16.2210251818, 15.2393409851, 
+            14.2460793794, 13.2485593473, 12.2494745342, 11.2498189803, 10.24996681, 
+            9.25007858994, 8.25027573123, 7.2507723611, 6.2521078997, 5.2557329573, 
+            4.26558493107, 3.29236465337, 2.36515922136, 1.56303527544, 1.10091812172};
+
+        Image::iterator dest_iter = dest.begin();
+        for (int i = 0 ; i < 40; i++)
+        {
+            shouldEqualTolerance (correct_data[i], dest_iter[i], 1e-10);
+        }
+    }// end of recursiveFilterTestWithReflect
+
+
+    void recursiveFilterTestWithClipOnConstImage()
+    {
+        Image src_const(25, 25);
+        Image dest(src_const);
+        src_const.init(42.1);
+        dest.init(1.12);
+        recursiveFilterX(srcImageRange(src_const), destImage(dest), 
+                           VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_CLIP);
+
+        Image::Iterator is = src_const.upperLeft();
+        Image::Iterator tmp_src = src_const.upperLeft();
+        Image::Iterator isend = src_const.lowerRight();
+        Image::Iterator id = dest.upperLeft();
+        Image::Iterator tmp_dest = dest.upperLeft();
+        Image::Accessor acc = src_const.accessor();
+
+        for(int y = 0; is.y != isend.y; is.y++, id.y++, y++)
+        {
+            for (int x = 0 ; is.x != isend.x ; is.x++, id.x++, x++)
+            {
+                shouldEqualTolerance (acc(id), acc(is), 0.000001);
+            }
+            is.x = tmp_src.x;
+            id.x = tmp_dest.x;
+        }
+
+        recursiveFilterY(srcImageRange(src_const), destImage(dest), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_CLIP);
+
+        is = src_const.upperLeft();
+        tmp_src = src_const.upperLeft();
+        isend = src_const.lowerRight();
+        id = dest.upperLeft();
+        tmp_dest = dest.upperLeft();
+        acc = src_const.accessor();
+
+        for(int y = 0; is.y != isend.y; is.y++, id.y++, y++)
+        {
+            for (int x = 0 ; is.x != isend.x ; is.x++, id.x++, x++)
+            {
+                shouldEqualTolerance (acc(id), acc(is), 0.000001);
+            }
+            is.x = tmp_src.x;
+            id.x = tmp_dest.x;
+        }
+    }// end of recursiveFilterTestWithClipOnConstImage()
+
+    void recursiveFilterTestWithClipOnNonConstImage(){
+        Image src(40, 1);
+        Image dest(src);
+        Image::value_type correct_data[40] = 
+            {0.831977, 1.53351, 2.3853, 3.31218, 4.27763, 5.26195, 
+            6.25506, 7.25211, 8.25086, 9.25035, 10.2501, 11.2501, 
+            12.25, 13.25, 14.25, 15.25, 16.25, 17.25, 18.25, 19.25, 
+            20.25, 21.25, 22.25, 23.25, 24.25, 25.25, 26.25, 27.25, 
+            28.2499, 29.2499, 30.2496, 31.2491, 32.2479, 33.2449, 
+            34.2381, 35.2224, 36.1878, 37.1147, 37.9665, 38.668};
+
+        Image::Accessor acc_src = src.accessor();
+        Image::iterator iter_src = src.begin();
+
+        for (int i = 0 ; i < 40 ; i++, iter_src++)
+        {
+            acc_src.set(i + 0.25, iter_src);
+        }
+
+        recursiveFilterX(srcImageRange(src), destImage(dest), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_CLIP);
+
+        Image::iterator idest = dest.begin();
+        Image::iterator idest_end = dest.end();
+        Image::Accessor dest_acc = dest.accessor();
+
+        for(int i = 0; idest != idest_end; idest++, i++)
+        {
+            shouldEqualTolerance (dest_acc(idest), correct_data[i], 0.00001);
+        }
+
+    }// end of recursiveFilterTestWithClipOnNonConstImage
+
+    void recursiveFilterTestWithWrap()
+    {
+        Image src_const(25, 25);
+        Image dest(src_const);
+        src_const.init(42.1);
+        dest.init(1.12);
+
+        recursiveFilterX(srcImageRange(src_const), destImage(dest), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_WRAP);
+
+        Image::Iterator is = src_const.upperLeft();
+        Image::Iterator tmp_src = src_const.upperLeft();
+        Image::Iterator isend = src_const.lowerRight();
+        Image::Iterator id = dest.upperLeft();
+        Image::Iterator tmp_dest = dest.upperLeft();
+        Image::Accessor acc = src_const.accessor();
+
+        for(int y = 0; is.y != isend.y; is.y++, id.y++, y++)
+        {
+            for (int x = 0 ; is.x != isend.x ; is.x++, id.x++, x++)
+            {
+                shouldEqualTolerance (acc(id) , acc(is), 1e-15);
+            }
+            is.x = tmp_src.x;
+            id.x = tmp_dest.x;
+        }
+
+        recursiveFilterY(srcImageRange(src_const), destImage(dest), 
+                    VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_WRAP);
+
+        is = src_const.upperLeft();
+        tmp_src = src_const.upperLeft();
+        isend = src_const.lowerRight();
+        id = dest.upperLeft();
+        tmp_dest = dest.upperLeft();
+        acc = src_const.accessor();
+
+        for(int y = 0; is.y != isend.y; is.y++, id.y++, y++)
+        {
+            for (int x = 0 ; is.x != isend.x ; is.x++, id.x++, x++)
+            {
+                shouldEqualTolerance(acc(is) , acc(id), 1e-15);
+            }
+            is.x = tmp_src.x;
+            id.x = tmp_dest.x;
+        }
+
+
+        // Hier wird an einem symmetrischen Bild /\ (Groesse 40x1)  getestet 
+        // ob die korrekten Daten eingehalten wurden.
+
+        Image src(getSymmetricLine());
+        dest = src;
+        recursiveFilterX(srcImageRange(src), destImage(dest), 
+                    VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_WRAP);
+        Image::value_type correct_data[40] = 
+            {0.8319696, 1.4640946, 2.328761, 3.2789745, 4.260659,
+            5.2539208, 6.2514412, 7.2505271, 8.2501855, 9.2500454,
+            10.249955, 11.249814, 12.249473, 13.248559, 14.246079,
+            15.239341, 16.221025, 17.171238, 18.035903, 18.668023,
+            18.668023, 18.035903, 17.171238, 16.221025, 15.239341,
+            14.246079, 13.248559, 12.249473, 11.249814, 10.249955,
+            9.2500454, 8.2501855, 7.2505271, 6.2514412, 5.2539208,
+            4.260659, 3.2789745, 2.328761, 1.4640946, 0.8319696};
+
+        Image::iterator dest_iter = dest.begin();
+
+        for (int i = 0 ; i < 40; i++)
+        {
+            shouldEqualTolerance (correct_data[i], dest_iter[i], 1e-7);
+        }
+
+    }// end of recursiveFilterTestWithWrap
+
+    void recursiveFilterTestWithRepeat()
+    {
+        Image src_const(25, 25);
+        Image dest(src_const);
+        src_const.init(42.1);
+        dest.init(1.12);
+
+        recursiveFilterX(srcImageRange(src_const), destImage(dest), 
+                    VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_REPEAT);
+
+        Image::Iterator is = src_const.upperLeft();
+        Image::Iterator tmp_src = src_const.upperLeft();
+        Image::Iterator isend = src_const.lowerRight();
+        Image::Iterator id = dest.upperLeft();
+        Image::Iterator tmp_dest = dest.upperLeft();
+        Image::Accessor acc = src_const.accessor();
+
+        for(int y = 0; is.y != isend.y; is.y++, id.y++, y++)
+        {
+            for (int x = 0 ; is.x != isend.x ; is.x++, id.x++, x++)
+            {
+                shouldEqualTolerance (acc(id) , acc(is), 1e-15);
+            }
+            is.x = tmp_src.x;
+            id.x = tmp_dest.x;
+        }
+        recursiveFilterY(srcImageRange(src_const), destImage(dest), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_REPEAT);
+
+        is = src_const.upperLeft();
+        tmp_src = src_const.upperLeft();
+        isend = src_const.lowerRight();
+        id = dest.upperLeft();
+        tmp_dest = dest.upperLeft();
+        acc = src_const.accessor();
+
+        for(int y = 0; is.y != isend.y; is.y++, id.y++, y++)
+        {
+            for (int x = 0 ; is.x != isend.x ; is.x++, id.x++, x++)
+            {
+                shouldEqualTolerance(acc(is) , acc(id), 1e-15);
+            }
+            is.x = tmp_src.x;
+            id.x = tmp_dest.x;
+        }
+
+        // Hier wird an einem symmetrischen Bild /\ (Groesse 40x1)  getestet 
+        // ob die korrekten Daten eingehalten wurden.
+
+        Image src(getSymmetricLine());
+        dest = src;
+        recursiveFilterX(srcImageRange(src), destImage(dest), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_REPEAT);
+        Image::value_type correct_data[40] = 
+            {0.67545906, 1.4065176, 2.3075796, 3.2711823, 4.2577924, 
+            5.2528662, 6.2510533, 7.2503844, 8.250133, 9.2500261, 
+            10.249947, 11.249812, 12.249472, 13.248558, 14.246079, 
+            15.239341, 16.221025, 17.171238, 18.035903, 18.668023, 
+            18.668023, 18.035903, 17.171238, 16.221025, 15.239341, 
+            14.246079, 13.248558, 12.249472, 11.249812, 10.249947, 
+            9.2500261, 8.250133, 7.2503844, 6.2510533, 5.2528662, 
+            4.2577924, 3.2711823, 2.3075796, 1.4065176, 0.67545906};
+
+        Image::iterator dest_iter = dest.begin();
+
+        for (int i = 0 ; i < 40; i++)
+        {
+            shouldEqualTolerance (correct_data[i], dest_iter[i], 1e-7);
+        }
+
+    }// end of recursiveFilterTestWithRepeat
+
+    void recursiveFilterTestFromWrapWithReflect()
+    {
+
+        Image src_wrap(78, 1);
+        Image src_reflect(40, 1);
+        Image dest_wrap(src_wrap);
+        Image dest_reflect(src_reflect);
+
+        Image::Accessor acc_src_wrap = src_wrap.accessor();
+        Image::iterator iter_src_wrap = src_wrap.begin();
+        Image::Accessor acc_src_reflect = src_reflect.accessor();
+        Image::iterator iter_src_reflect = src_reflect.begin();
+
+        for (int i = 0 ; i < 40 ; i++, iter_src_wrap++, iter_src_reflect++)
+        {
+            acc_src_wrap.set(i + 0.25, iter_src_wrap);
+            acc_src_reflect.set(i + 0.25, iter_src_reflect);
+        }
+        for (int j = 38 ; j > 0 ; j--, iter_src_wrap++)
+        {
+            acc_src_wrap.set( j + 0.25, iter_src_wrap);
+        }
+
+        recursiveFilterX(srcImageRange(src_wrap), destImage(dest_wrap), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_WRAP);
+
+        recursiveFilterX(srcImageRange(src_reflect), destImage(dest_reflect), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_REFLECT);
+
+        Image::iterator iter_dest_wrap = dest_wrap.begin();
+        Image::Accessor acc_dest_wrap = dest_wrap.accessor();
+        Image::iterator iter_dest_reflect = dest_reflect.begin();
+        Image::iterator end_dest_reflect = dest_reflect.end();
+        Image::Accessor acc_dest_reflect = dest_reflect.accessor();
+
+        while(iter_dest_reflect != end_dest_reflect)
+        {
+            shouldEqualTolerance(acc_dest_wrap(iter_dest_wrap), 
+                           acc_dest_reflect(iter_dest_reflect), 1e-6);
+            iter_dest_wrap++;
+            iter_dest_reflect++;
+        }
+    }
+
+    void recursiveFilterTestFromRepeatWithAvoid()
+    {
+        Image src_avoid(40, 1);
+        src_avoid.init(11.47);
+        Image src_repeat(18, 1);
+
+        Image dest_repeat(src_repeat);
+        Image dest_avoid(src_avoid);
+
+        Image::Accessor acc_src_avoid = src_avoid.accessor();
+        Image::iterator iter_src_avoid = src_avoid.begin();
+        Image::Accessor acc_src_repeat = src_repeat.accessor();
+        Image::iterator iter_src_repeat = src_repeat.begin();
+
+        int i = 0;
+        for ( ; i < 20 ; i++, iter_src_avoid++)
+        {
+            if(i > 10)
+            {
+                acc_src_repeat.set(i + 0.47, iter_src_repeat);
+                acc_src_avoid.set(i + 0.47, iter_src_avoid);
+                iter_src_repeat++;
+            }
+        }
+        i--;
+
+        for ( ; i >= 0 ; i--, iter_src_avoid++)
+        {
+            if(i > 10)
+            {
+                acc_src_repeat.set(i + 0.47, iter_src_repeat);
+                acc_src_avoid.set(i + 0.47, iter_src_avoid);
+                iter_src_repeat++;
+            }
+        }
+
+        recursiveFilterX(srcImageRange(src_repeat), destImage(dest_repeat), VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_REPEAT);
+        recursiveFilterX(srcImageRange(src_avoid), destImage(dest_avoid), VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_AVOID);
+
+        Image::Accessor acc_dest_repeat = dest_repeat.accessor();
+        Image::iterator dest_iter_repeat = dest_repeat.begin();
+
+        Image::Accessor acc_dest_avoid = dest_avoid.accessor();
+        Image::iterator dest_iter_avoid = dest_avoid.begin();
+
+        for (int i = 0 ; i < 39 ; i++, dest_iter_avoid++)
+        {
+            if (i < 11 || i > 28)
+            {
+                should(acc_dest_avoid(dest_iter_avoid) == 11.47);
+            }
+            else
+            {
+                shouldEqualTolerance(acc_dest_avoid(dest_iter_avoid), acc_dest_repeat(dest_iter_repeat), 1e-15);
+                dest_iter_repeat++;
+            }
+        }
+    }
+
+    /**
+   * Es wird die Positionierung der einzelnen 
+   * Punkte relativ zueinander getestet.
+   */
+    void recursiveFilterTestOfAllTreatmentsRelatively()
+    {
+        Image src(40, 1);
+
+        Image::Accessor acc_src = src.accessor();
+        Image::iterator iter_src = src.begin();
+
+        int i = 0;
+        for ( ; i < 20 ; i++, iter_src++)
+        {
+            acc_src.set(i + 0.25, iter_src);
+        }
+        i--;
+        for ( ; i >= 0 ; i--, iter_src++)
+        {
+            acc_src.set(i + 0.25, iter_src);
+        }
+
+        Image dest_avoid(src);
+        Image dest_repeat(src);
+        Image dest_reflect(src);
+        Image dest_wrap(src);
+        Image dest_clip(src);
+
+        recursiveFilterX(srcImageRange(src), destImage(dest_avoid), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_AVOID);
+        recursiveFilterX(srcImageRange(src), destImage(dest_repeat), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_REPEAT);
+        recursiveFilterX(srcImageRange(src), destImage(dest_reflect), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_REFLECT);
+        recursiveFilterX(srcImageRange(src), destImage(dest_wrap), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_WRAP);
+        recursiveFilterX(srcImageRange(src), destImage(dest_clip), 
+                VIGRA_CSTD::exp(-1.0), BORDER_TREATMENT_CLIP);
+                
+        iter_src = src.begin();
+        Image::iterator iter_dest_avoid = dest_avoid.begin();
+        Image::iterator iter_dest_repeat = dest_repeat.begin();
+        Image::iterator iter_dest_reflect = dest_reflect.begin();
+        Image::iterator iter_dest_wrap = dest_wrap.begin();
+        Image::iterator iter_dest_clip = dest_clip.begin();
+
+        for (int x = 0 ;  x < 40 ; x++)
+        {
+            if(x > 9 && x < 30 )
+            {
+                shouldEqualTolerance(iter_dest_avoid[x], iter_dest_repeat[x], 1e-5);
+                shouldEqualTolerance(iter_dest_avoid[x], iter_dest_reflect[x], 1e-5);
+                shouldEqualTolerance(iter_dest_avoid[x], iter_dest_wrap[x], 1e-5);
+                shouldEqualTolerance(iter_dest_avoid[x], iter_dest_clip[x], 1e-5);
+            }
+            else
+            {
+                should(iter_dest_avoid[x] == iter_src[x]);
+                should(iter_dest_repeat[x] < iter_dest_reflect[x]);
+                should(iter_dest_repeat[x] < iter_dest_clip[x]);
+                if (x < 2 || x > 37)
+                {
+                    should(iter_dest_clip[x] < iter_dest_reflect[x]);
+                }
+                else
+                {
+                    should(iter_dest_clip[x] > iter_dest_reflect[x]);
+                }
+            }
+        }
+    }
+    
+    void recursiveSmoothTest()
+    {
+        Image tmp1(constimg);
+        tmp1 = 0.0;
+
+        recursiveSmoothX(View(constimg), View(tmp1), 1.0);
+        recursiveSmoothY(View(tmp1), View(tmp1), 1.0);
+        
+        Image::ScanOrderIterator i1 = constimg.begin();
+        Image::ScanOrderIterator i1end = constimg.end();
+        Image::ScanOrderIterator i2 = tmp1.begin();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(acc(i1) == acc(i2));
+        }
+    }
+    
+    void recursiveGradientTest()
+    {
+        ImageImportInfo info("lenna128recgrad.xv");
+
+        Image recgrad(info.width(), info.height());
+        importImage(info, destImage(recgrad));
+        
+        Image tmp1(lenna);
+        tmp1 = 0.0;
+        Image tmp2(lenna);
+        tmp2 = 0.0;
+
+        recursiveFirstDerivativeX(View(lenna), View(tmp1), 1.0);
+        recursiveSmoothY(View(tmp1), View(tmp1), 1.0);
+        
+        recursiveSmoothX(View(lenna), View(tmp2), 1.0);
+        recursiveFirstDerivativeY(View(tmp2), View(tmp2), 1.0);
+        
+        Image::ScanOrderIterator i1 = tmp1.begin();
+        Image::ScanOrderIterator i1end = tmp1.end();
+        Image::ScanOrderIterator i2 = tmp2.begin();
+        Image::ScanOrderIterator i = recgrad.begin();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2, ++i)
+        {
+            double grad = sqrt(acc(i1)*acc(i1)+acc(i2)*acc(i2));
+            
+            shouldEqualTolerance(grad, acc(i), 1e-7);
+        }
+    }
+    
+    void recursiveSecondDerivativeTest()
+    {
+        double b = VIGRA_CSTD::exp(-1.0);
+        double factor = (1.0 - b) * (1.0 - b) / b;
+        
+        Image tmp1(rampimg);
+        tmp1 = 0.0;
+        Image tmp2(rampimg);
+        tmp2 = 0.0;
+
+        recursiveSmoothX(View(rampimg), View(tmp1), 1.0);
+        recursiveSecondDerivativeX(View(rampimg), View(tmp2), 1.0);
+        
+        Image::ScanOrderIterator i1 = rampimg.begin();
+        Image::ScanOrderIterator i1end = i1 + rampimg.width();
+        Image::ScanOrderIterator i2 = tmp1.begin();
+        Image::ScanOrderIterator i3 = tmp2.begin();
+        Image::Accessor acc = constimg.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2, ++i3)
+        {
+            double diff = factor * (acc(i2) - acc(i1));
+            shouldEqualTolerance(diff, acc(i3), 1e-7);
+        }
+    }
+    
+    void nonlinearDiffusionTest()
+    {
+         
+        Image res(lenna.size());
+                
+        Image comp(lenna.size());
+        importImage(vigra::ImageImportInfo("lenna128nonlinear.xv"), destImage(comp));
+
+        nonlinearDiffusion(srcImageRange(lenna), destImage(res),
+                           vigra::DiffusivityFunctor<double>(4.0), 4.0);
+        shouldEqualSequenceTolerance(res.begin(), res.end(), comp.begin(), 1e-7);
+
+        res = 0;
+        nonlinearDiffusion(View(lenna), View(res),
+                           vigra::DiffusivityFunctor<double>(4.0), 4.0);
+        shouldEqualSequenceTolerance(res.begin(), res.end(), comp.begin(), 1e-7);
+    }
+    
+    Image constimg, lenna, rampimg, sym_image, unsym_image;
+    vigra::Kernel2D<double> sym_kernel, unsym_kernel, line_kernel;
+    
+};
+
+struct ResamplingConvolutionTest
+{
+    typedef MultiArrayView<2, float> View;
+
+    void testKernelsSpline()
+    {
+        BSpline<3, double> spline, dspline(1);
+        ArrayVector<Kernel1D<double> > kernels(4);
+        Rational<int> samplingRatio(4), offset(1,8);
+        resampling_detail::MapTargetToSourceCoordinate 
+                   mapCoordinate(samplingRatio, offset);
+        createResamplingKernels(spline, mapCoordinate, kernels);
+        
+        for(unsigned int i = 0; i<kernels.size(); ++i)
+        {
+            double sum = 0.0;
+            for(int k = kernels[i].left(); k <= kernels[i].right(); ++k)
+            {
+                double x = rational_cast<double>(k + i / samplingRatio + offset);
+                shouldEqualTolerance(kernels[i][k], spline(x), 1e-14);
+                sum += kernels[i][k];
+            }
+            shouldEqualTolerance(sum, 1.0, 1e-14);
+        }
+
+        createResamplingKernels(dspline, mapCoordinate, kernels);
+        
+        for(unsigned int i = 0; i<kernels.size(); ++i)
+        {
+            double sum = 0.0;
+            for(int k = kernels[i].left(); k <= kernels[i].right(); ++k)
+            {
+                double x = rational_cast<double>(k + i / samplingRatio + offset);
+                shouldEqualTolerance(kernels[i][k], dspline(x), 1e-14);
+                sum += -x*kernels[i][k];
+            }
+            shouldEqualTolerance(sum, 1.0, 1e-14);
+        }
+    }
+    
+    void testKernelsGauss()
+    {
+        Gaussian<double> gauss(0.7), dgauss(0.7, 1);
+        ArrayVector<Kernel1D<double> > kernels(4);
+        Rational<int> samplingRatio(4), offset(1,8);
+        resampling_detail::MapTargetToSourceCoordinate 
+                   mapCoordinate(samplingRatio, offset);
+        createResamplingKernels(gauss, mapCoordinate, kernels);
+        
+        for(unsigned int i = 0; i<kernels.size(); ++i)
+        {
+            double sum = 0.0;
+            for(int k = kernels[i].left(); k <= kernels[i].right(); ++k)
+            {
+                double x = rational_cast<double>(k + i / samplingRatio + offset);
+                shouldEqualTolerance(kernels[i][k], gauss(x), 1e-4);
+                sum += kernels[i][k];
+            }
+            shouldEqualTolerance(sum, 1.0, 1e-14);
+       }
+
+        createResamplingKernels(dgauss, mapCoordinate, kernels);
+        
+        for(unsigned int i = 0; i<kernels.size(); ++i)
+        {
+            double sum = 0.0;
+            double f = i == 0 || i == 3 ? 1.00218 : 0.99851;
+            for(int k = kernels[i].left(); k <= kernels[i].right(); ++k)
+            {
+                double x = rational_cast<double>(k + i / samplingRatio + offset);
+                shouldEqualTolerance(kernels[i][k], f*dgauss(x), 1e-5);
+                sum += -x*kernels[i][k];
+            }
+            shouldEqualTolerance(sum, 1.0, 1e-14);
+        }
+    }
+    
+    void testOversamplingConstant()
+    {
+        BSpline<3, double> spline, dspline(1);
+        Rational<int> samplingRatio(4,1), offset(1,8);
+        
+        FImage img(100, 100);
+        img.init(1.0);
+        
+        int wnew = rational_cast<int>((img.width() - 1 - offset) * samplingRatio + 1);
+        int hnew = rational_cast<int>((img.height() - 1 - offset) * samplingRatio + 1);
+        
+        FImage res(wnew, hnew);
+        
+        resamplingConvolveImage(srcImageRange(img), destImageRange(res),
+             spline, samplingRatio, offset, spline, samplingRatio, offset);
+        for(FImage::iterator i = res.begin(); i < res.end(); ++i)
+            shouldEqual(*i, 1.0);
+        
+        resamplingConvolveImage(View(img), View(res),
+                                dspline, samplingRatio, offset, spline, samplingRatio, offset);
+        for(FImage::iterator i = res.begin(); i < res.end(); ++i)
+            shouldEqual(*i, 0.0);
+    }
+
+    void testOversamplingReal()
+    {
+        Gaussian<double> gauss(0.7);
+        Rational<int> samplingRatio(2,1), offset(1,4);
+        
+        ImageImportInfo info("lenna128.xv");
+        FImage img(info.size());
+        importImage(info, destImage(img));
+        
+        int wnew = rational_cast<int>((info.width() - 1 - offset) * samplingRatio + 1);
+        int hnew = rational_cast<int>((info.height() - 1 - offset) * samplingRatio + 1);
+        
+        FImage res(wnew, hnew);        
+        resamplingConvolveImage(View(img), View(res),
+             gauss, samplingRatio, offset, gauss, samplingRatio, offset);
+             
+        ImageImportInfo rinfo("resampling.xv");
+        shouldEqual(rinfo.width(), wnew);
+        shouldEqual(rinfo.height(), hnew);
+        FImage ref(wnew, hnew);        
+        importImage(rinfo, destImage(ref));
+
+        for(FImage::iterator i = res.begin(), j = ref.begin(); i < res.end(); ++i, ++j)
+            shouldEqualTolerance(*i, *j, 1e-6);
+    }
+};
+
+struct ImagePyramidTest
+{
+    typedef vigra::DImage Image;
+    Image img;
+    int w, h;
+
+    ImagePyramidTest()
+    {
+        ImageImportInfo ginfo("lenna128.xv");
+        w = ginfo.width();
+        h = ginfo.height();
+        img.resize(w, h);
+        importImage(ginfo, destImage(img));
+    }
+
+    void testPyramidConstruction()
+    {
+        vigra::ImagePyramid<Image> pyramid(-2, 2, img);
+        
+        shouldEqual(pyramid[-2].size(), Size2D(509, 477));
+        shouldEqual(pyramid[-1].size(), Size2D(255, 239));
+        shouldEqual(pyramid[0].size(), Size2D(128, 120));
+        shouldEqual(pyramid[1].size(), Size2D(64, 60));
+        shouldEqual(pyramid[2].size(), Size2D(32, 30));
+    }
+
+    void testBurtReduceExpand()
+    {
+        vigra::ImagePyramid<Image> pyramid(-2, 3, img), laplacian(-2,3, img);
+        
+        pyramidExpandBurtFilter(pyramid, 0, -2);
+        pyramidReduceBurtFilter(pyramid, 0,  3);
+        
+        pyramidReduceBurtLaplacian(laplacian, 0, 3);
+
+        char buf[100];
+
+        for(int i=-2; i<=2; ++i)
+        {
+            if(i==0)
+                continue;
+
+            std::sprintf(buf, "lenna_level%d.xv", i);
+            ImageImportInfo info(buf);
+            shouldEqual(info.size(), pyramid[i].size());
+            
+            Image ref(info.size());
+            importImage(info, destImage(ref));
+            shouldEqualSequenceTolerance(ref.begin(), ref.end(), pyramid[i].begin(), 1e-12);
+        }
+        
+        for(int i=0; i<=2; ++i)
+        {
+            std::sprintf(buf, "lenna_levellap%d.xv", i);
+            ImageImportInfo info(buf);
+            shouldEqual(info.size(), laplacian[i].size());
+            
+            Image ref(info.size());
+            importImage(info, destImage(ref));
+            for(int k=0; k<info.width()*info.height(); ++k)
+                shouldEqualTolerance(ref.data()[k]-laplacian[i].data()[k], 0.0, 1e-12);
+        }
+        
+        shouldEqualSequenceTolerance(pyramid[3].begin(), pyramid[3].end(), laplacian[3].begin(), 1e-14);
+        
+        pyramidExpandBurtLaplacian(laplacian, 3, -2);
+
+        for(int i=3; i>=-2; --i)
+        {
+            shouldEqualSequenceTolerance(pyramid[i].begin(), pyramid[i].end(), laplacian[i].begin(), 1e-14);
+        }
+    }
+    
+};
+
+struct TotalVariationTest{
+  
+  const int width,height;
+  MultiArray<2,double> data;
+  MultiArray<2,double> out;
+  MultiArray<2,double> weight;
+  TotalVariationTest():width(50),height(50),data(Shape2(50,50)),out(Shape2(50,50)),weight(Shape2(50,50)){
+    for (int y=0;y<height;y++){
+      for (int x=0;x<width;x++){
+        weight(x,y)=1;
+        data(x,y)=testdata[x+width*y]/255.;
+      }
+    }
+  }
+  
+  void testTotalVariation(){
+   
+    totalVariationFilter(data,out,0.5,1000,0.01);
+    //exportImage(srcImageRange(out), vigra::ImageExportInfo("test_tv.pgm"));
+    shouldEqualSequenceTolerance(out.begin(), out.end(), result_std_tv, 1e-12); 
+  }
+  void testWeightedTotalVariation(){
+   
+    totalVariationFilter(data,weight,out,.5,1000,0.01);
+    //exportImage(srcImageRange(out), vigra::ImageExportInfo("test_tvw.pgm"));
+    shouldEqualSequenceTolerance(out.begin(), out.end(), result_std_tv_weight, 1e-12); 
+  }
+  
+  void testAnisotropicTotalVariation(){
+    
+    double alpha0=0.05,beta0=0.5,sigma=0.1,rho=.5,K=10;
+    int inner_steps=200,outer_steps=5;
+   
+    MultiArray<2,double> phi(Shape2(width,height));
+    MultiArray<2,double> alpha(Shape2(width,height));
+    MultiArray<2,double> beta(Shape2(width,height)); 
+    MultiArray<2,double> xedges(Shape2(width,height)); 
+    MultiArray<2,double> yedges(Shape2(width,height)); 
+    
+    for (int y=0;y<height;y++){
+      for (int x=0;x<width;x++){
+        alpha(x,y)=alpha0;
+        beta(x,y)=beta0;
+        xedges(x,y)=1;
+        yedges(x,y)=1;
+      }
+    }
+    out=data; 
+    for (int i=0;i<outer_steps;i++){ 
+      getAnisotropy(out,phi,alpha,beta,alpha0,beta0,sigma,rho,K);
+      anisotropicTotalVariationFilter(data,weight,phi,alpha,beta,out,inner_steps);  
+    }
+    //exportImage(srcImageRange(out), vigra::ImageExportInfo("test_aniso.pgm"));
+    shouldEqualSequenceTolerance(out.begin(), out.end(), result_aniso_tv, 1e-8); 
+  }
+    
+  void testSecondOrderTotalVariation(){
+    
+    double alpha0=0.05,beta0=0.5,sigma=0.1,rho=.5,K=10,gamma0=0.1;
+    int inner_steps=200,outer_steps=5;
+   
+    MultiArray<2,double> phi(Shape2(width,height));
+    MultiArray<2,double> alpha(Shape2(width,height));
+    MultiArray<2,double> beta(Shape2(width,height)); 
+    MultiArray<2,double> gamma(Shape2(width,height)); 
+    MultiArray<2,double> xedges(Shape2(width,height)); 
+    MultiArray<2,double> yedges(Shape2(width,height)); 
+    
+    for (int y=0;y<height;y++){
+      for (int x=0;x<width;x++){
+        alpha(x,y)=alpha0;
+        beta(x,y)=beta0;
+        gamma(x,y)=gamma0;
+        xedges(x,y)=1;
+        yedges(x,y)=1;
+      }
+    }
+    out=data; 
+    for (int i=0;i<outer_steps;i++){
+      getAnisotropy(out,phi,alpha,beta,alpha0,beta0,sigma,rho,K);
+      secondOrderTotalVariationFilter(data,weight,phi,alpha,beta,gamma,xedges,yedges,out,inner_steps);
+    }
+    //exportImage(srcImageRange(out), vigra::ImageExportInfo("test_htv.pgm"));
+    shouldEqualSequenceTolerance(out.begin(), out.end(), result_higher_order_tv,1e-12); 
+  }
+};
+
+
+struct ConvolutionTestSuite
+: public vigra::test_suite
+{
+    ConvolutionTestSuite()
+    : vigra::test_suite("ConvolutionTestSuite")
+    {
+        add( testCase( &ConvolutionTest::borderCopyTest));
+
+#if 1
+        add( testCase( &ConvolutionTest::initExplicitlyTest));
+
+        add( testCase( &ConvolutionTest::simpleSharpeningTest)); 
+        add( testCase( &ConvolutionTest::gaussianSharpeningTest)); 
+        add( testCase( &ConvolutionTest::stdConvolutionTestOnConstImage));
+        add( testCase( &ConvolutionTest::stdConvolutionTestWithAvoid));
+        add( testCase( &ConvolutionTest::stdConvolutionTestWithZeropad));
+        add( testCase( &ConvolutionTest::stdConvolutionTestWithClip));
+        add( testCase( &ConvolutionTest::stdConvolutionTestWithWrap));
+        add( testCase( &ConvolutionTest::stdConvolutionTestWithReflect));
+        add( testCase( &ConvolutionTest::stdConvolutionTestWithRepeat));
+        add( testCase( &ConvolutionTest::stdConvolutionTestFromWrapWithReflect));
+        add( testCase( &ConvolutionTest::stdConvolutionTestFromRepeatWithAvoid));
+        add( testCase( &ConvolutionTest::stdConvolutionTestOfAllTreatmentsRelatively));
+
+        add( testCase( &ConvolutionTest::separableConvolutionTest));
+        add( testCase( &ConvolutionTest::separableDerivativeRepeatTest));
+        add( testCase( &ConvolutionTest::separableDerivativeReflectTest));
+        add( testCase( &ConvolutionTest::separableDerivativeAvoidTest));
+        add( testCase( &ConvolutionTest::separableSmoothClipTest));
+        add( testCase( &ConvolutionTest::separableSmoothZeropadTest));
+        add( testCase( &ConvolutionTest::separableSmoothWrapTest));
+        add( testCase( &ConvolutionTest::gaussianSmoothingTest));
+        add( testCase( &ConvolutionTest::optimalSmoothing3Test));
+        add( testCase( &ConvolutionTest::optimalSmoothing5Test));
+        add( testCase( &ConvolutionTest::optimalGradient3Test));
+        add( testCase( &ConvolutionTest::optimalGradient5Test));
+        add( testCase( &ConvolutionTest::optimalLaplacian3Test));
+        add( testCase( &ConvolutionTest::optimalLaplacian5Test));
+        add( testCase( &ConvolutionTest::separableGradientTest));
+        add( testCase( &ConvolutionTest::gradientTest));
+        add( testCase( &ConvolutionTest::gradientRGBTest));
+        add( testCase( &ConvolutionTest::hessianTest));
+        add( testCase( &ConvolutionTest::structureTensorTest));
+        add( testCase( &ConvolutionTest::structureTensorRGBTest));
+        add( testCase( &ConvolutionTest::stdConvolutionTest));
+        add( testCase( &ConvolutionTest::stdVersusSeparableConvolutionTest));
+        add( testCase( &ConvolutionTest::recursiveFilterTestWithAvoid));
+        add( testCase( &ConvolutionTest::recursiveFilterTestWithClipOnConstImage));
+        add( testCase( &ConvolutionTest::recursiveFilterTestWithClipOnNonConstImage));
+        add( testCase( &ConvolutionTest::recursiveFilterTestWithReflect));
+        add( testCase( &ConvolutionTest::recursiveFilterTestWithWrap));
+        add( testCase( &ConvolutionTest::recursiveFilterTestWithRepeat));
+        add( testCase( &ConvolutionTest::recursiveFilterTestFromWrapWithReflect));
+        add( testCase( &ConvolutionTest::recursiveFilterTestFromRepeatWithAvoid));
+        add( testCase( &ConvolutionTest::recursiveFilterTestOfAllTreatmentsRelatively));
+        add( testCase( &ConvolutionTest::recursiveSmoothTest));
+        add( testCase( &ConvolutionTest::recursiveGradientTest));
+        add( testCase( &ConvolutionTest::recursiveSecondDerivativeTest));
+        add( testCase( &ConvolutionTest::nonlinearDiffusionTest));
+
+        add( testCase( &ResamplingConvolutionTest::testKernelsSpline));
+        add( testCase( &ResamplingConvolutionTest::testKernelsGauss));
+        add( testCase( &ResamplingConvolutionTest::testOversamplingConstant));
+        add( testCase( &ResamplingConvolutionTest::testOversamplingReal));
+
+        add( testCase( &ImagePyramidTest::testPyramidConstruction));
+        add( testCase( &ImagePyramidTest::testBurtReduceExpand));
+    
+        add( testCase( &TotalVariationTest::testTotalVariation));
+        add( testCase( &TotalVariationTest::testWeightedTotalVariation));
+        add( testCase( &TotalVariationTest::testAnisotropicTotalVariation));
+        add( testCase( &TotalVariationTest::testSecondOrderTotalVariation));
+#endif
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    ConvolutionTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+
+    return (failed != 0);
+}
+
diff --git a/test/convolution/tv_test_data.hxx b/test/convolution/tv_test_data.hxx
new file mode 100644
index 0000000..b905e22
--- /dev/null
+++ b/test/convolution/tv_test_data.hxx
@@ -0,0 +1,260 @@
+#ifndef __tv_test_data_h
+#define __tv_test_data_h
+
+double testdata[2500]={
+255.,255.,237.,113.,80.,113.,252.,167.,113.,196.,200.,255.,15.,129.,255.,183.,164.,213.,224.,230.,235.,206.,210.,240.,230.,183.,193.,216.,116.,174.,114.,168.,148.,255.,198.,234.,193.,191.,206.,156.,246.,182.,117.,255.,153.,163.,177.,67.,129.,239.,
+194.,242.,203.,224.,225.,130.,115.,168.,180.,210.,155.,190.,106.,179.,189.,213.,95.,207.,120.,251.,164.,136.,183.,225.,245.,146.,215.,255.,162.,249.,255.,225.,221.,191.,139.,225.,139.,239.,172.,215.,134.,203.,198.,128.,191.,255.,255.,189.,193.,142.,
+202.,119.,137.,167.,216.,196.,255.,189.,168.,100.,239.,104.,242.,130.,102.,150.,85.,255.,168.,161.,255.,172.,255.,201.,222.,157.,157.,234.,108.,159.,232.,138.,168.,110.,144.,145.,209.,148.,240.,255.,255.,122.,181.,135.,122.,201.,228.,117.,219.,255.,
+227.,223.,237.,206.,123.,199.,212.,177.,185.,229.,255.,255.,90.,188.,143.,248.,160.,220.,197.,210.,209.,158.,255.,203.,198.,161.,161.,218.,166.,235.,182.,163.,104.,229.,235.,255.,171.,102.,189.,187.,224.,156.,230.,255.,83.,255.,198.,181.,176.,132.,
+197.,181.,183.,196.,253.,192.,240.,233.,240.,94.,195.,220.,216.,182.,255.,182.,178.,165.,225.,204.,205.,134.,221.,251.,234.,222.,194.,198.,196.,255.,245.,163.,233.,200.,218.,113.,245.,129.,217.,175.,255.,174.,216.,239.,223.,134.,222.,248.,99.,255.,
+246.,204.,231.,121.,193.,245.,140.,107.,144.,87.,168.,187.,156.,163.,32.,255.,120.,11.,255.,255.,205.,191.,122.,97.,144.,190.,173.,214.,220.,106.,183.,213.,196.,206.,255.,172.,167.,188.,185.,255.,255.,171.,157.,253.,138.,155.,175.,211.,152.,169.,
+198.,192.,191.,184.,156.,140.,222.,89.,162.,225.,162.,98.,181.,254.,177.,255.,216.,165.,116.,181.,132.,184.,110.,194.,222.,172.,182.,220.,172.,205.,224.,159.,117.,199.,201.,197.,133.,236.,161.,241.,152.,149.,161.,167.,170.,87.,189.,222.,174.,193.,
+160.,173.,175.,169.,161.,209.,163.,240.,150.,180.,167.,239.,147.,195.,128.,219.,189.,148.,201.,187.,219.,193.,189.,246.,120.,33.,164.,168.,86.,137.,246.,248.,153.,255.,188.,185.,121.,160.,199.,175.,138.,230.,250.,219.,172.,181.,236.,217.,124.,196.,
+189.,228.,204.,223.,183.,164.,163.,121.,124.,89.,119.,209.,217.,151.,177.,81.,135.,235.,255.,255.,204.,131.,195.,147.,183.,198.,110.,133.,156.,213.,188.,110.,212.,111.,248.,161.,141.,228.,162.,164.,143.,141.,185.,158.,139.,202.,153.,71.,243.,255.,
+189.,154.,124.,244.,203.,191.,184.,231.,206.,251.,195.,184.,129.,211.,255.,196.,168.,138.,205.,91.,142.,44.,193.,140.,170.,188.,191.,217.,214.,173.,191.,191.,0.,255.,209.,214.,117.,223.,151.,167.,123.,115.,126.,62.,209.,211.,171.,142.,255.,203.,
+255.,154.,206.,177.,171.,153.,255.,219.,188.,202.,182.,156.,162.,171.,174.,206.,92.,202.,217.,83.,180.,232.,200.,145.,110.,172.,223.,177.,219.,199.,215.,76.,89.,90.,168.,225.,208.,193.,195.,175.,83.,120.,255.,255.,255.,255.,235.,171.,216.,164.,
+198.,119.,172.,44.,218.,187.,169.,119.,214.,172.,139.,173.,185.,248.,92.,224.,255.,217.,191.,165.,154.,191.,127.,97.,175.,169.,185.,180.,255.,142.,214.,161.,150.,171.,183.,165.,191.,255.,169.,178.,254.,244.,155.,247.,255.,185.,128.,148.,106.,192.,
+207.,218.,100.,172.,210.,187.,218.,201.,135.,107.,177.,185.,255.,206.,200.,190.,212.,192.,148.,255.,189.,37.,206.,149.,212.,129.,255.,255.,236.,249.,130.,68.,141.,148.,227.,214.,176.,209.,145.,205.,255.,163.,215.,159.,110.,134.,158.,151.,92.,238.,
+207.,246.,167.,255.,110.,62.,121.,237.,221.,154.,86.,42.,239.,222.,210.,158.,131.,100.,204.,255.,159.,197.,231.,237.,160.,224.,184.,255.,210.,104.,150.,218.,180.,152.,134.,116.,103.,114.,211.,250.,171.,187.,141.,218.,207.,195.,205.,209.,196.,179.,
+67.,238.,203.,255.,86.,215.,160.,80.,255.,135.,183.,155.,181.,156.,130.,78.,180.,161.,212.,233.,255.,171.,230.,233.,194.,110.,165.,113.,255.,175.,220.,165.,85.,179.,150.,229.,169.,97.,199.,255.,168.,228.,180.,219.,239.,126.,204.,167.,184.,108.,
+0.,178.,168.,193.,228.,171.,210.,135.,146.,243.,194.,82.,238.,251.,123.,169.,173.,135.,215.,244.,164.,231.,191.,209.,174.,255.,230.,152.,104.,209.,193.,204.,175.,208.,213.,47.,173.,255.,151.,147.,255.,209.,122.,154.,245.,255.,255.,218.,162.,92.,
+0.,241.,80.,178.,211.,162.,166.,225.,133.,225.,249.,215.,83.,206.,215.,141.,139.,210.,208.,197.,198.,231.,224.,191.,200.,228.,186.,201.,200.,166.,112.,143.,154.,113.,142.,153.,122.,227.,198.,199.,214.,187.,255.,248.,216.,110.,215.,196.,255.,114.,
+36.,222.,221.,190.,177.,167.,185.,235.,238.,158.,238.,135.,77.,186.,214.,178.,209.,77.,255.,199.,121.,161.,188.,198.,157.,191.,156.,164.,188.,207.,147.,219.,210.,222.,195.,185.,150.,223.,191.,214.,156.,194.,198.,244.,242.,91.,217.,158.,204.,130.,
+51.,204.,107.,152.,255.,185.,230.,217.,126.,113.,213.,197.,255.,192.,179.,110.,172.,191.,177.,121.,143.,255.,168.,143.,176.,139.,177.,211.,218.,154.,205.,223.,126.,239.,136.,218.,176.,137.,145.,171.,193.,189.,156.,153.,84.,126.,198.,117.,134.,119.,
+73.,125.,117.,210.,114.,212.,130.,173.,233.,238.,179.,185.,160.,114.,140.,182.,157.,194.,255.,163.,173.,169.,245.,214.,222.,134.,200.,217.,255.,131.,157.,188.,219.,180.,222.,136.,143.,162.,121.,184.,111.,60.,232.,223.,198.,251.,191.,227.,133.,0.,
+46.,90.,153.,120.,209.,112.,241.,180.,174.,75.,187.,110.,123.,180.,255.,197.,215.,166.,196.,173.,230.,185.,165.,116.,99.,169.,90.,139.,230.,220.,255.,186.,228.,159.,179.,255.,115.,79.,225.,213.,215.,175.,151.,58.,226.,255.,245.,180.,38.,37.,
+41.,163.,84.,162.,136.,243.,248.,199.,180.,185.,129.,255.,255.,244.,145.,130.,130.,170.,205.,207.,145.,205.,93.,204.,216.,236.,247.,140.,193.,194.,242.,240.,195.,144.,154.,173.,240.,225.,184.,207.,228.,255.,63.,215.,205.,235.,255.,212.,0.,61.,
+39.,192.,156.,172.,168.,53.,192.,170.,165.,198.,146.,216.,134.,255.,157.,161.,141.,90.,120.,195.,157.,236.,157.,106.,161.,162.,241.,187.,226.,178.,126.,245.,210.,255.,255.,123.,255.,200.,112.,255.,216.,120.,158.,146.,216.,195.,160.,7.,39.,0.,
+37.,220.,188.,240.,222.,206.,140.,151.,173.,208.,152.,114.,236.,234.,207.,157.,163.,195.,214.,195.,239.,125.,204.,206.,62.,255.,229.,234.,200.,193.,145.,146.,253.,247.,212.,226.,255.,187.,255.,202.,172.,145.,50.,208.,171.,0.,14.,0.,70.,25.,
+38.,173.,162.,195.,125.,147.,240.,111.,188.,213.,143.,147.,150.,101.,143.,161.,226.,115.,212.,155.,188.,229.,73.,191.,97.,70.,49.,0.,90.,77.,19.,12.,31.,0.,11.,0.,29.,76.,1.,60.,0.,0.,0.,5.,0.,4.,20.,0.,9.,22.,
+0.,239.,226.,142.,210.,213.,139.,117.,203.,135.,178.,151.,217.,207.,0.,184.,179.,255.,111.,252.,187.,97.,30.,0.,77.,0.,21.,78.,65.,0.,0.,79.,33.,0.,66.,29.,80.,13.,27.,36.,64.,0.,0.,0.,5.,70.,144.,0.,0.,9.,
+0.,234.,190.,227.,152.,137.,127.,134.,176.,178.,189.,194.,163.,161.,255.,101.,161.,201.,255.,164.,193.,92.,13.,41.,0.,12.,114.,0.,0.,0.,27.,59.,22.,25.,17.,25.,90.,36.,73.,46.,107.,39.,0.,51.,32.,0.,24.,7.,0.,76.,
+0.,222.,131.,96.,218.,200.,193.,142.,251.,203.,188.,175.,166.,96.,92.,255.,190.,196.,230.,191.,0.,29.,58.,0.,19.,59.,22.,0.,0.,24.,47.,52.,58.,0.,0.,0.,15.,24.,6.,108.,0.,0.,61.,99.,0.,6.,15.,56.,1.,88.,
+1.,164.,204.,162.,173.,174.,230.,227.,222.,171.,220.,251.,183.,179.,178.,89.,152.,100.,122.,110.,6.,34.,67.,42.,162.,5.,0.,13.,3.,0.,67.,0.,130.,0.,99.,69.,0.,0.,0.,81.,23.,0.,2.,0.,0.,14.,88.,111.,0.,31.,
+0.,183.,145.,215.,74.,225.,176.,102.,153.,167.,253.,113.,166.,204.,229.,208.,254.,218.,156.,0.,13.,59.,0.,0.,0.,46.,66.,39.,0.,0.,10.,0.,0.,11.,43.,0.,0.,87.,0.,8.,70.,2.,83.,0.,0.,0.,3.,31.,0.,30.,
+0.,115.,243.,226.,230.,224.,160.,169.,170.,140.,199.,239.,169.,218.,204.,217.,101.,178.,143.,0.,95.,38.,0.,0.,0.,12.,46.,23.,60.,88.,23.,142.,55.,100.,0.,45.,0.,62.,78.,0.,62.,59.,46.,0.,23.,61.,79.,0.,59.,88.,
+31.,87.,200.,230.,255.,255.,125.,140.,143.,235.,195.,170.,172.,190.,215.,223.,218.,38.,0.,0.,0.,9.,112.,49.,0.,44.,6.,0.,0.,0.,51.,0.,13.,81.,9.,8.,21.,0.,0.,13.,0.,0.,87.,126.,0.,36.,4.,73.,31.,55.,
+18.,228.,255.,132.,148.,186.,149.,255.,215.,255.,210.,122.,132.,204.,255.,255.,127.,27.,18.,0.,0.,0.,0.,22.,25.,44.,27.,0.,0.,58.,105.,40.,31.,133.,22.,0.,40.,77.,0.,100.,0.,0.,0.,45.,16.,43.,0.,0.,9.,0.,
+0.,169.,158.,194.,255.,157.,166.,85.,130.,57.,197.,197.,131.,255.,128.,118.,0.,0.,0.,12.,42.,72.,40.,1.,180.,1.,0.,38.,1.,0.,7.,21.,63.,59.,28.,22.,9.,3.,0.,0.,112.,10.,0.,0.,0.,58.,18.,11.,33.,0.,
+0.,116.,141.,149.,219.,86.,107.,228.,112.,196.,134.,201.,176.,208.,166.,0.,0.,2.,15.,43.,0.,0.,0.,28.,0.,90.,35.,77.,0.,0.,69.,0.,3.,0.,2.,0.,23.,61.,43.,26.,48.,127.,0.,9.,0.,0.,56.,0.,0.,0.,
+77.,135.,235.,247.,255.,243.,255.,138.,158.,179.,229.,210.,225.,85.,27.,0.,0.,47.,51.,70.,43.,0.,0.,75.,0.,0.,0.,4.,41.,79.,56.,38.,0.,1.,0.,0.,0.,39.,35.,8.,148.,47.,0.,0.,26.,25.,0.,5.,22.,0.,
+0.,192.,129.,201.,228.,235.,177.,168.,137.,152.,129.,211.,44.,115.,0.,63.,38.,45.,0.,26.,80.,41.,204.,0.,0.,10.,30.,21.,0.,0.,94.,55.,0.,33.,16.,15.,55.,0.,0.,63.,39.,8.,0.,0.,61.,0.,36.,72.,47.,0.,
+34.,173.,255.,190.,203.,255.,229.,112.,213.,126.,237.,140.,97.,40.,0.,6.,124.,6.,7.,0.,0.,44.,0.,43.,49.,0.,0.,0.,0.,0.,0.,65.,0.,0.,0.,0.,0.,0.,0.,18.,51.,97.,0.,53.,37.,0.,60.,0.,36.,0.,
+27.,183.,180.,163.,169.,146.,109.,174.,99.,228.,126.,27.,95.,89.,0.,154.,27.,48.,0.,23.,15.,16.,70.,38.,87.,40.,45.,0.,61.,83.,6.,58.,70.,0.,35.,66.,63.,0.,23.,54.,0.,0.,0.,1.,9.,45.,39.,12.,41.,0.,
+6.,110.,165.,171.,214.,173.,183.,228.,213.,40.,0.,35.,24.,1.,80.,25.,0.,0.,11.,39.,0.,49.,35.,128.,52.,37.,4.,47.,0.,71.,23.,13.,73.,51.,42.,0.,34.,47.,12.,76.,10.,1.,0.,0.,0.,99.,79.,0.,0.,0.,
+42.,149.,184.,183.,254.,146.,213.,80.,41.,43.,0.,106.,82.,26.,0.,52.,0.,0.,0.,0.,3.,46.,5.,81.,52.,0.,34.,0.,109.,0.,68.,0.,39.,0.,0.,0.,71.,0.,81.,0.,75.,75.,0.,0.,0.,92.,60.,142.,41.,83.,
+76.,164.,224.,185.,209.,226.,0.,32.,23.,0.,0.,67.,63.,82.,19.,0.,0.,0.,0.,0.,103.,0.,0.,0.,0.,0.,17.,0.,23.,65.,0.,6.,0.,8.,2.,0.,0.,0.,10.,0.,41.,39.,0.,0.,7.,45.,21.,0.,12.,49.,
+31.,216.,170.,228.,204.,15.,89.,0.,0.,28.,14.,0.,0.,69.,43.,78.,62.,0.,0.,0.,0.,0.,0.,0.,113.,9.,27.,0.,0.,45.,0.,61.,0.,44.,30.,0.,0.,0.,38.,0.,0.,20.,57.,16.,0.,26.,93.,0.,0.,16.,
+103.,166.,165.,133.,0.,71.,0.,18.,14.,55.,35.,0.,0.,72.,5.,2.,23.,0.,70.,0.,32.,22.,0.,107.,0.,89.,0.,59.,97.,30.,89.,57.,10.,56.,0.,57.,17.,58.,2.,0.,64.,0.,12.,0.,66.,0.,8.,127.,49.,0.,
+11.,238.,85.,0.,0.,0.,3.,55.,0.,34.,0.,0.,17.,0.,58.,83.,15.,43.,0.,22.,0.,0.,0.,24.,33.,0.,0.,23.,0.,50.,0.,95.,0.,3.,0.,94.,87.,49.,51.,35.,0.,84.,45.,61.,0.,94.,0.,56.,0.,33.,
+36.,106.,0.,24.,0.,53.,62.,0.,26.,101.,20.,16.,0.,0.,0.,0.,52.,0.,90.,0.,18.,0.,0.,0.,15.,40.,0.,0.,17.,44.,17.,2.,0.,24.,0.,48.,25.,0.,15.,0.,0.,51.,0.,0.,67.,78.,62.,12.,0.,24.,
+0.,7.,0.,174.,2.,33.,0.,0.,35.,0.,61.,22.,34.,0.,106.,5.,10.,0.,0.,34.,0.,0.,0.,57.,49.,108.,0.,0.,22.,7.,39.,0.,13.,23.,0.,0.,0.,50.,76.,74.,116.,0.,75.,0.,26.,0.,85.,0.,23.,0.,
+0.,15.,69.,27.,0.,0.,88.,0.,54.,47.,6.,64.,0.,20.,18.,0.,41.,0.,16.,15.,74.,0.,0.,0.,118.,75.,69.,20.,6.,0.,96.,0.,5.,113.,24.,89.,0.,8.,46.,0.,103.,0.,0.,0.,0.,17.,35.,0.,0.,6.,
+0.,36.,9.,0.,44.,0.,80.,47.,0.,4.,64.,52.,79.,0.,0.,0.,58.,0.,0.,14.,0.,0.,0.,2.,44.,0.,0.,0.,11.,6.,0.,6.,0.,5.,42.,49.,104.,0.,21.,71.,0.,0.,0.,65.,0.,60.,0.,28.,22.,11.,
+0.,101.,84.,23.,0.,0.,29.,59.,23.,73.,0.,98.,98.,0.,0.,0.,0.,0.,11.,95.,0.,0.,0.,15.,64.,0.,0.,97.,0.,0.,10.,69.,25.,0.,108.,0.,0.,86.,12.,0.,0.,28.,92.,9.,0.,28.,0.,36.,78.,80.
+};
+double result_std_tv[2500]={ 0.690308141687422,0.690556209131614,0.690999062999294,0.691550031214746,0.692120839763581,0.692650721536391,0.693116800384269,0.693518467290874,0.693847294995725,0.694067342741971,0.694122208700116,0.693963375695578,0.693580493411179,0.693010151519970,0.692315363320019,0.691568412680464,0.690851468005372,0.690255018444581,0.689858900879930,0.689705894158191,0.689779214779000,0.690015657660194,0.690330748280741,0.690651763603106,0.690940399492681,0.69119186330 [...]
+0.690476163038575,0.690734200212068,0.691191647703667,0.691753160091612,0.692322171496674,0.692833794617339,0.693266799514267,0.693626887222604,0.693913820063614,0.694098654604365,0.694128664205691,0.693956257095492,0.693570957835401,0.693006727439096,0.692321189121081,0.691582058264022,0.690868444813680,0.690268158511648,0.689857793640849,0.689685087875945,0.689742749952922,0.689977464150352,0.690306057457025,0.690645600029489,0.690947905164803,0.691204289985739,0.691426721347196,0.6916 [...]
+0.690775313250602,0.691048082555158,0.691526938701427,0.692102920434472,0.692665986365554,0.693144593032436,0.693520663923864,0.693810657870121,0.694027637195714,0.694154023883455,0.694143988365191,0.693952415419654,0.693568156652762,0.693019697343505,0.692354407879575,0.691630924885761,0.690923421470411,0.690315577322306,0.689881293649297,0.689676087128208,0.689704395502940,0.689923531382476,0.690254040123776,0.690604650619049,0.690919622581648,0.691185242885675,0.691407032841052,0.6916 [...]
+0.691155342395856,0.691436425415804,0.691926450953022,0.692505606523845,0.693051518453300,0.693485912381961,0.693794305506514,0.694005205730706,0.694145857418618,0.694210188364227,0.694160228089828,0.693954904104198,0.693582278284703,0.693062591352690,0.692428042999094,0.691724385981598,0.691021731458686,0.690402008528553,0.689939313106760,0.689696420059794,0.689686889094835,0.689871637985840,0.690175421020584,0.690511336405492,0.690830938802409,0.691117815273483,0.691355596500711,0.6915 [...]
+0.691559263262063,0.691831243217976,0.692304781838885,0.692859745166273,0.693369750611876,0.693751780336344,0.693992570955166,0.694130174142497,0.694204566625521,0.694219205355832,0.694142297422358,0.693936905495609,0.693590829763475,0.693115111294077,0.692523664763364,0.691846571375644,0.691151972447130,0.690524011633274,0.690036740931463,0.689755503178574,0.689700985932029,0.689835312094172,0.690087795355213,0.690386266192794,0.690702292413730,0.691034513742871,0.691305332732674,0.6915 [...]
+0.691909914062281,0.692155460980305,0.692583162338137,0.693084080675728,0.693540306594167,0.693867790615180,0.694048203766509,0.694122146152414,0.694141265660198,0.694119935970644,0.694031460414392,0.693841131855947,0.693537063156782,0.693123710299454,0.692597607374193,0.691970468603453,0.691306526151180,0.690691325315851,0.690196502246100,0.689884168749931,0.689781172178471,0.689857235044357,0.690049691826650,0.690300314387013,0.690590878525407,0.691037634378792,0.691313617818414,0.6916 [...]
+0.692134417962716,0.692348331376461,0.692717147830380,0.693147696350692,0.693541022873847,0.693818656426504,0.693949463782670,0.693965655150299,0.693929361978437,0.693873423822644,0.693780222515621,0.693614664182398,0.693364249314872,0.693030818252259,0.692599010306472,0.692061080517096,0.691468862068541,0.690902741818025,0.690429625522157,0.690109065350978,0.689973636347599,0.690008854564066,0.690162729263688,0.690387541147102,0.690664920246175,0.691091096937878,0.691474560023264,0.6918 [...]
+0.692233100339406,0.692421632967247,0.692737803043704,0.693100918371471,0.693429061818178,0.693658945915276,0.693745190636526,0.693703282540502,0.693601391914350,0.693498334076973,0.693393540683361,0.693249291946132,0.693053076164443,0.692808671956940,0.692497046337534,0.692091810754713,0.691620156956698,0.691151070370053,0.690737156124293,0.690444559459899,0.690313405637152,0.690347161673204,0.690501832645263,0.690743259389262,0.691079676402217,0.691500224044366,0.691939558837226,0.6924 [...]
+0.692272746945817,0.692443999045013,0.692726975373500,0.693041454489923,0.693302304692429,0.693475995479718,0.693511752906872,0.693410233298264,0.693237565997816,0.693074495874178,0.692942652323124,0.692796536472382,0.692632967578469,0.692465690898105,0.692281537056085,0.692034273508446,0.691718667151341,0.691394471138083,0.691093261220926,0.690879208651694,0.690794056388523,0.690857750170452,0.691033476335863,0.691302341196812,0.691693296173821,0.692174282993245,0.692688194703325,0.6932 [...]
+0.692294989696362,0.692441838228577,0.692719152311429,0.692997774719115,0.693173276540348,0.693288521579915,0.693276704860111,0.693126638932795,0.692899787283488,0.692679620146759,0.692519293242937,0.692336849414308,0.692166945748797,0.692039145760734,0.691963639782721,0.691871324984930,0.691726995913056,0.691577336453936,0.691425782432049,0.691343973499128,0.691365138974420,0.691502157682305,0.691715781901920,0.692002940473441,0.692444422878491,0.693007609867135,0.693616036759765,0.6942 [...]
+0.692349829372760,0.692408035478970,0.692721685277756,0.692938944415342,0.692955157761860,0.693062675841320,0.693036618483743,0.692854034577498,0.692599014556892,0.692311065088745,0.692171097435002,0.691905339692609,0.691708878819154,0.691592675541738,0.691615702465600,0.691648041431317,0.691593073855200,0.691634207295744,0.691697935686938,0.691803267647397,0.691995339860841,0.692277994441395,0.692590455289056,0.692910395030805,0.693373444737437,0.693973075930445,0.694636745416210,0.6952 [...]
+0.691682593375371,0.691760593581248,0.691883713541518,0.692125359643897,0.692599740273761,0.692834730400362,0.692840048617069,0.692611059017326,0.692393211727481,0.691910582501791,0.691331506770906,0.691361652628756,0.691251057743326,0.691105711267861,0.690982195881456,0.691222737572791,0.691405323692196,0.691646972144139,0.691945482156238,0.692242212245478,0.692632648733712,0.693120960619437,0.693609909062335,0.694016179563366,0.694484563691689,0.695061275706917,0.695697435434061,0.6963 [...]
+0.691655423835270,0.691670761125424,0.691657807847107,0.691846196287504,0.692385552690843,0.692692405240006,0.692748521562915,0.692312359963720,0.690513686606802,0.690302311534710,0.690244377332148,0.690377961808184,0.690622122325011,0.690670231328088,0.690702806939336,0.690925994933684,0.691229806217218,0.691673415317784,0.692273061296771,0.692657848757888,0.693177122139910,0.693799991842124,0.694444531734330,0.694989781746536,0.695506132444445,0.696061304054642,0.696642920474957,0.6972 [...]
+0.691611144538247,0.691602799630418,0.691229281538553,0.691242251106123,0.690981821716195,0.690565041729796,0.690420236584365,0.690265430424223,0.690333142653855,0.690260570343303,0.690190039601121,0.690173726189147,0.690280249806917,0.690307438610550,0.690292834721902,0.690213944567309,0.690407167682003,0.690887772515411,0.692372756198037,0.693009624615355,0.693643544104102,0.694321458245103,0.695026807909669,0.695664793742590,0.696241081444479,0.696800728557559,0.697352240764700,0.6978 [...]
+0.675099568707600,0.689369121161542,0.690953596324514,0.690994308004875,0.690268790567242,0.690403475131317,0.690373996895714,0.690310905313365,0.690280490734588,0.690216084871694,0.690146274086017,0.690093371400290,0.690067335406827,0.690038915684841,0.690008079026980,0.690013396257007,0.690172214016188,0.690529338657654,0.692099384109862,0.693362517281710,0.694038646460396,0.694727475943733,0.695441511006472,0.696111885105013,0.696719173816457,0.697286288283581,0.697825876436816,0.6983 [...]
+0.657055721575981,0.679974603664215,0.684554620556498,0.688814432387045,0.690340565071756,0.690173846597582,0.690245304026219,0.690243213913838,0.690202591496781,0.690141133959907,0.690075927920302,0.690016292623149,0.689919183549806,0.689847908194083,0.689784996274649,0.689774929635958,0.689876338921998,0.690095276483588,0.691520652889791,0.692897794516127,0.693936793103665,0.694997912448792,0.695731652362863,0.696425544494789,0.697041649651929,0.697603784781614,0.698128292515147,0.6986 [...]
+0.647610515748778,0.674814603280768,0.678082071040378,0.685062012931106,0.688852225212943,0.689801754935541,0.690111404284331,0.690110315446556,0.690064782930639,0.690019633101810,0.689961694907119,0.689969132941226,0.689761029123917,0.689691824662788,0.689589820861796,0.689560417263105,0.689661039117939,0.690007733264765,0.691072860167247,0.692052388484878,0.693356216160518,0.694896264192900,0.695921535321259,0.696665829899025,0.697279211117002,0.697826431415766,0.698328548668872,0.6988 [...]
+0.645782965155991,0.669989914910565,0.674713682078478,0.681104122936962,0.686430670758351,0.688423343156334,0.689670152762036,0.689955276641057,0.689848230127405,0.689673456050074,0.689600781097607,0.689408857566575,0.689454997534873,0.689455029853604,0.689374950504179,0.689337470858352,0.689393048033446,0.689725488160397,0.691092860372022,0.691972072714671,0.693232407380297,0.694988410784388,0.696166765726977,0.696867922575152,0.697432327354532,0.697963915849443,0.698449567635594,0.6989 [...]
+0.644811392650241,0.663415438497333,0.665724262348084,0.673211191133172,0.682778471779718,0.685995712217427,0.688658648842955,0.689296406888816,0.688146433155721,0.688731437861303,0.689065252141906,0.689153087343585,0.689352961020939,0.689320384015123,0.689197440558342,0.689117668126176,0.689251721269987,0.689611024933224,0.690816383689806,0.691493987777992,0.692397771050327,0.694617146720749,0.695825900553538,0.696740336314498,0.697446844104025,0.697993836926446,0.698463269408500,0.6989 [...]
+0.642435682722061,0.660789859452137,0.661287755518783,0.666010859901397,0.671017677853144,0.677078656282093,0.679946210371831,0.683167712976050,0.687199202145708,0.688906563684572,0.688109460603412,0.687640655121784,0.687191477375666,0.687122130058155,0.687653142476972,0.688326156739490,0.688543112324810,0.688898462759242,0.689977549335567,0.690379529032018,0.691183524392102,0.692990273438014,0.695718681573591,0.696726701693479,0.697517818520867,0.697992461360360,0.698365031540415,0.6987 [...]
+0.635872136043634,0.660459391383418,0.660466332185549,0.661642739782607,0.666749851927918,0.671365206235298,0.675672228541633,0.676311653508408,0.677090773920253,0.677925878754589,0.680443373094625,0.682534186721904,0.684054073576208,0.685114856122030,0.685839254435622,0.686785142814931,0.687489576881708,0.687612405674818,0.688803007016164,0.689103209380792,0.689623642737663,0.689792014752325,0.690603903478051,0.692067528205371,0.694624367774535,0.697752939291069,0.698124134351649,0.6985 [...]
+0.626959620876479,0.660221432945223,0.660196557329017,0.660441969660570,0.662717895651175,0.668700094340254,0.675086051978084,0.676071316927964,0.676117655535368,0.676414168544255,0.678101068260809,0.682247993768661,0.684729970771748,0.685174250811896,0.681331819704774,0.680448857572950,0.681145035050124,0.683193434984029,0.685595544102580,0.686494861796464,0.685389319805333,0.686113260411383,0.684934268355567,0.688639485243511,0.692459802580927,0.697386269777483,0.697804795975891,0.6982 [...]
+0.615450503701026,0.659884730631859,0.659919482714863,0.660211559530789,0.660483674255270,0.660762124747487,0.664014753305446,0.666078946199859,0.668099810736892,0.670257822282951,0.671602345622110,0.674588113077845,0.675468842067044,0.676117547718000,0.676027003130486,0.676032805614831,0.676172335180473,0.676898124152233,0.677497407263296,0.677906457326963,0.678195277942956,0.678261813155850,0.676846872564662,0.676681111776020,0.678149847879262,0.697209344769278,0.697561292483853,0.6979 [...]
+0.600322033555649,0.659240713717348,0.659725270150742,0.660326014937331,0.660482482906524,0.660672011011924,0.661191473909479,0.662161480010380,0.663397609934158,0.664657538946438,0.665704879690722,0.667888285223594,0.673415866968096,0.675958121495957,0.676067532660165,0.675168844157758,0.675959384233579,0.676899697105512,0.677589837231517,0.677966823236270,0.678316579019672,0.676216823381634,0.676590655345040,0.668889431386464,0.618972596525075,0.696892549768403,0.697433897729832,0.6977 [...]
+0.579827387032324,0.658497848100254,0.659703348067820,0.660258457182184,0.660373433473966,0.660521455819906,0.660707638075987,0.661034886596808,0.661715016105167,0.661784388043228,0.661789891932668,0.661924954700689,0.662417500572896,0.663667447075893,0.666199821362814,0.669652481124634,0.672243459373208,0.672709778434780,0.672997487556993,0.673436626447331,0.673726564530713,0.673928672722179,0.572277833328646,0.561144723369581,0.397092422141676,0.306963630798735,0.247511474412791,0.2182 [...]
+0.548939510164356,0.657600472807601,0.659879774162249,0.659997279300042,0.660149288494564,0.660354292514058,0.660574122780468,0.660796077676183,0.661451372043092,0.661593702708330,0.661633424134878,0.661655485986290,0.661808177930461,0.661642314227881,0.662164137478510,0.665716405140913,0.669448279583186,0.672511461733666,0.672438045399135,0.673536470282354,0.673038049003984,0.544698622658390,0.275609552943754,0.183082769674223,0.179358289113224,0.170416190958502,0.169794868294149,0.1699 [...]
+0.525998704772676,0.655619078923037,0.659524154956806,0.659748517489000,0.659904752420414,0.660119281794328,0.660366459628329,0.660620162742581,0.661097519615987,0.661360989953066,0.661446870821079,0.661377770508669,0.661181646621642,0.661123369986780,0.661195506811216,0.662041893966149,0.664274583331398,0.667511367714951,0.669859368723983,0.667057364331987,0.640017188061766,0.291697860128296,0.167108550622167,0.167090368698326,0.167072575629649,0.167070277264368,0.167069055253764,0.1320 [...]
+0.512261109067358,0.651187412132559,0.658965595472013,0.659277082090249,0.659545749555786,0.659949682809033,0.660145340392746,0.660471173518843,0.660823178452328,0.661151774811450,0.661323660763535,0.661312444845308,0.661285051997917,0.661263273894736,0.661211818533741,0.661082472629595,0.661292149651536,0.661538222061596,0.661419260615860,0.655874420346680,0.167177897851536,0.167158212902002,0.167121285607825,0.167096679927562,0.167077735561593,0.167073221703704,0.131994058679612,0.1314 [...]
+0.507405586792657,0.641386778525812,0.658371889535517,0.659138889214858,0.659192563179617,0.659713733438032,0.659868037814380,0.660278826797224,0.660534704482444,0.660789707923655,0.661089127766587,0.661178926005314,0.661312688928533,0.661442566573597,0.661533067615327,0.661565637637403,0.661705732099617,0.661989967441110,0.656982285119849,0.417708365288750,0.167173759742028,0.167166901474893,0.167119881479966,0.167005897285893,0.167083487282377,0.133333538860345,0.132710410576677,0.1321 [...]
+0.509711629292800,0.629018906946945,0.657242339015193,0.658748004965568,0.658802620501022,0.659418507683028,0.659486734612241,0.659765146768997,0.659988302390750,0.660329159900096,0.660788347203724,0.661001220561452,0.661265557846874,0.661530351293357,0.661738226927329,0.661858896774585,0.661896205139749,0.661534451303685,0.577463931915016,0.167146316986314,0.167161820849553,0.166742806061988,0.138751540429370,0.134882244358686,0.134453305401147,0.133912979529860,0.133357453515975,0.1328 [...]
+0.519726165668612,0.608937560216164,0.656185643359745,0.658283781995508,0.658814530853788,0.659086444598997,0.659174183744660,0.659496703653219,0.659642607455511,0.659900802630333,0.660395644192316,0.660862689317424,0.661248730407142,0.661633120245415,0.661910660537257,0.662128135903808,0.662380361377286,0.636675370911192,0.373033110193068,0.167132819296243,0.165768640608002,0.137217605667913,0.134569970603633,0.134676157038787,0.134603215947008,0.134283205180053,0.133840839492661,0.1333 [...]
+0.535998045473534,0.597048276966285,0.653555108186707,0.656830918278481,0.658372198877974,0.658970154449343,0.658592679447010,0.659368655204013,0.659499795351697,0.659743129570463,0.660138786958833,0.660555104342591,0.661098403764022,0.661758907004520,0.662133018322660,0.662207219980463,0.658957450954539,0.275368786288991,0.133178250963638,0.133356383643858,0.133681156513058,0.134222221928723,0.134516928056365,0.134699101305656,0.134705149343803,0.134510899707948,0.134165478040586,0.1337 [...]
+0.538609692991924,0.616656309204758,0.649808747659647,0.651474860039629,0.652350864213306,0.653898307771625,0.655611786297602,0.658902565711674,0.659382264321117,0.659588441872164,0.659968311725447,0.657258879239956,0.658304701794058,0.661825259630265,0.662517777245456,0.660069397100859,0.430270774378203,0.133517675311184,0.133415535953204,0.133510690837233,0.133763827767554,0.134134685747895,0.134455688168155,0.134677732700902,0.134745051088496,0.134633967578893,0.134366401197936,0.1339 [...]
+0.539436244486098,0.609814119235114,0.646079962052166,0.649980923663745,0.650018098773029,0.649836494796657,0.649655044583489,0.649529250083123,0.649390440274131,0.649278677984244,0.649169686821440,0.648939686895176,0.648695937426116,0.648538443874544,0.648420425693093,0.467981724497544,0.134048126430674,0.133829984029063,0.133719526144023,0.133747546181544,0.133908669623254,0.134170051105788,0.134447008219270,0.134666040256113,0.134763195108499,0.134705300913163,0.134500783099805,0.1341 [...]
+0.548476794084142,0.599490723191279,0.642621915536643,0.649522347718580,0.649944534149916,0.649914785223570,0.649752054873805,0.649575108283466,0.649389594527112,0.649299657668048,0.649224350643205,0.649002026277326,0.648749272044416,0.648606564636466,0.505038434588064,0.134541811919498,0.134333327053902,0.134153134152420,0.134038638406493,0.134018112961641,0.134106065335131,0.134286798971934,0.134507301942740,0.134701460074255,0.134805526414520,0.134780767578784,0.134629054315858,0.1343 [...]
+0.563991630999258,0.598393948767520,0.639629670874091,0.648793038072230,0.650266024375887,0.650127264780821,0.649898936524825,0.649656748162406,0.649310490455748,0.649318820212819,0.649426141968595,0.649097816891469,0.648728858009320,0.398666713212260,0.182405893845719,0.134770404323453,0.134617408561213,0.134455032653003,0.134334735401822,0.134283547170550,0.134325084256272,0.134453743432572,0.134629435288973,0.134796404269723,0.134897861908396,0.134896125376988,0.134791531719523,0.1346 [...]
+0.558388090303336,0.602827559944257,0.630995633865006,0.644264632962710,0.650058698389065,0.650428295796655,0.650095017461176,0.649876427656098,0.642740465615794,0.642417712601058,0.640978352013010,0.641086009634965,0.304098360478669,0.299106725228214,0.135288363842109,0.135083792535561,0.134889830347730,0.134715772512963,0.134589313041588,0.134526141424781,0.134548258066233,0.134653378580531,0.134805581561240,0.134955446544581,0.135054431847519,0.135070122174529,0.135005207746592,0.1348 [...]
+0.557027044975247,0.597768725213452,0.625618402012321,0.635432638507046,0.645795653473089,0.650693415118861,0.650214232265201,0.637314350716056,0.641327995492625,0.636993836745077,0.640606305666730,0.442158873075465,0.298740283202500,0.169112855611794,0.135422213079832,0.135289667748605,0.135097842848080,0.134924554241898,0.134805151118558,0.134749819112719,0.134776309401246,0.134881712279650,0.135030246000363,0.135174707455846,0.135273326731210,0.135301406026518,0.135267013954424,0.1352 [...]
+0.550374496174686,0.588913797027803,0.613051845564925,0.615227964481416,0.615168790492153,0.615092524464718,0.615026099691642,0.614877139816440,0.614707034675478,0.614638659278366,0.408014906516026,0.202838039014717,0.180602365605229,0.152041164303088,0.135672192882172,0.135502444729982,0.135279641330014,0.135105047269691,0.135005552113381,0.134975417664167,0.135024312177927,0.135146259964849,0.135303452747797,0.135447967057615,0.135542456729761,0.135571871682394,0.135552969072709,0.1355 [...]
+0.541008474567661,0.576071416935013,0.610535293512575,0.615178907365230,0.615139255081918,0.615086232567535,0.615023982489971,0.614943217017282,0.614647707617168,0.222322754098125,0.139279257424380,0.139129601848727,0.139107786660644,0.136657074965167,0.136101293773992,0.135773772581181,0.135484945798965,0.135298065323568,0.135222583023459,0.135227212416562,0.135307133040552,0.135451667405336,0.135620449395598,0.135763152081211,0.135843985205677,0.135857217189689,0.135830515839042,0.1358 [...]
+0.534651253497336,0.569899154800691,0.606822556307069,0.615163969673410,0.615128379230907,0.615100648613830,0.615053270121203,0.351412096653371,0.165224844003928,0.143390879597059,0.139540460034554,0.139165940171222,0.138003223091642,0.137083169946310,0.136268735582813,0.136012991780113,0.135722772327757,0.135544588125568,0.135496368183677,0.135531344177142,0.135634987310864,0.135794442589807,0.135968035163408,0.136101960373373,0.136159437601105,0.136141295041753,0.136084991942569,0.1360 [...]
+0.520888015768920,0.560764809582969,0.599753407874048,0.615176666166098,0.615118896093093,0.615151144292493,0.139480286150839,0.139317092098205,0.139004754440762,0.138666278950576,0.138455578536565,0.138020658264009,0.137526002757338,0.137099443444138,0.136662386137227,0.136310172644381,0.136017888990937,0.135866994448411,0.135847127059585,0.135896315428414,0.136004411802254,0.136160927325137,0.136326714637117,0.136444651801435,0.136474556269034,0.136418836329234,0.136319525997585,0.1362 [...]
+0.485702563739533,0.537611334776199,0.574031740489356,0.615209040018212,0.609491790880158,0.139630767224916,0.139538072594162,0.139391909360001,0.139172796213773,0.138915127820891,0.138641926290499,0.138259363355733,0.137813037077255,0.137387716987159,0.136984056633665,0.136628656721159,0.136372403997928,0.136262029875686,0.136261211889937,0.136294677651115,0.136383376842641,0.136517187714905,0.136660648487492,0.136755793734042,0.136757793715575,0.136665240358347,0.136518444733605,0.1363 [...]
+0.438858095188947,0.472803481123890,0.472773926144642,0.434410426653951,0.139903136789838,0.139754117458902,0.139632278409014,0.139508430007359,0.139349101491166,0.139137721484739,0.138869161451024,0.138520451621820,0.138103753883440,0.137697877837699,0.137313377880730,0.136973904530977,0.136758287916244,0.136675860441216,0.136669671357054,0.136670687793187,0.136721676151144,0.136816248032637,0.136921258028244,0.136983639486317,0.136956182806142,0.136830801940282,0.136642108875459,0.1364 [...]
+0.346293963928328,0.472815615068983,0.319909324467163,0.140186767065892,0.140024481377632,0.139867081771856,0.139744184144627,0.139644568198913,0.139522045973612,0.139336823200079,0.139085652562558,0.138776608252840,0.138341740119944,0.137964121765472,0.137628314481940,0.137271257305288,0.137092028486141,0.137017878004393,0.136994771345729,0.136975326683433,0.136985386453938,0.137022781885066,0.137072856617954,0.137091825749349,0.137032773117668,0.136881083459022,0.136664728683461,0.1364 [...]
+0.140569505168009,0.140541508190828,0.140457618532877,0.140288781586153,0.140114495678010,0.139957535533670,0.139844637910866,0.139761981019952,0.139654084555742,0.139479812654510,0.139256513306889,0.139057683764522,0.138472861043259,0.138039044595353,0.137898782111903,0.137403757407397,0.137328418091951,0.137271144535136,0.137231093119988,0.137185848408060,0.137144783279230,0.137120345709425,0.137110990528413,0.137083877917101,0.136995725737515,0.136827352587863,0.136600797274722,0.1363 [...]
+0.140593460920038,0.140566487997603,0.140485261826685,0.140336728071383,0.140161113710499,0.140006719784633,0.139902159948983,0.139824869986256,0.139715375521550,0.139536601572722,0.139301074059951,0.139071291647488,0.138791515280684,0.137921420439532,0.137826987456709,0.137617959648923,0.137529980813365,0.137435487956440,0.137377883550241,0.137293160602583,0.137200996246557,0.137121334406941,0.137060307822450,0.136995266857837,0.136887858720567,0.136715621729366,0.136494962221572,0.1362 [...]
+0.140639574893947,0.140603754227642,0.140509328548432,0.140350492445580,0.140164302517193,0.140006994124699,0.139905017837571,0.139825431252787,0.139709254165566,0.139525515065759,0.139274874812140,0.138993105673831,0.138709905310428,0.137917642779522,0.137795031801351,0.137678823208935,0.137614128787810,0.137548014015789,0.137450343358454,0.137320093601798,0.137181845562812,0.137058402753937,0.136959998785417,0.136871629332170,0.136759025522043,0.136596283093312,0.136393395035835,0.1362 [...]
+0.140693588818904,0.140640812202744,0.140521160152664,0.140338071773839,0.140134318410391,0.139970134898536,0.139867893266946,0.139785468411528,0.139664940706492,0.139478572908174,0.139216895686914,0.138900774935322,0.138622780479935,0.137983725074308,0.137800191909764,0.137697496316013,0.137656839801494,0.137595980714056,0.137471715728302,0.137304089981149,0.137129890040414,0.136975777463966,0.136854770438996,0.136756710750545,0.136649555158197,0.136503757827713,0.136322619585047,0.1361 [...]
+0.140731727257235,0.140664292378787,0.140523286597393,0.140319971459790,0.140102311335564,0.139932660424661,0.139830328078706,0.139747638671690,0.139626556670704,0.139439260701078,0.139168274578810,0.138821514495114,0.138441558540352,0.138029355322264,0.137791782503221,0.137697372262870,0.137671183242418,0.137611950088696,0.137472937073711,0.137283931467712,0.137089430203580,0.136919188037622,0.136787967969547,0.136687779036349,0.136587312036594,0.136454606927452,0.136288451959825,0.1361 [...]
+};
+double result_std_tv_weight[2500]={ 0.690308141687422,0.690556209131614,0.690999062999294,0.691550031214746,0.692120839763581,0.692650721536391,0.693116800384269,0.693518467290874,0.693847294995725,0.694067342741971,0.694122208700116,0.693963375695578,0.693580493411179,0.693010151519970,0.692315363320019,0.691568412680464,0.690851468005372,0.690255018444581,0.689858900879930,0.689705894158191,0.689779214779000,0.690015657660194,0.690330748280741,0.690651763603106,0.690940399492681,0.6911 [...]
+0.690476163038575,0.690734200212068,0.691191647703667,0.691753160091612,0.692322171496674,0.692833794617339,0.693266799514267,0.693626887222604,0.693913820063614,0.694098654604365,0.694128664205691,0.693956257095492,0.693570957835401,0.693006727439096,0.692321189121081,0.691582058264022,0.690868444813680,0.690268158511648,0.689857793640849,0.689685087875945,0.689742749952922,0.689977464150352,0.690306057457025,0.690645600029489,0.690947905164803,0.691204289985739,0.691426721347196,0.6916 [...]
+0.690775313250602,0.691048082555158,0.691526938701427,0.692102920434472,0.692665986365554,0.693144593032436,0.693520663923864,0.693810657870121,0.694027637195714,0.694154023883455,0.694143988365191,0.693952415419654,0.693568156652762,0.693019697343505,0.692354407879575,0.691630924885761,0.690923421470411,0.690315577322306,0.689881293649297,0.689676087128208,0.689704395502940,0.689923531382476,0.690254040123776,0.690604650619049,0.690919622581648,0.691185242885675,0.691407032841052,0.6916 [...]
+0.691155342395856,0.691436425415804,0.691926450953022,0.692505606523845,0.693051518453300,0.693485912381961,0.693794305506514,0.694005205730706,0.694145857418618,0.694210188364227,0.694160228089828,0.693954904104198,0.693582278284703,0.693062591352690,0.692428042999094,0.691724385981598,0.691021731458686,0.690402008528553,0.689939313106760,0.689696420059794,0.689686889094835,0.689871637985840,0.690175421020584,0.690511336405492,0.690830938802409,0.691117815273483,0.691355596500711,0.6915 [...]
+0.691559263262063,0.691831243217976,0.692304781838885,0.692859745166273,0.693369750611876,0.693751780336344,0.693992570955166,0.694130174142497,0.694204566625521,0.694219205355832,0.694142297422358,0.693936905495609,0.693590829763475,0.693115111294077,0.692523664763364,0.691846571375644,0.691151972447130,0.690524011633274,0.690036740931463,0.689755503178574,0.689700985932029,0.689835312094172,0.690087795355213,0.690386266192794,0.690702292413730,0.691034513742871,0.691305332732674,0.6915 [...]
+0.691909914062281,0.692155460980305,0.692583162338137,0.693084080675728,0.693540306594167,0.693867790615180,0.694048203766509,0.694122146152414,0.694141265660198,0.694119935970644,0.694031460414392,0.693841131855947,0.693537063156782,0.693123710299454,0.692597607374193,0.691970468603453,0.691306526151180,0.690691325315851,0.690196502246100,0.689884168749931,0.689781172178471,0.689857235044357,0.690049691826650,0.690300314387013,0.690590878525407,0.691037634378792,0.691313617818414,0.6916 [...]
+0.692134417962716,0.692348331376461,0.692717147830380,0.693147696350692,0.693541022873847,0.693818656426504,0.693949463782670,0.693965655150299,0.693929361978437,0.693873423822644,0.693780222515621,0.693614664182398,0.693364249314872,0.693030818252259,0.692599010306472,0.692061080517096,0.691468862068541,0.690902741818025,0.690429625522157,0.690109065350978,0.689973636347599,0.690008854564066,0.690162729263688,0.690387541147102,0.690664920246175,0.691091096937878,0.691474560023264,0.6918 [...]
+0.692233100339406,0.692421632967247,0.692737803043704,0.693100918371471,0.693429061818178,0.693658945915276,0.693745190636526,0.693703282540502,0.693601391914350,0.693498334076973,0.693393540683361,0.693249291946132,0.693053076164443,0.692808671956940,0.692497046337534,0.692091810754713,0.691620156956698,0.691151070370053,0.690737156124293,0.690444559459899,0.690313405637152,0.690347161673204,0.690501832645263,0.690743259389262,0.691079676402217,0.691500224044366,0.691939558837226,0.6924 [...]
+0.692272746945817,0.692443999045013,0.692726975373500,0.693041454489923,0.693302304692429,0.693475995479718,0.693511752906872,0.693410233298264,0.693237565997816,0.693074495874178,0.692942652323124,0.692796536472382,0.692632967578469,0.692465690898105,0.692281537056085,0.692034273508446,0.691718667151341,0.691394471138083,0.691093261220926,0.690879208651694,0.690794056388523,0.690857750170452,0.691033476335863,0.691302341196812,0.691693296173821,0.692174282993245,0.692688194703325,0.6932 [...]
+0.692294989696362,0.692441838228577,0.692719152311429,0.692997774719115,0.693173276540348,0.693288521579915,0.693276704860111,0.693126638932795,0.692899787283488,0.692679620146759,0.692519293242937,0.692336849414308,0.692166945748797,0.692039145760734,0.691963639782721,0.691871324984930,0.691726995913056,0.691577336453936,0.691425782432049,0.691343973499128,0.691365138974420,0.691502157682305,0.691715781901920,0.692002940473441,0.692444422878491,0.693007609867135,0.693616036759765,0.6942 [...]
+0.692349829372760,0.692408035478970,0.692721685277756,0.692938944415342,0.692955157761860,0.693062675841320,0.693036618483743,0.692854034577498,0.692599014556892,0.692311065088745,0.692171097435002,0.691905339692609,0.691708878819154,0.691592675541738,0.691615702465600,0.691648041431317,0.691593073855200,0.691634207295744,0.691697935686938,0.691803267647397,0.691995339860841,0.692277994441395,0.692590455289056,0.692910395030805,0.693373444737437,0.693973075930445,0.694636745416210,0.6952 [...]
+0.691682593375371,0.691760593581248,0.691883713541518,0.692125359643897,0.692599740273761,0.692834730400362,0.692840048617069,0.692611059017326,0.692393211727481,0.691910582501791,0.691331506770906,0.691361652628756,0.691251057743326,0.691105711267861,0.690982195881456,0.691222737572791,0.691405323692196,0.691646972144139,0.691945482156238,0.692242212245478,0.692632648733712,0.693120960619437,0.693609909062335,0.694016179563366,0.694484563691689,0.695061275706917,0.695697435434061,0.6963 [...]
+0.691655423835270,0.691670761125424,0.691657807847107,0.691846196287504,0.692385552690843,0.692692405240006,0.692748521562915,0.692312359963720,0.690513686606802,0.690302311534710,0.690244377332148,0.690377961808184,0.690622122325011,0.690670231328088,0.690702806939336,0.690925994933684,0.691229806217218,0.691673415317784,0.692273061296771,0.692657848757888,0.693177122139910,0.693799991842124,0.694444531734330,0.694989781746536,0.695506132444445,0.696061304054642,0.696642920474957,0.6972 [...]
+0.691611144538247,0.691602799630418,0.691229281538553,0.691242251106123,0.690981821716195,0.690565041729796,0.690420236584365,0.690265430424223,0.690333142653855,0.690260570343303,0.690190039601121,0.690173726189147,0.690280249806917,0.690307438610550,0.690292834721902,0.690213944567309,0.690407167682003,0.690887772515411,0.692372756198037,0.693009624615355,0.693643544104102,0.694321458245103,0.695026807909669,0.695664793742590,0.696241081444479,0.696800728557559,0.697352240764700,0.6978 [...]
+0.675099568707600,0.689369121161542,0.690953596324514,0.690994308004875,0.690268790567242,0.690403475131317,0.690373996895714,0.690310905313365,0.690280490734588,0.690216084871694,0.690146274086017,0.690093371400290,0.690067335406827,0.690038915684841,0.690008079026980,0.690013396257007,0.690172214016188,0.690529338657654,0.692099384109862,0.693362517281710,0.694038646460396,0.694727475943733,0.695441511006472,0.696111885105013,0.696719173816457,0.697286288283581,0.697825876436816,0.6983 [...]
+0.657055721575981,0.679974603664215,0.684554620556498,0.688814432387045,0.690340565071756,0.690173846597582,0.690245304026219,0.690243213913838,0.690202591496781,0.690141133959907,0.690075927920302,0.690016292623149,0.689919183549806,0.689847908194083,0.689784996274649,0.689774929635958,0.689876338921998,0.690095276483588,0.691520652889791,0.692897794516127,0.693936793103665,0.694997912448792,0.695731652362863,0.696425544494789,0.697041649651929,0.697603784781614,0.698128292515147,0.6986 [...]
+0.647610515748778,0.674814603280768,0.678082071040378,0.685062012931106,0.688852225212943,0.689801754935541,0.690111404284331,0.690110315446556,0.690064782930639,0.690019633101810,0.689961694907119,0.689969132941226,0.689761029123917,0.689691824662788,0.689589820861796,0.689560417263105,0.689661039117939,0.690007733264765,0.691072860167247,0.692052388484878,0.693356216160518,0.694896264192900,0.695921535321259,0.696665829899025,0.697279211117002,0.697826431415766,0.698328548668872,0.6988 [...]
+0.645782965155991,0.669989914910565,0.674713682078478,0.681104122936962,0.686430670758351,0.688423343156334,0.689670152762036,0.689955276641057,0.689848230127405,0.689673456050074,0.689600781097607,0.689408857566575,0.689454997534873,0.689455029853604,0.689374950504179,0.689337470858352,0.689393048033446,0.689725488160397,0.691092860372022,0.691972072714671,0.693232407380297,0.694988410784388,0.696166765726977,0.696867922575152,0.697432327354532,0.697963915849443,0.698449567635594,0.6989 [...]
+0.644811392650241,0.663415438497333,0.665724262348084,0.673211191133172,0.682778471779718,0.685995712217427,0.688658648842955,0.689296406888816,0.688146433155721,0.688731437861303,0.689065252141906,0.689153087343585,0.689352961020939,0.689320384015123,0.689197440558342,0.689117668126176,0.689251721269987,0.689611024933224,0.690816383689806,0.691493987777992,0.692397771050327,0.694617146720749,0.695825900553538,0.696740336314498,0.697446844104025,0.697993836926446,0.698463269408500,0.6989 [...]
+0.642435682722061,0.660789859452137,0.661287755518783,0.666010859901397,0.671017677853144,0.677078656282093,0.679946210371831,0.683167712976050,0.687199202145708,0.688906563684572,0.688109460603412,0.687640655121784,0.687191477375666,0.687122130058155,0.687653142476972,0.688326156739490,0.688543112324810,0.688898462759242,0.689977549335567,0.690379529032018,0.691183524392102,0.692990273438014,0.695718681573591,0.696726701693479,0.697517818520867,0.697992461360360,0.698365031540415,0.6987 [...]
+0.635872136043634,0.660459391383418,0.660466332185549,0.661642739782607,0.666749851927918,0.671365206235298,0.675672228541633,0.676311653508408,0.677090773920253,0.677925878754589,0.680443373094625,0.682534186721904,0.684054073576208,0.685114856122030,0.685839254435622,0.686785142814931,0.687489576881708,0.687612405674818,0.688803007016164,0.689103209380792,0.689623642737663,0.689792014752325,0.690603903478051,0.692067528205371,0.694624367774535,0.697752939291069,0.698124134351649,0.6985 [...]
+0.626959620876479,0.660221432945223,0.660196557329017,0.660441969660570,0.662717895651175,0.668700094340254,0.675086051978084,0.676071316927964,0.676117655535368,0.676414168544255,0.678101068260809,0.682247993768661,0.684729970771748,0.685174250811896,0.681331819704774,0.680448857572950,0.681145035050124,0.683193434984029,0.685595544102580,0.686494861796464,0.685389319805333,0.686113260411383,0.684934268355567,0.688639485243511,0.692459802580927,0.697386269777483,0.697804795975891,0.6982 [...]
+0.615450503701026,0.659884730631859,0.659919482714863,0.660211559530789,0.660483674255270,0.660762124747487,0.664014753305446,0.666078946199859,0.668099810736892,0.670257822282951,0.671602345622110,0.674588113077845,0.675468842067044,0.676117547718000,0.676027003130486,0.676032805614831,0.676172335180473,0.676898124152233,0.677497407263296,0.677906457326963,0.678195277942956,0.678261813155850,0.676846872564662,0.676681111776020,0.678149847879262,0.697209344769278,0.697561292483853,0.6979 [...]
+0.600322033555649,0.659240713717348,0.659725270150742,0.660326014937331,0.660482482906524,0.660672011011924,0.661191473909479,0.662161480010380,0.663397609934158,0.664657538946438,0.665704879690722,0.667888285223594,0.673415866968096,0.675958121495957,0.676067532660165,0.675168844157758,0.675959384233579,0.676899697105512,0.677589837231517,0.677966823236270,0.678316579019672,0.676216823381634,0.676590655345040,0.668889431386464,0.618972596525075,0.696892549768403,0.697433897729832,0.6977 [...]
+0.579827387032324,0.658497848100254,0.659703348067820,0.660258457182184,0.660373433473966,0.660521455819906,0.660707638075987,0.661034886596808,0.661715016105167,0.661784388043228,0.661789891932668,0.661924954700689,0.662417500572896,0.663667447075893,0.666199821362814,0.669652481124634,0.672243459373208,0.672709778434780,0.672997487556993,0.673436626447331,0.673726564530713,0.673928672722179,0.572277833328646,0.561144723369581,0.397092422141676,0.306963630798735,0.247511474412791,0.2182 [...]
+0.548939510164356,0.657600472807601,0.659879774162249,0.659997279300042,0.660149288494564,0.660354292514058,0.660574122780468,0.660796077676183,0.661451372043092,0.661593702708330,0.661633424134878,0.661655485986290,0.661808177930461,0.661642314227881,0.662164137478510,0.665716405140913,0.669448279583186,0.672511461733666,0.672438045399135,0.673536470282354,0.673038049003984,0.544698622658390,0.275609552943754,0.183082769674223,0.179358289113224,0.170416190958502,0.169794868294149,0.1699 [...]
+0.525998704772676,0.655619078923037,0.659524154956806,0.659748517489000,0.659904752420414,0.660119281794328,0.660366459628329,0.660620162742581,0.661097519615987,0.661360989953066,0.661446870821079,0.661377770508669,0.661181646621642,0.661123369986780,0.661195506811216,0.662041893966149,0.664274583331398,0.667511367714951,0.669859368723983,0.667057364331987,0.640017188061766,0.291697860128296,0.167108550622167,0.167090368698326,0.167072575629649,0.167070277264368,0.167069055253764,0.1320 [...]
+0.512261109067358,0.651187412132559,0.658965595472013,0.659277082090249,0.659545749555786,0.659949682809033,0.660145340392746,0.660471173518843,0.660823178452328,0.661151774811450,0.661323660763535,0.661312444845308,0.661285051997917,0.661263273894736,0.661211818533741,0.661082472629595,0.661292149651536,0.661538222061596,0.661419260615860,0.655874420346680,0.167177897851536,0.167158212902002,0.167121285607825,0.167096679927562,0.167077735561593,0.167073221703704,0.131994058679612,0.1314 [...]
+0.507405586792657,0.641386778525812,0.658371889535517,0.659138889214858,0.659192563179617,0.659713733438032,0.659868037814380,0.660278826797224,0.660534704482444,0.660789707923655,0.661089127766587,0.661178926005314,0.661312688928533,0.661442566573597,0.661533067615327,0.661565637637403,0.661705732099617,0.661989967441110,0.656982285119849,0.417708365288750,0.167173759742028,0.167166901474893,0.167119881479966,0.167005897285893,0.167083487282377,0.133333538860345,0.132710410576677,0.1321 [...]
+0.509711629292800,0.629018906946945,0.657242339015193,0.658748004965568,0.658802620501022,0.659418507683028,0.659486734612241,0.659765146768997,0.659988302390750,0.660329159900096,0.660788347203724,0.661001220561452,0.661265557846874,0.661530351293357,0.661738226927329,0.661858896774585,0.661896205139749,0.661534451303685,0.577463931915016,0.167146316986314,0.167161820849553,0.166742806061988,0.138751540429370,0.134882244358686,0.134453305401147,0.133912979529860,0.133357453515975,0.1328 [...]
+0.519726165668612,0.608937560216164,0.656185643359745,0.658283781995508,0.658814530853788,0.659086444598997,0.659174183744660,0.659496703653219,0.659642607455511,0.659900802630333,0.660395644192316,0.660862689317424,0.661248730407142,0.661633120245415,0.661910660537257,0.662128135903808,0.662380361377286,0.636675370911192,0.373033110193068,0.167132819296243,0.165768640608002,0.137217605667913,0.134569970603633,0.134676157038787,0.134603215947008,0.134283205180053,0.133840839492661,0.1333 [...]
+0.535998045473534,0.597048276966285,0.653555108186707,0.656830918278481,0.658372198877974,0.658970154449343,0.658592679447010,0.659368655204013,0.659499795351697,0.659743129570463,0.660138786958833,0.660555104342591,0.661098403764022,0.661758907004520,0.662133018322660,0.662207219980463,0.658957450954539,0.275368786288991,0.133178250963638,0.133356383643858,0.133681156513058,0.134222221928723,0.134516928056365,0.134699101305656,0.134705149343803,0.134510899707948,0.134165478040586,0.1337 [...]
+0.538609692991924,0.616656309204758,0.649808747659647,0.651474860039629,0.652350864213306,0.653898307771625,0.655611786297602,0.658902565711674,0.659382264321117,0.659588441872164,0.659968311725447,0.657258879239956,0.658304701794058,0.661825259630265,0.662517777245456,0.660069397100859,0.430270774378203,0.133517675311184,0.133415535953204,0.133510690837233,0.133763827767554,0.134134685747895,0.134455688168155,0.134677732700902,0.134745051088496,0.134633967578893,0.134366401197936,0.1339 [...]
+0.539436244486098,0.609814119235114,0.646079962052166,0.649980923663745,0.650018098773029,0.649836494796657,0.649655044583489,0.649529250083123,0.649390440274131,0.649278677984244,0.649169686821440,0.648939686895176,0.648695937426116,0.648538443874544,0.648420425693093,0.467981724497544,0.134048126430674,0.133829984029063,0.133719526144023,0.133747546181544,0.133908669623254,0.134170051105788,0.134447008219270,0.134666040256113,0.134763195108499,0.134705300913163,0.134500783099805,0.1341 [...]
+0.548476794084142,0.599490723191279,0.642621915536643,0.649522347718580,0.649944534149916,0.649914785223570,0.649752054873805,0.649575108283466,0.649389594527112,0.649299657668048,0.649224350643205,0.649002026277326,0.648749272044416,0.648606564636466,0.505038434588064,0.134541811919498,0.134333327053902,0.134153134152420,0.134038638406493,0.134018112961641,0.134106065335131,0.134286798971934,0.134507301942740,0.134701460074255,0.134805526414520,0.134780767578784,0.134629054315858,0.1343 [...]
+0.563991630999258,0.598393948767520,0.639629670874091,0.648793038072230,0.650266024375887,0.650127264780821,0.649898936524825,0.649656748162406,0.649310490455748,0.649318820212819,0.649426141968595,0.649097816891469,0.648728858009320,0.398666713212260,0.182405893845719,0.134770404323453,0.134617408561213,0.134455032653003,0.134334735401822,0.134283547170550,0.134325084256272,0.134453743432572,0.134629435288973,0.134796404269723,0.134897861908396,0.134896125376988,0.134791531719523,0.1346 [...]
+0.558388090303336,0.602827559944257,0.630995633865006,0.644264632962710,0.650058698389065,0.650428295796655,0.650095017461176,0.649876427656098,0.642740465615794,0.642417712601058,0.640978352013010,0.641086009634965,0.304098360478669,0.299106725228214,0.135288363842109,0.135083792535561,0.134889830347730,0.134715772512963,0.134589313041588,0.134526141424781,0.134548258066233,0.134653378580531,0.134805581561240,0.134955446544581,0.135054431847519,0.135070122174529,0.135005207746592,0.1348 [...]
+0.557027044975247,0.597768725213452,0.625618402012321,0.635432638507046,0.645795653473089,0.650693415118861,0.650214232265201,0.637314350716056,0.641327995492625,0.636993836745077,0.640606305666730,0.442158873075465,0.298740283202500,0.169112855611794,0.135422213079832,0.135289667748605,0.135097842848080,0.134924554241898,0.134805151118558,0.134749819112719,0.134776309401246,0.134881712279650,0.135030246000363,0.135174707455846,0.135273326731210,0.135301406026518,0.135267013954424,0.1352 [...]
+0.550374496174686,0.588913797027803,0.613051845564925,0.615227964481416,0.615168790492153,0.615092524464718,0.615026099691642,0.614877139816440,0.614707034675478,0.614638659278366,0.408014906516026,0.202838039014717,0.180602365605229,0.152041164303088,0.135672192882172,0.135502444729982,0.135279641330014,0.135105047269691,0.135005552113381,0.134975417664167,0.135024312177927,0.135146259964849,0.135303452747797,0.135447967057615,0.135542456729761,0.135571871682394,0.135552969072709,0.1355 [...]
+0.541008474567661,0.576071416935013,0.610535293512575,0.615178907365230,0.615139255081918,0.615086232567535,0.615023982489971,0.614943217017282,0.614647707617168,0.222322754098125,0.139279257424380,0.139129601848727,0.139107786660644,0.136657074965167,0.136101293773992,0.135773772581181,0.135484945798965,0.135298065323568,0.135222583023459,0.135227212416562,0.135307133040552,0.135451667405336,0.135620449395598,0.135763152081211,0.135843985205677,0.135857217189689,0.135830515839042,0.1358 [...]
+0.534651253497336,0.569899154800691,0.606822556307069,0.615163969673410,0.615128379230907,0.615100648613830,0.615053270121203,0.351412096653371,0.165224844003928,0.143390879597059,0.139540460034554,0.139165940171222,0.138003223091642,0.137083169946310,0.136268735582813,0.136012991780113,0.135722772327757,0.135544588125568,0.135496368183677,0.135531344177142,0.135634987310864,0.135794442589807,0.135968035163408,0.136101960373373,0.136159437601105,0.136141295041753,0.136084991942569,0.1360 [...]
+0.520888015768920,0.560764809582969,0.599753407874048,0.615176666166098,0.615118896093093,0.615151144292493,0.139480286150839,0.139317092098205,0.139004754440762,0.138666278950576,0.138455578536565,0.138020658264009,0.137526002757338,0.137099443444138,0.136662386137227,0.136310172644381,0.136017888990937,0.135866994448411,0.135847127059585,0.135896315428414,0.136004411802254,0.136160927325137,0.136326714637117,0.136444651801435,0.136474556269034,0.136418836329234,0.136319525997585,0.1362 [...]
+0.485702563739533,0.537611334776199,0.574031740489356,0.615209040018212,0.609491790880158,0.139630767224916,0.139538072594162,0.139391909360001,0.139172796213773,0.138915127820891,0.138641926290499,0.138259363355733,0.137813037077255,0.137387716987159,0.136984056633665,0.136628656721159,0.136372403997928,0.136262029875686,0.136261211889937,0.136294677651115,0.136383376842641,0.136517187714905,0.136660648487492,0.136755793734042,0.136757793715575,0.136665240358347,0.136518444733605,0.1363 [...]
+0.438858095188947,0.472803481123890,0.472773926144642,0.434410426653951,0.139903136789838,0.139754117458902,0.139632278409014,0.139508430007359,0.139349101491166,0.139137721484739,0.138869161451024,0.138520451621820,0.138103753883440,0.137697877837699,0.137313377880730,0.136973904530977,0.136758287916244,0.136675860441216,0.136669671357054,0.136670687793187,0.136721676151144,0.136816248032637,0.136921258028244,0.136983639486317,0.136956182806142,0.136830801940282,0.136642108875459,0.1364 [...]
+0.346293963928328,0.472815615068983,0.319909324467163,0.140186767065892,0.140024481377632,0.139867081771856,0.139744184144627,0.139644568198913,0.139522045973612,0.139336823200079,0.139085652562558,0.138776608252840,0.138341740119944,0.137964121765472,0.137628314481940,0.137271257305288,0.137092028486141,0.137017878004393,0.136994771345729,0.136975326683433,0.136985386453938,0.137022781885066,0.137072856617954,0.137091825749349,0.137032773117668,0.136881083459022,0.136664728683461,0.1364 [...]
+0.140569505168009,0.140541508190828,0.140457618532877,0.140288781586153,0.140114495678010,0.139957535533670,0.139844637910866,0.139761981019952,0.139654084555742,0.139479812654510,0.139256513306889,0.139057683764522,0.138472861043259,0.138039044595353,0.137898782111903,0.137403757407397,0.137328418091951,0.137271144535136,0.137231093119988,0.137185848408060,0.137144783279230,0.137120345709425,0.137110990528413,0.137083877917101,0.136995725737515,0.136827352587863,0.136600797274722,0.1363 [...]
+0.140593460920038,0.140566487997603,0.140485261826685,0.140336728071383,0.140161113710499,0.140006719784633,0.139902159948983,0.139824869986256,0.139715375521550,0.139536601572722,0.139301074059951,0.139071291647488,0.138791515280684,0.137921420439532,0.137826987456709,0.137617959648923,0.137529980813365,0.137435487956440,0.137377883550241,0.137293160602583,0.137200996246557,0.137121334406941,0.137060307822450,0.136995266857837,0.136887858720567,0.136715621729366,0.136494962221572,0.1362 [...]
+0.140639574893947,0.140603754227642,0.140509328548432,0.140350492445580,0.140164302517193,0.140006994124699,0.139905017837571,0.139825431252787,0.139709254165566,0.139525515065759,0.139274874812140,0.138993105673831,0.138709905310428,0.137917642779522,0.137795031801351,0.137678823208935,0.137614128787810,0.137548014015789,0.137450343358454,0.137320093601798,0.137181845562812,0.137058402753937,0.136959998785417,0.136871629332170,0.136759025522043,0.136596283093312,0.136393395035835,0.1362 [...]
+0.140693588818904,0.140640812202744,0.140521160152664,0.140338071773839,0.140134318410391,0.139970134898536,0.139867893266946,0.139785468411528,0.139664940706492,0.139478572908174,0.139216895686914,0.138900774935322,0.138622780479935,0.137983725074308,0.137800191909764,0.137697496316013,0.137656839801494,0.137595980714056,0.137471715728302,0.137304089981149,0.137129890040414,0.136975777463966,0.136854770438996,0.136756710750545,0.136649555158197,0.136503757827713,0.136322619585047,0.1361 [...]
+0.140731727257235,0.140664292378787,0.140523286597393,0.140319971459790,0.140102311335564,0.139932660424661,0.139830328078706,0.139747638671690,0.139626556670704,0.139439260701078,0.139168274578810,0.138821514495114,0.138441558540352,0.138029355322264,0.137791782503221,0.137697372262870,0.137671183242418,0.137611950088696,0.137472937073711,0.137283931467712,0.137089430203580,0.136919188037622,0.136787967969547,0.136687779036349,0.136587312036594,0.136454606927452,0.136288451959825,0.1361 [...]
+};
+double result_aniso_tv[2500]={ 0.694624774879996,0.694603704783832,0.694567830096949,0.694527460676308,0.694493857007593,0.694476983009544,0.694484860563633,0.694523737735638,0.694597643940456,0.694706873358336,0.694846399345163,0.695005642021586,0.695170554716816,0.695328067330892,0.695470769862546,0.695601654238934,0.695754022622255,0.697603002563169,0.697614816747146,0.697606776353768,0.697589099142718,0.697566753021572,0.697539128959402,0.697505257776897,0.697466190509179,0.697425923 [...]
+0.694616974750424,0.694596125771788,0.694560751436479,0.694521269553163,0.694489084110097,0.694474311129340,0.694485068145741,0.694527531382382,0.694605393206370,0.694718348930127,0.694860661020076,0.695021296921015,0.695186542894507,0.695343710964518,0.695480542803512,0.695576524994392,0.695587888267021,0.697583998371394,0.697610818360295,0.697608999521998,0.697590536294221,0.697563950330413,0.697531882774944,0.697494834261931,0.697453465192707,0.697410533715460,0.697370939612903,0.6973 [...]
+0.694600332772727,0.694579917465082,0.694545543516454,0.694507865525408,0.694478576300937,0.694468057533319,0.694484547862219,0.694534031439752,0.694619565280204,0.694739823326104,0.694888030424168,0.695052931611682,0.695222524017152,0.695387280946393,0.695534981698038,0.695634759481432,0.695604366383324,0.697509766647318,0.697599544603782,0.697607426449336,0.697586899255473,0.697553640084541,0.697514387058046,0.697471252816705,0.697424976848560,0.697376874445939,0.697330889924429,0.6972 [...]
+0.694573122416062,0.694553390117451,0.694520588381790,0.694485730180513,0.694460910340000,0.694456807398005,0.694481694607780,0.694541190797852,0.694637519998660,0.694768204797553,0.694925534290975,0.695098599998362,0.695278331444286,0.695460844425433,0.695642304567061,0.695817063306418,0.696016396617466,0.697293765806670,0.697626239267618,0.697595974714531,0.697565263805464,0.697525615953296,0.697480177993966,0.697429622609911,0.697376374783989,0.697321262558832,0.697267499203646,0.6972 [...]
+0.694533569619560,0.694514877240921,0.694484374815427,0.694453464334486,0.694434650610111,0.694438827867319,0.694474143506998,0.694545712312253,0.694654911998800,0.694798277364788,0.694967431217634,0.695151908211859,0.695344909959837,0.695545862337482,0.695752202302417,0.695953665545370,0.696154197754546,0.696803104403655,0.697534900222759,0.697537778218709,0.697510492161434,0.697469971417061,0.697423837040509,0.697365094551151,0.697304039354162,0.697241088564617,0.697179251873492,0.6971 [...]
+0.694480578242810,0.694463382697694,0.694435993568394,0.694410055603084,0.694398321790314,0.694411754776223,0.694458318562110,0.694542702104115,0.694665651817967,0.694823027629182,0.695005951005675,0.695203904805237,0.695410809626195,0.695627094567535,0.695848621150368,0.696053214658273,0.696194458806892,0.696358902527220,0.697393636398515,0.697457867612231,0.697423089242224,0.697383636636830,0.697335869991369,0.697274563428142,0.697206564354648,0.697135764127178,0.697066107449507,0.6970 [...]
+0.694414269341609,0.694398972022352,0.694375280669643,0.694354741808481,0.694350065279521,0.694372271364895,0.694429471520760,0.694526357064463,0.694663320993925,0.694835659852314,0.695033883159065,0.695246590892874,0.695466937157442,0.695695796388801,0.695932351657012,0.696165667755302,0.696388995937004,0.696628923191186,0.697099908822920,0.697246664588881,0.697290557208970,0.697274579396487,0.697227378711455,0.697161878433445,0.697086690550903,0.697007934417606,0.696930650741574,0.6968 [...]
+0.694336148167527,0.694322821082426,0.694302672752871,0.694286728238301,0.694287468638037,0.694316410724769,0.694382698245472,0.694491658599083,0.694643153245359,0.694831314499144,0.695045983964952,0.695274132479533,0.695506544509541,0.695742948013490,0.695984979035054,0.696227131710665,0.696462598417285,0.696710813672712,0.696975760486342,0.697120167502591,0.697171203314942,0.697156939130532,0.697106143767059,0.697034327529075,0.696951147198989,0.696864055869150,0.696779097302666,0.6967 [...]
+0.694248964315484,0.694237058895581,0.694219066702617,0.694205268638487,0.694208135569941,0.694240671300548,0.694314341410412,0.694435781916112,0.694602961230401,0.694806626507808,0.695037703858670,0.695281327951796,0.695523674552478,0.695762507457929,0.696001455774765,0.696235338322262,0.696436282069499,0.696757628327480,0.696952186103384,0.697027802022882,0.697059038773677,0.697037015558906,0.696979583483456,0.696900310086985,0.696808857713023,0.696713434786410,0.696620912635133,0.6965 [...]
+0.694156612013009,0.694144847400120,0.694126238466076,0.694110619608996,0.694110920791202,0.694142765625526,0.694221599296766,0.694357539959290,0.694543498113825,0.694758830551467,0.695005492972350,0.695266169902642,0.695514139388895,0.695747779546086,0.695980505654611,0.696217202074021,0.696414780372629,0.696634143526889,0.696830170720357,0.696924498476425,0.696947314595414,0.696917207651148,0.696853063434765,0.696767073619495,0.696668558390329,0.696566024067954,0.696466869090342,0.6963 [...]
+0.694064448693573,0.694051080841548,0.694027791328089,0.694005177057894,0.693996169033636,0.694019547198398,0.694097131945988,0.694253506782693,0.694472005678996,0.694684098321327,0.694948819874796,0.695241390253379,0.695486792672869,0.695694762405056,0.695912261832429,0.696180552718213,0.696423318585162,0.696611217027762,0.696763443444329,0.696836124097769,0.696842162111799,0.696801919577835,0.696731252585522,0.696640082514498,0.696536903711911,0.696429864018366,0.696326283900078,0.6962 [...]
+0.693979772084996,0.693963499002599,0.693929481090809,0.693893959178876,0.693865062783848,0.693865424448438,0.693917409102717,0.694109099475198,0.694423978519306,0.694564695497633,0.694683517063247,0.695099678741242,0.695475343863309,0.695600573880300,0.695758663078827,0.696128239280769,0.696434985962675,0.696574681772440,0.696724683339888,0.696765290058978,0.696747385900490,0.696694469058088,0.696617324669856,0.696522854513695,0.696418048862616,0.696309965024159,0.696205197141092,0.6961 [...]
+0.693911297420748,0.693894913549203,0.693837494716178,0.693786589774480,0.693726586759628,0.693698137226635,0.693620902196142,0.693464085001918,0.693497492635922,0.693561371856082,0.693901668286866,0.694448379757246,0.695250746782509,0.695454581974413,0.695514952819617,0.695738248422920,0.696216471606371,0.696479708587722,0.696745895198382,0.696712196821592,0.696660858227773,0.696595719240613,0.696514245964035,0.696419118721024,0.696315674455339,0.696209754005940,0.696106972699537,0.6960 [...]
+0.693864655750592,0.693873149277578,0.693747942732637,0.693708021815120,0.693621420814260,0.693480452950424,0.693429491231160,0.693303138059399,0.693126461611876,0.693014272134216,0.692965025328790,0.693012616431440,0.694005156864233,0.694586119923182,0.694785706696580,0.694738252436578,0.695094551504733,0.695634599419498,0.696525016929606,0.696645363576135,0.696570691994227,0.696505853403693,0.696425843010976,0.696333248917393,0.696233754552037,0.696132459770591,0.696034000954788,0.6959 [...]
+0.679542936238856,0.692492264794449,0.693661889173945,0.693719501845596,0.693371285202842,0.693371693949999,0.693312316549920,0.693207044331484,0.693083074185370,0.692977543762962,0.692892779805471,0.692794158377901,0.692772756306352,0.692803413081672,0.692906494318288,0.693188309916769,0.694051311430869,0.694870399272874,0.696148290704970,0.696503332816801,0.696462003043049,0.696429648238890,0.696355704734559,0.696267484421314,0.696174281095527,0.696079922927643,0.695987711830620,0.6959 [...]
+0.663179228014454,0.684118160599674,0.688317856145427,0.692110222531444,0.693276798890887,0.693295895672785,0.693259466145688,0.693154204410713,0.693046781285486,0.692947044740014,0.692859407675966,0.692776706629955,0.692733483135312,0.692741194476908,0.692679308485426,0.692788315908796,0.693242075535279,0.693964035423224,0.695539573474114,0.696242926126001,0.696340297128937,0.696395884924619,0.696306707441713,0.696220229050569,0.696136134586348,0.696051445181003,0.695967560713044,0.6958 [...]
+0.654519630725755,0.679316119603248,0.682579166038690,0.689172957012345,0.692319744041250,0.692949342535270,0.693206986684599,0.693125920951390,0.693025680146720,0.692927292211472,0.692840988952147,0.692735719072863,0.692586311670697,0.692511051091092,0.692495236489213,0.692469162608634,0.692669239724719,0.693330661578326,0.694641725414959,0.695411893850989,0.695901653314584,0.696264468988665,0.696262522252975,0.696183733321702,0.696117050667946,0.696045003803988,0.695971281850213,0.6958 [...]
+0.652750445241081,0.674342206108190,0.679310434575926,0.685771124717854,0.690559614776134,0.692245987911516,0.693185210483829,0.693125319929119,0.693010933939441,0.692902776519537,0.692847832035078,0.692571049354188,0.692498539175497,0.692332652146462,0.692223825121283,0.692160981235810,0.692231510931511,0.692377743716998,0.693619889277345,0.694246229733228,0.694771582352540,0.695716307251908,0.696096052963983,0.696147497043640,0.696119361268608,0.696058427045442,0.695995475696750,0.6959 [...]
+0.651721282228638,0.667418169058823,0.670236421031831,0.678647164893052,0.687470944342242,0.690558787538897,0.693157961943275,0.693176987064322,0.692415788594132,0.692489627495760,0.692392447613951,0.692485497825137,0.692509922056654,0.692258684708137,0.691898920508181,0.691590743158805,0.691732934959786,0.691898376300441,0.692365527127537,0.692709102357927,0.693561069123260,0.695098162967680,0.695706496181024,0.695958169258738,0.696090581834317,0.696086761832231,0.696036332247196,0.6959 [...]
+0.649571370784017,0.664229424535263,0.665237398861261,0.671992184422282,0.676238557710559,0.681965076562599,0.684870336105381,0.687996584431616,0.691705246410485,0.692467823500477,0.691606504029831,0.690943214345741,0.690180604508872,0.690024392760019,0.690481877849475,0.690919842042624,0.691151812137366,0.691312968216656,0.691883725272546,0.691979933030298,0.692500185911719,0.693472690744636,0.695054688017150,0.695650661635859,0.695996416159082,0.696169412542359,0.696094924177061,0.6960 [...]
+0.644140722926630,0.663814941666613,0.664121790965690,0.668204782586343,0.672197361635313,0.676230196395337,0.680705735297352,0.681539448989682,0.682133367207044,0.682753779103281,0.685200830935877,0.687069749231723,0.688149217365138,0.688814031404716,0.689768514528227,0.690405592473701,0.690839915342393,0.690333948916157,0.691017486241429,0.691023185899425,0.691458813118429,0.691416731855216,0.691844704295182,0.692770642295791,0.694386921151605,0.696194712181618,0.696143550077942,0.6960 [...]
+0.636666182079552,0.663897703730276,0.663907933488753,0.667214901557880,0.668693473197739,0.673512808931619,0.678904523236653,0.680201302807734,0.680447582524623,0.680726325889919,0.682198309169790,0.686084545715175,0.687624065433393,0.687578025803738,0.684887833097307,0.684230915215289,0.684486092774223,0.685662836343270,0.687239906242997,0.687987480084488,0.687383787190252,0.688102845666069,0.687502402607198,0.690225026403946,0.692918278426581,0.696222783310829,0.696187986927582,0.6961 [...]
+0.626724676835995,0.663918461342646,0.664899159362680,0.666921839719607,0.666935827206061,0.666961242650784,0.669465615566570,0.671257220594200,0.673266652130775,0.675492234944342,0.676824721881182,0.680058845710372,0.681283473269239,0.682156807875964,0.682122349931192,0.682099686818754,0.681751437268564,0.681770296146563,0.681876069314816,0.681967511660581,0.682020796754556,0.682074905506627,0.682131469566133,0.682227900326306,0.683124162014971,0.696250717718599,0.696226487275710,0.6961 [...]
+0.613424200127431,0.664388822845764,0.665749791185107,0.666918637266751,0.666932480545329,0.666982608445010,0.667218355183258,0.667761300177646,0.668785821747777,0.670260581674168,0.671315623010661,0.673555585628171,0.679275681330989,0.682176178401271,0.682120786286602,0.680959561318698,0.681331163399543,0.681673425315942,0.681899489563261,0.682002473249826,0.682023770391206,0.682059933632986,0.682101653919682,0.678671137954709,0.639473829491176,0.696282911323440,0.696260632811883,0.6962 [...]
+0.595011120514665,0.664345415292098,0.666106549650732,0.666901754696746,0.666903295648845,0.666903141468238,0.666916263870715,0.666939732808919,0.666991428168739,0.667131756519443,0.667236495436346,0.667442498250230,0.667929921570393,0.668757072413746,0.671094800282665,0.675263234140328,0.679057455090023,0.680035184597761,0.681344549479376,0.682005810192719,0.682008153163251,0.682037427806382,0.618642628339129,0.590943739605881,0.417960448029774,0.317089816442688,0.250359313461607,0.2146 [...]
+0.567045818451300,0.664107736562337,0.666521598834980,0.666870413480561,0.666910821723975,0.666912017960467,0.666915544070033,0.666916711472672,0.666899078111990,0.666901814434599,0.666909902649324,0.666923606415490,0.666942363500778,0.666980775508240,0.667058642180313,0.670274378799701,0.673897684870360,0.677868606729376,0.678209794590225,0.682020726471814,0.681969482293252,0.601707862979884,0.289003252334326,0.159255024865097,0.150568691365684,0.135562372774696,0.134280025088362,0.1341 [...]
+0.545783432059507,0.662529421133924,0.666516568233842,0.666832213973160,0.666909502632703,0.666915210545575,0.666914825563894,0.666912206661311,0.666905316401652,0.666903560805820,0.666904669179542,0.666907836782530,0.666914828260116,0.666938809197550,0.666969228350370,0.667135822582077,0.667888261541255,0.669229840180727,0.670362439962106,0.669422961100690,0.663330527498077,0.289169736911576,0.130369658454700,0.130409250681825,0.130495725800914,0.130600422580303,0.130731320410066,0.1308 [...]
+0.532596523752353,0.658151440836336,0.666390250083477,0.666763353383362,0.666898370162617,0.666920337504451,0.666914725275099,0.666911536251860,0.666906399593022,0.666901723538499,0.666896249958545,0.666887748663759,0.666871319140651,0.666829251287716,0.666788976466726,0.666769256348605,0.666778061859427,0.666803492585138,0.666848570291808,0.666932647104625,0.170867153252281,0.130260143516458,0.130320226521375,0.130385038127066,0.130470505134957,0.130578788503921,0.130711922680770,0.1308 [...]
+0.527385076990138,0.647726800601878,0.666227244855852,0.666746763008222,0.666866295390617,0.666915853060941,0.666910536029520,0.666912734014540,0.666906881775518,0.666899470185753,0.666889178537530,0.666875120991999,0.666855440079071,0.666828039984225,0.666801592062483,0.666785212137229,0.666784000093420,0.666794505186521,0.666815431421811,0.428914625524182,0.130152936211486,0.130212412199712,0.130275484321872,0.130359189029141,0.130440199787605,0.130550685472168,0.130685809314501,0.1308 [...]
+0.528623419212675,0.634400845898296,0.665795587925694,0.666726940338507,0.666827546891397,0.666907536625979,0.666896891732093,0.666913548794806,0.666908988139976,0.666899484250637,0.666884795124404,0.666867890178674,0.666849158755096,0.666829782226673,0.666809917499547,0.666794817998637,0.666787464014237,0.666784911061585,0.596881821200776,0.130086918178432,0.130123298778657,0.130172667996823,0.130231285607954,0.130294995794418,0.130402435122213,0.130520083691026,0.130656853494253,0.1308 [...]
+0.536727775309777,0.612496187058647,0.665251219563776,0.666643521838425,0.666912623301947,0.666904531008866,0.666862587669031,0.666935481442932,0.666915870472118,0.666903474923662,0.666880747667144,0.666861557899093,0.666843565568474,0.666836149973497,0.666817088877529,0.666803533862629,0.666796960397173,0.648896400509478,0.367061048297046,0.130062967459514,0.130091997120152,0.130137895559276,0.130198436392450,0.130274532299950,0.130373391861573,0.130491023221776,0.130627368667919,0.1307 [...]
+0.549885241761847,0.599682106997139,0.663621422432681,0.665994706743894,0.666932841682011,0.666930457749082,0.666573686800299,0.666922707868866,0.666912874566770,0.666913674467731,0.666869961124529,0.666823376771413,0.666815800454879,0.666850930375474,0.666827525424237,0.666814674538233,0.665398712364363,0.302649653214062,0.129984079309559,0.130021092101087,0.130058376172606,0.130106317403347,0.130168663248292,0.130247840241931,0.130346134022233,0.130463330262805,0.130597692896450,0.1307 [...]
+0.551647707873510,0.622666232514389,0.661033043282455,0.662690304120266,0.663467470653081,0.664383497442975,0.665289258798409,0.666903566210767,0.666890836651795,0.666952615650729,0.666859384286032,0.665508411747983,0.665721156266505,0.666760275780306,0.666806421101717,0.666006600897172,0.446981624011570,0.129924343908790,0.129955521039340,0.129990540427367,0.130030705564259,0.130080663375153,0.130144502322399,0.130224669044940,0.130322695166180,0.130437881899288,0.130567712202075,0.1307 [...]
+0.551863937223960,0.615526226940681,0.657800924253540,0.661640019246083,0.662165261241946,0.662189707205380,0.662222369148181,0.662265157195658,0.662326207208135,0.662400852130382,0.662467081896376,0.662505869038895,0.662529971798052,0.662539263232818,0.662550324387940,0.487310676670486,0.129869669114519,0.129898139033549,0.129928619529853,0.129964341130272,0.130007557542569,0.130060478149279,0.130126068213903,0.130206572439072,0.130302710312722,0.130413282992414,0.130534962219113,0.1306 [...]
+0.559424493946595,0.604555507923545,0.654736723145506,0.660917491684952,0.662141301314133,0.662180542798679,0.662209049700756,0.662245425343863,0.662307694334597,0.662401815915077,0.662494268969489,0.662515658045906,0.662520922572690,0.662535206458500,0.519334161171576,0.129814688242163,0.129841835579856,0.129870176321225,0.129901556012997,0.129939703003769,0.129986196279743,0.130042249514466,0.130109700548434,0.130189861524152,0.130282632722677,0.130386250458862,0.130497201816756,0.1306 [...]
+0.572641979378725,0.604889757149282,0.652399101898085,0.660110639283167,0.662084995502249,0.662185653450544,0.662190506368020,0.662202989996992,0.662208781163715,0.662296484551812,0.662514064292549,0.662546021661696,0.662488794657288,0.419073560657293,0.175189103887644,0.129795447557368,0.129814415669624,0.129841461216506,0.129875190579339,0.129916259558436,0.129965501500661,0.130024055180943,0.130092849520475,0.130171961777506,0.130260318785403,0.130355616577623,0.130454341551926,0.1305 [...]
+0.567444109098285,0.612463820136172,0.645672627620630,0.656378974727894,0.661515698097297,0.662158208479143,0.662169636711658,0.662180189710499,0.660059734551763,0.660054117320123,0.659689892627257,0.659687840931488,0.334577948129371,0.289037333331824,0.129730672285861,0.129758251835997,0.129782455976764,0.129812972712410,0.129849938968077,0.129893711274631,0.129945334954899,0.130005856781071,0.130075378741520,0.130152788767332,0.130235975967334,0.130322045152605,0.130407401199831,0.1304 [...]
+0.566481223185631,0.608586845389294,0.641941483562652,0.649484325513176,0.657264551224225,0.662130647669898,0.662153328731612,0.656109743885290,0.660070360477781,0.657287271002463,0.659708571580167,0.457860886128628,0.286649997083038,0.148875112268736,0.129708533865279,0.129731083034076,0.129755454787307,0.129786853352988,0.129825661504928,0.129871743288695,0.129925684635604,0.129987962954979,0.130057809514483,0.130133002500069,0.130210410057062,0.130286511497899,0.130357578493704,0.1304 [...]
+0.560428135342178,0.600466249201205,0.633586164778173,0.636889768035689,0.636893731534614,0.636900327310237,0.636901304037646,0.636906051550251,0.636897983795323,0.637616623104094,0.420738726079144,0.189225315013701,0.162131033484933,0.138036765334401,0.129684119084566,0.129708365290540,0.129731471995996,0.129762521386154,0.129802273194819,0.129850282706993,0.129906480469059,0.129970460609103,0.130040436319471,0.130113088688524,0.130184318999282,0.130250014483152,0.130306340570249,0.1303 [...]
+0.551896447738322,0.585751743015261,0.630410696498577,0.636894321609074,0.636896862148466,0.636900047712761,0.636900786321205,0.636901731447902,0.633611094752013,0.236267750021868,0.129944395289948,0.129986283742844,0.130036307982850,0.129716381821285,0.129689925925951,0.129694431862000,0.129711413977506,0.129740222833058,0.129780003009442,0.129829464745926,0.129887726441163,0.129953361149713,0.130023420886515,0.130093465347769,0.130158490001164,0.130213858828808,0.130255687769043,0.1302 [...]
+0.547113955977745,0.581138732056912,0.626012274837864,0.636896414717277,0.636899768904852,0.636901653170083,0.636901527171153,0.361345576684081,0.159241921202141,0.130930756270273,0.129884456908179,0.129952441755716,0.129852521422236,0.129712753387183,0.129669887456300,0.129675159968623,0.129691021981949,0.129718898251977,0.129758726337257,0.129809359288301,0.129869502443787,0.129936792265021,0.130007072797364,0.130074774367137,0.130134047836737,0.130179805717749,0.130208161083598,0.1302 [...]
+0.535537908567904,0.574257227383311,0.618230217705301,0.636901275589599,0.636900782535479,0.636903945428231,0.129792015702598,0.129785982701420,0.129789593675939,0.129800974317391,0.129802832077494,0.129764044851072,0.129730935595474,0.129715883209900,0.129647428449345,0.129653765745617,0.129669676797236,0.129697819214779,0.129738134477467,0.129789931246958,0.129851980858251,0.129921127778506,0.129992021216898,0.130058004933561,0.130112470643114,0.130149952056568,0.130166581566712,0.1301 [...]
+0.503810990427253,0.553491298118313,0.591988987964178,0.636904381565176,0.631148350093045,0.129773023014711,0.129784779320017,0.129762923252956,0.129764039832331,0.129762451726236,0.129753411250575,0.129729600495629,0.129705925087952,0.129693867491468,0.129624176005049,0.129632002083905,0.129648664805866,0.129677215019033,0.129717987287477,0.129771161711614,0.129835502078853,0.129906986953762,0.129979124846189,0.130044303219198,0.130095288570489,0.130126311992018,0.130133517604524,0.1301 [...]
+0.460179038197595,0.492548416304656,0.492550977167402,0.453763499717344,0.129739503933703,0.129749162312038,0.129745231487868,0.129742206235380,0.129736349639910,0.129727955609721,0.129713544844266,0.129691631479918,0.129666340978053,0.129635769074218,0.129614417618226,0.129614258392913,0.129628797125655,0.129656668592429,0.129698018873613,0.129753217672738,0.129820541091035,0.129894993771293,0.129969096052641,0.130034507493829,0.130083542066620,0.130110194552343,0.130110579996921,0.1300 [...]
+0.363465264523962,0.492555504926465,0.331646494050880,0.129724580157858,0.129728974544452,0.129731770449065,0.129728074287488,0.129720607953855,0.129710884308390,0.129698092815408,0.129680487682545,0.129658597534144,0.129634060344739,0.129608483109207,0.129593358190315,0.129593500682650,0.129607583082730,0.129635541594000,0.129678411911660,0.129736563670351,0.129807541314708,0.129885443556354,0.129962093020925,0.130028705074383,0.130077303751625,0.130101681260808,0.130097854529900,0.1300 [...]
+0.129736791144901,0.129734027305689,0.129729860357681,0.129724563825431,0.129723100588639,0.129720204665701,0.129712979436254,0.129702306152657,0.129689002639987,0.129672624635469,0.129652948839994,0.129631044120789,0.129607194171795,0.129579434562069,0.129567796840834,0.129570155439422,0.129585395355969,0.129614731917081,0.129660153250715,0.129721885178292,0.129796726731877,0.129878141920620,0.129957609766173,0.130026148118468,0.130075593880354,0.130099531639636,0.130093803069289,0.1300 [...]
+0.129736008796981,0.129733409182622,0.129729167254453,0.129724141641388,0.129719178008076,0.129711869821262,0.129701099994961,0.129687231252790,0.129670582259418,0.129651240786433,0.129629990396402,0.129608799036597,0.129590443037411,0.129547845502128,0.129543228533123,0.129548069624909,0.129564840431504,0.129596193193295,0.129644567592587,0.129709782270966,0.129788056254756,0.129872578429081,0.129954774218735,0.130025606918401,0.130076761607708,0.130101593532052,0.130095713817196,0.1300 [...]
+0.129734789766463,0.129732488144748,0.129728208413432,0.129722452658197,0.129714934344345,0.129704724147933,0.129691406960712,0.129675069587121,0.129655863631206,0.129634068621556,0.129610807982578,0.129587722405274,0.129564909406608,0.129538270015374,0.129528247863853,0.129531778948807,0.129548830320703,0.129581806944606,0.129632672459278,0.129700582945661,0.129781399579997,0.129868311143309,0.129952831385909,0.130025910499440,0.130079086506673,0.130105483101243,0.130100471685580,0.1300 [...]
+0.129733443963604,0.129731120136290,0.129726555079588,0.129719867334320,0.129710828689561,0.129699028537678,0.129684264542563,0.129666475671263,0.129645703567058,0.129622288620768,0.129597408481211,0.129572851304958,0.129549537700323,0.129528658596647,0.129518523716867,0.129521128459239,0.129538183803315,0.129572302910634,0.129624826280158,0.129694394640573,0.129776765123543,0.129865247019082,0.129951453204446,0.130026317180806,0.130081250024790,0.130109184680219,0.130105296338722,0.1300 [...]
+0.129732626455672,0.129730172847147,0.129725301466342,0.129718073344824,0.129708349033616,0.129695896843720,0.129680523353187,0.129662094573752,0.129640608542688,0.129616447660961,0.129590778216384,0.129565493460774,0.129542352104812,0.129523397303975,0.129513557689717,0.129515777410471,0.129532919490292,0.129567663070983,0.129620970560860,0.129691273094691,0.129774348119158,0.129863599006369,0.129950690757185,0.130026541384577,0.130082487799534,0.130111355228634,0.130108208986714,0.1300 [...]
+};
+double result_higher_order_tv[2500]={ 0.724346500285334,0.723389799527951,0.722376888777462,0.720464753315472,0.718579452499973,0.716818770706615,0.715353804063815,0.713216974398622,0.711607271697609,0.710361734599316,0.709461319651048,0.708899151254834,0.708597461656926,0.709360219684473,0.710350728611932,0.711486454940578,0.713150861614893,0.715443710115497,0.717763935994428,0.720021969787538,0.721945852710442,0.723595773195826,0.725052120884010,0.726297152097550,0.727306565933688,0.72 [...]
+0.723292040319651,0.722696043228344,0.721690966043489,0.720224225386668,0.718520518312362,0.716665604965509,0.714811780740479,0.712967473472841,0.711380097910873,0.710119807014691,0.709224493727353,0.708726726335455,0.708553045732891,0.709043323191285,0.709904880511204,0.711185083683614,0.712874606983804,0.714988638617229,0.717229155551169,0.719480469119903,0.721441395579131,0.723139762056574,0.724615730773901,0.725862881740075,0.726866386349873,0.727623342600420,0.728147205236932,0.7284 [...]
+0.722048248280145,0.721562711786388,0.720609947370071,0.719288178656420,0.717690886393579,0.715927970168440,0.714055418341026,0.712294367600735,0.710756060453041,0.709521524458279,0.708645138788392,0.708170532165730,0.708108596978940,0.708546420275754,0.709412809854894,0.710713077139655,0.712402207253974,0.714423807405546,0.716558980515493,0.718698324713601,0.720654291496712,0.722372186508119,0.723853662861135,0.725088998650046,0.726068441909930,0.726795347554196,0.727288288725088,0.7275 [...]
+0.720446493666670,0.720064974292801,0.719116493888757,0.717840621055401,0.716319294681179,0.714650728113144,0.712899936383316,0.711242122636316,0.709791636406016,0.708632135019424,0.707824271756861,0.707408007932892,0.707431242453411,0.707901611826726,0.708798346559887,0.710099848599995,0.711753380572943,0.713668709467018,0.715707686930035,0.717740919560346,0.719634881171257,0.721320346987132,0.722769257333557,0.723963981196580,0.724897433626545,0.725576375856432,0.726023427016630,0.7262 [...]
+0.718444413736884,0.718046231465159,0.717135150571388,0.715891015333469,0.714448521374792,0.712898048337830,0.711317229918355,0.709823155662241,0.708520058396663,0.707490906853406,0.706799578951967,0.706486298639823,0.706592919831455,0.707118595849558,0.708047509537773,0.709341512914331,0.710918558178029,0.712746666310705,0.714693467117251,0.716629827017427,0.718413421075037,0.720025061330560,0.721404534127831,0.722527610380791,0.723390708983290,0.724003962834900,0.724392427853111,0.7245 [...]
+0.716454671172392,0.715382972821656,0.714419547846511,0.713307961624341,0.712041298276074,0.710686256597356,0.709327566051437,0.708057088111830,0.706963599417226,0.706122527696716,0.705594537725009,0.705421175052429,0.705631067707825,0.706223364814160,0.707180263798026,0.708463589301390,0.709996544594161,0.711720032321551,0.713564411198824,0.715408534294460,0.717015607353042,0.718513139214337,0.719798370242057,0.720828631676012,0.721601685520637,0.722133035549819,0.722450919724921,0.7225 [...]
+0.712630843285831,0.711852560136749,0.711043100103190,0.710136049052386,0.709117884940908,0.708033897476674,0.706958717252053,0.705970908927667,0.705145456467501,0.704547278224801,0.704229320850596,0.704229542239566,0.704567888895514,0.705242372953475,0.706232883699631,0.707501756100808,0.708990062570073,0.710622089957311,0.712306182868296,0.713966110842083,0.715486337066182,0.716850010656134,0.718005674264335,0.718916841883267,0.719581009552183,0.720016118983249,0.720252858941219,0.7203 [...]
+0.708145870252799,0.707687471961900,0.707130929179131,0.706468078291832,0.705733563733745,0.704973568904380,0.704238375767512,0.703591012261994,0.703089451863380,0.702784523816772,0.702719829988069,0.702925931045281,0.703416020379638,0.704186017851501,0.705215317130379,0.706466046957922,0.707888045649262,0.709416345049295,0.710966542071254,0.712460064926530,0.713836959811491,0.715049174177225,0.716053316076408,0.716824603806683,0.717364576274480,0.717692538973101,0.717840102763531,0.7178 [...]
+0.703698290242729,0.703138403172979,0.702738181709527,0.702336938213029,0.701924851103690,0.701541683991522,0.701199111332807,0.700944664775261,0.700817711833838,0.700851526442025,0.701077403717105,0.701517339521028,0.702178360302443,0.703053947145338,0.704125051798490,0.705358157311899,0.706707831898366,0.708119138835325,0.709526287550509,0.710857539042098,0.712066033629492,0.713107040054225,0.713944495932173,0.714563556123832,0.714969810201147,0.715183331680555,0.715235962223096,0.7151 [...]
+0.698539460881117,0.698122063349943,0.697950082488132,0.697834377604384,0.697760524600218,0.697782258677561,0.697876331786403,0.698062339283788,0.698351662025408,0.698761562077186,0.699308053978312,0.700003115622023,0.700848473551306,0.701835853677120,0.702948206502765,0.704158745422336,0.705429985976430,0.706715511102385,0.707965205019391,0.709123408350028,0.710148777999564,0.711004712101441,0.711666243456760,0.712126087294099,0.712392757930539,0.712487621319755,0.712442246915407,0.7122 [...]
+0.693379622863429,0.692907723559641,0.692841771883822,0.692992664636113,0.693315119953301,0.693751745234181,0.694307670376265,0.694976512848212,0.695715585372845,0.696526276557791,0.697412199666309,0.698374625308030,0.699409743925048,0.700508605448639,0.701657220592702,0.702835571143908,0.704016775922369,0.705166014623688,0.706245469740306,0.707216184297295,0.708045727579998,0.708707692005234,0.709187712597250,0.709483946855181,0.709607589816685,0.709582937951611,0.709441464250116,0.7092 [...]
+0.687392003924642,0.687312075797513,0.687484730486373,0.687814883843610,0.688667075775617,0.689553889559485,0.690565913964329,0.691722278041267,0.692929469697486,0.694154142149505,0.695385885704209,0.696616917523429,0.697838036001359,0.699039793606553,0.700212567562639,0.701344274008928,0.702419109211746,0.703416654764645,0.704312557210340,0.705082479516356,0.705705021206014,0.706167577906877,0.706463376213385,0.706594909295828,0.706575131634274,0.706432046820823,0.706206820147583,0.7059 [...]
+0.681613186529374,0.681653004019153,0.682033644202212,0.682777632593365,0.683865768778718,0.685164581158941,0.686694902046446,0.688334192813713,0.690009817215718,0.691651474013760,0.693225135348390,0.694713849396913,0.696105472266240,0.697391646957052,0.698567990590366,0.699631996798794,0.700580130912973,0.701407159570696,0.702105205780310,0.702664245622467,0.703070574849924,0.703331045626515,0.703443648498182,0.703414787638915,0.703258301657507,0.703000082999794,0.702699474808927,0.7023 [...]
+0.675151760253831,0.675844184173064,0.676431699801671,0.677585701263882,0.678934128321744,0.680503170140152,0.682714157400959,0.684891180659098,0.687016028814254,0.689041757837431,0.690927815773231,0.692646847707294,0.694181294872994,0.695523606974685,0.696675528940830,0.697645265288590,0.698443206789008,0.699079835231112,0.699565915383349,0.699909228239283,0.700095825977470,0.700152224182589,0.700084662795350,0.699904165950337,0.699630398966658,0.699305311120403,0.698850238023062,0.6983 [...]
+0.667330361327993,0.669448775279794,0.670690665727217,0.672281131136036,0.673908895470124,0.676359886083941,0.678870496090124,0.681435114974787,0.683951444363669,0.686322702034605,0.688484039498860,0.690396002277522,0.692036166392336,0.693398589377162,0.694492771085121,0.695338980703067,0.695962635357046,0.696390699734972,0.696652079357081,0.696771548706353,0.696740405760095,0.696597815986079,0.696358007635434,0.696036073406692,0.695642768461371,0.695177524340750,0.694700919933275,0.6941 [...]
+0.659387235831391,0.662266541867599,0.664541043725896,0.666848551780892,0.669354305865936,0.672106892427443,0.675007237563973,0.677952782959807,0.680821367181872,0.683494139427226,0.685885828546410,0.687945311461657,0.689647148089391,0.690989349397784,0.691990926670493,0.692684657293061,0.693111270318097,0.693317128267625,0.693349951627787,0.693245160470983,0.692996935088165,0.692661039087914,0.692259302544164,0.691810492615537,0.691333564235680,0.690821313418768,0.690315003562089,0.6897 [...]
+0.653736929606944,0.656385375770060,0.658828502887630,0.661682493848918,0.664752603489467,0.667887254880966,0.671164093370481,0.674463476214362,0.677640736832629,0.680563364240905,0.683132012553837,0.685286765394131,0.687001815804095,0.688282430185785,0.689159109497286,0.689675757544303,0.689884844147564,0.689860173295423,0.689673759851311,0.689331000686195,0.688888862746132,0.688380095232406,0.687841223260174,0.687297182430502,0.686769870758533,0.686261626000311,0.685770309366071,0.6852 [...]
+0.648858975476914,0.651282920109432,0.653912997243182,0.656937229612982,0.660293906976279,0.663800606843821,0.667409131442077,0.671006059465088,0.674431927464647,0.677542615849367,0.680227970750479,0.682422151847462,0.684101156308177,0.685279638265663,0.686002544864838,0.686327612428823,0.686305462440999,0.686048319558352,0.685718205958522,0.685062209674547,0.684443834676061,0.683812141975548,0.683181619516812,0.682583892792409,0.682050711999182,0.681595817084057,0.681176562891655,0.6807 [...]
+0.644428970844219,0.646755776570028,0.649400608155813,0.652540347617435,0.656120202380976,0.659902919005285,0.663782822533101,0.667610743277480,0.671217126905952,0.674447268137740,0.677185673109103,0.679363835497286,0.680960454166477,0.681998643686611,0.682538859727514,0.682669014874578,0.682427080825184,0.681942293889096,0.681303929989506,0.680561630115864,0.679813016179183,0.679084096834879,0.678397483150593,0.677788347888418,0.677298421573037,0.676958769806276,0.676680646508930,0.6763 [...]
+0.640356590121976,0.642660999325303,0.645351830176579,0.648566649770029,0.652266039581569,0.656244835271455,0.660324981615967,0.664300672910086,0.668014252804479,0.671293582323002,0.674022453796822,0.676133154579600,0.677607802939935,0.678478261516173,0.678815744099565,0.678721170239940,0.678268516174852,0.677597008129433,0.676788196321306,0.675948377768209,0.675124931132119,0.674339936222307,0.673627987427496,0.673050416948908,0.672675960604406,0.672527625333048,0.672454174240042,0.6722 [...]
+0.636680933005552,0.638878675913691,0.641706052130329,0.645010587194784,0.648777955041681,0.652856014098018,0.657058902610923,0.661088737200272,0.664832235548220,0.668094553481192,0.670757054678710,0.672756185904695,0.674079290870851,0.674774555874899,0.674985048344818,0.674569187226085,0.673923918790086,0.673119632680253,0.672234916480601,0.671365061835663,0.670546347705176,0.669765577757715,0.669031233823425,0.668480212736691,0.668359011882585,0.668576593320692,0.668682930830767,0.6686 [...]
+0.633677206521375,0.635880766187673,0.638548640585442,0.641827080645670,0.645611768368345,0.649719991427137,0.653954899864294,0.657978685174833,0.661674741517927,0.664855472832952,0.667401273791338,0.669255351810899,0.670412896890137,0.670905917946377,0.670805175837090,0.670299686595834,0.669536203379101,0.668650759213940,0.667752277214111,0.666936699385025,0.666240926941809,0.665588157957186,0.664818813825156,0.664081548830304,0.664336226191083,0.665474799348258,0.665700409833372,0.6654 [...]
+0.631005875528237,0.633117670131599,0.635718073431433,0.638949997400685,0.642707022052498,0.646784347448114,0.650950217820614,0.654927961398039,0.658523365043499,0.661570616287205,0.663957694240086,0.665635186661569,0.666611481885578,0.666934036671757,0.666668500833223,0.666036798825690,0.665194268401018,0.664283685565104,0.663431981529458,0.662744501929173,0.662282804747993,0.661958783398964,0.661314682444307,0.658838555129027,0.658850570351397,0.662336842704044,0.663415115429474,0.6627 [...]
+0.628585149110806,0.630572353033906,0.633110871347382,0.636285443296101,0.639977976337722,0.643977404325217,0.648031785886609,0.651890999723101,0.655342315256730,0.658224816123239,0.660433918401483,0.661932820466189,0.662750020078534,0.662916198682409,0.662551072264080,0.661841068938766,0.660965260479704,0.660079236687948,0.659325433208783,0.658809729420105,0.658566446161164,0.658626618611205,0.659528259019655,0.651183940174224,0.621198346699702,0.639426674256159,0.643068167010786,0.6392 [...]
+0.626240202104970,0.628131819670479,0.630613082312439,0.633720195777605,0.637320289927843,0.641201199266215,0.645113384795499,0.648815646227472,0.652095827144936,0.654802164137954,0.656836294078441,0.658164897771480,0.658860737607429,0.658883736968950,0.658479176130137,0.657764756728453,0.656911815716348,0.656070189604331,0.655401688388741,0.655059020484416,0.654948903431939,0.654928010968794,0.553026522848922,0.504908654373948,0.455215353726342,0.424967690374024,0.408679418863855,0.3974 [...]
+0.623801062197372,0.625654344356358,0.628096948478996,0.631130822578503,0.634618145857891,0.638354634973544,0.642102905012412,0.645634113931211,0.648737114422185,0.651274218934464,0.653171028643646,0.654394543839609,0.654967617227359,0.654962571270355,0.654548653560607,0.653875709179365,0.653096120869958,0.652309980945376,0.651574322914091,0.651214906888605,0.650324850098509,0.513213180131009,0.388693325428879,0.320814154875314,0.284246326786141,0.240694595677868,0.223167329611147,0.2160 [...]
+0.621185346009241,0.623026636634576,0.625435355319917,0.628392753180876,0.631754917833760,0.635337377850146,0.638912097402138,0.642266369950413,0.645209287599225,0.647594311389153,0.649376372376460,0.650537720433509,0.651091300385535,0.651136099951643,0.650798353913179,0.650221056912551,0.649554056499957,0.648880733871734,0.647943986153560,0.645515621620884,0.510882491621767,0.379867226471856,0.252335676446547,0.209862156183376,0.197499324815657,0.194678749790811,0.194205571118193,0.1896 [...]
+0.618213698730973,0.620110862933729,0.622503819726230,0.625386725506926,0.628621440598340,0.632060726565982,0.635486237288888,0.638637548209627,0.641438148750620,0.643725272521198,0.645448499789906,0.646607456804221,0.647234683194158,0.647420139503235,0.647266248199462,0.646856354401927,0.646261954507222,0.645619236839105,0.645138503549557,0.521374638364873,0.370495446652000,0.244830084236926,0.200507784425359,0.194671101068750,0.193905339724921,0.191864495690031,0.189821860239493,0.1869 [...]
+0.614742754719944,0.616784188449100,0.619204238780118,0.622004475559817,0.625116795330156,0.628438817421559,0.631847309916745,0.634785394458937,0.637350425187454,0.639581235413895,0.641347698630005,0.642570648352270,0.643370241803806,0.643804986050091,0.643979047825350,0.643903979425852,0.643533659246276,0.642812573725223,0.550996869730555,0.401676183822795,0.252843725455041,0.193780693866315,0.192841968709597,0.190803537547519,0.189459827138845,0.187775913835405,0.185395071946973,0.1829 [...]
+0.610686400075455,0.612926490275142,0.615472554003310,0.618157761301153,0.621155066663902,0.624370041156035,0.627370311574689,0.630247627758530,0.632879579255622,0.635167230197721,0.637117231929429,0.638436292034919,0.639455620566009,0.640227722627091,0.640857710618369,0.641314056606925,0.641283118332538,0.609297290563576,0.449940086044980,0.290752559366622,0.190185995110878,0.188561470317946,0.187429130860191,0.186169272785122,0.184590661458870,0.182700186957203,0.180273912502868,0.1777 [...]
+0.605960377962414,0.608380677893976,0.611211091264953,0.613783599348793,0.616659573518165,0.619679339465750,0.622565075723700,0.625419394219673,0.628098033040579,0.630477980250106,0.632534379824944,0.634193938124882,0.635487241868320,0.636570906130115,0.637564484072615,0.638758561787320,0.609279380914174,0.499917394468321,0.349562570193962,0.196300114155635,0.185904120295850,0.183924136569061,0.182380535974071,0.180936813376459,0.179113868315549,0.176910215494049,0.174359742164981,0.1717 [...]
+0.600818071364695,0.603329086369859,0.606118422102547,0.608673962726114,0.611497011239948,0.614385590782026,0.617274295574558,0.620187501789537,0.622982376305145,0.625549287192840,0.627819420397259,0.629776889087456,0.631410677457099,0.632802255017229,0.633723487527256,0.632731954046871,0.537855947300273,0.383078492899645,0.228987220722624,0.179518639442129,0.179544039370267,0.178646057663614,0.177100608839433,0.175266491338852,0.173095275848275,0.170573896301637,0.167830259975768,0.1650 [...]
+0.595022179201893,0.597722574019594,0.600203272704517,0.602756264003294,0.605527562976031,0.608458353949627,0.611497925476037,0.614575776677724,0.617577863665302,0.620400100105103,0.622974373638447,0.625290634903939,0.627247448757041,0.629073838654759,0.630684765204925,0.565268481361525,0.417141680463426,0.266184086286596,0.175891248365732,0.175277411690204,0.174489331491507,0.173262307739213,0.171452135613225,0.169240508768652,0.166681765068599,0.163856807457965,0.160908441958144,0.1579 [...]
+0.588370138589045,0.591290569827258,0.593673485255216,0.596222073656831,0.599037828572856,0.602100413581108,0.605341124761228,0.608676356219988,0.612001692023355,0.615189793824742,0.618096378042490,0.620782564993001,0.623183170610378,0.625308617907525,0.559491551368468,0.427490194177943,0.286161263755803,0.172842800467973,0.172128495058350,0.171169240663672,0.169738949594460,0.167856843917761,0.165572779692572,0.162928464226630,0.159998670085048,0.156911154204304,0.153799686377367,0.1507 [...]
+0.581135861408909,0.584158343829430,0.586612105979472,0.589234935808265,0.592153902056386,0.595427972174633,0.598951119324483,0.602594286686340,0.606287275369880,0.609989066493342,0.613387425204011,0.615958703703459,0.618977751221365,0.574515037163888,0.436107176415092,0.296775240135958,0.172236645341232,0.170246213835957,0.168608485779593,0.166880317072057,0.164776209407356,0.162280763081465,0.159474938069789,0.156411319850643,0.153182425843744,0.149914024964216,0.146716328501744,0.1436 [...]
+0.573769089952237,0.576643098186640,0.579162673321179,0.581910211507523,0.585045571044459,0.588588721465999,0.592445446746407,0.596427696992992,0.600325583173591,0.604379333866169,0.609139276609310,0.610523702905378,0.583137312105064,0.450009075988302,0.311929257778373,0.172170546918084,0.169412391766570,0.167094105788538,0.164758852997912,0.162266815297260,0.159504038326564,0.156467580037145,0.153219486262644,0.149833382247821,0.146412575467050,0.143060805028643,0.139864071932922,0.1368 [...]
+0.565328017993089,0.568847946867805,0.571748901649013,0.574494719480875,0.577888404098510,0.581707274592575,0.585887873292526,0.590351539082021,0.594407286535192,0.597416740315429,0.594300112208531,0.584231600440127,0.460424968402623,0.329088579917892,0.190188997802219,0.169009790996343,0.166087563214376,0.163277467355205,0.160378493137083,0.157283540350418,0.153978972104427,0.150508440344510,0.146938715831813,0.143354821609154,0.139852749182527,0.136513569354723,0.133405052952740,0.1305 [...]
+0.556342776203485,0.560788602030492,0.564663105802557,0.567358207305030,0.570910911909290,0.574950567244589,0.579259742721984,0.584194730827716,0.589303619421330,0.584611664627203,0.573091966769235,0.462800114084829,0.341895275321109,0.214699194043822,0.166947076092526,0.164762162206952,0.162033271306688,0.158911733131020,0.155543762409271,0.151981263861158,0.148276453092481,0.144504530945746,0.140745429504828,0.137086830253160,0.133609914704931,0.130378267584083,0.127444160961864,0.1248 [...]
+0.546795236160399,0.551828645537423,0.556947985192668,0.560355741397573,0.564248592931925,0.568574911482291,0.572837294743558,0.577116676112827,0.568784110259218,0.532046698344453,0.428725228024079,0.322607427280956,0.229724855348726,0.178654174829727,0.163461318721449,0.160600502640173,0.157529677278556,0.154080888566953,0.150346867285928,0.146441523522093,0.142470652896996,0.138531145758802,0.134712146518174,0.131095935633779,0.127748431790077,0.124717779657045,0.122039530719664,0.1197 [...]
+0.537293175471700,0.543080895542346,0.548836823414170,0.553419751543963,0.557785897734995,0.562211553720556,0.567271948351061,0.563839264621293,0.485706290569200,0.384463688318378,0.280122355281171,0.192298708874034,0.164998540694723,0.162141330489687,0.159503219386067,0.156338634873058,0.152791147503122,0.148944754857671,0.144893304251161,0.140750590563734,0.136635458045474,0.132654124208692,0.128895766141935,0.125431302571750,0.122311042932580,0.119566828239194,0.117216030206581,0.1152 [...]
+0.527571356528321,0.536034731598931,0.541695456638524,0.546549510627201,0.551107684020787,0.554004484643711,0.523475972543748,0.427009667699021,0.336581415027265,0.240509125501705,0.170211496637166,0.168993928934222,0.162854677890866,0.158733074346190,0.155367830107129,0.151764018992287,0.147794123266294,0.143588736859733,0.139283332473924,0.134998172904278,0.130850098214421,0.126940866877004,0.123349911261641,0.120133121933452,0.117324055787864,0.114936982560758,0.112970934606506,0.1114 [...]
+0.513105153509126,0.527978602631179,0.535486864126959,0.539787759124233,0.541518503271967,0.484417707080436,0.386177231497093,0.290980908582251,0.199283818145649,0.167540602136135,0.165704028240041,0.163230069028328,0.159341605722371,0.155183385554416,0.151129513163842,0.146962514311681,0.142585793844830,0.138092145401044,0.133616254198669,0.129282743394885,0.125201637283395,0.121461554162675,0.118125805012937,0.115233163872360,0.112799463338581,0.110821105951264,0.109279082713626,0.1081 [...]
+0.483144792926579,0.507646168296070,0.517674577446770,0.510674022311540,0.436622997992113,0.354096472185679,0.264714671250421,0.173756786704993,0.169947518304046,0.166293019935943,0.163154333008886,0.159517897306413,0.155533022513304,0.151193566194843,0.146672077760749,0.142018347298797,0.137278837492229,0.132566060869762,0.128006842118176,0.123714906460384,0.119785324407352,0.116289418961386,0.113273103815099,0.110757536783806,0.108740692574498,0.107201217061110,0.106102505149403,0.1053 [...]
+0.427787594473160,0.440145321711291,0.416348895454064,0.369324309184031,0.304586506868623,0.232203486387057,0.175034585934834,0.172040584464507,0.168431576530052,0.164631909213815,0.160719071218494,0.156374231175701,0.151793318953336,0.147007488041918,0.142055340865005,0.137009749178832,0.131996699092992,0.127153955193997,0.122596208740641,0.118419214086693,0.114701574453979,0.111498923559140,0.108840766716384,0.106730672568391,0.105148840117789,0.104056603487959,0.103400784347279,0.1031 [...]
+0.305852465896789,0.332907724623111,0.294849710424194,0.235203085504467,0.181636797793826,0.177761262629078,0.174338806875778,0.170756772926964,0.166801147800340,0.162578880188812,0.158058035768693,0.153177648171937,0.148052134436123,0.142784886879092,0.137434297304260,0.132097217391860,0.126919928545995,0.122034040251713,0.117540637184949,0.113524415386296,0.110052658323879,0.107167016489514,0.104880653942823,0.103179877147317,0.102027971913359,0.101370095605458,0.101138038189117,0.1012 [...]
+0.208826502884048,0.210393321722151,0.189094632356143,0.184255763996635,0.181105786600503,0.177429397420938,0.173630016943016,0.169544357070122,0.165117450136832,0.160373893671713,0.155304958670503,0.149944791336967,0.144380447079031,0.138719641368007,0.133060012580467,0.127528977778287,0.122267015296083,0.117390568224900,0.112995096531686,0.109161073344792,0.105945703441200,0.103376279161942,0.101450269497903,0.100138300995868,0.099388429993350,0.099131378258572,0.099285815695490,0.0997 [...]
+0.189655987468059,0.187347316896805,0.186292619072360,0.183875826286576,0.180616226450651,0.176903344411936,0.172816164432617,0.168336136157465,0.163476917185611,0.158264111261663,0.152736846133420,0.146966436923199,0.141046937768594,0.135086143676801,0.129206322830403,0.123547958048431,0.118242127285519,0.113399095257171,0.109114237895884,0.105462758808659,0.102490478544218,0.100211525208139,0.098610053310645,0.097643259212555,0.097246057929086,0.097336863725498,0.097823460953768,0.0986 [...]
+0.188157223106335,0.187180936241017,0.185716921691452,0.183343036008801,0.180137902893707,0.176334909662771,0.172023184510344,0.167241641500401,0.162037022849179,0.156464418626506,0.150591528028751,0.144504897413297,0.138311666164285,0.132130699197580,0.126097839072035,0.120354383982586,0.115026932392843,0.110226461821936,0.106046924458892,0.102555961254118,0.099789623520013,0.097752159206403,0.096417295857442,0.095731363148541,0.095618603597885,0.095987508097354,0.096737379308290,0.0977 [...]
+0.187580116425664,0.186901908423373,0.185365412147116,0.182964560616507,0.179764238115898,0.175880103722692,0.171406862464107,0.166416280171189,0.160974224504639,0.155156353184283,0.149046741288894,0.142744265380127,0.136365631515801,0.130040443781069,0.123909990032694,0.118113817655799,0.112778934276540,0.108017432669604,0.103919684572286,0.100547222430353,0.097930086004540,0.096066032992299,0.094921393733489,0.094434718214568,0.094522578700874,0.095086329167395,0.096019332030144,0.0972 [...]
+0.187532605354278,0.186894341761227,0.185335957114086,0.182866701900954,0.179592636950612,0.175638217936888,0.171076893816355,0.165978012751953,0.160414586111460,0.154469314235726,0.148234958632023,0.141820558778347,0.135348114407859,0.128952216468424,0.122774473960669,0.116953097593708,0.111617204734513,0.106879034401433,0.102825942789599,0.099516526114202,0.096978223069670,0.095205524917353,0.094160839393740,0.093778554744987,0.093971125389651,0.094636107743681,0.095663740227362,0.0969 [...]
+};
+#endif
\ No newline at end of file
diff --git a/test/coordinateiterator/CMakeLists.txt b/test/coordinateiterator/CMakeLists.txt
new file mode 100644
index 0000000..3615793
--- /dev/null
+++ b/test/coordinateiterator/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_coordinateiterator test.cxx)
diff --git a/test/coordinateiterator/test.cxx b/test/coordinateiterator/test.cxx
new file mode 100644
index 0000000..a2459a0
--- /dev/null
+++ b/test/coordinateiterator/test.cxx
@@ -0,0 +1,367 @@
+#include <iostream>
+#include <iomanip>
+#include <utility>
+#include <string>
+#include <sstream>
+#include "vigra/unittest.hxx"
+
+#include "vigra/multi_pointoperators.hxx"
+#include "vigra/multi_array.hxx"
+#include "vigra/rgbvalue.hxx"
+#include "vigra/coordinate_iterator.hxx"
+
+using namespace vigra;
+
+typedef float pixel_type;
+
+typedef vigra::MultiArrayShape<2>::type  shape_2d;
+typedef vigra::MultiArray<2, pixel_type> array_2d;
+typedef vigra::MultiArrayShape<3>::type  shape_3d;
+typedef vigra::MultiArray<3, pixel_type> array_3d;
+
+typedef vigra::RGBValue<double> rgb_type;
+
+typedef vigra::MultiArrayShape<2>::type  shape_rgb;
+typedef vigra::MultiArray<2, rgb_type>   array_rgb;
+
+using namespace vigra;
+
+struct count : public InitializerTag
+{
+    mutable unsigned long t;
+    count() : t(0) {}
+    unsigned long operator()() const
+    {
+        return t++;
+    }
+};
+
+void set_pr(std::ostream & os)
+{
+    os << std::fixed << std::setprecision(3);
+}
+
+struct echo
+{
+    std::ostringstream os;
+    std::string empty;
+    echo() { set_pr(os); }
+    template<class X>
+    void operator()(const X & x)
+    {
+        os.str(empty);
+        os << '"' << x << '"' << ',';
+        std::cout << os.str() << "\n";
+    }
+};
+
+typedef const char* char_s;
+
+struct echo_cmp : public echo
+{
+    typedef char_s* char_p;
+    char_p p;
+    echo_cmp() : p(0) {}
+    echo_cmp & operator()(char_p r)
+    {
+        p = r;
+        return *this;
+    }
+    template<class X>
+    void operator()(const X & x)
+    {
+        os.str(empty);
+        os << x;
+        should (p && *p);
+        if (p && *p)
+        {
+            shouldEqual(os.str(), *p);
+            ++p;
+        }
+    }
+};
+
+void testCoordinateIterator()
+{
+    StridePair<2>::coord_type c2_origin(10,  0);
+    StridePair<2>::coord_type c2_stride( 1,  2);
+    StridePair<2>::index_type c2_shape ( 2,  5);
+    
+    CoordinateMultiIterator<2>(c2_origin, c2_stride, c2_shape);
+
+    coordinateMultiRange<2>(c2_shape, c2_stride, c2_origin);
+    echo_cmp echo_f;
+    char_s out_1[] =
+    {
+        "(10.000, 0.000)",
+        "(11.000, 0.000)",
+        "(10.000, 2.000)",
+        "(11.000, 2.000)",
+        "(10.000, 4.000)",
+        "(11.000, 4.000)",
+        "(10.000, 6.000)",
+        "(11.000, 6.000)",
+        "(10.000, 8.000)",
+        "(11.000, 8.000)",
+        0
+    };
+    (inspectMultiArray(coordinateMultiRange<2>(
+                               c2_shape, c2_stride, c2_origin), echo_f(out_1)));
+
+    StridePair<2>::coord_type c7_origin(10,  5.5);
+    StridePair<2>::coord_type c7_stride( 1 / 7.0,  1 / 3.0);
+    StridePair<2>::index_type c7_shape ( 7,  3);
+    char_s out_2[] =
+    {
+        "(10.000, 5.500)",
+        "(10.143, 5.500)",
+        "(10.286, 5.500)",
+        "(10.429, 5.500)",
+        "(10.571, 5.500)",
+        "(10.714, 5.500)",
+        "(10.857, 5.500)",
+        "(10.000, 5.833)",
+        "(10.143, 5.833)",
+        "(10.286, 5.833)",
+        "(10.429, 5.833)",
+        "(10.571, 5.833)",
+        "(10.714, 5.833)",
+        "(10.857, 5.833)",
+        "(10.000, 6.167)",
+        "(10.143, 6.167)",
+        "(10.286, 6.167)",
+        "(10.429, 6.167)",
+        "(10.571, 6.167)",
+        "(10.714, 6.167)",
+        "(10.857, 6.167)",
+        0
+    };
+    (inspectMultiArray(coordinateMultiRange<2>(
+                               c7_shape, c7_stride, c7_origin), echo_f(out_2)));
+
+    StridePair<3>::coord_type c3_origin(20,  -3,  1 / 3.0);
+    StridePair<3>::coord_type c3_stride(0.5, 1/17.0,  1 / 6.0);
+    StridePair<3>::index_type c3_shape (  2,  3,    3);
+    char_s out_3[] =
+    {
+        "(20.000, -3.000, 0.333)",
+        "(20.500, -3.000, 0.333)",
+        "(20.000, -2.941, 0.333)",
+        "(20.500, -2.941, 0.333)",
+        "(20.000, -2.882, 0.333)",
+        "(20.500, -2.882, 0.333)",
+        "(20.000, -3.000, 0.500)",
+        "(20.500, -3.000, 0.500)",
+        "(20.000, -2.941, 0.500)",
+        "(20.500, -2.941, 0.500)",
+        "(20.000, -2.882, 0.500)",
+        "(20.500, -2.882, 0.500)",
+        "(20.000, -3.000, 0.667)",
+        "(20.500, -3.000, 0.667)",
+        "(20.000, -2.941, 0.667)",
+        "(20.500, -2.941, 0.667)",
+        "(20.000, -2.882, 0.667)",
+        "(20.500, -2.882, 0.667)",
+        0
+    };
+    (inspectMultiArray(coordinateMultiRange<3>(
+                               c3_shape, c3_stride, c3_origin), echo_f(out_3)));
+
+    StridePair<2>::coord_type c0_stride(0.5, 0.25);
+    StridePair<2>::index_type c0_shape (  2,  3);
+    char_s out_4[] =
+    {
+        "(0.000, 0.000)",
+        "(0.500, 0.000)",
+        "(0.000, 0.250)",
+        "(0.500, 0.250)",
+        "(0.000, 0.500)",
+        "(0.500, 0.500)",
+        0
+    };
+    (inspectMultiArray(coordinateMultiRange<2>(c0_shape, c0_stride),
+                                echo_f(out_4)));
+
+    StridePair<2>::index_type c1_shape (  2,  3);
+    char_s out_5[] =
+    {
+        "(0.000, 0.000)",
+        "(1.000, 0.000)",
+        "(0.000, 1.000)",
+        "(1.000, 1.000)",
+        "(0.000, 2.000)",
+        "(1.000, 2.000)",
+        0
+    };
+    (inspectMultiArray(coordinateMultiRange<2>(c1_shape),
+                                echo_f(out_5)));
+
+    array_2d stride_image2(array_2d::size_type(2, 3));
+    initMultiArray(destMultiArrayRange(stride_image2), count());
+    char_s out_6[] =
+    {
+        "[0.000, (0.000, 0.000)]",
+        "[1.000, (1.000, 0.000)]",
+        "[2.000, (0.000, 1.000)]",
+        "[3.000, (1.000, 1.000)]",
+        "[4.000, (0.000, 2.000)]",
+        "[5.000, (1.000, 2.000)]",
+        0
+    };
+    (inspectMultiArray(srcCoordinateMultiArrayRange(stride_image2),
+                                echo_f(out_6)));
+    
+    array_3d stride_image3(array_3d::size_type(2, 3, 4));
+    initMultiArray(destMultiArrayRange(stride_image3), count());
+    char_s out_7[] =
+    {
+        "[0.000, (0.000, 0.000, 0.000)]",
+        "[1.000, (1.000, 0.000, 0.000)]",
+        "[2.000, (0.000, 1.000, 0.000)]",
+        "[3.000, (1.000, 1.000, 0.000)]",
+        "[4.000, (0.000, 2.000, 0.000)]",
+        "[5.000, (1.000, 2.000, 0.000)]",
+        "[6.000, (0.000, 0.000, 1.000)]",
+        "[7.000, (1.000, 0.000, 1.000)]",
+        "[8.000, (0.000, 1.000, 1.000)]",
+        "[9.000, (1.000, 1.000, 1.000)]",
+        "[10.000, (0.000, 2.000, 1.000)]",
+        "[11.000, (1.000, 2.000, 1.000)]",
+        "[12.000, (0.000, 0.000, 2.000)]",
+        "[13.000, (1.000, 0.000, 2.000)]",
+        "[14.000, (0.000, 1.000, 2.000)]",
+        "[15.000, (1.000, 1.000, 2.000)]",
+        "[16.000, (0.000, 2.000, 2.000)]",
+        "[17.000, (1.000, 2.000, 2.000)]",
+        "[18.000, (0.000, 0.000, 3.000)]",
+        "[19.000, (1.000, 0.000, 3.000)]",
+        "[20.000, (0.000, 1.000, 3.000)]",
+        "[21.000, (1.000, 1.000, 3.000)]",
+        "[22.000, (0.000, 2.000, 3.000)]",
+        "[23.000, (1.000, 2.000, 3.000)]",
+        0
+    };
+    (inspectMultiArray(srcCoordinateMultiArrayRange(stride_image3),
+                                echo_f(out_7)));
+
+    array_rgb image_rgb(array_2d::size_type(2, 3));
+    initMultiArray(destMultiArrayRange(image_rgb), count());
+    char_s out_8[] =
+    {
+        "[(0.000, 0.000, 0.000), (0.000, 0.000)]",
+        "[(1.000, 1.000, 1.000), (1.000, 0.000)]",
+        "[(2.000, 2.000, 2.000), (0.000, 1.000)]",
+        "[(3.000, 3.000, 3.000), (1.000, 1.000)]",
+        "[(4.000, 4.000, 4.000), (0.000, 2.000)]",
+        "[(5.000, 5.000, 5.000), (1.000, 2.000)]",
+        0
+    };
+    (inspectMultiArray(srcCoordinateMultiArrayRange(image_rgb),
+                                echo_f(out_8)));
+    typedef AccessorTraits<rgb_type>::default_const_accessor
+        default_rgb_access;
+    char_s out_9[] =
+    {
+        "[(0.000, 0.000, 0.000), (0.000, 0.000)]",
+        "[(1.000, 1.000, 1.000), (1.000, 0.000)]",
+        "[(2.000, 2.000, 2.000), (0.000, 1.000)]",
+        "[(3.000, 3.000, 3.000), (1.000, 1.000)]",
+        "[(4.000, 4.000, 4.000), (0.000, 2.000)]",
+        "[(5.000, 5.000, 5.000), (1.000, 2.000)]",
+        0
+    };
+    (inspectMultiArray(srcCoordinateMultiArrayRangeAccessor(image_rgb,
+                                                          default_rgb_access()),
+                      echo_f(out_9)));
+    char_s out_10[] =
+    {
+        "[0.000, (0.000, 0.000)]",
+        "[1.000, (1.000, 0.000)]",
+        "[2.000, (0.000, 1.000)]",
+        "[3.000, (1.000, 1.000)]",
+        "[4.000, (0.000, 2.000)]",
+        "[5.000, (1.000, 2.000)]",
+        0
+    };
+    (inspectMultiArray(srcCoordinateMultiArrayRangeAccessor(image_rgb,
+                                                     GreenAccessor<rgb_type>()),
+                      echo_f(out_10)));
+
+    StridePair<2>::coord_type x2_origin(0.5,  2.2);
+    const StridePair<2>::coord_type x2_stride(1.5, 0.4);
+    char_s out_11[] =
+    {
+        "[0.000, (0.000, 0.000)]",
+        "[1.000, (1.500, 0.000)]",
+        "[2.000, (0.000, 0.400)]",
+        "[3.000, (1.500, 0.400)]",
+        "[4.000, (0.000, 0.800)]",
+        "[5.000, (1.500, 0.800)]",
+        0
+    };
+    (inspectMultiArray(srcCoordinateMultiArrayRange(stride_image2,
+                                                             x2_stride),
+                      echo_f(out_11)));
+    char_s out_12[] =
+    {
+        "[0.000, (0.500, 2.200)]",
+        "[1.000, (2.000, 2.200)]",
+        "[2.000, (0.500, 2.600)]",
+        "[3.000, (2.000, 2.600)]",
+        "[4.000, (0.500, 3.000)]",
+        "[5.000, (2.000, 3.000)]",
+        0
+    };
+    (inspectMultiArray(srcCoordinateMultiArrayRange(stride_image2,
+                                                   x2_stride,
+                                                   x2_origin),
+                      echo_f(out_12)));
+    char_s out_13[] =
+    {
+        "[0.000, (0.000, 0.000)]",
+        "[1.000, (1.500, 0.000)]",
+        "[2.000, (0.000, 0.400)]",
+        "[3.000, (1.500, 0.400)]",
+        "[4.000, (0.000, 0.800)]",
+        "[5.000, (1.500, 0.800)]",
+        0
+    };
+    (inspectMultiArray(srcCoordinateMultiArrayRangeAccessor(image_rgb,
+                                                    GreenAccessor<rgb_type>(),
+                                                    x2_stride),
+                      echo_f(out_13)));
+    char_s out_14[] =
+    {
+        "[0.000, (0.500, 2.200)]",
+        "[1.000, (2.000, 2.200)]",
+        "[2.000, (0.500, 2.600)]",
+        "[3.000, (2.000, 2.600)]",
+        "[4.000, (0.500, 3.000)]",
+        "[5.000, (2.000, 3.000)]",
+        0
+    };
+    (inspectMultiArray(srcCoordinateMultiArrayRangeAccessor(image_rgb,
+                                                    GreenAccessor<rgb_type>(),
+                                                    x2_stride,
+                                                    x2_origin),
+                      echo_f(out_14)));
+}
+
+struct CoordinateIteratorTestSuite : public vigra::test_suite
+{
+    CoordinateIteratorTestSuite()
+        : vigra::test_suite("CoordinateIteratorTestSuite")
+    {
+        add(testCase(&testCoordinateIterator));
+    }
+};
+
+
+int main(int argc, char** argv)
+{
+    CoordinateIteratorTestSuite test;
+    const int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test.report() << std::endl;
+
+    return failed != 0;
+}
diff --git a/test/error/CMakeLists.txt b/test/error/CMakeLists.txt
new file mode 100644
index 0000000..10eb594
--- /dev/null
+++ b/test/error/CMakeLists.txt
@@ -0,0 +1,3 @@
+VIGRA_ADD_TEST(test_error test.cxx)
+
+
diff --git a/test/error/test.cxx b/test/error/test.cxx
new file mode 100755
index 0000000..f91fc42
--- /dev/null
+++ b/test/error/test.cxx
@@ -0,0 +1,125 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+
+#include "vigra/unittest.hxx"
+#include "vigra/error.hxx"
+
+struct ErrorTest
+{
+    void testPrecondition()
+    {
+        try
+        {
+            vigra_precondition(0, "Intentional error");
+            failTest("no exception thrown");
+        }
+        catch(vigra::ContractViolation & c)
+        {
+            std::string expected("\nPrecondition violation!\nIntentional error");
+            std::string message(c.what());
+            should(0 == expected.compare(message.substr(0,expected.size())));
+        }
+        try
+        {
+            vigra_assert(0, "Intentional error");
+            failTest("no exception thrown");
+        }
+        catch(vigra::ContractViolation & c)
+        {
+            std::string expected("\nPrecondition violation!\nIntentional error");
+            std::string message(c.what());
+            should(0 == expected.compare(message.substr(0,expected.size())));
+        }
+    }
+
+    void testPostcondition()
+    {
+        try
+        {
+            vigra_postcondition(0, "Intentional error");
+            failTest("no exception thrown");
+        }
+        catch(vigra::ContractViolation & c)
+        {
+            std::string expected("\nPostcondition violation!\nIntentional error");
+            std::string message(c.what());
+            should(0 == expected.compare(message.substr(0,expected.size())));
+        }
+    }
+
+    void testInvariant()
+    {
+        try
+        {
+            vigra_invariant(0, "Intentional error");
+            failTest("no exception thrown");
+        }
+        catch(vigra::ContractViolation & c)
+        {
+            std::string expected("\nInvariant violation!\nIntentional error");
+            std::string message(c.what());
+            should(0 == expected.compare(message.substr(0,expected.size())));
+        }
+    }
+};
+
+struct ErrorTestSuite
+: public vigra::test_suite
+{
+    ErrorTestSuite()
+    : vigra::test_suite("ErrorTest")
+    {
+        add( testCase(&ErrorTest::testPrecondition));
+        add( testCase(&ErrorTest::testPostcondition));
+        add( testCase(&ErrorTest::testInvariant));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    ErrorTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+
+    return (failed != 0);
+}
diff --git a/test/features/CMakeLists.txt b/test/features/CMakeLists.txt
new file mode 100644
index 0000000..6f25790
--- /dev/null
+++ b/test/features/CMakeLists.txt
@@ -0,0 +1,10 @@
+if(FFTW3_FOUND)
+    INCLUDE_DIRECTORIES(${FFTW3_INCLUDE_DIR})
+
+    VIGRA_ADD_TEST(test_features test.cxx LIBRARIES vigraimpex ${FFTW3_LIBRARIES})
+
+    # VIGRA_COPY_TEST_DATA(ghouse.gif)
+else()
+    MESSAGE(STATUS "** WARNING: test_features will not be executed")
+endif()
+
diff --git a/test/features/test.cxx b/test/features/test.cxx
new file mode 100644
index 0000000..23c6d4a
--- /dev/null
+++ b/test/features/test.cxx
@@ -0,0 +1,171 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2009-2010 by Ullrich Koethe and Janis Fehr          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <functional>
+#include <cmath>
+#include <time.h>
+#include <stdio.h>
+#include "vigra/unittest.hxx"
+#include <vigra/wigner-matrix.hxx>
+#include <vigra/multi_pointoperators.hxx>
+#include "wigner-matrix-reference.hxx"
+
+using namespace vigra;
+
+template <class Real>
+struct ComplexRealFunctor
+{
+    Real operator()(std::complex<Real> const & c) const
+    {
+        return c.real();
+    }
+};
+
+template <class Real>
+struct ComplexImagFunctor
+{
+    Real operator()(std::complex<Real> const & c) const
+    {
+        return c.imag();
+    }
+};
+
+struct InvariantFeaturesTest
+{
+
+    InvariantFeaturesTest()
+    {
+    }
+
+    void wignerMatrixTest()
+    {
+        typedef Matrix<float> M;
+        typedef MultiArrayShape<2>::type Shape;
+        
+        int l_max = 15;
+        WignerMatrix<float> wigner(l_max);
+        
+        M ref[] = { M(), 
+                     M(3, 3, wignerRef1),
+                     M(5, 5, wignerRef2),
+                     M(7, 7, wignerRef3),
+                     M(9, 9, wignerRef4),
+                     M(11, 11, wignerRef5),
+                     M(13, 13, wignerRef6),
+                     M(15, 15, wignerRef7),
+                     M(17, 17, wignerRef8),
+                     M(19, 19, wignerRef9),
+                     M(21, 21, wignerRef10),
+                     M(23, 23, wignerRef11),
+                     M(25, 25, wignerRef12),
+                     M(27, 27, wignerRef13),
+                     M(29, 29, wignerRef14),
+                     M(31, 31, wignerRef15) };
+        
+        for(int l=1; l<=l_max; ++l)
+        {
+            wigner.compute_D(l);
+            
+            shouldEqual(wigner.get_D(l).shape(), Shape(2*l+1, 2*l+1));
+            
+            M diff(2*l+1, 2*l+1);
+            FindMinMax<float> minmax;
+
+            transformMultiArray(srcMultiArrayRange(wigner.get_D(l)),
+                                destMultiArray(diff), ComplexImagFunctor<float>());
+            inspectMultiArray(srcMultiArrayRange(diff), minmax);
+            shouldEqual(minmax.min, 0.0f);
+            shouldEqual(minmax.max, 0.0f);
+
+            transformMultiArray(srcMultiArrayRange(wigner.get_D(l)),
+                                destMultiArray(diff), ComplexRealFunctor<float>());
+            diff -= ref[l];
+            inspectMultiArray(srcMultiArrayRange(diff), minmax);
+            should(minmax.min > -1e-4f);
+            should(minmax.max <  1e-4f);
+        }
+        
+        WignerMatrix<float> wigner2(l_max);
+        for(int l=1; l<=l_max; ++l)
+        {
+            wigner2.compute_D(l, 0.0f, float(M_PI / 2.0), 0.0f);
+            
+            shouldEqual(wigner2.get_D(l).shape(), Shape(2*l+1, 2*l+1));
+            
+            M diff(2*l+1, 2*l+1);
+            FindMinMax<float> minmax;
+
+            transformMultiArray(srcMultiArrayRange(wigner.get_D(l)),
+                                destMultiArray(diff), ComplexImagFunctor<float>());
+            inspectMultiArray(srcMultiArrayRange(diff), minmax);
+            shouldEqual(minmax.min, 0.0f);
+            shouldEqual(minmax.max, 0.0f);
+            
+            // FIXME: transpose() shouldn't be necessary below
+            transformMultiArray(srcMultiArrayRange(transpose(wigner2.get_D(l))),
+                                destMultiArray(diff), ComplexRealFunctor<float>());
+            diff -= ref[l];
+            inspectMultiArray(srcMultiArrayRange(diff), minmax);
+            should(minmax.min > -1e-4f);
+            should(minmax.max <  1e-4f);
+        }
+        
+        // FIXME: compute_D() with arbitrary angles, rot(), and rotatePH() are untested!
+    }
+
+};
+
+struct FeaturesTestSuite
+: public vigra::test_suite
+{
+    FeaturesTestSuite()
+    : vigra::test_suite("FeaturesTestSuite")
+    {
+        add( testCase( &InvariantFeaturesTest::wignerMatrixTest));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    FeaturesTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+
+    return (failed != 0);
+}
+
diff --git a/test/features/wigner-matrix-reference.hxx b/test/features/wigner-matrix-reference.hxx
new file mode 100644
index 0000000..0f3e5ee
--- /dev/null
+++ b/test/features/wigner-matrix-reference.hxx
@@ -0,0 +1,324 @@
+/************************************************************************/
+/*                                                                      */
+/*        Copyright 2010-2011 by Ullrich Koethe and Janis Fehr          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_WIGNER_MATRIX_REFERENCE_HXX
+#define VIGRA_WIGNER_MATRIX_REFERENCE_HXX
+
+static float wignerRef1[] = { 
+     0.5f, 0.7071f, 0.5f, 
+    -0.7071f, 0.0f, 0.7071f, 
+     0.5f, -0.7071f, 0.5f };
+
+static float wignerRef2[] = {  
+    0.25f, 0.499995f, 0.612365f, 0.499995f, 0.25f, 
+    -0.499995f, -0.49999f, 0.0f, 0.49999f, 0.499995f, 
+    0.612365f, 0.0f, -0.499987f, 0.0f, 0.612365f, 
+    -0.499995f, 0.49999f, 0.0f, -0.49999f, 0.499995f, 
+    0.25f, -0.499995f, 0.612365f, -0.499995f, 0.25f };
+
+static float wignerRef3[] = {  
+    0.125f, 0.306183f, 0.484115f, 0.559007f, 0.484115f, 0.306183f, 0.125f, 
+    -0.306183f, -0.49999f, -0.395275f, 0.0f, 0.395275f, 0.49999f, 0.306183f, 
+    0.484115f, 0.395275f, -0.124996f, -0.432999f, -0.124996f, 0.395275f, 0.484115f, 
+    -0.559007f, 0.0f, 0.432999f, 0.0f, -0.432999f, 0.0f, 0.559007f, 
+    0.484115f, -0.395275f, -0.124996f, 0.432999f, -0.124996f, -0.395275f, 0.484115f, 
+    -0.306183f, 0.49999f, -0.395275f, 0.0f, 0.395275f, -0.49999f, 0.306183f, 
+    0.125f, -0.306183f, 0.484115f, -0.559007f, 0.484115f, -0.306183f, 0.125f };
+
+static float wignerRef4[] = {  
+    0.0625f, 0.176775f, 0.330713f, 0.467698f, 0.522901f, 0.467698f, 0.330713f, 0.176775f, 0.0625f, 
+    -0.176775f, -0.374993f, -0.467695f, -0.330709f, -7.45058e-09f, 0.330709f, 0.467695f, 0.374993f, 0.176775f, 
+    0.330713f, 0.467695f, 0.249992f, -0.17677f, -0.395269f, -0.17677f, 0.249992f, 0.467695f, 0.330713f, 
+    -0.467698f, -0.330709f, 0.17677f, 0.374985f, 1.86265e-09f, -0.374985f, -0.17677f, 0.330709f, 0.467698f, 
+    0.522901f, 0.0f, -0.395269f, 5.58794e-09f, 0.374984f, 1.11759e-08f, -0.395269f, 0.0f, 0.522901f, 
+    -0.467698f, 0.330709f, 0.17677f, -0.374985f, -3.72529e-09f, 0.374985f, -0.17677f, -0.330709f, 0.467698f, 
+    0.330713f, -0.467695f, 0.249992f, 0.17677f, -0.39527f, 0.17677f, 0.249992f, -0.467695f, 0.330713f, 
+    -0.176775f, 0.374993f, -0.467695f, 0.330709f, -7.45058e-09f, -0.330709f, 0.467695f, -0.374993f, 0.176775f, 
+    0.0625f, -0.176775f, 0.330713f, -0.467698f, 0.522901f, -0.467698f, 0.330713f, -0.176775f, 0.0625f };
+
+static float wignerRef5[] = {  
+    0.03125f, 0.0988202f, 0.209628f, 0.342319f, 0.452844f, 0.496065f, 0.452844f, 0.342319f, 0.209628f, 0.0988202f, 0.03125f, 
+    -0.0988202f, -0.249995f, -0.397737f, -0.432999f, -0.286401f, 0.0f, 0.286401f, 0.432999f, 0.397737f, 0.249995f, 0.0988202f, 
+    0.209628f, 0.397737f, 0.406236f, 0.153087f, -0.202514f, -0.369739f, -0.202514f, 0.153087f, 0.406236f, 0.397737f, 0.209628f, 
+    -0.342319f, -0.432999f, -0.153087f, 0.249989f, 0.330703f, 1.86265e-09f, -0.330703f, -0.249989f, 0.153087f, 0.432999f, 0.342319f, 
+    0.452844f, 0.286401f, -0.202514f, -0.330703f, 0.0624968f, 0.342309f, 0.0624968f, -0.330703f, -0.202514f, 0.286401f, 0.452844f, 
+    -0.496065f, 0.0f, 0.369739f, -1.86265e-09f, -0.342309f, 0.0f, 0.342309f, -7.45058e-09f, -0.369739f, 0.0f, 0.496065f, 
+    0.452844f, -0.286401f, -0.202514f, 0.330703f, 0.0624968f, -0.342309f, 0.0624968f, 0.330703f, -0.202514f, -0.286401f, 0.452844f, 
+    -0.342319f, 0.432999f, -0.153087f, -0.249989f, 0.330703f, 0.0f, -0.330703f, 0.249989f, 0.153087f, -0.432999f, 0.342319f, 
+    0.209628f, -0.397737f, 0.406236f, -0.153087f, -0.202514f, 0.369739f, -0.202514f, -0.153087f, 0.406236f, -0.397737f, 0.209628f, 
+    -0.0988202f, 0.249995f, -0.397737f, 0.432999f, -0.286401f, 7.45058e-09f, 0.286401f, -0.432999f, 0.397737f, -0.249995f, 0.0988202f, 
+    0.03125f, -0.0988202f, 0.209628f, -0.342319f, 0.452844f, -0.496065f, 0.452844f, -0.342319f, 0.209628f, -0.0988202f, 0.03125f };
+
+static float wignerRef6[] = {  
+    0.015625f, 0.0541261f, 0.126936f, 0.231751f, 0.347625f, 0.439713f, 0.474944f, 0.439713f, 0.347625f, 0.231751f, 0.126936f, 0.0541261f, 0.015625f, 
+    -0.0541261f, -0.156247f, -0.293143f, -0.4014f, -0.401398f, -0.253866f, 0.0f, 0.253866f, 0.401398f, 0.4014f, 0.293143f, 0.156247f, 0.0541261f, 
+    0.126936f, 0.293143f, 0.406236f, 0.342313f, 0.0855778f, -0.216496f, -0.350763f, -0.216496f, 0.0855778f, 0.342313f, 0.406236f, 0.293143f, 0.126936f, 
+    -0.231751f, -0.4014f, -0.342313f, -0.0312486f, 0.281236f, 0.296447f, 7.45058e-09f, -0.296447f, -0.281235f, 0.0312485f, 0.342313f, 0.4014f, 0.231751f, 
+    0.347625f, 0.401398f, 0.0855778f, -0.281236f, -0.26561f, 0.0988154f, 0.320198f, 0.0988154f, -0.26561f, -0.281235f, 0.0855778f, 0.401398f, 0.347625f, 
+    -0.439713f, -0.253866f, 0.216496f, 0.296447f, -0.0988154f, -0.312481f, 9.31323e-09f, 0.312481f, 0.0988154f, -0.296447f, -0.216496f, 0.253866f, 0.439713f, 
+    0.474944f, -7.45058e-09f, -0.350763f, 0.0f, 0.320198f, 1.86265e-09f, -0.31248f, 3.72529e-09f, 0.320198f, -3.72529e-09f, -0.350763f, 0.0f, 0.474944f, 
+    -0.439713f, 0.253866f, 0.216496f, -0.296447f, -0.0988154f, 0.312481f, 1.11759e-08f, -0.312481f, 0.0988154f, 0.296447f, -0.216496f, -0.253866f, 0.439713f, 
+    0.347625f, -0.401398f, 0.0855778f, 0.281235f, -0.26561f, -0.0988154f, 0.320198f, -0.0988154f, -0.26561f, 0.281235f, 0.0855777f, -0.401398f, 0.347625f, 
+    -0.231751f, 0.4014f, -0.342313f, 0.0312485f, 0.281236f, -0.296447f, 3.72529e-09f, 0.296447f, -0.281235f, -0.0312485f, 0.342313f, -0.4014f, 0.231751f, 
+    0.126936f, -0.293143f, 0.406236f, -0.342313f, 0.0855778f, 0.216496f, -0.350763f, 0.216496f, 0.0855777f, -0.342313f, 0.406236f, -0.293143f, 0.126936f, 
+    -0.0541261f, 0.156247f, -0.293143f, 0.4014f, -0.401398f, 0.253866f, -3.72529e-09f, -0.253866f, 0.401398f, -0.4014f, 0.293143f, -0.156247f, 0.0541261f, 
+    0.015625f, -0.0541261f, 0.126936f, -0.231751f, 0.347625f, -0.439713f, 0.474944f, -0.439713f, 0.347625f, -0.231751f, 0.126936f, -0.0541261f, 0.015625f };
+
+static float wignerRef7[] = {  
+    0.0078125f, 0.0292314f, 0.0745252f, 0.149049f, 0.247169f, 0.349549f, 0.428107f, 0.457665f, 0.428107f, 0.349549f, 0.247169f, 0.149049f, 0.0745252f, 0.0292314f, 0.0078125f, 
+    -0.0292314f, -0.0937482f, -0.199175f, -0.318678f, -0.396349f, -0.37368f, -0.228831f, 0.0f, 0.228831f, 0.37368f, 0.396349f, 0.318678f, 0.199175f, 0.0937482f, 0.0292314f, 
+    0.0745252f, 0.199175f, 0.335926f, 0.390609f, 0.285009f, 0.036642f, -0.224385f, -0.335829f, -0.224385f, 0.036642f, 0.285009f, 0.390609f, 0.335926f, 0.199175f, 0.0745252f, 
+    -0.149049f, -0.318678f, -0.390609f, -0.249988f, 0.0518195f, 0.293134f, 0.26926f, 1.86265e-09f, -0.26926f, -0.293134f, -0.0518195f, 0.249988f, 0.390609f, 0.318678f, 0.149049f, 
+    0.247169f, 0.396349f, 0.285009f, -0.0518195f, -0.304669f, -0.209909f, 0.121777f, 0.303765f, 0.121777f, -0.209909f, -0.304669f, -0.0518194f, 0.285009f, 0.396349f, 0.247169f, 
+    -0.349549f, -0.37368f, -0.036642f, 0.293134f, 0.209909f, -0.15624f, -0.28703f, 3.72529e-09f, 0.28703f, 0.15624f, -0.209909f, -0.293134f, 0.036642f, 0.37368f, 0.349549f, 
+    0.428107f, 0.228831f, -0.224385f, -0.26926f, 0.121777f, 0.28703f, -0.0390597f, -0.292296f, -0.0390597f, 0.28703f, 0.121777f, -0.26926f, -0.224385f, 0.228831f, 0.428107f, 
+    -0.457665f, 7.45058e-09f, 0.335829f, -9.31323e-10f, -0.303765f, -1.86265e-09f, 0.292296f, 0.0f, -0.292296f, 7.45058e-09f, 0.303765f, 0.0f, -0.335828f, -7.45058e-09f, 0.457665f, 
+    0.428107f, -0.228831f, -0.224385f, 0.26926f, 0.121777f, -0.28703f, -0.0390597f, 0.292296f, -0.0390597f, -0.28703f, 0.121777f, 0.26926f, -0.224385f, -0.228831f, 0.428107f, 
+    -0.349549f, 0.37368f, -0.036642f, -0.293134f, 0.209909f, 0.15624f, -0.28703f, 0.0f, 0.28703f, -0.15624f, -0.209909f, 0.293134f, 0.036642f, -0.37368f, 0.349549f, 
+    0.247169f, -0.396349f, 0.285009f, 0.0518195f, -0.304669f, 0.209909f, 0.121777f, -0.303765f, 0.121777f, 0.209909f, -0.304669f, 0.0518195f, 0.285009f, -0.396349f, 0.247169f, 
+    -0.149049f, 0.318678f, -0.390609f, 0.249988f, 0.0518195f, -0.293134f, 0.26926f, 0.0f, -0.26926f, 0.293134f, -0.0518195f, -0.249988f, 0.390609f, -0.318678f, 0.149049f, 
+    0.0745252f, -0.199175f, 0.335926f, -0.390609f, 0.285009f, -0.036642f, -0.224385f, 0.335828f, -0.224385f, -0.036642f, 0.285009f, -0.390609f, 0.335926f, -0.199175f, 0.0745252f, 
+    -0.0292314f, 0.0937482f, -0.199175f, 0.318678f, -0.396349f, 0.37368f, -0.228831f, 0.0f, 0.228831f, -0.37368f, 0.396349f, -0.318678f, 0.199175f, -0.0937482f, 0.0292314f, 
+    0.0078125f, -0.0292314f, 0.0745252f, -0.149049f, 0.247169f, -0.349549f, 0.428107f, -0.457665f, 0.428107f, -0.349549f, 0.247169f, -0.149049f, 0.0745252f, -0.0292314f, 0.0078125f };
+
+static float wignerRef8[] = {  
+    0.00390625f, 0.0156249f, 0.0427901f, 0.0924364f, 0.166641f, 0.258158f, 0.349547f, 0.417788f, 0.44313f, 0.417788f, 0.349547f, 0.258158f, 0.166641f, 0.0924364f, 0.0427901f, 0.0156249f, 0.00390625f, 
+    -0.0156249f, -0.0546864f, -0.128369f, -0.231089f, -0.333279f, -0.387234f, -0.349543f, -0.208892f, 0.0f, 0.208892f, 0.349543f, 0.387234f, 0.333279f, 0.231089f, 0.128369f, 0.0546864f, 0.0156249f, 
+    0.0427901f, 0.128369f, 0.249991f, 0.3544f, 0.365086f, 0.235661f, -1.11759e-08f, -0.228828f, -0.323611f, -0.228828f, -2.79397e-09f, 0.235661f, 0.365086f, 0.3544f, 0.249991f, 0.128369f, 0.0427901f, 
+    -0.0924364f, -0.231089f, -0.3544f, -0.351545f, -0.169001f, 0.109089f, 0.295414f, 0.24716f, -3.72529e-09f, -0.24716f, -0.295414f, -0.109089f, 0.169001f, 0.351545f, 0.3544f, 0.231089f, 0.0924364f, 
+    0.166641f, 0.333279f, 0.365086f, 0.169001f, -0.140616f, -0.302557f, -0.163865f, 0.137099f, 0.290831f, 0.137099f, -0.163865f, -0.302557f, -0.140616f, 0.169001f, 0.365086f, 0.333279f, 0.166641f, 
+    -0.258158f, -0.387234f, -0.235661f, 0.109089f, 0.302557f, 0.132803f, -0.190393f, -0.26549f, -1.86265e-09f, 0.26549f, 0.190393f, -0.132803f, -0.302557f, -0.109089f, 0.235661f, 0.387234f, 0.258158f, 
+    0.349547f, 0.349543f, 1.30385e-08f, -0.295414f, -0.163865f, 0.190393f, 0.249981f, -0.0653589f, -0.277294f, -0.0653589f, 0.249981f, 0.190393f, -0.163865f, -0.295414f, 1.11759e-08f, 0.349543f, 0.349547f, 
+    -0.417788f, -0.208892f, 0.228828f, 0.24716f, -0.137099f, -0.26549f, 0.0653589f, 0.273415f, -5.58794e-09f, -0.273415f, -0.0653589f, 0.26549f, 0.137099f, -0.24716f, -0.228828f, 0.208892f, 0.417788f, 
+    0.44313f, -3.72529e-09f, -0.323611f, 9.31323e-10f, 0.290831f, 1.86265e-09f, -0.277294f, 0.0f, 0.273415f, -7.45058e-09f, -0.277294f, 3.72529e-09f, 0.290831f, 7.45058e-09f, -0.323611f, -3.72529e-09f, 0.44313f, 
+    -0.417788f, 0.208892f, 0.228828f, -0.24716f, -0.137099f, 0.26549f, 0.0653589f, -0.273415f, 3.72529e-09f, 0.273415f, -0.0653589f, -0.26549f, 0.137099f, 0.24716f, -0.228828f, -0.208892f, 0.417788f, 
+    0.349547f, -0.349543f, 0.0f, 0.295414f, -0.163865f, -0.190393f, 0.249981f, 0.0653589f, -0.277294f, 0.0653589f, 0.249981f, -0.190393f, -0.163865f, 0.295414f, -7.45058e-09f, -0.349543f, 0.349547f, 
+    -0.258158f, 0.387234f, -0.235661f, -0.109089f, 0.302557f, -0.132803f, -0.190393f, 0.26549f, 3.72529e-09f, -0.26549f, 0.190393f, 0.132803f, -0.302557f, 0.109089f, 0.235661f, -0.387234f, 0.258158f, 
+    0.166641f, -0.333279f, 0.365086f, -0.169001f, -0.140616f, 0.302557f, -0.163865f, -0.137099f, 0.290831f, -0.137099f, -0.163865f, 0.302557f, -0.140616f, -0.169001f, 0.365086f, -0.333279f, 0.166641f, 
+    -0.0924364f, 0.231089f, -0.3544f, 0.351545f, -0.169001f, -0.109089f, 0.295414f, -0.24716f, 7.45058e-09f, 0.24716f, -0.295414f, 0.109089f, 0.169001f, -0.351545f, 0.3544f, -0.231089f, 0.0924364f, 
+    0.0427901f, -0.128369f, 0.249991f, -0.3544f, 0.365086f, -0.235661f, 1.11759e-08f, 0.228828f, -0.323611f, 0.228828f, -1.49012e-08f, -0.235661f, 0.365086f, -0.3544f, 0.249991f, -0.128369f, 0.0427901f, 
+    -0.0156249f, 0.0546864f, -0.128369f, 0.231089f, -0.333279f, 0.387234f, -0.349543f, 0.208892f, -3.72529e-09f, -0.208892f, 0.349543f, -0.387234f, 0.333279f, -0.231089f, 0.128369f, -0.0546864f, 0.0156249f, 
+    0.00390625f, -0.0156249f, 0.0427901f, -0.0924364f, 0.166641f, -0.258158f, 0.349547f, -0.417788f, 0.44313f, -0.417788f, 0.349547f, -0.258158f, 0.166641f, -0.0924364f, 0.0427901f, -0.0156249f, 0.00390625f };
+
+static float wignerRef9[] = {  
+    0.00195312f, 0.00828633f, 0.0241584f, 0.055791f, 0.108038f, 0.180781f, 0.266102f, 0.348408f, 0.408544f, 0.430643f, 0.408544f, 0.348408f, 0.266102f, 0.180781f, 0.108038f, 0.055791f, 0.0241584f, 0.00828633f, 0.00195312f, 
+    -0.00828633f, -0.0312494f, -0.0797178f, -0.157799f, -0.254646f, -0.340881f, -0.376321f, -0.328479f, -0.192588f, 3.72529e-09f, 0.192588f, 0.328479f, 0.376321f, 0.340881f, 0.254646f, 0.157799f, 0.0797178f, 0.0312494f, 0.00828633f, 
+    0.0241584f, 0.0797178f, 0.173822f, 0.284152f, 0.358102f, 0.336146f, 0.193614f, -0.0281666f, -0.231198f, -0.313333f, -0.231198f, -0.0281666f, 0.193614f, 0.336146f, 0.358102f, 0.284152f, 0.173822f, 0.0797178f, 0.0241584f, 
+    -0.055791f, -0.157799f, -0.284152f, -0.359357f, -0.30256f, -0.101255f, 0.149043f, 0.292714f, 0.228825f, -3.25963e-09f, -0.228825f, -0.292714f, -0.149043f, 0.101255f, 0.30256f, 0.359357f, 0.284152f, 0.157799f, 0.055791f, 
+    0.108038f, 0.254646f, 0.358102f, 0.30256f, 0.070308f, -0.196079f, -0.288619f, -0.125963f, 0.147705f, 0.28025f, 0.147705f, -0.125963f, -0.288619f, -0.196079f, 0.0703081f, 0.30256f, 0.358102f, 0.254646f, 0.108038f, 
+    -0.180781f, -0.340881f, -0.336146f, -0.101255f, 0.196079f, 0.281229f, 0.0689928f, -0.210776f, -0.247156f, -5.58794e-09f, 0.247156f, 0.210776f, -0.0689928f, -0.281229f, -0.196079f, 0.101255f, 0.336146f, 0.340881f, 0.180781f, 
+    0.266102f, 0.376321f, 0.193614f, -0.149043f, -0.288619f, -0.0689928f, 0.226544f, 0.21479f, -0.0839545f, -0.265487f, -0.0839545f, 0.21479f, 0.226544f, -0.0689928f, -0.288619f, -0.149043f, 0.193614f, 0.376321f, 0.266102f, 
+    -0.348408f, -0.328479f, 0.0281666f, 0.292714f, 0.125963f, -0.210776f, -0.21479f, 0.109365f, 0.256484f, -7.45058e-09f, -0.256484f, -0.109365f, 0.21479f, 0.210776f, -0.125963f, -0.292714f, -0.0281666f, 0.328479f, 0.348408f, 
+    0.408544f, 0.192588f, -0.231198f, -0.228825f, 0.147705f, 0.247156f, -0.0839544f, -0.256484f, 0.0273413f, 0.259382f, 0.0273413f, -0.256484f, -0.0839544f, 0.247156f, 0.147705f, -0.228825f, -0.231198f, 0.192588f, 0.408544f, 
+    -0.430643f, 3.72529e-09f, 0.313333f, -5.12227e-09f, -0.28025f, -2.79397e-09f, 0.265487f, 3.72529e-09f, -0.259382f, 0.0f, 0.259382f, -7.45058e-09f, -0.265487f, 0.0f, 0.28025f, 0.0f, -0.313333f, -7.45058e-09f, 0.430643f, 
+    0.408544f, -0.192588f, -0.231198f, 0.228825f, 0.147705f, -0.247156f, -0.0839544f, 0.256484f, 0.0273413f, -0.259382f, 0.0273413f, 0.256484f, -0.0839544f, -0.247156f, 0.147705f, 0.228825f, -0.231198f, -0.192588f, 0.408544f, 
+    -0.348408f, 0.328479f, 0.0281666f, -0.292714f, 0.125963f, 0.210776f, -0.21479f, -0.109365f, 0.256484f, 0.0f, -0.256484f, 0.109365f, 0.21479f, -0.210776f, -0.125963f, 0.292714f, -0.0281666f, -0.328479f, 0.348408f, 
+    0.266102f, -0.376321f, 0.193614f, 0.149043f, -0.288619f, 0.0689928f, 0.226544f, -0.21479f, -0.0839544f, 0.265487f, -0.0839544f, -0.21479f, 0.226544f, 0.0689928f, -0.288619f, 0.149043f, 0.193614f, -0.376321f, 0.266102f, 
+    -0.180781f, 0.340881f, -0.336146f, 0.101255f, 0.196079f, -0.281229f, 0.0689928f, 0.210776f, -0.247156f, 3.72529e-09f, 0.247156f, -0.210776f, -0.0689928f, 0.281229f, -0.196079f, -0.101255f, 0.336146f, -0.340881f, 0.180781f, 
+    0.108038f, -0.254646f, 0.358102f, -0.30256f, 0.0703081f, 0.196079f, -0.288619f, 0.125963f, 0.147705f, -0.28025f, 0.147705f, 0.125963f, -0.288619f, 0.196079f, 0.070308f, -0.30256f, 0.358102f, -0.254646f, 0.108038f, 
+    -0.055791f, 0.157799f, -0.284152f, 0.359357f, -0.30256f, 0.101255f, 0.149043f, -0.292714f, 0.228825f, -3.72529e-09f, -0.228825f, 0.292714f, -0.149043f, -0.101255f, 0.30256f, -0.359357f, 0.284152f, -0.157799f, 0.055791f, 
+    0.0241584f, -0.0797178f, 0.173822f, -0.284152f, 0.358102f, -0.336146f, 0.193614f, 0.0281666f, -0.231198f, 0.313333f, -0.231198f, 0.0281666f, 0.193614f, -0.336146f, 0.358102f, -0.284152f, 0.173822f, -0.0797178f, 0.0241584f, 
+    -0.00828633f, 0.0312494f, -0.0797178f, 0.157799f, -0.254646f, 0.340881f, -0.376321f, 0.328479f, -0.192588f, 3.72529e-09f, 0.192588f, -0.328479f, 0.376321f, -0.340881f, 0.254646f, -0.157799f, 0.0797178f, -0.0312494f, 0.00828633f, 
+    0.00195312f, -0.00828633f, 0.0241584f, -0.055791f, 0.108038f, -0.180781f, 0.266102f, -0.348408f, 0.408544f, -0.430643f, 0.408544f, -0.348408f, 0.266102f, -0.180781f, 0.108038f, -0.055791f, 0.0241584f, -0.00828633f, 0.00195312f };
+
+static float wignerRef10[] = {  
+    0.000976562f, 0.00436728f, 0.0134607f, 0.0329717f, 0.0679724f, 0.121592f, 0.192253f, 0.271886f, 0.346587f, 0.400204f, 0.419737f, 0.400204f, 0.346587f, 0.271886f, 0.192253f, 0.121592f, 0.0679724f, 0.0329717f, 0.0134607f, 0.00436728f, 0.000976562f, 
+    -0.00436728f, -0.0175778f, -0.0481581f, -0.103217f, -0.182387f, -0.271886f, -0.34391f, -0.36477f, -0.309994f, -0.178975f, 0.0f, 0.178975f, 0.309994f, 0.36477f, 0.34391f, 0.271886f, 0.182387f, 0.103217f, 0.0481581f, 0.0175778f, 0.00436728f, 
+    0.0134607f, 0.0481581f, 0.11523f, 0.210494f, 0.305731f, 0.352842f, 0.30684f, 0.157795f, -0.0502873f, -0.232266f, -0.304504f, -0.232266f, -0.0502872f, 0.157795f, 0.30684f, 0.352842f, 0.305731f, 0.210494f, 0.11523f, 0.0481581f, 0.0134607f, 
+    -0.0329717f, -0.103217f, -0.210494f, -0.314437f, -0.346256f, -0.252081f, -0.0455512f, 0.177152f, 0.287413f, 0.213349f, -4.19095e-09f, -0.213349f, -0.287413f, -0.177152f, 0.0455512f, 0.252081f, 0.346256f, 0.314437f, 0.210494f, 0.103217f, 0.0329717f, 
+    0.0679724f, 0.182387f, 0.305731f, 0.346256f, 0.23143f, -0.00873404f, -0.22924f, -0.26951f, -0.094603f, 0.155233f, 0.271349f, 0.155233f, -0.094603f, -0.26951f, -0.22924f, -0.00873401f, 0.23143f, 0.346256f, 0.305731f, 0.182387f, 0.0679724f, 
+    -0.121592f, -0.271886f, -0.352842f, -0.252081f, 0.00873402f, 0.242169f, 0.247033f, 0.0174678f, -0.222671f, -0.231406f, -1.49012e-08f, 0.231406f, 0.222671f, -0.0174678f, -0.247033f, -0.242169f, -0.008734f, 0.252081f, 0.352842f, 0.271886f, 0.121592f, 
+    0.192253f, 0.34391f, 0.30684f, 0.0455512f, -0.22924f, -0.247033f, 0.00781185f, 0.243046f, 0.183078f, -0.0975691f, -0.255828f, -0.0975691f, 0.183078f, 0.243046f, 0.00781184f, -0.247033f, -0.22924f, 0.0455512f, 0.30684f, 0.34391f, 0.192253f, 
+    -0.271886f, -0.36477f, -0.157795f, 0.177152f, 0.26951f, 0.0174678f, -0.243046f, -0.164047f, 0.139413f, 0.24147f, 0.0f, -0.24147f, -0.139413f, 0.164047f, 0.243046f, -0.0174678f, -0.26951f, -0.177152f, 0.157795f, 0.36477f, 0.271886f, 
+    0.346587f, 0.309994f, -0.0502872f, -0.287413f, -0.094603f, 0.222671f, 0.183078f, -0.139413f, -0.232399f, 0.0473561f, 0.248337f, 0.0473561f, -0.232399f, -0.139413f, 0.183078f, 0.222671f, -0.094603f, -0.287413f, -0.0502872f, 0.309994f, 0.346587f, 
+    -0.400204f, -0.178975f, 0.232266f, 0.213349f, -0.155233f, -0.231406f, 0.097569f, 0.24147f, -0.0473561f, -0.246069f, 7.45058e-09f, 0.246069f, 0.0473561f, -0.24147f, -0.0975691f, 0.231406f, 0.155233f, -0.213349f, -0.232266f, 0.178975f, 0.400204f, 
+    0.419737f, 0.0f, -0.304504f, -9.31323e-10f, 0.271349f, 3.72529e-09f, -0.255828f, 3.72529e-09f, 0.248337f, -1.86265e-09f, -0.246069f, 3.72529e-09f, 0.248337f, 3.72529e-09f, -0.255828f, 3.72529e-09f, 0.271349f, 0.0f, -0.304504f, -3.72529e-09f, 0.419737f, 
+    -0.400204f, 0.178975f, 0.232266f, -0.213349f, -0.155233f, 0.231406f, 0.097569f, -0.24147f, -0.0473561f, 0.246069f, 0.0f, -0.246069f, 0.0473561f, 0.24147f, -0.097569f, -0.231406f, 0.155233f, 0.213349f, -0.232266f, -0.178975f, 0.400204f, 
+    0.346587f, -0.309994f, -0.0502872f, 0.287413f, -0.094603f, -0.222671f, 0.183078f, 0.139413f, -0.232399f, -0.0473561f, 0.248337f, -0.0473561f, -0.232399f, 0.139413f, 0.183078f, -0.222671f, -0.094603f, 0.287413f, -0.0502872f, -0.309994f, 0.346587f, 
+    -0.271886f, 0.36477f, -0.157795f, -0.177152f, 0.26951f, -0.0174678f, -0.243046f, 0.164047f, 0.139413f, -0.24147f, 0.0f, 0.24147f, -0.139413f, -0.164047f, 0.243046f, 0.0174678f, -0.26951f, 0.177152f, 0.157795f, -0.36477f, 0.271886f, 
+    0.192253f, -0.34391f, 0.30684f, -0.0455512f, -0.22924f, 0.247033f, 0.00781183f, -0.243046f, 0.183078f, 0.0975691f, -0.255828f, 0.0975691f, 0.183078f, -0.243046f, 0.00781185f, 0.247033f, -0.22924f, -0.0455512f, 0.30684f, -0.34391f, 0.192253f, 
+    -0.121592f, 0.271886f, -0.352842f, 0.252081f, 0.00873402f, -0.242169f, 0.247033f, -0.0174678f, -0.222671f, 0.231406f, 0.0f, -0.231406f, 0.222671f, 0.0174678f, -0.247033f, 0.242169f, -0.00873403f, -0.252081f, 0.352842f, -0.271886f, 0.121592f, 
+    0.0679724f, -0.182387f, 0.305731f, -0.346256f, 0.23143f, 0.00873402f, -0.22924f, 0.26951f, -0.094603f, -0.155233f, 0.271349f, -0.155233f, -0.094603f, 0.26951f, -0.22924f, 0.00873404f, 0.23143f, -0.346256f, 0.305731f, -0.182387f, 0.0679724f, 
+    -0.0329717f, 0.103217f, -0.210494f, 0.314437f, -0.346256f, 0.252081f, -0.0455512f, -0.177152f, 0.287413f, -0.213349f, 0.0f, 0.213349f, -0.287413f, 0.177152f, 0.0455512f, -0.252081f, 0.346256f, -0.314437f, 0.210494f, -0.103217f, 0.0329717f, 
+    0.0134607f, -0.0481581f, 0.11523f, -0.210494f, 0.305731f, -0.352842f, 0.30684f, -0.157795f, -0.0502872f, 0.232266f, -0.304504f, 0.232266f, -0.0502872f, -0.157795f, 0.30684f, -0.352842f, 0.305731f, -0.210494f, 0.11523f, -0.0481581f, 0.0134607f, 
+    -0.00436728f, 0.0175778f, -0.0481581f, 0.103217f, -0.182387f, 0.271886f, -0.34391f, 0.36477f, -0.309994f, 0.178975f, 0.0f, -0.178975f, 0.309994f, -0.36477f, 0.34391f, -0.271886f, 0.182387f, -0.103217f, 0.0481581f, -0.0175778f, 0.00436728f, 
+    0.000976562f, -0.00436728f, 0.0134607f, -0.0329717f, 0.0679724f, -0.121592f, 0.192253f, -0.271886f, 0.346587f, -0.400204f, 0.419737f, -0.400204f, 0.346587f, -0.271886f, 0.192253f, -0.121592f, 0.0679724f, -0.0329717f, 0.0134607f, -0.00436728f, 0.000976562f };
+
+static float wignerRef11[] = {  
+    0.000488281f, 0.00229022f, 0.0074211f, 0.019161f, 0.0417602f, 0.079234f, 0.13337f, 0.201636f, 0.2761f, 0.344357f, 0.392626f, 0.410085f, 0.392626f, 0.344357f, 0.2761f, 0.201636f, 0.13337f, 0.079234f, 0.0417602f, 0.019161f, 0.0074211f, 0.00229022f, 0.000488281f, 
+    -0.00229022f, -0.00976544f, -0.028479f, -0.0653617f, -0.124645f, -0.202711f, -0.284343f, -0.343908f, -0.353185f, -0.293665f, -0.167415f, -3.72529e-09f, 0.167415f, 0.293665f, 0.353185f, 0.343908f, 0.284343f, 0.202711f, 0.124645f, 0.0653617f, 0.028479f, 0.00976544f, 0.00229022f, 
+    0.0074211f, 0.028479f, 0.0737278f, 0.1475f, 0.239039f, 0.318f, 0.342223f, 0.278595f, 0.12716f, -0.0679698f, -0.232492f, -0.296792f, -0.232492f, -0.0679698f, 0.12716f, 0.278595f, 0.342223f, 0.318f, 0.239039f, 0.1475f, 0.0737278f, 0.028479f, 0.0074211f, 
+    -0.019161f, -0.0653617f, -0.1475f, -0.249987f, -0.327749f, -0.323043f, -0.20391f, 4.19095e-09f, 0.196994f, 0.280793f, 0.200096f, 3.25963e-09f, -0.200096f, -0.280793f, -0.196994f, -9.31323e-09f, 0.20391f, 0.323043f, 0.327749f, 0.249987f, 0.1475f, 0.0653617f, 0.019161f, 
+    0.0417602f, 0.124645f, 0.239039f, 0.327749f, 0.313944f, 0.162117f, -0.0701697f, -0.247534f, -0.248563f, -0.0684441f, 0.160667f, 0.263703f, 0.160667f, -0.0684441f, -0.248563f, -0.247534f, -0.0701696f, 0.162117f, 0.313944f, 0.327749f, 0.239039f, 0.124645f, 0.0417602f, 
+    -0.079234f, -0.202711f, -0.318f, -0.323043f, -0.162117f, 0.0917897f, 0.261342f, 0.208738f, -0.0238188f, -0.22917f, -0.217744f, -3.72529e-09f, 0.217744f, 0.22917f, 0.0238188f, -0.208738f, -0.261342f, -0.0917897f, 0.162117f, 0.323043f, 0.318f, 0.202711f, 0.079234f, 
+    0.13337f, 0.284343f, 0.342223f, 0.20391f, -0.0701696f, -0.261343f, -0.192854f, 0.0671711f, 0.247632f, 0.155055f, -0.107799f, -0.247703f, -0.107799f, 0.155055f, 0.247632f, 0.0671711f, -0.192854f, -0.261342f, -0.0701696f, 0.20391f, 0.342223f, 0.284343f, 0.13337f, 
+    -0.201636f, -0.343908f, -0.278595f, -5.12227e-09f, 0.247534f, 0.208738f, -0.0671711f, -0.249976f, -0.117663f, 0.160092f, 0.228166f, 1.86265e-09f, -0.228166f, -0.160092f, 0.117663f, 0.249976f, 0.0671711f, -0.208738f, -0.247534f, 1.49012e-08f, 0.278595f, 0.343908f, 0.201636f, 
+    0.2761f, 0.353185f, 0.12716f, -0.196994f, -0.248563f, 0.0238188f, 0.247632f, 0.117663f, -0.174787f, -0.208254f, 0.0624857f, 0.239302f, 0.0624857f, -0.208254f, -0.174787f, 0.117663f, 0.247632f, 0.0238188f, -0.248563f, -0.196994f, 0.12716f, 0.353185f, 0.2761f, 
+    -0.344357f, -0.293665f, 0.0679697f, 0.280793f, 0.0684441f, -0.22917f, -0.155055f, 0.160092f, 0.208254f, -0.0820225f, -0.2338f, 7.45058e-09f, 0.2338f, 0.0820225f, -0.208254f, -0.160092f, 0.155055f, 0.22917f, -0.0684441f, -0.280793f, -0.0679697f, 0.293665f, 0.344357f, 
+    0.392626f, 0.167415f, -0.232492f, -0.200096f, 0.160667f, 0.217744f, -0.107799f, -0.228166f, 0.0624857f, 0.2338f, -0.0205056f, -0.235591f, -0.0205056f, 0.2338f, 0.0624857f, -0.228166f, -0.107799f, 0.217744f, 0.160667f, -0.200096f, -0.232492f, 0.167415f, 0.392626f, 
+    -0.410085f, -3.72529e-09f, 0.296792f, 4.65661e-10f, -0.263703f, -1.86265e-09f, 0.247703f, -1.86265e-09f, -0.239302f, -3.72529e-09f, 0.235591f, -3.72529e-09f, -0.235591f, 3.72529e-09f, 0.239302f, -3.72529e-09f, -0.247703f, 7.45058e-09f, 0.263703f, -3.72529e-09f, -0.296792f, 0.0f, 0.410085f, 
+    0.392626f, -0.167415f, -0.232492f, 0.200096f, 0.160667f, -0.217744f, -0.107799f, 0.228166f, 0.0624857f, -0.2338f, -0.0205056f, 0.235591f, -0.0205056f, -0.2338f, 0.0624857f, 0.228166f, -0.107799f, -0.217744f, 0.160667f, 0.200096f, -0.232492f, -0.167415f, 0.392626f, 
+    -0.344357f, 0.293665f, 0.0679698f, -0.280793f, 0.0684441f, 0.22917f, -0.155055f, -0.160092f, 0.208254f, 0.0820225f, -0.2338f, 0.0f, 0.2338f, -0.0820225f, -0.208254f, 0.160092f, 0.155055f, -0.22917f, -0.068444f, 0.280793f, -0.0679698f, -0.293665f, 0.344357f, 
+    0.2761f, -0.353185f, 0.12716f, 0.196994f, -0.248563f, -0.0238188f, 0.247632f, -0.117663f, -0.174787f, 0.208254f, 0.0624857f, -0.239302f, 0.0624857f, 0.208254f, -0.174787f, -0.117663f, 0.247632f, -0.0238188f, -0.248563f, 0.196994f, 0.12716f, -0.353185f, 0.2761f, 
+    -0.201636f, 0.343908f, -0.278595f, 9.31323e-10f, 0.247534f, -0.208738f, -0.0671711f, 0.249976f, -0.117663f, -0.160092f, 0.228166f, 0.0f, -0.228166f, 0.160092f, 0.117663f, -0.249976f, 0.0671711f, 0.208738f, -0.247534f, -3.72529e-09f, 0.278595f, -0.343908f, 0.201636f, 
+    0.13337f, -0.284343f, 0.342223f, -0.20391f, -0.0701696f, 0.261342f, -0.192854f, -0.0671711f, 0.247632f, -0.155055f, -0.107799f, 0.247703f, -0.107799f, -0.155055f, 0.247632f, -0.0671711f, -0.192854f, 0.261342f, -0.0701697f, -0.20391f, 0.342223f, -0.284343f, 0.13337f, 
+    -0.079234f, 0.202711f, -0.318f, 0.323043f, -0.162117f, -0.0917897f, 0.261342f, -0.208738f, -0.0238188f, 0.22917f, -0.217744f, 0.0f, 0.217744f, -0.22917f, 0.0238188f, 0.208738f, -0.261342f, 0.0917897f, 0.162117f, -0.323043f, 0.318f, -0.202711f, 0.079234f, 
+    0.0417602f, -0.124645f, 0.239039f, -0.327749f, 0.313944f, -0.162117f, -0.0701696f, 0.247534f, -0.248563f, 0.0684441f, 0.160667f, -0.263703f, 0.160667f, 0.0684441f, -0.248563f, 0.247534f, -0.0701697f, -0.162117f, 0.313944f, -0.327749f, 0.239039f, -0.124645f, 0.0417602f, 
+    -0.019161f, 0.0653617f, -0.1475f, 0.249987f, -0.327749f, 0.323043f, -0.20391f, 1.49012e-08f, 0.196994f, -0.280793f, 0.200096f, 0.0f, -0.200096f, 0.280793f, -0.196994f, 3.72529e-09f, 0.20391f, -0.323043f, 0.327749f, -0.249987f, 0.1475f, -0.0653617f, 0.019161f, 
+    0.0074211f, -0.028479f, 0.0737278f, -0.1475f, 0.239039f, -0.318f, 0.342223f, -0.278595f, 0.12716f, 0.0679697f, -0.232492f, 0.296792f, -0.232492f, 0.0679698f, 0.12716f, -0.278595f, 0.342223f, -0.318f, 0.239039f, -0.1475f, 0.0737278f, -0.028479f, 0.0074211f, 
+    -0.00229022f, 0.00976544f, -0.028479f, 0.0653617f, -0.124645f, 0.202711f, -0.284343f, 0.343908f, -0.353185f, 0.293665f, -0.167415f, 0.0f, 0.167415f, -0.293665f, 0.353185f, -0.343908f, 0.284343f, -0.202711f, 0.124645f, -0.0653617f, 0.028479f, -0.00976544f, 0.00229022f, 
+    0.000488281f, -0.00229022f, 0.0074211f, -0.019161f, 0.0417602f, -0.079234f, 0.13337f, -0.201636f, 0.2761f, -0.344357f, 0.392626f, -0.410085f, 0.392626f, -0.344357f, 0.2761f, -0.201636f, 0.13337f, -0.079234f, 0.0417602f, -0.019161f, 0.0074211f, -0.00229022f, 0.000488281f };
+
+static float wignerRef12[] = {  
+    0.000244141f, 0.00119603f, 0.00405589f, 0.0109833f, 0.0251658f, 0.0503312f, 0.0895646f, 0.143622f, 0.209363f, 0.27915f, 0.341886f, 0.385699f, 0.401448f, 0.385699f, 0.341886f, 0.27915f, 0.209363f, 0.143622f, 0.0895646f, 0.0503312f, 0.0251658f, 0.0109833f, 0.00405589f, 0.00119603f, 0.000244141f, 
+    -0.00119603f, -0.00537099f, -0.016558f, -0.0403549f, -0.0821903f, -0.143832f, -0.219386f, -0.293165f, -0.341885f, -0.341884f, -0.279146f, -0.15746f, -7.45058e-09f, 0.15746f, 0.279146f, 0.341884f, 0.341885f, 0.293165f, 0.219386f, 0.143832f, 0.0821903f, 0.0403549f, 0.016558f, 0.00537099f, 0.00119603f, 
+    0.00405589f, 0.016558f, 0.0458967f, 0.099166f, 0.175714f, 0.26054f, 0.323463f, 0.328506f, 0.252039f, 0.100815f, -0.0823151f, -0.232159f, -0.289967f, -0.232159f, -0.0823151f, 0.100815f, 0.252039f, 0.328506f, 0.323463f, 0.26054f, 0.175714f, 0.099166f, 0.0458967f, 0.016558f, 0.00405589f, 
+    -0.0109833f, -0.0403549f, -0.099166f, -0.186025f, -0.277444f, -0.328903f, -0.294633f, -0.159615f, 0.0372283f, 0.21096f, 0.273569f, 0.188606f, -4.65661e-10f, -0.188606f, -0.273569f, -0.21096f, -0.0372283f, 0.159615f, 0.294633f, 0.328903f, 0.277444f, 0.186025f, 0.099166f, 0.0403549f, 0.0109833f, 
+    0.0251658f, 0.0821903f, 0.175714f, 0.277444f, 0.328591f, 0.271464f, 0.0990471f, -0.117031f, -0.2559f, -0.227466f, -0.0464313f, 0.164627f, 0.257024f, 0.164627f, -0.0464313f, -0.227466f, -0.2559f, -0.117031f, 0.0990472f, 0.271465f, 0.328591f, 0.277444f, 0.175714f, 0.0821903f, 0.0251658f, 
+    -0.0503312f, -0.143832f, -0.26054f, -0.328903f, -0.271465f, -0.0786071f, 0.151176f, 0.263319f, 0.170599f, -0.0568662f, -0.232155f, -0.205783f, 7.45058e-09f, 0.205783f, 0.232155f, 0.0568662f, -0.170599f, -0.263318f, -0.151176f, 0.0786071f, 0.271465f, 0.328903f, 0.26054f, 0.143832f, 0.0503312f, 
+    0.0895646f, 0.219386f, 0.323463f, 0.294633f, 0.0990472f, -0.151176f, -0.262672f, -0.137011f, 0.111846f, 0.244995f, 0.130459f, -0.115639f, -0.240723f, -0.115639f, 0.130459f, 0.244995f, 0.111846f, -0.137011f, -0.262672f, -0.151176f, 0.0990472f, 0.294633f, 0.323463f, 0.219386f, 0.0895646f, 
+    -0.143622f, -0.293165f, -0.328506f, -0.159615f, 0.117031f, 0.263319f, 0.137011f, -0.128405f, -0.241982f, -0.0768647f, 0.174332f, 0.216341f, 2.79397e-09f, -0.216341f, -0.174332f, 0.0768647f, 0.241982f, 0.128405f, -0.137011f, -0.263319f, -0.117031f, 0.159616f, 0.328506f, 0.293165f, 0.143622f, 
+    0.209363f, 0.341885f, 0.252039f, -0.0372283f, -0.2559f, -0.170599f, 0.111846f, 0.241982f, 0.0583434f, -0.196267f, -0.185365f, 0.0742039f, 0.231702f, 0.0742039f, -0.185365f, -0.196267f, 0.0583434f, 0.241982f, 0.111846f, -0.170599f, -0.2559f, -0.0372282f, 0.252039f, 0.341885f, 0.209363f, 
+    -0.27915f, -0.341884f, -0.100815f, 0.21096f, 0.227466f, -0.0568662f, -0.244995f, -0.0768647f, 0.196267f, 0.172832f, -0.107631f, -0.222611f, 3.72529e-09f, 0.222611f, 0.107631f, -0.172832f, -0.196267f, 0.0768647f, 0.244995f, 0.0568662f, -0.227466f, -0.21096f, 0.100815f, 0.341884f, 0.27915f, 
+    0.341886f, 0.279146f, -0.0823151f, -0.273569f, -0.0464313f, 0.232155f, 0.130459f, -0.174332f, -0.185365f, 0.107631f, 0.216771f, -0.0363522f, -0.227019f, -0.0363522f, 0.216771f, 0.107631f, -0.185365f, -0.174332f, 0.130459f, 0.232155f, -0.0464313f, -0.273569f, -0.082315f, 0.279146f, 0.341886f, 
+    -0.385699f, -0.15746f, 0.232159f, 0.188606f, -0.164627f, -0.205783f, 0.115639f, 0.216341f, -0.0742039f, -0.222611f, 0.0363522f, 0.225559f, -5.58794e-09f, -0.225559f, -0.0363522f, 0.222611f, 0.0742039f, -0.216341f, -0.115639f, 0.205783f, 0.164627f, -0.188606f, -0.232159f, 0.15746f, 0.385699f, 
+    0.401448f, 3.72529e-09f, -0.289967f, 4.65661e-10f, 0.257024f, 6.51926e-09f, -0.240723f, 4.65661e-09f, 0.231702f, -1.86265e-09f, -0.227019f, -1.86265e-09f, 0.225559f, 0.0f, -0.227019f, 0.0f, 0.231702f, 0.0f, -0.240723f, 1.49012e-08f, 0.257024f, 3.72529e-09f, -0.289967f, 3.72529e-09f, 0.401448f, 
+    -0.385699f, 0.15746f, 0.232159f, -0.188606f, -0.164627f, 0.205783f, 0.115639f, -0.216341f, -0.0742039f, 0.222611f, 0.0363522f, -0.225559f, 0.0f, 0.225559f, -0.0363522f, -0.222611f, 0.0742039f, 0.21634f, -0.115639f, -0.205783f, 0.164627f, 0.188606f, -0.232159f, -0.15746f, 0.385699f, 
+    0.341886f, -0.279146f, -0.082315f, 0.273569f, -0.0464312f, -0.232155f, 0.130459f, 0.174332f, -0.185365f, -0.107631f, 0.216771f, 0.0363522f, -0.227019f, 0.0363522f, 0.216771f, -0.107631f, -0.185365f, 0.174332f, 0.130459f, -0.232155f, -0.0464312f, 0.273569f, -0.0823151f, -0.279146f, 0.341886f, 
+    -0.27915f, 0.341884f, -0.100815f, -0.21096f, 0.227466f, 0.0568662f, -0.244995f, 0.0768647f, 0.196267f, -0.172832f, -0.107631f, 0.222611f, 0.0f, -0.222611f, 0.107631f, 0.172832f, -0.196267f, -0.0768647f, 0.244995f, -0.0568662f, -0.227466f, 0.21096f, 0.100815f, -0.341884f, 0.27915f, 
+    0.209363f, -0.341885f, 0.252039f, 0.0372283f, -0.2559f, 0.170599f, 0.111846f, -0.241982f, 0.0583434f, 0.196267f, -0.185365f, -0.0742039f, 0.231702f, -0.0742039f, -0.185365f, 0.196267f, 0.0583433f, -0.241982f, 0.111846f, 0.170599f, -0.2559f, 0.0372283f, 0.252039f, -0.341885f, 0.209363f, 
+    -0.143622f, 0.293165f, -0.328506f, 0.159616f, 0.117031f, -0.263319f, 0.137011f, 0.128405f, -0.241982f, 0.0768647f, 0.174332f, -0.21634f, -1.11759e-08f, 0.216341f, -0.174332f, -0.0768647f, 0.241982f, -0.128405f, -0.137011f, 0.263319f, -0.117031f, -0.159615f, 0.328506f, -0.293165f, 0.143622f, 
+    0.0895646f, -0.219386f, 0.323463f, -0.294633f, 0.0990472f, 0.151176f, -0.262672f, 0.137011f, 0.111846f, -0.244995f, 0.130459f, 0.115639f, -0.240723f, 0.115639f, 0.130459f, -0.244995f, 0.111846f, 0.137011f, -0.262672f, 0.151176f, 0.0990471f, -0.294633f, 0.323463f, -0.219386f, 0.0895646f, 
+    -0.0503312f, 0.143832f, -0.26054f, 0.328903f, -0.271465f, 0.078607f, 0.151176f, -0.263319f, 0.170599f, 0.0568662f, -0.232155f, 0.205783f, -3.72529e-09f, -0.205783f, 0.232155f, -0.0568662f, -0.170599f, 0.263319f, -0.151176f, -0.078607f, 0.271465f, -0.328903f, 0.26054f, -0.143832f, 0.0503312f, 
+    0.0251658f, -0.0821903f, 0.175714f, -0.277444f, 0.328591f, -0.271465f, 0.0990471f, 0.117031f, -0.2559f, 0.227466f, -0.0464312f, -0.164627f, 0.257024f, -0.164627f, -0.0464312f, 0.227466f, -0.2559f, 0.117031f, 0.0990471f, -0.271465f, 0.328591f, -0.277444f, 0.175714f, -0.0821903f, 0.0251658f, 
+    -0.0109833f, 0.0403549f, -0.099166f, 0.186025f, -0.277444f, 0.328903f, -0.294633f, 0.159616f, 0.0372282f, -0.21096f, 0.273569f, -0.188606f, -3.72529e-09f, 0.188606f, -0.273569f, 0.21096f, -0.0372283f, -0.159615f, 0.294633f, -0.328903f, 0.277444f, -0.186025f, 0.099166f, -0.0403549f, 0.0109833f, 
+    0.00405589f, -0.016558f, 0.0458967f, -0.0991659f, 0.175714f, -0.26054f, 0.323463f, -0.328506f, 0.252039f, -0.100815f, -0.082315f, 0.232159f, -0.289967f, 0.232159f, -0.082315f, -0.100815f, 0.252039f, -0.328506f, 0.323463f, -0.26054f, 0.175714f, -0.099166f, 0.0458967f, -0.016558f, 0.00405589f, 
+    -0.00119603f, 0.00537099f, -0.016558f, 0.0403549f, -0.0821903f, 0.143832f, -0.219386f, 0.293165f, -0.341885f, 0.341884f, -0.279146f, 0.15746f, -3.72529e-09f, -0.15746f, 0.279146f, -0.341884f, 0.341885f, -0.293165f, 0.219386f, -0.143832f, 0.0821903f, -0.0403549f, 0.016558f, -0.00537099f, 0.00119603f, 
+    0.000244141f, -0.00119603f, 0.00405589f, -0.0109833f, 0.0251658f, -0.0503312f, 0.0895646f, -0.143622f, 0.209363f, -0.27915f, 0.341886f, -0.385699f, 0.401448f, -0.385699f, 0.341886f, -0.27915f, 0.209363f, -0.143622f, 0.0895646f, -0.0503312f, 0.0251658f, -0.0109833f, 0.00405589f, -0.00119603f, 0.000244141f };
+
+static float wignerRef13[] = {  
+    0.00012207f, 0.000622433f, 0.00220061f, 0.00622422f, 0.0149251f, 0.0313068f, 0.0585694f, 0.0989999f, 0.152568f, 0.215764f, 0.281321f, 0.339285f, 0.379331f, 0.393651f, 0.379331f, 0.339285f, 0.281321f, 0.215764f, 0.152568f, 0.0989999f, 0.0585694f, 0.0313069f, 0.0149251f, 0.00622422f, 0.00220061f, 0.000622433f, 0.00012207f, 
+    -0.000622433f, -0.00292963f, -0.00949457f, -0.0244132f, -0.0526863f, -0.0982355f, -0.160808f, -0.232983f, -0.299208f, -0.338515f, -0.331026f, -0.266154f, -0.148785f, -1.11759e-08f, 0.148785f, 0.266154f, 0.331026f, 0.338515f, 0.299208f, 0.232983f, 0.160808f, 0.0982355f, 0.0526863f, 0.0244132f, 0.00949457f, 0.00292963f, 0.000622433f, 
+    0.00220061f, 0.00949457f, 0.0279531f, 0.064562f, 0.123354f, 0.199704f, 0.276147f, 0.323994f, 0.313124f, 0.227396f, 0.0780228f, -0.0940989f, -0.231452f, -0.28386f, -0.231452f, -0.0940989f, 0.0780228f, 0.227396f, 0.313124f, 0.323994f, 0.276147f, 0.199704f, 0.123354f, 0.064562f, 0.0279531f, 0.00949457f, 0.00220061f, 
+    -0.00622422f, -0.0244132f, -0.064562f, -0.131829f, -0.217766f, -0.294702f, -0.321611f, -0.264043f, -0.119681f, 0.0677018f, 0.22068f, 0.26615f, 0.178539f, 0.0f, -0.178539f, -0.26615f, -0.22068f, -0.0677018f, 0.119681f, 0.264044f, 0.321611f, 0.294702f, 0.217766f, 0.131829f, 0.064562f, 0.0244132f, 0.00622422f, 
+    0.0149251f, 0.0526863f, 0.123354f, 0.217766f, 0.29954f, 0.314927f, 0.22513f, 0.0437213f, -0.152226f, -0.25763f, -0.207066f, -0.0277478f, 0.167524f, 0.251114f, 0.167524f, -0.0277478f, -0.207066f, -0.25763f, -0.152226f, 0.0437213f, 0.22513f, 0.314927f, 0.29954f, 0.217766f, 0.123354f, 0.0526863f, 0.0149251f, 
+    -0.0313068f, -0.0982355f, -0.199704f, -0.294702f, -0.314927f, -0.21092f, -0.00639388f, 0.191448f, 0.254592f, 0.134596f, -0.0833587f, -0.232816f, -0.195222f, 1.49012e-08f, 0.195222f, 0.232816f, 0.0833586f, -0.134596f, -0.254592f, -0.191448f, 0.0063939f, 0.21092f, 0.314927f, 0.294702f, 0.199704f, 0.0982355f, 0.0313068f, 
+    0.0585694f, 0.160808f, 0.276147f, 0.321611f, 0.22513f, 0.00639389f, -0.202374f, -0.245517f, -0.0845757f, 0.144788f, 0.238027f, 0.108889f, -0.121741f, -0.234626f, -0.121741f, 0.108889f, 0.238027f, 0.144788f, -0.0845756f, -0.245516f, -0.202374f, 0.0063939f, 0.22513f, 0.321611f, 0.276147f, 0.160808f, 0.0585694f, 
+    -0.0989999f, -0.232983f, -0.323994f, -0.264043f, -0.0437213f, 0.191448f, 0.245517f, 0.0673759f, -0.170045f, -0.225582f, -0.0416211f, 0.184055f, 0.20578f, 2.79397e-09f, -0.20578f, -0.184055f, 0.0416211f, 0.225582f, 0.170045f, -0.0673759f, -0.245517f, -0.191448f, 0.0437213f, 0.264044f, 0.323994f, 0.232983f, 0.0989999f, 
+    0.152568f, 0.299208f, 0.313124f, 0.119681f, -0.152226f, -0.254592f, -0.0845756f, 0.170045f, 0.219092f, 0.00742238f, -0.208181f, -0.164217f, 0.0834543f, 0.225172f, 0.0834543f, -0.164217f, -0.208181f, 0.00742239f, 0.219092f, 0.170045f, -0.0845757f, -0.254592f, -0.152226f, 0.119681f, 0.313124f, 0.299208f, 0.152568f, 
+    -0.215764f, -0.338515f, -0.227396f, 0.0677017f, 0.25763f, 0.134596f, -0.144788f, -0.225582f, -0.00742239f, 0.213842f, 0.138453f, -0.126674f, -0.212439f, -3.72529e-09f, 0.212439f, 0.126674f, -0.138453f, -0.213842f, 0.00742239f, 0.225582f, 0.144788f, -0.134596f, -0.25763f, -0.0677017f, 0.227396f, 0.338515f, 0.215764f, 
+    0.281321f, 0.331026f, 0.0780229f, -0.22068f, -0.207066f, 0.0833586f, 0.238027f, 0.0416211f, -0.208181f, -0.138453f, 0.139509f, 0.199167f, -0.0488799f, -0.219809f, -0.0488799f, 0.199167f, 0.139509f, -0.138453f, -0.208181f, 0.0416211f, 0.238027f, 0.0833586f, -0.207066f, -0.22068f, 0.0780229f, 0.331026f, 0.281321f, 
+    -0.339285f, -0.266154f, 0.0940989f, 0.26615f, 0.0277478f, -0.232816f, -0.108889f, 0.184055f, 0.164217f, -0.126674f, -0.199167f, 0.064445f, 0.216155f, -1.86265e-09f, -0.216155f, -0.0644449f, 0.199167f, 0.126674f, -0.164216f, -0.184055f, 0.108889f, 0.232816f, -0.0277478f, -0.26615f, -0.0940989f, 0.266154f, 0.339285f, 
+    0.379331f, 0.148785f, -0.231452f, -0.178538f, 0.167524f, 0.195222f, -0.121741f, -0.20578f, 0.0834543f, 0.212439f, -0.0488799f, -0.216155f, 0.0161112f, 0.217352f, 0.0161112f, -0.216155f, -0.0488799f, 0.212439f, 0.0834543f, -0.20578f, -0.121741f, 0.195222f, 0.167524f, -0.178538f, -0.231452f, 0.148785f, 0.379331f, 
+    -0.393651f, -3.72529e-09f, 0.28386f, -4.65661e-09f, -0.251114f, -5.58794e-09f, 0.234626f, 2.79397e-09f, -0.225172f, 3.72529e-09f, 0.219809f, 3.72529e-09f, -0.217352f, 0.0f, 0.217352f, -3.72529e-09f, -0.219809f, -7.45058e-09f, 0.225172f, -7.45058e-09f, -0.234626f, 7.45058e-09f, 0.251114f, 3.72529e-09f, -0.28386f, 3.72529e-09f, 0.393651f, 
+    0.379331f, -0.148785f, -0.231452f, 0.178539f, 0.167524f, -0.195222f, -0.121741f, 0.20578f, 0.0834543f, -0.212439f, -0.0488799f, 0.216155f, 0.0161112f, -0.217352f, 0.0161112f, 0.216155f, -0.0488799f, -0.212439f, 0.0834543f, 0.20578f, -0.121741f, -0.195222f, 0.167524f, 0.178538f, -0.231452f, -0.148785f, 0.379331f, 
+    -0.339285f, 0.266154f, 0.0940989f, -0.26615f, 0.0277478f, 0.232816f, -0.108889f, -0.184055f, 0.164217f, 0.126674f, -0.199167f, -0.0644449f, 0.216155f, -3.72529e-09f, -0.216155f, 0.0644449f, 0.199167f, -0.126674f, -0.164217f, 0.184055f, 0.108889f, -0.232816f, -0.0277478f, 0.26615f, -0.0940989f, -0.266154f, 0.339285f, 
+    0.281321f, -0.331026f, 0.0780229f, 0.22068f, -0.207066f, -0.0833586f, 0.238027f, -0.0416211f, -0.208181f, 0.138453f, 0.139509f, -0.199167f, -0.0488799f, 0.219809f, -0.0488799f, -0.199167f, 0.139509f, 0.138453f, -0.208181f, -0.0416211f, 0.238027f, -0.0833587f, -0.207066f, 0.22068f, 0.0780229f, -0.331026f, 0.281321f, 
+    -0.215764f, 0.338515f, -0.227396f, -0.0677018f, 0.25763f, -0.134596f, -0.144788f, 0.225582f, -0.00742239f, -0.213842f, 0.138453f, 0.126674f, -0.212439f, 0.0f, 0.212439f, -0.126674f, -0.138453f, 0.213842f, 0.00742239f, -0.225582f, 0.144788f, 0.134596f, -0.25763f, 0.0677018f, 0.227396f, -0.338515f, 0.215764f, 
+    0.152568f, -0.299208f, 0.313124f, -0.119681f, -0.152226f, 0.254592f, -0.0845757f, -0.170045f, 0.219092f, -0.00742239f, -0.208181f, 0.164217f, 0.0834543f, -0.225172f, 0.0834543f, 0.164217f, -0.208181f, -0.00742239f, 0.219092f, -0.170045f, -0.0845756f, 0.254592f, -0.152226f, -0.119681f, 0.313124f, -0.299208f, 0.152568f, 
+    -0.0989999f, 0.232984f, -0.323994f, 0.264044f, -0.0437213f, -0.191448f, 0.245517f, -0.0673759f, -0.170045f, 0.225582f, -0.0416211f, -0.184055f, 0.20578f, 3.72529e-09f, -0.20578f, 0.184055f, 0.0416211f, -0.225582f, 0.170045f, 0.0673759f, -0.245516f, 0.191448f, 0.0437213f, -0.264043f, 0.323994f, -0.232984f, 0.0989999f, 
+    0.0585694f, -0.160808f, 0.276147f, -0.321611f, 0.22513f, -0.00639389f, -0.202374f, 0.245516f, -0.0845756f, -0.144788f, 0.238027f, -0.108889f, -0.121741f, 0.234626f, -0.121741f, -0.108889f, 0.238027f, -0.144788f, -0.0845756f, 0.245516f, -0.202374f, -0.00639387f, 0.22513f, -0.321611f, 0.276147f, -0.160808f, 0.0585694f, 
+    -0.0313069f, 0.0982355f, -0.199704f, 0.294702f, -0.314927f, 0.21092f, -0.00639389f, -0.191448f, 0.254592f, -0.134596f, -0.0833586f, 0.232816f, -0.195222f, -3.72529e-09f, 0.195222f, -0.232816f, 0.0833586f, 0.134596f, -0.254592f, 0.191448f, 0.00639386f, -0.21092f, 0.314927f, -0.294702f, 0.199704f, -0.0982355f, 0.0313069f, 
+    0.0149251f, -0.0526863f, 0.123354f, -0.217766f, 0.29954f, -0.314927f, 0.22513f, -0.0437213f, -0.152226f, 0.25763f, -0.207066f, 0.0277478f, 0.167524f, -0.251114f, 0.167524f, 0.0277478f, -0.207066f, 0.25763f, -0.152226f, -0.0437213f, 0.22513f, -0.314927f, 0.29954f, -0.217766f, 0.123354f, -0.0526863f, 0.0149251f, 
+    -0.00622422f, 0.0244132f, -0.064562f, 0.131829f, -0.217766f, 0.294702f, -0.321611f, 0.264043f, -0.119681f, -0.0677018f, 0.22068f, -0.26615f, 0.178538f, 3.72529e-09f, -0.178538f, 0.26615f, -0.22068f, 0.0677018f, 0.119681f, -0.264043f, 0.321611f, -0.294702f, 0.217766f, -0.131829f, 0.064562f, -0.0244132f, 0.00622422f, 
+    0.00220061f, -0.00949457f, 0.0279531f, -0.064562f, 0.123354f, -0.199704f, 0.276147f, -0.323994f, 0.313124f, -0.227396f, 0.0780229f, 0.0940989f, -0.231452f, 0.28386f, -0.231452f, 0.0940989f, 0.0780229f, -0.227396f, 0.313124f, -0.323994f, 0.276147f, -0.199704f, 0.123354f, -0.064562f, 0.0279531f, -0.00949457f, 0.00220061f, 
+    -0.000622433f, 0.00292963f, -0.00949457f, 0.0244132f, -0.0526863f, 0.0982355f, -0.160808f, 0.232983f, -0.299208f, 0.338515f, -0.331026f, 0.266154f, -0.148785f, 3.72529e-09f, 0.148785f, -0.266154f, 0.331026f, -0.338515f, 0.299208f, -0.232984f, 0.160808f, -0.0982355f, 0.0526863f, -0.0244132f, 0.00949457f, -0.00292963f, 0.000622433f, 
+    0.00012207f, -0.000622433f, 0.00220061f, -0.00622422f, 0.0149251f, -0.0313068f, 0.0585694f, -0.0989999f, 0.152568f, -0.215764f, 0.281321f, -0.339285f, 0.379331f, -0.393651f, 0.379331f, -0.339285f, 0.281321f, -0.215764f, 0.152568f, -0.0989999f, 0.0585694f, -0.0313069f, 0.0149251f, -0.00622422f, 0.00220061f, -0.000622433f, 0.00012207f };
+
+static float wignerRef14[] = {  
+    6.10352e-05f, 0.000322965f, 0.00118664f, 0.00349334f, 0.00873327f, 0.0191335f, 0.0374611f, 0.0664111f, 0.107598f, 0.160397f, 0.221091f, 0.28282f, 0.336622f, 0.373448f, 0.386555f, 0.373448f, 0.336622f, 0.28282f, 0.221091f, 0.160397f, 0.107598f, 0.0664111f, 0.0374611f, 0.0191335f, 0.00873327f, 0.00349334f, 0.00118664f, 0.000322965f, 6.10352e-05f, 
+    -0.000322965f, -0.00158688f, -0.00538203f, -0.0145238f, -0.0330084f, -0.0650855f, -0.113271f, -0.175705f, -0.244006f, -0.303118f, -0.334255f, -0.320684f, -0.25446f, -0.141149f, -1.11759e-08f, 0.141149f, 0.25446f, 0.320684f, 0.334255f, 0.303118f, 0.244006f, 0.175705f, 0.113271f, 0.0650855f, 0.0330084f, 0.0145238f, 0.00538203f, 0.00158688f, 0.000322965f, 
+    0.00118664f, 0.00538203f, 0.016723f, 0.0409658f, 0.083548f, 0.145647f, 0.21965f, 0.286923f, 0.320979f, 0.296991f, 0.204686f, 0.0581856f, -0.103882f, -0.230493f, -0.278347f, -0.230493f, -0.103882f, 0.0581856f, 0.204686f, 0.296991f, 0.320979f, 0.286923f, 0.21965f, 0.145647f, 0.083548f, 0.0409658f, 0.016723f, 0.00538203f, 0.00118664f, 
+    -0.00349334f, -0.0145238f, -0.0409658f, -0.089961f, -0.161733f, -0.242688f, -0.303679f, -0.30863f, -0.233099f, -0.0840684f, 0.092704f, 0.227292f, 0.258769f, 0.169637f, -2.32831e-10f, -0.169637f, -0.258769f, -0.227292f, -0.092704f, 0.0840684f, 0.233099f, 0.30863f, 0.303679f, 0.242688f, 0.161733f, 0.089961f, 0.0409658f, 0.0145238f, 0.00349334f, 
+    0.00873327f, 0.0330084f, 0.083548f, 0.161733f, 0.249678f, 0.308204f, 0.291896f, 0.178679f, -0.00375964f, -0.178224f, -0.254934f, -0.187761f, -0.0117621f, 0.169636f, 0.245825f, 0.169636f, -0.0117621f, -0.187761f, -0.254934f, -0.178224f, -0.00375965f, 0.178679f, 0.291896f, 0.308205f, 0.249678f, 0.161733f, 0.083548f, 0.0330084f, 0.00873327f, 
+    -0.0191335f, -0.0650855f, -0.145647f, -0.242688f, -0.308204f, -0.284889f, -0.149123f, 0.0533815f, 0.216905f, 0.239437f, 0.101551f, -0.104645f, -0.231924f, -0.185825f, 1.11759e-08f, 0.185825f, 0.231924f, 0.104645f, -0.101551f, -0.239437f, -0.216905f, -0.0533815f, 0.149123f, 0.284889f, 0.308205f, 0.242688f, 0.145647f, 0.0650855f, 0.0191335f, 
+    0.0374611f, 0.113271f, 0.21965f, 0.303679f, 0.291896f, 0.149123f, -0.0690853f, -0.230235f, -0.218063f, -0.0376285f, 0.168568f, 0.228533f, 0.0899383f, -0.126547f, -0.22923f, -0.126547f, 0.0899384f, 0.228533f, 0.168568f, -0.0376284f, -0.218063f, -0.230235f, -0.0690853f, 0.149123f, 0.291896f, 0.303679f, 0.21965f, 0.113271f, 0.0374611f, 
+    -0.0664111f, -0.175705f, -0.286923f, -0.30863f, -0.178679f, 0.0533815f, 0.230235f, 0.209207f, 0.00553713f, -0.196333f, -0.204798f, -0.0114355f, 0.190554f, 0.1963f, -3.72529e-09f, -0.1963f, -0.190554f, 0.0114355f, 0.204798f, 0.196333f, -0.00553713f, -0.209207f, -0.230235f, -0.0533815f, 0.178679f, 0.30863f, 0.286923f, 0.175705f, 0.0664111f, 
+    0.107598f, 0.244006f, 0.320979f, 0.233099f, -0.00375963f, -0.216905f, -0.218063f, -0.00553713f, 0.203651f, 0.1875f, -0.0349867f, -0.213508f, -0.144914f, 0.0908689f, 0.219469f, 0.0908689f, -0.144914f, -0.213508f, -0.0349866f, 0.1875f, 0.203651f, -0.00553713f, -0.218063f, -0.216905f, -0.00375962f, 0.233099f, 0.320979f, 0.244006f, 0.107598f, 
+    -0.160397f, -0.303118f, -0.296991f, -0.0840684f, 0.178224f, 0.239437f, 0.0376285f, -0.196333f, -0.1875f, 0.0499207f, 0.218714f, 0.106531f, -0.140886f, -0.203188f, -1.39698e-08f, 0.203188f, 0.140886f, -0.106531f, -0.218714f, -0.0499207f, 0.1875f, 0.196333f, -0.0376285f, -0.239437f, -0.178224f, 0.0840684f, 0.296991f, 0.303118f, 0.160397f, 
+    0.221091f, 0.334255f, 0.204686f, -0.0927039f, -0.254934f, -0.101551f, 0.168568f, 0.204798f, -0.0349867f, -0.218714f, -0.0928836f, 0.161441f, 0.181932f, -0.0589631f, -0.213614f, -0.0589631f, 0.181932f, 0.161441f, -0.0928836f, -0.218714f, -0.0349866f, 0.204798f, 0.168568f, -0.101551f, -0.254934f, -0.0927039f, 0.204686f, 0.334255f, 0.221091f, 
+    -0.28282f, -0.320684f, -0.0581856f, 0.227292f, 0.187761f, -0.104645f, -0.228533f, -0.0114355f, 0.213508f, 0.106531f, -0.161441f, -0.173195f, 0.0862922f, 0.20742f, -5.58794e-09f, -0.20742f, -0.0862922f, 0.173195f, 0.161441f, -0.106531f, -0.213508f, 0.0114355f, 0.228533f, 0.104645f, -0.187761f, -0.227292f, 0.0581856f, 0.320684f, 0.28282f, 
+    0.336622f, 0.25446f, -0.103882f, -0.258769f, -0.0117621f, 0.231924f, 0.0899384f, -0.190554f, -0.144914f, 0.140886f, 0.181932f, -0.0862922f, -0.203402f, 0.0290446f, 0.210448f, 0.0290446f, -0.203402f, -0.0862922f, 0.181932f, 0.140886f, -0.144914f, -0.190554f, 0.0899384f, 0.231924f, -0.0117621f, -0.258769f, -0.103882f, 0.25446f, 0.336622f, 
+    -0.373448f, -0.141149f, 0.230493f, 0.169637f, -0.169636f, -0.185825f, 0.126547f, 0.1963f, -0.0908688f, -0.203188f, 0.0589631f, 0.20742f, -0.0290446f, -0.209444f, -1.86265e-09f, 0.209444f, 0.0290446f, -0.20742f, -0.0589631f, 0.203188f, 0.0908688f, -0.1963f, -0.126547f, 0.185825f, 0.169636f, -0.169637f, -0.230493f, 0.141149f, 0.373448f, 
+    0.386555f, 0.0f, -0.278347f, 6.51926e-09f, 0.245825f, 6.51926e-09f, -0.22923f, -9.31323e-10f, 0.219469f, -2.79397e-09f, -0.213614f, -1.86265e-09f, 0.210448f, -1.86265e-09f, -0.209443f, 3.72529e-09f, 0.210448f, -3.72529e-09f, -0.213614f, -3.72529e-09f, 0.219469f, -3.72529e-09f, -0.22923f, 3.72529e-09f, 0.245825f, -7.45058e-09f, -0.278347f, -3.72529e-09f, 0.386555f, 
+    -0.373448f, 0.141149f, 0.230493f, -0.169637f, -0.169636f, 0.185825f, 0.126547f, -0.1963f, -0.0908688f, 0.203188f, 0.0589631f, -0.20742f, -0.0290446f, 0.209444f, 0.0f, -0.209444f, 0.0290446f, 0.20742f, -0.0589631f, -0.203188f, 0.0908688f, 0.1963f, -0.126547f, -0.185825f, 0.169636f, 0.169637f, -0.230493f, -0.141149f, 0.373448f, 
+    0.336622f, -0.25446f, -0.103882f, 0.258769f, -0.0117621f, -0.231924f, 0.0899384f, 0.190554f, -0.144914f, -0.140886f, 0.181932f, 0.0862922f, -0.203402f, -0.0290446f, 0.210448f, -0.0290446f, -0.203402f, 0.0862922f, 0.181932f, -0.140886f, -0.144914f, 0.190554f, 0.0899384f, -0.231924f, -0.0117621f, 0.258769f, -0.103882f, -0.25446f, 0.336622f, 
+    -0.28282f, 0.320684f, -0.0581856f, -0.227292f, 0.187761f, 0.104645f, -0.228533f, 0.0114355f, 0.213508f, -0.106531f, -0.161441f, 0.173195f, 0.0862922f, -0.20742f, 3.72529e-09f, 0.20742f, -0.0862922f, -0.173195f, 0.161441f, 0.106531f, -0.213508f, -0.0114355f, 0.228533f, -0.104645f, -0.187761f, 0.227292f, 0.0581856f, -0.320684f, 0.28282f, 
+    0.221091f, -0.334255f, 0.204686f, 0.092704f, -0.254934f, 0.101551f, 0.168568f, -0.204798f, -0.0349866f, 0.218714f, -0.0928836f, -0.161441f, 0.181932f, 0.0589631f, -0.213614f, 0.0589631f, 0.181932f, -0.161441f, -0.0928836f, 0.218714f, -0.0349866f, -0.204798f, 0.168568f, 0.101551f, -0.254934f, 0.0927039f, 0.204686f, -0.334255f, 0.221091f, 
+    -0.160397f, 0.303118f, -0.296991f, 0.0840684f, 0.178224f, -0.239437f, 0.0376285f, 0.196333f, -0.1875f, -0.0499207f, 0.218714f, -0.106531f, -0.140886f, 0.203188f, 3.72529e-09f, -0.203188f, 0.140886f, 0.106531f, -0.218714f, 0.0499207f, 0.1875f, -0.196333f, -0.0376285f, 0.239437f, -0.178224f, -0.0840684f, 0.296991f, -0.303118f, 0.160397f, 
+    0.107598f, -0.244006f, 0.320979f, -0.233099f, -0.00375963f, 0.216905f, -0.218063f, 0.00553714f, 0.203651f, -0.1875f, -0.0349866f, 0.213508f, -0.144914f, -0.0908689f, 0.219469f, -0.0908688f, -0.144914f, 0.213508f, -0.0349866f, -0.1875f, 0.203651f, 0.00553713f, -0.218063f, 0.216905f, -0.00375964f, -0.233099f, 0.320979f, -0.244006f, 0.107598f, 
+    -0.0664111f, 0.175705f, -0.286923f, 0.30863f, -0.178679f, -0.0533815f, 0.230235f, -0.209207f, 0.00553713f, 0.196333f, -0.204798f, 0.0114355f, 0.190554f, -0.1963f, -3.72529e-09f, 0.1963f, -0.190554f, -0.0114355f, 0.204798f, -0.196333f, -0.00553712f, 0.209207f, -0.230235f, 0.0533815f, 0.178679f, -0.30863f, 0.286923f, -0.175706f, 0.0664111f, 
+    0.0374611f, -0.113271f, 0.21965f, -0.303679f, 0.291896f, -0.149123f, -0.0690853f, 0.230235f, -0.218063f, 0.0376284f, 0.168568f, -0.228533f, 0.0899384f, 0.126547f, -0.22923f, 0.126547f, 0.0899384f, -0.228533f, 0.168568f, 0.0376284f, -0.218063f, 0.230235f, -0.0690853f, -0.149123f, 0.291896f, -0.303679f, 0.21965f, -0.113271f, 0.0374611f, 
+    -0.0191335f, 0.0650855f, -0.145647f, 0.242688f, -0.308205f, 0.284889f, -0.149123f, -0.0533815f, 0.216905f, -0.239437f, 0.101551f, 0.104645f, -0.231924f, 0.185825f, 0.0f, -0.185825f, 0.231924f, -0.104645f, -0.101551f, 0.239437f, -0.216905f, 0.0533815f, 0.149123f, -0.284889f, 0.308205f, -0.242688f, 0.145647f, -0.0650855f, 0.0191335f, 
+    0.00873327f, -0.0330084f, 0.083548f, -0.161733f, 0.249678f, -0.308205f, 0.291896f, -0.178679f, -0.00375962f, 0.178224f, -0.254934f, 0.187761f, -0.0117621f, -0.169636f, 0.245825f, -0.169636f, -0.0117621f, 0.187761f, -0.254934f, 0.178224f, -0.00375964f, -0.178679f, 0.291896f, -0.308205f, 0.249678f, -0.161733f, 0.083548f, -0.0330084f, 0.00873327f, 
+    -0.00349334f, 0.0145238f, -0.0409658f, 0.089961f, -0.161733f, 0.242688f, -0.303679f, 0.30863f, -0.233099f, 0.0840684f, 0.0927039f, -0.227292f, 0.258769f, -0.169637f, 3.72529e-09f, 0.169637f, -0.258769f, 0.227292f, -0.0927039f, -0.0840684f, 0.233099f, -0.30863f, 0.303679f, -0.242688f, 0.161733f, -0.089961f, 0.0409658f, -0.0145238f, 0.00349334f, 
+    0.00118664f, -0.00538203f, 0.016723f, -0.0409658f, 0.083548f, -0.145647f, 0.21965f, -0.286923f, 0.320979f, -0.296991f, 0.204686f, -0.0581856f, -0.103882f, 0.230493f, -0.278347f, 0.230493f, -0.103882f, -0.0581856f, 0.204686f, -0.296991f, 0.320979f, -0.286923f, 0.21965f, -0.145647f, 0.083548f, -0.0409658f, 0.016723f, -0.00538203f, 0.00118664f, 
+    -0.000322965f, 0.00158688f, -0.00538203f, 0.0145238f, -0.0330084f, 0.0650855f, -0.113271f, 0.175705f, -0.244006f, 0.303118f, -0.334255f, 0.320684f, -0.25446f, 0.141149f, 0.0f, -0.141149f, 0.25446f, -0.320684f, 0.334255f, -0.303118f, 0.244006f, -0.175706f, 0.113271f, -0.0650855f, 0.0330084f, -0.0145238f, 0.00538203f, -0.00158688f, 0.000322965f, 
+    6.10352e-05f, -0.000322965f, 0.00118664f, -0.00349334f, 0.00873327f, -0.0191335f, 0.0374611f, -0.0664111f, 0.107598f, -0.160397f, 0.221091f, -0.28282f, 0.336622f, -0.373448f, 0.386555f, -0.373448f, 0.336622f, -0.28282f, 0.221091f, -0.160397f, 0.107598f, -0.0664111f, 0.0374611f, -0.0191335f, 0.00873327f, -0.00349334f, 0.00118664f, -0.000322965f, 6.10352e-05f };
+
+static float wignerRef15[] = {  
+    3.05176e-05f, 0.00016715f, 0.000636483f, 0.00194447f, 0.00505184f, 0.0115199f, 0.0235147f, 0.0435406f, 0.0738263f, 0.115425f, 0.167266f, 0.225541f, 0.283798f, 0.333944f, 0.367988f, 0.380056f, 0.367988f, 0.333944f, 0.283798f, 0.225541f, 0.167266f, 0.115425f, 0.0738263f, 0.0435406f, 0.0235147f, 0.0115199f, 0.00505184f, 0.00194447f, 0.000636483f, 0.00016715f, 3.05176e-05f, 
+    -0.00016715f, -0.000854476f, -0.00302131f, -0.00852016f, -0.0202912f, -0.0420643f, -0.0772766f, -0.127189f, -0.188701f, -0.252881f, -0.305381f, -0.32942f, -0.310883f, -0.243876f, -0.134369f, -7.45058e-09f, 0.134369f, 0.243876f, 0.310883f, 0.32942f, 0.305381f, 0.252881f, 0.188701f, 0.127189f, 0.0772766f, 0.0420643f, 0.0202912f, 0.00852016f, 0.00302131f, 0.000854476f, 0.00016715f, 
+    0.000636483f, 0.00302131f, 0.00985681f, 0.0254514f, 0.0549823f, 0.10218f, 0.165731f, 0.235896f, 0.29379f, 0.315443f, 0.280687f, 0.183832f, 0.0408205f, -0.112078f, -0.229364f, -0.27333f, -0.229364f, -0.112078f, 0.0408205f, 0.183832f, 0.280687f, 0.315443f, 0.29379f, 0.235896f, 0.165731f, 0.10218f, 0.0549823f, 0.0254514f, 0.00985681f, 0.00302131f, 0.000636483f, 
+    -0.00194447f, -0.00852016f, -0.0254514f, -0.0595671f, -0.115118f, -0.188021f, -0.261276f, -0.306124f, -0.291969f, -0.202882f, -0.0525004f, 0.113266f, 0.2316f, 0.251559f, 0.161703f, 0.0f, -0.161703f, -0.251559f, -0.2316f, -0.113266f, 0.0525004f, 0.202882f, 0.291969f, 0.306124f, 0.261276f, 0.188021f, 0.115118f, 0.0595671f, 0.0254514f, 0.00852016f, 0.00194447f, 
+    0.00505184f, 0.0202912f, 0.0549823f, 0.115118f, 0.195208f, 0.271731f, 0.30638f, 0.263268f, 0.134229f, -0.0439248f, -0.197021f, -0.249314f, -0.169713f, 0.00201716f, 0.171157f, 0.24105f, 0.171157f, 0.00201717f, -0.169713f, -0.249314f, -0.197021f, -0.0439248f, 0.134229f, 0.263268f, 0.30638f, 0.271731f, 0.195208f, 0.115118f, 0.0549823f, 0.0202912f, 0.00505184f, 
+    -0.0115199f, -0.0420643f, -0.10218f, -0.188021f, -0.271731f, -0.305272f, -0.24554f, -0.0904224f, 0.101299f, 0.231146f, 0.220649f, 0.0716921f, -0.121784f, -0.229992f, -0.177407f, 6.98492e-09f, 0.177407f, 0.229992f, 0.121784f, -0.0716921f, -0.220649f, -0.231146f, -0.101299f, 0.0904224f, 0.24554f, 0.305273f, 0.271731f, 0.188021f, 0.10218f, 0.0420643f, 0.0115199f, 
+    0.0235147f, 0.0772766f, 0.165731f, 0.261276f, 0.30638f, 0.24554f, 0.0756458f, -0.12696f, -0.240753f, -0.185583f, 0.00325587f, 0.185267f, 0.217654f, 0.0732367f, -0.130366f, -0.224403f, -0.130366f, 0.0732367f, 0.217654f, 0.185266f, 0.00325587f, -0.185583f, -0.240753f, -0.12696f, 0.0756459f, 0.24554f, 0.30638f, 0.261276f, 0.165731f, 0.0772766f, 0.0235147f, 
+    -0.0435406f, -0.127189f, -0.235896f, -0.306124f, -0.263268f, -0.0904224f, 0.12696f, 0.242162f, 0.164324f, -0.0465941f, -0.211003f, -0.18209f, 0.0143203f, 0.194718f, 0.187748f, 4.65661e-09f, -0.187748f, -0.194718f, -0.0143203f, 0.18209f, 0.211003f, 0.0465941f, -0.164324f, -0.242162f, -0.12696f, 0.0904224f, 0.263268f, 0.306124f, 0.235896f, 0.127189f, 0.0435406f, 
+    0.0738263f, 0.188701f, 0.29379f, 0.291969f, 0.134229f, -0.101299f, -0.240753f, -0.164324f, 0.0604483f, 0.218549f, 0.152442f, -0.069636f, -0.214307f, -0.127398f, 0.0968861f, 0.214422f, 0.0968861f, -0.127398f, -0.214307f, -0.069636f, 0.152442f, 0.218549f, 0.0604483f, -0.164324f, -0.240753f, -0.101299f, 0.134229f, 0.291969f, 0.29379f, 0.188701f, 0.0738263f, 
+    -0.115425f, -0.252881f, -0.315443f, -0.202882f, 0.0439248f, 0.231146f, 0.185583f, -0.0465941f, -0.218549f, -0.141462f, 0.0950697f, 0.215123f, 0.0775759f, -0.151491f, -0.194757f, -5.58794e-09f, 0.194757f, 0.151491f, -0.0775759f, -0.215123f, -0.0950697f, 0.141462f, 0.218549f, 0.0465941f, -0.185583f, -0.231146f, -0.0439248f, 0.202882f, 0.315443f, 0.252881f, 0.115425f, 
+    0.167266f, 0.305381f, 0.280687f, 0.0525004f, -0.197021f, -0.220649f, 0.00325587f, 0.211003f, 0.152442f, -0.0950697f, -0.213625f, -0.0511424f, 0.175973f, 0.165519f, -0.0671975f, -0.208204f, -0.0671975f, 0.165519f, 0.175973f, -0.0511424f, -0.213625f, -0.0950697f, 0.152442f, 0.211003f, 0.00325585f, -0.220649f, -0.197021f, 0.0525004f, 0.280687f, 0.305381f, 0.167266f, 
+    -0.225541f, -0.32942f, -0.183832f, 0.113266f, 0.249314f, 0.0716921f, -0.185266f, -0.18209f, 0.069636f, 0.215123f, 0.0511424f, -0.182592f, -0.146976f, 0.10337f, 0.199339f, -7.45058e-09f, -0.199339f, -0.10337f, 0.146976f, 0.182592f, -0.0511424f, -0.215123f, -0.0696359f, 0.18209f, 0.185266f, -0.0716921f, -0.249314f, -0.113266f, 0.183832f, 0.32942f, 0.225541f, 
+    0.283798f, 0.310883f, 0.0408205f, -0.2316f, -0.169713f, 0.121784f, 0.217654f, -0.0143203f, -0.214307f, -0.0775759f, 0.175973f, 0.146976f, -0.114455f, -0.189972f, 0.0396046f, 0.204517f, 0.0396046f, -0.189972f, -0.114455f, 0.146976f, 0.175973f, -0.0775759f, -0.214307f, -0.0143203f, 0.217654f, 0.121784f, -0.169713f, -0.2316f, 0.0408205f, 0.310883f, 0.283798f, 
+    -0.333944f, -0.243876f, 0.112078f, 0.251559f, -0.00201716f, -0.229992f, -0.0732367f, 0.194718f, 0.127398f, -0.151491f, -0.165519f, 0.10337f, 0.189972f, -0.0523605f, -0.201944f, 0.0f, 0.201944f, 0.0523605f, -0.189972f, -0.10337f, 0.165519f, 0.151491f, -0.127398f, -0.194718f, 0.0732367f, 0.229992f, 0.00201717f, -0.251559f, -0.112078f, 0.243876f, 0.333944f, 
+    0.367988f, 0.134369f, -0.229364f, -0.161703f, 0.171157f, 0.177407f, -0.130366f, -0.187748f, 0.0968861f, 0.194757f, -0.0671975f, -0.199339f, 0.0396046f, 0.201944f, -0.0130901f, -0.202791f, -0.0130901f, 0.201944f, 0.0396046f, -0.199339f, -0.0671975f, 0.194757f, 0.0968861f, -0.187748f, -0.130366f, 0.177407f, 0.171157f, -0.161703f, -0.229364f, 0.134369f, 0.367988f, 
+    -0.380056f, -3.72529e-09f, 0.27333f, -7.21775e-09f, -0.24105f, -6.51926e-09f, 0.224403f, 0.0f, -0.214422f, -9.31323e-10f, 0.208204f, -1.86265e-09f, -0.204517f, -3.72529e-09f, 0.202791f, -1.86265e-09f, -0.202791f, 5.58794e-09f, 0.204517f, 0.0f, -0.208204f, -3.72529e-09f, 0.214422f, -3.72529e-09f, -0.224403f, 0.0f, 0.24105f, -3.72529e-09f, -0.27333f, 0.0f, 0.380056f, 
+    0.367988f, -0.134369f, -0.229364f, 0.161703f, 0.171157f, -0.177407f, -0.130366f, 0.187748f, 0.0968861f, -0.194757f, -0.0671975f, 0.199339f, 0.0396046f, -0.201944f, -0.0130901f, 0.202791f, -0.0130901f, -0.201944f, 0.0396046f, 0.199339f, -0.0671975f, -0.194757f, 0.0968861f, 0.187748f, -0.130366f, -0.177407f, 0.171157f, 0.161703f, -0.229364f, -0.134369f, 0.367988f, 
+    -0.333944f, 0.243876f, 0.112078f, -0.251559f, -0.00201718f, 0.229992f, -0.0732367f, -0.194718f, 0.127398f, 0.151491f, -0.165519f, -0.10337f, 0.189972f, 0.0523605f, -0.201944f, 3.72529e-09f, 0.201944f, -0.0523605f, -0.189972f, 0.10337f, 0.165519f, -0.151491f, -0.127398f, 0.194718f, 0.0732367f, -0.229992f, 0.00201717f, 0.251559f, -0.112078f, -0.243876f, 0.333944f, 
+    0.283798f, -0.310883f, 0.0408205f, 0.2316f, -0.169713f, -0.121784f, 0.217654f, 0.0143203f, -0.214307f, 0.0775759f, 0.175973f, -0.146976f, -0.114455f, 0.189972f, 0.0396046f, -0.204517f, 0.0396046f, 0.189972f, -0.114455f, -0.146976f, 0.175973f, 0.0775759f, -0.214307f, 0.0143203f, 0.217654f, -0.121784f, -0.169713f, 0.2316f, 0.0408205f, -0.310883f, 0.283798f, 
+    -0.225541f, 0.32942f, -0.183832f, -0.113266f, 0.249314f, -0.0716921f, -0.185266f, 0.18209f, 0.069636f, -0.215123f, 0.0511424f, 0.182592f, -0.146976f, -0.10337f, 0.199339f, 3.72529e-09f, -0.199339f, 0.10337f, 0.146976f, -0.182592f, -0.0511424f, 0.215123f, -0.069636f, -0.18209f, 0.185266f, 0.0716921f, -0.249314f, 0.113266f, 0.183832f, -0.32942f, 0.225541f, 
+    0.167266f, -0.305381f, 0.280687f, -0.0525004f, -0.197021f, 0.220649f, 0.00325586f, -0.211003f, 0.152442f, 0.0950697f, -0.213625f, 0.0511424f, 0.175973f, -0.165519f, -0.0671975f, 0.208204f, -0.0671975f, -0.165519f, 0.175973f, 0.0511424f, -0.213625f, 0.0950697f, 0.152442f, -0.211003f, 0.00325587f, 0.220649f, -0.197021f, -0.0525004f, 0.280687f, -0.305381f, 0.167266f, 
+    -0.115425f, 0.252881f, -0.315443f, 0.202882f, 0.0439248f, -0.231146f, 0.185583f, 0.0465941f, -0.218548f, 0.141462f, 0.0950697f, -0.215123f, 0.0775759f, 0.151491f, -0.194757f, 0.0f, 0.194757f, -0.151491f, -0.0775759f, 0.215123f, -0.0950697f, -0.141462f, 0.218548f, -0.0465941f, -0.185583f, 0.231146f, -0.0439248f, -0.202882f, 0.315443f, -0.252881f, 0.115425f, 
+    0.0738263f, -0.188701f, 0.29379f, -0.291969f, 0.134229f, 0.101299f, -0.240753f, 0.164324f, 0.0604483f, -0.218548f, 0.152442f, 0.069636f, -0.214307f, 0.127398f, 0.0968861f, -0.214422f, 0.0968861f, 0.127398f, -0.214307f, 0.069636f, 0.152442f, -0.218549f, 0.0604483f, 0.164324f, -0.240753f, 0.101299f, 0.134229f, -0.291969f, 0.29379f, -0.188701f, 0.0738263f, 
+    -0.0435406f, 0.127189f, -0.235896f, 0.306124f, -0.263268f, 0.0904224f, 0.12696f, -0.242162f, 0.164324f, 0.0465941f, -0.211003f, 0.18209f, 0.0143203f, -0.194718f, 0.187748f, 0.0f, -0.187748f, 0.194718f, -0.0143203f, -0.18209f, 0.211003f, -0.0465941f, -0.164324f, 0.242162f, -0.12696f, -0.0904224f, 0.263268f, -0.306124f, 0.235896f, -0.127189f, 0.0435406f, 
+    0.0235147f, -0.0772766f, 0.165731f, -0.261276f, 0.30638f, -0.24554f, 0.0756458f, 0.12696f, -0.240753f, 0.185583f, 0.00325587f, -0.185266f, 0.217654f, -0.0732367f, -0.130366f, 0.224403f, -0.130366f, -0.0732367f, 0.217654f, -0.185266f, 0.00325588f, 0.185583f, -0.240753f, 0.12696f, 0.0756458f, -0.24554f, 0.30638f, -0.261276f, 0.165731f, -0.0772766f, 0.0235147f, 
+    -0.0115199f, 0.0420643f, -0.10218f, 0.188021f, -0.271731f, 0.305273f, -0.24554f, 0.0904224f, 0.101299f, -0.231146f, 0.220649f, -0.0716921f, -0.121784f, 0.229992f, -0.177407f, 0.0f, 0.177407f, -0.229992f, 0.121784f, 0.0716921f, -0.220649f, 0.231146f, -0.101299f, -0.0904224f, 0.24554f, -0.305273f, 0.271731f, -0.188021f, 0.10218f, -0.0420643f, 0.0115199f, 
+    0.00505184f, -0.0202912f, 0.0549823f, -0.115118f, 0.195207f, -0.271731f, 0.30638f, -0.263268f, 0.134229f, 0.0439248f, -0.197021f, 0.249314f, -0.169713f, -0.00201718f, 0.171157f, -0.24105f, 0.171157f, -0.00201717f, -0.169713f, 0.249314f, -0.197021f, 0.0439248f, 0.134229f, -0.263268f, 0.30638f, -0.271731f, 0.195208f, -0.115118f, 0.0549823f, -0.0202912f, 0.00505184f, 
+    -0.00194447f, 0.00852016f, -0.0254514f, 0.0595671f, -0.115118f, 0.188021f, -0.261276f, 0.306124f, -0.291969f, 0.202882f, -0.0525004f, -0.113266f, 0.2316f, -0.251559f, 0.161703f, 0.0f, -0.161703f, 0.251559f, -0.2316f, 0.113266f, 0.0525004f, -0.202882f, 0.291969f, -0.306124f, 0.261276f, -0.188021f, 0.115118f, -0.0595671f, 0.0254514f, -0.00852016f, 0.00194447f, 
+    0.000636483f, -0.00302131f, 0.00985681f, -0.0254514f, 0.0549823f, -0.10218f, 0.165731f, -0.235896f, 0.29379f, -0.315443f, 0.280687f, -0.183832f, 0.0408205f, 0.112078f, -0.229364f, 0.27333f, -0.229364f, 0.112078f, 0.0408205f, -0.183832f, 0.280687f, -0.315443f, 0.29379f, -0.235896f, 0.165731f, -0.10218f, 0.0549823f, -0.0254514f, 0.00985681f, -0.00302131f, 0.000636483f, 
+    -0.00016715f, 0.000854476f, -0.00302131f, 0.00852016f, -0.0202912f, 0.0420643f, -0.0772766f, 0.127189f, -0.188701f, 0.252881f, -0.305381f, 0.32942f, -0.310883f, 0.243876f, -0.134369f, 0.0f, 0.134369f, -0.243876f, 0.310883f, -0.32942f, 0.305381f, -0.252881f, 0.188701f, -0.127189f, 0.0772766f, -0.0420643f, 0.0202912f, -0.00852016f, 0.00302131f, -0.000854476f, 0.00016715f, 
+    3.05176e-05f, -0.00016715f, 0.000636483f, -0.00194447f, 0.00505184f, -0.0115199f, 0.0235147f, -0.0435406f, 0.0738263f, -0.115425f, 0.167266f, -0.225541f, 0.283798f, -0.333944f, 0.367988f, -0.380056f, 0.367988f, -0.333944f, 0.283798f, -0.225541f, 0.167266f, -0.115425f, 0.0738263f, -0.0435406f, 0.0235147f, -0.0115199f, 0.00505184f, -0.00194447f, 0.000636483f, -0.00016715f, 3.05176e-05f };
+    
+#endif //VIGRA_WIGNER_MATRIX_REFERENCE_HXX
diff --git a/test/fourier/CMakeLists.txt b/test/fourier/CMakeLists.txt
new file mode 100644
index 0000000..3857311
--- /dev/null
+++ b/test/fourier/CMakeLists.txt
@@ -0,0 +1,9 @@
+if(FFTW3_FOUND)
+    INCLUDE_DIRECTORIES(${FFTW3_INCLUDE_DIR})
+
+    VIGRA_ADD_TEST(test_fourier test.cxx LIBRARIES vigraimpex ${FFTW3_LIBRARIES})
+
+    VIGRA_COPY_TEST_DATA(ghouse.gif filter.xv gaborresult.xv)
+else()
+    MESSAGE(STATUS "** WARNING: test_fourier will not be executed")
+endif()
diff --git a/test/fourier/filter.xv b/test/fourier/filter.xv
new file mode 100644
index 0000000..edd6aa2
Binary files /dev/null and b/test/fourier/filter.xv differ
diff --git a/test/fourier/gaborresult.xv b/test/fourier/gaborresult.xv
new file mode 100644
index 0000000..bedd89a
Binary files /dev/null and b/test/fourier/gaborresult.xv differ
diff --git a/test/fourier/ghouse.gif b/test/fourier/ghouse.gif
new file mode 100644
index 0000000..f81e6a5
Binary files /dev/null and b/test/fourier/ghouse.gif differ
diff --git a/test/fourier/test.cxx b/test/fourier/test.cxx
new file mode 100755
index 0000000..e94b06f
--- /dev/null
+++ b/test/fourier/test.cxx
@@ -0,0 +1,886 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include "vigra/unittest.hxx"
+#include <stdlib.h>
+#include <algorithm>
+#include <functional>
+#include <vigra/stdimage.hxx>
+#include <vigra/stdimagefunctions.hxx>
+#include <vigra/functorexpression.hxx>
+#include <vigra/fftw3.hxx>
+#include <vigra/impex.hxx>
+#include <vigra/inspectimage.hxx>
+#include <vigra/gaborfilter.hxx>
+#include <vigra/multi_fft.hxx>
+#include <vigra/multi_pointoperators.hxx>
+#include <vigra/convolution.hxx>
+#include "test.hxx"
+
+using namespace std;
+using namespace vigra;
+using namespace vigra::functor;
+
+struct Compare1
+{
+    double s;
+
+    typedef FFTWComplexImage::value_type value_type;
+    typedef FFTWComplexImage::value_type result_type;
+
+    Compare1(double is)
+    : s(is)
+    {}
+
+    result_type operator()(value_type v1, value_type v2) const
+    { return v1 - v2/s; }
+};
+
+struct FFTWComplexTest
+{
+    FFTWComplex<> clx0, clx1, clx2, clx3;
+
+    template <class VECTOR>
+    void printVector(VECTOR const & v)
+    {
+        std::cerr << "(";
+        for(int i=0; i<v.size(); ++i)
+            std::cerr << v[i] << ", ";
+        std::cerr << ")\n";
+    }
+
+    FFTWComplexTest()
+    : clx0(), clx1(2.0), clx2(0.0, -2.0), clx3(2.0, -2.0)
+    {}
+
+    void testConstruction()
+    {
+        shouldEqual(clx0.re() , 0.0);
+        shouldEqual(clx0.im() , 0.0);
+        shouldEqual(clx1.re() , 2.0);
+        shouldEqual(clx1.im() , 0.0);
+        shouldEqual(clx2.re() , 0.0);
+        shouldEqual(clx2.im() , -2.0);
+        shouldEqual(clx3.re() , 2.0);
+        shouldEqual(real(clx3) , 2.0);
+        shouldEqual(clx3.im() , -2.0);
+        shouldEqual(imag(clx3) , -2.0);
+        shouldEqual(clx0[0] , 0.0);
+        shouldEqual(clx0[1] , 0.0);
+        shouldEqual(clx1[0] , 2.0);
+        shouldEqual(clx1[1] , 0.0);
+        shouldEqual(clx2[0] , 0.0);
+        shouldEqual(clx2[1] , -2.0);
+        shouldEqual(clx3[0] , 2.0);
+        shouldEqual(clx3[1] , -2.0);
+    }
+
+    void testComparison()
+    {
+        should(clx0 == FFTWComplex<>(0.0, 0.0));
+        should(clx1 == FFTWComplex<>(2.0, 0.0));
+        should(clx2 == FFTWComplex<>(0.0, -2.0));
+        should(clx3 == FFTWComplex<>(2.0, -2.0));
+        should(clx0 != clx1);
+        should(clx0 != clx2);
+        should(clx1 != clx2);
+        should(clx1 != clx3);
+    }
+
+    void testArithmetic()
+    {
+        shouldEqual(abs(clx0) , 0.0);
+        shouldEqual(abs(clx1) , 2.0);
+        shouldEqual(abs(clx2) , 2.0);
+        shouldEqual(abs(clx3) , sqrt(8.0));
+        should(conj(clx3) == FFTWComplex<>(2.0, 2.0));
+
+        shouldEqual(clx1.phase() , 0.0);
+        shouldEqual(arg(clx1) , 0.0);
+        shouldEqualTolerance(arg(clx3), -0.25*M_PI, 1e-16);
+        shouldEqual(sin(clx2.phase()) , -1.0);
+        shouldEqualTolerance(sin(clx3.phase()), -sqrt(2.0)/2.0, 1.0e-7);
+
+        should(FFTWComplex<>(2.0, -2.0) == clx1 + clx2);
+
+        should(clx0 == clx1 - clx1);
+        should(clx0 == clx2 - clx2);
+        should(FFTWComplex<>(2.0, 2.0) == clx1 - clx2);
+
+        should(2.0*clx1 == FFTWComplex<>(4.0, 0.0));
+        should(2.0*clx2 == FFTWComplex<>(0.0, -4.0));
+        should(clx1*clx2 == FFTWComplex<>(0.0, -4.0));
+        should(clx3*conj(clx3) == clx3.squaredMagnitude());
+
+        should(clx1/2.0 == FFTWComplex<>(1.0, 0.0));
+        should(clx2/2.0 == FFTWComplex<>(0.0, -1.0));
+        should(clx2/clx1 == FFTWComplex<>(0.0, -1.0));
+        should(clx3*conj(clx3) == clx3.squaredMagnitude());
+
+        std::complex<FFTWComplex<>::value_type> c(clx3.re(), clx3.im()),
+                                                   c1(clx1.re(), clx1.im());
+
+        shouldEqual(cos(clx3), FFTWComplex<>(cos(c)));
+        shouldEqual(cosh(clx3), FFTWComplex<>(cosh(c)));
+        shouldEqual(exp(clx3), FFTWComplex<>(exp(c)));
+        shouldEqual(log(clx3), FFTWComplex<>(log(c)));
+        shouldEqual(log10(clx3), FFTWComplex<>(log10(c)));
+        shouldEqual(sin(clx3), FFTWComplex<>(sin(c)));
+        shouldEqual(sinh(clx3), FFTWComplex<>(sinh(c)));
+        shouldEqual(sqrt(clx3), FFTWComplex<>(sqrt(c)));
+        shouldEqual(tan(clx3), FFTWComplex<>(tan(c)));
+        shouldEqual(tanh(clx3), FFTWComplex<>(tanh(c)));
+        shouldEqual(pow(clx3, 2), FFTWComplex<>(pow(c, 2)));
+        shouldEqual(pow(clx3, 2.0), FFTWComplex<>(pow(c, 2.0)));
+        shouldEqual(pow(clx3, clx1), FFTWComplex<>(pow(c, c1)));
+        shouldEqual(pow(2.0, clx3), FFTWComplex<>(pow(2.0, c)));
+    }
+
+    void testAccessor()
+    {
+        FFTWComplexImage img(2,2);
+        img = clx2;
+        img(0,0) = clx3;
+        FFTWComplexImage::Iterator i = img.upperLeft();
+
+        FFTWComplexImage::Accessor get = img.accessor();
+        FFTWRealAccessor<> real;
+        FFTWImaginaryAccessor<> imag;
+        FFTWSquaredMagnitudeAccessor<> smag;
+        FFTWMagnitudeAccessor<> mag;
+        FFTWPhaseAccessor<> phase;
+        FFTWWriteRealAccessor<> writeReal;
+
+        should(get(i) == clx3);
+        should(get(i, Diff2D(1,1)) == clx2);
+        should(real(i) == 2.0);
+        should(real(i, Diff2D(1,1)) == 0.0);
+        should(imag(i) == -2.0);
+        should(imag(i, Diff2D(1,1)) == -2.0);
+        shouldEqual(smag(i) , 8.0);
+        shouldEqual(smag(i, Diff2D(1,1)) , 4.0);
+        shouldEqual(mag(i) , sqrt(8.0));
+        shouldEqual(mag(i, Diff2D(1,1)) , 2.0);
+        shouldEqualTolerance(sin(phase(i)), -sqrt(2.0)/2.0, 1.0e-7);
+        shouldEqual(sin(phase(i, Diff2D(1,1))), -1.0);
+
+        writeReal.set(2.0, i);
+        writeReal.set(2.0, i, Diff2D(1,1));
+        should(get(i) == clx1);
+        should(get(i, Diff2D(1,1)) == clx1);
+    }
+
+    void testForwardBackwardTrans()
+    {
+        const int w=256, h=256;
+
+        FFTWComplexImage in(w, h);
+        for (int y=0; y<in.height(); y++)
+            for (int x=0; x<in.width(); x++)
+            {
+                in(x,y)= rand()/(double)RAND_MAX;
+            }
+
+        FFTWComplexImage out(w, h);
+        
+        fourierTransform(srcImageRange(in), destImage(out));
+        fourierTransformInverse(srcImageRange(out), destImage(out));
+
+        FindAverage<FFTWComplex<>::value_type> average;
+        inspectImage(srcImageRange(out, FFTWImaginaryAccessor<>()), average);
+
+        shouldEqualTolerance(average(), 0.0, 1e-14);
+
+        combineTwoImages(srcImageRange(in), srcImage(out), destImage(out),
+                         Compare1((double)w*h));
+
+        average = FindAverage<FFTWMagnitudeAccessor<>::value_type>();
+        inspectImage(srcImageRange(out, FFTWMagnitudeAccessor<>()), average);
+
+        shouldEqualTolerance(average(), 0.0, 1e-14);
+
+        for (int y=0; y<in.height(); y++)
+            for (int x=0; x<in.width(); x++)
+            {
+                in(x,y)[1]= rand()/(double)RAND_MAX;
+            }
+
+        fourierTransform(srcImageRange(in), destImage(out));
+        fourierTransformInverse(srcImageRange(out), destImage(out));
+
+        combineTwoImages(srcImageRange(in), srcImage(out), destImage(out),
+                         Compare1((double)w*h));
+
+        FindAverage<FFTWComplex<> > caverage;
+        inspectImage(srcImageRange(out), caverage);
+
+        shouldEqualTolerance(caverage().magnitude(), 0.0, 1e-14);
+    }
+
+    void testRearrangeQuadrants()
+    {
+        double t4[] = { 0, 1, 2, 2,
+                        1, 1, 2, 2,
+                        3, 3, 4, 4,
+                        3, 3, 4, 4};
+        double t4res[] = { 4, 4, 3, 3,
+                           4, 4, 3, 3,
+                           2, 2, 0, 1,
+                           2, 2, 1, 1};
+
+        FFTWComplexImage in4(4,4), out4(4,4);
+        copy(t4, t4+16, in4.begin());
+        moveDCToCenter(srcImageRange(in4), destImage(out4));
+        moveDCToUpperLeft(srcImageRange(out4), destImage(in4));
+        for(int i=0; i<16; ++i)
+        {
+            should(out4.begin()[i] == t4res[i]);
+            should(in4.begin()[i] == t4[i]);
+        }
+
+        double t5[] = { 0, 1, 1, 2, 2,
+                        1, 1, 1, 2, 2,
+                        1, 1, 1, 2, 2,
+                        3, 3, 3, 4, 4,
+                        3, 3, 3, 4, 4};
+        double t5res[] = { 4, 4, 3, 3, 3,
+                           4, 4, 3, 3, 3,
+                           2, 2, 0, 1, 1,
+                           2, 2, 1, 1, 1,
+                           2, 2, 1, 1, 1};
+
+        FFTWComplexImage in5(5,5), out5(5,5);
+        copy(t5, t5+25, in5.begin());
+        moveDCToCenter(srcImageRange(in5), destImage(out5));
+        moveDCToUpperLeft(srcImageRange(out5), destImage(in5));
+        for(int i=0; i<25; ++i)
+        {
+            should(out5.begin()[i] == t5res[i]);
+            should(in5.begin()[i] == t5[i]);
+        }
+    }
+};
+
+struct MultiFFTTest
+{
+    typedef double R;
+    typedef FFTWComplex<R> C;
+    typedef MultiArray<2, R, FFTWAllocator<R> > DArray2;
+    typedef MultiArray<2, C, FFTWAllocator<C> > CArray2;
+    typedef MultiArrayShape<2>::type Shape2;
+    typedef MultiArray<3, R, FFTWAllocator<R> > DArray3;
+    typedef MultiArray<3, C, FFTWAllocator<C> > CArray3;
+    typedef MultiArrayShape<3>::type Shape3;
+
+    void testFFTShift()
+    {
+        Shape3 s(5,5,5);
+        MultiArray<3, unsigned int> a(s), ref(s), iref(s);
+
+        for(int z=0; z<5; ++z)
+        {
+            for(int y=0; y<5; ++y)
+            {
+                for(int x=0; x<5; ++x)
+                {
+                    unsigned int v = ((z > 2) ? 4 : 0) + ((y > 2) ? 2 : 0) + ((x > 2) ? 1 : 0);
+                    a(x,y,z) = iref(x,y,z) = v;
+                    v = ((z < 2) ? 4 : 0) + ((y < 2) ? 2 : 0) + ((x < 2) ? 1 : 0);
+                    ref(x,y,z) = v;
+                }
+            }
+        }
+
+        moveDCToCenter(a);
+        should(a == ref);
+        moveDCToUpperLeft(a);
+        should(a == iref);
+
+        MultiArrayView<3, unsigned int> b = a.subarray(Shape3(1,1,1), s);
+        moveDCToCenter(b);
+        should(b == ref.subarray(Shape3(0,0,0), Shape3(4,4,4)));
+        moveDCToUpperLeft(b);
+        should(b == iref.subarray(Shape3(1,1,1), s));
+        moveDCToCenter(b);
+        moveDCToCenter(b);
+        should(b == iref.subarray(Shape3(1,1,1), s));
+
+        MultiArrayShape<1>::type s1_e(10), s1_5(5), s1_6(6);
+        MultiArray<1, double> e1(s1_e), k1_5(s1_5), k1_6(s1_6);
+
+        for(int k=0; k<k1_5.size(); ++k)
+            k1_5(k) = k+1;
+        detail::fftEmbedKernel(k1_5, e1);
+
+        double k1_5ref[] = {3, 4, 5, 0, 0, 0, 0, 0, 1, 2};
+        shouldEqualSequence(e1.data(), e1.data()+e1.size(), k1_5ref);
+
+        for(int k=0; k<k1_6.size(); ++k)
+            k1_6(k) = k+1;
+        detail::fftEmbedKernel(k1_6, e1);
+
+        double k1_6ref[] = {4, 5, 6, 0, 0, 0, 0, 1, 2, 3};
+        shouldEqualSequence(e1.data(), e1.data()+e1.size(), k1_6ref);
+
+        detail::fftEmbedArray(k1_5, e1);
+        double a1_5ref[] = {3, 2, 1, 2, 3, 4, 5, 4, 3, 2 };
+        shouldEqualSequence(e1.data(), e1.data()+e1.size(), a1_5ref);
+
+        detail::fftEmbedArray(k1_6, e1);
+        double a1_6ref[] = {3, 2, 1, 2, 3, 4, 5, 6, 5, 4 };
+        shouldEqualSequence(e1.data(), e1.data()+e1.size(), a1_6ref);
+
+        MultiArrayShape<2>::type s2_e(8, 8), s2_4(4, 4), s2_5(5, 5);
+        MultiArray<2, double> e2(s2_e), k2_4(s2_4), k2_5(s2_5);
+
+        for(int k=0; k<k2_4.size(); ++k)
+            k2_4(k) = k+1;
+        detail::fftEmbedKernel(k2_4, e2);
+
+        double k2_4ref[] = {11,12, 0, 0, 0, 0, 9,10,
+                            15,16, 0, 0, 0, 0,13,14,
+                             0, 0, 0, 0, 0, 0, 0, 0,
+                             0, 0, 0, 0, 0, 0, 0, 0,
+                             0, 0, 0, 0, 0, 0, 0, 0,
+                             0, 0, 0, 0, 0, 0, 0, 0,
+                             3, 4, 0, 0, 0, 0, 1, 2,
+                             7, 8, 0, 0, 0, 0, 5, 6};
+        shouldEqualSequence(e2.data(), e2.data()+e2.size(), k2_4ref);
+
+        for(int k=0; k<k2_5.size(); ++k)
+            k2_5(k) = k+1;
+        detail::fftEmbedKernel(k2_5, e2);
+
+        double k2_5ref[] = {13,14,15, 0, 0, 0,11,12,
+                            18,19,20, 0, 0, 0,16,17,
+                            23,24,25, 0, 0, 0,21,22,
+                             0, 0, 0, 0, 0, 0, 0, 0,
+                             0, 0, 0, 0, 0, 0, 0, 0,
+                             0, 0, 0, 0, 0, 0, 0, 0,
+                             3, 4, 5, 0, 0, 0, 1, 2,
+                             8, 9,10, 0, 0, 0, 6, 7};
+        shouldEqualSequence(e2.data(), e2.data()+e2.size(), k2_5ref);
+
+        detail::fftEmbedArray(k2_4, e2);
+        double a2_4ref[] = {11,10, 9,10,11,12,11,10,
+                             7, 6, 5, 6, 7, 8, 7, 6,
+                             3, 2, 1, 2, 3, 4, 3, 2,
+                             7, 6, 5, 6, 7, 8, 7, 6,
+                            11,10, 9,10,11,12,11,10,
+                            15,14,13,14,15,16,15,14,
+                            11,10, 9,10,11,12,11,10,
+                             7, 6, 5, 6, 7, 8, 7, 6};
+        shouldEqualSequence(e2.data(), e2.data()+e2.size(), a2_4ref);
+
+        detail::fftEmbedArray(k2_5, e2);
+        double a2_5ref[] = { 7, 6, 7, 8, 9,10, 9, 8,
+                             2, 1, 2, 3, 4, 5, 4, 3,
+                             7, 6, 7, 8, 9,10, 9, 8,
+                            12,11,12,13,14,15,14,13,
+                            17,16,17,18,19,20,19,18,
+                            22,21,22,23,24,25,24,23,
+                            17,16,17,18,19,20,19,18,
+                            12,11,12,13,14,15,14,13};
+        shouldEqualSequence(e2.data(), e2.data()+e2.size(), a2_5ref);
+    }
+
+    void testFFT2D()
+    {
+        Shape2 s(256, 256);
+
+        FFTWComplexImage in(s[0], s[1]);
+        for (int y=0; y<in.height(); y++)
+            for (int x=0; x<in.width(); x++)
+            {
+                in(x,y)= rand()/(double)RAND_MAX;
+            }
+
+        FFTWComplexImage out(in.size());
+        CArray2 aout(s);
+
+        fourierTransform(srcImageRange(in), destImage(out));
+        fourierTransform(MultiArrayView<2, C>(s, const_cast<C*>(in.data())), 
+                         aout);
+
+        shouldEqualSequence(aout.data(), aout.data()+aout.size(), out.data());
+
+        DArray2 rin(s);
+        copyImage(srcImageRange(in, FFTWRealAccessor<>()), destImage(rin));
+
+        fourierTransform(rin, aout);
+        shouldEqualSequence(aout.data(), aout.data()+aout.size(), out.data());
+    }
+
+    void testFFT3D()
+    {
+        Shape3 s(32, 24, 16);
+        CArray3 r(s), ir(s), irr(s);
+
+        fourierTransform(MultiArrayView<3, double>(s, f3data), r);
+
+        DArray3 re(s);
+        copyMultiArray(srcMultiArrayRange(r, FFTWRealAccessor<>()), destMultiArray(re));
+        shouldEqualSequenceTolerance(re.data(), re.data()+re.size(), f3ref, 1e-10);
+
+        FindMinMax<double> minmax;
+        inspectMultiArray(srcMultiArrayRange(r, FFTWImaginaryAccessor<>()), minmax);
+        shouldEqualTolerance(minmax.min, 0.0, 1e-10);
+        shouldEqualTolerance(minmax.max, 0.0, 1e-10);
+
+        fourierTransformInverse(r, ir);
+
+        copyMultiArray(srcMultiArrayRange(ir, FFTWRealAccessor<>()), destMultiArray(re));
+        shouldEqualSequenceTolerance(re.data(), re.data()+re.size(), f3data, 1e-10);
+
+        inspectMultiArray(srcMultiArrayRange(ir, FFTWImaginaryAccessor<>()), minmax);
+        shouldEqualTolerance(minmax.min, 0.0, 1e-10);
+        shouldEqualTolerance(minmax.max, 0.0, 1e-10);
+    }
+
+    void testPadding()
+    {
+        shouldEqual(0, detail::FFTWPaddingSize<0>::find(0));
+        shouldEqual(1, detail::FFTWPaddingSize<0>::find(1));
+        shouldEqual(3, detail::FFTWPaddingSize<0>::find(3));
+        shouldEqual(256, detail::FFTWPaddingSize<0>::find(255));
+        shouldEqual(256, detail::FFTWPaddingSize<0>::find(256));
+        shouldEqual(260, detail::FFTWPaddingSize<0>::find(257));
+        shouldEqual(0, detail::FFTWPaddingSize<0>::findEven(0));
+        shouldEqual(2, detail::FFTWPaddingSize<0>::findEven(1));
+        shouldEqual(4, detail::FFTWPaddingSize<0>::findEven(3));
+        shouldEqual(256, detail::FFTWPaddingSize<0>::findEven(255));
+        shouldEqual(256, detail::FFTWPaddingSize<0>::findEven(256));
+        shouldEqual(260, detail::FFTWPaddingSize<0>::findEven(257));
+
+        Shape3 s(113, 256, 257);
+        shouldEqual(Shape3(117, 256, 260), fftwBestPaddedShape(s));
+        shouldEqual(Shape3(120, 256, 260), fftwBestPaddedShapeR2C(s));
+    }
+
+    void testConvolveFFT()
+    {
+        typedef MultiArrayView<2, double> MV;
+        ImageImportInfo info("ghouse.gif");
+        Shape2 s(info.width(), info.height());
+        DArray2 in(s), out(s), ref(s), out2(s), ref2(s);
+        importImage(info, destImage(in));
+
+        double scale = 2.0;
+        gaussianSmoothing(srcImageRange(in), destImage(ref), scale);
+        gaussianSmoothing(srcImageRange(in), destImage(ref2), 2.0*scale);
+
+        Kernel2D<double> gauss;
+        gauss.initGaussian(scale);
+        MV kernel(Shape2(gauss.width(), gauss.height()), &gauss[gauss.upperLeft()]);
+        convolveFFT(in, kernel, out);
+
+        shouldEqualSequenceTolerance(out.data(), out.data()+out.size(),
+                                     ref.data(), 1e-14);
+        
+        Kernel2D<double> gauss2;
+        gauss2.initGaussian(2.0*scale);
+        MV kernel2(Shape2(gauss2.width(), gauss2.height()), &gauss2[gauss2.upperLeft()]);
+
+        MV kernels[] = { kernel, kernel2 };
+        MV outs[] = { out, out2 };
+        convolveFFTMany(in, kernels, kernels+2, outs);
+
+        shouldEqualSequenceTolerance(out.data(), out.data()+out.size(),
+                                     ref.data(), 1e-14);
+        shouldEqualSequenceTolerance(out2.data(), out2.data()+out2.size(),
+                                     ref2.data(), 1e-14);
+    }
+
+    void testConvolveFFTComplex()
+    {
+        typedef MultiArrayView<2, double> MV;
+        typedef MultiArrayView<2, FFTWComplex<double> > MVC;
+
+        ImageImportInfo info("ghouse.gif");
+        Shape2 s(info.width(), info.height());
+        DArray2 in(s), out(s), ref(s), ref2(s);
+        importImage(info, destImage(in));
+
+        double scale = 2.0;
+        Kernel2D<double> gauss, gauss2;
+        gauss.initGaussian(scale);
+        gauss2.initGaussian(2.0*scale);
+
+        convolveImage(srcImageRange(in), destImage(ref), kernel2d(gauss));
+        convolveImage(srcImageRange(in), destImage(ref2), kernel2d(gauss2));
+
+        MV kernel(Shape2(gauss.width(), gauss.height()), &gauss[gauss.upperLeft()]);
+        MV kernel2(Shape2(gauss2.width(), gauss2.height()), &gauss2[gauss2.upperLeft()]);
+
+        //test complex double 2D convolution with spatial domain kernels
+        
+        MultiArray<2, FFTWComplex<double> > inc(in);
+        MultiArray<2, FFTWComplex<double> > outc(inc.shape()), outc2(inc.shape());
+        MultiArray<2, FFTWComplex<double> > kernelc(kernel), kernelc2(kernel2);
+        convolveFFTComplex(inc, kernelc, outc, false);
+
+        copyMultiArray(srcMultiArrayRange(outc, FFTWRealAccessor<double>()), destMultiArray(out));
+
+        shouldEqualSequenceTolerance(out.data(), out.data()+out.size(),
+                                     ref.data(), 1e-14);
+
+        outc.init(0.0);
+        
+        MVC kernels[] = { kernelc, kernelc2 };
+        MVC outs[] = { outc, outc2 };
+        convolveFFTComplexMany(inc, kernels, kernels+2, outs, false);
+
+        copyMultiArray(srcMultiArrayRange(outc, FFTWRealAccessor<double>()), destMultiArray(out));
+        shouldEqualSequenceTolerance(out.data(), out.data()+out.size(),
+                                     ref.data(), 1e-14);
+        copyMultiArray(srcMultiArrayRange(outc2, FFTWRealAccessor<double>()), destMultiArray(out));
+        shouldEqualSequenceTolerance(out.data(), out.data()+out.size(),
+                                     ref2.data(), 1e-14);
+
+        //test complex double 2D convolution with Fourier domain kernels
+        
+        gauss.setBorderTreatment(BORDER_TREATMENT_WRAP);
+        gauss2.setBorderTreatment(BORDER_TREATMENT_WRAP);
+
+        convolveImage(srcImageRange(in), destImage(ref), kernel2d(gauss));
+        convolveImage(srcImageRange(in), destImage(ref2), kernel2d(gauss2));
+
+        MultiArray<2, FFTWComplex<double> > kernelf(in.shape()), kernelf2(in.shape());
+
+        detail::fftEmbedKernel(kernelc, kernelf);
+        fourierTransform(kernelf, kernelf);
+        moveDCToCenter(kernelf);
+
+        detail::fftEmbedKernel(kernelc2, kernelf2);
+        fourierTransform(kernelf2, kernelf2);
+        moveDCToCenter(kernelf2);
+
+        outc.init(0.0);
+        convolveFFTComplex(inc, kernelf, outc, true);
+
+        copyMultiArray(srcMultiArrayRange(outc, FFTWRealAccessor<double>()), destMultiArray(out));
+
+        shouldEqualSequenceTolerance(out.data(), out.data()+out.size(),
+                                     ref.data(), 1e-14);
+
+        outc.init(0.0);
+        outc2.init(0.0);
+        
+        MVC kernelsf[] = { kernelf, kernelf2 };
+        convolveFFTComplexMany(inc, kernelsf, kernelsf+2, outs, true);
+
+        copyMultiArray(srcMultiArrayRange(outc, FFTWRealAccessor<double>()), destMultiArray(out));
+        shouldEqualSequenceTolerance(out.data(), out.data()+out.size(),
+                                     ref.data(), 1e-14);
+        copyMultiArray(srcMultiArrayRange(outc2, FFTWRealAccessor<double>()), destMultiArray(out));
+        shouldEqualSequenceTolerance(out.data(), out.data()+out.size(),
+                                     ref2.data(), 1e-14);
+#if 0
+        // test complex float 3D convolution
+        // compile-only test, currently disabled because it requires libfftwf
+                
+        Shape3 sc(100,100,100);
+        vigra::MultiArray<3, FFTWComplex<float> > incf(sc);
+        vigra::MultiArray<3, FFTWComplex<float> > outcf(sc);
+        vigra::MultiArray<3, FFTWComplex<float> > kernelcf(Shape3(10,10,10));
+        convolveFFTComplex(incf, kernelcf, outcf, false);
+#endif
+    }
+
+    void testConvolveFourierKernel()
+    {
+        ImageImportInfo info("ghouse.gif");
+        Shape2 s(info.width(), info.height());
+        DArray2 in(s), out(s), out2(s), out3(s), out4(s), ref(s), tmp(s);
+        importImage(info, destImage(in));
+
+        double scale = 2.0;
+        gaussianSmoothing(srcImageRange(in), destImage(ref), scale);
+
+        Shape2 paddedShape = fftwBestPaddedShapeR2C(s + Shape2(16)),
+               kernelShape(paddedShape);
+        kernelShape[0] = kernelShape[0] / 2 + 1;
+        Shape2 center = div(kernelShape, Shape2::value_type(2));
+        center[0] = 0;
+
+        CArray2 kernel(kernelShape);
+
+        for(int y=0; y<kernelShape[1]; ++y)
+        {
+            for(int x=0; x<kernelShape[0]; ++x)
+            {
+                double xx = 2.0 * M_PI * (x - center[0]) / paddedShape[0];
+                double yy = 2.0 * M_PI * (y - center[1]) / paddedShape[1];
+                double r2 = sq(xx) + sq(yy);
+                kernel(x,y) = std::exp(-0.5 * sq(scale) * r2);
+            }
+        }
+        convolveFFT(in, kernel, out);
+
+        shouldEqualSequenceTolerance(out.data(), out.data()+out.size(),
+                                     ref.data(), 1e-2);
+
+        Kernel1D<double> gauss, grad;
+        gauss.initGaussian(scale);
+        grad.initGaussianDerivative(scale, 1);
+
+        separableConvolveX(srcImageRange(in), destImage(tmp), kernel1d(grad));
+        separableConvolveY(srcImageRange(tmp), destImage(ref), kernel1d(gauss));
+
+        CArray2 kernel2(kernelShape);
+        for(int y=0; y<kernelShape[1]; ++y)
+        {
+            for(int x=0; x<kernelShape[0]; ++x)
+            {
+                double xx = 2.0 * M_PI * (x - center[0]) / paddedShape[0];
+                double yy = 2.0 * M_PI * (y - center[1]) / paddedShape[1];
+                double r2 = sq(xx) + sq(yy);
+                kernel2(x,y) = C(0, xx*std::exp(-0.5 * sq(scale) * r2));
+            }
+        }
+        convolveFFT(in, kernel2, out2);
+
+        ref -= out2;
+
+        FindMinMax<double> minmax;
+        FindAverage<double> average;
+        inspectImage(srcImageRange(ref), minmax);
+        inspectImage(srcImageRange(ref), average);
+        
+        should(std::max(minmax.max, -minmax.min) < 0.2);
+        should(average.average() < 0.001);
+
+        MultiArrayView<2, C> kernels[] = { kernel, kernel2 };
+        MultiArrayView<2, R> outs[] = { out3, out4 };
+        convolveFFTMany(in, kernels, kernels+2, outs);
+
+        shouldEqualSequenceTolerance(out.data(), out.data()+out.size(),
+                                     out3.data(), 1e-15);
+        shouldEqualSequenceTolerance(out2.data(), out2.data()+out2.size(),
+                                     out4.data(), 1e-15);
+    }
+};
+
+struct FFTWTestSuite
+: public test_suite
+{
+
+    FFTWTestSuite()
+    : test_suite("FFTWTest")
+    {
+
+        add( testCase(&FFTWComplexTest::testConstruction));
+        add( testCase(&FFTWComplexTest::testComparison));
+        add( testCase(&FFTWComplexTest::testArithmetic));
+        add( testCase(&FFTWComplexTest::testAccessor));
+        add( testCase(&FFTWComplexTest::testForwardBackwardTrans));
+        add( testCase(&FFTWComplexTest::testRearrangeQuadrants));
+
+        add( testCase(&MultiFFTTest::testFFTShift));
+        add( testCase(&MultiFFTTest::testFFT2D));
+        add( testCase(&MultiFFTTest::testFFT3D));
+        add( testCase(&MultiFFTTest::testPadding));
+        add( testCase(&MultiFFTTest::testConvolveFFT));
+        add( testCase(&MultiFFTTest::testConvolveFFTComplex));
+        add( testCase(&MultiFFTTest::testConvolveFourierKernel));
+    }
+};
+
+int initializing;
+
+struct CompareFunctor
+{
+    double sumDifference_;
+
+    CompareFunctor(): sumDifference_(0) {}
+
+    void operator()(const fftw_real &a, const fftw_real &b)
+        { sumDifference_+= abs(a-b); }
+
+    double operator()()
+        { return sumDifference_; }
+};
+
+struct GaborTests
+{
+    typedef MultiArrayView<2, fftw_real> RView;
+
+    ImageImportInfo info;
+    int w, h;
+    BasicImage<fftw_real> image;
+
+    GaborTests()
+        : info("ghouse.gif"),
+          w(info.width()), h(info.height()),
+          image(w, h)
+    {
+        importImage(info, destImage(image));
+    }
+
+    template<class Iterator, class Accessor>
+    void checkImage(triple<Iterator, Iterator, Accessor> src, const char *filename)
+    {
+        if (initializing)
+        {
+            exportImage(src, ImageExportInfo(filename));
+            cout << "wrote " << filename << endl;
+        }
+        else
+        {
+            ImageImportInfo info(filename);
+            FImage image(info.width(), info.height());
+            importImage(info, destImage(image));
+
+            CompareFunctor cmp;
+
+            inspectTwoImages(src, srcImage(image), cmp);
+            cout << "difference to " << filename << ": " << cmp() << endl;
+            shouldEqualTolerance(cmp(), 0.0, 1e-4);
+        }
+    }
+
+    void testImages()
+    {
+        BasicImage<fftw_real> filter(w, h);
+        int directionCount= 8;
+        int dir= 1, scale= 1;
+        double angle = dir * M_PI / directionCount;
+        double centerFrequency = 3.0/8.0 / VIGRA_CSTD::pow(2.0,scale);
+
+        createGaborFilter(RView(filter),
+                          angle, centerFrequency,
+                          angularGaborSigma(directionCount, centerFrequency),
+                          radialGaborSigma(centerFrequency));
+
+        checkImage(srcImageRange(filter), "filter.xv");
+
+        cout << "Applying filter...\n";
+        FFTWComplexImage result(w, h);
+        applyFourierFilter(srcImageRange(image), srcImage(filter), destImage(result));
+        checkImage(srcImageRange(result, FFTWMagnitudeAccessor<>()), "gaborresult.xv");
+
+        BasicImage<fftw_real> realPart(w, h);
+        applyFourierFilter(srcImageRange(image), srcImage(filter), destImage(realPart));
+
+        CompareFunctor cmp;
+        inspectTwoImages(srcImageRange(result, FFTWRealAccessor<>()),
+                         srcImage(realPart), cmp);
+        cout << "difference between real parts: " << cmp() << endl;
+        shouldEqualTolerance(cmp(), 0.0, 1e-4);
+
+        cout << "testing vector results..\n";
+        FVector2Image vectorResult(w,h);
+        applyFourierFilter(srcImageRange(image), srcImage(filter),
+                           destImage(vectorResult));
+        CompareFunctor iCmp;
+        inspectTwoImages(srcImageRange(result, FFTWImaginaryAccessor<>()),
+                         srcImage(vectorResult,
+                                  VectorComponentAccessor<FVector2Image::PixelType>(1)),
+                         iCmp);
+        cout << "difference between imaginary parts: " << iCmp() << endl;
+        shouldEqualTolerance(cmp(), 0.0, 1e-4);
+
+        cout << "applying on ROI...\n";
+        BasicImage<fftw_real> bigImage(w+20, h+20);
+        BasicImage<fftw_real>::Iterator bigUL= bigImage.upperLeft() + Diff2D(5, 5);
+        copyImage(srcImageRange(image), destIter(bigUL));
+        applyFourierFilter(srcIterRange(bigUL, bigUL + Diff2D(w, h)),
+                           srcImage(filter), destImage(result));
+        checkImage(srcImageRange(result, FFTWMagnitudeAccessor<>()), "gaborresult.xv");
+#if 0
+        cout << "Creating plans with measurement...\n";
+        fftwnd_plan forwardPlan=
+            fftw2d_create_plan(h, w, FFTW_FORWARD, FFTW_MEASURE );
+        fftwnd_plan backwardPlan=
+            fftw2d_create_plan(h, w, FFTW_BACKWARD, FFTW_MEASURE | FFTW_IN_PLACE);
+
+        cout << "Applying again...\n";
+        applyFourierFilter(srcImageRange(image), srcImage(filter), destImage(result),
+                           forwardPlan, backwardPlan);
+
+        checkImage(srcImageRange(result, FFTWMagnitudeAccessor()), "gaborresult.xv");
+#endif
+    }
+
+    void testFamily()
+    {
+        cout << "testing 8x2 GaborFilterFamily...\n";
+        GaborFilterFamily<FImage> filters(w, h, 8, 2);
+        ImageArray<FFTWComplexImage> results((unsigned int)filters.size(), filters.imageSize());
+        applyFourierFilterFamily(srcImageRange(image), filters, results);
+        checkImage(srcImageRange(results[filters.filterIndex(1,1)], FFTWMagnitudeAccessor<>()),
+                   "gaborresult.xv");
+
+        ImageArray<FImage> realParts((unsigned int)filters.size(), filters.imageSize());
+        applyFourierFilterFamily(srcImageRange(image), filters, realParts);
+
+        CompareFunctor cmp;
+        inspectTwoImages(srcImageRange(results[3], FFTWRealAccessor<>()),
+                         srcImage(realParts[3]), cmp);
+        cout << "difference between real parts: " << cmp() << endl;
+        shouldEqualTolerance(cmp(), 0.0, 1e-4);
+    }
+};
+
+struct GaborTestSuite
+: public test_suite
+{
+    GaborTestSuite()
+    : test_suite("FFTWWithGaborTest")
+    {
+        add(testCase(&GaborTests::testImages));
+        add(testCase(&GaborTests::testFamily));
+    }
+};
+
+int main(int argc, char **argv)
+{
+    initializing= argc>1 && std::string(argv[1]) == "init"; // global variable,
+    // initializing means: don't compare with image files but create them
+
+    FFTWTestSuite fftwTest;
+
+    int failed = fftwTest.run(testsToBeExecuted(argc, argv));
+
+    std::cout << fftwTest.report() << std::endl;
+
+    GaborTestSuite gaborTest;
+
+    failed = failed || gaborTest.run(testsToBeExecuted(argc, argv));
+
+    std::cout << gaborTest.report() << std::endl;
+
+    return (failed != 0);
+}
diff --git a/test/fourier/test.hxx b/test/fourier/test.hxx
new file mode 100644
index 0000000..7793e5b
--- /dev/null
+++ b/test/fourier/test.hxx
@@ -0,0 +1,771 @@
+static double f3data[12288] = {
+-0.03651002889111, -0.03718508419910, 0.03522641326574, -0.02876889046885, -0.02548955050991, 0.04384574828821, -0.02788397290880, -0.03401426025387, 0.04169802746791, -0.04899968532023, -0.04939808301205, -0.01352102709593, -0.00866167202085, 0.02847526258331, -0.03653013164974, 0.04222968115101, -0.00710107751649, 0.04222968115101, -0.03653013164974, 0.02847526258331, -0.00866167202085, -0.01352102709593, -0.04939808301205, -0.04899968532023, 0.04169802746791, -0.03401426025387, -0.027 [...]
+0.01453221375941, 0.02849879584822, -0.00338379798127, 0.04144419729370, 0.04384574828821, -0.02111691650473, 0.04703493050962, 0.04741800568147, -0.00153126021194, 0.03510685742783, 0.01610767548006, 0.05259259692296, -0.04211210676874, -0.05728294659133, -0.01598181558280, 0.00801021034064, 0.05323681630826, 0.00801021034064, -0.01598181558280, -0.05728294659133, -0.04211210676874, 0.05259259692296, 0.01610767548006, 0.03510685742783, -0.00153126021194, 0.04741800568147, 0.047034930509 [...]
+-0.03825317999564, -0.03939946075725, 0.03697036111778, -0.03115444796200, -0.02788397290880, 0.04703493050962, -0.03079225925144, -0.03755053092747, 0.04507008450281, -0.05398199531481, -0.05430453818238, -0.01598181558280, -0.00864631825412, 0.03277758616341, -0.04023894554545, 0.04683219028095, -0.00905987177209, 0.04683219028095, -0.04023894554545, 0.03277758616341, -0.00864631825412, -0.01598181558280, -0.05430453818238, -0.05398199531481, 0.04507008450281, -0.03755053092747, -0.030 [...]
+-0.03759634244848, -0.04135242996492, 0.03447279299858, -0.03645408668750, -0.03401426025387, 0.04741800568147, -0.03755053092747, -0.04403132364326, 0.04222968115101, -0.05728294659133, -0.05403298716581, -0.02546580226758, 0.00027003849811, 0.04244418660272, -0.03484669808203, 0.04273731697500, -0.01933288371895, 0.04273731697500, -0.03484669808203, 0.04244418660272, 0.00027003849811, -0.02546580226758, -0.05403298716581, -0.05728294659133, 0.04222968115101, -0.04403132364326, -0.03755 [...]
+-0.00238974137531, 0.01485220652451, 0.01595838913427, 0.03644296273535, 0.04169802746791, -0.00153126021194, 0.04507008450281, 0.04222968115101, 0.02351130918583, 0.01700752911701, -0.00905987177209, 0.06377948953705, -0.06399728423775, -0.06161913050027, -0.04628401868063, 0.03895560265498, 0.07051434913474, 0.03895560265498, -0.04628401868063, -0.06161913050027, -0.06399728423775, 0.06377948953705, -0.00905987177209, 0.01700752911701, 0.02351130918583, 0.04222968115101, 0.045070084502 [...]
+-0.02511329203000, -0.03797145192049, 0.01512570665415, -0.04746872842254, -0.04899968532023, 0.03510685742783, -0.05398199531481, -0.05728294659133, 0.01700752911701, -0.05260385601595, -0.03484669808203, -0.05761715944068, 0.03895560265498, 0.06969057246245, 0.00155790816347, 0.00898729611428, -0.05782350471105, 0.00898729611428, 0.00155790816347, 0.06969057246245, 0.03895560265498, -0.05761715944068, -0.03484669808203, -0.05260385601595, 0.01700752911701, -0.05728294659133, -0.0539819 [...]
+-0.00905031863291, -0.02613601062284, -0.00434559103408, -0.04499172586632, -0.04939808301205, 0.01610767548006, -0.05430453818238, -0.05403298716581, -0.00905987177209, -0.03484669808203, -0.00879307760295, -0.07081173873106, 0.06316887617837, 0.07536267012088, 0.03433801412888, -0.02442011476440, -0.07714535201411, -0.02442011476440, 0.03433801412888, 0.07536267012088, 0.06316887617837, -0.07081173873106, -0.00879307760295, -0.03484669808203, -0.00905987177209, -0.05403298716581, -0.05 [...]
+-0.04200139277956, -0.03645408668750, 0.04703493050962, -0.01909407501789, -0.01352102709593, 0.05259259692296, -0.01598181558280, -0.02546580226758, 0.06377948953705, -0.05761715944068, -0.07081173873106, 0.00898729611428, -0.04040858119196, 0.01371110078340, -0.07419862922226, 0.07992564670887, 0.02127053092509, 0.07992564670887, -0.07419862922226, 0.01371110078340, -0.04040858119196, 0.00898729611428, -0.07081173873106, -0.05761715944068, 0.06377948953705, -0.02546580226758, -0.015981 [...]
+0.03501492614272, 0.02264757303314, -0.04548829345483, -0.00153126021194, -0.00866167202085, -0.04211210676874, -0.00864631825412, 0.00027003849811, -0.06399728423775, 0.03895560265498, 0.06316887617837, -0.04040858119196, 0.06720841455530, 0.02127053092509, 0.08701085516538, -0.08813390430467, -0.05605729667571, -0.08813390430467, 0.08701085516538, 0.02127053092509, 0.06720841455530, -0.04040858119196, 0.06316887617837, 0.03895560265498, -0.06399728423775, 0.00027003849811, -0.008646318 [...]
+0.04384574828821, 0.04364554753736, -0.04499172586632, 0.03250874444113, 0.02847526258331, -0.05728294659133, 0.03277758616341, 0.04244418660272, -0.06161913050027, 0.06969057246245, 0.07536267012088, 0.01371110078340, 0.02127053092509, -0.03929438261949, 0.06656064247057, -0.07614567822515, 0.00344457002262, -0.07614567822515, 0.06656064247057, -0.03929438261949, 0.02127053092509, 0.01371110078340, 0.07536267012088, 0.06969057246245, -0.06161913050027, 0.04244418660272, 0.03277758616341 [...]
+0.01595838913427, -0.00222561996695, -0.03079225925144, -0.02912466965015, -0.03653013164974, -0.01598181558280, -0.04023894554545, -0.03484669808203, -0.04628401868063, 0.00155790816347, 0.03433801412888, -0.07419862922226, 0.08701085516538, 0.06656064247057, 0.08094445627940, -0.07494530013047, -0.09172320431048, -0.07494530013047, 0.08094445627940, 0.06656064247057, 0.08701085516538, -0.07419862922226, 0.03433801412888, 0.00155790816347, -0.04628401868063, -0.03484669808203, -0.040238 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+-0.04198822986865, -0.03401426025387, 0.04945313461415, -0.01352102709593, -0.00710107751649, 0.05323681630826, -0.00905987177209, -0.01933288371895, 0.07051434913474, -0.05782350471105, -0.07714535201411, 0.02127053092509, -0.05605729667571, 0.00344457002262, -0.09172320431048, 0.09733017222613, 0.03779154935440, 0.09733017222613, -0.09172320431048, 0.00344457002262, -0.05605729667571, 0.02127053092509, -0.07714535201411, -0.05782350471105, 0.07051434913474, -0.01933288371895, -0.009059 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+0.01595838913427, -0.00222561996695, -0.03079225925144, -0.02912466965015, -0.03653013164974, -0.01598181558280, -0.04023894554545, -0.03484669808203, -0.04628401868063, 0.00155790816347, 0.03433801412888, -0.07419862922226, 0.08701085516538, 0.06656064247057, 0.08094445627940, -0.07494530013047, -0.09172320431048, -0.07494530013047, 0.08094445627940, 0.06656064247057, 0.08701085516538, -0.07419862922226, 0.03433801412888, 0.00155790816347, -0.04628401868063, -0.03484669808203, -0.040238 [...]
+0.04384574828821, 0.04364554753736, -0.04499172586632, 0.03250874444113, 0.02847526258331, -0.05728294659133, 0.03277758616341, 0.04244418660272, -0.06161913050027, 0.06969057246245, 0.07536267012088, 0.01371110078340, 0.02127053092509, -0.03929438261949, 0.06656064247057, -0.07614567822515, 0.00344457002262, -0.07614567822515, 0.06656064247057, -0.03929438261949, 0.02127053092509, 0.01371110078340, 0.07536267012088, 0.06969057246245, -0.06161913050027, 0.04244418660272, 0.03277758616341 [...]
+0.03501492614272, 0.02264757303314, -0.04548829345483, -0.00153126021194, -0.00866167202085, -0.04211210676874, -0.00864631825412, 0.00027003849811, -0.06399728423775, 0.03895560265498, 0.06316887617837, -0.04040858119196, 0.06720841455530, 0.02127053092509, 0.08701085516538, -0.08813390430467, -0.05605729667571, -0.08813390430467, 0.08701085516538, 0.02127053092509, 0.06720841455530, -0.04040858119196, 0.06316887617837, 0.03895560265498, -0.06399728423775, 0.00027003849811, -0.008646318 [...]
+-0.04200139277956, -0.03645408668750, 0.04703493050962, -0.01909407501789, -0.01352102709593, 0.05259259692296, -0.01598181558280, -0.02546580226758, 0.06377948953705, -0.05761715944068, -0.07081173873106, 0.00898729611428, -0.04040858119196, 0.01371110078340, -0.07419862922226, 0.07992564670887, 0.02127053092509, 0.07992564670887, -0.07419862922226, 0.01371110078340, -0.04040858119196, 0.00898729611428, -0.07081173873106, -0.05761715944068, 0.06377948953705, -0.02546580226758, -0.015981 [...]
+-0.00905031863291, -0.02613601062284, -0.00434559103408, -0.04499172586632, -0.04939808301205, 0.01610767548006, -0.05430453818238, -0.05403298716581, -0.00905987177209, -0.03484669808203, -0.00879307760295, -0.07081173873106, 0.06316887617837, 0.07536267012088, 0.03433801412888, -0.02442011476440, -0.07714535201411, -0.02442011476440, 0.03433801412888, 0.07536267012088, 0.06316887617837, -0.07081173873106, -0.00879307760295, -0.03484669808203, -0.00905987177209, -0.05403298716581, -0.05 [...]
+-0.02511329203000, -0.03797145192049, 0.01512570665415, -0.04746872842254, -0.04899968532023, 0.03510685742783, -0.05398199531481, -0.05728294659133, 0.01700752911701, -0.05260385601595, -0.03484669808203, -0.05761715944068, 0.03895560265498, 0.06969057246245, 0.00155790816347, 0.00898729611428, -0.05782350471105, 0.00898729611428, 0.00155790816347, 0.06969057246245, 0.03895560265498, -0.05761715944068, -0.03484669808203, -0.05260385601595, 0.01700752911701, -0.05728294659133, -0.0539819 [...]
+-0.00238974137531, 0.01485220652451, 0.01595838913427, 0.03644296273535, 0.04169802746791, -0.00153126021194, 0.04507008450281, 0.04222968115101, 0.02351130918583, 0.01700752911701, -0.00905987177209, 0.06377948953705, -0.06399728423775, -0.06161913050027, -0.04628401868063, 0.03895560265498, 0.07051434913474, 0.03895560265498, -0.04628401868063, -0.06161913050027, -0.06399728423775, 0.06377948953705, -0.00905987177209, 0.01700752911701, 0.02351130918583, 0.04222968115101, 0.045070084502 [...]
+-0.03759634244848, -0.04135242996492, 0.03447279299858, -0.03645408668750, -0.03401426025387, 0.04741800568147, -0.03755053092747, -0.04403132364326, 0.04222968115101, -0.05728294659133, -0.05403298716581, -0.02546580226758, 0.00027003849811, 0.04244418660272, -0.03484669808203, 0.04273731697500, -0.01933288371895, 0.04273731697500, -0.03484669808203, 0.04244418660272, 0.00027003849811, -0.02546580226758, -0.05403298716581, -0.05728294659133, 0.04222968115101, -0.04403132364326, -0.03755 [...]
+-0.03825317999564, -0.03939946075725, 0.03697036111778, -0.03115444796200, -0.02788397290880, 0.04703493050962, -0.03079225925144, -0.03755053092747, 0.04507008450281, -0.05398199531481, -0.05430453818238, -0.01598181558280, -0.00864631825412, 0.03277758616341, -0.04023894554545, 0.04683219028095, -0.00905987177209, 0.04683219028095, -0.04023894554545, 0.03277758616341, -0.00864631825412, -0.01598181558280, -0.05430453818238, -0.05398199531481, 0.04507008450281, -0.03755053092747, -0.030 [...]
+0.01453221375941, 0.02849879584822, -0.00338379798127, 0.04144419729370, 0.04384574828821, -0.02111691650473, 0.04703493050962, 0.04741800568147, -0.00153126021194, 0.03510685742783, 0.01610767548006, 0.05259259692296, -0.04211210676874, -0.05728294659133, -0.01598181558280, 0.00801021034064, 0.05323681630826, 0.00801021034064, -0.01598181558280, -0.05728294659133, -0.04211210676874, 0.05259259692296, 0.01610767548006, 0.03510685742783, -0.00153126021194, 0.04741800568147, 0.047034930509 [...]
+0.03232593614224, 0.02255847953252, -0.03939946075725, 0.00282925577496, -0.00283618587179, -0.03645408668750, -0.00222561996695, 0.00493640288370, -0.04899968532023, 0.03250874444113, 0.04745915084934, -0.02333152061039, 0.04222968115101, 0.00864062075235, 0.05634488400998, -0.05728294659133, -0.03144564133374, -0.05728294659133, 0.05634488400998, 0.00864062075235, 0.04222968115101, -0.02333152061039, 0.04745915084934, 0.03250874444113, -0.04899968532023, 0.00493640288370, -0.0022256199 [...]
+-0.03446030853185, -0.04008674845418, 0.02965188168129, -0.03814396416671, -0.03645408668750, 0.04341150826710, -0.03980537034422, -0.04513877691637, 0.03510685742783, -0.05349976932781, -0.04716218793354, -0.03045828585214, 0.00801021034064, 0.04496452881899, -0.02516948075949, 0.03296691756242, -0.02546580226758, 0.03296691756242, -0.02516948075949, 0.04496452881899, 0.00801021034064, -0.03045828585214, -0.04716218793354, -0.05349976932781, 0.03510685742783, -0.04513877691637, -0.03980 [...]
+0.03438945519666, 0.02443728561702, -0.04200139277956, 0.00380202623900, -0.00222561996695, -0.03980537034422, -0.00153126021194, 0.00629983820314, -0.05398199531481, 0.03669569988478, 0.05323681630826, -0.02516948075949, 0.04683219028095, 0.00869067734621, 0.06377948953705, -0.06514516365773, -0.03484669808203, -0.06514516365773, 0.06377948953705, 0.00869067734621, 0.04683219028095, -0.02516948075949, 0.05323681630826, 0.03669569988478, -0.05398199531481, 0.00629983820314, -0.0015312602 [...]
+0.03785607654408, 0.02991156721912, -0.04410886072389, 0.01076407940667, 0.00493640288370, -0.04513877691637, 0.00629983820314, 0.01466865762037, -0.05728294659133, 0.04496452881899, 0.05946062873198, -0.01764835261303, 0.04273731697500, -0.00086468661469, 0.06584304685785, -0.06883698723352, -0.02803496562843, -0.06883698723352, 0.06584304685785, -0.00086468661469, 0.04273731697500, -0.01764835261303, 0.05946062873198, 0.04496452881899, -0.05728294659133, 0.01466865762037, 0.00629983820 [...]
+-0.02511329203000, -0.03797145192049, 0.01512570665415, -0.04746872842254, -0.04899968532023, 0.03510685742783, -0.05398199531481, -0.05728294659133, 0.01700752911701, -0.05260385601595, -0.03484669808203, -0.05761715944068, 0.03895560265498, 0.06969057246245, 0.00155790816347, 0.00898729611428, -0.05782350471105, 0.00898729611428, 0.00155790816347, 0.06969057246245, 0.03895560265498, -0.05761715944068, -0.03484669808203, -0.05260385601595, 0.01700752911701, -0.05728294659133, -0.0539819 [...]
+0.04144419729370, 0.04348828141759, -0.04031243635006, 0.03568073651916, 0.03250874444113, -0.05349976932781, 0.03669569988478, 0.04496452881899, -0.05260385601595, 0.06522696614589, 0.06584304685785, 0.02156735149891, 0.00898729611428, -0.04330187825715, 0.05012494613301, -0.05912294255307, 0.01371110078340, -0.05912294255307, 0.05012494613301, -0.04330187825715, 0.00898729611428, 0.02156735149891, 0.06584304685785, 0.06522696614589, -0.05260385601595, 0.04496452881899, 0.03669569988478 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+0.02663318777774, 0.01076407940667, -0.03980537034422, -0.01578529983234, -0.02333152061039, -0.03045828585214, -0.02516948075949, -0.01764835261303, -0.05761715944068, 0.02156735149891, 0.05116991106925, -0.05912294255307, 0.07992564670887, 0.04485675423343, 0.08752809455106, -0.08513999504483, -0.07614567822515, -0.08513999504483, 0.08752809455106, 0.04485675423343, 0.07992564670887, -0.05912294255307, 0.05116991106925, 0.02156735149891, -0.05761715944068, -0.01764835261303, -0.0251694 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+-0.03645408668750, -0.02387116439873, 0.04755584645599, 0.00114288282262, 0.00864062075235, 0.04496452881899, 0.00869067734621, -0.00086468661469, 0.06969057246245, -0.04330187825715, -0.07051895298226, 0.04485675423343, -0.07614567822515, -0.02381038314910, -0.10125366504812, 0.10334674409940, 0.06525950351177, 0.10334674409940, -0.10125366504812, -0.02381038314910, -0.07614567822515, 0.04485675423343, -0.07051895298226, -0.04330187825715, 0.06969057246245, -0.00086468661469, 0.00869067 [...]
+0.01512570665415, 0.03282161335501, -0.00153126021194, 0.05166746230846, 0.05634488400998, -0.02516948075949, 0.06377948953705, 0.06584304685785, 0.00155790816347, 0.05012494613301, 0.02127053092509, 0.08752809455106, -0.07494530013047, -0.10125366504812, -0.03399633247860, 0.02003044394070, 0.10156554753512, 0.02003044394070, -0.03399633247860, -0.10125366504812, -0.07494530013047, 0.08752809455106, 0.02127053092509, 0.05012494613301, 0.00155790816347, 0.06584304685785, 0.06377948953705 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+0.02264757303314, 0.00493640288370, -0.03755053092747, -0.02333152061039, -0.03144564133374, -0.02546580226758, -0.03484669808203, -0.02803496562843, -0.05782350471105, 0.01371110078340, 0.04915146033489, -0.07614567822515, 0.09733017222613, 0.06525950351177, 0.10156554753512, -0.09751182812518, -0.10150612803431, -0.09751182812518, 0.10156554753512, 0.06525950351177, 0.09733017222613, -0.07614567822515, 0.04915146033489, 0.01371110078340, -0.05782350471105, -0.02803496562843, -0.0348466 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+0.01512570665415, 0.03282161335501, -0.00153126021194, 0.05166746230846, 0.05634488400998, -0.02516948075949, 0.06377948953705, 0.06584304685785, 0.00155790816347, 0.05012494613301, 0.02127053092509, 0.08752809455106, -0.07494530013047, -0.10125366504812, -0.03399633247860, 0.02003044394070, 0.10156554753512, 0.02003044394070, -0.03399633247860, -0.10125366504812, -0.07494530013047, 0.08752809455106, 0.02127053092509, 0.05012494613301, 0.00155790816347, 0.06584304685785, 0.06377948953705 [...]
+-0.03645408668750, -0.02387116439873, 0.04755584645599, 0.00114288282262, 0.00864062075235, 0.04496452881899, 0.00869067734621, -0.00086468661469, 0.06969057246245, -0.04330187825715, -0.07051895298226, 0.04485675423343, -0.07614567822515, -0.02381038314910, -0.10125366504812, 0.10334674409940, 0.06525950351177, 0.10334674409940, -0.10125366504812, -0.02381038314910, -0.07614567822515, 0.04485675423343, -0.07051895298226, -0.04330187825715, 0.06969057246245, -0.00086468661469, 0.00869067 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+0.02663318777774, 0.01076407940667, -0.03980537034422, -0.01578529983234, -0.02333152061039, -0.03045828585214, -0.02516948075949, -0.01764835261303, -0.05761715944068, 0.02156735149891, 0.05116991106925, -0.05912294255307, 0.07992564670887, 0.04485675423343, 0.08752809455106, -0.08513999504483, -0.07614567822515, -0.08513999504483, 0.08752809455106, 0.04485675423343, 0.07992564670887, -0.05912294255307, 0.05116991106925, 0.02156735149891, -0.05761715944068, -0.01764835261303, -0.0251694 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+0.04144419729370, 0.04348828141759, -0.04031243635006, 0.03568073651916, 0.03250874444113, -0.05349976932781, 0.03669569988478, 0.04496452881899, -0.05260385601595, 0.06522696614589, 0.06584304685785, 0.02156735149891, 0.00898729611428, -0.04330187825715, 0.05012494613301, -0.05912294255307, 0.01371110078340, -0.05912294255307, 0.05012494613301, -0.04330187825715, 0.00898729611428, 0.02156735149891, 0.06584304685785, 0.06522696614589, -0.05260385601595, 0.04496452881899, 0.03669569988478 [...]
+-0.02511329203000, -0.03797145192049, 0.01512570665415, -0.04746872842254, -0.04899968532023, 0.03510685742783, -0.05398199531481, -0.05728294659133, 0.01700752911701, -0.05260385601595, -0.03484669808203, -0.05761715944068, 0.03895560265498, 0.06969057246245, 0.00155790816347, 0.00898729611428, -0.05782350471105, 0.00898729611428, 0.00155790816347, 0.06969057246245, 0.03895560265498, -0.05761715944068, -0.03484669808203, -0.05260385601595, 0.01700752911701, -0.05728294659133, -0.0539819 [...]
+0.03785607654408, 0.02991156721912, -0.04410886072389, 0.01076407940667, 0.00493640288370, -0.04513877691637, 0.00629983820314, 0.01466865762037, -0.05728294659133, 0.04496452881899, 0.05946062873198, -0.01764835261303, 0.04273731697500, -0.00086468661469, 0.06584304685785, -0.06883698723352, -0.02803496562843, -0.06883698723352, 0.06584304685785, -0.00086468661469, 0.04273731697500, -0.01764835261303, 0.05946062873198, 0.04496452881899, -0.05728294659133, 0.01466865762037, 0.00629983820 [...]
+0.03438945519666, 0.02443728561702, -0.04200139277956, 0.00380202623900, -0.00222561996695, -0.03980537034422, -0.00153126021194, 0.00629983820314, -0.05398199531481, 0.03669569988478, 0.05323681630826, -0.02516948075949, 0.04683219028095, 0.00869067734621, 0.06377948953705, -0.06514516365773, -0.03484669808203, -0.06514516365773, 0.06377948953705, 0.00869067734621, 0.04683219028095, -0.02516948075949, 0.05323681630826, 0.03669569988478, -0.05398199531481, 0.00629983820314, -0.0015312602 [...]
+-0.03446030853185, -0.04008674845418, 0.02965188168129, -0.03814396416671, -0.03645408668750, 0.04341150826710, -0.03980537034422, -0.04513877691637, 0.03510685742783, -0.05349976932781, -0.04716218793354, -0.03045828585214, 0.00801021034064, 0.04496452881899, -0.02516948075949, 0.03296691756242, -0.02546580226758, 0.03296691756242, -0.02516948075949, 0.04496452881899, 0.00801021034064, -0.03045828585214, -0.04716218793354, -0.05349976932781, 0.03510685742783, -0.04513877691637, -0.03980 [...]
+0.03800181165995, 0.03438945519666, -0.04028853365296, 0.02051771641111, 0.01595838913427, -0.04512890076845, 0.01794329647509, 0.02522891682511, -0.04939808301205, 0.04745915084934, 0.05428131739349, -0.00071933672845, 0.02416013744322, -0.01598181558280, 0.04963142214735, -0.05403298716581, -0.00864631825412, -0.05403298716581, 0.04963142214735, -0.01598181558280, 0.02416013744322, -0.00071933672845, 0.05428131739349, 0.04745915084934, -0.04939808301205, 0.02522891682511, 0.01794329647 [...]
+-0.02428439051753, -0.03605961724444, 0.01485220652451, -0.04410886072389, -0.04512890076845, 0.03282161335501, -0.04899968532023, -0.05170195653292, 0.01610767548006, -0.04716218793354, -0.03144564133374, -0.04963002409968, 0.03277758616341, 0.05946062873198, 0.00027003849811, 0.00869067734621, -0.04836796828267, 0.00869067734621, 0.00027003849811, 0.05946062873198, 0.03277758616341, -0.04963002409968, -0.03144564133374, -0.04716218793354, 0.01610767548006, -0.05170195653292, -0.0489996 [...]
+0.04014593082298, 0.03678691831046, -0.04271220519611, 0.02264757303314, 0.01794329647509, -0.04899968532023, 0.02038138287138, 0.02847526258331, -0.05430453818238, 0.05323681630826, 0.06083851296868, 0.00027003849811, 0.02642596318589, -0.01933288371895, 0.05627305279151, -0.06161913050027, -0.00879307760295, -0.06161913050027, 0.05627305279151, -0.01933288371895, 0.02642596318589, 0.00027003849811, 0.06083851296868, 0.05323681630826, -0.05430453818238, 0.02847526258331, 0.0203813828713 [...]
+0.04123067549901, 0.04048597213817, -0.04200352716372, 0.02926181365419, 0.02522891682511, -0.05170195653292, 0.02847526258331, 0.03669569988478, -0.05403298716581, 0.05946062873198, 0.06377948953705, 0.01029899957189, 0.01848943615820, -0.03067019176029, 0.05387660966815, -0.06095484289857, 0.00155790816347, -0.06095484289857, 0.05387660966815, -0.03067019176029, 0.01848943615820, 0.01029899957189, 0.06377948953705, 0.05946062873198, -0.05403298716581, 0.03669569988478, 0.02847526258331 [...]
+-0.00905031863291, -0.02613601062284, -0.00434559103408, -0.04499172586632, -0.04939808301205, 0.01610767548006, -0.05430453818238, -0.05403298716581, -0.00905987177209, -0.03484669808203, -0.00879307760295, -0.07081173873106, 0.06316887617837, 0.07536267012088, 0.03433801412888, -0.02442011476440, -0.07714535201411, -0.02442011476440, 0.03433801412888, 0.07536267012088, 0.06316887617837, -0.07081173873106, -0.00879307760295, -0.03484669808203, -0.00905987177209, -0.05403298716581, -0.05 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+0.02073808121767, 0.03644296273535, -0.00875565887367, 0.05105292102523, 0.05428131739349, -0.03144564133374, 0.06083851296868, 0.06377948953705, -0.00879307760295, 0.05387660966815, 0.03017589095093, 0.07462272788890, -0.05771185029271, -0.08813390430467, -0.01626781358073, 0.00344457002262, 0.08094445627940, 0.00344457002262, -0.01626781358073, -0.08813390430467, -0.05771185029271, 0.07462272788890, 0.03017589095093, 0.05387660966815, -0.00879307760295, 0.06377948953705, 0.060838512968 [...]
+0.03963047977889, 0.02926181365419, -0.04899968532023, 0.00629983820314, -0.00071933672845, -0.04963002409968, 0.00027003849811, 0.01029899957189, -0.07081173873106, 0.05116991106925, 0.07462272788890, -0.03318526107069, 0.06656064247057, 0.00998778878484, 0.09733017222613, -0.10125366504812, -0.05169023594242, -0.10125366504812, 0.09733017222613, 0.00998778878484, 0.06656064247057, -0.03318526107069, 0.07462272788890, 0.05116991106925, -0.07081173873106, 0.01029899957189, 0.000270038498 [...]
+-0.02788397290880, -0.01159092756416, 0.04178512556283, 0.01610767548006, 0.02416013744322, 0.03277758616341, 0.02642596318589, 0.01848943615820, 0.06316887617837, -0.02442011476440, -0.05771185029271, 0.06656064247057, -0.09172320431048, -0.05169023594242, -0.10348456280590, 0.10156554753512, 0.09041357753814, 0.10156554753512, -0.10348456280590, -0.05169023594242, -0.09172320431048, 0.06656064247057, -0.05771185029271, -0.02442011476440, 0.06316887617837, 0.01848943615820, 0.0264259631 [...]
+-0.04512890076845, -0.03980537034422, 0.05105292102523, -0.02183846096527, -0.01598181558280, 0.05946062873198, -0.01933288371895, -0.03067019176029, 0.07536267012088, -0.07051895298226, -0.08813390430467, 0.00998778878484, -0.05169023594242, 0.02003044394070, -0.10150612803431, 0.11129083655510, 0.02834885437642, 0.11129083655510, -0.10150612803431, 0.02003044394070, -0.05169023594242, 0.00998778878484, -0.08813390430467, -0.07051895298226, 0.07536267012088, -0.03067019176029, -0.019332 [...]
+-0.00434559103408, 0.01552199992789, 0.02038138287138, 0.04222968115101, 0.04963142214735, 0.00027003849811, 0.05627305279151, 0.05387660966815, 0.03433801412888, 0.02127053092509, -0.01626781358073, 0.09733017222613, -0.10348456280590, -0.10150612803431, -0.08280335937603, 0.07210126160498, 0.12603831803759, 0.07210126160498, -0.08280335937603, -0.10150612803431, -0.10348456280590, 0.09733017222613, -0.01626781358073, 0.02127053092509, 0.03433801412888, 0.05387660966815, 0.0562730527915 [...]
+-0.00222561996695, -0.02205338028065, -0.01352102709593, -0.04716218793354, -0.05403298716581, 0.00869067734621, -0.06161913050027, -0.06095484289857, -0.02442011476440, -0.03318526107069, 0.00344457002262, -0.10125366504812, 0.10156554753512, 0.11129083655510, 0.07210126160498, -0.05916188988776, -0.13058003873376, -0.05916188988776, 0.07210126160498, 0.11129083655510, 0.10156554753512, -0.10125366504812, 0.00344457002262, -0.03318526107069, -0.02442011476440, -0.06095484289857, -0.0616 [...]
+0.03804111121964, 0.02522891682511, -0.04990035313554, -0.00071933672845, -0.00864631825412, -0.04836796828267, -0.00879307760295, 0.00155790816347, -0.07714535201411, 0.04915146033489, 0.08094445627940, -0.05169023594242, 0.09041357753814, 0.02834885437642, 0.12603831803759, -0.13058003873376, -0.08232980948645, -0.13058003873376, 0.12603831803759, 0.02834885437642, 0.09041357753814, -0.05169023594242, 0.08094445627940, 0.04915146033489, -0.07714535201411, 0.00155790816347, -0.008793077 [...]
+-0.00222561996695, -0.02205338028065, -0.01352102709593, -0.04716218793354, -0.05403298716581, 0.00869067734621, -0.06161913050027, -0.06095484289857, -0.02442011476440, -0.03318526107069, 0.00344457002262, -0.10125366504812, 0.10156554753512, 0.11129083655510, 0.07210126160498, -0.05916188988776, -0.13058003873376, -0.05916188988776, 0.07210126160498, 0.11129083655510, 0.10156554753512, -0.10125366504812, 0.00344457002262, -0.03318526107069, -0.02442011476440, -0.06095484289857, -0.0616 [...]
+-0.00434559103408, 0.01552199992789, 0.02038138287138, 0.04222968115101, 0.04963142214735, 0.00027003849811, 0.05627305279151, 0.05387660966815, 0.03433801412888, 0.02127053092509, -0.01626781358073, 0.09733017222613, -0.10348456280590, -0.10150612803431, -0.08280335937603, 0.07210126160498, 0.12603831803759, 0.07210126160498, -0.08280335937603, -0.10150612803431, -0.10348456280590, 0.09733017222613, -0.01626781358073, 0.02127053092509, 0.03433801412888, 0.05387660966815, 0.0562730527915 [...]
+-0.04512890076845, -0.03980537034422, 0.05105292102523, -0.02183846096527, -0.01598181558280, 0.05946062873198, -0.01933288371895, -0.03067019176029, 0.07536267012088, -0.07051895298226, -0.08813390430467, 0.00998778878484, -0.05169023594242, 0.02003044394070, -0.10150612803431, 0.11129083655510, 0.02834885437642, 0.11129083655510, -0.10150612803431, 0.02003044394070, -0.05169023594242, 0.00998778878484, -0.08813390430467, -0.07051895298226, 0.07536267012088, -0.03067019176029, -0.019332 [...]
+-0.02788397290880, -0.01159092756416, 0.04178512556283, 0.01610767548006, 0.02416013744322, 0.03277758616341, 0.02642596318589, 0.01848943615820, 0.06316887617837, -0.02442011476440, -0.05771185029271, 0.06656064247057, -0.09172320431048, -0.05169023594242, -0.10348456280590, 0.10156554753512, 0.09041357753814, 0.10156554753512, -0.10348456280590, -0.05169023594242, -0.09172320431048, 0.06656064247057, -0.05771185029271, -0.02442011476440, 0.06316887617837, 0.01848943615820, 0.0264259631 [...]
+0.03963047977889, 0.02926181365419, -0.04899968532023, 0.00629983820314, -0.00071933672845, -0.04963002409968, 0.00027003849811, 0.01029899957189, -0.07081173873106, 0.05116991106925, 0.07462272788890, -0.03318526107069, 0.06656064247057, 0.00998778878484, 0.09733017222613, -0.10125366504812, -0.05169023594242, -0.10125366504812, 0.09733017222613, 0.00998778878484, 0.06656064247057, -0.03318526107069, 0.07462272788890, 0.05116991106925, -0.07081173873106, 0.01029899957189, 0.000270038498 [...]
+0.02073808121767, 0.03644296273535, -0.00875565887367, 0.05105292102523, 0.05428131739349, -0.03144564133374, 0.06083851296868, 0.06377948953705, -0.00879307760295, 0.05387660966815, 0.03017589095093, 0.07462272788890, -0.05771185029271, -0.08813390430467, -0.01626781358073, 0.00344457002262, 0.08094445627940, 0.00344457002262, -0.01626781358073, -0.08813390430467, -0.05771185029271, 0.07462272788890, 0.03017589095093, 0.05387660966815, -0.00879307760295, 0.06377948953705, 0.060838512968 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+-0.00905031863291, -0.02613601062284, -0.00434559103408, -0.04499172586632, -0.04939808301205, 0.01610767548006, -0.05430453818238, -0.05403298716581, -0.00905987177209, -0.03484669808203, -0.00879307760295, -0.07081173873106, 0.06316887617837, 0.07536267012088, 0.03433801412888, -0.02442011476440, -0.07714535201411, -0.02442011476440, 0.03433801412888, 0.07536267012088, 0.06316887617837, -0.07081173873106, -0.00879307760295, -0.03484669808203, -0.00905987177209, -0.05403298716581, -0.05 [...]
+0.04123067549901, 0.04048597213817, -0.04200352716372, 0.02926181365419, 0.02522891682511, -0.05170195653292, 0.02847526258331, 0.03669569988478, -0.05403298716581, 0.05946062873198, 0.06377948953705, 0.01029899957189, 0.01848943615820, -0.03067019176029, 0.05387660966815, -0.06095484289857, 0.00155790816347, -0.06095484289857, 0.05387660966815, -0.03067019176029, 0.01848943615820, 0.01029899957189, 0.06377948953705, 0.05946062873198, -0.05403298716581, 0.03669569988478, 0.02847526258331 [...]
+0.04014593082298, 0.03678691831046, -0.04271220519611, 0.02264757303314, 0.01794329647509, -0.04899968532023, 0.02038138287138, 0.02847526258331, -0.05430453818238, 0.05323681630826, 0.06083851296868, 0.00027003849811, 0.02642596318589, -0.01933288371895, 0.05627305279151, -0.06161913050027, -0.00879307760295, -0.06161913050027, 0.05627305279151, -0.01933288371895, 0.02642596318589, 0.00027003849811, 0.06083851296868, 0.05323681630826, -0.05430453818238, 0.02847526258331, 0.0203813828713 [...]
+-0.02428439051753, -0.03605961724444, 0.01485220652451, -0.04410886072389, -0.04512890076845, 0.03282161335501, -0.04899968532023, -0.05170195653292, 0.01610767548006, -0.04716218793354, -0.03144564133374, -0.04963002409968, 0.03277758616341, 0.05946062873198, 0.00027003849811, 0.00869067734621, -0.04836796828267, 0.00869067734621, 0.00027003849811, 0.05946062873198, 0.03277758616341, -0.04963002409968, -0.03144564133374, -0.04716218793354, 0.01610767548006, -0.05170195653292, -0.0489996 [...]
+-0.00388219372909, -0.01984984065797, -0.00866995656907, -0.03797145192049, -0.04200352716372, 0.00881974876440, -0.04499172586632, -0.04326903841033, -0.01352102709593, -0.02333152061039, -0.00071933672845, -0.05728294659133, 0.05323681630826, 0.05742081875151, 0.03277758616341, -0.02546580226758, -0.06076173352856, -0.02546580226758, 0.03277758616341, 0.05742081875151, 0.05323681630826, -0.05728294659133, -0.00071933672845, -0.02333152061039, -0.01352102709593, -0.04326903841033, -0.04 [...]
+-0.03137727669444, -0.01958004332321, 0.04048597213817, 0.00253986035635, 0.00881974876440, 0.03568073651916, 0.00870175468576, 0.00114288282262, 0.05259259692296, -0.03045828585214, -0.04963002409968, 0.03296691756242, -0.05260385601595, -0.01764835261303, -0.06514516365773, 0.06522696614589, 0.04273731697500, 0.06522696614589, -0.06514516365773, -0.01764835261303, -0.05260385601595, 0.03296691756242, -0.04963002409968, -0.03045828585214, 0.05259259692296, 0.00114288282262, 0.0087017546 [...]
+-0.00338379798127, -0.02040531295214, -0.01000868479601, -0.04031243635006, -0.04499172586632, 0.00870175468576, -0.04883456542052, -0.04716218793354, -0.01598181558280, -0.02516948075949, 0.00027003849811, -0.06514516365773, 0.06145323689284, 0.06584304685785, 0.03895560265498, -0.03067019176029, -0.07081173873106, -0.03067019176029, 0.03895560265498, 0.06584304685785, 0.06145323689284, -0.06514516365773, 0.00027003849811, -0.02516948075949, -0.01598181558280, -0.04716218793354, -0.0488 [...]
+0.00282925577496, -0.01497649034024, -0.01690433755852, -0.03761152873895, -0.04326903841033, 0.00114288282262, -0.04716218793354, -0.04431851921725, -0.02546580226758, -0.01764835261303, 0.01029899957189, -0.06883698723352, 0.06969057246245, 0.06698830614494, 0.05116991106925, -0.04330187825715, -0.07747405815543, -0.04330187825715, 0.05116991106925, 0.06698830614494, 0.06969057246245, -0.06883698723352, 0.01029899957189, -0.01764835261303, -0.02546580226758, -0.04431851921725, -0.04716 [...]
+-0.04200139277956, -0.03645408668750, 0.04703493050962, -0.01909407501789, -0.01352102709593, 0.05259259692296, -0.01598181558280, -0.02546580226758, 0.06377948953705, -0.05761715944068, -0.07081173873106, 0.00898729611428, -0.04040858119196, 0.01371110078340, -0.07419862922226, 0.07992564670887, 0.02127053092509, 0.07992564670887, -0.07419862922226, 0.01371110078340, -0.04040858119196, 0.00898729611428, -0.07081173873106, -0.05761715944068, 0.06377948953705, -0.02546580226758, -0.015981 [...]
+0.02663318777774, 0.01076407940667, -0.03980537034422, -0.01578529983234, -0.02333152061039, -0.03045828585214, -0.02516948075949, -0.01764835261303, -0.05761715944068, 0.02156735149891, 0.05116991106925, -0.05912294255307, 0.07992564670887, 0.04485675423343, 0.08752809455106, -0.08513999504483, -0.07614567822515, -0.08513999504483, 0.08752809455106, 0.04485675423343, 0.07992564670887, -0.05912294255307, 0.05116991106925, 0.02156735149891, -0.05761715944068, -0.01764835261303, -0.0251694 [...]
+0.03963047977889, 0.02926181365419, -0.04899968532023, 0.00629983820314, -0.00071933672845, -0.04963002409968, 0.00027003849811, 0.01029899957189, -0.07081173873106, 0.05116991106925, 0.07462272788890, -0.03318526107069, 0.06656064247057, 0.00998778878484, 0.09733017222613, -0.10125366504812, -0.05169023594242, -0.10125366504812, 0.09733017222613, 0.00998778878484, 0.06656064247057, -0.03318526107069, 0.07462272788890, 0.05116991106925, -0.07081173873106, 0.01029899957189, 0.000270038498 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+0.03644296273535, 0.04741800568147, -0.02912466965015, 0.05259259692296, 0.05323681630826, -0.05260385601595, 0.06145323689284, 0.06969057246245, -0.04040858119196, 0.07992564670887, 0.06656064247057, 0.06717547808897, -0.03399633247860, -0.09751182812518, 0.02834885437642, -0.04599388822189, 0.07210126160498, -0.04599388822189, 0.02834885437642, -0.09751182812518, -0.03399633247860, 0.06717547808897, 0.06656064247057, 0.07992564670887, -0.04040858119196, 0.06969057246245, 0.061453236892 [...]
+0.00881974876440, 0.02821667474258, 0.00629983820314, 0.05121834474517, 0.05742081875151, -0.01764835261303, 0.06584304685785, 0.06698830614494, 0.01371110078340, 0.04485675423343, 0.00998778878484, 0.10334674409940, -0.09751182812518, -0.11954033404934, -0.05916188988776, 0.04399094217963, 0.13297118107692, 0.04399094217963, -0.05916188988776, -0.11954033404934, -0.09751182812518, 0.10334674409940, 0.00998778878484, 0.04485675423343, 0.01371110078340, 0.06698830614494, 0.06584304685785, [...]
+0.04703493050962, 0.04755584645599, -0.04883456542052, 0.03669569988478, 0.03277758616341, -0.06514516365773, 0.03895560265498, 0.05116991106925, -0.07419862922226, 0.08752809455106, 0.09733017222613, 0.02003044394070, 0.02834885437642, -0.05916188988776, 0.10061964911512, -0.11875106261662, 0.00693420455927, -0.11875106261662, 0.10061964911512, -0.05916188988776, 0.02834885437642, 0.02003044394070, 0.09733017222613, 0.08752809455106, -0.07419862922226, 0.05116991106925, 0.03895560265498 [...]
+-0.04746872842254, -0.04513877691637, 0.05166746230846, -0.03045828585214, -0.02546580226758, 0.06522696614589, -0.03067019176029, -0.04330187825715, 0.07992564670887, -0.08513999504483, -0.10125366504812, -0.00486213436803, -0.04599388822189, 0.04399094217963, -0.11875106261662, 0.13658472451851, 0.01504573058692, 0.13658472451851, -0.11875106261662, 0.04399094217963, -0.04599388822189, -0.00486213436803, -0.10125366504812, -0.08513999504483, 0.07992564670887, -0.04330187825715, -0.0306 [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+-0.04746872842254, -0.04513877691637, 0.05166746230846, -0.03045828585214, -0.02546580226758, 0.06522696614589, -0.03067019176029, -0.04330187825715, 0.07992564670887, -0.08513999504483, -0.10125366504812, -0.00486213436803, -0.04599388822189, 0.04399094217963, -0.11875106261662, 0.13658472451851, 0.01504573058692, 0.13658472451851, -0.11875106261662, 0.04399094217963, -0.04599388822189, -0.00486213436803, -0.10125366504812, -0.08513999504483, 0.07992564670887, -0.04330187825715, -0.0306 [...]
+0.04703493050962, 0.04755584645599, -0.04883456542052, 0.03669569988478, 0.03277758616341, -0.06514516365773, 0.03895560265498, 0.05116991106925, -0.07419862922226, 0.08752809455106, 0.09733017222613, 0.02003044394070, 0.02834885437642, -0.05916188988776, 0.10061964911512, -0.11875106261662, 0.00693420455927, -0.11875106261662, 0.10061964911512, -0.05916188988776, 0.02834885437642, 0.02003044394070, 0.09733017222613, 0.08752809455106, -0.07419862922226, 0.05116991106925, 0.03895560265498 [...]
+0.00881974876440, 0.02821667474258, 0.00629983820314, 0.05121834474517, 0.05742081875151, -0.01764835261303, 0.06584304685785, 0.06698830614494, 0.01371110078340, 0.04485675423343, 0.00998778878484, 0.10334674409940, -0.09751182812518, -0.11954033404934, -0.05916188988776, 0.04399094217963, 0.13297118107692, 0.04399094217963, -0.05916188988776, -0.11954033404934, -0.09751182812518, 0.10334674409940, 0.00998778878484, 0.04485675423343, 0.01371110078340, 0.06698830614494, 0.06584304685785, [...]
+0.03644296273535, 0.04741800568147, -0.02912466965015, 0.05259259692296, 0.05323681630826, -0.05260385601595, 0.06145323689284, 0.06969057246245, -0.04040858119196, 0.07992564670887, 0.06656064247057, 0.06717547808897, -0.03399633247860, -0.09751182812518, 0.02834885437642, -0.04599388822189, 0.07210126160498, -0.04599388822189, 0.02834885437642, -0.09751182812518, -0.03399633247860, 0.06717547808897, 0.06656064247057, 0.07992564670887, -0.04040858119196, 0.06969057246245, 0.061453236892 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+0.03963047977889, 0.02926181365419, -0.04899968532023, 0.00629983820314, -0.00071933672845, -0.04963002409968, 0.00027003849811, 0.01029899957189, -0.07081173873106, 0.05116991106925, 0.07462272788890, -0.03318526107069, 0.06656064247057, 0.00998778878484, 0.09733017222613, -0.10125366504812, -0.05169023594242, -0.10125366504812, 0.09733017222613, 0.00998778878484, 0.06656064247057, -0.03318526107069, 0.07462272788890, 0.05116991106925, -0.07081173873106, 0.01029899957189, 0.000270038498 [...]
+0.02663318777774, 0.01076407940667, -0.03980537034422, -0.01578529983234, -0.02333152061039, -0.03045828585214, -0.02516948075949, -0.01764835261303, -0.05761715944068, 0.02156735149891, 0.05116991106925, -0.05912294255307, 0.07992564670887, 0.04485675423343, 0.08752809455106, -0.08513999504483, -0.07614567822515, -0.08513999504483, 0.08752809455106, 0.04485675423343, 0.07992564670887, -0.05912294255307, 0.05116991106925, 0.02156735149891, -0.05761715944068, -0.01764835261303, -0.0251694 [...]
+-0.04200139277956, -0.03645408668750, 0.04703493050962, -0.01909407501789, -0.01352102709593, 0.05259259692296, -0.01598181558280, -0.02546580226758, 0.06377948953705, -0.05761715944068, -0.07081173873106, 0.00898729611428, -0.04040858119196, 0.01371110078340, -0.07419862922226, 0.07992564670887, 0.02127053092509, 0.07992564670887, -0.07419862922226, 0.01371110078340, -0.04040858119196, 0.00898729611428, -0.07081173873106, -0.05761715944068, 0.06377948953705, -0.02546580226758, -0.015981 [...]
+0.00282925577496, -0.01497649034024, -0.01690433755852, -0.03761152873895, -0.04326903841033, 0.00114288282262, -0.04716218793354, -0.04431851921725, -0.02546580226758, -0.01764835261303, 0.01029899957189, -0.06883698723352, 0.06969057246245, 0.06698830614494, 0.05116991106925, -0.04330187825715, -0.07747405815543, -0.04330187825715, 0.05116991106925, 0.06698830614494, 0.06969057246245, -0.06883698723352, 0.01029899957189, -0.01764835261303, -0.02546580226758, -0.04431851921725, -0.04716 [...]
+-0.00338379798127, -0.02040531295214, -0.01000868479601, -0.04031243635006, -0.04499172586632, 0.00870175468576, -0.04883456542052, -0.04716218793354, -0.01598181558280, -0.02516948075949, 0.00027003849811, -0.06514516365773, 0.06145323689284, 0.06584304685785, 0.03895560265498, -0.03067019176029, -0.07081173873106, -0.03067019176029, 0.03895560265498, 0.06584304685785, 0.06145323689284, -0.06514516365773, 0.00027003849811, -0.02516948075949, -0.01598181558280, -0.04716218793354, -0.0488 [...]
+-0.03137727669444, -0.01958004332321, 0.04048597213817, 0.00253986035635, 0.00881974876440, 0.03568073651916, 0.00870175468576, 0.00114288282262, 0.05259259692296, -0.03045828585214, -0.04963002409968, 0.03296691756242, -0.05260385601595, -0.01764835261303, -0.06514516365773, 0.06522696614589, 0.04273731697500, 0.06522696614589, -0.06514516365773, -0.01764835261303, -0.05260385601595, 0.03296691756242, -0.04963002409968, -0.03045828585214, 0.05259259692296, 0.00114288282262, 0.0087017546 [...]
+0.01961646864417, 0.03286903679693, -0.00905031863291, 0.04384574828821, 0.04569971096681, -0.02743053076570, 0.04945313461415, 0.05105292102523, -0.00866167202085, 0.04222968115101, 0.02416013744322, 0.05323681630826, -0.03931525868965, -0.06076173352856, -0.00905987177209, 0.00027003849811, 0.05322433439424, 0.00027003849811, -0.00905987177209, -0.06076173352856, -0.03931525868965, 0.05323681630826, 0.02416013744322, 0.04222968115101, -0.00866167202085, 0.05105292102523, 0.049453134614 [...]
+0.01871143836380, 0.00282925577496, -0.03115444796200, -0.02111691650473, -0.02743053076570, -0.01909407501789, -0.02912466965015, -0.02333152061039, -0.04211210676874, 0.00801021034064, 0.03277758616341, -0.05260385601595, 0.06377948953705, 0.04273731697500, 0.06145323689284, -0.05761715944068, -0.06161913050027, -0.05761715944068, 0.06145323689284, 0.04273731697500, 0.06377948953705, -0.05260385601595, 0.03277758616341, 0.00801021034064, -0.04211210676874, -0.02333152061039, -0.0291246 [...]
+0.02011120046566, 0.03447279299858, -0.00889141691347, 0.04703493050962, 0.04945313461415, -0.02912466965015, 0.05428131739349, 0.05634488400998, -0.00864631825412, 0.04683219028095, 0.02642596318589, 0.06145323689284, -0.04628401868063, -0.07081173873106, -0.01180521143300, 0.00155790816347, 0.06316887617837, 0.00155790816347, -0.01180521143300, -0.07081173873106, -0.04628401868063, 0.06145323689284, 0.02642596318589, 0.04683219028095, -0.00864631825412, 0.05634488400998, 0.054281317393 [...]
+0.01485220652451, 0.03105894328301, -0.00222561996695, 0.04741800568147, 0.05105292102523, -0.02333152061039, 0.05634488400998, 0.05742081875151, 0.00027003849811, 0.04273731697500, 0.01848943615820, 0.06969057246245, -0.05782350471105, -0.07747405815543, -0.02442011476440, 0.01371110078340, 0.07462272788890, 0.01371110078340, -0.02442011476440, -0.07747405815543, -0.05782350471105, 0.06969057246245, 0.01848943615820, 0.04273731697500, 0.00027003849811, 0.05742081875151, 0.05634488400998 [...]
+0.03501492614272, 0.02264757303314, -0.04548829345483, -0.00153126021194, -0.00866167202085, -0.04211210676874, -0.00864631825412, 0.00027003849811, -0.06399728423775, 0.03895560265498, 0.06316887617837, -0.04040858119196, 0.06720841455530, 0.02127053092509, 0.08701085516538, -0.08813390430467, -0.05605729667571, -0.08813390430467, 0.08701085516538, 0.02127053092509, 0.06720841455530, -0.04040858119196, 0.06316887617837, 0.03895560265498, -0.06399728423775, 0.00027003849811, -0.008646318 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+-0.02788397290880, -0.01159092756416, 0.04178512556283, 0.01610767548006, 0.02416013744322, 0.03277758616341, 0.02642596318589, 0.01848943615820, 0.06316887617837, -0.02442011476440, -0.05771185029271, 0.06656064247057, -0.09172320431048, -0.05169023594242, -0.10348456280590, 0.10156554753512, 0.09041357753814, 0.10156554753512, -0.10348456280590, -0.05169023594242, -0.09172320431048, 0.06656064247057, -0.05771185029271, -0.02442011476440, 0.06316887617837, 0.01848943615820, 0.0264259631 [...]
+0.03644296273535, 0.04741800568147, -0.02912466965015, 0.05259259692296, 0.05323681630826, -0.05260385601595, 0.06145323689284, 0.06969057246245, -0.04040858119196, 0.07992564670887, 0.06656064247057, 0.06717547808897, -0.03399633247860, -0.09751182812518, 0.02834885437642, -0.04599388822189, 0.07210126160498, -0.04599388822189, 0.02834885437642, -0.09751182812518, -0.03399633247860, 0.06717547808897, 0.06656064247057, 0.07992564670887, -0.04040858119196, 0.06969057246245, 0.061453236892 [...]
+-0.04567030131908, -0.04899968532023, 0.04507008450281, -0.04211210676874, -0.03931525868965, 0.06377948953705, -0.04628401868063, -0.05782350471105, 0.06720841455530, -0.08813390430467, -0.09172320431048, -0.03399633247860, -0.01132895341962, 0.07210126160498, -0.08232980948645, 0.10061964911512, -0.02658902847591, 0.10061964911512, -0.08232980948645, 0.07210126160498, -0.01132895341962, -0.03399633247860, -0.09172320431048, -0.08813390430467, 0.06720841455530, -0.05782350471105, -0.046 [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+-0.04548829345483, -0.03755053092747, 0.05428131739349, -0.01598181558280, -0.00905987177209, 0.06145323689284, -0.01180521143300, -0.02442011476440, 0.08701085516538, -0.07494530013047, -0.10348456280590, 0.02834885437642, -0.08232980948645, 0.00693420455927, -0.15403806518312, 0.17112027276390, 0.06683312417585, 0.17112027276390, -0.15403806518312, 0.00693420455927, -0.08232980948645, 0.02834885437642, -0.10348456280590, -0.07494530013047, 0.08701085516538, -0.02442011476440, -0.011805 [...]
+0.04309315116934, 0.03250874444113, -0.05398199531481, 0.00801021034064, 0.00027003849811, -0.05761715944068, 0.00155790816347, 0.01371110078340, -0.08813390430467, 0.06717547808897, 0.10156554753512, -0.04599388822189, 0.10061964911512, 0.01504573058692, 0.17112027276390, -0.18799488548807, -0.09766849275778, -0.18799488548807, 0.17112027276390, 0.01504573058692, 0.10061964911512, -0.04599388822189, 0.10156554753512, 0.06717547808897, -0.08813390430467, 0.01371110078340, 0.0015579081634 [...]
+0.04169802746791, 0.05105292102523, -0.03653013164974, 0.05323681630826, 0.05322433439424, -0.06161913050027, 0.06316887617837, 0.07462272788890, -0.05605729667571, 0.09733017222613, 0.09041357753814, 0.07210126160498, -0.02658902847591, -0.12535024958029, 0.06683312417585, -0.09766849275778, 0.09039717566130, -0.09766849275778, 0.06683312417585, -0.12535024958029, -0.02658902847591, 0.07210126160498, 0.09041357753814, 0.09733017222613, -0.05605729667571, 0.07462272788890, 0.063168876178 [...]
+0.04309315116934, 0.03250874444113, -0.05398199531481, 0.00801021034064, 0.00027003849811, -0.05761715944068, 0.00155790816347, 0.01371110078340, -0.08813390430467, 0.06717547808897, 0.10156554753512, -0.04599388822189, 0.10061964911512, 0.01504573058692, 0.17112027276390, -0.18799488548807, -0.09766849275778, -0.18799488548807, 0.17112027276390, 0.01504573058692, 0.10061964911512, -0.04599388822189, 0.10156554753512, 0.06717547808897, -0.08813390430467, 0.01371110078340, 0.0015579081634 [...]
+-0.04548829345483, -0.03755053092747, 0.05428131739349, -0.01598181558280, -0.00905987177209, 0.06145323689284, -0.01180521143300, -0.02442011476440, 0.08701085516538, -0.07494530013047, -0.10348456280590, 0.02834885437642, -0.08232980948645, 0.00693420455927, -0.15403806518312, 0.17112027276390, 0.06683312417585, 0.17112027276390, -0.15403806518312, 0.00693420455927, -0.08232980948645, 0.02834885437642, -0.10348456280590, -0.07494530013047, 0.08701085516538, -0.02442011476440, -0.011805 [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+-0.04567030131908, -0.04899968532023, 0.04507008450281, -0.04211210676874, -0.03931525868965, 0.06377948953705, -0.04628401868063, -0.05782350471105, 0.06720841455530, -0.08813390430467, -0.09172320431048, -0.03399633247860, -0.01132895341962, 0.07210126160498, -0.08232980948645, 0.10061964911512, -0.02658902847591, 0.10061964911512, -0.08232980948645, 0.07210126160498, -0.01132895341962, -0.03399633247860, -0.09172320431048, -0.08813390430467, 0.06720841455530, -0.05782350471105, -0.046 [...]
+0.03644296273535, 0.04741800568147, -0.02912466965015, 0.05259259692296, 0.05323681630826, -0.05260385601595, 0.06145323689284, 0.06969057246245, -0.04040858119196, 0.07992564670887, 0.06656064247057, 0.06717547808897, -0.03399633247860, -0.09751182812518, 0.02834885437642, -0.04599388822189, 0.07210126160498, -0.04599388822189, 0.02834885437642, -0.09751182812518, -0.03399633247860, 0.06717547808897, 0.06656064247057, 0.07992564670887, -0.04040858119196, 0.06969057246245, 0.061453236892 [...]
+-0.02788397290880, -0.01159092756416, 0.04178512556283, 0.01610767548006, 0.02416013744322, 0.03277758616341, 0.02642596318589, 0.01848943615820, 0.06316887617837, -0.02442011476440, -0.05771185029271, 0.06656064247057, -0.09172320431048, -0.05169023594242, -0.10348456280590, 0.10156554753512, 0.09041357753814, 0.10156554753512, -0.10348456280590, -0.05169023594242, -0.09172320431048, 0.06656064247057, -0.05771185029271, -0.02442011476440, 0.06316887617837, 0.01848943615820, 0.0264259631 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+0.03501492614272, 0.02264757303314, -0.04548829345483, -0.00153126021194, -0.00866167202085, -0.04211210676874, -0.00864631825412, 0.00027003849811, -0.06399728423775, 0.03895560265498, 0.06316887617837, -0.04040858119196, 0.06720841455530, 0.02127053092509, 0.08701085516538, -0.08813390430467, -0.05605729667571, -0.08813390430467, 0.08701085516538, 0.02127053092509, 0.06720841455530, -0.04040858119196, 0.06316887617837, 0.03895560265498, -0.06399728423775, 0.00027003849811, -0.008646318 [...]
+0.01485220652451, 0.03105894328301, -0.00222561996695, 0.04741800568147, 0.05105292102523, -0.02333152061039, 0.05634488400998, 0.05742081875151, 0.00027003849811, 0.04273731697500, 0.01848943615820, 0.06969057246245, -0.05782350471105, -0.07747405815543, -0.02442011476440, 0.01371110078340, 0.07462272788890, 0.01371110078340, -0.02442011476440, -0.07747405815543, -0.05782350471105, 0.06969057246245, 0.01848943615820, 0.04273731697500, 0.00027003849811, 0.05742081875151, 0.05634488400998 [...]
+0.02011120046566, 0.03447279299858, -0.00889141691347, 0.04703493050962, 0.04945313461415, -0.02912466965015, 0.05428131739349, 0.05634488400998, -0.00864631825412, 0.04683219028095, 0.02642596318589, 0.06145323689284, -0.04628401868063, -0.07081173873106, -0.01180521143300, 0.00155790816347, 0.06316887617837, 0.00155790816347, -0.01180521143300, -0.07081173873106, -0.04628401868063, 0.06145323689284, 0.02642596318589, 0.04683219028095, -0.00864631825412, 0.05634488400998, 0.054281317393 [...]
+0.01871143836380, 0.00282925577496, -0.03115444796200, -0.02111691650473, -0.02743053076570, -0.01909407501789, -0.02912466965015, -0.02333152061039, -0.04211210676874, 0.00801021034064, 0.03277758616341, -0.05260385601595, 0.06377948953705, 0.04273731697500, 0.06145323689284, -0.05761715944068, -0.06161913050027, -0.05761715944068, 0.06145323689284, 0.04273731697500, 0.06377948953705, -0.05260385601595, 0.03277758616341, 0.00801021034064, -0.04211210676874, -0.02333152061039, -0.0291246 [...]
+-0.00751015358970, 0.00913503411448, 0.02051771641111, 0.03105894328301, 0.03644296273535, 0.00493640288370, 0.03893806094712, 0.03510685742783, 0.02847526258331, 0.00864062075235, -0.01598181558280, 0.05742081875151, -0.06076173352856, -0.05260385601595, -0.04836796828267, 0.04244418660272, 0.06377948953705, 0.04244418660272, -0.04836796828267, -0.05260385601595, -0.06076173352856, 0.05742081875151, -0.01598181558280, 0.00864062075235, 0.02847526258331, 0.03510685742783, 0.0389380609471 [...]
+0.03785607654408, 0.02991156721912, -0.04410886072389, 0.01076407940667, 0.00493640288370, -0.04513877691637, 0.00629983820314, 0.01466865762037, -0.05728294659133, 0.04496452881899, 0.05946062873198, -0.01764835261303, 0.04273731697500, -0.00086468661469, 0.06584304685785, -0.06883698723352, -0.02803496562843, -0.06883698723352, 0.06584304685785, -0.00086468661469, 0.04273731697500, -0.01764835261303, 0.05946062873198, 0.04496452881899, -0.05728294659133, 0.01466865762037, 0.00629983820 [...]
+-0.00866995656907, 0.00896875039683, 0.02264757303314, 0.03282161335501, 0.03893806094712, 0.00629983820314, 0.04222968115101, 0.03821264299440, 0.03277758616341, 0.00869067734621, -0.01933288371895, 0.06584304685785, -0.07081173873106, -0.06095484289857, -0.05782350471105, 0.05116991106925, 0.07536267012088, 0.05116991106925, -0.05782350471105, -0.06095484289857, -0.07081173873106, 0.06584304685785, -0.01933288371895, 0.00869067734621, 0.03277758616341, 0.03821264299440, 0.0422296811510 [...]
+-0.01509084125054, 0.00253986035635, 0.02926181365419, 0.02821667474258, 0.03510685742783, 0.01466865762037, 0.03821264299440, 0.03296691756242, 0.04244418660272, -0.00086468661469, -0.03067019176029, 0.06698830614494, -0.07747405815543, -0.05912294255307, -0.07051895298226, 0.06486285706603, 0.07992564670887, 0.06486285706603, -0.07051895298226, -0.05912294255307, -0.07747405815543, 0.06698830614494, -0.03067019176029, -0.00086468661469, 0.04244418660272, 0.03296691756242, 0.03821264299 [...]
+0.04384574828821, 0.04364554753736, -0.04499172586632, 0.03250874444113, 0.02847526258331, -0.05728294659133, 0.03277758616341, 0.04244418660272, -0.06161913050027, 0.06969057246245, 0.07536267012088, 0.01371110078340, 0.02127053092509, -0.03929438261949, 0.06656064247057, -0.07614567822515, 0.00344457002262, -0.07614567822515, 0.06656064247057, -0.03929438261949, 0.02127053092509, 0.01371110078340, 0.07536267012088, 0.06969057246245, -0.06161913050027, 0.04244418660272, 0.03277758616341 [...]
+-0.03645408668750, -0.02387116439873, 0.04755584645599, 0.00114288282262, 0.00864062075235, 0.04496452881899, 0.00869067734621, -0.00086468661469, 0.06969057246245, -0.04330187825715, -0.07051895298226, 0.04485675423343, -0.07614567822515, -0.02381038314910, -0.10125366504812, 0.10334674409940, 0.06525950351177, 0.10334674409940, -0.10125366504812, -0.02381038314910, -0.07614567822515, 0.04485675423343, -0.07051895298226, -0.04330187825715, 0.06969057246245, -0.00086468661469, 0.00869067 [...]
+-0.04512890076845, -0.03980537034422, 0.05105292102523, -0.02183846096527, -0.01598181558280, 0.05946062873198, -0.01933288371895, -0.03067019176029, 0.07536267012088, -0.07051895298226, -0.08813390430467, 0.00998778878484, -0.05169023594242, 0.02003044394070, -0.10150612803431, 0.11129083655510, 0.02834885437642, 0.11129083655510, -0.10150612803431, 0.02003044394070, -0.05169023594242, 0.00998778878484, -0.08813390430467, -0.07051895298226, 0.07536267012088, -0.03067019176029, -0.019332 [...]
+0.00881974876440, 0.02821667474258, 0.00629983820314, 0.05121834474517, 0.05742081875151, -0.01764835261303, 0.06584304685785, 0.06698830614494, 0.01371110078340, 0.04485675423343, 0.00998778878484, 0.10334674409940, -0.09751182812518, -0.11954033404934, -0.05916188988776, 0.04399094217963, 0.13297118107692, 0.04399094217963, -0.05916188988776, -0.11954033404934, -0.09751182812518, 0.10334674409940, 0.00998778878484, 0.04485675423343, 0.01371110078340, 0.06698830614494, 0.06584304685785, [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+0.00493640288370, -0.01578529983234, -0.02183846096527, -0.04431851921725, -0.05260385601595, -0.00086468661469, -0.06095484289857, -0.05912294255307, -0.03929438261949, -0.02381038314910, 0.02003044394070, -0.11954033404934, 0.13297118107692, 0.13658472451851, 0.11717778964385, -0.10570143114241, -0.18799488548807, -0.10570143114241, 0.11717778964385, 0.13658472451851, 0.13297118107692, -0.11954033404934, 0.02003044394070, -0.02381038314910, -0.03929438261949, -0.05912294255307, -0.0609 [...]
+-0.04499172586632, -0.05170195653292, 0.04222968115101, -0.04963002409968, -0.04836796828267, 0.06584304685785, -0.05782350471105, -0.07051895298226, 0.06656064247057, -0.10125366504812, -0.10150612803431, -0.05916188988776, 0.00693420455927, 0.11717778964385, -0.09766849275778, 0.13337515469879, -0.07031805212178, 0.13337515469879, -0.09766849275778, 0.11717778964385, 0.00693420455927, -0.05916188988776, -0.10150612803431, -0.10125366504812, 0.06656064247057, -0.07051895298226, -0.05782 [...]
+0.04741800568147, 0.05131960071511, -0.04716218793354, 0.04496452881899, 0.04244418660272, -0.06883698723352, 0.05116991106925, 0.06486285706603, -0.07614567822515, 0.10334674409940, 0.11129083655510, 0.04399094217963, 0.01504573058692, -0.10570143114241, 0.13337515469879, -0.17678529895672, 0.04347274616886, -0.17678529895672, 0.13337515469879, -0.10570143114241, 0.01504573058692, 0.04399094217963, 0.11129083655510, 0.10334674409940, -0.07614567822515, 0.06486285706603, 0.05116991106925 [...]
+0.01552199992789, 0.03510685742783, -0.00071933672845, 0.05742081875151, 0.06377948953705, -0.02803496562843, 0.07536267012088, 0.07992564670887, 0.00344457002262, 0.06525950351177, 0.02834885437642, 0.13297118107692, -0.12535024958029, -0.18799488548807, -0.07031805212178, 0.04347274616886, 0.24531178657333, 0.04347274616886, -0.07031805212178, -0.18799488548807, -0.12535024958029, 0.13297118107692, 0.02834885437642, 0.06525950351177, 0.00344457002262, 0.07992564670887, 0.07536267012088 [...]
+0.04741800568147, 0.05131960071511, -0.04716218793354, 0.04496452881899, 0.04244418660272, -0.06883698723352, 0.05116991106925, 0.06486285706603, -0.07614567822515, 0.10334674409940, 0.11129083655510, 0.04399094217963, 0.01504573058692, -0.10570143114241, 0.13337515469879, -0.17678529895672, 0.04347274616886, -0.17678529895672, 0.13337515469879, -0.10570143114241, 0.01504573058692, 0.04399094217963, 0.11129083655510, 0.10334674409940, -0.07614567822515, 0.06486285706603, 0.05116991106925 [...]
+-0.04499172586632, -0.05170195653292, 0.04222968115101, -0.04963002409968, -0.04836796828267, 0.06584304685785, -0.05782350471105, -0.07051895298226, 0.06656064247057, -0.10125366504812, -0.10150612803431, -0.05916188988776, 0.00693420455927, 0.11717778964385, -0.09766849275778, 0.13337515469879, -0.07031805212178, 0.13337515469879, -0.09766849275778, 0.11717778964385, 0.00693420455927, -0.05916188988776, -0.10150612803431, -0.10125366504812, 0.06656064247057, -0.07051895298226, -0.05782 [...]
+0.00493640288370, -0.01578529983234, -0.02183846096527, -0.04431851921725, -0.05260385601595, -0.00086468661469, -0.06095484289857, -0.05912294255307, -0.03929438261949, -0.02381038314910, 0.02003044394070, -0.11954033404934, 0.13297118107692, 0.13658472451851, 0.11717778964385, -0.10570143114241, -0.18799488548807, -0.10570143114241, 0.11717778964385, 0.13658472451851, 0.13297118107692, -0.11954033404934, 0.02003044394070, -0.02381038314910, -0.03929438261949, -0.05912294255307, -0.0609 [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+0.00881974876440, 0.02821667474258, 0.00629983820314, 0.05121834474517, 0.05742081875151, -0.01764835261303, 0.06584304685785, 0.06698830614494, 0.01371110078340, 0.04485675423343, 0.00998778878484, 0.10334674409940, -0.09751182812518, -0.11954033404934, -0.05916188988776, 0.04399094217963, 0.13297118107692, 0.04399094217963, -0.05916188988776, -0.11954033404934, -0.09751182812518, 0.10334674409940, 0.00998778878484, 0.04485675423343, 0.01371110078340, 0.06698830614494, 0.06584304685785, [...]
+-0.04512890076845, -0.03980537034422, 0.05105292102523, -0.02183846096527, -0.01598181558280, 0.05946062873198, -0.01933288371895, -0.03067019176029, 0.07536267012088, -0.07051895298226, -0.08813390430467, 0.00998778878484, -0.05169023594242, 0.02003044394070, -0.10150612803431, 0.11129083655510, 0.02834885437642, 0.11129083655510, -0.10150612803431, 0.02003044394070, -0.05169023594242, 0.00998778878484, -0.08813390430467, -0.07051895298226, 0.07536267012088, -0.03067019176029, -0.019332 [...]
+-0.03645408668750, -0.02387116439873, 0.04755584645599, 0.00114288282262, 0.00864062075235, 0.04496452881899, 0.00869067734621, -0.00086468661469, 0.06969057246245, -0.04330187825715, -0.07051895298226, 0.04485675423343, -0.07614567822515, -0.02381038314910, -0.10125366504812, 0.10334674409940, 0.06525950351177, 0.10334674409940, -0.10125366504812, -0.02381038314910, -0.07614567822515, 0.04485675423343, -0.07051895298226, -0.04330187825715, 0.06969057246245, -0.00086468661469, 0.00869067 [...]
+0.04384574828821, 0.04364554753736, -0.04499172586632, 0.03250874444113, 0.02847526258331, -0.05728294659133, 0.03277758616341, 0.04244418660272, -0.06161913050027, 0.06969057246245, 0.07536267012088, 0.01371110078340, 0.02127053092509, -0.03929438261949, 0.06656064247057, -0.07614567822515, 0.00344457002262, -0.07614567822515, 0.06656064247057, -0.03929438261949, 0.02127053092509, 0.01371110078340, 0.07536267012088, 0.06969057246245, -0.06161913050027, 0.04244418660272, 0.03277758616341 [...]
+-0.01509084125054, 0.00253986035635, 0.02926181365419, 0.02821667474258, 0.03510685742783, 0.01466865762037, 0.03821264299440, 0.03296691756242, 0.04244418660272, -0.00086468661469, -0.03067019176029, 0.06698830614494, -0.07747405815543, -0.05912294255307, -0.07051895298226, 0.06486285706603, 0.07992564670887, 0.06486285706603, -0.07051895298226, -0.05912294255307, -0.07747405815543, 0.06698830614494, -0.03067019176029, -0.00086468661469, 0.04244418660272, 0.03296691756242, 0.03821264299 [...]
+-0.00866995656907, 0.00896875039683, 0.02264757303314, 0.03282161335501, 0.03893806094712, 0.00629983820314, 0.04222968115101, 0.03821264299440, 0.03277758616341, 0.00869067734621, -0.01933288371895, 0.06584304685785, -0.07081173873106, -0.06095484289857, -0.05782350471105, 0.05116991106925, 0.07536267012088, 0.05116991106925, -0.05782350471105, -0.06095484289857, -0.07081173873106, 0.06584304685785, -0.01933288371895, 0.00869067734621, 0.03277758616341, 0.03821264299440, 0.0422296811510 [...]
+0.03785607654408, 0.02991156721912, -0.04410886072389, 0.01076407940667, 0.00493640288370, -0.04513877691637, 0.00629983820314, 0.01466865762037, -0.05728294659133, 0.04496452881899, 0.05946062873198, -0.01764835261303, 0.04273731697500, -0.00086468661469, 0.06584304685785, -0.06883698723352, -0.02803496562843, -0.06883698723352, 0.06584304685785, -0.00086468661469, 0.04273731697500, -0.01764835261303, 0.05946062873198, 0.04496452881899, -0.05728294659133, 0.01466865762037, 0.00629983820 [...]
+0.03522641326574, 0.04123067549901, -0.03031839687312, 0.03963047977889, 0.03804111121964, -0.04499172586632, 0.04178512556283, 0.04745915084934, -0.03653013164974, 0.05634488400998, 0.04963142214735, 0.03277758616341, -0.00905987177209, -0.04836796828267, 0.02642596318589, -0.03484669808203, 0.02780036340898, -0.03484669808203, 0.02642596318589, -0.04836796828267, -0.00905987177209, 0.03277758616341, 0.04963142214735, 0.05634488400998, -0.03653013164974, 0.04745915084934, 0.041785125562 [...]
+-0.00338379798127, -0.02040531295214, -0.01000868479601, -0.04031243635006, -0.04499172586632, 0.00870175468576, -0.04883456542052, -0.04716218793354, -0.01598181558280, -0.02516948075949, 0.00027003849811, -0.06514516365773, 0.06145323689284, 0.06584304685785, 0.03895560265498, -0.03067019176029, -0.07081173873106, -0.03067019176029, 0.03895560265498, 0.06584304685785, 0.06145323689284, -0.06514516365773, 0.00027003849811, -0.02516948075949, -0.01598181558280, -0.04716218793354, -0.0488 [...]
+0.03697036111778, 0.04384574828821, -0.03188743137750, 0.04309315116934, 0.04178512556283, -0.04883456542052, 0.04661358044050, 0.05323681630826, -0.04023894554545, 0.06377948953705, 0.05627305279151, 0.03895560265498, -0.01180521143300, -0.05782350471105, 0.03017589095093, -0.04040858119196, 0.03433801412888, -0.04040858119196, 0.03017589095093, -0.05782350471105, -0.01180521143300, 0.03895560265498, 0.05627305279151, 0.06377948953705, -0.04023894554545, 0.05323681630826, 0.046613580440 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+0.01595838913427, -0.00222561996695, -0.03079225925144, -0.02912466965015, -0.03653013164974, -0.01598181558280, -0.04023894554545, -0.03484669808203, -0.04628401868063, 0.00155790816347, 0.03433801412888, -0.07419862922226, 0.08701085516538, 0.06656064247057, 0.08094445627940, -0.07494530013047, -0.09172320431048, -0.07494530013047, 0.08094445627940, 0.06656064247057, 0.08701085516538, -0.07419862922226, 0.03433801412888, 0.00155790816347, -0.04628401868063, -0.03484669808203, -0.040238 [...]
+0.01512570665415, 0.03282161335501, -0.00153126021194, 0.05166746230846, 0.05634488400998, -0.02516948075949, 0.06377948953705, 0.06584304685785, 0.00155790816347, 0.05012494613301, 0.02127053092509, 0.08752809455106, -0.07494530013047, -0.10125366504812, -0.03399633247860, 0.02003044394070, 0.10156554753512, 0.02003044394070, -0.03399633247860, -0.10125366504812, -0.07494530013047, 0.08752809455106, 0.02127053092509, 0.05012494613301, 0.00155790816347, 0.06584304685785, 0.06377948953705 [...]
+-0.00434559103408, 0.01552199992789, 0.02038138287138, 0.04222968115101, 0.04963142214735, 0.00027003849811, 0.05627305279151, 0.05387660966815, 0.03433801412888, 0.02127053092509, -0.01626781358073, 0.09733017222613, -0.10348456280590, -0.10150612803431, -0.08280335937603, 0.07210126160498, 0.12603831803759, 0.07210126160498, -0.08280335937603, -0.10150612803431, -0.10348456280590, 0.09733017222613, -0.01626781358073, 0.02127053092509, 0.03433801412888, 0.05387660966815, 0.0562730527915 [...]
+0.04703493050962, 0.04755584645599, -0.04883456542052, 0.03669569988478, 0.03277758616341, -0.06514516365773, 0.03895560265498, 0.05116991106925, -0.07419862922226, 0.08752809455106, 0.09733017222613, 0.02003044394070, 0.02834885437642, -0.05916188988776, 0.10061964911512, -0.11875106261662, 0.00693420455927, -0.11875106261662, 0.10061964911512, -0.05916188988776, 0.02834885437642, 0.02003044394070, 0.09733017222613, 0.08752809455106, -0.07419862922226, 0.05116991106925, 0.03895560265498 [...]
+-0.04548829345483, -0.03755053092747, 0.05428131739349, -0.01598181558280, -0.00905987177209, 0.06145323689284, -0.01180521143300, -0.02442011476440, 0.08701085516538, -0.07494530013047, -0.10348456280590, 0.02834885437642, -0.08232980948645, 0.00693420455927, -0.15403806518312, 0.17112027276390, 0.06683312417585, 0.17112027276390, -0.15403806518312, 0.00693420455927, -0.08232980948645, 0.02834885437642, -0.10348456280590, -0.07494530013047, 0.08701085516538, -0.02442011476440, -0.011805 [...]
+-0.04499172586632, -0.05170195653292, 0.04222968115101, -0.04963002409968, -0.04836796828267, 0.06584304685785, -0.05782350471105, -0.07051895298226, 0.06656064247057, -0.10125366504812, -0.10150612803431, -0.05916188988776, 0.00693420455927, 0.11717778964385, -0.09766849275778, 0.13337515469879, -0.07031805212178, 0.13337515469879, -0.09766849275778, 0.11717778964385, 0.00693420455927, -0.05916188988776, -0.10150612803431, -0.10125366504812, 0.06656064247057, -0.07051895298226, -0.05782 [...]
+-0.03079225925144, -0.01352102709593, 0.04661358044050, 0.01700752911701, 0.02642596318589, 0.03895560265498, 0.03017589095093, 0.02127053092509, 0.08094445627940, -0.03399633247860, -0.08280335937603, 0.10061964911512, -0.15403806518312, -0.09766849275778, -0.22344710449063, 0.24531178657333, 0.23463634685391, 0.24531178657333, -0.22344710449063, -0.09766849275778, -0.15403806518312, 0.10061964911512, -0.08280335937603, -0.03399633247860, 0.08094445627940, 0.02127053092509, 0.0301758909 [...]
+0.02522891682511, 0.00629983820314, -0.04211210676874, -0.02516948075949, -0.03484669808203, -0.03067019176029, -0.04040858119196, -0.03318526107069, -0.07494530013047, 0.02003044394070, 0.07210126160498, -0.11875106261662, 0.17112027276390, 0.13337515469879, 0.24531178657333, -0.27668385812757, -0.32757913759147, -0.27668385812757, 0.24531178657333, 0.13337515469879, 0.17112027276390, -0.11875106261662, 0.07210126160498, 0.02003044394070, -0.07494530013047, -0.03318526107069, -0.0404085 [...]
+0.04945313461415, 0.04745915084934, -0.05430453818238, 0.03277758616341, 0.02780036340898, -0.07081173873106, 0.03433801412888, 0.04915146033489, -0.09172320431048, 0.10156554753512, 0.12603831803759, 0.00693420455927, 0.06683312417585, -0.07031805212178, 0.23463634685391, -0.32757913759147, -0.06604332802355, -0.32757913759147, 0.23463634685391, -0.07031805212178, 0.06683312417585, 0.00693420455927, 0.12603831803759, 0.10156554753512, -0.09172320431048, 0.04915146033489, 0.0343380141288 [...]
+0.02522891682511, 0.00629983820314, -0.04211210676874, -0.02516948075949, -0.03484669808203, -0.03067019176029, -0.04040858119196, -0.03318526107069, -0.07494530013047, 0.02003044394070, 0.07210126160498, -0.11875106261662, 0.17112027276390, 0.13337515469879, 0.24531178657333, -0.27668385812757, -0.32757913759147, -0.27668385812757, 0.24531178657333, 0.13337515469879, 0.17112027276390, -0.11875106261662, 0.07210126160498, 0.02003044394070, -0.07494530013047, -0.03318526107069, -0.0404085 [...]
+-0.03079225925144, -0.01352102709593, 0.04661358044050, 0.01700752911701, 0.02642596318589, 0.03895560265498, 0.03017589095093, 0.02127053092509, 0.08094445627940, -0.03399633247860, -0.08280335937603, 0.10061964911512, -0.15403806518312, -0.09766849275778, -0.22344710449063, 0.24531178657333, 0.23463634685391, 0.24531178657333, -0.22344710449063, -0.09766849275778, -0.15403806518312, 0.10061964911512, -0.08280335937603, -0.03399633247860, 0.08094445627940, 0.02127053092509, 0.0301758909 [...]
+-0.04499172586632, -0.05170195653292, 0.04222968115101, -0.04963002409968, -0.04836796828267, 0.06584304685785, -0.05782350471105, -0.07051895298226, 0.06656064247057, -0.10125366504812, -0.10150612803431, -0.05916188988776, 0.00693420455927, 0.11717778964385, -0.09766849275778, 0.13337515469879, -0.07031805212178, 0.13337515469879, -0.09766849275778, 0.11717778964385, 0.00693420455927, -0.05916188988776, -0.10150612803431, -0.10125366504812, 0.06656064247057, -0.07051895298226, -0.05782 [...]
+-0.04548829345483, -0.03755053092747, 0.05428131739349, -0.01598181558280, -0.00905987177209, 0.06145323689284, -0.01180521143300, -0.02442011476440, 0.08701085516538, -0.07494530013047, -0.10348456280590, 0.02834885437642, -0.08232980948645, 0.00693420455927, -0.15403806518312, 0.17112027276390, 0.06683312417585, 0.17112027276390, -0.15403806518312, 0.00693420455927, -0.08232980948645, 0.02834885437642, -0.10348456280590, -0.07494530013047, 0.08701085516538, -0.02442011476440, -0.011805 [...]
+0.04703493050962, 0.04755584645599, -0.04883456542052, 0.03669569988478, 0.03277758616341, -0.06514516365773, 0.03895560265498, 0.05116991106925, -0.07419862922226, 0.08752809455106, 0.09733017222613, 0.02003044394070, 0.02834885437642, -0.05916188988776, 0.10061964911512, -0.11875106261662, 0.00693420455927, -0.11875106261662, 0.10061964911512, -0.05916188988776, 0.02834885437642, 0.02003044394070, 0.09733017222613, 0.08752809455106, -0.07419862922226, 0.05116991106925, 0.03895560265498 [...]
+-0.00434559103408, 0.01552199992789, 0.02038138287138, 0.04222968115101, 0.04963142214735, 0.00027003849811, 0.05627305279151, 0.05387660966815, 0.03433801412888, 0.02127053092509, -0.01626781358073, 0.09733017222613, -0.10348456280590, -0.10150612803431, -0.08280335937603, 0.07210126160498, 0.12603831803759, 0.07210126160498, -0.08280335937603, -0.10150612803431, -0.10348456280590, 0.09733017222613, -0.01626781358073, 0.02127053092509, 0.03433801412888, 0.05387660966815, 0.0562730527915 [...]
+0.01512570665415, 0.03282161335501, -0.00153126021194, 0.05166746230846, 0.05634488400998, -0.02516948075949, 0.06377948953705, 0.06584304685785, 0.00155790816347, 0.05012494613301, 0.02127053092509, 0.08752809455106, -0.07494530013047, -0.10125366504812, -0.03399633247860, 0.02003044394070, 0.10156554753512, 0.02003044394070, -0.03399633247860, -0.10125366504812, -0.07494530013047, 0.08752809455106, 0.02127053092509, 0.05012494613301, 0.00155790816347, 0.06584304685785, 0.06377948953705 [...]
+0.01595838913427, -0.00222561996695, -0.03079225925144, -0.02912466965015, -0.03653013164974, -0.01598181558280, -0.04023894554545, -0.03484669808203, -0.04628401868063, 0.00155790816347, 0.03433801412888, -0.07419862922226, 0.08701085516538, 0.06656064247057, 0.08094445627940, -0.07494530013047, -0.09172320431048, -0.07494530013047, 0.08094445627940, 0.06656064247057, 0.08701085516538, -0.07419862922226, 0.03433801412888, 0.00155790816347, -0.04628401868063, -0.03484669808203, -0.040238 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+0.03697036111778, 0.04384574828821, -0.03188743137750, 0.04309315116934, 0.04178512556283, -0.04883456542052, 0.04661358044050, 0.05323681630826, -0.04023894554545, 0.06377948953705, 0.05627305279151, 0.03895560265498, -0.01180521143300, -0.05782350471105, 0.03017589095093, -0.04040858119196, 0.03433801412888, -0.04040858119196, 0.03017589095093, -0.05782350471105, -0.01180521143300, 0.03895560265498, 0.05627305279151, 0.06377948953705, -0.04023894554545, 0.05323681630826, 0.046613580440 [...]
+-0.00338379798127, -0.02040531295214, -0.01000868479601, -0.04031243635006, -0.04499172586632, 0.00870175468576, -0.04883456542052, -0.04716218793354, -0.01598181558280, -0.02516948075949, 0.00027003849811, -0.06514516365773, 0.06145323689284, 0.06584304685785, 0.03895560265498, -0.03067019176029, -0.07081173873106, -0.03067019176029, 0.03895560265498, 0.06584304685785, 0.06145323689284, -0.06514516365773, 0.00027003849811, -0.02516948075949, -0.01598181558280, -0.04716218793354, -0.0488 [...]
+-0.03759634244848, -0.04135242996492, 0.03447279299858, -0.03645408668750, -0.03401426025387, 0.04741800568147, -0.03755053092747, -0.04403132364326, 0.04222968115101, -0.05728294659133, -0.05403298716581, -0.02546580226758, 0.00027003849811, 0.04244418660272, -0.03484669808203, 0.04273731697500, -0.01933288371895, 0.04273731697500, -0.03484669808203, 0.04244418660272, 0.00027003849811, -0.02546580226758, -0.05403298716581, -0.05728294659133, 0.04222968115101, -0.04403132364326, -0.03755 [...]
+0.00913503411448, 0.02559637848431, 0.00380202623900, 0.04341150826710, 0.04741800568147, -0.01578529983234, 0.05166746230846, 0.05121834474517, 0.00801021034064, 0.03296691756242, 0.00869067734621, 0.06522696614589, -0.05761715944068, -0.06883698723352, -0.03067019176029, 0.02156735149891, 0.06969057246245, 0.02156735149891, -0.03067019176029, -0.06883698723352, -0.05761715944068, 0.06522696614589, 0.00869067734621, 0.03296691756242, 0.00801021034064, 0.05121834474517, 0.05166746230846, [...]
+-0.03959381766328, -0.04410886072389, 0.03644296273535, -0.03980537034422, -0.03755053092747, 0.05166746230846, -0.04211210676874, -0.04963002409968, 0.04683219028095, -0.06514516365773, -0.06161913050027, -0.03067019176029, 0.00155790816347, 0.05116991106925, -0.04040858119196, 0.05012494613301, -0.02442011476440, 0.05012494613301, -0.04040858119196, 0.05116991106925, 0.00155790816347, -0.03067019176029, -0.06161913050027, -0.06514516365773, 0.04683219028095, -0.04963002409968, -0.04211 [...]
+-0.03797145192049, -0.04535566616530, 0.03282161335501, -0.04513877691637, -0.04403132364326, 0.05121834474517, -0.04963002409968, -0.05693896917516, 0.04273731697500, -0.06883698723352, -0.06095484289857, -0.04330187825715, 0.01371110078340, 0.06486285706603, -0.03318526107069, 0.04485675423343, -0.03929438261949, 0.04485675423343, -0.03318526107069, 0.06486285706603, 0.01371110078340, -0.04330187825715, -0.06095484289857, -0.06883698723352, 0.04273731697500, -0.05693896917516, -0.04963 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+-0.00222561996695, -0.02205338028065, -0.01352102709593, -0.04716218793354, -0.05403298716581, 0.00869067734621, -0.06161913050027, -0.06095484289857, -0.02442011476440, -0.03318526107069, 0.00344457002262, -0.10125366504812, 0.10156554753512, 0.11129083655510, 0.07210126160498, -0.05916188988776, -0.13058003873376, -0.05916188988776, 0.07210126160498, 0.11129083655510, 0.10156554753512, -0.10125366504812, 0.00344457002262, -0.03318526107069, -0.02442011476440, -0.06095484289857, -0.0616 [...]
+-0.04746872842254, -0.04513877691637, 0.05166746230846, -0.03045828585214, -0.02546580226758, 0.06522696614589, -0.03067019176029, -0.04330187825715, 0.07992564670887, -0.08513999504483, -0.10125366504812, -0.00486213436803, -0.04599388822189, 0.04399094217963, -0.11875106261662, 0.13658472451851, 0.01504573058692, 0.13658472451851, -0.11875106261662, 0.04399094217963, -0.04599388822189, -0.00486213436803, -0.10125366504812, -0.08513999504483, 0.07992564670887, -0.04330187825715, -0.0306 [...]
+0.04309315116934, 0.03250874444113, -0.05398199531481, 0.00801021034064, 0.00027003849811, -0.05761715944068, 0.00155790816347, 0.01371110078340, -0.08813390430467, 0.06717547808897, 0.10156554753512, -0.04599388822189, 0.10061964911512, 0.01504573058692, 0.17112027276390, -0.18799488548807, -0.09766849275778, -0.18799488548807, 0.17112027276390, 0.01504573058692, 0.10061964911512, -0.04599388822189, 0.10156554753512, 0.06717547808897, -0.08813390430467, 0.01371110078340, 0.0015579081634 [...]
+0.04741800568147, 0.05131960071511, -0.04716218793354, 0.04496452881899, 0.04244418660272, -0.06883698723352, 0.05116991106925, 0.06486285706603, -0.07614567822515, 0.10334674409940, 0.11129083655510, 0.04399094217963, 0.01504573058692, -0.10570143114241, 0.13337515469879, -0.17678529895672, 0.04347274616886, -0.17678529895672, 0.13337515469879, -0.10570143114241, 0.01504573058692, 0.04399094217963, 0.11129083655510, 0.10334674409940, -0.07614567822515, 0.06486285706603, 0.05116991106925 [...]
+0.02522891682511, 0.00629983820314, -0.04211210676874, -0.02516948075949, -0.03484669808203, -0.03067019176029, -0.04040858119196, -0.03318526107069, -0.07494530013047, 0.02003044394070, 0.07210126160498, -0.11875106261662, 0.17112027276390, 0.13337515469879, 0.24531178657333, -0.27668385812757, -0.32757913759147, -0.27668385812757, 0.24531178657333, 0.13337515469879, 0.17112027276390, -0.11875106261662, 0.07210126160498, 0.02003044394070, -0.07494530013047, -0.03318526107069, -0.0404085 [...]
+-0.01909407501789, 0.00114288282262, 0.03669569988478, 0.03296691756242, 0.04273731697500, 0.02156735149891, 0.05012494613301, 0.04485675423343, 0.06717547808897, -0.00486213436803, -0.05916188988776, 0.13658472451851, -0.18799488548807, -0.17678529895672, -0.27668385812757, 0.33905895852594, 0.57672480775687, 0.33905895852594, -0.27668385812757, -0.17678529895672, -0.18799488548807, 0.13658472451851, -0.05916188988776, -0.00486213436803, 0.06717547808897, 0.04485675423343, 0.05012494613 [...]
+-0.04899968532023, -0.04403132364326, 0.05634488400998, -0.02546580226758, -0.01933288371895, 0.06969057246245, -0.02442011476440, -0.03929438261949, 0.09733017222613, -0.09751182812518, -0.13058003873376, 0.01504573058692, -0.09766849275778, 0.04347274616886, -0.32757913759147, 0.57672480775687, 0.44005058574493, 0.57672480775687, -0.32757913759147, 0.04347274616886, -0.09766849275778, 0.01504573058692, -0.13058003873376, -0.09751182812518, 0.09733017222613, -0.03929438261949, -0.024420 [...]
+-0.01909407501789, 0.00114288282262, 0.03669569988478, 0.03296691756242, 0.04273731697500, 0.02156735149891, 0.05012494613301, 0.04485675423343, 0.06717547808897, -0.00486213436803, -0.05916188988776, 0.13658472451851, -0.18799488548807, -0.17678529895672, -0.27668385812757, 0.33905895852594, 0.57672480775687, 0.33905895852594, -0.27668385812757, -0.17678529895672, -0.18799488548807, 0.13658472451851, -0.05916188988776, -0.00486213436803, 0.06717547808897, 0.04485675423343, 0.05012494613 [...]
+0.02522891682511, 0.00629983820314, -0.04211210676874, -0.02516948075949, -0.03484669808203, -0.03067019176029, -0.04040858119196, -0.03318526107069, -0.07494530013047, 0.02003044394070, 0.07210126160498, -0.11875106261662, 0.17112027276390, 0.13337515469879, 0.24531178657333, -0.27668385812757, -0.32757913759147, -0.27668385812757, 0.24531178657333, 0.13337515469879, 0.17112027276390, -0.11875106261662, 0.07210126160498, 0.02003044394070, -0.07494530013047, -0.03318526107069, -0.0404085 [...]
+0.04741800568147, 0.05131960071511, -0.04716218793354, 0.04496452881899, 0.04244418660272, -0.06883698723352, 0.05116991106925, 0.06486285706603, -0.07614567822515, 0.10334674409940, 0.11129083655510, 0.04399094217963, 0.01504573058692, -0.10570143114241, 0.13337515469879, -0.17678529895672, 0.04347274616886, -0.17678529895672, 0.13337515469879, -0.10570143114241, 0.01504573058692, 0.04399094217963, 0.11129083655510, 0.10334674409940, -0.07614567822515, 0.06486285706603, 0.05116991106925 [...]
+0.04309315116934, 0.03250874444113, -0.05398199531481, 0.00801021034064, 0.00027003849811, -0.05761715944068, 0.00155790816347, 0.01371110078340, -0.08813390430467, 0.06717547808897, 0.10156554753512, -0.04599388822189, 0.10061964911512, 0.01504573058692, 0.17112027276390, -0.18799488548807, -0.09766849275778, -0.18799488548807, 0.17112027276390, 0.01504573058692, 0.10061964911512, -0.04599388822189, 0.10156554753512, 0.06717547808897, -0.08813390430467, 0.01371110078340, 0.0015579081634 [...]
+-0.04746872842254, -0.04513877691637, 0.05166746230846, -0.03045828585214, -0.02546580226758, 0.06522696614589, -0.03067019176029, -0.04330187825715, 0.07992564670887, -0.08513999504483, -0.10125366504812, -0.00486213436803, -0.04599388822189, 0.04399094217963, -0.11875106261662, 0.13658472451851, 0.01504573058692, 0.13658472451851, -0.11875106261662, 0.04399094217963, -0.04599388822189, -0.00486213436803, -0.10125366504812, -0.08513999504483, 0.07992564670887, -0.04330187825715, -0.0306 [...]
+-0.00222561996695, -0.02205338028065, -0.01352102709593, -0.04716218793354, -0.05403298716581, 0.00869067734621, -0.06161913050027, -0.06095484289857, -0.02442011476440, -0.03318526107069, 0.00344457002262, -0.10125366504812, 0.10156554753512, 0.11129083655510, 0.07210126160498, -0.05916188988776, -0.13058003873376, -0.05916188988776, 0.07210126160498, 0.11129083655510, 0.10156554753512, -0.10125366504812, 0.00344457002262, -0.03318526107069, -0.02442011476440, -0.06095484289857, -0.0616 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+-0.03797145192049, -0.04535566616530, 0.03282161335501, -0.04513877691637, -0.04403132364326, 0.05121834474517, -0.04963002409968, -0.05693896917516, 0.04273731697500, -0.06883698723352, -0.06095484289857, -0.04330187825715, 0.01371110078340, 0.06486285706603, -0.03318526107069, 0.04485675423343, -0.03929438261949, 0.04485675423343, -0.03318526107069, 0.06486285706603, 0.01371110078340, -0.04330187825715, -0.06095484289857, -0.06883698723352, 0.04273731697500, -0.05693896917516, -0.04963 [...]
+-0.03959381766328, -0.04410886072389, 0.03644296273535, -0.03980537034422, -0.03755053092747, 0.05166746230846, -0.04211210676874, -0.04963002409968, 0.04683219028095, -0.06514516365773, -0.06161913050027, -0.03067019176029, 0.00155790816347, 0.05116991106925, -0.04040858119196, 0.05012494613301, -0.02442011476440, 0.05012494613301, -0.04040858119196, 0.05116991106925, 0.00155790816347, -0.03067019176029, -0.06161913050027, -0.06514516365773, 0.04683219028095, -0.04963002409968, -0.04211 [...]
+0.00913503411448, 0.02559637848431, 0.00380202623900, 0.04341150826710, 0.04741800568147, -0.01578529983234, 0.05166746230846, 0.05121834474517, 0.00801021034064, 0.03296691756242, 0.00869067734621, 0.06522696614589, -0.05761715944068, -0.06883698723352, -0.03067019176029, 0.02156735149891, 0.06969057246245, 0.02156735149891, -0.03067019176029, -0.06883698723352, -0.05761715944068, 0.06522696614589, 0.00869067734621, 0.03296691756242, 0.00801021034064, 0.05121834474517, 0.05166746230846, [...]
+-0.00922205842859, -0.02511329203000, -0.00329848627313, -0.04200352716372, -0.04567030131908, 0.01552199992789, -0.04939808301205, -0.04883456542052, -0.00710107751649, -0.03144564133374, -0.00864631825412, -0.06076173352856, 0.05322433439424, 0.06377948953705, 0.02780036340898, -0.01933288371895, -0.06399728423775, -0.01933288371895, 0.02780036340898, 0.06377948953705, 0.05322433439424, -0.06076173352856, -0.00864631825412, -0.03144564133374, -0.00710107751649, -0.04883456542052, -0.04 [...]
+-0.02876889046885, -0.01509084125054, 0.03963047977889, 0.00881974876440, 0.01552199992789, 0.03250874444113, 0.01610767548006, 0.00864062075235, 0.05323681630826, -0.02546580226758, -0.04836796828267, 0.04273731697500, -0.06161913050027, -0.02803496562843, -0.07081173873106, 0.06969057246245, 0.05387660966815, 0.06969057246245, -0.07081173873106, -0.02803496562843, -0.06161913050027, 0.04273731697500, -0.04836796828267, -0.02546580226758, 0.05323681630826, 0.00864062075235, 0.0161076754 [...]
+-0.00905031863291, -0.02613601062284, -0.00434559103408, -0.04499172586632, -0.04939808301205, 0.01610767548006, -0.05430453818238, -0.05403298716581, -0.00905987177209, -0.03484669808203, -0.00879307760295, -0.07081173873106, 0.06316887617837, 0.07536267012088, 0.03433801412888, -0.02442011476440, -0.07714535201411, -0.02442011476440, 0.03433801412888, 0.07536267012088, 0.06316887617837, -0.07081173873106, -0.00879307760295, -0.03484669808203, -0.00905987177209, -0.05403298716581, -0.05 [...]
+-0.00283618587179, -0.02111691650473, -0.01159092756416, -0.04326903841033, -0.04883456542052, 0.00864062075235, -0.05403298716581, -0.05260385601595, -0.01933288371895, -0.02803496562843, 0.00155790816347, -0.07747405815543, 0.07462272788890, 0.07992564670887, 0.04915146033489, -0.03929438261949, -0.08813390430467, -0.03929438261949, 0.04915146033489, 0.07992564670887, 0.07462272788890, -0.07747405815543, 0.00155790816347, -0.02803496562843, -0.01933288371895, -0.05260385601595, -0.0540 [...]
+-0.04198822986865, -0.03401426025387, 0.04945313461415, -0.01352102709593, -0.00710107751649, 0.05323681630826, -0.00905987177209, -0.01933288371895, 0.07051434913474, -0.05782350471105, -0.07714535201411, 0.02127053092509, -0.05605729667571, 0.00344457002262, -0.09172320431048, 0.09733017222613, 0.03779154935440, 0.09733017222613, -0.09172320431048, 0.00344457002262, -0.05605729667571, 0.02127053092509, -0.07714535201411, -0.05782350471105, 0.07051434913474, -0.01933288371895, -0.009059 [...]
+0.02264757303314, 0.00493640288370, -0.03755053092747, -0.02333152061039, -0.03144564133374, -0.02546580226758, -0.03484669808203, -0.02803496562843, -0.05782350471105, 0.01371110078340, 0.04915146033489, -0.07614567822515, 0.09733017222613, 0.06525950351177, 0.10156554753512, -0.09751182812518, -0.10150612803431, -0.09751182812518, 0.10156554753512, 0.06525950351177, 0.09733017222613, -0.07614567822515, 0.04915146033489, 0.01371110078340, -0.05782350471105, -0.02803496562843, -0.0348466 [...]
+0.03804111121964, 0.02522891682511, -0.04990035313554, -0.00071933672845, -0.00864631825412, -0.04836796828267, -0.00879307760295, 0.00155790816347, -0.07714535201411, 0.04915146033489, 0.08094445627940, -0.05169023594242, 0.09041357753814, 0.02834885437642, 0.12603831803759, -0.13058003873376, -0.08232980948645, -0.13058003873376, 0.12603831803759, 0.02834885437642, 0.09041357753814, -0.05169023594242, 0.08094445627940, 0.04915146033489, -0.07714535201411, 0.00155790816347, -0.008793077 [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+0.04169802746791, 0.05105292102523, -0.03653013164974, 0.05323681630826, 0.05322433439424, -0.06161913050027, 0.06316887617837, 0.07462272788890, -0.05605729667571, 0.09733017222613, 0.09041357753814, 0.07210126160498, -0.02658902847591, -0.12535024958029, 0.06683312417585, -0.09766849275778, 0.09039717566130, -0.09766849275778, 0.06683312417585, -0.12535024958029, -0.02658902847591, 0.07210126160498, 0.09041357753814, 0.09733017222613, -0.05605729667571, 0.07462272788890, 0.063168876178 [...]
+0.01552199992789, 0.03510685742783, -0.00071933672845, 0.05742081875151, 0.06377948953705, -0.02803496562843, 0.07536267012088, 0.07992564670887, 0.00344457002262, 0.06525950351177, 0.02834885437642, 0.13297118107692, -0.12535024958029, -0.18799488548807, -0.07031805212178, 0.04347274616886, 0.24531178657333, 0.04347274616886, -0.07031805212178, -0.18799488548807, -0.12535024958029, 0.13297118107692, 0.02834885437642, 0.06525950351177, 0.00344457002262, 0.07992564670887, 0.07536267012088 [...]
+0.04945313461415, 0.04745915084934, -0.05430453818238, 0.03277758616341, 0.02780036340898, -0.07081173873106, 0.03433801412888, 0.04915146033489, -0.09172320431048, 0.10156554753512, 0.12603831803759, 0.00693420455927, 0.06683312417585, -0.07031805212178, 0.23463634685391, -0.32757913759147, -0.06604332802355, -0.32757913759147, 0.23463634685391, -0.07031805212178, 0.06683312417585, 0.00693420455927, 0.12603831803759, 0.10156554753512, -0.09172320431048, 0.04915146033489, 0.0343380141288 [...]
+-0.04899968532023, -0.04403132364326, 0.05634488400998, -0.02546580226758, -0.01933288371895, 0.06969057246245, -0.02442011476440, -0.03929438261949, 0.09733017222613, -0.09751182812518, -0.13058003873376, 0.01504573058692, -0.09766849275778, 0.04347274616886, -0.32757913759147, 0.57672480775687, 0.44005058574493, 0.57672480775687, -0.32757913759147, 0.04347274616886, -0.09766849275778, 0.01504573058692, -0.13058003873376, -0.09751182812518, 0.09733017222613, -0.03929438261949, -0.024420 [...]
+-0.03388455479970, -0.04883456542052, 0.02416013744322, -0.06076173352856, -0.06399728423775, 0.05387660966815, -0.07714535201411, -0.08813390430467, 0.03779154935440, -0.10150612803431, -0.08232980948645, -0.12535024958029, 0.09039717566130, 0.24531178657333, -0.06604332802355, 0.44005058574493, 0.00000000000000, 0.44005058574493, -0.06604332802355, 0.24531178657333, 0.09039717566130, -0.12535024958029, -0.08232980948645, -0.10150612803431, 0.03779154935440, -0.08813390430467, -0.077145 [...]
+-0.04899968532023, -0.04403132364326, 0.05634488400998, -0.02546580226758, -0.01933288371895, 0.06969057246245, -0.02442011476440, -0.03929438261949, 0.09733017222613, -0.09751182812518, -0.13058003873376, 0.01504573058692, -0.09766849275778, 0.04347274616886, -0.32757913759147, 0.57672480775687, 0.44005058574493, 0.57672480775687, -0.32757913759147, 0.04347274616886, -0.09766849275778, 0.01504573058692, -0.13058003873376, -0.09751182812518, 0.09733017222613, -0.03929438261949, -0.024420 [...]
+0.04945313461415, 0.04745915084934, -0.05430453818238, 0.03277758616341, 0.02780036340898, -0.07081173873106, 0.03433801412888, 0.04915146033489, -0.09172320431048, 0.10156554753512, 0.12603831803759, 0.00693420455927, 0.06683312417585, -0.07031805212178, 0.23463634685391, -0.32757913759147, -0.06604332802355, -0.32757913759147, 0.23463634685391, -0.07031805212178, 0.06683312417585, 0.00693420455927, 0.12603831803759, 0.10156554753512, -0.09172320431048, 0.04915146033489, 0.0343380141288 [...]
+0.01552199992789, 0.03510685742783, -0.00071933672845, 0.05742081875151, 0.06377948953705, -0.02803496562843, 0.07536267012088, 0.07992564670887, 0.00344457002262, 0.06525950351177, 0.02834885437642, 0.13297118107692, -0.12535024958029, -0.18799488548807, -0.07031805212178, 0.04347274616886, 0.24531178657333, 0.04347274616886, -0.07031805212178, -0.18799488548807, -0.12535024958029, 0.13297118107692, 0.02834885437642, 0.06525950351177, 0.00344457002262, 0.07992564670887, 0.07536267012088 [...]
+0.04169802746791, 0.05105292102523, -0.03653013164974, 0.05323681630826, 0.05322433439424, -0.06161913050027, 0.06316887617837, 0.07462272788890, -0.05605729667571, 0.09733017222613, 0.09041357753814, 0.07210126160498, -0.02658902847591, -0.12535024958029, 0.06683312417585, -0.09766849275778, 0.09039717566130, -0.09766849275778, 0.06683312417585, -0.12535024958029, -0.02658902847591, 0.07210126160498, 0.09041357753814, 0.09733017222613, -0.05605729667571, 0.07462272788890, 0.063168876178 [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+0.03804111121964, 0.02522891682511, -0.04990035313554, -0.00071933672845, -0.00864631825412, -0.04836796828267, -0.00879307760295, 0.00155790816347, -0.07714535201411, 0.04915146033489, 0.08094445627940, -0.05169023594242, 0.09041357753814, 0.02834885437642, 0.12603831803759, -0.13058003873376, -0.08232980948645, -0.13058003873376, 0.12603831803759, 0.02834885437642, 0.09041357753814, -0.05169023594242, 0.08094445627940, 0.04915146033489, -0.07714535201411, 0.00155790816347, -0.008793077 [...]
+0.02264757303314, 0.00493640288370, -0.03755053092747, -0.02333152061039, -0.03144564133374, -0.02546580226758, -0.03484669808203, -0.02803496562843, -0.05782350471105, 0.01371110078340, 0.04915146033489, -0.07614567822515, 0.09733017222613, 0.06525950351177, 0.10156554753512, -0.09751182812518, -0.10150612803431, -0.09751182812518, 0.10156554753512, 0.06525950351177, 0.09733017222613, -0.07614567822515, 0.04915146033489, 0.01371110078340, -0.05782350471105, -0.02803496562843, -0.0348466 [...]
+-0.04198822986865, -0.03401426025387, 0.04945313461415, -0.01352102709593, -0.00710107751649, 0.05323681630826, -0.00905987177209, -0.01933288371895, 0.07051434913474, -0.05782350471105, -0.07714535201411, 0.02127053092509, -0.05605729667571, 0.00344457002262, -0.09172320431048, 0.09733017222613, 0.03779154935440, 0.09733017222613, -0.09172320431048, 0.00344457002262, -0.05605729667571, 0.02127053092509, -0.07714535201411, -0.05782350471105, 0.07051434913474, -0.01933288371895, -0.009059 [...]
+-0.00283618587179, -0.02111691650473, -0.01159092756416, -0.04326903841033, -0.04883456542052, 0.00864062075235, -0.05403298716581, -0.05260385601595, -0.01933288371895, -0.02803496562843, 0.00155790816347, -0.07747405815543, 0.07462272788890, 0.07992564670887, 0.04915146033489, -0.03929438261949, -0.08813390430467, -0.03929438261949, 0.04915146033489, 0.07992564670887, 0.07462272788890, -0.07747405815543, 0.00155790816347, -0.02803496562843, -0.01933288371895, -0.05260385601595, -0.0540 [...]
+-0.00905031863291, -0.02613601062284, -0.00434559103408, -0.04499172586632, -0.04939808301205, 0.01610767548006, -0.05430453818238, -0.05403298716581, -0.00905987177209, -0.03484669808203, -0.00879307760295, -0.07081173873106, 0.06316887617837, 0.07536267012088, 0.03433801412888, -0.02442011476440, -0.07714535201411, -0.02442011476440, 0.03433801412888, 0.07536267012088, 0.06316887617837, -0.07081173873106, -0.00879307760295, -0.03484669808203, -0.00905987177209, -0.05403298716581, -0.05 [...]
+-0.02876889046885, -0.01509084125054, 0.03963047977889, 0.00881974876440, 0.01552199992789, 0.03250874444113, 0.01610767548006, 0.00864062075235, 0.05323681630826, -0.02546580226758, -0.04836796828267, 0.04273731697500, -0.06161913050027, -0.02803496562843, -0.07081173873106, 0.06969057246245, 0.05387660966815, 0.06969057246245, -0.07081173873106, -0.02803496562843, -0.06161913050027, 0.04273731697500, -0.04836796828267, -0.02546580226758, 0.05323681630826, 0.00864062075235, 0.0161076754 [...]
+-0.03759634244848, -0.04135242996492, 0.03447279299858, -0.03645408668750, -0.03401426025387, 0.04741800568147, -0.03755053092747, -0.04403132364326, 0.04222968115101, -0.05728294659133, -0.05403298716581, -0.02546580226758, 0.00027003849811, 0.04244418660272, -0.03484669808203, 0.04273731697500, -0.01933288371895, 0.04273731697500, -0.03484669808203, 0.04244418660272, 0.00027003849811, -0.02546580226758, -0.05403298716581, -0.05728294659133, 0.04222968115101, -0.04403132364326, -0.03755 [...]
+0.00913503411448, 0.02559637848431, 0.00380202623900, 0.04341150826710, 0.04741800568147, -0.01578529983234, 0.05166746230846, 0.05121834474517, 0.00801021034064, 0.03296691756242, 0.00869067734621, 0.06522696614589, -0.05761715944068, -0.06883698723352, -0.03067019176029, 0.02156735149891, 0.06969057246245, 0.02156735149891, -0.03067019176029, -0.06883698723352, -0.05761715944068, 0.06522696614589, 0.00869067734621, 0.03296691756242, 0.00801021034064, 0.05121834474517, 0.05166746230846, [...]
+-0.03959381766328, -0.04410886072389, 0.03644296273535, -0.03980537034422, -0.03755053092747, 0.05166746230846, -0.04211210676874, -0.04963002409968, 0.04683219028095, -0.06514516365773, -0.06161913050027, -0.03067019176029, 0.00155790816347, 0.05116991106925, -0.04040858119196, 0.05012494613301, -0.02442011476440, 0.05012494613301, -0.04040858119196, 0.05116991106925, 0.00155790816347, -0.03067019176029, -0.06161913050027, -0.06514516365773, 0.04683219028095, -0.04963002409968, -0.04211 [...]
+-0.03797145192049, -0.04535566616530, 0.03282161335501, -0.04513877691637, -0.04403132364326, 0.05121834474517, -0.04963002409968, -0.05693896917516, 0.04273731697500, -0.06883698723352, -0.06095484289857, -0.04330187825715, 0.01371110078340, 0.06486285706603, -0.03318526107069, 0.04485675423343, -0.03929438261949, 0.04485675423343, -0.03318526107069, 0.06486285706603, 0.01371110078340, -0.04330187825715, -0.06095484289857, -0.06883698723352, 0.04273731697500, -0.05693896917516, -0.04963 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+-0.00222561996695, -0.02205338028065, -0.01352102709593, -0.04716218793354, -0.05403298716581, 0.00869067734621, -0.06161913050027, -0.06095484289857, -0.02442011476440, -0.03318526107069, 0.00344457002262, -0.10125366504812, 0.10156554753512, 0.11129083655510, 0.07210126160498, -0.05916188988776, -0.13058003873376, -0.05916188988776, 0.07210126160498, 0.11129083655510, 0.10156554753512, -0.10125366504812, 0.00344457002262, -0.03318526107069, -0.02442011476440, -0.06095484289857, -0.0616 [...]
+-0.04746872842254, -0.04513877691637, 0.05166746230846, -0.03045828585214, -0.02546580226758, 0.06522696614589, -0.03067019176029, -0.04330187825715, 0.07992564670887, -0.08513999504483, -0.10125366504812, -0.00486213436803, -0.04599388822189, 0.04399094217963, -0.11875106261662, 0.13658472451851, 0.01504573058692, 0.13658472451851, -0.11875106261662, 0.04399094217963, -0.04599388822189, -0.00486213436803, -0.10125366504812, -0.08513999504483, 0.07992564670887, -0.04330187825715, -0.0306 [...]
+0.04309315116934, 0.03250874444113, -0.05398199531481, 0.00801021034064, 0.00027003849811, -0.05761715944068, 0.00155790816347, 0.01371110078340, -0.08813390430467, 0.06717547808897, 0.10156554753512, -0.04599388822189, 0.10061964911512, 0.01504573058692, 0.17112027276390, -0.18799488548807, -0.09766849275778, -0.18799488548807, 0.17112027276390, 0.01504573058692, 0.10061964911512, -0.04599388822189, 0.10156554753512, 0.06717547808897, -0.08813390430467, 0.01371110078340, 0.0015579081634 [...]
+0.04741800568147, 0.05131960071511, -0.04716218793354, 0.04496452881899, 0.04244418660272, -0.06883698723352, 0.05116991106925, 0.06486285706603, -0.07614567822515, 0.10334674409940, 0.11129083655510, 0.04399094217963, 0.01504573058692, -0.10570143114241, 0.13337515469879, -0.17678529895672, 0.04347274616886, -0.17678529895672, 0.13337515469879, -0.10570143114241, 0.01504573058692, 0.04399094217963, 0.11129083655510, 0.10334674409940, -0.07614567822515, 0.06486285706603, 0.05116991106925 [...]
+0.02522891682511, 0.00629983820314, -0.04211210676874, -0.02516948075949, -0.03484669808203, -0.03067019176029, -0.04040858119196, -0.03318526107069, -0.07494530013047, 0.02003044394070, 0.07210126160498, -0.11875106261662, 0.17112027276390, 0.13337515469879, 0.24531178657333, -0.27668385812757, -0.32757913759147, -0.27668385812757, 0.24531178657333, 0.13337515469879, 0.17112027276390, -0.11875106261662, 0.07210126160498, 0.02003044394070, -0.07494530013047, -0.03318526107069, -0.0404085 [...]
+-0.01909407501789, 0.00114288282262, 0.03669569988478, 0.03296691756242, 0.04273731697500, 0.02156735149891, 0.05012494613301, 0.04485675423343, 0.06717547808897, -0.00486213436803, -0.05916188988776, 0.13658472451851, -0.18799488548807, -0.17678529895672, -0.27668385812757, 0.33905895852594, 0.57672480775687, 0.33905895852594, -0.27668385812757, -0.17678529895672, -0.18799488548807, 0.13658472451851, -0.05916188988776, -0.00486213436803, 0.06717547808897, 0.04485675423343, 0.05012494613 [...]
+-0.04899968532023, -0.04403132364326, 0.05634488400998, -0.02546580226758, -0.01933288371895, 0.06969057246245, -0.02442011476440, -0.03929438261949, 0.09733017222613, -0.09751182812518, -0.13058003873376, 0.01504573058692, -0.09766849275778, 0.04347274616886, -0.32757913759147, 0.57672480775687, 0.44005058574493, 0.57672480775687, -0.32757913759147, 0.04347274616886, -0.09766849275778, 0.01504573058692, -0.13058003873376, -0.09751182812518, 0.09733017222613, -0.03929438261949, -0.024420 [...]
+-0.01909407501789, 0.00114288282262, 0.03669569988478, 0.03296691756242, 0.04273731697500, 0.02156735149891, 0.05012494613301, 0.04485675423343, 0.06717547808897, -0.00486213436803, -0.05916188988776, 0.13658472451851, -0.18799488548807, -0.17678529895672, -0.27668385812757, 0.33905895852594, 0.57672480775687, 0.33905895852594, -0.27668385812757, -0.17678529895672, -0.18799488548807, 0.13658472451851, -0.05916188988776, -0.00486213436803, 0.06717547808897, 0.04485675423343, 0.05012494613 [...]
+0.02522891682511, 0.00629983820314, -0.04211210676874, -0.02516948075949, -0.03484669808203, -0.03067019176029, -0.04040858119196, -0.03318526107069, -0.07494530013047, 0.02003044394070, 0.07210126160498, -0.11875106261662, 0.17112027276390, 0.13337515469879, 0.24531178657333, -0.27668385812757, -0.32757913759147, -0.27668385812757, 0.24531178657333, 0.13337515469879, 0.17112027276390, -0.11875106261662, 0.07210126160498, 0.02003044394070, -0.07494530013047, -0.03318526107069, -0.0404085 [...]
+0.04741800568147, 0.05131960071511, -0.04716218793354, 0.04496452881899, 0.04244418660272, -0.06883698723352, 0.05116991106925, 0.06486285706603, -0.07614567822515, 0.10334674409940, 0.11129083655510, 0.04399094217963, 0.01504573058692, -0.10570143114241, 0.13337515469879, -0.17678529895672, 0.04347274616886, -0.17678529895672, 0.13337515469879, -0.10570143114241, 0.01504573058692, 0.04399094217963, 0.11129083655510, 0.10334674409940, -0.07614567822515, 0.06486285706603, 0.05116991106925 [...]
+0.04309315116934, 0.03250874444113, -0.05398199531481, 0.00801021034064, 0.00027003849811, -0.05761715944068, 0.00155790816347, 0.01371110078340, -0.08813390430467, 0.06717547808897, 0.10156554753512, -0.04599388822189, 0.10061964911512, 0.01504573058692, 0.17112027276390, -0.18799488548807, -0.09766849275778, -0.18799488548807, 0.17112027276390, 0.01504573058692, 0.10061964911512, -0.04599388822189, 0.10156554753512, 0.06717547808897, -0.08813390430467, 0.01371110078340, 0.0015579081634 [...]
+-0.04746872842254, -0.04513877691637, 0.05166746230846, -0.03045828585214, -0.02546580226758, 0.06522696614589, -0.03067019176029, -0.04330187825715, 0.07992564670887, -0.08513999504483, -0.10125366504812, -0.00486213436803, -0.04599388822189, 0.04399094217963, -0.11875106261662, 0.13658472451851, 0.01504573058692, 0.13658472451851, -0.11875106261662, 0.04399094217963, -0.04599388822189, -0.00486213436803, -0.10125366504812, -0.08513999504483, 0.07992564670887, -0.04330187825715, -0.0306 [...]
+-0.00222561996695, -0.02205338028065, -0.01352102709593, -0.04716218793354, -0.05403298716581, 0.00869067734621, -0.06161913050027, -0.06095484289857, -0.02442011476440, -0.03318526107069, 0.00344457002262, -0.10125366504812, 0.10156554753512, 0.11129083655510, 0.07210126160498, -0.05916188988776, -0.13058003873376, -0.05916188988776, 0.07210126160498, 0.11129083655510, 0.10156554753512, -0.10125366504812, 0.00344457002262, -0.03318526107069, -0.02442011476440, -0.06095484289857, -0.0616 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+-0.03797145192049, -0.04535566616530, 0.03282161335501, -0.04513877691637, -0.04403132364326, 0.05121834474517, -0.04963002409968, -0.05693896917516, 0.04273731697500, -0.06883698723352, -0.06095484289857, -0.04330187825715, 0.01371110078340, 0.06486285706603, -0.03318526107069, 0.04485675423343, -0.03929438261949, 0.04485675423343, -0.03318526107069, 0.06486285706603, 0.01371110078340, -0.04330187825715, -0.06095484289857, -0.06883698723352, 0.04273731697500, -0.05693896917516, -0.04963 [...]
+-0.03959381766328, -0.04410886072389, 0.03644296273535, -0.03980537034422, -0.03755053092747, 0.05166746230846, -0.04211210676874, -0.04963002409968, 0.04683219028095, -0.06514516365773, -0.06161913050027, -0.03067019176029, 0.00155790816347, 0.05116991106925, -0.04040858119196, 0.05012494613301, -0.02442011476440, 0.05012494613301, -0.04040858119196, 0.05116991106925, 0.00155790816347, -0.03067019176029, -0.06161913050027, -0.06514516365773, 0.04683219028095, -0.04963002409968, -0.04211 [...]
+0.00913503411448, 0.02559637848431, 0.00380202623900, 0.04341150826710, 0.04741800568147, -0.01578529983234, 0.05166746230846, 0.05121834474517, 0.00801021034064, 0.03296691756242, 0.00869067734621, 0.06522696614589, -0.05761715944068, -0.06883698723352, -0.03067019176029, 0.02156735149891, 0.06969057246245, 0.02156735149891, -0.03067019176029, -0.06883698723352, -0.05761715944068, 0.06522696614589, 0.00869067734621, 0.03296691756242, 0.00801021034064, 0.05121834474517, 0.05166746230846, [...]
+0.03522641326574, 0.04123067549901, -0.03031839687312, 0.03963047977889, 0.03804111121964, -0.04499172586632, 0.04178512556283, 0.04745915084934, -0.03653013164974, 0.05634488400998, 0.04963142214735, 0.03277758616341, -0.00905987177209, -0.04836796828267, 0.02642596318589, -0.03484669808203, 0.02780036340898, -0.03484669808203, 0.02642596318589, -0.04836796828267, -0.00905987177209, 0.03277758616341, 0.04963142214735, 0.05634488400998, -0.03653013164974, 0.04745915084934, 0.041785125562 [...]
+-0.00338379798127, -0.02040531295214, -0.01000868479601, -0.04031243635006, -0.04499172586632, 0.00870175468576, -0.04883456542052, -0.04716218793354, -0.01598181558280, -0.02516948075949, 0.00027003849811, -0.06514516365773, 0.06145323689284, 0.06584304685785, 0.03895560265498, -0.03067019176029, -0.07081173873106, -0.03067019176029, 0.03895560265498, 0.06584304685785, 0.06145323689284, -0.06514516365773, 0.00027003849811, -0.02516948075949, -0.01598181558280, -0.04716218793354, -0.0488 [...]
+0.03697036111778, 0.04384574828821, -0.03188743137750, 0.04309315116934, 0.04178512556283, -0.04883456542052, 0.04661358044050, 0.05323681630826, -0.04023894554545, 0.06377948953705, 0.05627305279151, 0.03895560265498, -0.01180521143300, -0.05782350471105, 0.03017589095093, -0.04040858119196, 0.03433801412888, -0.04040858119196, 0.03017589095093, -0.05782350471105, -0.01180521143300, 0.03895560265498, 0.05627305279151, 0.06377948953705, -0.04023894554545, 0.05323681630826, 0.046613580440 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+0.01595838913427, -0.00222561996695, -0.03079225925144, -0.02912466965015, -0.03653013164974, -0.01598181558280, -0.04023894554545, -0.03484669808203, -0.04628401868063, 0.00155790816347, 0.03433801412888, -0.07419862922226, 0.08701085516538, 0.06656064247057, 0.08094445627940, -0.07494530013047, -0.09172320431048, -0.07494530013047, 0.08094445627940, 0.06656064247057, 0.08701085516538, -0.07419862922226, 0.03433801412888, 0.00155790816347, -0.04628401868063, -0.03484669808203, -0.040238 [...]
+0.01512570665415, 0.03282161335501, -0.00153126021194, 0.05166746230846, 0.05634488400998, -0.02516948075949, 0.06377948953705, 0.06584304685785, 0.00155790816347, 0.05012494613301, 0.02127053092509, 0.08752809455106, -0.07494530013047, -0.10125366504812, -0.03399633247860, 0.02003044394070, 0.10156554753512, 0.02003044394070, -0.03399633247860, -0.10125366504812, -0.07494530013047, 0.08752809455106, 0.02127053092509, 0.05012494613301, 0.00155790816347, 0.06584304685785, 0.06377948953705 [...]
+-0.00434559103408, 0.01552199992789, 0.02038138287138, 0.04222968115101, 0.04963142214735, 0.00027003849811, 0.05627305279151, 0.05387660966815, 0.03433801412888, 0.02127053092509, -0.01626781358073, 0.09733017222613, -0.10348456280590, -0.10150612803431, -0.08280335937603, 0.07210126160498, 0.12603831803759, 0.07210126160498, -0.08280335937603, -0.10150612803431, -0.10348456280590, 0.09733017222613, -0.01626781358073, 0.02127053092509, 0.03433801412888, 0.05387660966815, 0.0562730527915 [...]
+0.04703493050962, 0.04755584645599, -0.04883456542052, 0.03669569988478, 0.03277758616341, -0.06514516365773, 0.03895560265498, 0.05116991106925, -0.07419862922226, 0.08752809455106, 0.09733017222613, 0.02003044394070, 0.02834885437642, -0.05916188988776, 0.10061964911512, -0.11875106261662, 0.00693420455927, -0.11875106261662, 0.10061964911512, -0.05916188988776, 0.02834885437642, 0.02003044394070, 0.09733017222613, 0.08752809455106, -0.07419862922226, 0.05116991106925, 0.03895560265498 [...]
+-0.04548829345483, -0.03755053092747, 0.05428131739349, -0.01598181558280, -0.00905987177209, 0.06145323689284, -0.01180521143300, -0.02442011476440, 0.08701085516538, -0.07494530013047, -0.10348456280590, 0.02834885437642, -0.08232980948645, 0.00693420455927, -0.15403806518312, 0.17112027276390, 0.06683312417585, 0.17112027276390, -0.15403806518312, 0.00693420455927, -0.08232980948645, 0.02834885437642, -0.10348456280590, -0.07494530013047, 0.08701085516538, -0.02442011476440, -0.011805 [...]
+-0.04499172586632, -0.05170195653292, 0.04222968115101, -0.04963002409968, -0.04836796828267, 0.06584304685785, -0.05782350471105, -0.07051895298226, 0.06656064247057, -0.10125366504812, -0.10150612803431, -0.05916188988776, 0.00693420455927, 0.11717778964385, -0.09766849275778, 0.13337515469879, -0.07031805212178, 0.13337515469879, -0.09766849275778, 0.11717778964385, 0.00693420455927, -0.05916188988776, -0.10150612803431, -0.10125366504812, 0.06656064247057, -0.07051895298226, -0.05782 [...]
+-0.03079225925144, -0.01352102709593, 0.04661358044050, 0.01700752911701, 0.02642596318589, 0.03895560265498, 0.03017589095093, 0.02127053092509, 0.08094445627940, -0.03399633247860, -0.08280335937603, 0.10061964911512, -0.15403806518312, -0.09766849275778, -0.22344710449063, 0.24531178657333, 0.23463634685391, 0.24531178657333, -0.22344710449063, -0.09766849275778, -0.15403806518312, 0.10061964911512, -0.08280335937603, -0.03399633247860, 0.08094445627940, 0.02127053092509, 0.0301758909 [...]
+0.02522891682511, 0.00629983820314, -0.04211210676874, -0.02516948075949, -0.03484669808203, -0.03067019176029, -0.04040858119196, -0.03318526107069, -0.07494530013047, 0.02003044394070, 0.07210126160498, -0.11875106261662, 0.17112027276390, 0.13337515469879, 0.24531178657333, -0.27668385812757, -0.32757913759147, -0.27668385812757, 0.24531178657333, 0.13337515469879, 0.17112027276390, -0.11875106261662, 0.07210126160498, 0.02003044394070, -0.07494530013047, -0.03318526107069, -0.0404085 [...]
+0.04945313461415, 0.04745915084934, -0.05430453818238, 0.03277758616341, 0.02780036340898, -0.07081173873106, 0.03433801412888, 0.04915146033489, -0.09172320431048, 0.10156554753512, 0.12603831803759, 0.00693420455927, 0.06683312417585, -0.07031805212178, 0.23463634685391, -0.32757913759147, -0.06604332802355, -0.32757913759147, 0.23463634685391, -0.07031805212178, 0.06683312417585, 0.00693420455927, 0.12603831803759, 0.10156554753512, -0.09172320431048, 0.04915146033489, 0.0343380141288 [...]
+0.02522891682511, 0.00629983820314, -0.04211210676874, -0.02516948075949, -0.03484669808203, -0.03067019176029, -0.04040858119196, -0.03318526107069, -0.07494530013047, 0.02003044394070, 0.07210126160498, -0.11875106261662, 0.17112027276390, 0.13337515469879, 0.24531178657333, -0.27668385812757, -0.32757913759147, -0.27668385812757, 0.24531178657333, 0.13337515469879, 0.17112027276390, -0.11875106261662, 0.07210126160498, 0.02003044394070, -0.07494530013047, -0.03318526107069, -0.0404085 [...]
+-0.03079225925144, -0.01352102709593, 0.04661358044050, 0.01700752911701, 0.02642596318589, 0.03895560265498, 0.03017589095093, 0.02127053092509, 0.08094445627940, -0.03399633247860, -0.08280335937603, 0.10061964911512, -0.15403806518312, -0.09766849275778, -0.22344710449063, 0.24531178657333, 0.23463634685391, 0.24531178657333, -0.22344710449063, -0.09766849275778, -0.15403806518312, 0.10061964911512, -0.08280335937603, -0.03399633247860, 0.08094445627940, 0.02127053092509, 0.0301758909 [...]
+-0.04499172586632, -0.05170195653292, 0.04222968115101, -0.04963002409968, -0.04836796828267, 0.06584304685785, -0.05782350471105, -0.07051895298226, 0.06656064247057, -0.10125366504812, -0.10150612803431, -0.05916188988776, 0.00693420455927, 0.11717778964385, -0.09766849275778, 0.13337515469879, -0.07031805212178, 0.13337515469879, -0.09766849275778, 0.11717778964385, 0.00693420455927, -0.05916188988776, -0.10150612803431, -0.10125366504812, 0.06656064247057, -0.07051895298226, -0.05782 [...]
+-0.04548829345483, -0.03755053092747, 0.05428131739349, -0.01598181558280, -0.00905987177209, 0.06145323689284, -0.01180521143300, -0.02442011476440, 0.08701085516538, -0.07494530013047, -0.10348456280590, 0.02834885437642, -0.08232980948645, 0.00693420455927, -0.15403806518312, 0.17112027276390, 0.06683312417585, 0.17112027276390, -0.15403806518312, 0.00693420455927, -0.08232980948645, 0.02834885437642, -0.10348456280590, -0.07494530013047, 0.08701085516538, -0.02442011476440, -0.011805 [...]
+0.04703493050962, 0.04755584645599, -0.04883456542052, 0.03669569988478, 0.03277758616341, -0.06514516365773, 0.03895560265498, 0.05116991106925, -0.07419862922226, 0.08752809455106, 0.09733017222613, 0.02003044394070, 0.02834885437642, -0.05916188988776, 0.10061964911512, -0.11875106261662, 0.00693420455927, -0.11875106261662, 0.10061964911512, -0.05916188988776, 0.02834885437642, 0.02003044394070, 0.09733017222613, 0.08752809455106, -0.07419862922226, 0.05116991106925, 0.03895560265498 [...]
+-0.00434559103408, 0.01552199992789, 0.02038138287138, 0.04222968115101, 0.04963142214735, 0.00027003849811, 0.05627305279151, 0.05387660966815, 0.03433801412888, 0.02127053092509, -0.01626781358073, 0.09733017222613, -0.10348456280590, -0.10150612803431, -0.08280335937603, 0.07210126160498, 0.12603831803759, 0.07210126160498, -0.08280335937603, -0.10150612803431, -0.10348456280590, 0.09733017222613, -0.01626781358073, 0.02127053092509, 0.03433801412888, 0.05387660966815, 0.0562730527915 [...]
+0.01512570665415, 0.03282161335501, -0.00153126021194, 0.05166746230846, 0.05634488400998, -0.02516948075949, 0.06377948953705, 0.06584304685785, 0.00155790816347, 0.05012494613301, 0.02127053092509, 0.08752809455106, -0.07494530013047, -0.10125366504812, -0.03399633247860, 0.02003044394070, 0.10156554753512, 0.02003044394070, -0.03399633247860, -0.10125366504812, -0.07494530013047, 0.08752809455106, 0.02127053092509, 0.05012494613301, 0.00155790816347, 0.06584304685785, 0.06377948953705 [...]
+0.01595838913427, -0.00222561996695, -0.03079225925144, -0.02912466965015, -0.03653013164974, -0.01598181558280, -0.04023894554545, -0.03484669808203, -0.04628401868063, 0.00155790816347, 0.03433801412888, -0.07419862922226, 0.08701085516538, 0.06656064247057, 0.08094445627940, -0.07494530013047, -0.09172320431048, -0.07494530013047, 0.08094445627940, 0.06656064247057, 0.08701085516538, -0.07419862922226, 0.03433801412888, 0.00155790816347, -0.04628401868063, -0.03484669808203, -0.040238 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+0.03697036111778, 0.04384574828821, -0.03188743137750, 0.04309315116934, 0.04178512556283, -0.04883456542052, 0.04661358044050, 0.05323681630826, -0.04023894554545, 0.06377948953705, 0.05627305279151, 0.03895560265498, -0.01180521143300, -0.05782350471105, 0.03017589095093, -0.04040858119196, 0.03433801412888, -0.04040858119196, 0.03017589095093, -0.05782350471105, -0.01180521143300, 0.03895560265498, 0.05627305279151, 0.06377948953705, -0.04023894554545, 0.05323681630826, 0.046613580440 [...]
+-0.00338379798127, -0.02040531295214, -0.01000868479601, -0.04031243635006, -0.04499172586632, 0.00870175468576, -0.04883456542052, -0.04716218793354, -0.01598181558280, -0.02516948075949, 0.00027003849811, -0.06514516365773, 0.06145323689284, 0.06584304685785, 0.03895560265498, -0.03067019176029, -0.07081173873106, -0.03067019176029, 0.03895560265498, 0.06584304685785, 0.06145323689284, -0.06514516365773, 0.00027003849811, -0.02516948075949, -0.01598181558280, -0.04716218793354, -0.0488 [...]
+-0.00751015358970, 0.00913503411448, 0.02051771641111, 0.03105894328301, 0.03644296273535, 0.00493640288370, 0.03893806094712, 0.03510685742783, 0.02847526258331, 0.00864062075235, -0.01598181558280, 0.05742081875151, -0.06076173352856, -0.05260385601595, -0.04836796828267, 0.04244418660272, 0.06377948953705, 0.04244418660272, -0.04836796828267, -0.05260385601595, -0.06076173352856, 0.05742081875151, -0.01598181558280, 0.00864062075235, 0.02847526258331, 0.03510685742783, 0.0389380609471 [...]
+0.03785607654408, 0.02991156721912, -0.04410886072389, 0.01076407940667, 0.00493640288370, -0.04513877691637, 0.00629983820314, 0.01466865762037, -0.05728294659133, 0.04496452881899, 0.05946062873198, -0.01764835261303, 0.04273731697500, -0.00086468661469, 0.06584304685785, -0.06883698723352, -0.02803496562843, -0.06883698723352, 0.06584304685785, -0.00086468661469, 0.04273731697500, -0.01764835261303, 0.05946062873198, 0.04496452881899, -0.05728294659133, 0.01466865762037, 0.00629983820 [...]
+-0.00866995656907, 0.00896875039683, 0.02264757303314, 0.03282161335501, 0.03893806094712, 0.00629983820314, 0.04222968115101, 0.03821264299440, 0.03277758616341, 0.00869067734621, -0.01933288371895, 0.06584304685785, -0.07081173873106, -0.06095484289857, -0.05782350471105, 0.05116991106925, 0.07536267012088, 0.05116991106925, -0.05782350471105, -0.06095484289857, -0.07081173873106, 0.06584304685785, -0.01933288371895, 0.00869067734621, 0.03277758616341, 0.03821264299440, 0.0422296811510 [...]
+-0.01509084125054, 0.00253986035635, 0.02926181365419, 0.02821667474258, 0.03510685742783, 0.01466865762037, 0.03821264299440, 0.03296691756242, 0.04244418660272, -0.00086468661469, -0.03067019176029, 0.06698830614494, -0.07747405815543, -0.05912294255307, -0.07051895298226, 0.06486285706603, 0.07992564670887, 0.06486285706603, -0.07051895298226, -0.05912294255307, -0.07747405815543, 0.06698830614494, -0.03067019176029, -0.00086468661469, 0.04244418660272, 0.03296691756242, 0.03821264299 [...]
+0.04384574828821, 0.04364554753736, -0.04499172586632, 0.03250874444113, 0.02847526258331, -0.05728294659133, 0.03277758616341, 0.04244418660272, -0.06161913050027, 0.06969057246245, 0.07536267012088, 0.01371110078340, 0.02127053092509, -0.03929438261949, 0.06656064247057, -0.07614567822515, 0.00344457002262, -0.07614567822515, 0.06656064247057, -0.03929438261949, 0.02127053092509, 0.01371110078340, 0.07536267012088, 0.06969057246245, -0.06161913050027, 0.04244418660272, 0.03277758616341 [...]
+-0.03645408668750, -0.02387116439873, 0.04755584645599, 0.00114288282262, 0.00864062075235, 0.04496452881899, 0.00869067734621, -0.00086468661469, 0.06969057246245, -0.04330187825715, -0.07051895298226, 0.04485675423343, -0.07614567822515, -0.02381038314910, -0.10125366504812, 0.10334674409940, 0.06525950351177, 0.10334674409940, -0.10125366504812, -0.02381038314910, -0.07614567822515, 0.04485675423343, -0.07051895298226, -0.04330187825715, 0.06969057246245, -0.00086468661469, 0.00869067 [...]
+-0.04512890076845, -0.03980537034422, 0.05105292102523, -0.02183846096527, -0.01598181558280, 0.05946062873198, -0.01933288371895, -0.03067019176029, 0.07536267012088, -0.07051895298226, -0.08813390430467, 0.00998778878484, -0.05169023594242, 0.02003044394070, -0.10150612803431, 0.11129083655510, 0.02834885437642, 0.11129083655510, -0.10150612803431, 0.02003044394070, -0.05169023594242, 0.00998778878484, -0.08813390430467, -0.07051895298226, 0.07536267012088, -0.03067019176029, -0.019332 [...]
+0.00881974876440, 0.02821667474258, 0.00629983820314, 0.05121834474517, 0.05742081875151, -0.01764835261303, 0.06584304685785, 0.06698830614494, 0.01371110078340, 0.04485675423343, 0.00998778878484, 0.10334674409940, -0.09751182812518, -0.11954033404934, -0.05916188988776, 0.04399094217963, 0.13297118107692, 0.04399094217963, -0.05916188988776, -0.11954033404934, -0.09751182812518, 0.10334674409940, 0.00998778878484, 0.04485675423343, 0.01371110078340, 0.06698830614494, 0.06584304685785, [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+0.00493640288370, -0.01578529983234, -0.02183846096527, -0.04431851921725, -0.05260385601595, -0.00086468661469, -0.06095484289857, -0.05912294255307, -0.03929438261949, -0.02381038314910, 0.02003044394070, -0.11954033404934, 0.13297118107692, 0.13658472451851, 0.11717778964385, -0.10570143114241, -0.18799488548807, -0.10570143114241, 0.11717778964385, 0.13658472451851, 0.13297118107692, -0.11954033404934, 0.02003044394070, -0.02381038314910, -0.03929438261949, -0.05912294255307, -0.0609 [...]
+-0.04499172586632, -0.05170195653292, 0.04222968115101, -0.04963002409968, -0.04836796828267, 0.06584304685785, -0.05782350471105, -0.07051895298226, 0.06656064247057, -0.10125366504812, -0.10150612803431, -0.05916188988776, 0.00693420455927, 0.11717778964385, -0.09766849275778, 0.13337515469879, -0.07031805212178, 0.13337515469879, -0.09766849275778, 0.11717778964385, 0.00693420455927, -0.05916188988776, -0.10150612803431, -0.10125366504812, 0.06656064247057, -0.07051895298226, -0.05782 [...]
+0.04741800568147, 0.05131960071511, -0.04716218793354, 0.04496452881899, 0.04244418660272, -0.06883698723352, 0.05116991106925, 0.06486285706603, -0.07614567822515, 0.10334674409940, 0.11129083655510, 0.04399094217963, 0.01504573058692, -0.10570143114241, 0.13337515469879, -0.17678529895672, 0.04347274616886, -0.17678529895672, 0.13337515469879, -0.10570143114241, 0.01504573058692, 0.04399094217963, 0.11129083655510, 0.10334674409940, -0.07614567822515, 0.06486285706603, 0.05116991106925 [...]
+0.01552199992789, 0.03510685742783, -0.00071933672845, 0.05742081875151, 0.06377948953705, -0.02803496562843, 0.07536267012088, 0.07992564670887, 0.00344457002262, 0.06525950351177, 0.02834885437642, 0.13297118107692, -0.12535024958029, -0.18799488548807, -0.07031805212178, 0.04347274616886, 0.24531178657333, 0.04347274616886, -0.07031805212178, -0.18799488548807, -0.12535024958029, 0.13297118107692, 0.02834885437642, 0.06525950351177, 0.00344457002262, 0.07992564670887, 0.07536267012088 [...]
+0.04741800568147, 0.05131960071511, -0.04716218793354, 0.04496452881899, 0.04244418660272, -0.06883698723352, 0.05116991106925, 0.06486285706603, -0.07614567822515, 0.10334674409940, 0.11129083655510, 0.04399094217963, 0.01504573058692, -0.10570143114241, 0.13337515469879, -0.17678529895672, 0.04347274616886, -0.17678529895672, 0.13337515469879, -0.10570143114241, 0.01504573058692, 0.04399094217963, 0.11129083655510, 0.10334674409940, -0.07614567822515, 0.06486285706603, 0.05116991106925 [...]
+-0.04499172586632, -0.05170195653292, 0.04222968115101, -0.04963002409968, -0.04836796828267, 0.06584304685785, -0.05782350471105, -0.07051895298226, 0.06656064247057, -0.10125366504812, -0.10150612803431, -0.05916188988776, 0.00693420455927, 0.11717778964385, -0.09766849275778, 0.13337515469879, -0.07031805212178, 0.13337515469879, -0.09766849275778, 0.11717778964385, 0.00693420455927, -0.05916188988776, -0.10150612803431, -0.10125366504812, 0.06656064247057, -0.07051895298226, -0.05782 [...]
+0.00493640288370, -0.01578529983234, -0.02183846096527, -0.04431851921725, -0.05260385601595, -0.00086468661469, -0.06095484289857, -0.05912294255307, -0.03929438261949, -0.02381038314910, 0.02003044394070, -0.11954033404934, 0.13297118107692, 0.13658472451851, 0.11717778964385, -0.10570143114241, -0.18799488548807, -0.10570143114241, 0.11717778964385, 0.13658472451851, 0.13297118107692, -0.11954033404934, 0.02003044394070, -0.02381038314910, -0.03929438261949, -0.05912294255307, -0.0609 [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+0.00881974876440, 0.02821667474258, 0.00629983820314, 0.05121834474517, 0.05742081875151, -0.01764835261303, 0.06584304685785, 0.06698830614494, 0.01371110078340, 0.04485675423343, 0.00998778878484, 0.10334674409940, -0.09751182812518, -0.11954033404934, -0.05916188988776, 0.04399094217963, 0.13297118107692, 0.04399094217963, -0.05916188988776, -0.11954033404934, -0.09751182812518, 0.10334674409940, 0.00998778878484, 0.04485675423343, 0.01371110078340, 0.06698830614494, 0.06584304685785, [...]
+-0.04512890076845, -0.03980537034422, 0.05105292102523, -0.02183846096527, -0.01598181558280, 0.05946062873198, -0.01933288371895, -0.03067019176029, 0.07536267012088, -0.07051895298226, -0.08813390430467, 0.00998778878484, -0.05169023594242, 0.02003044394070, -0.10150612803431, 0.11129083655510, 0.02834885437642, 0.11129083655510, -0.10150612803431, 0.02003044394070, -0.05169023594242, 0.00998778878484, -0.08813390430467, -0.07051895298226, 0.07536267012088, -0.03067019176029, -0.019332 [...]
+-0.03645408668750, -0.02387116439873, 0.04755584645599, 0.00114288282262, 0.00864062075235, 0.04496452881899, 0.00869067734621, -0.00086468661469, 0.06969057246245, -0.04330187825715, -0.07051895298226, 0.04485675423343, -0.07614567822515, -0.02381038314910, -0.10125366504812, 0.10334674409940, 0.06525950351177, 0.10334674409940, -0.10125366504812, -0.02381038314910, -0.07614567822515, 0.04485675423343, -0.07051895298226, -0.04330187825715, 0.06969057246245, -0.00086468661469, 0.00869067 [...]
+0.04384574828821, 0.04364554753736, -0.04499172586632, 0.03250874444113, 0.02847526258331, -0.05728294659133, 0.03277758616341, 0.04244418660272, -0.06161913050027, 0.06969057246245, 0.07536267012088, 0.01371110078340, 0.02127053092509, -0.03929438261949, 0.06656064247057, -0.07614567822515, 0.00344457002262, -0.07614567822515, 0.06656064247057, -0.03929438261949, 0.02127053092509, 0.01371110078340, 0.07536267012088, 0.06969057246245, -0.06161913050027, 0.04244418660272, 0.03277758616341 [...]
+-0.01509084125054, 0.00253986035635, 0.02926181365419, 0.02821667474258, 0.03510685742783, 0.01466865762037, 0.03821264299440, 0.03296691756242, 0.04244418660272, -0.00086468661469, -0.03067019176029, 0.06698830614494, -0.07747405815543, -0.05912294255307, -0.07051895298226, 0.06486285706603, 0.07992564670887, 0.06486285706603, -0.07051895298226, -0.05912294255307, -0.07747405815543, 0.06698830614494, -0.03067019176029, -0.00086468661469, 0.04244418660272, 0.03296691756242, 0.03821264299 [...]
+-0.00866995656907, 0.00896875039683, 0.02264757303314, 0.03282161335501, 0.03893806094712, 0.00629983820314, 0.04222968115101, 0.03821264299440, 0.03277758616341, 0.00869067734621, -0.01933288371895, 0.06584304685785, -0.07081173873106, -0.06095484289857, -0.05782350471105, 0.05116991106925, 0.07536267012088, 0.05116991106925, -0.05782350471105, -0.06095484289857, -0.07081173873106, 0.06584304685785, -0.01933288371895, 0.00869067734621, 0.03277758616341, 0.03821264299440, 0.0422296811510 [...]
+0.03785607654408, 0.02991156721912, -0.04410886072389, 0.01076407940667, 0.00493640288370, -0.04513877691637, 0.00629983820314, 0.01466865762037, -0.05728294659133, 0.04496452881899, 0.05946062873198, -0.01764835261303, 0.04273731697500, -0.00086468661469, 0.06584304685785, -0.06883698723352, -0.02803496562843, -0.06883698723352, 0.06584304685785, -0.00086468661469, 0.04273731697500, -0.01764835261303, 0.05946062873198, 0.04496452881899, -0.05728294659133, 0.01466865762037, 0.00629983820 [...]
+0.01961646864417, 0.03286903679693, -0.00905031863291, 0.04384574828821, 0.04569971096681, -0.02743053076570, 0.04945313461415, 0.05105292102523, -0.00866167202085, 0.04222968115101, 0.02416013744322, 0.05323681630826, -0.03931525868965, -0.06076173352856, -0.00905987177209, 0.00027003849811, 0.05322433439424, 0.00027003849811, -0.00905987177209, -0.06076173352856, -0.03931525868965, 0.05323681630826, 0.02416013744322, 0.04222968115101, -0.00866167202085, 0.05105292102523, 0.049453134614 [...]
+0.01871143836380, 0.00282925577496, -0.03115444796200, -0.02111691650473, -0.02743053076570, -0.01909407501789, -0.02912466965015, -0.02333152061039, -0.04211210676874, 0.00801021034064, 0.03277758616341, -0.05260385601595, 0.06377948953705, 0.04273731697500, 0.06145323689284, -0.05761715944068, -0.06161913050027, -0.05761715944068, 0.06145323689284, 0.04273731697500, 0.06377948953705, -0.05260385601595, 0.03277758616341, 0.00801021034064, -0.04211210676874, -0.02333152061039, -0.0291246 [...]
+0.02011120046566, 0.03447279299858, -0.00889141691347, 0.04703493050962, 0.04945313461415, -0.02912466965015, 0.05428131739349, 0.05634488400998, -0.00864631825412, 0.04683219028095, 0.02642596318589, 0.06145323689284, -0.04628401868063, -0.07081173873106, -0.01180521143300, 0.00155790816347, 0.06316887617837, 0.00155790816347, -0.01180521143300, -0.07081173873106, -0.04628401868063, 0.06145323689284, 0.02642596318589, 0.04683219028095, -0.00864631825412, 0.05634488400998, 0.054281317393 [...]
+0.01485220652451, 0.03105894328301, -0.00222561996695, 0.04741800568147, 0.05105292102523, -0.02333152061039, 0.05634488400998, 0.05742081875151, 0.00027003849811, 0.04273731697500, 0.01848943615820, 0.06969057246245, -0.05782350471105, -0.07747405815543, -0.02442011476440, 0.01371110078340, 0.07462272788890, 0.01371110078340, -0.02442011476440, -0.07747405815543, -0.05782350471105, 0.06969057246245, 0.01848943615820, 0.04273731697500, 0.00027003849811, 0.05742081875151, 0.05634488400998 [...]
+0.03501492614272, 0.02264757303314, -0.04548829345483, -0.00153126021194, -0.00866167202085, -0.04211210676874, -0.00864631825412, 0.00027003849811, -0.06399728423775, 0.03895560265498, 0.06316887617837, -0.04040858119196, 0.06720841455530, 0.02127053092509, 0.08701085516538, -0.08813390430467, -0.05605729667571, -0.08813390430467, 0.08701085516538, 0.02127053092509, 0.06720841455530, -0.04040858119196, 0.06316887617837, 0.03895560265498, -0.06399728423775, 0.00027003849811, -0.008646318 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+-0.02788397290880, -0.01159092756416, 0.04178512556283, 0.01610767548006, 0.02416013744322, 0.03277758616341, 0.02642596318589, 0.01848943615820, 0.06316887617837, -0.02442011476440, -0.05771185029271, 0.06656064247057, -0.09172320431048, -0.05169023594242, -0.10348456280590, 0.10156554753512, 0.09041357753814, 0.10156554753512, -0.10348456280590, -0.05169023594242, -0.09172320431048, 0.06656064247057, -0.05771185029271, -0.02442011476440, 0.06316887617837, 0.01848943615820, 0.0264259631 [...]
+0.03644296273535, 0.04741800568147, -0.02912466965015, 0.05259259692296, 0.05323681630826, -0.05260385601595, 0.06145323689284, 0.06969057246245, -0.04040858119196, 0.07992564670887, 0.06656064247057, 0.06717547808897, -0.03399633247860, -0.09751182812518, 0.02834885437642, -0.04599388822189, 0.07210126160498, -0.04599388822189, 0.02834885437642, -0.09751182812518, -0.03399633247860, 0.06717547808897, 0.06656064247057, 0.07992564670887, -0.04040858119196, 0.06969057246245, 0.061453236892 [...]
+-0.04567030131908, -0.04899968532023, 0.04507008450281, -0.04211210676874, -0.03931525868965, 0.06377948953705, -0.04628401868063, -0.05782350471105, 0.06720841455530, -0.08813390430467, -0.09172320431048, -0.03399633247860, -0.01132895341962, 0.07210126160498, -0.08232980948645, 0.10061964911512, -0.02658902847591, 0.10061964911512, -0.08232980948645, 0.07210126160498, -0.01132895341962, -0.03399633247860, -0.09172320431048, -0.08813390430467, 0.06720841455530, -0.05782350471105, -0.046 [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+-0.04548829345483, -0.03755053092747, 0.05428131739349, -0.01598181558280, -0.00905987177209, 0.06145323689284, -0.01180521143300, -0.02442011476440, 0.08701085516538, -0.07494530013047, -0.10348456280590, 0.02834885437642, -0.08232980948645, 0.00693420455927, -0.15403806518312, 0.17112027276390, 0.06683312417585, 0.17112027276390, -0.15403806518312, 0.00693420455927, -0.08232980948645, 0.02834885437642, -0.10348456280590, -0.07494530013047, 0.08701085516538, -0.02442011476440, -0.011805 [...]
+0.04309315116934, 0.03250874444113, -0.05398199531481, 0.00801021034064, 0.00027003849811, -0.05761715944068, 0.00155790816347, 0.01371110078340, -0.08813390430467, 0.06717547808897, 0.10156554753512, -0.04599388822189, 0.10061964911512, 0.01504573058692, 0.17112027276390, -0.18799488548807, -0.09766849275778, -0.18799488548807, 0.17112027276390, 0.01504573058692, 0.10061964911512, -0.04599388822189, 0.10156554753512, 0.06717547808897, -0.08813390430467, 0.01371110078340, 0.0015579081634 [...]
+0.04169802746791, 0.05105292102523, -0.03653013164974, 0.05323681630826, 0.05322433439424, -0.06161913050027, 0.06316887617837, 0.07462272788890, -0.05605729667571, 0.09733017222613, 0.09041357753814, 0.07210126160498, -0.02658902847591, -0.12535024958029, 0.06683312417585, -0.09766849275778, 0.09039717566130, -0.09766849275778, 0.06683312417585, -0.12535024958029, -0.02658902847591, 0.07210126160498, 0.09041357753814, 0.09733017222613, -0.05605729667571, 0.07462272788890, 0.063168876178 [...]
+0.04309315116934, 0.03250874444113, -0.05398199531481, 0.00801021034064, 0.00027003849811, -0.05761715944068, 0.00155790816347, 0.01371110078340, -0.08813390430467, 0.06717547808897, 0.10156554753512, -0.04599388822189, 0.10061964911512, 0.01504573058692, 0.17112027276390, -0.18799488548807, -0.09766849275778, -0.18799488548807, 0.17112027276390, 0.01504573058692, 0.10061964911512, -0.04599388822189, 0.10156554753512, 0.06717547808897, -0.08813390430467, 0.01371110078340, 0.0015579081634 [...]
+-0.04548829345483, -0.03755053092747, 0.05428131739349, -0.01598181558280, -0.00905987177209, 0.06145323689284, -0.01180521143300, -0.02442011476440, 0.08701085516538, -0.07494530013047, -0.10348456280590, 0.02834885437642, -0.08232980948645, 0.00693420455927, -0.15403806518312, 0.17112027276390, 0.06683312417585, 0.17112027276390, -0.15403806518312, 0.00693420455927, -0.08232980948645, 0.02834885437642, -0.10348456280590, -0.07494530013047, 0.08701085516538, -0.02442011476440, -0.011805 [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+-0.04567030131908, -0.04899968532023, 0.04507008450281, -0.04211210676874, -0.03931525868965, 0.06377948953705, -0.04628401868063, -0.05782350471105, 0.06720841455530, -0.08813390430467, -0.09172320431048, -0.03399633247860, -0.01132895341962, 0.07210126160498, -0.08232980948645, 0.10061964911512, -0.02658902847591, 0.10061964911512, -0.08232980948645, 0.07210126160498, -0.01132895341962, -0.03399633247860, -0.09172320431048, -0.08813390430467, 0.06720841455530, -0.05782350471105, -0.046 [...]
+0.03644296273535, 0.04741800568147, -0.02912466965015, 0.05259259692296, 0.05323681630826, -0.05260385601595, 0.06145323689284, 0.06969057246245, -0.04040858119196, 0.07992564670887, 0.06656064247057, 0.06717547808897, -0.03399633247860, -0.09751182812518, 0.02834885437642, -0.04599388822189, 0.07210126160498, -0.04599388822189, 0.02834885437642, -0.09751182812518, -0.03399633247860, 0.06717547808897, 0.06656064247057, 0.07992564670887, -0.04040858119196, 0.06969057246245, 0.061453236892 [...]
+-0.02788397290880, -0.01159092756416, 0.04178512556283, 0.01610767548006, 0.02416013744322, 0.03277758616341, 0.02642596318589, 0.01848943615820, 0.06316887617837, -0.02442011476440, -0.05771185029271, 0.06656064247057, -0.09172320431048, -0.05169023594242, -0.10348456280590, 0.10156554753512, 0.09041357753814, 0.10156554753512, -0.10348456280590, -0.05169023594242, -0.09172320431048, 0.06656064247057, -0.05771185029271, -0.02442011476440, 0.06316887617837, 0.01848943615820, 0.0264259631 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+0.03501492614272, 0.02264757303314, -0.04548829345483, -0.00153126021194, -0.00866167202085, -0.04211210676874, -0.00864631825412, 0.00027003849811, -0.06399728423775, 0.03895560265498, 0.06316887617837, -0.04040858119196, 0.06720841455530, 0.02127053092509, 0.08701085516538, -0.08813390430467, -0.05605729667571, -0.08813390430467, 0.08701085516538, 0.02127053092509, 0.06720841455530, -0.04040858119196, 0.06316887617837, 0.03895560265498, -0.06399728423775, 0.00027003849811, -0.008646318 [...]
+0.01485220652451, 0.03105894328301, -0.00222561996695, 0.04741800568147, 0.05105292102523, -0.02333152061039, 0.05634488400998, 0.05742081875151, 0.00027003849811, 0.04273731697500, 0.01848943615820, 0.06969057246245, -0.05782350471105, -0.07747405815543, -0.02442011476440, 0.01371110078340, 0.07462272788890, 0.01371110078340, -0.02442011476440, -0.07747405815543, -0.05782350471105, 0.06969057246245, 0.01848943615820, 0.04273731697500, 0.00027003849811, 0.05742081875151, 0.05634488400998 [...]
+0.02011120046566, 0.03447279299858, -0.00889141691347, 0.04703493050962, 0.04945313461415, -0.02912466965015, 0.05428131739349, 0.05634488400998, -0.00864631825412, 0.04683219028095, 0.02642596318589, 0.06145323689284, -0.04628401868063, -0.07081173873106, -0.01180521143300, 0.00155790816347, 0.06316887617837, 0.00155790816347, -0.01180521143300, -0.07081173873106, -0.04628401868063, 0.06145323689284, 0.02642596318589, 0.04683219028095, -0.00864631825412, 0.05634488400998, 0.054281317393 [...]
+0.01871143836380, 0.00282925577496, -0.03115444796200, -0.02111691650473, -0.02743053076570, -0.01909407501789, -0.02912466965015, -0.02333152061039, -0.04211210676874, 0.00801021034064, 0.03277758616341, -0.05260385601595, 0.06377948953705, 0.04273731697500, 0.06145323689284, -0.05761715944068, -0.06161913050027, -0.05761715944068, 0.06145323689284, 0.04273731697500, 0.06377948953705, -0.05260385601595, 0.03277758616341, 0.00801021034064, -0.04211210676874, -0.02333152061039, -0.0291246 [...]
+-0.00388219372909, -0.01984984065797, -0.00866995656907, -0.03797145192049, -0.04200352716372, 0.00881974876440, -0.04499172586632, -0.04326903841033, -0.01352102709593, -0.02333152061039, -0.00071933672845, -0.05728294659133, 0.05323681630826, 0.05742081875151, 0.03277758616341, -0.02546580226758, -0.06076173352856, -0.02546580226758, 0.03277758616341, 0.05742081875151, 0.05323681630826, -0.05728294659133, -0.00071933672845, -0.02333152061039, -0.01352102709593, -0.04326903841033, -0.04 [...]
+-0.03137727669444, -0.01958004332321, 0.04048597213817, 0.00253986035635, 0.00881974876440, 0.03568073651916, 0.00870175468576, 0.00114288282262, 0.05259259692296, -0.03045828585214, -0.04963002409968, 0.03296691756242, -0.05260385601595, -0.01764835261303, -0.06514516365773, 0.06522696614589, 0.04273731697500, 0.06522696614589, -0.06514516365773, -0.01764835261303, -0.05260385601595, 0.03296691756242, -0.04963002409968, -0.03045828585214, 0.05259259692296, 0.00114288282262, 0.0087017546 [...]
+-0.00338379798127, -0.02040531295214, -0.01000868479601, -0.04031243635006, -0.04499172586632, 0.00870175468576, -0.04883456542052, -0.04716218793354, -0.01598181558280, -0.02516948075949, 0.00027003849811, -0.06514516365773, 0.06145323689284, 0.06584304685785, 0.03895560265498, -0.03067019176029, -0.07081173873106, -0.03067019176029, 0.03895560265498, 0.06584304685785, 0.06145323689284, -0.06514516365773, 0.00027003849811, -0.02516948075949, -0.01598181558280, -0.04716218793354, -0.0488 [...]
+0.00282925577496, -0.01497649034024, -0.01690433755852, -0.03761152873895, -0.04326903841033, 0.00114288282262, -0.04716218793354, -0.04431851921725, -0.02546580226758, -0.01764835261303, 0.01029899957189, -0.06883698723352, 0.06969057246245, 0.06698830614494, 0.05116991106925, -0.04330187825715, -0.07747405815543, -0.04330187825715, 0.05116991106925, 0.06698830614494, 0.06969057246245, -0.06883698723352, 0.01029899957189, -0.01764835261303, -0.02546580226758, -0.04431851921725, -0.04716 [...]
+-0.04200139277956, -0.03645408668750, 0.04703493050962, -0.01909407501789, -0.01352102709593, 0.05259259692296, -0.01598181558280, -0.02546580226758, 0.06377948953705, -0.05761715944068, -0.07081173873106, 0.00898729611428, -0.04040858119196, 0.01371110078340, -0.07419862922226, 0.07992564670887, 0.02127053092509, 0.07992564670887, -0.07419862922226, 0.01371110078340, -0.04040858119196, 0.00898729611428, -0.07081173873106, -0.05761715944068, 0.06377948953705, -0.02546580226758, -0.015981 [...]
+0.02663318777774, 0.01076407940667, -0.03980537034422, -0.01578529983234, -0.02333152061039, -0.03045828585214, -0.02516948075949, -0.01764835261303, -0.05761715944068, 0.02156735149891, 0.05116991106925, -0.05912294255307, 0.07992564670887, 0.04485675423343, 0.08752809455106, -0.08513999504483, -0.07614567822515, -0.08513999504483, 0.08752809455106, 0.04485675423343, 0.07992564670887, -0.05912294255307, 0.05116991106925, 0.02156735149891, -0.05761715944068, -0.01764835261303, -0.0251694 [...]
+0.03963047977889, 0.02926181365419, -0.04899968532023, 0.00629983820314, -0.00071933672845, -0.04963002409968, 0.00027003849811, 0.01029899957189, -0.07081173873106, 0.05116991106925, 0.07462272788890, -0.03318526107069, 0.06656064247057, 0.00998778878484, 0.09733017222613, -0.10125366504812, -0.05169023594242, -0.10125366504812, 0.09733017222613, 0.00998778878484, 0.06656064247057, -0.03318526107069, 0.07462272788890, 0.05116991106925, -0.07081173873106, 0.01029899957189, 0.000270038498 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+0.03644296273535, 0.04741800568147, -0.02912466965015, 0.05259259692296, 0.05323681630826, -0.05260385601595, 0.06145323689284, 0.06969057246245, -0.04040858119196, 0.07992564670887, 0.06656064247057, 0.06717547808897, -0.03399633247860, -0.09751182812518, 0.02834885437642, -0.04599388822189, 0.07210126160498, -0.04599388822189, 0.02834885437642, -0.09751182812518, -0.03399633247860, 0.06717547808897, 0.06656064247057, 0.07992564670887, -0.04040858119196, 0.06969057246245, 0.061453236892 [...]
+0.00881974876440, 0.02821667474258, 0.00629983820314, 0.05121834474517, 0.05742081875151, -0.01764835261303, 0.06584304685785, 0.06698830614494, 0.01371110078340, 0.04485675423343, 0.00998778878484, 0.10334674409940, -0.09751182812518, -0.11954033404934, -0.05916188988776, 0.04399094217963, 0.13297118107692, 0.04399094217963, -0.05916188988776, -0.11954033404934, -0.09751182812518, 0.10334674409940, 0.00998778878484, 0.04485675423343, 0.01371110078340, 0.06698830614494, 0.06584304685785, [...]
+0.04703493050962, 0.04755584645599, -0.04883456542052, 0.03669569988478, 0.03277758616341, -0.06514516365773, 0.03895560265498, 0.05116991106925, -0.07419862922226, 0.08752809455106, 0.09733017222613, 0.02003044394070, 0.02834885437642, -0.05916188988776, 0.10061964911512, -0.11875106261662, 0.00693420455927, -0.11875106261662, 0.10061964911512, -0.05916188988776, 0.02834885437642, 0.02003044394070, 0.09733017222613, 0.08752809455106, -0.07419862922226, 0.05116991106925, 0.03895560265498 [...]
+-0.04746872842254, -0.04513877691637, 0.05166746230846, -0.03045828585214, -0.02546580226758, 0.06522696614589, -0.03067019176029, -0.04330187825715, 0.07992564670887, -0.08513999504483, -0.10125366504812, -0.00486213436803, -0.04599388822189, 0.04399094217963, -0.11875106261662, 0.13658472451851, 0.01504573058692, 0.13658472451851, -0.11875106261662, 0.04399094217963, -0.04599388822189, -0.00486213436803, -0.10125366504812, -0.08513999504483, 0.07992564670887, -0.04330187825715, -0.0306 [...]
+-0.02743053076570, -0.04326903841033, 0.01610767548006, -0.05728294659133, -0.06076173352856, 0.04273731697500, -0.07081173873106, -0.07747405815543, 0.02127053092509, -0.07614567822515, -0.05169023594242, -0.09751182812518, 0.07210126160498, 0.13297118107692, 0.00693420455927, 0.01504573058692, -0.12535024958029, 0.01504573058692, 0.00693420455927, 0.13297118107692, 0.07210126160498, -0.09751182812518, -0.05169023594242, -0.07614567822515, 0.02127053092509, -0.07747405815543, -0.0708117 [...]
+-0.04746872842254, -0.04513877691637, 0.05166746230846, -0.03045828585214, -0.02546580226758, 0.06522696614589, -0.03067019176029, -0.04330187825715, 0.07992564670887, -0.08513999504483, -0.10125366504812, -0.00486213436803, -0.04599388822189, 0.04399094217963, -0.11875106261662, 0.13658472451851, 0.01504573058692, 0.13658472451851, -0.11875106261662, 0.04399094217963, -0.04599388822189, -0.00486213436803, -0.10125366504812, -0.08513999504483, 0.07992564670887, -0.04330187825715, -0.0306 [...]
+0.04703493050962, 0.04755584645599, -0.04883456542052, 0.03669569988478, 0.03277758616341, -0.06514516365773, 0.03895560265498, 0.05116991106925, -0.07419862922226, 0.08752809455106, 0.09733017222613, 0.02003044394070, 0.02834885437642, -0.05916188988776, 0.10061964911512, -0.11875106261662, 0.00693420455927, -0.11875106261662, 0.10061964911512, -0.05916188988776, 0.02834885437642, 0.02003044394070, 0.09733017222613, 0.08752809455106, -0.07419862922226, 0.05116991106925, 0.03895560265498 [...]
+0.00881974876440, 0.02821667474258, 0.00629983820314, 0.05121834474517, 0.05742081875151, -0.01764835261303, 0.06584304685785, 0.06698830614494, 0.01371110078340, 0.04485675423343, 0.00998778878484, 0.10334674409940, -0.09751182812518, -0.11954033404934, -0.05916188988776, 0.04399094217963, 0.13297118107692, 0.04399094217963, -0.05916188988776, -0.11954033404934, -0.09751182812518, 0.10334674409940, 0.00998778878484, 0.04485675423343, 0.01371110078340, 0.06698830614494, 0.06584304685785, [...]
+0.03644296273535, 0.04741800568147, -0.02912466965015, 0.05259259692296, 0.05323681630826, -0.05260385601595, 0.06145323689284, 0.06969057246245, -0.04040858119196, 0.07992564670887, 0.06656064247057, 0.06717547808897, -0.03399633247860, -0.09751182812518, 0.02834885437642, -0.04599388822189, 0.07210126160498, -0.04599388822189, 0.02834885437642, -0.09751182812518, -0.03399633247860, 0.06717547808897, 0.06656064247057, 0.07992564670887, -0.04040858119196, 0.06969057246245, 0.061453236892 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+0.03963047977889, 0.02926181365419, -0.04899968532023, 0.00629983820314, -0.00071933672845, -0.04963002409968, 0.00027003849811, 0.01029899957189, -0.07081173873106, 0.05116991106925, 0.07462272788890, -0.03318526107069, 0.06656064247057, 0.00998778878484, 0.09733017222613, -0.10125366504812, -0.05169023594242, -0.10125366504812, 0.09733017222613, 0.00998778878484, 0.06656064247057, -0.03318526107069, 0.07462272788890, 0.05116991106925, -0.07081173873106, 0.01029899957189, 0.000270038498 [...]
+0.02663318777774, 0.01076407940667, -0.03980537034422, -0.01578529983234, -0.02333152061039, -0.03045828585214, -0.02516948075949, -0.01764835261303, -0.05761715944068, 0.02156735149891, 0.05116991106925, -0.05912294255307, 0.07992564670887, 0.04485675423343, 0.08752809455106, -0.08513999504483, -0.07614567822515, -0.08513999504483, 0.08752809455106, 0.04485675423343, 0.07992564670887, -0.05912294255307, 0.05116991106925, 0.02156735149891, -0.05761715944068, -0.01764835261303, -0.0251694 [...]
+-0.04200139277956, -0.03645408668750, 0.04703493050962, -0.01909407501789, -0.01352102709593, 0.05259259692296, -0.01598181558280, -0.02546580226758, 0.06377948953705, -0.05761715944068, -0.07081173873106, 0.00898729611428, -0.04040858119196, 0.01371110078340, -0.07419862922226, 0.07992564670887, 0.02127053092509, 0.07992564670887, -0.07419862922226, 0.01371110078340, -0.04040858119196, 0.00898729611428, -0.07081173873106, -0.05761715944068, 0.06377948953705, -0.02546580226758, -0.015981 [...]
+0.00282925577496, -0.01497649034024, -0.01690433755852, -0.03761152873895, -0.04326903841033, 0.00114288282262, -0.04716218793354, -0.04431851921725, -0.02546580226758, -0.01764835261303, 0.01029899957189, -0.06883698723352, 0.06969057246245, 0.06698830614494, 0.05116991106925, -0.04330187825715, -0.07747405815543, -0.04330187825715, 0.05116991106925, 0.06698830614494, 0.06969057246245, -0.06883698723352, 0.01029899957189, -0.01764835261303, -0.02546580226758, -0.04431851921725, -0.04716 [...]
+-0.00338379798127, -0.02040531295214, -0.01000868479601, -0.04031243635006, -0.04499172586632, 0.00870175468576, -0.04883456542052, -0.04716218793354, -0.01598181558280, -0.02516948075949, 0.00027003849811, -0.06514516365773, 0.06145323689284, 0.06584304685785, 0.03895560265498, -0.03067019176029, -0.07081173873106, -0.03067019176029, 0.03895560265498, 0.06584304685785, 0.06145323689284, -0.06514516365773, 0.00027003849811, -0.02516948075949, -0.01598181558280, -0.04716218793354, -0.0488 [...]
+-0.03137727669444, -0.01958004332321, 0.04048597213817, 0.00253986035635, 0.00881974876440, 0.03568073651916, 0.00870175468576, 0.00114288282262, 0.05259259692296, -0.03045828585214, -0.04963002409968, 0.03296691756242, -0.05260385601595, -0.01764835261303, -0.06514516365773, 0.06522696614589, 0.04273731697500, 0.06522696614589, -0.06514516365773, -0.01764835261303, -0.05260385601595, 0.03296691756242, -0.04963002409968, -0.03045828585214, 0.05259259692296, 0.00114288282262, 0.0087017546 [...]
+0.03800181165995, 0.03438945519666, -0.04028853365296, 0.02051771641111, 0.01595838913427, -0.04512890076845, 0.01794329647509, 0.02522891682511, -0.04939808301205, 0.04745915084934, 0.05428131739349, -0.00071933672845, 0.02416013744322, -0.01598181558280, 0.04963142214735, -0.05403298716581, -0.00864631825412, -0.05403298716581, 0.04963142214735, -0.01598181558280, 0.02416013744322, -0.00071933672845, 0.05428131739349, 0.04745915084934, -0.04939808301205, 0.02522891682511, 0.01794329647 [...]
+-0.02428439051753, -0.03605961724444, 0.01485220652451, -0.04410886072389, -0.04512890076845, 0.03282161335501, -0.04899968532023, -0.05170195653292, 0.01610767548006, -0.04716218793354, -0.03144564133374, -0.04963002409968, 0.03277758616341, 0.05946062873198, 0.00027003849811, 0.00869067734621, -0.04836796828267, 0.00869067734621, 0.00027003849811, 0.05946062873198, 0.03277758616341, -0.04963002409968, -0.03144564133374, -0.04716218793354, 0.01610767548006, -0.05170195653292, -0.0489996 [...]
+0.04014593082298, 0.03678691831046, -0.04271220519611, 0.02264757303314, 0.01794329647509, -0.04899968532023, 0.02038138287138, 0.02847526258331, -0.05430453818238, 0.05323681630826, 0.06083851296868, 0.00027003849811, 0.02642596318589, -0.01933288371895, 0.05627305279151, -0.06161913050027, -0.00879307760295, -0.06161913050027, 0.05627305279151, -0.01933288371895, 0.02642596318589, 0.00027003849811, 0.06083851296868, 0.05323681630826, -0.05430453818238, 0.02847526258331, 0.0203813828713 [...]
+0.04123067549901, 0.04048597213817, -0.04200352716372, 0.02926181365419, 0.02522891682511, -0.05170195653292, 0.02847526258331, 0.03669569988478, -0.05403298716581, 0.05946062873198, 0.06377948953705, 0.01029899957189, 0.01848943615820, -0.03067019176029, 0.05387660966815, -0.06095484289857, 0.00155790816347, -0.06095484289857, 0.05387660966815, -0.03067019176029, 0.01848943615820, 0.01029899957189, 0.06377948953705, 0.05946062873198, -0.05403298716581, 0.03669569988478, 0.02847526258331 [...]
+-0.00905031863291, -0.02613601062284, -0.00434559103408, -0.04499172586632, -0.04939808301205, 0.01610767548006, -0.05430453818238, -0.05403298716581, -0.00905987177209, -0.03484669808203, -0.00879307760295, -0.07081173873106, 0.06316887617837, 0.07536267012088, 0.03433801412888, -0.02442011476440, -0.07714535201411, -0.02442011476440, 0.03433801412888, 0.07536267012088, 0.06316887617837, -0.07081173873106, -0.00879307760295, -0.03484669808203, -0.00905987177209, -0.05403298716581, -0.05 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+0.02073808121767, 0.03644296273535, -0.00875565887367, 0.05105292102523, 0.05428131739349, -0.03144564133374, 0.06083851296868, 0.06377948953705, -0.00879307760295, 0.05387660966815, 0.03017589095093, 0.07462272788890, -0.05771185029271, -0.08813390430467, -0.01626781358073, 0.00344457002262, 0.08094445627940, 0.00344457002262, -0.01626781358073, -0.08813390430467, -0.05771185029271, 0.07462272788890, 0.03017589095093, 0.05387660966815, -0.00879307760295, 0.06377948953705, 0.060838512968 [...]
+0.03963047977889, 0.02926181365419, -0.04899968532023, 0.00629983820314, -0.00071933672845, -0.04963002409968, 0.00027003849811, 0.01029899957189, -0.07081173873106, 0.05116991106925, 0.07462272788890, -0.03318526107069, 0.06656064247057, 0.00998778878484, 0.09733017222613, -0.10125366504812, -0.05169023594242, -0.10125366504812, 0.09733017222613, 0.00998778878484, 0.06656064247057, -0.03318526107069, 0.07462272788890, 0.05116991106925, -0.07081173873106, 0.01029899957189, 0.000270038498 [...]
+-0.02788397290880, -0.01159092756416, 0.04178512556283, 0.01610767548006, 0.02416013744322, 0.03277758616341, 0.02642596318589, 0.01848943615820, 0.06316887617837, -0.02442011476440, -0.05771185029271, 0.06656064247057, -0.09172320431048, -0.05169023594242, -0.10348456280590, 0.10156554753512, 0.09041357753814, 0.10156554753512, -0.10348456280590, -0.05169023594242, -0.09172320431048, 0.06656064247057, -0.05771185029271, -0.02442011476440, 0.06316887617837, 0.01848943615820, 0.0264259631 [...]
+-0.04512890076845, -0.03980537034422, 0.05105292102523, -0.02183846096527, -0.01598181558280, 0.05946062873198, -0.01933288371895, -0.03067019176029, 0.07536267012088, -0.07051895298226, -0.08813390430467, 0.00998778878484, -0.05169023594242, 0.02003044394070, -0.10150612803431, 0.11129083655510, 0.02834885437642, 0.11129083655510, -0.10150612803431, 0.02003044394070, -0.05169023594242, 0.00998778878484, -0.08813390430467, -0.07051895298226, 0.07536267012088, -0.03067019176029, -0.019332 [...]
+-0.00434559103408, 0.01552199992789, 0.02038138287138, 0.04222968115101, 0.04963142214735, 0.00027003849811, 0.05627305279151, 0.05387660966815, 0.03433801412888, 0.02127053092509, -0.01626781358073, 0.09733017222613, -0.10348456280590, -0.10150612803431, -0.08280335937603, 0.07210126160498, 0.12603831803759, 0.07210126160498, -0.08280335937603, -0.10150612803431, -0.10348456280590, 0.09733017222613, -0.01626781358073, 0.02127053092509, 0.03433801412888, 0.05387660966815, 0.0562730527915 [...]
+-0.00222561996695, -0.02205338028065, -0.01352102709593, -0.04716218793354, -0.05403298716581, 0.00869067734621, -0.06161913050027, -0.06095484289857, -0.02442011476440, -0.03318526107069, 0.00344457002262, -0.10125366504812, 0.10156554753512, 0.11129083655510, 0.07210126160498, -0.05916188988776, -0.13058003873376, -0.05916188988776, 0.07210126160498, 0.11129083655510, 0.10156554753512, -0.10125366504812, 0.00344457002262, -0.03318526107069, -0.02442011476440, -0.06095484289857, -0.0616 [...]
+0.03804111121964, 0.02522891682511, -0.04990035313554, -0.00071933672845, -0.00864631825412, -0.04836796828267, -0.00879307760295, 0.00155790816347, -0.07714535201411, 0.04915146033489, 0.08094445627940, -0.05169023594242, 0.09041357753814, 0.02834885437642, 0.12603831803759, -0.13058003873376, -0.08232980948645, -0.13058003873376, 0.12603831803759, 0.02834885437642, 0.09041357753814, -0.05169023594242, 0.08094445627940, 0.04915146033489, -0.07714535201411, 0.00155790816347, -0.008793077 [...]
+-0.00222561996695, -0.02205338028065, -0.01352102709593, -0.04716218793354, -0.05403298716581, 0.00869067734621, -0.06161913050027, -0.06095484289857, -0.02442011476440, -0.03318526107069, 0.00344457002262, -0.10125366504812, 0.10156554753512, 0.11129083655510, 0.07210126160498, -0.05916188988776, -0.13058003873376, -0.05916188988776, 0.07210126160498, 0.11129083655510, 0.10156554753512, -0.10125366504812, 0.00344457002262, -0.03318526107069, -0.02442011476440, -0.06095484289857, -0.0616 [...]
+-0.00434559103408, 0.01552199992789, 0.02038138287138, 0.04222968115101, 0.04963142214735, 0.00027003849811, 0.05627305279151, 0.05387660966815, 0.03433801412888, 0.02127053092509, -0.01626781358073, 0.09733017222613, -0.10348456280590, -0.10150612803431, -0.08280335937603, 0.07210126160498, 0.12603831803759, 0.07210126160498, -0.08280335937603, -0.10150612803431, -0.10348456280590, 0.09733017222613, -0.01626781358073, 0.02127053092509, 0.03433801412888, 0.05387660966815, 0.0562730527915 [...]
+-0.04512890076845, -0.03980537034422, 0.05105292102523, -0.02183846096527, -0.01598181558280, 0.05946062873198, -0.01933288371895, -0.03067019176029, 0.07536267012088, -0.07051895298226, -0.08813390430467, 0.00998778878484, -0.05169023594242, 0.02003044394070, -0.10150612803431, 0.11129083655510, 0.02834885437642, 0.11129083655510, -0.10150612803431, 0.02003044394070, -0.05169023594242, 0.00998778878484, -0.08813390430467, -0.07051895298226, 0.07536267012088, -0.03067019176029, -0.019332 [...]
+-0.02788397290880, -0.01159092756416, 0.04178512556283, 0.01610767548006, 0.02416013744322, 0.03277758616341, 0.02642596318589, 0.01848943615820, 0.06316887617837, -0.02442011476440, -0.05771185029271, 0.06656064247057, -0.09172320431048, -0.05169023594242, -0.10348456280590, 0.10156554753512, 0.09041357753814, 0.10156554753512, -0.10348456280590, -0.05169023594242, -0.09172320431048, 0.06656064247057, -0.05771185029271, -0.02442011476440, 0.06316887617837, 0.01848943615820, 0.0264259631 [...]
+0.03963047977889, 0.02926181365419, -0.04899968532023, 0.00629983820314, -0.00071933672845, -0.04963002409968, 0.00027003849811, 0.01029899957189, -0.07081173873106, 0.05116991106925, 0.07462272788890, -0.03318526107069, 0.06656064247057, 0.00998778878484, 0.09733017222613, -0.10125366504812, -0.05169023594242, -0.10125366504812, 0.09733017222613, 0.00998778878484, 0.06656064247057, -0.03318526107069, 0.07462272788890, 0.05116991106925, -0.07081173873106, 0.01029899957189, 0.000270038498 [...]
+0.02073808121767, 0.03644296273535, -0.00875565887367, 0.05105292102523, 0.05428131739349, -0.03144564133374, 0.06083851296868, 0.06377948953705, -0.00879307760295, 0.05387660966815, 0.03017589095093, 0.07462272788890, -0.05771185029271, -0.08813390430467, -0.01626781358073, 0.00344457002262, 0.08094445627940, 0.00344457002262, -0.01626781358073, -0.08813390430467, -0.05771185029271, 0.07462272788890, 0.03017589095093, 0.05387660966815, -0.00879307760295, 0.06377948953705, 0.060838512968 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+-0.00905031863291, -0.02613601062284, -0.00434559103408, -0.04499172586632, -0.04939808301205, 0.01610767548006, -0.05430453818238, -0.05403298716581, -0.00905987177209, -0.03484669808203, -0.00879307760295, -0.07081173873106, 0.06316887617837, 0.07536267012088, 0.03433801412888, -0.02442011476440, -0.07714535201411, -0.02442011476440, 0.03433801412888, 0.07536267012088, 0.06316887617837, -0.07081173873106, -0.00879307760295, -0.03484669808203, -0.00905987177209, -0.05403298716581, -0.05 [...]
+0.04123067549901, 0.04048597213817, -0.04200352716372, 0.02926181365419, 0.02522891682511, -0.05170195653292, 0.02847526258331, 0.03669569988478, -0.05403298716581, 0.05946062873198, 0.06377948953705, 0.01029899957189, 0.01848943615820, -0.03067019176029, 0.05387660966815, -0.06095484289857, 0.00155790816347, -0.06095484289857, 0.05387660966815, -0.03067019176029, 0.01848943615820, 0.01029899957189, 0.06377948953705, 0.05946062873198, -0.05403298716581, 0.03669569988478, 0.02847526258331 [...]
+0.04014593082298, 0.03678691831046, -0.04271220519611, 0.02264757303314, 0.01794329647509, -0.04899968532023, 0.02038138287138, 0.02847526258331, -0.05430453818238, 0.05323681630826, 0.06083851296868, 0.00027003849811, 0.02642596318589, -0.01933288371895, 0.05627305279151, -0.06161913050027, -0.00879307760295, -0.06161913050027, 0.05627305279151, -0.01933288371895, 0.02642596318589, 0.00027003849811, 0.06083851296868, 0.05323681630826, -0.05430453818238, 0.02847526258331, 0.0203813828713 [...]
+-0.02428439051753, -0.03605961724444, 0.01485220652451, -0.04410886072389, -0.04512890076845, 0.03282161335501, -0.04899968532023, -0.05170195653292, 0.01610767548006, -0.04716218793354, -0.03144564133374, -0.04963002409968, 0.03277758616341, 0.05946062873198, 0.00027003849811, 0.00869067734621, -0.04836796828267, 0.00869067734621, 0.00027003849811, 0.05946062873198, 0.03277758616341, -0.04963002409968, -0.03144564133374, -0.04716218793354, 0.01610767548006, -0.05170195653292, -0.0489996 [...]
+0.03232593614224, 0.02255847953252, -0.03939946075725, 0.00282925577496, -0.00283618587179, -0.03645408668750, -0.00222561996695, 0.00493640288370, -0.04899968532023, 0.03250874444113, 0.04745915084934, -0.02333152061039, 0.04222968115101, 0.00864062075235, 0.05634488400998, -0.05728294659133, -0.03144564133374, -0.05728294659133, 0.05634488400998, 0.00864062075235, 0.04222968115101, -0.02333152061039, 0.04745915084934, 0.03250874444113, -0.04899968532023, 0.00493640288370, -0.0022256199 [...]
+-0.03446030853185, -0.04008674845418, 0.02965188168129, -0.03814396416671, -0.03645408668750, 0.04341150826710, -0.03980537034422, -0.04513877691637, 0.03510685742783, -0.05349976932781, -0.04716218793354, -0.03045828585214, 0.00801021034064, 0.04496452881899, -0.02516948075949, 0.03296691756242, -0.02546580226758, 0.03296691756242, -0.02516948075949, 0.04496452881899, 0.00801021034064, -0.03045828585214, -0.04716218793354, -0.05349976932781, 0.03510685742783, -0.04513877691637, -0.03980 [...]
+0.03438945519666, 0.02443728561702, -0.04200139277956, 0.00380202623900, -0.00222561996695, -0.03980537034422, -0.00153126021194, 0.00629983820314, -0.05398199531481, 0.03669569988478, 0.05323681630826, -0.02516948075949, 0.04683219028095, 0.00869067734621, 0.06377948953705, -0.06514516365773, -0.03484669808203, -0.06514516365773, 0.06377948953705, 0.00869067734621, 0.04683219028095, -0.02516948075949, 0.05323681630826, 0.03669569988478, -0.05398199531481, 0.00629983820314, -0.0015312602 [...]
+0.03785607654408, 0.02991156721912, -0.04410886072389, 0.01076407940667, 0.00493640288370, -0.04513877691637, 0.00629983820314, 0.01466865762037, -0.05728294659133, 0.04496452881899, 0.05946062873198, -0.01764835261303, 0.04273731697500, -0.00086468661469, 0.06584304685785, -0.06883698723352, -0.02803496562843, -0.06883698723352, 0.06584304685785, -0.00086468661469, 0.04273731697500, -0.01764835261303, 0.05946062873198, 0.04496452881899, -0.05728294659133, 0.01466865762037, 0.00629983820 [...]
+-0.02511329203000, -0.03797145192049, 0.01512570665415, -0.04746872842254, -0.04899968532023, 0.03510685742783, -0.05398199531481, -0.05728294659133, 0.01700752911701, -0.05260385601595, -0.03484669808203, -0.05761715944068, 0.03895560265498, 0.06969057246245, 0.00155790816347, 0.00898729611428, -0.05782350471105, 0.00898729611428, 0.00155790816347, 0.06969057246245, 0.03895560265498, -0.05761715944068, -0.03484669808203, -0.05260385601595, 0.01700752911701, -0.05728294659133, -0.0539819 [...]
+0.04144419729370, 0.04348828141759, -0.04031243635006, 0.03568073651916, 0.03250874444113, -0.05349976932781, 0.03669569988478, 0.04496452881899, -0.05260385601595, 0.06522696614589, 0.06584304685785, 0.02156735149891, 0.00898729611428, -0.04330187825715, 0.05012494613301, -0.05912294255307, 0.01371110078340, -0.05912294255307, 0.05012494613301, -0.04330187825715, 0.00898729611428, 0.02156735149891, 0.06584304685785, 0.06522696614589, -0.05260385601595, 0.04496452881899, 0.03669569988478 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+0.02663318777774, 0.01076407940667, -0.03980537034422, -0.01578529983234, -0.02333152061039, -0.03045828585214, -0.02516948075949, -0.01764835261303, -0.05761715944068, 0.02156735149891, 0.05116991106925, -0.05912294255307, 0.07992564670887, 0.04485675423343, 0.08752809455106, -0.08513999504483, -0.07614567822515, -0.08513999504483, 0.08752809455106, 0.04485675423343, 0.07992564670887, -0.05912294255307, 0.05116991106925, 0.02156735149891, -0.05761715944068, -0.01764835261303, -0.0251694 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+-0.03645408668750, -0.02387116439873, 0.04755584645599, 0.00114288282262, 0.00864062075235, 0.04496452881899, 0.00869067734621, -0.00086468661469, 0.06969057246245, -0.04330187825715, -0.07051895298226, 0.04485675423343, -0.07614567822515, -0.02381038314910, -0.10125366504812, 0.10334674409940, 0.06525950351177, 0.10334674409940, -0.10125366504812, -0.02381038314910, -0.07614567822515, 0.04485675423343, -0.07051895298226, -0.04330187825715, 0.06969057246245, -0.00086468661469, 0.00869067 [...]
+0.01512570665415, 0.03282161335501, -0.00153126021194, 0.05166746230846, 0.05634488400998, -0.02516948075949, 0.06377948953705, 0.06584304685785, 0.00155790816347, 0.05012494613301, 0.02127053092509, 0.08752809455106, -0.07494530013047, -0.10125366504812, -0.03399633247860, 0.02003044394070, 0.10156554753512, 0.02003044394070, -0.03399633247860, -0.10125366504812, -0.07494530013047, 0.08752809455106, 0.02127053092509, 0.05012494613301, 0.00155790816347, 0.06584304685785, 0.06377948953705 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+0.02264757303314, 0.00493640288370, -0.03755053092747, -0.02333152061039, -0.03144564133374, -0.02546580226758, -0.03484669808203, -0.02803496562843, -0.05782350471105, 0.01371110078340, 0.04915146033489, -0.07614567822515, 0.09733017222613, 0.06525950351177, 0.10156554753512, -0.09751182812518, -0.10150612803431, -0.09751182812518, 0.10156554753512, 0.06525950351177, 0.09733017222613, -0.07614567822515, 0.04915146033489, 0.01371110078340, -0.05782350471105, -0.02803496562843, -0.0348466 [...]
+-0.02111691650473, -0.03761152873895, 0.00870175468576, -0.05349976932781, -0.05728294659133, 0.03296691756242, -0.06514516365773, -0.06883698723352, 0.00898729611428, -0.05912294255307, -0.03318526107069, -0.08513999504483, 0.06717547808897, 0.10334674409940, 0.02003044394070, -0.00486213436803, -0.09751182812518, -0.00486213436803, 0.02003044394070, 0.10334674409940, 0.06717547808897, -0.08513999504483, -0.03318526107069, -0.05912294255307, 0.00898729611428, -0.06883698723352, -0.06514 [...]
+0.01512570665415, 0.03282161335501, -0.00153126021194, 0.05166746230846, 0.05634488400998, -0.02516948075949, 0.06377948953705, 0.06584304685785, 0.00155790816347, 0.05012494613301, 0.02127053092509, 0.08752809455106, -0.07494530013047, -0.10125366504812, -0.03399633247860, 0.02003044394070, 0.10156554753512, 0.02003044394070, -0.03399633247860, -0.10125366504812, -0.07494530013047, 0.08752809455106, 0.02127053092509, 0.05012494613301, 0.00155790816347, 0.06584304685785, 0.06377948953705 [...]
+-0.03645408668750, -0.02387116439873, 0.04755584645599, 0.00114288282262, 0.00864062075235, 0.04496452881899, 0.00869067734621, -0.00086468661469, 0.06969057246245, -0.04330187825715, -0.07051895298226, 0.04485675423343, -0.07614567822515, -0.02381038314910, -0.10125366504812, 0.10334674409940, 0.06525950351177, 0.10334674409940, -0.10125366504812, -0.02381038314910, -0.07614567822515, 0.04485675423343, -0.07051895298226, -0.04330187825715, 0.06969057246245, -0.00086468661469, 0.00869067 [...]
+-0.01000868479601, 0.00881974876440, 0.02522891682511, 0.03510685742783, 0.04222968115101, 0.00801021034064, 0.04683219028095, 0.04273731697500, 0.03895560265498, 0.00898729611428, -0.02442011476440, 0.07992564670887, -0.08813390430467, -0.07614567822515, -0.07494530013047, 0.06717547808897, 0.09733017222613, 0.06717547808897, -0.07494530013047, -0.07614567822515, -0.08813390430467, 0.07992564670887, -0.02442011476440, 0.00898729611428, 0.03895560265498, 0.04273731697500, 0.0468321902809 [...]
+0.02663318777774, 0.01076407940667, -0.03980537034422, -0.01578529983234, -0.02333152061039, -0.03045828585214, -0.02516948075949, -0.01764835261303, -0.05761715944068, 0.02156735149891, 0.05116991106925, -0.05912294255307, 0.07992564670887, 0.04485675423343, 0.08752809455106, -0.08513999504483, -0.07614567822515, -0.08513999504483, 0.08752809455106, 0.04485675423343, 0.07992564670887, -0.05912294255307, 0.05116991106925, 0.02156735149891, -0.05761715944068, -0.01764835261303, -0.0251694 [...]
+0.03447279299858, 0.04411250286631, -0.02743053076570, 0.04755584645599, 0.04745915084934, -0.04716218793354, 0.05323681630826, 0.05946062873198, -0.03484669808203, 0.06584304685785, 0.05387660966815, 0.05116991106925, -0.02442011476440, -0.07051895298226, 0.02127053092509, -0.03318526107069, 0.04915146033489, -0.03318526107069, 0.02127053092509, -0.07051895298226, -0.02442011476440, 0.05116991106925, 0.05387660966815, 0.06584304685785, -0.03484669808203, 0.05946062873198, 0.053236816308 [...]
+0.04144419729370, 0.04348828141759, -0.04031243635006, 0.03568073651916, 0.03250874444113, -0.05349976932781, 0.03669569988478, 0.04496452881899, -0.05260385601595, 0.06522696614589, 0.06584304685785, 0.02156735149891, 0.00898729611428, -0.04330187825715, 0.05012494613301, -0.05912294255307, 0.01371110078340, -0.05912294255307, 0.05012494613301, -0.04330187825715, 0.00898729611428, 0.02156735149891, 0.06584304685785, 0.06522696614589, -0.05260385601595, 0.04496452881899, 0.03669569988478 [...]
+-0.02511329203000, -0.03797145192049, 0.01512570665415, -0.04746872842254, -0.04899968532023, 0.03510685742783, -0.05398199531481, -0.05728294659133, 0.01700752911701, -0.05260385601595, -0.03484669808203, -0.05761715944068, 0.03895560265498, 0.06969057246245, 0.00155790816347, 0.00898729611428, -0.05782350471105, 0.00898729611428, 0.00155790816347, 0.06969057246245, 0.03895560265498, -0.05761715944068, -0.03484669808203, -0.05260385601595, 0.01700752911701, -0.05728294659133, -0.0539819 [...]
+0.03785607654408, 0.02991156721912, -0.04410886072389, 0.01076407940667, 0.00493640288370, -0.04513877691637, 0.00629983820314, 0.01466865762037, -0.05728294659133, 0.04496452881899, 0.05946062873198, -0.01764835261303, 0.04273731697500, -0.00086468661469, 0.06584304685785, -0.06883698723352, -0.02803496562843, -0.06883698723352, 0.06584304685785, -0.00086468661469, 0.04273731697500, -0.01764835261303, 0.05946062873198, 0.04496452881899, -0.05728294659133, 0.01466865762037, 0.00629983820 [...]
+0.03438945519666, 0.02443728561702, -0.04200139277956, 0.00380202623900, -0.00222561996695, -0.03980537034422, -0.00153126021194, 0.00629983820314, -0.05398199531481, 0.03669569988478, 0.05323681630826, -0.02516948075949, 0.04683219028095, 0.00869067734621, 0.06377948953705, -0.06514516365773, -0.03484669808203, -0.06514516365773, 0.06377948953705, 0.00869067734621, 0.04683219028095, -0.02516948075949, 0.05323681630826, 0.03669569988478, -0.05398199531481, 0.00629983820314, -0.0015312602 [...]
+-0.03446030853185, -0.04008674845418, 0.02965188168129, -0.03814396416671, -0.03645408668750, 0.04341150826710, -0.03980537034422, -0.04513877691637, 0.03510685742783, -0.05349976932781, -0.04716218793354, -0.03045828585214, 0.00801021034064, 0.04496452881899, -0.02516948075949, 0.03296691756242, -0.02546580226758, 0.03296691756242, -0.02516948075949, 0.04496452881899, 0.00801021034064, -0.03045828585214, -0.04716218793354, -0.05349976932781, 0.03510685742783, -0.04513877691637, -0.03980 [...]
+
+static double f3ref[12288] = {
+7.74444231502662, -3.30460617132622, 2.22262450975110, -0.02265000742346, 4.57981527714915, -4.46200297698669, 5.30653639183482, -1.15214280730539, 0.45042591553746, 2.34613624356529, 7.26932678672958, 0.38036858510263, -3.66996429140484, -3.61576587061517, 2.45966152294346, -4.12637245433888, 1.09825033534010, -4.12637245433888, 2.45966152294346, -3.61576587061517, -3.66996429140484, 0.38036858510263, 7.26932678672957, 2.34613624356529, 0.45042591553746, -1.15214280730539, 5.30653639183 [...]
+-3.44849241719181, 2.83393816140164, -4.86046747390988, 9.38079257419346, -5.46504828859453, 5.80736227651040, -4.00599672704274, 7.41371253432584, -5.27568537649524, 4.71908443472533, 3.50001836968078, 1.97590706653304, -4.38342947940474, -1.18093691970083, 3.09051218026431, -6.19508346535584, 4.10336022219774, -6.19508346535584, 3.09051218026431, -1.18093691970083, -4.38342947940475, 1.97590706653303, 3.50001836968078, 4.71908443472532, -5.27568537649524, 7.41371253432582, -4.005996727 [...]
+-2.86416601217943, -8.60808565192260, 7.07272038803768, -1.85078415732380, -0.41817422677276, 2.07920722080515, -1.38353773076015, 1.43554088072311, 2.63563728711976, -6.90459822517653, 0.00635416658103, -1.97111276801481, 1.08572836254902, 6.08988781416648, -1.74385819486292, -0.15581221590921, 1.88886394075166, -0.15581221590922, -1.74385819486292, 6.08988781416648, 1.08572836254902, -1.97111276801480, 0.00635416658103, -6.90459822517652, 2.63563728711976, 1.43554088072311, -1.38353773 [...]
+-3.63768838908703, 6.51146418918496, -3.52023849143115, -3.26666008762003, -0.79141197977445, 0.11030155373336, -1.66756690081733, -3.29406647947230, 0.95722951420220, 0.02820346112595, -7.49808976976364, -0.14902290217018, 4.76321302172283, -0.27040478119413, -2.69155509169828, 6.62245548100018, -4.44660615959220, 6.62245548100018, -2.69155509169828, -0.27040478119413, 4.76321302172283, -0.14902290217017, -7.49808976976364, 0.02820346112595, 0.95722951420220, -3.29406647947230, -1.66756 [...]
+5.00904895279449, -5.04760356886646, 2.45400827308433, 2.32857540250695, 2.05100150692865, -2.02354236206146, 3.10712362036581, 1.67045960616215, -0.94676372761040, 1.03420252399012, 7.06084034562467, 0.43089411486126, -4.60307692646504, -1.03215812585098, 2.84192552608422, -5.74590762802640, 3.38656168598772, -5.74590762802640, 2.84192552608423, -1.03215812585099, -4.60307692646504, 0.43089411486126, 7.06084034562467, 1.03420252399012, -0.94676372761040, 1.67045960616215, 3.107123620365 [...]
+-3.33877962087733, 5.71555665735120, -2.66848666952597, -4.25112119556404, -0.21682133052970, -0.43295756695856, -1.24637771179251, -3.97704082344553, 1.63031501960668, -0.82772655089462, -7.62457282154426, -0.57848547281019, 5.35937233917291, -0.10618363258950, -2.76877075423901, 6.87379638938304, -4.44161265135408, 6.87379638938305, -2.76877075423901, -0.10618363258950, 5.35937233917292, -0.57848547281018, -7.62457282154426, -0.82772655089462, 1.63031501960668, -3.97704082344552, -1.24 [...]
+-5.05014490473224, -7.41667239093171, 6.07505533341960, -1.31227749889030, -1.90456935766031, 3.51533214643659, -2.98982751142837, 2.16028658728789, 2.06816764841105, -6.99212494539450, -1.93788364421032, -1.67821507154289, 1.49873179273464, 7.21775891118226, -2.57740873156455, 1.03551080768920, 1.34722011907049, 1.03551080768919, -2.57740873156455, 7.21775891118226, 1.49873179273464, -1.67821507154288, -1.93788364421032, -6.99212494539450, 2.06816764841105, 2.16028658728788, -2.98982751 [...]
+-2.41300782417371, 0.74493600528328, -2.13729932421246, 5.23769506839220, -3.28085174613910, 3.55766976471765, -2.46962156323022, 4.34106810546252, -2.68427669346718, 1.70275405023498, 2.16674865725326, 0.54234829176256, -1.90569976110202, -0.50647732352259, 2.25796709183844, -4.24221146756490, 3.31966616638922, -4.24221146756491, 2.25796709183844, -0.50647732352259, -1.90569976110202, 0.54234829176256, 2.16674865725326, 1.70275405023497, -2.68427669346718, 4.34106810546252, -2.469621563 [...]
+5.12480210840362, 1.09280090400396, -0.36072746990241, -1.61691888364554, 3.06265674825714, -3.60364385374449, 3.18345268102507, -2.47172505365689, 0.30309112472224, 2.52815580963259, 1.70644129003273, 0.79966216964325, -1.31225989550636, -2.69045064051649, 0.07862123531612, 0.60940470471168, -1.90175458108380, 0.60940470471168, 0.07862123531611, -2.69045064051649, -1.31225989550637, 0.79966216964325, 1.70644129003273, 2.52815580963259, 0.30309112472224, -2.47172505365689, 3.183452681025 [...]
+7.15207011384236, 5.13442842452098, -3.39061936807167, -1.27753859529645, 4.13404761353763, -5.58419173187169, 4.94420264342268, -4.20033080728172, 0.03284360886724, 5.19990500320383, 2.90819866047794, 0.94501105505199, -1.13008780896054, -6.80001035816794, 1.85278275462261, -0.38141565403651, -1.90055269185725, -0.38141565403650, 1.85278275462261, -6.80001035816794, -1.13008780896054, 0.94501105505199, 2.90819866047794, 5.19990500320383, 0.03284360886724, -4.20033080728172, 4.9442026434 [...]
+7.41547901331380, 2.81524238501025, -4.02035456032342, 5.23885638572911, 1.47029041649110, -2.23136119061919, 3.13572686616356, 1.97786272077885, -4.02927800788105, 8.31789983702216, 7.49952747963443, 2.78596877529615, -6.47007791187659, -6.33724447258133, 3.92957397696695, -5.73478485851572, 1.29181226980751, -5.73478485851571, 3.92957397696695, -6.33724447258134, -6.47007791187659, 2.78596877529614, 7.49952747963443, 8.31789983702215, -4.02927800788105, 1.97786272077884, 3.135726866163 [...]
+-4.60968742458002, -4.67142406988101, 3.00303261499480, 3.24328683211460, -3.74808594276695, 5.19820486472935, -3.77489538197461, 4.76405925026483, -0.06337430062342, -3.81353377509395, 1.78139202308631, -1.16269710542955, -0.48792078552730, 3.87065091793558, 0.58332084863417, -3.95998015793350, 4.67838970208850, -3.95998015793350, 0.58332084863418, 3.87065091793558, -0.48792078552730, -1.16269710542955, 1.78139202308630, -3.81353377509396, -0.06337430062342, 4.76405925026483, -3.7748953 [...]
+6.53018544775582, 6.11554206464931, -3.72729467869253, -3.51508047944537, 4.81842261197242, -6.34510027534184, 4.91775244784352, -5.66980207786843, 0.17341863431742, 5.46144253814456, -0.91467884962088, 1.61703255517642, -0.05489743160226, -5.50603920163742, -0.66176255486468, 4.30291226454501, -5.83734598265276, 4.30291226454501, -0.66176255486468, -5.50603920163742, -0.05489743160226, 1.61703255517641, -0.91467884962088, 5.46144253814457, 0.17341863431742, -5.66980207786842, 4.91775244 [...]
+-4.60968742458003, -4.67142406988101, 3.00303261499480, 3.24328683211461, -3.74808594276696, 5.19820486472936, -3.77489538197461, 4.76405925026484, -0.06337430062342, -3.81353377509395, 1.78139202308631, -1.16269710542956, -0.48792078552730, 3.87065091793558, 0.58332084863418, -3.95998015793350, 4.67838970208850, -3.95998015793351, 0.58332084863418, 3.87065091793558, -0.48792078552730, -1.16269710542955, 1.78139202308631, -3.81353377509396, -0.06337430062342, 4.76405925026483, -3.7748953 [...]
+7.41547901331379, 2.81524238501025, -4.02035456032342, 5.23885638572911, 1.47029041649110, -2.23136119061919, 3.13572686616356, 1.97786272077884, -4.02927800788105, 8.31789983702215, 7.49952747963443, 2.78596877529615, -6.47007791187659, -6.33724447258133, 3.92957397696695, -5.73478485851571, 1.29181226980751, -5.73478485851571, 3.92957397696695, -6.33724447258133, -6.47007791187659, 2.78596877529614, 7.49952747963443, 8.31789983702215, -4.02927800788105, 1.97786272077884, 3.135726866163 [...]
+7.15207011384236, 5.13442842452098, -3.39061936807166, -1.27753859529645, 4.13404761353763, -5.58419173187169, 4.94420264342269, -4.20033080728172, 0.03284360886724, 5.19990500320383, 2.90819866047794, 0.94501105505199, -1.13008780896055, -6.80001035816794, 1.85278275462261, -0.38141565403651, -1.90055269185725, -0.38141565403651, 1.85278275462261, -6.80001035816794, -1.13008780896055, 0.94501105505199, 2.90819866047794, 5.19990500320383, 0.03284360886724, -4.20033080728172, 4.9442026434 [...]
+5.12480210840363, 1.09280090400397, -0.36072746990241, -1.61691888364553, 3.06265674825714, -3.60364385374449, 3.18345268102507, -2.47172505365689, 0.30309112472224, 2.52815580963260, 1.70644129003273, 0.79966216964325, -1.31225989550637, -2.69045064051650, 0.07862123531612, 0.60940470471168, -1.90175458108380, 0.60940470471168, 0.07862123531612, -2.69045064051649, -1.31225989550637, 0.79966216964325, 1.70644129003273, 2.52815580963260, 0.30309112472224, -2.47172505365689, 3.183452681025 [...]
+-2.41300782417371, 0.74493600528327, -2.13729932421246, 5.23769506839220, -3.28085174613910, 3.55766976471765, -2.46962156323022, 4.34106810546252, -2.68427669346718, 1.70275405023497, 2.16674865725327, 0.54234829176256, -1.90569976110202, -0.50647732352259, 2.25796709183844, -4.24221146756491, 3.31966616638923, -4.24221146756491, 2.25796709183844, -0.50647732352259, -1.90569976110202, 0.54234829176256, 2.16674865725327, 1.70275405023497, -2.68427669346718, 4.34106810546252, -2.469621563 [...]
+-5.05014490473224, -7.41667239093171, 6.07505533341960, -1.31227749889030, -1.90456935766031, 3.51533214643659, -2.98982751142837, 2.16028658728789, 2.06816764841105, -6.99212494539450, -1.93788364421032, -1.67821507154289, 1.49873179273464, 7.21775891118226, -2.57740873156455, 1.03551080768920, 1.34722011907049, 1.03551080768919, -2.57740873156455, 7.21775891118226, 1.49873179273464, -1.67821507154288, -1.93788364421032, -6.99212494539450, 2.06816764841105, 2.16028658728788, -2.98982751 [...]
+-3.33877962087733, 5.71555665735120, -2.66848666952597, -4.25112119556404, -0.21682133052970, -0.43295756695856, -1.24637771179251, -3.97704082344552, 1.63031501960669, -0.82772655089462, -7.62457282154425, -0.57848547281019, 5.35937233917291, -0.10618363258950, -2.76877075423901, 6.87379638938304, -4.44161265135407, 6.87379638938305, -2.76877075423901, -0.10618363258950, 5.35937233917291, -0.57848547281018, -7.62457282154425, -0.82772655089462, 1.63031501960669, -3.97704082344552, -1.24 [...]
+5.00904895279449, -5.04760356886645, 2.45400827308433, 2.32857540250695, 2.05100150692865, -2.02354236206146, 3.10712362036581, 1.67045960616215, -0.94676372761040, 1.03420252399013, 7.06084034562467, 0.43089411486127, -4.60307692646504, -1.03215812585099, 2.84192552608423, -5.74590762802640, 3.38656168598772, -5.74590762802641, 2.84192552608423, -1.03215812585099, -4.60307692646504, 0.43089411486126, 7.06084034562467, 1.03420252399013, -0.94676372761040, 1.67045960616215, 3.107123620365 [...]
+-3.63768838908703, 6.51146418918496, -3.52023849143115, -3.26666008762004, -0.79141197977445, 0.11030155373336, -1.66756690081732, -3.29406647947231, 0.95722951420221, 0.02820346112595, -7.49808976976364, -0.14902290217018, 4.76321302172283, -0.27040478119413, -2.69155509169828, 6.62245548100018, -4.44660615959221, 6.62245548100019, -2.69155509169828, -0.27040478119413, 4.76321302172284, -0.14902290217018, -7.49808976976364, 0.02820346112595, 0.95722951420221, -3.29406647947230, -1.66756 [...]
+-2.86416601217943, -8.60808565192260, 7.07272038803768, -1.85078415732380, -0.41817422677276, 2.07920722080515, -1.38353773076016, 1.43554088072310, 2.63563728711976, -6.90459822517653, 0.00635416658103, -1.97111276801481, 1.08572836254902, 6.08988781416648, -1.74385819486292, -0.15581221590921, 1.88886394075166, -0.15581221590921, -1.74385819486292, 6.08988781416648, 1.08572836254902, -1.97111276801480, 0.00635416658103, -6.90459822517652, 2.63563728711976, 1.43554088072311, -1.38353773 [...]
+-3.44849241719181, 2.83393816140164, -4.86046747390988, 9.38079257419346, -5.46504828859453, 5.80736227651040, -4.00599672704273, 7.41371253432584, -5.27568537649524, 4.71908443472533, 3.50001836968078, 1.97590706653304, -4.38342947940474, -1.18093691970083, 3.09051218026431, -6.19508346535584, 4.10336022219774, -6.19508346535584, 3.09051218026431, -1.18093691970083, -4.38342947940475, 1.97590706653303, 3.50001836968079, 4.71908443472532, -5.27568537649524, 7.41371253432582, -4.005996727 [...]
+-2.83892324752302, 2.85383650050539, -5.26786903008573, 10.47164812229259, -5.44175398068539, 5.82686379169152, -3.70591594074213, 8.06186173708606, -5.86358474714272, 5.68625683320838, 4.83276142081909, 2.25463843492306, -5.30540746510734, -1.96488446581300, 3.87127506697336, -7.46148902140177, 4.69551251777414, -7.46148902140177, 3.87127506697337, -1.96488446581301, -5.30540746510734, 2.25463843492305, 4.83276142081909, 5.68625683320836, -5.86358474714272, 8.06186173708605, -3.70591594 [...]
+1.48844980656865, -7.53197097533598, 4.70466438429144, 2.17163880626252, 0.76722359582778, 0.43617086817483, 1.22518018396499, 2.96966794692195, 0.11530359076553, -1.85538946300149, 5.93872630793450, -0.45564423271207, -3.26839582099431, 1.76661900667650, 1.66266033403361, -5.16346552176544, 3.72489832557383, -5.16346552176544, 1.66266033403361, 1.76661900667650, -3.26839582099431, -0.45564423271206, 5.93872630793449, -1.85538946300150, 0.11530359076553, 2.96966794692195, 1.2251801839649 [...]
+-12.90357861837443, -0.39327153742449, -0.20052457623055, 4.07256654998588, -9.53342148296998, 11.32977513744765, -10.68952183745447, 7.12817473025631, -1.54161648491620, -4.91145904271028, -6.54138867500058, -0.98676950171581, 3.20845442459892, 7.32562176838770, -2.11122861028575, 0.59745607703475, 3.13473460008626, 0.59745607703474, -2.11122861028574, 7.32562176838770, 3.20845442459892, -0.98676950171580, -6.54138867500058, -4.91145904271029, -1.54161648491620, 7.12817473025630, -10.68 [...]
+8.81120083658668, 0.96699714387759, 3.10798917310940, -13.74760636035438, 12.40633475048180, -14.14945472274416, 11.54545844652241, -14.40300324513701, 7.27182755565673, -1.28042776052365, -3.08484993417518, -0.93096067496508, 4.12892821614578, -2.91495676083155, -4.56285684625124, 11.25464421374245, -11.09207238281739, 11.25464421374246, -4.56285684625125, -2.91495676083153, 4.12892821614577, -0.93096067496507, -3.08484993417519, -1.28042776052364, 7.27182755565673, -14.40300324513699,  [...]
+-6.07772619354717, 0.31720630501919, -4.42544903339189, 13.46692739275014, -11.08927873084958, 11.99114248041517, -9.82711103996451, 13.15894335817657, -7.83472486828902, 3.05190823784306, 3.91034290654757, 1.18963666006280, -4.45221665663239, 0.36488891885515, 6.19929929386605, -12.38924708360194, 11.66628994922002, -12.38924708360195, 6.19929929386606, 0.36488891885513, -4.45221665663239, 1.18963666006279, 3.91034290654758, 3.05190823784304, -7.83472486828902, 13.15894335817655, -9.827 [...]
+7.93680911024683, 1.69583282166668, 2.54940281679402, -13.59382280977509, 11.80811769545808, -13.61856126844256, 10.89158899246869, -14.21180174458240, 7.02600983653373, -1.21342973134077, -4.03317447425189, -0.76369131859191, 4.33668485649477, -2.50944552282383, -4.97998124586836, 11.92180662822939, -11.47315931505510, 11.92180662822940, -4.97998124586837, -2.50944552282382, 4.33668485649476, -0.76369131859190, -4.03317447425189, -1.21342973134075, 7.02600983653373, -14.21180174458239,  [...]
+-11.82121651815161, -1.54258789558302, 1.41302857641138, 1.38521194357438, -7.92378006544159, 9.62619103665524, -9.45987748833682, 4.99973245149732, 0.09578774923518, -6.55671226155791, -7.18222467872136, -1.84981894575742, 4.69429494883615, 7.40450346020666, -2.52585857745149, 1.76767994247842, 2.57103003912964, 1.76767994247842, -2.52585857745148, 7.40450346020666, 4.69429494883616, -1.84981894575741, -7.18222467872136, -6.55671226155791, 0.09578774923518, 4.99973245149731, -9.45987748 [...]
+-0.45647901794024, -4.44655967216671, 2.72933379748613, 1.55564669432081, -0.49304685858063, 1.25934607943491, -0.36172879866241, 2.43307547830834, -0.25115983160303, -1.48736597421603, 2.34188730208856, -0.02686264784769, -1.97025445310637, 2.41346622029012, 0.13438001226859, -2.19202820169768, 1.81268549712075, -2.19202820169768, 0.13438001226860, 2.41346622029012, -1.97025445310637, -0.02686264784769, 2.34188730208856, -1.48736597421603, -0.25115983160303, 2.43307547830834, -0.3617287 [...]
+3.22107757599756, 3.23399308552368, -3.03104207600299, 2.16207864750425, 0.82214964343268, -1.46028783433140, 1.75326752336222, -0.06258841497221, -1.45361690538590, 4.14679887458980, 3.24610963833748, 0.91335342390199, -1.93616762543124, -4.40142256945175, 2.39347634143422, -2.73075183789195, 0.71621739105259, -2.73075183789195, 2.39347634143422, -4.40142256945176, -1.93616762543124, 0.91335342390198, 3.24610963833748, 4.14679887458979, -1.45361690538590, -0.06258841497221, 1.7532675233 [...]
+9.33068055761014, 4.06913288309929, -3.65608563471563, 1.38995726427514, 4.06438203253835, -5.17576132410929, 5.23249020230399, -1.84125004091186, -2.01926074364267, 7.97145956622135, 5.79496293751167, 2.44448261311050, -4.66719170360885, -7.24184172313529, 2.45952382430921, -2.30328430918645, -1.70480970563651, -2.30328430918645, 2.45952382430921, -7.24184172313529, -4.66719170360886, 2.44448261311049, 5.79496293751167, 7.97145956622135, -2.01926074364267, -1.84125004091186, 5.232490202 [...]
+5.30887173513362, -0.35314929177096, -2.61131070520295, 8.25111156681908, 0.41017902078847, -0.86625067725685, 3.04378460756718, 4.50365078897768, -4.15482761607276, 6.40169873588622, 11.11987213835412, 1.73280651944722, -7.36714684531599, -5.84918454235114, 6.76983406014196, -11.25994512486713, 6.37954209195652, -11.25994512486714, 6.76983406014197, -5.84918454235115, -7.36714684531599, 1.73280651944721, 11.11987213835412, 6.40169873588621, -4.15482761607276, 4.50365078897768, 3.0437846 [...]
+-8.74363591172941, -4.17508994192660, 2.91004137947713, 3.94089301398669, -8.46655081935158, 11.34921816838086, -10.12044393037213, 8.12203673617978, -1.23852697990213, -4.65283592976415, -3.02905236090686, -0.50154070452117, 0.42110081161918, 8.14051929827691, -3.20629336164749, 0.16786445716181, 2.33185172968504, 0.16786445716181, -3.20629336164749, 8.14051929827691, 0.42110081161918, -0.50154070452116, -3.02905236090687, -4.65283592976415, -1.23852697990213, 8.12203673617977, -10.1204 [...]
+11.14535351330902, 5.18968876430293, -3.38123424448073, -4.28615501749418, 10.75134709711704, -13.76145495194181, 12.77644128265988, -9.58436396049421, 1.63479533576614, 6.58451940627450, 4.87389970716437, 1.02600374173176, -1.40902412469534, -10.25618613141288, 3.42885639532288, -0.14021710943359, -3.76029539109274, -0.14021710943358, 3.42885639532288, -10.25618613141288, -1.40902412469534, 1.02600374173175, 4.87389970716438, 6.58451940627450, 1.63479533576614, -9.58436396049420, 12.776 [...]
+-8.74363591172941, -4.17508994192660, 2.91004137947714, 3.94089301398669, -8.46655081935159, 11.34921816838087, -10.12044393037214, 8.12203673617979, -1.23852697990213, -4.65283592976415, -3.02905236090686, -0.50154070452117, 0.42110081161917, 8.14051929827692, -3.20629336164749, 0.16786445716181, 2.33185172968504, 0.16786445716180, -3.20629336164749, 8.14051929827691, 0.42110081161918, -0.50154070452116, -3.02905236090687, -4.65283592976415, -1.23852697990213, 8.12203673617978, -10.1204 [...]
+5.30887173513362, -0.35314929177096, -2.61131070520295, 8.25111156681908, 0.41017902078848, -0.86625067725686, 3.04378460756719, 4.50365078897768, -4.15482761607276, 6.40169873588622, 11.11987213835412, 1.73280651944722, -7.36714684531599, -5.84918454235114, 6.76983406014196, -11.25994512486713, 6.37954209195652, -11.25994512486713, 6.76983406014196, -5.84918454235116, -7.36714684531599, 1.73280651944721, 11.11987213835412, 6.40169873588621, -4.15482761607276, 4.50365078897767, 3.0437846 [...]
+9.33068055761013, 4.06913288309929, -3.65608563471563, 1.38995726427515, 4.06438203253834, -5.17576132410928, 5.23249020230397, -1.84125004091184, -2.01926074364268, 7.97145956622136, 5.79496293751167, 2.44448261311050, -4.66719170360886, -7.24184172313529, 2.45952382430921, -2.30328430918646, -1.70480970563650, -2.30328430918646, 2.45952382430921, -7.24184172313529, -4.66719170360886, 2.44448261311049, 5.79496293751167, 7.97145956622135, -2.01926074364268, -1.84125004091184, 5.232490202 [...]
+3.22107757599757, 3.23399308552368, -3.03104207600299, 2.16207864750426, 0.82214964343268, -1.46028783433141, 1.75326752336223, -0.06258841497221, -1.45361690538590, 4.14679887458980, 3.24610963833749, 0.91335342390199, -1.93616762543125, -4.40142256945176, 2.39347634143422, -2.73075183789196, 0.71621739105259, -2.73075183789195, 2.39347634143422, -4.40142256945176, -1.93616762543125, 0.91335342390199, 3.24610963833749, 4.14679887458980, -1.45361690538590, -0.06258841497221, 1.7532675233 [...]
+-0.45647901794025, -4.44655967216671, 2.72933379748613, 1.55564669432083, -0.49304685858064, 1.25934607943492, -0.36172879866243, 2.43307547830836, -0.25115983160304, -1.48736597421603, 2.34188730208857, -0.02686264784769, -1.97025445310637, 2.41346622029012, 0.13438001226860, -2.19202820169769, 1.81268549712076, -2.19202820169769, 0.13438001226860, 2.41346622029012, -1.97025445310637, -0.02686264784769, 2.34188730208856, -1.48736597421603, -0.25115983160304, 2.43307547830836, -0.3617287 [...]
+-11.82121651815161, -1.54258789558302, 1.41302857641138, 1.38521194357438, -7.92378006544159, 9.62619103665524, -9.45987748833682, 4.99973245149732, 0.09578774923518, -6.55671226155791, -7.18222467872136, -1.84981894575742, 4.69429494883615, 7.40450346020666, -2.52585857745149, 1.76767994247842, 2.57103003912964, 1.76767994247842, -2.52585857745148, 7.40450346020666, 4.69429494883616, -1.84981894575741, -7.18222467872136, -6.55671226155791, 0.09578774923518, 4.99973245149731, -9.45987748 [...]
+7.93680911024682, 1.69583282166668, 2.54940281679401, -13.59382280977508, 11.80811769545807, -13.61856126844254, 10.89158899246868, -14.21180174458239, 7.02600983653372, -1.21342973134077, -4.03317447425189, -0.76369131859191, 4.33668485649476, -2.50944552282383, -4.97998124586836, 11.92180662822938, -11.47315931505509, 11.92180662822939, -4.97998124586837, -2.50944552282382, 4.33668485649476, -0.76369131859189, -4.03317447425189, -1.21342973134075, 7.02600983653372, -14.21180174458238,  [...]
+-6.07772619354716, 0.31720630501919, -4.42544903339189, 13.46692739275014, -11.08927873084957, 11.99114248041516, -9.82711103996450, 13.15894335817656, -7.83472486828902, 3.05190823784306, 3.91034290654758, 1.18963666006280, -4.45221665663240, 0.36488891885514, 6.19929929386605, -12.38924708360195, 11.66628994922002, -12.38924708360196, 6.19929929386606, 0.36488891885513, -4.45221665663240, 1.18963666006279, 3.91034290654758, 3.05190823784304, -7.83472486828902, 13.15894335817655, -9.827 [...]
+8.81120083658668, 0.96699714387759, 3.10798917310940, -13.74760636035438, 12.40633475048180, -14.14945472274416, 11.54545844652241, -14.40300324513701, 7.27182755565673, -1.28042776052365, -3.08484993417519, -0.93096067496508, 4.12892821614578, -2.91495676083155, -4.56285684625124, 11.25464421374245, -11.09207238281739, 11.25464421374247, -4.56285684625125, -2.91495676083153, 4.12892821614577, -0.93096067496507, -3.08484993417519, -1.28042776052363, 7.27182755565673, -14.40300324513700,  [...]
+-12.90357861837442, -0.39327153742449, -0.20052457623054, 4.07256654998588, -9.53342148296997, 11.32977513744764, -10.68952183745446, 7.12817473025630, -1.54161648491619, -4.91145904271028, -6.54138867500058, -0.98676950171581, 3.20845442459892, 7.32562176838770, -2.11122861028575, 0.59745607703475, 3.13473460008625, 0.59745607703475, -2.11122861028574, 7.32562176838770, 3.20845442459893, -0.98676950171580, -6.54138867500058, -4.91145904271029, -1.54161648491619, 7.12817473025630, -10.68 [...]
+1.48844980656865, -7.53197097533598, 4.70466438429144, 2.17163880626253, 0.76722359582778, 0.43617086817483, 1.22518018396499, 2.96966794692195, 0.11530359076553, -1.85538946300149, 5.93872630793449, -0.45564423271207, -3.26839582099431, 1.76661900667650, 1.66266033403361, -5.16346552176544, 3.72489832557383, -5.16346552176544, 1.66266033403361, 1.76661900667650, -3.26839582099431, -0.45564423271207, 5.93872630793449, -1.85538946300150, 0.11530359076553, 2.96966794692195, 1.2251801839649 [...]
+-6.60654009415507, -10.92455945134428, 8.31842812710608, -0.66313409741331, -2.37951744465164, 4.55909849707647, -3.42185047060164, 3.58221390010071, 2.41751984540606, -9.23707520729638, -0.93784682718668, -2.39603349856301, 1.35402702203993, 9.14836894032928, -2.19399627701525, -0.53236050968769, 3.15696256419329, -0.53236050968770, -2.19399627701525, 9.14836894032928, 1.35402702203994, -2.39603349856300, -0.93784682718669, -9.23707520729637, 2.41751984540606, 3.58221390010070, -3.42185 [...]
+-14.74393062865332, -1.32106660863471, 0.65009178089675, 3.29677414624710, -10.06658568712778, 12.03137215116938, -11.53947232513444, 7.10939968198017, -0.99210751171965, -6.68829752956733, -8.14354163472282, -1.55863401457358, 4.49000105397609, 8.81238058229880, -2.68588684433825, 1.46968342799886, 3.21771717399408, 1.46968342799885, -2.68588684433825, 8.81238058229880, 4.49000105397610, -1.55863401457357, -8.14354163472283, -6.68829752956733, -0.99210751171965, 7.10939968198016, -11.53 [...]
+4.72639414878423, -0.45689074932855, 5.85246101180145, -17.56576529334052, 12.00204995338546, -12.93005425770587, 9.82276473004764, -16.04720784994145, 10.15798470236242, -5.96786929447220, -7.79823374625514, -2.15833956442626, 7.51280741127250, 1.62177196726920, -8.86498664655665, 17.12277675375032, -14.58191882062153, 17.12277675375033, -8.86498664655666, 1.62177196726922, 7.51280741127249, -2.15833956442624, -7.79823374625514, -5.96786929447217, 10.15798470236242, -16.04720784994143,  [...]
+8.91237533091781, 10.35130507919668, -13.28581569314380, 11.52146969550268, -1.15597058560114, -2.67830194356923, 2.80594748407554, 4.24722144998790, -10.36836318806294, 15.50615447505318, 8.38058913088777, 3.76726987893619, -6.70276057511472, -15.45666563691728, 14.19212528585193, -16.46480006133991, 11.12360390205130, -16.46480006133991, 14.19212528585193, -15.45666563691730, -6.70276057511472, 3.76726987893616, 8.38058913088778, 15.50615447505316, -10.36836318806294, 4.24722144998789, [...]
+-7.93441996713900, -10.82318919098342, 12.79852585873742, -7.81786650812990, -1.51348803031006, 5.83625324407772, -5.24840624495381, -0.56788891355608, 8.39448017605385, -14.12072694697901, -5.15371450706424, -3.03724428628333, 3.61355025190648, 15.69581758241049, -13.59455617290117, 13.63480450842786, -9.22907396159892, 13.63480450842786, -13.59455617290117, 15.69581758241050, 3.61355025190648, -3.03724428628330, -5.15371450706425, -14.12072694697900, 8.39448017605385, -0.56788891355607 [...]
+10.45825101919689, 10.29321540849251, -12.95513689261551, 10.48203493639938, 0.03305368990284, -4.03365616309647, 3.97202286263357, 3.06920025506652, -9.81456074389003, 15.62653083152716, 8.83250043699877, 3.60802626397507, -6.52944439898166, -16.30170070366778, 14.35725602262621, -16.31917489400403, 10.79167128308033, -16.31917489400402, 14.35725602262621, -16.30170070366780, -6.52944439898167, 3.60802626397504, 8.83250043699879, 15.62653083152714, -9.81456074389003, 3.06920025506651, 3 [...]
+5.60433862789432, 2.35242523863248, 3.63775785996725, -16.94448264989112, 11.95028794360235, -13.35486820024028, 10.00309928333821, -16.33187849196730, 9.24065247535889, -3.67693429548397, -8.01402110855953, -1.29874571399605, 6.87856583168096, 0.12013790576510, -8.81435526929244, 17.61337577776529, -15.58775359702257, 17.61337577776531, -8.81435526929245, 0.12013790576512, 6.87856583168096, -1.29874571399603, -8.01402110855953, -3.67693429548395, 9.24065247535889, -16.33187849196728, 10 [...]
+-7.85563821620906, -0.61879763716117, 0.90476461939520, 0.38362076520172, -5.25410518255157, 6.43767461665303, -6.44399752201603, 2.88730432872950, 0.43448159546764, -4.58014233264032, -5.18623175942545, -1.51565985911258, 3.87817685784167, 4.53187957898162, -1.59951450543482, 1.30684891456880, 1.81790098229721, 1.30684891456880, -1.59951450543482, 4.53187957898162, 3.87817685784167, -1.51565985911258, -5.18623175942545, -4.58014233264032, 0.43448159546764, 2.88730432872949, -6.443997522 [...]
+-0.69431137122357, -3.66263970794855, 1.19987581135881, 4.57534894170629, -1.81333037931406, 2.76331216788767, -1.21421109030508, 4.73327235844181, -2.03751252195637, 0.56498106387676, 4.03558214128579, 0.76279413984798, -3.75787966969865, 1.56389486865036, 1.23717255429903, -4.27683750735179, 2.85416219443029, -4.27683750735179, 1.23717255429903, 1.56389486865035, -3.75787966969865, 0.76279413984798, 4.03558214128579, 0.56498106387676, -2.03751252195637, 4.73327235844181, -1.21421109030 [...]
+-2.54604357447963, -4.66929282514188, -0.13819423108440, 11.02583808873697, -4.43047097026064, 5.50970390273781, -2.27286523076009, 9.58694035937608, -4.66322824909073, 1.84503222857398, 9.17081960315400, 0.78279584091770, -6.51522919190225, 0.12778700695287, 5.81743838515182, -12.30345289542709, 9.26501510412659, -12.30345289542710, 5.81743838515182, 0.12778700695286, -6.51522919190225, 0.78279584091769, 9.17081960315400, 1.84503222857397, -4.66322824909073, 9.58694035937607, -2.2728652 [...]
+-14.91579712362892, -9.74698132282363, 4.77651452440564, 11.19018288040513, -15.39503735964576, 20.09471115811250, -16.85383747599085, 17.19405573215886, -4.27560277753923, -7.24991661159171, -0.63770775434433, -0.84777469232249, -1.93728973301874, 12.90496602208402, -1.24312903168856, -6.58887726974358, 9.55867710193666, -6.58887726974359, -1.24312903168855, 12.90496602208400, -1.93728973301874, -0.84777469232249, -0.63770775434433, -7.24991661159172, -4.27560277753923, 17.1940557321588 [...]
+-2.78796510523727, -0.12671975788172, 5.81471250191857, -16.48937092176396, 11.73649333148879, -12.35123247255438, 10.27574298101094, -15.80450110998019, 11.39598252505389, -8.25051505196517, -9.19190048429895, -3.04973507217950, 9.55529512593388, 3.15487598418823, -8.75727896903642, 16.91983100136105, -14.03306153669358, 16.91983100136105, -8.75727896903643, 3.15487598418825, 9.55529512593388, -3.04973507217947, -9.19190048429896, -8.25051505196514, 11.39598252505389, -15.80450110998018 [...]
+1.64748694331119, -0.91387402580180, -7.04400202896831, 20.53374943769273, -13.49577523677131, 14.10806478087141, -11.19391194394507, 19.20792537128832, -13.94749639474252, 9.58117908275203, 11.05087412218366, 3.49713545835765, -11.20233591548618, -3.78237498736739, 11.87719021922083, -21.68775615665565, 18.05786614830462, -21.68775615665566, 11.87719021922084, -3.78237498736741, -11.20233591548618, 3.49713545835762, 11.05087412218366, 9.58117908275201, -13.94749639474252, 19.20792537128 [...]
+-2.78796510523727, -0.12671975788172, 5.81471250191858, -16.48937092176396, 11.73649333148879, -12.35123247255439, 10.27574298101095, -15.80450110998020, 11.39598252505389, -8.25051505196517, -9.19190048429896, -3.04973507217950, 9.55529512593388, 3.15487598418823, -8.75727896903643, 16.91983100136105, -14.03306153669359, 16.91983100136106, -8.75727896903644, 3.15487598418825, 9.55529512593388, -3.04973507217948, -9.19190048429896, -8.25051505196515, 11.39598252505389, -15.80450110998018 [...]
+-14.91579712362891, -9.74698132282363, 4.77651452440563, 11.19018288040514, -15.39503735964576, 20.09471115811250, -16.85383747599085, 17.19405573215886, -4.27560277753924, -7.24991661159171, -0.63770775434433, -0.84777469232249, -1.93728973301874, 12.90496602208401, -1.24312903168855, -6.58887726974359, 9.55867710193667, -6.58887726974360, -1.24312903168854, 12.90496602208400, -1.93728973301874, -0.84777469232249, -0.63770775434433, -7.24991661159172, -4.27560277753924, 17.1940557321588 [...]
+-2.54604357447964, -4.66929282514189, -0.13819423108439, 11.02583808873695, -4.43047097026062, 5.50970390273780, -2.27286523076008, 9.58694035937606, -4.66322824909072, 1.84503222857397, 9.17081960315399, 0.78279584091770, -6.51522919190224, 0.12778700695288, 5.81743838515180, -12.30345289542707, 9.26501510412657, -12.30345289542708, 5.81743838515181, 0.12778700695287, -6.51522919190225, 0.78279584091768, 9.17081960315400, 1.84503222857396, -4.66322824909072, 9.58694035937605, -2.2728652 [...]
+-0.69431137122357, -3.66263970794855, 1.19987581135881, 4.57534894170630, -1.81333037931407, 2.76331216788768, -1.21421109030509, 4.73327235844182, -2.03751252195638, 0.56498106387676, 4.03558214128580, 0.76279413984799, -3.75787966969866, 1.56389486865036, 1.23717255429903, -4.27683750735180, 2.85416219443030, -4.27683750735180, 1.23717255429904, 1.56389486865036, -3.75787966969866, 0.76279413984798, 4.03558214128579, 0.56498106387676, -2.03751252195638, 4.73327235844182, -1.21421109030 [...]
+-7.85563821620907, -0.61879763716118, 0.90476461939522, 0.38362076520170, -5.25410518255157, 6.43767461665303, -6.44399752201602, 2.88730432872949, 0.43448159546766, -4.58014233264033, -5.18623175942545, -1.51565985911258, 3.87817685784168, 4.53187957898164, -1.59951450543483, 1.30684891456882, 1.81790098229719, 1.30684891456882, -1.59951450543483, 4.53187957898164, 3.87817685784168, -1.51565985911258, -5.18623175942545, -4.58014233264034, 0.43448159546766, 2.88730432872948, -6.443997522 [...]
+5.60433862789432, 2.35242523863248, 3.63775785996725, -16.94448264989112, 11.95028794360235, -13.35486820024028, 10.00309928333821, -16.33187849196730, 9.24065247535889, -3.67693429548397, -8.01402110855953, -1.29874571399605, 6.87856583168096, 0.12013790576510, -8.81435526929244, 17.61337577776529, -15.58775359702257, 17.61337577776531, -8.81435526929245, 0.12013790576512, 6.87856583168096, -1.29874571399603, -8.01402110855953, -3.67693429548395, 9.24065247535889, -16.33187849196728, 10 [...]
+10.45825101919688, 10.29321540849250, -12.95513689261550, 10.48203493639936, 0.03305368990285, -4.03365616309647, 3.97202286263358, 3.06920025506651, -9.81456074389001, 15.62653083152715, 8.83250043699877, 3.60802626397506, -6.52944439898166, -16.30170070366777, 14.35725602262620, -16.31917489400401, 10.79167128308032, -16.31917489400401, 14.35725602262620, -16.30170070366779, -6.52944439898166, 3.60802626397503, 8.83250043699878, 15.62653083152713, -9.81456074389001, 3.06920025506650, 3 [...]
+-7.93441996713900, -10.82318919098342, 12.79852585873742, -7.81786650812989, -1.51348803031008, 5.83625324407773, -5.24840624495382, -0.56788891355607, 8.39448017605384, -14.12072694697901, -5.15371450706424, -3.03724428628333, 3.61355025190648, 15.69581758241049, -13.59455617290117, 13.63480450842785, -9.22907396159891, 13.63480450842785, -13.59455617290117, 15.69581758241051, 3.61355025190648, -3.03724428628330, -5.15371450706425, -14.12072694697900, 8.39448017605384, -0.56788891355606 [...]
+8.91237533091782, 10.35130507919668, -13.28581569314381, 11.52146969550268, -1.15597058560113, -2.67830194356924, 2.80594748407555, 4.24722144998790, -10.36836318806294, 15.50615447505319, 8.38058913088778, 3.76726987893620, -6.70276057511472, -15.45666563691729, 14.19212528585194, -16.46480006133992, 11.12360390205130, -16.46480006133992, 14.19212528585194, -15.45666563691731, -6.70276057511473, 3.76726987893617, 8.38058913088779, 15.50615447505316, -10.36836318806294, 4.24722144998789, [...]
+4.72639414878423, -0.45689074932855, 5.85246101180144, -17.56576529334051, 12.00204995338546, -12.93005425770587, 9.82276473004765, -16.04720784994145, 10.15798470236241, -5.96786929447219, -7.79823374625513, -2.15833956442626, 7.51280741127249, 1.62177196726920, -8.86498664655664, 17.12277675375031, -14.58191882062153, 17.12277675375032, -8.86498664655665, 1.62177196726922, 7.51280741127249, -2.15833956442624, -7.79823374625514, -5.96786929447217, 10.15798470236241, -16.04720784994143,  [...]
+-14.74393062865332, -1.32106660863471, 0.65009178089675, 3.29677414624710, -10.06658568712778, 12.03137215116938, -11.53947232513444, 7.10939968198017, -0.99210751171965, -6.68829752956732, -8.14354163472282, -1.55863401457358, 4.49000105397609, 8.81238058229880, -2.68588684433825, 1.46968342799886, 3.21771717399408, 1.46968342799885, -2.68588684433825, 8.81238058229880, 4.49000105397610, -1.55863401457357, -8.14354163472283, -6.68829752956733, -0.99210751171965, 7.10939968198016, -11.53 [...]
+6.66273664989452, 11.46633969041569, -7.44026904749622, -3.60687251998574, 3.93878122684753, -6.47939788765459, 4.21427333534627, -7.05837787525195, -0.28110740451400, 7.22981871982735, -2.49075510219528, 1.49455918728819, 1.70056379350934, -8.64722587430520, 0.50608572437551, 4.38064992184130, -5.47702056014126, 4.38064992184130, 0.50608572437551, -8.64722587430520, 1.70056379350934, 1.49455918728819, -2.49075510219527, 7.22981871982735, -0.28110740451400, -7.05837787525195, 4.214273335 [...]
+16.22243919948918, 3.89683707020860, -1.64061653683745, -6.64896140754365, 12.20734279433442, -15.02922579572945, 13.39769299830609, -10.84984411000403, 2.19156240896512, 7.11669765833022, 5.60802016883877, 1.58956755542132, -2.76764506768711, -9.96219299310700, 1.40383942158031, 2.23593732586146, -6.37994318561651, 2.23593732586148, 1.40383942158031, -9.96219299310700, -2.76764506768712, 1.58956755542131, 5.60802016883877, 7.11669765833023, 2.19156240896512, -10.84984411000402, 13.39769 [...]
+0.71603569067631, 2.48224819396778, -8.12512392288065, 18.55719008721814, -9.84840086209081, 9.65556542149440, -6.72340898037529, 14.99195273629978, -11.58266747950209, 10.07637227752972, 11.32403005265666, 3.05536129906870, -9.68069265450141, -6.42930848468039, 11.88865659819713, -20.26773553674023, 15.75597155390253, -20.26773553674023, 11.88865659819714, -6.42930848468041, -9.68069265450141, 3.05536129906867, 11.32403005265667, 10.07637227752969, -11.58266747950209, 14.99195273629976, [...]
+-12.62664738145496, -13.26193354235104, 14.67563322835584, -6.88006409494037, -3.53180140732135, 8.96180245189183, -7.62383768490718, 1.68511341430557, 8.84107601156307, -16.87556591295538, -6.38715986358795, -3.62056562711385, 4.41395343149593, 19.14014316625846, -14.71757512155857, 13.76751881642541, -8.46336038248997, 13.76751881642540, -14.71757512155856, 19.14014316625847, 4.41395343149594, -3.62056562711382, -6.38715986358797, -16.87556591295537, 8.84107601156307, 1.68511341430558, [...]
+10.16500142106782, 13.05223272851380, -13.41659463125813, 2.94607668413830, 6.02346581296995, -11.56966279561545, 9.71916395344094, -5.18237066131378, -6.33784191050401, 14.50764120131881, 2.53933945388330, 2.66273197748505, -0.81169073700030, -18.29899493822642, 13.44132273151443, -10.32560932507518, 6.24064365835762, -10.32560932507518, 13.44132273151442, -18.29899493822643, -0.81169073700030, 2.66273197748503, 2.53933945388331, 14.50764120131880, -6.33784191050401, -5.18237066131378,  [...]
+-14.02629194694770, -13.30963284393463, 14.34669021492076, -5.58046204644975, -4.72861351067897, 10.35803312031667, -8.73693223251548, 3.05034173174722, 8.18733720774694, -16.85196773705812, -6.45462132852358, -3.43504212211661, 4.02510965374610, 19.83993815341291, -14.68583294181605, 13.25022745567154, -7.91319378526907, 13.25022745567153, -14.68583294181605, 19.83993815341292, 4.02510965374610, -3.43504212211658, -6.45462132852359, -16.85196773705810, 8.18733720774694, 3.05034173174723 [...]
+-0.16854784188365, -0.39359901812678, -6.12141699953062, 18.83961428702428, -10.11699518580973, 10.49244266265025, -7.07194557225083, 16.01265616903866, -11.12764722954493, 8.27260411544710, 12.23586383006170, 2.43311920595548, -9.73059726118960, -5.02062307508863, 12.13141986459054, -21.49631153701344, 17.15893111475332, -21.49631153701346, 12.13141986459055, -5.02062307508866, -9.73059726118960, 2.43311920595545, 12.23586383006171, 8.27260411544707, -11.12764722954493, 16.0126561690386 [...]
+9.25106887268730, 2.38480458331391, -1.75107408997322, -2.22759645906200, 6.87535747414920, -8.65014669996938, 8.03266114816063, -5.26603891284810, 0.18137257671356, 5.32717526767155, 4.17852955458781, 1.64147097697236, -3.13052387042558, -5.76953126782468, 1.11010317447441, 0.64048386763145, -3.75877086225869, 0.64048386763146, 1.11010317447440, -5.76953126782468, -3.13052387042558, 1.64147097697235, 4.17852955458781, 5.32717526767155, 0.18137257671356, -5.26603891284809, 8.032661148160 [...]
+-1.58111675869628, 2.34039594598042, 0.15046934709092, -5.67750442076615, 1.13601088270197, -1.74102311236358, 0.04779744302994, -4.73102358613817, 2.90458196708296, -2.93119412690892, -6.02960502954886, -1.44447389541062, 5.27037270179626, 0.59754524450408, -2.32909453371172, 5.63303023483411, -2.99547099583388, 5.63303023483412, -2.32909453371172, 0.59754524450409, 5.27037270179627, -1.44447389541061, -6.02960502954886, -2.93119412690891, 2.90458196708296, -4.73102358613817, 0.04779744 [...]
+-2.78371043654612, 2.51296055586189, 2.29742616766443, -12.23863698590098, 2.11270333565586, -2.35992397634129, -0.97793651181315, -8.66035718257316, 5.91850203280306, -6.28311622048535, -13.12125555948169, -1.98966894090506, 9.28044355185572, 4.36377417610844, -8.01838019756589, 14.73670790074198, -9.32227835957131, 14.73670790074198, -8.01838019756590, 4.36377417610845, 9.28044355185572, -1.98966894090504, -13.12125555948170, -6.28311622048533, 5.91850203280306, -8.66035718257315, -0.9 [...]
+12.75414659397849, 10.02616578607079, -3.05854004299067, -17.47677578362690, 17.62151372912027, -22.57792287301751, 17.94334107780959, -22.13281438586507, 7.76688749136836, 3.44971431159391, -5.38973416393879, -0.42341524868165, 6.66436629042938, -10.59467153398466, -2.31962448425778, 13.54791617378325, -14.05249540014840, 13.54791617378326, -2.31962448425779, -10.59467153398465, 6.66436629042937, -0.42341524868165, -5.38973416393879, 3.44971431159393, 7.76688749136836, -22.1328143858650 [...]
+7.37582855618055, 3.01558823226362, -8.94400771252139, 17.19986499128087, -10.33534532764508, 9.49894703180168, -8.04877757438287, 14.61535016273023, -13.17461803519746, 12.13564359141704, 10.91564822231077, 3.88315210887298, -10.79393216415549, -7.70975797948486, 11.76699269905275, -19.37347197721331, 15.28656887311034, -19.37347197721332, 11.76699269905276, -7.70975797948489, -10.79393216415549, 3.88315210887295, 10.91564822231078, 12.13564359141702, -13.17461803519746, 14.615350162730 [...]
+-7.61324373567635, -2.71541435757618, 10.87489323943289, -21.58205724536926, 11.12390512183756, -10.09241433012311, 7.67023674887848, -17.59895969537530, 15.99941658738216, -14.92660387356454, -13.87351306521319, -4.71059182112956, 13.10917418100889, 9.87289791710298, -15.63080429806263, 24.88105456022913, -19.22379435705501, 24.88105456022915, -15.63080429806264, 9.87289791710301, 13.10917418100889, -4.71059182112952, -13.87351306521320, -14.92660387356452, 15.99941658738216, -17.598959 [...]
+7.37582855618055, 3.01558823226363, -8.94400771252140, 17.19986499128088, -10.33534532764508, 9.49894703180168, -8.04877757438287, 14.61535016273023, -13.17461803519747, 12.13564359141705, 10.91564822231078, 3.88315210887298, -10.79393216415550, -7.70975797948487, 11.76699269905276, -19.37347197721332, 15.28656887311035, -19.37347197721333, 11.76699269905277, -7.70975797948490, -10.79393216415550, 3.88315210887295, 10.91564822231079, 12.13564359141703, -13.17461803519747, 14.615350162730 [...]
+12.75414659397849, 10.02616578607078, -3.05854004299066, -17.47677578362690, 17.62151372912027, -22.57792287301751, 17.94334107780958, -22.13281438586507, 7.76688749136837, 3.44971431159390, -5.38973416393879, -0.42341524868166, 6.66436629042938, -10.59467153398466, -2.31962448425778, 13.54791617378325, -14.05249540014840, 13.54791617378327, -2.31962448425780, -10.59467153398464, 6.66436629042938, -0.42341524868165, -5.38973416393879, 3.44971431159392, 7.76688749136837, -22.1328143858650 [...]
+-2.78371043654611, 2.51296055586190, 2.29742616766442, -12.23863698590096, 2.11270333565585, -2.35992397634128, -0.97793651181316, -8.66035718257315, 5.91850203280304, -6.28311622048533, -13.12125555948169, -1.98966894090506, 9.28044355185571, 4.36377417610842, -8.01838019756588, 14.73670790074196, -9.32227835957129, 14.73670790074196, -8.01838019756588, 4.36377417610844, 9.28044355185571, -1.98966894090504, -13.12125555948169, -6.28311622048532, 5.91850203280304, -8.66035718257314, -0.9 [...]
+-1.58111675869628, 2.34039594598043, 0.15046934709092, -5.67750442076616, 1.13601088270198, -1.74102311236360, 0.04779744302995, -4.73102358613819, 2.90458196708296, -2.93119412690892, -6.02960502954887, -1.44447389541062, 5.27037270179627, 0.59754524450408, -2.32909453371172, 5.63303023483413, -2.99547099583390, 5.63303023483413, -2.32909453371173, 0.59754524450409, 5.27037270179627, -1.44447389541061, -6.02960502954887, -2.93119412690892, 2.90458196708296, -4.73102358613819, 0.04779744 [...]
+9.25106887268731, 2.38480458331392, -1.75107408997324, -2.22759645906198, 6.87535747414919, -8.65014669996938, 8.03266114816062, -5.26603891284809, 0.18137257671355, 5.32717526767157, 4.17852955458781, 1.64147097697236, -3.13052387042559, -5.76953126782470, 1.11010317447442, 0.64048386763144, -3.75877086225868, 0.64048386763144, 1.11010317447442, -5.76953126782470, -3.13052387042559, 1.64147097697236, 4.17852955458781, 5.32717526767157, 0.18137257671355, -5.26603891284809, 8.032661148160 [...]
+-0.16854784188365, -0.39359901812678, -6.12141699953062, 18.83961428702428, -10.11699518580973, 10.49244266265025, -7.07194557225083, 16.01265616903866, -11.12764722954493, 8.27260411544710, 12.23586383006170, 2.43311920595548, -9.73059726118960, -5.02062307508863, 12.13141986459054, -21.49631153701344, 17.15893111475332, -21.49631153701346, 12.13141986459055, -5.02062307508866, -9.73059726118960, 2.43311920595545, 12.23586383006171, 8.27260411544707, -11.12764722954493, 16.0126561690386 [...]
+-14.02629194694770, -13.30963284393462, 14.34669021492075, -5.58046204644974, -4.72861351067898, 10.35803312031668, -8.73693223251548, 3.05034173174723, 8.18733720774692, -16.85196773705811, -6.45462132852357, -3.43504212211661, 4.02510965374610, 19.83993815341290, -14.68583294181604, 13.25022745567152, -7.91319378526905, 13.25022745567152, -14.68583294181604, 19.83993815341291, 4.02510965374610, -3.43504212211658, -6.45462132852358, -16.85196773705809, 8.18733720774692, 3.05034173174723 [...]
+10.16500142106782, 13.05223272851381, -13.41659463125813, 2.94607668413828, 6.02346581296997, -11.56966279561546, 9.71916395344095, -5.18237066131380, -6.33784191050400, 14.50764120131881, 2.53933945388329, 2.66273197748505, -0.81169073700030, -18.29899493822642, 13.44132273151442, -10.32560932507517, 6.24064365835761, -10.32560932507516, 13.44132273151442, -18.29899493822643, -0.81169073700030, 2.66273197748503, 2.53933945388330, 14.50764120131880, -6.33784191050400, -5.18237066131380,  [...]
+-12.62664738145497, -13.26193354235105, 14.67563322835584, -6.88006409494037, -3.53180140732136, 8.96180245189184, -7.62383768490719, 1.68511341430558, 8.84107601156307, -16.87556591295539, -6.38715986358796, -3.62056562711386, 4.41395343149594, 19.14014316625847, -14.71757512155857, 13.76751881642541, -8.46336038248997, 13.76751881642541, -14.71757512155857, 19.14014316625848, 4.41395343149594, -3.62056562711382, -6.38715986358797, -16.87556591295537, 8.84107601156307, 1.68511341430559, [...]
+0.71603569067630, 2.48224819396777, -8.12512392288064, 18.55719008721814, -9.84840086209082, 9.65556542149440, -6.72340898037529, 14.99195273629978, -11.58266747950209, 10.07637227752971, 11.32403005265666, 3.05536129906869, -9.68069265450140, -6.42930848468038, 11.88865659819713, -20.26773553674022, 15.75597155390252, -20.26773553674023, 11.88865659819713, -6.42930848468040, -9.68069265450140, 3.05536129906866, 11.32403005265667, 10.07637227752968, -11.58266747950209, 14.99195273629976, [...]
+16.22243919948918, 3.89683707020860, -1.64061653683745, -6.64896140754365, 12.20734279433442, -15.02922579572945, 13.39769299830609, -10.84984411000403, 2.19156240896512, 7.11669765833022, 5.60802016883877, 1.58956755542132, -2.76764506768711, -9.96219299310700, 1.40383942158031, 2.23593732586146, -6.37994318561651, 2.23593732586147, 1.40383942158031, -9.96219299310700, -2.76764506768712, 1.58956755542131, 5.60802016883877, 7.11669765833023, 2.19156240896512, -10.84984411000402, 13.39769 [...]
+-3.79930783297356, -4.74120466973677, 5.96217380912226, -7.86867360682909, 1.17445262469222, -0.65309922427472, -0.81769500636621, -4.00686663867494, 4.89201620511217, -8.42438044048848, -7.19377407969774, -2.45860139709839, 5.68968556239167, 6.69569062282034, -5.05281865555310, 7.44243074011496, -3.18644021048831, 7.44243074011496, -5.05281865555310, 6.69569062282035, 5.68968556239167, -2.45860139709838, -7.19377407969774, -8.42438044048846, 4.89201620511217, -4.00686663867494, -0.81769 [...]
+-5.13492229917854, 3.72415982315523, -1.12361844878879, -4.43309125447855, -1.77811463471488, 1.42965393664389, -3.20658268810889, -2.89359175055380, 1.92720616029590, -3.30867749533838, -8.68309760930295, -1.33468782240254, 6.23406695352077, 2.14277793025021, -3.12388851622980, 6.63730420609597, -2.97003136804169, 6.63730420609597, -3.12388851622980, 2.14277793025022, 6.23406695352078, -1.33468782240254, -8.68309760930295, -3.30867749533838, 1.92720616029590, -2.89359175055380, -3.20658 [...]
+12.33434675226444, 3.76311994484352, -0.86308000264393, -8.41323897927573, 11.28944720434947, -13.78276078217295, 11.78269208886619, -11.42876457936816, 3.37123935386327, 4.46766813147399, 1.66318573798221, 0.99289215929101, -0.35562000827801, -7.02682447106838, -1.00274566338866, 5.86867143290008, -8.29708435012838, 5.86867143290009, -1.00274566338866, -7.02682447106838, -0.35562000827802, 0.99289215929101, 1.66318573798221, 4.46766813147400, 3.37123935386327, -11.42876457936815, 11.782 [...]
+-1.54626373495428, 0.30172393368944, -5.35189787389051, 15.52317502695129, -9.44169963223186, 9.87826755304772, -7.19419825406518, 13.57035942066562, -9.18724741244265, 6.30112099262326, 8.74402870775320, 1.86264101273072, -7.22920783296433, -3.45941126215697, 9.46702457281437, -16.99139964151387, 14.04461751323831, -16.99139964151388, 9.46702457281437, -3.45941126215699, -7.22920783296433, 1.86264101273070, 8.74402870775320, 6.30112099262324, -9.18724741244265, 13.57035942066560, -7.194 [...]
+-0.65585322360948, -1.94485035472051, 6.57809911623013, -13.72804010840783, 7.26661468726809, -6.66815536628271, 4.77056565027483, -10.89465587648248, 8.99902496464351, -7.48484793061143, -7.99600849839670, -1.90062496896635, 6.33296761912445, 5.83930809584791, -10.54020557100553, 16.57098060052476, -13.55196079681233, 16.57098060052477, -10.54020557100554, 5.83930809584793, 6.33296761912445, -1.90062496896632, -7.99600849839671, -7.48484793061141, 8.99902496464351, -10.89465587648247, 4 [...]
+-0.40512910569919, 0.04571781720206, -5.14018026746724, 15.39884403242205, -8.77103955029603, 9.18371415135998, -6.43846498497193, 13.26303702527783, -9.08023236965913, 6.66405260929340, 9.64520482846909, 1.88838351188050, -7.60594445656064, -4.09745199037701, 9.81384348472091, -17.47514056202300, 14.14096546676642, -17.47514056202301, 9.81384348472092, -4.09745199037703, -7.60594445656064, 1.88838351188048, 9.64520482846909, 6.66405260929338, -9.08023236965913, 13.26303702527781, -6.438 [...]
+12.72902760738854, 5.24573592337883, -2.53489148489309, -6.36383900286350, 10.63891479360222, -13.23545398077542, 11.56891317022132, -10.24905916842963, 2.05199304856081, 6.56071067211231, 2.90734079112609, 1.76774563166719, -1.78162086533475, -8.22429762215432, -0.21493317508084, 4.56410306635583, -7.89767818707390, 4.56410306635584, -0.21493317508084, -8.22429762215432, -1.78162086533475, 1.76774563166719, 2.90734079112609, 6.56071067211232, 2.05199304856081, -10.24905916842962, 11.568 [...]
+-1.40540597448464, 2.50497740683185, -0.60982269553672, -3.43288247872852, 0.10785937917191, -0.39360854589256, -0.73776551245540, -2.82089155199348, 1.64799667639605, -1.49218992314451, -4.41578444638819, -0.93603458072369, 3.86899743912450, -0.06809727830509, -1.43040346148670, 3.75606561927389, -1.94727281729659, 3.75606561927389, -1.43040346148670, -0.06809727830509, 3.86899743912450, -0.93603458072369, -4.41578444638819, -1.49218992314451, 1.64799667639605, -2.82089155199348, -0.737 [...]
+-5.02278137162993, -3.95742356319849, 2.60497058142900, 1.04698564525724, -2.78771712981609, 3.87715454026481, -3.29452504220191, 3.07102118218099, 0.01987328167566, -3.70205437164826, -1.70641819709222, -0.58848159924352, 0.45722039960182, 5.02452873498669, -1.44266443189156, 0.24152218517903, 1.22100808790073, 0.24152218517903, -1.44266443189156, 5.02452873498669, 0.45722039960182, -0.58848159924352, -1.70641819709222, -3.70205437164826, 0.01987328167566, 3.07102118218099, -3.294525042 [...]
+-10.52906350859377, -7.16208401597183, 4.41931527232739, 3.30802929188696, -6.04555815686641, 7.99698672579895, -6.50788592699034, 6.44963692788028, 0.04659243965101, -7.49513543706844, -1.86853321260226, -1.97065125619650, 1.51091582616531, 8.21583362280702, -0.56606882474507, -2.60298303639010, 5.31193279463100, -2.60298303639011, -0.56606882474506, 8.21583362280702, 1.51091582616531, -1.97065125619650, -1.86853321260226, -7.49513543706844, 0.04659243965101, 6.44963692788028, -6.507885 [...]
+-12.93276289852402, -4.21740984760849, 5.04262402828669, -3.96716685914395, -6.46395973075059, 8.82918432583110, -9.53541678774017, 2.14549954338794, 3.08682692015210, -10.63372400309847, -11.66372057735304, -2.67520910119314, 7.44965456031858, 11.59158137868349, -7.07366415155689, 8.44728282823356, -2.03956989888418, 8.44728282823356, -7.07366415155689, 11.59158137868350, 7.44965456031858, -2.67520910119312, -11.66372057735305, -10.63372400309847, 3.08682692015210, 2.14549954338794, -9. [...]
+7.65013692896325, 4.52397466301566, -1.12862793914300, -10.17021627225519, 11.91644773551517, -14.99749882945734, 12.65489480276605, -13.52050007453513, 4.88753221489818, 1.83319532802056, -1.76390160347601, -0.31822528245991, 3.29047455414783, -6.41868898662239, -0.59399513955277, 6.96388662329659, -7.88975548464535, 6.96388662329661, -0.59399513955277, -6.41868898662238, 3.29047455414783, -0.31822528245990, -1.76390160347601, 1.83319532802057, 4.88753221489818, -13.52050007453512, 12.6 [...]
+-10.72822063464215, -6.32093650453145, 1.43410548049422, 12.05917402550948, -14.83472683614027, 18.15119407025472, -15.63001744080919, 16.35494553003931, -6.10798382013596, -3.54450863605258, 0.76721579023276, -0.10779771769593, -2.96829824100697, 8.58547550546493, 1.43073486495006, -8.76880914581342, 10.80562365976089, -8.76880914581343, 1.43073486495007, 8.58547550546492, -2.96829824100696, -0.10779771769594, 0.76721579023276, -3.54450863605259, -6.10798382013596, 16.35494553003929, -1 [...]
+7.65013692896326, 4.52397466301567, -1.12862793914300, -10.17021627225520, 11.91644773551517, -14.99749882945735, 12.65489480276606, -13.52050007453514, 4.88753221489819, 1.83319532802056, -1.76390160347602, -0.31822528245991, 3.29047455414784, -6.41868898662240, -0.59399513955277, 6.96388662329660, -7.88975548464536, 6.96388662329661, -0.59399513955278, -6.41868898662239, 3.29047455414783, -0.31822528245990, -1.76390160347602, 1.83319532802057, 4.88753221489819, -13.52050007453513, 12.6 [...]
+-12.93276289852402, -4.21740984760849, 5.04262402828669, -3.96716685914395, -6.46395973075059, 8.82918432583110, -9.53541678774018, 2.14549954338795, 3.08682692015209, -10.63372400309847, -11.66372057735304, -2.67520910119314, 7.44965456031857, 11.59158137868349, -7.07366415155689, 8.44728282823355, -2.03956989888417, 8.44728282823355, -7.07366415155689, 11.59158137868350, 7.44965456031858, -2.67520910119312, -11.66372057735305, -10.63372400309847, 3.08682692015209, 2.14549954338795, -9. [...]
+-10.52906350859376, -7.16208401597183, 4.41931527232739, 3.30802929188695, -6.04555815686640, 7.99698672579894, -6.50788592699033, 6.44963692788026, 0.04659243965102, -7.49513543706844, -1.86853321260226, -1.97065125619650, 1.51091582616531, 8.21583362280702, -0.56606882474507, -2.60298303639009, 5.31193279463099, -2.60298303639009, -0.56606882474507, 8.21583362280702, 1.51091582616532, -1.97065125619650, -1.86853321260226, -7.49513543706844, 0.04659243965102, 6.44963692788026, -6.507885 [...]
+-5.02278137162994, -3.95742356319850, 2.60497058142900, 1.04698564525724, -2.78771712981609, 3.87715454026482, -3.29452504220192, 3.07102118218100, 0.01987328167566, -3.70205437164827, -1.70641819709223, -0.58848159924353, 0.45722039960182, 5.02452873498670, -1.44266443189156, 0.24152218517903, 1.22100808790073, 0.24152218517903, -1.44266443189156, 5.02452873498669, 0.45722039960183, -0.58848159924352, -1.70641819709223, -3.70205437164827, 0.01987328167566, 3.07102118218100, -3.294525042 [...]
+-1.40540597448464, 2.50497740683185, -0.60982269553671, -3.43288247872854, 0.10785937917193, -0.39360854589257, -0.73776551245539, -2.82089155199349, 1.64799667639606, -1.49218992314452, -4.41578444638819, -0.93603458072369, 3.86899743912451, -0.06809727830509, -1.43040346148670, 3.75606561927390, -1.94727281729660, 3.75606561927390, -1.43040346148671, -0.06809727830508, 3.86899743912451, -0.93603458072369, -4.41578444638819, -1.49218992314452, 1.64799667639606, -2.82089155199349, -0.737 [...]
+12.72902760738854, 5.24573592337883, -2.53489148489309, -6.36383900286350, 10.63891479360222, -13.23545398077542, 11.56891317022132, -10.24905916842963, 2.05199304856081, 6.56071067211231, 2.90734079112609, 1.76774563166719, -1.78162086533475, -8.22429762215432, -0.21493317508084, 4.56410306635583, -7.89767818707390, 4.56410306635584, -0.21493317508084, -8.22429762215432, -1.78162086533475, 1.76774563166719, 2.90734079112609, 6.56071067211232, 2.05199304856081, -10.24905916842962, 11.568 [...]
+-0.40512910569919, 0.04571781720206, -5.14018026746723, 15.39884403242204, -8.77103955029602, 9.18371415135997, -6.43846498497192, 13.26303702527781, -9.08023236965912, 6.66405260929340, 9.64520482846909, 1.88838351188050, -7.60594445656063, -4.09745199037701, 9.81384348472091, -17.47514056202299, 14.14096546676641, -17.47514056202300, 9.81384348472091, -4.09745199037703, -7.60594445656063, 1.88838351188048, 9.64520482846909, 6.66405260929338, -9.08023236965912, 13.26303702527780, -6.438 [...]
+-0.65585322360949, -1.94485035472052, 6.57809911623014, -13.72804010840783, 7.26661468726808, -6.66815536628270, 4.77056565027482, -10.89465587648248, 8.99902496464351, -7.48484793061143, -7.99600849839671, -1.90062496896635, 6.33296761912446, 5.83930809584792, -10.54020557100553, 16.57098060052476, -13.55196079681233, 16.57098060052477, -10.54020557100554, 5.83930809584794, 6.33296761912446, -1.90062496896632, -7.99600849839671, -7.48484793061141, 8.99902496464351, -10.89465587648246, 4 [...]
+-1.54626373495428, 0.30172393368944, -5.35189787389051, 15.52317502695129, -9.44169963223186, 9.87826755304772, -7.19419825406518, 13.57035942066562, -9.18724741244265, 6.30112099262326, 8.74402870775321, 1.86264101273072, -7.22920783296433, -3.45941126215697, 9.46702457281437, -16.99139964151388, 14.04461751323832, -16.99139964151389, 9.46702457281438, -3.45941126215699, -7.22920783296433, 1.86264101273070, 8.74402870775321, 6.30112099262324, -9.18724741244265, 13.57035942066561, -7.194 [...]
+12.33434675226444, 3.76311994484352, -0.86308000264393, -8.41323897927573, 11.28944720434946, -13.78276078217295, 11.78269208886619, -11.42876457936815, 3.37123935386327, 4.46766813147399, 1.66318573798221, 0.99289215929101, -0.35562000827802, -7.02682447106839, -1.00274566338865, 5.86867143290007, -8.29708435012837, 5.86867143290008, -1.00274566338866, -7.02682447106838, -0.35562000827802, 0.99289215929101, 1.66318573798221, 4.46766813147400, 3.37123935386327, -11.42876457936814, 11.782 [...]
+-5.13492229917853, 3.72415982315523, -1.12361844878879, -4.43309125447855, -1.77811463471488, 1.42965393664389, -3.20658268810889, -2.89359175055380, 1.92720616029590, -3.30867749533838, -8.68309760930295, -1.33468782240254, 6.23406695352077, 2.14277793025021, -3.12388851622980, 6.63730420609597, -2.97003136804169, 6.63730420609597, -3.12388851622980, 2.14277793025021, 6.23406695352078, -1.33468782240254, -8.68309760930295, -3.30867749533838, 1.92720616029590, -2.89359175055380, -3.20658 [...]
+-8.04061485937774, -1.97690770444849, 1.00357056324021, 1.65013744503928, -4.63349911093906, 5.48328590532855, -5.09179630348133, 3.43925875142879, -0.19522792824256, -4.41880664574692, -3.62073816758944, -1.26110986965203, 2.43268462834227, 4.86043549424324, -0.82823839280681, 0.13482266086208, 2.28329710556104, 0.13482266086208, -0.82823839280681, 4.86043549424323, 2.43268462834227, -1.26110986965203, -3.62073816758944, -4.41880664574692, -0.19522792824256, 3.43925875142879, -5.0917963 [...]
+-3.71498643311384, -3.73133453905243, 4.00680304613775, -4.04361013697313, -0.31460444516965, 0.95631205842463, -1.63577612251258, -1.20290159740288, 2.60109169463730, -5.69177347099769, -4.76366245248063, -1.45639832329181, 3.30980232396382, 5.31498487748052, -3.33933128477634, 4.37041123049489, -1.51286064307257, 4.37041123049489, -3.33933128477634, 5.31498487748053, 3.30980232396383, -1.45639832329180, -4.76366245248063, -5.69177347099768, 2.60109169463730, -1.20290159740288, -1.63577 [...]
+1.22622910074183, 4.90684354592600, -2.22114768258670, -4.39896014078974, 2.08262190327753, -3.18496771685189, 1.58356913845334, -5.04529036624320, 1.69516723572822, 0.60671384673762, -4.01740001684068, -0.40241907040053, 3.55192426393500, -2.50555708110943, -1.15804266333746, 4.62175344581036, -3.57701160892279, 4.62175344581036, -1.15804266333746, -2.50555708110942, 3.55192426393500, -0.40241907040053, -4.01740001684067, 0.60671384673762, 1.69516723572822, -5.04529036624320, 1.58356913 [...]
+7.45314113785137, 0.40522255590017, -1.77198659016177, 2.81700991377897, 3.20070445159922, -4.15345461968358, 4.76249012110497, 0.09316398232987, -2.30785361326424, 5.76435158044440, 6.95524160412663, 1.94882597453897, -5.48758101702970, -4.88950044182766, 3.24460130567061, -4.56151295032943, 0.84591298513178, -4.56151295032943, 3.24460130567062, -4.88950044182767, -5.48758101702970, 1.94882597453896, 6.95524160412664, 5.76435158044440, -2.30785361326424, 0.09316398232988, 4.762490121104 [...]
+-7.26720076758330, -1.10945138725057, 1.83004958335901, -0.96967204162724, -4.24905200054360, 5.47084029905553, -5.61425779268295, 1.73747118546329, 1.42660056355516, -5.27828638160723, -5.27317776575959, -1.74807270097580, 4.21054331835857, 4.84683462903593, -2.40054580698697, 2.43962993181923, 0.78500494697434, 2.43962993181922, -2.40054580698697, 4.84683462903593, 4.21054331835858, -1.74807270097580, -5.27317776575959, -5.27828638160723, 1.42660056355516, 1.73747118546329, -5.61425779 [...]
+7.65897239092610, 1.10430427319254, -2.35100199933245, 3.10956530285241, 3.13777746695841, -4.19944122367311, 4.79382791045846, 0.10920956890174, -2.56092537099428, 6.35451296569500, 7.06667104647448, 2.13464708292740, -5.68071530815100, -5.34749768372170, 3.37765971926726, -4.64340253443280, 0.75099213839613, -4.64340253443280, 3.37765971926726, -5.34749768372171, -5.68071530815101, 2.13464708292739, 7.06667104647449, 6.35451296569500, -2.56092537099428, 0.10920956890174, 4.793827910458 [...]
+3.34270509708587, 4.94185899547755, -2.02552627641390, -5.15140567689139, 3.42339199605816, -4.68694718604548, 2.97280942206309, -6.08259906422506, 2.02375397050821, 1.29608091681629, -3.06660563763092, -0.29300797036941, 3.16345686806901, -3.61527169774768, -0.93474480447748, 4.54599511924196, -4.00677103713394, 4.54599511924196, -0.93474480447748, -3.61527169774768, 3.16345686806901, -0.29300797036941, -3.06660563763092, 1.29608091681629, 2.02375397050821, -6.08259906422505, 2.97280942 [...]
+-2.13068751521485, -1.27012135093366, 1.80140692197715, -2.50312415926662, -0.24935642556017, 0.52637972828217, -1.07230513610193, -0.94393574078080, 1.44155498234604, -2.88280871715821, -3.30096725318357, -0.63186315705101, 2.00060075280376, 2.95171183532150, -2.32130164798476, 3.22204694387768, -1.51532701290173, 3.22204694387768, -2.32130164798476, 2.95171183532150, 2.00060075280376, -0.63186315705101, -3.30096725318358, -2.88280871715821, 1.44155498234604, -0.94393574078080, -1.07230 [...]
+-2.41884798467293, -2.00323099815561, 0.61653681426136, 2.75860434327362, -1.89165604045305, 2.54631084475110, -1.57350103260289, 2.95552656693729, -0.84190273437647, -0.84675547456157, 1.50170173546029, -0.22922524869928, -0.88062860396701, 1.26777130810009, 1.01851830962833, -2.71592613295942, 2.50838744940899, -2.71592613295942, 1.01851830962833, 1.26777130810008, -0.88062860396701, -0.22922524869928, 1.50170173546029, -0.84675547456157, -0.84190273437647, 2.95552656693729, -1.5735010 [...]
+-4.29714416929056, -3.68116123952020, 0.76966175684023, 6.10399148685355, -4.15726955473463, 5.47498568804640, -3.61566443695118, 6.66813114318867, -2.64438336517075, -0.49197312553650, 2.77734125862661, 0.37806190177288, -2.84429572672005, 2.81861600470915, 1.55112735376195, -5.00933321638367, 4.33957275757152, -5.00933321638368, 1.55112735376195, 2.81861600470915, -2.84429572672005, 0.37806190177288, 2.77734125862661, -0.49197312553650, -2.64438336517075, 6.66813114318866, -3.615664436 [...]
+-8.92885648852066, -6.50769983883173, 4.60325806736432, 1.51964322931870, -4.74544143880712, 6.61445676325356, -5.52064598811949, 4.73744068492497, 0.85834705777993, -7.17416711077465, -2.45874887452119, -1.80106767285323, 1.80204741885860, 7.85706603478576, -1.71612985165882, -0.56931764684860, 3.26632402458718, -0.56931764684861, -1.71612985165882, 7.85706603478576, 1.80204741885860, -1.80106767285322, -2.45874887452120, -7.17416711077465, 0.85834705777993, 4.73744068492496, -5.5206459 [...]
+-0.89388307485569, 2.67422932178826, -0.36075817502235, -5.07189564473924, 1.56428205290769, -1.88291408923939, 0.46309439176972, -4.32759863730048, 2.23579577863941, -1.26762593199865, -5.60031327787208, -0.55354204656053, 4.06163180601371, 0.34033708682896, -2.92995584959217, 6.44440828082145, -4.66025851484356, 6.44440828082145, -2.92995584959218, 0.34033708682897, 4.06163180601371, -0.55354204656053, -5.60031327787208, -1.26762593199865, 2.23579577863941, -4.32759863730047, 0.4630943 [...]
+-0.41027869852247, -3.95139275129727, 0.62757571076232, 6.34155798998998, -2.13433630442005, 2.62498532925977, -0.76437173184658, 5.59990918246035, -2.77635798467388, 0.85629018230064, 6.14350768863857, 0.52478881167432, -4.55373346255246, 0.39931603526423, 3.57212067801172, -7.70088049805676, 5.81727760187053, -7.70088049805676, 3.57212067801172, 0.39931603526423, -4.55373346255246, 0.52478881167432, 6.14350768863858, 0.85629018230064, -2.77635798467388, 5.59990918246034, -0.76437173184 [...]
+-0.89388307485569, 2.67422932178826, -0.36075817502235, -5.07189564473924, 1.56428205290769, -1.88291408923939, 0.46309439176972, -4.32759863730048, 2.23579577863941, -1.26762593199866, -5.60031327787208, -0.55354204656054, 4.06163180601371, 0.34033708682897, -2.92995584959218, 6.44440828082145, -4.66025851484356, 6.44440828082146, -2.92995584959218, 0.34033708682897, 4.06163180601371, -0.55354204656053, -5.60031327787209, -1.26762593199865, 2.23579577863941, -4.32759863730047, 0.4630943 [...]
+-8.92885648852066, -6.50769983883173, 4.60325806736432, 1.51964322931870, -4.74544143880712, 6.61445676325356, -5.52064598811949, 4.73744068492497, 0.85834705777993, -7.17416711077465, -2.45874887452119, -1.80106767285323, 1.80204741885859, 7.85706603478576, -1.71612985165882, -0.56931764684860, 3.26632402458718, -0.56931764684861, -1.71612985165882, 7.85706603478576, 1.80204741885859, -1.80106767285322, -2.45874887452119, -7.17416711077465, 0.85834705777993, 4.73744068492497, -5.5206459 [...]
+-4.29714416929056, -3.68116123952020, 0.76966175684023, 6.10399148685355, -4.15726955473463, 5.47498568804640, -3.61566443695118, 6.66813114318866, -2.64438336517075, -0.49197312553650, 2.77734125862660, 0.37806190177288, -2.84429572672004, 2.81861600470916, 1.55112735376195, -5.00933321638366, 4.33957275757152, -5.00933321638367, 1.55112735376195, 2.81861600470915, -2.84429572672004, 0.37806190177288, 2.77734125862660, -0.49197312553650, -2.64438336517075, 6.66813114318866, -3.615664436 [...]
+-2.41884798467293, -2.00323099815562, 0.61653681426137, 2.75860434327362, -1.89165604045305, 2.54631084475111, -1.57350103260289, 2.95552656693730, -0.84190273437647, -0.84675547456157, 1.50170173546029, -0.22922524869928, -0.88062860396701, 1.26777130810009, 1.01851830962833, -2.71592613295942, 2.50838744940900, -2.71592613295942, 1.01851830962833, 1.26777130810009, -0.88062860396701, -0.22922524869928, 1.50170173546029, -0.84675547456158, -0.84190273437647, 2.95552656693729, -1.5735010 [...]
+-2.13068751521486, -1.27012135093366, 1.80140692197715, -2.50312415926662, -0.24935642556017, 0.52637972828218, -1.07230513610193, -0.94393574078080, 1.44155498234605, -2.88280871715822, -3.30096725318358, -0.63186315705102, 2.00060075280377, 2.95171183532150, -2.32130164798476, 3.22204694387769, -1.51532701290173, 3.22204694387769, -2.32130164798476, 2.95171183532151, 2.00060075280377, -0.63186315705101, -3.30096725318358, -2.88280871715822, 1.44155498234605, -0.94393574078080, -1.07230 [...]
+3.34270509708587, 4.94185899547755, -2.02552627641390, -5.15140567689139, 3.42339199605816, -4.68694718604548, 2.97280942206309, -6.08259906422506, 2.02375397050821, 1.29608091681629, -3.06660563763092, -0.29300797036941, 3.16345686806901, -3.61527169774768, -0.93474480447748, 4.54599511924196, -4.00677103713394, 4.54599511924196, -0.93474480447748, -3.61527169774768, 3.16345686806901, -0.29300797036941, -3.06660563763092, 1.29608091681629, 2.02375397050821, -6.08259906422505, 2.97280942 [...]
+7.65897239092609, 1.10430427319254, -2.35100199933245, 3.10956530285241, 3.13777746695841, -4.19944122367311, 4.79382791045846, 0.10920956890174, -2.56092537099428, 6.35451296569500, 7.06667104647448, 2.13464708292740, -5.68071530815100, -5.34749768372170, 3.37765971926726, -4.64340253443280, 0.75099213839613, -4.64340253443279, 3.37765971926726, -5.34749768372170, -5.68071530815100, 2.13464708292739, 7.06667104647448, 6.35451296569500, -2.56092537099428, 0.10920956890174, 4.793827910458 [...]
+-7.26720076758330, -1.10945138725058, 1.83004958335901, -0.96967204162724, -4.24905200054360, 5.47084029905553, -5.61425779268296, 1.73747118546330, 1.42660056355516, -5.27828638160724, -5.27317776575959, -1.74807270097580, 4.21054331835857, 4.84683462903594, -2.40054580698697, 2.43962993181923, 0.78500494697435, 2.43962993181922, -2.40054580698697, 4.84683462903594, 4.21054331835858, -1.74807270097580, -5.27317776575959, -5.27828638160723, 1.42660056355516, 1.73747118546329, -5.61425779 [...]
+7.45314113785137, 0.40522255590017, -1.77198659016177, 2.81700991377898, 3.20070445159922, -4.15345461968358, 4.76249012110498, 0.09316398232988, -2.30785361326424, 5.76435158044440, 6.95524160412664, 1.94882597453897, -5.48758101702970, -4.88950044182767, 3.24460130567062, -4.56151295032943, 0.84591298513178, -4.56151295032943, 3.24460130567062, -4.88950044182767, -5.48758101702970, 1.94882597453896, 6.95524160412664, 5.76435158044440, -2.30785361326424, 0.09316398232988, 4.762490121104 [...]
+1.22622910074183, 4.90684354592600, -2.22114768258670, -4.39896014078974, 2.08262190327753, -3.18496771685189, 1.58356913845334, -5.04529036624320, 1.69516723572822, 0.60671384673762, -4.01740001684067, -0.40241907040053, 3.55192426393499, -2.50555708110943, -1.15804266333746, 4.62175344581036, -3.57701160892279, 4.62175344581036, -1.15804266333746, -2.50555708110942, 3.55192426393499, -0.40241907040053, -4.01740001684067, 0.60671384673762, 1.69516723572822, -5.04529036624320, 1.58356913 [...]
+-3.71498643311384, -3.73133453905243, 4.00680304613775, -4.04361013697313, -0.31460444516965, 0.95631205842463, -1.63577612251258, -1.20290159740288, 2.60109169463730, -5.69177347099769, -4.76366245248063, -1.45639832329181, 3.30980232396382, 5.31498487748052, -3.33933128477634, 4.37041123049489, -1.51286064307257, 4.37041123049489, -3.33933128477634, 5.31498487748052, 3.30980232396383, -1.45639832329180, -4.76366245248063, -5.69177347099768, 2.60109169463730, -1.20290159740288, -1.63577 [...]
+-6.26428955477971, -3.97118704398744, 3.19273713259141, -0.95599842323359, -2.93780486306583, 3.95657463979202, -4.02578325969409, 1.97483570549549, 0.88119810453719, -5.36737536199558, -4.47248804747262, -1.12836861956163, 2.40160708703872, 6.28477134161354, -2.61729237165413, 2.49243503534318, 0.28709273185579, 2.49243503534317, -2.61729237165413, 6.28477134161355, 2.40160708703872, -1.12836861956162, -4.47248804747263, -5.36737536199558, 0.88119810453719, 1.97483570549549, -4.02578325 [...]
+-5.55618265959335, -1.35137419559986, 2.12013235664412, -3.15131974934694, -1.53800290925024, 1.86268707389469, -2.56934693631093, -1.08941125013903, 2.37962023586021, -5.55858881046798, -5.43301166326226, -1.92777660045593, 4.60064068752284, 4.16196925523274, -2.31965183123754, 3.60922825815115, -0.42372040103379, 3.60922825815115, -2.31965183123754, 4.16196925523274, 4.60064068752284, -1.92777660045593, -5.43301166326227, -5.55858881046797, 2.37962023586021, -1.08941125013903, -2.56934 [...]
+4.28747341136722, 3.75145187207707, -0.99316777851351, -6.14302836100368, 4.19626034990540, -5.26910840168976, 3.38280492003585, -6.39072939183549, 2.11759217482208, 1.32143256889645, -3.62306864812320, 0.30210410143904, 2.36784113720966, -2.26698240951613, -2.55138128407136, 6.55184834088415, -6.04350466201750, 6.55184834088415, -2.55138128407136, -2.26698240951613, 2.36784113720966, 0.30210410143904, -3.62306864812321, 1.32143256889645, 2.11759217482208, -6.39072939183548, 3.3828049200 [...]
+5.39701483342643, 1.41582881334481, -3.26218528381419, 5.33403134523670, 1.53666102128426, -2.71124045248661, 3.79129082238306, 1.68130362049398, -3.20537853992316, 5.89762178955420, 7.99134344482788, 1.42924096410416, -5.15372244076487, -6.14113364751397, 5.78594545948304, -8.13014598865718, 4.32275541708897, -8.13014598865718, 5.78594545948304, -6.14113364751398, -5.15372244076487, 1.42924096410415, 7.99134344482788, 5.89762178955420, -3.20537853992316, 1.68130362049397, 3.791290822383 [...]
+-5.82311022995469, -2.05863138521962, 3.20276052803463, -3.00663510117185, -3.26767841865508, 4.85749834936510, -5.37571393562895, 0.75626586966107, 2.11217673413559, -5.49551754796539, -6.45318874490494, -1.19163786373660, 3.81135348684982, 6.49279975909239, -5.12278006797189, 6.01038894031824, -2.59884219320035, 6.01038894031824, -5.12278006797189, 6.49279975909239, 3.81135348684982, -1.19163786373659, -6.45318874490495, -5.49551754796539, 2.11217673413559, 0.75626586966107, -5.3757139 [...]
+6.24752505175794, 1.51298934771288, -3.26856274656056, 5.11436420992591, 2.02319259905925, -3.26545068248241, 4.30111210707947, 1.33444646564807, -3.15935375680643, 6.29114428545988, 8.35295215016554, 1.54626267562064, -5.39706441813527, -6.57897419473101, 5.84194841954571, -8.13187192632632, 4.09565769885504, -8.13187192632632, 5.84194841954571, -6.57897419473101, -5.39706441813527, 1.54626267562063, 8.35295215016555, 6.29114428545987, -3.15935375680643, 1.33444646564807, 4.301112107079 [...]
+5.27079226569002, 4.97233787026290, -2.01927601900400, -5.58891864591323, 4.43515112001899, -5.73134033347546, 3.88049807190540, -6.52320885785919, 1.71275615695759, 2.62685604630642, -2.80437300865437, 0.60051225570305, 1.85841519333930, -3.62590151731326, -1.95136347035007, 5.94155412955290, -6.00460351069659, 5.94155412955290, -1.95136347035008, -3.62590151731326, 1.85841519333930, 0.60051225570305, -2.80437300865437, 2.62685604630643, 1.71275615695759, -6.52320885785918, 3.8804980719 [...]
+-2.15727765389928, -0.74456611101775, 1.60382194426131, -2.95104808572994, 0.07872642086302, 0.02810955042859, -0.63611974628204, -1.73919434898226, 2.01214593617921, -3.27214500162122, -3.18048606226198, -1.18618364737300, 2.89970888323742, 2.07807748249136, -1.68681554667902, 2.78993058088680, -0.96104413201117, 2.78993058088680, -1.68681554667902, 2.07807748249136, 2.89970888323742, -1.18618364737299, -3.18048606226199, -3.27214500162121, 2.01214593617921, -1.73919434898226, -0.636119 [...]
+-3.23475436001362, -2.09145744791353, 0.57266793386382, 3.08891594387117, -2.66573074772091, 3.46968846500064, -2.53890182915785, 3.72373783622912, -1.31672171093509, -0.84414203341168, 0.65721185685545, 0.04910678044018, -0.99810235576164, 2.13269965524535, 0.53038519561303, -2.26459626133157, 2.32284374374864, -2.26459626133157, 0.53038519561304, 2.13269965524535, -0.99810235576164, 0.04910678044018, 0.65721185685545, -0.84414203341168, -1.31672171093509, 3.72373783622911, -2.538901829 [...]
+-4.82539420720761, -5.07318501768494, 2.07372354321970, 5.18438946919298, -3.78429252459930, 5.19909080783247, -3.33087093161850, 6.13113382583172, -1.67102662692398, -2.16894885184669, 2.59090571534986, -0.18791296410164, -2.28623125146986, 3.94917886979350, 0.99930933039009, -4.44182794880375, 4.21982875721568, -4.44182794880376, 0.99930933039009, 3.94917886979349, -2.28623125146986, -0.18791296410164, 2.59090571534986, -2.16894885184669, -1.67102662692398, 6.13113382583172, -3.3308709 [...]
+-10.96405873216306, -5.49150552325290, 3.82624282372670, 1.96558659778118, -6.56938079890574, 8.60419408168631, -7.70917449393445, 5.74806470570420, 0.28145933895284, -7.41150445225817, -4.40082017581657, -1.92997661116153, 2.97157764512724, 8.27658399093626, -1.66844771288540, -0.48083403447281, 4.01331228203412, -0.48083403447281, -1.66844771288540, 8.27658399093626, 2.97157764512724, -1.92997661116152, -4.40082017581657, -7.41150445225817, 0.28145933895284, 5.74806470570420, -7.709174 [...]
+1.58357489680906, 1.86743793574567, 0.89650211298442, -7.60642093095642, 4.67038737737714, -5.32183227016878, 3.65505184709454, -7.24782915483370, 3.91352879545471, -1.64811004903694, -4.90619395555925, -0.56115910558878, 3.74593963613661, 0.29352325446484, -4.30049041083907, 8.81461989805375, -7.49002506695657, 8.81461989805376, -4.30049041083908, 0.29352325446485, 3.74593963613661, -0.56115910558877, -4.90619395555925, -1.64811004903693, 3.91352879545471, -7.24782915483370, 3.655051847 [...]
+-3.29887958406139, -3.18181660143523, -0.72165979302802, 9.07920091694035, -5.60220427104272, 6.38919416810959, -4.30789185138654, 8.79189173837027, -4.62369911664526, 1.06709167117830, 5.22579145003335, 0.43657195186996, -4.04084593620938, 0.52054426713421, 5.22801827763571, -10.43601695204710, 9.19082626268238, -10.43601695204711, 5.22801827763572, 0.52054426713420, -4.04084593620938, 0.43657195186995, 5.22579145003336, 1.06709167117829, -4.62369911664526, 8.79189173837026, -4.30789185 [...]
+1.58357489680906, 1.86743793574567, 0.89650211298442, -7.60642093095642, 4.67038737737714, -5.32183227016878, 3.65505184709454, -7.24782915483370, 3.91352879545471, -1.64811004903694, -4.90619395555925, -0.56115910558878, 3.74593963613661, 0.29352325446484, -4.30049041083908, 8.81461989805376, -7.49002506695658, 8.81461989805377, -4.30049041083908, 0.29352325446485, 3.74593963613661, -0.56115910558877, -4.90619395555925, -1.64811004903693, 3.91352879545471, -7.24782915483370, 3.655051847 [...]
+-10.96405873216306, -5.49150552325290, 3.82624282372670, 1.96558659778118, -6.56938079890574, 8.60419408168631, -7.70917449393445, 5.74806470570421, 0.28145933895283, -7.41150445225816, -4.40082017581657, -1.92997661116153, 2.97157764512724, 8.27658399093626, -1.66844771288540, -0.48083403447281, 4.01331228203412, -0.48083403447282, -1.66844771288540, 8.27658399093626, 2.97157764512724, -1.92997661116152, -4.40082017581657, -7.41150445225817, 0.28145933895283, 5.74806470570420, -7.709174 [...]
+-4.82539420720762, -5.07318501768494, 2.07372354321970, 5.18438946919297, -3.78429252459930, 5.19909080783247, -3.33087093161850, 6.13113382583172, -1.67102662692397, -2.16894885184669, 2.59090571534986, -0.18791296410164, -2.28623125146986, 3.94917886979350, 0.99930933039008, -4.44182794880375, 4.21982875721567, -4.44182794880375, 0.99930933039009, 3.94917886979350, -2.28623125146985, -0.18791296410164, 2.59090571534986, -2.16894885184670, -1.67102662692397, 6.13113382583171, -3.3308709 [...]
+-3.23475436001362, -2.09145744791353, 0.57266793386382, 3.08891594387117, -2.66573074772091, 3.46968846500065, -2.53890182915786, 3.72373783622912, -1.31672171093510, -0.84414203341168, 0.65721185685545, 0.04910678044018, -0.99810235576164, 2.13269965524536, 0.53038519561303, -2.26459626133157, 2.32284374374865, -2.26459626133157, 0.53038519561304, 2.13269965524535, -0.99810235576164, 0.04910678044018, 0.65721185685545, -0.84414203341168, -1.31672171093510, 3.72373783622912, -2.538901829 [...]
+-2.15727765389928, -0.74456611101775, 1.60382194426131, -2.95104808572995, 0.07872642086302, 0.02810955042859, -0.63611974628204, -1.73919434898226, 2.01214593617922, -3.27214500162122, -3.18048606226199, -1.18618364737300, 2.89970888323742, 2.07807748249136, -1.68681554667902, 2.78993058088681, -0.96104413201118, 2.78993058088681, -1.68681554667902, 2.07807748249137, 2.89970888323742, -1.18618364737299, -3.18048606226199, -3.27214500162122, 2.01214593617922, -1.73919434898226, -0.636119 [...]
+5.27079226569002, 4.97233787026290, -2.01927601900400, -5.58891864591323, 4.43515112001899, -5.73134033347546, 3.88049807190540, -6.52320885785919, 1.71275615695759, 2.62685604630642, -2.80437300865437, 0.60051225570305, 1.85841519333930, -3.62590151731326, -1.95136347035007, 5.94155412955290, -6.00460351069659, 5.94155412955290, -1.95136347035008, -3.62590151731326, 1.85841519333930, 0.60051225570305, -2.80437300865437, 2.62685604630643, 1.71275615695759, -6.52320885785918, 3.8804980719 [...]
+6.24752505175793, 1.51298934771288, -3.26856274656056, 5.11436420992590, 2.02319259905925, -3.26545068248241, 4.30111210707947, 1.33444646564807, -3.15935375680642, 6.29114428545988, 8.35295215016554, 1.54626267562064, -5.39706441813527, -6.57897419473100, 5.84194841954571, -8.13187192632631, 4.09565769885503, -8.13187192632631, 5.84194841954571, -6.57897419473101, -5.39706441813527, 1.54626267562063, 8.35295215016554, 6.29114428545987, -3.15935375680642, 1.33444646564807, 4.301112107079 [...]
+-5.82311022995470, -2.05863138521963, 3.20276052803463, -3.00663510117184, -3.26767841865508, 4.85749834936511, -5.37571393562895, 0.75626586966107, 2.11217673413559, -5.49551754796540, -6.45318874490494, -1.19163786373660, 3.81135348684982, 6.49279975909239, -5.12278006797189, 6.01038894031823, -2.59884219320034, 6.01038894031823, -5.12278006797189, 6.49279975909240, 3.81135348684982, -1.19163786373659, -6.45318874490495, -5.49551754796539, 2.11217673413559, 0.75626586966108, -5.3757139 [...]
+5.39701483342643, 1.41582881334481, -3.26218528381419, 5.33403134523671, 1.53666102128426, -2.71124045248661, 3.79129082238306, 1.68130362049398, -3.20537853992316, 5.89762178955421, 7.99134344482788, 1.42924096410416, -5.15372244076487, -6.14113364751398, 5.78594545948304, -8.13014598865719, 4.32275541708897, -8.13014598865719, 5.78594545948304, -6.14113364751398, -5.15372244076488, 1.42924096410415, 7.99134344482789, 5.89762178955420, -3.20537853992316, 1.68130362049397, 3.791290822383 [...]
+4.28747341136722, 3.75145187207707, -0.99316777851351, -6.14302836100368, 4.19626034990540, -5.26910840168976, 3.38280492003585, -6.39072939183548, 2.11759217482207, 1.32143256889645, -3.62306864812320, 0.30210410143904, 2.36784113720966, -2.26698240951614, -2.55138128407136, 6.55184834088415, -6.04350466201749, 6.55184834088415, -2.55138128407136, -2.26698240951613, 2.36784113720966, 0.30210410143904, -3.62306864812320, 1.32143256889645, 2.11759217482207, -6.39072939183548, 3.3828049200 [...]
+-5.55618265959335, -1.35137419559985, 2.12013235664412, -3.15131974934694, -1.53800290925024, 1.86268707389469, -2.56934693631093, -1.08941125013904, 2.37962023586021, -5.55858881046798, -5.43301166326226, -1.92777660045593, 4.60064068752284, 4.16196925523274, -2.31965183123754, 3.60922825815115, -0.42372040103379, 3.60922825815115, -2.31965183123754, 4.16196925523274, 4.60064068752284, -1.92777660045593, -5.43301166326227, -5.55858881046797, 2.37962023586021, -1.08941125013903, -2.56934 [...]
+-2.72700060220857, 0.41568024652629, 2.64606645147220, -8.91749093368438, 1.99544708398240, -2.51478954068494, 0.28162144378410, -6.71128709046098, 5.17322923887540, -6.43617677610981, -8.28608726491123, -2.57838013691621, 7.45663395243100, 2.97125415713897, -4.12170476847627, 8.23986341593006, -4.03974362747457, 8.23986341593007, -4.12170476847627, 2.97125415713897, 7.45663395243101, -2.57838013691620, -8.28608726491123, -6.43617677610980, 5.17322923887540, -6.71128709046097, 0.28162144 [...]
+1.73128535207735, 4.42277821365558, -0.77671619741817, -8.00617484900773, 3.01859078190891, -4.02295223577496, 1.41866906333622, -7.07579076558005, 2.92575557929785, -0.67501814145510, -7.53648180148717, -0.26370581458193, 4.85256268243735, -0.30993684235978, -4.40351530596535, 9.65216259465132, -7.35649739987150, 9.65216259465133, -4.40351530596536, -0.30993684235977, 4.85256268243735, -0.26370581458193, -7.53648180148717, -0.67501814145509, 2.92575557929785, -7.07579076558004, 1.418669 [...]
+12.60915579383108, 5.89410801419846, -4.55319083557949, -2.51570130621527, 10.00099644272481, -13.34016357306758, 12.40542650866909, -8.39379145591341, 0.21807816471697, 8.23340961328307, 6.51312587154956, 1.54976024889811, -2.94150737583813, -11.45302659170248, 4.68195727310600, -2.13483830382407, -2.42393281046169, -2.13483830382406, 4.68195727310600, -11.45302659170248, -2.94150737583814, 1.54976024889810, 6.51312587154956, 8.23340961328307, 0.21807816471697, -8.39379145591340, 12.405 [...]
+-5.72596346153870, -5.28154588262918, -0.75446720430749, 16.17403127958275, -14.67097021687280, 17.62183116637571, -14.36465810779321, 18.59598414416564, -8.96596902191130, 1.47145989350062, 6.42403852147234, 1.49826720899706, -7.47724312784464, 4.61026552364062, 4.66743563953285, -14.07410129711223, 13.32400037935799, -14.07410129711224, 4.66743563953286, 4.61026552364061, -7.47724312784464, 1.49826720899705, 6.42403852147234, 1.47145989350060, -8.96596902191130, 18.59598414416563, -14. [...]
+2.61046301711100, 3.04480719285478, 3.17638308273625, -16.38705649694589, 13.78263079920826, -15.56852546238397, 12.95463294889952, -17.55609336202338, 10.28559907526657, -4.09513847072713, -6.95550444596427, -2.01121862072098, 7.89643514317116, -1.36745186073813, -6.91442943777618, 15.64257496744378, -14.35039247887897, 15.64257496744379, -6.91442943777619, -1.36745186073812, 7.89643514317116, -2.01121862072096, -6.95550444596427, -4.09513847072711, 10.28559907526657, -17.55609336202337 [...]
+-5.49443808778004, -5.12499614470875, -1.09825425376246, 16.95523752445051, -14.80287658417080, 17.76771674706712, -14.29997403527971, 19.05977187240720, -9.32710389012735, 2.03033008134396, 7.25788878267191, 1.62570655537498, -7.98948037773655, 4.10075074825109, 5.19353659047516, -14.95262541755741, 13.81324555487177, -14.95262541755742, 5.19353659047517, 4.10075074825108, -7.98948037773655, 1.62570655537496, 7.25788878267192, 2.03033008134394, -9.32710389012735, 19.05977187240719, -14. [...]
+13.57871740705889, 5.50136926887857, -4.72895145625602, -1.05768680610594, 10.00301995124347, -13.18620819678791, 12.70718812779511, -7.30793112334190, -0.59322683729438, 9.47718886177679, 8.34565770450198, 2.10885500022443, -4.58192509635757, -11.97401378825268, 5.30171643610927, -3.59524594324401, -1.88304543904608, -3.59524594324401, 5.30171643610927, -11.97401378825269, -4.58192509635758, 2.10885500022442, 8.34565770450199, 9.47718886177679, -0.59322683729438, -7.30793112334190, 12.7 [...]
+1.78273129013546, 3.82633907751006, -1.55812050662266, -4.07085358040659, 1.91708787608348, -2.58728532145840, 1.15842446413443, -4.14583615473415, 1.23684826993737, 1.00436308239746, -3.73954861017542, 0.15046677467401, 2.45709331336938, -1.57854587305166, -2.00738803692525, 5.19404456177215, -4.44651505319356, 5.19404456177216, -2.00738803692525, -1.57854587305165, 2.45709331336938, 0.15046677467401, -3.73954861017542, 1.00436308239747, 1.23684826993737, -4.14583615473415, 1.1584244641 [...]
+-5.49502176637932, -3.81566614536323, 3.39841270997282, -1.62907541680399, -1.88094502706279, 2.72926876259472, -2.75148031195139, 0.77873058470238, 1.77675390966589, -5.65710642821225, -3.61532764366092, -1.51653701745227, 2.67195150372528, 5.49607913167386, -2.36508076036627, 2.32446148837618, 0.23227774478850, 2.32446148837618, -2.36508076036627, 5.49607913167386, 2.67195150372528, -1.51653701745226, -3.61532764366093, -5.65710642821225, 1.77675390966589, 0.77873058470238, -2.75148031 [...]
+-13.01757394463585, -5.94707066894136, 4.71363593681632, 0.12258279889192, -7.08797623258932, 9.08534712332158, -8.76662365424324, 4.93409103891055, 1.27547062793833, -9.78625487789812, -7.27949473660446, -2.72026247359259, 5.15675379714660, 10.05373766180936, -2.73709521294256, 1.41005231982266, 3.70456075718665, 1.41005231982265, -2.73709521294256, 10.05373766180936, 5.15675379714661, -2.72026247359258, -7.27949473660446, -9.78625487789812, 1.27547062793833, 4.93409103891054, -8.766623 [...]
+-7.98923425086752, -1.86721702631852, 5.80347661652667, -12.20102789978222, 0.48443538199964, 0.63159238416103, -3.08423889386641, -6.87720017336103, 7.48612002563126, -11.03643130953561, -14.15967016416117, -3.00296705199610, 9.94368055250728, 9.96880160926344, -10.89565150789557, 16.86176188057157, -10.25902016179876, 16.86176188057158, -10.89565150789558, 9.96880160926346, 9.94368055250728, -3.00296705199607, -14.15967016416118, -11.03643130953559, 7.48612002563126, -6.87720017336102, [...]
+9.76213378709616, 7.63063362031139, -6.13765678528965, -3.94012618663503, 9.66301782937902, -13.93200503573686, 11.92610582614736, -9.57380736569911, -0.23254866300657, 7.63663890459861, 1.74730858090413, 0.95291868699360, 0.67369639912220, -12.25161251887637, 6.53269983285839, -2.33197675407965, -0.41607591876272, -2.33197675407965, 6.53269983285838, -12.25161251887637, 0.67369639912220, 0.95291868699359, 1.74730858090414, 7.63663890459861, -0.23254866300657, -9.57380736569911, 11.92610 [...]
+-12.92227031702633, -9.52346686232382, 7.03921162188168, 4.79043788749283, -13.12733241085900, 17.76081151462223, -15.93585792875255, 12.10719822639875, -0.43197686918711, -10.38299026427097, -3.81510704769825, -1.61934412884366, 0.23097956071699, 15.53837091368543, -7.00812190783967, 2.14786524468676, 2.43974572557895, 2.14786524468675, -7.00812190783967, 15.53837091368543, 0.23097956071699, -1.61934412884365, -3.81510704769826, -10.38299026427097, -0.43197686918711, 12.10719822639874,  [...]
+9.76213378709616, 7.63063362031139, -6.13765678528966, -3.94012618663504, 9.66301782937902, -13.93200503573687, 11.92610582614737, -9.57380736569912, -0.23254866300657, 7.63663890459862, 1.74730858090413, 0.95291868699360, 0.67369639912221, -12.25161251887638, 6.53269983285839, -2.33197675407965, -0.41607591876273, -2.33197675407964, 6.53269983285838, -12.25161251887638, 0.67369639912220, 0.95291868699359, 1.74730858090414, 7.63663890459862, -0.23254866300657, -9.57380736569912, 11.92610 [...]
+-7.98923425086753, -1.86721702631852, 5.80347661652667, -12.20102789978222, 0.48443538199963, 0.63159238416104, -3.08423889386642, -6.87720017336102, 7.48612002563125, -11.03643130953561, -14.15967016416117, -3.00296705199610, 9.94368055250728, 9.96880160926345, -10.89565150789557, 16.86176188057156, -10.25902016179876, 16.86176188057157, -10.89565150789558, 9.96880160926346, 9.94368055250728, -3.00296705199607, -14.15967016416118, -11.03643130953559, 7.48612002563125, -6.87720017336101, [...]
+-13.01757394463585, -5.94707066894135, 4.71363593681632, 0.12258279889191, -7.08797623258931, 9.08534712332156, -8.76662365424323, 4.93409103891053, 1.27547062793833, -9.78625487789812, -7.27949473660446, -2.72026247359259, 5.15675379714661, 10.05373766180935, -2.73709521294256, 1.41005231982266, 3.70456075718664, 1.41005231982266, -2.73709521294255, 10.05373766180935, 5.15675379714661, -2.72026247359258, -7.27949473660446, -9.78625487789812, 1.27547062793833, 4.93409103891053, -8.766623 [...]
+-5.49502176637933, -3.81566614536323, 3.39841270997283, -1.62907541680400, -1.88094502706280, 2.72926876259473, -2.75148031195140, 0.77873058470238, 1.77675390966590, -5.65710642821226, -3.61532764366093, -1.51653701745227, 2.67195150372529, 5.49607913167387, -2.36508076036628, 2.32446148837619, 0.23227774478850, 2.32446148837619, -2.36508076036628, 5.49607913167387, 2.67195150372529, -1.51653701745226, -3.61532764366093, -5.65710642821226, 1.77675390966590, 0.77873058470238, -2.75148031 [...]
+1.78273129013546, 3.82633907751006, -1.55812050662266, -4.07085358040660, 1.91708787608350, -2.58728532145842, 1.15842446413444, -4.14583615473417, 1.23684826993738, 1.00436308239746, -3.73954861017543, 0.15046677467401, 2.45709331336938, -1.57854587305166, -2.00738803692525, 5.19404456177216, -4.44651505319356, 5.19404456177216, -2.00738803692525, -1.57854587305166, 2.45709331336938, 0.15046677467401, -3.73954861017543, 1.00436308239747, 1.23684826993738, -4.14583615473416, 1.1584244641 [...]
+13.57871740705889, 5.50136926887857, -4.72895145625602, -1.05768680610594, 10.00301995124347, -13.18620819678791, 12.70718812779511, -7.30793112334190, -0.59322683729438, 9.47718886177679, 8.34565770450198, 2.10885500022443, -4.58192509635757, -11.97401378825268, 5.30171643610927, -3.59524594324401, -1.88304543904608, -3.59524594324401, 5.30171643610927, -11.97401378825269, -4.58192509635758, 2.10885500022442, 8.34565770450199, 9.47718886177679, -0.59322683729438, -7.30793112334190, 12.7 [...]
+-5.49443808778004, -5.12499614470874, -1.09825425376246, 16.95523752445050, -14.80287658417079, 17.76771674706711, -14.29997403527970, 19.05977187240719, -9.32710389012734, 2.03033008134396, 7.25788878267191, 1.62570655537497, -7.98948037773655, 4.10075074825109, 5.19353659047516, -14.95262541755741, 13.81324555487177, -14.95262541755742, 5.19353659047517, 4.10075074825107, -7.98948037773655, 1.62570655537496, 7.25788878267191, 2.03033008134394, -9.32710389012734, 19.05977187240718, -14. [...]
+2.61046301711099, 3.04480719285477, 3.17638308273625, -16.38705649694589, 13.78263079920826, -15.56852546238397, 12.95463294889951, -17.55609336202338, 10.28559907526657, -4.09513847072714, -6.95550444596428, -2.01121862072098, 7.89643514317116, -1.36745186073813, -6.91442943777619, 15.64257496744378, -14.35039247887897, 15.64257496744380, -6.91442943777620, -1.36745186073811, 7.89643514317116, -2.01121862072096, -6.95550444596428, -4.09513847072712, 10.28559907526657, -17.55609336202337 [...]
+-5.72596346153871, -5.28154588262919, -0.75446720430749, 16.17403127958276, -14.67097021687280, 17.62183116637572, -14.36465810779322, 18.59598414416566, -8.96596902191131, 1.47145989350062, 6.42403852147234, 1.49826720899706, -7.47724312784464, 4.61026552364063, 4.66743563953285, -14.07410129711224, 13.32400037935800, -14.07410129711225, 4.66743563953286, 4.61026552364061, -7.47724312784464, 1.49826720899705, 6.42403852147235, 1.47145989350060, -8.96596902191131, 18.59598414416564, -14. [...]
+12.60915579383108, 5.89410801419845, -4.55319083557949, -2.51570130621527, 10.00099644272480, -13.34016357306757, 12.40542650866908, -8.39379145591340, 0.21807816471697, 8.23340961328307, 6.51312587154956, 1.54976024889811, -2.94150737583813, -11.45302659170248, 4.68195727310601, -2.13483830382407, -2.42393281046169, -2.13483830382406, 4.68195727310600, -11.45302659170248, -2.94150737583814, 1.54976024889810, 6.51312587154957, 8.23340961328307, 0.21807816471697, -8.39379145591339, 12.405 [...]
+1.73128535207735, 4.42277821365558, -0.77671619741817, -8.00617484900773, 3.01859078190891, -4.02295223577496, 1.41866906333622, -7.07579076558005, 2.92575557929785, -0.67501814145510, -7.53648180148717, -0.26370581458193, 4.85256268243735, -0.30993684235978, -4.40351530596535, 9.65216259465132, -7.35649739987149, 9.65216259465133, -4.40351530596536, -0.30993684235977, 4.85256268243735, -0.26370581458193, -7.53648180148717, -0.67501814145509, 2.92575557929785, -7.07579076558004, 1.418669 [...]
+12.11025993035841, 7.14715921323743, -6.71915223884532, 3.03616473557748, 4.54981007544728, -6.47158033532207, 6.39170815498602, -1.89004037209981, -3.86926793449737, 11.89583975438121, 7.41330854690787, 3.62126672889507, -6.41975114188891, -10.55043505178084, 4.03290945015561, -3.56582457980762, -1.89580286453544, -3.56582457980762, 4.03290945015561, -10.55043505178085, -6.41975114188891, 3.62126672889506, 7.41330854690788, 11.89583975438121, -3.86926793449737, -1.89004037209981, 6.3917 [...]
+10.22014646958448, 1.99349399911022, -3.91497110886474, 5.93656648448172, 4.07101556772496, -5.70733238978333, 7.08884593586692, 0.66418468077287, -3.54869013835499, 8.84233961188577, 12.14677171858191, 2.14642400909641, -7.59984914267999, -9.55874327458129, 7.50346179729004, -10.43566209914296, 4.52600965662156, -10.43566209914296, 7.50346179729004, -9.55874327458130, -7.59984914268000, 2.14642400909640, 12.14677171858192, 8.84233961188575, -3.54869013835499, 0.66418468077286, 7.0888459 [...]
+-9.54005325319679, -7.10361430488068, 1.33251664571806, 15.60075189522548, -15.97767599794256, 19.95021401225561, -16.32767789148512, 19.48394436078267, -7.70633765403090, -1.49273370290946, 4.60542779514991, 0.84806640285395, -6.24186824394434, 8.08148746552660, 2.38303987364995, -12.04803060548266, 12.40493692891413, -12.04803060548268, 2.38303987364996, 8.08148746552659, -6.24186824394434, 0.84806640285394, 4.60542779514992, -1.49273370290948, -7.70633765403090, 19.48394436078265, -16 [...]
+-8.66039296471438, -2.96954906422847, 10.14128557597927, -20.29030282295903, 10.84055647310283, -9.92851361203805, 7.80619757858033, -16.71852241516466, 15.10298562840199, -14.47961776299700, -13.87617591999615, -4.67580807253828, 13.21833234722021, 9.30206757061809, -13.94410614974062, 22.94708622520246, -17.44077149295898, 22.94708622520247, -13.94410614974063, 9.30206757061812, 13.21833234722022, -4.67580807253824, -13.87617591999616, -14.47961776299697, 15.10298562840199, -16.7185224 [...]
+9.61899681729204, 5.12866081721603, -11.88962795229987, 17.74929701723685, -8.69295715527055, 6.51729390275672, -5.50918272627419, 13.41626903101451, -14.84184232860527, 15.21400090165562, 10.99874311453888, 4.49926609396424, -10.83001749139710, -11.55209632246687, 15.13810758181459, -21.75267417942349, 16.90120918548436, -21.75267417942350, 15.13810758181459, -11.55209632246690, -10.83001749139710, 4.49926609396421, 10.99874311453890, 15.21400090165560, -14.84184232860527, 13.4162690310 [...]
+-9.68763086395668, -3.69628433532419, 10.72315107642355, -20.42419458567318, 10.38855655064239, -9.27745566783213, 7.17625947372866, -16.36206607921333, 15.25670614564248, -15.35119031903566, -14.55674583527383, -4.82652162449667, 13.53133541180172, 10.39575816575687, -14.42644608290790, 23.36996810296474, -17.44104200716280, 23.36996810296476, -14.42644608290790, 10.39575816575689, 13.53133541180172, -4.82652162449663, -14.55674583527385, -15.35119031903562, 15.25670614564248, -16.36206 [...]
+-12.45620149356896, -8.29343703545534, 2.32024690570294, 15.40023512824363, -17.26994725399242, 21.60191794085293, -17.92282969661948, 20.16902887979355, -7.17563790665730, -3.81865461592451, 3.02751918142442, 0.06615530793346, -4.81756778255395, 10.08350679880326, 1.86024383950385, -11.61219473374567, 13.09574137559412, -11.61219473374569, 1.86024383950386, 10.08350679880324, -4.81756778255394, 0.06615530793345, 3.02751918142442, -3.81865461592453, -7.17563790665730, 20.16902887979354,  [...]
+5.32361092336852, -0.47019540940993, -1.44242649539944, 4.10613957511594, 2.13139057311918, -3.05967938904055, 4.09389969418738, 1.23791304497919, -2.28983573947654, 4.38784892143574, 7.62502645014687, 1.21125734087035, -5.06320005706919, -4.47283498651040, 4.62398634845693, -7.02211051583926, 3.62087113939661, -7.02211051583926, 4.62398634845693, -4.47283498651041, -5.06320005706919, 1.21125734087034, 7.62502645014687, 4.38784892143574, -2.28983573947654, 1.23791304497919, 4.09389969418 [...]
+4.92066813754002, 5.51975188293383, -2.93965769297090, -4.07428283832945, 3.54742348392516, -5.02269022542451, 3.35262285161065, -5.48540227620296, 0.86713676343437, 3.19796544847629, -1.94532799713086, 0.49112823698798, 1.68588189370516, -4.67980985992651, -0.26059205389729, 3.57994641004560, -3.84127625137092, 3.57994641004561, -0.26059205389730, -4.67980985992650, 1.68588189370516, 0.49112823698798, -1.94532799713086, 3.19796544847629, 0.86713676343437, -5.48540227620296, 3.3526228516 [...]
+11.16511448172167, 8.40530054448300, -2.77586351131454, -12.07612271098640, 10.65302419516718, -13.49548215942202, 9.98155343394424, -14.46063067051363, 4.69780037422499, 3.97630120805047, -4.14079235738720, 0.61207242504217, 3.59163280328208, -7.09903648519554, -3.80047081568363, 11.76804739685045, -12.18188707468130, 11.76804739685046, -3.80047081568364, -7.09903648519552, 3.59163280328208, 0.61207242504218, -4.14079235738720, 3.97630120805048, 4.69780037422499, -14.46063067051362, 9.9 [...]
+19.44947988481077, 11.92253329073072, -10.62103338875556, -0.26909689186569, 11.67628835278840, -17.25200791284725, 15.44537441066380, -9.38240618086483, -3.54282016758553, 16.00558051051717, 9.17436574125010, 3.30080173896679, -4.94102185922896, -20.09332829180408, 10.67583589184631, -7.71665797477029, 0.88943208222467, -7.71665797477029, 10.67583589184630, -20.09332829180409, -4.94102185922896, 3.30080173896676, 9.17436574125011, 16.00558051051717, -3.54282016758553, -9.38240618086482, [...]
+-2.44904659860173, -6.82227394971930, 1.54796449972136, 15.48020809927954, -15.12140150599235, 19.06280217871900, -15.55468279896989, 18.85927592937489, -7.60344489036771, 0.49467443465232, 9.16792202661572, 1.77106791118175, -10.13486837000626, 7.19791631287657, 0.33897805707351, -10.49350570543157, 9.24147827101776, -10.49350570543158, 0.33897805707352, 7.19791631287655, -10.13486837000626, 1.77106791118174, 9.16792202661572, 0.49467443465230, -7.60344489036771, 18.85927592937487, -15. [...]
+5.37550997174761, 9.51767259428679, -1.29128777154535, -20.23762748782687, 19.61306488869716, -24.00322207267388, 19.70628696133401, -24.36451926770317, 10.55294778653600, 0.25896023409944, -10.08384394894594, -1.78947911768990, 11.62624708592024, -9.31311919808895, -2.61233300118125, 15.14900840061247, -14.39163406362221, 15.14900840061248, -2.61233300118126, -9.31311919808894, 11.62624708592024, -1.78947911768989, -10.08384394894594, 0.25896023409946, 10.55294778653600, -24.36451926770 [...]
+-2.44904659860173, -6.82227394971931, 1.54796449972136, 15.48020809927955, -15.12140150599235, 19.06280217871901, -15.55468279896990, 18.85927592937490, -7.60344489036772, 0.49467443465232, 9.16792202661572, 1.77106791118176, -10.13486837000627, 7.19791631287657, 0.33897805707352, -10.49350570543158, 9.24147827101777, -10.49350570543159, 0.33897805707353, 7.19791631287655, -10.13486837000627, 1.77106791118175, 9.16792202661573, 0.49467443465231, -7.60344489036772, 18.85927592937489, -15. [...]
+19.44947988481077, 11.92253329073072, -10.62103338875555, -0.26909689186570, 11.67628835278841, -17.25200791284725, 15.44537441066380, -9.38240618086484, -3.54282016758552, 16.00558051051717, 9.17436574125010, 3.30080173896679, -4.94102185922895, -20.09332829180408, 10.67583589184630, -7.71665797477028, 0.88943208222466, -7.71665797477027, 10.67583589184629, -20.09332829180408, -4.94102185922896, 3.30080173896676, 9.17436574125011, 16.00558051051716, -3.54282016758552, -9.38240618086483, [...]
+11.16511448172167, 8.40530054448300, -2.77586351131454, -12.07612271098638, 10.65302419516716, -13.49548215942200, 9.98155343394422, -14.46063067051361, 4.69780037422498, 3.97630120805047, -4.14079235738719, 0.61207242504218, 3.59163280328207, -7.09903648519554, -3.80047081568362, 11.76804739685043, -12.18188707468129, 11.76804739685045, -3.80047081568363, -7.09903648519552, 3.59163280328207, 0.61207242504218, -4.14079235738719, 3.97630120805049, 4.69780037422498, -14.46063067051360, 9.9 [...]
+4.92066813754004, 5.51975188293384, -2.93965769297090, -4.07428283832946, 3.54742348392517, -5.02269022542453, 3.35262285161066, -5.48540227620297, 0.86713676343437, 3.19796544847630, -1.94532799713086, 0.49112823698799, 1.68588189370516, -4.67980985992652, -0.26059205389729, 3.57994641004561, -3.84127625137092, 3.57994641004561, -0.26059205389729, -4.67980985992651, 1.68588189370516, 0.49112823698798, -1.94532799713086, 3.19796544847630, 0.86713676343437, -5.48540227620297, 3.3526228516 [...]
+5.32361092336853, -0.47019540940993, -1.44242649539945, 4.10613957511596, 2.13139057311916, -3.05967938904054, 4.09389969418737, 1.23791304497921, -2.28983573947656, 4.38784892143575, 7.62502645014688, 1.21125734087036, -5.06320005706920, -4.47283498651041, 4.62398634845694, -7.02211051583928, 3.62087113939662, -7.02211051583928, 4.62398634845694, -4.47283498651041, -5.06320005706921, 1.21125734087035, 7.62502645014688, 4.38784892143575, -2.28983573947656, 1.23791304497921, 4.09389969418 [...]
+-12.45620149356896, -8.29343703545534, 2.32024690570294, 15.40023512824363, -17.26994725399242, 21.60191794085293, -17.92282969661948, 20.16902887979355, -7.17563790665730, -3.81865461592451, 3.02751918142442, 0.06615530793346, -4.81756778255395, 10.08350679880326, 1.86024383950385, -11.61219473374567, 13.09574137559412, -11.61219473374569, 1.86024383950386, 10.08350679880324, -4.81756778255394, 0.06615530793345, 3.02751918142442, -3.81865461592453, -7.17563790665730, 20.16902887979354,  [...]
+-9.68763086395667, -3.69628433532419, 10.72315107642354, -20.42419458567316, 10.38855655064238, -9.27745566783211, 7.17625947372864, -16.36206607921331, 15.25670614564247, -15.35119031903565, -14.55674583527383, -4.82652162449667, 13.53133541180171, 10.39575816575686, -14.42644608290789, 23.36996810296473, -17.44104200716279, 23.36996810296474, -14.42644608290790, 10.39575816575689, 13.53133541180171, -4.82652162449663, -14.55674583527384, -15.35119031903562, 15.25670614564247, -16.36206 [...]
+9.61899681729205, 5.12866081721604, -11.88962795229987, 17.74929701723685, -8.69295715527054, 6.51729390275671, -5.50918272627418, 13.41626903101449, -14.84184232860526, 15.21400090165563, 10.99874311453888, 4.49926609396424, -10.83001749139710, -11.55209632246688, 15.13810758181459, -21.75267417942349, 16.90120918548436, -21.75267417942349, 15.13810758181460, -11.55209632246691, -10.83001749139710, 4.49926609396421, 10.99874311453890, 15.21400090165561, -14.84184232860526, 13.4162690310 [...]
+-8.66039296471438, -2.96954906422847, 10.14128557597927, -20.29030282295904, 10.84055647310283, -9.92851361203805, 7.80619757858033, -16.71852241516467, 15.10298562840200, -14.47961776299701, -13.87617591999616, -4.67580807253828, 13.21833234722022, 9.30206757061810, -13.94410614974063, 22.94708622520248, -17.44077149295899, 22.94708622520249, -13.94410614974064, 9.30206757061812, 13.21833234722022, -4.67580807253824, -13.87617591999617, -14.47961776299698, 15.10298562840200, -16.7185224 [...]
+-9.54005325319679, -7.10361430488068, 1.33251664571806, 15.60075189522547, -15.97767599794256, 19.95021401225560, -16.32767789148512, 19.48394436078266, -7.70633765403089, -1.49273370290946, 4.60542779514991, 0.84806640285395, -6.24186824394433, 8.08148746552660, 2.38303987364995, -12.04803060548265, 12.40493692891413, -12.04803060548267, 2.38303987364996, 8.08148746552659, -6.24186824394433, 0.84806640285394, 4.60542779514991, -1.49273370290948, -7.70633765403089, 19.48394436078264, -16 [...]
+10.22014646958447, 1.99349399911022, -3.91497110886474, 5.93656648448172, 4.07101556772496, -5.70733238978333, 7.08884593586691, 0.66418468077287, -3.54869013835499, 8.84233961188577, 12.14677171858191, 2.14642400909641, -7.59984914267999, -9.55874327458129, 7.50346179729004, -10.43566209914296, 4.52600965662156, -10.43566209914296, 7.50346179729004, -9.55874327458130, -7.59984914268000, 2.14642400909640, 12.14677171858192, 8.84233961188576, -3.54869013835499, 0.66418468077286, 7.0888459 [...]
+-2.72700060220858, 0.41568024652629, 2.64606645147221, -8.91749093368438, 1.99544708398240, -2.51478954068493, 0.28162144378409, -6.71128709046097, 5.17322923887540, -6.43617677610981, -8.28608726491123, -2.57838013691621, 7.45663395243100, 2.97125415713897, -4.12170476847627, 8.23986341593006, -4.03974362747456, 8.23986341593007, -4.12170476847627, 2.97125415713898, 7.45663395243101, -2.57838013691620, -8.28608726491123, -6.43617677610980, 5.17322923887540, -6.71128709046097, 0.28162144 [...]
+1.73128535207734, 4.42277821365558, -0.77671619741817, -8.00617484900773, 3.01859078190890, -4.02295223577496, 1.41866906333621, -7.07579076558004, 2.92575557929785, -0.67501814145510, -7.53648180148717, -0.26370581458194, 4.85256268243735, -0.30993684235977, -4.40351530596536, 9.65216259465132, -7.35649739987149, 9.65216259465133, -4.40351530596536, -0.30993684235976, 4.85256268243735, -0.26370581458193, -7.53648180148718, -0.67501814145509, 2.92575557929785, -7.07579076558004, 1.418669 [...]
+12.60915579383108, 5.89410801419846, -4.55319083557949, -2.51570130621528, 10.00099644272481, -13.34016357306758, 12.40542650866909, -8.39379145591341, 0.21807816471698, 8.23340961328307, 6.51312587154955, 1.54976024889811, -2.94150737583813, -11.45302659170248, 4.68195727310600, -2.13483830382406, -2.42393281046170, -2.13483830382405, 4.68195727310600, -11.45302659170248, -2.94150737583813, 1.54976024889810, 6.51312587154956, 8.23340961328307, 0.21807816471698, -8.39379145591341, 12.405 [...]
+-5.72596346153869, -5.28154588262917, -0.75446720430749, 16.17403127958276, -14.67097021687279, 17.62183116637570, -14.36465810779321, 18.59598414416564, -8.96596902191131, 1.47145989350063, 6.42403852147234, 1.49826720899707, -7.47724312784464, 4.61026552364061, 4.66743563953285, -14.07410129711224, 13.32400037935799, -14.07410129711225, 4.66743563953286, 4.61026552364059, -7.47724312784464, 1.49826720899705, 6.42403852147235, 1.47145989350061, -8.96596902191131, 18.59598414416563, -14. [...]
+2.61046301711099, 3.04480719285477, 3.17638308273626, -16.38705649694589, 13.78263079920826, -15.56852546238396, 12.95463294889951, -17.55609336202338, 10.28559907526657, -4.09513847072714, -6.95550444596427, -2.01121862072098, 7.89643514317116, -1.36745186073812, -6.91442943777619, 15.64257496744378, -14.35039247887897, 15.64257496744379, -6.91442943777620, -1.36745186073811, 7.89643514317116, -2.01121862072096, -6.95550444596428, -4.09513847072712, 10.28559907526657, -17.55609336202337 [...]
+-5.49443808778003, -5.12499614470874, -1.09825425376247, 16.95523752445051, -14.80287658417080, 17.76771674706712, -14.29997403527971, 19.05977187240720, -9.32710389012735, 2.03033008134397, 7.25788878267192, 1.62570655537498, -7.98948037773656, 4.10075074825108, 5.19353659047517, -14.95262541755742, 13.81324555487177, -14.95262541755743, 5.19353659047518, 4.10075074825106, -7.98948037773655, 1.62570655537496, 7.25788878267192, 2.03033008134395, -9.32710389012735, 19.05977187240719, -14. [...]
+13.57871740705889, 5.50136926887857, -4.72895145625602, -1.05768680610595, 10.00301995124348, -13.18620819678791, 12.70718812779511, -7.30793112334191, -0.59322683729437, 9.47718886177679, 8.34565770450197, 2.10885500022443, -4.58192509635756, -11.97401378825268, 5.30171643610926, -3.59524594324400, -1.88304543904609, -3.59524594324400, 5.30171643610926, -11.97401378825268, -4.58192509635757, 2.10885500022442, 8.34565770450198, 9.47718886177679, -0.59322683729437, -7.30793112334191, 12.7 [...]
+1.78273129013545, 3.82633907751006, -1.55812050662266, -4.07085358040659, 1.91708787608348, -2.58728532145839, 1.15842446413442, -4.14583615473415, 1.23684826993737, 1.00436308239746, -3.73954861017543, 0.15046677467401, 2.45709331336938, -1.57854587305165, -2.00738803692525, 5.19404456177215, -4.44651505319355, 5.19404456177216, -2.00738803692525, -1.57854587305165, 2.45709331336938, 0.15046677467401, -3.73954861017543, 1.00436308239746, 1.23684826993737, -4.14583615473415, 1.1584244641 [...]
+-5.49502176637932, -3.81566614536323, 3.39841270997282, -1.62907541680399, -1.88094502706280, 2.72926876259473, -2.75148031195139, 0.77873058470238, 1.77675390966589, -5.65710642821225, -3.61532764366092, -1.51653701745227, 2.67195150372528, 5.49607913167386, -2.36508076036627, 2.32446148837618, 0.23227774478851, 2.32446148837617, -2.36508076036627, 5.49607913167386, 2.67195150372528, -1.51653701745226, -3.61532764366092, -5.65710642821225, 1.77675390966589, 0.77873058470238, -2.75148031 [...]
+-13.01757394463585, -5.94707066894136, 4.71363593681632, 0.12258279889193, -7.08797623258933, 9.08534712332158, -8.76662365424324, 4.93409103891055, 1.27547062793832, -9.78625487789812, -7.27949473660445, -2.72026247359259, 5.15675379714660, 10.05373766180936, -2.73709521294255, 1.41005231982265, 3.70456075718666, 1.41005231982264, -2.73709521294255, 10.05373766180936, 5.15675379714660, -2.72026247359258, -7.27949473660445, -9.78625487789812, 1.27547062793832, 4.93409103891055, -8.766623 [...]
+-7.98923425086753, -1.86721702631852, 5.80347661652668, -12.20102789978221, 0.48443538199963, 0.63159238416105, -3.08423889386642, -6.87720017336102, 7.48612002563125, -11.03643130953561, -14.15967016416117, -3.00296705199610, 9.94368055250728, 9.96880160926345, -10.89565150789557, 16.86176188057156, -10.25902016179875, 16.86176188057157, -10.89565150789558, 9.96880160926347, 9.94368055250728, -3.00296705199607, -14.15967016416117, -11.03643130953559, 7.48612002563125, -6.87720017336101, [...]
+9.76213378709615, 7.63063362031139, -6.13765678528965, -3.94012618663504, 9.66301782937902, -13.93200503573686, 11.92610582614736, -9.57380736569912, -0.23254866300656, 7.63663890459861, 1.74730858090412, 0.95291868699360, 0.67369639912221, -12.25161251887637, 6.53269983285838, -2.33197675407964, -0.41607591876273, -2.33197675407963, 6.53269983285837, -12.25161251887637, 0.67369639912221, 0.95291868699359, 1.74730858090413, 7.63663890459861, -0.23254866300656, -9.57380736569911, 11.92610 [...]
+-12.92227031702632, -9.52346686232382, 7.03921162188167, 4.79043788749284, -13.12733241085901, 17.76081151462223, -15.93585792875255, 12.10719822639876, -0.43197686918712, -10.38299026427096, -3.81510704769824, -1.61934412884366, 0.23097956071698, 15.53837091368543, -7.00812190783967, 2.14786524468674, 2.43974572557896, 2.14786524468673, -7.00812190783966, 15.53837091368543, 0.23097956071698, -1.61934412884364, -3.81510704769825, -10.38299026427096, -0.43197686918712, 12.10719822639875,  [...]
+9.76213378709616, 7.63063362031139, -6.13765678528965, -3.94012618663505, 9.66301782937903, -13.93200503573688, 11.92610582614737, -9.57380736569913, -0.23254866300656, 7.63663890459861, 1.74730858090412, 0.95291868699360, 0.67369639912221, -12.25161251887637, 6.53269983285838, -2.33197675407964, -0.41607591876274, -2.33197675407963, 6.53269983285837, -12.25161251887638, 0.67369639912221, 0.95291868699359, 1.74730858090413, 7.63663890459861, -0.23254866300656, -9.57380736569912, 11.92610 [...]
+-7.98923425086754, -1.86721702631853, 5.80347661652668, -12.20102789978220, 0.48443538199962, 0.63159238416106, -3.08423889386643, -6.87720017336101, 7.48612002563125, -11.03643130953561, -14.15967016416117, -3.00296705199610, 9.94368055250728, 9.96880160926345, -10.89565150789557, 16.86176188057156, -10.25902016179875, 16.86176188057156, -10.89565150789558, 9.96880160926347, 9.94368055250728, -3.00296705199607, -14.15967016416117, -11.03643130953559, 7.48612002563125, -6.87720017336100, [...]
+-13.01757394463585, -5.94707066894136, 4.71363593681632, 0.12258279889192, -7.08797623258931, 9.08534712332156, -8.76662365424323, 4.93409103891054, 1.27547062793833, -9.78625487789812, -7.27949473660445, -2.72026247359259, 5.15675379714660, 10.05373766180935, -2.73709521294255, 1.41005231982265, 3.70456075718665, 1.41005231982265, -2.73709521294255, 10.05373766180935, 5.15675379714661, -2.72026247359258, -7.27949473660445, -9.78625487789812, 1.27547062793833, 4.93409103891053, -8.766623 [...]
+-5.49502176637933, -3.81566614536324, 3.39841270997283, -1.62907541680399, -1.88094502706280, 2.72926876259473, -2.75148031195140, 0.77873058470238, 1.77675390966589, -5.65710642821226, -3.61532764366093, -1.51653701745227, 2.67195150372528, 5.49607913167387, -2.36508076036628, 2.32446148837618, 0.23227774478850, 2.32446148837618, -2.36508076036628, 5.49607913167387, 2.67195150372529, -1.51653701745226, -3.61532764366093, -5.65710642821226, 1.77675390966589, 0.77873058470238, -2.75148031 [...]
+1.78273129013546, 3.82633907751006, -1.55812050662266, -4.07085358040660, 1.91708787608349, -2.58728532145841, 1.15842446413444, -4.14583615473417, 1.23684826993738, 1.00436308239746, -3.73954861017543, 0.15046677467401, 2.45709331336939, -1.57854587305166, -2.00738803692525, 5.19404456177216, -4.44651505319356, 5.19404456177216, -2.00738803692525, -1.57854587305165, 2.45709331336939, 0.15046677467401, -3.73954861017543, 1.00436308239746, 1.23684826993738, -4.14583615473416, 1.1584244641 [...]
+13.57871740705889, 5.50136926887857, -4.72895145625602, -1.05768680610595, 10.00301995124348, -13.18620819678791, 12.70718812779511, -7.30793112334191, -0.59322683729437, 9.47718886177679, 8.34565770450197, 2.10885500022443, -4.58192509635756, -11.97401378825268, 5.30171643610926, -3.59524594324400, -1.88304543904609, -3.59524594324400, 5.30171643610926, -11.97401378825268, -4.58192509635757, 2.10885500022442, 8.34565770450198, 9.47718886177679, -0.59322683729437, -7.30793112334191, 12.7 [...]
+-5.49443808778003, -5.12499614470874, -1.09825425376247, 16.95523752445050, -14.80287658417078, 17.76771674706710, -14.29997403527969, 19.05977187240719, -9.32710389012735, 2.03033008134397, 7.25788878267192, 1.62570655537498, -7.98948037773655, 4.10075074825108, 5.19353659047517, -14.95262541755741, 13.81324555487177, -14.95262541755743, 5.19353659047518, 4.10075074825106, -7.98948037773655, 1.62570655537496, 7.25788878267192, 2.03033008134395, -9.32710389012735, 19.05977187240717, -14. [...]
+2.61046301711098, 3.04480719285477, 3.17638308273626, -16.38705649694589, 13.78263079920825, -15.56852546238396, 12.95463294889951, -17.55609336202338, 10.28559907526657, -4.09513847072714, -6.95550444596428, -2.01121862072098, 7.89643514317117, -1.36745186073812, -6.91442943777620, 15.64257496744379, -14.35039247887897, 15.64257496744380, -6.91442943777620, -1.36745186073810, 7.89643514317116, -2.01121862072096, -6.95550444596429, -4.09513847072712, 10.28559907526657, -17.55609336202336 [...]
+-5.72596346153870, -5.28154588262918, -0.75446720430749, 16.17403127958276, -14.67097021687280, 17.62183116637571, -14.36465810779321, 18.59598414416566, -8.96596902191131, 1.47145989350063, 6.42403852147235, 1.49826720899707, -7.47724312784464, 4.61026552364061, 4.66743563953286, -14.07410129711225, 13.32400037935800, -14.07410129711226, 4.66743563953287, 4.61026552364060, -7.47724312784464, 1.49826720899705, 6.42403852147235, 1.47145989350061, -8.96596902191131, 18.59598414416564, -14. [...]
+12.60915579383108, 5.89410801419845, -4.55319083557949, -2.51570130621528, 10.00099644272481, -13.34016357306758, 12.40542650866908, -8.39379145591341, 0.21807816471697, 8.23340961328307, 6.51312587154955, 1.54976024889811, -2.94150737583813, -11.45302659170247, 4.68195727310600, -2.13483830382406, -2.42393281046170, -2.13483830382405, 4.68195727310600, -11.45302659170247, -2.94150737583813, 1.54976024889810, 6.51312587154956, 8.23340961328307, 0.21807816471697, -8.39379145591340, 12.405 [...]
+1.73128535207734, 4.42277821365558, -0.77671619741817, -8.00617484900773, 3.01859078190890, -4.02295223577496, 1.41866906333621, -7.07579076558004, 2.92575557929785, -0.67501814145510, -7.53648180148717, -0.26370581458194, 4.85256268243735, -0.30993684235978, -4.40351530596536, 9.65216259465132, -7.35649739987149, 9.65216259465133, -4.40351530596536, -0.30993684235977, 4.85256268243735, -0.26370581458193, -7.53648180148717, -0.67501814145509, 2.92575557929785, -7.07579076558004, 1.418669 [...]
+-6.26428955477971, -3.97118704398744, 3.19273713259140, -0.95599842323359, -2.93780486306583, 3.95657463979202, -4.02578325969409, 1.97483570549549, 0.88119810453719, -5.36737536199558, -4.47248804747262, -1.12836861956163, 2.40160708703872, 6.28477134161354, -2.61729237165413, 2.49243503534318, 0.28709273185579, 2.49243503534318, -2.61729237165413, 6.28477134161355, 2.40160708703872, -1.12836861956162, -4.47248804747263, -5.36737536199557, 0.88119810453719, 1.97483570549549, -4.02578325 [...]
+-5.55618265959335, -1.35137419559986, 2.12013235664412, -3.15131974934695, -1.53800290925023, 1.86268707389469, -2.56934693631093, -1.08941125013904, 2.37962023586022, -5.55858881046798, -5.43301166326226, -1.92777660045593, 4.60064068752284, 4.16196925523274, -2.31965183123754, 3.60922825815115, -0.42372040103379, 3.60922825815115, -2.31965183123754, 4.16196925523274, 4.60064068752284, -1.92777660045593, -5.43301166326226, -5.55858881046797, 2.37962023586022, -1.08941125013904, -2.56934 [...]
+4.28747341136722, 3.75145187207707, -0.99316777851351, -6.14302836100368, 4.19626034990540, -5.26910840168975, 3.38280492003585, -6.39072939183548, 2.11759217482207, 1.32143256889645, -3.62306864812320, 0.30210410143904, 2.36784113720966, -2.26698240951613, -2.55138128407136, 6.55184834088414, -6.04350466201749, 6.55184834088415, -2.55138128407136, -2.26698240951613, 2.36784113720966, 0.30210410143904, -3.62306864812320, 1.32143256889645, 2.11759217482207, -6.39072939183547, 3.3828049200 [...]
+5.39701483342643, 1.41582881334481, -3.26218528381419, 5.33403134523670, 1.53666102128426, -2.71124045248661, 3.79129082238306, 1.68130362049398, -3.20537853992316, 5.89762178955420, 7.99134344482788, 1.42924096410416, -5.15372244076487, -6.14113364751397, 5.78594545948303, -8.13014598865718, 4.32275541708896, -8.13014598865718, 5.78594545948304, -6.14113364751398, -5.15372244076487, 1.42924096410415, 7.99134344482788, 5.89762178955419, -3.20537853992316, 1.68130362049397, 3.791290822383 [...]
+-5.82311022995469, -2.05863138521962, 3.20276052803462, -3.00663510117184, -3.26767841865508, 4.85749834936510, -5.37571393562895, 0.75626586966107, 2.11217673413559, -5.49551754796539, -6.45318874490494, -1.19163786373660, 3.81135348684982, 6.49279975909238, -5.12278006797189, 6.01038894031824, -2.59884219320034, 6.01038894031823, -5.12278006797189, 6.49279975909239, 3.81135348684982, -1.19163786373659, -6.45318874490495, -5.49551754796538, 2.11217673413559, 0.75626586966107, -5.3757139 [...]
+6.24752505175793, 1.51298934771288, -3.26856274656056, 5.11436420992590, 2.02319259905925, -3.26545068248241, 4.30111210707947, 1.33444646564807, -3.15935375680643, 6.29114428545988, 8.35295215016554, 1.54626267562064, -5.39706441813527, -6.57897419473100, 5.84194841954571, -8.13187192632632, 4.09565769885503, -8.13187192632632, 5.84194841954571, -6.57897419473101, -5.39706441813527, 1.54626267562063, 8.35295215016555, 6.29114428545987, -3.15935375680643, 1.33444646564807, 4.301112107079 [...]
+5.27079226569002, 4.97233787026290, -2.01927601900401, -5.58891864591323, 4.43515112001898, -5.73134033347546, 3.88049807190540, -6.52320885785919, 1.71275615695758, 2.62685604630642, -2.80437300865437, 0.60051225570305, 1.85841519333930, -3.62590151731327, -1.95136347035007, 5.94155412955289, -6.00460351069658, 5.94155412955290, -1.95136347035008, -3.62590151731326, 1.85841519333930, 0.60051225570305, -2.80437300865437, 2.62685604630643, 1.71275615695758, -6.52320885785918, 3.8804980719 [...]
+-2.15727765389927, -0.74456611101775, 1.60382194426131, -2.95104808572995, 0.07872642086302, 0.02810955042859, -0.63611974628204, -1.73919434898226, 2.01214593617921, -3.27214500162122, -3.18048606226198, -1.18618364737300, 2.89970888323742, 2.07807748249136, -1.68681554667902, 2.78993058088680, -0.96104413201117, 2.78993058088680, -1.68681554667902, 2.07807748249136, 2.89970888323742, -1.18618364737299, -3.18048606226199, -3.27214500162121, 2.01214593617921, -1.73919434898226, -0.636119 [...]
+-3.23475436001362, -2.09145744791353, 0.57266793386382, 3.08891594387117, -2.66573074772091, 3.46968846500064, -2.53890182915785, 3.72373783622912, -1.31672171093509, -0.84414203341168, 0.65721185685545, 0.04910678044018, -0.99810235576164, 2.13269965524535, 0.53038519561303, -2.26459626133156, 2.32284374374864, -2.26459626133157, 0.53038519561304, 2.13269965524535, -0.99810235576164, 0.04910678044018, 0.65721185685545, -0.84414203341168, -1.31672171093509, 3.72373783622911, -2.538901829 [...]
+-4.82539420720762, -5.07318501768494, 2.07372354321970, 5.18438946919297, -3.78429252459930, 5.19909080783247, -3.33087093161850, 6.13113382583172, -1.67102662692397, -2.16894885184669, 2.59090571534986, -0.18791296410164, -2.28623125146986, 3.94917886979350, 0.99930933039009, -4.44182794880375, 4.21982875721568, -4.44182794880376, 0.99930933039009, 3.94917886979350, -2.28623125146986, -0.18791296410164, 2.59090571534986, -2.16894885184669, -1.67102662692397, 6.13113382583172, -3.3308709 [...]
+-10.96405873216306, -5.49150552325290, 3.82624282372670, 1.96558659778117, -6.56938079890574, 8.60419408168631, -7.70917449393445, 5.74806470570420, 0.28145933895284, -7.41150445225817, -4.40082017581657, -1.92997661116153, 2.97157764512724, 8.27658399093626, -1.66844771288541, -0.48083403447281, 4.01331228203412, -0.48083403447281, -1.66844771288540, 8.27658399093626, 2.97157764512724, -1.92997661116152, -4.40082017581657, -7.41150445225817, 0.28145933895284, 5.74806470570420, -7.709174 [...]
+1.58357489680906, 1.86743793574567, 0.89650211298442, -7.60642093095642, 4.67038737737714, -5.32183227016878, 3.65505184709454, -7.24782915483370, 3.91352879545471, -1.64811004903694, -4.90619395555924, -0.56115910558878, 3.74593963613661, 0.29352325446484, -4.30049041083907, 8.81461989805375, -7.49002506695657, 8.81461989805376, -4.30049041083908, 0.29352325446485, 3.74593963613661, -0.56115910558877, -4.90619395555925, -1.64811004903693, 3.91352879545471, -7.24782915483369, 3.655051847 [...]
+-3.29887958406140, -3.18181660143524, -0.72165979302801, 9.07920091694035, -5.60220427104272, 6.38919416810959, -4.30789185138654, 8.79189173837027, -4.62369911664525, 1.06709167117830, 5.22579145003335, 0.43657195186996, -4.04084593620938, 0.52054426713421, 5.22801827763571, -10.43601695204709, 9.19082626268238, -10.43601695204710, 5.22801827763572, 0.52054426713420, -4.04084593620938, 0.43657195186995, 5.22579145003335, 1.06709167117829, -4.62369911664525, 8.79189173837026, -4.30789185 [...]
+1.58357489680906, 1.86743793574567, 0.89650211298442, -7.60642093095642, 4.67038737737714, -5.32183227016878, 3.65505184709454, -7.24782915483370, 3.91352879545471, -1.64811004903694, -4.90619395555925, -0.56115910558878, 3.74593963613661, 0.29352325446484, -4.30049041083907, 8.81461989805375, -7.49002506695657, 8.81461989805376, -4.30049041083908, 0.29352325446485, 3.74593963613661, -0.56115910558877, -4.90619395555925, -1.64811004903693, 3.91352879545471, -7.24782915483369, 3.655051847 [...]
+-10.96405873216306, -5.49150552325290, 3.82624282372670, 1.96558659778118, -6.56938079890574, 8.60419408168631, -7.70917449393445, 5.74806470570420, 0.28145933895284, -7.41150445225816, -4.40082017581657, -1.92997661116153, 2.97157764512724, 8.27658399093626, -1.66844771288540, -0.48083403447281, 4.01331228203412, -0.48083403447282, -1.66844771288540, 8.27658399093626, 2.97157764512724, -1.92997661116152, -4.40082017581657, -7.41150445225817, 0.28145933895284, 5.74806470570420, -7.709174 [...]
+-4.82539420720762, -5.07318501768494, 2.07372354321971, 5.18438946919297, -3.78429252459930, 5.19909080783247, -3.33087093161850, 6.13113382583172, -1.67102662692397, -2.16894885184669, 2.59090571534986, -0.18791296410164, -2.28623125146985, 3.94917886979350, 0.99930933039008, -4.44182794880374, 4.21982875721567, -4.44182794880375, 0.99930933039009, 3.94917886979350, -2.28623125146985, -0.18791296410164, 2.59090571534986, -2.16894885184670, -1.67102662692397, 6.13113382583171, -3.3308709 [...]
+-3.23475436001362, -2.09145744791353, 0.57266793386382, 3.08891594387117, -2.66573074772091, 3.46968846500065, -2.53890182915786, 3.72373783622912, -1.31672171093510, -0.84414203341168, 0.65721185685545, 0.04910678044018, -0.99810235576164, 2.13269965524536, 0.53038519561303, -2.26459626133157, 2.32284374374865, -2.26459626133157, 0.53038519561304, 2.13269965524535, -0.99810235576164, 0.04910678044018, 0.65721185685545, -0.84414203341168, -1.31672171093510, 3.72373783622912, -2.538901829 [...]
+-2.15727765389928, -0.74456611101775, 1.60382194426131, -2.95104808572995, 0.07872642086302, 0.02810955042859, -0.63611974628204, -1.73919434898226, 2.01214593617922, -3.27214500162122, -3.18048606226199, -1.18618364737300, 2.89970888323742, 2.07807748249136, -1.68681554667902, 2.78993058088681, -0.96104413201118, 2.78993058088681, -1.68681554667902, 2.07807748249137, 2.89970888323742, -1.18618364737299, -3.18048606226199, -3.27214500162122, 2.01214593617922, -1.73919434898226, -0.636119 [...]
+5.27079226569002, 4.97233787026290, -2.01927601900401, -5.58891864591323, 4.43515112001898, -5.73134033347546, 3.88049807190540, -6.52320885785919, 1.71275615695758, 2.62685604630642, -2.80437300865437, 0.60051225570305, 1.85841519333930, -3.62590151731327, -1.95136347035007, 5.94155412955289, -6.00460351069658, 5.94155412955290, -1.95136347035008, -3.62590151731326, 1.85841519333930, 0.60051225570305, -2.80437300865437, 2.62685604630643, 1.71275615695758, -6.52320885785918, 3.8804980719 [...]
+6.24752505175793, 1.51298934771288, -3.26856274656056, 5.11436420992590, 2.02319259905925, -3.26545068248241, 4.30111210707947, 1.33444646564807, -3.15935375680642, 6.29114428545988, 8.35295215016554, 1.54626267562064, -5.39706441813526, -6.57897419473100, 5.84194841954571, -8.13187192632631, 4.09565769885503, -8.13187192632631, 5.84194841954571, -6.57897419473100, -5.39706441813527, 1.54626267562063, 8.35295215016554, 6.29114428545987, -3.15935375680642, 1.33444646564807, 4.301112107079 [...]
+-5.82311022995470, -2.05863138521962, 3.20276052803463, -3.00663510117184, -3.26767841865508, 4.85749834936511, -5.37571393562895, 0.75626586966107, 2.11217673413559, -5.49551754796539, -6.45318874490494, -1.19163786373660, 3.81135348684982, 6.49279975909239, -5.12278006797189, 6.01038894031823, -2.59884219320034, 6.01038894031823, -5.12278006797189, 6.49279975909239, 3.81135348684982, -1.19163786373659, -6.45318874490495, -5.49551754796539, 2.11217673413559, 0.75626586966108, -5.3757139 [...]
+5.39701483342643, 1.41582881334481, -3.26218528381419, 5.33403134523670, 1.53666102128426, -2.71124045248661, 3.79129082238306, 1.68130362049398, -3.20537853992316, 5.89762178955420, 7.99134344482788, 1.42924096410416, -5.15372244076487, -6.14113364751397, 5.78594545948304, -8.13014598865718, 4.32275541708897, -8.13014598865719, 5.78594545948304, -6.14113364751398, -5.15372244076488, 1.42924096410415, 7.99134344482789, 5.89762178955420, -3.20537853992316, 1.68130362049397, 3.791290822383 [...]
+4.28747341136722, 3.75145187207707, -0.99316777851351, -6.14302836100368, 4.19626034990540, -5.26910840168976, 3.38280492003585, -6.39072939183548, 2.11759217482207, 1.32143256889645, -3.62306864812320, 0.30210410143904, 2.36784113720966, -2.26698240951614, -2.55138128407136, 6.55184834088414, -6.04350466201749, 6.55184834088415, -2.55138128407136, -2.26698240951613, 2.36784113720966, 0.30210410143904, -3.62306864812320, 1.32143256889646, 2.11759217482207, -6.39072939183547, 3.3828049200 [...]
+-5.55618265959335, -1.35137419559985, 2.12013235664412, -3.15131974934695, -1.53800290925023, 1.86268707389469, -2.56934693631093, -1.08941125013904, 2.37962023586022, -5.55858881046798, -5.43301166326226, -1.92777660045593, 4.60064068752284, 4.16196925523273, -2.31965183123754, 3.60922825815115, -0.42372040103379, 3.60922825815115, -2.31965183123754, 4.16196925523274, 4.60064068752284, -1.92777660045593, -5.43301166326226, -5.55858881046797, 2.37962023586022, -1.08941125013904, -2.56934 [...]
+-8.04061485937774, -1.97690770444849, 1.00357056324022, 1.65013744503927, -4.63349911093906, 5.48328590532855, -5.09179630348133, 3.43925875142879, -0.19522792824256, -4.41880664574692, -3.62073816758945, -1.26110986965204, 2.43268462834227, 4.86043549424324, -0.82823839280682, 0.13482266086209, 2.28329710556104, 0.13482266086208, -0.82823839280682, 4.86043549424324, 2.43268462834227, -1.26110986965203, -3.62073816758945, -4.41880664574692, -0.19522792824256, 3.43925875142878, -5.0917963 [...]
+-3.71498643311384, -3.73133453905243, 4.00680304613774, -4.04361013697314, -0.31460444516964, 0.95631205842463, -1.63577612251258, -1.20290159740288, 2.60109169463730, -5.69177347099769, -4.76366245248064, -1.45639832329181, 3.30980232396383, 5.31498487748052, -3.33933128477634, 4.37041123049490, -1.51286064307257, 4.37041123049490, -3.33933128477634, 5.31498487748052, 3.30980232396383, -1.45639832329180, -4.76366245248064, -5.69177347099768, 2.60109169463730, -1.20290159740288, -1.63577 [...]
+1.22622910074184, 4.90684354592601, -2.22114768258670, -4.39896014078975, 2.08262190327754, -3.18496771685190, 1.58356913845335, -5.04529036624321, 1.69516723572822, 0.60671384673763, -4.01740001684067, -0.40241907040053, 3.55192426393499, -2.50555708110944, -1.15804266333745, 4.62175344581036, -3.57701160892279, 4.62175344581036, -1.15804266333746, -2.50555708110943, 3.55192426393499, -0.40241907040053, -4.01740001684067, 0.60671384673763, 1.69516723572822, -5.04529036624321, 1.58356913 [...]
+7.45314113785136, 0.40522255590017, -1.77198659016177, 2.81700991377899, 3.20070445159921, -4.15345461968356, 4.76249012110496, 0.09316398232989, -2.30785361326424, 5.76435158044440, 6.95524160412664, 1.94882597453897, -5.48758101702970, -4.88950044182766, 3.24460130567062, -4.56151295032944, 0.84591298513179, -4.56151295032944, 3.24460130567062, -4.88950044182767, -5.48758101702970, 1.94882597453896, 6.95524160412664, 5.76435158044440, -2.30785361326424, 0.09316398232989, 4.762490121104 [...]
+-7.26720076758329, -1.10945138725057, 1.83004958335901, -0.96967204162726, -4.24905200054359, 5.47084029905552, -5.61425779268294, 1.73747118546328, 1.42660056355516, -5.27828638160724, -5.27317776575959, -1.74807270097580, 4.21054331835858, 4.84683462903593, -2.40054580698698, 2.43962993181924, 0.78500494697433, 2.43962993181924, -2.40054580698698, 4.84683462903593, 4.21054331835858, -1.74807270097580, -5.27317776575959, -5.27828638160723, 1.42660056355516, 1.73747118546328, -5.61425779 [...]
+7.65897239092609, 1.10430427319254, -2.35100199933245, 3.10956530285242, 3.13777746695840, -4.19944122367310, 4.79382791045845, 0.10920956890175, -2.56092537099429, 6.35451296569500, 7.06667104647449, 2.13464708292740, -5.68071530815101, -5.34749768372170, 3.37765971926727, -4.64340253443281, 0.75099213839614, -4.64340253443281, 3.37765971926727, -5.34749768372170, -5.68071530815101, 2.13464708292740, 7.06667104647449, 6.35451296569500, -2.56092537099429, 0.10920956890175, 4.793827910458 [...]
+3.34270509708589, 4.94185899547755, -2.02552627641391, -5.15140567689139, 3.42339199605817, -4.68694718604549, 2.97280942206310, -6.08259906422506, 2.02375397050821, 1.29608091681630, -3.06660563763091, -0.29300797036941, 3.16345686806901, -3.61527169774769, -0.93474480447747, 4.54599511924195, -4.00677103713394, 4.54599511924196, -0.93474480447748, -3.61527169774769, 3.16345686806901, -0.29300797036940, -3.06660563763091, 1.29608091681630, 2.02375397050821, -6.08259906422506, 2.97280942 [...]
+-2.13068751521485, -1.27012135093365, 1.80140692197715, -2.50312415926662, -0.24935642556017, 0.52637972828217, -1.07230513610193, -0.94393574078081, 1.44155498234604, -2.88280871715821, -3.30096725318358, -0.63186315705101, 2.00060075280376, 2.95171183532150, -2.32130164798476, 3.22204694387769, -1.51532701290173, 3.22204694387768, -2.32130164798476, 2.95171183532150, 2.00060075280377, -0.63186315705101, -3.30096725318358, -2.88280871715821, 1.44155498234604, -0.94393574078081, -1.07230 [...]
+-2.41884798467293, -2.00323099815562, 0.61653681426137, 2.75860434327362, -1.89165604045305, 2.54631084475110, -1.57350103260289, 2.95552656693729, -0.84190273437647, -0.84675547456158, 1.50170173546028, -0.22922524869928, -0.88062860396701, 1.26777130810009, 1.01851830962833, -2.71592613295942, 2.50838744940899, -2.71592613295942, 1.01851830962833, 1.26777130810009, -0.88062860396701, -0.22922524869928, 1.50170173546028, -0.84675547456158, -0.84190273437647, 2.95552656693729, -1.5735010 [...]
+-4.29714416929057, -3.68116123952021, 0.76966175684023, 6.10399148685355, -4.15726955473463, 5.47498568804641, -3.61566443695119, 6.66813114318867, -2.64438336517075, -0.49197312553651, 2.77734125862660, 0.37806190177288, -2.84429572672004, 2.81861600470916, 1.55112735376195, -5.00933321638367, 4.33957275757153, -5.00933321638368, 1.55112735376195, 2.81861600470916, -2.84429572672004, 0.37806190177288, 2.77734125862660, -0.49197312553651, -2.64438336517075, 6.66813114318866, -3.615664436 [...]
+-8.92885648852067, -6.50769983883173, 4.60325806736433, 1.51964322931869, -4.74544143880712, 6.61445676325357, -5.52064598811949, 4.73744068492496, 0.85834705777994, -7.17416711077466, -2.45874887452121, -1.80106767285323, 1.80204741885860, 7.85706603478577, -1.71612985165883, -0.56931764684859, 3.26632402458718, -0.56931764684859, -1.71612985165883, 7.85706603478577, 1.80204741885861, -1.80106767285322, -2.45874887452121, -7.17416711077466, 0.85834705777994, 4.73744068492496, -5.5206459 [...]
+-0.89388307485568, 2.67422932178827, -0.36075817502235, -5.07189564473924, 1.56428205290770, -1.88291408923940, 0.46309439176973, -4.32759863730048, 2.23579577863941, -1.26762593199865, -5.60031327787208, -0.55354204656053, 4.06163180601371, 0.34033708682896, -2.92995584959217, 6.44440828082145, -4.66025851484356, 6.44440828082145, -2.92995584959217, 0.34033708682896, 4.06163180601371, -0.55354204656053, -5.60031327787208, -1.26762593199864, 2.23579577863941, -4.32759863730048, 0.4630943 [...]
+-0.41027869852248, -3.95139275129727, 0.62757571076232, 6.34155798998998, -2.13433630442006, 2.62498532925978, -0.76437173184659, 5.59990918246036, -2.77635798467388, 0.85629018230064, 6.14350768863857, 0.52478881167432, -4.55373346255246, 0.39931603526425, 3.57212067801172, -7.70088049805676, 5.81727760187053, -7.70088049805676, 3.57212067801172, 0.39931603526424, -4.55373346255246, 0.52478881167431, 6.14350768863857, 0.85629018230063, -2.77635798467388, 5.59990918246035, -0.76437173184 [...]
+-0.89388307485568, 2.67422932178827, -0.36075817502235, -5.07189564473924, 1.56428205290770, -1.88291408923940, 0.46309439176973, -4.32759863730049, 2.23579577863941, -1.26762593199865, -5.60031327787208, -0.55354204656053, 4.06163180601371, 0.34033708682896, -2.92995584959217, 6.44440828082145, -4.66025851484356, 6.44440828082146, -2.92995584959217, 0.34033708682897, 4.06163180601371, -0.55354204656053, -5.60031327787208, -1.26762593199865, 2.23579577863941, -4.32759863730048, 0.4630943 [...]
+-8.92885648852067, -6.50769983883173, 4.60325806736433, 1.51964322931869, -4.74544143880712, 6.61445676325356, -5.52064598811949, 4.73744068492496, 0.85834705777994, -7.17416711077466, -2.45874887452120, -1.80106767285323, 1.80204741885860, 7.85706603478576, -1.71612985165883, -0.56931764684859, 3.26632402458718, -0.56931764684860, -1.71612985165883, 7.85706603478576, 1.80204741885860, -1.80106767285322, -2.45874887452121, -7.17416711077465, 0.85834705777994, 4.73744068492496, -5.5206459 [...]
+-4.29714416929057, -3.68116123952021, 0.76966175684023, 6.10399148685355, -4.15726955473463, 5.47498568804641, -3.61566443695119, 6.66813114318867, -2.64438336517075, -0.49197312553651, 2.77734125862660, 0.37806190177288, -2.84429572672004, 2.81861600470917, 1.55112735376194, -5.00933321638366, 4.33957275757152, -5.00933321638367, 1.55112735376195, 2.81861600470916, -2.84429572672004, 0.37806190177288, 2.77734125862660, -0.49197312553651, -2.64438336517075, 6.66813114318866, -3.615664436 [...]
+-2.41884798467294, -2.00323099815562, 0.61653681426137, 2.75860434327362, -1.89165604045305, 2.54631084475111, -1.57350103260289, 2.95552656693730, -0.84190273437647, -0.84675547456158, 1.50170173546028, -0.22922524869928, -0.88062860396701, 1.26777130810010, 1.01851830962833, -2.71592613295942, 2.50838744940900, -2.71592613295942, 1.01851830962833, 1.26777130810009, -0.88062860396701, -0.22922524869928, 1.50170173546028, -0.84675547456158, -0.84190273437647, 2.95552656693729, -1.5735010 [...]
+-2.13068751521486, -1.27012135093365, 1.80140692197715, -2.50312415926662, -0.24935642556017, 0.52637972828217, -1.07230513610193, -0.94393574078081, 1.44155498234605, -2.88280871715822, -3.30096725318358, -0.63186315705102, 2.00060075280377, 2.95171183532150, -2.32130164798476, 3.22204694387769, -1.51532701290173, 3.22204694387769, -2.32130164798477, 2.95171183532151, 2.00060075280377, -0.63186315705101, -3.30096725318358, -2.88280871715821, 1.44155498234605, -0.94393574078081, -1.07230 [...]
+3.34270509708589, 4.94185899547755, -2.02552627641391, -5.15140567689139, 3.42339199605817, -4.68694718604549, 2.97280942206310, -6.08259906422506, 2.02375397050821, 1.29608091681630, -3.06660563763091, -0.29300797036941, 3.16345686806901, -3.61527169774769, -0.93474480447747, 4.54599511924195, -4.00677103713394, 4.54599511924196, -0.93474480447748, -3.61527169774769, 3.16345686806901, -0.29300797036940, -3.06660563763091, 1.29608091681630, 2.02375397050821, -6.08259906422506, 2.97280942 [...]
+7.65897239092609, 1.10430427319254, -2.35100199933245, 3.10956530285242, 3.13777746695840, -4.19944122367310, 4.79382791045845, 0.10920956890175, -2.56092537099429, 6.35451296569500, 7.06667104647448, 2.13464708292740, -5.68071530815101, -5.34749768372170, 3.37765971926726, -4.64340253443281, 0.75099213839614, -4.64340253443281, 3.37765971926727, -5.34749768372170, -5.68071530815101, 2.13464708292739, 7.06667104647449, 6.35451296569500, -2.56092537099429, 0.10920956890175, 4.793827910458 [...]
+-7.26720076758330, -1.10945138725058, 1.83004958335902, -0.96967204162725, -4.24905200054359, 5.47084029905552, -5.61425779268295, 1.73747118546328, 1.42660056355516, -5.27828638160724, -5.27317776575959, -1.74807270097580, 4.21054331835858, 4.84683462903594, -2.40054580698698, 2.43962993181924, 0.78500494697433, 2.43962993181924, -2.40054580698698, 4.84683462903594, 4.21054331835858, -1.74807270097580, -5.27317776575959, -5.27828638160724, 1.42660056355516, 1.73747118546328, -5.61425779 [...]
+7.45314113785136, 0.40522255590017, -1.77198659016178, 2.81700991377899, 3.20070445159921, -4.15345461968356, 4.76249012110496, 0.09316398232989, -2.30785361326425, 5.76435158044440, 6.95524160412664, 1.94882597453897, -5.48758101702970, -4.88950044182766, 3.24460130567062, -4.56151295032945, 0.84591298513179, -4.56151295032944, 3.24460130567062, -4.88950044182767, -5.48758101702971, 1.94882597453896, 6.95524160412664, 5.76435158044440, -2.30785361326425, 0.09316398232989, 4.762490121104 [...]
+1.22622910074184, 4.90684354592601, -2.22114768258670, -4.39896014078975, 2.08262190327754, -3.18496771685191, 1.58356913845335, -5.04529036624321, 1.69516723572822, 0.60671384673763, -4.01740001684067, -0.40241907040053, 3.55192426393499, -2.50555708110944, -1.15804266333745, 4.62175344581036, -3.57701160892279, 4.62175344581036, -1.15804266333746, -2.50555708110943, 3.55192426393499, -0.40241907040053, -4.01740001684067, 0.60671384673763, 1.69516723572822, -5.04529036624321, 1.58356913 [...]
+-3.71498643311384, -3.73133453905243, 4.00680304613774, -4.04361013697314, -0.31460444516964, 0.95631205842463, -1.63577612251258, -1.20290159740288, 2.60109169463730, -5.69177347099769, -4.76366245248064, -1.45639832329181, 3.30980232396383, 5.31498487748052, -3.33933128477634, 4.37041123049490, -1.51286064307257, 4.37041123049490, -3.33933128477634, 5.31498487748052, 3.30980232396383, -1.45639832329180, -4.76366245248064, -5.69177347099768, 2.60109169463730, -1.20290159740288, -1.63577 [...]
+-3.79930783297356, -4.74120466973677, 5.96217380912226, -7.86867360682909, 1.17445262469222, -0.65309922427472, -0.81769500636621, -4.00686663867494, 4.89201620511217, -8.42438044048848, -7.19377407969774, -2.45860139709839, 5.68968556239167, 6.69569062282034, -5.05281865555310, 7.44243074011496, -3.18644021048831, 7.44243074011496, -5.05281865555310, 6.69569062282035, 5.68968556239167, -2.45860139709838, -7.19377407969774, -8.42438044048846, 4.89201620511217, -4.00686663867494, -0.81769 [...]
+-5.13492229917854, 3.72415982315523, -1.12361844878879, -4.43309125447855, -1.77811463471488, 1.42965393664389, -3.20658268810889, -2.89359175055380, 1.92720616029590, -3.30867749533838, -8.68309760930295, -1.33468782240254, 6.23406695352077, 2.14277793025021, -3.12388851622980, 6.63730420609597, -2.97003136804169, 6.63730420609597, -3.12388851622980, 2.14277793025022, 6.23406695352078, -1.33468782240254, -8.68309760930295, -3.30867749533838, 1.92720616029590, -2.89359175055380, -3.20658 [...]
+12.33434675226444, 3.76311994484352, -0.86308000264393, -8.41323897927573, 11.28944720434947, -13.78276078217295, 11.78269208886619, -11.42876457936816, 3.37123935386327, 4.46766813147399, 1.66318573798221, 0.99289215929101, -0.35562000827801, -7.02682447106838, -1.00274566338866, 5.86867143290008, -8.29708435012838, 5.86867143290009, -1.00274566338866, -7.02682447106838, -0.35562000827802, 0.99289215929101, 1.66318573798221, 4.46766813147400, 3.37123935386327, -11.42876457936815, 11.782 [...]
+-1.54626373495428, 0.30172393368944, -5.35189787389051, 15.52317502695129, -9.44169963223186, 9.87826755304772, -7.19419825406518, 13.57035942066562, -9.18724741244265, 6.30112099262326, 8.74402870775320, 1.86264101273072, -7.22920783296433, -3.45941126215697, 9.46702457281437, -16.99139964151387, 14.04461751323831, -16.99139964151388, 9.46702457281437, -3.45941126215699, -7.22920783296433, 1.86264101273070, 8.74402870775320, 6.30112099262324, -9.18724741244265, 13.57035942066560, -7.194 [...]
+-0.65585322360948, -1.94485035472051, 6.57809911623013, -13.72804010840783, 7.26661468726809, -6.66815536628271, 4.77056565027483, -10.89465587648248, 8.99902496464351, -7.48484793061143, -7.99600849839670, -1.90062496896635, 6.33296761912445, 5.83930809584791, -10.54020557100553, 16.57098060052476, -13.55196079681233, 16.57098060052477, -10.54020557100554, 5.83930809584793, 6.33296761912445, -1.90062496896632, -7.99600849839671, -7.48484793061141, 8.99902496464351, -10.89465587648247, 4 [...]
+-0.40512910569919, 0.04571781720206, -5.14018026746724, 15.39884403242205, -8.77103955029603, 9.18371415135998, -6.43846498497193, 13.26303702527783, -9.08023236965913, 6.66405260929340, 9.64520482846909, 1.88838351188050, -7.60594445656064, -4.09745199037701, 9.81384348472091, -17.47514056202300, 14.14096546676642, -17.47514056202301, 9.81384348472092, -4.09745199037703, -7.60594445656064, 1.88838351188048, 9.64520482846909, 6.66405260929338, -9.08023236965913, 13.26303702527781, -6.438 [...]
+12.72902760738854, 5.24573592337883, -2.53489148489309, -6.36383900286350, 10.63891479360222, -13.23545398077542, 11.56891317022132, -10.24905916842963, 2.05199304856081, 6.56071067211231, 2.90734079112609, 1.76774563166719, -1.78162086533475, -8.22429762215432, -0.21493317508084, 4.56410306635583, -7.89767818707390, 4.56410306635584, -0.21493317508084, -8.22429762215432, -1.78162086533475, 1.76774563166719, 2.90734079112609, 6.56071067211232, 2.05199304856081, -10.24905916842962, 11.568 [...]
+-1.40540597448464, 2.50497740683185, -0.60982269553672, -3.43288247872852, 0.10785937917191, -0.39360854589256, -0.73776551245540, -2.82089155199348, 1.64799667639605, -1.49218992314451, -4.41578444638819, -0.93603458072369, 3.86899743912450, -0.06809727830509, -1.43040346148670, 3.75606561927389, -1.94727281729659, 3.75606561927389, -1.43040346148670, -0.06809727830509, 3.86899743912450, -0.93603458072369, -4.41578444638819, -1.49218992314451, 1.64799667639605, -2.82089155199348, -0.737 [...]
+-5.02278137162993, -3.95742356319849, 2.60497058142900, 1.04698564525724, -2.78771712981609, 3.87715454026481, -3.29452504220191, 3.07102118218099, 0.01987328167566, -3.70205437164826, -1.70641819709222, -0.58848159924352, 0.45722039960182, 5.02452873498669, -1.44266443189156, 0.24152218517903, 1.22100808790073, 0.24152218517903, -1.44266443189156, 5.02452873498669, 0.45722039960182, -0.58848159924352, -1.70641819709222, -3.70205437164826, 0.01987328167566, 3.07102118218099, -3.294525042 [...]
+-10.52906350859377, -7.16208401597183, 4.41931527232739, 3.30802929188696, -6.04555815686641, 7.99698672579895, -6.50788592699034, 6.44963692788028, 0.04659243965101, -7.49513543706844, -1.86853321260226, -1.97065125619650, 1.51091582616531, 8.21583362280702, -0.56606882474507, -2.60298303639010, 5.31193279463100, -2.60298303639011, -0.56606882474506, 8.21583362280702, 1.51091582616531, -1.97065125619650, -1.86853321260226, -7.49513543706844, 0.04659243965101, 6.44963692788028, -6.507885 [...]
+-12.93276289852402, -4.21740984760849, 5.04262402828669, -3.96716685914395, -6.46395973075059, 8.82918432583110, -9.53541678774017, 2.14549954338794, 3.08682692015210, -10.63372400309847, -11.66372057735304, -2.67520910119314, 7.44965456031858, 11.59158137868349, -7.07366415155689, 8.44728282823356, -2.03956989888418, 8.44728282823356, -7.07366415155689, 11.59158137868350, 7.44965456031858, -2.67520910119312, -11.66372057735305, -10.63372400309847, 3.08682692015210, 2.14549954338794, -9. [...]
+7.65013692896325, 4.52397466301566, -1.12862793914300, -10.17021627225519, 11.91644773551517, -14.99749882945734, 12.65489480276605, -13.52050007453513, 4.88753221489818, 1.83319532802056, -1.76390160347601, -0.31822528245991, 3.29047455414783, -6.41868898662239, -0.59399513955277, 6.96388662329659, -7.88975548464535, 6.96388662329661, -0.59399513955277, -6.41868898662238, 3.29047455414783, -0.31822528245990, -1.76390160347601, 1.83319532802057, 4.88753221489818, -13.52050007453512, 12.6 [...]
+-10.72822063464215, -6.32093650453145, 1.43410548049422, 12.05917402550948, -14.83472683614027, 18.15119407025472, -15.63001744080919, 16.35494553003931, -6.10798382013596, -3.54450863605258, 0.76721579023276, -0.10779771769593, -2.96829824100697, 8.58547550546493, 1.43073486495006, -8.76880914581342, 10.80562365976089, -8.76880914581343, 1.43073486495007, 8.58547550546492, -2.96829824100696, -0.10779771769594, 0.76721579023276, -3.54450863605259, -6.10798382013596, 16.35494553003929, -1 [...]
+7.65013692896326, 4.52397466301567, -1.12862793914300, -10.17021627225520, 11.91644773551517, -14.99749882945735, 12.65489480276606, -13.52050007453514, 4.88753221489819, 1.83319532802056, -1.76390160347602, -0.31822528245991, 3.29047455414784, -6.41868898662240, -0.59399513955277, 6.96388662329660, -7.88975548464536, 6.96388662329661, -0.59399513955278, -6.41868898662239, 3.29047455414783, -0.31822528245990, -1.76390160347602, 1.83319532802057, 4.88753221489819, -13.52050007453513, 12.6 [...]
+-12.93276289852402, -4.21740984760849, 5.04262402828669, -3.96716685914395, -6.46395973075059, 8.82918432583110, -9.53541678774018, 2.14549954338795, 3.08682692015209, -10.63372400309847, -11.66372057735304, -2.67520910119314, 7.44965456031857, 11.59158137868349, -7.07366415155689, 8.44728282823355, -2.03956989888417, 8.44728282823355, -7.07366415155689, 11.59158137868350, 7.44965456031858, -2.67520910119312, -11.66372057735305, -10.63372400309847, 3.08682692015209, 2.14549954338795, -9. [...]
+-10.52906350859376, -7.16208401597183, 4.41931527232739, 3.30802929188695, -6.04555815686640, 7.99698672579894, -6.50788592699033, 6.44963692788026, 0.04659243965102, -7.49513543706844, -1.86853321260226, -1.97065125619650, 1.51091582616531, 8.21583362280702, -0.56606882474507, -2.60298303639009, 5.31193279463099, -2.60298303639009, -0.56606882474507, 8.21583362280702, 1.51091582616532, -1.97065125619650, -1.86853321260226, -7.49513543706844, 0.04659243965102, 6.44963692788026, -6.507885 [...]
+-5.02278137162994, -3.95742356319850, 2.60497058142900, 1.04698564525724, -2.78771712981609, 3.87715454026482, -3.29452504220192, 3.07102118218100, 0.01987328167566, -3.70205437164827, -1.70641819709223, -0.58848159924353, 0.45722039960182, 5.02452873498670, -1.44266443189156, 0.24152218517903, 1.22100808790073, 0.24152218517903, -1.44266443189156, 5.02452873498669, 0.45722039960183, -0.58848159924352, -1.70641819709223, -3.70205437164827, 0.01987328167566, 3.07102118218100, -3.294525042 [...]
+-1.40540597448464, 2.50497740683185, -0.60982269553671, -3.43288247872854, 0.10785937917193, -0.39360854589257, -0.73776551245539, -2.82089155199349, 1.64799667639606, -1.49218992314452, -4.41578444638819, -0.93603458072369, 3.86899743912451, -0.06809727830509, -1.43040346148670, 3.75606561927390, -1.94727281729660, 3.75606561927390, -1.43040346148671, -0.06809727830508, 3.86899743912451, -0.93603458072369, -4.41578444638819, -1.49218992314452, 1.64799667639606, -2.82089155199349, -0.737 [...]
+12.72902760738854, 5.24573592337883, -2.53489148489309, -6.36383900286350, 10.63891479360222, -13.23545398077542, 11.56891317022132, -10.24905916842963, 2.05199304856081, 6.56071067211231, 2.90734079112609, 1.76774563166719, -1.78162086533475, -8.22429762215432, -0.21493317508084, 4.56410306635583, -7.89767818707390, 4.56410306635584, -0.21493317508084, -8.22429762215432, -1.78162086533475, 1.76774563166719, 2.90734079112609, 6.56071067211232, 2.05199304856081, -10.24905916842962, 11.568 [...]
+-0.40512910569919, 0.04571781720206, -5.14018026746723, 15.39884403242204, -8.77103955029602, 9.18371415135997, -6.43846498497192, 13.26303702527781, -9.08023236965912, 6.66405260929340, 9.64520482846909, 1.88838351188050, -7.60594445656063, -4.09745199037701, 9.81384348472091, -17.47514056202299, 14.14096546676641, -17.47514056202300, 9.81384348472091, -4.09745199037703, -7.60594445656063, 1.88838351188048, 9.64520482846909, 6.66405260929338, -9.08023236965912, 13.26303702527780, -6.438 [...]
+-0.65585322360949, -1.94485035472052, 6.57809911623014, -13.72804010840783, 7.26661468726808, -6.66815536628270, 4.77056565027482, -10.89465587648248, 8.99902496464351, -7.48484793061143, -7.99600849839671, -1.90062496896635, 6.33296761912446, 5.83930809584792, -10.54020557100553, 16.57098060052476, -13.55196079681233, 16.57098060052477, -10.54020557100554, 5.83930809584794, 6.33296761912446, -1.90062496896632, -7.99600849839671, -7.48484793061141, 8.99902496464351, -10.89465587648246, 4 [...]
+-1.54626373495428, 0.30172393368944, -5.35189787389051, 15.52317502695129, -9.44169963223186, 9.87826755304772, -7.19419825406518, 13.57035942066562, -9.18724741244265, 6.30112099262326, 8.74402870775321, 1.86264101273072, -7.22920783296433, -3.45941126215697, 9.46702457281437, -16.99139964151388, 14.04461751323832, -16.99139964151389, 9.46702457281438, -3.45941126215699, -7.22920783296433, 1.86264101273070, 8.74402870775321, 6.30112099262324, -9.18724741244265, 13.57035942066561, -7.194 [...]
+12.33434675226444, 3.76311994484352, -0.86308000264393, -8.41323897927573, 11.28944720434946, -13.78276078217295, 11.78269208886619, -11.42876457936815, 3.37123935386327, 4.46766813147399, 1.66318573798221, 0.99289215929101, -0.35562000827802, -7.02682447106839, -1.00274566338865, 5.86867143290007, -8.29708435012837, 5.86867143290008, -1.00274566338866, -7.02682447106838, -0.35562000827802, 0.99289215929101, 1.66318573798221, 4.46766813147400, 3.37123935386327, -11.42876457936814, 11.782 [...]
+-5.13492229917853, 3.72415982315523, -1.12361844878879, -4.43309125447855, -1.77811463471488, 1.42965393664389, -3.20658268810889, -2.89359175055380, 1.92720616029590, -3.30867749533838, -8.68309760930295, -1.33468782240254, 6.23406695352077, 2.14277793025021, -3.12388851622980, 6.63730420609597, -2.97003136804169, 6.63730420609597, -3.12388851622980, 2.14277793025021, 6.23406695352078, -1.33468782240254, -8.68309760930295, -3.30867749533838, 1.92720616029590, -2.89359175055380, -3.20658 [...]
+6.66273664989452, 11.46633969041569, -7.44026904749622, -3.60687251998575, 3.93878122684753, -6.47939788765459, 4.21427333534627, -7.05837787525196, -0.28110740451399, 7.22981871982734, -2.49075510219528, 1.49455918728819, 1.70056379350935, -8.64722587430520, 0.50608572437551, 4.38064992184130, -5.47702056014126, 4.38064992184131, 0.50608572437551, -8.64722587430520, 1.70056379350935, 1.49455918728818, -2.49075510219528, 7.22981871982734, -0.28110740451399, -7.05837787525195, 4.214273335 [...]
+16.22243919948918, 3.89683707020861, -1.64061653683746, -6.64896140754365, 12.20734279433442, -15.02922579572945, 13.39769299830609, -10.84984411000404, 2.19156240896512, 7.11669765833022, 5.60802016883876, 1.58956755542132, -2.76764506768711, -9.96219299310700, 1.40383942158031, 2.23593732586147, -6.37994318561652, 2.23593732586148, 1.40383942158031, -9.96219299310700, -2.76764506768711, 1.58956755542131, 5.60802016883877, 7.11669765833023, 2.19156240896512, -10.84984411000403, 13.39769 [...]
+0.71603569067632, 2.48224819396778, -8.12512392288065, 18.55719008721814, -9.84840086209081, 9.65556542149439, -6.72340898037528, 14.99195273629978, -11.58266747950209, 10.07637227752972, 11.32403005265667, 3.05536129906870, -9.68069265450141, -6.42930848468040, 11.88865659819713, -20.26773553674023, 15.75597155390252, -20.26773553674023, 11.88865659819714, -6.42930848468042, -9.68069265450141, 3.05536129906867, 11.32403005265667, 10.07637227752970, -11.58266747950209, 14.99195273629976, [...]
+-12.62664738145497, -13.26193354235105, 14.67563322835584, -6.88006409494036, -3.53180140732137, 8.96180245189184, -7.62383768490719, 1.68511341430559, 8.84107601156306, -16.87556591295538, -6.38715986358795, -3.62056562711385, 4.41395343149593, 19.14014316625846, -14.71757512155856, 13.76751881642539, -8.46336038248996, 13.76751881642539, -14.71757512155856, 19.14014316625848, 4.41395343149593, -3.62056562711382, -6.38715986358796, -16.87556591295536, 8.84107601156306, 1.68511341430560, [...]
+10.16500142106782, 13.05223272851381, -13.41659463125813, 2.94607668413829, 6.02346581296997, -11.56966279561546, 9.71916395344095, -5.18237066131380, -6.33784191050400, 14.50764120131881, 2.53933945388329, 2.66273197748505, -0.81169073700030, -18.29899493822642, 13.44132273151442, -10.32560932507517, 6.24064365835761, -10.32560932507516, 13.44132273151442, -18.29899493822643, -0.81169073700030, 2.66273197748503, 2.53933945388331, 14.50764120131880, -6.33784191050400, -5.18237066131380,  [...]
+-14.02629194694771, -13.30963284393463, 14.34669021492076, -5.58046204644974, -4.72861351067898, 10.35803312031669, -8.73693223251549, 3.05034173174724, 8.18733720774693, -16.85196773705812, -6.45462132852357, -3.43504212211661, 4.02510965374609, 19.83993815341291, -14.68583294181605, 13.25022745567152, -7.91319378526905, 13.25022745567152, -14.68583294181605, 19.83993815341292, 4.02510965374610, -3.43504212211658, -6.45462132852358, -16.85196773705810, 8.18733720774693, 3.05034173174724 [...]
+-0.16854784188363, -0.39359901812678, -6.12141699953062, 18.83961428702428, -10.11699518580972, 10.49244266265024, -7.07194557225082, 16.01265616903865, -11.12764722954493, 8.27260411544711, 12.23586383006171, 2.43311920595548, -9.73059726118961, -5.02062307508864, 12.13141986459055, -21.49631153701344, 17.15893111475332, -21.49631153701346, 12.13141986459056, -5.02062307508867, -9.73059726118961, 2.43311920595545, 12.23586383006172, 8.27260411544708, -11.12764722954493, 16.0126561690386 [...]
+9.25106887268730, 2.38480458331391, -1.75107408997323, -2.22759645906200, 6.87535747414920, -8.65014669996938, 8.03266114816063, -5.26603891284810, 0.18137257671356, 5.32717526767155, 4.17852955458780, 1.64147097697236, -3.13052387042558, -5.76953126782469, 1.11010317447441, 0.64048386763146, -3.75877086225869, 0.64048386763146, 1.11010317447440, -5.76953126782468, -3.13052387042558, 1.64147097697235, 4.17852955458781, 5.32717526767155, 0.18137257671356, -5.26603891284810, 8.032661148160 [...]
+-1.58111675869629, 2.34039594598042, 0.15046934709093, -5.67750442076615, 1.13601088270197, -1.74102311236358, 0.04779744302994, -4.73102358613817, 2.90458196708296, -2.93119412690892, -6.02960502954886, -1.44447389541062, 5.27037270179627, 0.59754524450409, -2.32909453371172, 5.63303023483412, -2.99547099583388, 5.63303023483412, -2.32909453371172, 0.59754524450409, 5.27037270179627, -1.44447389541061, -6.02960502954886, -2.93119412690892, 2.90458196708296, -4.73102358613817, 0.04779744 [...]
+-2.78371043654613, 2.51296055586189, 2.29742616766444, -12.23863698590098, 2.11270333565585, -2.35992397634129, -0.97793651181316, -8.66035718257316, 5.91850203280306, -6.28311622048536, -13.12125555948170, -1.98966894090506, 9.28044355185572, 4.36377417610845, -8.01838019756590, 14.73670790074198, -9.32227835957131, 14.73670790074199, -8.01838019756590, 4.36377417610846, 9.28044355185573, -1.98966894090505, -13.12125555948170, -6.28311622048534, 5.91850203280306, -8.66035718257315, -0.9 [...]
+12.75414659397849, 10.02616578607079, -3.05854004299066, -17.47677578362691, 17.62151372912027, -22.57792287301751, 17.94334107780958, -22.13281438586508, 7.76688749136837, 3.44971431159390, -5.38973416393880, -0.42341524868166, 6.66436629042939, -10.59467153398466, -2.31962448425779, 13.54791617378326, -14.05249540014840, 13.54791617378328, -2.31962448425780, -10.59467153398464, 6.66436629042938, -0.42341524868165, -5.38973416393880, 3.44971431159392, 7.76688749136837, -22.1328143858650 [...]
+7.37582855618055, 3.01558823226363, -8.94400771252139, 17.19986499128086, -10.33534532764507, 9.49894703180167, -8.04877757438286, 14.61535016273022, -13.17461803519746, 12.13564359141705, 10.91564822231077, 3.88315210887298, -10.79393216415549, -7.70975797948487, 11.76699269905275, -19.37347197721331, 15.28656887311034, -19.37347197721332, 11.76699269905276, -7.70975797948489, -10.79393216415549, 3.88315210887295, 10.91564822231078, 12.13564359141702, -13.17461803519746, 14.615350162730 [...]
+-7.61324373567636, -2.71541435757619, 10.87489323943289, -21.58205724536926, 11.12390512183755, -10.09241433012309, 7.67023674887846, -17.59895969537529, 15.99941658738216, -14.92660387356455, -13.87351306521319, -4.71059182112956, 13.10917418100889, 9.87289791710299, -15.63080429806263, 24.88105456022913, -19.22379435705501, 24.88105456022915, -15.63080429806264, 9.87289791710302, 13.10917418100889, -4.71059182112952, -13.87351306521321, -14.92660387356452, 15.99941658738216, -17.598959 [...]
+7.37582855618056, 3.01558823226364, -8.94400771252140, 17.19986499128087, -10.33534532764507, 9.49894703180167, -8.04877757438286, 14.61535016273022, -13.17461803519747, 12.13564359141706, 10.91564822231078, 3.88315210887298, -10.79393216415550, -7.70975797948488, 11.76699269905276, -19.37347197721332, 15.28656887311035, -19.37347197721333, 11.76699269905277, -7.70975797948491, -10.79393216415550, 3.88315210887295, 10.91564822231079, 12.13564359141703, -13.17461803519747, 14.615350162730 [...]
+12.75414659397848, 10.02616578607078, -3.05854004299066, -17.47677578362691, 17.62151372912027, -22.57792287301751, 17.94334107780958, -22.13281438586508, 7.76688749136837, 3.44971431159390, -5.38973416393880, -0.42341524868166, 6.66436629042939, -10.59467153398465, -2.31962448425779, 13.54791617378327, -14.05249540014841, 13.54791617378328, -2.31962448425780, -10.59467153398463, 6.66436629042938, -0.42341524868165, -5.38973416393880, 3.44971431159392, 7.76688749136837, -22.1328143858650 [...]
+-2.78371043654612, 2.51296055586190, 2.29742616766442, -12.23863698590096, 2.11270333565584, -2.35992397634128, -0.97793651181317, -8.66035718257315, 5.91850203280304, -6.28311622048534, -13.12125555948169, -1.98966894090506, 9.28044355185572, 4.36377417610843, -8.01838019756588, 14.73670790074196, -9.32227835957129, 14.73670790074197, -8.01838019756589, 4.36377417610845, 9.28044355185572, -1.98966894090504, -13.12125555948170, -6.28311622048533, 5.91850203280304, -8.66035718257314, -0.9 [...]
+-1.58111675869628, 2.34039594598042, 0.15046934709093, -5.67750442076616, 1.13601088270198, -1.74102311236359, 0.04779744302995, -4.73102358613819, 2.90458196708297, -2.93119412690893, -6.02960502954887, -1.44447389541062, 5.27037270179627, 0.59754524450408, -2.32909453371173, 5.63303023483413, -2.99547099583390, 5.63303023483413, -2.32909453371173, 0.59754524450409, 5.27037270179627, -1.44447389541061, -6.02960502954887, -2.93119412690892, 2.90458196708297, -4.73102358613818, 0.04779744 [...]
+9.25106887268731, 2.38480458331393, -1.75107408997324, -2.22759645906199, 6.87535747414919, -8.65014669996938, 8.03266114816063, -5.26603891284809, 0.18137257671355, 5.32717526767157, 4.17852955458781, 1.64147097697236, -3.13052387042558, -5.76953126782470, 1.11010317447442, 0.64048386763144, -3.75877086225868, 0.64048386763144, 1.11010317447442, -5.76953126782470, -3.13052387042559, 1.64147097697236, 4.17852955458781, 5.32717526767157, 0.18137257671355, -5.26603891284809, 8.032661148160 [...]
+-0.16854784188363, -0.39359901812678, -6.12141699953062, 18.83961428702428, -10.11699518580972, 10.49244266265024, -7.07194557225082, 16.01265616903865, -11.12764722954493, 8.27260411544711, 12.23586383006171, 2.43311920595548, -9.73059726118961, -5.02062307508864, 12.13141986459055, -21.49631153701344, 17.15893111475332, -21.49631153701346, 12.13141986459056, -5.02062307508867, -9.73059726118961, 2.43311920595545, 12.23586383006172, 8.27260411544708, -11.12764722954493, 16.0126561690386 [...]
+-14.02629194694770, -13.30963284393462, 14.34669021492075, -5.58046204644972, -4.72861351067899, 10.35803312031669, -8.73693223251550, 3.05034173174724, 8.18733720774692, -16.85196773705810, -6.45462132852357, -3.43504212211661, 4.02510965374609, 19.83993815341290, -14.68583294181603, 13.25022745567151, -7.91319378526904, 13.25022745567151, -14.68583294181603, 19.83993815341291, 4.02510965374609, -3.43504212211658, -6.45462132852358, -16.85196773705809, 8.18733720774692, 3.05034173174725 [...]
+10.16500142106783, 13.05223272851381, -13.41659463125813, 2.94607668413827, 6.02346581296998, -11.56966279561548, 9.71916395344096, -5.18237066131381, -6.33784191050400, 14.50764120131881, 2.53933945388329, 2.66273197748505, -0.81169073700029, -18.29899493822642, 13.44132273151442, -10.32560932507515, 6.24064365835760, -10.32560932507515, 13.44132273151441, -18.29899493822643, -0.81169073700029, 2.66273197748502, 2.53933945388330, 14.50764120131879, -6.33784191050400, -5.18237066131382,  [...]
+-12.62664738145498, -13.26193354235105, 14.67563322835584, -6.88006409494036, -3.53180140732138, 8.96180245189185, -7.62383768490720, 1.68511341430560, 8.84107601156306, -16.87556591295539, -6.38715986358796, -3.62056562711386, 4.41395343149593, 19.14014316625848, -14.71757512155857, 13.76751881642539, -8.46336038248995, 13.76751881642539, -14.71757512155857, 19.14014316625849, 4.41395343149593, -3.62056562711382, -6.38715986358797, -16.87556591295537, 8.84107601156306, 1.68511341430560, [...]
+0.71603569067631, 2.48224819396778, -8.12512392288064, 18.55719008721814, -9.84840086209081, 9.65556542149439, -6.72340898037528, 14.99195273629978, -11.58266747950209, 10.07637227752972, 11.32403005265666, 3.05536129906869, -9.68069265450141, -6.42930848468039, 11.88865659819713, -20.26773553674022, 15.75597155390252, -20.26773553674023, 11.88865659819714, -6.42930848468041, -9.68069265450141, 3.05536129906867, 11.32403005265667, 10.07637227752969, -11.58266747950209, 14.99195273629976, [...]
+16.22243919948918, 3.89683707020861, -1.64061653683746, -6.64896140754365, 12.20734279433442, -15.02922579572945, 13.39769299830609, -10.84984411000404, 2.19156240896512, 7.11669765833022, 5.60802016883876, 1.58956755542132, -2.76764506768711, -9.96219299310700, 1.40383942158031, 2.23593732586147, -6.37994318561652, 2.23593732586148, 1.40383942158031, -9.96219299310700, -2.76764506768712, 1.58956755542131, 5.60802016883876, 7.11669765833023, 2.19156240896512, -10.84984411000403, 13.39769 [...]
+-6.60654009415507, -10.92455945134428, 8.31842812710608, -0.66313409741331, -2.37951744465164, 4.55909849707647, -3.42185047060164, 3.58221390010070, 2.41751984540606, -9.23707520729638, -0.93784682718669, -2.39603349856301, 1.35402702203993, 9.14836894032928, -2.19399627701525, -0.53236050968769, 3.15696256419329, -0.53236050968770, -2.19399627701525, 9.14836894032928, 1.35402702203994, -2.39603349856300, -0.93784682718669, -9.23707520729637, 2.41751984540606, 3.58221390010070, -3.42185 [...]
+-14.74393062865331, -1.32106660863471, 0.65009178089675, 3.29677414624710, -10.06658568712778, 12.03137215116938, -11.53947232513443, 7.10939968198017, -0.99210751171965, -6.68829752956732, -8.14354163472282, -1.55863401457358, 4.49000105397609, 8.81238058229880, -2.68588684433825, 1.46968342799886, 3.21771717399408, 1.46968342799885, -2.68588684433825, 8.81238058229880, 4.49000105397610, -1.55863401457357, -8.14354163472283, -6.68829752956733, -0.99210751171965, 7.10939968198016, -11.53 [...]
+4.72639414878423, -0.45689074932855, 5.85246101180145, -17.56576529334051, 12.00204995338546, -12.93005425770586, 9.82276473004764, -16.04720784994144, 10.15798470236241, -5.96786929447219, -7.79823374625514, -2.15833956442626, 7.51280741127249, 1.62177196726920, -8.86498664655664, 17.12277675375032, -14.58191882062153, 17.12277675375033, -8.86498664655665, 1.62177196726922, 7.51280741127249, -2.15833956442624, -7.79823374625514, -5.96786929447217, 10.15798470236241, -16.04720784994143,  [...]
+8.91237533091781, 10.35130507919668, -13.28581569314380, 11.52146969550268, -1.15597058560113, -2.67830194356923, 2.80594748407554, 4.24722144998790, -10.36836318806294, 15.50615447505318, 8.38058913088777, 3.76726987893619, -6.70276057511472, -15.45666563691728, 14.19212528585193, -16.46480006133991, 11.12360390205130, -16.46480006133991, 14.19212528585193, -15.45666563691729, -6.70276057511472, 3.76726987893616, 8.38058913088778, 15.50615447505315, -10.36836318806294, 4.24722144998789, [...]
+-7.93441996713900, -10.82318919098342, 12.79852585873741, -7.81786650812990, -1.51348803031006, 5.83625324407772, -5.24840624495381, -0.56788891355608, 8.39448017605384, -14.12072694697901, -5.15371450706424, -3.03724428628333, 3.61355025190648, 15.69581758241048, -13.59455617290117, 13.63480450842786, -9.22907396159892, 13.63480450842786, -13.59455617290117, 15.69581758241050, 3.61355025190648, -3.03724428628330, -5.15371450706425, -14.12072694697899, 8.39448017605384, -0.56788891355607 [...]
+10.45825101919689, 10.29321540849251, -12.95513689261551, 10.48203493639938, 0.03305368990284, -4.03365616309647, 3.97202286263357, 3.06920025506652, -9.81456074389002, 15.62653083152716, 8.83250043699877, 3.60802626397507, -6.52944439898166, -16.30170070366778, 14.35725602262621, -16.31917489400402, 10.79167128308033, -16.31917489400402, 14.35725602262621, -16.30170070366779, -6.52944439898167, 3.60802626397504, 8.83250043699879, 15.62653083152713, -9.81456074389002, 3.06920025506651, 3 [...]
+5.60433862789432, 2.35242523863248, 3.63775785996725, -16.94448264989111, 11.95028794360235, -13.35486820024027, 10.00309928333821, -16.33187849196730, 9.24065247535889, -3.67693429548397, -8.01402110855952, -1.29874571399605, 6.87856583168096, 0.12013790576510, -8.81435526929244, 17.61337577776529, -15.58775359702257, 17.61337577776530, -8.81435526929245, 0.12013790576512, 6.87856583168096, -1.29874571399603, -8.01402110855953, -3.67693429548394, 9.24065247535889, -16.33187849196728, 10 [...]
+-7.85563821620906, -0.61879763716117, 0.90476461939520, 0.38362076520172, -5.25410518255157, 6.43767461665303, -6.44399752201603, 2.88730432872950, 0.43448159546764, -4.58014233264032, -5.18623175942544, -1.51565985911258, 3.87817685784167, 4.53187957898162, -1.59951450543482, 1.30684891456881, 1.81790098229721, 1.30684891456880, -1.59951450543482, 4.53187957898162, 3.87817685784167, -1.51565985911258, -5.18623175942545, -4.58014233264032, 0.43448159546764, 2.88730432872949, -6.443997522 [...]
+-0.69431137122357, -3.66263970794854, 1.19987581135881, 4.57534894170629, -1.81333037931406, 2.76331216788767, -1.21421109030508, 4.73327235844181, -2.03751252195637, 0.56498106387676, 4.03558214128579, 0.76279413984798, -3.75787966969865, 1.56389486865036, 1.23717255429903, -4.27683750735179, 2.85416219443029, -4.27683750735179, 1.23717255429903, 1.56389486865035, -3.75787966969865, 0.76279413984798, 4.03558214128579, 0.56498106387676, -2.03751252195637, 4.73327235844181, -1.21421109030 [...]
+-2.54604357447963, -4.66929282514188, -0.13819423108440, 11.02583808873697, -4.43047097026064, 5.50970390273781, -2.27286523076009, 9.58694035937607, -4.66322824909073, 1.84503222857398, 9.17081960315400, 0.78279584091770, -6.51522919190225, 0.12778700695288, 5.81743838515182, -12.30345289542709, 9.26501510412659, -12.30345289542710, 5.81743838515182, 0.12778700695286, -6.51522919190225, 0.78279584091769, 9.17081960315400, 1.84503222857397, -4.66322824909073, 9.58694035937607, -2.2728652 [...]
+-14.91579712362891, -9.74698132282363, 4.77651452440564, 11.19018288040513, -15.39503735964576, 20.09471115811250, -16.85383747599084, 17.19405573215886, -4.27560277753923, -7.24991661159171, -0.63770775434433, -0.84777469232249, -1.93728973301874, 12.90496602208401, -1.24312903168856, -6.58887726974358, 9.55867710193666, -6.58887726974359, -1.24312903168855, 12.90496602208400, -1.93728973301873, -0.84777469232249, -0.63770775434433, -7.24991661159172, -4.27560277753923, 17.1940557321588 [...]
+-2.78796510523726, -0.12671975788172, 5.81471250191857, -16.48937092176395, 11.73649333148878, -12.35123247255438, 10.27574298101094, -15.80450110998019, 11.39598252505388, -8.25051505196516, -9.19190048429895, -3.04973507217950, 9.55529512593388, 3.15487598418823, -8.75727896903642, 16.91983100136104, -14.03306153669358, 16.91983100136105, -8.75727896903643, 3.15487598418825, 9.55529512593388, -3.04973507217947, -9.19190048429895, -8.25051505196514, 11.39598252505388, -15.80450110998017 [...]
+1.64748694331119, -0.91387402580180, -7.04400202896831, 20.53374943769273, -13.49577523677130, 14.10806478087141, -11.19391194394507, 19.20792537128831, -13.94749639474252, 9.58117908275203, 11.05087412218365, 3.49713545835765, -11.20233591548618, -3.78237498736739, 11.87719021922083, -21.68775615665565, 18.05786614830462, -21.68775615665566, 11.87719021922084, -3.78237498736741, -11.20233591548618, 3.49713545835762, 11.05087412218366, 9.58117908275200, -13.94749639474252, 19.20792537128 [...]
+-2.78796510523727, -0.12671975788172, 5.81471250191858, -16.48937092176396, 11.73649333148879, -12.35123247255438, 10.27574298101094, -15.80450110998020, 11.39598252505389, -8.25051505196517, -9.19190048429895, -3.04973507217950, 9.55529512593388, 3.15487598418823, -8.75727896903643, 16.91983100136105, -14.03306153669358, 16.91983100136106, -8.75727896903644, 3.15487598418825, 9.55529512593388, -3.04973507217948, -9.19190048429896, -8.25051505196515, 11.39598252505389, -15.80450110998018 [...]
+-14.91579712362891, -9.74698132282363, 4.77651452440563, 11.19018288040513, -15.39503735964576, 20.09471115811250, -16.85383747599084, 17.19405573215886, -4.27560277753924, -7.24991661159171, -0.63770775434433, -0.84777469232249, -1.93728973301874, 12.90496602208401, -1.24312903168855, -6.58887726974359, 9.55867710193666, -6.58887726974360, -1.24312903168854, 12.90496602208400, -1.93728973301874, -0.84777469232249, -0.63770775434433, -7.24991661159172, -4.27560277753924, 17.1940557321588 [...]
+-2.54604357447964, -4.66929282514189, -0.13819423108439, 11.02583808873695, -4.43047097026062, 5.50970390273779, -2.27286523076008, 9.58694035937606, -4.66322824909072, 1.84503222857396, 9.17081960315399, 0.78279584091769, -6.51522919190224, 0.12778700695289, 5.81743838515180, -12.30345289542707, 9.26501510412657, -12.30345289542708, 5.81743838515181, 0.12778700695287, -6.51522919190224, 0.78279584091768, 9.17081960315399, 1.84503222857395, -4.66322824909072, 9.58694035937605, -2.2728652 [...]
+-0.69431137122358, -3.66263970794855, 1.19987581135881, 4.57534894170630, -1.81333037931407, 2.76331216788768, -1.21421109030509, 4.73327235844182, -2.03751252195638, 0.56498106387676, 4.03558214128579, 0.76279413984799, -3.75787966969865, 1.56389486865036, 1.23717255429903, -4.27683750735180, 2.85416219443030, -4.27683750735180, 1.23717255429904, 1.56389486865036, -3.75787966969866, 0.76279413984798, 4.03558214128579, 0.56498106387676, -2.03751252195638, 4.73327235844182, -1.21421109030 [...]
+-7.85563821620906, -0.61879763716118, 0.90476461939522, 0.38362076520170, -5.25410518255156, 6.43767461665302, -6.44399752201602, 2.88730432872948, 0.43448159546766, -4.58014233264033, -5.18623175942545, -1.51565985911258, 3.87817685784168, 4.53187957898163, -1.59951450543483, 1.30684891456882, 1.81790098229719, 1.30684891456882, -1.59951450543483, 4.53187957898163, 3.87817685784168, -1.51565985911258, -5.18623175942545, -4.58014233264033, 0.43448159546766, 2.88730432872948, -6.443997522 [...]
+5.60433862789432, 2.35242523863248, 3.63775785996725, -16.94448264989111, 11.95028794360235, -13.35486820024027, 10.00309928333821, -16.33187849196730, 9.24065247535889, -3.67693429548397, -8.01402110855952, -1.29874571399605, 6.87856583168096, 0.12013790576510, -8.81435526929244, 17.61337577776529, -15.58775359702257, 17.61337577776530, -8.81435526929245, 0.12013790576512, 6.87856583168096, -1.29874571399603, -8.01402110855953, -3.67693429548394, 9.24065247535889, -16.33187849196728, 10 [...]
+10.45825101919688, 10.29321540849250, -12.95513689261550, 10.48203493639936, 0.03305368990285, -4.03365616309647, 3.97202286263358, 3.06920025506651, -9.81456074389001, 15.62653083152715, 8.83250043699877, 3.60802626397506, -6.52944439898166, -16.30170070366777, 14.35725602262620, -16.31917489400400, 10.79167128308032, -16.31917489400401, 14.35725602262620, -16.30170070366778, -6.52944439898166, 3.60802626397503, 8.83250043699878, 15.62653083152713, -9.81456074389001, 3.06920025506650, 3 [...]
+-7.93441996713900, -10.82318919098342, 12.79852585873741, -7.81786650812989, -1.51348803031008, 5.83625324407773, -5.24840624495382, -0.56788891355606, 8.39448017605384, -14.12072694697901, -5.15371450706424, -3.03724428628333, 3.61355025190648, 15.69581758241049, -13.59455617290117, 13.63480450842785, -9.22907396159891, 13.63480450842785, -13.59455617290116, 15.69581758241050, 3.61355025190648, -3.03724428628330, -5.15371450706425, -14.12072694697900, 8.39448017605384, -0.56788891355606 [...]
+8.91237533091781, 10.35130507919668, -13.28581569314380, 11.52146969550268, -1.15597058560113, -2.67830194356924, 2.80594748407555, 4.24722144998790, -10.36836318806294, 15.50615447505318, 8.38058913088778, 3.76726987893620, -6.70276057511472, -15.45666563691728, 14.19212528585193, -16.46480006133992, 11.12360390205130, -16.46480006133992, 14.19212528585194, -15.45666563691730, -6.70276057511472, 3.76726987893616, 8.38058913088779, 15.50615447505316, -10.36836318806294, 4.24722144998789, [...]
+4.72639414878423, -0.45689074932855, 5.85246101180144, -17.56576529334051, 12.00204995338546, -12.93005425770586, 9.82276473004764, -16.04720784994144, 10.15798470236241, -5.96786929447219, -7.79823374625513, -2.15833956442626, 7.51280741127249, 1.62177196726920, -8.86498664655664, 17.12277675375031, -14.58191882062152, 17.12277675375032, -8.86498664655665, 1.62177196726922, 7.51280741127249, -2.15833956442624, -7.79823374625514, -5.96786929447216, 10.15798470236241, -16.04720784994143,  [...]
+-14.74393062865331, -1.32106660863471, 0.65009178089675, 3.29677414624710, -10.06658568712777, 12.03137215116938, -11.53947232513443, 7.10939968198017, -0.99210751171965, -6.68829752956732, -8.14354163472282, -1.55863401457358, 4.49000105397609, 8.81238058229880, -2.68588684433825, 1.46968342799886, 3.21771717399408, 1.46968342799886, -2.68588684433825, 8.81238058229879, 4.49000105397610, -1.55863401457357, -8.14354163472282, -6.68829752956733, -0.99210751171965, 7.10939968198016, -11.53 [...]
+-2.83892324752302, 2.85383650050538, -5.26786903008573, 10.47164812229259, -5.44175398068539, 5.82686379169153, -3.70591594074213, 8.06186173708607, -5.86358474714272, 5.68625683320837, 4.83276142081909, 2.25463843492306, -5.30540746510734, -1.96488446581300, 3.87127506697336, -7.46148902140177, 4.69551251777414, -7.46148902140177, 3.87127506697337, -1.96488446581301, -5.30540746510734, 2.25463843492305, 4.83276142081909, 5.68625683320836, -5.86358474714272, 8.06186173708606, -3.70591594 [...]
+1.48844980656864, -7.53197097533599, 4.70466438429144, 2.17163880626252, 0.76722359582777, 0.43617086817483, 1.22518018396498, 2.96966794692196, 0.11530359076553, -1.85538946300150, 5.93872630793449, -0.45564423271207, -3.26839582099430, 1.76661900667651, 1.66266033403360, -5.16346552176543, 3.72489832557383, -5.16346552176544, 1.66266033403361, 1.76661900667650, -3.26839582099431, -0.45564423271207, 5.93872630793449, -1.85538946300150, 0.11530359076553, 2.96966794692196, 1.2251801839649 [...]
+-12.90357861837443, -0.39327153742449, -0.20052457623054, 4.07256654998587, -9.53342148296997, 11.32977513744764, -10.68952183745446, 7.12817473025630, -1.54161648491619, -4.91145904271029, -6.54138867500059, -0.98676950171581, 3.20845442459893, 7.32562176838770, -2.11122861028575, 0.59745607703476, 3.13473460008625, 0.59745607703475, -2.11122861028575, 7.32562176838770, 3.20845442459893, -0.98676950171580, -6.54138867500059, -4.91145904271029, -1.54161648491619, 7.12817473025629, -10.68 [...]
+8.81120083658669, 0.96699714387759, 3.10798917310939, -13.74760636035437, 12.40633475048180, -14.14945472274416, 11.54545844652242, -14.40300324513701, 7.27182755565672, -1.28042776052364, -3.08484993417518, -0.93096067496508, 4.12892821614577, -2.91495676083156, -4.56285684625123, 11.25464421374244, -11.09207238281739, 11.25464421374245, -4.56285684625124, -2.91495676083154, 4.12892821614577, -0.93096067496507, -3.08484993417518, -1.28042776052363, 7.27182755565672, -14.40300324513699,  [...]
+-6.07772619354717, 0.31720630501918, -4.42544903339188, 13.46692739275013, -11.08927873084958, 11.99114248041518, -9.82711103996451, 13.15894335817657, -7.83472486828901, 3.05190823784305, 3.91034290654757, 1.18963666006280, -4.45221665663239, 0.36488891885516, 6.19929929386604, -12.38924708360193, 11.66628994922002, -12.38924708360195, 6.19929929386605, 0.36488891885514, -4.45221665663239, 1.18963666006278, 3.91034290654757, 3.05190823784303, -7.83472486828901, 13.15894335817655, -9.827 [...]
+7.93680911024684, 1.69583282166668, 2.54940281679401, -13.59382280977508, 11.80811769545808, -13.61856126844256, 10.89158899246870, -14.21180174458240, 7.02600983653372, -1.21342973134076, -4.03317447425188, -0.76369131859191, 4.33668485649476, -2.50944552282385, -4.97998124586835, 11.92180662822938, -11.47315931505510, 11.92180662822939, -4.97998124586836, -2.50944552282383, 4.33668485649476, -0.76369131859189, -4.03317447425189, -1.21342973134074, 7.02600983653372, -14.21180174458239,  [...]
+-11.82121651815161, -1.54258789558302, 1.41302857641138, 1.38521194357436, -7.92378006544159, 9.62619103665523, -9.45987748833682, 4.99973245149731, 0.09578774923518, -6.55671226155792, -7.18222467872137, -1.84981894575742, 4.69429494883616, 7.40450346020666, -2.52585857745149, 1.76767994247843, 2.57103003912963, 1.76767994247843, -2.52585857745149, 7.40450346020666, 4.69429494883616, -1.84981894575741, -7.18222467872137, -6.55671226155792, 0.09578774923518, 4.99973245149731, -9.45987748 [...]
+-0.45647901794024, -4.44655967216672, 2.72933379748613, 1.55564669432081, -0.49304685858063, 1.25934607943491, -0.36172879866242, 2.43307547830835, -0.25115983160303, -1.48736597421604, 2.34188730208856, -0.02686264784769, -1.97025445310636, 2.41346622029012, 0.13438001226859, -2.19202820169768, 1.81268549712075, -2.19202820169768, 0.13438001226859, 2.41346622029012, -1.97025445310636, -0.02686264784769, 2.34188730208856, -1.48736597421604, -0.25115983160303, 2.43307547830835, -0.3617287 [...]
+3.22107757599756, 3.23399308552368, -3.03104207600299, 2.16207864750426, 0.82214964343268, -1.46028783433140, 1.75326752336222, -0.06258841497220, -1.45361690538590, 4.14679887458980, 3.24610963833749, 0.91335342390199, -1.93616762543124, -4.40142256945175, 2.39347634143422, -2.73075183789195, 0.71621739105259, -2.73075183789195, 2.39347634143422, -4.40142256945176, -1.93616762543124, 0.91335342390198, 3.24610963833749, 4.14679887458980, -1.45361690538590, -0.06258841497220, 1.7532675233 [...]
+9.33068055761014, 4.06913288309929, -3.65608563471563, 1.38995726427515, 4.06438203253835, -5.17576132410929, 5.23249020230399, -1.84125004091185, -2.01926074364268, 7.97145956622136, 5.79496293751167, 2.44448261311050, -4.66719170360886, -7.24184172313529, 2.45952382430921, -2.30328430918646, -1.70480970563650, -2.30328430918646, 2.45952382430921, -7.24184172313530, -4.66719170360886, 2.44448261311049, 5.79496293751168, 7.97145956622135, -2.01926074364268, -1.84125004091185, 5.232490202 [...]
+5.30887173513361, -0.35314929177097, -2.61131070520295, 8.25111156681909, 0.41017902078846, -0.86625067725684, 3.04378460756717, 4.50365078897770, -4.15482761607277, 6.40169873588622, 11.11987213835412, 1.73280651944722, -7.36714684531599, -5.84918454235113, 6.76983406014196, -11.25994512486714, 6.37954209195653, -11.25994512486715, 6.76983406014197, -5.84918454235115, -7.36714684531600, 1.73280651944721, 11.11987213835412, 6.40169873588621, -4.15482761607277, 4.50365078897769, 3.0437846 [...]
+-8.74363591172941, -4.17508994192660, 2.91004137947714, 3.94089301398668, -8.46655081935157, 11.34921816838086, -10.12044393037213, 8.12203673617977, -1.23852697990212, -4.65283592976415, -3.02905236090687, -0.50154070452117, 0.42110081161918, 8.14051929827692, -3.20629336164750, 0.16786445716182, 2.33185172968503, 0.16786445716182, -3.20629336164749, 8.14051929827691, 0.42110081161919, -0.50154070452117, -3.02905236090687, -4.65283592976416, -1.23852697990212, 8.12203673617977, -10.1204 [...]
+11.14535351330902, 5.18968876430293, -3.38123424448073, -4.28615501749417, 10.75134709711703, -13.76145495194180, 12.77644128265987, -9.58436396049420, 1.63479533576613, 6.58451940627451, 4.87389970716438, 1.02600374173176, -1.40902412469535, -10.25618613141288, 3.42885639532289, -0.14021710943361, -3.76029539109273, -0.14021710943360, 3.42885639532289, -10.25618613141288, -1.40902412469535, 1.02600374173175, 4.87389970716439, 6.58451940627451, 1.63479533576613, -9.58436396049419, 12.776 [...]
+-8.74363591172941, -4.17508994192660, 2.91004137947714, 3.94089301398668, -8.46655081935158, 11.34921816838087, -10.12044393037214, 8.12203673617978, -1.23852697990213, -4.65283592976416, -3.02905236090687, -0.50154070452117, 0.42110081161918, 8.14051929827692, -3.20629336164750, 0.16786445716182, 2.33185172968503, 0.16786445716181, -3.20629336164750, 8.14051929827692, 0.42110081161919, -0.50154070452117, -3.02905236090687, -4.65283592976416, -1.23852697990213, 8.12203673617977, -10.1204 [...]
+5.30887173513361, -0.35314929177097, -2.61131070520295, 8.25111156681908, 0.41017902078847, -0.86625067725684, 3.04378460756718, 4.50365078897769, -4.15482761607276, 6.40169873588621, 11.11987213835412, 1.73280651944722, -7.36714684531599, -5.84918454235113, 6.76983406014196, -11.25994512486714, 6.37954209195652, -11.25994512486714, 6.76983406014197, -5.84918454235115, -7.36714684531599, 1.73280651944721, 11.11987213835412, 6.40169873588621, -4.15482761607276, 4.50365078897769, 3.0437846 [...]
+9.33068055761013, 4.06913288309929, -3.65608563471564, 1.38995726427516, 4.06438203253833, -5.17576132410927, 5.23249020230397, -1.84125004091184, -2.01926074364268, 7.97145956622136, 5.79496293751167, 2.44448261311050, -4.66719170360886, -7.24184172313529, 2.45952382430921, -2.30328430918647, -1.70480970563650, -2.30328430918647, 2.45952382430921, -7.24184172313529, -4.66719170360887, 2.44448261311049, 5.79496293751168, 7.97145956622136, -2.01926074364268, -1.84125004091184, 5.232490202 [...]
+3.22107757599757, 3.23399308552368, -3.03104207600299, 2.16207864750426, 0.82214964343268, -1.46028783433141, 1.75326752336223, -0.06258841497220, -1.45361690538591, 4.14679887458980, 3.24610963833749, 0.91335342390199, -1.93616762543125, -4.40142256945176, 2.39347634143422, -2.73075183789196, 0.71621739105259, -2.73075183789196, 2.39347634143422, -4.40142256945176, -1.93616762543125, 0.91335342390199, 3.24610963833750, 4.14679887458980, -1.45361690538591, -0.06258841497220, 1.7532675233 [...]
+-0.45647901794025, -4.44655967216672, 2.72933379748613, 1.55564669432082, -0.49304685858065, 1.25934607943493, -0.36172879866243, 2.43307547830836, -0.25115983160304, -1.48736597421604, 2.34188730208856, -0.02686264784769, -1.97025445310637, 2.41346622029013, 0.13438001226859, -2.19202820169769, 1.81268549712076, -2.19202820169769, 0.13438001226860, 2.41346622029013, -1.97025445310637, -0.02686264784769, 2.34188730208856, -1.48736597421603, -0.25115983160304, 2.43307547830836, -0.3617287 [...]
+-11.82121651815161, -1.54258789558302, 1.41302857641138, 1.38521194357436, -7.92378006544159, 9.62619103665523, -9.45987748833682, 4.99973245149731, 0.09578774923518, -6.55671226155792, -7.18222467872137, -1.84981894575742, 4.69429494883616, 7.40450346020666, -2.52585857745149, 1.76767994247843, 2.57103003912963, 1.76767994247843, -2.52585857745149, 7.40450346020666, 4.69429494883616, -1.84981894575741, -7.18222467872137, -6.55671226155792, 0.09578774923518, 4.99973245149731, -9.45987748 [...]
+7.93680911024684, 1.69583282166669, 2.54940281679401, -13.59382280977507, 11.80811769545807, -13.61856126844255, 10.89158899246868, -14.21180174458239, 7.02600983653372, -1.21342973134076, -4.03317447425188, -0.76369131859191, 4.33668485649476, -2.50944552282384, -4.97998124586835, 11.92180662822937, -11.47315931505509, 11.92180662822939, -4.97998124586836, -2.50944552282383, 4.33668485649476, -0.76369131859189, -4.03317447425189, -1.21342973134074, 7.02600983653372, -14.21180174458238,  [...]
+-6.07772619354717, 0.31720630501918, -4.42544903339188, 13.46692739275014, -11.08927873084958, 11.99114248041517, -9.82711103996451, 13.15894335817657, -7.83472486828901, 3.05190823784305, 3.91034290654758, 1.18963666006280, -4.45221665663240, 0.36488891885515, 6.19929929386605, -12.38924708360194, 11.66628994922002, -12.38924708360195, 6.19929929386605, 0.36488891885514, -4.45221665663239, 1.18963666006279, 3.91034290654758, 3.05190823784303, -7.83472486828901, 13.15894335817655, -9.827 [...]
+8.81120083658669, 0.96699714387760, 3.10798917310939, -13.74760636035438, 12.40633475048180, -14.14945472274417, 11.54545844652242, -14.40300324513701, 7.27182755565672, -1.28042776052364, -3.08484993417518, -0.93096067496508, 4.12892821614577, -2.91495676083156, -4.56285684625124, 11.25464421374245, -11.09207238281739, 11.25464421374246, -4.56285684625124, -2.91495676083155, 4.12892821614577, -0.93096067496507, -3.08484993417519, -1.28042776052362, 7.27182755565672, -14.40300324513700,  [...]
+-12.90357861837442, -0.39327153742449, -0.20052457623054, 4.07256654998587, -9.53342148296997, 11.32977513744764, -10.68952183745446, 7.12817473025630, -1.54161648491619, -4.91145904271029, -6.54138867500059, -0.98676950171581, 3.20845442459893, 7.32562176838770, -2.11122861028575, 0.59745607703476, 3.13473460008624, 0.59745607703476, -2.11122861028575, 7.32562176838770, 3.20845442459893, -0.98676950171580, -6.54138867500059, -4.91145904271029, -1.54161648491619, 7.12817473025629, -10.68 [...]
+1.48844980656864, -7.53197097533599, 4.70466438429144, 2.17163880626253, 0.76722359582777, 0.43617086817483, 1.22518018396498, 2.96966794692196, 0.11530359076553, -1.85538946300150, 5.93872630793449, -0.45564423271207, -3.26839582099430, 1.76661900667651, 1.66266033403360, -5.16346552176543, 3.72489832557383, -5.16346552176544, 1.66266033403361, 1.76661900667651, -3.26839582099431, -0.45564423271207, 5.93872630793449, -1.85538946300150, 0.11530359076553, 2.96966794692196, 1.2251801839649 [...]
diff --git a/test/functorexpression/CMakeLists.txt b/test/functorexpression/CMakeLists.txt
new file mode 100644
index 0000000..55d4689
--- /dev/null
+++ b/test/functorexpression/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_functorexpression test.cxx)
diff --git a/test/functorexpression/test.cxx b/test/functorexpression/test.cxx
new file mode 100644
index 0000000..e9d8c93
--- /dev/null
+++ b/test/functorexpression/test.cxx
@@ -0,0 +1,472 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <algorithm>
+#include <cmath>
+#include "vigra/unittest.hxx"
+#include "vigra/functorexpression.hxx"
+#include "vigra/rgbvalue.hxx"
+#include "vigra/sized_int.hxx"
+
+using namespace vigra::functor;
+
+template <class EXPR>
+typename ResultTraits0<UnaryFunctor<EXPR> >::Res 
+exec(UnaryFunctor<EXPR> f) { return f(); } 
+
+template <class EXPR, class T1>
+typename ResultTraits1<UnaryFunctor<EXPR>, T1>::Res 
+exec(UnaryFunctor<EXPR> f, T1 const & a1) { return f(a1); } 
+
+template <class EXPR, class T1, class T2>
+typename ResultTraits2<UnaryFunctor<EXPR>, T1, T2>::Res 
+exec(UnaryFunctor<EXPR> f, T1 const & a1, T2 const & a2) { return f(a1, a2); } 
+
+template <class EXPR, class T1, class T2, class T3>
+typename ResultTraits3<UnaryFunctor<EXPR>, T1, T2, T3>::Res 
+exec(UnaryFunctor<EXPR> f, T1 const & a1, T2 const & a2, T3 const & a3) 
+{ return f(a1, a2, a3); } 
+
+template <class EXPR, class T1>
+void 
+exec(UnaryAnalyser<EXPR> f, T1 const & a1) { f(a1); } 
+
+template <class EXPR, class T1, class T2>
+void 
+exec(UnaryAnalyser<EXPR> f, T1 const & a1, T2 const & a2) { f(a1, a2); } 
+
+template <class EXPR, class T1, class T2, class T3>
+void 
+exec(UnaryAnalyser<EXPR> f, T1 const & a1, T2 const & a2, T3 const & a3) 
+{ f(a1, a2, a3); } 
+
+struct FunctorExpressionTest
+{    
+    void testArg1()
+    {
+        should(exec(Arg1(), 1.5) == 1.5); 
+        should(exec(Arg1(), 1.5, 2) == 1.5); 
+        should(exec(Arg1(), 1.5, 2, true) == 1.5); 
+    }
+    
+    void testArg2()
+    {
+        should(exec(Arg2(), 1, 2.5) == 2.5); 
+        should(exec(Arg2(), 1, 2.5, false) == 2.5); 
+    }
+    
+    void testArg3()
+    {
+        should(exec(Arg3(), 1, true, 3.5) == 3.5); 
+    }
+
+    void testParam()
+    {
+        should(exec(Param(4.5), 1) == 4.5); 
+        should(exec(Param(4.5), 1, true) == 4.5); 
+        should(exec(Param(4.5), 1, true, 3) == 4.5); 
+    }
+    
+    void testVar()
+    {
+        double v = 4.5;
+        should(exec(Var(v), 1) == 4.5); 
+        should(exec(Var(v), 1, true) == 4.5); 
+        should(exec(Var(v), 1, true, 3) == 4.5); 
+    }
+    
+    void testAssignment()
+    {
+        double v = 0.0;
+        exec(Var(v) = Arg1(), 1.5);
+        should(v == 1.5);
+        exec(Var(v) = Arg2(), 1, 2.5);
+        should(v == 2.5);
+        exec(Var(v) = Arg3(), 1, 2, 3.5);
+        should(v == 3.5);
+        exec(Var(v) += Arg1(), 2.5);
+        should(v == 6.0);
+        exec(Var(v) -= Arg1(), 2.5);
+        should(v == 3.5);
+        exec(Var(v) *= Arg1(), 2.0);
+        should(v == 7.0);
+        exec(Var(v) /= Arg1(), 2.0);
+        should(v == 3.5);
+    }
+    
+    void testIfThen()
+    {
+        double v = 4.0;
+        exec(ifThen(Arg1(), Var(v) = Param(1.5)), false);
+        should(v == 4.0);
+        exec(ifThen(Arg1(), Var(v) = Param(1.5)), true);
+        should(v == 1.5);
+        exec(ifThen(Arg2(), Var(v) = Arg1()), 2.5, false);
+        should(v == 1.5);
+        exec(ifThen(Arg2(), Var(v) = Arg1()), 2.5, true);
+        should(v == 2.5);
+        exec(ifThen(Arg3(), Var(v) = Arg2()), 1, 3.5, false);
+        should(v == 2.5);
+        exec(ifThen(Arg3(), Var(v) = Arg2()), 1, 3.5, true);
+        should(v == 3.5);
+    }
+    
+    void testIfThenElse()
+    {
+        should(exec(ifThenElse(Arg1(), Arg2(), Arg3()), true, 2, 3.5) == 2.0); 
+        should(exec(ifThenElse(Arg1(), Arg2(), Arg3()), false, 2, 3.5) == 3.5);
+        int trueBranch = 0, falseBranch = 0;
+        should(exec(ifThenElse(Arg1(), 
+                               (Var(trueBranch)  += Param(1), Arg2()),
+                               (Var(falseBranch) += Param(1), Arg3())), 
+                    true, 1, 2) == 1);
+        should(exec(ifThenElse(Arg1(), 
+                               (Var(trueBranch)  += Param(1), Arg2()),
+                               (Var(falseBranch) += Param(1), Arg3())), 
+                    true, 3.5, 2) == 3.5);
+        should(exec(ifThenElse(Arg1(), 
+                               (Var(trueBranch)  += Param(1), Arg2()),
+                               (Var(falseBranch) += Param(1), Arg3())), 
+                    false, 1, 2) == 2);
+        shouldEqual(trueBranch, 2);
+        shouldEqual(falseBranch, 1);
+    }
+    
+    void testUnary()
+    {
+        shouldEqual(exec(sq(Arg1()), 7.0) , vigra::sq(7.0)); 
+        shouldEqual(exec(sqrt(Arg1()), 7.0) , VIGRA_CSTD::sqrt(7.0)); 
+        shouldEqual(exec(exp(Arg1()), 4.0) , VIGRA_CSTD::exp(4.0)); 
+        shouldEqual(exec(log(Arg1()), 4.0) , VIGRA_CSTD::log(4.0)); 
+        shouldEqual(exec(log10(Arg1()), 4.0) , VIGRA_CSTD::log10(4.0)); 
+        shouldEqual(exec(sin(Arg1()), 4.0) , VIGRA_CSTD::sin(4.0)); 
+        shouldEqual(exec(asin(Arg1()), 0.5) , VIGRA_CSTD::asin(0.5)); 
+        shouldEqual(exec(cos(Arg1()), 4.0) , VIGRA_CSTD::cos(4.0)); 
+        shouldEqual(exec(acos(Arg1()), 0.5) , VIGRA_CSTD::acos(0.5)); 
+        shouldEqual(exec(tan(Arg1()), 4.0) , VIGRA_CSTD::tan(4.0)); 
+        shouldEqual(exec(atan(Arg1()), 0.5) , VIGRA_CSTD::atan(0.5)); 
+        shouldEqual(exec(abs(Arg1()), -0.5) , 0.5); 
+        shouldEqual(exec(norm(Arg1()), -0.5) , 0.5); 
+        shouldEqual(exec(squaredNorm(Arg1()), -0.5) , 0.25); 
+        shouldEqual(exec(floor(Arg1()), -0.5) , -1.0); 
+        shouldEqual(exec(ceil(Arg1()), 0.5) , 1.0); 
+        shouldEqual(exec(-Arg1(), -0.5) , 0.5); 
+        shouldEqual(exec(!Arg1(), true) , false); 
+        shouldEqual(exec(~Arg1(),(vigra::UInt32)0xff) , (vigra::UInt32)0xffffff00); 
+    }
+    
+    void testBinary()
+    {
+        should(exec(Arg1() + Arg2(), 1, 2.5) == 3.5); 
+        should(exec(Arg1() - Arg2(), 1, 2.5) == -1.5); 
+        should(exec(Arg1() * Arg2(), 1, 2.5) == 2.5); 
+        should(exec(Arg1() / Arg2(), 1, 2.0) == 0.5); 
+        should(exec(Arg1() == Arg2(), 1, 2.0) == false); 
+        should(exec(Arg1() != Arg2(), 1, 2.0) == true); 
+        should(exec(Arg1() < Arg2(), 1, 2.0) == true); 
+        should(exec(Arg1() <= Arg2(), 1, 2.0) == true); 
+        should(exec(Arg1() > Arg2(), 1, 2.0) == false); 
+        should(exec(Arg1() >= Arg2(), 1, 2.0) == false); 
+        should(exec(Arg1() && Arg2(), true, true) == true); 
+        should(exec(Arg1() || Arg2(), true, false) == true); 
+        should(exec(Arg1() & Arg2(), 0xff, 0xf) == 0xf); 
+        should(exec(Arg1() | Arg2(), 0xff, 0xf) == 0xff); 
+        should(exec(Arg1() ^ Arg2(), 0xff, 0xf) == 0xf0); 
+        should(exec(pow(Arg1(), Arg2()), 2.0, 3) == VIGRA_CSTD::pow(2.0, 3.0)); 
+        shouldEqualTolerance(exec(atan2(Arg1(), Arg2()), 2.0, 3.0), VIGRA_CSTD::atan2(2.0, 3.0), 1e-16); 
+        should(exec(fmod(Arg1(), Arg2()), 2.0, 3.0) == VIGRA_CSTD::fmod(2.0, 3.0)); 
+        should(exec(min(Arg1(), Arg2()), 2, 3.5) == 2.0); 
+        should(exec(max(Arg1(), Arg2()), 2, 3.5) == 3.5); 
+    }
+    
+    void testCombine()
+    {
+        should(exec(sqrt(Arg1() * Arg2() + Arg3()), 1.5, 2, 1) == 2.0);
+    }
+    
+    void testComma()
+    {
+        double v1 = 0.0;
+        int v2 = 0;
+        bool v3 = false;
+        
+        exec((Var(v1) = Arg1(), Var(v2) = Arg2(), Var(v3) = Arg3()),
+             1.5, 2, true);
+        should(v1 == 1.5);
+        should(v2 == 2);
+        should(v3 == true);
+        
+        should(exec((Var(v1) = Arg3(), Arg2()), true, 2.5, 3.5) == 2.5);
+        should(v1 == 3.5);
+        
+        double count = 0.0;
+        should(exec((Var(count) += Param(1), Var(count))) == 1.0);
+    }
+    
+    void testApply()
+    {
+        should(exec(applyFct((double (*)(double))&VIGRA_CSTD::sqrt, Arg1()), 4.0) == 2.0); 
+        should(exec(applyFct((double (*)(double, double))&VIGRA_CSTD::pow, 
+                             Arg1(), Arg2()), 4.0, 2) == 16.0); 
+    }
+    
+    void testSequence()
+    {
+        unsigned char data[] = { 1, 2, 3, 4, 5, 250};
+        int res[6];
+        int sum = 0;
+        int count = 0;
+        
+        std::for_each(data, data+6, 
+        (
+            Var(count) += Param(1),
+            Var(sum) += Arg1()
+        ));
+        
+        should(count == 6); 
+        should(sum == 265); 
+        
+        std::transform(data, data+6, res,
+        (
+            Var(count) = Var(count) - Param(1),
+            Param(2) * Arg1()
+        ));
+        
+        should(count == 0); 
+        
+        for(int i=0; i<6; ++i) should(res[i] == 2*data[i]);
+    }
+};
+
+struct FunctorRGBExpressionTest
+{    
+    vigra::RGBValue<double> v1_5, v2_5, v3_0, v_1_5;
+    vigra::RGBValue<int> v0, v1, v2;
+    
+    FunctorRGBExpressionTest()
+    : v1_5(1.5),
+      v2_5(2.5),
+      v3_0(3.0),
+      v_1_5(-1.5),
+      v0(0),
+      v1(1),
+      v2(2)
+    {}
+    
+    void testArg1()
+    {
+        should(exec(Arg1(), v1_5) == v1_5); 
+        should(exec(Arg1(), v1_5, v2) == v1_5); 
+        should(exec(Arg1(), v1_5, v2, true) == v1_5); 
+    }
+    
+    void testArg2()
+    {
+        should(exec(Arg2(), v1, v2_5) == v2_5); 
+        should(exec(Arg2(), v1, v2_5, false) == v2_5);
+    }
+    
+    void testArg3()
+    {
+        should(exec(Arg3(), 1, true, v2_5) == v2_5); 
+    }
+
+    void testParam()
+    {
+        should(exec(Param(v2_5), 1) == v2_5); 
+        should(exec(Param(v2_5), 1, true) == v2_5); 
+        should(exec(Param(v2_5), 1, true, 3) == v2_5); 
+    }
+    
+    void testVar()
+    {
+        should(exec(Var(v2_5), 1) == v2_5); 
+        should(exec(Var(v2_5), 1, true) == v2_5); 
+        should(exec(Var(v2_5), 1, true, 3) == v2_5); 
+    }
+    
+    void testAssignment()
+    {
+        vigra::RGBValue<double> v(0.0);
+        exec(Var(v) = Arg1(), v1_5);
+        should(v == v1_5);
+        exec(Var(v) = Arg2(), 1, v2_5);
+        should(v == v2_5);
+        exec(Var(v) = Arg3(), 1, 2, v1_5);
+        should(v == v1_5);
+        exec(Var(v) += Arg1(), v1);
+        should(v == v2_5);
+        exec(Var(v) -= Arg1(), v1);
+        should(v == v1_5);
+        exec(Var(v) *= Arg1(), 2.0);
+        should(v == v3_0);
+        exec(Var(v) /= Arg1(), 2.0);
+        should(v == v1_5);
+        exec(Var(v) *= Arg1(), v2);
+        should(v == v3_0);
+    }
+    
+    void testIfThen()
+    {
+        vigra::RGBValue<double> v(v3_0);
+        exec(ifThen(Arg1(), Var(v) = Param(v1_5)), false);
+        should(v == v3_0);
+        exec(ifThen(Arg1(), Var(v) = Param(v1_5)), true);
+        should(v == v1_5);
+        exec(ifThen(Arg2(), Var(v) = Arg1()), v2_5, false);
+        should(v == v1_5);
+        exec(ifThen(Arg2(), Var(v) = Arg1()), v2_5, true);
+        should(v == v2_5);
+        exec(ifThen(Arg3(), Var(v) = Arg2()), 1, v1_5, false);
+        should(v == v2_5);
+        exec(ifThen(Arg3(), Var(v) = Arg2()), 1, v1_5, true);
+        should(v == v1_5);
+    }
+    
+    void testIfThenElse()
+    {
+        should(exec(ifThenElse(Arg1(), Arg2(), Arg3()), true, v2, v1_5) == v2); 
+        should(exec(ifThenElse(Arg1(), Arg2(), Arg3()), false, v2, v1_5) == v1_5); 
+    }
+    
+    void testUnary()
+    {
+        should(exec(abs(Arg1()), v_1_5) == v1_5); 
+        should(exec(floor(Arg1()), vigra::RGBValue<double>(1.4)) == v1); 
+        should(exec(ceil(Arg1()), vigra::RGBValue<double>(1.6)) == v2); 
+        should(exec(-Arg1(), v_1_5) == v1_5); 
+    }
+    
+    void testBinary()
+    {
+        should(exec(Arg1() + Arg2(), v1, v1_5) == v2_5); 
+        should(exec(Arg1() - Arg2(), v2_5, v1) == v1_5); 
+        should(exec(Arg1() * Arg2(), v2, v1_5) == v3_0); 
+        should(exec(Arg1() * Arg2(), v1_5, 2.0) == v3_0); 
+        should(exec(Arg1() * Arg2(), 2.0, v1_5) == v3_0); 
+        should(exec(Arg1() / Arg2(), v3_0, 2.0) == v1_5); 
+        should(exec(Arg1() == Arg2(), v1, v1_5) == false); 
+        should(exec(Arg1() != Arg2(), v1, v1_5) == true); 
+    }
+    
+    void testCombine()
+    {
+        should(exec((Arg1() * Arg2() + Arg3()) / Param(2.0), v1_5, v2, v1) == v2);
+    }
+    
+    void testComma()
+    {
+        exec((Var(v0) = Arg1(), Var(v3_0) = Arg2()),
+             v1, v1_5);
+        should(v0 == v1);
+        should(v3_0 == v1_5);
+        
+        should(exec((Var(v0) = Arg2(), Arg3()), true, v2, v2_5) == v2_5);
+        should(v0 == v2);
+    }
+    
+    void testApply()
+    {
+        should(exec(applyFct(
+          (vigra::RGBValue<double> (*)(vigra::RGBValue<double> const &))&vigra::abs, Arg1()), 
+          v_1_5) == v1_5); 
+    }
+    
+    void testSequence()
+    {
+        vigra::RGBValue<int> data[] = { v0, v1, v2, vigra::RGBValue<int>(3)};
+        vigra::RGBValue<int> sum(0);
+        int count = 0;
+        
+        std::for_each(data, data+4, 
+        (
+            Var(count) += Param(1),
+            Var(sum) += Arg1()
+        ));
+        
+        should(count == 4); 
+        should(sum == vigra::RGBValue<int>(6)); 
+    }  
+};
+
+struct FunctorTestSuite
+: public vigra::test_suite
+{
+    FunctorTestSuite()
+    : vigra::test_suite("FunctorTestSuite")
+    {
+        add( testCase(&FunctorExpressionTest::testArg1));
+        add( testCase(&FunctorExpressionTest::testArg2));
+        add( testCase(&FunctorExpressionTest::testArg3));
+        add( testCase(&FunctorExpressionTest::testParam));
+        add( testCase(&FunctorExpressionTest::testVar));
+        add( testCase(&FunctorExpressionTest::testAssignment));
+        add( testCase(&FunctorExpressionTest::testIfThen));
+        add( testCase(&FunctorExpressionTest::testIfThenElse));
+        add( testCase(&FunctorExpressionTest::testUnary));
+        add( testCase(&FunctorExpressionTest::testBinary));
+        add( testCase(&FunctorExpressionTest::testCombine));
+        add( testCase(&FunctorExpressionTest::testComma));
+        add( testCase(&FunctorExpressionTest::testApply));
+        add( testCase(&FunctorExpressionTest::testSequence));
+
+        add( testCase(&FunctorRGBExpressionTest::testArg1));
+        add( testCase(&FunctorRGBExpressionTest::testArg2));
+        add( testCase(&FunctorRGBExpressionTest::testArg3));
+        add( testCase(&FunctorRGBExpressionTest::testParam));
+        add( testCase(&FunctorRGBExpressionTest::testVar));
+        add( testCase(&FunctorRGBExpressionTest::testAssignment));
+        add( testCase(&FunctorRGBExpressionTest::testIfThen));
+        add( testCase(&FunctorRGBExpressionTest::testIfThenElse));
+        add( testCase(&FunctorRGBExpressionTest::testUnary));
+        add( testCase(&FunctorRGBExpressionTest::testBinary));
+        add( testCase(&FunctorRGBExpressionTest::testCombine));
+        add( testCase(&FunctorRGBExpressionTest::testComma));
+        add( testCase(&FunctorRGBExpressionTest::testApply));
+        add( testCase(&FunctorRGBExpressionTest::testSequence));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    FunctorTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+
+    return (failed != 0);
+}
diff --git a/test/gridgraph/CMakeLists.txt b/test/gridgraph/CMakeLists.txt
new file mode 100644
index 0000000..1a4a2f6
--- /dev/null
+++ b/test/gridgraph/CMakeLists.txt
@@ -0,0 +1,13 @@
+VIGRA_ADD_TEST(test_gridgraph test.cxx)
+
+if(WITH_BOOST_GRAPH)
+    VIGRA_ADD_TEST(test_gridgraph_BGL test.cxx LIBRARIES ${Boost_GRAPH_LIBRARY})
+    INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
+    SET_TARGET_PROPERTIES(test_gridgraph_BGL PROPERTIES COMPILE_FLAGS "-DWITH_BOOST_GRAPH")
+endif()
+
+if(WITH_LEMON)
+    VIGRA_ADD_TEST(test_gridgraph_LEMON test.cxx LIBRARIES ${LEMON_LIBRARY})
+    INCLUDE_DIRECTORIES(${LEMON_INCLUDE_DIR})
+    SET_TARGET_PROPERTIES(test_gridgraph_LEMON PROPERTIES COMPILE_FLAGS "-DWITH_LEMON")
+endif()
diff --git a/test/gridgraph/test.cxx b/test/gridgraph/test.cxx
new file mode 100644
index 0000000..fb7cd49
--- /dev/null
+++ b/test/gridgraph/test.cxx
@@ -0,0 +1,1276 @@
+/************************************************************************/
+/*                                                                      */
+/*              Copyright 2012-2013 by Ullrich Koethe                   */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define VIGRA_CHECK_BOUNDS
+#include "vigra/unittest.hxx"
+#include <vigra/multi_shape.hxx>
+#include <vigra/multi_iterator.hxx>
+#include <vigra/multi_array.hxx>
+#include <vigra/multi_gridgraph.hxx>
+#include <vigra/multi_localminmax.hxx>
+#include <vigra/algorithm.hxx>
+
+#ifdef WITH_BOOST_GRAPH
+#  include <boost/graph/graph_concepts.hpp>
+#endif
+
+
+using namespace vigra;
+
+template <unsigned int N>
+struct NeighborhoodTests
+{
+    typedef typename MultiArrayShape<N>::type Shape;
+    
+    ArrayVector<Shape> neighborOffsets;
+    ArrayVector<ArrayVector<bool> > neighborExists;
+    ArrayVector<ArrayVector<Shape> > relativeOffsets, backOffsets, forwardOffsets;
+    ArrayVector<ArrayVector<GridGraphArcDescriptor<N> > > edgeDescrOffsets, backEdgeDescrOffsets, forwardEdgeDescrOffsets;
+    ArrayVector<ArrayVector<MultiArrayIndex> > neighborIndices, backIndices, forwardIndices;
+
+    NeighborhoodTests()
+    {}
+    
+    void testVertexIterator()
+    {
+        typedef typename MultiArrayShape<N>::type Shape;
+        
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();
+        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            Shape s = *i+Shape(1);
+            MultiCoordinateIterator<N> vi(s), viend = vi.getEndIterator();
+            
+            MultiArray<N, int> vertex_map(s);
+
+            for(; vi != viend; ++vi)
+            {
+                should(vi.isValid() && !vi.atEnd());
+                vertex_map[*vi] += 1;
+            }
+            
+            should(!vi.isValid() && vi.atEnd());
+            
+            // check that all vertice are found
+            int min = NumericTraits<int>::max(), max = NumericTraits<int>::min();
+            vertex_map.minmax(&min, &max);
+            
+            shouldEqual(min, 1);
+            shouldEqual(max, 1);
+        }
+    }   
+    
+    void testDirectNeighborhood()
+    {
+        detail::makeArrayNeighborhood(neighborOffsets, neighborExists, DirectNeighborhood);
+        
+        static const unsigned int neighborCount = 2*N;
+        shouldEqual(neighborOffsets.size(), neighborCount);
+        shouldEqual((GridGraphMaxDegree<N, DirectNeighborhood>::value), neighborCount);
+        shouldEqual(gridGraphMaxDegree(N, DirectNeighborhood), neighborCount);
+        
+        Shape pos, neg, strides = cumprod(Shape(3)) / 3;
+        for(int k=0; k<neighborCount; ++k)
+        {
+            shouldEqual(sum(abs(neighborOffsets[k])), 1); // test that it is a direct neighbor 
+            
+            if(k < neighborCount/2)
+            {
+                should(dot(strides, neighborOffsets[k]) < 0); // check that causal neighbors are first
+                neg += neighborOffsets[k];                    // check that all causal neighbors are found
+            }
+            else
+            {
+                should(dot(strides, neighborOffsets[k]) > 0); // check that anti-causal neighbors are last
+                pos += neighborOffsets[k];                    // check that all anti-causal neighbors are found
+            }
+            
+            shouldEqual(neighborOffsets[k], -neighborOffsets[neighborCount-1-k]); // check index of opposite neighbor
+        }
+        
+        shouldEqual(pos, Shape(1));   // check that all causal neighbors were found
+        shouldEqual(neg, Shape(-1));  // check that all anti-causal neighbors were found
+        
+        shouldEqual(neighborExists.size(), (MetaPow<2, 2*N>::value));
+        MultiArray<1, unsigned char> checkNeighborCodes(Shape1(neighborExists.size()), (unsigned char)0);
+
+        // check neighborhoods at ROI border
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();
+        MultiArray<N, int> a(Shape(3));
+        typedef typename MultiArray<N, int>::view_type View;
+        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            View va = a.subarray(Shape(), *i+Shape(1)); 
+            
+            // check neighborhood of all pixels
+            typename View::iterator vi = va.begin(), viend = vi.getEndIterator();
+            for(; vi != viend; ++vi)
+            {
+                int borderType = vi.borderType();
+                
+                shouldEqual(neighborExists[borderType].size(), neighborCount);
+                checkNeighborCodes[borderType] = 1;
+                
+                for(int k=0; k<neighborCount; ++k)
+                {
+                    // check that neighbors are correctly marked as inside or outside in neighborExists
+                    shouldEqual(va.isInside(vi.point()+neighborOffsets[k]), neighborExists[borderType][k]);
+                }
+            }
+        }
+        
+        should(checkNeighborCodes.all()); // check that all possible neighborhoods have been tested
+    }
+    
+    void testIndirectNeighborhood()
+    {
+        detail::makeArrayNeighborhood(neighborOffsets, neighborExists, IndirectNeighborhood);
+        
+        MultiArray<N, int> a(Shape(3));
+        Shape center(1), strides = cumprod(Shape(3)) / 3;
+        a[center] = 1;              
+        
+        static const unsigned int neighborCount = MetaPow<3, N>::value - 1;
+        shouldEqual(neighborOffsets.size(), neighborCount);
+        shouldEqual((GridGraphMaxDegree<N, IndirectNeighborhood>::value), neighborCount);
+        shouldEqual(gridGraphMaxDegree(N, IndirectNeighborhood), neighborCount);
+        
+        for(int k=0; k<neighborCount; ++k)
+        {
+            shouldEqual(abs(neighborOffsets[k]).maximum(), 1); // check that offset is at most 1 in any direction
+                 
+            if(k < neighborCount/2)
+                should(dot(strides, neighborOffsets[k]) < 0); // check that causal neighbors are first
+            else
+                should(dot(strides, neighborOffsets[k]) > 0); // check that anti-causal neighbors are last
+
+            shouldEqual(neighborOffsets[k], -neighborOffsets[neighborCount-1-k]); // check index of opposite neighbor
+            
+            a[center+neighborOffsets[k]] += 1;  // check that all neighbors are found
+        }
+        
+        // check that all neighbors are found
+        int min = NumericTraits<int>::max(), max = NumericTraits<int>::min();
+        a.minmax(&min, &max);
+        
+        shouldEqual(min, 1);
+        shouldEqual(max, 1);
+        
+        shouldEqual(neighborExists.size(), (MetaPow<2, 2*N>::value));
+        MultiArray<1, unsigned char> checkNeighborCodes(Shape1(neighborExists.size()), (unsigned char)0);
+
+        // check neighborhoods at ROI border
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();
+        typedef typename MultiArray<N, int>::view_type View;
+        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            View va = a.subarray(Shape(), *i +Shape(1));
+            
+            // check neighborhood of all pixels
+            typename View::iterator vi = va.begin(), viend = vi.getEndIterator();
+            for(; vi != viend; ++vi)
+            {
+                int borderType = vi.borderType();
+                
+                shouldEqual(neighborExists[borderType].size(), neighborCount);
+                checkNeighborCodes[borderType] = 1;
+                
+                for(int k=0; k<neighborCount; ++k)
+                {
+                    // check that neighbors are correctly marked as inside or outside in neighborExists
+                    shouldEqual(va.isInside(vi.point()+neighborOffsets[k]), neighborExists[borderType][k]);
+                }
+            }
+        }
+        
+        should(checkNeighborCodes.all()); // check that all possible neighborhoods have been tested
+    }
+    
+    template <NeighborhoodType NType>
+    void testNeighborhoodIterator()
+    {
+        detail::makeArrayNeighborhood(neighborOffsets, neighborExists, NType);
+        detail::computeNeighborOffsets(neighborOffsets, neighborExists, relativeOffsets, edgeDescrOffsets, neighborIndices, backIndices, true);
+        
+        // check neighborhoods at ROI border
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();
+        MultiArray<N, int> a(Shape(3));
+        typedef typename MultiArray<N, int>::view_type View;
+        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            View va = a.subarray(Shape(), *i+Shape(1)); 
+            
+            // check neighborhood of all pixels
+            typename View::iterator vi = va.begin(), viend = vi.getEndIterator();
+            for(; vi != viend; ++vi)
+            {
+                int borderType = vi.borderType();
+                
+                {
+                    GridGraphNeighborIterator<N> ni(relativeOffsets[borderType], 
+                                                    neighborIndices[borderType], 
+                                                    backIndices[borderType], 
+                                                    vi.point()),
+                                                 nend = ni.getEndIterator();
+                    
+                    for(int k=0; k<neighborExists[borderType].size(); ++k)
+                    {
+                        if(neighborExists[borderType][k])
+                        {
+                            should(ni.isValid() && !ni.atEnd());
+                            shouldEqual(vi.point()+neighborOffsets[k], *ni);
+                            ++ni;
+                        }
+                    }
+                    should(ni == nend);
+                    should(ni.atEnd() && !ni.isValid());
+                }
+                
+                {
+                    GridGraphNeighborIterator<N, true> ni(relativeOffsets[borderType], 
+                                                          neighborIndices[borderType], 
+                                                          backIndices[borderType], 
+                                                          vi.point()),
+                                                       nend = ni.getEndIterator();
+                    
+                    for(int k=0; k<neighborExists[borderType].size()/2; ++k)
+                    {
+                        if(neighborExists[borderType][k])
+                        {
+                            should(ni.isValid() && !ni.atEnd());
+                            shouldEqual(vi.point()+neighborOffsets[k], *ni);
+                            ++ni;
+                        }
+                    }
+                    should(ni == nend);
+                    should(ni.atEnd() && !ni.isValid());
+                }
+            }
+        }
+    }
+    
+    template <NeighborhoodType NType>
+    void testOutArcIteratorDirected()
+    {
+        detail::makeArrayNeighborhood(neighborOffsets, neighborExists, NType);
+        detail::computeNeighborOffsets(neighborOffsets, neighborExists, relativeOffsets, edgeDescrOffsets, neighborIndices, backIndices, true);
+
+        // check neighborhoods at ROI border
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();
+        MultiArray<N, int> a(Shape(3));
+        typedef typename MultiArray<N, int>::view_type View;
+        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            View va = a.subarray(Shape(), *i+Shape(1)); 
+            
+            // check neighborhood of all pixels
+            typename View::iterator vi = va.begin(), viend = vi.getEndIterator();
+            for(; vi != viend; ++vi)
+            {
+                int borderType = vi.borderType();
+                
+                {
+                    GridGraphOutArcIterator<N, false> ni(edgeDescrOffsets[borderType], 
+                                                         neighborIndices[borderType], 
+                                                         backIndices[borderType], 
+                                                         vi.point()),
+                                                      nend = ni.getEndIterator();
+                    
+                    for(int k=0; k<neighborExists[borderType].size(); ++k)
+                    {
+                        if(neighborExists[borderType][k])
+                        {
+                            should(ni.isValid() && !ni.atEnd());
+                            shouldEqual(vi.point(), ni->vertexDescriptor());
+                            shouldEqual(k, ni->edgeIndex());
+                            shouldEqual(k, ni.neighborIndex());
+                            should(!ni->isReversed());
+                            ++ni;
+                        }
+                    }
+                    should(ni == nend);
+                    should(ni.atEnd() && !ni.isValid());
+                }
+                        
+                {
+                    GridGraphOutArcIterator<N, true> ni(edgeDescrOffsets[borderType], 
+                                                        neighborIndices[borderType], 
+                                                        backIndices[borderType], 
+                                                        vi.point()),
+                                                     nend = ni.getEndIterator();
+                    
+                    for(int k=0; k<neighborExists[borderType].size()/2; ++k)
+                    {
+                        if(neighborExists[borderType][k])
+                        {
+                            should(ni.isValid() && !ni.atEnd());
+                            shouldEqual(vi.point(), ni->vertexDescriptor());
+                            shouldEqual(k, ni->edgeIndex());
+                            shouldEqual(k, ni.neighborIndex());
+                            should(!ni->isReversed());
+                            ++ni;
+                        }
+                    }
+                    should(ni == nend);
+                    should(ni.atEnd() && !ni.isValid());
+                }
+            }
+        }
+    }
+    
+    template <NeighborhoodType NType>
+    void testOutArcIteratorUndirected()
+    {
+        detail::makeArrayNeighborhood(neighborOffsets, neighborExists, NType);
+        detail::computeNeighborOffsets(neighborOffsets, neighborExists, relativeOffsets, edgeDescrOffsets, neighborIndices, backIndices, false);
+
+        // check neighborhoods at ROI border
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();
+        MultiArray<N, int> a(Shape(3));
+        typedef typename MultiArray<N, int>::view_type View;
+        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            View va = a.subarray(Shape(), *i+Shape(1)); 
+            
+            // check neighborhood of all pixels
+            typename View::iterator vi = va.begin(), viend = vi.getEndIterator();
+            for(; vi != viend; ++vi)
+            {
+                int borderType = vi.borderType();
+                
+                {
+                    GridGraphOutArcIterator<N> ni(edgeDescrOffsets[borderType], 
+                                                  neighborIndices[borderType], 
+                                                  backIndices[borderType], 
+                                                  vi.point()),
+                                                nend = ni.getEndIterator();
+                    
+                    for(int k=0; k<neighborExists[borderType].size(); ++k)
+                    {
+                        if(neighborExists[borderType][k])
+                        {
+                            should(ni.isValid() && !ni.atEnd());
+                            shouldEqual(k, ni.neighborIndex());
+                            if(k < neighborExists[borderType].size() / 2)
+                            {
+                                shouldEqual(vi.point(), ni->vertexDescriptor());
+                                shouldEqual(k, ni->edgeIndex());
+                                should(!ni->isReversed());
+                            }
+                            else
+                            {
+                                shouldEqual(vi.point()+neighborOffsets[k], ni->vertexDescriptor());
+                                shouldEqual(k, (int)neighborOffsets.size() - ni->edgeIndex() - 1);
+                                should(ni->isReversed());
+                            }
+                            ++ni;
+                        }
+                    }
+                    should(ni == nend);
+                    should(ni.atEnd() && !ni.isValid());
+                }
+                        
+                {
+                    GridGraphOutArcIterator<N, true> ni(edgeDescrOffsets[borderType], 
+                                                        neighborIndices[borderType], 
+                                                        backIndices[borderType], 
+                                                        vi.point()),
+                                                     nend = ni.getEndIterator();
+                    
+                    for(int k=0; k<neighborExists[borderType].size()/2; ++k)
+                    {
+                        if(neighborExists[borderType][k])
+                        {
+                            should(ni.isValid() && !ni.atEnd());
+                            shouldEqual(k, ni.neighborIndex());
+                            shouldEqual(vi.point(), ni->vertexDescriptor());
+                            shouldEqual(k, ni->edgeIndex());
+                            should(!ni->isReversed());
+                            ++ni;
+                        }
+                    }
+                    should(ni == nend);
+                    should(ni.atEnd() && !ni.isValid());
+                }
+            }
+        }
+    }
+    
+    template <NeighborhoodType NType>
+    void testArcIteratorDirected()
+    {
+        detail::makeArrayNeighborhood(neighborOffsets, neighborExists, NType);
+        detail::computeNeighborOffsets(neighborOffsets, neighborExists, relativeOffsets, edgeDescrOffsets, neighborIndices, backIndices, true);
+
+        // check neighborhoods at ROI border
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();
+        typedef typename MultiArrayShape<N+1>::type EdgeMapShape;
+        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            Shape s = *i + Shape(1);
+            
+            EdgeMapShape es(gridGraphMaxDegree(N, NType));
+            es.template subarray<0,N>() = s;
+            MultiArray<N+1, int> edge_map(es);
+            
+            GridGraphArcIterator<N, false> ni(edgeDescrOffsets, neighborIndices, backIndices, s),
+                                           nend = ni.getEndIterator();
+            
+            for(; ni != nend; ++ni)
+            {
+                should(ni.isValid() && !ni.atEnd());
+                edge_map[*ni] += 1;
+            }
+            
+            should(!ni.isValid() && ni.atEnd());
+                
+            // check neighborhood of all pixels
+            MultiCoordinateIterator<N> vi(s), viend = vi.getEndIterator();
+            for(; vi != viend; ++vi)
+            {
+                int borderType = vi.borderType();
+                es.template subarray<0,N>() = *vi;
+                
+                for(es[N]=0; es[N]<(MultiArrayIndex)neighborExists[borderType].size(); ++es[N])
+                {
+                    if(neighborExists[borderType][es[N]])
+                        shouldEqual(edge_map[es], 1);
+                    else
+                        shouldEqual(edge_map[es], 0);
+                }
+            }
+            
+            shouldEqual(edge_map.template sum<int>(), gridGraphEdgeCount(s, NType, true));
+        }
+    }
+    
+    template <NeighborhoodType NType>
+    void testArcIteratorUndirected()
+    {
+        detail::makeArrayNeighborhood(neighborOffsets, neighborExists, NType);
+        detail::computeNeighborOffsets(neighborOffsets, neighborExists, relativeOffsets, edgeDescrOffsets, neighborIndices, backIndices, false);
+
+        // check neighborhoods at ROI border
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();
+        typedef typename MultiArrayShape<N+1>::type EdgeMapShape;
+        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            Shape s = *i + Shape(1);
+            
+            EdgeMapShape es(gridGraphMaxDegree(N, NType) / 2);
+            es.template subarray<0,N>() = s;
+            MultiArray<N+1, int> edge_map(es);
+            
+            GridGraphArcIterator<N, true> ni(edgeDescrOffsets, neighborIndices, backIndices, s),
+                                          nend = ni.getEndIterator();
+            
+            for(; ni != nend; ++ni)
+            {
+                should(ni.isValid() && !ni.atEnd());
+                edge_map[*ni] += 1;
+            }
+            
+            should(!ni.isValid() && ni.atEnd());
+                
+            // check neighborhood of all pixels
+            MultiCoordinateIterator<N> vi(s), viend = vi.getEndIterator();
+            for(; vi != viend; ++vi)
+            {
+                int borderType = vi.borderType();
+                es.template subarray<0,N>() = *vi;
+                
+                for(es[N]=0; es[N]<(MultiArrayIndex)neighborExists[borderType].size()/2; ++es[N])
+                {
+                    if(neighborExists[borderType][es[N]])
+                        shouldEqual(edge_map[es], 1);
+                    else
+                        shouldEqual(edge_map[es], 0);
+                }
+            }
+            
+            shouldEqual(edge_map.template sum<int>(), gridGraphEdgeCount(s, NType, false));
+        }
+    }
+};
+
+template <unsigned int N>
+struct GridGraphTests
+{
+    typedef typename MultiArrayShape<N>::type Shape;
+    
+    template <class DirectedTag, NeighborhoodType NType>
+    void testBasics()
+    {
+        using namespace boost;
+        typedef GridGraph<N, DirectedTag> G;
+        
+        static const bool directed = IsSameType<DirectedTag, directed_tag>::value;
+        
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            Shape s = *i + Shape(1);
+            G g(s, NType);
+            
+#ifdef WITH_LEMON
+            shouldEqual(directed, !lemon::UndirectedTagIndicator<G>::value);
+#endif
+            
+            should(typename G::vertex_descriptor(lemon::INVALID) == lemon::INVALID);
+            should(typename G::edge_descriptor(lemon::INVALID) == lemon::INVALID);
+        
+            shouldEqual(g.shape(), s);
+            shouldEqual(g.isDirected(), directed);
+            shouldEqual(g.num_vertices(), prod(s));
+            shouldEqual(num_vertices(g), prod(s));
+            shouldEqual(g.num_edges(), gridGraphEdgeCount(s, NType, directed));
+            shouldEqual(num_edges(g), gridGraphEdgeCount(s, NType, directed));
+            shouldEqual(g.maxDegree(), gridGraphMaxDegree(N, NType));
+            
+            shouldEqual(g.num_vertices(), g.nodeNum());
+            shouldEqual(g.num_edges(), g.edgeNum());
+            shouldEqual(g.arcNum(), directed ? g.edgeNum() : 2*g.edgeNum());
+        }
+#ifdef WITH_BOOST_GRAPH
+        BOOST_CONCEPT_ASSERT(( boost::GraphConcept<G> ));
+        BOOST_CONCEPT_ASSERT(( boost::IncidenceGraphConcept<G> ));
+        BOOST_CONCEPT_ASSERT(( boost::BidirectionalGraphConcept<G> ));
+        BOOST_CONCEPT_ASSERT(( boost::AdjacencyGraphConcept<G> ));
+        BOOST_CONCEPT_ASSERT(( boost::VertexListGraphConcept<G> ));
+        BOOST_CONCEPT_ASSERT(( boost::EdgeListGraphConcept<G> ));
+        BOOST_CONCEPT_ASSERT(( boost::AdjacencyMatrixConcept<G> ));
+#endif
+    }
+    
+    template <class DirectedTag, NeighborhoodType NType>
+    void testVertexIterator()
+    {
+        using namespace boost;
+        
+        typedef GridGraph<N, DirectedTag> Graph;
+
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            Shape s = *i + Shape(1);
+            Graph g(s, NType);
+            typename Graph::template NodeMap<int> vertexMap(g);
+            lemon::InDegMap<Graph>  inDegreeMap(g);
+            lemon::OutDegMap<Graph> outDegreeMap(g);
+            typename Graph::IndexMap indexMap(g.indexMap());
+        
+            int count = 0;
+        
+            typename Graph::vertex_iterator j = g.get_vertex_iterator(), 
+                                            end = g.get_vertex_end_iterator();
+            typename Graph::NodeIt lj(g);
+                                            
+            should(j == vertices(g).first);
+            should(end == vertices(g).second);
+            should(j == typename Graph::vertex_iterator(g));
+            for(; j != end; ++j, ++lj, ++count)
+            {
+                should(j.isValid() && !j.atEnd());
+                should(j == lj);
+                should(j != lemon::INVALID);
+                should(!(j == lemon::INVALID));
+                
+                shouldEqual(j.scanOrderIndex(), g.id(j));
+                shouldEqual(j.scanOrderIndex(), g.id(*j));
+                shouldEqual(*j, g.nodeFromId(g.id(*j)));
+                
+                shouldEqual(g.out_degree(j), g.out_degree(*j));
+                shouldEqual(g.out_degree(j), out_degree(*j, g));
+                shouldEqual(g.forward_degree(j), g.forward_degree(*j));
+                shouldEqual(g.back_degree(j), g.back_degree(*j));
+                shouldEqual(g.forward_degree(j) + g.back_degree(j), g.out_degree(j));
+                shouldEqual(g.in_degree(j), g.out_degree(j));
+                shouldEqual(g.degree(j), g.isDirected() ? 2*g.out_degree(j) : g.out_degree(j));
+                shouldEqual(g.out_degree(j), boost::out_degree(*j, g));
+                shouldEqual(g.in_degree(j), boost::in_degree(*j, g));
+                shouldEqual(g.out_degree(j), outDegreeMap[*j]);
+                shouldEqual(g.in_degree(j), inDegreeMap[*j]);
+
+                shouldEqual(*j, indexMap[*j]);
+
+                put(vertexMap, *j, get(vertexMap, *j) + 1); // same as: vertexMap[*j] += 1;
+            }
+            should(!j.isValid() && j.atEnd());
+            should(j == lj);
+            should(j == lemon::INVALID);
+            should(!(j != lemon::INVALID));
+            
+            // check that all vertices are found exactly once
+            shouldEqual(count, g.num_vertices());
+            int min = NumericTraits<int>::max(), max = NumericTraits<int>::min();
+            vertexMap.minmax(&min, &max);
+            
+            shouldEqual(min, 1);
+            shouldEqual(max, 1);
+        }
+    }
+    
+    template <class DirectedTag, NeighborhoodType NType>
+    void testNeighborIterator()
+    {
+        using namespace boost;
+        
+        static const bool directed = IsSameType<DirectedTag, directed_tag>::value;
+        
+        typedef GridGraph<N, DirectedTag> Graph;
+        typedef typename Graph::Node Node;
+        
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            Shape s = *i + Shape(1);
+            Graph g(s, NType);
+            
+            MultiArray<N, int> vertexMap(s);
+            typename Graph::template EdgeMap<int> edgeMap(g);
+            
+            typename Graph::template ArcMap<int> arcIdMap(g);            
+            typename Graph::template EdgeMap<int> edgeIdMap(g);            
+
+            linearSequence(arcIdMap.begin(), arcIdMap.end());
+            linearSequence(edgeIdMap.begin(), edgeIdMap.end());
+            
+            shouldEqual((edgeMap.shape().template subarray<0, N>()), s);
+            shouldEqual(edgeMap.shape(N), g.maxUniqueDegree());
+            shouldEqual((arcIdMap.shape().template subarray<0, N>()), s);
+            shouldEqual(arcIdMap.shape(N), g.maxDegree());
+            shouldEqual(edgeMap.shape(), edgeIdMap.shape());
+            
+            int totalCount = 0;
+        
+            typename Graph::vertex_iterator j = g.get_vertex_iterator(), 
+                                            end = g.get_vertex_end_iterator();
+            for(; j != end; ++j)
+            {
+                typename Graph::neighbor_vertex_iterator n = g.get_neighbor_vertex_iterator(j), 
+                                                         nend = g.get_neighbor_vertex_end_iterator(j);
+                typename Graph::out_edge_iterator        e = g.get_out_edge_iterator(j), 
+                                                         eend = g.get_out_edge_end_iterator(j);
+                typename Graph::in_edge_iterator         i = g.get_in_edge_iterator(j), 
+                                                         iend = g.get_in_edge_end_iterator(j);
+                typename Graph::IncEdgeIt                le(g, j);
+                typename Graph::OutArcIt                 la(g, j);
+                typename Graph::InArcIt                  li(g, j);
+
+                should(n == g.get_neighbor_vertex_iterator(*j));
+                should(nend == g.get_neighbor_vertex_end_iterator(*j));
+                should(n == adjacent_vertices(*j, g).first);
+                should(nend == adjacent_vertices(*j, g).second);
+                should(n == adjacent_vertices_at_iterator(j, g).first);
+                should(nend == adjacent_vertices_at_iterator(j, g).second);
+                should(e == g.get_out_edge_iterator(*j));
+                should(eend == g.get_out_edge_end_iterator(*j));
+                should(e == out_edges(*j, g).first);
+                should(eend == out_edges(*j, g).second);
+                should(i == in_edges(*j, g).first);
+                should(iend == in_edges(*j, g).second);
+
+                int count = 0;
+                for(; n != nend; ++n, ++e, ++i, ++la, ++le, ++li, ++count)
+                {
+                    should(*n != *j);
+                    should(n.isValid() && !n.atEnd());
+                    should(n != lemon::INVALID);
+                    should(!(n == lemon::INVALID));
+                    should(e.isValid() && !e.atEnd());
+                    should(e == la);
+                    should(e == le);
+                    should(e != eend);
+                    should(e != lemon::INVALID);
+                    should(!(e == lemon::INVALID));
+                    should(i != lemon::INVALID);
+                    should(!(i == lemon::INVALID));
+                    should(i == li);
+                    
+                    shouldEqual(source(*e, g), *j);
+                    shouldEqual(target(*e, g), *n);
+                    vertexMap[*n] += 1;
+                    edgeMap[*e] += 1;
+                    
+                    shouldEqual(source(*i, g), *n);
+                    shouldEqual(target(*i, g), *j);
+                    
+                    typename Graph::Arc a  = g.findArc(*j, *n),
+                                        oa = g.findArc(*n, *j);
+                    should(a == *la);
+                    shouldEqual(source(oa, g), *n);
+                    shouldEqual(target(oa, g), *j);
+                    shouldEqual(g.baseNode(la), *j);
+                    shouldEqual(g.runningNode(la), *n);
+                    shouldEqual(g.oppositeArc(a), oa);
+                    
+                    typename Graph::Edge ge = g.findEdge(*j, *n),
+                                         oe = g.findEdge(*n, *j);
+                    should(ge == *le);
+                    shouldEqual(g.baseNode(le), *j);
+                    shouldEqual(g.runningNode(le), *n);
+                    
+                    typename Graph::Node u = g.u(oe), 
+                                         v = g.v(oe);
+                    if(directed)
+                    {
+                        should(g.direction(*la));
+                        shouldEqual(g.direct(*le, true), *la);
+                        shouldEqual(g.direct(*le, false), g.oppositeArc(*la));
+                    }
+                    else
+                    {
+                        should(oe == *le);
+                        if(g.id(n) < g.id(j))
+                        {
+                            std::swap(u, v);
+                            should(g.direction(*la));
+                            shouldEqual(g.direct(*le, true), *la);
+                            shouldEqual(g.direct(*le, false), g.oppositeArc(*la));
+                        }
+                        else
+                        {
+                            should(!g.direction(*la));
+                            shouldEqual(g.direct(*le, false), *la);
+                            shouldEqual(g.direct(*le, true), g.oppositeArc(*la));
+                        }
+                    }
+
+                    shouldEqual(u, *n);
+                    shouldEqual(v, *j);
+                    shouldEqual(g.direct(*le, v), *la);
+                    shouldEqual(g.direct(*le, u), g.oppositeArc(*la));
+                    shouldEqual(g.oppositeNode(u, *le), v);
+                    shouldEqual(g.oppositeNode(v, *le), u);
+                    shouldEqual(g.oppositeNode(lemon::INVALID, *le), Node(lemon::INVALID));
+                    
+                    shouldEqual(arcIdMap[*la], g.id(la));
+                    shouldEqual(edgeIdMap[*la], g.id((typename Graph::Edge &)*la));
+                    shouldEqual(edgeIdMap[*le], g.id(*le));
+                    shouldEqual(*la, g.arcFromId(g.id(*la)));
+                    shouldEqual(*le, g.edgeFromId(g.id(*le)));
+                }
+                should(!n.isValid() && n.atEnd());
+                should(n == lemon::INVALID);
+                should(!(n != lemon::INVALID));
+                should(!e.isValid() && e.atEnd());
+                should(e == eend);
+                should(e == la);
+                should(e == le);
+                should(e == lemon::INVALID);
+                should(!(e != lemon::INVALID));
+                should(i == li);
+                should(i == iend);
+                should(i == lemon::INVALID);
+                should(!(i != lemon::INVALID));
+                
+                shouldEqual(count, g.out_degree(j));
+                
+                totalCount += count;
+            }
+            
+            // check that all neighbors are found
+            if(!directed)
+                totalCount /= 2;
+            shouldEqual(totalCount, g.num_edges());
+            
+            int min = NumericTraits<int>::max(), max = NumericTraits<int>::min();
+            edgeMap.minmax(&min, &max);
+            shouldEqual(min, 0);
+            shouldEqual(max, g.num_edges() ? !directed ? 2 : 1 : 0);
+
+            j = g.get_vertex_iterator();
+            for(; j != end; ++j)
+            {
+                shouldEqual(vertexMap[*j], g.in_degree(j));
+                if(directed)
+                    shouldEqual(edgeMap.bindInner(*j).template sum<int>(), g.out_degree(j));
+                else
+                    shouldEqual(edgeMap.bindInner(*j).template sum<int>(), 2*g.back_degree(j));
+            }
+        }
+    }
+    
+    template <class DirectedTag, NeighborhoodType NType>
+    void testBackNeighborIterator()
+    {
+        using namespace boost;
+        
+        static const bool directed = IsSameType<DirectedTag, directed_tag>::value;
+        
+        typedef GridGraph<N, DirectedTag> Graph;
+        
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            Shape s = *i + Shape(1);
+            Graph g(s, NType);
+            
+            MultiArray<N, int> vertexMap(s);
+            typename Graph::template EdgeMap<int> edgeMap(g);
+            typename Graph::template ArcMap<int> arcMap(g);
+            
+            typename Graph::template ArcMap<int> arcIdMap(g);            
+            typename Graph::template EdgeMap<int> edgeIdMap(g);            
+
+            linearSequence(arcIdMap.begin(), arcIdMap.end());
+            linearSequence(edgeIdMap.begin(), edgeIdMap.end());
+            
+            shouldEqual((edgeMap.shape().template subarray<0, N>()), s);
+            shouldEqual(edgeMap.shape(N), g.maxUniqueDegree());
+            shouldEqual((arcIdMap.shape().template subarray<0, N>()), s);
+            shouldEqual(arcIdMap.shape(N), g.maxDegree());
+            shouldEqual(edgeMap.shape(), edgeIdMap.shape());
+            
+            int totalCount = 0;
+        
+            typename Graph::vertex_iterator j = g.get_vertex_iterator(), 
+                                            end = g.get_vertex_end_iterator();
+            for(; j != end; ++j)
+            {
+                typename Graph::back_neighbor_vertex_iterator n = g.get_back_neighbor_vertex_iterator(j), 
+                                                              nend = g.get_back_neighbor_vertex_end_iterator(j);
+                typename Graph::out_back_edge_iterator        e = g.get_out_back_edge_iterator(j), 
+                                                              eend = g.get_out_back_edge_end_iterator(j);
+                typename Graph::IncBackEdgeIt                 le(g, j);
+                typename Graph::OutBackArcIt                  la(g, j);
+
+                should(n == g.get_back_neighbor_vertex_iterator(*j));
+                should(nend == g.get_back_neighbor_vertex_end_iterator(*j));
+                should(n == back_adjacent_vertices(*j, g).first);
+                should(nend == back_adjacent_vertices(*j, g).second);
+                should(e == g.get_out_back_edge_iterator(*j));
+                should(eend == g.get_out_back_edge_end_iterator(*j));
+                should(e == out_back_edges(*j, g).first);
+                should(eend == out_back_edges(*j, g).second);
+
+                int count = 0;
+                for(; n != nend; ++n, ++e, ++la, ++le, ++count)
+                {
+                    should(*n != *j);
+                    should(n.isValid() && !n.atEnd());
+                    should(n != lemon::INVALID);
+                    should(!(n == lemon::INVALID));
+                    should(e.isValid() && !e.atEnd());
+                    should(e == la);
+                    should(e == le);
+                    should(e != eend);
+                    should(e != lemon::INVALID);
+                    should(!(e == lemon::INVALID));
+                    
+                    shouldEqual(source(*e, g), *j);
+                    shouldEqual(target(*e, g), *n);
+                    vertexMap[*n] += 1;
+                    edgeMap[*e] += 1;
+                    arcMap[*la] += 1;
+                    
+                    typename Graph::Arc a  = g.findArc(*j, *n),
+                                        oa = g.findArc(*n, *j);
+                    should(a == *la);
+                    shouldEqual(source(oa, g), *n);
+                    shouldEqual(target(oa, g), *j);
+                    shouldEqual(g.baseNode(la), *j);
+                    shouldEqual(g.runningNode(la), *n);
+                    shouldEqual(g.oppositeArc(a), oa);
+                    
+                    typename Graph::Edge ge = g.findEdge(*j, *n),
+                                         oe = g.findEdge(*n, *j);
+                    should(ge == *le);
+                    shouldEqual(g.baseNode(le), *j);
+                    shouldEqual(g.runningNode(le), *n);
+                    
+                    typename Graph::Node u = g.u(oe), 
+                                         v = g.v(oe);
+                    if(!directed)
+                    {
+                        should(oe == *le);
+                        if(g.id(n) < g.id(j))
+                            std::swap(u, v);
+                    }
+                    shouldEqual(u, *n);
+                    shouldEqual(v, *j);
+                    
+                    shouldEqual(arcIdMap[*la], g.id(la));
+                    shouldEqual(edgeIdMap[*la], g.id((typename Graph::Edge &)*la));
+                    shouldEqual(edgeIdMap[*le], g.id(*le));
+                    shouldEqual(*la, g.arcFromId(g.id(*la)));
+                    shouldEqual(*le, g.edgeFromId(g.id(*le)));
+                }
+                should(!n.isValid() && n.atEnd());
+                should(n == lemon::INVALID);
+                should(!(n != lemon::INVALID));
+                should(!e.isValid() && e.atEnd());
+                should(e == eend);
+                should(e == la);
+                should(e == le);
+                should(e == lemon::INVALID);
+                should(!(e != lemon::INVALID));
+                
+                shouldEqual(count, g.back_degree(j));
+                
+                totalCount += count;
+            }
+            
+            // check that all neighbors are found
+            if(directed)
+                totalCount *= 2;
+            shouldEqual(totalCount, g.num_edges());
+            
+            int min = NumericTraits<int>::max(), max = NumericTraits<int>::min();
+            edgeMap.minmax(&min, &max);
+            shouldEqual(min, 0);
+            shouldEqual(max, g.num_edges() ? 1 : 0);
+
+            typename Graph::edge_propmap_shape_type estart, estop;
+            estop.template subarray<0,N>() = s;
+            estop[N] = g.maxDegree() / 2;
+            shouldEqualSequence(edgeMap.begin(), edgeMap.end(), arcMap.subarray(estart, estop).begin());
+            
+            estart[N] = g.maxDegree() / 2;
+            estop[N] = g.maxDegree();
+            min = NumericTraits<int>::max(), max = NumericTraits<int>::min();
+            arcMap.subarray(estart, estop).minmax(&min, &max);
+            shouldEqual(min, 0);
+            shouldEqual(max, 0);
+
+            j = g.get_vertex_iterator();
+            for(; j != end; ++j)
+            {
+                shouldEqual(vertexMap[*j], g.forward_degree(j));
+                shouldEqual(edgeMap.bindInner(*j).template sum<int>(), g.back_degree(j));
+            }
+        }
+    }
+    
+    template <class DirectedTag, NeighborhoodType NType>
+    void testEdgeIterator()
+    {
+        using namespace boost;
+        
+        static const bool directed = IsSameType<DirectedTag, directed_tag>::value;
+        
+        typedef GridGraph<N, DirectedTag> Graph;
+        
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            Shape s = *i + Shape(1);
+            Graph g(s, NType);
+            
+            MultiArray<N, int> sourceVertexMap(s),targetVertexMap(s);
+            MultiArray<N+1, int> edgeMap(g.edge_propmap_shape()),
+                                 edgeIdMap(g.edge_propmap_shape());
+            
+            shouldEqual((edgeMap.shape().template subarray<0, N>()), s);
+            shouldEqual(edgeMap.shape(N), g.maxUniqueDegree());
+            
+            linearSequence(edgeIdMap.begin(), edgeIdMap.end());
+            
+            typename Graph::edge_iterator e = g.get_edge_iterator(),
+                                          eend = g.get_edge_end_iterator();
+            typename Graph::EdgeIt el(g);
+
+            should(e == edges(g).first);
+            should(eend == edges(g).second);
+            
+            int count = 0;
+            int maxEdgeId = -1;
+            for(; e != eend; ++e, ++el, ++count)
+            {
+                should(e.isValid() && !e.atEnd());
+                should(e == el);
+                should(e != lemon::INVALID);
+                should(!(e == lemon::INVALID));
+
+                put(edgeMap, *e, get(edgeMap, *e) + 1); // same as: edgeMap[*e] += 1;
+                sourceVertexMap[source(*e, g)] += 1;
+                targetVertexMap[target(*e, g)] += 1;
+                
+                shouldEqual(edgeIdMap[*e], g.id(el));
+                shouldEqual(*el, g.edgeFromId(g.id(*el)));
+
+                if(maxEdgeId < g.id(el))
+                    maxEdgeId = g.id(el);
+            }
+            should(!e.isValid() && e.atEnd());
+            should(e == el);
+            should(e == lemon::INVALID);
+            should(!(e != lemon::INVALID));
+            
+            shouldEqual(maxEdgeId, g.maxEdgeId());
+            
+            // check that all neighbors are found
+            shouldEqual(count, g.num_edges());
+            
+            int min = NumericTraits<int>::max(), max = NumericTraits<int>::min();
+            edgeMap.minmax(&min, &max);
+            shouldEqual(min, 0);
+            shouldEqual(max, g.num_edges() ? 1 : 0);
+            
+            MultiCoordinateIterator<N> j(s), end = j.getEndIterator();
+            for(; j != end; ++j)
+            {
+                if(directed)
+                {
+                    shouldEqual(edgeMap.bindInner(*j).template sum<int>(), g.out_degree(j));
+                    shouldEqual(sourceVertexMap[*j], g.out_degree(j));
+                    shouldEqual(targetVertexMap[*j], g.out_degree(j));
+                }
+                else
+                {
+                    shouldEqual(edgeMap.bindInner(*j).template sum<int>(), g.back_degree(j));
+                    shouldEqual(sourceVertexMap[*j], g.back_degree(j));
+                    shouldEqual(targetVertexMap[*j], g.forward_degree(j));
+                }
+            }
+        }
+    }
+    
+    template <class DirectedTag, NeighborhoodType NType>
+    void testArcIterator()
+    {
+        using namespace boost;
+        
+        static const bool directed = IsSameType<DirectedTag, directed_tag>::value;
+        
+        typedef GridGraph<N, DirectedTag> Graph;
+        
+        MultiCoordinateIterator<N> i(Shape(3)), iend = i.getEndIterator();        
+        for(; i != iend; ++i)
+        {
+            // create all possible array shapes from 1**N to 3**N
+            Shape s = *i + Shape(1);
+            Graph g(s, NType);
+            
+            typename Graph::template NodeMap<int> sourceVertexMap(g), targetVertexMap(g);
+            typename Graph::template EdgeMap<int> edgeMap(g);
+            typename Graph::template ArcMap<int> arcMap(g);
+            
+            shouldEqual(sourceVertexMap.shape(), s);
+            shouldEqual(targetVertexMap.shape(), s);
+            shouldEqual((edgeMap.shape().template subarray<0, N>()), s);
+            shouldEqual(edgeMap.shape(N), g.maxUniqueDegree());
+            shouldEqual((arcMap.shape().template subarray<0, N>()), s);
+            shouldEqual(arcMap.shape(N), g.maxDegree());
+            
+            typename Graph::ArcIt e(g);
+
+            int count = 0;
+            int maxArcId = -1;
+            for(; e != lemon::INVALID; ++e, ++count)
+            {
+                should(e.isValid() && !e.atEnd());
+                should(e != lemon::INVALID);
+                should(!(e == lemon::INVALID));
+
+                sourceVertexMap[source(*e, g)] += 1;
+                targetVertexMap[target(*e, g)] += 1;
+                edgeMap[*e] += 1;
+                arcMap[*e] += 1;
+                
+                shouldEqual(*e, g.arcFromId(g.id(*e)));
+                
+                if(maxArcId < g.id(e))
+                    maxArcId = g.id(e);
+            }
+            should(!e.isValid() && e.atEnd());
+            should(e == lemon::INVALID);
+            should(!(e != lemon::INVALID));
+            
+            shouldEqual(maxArcId, g.maxArcId());
+            
+            // check that all neighbors are found
+            shouldEqual(count, g.arcNum());
+            shouldEqual(count, directed ? g.edgeNum() : 2*g.edgeNum());
+            
+            int min = NumericTraits<int>::max(), max = NumericTraits<int>::min();
+            edgeMap.minmax(&min, &max);
+            shouldEqual(min, 0);
+            shouldEqual(max, g.arcNum() ? directed ? 1 : 2 : 0);
+            
+            min = NumericTraits<int>::max();
+            max = NumericTraits<int>::min();
+            arcMap.minmax(&min, &max);
+            shouldEqual(min, 0);
+            shouldEqual(max, g.arcNum() ? 1 : 0);
+            
+            MultiCoordinateIterator<N> j(s), end = j.getEndIterator();
+            for(; j != end; ++j)
+            {
+                shouldEqual(edgeMap.bindInner(*j).template sum<int>(), directed ? g.out_degree(j) : 2*g.back_degree(j));
+                shouldEqual(arcMap.bindInner(*j).template sum<int>(), g.out_degree(j));
+                shouldEqual(sourceVertexMap[*j], g.out_degree(j));
+                shouldEqual(targetVertexMap[*j], g.out_degree(j));
+            }
+        }
+    }
+};
+
+template <unsigned int N>
+struct GridGraphAlgorithmTests
+{
+    typedef typename MultiArrayShape<N>::type Shape;
+    
+    template <class DirectedTag, NeighborhoodType NType>
+    void testLocalMinMax()
+    {
+        typedef GridGraph<N, DirectedTag> Graph;
+        
+        Graph g(Shape(3), NType);
+        typename Graph::template NodeMap<int> src(g), dest(g);
+        
+        src[Shape(1)] = 1;
+        
+        should(1 == boost_graph::localMinMaxGraph(g, src, dest, 1, -9999, std::greater<int>()));
+        
+        shouldEqualSequence(src.begin(), src.end(), dest.begin());
+        
+        dest.init(0);
+        
+        should(1 == lemon_graph::localMinMaxGraph(g, src, dest, 1, -9999, std::greater<int>()));
+        
+        shouldEqualSequence(src.begin(), src.end(), dest.begin());
+    }
+};
+
+template <unsigned int N>
+struct GridgraphTestSuiteN
+: public vigra::test_suite
+{
+    GridgraphTestSuiteN()
+    : vigra::test_suite((std::string("Gridgraph Test Dimension ") + vigra::asString(N)).c_str())
+    {
+        add(testCase(&NeighborhoodTests<N>::testVertexIterator));
+        
+        add(testCase(&NeighborhoodTests<N>::testDirectNeighborhood));
+        add(testCase(&NeighborhoodTests<N>::testIndirectNeighborhood));
+        
+        add(testCase(&NeighborhoodTests<N>::template testNeighborhoodIterator<DirectNeighborhood>));
+        add(testCase(&NeighborhoodTests<N>::template testNeighborhoodIterator<IndirectNeighborhood>));
+        
+        add(testCase(&NeighborhoodTests<N>::template testOutArcIteratorDirected<DirectNeighborhood>));
+        add(testCase(&NeighborhoodTests<N>::template testOutArcIteratorDirected<IndirectNeighborhood>));
+        
+        add(testCase(&NeighborhoodTests<N>::template testOutArcIteratorUndirected<DirectNeighborhood>));
+        add(testCase(&NeighborhoodTests<N>::template testOutArcIteratorUndirected<IndirectNeighborhood>));
+        
+        add(testCase(&NeighborhoodTests<N>::template testArcIteratorDirected<DirectNeighborhood>));
+        add(testCase(&NeighborhoodTests<N>::template testArcIteratorDirected<IndirectNeighborhood>));
+        
+        add(testCase(&NeighborhoodTests<N>::template testArcIteratorUndirected<DirectNeighborhood>));
+        add(testCase(&NeighborhoodTests<N>::template testArcIteratorUndirected<IndirectNeighborhood>));
+        
+        add(testCase((&GridGraphTests<N>::template testBasics<directed_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testBasics<undirected_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testBasics<directed_tag, DirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testBasics<undirected_tag, DirectNeighborhood>)));
+        
+        add(testCase((&GridGraphTests<N>::template testVertexIterator<directed_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testVertexIterator<undirected_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testVertexIterator<directed_tag, DirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testVertexIterator<undirected_tag, DirectNeighborhood>)));
+        
+        add(testCase((&GridGraphTests<N>::template testNeighborIterator<directed_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testNeighborIterator<undirected_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testNeighborIterator<directed_tag, DirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testNeighborIterator<undirected_tag, DirectNeighborhood>)));
+        
+        add(testCase((&GridGraphTests<N>::template testBackNeighborIterator<directed_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testBackNeighborIterator<undirected_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testBackNeighborIterator<directed_tag, DirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testBackNeighborIterator<undirected_tag, DirectNeighborhood>)));
+        
+        add(testCase((&GridGraphTests<N>::template testEdgeIterator<directed_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testEdgeIterator<undirected_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testEdgeIterator<directed_tag, DirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testEdgeIterator<undirected_tag, DirectNeighborhood>)));
+        
+        add(testCase((&GridGraphTests<N>::template testArcIterator<directed_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testArcIterator<undirected_tag, IndirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testArcIterator<directed_tag, DirectNeighborhood>)));
+        add(testCase((&GridGraphTests<N>::template testArcIterator<undirected_tag, DirectNeighborhood>)));
+        
+        add(testCase((&GridGraphAlgorithmTests<N>::template testLocalMinMax<undirected_tag, DirectNeighborhood>)));
+    }
+};
+
+struct GridgraphTestSuite
+: public vigra::test_suite
+{
+    GridgraphTestSuite()
+#ifdef WITH_BOOST_GRAPH
+    : vigra::test_suite("Gridgraph BGL Test")
+#else
+    : vigra::test_suite("Gridgraph Test")
+#endif
+    {
+        add(VIGRA_TEST_SUITE(GridgraphTestSuiteN<2>));
+        add(VIGRA_TEST_SUITE(GridgraphTestSuiteN<3>));
+//        add(VIGRA_TEST_SUITE(GridgraphTestSuiteN<4>));
+    }
+};
+
+int main(int argc, char **argv)
+{
+
+    GridgraphTestSuite gridgraphTest;
+
+    int failed = gridgraphTest.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << gridgraphTest.report() << std::endl;
+
+    return (failed != 0);
+}
diff --git a/test/hdf5impex/CMakeLists.txt b/test/hdf5impex/CMakeLists.txt
new file mode 100644
index 0000000..de73e28
--- /dev/null
+++ b/test/hdf5impex/CMakeLists.txt
@@ -0,0 +1,9 @@
+if(HDF5_FOUND)
+    INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIR})
+  
+    ADD_DEFINITIONS(${HDF5_CPPFLAGS})
+
+    VIGRA_ADD_TEST(test_hdf5impex test.cxx LIBRARIES vigraimpex ${HDF5_LIBRARIES})
+else()
+    MESSAGE(STATUS "** WARNING: test_hdf5impex will not be executed")
+endif()
diff --git a/test/hdf5impex/test.cxx b/test/hdf5impex/test.cxx
new file mode 100644
index 0000000..c324e5c
--- /dev/null
+++ b/test/hdf5impex/test.cxx
@@ -0,0 +1,1378 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2009 by Michael Hanselmann and Ullrich Koethe        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include "vigra/stdimage.hxx"
+#include "vigra/unittest.hxx"
+#include "vigra/hdf5impex.hxx"
+#include "vigra/multi_array.hxx"
+#include "vigra/multi_impex.hxx"
+
+using namespace vigra;
+
+
+class HDF5ExportImportTest
+{
+
+public:
+
+    HDF5ExportImportTest()
+    {}
+
+
+
+
+    void testScalarUnstridedHDF5ExportImport()
+    {
+        // export and import data from and to scalar unstrided array
+
+        char hdf5File[] = "testfile_scalar_unstrided.hdf5";
+
+        // data 1: 
+        MultiArray<3,int> out_data_1(MultiArrayShape<3>::type(2, 3, 4));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 24; ++i)
+            out_data_1.data () [i] = i - 12;
+        //std::cout << "Test (0,0), (0,1), (1,0): " << out_data_1(0,0) << " " << out_data_1(0,1) << " " << out_data_1(1,0) << " " << std::endl;
+
+        // export
+        // ...data 1: 
+        char hdf5group_1[] = "group/subgroup/data_unstrided";
+        writeHDF5(hdf5File, hdf5group_1, out_data_1);
+
+        // import
+        // data 1: 
+        HDF5ImportInfo infoHDF5_1(hdf5File, hdf5group_1);
+        MultiArray<3,int> in_data_1(MultiArrayShape<3>::type(infoHDF5_1.shapeOfDimension(0), infoHDF5_1.shapeOfDimension(1), infoHDF5_1.shapeOfDimension(2)));
+        readHDF5(infoHDF5_1, in_data_1);
+
+        // compare content
+        should (in_data_1 == out_data_1);
+    }
+
+
+
+    void testScalarStridedHDF5ExportImport()
+    {
+        // export and import data from and to scalar strided array
+
+        char hdf5File[] = "testfile_scalar_strided.hdf5";
+
+        // data 1: unstrided
+        MultiArray<3,int> out_data_1(MultiArrayShape<3>::type(2, 3, 4));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 24; ++i)
+            out_data_1.data () [i] = i - 12;
+        // data 2: strided
+        MultiArrayView<2,int,StridedArrayTag> out_data_2(out_data_1.bindAt(1, 0));
+        
+        // export
+        // ...data 2: strided
+        char hdf5group_2[] = "group/subgroup/data_strided";
+        writeHDF5(hdf5File, hdf5group_2, out_data_2);
+
+        // import
+        // data 2: strided
+        HDF5ImportInfo infoHDF5_2(hdf5File, hdf5group_2);
+        // import to strided array
+        MultiArray<3,int> in_data_1(MultiArrayShape<3>::type(3, infoHDF5_2.shapeOfDimension(0), infoHDF5_2.shapeOfDimension(1))); // strided
+        in_data_1.init(42);
+        MultiArrayView<2,int,StridedArrayTag> in_data_2(in_data_1.bindInner(0));
+        readHDF5(infoHDF5_2, in_data_2);
+
+        // compare content
+        should (in_data_2 == out_data_2);
+    }
+
+
+
+
+    void testRGBValueUnstridedHDF5ExportImport()
+    {
+        // export and import data from and to scalar unstrided array
+
+        char hdf5File[] = "testfile_rgbvalue_unstrided.hdf5";
+
+        // data 1: 3D multi array
+        // create RGB image from that
+        MultiArray< 2, RGBValue<double> > out_data_1(MultiArrayShape<2>::type(5, 8));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 40; ++i)
+            out_data_1.data () [i] = RGBValue<double>(i + 0.1, i + 0.2, i + 0.3);
+
+        // export
+        // ...data 2: RGB image
+        char hdf5group_1[] = "group/subgroup/data_rgb";
+        writeHDF5(hdf5File, hdf5group_1, out_data_1);
+
+        // import
+        // data 1: 
+        HDF5ImportInfo infoHDF5_1(hdf5File, hdf5group_1);
+        MultiArray< 2, RGBValue<double> > in_data_1(MultiArrayShape<2>::type(infoHDF5_1.shapeOfDimension(1), infoHDF5_1.shapeOfDimension(2)));
+        readHDF5(infoHDF5_1, in_data_1);
+
+        // compare content
+        should (in_data_1 == out_data_1);
+    }
+
+
+
+
+    void testRGBValueStridedHDF5ExportImport()
+    {
+        // export and import data from and to scalar unstrided array
+
+        char hdf5File[] = "testfile_rgbvalue_strided.hdf5";
+
+        // data 1: 3D multi array
+        // create RGB image from that
+        MultiArray< 3, RGBValue<double> > out_data_1(MultiArrayShape<3>::type(5, 3, 8));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 120; ++i)
+            out_data_1.data () [i] = RGBValue<double>(i + 0.1, i + 0.2, i + 0.3);
+        MultiArrayView< 2, RGBValue<double>, StridedArrayTag> out_data_2(out_data_1.bindAt(1, 0));
+
+        // export
+        // ...data 2: RGB image
+        char hdf5group_2[] = "group/subgroup/data_rgb";
+        writeHDF5(hdf5File, hdf5group_2, out_data_2);
+
+        // import
+        // data 2: strided
+        HDF5ImportInfo infoHDF5_2(hdf5File, hdf5group_2);
+        // import to strided array
+        MultiArray< 3, RGBValue<double> > in_data_1(MultiArrayShape<3>::type(3, infoHDF5_2.shapeOfDimension(1), infoHDF5_2.shapeOfDimension(2))); // strided
+        //in_data_1.init(42);
+        MultiArrayView< 2, RGBValue<double>, StridedArrayTag > in_data_2(in_data_1.bindInner(0));
+
+        readHDF5(infoHDF5_2, in_data_2);
+
+        // compare content
+        should (in_data_2 == out_data_2);
+    }
+
+
+
+
+    void testTinyVectorUnstridedHDF5ExportImport()
+    {
+        // export and import data from and to scalar unstrided array
+
+        char hdf5File[] = "testfile_tinyvector_unstrided.hdf5";
+
+        // data 1: 3D multi array
+        // create TinyVector image from that
+        MultiArray< 2, TinyVector<double, 4> > out_data_1(MultiArrayShape<2>::type(5, 8));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 40; ++i)
+            out_data_1.data () [i] = TinyVector<double, 4>(i + 0.1, i + 0.2, i + 0.3, i + 0.4);
+
+        // export
+        // ...data 2: TinyVector image
+        char hdf5group_1[] = "group/subgroup/data_tinyvector";
+        writeHDF5(hdf5File, hdf5group_1, out_data_1);
+
+        // import
+        // data 1: 
+        HDF5ImportInfo infoHDF5_1(hdf5File, hdf5group_1);
+        MultiArray< 2, TinyVector<double, 4> > in_data_1(MultiArrayShape<2>::type(infoHDF5_1.shapeOfDimension(1), infoHDF5_1.shapeOfDimension(2)));
+        readHDF5(infoHDF5_1, in_data_1);
+
+        // compare content
+        should (in_data_1 == out_data_1);
+    }
+
+
+
+
+    void testTinyVectorStridedHDF5ExportImport()
+    {
+        // export and import data from and to scalar unstrided array
+
+        char hdf5File[] = "testfile_tinyvector_strided.hdf5";
+
+        // data 1: 3D multi array
+        // create TinyVector image from that
+        MultiArray< 3, TinyVector<double, 4> > out_data_1(MultiArrayShape<3>::type(5, 3, 8));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 120; ++i)
+            out_data_1.data () [i] = TinyVector<double, 4>(i + 0.1, i + 0.2, i + 0.3, i + 0.4);
+        MultiArrayView< 2, TinyVector<double, 4>, StridedArrayTag> out_data_2(out_data_1.bindAt(1, 0));
+
+        // export
+        // ...data 2: TinyVector image
+        char hdf5group_2[] = "group/subgroup/data_tinyvector";
+        writeHDF5(hdf5File, hdf5group_2, out_data_2);
+
+        // import
+        // data 2: strided
+        HDF5ImportInfo infoHDF5_2(hdf5File, hdf5group_2);
+        // import to strided array
+        MultiArray< 3, TinyVector<double, 4> > in_data_1(MultiArrayShape<3>::type(3, infoHDF5_2.shapeOfDimension(1), infoHDF5_2.shapeOfDimension(2))); // strided
+        MultiArrayView< 2, TinyVector<double, 4>, StridedArrayTag > in_data_2(in_data_1.bindInner(0));
+
+        readHDF5(infoHDF5_2, in_data_2);
+
+        // compare content
+        should (in_data_2 == out_data_2);
+    }
+
+
+
+
+    void testScalarToRGBValueUnstridedHDF5ExportImport()
+    {
+        // export scalar 3D array and import as RGB image (unstrided)
+
+        char hdf5File[] = "testfile_scalar2rgbvalue_unstrided.hdf5";
+
+        // data 1: 3D multi array
+        MultiArray< 3, double > out_data_1(MultiArrayShape<3>::type(3, 5, 8));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 120; ++i)
+            out_data_1.data () [i] = i;
+
+        // export
+        // ...data 1: 
+        char hdf5group_1[] = "group/subgroup/data";
+        writeHDF5(hdf5File, hdf5group_1, out_data_1);
+
+        // import
+        // data 1: 
+        HDF5ImportInfo infoHDF5_1(hdf5File, hdf5group_1);
+        MultiArray< 2, RGBValue<double> > in_data_1(MultiArrayShape<2>::type(infoHDF5_1.shapeOfDimension(1), infoHDF5_1.shapeOfDimension(2)));
+        readHDF5(infoHDF5_1, in_data_1);
+
+        // compare content
+        int i = 0;
+        for (int j=0; j<120; ++i, j+=3)
+            should (in_data_1.data () [i] == RGBValue<double>((double)out_data_1.data () [j], (double)out_data_1.data () [j+1], (double)out_data_1.data () [j+2]) );
+    }
+
+
+
+
+    void testOverwriteExistingDataInHDF5()
+    {
+        // write data to file, close file, open file, overwrite data, compare
+
+        char hdf5File[] = "testfile_overwrite_existing_data.hdf5";
+
+        // data 1: int data in 2 dimensions (partly negative)
+        MultiArray<2,int> out_data_1(MultiArrayShape<2>::type(10, 11));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 110; ++i)
+            out_data_1.data () [i] = i - 55;
+        // data 2: double data in 4 dimensions (partly negative)
+        MultiArray<4,double> out_data_2(MultiArrayShape<4>::type(10, 2, 3, 4));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 240; ++i)
+            out_data_2.data () [i] = i + (std::rand() / (double)RAND_MAX) - 120;
+
+        // export
+        // ...data 1: 
+        char hdf5group_1[] = "group/subgroup/data1";
+        writeHDF5(hdf5File, hdf5group_1, out_data_1);
+        // ...data 2, overwriting existing data
+        writeHDF5(hdf5File, hdf5group_1, out_data_2);
+
+        // import
+        // data 1: 
+        HDF5ImportInfo infoHDF5_2(hdf5File, hdf5group_1);
+        MultiArray<4,double> in_data_2(MultiArrayShape<4>::type(infoHDF5_2.shapeOfDimension(0), infoHDF5_2.shapeOfDimension(1), infoHDF5_2.shapeOfDimension(2), infoHDF5_2.shapeOfDimension(3)));
+        readHDF5(infoHDF5_2, in_data_2);
+
+        // compare content
+        should (in_data_2 == out_data_2);
+    }
+
+
+
+
+    void testAppendNewDataToHDF5()
+    {
+        // write data to file, close file, open file, write more data, compare
+
+        char hdf5File[] = "testfile_append_new_data.hdf5";
+
+        // data 1: int data in 2 dimensions (partly negative)
+        MultiArray<2,int> out_data_1(MultiArrayShape<2>::type(10, 11));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 110; ++i)
+            out_data_1.data () [i] = i - 55;
+
+        // data 2: double data in 4 dimensions (partly negative)
+        MultiArray<4,double> out_data_2(MultiArrayShape<4>::type(10, 2, 3, 4));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 240; ++i)
+            out_data_2.data () [i] = i + (std::rand() / (double)RAND_MAX) - 120;
+
+        // export
+        // ...data 1
+        char hdf5group_1[] = "group/data1";
+        writeHDF5(hdf5File, hdf5group_1, out_data_1);
+
+        // append to existing file
+        // ...data 2
+        char hdf5group_2[] = "group/subgroup/data2";
+        writeHDF5(hdf5File, hdf5group_2, out_data_2);
+
+        // import
+        // ...data 1
+        HDF5ImportInfo infoHDF5_1(hdf5File, hdf5group_1);
+        MultiArray<2,int> in_data_1(MultiArrayShape<2>::type(infoHDF5_1.shapeOfDimension(0), infoHDF5_1.shapeOfDimension(1)));
+        readHDF5(infoHDF5_1, in_data_1);
+        // ...data 2
+        HDF5ImportInfo infoHDF5_2(hdf5File, hdf5group_2);
+        MultiArray<4,double> in_data_2(MultiArrayShape<4>::type(infoHDF5_2.shapeOfDimension(0), infoHDF5_2.shapeOfDimension(1), infoHDF5_2.shapeOfDimension(2), infoHDF5_2.shapeOfDimension(3)));
+        readHDF5(infoHDF5_2, in_data_2);
+
+        // compare content
+        // ...data 1
+        should (in_data_1 == out_data_1);
+        // ...data 2
+        should (in_data_2 == out_data_2);
+    }
+
+
+
+
+    void testHDF5FileDataAccess()
+    {
+        //write some data and read it again. Only spot test general functionality.
+
+        std::string file_name( "testfile_HDF5File_data_access.hdf5");
+
+        // data 1: int data in 2 dimensions (partly negative)
+        MultiArray<2,int> out_data_1(MultiArrayShape<2>::type(10, 11));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 110; ++i)
+            out_data_1.data () [i] = i - 55;
+
+        // data 2: double data in 4 dimensions (partly negative)
+        MultiArray<4,double> out_data_2(MultiArrayShape<4>::type(10, 2, 3, 4));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 240; ++i)
+            out_data_2.data () [i] = i + (std::rand() / (double)RAND_MAX) - 120;
+
+        // data 3: 2+1D multi array
+        MultiArray< 2, TinyVector<double, 4> > out_data_3(MultiArrayShape<2>::type(5, 8));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 40; ++i)
+            out_data_3.data () [i] = TinyVector<double, 4>(i + 0.1, i + 0.2, i + 0.3, i + 0.4);
+
+        // data 4: RGB values
+        MultiArray< 2, RGBValue<double> > out_data_4(MultiArrayShape<2>::type(5, 8));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 40; ++i)
+            out_data_4.data () [i] = RGBValue<double>(i + 0.1, i + 0.2, i + 0.3);
+
+        //create a file
+        HDF5File file (file_name, HDF5File::New);
+
+        //write one dataset in each group level
+        file.write("/dataset",out_data_1);
+        file.write("/dataset_transposed",out_data_1.transpose());
+        file.cd_mk("/group/");
+        file.write("/group/dataset",out_data_2);
+        file.mkdir("subgroup1");
+        file.write("subgroup1/dataset",out_data_3);
+        file.cd("..");
+        file.write("/dataset_rgb",out_data_4);
+        file.write("/atomicint", (int)-42);
+        file.write("/atomicuint", (unsigned int)42);
+        file.write("/atomicdouble", (double)3.1);
+
+        //create a new dataset
+        MultiArrayShape<3>::type shape (50,50,50);
+        unsigned char init = 42;
+        file.createDataset<3,unsigned char>("/newset", shape, init );
+
+        //test compressed
+        MultiArray<3, double> out_data_6(Shape3(100,100,30));
+        linearSequence(out_data_6.begin(), out_data_6.end());
+        file.write("/compressed", out_data_6, 0, 6);
+        file.write("/compressed_transposed", out_data_6.transpose(), 0, 6);
+
+        file.close();
+
+        should(isHDF5(file_name.c_str()));
+        should(!isHDF5("testsuccess.cxx"));
+        should(!isHDF5("file_does_not_exist.txt"));
+
+        file.open(file_name, HDF5File::Open);
+        
+        // check if data is really written
+
+        MultiArray<2,int> in_data_1 (Shape2(10, 11));
+        should(file.existsDataset("dataset"));
+        file.read("dataset",in_data_1);
+
+        MultiArray<2,int> in_data_1_transposed_write (Shape2(10, 11));
+        should(file.existsDataset("dataset_transposed"));
+        file.read("dataset_transposed",in_data_1_transposed_write.transpose());
+
+        MultiArray<2,int> in_data_1_transposed_read (Shape2(11, 10));
+        file.read("dataset", in_data_1_transposed_read.transpose());
+
+        MultiArray<4,double> in_data_2 (Shape4(10, 2, 3, 4));
+        should(file.existsDataset("/group/dataset"));
+        should(file.getDatasetType("/group/dataset") == "DOUBLE");
+        file.read("/group/dataset",in_data_2);
+
+        MultiArray< 2, TinyVector<double, 4> > in_data_3 (Shape2(5,8));
+        should(file.existsDataset("/group/subgroup1/dataset"));
+        file.read("/group/subgroup1/dataset",in_data_3);
+
+        MultiArray< 2, RGBValue<double> > in_data_4(Shape2(5,8));
+        should(file.existsDataset("/dataset_rgb"));
+        file.read("/dataset_rgb", in_data_4);
+
+        MultiArray< 3, unsigned char > in_data_5 (shape);
+        should(file.existsDataset("/newset"));
+        should(file.getDatasetType("/newset") == "UINT8");
+        file.read("/newset",in_data_5);
+
+        MultiArray< 3, double > in_data_6 (out_data_6.shape());
+        should(file.existsDataset("/compressed"));
+        file.read("/compressed",in_data_6);
+
+        MultiArray< 3, double > in_data_6_transposed_write (out_data_6.shape());
+        should(file.existsDataset("/compressed_transposed"));
+        file.read("/compressed_transposed",in_data_6_transposed_write.transpose());
+
+        MultiArray< 3, double > in_data_6_transposed_read (out_data_6.transpose().shape());
+        file.read("/compressed",in_data_6_transposed_read.transpose());
+
+        int atomicint;
+        should(file.existsDataset("/atomicint"));
+        file.read("/atomicint",atomicint);
+        int atomicuint;
+        should(file.existsDataset("/atomicuint"));
+        file.read("/atomicuint",atomicuint);
+        double atomicdouble;
+        should(file.existsDataset("/atomicdouble"));
+        file.read("/atomicdouble",atomicdouble);
+
+        file.flushToDisk();
+
+        // compare content
+        // ...data 1
+        should (in_data_1 == out_data_1);
+
+        // ...data 1 transposed write
+        should (in_data_1_transposed_write == out_data_1);
+
+        // ...data 1 transposed read
+        should (in_data_1_transposed_read.transpose() == out_data_1);
+
+        // ...data 2
+        should (in_data_2 == out_data_2);
+        // ...data 3
+        should (in_data_3 == out_data_3);
+        // ...data 4
+        should (in_data_4 == out_data_4);
+        // ...data 5
+        should (in_data_5(1,2,3) == init);
+
+        // ...data 6
+        should (in_data_6 == out_data_6);
+        // ...data 6 transposed write
+        should (in_data_6_transposed_write == out_data_6);
+        // ...data 6 transposed read
+        should (in_data_6_transposed_read.transpose() == out_data_6);
+
+        should (atomicint == -42);
+        should (atomicuint == 42);
+        should (atomicdouble == 3.1);
+
+        // readAndResize
+        MultiArray<2,int> in_re_data_1;
+        file.readAndResize("dataset",in_re_data_1);
+
+        MultiArray<4,double> in_re_data_2;
+        file.readAndResize("/group/dataset",in_re_data_2);
+
+        MultiArray< 2, TinyVector<double, 4> > in_re_data_3;
+        file.readAndResize("/group/subgroup1/dataset",in_re_data_3);
+
+        MultiArray< 2, RGBValue<double> > in_re_data_4;
+        file.readAndResize("/dataset_rgb", in_re_data_4);
+
+        MultiArray< 3, unsigned char > in_re_data_5 ;
+        file.readAndResize("/newset",in_re_data_5);
+
+        // compare content
+        // ...data 1
+        should (in_re_data_1 == out_data_1);
+        // ...data 2
+        should (in_re_data_2 == out_data_2);
+        // ...data 3
+        should (in_re_data_3 == out_data_3);
+        // ...data 4
+        should (in_re_data_4 == out_data_4);
+        // ...data 5
+        should (in_re_data_5(1,2,3) == init);
+
+        // overwrite existing dataset
+        file.write("/dataset",out_data_2);
+        file.flushToDisk();
+
+        MultiArray<4,double> in_data_overwrite (MultiArrayShape<4>::type(10, 2, 3, 4));
+        file.read("/dataset",in_data_overwrite);
+
+        should(in_data_overwrite == out_data_2);
+        
+        file.cd("/");
+        
+        // writing and reading single values
+
+        file.write("set_char",'A');
+        file.write("set_int8",(Int8)8);
+        file.write("set_int16",(Int16)16);
+        file.write("set_int32",(Int32)32);
+        file.write("set_int64",(Int64)64);
+        file.write("set_uint8",(UInt8)8);
+        file.write("set_uint16",(UInt16)16);
+        file.write("set_uint32",(UInt32)32);
+        file.write("set_uint64",(UInt64)64);
+        file.write("set_float",(float)1.);
+        file.write("set_double",(double)2.);
+        file.write("set_longdouble",(long double)3.);
+        file.write("set_string",std::string("abc").c_str());
+        file.write("set_string2",std::string("abcdef"));
+        
+        char read_char = 0;
+        file.read("set_char",read_char);
+        should(read_char=='A');
+        
+        Int8 read_int8 = 0;
+        file.read("set_int8",read_int8);
+        should(read_int8==8);
+        
+        Int16 read_int16 = 0;
+        file.read("set_int16",read_int16);
+        should(read_int16 == 16);
+        
+        Int32 read_int32 = 0;
+        file.read("set_int32",read_int32);
+        should(read_int32 == 32);
+        
+        Int64 read_int64 = 0;
+        file.read("set_int64",read_int64);
+        should(read_int64 == 64);
+        
+        UInt8 read_uint8 = 0;
+        file.read("set_uint8",read_uint8);
+        should(read_uint8 == 8);
+        
+        UInt16 read_uint16 = 0;
+        file.read("set_uint16",read_uint16);
+        should(read_uint16 == 16);
+        
+        UInt32 read_uint32 = 0;
+        file.read("set_uint32",read_uint32);
+        should(read_uint32 == 32);
+        
+        UInt64 read_uint64 = 0;
+        file.read("set_uint64",read_uint64);
+        should(read_uint64 == 64);
+        
+        float read_float = 0;
+        file.read("set_float",read_float);
+        should(read_float == 1.);
+        
+        double read_double = 0;
+        file.read("set_double",read_double);
+        should(read_double == 2.);
+        
+        long double read_longdouble = 0;
+        file.read("set_longdouble",read_longdouble);
+        should(read_longdouble == 3.);
+        
+        std::string read_string = "";
+        file.read("set_string",read_string);  
+        should(read_string == "abc");
+
+        std::string read_string2 = "";
+        file.read("set_string2",read_string2);
+        should(read_string2 == "abcdef");
+       
+        // test read-only opening
+        file.close();
+        file.open(file_name, HDF5File::OpenReadOnly);
+        read_string2 = "";
+        file.read("set_string2",read_string2);
+        should(read_string2 == "abcdef");
+        file.close();
+    }
+
+    // reading and writing attributes. get handles of groups, datasets and attributes
+    void testHDF5FileAttributes()
+    {
+        std::string file_name( "testfile_HDF5File_data_attributes.hdf5");
+
+        // double data in 4 dimensions (partly negative)
+        MultiArray<4,double> out_data_1(MultiArrayShape<4>::type(10, 2, 3, 4));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 240; ++i)
+            out_data_1.data () [i] = i + (std::rand() / (double)RAND_MAX) - 120;
+
+        // variable length string MultiArrays
+        MultiArray<2,const char* > out_data_2(MultiArrayShape<2>::type(2, 2));
+        // ...initialize the array to the test data
+        out_data_2(0,0) = "Brot";
+        out_data_2(0,1) = "Huette";
+        out_data_2(1,0) = "Kamuffel";
+        out_data_2(1,1) = "Gorch Frog";
+
+        //create a file
+        HDF5File file (file_name, HDF5File::New);
+
+        //write one dataset in each group level
+        file.write("/double/dataset",out_data_1);
+        file.write("/string/dataset",out_data_2);
+
+        // check if data is really written
+        MultiArray< 2, const char* > in_data_2(MultiArrayShape<2>::type(2, 2));
+        file.read("/string/dataset",in_data_2);
+
+        should(std::string(in_data_2(0,0)) == std::string("Brot"));
+        should(std::string(in_data_2(0,1)) == std::string("Huette"));
+        should(std::string(in_data_2(1,0)) == std::string("Kamuffel"));
+        should(std::string(in_data_2(1,1)) == std::string("Gorch Frog"));
+
+        // write Attributes
+
+        // integer attribute
+        MultiArray<2,int> out_attr_1(MultiArrayShape<2>::type(2,3));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 6; ++i)
+            out_attr_1.data() [i] = i;
+
+        // variable length string attribute
+        MultiArray<1,const char*> out_attr_2(MultiArrayShape<1>::type(4));
+        // ...initialize the array to the test data
+        out_attr_2(3) = "Brot";
+        out_attr_2(2) = "Huette";
+        out_attr_2(1) = "Kamuffel";
+        out_attr_2(0) = "Gorch Frog";
+
+        // tiny vector multi array
+        MultiArray<2, TinyVector<double, 3> > out_attr_3(MultiArrayShape<2>::type(2,1));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 2; ++i)
+            out_attr_3.data () [i] = TinyVector<double, 3>(i + 0.1, i + 0.2, i + 0.3);
+
+        // data 4: RGB values
+        MultiArray< 2, RGBValue<double> > out_attr_4(MultiArrayShape<2>::type(2,3));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 6; ++i)
+            out_attr_4.data () [i] = RGBValue<double>(i + 0.1, i + 0.2, i + 0.3);
+
+        file.writeAttribute("/double/dataset","int attribute", out_attr_1);
+        file.writeAttribute("/double/dataset","string attribute", out_attr_2);
+        file.writeAttribute("/string/dataset","tinyvector attribute", out_attr_3);
+        file.writeAttribute("/string/dataset","rgb attribute", out_attr_4);
+
+
+        // read attributes
+        MultiArray<2,int> in_attr_1(MultiArrayShape<2>::type(2,3));
+        MultiArray<1,const char*> in_attr_2(MultiArrayShape<1>::type(4));
+        MultiArray<2, TinyVector<double, 3> > in_attr_3(MultiArrayShape<2>::type(2,1));
+        MultiArray< 2, RGBValue<double> > in_attr_4(MultiArrayShape<2>::type(2,3));
+
+        file.readAttribute("/double/dataset","int attribute", in_attr_1);
+        file.readAttribute("/double/dataset","string attribute", in_attr_2);
+        file.readAttribute("/string/dataset","tinyvector attribute", in_attr_3);
+        file.readAttribute("/string/dataset","rgb attribute", in_attr_4);
+
+        should(in_attr_1 == out_attr_1);
+        should(std::string(in_attr_2(0)) == std::string(out_attr_2(0)));
+        should(std::string(in_attr_2(1)) == std::string(out_attr_2(1)));
+        should(std::string(in_attr_2(2)) == std::string(out_attr_2(2)));
+        should(std::string(in_attr_2(3)) == std::string(out_attr_2(3)));
+        should(in_attr_3 == out_attr_3);
+        should(in_attr_4 == out_attr_4);
+
+
+
+        // write and read attributes
+
+        file.cd("/");
+        file.write("attrset",std::string("Dataset with many attributes").c_str());
+
+        file.writeAttribute("attrset","set_char",'A');
+        file.writeAttribute("attrset","set_int8",(Int8)8);
+        file.writeAttribute("attrset","set_int16",(Int16)16);
+        file.writeAttribute("attrset","set_int32",(Int32)32);
+        file.writeAttribute("attrset","set_int64",(Int64)64);
+        file.writeAttribute("attrset","set_uint8",(UInt8)8);
+        file.writeAttribute("attrset","set_uint16",(UInt16)16);
+        file.writeAttribute("attrset","set_uint32",(UInt32)32);
+        file.writeAttribute("attrset","set_uint64",(UInt64)64);
+        file.writeAttribute("attrset","set_float",(float)1.);
+        file.writeAttribute("attrset","set_double",(double)2.);
+        file.writeAttribute("attrset","set_longdouble",(long double)3.);
+        file.writeAttribute("attrset","set_string",std::string("abc").c_str());
+        file.writeAttribute("attrset","set_string2",std::string("abcdef"));
+
+        char read_char = 0;
+        file.readAttribute("attrset","set_char",read_char);
+        should(read_char=='A');
+
+        Int8 read_int8 = 0;
+        file.readAttribute("attrset","set_int8",read_int8);
+        should(read_int8==8);
+
+        Int16 read_int16 = 0;
+        file.readAttribute("attrset","set_int16",read_int16);
+        should(read_int16 == 16);
+
+        Int32 read_int32 = 0;
+        file.readAttribute("attrset","set_int32",read_int32);
+        should(read_int32 == 32);
+
+        Int64 read_int64 = 0;
+        file.readAttribute("attrset","set_int64",read_int64);
+        should(read_int64 == 64);
+
+        UInt8 read_uint8 = 0;
+        file.readAttribute("attrset","set_uint8",read_uint8);
+        should(read_uint8 == 8);
+
+        UInt16 read_uint16 = 0;
+        file.readAttribute("attrset","set_uint16",read_uint16);
+        should(read_uint16 == 16);
+
+        UInt32 read_uint32 = 0;
+        file.readAttribute("attrset","set_uint32",read_uint32);
+        should(read_uint32 == 32);
+
+        UInt64 read_uint64 = 0;
+        file.readAttribute("attrset","set_uint64",read_uint64);
+        should(read_uint64 == 64);
+
+        float read_float = 0;
+        file.readAttribute("attrset","set_float",read_float);
+        should(read_float == 1.);
+
+        double read_double = 0;
+        file.readAttribute("attrset","set_double",read_double);
+        should(read_double == 2.);
+
+        long double read_longdouble = 0;
+        file.readAttribute("attrset","set_longdouble",read_longdouble);
+        should(read_longdouble == 3.);
+
+        std::string read_string = "";
+        file.readAttribute("attrset","set_string",read_string);
+        should(read_string == "abc");
+
+        std::string read_string2 = "";
+        file.readAttribute("attrset","set_string2",read_string2);
+        should(read_string2 == "abcdef");
+
+        // get handles
+        HDF5Handle group_handle = file.getGroupHandle("/string");
+        HDF5Handle dataset_handle = file.getDatasetHandle("/string/dataset");
+        HDF5Handle attribute_handle = file.getAttributeHandle("/string/dataset","rgb attribute");
+
+        should(group_handle.get() > 0);
+        should(dataset_handle.get() > 0);
+        should(attribute_handle.get() > 0);
+
+        should(group_handle.close() >= 0);
+        should(dataset_handle.close() >= 0);
+        should(attribute_handle.close() >= 0);
+    }
+
+    void testHDF5FileBlockAccess()
+    {
+        // Create 3D dataset
+        MultiArray< 3, double > out_data(MultiArrayShape<3>::type(10, 10, 10));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 10; ++i){
+            for (int j = 0; j < 10; ++j){
+                for (int k = 0; k < 10; ++k){
+                    out_data (i,j,k) = 100*i+10*j+k;
+                }
+            }
+        }
+
+
+        std::string file_name( "testfile_HDF5File_block_access.hdf5");
+
+        //create a file and write data
+        HDF5File file (file_name, HDF5File::New);
+
+        file.write("/dataset",out_data);
+        file.cd_mk("group");
+        file.write("dataset2",out_data);
+        file.cd("..");
+        file.flushToDisk();
+
+
+        int sz = 10;
+        MultiArray< 3, double > in_data(MultiArrayShape<3>::type(sz, sz, sz));
+        MultiArray< 3, double > in_data_group(MultiArrayShape<3>::type(sz, sz, sz));
+        MultiArrayShape<3>::type block_offset (0,0,0);
+        MultiArrayShape<3>::type block_shape (sz,sz,sz);
+
+        file.readBlock("/dataset", block_offset, block_shape, in_data);
+        file.readBlock("/group/dataset2", block_offset, block_shape, in_data_group);
+
+        should(in_data == out_data);
+        should(in_data_group == out_data);
+
+        sz = 4;
+        MultiArray< 3, double > in_data_2(MultiArrayShape<3>::type(sz, sz, sz));
+        MultiArrayShape<3>::type block_offset_2 (2,2,2);
+        MultiArrayShape<3>::type block_shape_2 (sz,sz,sz);
+
+        file.readBlock("/dataset", block_offset_2, block_shape_2, in_data_2);
+
+        shouldEqual(in_data_2(0,0,0), out_data(2,2,2));
+        shouldEqual(in_data_2(1,0,0), out_data(3,2,2));
+        shouldEqual(in_data_2(0,2,0), out_data(2,4,2));
+        shouldEqual(in_data_2(0,0,3), out_data(2,2,5));
+
+        // write the data to different position
+        MultiArrayShape<3>::type block_offset_3 (6,2,2);
+        file.writeBlock("/dataset", block_offset_3, in_data_2 );
+        file.flushToDisk();
+
+        // now read it again and compare
+        MultiArray< 3, double > in_data_3(MultiArrayShape<3>::type(sz, sz, sz));
+        file.readBlock("/dataset", block_offset_3, block_shape_2, in_data_3);
+
+        should(in_data_2 == in_data_3);
+
+    }
+
+
+
+
+    void testHDF5FileChunks()
+    {
+        //write some data and read it again. Only spot test general functionality.
+
+        std::string file_name( "testfile_HDF5File_chunks.hdf5");
+
+        // data 1: int data in 2 dimensions (partly negative)
+        MultiArray<2,int> out_data_1(MultiArrayShape<2>::type(10, 11));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 110; ++i)
+            out_data_1.data () [i] = i - 55;
+
+        // data 2: double data in 4 dimensions (partly negative)
+        MultiArray<4,double> out_data_2(MultiArrayShape<4>::type(10, 2, 3, 4));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 240; ++i)
+            out_data_2.data () [i] = i + (std::rand() / (double)RAND_MAX) - 120;
+
+        // data 3: 2+1D multi array
+        MultiArray< 2, TinyVector<double, 4> > out_data_3(MultiArrayShape<2>::type(5, 8));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 40; ++i)
+            out_data_3.data () [i] = TinyVector<double, 4>(i + 0.1, i + 0.2, i + 0.3, i + 0.4);
+
+        // data 4: RGB values
+        MultiArray< 2, RGBValue<double> > out_data_4(MultiArrayShape<2>::type(5, 8));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 40; ++i)
+            out_data_4.data () [i] = RGBValue<double>(i + 0.1, i + 0.2, i + 0.3);
+
+        //create a file
+        HDF5File file (file_name, HDF5File::New);
+
+        //write one dataset in each group level
+        file.write("dataset",out_data_1,5);
+        file.write("group/dataset",out_data_2, MultiArrayShape<4>::type(5,2,3,2));
+        file.write("group/subgroup1/dataset",out_data_3, MultiArrayShape<2>::type(5,4));
+        file.write("dataset_rgb",out_data_4, MultiArrayShape<2>::type(5,4));
+
+
+        //create a new dataset
+        MultiArrayShape<3>::type shape (50,50,50);
+        MultiArrayShape<3>::type chunks (10,10,10);
+        unsigned char init = 42;
+        file.createDataset<3,unsigned char>("newset", shape, init, chunks);
+
+
+        // check if data is really written
+
+        MultiArray<2,int> in_data_1 (MultiArrayShape<2>::type(10, 11));
+        file.read("dataset",in_data_1);
+
+        MultiArray<4,double> in_data_2 (MultiArrayShape<4>::type(10, 2, 3, 4));
+        file.read("/group/dataset",in_data_2);
+
+        MultiArray< 2, TinyVector<double, 4> > in_data_3 (MultiArrayShape<2>::type(5, 8));
+        file.read("/group/subgroup1/dataset",in_data_3);
+
+        MultiArray< 2, RGBValue<double> > in_data_4(MultiArrayShape<2>::type(5,8));
+        file.read("/dataset_rgb", in_data_4);
+
+        MultiArray< 3, unsigned char > in_data_5 (shape);
+        file.read("/newset",in_data_5);
+
+        // compare content
+        // ...data 1
+        should (in_data_1 == out_data_1);
+        // ...data 2
+        should (in_data_2 == out_data_2);
+        // ...data 3
+        should (in_data_3 == out_data_3);
+        // ...data 4
+        should (in_data_4 == out_data_4);
+        // ...data 5
+        should (in_data_5(1,2,3) == init);
+
+    }
+
+
+
+
+    void testHDF5FileCompression()
+    {
+        //write some data and read it again. Only spot test general functionality.
+
+        std::string file_name( "testfile_HDF5File_compression.hdf5");
+
+        // data 1: int data in 2 dimensions (partly negative)
+        MultiArray<2,int> out_data_1(MultiArrayShape<2>::type(10, 11));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 110; ++i)
+            out_data_1.data () [i] = i - 55;
+
+        // data 2: double data in 4 dimensions (partly negative)
+        MultiArray<4,double> out_data_2(MultiArrayShape<4>::type(10, 2, 3, 4));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 240; ++i)
+            out_data_2.data () [i] = i + (std::rand() / (double)RAND_MAX) - 120;
+
+        // data 3: 2+1D multi array
+        MultiArray< 2, TinyVector<double, 4> > out_data_3(MultiArrayShape<2>::type(5, 8));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 40; ++i)
+            out_data_3.data () [i] = TinyVector<double, 4>(i + 0.1, i + 0.2, i + 0.3, i + 0.4);
+
+        // data 4: RGB values
+        MultiArray< 2, RGBValue<double> > out_data_4(MultiArrayShape<2>::type(5, 8));
+        // ...initialize the array to the test data
+        for (int i = 0; i < 40; ++i)
+            out_data_4.data () [i] = RGBValue<double>(i + 0.1, i + 0.2, i + 0.3);
+
+        //create a file
+        HDF5File file (file_name, HDF5File::New);
+
+        //write one dataset in each group level
+        file.write("/dataset",out_data_1, 5, 3);
+        file.write("/group/dataset",out_data_2, MultiArrayShape<4>::type(5,2,3,2), 5);
+        file.write("/group/subgroup1/dataset",out_data_3, MultiArrayShape<2>::type(5,4), 7);
+        file.write("/dataset_rgb",out_data_4, MultiArrayShape<2>::type(5,4), 9);
+
+
+        //create a new dataset
+        MultiArrayShape<3>::type shape (50,50,50);
+        MultiArrayShape<3>::type chunks (10,10,10);
+        unsigned char init = 42;
+        file.createDataset<3,unsigned char>("/newset", shape, init, chunks, 5);
+
+        // read block
+        int sz = 10;
+        MultiArray< 3, unsigned char > in_data_block(MultiArrayShape<3>::type(sz, sz, sz));
+        MultiArrayShape<3>::type block_offset (5,5,5);
+        MultiArrayShape<3>::type block_shape (sz,sz,sz);
+
+        file.readBlock("/newset", block_offset, block_shape, in_data_block);
+
+
+        // check if data is really written
+
+        MultiArray<2,int> in_data_1 (MultiArrayShape<2>::type(10, 11));
+        file.read("dataset",in_data_1);
+
+        MultiArray<4,double> in_data_2 (MultiArrayShape<4>::type(10, 2, 3, 4));
+        file.read("/group/dataset",in_data_2);
+
+        MultiArray< 2, TinyVector<double, 4> > in_data_3 (MultiArrayShape<2>::type(5, 8));
+        file.read("/group/subgroup1/dataset",in_data_3);
+
+        MultiArray< 2, RGBValue<double> > in_data_4(MultiArrayShape<2>::type(5,8));
+        file.read("/dataset_rgb", in_data_4);
+
+        MultiArray< 3, unsigned char > in_data_5 (shape);
+        file.read("/newset",in_data_5);
+
+        // compare content
+        // ...data 1
+        should (in_data_1 == out_data_1);
+
+        // ...data 2
+        should (in_data_2 == out_data_2);
+        // ...data 3
+        should (in_data_3 == out_data_3);
+        // ...data 4
+        should (in_data_4 == out_data_4);
+        // ...data 5
+        should (in_data_5(1,2,3) == init);
+        // ...data block
+        should (in_data_block(1,2,3) == 42);
+
+        // read same data with readHDF5()
+        HDF5ImportInfo infoHDF5(file_name.c_str(), "/dataset_rgb");
+        MultiArray<2, RGBValue<double> > in_data_4_2(MultiArrayShape<2>::type(5,8));
+        readHDF5(infoHDF5, in_data_4_2);
+        should (in_data_4_2 == out_data_4);
+    }
+
+
+
+
+    void testHDF5FileBrowsing()
+    {
+        //create groups, change current group, ...
+
+        std::string file_name( "testfile_HDF5File_browsing.hdf5");
+
+        //create a file
+        HDF5File file (file_name, HDF5File::New);
+
+        //we should be in root group in the beginning
+        should(file.pwd() == "/" );
+
+        //create group "group1"
+        file.mkdir("group1");
+        //we should still be in root (only created group)
+        should(file.pwd() == "/" );
+
+        //now change to new group (relative change)
+        file.cd("group1");
+        should(file.pwd() == "/group1" );
+
+        //create a subgroup and change there
+        file.cd_mk("subgroup");
+        should(file.pwd() == "/group1/subgroup" );
+
+        //create a group tree in root group
+        file.mkdir("/group2/subgroup/subsubgroup");
+        should(file.pwd() == "/group1/subgroup" );
+
+        //go to parent group
+        file.cd_up();
+        should(file.pwd() == "/group1" );
+
+        //change to recently created group tree (absolute change)
+        file.cd("/group2/subgroup/subsubgroup");
+        should(file.pwd() == "/group2/subgroup/subsubgroup" );
+
+        //change to parent group
+        file.cd("..");
+        should(file.pwd() == "/group2/subgroup" );
+
+        //change up 2 groups
+        file.cd_up(2);
+        should(file.pwd() == "/" );
+
+        //try to change to parent of root group
+        should( !file.cd_up() );
+
+        std::vector<std::string> entries;
+        entries = file.ls();
+        should(entries.size() == 2);
+        should(entries[0] == "group1/");
+        should(entries[1] == "group2/");
+
+        //enhanced navigation with .. and .
+        file.cd("/group1/");
+        should(file.pwd() == "/group1");
+        file.cd("../not/existing/../../group2/././subgroup/");
+        should(file.pwd() == "/group2/subgroup");
+    }
+
+
+
+
+    void testHDF5FileTutorial()
+    {
+        // First create a new HDF5 file (thereby also testing default construction + open);
+        HDF5File file;
+        file.open("tutorial_HDF5File.h5", HDF5File::New);
+
+        // we should be in root group in the beginning
+        should(file.pwd() == "/" );
+
+        // create the group "/group1/subgroup1" using absolute paths
+        file.mkdir("/group1/subgroup1");
+
+        // create the group "group2/subgroup2" using relative paths
+        file.mkdir("group2");
+        file.cd("group2");
+        file.cd_mk("subgroup2"); //cd_mk first creates group and then opens it
+
+        should(file.pwd() == "/group2/subgroup2" );
+
+
+        // Writing Data
+
+        // Create a new dataset with shape (10,10,10) of int, initialized with 42.
+        MultiArrayShape<3>::type shape (10,10,10);
+        file.createDataset<3,int>("new_dataset",shape,42);
+
+        // Create a new large dataset (20,20,20) with anisotropic (5,10,10) chunks and compression level 5.
+        shape = MultiArrayShape<3>::type(20,20,20);
+        MultiArrayShape<3>::type chunks (5,10,10);
+        file.createDataset<3,int>("new_dataset_chunks",shape, 42, chunks, 5);
+
+        // Create a double MultiArray
+        MultiArray<4,double> out_data(MultiArrayShape<4>::type(10, 2, 3, 4));
+        // ...initialize the array with some data
+        for (int i = 0; i < 240; ++i)
+            out_data.data () [i] = i + (std::rand() / (double)RAND_MAX) - 120;
+
+        // Write double MultiArray to "/group2". Use relative paths and ".." notation.
+        file.write("../double_array",out_data);
+
+        // Create a large MultiArray
+        MultiArray<3,float> out_data_float (shape, 42.);
+
+        // write with isotropic chunks (10,10,10) and compression 5.
+        file.write("../float_array",out_data_float,10,5);
+
+        // Write a (10,10,10) Block of data into the center of "/group2/float_array"
+        MultiArray<3,float> float_block (MultiArrayShape<3>::type(10,10,10), 42.);
+        MultiArrayShape<3>::type block_offset (5,5,5);
+
+        file.writeBlock("/group2/float_array",block_offset,float_block);
+
+        // Write a single long integer value in the root group
+        file.write("/single_value",(long int)23);
+
+        // Attach simple string attribute to dataset in root group
+        file.writeAttribute("/single_value","some_attribute_name","This is a simple string attribute");
+
+        // Attach a MultiArray attribute
+        MultiArray<1,double> attr_data (MultiArrayShape<1>::type(3));
+        attr_data(0) = 10; attr_data(1) = 100; attr_data(2) = 1000;
+
+        file.writeAttribute("/group2/float_array","float_array_attribute",attr_data);
+
+        file.flushToDisk();
+
+
+        // Reading Data
+
+        // it is possible to access one file with two different HDF5File instances.
+        HDF5File file_open ("tutorial_HDF5File.h5", HDF5File::Open);
+
+        file_open.cd("/");
+
+        // read "/group2/subgroup2/new_dataset_chunks", prepare array with correct shape
+        MultiArrayShape<3>::type read_shape (20,20,20);
+        MultiArray<3,int> read_chunks (read_shape);
+
+        file_open.read("/group2/subgroup2/new_dataset_chunks",read_chunks);
+
+        // read "/group2/subgroup2/new_dataset", reshape MultiArray automatically
+        MultiArray<3,int> read_reshape;
+
+        file_open.readAndResize("/group2/subgroup2/new_dataset",read_reshape);
+
+        // read a block of data from "/group2/float_array"
+        block_offset = MultiArrayShape<3>::type(0,0,0);
+        MultiArrayShape<3>::type block_shape (15,15,15);
+        MultiArray<3,float> read_block (block_shape);
+
+        file_open.readBlock("/group2/float_array",block_offset,block_shape,read_block);
+
+        // read the long int value from "/single_value"
+        long int single_value;
+        file_open.read("/single_value",single_value);
+
+        // read the attribute of "/single_value"
+        std::string attribute_string;
+        file_open.readAttribute("/single_value","some_attribute_name", attribute_string);
+
+        // read the MultiArray Attribute of "/group2/float_array"
+        MultiArray<1,double> read_attr (MultiArrayShape<1>::type(3));
+        file_open.readAttribute("/group2/float_array","float_array_attribute",read_attr);
+    }
+
+    struct HDF5File_close_test : public HDF5File
+    {
+        HDF5File_close_test(const std::string & name, HDF5File::OpenMode mode = HDF5File::New)
+            : HDF5File(name, mode) {}
+
+        hid_t get_file_id() const
+        {
+            return fileHandle_;
+        }
+
+        void closeCurrentGroup()
+        {
+            cGroupHandle_.close();
+        }
+
+            // this function is for debugging the test
+            // (the leak test should be strong enough to detect the leak) 
+        hid_t forceGroupLeak(std::string name)
+        {
+            return openCreateGroup_(name);
+        }
+    };
+    
+    void test_file_closing()
+    {
+        hid_t file_id = 0;
+        hid_t leak_id = 0;
+        {   // open a new block on purpose.
+            HDF5File_close_test test_file("open_file_test.hdf5");
+            file_id = test_file.get_file_id();
+
+            // mess around with the file in order to maybe trigger
+            // leaking hdf5 object descriptors that would block
+            // closing the file
+            test_file.cd_mk("subgroup_a"); // this at least used to leak.
+            test_file.cd("/");
+            test_file.cd_mk("subgroup_c");
+            test_file.mkdir("group1");
+            test_file.cd_mk("subgroup_b");
+            test_file.mkdir("group1");
+            test_file.cd("/");
+            test_file.mkdir("group1");
+            test_file.cd("/");
+            test_file.cd("group1");
+            test_file.mkdir("/group2/subgroup/subsubgroup");
+            test_file.cd_up();
+            test_file.cd("/group2/subgroup/subsubgroup");
+            test_file.cd("..");
+            test_file.cd_up(2);
+            test_file.cd_up();
+            test_file.ls();
+            test_file.cd("/group1/");
+            test_file.cd("../not/existing/../../group2/././subgroup/");
+            MultiArrayShape<3>::type shape (10, 10, 10);
+            test_file.createDataset<3, float>("new_dataset", shape, 1.23f);
+            test_file.closeCurrentGroup();
+            
+            // the file handle must be the only remaining open object
+            shouldEqual(H5Fget_obj_count(file_id, H5F_OBJ_ALL), 1);
+
+            hid_t new_file_id = H5Freopen(file_id);
+            should(new_file_id >= 0); // the file must still be open
+            shouldEqual(H5Fget_obj_count(file_id, H5F_OBJ_ALL), 2);
+
+            H5Fclose(new_file_id);
+            shouldEqual(H5Fget_obj_count(file_id, H5F_OBJ_ALL), 1);
+        } // this calls ~HDF5File() and therefore absolutely must close the file
+        {
+            HDF5File_close_test test_file("open_file_test.hdf5", HDF5File::Open);
+            file_id = test_file.get_file_id();
+            shouldEqual(H5Fget_obj_count(file_id, H5F_OBJ_ALL), 2);
+        }
+        {
+            HDF5File_close_test test_file("open_file_test.hdf5");
+            file_id = test_file.get_file_id();
+
+            // create an intentional leak
+            leak_id = test_file.forceGroupLeak("/group1/");
+
+            shouldEqual(H5Fget_obj_count(file_id, H5F_OBJ_ALL), 3);
+        }
+        {
+            HDF5File_close_test test_file("open_file_test.hdf5", HDF5File::Open);
+            file_id = test_file.get_file_id();
+            // check that the file has one more open object (the leak) than it should
+            shouldEqual(H5Fget_obj_count(file_id, H5F_OBJ_ALL), 3);
+            shouldEqual(H5Fget_obj_count(file_id, H5F_OBJ_ALL | H5F_OBJ_LOCAL), 2);
+            // check that the 'leaked' object is still usable
+            H5Gclose(leak_id);
+            shouldEqual(H5Fget_obj_count(file_id, H5F_OBJ_ALL), 2);
+        }
+    }
+};
+
+
+
+struct HDF5ImportExportTestSuite : public vigra::test_suite
+{
+    HDF5ImportExportTestSuite()
+        : vigra::test_suite("HDF5ImportExportTestSuite")
+    {
+        // tests for scalar data
+        add(testCase(&HDF5ExportImportTest::testScalarUnstridedHDF5ExportImport));
+        add(testCase(&HDF5ExportImportTest::testScalarStridedHDF5ExportImport));
+
+        // tests for non-scalar data
+        // RGBValue
+        add(testCase(&HDF5ExportImportTest::testRGBValueUnstridedHDF5ExportImport));
+        add(testCase(&HDF5ExportImportTest::testRGBValueStridedHDF5ExportImport));
+        // TinyVector
+        add(testCase(&HDF5ExportImportTest::testTinyVectorUnstridedHDF5ExportImport));
+        add(testCase(&HDF5ExportImportTest::testTinyVectorStridedHDF5ExportImport));
+
+        // mixed forms
+        add(testCase(&HDF5ExportImportTest::testScalarToRGBValueUnstridedHDF5ExportImport));
+
+        // general tests
+        add(testCase(&HDF5ExportImportTest::testOverwriteExistingDataInHDF5));
+        add(testCase(&HDF5ExportImportTest::testAppendNewDataToHDF5));
+
+        // HDF5File tests
+        add(testCase(&HDF5ExportImportTest::testHDF5FileDataAccess));
+        add(testCase(&HDF5ExportImportTest::testHDF5FileBlockAccess));
+        add(testCase(&HDF5ExportImportTest::testHDF5FileChunks));
+        add(testCase(&HDF5ExportImportTest::testHDF5FileCompression));
+        add(testCase(&HDF5ExportImportTest::testHDF5FileBrowsing));
+        add(testCase(&HDF5ExportImportTest::testHDF5FileAttributes));
+        add(testCase(&HDF5ExportImportTest::testHDF5FileTutorial));
+        add(testCase(&HDF5ExportImportTest::test_file_closing));
+    }
+};
+
+
+int main (int argc, char ** argv)
+{
+    HDF5ImportExportTestSuite test;
+    const int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test.report() << std::endl;
+
+    return failed != 0;
+}
diff --git a/test/image/CMakeLists.txt b/test/image/CMakeLists.txt
new file mode 100644
index 0000000..a1a6813
--- /dev/null
+++ b/test/image/CMakeLists.txt
@@ -0,0 +1,3 @@
+VIGRA_ADD_TEST(test_image test.cxx LIBRARIES vigraimpex)
+
+VIGRA_COPY_TEST_DATA(lenna.xv)
diff --git a/test/image/lenna.gif b/test/image/lenna.gif
new file mode 100644
index 0000000..525fa72
Binary files /dev/null and b/test/image/lenna.gif differ
diff --git a/test/image/lenna.xv b/test/image/lenna.xv
new file mode 100644
index 0000000..03ec3f4
Binary files /dev/null and b/test/image/lenna.xv differ
diff --git a/test/image/test.cxx b/test/image/test.cxx
new file mode 100755
index 0000000..1b55c2a
--- /dev/null
+++ b/test/image/test.cxx
@@ -0,0 +1,914 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include "vigra/unittest.hxx"
+#include "vigra/stdimage.hxx"
+#include "vigra/basicimageview.hxx"
+#include "vigra/imageiterator.hxx"
+#include "vigra/impex.hxx"
+#include "vigra/imagecontainer.hxx"
+#include "vigra/inspectimage.hxx"
+#include "vigra/pixelneighborhood.hxx"
+#include "vigra/contourcirculator.hxx"
+
+using vigra::Diff2D;
+using namespace vigra;
+
+unsigned char * testData(unsigned char)
+{
+    static unsigned char data[] = {1,2,3,4,5,6,7,8,9};
+    return data;
+}
+
+double * testData(double)
+{
+    static double data[] = {1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9};
+    return data;
+}
+
+RGBValue<unsigned char> * testData(RGBValue<unsigned char>)
+{
+    typedef RGBValue<unsigned char> BRGB;
+    static BRGB data[] = {
+        BRGB(1,1,1),
+        BRGB(2,2,2),
+        BRGB(3,3,3),
+        BRGB(4,4,4),
+        BRGB(5,5,5),
+        BRGB(6,6,6),
+        BRGB(7,7,7),
+        BRGB(8,8,8),
+        BRGB(9,9,9)
+    };
+    return data;
+}
+
+RGBValue<float> * testData(RGBValue<float>)
+{
+    typedef vigra::RGBValue<float> FRGB;
+    static FRGB data[] = {
+        FRGB(1.1f, 1.1f, 1.1f),
+        FRGB(2.2f, 2.2f, 2.2f),
+        FRGB(3.3f, 3.3f, 3.3f),
+        FRGB(4.4f, 4.4f, 4.4f),
+        FRGB(5.5f, 5.5f, 5.5f),
+        FRGB(6.6f, 6.6f, 6.6f),
+        FRGB(7.7f, 7.7f, 7.7f),
+        FRGB(8.8f, 8.8f, 8.8f),
+        FRGB(9.9f, 9.9f, 9.9f)
+    };
+    return data;
+}
+
+template <class IMAGE>
+struct ImageTest
+{
+    typedef IMAGE Image;
+    typedef typename Image::value_type value_type;
+    value_type internalMemory[9];
+    value_type * data;
+
+    ImageTest(IMAGE const & image) :
+            data(testData(value_type())),
+            img(image)
+    {
+        typename Image::Accessor acc = img.accessor();
+        typename Image::iterator i = img.begin();
+        
+        acc.set(data[0], i);
+        ++i;
+        acc.set(data[1], i);
+        ++i;
+        acc.set(data[2], i);
+        ++i;
+        acc.set(data[3], i);
+        ++i;
+        acc.set(data[4], i);
+        ++i;
+        acc.set(data[5], i);
+        ++i;
+        acc.set(data[6], i);
+        ++i;
+        acc.set(data[7], i);
+        ++i;
+        acc.set(data[8], i);
+        ++i;
+        should(i == img.end());
+    }
+
+    template <class Iterator>
+    void scanImage(Iterator ul, Iterator lr)
+    {
+        Iterator y = ul;
+        Iterator x = ul;
+        typename Image::Accessor acc = img.accessor();
+
+        should(acc(x) == data[0]);
+        ++x.x;
+        should(acc(x) == data[1]);
+        ++x.x;
+        should(acc(x) == data[2]);
+        ++x.x;
+        should(x.x == lr.x);
+
+        ++y.y;
+        x = y;
+        should(acc(x) == data[3]);
+        ++x.x;
+        should(acc(x) == data[4]);
+        ++x.x;
+        should(acc(x) == data[5]);
+        ++y.y;
+        x = y;
+        should(acc(x) == data[6]);
+        ++x.x;
+        should(acc(x) == data[7]);
+        ++x.x;
+        should(acc(x) == data[8]);
+        ++y.y;
+        should(y.y == lr.y);
+
+        y = ul;
+        should(acc(y, vigra::Diff2D(1,1)) == data[4]);
+    }
+
+    template <class Iterator>
+    void scanRows(Iterator r1, Iterator r2, Iterator r3, int w)
+    {
+        Iterator end = r1 + w;
+        typename Image::Accessor acc = img.accessor();
+
+        should(acc(r1) == data[0]);
+        ++r1;
+        should(acc(r1) == data[1]);
+        ++r1;
+        should(acc(r1) == data[2]);
+        ++r1;
+        should(r1 == end);
+
+        end = r2 + w;
+        should(acc(r2) == data[3]);
+        ++r2;
+        should(acc(r2) == data[4]);
+        ++r2;
+        should(acc(r2) == data[5]);
+        ++r2;
+        should(r2 == end);
+
+        end = r3 + w;
+        should(acc(r3) == data[6]);
+        ++r3;
+        should(acc(r3) == data[7]);
+        ++r3;
+        should(acc(r3) == data[8]);
+        ++r3;
+        should(r3 == end);
+    }
+
+    template <class Iterator>
+    void scanColumns(Iterator c1, Iterator c2, Iterator c3, int h)
+    {
+        Iterator end = c1 + h;
+        typename Image::Accessor acc = img.accessor();
+
+        should(acc(c1) == data[0]);
+        ++c1;
+        should(acc(c1) == data[3]);
+        ++c1;
+        should(acc(c1) == data[6]);
+        ++c1;
+        should(c1 == end);
+
+        end = c2 + h;
+        should(acc(c2) == data[1]);
+        ++c2;
+        should(acc(c2) == data[4]);
+        ++c2;
+        should(acc(c2) == data[7]);
+        ++c2;
+        should(c2 == end);
+
+        end = c3 + h;
+        should(acc(c3) == data[2]);
+        ++c3;
+        should(acc(c3) == data[5]);
+        ++c3;
+        should(acc(c3) == data[8]);
+        ++c3;
+        should(c3 == end);
+    }
+
+    void testIterator()
+    {
+        typename Image::Iterator ul = img.upperLeft();
+        typename Image::Iterator lr = img.lowerRight();
+
+        scanImage(ul, lr);
+        scanRows(ul.rowIterator(), (ul+Diff2D(0,1)).rowIterator(),
+                 (ul+Diff2D(0,2)).rowIterator(), img.width());
+        scanRows(img.rowBegin(0), img.rowBegin(1),
+                 img.rowBegin(2), img.width());
+        scanColumns(ul.columnIterator(), (ul+Diff2D(1,0)).columnIterator(),
+                 (ul+Diff2D(2,0)).columnIterator(), img.height());
+        scanColumns(img.columnBegin(0), img.columnBegin(1),
+                 img.columnBegin(2), img.height());
+
+        typename Image::Accessor acc = img.accessor();
+        typename Image::iterator i = img.begin();
+        should(acc(i, 4) == data[4]);
+    }
+
+    void testIndex()
+    {
+        for (int y=0; y<img.height(); ++y)
+        {
+            for(int x=0; x<img.width(); ++x)
+            {
+                shouldEqual(data[y*img.width()+x], img[Diff2D(x,y)]);
+                shouldEqual(data[y*img.width()+x], img(x,y));
+            }
+        }
+    }
+
+    void testConstructor()
+    {
+        Image img1(img.width(), img.height(), data);
+        
+        shouldEqual(img1.width(), img.width());
+        shouldEqual(img1.height(), img.height());
+        shouldEqualSequence(img.begin(), img.end(), img1.begin());
+        
+        Image img2(img.width(), img.height(), SkipInitialization);
+        
+        shouldEqual(img2.width(), img.width());
+        shouldEqual(img2.height(), img.height());
+    }
+
+    void copyImage()
+    {
+        typedef typename Image::value_type Value;
+
+        Image img1(img);
+        typename Image::iterator i = img.begin();
+        typename Image::iterator i1 = img1.begin();
+        typename Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i, ++i1)
+        {
+            should(acc(i) == acc(i1));
+        }
+
+        img.init(NumericTraits<Value>::zero());
+        for(; i != img.end(); ++i)
+        {
+            should(acc(i) == NumericTraits<Value>::zero());
+        }
+        img(1,1) = Value(200);
+        img1 = img;
+        i = img.begin();
+        i1 = img1.begin();
+
+        for(; i != img.end(); ++i, ++i1)
+        {
+            should(acc(i) == acc(i1));
+        }
+    }
+
+    Image img;
+};
+
+template <class IMAGE>
+struct BasicImageTest
+: public ImageTest<IMAGE>
+{
+    BasicImageTest()
+    : ImageTest<IMAGE>(IMAGE(Diff2D(3,3)))
+    {}
+
+    // next lines needed due to gcc 2.95 bug
+    void testIterator()
+    {
+        ImageTest<IMAGE>::testIterator();
+    }
+
+    void testIndex()
+    {
+        ImageTest<IMAGE>::testIndex();
+    }
+
+    void testConstructor()
+    {
+        ImageTest<IMAGE>::testConstructor();
+    }
+
+    void copyImage()
+    {
+        ImageTest<IMAGE>::copyImage();
+    }
+
+    void swapImage()
+    {
+        IMAGE other(1,1);
+        other(0,0) = this->data[2];
+        
+        this->img.swap(other);
+        
+        shouldEqual(this->img.width(), 1);
+        shouldEqual(this->img.height(), 1);
+        shouldEqual(this->img(0,0), this->data[2]);
+        shouldEqual(other.width(), 3);
+        shouldEqual(other.height(), 3);
+        shouldEqual(other(2,2), this->data[8]);
+    }
+};
+
+template <class IMAGE>
+struct BasicImageViewTest
+: public ImageTest<IMAGE>
+{
+    
+    BasicImageViewTest()
+    : ImageTest<IMAGE>(IMAGE(ImageTest<IMAGE>::internalMemory, Diff2D(3,3)))
+    {}
+
+    // next lines needed due to gcc 2.95 bug
+    void testIterator()
+    {
+        ImageTest<IMAGE>::testIterator();
+    }
+
+    void testIndex()
+    {
+        ImageTest<IMAGE>::testIndex();
+    }
+
+    void copyImage()
+    {
+        ImageTest<IMAGE>::copyImage();
+    }
+};
+
+template <class T>
+struct StridedImageIteratorTest
+{
+    T * data_;
+    
+    StridedImageIteratorTest()
+    : data_(testData(T()))
+    {}
+
+    void testIterator()
+    {
+        int w = 3, h = 3;
+        int xskip = 2, yskip = 2;
+        int ws = w / xskip + 1, hs = h / yskip + 1;
+        
+        StridedImageIterator<T> ul(data_, w, xskip, yskip);
+        StridedImageIterator<T> lr = ul + Diff2D(ws, hs);
+        
+        shouldEqual(ws, lr.x - ul.x);
+        shouldEqual(hs, lr.y - ul.y);
+        shouldEqual(Diff2D(ws, hs), lr - ul);
+        
+        StridedImageIterator<T> x = ul;
+        typename StridedImageIterator<T>::row_iterator r = ul.rowIterator();
+        typename StridedImageIterator<T>::row_iterator rend = r + ws;
+        shouldEqual(data_[0], *x);
+        shouldEqual(data_[0], *r);
+        should(x.x < lr.x);
+        should(r < rend);
+        ++x.x;
+        ++r;
+        shouldEqual(data_[2], *x);
+        shouldEqual(data_[2], *r);
+        should(x.x < lr.x);
+        should(r < rend);
+        ++x.x;
+        ++r;
+        should(x.x == lr.x);
+        should(r == rend);
+        
+        ++ul.y;
+        x = ul;
+        r = ul.rowIterator();
+        rend = r + ws;
+        shouldEqual(data_[6], *x);
+        shouldEqual(data_[6], *r);
+        should(x.x < lr.x);
+        should(r < rend);
+        ++x.x;
+        ++r;
+        shouldEqual(data_[8], *x);
+        shouldEqual(data_[8], *r);
+        should(x.x < lr.x);
+        should(r < rend);
+        ++x.x;
+        ++r;
+        should(x.x == lr.x);
+        should(r == rend);
+
+        ++ul.y;
+        should(ul.y == lr.y);
+    }
+};
+
+
+struct ImageTestSuite
+: public vigra::test_suite
+{
+    ImageTestSuite()
+    : vigra::test_suite("ImageTestSuite")
+    {
+        add( testCase( &BasicImageTest<BasicImage<unsigned char> >::testIterator));
+        add( testCase( &BasicImageTest<BasicImage<unsigned char> >::testIndex));
+        add( testCase( &BasicImageTest<BasicImage<unsigned char> >::testConstructor));
+        add( testCase( &BasicImageTest<BasicImage<unsigned char> >::copyImage));
+        add( testCase( &BasicImageTest<BasicImage<unsigned char> >::swapImage));
+        add( testCase( &BasicImageTest<BasicImage<double> >::testIterator));
+        add( testCase( &BasicImageTest<BasicImage<double> >::testIndex));
+        add( testCase( &BasicImageTest<BasicImage<double> >::testConstructor));
+        add( testCase( &BasicImageTest<BasicImage<double> >::copyImage));
+        add( testCase( &BasicImageTest<BasicImage<double> >::swapImage));
+        add( testCase( &BasicImageTest<BasicImage<RGBValue<unsigned char> > >::testIterator));
+        add( testCase( &BasicImageTest<BasicImage<RGBValue<unsigned char> > >::testIndex));
+        add( testCase( &BasicImageTest<BasicImage<RGBValue<unsigned char> > >::testConstructor));
+        add( testCase( &BasicImageTest<BasicImage<RGBValue<unsigned char> > >::copyImage));
+        add( testCase( &BasicImageTest<BasicImage<RGBValue<unsigned char> > >::swapImage));
+        add( testCase( &BasicImageTest<BasicImage<RGBValue<float> > >::testIterator));
+        add( testCase( &BasicImageTest<BasicImage<RGBValue<float> > >::testIndex));
+        add( testCase( &BasicImageTest<BasicImage<RGBValue<float> > >::testConstructor));
+        add( testCase( &BasicImageTest<BasicImage<RGBValue<float> > >::copyImage));
+        add( testCase( &BasicImageTest<BasicImage<RGBValue<float> > >::swapImage));
+        add( testCase( &BasicImageViewTest<BasicImageView<unsigned char> >::testIterator));
+        add( testCase( &BasicImageViewTest<BasicImageView<unsigned char> >::testIndex));
+        add( testCase( &BasicImageViewTest<BasicImageView<unsigned char> >::copyImage));
+        add( testCase( &BasicImageViewTest<BasicImageView<double> >::testIterator));
+        add( testCase( &BasicImageViewTest<BasicImageView<double> >::testIndex));
+        add( testCase( &BasicImageViewTest<BasicImageView<double> >::copyImage));
+        add( testCase( &BasicImageViewTest<BasicImageView<RGBValue<unsigned char> > >::testIterator));
+        add( testCase( &BasicImageViewTest<BasicImageView<RGBValue<unsigned char> > >::testIndex));
+        add( testCase( &BasicImageViewTest<BasicImageView<RGBValue<unsigned char> > >::copyImage));
+        add( testCase( &BasicImageViewTest<BasicImageView<RGBValue<float> > >::testIterator));
+        add( testCase( &BasicImageViewTest<BasicImageView<RGBValue<float> > >::testIndex));
+        add( testCase( &BasicImageViewTest<BasicImageView<RGBValue<float> > >::copyImage));
+        add( testCase( &StridedImageIteratorTest<unsigned char>::testIterator));
+        add( testCase( &StridedImageIteratorTest<RGBValue<float> >::testIterator));
+    }
+};
+
+struct CompareFunctor
+{
+    double sumDifference_;
+
+    CompareFunctor(): sumDifference_(0) {}
+
+    void operator()(const float &a, const float &b)
+    { sumDifference_+=  VIGRA_CSTD::abs(a-b); }
+
+    double operator()()
+        { return sumDifference_; }
+};
+
+struct ImageContainerTests
+{
+    ImageImportInfo info;
+    int w, h;
+    FImage lennaImage;
+
+    ImageContainerTests()
+        : info("lenna.xv"),
+          w(info.width()), h(info.height()),
+          lennaImage(w, h)
+    {
+        importImage(info, destImage(lennaImage));
+    }
+
+    void initArrayWithImageTest()
+    {
+        ImageArray<FImage> threeLennas(3, lennaImage);
+        CompareFunctor cmp;
+        inspectTwoImages(srcImageRange(threeLennas[0]), srcImage(threeLennas[2]), cmp);
+        shouldEqual(cmp(), 0.0);
+
+        Diff2D newsize(50, 50);
+        threeLennas.resizeImages(newsize);
+        for (ImageArray<FImage>::iterator it= threeLennas.begin(); it!= threeLennas.end(); it++)
+            shouldEqual((*it).size(), newsize);
+    }
+
+    void initArrayWithSizeTest()
+    {
+        Diff2D testsize(50, 50);
+        ImageArray<FImage> ia(6, testsize);
+
+        for (unsigned int i=0; i<ia.size(); i++)
+            shouldEqual(ia[i].size(), testsize);
+
+        ImageArray<FImage> ia2(ia.begin(), ia.end());
+        shouldEqual(ia2.imageSize(), testsize);
+
+        ia2.erase(ia2.begin()+1);
+        shouldEqual(ia2.size(), ia.size()-1);
+
+        ia.clear();
+        shouldEqual(ia.size(), 0u);
+    }
+};
+
+struct ImageContainerTestSuite
+: public vigra::test_suite
+{
+    ImageContainerTestSuite()
+    : vigra::test_suite("ImageContainerTestSuite")
+    {
+        add( testCase( &ImageContainerTests::initArrayWithImageTest ) );
+        add( testCase( &ImageContainerTests::initArrayWithSizeTest ) );
+    }
+};
+
+struct NeighborhoodCirculatorTest
+{
+    typedef vigra::NeighborhoodCirculator<vigra::BImage::Iterator, vigra::EightNeighborCode>
+    EightCirculator;
+    typedef vigra::NeighborhoodCirculator<vigra::BImage::Iterator, vigra::FourNeighborCode>
+    FourCirculator;
+
+    vigra::BImage img;
+    EightCirculator eightCirc;
+    FourCirculator fourCirc;
+
+    NeighborhoodCirculatorTest()
+        : img(4, 4),
+          eightCirc(img.upperLeft() + vigra::Diff2D(1, 1)),
+          fourCirc(img.upperLeft() + vigra::Diff2D(1, 1))
+    {
+        for(int y= 0; y<img.height(); y++)
+            for(int x= 0; x<img.width(); x++)
+                img(x, y)= y*img.width() + x;
+    }
+
+    void testInit()
+    {
+        shouldEqual(*eightCirc, 6);
+        should(!eightCirc.isDiagonal());
+        shouldEqual(*fourCirc, 6);
+        should(!fourCirc.isDiagonal());
+    }
+
+    void testEightCirculateForward()
+    {
+        eightCirc++;
+        shouldEqual(*eightCirc, 2);
+        eightCirc++;
+        shouldEqual(*eightCirc, 1);
+        eightCirc++;
+        shouldEqual(*eightCirc, 0);
+        eightCirc++;
+        shouldEqual(*eightCirc, 4);
+        eightCirc++;
+        shouldEqual(*eightCirc, 8);
+        eightCirc++;
+        shouldEqual(*eightCirc, 9);
+        eightCirc++;
+        shouldEqual(*eightCirc, 10);
+        eightCirc++;
+        shouldEqual(*eightCirc, 6);
+    }
+
+    void testEightCirculateReverse()
+    {
+        eightCirc--;
+        shouldEqual(*eightCirc, 10);
+        eightCirc--;
+        shouldEqual(*eightCirc, 9);
+        eightCirc--;
+        shouldEqual(*eightCirc, 8);
+        eightCirc--;
+        shouldEqual(*eightCirc, 4);
+        eightCirc--;
+        shouldEqual(*eightCirc, 0);
+        eightCirc--;
+        shouldEqual(*eightCirc, 1);
+        eightCirc--;
+        shouldEqual(*eightCirc, 2);
+        eightCirc--;
+        shouldEqual(*eightCirc, 6);
+    }
+
+    void testFourCirculateForward()
+    {
+        fourCirc++;
+        shouldEqual(*fourCirc, 1);
+        fourCirc++;
+        shouldEqual(*fourCirc, 4);
+        fourCirc++;
+        shouldEqual(*fourCirc, 9);
+        fourCirc++;
+        shouldEqual(*fourCirc, 6);
+    }
+
+    void testFourCirculateReverse()
+    {
+        fourCirc--;
+        shouldEqual(*fourCirc, 9);
+        fourCirc--;
+        shouldEqual(*fourCirc, 4);
+        fourCirc--;
+        shouldEqual(*fourCirc, 1);
+        fourCirc--;
+        shouldEqual(*fourCirc, 6);
+    }
+
+    void testIsDiagonal()
+    {
+        for(int i=0; i<10; i++, eightCirc++, fourCirc++)
+        {
+            if(i%2)
+                should(eightCirc.isDiagonal());
+            else
+                should(!eightCirc.isDiagonal());
+            should(!fourCirc.isDiagonal());
+        }
+    }
+
+    void testEquality()
+    {
+        EightCirculator eightCirc2 = eightCirc;
+        should(eightCirc == eightCirc2);
+        eightCirc2++;
+        should(eightCirc != eightCirc2);
+        eightCirc2++;
+        should(eightCirc != eightCirc2);
+        eightCirc++;
+        should(eightCirc != eightCirc2);
+        eightCirc2--;
+        should(eightCirc == eightCirc2);
+
+        FourCirculator fourCirc2(img.upperLeft() + vigra::Diff2D(1, 1));
+        should(fourCirc == fourCirc2);
+        fourCirc--;
+        should(fourCirc != fourCirc2);
+
+        eightCirc2 = eightCirc + 3;
+        eightCirc += 3;
+        should(eightCirc == eightCirc2);
+
+        fourCirc2 = fourCirc + 3;
+        fourCirc += 3;
+        should(fourCirc == fourCirc2);
+    }
+
+    void testTurning()
+    {
+        for(int i=0; i<4; i++)
+        {
+            shouldEqual(*fourCirc, *eightCirc);
+            fourCirc.turnRight();
+            eightCirc.turnRight();
+        }
+
+        for(int i=0; i<4; i++)
+        {
+            shouldEqual(*fourCirc, *eightCirc);
+            fourCirc.turnLeft();
+            eightCirc.turnLeft();
+        }
+
+        fourCirc.turnLeft();
+        fourCirc.turnLeft();
+        eightCirc.turnRound();
+        shouldEqual(*fourCirc, *eightCirc);
+
+        eightCirc.turnRight();
+        eightCirc.turnRight();
+        fourCirc.turnRound();
+        shouldEqual(*fourCirc, *eightCirc);
+    }
+
+    void testMoving()
+    {
+        eightCirc.swapCenterNeighbor();
+        shouldEqual(*eightCirc, 5); // looking west from 6 now
+        eightCirc++;
+        shouldEqual(*eightCirc, 9);
+        eightCirc++;
+        shouldEqual(*eightCirc, 10);
+        eightCirc++;
+        shouldEqual(*eightCirc, 11);
+        eightCirc++;
+        shouldEqual(*eightCirc, 7); // looking east again
+
+        eightCirc+= 4; // looking west again
+        eightCirc.moveCenterToNeighbor();
+        shouldEqual(*eightCirc, 4);
+    }
+
+    void testMiscellaneous()
+    {
+        // test direction()
+        should(fourCirc.direction() == vigra::FourNeighborCode::East);
+
+        // test operator -
+        EightCirculator eightCirc2 = eightCirc;
+        for(int i=0; i<7; i++, eightCirc2++)
+            shouldEqual(eightCirc2 - eightCirc, i);
+
+        // test operator[]
+        should(eightCirc2[1] == *eightCirc);
+
+        // test base()
+        eightCirc += vigra::EightNeighborCode::SouthEast - eightCirc.direction();
+        eightCirc.moveCenterToNeighbor();
+        should(eightCirc.base() - img.upperLeft() == vigra::Diff2D(3, 3));
+        eightCirc.turnRound();
+        eightCirc.swapCenterNeighbor();
+        should(eightCirc.base() - img.upperLeft() == vigra::Diff2D(2, 2));
+        eightCirc.turnRound();
+        should(eightCirc.base() - img.upperLeft() == vigra::Diff2D(0, 0));
+    }
+};
+
+struct CrackContourCirculatorTest
+{
+    typedef vigra::CrackContourCirculator<vigra::BImage::traverser> CrackCirc;
+
+    vigra::BImage img;
+
+    CrackContourCirculatorTest()
+            : img(8,8)
+    {
+        static int imdata[] = {
+            0, 0, 0, 0, 0, 0, 0, 0,
+            0, 1, 1, 0, 0, 1, 0, 0,
+            0, 1, 1, 1, 1, 1, 1, 0,
+            0, 1, 1, 1, 1, 0, 0, 0,
+            0, 0, 0, 1, 1, 0, 0, 0,
+            0, 0, 1, 1, 1, 1, 1, 0,
+            0, 0, 1, 1, 1, 1, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0
+        };
+    
+        for(int i = 0; i<img.width()*img.height(); ++i)
+            img.begin()[i] = imdata[i];
+    }
+
+    void testInit()
+    {
+        CrackCirc crackCirc(img.upperLeft() + vigra::Diff2D(1, 1));
+        CrackCirc end = crackCirc;
+        
+        should(crackCirc.pos() == vigra::Diff2D(0, 0));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(0, 1));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(0, 2));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(0, 3));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(1, 3));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(2, 3));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(2, 4));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(1, 4));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(1, 5));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(1, 6));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(2, 6));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(3, 6));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(4, 6));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(5, 6));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(5, 5));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(6, 5));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(6, 4));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(5, 4));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(4, 4));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(4, 3));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(4, 2));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(5, 2));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(6, 2));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(6, 1));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(5, 1));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(5, 0));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(4, 0));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(4, 1));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(3, 1));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(2, 1));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(2, 0));
+        ++crackCirc;
+        should(crackCirc.pos() == vigra::Diff2D(1, 0));
+        ++crackCirc;
+        should(crackCirc == end);
+    }
+
+};
+
+struct NeighborhoodCirculatorTestSuite
+: public vigra::test_suite
+{
+    NeighborhoodCirculatorTestSuite()
+    : vigra::test_suite("NeighborhoodCirculatorTestSuite")
+    {
+        add( testCase( &NeighborhoodCirculatorTest::testInit));
+        add( testCase( &NeighborhoodCirculatorTest::testEightCirculateForward));
+        add( testCase( &NeighborhoodCirculatorTest::testEightCirculateReverse));
+        add( testCase( &NeighborhoodCirculatorTest::testFourCirculateForward));
+        add( testCase( &NeighborhoodCirculatorTest::testFourCirculateReverse));
+        add( testCase( &NeighborhoodCirculatorTest::testIsDiagonal));
+        add( testCase( &NeighborhoodCirculatorTest::testEquality));
+        add( testCase( &NeighborhoodCirculatorTest::testTurning));
+        add( testCase( &NeighborhoodCirculatorTest::testMoving));
+        add( testCase( &NeighborhoodCirculatorTest::testMiscellaneous));
+   }
+};
+
+struct CrackContourCirculatorTestSuite
+: public vigra::test_suite
+{
+    CrackContourCirculatorTestSuite()
+    : vigra::test_suite("CrackContourCirculatorTestSuite")
+    {
+        add( testCase( &CrackContourCirculatorTest::testInit));
+   }
+};
+
+struct ImageTestCollection
+: public vigra::test_suite
+{
+    ImageTestCollection()
+    : vigra::test_suite("ImageTestCollection")
+    {
+        add( new ImageTestSuite);
+        add( new ImageContainerTestSuite);
+        add( new NeighborhoodCirculatorTestSuite);
+        add( new CrackContourCirculatorTestSuite);
+   }
+};
+
+int main(int argc, char ** argv)
+{
+    ImageTestCollection test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+
+    return (failed != 0);
+}
+
diff --git a/test/imagehierarchy/NewImHier.hxx b/test/imagehierarchy/NewImHier.hxx
new file mode 100755
index 0000000..9b18b11
--- /dev/null
+++ b/test/imagehierarchy/NewImHier.hxx
@@ -0,0 +1,2205 @@
+#ifndef VIGRA_IMAGEHIERARCHY_HXX
+#define VIGRA_IMAGEHIERARCHY_HXX
+
+#include "vigra/stdimage.hxx" 
+#include "vigra/stdimagefunctions.hxx"
+#include "vigra/imageiterator.hxx"
+#include "vigra/accessor.hxx"
+#include "vigra/utilities.hxx"
+#include "boost/smart_ptr.hpp" 
+#include "boost/static_assert.hpp"
+
+namespace vigra {
+
+typedef float GrayValue;                     
+
+/** Stellt ein Pixel dar, also ein Einband, Zweiband, Dreiband oder Vierband Pixel, also je nachdem um was es
+* fuer ein Pixel handelt, soviele Eintraege enthaelt auch der Vectorproxy, also z.B. ein Vierband-Pixel als 
+* VectorProxy hat vier Eintraege
+*/
+class ConstVectorProxy
+{
+  public:
+    typedef GrayValue value_type;
+    typedef GrayValue const * iterator;
+    typedef GrayValue const * const_iterator;
+    
+    ConstVectorProxy()
+    : data_(0), size_(0)
+    {}
+    
+    ConstVectorProxy(GrayValue const * data, int size)
+    : data_(const_cast<value_type *>(data)), size_(size)
+    {}
+    
+    ConstVectorProxy(value_type const & f)
+    : data_(const_cast<value_type *>(&f)), size_(1)
+    {}
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION                                      ////AEND_1////////
+    template <int N>
+    ConstVectorProxy(TinyVector<value_type, N> const & v)
+    : data_(const_cast<TinyVector<value_type, N> &>(v).begin()), size_(N)
+    {}
+#else   
+    ConstVectorProxy(TinyVector<value_type, 2> const & v)
+    : data_(const_cast<TinyVector<value_type, 2> &>(v).begin()), size_(2)
+    {}
+
+    ConstVectorProxy(TinyVector<value_type, 3> const & v)
+    : data_(const_cast<TinyVector<value_type, 3> &>(v).begin()), size_(3)
+    {}
+
+    ConstVectorProxy(TinyVector<value_type, 4> const & v)
+    : data_(const_cast<TinyVector<value_type, 4> &>(v).begin()), size_(4)
+    {}
+#endif                                                            //////AEND_1//////////////
+
+    void reset(ConstVectorProxy const & v)
+    {
+        data_ = v.data_;
+        size_ = v.size_;
+    }
+    
+    void reset(value_type const & f)
+    {
+        data_ = const_cast<value_type *>(&f);
+        size_ = 1;
+    }
+    
+    
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION                                  /////////////AEND_2//////////
+    template <int N>
+    void reset(TinyVector<value_type, N> const & v)
+    {
+        data_ = const_cast<TinyVector<value_type, N> &>(v).begin();
+        size_ = N;
+    }
+#else
+    void reset(TinyVector<value_type, 2> const & v)
+    {
+        data_ = const_cast<TinyVector<value_type, 2> &>(v).begin();
+        size_ = 2;
+    }
+    
+    void reset(TinyVector<value_type, 3> const & v)
+    {
+        data_ = const_cast<TinyVector<value_type, 3> &>(v).begin();
+        size_ = 3;
+    }
+    
+    void reset(TinyVector<value_type, 4> const & v)
+    {
+        data_ = const_cast<TinyVector<value_type, 4> &>(v).begin();
+        size_ = 4;
+    }
+#endif                                                                      /////////////AEND_2//////////
+    
+    void resize(int new_size)
+        { size_ = new_size; }
+    
+    iterator begin()
+        { return data_; }
+    
+    iterator end()
+        { return data_ + size_; }
+    
+    const_iterator begin() const
+        { return data_; }
+    
+    const_iterator end() const
+        { return data_ + size_; }
+    
+    value_type const & operator[](int i) const
+        { return data_[i]; }
+        
+    int size() const
+        { return size_; }
+        
+    operator value_type() const
+    {
+        vigra_precondition(size_ == 1, 
+            "ConstVectorProxy::operator value_type(): vector must have size 1.");
+        return *data_;
+    }
+    
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION                          ///////////AEND_3///////////
+    template <int N>
+    operator TinyVector<value_type, N>() const
+    {
+        vigra_precondition(size_ == N, 
+            "ConstVectorProxy::operator TinyVector(): size mismatch.");
+        TinyVector<value_type, N> res;
+        res.init(begin(), end());
+        return res;
+    }
+#else
+    operator TinyVector<value_type, 2>() const
+    {
+        vigra_precondition(size_ == 2, 
+            "ConstVectorProxy::operator TinyVector(): size mismatch.");
+        TinyVector<value_type, 2> res;
+        res.init(begin(), end());
+        return res;
+    }
+    operator TinyVector<value_type, 3>() const
+    {
+        vigra_precondition(size_ == 3, 
+            "ConstVectorProxy::operator TinyVector(): size mismatch.");
+        TinyVector<value_type, 3> res;
+        res.init(begin(), end());
+        return res;
+    }
+    operator TinyVector<value_type, 4>() const
+    {
+        vigra_precondition(size_ == 4, 
+            "ConstVectorProxy::operator TinyVector(): size mismatch.");
+        TinyVector<value_type, 4> res;
+        res.init(begin(), end());
+        return res;
+    }
+#endif                                                             ///////////AEND_3///////////
+   
+    operator RGBValue<value_type>() const
+    {
+        vigra_precondition(size_ == 3, 
+            "ConstVectorProxy::operator RGBValue(): size mismatch.");
+        return RGBValue<value_type>(begin(), end());
+    }
+    
+    bool operator==(ConstVectorProxy const & o) const
+    {
+        if(size() != o.size())
+            return false;
+        for(int i=0; i<size(); ++i)
+            if ((*this)[i] != o[i])
+                return false;
+        return true;
+    }
+     
+    bool operator!=(ConstVectorProxy const & o) const
+    {
+        return !(*this == o);
+    }
+    
+  protected:
+    
+    ConstVectorProxy & operator=(ConstVectorProxy const & v);
+  
+    ConstVectorProxy & operator=(value_type const & f);
+    
+    template <int N>
+    ConstVectorProxy & operator=(TinyVector<value_type, N> const & v);
+    
+    value_type * data_;
+    int size_;
+};
+
+/** Stellt ein Pixel dar, also ein Einband, Zweiband, Dreiband oder Vierband Pixel, also je nachdem um was es
+* fuer ein Pixel handelt, soviele Eintraege enthaelt auch der Vectorproxy, also z.B. ein Vierband-Pixel als 
+* VectorProxy hat vier Eintraege
+*/
+class VectorProxy
+: public ConstVectorProxy
+{
+  public:
+    
+    typedef GrayValue * iterator;
+    typedef GrayValue const * const_iterator;
+    
+    VectorProxy()
+    {}
+    
+    VectorProxy(GrayValue const * data, int size)
+    : ConstVectorProxy(data, size)
+    {}
+    
+    VectorProxy(value_type const & f)
+    : ConstVectorProxy(f)
+    {}
+    
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION                                      ////AEND_1////////
+    template <int N>
+    VectorProxy(TinyVector<value_type, N> const & v)
+    : ConstVectorProxy(v)
+    {}
+#else   
+    VectorProxy(TinyVector<value_type, 2> const & v)
+    : ConstVectorProxy(v)
+    {}
+
+    VectorProxy(TinyVector<value_type, 3> const & v)
+    : ConstVectorProxy(v)
+    {}
+
+    VectorProxy(TinyVector<value_type, 4> const & v)
+    : ConstVectorProxy(v)
+    {}
+#endif                                                                          //////AEND_1//////////////
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION                            /////////AEND_4////////////
+    template <int N>
+    VectorProxy & operator=(TinyVector<value_type, N> const & v)
+    {
+        vigra_precondition(size_ == N,
+           "VectorProxy::operator=(): size mismatch.");
+        for(int i=0; i<N; ++i)
+            data_[i] = v[i];
+        return *this;
+    }
+#else
+    VectorProxy & operator=(TinyVector<value_type, 2> const & v)
+    {
+        vigra_precondition(size_ == 2,
+           "VectorProxy::operator=(): size mismatch.");
+        for(int i=0; i<2; ++i)
+            data_[i] = v[i];
+        return *this;
+    }
+    
+    VectorProxy & operator=(TinyVector<value_type, 3> const & v)
+    {
+        vigra_precondition(size_ == 3,
+           "VectorProxy::operator=(): size mismatch.");
+        for(int i=0; i<3; ++i)
+            data_[i] = v[i];
+        return *this;
+    }
+    
+    VectorProxy & operator=(TinyVector<value_type, 4> const & v)
+    {
+        vigra_precondition(size_ == 4,
+           "VectorProxy::operator=(): size mismatch.");
+        for(int i=0; i<4; ++i)
+            data_[i] = v[i];
+        return *this;
+    }
+    
+#endif                                                              /////////AEND_4////////////
+    
+    VectorProxy & operator=(value_type const & v)
+    {
+        vigra_precondition(size_ == 1,
+           "VectorProxy::operator=(): size mismatch.");
+        data_[0] = v;
+        return *this;
+    }
+    
+    VectorProxy & operator=(VectorProxy const & v)
+    {
+        vigra_precondition(size_ == v.size(),
+           "VectorProxy::operator=(): size mismatch.");
+        for(int i=0; i<size_; ++i)
+            data_[i] = v[i];
+        return *this;
+    }
+    
+    VectorProxy & operator=(ConstVectorProxy const & v)
+    {
+        vigra_precondition(size_ == v.size(),
+           "VectorProxy::operator=(): size mismatch.");
+        for(int i=0; i<size_; ++i)
+            data_[i] = v[i];
+        return *this;
+    }
+    
+    iterator begin()
+        { return data_; }
+    
+    iterator end()
+        { return data_ + size_; }
+    
+    const_iterator begin() const
+        { return data_; }
+    
+    const_iterator end() const
+        { return data_ + size_; }
+    
+    value_type & operator[](int i)
+        { return data_[i]; }
+        
+    value_type const & operator[](int i) const
+        { return data_[i]; }
+        
+};
+
+template <int N>
+inline bool operator==(TinyVector<GrayValue, N> const & l, ConstVectorProxy const & r)
+{
+    return r == l;
+}
+
+template <class IMAGEITERATOR>
+class MultibandRowColumnIteratorPolicy
+{
+  public:
+    typedef IMAGEITERATOR                            ImageIterator;
+    typedef typename ImageIterator::value_type       value_type;
+    typedef int                                      difference_type;
+    typedef typename ImageIterator::reference        reference;
+    typedef typename ImageIterator::index_reference  index_reference;
+    typedef typename ImageIterator::pointer          pointer;
+    typedef std::random_access_iterator_tag          iterator_category;
+    
+    
+    struct BaseType
+    {
+        explicit BaseType(pointer c = 0, difference_type o = 0, difference_type s = 0)
+        : current_(c), offset_(o), size_(s)
+        {}
+        
+        pointer current_;
+        difference_type offset_, size_;
+    };
+    
+    static void initialize(BaseType & d) {}
+    
+    static reference dereference(BaseType const & d)
+        { return reference(d.current_, d.size_); }
+    
+    static index_reference dereference(BaseType const & d, difference_type n)
+    { 
+        return index_reference(d.current_+n*d.offset_, d.size_);
+    }
+    
+    static bool equal(BaseType const & d1, BaseType const & d2)
+        { return d1.current_ == d2.current_; }
+    
+    static bool less(BaseType const & d1, BaseType const & d2)
+        { return d1.current_ < d2.current_; }
+    
+    static difference_type difference(BaseType const & d1, BaseType const & d2)
+        { return (d1.current_ - d2.current_) / d1.offset_; }
+    
+    static void increment(BaseType & d)
+        { d.current_ += d.offset_; }
+    
+    static void decrement(BaseType & d)
+        { d.current_ -= d.offset_; }
+    
+    static void advance(BaseType & d, difference_type n)
+        { d.current_ += d.offset_*n; }
+};
+
+template <class PIXELTYPE, class ITERATOR>
+class VariableBandsIteratorBase
+{
+  protected:
+    
+    PIXELTYPE * data_;
+    int width_, bands_, size_;
+    
+    VariableBandsIteratorBase(PIXELTYPE * data, int width, int bands, int size)
+    : data_(data), width_(width), bands_(bands), size_(size), x(0), y(0)
+    {}
+    
+    VariableBandsIteratorBase()
+    : data_(0), width_(0), bands_(0), size_(0), x(0), y(0)
+    {}
+    
+    PIXELTYPE * get()
+        { return data_ + ((y * width_) + x)*bands_; }
+    
+    PIXELTYPE const * get() const
+        { return data_ + ((y * width_) + x)*bands_; }
+    
+    PIXELTYPE * get(int const & dx, int const & dy)
+        { return data_ + ((dy + y) * width_ + dx + x)*bands_; }
+    
+    PIXELTYPE const * get(int const & dx, int const & dy) const
+        { return data_ + ((dy + y) * width_ + dx + x)*bands_; }
+    
+  public:
+  
+    typedef int MoveX;
+    typedef int MoveY;
+    
+    int x, y;                                    //////////////////////Hier sind die x und y des VariableBandsIterator
+    
+    bool operator==(VariableBandsIteratorBase const & rhs) const
+    {
+        return (x == rhs.x) && (y == rhs.y);
+    }
+
+    bool operator!=(VariableBandsIteratorBase const & rhs) const
+    {
+        return (x != rhs.x) || (y != rhs.y);
+    }
+    
+    Diff2D operator-(VariableBandsIteratorBase const & rhs) const
+    {
+        return Diff2D(x - rhs.x, y - rhs.y);
+    }
+    
+    ITERATOR & operator+=(Diff2D const & s)
+    {
+        x += s.x;
+        y += s.y;
+        return (ITERATOR &)*this;
+    }
+
+    ITERATOR & operator-=(Diff2D const & s)
+    {
+        x -= s.x;
+        y -= s.y;
+        return (ITERATOR &)*this;
+    }
+};
+
+/** 2D Iterator ueber ein VariableBandsImage
+*/
+struct VariableBandsIterator
+: public VariableBandsIteratorBase<GrayValue, VariableBandsIterator>
+{
+  public:
+  
+    typedef VectorProxy          value_type;
+    typedef VectorProxy          PixelType;
+    typedef VectorProxy          reference;
+    typedef VectorProxy          index_reference;
+    typedef GrayValue *          pointer;
+    typedef Diff2D               difference_type;
+    typedef image_traverser_tag  iterator_category;
+    typedef IteratorAdaptor<MultibandRowColumnIteratorPolicy<VariableBandsIterator> > 
+        row_iterator;
+    typedef IteratorAdaptor<MultibandRowColumnIteratorPolicy<VariableBandsIterator> > 
+        column_iterator;
+    
+  
+    VariableBandsIterator(GrayValue * data, int width, int bands, int size)
+    : VariableBandsIteratorBase<GrayValue, VariableBandsIterator>(data, width, bands, size)
+    {}
+    
+    VariableBandsIterator()
+    {}
+    
+    VariableBandsIterator operator+(Diff2D const & s)
+    {
+        VariableBandsIterator res(*this);
+        res += s;
+        return res;
+    }
+
+    VariableBandsIterator operator-(Diff2D const & s)          //////////////////////////////hier die minus-Funktion
+    {
+        VariableBandsIterator res(*this);
+        res -= s;
+        return res;
+    }
+    
+    pointer operator->() const
+    {
+        return const_cast<pointer>(get());
+    }
+    
+    reference operator*() const
+    {
+        return reference(get(), size_);
+    }
+    
+    index_reference operator[](Diff2D const & dist) const
+    {
+        return index_reference(get(dist.x, dist.y), size_);
+    }
+    
+    row_iterator operator[](int dy) const
+    {
+        return row_iterator(
+            row_iterator::BaseType(const_cast<pointer>(get(0, dy)), bands_, size_));
+    }
+    
+    index_reference operator()(int const & dx, int const & dy) const
+    {
+        return index_reference(get(dx, dy), size_);
+    }
+    
+    row_iterator rowIterator() const
+    {
+        return row_iterator(
+            row_iterator::BaseType(const_cast<pointer>(get()), bands_, size_));
+    }
+    
+    column_iterator columnIterator() const
+    {
+        return column_iterator(
+            column_iterator::BaseType(const_cast<pointer>(get()), width_*bands_, size_));
+    }
+};
+
+/** 2D Iterator ueber ein VariableBandsImage
+*/
+struct ConstVariableBandsIterator
+: public VariableBandsIteratorBase<GrayValue, ConstVariableBandsIterator>
+{
+  public:
+  
+    typedef ConstVectorProxy          value_type;
+    typedef ConstVectorProxy          PixelType;
+    typedef ConstVectorProxy          reference;
+    typedef ConstVectorProxy          index_reference;
+    typedef GrayValue const *         pointer;
+    typedef Diff2D               difference_type;
+    typedef image_traverser_tag  iterator_category;
+    typedef IteratorAdaptor<MultibandRowColumnIteratorPolicy<ConstVariableBandsIterator> > 
+        row_iterator;
+    typedef IteratorAdaptor<MultibandRowColumnIteratorPolicy<ConstVariableBandsIterator> > 
+        column_iterator;
+  
+    ConstVariableBandsIterator(GrayValue const * data, int width, int bands, int size)
+    : VariableBandsIteratorBase<GrayValue, ConstVariableBandsIterator>(
+        const_cast<GrayValue *>(data), width, bands, size)
+    {}
+    
+    ConstVariableBandsIterator()
+    {}
+    
+    ConstVariableBandsIterator operator+(Diff2D const & s)
+    {
+        ConstVariableBandsIterator res(*this);
+        res += s;
+        return res;
+    }
+
+    ConstVariableBandsIterator operator-(Diff2D const & s)
+    {
+        ConstVariableBandsIterator res(*this);
+        res -= s;
+        return res;
+    }
+    
+    pointer operator->() const
+    {
+        return get();
+    }
+    
+    reference operator*() const
+    {
+        return reference(get(), size_);
+    }
+    
+    index_reference operator[](Diff2D const & dist) const
+    {
+        return index_reference(get(dist.x, dist.y), size_);
+    }
+    
+    row_iterator operator[](int dy) const
+    {
+        return row_iterator(row_iterator::BaseType(get(0, dy), bands_, size_));
+    }
+    
+    index_reference operator()(int const & dx, int const & dy) const
+    {
+        return index_reference(get(dx, dy), size_);
+    }
+    
+    row_iterator rowIterator() const
+    {
+        return row_iterator(row_iterator::BaseType(get(), bands_, size_));
+    }
+    
+    column_iterator columnIterator() const
+    {
+        return column_iterator(column_iterator::BaseType(get(), width_*bands_, size_));
+    }
+};
+
+/** Policyklasse des ScanOrderIterators, sie implementiert die Besonderheiten des Durchlaufs ueber eine 2D - Sequenz ,
+* wobei die Besonderheiten letzendlich auf Durchlauf einer 1D - Sequenz zurueckgefuehrt werden. ScanOrderIteratorPolicy
+* ist dazu da um spaeter (z.B. in VariableBandsImage) als Templateparameter an den "Interface" IteratorAdaptor
+* uebergeben zu werden und dann durch  typedef IteratorAdaptor<ScanOrderIteratorPolicy<VariableBandsIterator>> ScanOrderIterator
+* den gewoehnte ScanOrderIterator zu sehen bekommen!!! (IteratorAdapter ist die stellt die Schnittstelle zu Verfuegung
+* um Mehrdimensionale Sequenzen als eine 1D-Sequenz zu behandeln). 
+*/
+template <class ImageIterator>
+class ScanOrderIteratorPolicy
+{
+public:
+
+/** Hilfsstruktur, stellt den zugrundeliegenden BaseType zur Verfuegung, speichert in sich den Anfang und das 
+* Ende einer 2D-Sequenz (Matrix), die width Membervariable speichert die Anzahl der Elemente, die zum Anfang der
+* der Initialisation(Konstruieren eines ROI-Objektes) da waren, also die Spaltenzahl(RegionOfInteress) wird zu
+* Erzeugungszeit festgelegt  
+*/          
+struct ROI
+{
+    ROI(ImageIterator ul, ImageIterator lr)
+    : current(ul), lowerRight(lr), width(lr.x-ul.x)  // initialisiert den Zeiger current zunaechst mit der linken oberen Ecke, den lowerRight entsprechend mit lowerRight Ecke   
+    {}
+
+    ROI()
+    : width(0) // die Zeiger werden auf null gesetzt => VORSICHT NULLPOINTER !!! die Matrix ist leer => keine Spalten => width = 0
+    {}
+
+    ImageIterator current, lowerRight;                                           //der "Anfangsiterator" wird current genannt weil ueber ihn wird entschieden die aktuelle Position des Iterators daher nach ist der Name upperLeft nicht zutreffend, lowerRight bezeichnet wie gewoent das Ende der Sequenz, die in diesem Fall, der Matrix entspricht daher auch der Name   
+    int width;                                                                   // speichert Anzahl der Spalten in der Matrix
+};
+
+     typedef ROI                                         BaseType;
+     typedef typename ImageIterator::value_type          value_type;        // the adpator's value type
+     typedef typename ImageIterator::reference           reference;         // the adpator's reference type (result of '*iter')
+     typedef typename ImageIterator::index_reference     index_reference;   // the adpator's index_reference type (result of 'iter[n]')
+     typedef typename ImageIterator::pointer             pointer;           // the adpator's pointer type (result of 'iter.operator->()')
+     typedef std::random_access_iterator_tag             iterator_category; // the adpator's iterator category
+     typedef int                                         difference_type;   // the adpator's difference type (result of 'iter1 - iter2', argument of 'iter[
+
+     static void initialize(BaseType & d) {}
+
+     /** Liefert den aktuell referenzierten Objekt.
+     */
+     static reference dereference(ROI const & r)
+     { 
+         return *r.current; 
+     }
+
+     /** Verschiebt seine aktuelle Position um n Schritte und liefert dann den aktuell referenzierten Objekt.
+     */        
+     static index_reference dereference(ROI r, difference_type n)
+     { 
+         advance(r,n);
+         return *r.current; 
+     }
+
+     /** Haben zwei BaseType, die gleiche aktuelle Zeigerposition so sind sie aequivalent
+     */        
+     static bool equal(ROI const & l, ROI const & r)
+     {
+         return l.current == r.current;
+     }
+
+     /** Ist der d1 < d2, d.h. in der Matrix d1 steht hoeher als d2 oder stehen sie in der gleichen Zeile
+     * und d1 befindet sich links von d2, so wird true zurueckgeliefert
+     */
+     static bool less(BaseType const & d1, BaseType const & d2)
+     { 
+         return d1.current.y == d2.current.y ?
+                     d1.current.x < d2.current.x :
+                     d1.current.y < d2.current.y; 
+     }
+
+     /** Liefert die Anzahl der Schritte der einer BaseType (d1) braucht um seine aktuelle Position
+     * auf die des anderen (d2) zu veraendern. Dabei ist die Anordnungsposition von d1 und d2 egal, also
+     * es kann auch ein negativer Wert zurueckgeliefert werden.
+     */
+     static difference_type difference(BaseType const & d1, BaseType const & d2)
+     { 
+         return d1.current.x - d2.current.x + d1.width*(d1.current.y - d2.current.y);         
+     }
+
+     /** Inkrementiert die aktuelle Position des ScanOrderIterators, unter Beruecksichtigung
+     * des Falles, dass aktuelle Position am rechten Rande der Matrix ist
+     */
+     static void increment(ROI & r)
+     {
+         ++r.current.x;
+         if(r.current.x == r.lowerRight.x)
+         {
+             r.current.x -= r.width;
+             ++r.current.y;
+         }
+     }
+
+     /** Dekrementiert die aktuelle Position des ScanOrderIterators, unter Beruecksichtigung
+     * des Falles, dass aktuelle Position am linken Rande der Matrix ist
+     */
+     static void decrement(ROI & r)
+     {
+         --r.current.x;
+         if(r.current.x + r.width == r.lowerRight.x)
+         {
+             r.current.x += r.width;
+             --r.current.y;
+         }
+     }
+
+     /** verschiebt den Iterator um n Stellen wobei n kann durchaus neagtiv
+     * sein, das entspricht dan der Verschiebung nach links. 
+     * Precondition : r und n muessen gueltige Werte besitzen, insbesondere soll geachtet werden, dass 
+     * n <= width*"height" ist !!! 
+     */
+     static void advance(ROI & r, difference_type n) //n kann aber Diff2D sein; sollte es nicht int sein
+     {
+         if(n>0)                                        //ist n positiv so wird so wird die aktuelle Zeigerposition nach "rechts" verschoben
+         {
+             difference_type dy = (n) / r.width;        // dabei ist dy der Wert um den der Zeiger "in einer Matrix" nach unten verschoben werden soll 
+             difference_type dx = (n) % r.width;        // entsprechend ist dx um den der Zeiger nach rechts verschoben werden soll, wobei dx kann ueber die MAtrix hinausragen
+             if(dx >= r.lowerRight.x - r.current.x)     // laeuft dx ueber die "Matrix" hinaus so werden dx und dy korrigiert
+             {
+                 ++dy;                                  // der y-Wert wird einfach erhoeht
+                 dx -= r.width;                       // und es wird dann um Anzahl der Zeilenelemente nach LINKS (zurueck) gelaufen
+             }
+             r.current.x += dx;                         // jetzt enthalten dx und dy korrekte Werte bezueglich denen kann die
+             r.current.y += dy;                         // aktuelle Zeigerposition verschoben werden
+         }
+         else if(n < 0)                                 // ist n negativ so wird die aktuelle Zeigerposition nach "links" verschoben
+         {
+             n = -n;                                    // laesst sich mit positiver Zahl leichter rechnen
+             difference_type dy = n / r.width;          // dabei ist dy der Wert um den der Zeiger "in einer Matrix" nach "oben" verschoben werden soll 
+             difference_type dx = n % r.width;          // entsprechend ist dx um den der Zeiger nach "links" verschoben werden soll, wobei dx kann ueber die Matrix hinausragen
+
+             if((r.current.x - r.lowerRight.x) + r.width < dx)// laeuft dx ueber die Kante (r.lowerRight.x - width)(entspricht der upperLeft.x in der Matrix)
+             {
+                                                        // dx und dy beduerfen die Korrektur weil es durchaus sein kann dass dx < width ist, aber es kann nicht so viele Schritte nach links gegangen werden
+                    ++dy;                               // so werden die Differenzen um die die aktuelle Position veraendert werden soll korrigiert
+                    dx -= r.width;
+             }
+             r.current.x -= dx;                         // jetzt enthalten dx und dy korrekte Werte bezueglich denen kann die
+             r.current.y -= dy;                         // aktuelle Zeigerposition verschoben werden
+
+         }
+
+     }
+};// end of ScanOrderIteratorPolicy
+
+             
+template <class T>
+struct BandsForPixelType;
+
+template <>
+struct BandsForPixelType<GrayValue>
+    { static const int bands = 1; };
+
+template <>
+struct BandsForPixelType<RGBValue<GrayValue> >
+    { static const int bands = 3; };
+
+template <>
+struct BandsForPixelType<TinyVector<GrayValue, 2> >
+    { static const int bands = 2; };
+
+template <>
+struct BandsForPixelType<TinyVector<GrayValue, 3> >
+    { static const int bands = 3; };
+
+template <>
+struct BandsForPixelType<TinyVector<GrayValue, 4> >
+    { static const int bands = 4; };
+
+/** VaribleBandsImage stellt die Basis fuer die ganze Imagehierarchie, alle anderen ImageKlassen erben von ihr.
+* Also, SingleBandImage, GrayImage, FixedBansImage usw. sind von VariableBandsImage abgeleitet.
+*/    
+class VariableBandsImage                          
+{
+    
+  public:
+    typedef VectorProxy                                                             value_type;
+    typedef VectorProxy                                                             PixelType;
+    typedef ConstVectorProxy                                                        ConstPixelType;
+    typedef VectorProxy                                                             reference;
+    typedef ConstVectorProxy                                                        const_reference;
+    typedef GrayValue *                                                             pointer;
+    typedef GrayValue const *                                                       const_pointer;
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<VariableBandsIterator> >        iterator;
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<VariableBandsIterator> >        ScanOrderIterator;
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstVariableBandsIterator> >   const_iterator;
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstVariableBandsIterator> >   ConstScanOrderIterator;
+    typedef VariableBandsIterator                                                   traverser;
+    typedef VariableBandsIterator                                                   Iterator;
+    typedef ConstVariableBandsIterator                                              const_traverser;
+    typedef ConstVariableBandsIterator                                              ConstIterator; 
+    typedef Diff2D                                                                  difference_type;
+    typedef Diff2D                                                                  size_type;
+    typedef StandardValueAccessor<PixelType>                                        Accessor;
+    typedef StandardConstValueAccessor<ConstPixelType>                              ConstAccessor;
+    typedef VariableBandsImage                                                      CloneType;
+    
+    virtual ~VariableBandsImage() {}              
+    
+    /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
+    *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
+    *   mit der Groesse und Pixelinitialisierung der ROI
+    */
+    virtual CloneType * clone() const = 0;                                                      
+    
+    /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer 
+    *   auf das aufrufende Objekt zurueckgeliefert.
+    *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
+    *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
+    *   dabei ist an der shallowCopy genau so die ROI gesetzt.
+    */ 
+    virtual VariableBandsImage * shallowCopy() const = 0;                                       
+    
+    /** Liefert die Breite der ROI !!! Nicht des Bildes
+    */
+    int width() const                                   
+        { return roiLR_.x - roiUL_.x; } 
+    
+    /** Liefert die Hoehe der ROI !!! Nicht des Bildes
+    */    
+    int height() const                                  
+        { return roiLR_.y - roiUL_.y; }
+    
+    /** Liefert die Groesse der ROI !!! Nicht des Bildes
+    */    
+    Diff2D size() const                                 
+        { return roiLR_ - roiUL_; }
+        
+    /** Liefert die Groesse des Bildes !!! Nicht der ROI
+    */
+    Diff2D actualSize() const                           
+        { return actualLR_; }
+    
+    /** Liefert die Breite des Bildes !!! Nicht der ROI
+    */    
+    int actualWidth() const                             
+        { return actualSize().x; }
+    
+    /** Liefert die Hoehe des Bildes !!! Nicht der ROI
+    */    
+    int actualHeight() const                            
+        { return actualSize().y; }
+    
+    /** Liefert Anzahl der Baender eines Pixels des Bildes !!! Es unterscheidet
+    * sich von bands nur fuer SelectBandImage, sonst ist immer actualBands_ == bands_ 
+    * erfuelt.
+    */    
+    int actualBands() const                         
+        { return actualBands_; }
+    
+    /** Liefert Anzahl der Baender eines Pixels der ROI !!! Es unterscheidet
+    * sich von actualBands nur fuer SelectBandImage, sonst ist immer actualBands_ == bands_ 
+    * erfuelt. Fuer SelectBandImage ist bands_ gleich 1, da die ROI auf ein
+    * Band gesetzt ist.
+    */    
+    int bands() const                                  
+        { return bands_; }
+    
+    /** Liefert die linke obere Ecke der ROI.
+    */    
+    Diff2D roiUpperLeft() const                        
+        { return roiUL_; }
+    
+    /** Liefert den 1D-iterator auf linke obere Ecke der ROI
+    */
+    ScanOrderIterator begin()
+    {
+        return ScanOrderIterator(ScanOrderIteratorPolicy<Iterator>::ROI(upperLeft(), lowerRight()));
+    }    
+    
+    /** Liefert den 1D-iterator hinter der rechten unteren Ecke der ROI
+    */
+    ScanOrderIterator end()
+    {
+        return begin() + width()*height();
+    }
+    
+    /** Liefert den ConstIterator auf linke obere Ecke der ROI
+    */
+    ConstScanOrderIterator begin() const
+    {
+        return ConstScanOrderIterator(ScanOrderIteratorPolicy<ConstIterator>::ROI(upperLeft(), lowerRight()));
+    }    
+    
+    /** Liefert den ConstIterator hinter der rechten unteren Ecke der ROI
+    */
+    ConstScanOrderIterator end() const
+    {
+        return begin() + width()*height();
+    }
+    
+    /** fuellt das komplette Image mit einem Pixel aus, also hinterher haben alle Pixel die gleiche "Farbe",
+    * die hier uebergeben wurde
+    */
+    VariableBandsImage & init(ConstPixelType const & pixel)
+    {
+        initImage(upperLeft(), lowerRight(), accessor(), pixel);
+        
+        return *this;
+    }    
+    
+    /** Setzt die ROI (Region of interess) auf dem aufrufendem Bild
+    */
+    virtual void setROI(Diff2D const & ul, Diff2D const & new_size)             // setROI -methode mit Argumenten Diff2D upperLeft und Diff2D size
+    {
+        Diff2D new_ul = roiUL_ + ul;
+        Diff2D new_lr;
+        new_lr.x = new_size.x > 0 ?
+                        new_ul.x + new_size.x :
+                        roiLR_.x + new_size.x;
+        new_lr.y = new_size.y > 0 ?
+                        new_ul.y + new_size.y :
+                        roiLR_.y + new_size.y;
+                                
+        vigra_precondition(new_ul.x >= 0 && new_ul.x < actualWidth() && 
+                           new_ul.y >= 0 && new_ul.y < actualHeight(),
+            "Image::setROI(): new upper left outside of image.");
+        vigra_precondition(new_lr.x > 0 && new_lr.x <= actualWidth() && 
+                           new_lr.y > 0 && new_lr.y <= actualHeight(),
+            "Image::setROI(): new lower right outside of image.");
+        vigra_precondition(new_ul.x < new_lr.x,
+            "Image::setROI(): upper left isn't to the left of lower right.");
+        vigra_precondition(new_ul.y < new_lr.y,
+            "Image::setROI(): upper left isn't above lower right.");
+            
+        roiUL_ = new_ul;
+        roiLR_ = new_lr;
+    }
+    
+    /** hebt die ROI wieder auf.
+    */
+    virtual void resetROI()
+    {
+        roiUL_ = Diff2D(0,0);
+        roiLR_ = actualLR_;
+    }
+    
+    /** Stellt den gewohnten Operatrot
+    */
+    PixelType operator[](Diff2D const & c)                          
+        { return PixelType(get(c.x, c.y), bands_); }
+
+    PixelType operator()(int x, int y) 
+        { return PixelType(get(x,y), bands_); }
+
+    ConstPixelType operator[](Diff2D const & c) const
+        { return ConstPixelType(get(c.x, c.y), bands_); }
+
+    ConstPixelType operator()(int x, int y) const
+        { return ConstPixelType(get(x,y), bands_); }
+
+    ScanOrderIterator operator[](int dy)                          
+        { return begin()+dy*width(); }
+
+    ConstScanOrderIterator operator[](int dy) const                         
+        { return begin()+dy*width(); }
+
+    Iterator upperLeft()
+        { return Iterator(get(0,0), actualWidth(), actualBands_, bands_); }
+        
+    Iterator lowerRight()
+        { return upperLeft() + size(); }
+        
+    ConstIterator upperLeft() const
+        { return ConstIterator(get(0,0), actualWidth(), actualBands_, bands_); }
+
+    ConstIterator lowerRight() const
+        { return upperLeft() + size(); }
+    
+    Accessor accessor()
+        { return Accessor(); }
+
+    ConstAccessor accessor() const
+        { return ConstAccessor(); }
+        
+    /** Gibt an ob es ein Punkt mit Koordinaten (Diff2D) innerhalb des ganzen Bildes existiert
+    */    
+    bool isInside(Diff2D const & d) const
+    {
+        return d.x >= 0 && d.y >= 0 &&
+               d.x < actualWidth() && d.y < actualHeight();    
+    }
+    /** Gibt an ob es ein Punkt mit Koordinaten (Diff2D) innerhalb der ROI existiert
+    */
+    bool isInsideROI(Diff2D const & d) const
+    {
+        return d.x >= roiUL_.x  && d.y >= roiUL_.y &&
+               d.x < roiLR_.x && d.y < roiLR_.y;
+    }
+    
+  protected:
+    VariableBandsImage()                  
+    : data_(0)
+    {}
+    
+    VariableBandsImage(VariableBandsImage const & s)                 
+    : roiUL_(s.roiUL_), roiLR_(s.roiLR_), actualLR_(s.actualLR_),
+      bands_(s.bands_), actualBands_(s.actualBands_),
+      data_(s.data_)
+    {}
+    
+    VariableBandsImage & operator=(VariableBandsImage const & s)             
+    {
+        roiUL_ = s.roiUL_;
+        roiLR_ = s.roiLR_;
+        actualLR_ = s.actualLR_;
+        bands_ = s.bands_;
+        actualBands_ = s.actualBands_;
+        data_ = s.data_;
+        return *this;
+    }
+    
+    /** Initialisiert die Membervariablen des Images
+    */
+    void initAdministrationData(GrayValue * data, Diff2D const & actualLR, int actualBands)        
+    {
+        initAdministrationData(data, actualLR, actualBands, actualBands);
+    }
+    
+    /** Initialisiert die Membervariablen des Images
+    */
+    void initAdministrationData(GrayValue * data, Diff2D const & actualLR, int actualBands, int bands)
+    {
+        roiUL_ = Diff2D(0,0);
+        roiLR_ = actualLR;
+        actualLR_ = actualLR;
+        bands_ = bands;
+        actualBands_ = actualBands;
+        data_ = data;
+    }
+    
+    /** Liefert den Zeiger auf GrayValue
+    */
+    static GrayValue * getDataPtr(GrayValue * p)          
+        { return p; }
+
+    /** Liefert den Zeiger auf GrayValue,                                                            
+    */
+    template <class T>
+    static GrayValue * getDataPtr(T * p)   
+    {
+        BOOST_STATIC_ASSERT( sizeof(T) ==
+               BandsForPixelType<T>::bands*sizeof(GrayValue) );
+        return &(*p)[0]; 
+    }
+
+    /** Liefert Zeiger auf GrayValue (float) zu einem bestimmten Punkt im Bilde
+    */
+    GrayValue * get(int dx, int dy)                  
+        { return data_ + ((roiUL_.y + dy) * actualWidth() + roiUL_.x + dx)*actualBands_; }
+    
+    /** Liefert ConstZeiger auf GrayValue (float) zu einem bestimmten Punkt im Bilde
+    */
+    GrayValue const * get(int dx, int dy) const      
+        { return data_ + ((roiUL_.y + dy) * actualWidth() + roiUL_.x + dx)*actualBands_; }
+    
+    Diff2D roiUL_, roiLR_, actualLR_;// roiUL_ - ist der Abstand von der linken oberen Ecke des Images bis zur linken oberen Ecke von ROI
+    int bands_, actualBands_;
+    GrayValue * data_;// GrayValue ist float 
+};
+
+class SelectBandImage;
+
+template <class IMAGE, class ACCESSOR = typename IMAGE::Accessor>
+class FixedBandsImage                                    
+: public VariableBandsImage
+{
+  public:
+    
+    typedef IMAGE                                                   InnerImage;
+    typedef typename ACCESSOR::value_type                           value_type;
+    typedef value_type                                              PixelType;
+    typedef value_type                                              ConstPixelType;
+    typedef value_type &                                            reference;
+    typedef value_type const &                                      const_reference;
+    typedef value_type *                                            pointer;
+    typedef value_type const *                                      const_pointer;
+    typedef typename IMAGE::Iterator                                traverser;
+    typedef typename IMAGE::Iterator                                Iterator;           //2D Iterator !!! Soll deprecated werden, wurde in traverser umbenannt
+    typedef typename InnerImage::ConstIterator                           const_traverser;    
+    typedef typename InnerImage::ConstIterator                           ConstIterator;      //2D ConstIterator !!! Soll deprecated werden, wurde in const_traverser umbenannt
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<Iterator> >     ScanOrderIterator;
+    typedef ScanOrderIterator                                       iterator;           //1D Iterator entspricht den ScanOrderIterator
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstIterator> > ConstScanOrderIterator;
+    typedef ConstScanOrderIterator                                  const_iterator;     //1D ConstIterator entspricht den ConstScanOrderIterator
+    typedef Diff2D                                                  difference_type;
+    typedef Diff2D                                                  size_type;
+    typedef ACCESSOR                                                Accessor;
+    typedef ACCESSOR                                                ConstAccessor;
+    
+#ifndef NO_COVARIANT_RETURN_TYPES                                              ///////////////AEND_6///////////
+    typedef FixedBandsImage CloneType;
+#else
+    typedef VariableBandsImage CloneType;
+#endif                                                                      ///////////////AEND_6///////////   
+
+    friend class SelectBandImage;
+    /**  DefaultKonstruktor
+    */
+    FixedBandsImage()
+    : VariableBandsImage(),
+      image_(new InnerImage(0,0))
+    {
+        initAdministrationData(getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
+    }
+    
+    FixedBandsImage(int w, int h)                                   
+    : VariableBandsImage(),
+      image_(new InnerImage(w,h))
+    {   
+        initAdministrationData(getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
+    }
+        
+    /** Konstruktor, erzeugt ein FixedBandsImage mit width, height, und Pixel_value
+    */
+    FixedBandsImage(int w, int h, PixelType pixel_value)                                   
+    : VariableBandsImage(),
+      image_(new InnerImage(w,h, pixel_value))
+    {
+        initAdministrationData(getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
+    }
+    
+    FixedBandsImage(Diff2D const & s)                                                             
+    : VariableBandsImage(),
+      image_(new InnerImage(s))
+    {
+        initAdministrationData(getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
+    }
+    
+    FixedBandsImage(FixedBandsImage const & s)                       
+    : VariableBandsImage(s),
+      image_(s.image_)
+    {}
+    
+    FixedBandsImage(InnerImage * i)                                                             
+    : VariableBandsImage(),
+      image_(i)
+    {
+        initAdministrationData(getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
+    }
+    
+    FixedBandsImage & operator=(FixedBandsImage const & s)               
+    {
+        if(this != &s)
+        {
+            image_ = s.image_;
+            VariableBandsImage::operator=(s);
+        }
+        return *this;
+    }
+    
+    /** Destructor ist leer, weil es wird nur shared_ptr image_, als Klassenvariable angelegt und shared_ptr verwaltet
+    * selber Referenzen und gibt den Speicherplatz frei
+    */
+    virtual ~FixedBandsImage()                                                                          
+        {}
+    
+    /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
+    *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
+    *   mit der Groesse und Pixelinitialisierung der ROI
+    */ 
+    virtual CloneType * clone() const             
+    {
+        InnerImage * newimg = new InnerImage(size());
+        copyImage(srcIterRange(upperLeft(), lowerRight()), destImage(*newimg));
+        return new FixedBandsImage(newimg); 
+    }
+    
+    /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer 
+    *   auf das aufrufende Objekt zurueckgeliefert.
+    *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
+    *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
+    *   dabei ist an der shallowCopy genau so die ROI gesetzt.
+    */ 
+    virtual FixedBandsImage * shallowCopy() const                                       
+    {
+        return new FixedBandsImage(*this); 
+    }
+   
+    PixelType & operator[](Diff2D const & c)                 
+        { return image_->operator[](c+roiUL_); }
+
+    PixelType const & operator[](Diff2D const & c) const
+        { return image_->operator[](c+roiUL_); }
+
+    PixelType & operator()(int x, int y)
+        { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
+
+    PixelType const & operator()(int x, int y) const
+        { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
+      
+    PixelType * operator[](int c)                  
+        { return image_->operator[](c+roiUL_.y) + roiUL_.x; }              
+
+    PixelType  const * operator[](int c) const         
+        { return image_->operator[](c+roiUL_.y) + roiUL_.x; }
+
+    Iterator upperLeft()
+        { return image_->upperLeft()+roiUL_; }
+        
+    Iterator lowerRight()
+        { return upperLeft()+size(); }
+        
+    ConstIterator upperLeft() const
+        { return image_->upperLeft()+roiUL_; }
+
+    ConstIterator lowerRight() const
+        { return upperLeft()+size(); }
+
+    iterator begin()
+        { return ScanOrderIterator(ScanOrderIteratorPolicy<Iterator>::ROI(upperLeft(), lowerRight())); }
+        
+    iterator end()
+        { return begin() + width()*height(); }
+        
+    const_iterator begin() const
+        { return ConstScanOrderIterator(ScanOrderIteratorPolicy<ConstIterator>::ROI(upperLeft(), lowerRight())); }
+
+    const_iterator end() const
+        { return begin() + width()*height(); }
+
+    Accessor accessor() 
+        { return Accessor(); }
+    
+    ConstAccessor accessor() const                          
+        { return ConstAccessor(); }
+    
+  protected:
+    boost::shared_ptr<InnerImage> image_;                                   // shared_ptr verwaltet selber Referenzen und gibt den Speicherplatz frei
+    
+};
+
+template <class IMAGE>   
+class FixedRGBImage : public FixedBandsImage<IMAGE, VectorAccessor<TinyVector<GrayValue, 3> > >
+{
+  public:
+  
+    typedef 
+        FixedBandsImage<IMAGE, VectorAccessor<TinyVector<GrayValue, 3> > >  BaseType;
+        
+    typedef IMAGE                                                           InnerImage;
+    typedef typename IMAGE::value_type                                      value_type;
+    typedef value_type                                                      PixelType;
+    typedef value_type                                                      ConstPixelType;
+    typedef value_type &                                                    reference;
+    typedef value_type const &                                              const_reference;
+    typedef value_type *                                                    pointer;
+    typedef value_type const *                                              const_pointer;
+    typedef typename IMAGE::Iterator                                        traverser;
+    typedef typename IMAGE::Iterator                                        Iterator;           //2D Iterator !!! Soll deprecated werden, wurde in traverser umbenannt
+    typedef typename IMAGE::ConstIterator                                   const_traverser;
+    typedef typename IMAGE::ConstIterator                                   ConstIterator;      //2D ConstIterator !!! Soll deprecated werden, wurde in const_traverser umbenannt
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<Iterator> >             ScanOrderIterator;
+    typedef ScanOrderIterator                                               iterator;           //1D Iterator entspricht den ScanOrderIterator
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstIterator> >        ConstScanOrderIterator;
+    typedef ConstScanOrderIterator                                          const_iterator;     //1D ConstIterator entspricht den ConstScanOrderIterator
+
+    typedef Diff2D                                                          difference_type;
+    typedef Diff2D                                                          size_type;
+    typedef typename IMAGE::Accessor                                        Accessor;
+    typedef typename IMAGE::ConstAccessor                                   ConstAccessor;
+#ifndef NO_COVARIANT_RETURN_TYPES                                               ///////////////AEND_7////////////
+    typedef FixedRGBImage CloneType;
+#else
+    typedef typename BaseType::CloneType CloneType;
+#endif                                                                       ///////////////AEND_7//////////// 
+    friend class SelectBandImage;
+    
+    FixedRGBImage()
+    {}
+    
+    FixedRGBImage(int w, int h)                
+    : BaseType(w, h)
+    {}
+    
+    FixedRGBImage(int w, int h, PixelType pix_type)                
+    : BaseType(w, h, pix_type)
+    {}
+    
+    FixedRGBImage(Diff2D const & s)            
+    : BaseType(s)
+    {}
+    
+    FixedRGBImage(FixedRGBImage const & s)     
+    : BaseType(s)
+    {}
+    
+    FixedRGBImage(InnerImage * i)              
+    : BaseType(i)
+    {}
+    
+    FixedRGBImage & operator=(FixedRGBImage const & s)       
+    {
+        BaseType::operator=(s);
+        return *this;
+    }
+    
+    /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
+    *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
+    *   mit der Groesse und Pixelinitialisierung der ROI
+    */ 
+    virtual CloneType * clone() const                        
+    {
+        InnerImage * newimg = new InnerImage(size());
+        copyImage(srcIterRange(upperLeft(), lowerRight()), destImage(*newimg));
+        return new FixedRGBImage(newimg); 
+    }
+    
+    /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer 
+    *   auf das aufrufende Objekt zurueckgeliefert.
+    *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
+    *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
+    *   dabei ist an der shallowCopy genau so die ROI gesetzt.
+    */ 
+    virtual FixedRGBImage * shallowCopy() const               
+    {
+        return new FixedRGBImage(*this); 
+    }
+    
+    PixelType & operator[](Diff2D const & c)                 
+        { return image_->operator[](c+roiUL_); }
+
+    PixelType const & operator[](Diff2D const & c) const
+        { return image_->operator[](c+roiUL_); }
+
+    PixelType & operator()(int x, int y)
+        { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
+
+    PixelType const & operator()(int x, int y) const
+        { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
+      
+    PixelType * operator[](int c)                  
+        { return image_->operator[](c+roiUL_.y) + roiUL_.x; }              
+
+    PixelType  const * operator[](int c) const         
+        { return image_->operator[](c+roiUL_.y) + roiUL_.x; }
+
+    Iterator upperLeft()
+        { return image_->upperLeft()+roiUL_; }
+        
+    Iterator lowerRight()
+        { return upperLeft()+size(); }
+        
+    ConstIterator upperLeft() const
+        { return image_->upperLeft()+roiUL_; }
+
+    ConstIterator lowerRight() const
+        { return upperLeft()+size(); }
+
+    iterator begin()
+        { return ScanOrderIterator(ScanOrderIteratorPolicy<Iterator>::ROI(upperLeft(), lowerRight())); }
+        
+    iterator end()
+        { return begin() + width()*height(); }
+        
+    const_iterator begin() const
+        { return ConstScanOrderIterator(ScanOrderIteratorPolicy<ConstIterator>::ROI(upperLeft(), lowerRight())); }
+
+    const_iterator end() const
+        { return begin() + width()*height(); }
+
+    Accessor accessor()                                       
+        { return Accessor(); }
+    
+    ConstAccessor accessor() const                            
+        {return ConstAccessor(); }
+        
+    
+};
+
+typedef FixedBandsImage<BasicImage<TinyVector<GrayValue, 2> > > Vector2Image;
+typedef FixedRGBImage<BasicImage<RGBValue<GrayValue> > > RGBImage;
+typedef RGBImage::BaseType Vector3Image;
+typedef FixedBandsImage<BasicImage<TinyVector<GrayValue, 4> > > Vector4Image;
+
+template <class PIXELTYPE>
+class ConstSelectBandIterator
+: public VariableBandsIteratorBase<PIXELTYPE, ConstSelectBandIterator<PIXELTYPE> >
+{
+  public:
+  
+    typedef PIXELTYPE          value_type;
+    typedef PIXELTYPE          PixelType;
+    typedef PIXELTYPE const &  reference;
+    typedef PIXELTYPE const &  index_reference;
+    typedef PIXELTYPE const *  pointer;
+    typedef Diff2D             difference_type;
+    typedef image_traverser_tag  iterator_category;
+    typedef IteratorAdaptor<ContigousMemoryColumnIteratorPolicy<ConstSelectBandIterator> > 
+        row_iterator;
+    typedef IteratorAdaptor<ContigousMemoryColumnIteratorPolicy<ConstSelectBandIterator> > 
+        column_iterator;
+  
+    ConstSelectBandIterator(PIXELTYPE const * data, int width, int bands)
+    : VariableBandsIteratorBase<PIXELTYPE, ConstSelectBandIterator>(
+        const_cast<PIXELTYPE *>(data), width, bands, 1)
+    {}
+    
+    ConstSelectBandIterator()
+    {}
+    
+    ConstSelectBandIterator operator+(Diff2D const & s)
+    {
+        ConstSelectBandIterator res(*this);
+        res += s;
+        return res;
+    }
+
+    ConstSelectBandIterator operator-(Diff2D const & s)
+    {
+        ConstSelectBandIterator res(*this);
+        res -= s;
+        return res;
+    }
+    
+    pointer operator->() const
+    {
+        return get();
+    }
+    
+    reference operator*() const
+    {
+        return *get();
+    }
+    
+    index_reference operator[](Diff2D const & dist) const
+    {
+        return *get(dist.x, dist.y);
+    }
+    
+    row_iterator operator[](int dy) const
+    {
+        typedef typename row_iterator::BaseType BaseType;
+        return row_iterator(BaseType(const_cast<pointer>(get(0, dy)), bands_));   //  braeuchte man hier nicht die Auswahl von bands?
+    }
+    
+    index_reference operator()(int const & dx, int const & dy) const
+    {
+        return *get(dx, dy);
+    }
+    
+    row_iterator rowIterator() const
+    {
+        typedef typename row_iterator::BaseType BaseType;
+        return row_iterator(BaseType(get(), bands_));
+    }
+    
+    column_iterator columnIterator() const
+    {
+        typedef typename column_iterator::BaseType BaseType;
+        return column_iterator(BaseType(get(), width_*bands_));
+    }
+};
+
+template <class PIXELTYPE>
+class SelectBandIterator
+: public VariableBandsIteratorBase<PIXELTYPE, SelectBandIterator<PIXELTYPE> >
+{
+  public:
+  
+    typedef PIXELTYPE          value_type;
+    typedef PIXELTYPE          PixelType;
+    typedef PIXELTYPE &        reference;
+    typedef PIXELTYPE &        index_reference;
+    typedef PIXELTYPE *        pointer;
+    typedef Diff2D             difference_type;
+    typedef image_traverser_tag  iterator_category;
+    typedef IteratorAdaptor<ContigousMemoryColumnIteratorPolicy<SelectBandIterator> > 
+        row_iterator;
+    typedef IteratorAdaptor<ContigousMemoryColumnIteratorPolicy<SelectBandIterator> > 
+        column_iterator;
+  
+    SelectBandIterator(PIXELTYPE * data, int width, int bands)
+    : VariableBandsIteratorBase<PIXELTYPE, SelectBandIterator>(data, width, bands, 1)
+    {}
+    
+    SelectBandIterator()
+    {}
+    
+    SelectBandIterator operator+(Diff2D const & s)
+    {
+        SelectBandIterator res(*this);
+        res += s;
+        return res;
+    }
+
+    SelectBandIterator operator-(Diff2D const & s)
+    {
+        SelectBandIterator res(*this);
+        res -= s;
+        return res;
+    }
+    
+    pointer operator->() const
+    {
+        return const_cast<pointer>(get());
+    }
+    
+    reference operator*() const
+    {
+        return const_cast<reference>(*get());
+    }
+    
+    index_reference operator[](Diff2D const & dist) const
+    {
+        return const_cast<index_reference>(*get(dist.x, dist.y));
+    }
+    
+    row_iterator operator[](int dy) const
+    {
+        typedef typename row_iterator::BaseType BaseType;
+        return row_iterator(BaseType(const_cast<pointer>(get(0, dy)), bands_));
+    }
+    
+    index_reference operator()(int const & dx, int const & dy) const
+    {
+        return const_cast<index_reference>(*get(dx, dy));
+    }
+    
+    row_iterator rowIterator() const
+    {
+        typedef typename row_iterator::BaseType BaseType;
+        return (row_iterator(BaseType(const_cast<pointer>(get()), bands_)));
+    }
+    
+    column_iterator columnIterator() const
+    {
+        typedef typename column_iterator::BaseType BaseType;
+        return (column_iterator(BaseType(const_cast<pointer>(get()), width_*bands_)));
+    }
+};
+
+class SingleBandImage                          
+: public VariableBandsImage                    
+{
+  public:
+  
+    typedef GrayValue                                           value_type;         //entsricht float
+    typedef value_type                                          PixelType;          // -||- float
+    typedef value_type                                          ConstPixelType;     // -||- float
+    typedef value_type &                                        reference;          // -||- float const &
+    typedef value_type const &                                  const_reference;    // -||- float &
+    typedef value_type *                                        pointer;            // -||- float *
+    typedef value_type const *                                  const_pointer;      // -||- float const *
+    typedef SelectBandIterator<PixelType>                       traverser;          //"normaler" 2D Iterator
+    typedef SelectBandIterator<PixelType>                       Iterator;           //2D Iterator !!! Soll deprecated werden, wurde in traverser umbenannt
+    typedef ConstSelectBandIterator<PixelType>                  const_traverser;    //"normaler" 2D ConstIterator
+    typedef ConstSelectBandIterator<PixelType>                  ConstIterator;      //2D ConstIterator !!! Soll deprecated werden, wurde in const_traverser umbenannt
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<Iterator> > ScanOrderIterator;  // entspricht dem iterator, also gewoehnlicher 1D Iterator 
+    typedef ScanOrderIterator                                   iterator;           //1D Iterator entspricht den ScanOrderIterator
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstIterator> > ConstScanOrderIterator;
+    typedef ConstScanOrderIterator                              const_iterator;     //1D ConstIterator entspricht den ConstScanOrderIterator
+    typedef Diff2D                                              difference_type;
+    typedef Diff2D                                              size_type;
+    typedef StandardAccessor<PixelType>                         Accessor;
+    typedef StandardConstAccessor<ConstPixelType>               ConstAccessor;    
+#ifndef NO_COVARIANT_RETURN_TYPES                                                                         ////////AEND_8///////
+    typedef SingleBandImage CloneType;
+#endif                                                                                                  ////////AEND_8///////   
+    virtual ~SingleBandImage()                            
+        {}
+    
+    /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
+    *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
+    *   mit der Groesse und Pixelinitialisierung der ROI
+    */ 
+    virtual CloneType * clone() const = 0;                                          // dadurch wird gekennzeichent, dass die Funktion "virtual CloneType * clone() const" in der abgeleiteten Klasse implementiert werden soll, das gleiche wie eine abstrakte Funktion   
+    
+    /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer 
+    *   auf das aufrufende Objekt zurueckgeliefert.
+    *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
+    *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
+    *   dabei ist an der shallowCopy genau so die ROI gesetzt.
+    */ 
+    virtual SingleBandImage * shallowCopy() const = 0;                              // --//-- "virtual SingleBandImage * shallowCopy() const" --//--   
+    
+    PixelType & operator[](Diff2D const & c)              
+        { return *get(c.x, c.y); }
+
+    PixelType const & operator[](Diff2D const & c) const
+        { return *get(c.x, c.y); }
+ ////////////////////////////////////////////////
+
+
+    ScanOrderIterator operator[](int dy)                          
+        { return begin()+dy*width(); }
+
+    ConstScanOrderIterator operator[](int dy) const                         
+        { return begin()+dy*width(); }
+
+////////////////////////////////////////////////
+
+    PixelType & operator()(int x, int y)                  
+        { return *get(x, y); }
+
+    PixelType const & operator()(int x, int y) const
+        { return *get(x, y); }
+
+    Iterator upperLeft()                   
+        { return Iterator(get(0,0), actualWidth(), actualBands_); }
+        
+    Iterator lowerRight()                       
+        { return upperLeft()+size(); }
+        
+    ConstIterator upperLeft() const             
+        { return ConstIterator(get(0,0), actualWidth(), actualBands_); }
+
+    ConstIterator lowerRight() const
+        { return upperLeft()+size(); }
+    
+    iterator begin()
+        { return ScanOrderIterator(ScanOrderIteratorPolicy<Iterator>::ROI(upperLeft(), lowerRight())); }
+        
+    iterator end()
+        { return begin() + width()*height(); }
+        
+    const_iterator begin() const
+        { return ConstScanOrderIterator(ScanOrderIteratorPolicy<ConstIterator>::ROI(upperLeft(), lowerRight())); }
+
+    const_iterator end() const
+        { return begin() + width()*height(); }
+    
+    Accessor accessor()                           
+        { return Accessor(); }
+    
+    ConstAccessor accessor() const                
+        { return ConstAccessor(); }
+        
+  protected:                                      
+    SingleBandImage()                             
+    {}
+    
+    SingleBandImage(SingleBandImage const & s)         
+    : VariableBandsImage(s)
+    {}
+    
+    SingleBandImage & operator=(SingleBandImage const & s) 
+    {
+        VariableBandsImage::operator=(s);
+        return *this;
+    }
+};// end of SingleBandsImage
+
+/** entspricht BasicImage<float> und stellt die gleiche Operationen zur Verfuegung wie BasicImage,
+* also ist ein EinbandImage, der in die Imagehierarchie eingebetet ist.
+*/
+class GrayImage                                           
+: public SingleBandImage
+{
+  public:
+  
+    typedef BasicImage<GrayValue>                                      InnerImage;              // entspricht BasicImage<float>
+    typedef InnerImage::value_type                                     value_type;              // -||- float
+    typedef value_type                                                 PixelType;               // -||- float
+    typedef value_type                                                 ConstPixelType;          // -||- float
+    typedef value_type &                                               reference;               // -||- float &
+    typedef value_type const &                                         const_reference;         // -||- float const &
+    typedef value_type *                                               pointer;                 // -||- float *
+    typedef value_type const *                                         const_pointer;           // -||- float const *
+    typedef InnerImage::Iterator                                       traverser;               //"normaler"(gewoehnlicher) 2D-Iterator
+    typedef InnerImage::Iterator                                       Iterator;                // soll deprecated werden !!! Entspricht dem traverser
+    typedef InnerImage::ConstIterator                                  const_traverser;         //"normaler"(gewoehnlicher) 2D-ConstIterator
+    typedef InnerImage::ConstIterator                                  ConstIterator;           // soll deprecated werden !!! Entspricht dem const_traverser
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<Iterator> >        ScanOrderIterator;       // 1D Iterator ueber das Bild (bzw. ROI), entspricht dem iterator
+    typedef ScanOrderIterator                                          iterator;                // "normaler" 1D Iterator ueber das Bild (bzw.ROI)
+    typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstIterator> >   ConstScanOrderIterator;  // 1D ConstIterator ueber das Bild (bzw. ROI), entspricht dem const_iterator
+    typedef ConstScanOrderIterator                                     const_iterator;          // "normaler" 1D ConstIterator ueber das Bild (bzw.ROI)
+
+    typedef Diff2D                                                      difference_type;
+    typedef Diff2D                                                      size_type;
+    typedef InnerImage::Accessor                                        Accessor;               // Accessor aus dem BasicImage<float>
+    typedef InnerImage::ConstAccessor                                   ConstAccessor;          // ConstAccessor aus dem BasicImage<float>    
+#ifndef NO_COVARIANT_RETURN_TYPES                                                                   //////AEND_9////////
+    typedef GrayImage CloneType;
+#endif                                                                                            //////AEND_9//////// 
+    
+    GrayImage()
+    : image_(new InnerImage(0,0))                              
+    {
+        initAdministrationData(0, image_->size(), 1);
+    }
+    
+    GrayImage(int w, int h)                                        
+    : image_(new InnerImage(w,h))
+    {   
+        initAdministrationData((w*h == 0) ? 0 : getDataPtr(image_->begin()), image_->size(), 1);
+    }
+    
+    GrayImage(int w, int h, GrayValue gray_value)               
+    : image_(new InnerImage(w,h, gray_value))
+    {   
+        initAdministrationData((w*h == 0) ? 0 : getDataPtr(image_->begin()), image_->size(), 1);
+    }
+    
+    GrayImage(Diff2D const & s)                                   
+    : image_(new InnerImage(s))
+    {   
+        initAdministrationData((s.x*s.y == 0) ? 0 : getDataPtr(image_->begin()), image_->size(), 1);
+    }
+    
+    GrayImage(GrayImage const & s)                                
+    : SingleBandImage(s),
+      image_(s.image_)
+    {}
+    
+    GrayImage(InnerImage * i)                              
+    : image_(i)
+    {   
+        initAdministrationData((i->width()*i->height() == 0) ? 0 : getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
+    }
+    
+    GrayImage & operator=(GrayImage const & s)             
+    {   
+        if(this != &s)
+        {
+            image_ = s.image_;
+            SingleBandImage::operator=(s);
+        }
+        return *this;
+    }
+    
+    GrayImage & init(PixelType const & pixel)
+    {
+        initImage(upperLeft(), lowerRight(), accessor(), pixel);
+        return *this;
+    }
+    
+    virtual ~GrayImage()                                        
+        {}
+    
+    /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
+    *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
+    *   mit der Groesse und Pixelinitialisierung der ROI
+    */
+    virtual CloneType * clone() const
+    {   
+        InnerImage * newimg = new InnerImage(size());
+        copyImage(srcIterRange(upperLeft(), lowerRight()), destImage(*newimg));   // copyImage  kommt ueber imagefunctions.hxx aus copyimage.hxx; srcIterRange kommt aus stdimage.hxx 762; destImage kommt aus stdimage.hxx 733
+        return new GrayImage(newimg); 
+    }
+    
+    /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer 
+    *   auf das aufrufende Objekt zurueckgeliefert.
+    *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
+    *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
+    *   dabei ist an der shallowCopy genau so die ROI gesetzt.
+    */ 
+    virtual GrayImage * shallowCopy() const     
+    {   
+        return new GrayImage(*this); 
+    }                                                      
+    
+    PixelType & operator[](Diff2D const & c)               
+        { return image_->operator[](c+roiUL_); }
+    
+    PixelType const & operator[](Diff2D const & c) const 
+        { return image_->operator[](c+roiUL_); }
+      
+    PixelType * operator[](int c)                  
+        { return image_->operator[](c+roiUL_.y) + roiUL_.x; }              
+
+    PixelType  const * operator[](int c) const         
+        { return image_->operator[](c+roiUL_.y) + roiUL_.x; }
+
+    PixelType & operator()(int x, int y)
+        { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
+
+    PixelType const & operator()(int x, int y) const
+        { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
+
+    Iterator upperLeft()
+        { return image_->upperLeft()+roiUL_;}
+    
+    Iterator lowerRight()
+        { return upperLeft()+size(); }
+        
+    ConstIterator upperLeft() const
+        { return image_->upperLeft()+roiUL_; }
+
+    ConstIterator lowerRight() const
+        { return upperLeft()+size(); }
+
+    iterator begin()
+        { return ScanOrderIterator(ScanOrderIteratorPolicy<Iterator>::ROI(upperLeft(), lowerRight())); }
+        
+    iterator end()
+        { return begin() + width()*height(); }
+        
+    const_iterator begin() const
+        { return ConstScanOrderIterator(ScanOrderIteratorPolicy<ConstIterator>::ROI(upperLeft(), lowerRight())); }
+
+    const_iterator end() const
+        { return begin() + width()*height(); }
+
+    Accessor accessor() 
+        { return Accessor(); }
+    
+    ConstAccessor accessor() const                    
+        { return ConstAccessor(); }
+    
+  private:
+    boost::shared_ptr<InnerImage> image_;
+};// end of GrayImage
+
+class SelectBandImage                              
+: public SingleBandImage
+{
+    class ImageHandle
+    {
+      public:
+        virtual ~ImageHandle() {}         /////////das verstehe ich nicht
+    };
+
+    template <class IMAGE>
+    class ImageHandleImpl
+    : public ImageHandle
+    {
+        boost::shared_ptr<IMAGE> ptr_;  
+
+        typedef typename IMAGE::PixelType PixelType;
+
+      public:
+        ImageHandleImpl(boost::shared_ptr<IMAGE> const & p)
+        : ptr_(p)
+        {}
+    };
+    
+  public:
+#ifndef NO_COVARIANT_RETURN_TYPES                                           //////AEND_10//////
+    typedef GrayImage CloneType;
+    typedef SelectBandImage ShallowCopyType;
+#else                                                                       //////AEND_10//////
+    typedef CloneType ShallowCopyType;
+#endif    
+  
+    template <class IMAGE>                              
+    SelectBandImage(IMAGE const & s, int band)
+    : imageHandle_(new ImageHandleImpl<typename IMAGE::InnerImage>(s.image_)),    
+      band_(band)
+    {
+        vigra_precondition(band >= 0 && band < s.actualBands(),
+            "SelectBandImage(): band out of range.");
+        initAdministrationData(getDataPtr(s.image_->begin())+band, s.actualSize(), s.actualBands(), 1);
+        if(s.width()*s.height() > 0)
+            setROI(s.roiUpperLeft(), s.size());
+    }
+    
+    SelectBandImage(SelectBandImage const & s)       
+    : SingleBandImage(s),
+      imageHandle_(s.imageHandle_),
+      band_(s.band_)
+    {}
+
+    SelectBandImage & operator=(SelectBandImage const & s)           
+    {
+        if(this != &s)
+        {
+            imageHandle_ = s.imageHandle_;
+            band_ = s.band_;
+            SingleBandImage::operator=(s);
+        }
+        return *this;
+    }
+    
+    virtual ~SelectBandImage()                  
+        {}
+    
+    /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
+    *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
+    *   mit der Groesse und Pixelinitialisierung der ROI
+    */
+    virtual CloneType * clone() const           
+    {
+        CloneType::InnerImage * newimg = new CloneType::InnerImage(size());
+        copyImage(srcIterRange(upperLeft(), lowerRight(), accessor()), destImage(*newimg));
+        return new CloneType(newimg); 
+    }
+    
+    /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer 
+    *   auf das aufrufende Objekt zurueckgeliefert.
+    *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
+    *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
+    *   dabei ist an der shallowCopy genau so die ROI gesetzt.
+    */ 
+    virtual SelectBandImage * shallowCopy() const         
+    {
+        return new SelectBandImage(*this); 
+    }
+    
+    virtual void setROI(Diff2D const & ul, Diff2D const & new_size)       
+    {
+        VariableBandsImage::setROI(ul, new_size);
+    }
+    
+    /** die Methode "setROI(int band)" aendert den selektierten Band.
+    * Parameter "band" ist der neue zu selektierender Band des Bildes
+    */
+    virtual void setROI(int band)                                        
+    {
+        vigra_precondition(band >= 0 && band < actualBands_,
+            "SelectbandImage::setROI(): band out of range.");
+        data_ = (data_ - band_ + band);
+        band_ = band;
+    }
+    
+    /** Liefert die "Nummer" des selektierten Bandes
+    */
+    int getSelectedBand()
+    { return band_; }
+        
+ private:
+    boost::shared_ptr<ImageHandle> imageHandle_;
+    int band_;
+};
+    
+/****************************************************************/
+
+#if 0 // this didn't work with MSVC
+
+#define defineArgumentFactories(Image) \
+template <class Accessor> \
+inline triple<Image::ConstIterator, Image::ConstIterator, Accessor> \
+srcImageRange(Image const & img, Accessor a) \
+{ \
+    return triple<Image::ConstIterator, Image::ConstIterator, Accessor>( \
+            img.upperLeft(), img.lowerRight(), a); \
+} \
+ \
+template <class Accessor> \
+inline pair<Image::ConstIterator, Accessor> \
+srcImage(Image const & img, Accessor a) \
+{ \
+    return pair<Image::ConstIterator, Accessor>( \
+            img.upperLeft(), a); \
+} \
+ \
+template <class Accessor> \
+inline triple<Image::Iterator, Image::Iterator, Accessor> \
+destImageRange(Image & img, Accessor a) \
+{ \
+    return triple<Image::Iterator, Image::Iterator, Accessor>( \
+            img.upperLeft(), img.lowerRight(), a); \
+} \
+ \
+template <class Accessor> \
+inline pair<Image::Iterator, Accessor> \
+destImage(Image & img, Accessor a) \
+{ \
+    return pair<Image::Iterator, Accessor>( \
+            img.upperLeft(), a); \
+} \
+ \
+template <class Accessor> \
+inline pair<Image::ConstIterator, Accessor> \
+maskImage(Image const & img, Accessor a) \
+{ \
+    return pair<Image::ConstIterator, Accessor>( \
+            img.upperLeft(), a); \
+} \
+ \
+inline triple<Image::ConstIterator, Image::ConstIterator, Image::ConstAccessor> \
+srcImageRange(Image const & img) \
+{ \
+    return triple<Image::ConstIterator, Image::ConstIterator, Image::ConstAccessor>( \
+            img.upperLeft(), img.lowerRight(), img.accessor()); \
+} \
+ \
+inline pair<Image::ConstIterator, Image::ConstAccessor> \
+srcImage(Image const & img) \
+{ \
+    return pair<Image::ConstIterator, Image::ConstAccessor>( \
+            img.upperLeft(), img.accessor()); \
+} \
+ \
+inline triple<Image::Iterator, Image::Iterator, Image::Accessor> \
+destImageRange(Image & img) \
+{ \
+    return triple<Image::Iterator, Image::Iterator, Image::Accessor>( \
+            img.upperLeft(), img.lowerRight(), img.accessor()); \
+} \
+ \
+inline pair<Image::Iterator, Image::Accessor> \
+destImage(Image & img) \
+{ \
+    return pair<Image::Iterator, Image::Accessor>( \
+            img.upperLeft(), img.accessor()); \
+} \
+ \
+inline pair<Image::ConstIterator, Image::ConstAccessor> \
+maskImage(Image const & img) \
+{ \
+    return pair<Image::ConstIterator, Image::ConstAccessor>( \
+            img.upperLeft(), img.accessor()); \
+}
+
+defineArgumentFactories(VariableBandsImage)
+defineArgumentFactories(Vector2Image)
+defineArgumentFactories(Vector3Image)
+defineArgumentFactories(Vector4Image)
+defineArgumentFactories(GrayImage)
+defineArgumentFactories(RGBImage)
+defineArgumentFactories(SelectBandImage)
+defineArgumentFactories(SingleBandImage)
+
+#endif
+////////////////////////////////////////ab hier bis Markierung soll eine Anpassung an den Kompiler sein
+#define defineArgumentFactories(Image) \
+template <class Accessor> \
+inline triple<Image::ConstIterator, Image::ConstIterator, Accessor> \
+srcImageRange(Image const & img, Accessor a) \
+{ \
+    return triple<Image::ConstIterator, Image::ConstIterator, Accessor>( \
+            img.upperLeft(), img.lowerRight(), a); \
+} \
+  \
+template <class Accessor> \
+inline pair<Image::ConstIterator, Accessor> \
+srcImage(Image const & img, Accessor a) \
+{ \
+    return pair<Image::ConstIterator, Accessor>( \
+            img.upperLeft(), a); \
+} \
+ \
+template <class Accessor> \
+inline triple<Image::Iterator, Image::Iterator, Accessor> \
+destImageRange(Image & img, Accessor a) \
+{ \
+    return triple<Image::Iterator, Image::Iterator, Accessor>( \
+            img.upperLeft(), img.lowerRight(), a); \
+} \
+ \
+template <class Accessor> \
+inline pair<Image::Iterator, Accessor> \
+destImage(Image & img, Accessor a) \
+{ \
+    return pair<Image::Iterator, Accessor>( \
+            img.upperLeft(), a); \
+} \
+ \
+template <class Accessor> \
+inline pair<Image::ConstIterator, Accessor> \
+maskImage(Image const & img, Accessor a) \
+{ \
+    return pair<Image::ConstIterator, Accessor>( \
+            img.upperLeft(), a); \
+} \
+ \
+inline triple<Image::ConstIterator, Image::ConstIterator, Image::ConstAccessor> \
+srcImageRange(Image const & img) \
+{ \
+    return triple<Image::ConstIterator, Image::ConstIterator, Image::ConstAccessor>( \
+            img.upperLeft(), img.lowerRight(), img.accessor()); \
+} \
+ \
+inline pair<Image::ConstIterator, Image::ConstAccessor> \
+srcImage(Image const & img) \
+{ \
+    return pair<Image::ConstIterator, Image::ConstAccessor>( \
+            img.upperLeft(), img.accessor()); \
+} \
+ \
+inline triple<Image::Iterator, Image::Iterator, Image::Accessor> \
+destImageRange(Image & img) \
+{ \
+    return triple<Image::Iterator, Image::Iterator, Image::Accessor>( \
+            img.upperLeft(), img.lowerRight(), img.accessor()); \
+} \
+ \
+inline pair<Image::Iterator, Image::Accessor> \
+destImage(Image & img) \
+{ \
+    return pair<Image::Iterator, Image::Accessor>( \
+            img.upperLeft(), img.accessor()); \
+} \
+ \
+inline pair<Image::ConstIterator, Image::ConstAccessor> \
+maskImage(Image const & img) \
+{ \
+    return pair<Image::ConstIterator, Image::ConstAccessor>( \
+            img.upperLeft(), img.accessor()); \
+}
+
+#define defineArgumentFactories2(Image, BaseImage) \
+template <class Accessor> \
+inline triple<BaseImage::ConstIterator, BaseImage::ConstIterator, Accessor> \
+srcImageRange(Image const & img, Accessor a) \
+{ \
+    return triple<BaseImage::ConstIterator, BaseImage::ConstIterator, Accessor>( \
+            img.upperLeft(), img.lowerRight(), a); \
+} \
+  \
+template <class Accessor> \
+inline pair<BaseImage::ConstIterator, Accessor> \
+srcImage(Image const & img, Accessor a) \
+{ \
+    return pair<BaseImage::ConstIterator, Accessor>( \
+            img.upperLeft(), a); \
+} \
+ \
+template <class Accessor> \
+inline triple<BaseImage::Iterator, BaseImage::Iterator, Accessor> \
+destImageRange(Image & img, Accessor a) \
+{ \
+    return triple<BaseImage::Iterator, BaseImage::Iterator, Accessor>( \
+            img.upperLeft(), img.lowerRight(), a); \
+} \
+ \
+template <class Accessor> \
+inline pair<BaseImage::Iterator, Accessor> \
+destImage(Image & img, Accessor a) \
+{ \
+    return pair<BaseImage::Iterator, Accessor>( \
+            img.upperLeft(), a); \
+} \
+ \
+template <class Accessor> \
+inline pair<BaseImage::ConstIterator, Accessor> \
+maskImage(Image const & img, Accessor a) \
+{ \
+    return pair<BaseImage::ConstIterator, Accessor>( \
+            img.upperLeft(), a); \
+} \
+ \
+inline triple<BaseImage::ConstIterator, BaseImage::ConstIterator, Image::ConstAccessor> \
+srcImageRange(Image const & img) \
+{ \
+    return triple<BaseImage::ConstIterator, BaseImage::ConstIterator, Image::ConstAccessor>( \
+            img.upperLeft(), img.lowerRight(), img.accessor()); \
+} \
+ \
+inline pair<BaseImage::ConstIterator, Image::ConstAccessor> \
+srcImage(Image const & img) \
+{ \
+    return pair<BaseImage::ConstIterator, Image::ConstAccessor>( \
+            img.upperLeft(), img.accessor()); \
+} \
+ \
+inline triple<BaseImage::Iterator, BaseImage::Iterator, Image::Accessor> \
+destImageRange(Image & img) \
+{ \
+    return triple<BaseImage::Iterator, BaseImage::Iterator, Image::Accessor>( \
+            img.upperLeft(), img.lowerRight(), img.accessor()); \
+} \
+ \
+inline pair<BaseImage::Iterator, Image::Accessor> \
+destImage(Image & img) \
+{ \
+    return pair<BaseImage::Iterator, Image::Accessor>( \
+            img.upperLeft(), img.accessor()); \
+} \
+ \
+inline pair<BaseImage::ConstIterator, Image::ConstAccessor> \
+maskImage(Image const & img) \
+{ \
+    return pair<BaseImage::ConstIterator, Image::ConstAccessor>( \
+            img.upperLeft(), img.accessor()); \
+}
+
+defineArgumentFactories(VariableBandsImage)
+defineArgumentFactories2(Vector2Image, FVector2Image)
+//defineArgumentFactories2(Vector3Image, FVector3Image)
+defineArgumentFactories2(Vector4Image, FVector4Image)
+defineArgumentFactories(GrayImage)
+defineArgumentFactories(RGBImage)
+defineArgumentFactories(SelectBandImage)
+defineArgumentFactories(SingleBandImage)
+////////////////////////////////////////
+
+template<>
+struct IteratorTraits<VariableBandsIterator >
+{
+    typedef StandardValueAccessor<VectorProxy> DefaultAccessor;
+};  
+
+template<>
+struct IteratorTraits<ConstVariableBandsIterator >
+{
+    typedef StandardConstValueAccessor<ConstVectorProxy> DefaultAccessor;
+};  
+
+template<>
+struct IteratorTraits<SelectBandIterator<GrayValue> >
+{
+    typedef StandardAccessor<GrayValue> DefaultAccessor;
+};  
+
+template<>
+struct IteratorTraits<ConstSelectBandIterator<GrayValue> >
+{
+    typedef StandardConstAccessor<GrayValue> DefaultAccessor;
+};  
+
+
+} // namespace vigra
+
+#endif /* VIGRA_IMAGEHIERARCHY_HXX */
+
+
diff --git a/test/imagehierarchy/basic_image_test.hxx b/test/imagehierarchy/basic_image_test.hxx
new file mode 100644
index 0000000..9c1ec5a
--- /dev/null
+++ b/test/imagehierarchy/basic_image_test.hxx
@@ -0,0 +1,105 @@
+#ifndef BASIC_IMAGE_TEST_HXX
+#define BASIC_IMAGE_TEST_HXX
+
+#include "parent_test_class.hxx"
+
+template<class Policy>
+class BasicImageTest
+: public ImageTest<Policy>
+{
+public:
+    typedef typename Policy::Image              Image;              // zu testende Klasse z.B. GrayImage, VariableBandsImage usw.
+    typedef typename Policy::ChildImage         ChildImage;         // unterscheidet sich von zu testender Klasse Image, nur wenn einer der abstrakten Klassen VariableBandImage oder SingleBandImage oder die Klasse SelectBandImage getestet wird, sonst entspricht es der Klasse Image.  
+    typedef typename Policy::value_type         value_type;         // value_type der zu testenden Klasse
+    typedef typename Policy::child_value_type   child_value_type;   // value_type der Klasse an der die zu testende Klasse getestet wird, also z.B. VariableBandsImage wird am Beispiel von Vector2Image getestet dann ist child_value_type die value_type von Vector2Image
+    
+    
+    /** Testet den Zuweisungsoperator bei dem auf der linken Seiten ein Pixel steht
+    */
+    void testOperatorAssignmentPixel()
+    {
+        (*image1_) = data[4];
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[4])));
+        
+        (*image0_) = data[5];
+        should(image0_->end() == std::find_if(image0_->begin(), image0_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[5])));
+    }
+    
+    void testResizeInt()
+    {
+        image1_->resize(6, 10);
+        should(image1_->height() == 10);
+        should(image1_->width() == 6);
+        should(image1_->size() == vigra::Diff2D(6,10));
+        
+        image0_->resize(2, 3);
+        should(image0_->height() == 3);
+        should(image0_->width() == 2);
+        should(image0_->size() == vigra::Diff2D(2,3));          
+    }
+    
+    void testResize2D()
+    {
+        image1_->resize(vigra::Diff2D(7,8));
+        should(image1_->height() == 8);
+        should(image1_->width() == 7);
+        should(image1_->size() == vigra::Diff2D(7,8));
+        
+        image0_->resize(vigra::Diff2D(1, 4));
+        should(image0_->height() == 4);
+        should(image0_->width() == 1);
+        should(image0_->size() == vigra::Diff2D(1,4));         
+    }
+    
+    void testResizeIntInit()
+    {
+        image1_->resize(4, 6, data[9]);
+        should(image1_->height() == 6);
+        should(image1_->width() == 4);
+        should(image1_->size() == vigra::Diff2D(4,6));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
+        
+        image0_->resize(1, 4, data[10]);
+        should(image0_->height() == 4);
+        should(image0_->width() == 1);
+        should(image0_->size() == vigra::Diff2D(1,4));
+        should(image0_->end() == std::find_if(image0_->begin(), image0_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[10])));      
+    }
+    
+    /** testet die Methode resizeCopy(BasicImage img) an Instanzen der Klasse BasicImage.
+    * Imagehierarchie enthaelt die Methode nicht !!! Also, wird es auch nicht getestet
+    * fuer Imagehierarchie.
+    */
+    void testResizeCopy()
+    {
+        image0_->resizeCopy(*image1_);
+        should(equal(*image0_, *image1_));
+        should(&(*image0_) != &(*image1_));
+        
+        std::auto_ptr<Image> image1(new Image(*image1_));
+        image1->resize(6, 10, data[11]);
+        
+        image1_->resizeCopy(*image1);
+        should(equal(*image1, *image1_));
+        should(!equal(*image0_, *image1_));
+        should(& (*image0_ )!= & (*image1_));
+        should(& (*image1) != & (*image1_));
+    }
+};// end of class BasicImageTest
+
+template <class POLICY>
+struct BasicImageTestSuite
+: public ImageTestSuite<POLICY>
+{
+    BasicImageTestSuite(const char * to_test_Image_name)
+    : ImageTestSuite<POLICY>(to_test_Image_name)
+    {
+        add( testCase( &BasicImageTest<POLICY>::testOperatorAssignmentPixel)); 
+        add( testCase( &BasicImageTest<POLICY>::testResizeInt));
+        add( testCase( &BasicImageTest<POLICY>::testResize2D));
+        add( testCase( &BasicImageTest<POLICY>::testResizeIntInit));
+        add( testCase( &BasicImageTest<POLICY>::testResizeCopy));
+    }
+};//end of struct BasicImageTestSuite
+
+#endif // BASIC_IMAGE_TEST_HXX
diff --git a/test/imagehierarchy/g++_relops_workaround.hxx b/test/imagehierarchy/g++_relops_workaround.hxx
new file mode 100644
index 0000000..e729269
--- /dev/null
+++ b/test/imagehierarchy/g++_relops_workaround.hxx
@@ -0,0 +1,13 @@
+#if defined(__GNUC__) && (__GNUC__ < 3) && !defined(__SGI_STL_INTERNAL_RELOPS)
+
+#   define __STL_BEGIN_RELOPS_NAMESPACE namespace std { namespace rel_ops {
+#   define __STL_END_RELOPS_NAMESPACE }}
+#   define __STD_RELOPS std::rel_ops
+
+#include <stl_relops.h>
+
+#   undef __STL_BEGIN_RELOPS_NAMESPACE
+#   undef __STL_END_RELOPS_NAMESPACE
+#   undef __STD_RELOPS
+#endif
+
diff --git a/test/imagehierarchy/gray_image_test_suite.cxx b/test/imagehierarchy/gray_image_test_suite.cxx
new file mode 100644
index 0000000..eea0007
--- /dev/null
+++ b/test/imagehierarchy/gray_image_test_suite.cxx
@@ -0,0 +1,19 @@
+#include "g++_relops_workaround.hxx"
+
+#include <unittest.hxx>
+#include "one_band_image_policy.hxx"
+#include "imagehierarchy_test.hxx"
+
+GrayImageTestSuite::GrayImageTestSuite()
+    : vigra::test_suite(" GrayImageTestSuite")
+    {
+        add ( new ImageHierarchyTestSuite<OneBandImagePolicy<vigra::GrayImage> > ("vigra::GrayImage"));
+    }
+
+// int main()
+// {
+//     GrayImageTestSuite suite;
+//     int failed = suite.run();
+//     std::cout << suite.report() << std::endl;
+//     return (failed != 0);
+// }
diff --git a/test/imagehierarchy/imagehierarchy_test.hxx b/test/imagehierarchy/imagehierarchy_test.hxx
new file mode 100644
index 0000000..4cd371d
--- /dev/null
+++ b/test/imagehierarchy/imagehierarchy_test.hxx
@@ -0,0 +1,375 @@
+#ifndef IMAGEHIERARCHY_TEST_HXX
+#define IMAGEHIERARCHY_TEST_HXX
+
+#include "parent_test_class.hxx"
+
+template<class Policy>
+class ImageHierarchyTest
+: public ImageTest<Policy>
+{    
+public:
+    typedef typename Policy::Image              Image;              // zu testende Klasse z.B. GrayImage, VariableBandsImage usw.
+    typedef typename Policy::ChildImage         ChildImage;         // unterscheidet sich von zu testender Klasse Image, nur wenn einer der abstrakten Klassen VariableBandImage oder SingleBandImage oder die Klasse SelectBandImage getestet wird, sonst entspricht es der Klasse Image.  
+    typedef typename Policy::value_type         value_type;         // value_type der zu testenden Klasse
+    typedef typename Policy::child_value_type   child_value_type;   // value_type der Klasse an der die zu testende Klasse getestet wird, also z.B. VariableBandsImage wird am Beispiel von Vector2Image getestet dann ist child_value_type die value_type von Vector2Image
+    
+    /** testet die Konstruktorden der imagehierarchy Klasse, an die die InnerImage (BasicImage<float>)
+    * uebergeben wird, also Image (InnerImage i)
+    */
+    void testInnerImageConstructor()
+    {
+        std::auto_ptr<Image> image1(Policy::factory(new typename ChildImage::InnerImage(3, 4, child_data[0]))); 
+        should(image1->height() == 4);
+        should(image1->width() == 3);
+        should(image1->size() == vigra::Diff2D(3,4));
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), child_data[0])));    
+        
+        std::auto_ptr<Image> image2(Policy::factory(new typename ChildImage::InnerImage(0, 0, child_data[1])));
+        should(image2->height() == 0);
+        should(image2->width() == 0);
+        should(image2->size() == vigra::Diff2D(0,0));
+        should(image2->end() == std::find_if(image2->begin(), image2->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), child_data[1])));    
+    }
+    
+    /** testet die clone() Methode der Klasse aus imagehierarchy
+    */
+    void testClone()
+    {
+        /*
+        *  Im Falle der Aenderungsvornehmungen an einem der Images, werden die Aenderungen auch nur an einem sichtbar
+        */
+        std::auto_ptr<typename Image::CloneType> image1(image1_->clone()); 
+        should(equal(*image1, *image1_));                                               
+        should(equalPixels(image1_->begin(),image1_->end(), image1->begin()));             
+        should(&(*image1) != &(*image1_));                                              
+        
+        /* Aenderung mit der init-Funktion
+        */
+        image1->init(data[5]); 
+        should((*image1_->begin()) != static_cast<typename Image::PixelType> (data[5]));
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[5])));
+        
+        image1_->init(data[6]);
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[5])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[6])));
+        
+        std::auto_ptr<typename Image::CloneType> image0(image0_->clone());
+        should(equal(*image0, *image0_));
+        should(equalPixels(image0_->begin(),image0_->end(), image0->begin()));image1_->init(data[6]);
+        should(&(*image0) != &(*image0_));
+
+        /* Aenderung mit dem Zuweisungsoperator -> siehe in testShallowCopy()
+        */
+        (*image0_) = (*image1_);                              
+        should(image0->size() == vigra::Diff2D(0,0));
+        should(image0_->size() == vigra::Diff2D(3,5));
+        should(!equal(*image0, *image0_));
+        should(equal(*image1_, *image0_));
+    }
+    
+    /** testet die shallowCopy() Methode der Klassen aus imagehierarchy.
+    */
+    void testShallowCopy()
+    {
+        /*
+        *  Im Falle der Aenderungsvornehmungen an einem der Images, werden die Aenderungen an beiden sichtbar
+        *  Es gibt nur zwei Aenderungsmoeglichkeiten init() und Zuweisung eines anderen Images
+        *  bei der Zuweisung werden die Zeiger von den eigenen Daten auf die anderen umgeleitet,
+        *  und das entspricht nicht dem Sinn der shallowCopy
+        */
+        std::auto_ptr<Image> image1(image1_->shallowCopy());
+        should(equal(*image1, *image1_));     
+        should(&(*image1) != &(*image1_));
+        
+        /* Aenderung mit der init-Funktion
+        */
+        image1->init(data[7]);
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[7])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[7])));
+        
+        image1->init(data[8]);
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[8])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[8])));
+        
+        /* Eine shallowCopy zeigt auf die selben Daten des kopierten Objektes
+        */
+        std::auto_ptr<Image> image1Copy(image1->shallowCopy());
+        should(equal(*image1Copy, *image1_));
+        should(&(*image1Copy) != &(*image1_));
+        
+        image1Copy->init(data[9]);
+        should(image1Copy->end() == std::find_if(image1Copy->begin(), image1Copy->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
+        
+        std::auto_ptr<Image> image0(image0_->shallowCopy());
+        should(equal(*image0, *image0_));
+        should(&(*image0) != &(*image0_));
+        
+        (*image0_) = (*image1_);
+        should(equal(*image1_, *image0_));
+        should(!equal(*image1_, *image0));
+        should(!equal(*image0_, *image0));
+    }
+    
+    /** Testet die Methode actualSize(), die die Groesse des kompletten Bildes liefert und nicht der ROI
+    */
+    void testActualSize()
+    {
+        should(image1_->size() == image1_->actualSize());
+        image1_->setROI(Diff2D(1,1), Diff2D(1,3));
+        should(image1_->size() != image1_->actualSize());
+        should(image1_->size() == Diff2D(1,3));
+    }
+    
+    /** Testet die Methode actualWidth(), die die Breite des kompletten Bildes liefert und nicht der ROI
+    */
+    void testActualWidth()
+    {
+        should(image1_->width() == image1_->actualWidth());
+        image1_->setROI(Diff2D(1,1), Diff2D(1,3));
+        should(image1_->width() == 1);
+        should(image1_->width() != image1_->actualWidth());
+    }
+    
+    /** Testet die Methode actualHeight(), die die Hoehe des kompletten Bildes liefert und nicht der ROI
+    */
+    void testActualHeight()
+    {
+        should(image1_->height() == image1_->actualHeight());
+        image1_->setROI(Diff2D(1,1), Diff2D(1,3));
+        should(image1_->height() == 3);
+        should(image1_->height() != image1_->actualHeight());
+    }
+
+    /** Testet die Methode actualBands(), die die Anzahl der Baender eines Bildes liefert 
+    */
+    void testActualBands()
+    {
+        should(image1_->bands() == image1_->actualBands());
+    }
+    
+    /** Testet die Methode bands(), die die Anzahl der selektirerten Baender eines Bildes liefert.
+    * Die Anzahl der selektirerten Baender ist bei allen Bildern gleich dem Anzahl der Baender des Bildes,
+    * die Ausnahme bildet SelectBandImage dort ist immer nur ein Band selektiert.
+    */
+    void testBands()
+    {
+        should(image1_->bands() == image1_->actualBands());
+    }
+    
+    /** testet die Methode roiUpperLeft(), die die Koordinaten der linken
+    * oberen Ecke von ROI liefert.
+    */
+    void testRoiUpperLeft()
+    {
+        should(image1_->roiUpperLeft() == Diff2D(0, 0));
+        image1_->setROI(Diff2D(1,1), Diff2D(1,3));
+        should(image1_->roiUpperLeft() == Diff2D(1, 1));
+        should((*image1_)[image1_->roiUpperLeft()] != (*image1_->upperLeft()));
+    }
+
+    /** testet die Methode setROI(), die eine ROI auf einem Bild setzt.
+    */
+    void testSetROI()
+    {
+        std::auto_ptr<Image> image1_copy(image1_->shallowCopy());               //dient der Vergleichsmoeglichkeit
+        image1_->setROI(Diff2D(1,1), Diff2D(1,3));
+        
+        should(image1_->width() == (image1_->actualWidth() - 2));
+        should(image1_->height() == (image1_->actualHeight() - 2));
+        should(image1_->size() == (image1_->actualSize() - Diff2D(2, 2)));
+        should((*image1_copy)(1,1) == (*image1_)(0,0));
+        
+        /*  Differenz zweier ScanOrderIteratoren ist eine int_Zahl
+        */
+        should((image1_->end() - image1_->begin()) == 3);                       // Anzahl der Pixel in der ROI
+        should((image1_copy->end() - image1_copy->begin()) == 15);              // Anzahl der Pixel im Hauptbild
+                
+        /*  Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
+        *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
+        *   dabei ist an der shallowCopy genau so die ROI gesetzt.
+        */
+        std::auto_ptr<Image> image1_ROI_copy(image1_->shallowCopy());
+         
+        should(!(image1_ROI_copy->size() == image1_ROI_copy->actualSize()));
+        should(image1_ROI_copy->size() == image1_->size());
+        
+        /*  Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
+        *   mit der Groesse und Pixelinitialisierung der ROI
+        */
+        std::auto_ptr<typename Image::CloneType> image1_ROI_clone(image1_->clone());
+        
+        should(image1_ROI_clone->size() == image1_ROI_clone->actualSize());
+        should(image1_ROI_clone->size() == image1_->size());
+                   
+        for(int x = 0; x < image1_ROI_clone->width(); x++)
+            for(int y = 0; y < image1_ROI_clone->height(); y++)
+                should((*image1_ROI_clone)(x,y) == (*image1_copy)(x + 1,y + 1));
+                
+          
+        /*  Wenn man die Aenderungen an der ROI vornimmt, aendert sich auch die shallowCopy des Hauptbildes
+        *   aber verschoben um roiUpperLeft
+        */
+        image1_->init(data[7]);
+        
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[7])));
+                    
+        for(int x = 0; x < image1_->width(); x++)
+            for(int y = 0; y < image1_->height(); y++)
+                should((*image1_)(x,y) == static_cast<typename Policy::PixelType>(data[7]));
+
+                 
+        for(int x = 1; x < (image1_->width() + 1); x++)                                 //um 1 verschoben
+            for(int y = 1; y < (image1_->height() + 1); y++)                            //um 1 verschoben
+                should((*image1_copy)(x,y) == static_cast<typename Policy::PixelType>(data[7]));
+                
+        
+        for(int x = 0; x < image1_->width(); x++)                                       //Verhalten einer ROI
+            for(int y = 0; y < image1_->height(); y++)
+                should((*image1_ROI_copy)(x,y) == static_cast<typename Policy::PixelType>(data[7]));
+                
+        
+        /* Es wird ein neues Bild erzeugt mit unterschiedlichen Pixeldaten
+        */
+        std::auto_ptr<Image> image1_new(Policy::factory(3, 5));
+        typename Image::Accessor acc;
+        acc = image1_new->accessor();
+        scanOrderIter1_ = image1_new->begin();
+        for(unsigned int i = 0; i < data.size(); i++)
+            {   
+                acc.set(data[i], scanOrderIter1_);
+                ++scanOrderIter1_; 
+            }
+        
+        std::auto_ptr<Image> image1_new_copy(image1_new->shallowCopy());
+        
+        /*  Setzt man eine ROI auf der shallowCopy so ist sie auch nur in der Copy gesetzt.
+        *   Die Veraenderungen in der ROI sind aber in der Copie und im image1_new sichtbar,
+        *   im image1_new nur verschoben
+        */
+        image1_new_copy->setROI(Diff2D(1,1), Diff2D(1,3));
+        
+        should(image1_new->size() == image1_new->actualSize());
+        should(image1_new_copy->size() != image1_new_copy->actualSize());
+        
+        (*image1_new_copy)(0,0) = data[14];
+        
+        should((*image1_new_copy)(0,0) == static_cast<typename Policy::PixelType>(data[14]));
+        should((*image1_new)(1,1) == (*image1_new_copy)(0,0));
+        
+        /*  Von der ROI kann man in den negativen Bereich zurueckgreifen, da dort das Bild immernoch definiert ist
+        *   Vorsicht! der negative Zugrif darf nicht ausserhalb des eigentlichen Bildes erfolgen
+        */
+        should((image1_new_copy->upperLeft())[Diff2D(-1,-1)] == (*image1_new)(0,0));
+        
+        /*  Eine ROI ist auch auf die Groesse des Bildes ruecksetzbar
+        *   Vorsicht! Die Grenzueberschreitungen beachten!
+        */
+        image1_new_copy->setROI(Diff2D(-1,-1), image1_new_copy->actualSize());                      //Ruecksetzen
+        
+        should(image1_new_copy->size() == image1_new_copy->actualSize());
+        should((image1_new->upperLeft())[Diff2D(0,0)] == (*image1_new_copy)[image1_new_copy->roiUpperLeft()]);
+        
+        
+        /*  Setzt man die ROI mit neagtiven Werten in size so wird der negative Wert vom lowerRight des Bildes abgezogen
+        *   in unserem Falle sind Folgende ROIsetzungen gleich
+        */
+        image1_new_copy->setROI(Diff2D(1,1), Diff2D(-1,-1));
+        should((*image1_new_copy)(image1_new_copy->width() - 1, image1_new_copy->height() - 1) == (*image1_new)(1,3));
+        should(image1_new_copy->lowerRight()[Diff2D(0,0)] == (*image1_new)(image1_new->width() - 1,image1_new->height() - 1));
+        should(equalIteratorRun(image1_new_copy->upperLeft(), image1_new_copy->lowerRight(), image1_new_copy->begin()));
+        
+        image1_new_copy->setROI(Diff2D(-1,-1), image1_new_copy->actualSize());                      //Ruecksetzen
+        image1_new_copy->setROI(Diff2D(1,1), Diff2D(1,-1));                                         //neu setzen
+        
+        should((*image1_new_copy)(image1_new_copy->width() - 1, image1_new_copy->height() - 1) == (*image1_new)(1,3));
+        should(equalIteratorRun(image1_new_copy->upperLeft(), image1_new_copy->lowerRight(), image1_new_copy->begin()));
+        should(image1_new_copy->lowerRight()[Diff2D(0,0)] == (*image1_new)(image1_new->width() - 1,image1_new->height() - 1));
+        
+        image1_new_copy->resetROI();                                                                //Ruecksetzen
+        image1_new_copy->setROI(Diff2D(1,1), Diff2D(-1,3));                                         //neu setzen
+        
+        should((*image1_new_copy)(image1_new_copy->width() - 1, image1_new_copy->height() - 1) == (*image1_new)(1,3));
+        should(image1_new_copy->lowerRight()[Diff2D(0,0)] == (*image1_new)(image1_new->width() - 1,image1_new->height() - 1));
+        should(equalIteratorRun(image1_new_copy->upperLeft(), image1_new_copy->lowerRight(), image1_new_copy->begin()));
+     }//end of testSetRoi()
+     
+     /** testet die Methode resetROI(), die die gesetzte ROI wieder aufhebt
+     */
+     void testResetROI()
+     {
+        std::auto_ptr<typename Image::CloneType> image1(image1_->clone()); 
+        image1_->setROI(Diff2D(1,1), Diff2D(-1,3));
+        image1_->resetROI();  
+        should(equal(*image1, *image1_));
+     }
+     
+     /** Testet die setROI(int band) Methode der Klasse SelectBandImage. Die Methode aendert den 
+     * selektierten Band. 
+     */
+     void testSetROIBand()
+     {
+        should(image1_->getSelectedBand() == Policy::n);
+        image1_->setROI(Policy::n == 0 ? 1 : (Policy::n - 1));
+        should(image1_->getSelectedBand() != Policy::n);
+        should(image1_->getSelectedBand() == Policy::n == 0 ? 1 : (Policy::n - 1));
+        testSetROI();
+     }
+     
+     /** Testet die getSelectedBand() Methode der Klasse SelectBandImage. Die Methode liefert den 
+     * selektierten Band. 
+     */
+     void testGetSelectedBand()
+     {
+        should(image1_->getSelectedBand() == Policy::n);
+        image1_->setROI(Policy::n == 0 ? 1 : (Policy::n - 1));
+        should(image1_->getSelectedBand() != Policy::n);
+        should(image1_->getSelectedBand() == Policy::n == 0 ? 1 : (Policy::n - 1));
+     }
+         
+     void testIsInsideROI()
+     {
+        should(image1_->isInsideROI((image1_->actualSize())- Diff2D(1,1)));
+        
+        image1_->setROI(Diff2D(1,1), Diff2D(1,3));
+        
+        bool ergebnis = true;
+        for ( int i = 1 ; i < 2 ; i++)
+            for (int j = 1; j < 4; j ++)
+                ergebnis &= image1_->isInsideROI(vigra::Diff2D(i,j));
+
+        ergebnis &= !image1_->isInsideROI(vigra::Diff2D(0,0)) &&
+                     !image1_->isInsideROI(vigra::Diff2D(2,0)) &&
+                     !image1_->isInsideROI(vigra::Diff2D(0,4)) &&
+                     !image1_->isInsideROI(vigra::Diff2D(2,4)) &&
+                     !image1_->isInsideROI(vigra::Diff2D(2,2)) &&
+                     !image1_->isInsideROI(vigra::Diff2D(0,2)) &&
+                     !image1_->isInsideROI(vigra::Diff2D(2,0)); 
+                     
+        should(ergebnis);
+     }
+};// end of class ImageHierarchyTest
+
+template <class POLICY>
+struct ImageHierarchyTestSuite
+: public ImageTestSuite<POLICY>
+{
+    ImageHierarchyTestSuite(const char * to_test_Image_name)
+    : ImageTestSuite<POLICY>(to_test_Image_name)
+    {
+        add( testCase( &ImageHierarchyTest<POLICY>::testInnerImageConstructor));
+        add( testCase( &ImageHierarchyTest<POLICY>::testClone));
+        add( testCase( &ImageHierarchyTest<POLICY>::testShallowCopy));
+        add( testCase( &ImageHierarchyTest<POLICY>::testSetROI));
+        add( testCase( &ImageHierarchyTest<POLICY>::testResetROI));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualSize));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualWidth));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualHeight));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualBands));
+        add( testCase( &ImageHierarchyTest<POLICY>::testBands));
+        add( testCase( &ImageHierarchyTest<POLICY>::testRoiUpperLeft));
+        add( testCase( &ImageHierarchyTest<POLICY>::testIsInsideROI));
+    }
+};//end of struct ImageHierarchyTestSuite
+#endif // IMAGEHIERARCHY_TEST_HXX
diff --git a/test/imagehierarchy/one_band_basic_image_test_suite.cxx b/test/imagehierarchy/one_band_basic_image_test_suite.cxx
new file mode 100644
index 0000000..5169b70
--- /dev/null
+++ b/test/imagehierarchy/one_band_basic_image_test_suite.cxx
@@ -0,0 +1,31 @@
+#include "g++_relops_workaround.hxx"
+
+#include <unittest.hxx> 
+#include "one_band_image_policy.hxx" 
+#include "basic_image_test.hxx" 
+// 
+// struct OneBandBasicImageTestSuite
+// : public vigra::test_suite
+// {
+OneBandBasicImageTestSuite::OneBandBasicImageTestSuite()
+    : vigra::test_suite("OneBandBasicImageTestSuite")
+    {
+        add( new BasicImageTestSuite<OneBandImagePolicy<vigra::IImage> > ("vigra::IImage"));
+        add( new BasicImageTestSuite<OneBandImagePolicy<vigra::FImage> > ("vigra::FImage")); 
+        add( new BasicImageTestSuite<OneBandImagePolicy<vigra::BImage> > ("vigra::BImage"));
+        add( new BasicImageTestSuite<OneBandImagePolicy<vigra::SImage> > ("vigra::SImage"));
+        add( new BasicImageTestSuite<OneBandImagePolicy<vigra::DImage> > ("vigra::DImage"));
+    }
+// };
+// 
+// int main()
+// {
+//  
+//     OneBandBasicImageTestSuite itest;
+// 
+//     int failed = itest.run();
+// 
+//     std::cout << itest.report() << std::endl;
+//     
+//     return (failed != 0);
+// }  
diff --git a/test/imagehierarchy/one_band_image_policy.hxx b/test/imagehierarchy/one_band_image_policy.hxx
new file mode 100644
index 0000000..c86121e
--- /dev/null
+++ b/test/imagehierarchy/one_band_image_policy.hxx
@@ -0,0 +1,54 @@
+#ifndef ONE_BAND_IMAGE_POLICY_HXX
+#define ONE_BAND_IMAGE_POLICY_HXX
+
+#include "test_policy_parent.hxx"
+
+template<class ImageP>                                                  // bei dem template handelt es sich um ein EinBandImage, wie FImage, BImage, GrayImage usw.
+class OneBandImagePolicy 
+: public TestPolicy<ImageP> 
+{
+
+public:
+    typedef ImageP                               Image;                      //es handelt sich um ein EinBandImage, wie FImage, BImage, GrayImage usw. ChildImage und Image sind aequivalent.
+    typedef ImageP                               ChildImage;                 //es handelt sich um ein EinBandImage, wie FImage, BImage, GrayImage usw. ChildImage und Image sind aequivalent.
+    typedef typename ImageP::PixelType           PixelType;
+    typedef typename Image::value_type           value_type;
+    typedef typename Image::value_type           child_value_type;
+    typedef std::vector<value_type>              data_array_type;
+    typedef std::vector<value_type>              child_data_array_type;
+    
+    static data_array_type getData()
+    {
+        
+        static value_type variable = 1;
+        
+        variable = variable/100 + (variable*5)/1000 + variable;
+        
+        static value_type data[15];
+        
+        for(int i = 0; i<=14; i++)
+        {
+            data[i] = variable + i;
+        }
+        static data_array_type data_vector(data, data+sizeof(data)/sizeof(value_type));
+        return data_vector;
+    }
+    
+    static child_data_array_type getChildData()
+    {   
+        return getData();
+    }
+};
+
+struct OneBandBasicImageTestSuite 
+: public vigra::test_suite
+{
+    OneBandBasicImageTestSuite();
+};
+
+struct GrayImageTestSuite
+: public vigra::test_suite
+{
+    GrayImageTestSuite();
+};
+#endif // ONE_BAND_IMAGE_POLICY_HXX
diff --git a/test/imagehierarchy/parent_test_class.hxx b/test/imagehierarchy/parent_test_class.hxx
new file mode 100644
index 0000000..65e6377
--- /dev/null
+++ b/test/imagehierarchy/parent_test_class.hxx
@@ -0,0 +1,619 @@
+#ifndef PARENT_TEST_CLASS_HXX
+#define PARENT_TEST_CLASS_HXX
+
+#include <unittest.hxx>
+
+using vigra::Diff2D;
+// 
+// std::ostream & operator<<(std::ostream & o, vigra::ConstVectorProxy const & p)
+// {
+//     if(p.size() == 1)
+//     {
+//         o << p[0];
+//     }
+//     else
+//     {
+//         o << "(";
+//         int i;
+//         for (i=0; i<p.size()-1; ++i)
+//             o << p[i] << ", ";
+//         o << p[i] << ")";
+//     }
+//     return o;
+// }
+
+/** Vergleicht zwei Bilder auf aequivalenz der Pixel. Die Pixel muessen die GLEICHE 
+* ANZAHL der Baender haben
+*/
+template <class _InputIter1, class _InputIter2>
+inline bool equalPixels(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2) 
+{
+  for ( ; __first1 != __last1; ++__first1, ++__first2)
+    if (!(*__first1 == *__first2))
+      return false;
+  return true;
+}
+
+/** Vergleicht den gleichen Durchlauf von Iterator und ScanOrderIterator. Die Pixel muessen die GLEICHE 
+* ANZAHL der Baender haben
+*/
+template <class Iterator, class ScanOrderIterator>
+inline bool equalIteratorRun(Iterator ul, Iterator lr, ScanOrderIterator f) 
+{
+  for(; ul.y < lr.y; ++ul.y)
+  {
+    Iterator c = ul;
+    for(; c.x < lr.x; ++c.x, ++f)
+    {
+        if(*c != *f)
+            return false;
+    }
+  }
+  return true;
+}
+
+/** Untersucht zwei vergleichbare Bider auf Groesse- und PixelIdentitaet
+*  aeusserste Vorsicht: die Bilder muessen vergleichbar sein!!!! Es sind Bilder
+*  der gleichen Klasse vergleichbar und Bilder mit gleichen Anzahl der Baender !!!
+*/
+
+template<class Image, class ComparableImage>
+bool equal(Image const & image1, ComparableImage const & image2)
+{
+    if (image1.size() == image2.size())
+        return image1.height() == image2.height() &&
+               image1.width() == image2.width() &&
+               equalPixels(image1.begin(), image1.end(), image2.begin());
+    else return false;
+};
+
+/** Entspricht der "normalen" binary_function aus std, wurde aber aus Kompatibilitaetsgruenden
+* umbenannt und hier mitaufgenommen.
+*/
+template <class _Arg1, class _Arg2, class _Result>
+struct Pixels_binary_function {
+  typedef _Arg1 first_argument_type;
+  typedef _Arg2 second_argument_type;
+  typedef _Result result_type;
+}; 
+
+/** Vergleicht zwei Pixel auf Gleichheit.Entspricht der "normalen" not_equal_to aus std, 
+* wurde aber aus Kompatibilitaetsgruenden umbenannt und hier mitaufgenommen.
+*/
+template <class _Tp>
+struct Pixels_not_equal_to : public Pixels_binary_function<_Tp,_Tp,bool> 
+{
+  bool operator()(const _Tp& __x, const _Tp& __y) const { return !(__x == __y); }
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////                                    TESTKLASSE                                 ///////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+template <class Policy>
+class ImageTest
+{
+public:
+    typedef typename Policy::Image              Image;              // zu testende Klasse z.B. GrayImage, VariableBandsImage usw.
+    typedef typename Policy::ChildImage         ChildImage;         // unterscheidet sich von zu testender Klasse Image, nur wenn einer der abstrakten Klassen VariableBandImage oder SingleBandImage oder die Klasse SelectBandImage getestet wird, sonst entspricht es der Klasse Image.  
+    typedef typename Policy::value_type         value_type;         // value_type der zu testenden Klasse
+    typedef typename Policy::child_value_type   child_value_type;   // value_type der Klasse an der die zu testende Klasse getestet wird, also z.B. VariableBandsImage wird am Beispiel von Vector2Image getestet dann ist child_value_type die value_type von Vector2Image
+    
+    typename Policy::data_array_type data;
+    typename Policy::child_data_array_type child_data;
+ 
+    std::auto_ptr<Image> image0_;
+    std::auto_ptr<Image> image1_;
+    
+    typename Image::Accessor acc0_;
+    typename Image::Accessor acc1_;
+    
+    typename Image::ScanOrderIterator scanOrderIter0_;
+    typename Image::ConstScanOrderIterator constScanOrderIter0_;
+    typename Image::ScanOrderIterator scanOrderIter1_;
+    typename Image::ConstScanOrderIterator constScanOrderIter1_;
+    
+    typename Image::traverser traverserIter0_;
+    typename Image::const_traverser constTraverserIter0_;
+    typename Image::traverser traverserIter1_;
+    typename Image::const_traverser constTraverserIter1_;
+
+    typename Image::traverser::row_iterator rowIter1_;
+    typename Image::const_traverser::row_iterator constRowIter1_;
+
+    typename Image::traverser::column_iterator columnIter1_;
+    typename Image::const_traverser::column_iterator constColumnIter1_;
+    
+    ImageTest()
+    : image0_(Policy::factory()),
+      image1_(Policy::factory(3,5)), 
+      data(Policy::getData()),
+      child_data(Policy::getChildData())
+    {
+        acc0_ = image0_->accessor();
+        acc1_ = image1_->accessor();
+
+        scanOrderIter0_ = image0_->begin();
+        scanOrderIter1_ = image1_->begin();
+
+        acc1_.set(data[0], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[1], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[2], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[3], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[4], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[5], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[6], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[7], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[8], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[9], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[10], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[11], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[12], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[13], scanOrderIter1_);
+        ++scanOrderIter1_;
+        acc1_.set(data[14], scanOrderIter1_);
+        ++scanOrderIter1_;
+
+        should(scanOrderIter1_ == image1_->end());
+    }
+    
+    /**  Testet den Default-Konstruktor der zu testenden Imageklasse
+    */
+    void testImageDefaultConstuctor()
+    {
+        /*
+        *  image0_ wurde mit dem Default-Konstruktor erzeugt, es hat die Groesse Diff2D(0, 0)
+        */
+        should(image0_->height() == 0);
+        should(image0_->width() == 0);
+        should(image0_->size() == vigra::Diff2D(0,0));
+        should(!image0_->isInside(vigra::Diff2D(-1,0)));
+        should(!image0_->isInside(vigra::Diff2D(1,0)));
+        should(!image0_->isInside(vigra::Diff2D(0,1)));
+        should(!image0_->isInside(vigra::Diff2D(0,-1)));
+    }
+    
+    /**  Testet den "(WIDTH, HEIGHT)"-Konstruktor der zu testenden Imageklasse
+    */
+    void testImageIntConstuctor()
+    {
+        should(image1_->height() == 5);
+        should(image1_->width() == 3);
+        should(image1_->size() == vigra::Diff2D(3,5));
+    }
+    
+    /**  Testet den "(Diff2D)"-Konstruktor der zu testenden Imageklasse
+    */
+    void testImage2DConstuctor()
+    {
+        std::auto_ptr<Image> image1(Policy::factory(Diff2D(2,3)));
+        should(image1->height() == 3);
+        should(image1->width() == 2);
+        should(image1->size() == vigra::Diff2D(2,3));
+        
+        std::auto_ptr<Image> image2(Policy::factory(Diff2D(0, 0)));
+        should(image2->height() == 0);
+        should(image2->width() == 0);
+        should(image2->size() == vigra::Diff2D(0,0));
+    }
+    
+    /**  Testet den "(WIDTH, HEIGHT, PIXELTYPE)"-Konstruktor der zu testenden Imageklasse
+    */
+    void testImageIntPixelConstuctor()
+    {
+        std::auto_ptr<Image> image1(Policy::factory(2,3, child_data[0]));
+        should(image1->height() == 3);
+        should(image1->width() == 2);
+        should(image1->size() == vigra::Diff2D(2,3));
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), child_data[0])));    
+        
+        std::auto_ptr<Image> image2(Policy::factory(0, 0, child_data[1]));
+        should(image2->height() == 0);
+        should(image2->width() == 0);
+        should(image2->size() == vigra::Diff2D(0,0));
+        should(image2->end() == std::find_if(image2->begin(), image2->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), child_data[1])));    
+    }
+    
+    /** Testet den Copy Konstruktor ( Image(Image img) ).
+    */
+    void testCopyConstructor()
+    {
+        ChildImage * image1 = new ChildImage(3, 5, child_data[2]);
+        std::auto_ptr<Image> image1_copy(Policy::factory(*image1));
+
+        ChildImage image0(0, 0, child_data[3]);
+        std::auto_ptr<Image> image0_copy(Policy::factory(image0));
+
+        should(image1_copy->height() == 5);
+        should(image1_copy->width() == 3);
+        should(image1_copy->size() == vigra::Diff2D(3,5));
+        should(equalPixels(image1->begin(),image1->end(), image1_copy->begin()));
+        should(image0_copy->height() == 0);
+        should(image0_copy->width() == 0);
+        should(image0_copy->size() == vigra::Diff2D(0,0));
+        should(equalPixels(image0_->begin(), image0_->end(), image0_copy->begin()));
+     }
+     
+    /** Testet den Zuweisungsoperator bei dem auf den beiden Seiten das zu testende Bild steht
+    */
+    void testOperatorAssignmentImage()
+    {
+        std::auto_ptr<Image> image(Policy::factory());
+        (*image) = (*image1_);
+        should(equal(*image, *image1_));
+        should(&image != &image1_);
+        
+        (*image) = (*image0_);
+        should(!equal(*image, *image1_));
+        should(equal(*image, *image0_));
+        should( &(*image) !=  &(*image0_));
+    }
+    
+    /** Testet die init() Methode
+    */
+    void testInit()
+    {
+        image1_->init(data[6]);
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[6])));
+        image1_->init(data[7]);
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[7])));
+        should(image1_->end() != std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[6])));
+        
+        image0_->init(data[8]);
+        should(image0_->end() == std::find_if(image0_->begin(), image0_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[8])));
+    }
+    
+    void testWidth()
+    {
+        should(3 == image1_->width());
+        should(0 == image0_->width());
+    } 
+    
+    void testHeight()
+    {
+        should(5 == image1_->height());
+        should(0 == image0_->height());
+    } 
+    
+    void testSize()
+    {
+        should(image1_->size() == vigra::Diff2D(3,5));
+        should(image0_->size() == vigra::Diff2D(0,0));
+    }
+    
+    void testIsInside()
+    {
+        bool ergebnis = true;
+        for ( int i = 0 ; i < 3 ; i++)
+            for (int j = 0; j < 5; j ++)
+                ergebnis &= image1_->isInside(vigra::Diff2D(i,j));
+
+        ergebnis &= !image1_->isInside(vigra::Diff2D(-1,-1)) &&
+                     !image1_->isInside(vigra::Diff2D(-1,2)) &&
+                     !image1_->isInside(vigra::Diff2D(2,-1)) &&
+                     !image1_->isInside(vigra::Diff2D(-1,5)) &&
+                     !image1_->isInside(vigra::Diff2D(3,-1)) &&
+                     !image1_->isInside(vigra::Diff2D(3,2)) &&
+                     !image1_->isInside(vigra::Diff2D(3,5)) &&
+                     !image1_->isInside(vigra::Diff2D(2,5));
+                     
+        should(ergebnis);
+        
+        ergebnis = !image0_->isInside(vigra::Diff2D(-1,-1)) &&
+                   !image0_->isInside(vigra::Diff2D(-1,0)) &&
+                   !image0_->isInside(vigra::Diff2D(0,-1)) &&
+                   !image0_->isInside(vigra::Diff2D(1,0)) &&
+                   !image0_->isInside(vigra::Diff2D(0,1)) &&
+                   !image0_->isInside(vigra::Diff2D(1,1)) &&
+                   !image0_->isInside(vigra::Diff2D(1,-1)) &&
+                   !image0_->isInside(vigra::Diff2D(-1,1)) &&
+                   !image0_->isInside(vigra::Diff2D(0,0));
+        
+        should(ergebnis);
+    }
+    
+    /** testet den operator[](Diff2D)
+    */
+    void testOperatorIndex2D()
+    {
+        typename Image::ScanOrderIterator k = image1_->begin();
+        for ( int y = 0 ; y < 5 ; y++)
+            for (int x = 0; x < 3; x++, k++)
+                should((*image1_)[Diff2D(x,y)] == *k);
+    }
+    
+    /** test der Funktion "PixelType const& operator[] (Diff2D const &d) const"
+    */
+    void testOperatorIndex2DConst()
+    {
+        std::auto_ptr<Image> const & cimage = image1_;
+        typename Image::ScanOrderIterator k = cimage->begin();
+        for ( int y = 0 ; y < 5 ; y++)
+            for (int x = 0; x < 3; x++, k++)
+                should((*cimage)[Diff2D(x,y)] == *k);
+    }
+    
+    /** testet den operator(int x, int y).
+    */
+    void testOperatorFunctionCallInt()
+    {
+        for ( int y = 0 ; y < 5 ; y++)
+            for (int x = 0; x < 3; x++)
+                should((*image1_)(x,y) == (*image1_)[Diff2D(x,y)]);
+    }
+    
+    /** testet den const operator()(int x, int y) const.
+    */   
+    void testOperatorFunctionCallIntConst()
+    {
+        std::auto_ptr<Image> const & cimage = image1_;
+        for ( int y = 0 ; y < 5 ; y++)
+            for (int x = 0; x < 3; x++)
+                should((*cimage)(x,y) == (*cimage)[Diff2D(x,y)]);
+    }
+    
+    /** testet den operator[](int dy)
+    */
+    void testOperatorDoubleIndex()
+    {
+        for ( int x = 0 ; x < 3 ; x++)
+            for (int y = 0; y < 5; y++)
+                should((*image1_)[y][x] == (*image1_)(x,y));
+    }
+    
+    /** testet den const operator[](int dy) 
+    */
+    void testOperatorDoubleIndexConst()
+    {
+        std::auto_ptr<Image> const & cimage = image1_;
+        for ( int x = 0 ; x < 3 ; x++)
+            for (int y = 0; y < 5; y++)
+                should((*cimage)[y][x] == (*image1_)(x,y));
+    }
+    
+    /** testet die upperLeft() - Funktion der zu testenden Imageklasse
+    */
+    void testUpperLeft()
+    {
+        /*
+        * upperLeft liefert einen Iterator zurueck, um den Iterator 
+        * auf Richtigkeit zu ueberpruefen entreferenziere ich ihn, er soll
+        * dann eine !!!!SomePixelType!!!! zuruekgeben und das sollte derselbe Typ und value
+        * sein wie bei Index2d(0,0) vom anderen Image. 
+        * Eigentlich werden PixelTypes vergliechen, Da der Iterator keine
+        * Vergleichsmoeglichkeiten bietet
+        */
+        should((image1_->upperLeft())[2][1] == (*image1_)(1, 2));
+        should(*(image1_->upperLeft() + image1_->size() - Diff2D(1, 1)) == (*image1_)(2, 4));
+        should(image1_->upperLeft()[Diff2D(2,3)] == (*image1_)[Diff2D(2,3)]);
+
+        (*image1_->upperLeft()) = data[3];
+        should((*image1_->upperLeft()) == static_cast<typename Policy::PixelType>(data[3]));
+    }
+
+    void testLowerRight()
+    {
+        should(*(image1_->lowerRight() - Diff2D(1,1)) == (*image1_)(image1_->width() - 1 , image1_->height() - 1));   
+        should(*(image1_->lowerRight() - Diff2D(3, 5)) == *(image1_->upperLeft()));
+    }
+    
+    void testConstUpperLeft()
+    {
+        Image const * cimage = image1_.get();
+        should(*(cimage->upperLeft()) == (*cimage)[Diff2D(0,0)]);
+        should(cimage->upperLeft()[2][1] == (*cimage)(1, 2));
+        should(*(cimage->upperLeft() + Diff2D(2, 4)) == (*cimage)(2, 4));
+        should(cimage->upperLeft()[Diff2D(2,3)] == (*cimage)[Diff2D(2,3)]);       
+    }
+    
+    void testConstLowerRight()
+    {
+        Image const * cimage = image1_.get();
+        should(*(cimage->lowerRight() - Diff2D(1,1)) == (*cimage)(image1_->width() - 1 , image1_->height() - 1));         
+        should(*(cimage->lowerRight() - Diff2D(3, 5)) == *(cimage->upperLeft()));
+    }    
+        
+    void  testBegin()
+    { 
+        should(*image1_->begin() == *image1_->upperLeft());
+
+        //An dieser Stelle sollte begin()++ angesetzt werden funktioniert leider nicht (nur in BasicImage)                 //TO DO
+        should(*(image1_->begin() + 1) == (*image1_)[Diff2D(1,0)]);
+        should(*(image1_->begin() + image1_->width()) == (*image1_)[Diff2D(0,1)]);
+        should(*(image1_->begin() + ((image1_->width()*(image1_->height()) - 1))) == (*image1_)[Diff2D(2,4)]);
+    }
+
+    void testEnd()
+    {       
+        should(*(image1_->end() - 1) == (*image1_)(image1_->width() - 1 , image1_->height() - 1));
+        should(*(image1_->end() -(image1_->width()*image1_->height())) == (*image1_)(0, 0));    
+    }
+
+    void  testConstBegin()
+    {           
+        Image const * cimage = image1_.get();
+        should(*cimage->begin() == *cimage->upperLeft());
+        should(*(cimage->begin() + 1) == (*cimage)[Diff2D(1,0)]);
+        should(*(cimage->begin() + image1_->width()) == (*cimage)[Diff2D(3,0)]);
+        should(*(cimage->begin() + ((image1_->width()*image1_->height()) - 1)) == (*cimage)[Diff2D(2,4)]);
+    }
+
+    void testConstEnd()
+    {           
+        Image const * cimage = image1_.get();
+        should(*(cimage->end() - 1) == (*cimage)(image1_->width() - 1 , image1_->height() - 1));   
+        should(*(cimage->end() -(image1_->width()*image1_->height())) == (*cimage)(0, 0));    
+    }
+    
+    /** Testet den Accessor
+    */   
+    void testAccessor()
+    {
+        typename Image::Accessor acc = image1_->accessor();
+        
+        traverserIter1_ = image1_->upperLeft();
+        should(acc(traverserIter1_) == acc1_(traverserIter1_));
+        acc.set(data[6],traverserIter1_);
+        should(acc(traverserIter1_) == static_cast<typename Policy::PixelType>(data[6]));
+    } 
+    
+    /** Testet den konstanten Accessor
+    */
+    void testAccessorConst()
+    {
+        image1_->init(data[5]);
+        Image const * cimage = image1_.get();                                           //get ist eine Funktion des std::auto_ptr<...>
+        typename Image::ConstAccessor acc = cimage->accessor();
+        typename Image::ConstIterator i = cimage->upperLeft();
+        should(acc(i) == static_cast<typename Policy::PixelType>(data[5]));
+    }
+    
+    /** Testet richtige Funktionsweise aller Iteratoren und Zugriffsmoeglichkeiten (Accessor, Diff2D usw.) auf 
+    * ein Pixel des Bildes
+    */
+    void testAllAccessAndSetMethods()
+    {
+        scanOrderIter1_ = image1_->begin();
+        traverserIter1_ = image1_->upperLeft();
+        rowIter1_ = traverserIter1_.rowIterator();
+        
+        for(int i = 0; i < 5; i++)
+        {
+            for (int j = 0; j < 3; j++)
+            {   
+                should ((*image1_)(j,i) == (*image1_)[vigra::Diff2D(j,i)]);
+                should ((*image1_)(j,i) == (*image1_)[i][j]);
+                should ((*image1_)(j,i) == *scanOrderIter1_ );                            
+                should ((*image1_)(j,i) == *traverserIter1_ ); 
+                should ((*image1_)(j,i) == *rowIter1_ ); 
+                
+                (*image1_)(j,i) = data[7];
+                should ((*image1_)(j,i) == static_cast<typename Policy::PixelType>(data[7]));
+             
+                should ((*image1_)(j,i) == (*image1_)[vigra::Diff2D(j,i)]);
+                should ((*image1_)(j,i) == (*image1_)[i][j]);
+                should ((*image1_)(j,i) == acc1_(scanOrderIter1_ ));
+                should ((*image1_)(j,i) == acc1_(traverserIter1_ ));
+                should ((*image1_)(j,i) == acc1_(rowIter1_));
+                
+                (*image1_)[Diff2D(j,i)] = data[8];
+                should ((*image1_)(j,i) == static_cast<typename Policy::PixelType>(data[8]));
+                  
+                should ((*image1_)(j,i) == acc1_(scanOrderIter1_));
+                should ((*image1_)(j,i) == acc1_(rowIter1_));
+                should ((*image1_)(j,i) == acc1_(traverserIter1_));
+                
+                (*image1_)[i][j] = data[9];
+                should ((*image1_)(j,i) == static_cast<typename Policy::PixelType>(data[9]));
+                
+                should ((*image1_)(j,i) == (*image1_)[vigra::Diff2D(j,i)]);
+                should ((*image1_)(j,i) == (*image1_)[i][j]);
+                should((*image1_)(j,i) == acc1_(scanOrderIter1_));                        
+                should((*image1_)(j,i) == acc1_(traverserIter1_));
+                should((*image1_)(j,i) == acc1_(rowIter1_));
+                
+                *traverserIter1_ = data[10];
+                should((*image1_)(j,i) == static_cast<typename Policy::PixelType>(data[10]));
+                
+                traverserIter1_[Diff2D(0,0)] = data[11];
+                should((*image1_)(j,i) == static_cast<typename Policy::PixelType>(data[11]));
+                
+                acc1_.set(data[12], traverserIter1_);
+                should((*image1_)(j,i) == static_cast<typename Policy::PixelType>(data[12]));
+                
+                acc1_.set(data[13], traverserIter1_, Diff2D(0,0));
+                should((*image1_)(j,i) == static_cast<typename Policy::PixelType>(data[13]));
+                 
+                *rowIter1_ = data[10];
+                should((*image1_)(j,i) == static_cast<typename Policy::PixelType>(data[10]));
+                
+                rowIter1_[0] = data[0];
+                should((*image1_)(j,i) == static_cast<typename Policy::PixelType>(data[0]));
+                
+                acc1_.set(data[1], rowIter1_);
+                should((*image1_)(j,i) == static_cast<typename Policy::PixelType>(data[1]));
+                
+                acc1_.set(data[2], rowIter1_, 0);
+                should((*image1_)(j,i) == static_cast<typename Policy::PixelType>(data[2]));
+
+                scanOrderIter1_++;
+                traverserIter1_.x++;
+                rowIter1_++;
+            }
+            traverserIter1_.x = image1_->upperLeft().x;
+            traverserIter1_.y++;
+            rowIter1_ = traverserIter1_.rowIterator();
+        }
+        
+        /** tests columnIterator */
+        traverserIter1_ = image1_->upperLeft();
+        columnIter1_ = traverserIter1_.columnIterator();
+        for(int i = 0; i < 3; i++)  
+        {
+            for (int j = 0; j < 5; j++)
+            {
+                should((*image1_)(i,j) == acc1_(columnIter1_));
+                acc1_.set(data[3], columnIter1_);
+                should((*image1_)(i,j) == acc1_(columnIter1_));
+                columnIter1_++;
+                traverserIter1_.y++;
+            
+            }
+            traverserIter1_.y = image1_->upperLeft().y;
+            traverserIter1_.x++;
+            columnIter1_ = traverserIter1_.columnIterator();
+        }         
+    } 
+       
+};// end of class ImageTest
+
+template <class POLICY>
+struct ImageTestSuite
+: public vigra::test_suite
+{
+    ImageTestSuite(const char * to_test_Image_name)
+    : vigra::test_suite(to_test_Image_name)
+    {
+        add( testCase( &ImageTest<POLICY>::testImageDefaultConstuctor));
+        add( testCase( &ImageTest<POLICY>::testImageIntConstuctor));
+        add( testCase( &ImageTest<POLICY>::testImage2DConstuctor));
+        add( testCase( &ImageTest<POLICY>::testImageIntPixelConstuctor));
+        add( testCase( &ImageTest<POLICY>::testCopyConstructor));
+        add( testCase( &ImageTest<POLICY>::testOperatorAssignmentImage));
+        add( testCase( &ImageTest<POLICY>::testInit));
+        add( testCase( &ImageTest<POLICY>::testWidth));
+        add( testCase( &ImageTest<POLICY>::testHeight));
+        add( testCase( &ImageTest<POLICY>::testSize)); 
+        add( testCase( &ImageTest<POLICY>::testIsInside));
+        add( testCase( &ImageTest<POLICY>::testOperatorIndex2D));
+        add( testCase( &ImageTest<POLICY>::testOperatorIndex2DConst));
+        add( testCase( &ImageTest<POLICY>::testOperatorFunctionCallInt));
+        add( testCase( &ImageTest<POLICY>::testOperatorFunctionCallIntConst));
+        add( testCase( &ImageTest<POLICY>::testUpperLeft));
+        add( testCase( &ImageTest<POLICY>::testLowerRight));
+        add( testCase( &ImageTest<POLICY>::testConstUpperLeft));
+        add( testCase( &ImageTest<POLICY>::testConstLowerRight));
+        add( testCase( &ImageTest<POLICY>::testBegin));
+        add( testCase( &ImageTest<POLICY>::testEnd));
+        add( testCase( &ImageTest<POLICY>::testConstBegin));
+        add( testCase( &ImageTest<POLICY>::testConstEnd));
+        add( testCase( &ImageTest<POLICY>::testOperatorDoubleIndex));
+        add( testCase( &ImageTest<POLICY>::testOperatorDoubleIndexConst));
+        add( testCase( &ImageTest<POLICY>::testAccessor));
+        add( testCase( &ImageTest<POLICY>::testAccessorConst));
+        add( testCase( &ImageTest<POLICY>::testAllAccessAndSetMethods));
+    }
+};//end of struct TImageTestSuite
+#endif // PARENT_TEST_CLASS_HXX
diff --git a/test/imagehierarchy/rgb_basic_image_test.hxx b/test/imagehierarchy/rgb_basic_image_test.hxx
new file mode 100644
index 0000000..78f9ca7
--- /dev/null
+++ b/test/imagehierarchy/rgb_basic_image_test.hxx
@@ -0,0 +1,56 @@
+#ifndef RGB_BASIC_IMAGE_TEST_HXX
+#define RGB_BASIC_IMAGE_TEST_HXX
+
+#include "basic_image_test.hxx"
+
+template<class Policy>
+class RGBBasicImageTest
+: public BasicImageTest<Policy>
+{
+public:
+    typedef typename Policy::Image Image;
+    typedef typename BasicImageTest<Policy>::ChildImage ChildImage;
+    typedef typename Policy::value_type value_type;
+    typename Policy::data_array_type data;
+
+    RGBBasicImageTest()
+    : data(Policy::getData())
+    {}
+
+    void testRed()
+    {
+        std::auto_ptr<Image> image(Policy::factory(2,3, data[0]));
+        should((*image)(1,1)[0] == data[0].red());
+        should((*image)[Diff2D(1,2)][0] == data[0].red());
+    }    
+    void testGreen()
+    {
+        std::auto_ptr<Image> image(Policy::factory(2,3, data[3]));
+        should((*image)(1,1)[1] == data[3].green());
+        should((*image)[Diff2D(1,2)][1] == data[3].green());
+    }    
+    void testBlue()
+    {
+        std::auto_ptr<Image> image(Policy::factory(2,3, data[5]));
+        should((*image)(1,1)[2] == data[5].blue());
+        should((*image)[Diff2D(1,2)][2] == data[5].blue());
+    } 
+};
+
+
+template<class Policy>
+class RGBBasicImgTestSuite
+: public BasicImageTestSuite<Policy>
+{
+public:
+    // den Unterschied von RGBBasicImgTestSuite und RGBBasicImageTestSuite beachten
+    RGBBasicImgTestSuite(const char * to_test_Image_name)
+    : BasicImageTestSuite<Policy> (to_test_Image_name)
+    {
+        add ( testCase( &RGBBasicImageTest<Policy>::testRed));
+        add ( testCase( &RGBBasicImageTest<Policy>::testGreen));
+        add ( testCase( &RGBBasicImageTest<Policy>::testBlue));
+    }
+};
+
+#endif // RGB_BASIC_IMAGE_TEST_HXX
diff --git a/test/imagehierarchy/rgb_basic_image_test_suite.cxx b/test/imagehierarchy/rgb_basic_image_test_suite.cxx
new file mode 100644
index 0000000..3f430e2
--- /dev/null
+++ b/test/imagehierarchy/rgb_basic_image_test_suite.cxx
@@ -0,0 +1,22 @@
+#include "g++_relops_workaround.hxx"
+
+#include "rgb_images_policy.hxx"
+#include "rgb_basic_image_test.hxx"
+
+RGBBasicImageTestSuite::RGBBasicImageTestSuite()
+    : test_suite("RGBBasicImageTestSuite")
+    {
+        // den Unterschied zwischen RGBBasicImageTestSuite und RGBBasicImgTestSuite beachten !!!!
+        add ( new RGBBasicImgTestSuite<RGBImagePolicy<vigra::IRGBImage> > ("vigra::IRGBImage"));
+        add ( new RGBBasicImgTestSuite<RGBImagePolicy<vigra::FRGBImage> > ("vigra::FRGBImage"));
+        add ( new RGBBasicImgTestSuite<RGBImagePolicy<vigra::DRGBImage> > ("vigra::DRGBImage"));
+        add ( new RGBBasicImgTestSuite<RGBImagePolicy<vigra::BRGBImage> > ("vigra::BRGBImage"));
+    }
+
+// int main()
+// {
+//     RGBBasicImageTestSuite suite;
+//     int failed = suite.run();
+//     std::cout << suite.report() << std::endl;
+//     return (failed != 0);
+// }
diff --git a/test/imagehierarchy/rgb_imagehierarchy_test.hxx b/test/imagehierarchy/rgb_imagehierarchy_test.hxx
new file mode 100644
index 0000000..e104bcd
--- /dev/null
+++ b/test/imagehierarchy/rgb_imagehierarchy_test.hxx
@@ -0,0 +1,54 @@
+#ifndef RGB_IMAGEHIERARCHY_TEST_HXX
+#define RGB_IMAGEHIERARCHY_TEST_HXX
+
+#include "imagehierarchy_test.hxx"
+
+template<class Policy>
+class RGBImageHierarchyTest
+: public ImageHierarchyTest<Policy>
+{
+public:
+    typedef typename Policy::Image Image;
+    typedef typename ImageHierarchyTest<Policy>::ChildImage ChildImage;
+    typedef typename Policy::value_type value_type;
+    typename Policy::data_array_type data;
+
+    RGBImageHierarchyTest()
+    : data(Policy::getData())
+    {}
+
+    void testRed()
+    {
+        std::auto_ptr<Image> image(Policy::factory(2,3, data[0]));
+        should((*image)(1,1)[0] == data[0].red());
+        should((*image)[Diff2D(1,2)][0] == data[0].red());
+    }    
+    void testGreen()
+    {
+        std::auto_ptr<Image> image(Policy::factory(2,3, data[3]));
+        should((*image)(1,1)[1] == data[3].green());
+        should((*image)[Diff2D(1,2)][1] == data[3].green());
+    }    
+    void testBlue()
+    {
+        std::auto_ptr<Image> image(Policy::factory(2,3, data[5]));
+        should((*image)(1,1)[2] == data[5].blue());
+        should((*image)[Diff2D(1,2)][2] == data[5].blue());
+    } 
+};
+
+template<class Policy>
+class RGBImgHierarchyTestSuite
+: public ImageHierarchyTestSuite<Policy>
+{
+public:
+    // den Unterschied von RGBImgHierarchyTestSuite und RGBImageHierarchyTestSuite beachten
+    RGBImgHierarchyTestSuite(const char * to_test_Image_name)
+    : ImageHierarchyTestSuite<Policy> (to_test_Image_name)
+    {
+        add ( testCase( &RGBImageHierarchyTest<Policy>::testRed));
+        add ( testCase( &RGBImageHierarchyTest<Policy>::testGreen));
+        add ( testCase( &RGBImageHierarchyTest<Policy>::testBlue));
+    }
+};
+#endif // RGB_IMAGEHIERARCHY_TEST_HXX
diff --git a/test/imagehierarchy/rgb_imagehierarchy_test_suite.cxx b/test/imagehierarchy/rgb_imagehierarchy_test_suite.cxx
new file mode 100644
index 0000000..14a2e4e
--- /dev/null
+++ b/test/imagehierarchy/rgb_imagehierarchy_test_suite.cxx
@@ -0,0 +1,20 @@
+#include "g++_relops_workaround.hxx"
+
+
+#include "rgb_images_policy.hxx"
+#include "rgb_imagehierarchy_test.hxx"
+
+RGBImageHierarchyTestSuite::RGBImageHierarchyTestSuite()
+    : test_suite("RGBImageHierarchyTestSuite")
+    {
+        // den Unterschied zwischen RGBImageHierarchyTestSuite und RGBImgHierarchyTestSuite beachten !!!!
+        add ( new RGBImgHierarchyTestSuite<RGBImagePolicy<vigra::RGBImage> > ("vigra::RGBImage"));
+    }
+
+// int main()
+// {
+//     RGBImageHierarchyTestSuite suite;
+//     int failed = suite.run();
+//     std::cout << suite.report() << std::endl;
+//     return (failed != 0);
+// }
diff --git a/test/imagehierarchy/rgb_images_policy.hxx b/test/imagehierarchy/rgb_images_policy.hxx
new file mode 100644
index 0000000..9932c52
--- /dev/null
+++ b/test/imagehierarchy/rgb_images_policy.hxx
@@ -0,0 +1,58 @@
+#ifndef RGB__IMAGES_POLICY_HXX
+#define RGB__IMAGES_POLICY_HXX
+
+#include "test_policy_parent.hxx"
+#include <unittest.hxx>
+
+// bei dem template handelt es sich um ein RGBImage
+template<class ImageP>                                                  
+class RGBImagePolicy
+: public TestPolicy<ImageP> 
+{
+
+public:
+    typedef ImageP Image;
+    typedef ImageP ChildImage;
+    typedef typename ImageP::PixelType PixelType;
+    typedef typename Image::value_type value_type;  
+    typedef typename Image::value_type child_value_type;  
+    typedef std::vector<value_type> data_array_type;
+    typedef std::vector<value_type> child_data_array_type;
+    typedef typename value_type::value_type type;
+    
+    static data_array_type getData()
+    {
+        static type variable = 1;
+        variable = variable/100 + variable*5/1000 + variable;
+        
+        static value_type data[15];
+        
+        for(int i = 0; i <= 14 ; i ++)
+        {
+            data[i] = value_type((i+variable), (2*i), (2*i + variable));
+        }
+        
+        static data_array_type data_vector(data, data+sizeof(data)/sizeof(value_type));
+        return data_vector;
+    }
+    
+    static child_data_array_type getChildData()
+    {   
+        return getData();
+    }
+};
+
+struct RGBBasicImageTestSuite
+: public vigra::test_suite
+{
+    RGBBasicImageTestSuite();
+};
+
+
+struct RGBImageHierarchyTestSuite
+: public vigra::test_suite
+{
+    RGBImageHierarchyTestSuite();
+};
+
+#endif // RGB__IMAGES_POLICY_HXX
diff --git a/test/imagehierarchy/select_band_image_policy.hxx b/test/imagehierarchy/select_band_image_policy.hxx
new file mode 100644
index 0000000..ca2f7a1
--- /dev/null
+++ b/test/imagehierarchy/select_band_image_policy.hxx
@@ -0,0 +1,84 @@
+#ifndef SELECT_BAND_IMAGE_POLICY_HXX
+#define SELECT_BAND_IMAGE_POLICY_HXX
+
+#include "vigra/imagehierarchy.hxx"
+#include <unittest.hxx>
+
+template <class MULTI_BAND_IMAGE_POLICY, int TO_SELECT_BAND>
+class SelectBandImagePolicy
+{
+public:
+    typedef vigra::SelectBandImage                          Image;                  // entspricht SelectBandImage
+    typedef typename MULTI_BAND_IMAGE_POLICY::ChildImage    ChildImage;             // --||-- einer MultiBandKlasse, deren Obiekt an den Konstruktor der SelectBandImage Klasse uebergeben wurde 
+    typedef vigra::SelectBandImage::PixelType               PixelType;              // --||-- GrayValue (float)
+    typedef vigra::SelectBandImage::value_type              value_type;             // --||-- GrayValue (float)
+    typedef typename ChildImage::value_type                 child_value_type;       // --||-- VectorProxy oder RGBValue, die beiden sind letzendlich TinyVektoren 
+    typedef std::vector<value_type>                         data_array_type;        // Vektor von GrayValues (float)
+    typedef std::vector<child_value_type>                   child_data_array_type;  // Vektor von VectorProxy oder RGBValue, die beiden sind letzendlich TinyVektoren
+    
+    static const int n = TO_SELECT_BAND;                                            // der Band der selektiert werden muss
+
+    static data_array_type getData()
+    {
+        
+        static value_type variable = 1;
+        variable = variable/100 + (variable*5)/1000 + variable;
+        static value_type data[15];
+        for(int i = 0; i<=14; i++)
+        {
+            data[i] = variable + i;
+        }
+        static data_array_type data_vector(data, data+sizeof(data)/sizeof(value_type));
+        return data_vector;
+    }
+    
+    static child_data_array_type getChildData()
+    {        
+        return MULTI_BAND_IMAGE_POLICY::getChildData();
+    }
+    
+    static Image * factory()
+    {
+        return new Image(ChildImage(), TO_SELECT_BAND);
+    }
+    
+    static Image * factory(int x, int y)
+    {
+        return new Image(ChildImage(x,y), TO_SELECT_BAND);
+    }     
+    
+    static Image * factory(vigra::Diff2D size)
+    {
+        return new Image(ChildImage(size), TO_SELECT_BAND);
+    }
+
+    static Image * factory(int x, int y, child_value_type pixel)
+    {
+        return new Image(ChildImage(x, y, pixel), TO_SELECT_BAND);
+    }
+    
+    static Image * factory(Image image)
+    {
+        return new Image(image);
+    }
+    
+    static Image * factory(ChildImage image)
+    {
+        return new Image(ChildImage (image), TO_SELECT_BAND);
+    }
+    
+    static Image * factory(typename ChildImage::InnerImage image)
+    {
+        return new Image(ChildImage(image), TO_SELECT_BAND);
+    }
+};
+
+struct SelectImagesTestSuite
+: public vigra::test_suite
+{
+    SelectImagesTestSuite();
+};
+
+
+
+#endif // SELECT_BAND_IMAGE_POLICY_HXX
diff --git a/test/imagehierarchy/select_band_image_test_suite.cxx b/test/imagehierarchy/select_band_image_test_suite.cxx
new file mode 100644
index 0000000..34da15f
--- /dev/null
+++ b/test/imagehierarchy/select_band_image_test_suite.cxx
@@ -0,0 +1,41 @@
+#include "g++_relops_workaround.hxx"
+
+#include "select_band_image_policy.hxx" 
+#include "select_image_test.hxx"
+#include "vector_2_image_policy.hxx" 
+// #include "vector_3_image_policy.hxx" 
+// #include "vector_4_image_policy.hxx" 
+#include "rgb_images_policy.hxx" 
+// #include "select_image_test.hxx" 
+#include <unittest.hxx> 
+
+/* Vorsicht !!! in select_image_test.hxx gibt's SelectBandImageTestSuite. Den Unterschied beachten!!!
+*/
+SelectImagesTestSuite::SelectImagesTestSuite()
+    : vigra::test_suite("SelectBandImageTestSuite")
+    {
+        add(new SelectBandImageTestSuite<SelectBandImagePolicy<Vector2ImagePolicy<vigra::Vector2Image>, 0> > ("SelectBandImage an vigra::Vector2Image, selected band is 0"));
+//         add(new SelectBandImageTestSuite<SelectBandImagePolicy<Vector2ImagePolicy<vigra::Vector2Image>, 1> >("SelectBandImage an vigra::Vector2Image, selected band is 1"));
+//         add(new SelectBandImageTestSuite<SelectBandImagePolicy<Vector3ImagePolicy<vigra::Vector3Image>, 0> >("SelectBandImage an vigra::Vector3Image, selected band is 0"));
+//         add(new SelectBandImageTestSuite<SelectBandImagePolicy<Vector3ImagePolicy<vigra::Vector3Image>, 1> >("SelectBandImage an vigra::Vector3Image, selected band is 1"));
+//         add(new SelectBandImageTestSuite<SelectBandImagePolicy<Vector3ImagePolicy<vigra::Vector3Image>, 2> >("SelectBandImage an vigra::Vector3Image, selected band is 2"));
+//         add(new SelectBandImageTestSuite<SelectBandImagePolicy<Vector4ImagePolicy<vigra::Vector4Image>, 0> >("SelectBandImage an vigra::Vector4Image, selected band is 0"));
+//         add(new SelectBandImageTestSuite<SelectBandImagePolicy<Vector4ImagePolicy<vigra::Vector4Image>, 1> >("SelectBandImage an vigra::Vector4Image, selected band is 1"));
+//         add(new SelectBandImageTestSuite<SelectBandImagePolicy<Vector4ImagePolicy<vigra::Vector4Image>, 2> >("SelectBandImage an vigra::Vector4Image, selected band is 2"));
+//         add(new SelectBandImageTestSuite<SelectBandImagePolicy<Vector4ImagePolicy<vigra::Vector4Image>, 3> >("SelectBandImage an vigra::Vector4Image, selected band is 3"));
+//         add(new SelectBandImageTestSuite<SelectBandImagePolicy<RGBImagePolicy<vigra::RGBImage>, 0> >("SelectBandImage an vigra::RGBImage, selected band is 0"));
+//         add(new SelectBandImageTestSuite<SelectBandImagePolicy<RGBImagePolicy<vigra::RGBImage>, 1> >("SelectBandImage an vigra::RGBImage, selected band is 1"));
+        add(new SelectBandImageTestSuite<SelectBandImagePolicy<RGBImagePolicy<vigra::RGBImage>, 2> >("SelectBandImage an vigra::RGBImage, selected band is 2"));
+    }
+
+// int main()
+// {
+//  
+//     SelectImagesTestSuite itest;
+// 
+//     int failed = itest.run();
+// 
+//     std::cout << itest.report() << std::endl;
+//     
+//     return (failed != 0);
+// }  
diff --git a/test/imagehierarchy/select_image_test.hxx b/test/imagehierarchy/select_image_test.hxx
new file mode 100644
index 0000000..c2df9f0
--- /dev/null
+++ b/test/imagehierarchy/select_image_test.hxx
@@ -0,0 +1,209 @@
+#ifndef SELECT_IMAGE_TEST_HXX
+#define SELECT_IMAGE_TEST_HXX
+
+#include "imagehierarchy_test.hxx"
+
+template<class Policy>
+class SelectBandImageTest
+: public ImageHierarchyTest<Policy>
+{
+public:
+    typedef typename Policy::Image              Image;              // zu testende Klasse z.B. GrayImage, VariableBandsImage usw.
+    typedef typename Policy::ChildImage         ChildImage;         // unterscheidet sich von zu testender Klasse Image, nur wenn einer der abstrakten Klassen VariableBandImage oder SingleBandImage oder die Klasse SelectBandImage getestet wird, sonst entspricht es der Klasse Image.  
+    typedef typename Policy::value_type         value_type;         // value_type der zu testenden Klasse
+    typedef typename Policy::child_value_type   child_value_type;   // value_type der Klasse an der die zu testende Klasse getestet wird, also z.B. VariableBandsImage wird am Beispiel von Vector2Image getestet dann ist child_value_type die value_type von Vector2Image
+    
+    /**  Testet den "(WIDTH, HEIGHT, PIXELTYPE)"-Konstruktor der zu testenden Imageklasse
+    */
+    void testImageIntPixelConstuctor()
+    {
+        std::auto_ptr<Image> image1(Policy::factory(2,3, child_data[0]));
+        should(image1->height() == 3);
+        should(image1->width() == 2);
+        should(image1->size() == vigra::Diff2D(2,3));
+    
+        // Bei SelectBandImage wird nur der selektierte Band mit dem Pixel child_data[0] initialisiert   
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), child_data[0][Policy::n])));
+        
+        std::auto_ptr<Image> image2(Policy::factory(0, 0, child_data[1]));
+        should(image2->height() == 0);
+        should(image2->width() == 0);
+        should(image2->size() == vigra::Diff2D(0,0));
+    
+        // Bei SelectBandImage wird nur der selektierte Band mit dem Pixel child_data[1] initialisiert   
+        should(image2->end() == std::find_if(image2->begin(), image2->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), child_data[1][Policy::n])));
+    }
+    
+    /** Testet den Copy Konstruktor ( Image(Image img) ).
+    */
+    void testCopyConstructor()
+    {
+        std::auto_ptr<Image> image1_copy(Policy::factory(*image1_));
+        std::auto_ptr<Image> image1 = image1_;
+
+        std::auto_ptr<Image> image0_copy(Policy::factory(*image0_));
+
+        should(image1_copy->height() == 5);
+        should(image1_copy->width() == 3);
+        should(image1_copy->size() == vigra::Diff2D(3,5));
+        should(equalPixels(image1->begin(),image1->end(), image1_copy->begin()));
+        should(image0_copy->height() == 0);
+        should(image0_copy->width() == 0);
+        should(image0_copy->size() == vigra::Diff2D(0,0));
+        should(equalPixels(image0_->begin(), image0_->end(), image0_copy->begin()));
+     }
+    
+    /** testet die Konstruktorden der imagehierarchy Klasse, an die die InnerImage (BasicImage<float>)
+    * uebergeben wird, also Image (InnerImage i)
+    */
+    void testInnerImageConstructor()
+    {
+        std::auto_ptr<Image> image1(Policy::factory(new typename ChildImage::InnerImage(3, 4, child_data[0]))); 
+        should(image1->height() == 4);
+        should(image1->width() == 3);
+        should(image1->size() == vigra::Diff2D(3,4));
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), child_data[0][Policy::n])));
+
+        std::auto_ptr<Image> image2(Policy::factory(new typename ChildImage::InnerImage(0, 0, child_data[1])));
+        should(image2->height() == 0);
+        should(image2->width() == 0);
+        should(image2->size() == vigra::Diff2D(0,0));
+        should(image2->end() == std::find_if(image2->begin(), image2->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), child_data[1][Policy::n])));
+    }
+    
+    /** testet die clone() Methode der Klasse aus imagehierarchy
+    */
+    void testClone()
+    {
+        /*
+        *  Im Falle der Aenderungsvornehmungen an einem der Images, werden die Aenderungen auch nur an einem sichtbar
+        */
+        std::auto_ptr<typename Image::CloneType> image1(image1_->clone()); 
+        should(equal(*image1, *image1_));                                               
+        should(equalPixels(image1_->begin(),image1_->end(), image1->begin()));             
+        should(static_cast<vigra::SingleBandImage *> (&(*image1)) != static_cast<vigra::SingleBandImage *> (&(*image1_)));
+        
+        /* Aenderung mit der init-Funktion
+        */
+        image1->init(data[5]); 
+        should((*image1_->begin()) != static_cast<typename Image::PixelType> (data[5]));
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[5])));
+        
+        image1_->init(data[6]);
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[5])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[6])));
+        
+        std::auto_ptr<typename Image::CloneType> image0(image0_->clone());
+        should(equal(*image0, *image0_));
+        should(equalPixels(image0_->begin(),image0_->end(), image0->begin()));image1_->init(data[6]);
+        should(static_cast<vigra::SingleBandImage *> (&(*image0)) != static_cast<vigra::SingleBandImage *> (&(*image0_)));
+
+        /* Aenderung mit dem Zuweisungsoperator -> siehe in testShallowCopy()
+        */
+        (*image0_) = (*image1_);                              
+        should(image0->size() == vigra::Diff2D(0,0));
+        should(image0_->size() == vigra::Diff2D(3,5));
+        should(!equal(*image0, *image0_));
+        should(equal(*image1_, *image0_));
+    }
+
+    /** Testet die Methode actualBands(), die die Anzahl der Baender eines Bildes liefert 
+    */
+    void testActualBands()
+    {
+        should(image1_->bands() != image1_->actualBands());
+        int act_band = image1_->actualBands();
+        Policy::n == 0 ? image1_->setROI(1) : image1_->setROI(Policy::n - 1);
+        should(image1_->actualBands() != 1);
+        should(image1_->actualBands() == act_band);
+    }
+    
+    /** Testet die Methode bands(), die die Anzahl der selektirerten Baender eines Bildes liefert.
+    * Die Anzahl der selektirerten Baender ist bei allen Bildern gleich dem Anzahl der Baender des Bildes,
+    * die Ausnahme bildet SelectBandImage dort ist immer nur ein Band selektiert.
+    */
+    void testBands()
+    {
+        should(image1_->bands() != image1_->actualBands());
+        should(image1_->bands() == 1);
+        Policy::n == 0 ? image1_->setROI(1) : image1_->setROI(Policy::n - 1);
+        should(image1_->bands() == 1);
+    }
+    
+    /** Testet die setROI(int band) Methode der Klasse SelectBandImage. Die Methode aendert den 
+    * selektierten Band. 
+    */
+    void testSetROIBand()
+    {
+    should(image1_->getSelectedBand() == Policy::n);
+    image1_->setROI(Policy::n == 0 ? 1 : (Policy::n - 1));
+    should(image1_->getSelectedBand() != Policy::n);
+    should(image1_->getSelectedBand() == ((Policy::n == 0) ? 1 : (Policy::n - 1)));
+    testSetROI();
+    }
+
+    /** Testet die getSelectedBand() Methode der Klasse SelectBandImage. Die Methode liefert den 
+    * selektierten Band. 
+    */
+    void testGetSelectedBand()
+    {
+    should(image1_->getSelectedBand() == Policy::n);
+    image1_->setROI(Policy::n == 0 ? 1 : (Policy::n - 1));
+    should(image1_->getSelectedBand() != Policy::n);
+    should(image1_->getSelectedBand() == ((Policy::n == 0) ? 1 : (Policy::n - 1)));
+    }
+
+};
+
+template <class POLICY>
+struct SelectBandImageTestSuite
+: vigra::test_suite
+{ 
+    SelectBandImageTestSuite(const char * to_test_Image_name)
+    : vigra::test_suite(to_test_Image_name)
+    {
+        add( testCase( &ImageTest<POLICY>::testImageDefaultConstuctor));
+        add( testCase( &ImageTest<POLICY>::testImageIntConstuctor));
+        add( testCase( &ImageTest<POLICY>::testImage2DConstuctor));
+        add( testCase( &SelectBandImageTest<POLICY>::testImageIntPixelConstuctor));
+        add( testCase( &SelectBandImageTest<POLICY>::testCopyConstructor));
+        add( testCase( &ImageTest<POLICY>::testOperatorAssignmentImage));
+        add( testCase( &ImageTest<POLICY>::testInit));
+        add( testCase( &ImageTest<POLICY>::testWidth));
+        add( testCase( &ImageTest<POLICY>::testHeight));
+        add( testCase( &ImageTest<POLICY>::testSize)); 
+        add( testCase( &ImageTest<POLICY>::testIsInside));
+        add( testCase( &ImageTest<POLICY>::testOperatorIndex2D));
+        add( testCase( &ImageTest<POLICY>::testOperatorIndex2DConst));
+        add( testCase( &ImageTest<POLICY>::testOperatorFunctionCallInt));
+        add( testCase( &ImageTest<POLICY>::testOperatorFunctionCallIntConst));
+        add( testCase( &ImageTest<POLICY>::testUpperLeft));
+        add( testCase( &ImageTest<POLICY>::testLowerRight));
+        add( testCase( &ImageTest<POLICY>::testConstUpperLeft));
+        add( testCase( &ImageTest<POLICY>::testConstLowerRight));
+        add( testCase( &ImageTest<POLICY>::testBegin));
+        add( testCase( &ImageTest<POLICY>::testEnd));
+        add( testCase( &ImageTest<POLICY>::testConstBegin));
+        add( testCase( &ImageTest<POLICY>::testConstEnd));
+        add( testCase( &ImageTest<POLICY>::testOperatorDoubleIndex));
+        add( testCase( &ImageTest<POLICY>::testOperatorDoubleIndexConst));
+        add( testCase( &ImageTest<POLICY>::testAccessor));
+        add( testCase( &ImageTest<POLICY>::testAccessorConst));
+        add( testCase( &ImageTest<POLICY>::testAllAccessAndSetMethods));        
+        add( testCase( &SelectBandImageTest<POLICY>::testInnerImageConstructor));
+        add( testCase( &SelectBandImageTest<POLICY>::testClone));
+        add( testCase( &ImageHierarchyTest<POLICY>::testShallowCopy));
+        add( testCase( &ImageHierarchyTest<POLICY>::testSetROI));
+        add( testCase( &ImageHierarchyTest<POLICY>::testResetROI));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualSize));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualWidth));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualHeight));
+        add( testCase( &SelectBandImageTest<POLICY>::testActualBands));
+        add( testCase( &SelectBandImageTest<POLICY>::testBands));
+        add( testCase( &ImageHierarchyTest<POLICY>::testRoiUpperLeft));
+        add( testCase( &ImageHierarchyTest<POLICY>::testIsInsideROI));
+        add( testCase( &SelectBandImageTest<POLICY>::testSetROIBand));
+        add( testCase( &SelectBandImageTest<POLICY>::testGetSelectedBand));
+    }
+};//end of struct SelectBandImageTestSuite
+#endif // SELECT_IMAGE_TEST_HXX
diff --git a/test/imagehierarchy/single_band_image_policy.hxx b/test/imagehierarchy/single_band_image_policy.hxx
new file mode 100644
index 0000000..14115fb
--- /dev/null
+++ b/test/imagehierarchy/single_band_image_policy.hxx
@@ -0,0 +1,76 @@
+#ifndef SINGLE_BAND_IMAGE_POLICY_HXX
+#define SINGLE_BAND_IMAGE_POLICY_HXX
+
+#include "vigra/imagehierarchy.hxx"
+#include <unittest.hxx>
+
+template<class IMAGEPOLICY>                                 // Bei der IMAGEPOLICY handelt es sich bis jetzt nur um GrayImage, spaeter soll SelectBandImage folgen
+class SingleBandImagePolicy
+{
+
+/* Bei dem Image (in diesem Fall VariableBandsImage) handelt es sich um die zu testende Klasse
+*  dagegen ChildImage ist die abgeleitete Klasse von Image, z.B. GrayImage oder SelectBandImage.
+*  Die VariableBandsImage-Konstruktoren sind protected und somit nicht aufrufbar. Um dei Klasse zu testen,
+*  muessen wir die Konstruktoren der abgeleiteten Klassen benutzen. Somit werden alle zur Verfuegung
+*  stehende Funktionen getestet. 
+*  In der Testklasse werden die ChildImage Konstruktoren aufgerufen, aber an einem Objekt
+*  der Image Klasse (Polymorphie).
+*/
+
+public: 
+    typedef typename IMAGEPOLICY::Image             ChildImage;             // abgeleitete Klasse der ImageKlasse. Es kann sich hierbei um GrayImage oder SelectBandImage handeln                  
+    typedef vigra::SingleBandImage                  Image;                  // entspricht dem SingleBandImage
+    typedef vigra::SingleBandImage::PixelType       PixelType;              // --||-- GrayValue (float)
+    typedef typename ChildImage::value_type         value_type;             // --||-- GrayValue (float) 
+    typedef typename ChildImage::value_type         child_value_type;       // --||-- GrayValue (float)  
+    typedef std::vector<value_type>                 data_array_type;        // Vektor von GrayValues (float)
+    typedef std::vector<value_type>                 child_data_array_type;  // Vektor von GrayValues (float)
+    
+    static  data_array_type getData()
+    {
+        return IMAGEPOLICY::getData();
+    }
+    
+    static  child_data_array_type getChildData()
+    {
+        return IMAGEPOLICY::getChildData();
+    }
+    
+    static ChildImage * factory()
+    {
+        return new ChildImage();
+    }
+    
+    static ChildImage * factory(int x, int y)
+    {
+        return new ChildImage(x,y);
+    }     
+    
+    static ChildImage * factory(vigra::Diff2D size)
+    {
+        return new ChildImage(size);
+    }
+
+    static ChildImage * factory(int x, int y, value_type pixel)
+    {
+        return new ChildImage(x, y, pixel);
+    }
+    
+    static ChildImage * factory(ChildImage image)
+    {
+        return new ChildImage(image);
+    }
+    
+    static ChildImage * factory(typename ChildImage::InnerImage image)
+    {
+        return new ChildImage(image);
+    }
+};
+
+struct SingleImageTestSuite
+: public vigra::test_suite
+{
+    SingleImageTestSuite();
+};
+
+#endif // SINGLE_BAND_IMAGE_POLICY_HXX
diff --git a/test/imagehierarchy/single_band_image_test.hxx b/test/imagehierarchy/single_band_image_test.hxx
new file mode 100644
index 0000000..5002fde
--- /dev/null
+++ b/test/imagehierarchy/single_band_image_test.hxx
@@ -0,0 +1,133 @@
+#ifndef SINGLE_BAND_IMAGE_TEST_HXX
+#define SINGLE_BAND_IMAGE_TEST_HXX
+
+#include "imagehierarchy_test.hxx"
+
+template<class Policy>
+class SingleBandImageTest
+: public ImageHierarchyTest<Policy>
+{    
+public:
+    typedef typename Policy::Image              Image;              // zu testende Klasse z.B. GrayImage, SingleBandImage usw.
+    typedef typename Policy::ChildImage         ChildImage;         // unterscheidet sich von zu testender Klasse Image, nur wenn einer der abstrakten Klassen VariableBandImage oder SingleBandImage oder die Klasse SelectBandImage getestet wird, sonst entspricht es der Klasse Image.  
+    typedef typename Policy::value_type         value_type;         // value_type der zu testenden Klasse
+    typedef typename Policy::child_value_type   child_value_type;   // value_type der Klasse an der die zu testende Klasse getestet wird, also z.B. SingleBandImage wird am Beispiel von Vector2Image getestet dann ist child_value_type die value_type von Vector2Image
+    
+    /** testet die clone() Methode der Klasse aus imagehierarchy
+    */
+    void testClone()
+    {
+        /*
+        *  Im Falle der Aenderungsvornehmungen an einem der Images, werden die Aenderungen auch nur an einem sichtbar
+        */
+        std::auto_ptr<typename Image::CloneType> image1(image1_->clone()); 
+        should(equal(*image1, *image1_));                                               
+        should(equalPixels(image1_->begin(),image1_->end(), image1->begin()));             
+        should(&(*image1) != &(*image1_));                                              
+        
+        /* Aenderung mit der init-Funktion
+        */
+        image1->init(data[5]); 
+        should((*image1_->begin()) != static_cast<typename Image::PixelType> (data[5]));
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[5])));
+        
+        image1_->init(data[6]);
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[5])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[6])));
+        
+        std::auto_ptr<typename Image::CloneType> image0(image0_->clone());
+        should(equal(*image0, *image0_));
+        should(equalPixels(image0_->begin(),image0_->end(), image0->begin()));image1_->init(data[6]);
+        should(&(*image0) != &(*image0_));
+    }
+    
+    /** testet die shallowCopy() Methode der Klassen aus imagehierarchy.
+    */
+    void testShallowCopy()
+    {
+        /*
+        *  Im Falle der Aenderungsvornehmungen an einem der Images, werden die Aenderungen an beiden sichtbar
+        *  Es gibt nur zwei Aenderungsmoeglichkeiten init() und Zuweisung eines anderen Images
+        *  bei der Zuweisung werden die Zeiger von den eigenen Daten auf die anderen umgeleitet,
+        *  und das entspricht nicht dem Sinn der shallowCopy
+        */
+        std::auto_ptr<Image> image1(image1_->shallowCopy());
+        should(equal(*image1, *image1_));     
+        should(&(*image1) != &(*image1_));
+        
+        /* Aenderung mit der init-Funktion
+        */
+        image1->init(data[7]);
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[7])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[7])));
+        
+        image1->init(data[8]);
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[8])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[8])));
+        
+        /* Eine shallowCopy zeigt auf die selben Daten des kopierten Objektes
+        */
+        std::auto_ptr<Image> image1Copy(image1->shallowCopy());
+        should(equal(*image1Copy, *image1_));
+        should(&(*image1Copy) != &(*image1_));
+        
+        image1Copy->init(data[9]);
+        should(image1Copy->end() == std::find_if(image1Copy->begin(), image1Copy->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
+        
+        std::auto_ptr<Image> image0(image0_->shallowCopy());
+        should(equal(*image0, *image0_));
+        should(&(*image0) != &(*image0_));
+    }
+};
+
+template <class POLICY>
+struct SingleBandImageTestSuite
+: vigra::test_suite
+{
+    SingleBandImageTestSuite(const char * to_test_Image_name)
+    : vigra::test_suite(to_test_Image_name)
+    {
+        add( testCase( &ImageTest<POLICY>::testImageDefaultConstuctor));
+        add( testCase( &ImageTest<POLICY>::testImageIntConstuctor));
+        add( testCase( &ImageTest<POLICY>::testImage2DConstuctor));
+        add( testCase( &ImageTest<POLICY>::testImageIntPixelConstuctor));
+        add( testCase( &ImageTest<POLICY>::testCopyConstructor));
+        add( testCase( &ImageTest<POLICY>::testInit));
+        add( testCase( &ImageTest<POLICY>::testWidth));
+        add( testCase( &ImageTest<POLICY>::testHeight));
+        add( testCase( &ImageTest<POLICY>::testSize)); 
+        add( testCase( &ImageTest<POLICY>::testIsInside));
+        add( testCase( &ImageTest<POLICY>::testOperatorIndex2D));
+        add( testCase( &ImageTest<POLICY>::testOperatorIndex2DConst));
+        add( testCase( &ImageTest<POLICY>::testOperatorFunctionCallInt));
+        add( testCase( &ImageTest<POLICY>::testOperatorFunctionCallIntConst));
+        add( testCase( &ImageTest<POLICY>::testUpperLeft));
+        add( testCase( &ImageTest<POLICY>::testLowerRight));
+        add( testCase( &ImageTest<POLICY>::testConstUpperLeft));
+        add( testCase( &ImageTest<POLICY>::testConstLowerRight));
+        add( testCase( &ImageTest<POLICY>::testBegin));
+        add( testCase( &ImageTest<POLICY>::testEnd));
+        add( testCase( &ImageTest<POLICY>::testConstBegin));
+        add( testCase( &ImageTest<POLICY>::testConstEnd));
+        add( testCase( &ImageTest<POLICY>::testOperatorDoubleIndex));
+        add( testCase( &ImageTest<POLICY>::testOperatorDoubleIndexConst));
+        add( testCase( &ImageTest<POLICY>::testAccessor));
+        add( testCase( &ImageTest<POLICY>::testAccessorConst));
+        add( testCase( &ImageTest<POLICY>::testAllAccessAndSetMethods));        
+        add( testCase( &ImageHierarchyTest<POLICY>::testInnerImageConstructor));
+        add( testCase( &SingleBandImageTest<POLICY>::testClone));
+        add( testCase( &SingleBandImageTest<POLICY>::testShallowCopy));
+        add( testCase( &ImageHierarchyTest<POLICY>::testSetROI));
+        add( testCase( &ImageHierarchyTest<POLICY>::testResetROI));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualSize));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualWidth));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualHeight));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualBands));
+        add( testCase( &ImageHierarchyTest<POLICY>::testBands));
+        add( testCase( &ImageHierarchyTest<POLICY>::testRoiUpperLeft));
+        add( testCase( &ImageHierarchyTest<POLICY>::testIsInsideROI));
+    }
+};//end of struct SingleBandImageTestSuite
+#endif // SINGLE_BAND_IMAGE_TEST_HXX
diff --git a/test/imagehierarchy/single_band_image_test_suite.cxx b/test/imagehierarchy/single_band_image_test_suite.cxx
new file mode 100644
index 0000000..0f2dfc8
--- /dev/null
+++ b/test/imagehierarchy/single_band_image_test_suite.cxx
@@ -0,0 +1,26 @@
+#include "g++_relops_workaround.hxx"
+
+#include "single_band_image_policy.hxx" 
+#include "one_band_image_policy.hxx" 
+#include "single_band_image_test.hxx"
+#include <unittest.hxx> 
+
+/** Vorsicht !!! in select_image_test.hxx gibt's SingleBandImageTestSuite. Den Unterschied beachten!!!
+*/
+SingleImageTestSuite::SingleImageTestSuite()
+    : vigra::test_suite("SingleBandImageTestSuite")
+    {
+        add( new SingleBandImageTestSuite<SingleBandImagePolicy<OneBandImagePolicy<vigra::GrayImage> > > ("SingleBandImage an vigra::GrayImage"));
+    }
+
+// int main()
+// {
+//  
+//     SingleImageTestSuite itest;
+// 
+//     int failed = itest.run();
+// 
+//     std::cout << itest.report() << std::endl;
+//     
+//     return (failed != 0);
+// }  
diff --git a/test/imagehierarchy/test_policy_parent.hxx b/test/imagehierarchy/test_policy_parent.hxx
new file mode 100644
index 0000000..ec7cd47
--- /dev/null
+++ b/test/imagehierarchy/test_policy_parent.hxx
@@ -0,0 +1,69 @@
+#ifndef VIGRA_TEST_POLICY_PARENT_HXX
+#define VIGRA_TEST_POLICY_PARENT_HXX
+
+#include "vigra/imagehierarchy.hxx"
+
+/** Ist eine Oberklasse aller ImagePolicys. ImagePolicys stellen die Besonderheiten der einzelner
+* Bilder dar, z.B. Vector2ImagePolicy stellt die Besonderheiten der Bilder Vector2Image, DVector2Image FVector2Image,
+* bei denen die Pixel TinyVectoren sind. Zusaetzlich wird der Vektor von entsprechenden Pixeln zu Verfuegung
+* gestellt, so dass die entsprechende Pixeln brauchen nicht in der Testklasse ImageTest erzeugt zu
+* werden. Da aber die Methoden factory() fast in allen Policy - Klassen gleich sind wurde deswegen die
+* abstrakte Oberklasse geschaffen, damit die Methoden brauchen nicht mehrmals auf gleiche Weise in
+* unterschiedlichen Unterklassen wiederhollt zu werden.
+*/
+template<class ToTestImage>
+class TestPolicy
+{
+public:
+    typedef ToTestImage                          Image;                      //es handelt sich um ein EinBandImage, wie FImage, BImage, GrayImage usw. ChildImage und Image sind aequivalent.
+    typedef ToTestImage                          ChildImage;                 //es handelt sich um ein EinBandImage, wie FImage, BImage, GrayImage usw. ChildImage und Image sind aequivalent.
+    typedef typename ToTestImage::PixelType      PixelType;
+    typedef typename Image::value_type           value_type;
+    typedef typename Image::value_type           child_value_type;
+    typedef std::vector<value_type>              data_array_type;
+    typedef std::vector<value_type>              child_data_array_type;
+
+    /** factory() - Methoden sind dazu, da um den Aufruf des richtigen Konstruktors
+    * zu kapseln. Insbesondere geht es darum, dass fuer Tests von SingleBandImage
+    * und VariableBandsImage die Konstruktoren der Unterklassen aufgerufen werden
+    * muessen, da sie selbst abstrakte Klassen sind, also man kann nicht die Instanzen
+    * von Ihnen erzeugen. Bei allen anderen Bildern muessen aber die Konstruktoren
+    * der Testklasse selber aufgerufen werden. Aus diesem Grunde auch die Unterscheidung
+    * zwischen Image und ChildImage.
+    */
+    static ChildImage * factory()
+    {
+        return new ChildImage();
+    }
+
+    static ChildImage * factory(int x, int y)
+    {
+        return new ChildImage(x,y);
+    }
+
+    static ChildImage * factory(vigra::Diff2D size)
+    {
+        return new ChildImage(size);
+    }
+
+    static ChildImage * factory(int x, int y, value_type pixel)
+    {
+        return new ChildImage(x, y, pixel);
+    }
+
+    static ChildImage * factory(ChildImage image)
+    {
+        return new ChildImage(image);
+    }
+
+#ifdef IMAGEHIERARCHY
+    static ChildImage * factory(typename ChildImage::InnerImage image)
+    {
+        return new ChildImage(image);
+    }
+#endif // IMAGEHIERARCHY
+
+};// end of class TestPolicy
+
+#endif // VIGRA_TEST_POLICY_PARENT_HXX
+
diff --git a/test/imagehierarchy/tests_start_suite.cxx b/test/imagehierarchy/tests_start_suite.cxx
new file mode 100644
index 0000000..2bc7162
--- /dev/null
+++ b/test/imagehierarchy/tests_start_suite.cxx
@@ -0,0 +1,45 @@
+#include "g++_relops_workaround.hxx"
+
+#include <unittest.hxx>
+#include "one_band_image_policy.hxx"
+#include "vector_2_image_policy.hxx"
+#include "vector_3_image_policy.hxx"
+#include "vector_4_image_policy.hxx"
+#include "variable_bands_image_policy.hxx"
+#include "rgb_images_policy.hxx"
+#include "single_band_image_policy.hxx"
+#include "select_band_image_policy.hxx"
+
+struct TestsStartSuite
+: public vigra::test_suite
+{
+    TestsStartSuite()
+    : vigra::test_suite("ALL TESTS")
+    {
+         add( new VariableImagesTestSuite );
+         add( new RGBImageHierarchyTestSuite );
+         add( new RGBBasicImageTestSuite );
+         add( new SelectImagesTestSuite );
+         add( new SingleImageTestSuite );
+         add( new GrayImageTestSuite );
+         add( new OneBandBasicImageTestSuite );
+         add( new Vector2ImageHierarchyTestSuite );
+         add( new Vector3ImageHierarchyTestSuite );
+         add( new Vector4ImageHierarchyTestSuite );
+         add( new Vector2BasicImageTestSuite );
+         add( new Vector3BasicImageTestSuite );
+         add( new Vector4BasicImageTestSuite );
+    }
+};
+
+int main()
+{
+ 
+    TestsStartSuite itest;
+
+    int failed = itest.run();
+
+    std::cout << itest.report() << std::endl;
+    
+    return (failed != 0);
+}  
diff --git a/test/imagehierarchy/variable_bands_image_policy.hxx b/test/imagehierarchy/variable_bands_image_policy.hxx
new file mode 100644
index 0000000..1e25f5c
--- /dev/null
+++ b/test/imagehierarchy/variable_bands_image_policy.hxx
@@ -0,0 +1,81 @@
+#ifndef VARIABLE_BANDS_IMAGE_POLICY_HXX
+#define VARIABLE_BANDS_IMAGE_POLICY_HXX
+
+#include "vigra/imagehierarchy.hxx"
+#include <unittest.hxx>
+
+/**An das template wird eine Policy-Klasse der Bilder der Imagehierarchie uebergeben
+*  die moeglichen sind: ImagePolicy<GrayImage>, RGBImagePolicy<RGBImage>,
+*  Vector2ImagePolicy<Vector2Image>, Vector3ImagePolicy<Vector3Image>, Vector4ImagePolicy<Vector4Image>.
+*/
+template<class IMAGEPOLICY>
+class VariableBandsImagePolicy
+{
+
+/** Bei dem Image (in diesem Fall VariableBandsImage) handelt es sich um die zu testende Klasse
+*  dagegen ChildImage ist die abgeleitete Klasse von Image, z.B. GrayImage oder FixedRGBImage.
+*  Die VariableBandsImage-Konstruktoren sind protected und somit nicht aufrufbar. Um die Klasse zu testen,
+*  muessen wir die Konstruktoren der abgeleiteten Klassen benutzen. Somit werden alle zur Verfuegung
+*  stehende Funktionen getestet. 
+*  In der Testklasse werden die ChildImage Konstruktoren aufgerufen, aber an einem Objekt
+*  der VariableBandsImage Klasse (Polymorphie).
+*/
+
+public: 
+    typedef typename IMAGEPOLICY::Image                 ChildImage;             // abgeleitete Klasse der ImageKlasse, es kann sich hierbei um GrayImage, SelectBandImage, SingleBandImage, FixedRGBImage oder beliebiges FixedBandImage (Vector2Image, Vector3Image usw.) handeln                
+    typedef vigra::VariableBandsImage                   Image;                  // VariableBandsImage
+    typedef vigra::VariableBandsImage::PixelType        PixelType;              // VektorProxy
+    typedef typename ChildImage::value_type             value_type;             // 
+    typedef typename ChildImage::value_type             child_value_type;       
+    typedef std::vector<value_type>                     data_array_type;
+    typedef std::vector<value_type>                     child_data_array_type;
+    
+    static  data_array_type getData()
+    {
+        return IMAGEPOLICY::getData();
+    }
+    
+    static  child_data_array_type getChildData()
+    {
+        return IMAGEPOLICY::getChildData();
+    }
+    
+    static ChildImage * factory()
+    {
+        return new ChildImage();
+    }
+    
+    static ChildImage * factory(int x, int y)
+    {
+        return new ChildImage(x,y);
+    }     
+    
+    static ChildImage * factory(vigra::Diff2D size)
+    {
+        return new ChildImage(size);
+    }
+
+    static ChildImage * factory(int x, int y, value_type pixel)
+    {
+        return new ChildImage(x, y, pixel);
+    }
+    
+    static ChildImage * factory(ChildImage image)
+    {
+        return new ChildImage(image);
+    }
+    
+    static ChildImage * factory(typename ChildImage::InnerImage image)
+    {
+        return new ChildImage(image);
+    }
+
+};
+
+struct VariableImagesTestSuite
+: public vigra::test_suite
+{
+    VariableImagesTestSuite();
+};
+
+#endif // VARIABLE_BANDS_IMAGE_POLICY_HXX
diff --git a/test/imagehierarchy/variable_bands_image_test.hxx b/test/imagehierarchy/variable_bands_image_test.hxx
new file mode 100644
index 0000000..96c72e6
--- /dev/null
+++ b/test/imagehierarchy/variable_bands_image_test.hxx
@@ -0,0 +1,133 @@
+#ifndef VARIABLE_BANDS_IMAGE_TEST_HXX
+#define VARIABLE_BANDS_IMAGE_TEST_HXX
+
+#include "imagehierarchy_test.hxx"
+
+template<class Policy>
+class VariableBandsImageTest
+: public ImageHierarchyTest<Policy>
+{    
+public:
+    typedef typename Policy::Image              Image;              // zu testende Klasse z.B. GrayImage, VariableBandsImage usw.
+    typedef typename Policy::ChildImage         ChildImage;         // unterscheidet sich von zu testender Klasse Image, nur wenn einer der abstrakten Klassen VariableBandImage oder SingleBandImage oder die Klasse SelectBandImage getestet wird, sonst entspricht es der Klasse Image.  
+    typedef typename Policy::value_type         value_type;         // value_type der zu testenden Klasse
+    typedef typename Policy::child_value_type   child_value_type;   // value_type der Klasse an der die zu testende Klasse getestet wird, also z.B. VariableBandsImage wird am Beispiel von Vector2Image getestet dann ist child_value_type die value_type von Vector2Image
+    
+    /** testet die clone() Methode der Klasse aus imagehierarchy
+    */
+    void testClone()
+    {
+        /*
+        *  Im Falle der Aenderungsvornehmungen an einem der Images, werden die Aenderungen auch nur an einem sichtbar
+        */
+        std::auto_ptr<typename Image::CloneType> image1(image1_->clone()); 
+        should(equal(*image1, *image1_));                                               
+        should(equalPixels(image1_->begin(),image1_->end(), image1->begin()));             
+        should(&(*image1) != &(*image1_));                                              
+        
+        /* Aenderung mit der init-Funktion
+        */
+        image1->init(data[5]); 
+        should((*image1_->begin()) != static_cast<typename Image::PixelType> (data[5]));
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[5])));
+        
+        image1_->init(data[6]);
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[5])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[6])));
+        
+        std::auto_ptr<typename Image::CloneType> image0(image0_->clone());
+        should(equal(*image0, *image0_));
+        should(equalPixels(image0_->begin(),image0_->end(), image0->begin()));image1_->init(data[6]);
+        should(&(*image0) != &(*image0_));
+    }
+    
+    /** testet die shallowCopy() Methode der Klassen aus imagehierarchy.
+    */
+    void testShallowCopy()
+    {
+        /*
+        *  Im Falle der Aenderungsvornehmungen an einem der Images, werden die Aenderungen an beiden sichtbar
+        *  Es gibt nur zwei Aenderungsmoeglichkeiten init() und Zuweisung eines anderen Images
+        *  bei der Zuweisung werden die Zeiger von den eigenen Daten auf die anderen umgeleitet,
+        *  und das entspricht nicht dem Sinn der shallowCopy
+        */
+        std::auto_ptr<Image> image1(image1_->shallowCopy());
+        should(equal(*image1, *image1_));     
+        should(&(*image1) != &(*image1_));
+        
+        /* Aenderung mit der init-Funktion
+        */
+        image1->init(data[7]);
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[7])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[7])));
+        
+        image1->init(data[8]);
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[8])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[8])));
+        
+        /* Eine shallowCopy zeigt auf die selben Daten des kopierten Objektes
+        */
+        std::auto_ptr<Image> image1Copy(image1->shallowCopy());
+        should(equal(*image1Copy, *image1_));
+        should(&(*image1Copy) != &(*image1_));
+        
+        image1Copy->init(data[9]);
+        should(image1Copy->end() == std::find_if(image1Copy->begin(), image1Copy->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
+        should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
+        should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
+        
+        std::auto_ptr<Image> image0(image0_->shallowCopy());
+        should(equal(*image0, *image0_));
+        should(&(*image0) != &(*image0_));
+    }
+};
+
+template <class POLICY>
+struct VariableBandsImageTestSuite
+: vigra::test_suite
+{
+    VariableBandsImageTestSuite(const char * to_test_Image_name)
+    : vigra::test_suite(to_test_Image_name)
+    {
+        add( testCase( &ImageTest<POLICY>::testImageDefaultConstuctor));
+        add( testCase( &ImageTest<POLICY>::testImageIntConstuctor));
+        add( testCase( &ImageTest<POLICY>::testImage2DConstuctor));
+        add( testCase( &ImageTest<POLICY>::testImageIntPixelConstuctor));
+        add( testCase( &ImageTest<POLICY>::testCopyConstructor));
+        add( testCase( &ImageTest<POLICY>::testInit));
+        add( testCase( &ImageTest<POLICY>::testWidth));
+        add( testCase( &ImageTest<POLICY>::testHeight));
+        add( testCase( &ImageTest<POLICY>::testSize)); 
+        add( testCase( &ImageTest<POLICY>::testIsInside));
+        add( testCase( &ImageTest<POLICY>::testOperatorIndex2D));
+        add( testCase( &ImageTest<POLICY>::testOperatorIndex2DConst));
+        add( testCase( &ImageTest<POLICY>::testOperatorFunctionCallInt));
+        add( testCase( &ImageTest<POLICY>::testOperatorFunctionCallIntConst));
+        add( testCase( &ImageTest<POLICY>::testUpperLeft));
+        add( testCase( &ImageTest<POLICY>::testLowerRight));
+        add( testCase( &ImageTest<POLICY>::testConstUpperLeft));
+        add( testCase( &ImageTest<POLICY>::testConstLowerRight));
+        add( testCase( &ImageTest<POLICY>::testBegin));
+        add( testCase( &ImageTest<POLICY>::testEnd));
+        add( testCase( &ImageTest<POLICY>::testConstBegin));
+        add( testCase( &ImageTest<POLICY>::testConstEnd));
+        add( testCase( &ImageTest<POLICY>::testOperatorDoubleIndex));
+        add( testCase( &ImageTest<POLICY>::testOperatorDoubleIndexConst));
+        add( testCase( &ImageTest<POLICY>::testAccessor));
+        add( testCase( &ImageTest<POLICY>::testAccessorConst));
+        add( testCase( &ImageTest<POLICY>::testAllAccessAndSetMethods));        
+        add( testCase( &ImageHierarchyTest<POLICY>::testInnerImageConstructor));
+        add( testCase( &VariableBandsImageTest<POLICY>::testClone));
+        add( testCase( &VariableBandsImageTest<POLICY>::testShallowCopy));
+        add( testCase( &ImageHierarchyTest<POLICY>::testSetROI));
+        add( testCase( &ImageHierarchyTest<POLICY>::testResetROI));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualSize));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualWidth));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualHeight));
+        add( testCase( &ImageHierarchyTest<POLICY>::testActualBands));
+        add( testCase( &ImageHierarchyTest<POLICY>::testBands));
+        add( testCase( &ImageHierarchyTest<POLICY>::testRoiUpperLeft));
+        add( testCase( &ImageHierarchyTest<POLICY>::testIsInsideROI));
+    }
+};//end of struct VariableBandsImageTestSuite
+#endif // VARIABLE_BANDS_IMAGE_TEST_HXX
diff --git a/test/imagehierarchy/variable_bands_image_test_suite.cxx b/test/imagehierarchy/variable_bands_image_test_suite.cxx
new file mode 100644
index 0000000..a14b73a
--- /dev/null
+++ b/test/imagehierarchy/variable_bands_image_test_suite.cxx
@@ -0,0 +1,33 @@
+#include "g++_relops_workaround.hxx"
+
+#include "variable_bands_image_policy.hxx" 
+#include "vector_2_image_policy.hxx" 
+#include "vector_3_image_policy.hxx" 
+#include "vector_4_image_policy.hxx" 
+#include "rgb_images_policy.hxx" 
+#include "one_band_image_policy.hxx" 
+#include "variable_bands_image_test.hxx" 
+
+/** Vorsicht !!! in select_image_test.hxx gibt's VariableBandImageTestSuite. Den Unterschied beachten!!!
+*/
+VariableImagesTestSuite::VariableImagesTestSuite()
+    : vigra::test_suite("VariableBandImageTestSuite")
+    {
+        add( new VariableBandsImageTestSuite<VariableBandsImagePolicy<OneBandImagePolicy<vigra::GrayImage> > > ("VariableBandsImage an GrayImage"));
+        add( new VariableBandsImageTestSuite<VariableBandsImagePolicy<RGBImagePolicy<vigra::RGBImage> > > ("VariableBandsImage an RGBImage"));
+        add( new VariableBandsImageTestSuite<VariableBandsImagePolicy<Vector2ImagePolicy<vigra::Vector2Image> > > ("VariableBandsImage an Vector2Image"));
+//        add( new VariableBandsImageTestSuite<VariableBandsImagePolicy<Vector3ImagePolicy<vigra::Vector3Image> > > ("VariableBandsImage an Vector3Image"));
+        add( new VariableBandsImageTestSuite<VariableBandsImagePolicy<Vector4ImagePolicy<vigra::Vector4Image> > > ("VariableBandsImage an Vector4Image"));
+    }
+
+// int main()
+// {
+//  
+//     VariableImagesTestSuite itest;
+// 
+//     int failed = itest.run();
+// 
+//     std::cout << itest.report() << std::endl;
+//     
+//     return (failed != 0);
+// }  
diff --git a/test/imagehierarchy/vector_2_basic_image_test_suite.cxx b/test/imagehierarchy/vector_2_basic_image_test_suite.cxx
new file mode 100644
index 0000000..f7ee485
--- /dev/null
+++ b/test/imagehierarchy/vector_2_basic_image_test_suite.cxx
@@ -0,0 +1,19 @@
+#include "g++_relops_workaround.hxx"
+
+#include "vector_2_image_policy.hxx"
+#include "basic_image_test.hxx"
+
+Vector2BasicImageTestSuite ::Vector2BasicImageTestSuite()
+    : vigra::test_suite(" Vector2BasicImageTestSuite")
+    {
+        add ( new BasicImageTestSuite<Vector2ImagePolicy<vigra::FVector2Image> > ("vigra::FVector2Image"));
+        add ( new BasicImageTestSuite<Vector2ImagePolicy<vigra::DVector2Image> > ("vigra::DVector2Image"));
+    }
+
+// int main()
+// {
+//     Vector2BasicImageTestSuite suite;
+//     int failed = suite.run();
+//     std::cout << suite.report() << std::endl;
+//     return (failed != 0);
+// }
diff --git a/test/imagehierarchy/vector_2_image_policy.hxx b/test/imagehierarchy/vector_2_image_policy.hxx
new file mode 100644
index 0000000..aa5108f
--- /dev/null
+++ b/test/imagehierarchy/vector_2_image_policy.hxx
@@ -0,0 +1,52 @@
+#ifndef VECTOR_2_IMAGE_POLICY_HXX
+#define VECTOR_2_IMAGE_POLICY_HXX
+
+#include "test_policy_parent.hxx"
+#include <unittest.hxx>
+
+template<class Vector2ImageP>                                           // bei dem template handelt es sich um Vector2Image, der einer der folgenden Varianten einnehmen kann: FVector2Image, DVector2Image, Vector2Image
+class Vector2ImagePolicy
+: public TestPolicy<Vector2ImageP> 
+{
+
+public:
+    typedef Vector2ImageP                       Image;                  // die zu testende Klasse
+    typedef Vector2ImageP                       ChildImage;             // entspricht der zu testenden Klasse
+    typedef typename Vector2ImageP::PixelType   PixelType;              // PixelType der zu testenden Klasse
+    typedef typename Image::value_type          value_type;             // value_type der zu testenden Klasse
+    typedef typename Image::value_type          child_value_type;       // entspricht dem value_type der zu testenden Klasse
+    typedef std::vector<value_type>             data_array_type;
+    typedef std::vector<child_value_type>       child_data_array_type;
+    typedef typename value_type::value_type     type;
+ 
+    static data_array_type getData()
+    {
+        type frgb = 0.1;
+        static value_type data[15];
+    
+        for(int i = 0; i <= 14 ; i ++)
+        {
+            data[i] = value_type((i+frgb), (2*i + frgb));
+        }
+        static data_array_type data_vector(data, data+sizeof(data)/sizeof(value_type));
+        return data_vector;
+    }
+     
+    static child_data_array_type getChildData()
+    {
+        return getData();
+    }
+};
+
+struct Vector2ImageHierarchyTestSuite
+: public vigra::test_suite
+{
+    Vector2ImageHierarchyTestSuite();
+};
+
+struct Vector2BasicImageTestSuite
+: public vigra::test_suite
+{
+    Vector2BasicImageTestSuite();
+};
+#endif // VECTOR_2_IMAGE_POLICY_HXX
diff --git a/test/imagehierarchy/vector_2_imagehierarchy_test_suite.cxx b/test/imagehierarchy/vector_2_imagehierarchy_test_suite.cxx
new file mode 100644
index 0000000..b01a065
--- /dev/null
+++ b/test/imagehierarchy/vector_2_imagehierarchy_test_suite.cxx
@@ -0,0 +1,18 @@
+#include "g++_relops_workaround.hxx"
+
+#include "vector_2_image_policy.hxx"
+#include "imagehierarchy_test.hxx"
+
+Vector2ImageHierarchyTestSuite::Vector2ImageHierarchyTestSuite()
+    : vigra::test_suite(" Vector2ImageHierarchyTestSuite")
+    {
+        add ( new ImageHierarchyTestSuite<Vector2ImagePolicy<vigra::Vector2Image> > ("vigra::Vector2Image"));
+    }
+
+// int main()
+// {
+//     Vector2ImageHierarchyTestSuite suite;
+//     int failed = suite.run();
+//     std::cout << suite.report() << std::endl;
+//     return (failed != 0);
+// }
diff --git a/test/imagehierarchy/vector_3_basic_image_test_suite.cxx b/test/imagehierarchy/vector_3_basic_image_test_suite.cxx
new file mode 100644
index 0000000..4a495c2
--- /dev/null
+++ b/test/imagehierarchy/vector_3_basic_image_test_suite.cxx
@@ -0,0 +1,19 @@
+#include "g++_relops_workaround.hxx"
+
+#include "vector_3_image_policy.hxx"
+#include "basic_image_test.hxx"
+
+Vector3BasicImageTestSuite::Vector3BasicImageTestSuite()
+    : vigra::test_suite(" Vector3BasicImageTestSuite")
+    {
+        add ( new BasicImageTestSuite<Vector3ImagePolicy<vigra::FVector3Image> > ("vigra::FVector3Image"));
+        add ( new BasicImageTestSuite<Vector3ImagePolicy<vigra::DVector3Image> > ("vigra::DVector3Image"));
+    }
+
+// int main()
+// {
+//     Vector3BasicImageTestSuite suite;
+//     int failed = suite.run();
+//     std::cout << suite.report() << std::endl;
+//     return (failed != 0);
+// }
diff --git a/test/imagehierarchy/vector_3_image_policy.hxx b/test/imagehierarchy/vector_3_image_policy.hxx
new file mode 100644
index 0000000..8cc8d6a
--- /dev/null
+++ b/test/imagehierarchy/vector_3_image_policy.hxx
@@ -0,0 +1,55 @@
+#ifndef VECTOR_3_IMAGE_POLICY_HXX
+#define VECTOR_3_IMAGE_POLICY_HXX
+
+#include "test_policy_parent.hxx"
+#include <unittest.hxx>
+
+template<class Vector3ImageP>                                           // bei dem template handelt es sich um Vector3Image, der einer der folgenden Varianten einnehmen kann: FVector3Image, DVector3Image, Vector3Image
+class Vector3ImagePolicy
+: public TestPolicy<Vector3ImageP>
+{
+
+public:
+    typedef Vector3ImageP                       Image;                  // die zu testende Klasse
+    typedef Vector3ImageP                       ChildImage;             // entspricht der zu testenden Klasse
+    typedef typename Vector3ImageP::PixelType   PixelType;              // PixelType der zu testenden Klasse
+    typedef typename Image::value_type          value_type;             // value_type der zu testenden Klasse
+    typedef typename Image::value_type          child_value_type;       // entspricht dem value_type der zu testenden Klasse 
+    typedef std::vector<value_type>             data_array_type;
+    typedef std::vector<value_type>             child_data_array_type;
+    typedef typename value_type::value_type     type;
+    
+    static data_array_type getData()
+    {
+        type frgb = 0.1;
+        static value_type data[15];
+    
+        for(int i = 0; i <= 14 ; i ++)
+        {
+            data[i] = value_type((i+frgb), (2*i), (2*i + frgb));
+        }
+        static data_array_type data_vector(data, data+sizeof(data)/sizeof(value_type));
+        return data_vector;
+    }
+    
+    static child_data_array_type getChildData()
+    {        
+        return getData();
+    }
+};// end of class Vector3ImagePolicy
+
+struct Vector3ImageHierarchyTestSuite
+: public vigra::test_suite
+{
+    Vector3ImageHierarchyTestSuite();
+};
+
+
+struct Vector3BasicImageTestSuite
+: public vigra::test_suite
+{
+    Vector3BasicImageTestSuite();
+};
+
+
+#endif // VECTOR_3_IMAGE_POLICY_HXX
diff --git a/test/imagehierarchy/vector_3_imagehierarchy_test_suite.cxx b/test/imagehierarchy/vector_3_imagehierarchy_test_suite.cxx
new file mode 100644
index 0000000..7dcecfe
--- /dev/null
+++ b/test/imagehierarchy/vector_3_imagehierarchy_test_suite.cxx
@@ -0,0 +1,18 @@
+#include "g++_relops_workaround.hxx"
+
+#include "vector_3_image_policy.hxx"
+#include "imagehierarchy_test.hxx"
+
+Vector3ImageHierarchyTestSuite::Vector3ImageHierarchyTestSuite()
+    : vigra::test_suite(" Vector3ImageHierarchyTestSuite")
+    {
+        add ( new ImageHierarchyTestSuite<Vector3ImagePolicy<vigra::Vector3Image> > ("vigra::Vector3Image"));
+    }
+
+// int main()
+// {
+//     Vector3ImageHierarchyTestSuite suite;
+//     int failed = suite.run();
+//     std::cout << suite.report() << std::endl;
+//     return (failed != 0);
+// }
diff --git a/test/imagehierarchy/vector_4_basic_image_test_suite.cxx b/test/imagehierarchy/vector_4_basic_image_test_suite.cxx
new file mode 100644
index 0000000..57edcfc
--- /dev/null
+++ b/test/imagehierarchy/vector_4_basic_image_test_suite.cxx
@@ -0,0 +1,19 @@
+#include "g++_relops_workaround.hxx"
+
+#include "vector_4_image_policy.hxx"
+#include "basic_image_test.hxx"
+
+Vector4BasicImageTestSuite::Vector4BasicImageTestSuite()
+    : vigra::test_suite(" Vector4BasicImageTestSuite")
+    {
+        add ( new BasicImageTestSuite<Vector4ImagePolicy<vigra::FVector4Image> > ("vigra::FVector4Image"));
+        add ( new BasicImageTestSuite<Vector4ImagePolicy<vigra::DVector4Image> > ("vigra::DVector4Image"));
+    }
+
+// int main()
+// {
+//     Vector4BasicImageTestSuite suite;
+//     int failed = suite.run();
+//     std::cout << suite.report() << std::endl;
+//     return (failed != 0);
+// }
diff --git a/test/imagehierarchy/vector_4_image_policy.hxx b/test/imagehierarchy/vector_4_image_policy.hxx
new file mode 100644
index 0000000..6b125b1
--- /dev/null
+++ b/test/imagehierarchy/vector_4_image_policy.hxx
@@ -0,0 +1,55 @@
+#ifndef VECTOR_4_IMAGE_POLICY_HXX
+#define VECTOR_4_IMAGE_POLICY_HXX
+
+#include "test_policy_parent.hxx"
+#include <unittest.hxx>
+
+template<class Vector4ImageP>                                           // bei dem template handelt es sich um Vector4Image, der einer der folgenden Varianten einnehmen kann: FVector4Image, DVector4Image, Vector4Image
+class Vector4ImagePolicy
+: public TestPolicy<Vector4ImageP>
+{
+
+public:
+    typedef Vector4ImageP                       Image;                   // die zu testende Klasse
+    typedef Vector4ImageP                       ChildImage;              // entspricht der zu testenden Klasse
+    typedef typename Vector4ImageP::PixelType   PixelType;               // PixelType der zu testenden Klasse
+    typedef typename Image::value_type          value_type;              // value_type der zu testenden Klasse
+    typedef typename Image::value_type          child_value_type;        // entspricht dem value_type der zu testenden Klasse
+    typedef std::vector<value_type>             data_array_type;
+    typedef std::vector<value_type>             child_data_array_type;
+    typedef typename value_type::value_type     type;
+ 
+    static data_array_type getData()
+    {
+        type frgb = 0.1;
+        static value_type data[15];
+    
+        for(int i = 0; i <= 14 ; i ++)
+        {
+            data[i] = value_type((i+frgb), (2*i), (2*i + frgb), (2*i + 2*frgb));
+        }
+        static data_array_type data_vector(data, data+sizeof(data)/sizeof(value_type));
+        return data_vector;
+    }
+    
+    static child_data_array_type getChildData()
+    {        
+        return getData();
+    }
+};
+
+struct Vector4BasicImageTestSuite
+: public vigra::test_suite
+{
+    Vector4BasicImageTestSuite();
+};
+
+
+struct Vector4ImageHierarchyTestSuite
+: public vigra::test_suite
+{
+    Vector4ImageHierarchyTestSuite();
+};
+
+
+#endif // VECTOR_4_IMAGE_POLICY_HXX
diff --git a/test/imagehierarchy/vector_4_imagehierarchy_test_suite.cxx b/test/imagehierarchy/vector_4_imagehierarchy_test_suite.cxx
new file mode 100644
index 0000000..04ea07f
--- /dev/null
+++ b/test/imagehierarchy/vector_4_imagehierarchy_test_suite.cxx
@@ -0,0 +1,18 @@
+#include "g++_relops_workaround.hxx"
+
+#include "vector_4_image_policy.hxx"
+#include "imagehierarchy_test.hxx"
+
+Vector4ImageHierarchyTestSuite::Vector4ImageHierarchyTestSuite()
+    : vigra::test_suite(" Vector4ImageHierarchyTestSuite")
+    {
+        add ( new ImageHierarchyTestSuite<Vector4ImagePolicy<vigra::Vector4Image> > ("vigra::Vector4Image"));
+    }
+
+// int main()
+// {
+//     Vector4ImageHierarchyTestSuite suite;
+//     int failed = suite.run();
+//     std::cout << suite.report() << std::endl;
+//     return (failed != 0);
+// }
diff --git a/test/imgproc/CMakeLists.txt b/test/imgproc/CMakeLists.txt
new file mode 100644
index 0000000..4d6759a
--- /dev/null
+++ b/test/imgproc/CMakeLists.txt
@@ -0,0 +1,3 @@
+VIGRA_ADD_TEST(test_imgproc test.cxx LIBRARIES vigraimpex)
+
+VIGRA_COPY_TEST_DATA(lenna128.xv lenna128rgb.xv splineimageview2.xv splineimageview3.xv splineimageview5.xv lenna42lin.xv lenna288neu.xv lenna42neu.xv lenna288rgbneu.xv lenna42rgbneu.xv lenna367FIR.xv lenna42FIR.xv lenna367IIR.xv lenna42IIR.xv lenna42linrgb.xv lennargb42FIR.xv lennargb42IIR.xv lenna_rotate.xv)
diff --git a/test/imgproc/lenna128.xv b/test/imgproc/lenna128.xv
new file mode 100644
index 0000000..11782b2
Binary files /dev/null and b/test/imgproc/lenna128.xv differ
diff --git a/test/imgproc/lenna128rgb.xv b/test/imgproc/lenna128rgb.xv
new file mode 100644
index 0000000..44dc30b
Binary files /dev/null and b/test/imgproc/lenna128rgb.xv differ
diff --git a/test/imgproc/lenna288.xv b/test/imgproc/lenna288.xv
new file mode 100644
index 0000000..8d90479
Binary files /dev/null and b/test/imgproc/lenna288.xv differ
diff --git a/test/imgproc/lenna288neu.xv b/test/imgproc/lenna288neu.xv
new file mode 100755
index 0000000..bf3b383
Binary files /dev/null and b/test/imgproc/lenna288neu.xv differ
diff --git a/test/imgproc/lenna288rgb.xv b/test/imgproc/lenna288rgb.xv
new file mode 100644
index 0000000..caaa35f
Binary files /dev/null and b/test/imgproc/lenna288rgb.xv differ
diff --git a/test/imgproc/lenna288rgbneu.xv b/test/imgproc/lenna288rgbneu.xv
new file mode 100755
index 0000000..fef86ed
Binary files /dev/null and b/test/imgproc/lenna288rgbneu.xv differ
diff --git a/test/imgproc/lenna367FIR.xv b/test/imgproc/lenna367FIR.xv
new file mode 100644
index 0000000..db09bea
Binary files /dev/null and b/test/imgproc/lenna367FIR.xv differ
diff --git a/test/imgproc/lenna367IIR.xv b/test/imgproc/lenna367IIR.xv
new file mode 100644
index 0000000..ab4b982
Binary files /dev/null and b/test/imgproc/lenna367IIR.xv differ
diff --git a/test/imgproc/lenna42.xv b/test/imgproc/lenna42.xv
new file mode 100644
index 0000000..ef17ec8
Binary files /dev/null and b/test/imgproc/lenna42.xv differ
diff --git a/test/imgproc/lenna42FIR.xv b/test/imgproc/lenna42FIR.xv
new file mode 100644
index 0000000..3929649
Binary files /dev/null and b/test/imgproc/lenna42FIR.xv differ
diff --git a/test/imgproc/lenna42IIR.xv b/test/imgproc/lenna42IIR.xv
new file mode 100644
index 0000000..4cfd069
Binary files /dev/null and b/test/imgproc/lenna42IIR.xv differ
diff --git a/test/imgproc/lenna42lin.xv b/test/imgproc/lenna42lin.xv
new file mode 100644
index 0000000..cfefba5
Binary files /dev/null and b/test/imgproc/lenna42lin.xv differ
diff --git a/test/imgproc/lenna42linrgb.xv b/test/imgproc/lenna42linrgb.xv
new file mode 100644
index 0000000..59fe889
Binary files /dev/null and b/test/imgproc/lenna42linrgb.xv differ
diff --git a/test/imgproc/lenna42neu.xv b/test/imgproc/lenna42neu.xv
new file mode 100755
index 0000000..4cfd069
Binary files /dev/null and b/test/imgproc/lenna42neu.xv differ
diff --git a/test/imgproc/lenna42rgb.xv b/test/imgproc/lenna42rgb.xv
new file mode 100644
index 0000000..18c6f56
Binary files /dev/null and b/test/imgproc/lenna42rgb.xv differ
diff --git a/test/imgproc/lenna42rgbneu.xv b/test/imgproc/lenna42rgbneu.xv
new file mode 100755
index 0000000..7f97090
Binary files /dev/null and b/test/imgproc/lenna42rgbneu.xv differ
diff --git a/test/imgproc/lenna_rotate.xv b/test/imgproc/lenna_rotate.xv
new file mode 100755
index 0000000..c4a5503
Binary files /dev/null and b/test/imgproc/lenna_rotate.xv differ
diff --git a/test/imgproc/lennargb42FIR.xv b/test/imgproc/lennargb42FIR.xv
new file mode 100644
index 0000000..b4551ed
Binary files /dev/null and b/test/imgproc/lennargb42FIR.xv differ
diff --git a/test/imgproc/lennargb42IIR.xv b/test/imgproc/lennargb42IIR.xv
new file mode 100644
index 0000000..7f97090
Binary files /dev/null and b/test/imgproc/lennargb42IIR.xv differ
diff --git a/test/imgproc/splineimageview2.xv b/test/imgproc/splineimageview2.xv
new file mode 100755
index 0000000..f76327b
Binary files /dev/null and b/test/imgproc/splineimageview2.xv differ
diff --git a/test/imgproc/splineimageview3.xv b/test/imgproc/splineimageview3.xv
new file mode 100755
index 0000000..3c82c1d
Binary files /dev/null and b/test/imgproc/splineimageview3.xv differ
diff --git a/test/imgproc/splineimageview5.xv b/test/imgproc/splineimageview5.xv
new file mode 100755
index 0000000..4769965
Binary files /dev/null and b/test/imgproc/splineimageview5.xv differ
diff --git a/test/imgproc/test.cxx b/test/imgproc/test.cxx
new file mode 100755
index 0000000..d8ac224
--- /dev/null
+++ b/test/imgproc/test.cxx
@@ -0,0 +1,1841 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <functional>
+#include <cmath>
+#include <time.h>
+#include <stdio.h>
+#include "vigra/unittest.hxx"
+#include "vigra/stdimage.hxx"
+#include "vigra/stdimagefunctions.hxx"
+#include "vigra/splineimageview.hxx"
+#include "vigra/basicgeometry.hxx"
+#include "vigra/affinegeometry.hxx"
+#include "vigra/impex.hxx"
+#include "vigra/meshgrid.hxx"
+#include "vigra/multi_array.hxx"
+#include "vigra/multi_math.hxx"
+#include "vigra/functorexpression.hxx"
+
+using namespace vigra;
+
+struct Counter   // for initImageWithFunctor
+{
+    Counter() : count(0) {}
+        
+    int operator()() const { return count++; }
+    
+    mutable int count;
+};
+
+
+struct ImageFunctionsTest
+{
+    typedef vigra::DImage Image;
+    typedef vigra::MultiArrayView<2, double> View;
+    typedef vigra::DRGBImage RGBImage;
+    typedef vigra::MultiArrayView<2, RGBValue<double> > RGBView;
+    typedef Image::value_type GrayValue;
+    typedef RGBImage::value_type RGBPixel;
+
+    ImageFunctionsTest()
+    : img(3,3), mask(Shape2(3,3)), rgb(3,3), col(1.0, 2.0, 3.0)
+    {
+        Image::Accessor acc = img.accessor();
+        Image::ScanOrderIterator i = img.begin();
+
+        acc.set(1.1, i);
+        ++i;
+        acc.set(2.2, i);
+        ++i;
+        acc.set(3.3, i);
+        ++i;
+        acc.set(4.4, i);
+        ++i;
+        acc.set(5.5, i);
+        ++i;
+        acc.set(6.6, i);
+        ++i;
+        acc.set(7.7, i);
+        ++i;
+        acc.set(8.8, i);
+        ++i;
+        acc.set(9.9, i);
+        ++i;
+        should(i == img.end());
+
+        mask.init(1);
+        mask.begin()[0] = 0;
+        mask.begin()[8] = 0;
+
+        rgb.init(col);
+    }
+
+    void copyImageTest()
+    {
+        Image img1(3,3);
+
+        copyImage(srcImageRange(img), destImage(img1));
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i, ++i1)
+        {
+            should(acc(i) == acc(i1));
+        }
+
+        img1 = 0.0;
+        copyImage(View(img), View(img1));
+        should(View(img) == View(img1));
+    }
+
+    void copyImageIfTest()
+    {
+        Image img1(3,3);
+        img1 = 42.0;
+        Image img2(3,3);
+        img2 = 42.0;
+
+        copyImageIf(srcImageRange(img), maskImage(mask), destImage(img1));
+        copyImageIf(View(img), mask, View(img2));
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::ScanOrderIterator i1end = img1.end();
+        Image::Accessor acc = img.accessor();
+
+        should(acc(i1) == 42.0);
+        ++i;
+        ++i1;
+        --i1end;
+        should(acc(i1end) == 42.0);
+
+        for(; i1 != i1end; ++i, ++i1)
+        {
+            should(acc(i) == acc(i1));
+        }
+
+        should(View(img1) == View(img2));
+    }
+
+    void copyRedBandTest()
+    {
+        vigra::RedAccessor<RGBPixel> red;
+
+        Image img1(3,3);
+        copyImage(srcImageRange(rgb, red), destImage(img));
+        copyImage(RGBView(rgb).expandElements(0).bindInner(0), View(img1));
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i)
+        {
+            should(acc(i) == 1.0);
+        }
+
+        should(View(img) == View(img1));
+
+        img = 42.0;
+        col.setRed(42.0);
+
+        copyImage(srcImageRange(img), destImage(rgb, red));
+
+        RGBImage::ScanOrderIterator ri = rgb.begin();
+        RGBImage::Accessor racc = rgb.accessor();
+
+        for(; ri != rgb.end(); ++ri)
+        {
+            should(racc(ri) == col);
+        }
+
+        img1 = 12.0;
+        col.setBlue(12.0);
+
+        copyImage(View(img1), RGBView(rgb).expandElements(0).bindInner(2));
+        using namespace multi_math;
+        should(all(RGBView(rgb) == col));
+    }
+
+    void copyGreenBandTest()
+    {
+        vigra::GreenAccessor<RGBPixel> green;
+
+        copyImage(srcImageRange(rgb, green), destImage(img));
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i)
+        {
+            should(acc(i) == 2.0);
+        }
+
+        img = 42.0;
+        col.setGreen(42.0);
+
+        copyImage(srcImageRange(img), destImage(rgb, green));
+
+        RGBImage::ScanOrderIterator ri = rgb.begin();
+        RGBImage::Accessor racc = rgb.accessor();
+
+        for(; ri != rgb.end(); ++ri)
+        {
+            should(racc(ri) == col);
+        }
+    }
+
+    void copyBlueBandTest()
+    {
+        vigra::BlueAccessor<RGBPixel> blue;
+
+        copyImage(srcImageRange(rgb, blue), destImage(img));
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i)
+        {
+            should(acc(i) == 3.0);
+        }
+
+        img = 42.0;
+        col.setBlue(42.0);
+
+        copyImage(srcImageRange(img), destImage(rgb, blue));
+
+        RGBImage::ScanOrderIterator ri = rgb.begin();
+        RGBImage::Accessor racc = rgb.accessor();
+
+        for(; ri != rgb.end(); ++ri)
+        {
+            should(racc(ri) == col);
+        }
+    }
+
+    void rgbToGrayTest()
+    {
+        vigra::RGBToGrayAccessor<RGBPixel> gray;
+
+        copyImage(srcImageRange(rgb, gray), destImage(img));
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i)
+        {
+            shouldEqualTolerance(acc(i), col.luminance(), 1e-12);
+        }
+
+    }
+
+    void initImageTest()
+    {
+        initImage(destImageRange(img), 42.0);
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i)
+        {
+            should(acc(i) == 42.0);
+        }
+
+        initImage(View(img), 12.0);
+
+        i = img.begin();
+        for(; i != img.end(); ++i)
+        {
+            should(acc(i) == 12.0);
+        }
+
+        Counter counter;
+        initImageWithFunctor(View(img), counter);
+
+        i = img.begin();
+        for(int k=0; i != img.end(); ++i, ++k)
+        {
+            should(acc(i) == k);
+        }
+    }
+
+    void initImageIfTest()
+    {
+        initImageIf(destImageRange(img), maskImage(mask), 42.0);
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator iend = img.end();
+        Image::Accessor acc = img.accessor();
+
+        should(acc(i) == 1.1);
+        ++i;
+        --iend;
+        should(acc(iend) == 9.9);
+        for(; i != iend; ++i)
+        {
+            should(acc(i) == 42.0);
+        }
+
+        initImageIf(View(img), mask, 12.0);
+        i = img.begin();
+        should(acc(i) == 1.1);
+        should(acc(iend) == 9.9);
+        ++i;
+        for(; i != iend; ++i)
+        {
+            should(acc(i) == 12.0);
+        }
+    }
+
+    void initImageBorderTest()
+    {
+        initImageBorder(destImageRange(img), 1, 42.0);
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::Accessor acc = img.accessor();
+        int k;
+
+        for(k=0; i != img.end(); ++i, ++k)
+        {
+            if(k != 4)
+                should(acc(i) == 42.0);
+            else
+                should(acc(i) == 5.5);
+        }
+
+        initImageBorder(View(img), 1, 12.0);
+
+        i = img.begin();
+        for(k=0; i != img.end(); ++i, ++k)
+        {
+            if(k != 4)
+                should(acc(i) == 12.0);
+            else
+                should(acc(i) == 5.5);
+        }
+    }
+
+    void findMinMaxTest()
+    {
+        vigra::FindMinMax<Image::value_type> minmax, minmax1;
+
+        inspectImage(srcImageRange(img), minmax);
+
+        should(minmax.count == 9);
+        should(minmax.max == 9.9);
+        should(minmax.min == 1.1);
+
+        inspectImage(View(img), minmax1);
+
+        should(minmax1.count == 9);
+        should(minmax1.max == 9.9);
+        should(minmax1.min == 1.1);
+    }
+
+    void findMinMaxIfTest()
+    {
+        vigra::FindMinMax<Image::value_type> minmax, minmax1;
+
+        inspectImageIf(srcImageRange(img), maskImage(mask), minmax);
+
+        should(minmax.count == 7);
+        should(minmax.max == 8.8);
+        should(minmax.min == 2.2);
+
+        inspectImageIf(View(img), mask, minmax1);
+
+        should(minmax1.count == 7);
+        should(minmax1.max == 8.8);
+        should(minmax1.min == 2.2);
+    }
+
+    void findAverageTest()
+    {
+        vigra::FindAverage<Image::value_type> average;
+
+        inspectImage(srcImageRange(img), average);
+
+        should(average.count() == 9);
+        should(average() == 5.5);
+
+        average(average); // combine
+
+        should(average.count() == 18);
+        should(average() == 5.5);
+    }
+
+    void findAverageIfTest()
+    {
+        vigra::FindAverage<Image::value_type> average;
+
+        inspectImageIf(srcImageRange(img), maskImage(mask), average);
+
+        should(average.count() == 7);
+        should(average() == 5.5);
+    }
+
+    void findAverageWeightedTest()
+    {
+        vigra::FindAverage<Image::value_type> average;
+
+        average(10);
+        average(5,  2.0);
+        average(42, 0.2);
+
+        shouldEqualTolerance(average.count(), 3.2, 1e-12);
+        shouldEqualTolerance(average(), (10+10+42*0.2)/(1+2+0.2), 1e-8);
+
+        average(average); // combine
+
+        shouldEqualTolerance(average.count(), 6.4, 1e-12);
+        shouldEqualTolerance(average(), (10+10+42*0.2)/(1+2+0.2), 1e-8);
+    }
+
+    void findAverageAndVarianceTest()
+    {
+        vigra::FindAverageAndVariance<Image::value_type> averageAndVariance;
+
+        inspectImage(srcImageRange(img), averageAndVariance);
+
+        should(averageAndVariance.count() == 9);
+        shouldEqualTolerance(averageAndVariance.average(), 5.5, 1e-14);
+
+        // compute variance explicitly
+        double sumOfSquares = 0.0;
+        Image::ScanOrderIterator i = img.begin();
+        for(; i != img.end(); ++i)
+        {
+            sumOfSquares += sq(*i - averageAndVariance.average());
+        }
+
+        shouldEqualTolerance(averageAndVariance.variance(), sumOfSquares / 9.0, 1e-14);
+        shouldEqualTolerance(averageAndVariance(), sumOfSquares / 9.0, 1e-14);
+        shouldEqualTolerance(averageAndVariance.variance(true), sumOfSquares / 8.0, 1e-14);
+
+        // check merge of functors
+        vigra::FindAverageAndVariance<Image::value_type> averageAndVariance1(averageAndVariance), averageAndVariance2;
+
+        averageAndVariance1(5.31);
+        averageAndVariance1(-0.3);
+        averageAndVariance1(2.88);
+        averageAndVariance1(10.521);
+
+        averageAndVariance2(5.31);
+        averageAndVariance2(-0.3);
+        averageAndVariance2(2.88);
+        averageAndVariance2(10.521);
+        averageAndVariance2(averageAndVariance);
+
+        should(averageAndVariance1.count() == 13);
+        should(averageAndVariance2.count() == 13);
+        shouldEqualTolerance(averageAndVariance1.average(), averageAndVariance2.average(), 1e-14);
+        shouldEqualTolerance(averageAndVariance1.variance(), averageAndVariance2.variance(), 1e-14);
+    }
+
+    void reduceFunctorTest()
+    {
+        std::plus<double> p;
+        ReduceFunctor<std::plus<double>, double> f(p, 0.0);
+
+        inspectImage(srcImageRange(img), f);
+
+        shouldEqual(f(), 49.5);
+    }
+
+    void meshGridTest()
+    {
+        // create an image whose values are equal to each pixel's distance from the image center
+        int width = 5, height = 7;
+        int xc = width/2, yc = height/2;
+
+        DImage dist(width, height);
+        Point2D upperLeft(-xc, -yc);
+
+        using namespace vigra::functor;
+        transformImage(meshGrid(upperLeft, upperLeft+dist.size()),
+                       destImage(dist),
+                       norm(Arg1()));
+        for(int y=0; y<height; ++y)
+            for(int x=0; x<width; ++x)
+                shouldEqualTolerance(dist(x,y), vigra::hypot(x-xc, y-yc), 1e-14);
+        dist.init(0.0);
+        transformImage(meshGrid(Rect2D(upperLeft, upperLeft+dist.size())),
+                       destImage(dist),
+                       norm(Arg1()));
+        for(int y=0; y<height; ++y)
+            for(int x=0; x<width; ++x)
+                shouldEqualTolerance(dist(x,y), vigra::hypot(x-xc, y-yc), 1e-14);
+    }
+
+
+    void findBoundingRectangleTest()
+    {
+        vigra::FindBoundingRectangle findRect;
+
+        mask = 0;
+        mask(1,1) = 1;
+
+        inspectImageIf(srcIterRange<Diff2D>(vigra::Diff2D(0,0), img.size()),
+                       maskImage(mask), findRect);
+
+        Rect2D rect = findRect();
+        should(rect.upperLeft().x == 1);
+        should(rect.upperLeft().y == 1);
+        should(rect.lowerRight().x == 2);
+        should(rect.lowerRight().y == 2);
+
+        mask(1,0) = 1;
+
+        inspectImageIf(srcIterRange<Diff2D>(vigra::Diff2D(0,0), img.size()),
+                       maskImage(mask), findRect);
+
+        rect = findRect();
+        should(rect.upperLeft().x == 1);
+        should(rect.upperLeft().y == 0);
+        should(rect.lowerRight().x == 2);
+        should(rect.lowerRight().y == 2);
+
+        mask(0,1) = 1;
+
+        inspectImageIf(srcIterRange<Diff2D>(vigra::Diff2D(0,0), img.size()),
+                       maskImage(mask), findRect);
+
+        rect = findRect();
+        should(rect.upperLeft().x == 0);
+        should(rect.upperLeft().y == 0);
+        should(rect.lowerRight().x == 2);
+        should(rect.lowerRight().y == 2);
+
+        mask(1,2) = 1;
+
+        inspectImageIf(srcIterRange<Diff2D>(vigra::Diff2D(0,0), img.size()),
+                       maskImage(mask), findRect);
+
+        rect = findRect();
+        should(rect.upperLeft().x == 0);
+        should(rect.upperLeft().y == 0);
+        should(rect.lowerRight().x == 2);
+        should(rect.lowerRight().y == 3);
+
+        mask(2,1) = 1;
+
+        inspectImageIf(srcIterRange<Diff2D>(vigra::Diff2D(0,0), img.size()),
+                       maskImage(mask), findRect);
+
+        rect = findRect();
+        should(rect.upperLeft().x == 0);
+        should(rect.upperLeft().y == 0);
+        should(rect.lowerRight().x == 3);
+        should(rect.lowerRight().y == 3);
+
+        vigra::FindBoundingRectangle findRect1;
+        findRect1(vigra::Diff2D(4,4));
+
+        findRect(findRect1);
+
+        rect = findRect();
+        should(rect.upperLeft().x == 0);
+        should(rect.upperLeft().y == 0);
+        should(rect.lowerRight().x == 5);
+        should(rect.lowerRight().y == 5);
+    }
+
+    void lastValueFunctorTest()
+    {
+        typedef vigra::LastValueFunctor<int> LastValue;
+        {
+            LastValue a;
+            a(10);
+            shouldEqual(a(), 10);
+            a(vigra::NumericTraits<int>::max());
+            shouldEqual(a(), vigra::NumericTraits<int>::max());
+            a(42);
+            shouldEqual(a(), 42);
+        }
+        {
+            // try to construct at same place on stack as a
+            // (check whether ints are initialized to zero)
+            LastValue b;
+            shouldEqual(b(), 0);
+        }
+        LastValue c(23); // test init. with value
+        shouldEqual(c(), 23);
+    }
+
+    void arrayOfRegionStatisticsTest()
+    {
+        vigra::MultiArray<2, unsigned char> labels(Shape2(3,3));
+        labels = 1;
+        labels[0] = 0;
+        labels[8] = 0;
+
+        vigra::ArrayOfRegionStatistics<vigra::FindMinMax<Image::value_type> > stats(1);
+
+        inspectTwoImages(View(img), labels, stats);
+
+        should(stats[0].count == 2);
+        should(stats[0].min == 1.1);
+        should(stats[0].max == 9.9);
+        should(stats[1].count == 7);
+        should(stats[1].min == 2.2);
+        should(stats[1].max == 8.8);
+
+        vigra::ArrayOfRegionStatistics<vigra::FindBoundingRectangle> stats1(1);
+        labels.init(0);
+        labels(1,1) = 1;
+
+        inspectTwoImages(srcIterRange<Diff2D>(vigra::Diff2D(0,0), img.size()),
+                         srcImage(labels), stats1);
+
+        should(stats1[0].upperLeft.x == 0);
+        should(stats1[0].upperLeft.y == 0);
+        should(stats1[0].lowerRight.x == 3);
+        should(stats1[0].lowerRight.y == 3);
+        should(stats1[1].upperLeft.x == 1);
+        should(stats1[1].upperLeft.y == 1);
+        should(stats1[1].lowerRight.x == 2);
+        should(stats1[1].lowerRight.y == 2);
+    }
+
+    void arrayOfRegionStatisticsIfTest()
+    {
+        vigra::MultiArray<2, unsigned char> labels(Shape2(3,3));
+        labels = 1;
+        labels[4] = 2;
+        labels[5] = 2;
+
+        vigra::ArrayOfRegionStatistics<vigra::FindMinMax<Image::value_type> > stats(2), stats1(2);
+
+        inspectTwoImagesIf(srcImageRange(img), srcImage(labels), maskImage(mask), stats);
+
+        should(stats[0].count == 0);
+        should(stats[1].count == 5);
+        should(stats[1].min == 2.2);
+        should(stats[1].max == 8.8);
+        should(stats[2].count == 2);
+        should(stats[2].min == 5.5);
+        should(stats[2].max == 6.6);
+
+        inspectTwoImagesIf(View(img), labels, mask, stats1);
+
+        should(stats1[0].count == 0);
+        should(stats1[1].count == 5);
+        should(stats1[1].min == 2.2);
+        should(stats1[1].max == 8.8);
+        should(stats1[2].count == 2);
+        should(stats1[2].min == 5.5);
+        should(stats1[2].max == 6.6);
+    }
+
+    void writeArrayOfRegionStatisticsTest()
+    {
+        vigra::BImage labels(3,3);
+        labels = 1;
+        labels.begin()[0] = 0;
+        labels.begin()[8] = 0;
+
+        vigra::ArrayOfRegionStatistics<vigra::FindAverage<Image::value_type> > stats(1);
+
+        inspectTwoImages(srcImageRange(img), srcImage(labels), stats);
+
+        should(stats[0].count() == 2);
+        should(stats[0]() == 5.5);
+        should(stats[1].count() == 7);
+        should(stats[1]() == 5.5);
+
+        transformImage(srcImageRange(labels), destImage(img), stats);
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i)
+        {
+            should(acc(i) == 5.5);
+        }
+
+    }
+
+    void linearIntensityTransformTest()
+    {
+        vigra::LinearIntensityTransform<Image::value_type> trans(2.0, -1.1);
+
+        Image img1(3,3);
+
+        transformImage(View(img), View(img1), trans);
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i, ++i1)
+        {
+            shouldEqual(2.0*(acc(i) - 1.1), acc(i1));
+        }
+
+        RGBImage img2(3,3);
+
+        transformImage(srcImageRange(rgb), destImage(img2),
+                        linearIntensityTransform(2.0, RGBPixel(0.0, -1.0, -2.0)));
+
+        shouldEqual(img2(0,0), RGBPixel(2.0, 2.0, 2.0));
+
+        transformImage(srcImageRange(rgb), destImage(img2),
+                        linearIntensityTransform(RGBPixel(2.0, 3.0, 4.0),
+                                                 RGBPixel(0.0, -1.0, -2.0)));
+
+        shouldEqual(img2(0,0), RGBPixel(2.0, 3.0, 4.0));
+    }
+
+    void scalarIntensityTransformTest()
+    {
+        Image img1(3,3);
+
+        transformImage(srcImageRange(img), destImage(img1),
+                       linearIntensityTransform<Image::value_type>(3.3));
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i, ++i1)
+        {
+            shouldEqual(3.3*acc(i), acc(i1));
+        }
+
+        RGBImage img2(3,3);
+
+        transformImage(srcImageRange(rgb), destImage(img2),
+                        linearIntensityTransform<RGBPixel>(
+                                                 RGBPixel(1.0, 2.0, 3.0)));
+
+        shouldEqual(img2(0,0), RGBPixel(1.0, 4.0, 9.0));
+    }
+
+    void linearIntensityTransformIfTest()
+    {
+        vigra::LinearIntensityTransform<Image::value_type> trans(2.0, -1.1);
+
+        Image img1(3,3);
+        img1 = 42.0;
+
+        transformImageIf(View(img), mask, View(img1), trans);
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::ScanOrderIterator i1end = img1.end();
+        Image::Accessor acc = img.accessor();
+
+        should(acc(i1) == 42.0);
+        ++i;
+        ++i1;
+        --i1end;
+        should(acc(i1end) == 42.0);
+
+        for(; i1 != i1end; ++i, ++i1)
+        {
+            shouldEqual(2.0*(acc(i) - 1.1), acc(i1));
+        }
+
+    }
+
+    void linearRangeMappingTest()
+    {
+        BImage img1(3,3);
+
+        transformImage(srcImageRange(img), destImage(img1),
+                       linearRangeMapping(1.0, 10.0, 0, 250));
+
+        int res[] = {3, 33, 64, 94, 125, 156, 186, 217, 247 };
+
+        shouldEqualSequence(img1.begin(), img1.end(), res);
+
+        FindMinMax<double> minmax;
+        inspectImage(srcImageRange(img), minmax);
+        transformImage(srcImageRange(img), destImage(img1),
+                       linearRangeMapping(minmax, 0, 250));
+    
+        int res1[] = {0, 31, 62, 94, 125, 156, 187, 219, 250 };
+#if 0
+        for(int i=0; i<9; ++i)
+            std::cerr << (int)*(&img1(0,0)+i) << ", ";
+        std::cerr << "\n";
+#endif
+        shouldEqualSequence(img1.begin(), img1.end(), res1);
+
+        BRGBImage img2(3,3);
+
+        transformImage(srcImageRange(rgb), destImage(img2),
+                       linearRangeMapping(RGBPixel(1.0, 1.0, 1.0),
+                                          RGBPixel(3.0, 3.0, 3.0),
+                                          BRGBImage::value_type(0, 0, 0),
+                                          BRGBImage::value_type(255, 255, 255)));
+
+        shouldEqual(img2(0,0), BRGBImage::value_type(0, 128, 255));
+    }
+
+    void thresholdTest()
+    {
+        vigra::Threshold<Image::value_type, Image::value_type> trans(2.0, 9.0, 0.0, 1.0);
+
+        Image img1(3,3);
+
+        transformImage(srcImageRange(img), destImage(img1), trans);
+
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::ScanOrderIterator i1end = img1.end();
+        Image::Accessor acc = img.accessor();
+
+        should(acc(i1) == 0.0);
+        ++i1;
+        --i1end;
+        should(acc(i1end) == 0.0);
+
+        for(; i1 != i1end; ++i1)
+        {
+            should(1.0 == acc(i1));
+        }
+
+    }
+
+    void brightnessContrastTest()
+    {
+        Image img1(3,3);
+
+        transformImage(srcImageRange(img), destImage(img1),
+              vigra::BrightnessContrastFunctor<double>(1.0, 1.0, 0.0, 255.0));
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator i1 = img1.begin();
+
+        for(; i != img.end(); ++i, ++i1)
+        {
+            should(VIGRA_CSTD::fabs(*i - *i1) < 1.0e-10);
+        }
+
+        vigra::BrightnessContrastFunctor<unsigned char> charf(10.0, 1.0);
+
+        for(int k=1; k < 255; ++k)
+        {
+            should(k < charf(k));
+        }
+        should(0 == charf(0));
+        should(255 == charf(255));
+
+        vigra::BrightnessContrastFunctor<RGBPixel > rgbf(2.0, 1.0, RGBPixel(0.0), RGBPixel(255.0));
+
+        should(col.red() < rgbf(col).red());
+        should(col.green() < rgbf(col).green());
+        should(col.blue() < rgbf(col).blue());
+    }
+
+    void gradientFunctionTest()
+    {
+        RGBImage in(3,3);
+        int y;
+
+        for(y=0; y<3; ++y)
+        {
+            for(int x=0; x<3; ++x)
+            {
+                in(x,y) = RGBPixel(float(x+y));
+            }
+        }
+
+        Image res(3,3);
+
+        gradientBasedTransform(
+          srcImageRange(in, vigra::RedAccessor<RGBPixel >()),
+          destImage(res), vigra::MagnitudeFunctor<double>());
+
+        for(y=0; y<3; ++y)
+        {
+            for(int x=0; x<3; ++x)
+            {
+                should(VIGRA_CSTD::fabs(res(x,y) - VIGRA_CSTD::sqrt(2.0)) < 1e-6);
+            }
+        }
+
+        gradientBasedTransform(RGBView(in), View(res), 
+                               vigra::RGBGradientMagnitudeFunctor<double>());
+
+        for(y=0; y<3; ++y)
+        {
+            for(int x=0; x<3; ++x)
+            {
+                should(VIGRA_CSTD::fabs(res(x,y) - VIGRA_CSTD::sqrt(6.0)) < 1e-6);
+            }
+        }
+    }
+
+    void additionTest()
+    {
+        Image img1(3,3), img2(3,3), img3(3,3);
+
+        std::plus<Image::value_type> add;
+
+        combineTwoImages(srcImageRange(img), srcImage(img), destImage(img1), add);
+        combineTwoImages(View(img), View(img), View(img2), add);
+
+        using namespace functor;
+        combineThreeImages(View(img), View(img), View(img1), View(img3), Arg1() + Arg2() + Arg3());
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::ScanOrderIterator i2 = img2.begin();
+        Image::ScanOrderIterator i3 = img3.begin();
+        Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i, ++i1, ++i2, ++i3)
+        {
+            should(2.0*acc(i) == acc(i1));
+            should(2.0*acc(i) == acc(i2));
+            should(4.0*acc(i) == acc(i3));
+        }
+    }
+
+    void additionIfTest()
+    {
+        Image img1(3,3), img2(3,3);
+        img1 = 42.0;
+        img2 = 42.0;
+
+        std::plus<Image::value_type> add;
+
+        combineTwoImagesIf(srcImageRange(img), srcImage(img),
+                           maskImage(mask), destImage(img1), add);
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::ScanOrderIterator i1end = img1.end();
+        Image::Accessor acc = img.accessor();
+
+        should(acc(i1) == 42.0);
+        ++i;
+        ++i1;
+        --i1end;
+        should(acc(i1end) == 42.0);
+
+        for(; i1 != i1end; ++i, ++i1)
+        {
+            should(2.0*acc(i) == acc(i1));
+        }
+
+        combineTwoImagesIf(View(img), View(img), mask, View(img2), add);
+        should(View(img1) == View(img2));
+    }
+
+    void resizeNoInterpolationTest()
+    {
+        Image img1(5,5), img3(5,5);
+
+        resizeImageNoInterpolation(srcImageRange(img), destImageRange(img1));
+
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::Accessor acc = img.accessor();
+
+        should(acc(i1) == 1.1);
+        ++i1;
+        should(acc(i1) == 2.2);
+        ++i1;
+        should(acc(i1) == 2.2);
+        ++i1;
+        should(acc(i1) == 3.3);
+        ++i1;
+        should(acc(i1) == 3.3);
+        ++i1;
+        should(acc(i1) == 4.4);
+        ++i1;
+        should(acc(i1) == 5.5);
+        ++i1;
+        should(acc(i1) == 5.5);
+        ++i1;
+        should(acc(i1) == 6.6);
+        ++i1;
+        should(acc(i1) == 6.6);
+        ++i1;
+        should(acc(i1) == 4.4);
+        ++i1;
+        should(acc(i1) == 5.5);
+        ++i1;
+        should(acc(i1) == 5.5);
+        ++i1;
+        should(acc(i1) == 6.6);
+        ++i1;
+        should(acc(i1) == 6.6);
+        ++i1;
+        should(acc(i1) == 7.7);
+        ++i1;
+        should(acc(i1) == 8.8);
+        ++i1;
+        should(acc(i1) == 8.8);
+        ++i1;
+        should(acc(i1) == 9.9);
+        ++i1;
+        should(acc(i1) == 9.9);
+        ++i1;
+        should(acc(i1) == 7.7);
+        ++i1;
+        should(acc(i1) == 8.8);
+        ++i1;
+        should(acc(i1) == 8.8);
+        ++i1;
+        should(acc(i1) == 9.9);
+        ++i1;
+        should(acc(i1) == 9.9);
+
+        Image img2(3,3);
+        img2 = 0;
+
+        resizeImageNoInterpolation(View(img1), View(img2));
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator i2 = img2.begin();
+
+        for(; i != img.end(); ++i, ++i2)
+        {
+            should(acc(i) == acc(i2));
+        }
+
+        resizeImageSplineInterpolation(View(img), View(img3), BSpline<0>());
+        shouldEqualSequence(img1.begin(), img1.end(), img3.begin());
+    }
+
+    void resizeLinearInterpolationTest()
+    {
+        Image img1(5,5);
+        resizeImageLinearInterpolation(srcImageRange(img), destImageRange(img1));
+
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::Accessor acc = img.accessor();
+
+        shouldEqualTolerance(acc(i1), 1.1, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 1.65, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 2.2, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 2.75, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 3.3, 1e-14);
+        ++i1;
+
+        shouldEqualTolerance(acc(i1), 2.75, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 3.3, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 3.85, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 4.4, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 4.95, 1e-14);
+        ++i1;
+
+        shouldEqualTolerance(acc(i1), 4.4, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 4.95, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 5.5, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 6.05, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 6.6, 1e-14);
+        ++i1;
+
+        shouldEqualTolerance(acc(i1), 6.05, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 6.6, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 7.15, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 7.7, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 8.25, 1e-14);
+        ++i1;
+
+        shouldEqualTolerance(acc(i1), 7.7, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 8.25, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 8.8, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 9.35, 1e-14);
+        ++i1;
+        shouldEqualTolerance(acc(i1), 9.9, 1e-14);
+
+        Image img2(3,3);
+        img2 = 0;
+
+        resizeImageNoInterpolation(View(img1), View(img2));
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator i2 = img2.begin();
+
+        for(; i != img.end(); ++i, ++i2)
+        {
+            should(acc(i) == acc(i2));
+        }
+    }
+
+
+    Image img;
+    vigra::MultiArray<2, unsigned char> mask;
+    RGBImage rgb;
+    RGBPixel col;
+};
+
+struct ResizeImageTest
+{
+    typedef vigra::FImage Image;
+    typedef vigra::FRGBImage RGBImage;
+    typedef MultiArrayView<2, RGBValue<float> > View;
+
+    ResizeImageTest()
+    {
+        ImageImportInfo ginfo("lenna128.xv");
+        img.resize(ginfo.width(), ginfo.height());
+        importImage(ginfo, destImage(img));
+
+        ImageImportInfo cinfo("lenna128rgb.xv");
+        rgb.resize(cinfo.width(), cinfo.height());
+        importImage(cinfo, destImage(rgb));
+
+    }
+
+    void resizeLinearInterpolationReduceTest()
+    {
+        ImageImportInfo inforef("lenna42lin.xv");
+        Image ref(inforef.size());
+        importImage(inforef, destImage(ref));
+
+        Image dest(inforef.size());
+
+        resizeImageLinearInterpolation(srcImageRange(img), destImageRange(dest));
+
+        shouldEqualSequenceTolerance(dest.begin(), dest.end(), ref.begin(), 1.0e-6f);
+
+        ImageImportInfo inforgb("lenna42linrgb.xv");
+        RGBImage rgbref(inforgb.size());
+        importImage(inforgb, destImage(rgbref));
+
+        RGBImage rgbdest(inforgb.size());
+
+        resizeImageLinearInterpolation(View(rgb), View(rgbdest));
+
+        shouldEqualSequenceTolerance(rgbdest.begin(), rgbdest.end(), rgbref.begin(),
+                                     RGBImage::value_type(1.0e-6f));
+    }
+
+    void scalarExpand()
+    {
+        ImageImportInfo info("lenna288neu.xv");
+
+        Image imgex(info.width(), info.height());
+        importImage(info, destImage(imgex));
+
+        Image img1(imgex.width(), imgex.height());
+        resizeImageSplineInterpolation(srcImageRange(img), destImageRange(img1));
+
+        shouldEqualSequenceTolerance(img1.begin(), img1.end(), imgex.begin(), 1e-4f);
+    }
+
+    void scalarReduce()
+    {
+        ImageImportInfo info("lenna42neu.xv");
+
+        Image imgred(info.width(), info.height());
+        importImage(info, destImage(imgred));
+
+        Image img1(imgred.width(), imgred.height());
+
+        resizeImageSplineInterpolation(srcImageRange(img), destImageRange(img1));
+
+        shouldEqualSequenceTolerance(img1.begin(), img1.end(), imgred.begin(), 1e-4f);
+   }
+
+    void rgbExpand()
+    {
+        ImageImportInfo info("lenna288rgbneu.xv");
+
+        RGBImage rgbex(info.width(), info.height());
+        importImage(info, destImage(rgbex));
+
+        RGBImage img1(rgbex.width(), rgbex.height());
+
+        resizeImageSplineInterpolation(View(rgb), View(img1));
+
+        RGBImage::ScanOrderIterator i1 = img1.begin();
+        RGBImage::ScanOrderIterator iex = rgbex.begin();
+        RGBImage::Accessor acc = img1.accessor();
+
+        for(; i1 != img1.end(); ++i1, ++iex)
+        {
+            shouldEqualTolerance(acc.red(i1), acc.red(iex), 1e-4f);
+            shouldEqualTolerance(acc.green(i1), acc.green(iex), 1e-4f);
+            shouldEqualTolerance(acc.blue(i1), acc.blue(iex), 1e-4f);
+        }
+    }
+
+    void rgbReduce()
+    {
+        ImageImportInfo info("lenna42rgbneu.xv");
+
+        RGBImage rgbred(info.width(), info.height());
+        importImage(info, destImage(rgbred));
+
+        RGBImage img1(rgbred.width(), rgbred.height());
+
+        resizeImageSplineInterpolation(View(rgb), View(img1));
+
+        RGBImage::ScanOrderIterator i1 = img1.begin();
+        RGBImage::ScanOrderIterator iref = rgbred.begin();
+        RGBImage::Accessor acc = img1.accessor();
+
+        for(; i1 != img1.end(); ++i1, ++iref)
+        {
+            shouldEqualTolerance(acc.red(i1), acc.red(iref), 1e-4f);
+            shouldEqualTolerance(acc.green(i1), acc.green(iref), 1e-4f);
+            shouldEqualTolerance(acc.blue(i1), acc.blue(iref), 1e-4f);
+        }
+    }
+
+    /*Vergroesserungstest
+    */
+    void testCatmullRomInterpolationExtensionWithLena()
+    {
+        ImageImportInfo inforef("lenna367FIR.xv");
+        Image ref(inforef.size());
+        importImage(inforef, destImage(ref));
+
+        Image dest(inforef.size());
+
+        resizeImageCatmullRomInterpolation(srcImageRange(img), destImageRange(dest));
+
+        shouldEqualSequenceTolerance(dest.begin(), dest.end(), ref.begin(), 1.0e-6f);
+    }
+
+
+    /*Verkleinerungstest
+    */
+    void testCatmullRomInterpolationReductionWithLena()
+    {
+        ImageImportInfo inforef("lenna42FIR.xv");
+        Image ref(inforef.size());
+        importImage(inforef, destImage(ref));
+
+        Image dest(inforef.size());
+
+        resizeImageCatmullRomInterpolation(srcImageRange(img), destImageRange(dest));
+
+        shouldEqualSequenceTolerance(dest.begin(), dest.end(), ref.begin(), 1e-4f);
+
+        ImageImportInfo inforgb("lennargb42FIR.xv");
+        RGBImage rgbref(inforgb.size());
+        importImage(inforgb, destImage(rgbref));
+
+        RGBImage rgbdest(inforgb.size());
+
+        resizeImageCatmullRomInterpolation(View(rgb), View(rgbdest));
+
+        RGBImage::ScanOrderIterator i1 = rgbdest.begin();
+        RGBImage::ScanOrderIterator iref = rgbref.begin();
+        RGBImage::Accessor acc = rgbdest.accessor();
+
+        for(; i1 != rgbdest.end(); ++i1, ++iref)
+        {
+            shouldEqualTolerance(acc.red(i1), acc.red(iref), 1e-4f);
+            shouldEqualTolerance(acc.green(i1), acc.green(iref), 1e-4f);
+            shouldEqualTolerance(acc.blue(i1), acc.blue(iref), 1e-4f);
+        }
+    }
+
+    void testCubicInterpolationExtensionWithLena()
+    {
+        ImageImportInfo inforef("lenna367IIR.xv");
+        Image ref(inforef.size());
+        importImage(inforef, destImage(ref));
+
+        Image dest(inforef.size());
+
+        resizeImageSplineInterpolation(srcImageRange(img), destImageRange(dest));
+
+        shouldEqualSequenceTolerance(dest.begin(), dest.end(), ref.begin(), 1e-4f);
+    }
+
+    /*Verkleinerungstest
+    */
+    void testCubicInterpolationReductionWithLena()
+    {
+        ImageImportInfo inforef("lenna42IIR.xv");
+        Image ref(inforef.size());
+        importImage(inforef, destImage(ref));
+
+        Image dest(inforef.size());
+
+        resizeImageSplineInterpolation(srcImageRange(img), destImageRange(dest));
+
+        shouldEqualSequenceTolerance(dest.begin(), dest.end(), ref.begin(), 1e-4f);
+
+        ImageImportInfo inforgb("lennargb42IIR.xv");
+        RGBImage rgbref(inforgb.size());
+        importImage(inforgb, destImage(rgbref));
+
+        RGBImage rgbdest(inforgb.size());
+
+        resizeImageSplineInterpolation(srcImageRange(rgb), destImageRange(rgbdest));
+
+        RGBImage::ScanOrderIterator i1 = rgbdest.begin();
+        RGBImage::ScanOrderIterator iref = rgbref.begin();
+        RGBImage::Accessor acc = rgbdest.accessor();
+
+        for(; i1 != rgbdest.end(); ++i1, ++iref)
+        {
+            shouldEqualTolerance(acc.red(i1), acc.red(iref), 1e-4f);
+            shouldEqualTolerance(acc.green(i1), acc.green(iref), 1e-4f);
+            shouldEqualTolerance(acc.blue(i1), acc.blue(iref), 1e-4f);
+        }
+    }
+
+    void testCatmullRomInterpolationExtensionHandControled()
+    {
+        vigra::DImage src(6, 7), dest(10, 10, 145.346);
+
+        for(int i = 0; i<src.width()*src.height(); i++)
+        {
+          src.begin()[i] = 0.25 + i;
+        }
+
+        static double refdata[100] =
+        {           0.25,/**/    0.695816186557,   1.36111111111,       1.91666666667,      2.47222222222,    3.02777777778,    3.58333333333,      4.13888888889,      4.80418381344,/***/       5.25,/**/
+           3.80555555556,        4.25137174211,    4.91666666667,       5.47222222222,      6.02777777778,    6.58333333333,    7.13888888889,      7.69444444444,      8.359739369,              8.80555555556,
+                    8.25,        8.69581618656,    9.36111111111,       9.91666666667,      10.4722222222,    11.0277777778,    11.5833333333,      12.1388888889,      12.8041838134,            13.25,
+                   12.25,/**/    12.6958161866,    13.3611111111,/***/  13.9166666667,      14.4722222222,    15.0277777778,    15.5833333333,      16.1388888889,      16.8041838134,            17.25,/**/
+                   16.25,/***/   16.6958161866,    17.3611111111,       17.9166666667,/***/ 18.4722222222,    19.0277777778,    19.5833333333,      20.1388888889,      20.8041838134,            21.25,
+                   20.25,        20.6958161866,    21.3611111111,       21.9166666667,      22.4722222222,    23.0277777778,    23.5833333333,      24.1388888889,      24.8041838134,            25.25,/***/
+                   24.25,/**/    24.6958161866,    25.3611111111,       25.9166666667,      26.4722222222,    27.0277777778,    27.5833333333,      28.1388888889,      28.8041838134,            29.25,/**/
+                   28.25,        28.6958161866,    29.3611111111,       29.9166666667,      30.4722222222,    31.0277777778,    31.5833333333,/***/ 32.1388888889,      32.8041838134,            33.25,
+           32.6944444444,        33.140260631,     33.8055555556,       34.3611111111,      34.9166666667,    35.4722222222,    36.0277777778,      36.5833333333,/***/ 37.2486282579,            37.6944444444,
+                   36.25,/**/    36.6958161866,    37.3611111111,/***/  37.9166666667,      38.4722222222,    39.0277777778,    39.5833333333,      40.1388888889,      40.8041838134,            41.25/**/
+        };
+
+        resizeImageCatmullRomInterpolation(srcImageRange(src), destImageRange(dest));
+
+        shouldEqualSequenceTolerance(dest.begin(), dest.end(), refdata, 1e-11);
+    }
+
+    Image img;
+    RGBImage rgb;
+};
+
+template <int N>
+struct SplineImageViewTest
+{
+    //typedef vigra::MultiArray<2, double> Image;
+    typedef vigra::DImage Image;
+    Image img;
+
+    SplineImageViewTest()
+    {
+        ImageImportInfo ginfo("lenna128.xv");
+        img.resize(ginfo.width(), ginfo.height());
+        importImage(ginfo, destImage(img));
+        //importImage("lenna128.xv", img);
+    }
+
+    void testPSF()
+    {
+        int center = 10;
+        Image img(2*center+1, 2*center+1);
+        img.init(0.0);
+        img(center, center) = 1.0;
+        SplineImageView<N, double> view(srcImageRange(img), true);
+        BSplineBase<N> spline;
+
+        double d0 = center;
+        double epsilon = 1.0e-10;
+        shouldEqualTolerance(view(d0,d0), spline(0.0)*spline(0.0), epsilon);
+        shouldEqualTolerance(view(d0,d0, 1, 0), spline(0.0, 1)*spline(0.0), epsilon);
+        shouldEqualTolerance(view(d0,d0, 0, 1), spline(0.0, 1)*spline(0.0), epsilon);
+        for(double d = 0.2; d < spline.radius(); d += 1.0)
+        {
+            double d1 = d + d0;
+            shouldEqualTolerance(view(d1,d0), spline(d)*spline(0.0), epsilon);
+            shouldEqualTolerance(view(d0,d1), spline(d)*spline(0.0), epsilon);
+            shouldEqualTolerance(view(d1,d1), spline(d)*spline(d), epsilon);
+            shouldEqualTolerance(view(d1, d0, 1, 0), spline(d, 1)*spline(0.0), epsilon);
+            shouldEqualTolerance(view(d0, d1, 0, 1), spline(d, 1)*spline(0.0), epsilon);
+            shouldEqualTolerance(view(d1, d1, 1, 0), spline(d, 1)*spline(d), epsilon);
+            shouldEqualTolerance(view(d1, d1, 0, 1), spline(d, 1)*spline(d), epsilon);
+            shouldEqualTolerance(view(d1, d1, 1, 1), spline(d, 1)*spline(d, 1), epsilon);
+        }
+    }
+
+    void testCoefficientArray()
+    {
+        double x = 5.3, y = 7.85;
+        double dx = (N % 2) ? x - VIGRA_CSTD::floor(x) : x - VIGRA_CSTD::floor(x + 0.5),
+               dy = (N % 2) ? y - VIGRA_CSTD::floor(y) : y - VIGRA_CSTD::floor(y + 0.5);
+
+        Image coefficients(N+1, N+1);
+        SplineImageView<N, double> view(srcImageRange(img));
+        // use the coefficients from a different point in the same facet -- should be the same!
+        view.coefficientArray(x-0.1, y-0.1, coefficients);
+
+        double f_x_y = 0.0;
+        for(int ny = 0; ny < N + 1; ++ny)
+            for(int nx = 0; nx < N + 1; ++nx)
+                f_x_y += VIGRA_CSTD::pow(dx, nx) * VIGRA_CSTD::pow(dy, ny) * coefficients(nx, ny);
+
+        shouldEqualTolerance(f_x_y, view(x, y), 1e-12);
+
+        // test out-of-bounds cases
+        x = -x;
+        y += img.height();
+        dx = (N % 2) ? x - VIGRA_CSTD::floor(x) : x - VIGRA_CSTD::floor(x + 0.5);
+        dy = (N % 2) ? y - VIGRA_CSTD::floor(y) : y - VIGRA_CSTD::floor(y + 0.5);
+        view.coefficientArray(x-0.1, y-0.1, coefficients);
+
+        f_x_y = 0.0;
+        for(int ny = 0; ny < N + 1; ++ny)
+            for(int nx = 0; nx < N + 1; ++nx)
+                f_x_y += VIGRA_CSTD::pow(dx, nx) * VIGRA_CSTD::pow(dy, ny) * coefficients(nx, ny);
+
+        shouldEqualTolerance(f_x_y, view(x, y), 1e-12);
+
+        x = 5.3 + img.width();
+        y = -7.85;
+        dx = (N % 2) ? x - VIGRA_CSTD::floor(x) : x - VIGRA_CSTD::floor(x + 0.5);
+        dy = (N % 2) ? y - VIGRA_CSTD::floor(y) : y - VIGRA_CSTD::floor(y + 0.5);
+        view.coefficientArray(x-0.1, y-0.1, coefficients);
+
+        f_x_y = 0.0;
+        for(int ny = 0; ny < N + 1; ++ny)
+            for(int nx = 0; nx < N + 1; ++nx)
+                f_x_y += VIGRA_CSTD::pow(dx, nx) * VIGRA_CSTD::pow(dy, ny) * coefficients(nx, ny);
+
+        shouldEqualTolerance(f_x_y, view(x, y), 1e-12);
+    }
+
+    void testImageResize()
+    {
+        char name[200];
+        sprintf(name, "splineimageview%d.xv", N);
+        ImageImportInfo info(name);
+
+        Image reference(info.width(), info.height());
+        importImage(info, destImage(reference));
+
+        SplineImageView<N, double> view(srcImageRange(img));
+
+        for(int y=0; y<reference.height(); ++y)
+        {
+            for(int x=0; x<reference.width(); ++x)
+            {
+                double dx = (double)x / (reference.width() - 1) * (img.width() - 1);
+                double dy = (double)y / (reference.height() - 1) * (img.height() - 1);
+                shouldEqualTolerance(view(dx, dy), reference(x, y), 1e-4);
+            }
+        }
+    }
+
+    void testImageResize0()
+    {
+        Image reference(img.width()*2-1, img.height()*2-1);
+        resizeImageNoInterpolation(srcImageRange(img), destImageRange(reference));
+
+        SplineImageView<0, double> view(srcImageRange(img));
+        SplineImageView<0, int> viewi(srcImageRange(img));
+
+        // check that data have not been copied
+        shouldEqual(view.image().width(), 0);
+        shouldEqual(viewi.image().width(), img.width());
+
+        for(int y=0; y<reference.height(); ++y)
+        {
+            for(int x=0; x<reference.width(); ++x)
+            {
+                double dx = (double)x / 2.0;
+                double dy = (double)y / 2.0;
+                shouldEqualTolerance(view(dx, dy), reference(x, y), 1e-4);
+                shouldEqualTolerance(view.unchecked(dx, dy, 0, 0), reference(x, y), 1e-4);
+                FixedPoint<10, 1> fx(dx), fy(dy);
+                shouldEqual(viewi.unchecked(fx, fy, 0, 0), viewi.unchecked(dx, dy, 0, 0));
+            }
+        }
+    }
+
+    void testImageResize1()
+    {
+        Image reference(img.width()*2-1, img.height()*2-1);
+        resizeImageLinearInterpolation(srcImageRange(img), destImageRange(reference));
+
+        SplineImageView<1, double> view(srcImageRange(img));
+        SplineImageView<1, short> viewi(srcImageRange(img));
+
+        // check that data have not been copied unnecessarily
+        shouldEqual(view.image().width(), 0);
+        shouldEqual(viewi.image().width(), img.width());
+
+        for(int y=0; y<reference.height(); ++y)
+        {
+            for(int x=0; x<reference.width(); ++x)
+            {
+                double dx = (double)x / 2.0;
+                double dy = (double)y / 2.0;
+                shouldEqualTolerance(view(dx, dy), reference(x, y), 1e-4);
+                shouldEqualTolerance(view.unchecked(dx, dy, 0, 0), reference(x, y), 1e-4);
+                FixedPoint<10, 1> fx(dx), fy(dy);
+                shouldEqual(viewi.unchecked(fx, fy, 0, 0), viewi.unchecked(dx, dy, 0, 0));
+                shouldEqual(viewi.unchecked(fx, fy), viewi.unchecked(dx, dy));
+            }
+        }
+    }
+
+    void testOutside()
+    {
+        int center = 10;
+        Image img(2*center+1, 2*center+1);
+        img.init(0.0);
+        img(center, center) = 1.0;
+        SplineImageView<N, double> view(srcImageRange(img), true);
+        BSplineBase<N> spline;
+
+        double epsilon = 1.0e-10;
+        double cx = center-0.42;
+        double cy = center-0.23;
+        shouldEqualTolerance(view(-cx,cy),      view(cx,cy), epsilon);
+        shouldEqualTolerance(view(-cx,cy,1,0), -view(cx,cy,1,0), epsilon);
+        shouldEqualTolerance(view(-cx,cy,0,1),  view(cx,cy,0,1), epsilon);
+        shouldEqualTolerance(view(-cx,cy,1,1), -view(cx,cy,1,1), epsilon);
+
+        shouldEqualTolerance(view(cx,-cy),      view(cx,cy), epsilon);
+        shouldEqualTolerance(view(cx,-cy,1,0),  view(cx,cy,1,0), epsilon);
+        shouldEqualTolerance(view(cx,-cy,0,1), -view(cx,cy,0,1), epsilon);
+        shouldEqualTolerance(view(cx,-cy,1,1), -view(cx,cy,1,1), epsilon);
+
+        shouldEqualTolerance( view(view.width() + cx,cy),
+                              view(view.width() - 2.0 - cx,cy), epsilon);
+        shouldEqualTolerance( view(view.width() + cx,cy,1,0),
+                             -view(view.width() - 2.0 - cx,cy,1,0), epsilon);
+        shouldEqualTolerance( view(view.width() + cx,cy,0,1),
+                              view(view.width() - 2.0 - cx,cy,0,1), epsilon);
+        shouldEqualTolerance( view(view.width() + cx,cy,1,1),
+                             -view(view.width() - 2.0 - cx,cy,1,1), epsilon);
+
+        shouldEqualTolerance( view(cx, view.height() + cy),
+                              view(cx, view.height() - 2.0 - cy), epsilon);
+        shouldEqualTolerance( view(cx, view.height() + cy,1,0),
+                              view(cx, view.height() - 2.0 - cy,1,0), epsilon);
+        shouldEqualTolerance( view(cx, view.height() + cy,0,1),
+                             -view(cx, view.height() - 2.0 - cy,0,1), epsilon);
+        shouldEqualTolerance( view(cx, view.height() + cy,1,1),
+                             -view(cx, view.height() - 2.0 - cy,1,1), epsilon);
+
+        try
+        {
+            view(2*view.width(), 0);
+            failTest("Out-of-range coordinate failed to throw exception");
+        }
+        catch(vigra::PreconditionViolation) {}
+    }
+
+    void testVectorSIV()
+    {
+        // (compile-time only test for now)
+        BRGBImage rgb(20, 10);
+        SplineImageView<N, TinyVector<float, 3> > view(srcImageRange(rgb));
+        (void)view(4.5, 1.3);
+    }
+
+};
+
+struct GeometricTransformsTest
+{
+    typedef vigra::DImage Image;
+    typedef vigra::MultiArrayView<2, double> View;
+    Image img;
+    int w, h;
+
+    GeometricTransformsTest()
+    {
+        ImageImportInfo ginfo("lenna128.xv");
+        w = ginfo.width();
+        h = ginfo.height();
+        img.resize(w, h);
+        importImage(ginfo, destImage(img));
+    }
+
+    void testSimpleGeometry()
+    {
+        Image res1(img.size()), res11(img.size()), res2(h, w), res21(h, w);
+
+        rotateImage(srcImageRange(img), destImage(res1), 180);
+        rotateImage(View(img), View(res11), 180);
+        for(int y = 0; y < 10; ++y)
+            for(int x = 0; x < 10; ++x)
+            {
+                shouldEqual(img(x,y), res1(w-x-1, h-y-1));
+                shouldEqual(img(x,y), res11(w-x-1, h-y-1));
+            }
+        
+        rotateImage(srcImageRange(img), destImage(res2), 90);
+        for(int y = 0; y < 10; ++y)
+            for(int x = 0; x < 10; ++x)
+                shouldEqual(img(x,y), res2(y, w-x-1));
+        rotateImage(srcImageRange(img), destImage(res2), -90);
+        for(int y = 0; y < 10; ++y)
+            for(int x = 0; x < 10; ++x)
+                shouldEqual(img(x,y), res2(h-y-1, x));
+
+
+        try
+        {
+            rotateImage(srcImageRange(img), destImage(res2), 22);
+            failTest("rotateImage() failed to throw exception");
+        }
+        catch(vigra::PreconditionViolation) {}
+
+        transposeImage(srcImageRange(img), destImage(res2), vigra::major);
+        transposeImage(View(img), View(res21), vigra::major);
+        View transposed(View(img).transpose());
+        for(int y = 0; y < 10; ++y)
+            for(int x = 0; x < 10; ++x)
+            {
+                shouldEqual(img(x,y), res2(y, x));
+                shouldEqual(img(x,y), res21(y, x));
+                shouldEqual(transposed(y,x), res21(y,x));
+            }
+
+        transposeImage(srcImageRange(img), destImage(res2), vigra::minor);
+        for(int y = 0; y < 10; ++y)
+            for(int x = 0; x < 10; ++x)
+                shouldEqual(img(x,y), res2(h-y-1, w-x-1));
+
+        reflectImage(srcImageRange(img), destImage(res1), vigra::horizontal);
+        reflectImage(View(img), View(res11), vigra::horizontal);
+        for(int y = 0; y < 10; ++y)
+            for(int x = 0; x < 10; ++x)
+            {
+                shouldEqual(img(x,y), res1(x, h-y-1));
+                shouldEqual(img(x,y), res11(x, h-y-1));
+            }
+
+        reflectImage(srcImageRange(img), destImage(res1), vigra::vertical);
+        for(int y = 0; y < 10; ++y)
+            for(int x = 0; x < 10; ++x)
+                shouldEqual(img(x,y), res1(w-x-1, y));
+        reflectImage(srcImageRange(img), destImage(res1), vigra::horizontal | vigra::vertical);
+        for(int y = 0; y < 10; ++y)
+            for(int x = 0; x < 10; ++x)
+                shouldEqual(img(x,y), res1(w-x-1, h-y-1));
+
+        double xfactor = 3.0;
+        double yfactor = 2.0;
+        Image res3((int)(w*xfactor), (int)(h*yfactor)), res31(res3.size());
+        resampleImage(srcImageRange(img), destImage(res3), xfactor, yfactor);
+        resampleImage(View(img), View(res31), xfactor, yfactor);
+        for(int y = 0; y < 10; ++y)
+            for(int x = 0; x < 10; ++x)
+            {
+                shouldEqual(img(x,y), res3(int(x*xfactor), int(y*yfactor)));
+                shouldEqual(img(x,y), res31(int(x*xfactor), int(y*yfactor)));
+            }
+    }
+
+    void testAffineMatrix()
+    {
+        typedef TinyVector<double, 2> Vector2;
+
+        Matrix<double> point(3,1);
+        point(0,0) = 1.6;
+        point(1,0) = 2.9;
+        point(2,0) = 1.0;
+
+        Matrix<double> t = translationMatrix2D(Vector2(2.2, 4.1));
+        Matrix<double> res = t * point;
+        shouldEqualTolerance(res(0,0), 3.8, 1e-14);
+        shouldEqualTolerance(res(1,0), 7.0, 1e-14);
+        shouldEqual(res(2,0), 1.0);
+
+        Matrix<double> r = rotationMatrix2DDegrees(-90.0);
+        res = r * point;
+        shouldEqualTolerance(res(0,0), 2.9, 1e-14);
+        shouldEqualTolerance(res(1,0), -1.6, 1e-14);
+        shouldEqual(res(2,0), 1.0);
+
+        r = rotationMatrix2DDegrees(-90.0, Vector2(1.6, 2.9));
+        res = r * point;
+        shouldEqualTolerance(res(0,0), 1.6, 1e-14);
+        shouldEqualTolerance(res(1,0), 2.9, 1e-14);
+        shouldEqual(res(2,0), 1.0);
+
+        Matrix<double> s = scalingMatrix2D(2.0);
+        res = s * point;
+        shouldEqualTolerance(res(0,0), 3.2, 1e-14);
+        shouldEqualTolerance(res(1,0), 5.8, 1e-14);
+        shouldEqual(res(2,0), 1.0);
+
+        Matrix<double> sh = shearMatrix2D(2.0, 0.5);
+        res = sh * point;
+        shouldEqualTolerance(res(0,0), 7.4, 1e-14);
+        shouldEqualTolerance(res(1,0), 3.7, 1e-14);
+        shouldEqual(res(2,0), 1.0);
+    }
+
+    void testRotation()
+    {
+        Image res(img.size()), ref(img.size()), res1(img.size());
+        importImage(vigra::ImageImportInfo("lenna_rotate.xv"), destImage(ref));
+
+        SplineImageView<3, double> sp(srcImageRange(img));
+
+        rotateImage(sp, destImage(res), 45.0);
+        shouldEqualSequenceTolerance(res.begin(), res.end(), ref.begin(), 1e-12);
+
+        rotateImage(sp, View(res1), 45.0);
+        shouldEqualSequenceTolerance(res1.begin(), res1.end(), ref.begin(), 1e-12);
+
+        TinyVector<double, 2> center((w-1.0)/2.0, (h-1.0)/2.0);
+        affineWarpImage(sp, destImageRange(res), rotationMatrix2DDegrees(45.0, center));
+        shouldEqualSequenceTolerance(res.begin(), res.end(), ref.begin(), 1e-12);
+
+        affineWarpImage(sp, View(res1), rotationMatrix2DDegrees(45.0, center));
+        shouldEqualSequenceTolerance(res1.begin(), res1.end(), ref.begin(), 1e-12);
+    }
+
+    void testScaling()
+    {
+        Image res(2*w-1, 2*h-1), ref(2*w-1, 2*h-1);
+        resizeImageSplineInterpolation(srcImageRange(img), destImageRange(ref));
+
+        SplineImageView<3, double> sp(srcImageRange(img));
+
+        affineWarpImage(sp, destImageRange(res), scalingMatrix2D(0.5));
+        shouldEqualSequenceTolerance(res.begin(), res.end(), ref.begin(), 1e-14);
+    }
+};
+
+struct ImageFunctionsTestSuite
+: public vigra::test_suite
+{
+    ImageFunctionsTestSuite()
+    : vigra::test_suite("ImageFunctionsTestSuite")
+    {
+        add( testCase( &ImageFunctionsTest::copyImageTest));
+        add( testCase( &ImageFunctionsTest::copyImageIfTest));
+        add( testCase( &ImageFunctionsTest::copyRedBandTest));
+        add( testCase( &ImageFunctionsTest::copyGreenBandTest));
+        add( testCase( &ImageFunctionsTest::copyBlueBandTest));
+        add( testCase( &ImageFunctionsTest::rgbToGrayTest));
+        add( testCase( &ImageFunctionsTest::initImageTest));
+        add( testCase( &ImageFunctionsTest::initImageIfTest));
+        add( testCase( &ImageFunctionsTest::initImageBorderTest));
+        add( testCase( &ImageFunctionsTest::findMinMaxTest));
+        add( testCase( &ImageFunctionsTest::findMinMaxIfTest));
+        add( testCase( &ImageFunctionsTest::findAverageTest));
+        add( testCase( &ImageFunctionsTest::findAverageIfTest));
+        add( testCase( &ImageFunctionsTest::findAverageWeightedTest));
+        add( testCase( &ImageFunctionsTest::findAverageAndVarianceTest));
+        add( testCase( &ImageFunctionsTest::reduceFunctorTest));
+        add( testCase( &ImageFunctionsTest::meshGridTest));
+        add( testCase( &ImageFunctionsTest::findBoundingRectangleTest));
+        add( testCase( &ImageFunctionsTest::lastValueFunctorTest));
+        add( testCase( &ImageFunctionsTest::arrayOfRegionStatisticsTest));
+        add( testCase( &ImageFunctionsTest::arrayOfRegionStatisticsIfTest));
+        add( testCase( &ImageFunctionsTest::writeArrayOfRegionStatisticsTest));
+        add( testCase( &ImageFunctionsTest::linearIntensityTransformTest));
+        add( testCase( &ImageFunctionsTest::scalarIntensityTransformTest));
+        add( testCase( &ImageFunctionsTest::linearIntensityTransformIfTest));
+        add( testCase( &ImageFunctionsTest::linearRangeMappingTest));
+        add( testCase( &ImageFunctionsTest::thresholdTest));
+        add( testCase( &ImageFunctionsTest::brightnessContrastTest));
+        add( testCase( &ImageFunctionsTest::gradientFunctionTest));
+        add( testCase( &ImageFunctionsTest::additionTest));
+        add( testCase( &ImageFunctionsTest::additionIfTest));
+        add( testCase( &ImageFunctionsTest::resizeNoInterpolationTest));
+        add( testCase( &ImageFunctionsTest::resizeLinearInterpolationTest));
+
+        add( testCase( &ResizeImageTest::resizeLinearInterpolationReduceTest));
+        add( testCase( &ResizeImageTest::scalarExpand));
+        add( testCase( &ResizeImageTest::scalarReduce));
+        add( testCase( &ResizeImageTest::rgbExpand));
+        add( testCase( &ResizeImageTest::rgbReduce));
+        add( testCase( &ResizeImageTest::testCatmullRomInterpolationExtensionWithLena));
+        add( testCase( &ResizeImageTest::testCatmullRomInterpolationReductionWithLena));
+        add( testCase( &ResizeImageTest::testCubicInterpolationExtensionWithLena));
+        add( testCase( &ResizeImageTest::testCubicInterpolationReductionWithLena));
+        add( testCase( &ResizeImageTest::testCatmullRomInterpolationExtensionHandControled));
+        add( testCase( &SplineImageViewTest<0>::testPSF));
+        add( testCase( &SplineImageViewTest<0>::testCoefficientArray));
+        add( testCase( &SplineImageViewTest<0>::testImageResize0));
+        add( testCase( &SplineImageViewTest<0>::testOutside));
+        add( testCase( &SplineImageViewTest<1>::testPSF));
+        add( testCase( &SplineImageViewTest<1>::testCoefficientArray));
+        add( testCase( &SplineImageViewTest<1>::testImageResize1));
+        add( testCase( &SplineImageViewTest<1>::testOutside));
+        add( testCase( &SplineImageViewTest<2>::testPSF));
+        add( testCase( &SplineImageViewTest<2>::testCoefficientArray));
+        add( testCase( &SplineImageViewTest<2>::testImageResize));
+        add( testCase( &SplineImageViewTest<2>::testOutside));
+        add( testCase( &SplineImageViewTest<3>::testPSF));
+        add( testCase( &SplineImageViewTest<3>::testCoefficientArray));
+        add( testCase( &SplineImageViewTest<3>::testImageResize));
+        add( testCase( &SplineImageViewTest<3>::testOutside));
+        add( testCase( &SplineImageViewTest<5>::testPSF));
+        add( testCase( &SplineImageViewTest<5>::testCoefficientArray));
+        add( testCase( &SplineImageViewTest<5>::testImageResize));
+        add( testCase( &SplineImageViewTest<5>::testOutside));
+        add( testCase( &SplineImageViewTest<5>::testVectorSIV));
+
+        add( testCase( &GeometricTransformsTest::testSimpleGeometry));
+        add( testCase( &GeometricTransformsTest::testAffineMatrix));
+        add( testCase( &GeometricTransformsTest::testRotation));
+        add( testCase( &GeometricTransformsTest::testScaling));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    ImageFunctionsTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+
+    return (failed != 0);
+}
+
diff --git a/test/impex/CMakeLists.txt b/test/impex/CMakeLists.txt
new file mode 100644
index 0000000..a879d78
--- /dev/null
+++ b/test/impex/CMakeLists.txt
@@ -0,0 +1,21 @@
+IF(JPEG_FOUND)
+  ADD_DEFINITIONS(-DHasJPEG)
+ENDIF(JPEG_FOUND)
+
+IF(PNG_FOUND)
+  ADD_DEFINITIONS(-DHasPNG)
+ENDIF(PNG_FOUND)
+
+IF(TIFF_FOUND)
+  ADD_DEFINITIONS(-DHasTIFF)
+  INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR})
+ENDIF(TIFF_FOUND)
+
+IF(OPENEXR_FOUND)
+  ADD_DEFINITIONS(-DHasEXR)
+ENDIF(OPENEXR_FOUND)
+
+VIGRA_ADD_TEST(test_impex test.cxx LIBRARIES vigraimpex)
+
+VIGRA_COPY_TEST_DATA(lenna.xv lenna_gifref.xv lennafloat.xv lennafloatrgb.xv lennargb.xv no-image.txt lenna_0.tif lenna_1.tif lenna_2.tif lenna_masked_color.tif  lenna_masked_gray.tif)
+
diff --git a/test/impex/lenna.xv b/test/impex/lenna.xv
new file mode 100644
index 0000000..e2d5d37
Binary files /dev/null and b/test/impex/lenna.xv differ
diff --git a/test/impex/lenna_0.tif b/test/impex/lenna_0.tif
new file mode 100644
index 0000000..dccd7ae
Binary files /dev/null and b/test/impex/lenna_0.tif differ
diff --git a/test/impex/lenna_1.tif b/test/impex/lenna_1.tif
new file mode 100644
index 0000000..c7c8e55
Binary files /dev/null and b/test/impex/lenna_1.tif differ
diff --git a/test/impex/lenna_2.tif b/test/impex/lenna_2.tif
new file mode 100644
index 0000000..24fd6f7
Binary files /dev/null and b/test/impex/lenna_2.tif differ
diff --git a/test/impex/lenna_gifref.xv b/test/impex/lenna_gifref.xv
new file mode 100644
index 0000000..18e087d
Binary files /dev/null and b/test/impex/lenna_gifref.xv differ
diff --git a/test/impex/lenna_masked_color.tif b/test/impex/lenna_masked_color.tif
new file mode 100644
index 0000000..a5c0193
Binary files /dev/null and b/test/impex/lenna_masked_color.tif differ
diff --git a/test/impex/lenna_masked_gray.tif b/test/impex/lenna_masked_gray.tif
new file mode 100644
index 0000000..0d67307
Binary files /dev/null and b/test/impex/lenna_masked_gray.tif differ
diff --git a/test/impex/lennafloat.xv b/test/impex/lennafloat.xv
new file mode 100644
index 0000000..e6bd2c8
Binary files /dev/null and b/test/impex/lennafloat.xv differ
diff --git a/test/impex/lennafloatrgb.xv b/test/impex/lennafloatrgb.xv
new file mode 100644
index 0000000..0542e8f
Binary files /dev/null and b/test/impex/lennafloatrgb.xv differ
diff --git a/test/impex/lennargb.xv b/test/impex/lennargb.xv
new file mode 100644
index 0000000..03ec3f4
Binary files /dev/null and b/test/impex/lennargb.xv differ
diff --git a/test/impex/no-image.txt b/test/impex/no-image.txt
new file mode 100644
index 0000000..4ffea8d
--- /dev/null
+++ b/test/impex/no-image.txt
@@ -0,0 +1 @@
+dummy file to test that impex recognizes that this is not an image
diff --git a/test/impex/test.cxx b/test/impex/test.cxx
new file mode 100755
index 0000000..2e70fb9
--- /dev/null
+++ b/test/impex/test.cxx
@@ -0,0 +1,1860 @@
+/************************************************************************/
+/*                                                                      */
+/*           Copyright 2004-2012 by Ullrich Koethe                      */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include "vigra/stdimage.hxx"
+#include "vigra/impex.hxx"
+#include "vigra/impexalpha.hxx"
+#include "vigra/unittest.hxx"
+#include "vigra/multi_array.hxx"
+
+#if HasTIFF
+# include "vigra/tiff.hxx"
+#endif
+
+using namespace vigra;
+
+template <class Image>
+void failCodec(Image const & img, ImageExportInfo const & info)
+{
+    try {
+        exportImage (srcImageRange (img), info);
+        failTest( "Failed to throw exception." );
+    }
+    catch( vigra::PreconditionViolation & e )
+    {
+        std::string expected = "\nPrecondition violation!\n";
+        expected += "did not find a matching codec for the given file extension";
+        const bool rc = std::strncmp( expected.c_str(), e.what(), expected.length() ) == 0;
+        should(rc);
+    }
+}
+
+class ByteImageExportImportTest
+{
+    typedef vigra::BImage Image;
+    typedef vigra::MultiArrayView<2, unsigned char> View;
+
+public:
+
+    ByteImageExportImportTest ()
+    {
+        vigra::ImageImportInfo info ("lenna.xv");
+
+        const int w = info.width ();
+        const int h = info.height ();
+
+        img.resize (w, h);
+
+        importImage (info, destImage (img));
+    }
+
+    void testListFormatsExtensions()
+    {
+        const std::string formats = impexListFormats();
+        const std::string extensions = impexListExtensions();
+
+        const char * refFormats = "BMP "
+#if defined(HasEXR)
+        "EXR "
+#endif
+        "GIF HDR "
+#if defined(HasJPEG)
+        "JPEG "
+#endif
+#if defined(HasPNG)
+        "PNG "
+#endif
+        "PNM SUN "
+#if defined(HasTIFF)
+        "TIFF "
+#endif
+        "VIFF";
+        shouldEqual(formats, refFormats);
+
+        const char * refExtensions = "bmp "
+#if defined(HasEXR)
+        "exr "
+#endif
+        "gif hdr "
+#if defined(HasJPEG)
+        "jpeg jpg "
+#endif
+        "pbm pgm "
+#if defined(HasPNG)
+        "png "
+#endif
+        "pnm ppm ras "
+#if defined(HasTIFF)
+        "tif tiff "
+#endif
+        "xv";
+        shouldEqual(extensions, refExtensions);
+    }
+
+    void testIsImage()
+    {
+        should(isImage("lenna.xv"));
+        should(!isImage("no-image.txt"));
+        should(!isImage("filename-does-not-exist.gif"));
+    }
+
+    void testFile (const char *filename);
+
+    void testGIF ()
+    {
+        exportImage (View(img), "res.gif");
+
+        vigra::ImageImportInfo info ("res.gif");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isGrayscale ());
+        should (info.pixelType () == vigra::ImageImportInfo::UINT8);
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, View (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        float sum = 0;
+        for (; i != img.end (); ++i, ++i1)
+            sum += std::abs (acc (i) - acc (i1));
+
+        should (sum / (info.width () * info.height ()) < 0.1);
+
+        MultiArray<2, unsigned char> res1;
+        importImage("res.gif", res1);
+        should(res1 == View(res));
+    }
+
+    void testGrayToRGB()
+    {
+        MultiArray<2, RGBValue<unsigned char> > rgb;
+
+        importImage("lenna.xv", rgb);
+
+        should (rgb.shape(0) == img.width());
+        should (rgb.shape(1) == img.height());
+        shouldEqualSequence(img.begin(), img.end(), rgb.bindElementChannel(0).begin());
+        shouldEqualSequence(img.begin(), img.end(), rgb.bindElementChannel(1).begin());
+        shouldEqualSequence(img.begin(), img.end(), rgb.bindElementChannel(2).begin());
+    }
+
+    void testJPEG ()
+    {
+        vigra::ImageExportInfo exportinfo ("res.jpg");
+#if !defined(HasJPEG)
+        failCodec(img, exportinfo);
+#else
+        exportinfo.setCompression ("JPEG QUALITY=100");
+        exportImage (srcImageRange (img), exportinfo);
+
+        vigra::ImageImportInfo info ("res.jpg");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isGrayscale ());
+        should (info.pixelType () == vigra::ImageImportInfo::UINT8);
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        float sum = 0;
+        for (; i != img.end (); ++i, ++i1)
+            sum += std::abs (acc (i) - acc (i1));
+
+        should (sum / (info.width () * info.height ()) < 0.1);
+#endif
+    }
+
+    void testTIFF ()
+    {
+        vigra::ImageExportInfo exportinfo ("res.tif");
+#if !defined(HasTIFF)
+        failCodec(img, exportinfo);
+#else
+        exportinfo.setCompression ("LZW");
+        exportImage (srcImageRange (img), exportinfo);
+
+        vigra::ImageImportInfo info ("res.tif");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isGrayscale ());
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            should (acc (i) == acc (i1));
+
+        TiffImage * tiff = TIFFOpen("res2.tif", "w");
+        createTiffImage(View(img), tiff);
+        TIFFClose(tiff);
+
+        uint32 w, h;
+        tiff = TIFFOpen("res2.tif", "r");
+        TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
+        TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
+        shouldEqual(w, img.width());
+        shouldEqual(h, img.height());
+    
+        MultiArray<2, unsigned char> res2(w,h);
+        importTiffImage(tiff, res2);
+        TIFFClose(tiff);
+
+        shouldEqualSequence(res2.begin(), res2.end(), img.data());
+#endif
+    }
+
+    void testTIFFSequence()
+    {
+#if defined(HasTIFF)
+        for (int i=0; i < 3; ++i)
+        {
+            std::string fileName = std::string("lenna_") + vigra::asString(i) + ".tif";
+            vigra::ImageImportInfo ininfo (fileName.c_str());
+            Image inimg(ininfo.width(), ininfo.height());
+            importImage(ininfo, destImage(inimg));
+            vigra::ImageExportInfo outinfo ("resseq.tif", i==0?"w":"a");
+            exportImage(srcImageRange(inimg), outinfo);
+        }
+
+        for (int j=0; j < 3; ++j)
+        {
+            vigra::ImageImportInfo ininfo ("resseq.tif", j);
+            Image inimg(ininfo.width(), ininfo.height());
+            std::string fileName = std::string("lenna_") + vigra::asString(j) + ".tif";
+            importImage(ininfo, destImage(inimg));
+            vigra::ImageImportInfo originfo (fileName.c_str());
+            Image origimg(originfo.width(), originfo.height());
+            importImage(originfo, destImage(origimg));
+
+            Image::ScanOrderIterator it = inimg.begin ();
+            Image::ScanOrderIterator it1 = origimg.begin ();
+            Image::Accessor acc = inimg.accessor ();
+            for (; it != inimg.end (); ++it, ++it1)
+                should (acc (it) == acc (it1));
+        }
+#endif
+    }
+
+    void testBMP ()
+    {
+        testFile ("res.bmp");
+    }
+
+    void testPGM ()
+    {
+        testFile ("res.pgm");
+    }
+
+    void testPNM ()
+    {
+        testFile ("res.pnm");
+    }
+
+    void testPNM2 ()
+    {
+        vigra::ImageExportInfo exportinfo ("res.pgm");
+        exportinfo.setCompression ("ASCII");
+        exportImage (srcImageRange (img), exportinfo);
+
+        vigra::ImageImportInfo info ("res.pgm");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isGrayscale ());
+        should (info.getPixelType () == std::string ("UINT8"));
+        should (info.getFileType () == std::string ("PNM"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            should (acc (i) == acc (i1));
+    }
+
+    void testPNG ()
+    {
+#if !defined(HasPNG)
+        failCodec(img, vigra::ImageExportInfo("res.png"));
+#else
+        testFile ("res.png");
+#endif
+    }
+
+    void testSUN ()
+    {
+        testFile ("res.ras");
+    }
+
+    void testVIFF1 ()
+    {
+        testFile ("res.xv");
+    }
+
+    void testVIFF2 ()
+    {
+        vigra::ImageExportInfo exportinfo ("res.foo");
+        exportinfo.setFileType ("VIFF");
+        exportImage (srcImageRange (img), exportinfo);
+
+        vigra::ImageImportInfo info ("res.foo");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isGrayscale ());
+        should (info.getPixelType () == std::string ("UINT8"));
+        should (info.getFileType () == std::string ("VIFF"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            should (acc (i) == acc (i1));
+    }
+
+    Image img;
+};
+
+void
+ByteImageExportImportTest::testFile (const char *filename)
+{
+    exportImage (srcImageRange (img), vigra::ImageExportInfo (filename));
+
+    vigra::ImageImportInfo info (filename);
+
+    should (info.width () == img.width ());
+    should (info.height () == img.height ());
+    should (info.isGrayscale ());
+    should (info.getPixelType () == std::string ("UINT8"));
+
+    Image res (info.width (), info.height ());
+
+    importImage (info, destImage (res));
+
+    Image::ScanOrderIterator i = img.begin ();
+    Image::ScanOrderIterator i1 = res.begin ();
+    Image::Accessor acc = img.accessor ();
+
+    for (; i != img.end (); ++i, ++i1)
+        should (acc (i) == acc (i1));
+}
+
+
+class ByteRGBImageExportImportTest
+{
+    typedef vigra::BRGBImage Image;
+public:
+    ByteRGBImageExportImportTest ()
+    {
+        vigra::ImageImportInfo info ("lennargb.xv");
+
+        int w = info.width ();
+        int h = info.height ();
+
+        img.resize (w, h);
+
+        importImage (info, destImage (img));
+    }
+
+    void testFile (const char *fileName);
+
+    void testGIF ()
+    {
+        exportImage (srcImageRange (img), vigra::ImageExportInfo ("resrgb.gif"));
+
+        vigra::ImageImportInfo info ("resrgb.gif");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.pixelType () == vigra::ImageImportInfo::UINT8);
+
+        Image res (info.width (), info.height ());
+        Image ref (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+        importImage (vigra::ImageImportInfo("lenna_gifref.xv"), destImage (ref));
+
+        Image::ScanOrderIterator i = ref.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = ref.accessor ();
+
+        double sum = 0.0;
+        for (; i != ref.end (); ++i, ++i1)
+                sum += (acc (i) - acc (i1)).magnitude ();
+
+        should (sum / (info.width () * info.height ()) < 4.0);  // use rather large tolerance to make the
+                                                                // test portable
+    }
+
+    void testJPEG ()
+    {
+#if !defined(HasJPEG)
+        failCodec(img, vigra::ImageExportInfo ("res.jpg").setCompression ("JPEG QUALITY=100"));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.jpg").setCompression ("JPEG QUALITY=100"));
+
+        vigra::ImageImportInfo info ("res.jpg");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        double sum = 0.0;
+        for (; i != img.end (); ++i, ++i1)
+            {
+                sum += (acc (i) - acc (i1)).magnitude ();
+            }
+        should (sum / (info.width () * info.height ()) < 2.0);
+#endif
+    }
+
+    void testTIFF ()
+    {
+#if !defined(HasTIFF)
+        failCodec(img, vigra::ImageExportInfo ("res.tif").setCompression ("LZW"));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.tif").
+                     setCompression ("LZW"));
+
+        vigra::ImageImportInfo info ("res.tif");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            {
+                should (acc (i) == acc (i1));
+            }
+
+        TiffImage * tiff = TIFFOpen("res2.tif", "w");
+        createTiffImage(MultiArrayView<2, RGBValue<unsigned char> >(img), tiff);
+        TIFFClose(tiff);
+
+        uint32 w, h;
+        tiff = TIFFOpen("res2.tif", "r");
+        TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
+        TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
+        shouldEqual(w, img.width());
+        shouldEqual(h, img.height());
+    
+        MultiArray<2, RGBValue<unsigned char> > res2(w,h);
+        importTiffImage(tiff, res2);
+        TIFFClose(tiff);
+
+        shouldEqualSequence(res2.begin(), res2.end(), img.data());
+#endif
+    }
+
+    void testBMP ()
+    {
+        testFile ("res.bmp");
+    }
+
+    void testPPM ()
+    {
+        testFile ("res.ppm");
+    }
+
+    void testPNM ()
+    {
+        testFile ("res.pnm");
+    }
+
+
+    void testPNM2 ()
+    {
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.ppm").setCompression ("ASCII"));
+
+        vigra::ImageImportInfo info ("res.ppm");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("UINT8"));
+        should (info.getFileType () == std::string ("PNM"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            should (acc (i) == acc (i1));
+    }
+
+    void testPNG ()
+    {
+#if !defined(HasPNG)
+        failCodec(img, vigra::ImageExportInfo("res.png"));
+#else
+        testFile ("res.png");
+#endif
+    }
+
+    void testSUN ()
+    {
+        testFile ("res.ras");
+    }
+
+    void testVIFF1 ()
+    {
+        testFile ("res.xv");
+    }
+
+    void testVIFF2 ()
+    {
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.foo").setFileType ("VIFF"));
+
+        vigra::ImageImportInfo info ("res.foo");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("UINT8"));
+        should (info.getFileType () == std::string ("VIFF"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            should (acc (i) == acc (i1));
+    }
+
+    Image img;
+};
+
+void
+ByteRGBImageExportImportTest::testFile (const char *fileName)
+{
+    exportImage (srcImageRange (img), vigra::ImageExportInfo (fileName));
+
+    vigra::ImageImportInfo info (fileName);
+
+    should (info.width () == img.width ());
+    should (info.height () == img.height ());
+    should (info.isColor ());
+    should (info.getPixelType () == std::string ("UINT8"));
+
+    Image res (info.width (), info.height ());
+
+    importImage (info, destImage (res));
+
+    Image::ScanOrderIterator i = img.begin ();
+    Image::ScanOrderIterator i1 = res.begin ();
+    Image::Accessor acc = img.accessor ();
+
+    for (; i != img.end (); ++i, ++i1)
+        should (acc (i) == acc (i1));
+}
+
+class CanvasSizeTest
+{
+  public:
+    void testTIFFCanvasSize ()
+    {
+        vigra::ImageExportInfo exportinfo ("res.tif");
+        FRGBImage img(1, 1);
+#if !defined(HasTIFF)
+        failCodec(img, exportinfo);
+#else
+        img(0,0) = 1;
+        exportinfo.setCompression ("LZW");
+        Size2D canvasSize(3, 8);
+        exportinfo.setCanvasSize (canvasSize);
+        exportImage (srcImageRange (img), exportinfo);
+
+        vigra::ImageImportInfo info ("res.tif");
+
+        should (info.getCanvasSize () == canvasSize);
+#endif
+    }
+};
+
+class PNGInt16Test
+{
+  public:
+    void testByteOrder()
+    {
+        UInt16Image i(1,1);
+        i(0,0) = 1;
+        exportImage(srcImageRange(i), ImageExportInfo("res.png"));
+        ImageImportInfo info("res.png");
+        shouldEqual(info.width(), 1);
+        shouldEqual(info.height(), 1);
+        shouldEqual(info.numBands(), 1);
+        shouldEqual(info.isGrayscale(), true);
+        shouldEqual(std::string(info.getPixelType()), std::string("UINT16"));
+        i(0,0) = 0;
+        importImage(info, destImage(i));
+        shouldEqual(i(0,0), 1);
+
+        // DGSW: Note that this produces a PNG standard conformant image
+        //       but both Imagemagick 'identify' and photoshop CS2 see
+        //       the data incorrectly
+        BasicImage<RGBValue<unsigned short> > rgb(1,1);
+        // Using unsigned values 0xff01, 0xfff1, 0xfffd
+        rgb(0,0) = RGBValue<unsigned short>(65281,65521,65533);
+        // Using unsigned values 0x7f01, 0x7ff1, 0x7ffd
+        // rgb(0,0) = RGBValue<unsigned short>(32513,32753,32765);
+        exportImage(srcImageRange(rgb), ImageExportInfo("res.png"));
+        ImageImportInfo rgbinfo("res.png");
+        shouldEqual(rgbinfo.width(), 1);
+        shouldEqual(rgbinfo.height(), 1);
+        shouldEqual(rgbinfo.numBands(), 3);
+        shouldEqual(std::string(rgbinfo.getPixelType()), std::string("UINT16"));
+        rgb(0,0) = RGBValue<short>(0,0,0);
+        importImage(rgbinfo, destImage(rgb));
+        shouldEqual(rgb(0,0), RGBValue<unsigned short>(65281,65521,65533));
+//        shouldEqual(rgb(0,0), RGBValue<unsigned short>(32513,32753,32765));
+    }
+};
+
+class FloatImageExportImportTest
+{
+    typedef vigra::DImage Image;
+    std::string rereadType;
+
+public:
+
+    FloatImageExportImportTest ()
+    : rereadType("DOUBLE")
+    {
+        vigra::ImageImportInfo info ("lenna.xv");
+
+        int w = info.width ();
+        int h = info.height ();
+
+        img.resize (w, h);
+
+        importImage (info, destImage (img));
+
+        vigra::ImageImportInfo rinfo ("lennafloat.xv");
+
+        reread.resize (w, h);
+
+        importImage (rinfo, destImage (reread));
+    }
+
+    void testGIF()
+    {
+        exportImage (srcImageRange (img), vigra::ImageExportInfo ("res.gif"));
+
+        vigra::ImageImportInfo info ("res.gif");
+
+        should (info.width () == reread.width ());
+        should (info.height () == reread.height ());
+        should (info.isGrayscale ());
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = reread.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = reread.accessor ();
+
+        double sum = 0.0;
+        for (; i != reread.end (); ++i, ++i1)
+            sum += std::abs (acc (i) - acc (i1));
+        should (sum / (info.width () * info.height ()) < 0.1);
+    }
+
+    void testJPEG ()
+    {
+#if !defined(HasJPEG)
+        failCodec(img, vigra::ImageExportInfo ("res.jpg").setCompression ("JPEG QUALITY=100"));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.jpg").setCompression ("JPEG QUALITY=100"));
+
+        vigra::ImageImportInfo info ("res.jpg");
+
+        should (info.width () == reread.width ());
+        should (info.height () == reread.height ());
+        should (info.isGrayscale ());
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = reread.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = reread.accessor ();
+
+        double sum = 0.0;
+        for (; i != reread.end (); ++i, ++i1)
+            sum += std::abs (acc (i) - acc (i1));
+        should (sum / (info.width () * info.height ()) < 0.1);
+#endif
+    }
+
+    void testPNG ()
+    {
+#if !defined(HasPNG)
+        failCodec(img, vigra::ImageExportInfo ("res.png"));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res_.png"));
+
+        vigra::ImageImportInfo info ("res_.png");
+
+        should (info.width () == reread.width ());
+        should (info.height () == reread.height ());
+        should (info.isGrayscale ());
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = reread.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = reread.accessor ();
+
+        double sum = 0.0;
+        for (; i != reread.end (); ++i, ++i1)
+            sum += std::abs (acc (i) - acc (i1));
+        should (sum / (info.width () * info.height ()) < 0.1);
+#endif
+    }
+
+    void testTIFF ()
+    {
+#if !defined(HasTIFF)
+        failCodec(img, vigra::ImageExportInfo ("res.tif").setCompression ("LZW"));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.tif").setCompression ("LZW"));
+
+        vigra::ImageImportInfo info ("res.tif");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isGrayscale ());
+        should (info.getPixelType () == rereadType);
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        //Image::Accessor acc = img.accessor ();
+
+        shouldEqualSequence(i, img.end(), i1);
+#endif
+    }
+
+    void testTIFFForcedRange ()
+    {
+#if !defined(HasTIFF)
+        failCodec(img, vigra::ImageExportInfo ("res.tif").setForcedRangeMapping(0, 255, 1, 2));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.tif").setForcedRangeMapping(0, 255, 1, 2));
+
+        vigra::ImageImportInfo info ("res.tif");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isGrayscale ());
+        should (info.getPixelType () == rereadType);
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            shouldEqualTolerance(acc (i) / 255.0, acc (i1) - 1.0, 1e-12);
+#endif
+    }
+
+    void testBMP ()
+    {
+        exportImage (srcImageRange (img), vigra::ImageExportInfo ("res.bmp"));
+
+        vigra::ImageImportInfo info ("res.bmp");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isGrayscale ());
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = reread.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = reread.accessor ();
+
+        for (; i != reread.end (); ++i, ++i1)
+            should (acc (i) == acc (i1));
+    }
+
+    void testSUN ()
+    {
+        exportImage (srcImageRange (img), vigra::ImageExportInfo ("res.ras"));
+
+        vigra::ImageImportInfo info ("res.ras");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isGrayscale ());
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = reread.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = reread.accessor ();
+
+        for (; i != reread.end (); ++i, ++i1)
+            {
+                should (acc (i) == acc (i1));
+            }
+    }
+
+    void testVIFF ()
+    {
+        exportImage (srcImageRange (img), vigra::ImageExportInfo ("res.xv"));
+
+        vigra::ImageImportInfo info ("res.xv");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isGrayscale ());
+        should (info.getPixelType () == rereadType);
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            {
+                should (acc (i) == acc (i1));
+            }
+    }
+
+    Image img, reread;
+};
+
+class FloatRGBImageExportImportTest
+{
+    typedef vigra::FRGBImage Image;
+    Image img, reread;
+
+public:
+
+    FloatRGBImageExportImportTest ()
+    {
+        vigra::ImageImportInfo info ("lennargb.xv");
+
+        int w = info.width ();
+        int h = info.height ();
+
+        img.resize (w, h);
+
+        importImage (info, destImage (img));
+
+        vigra::ImageImportInfo rinfo ("lennafloatrgb.xv");
+
+        reread.resize (w, h);
+
+        importImage (rinfo, destImage (reread));
+    }
+
+    void testJPEG ()
+    {
+#if !defined(HasJPEG)
+        failCodec(img, vigra::ImageExportInfo ("res.jpg").setCompression ("JPEG QUALITY=100"));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.jpg").setCompression ("JPEG QUALITY=100"));
+
+        vigra::ImageImportInfo info ("res.jpg");
+
+        should (info.width () == reread.width ());
+        should (info.height () == reread.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = reread.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = reread.accessor ();
+
+        float sum = 0.0f;
+        for (; i != reread.end (); ++i, ++i1)
+            sum += (acc (i) - acc (i1)).magnitude ();
+        should (sum / (info.width () * info.height ()) < 2.0f);
+#endif
+    }
+
+    void testTIFF ()
+    {
+#if !defined(HasTIFF)
+        failCodec(img, vigra::ImageExportInfo ("res.tif"));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.tif"));
+
+        vigra::ImageImportInfo info ("res.tif");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("FLOAT"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            shouldEqual (acc (i), acc (i1));
+#endif
+    }
+
+    void testTIFFForcedRange ()
+    {
+#if !defined(HasTIFF)
+        failCodec(img, vigra::ImageExportInfo ("res.tif").setForcedRangeMapping(0, 255, 1, 2));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.tif").setForcedRangeMapping(0,255,1,2));
+
+        vigra::ImageImportInfo info ("res.tif");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("FLOAT"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+        {
+            shouldEqualTolerance(acc.red(i)/255.0f, acc.red(i1)-1.0f, 1e-4);
+            shouldEqualTolerance(acc.green(i)/255.0f, acc.green(i1)-1.0f, 1e-4);
+            shouldEqualTolerance(acc.blue(i)/255.0f, acc.blue(i1)-1.0f, 1e-4);
+        }
+#endif
+    }
+
+    void testBMP ()
+    {
+        exportImage (srcImageRange (img), vigra::ImageExportInfo ("res.bmp"));
+
+        vigra::ImageImportInfo info ("res.bmp");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = reread.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = reread.accessor ();
+
+        float sum = 0.0f;
+        for (; i != reread.end (); ++i, ++i1)
+            sum += (acc (i) - acc (i1)).magnitude ();
+        should (sum / (info.width () * info.height ()) < 2.0f);
+    }
+
+    void testSUN ()
+    {
+        exportImage (srcImageRange (img), vigra::ImageExportInfo ("res.ras"));
+
+        vigra::ImageImportInfo info ("res.ras");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = reread.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = reread.accessor ();
+
+        float sum = 0.0f;
+        for (; i != reread.end (); ++i, ++i1)
+            sum += (acc (i) - acc (i1)).magnitude ();
+        should (sum / (info.width () * info.height ()) < 2.0f);
+    }
+
+    void testVIFF ()
+    {
+        exportImage (srcImageRange (img), vigra::ImageExportInfo ("res.xv"));
+
+        vigra::ImageImportInfo info ("res.xv");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("FLOAT"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            should (acc (i) == acc (i1));
+    }
+
+    void testHDR ()
+    {
+        vigra::ImageExportInfo exi("res.hdr");
+
+        exportImage (srcImageRange (img), exi );
+
+        vigra::ImageImportInfo info ("res.hdr");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("FLOAT"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            shouldEqual (acc (i), acc (i1));
+    }
+
+};
+
+class Vector4ExportImportTest
+{
+  public:
+
+    typedef vigra::FVector4Image Image;
+    typedef vigra::BasicImage<TinyVector<UInt8, 4> > BImage;
+    Image img, reread;
+    BImage breread, breference;
+
+public:
+
+    Vector4ExportImportTest ()
+    : img(2,3),
+      reread(2,3),
+      breread(2,3),
+      breference(2,3)
+    {
+        double scale = 255.0 / 11.0;
+        double offset = 5.5;
+        for(int y = 0; y<3; ++y)
+        {
+            for(int x=0; x<2; ++x)
+            {
+                img(x,y)[0] = 2*y+x + 0.5f;
+                img(x,y)[1] = -img(x,y)[0];
+                img(x,y)[2] = 0.0;
+                img(x,y)[3] = 0.5;
+                for(int b=0; b<4; ++b)
+                {
+                    breference(x,y)[b] =
+                        NumericTraits<UInt8>::fromRealPromote(scale*(img(x,y)[b]+offset));
+                }
+            }
+        }
+    }
+
+    void failingTest (char const * filename,
+                      char const * message = "exportImage(): file format does not support requested number of bands (color channels)")
+    {
+        try
+        {
+            exportImage( srcImageRange(img), vigra::ImageExportInfo( filename ) );
+            failTest( "Failed to throw exception." );
+        }
+        catch( vigra::PreconditionViolation & e )
+        {
+            std::string expected = "\nPrecondition violation!\n";
+            expected += message;
+            const bool rc = std::strncmp( expected.c_str(), e.what(), expected.length() ) == 0;
+            should(rc);
+        }
+    }
+
+    void testJPEG ()
+    {
+#if !defined(HasJPEG)
+        failingTest("res.jpg", "did not find a matching codec for the given file extension");
+#else
+        failingTest("res.jpg");
+#endif
+    }
+
+    void testGIF ()
+    {
+        failingTest("res.gif");
+    }
+
+    void testBMP ()
+    {
+        failingTest("res.bmp");
+    }
+
+    void testPNM ()
+    {
+        failingTest("res.pnm");
+    }
+
+    void testSUN ()
+    {
+        failingTest("res.ras");
+    }
+
+    void testVIFF ()
+    {
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.xv"));
+
+        vigra::ImageImportInfo info ("res.xv");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.numBands () == 4);
+        should (info.getPixelType () == std::string ("FLOAT"));
+
+        importImage (info, destImage (reread));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = reread.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            shouldEqual (acc (i), acc (i1));
+    }
+
+    void testTIFF ()
+    {
+#if !defined(HasTIFF)
+        failCodec(img, vigra::ImageExportInfo ("res.tif"));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.tif"));
+
+        vigra::ImageImportInfo info ("res.tif");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.numBands () == 4);
+        should (info.getPixelType () == std::string ("FLOAT"));
+
+        importImage (info, destImage (reread));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = reread.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            shouldEqual (acc (i), acc (i1));
+#endif
+    }
+
+    void testEXR ()
+    {
+#if !defined(HasEXR)
+        failCodec(img, vigra::ImageExportInfo ("res.exr"));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.exr"));
+
+        vigra::ImageImportInfo info ("res.exr");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.isColor ());
+        should (info.getPixelType () == std::string ("FLOAT"));
+
+        Image res (info.width (), info.height ());
+
+        importImage (info, destImage (res));
+
+        Image::ScanOrderIterator i = img.begin ();
+        Image::ScanOrderIterator i1 = res.begin ();
+        Image::Accessor acc = img.accessor ();
+
+        for (; i != img.end (); ++i, ++i1)
+            shouldEqual (acc (i), acc (i1));
+#endif
+    }
+
+    void testPNG ()
+    {
+#if !defined(HasPNG)
+        failCodec(img, vigra::ImageExportInfo("res.png"));
+#else
+        exportImage (srcImageRange (img),
+                     vigra::ImageExportInfo ("res.png"));
+
+        vigra::ImageImportInfo info ("res.png");
+
+        should (info.width () == img.width ());
+        should (info.height () == img.height ());
+        should (info.numBands () == 4);
+        should (info.getPixelType () == std::string ("UINT8"));
+
+        importImage (info, destImage (breread));
+
+        BImage::ScanOrderIterator i = breference.begin ();
+        BImage::ScanOrderIterator i1 = breread.begin ();
+        BImage::Accessor acc = breference.accessor ();
+
+        for (; i != breference.end (); ++i, ++i1)
+        {
+            should ((acc (i)- acc (i1)).magnitude() <= 1.0);
+        }
+#endif
+    }
+};
+
+
+class ImageExportImportFailureTest
+{
+    vigra::BImage img;
+
+public:
+
+    ImageExportImportFailureTest()
+        : img( 3, 3 )
+    {}
+
+    // gif
+
+    void testGIFExport()
+    {
+        testExport("gif");
+    }
+
+    void testGIFImport()
+    {
+        testImport("gif");
+    }
+
+    // jpeg
+
+    void testJPEGExport()
+    {
+#if !defined(HasJPEG)
+        testExport("jpg", "did not find a matching codec for the given file extension");
+#else
+        testExport("jpg");
+#endif
+    }
+
+    void testJPEGImport()
+    {
+        testImport("jpg");
+    }
+
+    // tiff
+
+    void testTIFFExport()
+    {
+#if !defined(HasTIFF)
+        testExport("tiff", "did not find a matching codec for the given file extension");
+#else
+        testExport("tiff");
+#endif
+    }
+
+    void testTIFFImport()
+    {
+        testImport("tiff");
+    }
+
+    // exr
+
+    void testEXRExport()
+    {
+#if !defined(HasEXR)
+        testExport("exr", "did not find a matching codec for the given file extension");
+#else
+        testExport("exr");
+#endif
+    }
+
+    // viff
+
+    void testVIFFExport()
+    {
+        testExport("xv");
+    }
+
+    void testVIFFImport()
+    {
+        testImport("xv");
+    }
+
+    // sun
+
+    void testSUNExport()
+    {
+        testExport("ras");
+    }
+
+    void testSUNImport()
+    {
+        testImport("ras");
+    }
+
+    // pnm
+
+    void testPNMExport()
+    {
+        testExport("pnm");
+    }
+
+    void testPNMImport()
+    {
+        testImport("pnm");
+    }
+
+    // png
+
+    void testPNGExport()
+    {
+#if !defined(HasPNG)
+        testExport("png", "did not find a matching codec for the given file extension");
+#else
+        testExport("png");
+#endif
+    }
+
+    void testPNGImport()
+    {
+        testImport("png");
+    }
+
+    // bmp
+
+    void testBMPExport()
+    {
+        testExport("bmp");
+    }
+
+    void testBMPImport()
+    {
+        testImport("bmp");
+    }
+
+    // test implementation
+
+    void testImport( const char * fext )
+    {
+        std::string fname = "foo.";
+        fname += fext;
+        try {
+            vigra::ImageImportInfo info( fname.c_str() );
+            failTest( "Failed to throw exception." );
+        }
+        catch( vigra::PreconditionViolation & e ) {
+            std::string expected = "\nPrecondition violation!\n";
+            expected += "Unable to open file '";
+            expected += fname;
+            expected += "'.";
+            const bool rc = std::strncmp( expected.c_str(), e.what(), expected.length() ) == 0;
+            should(rc);
+        }
+    }
+
+    void testExport( const char * fext ,
+                     const char * message = 0)
+    {
+        std::string fname = "intentionalFailure/foo.";
+        fname += fext;
+        try {
+            exportImage( srcImageRange(img), vigra::ImageExportInfo( fname.c_str() ) );
+            failTest( "Failed to throw exception." );
+        }
+        catch( vigra::PreconditionViolation & e ) {
+            std::string expected = "\nPrecondition violation!\n";
+            if(message)
+            {
+                expected += message;
+            }
+            else
+            {
+                expected += "Unable to open file '";
+                expected += fname;
+                expected += "'.";
+            }
+            const bool rc = std::strncmp( expected.c_str(), e.what(), expected.length() ) == 0;
+            should(rc);
+        }
+    }
+
+    void testShapeMismatch ()
+    {
+        MultiArray<2, RGBValue<UInt8> > rgb(1,1);
+
+        try {
+            importImage(ImageImportInfo("lennargb.xv"), rgb);
+            failTest( "Failed to throw exception." );
+        }
+        catch( vigra::PreconditionViolation & e ) {
+            std::string expected = "\nPrecondition violation!\nimportImage(): shape mismatch between input and output.";
+            const bool rc = std::strncmp( expected.c_str(), e.what(), expected.length() ) == 0;
+            should(rc);
+        }
+
+        MultiArray<2, TinyVector<UInt8, 4> > vec4;
+        
+        try {
+            importImage("lennargb.xv", vec4);
+            failTest( "Failed to throw exception." );
+        }
+        catch( vigra::PreconditionViolation & e ) {
+            std::string expected = "\nPrecondition violation!\nimportImage(): Number of channels in input and destination image don't match.";
+            const bool rc = std::strncmp( expected.c_str(), e.what(), expected.length() ) == 0;
+            should(rc);
+        }
+    }
+};
+
+class GrayscaleImportExportAlphaTest
+{
+public:
+    GrayscaleImportExportAlphaTest()
+    {
+#if defined(HasTIFF)
+        vigra::ImageImportInfo info("lenna_masked_gray.tif");
+        
+        image_.resize(info.size());
+        alpha_.resize(info.size());
+        importImageAlpha(info, destImage(image_), destImage(alpha_));
+#else
+        image_.resize(Size2D(20,10));
+        alpha_.resize(image_.size());
+        
+        image_.init(10);
+        alpha_.init(255);
+#endif
+    }
+
+    void testFile(const char* filename);
+    void testFileMultiArray(const char* filename);
+
+    void testTIFF()
+    {
+        const char filename[] = "res.tif";
+
+#if defined(HasTIFF)
+        testFile(filename);
+        testFileMultiArray(filename);
+#else
+        failCodec(image_, vigra::ImageExportInfo(filename));
+#endif
+    }
+
+    void testPNG()
+    {
+        const char filename[] = "res.png";
+
+#if defined(HasPNG)
+        testFile(filename);
+        testFileMultiArray(filename);
+#else
+        failCodec(image_, vigra::ImageExportInfo(filename));
+#endif
+    }
+
+private:
+    BImage image_;
+    BImage alpha_;
+};
+
+void
+GrayscaleImportExportAlphaTest::testFile(const char* filename)
+{
+    exportImageAlpha(srcImageRange(image_), srcImage(alpha_), vigra::ImageExportInfo(filename));
+
+    vigra::ImageImportInfo info(filename);
+
+    should(info.width() == image_.width());
+    should(info.height() == image_.height());
+    should(!info.isColor());
+    should(!strcmp(info.getPixelType(), "UINT8"));
+    should(info.numBands() == 2);
+
+    should(info.width() == alpha_.width());
+    should(info.height() == alpha_.height());
+    should(info.numExtraBands() == 1);
+
+    BImage image(info.size());
+    BImage alpha(info.size());
+
+    importImageAlpha(info, destImage(image), destImage(alpha));
+
+    for (BImage::const_iterator x = alpha_.begin(), xx = alpha_.begin(); x != alpha_.end(); ++x, ++xx)
+    {
+        should(*x == 255);
+        should(*x == *xx);
+    }
+
+    for (BImage::const_iterator x = image_.begin(), xx = image.begin(); x != image_.end(); ++x, ++xx)
+    {
+        should(*x == *xx);
+    }
+}
+
+void
+GrayscaleImportExportAlphaTest::testFileMultiArray(const char* filename)
+{
+    typedef MultiArrayView<2, unsigned char> View;
+
+    exportImageAlpha(View(image_), View(alpha_), vigra::ImageExportInfo(filename));
+
+    vigra::ImageImportInfo info(filename);
+    MultiArray<2, unsigned char> image(info.shape()),
+                                 alpha(info.shape());
+
+    importImageAlpha(info, image, alpha);
+
+    MultiArray<2, unsigned char>::iterator xx = alpha.begin();
+    for (BImage::const_iterator x = alpha_.begin(); x != alpha_.end(); ++x, ++xx)
+    {
+        should(*x == 255);
+        should(*x == *xx);
+    }
+
+    xx = image.begin();
+    for (BImage::const_iterator x = image_.begin(); x != image_.end(); ++x, ++xx)
+    {
+        should(*x == *xx);
+    }
+}
+
+class RGBImportExportAlphaTest
+{
+public:
+    RGBImportExportAlphaTest()
+    {
+#if defined(HasTIFF)
+        vigra::ImageImportInfo info("lenna_masked_color.tif");
+
+        image_.resize(info.size());
+        alpha_.resize(info.size());
+        importImageAlpha(info, destImage(image_), destImage(alpha_));
+#else
+        image_.resize(Size2D(20,10));
+        alpha_.resize(image_.size());
+        
+        image_.init(RGBValue<unsigned char>(10,20,30));
+        alpha_.init(255);
+#endif
+    }
+
+    void testFile(const char* filename);
+
+    void testTIFF()
+    {
+        const char filename[] = "res.tif";
+
+#if defined(HasTIFF)
+        testFile(filename);
+#else
+        failCodec(image_, vigra::ImageExportInfo(filename));
+#endif
+    }
+
+    void testPNG()
+    {
+        const char filename[] = "res.png";
+
+#if defined(HasPNG)
+        testFile(filename);
+#else
+        failCodec(image_, vigra::ImageExportInfo(filename));
+#endif
+    }
+
+private:
+    BRGBImage image_;
+    BImage alpha_;
+};
+
+void
+RGBImportExportAlphaTest::testFile(const char* filename)
+{
+    exportImageAlpha(srcImageRange(image_), srcImage(alpha_), vigra::ImageExportInfo(filename));
+
+    vigra::ImageImportInfo info(filename);
+
+    should(info.width() == image_.width());
+    should(info.height() == image_.height());
+    should(info.isColor());
+    should(!strcmp(info.getPixelType(), "UINT8"));
+    should(info.numBands() == 4);
+
+    should(info.width() == alpha_.width());
+    should(info.height() == alpha_.height());
+    should(info.numExtraBands() == 1);
+
+    BRGBImage image(info.size());
+    BImage alpha(info.size());
+
+    importImageAlpha(info, destImage(image), destImage(alpha));
+
+    for (BImage::const_iterator x = alpha_.begin(), xx = alpha_.begin(); x != alpha_.end(); ++x, ++xx)
+    {
+        should(*x == 255);
+        should(*x == *xx);
+    }
+
+    for (BRGBImage::const_iterator x = image_.begin(), xx = image.begin(); x != image_.end(); ++x, ++xx)
+    {
+        should(*x == *xx);
+    }
+}
+
+struct ImageImportExportTestSuite : public vigra::test_suite
+{
+    ImageImportExportTestSuite()
+        : vigra::test_suite("ImageImportExportTestSuite")
+    {
+        // general tests
+        add(testCase(&ByteImageExportImportTest::testListFormatsExtensions));
+        add(testCase(&ByteImageExportImportTest::testIsImage));
+
+        // grayscale byte images
+        add(testCase(&ByteImageExportImportTest::testGIF));
+        add(testCase(&ByteImageExportImportTest::testJPEG));
+        add(testCase(&ByteImageExportImportTest::testTIFF));
+        add(testCase(&ByteImageExportImportTest::testTIFFSequence));
+        add(testCase(&ByteImageExportImportTest::testBMP));
+        add(testCase(&ByteImageExportImportTest::testPGM));
+        add(testCase(&ByteImageExportImportTest::testPNM));
+        add(testCase(&ByteImageExportImportTest::testPNM2));
+        add(testCase(&ByteImageExportImportTest::testPNG));
+        add(testCase(&ByteImageExportImportTest::testSUN));
+        add(testCase(&ByteImageExportImportTest::testVIFF1));
+        add(testCase(&ByteImageExportImportTest::testVIFF2));
+        add(testCase(&ByteImageExportImportTest::testGrayToRGB));
+        
+        // rgb byte images
+        add(testCase(&ByteRGBImageExportImportTest::testGIF));
+        add(testCase(&ByteRGBImageExportImportTest::testJPEG));
+        add(testCase(&ByteRGBImageExportImportTest::testTIFF));
+        add(testCase(&ByteRGBImageExportImportTest::testBMP));
+        add(testCase(&ByteRGBImageExportImportTest::testPPM));
+        add(testCase(&ByteRGBImageExportImportTest::testPNM));
+        add(testCase(&ByteRGBImageExportImportTest::testPNM2));
+        add(testCase(&ByteRGBImageExportImportTest::testPNG));
+        add(testCase(&ByteRGBImageExportImportTest::testSUN));
+        add(testCase(&ByteRGBImageExportImportTest::testVIFF1));
+        add(testCase(&ByteRGBImageExportImportTest::testVIFF2));
+
+#if defined(HasPNG)
+        // 16-bit PNG
+        add(testCase(&PNGInt16Test::testByteOrder));
+#endif
+
+        add(testCase(&CanvasSizeTest::testTIFFCanvasSize));
+
+        // grayscale float images
+        add(testCase(&FloatImageExportImportTest::testGIF));
+        add(testCase(&FloatImageExportImportTest::testJPEG));
+        add(testCase(&FloatImageExportImportTest::testPNG));
+        add(testCase(&FloatImageExportImportTest::testTIFF));
+        add(testCase(&FloatImageExportImportTest::testTIFFForcedRange));
+        add(testCase(&FloatImageExportImportTest::testBMP));
+        add(testCase(&FloatImageExportImportTest::testSUN));
+        add(testCase(&FloatImageExportImportTest::testVIFF));
+
+        // 4-band images
+        add(testCase(&Vector4ExportImportTest::testJPEG));
+        add(testCase(&Vector4ExportImportTest::testGIF));
+        add(testCase(&Vector4ExportImportTest::testBMP));
+        add(testCase(&Vector4ExportImportTest::testPNM));
+        add(testCase(&Vector4ExportImportTest::testSUN));
+        add(testCase(&Vector4ExportImportTest::testVIFF));
+        add(testCase(&Vector4ExportImportTest::testTIFF));
+        add(testCase(&Vector4ExportImportTest::testEXR));
+        add(testCase(&Vector4ExportImportTest::testPNG));
+
+        // rgb float images
+        add(testCase(&FloatRGBImageExportImportTest::testJPEG));
+        add(testCase(&FloatRGBImageExportImportTest::testTIFF));
+        add(testCase(&FloatRGBImageExportImportTest::testTIFFForcedRange));
+        add(testCase(&FloatRGBImageExportImportTest::testBMP));
+        add(testCase(&FloatRGBImageExportImportTest::testSUN));
+        add(testCase(&FloatRGBImageExportImportTest::testVIFF));
+        add(testCase(&FloatRGBImageExportImportTest::testHDR));
+
+        // failure tests
+        add(testCase(&ImageExportImportFailureTest::testGIFExport));
+        add(testCase(&ImageExportImportFailureTest::testGIFImport));
+        add(testCase(&ImageExportImportFailureTest::testJPEGExport));
+        add(testCase(&ImageExportImportFailureTest::testJPEGImport));
+        add(testCase(&ImageExportImportFailureTest::testTIFFExport));
+        add(testCase(&ImageExportImportFailureTest::testTIFFImport));
+        add(testCase(&ImageExportImportFailureTest::testBMPExport));
+        add(testCase(&ImageExportImportFailureTest::testBMPImport));
+        add(testCase(&ImageExportImportFailureTest::testPNMExport));
+        add(testCase(&ImageExportImportFailureTest::testPNMImport));
+        add(testCase(&ImageExportImportFailureTest::testPNGExport));
+        add(testCase(&ImageExportImportFailureTest::testPNGImport));
+        add(testCase(&ImageExportImportFailureTest::testSUNExport));
+        add(testCase(&ImageExportImportFailureTest::testSUNImport));
+        add(testCase(&ImageExportImportFailureTest::testVIFFExport));
+        add(testCase(&ImageExportImportFailureTest::testVIFFImport));
+        add(testCase(&ImageExportImportFailureTest::testShapeMismatch));
+
+        // alpha-channel tests
+        add(testCase(&GrayscaleImportExportAlphaTest::testTIFF));
+        add(testCase(&GrayscaleImportExportAlphaTest::testPNG));
+        add(testCase(&RGBImportExportAlphaTest::testTIFF));
+        add(testCase(&RGBImportExportAlphaTest::testPNG));
+    }
+};
+
+
+int main (int argc, char ** argv)
+{
+    ImageImportExportTestSuite test;
+    const int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test.report() << std::endl;
+
+    return failed != 0;
+}
diff --git a/test/math/CMakeLists.txt b/test/math/CMakeLists.txt
new file mode 100644
index 0000000..1b3a4ff
--- /dev/null
+++ b/test/math/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_math test.cxx)
diff --git a/test/math/convex_hull_test.hxx b/test/math/convex_hull_test.hxx
new file mode 100644
index 0000000..3c6a869
--- /dev/null
+++ b/test/math/convex_hull_test.hxx
@@ -0,0 +1,460 @@
+/************************************************************************/
+/*                                                                      */
+/*                Copyright 2011 by Ullrich Koethe                      */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_CONVEX_HULL_TEST_HXX
+#define VIGRA_CONVEX_HULL_TEST_HXX
+
+#include <vigra/tinyvector.hxx>
+
+typedef vigra::TinyVector<double, 2> P;
+
+P convexHullReference[] = {
+    P(124.0,  23.0),
+    P(125.0,  20.0),
+    P(127.0,  17.0),
+    P(128.0,  16.0),
+    P(141.0,   5.0), 
+    P(159.0,   5.0),
+    P(176.0,  11.0),
+    P(186.0,  15.0),
+    P(251.0,  47.0),
+    P(254.0,  49.0),
+    P(293.0,  84.0),
+    P(297.0,  88.0),
+    P(455.0, 510.0),
+    P(455.0, 511.0),
+    P(188.0, 511.0),
+    P(178.0, 476.0),
+    P(124.0,  23.0)
+};
+
+P convexHullInputs[] = {
+    P(124.0, 23.0), P(125.0, 20.0), P(125.0, 23.0), P(126.0, 19.0), 
+    P(126.0, 20.0), P(127.0, 17.0), P(127.0, 18.0), P(127.0, 35.0), 
+    P(127.0, 36.0), P(127.0, 37.0), P(127.0, 38.0), P(128.0, 16.0), 
+    P(128.0, 33.0), P(128.0, 40.0), P(128.0, 41.0), P(128.0, 42.0), 
+    P(128.0, 43.0), P(128.0, 44.0), P(128.0, 45.0), P(128.0, 46.0), 
+    P(128.0, 47.0), P(128.0, 48.0), P(129.0, 16.0), P(129.0, 29.0), 
+    P(129.0, 30.0), P(129.0, 31.0), P(130.0, 16.0), P(130.0, 50.0), 
+    P(131.0, 50.0), P(132.0, 15.0), P(134.0, 52.0), P(134.0, 53.0), 
+    P(134.0, 54.0), P(134.0, 55.0), P(136.0, 12.0), P(137.0, 11.0), 
+    P(137.0, 58.0), P(138.0, 58.0), P(140.0, 6.0), P(140.0, 7.0), 
+    P(141.0, 5.0), P(141.0, 60.0), P(142.0, 5.0), P(144.0, 6.0), 
+    P(145.0, 6.0), P(147.0, 7.0), P(148.0, 66.0), P(149.0, 8.0), 
+    P(150.0, 8.0), P(150.0, 67.0), P(151.0, 8.0), P(153.0, 8.0), 
+    P(153.0, 9.0), P(154.0, 71.0), P(155.0, 73.0), P(155.0, 74.0), 
+    P(156.0, 7.0), P(156.0, 76.0), P(156.0, 77.0), P(157.0, 77.0), 
+    P(157.0, 78.0), P(159.0, 5.0), P(159.0, 6.0), P(159.0, 78.0), 
+    P(160.0, 78.0), P(161.0, 6.0), P(161.0, 78.0), P(163.0, 8.0), 
+    P(163.0, 78.0), P(163.0, 79.0), P(164.0, 9.0), P(164.0, 85.0), 
+    P(164.0, 86.0), P(164.0, 87.0), P(165.0, 78.0), P(165.0, 84.0), 
+    P(165.0, 89.0), P(165.0, 90.0), P(165.0, 91.0), P(166.0, 10.0), 
+    P(167.0, 10.0), P(167.0, 82.0), P(167.0, 94.0), P(167.0, 97.0), 
+    P(167.0, 98.0), P(168.0, 10.0), P(168.0, 95.0), P(168.0, 96.0), 
+    P(169.0, 99.0), P(169.0, 100.0), P(170.0, 50.0), P(170.0, 51.0), 
+    P(171.0, 12.0), P(171.0, 49.0), P(171.0, 99.0), P(172.0, 12.0), 
+    P(172.0, 49.0), P(172.0, 53.0), P(172.0, 99.0), P(172.0, 105.0), 
+    P(173.0, 12.0), P(173.0, 53.0), P(173.0, 100.0), P(173.0, 101.0), 
+    P(173.0, 102.0), P(173.0, 103.0), P(173.0, 105.0), P(174.0, 51.0), 
+    P(174.0, 52.0), P(175.0, 11.0), P(175.0, 109.0), P(175.0, 110.0), 
+    P(175.0, 111.0), P(175.0, 113.0), P(175.0, 114.0), P(175.0, 115.0), 
+    P(175.0, 116.0), P(175.0, 117.0), P(175.0, 118.0), P(175.0, 119.0), 
+    P(175.0, 120.0), P(175.0, 121.0), P(175.0, 122.0), P(175.0, 132.0), 
+    P(175.0, 133.0), P(175.0, 134.0), P(175.0, 135.0), P(175.0, 142.0), 
+    P(175.0, 143.0), P(175.0, 147.0), P(175.0, 148.0), P(176.0, 11.0), 
+    P(176.0, 123.0), P(176.0, 145.0), P(176.0, 173.0), P(176.0, 224.0), 
+    P(176.0, 227.0), P(176.0, 228.0), P(176.0, 236.0), P(176.0, 237.0), 
+    P(176.0, 238.0), P(176.0, 239.0), P(176.0, 240.0), P(176.0, 241.0), 
+    P(177.0, 124.0), P(177.0, 129.0), P(177.0, 150.0), P(177.0, 173.0), 
+    P(177.0, 221.0), P(177.0, 222.0), P(177.0, 224.0), P(177.0, 230.0), 
+    P(177.0, 234.0), P(177.0, 243.0), P(177.0, 248.0), P(177.0, 249.0), 
+    P(177.0, 250.0), P(177.0, 251.0), P(178.0, 126.0), P(178.0, 127.0), 
+    P(178.0, 150.0), P(178.0, 182.0), P(178.0, 183.0), P(178.0, 184.0), 
+    P(178.0, 185.0), P(178.0, 186.0), P(178.0, 187.0), P(178.0, 188.0), 
+    P(178.0, 189.0), P(178.0, 190.0), P(178.0, 205.0), P(178.0, 206.0), 
+    P(178.0, 207.0), P(178.0, 208.0), P(178.0, 209.0), P(178.0, 210.0), 
+    P(178.0, 218.0), P(178.0, 219.0), P(178.0, 232.0), P(178.0, 245.0), 
+    P(178.0, 246.0), P(178.0, 252.0), P(178.0, 253.0), P(178.0, 254.0), 
+    P(178.0, 255.0), P(178.0, 473.0), P(178.0, 474.0), P(178.0, 475.0), 
+    P(178.0, 476.0), P(179.0, 13.0), P(179.0, 168.0), P(179.0, 169.0), 
+    P(179.0, 177.0), P(179.0, 179.0), P(179.0, 180.0), P(179.0, 192.0), 
+    P(179.0, 200.0), P(179.0, 201.0), P(179.0, 204.0), P(179.0, 212.0), 
+    P(179.0, 213.0), P(179.0, 214.0), P(179.0, 215.0), P(179.0, 216.0), 
+    P(179.0, 257.0), P(179.0, 258.0), P(179.0, 259.0), P(179.0, 260.0), 
+    P(180.0, 13.0), P(180.0, 155.0), P(180.0, 156.0), P(180.0, 166.0), 
+    P(180.0, 194.0), P(180.0, 196.0), P(180.0, 197.0), P(180.0, 198.0), 
+    P(180.0, 203.0), P(180.0, 262.0), P(180.0, 263.0), P(180.0, 264.0), 
+    P(180.0, 265.0), P(180.0, 275.0), P(180.0, 276.0), P(180.0, 372.0), 
+    P(180.0, 373.0), P(180.0, 471.0), P(180.0, 478.0), P(181.0, 153.0), 
+    P(181.0, 156.0), P(181.0, 157.0), P(181.0, 158.0), P(181.0, 159.0), 
+    P(181.0, 160.0), P(181.0, 161.0), P(181.0, 162.0), P(181.0, 163.0), 
+    P(181.0, 164.0), P(181.0, 267.0), P(181.0, 268.0), P(181.0, 269.0), 
+    P(181.0, 270.0), P(181.0, 272.0), P(181.0, 273.0), P(181.0, 471.0), 
+    P(181.0, 478.0), P(182.0, 14.0), P(182.0, 58.0), P(182.0, 59.0), 
+    P(182.0, 277.0), P(182.0, 278.0), P(182.0, 370.0), P(182.0, 375.0), 
+    P(182.0, 448.0), P(182.0, 449.0), P(182.0, 450.0), P(182.0, 451.0), 
+    P(182.0, 471.0), P(183.0, 14.0), P(183.0, 278.0), P(183.0, 285.0), 
+    P(183.0, 286.0), P(183.0, 287.0), P(183.0, 288.0), P(183.0, 289.0), 
+    P(183.0, 453.0), P(183.0, 454.0), P(183.0, 455.0), P(183.0, 456.0), 
+    P(183.0, 457.0), P(183.0, 458.0), P(183.0, 459.0), P(183.0, 460.0), 
+    P(183.0, 461.0), P(183.0, 462.0), P(183.0, 463.0), P(183.0, 471.0), 
+    P(183.0, 480.0), P(184.0, 57.0), P(184.0, 280.0), P(184.0, 281.0), 
+    P(184.0, 282.0), P(184.0, 283.0), P(184.0, 291.0), P(184.0, 292.0), 
+    P(184.0, 319.0), P(184.0, 320.0), P(184.0, 369.0), P(184.0, 376.0), 
+    P(184.0, 439.0), P(184.0, 440.0), P(184.0, 445.0), P(184.0, 465.0), 
+    P(184.0, 468.0), P(184.0, 469.0), P(184.0, 470.0), P(184.0, 482.0), 
+    P(184.0, 483.0), P(184.0, 484.0), P(185.0, 15.0), P(185.0, 294.0), 
+    P(185.0, 295.0), P(185.0, 307.0), P(185.0, 308.0), P(185.0, 309.0), 
+    P(185.0, 316.0), P(185.0, 317.0), P(185.0, 336.0), P(185.0, 337.0), 
+    P(185.0, 338.0), P(185.0, 339.0), P(185.0, 369.0), P(185.0, 376.0), 
+    P(185.0, 437.0), P(185.0, 442.0), P(185.0, 443.0), P(185.0, 485.0), 
+    P(186.0, 15.0), P(186.0, 297.0), P(186.0, 298.0), P(186.0, 299.0), 
+    P(186.0, 303.0), P(186.0, 304.0), P(186.0, 305.0), P(186.0, 311.0), 
+    P(186.0, 312.0), P(186.0, 313.0), P(186.0, 314.0), P(186.0, 334.0), 
+    P(186.0, 340.0), P(186.0, 369.0), P(186.0, 419.0), P(186.0, 420.0), 
+    P(187.0, 60.0), P(187.0, 301.0), P(187.0, 328.0), P(187.0, 329.0), 
+    P(187.0, 330.0), P(187.0, 331.0), P(187.0, 332.0), P(187.0, 375.0), 
+    P(187.0, 389.0), P(187.0, 398.0), P(187.0, 399.0), P(187.0, 400.0), 
+    P(187.0, 487.0), P(187.0, 488.0), P(188.0, 65.0), P(188.0, 325.0), 
+    P(188.0, 326.0), P(188.0, 367.0), P(188.0, 387.0), P(188.0, 389.0), 
+    P(188.0, 391.0), P(188.0, 392.0), P(188.0, 395.0), P(188.0, 408.0), 
+    P(188.0, 409.0), P(188.0, 410.0), P(188.0, 411.0), P(188.0, 412.0), 
+    P(188.0, 413.0), P(188.0, 414.0), P(188.0, 415.0), P(188.0, 416.0), 
+    P(188.0, 431.0), P(188.0, 432.0), P(188.0, 433.0), P(188.0, 490.0), 
+    P(188.0, 491.0), P(188.0, 492.0), P(188.0, 493.0), P(188.0, 494.0), 
+    P(188.0, 495.0), P(188.0, 503.0), P(188.0, 504.0), P(188.0, 510.0), 
+    P(188.0, 511.0), P(189.0, 19.0), P(189.0, 62.0), P(189.0, 343.0), 
+    P(189.0, 365.0), P(189.0, 375.0), P(189.0, 384.0), P(189.0, 385.0), 
+    P(189.0, 395.0), P(189.0, 402.0), P(189.0, 423.0), P(189.0, 429.0), 
+    P(189.0, 500.0), P(189.0, 501.0), P(189.0, 506.0), P(189.0, 507.0), 
+    P(189.0, 508.0), P(190.0, 19.0), P(190.0, 20.0), P(190.0, 345.0), 
+    P(190.0, 346.0), P(190.0, 376.0), P(190.0, 377.0), P(190.0, 380.0), 
+    P(190.0, 381.0), P(190.0, 382.0), P(190.0, 403.0), P(190.0, 404.0), 
+    P(190.0, 405.0), P(190.0, 423.0), P(190.0, 498.0), P(191.0, 21.0), 
+    P(191.0, 68.0), P(191.0, 348.0), P(191.0, 349.0), P(191.0, 362.0), 
+    P(191.0, 424.0), P(191.0, 425.0), P(191.0, 426.0), P(192.0, 23.0), 
+    P(192.0, 64.0), P(192.0, 70.0), P(192.0, 71.0), P(192.0, 351.0), 
+    P(192.0, 352.0), P(192.0, 353.0), P(192.0, 355.0), P(192.0, 360.0), 
+    P(193.0, 73.0), P(193.0, 355.0), P(193.0, 357.0), P(193.0, 358.0), 
+    P(195.0, 26.0), P(195.0, 67.0), P(195.0, 507.0), P(196.0, 68.0), 
+    P(196.0, 77.0), P(196.0, 78.0), P(196.0, 79.0), P(196.0, 80.0), 
+    P(196.0, 81.0), P(196.0, 82.0), P(196.0, 508.0), P(196.0, 511.0), 
+    P(197.0, 26.0), P(197.0, 68.0), P(198.0, 26.0), P(198.0, 68.0), 
+    P(198.0, 85.0), P(199.0, 26.0), P(199.0, 68.0), P(199.0, 86.0), 
+    P(200.0, 68.0), P(200.0, 86.0), P(201.0, 28.0), P(201.0, 29.0), 
+    P(201.0, 30.0), P(201.0, 68.0), P(202.0, 88.0), P(202.0, 89.0), 
+    P(202.0, 92.0), P(202.0, 93.0), P(202.0, 94.0), P(203.0, 32.0), 
+    P(203.0, 96.0), P(204.0, 32.0), P(204.0, 70.0), P(205.0, 99.0), 
+    P(205.0, 101.0), P(205.0, 103.0), P(205.0, 104.0), P(205.0, 105.0), 
+    P(205.0, 106.0), P(205.0, 107.0), P(205.0, 108.0), P(206.0, 33.0), 
+    P(206.0, 71.0), P(206.0, 101.0), P(206.0, 110.0), P(206.0, 111.0), 
+    P(207.0, 33.0), P(207.0, 71.0), P(207.0, 113.0), P(207.0, 114.0), 
+    P(207.0, 115.0), P(207.0, 116.0), P(207.0, 119.0), P(208.0, 71.0), 
+    P(209.0, 32.0), P(209.0, 121.0), P(210.0, 32.0), P(210.0, 72.0), 
+    P(210.0, 121.0), P(211.0, 32.0), P(211.0, 122.0), P(211.0, 130.0), 
+    P(211.0, 131.0), P(211.0, 132.0), P(211.0, 133.0), P(211.0, 134.0), 
+    P(211.0, 135.0), P(211.0, 136.0), P(211.0, 137.0), P(211.0, 138.0), 
+    P(211.0, 139.0), P(211.0, 140.0), P(212.0, 32.0), P(212.0, 124.0), 
+    P(212.0, 125.0), P(212.0, 126.0), P(212.0, 127.0), P(212.0, 128.0), 
+    P(212.0, 142.0), P(212.0, 143.0), P(212.0, 144.0), P(213.0, 33.0), 
+    P(213.0, 34.0), P(213.0, 75.0), P(213.0, 166.0), P(213.0, 167.0), 
+    P(213.0, 168.0), P(214.0, 35.0), P(214.0, 147.0), P(214.0, 161.0), 
+    P(214.0, 162.0), P(214.0, 163.0), P(214.0, 164.0), P(214.0, 170.0), 
+    P(214.0, 171.0), P(215.0, 77.0), P(215.0, 148.0), P(215.0, 155.0), 
+    P(215.0, 156.0), P(215.0, 157.0), P(215.0, 158.0), P(215.0, 159.0), 
+    P(215.0, 173.0), P(215.0, 181.0), P(215.0, 182.0), P(215.0, 183.0), 
+    P(215.0, 184.0), P(215.0, 185.0), P(215.0, 186.0), P(215.0, 187.0), 
+    P(215.0, 188.0), P(215.0, 215.0), P(215.0, 216.0), P(216.0, 148.0), 
+    P(216.0, 179.0), P(216.0, 192.0), P(216.0, 193.0), P(216.0, 194.0), 
+    P(216.0, 195.0), P(216.0, 213.0), P(216.0, 218.0), P(216.0, 219.0), 
+    P(216.0, 220.0), P(216.0, 221.0), P(216.0, 228.0), P(216.0, 229.0), 
+    P(216.0, 230.0), P(216.0, 231.0), P(216.0, 233.0), P(217.0, 37.0), 
+    P(217.0, 148.0), P(217.0, 153.0), P(217.0, 176.0), P(217.0, 177.0), 
+    P(217.0, 197.0), P(217.0, 198.0), P(217.0, 223.0), P(217.0, 224.0), 
+    P(217.0, 225.0), P(217.0, 226.0), P(217.0, 235.0), P(217.0, 236.0), 
+    P(217.0, 237.0), P(217.0, 239.0), P(217.0, 240.0), P(217.0, 241.0), 
+    P(218.0, 149.0), P(218.0, 150.0), P(218.0, 151.0), P(218.0, 152.0), 
+    P(218.0, 200.0), P(218.0, 201.0), P(218.0, 243.0), P(218.0, 244.0), 
+    P(218.0, 245.0), P(218.0, 246.0), P(218.0, 247.0), P(218.0, 248.0), 
+    P(218.0, 261.0), P(219.0, 210.0), P(219.0, 250.0), P(219.0, 251.0), 
+    P(219.0, 252.0), P(219.0, 254.0), P(219.0, 256.0), P(219.0, 257.0), 
+    P(219.0, 259.0), P(219.0, 260.0), P(219.0, 263.0), P(219.0, 264.0), 
+    P(219.0, 265.0), P(220.0, 39.0), P(220.0, 204.0), P(220.0, 254.0), 
+    P(220.0, 259.0), P(220.0, 266.0), P(221.0, 206.0), P(221.0, 207.0), 
+    P(221.0, 208.0), P(222.0, 40.0), P(222.0, 83.0), P(222.0, 286.0), 
+    P(222.0, 287.0), P(222.0, 288.0), P(223.0, 40.0), P(223.0, 290.0), 
+    P(224.0, 40.0), P(224.0, 84.0), P(224.0, 270.0), P(224.0, 271.0), 
+    P(224.0, 272.0), P(224.0, 273.0), P(224.0, 274.0), P(224.0, 275.0), 
+    P(224.0, 280.0), P(224.0, 287.0), P(224.0, 288.0), P(225.0, 40.0), 
+    P(225.0, 84.0), P(225.0, 277.0), P(225.0, 278.0), P(225.0, 282.0), 
+    P(225.0, 286.0), P(225.0, 287.0), P(225.0, 293.0), P(225.0, 302.0), 
+    P(226.0, 40.0), P(226.0, 282.0), P(226.0, 304.0), P(226.0, 318.0), 
+    P(226.0, 319.0), P(226.0, 320.0), P(226.0, 321.0), P(226.0, 322.0), 
+    P(226.0, 323.0), P(226.0, 324.0), P(226.0, 325.0), P(227.0, 40.0), 
+    P(227.0, 85.0), P(227.0, 296.0), P(227.0, 297.0), P(227.0, 298.0), 
+    P(227.0, 299.0), P(227.0, 306.0), P(227.0, 327.0), P(228.0, 306.0), 
+    P(228.0, 314.0), P(228.0, 315.0), P(228.0, 329.0), P(229.0, 86.0), 
+    P(229.0, 306.0), P(229.0, 312.0), P(229.0, 356.0), P(229.0, 357.0), 
+    P(229.0, 358.0), P(230.0, 306.0), P(230.0, 333.0), P(230.0, 335.0), 
+    P(230.0, 361.0), P(231.0, 87.0), P(231.0, 307.0), P(231.0, 308.0), 
+    P(231.0, 309.0), P(231.0, 333.0), P(231.0, 353.0), P(231.0, 361.0), 
+    P(231.0, 363.0), P(232.0, 44.0), P(232.0, 335.0), P(232.0, 336.0), 
+    P(232.0, 351.0), P(232.0, 352.0), P(232.0, 365.0), P(232.0, 394.0), 
+    P(232.0, 395.0), P(232.0, 399.0), P(232.0, 413.0), P(232.0, 414.0), 
+    P(232.0, 415.0), P(232.0, 428.0), P(232.0, 429.0), P(232.0, 430.0), 
+    P(232.0, 431.0), P(232.0, 450.0), P(233.0, 336.0), P(233.0, 337.0), 
+    P(233.0, 338.0), P(233.0, 340.0), P(233.0, 350.0), P(233.0, 351.0), 
+    P(233.0, 391.0), P(233.0, 392.0), P(233.0, 397.0), P(233.0, 398.0), 
+    P(233.0, 402.0), P(233.0, 403.0), P(233.0, 404.0), P(233.0, 405.0), 
+    P(233.0, 411.0), P(233.0, 412.0), P(233.0, 416.0), P(233.0, 420.0), 
+    P(233.0, 421.0), P(233.0, 422.0), P(233.0, 424.0), P(233.0, 425.0), 
+    P(233.0, 433.0), P(233.0, 450.0), P(233.0, 452.0), P(234.0, 43.0), 
+    P(234.0, 340.0), P(234.0, 341.0), P(234.0, 350.0), P(234.0, 368.0), 
+    P(234.0, 381.0), P(234.0, 382.0), P(234.0, 383.0), P(234.0, 384.0), 
+    P(234.0, 385.0), P(234.0, 388.0), P(234.0, 389.0), P(234.0, 407.0), 
+    P(234.0, 408.0), P(234.0, 417.0), P(234.0, 418.0), P(234.0, 434.0), 
+    P(234.0, 452.0), P(235.0, 43.0), P(235.0, 369.0), P(235.0, 378.0), 
+    P(235.0, 379.0), P(235.0, 434.0), P(235.0, 453.0), P(235.0, 465.0), 
+    P(235.0, 471.0), P(235.0, 473.0), P(235.0, 474.0), P(236.0, 43.0), 
+    P(236.0, 92.0), P(236.0, 349.0), P(236.0, 370.0), P(236.0, 371.0), 
+    P(236.0, 372.0), P(236.0, 373.0), P(236.0, 374.0), P(236.0, 375.0), 
+    P(236.0, 376.0), P(236.0, 435.0), P(236.0, 446.0), P(237.0, 338.0), 
+    P(237.0, 455.0), P(237.0, 471.0), P(238.0, 44.0), P(238.0, 94.0), 
+    P(238.0, 468.0), P(238.0, 469.0), P(238.0, 470.0), P(238.0, 474.0), 
+    P(238.0, 475.0), P(239.0, 95.0), P(239.0, 336.0), P(239.0, 439.0), 
+    P(239.0, 441.0), P(239.0, 443.0), P(239.0, 473.0), P(240.0, 336.0), 
+    P(240.0, 337.0), P(240.0, 346.0), P(240.0, 441.0), P(240.0, 466.0), 
+    P(240.0, 473.0), P(240.0, 474.0), P(241.0, 46.0), P(241.0, 98.0), 
+    P(241.0, 337.0), P(241.0, 339.0), P(241.0, 340.0), P(241.0, 345.0), 
+    P(241.0, 458.0), P(241.0, 466.0), P(241.0, 474.0), P(241.0, 475.0), 
+    P(242.0, 99.0), P(242.0, 342.0), P(242.0, 343.0), P(243.0, 48.0), 
+    P(243.0, 459.0), P(243.0, 465.0), P(243.0, 474.0), P(244.0, 48.0), 
+    P(244.0, 460.0), P(244.0, 461.0), P(244.0, 462.0), P(244.0, 463.0), 
+    P(244.0, 464.0), P(244.0, 474.0), P(245.0, 48.0), P(245.0, 102.0), 
+    P(245.0, 474.0), P(246.0, 104.0), P(246.0, 105.0), P(246.0, 106.0), 
+    P(246.0, 107.0), P(246.0, 108.0), P(246.0, 474.0), P(247.0, 110.0), 
+    P(247.0, 475.0), P(247.0, 483.0), P(247.0, 484.0), P(247.0, 485.0), 
+    P(247.0, 486.0), P(247.0, 487.0), P(247.0, 488.0), P(247.0, 489.0), 
+    P(247.0, 490.0), P(248.0, 477.0), P(248.0, 478.0), P(248.0, 480.0), 
+    P(248.0, 481.0), P(249.0, 47.0), P(249.0, 112.0), P(249.0, 493.0), 
+    P(250.0, 47.0), P(250.0, 494.0), P(251.0, 47.0), P(251.0, 494.0), 
+    P(252.0, 114.0), P(252.0, 502.0), P(252.0, 503.0), P(253.0, 114.0), 
+    P(253.0, 496.0), P(253.0, 497.0), P(253.0, 498.0), P(253.0, 499.0), 
+    P(253.0, 500.0), P(253.0, 503.0), P(254.0, 49.0), P(254.0, 115.0), 
+    P(254.0, 507.0), P(254.0, 509.0), P(254.0, 511.0), P(255.0, 117.0), 
+    P(255.0, 118.0), P(255.0, 509.0), P(256.0, 52.0), P(256.0, 54.0), 
+    P(256.0, 55.0), P(256.0, 56.0), P(256.0, 57.0), P(256.0, 58.0), 
+    P(257.0, 52.0), P(257.0, 60.0), P(257.0, 121.0), P(257.0, 122.0), 
+    P(257.0, 123.0), P(257.0, 124.0), P(257.0, 193.0), P(257.0, 194.0), 
+    P(257.0, 195.0), P(257.0, 196.0), P(258.0, 126.0), P(258.0, 127.0), 
+    P(258.0, 190.0), P(258.0, 191.0), P(258.0, 197.0), P(259.0, 129.0), 
+    P(259.0, 166.0), P(259.0, 167.0), P(259.0, 168.0), P(259.0, 169.0), 
+    P(259.0, 170.0), P(259.0, 171.0), P(260.0, 64.0), P(260.0, 131.0), 
+    P(260.0, 163.0), P(260.0, 164.0), P(260.0, 173.0), P(260.0, 188.0), 
+    P(260.0, 197.0), P(260.0, 198.0), P(261.0, 65.0), P(261.0, 144.0), 
+    P(261.0, 161.0), P(261.0, 188.0), P(262.0, 65.0), P(262.0, 142.0), 
+    P(262.0, 144.0), P(262.0, 146.0), P(262.0, 147.0), P(262.0, 148.0), 
+    P(262.0, 149.0), P(262.0, 150.0), P(262.0, 151.0), P(262.0, 152.0), 
+    P(262.0, 158.0), P(262.0, 159.0), P(262.0, 188.0), P(262.0, 206.0), 
+    P(262.0, 207.0), P(262.0, 208.0), P(263.0, 135.0), P(263.0, 136.0), 
+    P(263.0, 154.0), P(263.0, 155.0), P(263.0, 156.0), P(263.0, 176.0), 
+    P(263.0, 188.0), P(263.0, 195.0), P(264.0, 138.0), P(264.0, 139.0), 
+    P(264.0, 176.0), P(264.0, 203.0), P(265.0, 67.0), P(265.0, 177.0), 
+    P(265.0, 186.0), P(265.0, 193.0), P(265.0, 194.0), P(265.0, 201.0), 
+    P(265.0, 212.0), P(266.0, 67.0), P(266.0, 181.0), P(266.0, 182.0), 
+    P(266.0, 183.0), P(266.0, 184.0), P(266.0, 194.0), P(266.0, 196.0), 
+    P(266.0, 198.0), P(266.0, 199.0), P(266.0, 214.0), P(266.0, 215.0), 
+    P(267.0, 67.0), P(268.0, 67.0), P(268.0, 218.0), P(268.0, 219.0), 
+    P(268.0, 220.0), P(268.0, 221.0), P(268.0, 222.0), P(268.0, 247.0), 
+    P(268.0, 248.0), P(268.0, 249.0), P(268.0, 250.0), P(268.0, 251.0), 
+    P(270.0, 69.0), P(270.0, 70.0), P(270.0, 244.0), P(270.0, 253.0), 
+    P(270.0, 258.0), P(271.0, 71.0), P(271.0, 226.0), P(271.0, 227.0), 
+    P(271.0, 228.0), P(271.0, 230.0), P(271.0, 231.0), P(271.0, 232.0), 
+    P(271.0, 233.0), P(271.0, 237.0), P(271.0, 238.0), P(271.0, 239.0), 
+    P(271.0, 240.0), P(271.0, 241.0), P(271.0, 242.0), P(271.0, 253.0), 
+    P(271.0, 256.0), P(271.0, 258.0), P(272.0, 234.0), P(272.0, 236.0), 
+    P(272.0, 253.0), P(272.0, 261.0), P(272.0, 319.0), P(273.0, 72.0), 
+    P(273.0, 262.0), P(273.0, 319.0), P(274.0, 262.0), P(274.0, 284.0), 
+    P(274.0, 317.0), P(274.0, 321.0), P(275.0, 262.0), P(275.0, 279.0), 
+    P(275.0, 281.0), P(275.0, 282.0), P(275.0, 284.0), P(275.0, 286.0), 
+    P(275.0, 317.0), P(275.0, 321.0), P(275.0, 324.0), P(275.0, 325.0), 
+    P(275.0, 326.0), P(275.0, 327.0), P(276.0, 74.0), P(276.0, 262.0), 
+    P(276.0, 277.0), P(276.0, 279.0), P(276.0, 287.0), P(276.0, 322.0), 
+    P(277.0, 276.0), P(277.0, 287.0), P(277.0, 318.0), P(277.0, 329.0), 
+    P(278.0, 276.0), P(278.0, 287.0), P(278.0, 319.0), P(278.0, 320.0), 
+    P(278.0, 329.0), P(279.0, 76.0), P(279.0, 262.0), P(279.0, 263.0), 
+    P(279.0, 287.0), P(279.0, 321.0), P(279.0, 329.0), P(280.0, 76.0), 
+    P(280.0, 263.0), P(280.0, 321.0), P(281.0, 265.0), P(281.0, 266.0), 
+    P(281.0, 267.0), P(281.0, 274.0), P(281.0, 328.0), P(282.0, 78.0), 
+    P(282.0, 269.0), P(282.0, 270.0), P(282.0, 271.0), P(282.0, 272.0), 
+    P(282.0, 273.0), P(282.0, 290.0), P(282.0, 291.0), P(283.0, 78.0), 
+    P(283.0, 79.0), P(283.0, 293.0), P(283.0, 294.0), P(283.0, 299.0), 
+    P(283.0, 300.0), P(283.0, 303.0), P(283.0, 323.0), P(283.0, 329.0), 
+    P(284.0, 79.0), P(284.0, 296.0), P(284.0, 297.0), P(284.0, 303.0), 
+    P(284.0, 305.0), P(284.0, 306.0), P(284.0, 307.0), P(284.0, 323.0), 
+    P(285.0, 309.0), P(285.0, 310.0), P(285.0, 311.0), P(285.0, 312.0), 
+    P(285.0, 313.0), P(286.0, 80.0), P(286.0, 81.0), P(286.0, 315.0), 
+    P(286.0, 322.0), P(286.0, 332.0), P(286.0, 333.0), P(287.0, 316.0), 
+    P(287.0, 317.0), P(287.0, 335.0), P(287.0, 336.0), P(287.0, 337.0), 
+    P(287.0, 338.0), P(287.0, 339.0), P(287.0, 340.0), P(288.0, 82.0), 
+    P(288.0, 317.0), P(288.0, 319.0), P(288.0, 320.0), P(288.0, 342.0), 
+    P(289.0, 83.0), P(289.0, 344.0), P(289.0, 345.0), P(289.0, 346.0), 
+    P(289.0, 347.0), P(289.0, 348.0), P(289.0, 349.0), P(289.0, 350.0), 
+    P(289.0, 351.0), P(289.0, 373.0), P(289.0, 376.0), P(289.0, 377.0), 
+    P(289.0, 378.0), P(289.0, 379.0), P(289.0, 380.0), P(289.0, 381.0), 
+    P(289.0, 382.0), P(289.0, 383.0), P(290.0, 352.0), P(290.0, 373.0), 
+    P(291.0, 84.0), P(291.0, 353.0), P(291.0, 371.0), P(291.0, 385.0), 
+    P(292.0, 84.0), P(292.0, 355.0), P(292.0, 356.0), P(292.0, 371.0), 
+    P(293.0, 84.0), P(293.0, 358.0), P(293.0, 386.0), P(294.0, 85.0), 
+    P(294.0, 360.0), P(294.0, 386.0), P(295.0, 93.0), P(295.0, 94.0), 
+    P(295.0, 95.0), P(295.0, 98.0), P(295.0, 374.0), P(295.0, 386.0), 
+    P(296.0, 87.0), P(296.0, 100.0), P(296.0, 101.0), P(296.0, 363.0), 
+    P(297.0, 88.0), P(297.0, 89.0), P(297.0, 90.0), P(297.0, 103.0), 
+    P(297.0, 365.0), P(297.0, 387.0), P(298.0, 387.0), P(299.0, 105.0), 
+    P(299.0, 368.0), P(299.0, 369.0), P(299.0, 370.0), P(299.0, 371.0), 
+    P(299.0, 373.0), P(299.0, 387.0), P(300.0, 373.0), P(300.0, 387.0), 
+    P(301.0, 107.0), P(301.0, 108.0), P(301.0, 376.0), P(301.0, 377.0), 
+    P(301.0, 395.0), P(301.0, 396.0), P(302.0, 110.0), P(302.0, 389.0), 
+    P(302.0, 392.0), P(302.0, 393.0), P(302.0, 398.0), P(303.0, 112.0), 
+    P(303.0, 400.0), P(304.0, 411.0), P(304.0, 418.0), P(304.0, 419.0), 
+    P(304.0, 420.0), P(305.0, 410.0), P(305.0, 411.0), P(305.0, 413.0), 
+    P(305.0, 414.0), P(305.0, 415.0), P(305.0, 416.0), P(305.0, 421.0), 
+    P(306.0, 116.0), P(306.0, 117.0), P(306.0, 118.0), P(306.0, 119.0), 
+    P(306.0, 121.0), P(306.0, 123.0), P(306.0, 196.0), P(306.0, 410.0), 
+    P(306.0, 421.0), P(307.0, 121.0), P(307.0, 124.0), P(307.0, 125.0), 
+    P(307.0, 126.0), P(307.0, 127.0), P(307.0, 187.0), P(307.0, 188.0), 
+    P(307.0, 189.0), P(307.0, 190.0), P(307.0, 191.0), P(307.0, 193.0), 
+    P(307.0, 405.0), P(307.0, 407.0), P(307.0, 408.0), P(307.0, 409.0), 
+    P(308.0, 129.0), P(308.0, 130.0), P(308.0, 131.0), P(308.0, 133.0), 
+    P(308.0, 193.0), P(308.0, 212.0), P(308.0, 421.0), P(308.0, 422.0), 
+    P(309.0, 133.0), P(309.0, 165.0), P(309.0, 183.0), P(309.0, 184.0), 
+    P(309.0, 207.0), P(309.0, 209.0), P(309.0, 210.0), P(309.0, 211.0), 
+    P(310.0, 136.0), P(310.0, 137.0), P(310.0, 160.0), P(310.0, 161.0), 
+    P(310.0, 162.0), P(310.0, 172.0), P(310.0, 173.0), P(310.0, 174.0), 
+    P(310.0, 176.0), P(310.0, 180.0), P(310.0, 181.0), P(310.0, 201.0), 
+    P(310.0, 202.0), P(310.0, 203.0), P(310.0, 204.0), P(310.0, 205.0), 
+    P(310.0, 215.0), P(310.0, 216.0), P(310.0, 217.0), P(310.0, 218.0), 
+    P(310.0, 219.0), P(310.0, 220.0), P(310.0, 221.0), P(310.0, 222.0), 
+    P(310.0, 223.0), P(311.0, 138.0), P(311.0, 144.0), P(311.0, 145.0), 
+    P(311.0, 146.0), P(311.0, 147.0), P(311.0, 148.0), P(311.0, 149.0), 
+    P(311.0, 150.0), P(311.0, 151.0), P(311.0, 152.0), P(311.0, 153.0), 
+    P(311.0, 158.0), P(311.0, 167.0), P(311.0, 176.0), P(311.0, 225.0), 
+    P(311.0, 226.0), P(311.0, 227.0), P(311.0, 230.0), P(311.0, 231.0), 
+    P(311.0, 232.0), P(311.0, 419.0), P(312.0, 155.0), P(312.0, 156.0), 
+    P(312.0, 168.0), P(312.0, 169.0), P(312.0, 234.0), P(312.0, 235.0), 
+    P(312.0, 237.0), P(312.0, 239.0), P(312.0, 240.0), P(312.0, 242.0), 
+    P(312.0, 419.0), P(313.0, 140.0), P(313.0, 141.0), P(313.0, 237.0), 
+    P(313.0, 242.0), P(313.0, 420.0), P(313.0, 421.0), P(313.0, 422.0), 
+    P(313.0, 423.0), P(313.0, 424.0), P(313.0, 425.0), P(313.0, 426.0), 
+    P(313.0, 427.0), P(313.0, 428.0), P(314.0, 245.0), P(314.0, 263.0), 
+    P(314.0, 264.0), P(314.0, 429.0), P(315.0, 246.0), P(315.0, 262.0), 
+    P(315.0, 264.0), P(316.0, 246.0), P(316.0, 262.0), P(316.0, 264.0), 
+    P(317.0, 260.0), P(317.0, 261.0), P(317.0, 264.0), P(317.0, 432.0), 
+    P(318.0, 248.0), P(318.0, 258.0), P(318.0, 264.0), P(318.0, 434.0), 
+    P(318.0, 435.0), P(319.0, 250.0), P(319.0, 251.0), P(319.0, 256.0), 
+    P(320.0, 253.0), P(320.0, 254.0), P(321.0, 267.0), P(321.0, 268.0), 
+    P(321.0, 269.0), P(321.0, 294.0), P(322.0, 296.0), P(322.0, 297.0), 
+    P(322.0, 298.0), P(322.0, 299.0), P(322.0, 439.0), P(323.0, 272.0), 
+    P(323.0, 292.0), P(323.0, 293.0), P(323.0, 299.0), P(324.0, 273.0), 
+    P(324.0, 281.0), P(324.0, 282.0), P(324.0, 290.0), P(324.0, 292.0), 
+    P(324.0, 299.0), P(324.0, 441.0), P(325.0, 280.0), P(325.0, 282.0), 
+    P(325.0, 283.0), P(325.0, 300.0), P(325.0, 301.0), P(325.0, 443.0), 
+    P(325.0, 444.0), P(325.0, 445.0), P(325.0, 446.0), P(325.0, 447.0), 
+    P(325.0, 448.0), P(325.0, 449.0), P(325.0, 451.0), P(325.0, 454.0), 
+    P(326.0, 275.0), P(326.0, 277.0), P(326.0, 279.0), P(326.0, 290.0), 
+    P(326.0, 451.0), P(326.0, 454.0), P(326.0, 456.0), P(327.0, 277.0), 
+    P(327.0, 285.0), P(327.0, 287.0), P(327.0, 289.0), P(328.0, 287.0), 
+    P(328.0, 305.0), P(328.0, 307.0), P(328.0, 309.0), P(328.0, 312.0), 
+    P(328.0, 313.0), P(328.0, 314.0), P(329.0, 307.0), P(329.0, 316.0), 
+    P(329.0, 460.0), P(330.0, 317.0), P(330.0, 462.0), P(331.0, 317.0), 
+    P(332.0, 317.0), P(332.0, 464.0), P(333.0, 328.0), P(333.0, 329.0), 
+    P(333.0, 330.0), P(333.0, 331.0), P(333.0, 332.0), P(333.0, 333.0), 
+    P(333.0, 334.0), P(333.0, 335.0), P(333.0, 336.0), P(333.0, 337.0), 
+    P(333.0, 339.0), P(333.0, 464.0), P(334.0, 317.0), P(334.0, 327.0), 
+    P(334.0, 340.0), P(334.0, 341.0), P(334.0, 342.0), P(334.0, 464.0), 
+    P(335.0, 317.0), P(335.0, 464.0), P(336.0, 317.0), P(336.0, 344.0), 
+    P(337.0, 317.0), P(338.0, 324.0), P(338.0, 346.0), P(338.0, 361.0), 
+    P(338.0, 362.0), P(338.0, 363.0), P(338.0, 364.0), P(339.0, 318.0), 
+    P(339.0, 348.0), P(339.0, 358.0), P(339.0, 359.0), P(340.0, 319.0), 
+    P(340.0, 320.0), P(340.0, 321.0), P(340.0, 322.0), P(340.0, 468.0), 
+    P(340.0, 469.0), P(341.0, 350.0), P(341.0, 367.0), P(341.0, 471.0), 
+    P(341.0, 472.0), P(341.0, 473.0), P(342.0, 351.0), P(342.0, 352.0), 
+    P(342.0, 353.0), P(342.0, 354.0), P(342.0, 368.0), P(342.0, 475.0), 
+    P(343.0, 369.0), P(343.0, 476.0), P(344.0, 369.0), P(344.0, 376.0), 
+    P(344.0, 377.0), P(344.0, 378.0), P(344.0, 380.0), P(344.0, 391.0), 
+    P(344.0, 392.0), P(344.0, 476.0), P(345.0, 369.0), P(345.0, 375.0), 
+    P(345.0, 380.0), P(345.0, 383.0), P(345.0, 384.0), P(345.0, 385.0), 
+    P(345.0, 386.0), P(345.0, 391.0), P(345.0, 394.0), P(346.0, 395.0), 
+    P(347.0, 372.0), P(347.0, 396.0), P(347.0, 477.0), P(348.0, 372.0), 
+    P(348.0, 395.0), P(348.0, 477.0), P(349.0, 394.0), P(349.0, 395.0), 
+    P(350.0, 478.0), P(351.0, 395.0), P(351.0, 479.0), P(352.0, 395.0), 
+    P(352.0, 481.0), P(352.0, 482.0), P(353.0, 484.0), P(353.0, 485.0), 
+    P(353.0, 486.0), P(353.0, 487.0), P(353.0, 488.0), P(353.0, 489.0), 
+    P(354.0, 396.0), P(354.0, 490.0), P(355.0, 397.0), P(355.0, 403.0), 
+    P(356.0, 399.0), P(356.0, 400.0), P(356.0, 401.0), P(356.0, 405.0), 
+    P(356.0, 491.0), P(357.0, 416.0), P(357.0, 491.0), P(358.0, 408.0), 
+    P(358.0, 416.0), P(358.0, 418.0), P(358.0, 419.0), P(358.0, 491.0), 
+    P(359.0, 410.0), P(359.0, 411.0), P(359.0, 412.0), P(359.0, 419.0), 
+    P(359.0, 420.0), P(359.0, 492.0), P(360.0, 421.0), P(360.0, 493.0), 
+    P(361.0, 423.0), P(361.0, 424.0), P(361.0, 426.0), P(361.0, 428.0), 
+    P(362.0, 426.0), P(363.0, 430.0), P(363.0, 495.0), P(364.0, 432.0), 
+    P(365.0, 497.0), P(366.0, 434.0), P(367.0, 435.0), P(367.0, 498.0), 
+    P(367.0, 499.0), P(367.0, 500.0), P(368.0, 499.0), P(368.0, 500.0), 
+    P(369.0, 438.0), P(369.0, 502.0), P(370.0, 440.0), P(370.0, 502.0), 
+    P(371.0, 441.0), P(372.0, 442.0), P(372.0, 443.0), P(372.0, 444.0), 
+    P(372.0, 447.0), P(372.0, 503.0), P(373.0, 449.0), P(373.0, 503.0), 
+    P(374.0, 503.0), P(375.0, 451.0), P(375.0, 503.0), P(376.0, 504.0), 
+    P(377.0, 449.0), P(377.0, 450.0), P(377.0, 505.0), P(378.0, 507.0), 
+    P(378.0, 508.0), P(379.0, 451.0), P(379.0, 509.0), P(380.0, 452.0), 
+    P(381.0, 452.0), P(381.0, 510.0), P(382.0, 511.0), P(384.0, 454.0), 
+    P(385.0, 454.0), P(387.0, 455.0), P(388.0, 455.0), P(391.0, 466.0), 
+    P(391.0, 467.0), P(391.0, 468.0), P(392.0, 463.0), P(392.0, 464.0), 
+    P(393.0, 460.0), P(393.0, 461.0), P(393.0, 471.0), P(394.0, 471.0), 
+    P(397.0, 473.0), P(398.0, 473.0), P(400.0, 474.0), P(403.0, 477.0), 
+    P(404.0, 479.0), P(406.0, 482.0), P(406.0, 483.0), P(407.0, 484.0), 
+    P(407.0, 485.0), P(408.0, 486.0), P(409.0, 484.0), P(409.0, 485.0), 
+    P(410.0, 484.0), P(413.0, 486.0), P(414.0, 487.0), P(414.0, 488.0), 
+    P(414.0, 489.0), P(414.0, 490.0), P(414.0, 491.0), P(416.0, 494.0), 
+    P(417.0, 494.0), P(418.0, 494.0), P(420.0, 495.0), P(423.0, 497.0), 
+    P(424.0, 497.0), P(425.0, 497.0), P(426.0, 498.0), P(427.0, 499.0), 
+    P(428.0, 499.0), P(430.0, 498.0), P(430.0, 499.0), P(436.0, 503.0), 
+    P(438.0, 504.0), P(440.0, 504.0), P(440.0, 505.0), P(442.0, 503.0), 
+    P(442.0, 505.0), P(444.0, 501.0), P(445.0, 501.0), P(448.0, 499.0), 
+    P(448.0, 500.0), P(450.0, 501.0), P(450.0, 502.0), P(452.0, 504.0), 
+    P(453.0, 505.0), P(453.0, 506.0), P(454.0, 508.0), P(455.0, 510.0), 
+    P(455.0, 511.0)
+};
+
+#endif // VIGRA_CONVEX_HULL_TEST_HXX
diff --git a/test/math/test.cxx b/test/math/test.cxx
new file mode 100755
index 0000000..0bd76ca
--- /dev/null
+++ b/test/math/test.cxx
@@ -0,0 +1,3103 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2004-2011 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ == 95
+// deactivate broken std::relops
+#  define __SGI_STL_INTERNAL_RELOPS
+#endif  // __GNUC__
+
+#include <typeinfo>
+#include <iostream>
+#include <iomanip>
+#include <algorithm>
+#include <sstream>
+#include <cstdlib>
+#include "vigra/unittest.hxx"
+#include "vigra/mathutil.hxx"
+#include "vigra/algorithm.hxx"
+#include "vigra/functorexpression.hxx"
+#include "vigra/polynomial.hxx"
+#include "vigra/array_vector.hxx"
+#include "vigra/splines.hxx"
+#include "vigra/gaussians.hxx"
+#include "vigra/rational.hxx"
+#include "vigra/fixedpoint.hxx"
+#include "vigra/autodiff.hxx"
+#include "vigra/linear_algebra.hxx"
+#include "vigra/singular_value_decomposition.hxx"
+#include "vigra/regression.hxx"
+#include "vigra/random.hxx"
+#include "vigra/tinyvector.hxx"
+#include "vigra/polygon.hxx"
+#include "vigra/quaternion.hxx"
+#include "vigra/clebsch-gordan.hxx"
+#include "vigra/bessel.hxx"
+#include "vigra/timing.hxx"
+#include "convex_hull_test.hxx"
+
+#define VIGRA_TOLERANCE_MESSAGE "If this test fails, please adjust the tolerance threshold and report\n" \
+                       "your findings (including compiler information etc.) to the VIGRA mailing list:"
+
+static double coefficients[][12] =
+{
+    { 5.0, -416.0, 720.0, -464.0, 136.0, -18.0, 1.0 },
+    { 8.0, 40320.0, -109584.0, 118124.0, -67284.0, 22449.0, -4536.0, 546.0, -36.0, 1.0},
+    { 3.0, 1e10, -1e10, -1e-10, 1e-10},
+    { 3.0, 1e-10, -1e-10, -1e10, 1e10},
+    { 10.0, 2.88e-8, -1.848e-6, 0.00005204, -0.0008458, 0.008777,
+           -0.06072, 0.2835, -0.882, 1.75, -2.0, 1.0},
+    { 5.0, 0.3411268890719874, 0.48265610836623374, 0.29941395284477745,
+           0.13065520631476124, 0.68342489290545338, 0.0017437185812028133 },
+    { 3.0, -1.0, 1000001000001.0 / 1e6, -1000001000001.0 / 1e6, 1.0},
+    { 8.0, 36.0, 0.0, 85.0, 0.0, 63.0, 0.0, 15.0, 0.0, 1.0 }
+};
+
+typedef std::complex<double> C;
+
+static C reference[][12] =
+{
+    { C(1e-12), C(2.0), C(2.0), C(2.0), C(6.0, -4.0), C(6.0, 4.0) },
+    { C(1e-11), C(1.0), C(2.0), C(3.0), C(4.0), C(5.0), C(6.0), C(7.0), C(8.0) },
+    { C(1e-12), C(-1e10), C(1.0), C(1e10) },
+    { C(1e-12), C(-1e-10), C(1e-10), C(1.0) },
+    { C(1e-5), C(0.1), C(0.1), C(0.1), C(0.1), C(0.2), C(0.2), C(0.2),
+               C(0.3), C(0.3), C(0.4) },
+    { C(1e-12), C(-391.74516023901123),
+                C(-0.56839260551055271, -0.4046562986541693), C(-0.56839260551055271, 0.4046562986541693),
+                C(0.47331479192572767, -0.89542786425410759), C(0.47331479192572767, 0.89542786425410759) },
+    { C(1e-12), C(1e-6), C(1.0), C(1e6) },
+    { C(1e-12), C(0.0, -3.0), C(0.0, -2.0), C(0.0, -1.0), C(0.0, -1.0),
+                C(0.0, 1.0), C(0.0, 1.0), C(0.0, 2.0), C(0.0, 3.0) }
+};
+
+#if 0
+#undef should
+#define should(v) (std::cerr << #v << ": " << (v) << std::endl)
+#undef shouldEqual
+#define shouldEqual(v1, v2) \
+(std::cerr << #v1 << " == " << #v2 << ": " << (v1) << " " << (v2) << std::endl)
+#undef shouldEqualTolerance
+#define shouldEqualTolerance(v1, v2, e) \
+(std::cerr << #v1 << " == " << #v2 << ": " << (v1) << " " << (v2) << " " << (v1 - v2) << std::endl)
+#endif
+
+template <unsigned int N, class POLYNOMIAL>
+struct PolynomialTest
+{
+    void testPolynomial()
+    {
+        double epsilon = reference[N][0].real();
+        unsigned int order = (unsigned int)(coefficients[N][0] + 0.5);
+        POLYNOMIAL p(coefficients[N]+1, order);
+
+        vigra::ArrayVector<std::complex<double> > roots;
+
+        should(polynomialRoots(p, roots));
+        shouldEqual(roots.size(), order);
+        for(unsigned int i = 0; i<roots.size(); ++i)
+        {
+            shouldEqualTolerance(roots[i].real(), reference[N][i+1].real(), epsilon);
+            shouldEqualTolerance(roots[i].imag(), reference[N][i+1].imag(), epsilon);
+        }
+    }
+
+    void testPolynomialEigenvalueMethod()
+    {
+        double epsilon = 1e-7;
+        unsigned int order = (unsigned int)(coefficients[N][0] + 0.5);
+        POLYNOMIAL p(coefficients[N]+1, order);
+        p.setEpsilon(epsilon);
+
+        vigra::ArrayVector<std::complex<double> > roots;
+
+        should(polynomialRootsEigenvalueMethod(p, roots));
+        shouldEqual(roots.size(), order);
+        for(unsigned int i = 0; i<roots.size(); ++i)
+        {
+            shouldEqualTolerance(roots[i].real(), reference[N][i+1].real(), epsilon);
+            shouldEqualTolerance(roots[i].imag(), reference[N][i+1].imag(), epsilon);
+        }
+    }
+};
+
+struct HighOrderPolynomialTest
+{
+    void testPolynomial()
+    {
+        unsigned int order = 80;
+        double epsilon = 1e-12;
+        vigra::ArrayVector<double> coeffs(order+1, 0.0);
+        coeffs[0] = -1.0;
+        coeffs[order] = 1.0;
+        vigra::Polynomial<double> p(coeffs.begin(), order);
+
+        vigra::ArrayVector<std::complex<double> > roots;
+
+        should(vigra::polynomialRoots(p, roots));
+        shouldEqual(roots.size(), order);
+        for(unsigned int i = 0; i<roots.size(); ++i)
+        {
+            shouldEqualTolerance(std::abs(roots[i]), 1.0, epsilon);
+            C r = p(roots[i]);
+            shouldEqualTolerance(r.real(), 0.0, epsilon);
+            shouldEqualTolerance(r.imag(), 0.0, epsilon);
+        }
+        vigra::ArrayVector<double> rroots;
+        should(polynomialRealRoots(p, rroots));
+        shouldEqual(rroots.size(), 2u);
+        shouldEqualTolerance(rroots[0], -1.0, epsilon);
+        shouldEqualTolerance(rroots[1], 1.0, epsilon);
+    }
+
+    void testPolynomialEigenvalueMethod()
+    {
+        unsigned int order = 80;
+        double epsilon = 1e-12;
+        vigra::ArrayVector<double> coeffs(order+1, 0.0);
+        coeffs[0] = -1.0;
+        coeffs[order] = 1.0;
+        vigra::Polynomial<double> p(coeffs.begin(), order);
+
+        vigra::ArrayVector<std::complex<double> > roots;
+
+        should(vigra::polynomialRootsEigenvalueMethod(p, roots));
+        shouldEqual(roots.size(), order);
+        for(unsigned int i = 0; i<roots.size(); ++i)
+        {
+            shouldEqualTolerance(std::abs(roots[i]), 1.0, epsilon);
+            C r = p(roots[i]);
+            shouldEqualTolerance(r.real(), 0.0, epsilon);
+            shouldEqualTolerance(r.imag(), 0.0, epsilon);
+        }
+        vigra::ArrayVector<double> rroots;
+        should(polynomialRealRootsEigenvalueMethod(p, rroots));
+        shouldEqual(rroots.size(), 2u);
+        shouldEqualTolerance(rroots[0], -1.0, epsilon);
+        shouldEqualTolerance(rroots[1], 1.0, epsilon);
+    }
+};
+
+template <int ORDER>
+struct SplineTest
+{
+    typedef vigra::BSpline<ORDER, double> BS;
+    typedef vigra::BSplineBase<ORDER, double> BSB;
+    BS spline;
+    BSB splineBase;
+
+    void testValues()
+    {
+        double r = spline.radius();
+        shouldEqual(r, splineBase.radius());
+
+        for(int d = 0; d <= ORDER+1; ++d)
+        {
+            for(double x = -r-0.5; x <= r+0.5; x += 0.5)
+                shouldEqualTolerance(spline(x, d), splineBase(x, d), 1e-15);
+        }
+    }
+
+    void testFixedPointValues()
+    {
+        double r = spline.radius();
+        shouldEqual(r, splineBase.radius());
+
+        for(double x = -r-0.5; x <= r+0.5; x += 0.5)
+        {
+            vigra::FixedPoint<11,20> fpx20(x);
+            vigra::FixedPoint<11,15> fpx15(x);
+            should(vigra::abs(vigra::fixed_point_cast<double>(spline(fpx20)) - spline(x)) < 1e-6);
+            should(vigra::abs(vigra::fixed_point_cast<double>(spline(fpx15)) - spline(x)) < 4e-5);
+
+        }
+    }
+
+    void testPrefilterCoefficients()
+    {
+        int n = ORDER / 2;
+        vigra::ArrayVector<double> const & ps = spline.prefilterCoefficients();
+        vigra::ArrayVector<double> const & psb = splineBase.prefilterCoefficients();
+
+        if(n == 0)
+        {
+            shouldEqual(ps.size(), 0u);
+            shouldEqual(psb.size(), 0u);
+        }
+        else
+        {
+            vigra::ArrayVector<double> & psb1 =
+                const_cast<vigra::ArrayVector<double> &>(psb);
+            std::sort(psb1.begin(), psb1.end());
+
+            for(int i = 0; i < n; ++i)
+                shouldEqualTolerance(ps[i], psb[i], 1e-14);
+        }
+    }
+
+    void testWeightMatrix()
+    {
+        int n = ORDER + 1;
+        typename BS::WeightMatrix const & ws = BS::weights();
+        typename BSB::WeightMatrix const & wsb = BSB::weights();
+
+        for(int d = 0; d < n; ++d)
+            for(int i = 0; i < n; ++i)
+                shouldEqualTolerance(ws[d][i], wsb[d][i], 1e-14);
+    }
+};
+
+struct FunctionsTest
+{
+    void testGaussians()
+    {
+        vigra::Gaussian<double> g,
+                          g1(2.0, 1),
+                          g2(1.0, 2),
+                          g3(2.0, 3),
+                          g4(2.0, 4),
+                          g5(2.0, 5);
+
+        double epsilon = 1e-15;
+        shouldEqual(g.derivativeOrder(), 0u);
+        shouldEqual(g.sigma(), 1.0);
+        shouldEqualTolerance(g(0.0), 0.3989422804014327, epsilon);
+        shouldEqualTolerance(g(0.5), 0.35206532676429952, epsilon);
+        shouldEqualTolerance(g(1.0), 0.24197072451914337, epsilon);
+        shouldEqualTolerance(g(-1.0), 0.24197072451914337, epsilon);
+
+        shouldEqual(g1.derivativeOrder(), 1u);
+        shouldEqual(g1.sigma(), 2.0);
+        shouldEqualTolerance(g1(0.0), 0, epsilon);
+        shouldEqualTolerance(g1(0.5), -0.024166757300178077, epsilon);
+        shouldEqualTolerance(g1(1.0), -0.044008165845537441, epsilon);
+        shouldEqualTolerance(g1(-1.0), 0.044008165845537441, epsilon);
+
+        shouldEqual(g2.derivativeOrder(), 2u);
+        shouldEqual(g2.sigma(), 1.0);
+        shouldEqualTolerance(g2(0.0), -0.3989422804014327, epsilon);
+        shouldEqualTolerance(g2(0.5), -0.26404899507322466, epsilon);
+        shouldEqualTolerance(g2(1.0), 0, epsilon);
+        shouldEqualTolerance(g2(-1.0), 0, epsilon);
+        shouldEqualTolerance(g2(1.5), 0.16189699458236467, epsilon);
+        shouldEqualTolerance(g2(-1.5), 0.16189699458236467, epsilon);
+
+        shouldEqual(g3.derivativeOrder(), 3u);
+        shouldEqual(g3.sigma(), 2.0);
+        shouldEqualTolerance(g3(0.0), 0, epsilon);
+        shouldEqualTolerance(g3(0.5), 0.017747462392318277, epsilon);
+        shouldEqualTolerance(g3(1.0), 0.030255614018806987, epsilon);
+        shouldEqualTolerance(g3(-1.0), -0.030255614018806987, epsilon);
+        shouldEqualTolerance(g3(2.0*VIGRA_CSTD::sqrt(3.0)), 0, epsilon);
+        shouldEqualTolerance(g3(-2.0*VIGRA_CSTD::sqrt(3.0)), 0, epsilon);
+
+        shouldEqualTolerance(g4(0.0), 0.037400838787634318, epsilon);
+        shouldEqualTolerance(g4(1.0), 0.017190689783413062, epsilon);
+        shouldEqualTolerance(g4(-1.0), 0.017190689783413062, epsilon);
+        shouldEqualTolerance(g4(1.483927568605452), 0, epsilon);
+        shouldEqualTolerance(g4(4.668828436677955), 0, epsilon);
+        shouldEqualTolerance(g5(0.0), 0, epsilon);
+        shouldEqualTolerance(g5(1.0), -0.034553286464660257, epsilon);
+        shouldEqualTolerance(g5(-1.0), 0.034553286464660257, epsilon);
+        shouldEqualTolerance(g5(2.711252359948531), 0, epsilon);
+        shouldEqualTolerance(g5(5.713940027745611), 0, epsilon);
+    }
+
+    void testSpecialIntegerFunctions()
+    {
+        for(vigra::Int32 i = 0; i < 1024; ++i)
+        {
+            shouldEqual(vigra::sqrti(i), (vigra::Int32)vigra::floor(vigra::sqrt((double)i)));
+        }
+
+        shouldEqual(vigra::roundi(0.0), 0);
+        shouldEqual(vigra::roundi(1.0), 1);
+        shouldEqual(vigra::roundi(1.1), 1);
+        shouldEqual(vigra::roundi(1.6), 2);
+        shouldEqual(vigra::roundi(-1.0), -1);
+        shouldEqual(vigra::roundi(-1.1), -1);
+        shouldEqual(vigra::roundi(-1.6), -2);
+
+        vigra::UInt32 roundPower2[] = {0, 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 0xffff, 0x7fffffff, 0x80000000, 0x80000001, 0xffffffff};
+        vigra::UInt32 floorResult[] = {0, 1, 2, 2, 4, 4, 4, 8, 8, 8, 16, 0x8000, 0x40000000, 0x80000000, 0x80000000, 0x80000000};
+        vigra::UInt32 ceilResult[] = {0, 1, 2, 4, 4, 8, 8, 8, 16, 16, 16, 0x10000, 0x80000000, 0x80000000, 0, 0};
+        for(unsigned int i = 0; i < sizeof(roundPower2) / sizeof(vigra::UInt32); ++i)
+        {
+            shouldEqual(vigra::floorPower2(roundPower2[i]), floorResult[i]);
+            shouldEqual(vigra::ceilPower2(roundPower2[i]), ceilResult[i]);
+        }
+
+        for(vigra::Int32 k=0; k<32; ++k)
+        {
+            shouldEqual(vigra::log2i(1 << k), k);
+            shouldEqual(vigra::log2i((1 << k) + 1), k == 0 ? 1 : k);
+            shouldEqual(vigra::log2i((1 << k) - 1), k-1);
+        }
+
+        should(vigra::even(0));
+        should(!vigra::odd(0));
+        should(!vigra::even(1));
+        should(vigra::odd(1));
+        should(vigra::even(2));
+        should(!vigra::odd(2));
+        should(!vigra::even(-1));
+        should(vigra::odd(-1));
+        should(vigra::even(-2));
+        should(!vigra::odd(-2));
+    }
+
+
+    void testSpecialFunctions()
+    {
+        shouldEqualTolerance(vigra::ellipticIntegralE(M_PI / 2.0, 0.0), M_PI / 2.0, 1e-14);
+        shouldEqualTolerance(vigra::ellipticIntegralF(0.3, 0.3), 0.30039919311549118, 1e-14);
+        shouldEqualTolerance(vigra::ellipticIntegralE(0.3, 0.3), 0.29960175507025716, 1e-14);
+
+        shouldEqualTolerance(vigra::erf(0.3), 0.32862675945912745, 1e-7);
+
+        should(vigra::noncentralChi2CDFApprox(200, 0.0, 200.0) > 0.5);
+        should(vigra::noncentralChi2CDFApprox(200, 0.0, 199.0) < 0.5);
+        should(vigra::noncentralChi2CDF(200, 0.0, 200.0) > 0.5);
+        should(vigra::noncentralChi2CDF(200, 0.0, 199.0) < 0.5);
+
+        shouldEqualTolerance(vigra::noncentralChi2CDF(2, 2.0, 2.0), 0.34574583872316456, 1e-7);
+        shouldEqualTolerance(vigra::noncentralChi2(2, 2.0, 2.0), 0.154254161276835, 1e-7);
+        shouldEqualTolerance(vigra::noncentralChi2CDF(3, 2.0, 2.0), 0.22073308707450343, 1e-7);
+        shouldEqualTolerance(vigra::noncentralChi2(3, 2.0, 2.0), 0.13846402271767755, 1e-7);
+        shouldEqualTolerance(vigra::noncentralChi2CDFApprox(2, 2.0, 2.0), 0.34574583872316456, 1e-1);
+        shouldEqualTolerance(vigra::noncentralChi2CDFApprox(3, 2.0, 2.0), 0.22073308707450343, 1e-1);
+
+        for(double x = -4.0; x <= 4.0; x += 1.0)
+        {
+            shouldEqual(vigra::sin_pi(x), 0.0);
+            shouldEqual(vigra::cos_pi(x+0.5), 0.0);
+        }
+        
+        for(double x = -4.5; x <= 4.5; x += 2.0)
+        {
+            shouldEqual(vigra::sin_pi(x), -1.0);
+            shouldEqual(vigra::cos_pi(x+0.5), 1.0);
+        }
+        
+        for(double x = -3.5; x <= 4.5; x += 2.0)
+        {
+            shouldEqual(vigra::sin_pi(x), 1.0);
+            shouldEqual(vigra::cos_pi(x+0.5), -1.0);
+        }
+        
+        for(double x = -4.0; x <= 4.0; x += 0.0625)
+        {
+            shouldEqualTolerance(vigra::sin_pi(x), std::sin(M_PI*x), 1e-14);
+            shouldEqualTolerance(vigra::cos_pi(x), std::cos(M_PI*x), 1e-14);
+        }
+
+        shouldEqualTolerance(vigra::sin_pi(0.25), 0.5*M_SQRT2, 2e-16);
+        shouldEqualTolerance(vigra::cos_pi(0.25), 0.5*M_SQRT2, 2e-16);
+
+        shouldEqual(vigra::gamma(4.0), 6.0);
+        shouldEqualTolerance(vigra::gamma(0.1), 9.5135076986687306, 1e-15);
+        shouldEqualTolerance(vigra::gamma(3.2), 2.4239654799353683, 1e-15);
+        shouldEqualTolerance(vigra::gamma(170.2), 1.1918411166366696e+305, 1e-15);
+        shouldEqualTolerance(vigra::gamma(-0.1), -10.686287021193193, 1e-14);
+        shouldEqualTolerance(vigra::gamma(-3.2), 0.689056412005979, 1e-14);
+        shouldEqualTolerance(vigra::gamma(-170.2), -2.6348340538196879e-307, 1e-14);
+        try { vigra::gamma(0.0); failTest("No exception thrown"); } catch(vigra::PreconditionViolation &) {}
+        try { vigra::gamma(-1.0); failTest("No exception thrown"); } catch(vigra::PreconditionViolation &) {}
+
+        shouldEqual(vigra::loggamma(1.0), 0.0);
+        shouldEqual(vigra::loggamma(2.0), 0.0);
+        shouldEqualTolerance(vigra::loggamma(4.0e-22), 49.2705776847491144296, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(0.1), 2.2527126517342055401, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(0.3), 1.0957979948180756047, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(0.8), 0.15205967839983755563, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(1.1), -0.049872441259839757344, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(1.3), -0.10817480950786048655, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(1.8), -0.071083872914372153717, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(3.0), 0.69314718055994528623, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(3.1), 0.78737508327386251938, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(4.0), 1.79175946922805500081, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(8.0), 8.5251613610654143002, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(1000.0), 5905.2204232091812118261, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(1000.2), 5906.6018942569799037, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(2.8e+17), 1.096859847946237952e+19, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(2.9e+17), 1.1370510622188449792e+19, 1e-15);
+        shouldEqualTolerance(vigra::loggamma(5.7646075230342349e+17), 2.2998295812288974848e+19, 1e-15);
+        try { vigra::loggamma(0.0); failTest("No exception thrown"); } catch(vigra::PreconditionViolation &) {}
+        try { vigra::loggamma(-1.0); failTest("No exception thrown"); } catch(vigra::PreconditionViolation &) {}
+
+        double args[5] = {0.0, 1.0, 0.7, -0.7, -1.0};
+        for(int i=0; i<5; ++i)
+        {
+            double x = args[i], x2 = x*x;
+            shouldEqualTolerance(vigra::legendre(0, x), 1.0, 1e-15);
+            shouldEqualTolerance(vigra::legendre(1, x), x, 1e-15);
+            shouldEqualTolerance(vigra::legendre(2, x), 0.5*(3.0*x2-1.0), 1e-15);
+            shouldEqualTolerance(vigra::legendre(3, x), 0.5*x*(5.0*x2-3.0), 1e-15);
+
+            shouldEqualTolerance(vigra::legendre(0, 0, x), 1.0, 1e-15);
+            shouldEqualTolerance(vigra::legendre(1, 0, x), x, 1e-15);
+            shouldEqualTolerance(vigra::legendre(1, 1, x), -std::sqrt(1.0-x2), 1e-15);
+            shouldEqualTolerance(vigra::legendre(2, 0, x), 0.5*(3.0*x2-1.0), 1e-15);
+            shouldEqualTolerance(vigra::legendre(2, 1, x), -3.0*x*std::sqrt(1.0-x2), 1e-15);
+            shouldEqualTolerance(vigra::legendre(2, 2, x), 3.0*(1.0-x2), 1e-15);
+            shouldEqualTolerance(vigra::legendre(4, 2, x), 7.5*(7.0*x2-1.0)*(1.0-x2), 1e-15);
+            shouldEqualTolerance(vigra::legendre(1, -1, x), -vigra::legendre(1, 1, x) / 2.0, 1e-15);
+            shouldEqualTolerance(vigra::legendre(2, -1, x), -vigra::legendre(2, 1, x) / 6.0, 1e-15);
+            shouldEqualTolerance(vigra::legendre(2, -2, x), vigra::legendre(2, 2, x) / 24.0, 1e-15);
+        }
+    }
+
+    void testBessel()
+    {
+        // Reference values computed to 16 digits with Python.mpmath. 
+        // Casual comparison showed no difference to Mathematica's results.
+        double x[] = { 1.0, 4.0, 6.0 };
+        double besseljnref[] = {
+            7.6519768655796649e-01, -3.9714980986384740e-01, 1.5064525725099692e-01, 
+            5.7672480775687329e-01, -3.2757913759146523e-01, -4.6828234823458334e-03, 
+            4.8609126058589103e-01, -2.4287320996018547e-01, -1.1299172042407525e-01, 
+            4.3017147387562193e-01, -1.6755558799533424e-01, -1.8093519033665686e-01, 
+            3.9123236045864818e-01, -1.0535743487538894e-01, -2.1960268610200856e-01, 
+            3.6208707488717234e-01, -5.5038855669513713e-02, -2.3828585178317879e-01, 
+            3.3919660498317961e-01, -1.4458842084785106e-02, -2.4372476722886663e-01, 
+            3.2058907797982628e-01, 1.8376032647858614e-02, -2.4057094958616052e-01, 
+            3.0506707225300012e-01, 4.5095329080457235e-02, -2.3197310306707983e-01, 
+            2.9185568526512001e-01, 6.6976198673670620e-02, -2.2004622511384700e-01, 
+            2.8042823052537585e-01, 8.5006705446061023e-02, -2.0620569442259729e-01, 
+            2.7041248255096445e-01, 9.9950477050301592e-02, -1.9139539469541733e-01, 
+            2.6153687541034509e-01, 1.1240023492610679e-01, -1.7624117645477547e-01, 
+            2.5359797330294920e-01, 1.2281915265293869e-01, -1.6115376768165826e-01, 
+            2.4643993656993257e-01, 1.3157198580936999e-01, -1.4639794400255970e-01    
+        };
+        double besselynref[] = {
+            8.8256964215676956e-02, -1.6940739325064992e-02, -2.8819468398157916e-01, 
+            -1.0703243154093754e-01, 1.4786314339122683e-01, -3.0266723702418485e-01, 
+            -1.6040039348492374e-01, 2.2985790254811306e-01, -2.6303660482037811e-01, 
+            -1.8202211595348500e-01, 2.6808060304231507e-01, -2.0509487811877961e-01, 
+            -1.9214228737369318e-01, 2.8294322431117191e-01, -1.4494951186809379e-01, 
+            -1.9706088806443733e-01, 2.8511777841103764e-01, -8.9252841434580163e-02, 
+            -1.9930679029227036e-01, 2.8035255955745608e-01, -4.0297251103395833e-02, 
+            -2.0006390460040860e-01, 2.7184139484930947e-01, 1.5698795407253514e-03, 
+            -1.9994686666043449e-01, 2.6140472921203017e-01, 3.6815736940746704e-02, 
+            -1.9929926580524435e-01, 2.5009898312668521e-01, 6.6197858895869655e-02, 
+            -1.9832403085028555e-01, 2.3854272714494473e-01, 9.0526604143921052e-02, 
+            -1.9714613354518651e-01, 2.2709735924007149e-01, 1.1056356972736049e-01, 
+            -1.9584504763522584e-01, 2.1597027298252575e-01, 1.2698414345087472e-01, 
+            -1.9447256680104227e-01, 2.0527533641239212e-01, 1.4036965442780550e-01, 
+            -1.9306306446008192e-01, 1.9506914688206353e-01, 1.5121244335755843e-01        
+        };
+
+        for(int n = 0; n < 15; ++n)
+        {
+            if(n == 0)
+                shouldEqual(vigra::besselJ(n, 0.0), 1.0);
+            else
+                shouldEqual(vigra::besselJ(n, 0.0), 0.0);
+            should(vigra::besselY(n, 0.0) == -std::numeric_limits<double>::infinity());
+
+            for(int k=0; k<3; ++k)
+            {
+                double f = vigra::odd(n) ? -1.0 : 1.0;
+                double eps = 1e-14;
+                shouldEqualTolerance(vigra::besselJ(n, x[k]+n) - besseljnref[k+3*n], 0.0, eps);
+                shouldEqualTolerance(vigra::besselJ(-n, x[k]+n) - f*besseljnref[k+3*n], 0.0, eps);
+                shouldEqualTolerance(vigra::besselY(n, x[k]+n) - besselynref[k+3*n], 0.0, eps);
+                shouldEqualTolerance(vigra::besselY(-n, x[k]+n) - f*besselynref[k+3*n], 0.0, eps);
+            }
+        }
+    }
+
+    void closeAtToleranceTest()
+    {
+        double a = 0.0, b = vigra::NumericTraits<double>::epsilon(), c = 1000.0, d = 1000.1;
+
+        using vigra::closeAtTolerance;
+        should(closeAtTolerance(a, b));
+        should(closeAtTolerance(c, c + b));
+        should(closeAtTolerance(c, d, 1.0));
+        should(closeAtTolerance(-a, -b));
+        should(closeAtTolerance(-c, -c + b));
+        should(closeAtTolerance(-c, -d, 1.0));
+        should(!closeAtTolerance(c, -c));
+        should(!closeAtTolerance(a, c));
+        should(!closeAtTolerance(c, d));
+        should(!closeAtTolerance(-a, -c));
+        should(!closeAtTolerance(-c, -d));
+    }
+
+    void testArgMinMax()
+    {
+        using namespace vigra;
+        using namespace vigra::functor;
+
+        double data[] = {1.0, 5.0,
+                         3.0, 2.0,
+                        -2.0, 4.0};
+        double *end = data + 6;
+
+        shouldEqual(argMin(data, end), data+4);
+        shouldEqual(argMax(data, end), data+1);
+        shouldEqual(argMinIf(data, end, Arg1() > Param(0.0)), data);
+        shouldEqual(argMinIf(data, end, Arg1() > Param(5.0)), end);
+        shouldEqual(argMaxIf(data, end, Arg1() < Param(5.0)), data+5);
+        shouldEqual(argMaxIf(data, end, Arg1() < Param(-2.0)), end);
+    }
+
+    void testAlgorithms()
+    {
+        static const int size = 6;
+        int index[size];
+
+        vigra::linearSequence(index, index+size);
+        int indexref[size] = {0, 1, 2, 3, 4, 5};
+        shouldEqualSequence(index, index+size, indexref);
+
+        vigra::linearSequence(index, index+size, 5, 5);
+        int indexref2[size] = {5, 10, 15, 20, 25, 30};
+        shouldEqualSequence(index, index+size, indexref2);
+
+        double data[size] = {1.0, 5.0,
+                         3.0, 2.0,
+                        -2.0, 4.0};
+
+        vigra::indexSort(data, data+size, index, std::greater<double>());
+        int sortref[size] = {1, 5, 2, 3, 0, 4};
+        shouldEqualSequence(index, index+size, sortref);
+
+        vigra::indexSort(data, data+size, index);
+        int sortref2[size] = {4, 0, 3, 2, 5, 1};
+        shouldEqualSequence(index, index+size, sortref2);
+
+        double res[size];
+        vigra::applyPermutation(index, index+size, data, res);
+        double ref[size] = {-2.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
+        shouldEqualSequence(res, res+size, ref);
+
+        int inverse[size];
+        vigra::inversePermutation(index, index+size, inverse);
+        int inverseref[size] = {1, 5, 3, 2, 0, 4};
+        shouldEqualSequence(inverse, inverse+size, inverseref);
+
+        vigra::applyPermutation(inverse, inverse+size, ref, res);
+        shouldEqualSequence(res, res+size, data);
+    }
+
+    void testChecksum()
+    {
+        std::string s("");
+        vigra::UInt32 crc = vigra::checksum(s.c_str(), s.size());
+        shouldEqual(crc, 0u);
+
+        s = "hello world";
+        crc = vigra::checksum(s.c_str(), s.size());
+        shouldEqual(crc, 222957957u);
+
+        s = "hallo world";
+        crc = vigra::checksum(s.c_str(), s.size());
+        shouldEqual(crc, 77705727u);
+
+        int split = 5;
+        std::string s1 = s.substr(0, split), s2 = s.substr(split);
+        crc = vigra::checksum(s1.c_str(), s1.size());
+        crc = vigra::concatenateChecksum(crc, s2.c_str(), s2.size());
+        shouldEqual(crc, 77705727u);
+
+        const int size = 446;
+        char t[size+1] =  
+            "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
+            "sed do eiusmod tempor incididunt ut labore et dolore magna "
+            "aliqua. Ut enim ad minim veniam, quis nostrud exercitation "
+            "ullamco laboris nisi ut aliquip ex ea commodo consequat. "
+            "Duis aute irure dolor in reprehenderit in voluptate velit "
+            "esse cillum dolore eu fugiat nulla pariatur. Excepteur "
+            "sint occaecat cupidatat non proident, sunt in culpa qui "
+            "officia deserunt mollit anim id est laborum.";
+
+        crc = vigra::checksum(t, size);
+        shouldEqual(crc, 2408722991u);
+
+        for(split = 64; split < 80; ++split) // check alignment
+        {
+            crc = vigra::checksum(t, split);
+            crc = vigra::concatenateChecksum(crc, t+split, size-split);
+            shouldEqual(crc, 2408722991u);
+        }
+    }
+
+    void testClebschGordan()
+    {
+        using vigra::clebschGordan;
+
+        shouldEqualTolerance(clebschGordan(0.5, 0.5, 0.5, 0.5, 1.0, 1.0), std::sqrt(1.0), 1e-15);
+        shouldEqualTolerance(clebschGordan(0.5, 0.5, 0.5, -0.5, 1.0, 0.0), std::sqrt(0.5), 1e-15);
+        shouldEqualTolerance(clebschGordan(0.5, -0.5, 0.5, 0.5, 1.0, 0.0), std::sqrt(0.5), 1e-15);
+        shouldEqualTolerance(clebschGordan(0.5, 0.5, 0.5, -0.5, 0.0, 0.0), std::sqrt(0.5), 1e-15);
+        shouldEqualTolerance(clebschGordan(0.5, -0.5, 0.5, 0.5, 0.0, 0.0), -std::sqrt(0.5), 1e-15);
+
+        shouldEqualTolerance(clebschGordan(2.0, 2.0, 0.5, 0.5, 2.5, 2.5), std::sqrt(1.0), 1e-15);
+        shouldEqualTolerance(clebschGordan(2.0, 2.0, 0.5, -0.5, 2.5, 1.5), std::sqrt(0.2), 1e-15);
+        shouldEqualTolerance(clebschGordan(2.0, 1.0, 0.5, 0.5, 2.5, 1.5), std::sqrt(0.8), 1e-15);
+        shouldEqualTolerance(clebschGordan(2.0, 2.0, 0.5, -0.5, 1.5, 1.5), std::sqrt(0.8), 1e-15);
+        shouldEqualTolerance(clebschGordan(2.0, 1.0, 0.5, 0.5, 1.5, 1.5), -std::sqrt(0.2), 1e-15);
+    }
+};
+
+struct RationalTest
+{
+    typedef vigra::Rational<int> R;
+
+    void testGcdLcm()
+    {
+        shouldEqual(vigra::gcd(24, 18), 6);
+        shouldEqual(vigra::lcm(6, 4), 12);
+        shouldEqual(vigra::gcd(18, 24), 6);
+        shouldEqual(vigra::lcm(4, 6), 12);
+    }
+
+    void testOStreamShifting()
+    {
+        std::ostringstream out;
+        out << R(1,2);
+        out << "Testing.." << R(42,23) << 3.141592653589793238 << std::endl;
+    }
+
+    void testOperators()
+    {
+        shouldEqual(R(3,4), R(3,4));
+        shouldEqual(-R(3,4), R(-3,4));
+
+        shouldEqual(R(3,4) + R(12,6), R(11,4));
+        shouldEqual(R(3,4) - R(12,6), R(-5,4));
+        shouldEqual(R(3,4) * R(12,6), R(3,2));
+        shouldEqual(R(3,4) / R(12,6), R(3,8));
+
+        shouldEqual(abs(R(-3,4)), R(3,4));
+        shouldEqual(norm(R(-3,4)), R(3,4));
+        shouldEqual(squaredNorm(R(-3,4)), R(9,16));
+
+        should(R(3,4) == R(9,12));
+        should(R(3,4) != R(12,6));
+        should(R(3,4) < R(12,6));
+        should(R(19,4) > R(12,6));
+        should(R(3,4) <= R(12,6));
+        should(R(19,4) >= R(12,6));
+
+        shouldEqual(R(3,4) + 2, R(11,4));
+        shouldEqual(R(3,4) - 2, R(-5,4));
+        shouldEqual(R(3,4) * 2, R(3,2));
+        shouldEqual(R(3,4) / 2, R(3,8));
+        should(!(R(3,4) == 2));
+        should(R(3,4) != 2);
+        should(R(3,4) < 2);
+        should(R(19,4) > 2);
+        should(R(3,4) <= 2);
+        should(R(19,4) >= 2);
+
+        shouldEqual(2 + R(3,4), R(11,4));
+        shouldEqual(2 - R(3,4), R(5,4));
+        shouldEqual(2 * R(3,4), R(3,2));
+        shouldEqual(2 / R(3,4), R(8, 3));
+        should(!(2 == R(3,4)));
+        should(2 != R(3,4));
+        should(2 > R(3,4));
+        should(2 < R(19,4));
+        should(2 >= R(3,4));
+        should(2 <= R(19,4));
+    }
+
+    void testConversion()
+    {
+        shouldEqual(vigra::rational_cast<R>(R(3,2)), R(3,2));
+        shouldEqual(vigra::rational_cast<int>(R(3,2)), 1);
+        shouldEqual(vigra::rational_cast<double>(R(3,2)), 1.5);
+        shouldEqual(vigra::rational_cast<double>(1.5), 1.5);
+
+        shouldEqual(R(vigra::Rational<short>((short)-2, (short)-4)), R(1,2));
+
+        shouldEqual(R(3.5, 1e-4), R(7,2));
+        shouldEqual(R(-3.5, 1e-4), R(-7,2));
+        shouldEqual(R(0.123, 1e-4), R(123,1000));
+        shouldEqual(R(-0.123, 1e-4), R(-123,1000));
+        shouldEqual(R(0.123456, 1e-4), R(1235,10000));
+        shouldEqual(R(0.123432, 1e-4), R(1234,10000));
+        shouldEqual(R(-0.123456, 1e-4), R(-1235,10000));
+        shouldEqual(R(-0.123432, 1e-4), R(-1234,10000));
+    }
+
+    void testFunctions()
+    {
+        shouldEqual(pow(R(1,2),2), R(1,4));
+        shouldEqual(pow(R(2),-2), R(1,4));
+        shouldEqual(pow(R(-1,2),2), R(1,4));
+        shouldEqual(pow(R(-2),-2), R(1,4));
+        shouldEqual(pow(R(-1,2),3), R(-1,8));
+        shouldEqual(pow(R(-2),-3), R(-1,8));
+        shouldEqual(pow(R(3),0), R(1));
+        shouldEqual(pow(R(0),3), R(0));
+        shouldEqual(pow(R(0),0), R(1));
+        should(pow(R(0),-3).is_pinf());
+
+        should(pow(R(1,0, false), 1).is_pinf());
+        should(pow(R(-1,0, false), 1).is_ninf());
+        shouldEqual(pow(R(1,0, false), -1), R(0));
+        shouldEqual(pow(R(-1,0, false), -1), R(0));
+        try { pow(R(1,0, false), 0); failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { pow(R(-1,0, false), 0); failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+
+        shouldEqual(floor(R(2)), R(2));
+        shouldEqual(floor(R(3,2)), R(1));
+        shouldEqual(floor(R(1,2)), R(0));
+        shouldEqual(floor(R(-1,2)), R(-1));
+        shouldEqual(floor(R(1,-2)), R(-1));
+        shouldEqual(floor(R(-3,2)), R(-2));
+        shouldEqual(floor(R(-2)), R(-2));
+        shouldEqual(floor(R(1,0,false)), R(1,0,false));
+        shouldEqual(floor(R(-1,0,false)), R(-1,0,false));
+
+        shouldEqual(ceil(R(2)), R(2));
+        shouldEqual(ceil(R(3,2)), R(2));
+        shouldEqual(ceil(R(1,2)), R(1));
+        shouldEqual(ceil(R(-1,2)), R(0));
+        shouldEqual(ceil(R(1,-2)), R(0));
+        shouldEqual(ceil(R(-3,2)), R(-1));
+        shouldEqual(ceil(R(-2)), R(-2));
+        shouldEqual(ceil(R(1,0,false)), R(1,0,false));
+        shouldEqual(ceil(R(-1,0,false)), R(-1,0,false));
+    }
+
+    void testInf()
+    {
+        R inf(2,0);
+        R ninf(-2,0);
+
+        should(inf.is_inf());
+        should(inf.is_pinf());
+        should(!inf.is_ninf());
+        should(ninf.is_inf());
+        should(ninf.is_ninf());
+        should(!ninf.is_pinf());
+        shouldEqual(inf.numerator(), 1);
+        shouldEqual(ninf.numerator(), -1);
+
+        should((inf + R(1)).is_pinf());
+        should((inf + R(0)).is_pinf());
+        should((inf + R(-1)).is_pinf());
+        should((ninf + R(1)).is_ninf());
+        should((ninf + R(0)).is_ninf());
+        should((ninf + R(-1)).is_ninf());
+        should((inf + 1).is_pinf());
+        should((inf + 0).is_pinf());
+        should((inf + (-1)).is_pinf());
+        should((ninf + 1).is_ninf());
+        should((ninf + 0).is_ninf());
+        should((ninf + (-1)).is_ninf());
+        should((inf + inf).is_pinf());
+        should((ninf + ninf).is_ninf());
+        shouldEqual((inf + R(3)).numerator(), 1);
+        shouldEqual((ninf + R(3)).numerator(), -1);
+
+        should((inf - R(1)).is_pinf());
+        should((inf - R(0)).is_pinf());
+        should((inf - R(-1)).is_pinf());
+        should((ninf - R(1)).is_ninf());
+        should((ninf - R(0)).is_ninf());
+        should((ninf - R(-1)).is_ninf());
+        should((inf - 1).is_pinf());
+        should((inf - 0).is_pinf());
+        should((inf - (-1)).is_pinf());
+        should((ninf - 1).is_ninf());
+        should((ninf - 0).is_ninf());
+        should((ninf - (-1)).is_ninf());
+        should((inf - ninf).is_pinf());
+        should((ninf - inf).is_ninf());
+        shouldEqual((inf - R(3)).numerator(), 1);
+        shouldEqual((ninf - R(3)).numerator(), -1);
+
+        should((inf * R(1)).is_pinf());
+        should((inf * R(-1)).is_ninf());
+        should((ninf * R(1)).is_ninf());
+        should((ninf * R(-1)).is_pinf());
+        should((inf * 1).is_pinf());
+        should((inf * (-1)).is_ninf());
+        should((ninf * 1).is_ninf());
+        should((ninf * (-1)).is_pinf());
+        should((inf * inf).is_pinf());
+        should((inf * ninf).is_ninf());
+        should((ninf * inf).is_ninf());
+        should((ninf * ninf).is_pinf());
+        shouldEqual((inf * R(3)).numerator(), 1);
+        shouldEqual((ninf * R(3)).numerator(), -1);
+        shouldEqual((inf * R(-3)).numerator(), -1);
+        shouldEqual((ninf * R(-3)).numerator(), 1);
+
+        should((inf / R(1)).is_pinf());
+        should((inf / R(0)).is_pinf());
+        should((inf / R(-1)).is_ninf());
+        should((ninf / R(1)).is_ninf());
+        should((ninf / R(0)).is_ninf());
+        should((ninf / R(-1)).is_pinf());
+        shouldEqual(R(1) / inf, R(0));
+        shouldEqual(R(-1) / inf, R(0));
+        shouldEqual(R(1) / ninf, R(0));
+        shouldEqual(R(-1) / ninf, R(0));
+        should((inf / 1).is_pinf());
+        should((inf / 0).is_pinf());
+        should((inf / (-1)).is_ninf());
+        should((ninf / 1).is_ninf());
+        should((ninf / 0).is_ninf());
+        should((ninf / (-1)).is_pinf());
+
+        shouldEqual(2 / inf, R(0));
+        shouldEqual((-2) / inf, R(0));
+        shouldEqual(2 / ninf, R(0));
+        shouldEqual((-2) / ninf, R(0));
+        shouldEqual((2 / inf).denominator(), 1);
+        shouldEqual(((-2) / inf).denominator(), 1);
+        shouldEqual((2 / ninf).denominator(), 1);
+        shouldEqual(((-2) / ninf).denominator(), 1);
+
+        shouldEqual((inf / R(3)).numerator(), 1);
+        shouldEqual((ninf / R(3)).numerator(), -1);
+        shouldEqual((inf / R(-3)).numerator(), -1);
+        shouldEqual((ninf / R(-3)).numerator(), 1);
+
+        should(inf == inf);
+        should(!(inf != inf));
+        should(!(inf < inf));
+        should(inf <= inf);
+        should(!(inf > inf));
+        should(inf >= inf);
+        should(ninf == ninf);
+        should(!(ninf != ninf));
+        should(!(ninf < ninf));
+        should(ninf <= ninf);
+        should(!(ninf > ninf));
+        should(ninf >= ninf);
+        should(inf != ninf);
+        should(ninf != inf);
+        should(inf > ninf);
+        should(ninf < inf);
+        should(!(inf < ninf));
+        should(!(ninf > inf));
+
+        should(inf != 0);
+        should(ninf != 0);
+        should(inf > 0);
+        should(inf >= 0);
+        should(ninf < 0);
+        should(ninf <= 0);
+        should(!(0 < ninf));
+        should(!(0 > inf));
+        should(!(0 <= ninf));
+        should(!(0 >= inf));
+
+        should(inf != R(1));
+        should(ninf != R(1));
+        should(inf > R(1));
+        should(inf >= R(1));
+        should(ninf < R(1));
+        should(ninf <= R(1));
+        should(!(R(1) < ninf));
+        should(!(R(1) > inf));
+        should(!(R(1) <= ninf));
+        should(!(R(1) >= inf));
+
+        try { inf + ninf; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { ninf + inf; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { inf - inf; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { ninf - ninf; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { inf * R(0); failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { ninf * R(0); failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { R(0) * inf; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { R(0) * ninf; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { inf * 0; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { ninf * 0; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { 0 * inf; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { 0 * ninf; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { inf / inf; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { inf / ninf; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { ninf / inf; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { R(0) / R(0); failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { R(0) / 0; failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+        try { 0 / R(0); failTest("No exception thrown"); } catch(vigra::bad_rational &) {}
+    }
+};
+
+struct AutodiffTest
+{
+    typedef vigra::autodiff::DualVector<double, 1> N1;
+    typedef vigra::autodiff::DualVector<double, 2> N2;
+
+    void testOStreamShifting()
+    {
+        std::ostringstream out;
+        out << N1(1.0,2.0);
+        out << "Testing.." << N1(42.0,23.0) << 3.141592653589793238 << std::endl;
+    }
+
+    void testOperators()
+    {
+        should(N2(3.0,4.0,5.0).value() == 3.0);
+        should(N2(3.0,4.0,5.0).gradient() == N2::Gradient(4.0,5.0));
+        should(N2(3.0,4.0,5.0) == N2(3.0, N2::Gradient(4.0,5.0)));
+
+        should(N1(3.0,4.0) == N1(3.0,4.0));
+        should(!(N1(3.0,4.0) == N1(2.0,4.0)));
+        should(!(N1(3.0,4.0) == N1(3.0,2.0)));
+        should(!(N1(3.0,4.0) != N1(3.0,4.0)));
+        should(N1(3.0,4.0) != N1(2.0,4.0));
+        should(N1(3.0,4.0) != N1(3.0,2.0));
+        should(closeAtTolerance(N1(3.0,4.0), N1(3.0,4.0)));
+        should(!closeAtTolerance(N1(3.0,4.0), N1(2.0,4.0)));
+        should(!closeAtTolerance(N1(3.0,4.0), N1(3.0,2.0)));
+        should(closeAtTolerance(N1(3.0,4.0), N1(2.0,4.0), 1.0));
+        should(closeAtTolerance(N1(3.0,4.0), N1(3.0,2.0), 1.0));
+
+        shouldEqual(N1(3.0,4.0), N1(3.0,4.0));
+        shouldEqual(-N1(3.0,4.0), N1(-3.0,-4.0));
+
+        vigra::TinyVector<N2, 2> v = vigra::autodiff::dualMatrix(vigra::TinyVector<double, 2>(2.0, 3.0));
+        shouldEqual(v[0], N2(2.0, 1.0, 0.0));
+        shouldEqual(v[1], N2(3.0, 0.0, 1.0));
+
+        shouldEqual(N2(5.0,1.0,0.0) + N2(2.0,0.0,1.0), N2(7.0,1.0,1.0));
+        shouldEqual(N2(5.0,1.0,0.0) - N2(2.0,0.0,1.0), N2(3.0,1.0,-1.0));
+        shouldEqual(N2(5.0,1.0,0.0) * N2(2.0,0.0,1.0), N2(10.0,2.0,5.0));
+        shouldEqual(N2(5.0,1.0,0.0) / N2(2.0,0.0,1.0), N2(2.5,0.5,-1.25));
+
+        shouldEqual(5.0 + N2(2.0,0.0,1.0), N2(7.0,0.0,1.0));
+        shouldEqual(5.0 - N2(2.0,0.0,1.0), N2(3.0,0.0,-1.0));
+        shouldEqual(5.0 * N2(2.0,0.0,1.0), N2(10.0,0.0,5.0));
+        shouldEqual(5.0 / N2(2.0,0.0,1.0), N2(2.5,0.0,-1.25));
+
+        shouldEqual(N2(5.0,1.0,0.0) + 2.0, N2(7.0,1.0,0.0));
+        shouldEqual(N2(5.0,1.0,0.0) - 2.0, N2(3.0,1.0,0.0));
+        shouldEqual(N2(5.0,1.0,0.0) * 2.0, N2(10.0,2.0,0.0));
+        shouldEqual(N2(5.0,1.0,0.0) / 2.0, N2(2.5,0.5,0.0));
+
+        shouldEqual(abs(N1(3.0,4.0)), N1(3.0,4.0));
+        shouldEqual(abs(N1(-3.0,4.0)), N1(3.0,-4.0));
+        shouldEqual(abs(N1(-3.0,-4.0)), N1(3.0,4.0));
+        shouldEqual(abs(N1(3.0,-4.0)), N1(3.0,-4.0));
+
+        shouldEqual(max(N2(5.0,1.0,0.0), N2(2.0,0.0,1.0)), N2(5.0,1.0,0.0));
+        shouldEqual(min(N2(5.0,1.0,0.0), N2(2.0,0.0,1.0)), N2(2.0,0.0,1.0));
+        shouldEqual(max(5.0, N2(2.0,0.0,1.0)), N2(5.0,0.0,0.0));
+        shouldEqual(min(5.0, N2(2.0,0.0,1.0)), N2(2.0,0.0,1.0));
+        shouldEqual(max(N2(5.0,1.0,0.0), 2.0), N2(5.0,1.0,0.0));
+        shouldEqual(min(N2(5.0,1.0,0.0), 2.0), N2(2.0,0.0,0.0));
+
+        should(N2(1.0, 1.0, 0.0) < N2(2.0, 0.0, 1.0));
+        should(!(N2(1.0, 1.0, 0.0) < N2(1.0, 0.0, 1.0)));
+        should(N2(1.0, 1.0, 0.0) < 1.1);
+        should(!(N2(1.0, 1.0, 0.0) < 1.0));
+        should(0.8 < N2(2.0, 0.0, 1.0));
+        should(!(2.0 < N2(2.0, 0.0, 1.0)));
+
+        should(N2(1.0, 1.0, 0.0) <= N2(2.0, 0.0, 1.0));
+        should(N2(1.0, 1.0, 0.0) <= N2(1.0, 0.0, 1.0));
+        should(N2(1.0, 1.0, 0.0) <= 1.1);
+        should(N2(1.0, 1.0, 0.0) <= 1.0);
+        should(0.8 <= N2(2.0, 0.0, 1.0));
+        should(2.0 <= N2(2.0, 0.0, 1.0));
+
+        should(N2(2.0, 1.0, 0.0) > N2(1.0, 0.0, 1.0));
+        should(!(N2(1.0, 1.0, 0.0) > N2(1.0, 0.0, 1.0)));
+        should(N2(2.0, 1.0, 0.0) > 1.1);
+        should(!(N2(1.0, 1.0, 0.0) > 1.0));
+        should(2.8 > N2(2.0, 0.0, 1.0));
+        should(!(2.0 > N2(2.0, 0.0, 1.0)));
+
+        should(N2(2.0, 1.0, 0.0) >= N2(1.0, 0.0, 1.0));
+        should(N2(1.0, 1.0, 0.0) >= N2(1.0, 0.0, 1.0));
+        should(N2(2.0, 1.0, 0.0) >= 1.1);
+        should(N2(1.0, 1.0, 0.0) >= 1.0);
+        should(2.8 >= N2(2.0, 0.0, 1.0));
+        should(2.0 >= N2(2.0, 0.0, 1.0));
+    }
+
+    void testFunctions()
+    {
+        // check numbers
+        should(closeAtTolerance(log(N1(M_E, 1.0)), N1(1.0, 1.0 / M_E)));
+        should(closeAtTolerance(exp(N1(0.0, 1.0)), N1(1.0, 1.0)));
+        should(closeAtTolerance(sqrt(N1(4.0, 1.0)), N1(2.0, 0.25)));
+        should(closeAtTolerance(sq(N1(3.0, 1.0)), N1(9.0, 6.0)));
+        should(closeAtTolerance(sin(N1(M_PI_2, 1.0)), N1(1.0, 0.0)));
+        should(closeAtTolerance(sin(N1(M_PI, 1.0)), N1(0.0, -1.0)));
+        should(closeAtTolerance(sin_pi(N1(0.5, 1.0)), N1(1.0, 0.0)));
+        should(closeAtTolerance(sin_pi(N1(1.0, 1.0)), N1(0.0, -M_PI)));
+        should(closeAtTolerance(cos(N1(0.0, 1.0)), N1(1.0, 0.0)));
+        should(closeAtTolerance(cos(N1(M_PI_2, 1.0)), N1(0.0, -1.0)));
+        should(closeAtTolerance(cos_pi(N1(1.0, 1.0)), N1(-1.0, 0.0)));
+        should(closeAtTolerance(cos_pi(N1(0.5, 1.0)), N1(0.0, -M_PI)));
+        should(closeAtTolerance(asin(N1(0.5, 1.0)), N1(M_PI/6.0, 2.0/sqrt(3.0)), 1e-15));
+        should(closeAtTolerance(acos(N1(0.5, 1.0)), N1(M_PI/3.0, -2.0/sqrt(3.0)), 1e-15));
+        should(closeAtTolerance(tan(N1(M_PI/4.0, 1.0)), N1(1.0, 2.0)));
+        should(closeAtTolerance(atan(N1(1.0, 1.0)), N1(0.25*M_PI, 0.5)));
+        should(closeAtTolerance(sinh(N1(1.0, 1.0)), N1(sinh(1.0), cosh(1.0))));
+        should(closeAtTolerance(cosh(N1(1.0, 1.0)), N1(cosh(1.0), sinh(1.0))));
+        should(closeAtTolerance(tanh(N1(0.0, 1.0)), N1(0.0, 1.0)));
+        should(closeAtTolerance(atan2(N2(-1.0, 1.0, 0.0), N2(-1.0, 0.0, 1.0)), N2(-0.75*M_PI, -0.5, 0.5)));
+        should(closeAtTolerance(pow(N1(3.0, 1.0), 2.0), N1(9.0, 6.0)));
+        should(closeAtTolerance(pow(3.0, N1(2.0, 1.0)), N1(9.0, 9.0*log(3.0))));
+        should(closeAtTolerance(pow(N2(3.0, 1.0, 0.0), N2(2.0, 0.0, 1.0)), N2(9.0, 6.0, 9.0*log(3.0))));
+        
+        // check constraints
+        N1 x(2.3, 1.0);
+        N2 a(1.2,2.3,3.4), b(4.5,5.6,6.7);
+        should(closeAtTolerance(sq(sqrt(a)), a));
+        should(closeAtTolerance(exp(log(a)), a));
+        should(closeAtTolerance(sq(sin(x)) + sq(cos(x)), N1(1.0, 0.0), 1e-13));
+        should(closeAtTolerance(sin(2.0*a), 2.0*cos(a)*sin(a), 1e-13));
+        should(closeAtTolerance(cos(2.0*a), sq(cos(a)) - sq(sin(a)), 1e-13));
+        should(closeAtTolerance(sin(a) / cos(a), tan(a), 1e-13));
+        should(closeAtTolerance(tan(atan(a)), a, 1e-13));
+        should(closeAtTolerance(sq(cosh(x)) - sq(sinh(x)), N1(1.0, 0.0), 1e-13));
+        should(closeAtTolerance(tanh(a+b), (tanh(a) + tanh(b)) / (1.0 + tanh(a) * tanh(b)), 1e-12));
+        should(closeAtTolerance(atan2(b*sin(a), b*cos(a)), a, 1e-13));
+        should(closeAtTolerance(pow(a, 1.0), a));
+        should(closeAtTolerance(pow(pow(a, b), 1.0 / b), a, 1e-13));
+
+        vigra::BSpline<0, double> s0;
+        vigra::BSpline<1, double> s1;
+        vigra::BSpline<2, double> s2;
+        vigra::BSpline<3, double> s3;
+        vigra::BSpline<4, double> s4;
+        vigra::BSpline<5, double> s5;
+
+        for(double x=-3.3; x < 3.5; x += 0.5)
+        {
+            N1 r = s0(N1(x, 0));
+            should(vigra::closeAtTolerance(r.value(), s0(x), 1e-15));
+            should(vigra::closeAtTolerance(r.gradient()[0], s0(x,1), 1e-13));
+
+            r = s1(N1(x, 0));
+            should(vigra::closeAtTolerance(r.value(), s1(x), 1e-15));
+            should(vigra::closeAtTolerance(r.gradient()[0], s1(x,1), 1e-13));
+
+            r = s2(N1(x, 0));
+            should(vigra::closeAtTolerance(r.value(), s2(x), 1e-15));
+            should(vigra::closeAtTolerance(r.gradient()[0], s2(x,1), 1e-13));
+
+            r = s3(N1(x, 0));
+            should(vigra::closeAtTolerance(r.value(), s3(x), 1e-15));
+            should(vigra::closeAtTolerance(r.gradient()[0], s3(x,1), 1e-13));
+
+            r = s4(N1(x, 0));
+            should(vigra::closeAtTolerance(r.value(), s4(x), 1e-15));
+            should(vigra::closeAtTolerance(r.gradient()[0], s4(x,1), 1e-13));
+
+            r = s5(N1(x, 0));
+            should(vigra::closeAtTolerance(r.value(), s5(x), 1e-15));
+            should(vigra::closeAtTolerance(r.gradient()[0], s5(x,1), 1e-13));
+        }
+    }
+};
+
+struct QuaternionTest
+{
+    typedef vigra::Quaternion<double> Q;
+    typedef Q::Vector V;
+
+    void testContents()
+    {
+        Q q(1.0, 2.0, 3.0, 4.0), q0, q1(-1.0), q2(q), q3(q.w(), q.v());
+
+        shouldEqual(q.w(), 1.0);
+        shouldEqual(q.v(), V(2.0, 3.0, 4.0));
+        shouldEqual(q0.w(), 0.0);
+        shouldEqual(q0.v(), V(0.0, 0.0, 0.0));
+        shouldEqual(q1.w(), -1.0);
+        shouldEqual(q1.v(), V(0.0, 0.0, 0.0));
+        shouldEqual(q2.w(), 1.0);
+        shouldEqual(q2.v(), V(2.0, 3.0, 4.0));
+        shouldEqual(q3.w(), 1.0);
+        shouldEqual(q3.v(), V(2.0, 3.0, 4.0));
+
+        shouldEqual(q[0], 1.0);
+        shouldEqual(q[1], 2.0);
+        shouldEqual(q[2], 3.0);
+        shouldEqual(q[3], 4.0);
+        shouldEqual(q.x(), 2.0);
+        shouldEqual(q.y(), 3.0);
+        shouldEqual(q.z(), 4.0);
+
+        should(q == q2);
+        should(q1 != q2);
+
+        q2 = q1;
+        shouldEqual(q2.w(), -1.0);
+        shouldEqual(q2.v(), V(0.0, 0.0, 0.0));
+
+        should(q != q2);
+        should(q1 == q2);
+
+        q3 = 10.0;
+        shouldEqual(q3.w(), 10.0);
+        shouldEqual(q3.v(), V(0.0, 0.0, 0.0));
+
+        q2.setW(-2.0);
+        shouldEqual(q2.w(), -2.0);
+        shouldEqual(q2.v(), V(0.0, 0.0, 0.0));
+
+        q2.setV(V(5.0, 6.0, 7.0));
+        shouldEqual(q2.w(), -2.0);
+        shouldEqual(q2.v(), V(5.0, 6.0, 7.0));
+
+        q3.setV(5.0, 6.0, 7.0);
+        shouldEqual(q3.w(), 10.0);
+        shouldEqual(q3.v(), V(5.0, 6.0, 7.0));
+
+        q3.setX(2.0);
+        q3.setY(3.0);
+        q3.setZ(4.0);
+        shouldEqual(q3.w(), 10.0);
+        shouldEqual(q3.v(), V(2.0, 3.0, 4.0));
+
+        shouldEqual(q.squaredMagnitude(), 30.0);
+        shouldEqual(squaredNorm(q), 30.0);
+        shouldEqualTolerance(q.magnitude(), std::sqrt(30.0), 1e-15);
+        shouldEqualTolerance(norm(q), std::sqrt(30.0), 1e-15);
+        shouldEqual(norm(q), abs(q));
+    }
+
+    void testStreamIO()
+    {
+        std::ostringstream out;
+        Q q(1.0, 2.0, 3.0, 4.0);
+
+        out << q;
+        shouldEqual(out.str(), "1 2 3 4");
+
+        std::istringstream in;
+        in.str("10 11 12 13");
+        in >> q;
+        shouldEqual(q, Q(10.0, 11.0, 12.0, 13.0));
+    }
+
+    void testOperators()
+    {
+        Q q(1.0, 2.0, 3.0, 4.0);
+
+        shouldEqual(+q, q);
+        shouldEqual(-q, Q(-1,-2,-3,-4));
+
+        shouldEqual(q+q, Q(2,4,6,8));
+        shouldEqual(q+2.0, Q(3,2,3,4));
+        shouldEqual(2.0+q, Q(3,2,3,4));
+
+        shouldEqual(Q(2,4,6,8) - q, q);
+        shouldEqual(q-2.0, Q(-1,2,3,4));
+        shouldEqual(2.0-q, Q(1,-2,-3,-4));
+
+        shouldEqual(Q(1,0,0,0)*Q(1,0,0,0), Q(1,0,0,0));
+        shouldEqual(Q(0,1,0,0)*Q(0,1,0,0), Q(-1,0,0,0));
+        shouldEqual(Q(0,0,1,0)*Q(0,0,1,0), Q(-1,0,0,0));
+        shouldEqual(Q(0,0,0,1)*Q(0,0,0,1), Q(-1,0,0,0));
+
+        shouldEqual(Q(0,1,0,0)*Q(0,0,1,0), Q(0,0,0,1));
+        shouldEqual(Q(0,0,1,0)*Q(0,1,0,0), Q(0,0,0,-1));
+        shouldEqual(Q(0,0,1,0)*Q(0,0,0,1), Q(0,1,0,0));
+        shouldEqual(Q(0,0,0,1)*Q(0,0,1,0), Q(0,-1,0,0));
+        shouldEqual(Q(0,0,0,1)*Q(0,1,0,0), Q(0,0,1,0));
+        shouldEqual(Q(0,1,0,0)*Q(0,0,0,1), Q(0,0,-1,0));
+
+        shouldEqual(q*q, Q(-28,4,6,8));
+        shouldEqual(q*2.0, Q(2,4,6,8));
+        shouldEqual(2.0*q, Q(2,4,6,8));
+
+        Q q1 = q / q;       
+        shouldEqualTolerance(q1[0], 1.0, 1e-16);
+        shouldEqualTolerance(q1[1], 0.0, 1e-16);
+        shouldEqualTolerance(q1[2], 0.0, 1e-16);
+        shouldEqualTolerance(q1[3], 0.0, 1e-16);
+        shouldEqual(Q(2,4,6,8)/2.0, q);
+        shouldEqual(60.0/q, Q(2,-4,-6,-8));
+
+        shouldEqualTolerance(norm(q / norm(q)), 1.0, 1e-15);
+    }
+
+    void testRotation()
+    {
+        Q q(1.0, 2.0, 3.0, 4.0);
+        q /= norm(q);
+
+        double ref[3][3] = {{-2.0/3.0,  0.4/3.0, 2.2/3.0 }, 
+                            { 2.0/3.0, -1.0/3.0, 2.0/3.0 },
+                            { 1.0/3.0,  2.8/3.0, 0.4/3.0 } };
+
+        vigra::Matrix<double> m(3,3), mref(3,3, (double*)ref);
+        q.fillRotationMatrix(m);
+        shouldEqualSequenceTolerance(m.begin(), m.end(), mref.begin(), 1e-15);
+
+        double res[3][3];
+        q.fillRotationMatrix(res);
+        shouldEqualSequenceTolerance((double*)res, (double*)res+9, (double*)ref, 1e-15);
+
+        Q q1 = Q::createRotation(M_PI/2.0, V(1,0,0));
+        Q q2 = Q::createRotation(M_PI/2.0, V(0,1,0));
+        Q q3 = Q::createRotation(M_PI/2.0, V(0,0,1));
+        Q q4 = q3*(-q1)*q2*q1;
+
+        shouldEqualTolerance(norm(q4), 1.0, 1e-15);
+        shouldEqualTolerance(q4[0], 0.0, 1e-15);
+    }
+};
+
+struct FixedPointTest
+{
+    void testConstruction()
+    {
+        shouldEqual(vigra::fixedPoint(3).value, 3);
+        shouldEqual(vigra::fixedPoint(-3).value, -3);
+        shouldEqual(-vigra::fixedPoint(3).value, -3);
+
+        shouldEqual((vigra::FixedPoint<3,4>(3).value), 3 << 4);
+        shouldEqual((vigra::FixedPoint<3,4>(-3).value), -3 << 4);
+        shouldEqual((-vigra::FixedPoint<3,4>(3).value), -3 << 4);
+
+        shouldEqual((vigra::FixedPoint<3,4>(3.5).value), 56);
+        shouldEqual((vigra::FixedPoint<3,4>(-3.5).value), -56);
+        shouldEqual((-vigra::FixedPoint<3,4>(3.5).value), -56);
+
+        try { vigra::FixedPoint<1, 8>(3.75); failTest("No exception thrown"); } catch(vigra::PreconditionViolation &) {}
+
+        shouldEqual((vigra::NumericTraits<vigra::FixedPoint<1, 8> >::zero()).value, 0);
+        shouldEqual((vigra::NumericTraits<vigra::FixedPoint<1, 8> >::one()).value, 1 << 8);
+        shouldEqual((vigra::NumericTraits<vigra::FixedPoint<1, 8> >::max()).value, (1 << 9) - 1);
+        shouldEqual((vigra::NumericTraits<vigra::FixedPoint<1, 8> >::min()).value, -((1 << 9) - 1));
+
+        vigra::FixedPoint<2, 8> v(3.75);
+        shouldEqual((vigra::FixedPoint<2, 8>(v).value), 15 << 6);
+        shouldEqual((vigra::FixedPoint<3, 10>(v).value), 15 << 8);
+        shouldEqual((vigra::FixedPoint<2, 2>(v).value), 15);
+        shouldEqual((vigra::FixedPoint<2, 0>(v).value), 4);
+
+        shouldEqual((vigra::FixedPoint<2, 8>(-v).value), -15 << 6);
+        shouldEqual((vigra::FixedPoint<3, 10>(-v).value), -15 << 8);
+        shouldEqual((vigra::FixedPoint<2, 2>(-v).value), -15);
+        shouldEqual((vigra::FixedPoint<2, 0>(-v).value), -4);
+
+        shouldEqual(vigra::fixed_point_cast<double>(v), 3.75);
+        should((frac(v) == vigra::FixedPoint<0, 8>(0.75)));
+        should((dual_frac(v) == vigra::FixedPoint<0, 8>(0.25)));
+        should(vigra::floor(v) == 3);
+        should(vigra::ceil(v) == 4);
+        should(round(v) == 4);
+        should(vigra::abs(v) == v);
+        should((frac(-v) == vigra::FixedPoint<0, 8>(0.25)));
+        should((dual_frac(-v) == vigra::FixedPoint<0, 8>(0.75)));
+        should(vigra::floor(-v) == -4);
+        should(vigra::ceil(-v) == -3);
+        should(round(-v) == -4);
+        should(vigra::abs(-v) == v);
+        should(vigra::norm(-v) == v);
+        should(vigra::squaredNorm(-v) == v*v);
+
+        vigra::FixedPoint<3, 10> v1;
+        shouldEqual((v1 = v).value, 15 << 8);
+        shouldEqual((v1 = -v).value, -15 << 8);
+
+        vigra::FixedPoint<2, 0> v2;
+        shouldEqual((v2 = v).value, 4);
+        shouldEqual((v2 = -v).value, -4);
+    }
+
+    void testComparison()
+    {
+        vigra::FixedPoint<3, 8> v1(3.75), v2(4);
+        vigra::FixedPoint<2, 2> v3(3.75);
+        should(v1 == v1);
+        should(v1 == v3);
+        should(!(v1 != v1));
+        should(!(v1 != v3));
+        should(v1 <= v1);
+        should(v1 <= v3);
+        should(!(v1 < v1));
+        should(!(v1 < v3));
+        should(v1 >= v1);
+        should(v1 >= v3);
+        should(!(v1 > v1));
+        should(!(v1 > v3));
+
+        should(v2 != v1);
+        should(v2 != v3);
+        should(!(v2 == v1));
+        should(!(v2 == v3));
+        should(!(v2 <= v1));
+        should(!(v2 <= v3));
+        should(!(v2 < v1));
+        should(!(v2 < v3));
+        should(v2 >= v1);
+        should(v2 >= v3);
+        should(v2 > v1);
+        should(v2 > v3);
+    }
+
+    void testArithmetic()
+    {
+        vigra::FixedPoint<1, 16> t1(0.75), t2(0.25);
+        signed char v1 = 1, v2 = 2, v4 = 4, v8 = 8;
+
+        should((vigra::FixedPoint<1, 16>(t1) += t1) == (vigra::FixedPoint<1, 16>(1.5)));
+        should((vigra::FixedPoint<1, 16>(t1) -= t1) == (vigra::FixedPoint<1, 16>(0.0)));
+        should((vigra::FixedPoint<2, 16>(t1) *= t1) == (vigra::FixedPoint<1, 16>(9.0 / 16.0)));
+
+        should(--t1 == (vigra::FixedPoint<1, 16>(-0.25)));
+        should(t1 == (vigra::FixedPoint<1, 16>(-0.25)));
+        should(++t1 == (vigra::FixedPoint<1, 16>(0.75)));
+        should(t1 == (vigra::FixedPoint<1, 16>(0.75)));
+        should(t1++ == (vigra::FixedPoint<1, 16>(0.75)));
+        should(t1 == (vigra::FixedPoint<1, 16>(1.75)));
+        should(t1-- == (vigra::FixedPoint<1, 16>(1.75)));
+        should(t1 == (vigra::FixedPoint<1, 16>(0.75)));
+
+        shouldEqual((t1 * vigra::fixedPoint(v1)).value, 3 << 14);
+        shouldEqual((t2 * vigra::fixedPoint(v1)).value, 1 << 14);
+        shouldEqual((-t1 * vigra::fixedPoint(v1)).value, -3 << 14);
+        shouldEqual((-t2 * vigra::fixedPoint(v1)).value, -1 << 14);
+        shouldEqual((t1 * -vigra::fixedPoint(v1)).value, -3 << 14);
+        shouldEqual((t2 * -vigra::fixedPoint(v1)).value, -1 << 14);
+
+        shouldEqual((vigra::FixedPoint<8, 2>(t1 * vigra::fixedPoint(v1))).value, 3);
+        shouldEqual((vigra::FixedPoint<8, 2>(t2 * vigra::fixedPoint(v1))).value, 1);
+        shouldEqual((vigra::FixedPoint<8, 2>(-t1 * vigra::fixedPoint(v1))).value, -3);
+        shouldEqual((vigra::FixedPoint<8, 2>(-t2 * vigra::fixedPoint(v1))).value, -1);
+
+        shouldEqual(vigra::floor(t1 * vigra::fixedPoint(v1) + t2 * vigra::fixedPoint(v2)), 1);
+        shouldEqual(vigra::ceil(t1 * vigra::fixedPoint(v1) + t2 * vigra::fixedPoint(v2)), 2);
+        shouldEqual(round(t1 * vigra::fixedPoint(v1) + t2 * vigra::fixedPoint(v2)), 1);
+        shouldEqual(vigra::floor(t1 * vigra::fixedPoint(v4) + t2 * vigra::fixedPoint(v8)), 5);
+        shouldEqual(vigra::ceil(t1 * vigra::fixedPoint(v4) + t2 * vigra::fixedPoint(v8)), 5);
+        shouldEqual(round(t1 * vigra::fixedPoint(v4) + t2 * vigra::fixedPoint(v8)), 5);
+
+        shouldEqual(vigra::floor(t1 * -vigra::fixedPoint(v1) - t2 * vigra::fixedPoint(v2)), -2);
+        shouldEqual(vigra::ceil(t1 * -vigra::fixedPoint(v1) - t2 * vigra::fixedPoint(v2)), -1);
+        shouldEqual(round(t1 * -vigra::fixedPoint(v1) - t2 * vigra::fixedPoint(v2)), -1);
+        shouldEqual(vigra::floor(t1 * -vigra::fixedPoint(v4) - t2 * vigra::fixedPoint(v8)), -5);
+        shouldEqual(vigra::ceil(t1 * -vigra::fixedPoint(v4) - t2 * vigra::fixedPoint(v8)), -5);
+        shouldEqual(round(t1 * -vigra::fixedPoint(v4) - t2 * vigra::fixedPoint(v8)), -5);
+
+        double d1 = 1.0 / 3.0, d2 = 1.0 / 7.0;
+        vigra::FixedPoint<1, 24> r1(d1), r2(d2);
+        vigra::FixedPoint<2, 24> r3;
+        add(r1, r2, r3);
+        shouldEqual(r3.value, (vigra::FixedPoint<2, 24>(d1 + d2)).value);
+        sub(r1, r2, r3);
+        shouldEqual(r3.value, (vigra::FixedPoint<2, 24>(d1 - d2)).value);
+        mul(r1, r2, r3);
+        shouldEqual(r3.value >> 2, (vigra::FixedPoint<2, 24>(d1 * d2)).value >> 2);
+
+        for(int i = 0; i < 1024; ++i)
+        {
+            vigra::FixedPoint<4,5> fv1(i, vigra::FPNoShift);
+            vigra::FixedPoint<5,4> fv2(i, vigra::FPNoShift);
+            vigra::FixedPoint<5,5> fv3(i, vigra::FPNoShift);
+            vigra::FixedPoint<6,6> fv4(i, vigra::FPNoShift);
+            shouldEqual(vigra::fixed_point_cast<double>(vigra::sqrt(fv1)), vigra::floor(vigra::sqrt((double)fv1.value)) / 8.0);
+            shouldEqual(vigra::fixed_point_cast<double>(vigra::sqrt(fv2)), vigra::floor(vigra::sqrt((double)fv2.value)) / 4.0);
+            shouldEqual(vigra::fixed_point_cast<double>(vigra::sqrt(fv3)), vigra::floor(vigra::sqrt((double)fv3.value)) / 4.0);
+            shouldEqual(vigra::fixed_point_cast<double>(vigra::sqrt(fv4)), vigra::floor(vigra::sqrt((double)fv4.value)) / 8.0);
+        }
+    }
+};
+
+struct FixedPoint16Test
+{
+    void testConstruction()
+    {
+        shouldEqual((vigra::FixedPoint16<3>(3).value), 3 << 12);
+        shouldEqual((vigra::FixedPoint16<3>(-3).value), -3 << 12);
+        shouldEqual((-vigra::FixedPoint16<3>(3).value), -3 << 12);
+
+        shouldEqual((vigra::FixedPoint16<8>(3).value), 3 << 7);
+
+        shouldEqual((vigra::FixedPoint16<3>(3.5).value), 7 << 11);
+        shouldEqual((vigra::FixedPoint16<3>(-3.5).value), -(7 << 11));
+        shouldEqual((-vigra::FixedPoint16<3>(3.5).value), -(7 << 11));
+
+        shouldEqual((vigra::NumericTraits<vigra::FixedPoint16<4> >::zero()).value, 0);
+        shouldEqual((vigra::NumericTraits<vigra::FixedPoint16<4> >::one()).value, 1 << 11);
+        shouldEqual((vigra::NumericTraits<vigra::FixedPoint16<4> >::max()).value, (1 << 15) - 1);
+        shouldEqual((vigra::NumericTraits<vigra::FixedPoint16<4> >::min()).value, -(1 << 15));
+
+        shouldEqual((vigra::FixedPoint16<1, vigra::FPOverflowSaturate>(3.75).value), (1 << 15)-1);
+        shouldEqual((vigra::FixedPoint16<1, vigra::FPOverflowSaturate>(-3.75).value), -(1 << 15));
+        try { vigra::FixedPoint16<1, vigra::FPOverflowError>(3.75); failTest("No exception thrown"); } 
+        catch(vigra::PreconditionViolation &) {}
+        try { vigra::FixedPoint16<1, vigra::FPOverflowError>(-3.75); failTest("No exception thrown"); } 
+        catch(vigra::PreconditionViolation &) {}
+
+        vigra::FixedPoint16<4> v(3.75);
+        shouldEqual((v.value), 15 << 9);
+        shouldEqual(((-v).value), -15 << 9);
+        shouldEqual((vigra::FixedPoint16<4>(v).value), 15 << 9);
+        shouldEqual((vigra::FixedPoint16<6>(v).value), 15 << 7);
+        shouldEqual((vigra::FixedPoint16<13>(v).value), 15);
+        shouldEqual((vigra::FixedPoint16<15>(v).value), 4);
+
+        shouldEqual((vigra::FixedPoint16<4>(-v).value), -15 << 9);
+        shouldEqual((vigra::FixedPoint16<6>(-v).value), -15 << 7);
+        shouldEqual((vigra::FixedPoint16<13>(-v).value), -15);
+        shouldEqual((vigra::FixedPoint16<15>(-v).value), -4);
+
+        shouldEqual(vigra::fixed_point_cast<double>(v), 3.75);
+        shouldEqual(vigra::fixed_point_cast<double>(-v), -3.75);
+        shouldEqual(frac(v), vigra::FixedPoint16<4>(0.75));
+        shouldEqual(dual_frac(v), vigra::FixedPoint16<4>(0.25));
+        shouldEqual(frac(-v), vigra::FixedPoint16<4>(0.25));
+        shouldEqual(dual_frac(-v), vigra::FixedPoint16<4>(0.75));
+        shouldEqual(vigra::floor(v), 3);
+        shouldEqual(vigra::ceil(v), 4);
+        shouldEqual(vigra::floor(-v), -4);
+        shouldEqual(vigra::ceil(-v), -3);
+        shouldEqual(round(v), 4);
+        shouldEqual(round(-v), -4);
+        shouldEqual(vigra::abs(v), v);
+        shouldEqual(vigra::abs(-v), v);
+        shouldEqual(vigra::norm(-v), v);
+        shouldEqual(vigra::squaredNorm(-v), v*v);
+
+        vigra::FixedPoint16<2> v1;
+        shouldEqual((v1 = v).value, 15 << 11);
+        shouldEqual((v1 = -v).value, -15 << 11);
+
+        vigra::FixedPoint16<15> v2;
+        shouldEqual((v2 = v).value, 4);
+        shouldEqual((v2 = -v).value, -4);
+    }
+
+    void testComparison()
+    {
+        vigra::FixedPoint16<4> v1(3.75), v2(4);
+        vigra::FixedPoint16<2> v3(3.75);
+        should(v1 == v1);
+        should(v1 == v3);
+        should(!(v1 != v1));
+        should(!(v1 != v3));
+        should(v1 <= v1);
+        should(v1 <= v3);
+        should(!(v1 < v1));
+        should(!(v1 < v3));
+        should(v1 >= v1);
+        should(v1 >= v3);
+        should(!(v1 > v1));
+        should(!(v1 > v3));
+
+        should(v2 != v1);
+        should(v2 != v3);
+        should(!(v2 == v1));
+        should(!(v2 == v3));
+        should(!(v2 <= v1));
+        should(!(v2 <= v3));
+        should(!(v2 < v1));
+        should(!(v2 < v3));
+        should(v2 >= v1);
+        should(v2 >= v3);
+        should(v2 > v1);
+        should(v2 > v3);
+    }
+
+    void testArithmetic()
+    {
+        typedef vigra::FixedPoint16<1> FP1;
+        typedef vigra::FixedPoint16<2> FP2;
+        typedef vigra::FixedPoint16<7> FP7;
+        typedef vigra::FixedPoint16<8> FP8;
+        typedef vigra::FixedPoint16<13> FP13;
+        typedef vigra::FixedPoint16<15> FP15;
+        
+        FP1 t0(0), t1(0.75), t2(0.25);
+        signed char v1 = 1, v2 = 2, v4 = 4, v8 = 8;
+
+        shouldEqual(FP1(t1) += t1, FP1(1.5));
+        shouldEqual(FP1(t1) -= t1, FP1(0.0));
+        shouldEqual(FP1(t1) -= t2, FP1(0.5));
+        shouldEqual(FP2(t1) *= t1, FP1(9.0 / 16.0));
+        shouldEqual(FP2(t1) /= t2, FP2(3));
+        shouldEqual(FP2(t1) /= t0, vigra::NumericTraits<FP2>::max());
+        shouldEqual(FP2(-t1) /= t0, vigra::NumericTraits<FP2>::min());
+        
+        FP2 res;
+        shouldEqual(add(t1, t1, res), FP2(1.5));
+        shouldEqual(sub(t1, t1, res), FP2(0));
+        shouldEqual(sub(t1, t2, res), FP2(0.5));
+        shouldEqual(mul(t1, t1, res), FP2(9.0 / 16.0));
+        shouldEqual(div(t1, t2, res), FP2(3));
+        shouldEqual(div(t1, t0, res), vigra::NumericTraits<FP2>::max());
+        shouldEqual(div(-t1, t0, res), vigra::NumericTraits<FP2>::min());
+
+        shouldEqual(--t1, FP1(-0.25));
+        shouldEqual(t1, FP1(-0.25));
+        shouldEqual(++t1, FP1(0.75));
+        shouldEqual(t1, FP1(0.75));
+        shouldEqual(t1++, FP1(0.75));
+        shouldEqual(t1, FP1(1.75));
+        shouldEqual(t1--, FP1(1.75));
+        shouldEqual(t1, FP1(0.75));
+
+        shouldEqual((t1 * FP7(v1)).value, 3 << 6);
+        shouldEqual((t2 * FP7(v1)).value, 1 << 6);
+        shouldEqual((-t1 * FP7(v1)).value, -3 << 6);
+        shouldEqual((-t2 * FP7(v1)).value, -1 << 6);
+        shouldEqual((t1 * -FP7(v1)).value, -3 << 6);
+        shouldEqual((t2 * -FP7(v1)).value, -1 << 6);
+
+        shouldEqual((vigra::FixedPoint16<2, vigra::FPOverflowSaturate>(t1*FP7(v8)).value), (1 << 15)-1);
+        shouldEqual((vigra::FixedPoint16<2, vigra::FPOverflowSaturate>(t1*FP7(-v8)).value), -(1 << 15));
+        try { vigra::FixedPoint16<2, vigra::FPOverflowError>(t1*FP7(v8)); failTest("No exception thrown"); } 
+        catch(vigra::PreconditionViolation &) {}
+        try { vigra::FixedPoint16<2, vigra::FPOverflowError>(t1*FP7(-v8)); failTest("No exception thrown"); } 
+        catch(vigra::PreconditionViolation &) {}
+
+        shouldEqual((FP13(t1 * FP7(v1))).value, 3);
+        shouldEqual((FP13(t2 * FP7(v1))).value, 1);
+        shouldEqual((FP13(-t1 * FP7(v1))).value, -3);
+        shouldEqual((FP13(-t2 * FP7(v1))).value, -1);
+
+        shouldEqual((t1 * FP7(v4) + t2 * FP7(v8)).value, 5 << 8);
+        shouldEqual((t1 * FP7(v1) + t2 * FP7(v2)).value, 5 << 6);
+
+        shouldEqual(FP7(6) / FP7(3), FP7(2));
+        shouldEqual(FP7(0.75) / FP7(0.25), FP7(3));
+        shouldEqual(FP7(12) / FP7(48), FP7(0.25));
+        shouldEqual(FP1(0.25) / FP7(2), FP7(0.125));
+        shouldEqual(FP7(10) / FP1(0.25), FP7(40));
+        shouldEqual(FP7(10) / t0, vigra::NumericTraits<FP7>::max());
+        shouldEqual(FP7(-10) / t0, vigra::NumericTraits<FP7>::min());
+
+        shouldEqual(vigra::floor(t1 * FP7(v1) + t2 * FP7(v2)), 1);
+        shouldEqual(vigra::ceil(t1 * FP7(v1) + t2 * FP7(v2)), 2);
+        shouldEqual(round(t1 * FP7(v1) + t2 * FP7(v2)), 1);
+        shouldEqual(vigra::floor(t1 * FP7(v4) + t2 * FP7(v8)), 5);
+        shouldEqual(vigra::ceil(t1 * FP7(v4) + t2 * FP7(v8)), 5);
+        shouldEqual(round(t1 * FP7(v4) + t2 * FP7(v8)), 5);
+
+        shouldEqual(vigra::floor(t1 * -FP7(v1) - t2 * FP7(v2)), -2);
+        shouldEqual(vigra::ceil(t1 * -FP7(v1) - t2 * FP7(v2)), -1);
+        shouldEqual(round(t1 * -FP7(v1) - t2 * FP7(v2)), -1);
+        shouldEqual(vigra::floor(t1 * -FP7(v4) - t2 * FP7(v8)), -5);
+        shouldEqual(vigra::ceil(t1 * -FP7(v4) - t2 * FP7(v8)), -5);
+        shouldEqual(round(t1 * -FP7(v4) - t2 * FP7(v8)), -5);
+
+        double d1 = 1.0 / 3.0, d2 = 1.0 / 7.0;
+        FP1 r1(d1), r2(d2);
+        FP2 r3;
+        add(r1, r2, r3);
+        shouldEqual(r3.value, FP2(d1 + d2).value);
+        sub(r1, r2, r3);
+        shouldEqual(r3.value, FP2(d1 - d2).value);
+        mul(r1, r2, r3);
+        shouldEqual(r3.value >> 2, FP2(d1 * d2).value >> 2);
+
+        shouldEqual(vigra::sqrt(FP7(4)).value, 1 << 12);
+        shouldEqual(vigra::sqrt(FP8(4)).value, 1 << 12);
+        shouldEqual(vigra::hypot(FP8(3), FP8(4)), FP8(5));
+        shouldEqual(vigra::hypot(FP8(-3), FP8(-4)), FP8(5));
+        shouldEqual(vigra::fixed_point_cast<double>(vigra::sqrt(FP7(4))), 2.0);
+        shouldEqual(vigra::fixed_point_cast<double>(vigra::sqrt(FP2(2.25))), 1.5);
+        shouldEqual(vigra::fixed_point_cast<double>(vigra::sqrt(FP8(6.25))), 2.5);
+
+        for(int i = 0; i < 1024; ++i)
+        {
+            vigra::FixedPoint16<11> fv1(i, vigra::FPNoShift);
+            vigra::FixedPoint16<10> fv2(i, vigra::FPNoShift);
+            vigra::FixedPoint16<9>  fv3(i, vigra::FPNoShift);
+            vigra::FixedPoint16<8>  fv4(i, vigra::FPNoShift);
+            shouldEqual(vigra::fixed_point_cast<double>(vigra::sqrt(fv1)), vigra::floor(vigra::sqrt((double)(i << 14))) / 512.0);
+            shouldEqual(vigra::fixed_point_cast<double>(vigra::sqrt(fv2)), vigra::floor(vigra::sqrt((double)(i << 15))) / 1024.0);
+            shouldEqual(vigra::fixed_point_cast<double>(vigra::sqrt(fv3)), vigra::floor(vigra::sqrt((double)(i << 14))) / 1024.0);
+            shouldEqual(vigra::fixed_point_cast<double>(vigra::sqrt(fv4)), vigra::floor(vigra::sqrt((double)(i << 15))) / 2048.0);
+        }
+
+        shouldEqual(vigra::atan2(FP1(0), FP1(1)), FP2(0));
+        shouldEqual(vigra::atan2(FP1(0), FP1(-1)), FP2(M_PI));
+        shouldEqual(vigra::atan2(FP1(1), FP1(0)), FP2(0.5*M_PI));
+        shouldEqual(vigra::atan2(FP1(-1), FP1(0)), FP2(-0.5*M_PI));
+        
+        for(int i = -179; i < 180; ++i)
+        {
+            double angle = M_PI*i/180.0;
+            double c = std::cos(angle), s = std::sin(angle);
+            FP2 a = vigra::atan2(FP1(s), FP1(c));
+            should(vigra::abs(i-vigra::fixed_point_cast<double>(a)/M_PI*180.0) < 0.3);
+            a = vigra::atan2(FP15(30000.0*s), FP15(30000.0*c));
+            should(vigra::abs(i-vigra::fixed_point_cast<double>(a)/M_PI*180.0) < 0.3);
+        }
+    }
+};
+
+struct LinalgTest
+{
+    typedef vigra::Matrix<double> Matrix;
+    typedef Matrix::difference_type Shape;
+
+    unsigned int size, iterations;
+    vigra::RandomMT19937 random_;
+
+    LinalgTest()
+    : size(50),
+      iterations(5),
+      random_(23098349)
+    {}
+
+    void testOStreamShifting()
+    {
+        Matrix a = random_matrix (size, size);
+        std::ostringstream out;
+        out << a;
+        out << "Testing.." << a << 42 << std::endl;
+    }
+
+    double random_double ()
+    {
+        double ret = 2.0 * random_.uniform53() - 1.0;
+        return ret;
+    }
+
+    Matrix random_matrix(unsigned int rows, unsigned int cols)
+    {
+        Matrix ret (rows, cols);
+        for (unsigned int i = 0; i < rows; ++i)
+            for (unsigned int j = 0; j < cols; ++j)
+                ret (i, j) = random_double ();
+        return ret;
+    }
+
+    Matrix random_symmetric_matrix(unsigned int rows)
+    {
+        Matrix ret (rows, rows);
+        for (unsigned int i = 0; i < rows; ++i)
+            for (unsigned int j = i; j < rows; ++j)
+                ret (j, i) = ret (i, j) = random_double ();
+        return ret;
+    }
+
+    void testMatrix()
+    {
+        double data[] = {1.0, 5.0,
+                         3.0, 2.0,
+                         4.0, 7.0};
+        double tref[] = {1.0, 3.0, 4.0,
+                         5.0, 2.0, 7.0};
+        double tref2[] = {1.0, 3.0,
+                          5.0, 2.0};
+        double idref[] = {1.0, 0.0, 0.0,
+                          0.0, 1.0, 0.0,
+                          0.0, 0.0, 1.0};
+        std::string sref("1.0000 5.0000 \n3.0000 2.0000 \n4.0000 7.0000 \n");
+        unsigned int r = 3, c = 2;
+
+        Matrix a(r, c, data), zero(r, c);
+        shouldEqual(a.rowCount(), r);
+        shouldEqual(a.columnCount(), c);
+        shouldEqual(a.elementCount(), r*c);
+        shouldEqual(a.squaredNorm(), 104.0);
+        shouldEqual(a.norm(), std::sqrt(104.0));
+        shouldEqual(a.squaredNorm(), squaredNorm(a));
+        shouldEqual(a.norm(), vigra::norm(a));
+        shouldEqual(rowCount(a), r);
+        shouldEqual(columnCount(a), c);
+
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(zero(i,j), 0.0);
+
+        Matrix one = zero + Matrix(r,c).init(1.0);
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(one(i,j), 1.0);
+
+        std::stringstream s;
+        s << std::setprecision(4) << a;
+        shouldEqual(s.str(), sref);
+
+        for(unsigned int i=0, k=0; i<r; ++i)
+        {
+            Matrix::view_type ar = a.rowVector(i);
+            shouldEqual(rowCount(ar), 1);
+            shouldEqual(columnCount(ar), c);
+            Matrix::view_type ar1 = rowVector(a, i);
+            shouldEqual(rowCount(ar1), 1);
+            shouldEqual(columnCount(ar1), c);
+            for(unsigned int j=0; j<c; ++j, ++k)
+            {
+                shouldEqual(a(i,j), data[k]);
+                shouldEqual(ar(0, j), data[k]);
+                shouldEqual(ar1(0, j), data[k]);
+            }
+        }
+
+        Matrix aa(r, c, tref, vigra::ColumnMajor);
+        shouldEqual(aa.rowCount(), r);
+        shouldEqual(aa.columnCount(), c);
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(aa(i,j), a(i,j));
+
+        Matrix b = a;
+        shouldEqual(b.rowCount(), r);
+        shouldEqual(b.columnCount(), c);
+        shouldEqualSequence(a.begin(), a.end(), b.begin());
+
+        b.init(0.0);
+        should(b == zero);
+
+        Matrix::iterator ib = b.begin();
+        b = a;
+        shouldEqual(ib, b.begin());
+        shouldEqualSequence(a.begin(), a.end(), b.begin());
+
+        b = 4.0 + a;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), 4.0+data[k]);
+        b = a + 3.0;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), data[k]+3.0);
+        b += 4.0;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), 7.0+data[k]);
+        b += a;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), 7.0+2.0*data[k]);
+
+
+        b = 4.0 - a;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), 4.0-data[k]);
+        b = a - 3.0;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), data[k]-3.0);
+        b -= 4.0;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), data[k]-7.0);
+        b -= a;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), -7.0);
+
+        b = 4.0 * a;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), 4.0*data[k]);
+        b = a * 3.0;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), data[k]*3.0);
+        b *= 4.0;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), data[k]*12.0);
+        b *= a;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), data[k]*data[k]*12.0);
+
+        b = 4.0 / a;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), 4.0/data[k]);
+        b = a / 3.0;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), data[k] / 3.0);
+        b /= 4.0;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), data[k] / 12.0);
+        b /= a;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqualTolerance(b(i,j), 1.0 / 12.0, 1e-12);
+
+        b = a + a;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), 2.0 * data[k]);
+
+        b = a - a;
+        for(unsigned int i=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j)
+                shouldEqual(b(i,j), 0.0);
+
+        b = -a;
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), -data[k]);
+
+        b = a * pointWise(a);
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), data[k] * data[k]);
+
+        b = a / pointWise(a);
+        for(unsigned int i=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j)
+                shouldEqual(b(i,j), 1.0);
+
+        b = pow(a, 2);
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), data[k] * data[k]);
+
+        b = sqrt(a);
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), sqrt(data[k]));
+
+        b = sq(a);
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), vigra::sq(data[k]));
+
+        b = sign(a);
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(b(i,j), vigra::sign(data[k]));
+
+        Matrix at = transpose(a);
+        shouldEqual(at.rowCount(), c);
+        shouldEqual(at.columnCount(), r);
+        for(unsigned int i=0, k=0; i<c; ++i)
+        {
+            Matrix::view_type ac = a.columnVector(i);
+            shouldEqual(rowCount(ac), r);
+            shouldEqual(columnCount(ac), 1);
+            Matrix::view_type ac1 = columnVector(a, i);
+            shouldEqual(rowCount(ac1), r);
+            shouldEqual(columnCount(ac1), 1);
+            for(unsigned int j=0; j<r; ++j, ++k)
+            {
+                shouldEqual(at(i,j), tref[k]);
+                shouldEqual(ac(j,0), tref[k]);
+                shouldEqual(ac1(j,0), tref[k]);
+            }
+            shouldEqual(ac, subVector(ac, 0, r));
+            shouldEqual(a.subarray(Shape(1, i), Shape(r-1, i+1)), subVector(ac, 1, r-1));
+        }
+
+        double sn = squaredNorm(columnVector(a, 0));
+        shouldEqual(sn, 26.0);
+        shouldEqual(sn, dot(columnVector(a, 0), columnVector(a, 0)));
+        shouldEqual(sn, dot(rowVector(at, 0), columnVector(a, 0)));
+        shouldEqual(sn, dot(columnVector(a, 0), rowVector(at, 0)));
+        shouldEqual(sn, dot(rowVector(at, 0), rowVector(at, 0)));
+        shouldEqual(0.0, dot(a.subarray(Shape(0,0), Shape(1,0)), a.subarray(Shape(0,0), Shape(0,1))));
+        shouldEqual(0.0, dot(a.subarray(Shape(0,0), Shape(0,1)), a.subarray(Shape(0,0), Shape(0,1))));
+        shouldEqual(0.0, dot(a.subarray(Shape(0,0), Shape(1,0)), a.subarray(Shape(0,0), Shape(1,0))));
+        shouldEqual(0.0, dot(a.subarray(Shape(0,0), Shape(0,1)), a.subarray(Shape(0,0), Shape(1,0))));
+
+        Matrix a2(c, c, data);
+        a2 = a2.transpose();
+        for(unsigned int i=0, k=0; i<c; ++i)
+            for(unsigned int j=0; j<c; ++j, ++k)
+                shouldEqual(a2(i,j), tref2[k]);
+        
+        shouldEqual(trace(a2), 3.0);
+
+        Matrix id = vigra::identityMatrix<double>(r);
+        shouldEqual(id.rowCount(), r);
+        shouldEqual(id.columnCount(), r);
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<r; ++j, ++k)
+                shouldEqual(id(i,j), idref[k]);
+
+        shouldEqual(trace(id), 3.0);
+
+        Matrix d = diagonalMatrix(Matrix(r, 1, data));
+        shouldEqual(d.rowCount(), r);
+        shouldEqual(d.columnCount(), r);
+        for(unsigned int i=0, k=0; i<r; ++i)
+            for(unsigned int j=0; j<r; ++j, ++k)
+                shouldEqual(d(i,j), idref[k]*data[i]);
+
+        Matrix e(r*c, 1, data);
+        shouldEqual(dot(transpose(e), e), e.squaredNorm());
+
+        double dc1[] = {1.0, 1.0, 1.0},
+               dc2[] = {1.2, 2.4, 3.6};
+        Matrix c1(3,1, dc1), c2(3,1, dc2);
+        Matrix cr = cross(c1, c2);
+        shouldEqualTolerance(cr(0,0), 1.2, 1e-12);
+        shouldEqualTolerance(cr(1,0), -2.4, 1e-12);
+        shouldEqualTolerance(cr(2,0), 1.2, 1e-12);
+
+        Matrix f(1, r*c - 1, tref);
+        Matrix g = outer(e, f);
+        shouldEqual(g.rowCount(), e.rowCount());
+        shouldEqual(g.columnCount(), f.columnCount());
+        for(int i=0; i<g.rowCount(); ++i)
+            for(int j=0; j<g.columnCount(); ++j)
+                shouldEqual(g(i,j), data[i]*tref[j]);
+
+        Matrix g1 = outer(e);
+        shouldEqual(g1.rowCount(), e.rowCount());
+        shouldEqual(g1.columnCount(), e.rowCount());
+        for(int i=0; i<g1.rowCount(); ++i)
+            for(int j=0; j<g1.columnCount(); ++j)
+                shouldEqual(g1(i,j), data[i]*data[j]);
+
+        Matrix g2 = outer(vigra::TinyVector<double, 6>(data));
+        shouldEqual(g2.rowCount(), 6);
+        shouldEqual(g2.columnCount(), 6);
+        for(int i=0; i<g2.rowCount(); ++i)
+            for(int j=0; j<g2.columnCount(); ++j)
+                shouldEqual(g2(i,j), data[i]*data[j]);
+
+        Matrix h = transpose(a) * a;
+        shouldEqual(h.rowCount(), c);
+        shouldEqual(h.columnCount(), c);
+        for(int i=0; i<(int)c; ++i)
+            for(int j=0; j<(int)c; ++j)
+                shouldEqual(h(i,j), dot(rowVector(at, i), columnVector(a, j)));
+
+        should(isSymmetric(random_symmetric_matrix(10)));
+        should(!isSymmetric(random_matrix(10, 10)));
+
+        Matrix tm(2, 2, tref2);
+        vigra::TinyVector<double, 2> tv(1.0, 2.0), tvrref(7.0, 9.0), tvlref(11.0, 7.0);
+        shouldEqual(tm * tv, tvrref);
+        shouldEqual(tv * tm, tvlref);
+
+        Matrix rep = repeatMatrix(a, 2, 4);
+        shouldEqual(rowCount(rep), 2*r);
+        shouldEqual(columnCount(rep), 4*c);
+
+        for(unsigned int l=0; l<4; ++l)
+            for(unsigned int k=0; k<2; ++k)
+                for(unsigned int j=0; j<c; ++j)
+                    for(unsigned int i=0; i<r; ++i)
+                        shouldEqual(rep(k*r+i, l*c+j), a(i,j));
+
+        double columnSum[] = {8.0, 14.0};
+        double rowSum[] = {6.0, 5.0, 11.0};
+        Matrix matColumnSum = Matrix(1, 2, columnSum);
+        Matrix matRowSum = Matrix(3, 1, rowSum);
+        shouldEqualSequence(matColumnSum.data(), matColumnSum.data()+2, a.sum(0).data());
+        shouldEqualSequence(matRowSum.data(), matRowSum.data()+3, a.sum(1).data());
+
+        double columnMean[] = {8/3.0, 14/3.0};
+        double rowMean[] = {3.0, 2.5, 5.5};
+        Matrix matColumnMean = Matrix(1, 2, columnMean);
+        Matrix matRowMean = Matrix(3, 1, rowMean);
+        shouldEqualSequence(matColumnMean.data(), matColumnMean.data()+2, a.mean(0).data());
+        shouldEqualSequence(matRowMean.data(), matRowMean.data()+3, a.mean(1).data());  
+    }
+
+    void testArgMinMax()
+    {
+        using namespace vigra::functor;
+
+        double data[] = {1.0, 5.0,
+                         3.0, 2.0,
+                        -2.0, 4.0};
+        unsigned int r = 3, c = 2;
+        Matrix minmax(r, c, data);
+
+        shouldEqual(argMin(minmax), 2);
+        shouldEqual(argMax(minmax), 3);
+        shouldEqual(argMinIf(minmax, Arg1() > Param(0.0)), 0);
+        shouldEqual(argMinIf(minmax, Arg1() > Param(5.0)), -1);
+        shouldEqual(argMaxIf(minmax, Arg1() < Param(5.0)), 5);
+        shouldEqual(argMaxIf(minmax, Arg1() < Param(-2.0)), -1);
+    }
+
+    void testColumnAndRowStatistics()
+    {
+        double epsilon = 1e-11;
+
+        Matrix rowMean(size, 1), columnMean(1, size);
+        Matrix rowStdDev(size, 1), columnStdDev(1, size);
+        Matrix rowNorm(size, 1), columnNorm(1, size);
+        Matrix rowCovariance(size, size), columnCovariance(size, size);
+
+        for(unsigned int i = 0; i < iterations; ++i)
+        {
+            Matrix a = random_matrix (size, size);
+
+            rowStatistics(a, rowMean, rowStdDev, rowNorm);
+            columnStatistics(a, columnMean, columnStdDev, columnNorm);
+
+            for(unsigned int k=0; k<size; ++k)
+            {
+                double rm = 0.0, cm = 0.0, rn = 0.0, cn = 0.0, rs = 0.0, cs = 0.0;
+                for(unsigned int l=0; l<size; ++l)
+                {
+                    rm += a(k, l);
+                    cm += a(l, k);
+                    rn += vigra::sq(a(k, l));
+                    cn += vigra::sq(a(l, k));
+                }
+                rm /= size;
+                cm /= size;
+                rn = std::sqrt(rn);
+                cn = std::sqrt(cn);
+
+                shouldEqualTolerance(rm, rowMean(k,0), epsilon);
+                shouldEqualTolerance(cm, columnMean(0,k), epsilon);
+                shouldEqualTolerance(rn, rowNorm(k,0), epsilon);
+                shouldEqualTolerance(cn, columnNorm(0,k), epsilon);
+
+                for(unsigned int l=0; l<size; ++l)
+                {
+                    rs += vigra::sq(a(k, l) - rm);
+                    cs += vigra::sq(a(l, k) - cm);
+                }
+                rs = std::sqrt(rs / (size-1));
+                cs = std::sqrt(cs / (size-1));
+
+                shouldEqualTolerance(rs, rowStdDev(k,0), epsilon);
+                shouldEqualTolerance(cs, columnStdDev(0,k), epsilon);
+            }
+
+            covarianceMatrixOfRows(a, rowCovariance);
+            covarianceMatrixOfColumns(a, columnCovariance);
+            Matrix rowCovarianceRef(size, size), columnCovarianceRef(size, size);
+            for(unsigned int k=0; k<size; ++k)
+            {
+                for(unsigned int l=0; l<size; ++l)
+                {
+                    for(unsigned int m=0; m<size; ++m)
+                    {
+                        rowCovarianceRef(l, m) += (a(l, k) - rowMean(l, 0)) * (a(m, k) - rowMean(m, 0));
+                        columnCovarianceRef(l, m) += (a(k, l) - columnMean(0, l)) * (a(k, m) - columnMean(0, m));
+                    }
+                }
+            }
+            rowCovarianceRef /= (size-1);
+            columnCovarianceRef /= (size-1);
+
+            shouldEqualSequenceTolerance(rowCovariance.data(), rowCovariance.data()+size*size, rowCovarianceRef.data(), epsilon);
+            shouldEqualSequenceTolerance(columnCovariance.data(), columnCovariance.data()+size*size, columnCovarianceRef.data(), epsilon);
+        }
+    }
+
+    void testColumnAndRowPreparation()
+    {
+        using vigra::ZeroMean;
+        using vigra::UnitVariance;
+        using vigra::UnitNorm;
+        using vigra::UnitSum;
+
+        double epsilon = 1e-11;
+
+        Matrix rowMean(size, 1), columnMean(1, size);
+        Matrix rowStdDev(size, 1), columnStdDev(1, size);
+        Matrix rowNorm(size, 1), columnNorm(1, size);
+
+        Matrix rowPrepared(size, size), columnPrepared(size, size);
+        Matrix rowMeanPrepared(size, 1), columnMeanPrepared(1, size);
+        Matrix rowStdDevPrepared(size, 1), columnStdDevPrepared(1, size);
+        Matrix rowNormPrepared(size, 1), columnNormPrepared(1, size);
+        Matrix rowOffset(size, 1), columnOffset(1, size);
+        Matrix rowScaling(size, 1), columnScaling(1, size);
+
+        Matrix zeroRowRef(size,1), zeroColRef(1, size);
+        Matrix oneRowRef(size,1), oneColRef(1, size);
+        oneRowRef.init(1.0);
+        oneColRef.init(1.0);
+
+        {
+            Matrix a = random_matrix (size, size);
+
+            columnStatistics(a, columnMean, columnStdDev, columnNorm);
+
+            prepareColumns(a, columnPrepared, columnOffset, columnScaling, UnitSum);
+            shouldEqualSequence(zeroColRef.data(), zeroColRef.data()+size, columnOffset.data());
+            columnScaling *= columnMean;
+            columnScaling *= size;
+            shouldEqualSequenceTolerance(oneColRef.data(), oneColRef.data()+size, columnScaling.data(), epsilon);
+            columnStatistics(columnPrepared, columnMeanPrepared, columnStdDevPrepared, columnNormPrepared);
+            columnMeanPrepared *= size;
+            shouldEqualSequenceTolerance(oneColRef.data(), oneColRef.data()+size, columnMeanPrepared.data(), epsilon);
+
+            prepareColumns(a, columnPrepared, columnOffset, columnScaling, ZeroMean);
+            columnStatistics(columnPrepared, columnMeanPrepared, columnStdDevPrepared, columnNormPrepared);
+            shouldEqualSequenceTolerance(zeroColRef.data(), zeroColRef.data()+size, columnMeanPrepared.data(), epsilon);
+            shouldEqualSequenceTolerance(columnStdDev.data(), columnStdDev.data()+size, columnStdDevPrepared.data(), epsilon);
+
+            Matrix ap = columnPrepared / pointWise(repeatMatrix(columnScaling, size, 1)) + repeatMatrix(columnOffset, size, 1);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+
+            prepareColumns(a, columnPrepared, columnOffset, columnScaling, UnitNorm);
+            columnStatistics(columnPrepared, columnMeanPrepared, columnStdDevPrepared, columnNormPrepared);
+            shouldEqualSequenceTolerance(oneColRef.data(), oneColRef.data()+size, columnNormPrepared.data(), epsilon);
+
+            ap = columnPrepared / pointWise(repeatMatrix(columnScaling, size, 1)) + repeatMatrix(columnOffset, size, 1);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+
+            prepareColumns(a, columnPrepared, columnOffset, columnScaling, UnitVariance);
+            columnStatistics(columnPrepared, columnMeanPrepared, columnStdDevPrepared, columnNormPrepared);
+            columnMeanPrepared /= columnScaling;
+            shouldEqualSequenceTolerance(columnMean.data(), columnMean.data()+size, columnMeanPrepared.data(), epsilon);
+            shouldEqualSequenceTolerance(oneColRef.data(), oneColRef.data()+size, columnStdDevPrepared.data(), epsilon);
+
+            ap = columnPrepared / pointWise(repeatMatrix(columnScaling, size, 1)) + repeatMatrix(columnOffset, size, 1);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+
+            prepareColumns(a, columnPrepared, columnOffset, columnScaling, ZeroMean | UnitVariance);
+            columnStatistics(columnPrepared, columnMeanPrepared, columnStdDevPrepared, columnNormPrepared);
+            shouldEqualSequenceTolerance(zeroColRef.data(), zeroColRef.data()+size, columnMeanPrepared.data(), epsilon);
+            shouldEqualSequenceTolerance(oneColRef.data(), oneColRef.data()+size, columnStdDevPrepared.data(), epsilon);
+
+            ap = columnPrepared / pointWise(repeatMatrix(columnScaling, size, 1)) + repeatMatrix(columnOffset, size, 1);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+
+            prepareColumns(a, columnPrepared, columnOffset, columnScaling, ZeroMean | UnitNorm);
+            columnStatistics(columnPrepared, columnMeanPrepared, columnStdDevPrepared, columnNormPrepared);
+            shouldEqualSequenceTolerance(zeroColRef.data(), zeroColRef.data()+size, columnMeanPrepared.data(), epsilon);
+            shouldEqualSequenceTolerance(oneColRef.data(), oneColRef.data()+size, columnNormPrepared.data(), epsilon);
+
+            ap = columnPrepared / pointWise(repeatMatrix(columnScaling, size, 1)) + repeatMatrix(columnOffset, size, 1);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+
+            rowStatistics(a, rowMean, rowStdDev, rowNorm);
+
+            prepareRows(a, rowPrepared, rowOffset, rowScaling, UnitSum);
+            shouldEqualSequence(zeroRowRef.data(), zeroRowRef.data()+size, rowOffset.data());
+            rowScaling *= rowMean;
+            rowScaling *= size;
+            shouldEqualSequenceTolerance(oneRowRef.data(), oneRowRef.data()+size, rowScaling.data(), epsilon);
+            rowStatistics(rowPrepared, rowMeanPrepared, rowStdDevPrepared, rowNormPrepared);
+            rowMeanPrepared *= size;
+            shouldEqualSequenceTolerance(oneRowRef.data(), oneRowRef.data()+size, rowMeanPrepared.data(), epsilon);
+
+            prepareRows(a, rowPrepared, rowOffset, rowScaling, ZeroMean);
+            rowStatistics(rowPrepared, rowMeanPrepared, rowStdDevPrepared, rowNormPrepared);
+            shouldEqualSequenceTolerance(zeroRowRef.data(), zeroRowRef.data()+size, rowMeanPrepared.data(), epsilon);
+            shouldEqualSequenceTolerance(rowStdDev.data(), rowStdDev.data()+size, rowStdDevPrepared.data(), epsilon);
+
+            ap = rowPrepared / pointWise(repeatMatrix(rowScaling, 1, size)) + repeatMatrix(rowOffset, 1, size);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+
+            prepareRows(a, rowPrepared, rowOffset, rowScaling, UnitNorm);
+            rowStatistics(rowPrepared, rowMeanPrepared, rowStdDevPrepared, rowNormPrepared);
+            shouldEqualSequenceTolerance(oneRowRef.data(), oneRowRef.data()+size, rowNormPrepared.data(), epsilon);
+
+            ap = rowPrepared / pointWise(repeatMatrix(rowScaling, 1, size)) + repeatMatrix(rowOffset, 1, size);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+
+            prepareRows(a, rowPrepared, rowOffset, rowScaling, UnitVariance);
+            rowStatistics(rowPrepared, rowMeanPrepared, rowStdDevPrepared, rowNormPrepared);
+            rowMeanPrepared /= rowScaling;
+            shouldEqualSequenceTolerance(rowMean.data(), rowMean.data()+size, rowMeanPrepared.data(), epsilon);
+            shouldEqualSequenceTolerance(oneRowRef.data(), oneRowRef.data()+size, rowStdDevPrepared.data(), epsilon);
+
+            ap = rowPrepared / pointWise(repeatMatrix(rowScaling, 1, size)) + repeatMatrix(rowOffset, 1, size);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+
+            prepareRows(a, rowPrepared, rowOffset, rowScaling, ZeroMean | UnitVariance);
+            rowStatistics(rowPrepared, rowMeanPrepared, rowStdDevPrepared, rowNormPrepared);
+            shouldEqualSequenceTolerance(zeroRowRef.data(), zeroRowRef.data()+size, rowMeanPrepared.data(), epsilon);
+            shouldEqualSequenceTolerance(oneRowRef.data(), oneRowRef.data()+size, rowStdDevPrepared.data(), epsilon);
+
+            ap = rowPrepared / pointWise(repeatMatrix(rowScaling, 1, size)) + repeatMatrix(rowOffset, 1, size);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+
+            prepareRows(a, rowPrepared, rowOffset, rowScaling, ZeroMean | UnitNorm);
+            rowStatistics(rowPrepared, rowMeanPrepared, rowStdDevPrepared, rowNormPrepared);
+            shouldEqualSequenceTolerance(zeroRowRef.data(), zeroRowRef.data()+size, rowMeanPrepared.data(), epsilon);
+            shouldEqualSequenceTolerance(oneRowRef.data(), oneRowRef.data()+size, rowNormPrepared.data(), epsilon);
+
+            ap = rowPrepared / pointWise(repeatMatrix(rowScaling, 1, size)) + repeatMatrix(rowOffset, 1, size);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+        }
+
+        {
+            Matrix a(size, size, 2.0), aref(size, size, 1.0/std::sqrt((double)size));
+
+            prepareColumns(a, columnPrepared, columnOffset, columnScaling, ZeroMean | UnitVariance);
+            shouldEqualSequence(a.data(), a.data()+size*size, columnPrepared.data());
+
+            prepareColumns(a, columnPrepared, columnOffset, columnScaling, ZeroMean | UnitNorm);
+            shouldEqualSequenceTolerance(aref.data(), aref.data()+size*size, columnPrepared.data(), epsilon);
+            Matrix ap = columnPrepared / pointWise(repeatMatrix(columnScaling, size, 1)) + repeatMatrix(columnOffset, size, 1);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+
+            prepareRows(a, rowPrepared, rowOffset, rowScaling, ZeroMean | UnitVariance);
+            shouldEqualSequence(a.data(), a.data()+size*size, rowPrepared.data());
+
+            prepareRows(a, rowPrepared, rowOffset, rowScaling, ZeroMean | UnitNorm);
+            shouldEqualSequenceTolerance(aref.data(), aref.data()+size*size, rowPrepared.data(), epsilon);
+            ap = rowPrepared / pointWise(repeatMatrix(rowScaling, 1, size)) + repeatMatrix(rowOffset, 1, size);
+            shouldEqualSequenceTolerance(a.data(), a.data()+size*size, ap.data(), epsilon);
+        }
+    }
+
+    void testCholesky()
+    {
+        double epsilon = 1e-11;
+        Matrix idref = vigra::identityMatrix<double>(size);
+
+        for(unsigned int i = 0; i < iterations; ++i)
+        {
+            Matrix a = random_matrix (size, size);
+            a = transpose(a) * a; // make a symmetric positive definite matrix
+            Matrix l(size, size);
+            choleskyDecomposition (a, l);
+            Matrix ch = l * transpose(l);
+            shouldEqualSequenceTolerance(ch.data(), ch.data()+size*size, a.data(), epsilon);
+        }
+    }
+
+    void testQR()
+    {
+        double epsilon = 1e-11;
+        Matrix idref = vigra::identityMatrix<double>(size);
+
+        for(unsigned int i = 0; i < iterations; ++i)
+        {
+            Matrix a = random_matrix (size, size);
+            Matrix r(size, size);
+            Matrix q(size, size);
+            qrDecomposition (a, q, r);
+            Matrix id = transpose(q) * q;
+            shouldEqualSequenceTolerance(id.data(), id.data()+size*size, idref.data(), epsilon);
+            Matrix qr = q * r;
+            shouldEqualSequenceTolerance(qr.data(), qr.data()+size*size, a.data(), epsilon);
+        }
+    }
+
+    void testLinearSolve()
+    {
+        double epsilon = 1e-11;
+        int size = 50;
+
+        for(unsigned int i = 0; i < iterations; ++i)
+        {
+            Matrix a = random_matrix (size, size);
+            Matrix b = random_matrix (size, 1);
+            Matrix x(size, 1);
+
+            should(linearSolve (a, b, x, "QR"));
+            Matrix ax = a * x;
+            shouldEqualSequenceTolerance(ax.data(), ax.data()+size, b.data(), epsilon);
+
+            should(linearSolve(a, b, x, "SVD"));
+            ax = a * x;
+            shouldEqualSequenceTolerance(ax.data(), ax.data()+size, b.data(), epsilon);
+
+            should(linearSolve(a, b, x, "NE"));
+            ax = a * x;
+            shouldEqualSequenceTolerance(ax.data(), ax.data()+size, b.data(), epsilon);
+
+            Matrix c = transpose(a) * a; // make a symmetric positive definite matrix
+            Matrix d = transpose(a) * b; 
+            should(linearSolve (c, d, x, "Cholesky"));
+            ax = c * x;
+            shouldEqualSequenceTolerance(ax.data(), ax.data()+size, d.data(), epsilon);
+        }
+
+        size = 4;
+        Matrix a = random_matrix (size, size);
+        Matrix b = random_matrix (size, 1);
+        Matrix x(size, 1);
+
+        vigra::TinyVector<double, 4> vb(b.data()), vx;
+        should(linearSolve (a, b, x));
+        should(linearSolve (a, vb, vx));
+        shouldEqualSequenceTolerance(x.data(), x.data()+size, vx.data(), epsilon);
+    }
+
+    void testUnderdetermined()
+    {
+        // test singular matrix
+        Matrix a = vigra::identityMatrix<Matrix::value_type> (size);
+        a(0,0) = 0;
+        Matrix b = random_matrix (size, 1);
+        Matrix x(size, 1);
+        should(!linearSolve (a, b, x, "Cholesky"));
+        should(!linearSolve (a, b, x, "QR"));
+        should(!linearSolve (a, b, x, "SVD"));
+
+        {
+            // square, rank-deficient system (compute minimum norm solution)
+            double mdata[] = {1.0,  3.0,  7.0,
+                             -1.0,  4.0,  4.0,
+                              1.0, 10.0, 18.0};
+            double rhsdata[] = { 5.0, 2.0, 12.0};
+            double refdata[] = { 0.3850, -0.1103, 0.7066 };
+
+            Matrix m(3,3,mdata), rhs(3,1,rhsdata), xx(3,1);
+
+            shouldEqual(linearSolveQR(m, rhs, xx), 2u);
+            shouldEqualSequenceTolerance(refdata, refdata+3, xx.data(), 1e-3);
+        }
+        {
+            // underdetermined, full-rank system (compute minimum norm solution)
+            double mdata[] = {2.0, -3.0, 1.0, -6.0,
+                              4.0,  1.0, 2.0,  9.0,
+                              3.0,  1.0, 1.0,  8.0};
+            double rhsdata[] = { -7.0, -7.0, -8.0};
+            double refdata[] = { -3.26666666666667, 3.6, 5.13333333333333, -0.86666666666667 };
+
+            Matrix m(3,4,mdata), rhs(3,1,rhsdata), xx(4,1);
+
+            shouldEqual(linearSolveQR(m, rhs, xx), 3u);
+            shouldEqualSequenceTolerance(refdata, refdata+4, xx.data(), 1e-12);
+        }
+        {
+            // underdetermined, rank-deficient, consistent system (compute minimum norm solution)
+            double mdata[] = {1.0,  3.0, 3.0, 2.0,
+                              2.0,  6.0, 9.0, 5.0,
+                             -1.0, -3.0, 3.0, 0.0};
+            double rhsdata[] = { 1.0, 5.0, 5.0};
+            double refdata[] = { -0.211009, -0.633027, 0.963303, 0.110092 };
+
+            Matrix m(3,4,mdata), rhs(3,1,rhsdata), xx(4,1);
+
+            shouldEqual(linearSolveQR(m, rhs, xx), 2u);
+            shouldEqualSequenceTolerance(refdata, refdata+4, xx.data(), 1e-5);
+        }
+        {
+            // underdetermined, rank-deficient, inconsistent system (compute minimum norm least squares solution)
+            double mdata[] = {2.0, 1.0,  7.0, -7.0,
+                             -3.0, 4.0, -5.0, -6.0,
+                              1.0, 1.0,  4.0, -5.0};
+            double rhsdata[] = { 2.0, 3.0, 2.0};
+            double refdata[] = { -0.0627, 0.1561, -0.0321, -0.3427 };
+
+            Matrix m(3,4,mdata), rhs(3,1,rhsdata), xx(4,1);
+
+            shouldEqual(linearSolveQR(m, rhs, xx), 2u);
+            shouldEqualSequenceTolerance(refdata, refdata+4, xx.data(), 1e-3);
+        }
+    }
+
+    void testOverdetermined()
+    {
+        double epsilon = 1e-11;
+
+        unsigned int n = 5;
+        unsigned int size = 1000;
+        double noiseStdDev = 0.1;
+
+        Matrix A(size, n), xs(n,1), xq(n,1), xn(n,1), r(size, 1);
+
+        for(unsigned int iter=0; iter<iterations; ++iter)
+        {
+            // set up a linear regression problem for a polynomial of degree n
+            Matrix weights = random_matrix (n, 1);
+            Matrix v = random_matrix (size, 1);
+
+            // init rhs with Gaussian noise with zero mean and noiseStdDev
+            Matrix rhs = 0.5*noiseStdDev*random_matrix (size, 1);
+            for(unsigned int k=1; k<12; ++k)
+                rhs += 0.5*noiseStdDev*random_matrix (size, 1);
+
+            for(unsigned int k=0; k<size; ++k)
+            {
+                for(unsigned int l=0; l<n; ++l)
+                {
+                    A(k,l) = std::pow(v(k,0), double(l));
+                    rhs(k,0) += weights(l,0)*A(k,l);
+                }
+            }
+
+            shouldEqual(linearSolve(A, rhs, xs, "SVD"), true);
+
+            // check that solution is indeed a minimum by
+            // testing for zero derivative of the objective
+            Matrix derivative = abs(transpose(A)*(A*xs - rhs));
+            int absIndex = argMax(derivative);
+            shouldEqualTolerance(derivative(absIndex,0), 0.0, epsilon);
+
+            shouldEqual(linearSolveQR(A, rhs, xq), n);
+            shouldEqualSequenceTolerance(xs.data(), xs.data()+n, xq.data(), epsilon);
+
+            shouldEqual(linearSolve(A, rhs, xn, "ne"), true);
+            shouldEqualSequenceTolerance(xs.data(), xs.data()+n, xn.data(), epsilon);
+        }
+    }
+
+    void testIncrementalLinearSolve()
+    {
+        double epsilon = 1e-11;
+        int size = 50;
+
+        for(unsigned int i = 0; i < iterations; ++i)
+        {
+            Matrix a = random_matrix (size, size);
+            Matrix b = random_matrix (size, 1);
+            Matrix x(size, 1);
+
+            should(linearSolve(a, b, x, "QR"));
+
+            {
+                Matrix r(a), qtb(b), px(size,1), xx(size,1);
+                vigra::ArrayVector<unsigned int> permutation(size);
+
+                for(int k=0; k<size; ++k)
+                {
+                    // use Givens steps for a change (Householder steps like
+                    //    should(vigra::linalg::detail::qrColumnHouseholderStep(k, r, qtb));
+                    // work as well, but are already extensively tested within the QR algorithm)
+                    should(vigra::linalg::detail::qrGivensStepImpl(k, r, qtb));
+                    permutation[k] = k;
+                }
+
+                for(int k=0; k<size; ++k)
+                {
+                    int i = random_.uniformInt(size), j = random_.uniformInt(size);
+                    if(i==j) continue;
+
+                    vigra::linalg::detail::upperTriangularCyclicShiftColumns(i, j, r, qtb, permutation);
+                }
+                should(vigra::linalg::linearSolveUpperTriangular(r, qtb, px));
+                vigra::linalg::detail::inverseRowPermutation(px, xx, permutation);
+
+                shouldEqualSequenceTolerance(x.data(), x.data()+size, xx.data(), epsilon);
+            }
+
+            {
+                Matrix r(a), qtb(b), px(size,1), xx(size,1);
+                vigra::ArrayVector<unsigned int> permutation(size);
+
+                for(int k=0; k<size; ++k)
+                {
+                    // use Givens steps for a change (Householder steps like
+                    //    should(vigra::linalg::detail::qrColumnHouseholderStep(k, r, qtb));
+                    // work as well, but are already extensively tested within the QR algorithm)
+                    should(vigra::linalg::detail::qrGivensStepImpl(k, r, qtb));
+                    permutation[k] = k;
+                }
+
+                for(int k=0; k<size; ++k)
+                {
+                    int i = random_.uniformInt(size), j = random_.uniformInt(size);
+                    vigra::linalg::detail::upperTriangularSwapColumns(i, j, r, qtb, permutation);
+                }
+                should(vigra::linalg::linearSolveUpperTriangular(r, qtb, px));
+                vigra::linalg::detail::inverseRowPermutation(px, xx, permutation);
+
+                shouldEqualSequenceTolerance(x.data(), x.data()+size, xx.data(), epsilon);
+            }
+        }
+    }
+
+    void testInverse()
+    {
+        double epsilon = 1e-11;
+        Matrix idref = vigra::identityMatrix<double>(size);
+
+        for(unsigned int i = 0; i < iterations; ++i)
+        {
+            Matrix a = random_matrix (size, size);
+            Matrix id = a * inverse(a);
+            shouldEqualSequenceTolerance(id.data(), id.data()+size*size, idref.data(), epsilon);
+            id = inverse(a) * a;
+            shouldEqualSequenceTolerance(id.data(), id.data()+size*size, idref.data(), epsilon);
+            id = inverse(idref * a) * a; // test inverse(const TemporaryMatrix<T> &v)
+            shouldEqualSequenceTolerance(id.data(), id.data()+size*size, idref.data(), epsilon);
+        }
+
+        double data[] = { 1.0, 0.0, 0.0, 0.0 };
+        Matrix singular(2, 2, data);
+        try {
+            inverse(singular);
+            failTest("inverse(singular) didn't throw an exception.");
+        }
+        catch(vigra::PreconditionViolation & c)
+        {
+            std::string expected("\nPrecondition violation!\ninverse(): matrix is not invertible.");
+            std::string message(c.what());
+            should(0 == expected.compare(message.substr(0,expected.size())));
+        }
+
+        // test pseudo-inverse
+        double data2[] = { 0.,  1.,  0.,  0.,  0.,
+                           0.,  0.,  1.,  0.,  2.,
+                           2.,  0.,  0.,  3.,  0. };
+        double refdata[] = {  0.0, 0.0, 0.15384615384615388,
+                              1.0, 0.0, 0.0,
+                              0.0, 0.2, 0.0,
+                              0.0, 0.0, 0.23076923076923081,
+                              0.0, 0.4, 0.0 };
+            
+        Matrix m(3, 5, data2), piref(5, 3, refdata), pitref(transpose(piref));
+        Matrix pi = inverse(m);
+        shouldEqual(pi.shape(), Shape(5, 3));
+        shouldEqualSequenceTolerance(piref.data(), piref.data()+15, pi.data(), 1e-15);
+
+        Matrix pit = inverse(transpose(m));
+        shouldEqual(pit.shape(), Shape(3, 5));
+        shouldEqualSequenceTolerance(pitref.data(), pitref.data()+15, pit.data(), 1e-15);
+    }
+
+    void testSymmetricEigensystem()
+    {
+        double epsilon = 1e-8;
+        Matrix idref = vigra::identityMatrix<double>(size);
+
+        for(unsigned int i = 0; i < iterations; ++i)
+        {
+            Matrix a = random_symmetric_matrix (size);
+            Matrix ew(size, 1);
+            Matrix ev(size, size);
+            should(symmetricEigensystem(a, ew, ev));
+            Matrix id = ev * transpose(ev);
+            shouldEqualSequenceTolerance(id.data(), id.data()+size*size, idref.data(), epsilon);
+            Matrix ae = ev * diagonalMatrix(ew) * transpose(ev);
+            shouldEqualSequenceTolerance(ae.data(), ae.data()+size*size, a.data(), epsilon);
+        }
+    }
+
+    void testSymmetricEigensystemAnalytic()
+    {
+        double epsilon = 1e-8;
+
+        int size = 2;
+        for(unsigned int i = 0; i < iterations; ++i)
+        {
+            Matrix a = random_symmetric_matrix (size);
+            Matrix ew(size, 1), ewref(size, 1);
+            Matrix ev(size, size);
+            symmetricEigensystem(a, ewref, ev);
+            vigra::symmetric2x2Eigenvalues(
+                a(0,0), a(0,1),
+                a(1,1),
+                &ew(0,0), &ew(1,0));
+            shouldEqualSequenceTolerance(ew.data(), ew.data()+size, ewref.data(), epsilon);
+        }
+
+        size = 3;
+        for(unsigned int i = 0; i < iterations; ++i)
+        {
+            Matrix a = random_symmetric_matrix (size);
+            Matrix ew(size, 1), ewref(size, 1);
+            Matrix ev(size, size);
+            symmetricEigensystem(a, ewref, ev);
+            vigra::symmetric3x3Eigenvalues<double>(
+                a(0,0), a(0,1), a(0,2),
+                a(1,1), a(1,2),
+                a(2,2),
+                &ew(0,0), &ew(1,0), &ew(2,0));
+            shouldEqualSequenceTolerance(ew.data(), ew.data()+size, ewref.data(), epsilon);
+        }
+    }
+
+    void testNonsymmetricEigensystem()
+    {
+        double epsilon = 1e-8;
+        Matrix idref = vigra::identityMatrix<double>(size);
+
+        for(unsigned int i = 0; i < iterations; ++i)
+        {
+            Matrix a = random_matrix (size, size);
+            vigra::Matrix<std::complex<double> > ew(size, 1);
+            Matrix ev(size, size);
+            should(nonsymmetricEigensystem(a, ew, ev));
+
+            Matrix ewm(size, size);
+            for(unsigned int k = 0; k < size; k++)
+            {
+                ewm(k, k) = ew(k, 0).real();
+                if(ew(k, 0).imag() > 0.0)
+                {
+                    ewm(k, k+1) = ew(k, 0).imag();
+                }
+                else if(ew(k, 0).imag() < 0.0)
+                {
+                    ewm(k, k-1) = ew(k, 0).imag();
+                }
+            }
+            Matrix ae = ev * ewm * inverse(ev);
+            shouldEqualSequenceTolerance(ae.data(), ae.data()+size*size, a.data(), epsilon);
+        }
+    }
+
+    void testDeterminant()
+    {
+        double ds2[] = {1, 2, 2, 1};
+        double dns2[] = {1, 2, 3, 1};
+        Matrix ms2(Shape(2,2), ds2);
+        Matrix mns2(Shape(2,2), dns2);
+        double eps = 1e-12;
+        shouldEqualTolerance(determinant(ms2), -3.0, eps);
+        shouldEqualTolerance(determinant(mns2), -5.0, eps);
+        shouldEqualTolerance(logDeterminant(transpose(ms2)*ms2), std::log(9.0), eps);
+        shouldEqualTolerance(logDeterminant(transpose(mns2)*mns2), std::log(25.0), eps);
+
+        double ds3[] = {1, 2, 3, 2, 3, 1, 3, 1, 2};
+        double dns3[] = {1, 2, 3, 5, 3, 1, 3, 1, 2};
+        Matrix ms3(Shape(3,3), ds3);
+        Matrix mns3(Shape(3,3), dns3);
+        shouldEqualTolerance(determinant(ms3), -18.0, eps);
+        shouldEqualTolerance(determinant(mns3), -21.0, eps);
+        shouldEqualTolerance(determinant(transpose(ms3)*ms3, "Cholesky"), 324.0, eps);
+        shouldEqualTolerance(determinant(transpose(mns3)*mns3, "Cholesky"), 441.0, eps);
+        shouldEqualTolerance(logDeterminant(transpose(ms3)*ms3), std::log(324.0), eps);
+        shouldEqualTolerance(logDeterminant(transpose(mns3)*mns3), std::log(441.0), eps);
+    }
+
+    void testSVD()
+    {
+        unsigned int m = 6, n = 4;
+        Matrix a(m, n);
+        for(unsigned int i1= 0; i1 < m; i1++)
+            for(unsigned int i2= 0; i2 < n; i2++)
+                a(i1, i2)= random_double();
+        Matrix u(m, n);
+        Matrix v(n, n);
+        Matrix S(n, 1);
+
+        unsigned int rank = singularValueDecomposition(a, u, S, v);
+        shouldEqual(rank, n);
+
+        double eps = 1e-11;
+
+        shouldEqualToleranceMessage(vigra::norm(a-u*diagonalMatrix(S)*transpose(v)), 0.0, eps, VIGRA_TOLERANCE_MESSAGE);
+        shouldEqualToleranceMessage(vigra::norm(vigra::identityMatrix<double>(4) - transpose(u)*u), 0.0, eps, VIGRA_TOLERANCE_MESSAGE);
+        shouldEqualToleranceMessage(vigra::norm(vigra::identityMatrix<double>(4) - transpose(v)*v), 0.0, eps, VIGRA_TOLERANCE_MESSAGE);
+        shouldEqualToleranceMessage(vigra::norm(vigra::identityMatrix<double>(4) - v*transpose(v)), 0.0, eps, VIGRA_TOLERANCE_MESSAGE);
+    }
+};
+
+struct RandomTest
+{
+    void testTT800()
+    {
+        const unsigned int n = 50;
+        unsigned int iref[n] = {
+            3169973338U, 2724982910U,  347012937U, 1735893326U, 2282497071U,
+            3975116866U,   62755666U,  500522132U,  129776071U, 1978109378U,
+            4040131704U, 3800592193U, 3057303977U, 1468369496U,  370579849U,
+            3630178833U,   51910867U,  819270944U,  476180518U,  190380673U,
+            1370447020U, 1620916304U,  663482756U, 1354889312U, 4000276916U,
+             868393086U, 1441698743U, 1086138563U, 1899869374U, 3717419747U,
+            2455034041U, 2617437696U, 1595651084U, 4148285605U, 1860328467U,
+             928897371U,  263340857U, 4091726170U, 2359987311U, 1669697327U,
+            1882626857U, 1635656338U,  897501559U, 3233276032U,  373770970U,
+            2950632840U, 2706386845U, 3294066568U, 3819538748U, 1902519841U };
+
+        vigra::RandomTT800 random;
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqual(random(), iref[k]);
+
+        double fref[n] = {
+              0.738067,   0.634460,   0.080795,   0.404169,   0.531435,
+              0.925529,   0.014611,   0.116537,   0.030216,   0.460564,
+              0.940666,   0.884894,   0.711834,   0.341881,   0.086282,
+              0.845217,   0.012086,   0.190751,   0.110869,   0.044326,
+              0.319082,   0.377399,   0.154479,   0.315460,   0.931387,
+              0.202189,   0.335672,   0.252886,   0.442348,   0.865529,
+              0.571607,   0.609420,   0.371516,   0.965848,   0.433141,
+              0.216276,   0.061314,   0.952679,   0.549477,   0.388757,
+              0.438333,   0.380831,   0.208966,   0.752806,   0.087025,
+              0.686998,   0.630130,   0.766960,   0.889306,   0.442965 };
+        vigra::RandomTT800 randomf;
+        for(unsigned int k=0; k<n; ++k)
+            should(vigra::abs(randomf.uniform() - fref[k]) < 2e-6);
+
+        vigra::RandomTT800 randomr(vigra::RandomSeed);
+    }
+
+    void testMT19937()
+    {
+        const unsigned int n = 20, skip = 960, ilen = 4;
+        unsigned int first[n] = {
+             956529277U, 3842322136U, 3319553134U, 1843186657U, 2704993644U,
+             595827513U,  938518626U, 1676224337U, 3221315650U, 1819026461U,
+            2401778706U, 2494028885U,  767405145U, 1590064561U, 2766888951U,
+            3951114980U, 2568046436U, 2550998890U, 2642089177U,  568249289U };
+        unsigned int last[n] = {
+            2396869032U, 1982500200U, 2649478910U,  839934727U, 3814542520U,
+             918389387U,  995030736U, 2017568170U, 2621335422U, 1020082601U,
+              24244213U, 2575242697U, 3941971804U,  922591409U, 2851763435U,
+            2055641408U, 3695291669U, 2040276077U, 4118847636U, 3528766079U };
+
+        vigra::RandomMT19937 random(0xDEADBEEF);
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqual(random(), first[k]);
+        for(unsigned int k=0; k<skip; ++k)
+            random();
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqual(random(), last[k]);
+
+        for(unsigned int k=0; k<skip; ++k)
+            should(random.uniformInt(31) < 31);
+
+        random.seed(0xDEADBEEF);
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqual(random(), first[k]);
+        for(unsigned int k=0; k<skip; ++k)
+            random();
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqual(random(), last[k]);
+
+        unsigned int firsta[n] = {
+            1067595299U,  955945823U,  477289528U, 4107218783U, 4228976476U,
+            3344332714U, 3355579695U,  227628506U,  810200273U, 2591290167U,
+            2560260675U, 3242736208U,  646746669U, 1479517882U, 4245472273U,
+            1143372638U, 3863670494U, 3221021970U, 1773610557U, 1138697238U };
+        unsigned int lasta[n] = {
+             123599888U,  472658308U, 1053598179U, 1012713758U, 3481064843U,
+            3759461013U, 3981457956U, 3830587662U, 1877191791U, 3650996736U,
+             988064871U, 3515461600U, 4089077232U, 2225147448U, 1249609188U,
+            2643151863U, 3896204135U, 2416995901U, 1397735321U, 3460025646U };
+
+        unsigned int init[ilen] = {0x123, 0x234, 0x345, 0x456};
+        vigra::RandomMT19937 randoma(init, ilen);
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqual(randoma(), firsta[k]);
+        for(unsigned int k=0; k<skip; ++k)
+            randoma();
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqual(randoma(), lasta[k]);
+
+        double ref53[n] = {
+            0.76275444, 0.98670464, 0.27933125, 0.94218739, 0.78842173,
+            0.92179002, 0.54534773, 0.38107717, 0.65286910, 0.22765212,
+            0.74557914, 0.54708246, 0.42043117, 0.19189126, 0.70259889,
+            0.77408120, 0.04605807, 0.69398269, 0.61711170, 0.10133577};
+        for(unsigned int k=0; k<n; ++k)
+            should(vigra::abs(randoma.uniform53()-ref53[k]) < 2e-8);
+
+        randoma.seed(init, ilen);
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqual(randoma(), firsta[k]);
+        for(unsigned int k=0; k<skip; ++k)
+            randoma();
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqual(randoma(), lasta[k]);
+    }
+
+    void testRandomFunctors()
+    {
+        const unsigned int n = 50;
+        unsigned int iref[n] = {
+            3169973338U, 2724982910U,  347012937U, 1735893326U, 2282497071U,
+            3975116866U,   62755666U,  500522132U,  129776071U, 1978109378U,
+            4040131704U, 3800592193U, 3057303977U, 1468369496U,  370579849U,
+            3630178833U,   51910867U,  819270944U,  476180518U,  190380673U,
+            1370447020U, 1620916304U,  663482756U, 1354889312U, 4000276916U,
+             868393086U, 1441698743U, 1086138563U, 1899869374U, 3717419747U,
+            2455034041U, 2617437696U, 1595651084U, 4148285605U, 1860328467U,
+             928897371U,  263340857U, 4091726170U, 2359987311U, 1669697327U,
+            1882626857U, 1635656338U,  897501559U, 3233276032U,  373770970U,
+            2950632840U, 2706386845U, 3294066568U, 3819538748U, 1902519841U };
+        double fref[n] = {
+              0.738067,   0.634460,   0.080795,   0.404169,   0.531435,
+              0.925529,   0.014611,   0.116537,   0.030216,   0.460564,
+              0.940666,   0.884894,   0.711834,   0.341881,   0.086282,
+              0.845217,   0.012086,   0.190751,   0.110869,   0.044326,
+              0.319082,   0.377399,   0.154479,   0.315460,   0.931387,
+              0.202189,   0.335672,   0.252886,   0.442348,   0.865529,
+              0.571607,   0.609420,   0.371516,   0.965848,   0.433141,
+              0.216276,   0.061314,   0.952679,   0.549477,   0.388757,
+              0.438333,   0.380831,   0.208966,   0.752806,   0.087025,
+              0.686998,   0.630130,   0.766960,   0.889306,   0.442965 };
+        double nref[n] = {
+            1.35298, 0.764158, -0.757076, -0.173069, 0.0586711,
+            0.794212, -0.483372, -0.0405762, 1.27956, -0.955101,
+            -1.5062, -1.02069, -0.871562, -0.465495, -0.799888,
+            -1.20286, -0.170944, 1.08383, 1.26832, 1.93807,
+            -0.098183, 0.355986, -0.336965, -1.42996, 0.966012,
+            -2.17195, -1.05422, -2.03724, -0.769992, 0.668851,
+            -0.570259, 0.258217, 0.632492, 1.29755, 0.96869,
+            -0.141918, -0.836236, -0.62337, 0.116509, -0.0314471,
+            0.402451, -1.20504, -0.140861, -0.0765263, 1.06057,
+            2.57671, 0.0299117, 0.471425, 1.59464, 1.37346};
+
+        vigra::RandomTT800 random1;
+        vigra::UniformRandomFunctor<vigra::RandomTT800> f1(random1);
+        for(unsigned int k=0; k<n; ++k)
+            should(vigra::abs(f1() - fref[k]) < 2e-6);
+
+        vigra::RandomTT800 random2;
+        vigra::UniformIntRandomFunctor<vigra::RandomTT800> f2(4, 34, random2, true);
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqual(f2(), iref[k] % 31 + 4);
+
+        vigra::RandomTT800 random3;
+        vigra::UniformIntRandomFunctor<vigra::RandomTT800> f3(random3);
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqual(f3(32), iref[k] % 32);
+
+        vigra::RandomTT800 random4;
+        vigra::NormalRandomFunctor<vigra::RandomTT800> f4(random4);
+        for(unsigned int k=0; k<n; ++k)
+            shouldEqualTolerance(f4(), nref[k], 1e-5);
+    }
+};
+
+struct PolygonTest
+{
+    typedef vigra::TinyVector<double, 2> Point;
+    
+    void testConvexHull()
+    {
+        vigra::ArrayVector<Point> points, reference, hull;
+        points.push_back(Point(0.0, 0.0));
+        points.push_back(Point(2.0, 1.0));
+        points.push_back(Point(2.0, -1.0));
+        points.push_back(Point(0.0, 2.0));
+        points.push_back(Point(-2.0, 1.0));
+        points.push_back(Point(-2.0, -1.0));
+        points.push_back(Point(0.0, -2.0));
+
+        reference.push_back(Point(-2.0, -1.0));
+        reference.push_back(Point(0.0, -2.0));
+        reference.push_back(Point(2.0, -1.0));
+        reference.push_back(Point(2.0, 1.0));
+        reference.push_back(Point(0.0, 2.0));
+        reference.push_back(Point(-2.0, 1.0));
+        reference.push_back(Point(-2.0, -1.0));
+        
+        vigra::convexHull(points, hull);
+
+        shouldEqual(7u, hull.size());
+        shouldEqualSequence(reference.begin(), reference.end(), hull.begin());
+
+        hull.clear();
+
+        vigra::convexHull(reference, hull);
+        
+        shouldEqual(7u, hull.size());
+        shouldEqualSequence(reference.begin(), reference.end(), hull.begin());
+        
+        typedef Point P;
+        P p[200] = { P(0.0, 0.0), P(42.0, 468.0), P(335.0, 501.0), P(170.0, 725.0), P(479.0, 359.0), 
+                  P(963.0, 465.0), P(706.0, 146.0), P(282.0, 828.0), P(962.0, 492.0), 
+                  P(996.0, 943.0), P(828.0, 437.0), P(392.0, 605.0), P(903.0, 154.0), 
+                  P(293.0, 383.0), P(422.0, 717.0), P(719.0, 896.0), P(448.0, 727.0), 
+                  P(772.0, 539.0), P(870.0, 913.0), P(668.0, 300.0), P(36.0, 895.0), 
+                  P(704.0, 812.0), P(323.0, 334.0), P(674.0, 665.0), P(142.0, 712.0), 
+                  P(254.0, 869.0), P(548.0, 645.0), P(663.0, 758.0), P(38.0, 860.0), 
+                  P(724.0, 742.0), P(530.0, 779.0), P(317.0, 36.0), P(191.0, 843.0), 
+                  P(289.0, 107.0), P(41.0, 943.0), P(265.0, 649.0), P(447.0, 806.0), 
+                  P(891.0, 730.0), P(371.0, 351.0), P(7.0, 102.0), P(394.0, 549.0), 
+                  P(630.0, 624.0), P(85.0, 955.0), P(757.0, 841.0), P(967.0, 377.0), 
+                  P(932.0, 309.0), P(945.0, 440.0), P(627.0, 324.0), P(538.0, 539.0), 
+                  P(119.0, 83.0), P(930.0, 542.0), P(834.0, 116.0), P(640.0, 659.0), 
+                  P(705.0, 931.0), P(978.0, 307.0), P(674.0, 387.0), P(22.0, 746.0), 
+                  P(925.0, 73.0), P(271.0, 830.0), P(778.0, 574.0), P(98.0, 513.0), 
+                  P(987.0, 291.0), P(162.0, 637.0), P(356.0, 768.0), P(656.0, 575.0), 
+                  P(32.0, 53.0), P(351.0, 151.0), P(942.0, 725.0), P(967.0, 431.0), 
+                  P(108.0, 192.0), P(8.0, 338.0), P(458.0, 288.0), P(754.0, 384.0), 
+                  P(946.0, 910.0), P(210.0, 759.0), P(222.0, 589.0), P(423.0, 947.0), 
+                  P(507.0, 31.0), P(414.0, 169.0), P(901.0, 592.0), P(763.0, 656.0), 
+                  P(411.0, 360.0), P(625.0, 538.0), P(549.0, 484.0), P(596.0, 42.0), 
+                  P(603.0, 351.0), P(292.0, 837.0), P(375.0, 21.0), P(597.0, 22.0), 
+                  P(349.0, 200.0), P(669.0, 485.0), P(282.0, 735.0), P(54.0, 1000.0), 
+                  P(419.0, 939.0), P(901.0, 789.0), P(128.0, 468.0), P(729.0, 894.0), 
+                  P(649.0, 484.0), P(808.0, 422.0), P(311.0, 618.0), P(814.0, 515.0), 
+                  P(310.0, 617.0), P(936.0, 452.0), P(601.0, 250.0), P(520.0, 557.0), 
+                  P(799.0, 304.0), P(225.0, 9.0), P(845.0, 610.0), P(990.0, 703.0), 
+                  P(196.0, 486.0), P(94.0, 344.0), P(524.0, 588.0), P(315.0, 504.0), 
+                  P(449.0, 201.0), P(459.0, 619.0), P(581.0, 797.0), P(799.0, 282.0), 
+                  P(590.0, 799.0), P(10.0, 158.0), P(473.0, 623.0), P(539.0, 293.0), 
+                  P(39.0, 180.0), P(191.0, 658.0), P(959.0, 192.0), P(816.0, 889.0), 
+                  P(157.0, 512.0), P(203.0, 635.0), P(273.0, 56.0), P(329.0, 647.0), 
+                  P(363.0, 887.0), P(876.0, 434.0), P(870.0, 143.0), P(845.0, 417.0), 
+                  P(882.0, 999.0), P(323.0, 652.0), P(22.0, 700.0), P(558.0, 477.0), 
+                  P(893.0, 390.0), P(76.0, 713.0), P(601.0, 511.0), P(4.0, 870.0), 
+                  P(862.0, 689.0), P(402.0, 790.0), P(256.0, 424.0), P(3.0, 586.0), 
+                  P(183.0, 286.0), P(89.0, 427.0), P(618.0, 758.0), P(833.0, 933.0), 
+                  P(170.0, 155.0), P(722.0, 190.0), P(977.0, 330.0), P(369.0, 693.0), 
+                  P(426.0, 556.0), P(435.0, 550.0), P(442.0, 513.0), P(146.0, 61.0), 
+                  P(719.0, 754.0), P(140.0, 424.0), P(280.0, 997.0), P(688.0, 530.0), 
+                  P(550.0, 438.0), P(867.0, 950.0), P(194.0, 196.0), P(298.0, 417.0), 
+                  P(287.0, 106.0), P(489.0, 283.0), P(456.0, 735.0), P(115.0, 702.0), 
+                  P(317.0, 672.0), P(787.0, 264.0), P(314.0, 356.0), P(186.0, 54.0), 
+                  P(913.0, 809.0), P(833.0, 946.0), P(314.0, 757.0), P(322.0, 559.0), 
+                  P(647.0, 983.0), P(482.0, 145.0), P(197.0, 223.0), P(130.0, 162.0), 
+                  P(536.0, 451.0), P(174.0, 467.0), P(45.0, 660.0), P(293.0, 440.0), 
+                  P(254.0, 25.0), P(155.0, 511.0), P(746.0, 650.0), P(187.0, 314.0), 
+                  P(475.0, 23.0), P(169.0, 19.0), P(788.0, 906.0), P(959.0, 392.0), 
+                  P(203.0, 626.0), P(478.0, 415.0), P(315.0, 825.0), P(335.0, 875.0), 
+                  P(373.0, 160.0), P(834.0, 71.0), P(488.0, 298.0) };
+                  
+        P ref[10] = { P(0.0, 0.0), P(597.0, 22.0), P(925.0, 73.0), P(959.0, 192.0), 
+                    P(987.0, 291.0), P(996.0, 943.0), P(882.0, 999.0), P(54.0, 1000.0),
+                    P(4.0, 870.0), P(0.0, 0.0) };
+        points = vigra::ArrayVector<Point>(p, p+200);
+        hull.clear();
+        
+        vigra::convexHull(points, hull);
+        
+        shouldEqual(10u, hull.size());
+        shouldEqualSequence(ref, ref+10, hull.begin());
+
+        int size = sizeof(convexHullInputs) / sizeof(Point);
+        points = vigra::ArrayVector<Point>(convexHullInputs, convexHullInputs+size);
+        hull.clear();
+        
+        vigra::convexHull(points, hull);
+        
+        shouldEqual(17u, hull.size());
+        shouldEqualSequence(convexHullReference, convexHullReference+17, hull.begin());
+    }
+};
+
+
+struct MathTestSuite
+: public vigra::test_suite
+{
+    MathTestSuite()
+    : vigra::test_suite("MathTest")
+    {
+        typedef vigra::Polynomial<double> P1;
+        typedef vigra::StaticPolynomial<10, double> P2;
+
+        add( testCase((&PolynomialTest<0, P1>::testPolynomial)));
+        add( testCase((&PolynomialTest<1, P1>::testPolynomial)));
+        add( testCase((&PolynomialTest<2, P1>::testPolynomial)));
+        add( testCase((&PolynomialTest<3, P1>::testPolynomial)));
+        add( testCase((&PolynomialTest<4, P1>::testPolynomial)));
+        add( testCase((&PolynomialTest<5, P1>::testPolynomial)));
+        add( testCase((&PolynomialTest<6, P1>::testPolynomial)));
+        add( testCase((&PolynomialTest<7, P1>::testPolynomial)));
+
+        // test only some polynomials, as the eigenvalue method is less robust
+        add( testCase((&PolynomialTest<1, P1>::testPolynomialEigenvalueMethod)));
+        add( testCase((&PolynomialTest<5, P1>::testPolynomialEigenvalueMethod)));
+        add( testCase((&PolynomialTest<6, P1>::testPolynomialEigenvalueMethod)));
+        add( testCase((&PolynomialTest<7, P1>::testPolynomialEigenvalueMethod)));
+
+        add( testCase((&PolynomialTest<0, P2>::testPolynomial)));
+        add( testCase((&PolynomialTest<1, P2>::testPolynomial)));
+        add( testCase((&PolynomialTest<2, P2>::testPolynomial)));
+
+        add( testCase(&HighOrderPolynomialTest::testPolynomial));
+        add( testCase(&HighOrderPolynomialTest::testPolynomialEigenvalueMethod));
+
+        add( testCase(&SplineTest<0>::testValues));
+        add( testCase(&SplineTest<1>::testValues));
+        add( testCase(&SplineTest<2>::testValues));
+        add( testCase(&SplineTest<3>::testValues));
+        add( testCase(&SplineTest<4>::testValues));
+        add( testCase(&SplineTest<5>::testValues));
+        add( testCase(&SplineTest<0>::testFixedPointValues));
+        add( testCase(&SplineTest<1>::testFixedPointValues));
+        add( testCase(&SplineTest<2>::testFixedPointValues));
+        add( testCase(&SplineTest<3>::testFixedPointValues));
+        add( testCase(&SplineTest<0>::testPrefilterCoefficients));
+        add( testCase(&SplineTest<1>::testPrefilterCoefficients));
+        add( testCase(&SplineTest<2>::testPrefilterCoefficients));
+        add( testCase(&SplineTest<3>::testPrefilterCoefficients));
+        add( testCase(&SplineTest<4>::testPrefilterCoefficients));
+        add( testCase(&SplineTest<5>::testPrefilterCoefficients));
+        add( testCase(&SplineTest<0>::testWeightMatrix));
+        add( testCase(&SplineTest<1>::testWeightMatrix));
+        add( testCase(&SplineTest<2>::testWeightMatrix));
+        add( testCase(&SplineTest<3>::testWeightMatrix));
+        add( testCase(&SplineTest<4>::testWeightMatrix));
+        add( testCase(&SplineTest<5>::testWeightMatrix));
+
+        add( testCase(&FunctionsTest::testGaussians));
+        add( testCase(&FunctionsTest::testSpecialIntegerFunctions));
+        add( testCase(&FunctionsTest::testSpecialFunctions));
+        add( testCase(&FunctionsTest::testBessel));
+        add( testCase(&FunctionsTest::closeAtToleranceTest));
+        add( testCase(&FunctionsTest::testArgMinMax));
+        add( testCase(&FunctionsTest::testAlgorithms));
+        add( testCase(&FunctionsTest::testChecksum));
+        add( testCase(&FunctionsTest::testClebschGordan));
+
+        add( testCase(&RationalTest::testGcdLcm));
+        add( testCase(&RationalTest::testOStreamShifting));
+        add( testCase(&RationalTest::testOperators));
+        add( testCase(&RationalTest::testConversion));
+        add( testCase(&RationalTest::testFunctions));
+        add( testCase(&RationalTest::testInf));
+
+        add( testCase(&AutodiffTest::testOStreamShifting));
+        add( testCase(&AutodiffTest::testOperators));
+        add( testCase(&AutodiffTest::testFunctions));
+
+        add( testCase(&QuaternionTest::testContents));
+        add( testCase(&QuaternionTest::testStreamIO));
+        add( testCase(&QuaternionTest::testOperators));
+        add( testCase(&QuaternionTest::testRotation));
+
+        add( testCase(&LinalgTest::testOStreamShifting));
+        add( testCase(&LinalgTest::testMatrix));
+        add( testCase(&LinalgTest::testArgMinMax));
+        add( testCase(&LinalgTest::testColumnAndRowStatistics));
+        add( testCase(&LinalgTest::testColumnAndRowPreparation));
+        add( testCase(&LinalgTest::testCholesky));
+        add( testCase(&LinalgTest::testQR));
+        add( testCase(&LinalgTest::testLinearSolve));
+        add( testCase(&LinalgTest::testUnderdetermined));
+        add( testCase(&LinalgTest::testOverdetermined));
+        add( testCase(&LinalgTest::testIncrementalLinearSolve));
+        add( testCase(&LinalgTest::testInverse));
+        add( testCase(&LinalgTest::testSymmetricEigensystem));
+        add( testCase(&LinalgTest::testNonsymmetricEigensystem));
+        add( testCase(&LinalgTest::testSymmetricEigensystemAnalytic));
+        add( testCase(&LinalgTest::testDeterminant));
+        add( testCase(&LinalgTest::testSVD));
+
+        add( testCase(&FixedPointTest::testConstruction));
+        add( testCase(&FixedPointTest::testComparison));
+        add( testCase(&FixedPointTest::testArithmetic));
+        add( testCase(&FixedPoint16Test::testConstruction));
+        add( testCase(&FixedPoint16Test::testComparison));
+        add( testCase(&FixedPoint16Test::testArithmetic));
+
+        add( testCase(&RandomTest::testTT800));
+        add( testCase(&RandomTest::testMT19937));
+        add( testCase(&RandomTest::testRandomFunctors));
+
+        add( testCase(&PolygonTest::testConvexHull));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+  try
+  {
+    MathTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cerr << test.report() << std::endl;
+
+    return (failed != 0);
+  }
+  catch(std::exception & e)
+  {
+    std::cerr << "Unexpected exception: " << e.what() << "\n";
+    return 1;
+  }
+}
diff --git a/test/morphology/CMakeLists.txt b/test/morphology/CMakeLists.txt
new file mode 100644
index 0000000..43b587a
--- /dev/null
+++ b/test/morphology/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_morphology test.cxx)
diff --git a/test/morphology/test.cxx b/test/morphology/test.cxx
new file mode 100755
index 0000000..81510af
--- /dev/null
+++ b/test/morphology/test.cxx
@@ -0,0 +1,296 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include "vigra/unittest.hxx"
+#include "vigra/stdimage.hxx"
+#include "vigra/flatmorphology.hxx"
+#include "vigra/multi_array.hxx"
+
+using namespace vigra;
+
+struct FlatMorphologyTest
+{
+    typedef vigra::BImage Image;
+    typedef vigra::MultiArrayView<2, unsigned char> View;
+
+    FlatMorphologyTest()
+    : img(7,7), mask(7,7)
+    {
+        static const unsigned char in[] = {
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6};
+        
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator end = img.end();
+        Image::Accessor acc = img.accessor();
+        const unsigned char * p = in;
+        
+        for(; i != end; ++i, ++p)
+        {
+            acc.set(*p, i);
+        }
+
+        static const unsigned char in1[] = {
+            1, 1, 1, 1, 1, 1, 1,
+            0, 1, 1, 1, 1, 1, 0,
+            0, 1, 1, 1, 1, 1, 0,
+            0, 1, 1, 1, 1, 1, 0,
+            0, 1, 1, 1, 1, 1, 0,
+            0, 1, 1, 1, 1, 1, 0,
+            1, 1, 1, 1, 1, 1, 1};
+        
+        i = mask.begin();
+        end = mask.end();
+        p = in1;
+        
+        for(; i != end; ++i, ++p)
+        {
+            acc.set(*p, i);
+        }
+    }
+    
+    void erosionTest()
+    {
+        Image res(img.size()), res1(img.size());
+        
+        discErosion(srcImageRange(img), destImage(res), 2);
+        
+        static const unsigned char desired[] = {
+                   0, 0, 0, 1, 2, 3, 4,
+                   0, 0, 0, 1, 2, 3, 4,
+                   0, 0, 0, 1, 2, 3, 4,
+                   0, 0, 0, 1, 2, 3, 4,
+                   0, 0, 0, 1, 2, 3, 4,
+                   0, 0, 0, 1, 2, 3, 4,
+                   0, 0, 0, 1, 2, 3, 4};
+                                         
+        const unsigned char * i1 = desired;
+        const unsigned char * i1end = i1 + 49;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+
+        discErosion(View(img), View(res1), 2);
+        should(View(res) == View(res1));
+    }
+    
+    void erosionWithMaskTest()
+    {
+        Image res(img.size(), 9), res1(img.size(), 9);
+        
+        discErosionWithMask(srcImageRange(img), maskImage(mask),
+                            destImage(res), 2);
+        
+        static const unsigned char desired[] = {
+                   0, 0, 0, 1, 2, 3, 4,
+                   0, 0, 0, 1, 2, 3, 4,
+                   0, 0, 1, 1, 2, 3, 4,
+                   1, 1, 1, 1, 2, 3, 4,
+                   0, 0, 1, 1, 2, 3, 4,
+                   0, 0, 0, 1, 2, 3, 4,
+                   0, 0, 0, 1, 2, 3, 4};
+                                         
+        const unsigned char * i1 = desired;
+        const unsigned char * i1end = i1 + 49;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+
+        discErosionWithMask(View(img), View(mask), View(res1), 2);
+        should(View(res) == View(res1));
+    }
+    
+    void dilationTest()
+    {
+        Image res(img.size()), res1(img.size());
+        
+        discDilation(srcImageRange(img), destImage(res), 2);
+        
+        static const unsigned char desired[] = {
+                   2, 3, 4, 5, 6, 6, 6,
+                   2, 3, 4, 5, 6, 6, 6,
+                   2, 3, 4, 5, 6, 6, 6,
+                   2, 3, 4, 5, 6, 6, 6,
+                   2, 3, 4, 5, 6, 6, 6,
+                   2, 3, 4, 5, 6, 6, 6,
+                   2, 3, 4, 5, 6, 6, 6};
+                                         
+        const unsigned char * i1 = desired;
+        const unsigned char * i1end = i1 + 49;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+
+        discDilation(View(img), View(res1), 2);
+        should(View(res) == View(res1));
+    }
+    
+    void dilationWithMaskTest()
+    {
+        Image res(img.size(), 9), res1(img.size(), 9);
+        
+        discDilationWithMask(srcImageRange(img), maskImage(mask),
+                            destImage(res), 2);
+        
+        static const unsigned char desired[] = {
+                   2, 3, 4, 5, 6, 6, 6,
+                   2, 3, 4, 5, 6, 6, 6,
+                   2, 3, 4, 5, 5, 6, 6,
+                   2, 3, 4, 5, 5, 5, 5,
+                   2, 3, 4, 5, 5, 6, 6,
+                   2, 3, 4, 5, 6, 6, 6,
+                   2, 3, 4, 5, 6, 6, 6};
+                                         
+        const unsigned char * i1 = desired;
+        const unsigned char * i1end = i1 + 49;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+
+        discDilationWithMask(View(img), View(mask), View(res1), 2);
+        should(View(res) == View(res1));
+    }
+    
+    void medianTest()
+    {
+        Image res(img.size()), res1(img.size());
+        
+        discMedian(srcImageRange(img), destImage(res), 2);
+        
+        static const unsigned char desired[] = {
+            1, 1, 2, 3, 4, 5, 5,
+            1, 1, 2, 3, 4, 5, 5,
+            1, 1, 2, 3, 4, 5, 5,
+            1, 1, 2, 3, 4, 5, 5,
+            1, 1, 2, 3, 4, 5, 5,
+            1, 1, 2, 3, 4, 5, 5,
+            1, 1, 2, 3, 4, 5, 5};
+                                         
+        const unsigned char * i1 = desired;
+        const unsigned char * i1end = i1 + 49;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+
+        discMedian(View(img), View(res1), 2);
+        should(View(res) == View(res1));
+    }
+    
+    void medianWithMaskTest()
+    {
+        Image res(img.size(), 9), res1(img.size(), 9);
+        
+        discMedianWithMask(srcImageRange(img), maskImage(mask),
+                            destImage(res), 2);
+        
+        static const unsigned char desired[] = {
+                   1, 2, 2, 3, 4, 4, 5,
+                   1, 2, 2, 3, 4, 4, 5,
+                   1, 2, 2, 3, 4, 4, 5,
+                   1, 2, 2, 3, 4, 4, 5,
+                   1, 2, 2, 3, 4, 4, 5,
+                   1, 2, 2, 3, 4, 4, 5,
+                   1, 2, 2, 3, 4, 4, 5};
+                                         
+        const unsigned char * i1 = desired;
+        const unsigned char * i1end = i1 + 49;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+        
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+
+        discMedianWithMask(View(img), View(mask), View(res1), 2);
+        should(View(res) == View(res1));
+    }
+    
+    Image img, mask;
+};
+
+        
+struct MorphologyTestSuite
+: public vigra::test_suite
+{
+    MorphologyTestSuite()
+    : vigra::test_suite("MorphologyTestSuite")
+    {
+        add( testCase( &FlatMorphologyTest::erosionTest));
+        add( testCase( &FlatMorphologyTest::erosionWithMaskTest));
+        add( testCase( &FlatMorphologyTest::dilationTest));
+        add( testCase( &FlatMorphologyTest::dilationWithMaskTest));
+        add( testCase( &FlatMorphologyTest::medianTest));
+        add( testCase( &FlatMorphologyTest::medianWithMaskTest));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    MorphologyTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+
+    return (failed != 0);
+}
+
diff --git a/test/multiarray/CMakeLists.txt b/test/multiarray/CMakeLists.txt
new file mode 100644
index 0000000..a30f519
--- /dev/null
+++ b/test/multiarray/CMakeLists.txt
@@ -0,0 +1,15 @@
+IF(JPEG_FOUND)
+  ADD_DEFINITIONS(-DHasJPEG)
+ENDIF(JPEG_FOUND)
+
+IF(PNG_FOUND)
+  ADD_DEFINITIONS(-DHasPNG)
+ENDIF(PNG_FOUND)
+
+IF(TIFF_FOUND)
+  ADD_DEFINITIONS(-DHasTIFF)
+ENDIF(TIFF_FOUND)
+
+VIGRA_ADD_TEST(test_multiarray test.cxx LIBRARIES vigraimpex)
+
+FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/impex)
diff --git a/test/multiarray/test.cxx b/test/multiarray/test.cxx
new file mode 100644
index 0000000..eb18ec5
--- /dev/null
+++ b/test/multiarray/test.cxx
@@ -0,0 +1,2991 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include "vigra/unittest.hxx"
+#include "vigra/multi_array.hxx"
+#include "vigra/multi_iterator_coupled.hxx"
+#include "vigra/multi_impex.hxx"
+#include "vigra/basicimageview.hxx"
+#include "vigra/navigator.hxx"
+#include "vigra/multi_pointoperators.hxx"
+#include "vigra/tensorutilities.hxx"
+#include "vigra/multi_tensorutilities.hxx"
+#include "vigra/functorexpression.hxx"
+#include "vigra/multi_math.hxx"
+#include "vigra/algorithm.hxx"
+#include "vigra/random.hxx"
+#include "vigra/timing.hxx"
+//#include "marray.hxx"
+
+using namespace vigra;
+using namespace vigra::functor;
+
+template <class T>
+class MultiArrayDataTest
+{
+public:
+
+    // test a three-dimensional image of size 10*10*10.
+    // the image is filled from start to beginning (memory-wise) with
+    // ascending numbers.
+
+    typedef typename vigra::detail::ResolveMultiband<T>::type   scalar_type;
+    typedef MultiArray <2, scalar_type> array2_type;
+    typedef MultiArray <3, T> array3_type;
+    typedef typename array3_type::view_type       array3_view_type;
+    typedef typename array3_type::actual_stride   array3_stride;
+    typedef typename array2_type::difference_type difference2_type;
+    typedef typename array3_type::difference_type difference3_type;
+    
+    difference3_type shape3;
+    array3_type array3;
+
+    MultiArrayDataTest ()
+        : shape3 (10, 10, 10), array3 (shape3, 1)
+    {
+        // initialize the array to the test data
+        for (int i = 0; i < 1000; ++i)
+            array3[i] = i;
+    }
+
+    void testHasData ()
+    {
+        should(array3.hasData());
+        array3_type empty;
+        should(!empty.hasData());
+        array3_type empty2(Shape3(2,1,0));
+        should(!empty2.hasData());
+    }
+
+    void testEquality ()
+    {
+        typedef difference3_type Shape;
+        should(array3 == array3);
+        should(array3 != array3.subarray(Shape(1,1,1), Shape(2,2,2)));
+        should(array3.subarray(Shape(0,0,0), Shape(10,1,1)) != array3.subarray(Shape(0,1,0), Shape(10,2,1)));
+
+        array3_type a(array3.shape());
+        linearSequence(a.begin(), a.end());
+        should(a == array3);
+
+        for(unsigned int k=0; k<10; ++k)
+            array3(k,0,0) += 10;
+        should(array3.subarray(Shape(0,0,0), Shape(10,1,1)) == array3.subarray(Shape(0,1,0), Shape(10,2,1)));
+    }
+    
+    // bindInner tests
+    void test_bindInner ()
+    {
+        TinyVector <int, 2> inner_indices (2, 5);
+        MultiArrayView <1, scalar_type, StridedArrayTag>
+            array = array3.bindInner(inner_indices);
+        shouldEqual ((array [TinyVector <int, 1> (0)]), 52);
+        shouldEqual ((array [TinyVector <int, 1> (1)]), 152);
+        shouldEqual ((array (0)), 52);
+        shouldEqual ((array (1)), 152);
+    }
+    
+    // bindOuter tests
+    void test_bindOuter ()
+    {
+        TinyVector <int, 2> outer_indices (2, 5);
+        MultiArrayView <1, scalar_type, array3_stride>
+            array = array3.bindOuter(outer_indices);
+        shouldEqual ((array [TinyVector <int, 1> (0)]), 520);
+        shouldEqual ((array [TinyVector <int, 1> (1)]), 521);
+        shouldEqual ((array (0)), 520);
+        shouldEqual ((array (1)), 521);
+    }
+
+    // bindAt tests
+    void test_bindAt ()
+    {
+        MultiArrayView <2, scalar_type, StridedArrayTag>
+            array = array3.bindAt (1, 4);
+        shouldEqual ((array [TinyVector <int, 2> (0, 0)]), 40);
+        shouldEqual ((array [TinyVector <int, 2> (1, 0)]), 41);
+        shouldEqual ((array [TinyVector <int, 2> (0, 1)]), 140);
+        shouldEqual ((array (0, 0)), 40);
+        shouldEqual ((array (1, 0)), 41);
+        shouldEqual ((array (0, 1)), 140);
+    }
+    
+    // bind tests
+    void test_bind ()
+    {
+        MultiArrayView <2, scalar_type, array3_stride>
+            array = array3.template bind<1>(4);
+        shouldEqual ((array [TinyVector <int, 2> (0, 0)]), 40);
+        shouldEqual ((array [TinyVector <int, 2> (1, 0)]), 41);
+        shouldEqual ((array [TinyVector <int, 2> (0, 1)]), 140);
+        shouldEqual ((array (0, 0)), 40);
+        shouldEqual ((array (1, 0)), 41);
+        shouldEqual ((array (0, 1)), 140);
+    }
+
+    void test_bind0 ()
+    {
+        MultiArrayView <2, scalar_type, StridedArrayTag>
+            array = array3.template bind <0> (4);
+        shouldEqual ((array [TinyVector <int, 2> (0, 0)]), 4);
+        shouldEqual ((array [TinyVector <int, 2> (1, 0)]), 14);
+        shouldEqual ((array [TinyVector <int, 2> (0, 1)]), 104);
+        shouldEqual ((array (0, 0)), 4);
+        shouldEqual ((array (1, 0)), 14);
+        shouldEqual ((array (0, 1)), 104);
+    }
+
+    void test_singletonDimension ()
+    {
+        MultiArrayView <4, scalar_type, UnstridedArrayTag> a0 = array3.insertSingletonDimension(0);
+        shouldEqual ((a0 [TinyVector <int, 4> (0, 4, 0, 0)]), 4);
+        shouldEqual ((a0 [TinyVector <int, 4> (0, 4, 1, 0)]), 14);
+        shouldEqual ((a0 [TinyVector <int, 4> (0, 4, 0, 1)]), 104);
+
+        MultiArrayView <4, scalar_type, array3_stride> a1 = array3.insertSingletonDimension(1);
+        shouldEqual ((a1 [TinyVector <int, 4> (4, 0, 0, 0)]), 4);
+        shouldEqual ((a1 [TinyVector <int, 4> (4, 0, 1, 0)]), 14);
+        shouldEqual ((a1 [TinyVector <int, 4> (4, 0, 0, 1)]), 104);
+
+        MultiArrayView <4, scalar_type, array3_stride> a3 = array3.insertSingletonDimension(3);
+        shouldEqual ((a3 [TinyVector <int, 4> (4, 0, 0, 0)]), 4);
+        shouldEqual ((a3 [TinyVector <int, 4> (4, 1, 0, 0)]), 14);
+        shouldEqual ((a3 [TinyVector <int, 4> (4, 0, 1, 0)]), 104);
+    }
+
+    // subarray and diagonal tests
+    void test_subarray ()
+    {
+        MultiArray<1, scalar_type> diagRef(Shape1(10));
+        linearSequence(diagRef.begin(), diagRef.end(), 0, 111);
+
+        MultiArrayView <1, scalar_type, StridedArrayTag> diag = array3.diagonal();
+        shouldEqual(diag.shape(0), 10);
+        shouldEqualSequence(diagRef.begin(), diagRef.end(), diag.begin());
+
+        typedef difference3_type Shape;
+        
+        Shape offset (1,1,1);
+        Shape size (5,5,5);
+        MultiArrayView <3, scalar_type> array = array3.subarray (offset, size);
+        shouldEqual (array [Shape (0,0,0)], 111);
+        shouldEqual (array [Shape (5,2,1)], 236);
+        shouldEqual (array (0,0,0), 111);
+        shouldEqual (array (5,2,1), 236);
+
+        shouldEqual(array.shape(), array3.subarray(offset, Shape3(-5)).shape());
+        shouldEqualSequence(array.begin(), array.end(), array3.subarray(offset, Shape3(-5)).begin());
+
+        shouldEqual(array.shape(), array3.subarray(Shape3(-9), size).shape());
+        shouldEqualSequence(array.begin(), array.end(), array3.subarray(offset, size).begin());
+
+        shouldEqual(array.shape(), array3.subarray(Shape3(-9), Shape3(-5)).shape());
+        shouldEqualSequence(array.begin(), array.end(), array3.subarray(Shape3(-9), Shape3(-5)).begin());
+        
+        // test swap
+        array3.subarray(Shape(0,0,0), Shape(10,10,1)).swapData( 
+             array3.subarray(Shape(0,0,1), Shape(10,10,2)));
+        for(int k=0; k<100; ++k)
+            shouldEqual(array3[k], k+100);
+        for(int k=100; k<200; ++k)
+            shouldEqual(array3[k], k-100);
+
+    }
+        
+    // stridearray tests
+    void test_stridearray ()
+    {
+        difference3_type stride (2, 2, 2);
+        difference3_type traverser (0, 0, 0);
+        MultiArrayView <3, scalar_type, StridedArrayTag>
+            array = array3.stridearray (stride);
+        shouldEqual (array [traverser], 0);
+        traverser [0] += 1;
+        shouldEqual (array [traverser], 2);
+        traverser [1] += 1;
+        shouldEqual (array [traverser], 22);
+        traverser [2] += 1;
+        shouldEqual (array [traverser], 222);
+        shouldEqual (array (1,1,1), 222);
+    }
+
+    void testIsUnstrided()
+    {
+        typedef difference3_type Shape;
+
+        should(array3.isUnstrided());
+        should(array3.isUnstrided(0));
+        should(array3.isUnstrided(1));
+        should(array3.isUnstrided(2));
+        should(array3.bindOuter(0).isUnstrided());
+        should(!array3.bindInner(0).isUnstrided());
+        should(!array3.bindAt(1, 0).isUnstrided());
+        should(array3.bindAt(1, 0).isUnstrided(0));
+        should(!array3.subarray(Shape(), array3.shape()-Shape(1)).isUnstrided());
+        should(!array3.subarray(Shape(), array3.shape()-Shape(1)).isUnstrided(1));
+        should(array3.subarray(Shape(), array3.shape()-Shape(1)).isUnstrided(0));
+        should(!array3.subarray(Shape(), array3.shape()-Shape(0,2,2)).isUnstrided());
+        should(array3.subarray(Shape(), array3.shape()-Shape(0,2,2)).isUnstrided(1));
+        should(array3.subarray(Shape(), array3.shape()-Shape(0,2,2)).isUnstrided(0));
+    }
+
+    void testIsStrided()
+    {
+        // for MultiArray<3, Multiband<T> >
+
+        should(!array3.isUnstrided());
+        should(array3.permuteStridesAscending().isUnstrided());
+        should(!array3.isUnstrided(0));
+        should(!array3.isUnstrided(1));
+        should(!array3.isUnstrided(2));
+        should(array3.bindInner(Shape2(0,0)).isUnstrided());
+    }
+
+    // permute and transpose tests
+    void testPermute ()
+    {
+        typedef MultiArrayView <3, scalar_type, StridedArrayTag> transposed_view;
+        array3.reshape(difference3_type(3,5,7));
+        for(int k=0; k<array3.size(); ++k)
+            array3[k] = k;
+
+        array3_type ref(difference3_type(array3.shape(2), array3.shape(0), array3.shape(1)));
+        for(int k=0; k<array3.shape(0); ++k)
+            for(int l=0; l<array3.shape(1); ++l)
+                for(int m=0; m<array3.shape(2); ++m)
+                    ref(m,k,l) = array3(k,l,m);
+
+        MultiArrayView <3, scalar_type, StridedArrayTag>
+                parray = array3.transpose (difference3_type (2, 0, 1));        
+        shouldEqual(ref.shape(), parray.shape());
+        should(ref == parray);
+        
+        if(vigra::detail::ResolveMultiband<T>::value) // array is Multiband<T>
+        {
+            shouldEqual(array3.strideOrdering(), Shape3(1,2,0));
+            
+            array3_type ref_ascending(difference3_type(array3.shape(2), array3.shape(0), array3.shape(1)));
+            for(int k=0; k<array3.shape(0); ++k)
+                for(int l=0; l<array3.shape(1); ++l)
+                    for(int m=0; m<array3.shape(2); ++m)
+                        ref_ascending(m,k,l) = array3(k,l,m);
+
+            transposed_view parray_ascending = array3.permuteStridesAscending();
+            shouldEqual(ref_ascending.shape(), parray_ascending.shape());
+            should(ref_ascending == parray_ascending);
+            
+            array3_type ref_descending(difference3_type(array3.shape(1), array3.shape(0), array3.shape(2)));
+            for(int k=0; k<array3.shape(0); ++k)
+                for(int l=0; l<array3.shape(1); ++l)
+                    for(int m=0; m<array3.shape(2); ++m)
+                        ref_descending(l,k,m) = array3(k,l,m);
+
+            transposed_view parray_descending = array3.permuteStridesDescending();
+            shouldEqual(ref_descending.shape(), parray_descending.shape());
+            should(ref_descending == parray_descending);
+        }
+        else
+        {
+            shouldEqual(array3.strideOrdering(), Shape3(0,1,2));
+            transposed_view parray_ascending = parray.permuteStridesAscending();        
+            shouldEqual(array3.shape(), parray_ascending.shape());
+            should(array3 == parray_ascending);
+
+            array3_type ref_descending(difference3_type(array3.shape(2), array3.shape(1), array3.shape(0)));
+            for(int k=0; k<array3.shape(0); ++k)
+                for(int l=0; l<array3.shape(1); ++l)
+                    for(int m=0; m<array3.shape(2); ++m)
+                        ref_descending(m,l,k) = array3(k,l,m);
+
+            MultiArrayView <3, scalar_type, StridedArrayTag>
+                    parray_descending = array3.permuteStridesDescending();        
+            shouldEqual(ref_descending.shape(), parray_descending.shape());
+            should(ref_descending == parray_descending);
+        }
+
+        array2_type ref2(difference2_type(array3.shape(1), array3.shape(0)));
+        for(int k=0; k<array3.shape(0); ++k)
+            for(int l=0; l<array3.shape(1); ++l)
+                ref2(l, k) = array3(k, l, 0);
+
+        MultiArrayView <2, scalar_type, StridedArrayTag>
+                array2 = array3.bindOuter(0).transpose ();
+        shouldEqual(ref2.shape(), array2.shape());
+        should(ref2 == array2);
+
+        try {
+            array3.transpose (difference3_type (2, 0, 0));   
+            failTest("no exception thrown");
+        }
+        catch(vigra::ContractViolation & c)
+        {
+            std::string expected("\nPrecondition violation!\nMultiArrayView::transpose(): every dimension must occur exactly once");
+            std::string message(c.what());
+            should(0 == expected.compare(message.substr(0,expected.size())));
+        }
+    }
+
+    void testMethods ()
+    {
+        shouldEqual(array3.squaredNorm(), 332833500);
+        
+        shouldEqual(array3.norm(), std::sqrt(332833500.0));
+        shouldEqual(array3.norm(0), 999.0);
+        shouldEqual(array3.norm(1), 499500.0);
+        shouldEqualTolerance(array3.norm(2, false), std::sqrt(332833500.0), 1e-14);
+        
+        difference3_type first(0,0,0), last(1,1,1);
+        shouldEqual(array3.subarray(first, last).norm(), 0.0);
+        shouldEqual(array3.subarray(first, last).norm(0), 0.0);
+        shouldEqual(array3.subarray(first, last).norm(1), 0.0);
+        shouldEqual(array3.subarray(first, last).norm(2, false), 0.0);
+
+        shouldEqual(array3.squaredNorm(), squaredNorm(array3));
+        shouldEqual(array3.norm(), vigra::norm(array3));
+
+        should(array3.any());
+        should(!array3.subarray(first, last).any());
+        should(!array3.all());
+        should(array3.subarray(last, array3.shape()).all());
+
+        shouldEqual(array3.template sum<int>(), 499500);
+        shouldEqual(array3.subarray(Shape3(1,1,1),Shape3(3,3,2)).template product<int>(), 183521184);
+
+        Shape3 reducedShape(1, 1, array3.shape(2));
+        array3_type reducedSums(reducedShape);
+        array3.sum(reducedSums);
+        int res = 4950;
+        for(int k=0; k<reducedShape[2]; ++k, res += 10000)
+            shouldEqual(reducedSums(0,0,k), res);
+
+        scalar_type minimum, maximum;
+        array3.minmax(&minimum, &maximum);
+        shouldEqual(minimum, 0);
+        shouldEqual(maximum, array3.size()-1);
+
+        double mean, variance;
+        array3.meanVariance(&mean, &variance);
+        shouldEqual(mean, 499.5);
+        shouldEqual(variance, 83333.25);
+    }
+    
+    void testScanOrderAccess()
+    {
+        shouldEqual(array3.size(), 1000);
+        for(int k=0; k< array3.size(); ++k)
+        {
+            shouldEqual(array3[k], k);
+            shouldEqual(array3[array3.scanOrderIndexToCoordinate(k)], k);
+            shouldEqual(array3.coordinateToScanOrderIndex(array3.scanOrderIndexToCoordinate(k)), k);
+        }
+            
+        MultiArrayView <2, scalar_type, StridedArrayTag> array = array3.bindInner(2);
+        shouldEqual(array.size(), 100);
+        for(int k=0; k< array.size(); ++k)
+            shouldEqual(array[k], 10*k+2);
+            
+        MultiArrayView <2, scalar_type, array3_stride>
+            subarray = array3.bindOuter(2).subarray(Shape2(1,0), Shape2(10,9));
+        shouldEqual(subarray.size(), 81);
+        for(int k=0, l=200; k< subarray.size(); ++k, ++l)
+        {
+            if(k%9 == 0)
+                ++l;
+            shouldEqual(subarray[k], l);
+        }
+    }
+    
+    void testAssignmentAndReset()
+    {
+        typedef Shape3 Shape;
+        typename array3_type::view_type array;
+        array = array3;
+        should(array3 == array);
+        try {
+            array = array3.subarray(Shape(0,0,0), Shape(10,1,1));
+            failTest("no exception thrown");
+        }
+        catch(vigra::ContractViolation & c)
+        {
+            std::string expected("\nPrecondition violation!\nMultiArrayView::operator=(MultiArrayView const &): shape mismatch");
+            std::string message(c.what());
+            should(0 == expected.compare(message.substr(0,expected.size())));
+        }
+        MultiArrayView <3, scalar_type, array3_stride> subarray = array3.subarray(Shape(0,0,0), Shape(10,1,1));
+        subarray = array3.subarray(Shape(0,1,0), Shape(10,2,1)); // should overwrite the data
+        for(unsigned int k=0; k<10; ++k)
+            shouldEqual(array3(k,0,0), array3(k,1,0));
+        subarray += array3.subarray(Shape(0,1,0), Shape(10,2,1)); // should overwrite the data
+        for(unsigned int k=0; k<10; ++k)
+            shouldEqual(array3(k,0,0), 2.0*array3(k,1,0));
+        subarray -= array3.subarray(Shape(0,1,0), Shape(10,2,1)); // should overwrite the data
+        for(unsigned int k=0; k<10; ++k)
+            shouldEqual(array3(k,0,0), array3(k,1,0));
+        subarray *= array3.subarray(Shape(0,1,0), Shape(10,2,1)); // should overwrite the data
+        for(unsigned int k=0; k<10; ++k)
+            shouldEqual(array3(k,0,0), sq(array3(k,1,0)));
+        subarray /= array3.subarray(Shape(0,1,0), Shape(10,2,1)); // should overwrite the data
+        for(unsigned int k=0; k<10; ++k)
+            shouldEqual(array3(k,0,0), array3(k,1,0));
+            
+        subarray += 1; // should overwrite the data
+        for(unsigned int k=0; k<10; ++k)
+            shouldEqual(array3(k,0,0), array3(k,1,0) + 1);
+        subarray -= 2; // should overwrite the data
+        for(unsigned int k=0; k<10; ++k)
+            shouldEqual(array3(k,0,0), array3(k,1,0) - 1);
+        subarray *= 2; // should overwrite the data
+        for(unsigned int k=0; k<10; ++k)
+            shouldEqual(array3(k,0,0), 2*(array3(k,1,0) - 1));
+        subarray /= 2; // should overwrite the data
+        for(unsigned int k=0; k<10; ++k)
+            shouldEqual(array3(k,0,0), array3(k,1,0) - 1);
+
+        // test assignment from UInt8 => double (reproduces compiler crash in VisualStudio 2010)
+        MultiArray<2, UInt8> d1(Shape2(50, 100));
+        MultiArray<2, double> d2(d1.shape());
+        d2 = d1;
+    }
+};
+
+
+class MultiArrayTest
+{
+public:
+    typedef unsigned char scalar_type;
+    typedef MultiArray <1, scalar_type> array1_t;
+    typedef array1_t::difference_type shape1_t;
+    typedef MultiArray <3, scalar_type> array3_t;
+    typedef array3_t::difference_type shape3_t;
+    typedef array3_t::traverser traverser3_t;
+    typedef traverser3_t::next_type traverser2_t;
+    typedef traverser2_t::next_type traverser1_t;
+    typedef MultiArrayView<3, scalar_type> array_view3_t;
+    typedef array_view3_t::iterator iterator3_t;
+    
+    shape3_t s;
+    array3_t a3;
+    
+    MultiArrayTest()
+    : s(shape3_t(2,3,5)),
+      a3(s, 1)
+    {
+    }
+    
+    void test_default_ctor ()
+    {
+        array1_t a;
+        shouldEqual (a.shape (0), 0);
+    }
+
+    void test_first_ctor ()
+    {
+        using namespace multi_math;
+        array1_t a (shape1_t(2));
+        should (a.shape (0) == 2);
+        should (a.size() == 2);
+        should(all(a == 0));
+
+        array1_t b(4);
+        should (b.shape (0) == 4);
+        should (b.size() == 4);
+        should(all(b == 0));
+
+        typedef MultiArray <2, unsigned char> array2_t;
+        array2_t a2 (Shape2(2, 4));
+        should (a2.shape (0) == 2);
+        should (a2.shape (1) == 4);
+        should (a2.width() == 2);
+        should (a2.height() == 4);
+        should (a2.size() == 8);
+        should(all(a2 == 0));
+
+        array2_t b2(5,3);
+        should (b2.shape (0) == 5);
+        should (b2.shape (1) == 3);
+        should (b2.width() == 5);
+        should (b2.height() == 3);
+        should (b2.size() == 15);
+        should(all(b2 == 0));
+    }
+
+    void test_second_ctor ()
+    {
+        array1_t a (shape1_t(2), 1);
+        shouldEqual (a.shape (0), 2);
+        shouldEqual (a(0), 1);
+        shouldEqual (a(1), 1);
+        
+        a.init(2);
+        shouldEqual(a(0), 2);
+        shouldEqual(a(1), 2);
+        should(a == array1_t(shape1_t(2), 4).init(2));
+    }
+
+    void test_assignment ()
+    {
+        array1_t a (shape1_t(2), 1);
+        array1_t b;
+        b = a;
+        shouldEqual (b.shape (0), 2);
+    }
+
+    void test_copy_construction ()
+    {
+        array1_t a (shape1_t(2), 1);
+        array1_t b (a);
+        shouldEqual (b.shape (0), 2);
+    }
+
+    void testShape()
+    {
+        shouldEqual(a3.shape(0), 2);
+        shouldEqual(a3.shape(1), 3);
+        shouldEqual(a3.shape(2), 5);
+        should(a3.isInside(shape3_t(1,2,3)));
+        should(!a3.isInside(shape3_t(1,23,3)));
+    }
+
+    void test_iterator ()
+    {
+        // test scan-order navigation
+        array_view3_t av = a3;
+        iterator3_t i1 = av.begin();
+        iterator3_t i2 = av.begin();
+        iterator3_t iend = av.end();
+        iterator3_t i3;
+        MultiCoordinateIterator<3> c(av.shape()),
+                                   cend = c.getEndIterator();
+
+        should(i1.isValid() && !i1.atEnd());
+        should(!iend.isValid() && iend.atEnd());
+        should(iend.getEndIterator() == iend);
+        
+        shouldEqual(i1.point(), *c);
+        shouldEqual((i1+0).point(), *(c+0));
+        shouldEqual((i1+1).point(), *(c+1));
+        shouldEqual((i1+2).point(), *(c+2));
+        shouldEqual((i1+3).point(), *(c+3));
+        shouldEqual((i1+6).point(), *(c+6));
+        shouldEqual((i1+7).point(), *(c+7));
+        shouldEqual((i1+9).point(), *(c+9));
+
+        shouldEqual((i1+0).point(), c[0]);
+        shouldEqual((i1+1).point(), c[1]);
+        shouldEqual((i1+2).point(), c[2]);
+        shouldEqual((i1+3).point(), c[3]);
+        shouldEqual((i1+6).point(), c[6]);
+        shouldEqual((i1+7).point(), c[7]);
+        shouldEqual((i1+9).point(), c[9]);
+
+        shouldEqual((iend-1).point(), *(cend-1));
+        shouldEqual((iend-2).point(), *(cend-2));
+        shouldEqual((iend-3).point(), *(cend-3));
+        shouldEqual((iend-7).point(), *(cend-7));
+        shouldEqual((iend-8).point(), *(cend-8));
+        shouldEqual((iend-10).point(), *(cend-10));
+
+        shouldEqual(&i1[0], &a3(0,0,0));
+        shouldEqual(&i1[1], &a3(1,0,0));
+        shouldEqual(&i1[2], &a3(0,1,0));
+        shouldEqual(&i1[3], &a3(1,1,0));
+        shouldEqual(&i1[6], &a3(0,0,1));
+        shouldEqual(&i1[7], &a3(1,0,1));
+        shouldEqual(&i1[9], &a3(1,1,1));
+
+        shouldEqual(&*(i1+0), &a3(0,0,0));
+        shouldEqual(&*(i1+1), &a3(1,0,0));
+        shouldEqual(&*(i1+2), &a3(0,1,0));
+        shouldEqual(&*(i1+3), &a3(1,1,0));
+        shouldEqual(&*(i1+6), &a3(0,0,1));
+        shouldEqual(&*(i1+7), &a3(1,0,1));
+        shouldEqual(&*(i1+9), &a3(1,1,1));
+
+        shouldEqual(&*(i1+shape3_t(0,0,0)), &a3(0,0,0));
+        shouldEqual(&*(i1+shape3_t(1,0,0)), &a3(1,0,0));
+        shouldEqual(&*(i1+shape3_t(0,1,0)), &a3(0,1,0));
+        shouldEqual(&*(i1+shape3_t(1,1,0)), &a3(1,1,0));
+        shouldEqual(&*(i1+shape3_t(0,0,1)), &a3(0,0,1));
+        shouldEqual(&*(i1+shape3_t(1,0,1)), &a3(1,0,1));
+        shouldEqual(&*(i1+shape3_t(1,1,1)), &a3(1,1,1));
+
+        shouldEqual(&*(iend-1), &a3(1,2,4));
+        shouldEqual(&*(iend-2), &a3(0,2,4));
+        shouldEqual(&*(iend-3), &a3(1,1,4));
+        shouldEqual(&*(iend-7), &a3(1,2,3));
+        shouldEqual(&*(iend-8), &a3(0,2,3));
+        shouldEqual(&*(iend-10), &a3(0,1,3));
+        
+        i3 = iend;
+        --i3;
+        should(i3.isValid() && !i3.atEnd());
+        should(i3.getEndIterator() == iend);
+        shouldEqual(&*iend, &*(i3+1));
+        shouldEqual(&*i3, &a3(1,2,4));
+        --i3;
+        should(i3.isValid() && !i3.atEnd());
+        should(i3.getEndIterator() == iend);
+        shouldEqual(&*i3, &a3(0,2,4));
+        --i3;
+        should(i3.isValid() && !i3.atEnd());
+        should(i3.getEndIterator() == iend);
+        shouldEqual(&*i3, &a3(1,1,4));
+        i3 -= 4;
+        should(i3.isValid() && !i3.atEnd());
+        should(i3.getEndIterator() == iend);
+        shouldEqual(&*i3, &a3(1,2,3));
+        --i3;
+        should(i3.isValid() && !i3.atEnd());
+        should(i3.getEndIterator() == iend);
+        shouldEqual(&*i3, &a3(0,2,3));
+        --i3;
+        --i3;
+        should(i3.isValid() && !i3.atEnd());
+        should(i3.getEndIterator() == iend);
+        shouldEqual(&*i3, &a3(0,1,3));
+
+        i3 = iend-1;
+        shouldEqual(&*(i3-shape3_t(0,0,0)), &a3(1,2,4));
+        shouldEqual(&*(i3-shape3_t(1,0,0)), &a3(0,2,4));
+        shouldEqual(&*(i3-shape3_t(0,1,0)), &a3(1,1,4));
+        shouldEqual(&*(i3-shape3_t(1,1,0)), &a3(0,1,4));
+        shouldEqual(&*(i3-shape3_t(0,0,1)), &a3(1,2,3));
+        shouldEqual(&*(i3-shape3_t(1,0,1)), &a3(0,2,3));
+        shouldEqual(&*(i3-shape3_t(1,1,1)), &a3(0,1,3));
+
+        shouldEqual(&iend[-1], &a3(1,2,4));
+        shouldEqual(&iend[-2], &a3(0,2,4));
+        shouldEqual(&iend[-3], &a3(1,1,4));
+        shouldEqual(&iend[-7], &a3(1,2,3));
+        shouldEqual(&iend[-8], &a3(0,2,3));
+        shouldEqual(&iend[-10], &a3(0,1,3));
+
+        i3 = i1;
+        i3 += shape3_t(0,0,1);
+        shouldEqual(i3.index(), 6);
+        shouldEqual(i3.point(), shape3_t(0,0,1));
+        i3 -= shape3_t(0,0,1);
+        shouldEqual(i3.index(), 0);
+        shouldEqual(i3.point(), shape3_t(0,0,0));
+        should(i3 == i1);
+
+        unsigned int count = 0;
+        shape3_t p;
+
+        // iterate over the third dimension
+        for (p[2]=0; p[2] != s[2]; ++p[2]) 
+        {
+            for (p[1]=0; p[1] != s[1]; ++p[1]) 
+            {
+                for (p[0]=0; p[0] != s[0]; ++p[0], ++i1, ++c, i2 += 1, ++count)
+                {
+                    shouldEqual(&*i1, &a3[p]);
+                    shouldEqual(&*i2, &a3[p]);
+                    shouldEqual(i1.operator->(), &a3[p]);
+                    shouldEqual(i2.operator->(), &a3[p]);
+                    shouldEqual(*c, p);
+                    shouldEqual(i1.point(), p);
+                    shouldEqual(i2.point(), p);
+                    shouldEqual(i1.index(), count);
+                    shouldEqual(i2.index(), count);
+
+                    should(i1 != iend);
+                    should(!(i1 == iend));
+                    should(i1 < iend);
+                    should(i1 <= iend);
+                    should(!(i1 > iend));
+                    should(!(i1 >= iend));
+
+                    shouldEqual(iend - i1, av.size() - count);
+
+                    bool atBorder = p[0] == 0 || p[0] == s[0]-1 || p[1] == 0 || p[1] == s[1]-1 ||
+                                    p[2] == 0 || p[2] == s[2]-1;
+                    if(!atBorder)
+                    {
+                        should(!i1.atBorder());
+                        should(!i2.atBorder());
+                    }
+                    else
+                    {
+                        should(i1.atBorder());
+                        should(i2.atBorder());
+                    }
+                }
+            }
+        }
+
+        should(c == cend);
+        should(i1 == iend);
+        should(!(i1 != iend));
+        should(!(i1 < iend));
+        should(i1 <= iend);
+        should(!(i1 > iend));
+        should(i1 >= iend);
+
+        should(i2 == iend);
+        should(!(i2 != iend));
+        should(!(i2 < iend));
+        should(i2 <= iend);
+        should(!(i2 > iend));
+        should(i2 >= iend);
+
+        shouldEqual(iend - i1, 0);
+        shouldEqual(iend - i2, 0);
+        shouldEqual (count, av.size());
+
+        --i1;
+        i2 -= 1;
+        shouldEqual(&*i1, &a3(1,2,4));
+        shouldEqual(&*i2, &a3(1,2,4));
+    }
+
+    void test_const_iterator()
+    {
+        typedef array_view3_t::const_iterator iterator;
+
+        // test const scan-order navigation
+        array_view3_t av = a3;
+        iterator i1 = const_cast<array_view3_t const &>(av).begin();
+        iterator i2 = const_cast<array_view3_t const &>(av).begin();
+        iterator iend = const_cast<array_view3_t const &>(av).end();
+
+        shouldEqual(&i1[0], &a3(0,0,0));
+        shouldEqual(&i1[1], &a3(1,0,0));
+        shouldEqual(&i1[2], &a3(0,1,0));
+        shouldEqual(&i1[3], &a3(1,1,0));
+        shouldEqual(&i1[6], &a3(0,0,1));
+        shouldEqual(&i1[7], &a3(1,0,1));
+        shouldEqual(&i1[9], &a3(1,1,1));
+
+        shouldEqual(&*(i1+0), &a3(0,0,0));
+        shouldEqual(&*(i1+1), &a3(1,0,0));
+        shouldEqual(&*(i1+2), &a3(0,1,0));
+        shouldEqual(&*(i1+3), &a3(1,1,0));
+        shouldEqual(&*(i1+6), &a3(0,0,1));
+        shouldEqual(&*(i1+7), &a3(1,0,1));
+        shouldEqual(&*(i1+9), &a3(1,1,1));
+
+        shouldEqual(&*(iend-1), &a3(1,2,4));
+        shouldEqual(&*(iend-2), &a3(0,2,4));
+        shouldEqual(&*(iend-3), &a3(1,1,4));
+        shouldEqual(&*(iend-7), &a3(1,2,3));
+        shouldEqual(&*(iend-8), &a3(0,2,3));
+        shouldEqual(&*(iend-10), &a3(0,1,3));
+
+        shouldEqual(&iend[-1], &a3(1,2,4));
+        shouldEqual(&iend[-2], &a3(0,2,4));
+        shouldEqual(&iend[-3], &a3(1,1,4));
+        shouldEqual(&iend[-7], &a3(1,2,3));
+        shouldEqual(&iend[-8], &a3(0,2,3));
+        shouldEqual(&iend[-10], &a3(0,1,3));
+
+        unsigned int count = 0;
+        shape3_t p;
+
+        // iterate over the third dimension
+        for (p[2]=0; p[2] != s[2]; ++p[2]) 
+        {
+            for (p[1]=0; p[1] != s[1]; ++p[1]) 
+            {
+                for (p[0]=0; p[0] != s[0]; ++p[0], ++i1, i2 += 1, ++count)
+                {
+                    shouldEqual(&*i1, &a3[p]);
+                    shouldEqual(&*i2, &a3[p]);
+                    shouldEqual(i1.operator->(), &a3[p]);
+                    shouldEqual(i2.operator->(), &a3[p]);
+                    shouldEqual(i1.point(), p);
+                    shouldEqual(i2.point(), p);
+                    shouldEqual(i1.index(), count);
+                    shouldEqual(i2.index(), count);
+
+                    should(i1 != iend);
+                    should(!(i1 == iend));
+                    should(i1 < iend);
+                    should(i1 <= iend);
+                    should(!(i1 > iend));
+                    should(!(i1 >= iend));
+
+                    shouldEqual(iend - i1, av.size() - count);
+
+                    bool atBorder = p[0] == 0 || p[0] == s[0]-1 || p[1] == 0 || p[1] == s[1]-1 ||
+                                    p[2] == 0 || p[2] == s[2]-1;
+                    if(!atBorder)
+                    {
+                        should(!i1.atBorder());
+                        should(!i2.atBorder());
+                    }
+                    else
+                    {
+                        should(i1.atBorder());
+                        should(i2.atBorder());
+                    }
+                }
+            }
+        }
+
+        should(i1 == iend);
+        should(!(i1 != iend));
+        should(!(i1 < iend));
+        should(i1 <= iend);
+        should(!(i1 > iend));
+        should(i1 >= iend);
+
+        should(i2 == iend);
+        should(!(i2 != iend));
+        should(!(i2 < iend));
+        should(i2 <= iend);
+        should(!(i2 > iend));
+        should(i2 >= iend);
+
+        shouldEqual(iend - i1, 0);
+        shouldEqual(iend - i2, 0);
+        shouldEqual (count, av.size());
+
+        --i1;
+        i2 -= 1;
+        shouldEqual(&*i1, &a3(1,2,4));
+        shouldEqual(&*i2, &a3(1,2,4));
+    }
+
+    void test_coupled_iterator ()
+    {
+        // test scan-order navigation
+        typedef CoupledIteratorType<3, scalar_type>::type Iterator;
+        Iterator i1 = createCoupledIterator(a3);
+        Iterator iend = i1.getEndIterator();
+        Iterator i2 = i1;
+        Iterator i3;
+
+        shouldEqual(&(*(*i1)), &a3(0,0,0));
+        shouldEqual(&get<1>(i1[0]), &a3(0,0,0));
+        shouldEqual(&get<1>(i1[1]), &a3(1,0,0));
+        shouldEqual(&get<1>(i1[2]), &a3(0,1,0));
+        shouldEqual(&get<1>(i1[3]), &a3(1,1,0));
+        shouldEqual(&get<1>(i1[6]), &a3(0,0,1));
+        shouldEqual(&get<1>(i1[7]), &a3(1,0,1));
+        shouldEqual(&get<1>(i1[9]), &a3(1,1,1));
+
+        shouldEqual(&get<1>(*(i1+0)), &a3(0,0,0));
+        shouldEqual(&get<1>(*(i1+1)), &a3(1,0,0));
+        shouldEqual(&get<1>(*(i1+2)), &a3(0,1,0));
+        shouldEqual(&get<1>(*(i1+3)), &a3(1,1,0));
+        shouldEqual(&get<1>(*(i1+6)), &a3(0,0,1));
+        shouldEqual(&get<1>(*(i1+7)), &a3(1,0,1));
+        shouldEqual(&get<1>(*(i1+9)), &a3(1,1,1));
+
+        shouldEqual(&get<1>(*(i1+shape3_t(0,0,0))), &a3(0,0,0));
+        shouldEqual(&get<1>(*(i1+shape3_t(1,0,0))), &a3(1,0,0));
+        shouldEqual(&get<1>(*(i1+shape3_t(0,1,0))), &a3(0,1,0));
+        shouldEqual(&get<1>(*(i1+shape3_t(1,1,0))), &a3(1,1,0));
+        shouldEqual(&get<1>(*(i1+shape3_t(0,0,1))), &a3(0,0,1));
+        shouldEqual(&get<1>(*(i1+shape3_t(1,0,1))), &a3(1,0,1));
+        shouldEqual(&get<1>(*(i1+shape3_t(1,1,1))), &a3(1,1,1));
+
+        shouldEqual(&get<1>(*(iend-1)), &a3(1,2,4));
+        shouldEqual(&get<1>(*(iend-2)), &a3(0,2,4));
+        shouldEqual(&get<1>(*(iend-3)), &a3(1,1,4));
+        shouldEqual(&get<1>(*(iend-7)), &a3(1,2,3));
+        shouldEqual(&get<1>(*(iend-8)), &a3(0,2,3));
+        shouldEqual(&get<1>(*(iend-10)), &a3(0,1,3));
+
+        i3 = iend-1;
+        shouldEqual(&get<1>(*(i3-shape3_t(0,0,0))), &a3(1,2,4));
+        shouldEqual(&get<1>(*(i3-shape3_t(1,0,0))), &a3(0,2,4));
+        shouldEqual(&get<1>(*(i3-shape3_t(0,1,0))), &a3(1,1,4));
+        shouldEqual(&get<1>(*(i3-shape3_t(1,1,0))), &a3(0,1,4));
+        shouldEqual(&get<1>(*(i3-shape3_t(0,0,1))), &a3(1,2,3));
+        shouldEqual(&get<1>(*(i3-shape3_t(1,0,1))), &a3(0,2,3));
+        shouldEqual(&get<1>(*(i3-shape3_t(1,1,1))), &a3(0,1,3));
+
+        shouldEqual(&get<1>(iend[-1]), &a3(1,2,4));
+        shouldEqual(&get<1>(iend[-2]), &a3(0,2,4));
+        shouldEqual(&get<1>(iend[-3]), &a3(1,1,4));
+        shouldEqual(&get<1>(iend[-7]), &a3(1,2,3));
+        shouldEqual(&get<1>(iend[-8]), &a3(0,2,3));
+        shouldEqual(&get<1>(iend[-10]), &a3(0,1,3));
+
+        i3 = i1;
+        i3 += shape3_t(0,0,1);
+        shouldEqual(i3.scanOrderIndex(), 6);
+        shouldEqual(i3.point(), shape3_t(0,0,1));
+        i3 -= shape3_t(0,0,1);
+        shouldEqual(i3.scanOrderIndex(), 0);
+        shouldEqual(i3.point(), shape3_t(0,0,0));
+        should(i3 == i1);
+
+        unsigned int count = 0;
+        shape3_t p;
+
+        // iterate over the third dimension
+        for (p[2]=0; p[2] != s[2]; ++p[2]) 
+        {
+            for (p[1]=0; p[1] != s[1]; ++p[1]) 
+            {
+                for (p[0]=0; p[0] != s[0]; ++p[0], ++i1, i2 += 1, ++count)
+                {
+                    shouldEqual(&get<1>(*i1), &a3[p]);
+                    shouldEqual(&get<1>(*i2), &a3[p]);
+                    shouldEqual(&i1.get<1>(), &a3[p]);
+                    shouldEqual(&i2.get<1>(), &a3[p]);
+                    //shouldEqual(i1.operator->(), &a3[p]);
+                    //shouldEqual(i2.operator->(), &a3[p]);
+                    shouldEqual(i1.point(), p);
+                    shouldEqual(i2.point(), p);
+                    shouldEqual(i1.get<0>(), p);
+                    shouldEqual(i2.get<0>(), p);
+                    shouldEqual(i1.scanOrderIndex(), count);
+                    shouldEqual(i2.scanOrderIndex(), count);
+
+                    should(i1 != iend);
+                    should(!(i1 == iend));
+                    should(i1 < iend);
+                    should(i1 <= iend);
+                    should(!(i1 > iend));
+                    should(!(i1 >= iend));
+
+                    shouldEqual(iend - i1, a3.size() - count);
+
+                    bool atBorder = p[0] == 0 || p[0] == s[0]-1 || p[1] == 0 || p[1] == s[1]-1 ||
+                                    p[2] == 0 || p[2] == s[2]-1;
+                    if(!atBorder)
+                    {
+                        should(!i1.atBorder());
+                        should(!i2.atBorder());
+                    }
+                    else
+                    {
+                        should(i1.atBorder());
+                        should(i2.atBorder());
+                    }
+                }
+            }
+        }
+
+        should(i1 == iend);
+        should(!(i1 != iend));
+        should(!(i1 < iend));
+        should(i1 <= iend);
+        should(!(i1 > iend));
+        should(i1 >= iend);
+
+        should(i2 == iend);
+        should(!(i2 != iend));
+        should(!(i2 < iend));
+        should(i2 <= iend);
+        should(!(i2 > iend));
+        should(i2 >= iend);
+
+        shouldEqual(iend - i1, 0);
+        shouldEqual(iend - i2, 0);
+        shouldEqual (count, a3.size());
+
+        --i1;
+        i2 -= 1;
+        shouldEqual(&get<1>(*i1), &a3(1,2,4));
+        shouldEqual(&get<1>(*i2), &a3(1,2,4));
+
+        int idata[] = { 10, 11, 12, 13 };
+        double ddata[] = { 20.0, 21.0, 22.0, 23.0 };
+
+        typedef CoupledIteratorType<1>::type Iterator0;
+        typedef CoupledIteratorType<1, int, double>::type Iterator1;
+        MultiArrayView<1, int> vi(Shape1(4), idata);
+        MultiArrayView<1, double> vd(Shape1(4), ddata);
+
+        Iterator0 i0 = createCoupledIterator(Shape1(4));
+        Iterator1 it = createCoupledIterator(vi, vd),
+                  end = it.getEndIterator();
+
+        count = 0;
+        for(; it < end; ++it, ++i0, ++count)
+        {
+            shouldEqual(i0.get<0>(), Shape1(count));
+            shouldEqual(it.get<0>(), Shape1(count));
+            shouldEqual(it.get<1>(), count+10);
+            shouldEqual(it.get<2>(), count+20.0);
+        }
+        shouldEqual(count, 4);
+
+        // test multiband
+        MultiArrayView<3, scalar_type, StridedArrayTag> at = a3.transpose();
+
+        typedef CoupledIteratorType<3, Multiband<scalar_type>, scalar_type, scalar_type>::type MultibandIterator;
+        MultibandIterator im = createCoupledIterator(MultiArrayView<3, Multiband<scalar_type>, StridedArrayTag>(at),
+                                                     at.bindOuter(0), at.bindOuter(1));
+        MultibandIterator imend = im.getEndIterator();
+        count = 0;
+        for(; im < imend; ++im, ++count)
+        {
+            shouldEqual(im.get<1>().shape(), Shape1(2));
+            shouldEqual(&(im.get<1>()[0]), &(im.get<2>()));
+            shouldEqual(&(im.get<1>()[1]), &(im.get<3>()));
+        }
+        shouldEqual(count, 15);
+    }
+
+    void test_traverser ()
+    {
+        // test hierarchical navigation and 
+        traverser3_t i3_f = a3.traverser_begin ();
+        traverser3_t i3_l = a3.traverser_end ();
+        array3_t::iterator seqi = a3.begin();
+
+        int countx = 0, county = 0, countz = 0;
+
+        // iterate over the third dimension
+        for (int z=0; i3_f != i3_l; ++i3_f, ++z) 
+        {
+            traverser2_t i2_f = i3_f.begin ();
+            traverser2_t i2_l = i3_f.end ();
+            // iterate over the second dimension
+            for (int y=0; i2_f != i2_l; ++i2_f, ++y) 
+            {
+                traverser1_t i1_f = i2_f.begin ();
+                traverser1_t i1_l = i2_f.end ();
+                // iterate over the first dimension
+                for (int x=0; i1_f != i1_l; ++i1_f, ++x, ++seqi)
+                {
+                    ++countx;
+                    shouldEqual(&*i1_f, &a3(x,y,z));
+                    shouldEqual(&*seqi, &a3(x,y,z));
+                }
+                ++county;
+            }
+            ++countz;
+        }
+
+        shouldEqual (countx, 30);
+        shouldEqual (county, 15);
+        shouldEqual (countz, 5);
+        shouldEqual (seqi, a3.end());
+        
+        // test direct navigation
+        traverser3_t i3 = a3.traverser_begin();
+        shouldEqual(&*i3, &a3[shape3_t(0,0,0)]);
+
+        i3.dim<2>()++;
+        i3.dim<1>()++;
+        i3.dim<0>()++;        
+        shouldEqual(&*i3, &a3[shape3_t(1,1,1)]);
+
+        i3.dim<2>()+= 3;
+        i3.dim<1>()+= 2;
+        i3.dim<0>()+= 1;        
+        shouldEqual(&*i3, &a3[shape3_t(2,3,4)]);
+        shouldEqual(&i3[shape3_t(-2,-3,-4)], &a3[shape3_t(0,0,0)]);
+        shouldEqual(&*(i3-shape3_t(2,3,4)), &a3[shape3_t(0,0,0)]);
+
+        i3.dim<2>()--;
+        i3.dim<1>()--;
+        i3.dim<0>()--;        
+        shouldEqual(&*i3, &a3[shape3_t(1,2,3)]);
+
+        i3.dim<2>()-= 3;
+        i3.dim<1>()-= 2;
+        i3.dim<0>()-= 1;        
+        shouldEqual(&*i3, &a3[shape3_t(0,0,0)]);
+
+        shouldEqual(&i3[shape3_t(2,3,4)], &a3[shape3_t(2,3,4)]);
+        shouldEqual(&*(i3+shape3_t(2,3,4)), &i3[shape3_t(2,3,4)]);
+    }
+
+    void test_const_traverser ()
+    {
+        typedef array3_t::const_traverser traverser;
+
+        // test hierarchical navigation
+        traverser i3_f = const_cast<array3_t const &>(a3).traverser_begin ();
+        traverser i3_l = const_cast<array3_t const &>(a3).traverser_end ();
+
+        unsigned int countx = 0, county = 0, countz = 0;
+
+        // iterate over the third dimension
+        for (; i3_f != i3_l; ++i3_f) {
+            traverser::next_type i2_f = i3_f.begin ();
+            traverser::next_type i2_l = i3_f.end ();
+            // iterate over the second dimension
+            for (; i2_f != i2_l; ++i2_f) {
+                traverser::next_type::next_type i1_f = i2_f.begin ();
+                traverser::next_type::next_type i1_l = i2_f.end ();
+                // iterate over the first dimension
+                for (; i1_f != i1_l; ++i1_f)
+                    ++countx;
+                ++county;
+            }
+            ++countz;
+        }
+
+        shouldEqual (countx, 30u);
+        shouldEqual (county, 15u);
+        shouldEqual (countz, 5u);
+        
+        // test direct navigation
+        traverser i3 = const_cast<array3_t const &>(a3).traverser_begin();
+        shouldEqual(&*i3, &a3[shape3_t(0,0,0)]);
+
+        i3.dim<2>()++;
+        i3.dim<1>()++;
+        i3.dim<0>()++;        
+        shouldEqual(&*i3, &a3[shape3_t(1,1,1)]);
+
+        i3.dim<2>()+= 3;
+        i3.dim<1>()+= 2;
+        i3.dim<0>()+= 1;        
+        shouldEqual(&*i3, &a3[shape3_t(2,3,4)]);
+        shouldEqual(&i3[shape3_t(-2,-3,-4)], &a3[shape3_t(0,0,0)]);
+        shouldEqual(&*(i3-shape3_t(2,3,4)), &a3[shape3_t(0,0,0)]);
+
+        i3.dim<2>()--;
+        i3.dim<1>()--;
+        i3.dim<0>()--;        
+        shouldEqual(&*i3, &a3[shape3_t(1,2,3)]);
+
+        i3.dim<2>()-= 3;
+        i3.dim<1>()-= 2;
+        i3.dim<0>()-= 1;        
+        shouldEqual(&*i3, &a3[shape3_t(0,0,0)]);
+
+        shouldEqual(&i3[shape3_t(2,3,4)], &a3[shape3_t(2,3,4)]);
+        shouldEqual(&*(i3+shape3_t(2,3,4)), &i3[shape3_t(2,3,4)]);
+    }
+
+    void test_bindOuter ()
+    {
+        MultiArrayView <2, unsigned char> ba = a3.bindOuter(TinyVector<int, 1>(2));
+
+        shouldEqual (ba.shape (0), 2);
+        shouldEqual (ba.shape (1), 3);
+    }
+
+
+    void test_bindInner ()
+    {
+        MultiArrayView <2, unsigned char, StridedArrayTag>
+            fa = a3.bindInner(TinyVector <int, 1>(1));
+
+        shouldEqual (fa.shape (0), 3);
+        shouldEqual (fa.shape (1), 5);
+    }
+
+    void test_bindInnerAll ()
+    {
+        MultiArrayView <0, unsigned char, StridedArrayTag>
+            fa = a3.bindInner(shape3_t(1,1,1));
+
+        shouldEqual (fa.shape (0), 1);
+        shouldEqual (fa[shape1_t(shape1_t::value_type(0))], 1.0);
+    }
+
+    void test_bindAt ()
+    {
+        MultiArrayView <2, unsigned char, StridedArrayTag>
+            fa = a3.bindAt (1, 1);
+
+        shouldEqual (fa.shape (0), 2);
+        shouldEqual (fa.shape (1), 5);
+    }
+
+    void test_bind ()
+    {
+        MultiArrayView <2, unsigned char, StridedArrayTag>
+            fa = a3.bind <0> (1);
+
+        shouldEqual (fa.shape (0), 3);
+        shouldEqual (fa.shape (1), 5);
+    }
+
+    void test_reshape ()
+    {
+        shouldEqual(a3(0,0), 1);
+        a3.reshape(a3.shape());
+        shouldEqual(a3(0,0), 0);
+    
+        a3.reshape (shape3_t(20,30,50));
+
+        shouldEqual (a3.shape (0), 20);
+        shouldEqual (a3.shape (1), 30);
+        shouldEqual (a3.shape (2), 50);
+        shouldEqual(a3(0,0), 0);
+    }
+    
+    void test_copy_int_float()
+    {
+        MultiArray<2, float> a(MultiArrayShape<2>::type(2,2));
+        a.init(3);
+        MultiArray<2, unsigned short> b(a.shape());
+        b = a;
+    }
+
+    void test_subarray ()
+    {
+        a3.reshape (shape3_t(20,30,50));
+
+        MultiArrayView <3, unsigned char> st = 
+            a3.subarray (shape3_t(1,3,3),shape3_t(5,3,5));
+
+        shouldEqual (st.shape (0), 4);
+        shouldEqual (st.shape (1), 0);
+        shouldEqual (st.shape (2), 2);
+    }
+
+    void test_stridearray ()
+    {
+        typedef MultiArrayView <3, unsigned char, StridedArrayTag>
+                strided_array_t;
+        
+        a3.reshape (shape3_t(20,30,50));
+        
+        strided_array_t st = a3.stridearray (shape3_t(3,4,6));
+
+        shouldEqual (st.shape (0), 6);
+        shouldEqual (st.shape (1), 7);
+        shouldEqual (st.shape (2), 8);
+        
+        // test hierarchical navigation
+        typedef strided_array_t::traverser Traverser3;
+        Traverser3 i3_f = st.traverser_begin ();
+        Traverser3 i3_l = st.traverser_end ();
+
+        unsigned int countx = 0, county = 0, countz = 0;
+
+        // iterate over the third dimension
+        for (; i3_f != i3_l; ++i3_f) {
+            typedef Traverser3::next_type Traverser2;
+            Traverser2 i2_f = i3_f.begin ();
+            Traverser2 i2_l = i3_f.end ();
+            // iterate over the second dimension
+            for (; i2_f != i2_l; ++i2_f) {
+                typedef Traverser2::next_type Traverser1;
+                Traverser1 i1_f = i2_f.begin ();
+                Traverser1 i1_l = i2_f.end ();
+                // iterate over the first dimension
+                for (; i1_f != i1_l; ++i1_f)
+                    ++countx;
+                ++county;
+            }
+            ++countz;
+        }
+
+        shouldEqual (countx, 336u);
+        shouldEqual (county, 56u);
+        shouldEqual (countz, 8u);
+  
+        // test direct navigation
+        strided_array_t::traverser i = st.traverser_begin();        
+        shouldEqual(&*i, &st[shape3_t(0,0,0)]);
+        shouldEqual(&*i, &a3[shape3_t(0,0,0)]);
+        
+        i.dim<2>()++;
+        i.dim<1>()++;
+        i.dim<0>()++;
+        shouldEqual(&*i, &st[shape3_t(1,1,1)]);
+        shouldEqual(&*i, &a3[shape3_t(3,4,6)]);
+        
+        i.dim<2>()+= 3;
+        i.dim<1>()+= 2;
+        i.dim<0>()+= 1;
+        shouldEqual(&*i, &st[shape3_t(2,3,4)]);
+        shouldEqual(&*i, &a3[shape3_t(6,12,24)]);
+        shouldEqual(&i[shape3_t(-2,-3,-4)], &a3[shape3_t(0,0,0)]);
+        shouldEqual(&*(i-shape3_t(2,3,4)), &a3[shape3_t(0,0,0)]);
+        
+        i.dim<2>()--;
+        i.dim<1>()--;
+        i.dim<0>()--;
+        shouldEqual(&*i, &st[shape3_t(1,2,3)]);
+        shouldEqual(&*i, &a3[shape3_t(3,8,18)]);
+        
+        i.dim<2>()-= 3;
+        i.dim<1>()-= 2;
+        i.dim<0>()-= 1;
+        shouldEqual(&*i, &st[shape3_t(0,0,0)]);
+        shouldEqual(&*i, &a3[shape3_t(0,0,0)]);
+        shouldEqual(&i[shape3_t(2,3,4)], &a3[shape3_t(6,12,24)]);
+        shouldEqual(&*(i+shape3_t(2,3,4)), &a3[shape3_t(6,12,24)]);
+    }
+
+    void test_expandElements()
+    {
+        using namespace multi_math;
+
+        MultiArray<3, TinyVector<int, 3> > a(Shape3(4,3,2));
+        a.init(TinyVector<int, 3>(1,2,3));
+
+        MultiArrayView<4, int, StridedArrayTag> ex = a.expandElements(0);
+        MultiArrayView<4, int, StridedArrayTag>::iterator i = ex.begin();
+        while(i != ex.end())
+        {
+            shouldEqual(*i, 1); ++i;
+            shouldEqual(*i, 2); ++i;
+            shouldEqual(*i, 3); ++i;
+        }
+
+        MultiArrayView<4, int, StridedArrayTag> ex2 = a.expandElements(3);
+        i = ex2.begin();
+        for(int k=0; k < a.size(); ++i, ++k)
+            shouldEqual(*i, 1);
+        for(int k=0; k < a.size(); ++i, ++k)
+            shouldEqual(*i, 2);
+        for(int k=0; k < a.size(); ++i, ++k)
+            shouldEqual(*i, 3);
+
+        MultiArray<3, bool> b = (a.bindElementChannel(0) == 1);
+        should(b.all());
+        b = (a.bindElementChannel(1) == 2);
+        should(b.all());
+        b = (a.bindElementChannel(2) == 3);
+        should(b.all());
+    }
+};
+
+class MultiArrayNavigatorTest
+{
+public:
+
+    typedef unsigned int scalar_type;
+    typedef MultiArray <3, scalar_type> array3_type;
+    typedef MultiArrayView <3, scalar_type> array3_view_type;
+    typedef array3_type::difference_type difference3_type;
+    
+    difference3_type shape3;
+    array3_type array3;
+
+    MultiArrayNavigatorTest ()
+        : shape3 (4, 3, 2), array3 (shape3)
+    {
+        // initialize the array to the test data
+        for (unsigned int i = 0; i < 24; ++i)
+            array3.data () [i] = i;
+    }
+
+    void testNavigator ()
+    {
+        unsigned char expected[][24] = 
+            {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
+            {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13, 17, 21, 14, 18, 22, 15, 19, 23},
+            {0, 12, 1, 13, 2, 14, 3, 15, 4, 16, 5, 17, 6, 18, 7, 19, 8, 20, 9, 21, 10, 22, 11, 23}};
+        typedef MultiArrayNavigator<array3_type::traverser, 3> Navigator;
+        for(int d=0; d<3; ++d)
+        {
+            Navigator nav(array3.traverser_begin(), array3.shape(), d);
+            int k = 0;
+            for(; nav.hasMore(); ++nav)
+            {
+                Navigator::iterator i = nav.begin(), end = nav.end();
+                for(; i != end; ++i, ++k)
+                    shouldEqual(*i, expected[d][k]);
+            }
+        }
+        
+        Shape3 start(1, 1, 0), stop(3, 3, 2);
+        unsigned char sexpected[][8] = 
+            {{5,  6,  9, 10, 17, 18, 21, 22},
+            {5,  9,  6, 10, 17, 21, 18, 22},
+            {5, 17,  6, 18,  9, 21, 10, 22}};
+        for(int d=0; d<3; ++d)
+        {
+            Navigator nav(array3.traverser_begin(), start, stop, d);
+            int k = 0;
+            for(; nav.hasMore(); ++nav)
+            {
+                Navigator::iterator i = nav.begin(), end = nav.end();
+                for(; i != end; ++i, ++k)
+                    shouldEqual(*i, sexpected[d][k]);
+            }
+        }
+    }
+
+    void testCoordinateNavigator ()
+    {
+        unsigned char expected[][24] = 
+            {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
+            {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13, 17, 21, 14, 18, 22, 15, 19, 23},
+            {0, 12, 1, 13, 2, 14, 3, 15, 4, 16, 5, 17, 6, 18, 7, 19, 8, 20, 9, 21, 10, 22, 11, 23}};
+        typedef MultiCoordinateNavigator<3> Navigator;
+        for(int d=0; d<3; ++d)
+        {
+            Navigator nav(array3.shape(), d);
+            int k = 0;
+            for(; nav.hasMore(); ++nav)
+            {
+                Navigator::value_type i = nav.begin(), end = nav.end();
+                for(; i[d] != end[d]; ++i[d], ++k)
+                    shouldEqual(array3[i], expected[d][k]);
+            }
+        }
+    }    
+};
+
+struct MultiImpexTest
+{
+    typedef MultiArray<3, unsigned char> Array;
+    typedef Array::difference_type Shape;
+    typedef Array::traverser Traverser;
+    
+    Array array;
+    
+    MultiImpexTest()
+    : array(Shape(2,3,4))
+    {
+        int value = 1;
+        
+        Traverser i3 = array.traverser_begin ();
+
+        for (; i3 != array.traverser_end(); ++i3, ++value) 
+        {
+            typedef Traverser::next_type Traverser2;
+            Traverser2 i2 = i3.begin ();
+            for (; i2 != i3.end(); ++i2) 
+            {
+                typedef Traverser2::next_type Traverser1;
+                Traverser1 i1 = i2.begin ();
+                for (; i1 != i2.end(); ++i1)
+                {
+                    *i1 = value;
+                }
+            }
+        }
+    }
+    
+    void testImpex()
+    {
+#if defined(HasTIFF)
+        const char * ext1 = ".tif";
+#else
+        const char * ext1 = ".xv";
+#endif
+        exportVolume(array, VolumeExportInfo("test", ext1));
+        
+        Array result;
+        
+        VolumeImportInfo import_info("test", ext1);
+        shouldEqual(Shape(2,3,4), import_info.shape());
+
+        result.reshape(import_info.shape());
+        importVolume(import_info, result);
+        
+        shouldEqual(result(0,1,0), 1);
+        shouldEqual(result(0,1,1), 2);
+        shouldEqual(result(0,1,2), 3);
+        shouldEqual(result(0,1,3), 4);
+
+#if defined(HasPNG)
+        const char * ext2 = ".png";
+#else
+        const char * ext2 = ".pnm";
+#endif
+        exportVolume(array, std::string("impex/test"), std::string(ext2));
+        
+        importVolume(result, std::string("impex/test"), std::string(ext2));
+        
+        shouldEqual(result.shape(), Shape(2,3,4));
+        shouldEqual(result(0,1,0), 1);
+        shouldEqual(result(0,1,1), 2);
+        shouldEqual(result(0,1,2), 3);
+        shouldEqual(result(0,1,3), 4);
+
+#ifdef _WIN32
+        exportVolume(array, VolumeExportInfo("impex\\test", ext2));
+        
+        importVolume(result, std::string("impex\\test"), std::string(ext2));
+        
+        shouldEqual(result.shape(), Shape(2,3,4));
+        shouldEqual(result(0,1,0), 1);
+        shouldEqual(result(0,1,1), 2);
+        shouldEqual(result(0,1,2), 3);
+        shouldEqual(result(0,1,3), 4);
+#endif // _WIN32
+    }
+
+#if defined(HasTIFF)
+    void testMultipageTIFF()
+    {
+        exportVolume(array, VolumeExportInfo("multipage.tif"));
+
+        VolumeImportInfo info("multipage.tif");
+        shouldEqual(Shape(2,3,4), info.shape());
+
+        Array result(info.shape());
+        importVolume(info, result);
+        shouldEqual(result(0,1,0), 1);
+        shouldEqual(result(0,1,1), 2);
+        shouldEqual(result(0,1,2), 3);
+        shouldEqual(result(0,1,3), 4);
+    }
+#endif
+
+};
+
+template <class IMAGE>
+struct ImageViewTest
+{
+    typedef typename IMAGE::value_type value_type;
+    typedef MultiArray<2, value_type> MA;
+    typedef BasicImageView<value_type> Image;
+    static typename Image::value_type data[];
+
+    ImageViewTest()
+    : ma(TinyVector<int, 2>(3,3)),
+      img(makeBasicImageView(ma))
+    {
+        typename Image::Accessor acc = img.accessor();
+        typename Image::iterator i = img.begin();
+
+        acc.set(data[0], i);
+        ++i;
+        acc.set(data[1], i);
+        ++i;
+        acc.set(data[2], i);
+        ++i;
+        acc.set(data[3], i);
+        ++i;
+        acc.set(data[4], i);
+        ++i;
+        acc.set(data[5], i);
+        ++i;
+        acc.set(data[6], i);
+        ++i;
+        acc.set(data[7], i);
+        ++i;
+        acc.set(data[8], i);
+        ++i;
+        should(i == img.end());
+    }
+
+    template <class Iterator>
+    void scanImage(Iterator ul, Iterator lr)
+    {
+        Iterator y = ul;
+        Iterator x = ul;
+        typename Image::Accessor acc = img.accessor();
+
+        should(acc(x) == data[0]);
+        ++x.x;
+        should(acc(x) == data[1]);
+        ++x.x;
+        should(acc(x) == data[2]);
+        ++x.x;
+        should(x.x == lr.x);
+
+        ++y.y;
+        x = y;
+        should(acc(x) == data[3]);
+        ++x.x;
+        should(acc(x) == data[4]);
+        ++x.x;
+        should(acc(x) == data[5]);
+        ++y.y;
+        x = y;
+        should(acc(x) == data[6]);
+        ++x.x;
+        should(acc(x) == data[7]);
+        ++x.x;
+        should(acc(x) == data[8]);
+        ++y.y;
+        should(y.y == lr.y);
+
+        y = ul;
+        should(acc(y, vigra::Diff2D(1,1)) == data[4]);
+    }
+
+    template <class Iterator>
+    void scanRows(Iterator r1, Iterator r2, Iterator r3, int w)
+    {
+        Iterator end = r1 + w;
+        typename Image::Accessor acc = img.accessor();
+
+        should(acc(r1) == data[0]);
+        ++r1;
+        should(acc(r1) == data[1]);
+        ++r1;
+        should(acc(r1) == data[2]);
+        ++r1;
+        should(r1 == end);
+
+        end = r2 + w;
+        should(acc(r2) == data[3]);
+        ++r2;
+        should(acc(r2) == data[4]);
+        ++r2;
+        should(acc(r2) == data[5]);
+        ++r2;
+        should(r2 == end);
+
+        end = r3 + w;
+        should(acc(r3) == data[6]);
+        ++r3;
+        should(acc(r3) == data[7]);
+        ++r3;
+        should(acc(r3) == data[8]);
+        ++r3;
+        should(r3 == end);
+    }
+
+    template <class Iterator>
+    void scanColumns(Iterator c1, Iterator c2, Iterator c3, int h)
+    {
+        Iterator end = c1 + h;
+        typename Image::Accessor acc = img.accessor();
+
+        should(acc(c1) == data[0]);
+        ++c1;
+        should(acc(c1) == data[3]);
+        ++c1;
+        should(acc(c1) == data[6]);
+        ++c1;
+        should(c1 == end);
+
+        end = c2 + h;
+        should(acc(c2) == data[1]);
+        ++c2;
+        should(acc(c2) == data[4]);
+        ++c2;
+        should(acc(c2) == data[7]);
+        ++c2;
+        should(c2 == end);
+
+        end = c3 + h;
+        should(acc(c3) == data[2]);
+        ++c3;
+        should(acc(c3) == data[5]);
+        ++c3;
+        should(acc(c3) == data[8]);
+        ++c3;
+        should(c3 == end);
+    }
+
+    void testStridedImageView()
+    {
+        // create stride MultiArrayView
+        typename MA::difference_type
+            start(0,0), end(2,2);
+        MA roi = ma.subarray(start, end);
+
+        // inspect both the MultiArrayView and the corresponding BasicImageView
+        vigra::FindSum<typename Image::value_type> sum1, sum2;
+        vigra::inspectMultiArray(srcMultiArrayRange(roi), sum1);
+        vigra::inspectImage(srcImageRange(makeBasicImageView(roi)), sum2);
+
+        shouldEqual(sum1.sum(), sum2.sum());
+        shouldEqual(data[0] + data[1] + data[3] + data[4], sum2.sum());
+    }
+
+    void testBasicImageIterator()
+    {
+        typename Image::Iterator ul = img.upperLeft();
+        typename Image::Iterator lr = img.lowerRight();
+
+        scanImage(ul, lr);
+        scanRows(ul.rowIterator(), (ul+Diff2D(0,1)).rowIterator(),
+                 (ul+Diff2D(0,2)).rowIterator(), img.width());
+        scanColumns(ul.columnIterator(), (ul+Diff2D(1,0)).columnIterator(),
+                 (ul+Diff2D(2,0)).columnIterator(), img.height());
+
+        typename Image::Accessor acc = img.accessor();
+        typename Image::iterator i = img.begin();
+        should(acc(i, 4) == data[4]);
+    }
+
+    void testImageIterator()
+    {
+        vigra::ImageIterator<typename Image::value_type>
+            ul(img.begin(), img.width());
+        vigra::ImageIterator<typename Image::value_type> lr = ul + img.size();
+        scanImage(ul, lr);
+        scanRows(ul.rowIterator(), (ul+Diff2D(0,1)).rowIterator(),
+                 (ul+Diff2D(0,2)).rowIterator(), img.width());
+        scanColumns(ul.columnIterator(), (ul+Diff2D(1,0)).columnIterator(),
+                 (ul+Diff2D(2,0)).columnIterator(), img.height());
+    }
+
+    void copyImage()
+    {
+        typedef typename Image::value_type Value;
+
+        Image img1(img);
+        typename Image::iterator i = img.begin();
+        typename Image::iterator i1 = img1.begin();
+        typename Image::Accessor acc = img.accessor();
+
+        for(; i != img.end(); ++i, ++i1)
+        {
+            should(acc(i) == acc(i1));
+        }
+
+        img.init(NumericTraits<Value>::zero());
+        for(; i != img.end(); ++i)
+        {
+            should(acc(i) == Value(NumericTraits<Value>::zero()));
+        }
+        img(1,1) = Value(200);
+        img1 = img;
+        i = img.begin();
+        i1 = img1.begin();
+
+        for(; i != img.end(); ++i, ++i1)
+        {
+            should(acc(i) == acc(i1));
+        }
+    }
+
+    MA ma;
+    Image img;
+};
+
+typedef ImageViewTest<vigra::BImage> BImageViewTest;
+
+template <>
+unsigned char BImageViewTest::data[] = {1,2,3,4,5,6,7,8,9};
+
+typedef ImageViewTest<vigra::DImage> DImageViewTest;
+
+template <>
+double DImageViewTest::data[] = {1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9};
+
+typedef ImageViewTest<vigra::BRGBImage> BRGBImageViewTest;
+typedef vigra::RGBValue<unsigned char> BRGB;
+template <>
+BRGB BRGBImageViewTest::data[] = {
+    BRGB(1,1,1),
+    BRGB(2,2,2),
+    BRGB(3,3,3),
+    BRGB(4,4,4),
+    BRGB(5,5,5),
+    BRGB(6,6,6),
+    BRGB(7,7,7),
+    BRGB(8,8,8),
+    BRGB(9,9,9)
+};
+
+typedef ImageViewTest<vigra::FRGBImage> FRGBImageViewTest;
+typedef vigra::RGBValue<float> FRGB;
+template <>
+FRGB FRGBImageViewTest::data[] = {
+    FRGB(1.1f, 1.1f, 1.1f),
+    FRGB(2.2f, 2.2f, 2.2f),
+    FRGB(3.3f, 3.3f, 3.3f),
+    FRGB(4.4f, 4.4f, 4.4f),
+    FRGB(5.5f, 5.5f, 5.5f),
+    FRGB(6.6f, 6.6f, 6.6f),
+    FRGB(7.7f, 7.7f, 7.7f),
+    FRGB(8.8f, 8.8f, 8.8f),
+    FRGB(9.9f, 9.9f, 9.9f)
+};
+
+struct MultiArrayPointoperatorsTest
+{
+
+    typedef float PixelType;
+    typedef MultiArray<3,PixelType> Image3D;
+    typedef MultiArrayView<3,PixelType> View3D;
+    typedef Image3D::difference_type Size3;
+    typedef MultiArray<1,PixelType> Image1D;
+    typedef Image1D::difference_type Size1;
+
+    Image3D img;
+
+    MultiArrayPointoperatorsTest()
+    : img(Size3(5,4,3))
+    {
+        int i;
+        PixelType c = 0.1f;
+        for(i=0; i<img.elementCount(); ++i, ++c)
+            img.data()[i] = c;
+    }
+
+    void testInit()
+    {
+        Image3D res(img.shape());
+        const Image3D::value_type ini = 1.1f;
+        should(res.shape() == Size3(5,4,3));
+
+        initMultiArray(destMultiArrayRange(res), ini);
+
+        int x,y,z;
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    shouldEqual(res(x,y,z), ini);
+
+        using namespace multi_math;
+        should(all(res == ini));
+
+        initMultiArray(res, 2.2f);
+        should(all(res == 2.2f));
+
+        res = 3.3f;
+        should(all(res == 3.3f));
+
+        res.init(4.4f);
+        should(all(res == 4.4f));
+    }
+
+    void testCopy()
+    {
+        Image3D res(img.shape(), 1.0), res1(img.shape(), 1.0);
+        
+        copyMultiArray(srcMultiArrayRange(img), destMultiArray(res));
+        copyMultiArray(img, res1);
+
+        should(img == res);
+        should(img == res1);
+    }
+
+    void testCopyOuterExpansion()
+    {
+        Image3D res(img.shape());
+
+        copyMultiArray(img.subarray(Size3(0,0,0), Size3(5,1,1)), res);
+        
+        int x,y,z;
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    shouldEqual(res(x,y,z), img(x,0,0));
+    }
+
+    void testCopyInnerExpansion()
+    {
+        Image3D res(img.shape());
+
+        copyMultiArray(img.subarray(Size3(0,0,0), Size3(1,1,3)), res);
+        
+        int x,y,z;
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    shouldEqual(res(x,y,z), img(0,0,z));
+    }
+
+    void testTransform()
+    {
+        Image3D res(img.shape()), res1(img.shape());
+        transformMultiArray(srcMultiArrayRange(img), destMultiArray(res),
+                            Arg1() + Arg1());
+        transformMultiArray(img, res1, Arg1() + Arg1());
+        
+        using namespace multi_math;
+        should(all(2.0*img == res));
+        should(all(2.0*img == res1));
+    }
+
+    void testTransformOuterExpand()
+    {
+        Image3D res(img.shape());
+        transformMultiArray(img.subarray(Size3(0,0,0), Size3(5,1,1)), res,
+                            Arg1() + Arg1());
+        
+        int x,y,z;
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    shouldEqual(res(x,y,z), 2.0*img(x,0,0));
+    }
+
+    void testTransformInnerExpand()
+    {
+        Image3D res(img.shape());
+
+        transformMultiArray(img.subarray(Size3(0,0,0), Size3(1,1,3)), res,
+                            Arg1() + Arg1());
+        
+        int x,y,z;
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    shouldEqual(res(x,y,z), 2.0*img(0,0,z));
+    }
+
+    void testTransformOuterReduce()
+    {
+        Image3D res(Size3(5,1,1));
+
+        transformMultiArray(img, res, reduceFunctor(Arg1() + Arg2(), 0.0));
+        
+        int x,y,z;
+        for(x=0; x<img.shape(0); ++x)
+        {
+            double sum = 0.0;
+            for(y=0; y<img.shape(1); ++y)
+                for(z=0; z<img.shape(2); ++z)
+                    sum += img(x,y,z);
+            shouldEqual(res(x,0,0), sum);
+        }
+        
+        Image1D res1(Size1(5));
+        MultiArrayView<3,PixelType> res3 = res1.insertSingletonDimension(1).insertSingletonDimension(2);
+        transformMultiArray(img, res3, FindSum<PixelType>());
+        shouldEqualSequenceTolerance(res1.data(), res1.data()+5, res.data(), 1e-7);       
+    }
+
+    void testTransformInnerReduce()
+    {
+        Image3D res(Size3(1,1,3));
+        
+        transformMultiArray(img, res, reduceFunctor(Arg1() + Arg2(), 0.0));
+        
+        int x,y,z;
+        for(z=0; z<img.shape(2); ++z)
+        {
+            double sum = 0.0;
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    sum += img(x,y,z);
+            shouldEqual(res(0,0,z), sum);
+        }
+        
+        Image1D res1(Size1(3));
+        MultiArrayView<3,PixelType> res3 = res1.insertSingletonDimension(0).insertSingletonDimension(0);
+        transformMultiArray(img, res3, FindSum<PixelType>());
+        shouldEqualSequenceTolerance(res1.data(), res1.data()+3, res.data(), 1e-6);       
+    }
+
+    void testCombine2()
+    {
+        Image3D res(img.shape()), res1(img.shape());
+        
+        combineTwoMultiArrays(srcMultiArrayRange(img), srcMultiArray(img), 
+                              destMultiArray(res),
+                              Arg1() + Arg2());
+        combineTwoMultiArrays(img, img, res1, Arg1() + Arg2());
+        
+        using namespace multi_math;
+        should(all(2.0*img == res));
+        should(all(2.0*img == res1));
+    }
+
+    void testCombine2OuterExpand()
+    {
+        Image3D res(img.shape());
+        
+        combineTwoMultiArrays(img.subarray(Size3(0,0,0), Size3(5,1,1)), img, res,
+                              Arg1() + Param(2.0)*Arg2());       
+        int x,y,z;
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    shouldEqual(res(x,y,z), 2.0*img(x,y,z) + img(x,0,0));
+
+        combineTwoMultiArrays(img, img.subarray(Size3(0,0,0), Size3(5,1,1)), res,
+                              Arg1() + Param(2.0)*Arg2());       
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    shouldEqual(res(x,y,z), img(x,y,z) + 2.0*img(x,0,0));
+
+        View3D view = img.subarray(Size3(0,0,0), Size3(5,1,1));
+        combineTwoMultiArrays(srcMultiArrayRange(view), srcMultiArrayRange(view), 
+                              destMultiArrayRange(res),
+                              Arg1() + Param(2.0)*Arg2());       
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    shouldEqual(res(x,y,z), 3.0*img(x,0,0));
+    }
+
+    void testCombine2InnerExpand()
+    {
+        Image3D res(img.shape());
+        
+        View3D view = img.subarray(Size3(0,0,0), Size3(1,1,3));
+        combineTwoMultiArrays(view, img, res,
+                              Arg1() + Param(2.0)*Arg2());       
+        int x,y,z;
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    shouldEqual(res(x,y,z), 2.0*img(x,y,z) + img(0,0,z));
+
+        combineTwoMultiArrays(img, view, res,
+                              Arg1() + Param(2.0)*Arg2());       
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    shouldEqual(res(x,y,z), img(x,y,z) + 2.0*img(0,0,z));
+
+        combineTwoMultiArrays(srcMultiArrayRange(view), srcMultiArrayRange(view), 
+                              destMultiArrayRange(res),
+                              Arg1() + Param(2.0)*Arg2());       
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    shouldEqual(res(x,y,z), 3.0*img(0,0,z));
+    }
+
+    void testCombine2OuterReduce()
+    {
+        Image3D res(Size3(5,1,1));
+        
+        combineTwoMultiArrays(img, img, res,
+                              reduceFunctor(Arg1() + Arg2() + Arg3(), 0.0));
+        
+        int x,y,z;
+        for(x=0; x<img.shape(0); ++x)
+        {
+            double sum = 0.0;
+            for(y=0; y<img.shape(1); ++y)
+                for(z=0; z<img.shape(2); ++z)
+                    sum += img(x,y,z);
+            shouldEqual(res(x,0,0), 2.0*sum);
+        }
+    }
+
+    void testCombine2InnerReduce()
+    {
+        Image3D res(Size3(1,1,3));
+        
+        combineTwoMultiArrays(img, img, res,
+                              reduceFunctor(Arg1() + Arg2() + Arg3(), 0.0));
+        
+        int x,y,z;
+        for(z=0; z<img.shape(2); ++z)
+        {
+            double sum = 0.0;
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                    sum += img(x,y,z);
+            shouldEqual(res(0,0,z), 2.0*sum);
+        }
+    }
+
+    void testCombine3()
+    {
+        Image3D res(img.shape()), res1(img.shape());
+        
+        combineThreeMultiArrays(srcMultiArrayRange(img), 
+                                srcMultiArray(img), srcMultiArray(img), 
+                                destMultiArray(res),
+                                Arg1() + Arg2() + Arg3());
+        combineThreeMultiArrays(img, img, img, res1,
+                                Arg1() + Arg2() + Arg3());
+
+        int x,y,z;
+        for(z=0; z<img.shape(2); ++z)
+            for(y=0; y<img.shape(1); ++y)
+                for(x=0; x<img.shape(0); ++x)
+                {
+                    shouldEqual(res(x,y,z), 3.0*img(x,y,z));
+                    shouldEqual(res1(x,y,z), 3.0*img(x,y,z));
+                }
+    }
+    
+    void testInitMultiArrayBorder(){
+        typedef vigra::MultiArray<1,int> IntLine;
+        typedef vigra::MultiArray<2,int> IntImage;
+        typedef vigra::MultiArray<3,int> IntVolume;
+        
+        const int desired_vol[] ={  0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 5, 5, 0, 0,
+                                    0, 0, 5, 5, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 5, 5, 0, 0,
+                                    0, 0, 5, 5, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0};
+
+        const int desired_img[] ={  0, 0, 0, 0, 0, 0,
+                                    0, 5, 5, 5, 5, 0,
+                                    0, 5, 5, 5, 5, 0,
+                                    0, 5, 5, 5, 5, 0,
+                                    0, 5, 5, 5, 5, 0,
+                                    0, 0, 0, 0, 0, 0};
+
+        const int desired_lin[] ={  0, 0, 0, 5, 0, 0, 0 };
+
+        const int desired_vol2[] ={  0, 0,
+                                     0, 0,
+
+                                     0, 0, 
+                                     0, 0};
+
+        IntVolume vol(IntVolume::difference_type(6,6,6));
+        
+        for(IntVolume::iterator iter=vol.begin(); iter!=vol.end(); ++iter)
+            *iter=5;
+        initMultiArrayBorder(destMultiArrayRange(vol),2,0);
+        shouldEqualSequence(vol.begin(), vol.end(), desired_vol);
+
+        IntImage img(IntImage::difference_type(6,6));
+        
+        for(IntImage::iterator iter=img.begin(); iter!=img.end(); ++iter)
+            *iter=5;
+        initMultiArrayBorder(destMultiArrayRange(img),1,0);
+        shouldEqualSequence(img.begin(), img.end(), desired_img);
+
+        IntLine lin(IntLine::difference_type(7));
+        
+        for(IntLine::iterator iter=lin.begin(); iter!=lin.end(); ++iter)
+            *iter=5;
+        initMultiArrayBorder(destMultiArrayRange(lin),3,0);
+        shouldEqualSequence(lin.begin(), lin.end(), desired_lin);
+
+        IntVolume vol2(IntVolume::difference_type(2,2,2));
+        
+        for(IntVolume::iterator iter=vol2.begin(); iter!=vol2.end(); ++iter)
+            *iter=5;
+        initMultiArrayBorder(vol2, 9, 0);
+        shouldEqualSequence(vol2.begin(), vol2.end(), desired_vol2);
+
+    }
+
+    void testInspect()
+    {
+        vigra::FindMinMax<PixelType> minmax;
+
+        inspectMultiArray(img, minmax);
+
+        shouldEqual(minmax.count, img.size());
+        shouldEqual(minmax.min, 0.1f);
+        shouldEqual(minmax.max, 59.1f);
+
+        vigra::MultiArray<3, unsigned char> labels(img.shape());
+        labels.subarray(Shape3(1,0,0), img.shape()-Shape3(1,0,0)) = 1;
+
+        vigra::ArrayOfRegionStatistics<vigra::FindMinMax<PixelType> > stats(1);
+
+        inspectTwoMultiArrays(img, labels, stats);
+
+        shouldEqual(stats[0].count, 24);
+        shouldEqual(stats[0].min, 0.1f);
+        shouldEqual(stats[0].max, 59.1f);
+        shouldEqual(stats[1].count, 36);
+        shouldEqual(stats[1].min, 1.1f);
+        shouldEqual(stats[1].max, 58.1f);
+    }
+    
+    void testTensorUtilities()
+    {
+        MultiArrayShape<2>::type shape(3,4);
+        int size = shape[0]*shape[1];
+        
+        MultiArray<2, TinyVector<double, 2> > vector(shape), rvector(shape);
+        MultiArray<2, TinyVector<double, 3> > tensor1(shape), tensor2(shape), rtensor(shape);
+        MultiArray<2, double > trace(shape), rtrace(shape);
+        MultiArray<2, double > determinant(shape), rdet(shape);
+        
+        for(int k=0; k<size; ++k)
+        {
+            for(int l=0; l<2; ++l)
+                vector[k][l] = randomMT19937().uniform();
+            for(int l=0; l<3; ++l)
+                tensor1[k][l] = randomMT19937().uniform();
+            rdet[k] = tensor1[k][0]*tensor1[k][2] - sq(tensor1[k][1]);
+        }
+        
+        vectorToTensor(srcImageRange(vector), destImage(rtensor));
+        vectorToTensorMultiArray(srcMultiArrayRange(vector), destMultiArray(tensor2));
+        shouldEqualSequence(tensor2.data(), tensor2.data()+size, rtensor.data());
+        tensor2.init(TinyVector<double, 3>());
+        vectorToTensorMultiArray(vector, tensor2);
+        shouldEqualSequence(tensor2.data(), tensor2.data()+size, rtensor.data());
+                
+        tensorTrace(srcImageRange(tensor1), destImage(rtrace));
+        tensorTraceMultiArray(srcMultiArrayRange(tensor1), destMultiArray(trace));
+        shouldEqualSequence(trace.data(), trace.data()+size, rtrace.data());
+        trace = 0;
+        tensorTraceMultiArray(tensor1, trace);
+        shouldEqualSequence(trace.data(), trace.data()+size, rtrace.data());
+                
+        tensorDeterminantMultiArray(srcMultiArrayRange(tensor1), destMultiArray(determinant));
+        shouldEqualSequence(determinant.data(), determinant.data()+size, rdet.data());
+        determinant = 0;
+        tensorDeterminantMultiArray(tensor1, determinant);
+        shouldEqualSequence(determinant.data(), determinant.data()+size, rdet.data());
+                
+        determinant = 1000.0;
+        tensorDeterminantMultiArray(srcMultiArrayRange(tensor2), destMultiArray(determinant));
+        shouldEqualTolerance(norm(determinant), 0.0, 1e-14);
+
+        tensorEigenRepresentation(srcImageRange(tensor1), destImage(rtensor));
+        tensorEigenvaluesMultiArray(srcMultiArrayRange(tensor1), destMultiArray(vector));
+        shouldEqualSequenceTolerance(vector.begin(), vector.end(), rtensor.begin(), (TinyVector<double, 2>(1e-14)));
+
+        vector = TinyVector<double, 2>();
+        tensorEigenvaluesMultiArray(tensor1, vector);
+        shouldEqualSequenceTolerance(vector.begin(), vector.end(), rtensor.begin(), (TinyVector<double, 2>(1e-14)));
+    }
+};
+
+class MultiMathTest
+{
+public:
+
+    typedef double scalar_type;
+    typedef MultiArray <3, scalar_type> array3_type;
+    typedef MultiArrayView <3, scalar_type> view_type;
+    typedef array3_type::difference_type shape3_type;
+    
+    shape3_type shape3;
+    array3_type r1, r2, r3, r4, r5, a, b, c, d;
+    view_type rv, bv, cv, dv;
+
+    MultiMathTest ()
+        : shape3 (4, 3, 2), 
+          r2(shape3),
+          r3(shape3),
+          r4(shape3),
+          r5(Shape3(2,3,4)),
+          a(shape3),
+          b(shape3),
+          c(shape3),
+          d(shape3),
+          rv(r3),
+          bv(b),
+          cv(c),
+          dv(d)
+    {
+        // initialize the array to the test data
+        for (unsigned int i = 0; i < 24; ++i)
+        {
+            a[i] = std::exp(-0.2*i);
+            b[i] = 0.5 + i;
+            c[i] = 100.0 + i;
+            d[i] = -(i+1.0);
+        }
+    }
+
+    void testSpeed()
+    {
+        using namespace vigra::multi_math;
+        using namespace vigra::functor;
+        const int size = 200;
+        Shape3 s(size, size, size);
+        array3_type u(s),
+                    v(s),
+                    w(s);
+        std::string t;
+        USETICTOC;
+        std::cerr << "multi_math speed test: \n";
+#if 0
+        marray::Marray<double> mu(s.begin(), s.end()),
+                               mv(s.begin(), s.end()),
+                               mw(s.begin(), s.end());
+        
+        TIC;
+        marray::Marray<double>::iterator iu = mu.begin(), end = mu.end(),
+                                         iv = mv.begin(), iw = mw.begin();
+        for(; iu != end; ++iu, ++iv, ++iw)
+            *iw = *iu * *iv;
+        t = TOCS;
+        std::cerr << "    marray iterator: " << t << "\n";
+        TIC;
+        mw = mu*mv;
+        t = TOCS;
+        std::cerr << "    marray expression: " << t << "\n";
+#endif
+        TIC;
+        typedef array3_type::view_type View;
+        View::iterator wi = ((View &)w).begin(), wend = wi.getEndIterator(),
+                       ui = ((View &)u).begin(), vi = ((View &)v).begin();
+        for(; wi != wend; ++wi, ++ui, ++vi)
+                    *wi = *ui * *vi;
+        t = TOCS;
+        std::cerr << "    StridedScanOrderIterator: " << t << "\n";
+        TIC;
+        typedef CoupledIteratorType<3, scalar_type, scalar_type, scalar_type>::type CI;
+        CI i = createCoupledIterator(w, u, v), end = i.getEndIterator();
+        for(; i != end; ++i)
+                    i.get<1>() = i.get<2>() * i.get<3>();
+        t = TOCS;
+        std::cerr << "    CoupledScanOrderIterator: " << t << "\n";
+        TIC;
+        w = u*v;
+        t = TOCS;
+        std::cerr << "    multi_math expression: " << t << "\n";
+        TIC;
+        w.transpose() = u.transpose()*v.transpose();
+        t = TOCS;
+        std::cerr << "    transposed multi_math expression: " << t << "\n";
+        TIC;
+        combineTwoMultiArrays(srcMultiArrayRange(u), srcMultiArray(v), destMultiArray(w),
+                              Arg1()*Arg2());
+        t = TOCS;
+        std::cerr << "    lambda expression: " << t << "\n";
+        TIC;
+        combineTwoMultiArrays(srcMultiArrayRange(u.transpose()), srcMultiArray(v.transpose()), destMultiArray(w),
+                              Arg1()*Arg2());
+        t = TOCS;
+        std::cerr << "    transposed lambda expression: " << t << "\n";
+        TIC;
+        for(int z=0; z<size; ++z)
+            for(int y=0; y<size; ++y)
+                for(int x=0; x<size; ++x)
+                    w(x,y,z) = u(x,y,z) * v(x,y,z);
+        t = TOCS;
+        std::cerr << "    explicit loops: " << t << "\n";
+    }
+
+    void testBasicArithmetic()
+    {
+        using namespace vigra::multi_math;
+        using namespace vigra::functor;
+
+        // test all overload variants
+        r1 = b*d;
+        rv = bv*dv;
+        r4.transpose() = b.transpose()*d.transpose();
+        r5 = b.transpose()*d.transpose();
+        combineTwoMultiArrays(srcMultiArrayRange(b), srcMultiArray(d), destMultiArray(r2),
+                              Arg1()*Arg2());
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+        shouldEqualSequence(r4.begin(), r4.end(), r2.begin());
+        shouldEqualSequence(r2.begin(), r2.end(), r5.transpose().begin());
+
+        r1 = b*cv;
+        rv = cv*b;
+        combineTwoMultiArrays(srcMultiArrayRange(b), srcMultiArray(c), destMultiArray(r2),
+                              Arg1()*Arg2());
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+        r1 = 2.0*d;
+        rv = 2.0*dv;
+        r4.transpose() = 2.0*d.transpose();
+        r5 = 2.0*d.transpose();
+        transformMultiArray(srcMultiArrayRange(d), destMultiArray(r2),
+                            Param(2.0)*Arg1());
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+        shouldEqualSequence(r4.begin(), r4.end(), r2.begin());
+        shouldEqualSequence(r2.begin(), r2.end(), r5.transpose().begin());
+
+        r1 = d*4.0;
+        rv = dv*4.0;
+        transformMultiArray(srcMultiArrayRange(d), destMultiArray(r2),
+                            Arg1()*Param(4.0));
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+        r1 = (d*2.0)+b;
+        rv = (dv*2.0)+bv;
+        combineTwoMultiArrays(srcMultiArrayRange(b), srcMultiArray(d), destMultiArray(r2),
+                              (Arg2()*Param(2.0))+Arg1());
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+        r1 = b/(d*2.0);
+        rv = bv/(dv*2.0);
+        combineTwoMultiArrays(srcMultiArrayRange(b), srcMultiArray(d), destMultiArray(r2),
+                              Arg1()/(Arg2()*Param(2.0)));
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+        r1 = (2.0*b)-(d*2.0);
+        rv = (2.0*bv)-(dv*2.0);
+        combineTwoMultiArrays(srcMultiArrayRange(b), srcMultiArray(d), destMultiArray(r2),
+                              (Param(2.0)*Arg1())-(Arg2()*Param(2.0)));
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+        r1 = 2.0*(d*2.0);
+        rv = 2.0*(dv*2.0);
+        transformMultiArray(srcMultiArrayRange(d), destMultiArray(r2),
+                            Param(2.0)*(Arg1()*Param(2.0)));
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+        r1 = (d*3.0)*6.0;
+        rv = (dv*3.0)*6.0;
+        transformMultiArray(srcMultiArrayRange(d), destMultiArray(r2),
+                            (Param(3.0)*Arg1())*Param(6.0));
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+
+        r1 = sqrt(b);
+        rv = sqrt(bv);
+        r4.transpose() = sqrt(b.transpose());
+        r5 = sqrt(b.transpose());
+        transformMultiArray(srcMultiArrayRange(b), destMultiArray(r2),
+                            sqrt(Arg1()));
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+        shouldEqualSequence(r4.begin(), r4.end(), r2.begin());
+        shouldEqualSequence(r2.begin(), r2.end(), r5.transpose().begin());
+
+        r1 = sqrt(-d);
+        rv = sqrt(-dv);
+        transformMultiArray(srcMultiArrayRange(d), destMultiArray(r2),
+                            sqrt(-Arg1()));
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+        r1 = sqrt(b)*d;
+        rv = sqrt(bv)*dv;
+        combineTwoMultiArrays(srcMultiArrayRange(b), srcMultiArray(d), destMultiArray(r2),
+                              sqrt(Arg1())*Arg2());
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+        r1 = d*sqrt(b);
+        rv = dv*sqrt(bv);
+        combineTwoMultiArrays(srcMultiArrayRange(b), srcMultiArray(d), destMultiArray(r2),
+                              Arg2()*sqrt(Arg1()));
+        shouldEqualSequenceTolerance(r1.begin(), r1.end(), r2.begin(), 1e-15);
+        shouldEqualSequenceTolerance(rv.begin(), rv.end(), r2.begin(), 1e-15);
+
+        r1 = sqrt(b)*(d*2.0);
+        rv = sqrt(bv)*(dv*2.0);
+        combineTwoMultiArrays(srcMultiArrayRange(b), srcMultiArray(d), destMultiArray(r2),
+                              sqrt(Arg1())*(Arg2()*Param(2.0)));
+        shouldEqualSequenceTolerance(r1.begin(), r1.end(), r2.begin(), 1e-15);
+        shouldEqualSequenceTolerance(rv.begin(), rv.end(), r2.begin(), 1e-15);
+
+        r1 = (d*2.0)*sqrt(b);
+        rv = (dv*2.0)*sqrt(bv);
+        combineTwoMultiArrays(srcMultiArrayRange(b), srcMultiArray(d), destMultiArray(r2),
+                              (Arg2()*Param(2.0))*sqrt(Arg1()));
+        shouldEqualSequenceTolerance(r1.begin(), r1.end(), r2.begin(), 1e-15);
+        shouldEqualSequenceTolerance(rv.begin(), rv.end(), r2.begin(), 1e-15);
+
+
+        r1 = b*(-c);
+        rv = bv*(-cv);
+        combineTwoMultiArrays(srcMultiArrayRange(b), srcMultiArray(c), destMultiArray(r2),
+                              Arg1()*(-Arg2()));
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+        r1 = b*c*d;
+        rv = bv*cv*dv;
+        combineThreeMultiArrays(srcMultiArrayRange(b), srcMultiArray(c), srcMultiArray(d), destMultiArray(r2),
+                                Arg1()*Arg2()*Arg3());
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+        r1 = sqrt(b)*c*d*b;
+        rv = sqrt(bv)*cv*dv*bv;
+        combineThreeMultiArrays(srcMultiArrayRange(b), srcMultiArray(c), srcMultiArray(d), destMultiArray(r2),
+                                sqrt(Arg1())*Arg2()*Arg3()*Arg1());
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+
+        r1 = (b*c)*2.0*(abs(d)*b);
+        rv = (bv*cv)*2.0*(abs(dv)*bv);
+        combineThreeMultiArrays(srcMultiArrayRange(b), srcMultiArray(c), srcMultiArray(d), destMultiArray(r2),
+                                (Arg1()*Arg2())*Param(2.0)*(abs(Arg3())*Arg1()));
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+        shouldEqualSequence(rv.begin(), rv.end(), r2.begin());
+    
+        shouldEqual(sum(b+0.5, 0.0), 300.0);
+        shouldEqual(sum<double>(b+0.5), 300.0);
+        shouldEqual(sum<double>(b), 288.0);
+
+        shouldEqual(product(b.subarray(Shape3(1,0,0), Shape3(2,2,2))+0.5, 1.0), 3024.0);
+        shouldEqual(product<double>(b.subarray(Shape3(1,0,0), Shape3(2,2,2))+0.5), 3024.0);
+        shouldEqual(product<double>(MultiArray<3, float>(shape3)), 0.0);
+
+        should(all(b > 0.0));
+        should(!all(b > 10.0));
+
+        should(any(b > 10.0));
+        should(!any(b > 100.0));
+
+        try 
+        {
+            array3_type fails(shape3_type(2, 7, 6));
+            r1 = b * fails;
+            failTest("shape mismatch exception not thrown");
+        }
+        catch(PreconditionViolation & e)
+        {
+            std::string expected("\nPrecondition violation!\nmulti_math: shape mismatch in expression.\n"),
+                        actual(e.what());
+            shouldEqual(actual.substr(0, expected.size()), expected);
+        }
+    }
+
+#define VIGRA_TEST_UNARY_FUNCTION(FCT, RHS) \
+        r1 = FCT(RHS); \
+        for(int k=0; k<r2.size(); ++k) \
+            r2[k] = FCT(RHS[k]); \
+        shouldEqualSequence(r2.begin(), r2.end(), r1.begin()); 
+
+#define VIGRA_TEST_BINARY_FUNCTION(FCT, MFCT, V1, V2) \
+        r1 = MFCT(V1, V2); \
+        for(int k=0; k<r2.size(); ++k) \
+            r2[k] = FCT(V1[k], V2[k]); \
+        shouldEqualSequence(r2.begin(), r2.end(), r1.begin()); 
+
+#define VIGRA_TEST_BINARY_OPERATOR(OP, V1, V2) \
+        r1 = V1 OP V2; \
+        for(int k=0; k<r2.size(); ++k) \
+            r2[k] = V1[k] OP V2[k]; \
+        shouldEqualSequence(r2.begin(), r2.end(), r1.begin()); 
+
+    void testAllFunctions()
+    {
+        using namespace vigra::multi_math;
+
+        MultiArray<3, unsigned int> i(r2.shape()), j(r2.shape());
+        linearSequence(i.begin(), i.end());
+        j.init(2);
+
+        VIGRA_TEST_UNARY_FUNCTION(-, b)
+        VIGRA_TEST_UNARY_FUNCTION(!, i)
+        VIGRA_TEST_UNARY_FUNCTION(~, i)
+
+        VIGRA_TEST_UNARY_FUNCTION(abs, d)
+        VIGRA_TEST_UNARY_FUNCTION(erf, b)
+        VIGRA_TEST_UNARY_FUNCTION(even, i)
+        VIGRA_TEST_UNARY_FUNCTION(odd, i)
+        VIGRA_TEST_UNARY_FUNCTION(sign, d)
+        VIGRA_TEST_UNARY_FUNCTION(signi, b)
+        VIGRA_TEST_UNARY_FUNCTION(sq, b)
+        VIGRA_TEST_UNARY_FUNCTION(norm, d)
+        VIGRA_TEST_UNARY_FUNCTION(squaredNorm, d)
+        VIGRA_TEST_UNARY_FUNCTION(vigra::multi_math::round, b)
+        VIGRA_TEST_UNARY_FUNCTION(roundi, b)
+        VIGRA_TEST_UNARY_FUNCTION(sqrti, i)
+        VIGRA_TEST_UNARY_FUNCTION(sin_pi, b)
+        VIGRA_TEST_UNARY_FUNCTION(cos_pi, b)
+        VIGRA_TEST_UNARY_FUNCTION(vigra::multi_math::gamma, b)
+        VIGRA_TEST_UNARY_FUNCTION(loggamma, b)
+        VIGRA_TEST_UNARY_FUNCTION(sqrt, b)
+        VIGRA_TEST_UNARY_FUNCTION(exp, b)
+        VIGRA_TEST_UNARY_FUNCTION(log, b)
+        VIGRA_TEST_UNARY_FUNCTION(log10, b)
+        VIGRA_TEST_UNARY_FUNCTION(sin, b)
+        VIGRA_TEST_UNARY_FUNCTION(asin, a)
+        VIGRA_TEST_UNARY_FUNCTION(cos, b)
+        VIGRA_TEST_UNARY_FUNCTION(acos, a)
+        VIGRA_TEST_UNARY_FUNCTION(tan, b)
+        VIGRA_TEST_UNARY_FUNCTION(atan, b)
+        VIGRA_TEST_UNARY_FUNCTION(floor, b)
+        VIGRA_TEST_UNARY_FUNCTION(ceil, b)
+
+        VIGRA_TEST_BINARY_FUNCTION(atan2, atan2, b, c)
+        VIGRA_TEST_BINARY_FUNCTION(pow, pow, b, c)
+        VIGRA_TEST_BINARY_FUNCTION(fmod, fmod, b, c)
+        VIGRA_TEST_BINARY_FUNCTION(std::min, minimum, b, c)
+        VIGRA_TEST_BINARY_FUNCTION(std::max, maximum, b, c)
+        VIGRA_TEST_BINARY_FUNCTION(std::min, multi_math::min, b, c)
+        VIGRA_TEST_BINARY_FUNCTION(std::max, multi_math::max, b, c)
+
+        VIGRA_TEST_BINARY_OPERATOR(+, b, c)
+        VIGRA_TEST_BINARY_OPERATOR(-, b, c)
+        VIGRA_TEST_BINARY_OPERATOR(*, b, c)
+        VIGRA_TEST_BINARY_OPERATOR(/, b, c)
+        VIGRA_TEST_BINARY_OPERATOR(%, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(&&, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(||, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(==, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(!=, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(<, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(<=, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(>, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(>=, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(<<, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(>>, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(&, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(|, i, j)
+        VIGRA_TEST_BINARY_OPERATOR(^, i, j)
+    }
+
+#undef VIGRA_TEST_UNARY_FUNCTION
+#undef VIGRA_TEST_BINARY_FUNCTION
+#undef VIGRA_TEST_BINARY_OPERATOR
+
+    void testMixedExpressions()
+    {
+        using namespace vigra::multi_math;
+
+        r1 = 2.0 + b;
+        r2 = 2 + b;
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+
+        MultiArray<3, int> i(r2.shape());
+
+        i = 2 + c;
+        r1 = i;
+        r2 = 2 + c;
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+    }
+
+    void testComputedAssignment()
+    {
+        using namespace vigra::multi_math;
+        shouldEqual(r1.size(), 0);
+        r1 += sq(b);
+        rv.init(0.0);
+        rv += sq(b);
+        r2 = sq(b);
+        shouldEqual(r1.size(), 24);
+        shouldEqualSequence(r2.begin(), r2.end(), r1.begin());
+        shouldEqualSequence(r2.begin(), r2.end(), rv.begin());
+
+        r1 *= sq(b);
+        rv *= sq(b);
+        r2 = r2 * sq(b);
+        shouldEqualSequence(r2.begin(), r2.end(), r1.begin());
+        shouldEqualSequence(r2.begin(), r2.end(), rv.begin());
+
+        r1 -= sq(b);
+        rv -= sq(b);
+        r2 = r2 - sq(b);
+        shouldEqualSequence(r2.begin(), r2.end(), r1.begin());
+        shouldEqualSequence(r2.begin(), r2.end(), rv.begin());
+
+        r1 /= sq(b);
+        rv /= sq(b);
+        r2 = r2 / sq(b);
+        shouldEqualSequence(r2.begin(), r2.end(), r1.begin());
+        shouldEqualSequence(r2.begin(), r2.end(), rv.begin());
+    }
+
+    void testNonscalarValues()
+    {
+        using namespace vigra::multi_math;
+        using namespace vigra::functor;
+
+        typedef std::complex<double> C;
+        MultiArray<3, C> q(r2.shape()), qr(q.shape()), qref(q.shape());
+        linearSequence(q.begin(), q.end(), 1.0);
+
+        qr = -q;
+        transformMultiArray(srcMultiArrayRange(q), destMultiArray(qref),
+                            -Arg1());
+        shouldEqualSequence(qref.begin(), qref.end(), qr.begin());
+        shouldEqual(qr[0], C(-1.0));
+
+        qr = C(2.0, -2.0)*q;
+        transformMultiArray(srcMultiArrayRange(q), destMultiArray(qref),
+                            Param(C(2.0, -2.0))*Arg1());
+        shouldEqualSequence(qref.begin(), qref.end(), qr.begin());
+        shouldEqual(qr[1], C(4.0, -4.0));
+
+        qr = 2.0*q;
+        transformMultiArray(srcMultiArrayRange(q), destMultiArray(qref),
+                            Param(2.0)*Arg1());
+        shouldEqualSequence(qref.begin(), qref.end(), qr.begin());
+        shouldEqual(qr[1], C(4.0));
+
+        typedef RGBValue<int> R;
+        MultiArray<3, R> r(r2.shape()), rr(q.shape()), rref(q.shape());
+        linearSequence(r.begin(), r.end(), 1);
+
+        rr = sq(r);
+        transformMultiArray(srcMultiArrayRange(r), destMultiArray(rref),
+                            sq(Arg1()));
+        shouldEqualSequence(rref.begin(), rref.end(), rr.begin());
+        shouldEqual(rr[1], R(4));
+
+        rr = R(2)*r;
+        transformMultiArray(srcMultiArrayRange(r), destMultiArray(rref),
+                            Param(R(2))*Arg1());
+        shouldEqualSequence(rref.begin(), rref.end(), rr.begin());
+        shouldEqual(rr[0], R(2));
+
+        rr = 4.0*r;
+        transformMultiArray(srcMultiArrayRange(r), destMultiArray(rref),
+                            Param(4.0)*Arg1());
+        shouldEqualSequence(rref.begin(), rref.end(), rr.begin());
+        shouldEqual(rr[0], R(4));
+    }
+
+    void testExpandMode()
+    {
+        using namespace vigra::multi_math;
+        using namespace vigra::functor;
+
+        array3_type s(shape3_type(1,1,1));
+        s.init(3.0);
+
+        r1 = s*d;
+        transformMultiArray(srcMultiArrayRange(d), destMultiArray(r2),
+                            Param(3.0)*Arg1());
+        shouldEqualSequence(r1.begin(), r1.end(), r2.begin());
+
+        MultiArray<1, double> ss(Shape1(d.shape(1)));
+        linearSequence(ss.begin(), ss.end(), 1.0);
+
+        r1 = ss.insertSingletonDimension(0).insertSingletonDimension(2) + d;
+
+        for(int z=0; z<d.shape(2); ++z)
+            for(int y=0; y<d.shape(1); ++y)
+                for(int x=0; x<d.shape(0); ++x)
+                    shouldEqual(d(x,y,z)+ss(y), r1(x,y,z));
+    }
+
+    void testComplex()
+    {
+        using namespace vigra::multi_math;
+        MultiArray<3, std::complex<double> > ac(a.shape());
+        ac.init(std::complex<double>(3.0, 4.0));
+
+        MultiArray<3, std::complex<double> > bc = conj(ac);
+        for(int z=0; z<bc.shape(2); ++z)
+            for(int y=0; y<bc.shape(1); ++y)
+                for(int x=0; x<bc.shape(0); ++x)
+                    shouldEqual(bc(x,y,z), std::complex<double>(3.0, -4.0));
+
+        bc = ac + ac;
+        for(int z=0; z<bc.shape(2); ++z)
+            for(int y=0; y<bc.shape(1); ++y)
+                for(int x=0; x<bc.shape(0); ++x)
+                    shouldEqual(bc(x,y,z), std::complex<double>(6.0, 8.0));
+
+        a = real(ac);
+        for(int z=0; z<a.shape(2); ++z)
+            for(int y=0; y<a.shape(1); ++y)
+                for(int x=0; x<a.shape(0); ++x)
+                    shouldEqual(a(x,y,z), 3.0);
+
+        a = imag(ac);
+        for(int z=0; z<a.shape(2); ++z)
+            for(int y=0; y<a.shape(1); ++y)
+                for(int x=0; x<a.shape(0); ++x)
+                    shouldEqual(a(x,y,z), 4.0);
+
+        a = abs(ac);
+        for(int z=0; z<a.shape(2); ++z)
+            for(int y=0; y<a.shape(1); ++y)
+                for(int x=0; x<a.shape(0); ++x)
+                    shouldEqual(a(x,y,z), 5.0);
+
+        a = arg(ac);
+        for(int z=0; z<a.shape(2); ++z)
+            for(int y=0; y<a.shape(1); ++y)
+                for(int x=0; x<a.shape(0); ++x)
+                    shouldEqualTolerance(a(x,y,z), std::atan2(4.0, 3.0), 1e-16);
+    }
+
+};
+
+
+struct ImageViewTestSuite
+: public vigra::test_suite
+{
+    ImageViewTestSuite()
+    : vigra::test_suite("ImageViewTestSuite")
+    {
+		add( testCase( &BImageViewTest::testStridedImageView));
+        add( testCase( &BImageViewTest::testBasicImageIterator));
+        add( testCase( &BImageViewTest::testImageIterator));
+        add( testCase( &BImageViewTest::copyImage));
+		add( testCase( &DImageViewTest::testStridedImageView));
+        add( testCase( &DImageViewTest::testBasicImageIterator));
+        add( testCase( &DImageViewTest::testImageIterator));
+        add( testCase( &DImageViewTest::copyImage));
+		add( testCase( &BRGBImageViewTest::testStridedImageView));
+        add( testCase( &BRGBImageViewTest::testBasicImageIterator));
+        add( testCase( &BRGBImageViewTest::testImageIterator));
+        add( testCase( &BRGBImageViewTest::copyImage));
+		add( testCase( &FRGBImageViewTest::testStridedImageView));
+        add( testCase( &FRGBImageViewTest::testBasicImageIterator));
+        add( testCase( &FRGBImageViewTest::testImageIterator));
+        add( testCase( &FRGBImageViewTest::copyImage));
+    }
+};
+
+struct MultiArrayTestSuite
+: public vigra::test_suite
+{
+    MultiArrayTestSuite()
+    : vigra::test_suite("MultiArrayTestSuite")
+    {
+        add( testCase( &MultiArrayTest::test_default_ctor ) );
+        add( testCase( &MultiArrayTest::test_first_ctor ) );
+        add( testCase( &MultiArrayTest::test_second_ctor ) );
+        add( testCase( &MultiArrayTest::test_assignment ) );
+        add( testCase( &MultiArrayTest::test_copy_construction ) );
+        add( testCase( &MultiArrayTest::testShape ) );
+        add( testCase( &MultiArrayTest::test_iterator ) );
+        add( testCase( &MultiArrayTest::test_const_iterator ) );
+        add( testCase( &MultiArrayTest::test_coupled_iterator ) );
+        add( testCase( &MultiArrayTest::test_traverser ) );
+        add( testCase( &MultiArrayTest::test_const_traverser ) );
+        add( testCase( &MultiArrayTest::test_bindOuter ) );
+        add( testCase( &MultiArrayTest::test_bindInner ) );
+        add( testCase( &MultiArrayTest::test_bindInnerAll ) );
+        add( testCase( &MultiArrayTest::test_bindAt ) );
+        add( testCase( &MultiArrayTest::test_bind ) );
+        add( testCase( &MultiArrayTest::test_reshape) );
+        add( testCase( &MultiArrayTest::test_subarray ) );
+        add( testCase( &MultiArrayTest::test_stridearray ) );
+        add( testCase( &MultiArrayTest::test_copy_int_float ) );
+        add( testCase( &MultiArrayTest::test_expandElements ) );
+
+        add( testCase( &MultiImpexTest::testImpex ) );
+#if defined(HasTIFF)
+        add( testCase( &MultiImpexTest::testMultipageTIFF ) );
+#endif
+    }
+};
+
+struct MultiArrayDataTestSuite
+: public vigra::test_suite
+{
+    MultiArrayDataTestSuite()
+    : vigra::test_suite("MultiArrayDataTestSuite")
+    {
+        {
+            typedef int T;
+            add( testCase( &MultiArrayDataTest<T>::testHasData ) );
+            add( testCase( &MultiArrayDataTest<T>::testEquality ) );
+            add( testCase( &MultiArrayDataTest<T>::test_subarray ) );
+            add( testCase( &MultiArrayDataTest<T>::test_stridearray ) );
+            add( testCase( &MultiArrayDataTest<T>::test_bindOuter ) );
+            add( testCase( &MultiArrayDataTest<T>::test_bindInner ) );
+            add( testCase( &MultiArrayDataTest<T>::test_bindAt ) );
+            add( testCase( &MultiArrayDataTest<T>::test_bind ) );
+            add( testCase( &MultiArrayDataTest<T>::test_bind0 ) );
+            add( testCase( &MultiArrayDataTest<T>::testIsUnstrided ) );
+            add( testCase( &MultiArrayDataTest<T>::test_singletonDimension ) );
+            add( testCase( &MultiArrayDataTest<T>::testPermute ) );
+            add( testCase( &MultiArrayDataTest<T>::testMethods ) );
+            add( testCase( &MultiArrayDataTest<T>::testScanOrderAccess ) );
+            add( testCase( &MultiArrayDataTest<T>::testAssignmentAndReset ) );
+            add( testCase( &MultiArrayNavigatorTest::testNavigator ) );
+            add( testCase( &MultiArrayNavigatorTest::testCoordinateNavigator ) );
+        }
+        {
+            typedef Multiband<int> T;
+            add( testCase( &MultiArrayDataTest<T>::testHasData ) );
+            add( testCase( &MultiArrayDataTest<T>::testEquality ) );
+            add( testCase( &MultiArrayDataTest<T>::test_subarray ) );
+            add( testCase( &MultiArrayDataTest<T>::test_stridearray ) );
+            add( testCase( &MultiArrayDataTest<T>::test_bindOuter ) );
+            add( testCase( &MultiArrayDataTest<T>::test_bindInner ) );
+            add( testCase( &MultiArrayDataTest<T>::test_bindAt ) );
+            add( testCase( &MultiArrayDataTest<T>::test_bind ) );
+            add( testCase( &MultiArrayDataTest<T>::test_bind0 ) );
+            add( testCase( &MultiArrayDataTest<T>::testIsStrided ) );
+            add( testCase( &MultiArrayDataTest<T>::test_singletonDimension ) );
+            add( testCase( &MultiArrayDataTest<T>::testPermute ) );
+            add( testCase( &MultiArrayDataTest<T>::testMethods ) );
+            add( testCase( &MultiArrayDataTest<T>::testScanOrderAccess ) );
+            add( testCase( &MultiArrayDataTest<T>::testAssignmentAndReset ) );
+        }
+    }
+};
+
+struct MultiArrayPointOperatorsTestSuite
+: public vigra::test_suite
+{
+  MultiArrayPointOperatorsTestSuite()
+    : vigra::test_suite("MultiArrayPointOperatorsTestSuite")
+    {
+        add( testCase( &MultiArrayPointoperatorsTest::testInit ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testCopy ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testCopyOuterExpansion ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testCopyInnerExpansion ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testTransform ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testTransformOuterExpand ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testTransformInnerExpand ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testTransformOuterReduce ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testTransformInnerReduce ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testCombine2 ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testCombine2OuterExpand ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testCombine2InnerExpand ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testCombine2OuterReduce ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testCombine2InnerReduce ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testCombine3 ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testInitMultiArrayBorder ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testInspect ) );
+        add( testCase( &MultiArrayPointoperatorsTest::testTensorUtilities ) );
+
+        add( testCase( &MultiMathTest::testSpeed ) );
+        add( testCase( &MultiMathTest::testBasicArithmetic ) );
+        add( testCase( &MultiMathTest::testExpandMode ) );
+        add( testCase( &MultiMathTest::testAllFunctions ) );
+        add( testCase( &MultiMathTest::testComputedAssignment ) );
+        add( testCase( &MultiMathTest::testNonscalarValues ) );
+        add( testCase( &MultiMathTest::testMixedExpressions ) );
+        add( testCase( &MultiMathTest::testComplex ) );
+    }
+}; // struct MultiArrayPointOperatorsTestSuite
+
+
+int main(int argc, char ** argv)
+{
+    // run the multi-array testsuite
+    MultiArrayTestSuite test1;
+    int failed = test1.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test1.report() << std::endl;
+
+    // run the multi-array data-testsuite
+    MultiArrayDataTestSuite test1a;
+    failed += test1a.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test1a.report() << std::endl;
+
+    // run the image testsuite
+    ImageViewTestSuite test2;
+    failed += test2.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test2.report() << std::endl;
+
+    // run the multi-array point operator test suite
+    MultiArrayPointOperatorsTestSuite test3;
+    failed += test3.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test3.report() << std::endl;
+    
+    return (failed != 0);
+}
+
+
diff --git a/test/multiconvolution/CMakeLists.txt b/test/multiconvolution/CMakeLists.txt
new file mode 100644
index 0000000..688156c
--- /dev/null
+++ b/test/multiconvolution/CMakeLists.txt
@@ -0,0 +1,5 @@
+VIGRA_ADD_TEST(test_multiconvolution test.cxx LIBRARIES vigraimpex)
+
+VIGRA_ADD_TEST(test_multiconvolution_speed speedtest.cxx)
+
+VIGRA_COPY_TEST_DATA(oi_single.gif)
diff --git a/test/multiconvolution/oi_single.gif b/test/multiconvolution/oi_single.gif
new file mode 100644
index 0000000..f36f218
Binary files /dev/null and b/test/multiconvolution/oi_single.gif differ
diff --git a/test/multiconvolution/speedtest.cxx b/test/multiconvolution/speedtest.cxx
new file mode 100644
index 0000000..9c0554c
--- /dev/null
+++ b/test/multiconvolution/speedtest.cxx
@@ -0,0 +1,387 @@
+// -*- c++ -*-
+// $Id$
+
+#include "vigra/unittest.hxx"
+#include "vigra/multi_array.hxx"
+#include "vigra/multi_pointoperators.hxx"
+//#include "vigra/multi_convolution.hxx"
+#include "vigra/basicimageview.hxx"
+#include "vigra/convolution.hxx" 
+#include "vigra/navigator.hxx"
+#include "vigra/functorexpression.hxx"
+
+#include <ctime>
+
+#define W 100
+#define H 30
+#define D 170
+
+
+using namespace vigra;
+using namespace vigra::functor;
+
+namespace Impls
+{
+
+  /////////////////////////////////////////////////////////////////////////////////////////
+
+template <class SrcIterator, class SrcShape, class SrcAccessor, 
+          class DestIterator, class DestAccessor, class KernelIterator>
+inline void 
+convolveCDR( SrcIterator si, SrcShape const & shape, SrcAccessor src, 
+         DestIterator di, DestAccessor dest, KernelIterator kit)
+{
+    enum { N = 1 + SrcIterator::level };
+
+    typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
+    
+    // temporay array to hold the current line to enable in-place operation
+    ArrayVector<TmpType> tmp;
+
+    typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
+    typedef MultiArrayNavigator<DestIterator, N> DNavigator;
+
+    { // only operate on first dimension here
+        SNavigator snav( si, shape, 0 );
+        DNavigator dnav( di, shape, 0 );        
+
+        for( ; snav.hasMore(); snav++, dnav++ ) 
+        {
+      convolveLine( srcIterRange( snav.begin(), snav.end(), src ),
+            destIter( dnav.begin(), dest ),
+            kernel1d( *kit ) );
+        }
+        ++kit;
+    }
+
+    // operate on further dimensions
+    for( int d = 1; d < N; ++d, ++kit ) 
+    {
+        DNavigator dnav( di, shape, d );
+
+        tmp.resize( shape[d] );
+
+        for( ; dnav.hasMore(); dnav++ ) 
+        {
+             convolveLine( srcIterRange( dnav.begin(), dnav.end(), dest ),
+                           destIter( tmp.begin(), StandardValueAccessor<TmpType>() ),
+                           kernel1d( *kit ) );
+
+             // copy temp result to target object
+             copyLine( tmp.begin(), tmp.end(), StandardConstValueAccessor<TmpType>(),
+                       dnav.begin(), dest);
+        }
+    }
+}
+
+
+
+template <class SrcIterator, class SrcShape, class SrcAccessor, 
+          class DestIterator, class DestAccessor, class KernelIterator>
+inline void convolveCDR( 
+        triple<SrcIterator, SrcShape, SrcAccessor> const & source, 
+        pair<DestIterator, DestAccessor> const & dest, KernelIterator kit )
+{
+  convolveCDR( source.first, source.second, source.third, 
+           dest.first, dest.second, kit );
+}
+
+
+
+
+  /////////////////////////////////////////////////////////////////////////////////////////
+
+template <class SrcIterator, class SrcShape, class SrcAccessor, 
+          class DestIterator, class DestAccessor, class KernelIterator>
+inline void 
+convolveCopyDest( SrcIterator si, SrcShape const & shape, SrcAccessor src, 
+          DestIterator di, DestAccessor dest, KernelIterator kit)
+{
+    enum { N = 1 + SrcIterator::level };
+
+    typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
+    
+    // temporay array to hold the current line to enable in-place operation
+    ArrayVector<TmpType> tmp( shape[0] );
+
+    typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
+    typedef MultiArrayNavigator<DestIterator, N> DNavigator;
+
+    { // only operate on first dimension here
+        SNavigator snav( si, shape, 0 );
+        DNavigator dnav( di, shape, 0 );        
+
+        for( ; snav.hasMore(); snav++, dnav++ ) 
+        {
+      convolveLine( srcIterRange( snav.begin(), snav.end(), src ),
+            destIter( tmp.begin(), StandardValueAccessor<TmpType>() ),
+            kernel1d( *kit ) );
+
+      // copy temp result to target object
+      copyLine( tmp.begin(), tmp.end(), StandardConstValueAccessor<TmpType>(),
+            dnav.begin(), dest);
+        }
+        ++kit;
+    }
+
+    // operate on further dimensions
+    for( int d = 1; d < N; ++d, ++kit ) 
+    {
+        DNavigator dnav( di, shape, d );
+
+        tmp.resize( shape[d] );
+
+        for( ; dnav.hasMore(); dnav++ ) 
+        {
+             convolveLine( srcIterRange( dnav.begin(), dnav.end(), dest ),
+                           destIter( tmp.begin(), StandardValueAccessor<TmpType>() ),
+                           kernel1d( *kit ) );
+
+             // copy temp result to target object
+             copyLine( tmp.begin(), tmp.end(), StandardConstValueAccessor<TmpType>(),
+                       dnav.begin(), dest);
+        }
+    }
+}
+
+
+
+template <class SrcIterator, class SrcShape, class SrcAccessor, 
+          class DestIterator, class DestAccessor, class KernelIterator>
+inline void convolveCopyDest( 
+        triple<SrcIterator, SrcShape, SrcAccessor> const & source, 
+        pair<DestIterator, DestAccessor> const & dest, KernelIterator kit )
+{
+  convolveCopyDest( source.first, source.second, source.third, 
+            dest.first, dest.second, kit );
+}
+
+
+
+
+
+  /////////////////////////////////////////////////////////////////////////////////////////
+
+template <class SrcIterator, class SrcShape, class SrcAccessor, 
+          class DestIterator, class DestAccessor, class KernelIterator>
+inline void 
+convolveCopySrc( SrcIterator si, SrcShape const & shape, SrcAccessor src, 
+         DestIterator di, DestAccessor dest, KernelIterator kit)
+{
+    enum { N = 1 + SrcIterator::level };
+
+    typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote TmpType;
+    
+    // temporay array to hold the current line to enable in-place operation
+    ArrayVector<TmpType> tmp( shape[0] );
+
+    typedef MultiArrayNavigator<SrcIterator, N> SNavigator;
+    typedef MultiArrayNavigator<DestIterator, N> DNavigator;
+
+    { // only operate on first dimension here
+        SNavigator snav( si, shape, 0 );
+        DNavigator dnav( di, shape, 0 );        
+
+        for( ; snav.hasMore(); snav++, dnav++ ) 
+        {
+      // copy source to temp 
+      copyLine( snav.begin(), snav.end(), src,
+            tmp.begin(), StandardValueAccessor<TmpType>() );
+
+      convolveLine( srcIterRange(tmp.begin(), tmp.end(), StandardConstValueAccessor<TmpType>()),
+            destIter(dnav.begin(), dest),
+            kernel1d( *kit ) );
+        }
+        ++kit;
+    }
+
+    // operate on further dimensions
+    for( int d = 1; d < N; ++d, ++kit ) 
+    {
+        DNavigator dnav( di, shape, d );
+
+        tmp.resize( shape[d] );
+
+        for( ; dnav.hasMore(); dnav++ ) 
+        {
+      // copy source to temp 
+      copyLine( dnav.begin(), dnav.end(), dest,
+            tmp.begin(), StandardValueAccessor<TmpType>() );
+
+      convolveLine( srcIterRange(tmp.begin(), tmp.end(), StandardConstValueAccessor<TmpType>()),
+            destIter(dnav.begin(), dest),
+            kernel1d( *kit ) );
+        }
+    }
+}
+
+
+
+template <class SrcIterator, class SrcShape, class SrcAccessor, 
+          class DestIterator, class DestAccessor, class KernelIterator>
+inline void convolveCopySrc( 
+        triple<SrcIterator, SrcShape, SrcAccessor> const & source, 
+        pair<DestIterator, DestAccessor> const & dest, KernelIterator kit )
+{
+  convolveCopySrc( source.first, source.second, source.third, 
+            dest.first, dest.second, kit );
+}
+
+
+
+
+
+  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+} //-- namespace Impls
+
+
+//---------------------------------------------------------------
+
+struct MultiArraySepConvSpeedTest
+{
+  typedef float PixelType;
+  typedef MultiArray<3,PixelType> Image3D;
+  typedef Image3D::difference_type Size3;
+
+  const Size3 size;
+  Image3D img, dst1, dst2, dst3;
+  ArrayVector<vigra::Kernel1D<float> > kernels;
+
+  MultiArraySepConvSpeedTest()
+    : size(W,H,D),
+      img( size ),
+      dst1( size ),
+      dst2( size ),
+      dst3( size ),
+      kernels( 3 )
+  {
+    std::cout <<"   MultiArraySepConvSpeedTest called" << std::endl;
+    const double sigma = 2.3;
+    makeBox( img );
+    kernels[0].initGaussian( sigma );
+    kernels[1].initGaussian( sigma );
+    kernels[2].initGaussian( sigma );
+  }
+
+
+  void testCpySrc( const Image3D &src, Image3D &dst )
+  {
+    Impls::convolveCopySrc( srcMultiArrayRange(src),
+                destMultiArray(dst),
+                kernels.begin() );
+  }
+
+
+  void testCpyDest( const Image3D &src, Image3D &dst )
+  {
+    Impls::convolveCopyDest( srcMultiArrayRange(src),
+                 destMultiArray(dst),
+                 kernels.begin() );
+  }
+
+
+  void testCDR( const Image3D &src, Image3D &dst )
+  {
+    Impls::convolveCDR( srcMultiArrayRange(src),
+            destMultiArray(dst),
+            kernels.begin() );
+  }
+
+
+  void testCorrectness()
+  {
+    testCDR(img,dst1);
+    testCpyDest(img,dst2);
+    testCpySrc(img,dst3);
+
+    //    shouldEqualSequence( dst1.
+  }
+
+
+  /*
+  void speedTest( const char *name, void (MultiArraySepConvSpeedTest::*f)( const Image3D &, Image3D &),
+          const Image3D &src, Image3D &dst )
+  {
+    int t = clock();
+    this->*f( src, dst );
+    t = clock() - t;
+
+    std::cout << "Timed function: " << name << std::endl << "   = " << t  << std::endl;
+  }
+  */
+
+
+#define Speedy(f,name) int t = clock(); f; t = clock() - t;         \
+    std::cout << "Timed function: " << name << std::endl << "   = " << t  << std::endl;
+
+  void test1()
+  {
+    Speedy( testCDR(img,dst1), "testCDR" );
+  }
+
+  void test2()
+  {
+    Speedy( testCpyDest(img,dst2), "testCpyDest" );
+  }
+
+  void test3()
+  {
+    Speedy( testCpySrc(img,dst3), "testCpySrc" );
+  }
+
+
+  void makeBox( Image3D &image )
+  {
+    const int b = 8;
+    const Size3 size = image.shape();
+    const int width = size[0];
+    const int height = size[1];
+    const int depth = size[2];
+    for( int z = 0; z < depth; ++z ) 
+    {
+      for( int y = 0; y < height; ++y ) 
+      {
+        for( int x = 0; x < width; ++x ) 
+        {        
+          Image3D::value_type val = 80;
+
+          if( (x > b) && x < (width-b) &&
+              (y > b) && y < (height-b) &&
+              (z > b)  && z < (depth-b) ) 
+          {
+            val = 220;
+          }
+          image( x, y, z ) = val;
+        }
+      }
+    }
+  }
+
+};
+
+
+struct MultiArraySepConvSpeedTestSuite
+: public vigra::test_suite
+{
+    MultiArraySepConvSpeedTestSuite()
+    : vigra::test_suite("MultiArraySeparableConvolutionTestSuite")
+    {
+        add( testCase( &MultiArraySepConvSpeedTest::test3 ) );
+        add( testCase( &MultiArraySepConvSpeedTest::test1 ) );
+        add( testCase( &MultiArraySepConvSpeedTest::test2 ) );
+        add( testCase( &MultiArraySepConvSpeedTest::testCorrectness ) );
+    }
+};
+
+
+
+
+int main()
+{
+  // run the multi-array separable convolutiontestsuite
+  MultiArraySepConvSpeedTestSuite test1;
+  int failed = test1.run();
+  std::cout << test1.report() << std::endl;
+  return (failed != 0);
+}
diff --git a/test/multiconvolution/test.cxx b/test/multiconvolution/test.cxx
new file mode 100644
index 0000000..9c375c3
--- /dev/null
+++ b/test/multiconvolution/test.cxx
@@ -0,0 +1,1313 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+// -*- c++ -*-
+// $Id$
+
+#include <iostream>
+#include <vector>
+#include <string>
+#include <sstream>
+#include <limits>
+#include <functional>
+#include <cmath>
+
+#include "vigra/unittest.hxx"
+#include "vigra/multi_array.hxx"
+#include "vigra/multi_convolution.hxx"
+#include "vigra/basicimageview.hxx"
+#include "vigra/convolution.hxx" 
+#include "vigra/navigator.hxx"
+#include "vigra/random.hxx"
+
+#include "vigra/impex.hxx"
+#include "vigra/imageinfo.hxx"
+#include "vigra/basicimage.hxx"
+#include "vigra/diff2d.hxx"
+#include "vigra/stdimage.hxx"
+#include "vigra/multi_resize.hxx"
+#include "vigra/separableconvolution.hxx"
+#include "vigra/bordertreatment.hxx"
+
+using namespace vigra;
+using namespace vigra::functor;
+
+struct MultiArraySeparableConvolutionTest
+{
+
+    typedef float PixelType;
+
+    typedef TinyVector<PixelType,3> VectorPixelType;
+    typedef MultiArray<3, VectorPixelType> Image3x3;
+
+    typedef MultiArray<3,PixelType> Image3D;
+    typedef Image3D::difference_type Size3;
+
+    typedef BasicImage<PixelType> Image2D;
+    typedef Image2D::difference_type Size2;
+
+
+    // - - - - - - - - - - - - - - - - - - - - - - - -
+
+    template<class Image>
+    void makeRandom( Image &image )
+    {
+        typedef typename Image::value_type T;
+
+        int size = image.size();
+        for( int k = 0; k < size; ++k ) 
+        {
+            typedef typename NumericTraits<typename Image::value_type>::isIntegral isIntegral;
+            if(isIntegral::value)
+                image[k] = (T)randomMT19937().uniformInt(256);
+            else
+                image[k] = (T)randomMT19937().uniform();
+        }
+    }
+
+    void makeWedge( Image3D &image )
+    {
+        const Size3 shape = image.shape();
+        const int width = shape[0];
+        const int height = shape[1];
+        const int depth = shape[2];
+        for( int z = 0; z < depth; ++z ) 
+        {
+            for( int y = 0; y < height; ++y ) 
+            {
+                for( int x = 0; x < width; ++x ) 
+                {
+                    const Image3D::value_type val = Image3D::value_type(x + y + z);
+                    image( x, y, z ) = val;
+                }
+            }
+        }
+    }
+
+
+    void makeBox( Image3D &image )
+    {
+        const int b = 8;
+        const Size3 shape = image.shape();
+        const int width = shape[0];
+        const int height = shape[1];
+        const int depth = shape[2];
+        for( int z = 0; z < depth; ++z ) 
+        {
+            for( int y = 0; y < height; ++y ) 
+            {
+                for( int x = 0; x < width; ++x ) 
+                {
+                
+                    Image3D::value_type val = 80;
+
+                    if( (x > b) && x < (width-b) &&
+                            (y > b) && y < (height-b) &&
+                            (z > b)    && z < (depth-b) ) 
+                    {
+                        val = 220;
+                    }
+                    image( x, y, z ) = val;
+                }
+            }
+        }
+    }
+    
+    // - - - - - - - - - - - - - - - - - - - - - - - -
+
+    void test_1DValidity( const Image3D &src, float ksize )
+    {
+        Image3D d1( src.shape() );
+        Image3D dn( src.shape() );
+        Image3D dest3( src.shape() );
+
+        for( int d = 0; d < 3; ++d ) 
+        {
+            std::vector<vigra::Kernel1D<float> > kernels( 3 );
+            kernels[d].initGaussianDerivative( ksize, 1 );
+
+            separableConvolveMultiArray( srcMultiArrayRange(src),
+                                         destMultiArray(dn),
+                                         kernels.begin() );
+
+            convolveMultiArrayOneDimension( srcMultiArrayRange(src),
+                                            destMultiArray(d1),
+                                            d,
+                                            kernels[d] );
+ 
+            shouldEqualSequence(    dn.begin(), dn.end(), d1.begin() );
+        }
+
+        for( int d = 0; d < 3; ++d ) 
+        {
+            std::vector<vigra::Kernel1D<float> > kernels( 3 );
+            kernels[d].initGaussianDerivative( ksize, 1 );
+
+            separableConvolveMultiArray(src, dn, kernels.begin());
+
+            convolveMultiArrayOneDimension(src, d1, d, kernels[d] );
+ 
+            shouldEqualSequence(    dn.begin(), dn.end(), d1.begin() );
+        }
+    }
+
+    // - - - - - - - - - - - - - - - - - - - - - - - -
+
+    void test_1DValidityB( const Image3D &src, float ksize )
+    {
+        Image3D dst1( src.shape() );
+        Image3D dst2( src.shape() );
+
+        const int depth = src.shape()[2];
+
+        vigra::Kernel1D<float> kernx;
+        vigra::Kernel1D<float> kerny;
+        kernx.initGaussian( ksize );
+        kerny.initGaussianDerivative( ksize, 1 );
+
+        int z;
+
+        // x convolution
+        convolveMultiArrayOneDimension( srcMultiArrayRange(src),
+                                        destMultiArray(dst1),
+                                        0, kernx );
+
+        for( z = 0; z < depth; ++z ) 
+        {
+            BasicImageView<Image3D::value_type> sslice =
+                makeBasicImageView( src.bindOuter(z) );
+            BasicImageView<Image3D::value_type> dslice =
+                makeBasicImageView( dst2.bindOuter(z) );
+            
+            vigra::separableConvolveX( srcImageRange(sslice), destImage(dslice),
+                                                                 vigra::kernel1d(kernx) );
+        }
+
+        shouldEqualSequence(    dst1.begin(), dst1.end(), dst2.begin() );
+
+
+        // y convolution
+        convolveMultiArrayOneDimension( srcMultiArrayRange(src),
+                                        destMultiArray(dst1),
+                                        1, kerny );
+
+        for( z = 0; z < depth; ++z ) 
+        {
+            BasicImageView<Image3D::value_type> sslice =
+                makeBasicImageView( src.bindOuter(z) );
+            BasicImageView<Image3D::value_type> dslice =
+                makeBasicImageView( dst2.bindOuter(z) );
+            
+            vigra::separableConvolveY( srcImageRange(sslice), destImage(dslice),
+                                                                 vigra::kernel1d(kerny) );
+        }
+
+        shouldEqualSequence(    dst1.begin(), dst1.end(), dst2.begin() );
+    }
+
+    void test_2DValidity( const Image3D &src, float ksize )
+    {
+        Image3D d2( src.shape() );
+        Image3D dn( src.shape() );
+
+        int depth = src.shape()[2];
+
+        std::vector<vigra::Kernel1D<float> > kernels( 3 );
+        kernels[0].initGaussian( ksize );
+        kernels[1].initGaussianDerivative( ksize, 1 );
+
+        for( int z = 0; z < depth; ++z )
+        {
+            BasicImageView<Image3D::value_type> sslice =
+                makeBasicImageView( src.bindOuter(z) );
+            BasicImageView<Image3D::value_type> dslice =
+                makeBasicImageView( d2.bindOuter(z) );
+            
+            vigra::convolveImage( srcImageRange(sslice), destImage(dslice),
+                                    kernels[0], kernels[1] );
+        }
+
+        separableConvolveMultiArray( srcMultiArrayRange(src),
+                                     destMultiArray(dn),
+                                     kernels.begin() );
+
+        shouldEqualSequence( dn.begin(), dn.end(), d2.begin() );
+    }
+
+
+    // - - - - - - - - - - - - - - - - - - - - - - - -
+
+    void test_inplacenessN( const Image3D &src, float ksize )
+    {
+        Image3D da( src.shape() );
+        Image3D db( src.shape() );
+
+        std::vector<vigra::Kernel1D<float> > kernels( 3 );
+        kernels[0].initGaussian( ksize );
+        kernels[1].initGaussianDerivative( ksize, 1 );
+
+        vigra::separableConvolveMultiArray( srcMultiArrayRange(src),
+                                            destMultiArray(da),
+                                            kernels.begin() );
+
+        copyMultiArray(srcMultiArrayRange(src), destMultiArray(db));
+
+        vigra::separableConvolveMultiArray( srcMultiArrayRange(db),
+                                            destMultiArray(db),
+                                            kernels.begin() );
+
+        shouldEqualSequenceTolerance( da.begin(), da.end(),
+                                        db.begin(),
+                                        1e-5 );
+    }
+
+
+    // - - - - - - - - - - - - - - - - - - - - - - - -
+
+    void testSmoothing()
+    {
+        makeRandom(srcImage);
+
+        ArrayVector<Kernel1D<double> > kernels(3);
+        kernels[0].initGaussian(1.0);
+        kernels[1].initAveraging(1);
+        kernels[2].initGaussian(2.0);
+
+        //kernels[1].setBorderTreatment(BORDER_TREATMENT_REFLECT);
+
+        Image3D res(shape);
+        separableConvolveMultiArray(srcMultiArrayRange(srcImage), destMultiArray(res), 
+                                    kernels.begin());
+
+        typedef Shape3 S;
+        int w = shape[0], h = shape[1], d = shape[2];
+        S start[] = { S(0, 0, 25), S(30, 0, 0), S(0, 30, 0), 
+                      S(2, h-1, 20), S(15, 1, d-2), S(2, 14, 1), 
+                      S(0,0,0), S(0, 0, 34), S(0, 12, 0) };
+        S stop[]  = { S(w, h, 26), S(31, h, d), S(w, 31, d), 
+                      S(w-2, h, 30), S(28, h-1, d), S(w-2, 44, d-1), 
+                      S(w,h,d), S(w, 1, 39), S(w-1, 26, 1) };
+        for(int k=0; k<9; ++k)
+        {
+            Image3D subarray(stop[k]-start[k]);
+            separableConvolveMultiArray(srcImage, subarray, 
+                                        kernels.begin(), start[k], stop[k]);
+
+            shouldEqualSequenceTolerance(subarray.begin(), subarray.end(), 
+                                         res.subarray(start[k], stop[k]).begin(), 1e-6);
+        }
+    }
+
+    void test_inplaceness1( const Image3D &src, float ksize, bool useDerivative )
+    {
+        Image3D da( src.shape() );
+        Image3D db( src.shape() );
+
+        Kernel1D<float> kernel;
+        if( ! useDerivative )
+            kernel.initGaussian( ksize );
+        else
+            kernel.initGaussianDerivative( ksize, 1 );
+
+
+        for( int i = 0; i < 3; ++i ) 
+        {
+            const int d = 2-i;
+
+            convolveMultiArrayOneDimension(src, da, d, kernel );
+
+            copyMultiArray(src, db);
+
+            convolveMultiArrayOneDimension(db, db, d, kernel );
+
+            shouldEqualSequence( da.begin(), da.end(), db.begin() );
+        }
+    }
+
+
+    // - - - - - - - - - - - - - - - - - - - - - - - -
+
+    void test_gradient1( const Image3D &base, bool useGaussian )
+    {
+        const double sigma = kernelSize/2;
+        const int b = useGaussian ? int( 0.5 + 3*sigma ) : 1;
+        Image3D src( base.shape() );
+        Image3x3 grad( src.shape() );
+        makeWedge( src );
+
+        if( ! useGaussian )
+            symmetricGradientMultiArray(src, grad);
+        else
+            gaussianGradientMultiArray(src, grad, sigma );
+
+        Image3x3::value_type v;
+        v[0] = 1; v[1] = 1; v[2] = 1;
+        const float v2 = dot(v,v);
+
+        const Size3 shape = src.shape();
+        const int width = shape[0];
+        const int height = shape[1];
+        const int depth = shape[2];
+        for( int z = b; z < depth-b; ++z ) 
+        {
+            for( int y = b; y < height-b; ++y ) 
+            {
+                for( int x = b; x < width-b; ++x ) 
+                {
+                    shouldEqualTolerance( dot(grad(x,y,z), v), v2, 1e-5 );
+                }
+            }
+        }
+
+    }
+
+
+    void test_gradient_magnitude()
+    {
+        using namespace functor;
+        
+        MultiArrayShape<2>::type shape(30,40);
+        int size = shape[0]*shape[1];
+
+        MultiArray<2, double > src(shape), mgrad(shape), rmgrad(shape);
+        MultiArray<2, TinyVector<double, 2> > grad(shape);
+        
+        makeRandom(src);
+        
+        gaussianGradientMagnitude(src, rmgrad, 1.0);
+        gaussianGradientMultiArray(src, grad, 1.0 );
+        transformMultiArray(grad, mgrad, norm(Arg1()));
+
+        shouldEqualSequence(mgrad.data(), mgrad.data()+size, rmgrad.data());
+
+        rmgrad.init(0);
+        gaussianGradientMagnitude(src, rmgrad, 1.0);
+        shouldEqualSequence(mgrad.data(), mgrad.data()+size, rmgrad.data());
+
+        MultiArray<2, TinyVector<double, 3> > rgb(shape);
+        MultiArrayView<3, Multiband<double> > expanded(rgb.expandElements(2));
+       
+        makeRandom(expanded);
+        
+        mgrad.init(0);
+        gaussianGradientMagnitude(srcImageRange(rgb), destImage(mgrad), 1.0);
+        rmgrad.init(0);
+        gaussianGradientMagnitude(rgb, rmgrad, 1.0);
+        shouldEqualSequenceTolerance(mgrad.data(), mgrad.data()+size, rmgrad.data(), 1e-14);
+
+        rmgrad.init(0);
+        gaussianGradientMagnitude<2>(expanded, rmgrad, 1.0);
+        shouldEqualSequenceTolerance(mgrad.data(), mgrad.data()+size, rmgrad.data(), 1e-14);
+
+        MultiArray<3, Multiband<double> > spectral(Shape3(shape[0], shape[1], 10));
+        MultiArrayView<3, Multiband<double> > spectral_expanded(spectral);
+        gaussianGradientMagnitude<2>(spectral_expanded, rmgrad, 1.0);
+    }
+
+    void test_laplacian()
+    {
+        MultiArrayShape<2>::type shape(30,40);
+        int size = shape[0]*shape[1];
+
+        MultiArray<2, double > src(shape), laplacian(shape);
+        MultiArray<2, double> rlaplacian(shape[0], shape[1]);
+        
+        makeRandom(src);
+        
+        laplacianOfGaussian(srcImageRange(src), destImage(rlaplacian), 2.0);
+        laplacianOfGaussianMultiArray(srcMultiArrayRange(src), destMultiArray(laplacian), 2.0 );
+
+        shouldEqualSequenceTolerance(laplacian.data(), laplacian.data()+size, rlaplacian.data(), 1e-12);
+
+        laplacian = 0;
+        laplacianOfGaussianMultiArray(src, laplacian, 2.0 );
+        shouldEqualSequenceTolerance(laplacian.data(), laplacian.data()+size, rlaplacian.data(), 1e-12);
+    }
+
+    void test_divergence()
+    {
+        // test divergence of gradient - theoretically, it equals the Laplacian, but in practice this requires
+        //                               large kernel windows, a high tolerance, and doesn't hold near the border
+        MultiArray<2, double> src;
+        importImage("oi_single.gif", src);
+
+        MultiArray<2, double> laplacian(src.shape()), divergence(src.shape());
+        MultiArray<2, TinyVector<double, 2> > grad(src.shape());
+
+        laplacianOfGaussianMultiArray(src, laplacian, 2.0, ConvolutionOptions<2>().filterWindowSize(5));
+
+        gaussianGradientMultiArray(src, grad, sqrt(2.0), ConvolutionOptions<2>().filterWindowSize(5));
+        gaussianDivergenceMultiArray(grad, divergence, sqrt(2.0), ConvolutionOptions<2>().filterWindowSize(5));
+
+        divergence -= laplacian;
+        MultiArrayView <2, double> center(divergence.subarray(Shape2(10,10), Shape2(-10,-10)));
+
+        using namespace multi_math;
+        should(all(abs(center) < 0.001));
+    }
+
+    void test_hessian()
+    {
+        MultiArrayShape<2>::type shape(30,40);
+        int size = shape[0]*shape[1];
+
+        MultiArray<2, double > src(shape);
+        MultiArray<2, TinyVector<double, 3> > hessian(shape), hessian1(shape);
+        BasicImage<TinyVector<double, 3> > rhessian(shape[0], shape[1]);
+        
+        makeRandom(src);
+        
+        typedef VectorComponentAccessor<TinyVector<double, 3> > BandAccessor;
+        hessianMatrixOfGaussian(srcImageRange(src), 
+                                destImage(rhessian, BandAccessor(0)), 
+                                destImage(rhessian, BandAccessor(1)), 
+                                destImage(rhessian, BandAccessor(2)), 
+                                2.0);
+        hessianOfGaussianMultiArray(srcMultiArrayRange(src), destMultiArray(hessian), 2.0 );
+
+        TinyVector<double, 3> epsilon(1e-12, 1e-12, 1e-12);
+        shouldEqualSequenceTolerance(hessian.data(), hessian.data()+size, rhessian.data(), epsilon);
+
+        hessianOfGaussianMultiArray(src, hessian1, 2.0 );
+        shouldEqualSequenceTolerance(hessian1.data(), hessian1.data()+size, rhessian.data(), epsilon);
+    }
+
+    void test_structureTensor()
+    {
+        MultiArrayShape<2>::type shape(30,40);
+        int size = shape[0]*shape[1];
+
+        MultiArray<2, double > src(shape);
+        MultiArray<2, TinyVector<double, 3> > st(shape), st1(shape);
+        BasicImage<TinyVector<double, 3> > rst(shape[0], shape[1]);
+        
+        makeRandom(src);
+        
+        typedef VectorComponentAccessor<TinyVector<double, 3> > BandAccessor;
+        structureTensor(srcImageRange(src), 
+                        destImage(rst, BandAccessor(0)), 
+                        destImage(rst, BandAccessor(1)), 
+                        destImage(rst, BandAccessor(2)), 
+                        1.5, 3.0);
+        structureTensorMultiArray(srcMultiArrayRange(src), destMultiArray(st), 1.5, 3.0 );
+
+        TinyVector<double, 3> epsilon(1e-12, 1e-12, 1e-12);
+        shouldEqualSequenceTolerance(st.data(), st.data()+size, rst.data(), epsilon);
+
+        structureTensorMultiArray(src, st1, 1.5, 3.0 );
+        shouldEqualSequenceTolerance(st1.data(), st1.data()+size, rst.data(), epsilon);
+    }
+
+    //--------------------------------------------
+
+    const Size3 shape;
+    Image3D srcImage;
+    const float kernelSize;
+
+    MultiArraySeparableConvolutionTest()
+        : shape( 60, 70, 50 ),
+            srcImage( shape ),
+            kernelSize( 1.8f )
+    {
+        makeBox( srcImage );
+    }
+
+
+    void test_Valid1() 
+    {
+        test_1DValidity( srcImage, kernelSize );
+    }
+
+    void test_Valid3() 
+    {
+     test_1DValidityB( srcImage, kernelSize );
+    }
+
+    void test_Valid2() 
+    {
+        test_2DValidity( srcImage, kernelSize );
+    }
+
+    void test_InplaceN() 
+    {
+        test_inplacenessN( srcImage, kernelSize );
+    }
+
+    void test_Inplace1() 
+    {
+        test_inplaceness1( srcImage, kernelSize, false );
+        test_inplaceness1( srcImage, kernelSize, true );
+    }
+
+    void test_gradient1() 
+    {
+        test_gradient1( srcImage, false );
+        test_gradient1( srcImage, true );
+    }
+};                //-- struct MultiArraySeparableConvolutionTest
+
+//--------------------------------------------------------
+
+struct MultiArraySeparableConvolutionTestSuite
+: public vigra::test_suite
+{
+    MultiArraySeparableConvolutionTestSuite()
+        : vigra::test_suite("MultiArraySeparableConvolutionTestSuite")
+        {
+                add( testCase( &MultiArraySeparableConvolutionTest::test_Valid1 ) );
+                add( testCase( &MultiArraySeparableConvolutionTest::test_Valid2 ) );
+                add( testCase( &MultiArraySeparableConvolutionTest::test_Valid3 ) );
+                add( testCase( &MultiArraySeparableConvolutionTest::test_InplaceN ) );
+                add( testCase( &MultiArraySeparableConvolutionTest::test_Inplace1 ) );
+                add( testCase( &MultiArraySeparableConvolutionTest::testSmoothing ) );
+                add( testCase( &MultiArraySeparableConvolutionTest::test_gradient1 ) );
+                add( testCase( &MultiArraySeparableConvolutionTest::test_laplacian ) );
+                add( testCase( &MultiArraySeparableConvolutionTest::test_divergence ) );
+                add( testCase( &MultiArraySeparableConvolutionTest::test_hessian ) );
+                add( testCase( &MultiArraySeparableConvolutionTest::test_structureTensor ) );
+                add( testCase( &MultiArraySeparableConvolutionTest::test_gradient_magnitude ) );
+    }
+}; // struct MultiArraySeparableConvolutionTestSuite
+
+//--------------------------------------------------------
+
+typedef double pixel_type;
+
+typedef vigra::MultiArrayShape<2>::type                         shape_2d;
+typedef vigra::MultiArray<2, pixel_type>                        array_2d;
+typedef vigra::MultiArray<2, vigra::TinyVector<pixel_type, 2> > grad_2d;
+typedef vigra::MultiArray<2, vigra::TinyVector<pixel_type, 3> > symm_2d;
+typedef vigra::BasicImageView<pixel_type>                       image_2d;
+typedef vigra::ConvolutionOptions<2>                            options_2d;
+
+struct delta_dist
+{
+    double scale;
+    double offset;
+    delta_dist(double s, double of = 0) : scale(std::abs(s)), offset(of) {}
+    template<class V>
+    double operator()(V a, V b) const
+    {
+        double delta = std::abs(double(a) - double(b));
+        if (offset == 0)
+            return delta;
+        else
+            return offset - delta;
+    }
+};
+
+struct rel_dist
+{
+    double scale;
+    double offset;
+    rel_dist(double s, double of = 0) : scale(std::abs(s)), offset(of) {}
+    template<class V>
+    double operator()(V a, V b) const
+    {
+        double delta = std::abs((double(a) - double(b)) / double(a));
+        if (offset == 0)
+            return delta;
+        else
+            return offset - delta;
+    }
+};
+
+struct logger
+{
+    const bool do_log;
+    std::ostringstream os;
+
+    logger(bool d = true) : do_log(d) {}
+
+    operator bool()
+    {
+        return do_log;
+    }
+
+    void next()
+    {
+        if(os.str().size())
+            os << ", ";
+    }
+
+    void operator()(const std::string & msg)
+    {
+        next();
+        os << msg;
+    }
+    template<class X>
+    void operator()(const std::string & name, const X & value)
+    {
+        next();
+        os << name << " = " << value;
+    }
+
+    std::string str() {
+        return os.str();
+    }
+};
+
+template<class IM>
+double min_max_delta(const IM & image)
+{
+    vigra::FindMinMax<double> minmax;
+    vigra::inspectMultiArray(image, minmax);
+    return minmax.max - minmax.min;
+}
+
+template<class IM>
+double max(const IM & image)
+{
+    vigra::FindMinMax<double> minmax;
+    vigra::inspectMultiArray(image, minmax);
+    return minmax.max;
+}
+
+template<class IM>
+double min(const IM & image)
+{
+    vigra::FindMinMax<double> minmax;
+    vigra::inspectMultiArray(image, minmax);
+    return minmax.min;
+}
+
+template<class IM>
+void write_out(const IM & image, const char *const name, bool do_it = true)
+{
+    if (do_it)
+    {
+        vigra::exportImage(srcImageRange(image),
+                        vigra::ImageExportInfo(name));
+    }
+}
+
+template<class F>
+double compare(F func, const char *const func_name,
+        const array_2d & image_a, const array_2d & image_b,
+        double sigma_pix = 0, const char* name = 0, bool do_it = true) {
+    array_2d delta_image(image_a);
+    vigra::combineTwoMultiArrays(srcMultiArrayRange(image_a),
+                                 srcMultiArray(image_b),
+                                 destMultiArray(delta_image),
+                                 func);
+
+    // crop off border artifacts
+    image_2d image_view_delta = vigra::makeBasicImageView(delta_image);
+    // accounting for x step size by using "pixel" counts ...
+    int crop = 1 + int(3 * sigma_pix + 0.5);
+    int wcrop = image_view_delta.width() - 2 * crop;
+    shouldMsg(wcrop > 1, ("no width left after std. dev. crop at"
+            " borders, width = " + asString(wcrop)).c_str());
+
+    array_2d delta_cropped(shape_2d(wcrop, image_view_delta.height()));
+    copyImage(srcIterRange(
+        image_view_delta.upperLeft() + vigra::Diff2D(crop, 0),
+        image_view_delta.lowerRight() - vigra::Diff2D(crop, 0)),
+        destImage(delta_cropped));
+
+    if (!name)
+        name = func_name;
+    write_out(delta_cropped, name, do_it);
+
+    return max(delta_cropped);
+}
+
+void resize_0(const array_2d & a, array_2d & b)
+{
+    vigra::resizeImageNoInterpolation(srcImageRange(a), destImageRange(b));
+}
+template<unsigned order>
+void resize_n(const array_2d & a, array_2d & b)
+{
+    typedef typename vigra::BSpline<order, double> my_spline;
+
+    if(order <=3) // arbitrarily use the different APIs for small and large orders
+        vigra::resizeMultiArraySplineInterpolation(srcMultiArrayRange(a),
+                                                   destMultiArrayRange(b),
+                                                   my_spline());
+    else
+        vigra::resizeMultiArraySplineInterpolation(a, b, my_spline());
+}
+
+struct t_func
+{
+    static const double zeros[2]; // = { 0, 0 };
+    virtual double operator()(array_2d & image, const options_2d & opt) const = 0;
+    virtual double operator()(array_2d & image,
+                              const double sigma_d[2],
+                              const double step_size[2]) const
+    {
+        // test various ways to create option setter functions.
+        options_2d opt;
+        opt.resolutionStdDev(sigma_d).stepSize(step_size);
+        std::vector<double> vstep;
+        vstep.push_back(step_size[0]);
+        vstep.push_back(step_size[1]);
+        opt.resolutionStdDev(sigma_d).stepSize((const double *const)step_size);
+        opt.resolutionStdDev(sigma_d).stepSize(vstep);
+
+        return operator()(image, opt);
+    }
+    virtual double operator()(array_2d & test_image, double im_scale) const
+    {
+        double w[2] = { 1.0 / im_scale, 1 };
+        return operator()(test_image, zeros, w);
+    }
+    virtual double operator()(array_2d & image) const
+    {
+        return operator()(image, 1);
+    }
+    virtual std::string name() const = 0;
+    virtual void log(logger & log_write) const
+    {
+        log_write("test operator", name());
+    }
+    virtual ~t_func() {}
+};
+const double t_func::zeros[2] = { 0, 0 };
+
+struct gsmaa_f : public t_func
+{
+    double sigma;
+    gsmaa_f(double s) : sigma(s) {}
+    std::string name() const {
+        return "gaussianSmoothMultiArray";
+    }
+    double operator()(array_2d & test_image,  const options_2d & opt) const
+    {
+        vigra::gaussianSmoothMultiArray(vigra::srcMultiArrayRange(test_image),
+                                        vigra::destMultiArray(test_image),
+                                        sigma, opt);
+        return sigma;
+    }
+};
+
+struct ggma_f : public t_func
+{
+    double sigma;
+    int axis;
+    ggma_f(double s, int a) : sigma(s), axis(a) {}
+    std::string name() const
+    {
+        return "gaussianGradientMultiArray, axis " + asString(axis);
+    }
+    double operator()(array_2d & test_image,  const options_2d & opt) const {
+
+        grad_2d grad_data(test_image.shape());
+        vigra::gaussianGradientMultiArray(vigra::srcMultiArrayRange(test_image),
+                                          vigra::destMultiArray(grad_data),
+                                          sigma, opt);
+        // copy gradient #axis to image:
+        typedef grad_2d::value_type value_type;
+        typedef vigra::VectorComponentAccessor<value_type> accessor;
+        vigra::copyMultiArray(vigra::srcMultiArrayRange(grad_data, accessor(axis)),
+                              vigra::destMultiArray(test_image));
+        return sigma;
+    }
+};
+
+struct sgma_f : public t_func {
+    int axis;
+    sgma_f(int a) : axis(a) {}
+    std::string name() const {
+        return "symmetricGradientMultiArray, axis " + asString(axis);
+    }
+    double operator()(array_2d & test_image,  const options_2d & opt) const
+    {
+        grad_2d grad_data(test_image.shape());
+        vigra::symmetricGradientMultiArray(
+                                          vigra::srcMultiArrayRange(test_image),
+                                          vigra::destMultiArray(grad_data),
+                                          opt);
+
+        // copy gradient #axis to image:
+        typedef grad_2d::value_type value_type;
+        typedef vigra::VectorComponentAccessor<value_type> accessor;
+        vigra::copyMultiArray(vigra::srcMultiArrayRange(grad_data, accessor(axis)),
+                              vigra::destMultiArray(test_image));
+        return 0;
+    }
+};
+
+struct lgma_f : public t_func
+{
+    double sigma;
+    lgma_f(double s) : sigma(s) {}
+    std::string name() const {
+        return "laplacianOfGaussianMultiArray";
+    }
+    double operator()(array_2d & test_image,  const options_2d & opt) const
+    {
+        array_2d dest_image(test_image);
+        vigra::laplacianOfGaussianMultiArray(
+                                          vigra::srcMultiArrayRange(test_image),
+                                          vigra::destMultiArray(dest_image),
+                                          sigma, opt);
+        // copy result to image:
+        vigra::copyMultiArray(vigra::srcMultiArrayRange(dest_image),
+                              vigra::destMultiArray(test_image));
+        return sigma;
+    }
+};
+
+struct hgma_f : public t_func
+{
+    double sigma;
+    int entry;
+    hgma_f(double s, int e) : sigma(s), entry(e) {}
+    std::string name() const
+    {
+        return "hessianOfGaussianMultiArray, entry " + asString(entry);
+    }
+    double operator()(array_2d & test_image,  const options_2d & opt) const
+    {
+        symm_2d hess_data(test_image.shape());
+        vigra::hessianOfGaussianMultiArray(
+                                          vigra::srcMultiArrayRange(test_image),
+                                          vigra::destMultiArray(hess_data),
+                                          sigma, opt);
+        // copy hessian entry to image:
+        typedef symm_2d::value_type value_type;
+        typedef vigra::VectorComponentAccessor<value_type> accessor;
+        vigra::copyMultiArray(vigra::srcMultiArrayRange(hess_data, accessor(entry)),
+                              vigra::destMultiArray(test_image));
+        return sigma;
+    }
+};
+
+struct stma_f : public t_func
+{
+    double inner;
+    double outer;
+    int entry;
+    stma_f(double in, double out, int e) : inner(in), outer(out), entry(e) {}
+    std::string name() const
+    {
+        return "structureTensorMultiArray, entry " + asString(entry);
+    }
+    double operator()(array_2d & test_image,  const options_2d & opt) const
+    {
+
+        symm_2d st_data(test_image.shape());
+        vigra::structureTensorMultiArray(vigra::srcMultiArrayRange(test_image),
+                                         vigra::destMultiArray(st_data),
+                                         inner, outer, opt);
+        // copy st entry to image:
+        typedef symm_2d::value_type value_type;
+        typedef vigra::VectorComponentAccessor<value_type> accessor;
+        vigra::copyMultiArray(vigra::srcMultiArrayRange(st_data, accessor(entry)),
+                              vigra::destMultiArray(test_image));
+        return std::sqrt(inner * inner + outer * outer);
+    }
+};
+
+const t_func * new_test_alloc(double sigma, double outer, int test_nr)
+{
+    switch (test_nr)
+    {
+    case 0:
+            return new gsmaa_f(sigma);
+    case 1:
+            return new ggma_f(sigma, 0);
+    case 2:
+            return new ggma_f(sigma, 1);
+    case 11:
+            return new sgma_f(0);
+    case 12:
+            return new sgma_f(1);
+    case 20:
+            return new lgma_f(sigma);
+    case 21:
+            return new hgma_f(sigma, 0);
+    case 22:
+            return new hgma_f(sigma, 1);
+    case 23:
+            return new hgma_f(sigma, 2);
+    case 31:
+            return new stma_f(sigma, outer, 0);
+    case 32:
+            return new stma_f(sigma, outer, 1);
+    case 33:
+            return new stma_f(sigma, outer, 2);
+        }
+    return 0;
+}
+
+const t_func * new_test(double sigma, double outer, int test_nr,
+                                                              logger & log_name)
+{
+    const t_func *const test = new_test_alloc(sigma, outer, test_nr);
+    if (test)
+        test->log(log_name);
+    else
+        log_name("[no test operator found in new_test_alloc()]");
+    return test;
+}
+
+struct cmp_double
+{
+    double tol;
+    cmp_double(double t) : tol(t) {}
+    void check(double val) const
+    {
+        shouldMsg(!tol || (std::abs(val) <= tol),
+                  ("relative difference above tolerance: "
+                  "accepted = " + asString(tol) +
+                  ", actual = " + asString(val)).c_str());
+    }
+};
+
+struct cmp_data
+{
+    bool write_im;
+    cmp_double global_tol;
+    cmp_double local_tol;
+    cmp_data(bool w, double glob, double loc)
+        : write_im(w), global_tol(glob), local_tol(loc) {}
+    operator bool() const
+    {
+        return write_im;
+    }
+};
+
+void test_compare(const array_2d & x1_image_b, const array_2d & res_image,
+                  double sigma_pix, const cmp_data & cmp,
+                  logger & log_write)
+{
+    double mm_delta = min_max_delta(x1_image_b);
+
+    double dist = compare(delta_dist(1), "delta_dist",
+                          res_image, x1_image_b, sigma_pix,
+                          "delta_dist_im.png", cmp);
+    double rel = compare(rel_dist(1), "rel_dist", res_image, x1_image_b, sigma_pix,
+                         "rel_dist_im.png", cmp);
+
+    log_write("globally relative error", dist / mm_delta);
+    log_write("locally relative error", rel);
+    cmp.global_tol.check(dist / mm_delta);
+    cmp.local_tol.check(rel);
+}
+
+unsigned resized(double scale, int size)
+{
+    return static_cast<unsigned>(std::floor(1 + scale * (size - 1)));
+}
+
+shape_2d resized_shape(const vigra::ImageImportInfo & size_info, double scale_x,
+                       double scale_y)
+{
+    return shape_2d(resized(scale_x, size_info.width()),
+                    resized(scale_y, size_info.height()));
+}
+
+void test_upscaled(void (*resize)(const array_2d &, array_2d &),
+                   const vigra::ImageImportInfo & size_info,
+                   const array_2d & test_image,
+                   const t_func & test_f,
+                   double im_scale, const cmp_data & cmp,
+                   logger & log_write, logger & log_name)
+{
+
+    log_name("upscaled test");
+    if (log_name)
+        return;
+    // image inflated by im_scale in x direction:
+    array_2d x_scaled_image(resized_shape(size_info, im_scale, 1));
+    (*resize)(test_image, x_scaled_image);
+
+    write_out(x_scaled_image, "test_any_scaled.png", cmp);
+    double sigma = test_f(x_scaled_image, im_scale);
+
+    write_out(x_scaled_image, "test_any_scaled_new_f.png", cmp);
+
+    array_2d x1_image_b(test_image);
+    test_f(x1_image_b);
+    write_out(x1_image_b, "test_any_old_f.png", cmp);
+
+    // compare with resampled image
+    array_2d res_image(test_image);
+    (*resize)(x_scaled_image, res_image);
+    write_out(res_image, "test_any_res_f.png", cmp);
+
+    test_compare(x1_image_b, res_image, sigma, cmp, log_write);
+}
+
+void test_downscaled(void (*resize)(const array_2d &, array_2d &),
+                     const vigra::ImageImportInfo & size_info,
+                     const array_2d & m2_image_old,
+                     const t_func & test_f,
+                     double im_scale, const cmp_data & cmp,
+                     logger & log_write, logger & log_name)
+{
+    const double y_scale = 3;
+    const double x_scale = im_scale * y_scale;
+    log_name("downscaled test (factor " + asString(y_scale) + ")");
+    if (log_name)
+        return;
+
+    int w = (int(size_info.width() - 1) / int(x_scale)) * int(x_scale) + 1;
+    int h = (int(size_info.height() - 1) / int(y_scale)) * int(y_scale) + 1;
+
+    array_2d test_image(shape_2d(w, h));
+    (*resize)(m2_image_old, test_image);
+
+    // pre-sample image with gaussian, std. dev. == scale:
+    const double std_dev_factor = 1;
+    array_2d pre_scale_image(test_image);
+    double sigmas[2] = { 0, 0 };
+    sigmas[0] = std_dev_factor * x_scale;
+    sigmas[1] = std_dev_factor * y_scale;
+    vigra::gaussianSmoothMultiArray(test_image, pre_scale_image,
+                                    options_2d().stdDev(sigmas));
+    // downscale:
+    array_2d downscaled_image(resized_shape(size_info,
+                        1 / x_scale, 1 / y_scale));
+    (*resize)(pre_scale_image, downscaled_image);
+    write_out(downscaled_image, "test_downscaled.png", cmp);
+
+    const double step_size[2] = { x_scale, y_scale };
+
+    double sigma = test_f(downscaled_image, sigmas, step_size);
+
+    write_out(downscaled_image, "test_downscaled_new_f.png", cmp);
+
+    array_2d x1_image_b(test_image);
+    test_f(x1_image_b);
+
+    write_out(x1_image_b, "test_any_old_f.png", cmp);
+
+    // compare with resampled image
+    array_2d res_image_b(downscaled_image);
+    (*resize)(x1_image_b, res_image_b);
+
+    write_out(res_image_b, "test_any_res_b_f.png", cmp);
+
+    test_compare(res_image_b, downscaled_image, sigma / x_scale, cmp, log_write);
+}
+
+void test_any(void (*resize)(const array_2d &, array_2d &),
+              const vigra::ImageImportInfo & size_info,
+              const array_2d & test_image,
+              const t_func & test_f,
+              double im_scale,
+              const cmp_data & cmp,
+              logger & log_write,
+              logger & log_name,
+              int test_type)
+{
+    if (test_type == 0)
+    {
+        test_upscaled(resize, size_info, test_image, test_f, im_scale,
+                      cmp, log_write, log_name);
+    }
+    else if (test_type == 1)
+    {
+        test_downscaled(resize, size_info, test_image, test_f, im_scale,
+                        cmp, log_write, log_name);
+    }
+}
+
+typedef const double test_data[9];
+
+struct args
+{
+    const int argc;
+    test_data & argv;
+    int pos;
+    args(int a_c, test_data & a_v) : argc(a_c), argv(a_v), pos(-1) {}
+    template<class X>
+    X operator()(X default_value)
+    {
+        ++pos;
+        return static_cast<X>(
+                 (argc > pos) ? argv[pos] : static_cast<double>(default_value));
+    }
+};
+
+std::string perform_test(int argc, test_data & argv,
+                         const vigra::ImageImportInfo & import_info,
+                         const array_2d & test_image,
+                         bool run_test = true)
+{
+    logger log_name(!run_test);
+    logger log_write;
+    args cmd_line(argc, argv);
+    const double sigma        = cmd_line(2.0);
+    const double im_scale     = cmd_line(3.0);
+    const int intp_type       = cmd_line(0);
+    const bool write_im       = cmd_line(1) == 1;
+    const int test_nr         = cmd_line(0);
+    const double outer        = cmd_line(sigma);
+    const int test_type       = cmd_line(0);
+    const double global_tol   = cmd_line(0.0);
+    const double local_tol    = cmd_line(0.0);
+
+    const cmp_data cmp(write_im, global_tol, local_tol);
+
+    const t_func *const test = new_test(sigma, outer, test_nr, log_name);
+    if (! test)
+    {
+        shouldMsg(!run_test, ("unknown test number " + asString(test_nr)
+                                            + " for new_test_alloc()").c_str());
+        return "(unknown test number)";
+    }
+    log_name("sigma", sigma);
+    log_name("image scaling factor", im_scale);
+    log_name("outer sigma", outer);
+    log_name("global_tol", global_tol);
+    log_name("local_tol", local_tol);
+    
+    if (intp_type == 0)
+    {
+        log_name("resizing without interpolation");
+        test_any(&resize_0, import_info, test_image, *test, im_scale,
+                    cmp, log_write, log_name, test_type);
+    }
+    else if (intp_type == 3)
+    {
+        log_name("resizing with spline3");
+        test_any(&resize_n<3>, import_info, test_image, *test, im_scale,
+                    cmp, log_write, log_name, test_type);
+    }
+    else if (intp_type == 5)
+    {
+        log_name("resizing with spline5");
+        test_any(&resize_n<5>, import_info, test_image, *test, im_scale,
+                    cmp, log_write, log_name, test_type);
+    }
+    if (log_name)
+        return log_name.str();
+    else
+        return log_name.str() + ":\n" + log_write.str();
+}
+
+struct scaled_test : public vigra::detail::test_functor<scaled_test>
+{
+    static const int argc;
+    test_data & argv;
+    const vigra::ImageImportInfo & import_info;
+    const array_2d & test_image;
+
+    scaled_test(test_data & a,  const vigra::ImageImportInfo & ii,
+                                                             const array_2d & t)
+        : argv(a), import_info(ii), test_image(t) {}
+    void operator()()
+    {
+        // std::cout << perform_test(argc, argv, import_info, test_image)
+        // << "\n";
+        perform_test(argc, argv, import_info, test_image);
+    }
+    std::string str()
+    {
+        return "MultiArraySeparableConvolutionScaledTestSuite ["
+               + perform_test(argc, argv, import_info, test_image, false) + "]";
+    }
+};
+const int scaled_test::argc = sizeof(test_data) / sizeof(double);
+
+test_data tests[] =
+{
+/*    sigma        write_im     test_type           */
+/*         im_scale    test_nr      global_tol      */
+/*             intp_type   outer        local_tol   */
+    { 2,   3,  5,  0,  0,  0,   0,  0,  0.007 },
+    { 1,   3,  0,  0,  1,  0,   0,  0.023,  0 },
+    { 1,   3,  0,  0,  2,  0,   0,  0.011,  0 },
+    { 4.5, 3,  0,  0,  1,  0,   0,  0.004,  0 },
+    { 4.5, 3,  0,  0,  2,  0,   0,  0.002,  0 },
+    { 5, 0.99, 5,  0, 11,  0,   0,  0.065,  0 },
+    { 5, 0.99, 5,  0, 12,  0,   0,  0.135,  0 },
+    { 3,   3,  0,  0, 20,  0,   0,  0.014,  0 },
+    { 3,   3,  0,  0, 21,  0,   0,  0.019,  0 },
+    { 3,   3,  0,  0, 22,  0,   0,  0.005,  0 },
+    { 3,   3,  0,  0, 23,  0,   0,  0.001,  0 },
+    { 4,   3,  0,  0, 31,  2,   0,  0.012,  0 },
+    { 4,   3,  0,  0, 32,  2,   0,  0.004,  0 },
+    { 4,   3,  0,  0, 33,  2,   0,  0.001,  0 },
+    { 15,  3,  0,  0, 0,   0,   1,  0,  0.012 },
+    { 15,  3,  5,  0, 0,   0,   1,  0,  0.012 },
+    { 15,  2,  5,  0, 1,   0,   1,  0.005,  0 },
+    { 15,  2,  5,  0, 2,   0,   1,  0.003,  0 },
+    { 15,  2,  0,  0, 20,  0,   1,  0.028,  0 },
+    { 15,  3,  0,  0, 21,  0,   1,  0.045,  0 },
+    { 15,  3,  0,  0, 22,  0,   1,  0.023,  0 },
+    { 15,  3,  0,  0, 23,  0,   1,  0.024,  0 },
+    { 15,  3,  0,  0, 31,  1.1, 1,  0.025,  0 },
+    { 15,  3,  0,  0, 32,  1.1, 1,  0.035,  0 },
+    { 15,  3,  0,  0, 33,  1.1, 1,  0.006,  0 },
+    { 0,   0,  0,  0,  0,  0,   0,  0,      0 }
+};
+
+
+//--------------------------------------------------------
+
+
+struct MultiArraySeparableConvolutionScaledTestSuite : public vigra::test_suite
+{
+    vigra::ImageImportInfo import_info;
+    array_2d               test_image;
+
+    MultiArraySeparableConvolutionScaledTestSuite()
+        : vigra::test_suite("MultiArraySeparableConvolutionScaledTestSuite"),
+          import_info("oi_single.gif"),
+          test_image(shape_2d(import_info.width(), import_info.height()))
+        {
+            vigra::importImage(import_info, destImage(test_image));
+
+            for (test_data* p = tests; (*p)[0]; ++p)
+            {
+                scaled_test* test
+                                 = new scaled_test(*p, import_info, test_image);
+                add(vigra::create_test_case(*test, test->str().c_str()));
+            }
+        }
+}; // struct MultiArraySeparableConvolutionScaledTestSuite
+
+//--------------------------------------------------------
+
+int main(int argc, char ** argv)
+{
+    // run the multi-array separable convolution test suite
+    MultiArraySeparableConvolutionTestSuite test1;
+    int failed = test1.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test1.report() << std::endl;
+
+    // run the multi-array separable scaled-convolution test suite
+    MultiArraySeparableConvolutionScaledTestSuite test2;
+    failed += test2.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test2.report() << std::endl;
+
+    return (failed != 0);
+}
diff --git a/test/multidistance/CMakeLists.txt b/test/multidistance/CMakeLists.txt
new file mode 100644
index 0000000..87f0834
--- /dev/null
+++ b/test/multidistance/CMakeLists.txt
@@ -0,0 +1,9 @@
+if(HDF5_FOUND)
+    INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIR})
+  
+    ADD_DEFINITIONS(${HDF5_CPPFLAGS})
+
+    VIGRA_ADD_TEST(test_multidistance test.cxx LIBRARIES vigraimpex ${HDF5_LIBRARIES})
+else()
+    VIGRA_ADD_TEST(test_multidistance test.cxx LIBRARIES vigraimpex)
+endif()
diff --git a/test/multidistance/test.cxx b/test/multidistance/test.cxx
new file mode 100644
index 0000000..9942e14
--- /dev/null
+++ b/test/multidistance/test.cxx
@@ -0,0 +1,1175 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2007 by F. Heinrich, B. Seppke, Ullrich Koethe       */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <functional>
+#include <cmath>
+#include <list>
+#include "vigra/unittest.hxx"
+
+#include "vigra/multi_distance.hxx"
+#include "vigra/distancetransform.hxx"
+
+using namespace vigra;
+
+static double volume_data[4200] = {
+255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0,
+0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 0.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 0.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 255.0, 0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 255.0, 0.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 255.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 255.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0, 255.0, 255.0,
+255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 255.0, 255.0,
+255.0, 255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+255.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
+};
+
+// reference squred distance for the foreground of above volume
+static double ref_dist2[4200] = {
+5.0, 4.0, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 3.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 4.0, 4.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 4.0, 4.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0,
+1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 1.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 1.0, 2.0, 2.0, 3.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 5.0, 6.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 2.0, 3.0, 5.0, 5.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 1.0, 2.0,
+2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0,
+1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 1.0, 1.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 1.0, 2.0, 3.0, 5.0, 6.0, 9.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 1.0, 3.0, 5.0, 6.0, 5.0, 4.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 5.0, 4.0, 4.0,
+2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 3.0,
+2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0,
+1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0,
+1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 1.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 2.0, 1.0, 2.0, 4.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 1.0, 2.0, 3.0, 2.0, 3.0, 5.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 2.0, 4.0, 5.0, 5.0, 5.0, 4.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 3.0, 5.0, 5.0, 4.0,
+2.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 5.0, 5.0,
+2.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 3.0,
+2.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 1.0,
+2.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0,
+2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 2.0, 1.0, 2.0, 3.0, 4.0, 4.0,
+0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 3.0, 2.0, 3.0, 2.0,
+2.0, 1.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 5.0, 5.0,
+2.0, 1.0, 1.0, 0.0, 0.0, 1.0, 2.0, 3.0, 5.0, 3.0,
+2.0, 2.0, 1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 5.0, 4.0,
+2.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 2.0, 3.0,
+5.0, 4.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0,
+0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 1.0,
+1.0, 1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 3.0,
+1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 5.0, 6.0, 3.0, 2.0,
+1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 2.0, 3.0, 6.0, 5.0,
+2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 6.0,
+8.0, 4.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 3.0, 2.0, 2.0, 1.0,
+1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 4.0, 5.0, 2.0, 1.0,
+1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 4.0, 5.0, 6.0, 3.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 8.0, 9.0,
+5.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 3.0, 2.0, 1.0, 0.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 4.0, 4.0, 2.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 4.0,
+4.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 2.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 1.0, 1.0, 1.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 1.0,
+1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 2.0, 3.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 0.0, 1.0, 1.0, 2.0, 3.0, 2.0, 0.0, 1.0,
+1.0, 1.0, 1.0, 2.0, 1.0, 2.0, 1.0, 2.0, 5.0, 5.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 1.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 1.0, 1.0, 2.0, 2.0, 3.0, 0.0, 1.0, 1.0, 1.0,
+1.0, 1.0, 1.0, 2.0, 2.0, 3.0, 5.0, 5.0, 0.0, 1.0,
+2.0, 2.0, 2.0, 3.0, 2.0, 3.0, 4.0, 5.0, 8.0, 8.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0,
+2.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0,
+1.0, 2.0, 3.0, 5.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
+1.0, 2.0, 2.0, 3.0, 5.0, 6.0, 0.0, 0.0, 1.0, 2.0,
+2.0, 2.0, 3.0, 5.0, 5.0, 6.0, 8.0, 9.0, 1.0, 1.0,
+2.0, 5.0, 5.0, 5.0, 5.0, 6.0, 8.0, 9.0, 12.0, 13.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0,
+3.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0,
+3.0, 5.0, 6.0, 9.0, 0.0, 1.0, 0.0, 1.0, 1.0, 2.0,
+2.0, 3.0, 5.0, 6.0, 9.0, 11.0, 1.0, 1.0, 1.0, 2.0,
+4.0, 5.0, 5.0, 6.0, 8.0, 9.0, 12.0, 14.0, 2.0, 2.0,
+3.0, 5.0, 8.0, 8.0, 9.0, 11.0, 13.0, 14.0, 16.0, 16.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0,
+5.0, 6.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0,
+5.0, 6.0, 9.0, 10.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0,
+5.0, 6.0, 9.0, 9.0, 9.0, 9.0, 1.0, 2.0, 2.0, 3.0,
+5.0, 6.0, 8.0, 9.0, 10.0, 9.0, 9.0, 9.0, 4.0, 5.0,
+4.0, 4.0, 5.0, 8.0, 10.0, 9.0, 9.0, 9.0, 9.0, 9.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 1.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 0.0, 1.0, 2.0, 3.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 3.0, 5.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 5.0, 6.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 5.0, 6.0,
+8.0, 8.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 4.0, 5.0,
+6.0, 5.0, 5.0, 5.0, 1.0, 1.0, 1.0, 2.0, 4.0, 5.0,
+8.0, 8.0, 5.0, 4.0, 4.0, 4.0, 2.0, 3.0, 2.0, 2.0,
+3.0, 6.0, 6.0, 5.0, 5.0, 4.0, 4.0, 4.0, 5.0, 2.0,
+1.0, 1.0, 2.0, 5.0, 5.0, 4.0, 4.0, 4.0, 4.0, 4.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0,
+4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+1.0, 2.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 1.0, 1.0, 2.0, 5.0, 6.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 6.0, 8.0, 0.0, 0.0,
+0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 5.0, 6.0, 6.0, 5.0,
+0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 3.0, 6.0, 5.0,
+5.0, 4.0, 1.0, 1.0, 1.0, 2.0, 2.0, 3.0, 5.0, 6.0,
+3.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 3.0, 5.0, 6.0,
+6.0, 5.0, 2.0, 1.0, 1.0, 1.0, 3.0, 2.0, 1.0, 1.0,
+2.0, 5.0, 3.0, 2.0, 2.0, 1.0, 1.0, 1.0, 2.0, 1.0,
+0.0, 0.0, 1.0, 4.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 4.0, 5.0,
+8.0, 9.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+4.0, 5.0, 8.0, 9.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 2.0, 4.0, 5.0, 8.0, 9.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 1.0, 1.0, 2.0, 5.0, 6.0, 6.0, 5.0, 0.0, 0.0,
+0.0, 1.0, 2.0, 2.0, 2.0, 3.0, 6.0, 6.0, 3.0, 2.0,
+0.0, 1.0, 1.0, 2.0, 3.0, 5.0, 5.0, 6.0, 5.0, 3.0,
+2.0, 1.0, 1.0, 2.0, 4.0, 5.0, 5.0, 6.0, 6.0, 5.0,
+2.0, 1.0, 1.0, 1.0, 4.0, 4.0, 4.0, 4.0, 5.0, 5.0,
+3.0, 2.0, 1.0, 0.0, 0.0, 0.0, 2.0, 1.0, 1.0, 1.0,
+2.0, 2.0, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 4.0, 6.0,
+5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0,
+5.0, 5.0, 4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+2.0, 3.0, 6.0, 5.0, 4.0, 4.0, 0.0, 0.0, 0.0, 1.0,
+1.0, 2.0, 3.0, 5.0, 8.0, 5.0, 4.0, 4.0, 0.0, 1.0,
+1.0, 2.0, 3.0, 5.0, 5.0, 6.0, 6.0, 3.0, 2.0, 1.0,
+1.0, 2.0, 2.0, 3.0, 6.0, 8.0, 8.0, 6.0, 3.0, 2.0,
+1.0, 0.0, 2.0, 3.0, 5.0, 6.0, 8.0, 6.0, 5.0, 4.0,
+2.0, 1.0, 0.0, 0.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0,
+2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0,
+1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 5.0, 3.0,
+2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0,
+5.0, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0,
+5.0, 6.0, 5.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0,
+2.0, 3.0, 6.0, 8.0, 5.0, 2.0, 1.0, 1.0, 1.0, 2.0,
+2.0, 3.0, 5.0, 6.0, 9.0, 6.0, 3.0, 2.0, 1.0, 1.0,
+2.0, 3.0, 5.0, 6.0, 6.0, 5.0, 5.0, 5.0, 2.0, 1.0,
+0.0, 0.0, 5.0, 6.0, 8.0, 6.0, 5.0, 3.0, 2.0, 2.0,
+1.0, 0.0, 0.0, 0.0, 4.0, 4.0, 4.0, 3.0, 2.0, 2.0,
+1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0,
+1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 4.0, 5.0, 2.0, 1.0,
+1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 5.0, 5.0,
+2.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 2.0, 3.0,
+5.0, 4.0, 2.0, 1.0, 0.0, 0.0, 2.0, 2.0, 2.0, 3.0,
+5.0, 6.0, 5.0, 4.0, 2.0, 1.0, 0.0, 0.0, 4.0, 5.0,
+5.0, 6.0, 6.0, 5.0, 5.0, 3.0, 2.0, 1.0, 0.0, 0.0,
+5.0, 6.0, 8.0, 6.0, 3.0, 2.0, 3.0, 2.0, 1.0, 0.0,
+0.0, 0.0, 6.0, 5.0, 5.0, 5.0, 2.0, 1.0, 1.0, 1.0,
+1.0, 0.0, 0.0, 0.0, 3.0, 2.0, 2.0, 2.0, 1.0, 1.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+1.0, 1.0, 2.0, 4.0, 4.0, 5.0, 5.0, 4.0, 1.0, 0.0,
+0.0, 0.0, 1.0, 1.0, 2.0, 4.0, 4.0, 5.0, 3.0, 2.0,
+1.0, 0.0, 0.0, 0.0, 2.0, 2.0, 3.0, 5.0, 5.0, 5.0,
+2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 5.0, 5.0, 5.0, 6.0,
+6.0, 5.0, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 8.0, 8.0,
+8.0, 6.0, 3.0, 2.0, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0,
+9.0, 8.0, 6.0, 3.0, 2.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+0.0, 0.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0, 1.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 2.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+4.0, 4.0, 5.0, 8.0, 9.0, 5.0, 2.0, 1.0, 1.0, 0.0,
+0.0, 0.0, 4.0, 4.0, 5.0, 8.0, 9.0, 5.0, 2.0, 1.0,
+1.0, 0.0, 0.0, 0.0, 5.0, 5.0, 6.0, 9.0, 6.0, 3.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 8.0, 8.0, 8.0, 6.0,
+3.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 9.0, 6.0,
+5.0, 3.0, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+6.0, 5.0, 3.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 3.0, 2.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+9.0, 9.0, 10.0, 13.0, 9.0, 4.0, 1.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 9.0, 9.0, 10.0, 9.0, 6.0, 4.0, 1.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 10.0, 10.0, 10.0, 6.0, 3.0, 2.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 9.0, 6.0, 5.0, 5.0,
+2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 6.0, 3.0,
+2.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+3.0, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+16.0, 16.0, 17.0, 13.0, 9.0, 4.0, 1.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 16.0, 16.0, 13.0, 8.0, 5.0, 4.0, 1.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 13.0, 10.0, 9.0, 5.0, 2.0, 1.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 8.0, 5.0, 4.0, 4.0,
+1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 2.0,
+1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
+};
+
+struct MultiDistanceTest
+{
+    typedef vigra::MultiArray<3,int> IntVolume;
+    typedef vigra::MultiArray<3,double> DoubleVolume; 
+    typedef vigra::MultiArray<2,double> Double2DArray;
+    typedef vigra::DImage Image;
+    typedef vigra::MultiArrayView<2,Image::value_type> ImageView;
+    typedef vigra::TinyVector<int,3> IntVec;
+
+#if 1
+    enum { WIDTH    =   15,  // 
+           HEIGHT   =   15,  // Volume-Dimensionen
+           DEPTH    =   15}; //
+#else
+    enum { WIDTH    =   4,  // 
+           HEIGHT   =   4,  // Volume-Dimensionen
+           DEPTH    =   1}; //
+#endif
+
+    std::list<std::list<IntVec> > pointslists;
+    std::vector<Image> images;
+    Double2DArray img2;
+    DoubleVolume volume;
+    IntVolume shouldVol;
+
+    MultiDistanceTest()
+    : images(3, Image(7,7)), img2(Double2DArray::difference_type(7,1)),
+      volume(IntVolume::difference_type(WIDTH,HEIGHT,DEPTH)),
+      shouldVol(IntVolume::difference_type(WIDTH,HEIGHT,DEPTH))
+    {
+        std::list<IntVec> temp;
+        temp.push_back(IntVec(      0,        0,       0));
+        temp.push_back(IntVec(WIDTH-1,        0,       0));
+        temp.push_back(IntVec(      0, HEIGHT-1,       0));
+        temp.push_back(IntVec(WIDTH-1, HEIGHT-1,       0));
+        temp.push_back(IntVec(      0,        0, DEPTH-1));
+        temp.push_back(IntVec(WIDTH-1,        0, DEPTH-1));
+        temp.push_back(IntVec(      0, HEIGHT-1, DEPTH-1));
+        temp.push_back(IntVec(WIDTH-1, HEIGHT-1, DEPTH-1));
+        pointslists.push_back(temp);
+
+        temp.clear();
+        temp.push_back(IntVec(      0, HEIGHT/2, DEPTH/2));
+        temp.push_back(IntVec(WIDTH/2, HEIGHT/2,       0));
+        temp.push_back(IntVec(WIDTH/2,        0, DEPTH/2));
+        temp.push_back(IntVec(WIDTH-1, HEIGHT/2, DEPTH/2));
+        temp.push_back(IntVec(WIDTH/2, HEIGHT/2, DEPTH-1));
+        temp.push_back(IntVec(WIDTH/2, HEIGHT-1, DEPTH/2));
+        pointslists.push_back(temp);
+    
+
+        static const double in[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        {
+            Image::ScanOrderIterator i = images[0].begin();
+            Image::ScanOrderIterator end = images[0].end();
+            Image::Accessor acc = images[0].accessor();
+            const double * p = in;
+
+            for(; i != end; ++i, ++p)
+            {
+                acc.set(*p, i);
+            }
+        }
+        
+        static const unsigned char in2[] = {
+            1, 0, 0, 0, 0, 0, 1,
+            1, 0, 0, 0, 0, 0, 1,
+            1, 0, 0, 0, 0, 0, 1,
+            1, 0, 0, 0, 0, 0, 1,
+            1, 0, 0, 0, 0, 0, 1,
+            1, 0, 0, 0, 0, 0, 1,
+            1, 0, 0, 0, 0, 0, 1};
+
+        {
+            Image::ScanOrderIterator i = images[1].begin();
+            Image::ScanOrderIterator end = images[1].end();
+            Image::Accessor acc = images[1].accessor();
+            const unsigned char * p = in2;
+
+            for(; i != end; ++i, ++p)
+            {
+                acc.set(*p, i);
+            }
+        }
+
+        static const unsigned char in3[] = {
+            1, 1, 1, 1, 1, 1, 1,
+            1, 0, 0, 0, 0, 0, 1,
+            1, 0, 0, 0, 0, 0, 1,
+            1, 0, 0, 0, 0, 0, 1,
+            1, 0, 0, 0, 0, 0, 1,
+            1, 0, 0, 0, 0, 0, 1,
+            1, 1, 1, 1, 1, 1, 1};
+
+        {
+            Image::ScanOrderIterator i = images[2].begin();
+            Image::ScanOrderIterator end = images[2].end();
+            Image::Accessor acc = images[2].accessor();
+            const unsigned char * p = in3;
+
+            for(; i != end; ++i, ++p)
+            {
+                acc.set(*p, i);
+            }
+        }
+
+        static const double in2d[] = {0, 0, 0, 1, 0, 0, 0};
+        const double * p=in2d;
+        for(Double2DArray::iterator iter=img2.begin(); iter!=img2.end(); ++iter, ++p){
+            *iter=*p;
+        }
+    }
+
+    void testDistanceVolumes()
+    {    
+        DoubleVolume desired(volume);
+        for(std::list<std::list<IntVec> >::iterator list_iter=pointslists.begin(); 
+                                          list_iter!=pointslists.end(); ++list_iter)
+        {
+            IntVec temp;
+            for(int z=0; z<DEPTH; ++z)
+                for(int y=0; y<HEIGHT; ++y)
+                    for(int x=0; x<WIDTH; ++x){
+                        temp = IntVec(x,y,z);
+                        int tempVal=10000000;
+                        for(std::list<IntVec>::iterator iter=(*list_iter).begin(); iter!=(*list_iter).end(); ++iter){
+                            if((temp-*iter).squaredMagnitude()<tempVal){
+                                tempVal = (temp-*iter).squaredMagnitude();
+                            }
+                        }
+                        desired(x,y,z)=tempVal;
+                    }
+
+            for(DoubleVolume::iterator vol_iter = volume.begin(); vol_iter != volume.end(); ++vol_iter)
+                *vol_iter=0;
+            for(std::list<IntVec>::iterator iter=(*list_iter).begin(); iter!=(*list_iter).end(); ++iter){
+                *(volume.traverser_begin()+*iter)=1;
+            }
+
+            separableMultiDistSquared(volume, volume, true);
+            shouldEqualSequence(volume.begin(),volume.end(),desired.begin());
+        }
+
+        typedef MultiArrayShape<3>::type Shape;
+        MultiArrayView<3, double> vol(Shape(12,10,35), volume_data);
+        
+        MultiArray<3, double> res(vol.shape());
+
+        separableMultiDistSquared(srcMultiArrayRange(vol), destMultiArray(res), false);
+                
+        shouldEqualSequence(res.data(), res.data()+res.elementCount(), ref_dist2);
+    }
+
+    void testDistanceAxesPermutation()
+    {
+        typedef MultiArrayShape<3>::type Shape;
+        MultiArrayView<3, double> vol(Shape(12,10,35), volume_data);
+        
+        MultiArray<3, double> res1(vol.shape()), res2(vol.shape());
+        MultiArrayView<3, double, StridedArrayTag> pvol(vol.transpose()), pres2(res2.transpose());
+        
+        separableMultiDistSquared(vol, res1, true);
+        separableMultiDistSquared(pvol, pres2, true);
+                
+        shouldEqualSequence(res1.data(), res1.data()+res1.elementCount(), res2.data());
+        
+        separableMultiDistSquared(vol, res1, false);
+        separableMultiDistSquared(pvol, pres2, false);
+                
+        shouldEqualSequence(res1.data(), res1.data()+res1.elementCount(), res2.data());
+    }
+
+    void testDistanceVolumesAnisoptopic()
+    {    
+        double epsilon = 1e-14;
+        TinyVector<double, 3> pixelPitch(1.2, 1.0, 2.4);
+        
+        DoubleVolume desired(volume);
+        for(std::list<std::list<IntVec> >::iterator list_iter=pointslists.begin(); 
+                                          list_iter!=pointslists.end(); ++list_iter){
+
+            for(DoubleVolume::iterator vol_iter = volume.begin(); vol_iter != volume.end(); ++vol_iter)
+                *vol_iter=0;
+            for(std::list<IntVec>::iterator iter=(*list_iter).begin(); iter!=(*list_iter).end(); ++iter)
+                *(volume.traverser_begin()+*iter)=1;
+
+            IntVec temp;
+            for(int z=0; z<DEPTH; ++z)
+                for(int y=0; y<HEIGHT; ++y)
+                {
+                    for(int x=0; x<WIDTH; ++x)
+                    {
+                        temp = IntVec(x,y,z);
+                        double tempVal=10000000.0;
+                        for(std::list<IntVec>::iterator iter=(*list_iter).begin(); iter!=(*list_iter).end(); ++iter){
+                            double squaredMag = (pixelPitch*(temp-*iter)).squaredMagnitude();
+                            if(squaredMag<tempVal){
+                                tempVal = squaredMag;
+                            }
+                        }
+                        desired(x,y,z)=tempVal;
+                    }
+                }
+
+
+            separableMultiDistSquared(volume, volume, true, pixelPitch);
+            shouldEqualSequenceTolerance(volume.begin(),volume.end(),desired.begin(), epsilon);
+        }
+    }
+
+    void distanceTransform2DCompare()
+    {
+        for(unsigned int k=0; k<images.size(); ++k)
+        {
+            Image res(images[k]);
+            ImageView img_array(ImageView::difference_type(images[k].width(), images[k].height()), &images[k](0,0));
+
+            distanceTransform(srcImageRange(images[k]), destImage(res), 0.0, 2);
+
+            separableMultiDistance(img_array, img_array, true);
+
+            Image::Iterator i = res.upperLeft();
+            Image::Accessor acc = res.accessor();
+
+            int x,y;
+
+            for(y=0; y<7; ++y)
+            {
+                for(x=0; x<7; ++x)
+                {
+                    double dist_old = acc(i, vigra::Diff2D(x,y));
+
+                    shouldEqualTolerance(dist_old, img_array(x,y), 1e-7);
+                }
+            }
+        }
+    }
+
+    void distanceTest1D()
+    {
+        vigra::MultiArray<2,double> res(img2);
+        
+        static const int desired[] = {3, 2, 1, 0, 1, 2, 3};
+        separableMultiDistance(img2, res, true);
+        shouldEqualSequence(res.begin(), res.end(), desired);
+    }
+};
+
+
+
+struct SimpleAnalysisTestSuite
+: public vigra::test_suite
+{
+    SimpleAnalysisTestSuite()
+    : vigra::test_suite("SimpleAnalysisTestSuite")
+    {
+        add( testCase( &MultiDistanceTest::testDistanceVolumes));
+        add( testCase( &MultiDistanceTest::testDistanceAxesPermutation));
+        add( testCase( &MultiDistanceTest::testDistanceVolumesAnisoptopic));
+        add( testCase( &MultiDistanceTest::distanceTransform2DCompare));
+        add( testCase( &MultiDistanceTest::distanceTest1D));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    SimpleAnalysisTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+    return (failed != 0);
+}
+
diff --git a/test/multimorphology/CMakeLists.txt b/test/multimorphology/CMakeLists.txt
new file mode 100644
index 0000000..eccbe1f
--- /dev/null
+++ b/test/multimorphology/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_multimorphology test.cxx LIBRARIES vigraimpex)
diff --git a/test/multimorphology/test.cxx b/test/multimorphology/test.cxx
new file mode 100644
index 0000000..54152e3
--- /dev/null
+++ b/test/multimorphology/test.cxx
@@ -0,0 +1,324 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include "vigra/unittest.hxx"
+#include "vigra/stdimage.hxx"
+#include "vigra/multi_morphology.hxx"
+#include "vigra/linear_algebra.hxx"
+#include "vigra/matrix.hxx"
+
+using namespace vigra;
+
+struct MultiMorphologyTest
+{
+    typedef vigra::MultiArray<3,int> IntVolume;
+    typedef vigra::MultiArray<2,int> IntImage;
+
+    MultiMorphologyTest() :
+        img(IntImage::difference_type(7,7)),
+        img2(IntImage::difference_type(7,7)),
+        lin(IntImage::difference_type(7,1)),
+        vol(IntVolume::difference_type(5,5,5))
+    {
+        static const unsigned char in[] = {
+            0, 1, 1, 1, 1, 1, 0,
+            0, 1, 1, 1, 1, 1, 0,
+            0, 1, 1, 1, 1, 1, 0,
+            0, 1, 1, 1, 1, 1, 0,
+            0, 1, 1, 1, 1, 1, 0,
+            0, 1, 1, 1, 1, 1, 0,
+            0, 1, 1, 1, 1, 1, 0};
+        
+        const unsigned char *i=in;
+        for(IntImage::iterator iter=img.begin(); iter!=img.end(); ++iter, ++i){
+            *iter=*i;
+        }
+        static const unsigned char in1d[] = {0, 1, 1, 1, 1, 1, 0};
+        i=in1d;
+        for(IntImage::iterator iter=lin.begin(); iter!=lin.end(); ++iter, ++i){
+            *iter=*i;
+        }
+
+        static const unsigned char in1[] = {
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6,
+            0, 1, 2, 3, 4, 5, 6};
+        
+        i=in1;
+        for(IntImage::iterator iter=img2.begin(); iter!=img2.end(); ++iter, ++i){
+            *iter=*i;
+        }
+
+        static const unsigned char in2[] = { 0, 0, 0, 0, 0, 
+                                             0, 0, 0, 0, 0,  
+                                             0, 0, 0, 0, 0,  
+                                             0, 0, 0, 0, 0,  
+                                             0, 0, 0, 0, 0,
+
+                                             0, 0, 0, 0, 0,  
+                                             0, 1, 1, 1, 0,  
+                                             0, 1, 1, 1, 0,  
+                                             0, 1, 1, 1, 0,  
+                                             0, 0, 0, 0, 0,
+
+                                             0, 0, 0, 0, 0,  
+                                             0, 1, 1, 1, 0,  
+                                             0, 1, 1, 1, 0,  
+                                             0, 1, 1, 1, 0,  
+                                             0, 0, 0, 0, 0,
+
+                                             0, 0, 0, 0, 0,  
+                                             0, 1, 1, 1, 0,  
+                                             0, 1, 1, 1, 0,  
+                                             0, 1, 1, 1, 0,  
+                                             0, 0, 0, 0, 0,
+
+                                             0, 0, 0, 0, 0, 
+                                             0, 0, 0, 0, 0,  
+                                             0, 0, 0, 0, 0,  
+                                             0, 0, 0, 0, 0,  
+                                             0, 0, 0, 0, 0};
+
+        i=in2;
+        for(IntVolume::iterator iter=vol.begin(); iter!=vol.end(); ++iter, ++i){
+            *iter=*i;
+        }
+    }
+    
+    void binaryErosionTest()
+    {
+        IntImage res(img);
+        int foreground = NumericTraits<int>::one();
+        
+        static const int desired[] = {
+                   0, 0, 0, foreground, 0, 0, 0,
+                   0, 0, 0, foreground, 0, 0, 0,
+                   0, 0, 0, foreground, 0, 0, 0,
+                   0, 0, 0, foreground, 0, 0, 0,
+                   0, 0, 0, foreground, 0, 0, 0,
+                   0, 0, 0, foreground, 0, 0, 0,
+                   0, 0, 0, foreground, 0, 0, 0};
+        
+        multiBinaryErosion(srcMultiArrayRange(img), destMultiArray(res), 2);
+        shouldEqualSequence(res.begin(), res.end(), desired);
+        
+        res = 0;
+        multiBinaryErosion(img, res, 2);
+        shouldEqualSequence(res.begin(), res.end(), desired);
+    }
+
+    void binaryErosionTest2()
+    {
+        IntImage res(img2);
+        int foreground = NumericTraits<int>::one();
+        
+        static const int desired[] = {
+                   0, 0, 0, foreground, foreground, foreground, foreground,
+                   0, 0, 0, foreground, foreground, foreground, foreground,
+                   0, 0, 0, foreground, foreground, foreground, foreground,
+                   0, 0, 0, foreground, foreground, foreground, foreground,
+                   0, 0, 0, foreground, foreground, foreground, foreground,
+                   0, 0, 0, foreground, foreground, foreground, foreground,
+                   0, 0, 0, foreground, foreground, foreground, foreground};
+
+        multiBinaryErosion(img2, res, 2);
+        shouldEqualSequence(res.begin(), res.end(), desired);
+    }
+
+    void binaryErosionTest1D()
+    {
+        IntImage res(lin);
+        int foreground = NumericTraits<int>::one();
+        
+        static const int desired[] = {0, 0, 0, foreground, 0, 0, 0};
+        multiBinaryErosion(lin, res, 2);
+        shouldEqualSequence(res.begin(), res.end(), desired);
+    }
+
+    void binaryErosionAndDilationTest3D()
+    {
+        IntVolume res(vol.shape()), res2(vol.shape());
+        int f = NumericTraits<int>::one();
+        
+        static const int desired[] = {  0, 0, 0, 0, 0, 
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,
+
+                                        0, 0, 0, 0, 0, 
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,
+
+                                        0, 0, 0, 0, 0, 
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, f, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,
+
+                                        0, 0, 0, 0, 0, 
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,
+
+                                        0, 0, 0, 0, 0, 
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0};
+
+        multiBinaryErosion(vol, res, 1);
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        multiBinaryDilation(res, res2, 1.8);
+        shouldEqualSequence(res2.begin(), res2.end(), vol.begin());
+    }
+    
+    void grayErosionTest2D()
+    {
+        typedef vigra::MultiArray<2,float> FloatImage;
+        FloatImage in(img), res(img), res_cmp(img);
+        
+        //erosion on original image
+        multiGrayscaleErosion(srcMultiArrayRange(in), destMultiArray(res), 1);
+        
+        //create comparable result = result+2 for every pixel
+        for(FloatImage::iterator iter=res.begin(); iter!=res.end(); ++iter){
+            *iter+=2.9f;
+        }
+        
+        //create compare image = img+2 for every pixel
+        for(FloatImage::iterator iter=in.begin(); iter!=in.end(); ++iter){
+            *iter+=2.9f;
+        }
+        //erosion on compare image (image+2)
+        multiGrayscaleErosion(in, res_cmp, 1);
+        
+        shouldEqualSequence(res.begin(), res.end(), res_cmp.begin());
+    }
+
+    void grayDilationTest2D()
+    {
+        typedef vigra::MultiArray<2,float> FloatImage;
+        FloatImage in(img), res(img), res_cmp(img);
+
+        //dilation on original image
+        multiGrayscaleDilation(srcMultiArrayRange(in), destMultiArray(res), 1);
+
+        //create comparable result = result+2 for every pixel
+        for(FloatImage::iterator iter=res.begin(); iter!=res.end(); ++iter){
+            *iter+=2.9f;
+        }
+
+        //create compare image = img+2 for every pixel
+        for(FloatImage::iterator iter=in.begin(); iter!=in.end(); ++iter){
+            *iter+=2.9f;
+        }
+        //dilation on compare image (image+2)
+        multiGrayscaleDilation(in, res_cmp, 1);
+
+        shouldEqualSequence(res.begin(), res.end(), res_cmp.begin());
+    }
+
+    void grayErosionAndDilationTest2D()
+    {
+        typedef vigra::MultiArray<2, float> FloatImage;
+        FloatImage in(img), di_res(img), er_res(img);
+
+        //erosion on original image
+        multiGrayscaleErosion(in, er_res, 1);
+        //dilation on original inverted image
+        for(FloatImage::iterator iter=in.begin(); iter!=in.end(); ++iter){
+            *iter*=-1.0f;
+        }
+        multiGrayscaleDilation(in, di_res, 1);
+        //Invert dilation res
+        for(FloatImage::iterator iter=di_res.begin(); iter!=di_res.end(); ++iter){
+            *iter*=-1.0f;
+        }
+
+        shouldEqualSequence(di_res.begin(),di_res.end(), er_res.begin());
+    }
+
+    void grayClosingTest2D()
+    {
+        typedef vigra::MultiArray<2,UInt8> UInt8Image;
+        UInt8Image in(img), tmp(img), res(img);
+
+        //erosion on original image
+        multiGrayscaleErosion(srcMultiArrayRange(in), destMultiArray(tmp),2);
+        multiGrayscaleDilation(srcMultiArrayRange(tmp), destMultiArray(res),2);
+    }
+    
+    IntImage img, img2, lin;
+    IntVolume vol;
+};
+
+        
+struct MorphologyTestSuite
+: public vigra::test_suite
+{
+    MorphologyTestSuite()
+    : vigra::test_suite("MorphologyTestSuite")
+    {
+        add( testCase( &MultiMorphologyTest::binaryErosionTest));
+        add( testCase( &MultiMorphologyTest::binaryErosionTest2));
+        add( testCase( &MultiMorphologyTest::binaryErosionTest1D));
+        add( testCase( &MultiMorphologyTest::binaryErosionAndDilationTest3D));
+        add( testCase( &MultiMorphologyTest::grayErosionTest2D));
+        add( testCase( &MultiMorphologyTest::grayDilationTest2D));
+        add( testCase( &MultiMorphologyTest::grayErosionAndDilationTest2D));
+        add( testCase( &MultiMorphologyTest::grayClosingTest2D));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    MorphologyTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+    return (failed != 0);
+}
+
diff --git a/test/objectfeatures/CMakeLists.txt b/test/objectfeatures/CMakeLists.txt
new file mode 100644
index 0000000..2052e49
--- /dev/null
+++ b/test/objectfeatures/CMakeLists.txt
@@ -0,0 +1,4 @@
+VIGRA_ADD_TEST(test_objectfeatures test.cxx LIBRARIES vigraimpex)
+
+VIGRA_COPY_TEST_DATA(of.gif)
+
diff --git a/test/objectfeatures/of.gif b/test/objectfeatures/of.gif
new file mode 100644
index 0000000..f515c93
Binary files /dev/null and b/test/objectfeatures/of.gif differ
diff --git a/test/objectfeatures/test.cxx b/test/objectfeatures/test.cxx
new file mode 100644
index 0000000..dad316b
--- /dev/null
+++ b/test/objectfeatures/test.cxx
@@ -0,0 +1,1460 @@
+/************************************************************************/
+/*                                                                      */
+/*             Copyright 2011-2012 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <sstream>
+#include <map>
+#include <set>
+
+#include <vigra/unittest.hxx>
+#include <vigra/multi_array.hxx>
+#include <vigra/accumulator.hxx>
+
+namespace std {
+
+template <unsigned int N, class T, class Stride>
+ostream & operator<<(ostream & o, vigra::MultiArrayView<N, T, Stride> const & m)
+{
+    for(vigra::MultiArrayIndex k=0; k<m.size(); ++k)
+        o << m[k] << " ";
+    return o;
+}
+
+} // namespace std
+
+using namespace vigra;
+
+// mask cl.exe shortcomings
+#if defined(_MSC_VER)
+#pragma warning( disable : 4503 )
+#endif
+
+struct AccumulatorTest
+{
+    AccumulatorTest()
+    {}
+    
+    void testStandardizeTag()
+    {
+        using namespace vigra::acc;
+
+            // count
+        should((IsSameType<StandardizeTag<Count>::type,
+                           Count>::value));
+        should((IsSameType<StandardizeTag<Central<Count> >::type,
+                           Count>::value));
+        should((IsSameType<StandardizeTag<Principal<Count> >::type,
+                           Count>::value));
+        should((IsSameType<StandardizeTag<Coord<Count> >::type,
+                           Count>::value));
+        should((IsSameType<StandardizeTag<Weighted<Count> >::type,
+                           Weighted<Count> >::value));
+        should((IsSameType<StandardizeTag<CoordWeighted<Count> >::type,
+                           Weighted<Count> >::value));
+        should((IsSameType<StandardizeTag<Coord<Central<Count> > >::type,
+                           Count>::value));
+        shouldEqual(Count::name(), "PowerSum<0>");
+        shouldEqual(Weighted<Count>::name(), "Weighted<PowerSum<0> >");
+
+        // sum 
+        should((IsSameType<StandardizeTag<Sum>::type,
+                           Sum>::value));
+        should((IsSameType<StandardizeTag<Central<Sum> >::type,
+                           Central<Sum> >::value));
+        should((IsSameType<StandardizeTag<Weighted<Central<Sum> > >::type,
+                           Weighted<Central<Sum> > >::value));
+        should((IsSameType<StandardizeTag<Central<Weighted<Sum> > >::type,
+                           Weighted<Central<Sum> > >::value));
+        shouldEqual(Weighted<Central<Sum> >::name(), "Weighted<Central<PowerSum<1> > >");
+
+            // mean
+        typedef DivideByCount<Principal<Sum> > PrincipalMean;
+        should((IsSameType<StandardizeTag<Mean>::type,
+                           Mean>::value));
+        should((IsSameType<StandardizeTag<Principal<Mean> >::type,
+                           PrincipalMean>::value));
+        should((IsSameType<StandardizeTag<Weighted<Principal<Mean> > >::type,
+                           Weighted<PrincipalMean> >::value));
+        should((IsSameType<StandardizeTag<Principal<Weighted<Mean> > >::type,
+                           Weighted<PrincipalMean> >::value));
+        shouldEqual(Weighted<PrincipalMean>::name(), "Weighted<DivideByCount<Principal<PowerSum<1> > > >");
+
+            // moment
+        should((IsSameType<StandardizeTag<Moment<2> >::type,
+                           DivideByCount<PowerSum<2> > >::value));
+        should((IsSameType<StandardizeTag<Central<Moment<2> > >::type,
+                           DivideByCount<Central<PowerSum<2> > > >::value));
+        should((IsSameType<StandardizeTag<Coord<Central<Moment<2> > > >::type,
+                           Coord<DivideByCount<Central<PowerSum<2> > > > >::value));
+        should((IsSameType<StandardizeTag<Central<Coord<Moment<2> > > >::type,
+                           Coord<DivideByCount<Central<PowerSum<2> > > > >::value));
+        shouldEqual(Coord<Central<Moment<2> > >::name(), "Coord<DivideByCount<Central<PowerSum<2> > > >");
+
+        should((IsSameType<StandardizeTag<Principal<Moment<2> > >::type,
+                           DivideByCount<Principal<PowerSum<2> > > >::value));
+        should((IsSameType<StandardizeTag<Coord<Principal<Moment<2> > > >::type,
+                           Coord<DivideByCount<Principal<PowerSum<2> > > > >::value));
+        should((IsSameType<StandardizeTag<Principal<Coord<Moment<2> > > >::type,
+                           Coord<DivideByCount<Principal<PowerSum<2> > > > >::value));
+
+        should((IsSameType<StandardizeTag<Moment<3> >::type,
+                           DivideByCount<PowerSum<3> > >::value));
+        should((IsSameType<StandardizeTag<Principal<Moment<3> > >::type,
+                           DivideByCount<Principal<PowerSum<3> > > >::value));
+        should((IsSameType<StandardizeTag<Central<Moment<3> > >::type,
+                           DivideByCount<Central<PowerSum<3> > > >::value));
+
+            // SumOfSquaredDifferences
+        should((IsSameType<StandardizeTag<SumOfSquaredDifferences>::type,
+                           Central<PowerSum<2> > >::value));
+        should((IsSameType<StandardizeTag<Weighted<SSD> >::type,
+                           Weighted<Central<PowerSum<2> > > >::value));
+
+            // variance
+        typedef DivideByCount<Central<PowerSum<2> > > CentralVarianceDesired;
+        typedef DivideByCount<Principal<PowerSum<2> > > PrincipalVarianceDesired;
+        should((IsSameType<StandardizeTag<Variance>::type,
+                           CentralVarianceDesired >::value));
+        should((IsSameType<StandardizeTag<Variance>::type,
+                           StandardizeTag<Central<Moment<2> > >::type >::value));
+        should((IsSameType<StandardizeTag<Principal<Variance> >::type,
+                           PrincipalVarianceDesired >::value));
+        should((IsSameType<StandardizeTag<Principal<Variance> >::type,
+                           StandardizeTag<Principal<Moment<2> > >::type >::value));
+        should((IsSameType<StandardizeTag<Coord<Central<Variance> > >::type,
+                           Coord<CentralVarianceDesired> >::value));
+        should((IsSameType<StandardizeTag<Central<Coord<Variance> > >::type,
+                           Coord<CentralVarianceDesired> >::value));
+        should((IsSameType<StandardizeTag<Coord<Principal<Variance> > >::type,
+                           Coord<PrincipalVarianceDesired> >::value));
+        should((IsSameType<StandardizeTag<Principal<Coord<Variance> > >::type,
+                           Coord<PrincipalVarianceDesired> >::value));
+
+            // IsCoordinateFeature
+        should(!IsCoordinateFeature<StandardizeTag<Variance>::type>::value);
+        should(IsCoordinateFeature<StandardizeTag<Coord<Variance> >::type>::value);
+        should(!IsCoordinateFeature<StandardizeTag<Principal<Variance> >::type>::value);
+        should(IsCoordinateFeature<StandardizeTag<Principal<Coord<Variance> > >::type>::value);
+        should(!IsCoordinateFeature<StandardizeTag<Global<Variance> >::type>::value);
+        should(IsCoordinateFeature<StandardizeTag<Global<Coord<Variance> > >::type>::value);
+
+            // IsPrincipalFeature
+        should(!IsPrincipalFeature<StandardizeTag<Variance>::type>::value);
+        should(!IsPrincipalFeature<StandardizeTag<Coord<Variance> >::type>::value);
+        should(IsPrincipalFeature<StandardizeTag<Principal<Variance> >::type>::value);
+        should(IsPrincipalFeature<StandardizeTag<Principal<Coord<Variance> > >::type>::value);
+        should(!IsPrincipalFeature<StandardizeTag<Global<Variance> >::type>::value);
+        should(IsPrincipalFeature<StandardizeTag<Global<Principal<Coord<Variance> > > >::type>::value);
+
+            // std dev
+        typedef RootDivideByCount<Central<PowerSum<2> > > CentralStdDevDesired;
+        typedef RootDivideByCount<Principal<PowerSum<2> > > PrincipalStdDevDesired;
+        should((IsSameType<StandardizeTag<StdDev>::type,
+                           CentralStdDevDesired>::value));
+        should((IsSameType<StandardizeTag<Principal<StdDev> >::type,
+                           PrincipalStdDevDesired>::value));
+        should((IsSameType<StandardizeTag<Coord<Central<StdDev> > >::type,
+                           Coord<CentralStdDevDesired> >::value));
+        should((IsSameType<StandardizeTag<Central<Coord<StdDev> > >::type,
+                           Coord<CentralStdDevDesired> >::value));
+        should((IsSameType<StandardizeTag<Coord<Principal<StdDev> > >::type,
+                           Coord<PrincipalStdDevDesired> >::value));
+        should((IsSameType<StandardizeTag<Principal<Coord<StdDev> > >::type,
+                           Coord<PrincipalStdDevDesired> >::value));
+
+            // skewness
+        should((IsSameType<StandardizeTag<Skewness>::type,
+                           Skewness >::value));
+        should((IsSameType<StandardizeTag<Coord<Skewness> >::type,
+                           Coord<Skewness> >::value));
+        should((IsSameType<StandardizeTag<Principal<Skewness> >::type,
+                           Principal<Skewness> >::value));
+        should((IsSameType<StandardizeTag<Coord<Principal<Skewness> > >::type,
+                           Coord<Principal<Skewness> > >::value));
+        should((IsSameType<StandardizeTag<Principal<Coord<Skewness> > >::type,
+                           Coord<Principal<Skewness> > >::value));
+
+            // AbsPowerSum
+        should((IsSameType<StandardizeTag<AbsSum>::type,
+                           AbsPowerSum<1> >::value));
+        should((IsSameType<StandardizeTag<AbsPowerSum<0> >::type,
+                           Count>::value));
+        should((IsSameType<StandardizeTag<AbsPowerSum<2> >::type,
+                           PowerSum<2> >::value));
+        should((IsSameType<StandardizeTag<AbsPowerSum<3> >::type,
+                           AbsPowerSum<3> >::value));
+
+            // CovarianceEigensystem
+        should((IsSameType<StandardizeTag<CovarianceEigensystem>::type,
+                           DivideByCount<ScatterMatrixEigensystem> >::value));
+        should((IsSameType<StandardizeTag<Central<CovarianceEigensystem> >::type,
+                           DivideByCount<ScatterMatrixEigensystem> >::value));
+        should((IsSameType<StandardizeTag<Coord<CovarianceEigensystem> >::type,
+                           Coord<DivideByCount<ScatterMatrixEigensystem> > >::value));
+
+            // CoordinateSystem 
+        should((IsSameType<StandardizeTag<Central<CoordinateSystem> >::type,
+                           CoordinateSystem>::value));
+        should((IsSameType<StandardizeTag<Principal<CoordinateSystem> >::type,
+                           Principal<CoordinateSystem> >::value));
+
+            // RegionRadii
+        should((IsSameType<StandardizeTag<RegionRadii>::type,
+                           Coord<RootDivideByCount<Principal<PowerSum<2> > > > >::value));
+        shouldEqual(StandardizeTag<RegionRadii>::type::name(), "Coord<RootDivideByCount<Principal<PowerSum<2> > > >");
+
+            // HasModifierPriority
+        using namespace vigra::acc::acc_detail;
+        should((HasModifierPriority<StandardizeTag<Count>::type, AccumulatorPriority>::value));
+        should(!(HasModifierPriority<StandardizeTag<Count>::type, AccessDataPriority>::value));
+        should((HasModifierPriority<StandardizeTag<Weighted<Count> >::type, WeightingPriority>::value));
+
+            // nested Select
+        should((IsSameType<Select<Count, Mean, Select<Sum, Minimum>, Variance>::type,
+                           Select<Count, Mean, Sum, Minimum, Variance>::type>::value));
+    }
+
+    template <class SOURCE, class REFERENCE>
+    void testLongFormImpl(const char * message)
+    {
+        using namespace vigra::acc;
+        using namespace vigra::acc::acc_detail;
+
+        typedef typename StandardizeTag<SOURCE >::type StdSource;
+        typedef typename TagLongForm<StdSource, MinPriority>::type LongSource;
+        typedef typename StandardizeTagLongForm<LongSource>::type Dest;
+            
+        shouldMsg((IsSameType<LongSource, REFERENCE >::value), message);
+//        shouldMsg((IsSameType<LongSource, REFERENCE >::value), typeid(LongSource).name());
+        shouldMsg((IsSameType<StdSource, Dest>::value), message);
+    }
+
+    void testTagTransfer()
+    {
+        using namespace vigra::acc;
+
+#define TEST_LONG_FORM(SOURCE, TARGET) testLongFormImpl<SOURCE, TARGET >(#SOURCE)
+#define DM DefaultModifier
+        {
+            using namespace vigra::acc::acc_detail;
+
+
+            TEST_LONG_FORM(Minimum, DM<DM<DM<DM<DM<Minimum> > > > >);
+            TEST_LONG_FORM(Principal<Minimum>, DM<DM<DM<DM<Principal<Minimum> > > > >);
+            TEST_LONG_FORM(Weighted<Coord<Principal<Minimum> > >, DM<Weighted<Coord<DM<Principal<Minimum> > > > >);
+            TEST_LONG_FORM(Mean, DM<DM<DM<DivideByCount<DM<Sum> > > > >);
+            TEST_LONG_FORM(Coord<Mean>, DM<DM<Coord<DivideByCount<DefaultModifier<Sum> > > > >);
+            TEST_LONG_FORM(Count, DM<DM<DM<DM<DM<Count> > > > >);
+            TEST_LONG_FORM(Weighted<Count>, DM<Weighted<DM<DM<DM<Count> > > > >);
+            TEST_LONG_FORM(Coord<Count>, DM<DM<DM<DM<DM<Count> > > > >);
+            TEST_LONG_FORM(Principal<Variance>, DM<DM<DM<DivideByCount<Principal<PowerSum<2> > > > > >);
+            TEST_LONG_FORM(Global<Count>, Global<DM<DM<DM<DM<PowerSum<0> > > > > >);
+        }
+#undef TEST_LONG_FORM
+#undef DM
+          
+          typedef Select<Count, Sum, Mean, Variance>::type Target;
+
+          should((IsSameType<TransferModifiers<Minimum, Target>::type,
+                             Target>::value));
+
+          typedef Select<Count, Coord<Sum>, Coord<Mean>, Coord<Variance> >::type Desired1;
+          should((IsSameType<TransferModifiers<Coord<Minimum>, Target>::type,
+                             Desired1>::value));
+
+          typedef Select<Count, Sum, Mean, Principal<Variance> >::type Desired2;
+          should((IsSameType<TransferModifiers<Principal<Minimum>, Target>::type,
+                             Desired2>::value));
+
+          typedef Select<Count, Coord<Sum>, Coord<Mean>, Coord<Principal<Variance> > >::type Desired3;
+          should((IsSameType<TransferModifiers<Coord<Principal<Minimum> >, Target>::type,
+                             Desired3>::value));
+
+          typedef Select<Weighted<Count>, CoordWeighted<Sum>, CoordWeighted<Mean>, CoordWeighted<Variance> >::type Desired4;
+          should((IsSameType<TransferModifiers<Coord<Weighted<Minimum> >, Target>::type,
+                             Desired4>::value));
+
+          typedef Select<Weighted<Count>, CoordWeighted<Sum>, CoordWeighted<Mean>, CoordWeighted<Principal<Variance> > >::type Desired5;
+          should((IsSameType<TransferModifiers<Principal<Coord<Weighted<Minimum> > >, Target>::type,
+                             Desired5>::value));
+
+          should((IsSameType<TransferModifiers<Principal<Minimum>, Centralize>::type,
+                             PrincipalProjection>::value));
+          should((IsSameType<TransferModifiers<Principal<Weighted<Coord<Minimum> > >, Centralize>::type,
+                             Weighted<Coord<PrincipalProjection> > >::value));
+    }
+
+    void testScalar()
+    {
+        using namespace vigra::acc;
+        
+        { 
+            typedef AccumulatorChain<double, Select<Count> > A;
+            A a;
+
+            shouldEqual(1, a.passesRequired());
+
+            a(1.0);
+            a(2.0);
+            a(3.0);
+            
+            shouldEqual(get<Count>(a), 3.0);
+            // access to an inactive statistic triggers a static assertion
+            // get<Mean>(a);
+        }
+
+        {
+            typedef AccumulatorChain<double, Select<CovarianceEigensystem, Covariance, UnbiasedVariance, UnbiasedStdDev, 
+                                               Variance, StdDev, Minimum, Maximum, Skewness, Kurtosis,
+                                               AbsSum, SumOfAbsDifferences, MeanAbsoluteDeviation, 
+                                               Principal<Variance>, Principal<CoordinateSystem>
+                                              > > A;
+
+            A a;
+
+
+            shouldEqual(2, a.passesRequired());
+            shouldEqual(24, A::staticSize);
+
+            double data[] = { 1.0, 2.0, 3.0, 5.0 };
+
+            for(int k=0; k<4; ++k)
+                a(data[k]);
+
+            shouldEqual(get<Count>(a), 4.0);
+            shouldEqual(get<Minimum>(a), 1.0);
+            shouldEqual(get<Maximum>(a), 5.0);
+            shouldEqual(get<Sum>(a), 11.0);
+            shouldEqual(get<AbsSum>(a), 11.0);
+            shouldEqual(get<Mean>(a), 2.75);
+            shouldEqualTolerance(get<UnbiasedVariance>(a), 2.9166666666666665, 1e-15);
+            shouldEqualTolerance(get<UnbiasedStdDev>(a), sqrt(2.9166666666666665), 1e-15);
+            shouldEqualTolerance(get<Variance>(a), 2.1875, 1e-15);
+            shouldEqualTolerance(get<StdDev>(a), sqrt(2.1875), 1e-15);
+            shouldEqualTolerance(get<Covariance>(a), 2.1875, 1e-15);
+
+            std::pair<double, double> seigen = get<ScatterMatrixEigensystem>(a);
+            shouldEqual(seigen.first, 8.75);
+            shouldEqual(seigen.second, 1.0);
+
+            std::pair<double, double> eigen = get<CovarianceEigensystem>(a);
+            shouldEqual(eigen.first, 2.1875);
+            shouldEqual(eigen.second, 1.0);
+
+            shouldEqual(get<Principal<Variance> >(a), 2.1875);
+            shouldEqual(get<Principal<CoordinateSystem> >(a), 1.0);
+
+            for(int k=0; k<4; ++k)
+                a.updatePass2(data[k]);
+
+            shouldEqual(get<Count>(a), 4.0);
+            shouldEqualTolerance(get<CentralMoment<2> >(a),  2.1875, 1e-15);
+            shouldEqualTolerance(get<Skewness>(a), 0.43465075957466565, 1e-15);
+            shouldEqualTolerance(get<Kurtosis>(a), -1.1542857142857144, 1e-15);
+            shouldEqual(get<SumOfAbsDifferences>(a), 5);
+            shouldEqual(get<MeanAbsoluteDeviation>(a), 1.25);
+        }
+
+        { 
+            DynamicAccumulatorChain<double, Select<Mean, Covariance, StdDev, Minimum, CentralMoment<4> > > a;
+
+            shouldEqual(0, a.passesRequired());
+
+            activate<Count>(a);
+            should(isActive<Count>(a));
+            should(!isActive<Covariance>(a));
+            shouldEqual(1, a.passesRequired());
+
+            a(1.0);
+            a(2.0);
+            a(3.0);
+
+            shouldEqual(get<Count>(a), 3.0);
+
+            try 
+            {
+                get<Mean>(a);
+                failTest("get<Mean>() failed to throw exception");
+            }
+            catch(ContractViolation & c) 
+            {
+                std::string expected("\nPrecondition violation!\nget(accumulator): attempt to access inactive statistic");
+                std::string message(c.what());
+                should(0 == expected.compare(message.substr(0,expected.size())));
+            }
+
+            a.reset();
+            shouldEqual(0, a.passesRequired());
+            should(!isActive<Count>(a));
+
+            activate<Mean>(a);
+            activate<StdDev>(a);
+            activate<Covariance>(a);
+            activate<CentralMoment<4> >(a);
+            //activate<Minimum>(a);
+            a.activate("Minimum");
+
+            should(isActive<Count>(a));
+            should(isActive<Minimum>(a));
+            should(isActive<Sum>(a));
+            should(isActive<Mean>(a));
+            should(isActive<Variance>(a));
+            should(isActive<StdDev>(a));
+            should(isActive<CentralMoment<4> >(a));
+            should(isActive<Covariance>(a));
+
+            shouldEqual(2, a.passesRequired());
+
+            a.reset();
+            a.activateAll();
+
+            a(1.0);
+            a(2.0);
+            a(3.0);
+
+            shouldEqual(get<Count>(a), 3.0);
+            shouldEqual(get<Minimum>(a), 1.0);
+            shouldEqual(get<Sum>(a), 6.0);
+            shouldEqual(get<Mean>(a), 2.0);
+            shouldEqual(get<Variance>(a), 2.0/3.0);
+            shouldEqual(get<StdDev>(a), sqrt(2.0/3.0));
+            shouldEqual(get<Covariance>(a), 2.0/3.0);
+
+            a.updatePass2(1.0);
+            a.updatePass2(2.0);
+            a.updatePass2(3.0);
+
+            shouldEqual(get<Count>(a), 3.0);
+            shouldEqual(get<CentralMoment<4> >(a), 2.0/3.0);
+        }
+    }
+
+    void testVector()
+    {
+        using namespace vigra::acc;
+
+        {
+            typedef TinyVector<int, 3> V;
+            typedef AccumulatorChain<V, Select<StdDev, Mean, CovarianceEigensystem, Covariance, Minimum, Maximum, CentralMoment<2>,
+                                          AbsSum, SumOfAbsDifferences, MeanAbsoluteDeviation, 
+                                          Principal<Variance>, Principal<CoordinateSystem>, Principal<Sum>,
+                                          Principal<Minimum>, Principal<Maximum>, Principal<Skewness>, Principal<Kurtosis>, Principal<SumOfAbsDifferences>
+                                          > > A;
+            typedef LookupTag<Mean, A>::value_type W;
+            typedef LookupTag<Covariance, A>::value_type Var;
+
+            A a;
+
+            static const int SIZE = 4;
+            V d[SIZE] = { V(1,2,3), V(2,3,0), V(3,4,2), V(2,1,2) };
+
+            for(int k=0; k<SIZE; ++k)
+                a(d[k]);
+            for(int k=0; k<SIZE; ++k)
+                a.updatePass2(d[k]);
+
+            shouldEqual(get<Count>(a), 4.0);
+            shouldEqual(get<Minimum>(a), V(1,1,0));
+            shouldEqual(get<Maximum>(a), V(3,4,3));
+            shouldEqual(get<Sum>(a), W(8.0, 10.0, 7.0));
+            shouldEqual(get<AbsSum>(a), W(8.0, 10.0, 7.0));
+            shouldEqual(get<Mean>(a), W(2.0, 2.5, 7.0/4.0));
+            shouldEqual(get<CentralMoment<2> >(a), W(0.5, 1.25, 1.1875));
+            shouldEqual(get<Variance>(a),  W(0.5, 1.25, 1.1875));
+            shouldEqualTolerance(sqrt(W(0.5, 1.25, 1.1875)), get<StdDev>(a), W(1e-15));
+            shouldEqualTolerance(get<SumOfAbsDifferences>(a), W(2.0, 4.0, 3.5), W(1e-15));
+            shouldEqualTolerance(get<MeanAbsoluteDeviation>(a), W(0.5, 1.0, 7.0/8.0), W(1e-15));
+
+            double covarianceData[] = { 
+                0.5,   0.5,  -0.25,
+                0.5,   1.25, -0.375,
+               -0.25, -0.375, 1.1875 };
+            Var covariance(3,3, covarianceData);
+            shouldEqual(get<Covariance>(a).shape(), Shape2(3,3));
+            shouldEqual(get<Covariance>(a), covariance);
+            std::pair<W const &, Var const &> eigen = get<CovarianceEigensystem>(a);
+            W ew(1.8181423035878563, 0.87335382939336145, 0.24600386701878226); 
+            shouldEqualTolerance(ew, eigen.first, W(1e-15));
+            shouldEqualTolerance(ew, get<Principal<Variance> >(a), W(1e-15));
+
+            double eigenvectorData[] = {
+                -0.38281255664062192, -0.19398130489891852, -0.90323075668844639,
+                -0.71942795069852928, -0.55075408575738086,  0.42319423528123123,
+                 0.57954979961344579,- 0.81181351945583191, -0.071280006991795777 };
+            Var ev(3,3, eigenvectorData),
+                eps(3, 3, 1e-14);
+            shouldEqualTolerance(ev, eigen.second, eps);
+            shouldEqualTolerance(ev, get<Principal<CoordinateSystem> >(a), eps);
+
+            shouldEqualTolerance(get<Principal<Sum> >(a), W(0.0), W(1e-15));
+            shouldEqualTolerance(get<Principal<Minimum> >(a), W(-1.3739261246727945, -1.2230658133989472, -0.6526113546697957), W(1e-15));
+            shouldEqualTolerance(get<Principal<Maximum> >(a), W(1.4669637815066938,  1.1452966161690161, 0.60253363030808593), W(1e-15));
+            shouldEqualTolerance(get<Principal<Skewness> >(a), W(0.01148108748350361, -0.07581454384153662, -0.09140344434535799), W(1e-13));
+            shouldEqualTolerance(get<Principal<Kurtosis> >(a), W(-1.9829394126459396, -1.6241963546875782, -1.6255854346698215), W(1e-13));
+            shouldEqualTolerance(get<Principal<SumOfAbsDifferences> >(a), W(5.3819863149157, 3.5369487298822575, 1.8777415203686885), W(1e-14));
+        }
+
+        {
+            using namespace vigra::multi_math;
+            
+            typedef MultiArray<1, int> V;
+            typedef TinyVector<int, 3> T;
+            typedef AccumulatorChain<V::view_type, Select<Covariance, Mean, StdDev, Minimum, Maximum, CentralMoment<2> > > A;
+            typedef LookupTag<Mean, A>::value_type W;
+            typedef LookupTag<Covariance, A>::value_type Var;
+
+            A a;
+
+            Shape1 s(3);
+
+            V data[] = { V(s, 1), V(s, 2), V(s, 3) };
+
+            a(data[0]);
+            a(data[1]);
+            a(data[2]);
+
+            a.updatePass2(data[0]);
+            a.updatePass2(data[1]);
+            a.updatePass2(data[2]);
+
+            shouldEqual(get<Count>(a), 3.0);
+            shouldEqual(get<Minimum>(a), V(s, 1));
+            shouldEqual(get<Maximum>(a), V(s, 3));
+            shouldEqual(get<Sum>(a), W(s, 6.0));
+            shouldEqual(get<Mean>(a),  W(s, 2.0));
+            shouldEqual(get<CentralMoment<2> >(a),  W(s, 2.0 / 3.0));
+
+            Var covariance(3,3);
+            covariance.init(2.0/3.0);
+            shouldEqual(get<Covariance>(a), covariance);
+
+            W variance(s, 2.0/3.0);
+            shouldEqual(get<Variance>(a), variance);
+
+            W stddev = sqrt(variance);
+            shouldEqualTolerance(stddev, get<StdDev>(a), W(1e-15));
+
+            a.reset(1);
+
+            a(V(s, T(0, 2, 4).begin()));
+            shouldEqual(get<Minimum>(a), V(s, T(0,1,1).begin()));
+            shouldEqual(get<Maximum>(a), V(s, T(3,3,4).begin()));
+        }
+
+        {
+            typedef TinyVector<double, 2> V;
+            static const int SIZE = 20;
+
+            V data[SIZE] = {
+                V(1.88417085437108889, 3.10984300178095197),
+                V(3.22221249967652135, 4.62610895051767734),
+                V(5.02965943418706019, 3.61409282557627254),
+                V(1.99001871343947201, 0.44572597781938073),
+                V(0.82190895017090260, 1.52581824695525770),
+                V(1.79509471114960295, 4.54126165421070915),
+                V(0.63954006398369945, 4.03816177019905265),
+                V(-1.19055182745611221, 3.05473509195811443),
+                V(1.60460514736327031, 2.39320817128161423),
+                V(-1.26828508191601941, 3.08007018243650110),
+                V(2.67471223051054885, 2.36574957680121889),
+                V(2.54777120650106648, 3.00252905176459528),
+                V(-0.49276533572213554, -1.13913810037296859),
+                V(3.08185249197166877, 2.61911514709572302),
+                V(-3.21266705448485190, 0.62656641585875028),
+                V(1.25495155317623874, 0.46593677346153228),
+                V(0.71219264300245499, 2.68491068466799110),
+                V(0.91993307568972671, 1.99693758751466821),
+                V(2.11157305527596195, -1.11069145843301786),
+                V(0.10242024165277441, 2.44449590189711241)
+            };
+
+            typedef AccumulatorChain<V, Select<Mean, Variance, Covariance, Central<Sum>,
+                                          Principal<Variance>, Principal<CoordinateSystem>, Principal<Sum>
+                                          > > A;
+            typedef LookupTag<Covariance, A>::value_type Var;
+
+            A a;
+
+            for(int k=0; k<SIZE; ++k)
+                a(data[k]);
+
+            for(int k=0; k<SIZE; ++k)
+                a.updatePass2(data[k]);
+
+
+            shouldEqual(get<Count>(a), (double)SIZE);
+            shouldEqualTolerance(get<Mean>(a), V(1.2114173786271469, 2.2192718726495571), V(1e-15));
+            shouldEqualTolerance(get<Central<Sum> >(a), V(0.0),  V(1e-14));
+            shouldEqualTolerance(get<Principal<Sum> >(a), V(0.0),  V(1e-14));
+
+            Var eps = Var(2,2, 1e-15);
+            double covarianceData[] = {
+                 3.24260523085696217,  0.85916467806966068,
+                 0.85916467806966068,  2.57086707635742417 };
+            Var cov(2,2, covarianceData);
+            shouldEqualTolerance(cov, get<Covariance>(a), eps);
+
+            V principalVariance(3.82921757948803698, 1.98425472772634914);
+            shouldEqualTolerance(get<Principal<Variance> >(a), principalVariance, V(1e-15));
+
+            double eigenvectorData[] = {
+                 0.82586108137035807,  0.56387363325286188,
+                 0.56387363325286188, -0.82586108137035807 };
+            Var ev(2,2, eigenvectorData);
+            shouldEqualTolerance(ev, get<Principal<CoordinateSystem> >(a), eps);
+
+                // desired principal projection
+            V principal[SIZE] = {
+                V(1.05777049122698186, -0.35614008909044692),
+                V(3.01778940082927427, -0.85387872117719943),
+                V(3.93984027140249449, 1.00107768000535380),
+                V(-0.35703922713407876, 1.90373529408056230),
+                V(-0.71270006734035740, 0.35306282845985459),
+                V(1.79134520751326742, -1.58852073379423842),
+                V(0.55333283753554596, -1.82461691686673699),
+                V(-1.51259720503357187, -2.04438366093898516),
+                V(0.42279656853422592, 0.07806099602999564),
+                V(-1.56250828510342998, -2.10913865877495876),
+                V(1.29107318397063953, 0.70414314950436341),
+                V(1.54530068874035664, 0.10667306729959503),
+                V(-3.30113701276602800, 1.81263639313852387),
+                V(1.77018064523347562, 0.72447404411252858),
+                V(-4.55176376662593363, -1.17927111226656489),
+                V(-0.95270625221923966, 1.47255899419368674),
+                V(-0.14972883129345838, -0.66605263830794725),
+                V(-0.36609398278207039, 0.01925692021370382),
+                V(-1.13427498157747753, 3.25766116941665018),
+                V(-0.78887968311061840, -0.81133800523773636)
+            };
+
+            for(int k=0; k<SIZE; ++k)
+                shouldEqualTolerance(principal[k], getAccumulator<PrincipalProjection>(a)(data[k]), V(1e-14));
+
+                // check that statistics of points in principal representation have expected properties
+            a.reset();
+            for(int k=0; k<SIZE; ++k)
+                a(principal[k]);
+
+            shouldEqual(SIZE, get<Count>(a));
+            shouldEqualTolerance(V(0.0), get<Mean>(a), V(1e-14));
+            shouldEqualTolerance(get<Variance>(a), principalVariance, V(1e-15));
+            shouldEqualTolerance(get<Principal<Variance> >(a), principalVariance, V(1e-15));
+
+            Var res = abs(get<Principal<CoordinateSystem> >(a)),
+                ref = linalg::identityMatrix<double>(2);
+            shouldEqualTolerance(res, ref, eps);
+            ref(0,0) = principalVariance[0];
+            ref(1,1) = principalVariance[1];
+            shouldEqualTolerance(get<Covariance>(a), ref, eps);
+        }
+    }
+
+    void testMerge()
+    {
+        using namespace vigra::acc;
+        
+        typedef AccumulatorChain<double, Select<Covariance, StdDev, Minimum, Maximum, Skewness, Kurtosis, 
+                                           CentralMoment<3>, CentralMoment<4> > > A;
+
+        A a, b;
+
+        double data[] = { 1.0, 2.0, 3.0, 4.0, 6.0 };
+
+        for(int k=0; k<3; ++k)
+            a(data[k]);
+
+        for(int k=0; k<3; ++k)
+            a.updatePass2(data[k]);
+
+        for(int k=3; k<5; ++k)
+            b(data[k]);
+
+        for(int k=3; k<5; ++k)
+            b.updatePass2(data[k]);
+
+        a += b;
+
+        shouldEqual(get<Count>(a), 5.0);
+        shouldEqual(get<Minimum>(a), 1.0);
+        shouldEqual(get<Maximum>(a), 6.0);
+        shouldEqual(get<Sum>(a), 16.0);
+        shouldEqualTolerance(get<Mean>(a), 3.2, 1e-15);
+        shouldEqualTolerance(get<SSD>(a), 14.8, 1e-15);
+        shouldEqualTolerance(get<Variance>(a), 2.96, 1e-15);
+        shouldEqualTolerance(get<StdDev>(a), sqrt(2.96), 1e-15);
+        shouldEqualTolerance(get<FlatScatterMatrix>(a), 14.8, 1e-15);
+        shouldEqualTolerance(get<Covariance>(a), 2.96, 1e-15);
+        shouldEqualTolerance(get<CentralMoment<2> >(a), 2.96, 1e-15);
+        shouldEqualTolerance(get<CentralMoment<3> >(a), 2.016, 1e-15);
+        shouldEqualTolerance(get<CentralMoment<4> >(a), 17.4752, 1e-15);
+        shouldEqualTolerance(get<Skewness>(a), 0.395870337343817, 1e-15);
+        shouldEqualTolerance(get<Kurtosis>(a), -1.0054784514243973, 1e-15);
+    }
+
+    void testCoordAccess()
+    {
+        using namespace vigra::acc;
+
+        {
+            typedef CoupledIteratorType<3>::type Iterator;
+            typedef Iterator::value_type Handle;
+            typedef Shape3 V;
+
+            typedef AccumulatorChain<Handle, Select<Coord<Maximum>, Coord<Minimum>, Coord<Mean>, Coord<StdDev>, Coord<Covariance>,
+                                               Coord<Principal<Variance> >, Coord<Principal<CoordinateSystem> >,
+                                               Coord<AbsSum>, Coord<MeanAbsoluteDeviation>, Coord<CovarianceEigensystem>
+                                          > > A;
+
+            typedef LookupTag<Coord<Mean>, A>::value_type W;
+            typedef LookupTag<Coord<Covariance>, A>::value_type Var;
+            
+            A a;
+
+            Iterator i = createCoupledIterator(V(4,4,4));
+
+            a(*(i+V(1,2,3)));
+            a(*(i+V(2,3,1)));
+            a(*(i+V(3,1,2)));
+
+            a.updatePass2(*(i+V(1,2,3)));
+            a.updatePass2(*(i+V(2,3,1)));
+            a.updatePass2(*(i+V(3,1,2)));
+
+            shouldEqual(get<Count>(a), 3.0);
+            shouldEqual(get<Coord<Minimum> >(a), V(1));
+            shouldEqual(get<Coord<Maximum> >(a), V(3));
+            shouldEqual(get<Coord<Sum> >(a), W(6.0));
+            shouldEqual(get<Coord<AbsSum> >(a), W(6.0));
+            shouldEqual(get<Coord<Mean> >(a), W(2.0));
+            shouldEqual(get<Coord<CentralMoment<2> > >(a), W(2.0/3.0));
+            shouldEqual(get<Coord<Variance> >(a), W(2.0/3.0));
+            shouldEqual(get<Coord<SumOfAbsDifferences> >(a), W(2.0));
+            shouldEqual(get<Coord<MeanAbsoluteDeviation> >(a), W(2.0/3.0));
+
+            W stddev = sqrt( W(2.0/3.0));
+            shouldEqualTolerance(stddev, get<Coord<StdDev> >(a), W(1e-15));
+
+            double covarianceData[] = { 
+                2.0/3.0, -1.0/3.0, -1.0/3.0,
+               -1.0/3.0,  2.0/3.0, -1.0/3.0,
+               -1.0/3.0, -1.0/3.0,  2.0/3.0 };
+            Var covariance(3,3, covarianceData);
+            shouldEqual(get<Coord<Covariance> >(a), covariance);
+
+            W sew(3.0, 3.0, 0.0); 
+            std::pair<W const &, Var const &> seigen = get<Coord<ScatterMatrixEigensystem> >(a);
+            shouldEqualTolerance(sew, seigen.first, W(1e-15));
+
+            W ew(1.0, 1.0, 0.0); 
+            std::pair<W const &, Var const &> eigen = get<Coord<CovarianceEigensystem> >(a);
+            shouldEqualTolerance(ew, eigen.first, W(1e-15));
+            shouldEqualTolerance(ew, get<Coord<Principal<Variance> > >(a), W(1e-15));
+
+            double eigenvectorData[] = {
+                -0.7071067811865476, -0.4082482904638629, -0.5773502691896257,
+                 0.7071067811865476, -0.4082482904638629, -0.5773502691896257,
+                 0.0               ,  0.816496580927726,  -0.5773502691896257 };
+            double eigenvectorDataSwapped[] = {
+                -0.4082482904638629, -0.7071067811865476, -0.5773502691896257,
+                -0.4082482904638629,  0.7071067811865476, -0.5773502691896257,
+                 0.816496580927726,   0.0               , -0.5773502691896257 };
+            
+            Var ev(3,3, closeAtTolerance(seigen.second(0,0), -0.7071067811865476, 1e-15)
+                                ? eigenvectorData
+                                : eigenvectorDataSwapped),
+                eps(3, 3, 1e-15);
+            shouldEqualTolerance(ev, seigen.second, W(1e-15));
+            shouldEqualTolerance(ev, get<Coord<Principal<CoordinateSystem> > >(a), W(1e-15));
+        }
+
+        {
+            typedef CoupledIteratorType<3, double, double>::type Iterator;
+            typedef Iterator::value_type Handle;
+            typedef Shape3 V;
+
+            typedef AccumulatorChain<Handle, Select<Mean, Coord<Mean>, Coord<Maximum>, Coord<Minimum>, Weighted<Count>,
+                                               Weighted<Mean>, CoordWeighted<Mean>,
+                                               ArgMinWeight, ArgMaxWeight,
+                                               Coord<ArgMinWeight>, Coord<ArgMaxWeight>, WeightArg<2>, DataArg<1>
+                                          > > A;
+            
+            A a;
+
+            typedef LookupTag<Coord<Mean>, A>::value_type W;
+            
+            MultiArray<3, double> data(Shape3(4,4,4), 1.0);
+            data(1,2,3) = 0.5;
+            data(3,1,2) = 4.0;
+            MultiArray<3, double> weights(Shape3(4,4,4), 1.0);
+            weights(1,2,3) = 0.5;
+            weights(3,1,2) = 0.25;
+
+            Iterator i = createCoupledIterator(data, weights);
+
+            a(*(i+V(1,2,3)));
+            a(*(i+V(2,3,1)));
+            a(*(i+V(3,1,2)));
+
+            shouldEqual(get<Count>(a), 3.0);
+            shouldEqual(get<Coord<Minimum> >(a), V(1));
+            shouldEqual(get<Coord<Maximum> >(a), V(3));
+            shouldEqual(get<Coord<Mean> >(a), W(2.0));
+            shouldEqualTolerance(get<Weighted<Mean> >(a), 1.2857142857142858, 1e-15);
+            shouldEqualTolerance(get<Mean>(a), 1.8333333333333333, 1e-15);
+            W coordWeightedMean(1.8571428571428572, 2.4285714285714284,  1.7142857142857142);
+            shouldEqualTolerance(coordWeightedMean, get<CoordWeighted<Mean> >(a), W(1e-15));
+            shouldEqual(4.0, get<ArgMinWeight>(a));
+            shouldEqual(1.0, get<ArgMaxWeight>(a));
+            shouldEqual(V(3,1,2), get<Coord<ArgMinWeight> >(a));
+            shouldEqual(V(2,3,1), get<Coord<ArgMaxWeight> >(a));
+
+            // test coordinate offset
+            A b;
+            b.setCoordinateOffset(W(0.5, 1.5, -0.5));
+
+            b(*(i+V(1,2,3)));
+            b(*(i+V(2,3,1)));
+            b(*(i+V(3,1,2)));
+
+            shouldEqual(get<Count>(b), 3.0);
+            shouldEqual(get<Coord<Minimum> >(b), W(1.5, 2.5, 0.5));
+            shouldEqual(get<Coord<Maximum> >(b), W(3.5, 4.5, 2.5));
+            shouldEqual(get<Coord<Mean> >(b), W(2.5, 3.5, 1.5));
+            shouldEqualTolerance(get<Weighted<Mean> >(b), 1.2857142857142858, 1e-15);
+            shouldEqualTolerance(get<Mean>(b), 1.8333333333333333, 1e-15);
+            coordWeightedMean = W(2.3571428571428572, 3.9285714285714284,  1.2142857142857142);
+            shouldEqualTolerance(coordWeightedMean, get<CoordWeighted<Mean> >(b), W(1e-15));
+            shouldEqual(4.0, get<ArgMinWeight>(b));
+            shouldEqual(1.0, get<ArgMaxWeight>(b));
+            shouldEqual(W(3.5,2.5,1.5), get<Coord<ArgMinWeight> >(b));
+            shouldEqual(W(2.5,4.5,0.5), get<Coord<ArgMaxWeight> >(b));
+        }
+    }
+
+    void testIndexSpecifiers()
+    {
+        using namespace vigra::acc;
+
+        typedef CoupledIteratorType<3, double, double>::type Iterator;
+        typedef Iterator::value_type Handle;
+        typedef Shape3 V;
+        
+        typedef AccumulatorChain<Handle, Select<WeightArg<1>, DataArg<2>, Mean, Coord<Mean>, Coord<Maximum>, Coord<Minimum>, Weighted<Count>, Weighted<Mean>, CoordWeighted<Mean>, ArgMinWeight, ArgMaxWeight, Coord<ArgMinWeight>, Coord<ArgMaxWeight> > >  A;
+        A a;
+        
+        typedef LookupTag<Coord<Mean>, A>::value_type W;
+        
+        MultiArray<3, double> data(Shape3(4,4,4), 1.0);
+        data(1,2,3) = 0.5;
+        data(3,1,2) = 4.0;
+        MultiArray<3, double> weights(Shape3(4,4,4), 1.0);
+        weights(1,2,3) = 0.5;
+        weights(3,1,2) = 0.25;
+        
+        Iterator i = createCoupledIterator(weights, data);
+        
+        a(*(i+V(1,2,3)));
+        a(*(i+V(2,3,1)));
+        a(*(i+V(3,1,2)));
+        
+        shouldEqual(get<Count>(a), 3.0);
+        shouldEqual(get<Coord<Minimum> >(a), V(1));
+        shouldEqual(get<Coord<Maximum> >(a), V(3));
+        shouldEqual(get<Coord<Mean> >(a), W(2.0));
+        shouldEqualTolerance(get<Weighted<Mean> >(a), 1.2857142857142858, 1e-15);
+        shouldEqualTolerance(get<Mean>(a), 1.8333333333333333, 1e-15);
+        W coordWeightedMean(1.8571428571428572, 2.4285714285714284,  1.7142857142857142);
+        shouldEqualTolerance(coordWeightedMean, get<CoordWeighted<Mean> >(a), W(1e-15));
+        shouldEqual(4.0, get<ArgMinWeight>(a));
+        shouldEqual(1.0, get<ArgMaxWeight>(a));
+        shouldEqual(V(3,1,2), get<Coord<ArgMinWeight> >(a));
+        shouldEqual(V(2,3,1), get<Coord<ArgMaxWeight> >(a));
+
+        AccumulatorChain<CoupledArrays<3, double>, Select<WeightArg<1>, Coord<ArgMinWeight> > > b;
+
+        extractFeatures(weights, b);
+
+        shouldEqual(V(3,1,2), get<Coord<ArgMinWeight> >(b));
+    }
+  
+    void testHistogram()
+    {
+        static const int SIZE = 30, HSIZE = 10;
+        int data[SIZE] = {4, 3, 2, 2, 2, 0, 3, 6, 8, 8, 4, 0, 2, 0, 2, 8, 7, 8, 6, 0, 9, 3, 7, 0, 9, 5, 9, 9, 2, 4};
+        // the same sorted:
+        // int data[SIZE] = {0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9};
+
+        using namespace vigra::acc;
+        {
+
+            typedef AccumulatorChain<int, Select<StandardQuantiles<UserRangeHistogram<HSIZE> >, StandardQuantiles<AutoRangeHistogram<HSIZE> >,
+                                                 StandardQuantiles<IntegerHistogram<HSIZE> >, StandardQuantiles<IntegerHistogram<0> >,
+                                                 DivideByCount<UserRangeHistogram<HSIZE> >, StandardQuantiles<UserRangeHistogram<HSIZE+2> >,
+                                                 StandardQuantiles<UserRangeHistogram<3> >, StandardQuantiles<IntegerHistogram<HSIZE+2> >
+                                    > > A;
+            A a;
+
+            getAccumulator<UserRangeHistogram<HSIZE> >(a).setMinMax(-0.5, 9.5);
+            getAccumulator<UserRangeHistogram<HSIZE+2> >(a).setMinMax(-1.5, 10.5);
+            getAccumulator<UserRangeHistogram<3> >(a).setMinMax(-20.0, 30.0);  // all data in one bin
+            getAccumulator<IntegerHistogram<0> >(a).setBinCount(HSIZE);
+
+            shouldEqual(HSIZE, get<IntegerHistogram<HSIZE> >(a).size());
+            shouldEqual(HSIZE, get<UserRangeHistogram<HSIZE> >(a).size());
+            shouldEqual(HSIZE, get<AutoRangeHistogram<HSIZE> >(a).size());
+            shouldEqual(HSIZE, get<IntegerHistogram<0> >(a).size());
+
+            for(int k=0; k<SIZE; ++k)
+                a(data[k]);
+
+            for(int k=0; k<SIZE; ++k)
+                a.updatePass2(data[k]);
+
+            double h[HSIZE] = { 5.0, 0.0, 6.0, 3.0, 3.0, 1.0, 2.0, 2.0, 4.0, 4.0 };
+
+            shouldEqualSequence(h, h+HSIZE, get<IntegerHistogram<HSIZE> >(a).begin());
+            shouldEqualSequence(h, h+HSIZE, get<UserRangeHistogram<HSIZE> >(a).begin());
+            shouldEqualSequence(h, h+HSIZE, get<AutoRangeHistogram<HSIZE> >(a).begin());
+            shouldEqualSequence(h, h+HSIZE, get<IntegerHistogram<0> >(a).begin());
+
+            double density[HSIZE] = { 5.0/30.0, 0.0, 6.0/30.0, 3.0/30.0, 3.0/30.0, 1.0/30.0, 2.0/30.0, 2.0/30.0, 4.0/30.0, 4.0/30.0 };
+            shouldEqualSequence(density, density+HSIZE, get<DivideByCount<UserRangeHistogram<HSIZE> > >(a).begin());
+
+            typedef LookupTag<StandardQuantiles<UserRangeHistogram<HSIZE> >, A>::value_type QuantileVector;
+            static const int QSIZE = QuantileVector::static_size;
+            shouldEqual(QSIZE, 7);
+
+            double quser[QSIZE] = { 0.0, 0.3, 1.9166666666666666, 3.833333333333333, 7.625, 8.625, 9.0 };
+            shouldEqualSequenceTolerance(quser, quser+QSIZE, get<StandardQuantiles<UserRangeHistogram<HSIZE> > >(a).begin(), 1e-15);
+            shouldEqualSequenceTolerance(quser, quser+QSIZE, get<StandardQuantiles<UserRangeHistogram<HSIZE+2> > >(a).begin(), 1e-15);
+
+            double q_onebin[QSIZE] = { 0.0, 0.9, 2.25, 4.5, 6.75, 8.1, 9.0 };
+            shouldEqualSequenceTolerance(q_onebin, q_onebin+QSIZE, get<StandardQuantiles<UserRangeHistogram<3> > >(a).begin(), 1e-14);
+            
+            double qauto[QSIZE] = { 0.0, 0.54, 2.175, 3.9, 7.3125, 8.325, 9.0 };
+            shouldEqualSequenceTolerance(qauto, qauto+QSIZE, get<StandardQuantiles<AutoRangeHistogram<HSIZE> > >(a).begin(), 1e-15);
+            
+            double qint[QSIZE] = { 0.0, 0.0, 2.0, 4.0, 7.75, 9.0, 9.0 };
+            shouldEqualSequence(qint, qint+QSIZE, get<StandardQuantiles<IntegerHistogram<HSIZE> > >(a).begin());
+            shouldEqualSequence(qint, qint+QSIZE, get<StandardQuantiles<IntegerHistogram<0> > >(a).begin());
+
+                // repeat test with negated data => quantiles should be negated, but otherwise the same as before
+            a.reset();
+
+            getAccumulator<UserRangeHistogram<HSIZE> >(a).setMinMax(-9.5, 0.5);
+            getAccumulator<UserRangeHistogram<HSIZE+2> >(a).setMinMax(-10.5, 1.5);
+            getAccumulator<UserRangeHistogram<3> >(a).setMinMax(-30.0, 20.0);
+            getAccumulator<IntegerHistogram<0> >(a).setBinCount(HSIZE);
+
+            for(int k=0; k<SIZE; ++k)
+                a(-data[k]);
+
+            for(int k=0; k<SIZE; ++k)
+                a.updatePass2(-data[k]);
+
+            std::reverse(h, h+HSIZE);
+            shouldEqualSequence(h, h+HSIZE, get<UserRangeHistogram<HSIZE> >(a).begin());
+            shouldEqualSequence(h, h+HSIZE, get<AutoRangeHistogram<HSIZE> >(a).begin());
+
+            double hneg[HSIZE] = { 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+            shouldEqualSequence(hneg, hneg+HSIZE, get<IntegerHistogram<HSIZE> >(a).begin());
+            shouldEqualSequence(hneg, hneg+HSIZE, get<IntegerHistogram<0> >(a).begin());
+
+            std::reverse(quser, quser+QSIZE);
+            shouldEqualSequenceTolerance(quser, quser+QSIZE, (-get<StandardQuantiles<UserRangeHistogram<HSIZE> > >(a)).begin(), 1e-14);
+            
+            std::reverse(qauto, qauto+QSIZE);
+            shouldEqualSequenceTolerance(qauto, qauto+QSIZE, (-get<StandardQuantiles<AutoRangeHistogram<HSIZE> > >(a)).begin(), 1e-14);
+
+                // repeat test with data shifted by one (test behavior of IntegerHistogram with empty bins at the ends)
+            a.reset();
+
+            getAccumulator<UserRangeHistogram<HSIZE> >(a).setMinMax(-0.5, 9.5);
+            getAccumulator<UserRangeHistogram<HSIZE+2> >(a).setMinMax(-1.5, 10.5);
+            getAccumulator<UserRangeHistogram<3> >(a).setMinMax(-20.0, 30.0);  // all data in one bin
+            getAccumulator<IntegerHistogram<0> >(a).setBinCount(HSIZE+2);
+
+            for(int k=0; k<SIZE; ++k)
+                a(1+data[k]);
+
+            for(int k=0; k<SIZE; ++k)
+                a.updatePass2(1+data[k]);
+
+            shouldEqualSequence(qint, qint+QSIZE, (get<StandardQuantiles<IntegerHistogram<HSIZE+2> > >(a)-QuantileVector(1.0)).begin());
+            shouldEqualSequence(qint, qint+QSIZE, (get<StandardQuantiles<IntegerHistogram<0> > >(a)-QuantileVector(1.0)).begin());
+        }
+
+        {
+            typedef AccumulatorChain<int, Select<UserRangeHistogram<0>, AutoRangeHistogram<0>, IntegerHistogram<0>
+                                    > > A;
+            A a;
+
+            a.setHistogramOptions(HistogramOptions().setMinMax(-0.5, 9.5).setBinCount(HSIZE));
+
+            shouldEqual(HSIZE, get<UserRangeHistogram<0> >(a).size());
+            shouldEqual(HSIZE, get<AutoRangeHistogram<0> >(a).size());
+            shouldEqual(HSIZE, get<IntegerHistogram<0> >(a).size());
+
+            extractFeatures(data, data+SIZE, a);
+
+            double h[HSIZE] = { 5.0, 0.0, 6.0, 3.0, 3.0, 1.0, 2.0, 2.0, 4.0, 4.0 };
+
+            shouldEqualSequence(h, h+HSIZE, get<UserRangeHistogram<0> >(a).begin());
+            shouldEqualSequence(h, h+HSIZE, get<AutoRangeHistogram<0> >(a).begin());
+            shouldEqualSequence(h, h+HSIZE, get<IntegerHistogram<0> >(a).begin());
+
+            try 
+            {
+                A b;
+                extractFeatures(data, data+SIZE, b);
+                failTest("extractFeatures() failed to throw exception");
+            }
+            catch(ContractViolation & c) 
+            {
+                std::string expected("\nPrecondition violation!\nUserRangeHistogram::update(): setMinMax(...) has not been called.");
+                std::string message(c.what());
+                shouldEqual(expected, message.substr(0,expected.size()));
+            }
+
+            try 
+            {
+                A b;
+                getAccumulator<UserRangeHistogram<0> >(b).setMinMax(-2.5, 12.5);
+                failTest("extractFeatures() failed to throw exception");
+            }
+            catch(ContractViolation & c) 
+            {
+                std::string expected("\nPrecondition violation!\nRangeHistogramBase::setMinMax(...): setBinCount(...) has not been called.");
+                std::string message(c.what());
+                shouldEqual(expected, message.substr(0,expected.size()));
+            }
+
+            try 
+            {
+                A b;
+                getAccumulator<UserRangeHistogram<0> >(b).setBinCount(HSIZE+2);
+                getAccumulator<UserRangeHistogram<0> >(b).setMinMax(-2.5, 12.5);
+                extractFeatures(data, data+SIZE, b);
+                failTest("extractFeatures() failed to throw exception");
+            }
+            catch(ContractViolation & c) 
+            {
+                std::string expected("\nPrecondition violation!\nRangeHistogramBase::setMinMax(...): setBinCount(...) has not been called.");
+                std::string message(c.what());
+                shouldEqual(expected, message.substr(0,expected.size()));
+            }
+
+            try 
+            {
+                A b;
+                b.setHistogramOptions(HistogramOptions().setBinCount(HSIZE));
+                getAccumulator<UserRangeHistogram<0> >(b).setMinMax(-2.5, 12.5);
+
+                extractFeatures(data, data+SIZE, b);
+                a.merge(b);
+
+                failTest("extractFeatures() failed to throw exception");
+            }
+            catch(ContractViolation & c) 
+            {
+                std::string expected("\nPrecondition violation!\nRangeHistogramBase::operator+=(): cannot merge histograms with different data mapping.");
+                std::string message(c.what());
+                shouldEqual(expected, message.substr(0,expected.size()));
+            }
+
+            A b;
+            b.setHistogramOptions(HistogramOptions().setBinCount(HSIZE).setMinMax(-0.5, 9.5));
+
+            extractFeatures(data, data+SIZE, b);
+            a.merge(b);
+
+            TinyVector<double, HSIZE> h2 = TinyVector<double, HSIZE>(h)*2.0;
+            shouldEqualSequence(h2.begin(), h2.end(), get<UserRangeHistogram<0> >(a).begin());
+            shouldEqualSequence(h2.begin(), h2.end(), get<AutoRangeHistogram<0> >(a).begin());
+            shouldEqualSequence(h2.begin(), h2.end(), get<IntegerHistogram<0> >(a).begin());
+        }
+    }
+
+    template <class TAG, class A>
+    static inline typename acc::LookupDependency<TAG, A>::reference
+    getAccumulatorIndirectly(A & a)
+    {
+        typedef typename acc::LookupDependency<TAG, A>::Tag StandardizedTag;
+        typedef typename acc::LookupDependency<TAG, A>::reference reference;
+        return acc::acc_detail::CastImpl<StandardizedTag, typename A::Tag, reference>::exec(a);
+    }
+
+    void testLabelDispatch()
+    {
+        using namespace vigra::acc;
+        {
+            typedef CoupledIteratorType<2, int>::type Iterator;
+            typedef Iterator::value_type Handle;
+            typedef Shape2 V;
+
+            typedef Select<Count, Coord<Sum>, Global<Count>, Global<Coord<Minimum> >, LabelArg<1>, DataArg<1> > Selected;
+            typedef AccumulatorChainArray<Handle, Selected> A;
+
+            should((IsSameType<acc::acc_detail::ConfigureAccumulatorChainArray<Handle, Selected>::GlobalTags, 
+                               TypeList<Count,TypeList<Coord<Minimum>,TypeList<DataArg<1>, TypeList<LabelArg<1>, void> > > > >::value));
+            should((IsSameType<acc::acc_detail::ConfigureAccumulatorChainArray<Handle, Selected>::RegionTags, 
+                               TypeList<Count,TypeList<Coord<Sum>,TypeList<DataArg<1>, void> > > >::value));
+
+            typedef LookupTag<Count, A>::type RegionCount;
+            typedef LookupDependency<Global<Count>, RegionCount>::type GlobalCountViaRegionCount;
+
+            should(!(IsSameType<RegionCount, LookupTag<Global<Count>, A>::type>::value));
+            should((IsSameType<GlobalCountViaRegionCount, LookupTag<Global<Count>, A>::type>::value));
+
+            MultiArray<2, int> labels(Shape2(3,2));
+            labels(2,0) = labels(2,1) = 1;
+            Iterator i     = createCoupledIterator(labels),
+                     start = i,   
+                     end   = i.getEndIterator();
+
+            A a;
+
+            shouldEqual(1, a.passesRequired());
+
+            a.setMaxRegionLabel(1);
+
+            shouldEqual(a.maxRegionLabel(), 1);
+            shouldEqual(a.regionCount(), 2);
+            should((&getAccumulator<Count, A>(a, 0) != &getAccumulator<Count, A>(a, 1)));
+   
+            LookupTag<Count, A>::reference rc = getAccumulator<Count>(a, 0);
+            LookupTag<Global<Count>, A>::reference gc = getAccumulator<Global<Count> >(a);
+            should((&gc == &getAccumulatorIndirectly<Global<Count> >(rc)));
+            should((&gc == &getAccumulatorIndirectly<Global<Count> >(getAccumulator<Count>(a, 1))));
+
+            for(; i < end; ++i)
+                a(*i);
+            
+            shouldEqual(4, get<Count>(a, 0));
+            shouldEqual(2, get<Count>(a, 1));
+            shouldEqual(6, get<Global<Count> >(a));
+
+            shouldEqual(V(2,2), get<Coord<Sum> >(a, 0));
+            shouldEqual(V(4,1), get<Coord<Sum> >(a, 1));
+            shouldEqual(V(0,0), get<Global<Coord<Minimum> > >(a));
+
+            A aa;
+            aa.setMaxRegionLabel(1);
+            aa.setCoordinateOffset(V(2, -1));
+
+            for(i = start; i < end; ++i)
+                aa(*i);
+            
+            shouldEqual(4, get<Count>(aa, 0));
+            shouldEqual(2, get<Count>(aa, 1));
+            shouldEqual(6, get<Global<Count> >(aa));
+
+            shouldEqual(V(10,-2), get<Coord<Sum> >(aa, 0));
+            shouldEqual(V(8,-1), get<Coord<Sum> >(aa, 1));
+            shouldEqual(V(2,-1), get<Global<Coord<Minimum> > >(aa));
+
+            A b;
+            b.ignoreLabel(0);
+
+            i = start;
+
+            for(; i < end; ++i)
+                b(*i);
+            
+            shouldEqual(0, get<Count>(b, 0));
+            shouldEqual(2, get<Count>(b, 1));
+            shouldEqual(2, get<Global<Count> >(b));
+
+            shouldEqual(V(0,0), get<Coord<Sum> >(b, 0));
+            shouldEqual(V(4,1), get<Coord<Sum> >(b, 1));
+            shouldEqual(V(2,0), get<Global<Coord<Minimum> > >(b));
+        }
+
+        {
+            typedef CoupledIteratorType<2, double, int>::type Iterator;
+            typedef Iterator::value_type Handle;
+
+            typedef AccumulatorChainArray<Handle, Select<Count, AutoRangeHistogram<3>, GlobalRangeHistogram<3>,
+                                                         Global<Count>, Global<AutoRangeHistogram<3> >, DataArg<1>, LabelArg<2>
+                                          > > A;
+
+            double d[] = { 1.0, 3.0, 3.0,
+                           1.0, 2.0, 5.0 };
+            MultiArrayView<2, double> data(Shape2(3,2), d);
+
+            MultiArray<2, int> labels(Shape2(3,2));
+            labels(2,0) = labels(2,1) = 1;
+
+            Iterator i     = createCoupledIterator(data, labels),
+                     start = i,   
+                     end   = i.getEndIterator();
+
+            A a;
+            shouldEqual(a.regionCount(), 0);
+            shouldEqual(2, a.passesRequired());
+
+            for(; i < end; ++i)
+                a(*i);
+            
+            shouldEqual(a.maxRegionLabel(), 1);
+            shouldEqual(a.regionCount(), 2);
+            shouldEqual(4, get<Count>(a, 0));
+            shouldEqual(2, get<Count>(a, 1));
+            shouldEqual(6, get<Global<Count> >(a));
+
+            shouldEqual(1, get<Minimum>(a, 0));
+            shouldEqual(3, get<Minimum>(a, 1));
+            shouldEqual(1, get<Global<Minimum> >(a));
+
+            shouldEqual(3, get<Maximum>(a, 0));
+            shouldEqual(5, get<Maximum>(a, 1));
+            shouldEqual(5, get<Global<Maximum> >(a));
+
+            for(i = start; i < end; ++i)
+                a.updatePass2(*i);
+            
+            shouldEqual(4, get<Count>(a, 0));
+            shouldEqual(2, get<Count>(a, 1));
+            shouldEqual(6, get<Global<Count> >(a));
+
+            typedef TinyVector<double, 3> V;
+
+            shouldEqual(V(2,1,1), get<AutoRangeHistogram<3> >(a, 0));
+            shouldEqual(V(1,0,1), get<AutoRangeHistogram<3> >(a, 1));
+            shouldEqual(V(3,1,0), get<GlobalRangeHistogram<3> >(a, 0));
+            shouldEqual(V(0,1,1), get<GlobalRangeHistogram<3> >(a, 1));
+            shouldEqual(V(3,2,1), get<Global<AutoRangeHistogram<3> > >(a));
+        }
+
+        {
+            typedef CoupledIteratorType<2, double, int>::type Iterator;
+
+            typedef DynamicAccumulatorChainArray<CoupledArrays<2, double, int>, 
+                                                Select<Count, Coord<Mean>, GlobalRangeHistogram<3>,
+                                                       AutoRangeHistogram<3>, 
+                                                       Global<Count>, Global<Coord<Mean> >, 
+                                                       StandardQuantiles<GlobalRangeHistogram<3> >, 
+                                                       LabelArg<2>, DataArg<1>
+                                                 > > A;
+
+            A a;
+
+            shouldEqual(0, a.passesRequired());
+
+            should(!isActive<Count>(a));
+            should(!isActive<Coord<Sum> >(a));
+            should(!isActive<GlobalRangeHistogram<3> >(a));
+
+            should(!isActive<Global<Count> >(a));
+            should(!isActive<Global<Minimum> >(a));
+            should(!isActive<Global<Coord<Sum> > >(a));
+
+            activate<Count>(a);
+            should(isActive<Count>(a));
+            should(!isActive<Global<Count> >(a));
+
+            //activate<Global<Count> >(a);
+            a.activate("Global<PowerSum<0> >");
+
+            should(isActive<Count>(a));
+            should(isActive<Global<Count> >(a));
+
+            //activate<Coord<Mean> >(a);
+            a.activate("Coord<DivideByCount<PowerSum<1> > >");
+            should(isActive<Coord<Mean> >(a));
+            should(isActive<Coord<Sum> >(a));
+            should(!isActive<Global<Coord<Sum> > >(a));
+            should(!isActive<Global<Coord<Mean> > >(a));
+
+            activate<Global<Coord<Mean> > >(a);
+            should(isActive<Global<Coord<Sum> > >(a));
+            should(isActive<Global<Coord<Mean> > >(a));
+            should(!isActive<GlobalRangeHistogram<3> >(a));
+            should(!isActive<AutoRangeHistogram<3> >(a));
+            should(!isActive<Global<Minimum> >(a));
+
+            shouldEqual(1, a.passesRequired());
+
+            activate<GlobalRangeHistogram<3> >(a);
+            a.activate("AutoRangeHistogram<3>");
+
+            should(isActive<GlobalRangeHistogram<3> >(a));
+            should(isActive<AutoRangeHistogram<3> >(a));
+            should(isActive<Global<Minimum> >(a));
+
+            shouldEqual(2, a.passesRequired());
+
+            MultiArray<2, double> data(Shape2(3,2));
+            data(0,0) = 0.1;
+            data(2,0) = 1.0;
+            data(2,1) = 0.9;
+            MultiArray<2, int> labels(Shape2(3,2));
+            labels(2,0) = labels(2,1) = 1;
+            Iterator i     = createCoupledIterator(data, labels),
+                     start = i,   
+                     end   = i.getEndIterator();
+
+            for(; i < end; ++i)
+                a(*i);
+            
+            for(i = start; i < end; ++i)
+                a.updatePass2(*i);
+            
+            shouldEqual(a.maxRegionLabel(), 1);
+            shouldEqual(4, get<Count>(a, 0));
+            shouldEqual(2, get<Count>(a, 1));
+            shouldEqual(6, get<Global<Count> >(a));
+
+            typedef TinyVector<double, 2> V;
+
+            shouldEqual(V(0.5, 0.5), get<Coord<Mean> >(a, 0));
+            shouldEqual(V(2, 0.5), get<Coord<Mean> >(a, 1));
+            shouldEqual(V(1, 0.5), get<Global<Coord<Mean> > >(a));
+
+            should(getAccumulator<GlobalRangeHistogram<3> >(a,0).scale_ == getAccumulator<GlobalRangeHistogram<3> >(a,1).scale_);
+            should(getAccumulator<GlobalRangeHistogram<3> >(a,0).scale_ != getAccumulator<AutoRangeHistogram<3> >(a,0).scale_);
+            should(getAccumulator<GlobalRangeHistogram<3> >(a,1).scale_ != getAccumulator<AutoRangeHistogram<3> >(a,1).scale_);
+            
+            typedef TinyVector<double, 3> W;
+            shouldEqual(W(4, 0, 0), get<GlobalRangeHistogram<3> >(a,0));
+            shouldEqual(W(0, 0, 2), get<GlobalRangeHistogram<3> >(a,1));
+            shouldEqual(W(3, 0, 1), get<AutoRangeHistogram<3> >(a,0));
+            shouldEqual(W(1, 0, 1), get<AutoRangeHistogram<3> >(a,1));
+
+            A b;
+            b.activateAll();
+
+            extractFeatures(data, labels, b);
+            
+            shouldEqual(W(4, 0, 0), get<GlobalRangeHistogram<3> >(b,0));
+            shouldEqual(W(0, 0, 2), get<GlobalRangeHistogram<3> >(b,1));
+
+            a += b;
+            
+            shouldEqual(a.maxRegionLabel(), 1);
+            shouldEqual(8, get<Count>(a, 0));
+            shouldEqual(4, get<Count>(a, 1));
+            shouldEqual(12, get<Global<Count> >(a));
+            shouldEqual(V(0.5, 0.5), get<Coord<Mean> >(a, 0));
+            shouldEqual(V(2, 0.5), get<Coord<Mean> >(a, 1));
+            shouldEqual(V(1, 0.5), get<Global<Coord<Mean> > >(a));
+            shouldEqual(W(8, 0, 0), get<GlobalRangeHistogram<3> >(a,0));
+            shouldEqual(W(0, 0, 4), get<GlobalRangeHistogram<3> >(a,1));
+            shouldEqual(W(4, 0, 0), get<GlobalRangeHistogram<3> >(b,0));
+            shouldEqual(W(0, 0, 2), get<GlobalRangeHistogram<3> >(b,1));
+
+            TinyVector<int, 2> labelMapping(2, 3);
+            a.merge(b, labelMapping);
+            shouldEqual(a.maxRegionLabel(), 3);
+            shouldEqual(8, get<Count>(a, 0));
+            shouldEqual(4, get<Count>(a, 1));
+            shouldEqual(4, get<Count>(a, 2));
+            shouldEqual(2, get<Count>(a, 3));
+            shouldEqual(18, get<Global<Count> >(a));
+            shouldEqual(V(0.5, 0.5), get<Coord<Mean> >(a, 0));
+            shouldEqual(V(2, 0.5), get<Coord<Mean> >(a, 1));
+            shouldEqual(V(0.5, 0.5), get<Coord<Mean> >(a, 2));
+            shouldEqual(V(2, 0.5), get<Coord<Mean> >(a, 3));
+            shouldEqual(V(1, 0.5), get<Global<Coord<Mean> > >(a));
+
+            A c;
+            c.activateAll();
+            c.setHistogramOptions(HistogramOptions().regionAutoInit());
+            extractFeatures(start, end, c);
+
+            shouldEqual(getAccumulator<GlobalRangeHistogram<3> >(c,0).scale_, getAccumulator<AutoRangeHistogram<3> >(c,0).scale_);
+            shouldEqual(getAccumulator<GlobalRangeHistogram<3> >(c,1).scale_, getAccumulator<AutoRangeHistogram<3> >(c,1).scale_);
+            
+            shouldEqual(W(3, 0, 1), get<GlobalRangeHistogram<3> >(c,0));
+            shouldEqual(W(1, 0, 1), get<GlobalRangeHistogram<3> >(c,1));
+            shouldEqual(W(3, 0, 1), get<AutoRangeHistogram<3> >(c,0));
+            shouldEqual(W(1, 0, 1), get<AutoRangeHistogram<3> >(c,1));
+
+            c.merge(c, TinyVector<int, 2>(3, 2));
+
+            shouldEqual(c.maxRegionLabel(), 3);
+            shouldEqual(get<Count>(c, 0), 4);
+            shouldEqual(get<Count>(c, 1), 2);
+            shouldEqual(get<Count>(c, 2), 2);
+            shouldEqual(get<Count>(c, 3), 4);
+            shouldEqual(get<Global<Count> >(c), 12);
+
+            shouldEqual(W(3, 0, 1), get<AutoRangeHistogram<3> >(c,0));
+            shouldEqual(W(1, 0, 1), get<AutoRangeHistogram<3> >(c,1));
+            shouldEqual(W(1, 0, 1), get<AutoRangeHistogram<3> >(c,2));
+            shouldEqual(W(3, 0, 1), get<AutoRangeHistogram<3> >(c,3));
+
+            c.merge(1, 2);
+
+            shouldEqual(c.maxRegionLabel(), 3);
+            shouldEqual(get<Count>(c, 0), 4);
+            shouldEqual(get<Count>(c, 1), 4);
+            shouldEqual(get<Count>(c, 2), 0);
+            shouldEqual(get<Count>(c, 3), 4);
+            shouldEqual(get<Global<Count> >(c), 12);
+
+            shouldEqual(W(3, 0, 1), get<AutoRangeHistogram<3> >(c,0));
+            shouldEqual(W(2, 0, 2), get<AutoRangeHistogram<3> >(c,1));
+            shouldEqual(W(0, 0, 0), get<AutoRangeHistogram<3> >(c,2));
+            shouldEqual(W(3, 0, 1), get<AutoRangeHistogram<3> >(c,3));
+        }
+    }
+};
+
+struct FeaturesTestSuite : public vigra::test_suite
+{
+    FeaturesTestSuite()
+        : vigra::test_suite("FeaturesTestSuite")
+    {
+        add(testCase(&AccumulatorTest::testStandardizeTag));
+        add(testCase(&AccumulatorTest::testTagTransfer));
+        add(testCase(&AccumulatorTest::testScalar));
+        add(testCase(&AccumulatorTest::testVector));
+        add(testCase(&AccumulatorTest::testMerge));
+        add(testCase(&AccumulatorTest::testCoordAccess));
+        add(testCase(&AccumulatorTest::testHistogram));
+        add(testCase(&AccumulatorTest::testLabelDispatch));
+        add(testCase(&AccumulatorTest::testIndexSpecifiers));
+    }
+};
+
+int main(int argc, char** argv)
+{
+    FeaturesTestSuite test;
+    const int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test.report() << std::endl;
+
+    return failed != 0;
+}
diff --git a/test/optimization/CMakeLists.txt b/test/optimization/CMakeLists.txt
new file mode 100644
index 0000000..b80ed2b
--- /dev/null
+++ b/test/optimization/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_optimization test.cxx)
diff --git a/test/optimization/larsdata.hxx b/test/optimization/larsdata.hxx
new file mode 100644
index 0000000..9b327ef
--- /dev/null
+++ b/test/optimization/larsdata.hxx
@@ -0,0 +1,9065 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 2008 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_LARS_DATA_HXX
+#define VIGRA_LARS_DATA_HXX
+
+#include "vigra/array_vector.hxx"
+#include "vigra/matrix.hxx"
+
+namespace larsdata {
+
+
+// Data from file x1.txt and y1.txt
+double x0[5000] = {
+-4824.85609148439, 5492.68670002464, 10677.6814107257, -6577.76436526851, 3006.52263630013, 1232.75930288669, -13874.8715790338, -12013.7032176346, 7763.15613936006, 3154.84616282376, -9720.70147471624, 1050.31817626143, 1105.76477821089, 14008.3129836710, 59.6625008434368, -9001.37338256055, -3315.94876129626, 2959.22173007536, 2067.03735437843, -7026.54280114668, 2016.87450797157, -1500.93226203831, -13486.8751042545, 4018.70107849734, 729.667410769464, -3461.59203658467, -15940.435219 [...]
+10503.8128130289, -1975.96432576903, -10882.6707132376, -15496.8179537946, -2683.96070749656, 20364.3600367006, 12060.9162634738, -3863.9069736504, -2204.42301752556, 3498.54907646087, -10328.4817762828, -5183.6907866054, 23715.4647323558, 3910.7424355139, -974.076602220367, 5545.33415522038, -546.959719392361, -10517.1756427108, 4038.22915100764, 1519.35693087274, 278.379572073084, 8950.68784307226, 3071.62136041175, 1773.43305514849, -8810.50056996015, 6208.37949084252, 7104.4146312662 [...]
+-25410.1944551726, -8607.6172702845, 10784.4299911228, -19796.7021284725, 19080.2870309262, 6086.60008471648, 17369.2242211683, 7958.25148938802, -11165.5235658922, -6882.9837503392, 39.3952313900356, 10436.4613948821, -17997.3873162621, -4858.3648132209, 6867.65626485278, -3503.36484183816, 6879.05370745725, 2748.5660816116, 6486.67616855507, 3293.18033529253, -1213.36604532598, 1781.93751889423, 6973.55968552688, -8708.25640431769, 13697.6906048666, 9647.7526027641, -10134.6719555600,  [...]
+8391.62537594225, -3538.07411618347, 14562.5447430808, 2188.67183459842, 12031.3584588355, 1782.78901970306, 10040.5315089185, 5502.23456412132, -5488.64570159822, 1337.27074170818, 12160.3412642307, 16335.3729432636, -1629.51338234909, -914.281285957799, 18627.1309174643, 3048.87618671333, 10606.3934419140, -8036.60956403262, -5097.81053406837, -8830.48979960146, 13072.5027144019, -9405.8632558346, -8365.79977952925, 11284.1469515193, 15224.9459773680, 10911.7908759297, -5457.1539520728 [...]
+3971.91281065321, 5137.77630454473, 4386.10219794586, 17220.1012112582, -8071.44723595137, 21775.6566595257, 13350.4159019676, 6109.79440823346, 8351.28001540748, 22748.2360364964, 1247.07685572059, 12108.8442905456, 12497.4570896021, 14493.6005299090, -10282.1589071261, 13334.7568876448, 3641.36472419559, -8569.1122413144, -4328.73196021228, 3817.88898783385, 4749.21612683583, -7517.36372326186, 7357.39251238079, 5333.62221318679, -6716.91319369655, 18782.5656746495, -4843.12889948442,  [...]
+-10222.8028382756, -23174.3418660024, 22786.6607074203, -4897.3994688443, -11525.3277957892, 2739.50354065979, -4393.51378220903, 7299.44910522972, -468.192055381877, -14786.4736575303, 6815.16177574024, -278.166287127477, 2225.61162185042, 9545.59509280576, -14106.9164029350, 14481.5791318834, -7864.88421030937, 7269.82399986671, 4825.81855277675, -10323.7242377048, 6552.02129626765, 3132.89176919866, 23595.121598137, 10141.7748340406, 6411.70795857581, 19711.9877701657, 13766.955365460 [...]
+-8791.58641745136, -3634.73952064475, -2898.70862013585, -957.044674560697, 2606.50223201647, -618.890697352841, -9819.40051079775, 7728.49421101888, -4676.04574156576, 8513.80111019302, 349.605545822288, 20983.5866041862, 9821.41890345264, 13977.8697774532, 2235.87581018277, 10719.5652664215, 6795.34348686544, -18920.8440434330, -3499.76327541941, 3148.39386326094, 19046.1280436337, 9657.11847365912, 15726.0686245592, 12257.5050185458, -1751.64471951930, -1905.96529847711, -5992.5859314 [...]
+4806.05369198179, -1167.97627761998, -22738.2054421141, 5243.44835818554, 10777.0361568215, 7117.53547006903, -7863.19584597646, -2939.82023501363, -2246.00511366296, 4609.76494369509, -4317.09714191309, 336.843479693964, 13305.4652208912, -13344.9013560647, 7431.54612273091, 9723.49254416922, -22220.7239017123, -1500.96506156070, -9382.3891867843, 10370.4227380919, 1253.97226347699, -492.821377612752, 13608.8966512116, 6141.50364301481, -7572.33682941791, -7451.53264297602, -11397.72174 [...]
+13553.8881543861, 1893.15865617829, -3555.07233584128, 21226.0441505095, -9091.95814349642, -14675.163092321, -24883.7639726919, 2957.17452521401, 12976.1160923964, -26285.4408028390, -11734.0763814492, -365.128773943433, 109.657220564343, 3894.74351335176, -33939.853798569, 7469.89038872013, -2650.55003336111, 294.493169263204, 3027.94168201182, -6829.84319289845, -3892.22042906797, -1155.61729194143, 3957.06964705125, 10640.0529362767, 9239.99825721938, -12314.8950643457, 3001.08477982 [...]
+1804.64493321438, 5680.60809245673, -19799.7288133307, 8481.7426629902, -1382.55677936705, -20533.2594830072, 15255.0908255019, -7086.29737607512, 15724.1692987392, 6993.6203967993, 2146.31766905143, -2088.11143346794, 8451.63630372608, 5431.9289200047, 4008.06761229044, 10419.8069301054, -4792.6298887994, -742.282713932987, -3897.83870644958, 12876.3299843787, -2187.45072346789, 18791.9077599508, 25022.7830150519, -1867.43193463396, 98.89130623306, 1562.16177531646, 4945.02196234184, 92 [...]
+-1164.39740106653, 22338.1016649186, -8661.97933908767, 3485.01202955175, 25262.5630986758, 7085.92094219246, 30018.3262344347, -2053.59176824007, 13839.1494102145, 8359.57207266262, -3129.85774930115, -2387.44953057414, -1102.87463335674, -970.688682306271, 13269.4612794143, -17495.3314960931, -883.174965298747, 1860.09788589645, 14025.1603445487, -1310.86071097947, 10403.2329471069, 3600.75397352298, -1326.62987073955, -4792.11473370489, -9954.80982073105, -13373.0761254585, -11545.702 [...]
+5184.00912872932, 2048.04366009304, 9812.88983856197, 11030.0178225529, -3350.68411124609, -1651.81016109354, 3404.8504392251, -3903.61661595423, 3005.62741245755, 7633.82990785147, 9632.09101506813, -7232.45927457797, -2167.64912996164, -16574.3480631209, 17845.6975792498, 11872.6264973417, -512.366409982419, 3160.08849702186, 4760.63225946374, 1752.02135983167, -9564.75830205253, -10867.8968032245, -10899.1274152788, 13793.5048515752, -16823.2178358861, 5747.83460896412, -11512.5934448 [...]
+-4761.45761383895, 4635.95323449235, 2284.93972802302, -4088.22792233849, -22019.0634758780, 11487.5276135778, -2446.12179435328, 331.349711286565, -3968.46326146169, 5812.66913119542, 14614.8986398500, -6849.52368130914, 15296.4554882958, 3030.68303980318, -2270.45619173159, 4226.52033785159, -8814.07789526021, 1047.99179802261, -8115.94296176556, 800.162396432455, -878.745652640845, 13069.6705507101, -12379.1338986065, 13122.7024438335, 4286.80745240244, -4569.82743598502, -2660.738847 [...]
+-8163.28238227322, -2846.33729430954, -1847.95763525237, 13784.2345987643, 459.866693383869, 9167.2036087145, -6385.36932251463, -1543.25933709673, 7801.83145840204, -1692.04476788548, 11516.6015376493, 623.720792810618, 15543.7364517478, -9690.29474046038, -723.015536477439, -5973.43791929899, -8648.1387914708, 10405.3351335259, 9539.44036783994, -3777.93179491656, 8131.20040750354, -7901.91675598824, -1085.38560813678, -3828.55356736649, 106.729573631947, 4545.21659703984, 5334.7350228 [...]
+951.098634847252, 1327.31699301869, 8021.53000068268, 3566.01311480221, 6466.42473123153, -6379.06807700168, 12849.7282070894, 8613.7882993374, -7080.48725085868, 14379.2233878282, -3007.93438033794, -1015.04369508374, -3189.57226077769, -9279.59403099261, 3806.9401471939, 1652.29245263551, 12029.7103330733, -9132.77187166128, -1486.91517287111, -13806.2783507678, -1202.70761129167, -12313.2731930383, 1602.218426137, 8308.3730021539, 353.641127382601, -3256.14238188096, 5484.61711872388, [...]
+-1527.62441538694, 20661.2665636579, 1540.93186814551, 5634.73964135377, -9106.67705173826, -53.781697646746, 31.0864089765304, -8364.58500017263, -14291.629558555, 2942.67402025496, -61.4905859499793, 3392.55205069357, 1806.90872767595, 4756.5147385043, -22184.0735349075, 15823.4395249394, 7858.59765951906, 11857.3864604558, -1181.00409992289, 3858.92651898401, 2875.19903782331, -20781.6126520632, -2003.88220633766, -3026.63553635995, 18056.5746453325, -4163.15323453536, -13582.00367050 [...]
+11456.5298881470, -9739.61108385849, 10717.9925874970, -6960.33330866798, -4387.92436134847, 2504.69332004430, 8206.88405586308, 4629.97538725424, 4468.8656626506, 9019.50844398417, 6810.45923366842, 11874.8312312245, 7127.56426235128, -19509.0003750572, 257.057679634302, -6809.02520232946, 883.873605507108, 8681.3651358931, -16042.8219510072, 4088.01991796025, 2209.69327447178, -145.273422952063, -16220.7907002456, 6449.68073363522, 2255.42918971335, 17334.4720859625, 6072.99379730343,  [...]
+11562.8529806538, 7207.047098654, 8398.86334252775, 8028.84586817969, -4487.47062992083, 12757.2628492482, -2545.93247147323, -9232.36709625594, 14385.3332060094, -13665.2527063403, 10186.8685153309, -22877.4563717562, 21376.1092029609, 9977.30528690112, 9003.33658348488, 9180.38957893759, 13472.8603548464, 1326.47928010877, -15380.4724030317, -4996.21832682545, 6648.75812189012, -15598.3683284986, 125.473352624358, 8717.5279833547, -828.2841704852, -446.499204881674, 7966.66145744788, 7 [...]
+-6010.26767533545, -9292.30032517972, 2552.68319707619, 15649.8604855021, -440.20278143756, 614.340640072097, -7356.79004217763, -10618.7472663112, 2207.91677310437, 17373.5641802437, -8358.89825035036, 1403.39968460752, 13747.4319245988, 10602.0417113762, -11100.5936367786, 12695.3918684317, 10536.1946768026, 7744.00807127985, -25850.3244449546, 9395.70596072066, 1906.66379151568, 21266.8307509735, -18183.9781631291, 12106.0156824092, 2573.00611805989, 28727.7325489775, -1015.9872387639 [...]
+-9700.45826128302, 4202.44145540171, -7331.70712871278, 13895.7810932697, 5367.40437490942, -10910.8877290345, 7399.41976022675, 19464.7622810525, 3454.46727427057, 7188.924870479, -2997.94416742258, -13682.2004916015, -3823.43009755215, 297.140020794265, 1285.53829269865, -16635.0110760469, -6455.16842505229, -3823.46159780881, 12536.2234059467, -3212.56834604651, 10954.9967404167, -5339.32453358863, -9992.93315846257, 5970.13388972311, 4837.25534056856, -11248.8598421303, 9496.08856326 [...]
+-9916.18512837253, 8993.25403581071, 12258.6619747396, -3096.39557523355, -2289.01157826236, -11997.7989745403, 13185.2622253589, 10137.3313940583, 9722.2896373784, 6540.65457973578, -5791.70981271927, -13180.8592396066, 68.1180957735234, 10141.9661144276, -4098.35467684728, -5131.0988189861, 3854.61765191059, -9321.8283908739, -29.0458415392876, -1936.38920655955, -20387.2874856425, -2471.36737709437, 5886.97219271367, 19468.0870907998, -17424.4938922676, -17450.1555813509, -5754.998798 [...]
+5907.53805979406, 13391.4952932841, 3407.03779409858, 3583.02423982365, -9250.35881480299, -7452.73890935147, 8540.10802599838, 160.850016016636, -148.326279518587, 11792.3121132674, 4969.00907574298, 488.198363836627, -3469.35129203196, 775.901117211781, -858.24783403498, -22255.6526058983, 12583.6896594865, -4063.47523118302, 8208.37980947471, -4110.25042825939, 3441.54844713004, 6320.26648912106, 17590.3714906978, 7416.66904690148, -7030.36779700298, 10034.8249174049, -30529.793803498 [...]
+1774.39956169349, 1138.03132019224, -3766.19942960475, -3567.39431742306, -4956.13072195059, 5266.48610430315, -12322.3073483239, 8614.3274593628, 1684.82349088582, 15551.8726760613, -923.583367304518, -11157.5972408683, 10759.5862103033, 6493.04119076034, -8609.0295943423, -452.798490755927, -6297.44033446193, -6395.32747797579, -17334.4566811780, -2116.66267290296, -6175.68857087696, -15651.5292921657, -2493.41331123250, 7755.72710797622, 6992.1532459495, -475.878213117065, -3374.80540 [...]
+-9512.76304020336, 9743.6831624421, -1488.57028902389, -14134.9430312023, 6169.96997687961, 2074.05961828822, 5578.61134196343, -469.771131205848, 1469.08189895578, -2591.23019950543, 8145.40484860913, -7524.95452380146, 2505.5638522305, 4565.91172660633, -7982.6432358739, 3381.68677524175, -6547.84160547134, -5453.97361206009, -10515.4825288194, 1268.36507726799, 15830.4953138404, 10918.5270745380, 6515.68638302463, 19964.4072180938, 12441.0360402267, 7664.82419935336, 40.5576683685638, [...]
+-5876.37400427761, -21180.2216512963, -981.07665100796, 9154.41282693216, 4111.58633364548, 6600.21537137221, 4850.65343750806, 7951.80878820103, -2763.25162072124, 8744.81581568888, 23757.0069666339, -6968.49446015862, 10630.7442649398, 18970.3466618638, 12036.0012297407, -10195.0532171385, -1966.29071835242, 11226.8412020283, -13958.5075626461, 11871.8461623488, 2700.26942082396, 424.409226394301, 3793.7317271612, -4240.43165970141, 7875.2202808738, -6067.85361453415, -9018.4032137098, [...]
+-709.40472383053, 15907.6147564127, -5807.9875710387, -16499.7085707429, -1361.45262204922, 5895.70859165384, 6161.81942083547, 6877.5318800545, 17577.5088687095, 24126.1303093394, -7140.20039576603, 401.387759025087, 14319.4455530612, 4987.40764167988, -6801.79786045557, 319.448889274223, 10760.1770347074, 16394.4622850763, 3130.77219058093, -874.226486015664, -8144.61795207004, 7245.90904187284, 2325.81750641151, -1662.81692403745, -13210.5739652531, 15643.7127972196, 12258.3499112285, [...]
+-4120.13460134216, -510.627573020775, 10736.7277135466, 13444.5601889644, 5414.08794068912, -5882.99025483752, -71.223801125205, -6847.54697707565, 22242.2070162443, -21017.3517713852, 2126.91482723250, -14993.9101033140, 10637.3170942479, 4541.92608987509, 2864.88813311507, -15263.2258755284, -5942.88705941216, 20335.9403688677, -8103.17076101, 18430.9003634245, -4378.11982640782, -8974.42643215296, 9475.59133521844, -1576.78379757865, 9067.1022956277, 21391.4171816223, 18552.4312440091 [...]
+-4768.70037694761, -17647.9111013430, -817.794066654996, 8099.13945165725, 13835.9777497985, 13332.1924091396, 11865.7928968444, 958.203795014972, 8049.6666809136, -9554.55203089675, 2230.09903914232, 3540.01007643135, 11459.3879560829, 3986.95493192382, -9164.83318274846, 1748.25951057377, 16110.3014074343, 11288.4764222186, -6361.9829105993, -6397.52664398506, 3345.14201406428, 2068.8163548545, -4577.717654487, -878.229993636366, 1242.21560039523, 20637.6451348872, -4612.7072121637, 19 [...]
+10818.7555598753, -15568.5374145466, 117.611747547657, -2016.07444395494, -7693.56681615861, -2875.30490987236, 7919.57534599016, -8102.43671763125, -548.342368164859, -25284.9254914776, -30971.1879200918, 17105.4452793528, -18094.8649260013, -1730.18690784657, 6149.23269181016, 13427.9054715673, 251.234495233434, -9686.80634690475, 763.948285604306, -6765.44219635876, -6924.28923543938, 4351.2128540198, 13470.9282793082, -16934.6274101511, 7108.91781096736, -11901.6206054643, -5754.5409 [...]
+-6249.91453626662, 6026.88814677233, -9.904415446787, -2468.94740153740, 13876.9607367912, 27438.6325735332, -8601.42928721941, -11565.0837790560, -6150.84584249366, 7563.85559769436, -5842.28817171399, -541.739210672082, -6954.88559107189, -2499.84986966314, 8819.64846365021, -23307.6504624936, -7459.997725058, 6522.54602365648, -2960.82910477031, -7949.68375898257, 2469.35650152794, -6997.36853414099, -7281.25852350411, -21609.4023426549, -9727.59620659824, 4998.91782331428, -4665.4675 [...]
+1553.21552030719, -14910.3414130293, 16922.7668834461, 14240.5238595389, -7992.61595797125, 2365.33467955880, 9162.44087098933, -2861.21237083508, -18275.4865289382, 2706.39327501875, 11374.6242047425, 11099.3131665419, 8056.66418629152, 1436.74336236156, 8070.21505399675, -15556.8688208798, -5507.90577406097, 4729.71551166834, -8746.06552149525, 64.2847307067655, 4616.42300653668, 9698.21255674279, 3923.01654309753, -16815.0652161126, 3624.9225649092, 7428.19228707702, -515.751791914086 [...]
+-8600.76713249462, -8575.33295593712, -9816.08852515728, 13739.6608134169, 12919.8962340073, 8213.86107187795, 204.000257799153, -5651.72023914428, -2768.42033988729, 12090.6327749762, -9123.83274804015, 12609.3703327335, 7981.80874930728, 5368.9679014326, 1480.88644845351, 14012.2965484729, 1986.66923228551, 94.1170597266779, -2663.04881220572, 15976.9361432522, 4091.9108792577, 5920.81635575405, 19182.8566614837, 918.714408172356, -3639.44005873442, 859.578530298104, -12422.3396362302, [...]
+15136.4250063966, 2634.61627264064, -131.047130933474, 14350.8138825273, 3843.57917517211, 1456.04545325364, 3309.68954366319, 1309.41161672202, 17519.0350691211, 731.388709922945, 11128.026516854, 15230.1429460437, 5579.53237695697, 6712.15943367919, -12693.7224891183, -5893.15893320199, 2179.41172605898, -16580.1304254549, 15574.7223698664, -1235.58230593523, -4281.49526911827, 5348.31328981326, -2841.97504234001, -2241.09415200301, -16694.0827374272, 17307.1893395951, 11856.4076649615 [...]
+876.477938467214, -5237.35621810869, -3185.03340360349, -5212.06644762613, 8155.34657895837, 9137.67851641079, 11764.2312935305, -3081.69693741023, -372.911275286354, 11592.2897713017, -13186.0344854695, -2128.87517871824, -11461.4933256472, 3206.15744386194, -18657.4062104784, -9256.5509762841, -13342.5912965447, 5008.86441663507, 8667.04907922854, -15067.9648654486, -20713.4070371867, 17331.7079709014, 12450.6806836023, 3813.58592354743, -5314.19204138884, -9481.7643847975, -1625.47133 [...]
+-10540.3699555848, 12331.7454771781, -8672.12463027416, 11001.9400898818, 218.430454969114, 29014.2391462534, 10349.1891524431, -16568.5041438234, 14263.7207918010, -8753.00254753358, 15922.7344226545, -9094.80711549415, 20014.8461263217, -9656.45350445213, -3969.04210684058, 2547.14826554641, 18753.7317507468, 5483.16540392872, 5257.7676308545, -7918.51482221627, -8828.24271751857, -8420.9308896897, 6799.10562106068, -3770.01642463745, -2935.91675223561, -3411.47014622246, -7513.3969087 [...]
+-13010.9885299761, 6941.38135637678, -9132.31656273503, 366.142410117724, -5127.02916036904, -7551.12792977528, 2011.12362567406, -2800.73013852151, -14301.9366454713, -4937.59261473466, 14052.3497884575, -7774.84997173226, -16859.1368052546, 2795.41909100985, 3456.39752833561, -1833.61912516418, 7749.95539740631, 14913.7275583030, -9207.88162217859, 11456.6824479260, 6450.62195623838, -8264.02862461315, 3622.60247104048, 13360.8852712495, 6933.18433740629, 2549.56804484152, 10512.611747 [...]
+11102.8662079696, 594.386855224411, 7625.0413139489, -8040.3329996603, 6766.258963667, 2527.50586429668, 8426.26012095692, -12857.1094022565, 15314.9370216362, 6827.1029380996, -19914.5051257726, 614.198268980164, -3129.72733416676, -13221.2473585420, -5364.85630916316, -10475.0095590568, -1255.51853580065, -10620.7549044712, -1949.45917716556, -3378.75249188721, 8056.25710561136, -15407.8628725591, -10212.8412805955, -2582.64419585255, -28734.6999070995, 15774.3841677429, 7098.395852056 [...]
+-7530.16487247282, 2118.14323338065, -8045.60703313338, -1680.69467922360, 13333.0332710061, -2665.25422986077, 6354.51197265106, -24659.8683274987, 11736.6205715524, -14502.6881876177, -2687.27922860697, 7549.25741711665, -4238.31961020543, 24039.2615707739, -1233.31894603607, 4205.18025387764, -10408.7405643688, -6112.0069324865, 9045.95165878989, 222.696059418771, 4336.2589009708, -659.718745185551, 109.125640600962, 9028.32300816694, -82.307975178742, 2250.20075209263, 6120.972897655 [...]
+-1083.12967651474, 7435.2918000411, -861.29312935799, 1374.04308433799, 12568.2280166065, 1770.72478695433, 13781.2135762500, -3831.97749471555, 15308.6494809410, 12326.1009698078, -7551.88013188934, -3157.43356379652, 8471.91460070194, -8474.11750221512, -5229.48658321032, 574.349098349991, -9669.18389721024, 14590.5111372966, 140.540701026542, -5673.75374940299, 4330.20761834588, -9064.67716701743, -1111.55233254291, 13364.2056781319, -2397.13488182518, 7114.5535922283, 1962.7228181008 [...]
+8318.10480380688, -6777.82325962813, 3451.81368751099, -4382.64378065906, -11315.0552168084, 2843.3277777772, 12892.17823615, -8003.8256717294, 6991.43813114445, 6954.03034831808, 1020.98688919508, 5616.40791416262, -7414.37394327857, 2056.24464668181, -5842.27338285397, 13856.7704098370, 70.0131499513393, -4510.18713794246, -14746.037781864, -9416.55052156447, 2003.58280370399, 4010.5642139311, 4952.16775415689, 17026.2083314205, 2215.55091430398, 579.64404116588, -2893.25673961483, -16 [...]
+-360.342100874971, 5277.17131934326, -13125.0823287071, -2832.38048622805, 12216.5964091710, -5624.0523380809, -4244.90489953177, -5409.32784744764, 20279.1068239727, 9701.49059187926, -904.10182118892, -8113.6439321167, 3866.82201389498, 10060.6456768263, 13283.8393923858, 6603.23137162653, -18768.7075974230, 1281.21439961364, 23212.8202881072, -4313.50163784195, -9462.81590616787, -11490.9188062610, -3016.24952574545, 2822.09634220427, 6633.64936951001, 252.532890069648, 5411.176463803 [...]
+-5495.56074632106, -16233.4644203965, -1985.96354077756, 4124.03044115942, -10965.4777716633, -1010.30480657005, 9641.86916843932, -10812.4847460162, -13206.2909191514, 8179.36953753785, 7572.58401597548, 626.786973883652, 6389.26950277156, -6736.37896751648, -4399.51691660717, -12469.9332134867, -8407.63036516757, -1387.37115062335, -17597.3662327143, -10934.8955359536, 4775.10006864655, -5746.92977625092, -11726.5513161471, 4101.88062859755, -7747.63450516724, 1055.99661508595, -12191. [...]
+23472.8871621336, 6203.97466957064, -6457.74022525885, -19694.0662992365, -4282.21058114158, 11351.5109878552, -1744.59777714166, 4629.82292897089, -3016.90968578588, 2065.27780756137, -5841.30605609023, -6333.68658864157, 1335.64731608412, -162.101732909273, -633.929131077479, 1801.65766561693, -1923.67193765637, 8887.89292761052, 10800.7392321290, -22919.0564292216, -2512.03004592118, -7865.8071901461, 8456.630149648, 3806.12317399226, 6845.10140219325, 7358.36506328308, 4859.520378359 [...]
+15590.9780882341, 7519.9361389498, -9151.15806657458, 3227.44663502638, 4436.36395209976, 1602.23551969854, -6123.96159584697, -7778.98429249122, 8429.7092192012, -14244.9701465841, -5725.86087558552, -10002.7976445878, -4824.28279586166, 21534.0462829978, 11145.1401849305, 14551.7614690140, -6821.46075629471, 13238.6590196188, -17533.398175041, 1749.71266647208, -1048.77124083890, 52.019795117569, 11366.6474803708, -515.920956581153, 1206.05218156084, 5395.45461470166, 30620.1820634963, [...]
+-13466.8466673653, 6439.36305052308, 2789.31899566824, 20514.3203232925, -2037.92326835505, -16049.5008254556, -5284.56169638816, 3002.13644289119, -14953.8981442902, -18046.4589947806, 11808.2348337624, 754.402419293955, -2883.4653372912, 3273.47474925218, -1598.30941521789, -450.152880945994, -2705.59917801875, 3769.5358311248, 3342.90318971359, -13424.8710518407, 11241.7766040175, -9581.19873793995, -18386.1430989744, -20812.924805159, -11240.1023315598, -5346.34373639239, -14901.4853 [...]
+-10994.1650372605, 1082.59260405213, 10888.0083024988, 12667.5308427691, 9086.02780657668, -1401.30071864777, 14188.0906239169, -13371.3287851099, -8368.1738282937, 18652.0453509996, -7421.57421771541, 4845.79360690297, -18421.7409780635, 7752.90356500328, 6659.20084142545, 2919.80171260193, 3969.24730620773, -2594.27204702894, 5352.80319523581, 5433.81445444908, -8815.7776353296, 4608.09117999654, -7847.91081396033, -8153.94915428886, 18416.0475735382, -6951.484818104, 8511.1887511771,  [...]
+-7877.6931986383, 2792.02302766424, 3738.40540922395, 12463.7068617216, -5891.38988655154, -9159.78395950459, 999.902159797344, 18156.2872525491, 171.125547462974, -5728.16721702951, 16915.6725174082, -6502.92748504254, 21265.4093914948, -9053.0814631274, -11157.2255643595, 4960.01885589786, -1936.26745040668, -11193.0400005781, -5671.96280772193, 2966.07219541576, 11139.7780370972, -7999.89041292808, 10006.8152374248, 15430.7404217504, 9943.38384030973, 402.325463676895, 6130.2761493725 [...]
+-3761.47521344569, -12758.3920333787, 6639.12503656351, -10051.5884839444, -6702.91571076933, 15948.2769331193, -1675.08872363852, 756.29680506233, 4358.38903765645, 6987.35419027094, -4536.90190651473, 14946.9656387871, 932.14991993351, -8995.29827349452, 129.918556306859, -4602.23564544512, -6453.99552915667, 17130.0544919784, 9581.14693324637, 8912.20650360101, -4337.38100633724, -2781.11434583356, 1563.65688222339, 20038.5783749391, -544.360193487994, -4068.15537585061, -11348.186395 [...]
+3521.83437395218, -7757.14643219915, -4441.78009873056, -4296.34048677635, 8669.06351687276, 14044.9013174006, 1575.46706447004, 7131.04982578448, -12751.8565719407, -4509.63739087397, 376.696173405827, -8000.37199996768, -3146.96673479856, 300.909853220674, -307.735239264786, 9875.56523553797, 16454.9678912822, 10355.7773112277, -9067.5535187168, -1314.82991627572, 9632.8925719968, 1988.63205913349, -2237.57888300717, -5054.17364066997, 2512.85495638666, -16010.1557560335, -3666.6537401 [...]
+1280.5133410862, 25059.4115522934, 2970.37236525642, 7498.30399165342, -3995.89206851315, -4055.6582635772, -6023.12839354748, 17435.0090927124, -2504.19260773296, 13024.8730157854, -4732.82166216199, -1472.31938234297, 30620.5823865672, 1926.20456656951, 5241.15439694431, -738.179445427535, 10094.7838737116, 5683.93515122341, -7938.74997509891, 2722.03111550069, 6678.92636261568, 2477.88770434279, 13684.4960220865, 10732.4680555461, 14747.3592112661, -7937.21425052153, 15127.0012880096, [...]
+-4698.83644164109, -3294.78462633624, -10260.6053796036, 15713.7596688237, 1685.83500280335, 6334.96840386087, -10896.0765724291, 17789.5306768606, -3000.31815424563, -18107.0652492443, -8725.37337996408, -3899.30582472221, 18326.0495451576, 4852.58046070106, 3942.1320643398, -4792.15848775285, -11507.4054753719, -21447.0818288148, 11416.4060483293, 14506.5311160027, 12666.2654918468, -9491.06780047113, 2868.72086635851, 7856.72483454954, 5557.12880952764, -11351.5304449190, -4547.952657 [...]
+-3828.1832765269, -21951.7712396335, -3030.91518249315, 10776.9498493762, 2998.52109254516, 12802.3808955365, 14864.2045086299, -15114.2836816863, 17758.8281812521, 3538.73528658134, -22144.4817365270, -7976.92009992644, -7452.35761751997, -22113.3782089824, 4604.57384907743, 4186.44348587885, 6621.5764049734, 12674.9940961623, 209.137542504326, 432.519833094448, 14777.2302755756, -14009.2461485554, 9120.95104010261, -6582.44033351724, -11649.3194654489, -8989.95658598463, 7185.406592921 [...]
+7091.72874497572, 7392.91824295724, 4024.15079979619, -8973.44560569921, 11730.7440686319, -4368.34450097087, -12719.6225091051, 10037.4282654745, 3512.27393472789, -2240.69005374955, 12973.8569515753, 14218.0627359009, -5617.24113729045, -12073.2782373664, 4984.50355505512, -9378.88849630672, -14064.4186625511, -2556.62392131922, -6856.54697603532, 14168.8126076529, 3319.67398712474, 11048.6993505116, -23612.1428247742, 3127.10372965534, -3948.85326798672, 2887.40644526507, -21259.27161 [...]
+-4996.8819231772, 10443.6141062952, -2662.3898591467, -3041.84651886356, 1462.66299554295, -4580.40875660864, -1557.40640649097, -8584.65930445318, -5108.00242033754, -1133.40428137833, 14694.1033425642, 13293.5482324996, -3115.49283697146, 927.191081570306, 6420.1812752164, -13270.3518454222, -10994.0439771162, -2629.52701677372, 16731.5576860456, 3314.85797251524, 16207.7759036648, -1299.11630518918, 6228.16379582732, -13496.3721706199, -441.443381093076, 9265.4933751111, -1899.9214465 [...]
+-5363.72866154285, 8335.63646529664, -4475.23403593852, -7980.7738407945, 7541.6834103499, 4636.38159776186, -6493.590688195, -20638.834668788, -6403.73482345636, 19280.9193205238, -6702.15449850397, -15067.6821397329, 11070.2707346351, -1906.88504879459, -6725.62556952798, 899.27039934782, 15288.6350495574, -12379.9858502416, -9016.19014179858, -10412.1155631880, -7438.78675027975, -4149.48640416019, -10429.6005176145, -9570.4544782674, 3258.087177403, -4897.63582485236, 5738.2644885816 [...]
+7858.72336050382, 1600.76436220972, -13987.389905561, -219.399821078662, -5450.9369740892, 5652.32778722041, 3614.15468815554, -8336.64275819142, 364.578617414275, -22019.8793857586, -9109.63729832342, -13668.5142796147, 3890.17371826226, -4196.46454983520, 17906.1594001559, 852.688509139237, -5978.7629822349, -8851.73155487656, -4818.19050645472, 2810.68068418934, 6170.41725019772, -14227.0984790449, 190.663646192463, -4166.74265291695, -6248.32941338851, -8762.13105811527, -5259.826598 [...]
+6758.63029436768, 10771.0885454808, 3810.2668139746, -7043.66069594739, 12102.2944521006, 11954.9998175580, 12080.5356664133, -1174.86018372835, -4800.83556903892, -2811.68709450537, 6880.52567923966, -13781.6927883705, 20964.5190341327, 2022.30089574333, 8214.50394317405, -21747.6720589077, 3478.50393874018, 1652.09037130015, -12239.6783040935, 13341.8800569775, -4753.22233608194, 4014.08737820059, 4256.36769854610, 10384.8466941727, -10175.7935573676, 10036.9002808119, -4087.7254315904 [...]
+1980.70044151966, 16913.6334945936, -13729.0090672246, -1589.01364897623, 1883.63277076650, 15269.4616785642, -2218.31319041127, 1101.79400663992, -7995.52745550003, -9368.93559121668, -11297.0492007325, -2069.84207903401, 11514.625160192, -9782.57223828835, -4537.72488241988, 713.170154003584, 12565.1503199539, -12412.3196024492, -2180.91155859484, -2709.85005683046, 9537.57239052799, -12008.0912903545, -13600.4573159884, 4172.65310885798, -14733.5761305490, 3297.78602577477, 2359.54375 [...]
+-8164.32987817601, -2972.96021736828, -2445.41847285054, 3638.79741916176, 10620.7226982122, 3611.0049464241, -989.967458119005, -3261.92665841297, 3075.35841263000, 8637.00595516144, -3729.48545612927, 10360.5829123865, 9378.02971846865, 3065.45068392145, 15993.3927091204, 8833.19045444387, 10387.0310593231, -6528.49465498448, -24489.5373823419, 16893.5689029536, -15642.2919754732, -18587.7101315684, 12223.1628372279, 1694.97242687839, 6989.04936818395, -5788.97010518993, 2924.533622506 [...]
+-9058.27402422854, -3455.65256338419, 11600.6529872598, -10015.1186627615, -7520.86184753665, -7048.5517363287, -18686.4016530713, -25298.7007177402, -5553.48632704884, 3607.74931037788, 9229.13747024325, -9531.98535696342, -6318.46940504992, -7217.61251517955, -746.109802086927, 6271.3479161998, 16855.2123674553, -2111.28514846973, -21075.2843210073, 931.750779691117, 3536.93568537398, -3782.09350681817, -21835.1452069759, 495.40966462482, 7723.99398363152, 1098.43670989990, 7466.580236 [...]
+3648.18804131241, 6320.74089837219, 1803.70028269538, -1427.92975173518, 8878.99765771074, 915.390953602496, -14651.564462072, 3832.53047604967, -5275.86887879710, 13167.3873813578, 8422.71498664639, 11429.3621659629, -2471.50700147899, 3635.71565568741, 14365.6190488101, -1.05212983073762, 2253.76478503437, 3731.84683043434, -823.853883278859, 12577.6905288763, 1962.61943794608, 7993.67237527144, -11394.2291860505, -4303.46551340010, 3669.96107542671, -14338.4305193353, 8794.6163802845, [...]
+-21081.0174051601, -187.332279347855, 13791.3315374303, 16024.3094879744, 2670.97584063561, 2613.19219625988, -4453.3944516161, -1788.54977207549, -17008.2029842721, 12000.9480830462, 12420.6344057738, -12804.4560795243, 867.095733126103, -3450.45824804521, 1023.56265162025, -7759.3134983636, -3788.84706250786, -11223.3224065716, 13342.4314124636, 7056.52752856997, -3194.34782900327, -4236.28772828393, -8711.62188655431, -4394.07179679363, -522.181535153239, 4259.9997262971, 8857.9997811 [...]
+328.251743805354, 14925.8963424979, -8018.74135370715, -3944.33085162701, -18713.4193700233, -12014.5870071474, -4254.16846679176, -6989.58171919215, 5163.52253729991, 6437.54844029624, 6744.53495762136, -12652.6398855025, -9539.90634457723, 6090.6258360667, 1819.04159683925, 6418.6015883616, -359.663183830177, 13944.8603220351, 16064.8014693000, -7238.92234809932, -19183.4211634466, 18823.4722384114, -9604.39277635367, -12324.9378272815, -7778.95309864735, 28577.3829165219, -1042.460992 [...]
+-1770.34475748782, 6432.80654144173, 4472.15943195105, -12455.2077029846, 2038.95513932132, -3257.78077512111, 2275.39570156116, 13698.2925583505, -15055.5570275299, -1173.34415286674, 8140.01523246278, -11902.2680823381, -4250.05518819965, 18435.1806002916, 28285.6913653518, -7036.56142924373, 12277.8502188718, -12435.1120983421, 14375.4725241798, 18679.1449413604, -12938.8601588104, -3164.72202404174, 15192.1621360240, 5644.83785391433, 2212.78345568562, 5501.1938199925, 2386.205456305 [...]
+-12158.8981855102, -18578.6274457522, -16739.9896635051, 7735.51690726691, 8480.37893373285, 6066.1920789342, 10158.8305579039, 16674.5572245439, -7936.83138320614, -3278.84698111439, 5607.01493488326, -11084.2961160655, -17183.2375974604, 13659.1537315801, -6548.57356353482, -9967.27468053422, -13167.7534494016, 17104.8790925511, 2034.28375664260, 2247.40945145081, 11006.8382846253, -4147.28864375517, 8004.36726595098, -8827.81021914280, 6841.27914756382, -3992.98210904529, 16211.300429 [...]
+851.153956924956, -1992.25231842745, 9966.53891877332, -3579.94505371603, -2659.92645503138, 4460.17614289051, -2294.54335226914, -9574.56775049583, 7545.36637093599, 6197.59104934783, 11388.1180859253, -872.304524117423, -6266.35512040948, 8933.87076372838, 5141.9893269689, -12647.621553985, -10591.9817886771, -6122.86434461601, 16452.7025981356, 2072.1447218245, -2357.05851914926, -7844.00708119588, 6290.15026959932, 7059.21068311395, -9286.78888540416, 5182.99340707969, 5627.954489988 [...]
+12587.0304414902, 13606.4547525132, 4512.2403244391, -19809.8936598684, -4268.97213562258, 18969.8999924370, 12517.6851852282, -850.934400428425, -14854.1208951986, 2888.1409537399, -9737.53276526467, 5666.45574053879, -3522.24263192380, 12162.5850488367, -4762.57561996328, -1321.57219214247, -1741.91132226665, -15762.9024018699, 9293.94092389933, 8313.25536401047, -1662.43396203933, 15216.724289894, 9349.035279425, -10477.0854029222, 6583.94017568949, -1970.65404909634, -1452.8807949040 [...]
+529.086598759555, 6580.2329252336, -8648.18385479381, -2463.13558970540, -14746.6502015659, -8454.81246270534, -12305.0921575843, -5321.09315563727, 1044.00422238266, 6329.64585979454, 3200.7367423372, 3164.91765944538, 569.396511988699, -1186.21013671247, 29558.4188613918, 23217.3292240889, 21756.8898565148, -5288.88996835778, 9463.1797398039, 3383.85841060793, 5754.19348765956, -19378.6251436432, -16213.3163791925, -7123.41093692241, 2724.44590804818, -3826.69481803253, -7484.283907987 [...]
+-1398.70743723807, -2093.39130904644, -94.2870051400672, 1393.32562696120, -10635.2803650332, -15274.893536963, 3187.959311548, 9007.6403107394, 2093.36699848986, 2444.88132396997, -10522.3332375191, -1497.67241137985, 18783.4621174899, 10946.6244904614, -1729.09799194673, -3323.67207672829, 1439.30333037998, -13307.7965379810, 13330.0658614106, 4146.04311316799, -4920.63796281113, -10526.1896400085, -12025.6558424824, -5894.99152867849, 4200.56167241659, -9849.29775445111, -1145.5540207 [...]
+-1069.46030298556, 9758.49832679154, -3908.07077922033, 1320.99374600299, 6840.44127262085, -4118.42294455477, -10291.2396630256, 15775.2835029083, 4531.43699063607, 484.216039597413, -1452.40633102103, -9007.57229031525, 2532.22304309091, -1624.44930638343, -5864.44122441694, -8255.36840003812, -2375.77765577063, 24226.4524782108, 7559.95641371435, -9273.59122289261, 4921.96698863886, 14337.6089211855, 25101.6909823347, 9183.99237264343, -4081.38793272373, 2071.99111909967, 10722.218871 [...]
+2887.05683083313, 2214.67983292177, -8138.39582438432, -6430.24101022376, -8138.33111299527, 28805.3948978265, -8990.20063601434, -10224.3959966424, 2067.31175644786, 5318.42911503692, -8286.5297881894, -2315.04185012002, 7633.35719590727, -5572.92691154325, -2205.04653000039, -8890.77402527985, 971.932732038222, -786.511013736179, 6175.01258357475, -19464.8613587248, -4084.83401006874, 2673.1893069102, 12645.3076794401, -6531.02232298258, -1418.93986278358, -10355.3565085494, 23194.3976 [...]
+-5863.19626211692, -7720.63350729686, 4097.69000379121, 2955.21550148742, 2275.37926405776, -3485.54786860116, -3376.80175120822, 3873.41699149116, -18042.3164092100, -5945.65483487155, 7740.2650351972, -985.570199050552, 8696.0208990437, 4743.15667133767, 24665.2061955362, 9452.0001068856, -6050.0876461255, 10650.7752688701, 7961.64701294977, -5227.18070741001, 10364.2248479695, 19717.5781951997, 1983.59714104482, 1809.93695502795, -7808.7764943428, 3515.6671978837, 13085.9195465074, 35 [...]
+-4737.1449877747, -677.099190516198, -3728.83004220666, 4352.80765499313, -1987.57638726001, 850.609765279381, -4436.42791793939, -196.211385186121, -6510.43466765689, 3502.70309567312, 24355.9302237796, 9825.20828992563, 15028.8296988165, -1035.14339702042, 6404.31406190151, -14467.7034591687, 418.235288742969, 6977.3513136535, 5275.18573314824, 4501.12054022185, 14469.4124686328, 5498.18434074371, -8821.94659290086, 8873.49913635219, -13026.8573129455, -5463.65752917363, 22221.69339349 [...]
+726.879436917596, -5580.15260143472, -13667.8944091658, 11056.5309504209, -9192.83171982899, 6281.04652266824, -17863.7993945390, 7407.64379367348, 3542.01167150378, -6133.67742305791, -15118.0549369925, 6687.98217040297, 7971.4214380952, -10782.3816836785, 13953.3549944342, -5267.03810007737, -12077.2758494046, 5807.96341917963, 2826.74749845427, 1574.93244300989, -5966.03111363501, 13354.9060415424, 12956.5841647995, 4725.80191595835, 336.438456881131, -6340.2151074686, -4191.824073520 [...]
+-10084.5974840253, -1605.11742826467, -4830.22133676771, 5395.70196384489, -915.312250681838, 6888.32271441858, 8140.64848429746, -15412.1094262354, -1958.53086857358, -7334.47965566987, -8230.0175518831, 2894.31952789788, -5300.17351618974, -8097.59123200719, 5088.86822686245, 11406.7166170077, -807.773555963248, 2041.51515818584, 12517.8981146127, -13098.8302397369, 8179.71670365038, -16077.1297384529, 4868.95730623276, 4568.26616761989, 11654.7835565453, 5967.93488426115, 8816.1906886 [...]
+-7216.86310943319, 4892.7356365574, -16356.4049005272, -22065.1947972293, 4549.59531183912, 2965.23340291187, 7193.90771431912, -7688.45146034638, -5394.98839463856, 6276.2907038032, -16055.8433581785, -12333.1806525465, 6919.34413700972, 10662.4187126883, -3918.47455028046, 10648.0748128335, -23494.7169593063, 5929.96228393813, -12029.8210338684, 8505.71432821114, -15534.7570998859, -6470.77851185093, 7939.3781845564, 3555.24241810137, -27705.8065357442, 1369.85142622644, -13309.6177746 [...]
+-8231.35501627282, -4904.44488145935, -5788.37203928754, 3762.87914012076, -5191.78068965296, -12280.7305131397, 2050.00750882016, -7958.06306794485, -5985.61920886675, -4769.57964432112, 23949.7654007804, -10656.9050085556, -8272.19741209448, -11482.8502837001, 4346.32656043411, 10673.5246624738, 7703.9939117932, -4254.99054069772, -7239.97879740124, -7024.18076472046, 9602.67707923016, -1736.43552098692, 1378.84026371565, 1114.51594728836, -9701.67868251545, 9337.71561197576, 9280.8942 [...]
+-2147.09899882104, -4167.8544820226, 4913.09533840534, 6944.88743892773, 14506.3588266583, 622.960565317762, 11561.0604179070, 10216.9810453117, 13740.1907435929, 8811.82744286671, 16441.4849103172, -14442.6013012307, 7414.37519601885, 7141.56362556873, 2213.12269210017, -555.089079506994, -9968.9471347185, -12510.9999619631, -14573.0010758804, -7746.8935292431, 10467.5177885604, 5641.17471430818, 421.013486166145, -4859.24867435105, 13463.5603468691, 20630.7028362060, 7286.47123257527,  [...]
+-686.316762649096, 3892.70793723231, 4305.46470915774, 3677.64168548138, -8888.60602441446, 2586.76022692734, -6361.97206560332, -536.269570836826, -12988.1435116130, 3973.21257267965, -8771.6489552965, -3806.91223658372, -8117.58554586808, 19874.1202784676, -7074.84999963197, 1845.97776660672, -8783.29096853744, -9213.24782185591, 1952.96376413942, 28612.1605034938, 3032.19066815205, 9158.25432308955, -9944.46399142012, -2213.45745542143, -5644.58790035514, -5340.40928454661, 1095.48940 [...]
+-9107.76304251484, -6057.97527378124, 12801.8207292003, 7730.16030125723, 2753.06558387889, 7128.28355019567, -16376.0135549846, -11579.8305615360, 5908.73268447345, 6152.25990016628, -4935.96166534765, -13952.6497545544, -5266.72840449777, -9172.15475096494, -11950.2415908319, -23227.467185525, 25343.1012379351, 21894.8917649566, 9219.65291257388, 3336.28057201696, -10253.7523944212, -855.523019477605, -6321.18835187538, 7178.16445151751, -6607.61466325018, 19703.9072461377, -11226.9196 [...]
+7702.60987201496, 12631.4647640854, 2014.08878658247, 4177.32340235659, 6745.44309021972, 5254.12316043746, 5980.09284597262, -2124.14602789867, 23059.4592093700, 711.714469537971, -4176.83512300217, 6191.91242968774, -7854.1411161041, 7072.43391789103, -2533.87092336940, 635.772020360041, -15558.0423912002, -4981.6820914699, -2465.07545376002, 16919.7804511905, 4098.41229618822, -2308.97135121485, 6909.02606976512, 16337.8136760394, 1260.22386625425, 11910.3184950000, -3625.12009840876, [...]
+-5683.43873262308, 19895.6282979148, -6889.77007691614, 2565.63253352238, -1720.52850232648, 14775.6512607148, -7012.149117954, -1614.39840566771, -20723.105012471, -984.306874706967, -9479.28165103427, -1782.44795364309, 11101.8785536079, 13191.2445707016, 2017.80150650678, 9221.31342533081, -980.012514794165, -4813.02972782876, -6871.30839850576, -4479.92917450659, 10719.9081335213, -12436.3035297200, -9774.45568973892, -7031.79684106384, -2939.58567639146, 4144.28608135736, -20670.981 [...]
+11910.8479975243, -24103.1333388311, 5502.12237276774, 7870.17119658337, -2813.5311873177, -11604.1254642639, 7316.19143394093, -14590.9086390203, 4903.39481104629, 2033.17076310717, 5241.82889047789, -18465.9028380239, 4531.014663028, 21892.4562627062, -8264.85923452528, -16650.7974335453, -4586.63583124641, -19717.3896517579, -15540.2314479162, 5287.82224909941, 11530.9947546759, -2179.07851803024, 6695.2682143098, -9153.50176364406, -4393.95633963678, 10972.2970517423, 7213.9890876321 [...]
+8179.2020253707, -5359.9203552593, 9772.50039838626, -3309.34559697327, 8248.57390650957, 10811.7906660900, -8427.11173180718, 5005.22928644525, -6117.3925653074, 11000.7299266127, -1936.39833078005, 1422.44212464422, -13002.963015064, 12149.6678087043, -1013.39139914660, 23011.3328042587, -2901.97298661737, 414.900935690629, 6353.74270483133, 17229.1085017347, -2623.22480519604, -4734.92838434599, -11931.1306618232, -4038.45600716627, 577.941179180243, 12065.0233759077, 16204.6088431369 [...]
+-8683.8934838666, -2459.67012181272, 1173.31995671848, 9527.09092142303, -2639.03353902972, 20634.4115842801, -15792.0839586123, -12333.1807348315, 10507.7541788692, 5295.62681597934, 3819.65646531608, -18821.7760808016, 23470.6902772661, 12113.6661984995, 1761.66487901323, -4979.44043463584, -23150.0729308694, 19763.7124418869, -9603.6139488522, -3722.54165775771, -2979.41044977805, -10011.5949902023, 3010.24212011476, -3724.80752374849, 2964.84275414036, 40.7594863981976, -13052.805768 [...]
+13607.6229507570, -1482.90851785033, 1178.45523959058, -9992.07140009776, -1638.85105445075, -534.500171086086, 2299.13610584071, -13250.4748591714, -3958.67838577909, 9119.1771971194, -719.928927482014, -8606.49848957195, 13407.6615089204, -6951.47110457894, -4185.48634941225, 7512.36048955413, 640.590329885941, -528.932149677451, 20120.7783395021, 7407.99803031561, -284.872518425303, 8882.52041884342, 21977.4691157522, -6339.61736281464, 11080.5664650948, 23797.0638962404, 10648.194750 [...]
+4408.77005758327, 4468.03203445801, -9210.4309746287, 22338.6299342918, 2640.35712585595, -6993.39916937378, 6816.85114828286, 6405.03417317658, 10558.3348479436, 2893.43690561396, -15644.9111813502, 2364.01949152678, -1733.74473947748, 7777.35653688649, -10477.1485358545, 3822.75930712094, 12444.4762823661, 8793.58644014563, 11749.1102673534, -9095.84289580509, 11584.8101743227, 3787.13274243599, -7977.60514711722, 11087.6999246800, 7299.23058329821, 6678.08604740606, -9629.75912952476, [...]
+-7808.53236098579, 1424.88241190044, -12176.0307874088, -574.596211366644, -5152.32522340258, -10086.2459893900, 22462.3912946882, -4634.83015237711, -15500.5602610441, -14530.9959241919, 19506.1947841569, -8377.6901864232, 4235.67145658982, 234.618628509637, 8782.26287599298, -11608.3047561985, 13577.6182161562, 11343.5282304273, 10002.4949947037, -150.927702320332, -4676.53403920204, -106.937553347030, 6618.53479380028, -4171.22754599242, -12763.5140777626, 3847.20172068878, 1006.75309 [...]
+1820.19946294428, 1254.17180684127, -1824.72608675663, 6568.71700148, -3139.60063456663, 11984.6609512417, 874.619579598934, -9355.44868764078, -826.206045489028, -7956.98811291737, -3225.91468824075, 11434.381765886, 16760.9071997997, 7941.20146699572, 9055.8944663037, -10071.8432178143, -2394.75441642553, -10247.0879512960, 12667.4131967604, 10364.0630181367, -5872.36385961997, -8059.72547068219, -11096.7096513743, -9675.8753588202, 32091.3209248539, 10610.4927821381, -2687.46733991051 [...]
+19745.3507486497, -13563.6901748028, 11279.8090514382, -10518.955537655, -294.445166051541, -5948.67821738272, -301.69968606719, -17723.5737472365, -1321.49953991001, -4421.63109694673, -13125.3107800732, -32277.7847403167, 6227.14247875785, 14225.1887780516, -10885.6762563794, -2032.27218378306, -9965.8449188243, 3837.50881871055, -24718.3239955421, -7388.73577276734, 6452.36465754738, 3903.90926633336, -5836.30471581236, 6464.08716239171, 8584.35724178568, -1106.34128030584, -11474.708 [...]
+-4847.09136024644, 3952.22817875172, 16870.4920546086, 9113.46635937356, -9738.5496285101, -1678.43486404832, -9872.15684145089, 1056.06477109596, -4622.94779072534, -15081.4001048515, -1005.58106495869, 6868.75499042741, 6207.59375733168, -3215.69303523415, -10209.5129165981, -3857.48651930284, -16504.0660331169, 6861.44887816554, 9171.19027647992, 2109.09644148060, 6466.98738692035, 7234.2607606375, 4217.55782546834, -8964.80948133332, -1980.08942609505, -21610.7362309589, 15646.932776 [...]
+9697.80041736407, 2684.01293951249, 212.511047747819, -13726.6533998110, 9207.54066158457, 4641.97706621692, -0.241160769659885, -5962.29081509903, -12485.9508472745, 4537.53629015213, 429.599049371582, 6614.8963108324, -3455.97317875935, 16096.3473897250, 19014.4817573203, -11529.2157985744, 5326.18947893432, -3575.80768076626, -14637.2730985565, -10082.2985634396, -10476.0743345894, -10012.6121602980, -13739.5543254500, 996.740491860702, -2675.83648585496, 946.322862504347, 7256.216986 [...]
+-9915.00907289945, -6930.7770848835, 15608.6543389669, 9852.86592579898, 2318.1058523209, 20717.0854080694, -880.986477752934, -14441.8408696264, 16495.6256417791, 3152.47425907219, -8532.6495292423, -8496.46030976805, -1313.78547424769, -7314.40186797094, -818.443162491996, 19688.9093082116, 6009.21997719322, 4638.56454147549, -10301.5746052556, -10534.8223441248, 9494.3914182345, -4213.27447873057, -19177.1770327065, 3387.37163683394, 5494.90411765995, -2079.08311488286, -3468.63074453 [...]
+305.530197238026, -1562.76967820089, -19592.4722581862, -15353.3586307429, 9229.7846394253, 6867.27589445876, -11876.8580002364, -6994.10479960623, 19830.7097478344, 6464.65072974247, 9069.60951562874, 4445.69232399863, -1066.02818256066, -2455.72717113097, 9382.90988637206, -6990.41110637196, -2059.87605515241, 559.490209581068, 4239.59325382831, 6499.37648758687, 3696.95755224207, 71.6159489419087, 3867.48456572436, 12019.4828706972, -9856.91362570257, 13923.7283750374, 12095.429189042 [...]
+-10077.2161638232, -4336.44793316305, -348.134127234342, -5183.97766564894, 9191.88868970031, 1494.72986089728, 8456.6729675495, 11493.9008544875, -177.968965111052, 9033.30148543038, -9776.2119182365, 19173.5687403651, 6737.04215389899, 13625.8332513427, -6980.14190309085, -5195.17825456214, 6678.94783072969, -11424.2302905623, -3290.21190235017, 8768.29253384606, 18721.208975569, -1976.05478079694, 1808.73651711345, 2357.41987721487, 4011.92532510421, 2945.83118265104, -14968.425969959 [...]
+4189.73065056335, -7954.3420849428, -10334.6047773677, -3470.7250631918, -3889.99365721765, -2723.63252657222, 8381.1829338195, -6375.59368882704, 14571.2220308849, 18769.122774409, -8488.24218632707, -1080.57844057456, -11434.8305848687, -9318.47725318146, 12182.7077769320, -1627.07753864518, 16055.0302473087, 1912.4528173136, 4951.01950414273, 7253.76006103736, -3562.12895566958, 10126.1404582128, 2381.899405811, 301.773505895726, -19419.4625085341, 5552.21570786584, 1564.45451156676,  [...]
+5751.67600554383, 555.364899015684, -26204.9225780051, -6037.97895848485, -3416.74519426252, -8533.96692846126, 8841.94283189786, -14726.2080871776, -5492.84354038682, 530.717920466712, 3732.53242952378, 97.6697365780837, -6999.08784653104, 17965.9363950697, 2927.12627107304, 1003.62201722129, 10367.7027180710, -7164.85489271599, -5875.73266663738, 18855.7858708005, -11285.1004148661, 8865.13910679787, -15086.6616325901, 2468.41919279055, -15255.6490486945, -23904.7954170811, 4038.307821 [...]
+-12478.4673069310, 4482.02940489219, 8581.9315920528, -4852.28680884133, 13595.9767546739, 11381.0817766081, 4447.20808073019, 725.036643920251, -11754.4439397823, 5832.8011337391, -7141.30192171884, -21221.2126854112, 6808.62465190517, 1356.67654450099, 7526.69729539175, -18391.1392915166, 12991.1254470229, 17918.3874546027, -6856.08222516611, -1875.83154843294, 3582.17379034696, -3671.67097583703, -3996.05993934718, -3088.33021833657, 10433.2265154945, 10070.6163034205, -25399.12516770 [...]
+-22129.7127065242, -13979.1508378578, 3583.98321140996, 12295.1797316585, 4357.93375799366, 8425.34332321918, 4376.58280219881, 3586.20687425877, 17723.7429273968, 13094.1700964668, -14446.8721954365, 14204.1760466729, 3854.89580432167, -6158.14553956297, 10782.1940679317, -20044.8268518234, -7627.50993490719, 11444.3685176607, -5493.94612956247, 936.577517513047, -6265.2134788742, 9498.28535118705, -2022.42220737226, -8648.3189646463, -11172.4230565974, 7864.61889210125, -3590.938827435 [...]
+6252.18125314295, -10798.9024827298, 14153.1649155778, -3916.34929737669, 9609.93031578474, 7128.69178733727, 8695.26168101816, 8130.24652676019, 6272.03183012953, -164.366443634124, 24610.2008580558, -1150.42502288010, 4627.65317375373, 2851.4961204206, 6853.08715340243, 16253.9795824004, 5974.72669354246, -1970.29419698169, -7363.59071323533, -10609.4308020301, -9690.3668490724, -8429.13174598708, 7654.631058448, -10254.1174537611, -10678.7025811818, -3629.30062652774, 891.967984511137 [...]
+
+double yy0[100] = {
+71043200.4687874, 74466502.1571648, 34943440.1365317, 135794322.831266, -8982557.01490107, -66051625.8324929, 12436670.5589970, 46205561.1086465, -19205538.6316236, 62758931.9112128, 128000583.810878, 25103579.2540299, -1682872.15766174, 6332945.22139147, -15836271.8896985, 25243992.2241364, -48541985.3091064, -59350041.2040099, -86939022.9698905, 23403142.1524314, 120995918.311852, 150494865.60286, 8369268.02337636, 139539257.893322, 60966020.1122705, -95624184.8902574, -29144172.305755 [...]
+
+double lars0[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 104.86097902724276000, 260.79474009237180000, 275.60673890053454000, 341.56290166173665000, 348.59436019009257000, 428.34248173123177000, 526.65636168686672000, 552.74684843464490000, 578.47714214642792000, 823.02808048284703000, 857.92838821000271000, 879.08059230687456000, 900.56122838253543000, 926.97185475790320000, 950.16285310519856000, 956.18636353583599000, 957.18559463859810000, 1005.990194460004 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -55.59418890659734600, -112.06027882712141000, -125.62369490770651000, -127.49839886249895000, -201.56715209874642000, -269.21834815741 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 25.40337833776978400, 53.84065437336426600, 96.77270772445157800, 129.14976179932103000, 138.37554467146560000, 139.38576898485945000, 180.89346056466692000, 222.491359615795720 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.51871474881506340, 72.67696892248271500, 110.59674680810579000, 123.79 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -4.03450479444792260, -4.71822545941632490, -45.06399919639462600, -87.06442150831863100, -98 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -34.00838844359564900, -93.62564000319503100, -158.48365111350512000, -174.84836637178378000, -177.23612651013775000, -271.88471020611121000, -381.378314327 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 180.53184546622649000, 206.47280589217624000, 226.99493898097168000, 248.21854952173814000, 291.98783948612169000, 335.45919032525410000, 347.01416451998290000, 348.81805241535693000, 423.66866418387480000, 500.91444773 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.91168079897419310, 44.35749946087132400, 100.37839838266956000, 117.23234477539086000, 135.14098531920791000, 334.02531142665686000, 357.78793707180779000, 373.40492047279150000, 385.48408447552862000, 402.77155323406527000, 417.72944172488241000, 421.17173008653344000, 421.74994994196169000, 436.66446146759245000, 446.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -101.47573482470388000, -127.10817288571036000, -155.06926000136787000, -449.08523239460095000, -487.81129674570877000, -508.98867437047443000, -528.66789825363310000, -559.77089010761313000, -599.83211658546736000, -609.72752653017483000, -611.08752605849429000, -658.6028468174914 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -56.62849111949727600, -121.91808370284191000, -138 [...]
+-22.17288470348218600, -778.32629818663145000, -1192.89078499792000000, -1367.79620805705760000, -1444.52567898733880000, -1544.27942162885120000, -1554.29011544399690000, -1599.32715059251810000, -1603.53292958236120000, -1646.06768549352640000, -1712.04196284820770000, -1728.48738970539580000, -1742.25844931773370000, -1881.96626626389660000, -1898.69318067471500000, -1910.06043770187400000, -1921.33076586031050000, -1935.46329073744890000, -1951.96794943498280000, -1955.81620898296050 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 465.61849855319929000, 678.55954006253239000, 780.66425855304078000, 895.99472089040250000, 909.77118282340109000, 971.06358802947625000, 976.79314144821944000, 1032.94170396963450000, 1094.47505903944170000, 1110.92915067443140000, 1129.17195906511710000, 1315.47343754905110000, 1343.67163060345430000, 1359.37858797050540000, 1374.17450713936710000, 1401.76923986370500000, 1438.46366069482770000, 1447.24101956966160000, 1448.61758103161450000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -25.78817695897400200, -305.52390406906221000, -351.15180618241271000, -380.85430870618524000, -401.99904966551793000, -438.52682543808044000, -480.77099014789786000, -490.72483932302754000, -492.20093008585280000, -547.88515465664443000, - [...]
+0.00000000000000000, -710.77181256316487000, -1158.28715328331260000, -1353.48186365661350000, -1440.24263573404300000, -1568.34693070917910000, -1580.56167130278980000, -1635.76948318674640000, -1642.04719647752900000, -1711.74586424011980000, -1789.71269021599890000, -1811.89942463169520000, -1834.19357562044680000, -2071.44328620751230000, -2107.37030335824510000, -2129.32226911017140000, -2151.53343715934030000, -2186.82403998920200000, -2220.46176344815600000, -2228.4669851323069000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.46265064384541100, -50.16569612229420000, -334.23118950251944000, -376.22356425450812000, -402.47034251024348000, -425.22853707411485000, -458.82165295013095000, -493.65985590747010000, -502.07305378723510000, -503.03906012010299000, -548.14470826953948000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 80.04048809215778700, 184.43407544595041000, 210.45047388799674000, 240.80000666280816000, 518.30285569894147000, 568.71636072264062000, 596.71190246845219000, 618.83633832082887000, 650.17872856076258000, 677.70334200500008000, 684.51219525570014000, 685.34779676115181000, 720.06523334478129000, 746.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -15.91789294680389200, -92.72980766698069000, -100.75330642636234000, -186.76737268879467000, -288.51047688545862000, -315.52843831208122000, -342.06366593104116000, -609.76392965626997000, -653.46064421924302000, -676.98374236411348000, -694.91580695228515000, -723.61488201253792000, -758.99937051324309000, -767.23724677895711000, -768.17394171434569000, -801.816 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 107.48394421888969000, 136.784 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 59.70897134237968400, 66.38605894481136700, 144.32228169557351000, 242.18976312282911000, 268.89437690529661000, 296.92797314851987000, 573.14416743629522000, 616.39791850410484000, 644.04901614487528000, 665.01757587999771000, 697.77621789040450000, 742.05484598879980000, 752.38198781524363000, 753.79939771771501000, 803.82691928313238000, 87 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 206.11524969721657000, 315.08254832002370000, 490.93820323296507000, 505.92596408680396000, 570.76965883556886000, 577.90511322833595000, 657.05795131074535000, 749.41059827969946000, 773.34947232093396000, 799.07444175358137000, 1049.47092061501420000, 1088.32807575648530000, 1111.34787240105310000, 1130.81290728904810000, 1163.00904218628880000, 1189.37418272177800000, 1196.77064064368760000, 1197.97445795806270000, 1251.11 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -34.59383139175611200, -54.50120561194716400, -74.65260262985191300, -101.46306527023867000, -132.23574970968244000, -140.09316749960445000, -140.81529687085037000, -177.09931480812855000, -233.0114 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 125.54661711429884000, 134.64668537872009000, 180.19936205533190000, 184.93184313922765000, 251.06270909263210000, 342.06245685537260000, 366.94057297435404000, 390.15162020708721000, 650.63326407324041000, 686.69716218259828000, 709.70834217775030000, 735.45154237786062000, 773.42353417253219000, 808.80355830284043000, 818.27668848973826000, 819.52251733342007000, 869.325102903308220 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 57.47326640718755900, 71.71894148140411600, 73.70681154822824500, 154.41782999220391000, 252.68149959819849000, 27 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -18.42457 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq0[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2128.83781024428940000, 2108.73778041186140000, 2135.32438706946100000, 2044.04719942726750000, 1993.82336055508740000, 2021.69623604157820000, 1980.96791292565040000, 1944.64459830614900000, 1856.21841591627070000, 1725.87012520253530000, 1658.71569621917140000, 1631.22645163549780000, 1726.18590196130570000, 1549.45860790768890000, 1449.25574434015020000, 1462.48153770079220000, 1557.82897155116050000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1365.92457087512750000, -1327.26557758709350000, -1265.67187542775760000, -1254.39337941808570000, -1192.22053424839310000, -1048.0430 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 928.71566400816130000, 1146.84910447973170000, 1108.66216906251910000, 825.93552694433470000, 913.83188360343138000, 746.63722598880190000, 736.04976132764045000, 701.3811924646 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 914.42660239708619000, 1024.40306238277340000, 547.14273849370602000, 67 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -343.14744086323196000, -415.70652229710123000, -584.67990282176095000, -570.5882455316774400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1341.14680412106350000, -1498.77782487001220000, -1554.29127440059820000, -1550.35463589002030000, -1612.53203432707260000, -1537.78882573811390000, -1641. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 847.02587573457697000, 801.68795496964970000, 956.73626317758840000, 1063.96425012218510000, 1323.61059656741300000, 1271.00503666100830000, 1318.24642845628480000, 1433.14510554043270000, 1424.77923327827420000, 1390.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1154.15257561766090000, 832.47817292847515000, 929.06952978259403000, 1016.37118749864510000, 1024.46659645531710000, 1068.27369692469760000, 903.02121038199687000, 928.72527131939103000, 849.75598972717034000, 810.22952657908536000, 739.63778313626335000, 710.50699490548129000, 769.32112301914947000, 636.14279261824288000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1602.55913619800140000, -1494.56954705397310000, -1543.58955702342380000, -1534.54408813035410000, -1376.38056278068230000, -1262.02967279114020000, -1285.05391669310370000, -1292.85461698528660000, -1461.98876244552890000, -1441.46814673512590000, -1428.59081136566870000, -1294.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -814.02218012393996000, -873.55513250135800000, -81 [...]
+-3778.94975614819940000, -3647.86906533646380000, -3277.60519293438850000, -3085.87426724283160000, -2925.52149721334080000, -2726.44313781864590000, -2811.18084299265550000, -2761.83937004769500000, -2587.60608244407690000, -2495.90479400482170000, -2687.96879723661280000, -2605.83218052826170000, -2426.11582954542750000, -2397.74466389768530000, -2282.49211067431450000, -2314.26584654464390000, -2354.51444692820410000, -2268.56063570551170000, -2307.16429350090540000, -2279.27464082452 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 2807.06747311878550000, 2770.25758417437420000, 2751.44105750928930000, 2262.75534897620080000, 2639.47219873258700000, 2553.16529114746980000, 2317.40084120815940000, 2154.78032742203230000, 2004.70939324414050000, 1988.73619752349190000, 2035.09201933941090000, 2003.26800874529340000, 1990.67896599117220000, 1917.89830025077690000, 1942.86697467439100000, 2052.16485462390760000, 2228.16336704372950000, 2185.00589794344210000, 2276.0763368183648 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1306.40387629209140000, -1338.26243111485880000, -1398.08368968055270000, -1437.03806065179580000, -1214.71333759284080000, -1299.47030391812450000, -1389.90659470832570000, -1327.37746236841490000, -1379.48730253948570000, -1292.649485001 [...]
+0.00000000000000000, -3408.09497141716930000, -3408.70104123548570000, -3270.85951436616780000, -3114.85786603433280000, -3086.48795877982960000, -3114.18106622366030000, -3060.81346560772770000, -3110.91399279310780000, -3104.31326023407560000, -2943.03972482507700000, -2995.53643411883970000, -2941.29935533175470000, -2947.33039288839200000, -2931.71545165471480000, -2909.90665023747400000, -3005.23666576981580000, -3018.60790077441700000, -2944.37836265092530000, -2901.331281372518300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1329.51719854187060000, -1326.55384921817650000, -1382.95450507164330000, -1339.73829877910570000, -1335.77287189948040000, -1299.95714808245020000, -1250.59649890187370000, -1243.41194415408110000, -1209.22904444585470000, -1083.71084294260300000, -1151.42289 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1679.23567581432390000, 1728.67991369774290000, 1598.39569703829030000, 1747.92818407061510000, 1542.79796229576030000, 1725.45386833557950000, 1592.19826915341420000, 1469.20594862441770000, 1388.90496924569970000, 1270.05985457450060000, 1256.81792662670000000, 1187.63251207901700000, 1184.4033579712 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2014.48586599585810000, -2075.42669629389870000, -1978.10105584326040000, -1905.31362499200210000, -1793.54894916293030000, -1756.90590586866300000, -1659.77717194111210000, -1598.06949543251220000, -1656.08144336197690000, -1513.43562166786820000, -1384.14842185506150000, -1400.03935596294290000, -1520.50805617732410000, -1459.65689919379360000, -1331.2264803847 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1344.87740050030990000, 1350.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1600.93850760536410000, 1628.69893005076410000, 1701.47460976181330000, 1689.89794832040800000, 1693.55510456187560000, 1689.04900267886500000, 1592.88915525721430000, 1608.85492345879150000, 1627.28738228150860000, 1470.96020373091640000, 1469.88288483690080000, 1694.97408588527990000, 1620.41104327292120000, 1605.81237843485360000, 1472.9340 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2230.76423984689250000, 2418.31761076944800000, 2574.97203514615060000, 2387.71138193729170000, 2244.53853042025730000, 2247.46718920732840000, 2238.51804448505390000, 2115.54039943326920000, 2050.46113507246040000, 2076.55131701787240000, 1973.89374435766100000, 1979.90521902682740000, 1929.90298133927790000, 1878.96640791138590000, 1921.85766589209170000, 1756.77770803002110000, 1818.46641006242950000, 1921.5957452591617000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -828.34904210505442000, -762.38247515947364000, -849.18695656899160000, -733.37378189843025000, -794.49391634587437000, -800.53407720588700000, -574.89128080874752000, -662.39012256473234000, -876.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1613.37706349930840000, 1277.20399787052020000, 1356.02150689273730000, 1292.24337623086850000, 1572.34603848484540000, 1688.17944858522580000, 1694.15973073886060000, 1542.78957253263430000, 1612.28886662318520000, 1514.18304308325810000, 1527.95705386537910000, 1724.91112761665930000, 1668.40654392579360000, 1570.21616636407090000, 1614.52335446510280000, 1568.39716870833190000, 153 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1294.35398496517700000, 1269.11315634204700000, 1268.62657185182980000, 1233.91005721033640000, 1383.9278698750372 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -781.8849 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso0[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 104.86097902724276000, 260.79474009237180000, 275.60673890053454000, 341.56290166173665000, 348.59436019009257000, 428.34248173123177000, 526.65636168686672000, 552.74684843464490000, 578.47714214642792000, 823.02808048284703000, 857.92838821000271000, 879.08059230687456000, 900.56122838253543000, 926.97185475790320000, 950.16285310519856000, 956.18636353583599000, 957.18559463859810000, 1005.990194460004 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -55.59418890659734600, -112.06027882712141000, -125.62369490770651000, -127.49839886249895000, -201.56715209874642000, -269.21834815741 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 25.40337833776978400, 53.84065437336426600, 96.77270772445157800, 129.14976179932103000, 138.37554467146560000, 139.38576898485945000, 180.89346056466692000, 222.491359615795720 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.51871474881506340, 72.67696892248271500, 110.59674680810579000, 123.79 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -4.03450479444792260, -4.71822545941632490, -45.06399919639462600, -87.06442150831863100, -98 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -34.00838844359564900, -93.62564000319503100, -158.48365111350512000, -174.84836637178378000, -177.23612651013775000, -271.88471020611121000, -381.378314327 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 180.53184546622649000, 206.47280589217624000, 226.99493898097168000, 248.21854952173814000, 291.98783948612169000, 335.45919032525410000, 347.01416451998290000, 348.81805241535693000, 423.66866418387480000, 500.91444773 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.91168079897419310, 44.35749946087132400, 100.37839838266956000, 117.23234477539086000, 135.14098531920791000, 334.02531142665686000, 357.78793707180779000, 373.40492047279150000, 385.48408447552862000, 402.77155323406527000, 417.72944172488241000, 421.17173008653344000, 421.74994994196169000, 436.66446146759245000, 446.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -101.47573482470388000, -127.10817288571036000, -155.06926000136787000, -449.08523239460095000, -487.81129674570877000, -508.98867437047443000, -528.66789825363310000, -559.77089010761313000, -599.83211658546736000, -609.72752653017483000, -611.08752605849429000, -658.6028468174914 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -56.62849111949727600, -121.91808370284191000, -138 [...]
+-22.17288470348218600, -778.32629818663145000, -1192.89078499792000000, -1367.79620805705760000, -1444.52567898733880000, -1544.27942162885120000, -1554.29011544399690000, -1599.32715059251810000, -1603.53292958236120000, -1646.06768549352640000, -1712.04196284820770000, -1728.48738970539580000, -1742.25844931773370000, -1881.96626626389660000, -1898.69318067471500000, -1910.06043770187400000, -1921.33076586031050000, -1935.46329073744890000, -1951.96794943498280000, -1955.81620898296050 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 465.61849855319929000, 678.55954006253239000, 780.66425855304078000, 895.99472089040250000, 909.77118282340109000, 971.06358802947625000, 976.79314144821944000, 1032.94170396963450000, 1094.47505903944170000, 1110.92915067443140000, 1129.17195906511710000, 1315.47343754905110000, 1343.67163060345430000, 1359.37858797050540000, 1374.17450713936710000, 1401.76923986370500000, 1438.46366069482770000, 1447.24101956966160000, 1448.61758103161450000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -25.78817695897400200, -305.52390406906221000, -351.15180618241271000, -380.85430870618524000, -401.99904966551793000, -438.52682543808044000, -480.77099014789786000, -490.72483932302754000, -492.20093008585280000, -547.88515465664443000, - [...]
+0.00000000000000000, -710.77181256316487000, -1158.28715328331260000, -1353.48186365661350000, -1440.24263573404300000, -1568.34693070917910000, -1580.56167130278980000, -1635.76948318674640000, -1642.04719647752900000, -1711.74586424011980000, -1789.71269021599890000, -1811.89942463169520000, -1834.19357562044680000, -2071.44328620751230000, -2107.37030335824510000, -2129.32226911017140000, -2151.53343715934030000, -2186.82403998920200000, -2220.46176344815600000, -2228.4669851323069000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.46265064384541100, -50.16569612229420000, -334.23118950251944000, -376.22356425450812000, -402.47034251024348000, -425.22853707411485000, -458.82165295013095000, -493.65985590747010000, -502.07305378723510000, -503.03906012010299000, -548.14470826953948000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 80.04048809215778700, 184.43407544595041000, 210.45047388799674000, 240.80000666280816000, 518.30285569894147000, 568.71636072264062000, 596.71190246845219000, 618.83633832082887000, 650.17872856076258000, 677.70334200500008000, 684.51219525570014000, 685.34779676115181000, 720.06523334478129000, 746.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -15.91789294680389200, -92.72980766698069000, -100.75330642636234000, -186.76737268879467000, -288.51047688545862000, -315.52843831208122000, -342.06366593104116000, -609.76392965626997000, -653.46064421924302000, -676.98374236411348000, -694.91580695228515000, -723.61488201253792000, -758.99937051324309000, -767.23724677895711000, -768.17394171434569000, -801.816 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 107.48394421888969000, 136.784 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 59.70897134237968400, 66.38605894481136700, 144.32228169557351000, 242.18976312282911000, 268.89437690529661000, 296.92797314851987000, 573.14416743629522000, 616.39791850410484000, 644.04901614487528000, 665.01757587999771000, 697.77621789040450000, 742.05484598879980000, 752.38198781524363000, 753.79939771771501000, 803.82691928313238000, 87 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 206.11524969721657000, 315.08254832002370000, 490.93820323296507000, 505.92596408680396000, 570.76965883556886000, 577.90511322833595000, 657.05795131074535000, 749.41059827969946000, 773.34947232093396000, 799.07444175358137000, 1049.47092061501420000, 1088.32807575648530000, 1111.34787240105310000, 1130.81290728904810000, 1163.00904218628880000, 1189.37418272177800000, 1196.77064064368760000, 1197.97445795806270000, 1251.11 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -34.59383139175611200, -54.50120561194716400, -74.65260262985191300, -101.46306527023867000, -132.23574970968244000, -140.09316749960445000, -140.81529687085037000, -177.09931480812855000, -233.0114 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 125.54661711429884000, 134.64668537872009000, 180.19936205533190000, 184.93184313922765000, 251.06270909263210000, 342.06245685537260000, 366.94057297435404000, 390.15162020708721000, 650.63326407324041000, 686.69716218259828000, 709.70834217775030000, 735.45154237786062000, 773.42353417253219000, 808.80355830284043000, 818.27668848973826000, 819.52251733342007000, 869.325102903308220 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 57.47326640718755900, 71.71894148140411600, 73.70681154822824500, 154.41782999220391000, 252.68149959819849000, 27 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -18.42457 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq0[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2128.83781024428940000, 2108.73778041186140000, 2135.32438706946100000, 2044.04719942726750000, 1993.82336055508740000, 2021.69623604157820000, 1980.96791292565040000, 1944.64459830614900000, 1856.21841591627070000, 1725.87012520253530000, 1658.71569621917140000, 1631.22645163549780000, 1726.18590196130570000, 1549.45860790768890000, 1449.25574434015020000, 1462.48153770079220000, 1557.82897155116050000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1365.92457087512750000, -1327.26557758709350000, -1265.67187542775760000, -1254.39337941808570000, -1192.22053424839310000, -1048.0430 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 928.71566400816130000, 1146.84910447973170000, 1108.66216906251910000, 825.93552694433470000, 913.83188360343138000, 746.63722598880190000, 736.04976132764045000, 701.3811924646 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 914.42660239708619000, 1024.40306238277340000, 547.14273849370602000, 67 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -343.14744086323196000, -415.70652229710123000, -584.67990282176095000, -570.5882455316774400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1341.14680412106350000, -1498.77782487001220000, -1554.29127440059820000, -1550.35463589002030000, -1612.53203432707260000, -1537.78882573811390000, -1641. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 847.02587573457697000, 801.68795496964970000, 956.73626317758840000, 1063.96425012218510000, 1323.61059656741300000, 1271.00503666100830000, 1318.24642845628480000, 1433.14510554043270000, 1424.77923327827420000, 1390.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1154.15257561766090000, 832.47817292847515000, 929.06952978259403000, 1016.37118749864510000, 1024.46659645531710000, 1068.27369692469760000, 903.02121038199687000, 928.72527131939103000, 849.75598972717034000, 810.22952657908536000, 739.63778313626335000, 710.50699490548129000, 769.32112301914947000, 636.14279261824288000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1602.55913619800140000, -1494.56954705397310000, -1543.58955702342380000, -1534.54408813035410000, -1376.38056278068230000, -1262.02967279114020000, -1285.05391669310370000, -1292.85461698528660000, -1461.98876244552890000, -1441.46814673512590000, -1428.59081136566870000, -1294.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -814.02218012393996000, -873.55513250135800000, -81 [...]
+-3778.94975614819940000, -3647.86906533646380000, -3277.60519293438850000, -3085.87426724283160000, -2925.52149721334080000, -2726.44313781864590000, -2811.18084299265550000, -2761.83937004769500000, -2587.60608244407690000, -2495.90479400482170000, -2687.96879723661280000, -2605.83218052826170000, -2426.11582954542750000, -2397.74466389768530000, -2282.49211067431450000, -2314.26584654464390000, -2354.51444692820410000, -2268.56063570551170000, -2307.16429350090540000, -2279.27464082452 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 2807.06747311878550000, 2770.25758417437420000, 2751.44105750928930000, 2262.75534897620080000, 2639.47219873258700000, 2553.16529114746980000, 2317.40084120815940000, 2154.78032742203230000, 2004.70939324414050000, 1988.73619752349190000, 2035.09201933941090000, 2003.26800874529340000, 1990.67896599117220000, 1917.89830025077690000, 1942.86697467439100000, 2052.16485462390760000, 2228.16336704372950000, 2185.00589794344210000, 2276.0763368183648 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1306.40387629209140000, -1338.26243111485880000, -1398.08368968055270000, -1437.03806065179580000, -1214.71333759284080000, -1299.47030391812450000, -1389.90659470832570000, -1327.37746236841490000, -1379.48730253948570000, -1292.649485001 [...]
+0.00000000000000000, -3408.09497141716930000, -3408.70104123548570000, -3270.85951436616780000, -3114.85786603433280000, -3086.48795877982960000, -3114.18106622366030000, -3060.81346560772770000, -3110.91399279310780000, -3104.31326023407560000, -2943.03972482507700000, -2995.53643411883970000, -2941.29935533175470000, -2947.33039288839200000, -2931.71545165471480000, -2909.90665023747400000, -3005.23666576981580000, -3018.60790077441700000, -2944.37836265092530000, -2901.331281372518300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1329.51719854187060000, -1326.55384921817650000, -1382.95450507164330000, -1339.73829877910570000, -1335.77287189948040000, -1299.95714808245020000, -1250.59649890187370000, -1243.41194415408110000, -1209.22904444585470000, -1083.71084294260300000, -1151.42289 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1679.23567581432390000, 1728.67991369774290000, 1598.39569703829030000, 1747.92818407061510000, 1542.79796229576030000, 1725.45386833557950000, 1592.19826915341420000, 1469.20594862441770000, 1388.90496924569970000, 1270.05985457450060000, 1256.81792662670000000, 1187.63251207901700000, 1184.4033579712 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2014.48586599585810000, -2075.42669629389870000, -1978.10105584326040000, -1905.31362499200210000, -1793.54894916293030000, -1756.90590586866300000, -1659.77717194111210000, -1598.06949543251220000, -1656.08144336197690000, -1513.43562166786820000, -1384.14842185506150000, -1400.03935596294290000, -1520.50805617732410000, -1459.65689919379360000, -1331.2264803847 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1344.87740050030990000, 1350.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1600.93850760536410000, 1628.69893005076410000, 1701.47460976181330000, 1689.89794832040800000, 1693.55510456187560000, 1689.04900267886500000, 1592.88915525721430000, 1608.85492345879150000, 1627.28738228150860000, 1470.96020373091640000, 1469.88288483690080000, 1694.97408588527990000, 1620.41104327292120000, 1605.81237843485360000, 1472.9340 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2230.76423984689250000, 2418.31761076944800000, 2574.97203514615060000, 2387.71138193729170000, 2244.53853042025730000, 2247.46718920732840000, 2238.51804448505390000, 2115.54039943326920000, 2050.46113507246040000, 2076.55131701787240000, 1973.89374435766100000, 1979.90521902682740000, 1929.90298133927790000, 1878.96640791138590000, 1921.85766589209170000, 1756.77770803002110000, 1818.46641006242950000, 1921.5957452591617000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -828.34904210505442000, -762.38247515947364000, -849.18695656899160000, -733.37378189843025000, -794.49391634587437000, -800.53407720588700000, -574.89128080874752000, -662.39012256473234000, -876.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1613.37706349930840000, 1277.20399787052020000, 1356.02150689273730000, 1292.24337623086850000, 1572.34603848484540000, 1688.17944858522580000, 1694.15973073886060000, 1542.78957253263430000, 1612.28886662318520000, 1514.18304308325810000, 1527.95705386537910000, 1724.91112761665930000, 1668.40654392579360000, 1570.21616636407090000, 1614.52335446510280000, 1568.39716870833190000, 153 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1294.35398496517700000, 1269.11315634204700000, 1268.62657185182980000, 1233.91005721033640000, 1383.9278698750372 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -781.8849 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso0[1200] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 85.63725683745056500, 141.75705237535723000, 301.04490780354325000, 316.50050741447836000, 342.35775666390754000, 477.69270149639942000, 606.24269821852465000, 655.5487110150588 [...]
+0.00000000000000000, 0.00000000000000000, 37.78033308833145300, 351.83964317289218000, 395.50104605569373000, 497.86196023093891000, 769.08314528771189000, 837.97053529697553000, 960.31253150511395000, 1110.47469794233550000, 1409.55457648868490000, 1450.32019910342910000, 1664.65914313155210000, 1699.10628271111000000, 1704.49109412902410000, 1760.11724257557400000, 1800.77141754271790000, 1924.68975567719530000, 1933.46597067798670000, 1951.29191761745620000, 2062.30756216817370000, 21 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 254.21739515884227000, 285.81565020246779000, 430.97385649134662000, 455.81462453289987000, 458.07236091688691000, 500.01802937532165000, 509.21879442111543000, 543.36076949339940000, 546.16610749417850000, 551.73025252753325000, 573.81324554134096000, 574.90365350328716000, 575.68 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 58.42025256818439500, 254.89255649166836000, 273.80451893152730000, 303.67802020020940000, 472.83027855336240000, 627.60434189212606000, 688.145823733204910 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 156.52660748021799000, 350.07472430361628000, 698.14170638229064000, 740.08937895721522000, 982.77758823689283000, 1019.37931121425460000, 1025.25384258470310000, 1090.55225157337780000, 1137.84835167560550000, 1292.87512216212460000, 1303.42297017387860000, 1322.65966231514240000, 1416.74965513995560000, 1509.165528623603 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 119.62045290751925000, 350.03791639988907000, 381.22240289260719000, 565.21580914440801000, 599.84348658631507000, 605.94993864829507000, 682.26633874403262000, 740.41274083685641000, 896.81945716356029000, 909.99259039371589000, 928.32657208855198000, 1009.45489956987070000, 1072.94119344207430000, 10 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 28.12527954532683700, 267.30744958721056000, 469.34399071101814000, 553.64275917145631000, 55 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 39.65042062783857800, 123.86548570008634000, 220.03287448616862000, 451.54427028961300000, 480.68480022677517000, 641.12471924503495000, 667.97858293187187000, 672.75907767619969000, 726.72134389499354000, 743.60972484229717000, 780.38066762348535000, 781.83311786952891000, 790.21395181640787000, 871.25338623505843000, 935.95914531029143000, 9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 31.07841690684126600, 110.79003699605899000, 264.22892479600063000, 308.05704583335091000, 382.74985648779477000, 475.67083990318071000, 671.00167868962933000, 691.48716866125687000, 803.63953659564095000, 822.03017153074200000, 826.22188809873740000, 866.70129070814494000, 899.18710181550148000, 1026.79147352350610000, 1034.64717270432630000, 1052.96007466447650000, 1200.14966204530360000, 1343.809105443 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 8.33799728388278540, 104.62328225640765000, 168.52750066444810000, 418.17688290202813000, 437.11642472777157000, 472.24998591063849000, 682.64857244860650000, 883.06502467220355000, 966.041912050519 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+429.02139665452466000, 668.71490684001958000, 704.98170480954536000, 929.41126432812541000, 955.38566898203669000, 1013.40245420004210000, 1140.42682683789710000, 1174.44631208885430000, 1244.83449846464210000, 1322.21646825634980000, 1463.67237118101020000, 1482.77288491699510000, 1611.95836661366370000, 1631.98909733930510000, 1633.36861089725610000, 1654.64340348051840000, 1675.66813758995860000, 1712.14967254878620000, 1715.78745660017830000, 1716.23764449036090000, 1697.003906653009 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 140.33613649393953000, 203.17803445976725000, 204.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 42.96746290369154100, 43.96105 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 235.77382674918255000, 253.22471184530187000, 288.63441895560919000, 537.22910661292644000, 762.23508756645901000, 850.4121398202438500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 40.45183264701477600, 242.22508707753198000, 265.90856699009754000, 269.52052836738778000, 310.64750806491736000, 338.38711127219807000, 426.01581453940287000, 434.21075388117271000, 452.29759951116233000, 570.98134608248665000, 666.57362796716336000, 708.34200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.2521859 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 268.98276397169110000, 333.51136523423861000, 428.35123629387317000, 532.09934244250280000, 718.41938740515548000, 736.72403709512821000, 821.95700620109903000, 830.88128475176768000, 831.67267054674846000, 844.02814744318744000, 858.67762164702265000, 888.41852939099022000, 889.71480196850791000, 889.07431880104082000, 899.99855483638851000, 895.77688167504596000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 89.91916785933365500, 336.49804695868477000, 400.07215659014116000, 506.97639375306102000, 636.98251490516532000, 911.69130311615220000, 951.76132490488658000, 1206.35304946736730000, 1250.11945179064760000, 1257.98337343609250000, 1350.80384343165930000, 1420.61515347241490000, 1621.35027663712570000, 1636.17763627621230000, 1662.51875537206800000, 1855.37959443090650000, 2004.804760 [...]
+0.00000000000000000, 240.42662670366386000, 280.37978834143149000, 640.15018794377306000, 691.36507998205957000, 809.81571699314202000, 1115.21286970308670000, 1194.40234190637120000, 1331.17915300008240000, 1511.78645730677040000, 1861.53866118616680000, 1916.53056993130370000, 2201.08689241458750000, 2244.93849212347640000, 2252.90744232728370000, 2341.51838771852230000, 2403.23605430469570000, 2650.06691456460610000, 2671.12592899697170000, 2714.13198332598310000, 2969.850196129308600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.43092790465246400, 37.82084759158136900, 139.42477555584821000, 224.19995439754291000, 260.75295721663474000, 2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 257.98154946163061000, 292.26178828121135000, 381.42124120094843000, 655.64497548113286000, 734.17120922457502000, 844.44816180555461000, 993.53339691400618000, 1306.05666705540850000, 1348.76502722316950000, 1577.68506030701590000, 1616.76251165560640000, 1623.71414812551980000, 1706.87795441360530000, 1759.73802137113600000, 1942.34846658995730000, 1955.35876448536900000, 1980.85727287292660000, 2180.13805321874360000, 2359 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 232.14120223275694000, 436.73171911577242000, 522.76325530431552000, 524 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 180.59417945012899000, 219.39275621384303000, 226.99781080078154000, 311.89337750460481000, 367.82839932583067000, 522.85717623320363000, 532.07925938062010000, 549.73453936481019000, 684.42191507809343000, 823.58566515859479000, 881.061710 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 45.19208878808579800, 53.63259976813373000, 151.11116205841705000, 198.71339246660341000, 392.97817850638336000, 407.35069167917050000, 435.15144126490327000, 622.75379580099150000, 800.01938954756145000, 869.6403499388 [...]
+
+double nnlassolsq0[1200] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 739.95332606746956000, 731.33860104305484000, 660.26054422357186000, 751.21625184551283000, 712.89036594696233000, 650.23911123778123000, 658.97921305478883000, 656.273668922134 [...]
+0.00000000000000000, 0.00000000000000000, 2626.82440346584640000, 2577.69285964830940000, 2504.21503764279850000, 2391.46307164972630000, 2417.35999845274410000, 2286.82204513069560000, 2405.14049653480790000, 2362.08540874883740000, 2320.26361231856120000, 2347.56969670371560000, 2288.46030753426430000, 2280.53623020132090000, 2249.57379872098410000, 2185.13182316913570000, 2227.87474547174090000, 2204.14235159187360000, 2180.31235214458410000, 2206.73651532804480000, 2203.8478784261874 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1028.31854820720040000, 981.29180497324103000, 853.43491934761767000, 875.09955310177111000, 686.61389355909307000, 820.50616643748526000, 605.87989684731053000, 620.35553642813625000, 625.07114049765653000, 631.46406944480600000, 601.96814053607216000, 575.35098385823892000, 575.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 672.16986894807644000, 697.96414850391875000, 805.73650718504666000, 731.76324561334002000, 688.49235248857815000, 691.09905130995048000, 689.03597938517146 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2005.06616681430610000, 1963.30994739737660000, 1758.01824235580600000, 1663.35574235968560000, 1689.08501277850250000, 1637.17626412606890000, 1619.90891944803910000, 1589.46825932853430000, 1634.73020373757160000, 1642.48143629549050000, 1600.09962562572720000, 1598.32014206376310000, 1536.71047142881780000, 1547.0783345 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1116.66414002806160000, 1051.66741764024660000, 1067.59153069772010000, 1100.70086335478600000, 1184.32071524723850000, 1224.08141012971830000, 1265.36590045945540000, 1351.28534767280980000, 1249.53773562009930000, 1280.50997974071720000, 1191.05127301880730000, 1112.89013318636830000, 1098.9858917233 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 431.15860749978134000, 572.25473992645641000, 552.22771937788445000, 554.88222379830279000, 5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 873.58493004183651000, 1118.42405809883210000, 1021.59385812630840000, 1156.50483494060220000, 1122.06653731002760000, 1108.06090181359130000, 1121.24235879013330000, 1156.66924690832050000, 1139.02294278955400000, 921.03513592875936000, 863.30411195891361000, 822.68581888742813000, 910.31072778624889000, 974.57528490444929000, 962.50411855396 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1532.07216059729310000, 1585.39598019345250000, 1196.71422119012350000, 1229.85767334443490000, 1264.85301783076220000, 1250.17283904683610000, 1265.79114003241120000, 1142.37187018647230000, 1130.04208572274090000, 1132.44392533261200000, 1250.53242127075050000, 1175.98634464723840000, 1240.47549459776770000, 1314.55657319072040000, 1255.60243832859460000, 1315.38270444165550000, 1387.81024656995710000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 852.35977588496394000, 840.29618345054462000, 839.89038953958914000, 981.16997161725681000, 969.82413139840753000, 975.71150932774628000, 950.89799440478919000, 965.28412599950889000, 967.2619407487 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+3328.60184092859480000, 3243.83605031792330000, 3190.30490233266120000, 2520.02565112050840000, 2209.87102447717730000, 2086.67001784914780000, 1912.38471487293260000, 1889.95001404340930000, 2076.10113817552110000, 1967.19985197103260000, 1894.41070634118640000, 1903.17432255678950000, 1987.93322396732170000, 1970.08586984786260000, 1773.01119497879380000, 1817.19460106484390000, 1896.54911510880110000, 1794.42046314099730000, 1818.10648929959260000, 1722.68880609721960000, 1672.4816931 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 197.90781236316857000, 204.10201367126774000, 204.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.59922362033184800, 43.96105 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 767.47566302054088000, 744.06134688420332000, 796.05309458370414000, 854.17696430882052000, 854.54182856509067000, 851.7086277662028800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 930.79482734513999000, 829.45570739152640000, 665.65974081819343000, 635.14478586045857000, 624.88040959361410000, 629.81294526920533000, 623.63038049720933000, 664.70774178218664000, 711.48085757283718000, 722.29817257460115000, 705.78952777570817000, 708.9561 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.2521859 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1903.65618987714220000, 1690.68807571967890000, 1548.38607431995820000, 1396.84606235482100000, 1285.77065599750380000, 1139.60854331966990000, 1070.01470572409810000, 981.51332190885466000, 911.78145728507241000, 938.43083355077079000, 1012.58159805104710000, 955.48829484322960000, 926.17473317185033000, 879.89623891504323000, 913.92650012354034000, 894.044977085 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1753.35718585883390000, 1835.01763647291730000, 1737.17383388527060000, 1769.48833748803170000, 1720.59137301530020000, 1748.18948835548510000, 1833.70067999696560000, 1947.30385964086670000, 1988.84833654721140000, 2054.01639047696880000, 2060.00363934364400000, 2154.03657623130680000, 2074.03510201587910000, 2053.22303378326480000, 2039.98518638613270000, 2101.26911986353980000, 206 [...]
+0.00000000000000000, 2823.42392771753480000, 3018.32537471966410000, 3189.97461738642600000, 3164.88980177469240000, 3001.06478603177170000, 2971.18535846328130000, 2859.92902754848550000, 2946.47862301666780000, 3017.15922784844360000, 2926.54675842938200000, 3126.89997750682050000, 3029.24514479421900000, 2985.10541533679630000, 3059.57207600400120000, 3018.55508436566970000, 3051.62753715417470000, 3206.70385539115200000, 3263.44750605650780000, 3330.40579388412380000, 3295.8802512588 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 420.32599020059041000, 372.99679337437448000, 268.96554573575531000, 258.97823203838948000, 261.29040461742977000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2086.39116261995650000, 1947.89386743897030000, 2030.80509540587240000, 2322.16904773563830000, 2385.74854878472340000, 2146.79101974114840000, 2236.16782016504790000, 2257.70131599747540000, 2288.77408990816090000, 2243.92228490617210000, 2276.34704502991460000, 2327.40022258201320000, 2342.29549161839300000, 2315.07361803146890000, 2354.15969425632150000, 2321.29612552258730000, 2346.24915019630730000, 2434.2127360118043000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 528.11155229930989000, 520.66319405997308000, 524.02819722276115000, 524 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 706.18629681430468000, 874.27019235975649000, 996.82676136108682000, 960.54252335636954000, 955.46875820497746000, 872.46801511669605000, 791.46646153081304000, 802.73349130511576000, 856.14270120306821000, 880.67637972823104000, 881.906794 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 807.98499791610220000, 908.03142566515578000, 895.90136281224295000, 698.81137848185949000, 831.07151941862571000, 811.60273757407288000, 833.53427714423651000, 861.93897280237388000, 872.74105312552854000, 870.66400330 [...]
+
+
+
+// Data from file x5.txt and y5.txt
+double x1[5000] = {
+-7054.67658600709, 8484.51549339579, 3228.24264248921, -11909.7160575963, -6593.21459226395, 9418.91755847784, 4515.55863251987, -20400.4208212937, 7933.67363555387, -9425.5560631482, 9188.2199226505, 4453.43570598148, -4856.41276605415, 1861.83476190500, 8636.66188882458, -14553.4354695762, 5680.4621684432, 3342.46270232118, 7653.23901452694, 4004.28088591436, -1271.08219037372, 18061.0756715459, 15374.4039664115, 18093.8869508444, 9159.37742970751, 10990.0660302707, 4569.12677317348, - [...]
+9577.18025281376, 4475.7913187288, 3292.28529970623, -17749.9552239435, 15846.7027097015, 5060.06239213793, 684.840758022536, -726.48476430495, 1369.25947049597, -2652.39182885904, 9084.73516695335, 25522.4853506547, 442.051098954115, -15904.4474822468, -12010.9666019956, -27783.1653618319, 9057.94799249308, 2966.43982430354, -5268.54456875361, 9995.26690535702, 19025.4995679264, 480.864775783722, -14752.0978790698, 2002.40588137369, 5431.25865963568, -9846.17951481933, -9328.87671435456 [...]
+6196.84779415505, 7993.77897511089, -11870.7233247089, 1482.29619127955, 19644.5370807348, -4753.18087285877, -14983.8028230422, 6177.08875724147, -23445.7835236651, -9250.02638337182, 1816.09151520825, 4597.52161193633, 8226.94372875153, -3505.63071332173, 5354.76731744755, -2964.08935434417, 19480.7872007669, 4563.03619438228, 126.584148766589, -11065.1883931865, -14.8602341401534, -1377.13571609124, -3081.23555344787, 2553.17137238609, 6000.98388475136, -19181.5675146383, 2638.1679131 [...]
+-2926.32615104349, -5440.44097183076, -7659.54541465252, -4559.44733631566, 10481.6450728483, -4401.38925116699, 3590.5922154555, -4202.16976587417, -12141.2588585049, -1277.97337308430, -15056.9849938174, 5579.44516248833, -484.174408937609, 29303.0268767858, 1995.50931329148, -1659.95082933387, 2655.07040991112, 1562.03119721000, -7321.2960692452, -126.545195994981, -5755.0764150246, 9445.85398052727, 2630.57693169091, -3723.61186482221, -947.978382357656, -554.330346305584, 17229.9408 [...]
+7612.76702537207, -8587.75346224458, 11750.4572968809, -2967.79984201979, -6824.55097779311, -6513.14146867636, 874.517590735211, 14222.7137897355, -15785.2584350247, -12114.5734024135, -3097.79798214869, 12906.7301639958, -3772.93776455896, -2497.425632748, -58.0991198509348, 22019.6931467889, -6390.34910784964, 23680.6488342803, 1273.16026603663, 8366.04045538804, 2319.28547739490, 2691.03093258443, -4949.30383434823, -3001.09820858773, -298.378370146992, 1881.73216044378, 3866.8005031 [...]
+9886.41520132672, -4941.37674269898, -5987.73794638949, 4613.02867882296, -3193.41681928324, -21729.6155734947, 1006.65079320462, 7334.10633245095, 2681.7050218353, -4272.52614565611, 8869.79573667571, -1.31525908441807, 6483.20729123114, -9770.50958367618, -530.271637037295, 6550.93889952071, -2272.40613127707, -6305.31099371149, 27895.9492512216, -17574.4451439312, 8590.08191867085, -10696.8172981074, -6446.52741869196, 6467.12521371059, -2862.3187620102, 5429.31660601166, 10214.728988 [...]
+-8920.67810218429, -8834.87407867868, -19580.0236225465, 10211.3405487206, -7257.01725597896, 11080.5608707781, 4081.7097315025, -17605.4824344382, 4042.81662075097, -6139.39059818738, 2397.77686485365, -13994.2211319675, -727.955037968634, 2110.56608943556, -686.204886717925, -15602.0791613855, 11382.3463053056, 10600.1637551132, 2868.51040247577, 2615.91946390013, -3983.26559415618, -1234.51606888785, 5164.6072268089, -16478.8279992226, -9051.52576598068, -16736.6278871872, 3363.626220 [...]
+12395.8535507637, 3522.90489890719, 21753.3397003005, 13233.2694665280, 168.813487222035, 7748.12192207605, -6314.10060701192, -2151.45894683404, -6203.8567169948, 3080.08155688784, 13151.2051020626, 3558.87845293574, 809.996977098513, -2884.08645458395, 4298.35683288929, 17136.5524660285, 15962.0626117012, 2611.33776059397, 2756.32612687514, -13087.799424433, -3808.65850688687, -7329.26937156573, -14109.4248079563, -15673.8144705759, 10160.3512834705, -650.615817450004, -139.69430128053 [...]
+3243.57749355541, 5114.95706545062, -12489.1606834822, -3204.24851876784, 5236.27605366104, 11307.9799800459, 3737.12604773602, -6757.29371773126, 961.736537710892, -5546.8447562916, -9601.19099908254, 10201.6104607509, 2851.00706303951, 12788.2462823544, 4736.14636281564, -5334.67849239148, 1503.70406347764, -3124.88772753961, -7993.84545967612, 11058.4194869767, -1218.56325564472, -7622.6329541314, 8893.69524691647, 4625.5070394984, 1396.15794884015, -1772.79009022727, -3762.2313868680 [...]
+8519.35350886881, 6594.87326625043, 3879.56457896309, 8012.45942999462, 8324.92590403547, -5386.60865312981, 5023.99849628765, -1293.26662242651, -18687.2067083037, -16699.8218777985, -7596.26487108897, 281.549861446825, -6429.43182675608, 4391.5102842123, -11022.7927143965, 687.473899003513, 10636.5390214193, 18479.4274645099, -4410.25278203831, 4753.37419808167, 6269.33386774853, 2420.09338555152, -12352.6167293539, -2085.33293762319, 4832.76431329723, 4216.47265017608, 10782.961289911 [...]
+11536.3837434685, -4056.57890897398, -8192.96724050554, 379.523448898178, 20575.6677224249, 48.2445687490131, 14239.9808524248, -4531.01470020162, -1407.03826195042, 13375.7446853035, 5601.77565061187, -12514.7537641701, 13998.6813552309, -4665.44601388165, -2217.20666351709, -783.225121613593, 200.327148907508, 87.5118325553658, 2795.14766456163, 4112.04821587802, -1206.17410934132, 12979.6403639706, -9729.66813725587, 3024.8166837736, -5825.34029646915, 6033.86023955525, 9740.811003304 [...]
+13832.0789148715, 12098.0104988730, 975.578674072825, -7164.89717794207, 3922.66401022957, -20857.7921476374, -14648.1388951931, 14918.7717588671, 3500.08921053554, 6681.85504594808, -834.092268094308, 20803.1317348393, 11572.7773696299, 18180.8046516354, 26463.2625162827, 28599.8004730028, 4874.07452521633, 5688.07942074163, -1456.56327346738, 12019.9268921578, -3956.66281336822, 2167.69347747079, 11238.6001239928, 2426.33086332965, 14964.8652300121, -4461.44792788199, 13168.1565366521, [...]
+-19763.6333226368, 6200.73581993822, 2814.06100223425, -13969.8221644442, -7018.46148533869, 5217.31140331343, 1908.90922649457, 11773.9828230993, -13863.4090135306, -8763.87101318625, 9204.87371152288, -16916.6611656473, -4516.43239632052, 17954.2436170630, -2852.87936188754, 1205.78037193308, -7053.08004154441, -2610.33990707564, 9566.42496475683, 12890.0547811740, 1406.56841494219, 13374.3546197778, 625.768213011898, 4028.96738253672, -2937.21094200861, 4919.67882006948, 814.017308297 [...]
+25349.8956322645, -16228.4047128303, -2415.59027661629, 1162.92834830575, 6687.78714711376, -1016.63415084870, -5563.68808636981, -11160.9267130969, 5867.7697798458, -10570.8999994160, 9940.8237135569, -12068.3547384855, -2183.80615469505, -16987.3496673810, -1830.00290373335, 1288.42528560977, -8474.09296561063, 15365.6055514539, -972.237239173834, -2565.18708941698, -90.7358996553297, -4951.26642120519, 4371.22819954248, -924.630347028547, 6602.39754938756, 16124.3138289618, 11474.7911 [...]
+-6601.89822068388, 18413.5635803933, -1249.95758965871, -4614.84808579614, -14358.5240635132, 4660.85604113319, 27592.0801370292, 16075.8618604139, 9434.01741809666, 9484.23798240408, 13996.7258042388, 1384.53573620836, 2749.54812567756, 8196.38586819566, -15970.4734651937, 13580.4055385487, 8839.33884457856, -20311.7868128557, -17764.6390499773, 5913.41437879687, -9656.77861935059, 6018.42387982523, 4359.78346794444, 14663.7686864427, 10832.3754785981, 15164.5728404898, -25997.859026628 [...]
+8041.03304098651, 3215.27165824492, 7924.85419466224, -10057.3679792007, -8454.4524606082, 7129.41546260748, -3528.15513372362, 51.270295280484, -206.797894436491, 404.924377258728, 19775.4470892705, -14123.5822946049, -7224.53205015561, -3030.83171706993, 736.338892137124, -454.391667222248, 17368.2923062446, 12904.3147780382, -3618.56370788667, 5411.72312053745, 17280.8797375318, -1155.6139247902, -2232.55739128969, -1300.98090871674, -4624.28330822127, 25264.7047637654, 552.1220899691 [...]
+-6713.60261286514, -6416.44017826462, 7373.08101872237, 1039.45589174163, 3257.36166165077, 16131.2014767206, -802.460596890295, -8381.17412175822, 1581.3576524177, 7219.84327038406, 10567.2989736948, 1384.04866214056, -1400.94154683639, 2651.18869082404, 15395.3563513130, 3151.00069942522, -2267.06312824007, -9966.2228932496, 4463.4502404277, 15008.5689438440, 17489.7513148344, 484.332392160751, -18560.8686176272, 5513.07773367902, -7041.80194834938, -4235.59601152183, -20112.6042175356 [...]
+5536.95103806201, -10405.8570516991, 3854.78752057459, -277.580971191826, -1134.47728534705, -7381.09414341605, 1723.36270479698, -11385.4399917933, -10764.4717821574, -17725.8179228446, 25630.2046913593, -3174.12271743948, -17390.7481490425, -19520.0510468245, 12136.1387421065, -8495.23481533012, 15132.2691937239, 5005.46751740004, -12182.9203485240, -4285.20044007775, 13908.1840469507, -4413.23110981671, 10569.8547944761, -8510.43855273157, -13451.5893056403, 3081.40291989479, 1805.542 [...]
+4167.84303612958, -14435.8599148526, -7599.94999334583, -372.755182875022, -9799.27820220518, -881.18320050586, 7153.33994920041, 9424.8419344432, 8915.03933783208, 7138.08364640927, 9255.7506031436, 2121.27249147548, 2295.34047224723, -10595.1638234412, -9144.8284804017, -16364.8529533400, -750.315506031741, -12716.4399030001, -881.817234761322, -3060.41436652169, -5738.6417155273, 8686.90615612141, -6075.10659980318, 11073.5247512562, -4047.74541928726, -6260.34070126081, -7156.3871414 [...]
+-1877.54262069336, 2420.34974614852, 10167.1696144917, 20197.9589605606, 8882.4672699098, -259.779123948245, 5806.66243878115, -9888.41601287722, 15264.1137240713, -2763.87219040052, 14384.3654292233, -7048.26786908288, 11176.6221272853, -935.386494450344, -2479.05862003347, 18024.6169073288, -5434.15753172822, 10494.7269005287, -21203.4798189913, 7002.81277778321, -7098.28114002897, -8750.04538119194, 12717.8102713759, 7440.24304073634, 6878.29327289433, -7827.87334131842, 1495.61695488 [...]
+12695.0472661077, -2047.69848259142, -1846.94777228669, -8630.2519584244, 7164.27694247641, -3705.28535945395, -2054.49406074497, -10229.9002379336, 3294.59084250747, -9235.62053697562, -19981.6151311956, 1585.22864917048, -5981.4518759224, 14647.3354802136, -9862.66524585641, 1142.65196000029, -6326.3043906197, 221.862280328297, 21092.6801253004, 21299.2497137519, 2680.46010825618, 13045.9987881708, 3203.02375676736, -4277.3912673181, -12222.7115946315, 4625.86027708673, -8970.408462185 [...]
+-9624.18306638911, 7761.93448945395, 3442.29962462523, -480.755634845905, -1401.00826394683, 20102.0160494953, 14566.7280943968, 21650.1135043824, -6096.04966615581, -9433.26856341313, -18191.3288789299, -23427.9074752490, 15369.8552996733, -4160.34296001845, -3770.12829807098, 2252.58882473683, -11212.3231563460, 16188.0100070584, 3795.87209564778, 16391.7915985442, 13765.0309172110, -10480.6943973326, -9115.20094000085, 11159.6404401417, 11582.6610536576, 23989.2864431042, -898.2669895 [...]
+2770.11431972903, -19928.7947196957, 5527.87201370937, -1107.69806616331, -3798.67323545031, 236.81918077506, 6942.42254738572, 11187.3689371588, 14033.8505059746, 5696.13840123759, 20323.8553638286, 5190.08204502331, 18227.5565546030, -15473.6193369967, -10943.8235189431, 9650.61042011288, -7868.92085891557, 9383.29471571666, 23030.9015174829, -1239.72245754084, 14830.1954538909, -2345.85802176022, -7145.81057253734, 15899.5223481322, -7120.37559826714, 10443.8808249107, -4427.795645239 [...]
+18712.7386427901, 25318.6379347035, 19217.3145035193, 7779.06352643464, -15893.4652112126, -372.257347361756, -4415.54525218563, -8372.52511019805, 4427.22317371222, 3984.88185029189, 7298.61477556252, -2085.76377365745, 16013.8719375699, 1818.97918618434, 2300.59888451472, 2627.99661508676, 2841.54244066663, -11524.5721498359, 17152.3979879796, 11757.797595823, 5228.44680144534, 12669.2112131835, 5130.7440298025, -10147.1281129816, 10659.8891004434, 1945.20732535915, -5616.21711580648,  [...]
+-5656.24724921922, -4798.5572225267, 1666.87579457511, 3797.63590866937, -1918.92428617331, -2628.67644587203, -15532.825356426, 5460.95618202462, 6360.64939520117, -19685.2079208319, 14991.1989829984, 4509.59575250167, 5523.33942953747, 7899.14239809887, -1559.53735399995, -15429.0535470103, -9193.75474335859, -10878.5738512703, 3351.71697194952, -2747.87557587985, -14992.4620203274, 10800.5284477617, 1075.30016629156, 135.345710879563, -7644.96375742097, 23498.3597155104, 18938.3401967 [...]
+1140.09690781192, 2724.15294157216, -2535.71308900262, -2143.94650502453, -4050.90705264292, -14267.3624044591, -13363.6690775577, -7524.30307790414, 7976.83672520536, 18940.2451116037, 17743.5209398026, -6824.02153886538, 231.769040731775, -317.82410466603, 2848.56301581957, 7657.34619855385, -1742.40115376577, -11242.2960883380, 11403.6609395824, -1548.1247403414, 6231.18333933731, -3534.30370946796, -8030.98501512005, -3654.89863226280, -13487.2714485923, 19580.537007354, 16079.028995 [...]
+7398.38290022854, 18352.2824286097, 18516.3774899817, 140.612324006926, 9811.45367858223, 2829.22500471913, -7549.51411294757, 12011.6195860166, 25109.4042469001, 6697.47263656298, -1823.01506072784, -9686.42818170283, -4482.84837067396, -240.590760664426, 4285.89658241811, 10755.4607421407, -5942.77929174052, 14313.8703499587, -4209.3674403771, -14273.4334935188, 8947.84629088592, 11631.2308585356, 18356.1554604588, -8254.28134333943, 4017.0917863427, 16400.0912614551, -9009.19611841559 [...]
+11764.4336104825, 2990.78213240013, -7721.03902739293, -875.448885941855, 9230.21771135985, 3222.62272932633, 1341.96943570658, -2144.98543673871, 8166.70989049187, -11526.5917890043, -5553.02089071176, -5414.08513134374, -227.494547391124, 3312.19795993551, -5385.08351296601, 5864.75594656232, 4442.40819061046, -5202.81554024891, 7071.95074476983, -7459.55873632772, -13999.4742087773, 4977.90842590764, 1624.96644520327, -7844.35635470543, -8667.0633077821, 4669.13699750321, -14423.44616 [...]
+10136.1863609215, -5794.37598910309, -9614.08169052826, -5944.16642488027, 3800.02671413711, 12652.0101320771, -11854.2052646217, 7994.75304033867, 10358.8690250035, -13693.7301620621, 12153.1423093334, -23926.4361173740, 6077.01819030876, -336.141988555298, 3952.37388338953, -6869.31201305302, 1380.89056827562, -13665.7812240744, 9803.21329524401, 7478.37436961391, 3979.23866274179, 7035.41395716296, 16049.9487173406, -897.085704570118, -1765.83189538625, 2665.40661383425, 10660.1290703 [...]
+20962.9209929710, 13644.6782181397, -12096.4475799631, 12415.7053458003, 731.957668636457, 19162.3282957246, -1647.26923917597, 7270.73973633409, -13299.9990630529, 9258.98265546489, 19278.4197259428, -12557.1534706868, 3984.09664469558, -14151.7198786145, -3040.82333479591, -2865.96252451552, 3834.40118640170, 23425.2895542654, 6334.89949393481, 2240.7263342665, -11939.7303338090, -13132.2971172965, -8689.43426343527, -4584.33277390995, -4391.03841182788, -16059.9671170663, -5198.033022 [...]
+9323.31392207409, 3544.10414603403, -2641.91470668187, 1014.92827867206, 3323.85293919047, 10348.0172993844, -336.657722034469, -1730.10916778903, -359.651738649788, -8374.37881395987, 15706.0587755846, -4929.27583990137, -18881.7894706766, 6784.51978520975, -8810.22760499496, 4787.79200975066, -13895.7020088106, -12821.4677409698, -5884.76245231681, -21365.9439372684, 623.338574573493, -12195.0604095120, 7099.13261548436, 12804.5736665124, 788.192140027866, -3230.67317424976, -28218.484 [...]
+7032.42704770666, -10460.3796894458, 5912.88859004561, 17069.8220293451, 8100.25386786556, -409.448096385608, 19288.8254521129, -2315.35156983379, 8777.41228188421, -17244.8811363527, 1050.19441825777, 11889.8966465751, -5844.27078718144, 4629.5935716835, 1883.6798901552, -6753.62638086544, -12656.4516368697, 565.694550624649, 18550.0705407131, -11930.2625276559, 8502.3396255124, 18585.9375381646, 8225.93572312762, 21053.0144739591, 7159.13657469739, -9339.50436769654, 6023.0163544818, - [...]
+188.890688972113, -1849.22167634933, -18215.5593711538, 9404.67127489963, 2464.37395518196, 8095.71885228352, -9205.76846972312, 6168.01623945159, -7963.67071254628, 18223.1777140564, -591.724430470447, -2565.21724083723, -4376.8132687342, 4459.84437530694, 6487.14987732046, -2267.02239454353, 18554.2486085233, 12050.4498628782, 2038.73600215498, 7120.83945402286, 5755.70081947738, -779.860270286214, -8303.78794834005, 6482.51828313068, 252.925372572961, -4328.33695490259, -18237.8869285 [...]
+-16714.0223759167, 5926.30930570225, 10847.2903445611, 7056.46455145718, 1299.35951927732, -798.178249874121, -301.759097330653, -6582.48057667928, 5114.02648338284, -12671.9945068220, 3211.17381858793, 1825.31950019233, -287.686787534736, 886.03551854129, -12405.1840076936, -2305.61880195947, 3796.49930134046, -8449.43141804634, -18897.0916956768, 23047.2300062633, -3209.81219865975, -1571.44941004616, 25130.6807285091, -1131.79410326959, -14683.3621111768, 4991.86399576447, -8768.68686 [...]
+-4624.59912667131, 6052.70206696465, -4596.17926006583, -6119.56114138252, 5386.70654810354, -4593.70147574025, -3983.46667074906, -13113.8644872145, 8026.23014508046, 2475.57566752918, -1298.73651685640, -1858.85279924355, 2860.05404029503, 23099.5621220007, -762.63586975026, -25093.5200743484, 2479.80670710942, -5654.25426050569, -8372.93633942557, -6978.66208340463, -10563.0007303973, -12108.7898759491, 15678.8924857607, -9075.38967690837, 4478.15723921652, 4680.53861220637, 10058.429 [...]
+-9158.98247232457, 5938.56906190562, -587.784951515445, -3310.57237946123, 7993.67266283175, -1237.16237986119, -88.5731116816052, 10126.315620657, 5748.46731135564, 4164.1793279064, 15477.0258876483, -2758.52964705087, 5156.88820246199, 118.770019969649, 11490.7024376221, 17037.1543996409, -3780.91825723108, -6432.43197114192, 1478.22353370629, -5970.11360259869, -364.726140656284, -12290.8846050477, -2897.47241938333, 3869.02384905485, 11544.9878082675, 3328.38933268596, 4776.392539482 [...]
+7213.18774618022, -2936.49674038573, -2555.88839780092, 5034.73157488339, -3647.21746983585, -18213.1974547117, -14535.6533708432, -12458.3422048056, 16518.7976739433, 4490.6647950183, -2635.43348520034, 2776.04271705691, 3336.92977591733, -1517.48042508731, -2808.31619598868, -13713.9709299004, -17397.8040792135, 12703.8420586026, 9232.65073790827, 2513.03546136155, 3171.04776086617, -17111.3681821258, -1807.40979307686, 2686.9882499354, 3857.93638603780, 11635.9432440648, -1840.4605220 [...]
+404.886592373373, -8800.58432195165, 14618.2587520278, 967.6951104311, 2397.18088617108, -11772.8051706811, -3154.60485275802, 13290.3912647336, 5431.04189245681, -8481.81265727786, 1670.00361536791, 10196.1964054635, 440.107397814174, 21149.0647746890, 2059.80356119691, 16030.3071570796, -2645.36901373849, 1908.90716678441, -3960.10270047042, -6158.90075289659, -60.7420612824971, -1918.15898269145, 12431.8864487976, -11688.2187978121, 3719.50615140241, -2185.66367538792, -11884.15621548 [...]
+9771.88584586733, 9286.03197290702, -2187.82453156443, 2424.81719375148, -6877.33595812952, 5096.02652491647, 552.317632962544, -6030.92832073761, 7351.30738921762, 14055.6042795115, -597.818211503469, 6046.62340290092, -5850.53197721093, -3477.99843804662, -453.074834409006, -3997.3903044152, 2301.50532070822, 12195.8055671055, -3016.19264374203, -6379.58895965012, -19292.4175862141, -8466.25643558187, -16797.1382438041, 22546.1365297558, 3370.27946879191, -9576.2531763784, -17754.63081 [...]
+-10069.2059789463, 301.386612753376, -34954.5896712522, 807.38762021397, 4971.64344385697, 13056.9503956977, 15995.4658718051, 5914.79191849127, -2643.67272967988, -568.856775329229, 11004.9236976826, 12793.8331038297, -21472.7382669887, -1806.49553411537, 1455.51020134194, 7076.99678680155, -13521.1188938813, 3254.81455906819, -4253.50382920539, -12028.4050421359, 28007.2683389741, 10756.7371290034, 27604.090309097, -16012.9094499587, 9089.71221439568, -6534.19525455089, -7928.635315879 [...]
+-3904.07942373386, 8652.8741863041, -8258.50882237451, -20604.9950279008, 8732.52114513826, 6426.44864330513, 21912.8171016107, 21900.9461816305, 11150.2764359910, 265.921436715738, -1990.75439947974, -4806.64723355356, 12316.5143516940, 28990.5948512443, -23919.9337574354, 1384.62298480509, -575.50903366789, 20237.8260155231, 12531.1472594404, 809.504035690498, 5746.09282568375, 23070.2142602366, -9913.7829554526, 3957.34016505114, 3723.51100216161, -4050.90607883887, 16485.5490746343,  [...]
+8418.21804225873, -10368.4350002557, -11254.5782064452, -10710.2870967360, 5930.36735929855, -6321.96634928607, 8490.4496691227, 1280.32819144245, 1316.23967330887, -6607.162460637, 11595.8398872062, -10596.7637605621, 14366.0871403337, 3345.5320038218, -2870.74660092077, -1823.76343681718, 2538.20185326485, 11305.2659615544, -15693.1278913122, 7155.89771629726, -7342.42315254194, 13961.1262252546, -13999.2295899293, 16673.3606357407, 3298.7488639834, 2148.84608281381, -2650.06379470172, [...]
+21454.7936522427, 20785.6569278385, -10099.4030143552, -9180.54207464842, 6733.24851637874, -691.729466751101, 8731.99825243759, -9024.4306460385, 3038.97349162314, -3156.11391128162, -5720.79891494759, -28095.8826028346, 4436.52465481308, -1953.12082059300, -920.663753847148, -15825.048385367, -10080.7391342517, -461.795054154195, 3634.74339350254, 9093.6684044947, 14091.4481201032, 5485.79690344376, -3823.86508483395, -7211.43942085054, 13098.9441905698, -3870.85877811987, 10960.811649 [...]
+-3917.5863839467, 7843.04614456168, -9139.87949724772, 1069.85835221553, 8701.73652027748, -5444.2010275244, -9817.79324751833, 6821.75982745104, -1601.31912163358, -3091.15707194547, 18355.1247005745, 4594.32990250475, 987.334997292204, -11959.1374102455, 9390.93713997927, 9138.29675483534, -6744.69487064268, 13562.3535249935, -3017.73916245908, -6331.8278747754, -2755.11071740156, 4211.34995745869, -9841.68766384414, 1866.17187426157, 3895.39747983615, 10141.2537594049, -294.7610002373 [...]
+2877.51514792078, 12593.9195330701, 1554.24559978594, -4320.78512436644, -17450.9413097521, 3649.57336249734, 3500.23677405955, -1653.22205816413, -2045.20364674897, -17797.2721476115, 7445.24463261399, -2437.72154787268, 9319.40886478483, 301.8441548442, -4817.70340058741, 6614.7857875752, 4319.23346654254, 10470.0082461002, 7400.89635935028, 7948.71061737132, 3261.99057181609, -3909.12064349884, 21426.9367410136, -11825.7797002494, -17923.5131679566, -1621.24326009166, 1389.28382798488 [...]
+-10055.7897584851, -7686.4146280999, -14936.0908128713, 16744.5640544338, 155.952263355087, 8902.84211745211, -10837.5391193704, -4565.18433131186, -2935.89123284998, 3200.18752901867, -8497.237676158, -3881.76962751205, 25748.2891601355, 8840.23028672647, 12147.7807744245, 15514.6145917953, 5158.47302382121, 1813.59860368161, -204.742704918474, -621.362977783496, 4847.49380412401, 5361.6862287225, 16228.4236308609, 7122.91704429877, -1901.12392778880, 2718.29757583906, 795.865406404306, [...]
+2372.04854497014, -16470.6066679903, 1956.83154685602, 6454.39920012491, 19479.0923352714, -15319.1691908751, 21775.4503873950, -4282.96366707651, -3715.33477142599, 11586.2453196718, 8850.35912213074, 13779.9580647629, -11560.3269432809, 1774.93983233405, 7752.80909548296, 4069.24245772124, 1249.48938953937, 1033.46652524876, 7018.59778602250, 6947.34774436135, 333.798938092502, -18370.0140651060, 633.56004756906, 9336.4490165216, 4487.88510852877, 6573.0034336825, -2648.99894914637, 22 [...]
+-2938.63365903864, -8781.5988873102, 276.633245519496, 7183.8868107644, 15716.7061220358, 10988.565179458, -12819.0402227833, -1585.44570449588, -7146.32270019909, 12639.8366129296, 17536.5479210150, 1330.52593178694, -8680.61979758047, 10204.7045853233, -5676.7039497011, -5101.57443122134, -8509.28080137483, -9746.3020167854, 8984.1687497405, 2307.7184067385, -1627.91009558963, 9043.41198110376, -7557.94464898764, -5987.06317633685, 13917.8529490979, -6464.00337726357, 27259.0946081802, [...]
+16056.1635126023, -2248.24073397517, 7045.98127248997, 209.448858520636, 9678.70087767337, -10049.0352355776, -944.177898188802, 9707.8792183105, -9571.08602068524, 10313.7492977556, 5777.64140876095, 11106.9729517157, 4142.62449978068, 828.730091712075, 10360.3030258868, -223.585089533165, -9795.17271523132, -11839.3424322677, 7745.59246707185, -2606.01420754604, 11882.7764141493, 18679.0390061084, -3216.96543271528, 3750.60469778413, -12051.5089948274, 543.985072020545, 14559.674558738 [...]
+2988.87024112363, -7116.69168491516, -26957.8429125979, -458.60616106683, -4186.38155003555, -1620.87691813109, 6147.34170041965, -13730.9132899838, -2018.76319002855, -5308.65011235276, 2575.39027375496, 9137.31092221083, -8821.72926055862, -17910.0777246777, 7700.93822139277, 12432.2356837751, -379.820273729768, -804.11067316022, -800.79615084272, -17868.6801911296, 8183.02612814045, -908.980822150842, -12627.7945866486, -8797.48017931434, 11257.1318914754, -6090.57124295557, 6727.9953 [...]
+19451.5127322634, 6894.04799386543, -2082.4275540677, -7914.32749573652, -9944.23899958232, 2003.62585510313, -10199.2841252666, 13271.3710736045, -9337.91135254478, 1159.79315690368, 11021.4784221818, -2073.02726668726, 2751.14562759201, -8180.60793791949, -6626.12988754885, 12213.1968030724, 2512.10447741053, -3191.68413773633, 12707.0962893093, 1316.63277328273, 14010.6532935114, -276.779293083664, -8241.41092836957, -9476.57141614781, 3631.11860494632, -7924.45550056039, -11248.37720 [...]
+3379.39817784899, -4969.35754045776, -8326.74371084275, 4610.0596850894, 9555.66853222798, 10919.7071970135, 24174.0366421604, 10930.4134992298, 7027.54523330656, -3159.98765524728, 1448.64894363877, 7282.82914036594, -1877.94179401102, -4516.33433421064, -14734.1349808955, -20827.0156017956, 7790.15126684602, -4823.28201010496, -11101.5388605123, 5116.18897836916, 5748.86271580356, 3847.12040880750, -2113.53004372681, -15101.8958765502, 3012.00357205179, -13922.2270899464, -14915.932136 [...]
+7437.04049022023, -1093.27077644614, -11579.0142771098, 10619.8613396527, 8961.55972716045, -13997.4013753634, -2779.07648989595, 3837.66891173972, -15721.3065532363, 16776.9872680179, -1005.16129318055, -2061.67318762239, 12659.7213587072, -2150.51468912177, 14263.0641426409, 15607.1955514796, -11555.7407081852, 5219.95015083993, 3478.8368165754, -9355.01121584221, 12001.2254713471, 10903.9162225344, 17637.2579982372, -6473.51596735273, -5397.62585500489, -4248.58441428316, 11192.684380 [...]
+10134.2315335525, 4780.19376143495, 4431.14329179547, 3484.9021626536, 14491.5772860089, 19150.7835953709, -26296.9071440465, -2524.76644824904, -3039.36122398278, 12826.3757539781, -15923.3824913259, -12573.5928220330, 87.3309447580241, -18.0820416544169, 11996.3206973043, -4161.08661789272, -9473.15004012553, 5150.11694276108, 10772.2796441312, -6555.45429098726, -5938.68379204974, -6954.53373515199, 10913.2473356182, -676.993104495305, 26249.1025360922, 11318.8321484198, 5186.83716625 [...]
+-866.203811386139, 3361.87613210585, 7180.63428827448, -9438.33063527773, -2391.49770764552, 11906.3701557733, 10125.8984278477, -2498.60998138146, -8214.18392353417, 15383.0726440874, -11222.9668313922, 19486.5041026556, 5743.2367637507, -16385.3475370755, -10425.1438222009, 5248.72031281046, 616.489430191878, -997.545529982913, -5159.90619284051, 1039.82526510795, -20998.9844323, -10503.2431359578, 1009.34860552513, -1535.82294514417, 16360.4470575376, -10459.2179496471, -14040.1350840 [...]
+14095.0619112323, 253.961984000068, 24925.3122242193, 10782.8192881722, -11506.6603577056, -8932.46706223232, 3372.62324394064, 12438.7068780557, -7559.47808521244, 7231.53405621025, 2906.72822793127, -19596.5857866073, 7424.81967298277, 9504.85422107678, 6604.86542721916, 1968.95990521584, 5835.44783979496, 15417.1246736777, 32.6880205956889, -19402.3777256053, 802.390965675175, 10538.0479627278, -7232.63495507945, 9580.86149239978, -3486.78081916518, -5018.07674308296, -1351.0590775620 [...]
+-9409.022444368, -1976.25721193536, 18703.4637563273, -1838.78709041467, 8313.7711277129, 2091.29372694980, 2840.73938381406, -8982.28850167702, 2226.47195044806, -5671.24870136134, 14146.4530729395, 5035.39431122904, 12342.6955959325, 1873.69278935454, -9605.38623258041, -6672.67967846336, -4751.90763624025, 4415.57344152756, 2990.64741473162, 3912.538199267, -13686.3065830452, -5152.87875960623, 11238.5786461838, 9912.97430567048, -12288.9861652076, 3982.55921542976, -16681.7339793900, [...]
+4219.15846193908, -2164.72781259945, 2333.33610353471, -1969.61884065392, 5280.75216247442, -1409.37684285359, 1161.97931905394, -6128.75153262444, 6000.47282890826, -9368.28759927633, 13766.2407329111, -3462.67779092855, 7873.15186940069, -5702.76824026557, -2074.08086003311, -6400.75765967194, -3460.82464186769, -5321.61788874168, -9393.46055514238, 849.894455682846, -12510.8428586559, 6106.0051774081, -8481.59343471012, -5661.15437115212, -1150.30522678560, 14821.3339579621, 2498.6562 [...]
+9629.82430010348, -3413.06124549144, -3900.42221730845, -233.758433702750, -1920.36826458710, -4152.49116497539, 3559.66777597103, -9324.04635439901, 11787.9654184254, -6539.16047188779, -5145.12539662753, 14461.0999379900, 14603.9758720134, 17448.7072619620, -22867.0015270217, -5520.53114938229, -13992.3861172460, 12460.1337730863, 4463.92525707162, 5817.78588155639, -1701.32269474623, -14245.1254084701, 9619.58044667973, 15821.7067001151, 10079.7141945005, -1948.13424459729, -2692.3754 [...]
+-7572.03332637205, 8653.91473391137, 9227.44493997604, 17431.3271059441, -2416.8321025247, -1502.43146472893, -2040.03574745676, 12482.0778868348, -12781.6380249684, 9420.53119314646, -880.500871899352, -6918.08919772604, 5524.62506716336, -12724.4183310759, -7649.42459755924, -1656.53584742166, -11802.0756661207, -3580.87886986316, -6225.61529313421, -6075.40886024049, -2166.21233679431, 1364.11096364126, 2980.97977191951, -6794.99934232727, 6585.932173997, -1216.22289024042, -3457.9914 [...]
+8961.28682859116, -5983.81770401536, -989.752337859401, 20448.3437919248, 2702.63548583711, 7047.54824997788, 1490.90359103624, 9126.93725960195, 14347.7494943450, 13673.6218261407, -1691.16371519793, -8777.25801981263, -11279.6244979148, -5186.89160735091, -969.12714608803, -846.313878397238, 2985.25737363788, -18135.9741438458, -5727.1550209284, -11164.0273591252, 6720.61690673988, -7238.6349899516, 4793.67930343892, 10378.3691322435, 12373.8253061583, -13694.4974045599, 12290.34091225 [...]
+-7956.03190738818, 7548.53030228856, -11237.3053336604, 3786.59233427118, -4132.49789864084, -9280.1350055257, -16265.1131810504, -2418.85344328921, -6422.15134788163, -10019.6287209303, -7688.49421787479, -8903.3486646519, -10011.4809561677, -4240.87975823159, -11546.6065024296, 21271.4142746236, 2805.70050590397, -5436.4796708823, -12523.5717762121, 13319.5780179519, 4700.71305412202, 6384.43053991547, -15511.6796618228, -5236.13293923625, -1838.87207470016, -7358.80673857023, -1952.59 [...]
+4389.82838557675, 4802.3847320514, 3288.63804508181, 9701.24456699527, -3455.0560987482, 11587.8661460405, -8735.87015672351, 5339.08475416595, 2597.60547708583, 2384.81342277023, 17520.4439618955, -13253.2159095174, 1794.68920641432, 8429.37645922248, -4882.93320063237, -4899.15454885756, 7467.34544571338, -2813.59709577415, 10428.8882966593, 10025.2415917047, -4433.30619749371, -1842.59958514779, -15846.1465863456, 8888.45772278264, -2530.80461281384, -5360.28134062754, 9653.9684637510 [...]
+-2905.67804354979, 9326.13803460467, 2252.96884754588, -3831.94137350649, 4508.37680897326, -10002.2156683925, -9060.2343936963, -1084.14815544092, -7134.38852694368, 15233.9047676548, -2729.88541710245, -2387.98679364825, -18076.0783729529, -780.704514371902, -2272.28019006279, 9668.01311087194, 12050.3873071001, 4832.8211858025, -5007.46631237692, -25360.1839218393, 8606.17625109465, -1689.171571021, -18026.4190508141, 13729.6932552922, -15888.9313134966, 4258.74806617452, -2548.343448 [...]
+-5133.64282862798, -163.719483519123, 6235.7157609372, -5070.54021804521, -3188.16745060335, -4947.11626563926, -7395.999578687, -12382.2317139725, 5862.51199273438, -6774.83920889631, 22444.8180507183, 8017.78952443926, -12710.6117748084, 1158.74223719046, -7790.38199122767, -4274.69520445988, -4096.25473707636, -3342.46309868389, -782.357304864733, 1512.88351873857, 2882.42815370182, -885.50650030384, 3736.44912785591, 13724.7747140453, 9104.8099621597, -16806.5217807366, 16968.1141861 [...]
+-3989.40123173722, -18537.5662799481, -8717.57616669514, -19564.5949708220, 2842.24094829520, 714.605003802216, 15314.5250269628, 24131.0017113683, 11018.9299287603, 5888.16057712456, -7091.15448653664, 4283.91074222162, 4546.53765421889, 16971.6327969546, 12624.3016851336, -3605.36972577048, 11585.3413042611, -9272.77812517114, 11021.0947547791, 618.485838302798, 1143.15619873639, -8947.16828264884, -1235.81138534910, -754.205938988973, 9148.07057331403, 941.632432815092, -2716.02953438 [...]
+12698.598223898, 4824.12322257651, -1418.52832203472, -1676.12569419520, -6308.13497409789, 14927.3043799455, -13341.1192871152, 12164.9817455770, -5980.59002602856, -10547.272392048, -7140.3188697396, -16665.2678814081, -344.42186423163, 3184.45677130097, -21034.5174203694, 1302.05163906914, 3851.08674618622, -1801.12302227019, 11190.6761756342, -7675.02156707789, 14207.3886141335, -11558.3978751224, -2497.96946642127, 85.880047484674, 20488.6492892018, 1292.55020504623, 7865.1500457547 [...]
+17696.0084874192, -14466.5551142931, 15012.0137372473, -5259.49918069927, -3172.92752245789, -3933.48850534298, -16211.3602570629, -824.751013754979, -3775.09359800258, 6304.85809930561, -9595.98392211654, 5557.49429118206, -3695.83740829859, 5104.06196008509, 6038.1966597403, 3959.52597752848, 557.94131456263, 7183.50021704622, -6165.72143589337, 1237.51159169266, 4357.18053178149, 10835.5191361294, -3770.62051041811, 5483.3474633482, 3458.62585875108, -9513.82576685376, -8716.185033108 [...]
+17513.5596979072, 4561.39611246206, -109.649756359668, 3698.00857710652, 567.886179249834, -9359.8742023145, 14218.8523986663, 2619.29881201951, -6447.84417963876, -1451.34764925568, -13133.9531881471, 2933.02767811755, 7013.94387757725, 13638.2115223216, 18110.7091192703, 320.295014607949, 16507.4357970566, -5358.33613743169, -9017.52276262102, 257.565186773208, 4121.69204309532, 2735.67357245969, -3606.01849432881, 1107.93994974064, 11537.6209216445, 8763.54452953312, -8677.20622643813 [...]
+-22574.5962343155, -4336.05323217874, 6948.26774965781, 8392.02025573505, -10459.5016560958, -5144.81410537949, 10558.1741936192, 3641.26093473596, -15689.3478932836, -11347.9043994900, -8684.56631007005, 1365.03167417111, 22689.8058550947, 18082.2888067351, -2481.48782835972, -11487.4592637429, 9816.52466613727, 17963.1554908135, 13165.7465949147, 2204.98262286412, -4526.94431820387, 21298.7136922876, 2996.79680776436, 7450.95763581684, 2315.28725507747, 241.914017524301, 17649.13878528 [...]
+16548.8453082413, -6336.67573727098, -6743.52224254342, 8533.80365450262, -9626.2669192816, -527.244712460308, 6608.40861072748, 14017.6139066184, 8130.24454578231, 14093.5285110365, -25712.4664823626, 3439.34011557986, 20188.6138647807, 10383.8037481297, 687.982028346944, 2875.95863841907, -4519.60473497445, -1343.37841768272, -7527.93222145741, 4114.08319957963, 2319.16348394623, 6687.3600434902, 13440.7840570214, 3406.31392036055, -331.299651600719, -21056.0348126449, -12802.522222389 [...]
+2735.07230011679, 6032.33166298734, -5198.93658177951, 5938.69344320251, 4030.26340769996, -2901.91303034600, -11099.6520396960, 1443.80418181353, -13758.8687749580, 8576.37923091632, 1415.36521687756, 11040.2288640543, 872.881024703941, 1810.63039476970, 19306.860718943, 8341.39010017183, 3660.60677585052, -37.0250021183099, -14707.5353517661, -3829.97830594562, -13768.36270722, 9133.29528915883, -9597.46431505655, 529.862985013084, -10603.2038565038, -8496.74612763182, 21099.7620092148 [...]
+-3406.42412124595, 32.5849293156646, -6184.07263101853, -10252.0746392741, -249.360037829524, 1685.39268835026, 15298.2695532821, 7803.64669937405, 19244.8226992501, -14666.4402912831, 11489.6554668932, -11812.6949662168, -8633.89288119586, 12475.6521120740, 2033.04509739349, -11260.0686983374, 1600.53393163318, 12426.6094313525, 8545.17646305638, 6750.5428302956, -3147.75959487325, -8374.94113718382, -392.570270022391, -291.576770537284, -1627.33380660914, -15906.2031943093, 1158.715845 [...]
+24251.4080435174, 864.005753223559, 12488.6692205174, 1544.33815206155, 13493.925247181, -15385.4368162430, 9753.55252905616, -7051.63664322823, -9682.84250037758, -1021.56259966581, 1986.05040673803, -18383.9775422578, -10619.2750916737, 2714.89434203402, 2761.52082635148, 20513.7621282739, -2605.95176667471, -3262.75099308952, -6344.21917366274, -6146.15418838999, 13993.9584517780, 1378.10315937051, -5617.7507607028, 10644.9861248361, 5177.05120231841, 3117.07225128685, -731.6461212463 [...]
+-5616.57607005445, 2962.09002611579, 16721.2950610965, -5942.49793175146, -7771.26088011573, 2753.84519110999, 2077.4571557169, -203.545156090249, 24510.5782860325, -8248.98626884043, -8751.74925163663, -3463.36306548615, 14420.2424632953, 7700.04759810622, 13368.4874971635, 3793.86986564605, -15762.6003969883, 10121.024777518, -3797.75595014285, -3819.00250254031, 817.7791484853, 9089.69975445233, 21731.7734223997, 1487.7592266369, -13511.2753848688, 3712.40130690509, 17274.9817181974,  [...]
+150.890237369702, -18581.8850565517, 4128.34689735951, -9762.78559145493, -16426.7407445834, 1070.87526751707, -124.029622718288, 9639.88819872073, -17118.8915083873, 1066.79277826187, 556.46086227373, -3212.83821006404, 1045.34426563444, -11799.9975155515, -10473.5890805015, 5431.42293322374, 21615.9271300843, 9601.98317238446, 17231.9968829261, 5766.48835944666, -8601.71698190236, -6349.0065067075, 6685.40560990506, 10711.1945263336, -2241.79573277122, -10605.8429083181, -9974.79212492 [...]
+-12325.2243029756, -16739.5832628577, -9132.95241925506, -17529.6760612182, -14274.5644105758, 11028.7380047482, 12586.3231936097, -11010.0685033821, 4345.94013388659, 1969.51758508925, 1767.04210069963, 7322.50614270313, 4534.09100183648, 3653.15419076119, 2227.86334701087, 4338.45741010862, 7841.74944277544, -13224.5873036625, 1690.1337006547, -9617.99965669876, -10266.1988164460, -9562.85095268387, -14986.6835355311, 6988.00088696342, 2042.59371938147, 11129.6825854189, -6945.66650124 [...]
+-8237.4441255871, 5043.99820445746, -159.987021285183, -12049.8005140029, -2968.54271833005, -6564.73760906383, 3315.17603464266, 6716.66868822095, 20580.3140506811, -2859.51879860716, -8041.87850620498, 8337.24320515073, -6919.5787239798, -2191.89856124130, 2280.55776039617, 10209.8126219705, 12800.8301221555, -529.770229742053, 49.9893961171719, -10521.3965307656, 2818.99332269518, -1271.37195941907, -2823.10918552077, 4218.78130278065, 9376.6470043118, 8949.52563612163, 1762.902671501 [...]
+4408.80938071573, 12857.9202734358, 13323.3291458459, -6142.99387582404, 1352.49194823780, 10113.1283766867, -13198.5460387800, 5408.3929147589, -12685.6606238645, 6345.93699363864, 15153.5760454470, 9694.66252481762, 3827.67859890875, -4633.02977829871, 12877.7941838887, 12141.4039704517, 2990.20461180809, 18658.3720646040, -9433.83203011168, 4896.46502534849, -8192.70096964336, -8122.06684385589, 1637.70126087389, -12684.4833946854, 14338.9781522486, 3805.56125669659, 10000.6139044671, [...]
+-18909.3765709720, -9177.98141386066, -11931.7662054294, -3226.77413771853, 11182.9050310233, 6908.34480020061, 7982.59707015866, -970.578118484238, 6169.87225096739, -4276.06875077581, 5678.68306342598, -8676.8735928244, 7578.28515686656, -1930.42099587316, 2027.49675158100, 2271.12462219816, 9740.63439359005, -11063.5796046845, -4807.02941036491, -6688.33098041736, -4705.70735216284, 5012.42238191569, -21230.5714747499, 9675.0912283074, -23580.2256193035, -4205.72588282377, -2168.05220 [...]
+-3494.04234438437, 12713.5467076059, -3981.11879685007, 9736.44953222091, -4152.83060966196, -1857.56733178975, -8185.13845942615, 10182.8659263439, 1980.13310795802, -15422.9343604382, 3420.04516833866, -2064.08981350548, 11270.6338519312, 7084.63441094949, 5812.25507215939, 23339.1675494892, 6839.55379003755, -5664.10367396216, 12580.8852925103, 18616.473955091, -227.607749529353, 5682.56652384097, 11332.8757859493, -6780.14364293494, -9565.22744286997, 710.044259451685, -577.749000703 [...]
+-263.334685749672, -9058.60320573829, 1376.20484359357, -5788.03557827914, -6397.07489074011, -6126.21980503471, 12301.1205681324, -3681.93921751724, 22.2086307614247, 6623.93757414929, 7466.7065084958, -4533.29058996945, 6346.93918498392, 22671.672710231, -23326.6552148679, 5562.05841186903, -1374.31340664848, 543.738303116193, 3854.74801470479, -14913.1970271318, 3039.56275715272, -8451.89775693653, 3899.33881407645, 18935.4559023428, -2705.56970355955, 21083.6502243532, -19161.6542348 [...]
+-8809.72081664667, -11143.3276723686, -1044.04100905834, -13170.7981370723, -13199.4993767207, -7240.95793155048, -7943.82118318523, -22136.3318107195, 4062.63116119255, -1339.52000564621, 7065.32668953251, 365.291257518291, -3292.98288774505, -14967.2123491975, -1229.94531668337, 10652.3983590575, 3530.35868465625, 7538.96354939715, 2643.80301474587, 811.51126232125, -18094.9005981129, 14159.2575570016, -9667.65952963135, -15678.8646118393, -3301.6185525711, -15702.5213216075, 7047.8542 [...]
+-4632.32866201082, -9347.72194493129, 3498.40762647744, -11807.6966845699, -22134.5414794404, 6288.29816946763, -9424.51244420246, -6529.69623200576, -17672.6264714199, 7593.12358569385, 9862.4632200485, -3537.36125177691, 6356.22010847739, 570.373276318709, -5217.11346317544, -11840.5922734233, -2350.00702208518, 8028.52454338627, -5197.0160196949, 18225.8768977629, -7580.60422176552, -4660.19789391, -8230.02967937897, 701.83048581247, 1335.96328592534, 9798.46115311363, 3774.0884787790 [...]
+393.121165927477, 3008.28497368697, 5137.33738362637, -3195.16917667534, -12147.4224001850, -16723.6498489469, 6374.08772793945, 5304.47357747026, -6746.1613296988, -11578.5221047756, 2093.53325882686, 9097.2696680261, -8703.58411218009, -4735.09217944241, -20.5919973861466, 9328.1180067957, -2285.36402272017, -472.687964234225, 7725.45210956025, -13762.0293483832, -4730.43919813698, -14530.9119843367, -14568.4863618349, -13252.5609028587, 13092.5395477754, 4532.67741302674, 6956.8838749 [...]
+1074.75827647062, -2720.92393941046, -2723.01760675558, 17.0424905985961, 3366.11551627436, 10043.9457509403, 5944.45094157816, 1218.56298238693, 9177.99506944504, -4219.25446597741, 2185.17816846564, 12383.7359855997, -12481.5261549367, -5772.83778101938, -2119.82787868073, -13883.3768447605, 6093.1995498204, 4395.79304416298, -11688.5769063096, -6111.99632120435, 22574.8276592079, -14532.0339480976, 3645.70512455156, -2016.45740665007, 13901.9510768599, -6572.16110467819, -4010.1413003 [...]
+-14571.9779433380, -7534.02637692702, 5491.6858803302, 10416.6848108655, 5755.12099805928, 19780.525956094, -10464.2414987443, 12821.9969349204, -11.0691955011543, 3576.57517884969, 3703.59470095541, 13344.2304657970, -7326.78650504705, -7679.80778500485, -4795.50118559746, 12365.2892696652, -6688.42386235193, 30041.2153512799, -2766.05894064739, -959.055335481475, 1267.33615256896, -6416.01525027559, -2907.01888653112, 16457.3138091917, -23886.4842921892, 4395.95225207226, -4623.0925106 [...]
+-4701.622962059, -13151.3975267064, 1283.10617101074, -3876.13882203445, -3733.51545923322, -15001.1589430719, 5157.06257476291, -3443.98810476754, -2304.84774334130, 6338.16146243093, 9556.44687023447, -3740.64024012569, -10560.4991287279, 11889.1408192537, 4790.2199098899, 2880.08552792184, 5362.55818676102, 2574.89264494249, 18885.3090885330, -19649.6267572696, 13464.7628944951, 14173.5566947665, 5961.32040757151, 14068.3271379194, -12946.2645998368, 12053.4494476613, -2476.0702492107 [...]
+6081.1596447436, -3013.40160216537, 9747.4545879996, 9328.86312056355, 3174.21875621798, 5797.80237675382, 4241.04491968171, 227.411932249348, 7968.38520388865, 11123.7690594575, 9709.16653637119, -10263.3524732725, 15049.1515323009, -5402.20686892802, -13221.4144231873, 11883.0915355580, -9596.78677091973, 13048.7729708026, 10930.9224211422, -9036.87449408012, -20235.1729245942, -8313.31116401826, 9474.92710373633, -2182.04496711928, 15669.3236111777, -26025.3280267448, 17956.8868041952 [...]
+-12697.4909214183, 11373.6602717986, 15304.2757885963, 18028.6717834053, -7608.68998698382, 2598.28627708207, -4403.61455879139, 9727.0862152567, 157.192959242496, 1113.46302039128, 7112.1830608542, 2292.71698135828, 2758.96905497467, -17325.4146143709, -1395.19701541633, 14521.4212521746, -8055.95351889727, -9271.27756838354, -19783.7152965398, -16257.3493975979, -12247.8034396810, 9680.18958222103, 1838.31269806073, -4195.22409904596, 4907.2458389342, -196.299016524385, 9928.3649174348 [...]
+4398.68876780578, -5469.22937578445, 5683.16911167911, -4397.70136119325, 7048.3883010574, 12860.0209465345, -8666.42516709954, -8929.23755370856, -2492.88698837315, -10776.1981895730, -3028.16744142927, -340.635891735201, 10719.3763092466, -3997.75020646446, 2019.42717634637, 14191.4025797665, 889.575075158737, -630.897442683087, 19361.0275292363, -15783.806754329, -2368.89098709159, 9237.13851362177, 1927.76569323948, 10336.3975964851, 16635.1305428664, -18482.2996723832, 7440.37508184 [...]
+-6422.12622211442, -1804.62392085795, 14133.6878088311, -4665.29898405624, -11943.1521073738, 6522.68980601259, -204.129067032893, 4837.11882022793, -2665.47733299602, -2500.27337800661, 15304.9586173983, 14341.4060352808, -2808.03544800521, -11434.7172390184, -10073.3041191449, 11246.9062272519, 16716.502749914, -23648.099678056, 1143.06325890941, 2291.59233532907, 7292.50471130268, -3398.27227213672, 1618.46623612370, 648.135524861123, -76.1713942480302, 307.285576559509, 13369.8272336 [...]
+-1706.96830394205, 19267.5321842898, 1214.81873930835, 8227.94230334938, 17128.4643707938, -2882.21329652531, 5278.94400250907, 5871.86839460806, -6074.73659363054, 8566.65262652954, 2697.64395954454, 4726.72894146741, -3091.02204350344, 10395.1764599673, 15667.3644266537, -1710.34008600062, -21178.2512625479, 9698.66447971267, -11341.9907341698, -5965.10879716482, 6480.45981061882, 16533.9530964496, 11479.7518952944, -9963.28083869032, 3417.43260324289, -5356.27068228249, 7117.291006463 [...]
+-130.353236720249, -1886.11449582653, 6475.18456932585, 3372.22621417427, -9126.23758487704, -19588.5928187986, -2266.44000988985, 7527.91982097985, -6661.71002404392, -32967.0454241942, 12136.8880732727, 2436.58086836989, -854.712739269061, 8132.5801635806, -7034.89416993864, 9834.3631188363, 4291.18762081321, 23404.9454203223, 16783.2841814771, 2348.82672781735, -20156.6195084287, -15534.0427723275, -4507.03107217462, -5478.98828991136, -11989.2666927461, -1979.41530698889, 10329.28295 [...]
+11391.3685350554, 9478.70896601249, -973.769421690026, 4805.22129518411, -1610.79850976261, -14417.5897286307, 3577.47203428785, -9330.18486103112, 4382.59105969050, -11555.7745476512, 14789.4174585077, -3036.2508238717, 15623.9859896645, 23609.6179276462, -21182.5439011940, -1119.81610241935, -3998.38440310842, 4896.49001372628, 13685.2257659837, -15513.5133863473, -5841.54447606876, 18138.9032918805, -25864.7842460844, 1560.96954733029, -8855.49285187702, 12408.2571115470, -16608.94253 [...]
+-9438.94894033582, -1060.7549368109, -1851.7120125243, -28508.5193986197, -13361.1718304897, -8276.6891470734, 13474.4421148781, -18437.1831026966, -5235.81886193892, -10806.0442275446, -9811.1445476419, 2237.68765394152, 8923.75350948745, 15269.7546284911, 9547.847275969, -6999.39946458845, 9123.03707012553, -5662.14741076465, -724.61292843431, 3563.17548248937, -14863.1625564397, 7674.08902455305, 17598.8907888651, -4464.0339458706, 667.540381801158, -8816.66169742873, 16527.3894077065 [...]
+7742.25560468884, 7383.2475450937, 6276.07347211091, -4914.54829827997, 15678.3277208477, -3161.23505123586, 3284.00756158020, -1807.61911600062, -5422.0117174405, -132.008786037379, -557.966556878101, -6277.67877560195, -3961.91205033905, -6215.8705464239, 2320.71919017975, -1066.87790495342, -46.1332786798307, -7893.07050903027, 3496.80834411311, 5053.49384789034, 12306.2445080443, -2209.92968003065, 7646.67099852437, -4175.12613312591, 2818.96421174593, -2751.64863910827, -6781.349929 [...]
+-23310.3628772942, -11129.2453727411, -5142.79544079978, 72.8186245150859, 3243.83808545221, -8579.34356684334, 1458.98097121530, -3985.79841356638, -9532.54537231324, 8240.1003268036, 216.275393273686, 4246.35191514642, 3345.80613477687, -17521.6246638025, 924.663046611991, 16872.3060823493, -8191.52219070745, 11613.6174327593, 25399.4725163012, -3215.03162193284, 10913.9934994871, -6634.65318943403, 7269.9040392357, 14195.3666334284, -1066.27568536934, 182.336010368007, -7831.091560720 [...]
+-19711.5315038499, 5736.88712665837, -9188.18024271568, -8394.62238551787, 9428.84040482599, 141.038712879043, 1946.87509964046, -12721.3794558829, -7242.14091646052, 5318.98821945541, 1517.81438729282, 396.890424451562, -5795.6022640407, 1717.95660519651, 2286.36840111800, -992.928062603114, -10286.4983128473, 1982.08631777723, 21213.0431754637, -5546.3667848054, 12897.6522645054, 16939.2179204092, 1805.35761432942, -22261.2894698372, -13978.9584249299, 23.1304694687083, 7615.9377812938 [...]
+5264.57838805882, 7743.71047340444, -7302.71704036285, -13756.6686927819, 2263.0683621902, -719.302342347699, -2464.42652669558, 13760.1735327218, 2704.61912934300, -5484.81780154758, 8816.44355018442, 587.974916261113, -9899.99947256402, -10219.5297580181, -8458.49536258033, -2893.36602415202, 3790.37026668229, -10363.4859339269, -6646.23853862054, 8525.90111984176, 905.700805785874, -5832.52758854512, 12843.9981578544, 20516.8840339982, 18952.9487613886, -10.7655970831381, -12703.93566 [...]
+
+double yy1[100] = {
+58013524.9935325, 80574348.3926748, -29503767.1012542, 24210223.4821499, 3431577.64118068, -38652734.082556, 42878071.9574764, -71175155.4499453, 53568036.1357632, 103184208.336666, -23644802.9219393, 8055534.68288158, -5601889.00061195, 109257764.837792, -62326779.8249833, -52281772.2729535, -174284271.288372, 67652817.9657768, -11096241.7598387, 62178279.4956061, 85627066.0295197, -162953356.395025, 6062630.72379463, -8571934.75244369, -44265323.2443962, -84597967.5653845, -36834699.77 [...]
+
+double lars1[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 38.23740324743330600, 43.10537614002905100, 69.87845270767906000, 80.17097332676398500, 93.24532081516629500, 101.86021756666102000, 103.86551922079182000, 134.14706417487375000, 165.842862810832860 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 12.77390603082450800, 28.40525457939803300, 37.98205596755769900, 40.75683976124865600, 79.57435563940001100, 138.76506616059424000, 15 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -90.04830212005545300, -127.03739399278913000, -131.38808982480180000, -154.02529135943018000, -165.23517454337318000, -178.86325883224873000, -187.65660628004426000, -189.76111104411402000, -220.51564596763188000, -263 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -33.68558078818011800, -330.61395149424897000, -388.40048442225230000, -465.89122627891169000, -502.27645679748122000, -528.94218847853620000, -777.69186462367645000, -824.53704512417119000, -886.02261892135380000, -908.83538518178841000, -912.00197497809222000, -926.28501429350956000, -933.33887156257470000, -943.06207195804905000, -949.58879358750710000, -951.88716297717235000, -984 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 69.54981373838141700, 172.81455449060053000, 208.84596563059421000, 214.33202382610537000, 239.81782971204473000, 250.09474030353178000, 264.13103161019257000, 272.46353345156075000, 274.92314042082177000, 307.44589608692490000, 354.3883303 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -201.01830046555924000, -505.66573342661439000, -525.31388992661221000, -671.43061386684803000, -691.02550497367565000, -724.09024998436098000, -736.01007049544489000, -745.80126488012365000, -850.31879516875688000, -869.86809748453231000, -904.52870499568655000, -920.61403854157868000, -923.12884646090231000, -935.67103531391240000, -940.48665969832336000, -947.57679326453297000, -951.40747479277218000, -952.5358273063876600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -10.47267359991118400, -15.20852776934026300, -16.22034978051193800, -29.73983224383573500, -51.29963218123113900, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 22.87555446674134500, 34.29352336385176900, 48.77807298244163500, 58.03940806028131000, 60.68859895135889100, 98.51271960646154500, 140.79005481569405000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 5.13900894187759240, 7.08872401437782160, 33.89129426509484900, 65.78028328311788200, 72.9209 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -45.40471629268547800, -113.09605909424697000, -144.08054675530227000, -167.10720402149249000, -396.24827427963316000, -434.71304118765551000, -497.34289943859392000, -520.41219111819021000, -523.52994921043626000, -540.09774256841274000, -547.76971526581326000, -558.84907110612983000, -566.18647410871688000, -568.61769683671571000, -605.13208 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -29.08907919776519400, -296.95548126865555000, -340.87638313882724000, -386.98338079251033000, -401.27969308415089000, -403.07284661034163000, -412.38827671276204000, -417.07942630063809000, -422.43134645633023000, -425.09249707060695000, -425.73109029366316000, -434.86889639297482 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 224.35045061025036000, 266.79264863697318000, 320.97036265695937000, 349.12438840767078000, 377.76845595337323000, 618.43452544302568000, 672.69655367306495000, 753.58508169972072000, 779.53476863695778000, 782.97551540713084000, 799.81004080826756000, 807.81152952298191000, 816.87570158814117000, 822.78898831625042000, 824.63404790187701000, 851.29603806467253000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 3.23418614787750200, 47.66356911600042400, 91.77516407397023100, 103.630 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 9.97042236767525840, 22.55595774854374700, 25.64975 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -4.04503615923393940, -18.12259916778914700, -23.69844903490367500, -30.69939429029375000, -35.65733028651085600, -37.51813832118887900, -63.11049214680064500, -98.3529635323705 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+197.39805776885407000, 324.11108420782347000, 360.71622910444682000, 574.25699630587371000, 946.25864515499711000, 972.60425969796245000, 1175.36740730566290000, 1208.14627921151440000, 1257.69197435326420000, 1280.58623578375020000, 1301.54177486071650000, 1509.09783115728310000, 1548.44086511148630000, 1587.72259414903280000, 1596.33641372988250000, 1598.23237791392810000, 1605.31401660292070000, 1606.32592337875280000, 1609.70483449848760000, 1611.29402204867260000, 1611.2283490268057 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 51.22218545292967200, 75.53482486250209100, 102.08693115435599000, 346.05052645984028000, 392.49208684420637000, 476.64201470431755000, 509.77112077514738000, 514.18113911218165000, 535.28846978042782000, 544.80015516995525000, 558.60509798731721000, 567.07838604420272000, 569.55417658889485000, 604.45964412633089000, 645. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -11.97183 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 338.47237247948533000, 406.51067552945096000, 504.16698425051567000, 539.45364364200941000, 544.91084100031242000, 566.98127757556836000, 575.01532954773677000, 585.96502495032632000, 592.77740006832664000, 594.72985335247347000, 622.25069861274642000, 658.8749 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -55.22891133608180800, -67.525 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 44.22512649424554400, 308.11155237410668000, 770.18525695657661000, 804.34739954643817000, 1082.88468924307540000, 1138.18882511465340000, 1214.30720507874140000, 1247.75439502523300000, 1275.74039247487940000, 1564.49181373203710000, 1625.69798750261270000, 1712.02213605994580000, 1738.60878190836590000, 1742.44912939404050000, 1759.08908080693750000, 1765.32470942191840000, 1773.93895586976920000, 1780.15535872206060000, 1782.14373857221930000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 130.39442125586311000, 164.06444129950825000, 348.96000763867863000, 589.20839852963479000, 609.88084329771095000, 790.29824162037812000, 822.16281836844155000, 868.34700864960882000, 888.77045041465340000, 903.51429179178797000, 998.09335571825034000, 1007.92862327569800000, 1019.03051908521580000, 1024.60139441901970000, 1025.24128823187860000, 1028.39098618229540000, 1030.61685959697820000, 1033.29514721326060000, 1034.96242926379550000, 1035.03753641287900000, 10 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 412.61183063150389000, 445.06073587733692000, 692.43177367773535000, 735.48081178477173000, 792.49878184885756000, 821.24871671264225000, 853.56857607113477000, 1119.39365385185900000, 1176.85562652165030000, 1247.47340635847290000, 1274.74145413417090000, 1278.20224250828690000, 1295.15577774923050000, 1300.34523607870280000, 1306.69361842777020000, 1310.46259761712870000, 1311.51597273000580000, 1326.40 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -28.35381112078047400, -62.60201432322905600, -403.00464369678616000, -458.63399730197563000, -524.36508576059680000, -545.69006923003462000, -548.34148064942974000, -559.18515151539339000, -565.88897760826762000, -572.15171340232098000, -576.11506925839069000, -577.34484140734583000, -595.147749288312 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq1[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 900.25399348292717000, 825.36128293231400000, 969.97443921964873000, 894.56280590924018000, 868.29193084863118000, 904.94646637624123000, 781.09493675915394000, 814.45185144284221000, 675.4881144696 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1023.50442838603750000, 955.03074878246616000, 930.73767733668285000, 977.85535983939167000, 951.64815246187720000, 1090.50838412868370 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -825.12350599270974000, -960.91229511284905000, -830.52047785125148000, -915.07545291619306000, -1052.21297590710580000, -986.73535636620079000, -1007.37814445218120000, -900.49335057614235000, -911.44661961495979000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1704.29902929860830000, -1790.22458982157330000, -1857.00891201779400000, -1731.34081680994970000, -1703.39364371819330000, -1419.36927947834400000, -1430.45725504191300000, -1424.59882763021980000, -1387.93680975122110000, -1423.12195580499700000, -1420.85517264370330000, -1406.47287505411400000, -1491.47268161074770000, -1519.45286407010490000, -1558.01400652073740000, -1728.091261 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 960.44584101222324000, 1015.77714872243860000, 1021.13109836526640000, 1095.91076781875560000, 1096.63648979368830000, 1063.25143530868190000, 1096.20161901960140000, 1049.22474603628870000, 1105.58030949794100000, 1038.10169348255680000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1802.51878152217610000, -1671.77624091211810000, -1499.75083651628350000, -1389.69651817757450000, -1189.01735115620700000, -1264.04853444862580000, -1129.49668791748080000, -1072.75065586785400000, -1124.59222346701700000, -1120.28423568747760000, -1187.46744490266860000, -1283.23867302068150000, -1327.24435670362800000, -1357.33246896140370000, -1321.52113245684970000, -1367.87952654049790000, -1308.50608521594650000, -133 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -631.29219662377136000, -456.68791742959593000, -357.93234601147708000, -333.46834593529883000, -397.9654408269577 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 791.93900941644438000, 937.73602871529465000, 907.42138881199821000, 921.38705588210712000, 955.37195016520320000, 948.26891252484631000, 820.57867253259883 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 484.20074732142365000, 665.54547050693202000, 636.03748199422887000, 578.53189493667026000, 4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1199.33705348795870000, -1218.51820344774980000, -1166.91316667323100000, -936.01764271575166000, -997.55703779590692000, -927.42619434251912000, -1008.59802294936330000, -1040.48182095448190000, -1024.53616625788300000, -1097.09776717123670000, -1154.81167668520150000, -1215.63268443818720000, -1250.18392913676170000, -1389.68895491755730000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1000.43704293398460000, -999.88671413470149000, -903.47971573160248000, -763.36039071159769000, -723.57297996965519000, -691.22254846707835000, -725.56787064679486000, -788.26487748203772000, -739.69288302773509000, -673.16667903524024000, -641.39645694982232000, -640.158727011416 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1327.18984465525180000, 1345.43444542693780000, 1205.71045392255060000, 1278.52029241134050000, 1334.25650751666900000, 1249.98702933119850000, 1367.76420063766590000, 1413.88793950241440000, 1364.53946957248060000, 1335.88419919176680000, 1365.77744877908140000, 1440.92632218915110000, 1354.19933002110340000, 1374.02940286779150000, 1447.74659853660930000, 1450.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1095.48182710796730000, 1045.81349754300410000, 801.05733650421951000, 7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 233.96579902690939000, 224.92215839591671000, 206.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -654.05963126143740000, -491.40246044381871000, -464.88547790168440000, -445.71504933794887000, -497.83933152165628000, -665.94924686776710000, -638.06797372247092000, -665.0261 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+2677.88291006687950000, 2263.85679908056320000, 2424.07454608089940000, 2275.52320244851760000, 2370.18343358526770000, 2279.19707878907500000, 2172.09010714461100000, 2041.20071402222420000, 2066.78965657289560000, 2036.35143210368640000, 2001.29304828602490000, 2053.76350558833250000, 2052.40415080115830000, 1908.38410914625770000, 1790.52468891005330000, 1902.90317513471700000, 1843.39478202350030000, 1686.39266738357670000, 1810.00650242326360000, 1759.43911364382320000, 1589.0492907 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 887.69751211086316000, 878.12226592157731000, 988.71982194319162000, 986.25635106763389000, 987.38371088887527000, 1163.56807462237340000, 1256.62725187614410000, 1222.84632055853810000, 1244.90522123832350000, 1297.40869315644180000, 1376.96135949813420000, 1356.96378072482280000, 1405.67685422941960000, 1388.645414817779 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -712.9743 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1226.68679668015220000, 1278.04505688204130000, 1301.34726808175970000, 1334.94923764520670000, 1421.85181052725030000, 1308.97711551219340000, 1210.70667774333810000, 1235.06237456598230000, 1227.83141601452230000, 1254.11134723885360000, 1240.5336431789842000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -943.26939707998258000, -787.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 2537.10646404782980000, 2410.47853593795390000, 2538.88226158635920000, 2498.59560620283810000, 2452.09030016303630000, 2543.70869118935020000, 2457.34566941063350000, 2351.88357399057120000, 2210.25404452370460000, 2322.22921927049130000, 2409.71643594809670000, 2416.69662304044410000, 2337.97296079235280000, 2359.57140412432450000, 2318.51501919910470000, 2258.71648418716310000, 2284.59101811011620000, 2359.65245447885900000, 2453.6583333933936 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2126.49558766746850000, 2061.97567989776370000, 1822.01165393965830000, 1508.81625572186200000, 1635.11666928219960000, 1677.17595325469120000, 1631.98101618756600000, 1622.55019834701350000, 1562.97112388709160000, 1395.84339585053000000, 1246.28640081522490000, 1133.91315613246750000, 1109.65664010495680000, 1150.19012566203330000, 1128.06863051025450000, 1134.28208452998430000, 1206.73825846198700000, 1192.06389185122880000, 1190.38754070687950000, 1060.4026832086 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1991.98174862367020000, 2054.34210270330910000, 1908.43345626856170000, 1829.54506794362620000, 1723.62119907872510000, 1770.31624756473090000, 1932.79935414693640000, 1816.96807231761930000, 1912.91285542238390000, 1823.93490189427140000, 1889.46702568729390000, 1834.33149949903550000, 1865.12423053441260000, 1710.95917949046860000, 1683.02537977994190000, 1661.80927608990190000, 1667.26126056417680000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -964.34485381850811000, -1206.22441007367500000, -1296.28442080400740000, -1171.21635321021450000, -1060.93592731932110000, -1026.43635365213530000, -974.40840623010752000, -923.74335239485663000, -1096.32670216009000000, -943.40635161826401000, -945.58166635907401000, -992.66284327813298000, -995.1076 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso1[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 38.23740324743330600, 43.10537614002905100, 69.87845270767906000, 80.17097332676398500, 93.24532081516629500, 101.86021756666102000, 103.86551922079182000, 134.14706417487375000, 165.842862810832860 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 12.77390603082450800, 28.40525457939803300, 37.98205596755769900, 40.75683976124865600, 79.57435563940001100, 138.76506616059424000, 15 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -90.04830212005545300, -127.03739399278913000, -131.38808982480180000, -154.02529135943018000, -165.23517454337318000, -178.86325883224873000, -187.65660628004426000, -189.76111104411402000, -220.51564596763188000, -263 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -33.68558078818011800, -330.61395149424897000, -388.40048442225230000, -465.89122627891169000, -502.27645679748122000, -528.94218847853620000, -777.69186462367645000, -824.53704512417119000, -886.02261892135380000, -908.83538518178841000, -912.00197497809222000, -926.28501429350956000, -933.33887156257470000, -943.06207195804905000, -949.58879358750710000, -951.88716297717235000, -984 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 69.54981373838141700, 172.81455449060053000, 208.84596563059421000, 214.33202382610537000, 239.81782971204473000, 250.09474030353178000, 264.13103161019257000, 272.46353345156075000, 274.92314042082177000, 307.44589608692490000, 354.3883303 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -201.01830046555924000, -505.66573342661439000, -525.31388992661221000, -671.43061386684803000, -691.02550497367565000, -724.09024998436098000, -736.01007049544489000, -745.80126488012365000, -850.31879516875688000, -869.86809748453231000, -904.52870499568655000, -920.61403854157868000, -923.12884646090231000, -935.67103531391240000, -940.48665969832336000, -947.57679326453297000, -951.40747479277218000, -952.5358273063876600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -10.47267359991118400, -15.20852776934026300, -16.22034978051193800, -29.73983224383573500, -51.29963218123113900, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 22.87555446674134500, 34.29352336385176900, 48.77807298244163500, 58.03940806028131000, 60.68859895135889100, 98.51271960646154500, 140.79005481569405000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 5.13900894187759240, 7.08872401437782160, 33.89129426509484900, 65.78028328311788200, 72.9209 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -45.40471629268547800, -113.09605909424697000, -144.08054675530227000, -167.10720402149249000, -396.24827427963316000, -434.71304118765551000, -497.34289943859392000, -520.41219111819021000, -523.52994921043626000, -540.09774256841274000, -547.76971526581326000, -558.84907110612983000, -566.18647410871688000, -568.61769683671571000, -605.13208 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -29.08907919776519400, -296.95548126865555000, -340.87638313882724000, -386.98338079251033000, -401.27969308415089000, -403.07284661034163000, -412.38827671276204000, -417.07942630063809000, -422.43134645633023000, -425.09249707060695000, -425.73109029366316000, -434.86889639297482 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 224.35045061025036000, 266.79264863697318000, 320.97036265695937000, 349.12438840767078000, 377.76845595337323000, 618.43452544302568000, 672.69655367306495000, 753.58508169972072000, 779.53476863695778000, 782.97551540713084000, 799.81004080826756000, 807.81152952298191000, 816.87570158814117000, 822.78898831625042000, 824.63404790187701000, 851.29603806467253000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 3.23418614787750200, 47.66356911600042400, 91.77516407397023100, 103.630 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 9.97042236767525840, 22.55595774854374700, 25.64975 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -4.04503615923393940, -18.12259916778914700, -23.69844903490367500, -30.69939429029375000, -35.65733028651085600, -37.51813832118887900, -63.11049214680064500, -98.3529635323705 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+197.39805776885407000, 324.11108420782347000, 360.71622910444682000, 574.25699630587371000, 946.25864515499711000, 972.60425969796245000, 1175.36740730566290000, 1208.14627921151440000, 1257.69197435326420000, 1280.58623578375020000, 1301.54177486071650000, 1509.09783115728310000, 1548.44086511148630000, 1587.72259414903280000, 1596.33641372988250000, 1598.23237791392810000, 1605.31401660292070000, 1606.32592337875280000, 1609.70483449848760000, 1611.29402204867260000, 1611.2283490268057 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 51.22218545292967200, 75.53482486250209100, 102.08693115435599000, 346.05052645984028000, 392.49208684420637000, 476.64201470431755000, 509.77112077514738000, 514.18113911218165000, 535.28846978042782000, 544.80015516995525000, 558.60509798731721000, 567.07838604420272000, 569.55417658889485000, 604.45964412633089000, 645. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -11.97183 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 338.47237247948533000, 406.51067552945096000, 504.16698425051567000, 539.45364364200941000, 544.91084100031242000, 566.98127757556836000, 575.01532954773677000, 585.96502495032632000, 592.77740006832664000, 594.72985335247347000, 622.25069861274642000, 658.8749 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -55.22891133608180800, -67.525 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 44.22512649424554400, 308.11155237410668000, 770.18525695657661000, 804.34739954643817000, 1082.88468924307540000, 1138.18882511465340000, 1214.30720507874140000, 1247.75439502523300000, 1275.74039247487940000, 1564.49181373203710000, 1625.69798750261270000, 1712.02213605994580000, 1738.60878190836590000, 1742.44912939404050000, 1759.08908080693750000, 1765.32470942191840000, 1773.93895586976920000, 1780.15535872206060000, 1782.14373857221930000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 130.39442125586311000, 164.06444129950825000, 348.96000763867863000, 589.20839852963479000, 609.88084329771095000, 790.29824162037812000, 822.16281836844155000, 868.34700864960882000, 888.77045041465340000, 903.51429179178797000, 998.09335571825034000, 1007.92862327569800000, 1019.03051908521580000, 1024.60139441901970000, 1025.24128823187860000, 1028.39098618229540000, 1030.61685959697820000, 1033.29514721326060000, 1034.96242926379550000, 1035.03753641287900000, 10 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 412.61183063150389000, 445.06073587733692000, 692.43177367773535000, 735.48081178477173000, 792.49878184885756000, 821.24871671264225000, 853.56857607113477000, 1119.39365385185900000, 1176.85562652165030000, 1247.47340635847290000, 1274.74145413417090000, 1278.20224250828690000, 1295.15577774923050000, 1300.34523607870280000, 1306.69361842777020000, 1310.46259761712870000, 1311.51597273000580000, 1326.40 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -28.35381112078047400, -62.60201432322905600, -403.00464369678616000, -458.63399730197563000, -524.36508576059680000, -545.69006923003462000, -548.34148064942974000, -559.18515151539339000, -565.88897760826762000, -572.15171340232098000, -576.11506925839069000, -577.34484140734583000, -595.147749288312 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq1[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 900.25399348292717000, 825.36128293231400000, 969.97443921964873000, 894.56280590924018000, 868.29193084863118000, 904.94646637624123000, 781.09493675915394000, 814.45185144284221000, 675.4881144696 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1023.50442838603750000, 955.03074878246616000, 930.73767733668285000, 977.85535983939167000, 951.64815246187720000, 1090.50838412868370 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -825.12350599270974000, -960.91229511284905000, -830.52047785125148000, -915.07545291619306000, -1052.21297590710580000, -986.73535636620079000, -1007.37814445218120000, -900.49335057614235000, -911.44661961495979000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1704.29902929860830000, -1790.22458982157330000, -1857.00891201779400000, -1731.34081680994970000, -1703.39364371819330000, -1419.36927947834400000, -1430.45725504191300000, -1424.59882763021980000, -1387.93680975122110000, -1423.12195580499700000, -1420.85517264370330000, -1406.47287505411400000, -1491.47268161074770000, -1519.45286407010490000, -1558.01400652073740000, -1728.091261 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 960.44584101222324000, 1015.77714872243860000, 1021.13109836526640000, 1095.91076781875560000, 1096.63648979368830000, 1063.25143530868190000, 1096.20161901960140000, 1049.22474603628870000, 1105.58030949794100000, 1038.10169348255680000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1802.51878152217610000, -1671.77624091211810000, -1499.75083651628350000, -1389.69651817757450000, -1189.01735115620700000, -1264.04853444862580000, -1129.49668791748080000, -1072.75065586785400000, -1124.59222346701700000, -1120.28423568747760000, -1187.46744490266860000, -1283.23867302068150000, -1327.24435670362800000, -1357.33246896140370000, -1321.52113245684970000, -1367.87952654049790000, -1308.50608521594650000, -133 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -631.29219662377136000, -456.68791742959593000, -357.93234601147708000, -333.46834593529883000, -397.9654408269577 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 791.93900941644438000, 937.73602871529465000, 907.42138881199821000, 921.38705588210712000, 955.37195016520320000, 948.26891252484631000, 820.57867253259883 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 484.20074732142365000, 665.54547050693202000, 636.03748199422887000, 578.53189493667026000, 4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1199.33705348795870000, -1218.51820344774980000, -1166.91316667323100000, -936.01764271575166000, -997.55703779590692000, -927.42619434251912000, -1008.59802294936330000, -1040.48182095448190000, -1024.53616625788300000, -1097.09776717123670000, -1154.81167668520150000, -1215.63268443818720000, -1250.18392913676170000, -1389.68895491755730000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1000.43704293398460000, -999.88671413470149000, -903.47971573160248000, -763.36039071159769000, -723.57297996965519000, -691.22254846707835000, -725.56787064679486000, -788.26487748203772000, -739.69288302773509000, -673.16667903524024000, -641.39645694982232000, -640.158727011416 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1327.18984465525180000, 1345.43444542693780000, 1205.71045392255060000, 1278.52029241134050000, 1334.25650751666900000, 1249.98702933119850000, 1367.76420063766590000, 1413.88793950241440000, 1364.53946957248060000, 1335.88419919176680000, 1365.77744877908140000, 1440.92632218915110000, 1354.19933002110340000, 1374.02940286779150000, 1447.74659853660930000, 1450.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1095.48182710796730000, 1045.81349754300410000, 801.05733650421951000, 7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 233.96579902690939000, 224.92215839591671000, 206.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -654.05963126143740000, -491.40246044381871000, -464.88547790168440000, -445.71504933794887000, -497.83933152165628000, -665.94924686776710000, -638.06797372247092000, -665.0261 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+2677.88291006687950000, 2263.85679908056320000, 2424.07454608089940000, 2275.52320244851760000, 2370.18343358526770000, 2279.19707878907500000, 2172.09010714461100000, 2041.20071402222420000, 2066.78965657289560000, 2036.35143210368640000, 2001.29304828602490000, 2053.76350558833250000, 2052.40415080115830000, 1908.38410914625770000, 1790.52468891005330000, 1902.90317513471700000, 1843.39478202350030000, 1686.39266738357670000, 1810.00650242326360000, 1759.43911364382320000, 1589.0492907 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 887.69751211086316000, 878.12226592157731000, 988.71982194319162000, 986.25635106763389000, 987.38371088887527000, 1163.56807462237340000, 1256.62725187614410000, 1222.84632055853810000, 1244.90522123832350000, 1297.40869315644180000, 1376.96135949813420000, 1356.96378072482280000, 1405.67685422941960000, 1388.645414817779 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -712.9743 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1226.68679668015220000, 1278.04505688204130000, 1301.34726808175970000, 1334.94923764520670000, 1421.85181052725030000, 1308.97711551219340000, 1210.70667774333810000, 1235.06237456598230000, 1227.83141601452230000, 1254.11134723885360000, 1240.5336431789842000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -943.26939707998258000, -787.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 2537.10646404782980000, 2410.47853593795390000, 2538.88226158635920000, 2498.59560620283810000, 2452.09030016303630000, 2543.70869118935020000, 2457.34566941063350000, 2351.88357399057120000, 2210.25404452370460000, 2322.22921927049130000, 2409.71643594809670000, 2416.69662304044410000, 2337.97296079235280000, 2359.57140412432450000, 2318.51501919910470000, 2258.71648418716310000, 2284.59101811011620000, 2359.65245447885900000, 2453.6583333933936 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2126.49558766746850000, 2061.97567989776370000, 1822.01165393965830000, 1508.81625572186200000, 1635.11666928219960000, 1677.17595325469120000, 1631.98101618756600000, 1622.55019834701350000, 1562.97112388709160000, 1395.84339585053000000, 1246.28640081522490000, 1133.91315613246750000, 1109.65664010495680000, 1150.19012566203330000, 1128.06863051025450000, 1134.28208452998430000, 1206.73825846198700000, 1192.06389185122880000, 1190.38754070687950000, 1060.4026832086 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1991.98174862367020000, 2054.34210270330910000, 1908.43345626856170000, 1829.54506794362620000, 1723.62119907872510000, 1770.31624756473090000, 1932.79935414693640000, 1816.96807231761930000, 1912.91285542238390000, 1823.93490189427140000, 1889.46702568729390000, 1834.33149949903550000, 1865.12423053441260000, 1710.95917949046860000, 1683.02537977994190000, 1661.80927608990190000, 1667.26126056417680000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -964.34485381850811000, -1206.22441007367500000, -1296.28442080400740000, -1171.21635321021450000, -1060.93592731932110000, -1026.43635365213530000, -974.40840623010752000, -923.74335239485663000, -1096.32670216009000000, -943.40635161826401000, -945.58166635907401000, -992.66284327813298000, -995.1076 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso1[1250] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 180.90306477422399000, 252.94887147070628000, 484.01065923904144000, 525.57591645497632000, 532.27363706604694000, 617.41844165786722000, 688.86224989427706000, 753.48114601068676000, 788.46160978909813000, 814.81081203 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.12502752196399760, 82.21257129925322700, 161.82161090790876000, 238.08542891115513000, 299.12458144263923000, 343.66745967951954000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 369.71359349861126000, 382.50221096175642000, 410.10556512526773000, 511.05732707556109000, 513.64658051104800000, 556.18028618000665000, 734.92140911190188000, 783.37158835758953000, 986.11646813263360000, 1020.52872222098090000, 1023.97629473951840000, 1047.75638787276310000, 1065.65853156775550000, 1079.25779661505070000, 1076.9547899763402 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.32297934719664400, 40.79266392344968000, 235.40579870179340000, 304.37247795002258000, 567.83923521037332000, 614.32218068521433000, 620.43192010067685000, 692.97173060130274000, 756.23781734274655000, 813.57717388082540000, 843.91532948481370000, 865.7542954 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 18.75125367466831200, 69.38309015301307200, 70.69304321219853200, 88.92533270364016600, 174.88382950659928000, 213.36706897925120000, 382.48677191559682000, 412.19705702744778000, 415.11240914256251000, 445.28970794283663000, 466.67601765963502000, 481.39792924975518000, 492.04682354856760000, 499.5382 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 295.29146243916642000, 440.66240555664785000, 514.40946152516096000, 723.43656045692092000, 732.14360882403321000, 751.69606191720516000, 830.58584576439921000, 832.65486084921793000, 864.92067292268064000, 994.56948077127231000, 1038.86230930009310000, 1215.63593410416770000, 1247.80653030128220000, 1252.20105391129780000, 1303.51198170819450000, 1340.23559941063080000, 1371.24308361682480000, 1387.15388 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 26.04624395906332900, 148.72064740736232000, 201.38138934879893000, 388.56742208606408000, 418.29909279590544000, 422.56886411190987000, 477.43961191469896000, 533.52786870068780000, 580.76931352982672000, 609.92773556592601000, 627.9440372 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 229.67924044633557000, 267.75202882094720000, 272.05968197881731000, 323.42851632722784000, 360.38585988484732000, 386.72528082381638000, 398.15459846792220000, 406.712251817804 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 9.46365370589991710, 27.74222650359413600, 122.96849658713963000, 125.26332673457753000, 160.79723404526294000, 330.26200427504847000, 392.70987948148689000, 584.79564482486035000, 620.36337482006923000, 626.19628291728964000, 711.64949867010739000, 789.14529680871783000, 851.15027683591165000, 905.89100029219560000, 947.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 98.46754826192292900, 179.04830044964422000, 239.44140966421941000, 276.28788690813991000, 303.61146189495577000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 20.58821430147270300, 153.7617 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+197.39805776885407000, 324.11108420782347000, 579.85133441223877000, 980.46977776585038000, 1295.09690440060060000, 1478.98071173773290000, 1588.08524859266590000, 1814.34848457791260000, 1825.46766638359550000, 1848.97273366032870000, 1939.40324761197850000, 1941.62329173029890000, 1980.27642262188940000, 2133.44508068367300000, 2189.80613867846390000, 2354.39004400550860000, 2380.85005843363430000, 2385.93416881422400000, 2441.38809840612380000, 2492.50495654498130000, 2534.07335891593 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 48.71516278570112500, 89.65096766656525100, 324.277 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 158.46650791720094000, 246.60147987716311000, 440.98352388015172000, 448.58516662353605000, 466.45983096381889000, 540.13155692286739000, 541.93609676848394000, 570.37049704995263000, 704.24866985273945000, 757.59155952184551000, 975.44085790565725000, 1010.17255214241520000, 1016.18550139374460000, 1086.26994047343310000, 1152.24674215497980000, 1211.14298479966060000, 1254.073327337 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 25.73607029905888800, 29.77641089658154500, 94.03818415748627000, 146.63063929364171000, 192.64482639338055000, 222.87378998969646000, 242.85957458694074000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 160.00882677232335000, 164.28977411977320000, 232.63958460546758000, 525.79863454085637000, 621.88112702137971000, 1002.63031861209610000, 1071.14464809401760000, 1081.97098053184910000, 1226.79595096680800000, 1339.50945132712970000, 1427.75122341759400000, 1482.59836174796210000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 177.71406 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 108.64999255679551000, 367.54978348878183000, 377.74883335222609000, 400.52970669442544000, 500.76622591393794000, 503.00622646659417000, 535.94001722111102000, 676.79519644699178000, 717.06702033518570000, 868.91031559523594000, 892.92607821333718000, 896.68423145771760000, 936.91442722866759000, 968.68061478488278000, 1003.64254997473680000, 1035.698706354450900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 51.65330895205340800, 91.05388355139814400, 118.61790697795125000, 269.0 [...]
+0.00000000000000000, 0.00000000000000000, 308.97691968987618000, 796.88866141144229000, 1198.62431169338790000, 1412.17285008652240000, 1542.66951131884890000, 1849.92287174236300000, 1861.73699245006170000, 1891.11078881338880000, 1959.33443528407160000, 1960.88845539421660000, 1981.95551224120000000, 2054.11251914842250000, 2064.70270922061760000, 2118.73000459177590000, 2126.84302282135880000, 2127.62416303191000000, 2129.44809024873620000, 2126.32297277051610000, 2115.180306957850000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 130.39442125586311000, 365.62854953666084000, 645.19166119414911000, 887.17383384186030000, 1026.69031991483390000, 1093.06209142080660000, 1181.10315355587390000, 1185.86822771783590000, 1195.43210347996890000, 1234.56334893295320000, 1235.53735782853050000, 1250.52854714543400000, 1326.59086899142950000, 1355.47117222648350000, 1427.50750217727680000, 1436.93562375442000000, 1438.15834938863370000, 1447.82087299280870000, 1457.24107714472780000, 1470.42261843331270 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 47.65689200527660300, 102.33547210021209000, 148.13169672320919000, 183.83695456626546000, 38 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 434.45099813846497000, 767.90244221479327000, 940.58864239595641000, 1027.45046119030990000, 1256.01785840864250000, 1264.88730460713400000, 1284.15202757714450000, 1327.68749431769720000, 1328.76504506861490000, 1348.24454546549190000, 1450.12027106617010000, 1479.47992544914470000, 1588.96556034040850000, 1607.98930726570730000, 1610.54031338532560000, 1645.12692054496120000, 1666.63518691582520000, 1675.38795210067700000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 74.75922991619353300, 341.13812584743448000, 388.58282640738116000, 395.58165962971356000, 497.24314961080898000, 584.64603974713214000, 668.04172420824398000, 727.79221914063385000, 773.53415957029 [...]
+
+double nnlassolsq1[1250] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 812.17355542147766000, 945.61645067717427000, 873.58881519744318000, 891.85014686975842000, 956.34985626516936000, 1008.60491464232930000, 1005.72832164382440000, 1031.66950999226360000, 982.11317915397979000, 994.69796 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 458.25682424245889000, 427.19229796746208000, 514.90194465883565000, 566.40590537197397000, 637.03684456475855000, 647.7636364593032600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1410.35308183763480000, 1240.42485576040510000, 1204.00525397016510000, 1320.83786795586460000, 1357.93910844223610000, 1378.26418234735300000, 1358.64769320156640000, 1249.18451917273480000, 1327.95133903721060000, 1323.77048534942450000, 1242.26451605762050000, 1157.01086093934080000, 1145.05774178003030000, 1137.80347786660920000, 1064.2053 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 759.79000767912578000, 784.32788342479989000, 914.51827936237521000, 967.43650556278249000, 1012.05328912713820000, 1023.93122009908850000, 1007.27922861912740000, 1026.24623580143790000, 1036.83423116200540000, 1060.42666753897670000, 1011.86711770479110000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 558.05580230265480000, 475.52435145546565000, 497.83685410873761000, 441.31578036016754000, 474.84039751625352000, 583.35518553740906000, 667.62843312455254000, 674.00493561733640000, 599.70229791285726000, 583.93529105821005000, 561.52812754097158000, 544.77667364302090000, 550.99901772269072000, 550. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1332.95280343759010000, 1191.53965130713140000, 1120.76660961025030000, 1311.78888805981230000, 1316.25475180176750000, 1314.04389598379880000, 1463.39710729706960000, 1507.31032421480950000, 1488.54854839636410000, 1446.98562222557440000, 1464.70536276906660000, 1513.68237197861460000, 1531.29474024709750000, 1530.44690290003750000, 1539.25321062583770000, 1503.11141425098320000, 1504.73223030491070000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 529.46341341624418000, 576.79924823878957000, 707.67579165122197000, 704.16953942130567000, 680.29542188437256000, 692.91583462350582000, 729.53596008172588000, 782.28932246091495000, 784.14666967452035000, 771.34852813354905000, 750.942116 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 616.92637386123556000, 603.25052433632220000, 544.80519808637791000, 559.43578918916228000, 524.29829070951473000, 500.11812501654038000, 461.42721007682815000, 465.135725309268 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 644.33156184547249000, 553.45200694037578000, 886.82223231723913000, 873.55158612183186000, 847.59027285017066000, 921.61798148800972000, 993.10038837065088000, 908.65888058999417000, 933.78722454910644000, 995.51560159961662000, 1104.25292568808940000, 1132.85302655377130000, 1118.08556959302610000, 1208.93521012970720000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 550.86359394748035000, 536.43835334067251000, 499.43749839184568000, 480.26969198232854000, 490.15070269701965000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 161.14485328886838000, 189.170 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+2677.88291006687950000, 2263.85679908056320000, 2424.07454608089940000, 2512.32651313848240000, 2400.70423703912550000, 2428.78652458049510000, 2485.15584946855280000, 2451.21567655067070000, 2571.39644955499170000, 2525.00164981082300000, 2664.78801638804950000, 2665.52564716848970000, 2727.35725986988060000, 2667.93494157750820000, 2731.67636531406470000, 2631.88419376093130000, 2614.01645918696070000, 2707.84223775153170000, 2696.16379768899060000, 2719.21736785768280000, 2713.0279146 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 318.40191665712609000, 369.12149697257274000, 386.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 976.98561811107425000, 971.25780062600904000, 988.11415248205481000, 958.54032526465005000, 980.55280582105797000, 1131.08637477020900000, 1130.35262144196760000, 1119.94552703920040000, 1171.42339648133450000, 1270.44431180814060000, 1342.74230035051510000, 1316.22923095668650000, 1396.90439559862060000, 1408.26356845941610000, 1444.86566171554590000, 1464.69496991048250000, 1491.735 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 252.52305476825879000, 285.59663159107305000, 389.28034896334185000, 379.88758729274110000, 390.73876173635597000, 390.22109212333066000, 379.30339965018487 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1443.51326281290880000, 1560.20251421000760000, 1553.69256183022640000, 1548.79212291189650000, 1545.64380693675890000, 1644.58660820543310000, 1674.89487085830680000, 1767.45644560778120000, 1892.17500323106470000, 1839.41399132776840000, 1807.63753667894960000, 1786.2316834823516 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 224.96609 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1001.98327564179010000, 1096.27967252802390000, 1061.95069164500520000, 1055.73009106997760000, 1304.80947569398630000, 1233.41588944101340000, 1172.47846580477930000, 1168.31654359001800000, 1104.25106395873330000, 1124.92335666703230000, 1104.55366240152940000, 1134.63733693863580000, 1121.74670756047590000, 1109.56933997839130000, 1154.15585392493380000, 1213.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 274.02401435253785000, 309.17515127884764000, 306.79869978857448000, 309 [...]
+0.00000000000000000, 0.00000000000000000, 2537.10646404782980000, 2662.53139509821950000, 2610.33310325493450000, 2515.20441130500060000, 2615.62872711783120000, 2714.75442082299510000, 2654.28565634814230000, 2735.93014137833600000, 2506.58770033414520000, 2467.61659149248680000, 2389.13583902346320000, 2305.90808276039930000, 2166.51961789299320000, 2209.82189090236990000, 2198.33517052885190000, 2177.08322625520170000, 2137.82788110445740000, 2112.46251763068360000, 2067.2104380941837 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2126.49558766746850000, 2061.97567989776370000, 1714.16550066427290000, 1737.50504116237330000, 1747.32783214861300000, 1638.77876519419460000, 1428.91391157011660000, 1505.53257294304920000, 1470.49860252686470000, 1548.45307701753900000, 1553.13795319849960000, 1540.27558723972080000, 1592.01422868639750000, 1633.13410149104560000, 1548.96324289186920000, 1520.01649961632190000, 1515.57705557027680000, 1492.21405173068570000, 1499.02136795481600000, 1527.1699729412 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 259.02373448286687000, 337.73015779777432000, 401.65923213294155000, 427.59831060768516000, 4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2095.67428610462230000, 1939.65888163229260000, 1832.55601627726130000, 1741.63876375950740000, 1899.37061436610360000, 1859.89288378236530000, 1838.22445953513940000, 1676.90550818455470000, 1680.12811945821590000, 1724.74086361594500000, 1805.62082250927980000, 1761.75146435311040000, 1773.56212283060240000, 1775.62710699038100000, 1772.06108935997760000, 1804.03048409341550000, 1762.02819637756370000, 1713.0691502242462000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 793.51438283639675000, 790.26214616001926000, 806.66687902313515000, 838.72327512589652000, 964.31333545125585000, 972.29349500889907000, 1027.06532903068860000, 1058.57048403964790000, 1085.8163863 [...]
+
+
+
+// Data from file x13.txt and y13.txt
+double x2[5000] = {
+-14074.4194118023, 3633.80195532272, 6031.29155379607, 5887.25925537132, -3430.70743721526, -6560.86332396419, -12041.7916399995, -6131.323951836, -1948.09551731409, 11551.88825044, 5314.69539939044, -12918.3719626566, -4129.58259604954, 1989.92720351500, 12637.5094545768, -405.001205905332, -8491.70327650958, 127.841278852560, 13033.0754555777, 11307.1392900841, -689.098560283329, 32.6716015182633, 8459.7988244877, 13499.4227848558, -8177.4428882636, 6689.55361113379, 15072.2341128806,  [...]
+-9232.49638314718, -21520.2331526078, -3297.72711873837, 514.440126654894, 3716.65824076188, 4551.56523238511, -6071.23676750082, -2233.37630340177, -3695.51991360918, 10528.1107828990, 13439.4820183708, -11730.3994794363, 4507.04518184803, 8626.04414155993, 1132.05882579099, -9671.17813939653, -18104.2790432186, -3103.33985978510, 5915.1024894252, -1403.39671157511, -1509.93574861294, 5423.06899220274, 15200.3170046740, -450.898302520011, -8680.27939766264, 5074.1024818683, -645.4563423 [...]
+-5460.50484904639, -8239.6303485994, 677.295021054508, -9603.81680632572, -14507.7719748815, -16832.3563665747, 10909.9720982742, 3128.47287779298, -1101.73767922685, 2720.74966719693, -22374.0288724253, 18198.4334026684, -21752.7963104273, -1866.63493846870, -18014.2086874138, 131.626060516165, -6755.56544643636, -12171.8725338975, -2568.53392266695, -29264.4027208234, 6003.10418360675, -24227.9361372885, 4221.46143104339, 4362.46649392212, 7987.58731517287, -2890.2133713655, -3282.8126 [...]
+-19352.3797568840, -18259.6194251737, 8170.04363515171, 3708.6415048916, -21720.0160207889, 398.459385528202, -6117.60648799121, -5739.2113665142, 1336.56676568992, 6488.71150404167, 4286.21063754965, 14237.8124715771, 5729.36889890576, 7552.88215375052, -11850.5881758873, 16023.0340139576, -2108.79065823742, 3673.81898113495, -3153.5171211938, 5830.7400065744, -9626.9323386362, 14697.1228358476, 1499.9129753872, -30535.7876579256, -8265.83422485992, 8566.29043623729, -1297.72018626187,  [...]
+-3521.7563369501, 5208.86818323788, 10888.1234208023, -11124.4303924591, -5671.56183042895, 259.758114732713, -2024.22905328712, 1332.60151005926, 1059.14306814200, -10848.582990424, -17066.3647738829, -13864.0275420806, -1382.98227296868, 8189.89274921326, -16492.9582259010, -6931.85984077054, 22533.2440562436, -8666.92870549327, -15154.2108346941, -11358.8521711162, -22424.1822313074, 14104.2423218902, -10912.2435354724, -6851.09613307015, -16659.1263429693, -9433.68112875413, 21225.41 [...]
+11516.1028017775, -3327.39762291684, 7038.999976361, 9936.74183932263, -11579.1138014859, 17576.1907657132, -11787.7986971618, -5315.59810838943, 5953.80540075927, 5028.81838987888, 10637.442020426, 892.587936353275, -3067.68978000127, -15370.9654747467, -11086.558130201, 9484.27258222025, 12867.9288727382, 8555.8058297481, 2199.00394651871, -15222.3882565064, -16741.1917430364, 16429.5737310404, -1393.88618182124, 3927.71245256394, -4920.16073081394, 10968.4234759012, 6209.09096106327,  [...]
+13409.3493599058, 693.526007647363, 15789.6403837863, 247.694613783117, -3861.68649780529, 794.80683216105, -3247.35968693701, -14047.9159571554, -5221.55195956472, 1001.41236932442, 8439.51954689835, 13629.5892094815, 9231.00294833894, -4094.16478438147, -523.398516064211, -7066.54041237112, 3933.41012242094, -1504.87246047581, 16104.8538470527, 8599.8870082851, 6483.67209803639, 10760.5392300859, 8756.27188308401, 12965.3440457703, 14740.2337269809, 2010.01111368824, 10229.3535542681,  [...]
+37.3591029904941, -4201.07204256797, 3508.94449072085, 7433.24038169486, -11610.0220097205, -12637.4834502623, 4855.51467564584, 20033.5324537648, -15424.3208388677, 16957.0856918856, -3577.75949976764, -3033.60613083993, -1362.20681135063, -8845.55119257694, 15302.3441067593, -1467.06209622046, 5027.04065331396, 10515.2021593699, -4882.28737823645, -2432.74486970190, -3571.71736404339, 18889.3824314083, 6517.33835213388, -6107.7698931835, 1330.82424682304, 10759.9500959014, 14804.837754 [...]
+15623.9312489549, 4347.92056755300, 9432.99348400728, 976.29101338861, 6919.99881668712, 7521.23888857702, 12461.2772564465, -2872.56135882667, -16118.8545605761, 11564.5224467137, 11153.0542337003, -14987.3503472867, 4248.9156120628, -1986.23913055177, 6802.12213535785, -3923.61194390757, -7381.01497610353, -5687.12920632083, -2778.2142174008, 309.252122215804, 3715.53145398213, -5726.42390725284, 10885.4145333346, 301.51793029874, -6032.40828909773, -5375.61339850888, 5243.37214194639, [...]
+-220.370042270786, -8314.92175759936, -15499.5097067234, 4792.37131795258, -2582.42968140829, 18218.9692896103, -8202.3662596703, 9415.37583331694, -4625.43744880662, -2556.27723261042, -10323.7716817885, 17326.6486291596, -15056.1415020914, 9619.16054158023, -3598.60643546588, 6397.86276551298, 1748.97143611958, 1446.84403922387, 4025.34400681809, -8009.29252832566, 9649.32557244028, -912.465603172158, -3914.10637669478, -9703.3653720284, -13196.6909887174, 7876.51640534574, 6072.366088 [...]
+-8680.03977251632, -14742.8691012547, -13351.9157889633, 1587.88544168702, 5942.79569858482, -12413.3514217232, 18670.0446504877, 11425.1698076315, 8806.72125922628, 16108.3825981880, -4302.85046300238, -2562.69473683686, 547.266708953103, 5142.23497570271, 980.557437294136, -2877.82879798062, 7015.09586586602, -6319.90231123033, -18982.0396470584, 14623.7919065413, 7788.04332942975, -5422.79982509859, 13338.9332734046, 14447.3321451737, -19602.2105351548, -8661.54158549023, -375.7697990 [...]
+-1377.08816172438, 15047.2665341115, 15774.5789592316, 5241.06891934836, -350.91973529221, -11961.2195204667, 19059.3898224913, -3792.70608264536, 8807.8780623286, 1855.26191351788, 3366.50909793013, -6521.48531701403, 5655.60393438685, 17726.2157866576, -1974.87765879942, -4925.89997131385, -10758.5654293006, 123.609004432200, 18614.0920860410, 2098.15997061092, -9290.03884620592, -600.191454489582, 19703.8124200070, -9111.82845337026, -19224.6647852714, 19290.0019294212, 4995.277407594 [...]
+-4746.24311257093, -1580.23818347278, 18856.0100916507, -21871.7696588049, -2427.46317086761, 4468.25256682474, 14552.2037858047, -7297.72820771111, 2803.53969432022, 5308.02248843203, 5611.03439980259, 3444.19581653846, -7352.42419919215, -4257.44419348132, 21.0932012477519, -3435.13752415524, 11187.3148644399, 137.202380280912, 6476.32612346181, 5096.03820289726, -3509.25087909736, -10431.1268367800, 6542.6161698549, -15259.5104839897, -20037.3854236619, -5911.43834722094, -7579.482491 [...]
+-106.699778197227, 8603.75019128609, -7817.19716912969, 640.343002765042, -8370.6020459209, -10779.9277454384, -5940.88150170207, 20883.8721888812, -5632.35856396787, 964.434480172566, -1439.73238462008, -45.7935664341983, -5240.44099450825, -12356.2590368191, -7454.22322084695, 7435.04095665511, 15332.5352666712, 16900.8359367322, 3523.21770913312, -10597.6757385610, -15640.7083264811, 20457.3442190961, 3263.4261668452, 6120.57343355441, -15352.4677641094, 4917.24168709625, -963.5433920 [...]
+-3332.43890473479, 13379.5799533408, -9742.00280887583, 4529.09837687731, -3529.74431823179, -5873.51810053065, -5654.92737265857, -11575.9706720954, -2706.34556005849, 7199.04627097792, -7211.8880933953, -23155.1326224299, 2807.02019651439, 1983.86415931832, -6157.29863604861, 5819.85505617688, -14194.9534605315, 4533.20300736042, 5203.96838501822, -17846.8902172397, 2893.58912659503, 5905.67879063395, 15347.3090853726, -5265.14879862735, 16577.3706779457, 2266.61439973014, 6069.3789039 [...]
+13169.2095030808, -704.938960470186, 6061.71462768718, -1703.26408217144, -441.72870482873, 8995.17977105125, 18804.9316502294, 7546.25198672673, -5246.04286362541, -15289.9701503929, -2572.53480463563, 10710.7642396432, -5436.33690878322, 1384.52187677221, 8159.03566167166, -12245.8955966341, 12745.9090447262, 5380.9639822388, -7405.73796007027, 17819.5554338293, 9115.23024544591, 5533.91234850879, -5018.96650823667, 4015.8305645591, -17569.2024400831, -3049.90739517078, 655.31746839681 [...]
+-6921.72557547665, -2937.19997635596, 12916.7712778798, 9961.70535587175, -3436.00746981035, -2205.85414286749, -12491.3494460215, -18786.4461438029, -1840.16700789059, 2177.78590456200, -7133.64362132584, -17322.2268073057, -7894.56906352137, 13333.7890906265, -4690.20379546767, 7342.11924888829, -3049.78287397450, -715.528895822421, -9340.11166957791, -9710.96249863288, -14331.8019119779, -3405.46387985950, 4156.46923379818, -12104.5328744092, 1307.78377694105, 13071.9684757615, 1248.3 [...]
+4531.45516324653, 12653.5800230572, 16862.4630221606, -2853.48297558765, -19480.7780222259, 285.844125717493, -3903.40269182093, 8340.93760329627, 6239.32941098311, 18937.6045611476, -5932.68856282738, 4779.93363129948, -12868.2801768682, -3937.26871364294, 18073.2117510169, -14663.1975728603, -13432.8584901765, 4113.69352516046, -13192.83359967, 15616.0865534846, 13125.8628970504, -3711.33927306298, 1580.37262705535, -13460.5584081301, 13283.3564930520, -20559.3391780032, -7715.43293539 [...]
+5154.1825161767, -5157.5750819618, -1789.70460681474, 544.685667337899, 3585.0553832032, -6753.67343061741, -6872.50618731474, -9261.603415298, -3109.53747693574, -7467.49888156207, 3105.72124973545, 7723.81971552402, 12517.7692851729, 9293.50325890997, 10560.1712810918, 12620.5356769474, 22789.7341729825, 30508.7635839832, -6233.52698894688, 8338.77864351294, 3886.12338127115, 9173.17620676998, -18523.2778889325, 6898.94505596023, -9544.6357947127, -2751.92115764258, 6630.08246088623, 6 [...]
+5832.90768285214, 6767.17190344548, 15426.6396990147, 2004.48706573718, 12972.9272976583, 5680.35117425746, -5602.75342148067, 6653.95217318698, -4462.4166423524, 2484.68377770947, -15631.724283976, 1799.70880133174, 9679.2318743629, -3828.31297667445, -11612.5078397336, 4760.76694296355, -10008.0113176405, -6049.67795242737, 8524.78377650631, 16143.5433406248, 19933.9883046955, 17050.6777206771, 719.930311505094, 839.050544074815, 716.12544436117, -5266.90722827989, -13834.5627691039, - [...]
+7237.31414052494, -7425.99368857543, -830.941793380968, 5053.04779975801, 1308.12684122704, 2053.76067486141, -10658.9932459183, 5232.23559028387, -8153.7346095028, 2775.09716718647, -18940.0659278968, -239.597786244306, -2950.50608218613, 27140.0899707307, -6286.5368294516, -8689.95756062922, 606.357092285643, -96.3911255375029, -14432.333323079, -1499.14154797499, 2256.43101718944, -2494.86653683197, 8007.65274261232, 4843.34114599576, 280.225660824247, -5101.88539080268, -15414.416919 [...]
+-2609.97443223534, 10089.9527647336, -2147.40775425426, -16113.5401655746, -8659.4795320767, 22636.8544245754, 1318.13628548912, 12740.3375041228, 2233.46759825508, 10736.6889969719, 13428.1124189685, -16415.4371050223, 2878.85098102236, 10643.9774467996, 6025.92892778344, -4943.40384726214, 13945.1644709776, -5871.62055396337, 20094.2197524749, 6794.26272028619, -11316.5867083522, 14961.4294295941, -14888.8464995243, -4942.45572664734, -9863.63897051268, 19993.4002528498, -2710.57399109 [...]
+3586.30498869924, -8044.30266552172, 8069.13204916797, 3888.93958882226, 10991.7461856717, 2807.59956571497, 1565.04502078971, 14086.0747129282, -7130.05094061164, -23815.6109390185, -8022.28293550044, -1494.86579717686, 9377.9605388613, 12740.6911194917, 7193.07096055018, -2118.00709178296, 16563.9113937091, -7727.47614373698, -1455.17640370668, 12817.3231929893, 1570.04161627371, -21719.7190264687, -7280.34452273637, 2013.43627366811, 8518.7757694946, -554.44035161336, 11002.8615375155 [...]
+-7518.73152304827, 4187.04812778012, 19300.6338171197, 3105.7658953641, 13799.7146205858, 10055.1647514737, -3564.64002464916, 4304.66999825196, 1697.50402601194, -18023.8926010851, 14252.6834438491, 6499.8773139637, 75.1564037425645, 15220.3129725864, -6410.47644685135, -22490.1845322480, -1319.62714774383, -10752.7587226790, -3814.33230149981, -15008.1967410518, 2140.26753842747, 4406.56322229559, 12320.0858652165, 8719.73602569939, 3732.99536148139, 11903.4941129839, 15383.1320854914, [...]
+22241.1939700748, 6950.49927910391, 12797.6281189433, 11559.5862056274, 3404.38428127394, 668.245449483421, -81.4239757780352, -17911.5408110213, -9707.86099857813, 26198.3010843117, -5699.90699972228, 5040.14540172379, -990.87661742067, -4206.30887426993, -6904.56566920892, -8906.14225782754, -6790.59940971143, -3086.80326584726, -4142.43255231937, -4655.55676531654, 4359.07697226972, -3786.24188231679, -11450.9861516119, -13100.8746573506, 4119.71311238142, -6461.13232897203, 3776.2624 [...]
+-2701.41660930345, 17630.8871487346, 10751.0707880259, -2894.31670804185, 7980.28800601454, 6614.89563595969, -14090.9687861212, 1312.40205318394, -29.7452537930627, 5912.76990084620, 3670.75019049027, 2225.16838868996, 11083.1367928983, 14091.4536692825, 497.971100377404, -4901.6344091053, 1676.21267549162, -670.926219571422, 14154.3634138716, 9968.18381966933, 1362.07525752192, 5173.61081708951, -8808.85272808653, -3164.26569252636, 2843.45717692208, 4580.90014800344, -7170.70721021885 [...]
+-8942.73732890706, -3322.65758846357, 15973.0199708199, -4131.64539002400, 1923.66560088059, 11617.3191529204, -1627.57436919103, 2521.86388862490, 34316.4783846974, 18755.6704162542, 4074.77687613178, 9633.14947818775, 5245.11158452532, -3948.21970480151, -470.684452422569, 18397.8146568003, 6323.26417880036, 14306.3669115777, -4745.23340520863, 692.657973926925, 2524.77682169528, -2720.16264833690, 7751.12995368051, -1231.24386452047, -16244.2092372554, 629.725663720947, 14704.90376179 [...]
+-8608.89280504034, 3753.07260453864, 13888.1875237074, 1616.80068010496, 5801.12190510132, 10503.8896291577, 5851.63230750488, 22723.9592752944, 2110.53768429176, -1377.14721432363, 6690.9083290471, -5264.73913331734, -8053.68969061089, -4622.99851533508, 12289.8851623688, 6135.84848155591, 6512.28105611184, 15827.7871858459, -4500.91390589821, -2161.89252618282, 15099.8845888484, 6236.18820882479, 2987.14597822465, 7871.18588236552, 5272.81899869195, 16767.3699521099, 12712.9043981873,  [...]
+7308.43653778791, -3495.69701944689, -1995.45724123300, -13025.7497020718, -20029.2047891436, 2671.67806236893, 15197.2258902774, 13928.7912683742, -10942.3666944411, 21118.3072905004, -9905.02123907552, -10129.6146829581, -16052.036255332, -8411.49748617216, -5473.93189694599, -27188.2892358938, 1447.03927548939, 1192.42814958698, 5941.69655841085, 19999.4035386230, -1792.17884052219, -9468.3952937043, -3644.27470200421, 6703.92065351086, -1470.28633865411, 2374.77518553993, 3405.751980 [...]
+18925.3086863413, -17236.0781649127, 16650.0873878902, 6235.41233902937, 1475.18143011332, -5804.11985589998, 1294.24451265504, -3061.03919755023, 11635.9443171025, 12501.4037603293, 1627.37287671513, 5007.39308332098, 9717.87104697755, 9112.36351947317, -3900.34695897693, 2973.1604853757, 1042.67698278401, -2615.43248554077, 321.253449562084, -3710.3536174045, -2446.13037090491, -24906.4522780625, 2714.56661284737, 3895.83648603703, 3625.79721243694, 5146.02282816619, -10792.6122994535, [...]
+-8313.10368065455, 7669.54711890237, -10431.3919835404, -1855.08531709394, -3251.16499731540, -22519.0612613001, -17873.5751509262, -5596.96446517115, 3553.26243929464, 17641.6099872733, -1616.44059573253, -5621.46593217296, 17769.4762090134, -9206.60482981022, -2663.01861334235, -1524.06526524291, -2887.94714490896, 3469.66005370088, -22531.5065298466, 14574.9421281890, -4317.65829229467, -861.226365642414, 8182.53208477944, 21014.9281355778, -20117.1140803169, 1453.62055862828, 3840.93 [...]
+-12073.0364774013, 2764.01927427792, 2190.79420322158, -20333.9821497156, 4609.79571452386, -11799.6787477762, -8551.45865182603, 10401.3842501181, 1765.60679464428, 9100.88498099612, 5394.16503085704, 2878.29728757419, 5366.85041154595, -3927.54742875026, -3451.16784220135, -12074.3447026404, 440.301931218512, 12025.4745283881, 9863.48547921814, -12641.0787946621, -15422.8961673873, 13770.9269704549, -17472.7558426343, 2341.98551814774, -2345.51625349174, -10269.1192726779, -1249.675886 [...]
+6403.5341474568, -5495.82148568112, -13556.0977132680, -14105.3389446012, 582.568638415379, 15913.9913074445, 3876.98098294364, -3414.14553469421, -5673.03349413901, -6881.15535926044, 15532.1221158632, -13208.6466613998, 6201.53790453508, 13405.5786822137, 11467.9584883408, 15328.9406543377, 14725.0207522746, -3402.43912019826, 7947.94903750089, -10408.2559873998, 1052.949969288, -1901.61416144801, -1995.64800491387, -9559.40412746538, 5737.78516643015, -21374.6175842642, -4471.18920828 [...]
+-7594.28771906998, -16472.0216328205, -14029.9835553679, -15334.5402062043, 2109.34836725132, -9100.2337539871, -4373.82898841701, -10400.2473672988, 2213.51689628770, 7909.06832035646, -6362.06758194715, 6761.94539097549, -16646.9838216942, 9650.94536662046, -21359.2705220884, -14164.0542281098, 2329.35707605467, -4876.65535303503, 7717.57508903473, 2699.95225715663, 13901.2442274127, 5282.05862466318, 7972.99487256397, 2405.07975271674, 25803.4779203914, 21349.4509551713, 14667.3178480 [...]
+15328.0114338024, 25495.7642755863, 7673.81057979097, 998.926514712448, -12245.5919572161, 7016.96855599966, -14518.6045031013, 4890.34392956722, 5560.92692690183, 6388.87505612981, 14722.4791636230, -10328.4162660577, -3853.66916442966, -7286.310334152, 22842.7729087224, -3173.39018432416, -15604.3911507406, 626.566571478026, 4552.08746392122, 9599.97544122767, 2527.86998011441, 11687.1601547555, -4520.43068905871, 29666.6288797557, -22391.3660364243, 1914.52241727809, -5826.72210411864 [...]
+-12169.2154436959, 523.769285672481, -6183.05072779205, 12839.7194471679, 7509.39052617431, 6383.70603749364, 2920.69884960875, -8898.60765824348, 263.755583774284, 17266.4070255727, -8901.40363027796, -12292.0300023830, 10226.2761887365, 10633.8586538023, 298.762609152623, 2979.19051265482, 12433.0829285377, -4472.54254499939, 17173.7285824610, -10588.6730434306, 4205.10172809967, -11662.3588552552, 8717.57333184774, -3793.30043308701, -3968.68010562443, -4536.76272014879, -1230.6109497 [...]
+-18755.0058604434, 8579.95868438166, 10635.4820469752, -7517.7138132557, -17984.3540790225, 4828.63023038753, 8348.12454137214, 2874.00888507638, 7173.55139213106, -16165.0054396078, 5686.8906594077, 6989.34484859451, -14622.3438107447, 10237.1364066256, 17836.8287405893, -14653.4547595736, 9639.69006543788, 2535.34058737507, 8070.27409940991, -12003.7619755559, -15288.3681778066, -16473.4345557102, 13216.8059017228, -10602.8657577889, -23290.5329664834, -54.8892837106462, 15702.91562510 [...]
+-3698.69038464183, 10036.6911416952, -10020.9751842422, 13877.4067095129, -11279.6445138184, 6397.1977147343, -1206.08486912147, 497.596388137271, -5647.66680076743, -1886.69615364288, -143.120073894037, 1509.82744563210, -820.994336874737, -9596.1240079627, 7487.85488387103, 12105.7975028898, 5468.48534569864, -16007.6974115765, -16969.7457297610, 7710.55729995835, 2666.92673293158, 10279.6168351579, 4490.79465044616, -14837.058662515, -554.726340412586, -3249.64700639798, -13984.391108 [...]
+-17749.5388056318, 2029.70864398996, -3110.43965073291, 7246.15068420523, -12770.7012538254, 4928.49750534918, 12229.3357098924, -13431.3124751608, -3686.85602294325, -1971.90043842235, 3790.84560415192, -2625.39472202786, -710.475663132841, 27141.959917122, 6153.70425922017, 5317.10620382464, 2397.22386385408, 449.898257524012, 9804.30224881425, 2704.43012207507, 2312.51742709390, 9911.4699424566, -4124.44477778057, -2943.35508081382, 6400.15841051196, -13715.7362037172, -5170.671823898 [...]
+-18487.1615107488, -5616.38571790237, 9634.72280146902, 7203.91746183858, 7422.6824821296, -7818.8707605418, 8269.37417691614, 9637.68637150225, 3220.56029083138, 11825.2396237999, -7551.24074666119, -7665.3176322476, -8294.10629635545, 1371.25032579793, 15590.5309340093, 314.966633865644, 5887.11028033729, 1179.50108936756, 11966.2681018619, -17685.2462805084, -14256.1803290326, -3758.19499944331, -3223.61804949992, 10205.3551655701, 10147.4725655298, 6169.64547311632, 18838.4422500580, [...]
+2319.56973180013, -8151.68337743053, 8978.86714611503, 1701.88424866388, 7553.87010668583, 13804.9017391522, 947.890381252575, 12995.7308519052, -26068.6990499283, -1096.90312100208, -2679.25911555101, 11248.0929947467, 3493.77211830056, -8675.86307831641, 1815.40257725277, 8426.83151043378, 7824.63864770473, 4214.15281384394, 2993.30879532845, 19423.9880473509, 1366.39542845116, 3916.17905643392, -3147.64619202361, 10156.8809117048, -10605.4142132577, -4065.55175532775, -876.33737208944 [...]
+6139.82834625202, 11978.7707432898, 13157.5992481304, -16002.0598440492, 6030.75360581993, -6113.40061112925, -6963.13766117125, -4290.38851725723, -3952.13543572483, -7559.8343791125, -20239.7752021651, 2214.02176362756, 3262.80720785004, 7535.76726931433, -1366.61332930921, -5229.83699883033, 4819.81127035226, -9536.3365708929, 16862.6884225510, 1015.64923925902, -8505.64308655642, 2861.16563884289, -11329.8807207244, -522.230325514619, -15533.6705775793, 1537.19669880467, -3261.118438 [...]
+27784.8211258327, -25496.8961388045, 14565.7133824085, 5339.67195391609, -944.496995718828, -20218.8622755186, 12694.3798406492, 2302.87783787943, 21927.2948428843, 4220.44081397735, -1967.00669012749, -7676.34092462823, 7110.78037773174, -636.727055382475, 2277.75042900443, -3551.03370592930, 2457.87091149655, -2410.42312651483, 11936.9714917226, -1073.20188790824, -1112.63440180495, -5267.58857336598, 3749.61465964466, -2317.4818476762, 9308.60499990833, 3913.50891555719, -4272.7329631 [...]
+14453.2029841621, 1973.45736759806, 8972.96311115186, -5471.66034668301, -892.456336754075, -4.44111285020727, -8052.18381668173, 20824.2482232917, -1003.17853543713, -12524.6156621257, 2044.50037239708, -20322.3859340120, -14941.5777766, 5495.21844346543, -16964.7065573803, -14494.9508964343, 11364.05987061, 19125.3433402016, -995.49350838029, 5812.06861811265, -1295.92458129854, 23264.2092402054, 12377.3022976314, -8853.39252459723, 4167.52979539385, -14017.7186945561, -13810.419751406 [...]
+-1725.30665279438, 5075.44261002958, -14323.8163814671, 735.341423903, -10666.2054371110, -7284.27164451260, -2739.34631427138, 5419.86803942119, 6283.86121407418, 9748.56904985267, 10749.1159421427, -14272.5978649708, -11771.6475387956, 10699.8536336372, -14068.6728844710, 3857.60430098825, 24533.2895135075, -14763.5402302756, -984.888802661217, 9693.58136479903, -7076.85576595533, -16159.4757973698, -24830.4877927826, -13143.2051443210, -4259.98178681863, 8611.52775149094, -15646.64417 [...]
+-2184.69388809168, -8126.02349024447, -18349.7079060461, -15626.5983570689, 18798.2862916604, -93.2271819505798, -9898.8267516395, 10340.7940814296, -26245.4955225843, 21279.5425417787, -5673.49538864543, 21272.2736176921, -14679.1857951386, -12486.4539424865, 4375.41597827429, -6106.35372485283, 15903.6452058009, -18057.1094943402, 4663.83692257819, -22432.9861077045, -163.306769140450, 968.40614189535, 15285.3649291758, 14101.6368512297, -1106.09885765533, -76.5618102526758, 19398.3271 [...]
+-8057.76846139324, -3189.09795221476, 3934.03977755841, -15429.7685525852, 11369.7705258318, 12837.7966635428, 2178.36988959942, -7210.32604097877, -3975.58978817017, 4102.91725877216, 7081.7855755943, -1996.92717850073, 8568.7317855853, -17526.6834497276, 5604.95243079938, -9921.9460341698, -13439.9962639903, 28942.8713362748, 16242.0344116947, 8609.75119796477, 5968.98742816911, -4736.00022816276, -14460.8540049671, 3034.01340256805, 12659.4880310455, 3038.28536085765, 2872.33242610595 [...]
+4523.1659895431, -186.426961673410, 15067.2111224673, 9196.2011912799, -5663.64734502514, 12739.5291936286, -4945.49628609068, 4102.48871055629, -13970.2674106817, -7747.45724476394, 1697.69261053462, 5642.67061457703, 7019.5496388095, -6558.09680870499, 18849.6764595138, -8220.44364066523, 14548.9760664319, -12620.1179207026, -11863.8577967152, 9569.5847368391, 16430.6751591622, 4213.22791078117, 9242.8208908629, 22465.2316896907, 4622.74479029937, 3431.43805782399, 11331.3242157343, 55 [...]
+15688.4689059708, -9050.78447044253, -20976.3447364441, 11519.7289210513, -3806.88670937225, 5013.08278967333, -10438.8581817069, 3939.82872016644, 5849.35392620746, 17458.3351054229, -11617.7843000465, -6507.07653257882, 20460.9962814474, 11463.0779683833, -8641.42377165598, 1388.91245574318, 11942.0306221325, -16297.5201009901, 17330.5365232456, 22512.5055430616, -4478.24032857292, -24739.0724235055, -1520.76391428522, -8653.42817637038, 23337.0427176410, 14793.7931622917, 2464.5961949 [...]
+-2339.3594995713, -7942.980604843, -12235.560540878, -12862.8644544098, 17347.3803032216, 8125.99335634954, 5659.27571239323, -9172.90189003072, 12488.4545501417, -7664.11114229676, 10895.5763602738, -10160.0555771796, 6389.32651277644, 6016.21310250928, 8349.52605316369, -4601.30087151770, 8966.1975971903, 7727.83090954106, 25158.1512784427, -2826.10990895078, 2199.33765831678, -5220.34112871121, 6448.74832872305, -9761.95602070466, 18134.1897168855, -1330.37616702836, 22764.7717975817, [...]
+-8382.154745327, -6361.12871923819, -2642.20160044395, 14217.6043858376, 9481.800972982, -499.446213391707, 15084.9745527882, -3747.5469279073, 2660.82517625666, 13242.740944466, 1988.33517290742, -775.45117287642, 8267.06938578735, -5081.09894112288, 3707.34219981031, 4113.93515857202, -476.378328615873, 15885.8836889151, -14825.8665612571, 4162.92511246065, -3857.57156821044, -5856.33612430699, -16257.4985701924, -1393.08567157419, 3185.43487227262, 4569.48495810427, -12239.3336777105, [...]
+-10734.7227140366, -965.974139359387, -15115.7110943000, -13830.5211588684, 6469.30001713564, -5098.23930200337, -3911.2066056486, -11537.4753862859, 4916.74728172073, -4578.60652243515, -8160.19090747427, -4247.83300041832, 6796.67064179395, -2331.23852626966, -1452.23291060948, 8315.51792217513, -14299.7240104371, 8891.47580444454, 32018.865485044, 3275.45308838208, -10128.1583604814, -8767.01286501251, -7538.97292871356, 19846.4347007809, -12384.3040597742, 2186.36362916592, -11119.24 [...]
+8329.19477808897, -7282.91391722517, 10203.0392450148, 7402.86096732243, 4499.10636947552, 9150.29115133719, -9324.7425535115, -10964.8487261021, -20848.2269875718, -12237.8951091888, 5894.07391908006, -4506.7503349767, 5780.27926296393, 7716.12624168089, -4932.50615244614, 9181.86525220139, 1523.80992530131, -9263.48928466346, -9240.48855318897, -10803.5282787791, 6665.29301830174, -21664.8652172958, 2940.96449743122, 3207.37977768196, -1421.84374759353, 19029.3856384477, 6845.436602671 [...]
+1332.46572950018, 2297.38153713431, 12434.0307094456, 3958.17823923535, 4634.28408076968, -3413.81599761019, 3357.38224088576, 3102.94649098358, 832.205986683457, -3308.0378065476, 1334.43705472089, -6816.86244068524, 21056.3850551603, 5769.49301332013, 16086.0673400696, 8727.52079010175, -673.020534543354, 4916.96927517003, 11204.2872610592, 1234.30432416664, 2822.76100841703, 14088.3366974754, 8787.5088254636, -5002.29993420177, 19261.0578362573, -3786.20880757285, -9157.70442986647, - [...]
+-3437.90340328047, -15198.8946425669, -10873.8908263870, 6338.02619958787, -922.046665554167, 13312.5325456611, -12031.9970167405, 12501.2053654130, 5513.60923635455, 10509.0001218889, -2295.44561374777, 24004.4155430521, 2739.28710262259, -3665.99107296991, 8075.64906223118, -17896.0011383455, -737.874109066905, -3089.49733629217, 9100.91006760448, -3407.22742222544, 1762.20879223133, 14903.6019843227, -5359.37199824248, 988.275291927005, -7685.31096726442, -15995.2857969334, 5837.94013 [...]
+24564.7738587259, -2075.06795334178, 2450.51768328869, -10043.5970179776, -9064.43985340359, 116.665045458613, -5808.1149164718, 9821.20355783381, -3532.52913290783, -9175.10902533637, 5158.56781375831, 7217.64652714136, -777.275956200249, -6377.32198520371, 21155.2679749916, 655.591766637272, -13165.3664198440, 6780.63088140039, -21386.7733812541, 6447.58570138883, -17342.9327207286, -11508.3708521522, 15821.8713196270, 10075.8162534947, -6300.23304034984, -15560.7248435414, -8091.64437 [...]
+14374.7779965781, -2121.76363721618, 12302.9326223675, -3275.95289458159, 1450.79249429552, 5770.89482533472, -11461.0724806099, -7597.90152993072, -14673.6040052345, -12918.1336694401, 6312.95352047767, -8639.98635814912, -11698.4182473592, 3111.37307340298, 9302.36870317086, -2807.87985010687, 6491.13510635404, 25949.2811230247, 5285.00258513191, 12362.6386236943, 2935.82532837678, -780.611967092762, -460.217374179147, -1624.10516050929, 8372.97043675193, 2735.18786866919, -2794.440059 [...]
+7348.79081436387, -5455.78250535974, 11060.4780671429, 4318.0344673306, 5311.82345725708, 1757.59455415222, -9270.41461676699, 6862.99953392814, -32197.2218694961, -9864.1152729741, -6313.46329228814, 1494.64776810514, -21605.5269323666, -5131.3981193525, -4740.724377092, -16004.8808023164, -2629.10170914597, 8112.8852513844, 11285.6294364595, -1299.99319390602, 3582.02094746262, -2908.15543718768, -22647.4214155469, 710.679649550066, -17854.3066506625, -2110.81903926631, 1056.4740510705 [...]
+8759.16409065358, -9885.53459929984, 3540.95260175048, -2980.11045527994, 2599.00206435107, -22900.4688462083, 4330.29146438233, 1328.09416697586, -4758.72572399564, -5900.48375514442, -892.43632109162, 12431.3136496926, -20008.8567579670, 2839.42230446179, 80.3008029773396, 4662.46989941452, 18066.6949239028, 15634.8444680223, -19497.8283336322, -8454.69214310817, -9523.95202957394, 7517.64877899688, 4862.03927939575, -14469.6893300380, -12518.6942698095, 4286.12933981304, -13968.961934 [...]
+1408.44289598372, 8782.1845714968, -6432.08133052588, -162.896596671465, -14963.4385123422, 3202.32680949118, 2445.63263154179, 5295.22471457304, -9996.60370742597, 9860.61990362874, 1184.14662868531, 3755.60331409585, -7027.82476882124, 6060.62438649082, 1214.00492624616, 1849.82456718816, 5673.1005475786, -11257.7188590048, -7600.16789198027, 6061.17431027172, 4678.87023616372, -11922.7151768079, 7210.93623981605, 3267.86352345176, -6976.99225196774, -15175.1097899923, 8464.15214924942 [...]
+7957.13923769203, 3274.97658242542, -5976.02800397169, -8103.1991005134, -8551.92042662971, 5372.51664728311, -1132.14170464660, -1002.92136623372, -5795.60621164288, -11440.9563277108, -9615.30018063736, -11689.6902370663, -7696.36619471512, -11132.9878069202, 20753.5332238369, -5882.29314585498, 10259.54066259, 9033.89256627678, 13179.9194951845, 1278.28365468782, -18839.5299252571, 7112.7959149018, -6059.20818982168, -4319.72326313722, -2169.9048287173, -9898.5215286492, -728.11909806 [...]
+12298.0512943676, 13455.9570395703, -406.918688154961, 5171.64216790581, -7308.50911673492, 11300.1479239411, 4579.30974591655, -2836.88249890232, 1401.12708463360, 17698.1548592952, 3587.89094476384, -10364.0318801353, -761.262371696815, 11278.9142717977, -11598.5922335537, 15753.0853518553, -20925.5302855426, 13180.3353345072, -0.629615038354308, -4481.27966237191, 13399.6350487033, -21573.4207313441, 22486.7117661463, -17355.8456598287, -7789.44241588174, -6953.49801525617, 6735.11675 [...]
+-1334.31244661455, 6540.27035965774, -3630.96936953556, 2710.95213371643, -8261.0721260759, -297.478319512604, 22499.4508828467, -6549.46266346478, 16174.2018893917, 741.153655221452, -4081.32233050196, -17272.3116833150, -2332.50239543994, -13543.7797069792, -8369.9075504021, 3034.10189117123, -13137.0591381390, 21605.7080310494, 436.433050426716, -77.3334662374863, 15536.7556813893, -11373.0316453630, 2005.18982498744, 11775.8667829385, -330.255603389848, -13422.7532190934, 12555.33887 [...]
+5340.50609123777, 12547.5712090586, 11076.8931954321, 1605.54067810081, 18856.1778079073, -12966.5141507661, 3302.54255469743, -1159.65970452220, -14070.2835373608, -25091.6162450751, 8318.70328447604, 224.482994292723, 14322.7302264053, 13706.2755644683, 20231.2466667602, 13291.2072824806, 16505.8046642899, -12581.5033397702, -5975.35698881844, -3658.79556457886, 10503.4055601811, -7915.83942573386, -1874.86035132681, 1434.99709686340, -892.224907514519, 4737.12948439488, -3074.97633573 [...]
+2571.56169458065, 2375.48569508133, -10250.0688060331, 10674.3299626671, -3445.55716166821, -4400.76147291829, 10036.4941050590, -8053.99753985213, -6540.0046175913, 2689.05442645629, 1296.35634159831, -7549.56339969035, 6020.49023988468, 6613.207423864, -3473.56690750845, 9559.34757907365, -5379.24747449882, -13845.5496202140, -17700.7616025158, -4776.14521924333, 874.709118523304, 8447.80127899809, 5344.09849664679, -2200.90555427225, 3276.54736738338, -2922.83227226481, 9722.226267000 [...]
+17394.5282154758, -18660.4884348156, 6523.24246618719, 4241.14804994987, -12554.5814394878, -8196.95876410751, 3620.42412804126, 9492.40625062049, -1420.52361937290, 16616.0781541368, -10790.0180555875, 13400.4226904208, 19905.9364512552, -1912.96434856765, 11237.1966973195, 12476.6995798691, -8419.40148418557, 29543.7186774575, 4062.10752806934, 12513.2463553329, 6265.50784823614, 11026.1210605009, 4246.37688156087, -9876.54807481653, 361.685700389729, 3654.64855992458, 2414.46426286116 [...]
+-8238.18288183001, -216.284980090429, 7291.96906063515, -10057.1314082890, 18710.5788053903, -15936.1168345813, 4963.47031746002, -23899.8612810232, -7601.82584065442, -6169.6264579, 4505.26299508888, -10227.8847837682, -7611.80839981728, -4466.2607616239, 10556.4527499309, -12952.5988230902, -17002.3540293043, 15884.2630712396, -3332.32744988624, 3105.38102432696, 2952.94118107348, 7130.21151188432, 22005.3622592493, 1219.11436712381, 13918.7629958614, -4886.63114389677, 3191.8733997948 [...]
+1402.14651072666, -211.233032301259, 10040.1936872854, -1509.7714475296, 17722.6136406511, 3636.59504012589, -13284.1910196530, 15962.9717339718, -13652.2981452095, 2775.07873051824, 7111.84501852032, 4129.94553132172, -3521.96393535587, 9550.39873938631, -4185.54998496641, -6629.70934079752, 21621.8586190150, -5804.15639798272, -1294.96920374981, 1023.52495111036, -6061.07255463984, 6834.477551394, -3631.5674353929, 6993.18204770781, -10670.6301160822, 10452.3578810841, -7997.7003786177 [...]
+-1093.18544870211, 10289.9376007964, -7512.49941223127, -15318.3143875477, 4145.80329284592, -7331.62174750463, -1389.00160703773, 20626.6949717778, -15543.6457497873, -14370.8139415015, 4680.65784301271, -3808.91833550447, 10990.9286318541, -8013.64450142558, -3377.40284564387, 15121.8950516891, 5693.06986334379, -19175.8904262266, 5334.82946420261, 8046.76960327969, 21.5924381039454, -13406.7973172010, -14097.9805608691, 16800.0256640516, 8595.45549142406, 7475.62284549507, -11420.8484 [...]
+-4791.2962978966, -20869.4655573679, -8597.96036336491, 11167.6608150207, 5056.46494699153, -12017.7971431120, -5473.1467532724, 6695.29697282063, -7943.69982089992, 10396.5750899132, -10260.4377055042, -2877.52433239381, 7778.17932195165, 17350.2454531490, 23063.651372909, -814.14306573847, 9288.78589926647, -2080.9055368762, 4122.11775077987, 743.352465268036, -7547.81524801371, 655.625391399961, -13025.6120670887, -2077.75289541995, 13229.6837891537, -24180.4702212527, -12028.26185978 [...]
+5451.42762062874, 11339.4188966078, 4450.98220118550, -14664.1101664399, -22588.0562044254, -8782.11079367878, -1996.09131130431, 3851.30486578908, -4140.25702320187, 6756.83607909454, 15467.5666805891, 2055.06632525211, 3683.81496668765, 10536.8165737604, -25392.1842591163, 4652.39366119599, -598.420135003948, -6731.2412521569, -7781.49835147643, -6374.23018311761, 14083.7236429183, -12447.8543672218, -5829.3335814064, 6579.03218105743, -870.55817121321, 14952.6999962986, 2728.745179155 [...]
+6149.14464686487, 2919.20414707069, 2646.03241745896, -12970.3087016556, -3921.11602095744, -4709.59762684048, 52.4028379108259, 7406.36034533427, -4910.96845351053, 7846.6563782129, 4797.77380993568, 13527.3252596006, 26940.1481097399, -4056.33821063643, 8273.58963147657, -14575.9424040589, -4366.21833979145, -3712.44439024236, 696.492046633223, -3427.82902496586, 10979.5793803648, 199.984437379812, -14347.0114899594, -6093.3048878094, 7400.68773044884, 12474.1850870948, -12625.50209646 [...]
+870.173360171281, 6960.30456499343, 18458.1615580830, -7366.9321454719, -4722.74833517248, -1764.50143951859, 9424.79830706902, 235.381411084355, 3115.76232262189, 11382.2273254489, 6121.98024479014, 6764.93211292946, -25234.6826085369, -3986.24086616985, 959.73221273119, 11172.1466495437, 6916.83386068587, 7233.22965266813, 15198.3612638218, -12403.5709924817, -20996.2493663083, -4909.97267925864, 10264.5836035706, 3834.19645414586, 6654.95206436396, -4635.28551225581, 6285.83245378119, [...]
+-1585.81072956663, 1050.26449268737, -310.589893549741, 16532.1747491741, -26292.0145763335, -6781.47560304824, 6798.83472952854, 4042.36891582918, 4952.61952294971, -588.264188061927, 13508.7889892979, -12619.6451597910, 9206.2473949106, -1509.68353959869, -9457.03140132092, 12400.8196468633, -2839.18425341581, 5961.01681690717, -13251.1972623259, -3229.77051888078, -9327.47334120202, 13828.5272388422, 3616.36189701715, 9177.0293946986, 7674.0376060299, -6744.53219835702, -9004.95915875 [...]
+-2867.25201120895, 5537.49197006231, -1165.86406013457, 923.955679919836, -8278.30265993827, -6878.30867709288, 2149.33423092754, 8509.26508816816, -2115.63150143023, 6391.94491327279, 3980.92031527272, 12179.0380487818, 14191.2439941056, 9916.45847303672, -6793.72863531957, 12826.0149137418, 6801.21106469022, -9106.85388141205, 12007.4644664021, -8785.67778825209, 9228.01225168307, -1195.16311983343, -8693.4083021153, -16872.8154650196, -2089.02206644329, 4058.25481168462, 2844.69954188 [...]
+8122.59942031461, 1036.64989533697, -1841.31795601375, -6468.71072445937, 1144.95386851747, -6898.35120562062, -6522.65483305367, -1922.90144612318, -11868.6665109465, 3628.05229900272, 18109.3487024763, -2724.38335518756, -9264.86670665884, 6152.8739280167, 15303.8511709092, 19408.7587142275, 9078.09225372883, 10184.6710177425, 2738.13524251607, -21581.4318074948, -8346.9578835662, -5597.96992421553, 646.111278255467, -4727.57464366776, 20985.0505856699, 793.12026463303, 2648.9394979515 [...]
+14680.6889827044, 12414.8124989749, -22141.8474966610, 12685.9277094182, 17998.3991383143, -6745.47729086409, -12953.6514959078, -9152.45461753173, 5554.39050586149, -16382.4999109415, -5207.24612621083, 6262.70501150022, 6341.84570824446, 3491.46299895382, 5670.14277610517, -7909.33162255962, 2242.81658286686, 5173.31179663535, 3148.33578857185, -9965.08379776903, -5388.90326017284, 1954.05432836792, -11165.2731445241, 21797.2053522149, -3706.74027828368, 784.353695324618, -4637.5885259 [...]
+-8707.06012631616, -2455.80291500762, -1424.40090769177, -5182.89295416087, 11611.1987966678, -1424.34097199963, -2033.02253896361, -18622.3664297760, 1399.76291547982, -8657.93135073558, -1694.55196248983, 12751.2507682732, 1607.84624282931, 15983.4317626514, -5134.30110202185, -464.590311282627, 6769.0487407279, 9309.04709938363, 3804.91523940686, -4435.11492214255, 9449.80413850764, -10285.2741847586, 5909.0193188647, -11357.9590602495, -4551.49204051461, -4378.01713465494, -13877.772 [...]
+-13573.1416768268, 8269.0781818255, -25158.3184615304, -1477.79595426449, 13817.5762648757, -9305.82463186206, 13371.3996542715, 5125.2689246578, -10302.8819612115, -1023.53029404331, 1932.3846936649, -1314.42163551838, 3956.89446113356, -12624.8313018058, 6045.83685827672, 4894.24205980846, -1915.51333118174, -19198.3778348153, 16326.793732061, -5732.31880042781, 4627.78598945078, -2858.24430206945, -3112.15922203257, 6902.44421934362, -11584.3685420523, 2527.81101200979, 6628.675574694 [...]
+9680.8531844459, -9019.2552450294, -21488.2009698305, -17459.2360100109, 5254.23293070175, 8991.87686687666, -23131.0444633735, -8049.96636473338, 8161.48899759514, 123.674819913845, 21700.6069335059, 9404.38617085524, 15476.7230154925, 6460.78218282586, -1750.21585133108, 5557.51792975371, 19078.5679404864, -14009.6762053869, 635.004767640901, -9208.88231309226, 1052.84438750167, 13498.5070079300, 6041.27560041442, -2469.66501088662, -6832.17181610464, -2849.83999629242, -8856.275658684 [...]
+-8108.7761714134, 5051.29612350411, -10313.4064399417, 40.0573568716957, 18925.6624848960, 7214.55674919538, 13449.6346068075, -1257.42746420855, 1339.16146617833, 3505.57739364257, -1832.37536695732, -4278.23779796568, 1235.08368875852, 10116.0847839834, 2755.35615672383, -3095.01415301939, 6114.70447644131, -18220.8495824216, -3731.65800600948, 17237.5961408082, 14183.4151937203, 5533.72997160350, -20942.0098815219, 8716.44824434553, -3120.57345060258, 880.428158534969, -19093.48995150 [...]
+-1903.74363053652, 13464.6659125176, -2588.32476794848, -11126.1522439495, -3953.20464296604, 9578.1189568280, 13405.9300680636, 12309.7324274083, -17529.3472968451, -8992.04379525032, 1378.24319502404, 16403.6566328085, 15081.8475730980, -12010.2683063153, 17369.0976986168, 17958.4219652289, 20199.1646256755, -12519.442878104, -6543.16525944971, 5488.37461961139, 9885.5322467597, -12581.4872819190, 14268.8379132364, -7945.76100577485, 1561.39259054027, 18436.5273838856, 835.585070871726 [...]
+7742.81456562816, 8348.62706726283, 10018.6467666975, -6200.7697068176, -820.427857662738, -19320.0719991882, -7592.47235774002, 2185.83629077375, -1697.24013047498, 19415.5536905080, 1418.07701968731, -12189.112827141, -2257.48879271114, 3424.50131096443, -7479.2051739676, 8351.65867480534, 12588.0270775320, 3017.52841316601, 5849.73259746271, -8914.83949521208, -8314.72600596726, 17465.2555648754, 11309.8056668150, 2694.34941397672, -22020.0031571689, -353.875614770615, 9892.1916202928 [...]
+499.162492953856, -5335.19523285458, -2908.49911386011, -887.265956320791, -8199.33491790568, -4084.62305293396, -8470.15341707081, -21075.8284578880, 4399.75444728105, -17396.7358288171, -2180.51931667469, -524.535616297178, -9539.50930661585, 13259.1398984719, -17238.813279428, 5698.27398114562, 8410.21092278627, 6938.7796398726, -296.65044572318, 3791.55597805729, -3901.54171842998, 9941.39603517978, -6336.09921845875, 22433.1338613820, 4513.89094827974, -4530.77733474143, 11163.64043 [...]
+-2446.29729537955, 24638.5801913936, -18131.7441359773, 524.210428864929, 8739.56518548069, -6138.68062393817, 880.966340173836, 13968.4617737262, -968.449704532704, 5214.67282970117, 1604.81186056803, 15931.0021727921, 1458.34066366955, -10.7528623443427, 10175.0429731329, -1588.71013054772, 14677.525376797, 5779.26252883833, -7667.86387515334, -23530.7703006624, 8703.13995241938, 5332.8267585551, 1189.19705746717, -8231.1364388531, 9863.33609090578, 485.857632980555, 5727.56314493289,  [...]
+14149.981628185, 1813.50759933254, 21464.8080903026, -13936.3904747668, -4016.76632703281, 1453.51333087843, 15389.7866699984, -10810.6478396529, 2697.52248816318, -2618.02796555883, -10134.2795188956, -11153.5322578008, -10006.6034979213, -12227.6778918416, 10396.5845974841, -5090.56589175311, 4039.33349861336, -2738.30902688679, 4048.9840429216, -5652.21561621134, -6991.60038595148, -1305.71245229254, -10318.4726872081, -3944.52715663267, 4640.65541151596, -8371.402919595, -7286.026314 [...]
+-3747.42553807461, 3848.68952961567, -12795.2266021709, -1172.07731555008, -3312.72221058407, 6239.07449786619, -1898.13704905728, 22380.3266238657, -5514.07211578047, 2694.95745960434, 5181.14241207722, 13227.5915280794, 16757.5220223717, -5616.08182176591, 478.231514480881, -6408.3382836002, 14532.0381489016, 15725.4342712646, -3482.83168584695, -18316.0867629972, -6237.95692769941, 7767.21704453006, -12167.8794874429, -2435.38787471398, -3316.17415504247, 21481.3700852766, -12572.1024 [...]
+5930.86605049723, -10232.963734385, -10500.8077770670, -1119.78485889428, 9929.47189292636, 1222.38816706342, 9321.82150245617, -27621.004284061, -340.280605958103, -12082.3399176575, 18712.1205077998, 18595.1519323452, 24812.0629811865, 6277.78485897626, -5085.08482586716, 11691.5543307902, -1393.14515306988, -8711.44265862037, -15245.0659466197, 530.42064211529, -11393.6210027641, -5946.65362073309, -10273.2542767089, -4280.40179617457, -11228.0907195044, -4010.35664082834, 1152.687198 [...]
+1352.03838096133, 9825.64829697775, -9490.19598542457, 17017.4606318522, -7901.48218280634, 24975.422392501, -282.076712829217, 16156.7765890383, 15055.2938401572, 13489.8776307939, -4164.61272730232, -12252.324502415, 2482.56333339756, 15002.2461725211, 12814.1638899810, -10143.5812581871, 4123.11003812767, 877.134291163007, 13512.5367253923, -4143.15744226026, -4046.40740554801, -8485.5151837887, 1085.92249920054, 12706.0410426215, -10994.2708187817, 9138.20076702297, 12724.8438812764, [...]
+6178.87710045174, -7290.21275139985, -17206.928573547, 10977.3876029831, 14915.0630264116, 6430.56441252111, 11189.7910985560, 1959.12163655427, 8833.91034676727, -5669.01871868972, -3753.59934262085, 9814.56997174558, -6033.6238034536, 10042.8547244149, -5612.07343245404, 17953.4944773377, -12356.6288364569, -12114.4710108544, -1223.23455212241, -19232.3010274457, 11995.9347475766, 4722.20214010961, -12868.8034609628, 7393.34147043082, 21115.5382763536, -221.89843279481, 141.93078513249 [...]
+19616.0335714434, -1598.42345981719, 8215.31013233977, -5885.4724402281, -3058.69280032529, 15933.3297118756, 12591.9599111168, -1817.50428857891, 14331.1995174765, 18294.0571661354, 8326.7814641654, 8417.89541019886, 5815.80401674772, -30232.3422252395, 3228.64544528975, -3119.62204582133, 8872.11318658863, 8927.21084456249, -7967.20308162453, 622.073299616128, 4344.62619720144, 5473.71070787955, -1378.99254040802, 13948.8345045135, -15013.7441063496, 11026.8269941341, 7221.6490156492,  [...]
+19297.1219826014, 1525.34870245464, 8146.86381006694, -10811.5263175077, -3552.79105149626, -3437.44836553505, 22878.4459844581, 2529.63420407902, 240.829183856598, 1534.61385807804, 5497.10485346407, 10555.9147688131, 11047.9413114377, 2185.05164045392, -821.362932984686, -1037.99083837386, 873.83041817599, 11448.2791495514, 357.885169789797, -14108.0454576156, -14314.645010039, 18120.1679259895, -3836.93419070033, -8040.57561129296, -10656.3872750737, -8336.06193175646, 9088.422838918, [...]
+1596.75298442794, 2571.26964915778, 7628.91023763226, -5661.7301077477, 3835.23833320199, 9176.73712447676, -82.9415468787401, -3112.543781385, 11613.6405832768, -17980.9338784586, 5630.09170255668, 3453.53027457, -2950.36243974644, 25834.6968168648, 6299.35440754674, -208.537958255283, -6976.7959685937, 3740.99381103420, -1157.65677108975, -2386.23830948676, 1162.06315048246, 6278.05383646916, 9115.99173937638, -6307.16648351315, -6630.71186200316, 17941.3076235093, 11634.7200793692, 39 [...]
+-15407.7556540822, 8004.12710402016, 4838.10612531755, -11204.2094989908, 11526.9847965256, 7085.04474404985, 2838.08786643185, 2904.86497324621, -6817.44156706266, 3883.74360501529, 488.547463468517, 699.748000770016, -2833.29275041196, -7505.77925965498, 2747.54027941363, -8687.57953078989, -9425.15831579333, -5286.80644507134, -8651.59617447997, 5966.3831276732, 8638.14076272292, 3361.22518816628, -2739.55775828961, -5718.97363285607, 6189.32957061673, 14476.5252667979, -13842.2496950 [...]
+-547.376596230633, -13632.0251862393, 15031.6843837798, -21372.9595817440, -5144.84490983775, -2294.91751715198, -16227.4752078538, 4885.95713869583, -19164.6363969031, -13343.0188922776, 2779.32132949581, 9334.56160370779, -9461.9418593066, -10643.4191593911, 7678.17350615184, 3113.9199500606, 10425.9662914243, 3106.18873957861, 25680.1171272414, 12124.0322678322, 9582.13586002731, -8831.67638316781, -4285.80220135698, -2068.86534540428, 1940.07351911742, 5692.94983040935, -2124.3405315 [...]
+6387.71896894504, 1174.03077291784, 3348.90257103928, -9075.4277567119, 5386.24347386883, 6153.64005616867, 4051.57870867174, 13479.8979620965, -7076.4566951149, 3281.32447007392, 4140.33118498744, -12646.3857296335, -15103.6650743244, -4343.77364740812, 12957.1511420164, 20706.6005647054, -12554.3966491702, 7252.71147379896, -5887.16898019051, -4177.17599588598, -8141.3397948805, -6837.69310806854, -8054.6567570843, 13445.6870841029, -16540.0296966512, -14750.3187909660, 18.527265380532 [...]
+24102.3380409153, 22539.159073794, -1626.91910053914, 570.976940551568, 6000.63232886786, 9324.29251351043, 7644.70883551903, -8540.74631336772, -16747.2744569160, 21183.2195591192, -88.0485065332465, -1476.47704097697, 1162.44845697916, -12128.4141668030, 8108.70777431862, -7972.75855157866, 5166.93030173073, 12381.4617133338, 790.251320901392, -3776.22114894905, 267.141041443248, 14277.8023966700, 3099.01852017088, -1759.43954778463, -2437.19972032214, 2203.67148438419, -16503.65259786 [...]
+4594.62866986987, -15169.5451787126, -4362.05437016344, 2583.01440454623, 5127.65378562239, 3142.01262674569, 3351.50768795731, 4688.90741371809, 3330.83343819179, -14000.6071589519, -9291.07176594588, 13617.2317120551, 568.203543620507, 11897.8913620738, 4890.2039901981, 2436.22467255119, 7657.67961822862, -8288.41378322289, 14301.1728967365, 8593.32389702003, 3609.68536281701, -16344.6580918691, 5068.83341876966, 19065.4610550503, -4195.82214999446, 2131.72831770264, -3811.27566845937, [...]
+7294.48849917043, 11384.5266804831, -17937.8487755861, 3756.76791776286, 10631.2420900374, 2043.69590589162, 11308.3085879061, 13627.8613984081, -1917.10609366101, 1498.18229981858, 2907.63640771586, 112.922875714753, -8194.29049533099, 29.5525445245867, -492.444468321699, 10579.8908345331, 10095.3091241569, 48.7469206219277, 11674.3725060184, 7211.09630401027, 10953.2537150696, 1700.54822715859, -10211.3535250699, -1292.50397157766, 11319.8875955786, -2698.04717268383, 4383.84913505775, [...]
+1341.78606311751, 412.553012956788, -3324.95052186621, 4334.7449503077, 10169.3478059893, -7267.41157384354, -13164.31062202, 5321.55556934208, 15356.8087355698, 7388.64321053067, -52.5991811067553, -2099.98422707884, -4475.24632468798, 7558.63518231627, 7836.74002061796, -12179.7007742993, 11677.9871013435, -5462.04811821025, -8759.79938363689, 805.34304905866, -4928.33611315770, 14017.0853404559, 8344.55648124063, 6398.41237322935, -4613.74518630331, 2566.99935325764, -6942.8297595063, [...]
+
+double y2[100] = {
+59222305.0599619, -60485686.2745677, -3420158.85320719, 48274230.7468772, 26299560.3743166, -35330795.0269971, 49044489.5345209, 49242047.0143661, 82124459.3266337, 76892180.6657918, 30070295.8627113, 82669832.9086654, 88496271.7849554, -87834349.3299173, -76351128.093263, -6301557.21526601, 61657410.0881203, 22388628.7181635, 71836988.2817706, -47445468.7706105, -7128221.87136625, 33898094.1990993, 65898232.2541901, 6003991.388132, -13076115.0017139, 12341031.8297821, 162523651.688945,  [...]
+
+double lars2[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 90.33902020867478200, 122.70798506974135000, 243.20530461583570000, 246.40231341803522000, 405.80632090818909000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.35874943415483800, 108.87299898439686000, 125.35798573060281000, 157.24553687756946000, 202.51882826967875000, 278.39172144009297000, 338.33163700212924000, 352.99375315154583000, 353.34330940607066000, 361.31088139914101000, 412.28818144063860000, 431.15151999575085000, 496.64461352688886000, 498.33207609597059000, 555 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 21.468485 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -109.66767836674514000, -126.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 107.34513286933682000, 169.53219223222445000, 181.55885814462616000, 181.90083238313545000, 188.59198981507120000, 246.66071196901086000, 271.47100854877431000, 361.98945197785207000, 364.52809459270782000, 472.75205507 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 328.06190151981588000, 381.29503088332945000, 748.46322696054222000, 788.71308231663465000, 913.63963503026889000, 964.50794243408802000, 1138.46568971196760000, 1181.87404537410910000, 1238.81212789135880000, 1253.59384474984810000, 1277.27188725215680000, 1313.36638676770490000, 1369.68203357772150000, 1402.42175312007630000, 1408.71279115982630000, 1408.86472858486600000, 1411.05171479862290000, 1429.31865495236680000, 1435.10470065274940000, 1461.2478925588548000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 45.91288168902228500, 113.88157849905518000, 218.61206693712768000, 303.95186182918445000, 322.29384006850057000, 322.83930087781420000, 333.71183299383858000, 426.75185475324486000, 460.56755111990265000, 578.51590637552806000, 581.73791461549195000, 714.16584 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 13.65814964925465700, 14.07288967622387300, 24.21311513140698300, 105.13005453803142000, 133.64751884535616000, 225.37347132650206000, 228.12484200861039000, 329.182512445046430 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.99221268716260191, 51.21183990305507200, 58.94594 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 54.98394235372808900, 226.42873061215624000, 285.95446038232075000, 459.06025986696545000, 508.48772331972214000, 578.16284182491029000, 600.58747355493722000, 637.55592246591880000, 693.05635901570759000, 794.28984346310392000, 858.10733180169620000, 873.15588575956087000, 873.64673331311747000, 886.00445499236764000, 997.05704863812650000, 1036.73683715995120000, 1166.82453634088730000, 1170.42329394595 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 19.81425179011610600, 49.96008027663264500, 94.65084880797921600, 173.94816060751035000, 253.52991042387617000, 273.91422388719900000, 274.54695928371342000, 291.26589742893856000, 431.13983955064771000, 481.60302165733526000, 656.63997232403540000, 661.54932151673870000, 892.28446 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -76.13223476380504500, -352.65448557904921000, -422.24473284327632000, -521.92622394529224000, -548.29704612285946000, -582.65683919829701000, -628.37496354720770000, -691.99824662369736000, -732.20835472779970000, -739.92955401905442000, -740.20439847671435000, -744.30267328873242000, -788.52927314268481000, -802.86096879783838000, -859.98611119919303000, -861.48 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 219.78535200881655000, 276.26887679027703000, 373.05235715851296000, 394.38706182485328000, 428.03276385690225000, 491.44454585018707000, 586.10030346716326000, 648.66705295858117000, 661.20803126439898000, 661.60636306945980000, 666.93265758771645000, 728.92786057659407000, 746.07410358236871000, 814.63289463586318000, 816.45921714230224000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+130.24806091415982000, 455.92540165373339000, 517.01098785762952000, 889.57360690614723000, 929.94674058947317000, 1055.60460066310880000, 1104.35130195979010000, 1265.68972835711910000, 1303.40933734715370000, 1360.10934851704500000, 1376.36727641609240000, 1401.71922409453990000, 1449.36064816020830000, 1517.27264751904180000, 1573.48684890469640000, 1586.06312035100770000, 1586.46715716143330000, 1595.83002323959230000, 1681.30165971360200000, 1708.32086146059940000, 1805.659654918661 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 18.07096289994384400, 161.44622659960598000, 213.19922034244138000, 394.07517914880526000, 399.04163861298463000, 631.14230458242935000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 19.84993434521544800, 106.32368456227741000, 108.52687483999416000, 202.59718384305160000, 22 [...]
+0.00000000000000000, 0.00000000000000000, 61.45289176755488800, 486.75385617363412000, 537.08032155154910000, 725.01000503474279000, 787.79674684952704000, 983.95328708018883000, 1047.24724593139900000, 1128.04129036137310000, 1151.55639076861280000, 1184.37244669415350000, 1229.53964360633970000, 1302.85577393681770000, 1348.68594588403580000, 1360.42976458299470000, 1360.72461056471890000, 1369.70127786511650000, 1448.46341163006970000, 1473.19208937836080000, 1549.88364583128960000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -152.44382657824016000, -194.72680177882197000, -298.98674030541719000, -327.87800350970269000, -350.77967283072167000, -355.93652216157386000, -364.65306553309534000, -378.69379562382727000, -395.14654101848265000, -400.31578925277557000, -400.31168467168305000, -400.25876034526470000, -402.71760451298024000, -439.00016863597051000, -452.41962644135413000, -505.88121569495991000, -50 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 62.64191467219561800, 171.69119193422435000, 252.09734024022075000, 268.65738836953670000, 269.10126544748039000, 281.85728451679194000, 395.72632739360023000, 433.80365969045374000, 564.52529178160137000, 568.13235633119143000, 729.5210282 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -364.07521181431974000, -413.17329809410626000, -568.02741676761377000, -623.94424615693686000, -789.27882884793200000, -830.50263687486631000, -892.81661061817988000, -909.76048321175517000, -928.02296192003587000, -957.15517080354755000, -1001.69918045839290000, -1031.36974596696720000, -1037.82880938568180000, -1038.06579362433900000, -1045.84187470679190000, -1102.19772925724670000, -1124.97765169471540000, -1189.24555291 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -0.32803343440700417, -6.91709934833832210, -68.25005631288942700, -89.83612196025330800, -160.69601720538077000, -162.49008064270512000, -235.1575204396349 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -104.09056725792594000, -106.76099845864626000, -242.72145512723961000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 66.24180220580902300, 85.83034410500965800, 119.58729440650322000, 181.19787318365778000, 262.49172483628990000, 321.14345173253270000, 335.15115485180064000, 335.58843035151040000, 350.05543079783780000, 460.29766289995837000, 498.03004458242867000, 622.26463554217833000, 625.71935567868320000, 761.69 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -105.62047293524826000, -126.57839370687697000, -127.18973763276276000, -136.50659193393361000, -216.30795509399530000, -244.38853657830381000, -343.97866704147526000, -346.71385702428626000, -470.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq2[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 959.66593451659242000, 962.24470945807161000, 1004.10042119294090000, 971.97115224759693000, 1028.2716881750464000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 975.83967365189312000, 1008.90765566803550000, 916.54200500427271000, 1129.56696903780020000, 1027.21959568823190000, 1089.61739103553080000, 1206.94336983192280000, 1294.52792284762810000, 1098.94417897086280000, 1090.70289810357300000, 902.83964903967046000, 920.39995687224632000, 910.20879258987293000, 881.3057657444300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 566.60928 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -537.91495248923650000, -546.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1255.06895953494950000, 1070.70812627039390000, 953.85644388540879000, 911.32931864463171000, 801.13453321614566000, 805.45250461057844000, 914.96255086655003000, 933.57927509420063000, 940.67914334704471000, 895.361676 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2589.65975253239870000, 2295.08977789138540000, 2186.32823203981980000, 2082.77922356951190000, 1954.62344549393490000, 2147.37285411577840000, 2216.41504312203600000, 2115.42180989337110000, 2021.02741544246960000, 1963.03076064889320000, 1999.26737980303600000, 1970.86577624768280000, 1971.80350783791410000, 1876.86527305819820000, 1812.69453683151460000, 1732.94611680930230000, 1611.25954302338120000, 1605.10031254639900000, 1585.17430823242080000, 1626.3322871995 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1445.89742966269140000, 1352.00309995403750000, 1338.38036705200780000, 1540.64274511561260000, 1500.13195539575530000, 1486.30311671078490000, 1329.03865698589470000, 1322.07034322495700000, 1337.62738551458280000, 1323.31527502850300000, 1312.9804359878015000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 890.72217359695446000, 898.71025704912142000, 952.50086716255942000, 883.78885653870748000, 873.28991010481002000, 804.58825858647072000, 852.55503739423955000, 723.808098926833 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 226.17726904397423000, 247.31719002027873000, 255.3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1822.76316747309530000, 1655.03814221178410000, 1670.13452614341690000, 1531.73041998310490000, 1571.48348319877910000, 1535.35950962948190000, 1676.84009880973620000, 1764.80508074087700000, 1704.05536543327640000, 1876.66851356160330000, 1782.91042187709900000, 1839.50532750835620000, 1920.62088416336560000, 2017.29307658748210000, 2065.70942428884380000, 2065.89052875986270000, 1988.27928244137090000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 970.78373763532750000, 969.17256519191642000, 908.74034773825122000, 1021.78738452123420000, 1406.77880911605690000, 1582.90178447735550000, 1624.16681514044900000, 1821.80242995208660000, 1777.13830417726990000, 1790.43989024122290000, 1761.93228492101410000, 1775.7379314160537000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1846.47124830953730000, -2066.15667869288840000, -1918.86488292469700000, -1891.35039101773050000, -1813.94398919976920000, -1630.36235467864160000, -1461.17883258631330000, -1372.25226434858470000, -1314.90806910142490000, -1235.74972688263030000, -1326.44556559524200000, -1119.47956943058330000, -1214.11916212484930000, -1174.57458018151010000, -1220.7098355998 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1581.71077237228680000, 1491.01353798667260000, 1702.66365735467120000, 1418.32949185542470000, 1453.96407589339240000, 1646.55705623317700000, 1598.15055152383390000, 1555.34521864637260000, 1466.53241118445640000, 1511.24511615767960000, 1154.52871616263110000, 1325.50394023435050000, 1190.78714122258450000, 1247.55579705012700000, 1230.9475 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+3004.96696470083360000, 2701.08453329286520000, 2713.11096155281350000, 2348.56367699896420000, 2227.97638202916690000, 2102.68222469721330000, 2237.88149918714320000, 2265.44199657537960000, 2114.61391107622740000, 2139.05401227474570000, 2156.65378427090760000, 2174.75575992473520000, 2317.19945068026120000, 2243.38120686572890000, 2388.10786425631750000, 2393.65386464791300000, 2448.27464391062220000, 2452.95434879592180000, 2503.79003544721630000, 2409.10360899743860000, 2420.3174155 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1672.37870995824640000, 1541.13769648941090000, 1555.48925126059840000, 1536.23862544286730000, 1526.19156201622310000, 1537.4848022418 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 534.68718450238566000, 652.37279586305669000, 608.54620866970174000, 569.93744312801209000, 6 [...]
+0.00000000000000000, 0.00000000000000000, 2270.75794032273010000, 2152.27222045311870000, 2155.11780959527140000, 2290.98420156930300000, 2247.80667448376150000, 2199.46003522767930000, 2408.45830522648110000, 2237.98974493152580000, 2280.14520556434350000, 2185.00602775255170000, 2052.30778814016090000, 2086.74478138382030000, 2012.82810720822750000, 2114.56419341340420000, 1989.62887852061160000, 2191.47100535753410000, 2206.38664958455460000, 2114.56672722555140000, 2034.1618937420935 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1422.72265862800550000, -1177.95290618268840000, -945.04553952515187000, -949.21861333200320000, -665.40276973452194000, -603.43546427090564000, -630.43960697752243000, -634.46050762748723000, -571.05771089419534000, -475.22529861919185000, -400.04810721045260000, -287.37156897662800000, -627.81269092221510000, -788.14508341765111000, -800.47300712113099000, -843.47098400477455000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1203.73047956790470000, 1337.63556639078180000, 1417.29290575543220000, 1332.06808616182660000, 1215.88774404892890000, 1449.60807260850490000, 1491.48122323634170000, 1421.39529158711340000, 1389.98308506549440000, 1386.76433351835360000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1789.82780116590240000, -1991.71738211320640000, -1858.39065037301430000, -1924.20483733509240000, -1813.79374294020360000, -1717.06913407300390000, -1748.88588332878020000, -1722.96836909199330000, -1484.88602646177540000, -1487.82909099078480000, -1477.95944349536420000, -1461.33700699470680000, -1452.60037789462130000, -1543.55139752571970000, -1757.70384065081090000, -1644.50670079984660000, -1715.80845357728300000, -159 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -700.02088908839085000, -610.11366655108816000, -658.45338262983398000, -649.70249160795390000, -608.14952452226044000, -569.65709379275222000, -518.9205532 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -761.38323241135356000, -712.82178382395693000, -773.64082739718140000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 976.27157612070482000, 1025.96706062904350000, 1148.91081038406150000, 1303.49956666018620000, 1131.67776065513020000, 1171.08756084756620000, 1234.66190700704210000, 1268.29379208549900000, 1674.43814618317400000, 1521.15197854761820000, 1476.67487480909310000, 1406.75921124987240000, 1409.77640181516 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1636.20624634422870000, -1472.40039724194910000, -1431.18174705405360000, -989.41876567805093000, -984.23163451021730000, -972.69972908763259000, -972.85277157884991000, -967.47180377783161000, -95 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso2[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 90.33902020867478200, 122.70798506974135000, 243.20530461583570000, 246.40231341803522000, 405.80632090818909000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.35874943415483800, 108.87299898439686000, 125.35798573060281000, 157.24553687756946000, 202.51882826967875000, 278.39172144009297000, 338.33163700212924000, 352.99375315154583000, 353.34330940607066000, 361.31088139914101000, 412.28818144063860000, 431.15151999575085000, 496.64461352688886000, 498.33207609597059000, 555 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 21.468485 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -109.66767836674514000, -126.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 107.34513286933682000, 169.53219223222445000, 181.55885814462616000, 181.90083238313545000, 188.59198981507120000, 246.66071196901086000, 271.47100854877431000, 361.98945197785207000, 364.52809459270782000, 472.75205507 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 328.06190151981588000, 381.29503088332945000, 748.46322696054222000, 788.71308231663465000, 913.63963503026889000, 964.50794243408802000, 1138.46568971196760000, 1181.87404537410910000, 1238.81212789135880000, 1253.59384474984810000, 1277.27188725215680000, 1313.36638676770490000, 1369.68203357772150000, 1402.42175312007630000, 1408.71279115982630000, 1408.86472858486600000, 1411.05171479862290000, 1429.31865495236680000, 1435.10470065274940000, 1461.2478925588548000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 45.91288168902228500, 113.88157849905518000, 218.61206693712768000, 303.95186182918445000, 322.29384006850057000, 322.83930087781420000, 333.71183299383858000, 426.75185475324486000, 460.56755111990265000, 578.51590637552806000, 581.73791461549195000, 714.16584 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 13.65814964925465700, 14.07288967622387300, 24.21311513140698300, 105.13005453803142000, 133.64751884535616000, 225.37347132650206000, 228.12484200861039000, 329.182512445046430 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.99221268716260191, 51.21183990305507200, 58.94594 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 54.98394235372808900, 226.42873061215624000, 285.95446038232075000, 459.06025986696545000, 508.48772331972214000, 578.16284182491029000, 600.58747355493722000, 637.55592246591880000, 693.05635901570759000, 794.28984346310392000, 858.10733180169620000, 873.15588575956087000, 873.64673331311747000, 886.00445499236764000, 997.05704863812650000, 1036.73683715995120000, 1166.82453634088730000, 1170.42329394595 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 19.81425179011610600, 49.96008027663264500, 94.65084880797921600, 173.94816060751035000, 253.52991042387617000, 273.91422388719900000, 274.54695928371342000, 291.26589742893856000, 431.13983955064771000, 481.60302165733526000, 656.63997232403540000, 661.54932151673870000, 892.28446 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -76.13223476380504500, -352.65448557904921000, -422.24473284327632000, -521.92622394529224000, -548.29704612285946000, -582.65683919829701000, -628.37496354720770000, -691.99824662369736000, -732.20835472779970000, -739.92955401905442000, -740.20439847671435000, -744.30267328873242000, -788.52927314268481000, -802.86096879783838000, -859.98611119919303000, -861.48 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 219.78535200881655000, 276.26887679027703000, 373.05235715851296000, 394.38706182485328000, 428.03276385690225000, 491.44454585018707000, 586.10030346716326000, 648.66705295858117000, 661.20803126439898000, 661.60636306945980000, 666.93265758771645000, 728.92786057659407000, 746.07410358236871000, 814.63289463586318000, 816.45921714230224000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+130.24806091415982000, 455.92540165373339000, 517.01098785762952000, 889.57360690614723000, 929.94674058947317000, 1055.60460066310880000, 1104.35130195979010000, 1265.68972835711910000, 1303.40933734715370000, 1360.10934851704500000, 1376.36727641609240000, 1401.71922409453990000, 1449.36064816020830000, 1517.27264751904180000, 1573.48684890469640000, 1586.06312035100770000, 1586.46715716143330000, 1595.83002323959230000, 1681.30165971360200000, 1708.32086146059940000, 1805.659654918661 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 18.07096289994384400, 161.44622659960598000, 213.19922034244138000, 394.07517914880526000, 399.04163861298463000, 631.14230458242935000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 19.84993434521544800, 106.32368456227741000, 108.52687483999416000, 202.59718384305160000, 22 [...]
+0.00000000000000000, 0.00000000000000000, 61.45289176755488800, 486.75385617363412000, 537.08032155154910000, 725.01000503474279000, 787.79674684952704000, 983.95328708018883000, 1047.24724593139900000, 1128.04129036137310000, 1151.55639076861280000, 1184.37244669415350000, 1229.53964360633970000, 1302.85577393681770000, 1348.68594588403580000, 1360.42976458299470000, 1360.72461056471890000, 1369.70127786511650000, 1448.46341163006970000, 1473.19208937836080000, 1549.88364583128960000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -152.44382657824016000, -194.72680177882197000, -298.98674030541719000, -327.87800350970269000, -350.77967283072167000, -355.93652216157386000, -364.65306553309534000, -378.69379562382727000, -395.14654101848265000, -400.31578925277557000, -400.31168467168305000, -400.25876034526470000, -402.71760451298024000, -439.00016863597051000, -452.41962644135413000, -505.88121569495991000, -50 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 62.64191467219561800, 171.69119193422435000, 252.09734024022075000, 268.65738836953670000, 269.10126544748039000, 281.85728451679194000, 395.72632739360023000, 433.80365969045374000, 564.52529178160137000, 568.13235633119143000, 729.5210282 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -364.07521181431974000, -413.17329809410626000, -568.02741676761377000, -623.94424615693686000, -789.27882884793200000, -830.50263687486631000, -892.81661061817988000, -909.76048321175517000, -928.02296192003587000, -957.15517080354755000, -1001.69918045839290000, -1031.36974596696720000, -1037.82880938568180000, -1038.06579362433900000, -1045.84187470679190000, -1102.19772925724670000, -1124.97765169471540000, -1189.24555291 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -0.32803343440700417, -6.91709934833832210, -68.25005631288942700, -89.83612196025330800, -160.69601720538077000, -162.49008064270512000, -235.1575204396349 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -104.09056725792594000, -106.76099845864626000, -242.72145512723961000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 66.24180220580902300, 85.83034410500965800, 119.58729440650322000, 181.19787318365778000, 262.49172483628990000, 321.14345173253270000, 335.15115485180064000, 335.58843035151040000, 350.05543079783780000, 460.29766289995837000, 498.03004458242867000, 622.26463554217833000, 625.71935567868320000, 761.69 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -105.62047293524826000, -126.57839370687697000, -127.18973763276276000, -136.50659193393361000, -216.30795509399530000, -244.38853657830381000, -343.97866704147526000, -346.71385702428626000, -470.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq2[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 959.66593451659242000, 962.24470945807161000, 1004.10042119294090000, 971.97115224759693000, 1028.2716881750464000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 975.83967365189312000, 1008.90765566803550000, 916.54200500427271000, 1129.56696903780020000, 1027.21959568823190000, 1089.61739103553080000, 1206.94336983192280000, 1294.52792284762810000, 1098.94417897086280000, 1090.70289810357300000, 902.83964903967046000, 920.39995687224632000, 910.20879258987293000, 881.3057657444300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 566.60928 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -537.91495248923650000, -546.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1255.06895953494950000, 1070.70812627039390000, 953.85644388540879000, 911.32931864463171000, 801.13453321614566000, 805.45250461057844000, 914.96255086655003000, 933.57927509420063000, 940.67914334704471000, 895.361676 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2589.65975253239870000, 2295.08977789138540000, 2186.32823203981980000, 2082.77922356951190000, 1954.62344549393490000, 2147.37285411577840000, 2216.41504312203600000, 2115.42180989337110000, 2021.02741544246960000, 1963.03076064889320000, 1999.26737980303600000, 1970.86577624768280000, 1971.80350783791410000, 1876.86527305819820000, 1812.69453683151460000, 1732.94611680930230000, 1611.25954302338120000, 1605.10031254639900000, 1585.17430823242080000, 1626.3322871995 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1445.89742966269140000, 1352.00309995403750000, 1338.38036705200780000, 1540.64274511561260000, 1500.13195539575530000, 1486.30311671078490000, 1329.03865698589470000, 1322.07034322495700000, 1337.62738551458280000, 1323.31527502850300000, 1312.9804359878015000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 890.72217359695446000, 898.71025704912142000, 952.50086716255942000, 883.78885653870748000, 873.28991010481002000, 804.58825858647072000, 852.55503739423955000, 723.808098926833 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 226.17726904397423000, 247.31719002027873000, 255.3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1822.76316747309530000, 1655.03814221178410000, 1670.13452614341690000, 1531.73041998310490000, 1571.48348319877910000, 1535.35950962948190000, 1676.84009880973620000, 1764.80508074087700000, 1704.05536543327640000, 1876.66851356160330000, 1782.91042187709900000, 1839.50532750835620000, 1920.62088416336560000, 2017.29307658748210000, 2065.70942428884380000, 2065.89052875986270000, 1988.27928244137090000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 970.78373763532750000, 969.17256519191642000, 908.74034773825122000, 1021.78738452123420000, 1406.77880911605690000, 1582.90178447735550000, 1624.16681514044900000, 1821.80242995208660000, 1777.13830417726990000, 1790.43989024122290000, 1761.93228492101410000, 1775.7379314160537000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1846.47124830953730000, -2066.15667869288840000, -1918.86488292469700000, -1891.35039101773050000, -1813.94398919976920000, -1630.36235467864160000, -1461.17883258631330000, -1372.25226434858470000, -1314.90806910142490000, -1235.74972688263030000, -1326.44556559524200000, -1119.47956943058330000, -1214.11916212484930000, -1174.57458018151010000, -1220.7098355998 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1581.71077237228680000, 1491.01353798667260000, 1702.66365735467120000, 1418.32949185542470000, 1453.96407589339240000, 1646.55705623317700000, 1598.15055152383390000, 1555.34521864637260000, 1466.53241118445640000, 1511.24511615767960000, 1154.52871616263110000, 1325.50394023435050000, 1190.78714122258450000, 1247.55579705012700000, 1230.9475 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+3004.96696470083360000, 2701.08453329286520000, 2713.11096155281350000, 2348.56367699896420000, 2227.97638202916690000, 2102.68222469721330000, 2237.88149918714320000, 2265.44199657537960000, 2114.61391107622740000, 2139.05401227474570000, 2156.65378427090760000, 2174.75575992473520000, 2317.19945068026120000, 2243.38120686572890000, 2388.10786425631750000, 2393.65386464791300000, 2448.27464391062220000, 2452.95434879592180000, 2503.79003544721630000, 2409.10360899743860000, 2420.3174155 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1672.37870995824640000, 1541.13769648941090000, 1555.48925126059840000, 1536.23862544286730000, 1526.19156201622310000, 1537.4848022418 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 534.68718450238566000, 652.37279586305669000, 608.54620866970174000, 569.93744312801209000, 6 [...]
+0.00000000000000000, 0.00000000000000000, 2270.75794032273010000, 2152.27222045311870000, 2155.11780959527140000, 2290.98420156930300000, 2247.80667448376150000, 2199.46003522767930000, 2408.45830522648110000, 2237.98974493152580000, 2280.14520556434350000, 2185.00602775255170000, 2052.30778814016090000, 2086.74478138382030000, 2012.82810720822750000, 2114.56419341340420000, 1989.62887852061160000, 2191.47100535753410000, 2206.38664958455460000, 2114.56672722555140000, 2034.1618937420935 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1422.72265862800550000, -1177.95290618268840000, -945.04553952515187000, -949.21861333200320000, -665.40276973452194000, -603.43546427090564000, -630.43960697752243000, -634.46050762748723000, -571.05771089419534000, -475.22529861919185000, -400.04810721045260000, -287.37156897662800000, -627.81269092221510000, -788.14508341765111000, -800.47300712113099000, -843.47098400477455000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1203.73047956790470000, 1337.63556639078180000, 1417.29290575543220000, 1332.06808616182660000, 1215.88774404892890000, 1449.60807260850490000, 1491.48122323634170000, 1421.39529158711340000, 1389.98308506549440000, 1386.76433351835360000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1789.82780116590240000, -1991.71738211320640000, -1858.39065037301430000, -1924.20483733509240000, -1813.79374294020360000, -1717.06913407300390000, -1748.88588332878020000, -1722.96836909199330000, -1484.88602646177540000, -1487.82909099078480000, -1477.95944349536420000, -1461.33700699470680000, -1452.60037789462130000, -1543.55139752571970000, -1757.70384065081090000, -1644.50670079984660000, -1715.80845357728300000, -159 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -700.02088908839085000, -610.11366655108816000, -658.45338262983398000, -649.70249160795390000, -608.14952452226044000, -569.65709379275222000, -518.9205532 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -761.38323241135356000, -712.82178382395693000, -773.64082739718140000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 976.27157612070482000, 1025.96706062904350000, 1148.91081038406150000, 1303.49956666018620000, 1131.67776065513020000, 1171.08756084756620000, 1234.66190700704210000, 1268.29379208549900000, 1674.43814618317400000, 1521.15197854761820000, 1476.67487480909310000, 1406.75921124987240000, 1409.77640181516 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1636.20624634422870000, -1472.40039724194910000, -1431.18174705405360000, -989.41876567805093000, -984.23163451021730000, -972.69972908763259000, -972.85277157884991000, -967.47180377783161000, -95 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso2[1350] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.83694139646208580, 230.43843276889123000, 312.37500563538072000, 397.28945311297116000, 502.04640010235920000, 504.07262133129097000, 606.62301376308392000, 700.04839920701556000, 742.91525260263654000, 746.9426911519 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 65.23507852367707500, 133.46557027073513000, 147.62549456262428000, 245.50357066734230000, 313.07754832739073000, 406.38136311162503000, 597.23370736915695000, 610.26397856618325000, 613.48021232520193000, 807.95244781381200000, 879.52865116524003000, 934.37967485896672000, 997.53602687908676000, 998.91303380475529000, 1070.04706775234810000, 1146.88963957599800000, 1186.7980379071257 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 87.12247298008435300, 126.32629625567596000, 129.06122316010027000, 129. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.95067328846468890, 89.64104310800944100, 173.73432801418090000, 215.64405654902205000, 218.67858113604353000, 21 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 81.01625156965404500, 82.67477146731897600, 147.96870395755172000, 206.60710976175159000, 237.75437559303430000, 239.27310538778937000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 110.54538377258233000, 217.04892463525849000, 264.57043754085242000, 269.84251493605126000, 2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 120.30797141535649000, 302.13849879155879000, 317.55278090713625000, 322.27779723244674000, 548.49320858345652000, 637.87272723435410000, 729.52135782191135000, 846.50044126459727000, 848.87907823535909000, 973.14537277951774000, 1076.65344631821090000, 1124.70965047505890000, 1128 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 32.27957070828132700, 34.82058711194994100, 35.0819 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 111.61248629069598000, 256.92539748456403000, 260.01409415343579000, 393.45436446162608000, 503.12445677860143000, 556.83175797280410000, 561.74181972386953 [...]
+0.00000000000000000, 328.06190151981588000, 797.74441997590645000, 961.11411485776534000, 1095.72499642611610000, 1143.60856390895240000, 1184.98385870231600000, 1192.82662424866090000, 1247.44101849314190000, 1289.65927442515980000, 1345.61609491393230000, 1429.74292084111950000, 1434.93246502574990000, 1436.48572742353690000, 1502.68321047815200000, 1526.08253030721240000, 1566.10029518086940000, 1610.63956453542030000, 1611.32381863832600000, 1660.28811273448830000, 1690.2558721003547 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 18.03268188138444500, 153.77647387542979000, 251.76206833675559000, 377.67147265803624000, 598.18784953588363000, 615.61511943716164000, 620.86180953928204000, 897.72700669144706000, 998.63355829207228000, 1075.60759713902890000, 1166.37403057511350000, 1168.34235676313120000, 1263.74872407605240000, 1357.55475632127830000, 1397.43566560311000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 222.18254631265654000, 242.37525650168783000, 248.26244108225583000, 584.07766651292343000, 701.61351095980183000, 783.97660519676253000, 892.54225889803024000, 894.88025753059333000, 1011.43553502216340000, 1118.41400884548850000, 1174.35215160137800000, 1181. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 12.57456367501476500, 16.02502587144183700, 193.29817882245442000, 251.19171249723118000, 319.47879225959537000, 406.26220692476289000, 408.25597061929938000, 484.59084020647117000, 559.09964132108064000, 599.86213167776145000, 604.21094217 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 191.54627713123085000, 330.89486262858878000, 389.93410636693562000, 445.86370355670698000, 457.03707910926329000, 554.39008765158803000, 625.68203998502383000, 734.81011860294689000, 941.68369354451124000, 958.40441662643082000, 963.92545901634503000, 1297.51200073291510000, 1415.99629930058680000, 1509.63970979720560000, 1627.93411913259640000, 1630.31181976917760000, 1743.17815532273520000, 1837.14648495107920000, 1883.673 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.70251032154480700, 8.0445485 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 88.47076615423759400, 152.23340345917265000, 245.38772919671035000, 464.26858163315632000, 482.98113764194227000, 488.68241766460369000, 895.76776162210149000, 1041.40535999171130000, 1149.36897755271660000, 1281.81024127678960000, 1284.88452698401100000, 1428.06634417618940000, 1562.61769537769510000, 1632.592899064668500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 167.04859176406660000, 229.00923454963112000, 303.67245566122773000, 317.41113242652307000, 395.75078062550091000, 473.42691812893986000, 570.66594240964560000, 723.27809011899319000, 734.72313402602401000, 739.01519986870892000, 906.29821670601712000, 956.66744758001153000, 1003.79444390444560000, 1049.55505091202580000, 1050.30553049674840000, 1071.91445287726700000, 1094.26765053226150000, 1107.5494631 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+130.24806091415982000, 455.92540165373339000, 994.89112305048377000, 1185.01604019245770000, 1335.66675904262410000, 1385.44464594810230000, 1436.51646616764400000, 1445.38599607164520000, 1514.03460717971620000, 1579.41722482936420000, 1657.72552733341420000, 1803.63018970774310000, 1816.90975028123670000, 1821.16398400344410000, 2096.50136480498170000, 2187.67417451615570000, 2267.31443625721480000, 2363.40459530114690000, 2365.40637649693740000, 2469.40980905050950000, 2556.1995060613 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 453.07592349318281000, 614.04066564146956000, 750.92294290513485000, 906.81773486844588000, 910.39803761286817000, 1105.03077948587450000, 1277.64860938739120000, 1364.94614395271260000, 1373.775196 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 44.49811609985681600, 81.63425309630879700, 142.32834211901417000, 143.27907187476998000, 213.14122281502381000, 268.62447984600203000, 296.51325944318040000, 298.38219496711980 [...]
+0.00000000000000000, 0.00000000000000000, 542.20650404929881000, 743.57918818374071000, 903.59299280639334000, 981.30707610481625000, 1051.37289765121980000, 1062.17462270758760000, 1148.59503862913930000, 1206.31254948943340000, 1285.85847501426930000, 1455.92400485718690000, 1470.21253758216540000, 1474.61789308812690000, 1762.08193615310350000, 1856.64835502188430000, 1926.18834824887610000, 1995.24587022028410000, 1996.99032817259670000, 2069.29217567241990000, 2142.47835924880250000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.2845731 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 88.23873518335740600, 215.23336445357950000, 422.47866671574303000, 438.59871402156261000, 443.97581210488607000, 805.77509839009019000, 928.47297846703964000, 1034.62630037638790000, 1140.61774501638930000, 1142.95848774085810000, 1255.12959594010790000, 1345.57708059277870000, 1389.75887599874480000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 62.61515828715793200, 75.13683945502739900, 173.11381770540996000, 260.44501383372449000, 356.19249739370542000, 540.33436780177396000, 554.83284662872757000, 558.91658973602443000, 924.04318079805603000, 1050.09186161997810000, 1132.60918002241440000, 1228.65662427075290000, 1230.72661788173080000, 1322.88436890954770000, 1405.63176819080380000, 1446.534054131072 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlassolsq2[1350] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 924.77233145703281000, 757.07293307805548000, 767.33744042381113000, 882.15392825980791000, 889.01338873064651000, 852.38438057769781000, 868.42133775916170000, 870.78864265695643000, 857.52386333775928000, 854.37112167 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1368.92147160317240000, 1401.43205942660850000, 1628.28766798431160000, 1493.04253324887690000, 1343.95274069873900000, 1399.45055366221190000, 1525.64626954130740000, 1372.11312170188850000, 1225.17405252614660000, 1261.92014074665510000, 1276.96391859751770000, 1247.58094513213540000, 1230.83247218738320000, 1235.62346696264830000, 1251.64335836572700000, 1287.32384124555850000, 129 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 246.34378286173080000, 231.14144747878399000, 202.01302648062446000, 224 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 337.27558012418172000, 313.50358819404664000, 327.41962317415465000, 327.69370291179735000, 299.62189281489265000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 380.28628378085074000, 367.77788609877979000, 314.65594608024992000, 313.77215526786927000, 321.02955401995200000, 279.7839055502214500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 392.75392057963427000, 411.69024625000617000, 391.62372330167966000, 410.47060726383404000, 4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1400.79301981896150000, 1186.66389699499810000, 1218.78940478375350000, 1220.92621572401050000, 1076.56081750898150000, 1134.16299180143940000, 1252.83825486101070000, 1278.61539834614500000, 1257.77185660752590000, 1290.38167845725050000, 1265.82037981335930000, 1253.1924841645127 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 118.58207394683716000, 102.59999599296225000, 72.96 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 748.92370002088740000, 793.70411497808880000, 790.96765201365315000, 734.11068270539079000, 703.55283256106520000, 700.42333721452076000, 692.71345870108928 [...]
+0.00000000000000000, 2589.65975253239870000, 2295.08977789138540000, 2212.04839152216750000, 2230.81575769810160000, 2100.53475748777010000, 1953.88476991687660000, 2012.92184793143700000, 1943.54772031351630000, 1933.72011282143030000, 1941.18653924221100000, 1838.98286133185800000, 1738.35284135897110000, 1731.89990193054380000, 1657.21179181913520000, 1656.00999919426640000, 1794.60313702219380000, 1775.16542590460090000, 1728.94856116479040000, 1785.28783068829490000, 1745.0236689412 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1903.65787285833040000, 1883.94604995041350000, 1746.58185011882850000, 1717.77477412742540000, 1670.90285995159800000, 1634.54637886584530000, 1618.72709464513420000, 1544.02931554687460000, 1558.92902582560280000, 1515.13206033843290000, 1501.66075307619530000, 1506.70183475589760000, 1507.30924557956200000, 1528.99065360462350000, 1504.0610 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1303.00273688741960000, 1422.99526989111470000, 1367.94304077790960000, 1367.99040735973400000, 1354.24507820388520000, 1254.27276380054420000, 1293.57842202234160000, 1296.78721872311440000, 1308.98657872475970000, 1313.92329765071920000, 1323.9080979916575000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 747.77956564777651000, 672.26665180495388000, 607.11706696299575000, 572.65235110730362000, 709.40041421947251000, 726.83585479235251000, 750.98821034207583000, 679.46421364258447000, 695.26874333786009000, 708.84452762754802000, 720.211690 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1658.23080392912470000, 1505.93576683702940000, 1569.80022228570120000, 1485.23559100429250000, 1625.40452155253480000, 1795.23661952603970000, 1713.27681568387670000, 1896.30317170106510000, 1948.03248378018840000, 1936.02555435662360000, 2013.96966427001080000, 2076.22219736345870000, 2073.89426933630690000, 2044.34687012331390000, 2064.90782510281090000, 2039.04364029479210000, 2031.31179170207000000, 2008.8789899987198000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 185.48616042207277000, 202.548 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1216.10559735757510000, 1124.96467182568810000, 1236.86584903981950000, 1529.02748628006910000, 1577.06003635480440000, 1573.00592535228380000, 1846.05042772526210000, 1850.07521318343700000, 1765.84502278030390000, 1771.04172869901320000, 1813.36080974063000000, 1793.59161305857360000, 1808.51799700878430000, 1819.6782632 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1575.66660975548120000, 1467.25786908881760000, 1691.18205610349240000, 1754.02467497861110000, 1394.25593451301440000, 1658.41566622898270000, 1605.61911507120020000, 1465.66894533553000000, 1403.88778623310120000, 1555.32098931738160000, 1296.79655714868890000, 1236.34851203206470000, 1272.89124682628110000, 1218.59247325423640000, 1179.31457486997830000, 1127.07932868545820000, 1135.11939967263700000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+3004.96696470083360000, 2701.08453329286520000, 2713.11096155281350000, 2640.81710459956780000, 2606.01160155060550000, 2380.22774889736230000, 2385.61348892748040000, 2372.84698768229370000, 2389.01928702568380000, 2576.86211236293680000, 2491.19158400988320000, 2513.39208419632590000, 2593.33425374388710000, 2630.27450196636070000, 2739.23720432777330000, 2693.92189810946770000, 2722.06312575232140000, 2718.35689727888980000, 2709.51684181853810000, 2734.91756271877280000, 2714.8126487 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1510.71703711972830000, 1507.81628305965140000, 1532.52554992752770000, 1482.68539732511270000, 1525.85973041228020000, 1601.90382315564470000, 1593.11758134976300000, 1598.34440775331400000, 1609.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 291.57912688703050000, 293.68289862883267000, 366.52930951674387000, 306.71154857910136000, 391.49055520869689000, 370.02331023723582000, 371.07656492380056000, 348.234429240951 [...]
+0.00000000000000000, 0.00000000000000000, 2270.75794032273010000, 2285.50526663943130000, 2252.89097813254780000, 2534.37936849162180000, 2353.44637654924870000, 2191.67965175821750000, 2250.09641989137800000, 2086.82235772703230000, 2132.49704017070600000, 2283.21787391007410000, 2305.62925674267400000, 2312.47018517843800000, 2433.12573890199470000, 2381.73949164860460000, 2323.26415006243910000, 2250.34094589211100000, 2296.86637804587640000, 2253.86974820451090000, 2276.2303019528849 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 187.45985 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1434.36525099046180000, 1566.88714179689510000, 1430.63574657704320000, 1381.09975959062470000, 1466.64332391187830000, 1650.34392276226000000, 1609.76735422946850000, 1640.76549390117200000, 1532.14490699886030000, 1545.33716419601930000, 1541.48840384889290000, 1510.87503976790840000, 1507.8831092968 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1226.22867459645790000, 1384.49268562512450000, 1421.91337188324270000, 1592.72656253443100000, 1375.27061564694150000, 1436.10343143998490000, 1402.52461789490300000, 1335.60158556130110000, 1776.37912354280840000, 1749.99195168178130000, 1603.78596402351720000, 1583.45113990309570000, 1586.56294314254500000, 1558.15157940196150000, 1556.85738027682560000, 1555.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+
+
+// Data from file x23.txt and y23.txt
+double x3[5000] = {
+1471.86835354996, 10716.8189864451, 1026.65392734577, 6927.2704771031, -11953.1660867543, 5224.08585864581, 3465.92771644415, 5207.83102059167, -4203.03646887612, 4897.86672019757, -14071.4505266649, -346.852436164403, -15862.5250266587, 463.442257904917, -1620.58084506434, 7744.08160504791, -1454.73416282433, 162.897925390874, -9204.30222385778, -12865.0789593636, 18554.5673909367, -8208.25138899142, -1104.84497443366, -7569.81774975895, 7889.40183934305, -233.843342103902, 1189.5539835 [...]
+2355.98664163593, -5436.83492743328, -11198.6581947084, -2390.04535359121, 3719.73895669013, -7144.72785338785, 17094.6049132476, -3006.20467667888, 21793.4546880404, 5483.82044815056, -23368.4688608457, 4464.3745144628, -6997.82287654743, 14709.1794348205, -6343.10080631715, 5203.65674060481, 7614.74725549055, 6584.25811127285, -993.471452852388, 13366.0431915235, -2908.56682123908, -3637.51932018235, 16070.1741474343, 4810.01058434896, 3628.21419166535, -5627.35376412742, -6084.5384326 [...]
+9869.89382971353, -2066.65354347079, -2304.86294868252, -13716.3770652648, -12284.3823618312, 13606.5361331903, -7996.40341478026, 3826.20651104187, 11216.6598641754, -9127.86045647954, -2987.99879962086, 14785.9473399506, -5629.72915155491, -8663.15900925558, -3309.99574031522, 6481.82498211491, -5088.34524054044, 232.680371359739, -6537.61093981375, 3972.25153770826, 15079.8544568150, -489.27659027495, 2879.34486638623, 2879.27036984959, 18656.6385182339, 11495.7892155492, 6286.0978812 [...]
+-12378.5534904898, -5418.9200000673, 2033.54341911336, 2139.82444384518, 3362.32663922948, 1530.71233579704, -18924.653005633, 5872.70365445278, -11929.7320966046, -15392.415781911, -6715.19899527896, -981.670878707547, -14037.9226873216, -1527.00036616565, -7990.8530852072, 7314.40670953773, -7837.88369161833, 12140.4421586994, -9321.48870714579, 18119.4091562712, 12633.0402305155, 214.184366576039, -1751.71945388513, 9846.65926154624, 8997.26591689995, 15968.8962780642, -8687.042682368 [...]
+1631.09108241117, 4855.56653975742, -7517.87235347829, -4727.25044862465, 10791.3088138869, 20834.4035689749, 1022.12402616163, 7796.8632751284, -6259.23404244212, -10937.9427998198, -14186.1637790877, -4122.07266804033, 8984.94649695465, -5876.0193494513, 10836.4269783817, 14322.7134374650, 13356.0293393769, 18110.8899090409, 10498.2303395953, -504.217323088882, -1312.81334236399, 11833.6296455024, -4186.0403508861, -12140.8863046385, 268.609654654719, -7858.81133093046, 11883.009905959 [...]
+-2305.76124810113, -11835.4557581522, 1442.14224858533, 2980.62277817034, -5180.22918381641, -8698.64765869012, 8987.0328913361, 4824.37231732689, 2727.18127041561, -6363.78437836846, 1983.79380124736, -1582.55704500925, 4618.26351395325, 9363.13912636116, 18105.1282323013, -2374.48979897312, 624.653887898251, 2647.92722450638, 16088.1976957093, 3343.15777374750, -3289.02797097605, 16636.9911078655, 16982.0273424834, -10706.6182842325, -2782.63544932812, 7859.31754109206, -5093.433011258 [...]
+8433.297944856, -792.772392035422, 3231.76216769149, -21205.4008914183, -7652.59314219436, -2501.47170037693, -219.054436687828, 1146.38504939470, 17355.3551277170, -14386.3984288345, 8724.153195973, -221.115627819653, -4411.29845755884, -11321.8338877630, 14637.1051676718, -8348.60865043982, 87.6590801486283, 1037.55351518446, -2924.26682057018, 6237.94669780815, 22807.7346376941, 9529.71102797557, -10254.2658229846, -14521.7491246001, -6489.47234376136, 2636.84214982369, -13545.3146313 [...]
+216.712862131827, 8329.98773923245, 3333.08692797902, 7568.64772925824, -5157.28596620657, 22936.1069381033, -897.235890287839, -9178.66416369834, 16408.5064606034, -2579.72949582728, -8734.57481283847, -7689.99226409783, 1105.39262234576, -5086.33084785573, 3523.80661007887, 12621.5424151264, 16053.482406752, -15439.5944633923, -4978.97764827716, 5030.88709274132, -12702.5657957892, -11706.1845429799, -9660.69637179272, 5522.2337455493, 16067.0366437237, 13671.1179561546, -8397.74632672 [...]
+7620.08426847521, 7265.7097858309, 5798.92390522004, 1445.22439009437, -14304.2293440644, 15899.2848958405, -12529.2101498967, -12949.4186866737, 8235.44601154298, 25823.8115615684, -831.919477546353, 11264.5599949457, -6393.32301884875, 5312.83641920780, -9356.334866684, -2501.16370200957, 1515.94285704825, -5017.71110044237, -6154.22804196877, -4195.12999807593, -1336.43944601935, 19301.0033588472, -15236.4989111178, -5782.9111537259, -3482.16440170311, 638.503101282334, -7183.51922591 [...]
+6530.48774560304, 4712.90547787201, 16609.5962125027, -9676.70273212866, 4104.11795850929, -14385.9613589096, -6445.30499018312, 8455.59100228338, -14673.7887097921, -244.629215349256, 10989.7572334387, 1576.41081914353, 12134.1460360975, -7220.81025730009, -2052.07877607589, 1306.3467869468, 5212.13642991368, -6006.71048436354, 8236.59516488889, -9630.02979292675, -2807.42784154151, -16525.5861412244, 14387.3505705984, 1601.20226719165, -13519.3723744121, 9063.50828651796, -1406.6190463 [...]
+-3869.86951628704, 10399.3291778712, 22627.7206753122, -8737.5039328001, -2450.84445619665, -12451.1395909658, 9144.94985755676, 15426.7484397712, -12971.1830645817, 15259.9160731862, -3241.54662831703, 3843.75776932148, 9193.72507096603, 12563.2731514756, 2474.70786049754, -2983.40351518278, 14157.6765577906, 9787.95056192674, 6925.26552709105, 4486.08757856536, 14657.3089485389, -9079.33097343146, -366.066489819689, -5997.91253309986, 7890.19323162069, 15526.1504850999, -12102.34070445 [...]
+-5275.22331942861, -9855.0232346974, 5612.4093980329, -16403.9661884263, 9461.76866603733, -7833.57760995444, 9837.87943166953, 13676.4632578422, 5788.64699326166, -13872.5499493109, -3595.51947397671, 2307.61174104129, 7896.22675343963, -4072.52932048255, 21206.7115889024, 6314.35448935445, 1853.89684244518, 14780.8042677777, -5806.38362782608, 1645.90691579376, -8019.75135411042, 16243.3946885519, 18369.3715425558, 998.722679265642, -16298.2530636891, -353.926998164194, -1443.494821235 [...]
+-264.265207410116, -12912.6335281640, 18356.1133216691, -3246.68506210576, -4570.05807234741, 1110.11068932278, -13580.1651799947, -7702.99860420269, 24023.6063600803, 7906.63499494864, 8541.10361183042, 5582.54832911616, -8814.87288292555, 4437.84763667991, 26385.4839043831, 15623.2256575204, -1561.27559046967, 3973.25736939046, -5048.67747213979, -5718.11044113649, 2028.33488524487, 9421.89343814048, -3254.89316690069, 6379.215748601, 11811.4894379809, 5023.02662530306, 8812.0239732136 [...]
+7315.51088480908, -551.303049877595, 6035.26885235735, -17234.6096120192, 3805.78389945461, -8820.84288337734, -1761.53332405556, -14550.9278762866, 13656.3340730209, -3191.49639330004, 3909.61915601563, -1106.90038739524, -1065.99378382375, 936.049517422286, 38962.7154982927, -2358.64724712713, -9166.67381627217, 1091.46664270603, 5931.60134295336, -17520.8251106366, 23323.2674813866, 2079.34978877889, 744.583722088098, 7668.65938406432, 11462.7130354692, 2003.32260990191, -18866.346786 [...]
+7682.46979371542, 182.914004822851, 4372.66194454539, -3683.80296296102, 3231.09157688821, -8119.62866805886, 7834.90645261914, -3395.80095392706, 5686.23246662797, 1744.79746864116, 2037.72146054281, 7843.96122424248, -35337.6282532386, -2747.19098429906, -8491.15551996463, -3335.23012599793, -1234.79710578331, -8289.07525628032, 8735.455998424, 10102.5739449312, -3732.72618959491, 3062.44572504551, -6777.17752281781, 2713.08679030342, 4284.15676384232, -9425.66681178946, -1757.80779336 [...]
+7391.15758347143, 15372.7831432559, -9345.60013223805, 588.349491062656, -16177.5346930521, -10709.6645617798, 8875.08430490227, -2362.82516257379, -1041.19253712593, -6015.52574227276, -3949.43445360397, 3300.83809549315, 10262.3618560819, 14462.8716270377, 7072.71638866428, -2156.82373685429, 5231.46414521872, -4599.60525639179, 12511.0199674954, 9943.21214463663, 1389.83681340500, 1242.67660591538, 5507.49831306701, -12579.7212173833, -4408.12939004722, -219.516220618553, -3230.122954 [...]
+-3664.25772095473, 6065.45055374864, 5411.73419398682, -21322.6111378143, 17097.5956873412, 18137.4646414334, -1548.83254834642, -3910.02853107697, 8178.89906240924, -6435.1012149009, -14440.5081456321, 6232.64191915587, -4561.08848357589, -18034.7293670877, 14579.6786794920, 4891.47509517831, -6958.2912249057, -7315.95717250518, 6686.18252351116, -11360.5824902837, 2592.16188427574, 1622.15337383048, -8636.51984281776, 1859.97812923519, 12766.8199079427, -6294.21298346383, -19127.419264 [...]
+-2593.30179652968, 4797.06101051829, 6296.29506576335, -2574.76166009592, -12172.4082730233, -9915.4760429892, 17023.4729089139, -3001.13355425395, -8410.58116619504, -8959.7067820151, -14785.5942758287, -4263.84832772183, 8980.24862900374, 9497.31924327377, -1311.49097833466, 14800.7886586544, -1367.24351645432, -16840.3192762143, -5709.67821076474, 7629.20365586333, 14957.6909384841, 27801.8016269251, 12724.3697368409, -4233.62930649436, 5779.68488893571, -8518.71338878553, 17613.12977 [...]
+-746.25985916724, -6013.37912365145, -2017.97970076726, -6719.33767209969, 6591.53413078934, -10844.7663496878, -11792.0377255547, 10220.9037099440, 5479.51272173494, -9039.36145336223, 8628.3008180665, 5094.86766246191, -9476.08628427533, 550.105082037006, 13553.3993792613, -2260.10314927645, 15471.6748030962, -4714.46679425728, 5027.04986923473, 17966.5609516741, -7395.61828348667, -12331.9160411352, 8748.6827145819, -10526.9532220270, -5291.49702568355, -2423.59307718449, -8627.807033 [...]
+-4336.4222685644, 582.318759100984, 518.88688602202, 15001.0368449350, 4357.85729088957, -19350.1637286504, 11949.5700685909, -9539.49915076446, -11467.1741523544, -24220.6550396722, -1049.09226741786, 2342.26191321461, 2375.46773200797, 21862.3016661247, 1035.73822336767, -210.663303782306, 3754.3848084156, -9596.11670014852, 3622.34638266991, -1664.36028354588, 12809.9616514477, -1949.02499425566, -11017.4490521740, 1672.84259233061, 1706.92771637785, -95.3717085417005, -19084.30575278 [...]
+310.789992090598, -22917.0285308896, 18192.9686755229, -5856.12548052997, -13650.4396152428, -2755.25152463456, 974.037344739836, 20215.2659993021, -23854.2660900294, -660.822307890935, -1358.63721897957, 12157.8094676324, -10922.3482411170, 10877.5356921004, 7831.16511083942, 3934.65710273763, 7906.39306526833, -1364.47531123692, -8448.92468956197, -23988.9293171288, -15122.6306773387, -19551.6145493154, 23319.8255384661, 16803.7167693431, 8403.03228547328, -11301.3758382197, 11026.9072 [...]
+-12289.9158217086, 1806.45731589736, -6898.92346610191, 1462.81937761559, -20237.7952559752, -13407.5438136299, 18139.9402613178, 11688.5311702074, 3935.64730716166, 7701.5105041188, 11223.5492830071, -463.235821799674, 10973.3263506387, 15261.8661632338, 450.90112232641, -5897.07663676885, 20770.1068221306, 989.66813667493, 6951.32211334566, 23492.0951294725, -6987.28158953117, -9824.47708981297, -5509.06816842082, -1652.01478834382, 7624.60314186379, 7045.5414604219, 7294.89789143209,  [...]
+3445.68626784091, 8723.41230912463, 11773.2592728368, 7731.92182652986, 26593.3266890811, -4173.48759513521, -9941.97366885469, 9859.02909493873, -21594.8118973619, -15764.3735090625, 7117.70894034172, -6199.96741791458, 11272.0330281878, 18458.1904598424, 16052.4523398122, 9493.05385114983, 3609.26306711831, 7336.38897836353, 5907.96241075646, -3714.49962063746, 1320.05517284182, 2751.88262321074, 13645.2555106325, -6461.5902560021, -14075.4400242461, -7187.94517113144, 13948.6608430462 [...]
+-3388.99685067708, 2291.38157418745, 21831.2801566428, -20981.6836531438, 2153.52186055201, -6763.8717911934, 10128.0075602643, 10344.5154452850, -9494.7987217046, 1080.80039074714, 536.534503422319, 2877.86837002405, -16391.1307352209, 858.897234058889, 14636.8302292243, 21071.1813386692, -2502.10652386684, -1727.94169739725, 851.33963492468, -4761.34094229669, -3533.06936609565, 2099.19181698079, 3724.40638655370, -17494.9512941608, 7999.61541412161, -10268.4760420172, 18195.3457000474 [...]
+-17456.2715922120, -1332.14989780511, 13098.0420243835, -18243.7529645099, 6935.48709296465, 11036.7753084071, 14354.0230389952, -2505.05845718946, -11314.3489254994, -22459.8324791567, -295.201602833775, 7060.11967301066, 1723.04668926292, -107.253094777225, 2075.24381396261, -376.78037952542, 10368.2191229191, -9956.99424820363, 8183.11039932734, -6551.02370045603, 12025.6556572981, 12538.3539931410, -5983.62634574986, -15958.5634592051, 10197.5991400235, 8630.41429857876, 11704.406146 [...]
+2733.06851209939, -18623.9922203210, -1114.9982136223, 3626.66315920289, 17486.5488762637, -5480.77630203894, 6296.29111619017, -14681.5757362521, 1184.27279690890, 7157.09571238108, 9072.84173177685, 21316.1625987924, -8036.02268829362, -13194.1099006098, 14855.7474703914, -2734.27022446451, -9655.00852815502, -6239.3234273395, 8471.78395177242, 1082.39544947444, 5913.14688853924, 4079.40424472908, -2133.14205340418, -11151.7037528134, -6080.0033801203, -12259.9535846869, 4738.790017621 [...]
+6747.48178044381, -389.714637805122, 1071.87494858580, -4493.7181889726, 11601.5586034140, 2569.46435801472, -9550.24984015343, -109.477363330325, 19269.1385154478, 3199.21402102734, 782.121265010837, -12110.3360289406, 13596.3095736201, 3615.3441058782, 8397.48875225846, 90.1136967258189, 8393.92694977555, -62.4530970949224, -12303.7190290798, 3352.97487502623, 3444.5642022541, 8380.49079534339, -9287.58059336916, -24448.2962258945, 8856.94729950155, -10590.3353869856, 1349.56881645733, [...]
+2464.37082740399, -14026.9755708438, -13689.5098698486, 364.154886074022, 2021.03320107695, 8509.8771543778, -9273.65064504644, 13549.5932573024, 13781.6413038495, 5291.03707343997, 1646.93575364295, 822.016676170137, 13715.2601769925, 2807.78470547838, 10824.5589696189, -14084.8016770812, -12160.7564234048, -6920.56139057436, -5014.51528263657, 523.34051021983, 5420.83576268897, 11336.3117176116, 4941.11222836924, -11688.0279117428, 283.678973308572, 21795.1033550146, 30367.1547343209,  [...]
+-16011.9254248366, -5369.51187399006, 3766.71892721517, -13018.1310236461, -20423.0439587354, 4049.58917715151, 4168.04547598598, -4215.96115111385, 8258.97618286577, 15871.3541048001, 13456.4218287627, -19422.7762180322, -7679.51350229948, 2929.85229783444, 4084.64800751116, 24483.0594931954, 7894.69917525082, 13533.1561230529, 14704.4661033945, -2996.51166149476, 493.282053761435, 1419.52268742938, -6013.25433215243, -8799.1345981656, -8653.96013879554, 3794.16333912975, -4307.72865121 [...]
+1738.93792545225, -484.065325214191, 7833.78605310446, 1952.07644783504, 3624.81058874365, -7284.42924973527, 19932.8792392932, -2431.54474198847, -8799.0879643247, 5174.14694797055, 2881.70962003018, -12900.6763505873, -3725.15927994325, -15238.3471867075, 17536.6979017109, -5291.52051181786, -2241.16134179073, 151.735945910112, 1131.86592836022, -7244.61175127905, 7640.80354405294, 5579.74697607093, -1640.40962722139, -4003.89741360207, 3385.31947456934, -3594.48456426602, -16328.52011 [...]
+273.653166243160, -5566.83794286656, -3498.73118946167, 3205.27005768873, 2065.7924231889, -2200.90683119092, 344.260631063723, 6930.4446685377, -564.709315308688, 13719.4769195076, -12894.7884174352, -13104.9983490422, -12978.1390953623, 8062.85103314104, -3475.91560791174, -133.520297745254, 13449.7615855376, -1847.79459760075, -2122.45307527943, 13618.2705960974, -9657.81849789714, -2941.62918588156, -5874.13503087158, -4880.76610931905, -2159.00683034011, -11931.6804327945, -7263.577 [...]
+9967.70363180893, 10241.0869481576, -17039.0147112928, -10009.9975618663, 17155.6483616858, -251.69347821761, -18589.2029445538, -4419.1211053611, 1031.68173353552, 5030.27258568522, 6574.86403190756, -8725.00374082645, 21560.6307335118, 1415.17855863202, 10609.3443574065, -856.47720458533, -3824.04053149221, -10262.6626053646, -3880.31268089863, 15183.3262109863, -2833.46452143590, -12056.0644787954, -15387.2883761320, 25593.8709309178, -2917.49128769096, -9899.57369302571, -1776.112074 [...]
+-5994.53113881033, -4924.68600500567, 8689.10747924829, 16201.9395550202, 402.642450129931, -11236.8532785670, -12111.0114957198, 1015.95878318122, 5222.87781941104, -13383.5739196407, 4265.34150929187, 14387.8752960336, 11434.8483474606, 2209.11272670435, 6396.2852253881, -3454.66713483944, -1515.10936265591, -2060.24062825401, 775.460333141697, 6947.94147467792, -17849.6935463666, -83.187914902162, 5092.06438303021, 17618.5829880706, 4985.90159761, -9904.80796744674, -19638.0607080905, [...]
+9442.7187909625, -6965.18527739928, 12354.0320751425, 21907.8254299523, -14348.1345788253, -8524.48642040279, -13175.0567603081, 8273.08508511958, 3020.10602648584, -2210.08282135786, 6301.92374314698, -4048.03043417195, 5464.24161779733, -16676.4559691356, 10311.0329346358, 15134.8559639937, 1450.863340366, -9190.91498495276, 13551.2994848738, 3401.39480515761, 6591.53060203437, -475.452107849635, 5999.57723364708, -2179.2438380485, 2970.05732802869, 5646.08089882356, 20012.1946607945,  [...]
+3203.22723909431, -624.550845299604, 9188.51081143488, -8068.00197831485, -16050.2415123312, -7001.026905902, -1767.16603387343, 1397.39725154088, 2131.75342570658, 1778.09656496008, 4683.96830512575, 4563.96048759171, 3636.86559308993, 9576.44778091167, 3321.021156827, -3549.4665076851, -281.104341989013, 3463.37104025032, 1438.38387872275, 1189.47479418862, 15577.3938540807, -19481.6806732633, -5820.2734350446, 6911.31561168075, -4897.17934677263, 1521.05640090953, 9190.76928088353, -4 [...]
+10804.0881675441, 5016.53032529385, 1186.47321596346, -21599.1317440869, -6782.49059546885, 5704.40263085411, -6706.03554612784, -7974.19932992413, -10599.6059419405, 6055.49508441943, 6611.70831866392, -11138.9418501686, 12445.5845249341, -12436.3674992033, -2061.27753391079, -11124.3370920264, 8270.05516871575, 9848.4321912161, 8302.77883966672, -21530.801973201, -527.626621886015, 9720.85938841791, 6516.54294084458, 13729.9535789127, -2471.22975629977, -12530.9815216847, 10161.1316937 [...]
+16022.5949231014, -14125.9941307568, 16980.2779151050, -3893.90688331295, -1097.10693529335, -4176.24629555198, -11573.2137122373, -1487.0993580308, -7924.29634645544, -3348.89375368423, -9917.93927500025, -9068.14436001841, -5887.1519312723, 3105.89309925003, 23378.2069176942, -7666.17202813136, 11245.0366366436, -13689.5923260791, -1983.40489618284, 13773.2198023829, 13585.5358301761, 1199.88074980563, 3587.21659977439, 8342.95917427002, -3627.93752069092, 4694.23045456958, -4925.87978 [...]
+-1337.27071043214, -19781.7771540819, -1502.66150459825, -1403.22205710142, -2126.14151787625, 1487.28562049690, -5801.5526798869, 6600.04222990383, -1784.99308742593, -5931.3882462894, 4196.59120937508, -13684.9480116403, 631.53005811462, 218.050656758541, -6733.62235602583, 6468.89112062957, -273.086362333761, 17402.6513510416, 13575.8021902731, -3214.37248575506, -6395.1626052228, -3077.71608229750, -6073.58823544069, 17672.9401021285, 4418.59162855846, 4662.38141574537, -10766.158993 [...]
+9005.4045762504, -1263.53732215030, -5451.08792380276, -302.843462335895, 13075.697014643, 3813.84984599627, -8640.78567919241, 13532.3624880123, -6791.45503201502, 23736.9325749868, -6288.85673487712, 2653.01998717792, 7707.08115794494, 4193.88900889905, -2049.31856452743, 5188.98828463805, -12706.9656390695, -8779.18046616365, -12271.7710692258, 10266.5811510890, -16312.1975443148, 734.987002434546, -8784.14959558142, 17599.0136125051, 2542.74982479494, 8658.6731183325, 3190.7779637495 [...]
+-55.299439373811, -2180.04689184823, -11025.9327717594, 7632.01346831773, 21045.6546898501, 4780.94393860272, 1675.99447081496, 11184.4459422888, 3365.95926317192, 11520.3618198465, -3030.01103920097, 4629.44440845244, 927.065870704748, -7238.13618382607, -17588.4913509685, 12129.6932453062, -5689.05834299718, -930.770971161313, -15644.3980267752, 23605.8532011534, 9847.16989789555, 601.780630480942, 6905.24842842838, 289.113464789784, 7959.01324514687, 13278.7408161417, 362.961083273427 [...]
+-12394.9183252770, -23106.7232560052, 25200.2921338436, 2324.49503431631, 6307.81201202278, -17150.8157782076, -2369.27151903657, 11046.5211452796, 2718.83390435207, 5481.69309245041, -14708.0776670154, -7613.51695111084, 18278.9383628902, -8344.05879824587, 7058.74488070327, -12204.2727213045, 15264.8199771176, 9146.92445289953, -11277.4831220327, -960.812219352984, 20091.8867586325, -5048.27937333798, -7451.69087830859, 12928.5317035245, -942.025129254335, -9633.37166079013, 2676.64225 [...]
+-9751.77183905745, -5651.68385717633, 1184.78427143391, -11482.8538203601, 5826.84910603849, 10808.5003695489, 2596.52683714747, -12235.0708639703, 9540.2532155542, 18524.7322907669, 9676.14345569246, 12202.8948078109, -978.208374968714, -5949.96831518904, -7570.4478776721, -6176.19070139067, 5903.47187614546, -16947.5397924615, -9917.60190622232, -9436.94552732175, 753.237022801788, 8677.14095846243, -3670.7136233795, -15109.6701245457, -16046.5130902084, 7289.67695668191, 12367.2936383 [...]
+21240.8018556036, 14663.1278628482, -405.721589572121, -16730.0219707816, 23892.5320917165, -9131.01603216184, -10203.1692394718, 7753.58040217341, -6186.4119348515, -8903.30568746681, -16574.7875947921, -2387.2994687502, -26539.6569444892, -3400.30379200774, -4316.25738873772, 8261.39560922152, -5199.45641457142, 8787.45474591198, 6551.62661461144, 11679.8932279761, -5546.09090149638, -2134.4652196386, -3521.60816151649, 18127.5916739776, 7754.48668511268, -3733.01491962842, 7570.362651 [...]
+-6245.67400737317, -10968.3994324051, -4538.7140335957, -2422.37075601698, 3351.78895817544, -5352.10430874693, -11207.2847352072, 14830.6042945743, 10371.8102959858, -4386.13769608045, 8932.91812383111, -6781.39830224414, -2621.46513110335, 5039.66526319216, 5075.52782247228, 23617.8511726941, 17430.1876035843, -12334.4700108307, 1862.84992808113, -10887.4423531066, 10242.1915556441, 6192.60410672415, -10168.6444347654, -724.467360777116, -19883.4775816114, -712.798393525282, -2679.7321 [...]
+-20991.7482421863, 11365.4366854272, 4666.77818670577, -2442.45462991233, -2686.42214070188, -2737.71633674297, -1676.106796766, 18594.5348358848, -14470.4367760656, -10229.3365800157, 12648.9585052787, 5841.2643987332, 1033.25163593174, -21015.9750555874, -3354.50790492322, 523.528900414461, -14154.3780352228, -5512.8014100096, -8569.47649275291, 1132.39557773216, -6016.70937313516, -7302.48129623702, -3327.8141587405, 6162.29199844604, -6633.2576637816, 707.393923179067, 12111.55861006 [...]
+14599.1153307625, 1857.8102974487, -21509.5593916908, 20154.4594302444, 2444.92350848362, -11129.3024824342, 16223.5930928827, -8472.4000475384, 2832.38810026205, 2411.87321083491, -12695.629774249, 11703.4181206879, 14424.6836047076, -8452.95588169832, 6467.44941309947, -5181.73851659205, -7360.8220769474, -15095.2794445154, -1505.39921975121, -15364.9212089794, 3719.49455086105, -2402.73186830620, 8380.19385063617, 22198.1499895313, -3490.41616256878, -3527.49145593546, -3412.545619148 [...]
+4943.35252411797, 11075.3217283485, 762.182219528345, -8693.38307697837, -3193.95832801231, -347.796157020952, 11726.4994356011, 4909.65756857728, 11264.1225042248, 1417.85431058858, 8249.75640600815, -7409.81380023618, 14678.8494282337, -286.395621776508, 12895.4706917881, -308.67143691699, 17886.5446387145, -21797.4806579285, -11244.4647737975, -10240.7611556429, -9972.60833977984, 40.2347052887917, 14892.9900172216, 639.789535248885, 488.98816948587, 1514.40660494326, 7743.40991236096 [...]
+-812.749512680273, -897.836565443133, -16880.1218055560, -8765.88150149703, 1302.98309811259, -7577.12387998186, 4437.54827158429, -18349.5922639181, -10359.4717452858, -1244.41590743458, -2709.21022738328, -8993.20173485101, -10101.2486544087, 1486.8314065085, -3314.66876046191, -23686.2919385308, -13653.4107994964, 8108.54080869006, -7510.9964873269, -2346.04165645239, -8896.09047284747, -8730.43374786793, -9216.79378306631, 21034.0921721138, -17671.6349137701, -9798.00100537285, 757.5 [...]
+3828.81301161258, -4622.38752872813, 8599.22389948273, -1269.13693334139, -9921.04213517033, -11361.9994843264, 13321.5088817283, -4640.90595616341, -7656.01810013211, 1695.13174681540, 9849.4368772214, -1102.29979713847, 97.6171454190532, -139.653576342100, 8274.60070190546, -3847.44977198468, -2476.55142254435, -24379.5082431159, 22507.5990170843, -7197.55455250624, -5872.66677797773, -8817.79164341874, 1854.97662249471, 8232.56633019795, -5052.03580700147, -6344.7087313201, 3749.62349 [...]
+3922.1745578446, -9884.73497850678, -18793.3170030683, 20508.3280794140, 816.460622838218, 6278.65070456951, 727.164438575311, -3078.85451838754, -10957.8916792635, -4936.72438511852, -8105.8209618005, 10913.0214782848, -13145.7336575862, -10035.2631604756, -3099.26933608443, 4321.34805083711, -18868.7423519384, 17488.6858884310, 7415.13444026865, -10656.1372402674, 3804.60104571978, -7662.86898055628, -1198.70505636689, -5672.11326052417, -4009.8014914464, 8673.37738552448, -4149.320852 [...]
+1701.58076277736, -4936.6720355489, 3104.09329825182, -17077.0639512134, -4215.03940345123, 5504.40959930213, 7462.14347160641, -10158.6146816197, 1993.16959976917, -14617.1793614441, 10335.9702220180, 9190.55532553451, -4909.41797204506, -2989.55188212738, 4301.42209193345, 11454.1882968293, 3701.29978293429, 21047.1475275476, -7191.39234680145, 6902.15708845364, -5958.35802620897, 5760.74285921521, -4637.86351155897, -6489.43098918427, 2629.58264137961, -1562.22224651178, -2211.2994291 [...]
+5141.49645309111, 11846.6977376765, -9846.49273510797, 13700.7774755134, 7292.81479667336, 7058.27546393718, 17642.9279398298, 8531.46992704352, -3011.17875622018, -18454.3790402475, -10826.0586934765, -5751.31923399328, 8881.63989741482, 25980.3864796844, -4892.22065991345, 10699.2496255138, -2062.61949762556, 9315.75957266335, 19538.8212723482, 5552.40489184869, -20182.8316813528, -8369.15753937852, -7209.07219897175, -4487.13224779441, 4021.63697559756, -11760.5590272872, -1687.933834 [...]
+7519.13096077688, 9429.316460853, -10344.4063542464, 1356.67609810456, 5093.59886914869, -8699.59356533254, 4147.02552779057, -12239.2743762804, -1468.11271932251, -6008.96179853084, -3059.22734214029, 21778.6009785456, 7210.80665814912, 12117.1628567543, 10993.4130916677, -7327.09834839703, 6439.44856312329, 6527.38111041857, 8816.20404016715, -1059.36608234424, -6927.38414776736, 18340.2443850582, 11178.6772379255, -5869.84926433522, 11806.5222917454, 2040.70644399884, 12539.2618312461 [...]
+9754.15106402797, 12365.0572403893, 15918.3859564001, -1236.42479579702, -16245.6296984805, 17114.1919073608, -2319.62239423824, 11496.9630897181, -24424.2934395559, 2528.39286345929, -11234.7629583543, -6602.4540580673, -10989.9670783103, 5505.06149856459, -3924.865251176, 7024.75802295104, -17650.8312371042, -1918.62900565708, 8578.02144120306, -8337.55737947481, -2294.31065526501, 9073.16263356938, 11441.2119763430, 11571.2941652508, 2080.24827060229, 10886.1992488735, 20230.446745302 [...]
+756.857504464321, -17261.3894004104, -2584.58195363165, 11113.4882034675, -10571.4189434449, 9855.77716244361, -3704.75759764183, 2336.63176546439, 1901.31077441758, 7099.24145278356, -2200.29549509131, -929.086179694327, 14707.1904694480, 2883.13780671581, 9110.57424495367, -2107.68811789895, -7504.05982568078, -23282.4495530565, 15109.9659940599, 1508.14497685141, -7043.56217349695, -2947.79171186935, 1224.17799196486, 6881.22195795753, -13326.8507632486, -22588.1645758349, 13111.14669 [...]
+-3462.2627067094, 23085.2340130042, 17446.0902530518, -9802.20463694433, 10514.6027848206, -2394.06469898151, -4865.06997898046, 5837.72177685885, -8592.81290402523, -10446.4232979594, 6724.41529281678, -9728.57947539467, -2604.06665723261, -1801.48027196513, 12096.5140921606, 6019.25606755985, -2031.59116652421, -13413.2994505037, -2236.37333616305, 20204.9635149907, -22519.7152142093, -3900.23282114878, 1660.13193076724, 15588.7553785844, 4976.77286304251, -1989.44895973368, 4404.08025 [...]
+-2979.61022150051, 16269.3373944261, 4981.27967573414, 313.683774750004, 18417.5742026475, 14418.7795588318, -2535.96492470869, 734.882736329146, -7500.0183406341, -1421.98026172811, -1785.30759064097, 12571.2925057958, 286.232510937769, -3528.30381581439, 13084.5889966818, -2169.10967639338, 15819.7672708510, 9984.30893207583, 9840.03811279965, -1560.84244992973, 6025.60737783825, 5353.44218986214, -5095.62355431822, -11392.2419528319, 463.173061412602, -5904.0650038607, 12798.134982287 [...]
+3514.78097137473, 18450.6610220185, -2022.37871610524, 24455.8300847350, -753.450804750748, -5085.2561204647, 14262.0383964840, -2683.11375360351, 21612.5411011303, 929.552173063874, -3689.17272898886, 11806.7335852845, -6145.98879926133, 1000.61650819915, 12921.7820476143, -4673.97183521737, 2885.73687101265, 4628.70551768604, 1216.64531255665, -4080.519271485, -4108.03319390407, 10532.5408148525, 20202.9866356295, -8642.76072246281, 15336.9830510347, -7563.64928320476, 1350.19536975311 [...]
+-1001.97553977363, 1537.99087118333, 11160.9613125144, 6245.08825772727, -2672.71517253309, -542.384623605574, -321.933284405703, -7014.03608897938, 12796.8438190059, -2454.03054704785, -5976.63015829157, -6300.60461683718, 471.978590515539, -10887.0099518309, 257.017847699904, 17989.3164595323, 7403.45101053367, 172.882604903110, 3343.37409506743, 11392.9980410026, 1086.82702683619, 2262.33521664130, 8630.64575120628, 14288.6131806650, -5890.61419288332, 22672.3718261415, -4644.23729235 [...]
+3168.34630932452, -14608.9632935833, -5841.25604623989, -6971.46563426022, -6396.23902981286, 15633.1907505897, -11467.8525337780, -20247.4957165889, -3053.57484486658, 16386.8259408742, -10566.4380517018, 11418.0830909786, 7303.53130959838, -6698.12475651551, -8031.60766145286, -10753.6213120655, 1174.53073488398, 8428.1959889604, -1204.77070307929, -1296.94200633761, 20275.6313729974, 3972.15741106619, 9546.72628878589, -18047.9537070811, 14603.1322857699, -736.655149446964, -25791.436 [...]
+-7334.9638705521, -4124.93098588921, -3443.10549971041, -499.687033115314, -7114.57128161013, -3907.74150285733, -3800.38477454078, 20833.1757094679, -8309.9379951721, -4662.60156922176, 1902.20623514487, -5278.53786436722, -561.569575207408, 17433.7333875977, -2467.97965091535, -1601.91460526934, -9544.30960598875, -22709.4435021978, -1761.10305044045, 2363.19934958476, -5421.29973512356, 9886.69154956928, 13327.5768990852, 125.784841668597, 5669.98082001985, 7396.20143098359, -8866.141 [...]
+8543.2752084995, -4376.73625820616, 11203.0054140291, 7638.08269816506, 3023.19281923911, 7901.49115563596, -6361.51993202966, -12656.6929241090, -3098.52046810914, 16338.2366864528, -6071.91676146463, -8241.02727578396, 2386.97349882754, 6893.41589135493, 13091.9672523808, -4131.24017634795, 14399.3433990139, 10455.7340360748, 2743.24229567452, 5161.34265186617, 5562.2185232314, -1581.23051135089, -19073.8336347424, -5162.84860229433, -6813.43264193036, 9443.77463793398, 13517.356644801 [...]
+21672.2729260340, -30908.6916330856, -3566.97688413406, 10544.7335748599, 4242.32187111945, 2618.64244456987, 717.25436776645, -11861.7689434327, 6000.54103766133, 3211.38141666677, 12462.3822663589, 1649.19809863416, -4180.10731733913, 12098.6284835154, 8184.40575901185, 7708.54386466867, -4234.06687644096, -6125.07892670568, 6070.76484083661, 5754.72896816747, -4885.61931488936, 7712.94585637378, -6278.6481367129, -4165.37446525893, 6659.07022862837, -4773.93988879961, -3675.3868457450 [...]
+-7060.7251979029, 6104.77071610842, 16812.2690702145, -7280.8357541538, 7013.09554754342, 18693.5330204806, -4491.70259600975, 79.3952696341833, -17208.6175062352, -9092.33100234912, -16292.0818156198, -1866.90535193725, -722.833733476168, 13210.9291568990, 7808.31419082779, 84.2956223578041, -4478.53042413896, 21258.3163788742, 4151.09761780012, 2359.99878872825, 19655.0666782083, 4503.16447102658, 4155.39431334648, -10677.1865793546, -11385.2049714565, 2084.06499033627, -193.7220021291 [...]
+7820.25504302286, 3224.97921669903, 9514.18010231877, 2432.68270368687, -12608.5229829268, -14783.9239800200, -10071.9333562050, 3607.27197291786, 13963.0979447632, -890.126133117728, 2595.22065444048, 7950.16231067363, 9559.86220585736, 22914.9748904432, 18984.0338479696, 11081.9193986313, -7682.53496282261, 10399.5046967577, -11693.2669602558, 13648.5145972933, -17524.1539338326, 2220.67385077735, -5742.19598402325, -6375.35146854258, 4269.00069467802, -4120.34909038822, 9093.802535075 [...]
+-15255.5345464590, -2460.16250108116, 10865.4283996266, 6660.63283775413, -19461.8043244917, -1058.99870184242, -17458.2236285558, -5757.92981577371, 8676.58158494888, 18283.6623925943, -164.504655163886, 19479.6747393018, 5381.73956702062, -25441.3331563573, 3380.83872244757, 14351.6490400014, 10332.9718765569, 5520.25324114013, -12814.4587968501, -12259.4730368586, -10734.8241556652, 638.001975922108, 5670.78869964398, -6524.63367247204, 5604.32623649426, 2480.68034977586, 8129.9384975 [...]
+-9194.59454651027, -13494.6818438274, 2443.8515939139, -6568.74486439215, -13741.2629249930, 9339.82085293444, -17688.2481219677, 6037.23848678568, 1378.7608392112, 18651.9164189116, -4163.66565065605, 4016.60707798145, -13685.3722326923, -5948.46445157636, -6124.86609594516, -10315.4944399720, -14319.5037958476, -4538.11414884918, 1549.60183623258, -17173.1734754869, -678.542540336075, -63.0052818284275, 9670.8458992273, -19538.1325494678, 12081.9588183483, -3808.64684896213, 3642.81424 [...]
+-19246.4140650754, -9306.56533910381, -15108.1195498581, 11979.1515007085, -13586.9278687979, 29661.9089619145, -13131.4505117571, -13072.8685325767, 6994.01524480122, -12339.311512469, 15609.6886036190, -2140.74139625551, 3101.37118607973, -5197.86965051266, -5572.86410400057, 677.04540538111, 9358.0223480532, -10681.5608390205, -5347.6103975998, -9002.19677045045, -7105.32471331241, -11400.9491438397, -10227.9424712515, 14941.6146680298, -10163.4077973402, -1886.26194240842, -267.17161 [...]
+-11670.0432893360, -19059.7572530895, -940.74021047721, -1667.34035061631, -2121.17283136845, -4669.48807541222, -13256.6084913021, -11581.3851524369, 10051.9996812391, 4620.53240340594, 4878.24573718031, -7504.81514783841, -5682.95514096415, 22072.2515918978, -9495.58670163205, 15900.8848597266, 3078.11383058944, 1957.33498011147, 2546.13790270452, 13504.4508578697, 8681.688699709, -11410.7501183060, 30996.8240244709, -16030.2744953794, -1746.97853035122, -4252.34051369451, 991.18443757 [...]
+-8597.18824130959, -994.583381227816, -119.370256319806, 15155.2570688008, -16168.3709762742, -7944.62944468993, -450.825375414572, -5784.37725597229, -3314.05001334048, -16916.2628347579, -10893.4808797810, 5627.3019238433, -5192.49286584986, -2636.55076621418, -6620.52252048341, 11872.3260722238, 822.72322160161, 12995.2473737771, 3070.82414782691, 2245.77951765494, 13138.1384462867, -5372.06508922699, 13099.0745777994, -2475.08209057488, 1312.05325729374, 14786.2822947406, 10539.55944 [...]
+-12083.3543202779, 20339.5795605570, -9045.20630980912, 8358.4851573403, -12299.8434994062, 8996.85148929007, -2459.55911976271, 7666.39769315022, -3881.52619381325, -7269.59287751599, 521.527759904658, -10983.2914915616, 17622.5021206519, 785.632524066307, -18964.448808123, -3517.98157536702, -2459.23657135753, -4508.99835531820, -244.376866717029, -10682.4547510387, -1758.04122111414, -4537.00017804686, 3945.27800633945, -21954.8798504011, 6263.64390777797, 3113.55098788255, 12596.7046 [...]
+-5896.66066528988, 15110.0039868910, 6476.87257118639, -1193.40083532965, 8535.63824721014, -18356.2026172588, -3697.97750695282, 21714.1610333133, 4299.65011588421, 20090.868123797, 2176.04156326658, -8872.79177982998, -3903.67974728592, -5943.63486239618, -3729.58497652122, 4648.95009690064, 7434.51369025689, -514.814743635195, 742.59920277677, -1211.31671482865, 16999.4008673752, -15413.6144468549, -4109.67733241397, -6504.6591510837, -2837.09815369125, 391.5055644391, 20765.982628828 [...]
+9574.39491412108, -6833.00692859199, -12812.2039114524, 3026.36114369259, -4944.91558871315, -22409.3459254539, 2123.01674133954, -5397.47668745529, 17587.868449399, 14446.2387924851, -3006.73172816668, 5131.91903731605, 9134.41793179122, 5050.27960289052, 10927.5282566699, 10064.8389604667, 9629.36640957714, -6825.09196658832, -7137.17850077494, -2116.95454343718, -863.458074412673, 20908.0977793104, 6495.6394047427, 1879.08845056274, 10696.1392739417, -2910.95488228891, -8116.445208514 [...]
+-8267.17842526116, -4452.13814956093, 2611.23111832483, -1671.04153586379, -381.478863731553, -22464.2219376329, 4486.91033137275, -12642.1219998427, 3495.65624711004, 9880.02368908113, 3203.67732069322, 3089.71874294152, 3170.43471680319, -3231.13795423974, -1504.17585561283, 12341.1910299189, -1051.78672184315, 21021.3395587895, 1806.06260626113, -7890.88328653612, 7021.7176939289, 1727.1081008694, -5720.13411244065, 12371.6748104389, -18007.7682950966, 17924.3691548234, -363.479446002 [...]
+1157.33625820679, -18512.4829421582, -3980.78141778758, -9620.35056279173, -2337.38623704008, 8618.4231925495, 7851.47257417668, -3102.78949620576, -4528.3864195943, 17784.6684368406, -6436.02317439024, -1349.06728749926, 27330.6692126784, -389.950399496168, -9924.9348266418, 15106.3365037050, -11240.7427785121, -13952.5388120284, -508.740234287322, 15789.3802735573, -3049.98223529669, 780.497458165328, 3598.65530063396, -7680.63466998475, -5022.70141006345, 7654.63380791185, 9352.461691 [...]
+-15716.69302841, 2641.35871193141, -5431.10740818998, 4355.74168444531, -4751.18494036194, 12601.6566536760, 2989.13997063934, -28393.6411086624, 719.094953630822, -14416.5849974152, -11527.9187618237, -2412.79069759059, 13708.9791074068, 3660.01102744571, -11347.3181198440, 11008.7905292922, 2486.79556935166, 19776.5308824534, -3750.98615278557, 19430.4964686588, -8574.20011819522, 11604.4812056002, -9240.43055118586, 11827.3432902354, 11038.9452453513, -9529.29000764426, -6966.68644533 [...]
+-661.36389444638, 3241.28250949624, -9782.33803938969, -1618.91273525861, -2845.47619230761, -2209.96142479661, -7864.87956138218, -11694.1806127623, 7780.83376273477, -5183.70648513456, 5637.13137756477, 2315.88159715895, 1272.06999455968, -8069.07832469416, -16345.3594724720, -4694.92941177597, 6291.44798352014, 3476.35507539614, 2875.34262558213, -6545.76231373808, 3780.09448267416, -5835.23319274122, 6180.89910905832, -3323.4797229384, 8926.65947969496, -1622.05631287676, -1301.29041 [...]
+2115.45035826121, 3318.88835065685, 17636.0253358195, -24335.6550482184, -17710.5967773415, -1000.41842744583, -3150.55934443393, 9766.14772363594, -347.274926138034, -4781.31957912548, 3129.22612005287, 14815.6700219758, 7383.52920161634, 7530.90596748557, -403.827613780861, 4280.62045255785, -5647.58499672009, 14642.7433154623, -3606.1811681432, 10132.0018512412, -1545.22997534068, -4517.65766629123, -11620.9501192099, 12637.2632206577, -4974.08770946204, 707.717506974476, 12800.473669 [...]
+-348.434874770309, -1442.48613952641, 522.043477072385, 7476.40172411877, 6263.92262385745, -9710.38382510373, 700.71360462044, 3328.51074948535, -12523.5581589149, -630.87757392093, 17324.6362909880, -8844.68935322665, -7464.490597516, 4365.18408201715, 4788.1352456205, 6408.51549215038, 595.659066315795, 9016.02464174504, -6640.70077997544, 3381.06422965743, -2734.46477347376, -8669.818083636, -6943.69014514754, -18243.9547985363, -3865.08923216475, 18518.4517049130, 21705.0269771949,  [...]
+5595.10669015399, -10490.0258799730, 13509.1845862979, -10317.5847361796, 3489.47643593894, 7174.17485327797, 23462.8073296808, -10510.9776574240, 27234.9722219110, 13639.3956974653, 19309.4788111635, 13409.5004165638, 11206.0246709038, 11581.4159798133, -6273.44960008674, -7994.61741288247, 1460.80003607539, 10.5048997477827, -18477.9035860003, -5130.51436416592, 1904.8280785589, -7271.01624847709, -2663.45722147244, -16978.1701965073, 6446.73185769028, -563.881723321335, -8215.27392354 [...]
+27165.2398665504, -6983.7836583044, -788.061385054776, 22045.8082442837, -12051.7719413167, 8185.1356168216, 6233.03411751973, 4359.15764325676, 4002.97935235069, 6062.54690834348, 11330.0061085178, -13447.9512875629, -8703.47879546201, 16981.4211586934, 449.528342776584, 9631.69323919747, -9766.58576049276, -1979.97043560223, 10397.9346510749, -317.600693486734, 8114.67892248548, 8724.34642154605, 14613.4211092749, 7942.20183749736, -3340.20532815625, -7316.24165275268, -7196.5206538537 [...]
+12174.1287051788, 1002.68624119883, -15798.2728768610, -3318.87635876337, -915.625299520234, -783.793142331242, 21127.7012023260, -12099.7222904140, -11802.2451715849, -2382.9783807585, 3779.27048174908, 3131.92792809469, 12766.9429619489, -13054.1815877623, 14994.1243485881, 8082.9767641874, -12748.8685051709, -9893.30056776048, -6782.19134684039, -7902.53474091733, -13430.3991654493, -14115.2965691078, -1658.48108084085, -11364.7241306200, 1714.58357208716, 4765.87550809285, 7870.15750 [...]
+-19194.4836509271, 16690.7691053274, -9135.0038082823, 5561.97184035924, -4660.1142073968, -22540.5220126727, 11321.5189932270, -12738.7607335448, 17129.6403567650, 2937.80544776737, -14361.6275282812, -1803.81783077892, -12153.8650893305, 5969.66844496303, 13737.8942412784, 4930.14330215612, 1304.07511457758, -3396.1995512092, 10543.6538595803, -12271.8441171715, 4136.45472299558, 9183.66288465696, -8382.86847987278, -2332.55722133583, -6047.95799491161, -3203.76399438976, 14015.0825906 [...]
+-6262.30564401455, 1990.71137303970, -7381.26032941805, 13579.3968950233, -23865.9088989098, -19078.3063718847, -12686.8518863989, -753.148377427626, 9399.37978395805, 12483.4702766617, 2412.77799539585, -14748.9297307734, 19059.9660317070, 15958.4193681362, 4699.7024211032, 3597.91661852441, 15725.9733517252, 8717.25962755068, -2504.34259932754, -9108.61983730721, 12691.7004020384, -18444.0682946171, 8626.46276604682, -2044.18577102582, -8.58478560643298, 16267.3177384626, 9544.26640313 [...]
+9047.15984031135, -202.089170630779, 6689.62359799634, -5918.60173440244, 16039.9839429608, 2417.95602889567, -0.581754257570036, 9753.5410904948, -14949.8146385685, 3491.09414796746, 9160.80611693221, 8020.28729240413, 16375.1429507220, -4667.55802791393, 21302.7714095716, 3085.18897847637, -16708.0325376438, 1525.72479934248, 7616.60383736634, -12137.2537836659, 2944.04316282286, 4962.27862296448, 7470.0226570673, 1519.99663187308, 5915.21518743556, 10180.8312467463, 14525.8885716085,  [...]
+-4473.78376761842, -17500.9159506709, 13454.5017473187, 2036.46178321677, 11274.4998802876, 10265.3947851390, -13164.0464281482, 17049.6350627056, 27720.9813530775, 826.202626792229, 1318.04522066844, -12130.5861358372, -6966.93915236586, -6757.44672407371, 6437.44217074992, 15509.4846293982, -13146.8185039409, -1243.63962482993, -9221.58101782941, 15158.5586122002, 11068.1863566947, -18501.3763242581, -19290.3735075738, -6811.1055437046, 1740.41443804786, 20442.8846936747, 2165.89925485 [...]
+7682.06374638982, -2453.54117697428, 2697.2898728059, 6187.63140302813, -11497.5339871122, -7278.24089511527, 5489.58332155309, -14982.5024447232, -5425.31380443946, -4259.23429880798, -1381.9716467828, 14456.5540833726, -6302.97208036962, 10548.1100083653, 2392.1163172432, -3983.31831911908, -10517.5020595836, -9127.90530121974, -6522.94748962773, -13720.1380210977, -559.482111078119, -17634.8979645857, 1812.88333750318, 7533.25852743832, -7814.04654138922, -9788.38074402413, -9042.4096 [...]
+4956.98608473602, -5324.72413243278, 13425.65855402, 8649.08277048687, -7297.48826544117, -3058.65759300973, -2216.67762340168, 2007.03260318213, 6490.97599461176, 4963.52168834572, 8185.77813657503, 13420.9633670092, -6960.37498708188, 7149.73580947858, -219.643078262508, 8212.1273106092, 447.77101403285, 374.129889165055, -4474.91194502609, 2009.52698051270, -3386.11337079578, 13399.6291534768, -1344.62473982567, -15509.9892965230, 8880.3129749471, -19896.5127441399, 17794.5954488847,  [...]
+8456.11010721427, -4475.51961554564, 21742.0853662219, 1774.20736552838, -14446.5932133901, 1650.12636063020, 6461.61985348238, 2409.12135174136, 6867.31381083633, 5931.13460709798, 5664.80475125857, -1620.78789688914, 11008.1306081290, 3976.24043373292, -5225.30569631495, 6308.50541168618, 7047.74483379138, 6651.78386513575, -9570.87071414235, 2431.78794591946, -22032.7539325304, -6009.81327615179, 6000.21768050292, 12755.1289798737, -11665.5239425594, 8407.14238212756, -5945.2468640902 [...]
+-6547.43839824042, 7400.08710091703, 14953.3411947185, 7036.97760617977, 13049.2518650865, -5623.76625250321, 21861.8979889137, -9877.50355406682, -23290.3060490991, 3892.94311395292, 15474.1037471253, 18302.6771762118, -2674.08277040581, 8028.62673378715, 15842.0724779558, -1422.28161090380, 2983.91082832048, -1197.47524293428, 1576.22813236465, 14082.9356481694, 15957.1565335684, 4537.21024444517, 6941.88855054983, -3126.09584864213, 4222.42149216417, -20236.7589835229, -4181.441552706 [...]
+-5224.20958174674, -12624.9183993617, 4432.26316382146, 16296.2404170619, 8844.87802835533, 18175.7455917418, -15747.9676253582, 7144.49312954772, 2282.58200589500, 3082.75390154819, 185.780394133068, 8321.90244737388, 3861.47216727983, 8467.42303223201, -5657.40903854151, 1614.29888946253, -959.324901424283, -2924.66394210542, 305.836931943124, 4913.00389771064, -3111.04078705443, -16211.9031930572, 16998.9578558899, 13915.8013046289, 10203.6868096650, -29525.9167656112, -7541.351400591 [...]
+-9732.23355591897, -6491.96955173305, 3220.03846232002, 17256.7513058740, 2379.55843908724, 3478.6282934002, 19571.4031945315, 9010.47992937297, 15096.6589735226, 3117.08006901738, -5732.91687338069, -7607.68272249484, 5511.93807530604, -4986.95256172803, 412.688074761899, 2824.80446725208, 4392.29814658474, -8261.91436335845, -2607.15668232364, -20081.0902846733, -5948.21892175002, -3558.28358000479, -4185.13521719441, -14356.9258673079, 6924.64290196498, 9642.55271185118, -13131.141695 [...]
+-14270.8766211776, -1260.97339309871, 8082.50374246713, -12953.1595620270, -1545.01729515977, -9796.33991937967, -14781.3915029531, -6756.06221234137, -4528.72924458271, -5275.34253959614, 10906.4182538318, 8718.96347758418, -3956.66004874973, -3623.77126868979, 9295.72877495653, 1630.85002757810, -12883.2468157395, 3491.27816586926, 952.742379177847, 5123.4243293331, -8198.3179873759, 7152.63600441195, 1727.51368570121, -9231.88989679799, 11648.7264776683, -3784.45822168470, 7639.053273 [...]
+-30189.2004196161, -53.0580451055717, -11826.5236647867, -8514.36139425038, -4252.22183567755, -13042.4619420806, -17312.6164671050, 5152.0897468403, -10755.4496198294, 3742.29426760787, 13259.6171631127, -12645.1728267360, 12558.1555301745, 6768.03010596244, -1433.05522145318, -7845.8922489987, 5347.75994383813, 7584.70078889794, -8916.86578237102, -5184.78510544169, 13016.6306031695, 4953.44200390955, -5680.11911793564, -13788.6807701201, 1437.45480082168, -7272.30363579916, -4105.0774 [...]
+-6564.63622288045, 10748.1002221352, 23468.5355367535, 12598.4933311302, 13460.5863050505, 5706.06211715046, 1604.83277387448, 5849.02114836171, 14031.4226232932, 8746.07525154625, 4497.81446079933, 7989.15159479645, -8982.8257594731, 12905.1709970296, -9653.4466494428, -8817.42711159977, 16370.3718546186, -4019.27436608034, 21073.0507935328, 6633.50789741605, -3761.75451819886, 9630.5603729171, -5458.85972613023, 573.115493290214, -8764.52082529493, 7760.73218175658, 12433.3393876703, 8 [...]
+3798.20844948125, 12579.6088367998, 1512.03781519445, -18276.8302888373, 6968.19928549053, 1580.24107045203, -10423.4613206322, -3849.08566402506, 4938.86886172145, -4818.18830284043, 10051.4425207044, -4161.03336559576, -3990.65064265583, -2732.97855786998, -158.881482677201, -9880.73366200843, 6327.00761700785, 15251.7944203880, 12089.0280751109, 938.809564172449, -15.4273167719622, 4590.43185810553, 10323.7278422363, 4433.88425277463, 8096.54937196795, -8905.04611526048, -3057.9297242 [...]
+4028.09111809484, -16943.0019068241, 953.842825108231, -4778.05925837431, -7274.26636116392, -7602.74321444296, -4819.84698139567, -1520.65007567045, 20731.6481848955, 2654.60147637603, 17935.1533913359, 7354.6546865329, -16067.7255428990, 10887.7709264075, -11008.4988164710, -82.7521518258531, 15834.0644820559, 13268.8130221053, -5164.86012045352, 4801.47713903438, -6035.21652512, 12679.0687860767, 4614.86795876857, 8383.17266218043, -16260.8134606125, 2392.00513668064, 16839.6461884282 [...]
+-3944.4946825736, 18032.5015161406, -5533.00849061767, -10895.2047381381, 16510.6214278763, -5029.8525613643, -1652.41094564115, -6273.4919273872, 4790.13121069816, 6850.85631861184, 16118.7763707643, 6762.99979087465, 7773.34193757578, -13335.1702717806, -3128.144294066, 5876.26433010302, 326.242654985643, 8976.44068732377, -5592.29152041123, 2878.60140330661, -7170.31443871253, 3634.68441651529, 15730.704618506, 1618.47427083631, -361.41649400301, 3089.55219290573, -14144.9453411747, 2 [...]
+-8314.58935488631, 13758.1512873845, 4193.25666262212, 1581.97414602027, -12475.5405774893, 10382.7451364230, 7473.9566938359, 2003.93123145172, 3461.75953425425, -6922.44533610839, 6697.17206765934, -14022.7833191756, -7071.05559155095, 3859.00236956742, 6226.33511509696, -6997.32611759636, 3542.70416294125, 10152.7102026396, -15376.4097202961, -9248.561649843, -4843.33243317297, -7003.16596652202, 12586.3419633284, -11644.0993647528, 5583.75627013135, -1980.77100639073, 4407.0572523708 [...]
+-13688.2753230624, 1563.24005904437, 15226.7629108824, 12580.7082729723, 10869.2050333935, -7606.87567902227, -647.97287299993, -154.017633301918, -351.021917835695, 9634.71563357439, -4671.19661320650, 9358.65196020796, -6183.23299612937, 12407.0263915746, -591.218801402813, -26151.2864188335, 6379.05910860042, -9143.01089342181, -11010.2428287726, 7231.57143146763, -10952.7146421567, 4386.04466297222, -11346.8440411997, 11274.2839713608, -520.246802790196, -6669.54630382784, 1384.83917 [...]
+
+double y3[100] = {
+-41713424.5881424, -101088192.692712, -70340368.016507, -48293529.5208606, -74479322.5424261, 4910314.99208515, 14484012.0449694, -15662680.9130609, 50042721.3589472, 8160690.91463197, -92285139.316809, -19157318.1695229, -11239319.1334258, 71078069.3903963, 11580115.4732065, 19259581.1224577, -252598.900653503, -159254900.119055, 23911935.3070683, -25086928.0926788, -85205170.6560223, 16163347.7806557, -37130848.4796604, -137606581.621502, -30769671.1663977, 150668395.465123, -106425211 [...]
+
+double lars3[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 51.32911692678412400, 110.34148990308209000, 129.32450872975195000, 139.67442869293515000, 143.45003955672502000, 150.58197464587533000, 216.66298348198956000, 250.14963501283992000, 251.90856833119935000, 289.07273566390313000, 291.0510323 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -54.62955408275207200, -230.93225514683724000, -403.43271206647256000, -417.92989801940467000, -550.78659783861849000, -564.59217106337280000, -779.26940095704356000, -809.47979390565081000, -872.99912091810040000, -936.57491474798417000, -1026.14198978681840000, -1065.63093910629250000, -1090.52025838018490000, -1100.95365333022070000, -1122.35469958685010000, -1337.06365562243080000, -1454.29504856732340000, -1460.537349123 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -165.02807312869055000, -270.60290745847539000, -279.14868785567722000, -436.74822235387290000, -443.2362366065413 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 79.46056711794173600, 163.73590024695710000, 269.30237366875241000, 317.53891580061503000, 349.05698416604235000, 360.14160950289278000, 382.64180453816249000, 599.82468915570416000, 718.11179962683332000, 726.89294963793884000, 862.50410278083632000, 866.94227 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 42.33186748223857200, 71.48788661223757400, 81.99891664314770900, 102.86981349469572000, 307.25654617504370000, 418.26412937089526000, 424.57931446556745000, 544.87626175699359000, 548.8272780932429 [...]
+0.00000000000000000, -164.65876857644622000, -636.97591266520021000, -712.07145947973970000, -912.43263636208599000, -1090.37442494736590000, -1107.73864659358080000, -1230.44962056066970000, -1244.34015597815140000, -1478.61762103481490000, -1503.11566127304740000, -1549.43786047034430000, -1597.18482570193900000, -1654.34030514116600000, -1670.84251481888030000, -1681.54640702147690000, -1687.98192885275060000, -1701.01338627385010000, -1782.60384002374330000, -1827.78603176837100000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+586.89068893129888000, 766.98866577369097000, 1175.41666997288730000, 1235.86131619702950000, 1404.55978006437230000, 1598.96205072372910000, 1613.60450940444410000, 1748.89793713354270000, 1762.44027094809800000, 1953.78581661305290000, 1980.24118822064770000, 2051.19673959921600000, 2129.37929269509780000, 2211.65713767908850000, 2245.99154848585070000, 2269.65464405835340000, 2277.86820013078300000, 2295.22096126769430000, 2477.19896460656130000, 2585.89359776000170000, 2593.464687649 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -62.81562 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -194.82804034945818000, -388.95445916011994000, -406.63187125465782000, -569.14825074110740000, -579.69348600332034000, -755.04020789230299000, -774.68236536293216000, -823.42582911660213000, -877.65148548803222000, -935.70811379475720000, -958.43929394063503000, -974.36986599049271000, -979.50720485409784000, -990.47424755480085000, -1093.00929432126600000, -1148.96122097757730000, -1153.8192703175112000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -14.80459572908219600, -18.88876240992974000, -27.69653695338233800, -80.52532588625982200, -112.24411183181100000, -116.33136450569516000, -184.66198608487426000, -188.13236179 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.23132499369578770, 61.52153893652718600, 96.14603725819709700, 97.37567594443768800, 124.76110874695776000, 127.30311763066652000, 15 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -131.04377197616733000, -136.92954001883496000, -18 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.96621516488069400, -205.54183421199843000, -216.69464938003341000, -414.34966311828606000, -433.42658979260659000, -489.17171002175911000, -555.10144509725058000, -651.70431454358550000, -689.53067719737498000, -716.73448498801542000, -726.38681654081086000, -744.90779175595526000, -914.91601104277265000, -999.50088061283429000, -1007.14781187964080000, -1115. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -122.83474759689297000, -137.78889711141824000, -271.28517431044889000, -281.20330834078396000, -464.04073007853526000, -485.15777419328458000, -537.17498473275782000, -593.16882007596996000, -652.59518818017875000, -674.15709218699249000, -689.71228793767045000, -694.99661962852656000, -705.92779261797136000, -803.90362692684573000, -869.24904066706210000, -871.39409743358613000, -91 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -166.79220754404153000, -183.50027401612596000, -221.02556399427007000, -255.88013282587784000, -299.71682372578056000, -323.93811863836845000, -340.87406663179911000, -345.77495682180449000, -355.03346504351964000, -447.75568246458477000, -494.81207279141364000, -497.07241037178466000, -538.5397113012 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -18.82445501421870700, -342.94803206586943000, -378.91519994403200000, -461.15735888699282000, -542.31949084406983000, -653.10345041492951000, -693.21047176282377000, -717.73750675928409000, -725.49880321406192000, -741.05792590736235000, -864.36902463184924000, -926.28730352659886000, -929.90016100931541000, -987.66122191 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 96.02064392166350600, 132.36467565197447000, 155.83141916366580000, 165.59671513660001000, 183.69276664780676000, 354.68999172692224000, 447.60260340442215000, 453.90775839891609000, 567.73598075795712000, 572.292726079 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.42233492249030300, 60.134020 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -34.05837789162090000, -114.86730040981722000, -192.84708993901532000, -288.03338966617753000, -325.36462543653977000, -350.32561851395940000, -359.60992608483394000, -377.60440850226161000, -576.59494742918071000, -700.82619322715630000, -709.15771305774069000, -892.72559500732473 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -112.62079201562595000, -123.32864743266224000, -319.98461451896935000, -340.12274887626739000, -387.13060805448026000, -432.94796319138038000, -476.81608192796460000, -489.35813608292733000, -496.43796336781071000, -499.89130198601032000, -507.07421905342414000, -585.58879104224923000, -617.48570434560474000, -619.50332744122954000, -635.4804 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -399.35155768935039000, -463.86216493996557000, -649.63376691313840000, -837.32231872587511000, -857.85767833596128000, -1036.92665038034940000, -1051.48131640703880000, -1302.51899127537010000, -1326.36306363284530000, -1370.84833147876110000, -1422.39611479284050000, -1489.05619788864560000, -1514.31058153352770000, -1529.15699357892230000, -1535.87320562764880000, -1548.97116098615860000, -1693.15011369172360000, -1771.67921059596420000, -1777 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -77.07885216891223500, -82.03571279300508900, -186.00753244313034000, -189.83890008774105000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 9.97384358030135760, 30.02509329230067800, 238.37716905798931000, 367.23878397202310000, 375.25891431087376000, 503.80949694557427000, 509.11276347486421000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -9.34308173878586960, -152.30472963361154000, -158.96962473121815000, -2 [...]
+
+double larslsq3[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 709.33450276780593000, 667.47036173126560000, 571.58586043907314000, 488.56883453120423000, 483.43463893572419000, 459.62920387399464000, 447.00272113202459000, 419.85556759181492000, 386.19087744712823000, 414.62108556781993000, 452.094422 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1718.48074585271300000, -1854.90032644746000000, -1724.20126742470120000, -1540.82281002172160000, -1574.35287985019360000, -1805.34065877828700000, -1664.56979145244080000, -1891.25835349398310000, -1815.13833161735850000, -1751.57461187608370000, -1871.73420973327300000, -1985.63403571994350000, -1929.53585373489000000, -2040.45555917285490000, -2049.72349438361650000, -2085.47844945530280000, -2048.40828347576640000, -193 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -740.26933743243683000, -805.64224097621366000, -931.55950579631053000, -969.15249566211025000, -971.3935295087254 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1258.04540904392840000, 1244.09002306456750000, 1265.94303178950140000, 1441.34111606233180000, 1411.52681723165960000, 1358.28523191861790000, 1357.63987249881690000, 1356.86289946738630000, 1317.57527169365150000, 1397.27259841530830000, 1320.6270133048076000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1028.56851951420570000, 1054.33335857293290000, 1028.49167319076990000, 1007.26571206213700000, 1019.69098405563150000, 980.83591748278218000, 906.69971559483338000, 951.26457380257432000, 870.46006 [...]
+0.00000000000000000, -2735.11025149239960000, -3073.51307099401670000, -2999.25496595169900000, -2758.00931795173850000, -2452.80512944764860000, -2452.70045313151380000, -2175.85030834252480000, -2492.72445210342450000, -2444.74677875528600000, -2380.34538571706250000, -2236.50370707544650000, -2209.26939214339200000, -2193.93846350644840000, -2055.30663113756600000, -2042.37316930237720000, -2267.48505842160690000, -2265.70386066161020000, -2067.00512327453500000, -2056.763419337863500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+3598.56365879492750000, 3578.45820151094680000, 3282.36963830812010000, 3076.82264829592850000, 2958.48332941738270000, 3087.42423083689710000, 2747.74965455492380000, 2791.23747281157690000, 2979.53063923588710000, 2742.86943941106480000, 2927.55934590642250000, 3103.63243617755050000, 3131.62799861522220000, 2988.43259408712080000, 3045.90557018023900000, 3067.33440384687580000, 3017.47899994685170000, 3047.16593577794630000, 3111.52289950756180000, 3136.74366016890690000, 3171.4646733 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -588.2090 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1989.43762382136220000, -1875.30454951886190000, -1775.85213289350010000, -1821.22124776184300000, -1527.42557153008650000, -1478.14680581743710000, -1478.03186670610920000, -1546.40465505141610000, -1572.78859439369720000, -1483.81391261876320000, -1488.02431669476480000, -1511.38730088565240000, -1442.11210732643140000, -1465.70770342779250000, -1450.41751474804210000, -1432.51820439384660000, -1524.69 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -513.86552073601365000, -386.65806461794750000, -409.36270248830624000, -264.67156695450717000, -272.99073483183105000, -428.36464129946029000, -415.49715347541945000, -470.6385 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 276.25253237277690000, 254.24761256217585000, 271.61842727440285000, 191.25002606515253000, 217.27484298406097000, 334.2355438349894100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -573.73711122166128000, -616.06093446467378000, -58 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1958.74744272092130000, -1596.74841439581840000, -1219.03177281734320000, -1229.45269445755530000, -1116.53621680823610000, -1316.00137027201980000, -1400.27711466166990000, -1563.72064189274190000, -1570.79926941984420000, -1633.77117603648320000, -1595.55585817143700000, -1547.47483720630040000, -1507.51665862056570000, -1428.16584161180960000, -1590.9377585703 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1063.33238469546450000, -1296.07634333728740000, -1299.77894467307120000, -1172.57591553008730000, -1218.03797953892190000, -1241.32025126129290000, -1308.71108225518720000, -1310.97281585254950000, -1213.63253931401550000, -1176.50062872095190000, -1214.07583842271720000, -1170.83786961848050000, -1179.60691088987570000, -1145.41972010149810000, -1200.41097748615290000, -1035.154242 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -854.62112420868107000, -781.78537783536603000, -777.61280671395684000, -702.69269040559038000, -713.57386613878191000, -888.23944109933473000, -911.78258896770535000, -787.08822981544506000, -756.23121529501850000, -770.95915062086067000, -733.28765154128325000, -669.63344296217315000, -678.6249487843 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1710.63498042360610000, -1679.59062557574290000, -1666.83327257221710000, -1680.99967077952030000, -1582.76443031718650000, -1699.00178155240110000, -1627.61324701761920000, -1544.54054799097530000, -1424.38472155538810000, -1415.27939560356160000, -1294.19669569508210000, -1240.08097303810150000, -1205.71666878827550000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1002.54024857776610000, 979.09831408842308000, 946.89217746855513000, 1044.93792877078520000, 967.84664769133622000, 950.73803423322272000, 918.47146285284509000, 935.26243123220627000, 952.27158360726298000, 943.234924 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 529.23299696419667000, 509.381 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1253.62619484089370000, -1313.45138590916440000, -1192.49650082118360000, -1186.67604892329400000, -1195.09788248752600000, -1191.75732811734880000, -1195.63930089883300000, -1157.35700902160310000, -1270.21977759696600000, -1330.41375901199790000, -1345.21122891218330000, -1512.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -980.28381177672634000, -1085.67589655199000000, -1130.96771012248970000, -1061.23226952679220000, -1084.36638535015210000, -1020.29620236086200000, -890.96983085031763000, -781.55959647405973000, -735.09798612969325000, -810.85606742004438000, -818.33064381206395000, -859.26841900408829000, -779.13505329737154000, -773.53479945793651000, -689 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -2459.48196312674330000, -2428.66038740300700000, -2360.82224183694870000, -2274.38017852316850000, -2448.44290131992370000, -2416.52558809686210000, -2359.55303264914940000, -2337.76502878045270000, -2180.17540210421750000, -2030.66821791870440000, -2083.20465933125390000, -2118.38620137884890000, -2102.68053203263570000, -2029.62754096807200000, -2140.65180837768180000, -2116.54318197370280000, -2195.71723132184890000, -2169.65431456959190000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -467.70430713240017000, -460.45750037381345000, -537.24614023225263000, -501.7316741300202200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 908.09426336154127000, 898.90332740320025000, 964.63367324865692000, 1020.29244962360120000, 987.54001108154387000, 938.08031981886006000, 940.8255779922725 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -722.62230446294609000, -635.25915269546465000, -701.52591624693684000,  [...]
+
+double lasso3[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 51.32911692678412400, 110.34148990308209000, 129.32450872975195000, 139.67442869293515000, 143.45003955672502000, 150.58197464587533000, 216.66298348198956000, 250.14963501283992000, 251.90856833119935000, 289.07273566390313000, 291.0510323 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -54.62955408275207200, -230.93225514683724000, -403.43271206647256000, -417.92989801940467000, -550.78659783861849000, -564.59217106337280000, -779.26940095704356000, -809.47979390565081000, -872.99912091810040000, -936.57491474798417000, -1026.14198978681840000, -1065.63093910629250000, -1090.52025838018490000, -1100.95365333022070000, -1122.35469958685010000, -1337.06365562243080000, -1454.29504856732340000, -1460.537349123 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -165.02807312869055000, -270.60290745847539000, -279.14868785567722000, -436.74822235387290000, -443.2362366065413 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 79.46056711794173600, 163.73590024695710000, 269.30237366875241000, 317.53891580061503000, 349.05698416604235000, 360.14160950289278000, 382.64180453816249000, 599.82468915570416000, 718.11179962683332000, 726.89294963793884000, 862.50410278083632000, 866.94227 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 42.33186748223857200, 71.48788661223757400, 81.99891664314770900, 102.86981349469572000, 307.25654617504370000, 418.26412937089526000, 424.57931446556745000, 544.87626175699359000, 548.8272780932429 [...]
+0.00000000000000000, -164.65876857644622000, -636.97591266520021000, -712.07145947973970000, -912.43263636208599000, -1090.37442494736590000, -1107.73864659358080000, -1230.44962056066970000, -1244.34015597815140000, -1478.61762103481490000, -1503.11566127304740000, -1549.43786047034430000, -1597.18482570193900000, -1654.34030514116600000, -1670.84251481888030000, -1681.54640702147690000, -1687.98192885275060000, -1701.01338627385010000, -1782.60384002374330000, -1827.78603176837100000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+586.89068893129888000, 766.98866577369097000, 1175.41666997288730000, 1235.86131619702950000, 1404.55978006437230000, 1598.96205072372910000, 1613.60450940444410000, 1748.89793713354270000, 1762.44027094809800000, 1953.78581661305290000, 1980.24118822064770000, 2051.19673959921600000, 2129.37929269509780000, 2211.65713767908850000, 2245.99154848585070000, 2269.65464405835340000, 2277.86820013078300000, 2295.22096126769430000, 2477.19896460656130000, 2585.89359776000170000, 2593.464687649 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -62.81562 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -194.82804034945818000, -388.95445916011994000, -406.63187125465782000, -569.14825074110740000, -579.69348600332034000, -755.04020789230299000, -774.68236536293216000, -823.42582911660213000, -877.65148548803222000, -935.70811379475720000, -958.43929394063503000, -974.36986599049271000, -979.50720485409784000, -990.47424755480085000, -1093.00929432126600000, -1148.96122097757730000, -1153.8192703175112000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -14.80459572908219600, -18.88876240992974000, -27.69653695338233800, -80.52532588625982200, -112.24411183181100000, -116.33136450569516000, -184.66198608487426000, -188.13236179 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.23132499369578770, 61.52153893652718600, 96.14603725819709700, 97.37567594443768800, 124.76110874695776000, 127.30311763066652000, 15 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -131.04377197616733000, -136.92954001883496000, -18 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.96621516488069400, -205.54183421199843000, -216.69464938003341000, -414.34966311828606000, -433.42658979260659000, -489.17171002175911000, -555.10144509725058000, -651.70431454358550000, -689.53067719737498000, -716.73448498801542000, -726.38681654081086000, -744.90779175595526000, -914.91601104277265000, -999.50088061283429000, -1007.14781187964080000, -1115. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -122.83474759689297000, -137.78889711141824000, -271.28517431044889000, -281.20330834078396000, -464.04073007853526000, -485.15777419328458000, -537.17498473275782000, -593.16882007596996000, -652.59518818017875000, -674.15709218699249000, -689.71228793767045000, -694.99661962852656000, -705.92779261797136000, -803.90362692684573000, -869.24904066706210000, -871.39409743358613000, -91 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -166.79220754404153000, -183.50027401612596000, -221.02556399427007000, -255.88013282587784000, -299.71682372578056000, -323.93811863836845000, -340.87406663179911000, -345.77495682180449000, -355.03346504351964000, -447.75568246458477000, -494.81207279141364000, -497.07241037178466000, -538.5397113012 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -18.82445501421870700, -342.94803206586943000, -378.91519994403200000, -461.15735888699282000, -542.31949084406983000, -653.10345041492951000, -693.21047176282377000, -717.73750675928409000, -725.49880321406192000, -741.05792590736235000, -864.36902463184924000, -926.28730352659886000, -929.90016100931541000, -987.66122191 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 96.02064392166350600, 132.36467565197447000, 155.83141916366580000, 165.59671513660001000, 183.69276664780676000, 354.68999172692224000, 447.60260340442215000, 453.90775839891609000, 567.73598075795712000, 572.292726079 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.42233492249030300, 60.134020 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -34.05837789162090000, -114.86730040981722000, -192.84708993901532000, -288.03338966617753000, -325.36462543653977000, -350.32561851395940000, -359.60992608483394000, -377.60440850226161000, -576.59494742918071000, -700.82619322715630000, -709.15771305774069000, -892.72559500732473 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -112.62079201562595000, -123.32864743266224000, -319.98461451896935000, -340.12274887626739000, -387.13060805448026000, -432.94796319138038000, -476.81608192796460000, -489.35813608292733000, -496.43796336781071000, -499.89130198601032000, -507.07421905342414000, -585.58879104224923000, -617.48570434560474000, -619.50332744122954000, -635.4804 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -399.35155768935039000, -463.86216493996557000, -649.63376691313840000, -837.32231872587511000, -857.85767833596128000, -1036.92665038034940000, -1051.48131640703880000, -1302.51899127537010000, -1326.36306363284530000, -1370.84833147876110000, -1422.39611479284050000, -1489.05619788864560000, -1514.31058153352770000, -1529.15699357892230000, -1535.87320562764880000, -1548.97116098615860000, -1693.15011369172360000, -1771.67921059596420000, -1777 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -77.07885216891223500, -82.03571279300508900, -186.00753244313034000, -189.83890008774105000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 9.97384358030135760, 30.02509329230067800, 238.37716905798931000, 367.23878397202310000, 375.25891431087376000, 503.80949694557427000, 509.11276347486421000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -9.34308173878586960, -152.30472963361154000, -158.96962473121815000, -2 [...]
+
+double lassolsq3[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 709.33450276780593000, 667.47036173126560000, 571.58586043907314000, 488.56883453120423000, 483.43463893572419000, 459.62920387399464000, 447.00272113202459000, 419.85556759181492000, 386.19087744712823000, 414.62108556781993000, 452.094422 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1718.48074585271300000, -1854.90032644746000000, -1724.20126742470120000, -1540.82281002172160000, -1574.35287985019360000, -1805.34065877828700000, -1664.56979145244080000, -1891.25835349398310000, -1815.13833161735850000, -1751.57461187608370000, -1871.73420973327300000, -1985.63403571994350000, -1929.53585373489000000, -2040.45555917285490000, -2049.72349438361650000, -2085.47844945530280000, -2048.40828347576640000, -193 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -740.26933743243683000, -805.64224097621366000, -931.55950579631053000, -969.15249566211025000, -971.3935295087254 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1258.04540904392840000, 1244.09002306456750000, 1265.94303178950140000, 1441.34111606233180000, 1411.52681723165960000, 1358.28523191861790000, 1357.63987249881690000, 1356.86289946738630000, 1317.57527169365150000, 1397.27259841530830000, 1320.6270133048076000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1028.56851951420570000, 1054.33335857293290000, 1028.49167319076990000, 1007.26571206213700000, 1019.69098405563150000, 980.83591748278218000, 906.69971559483338000, 951.26457380257432000, 870.46006 [...]
+0.00000000000000000, -2735.11025149239960000, -3073.51307099401670000, -2999.25496595169900000, -2758.00931795173850000, -2452.80512944764860000, -2452.70045313151380000, -2175.85030834252480000, -2492.72445210342450000, -2444.74677875528600000, -2380.34538571706250000, -2236.50370707544650000, -2209.26939214339200000, -2193.93846350644840000, -2055.30663113756600000, -2042.37316930237720000, -2267.48505842160690000, -2265.70386066161020000, -2067.00512327453500000, -2056.763419337863500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+3598.56365879492750000, 3578.45820151094680000, 3282.36963830812010000, 3076.82264829592850000, 2958.48332941738270000, 3087.42423083689710000, 2747.74965455492380000, 2791.23747281157690000, 2979.53063923588710000, 2742.86943941106480000, 2927.55934590642250000, 3103.63243617755050000, 3131.62799861522220000, 2988.43259408712080000, 3045.90557018023900000, 3067.33440384687580000, 3017.47899994685170000, 3047.16593577794630000, 3111.52289950756180000, 3136.74366016890690000, 3171.4646733 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -588.2090 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1989.43762382136220000, -1875.30454951886190000, -1775.85213289350010000, -1821.22124776184300000, -1527.42557153008650000, -1478.14680581743710000, -1478.03186670610920000, -1546.40465505141610000, -1572.78859439369720000, -1483.81391261876320000, -1488.02431669476480000, -1511.38730088565240000, -1442.11210732643140000, -1465.70770342779250000, -1450.41751474804210000, -1432.51820439384660000, -1524.69 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -513.86552073601365000, -386.65806461794750000, -409.36270248830624000, -264.67156695450717000, -272.99073483183105000, -428.36464129946029000, -415.49715347541945000, -470.6385 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 276.25253237277690000, 254.24761256217585000, 271.61842727440285000, 191.25002606515253000, 217.27484298406097000, 334.2355438349894100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -573.73711122166128000, -616.06093446467378000, -58 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1958.74744272092130000, -1596.74841439581840000, -1219.03177281734320000, -1229.45269445755530000, -1116.53621680823610000, -1316.00137027201980000, -1400.27711466166990000, -1563.72064189274190000, -1570.79926941984420000, -1633.77117603648320000, -1595.55585817143700000, -1547.47483720630040000, -1507.51665862056570000, -1428.16584161180960000, -1590.9377585703 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1063.33238469546450000, -1296.07634333728740000, -1299.77894467307120000, -1172.57591553008730000, -1218.03797953892190000, -1241.32025126129290000, -1308.71108225518720000, -1310.97281585254950000, -1213.63253931401550000, -1176.50062872095190000, -1214.07583842271720000, -1170.83786961848050000, -1179.60691088987570000, -1145.41972010149810000, -1200.41097748615290000, -1035.154242 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -854.62112420868107000, -781.78537783536603000, -777.61280671395684000, -702.69269040559038000, -713.57386613878191000, -888.23944109933473000, -911.78258896770535000, -787.08822981544506000, -756.23121529501850000, -770.95915062086067000, -733.28765154128325000, -669.63344296217315000, -678.6249487843 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1710.63498042360610000, -1679.59062557574290000, -1666.83327257221710000, -1680.99967077952030000, -1582.76443031718650000, -1699.00178155240110000, -1627.61324701761920000, -1544.54054799097530000, -1424.38472155538810000, -1415.27939560356160000, -1294.19669569508210000, -1240.08097303810150000, -1205.71666878827550000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1002.54024857776610000, 979.09831408842308000, 946.89217746855513000, 1044.93792877078520000, 967.84664769133622000, 950.73803423322272000, 918.47146285284509000, 935.26243123220627000, 952.27158360726298000, 943.234924 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 529.23299696419667000, 509.381 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1253.62619484089370000, -1313.45138590916440000, -1192.49650082118360000, -1186.67604892329400000, -1195.09788248752600000, -1191.75732811734880000, -1195.63930089883300000, -1157.35700902160310000, -1270.21977759696600000, -1330.41375901199790000, -1345.21122891218330000, -1512.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -980.28381177672634000, -1085.67589655199000000, -1130.96771012248970000, -1061.23226952679220000, -1084.36638535015210000, -1020.29620236086200000, -890.96983085031763000, -781.55959647405973000, -735.09798612969325000, -810.85606742004438000, -818.33064381206395000, -859.26841900408829000, -779.13505329737154000, -773.53479945793651000, -689 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -2459.48196312674330000, -2428.66038740300700000, -2360.82224183694870000, -2274.38017852316850000, -2448.44290131992370000, -2416.52558809686210000, -2359.55303264914940000, -2337.76502878045270000, -2180.17540210421750000, -2030.66821791870440000, -2083.20465933125390000, -2118.38620137884890000, -2102.68053203263570000, -2029.62754096807200000, -2140.65180837768180000, -2116.54318197370280000, -2195.71723132184890000, -2169.65431456959190000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -467.70430713240017000, -460.45750037381345000, -537.24614023225263000, -501.7316741300202200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 908.09426336154127000, 898.90332740320025000, 964.63367324865692000, 1020.29244962360120000, 987.54001108154387000, 938.08031981886006000, 940.8255779922725 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -722.62230446294609000, -635.25915269546465000, -701.52591624693684000,  [...]
+
+double nnlasso3[1150] = {
+0.00000000000000000, 0.00000000000000000, 30.66833356081625100, 157.47301323905782000, 177.05893647870820000, 192.70983228296998000, 245.70869040571654000, 248.42411150597840000, 330.17411110723680000, 367.85171163065496000, 393.70818362213583000, 457.00452664955407000, 457.53915243266965000, 482.40797598900366000, 482.50162054200183000, 489.48592847455029000, 489.39470184711604000, 472.14919086318065000, 464.66915600275456000, 462.75883187181489000, 457.66157192978466000, 457.3672327424 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.31150646378468300, 124.93283071544032000, 138.63952248849947000, 151.40600378255880000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.46407551501247812, 26.24408439761884200, 30.00095033255016500, 231.90528450718261000, 316.58445285483066000, 336.67347419152026000, 474.54844827969214000, 492.91509974970893000, 510.34856263823519000, 
+0.00000000000000000, 90.22314270150181400, 119.71935496173340000, 226.40213969498893000, 245.95492089763331000, 266.78567017964764000, 393.60748078390469000, 399.53267794835745000, 577.51791819587254000, 714.03752655923245000, 835.90721091995886000, 1027.69545538816100000, 1029.41132050414400000, 1146.74342526177070000, 1147.21193159801690000, 1177.32491050265590000, 1181.05194985870180000, 1321.30662190412040000, 1381.93488265623070000, 1396.68678880826090000, 1522.26883279760700000, 15 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 20.40253214103556400, 150.18970756480309000, 156.57594356782556000, 345.20806599545062000, 488.95569360265569000, 607.40712268691266000, 808.22225268393652000, 809.79403562682364000, 905.42476733192234000, 905.83557223264643000, 934.34302554070382000, 938.13209690129520000, 1104.65344680889670000, 1177.31751468850870000, 1193.39710202855210000, 1298.54732045582910000, 1313.28335168151 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 5.24335774866827280, 259.59349933583428000, 368.22692221480270000, 391.98003237638454000, 568.72708577329377000, 592.33647981967545000, 614.71013500728452000, 
+2150.17876159228720000, 2256.38442957990360000, 2293.53939822327400000, 2448.87784933269590000, 2477.27395261579700000, 2504.65483189650240000, 2665.23754518877510000, 2672.75216612068830000, 2892.88398761614230000, 3052.30008046042120000, 3191.35412202691940000, 3449.69458657661560000, 3451.98345975974050000, 3591.01499591836860000, 3591.66247111790060000, 3634.98289819473480000, 3640.07573538469340000, 3873.82553776386020000, 3974.03527490910760000, 3999.72800469444930000, 4178.8774649 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 84.64962153000422500, 273.39120192965942000, 275.14723865050121000, 378.04213861658053000, 378.48528193484304000, 404.37760996228315000, 407.58038358515643000, 554.69696358729811000, 617.65663199259473000, 631.88447138489846000, 740.77579693836583000, 755.05521693230435000, 764.306 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 25.16082741482134100, 44.77012088009202300, 147.79266865067396000, 152.85095606156193000, 290.65435323652702000, 386.06977544471101000, 482.66038270037990000, 735.73955955982274000, 737.83535042113760000, 867.87845118306404000, 868.49451015754391000, 898.75966290777319000, 904.09730905958986000, 1157.52855726495700000, 1265.97237145281540000, 1289.69421811451230000, 1462.01475607100500000, 1483.2267063271 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 40.47043339859057200, 45.12396519829820800, 264.68162027160707000, 358.20583152272098000, 380.38692129581199000, 550.78234815073438000, 574.65607579891719000, 598.85804983892967000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 120.53948426167403000, 126.64600028291386000, 304.68928293743608000, 425.40631661098695000, 533.32811893435826000, 760.04964406938905000, 761.81472691437637000, 873.91603520031151000, 874.43075769277971000, 914.41360942690301000, 919.91221410696426000, 1167.82942129272780000, 1274.52999128399280000, 1298.38793656663550000, 1457.64492907026830000, 1479.131401110600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 118.08952708042705000, 118.61634570314246000, 142.34089706105928000, 145.88861225350126000, 295.84801704799077000, 361.05384038001722000, 375.80501438926734000, 473.27980276891464000, 486.80085288026476000, 494.79350550 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 187.30486901491074000, 267.23847090373687000, 285.01201158374852000, 438.38385353690228000, 459.51142535271538000, 479.80749827070008000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.78047096564942060, 79.35879067932120300, 119.49934825767104000, 142.62492342315511000, 245.33468878669839000, 246.26948672588119000, 269.11543364999642000, 269.28589204237841000, 285.58340614308349000, 287.66997136171460000, 407.97546675122442000, 455.70923895584770000, 466.47277907213930000, 550.85291523015019000, 561.18581331879932000, 573 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 135.58696750102771000, 154.48399994392338000, 173.94928918683286000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 35.90692801675513100, 65.57439722532831200, 80.91619411111888400, 92.34381994593998400, 92.49390094349793400, 102.86063184399188000, 102.87060038243780000, 105.36750410777137000, 104.76351020540783000, 70.91399613267027700, 59.00671388430624400, 51.78728925993031100, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 223.80541909902448000, 225.90457384713829000, 333.77628634455448000, 334.40564268162387000, 366.65997010450883000, 371.11163953907794000, 632.81910577852989000, 744.27086815787561000, 766.61776550022887000, 915.16808947494360000, 935.13760732595210000, 953.8861 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 107.15140152467998000, 127.57393877258433000, 144.48882085712177000, 229.91984315999935000, 234.71432116527561000, 368.00402418361080000, 454.22913301055655000, 527.36432303319680000, 685.00292200127035000, 686.33410733576898000, 781.90698934522482000, 782.44850075085208000, 814.34895209950605000, 818.96139088677080000, 1007.67186000021950000, 1089.34809732729170000, 1108.20603363432430000, 1227.46400867651120000, 1242.251520 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 20.99709448623680400, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.53364946588321670, 103.19087465462678000, 103.68308243712406000, 128.56334582915332000, 131.94770836934967000, 312.55490816556045000, 384.64683105881039000, 400.98831313449620000, 543.51544841007774000, 563.07776545515128000, 579.49318323 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 105.25609904607393000, 197.94989341816355000, 369.08704923409630000, 370.35157885572579000, 453.79153398235081000, 454.09818984574878000, 463.72576968041767000, 465.01738628079488000, 468.51547874327673000, 471.09764725566487000, 473.13778158126121000, 479.65410748489876000, 480.78636579083980000, 483. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 16.13646615534914000, 18.51980385240781500, 25.59018328655201200, 27.63899967887652000, 29.43260846269324900, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000};
+
+double nnlassolsq3[1150] = {
+0.00000000000000000, 0.00000000000000000, 1331.76025514262320000, 1311.66020039473800000, 1162.58169133653250000, 1073.46974728671060000, 771.26632896534295000, 771.87611938574071000, 778.92644167217190000, 625.16396415647432000, 571.51719210773388000, 608.97491586547756000, 606.61666196515694000, 574.76542463734677000, 557.96846712352942000, 582.45023977397443000, 479.49543545147145000, 448.07657229835536000, 447.93642945821841000, 446.25319077448387000, 457.10104950396266000, 457.10104 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 140.60431213352078000, 151.03505717117935000, 151.03505717117935000, 151.40600378255880000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 374.45609717960065000, 369.38771354600385000, 437.66938825043326000, 513.73897605152126000, 506.01049089059882000, 516.86219965555233000, 509.52483089933372000, 509.52483089933372000, 510.3485626382 [...]
+0.00000000000000000, 1394.56479516345300000, 1371.08449395587630000, 1197.43809469010560000, 1229.81003766599250000, 1439.04374387375670000, 1651.22271363781940000, 1541.73355151346660000, 1554.53677760639680000, 1646.37311730592070000, 1673.97698887625390000, 1488.16651524459010000, 1507.87103244274090000, 1582.48956401285320000, 1524.77469064738080000, 1578.14233895506570000, 1585.48381904264120000, 1517.08494504161010000, 1517.55939871338020000, 1531.08529260918110000, 1556.5248025736 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1168.56252880438180000, 1437.21067079125260000, 1387.65132198840750000, 1380.67112375311560000, 1470.65371420412660000, 1421.97034562441260000, 1290.36627564707100000, 1248.07721247953580000, 1260.57668566251800000, 1236.89754460884730000, 1313.79017897069620000, 1349.29523912823400000, 1337.09683123279770000, 1339.86595197933590000, 1339.05036805719420000, 1326.60976108557590000, 132 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 574.21534127602251000, 614.63510674548229000, 611.23827076448049000, 604.99625632574930000, 613.68744237025908000, 613.68744237025908000, 614.71013500728452000, 
+3598.56365879492750000, 3791.78291311651360000, 3869.82424763158910000, 3862.78189765362230000, 3906.10656838626030000, 4045.52387924107920000, 4257.63924176726500000, 4121.34642462670040000, 4101.25913635521010000, 4141.00300656982200000, 4147.59677048261620000, 4069.95318399405960000, 4090.22337364388930000, 4107.34814421481310000, 4113.45375511621570000, 4211.59746148265190000, 4192.71429575922500000, 4200.11159780108570000, 4198.20296396928550000, 4230.71909362801760000, 4224.9054628 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 666.76559148484921000, 726.54742016709179000, 764.80858544358705000, 760.17161161986405000, 735.60833653019233000, 749.01625795090899000, 755.12265484408499000, 760.05366877580423000, 758.49647223640056000, 758.94690674854235000, 767.96869370073341000, 767.96869370073341000, 764.30 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1291.20111793112260000, 1148.29031945251270000, 1169.40499847302480000, 1127.93754628024480000, 1047.10201003968450000, 1037.69187645483430000, 1146.89176395034160000, 1343.36614855746890000, 1322.23530263635600000, 1350.83048843904040000, 1364.96789407254600000, 1301.60259437203600000, 1483.30080116112160000, 1511.28750219493740000, 1508.55956818528780000, 1499.08741276702680000, 1502.40956017981280000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 579.15028618056454000, 550.09222130475075000, 571.15718301316110000, 567.41809875929175000, 581.33474805890967000, 596.24608628193937000, 596.24608628193937000, 598.85804983892967000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1315.85668439907270000, 1303.79972872659390000, 1282.02675599374700000, 1249.82112597418500000, 1275.48152143334710000, 1304.39323124113910000, 1253.99853652375830000, 1290.23612368287830000, 1289.23847610742910000, 1446.60352876419050000, 1516.58178376237830000, 1513.89144113076010000, 1513.21757671969570000, 1512.94315914992330000, 1498.56251649526640000, 1498.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 556.64856902834458000, 543.17216773265181000, 458.12545283619158000, 530.86149543060867000, 505.17295703896616000, 506.91829573149789000, 509.16524722763916000, 499.02850404339341000, 499.02850404339341000, 494.79350550 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 448.75949748783222000, 446.04874747099933000, 445.37598323063389000, 478.61797225256373000, 478.61797225256373000, 479.80749827070008000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 538.77214816083472000, 499.72208865942224000, 393.63191361856377000, 301.65418279731409000, 491.93413311498318000, 506.93283872015803000, 353.96035464463409000, 406.65594651489442000, 502.51072219168566000, 514.08922560871633000, 575.90718558876881000, 562.48897623552762000, 561.19250152450422000, 570.53028525638194000, 570.53028525638194000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 171.57337679166440000, 171.57337679166440000, 173.94928918683286000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 233.01173180317849000, 268.18292915807780000, 186.41820125071007000, 119.78080386741918000, 134.34317580208500000, 141.36043520721537000, 110.90410727050210000, 138.60242694455718000, 39.22237699673119900, 23.66422535830780700, 32.37030089048545300, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.000000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 761.14762596836374000, 811.24252771167835000, 734.38856802409737000, 841.59518669731085000, 795.97972007156375000, 854.17522390697297000, 998.13063619463696000, 993.58680018202062000, 967.45337232451720000, 953.19687758729276000, 953.19687758729276000, 953.8861 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1082.45274717983010000, 1155.19336337012870000, 1096.38002845296800000, 1077.08764887476010000, 1158.94634483009760000, 1099.67454603723080000, 1043.08767676934300000, 1030.29819690493040000, 1063.48291144163550000, 1057.52794171605860000, 1136.84406637934490000, 1218.84503276684520000, 1238.95845076550810000, 1319.47052482009710000, 1271.08853384589360000, 1272.05662340797040000, 1275.40812432258870000, 1255.6244850133949000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 20.99709448623680400, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 429.18351239864285000, 480.72389039356887000, 500.34650832428184000, 459.73095377628783000, 499.19472064125910000, 564.66041172560892000, 545.91538853901295000, 548.29291072736009000, 580.76878699562246000, 580.76878699562246000, 579.493183 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 824.08329508241354000, 835.38378909811286000, 779.97619281996788000, 722.95882803105474000, 763.66953658953616000, 701.22789739869268000, 591.87323073940274000, 605.17445629193060000, 473.39838685961246000, 476.87391974849669000, 492.01891731291306000, 481.81031433607751000, 481.81031433607751000, 483. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 52.23350054233068100, 42.08107271332483600, 29.49183003867334900, 29.49183003867334900, 29.43260846269324900, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000};
+
+
+
+// Data from file x29.txt and y29.txt
+double x4[5000] = {
+-215.662944455778, -4465.95666035005, 15579.2916911965, -4974.48063677033, 17902.4091417362, -11839.6932765287, 4302.68806539793, 12306.9278553992, 6986.27346766313, -14550.6754437867, 8943.12105331526, 6793.26976377595, 6699.13371756686, -8228.8736554443, 72.4615133087601, 3505.69479705446, 291.089485433491, 12830.6944910780, 12468.6059558900, 2794.04333513528, -5290.32998358572, 7488.90680503458, -2705.51068951268, -9053.59438945826, -2497.77215490973, -17836.0707917171, 7143.267757235 [...]
+11900.1604431316, 170.139662599455, -4934.99414865673, 3237.41169081687, -4176.80733128593, 11946.4798056341, -625.9946728452, 19943.1144146902, 8361.04979889673, 5848.53876620371, 17237.2278774365, 1677.98160622168, 3127.16871457672, 21071.7176811937, -11545.7384229422, 14825.7484164642, -9935.70879439492, 3464.34307977973, 8874.07784225026, -6111.88624611898, 9591.12228649091, 7015.43072294812, -13914.2318556297, -165.999780041575, -1555.27048029548, 5600.64920593106, 14014.1220088477, [...]
+10667.5084810783, 20909.5974640713, -3850.66906664474, -14752.3781881547, 4894.45981760838, -4962.24269734588, 8747.88937134589, -99.607176058536, 4219.54258422006, -6832.39382834908, 12153.0018177547, -2307.32249773072, 214.233386868733, 2757.66022842335, -7016.47065703171, 577.373801975126, -9998.25662023876, -1992.36836883414, 16274.7680654318, -1636.6759717333, 5981.70566244704, 6101.26537183995, -2919.91353492446, 16144.6817769764, 2312.92036567842, -7002.74806645596, 7663.874868190 [...]
+-3127.07841501092, 14943.3338720401, -14434.8791137626, -1483.8985830251, 3445.06966537885, 2163.83201859088, -6297.12997346402, -388.710890741472, -15110.6974903159, 11381.6058854105, 6547.73371886795, -17956.3494372927, -21666.8754160516, 15942.4056802887, -1423.33727637165, 9242.56084996752, 11746.935741274, 5125.60576667515, 1282.35761056925, 1652.37597651897, 3944.73440659606, 11034.3866927746, 13076.4754033147, 462.591977975813, -3284.90542225008, 15064.4038498400, -6676.2992907064 [...]
+1633.34002039662, -13569.3620048014, -9889.82740944683, -12057.7847952655, -10966.0901785423, -3991.00029740706, -1610.39336958695, -8508.38646284067, -9091.99875647906, 187.480140414504, 9455.08086820788, -2220.27577616400, -5970.17294055612, 10494.2523524928, -8.51276796013328, -9338.84982248669, -1903.64759309280, 2532.00025331788, -1690.11495610924, -7830.04061800309, -11134.5768976378, 9594.43977206986, 692.703568112868, 12828.2414126086, 10685.1370413583, -3228.73648836910, 434.976 [...]
+-8483.17283392386, 2710.65819120138, -6127.16636502626, 4926.74569566986, 3522.95110466552, 6876.85903976237, 2753.11306625560, -12536.1300855041, 2673.20266946517, 3038.61181709846, 23445.1808473379, -7444.92191665547, 6279.41408247988, -3168.32147594393, 8606.22029483878, -11053.8674719458, 1849.12589130713, -5393.62552760865, 7627.94996747753, -2189.20216643355, -11151.249804, 7977.1053029944, 8232.56083235833, -3431.68802444173, 2008.71468812459, 12369.8309269689, -1990.69481042674,  [...]
+-5504.42045657652, -9029.10400075346, -5208.79045897316, -7278.80962514615, 12937.3929900857, 2846.03730206503, -953.111255674864, 9309.47182602079, 10225.7667213509, 3740.46930779927, -2687.48378142831, 9835.51037956278, -2084.68011444342, -13293.4936713858, -12210.8936450919, -4630.58801053493, -1227.50543147963, -422.037866891225, -2407.56818546383, 14258.5778507429, 1169.41049298056, 5649.86117722568, -14058.7882441122, 8932.37836229303, -1143.65903279317, 6577.6045593002, 5134.21757 [...]
+15164.1995077783, 2049.5497599155, -18787.3198516864, 2502.07989091553, -3030.20737106385, -11665.9517990980, 8176.35256302996, 2287.66169176502, -6789.4790065566, 2884.0309007189, -5067.90379875972, -8179.42055272092, -10205.1397969695, -7178.18539800951, 30431.6184970046, 12290.3722771355, -497.225021884072, 8048.3768569002, -14071.9095386441, 15126.8799095607, 19210.7941649078, -16839.3155878342, -3573.00030410652, 18294.3230272434, 5991.60059094484, -9640.43261010674, 3336.2613764501 [...]
+-10820.0842942821, 1500.08119683576, 14002.8305939389, 18822.1679208791, -11008.7673086803, 21930.3531091126, -4396.04748354589, 8075.57847021628, -15230.1533050107, 7383.33673066349, -19343.7170878465, -4702.91385211714, -11186.905122615, -6505.90809511963, -3827.78683769896, 10093.0970226570, -7768.73254747322, 17269.6970879806, 2878.60677245545, -7317.93465907295, -16437.1438329788, -6593.44495766351, 5301.20899027245, 965.981665609976, 21259.5526283697, -6247.0423409531, -8419.432117 [...]
+6401.54572091344, -3456.51697978454, 12031.9554211529, 15619.594774042, -7583.88458900007, -5642.98261926203, -28965.2831625784, -784.834727152551, 2473.13468529336, 7115.05353148809, 4488.03749642937, -1975.17382256715, -7651.11521663972, 9016.83366782763, 14538.2309103357, 840.67520063285, 8079.16909624727, -4685.83357790646, 4878.93295110794, -14595.3815371911, 3590.51625810714, 3116.7709924088, 3683.15484484706, 5639.1976838777, 1318.12143442018, 12919.0499278330, 2664.43597780082, - [...]
+-5472.13133437388, 15520.5323028708, -15482.4511051373, -4684.20556382768, -1422.33476033103, -8035.58871021228, -1438.73848174406, 10378.0498641754, -2146.92319497593, 11700.4204341917, 5435.86315687904, 1071.00912859403, -5179.41436115382, -937.622199304935, 3661.15193222038, 11229.1103552401, -5543.20687400882, -4230.63133470894, 7393.02332678334, -6172.74359664079, -532.689463746578, 8095.49040272563, -14110.2066999208, 8108.63082894937, -9875.1223268155, 2369.83240506400, 15979.3774 [...]
+18071.9417466126, -12870.3406961975, 7135.48874082592, 34980.3834234874, 1466.14170934962, 15695.1629859457, 2288.04141862243, 13163.8398403471, -6951.78840608009, -8739.3718258699, -4606.71708924016, 1037.95872592456, -12455.5173281347, -8772.57461592012, 3682.50200460091, 9996.43111011689, 6503.69616262212, -3747.74412573634, -2578.01517546496, -4674.33897911639, -5917.42117014231, -14721.9831538566, 9946.15494638912, -7827.84537435463, -14367.1191173197, -17585.8792968934, 8098.789947 [...]
+-9892.7289048034, 4765.36769927807, -5615.27843430293, 16737.0415833001, 16238.1378235557, 6972.01413910308, -1952.08760053689, -20570.8964597277, 7248.96892219076, 3501.25213367595, 7642.97095616267, 3914.96188067842, 9610.5502544464, -9197.04914468358, -3167.47266019734, -6440.85960790812, 1988.63058576026, -2523.77111486498, 10708.1750328606, 431.457590422867, 92.6113549305609, -5591.27524672553, 1710.14053161971, -5300.51978166031, -12022.7429467384, -19589.1525776805, -7277.65910549 [...]
+6673.44250583367, 1546.17874244055, -8793.24300618612, 7631.81480415052, 1685.11758936807, -4123.98225502376, 12903.091761792, -8919.7839704125, -12228.5674743180, 7124.21464725879, 12305.1782510775, 3753.03092539148, 23251.5085059072, -19603.6277451596, -14710.0900918433, -5177.74454785889, 412.825610117156, -8351.66138069329, 3136.03295927863, 16320.0920931781, 10320.5037280627, -15871.7206842730, 6250.64429004048, -25177.4622447821, -8603.69610439749, 693.735042114645, -7292.178177815 [...]
+-24106.1385365483, 936.436085698397, 868.992015290145, 9000.64802183995, -12133.3272514926, 13919.6786008186, -32681.3721320386, 2546.17861334556, -7462.26796766453, -4272.38155699594, 4953.04208769157, 968.998831631485, -25878.8349597012, 21684.6378886958, 3372.47306102299, -6778.30770211936, 5753.11048630906, -21201.0786146198, -1118.51800246624, 15948.0322402766, 1812.39978521018, 11717.6098374995, -14051.1652940469, -3584.97611969005, -6913.39135271224, 6984.41367885183, 6137.4654972 [...]
+-2439.51196797007, -8595.16106438686, 10008.5881807381, 602.154655933933, -22480.5085526763, 22611.9198567229, -13703.9443520482, 8985.07299580758, 9102.94344966713, 12191.6614319391, -4253.03577839318, 19547.5398578098, -11078.4773330626, -420.942210284368, 13415.7436059594, -16293.8322386891, 1446.82646988183, 12510.5529014592, 15650.8928553755, 4653.64396334793, -3371.18026142084, 18486.2603992132, -6545.47724675357, -3821.20662909085, 10142.1742879894, 25442.9801409826, -3746.0166158 [...]
+11179.2887368445, -4695.08182197196, 2568.94861472426, -10258.9483580566, -20776.0737297834, -1775.56764813749, -17245.2851934742, 9956.09701969722, -7640.176212682, -2143.96977744230, 16102.7880564480, 1044.49555935924, 5940.53748421095, -7942.16289201319, -4134.36542512385, -2373.65868964987, -17939.9321364008, 1983.98891293244, 17047.6659726119, -6601.47052301036, -2538.47323726358, -4309.52994637625, -9309.95907909171, 10852.8390688969, 6482.67773743531, 9077.51675606591, -3096.07239 [...]
+-654.407600832465, 176.093587354523, -9398.26424332557, -9890.03490241945, -2878.51390239536, -13614.8065647599, 59.2833507667066, 20166.0689064115, 18228.9497278290, 11763.3695610371, 29116.9306477771, -30050.5417146335, 26387.9263234570, -10737.0418176214, -9033.85488132312, -2918.44351749258, -756.234870308982, -9588.6106856911, -7259.53807559008, -2337.76489650241, -3252.21790500012, 4443.44901603502, 7024.77411461597, 17823.7954141280, -18912.6413385465, -1441.67528151949, -1532.359 [...]
+-4416.97312132273, -15329.1549613651, -9738.01348108135, -16783.8289978134, 8678.99012425638, 3093.50672517226, -4024.74279887118, 1923.75951888648, -7971.12083835352, -4110.50687013175, 1190.22121999006, -1778.09420961957, -5371.83103689298, -2056.49156996776, -10347.4815265266, -8028.57558140987, -5986.24642867593, -4227.96652049906, -241.225712241416, 4846.02174506827, 988.598503280942, 15882.6957748109, 21431.4209777794, 17412.5191843118, -12453.4455261798, -12783.9691624383, -14751. [...]
+-5183.4161058278, -4978.39766175274, 6206.93084611951, 12611.0704942479, 17653.3213617042, 9763.9872231595, 11544.6369722002, 15237.9974541235, -5103.83022454613, 1512.79708196302, -6643.1721577734, 9550.8720696417, 19768.1999398055, -17818.3560411012, 7049.41536420235, -10142.2582081208, 6642.79679682329, 4969.77375524729, -3025.27394362723, -11095.9808248938, 5507.45944520947, 10878.2563517004, -10571.7509223071, 8994.77623885216, -13590.0365696492, 26781.978700141, -4270.70672742554,  [...]
+-5737.25933105483, 1103.16342004823, -2241.08273864714, 1441.4234590706, -3439.27000753437, -3873.34825998306, 4549.88737110085, -3352.36595351673, 8398.50820288567, 22635.0840819094, -20754.9749107691, -11017.3628879629, 661.963319585917, 12647.0446356680, -1352.91674691945, 10392.1382126406, 1005.39331269112, -2957.28418853963, 16000.1161676924, -2268.65696745762, 9968.95778059715, 7683.06563058881, -21311.3192938724, -896.49711946405, -10460.0272741325, 3540.54610541236, 1123.19303570 [...]
+-18148.9058280129, -353.949937217603, -4358.68014374878, 4079.84291339877, 11098.4581185451, 5857.09289661316, 9767.85651952597, 6349.73522964675, -2392.02440919399, -2776.34154219819, 8691.6617205364, -1984.03635499976, -27376.9761856679, 4441.22378666375, -2375.7800682662, 27256.9388729917, 16095.2638695389, 12265.7468941217, -6708.52446004128, 9123.7606642793, 22598.7026111884, 2276.82989480689, -2351.92303494500, -9387.17352865926, -5415.40718672616, 3037.61929861981, 1654.2264517596 [...]
+10479.4100694628, 2548.21412218681, -4578.66657053941, 14647.4178060787, 6882.27199026264, 9896.59540415664, 4983.90938574602, 7535.52691571589, -336.60684412394, -3516.63679711411, -4418.26877235379, -9654.59172411313, 14978.6700738766, 6738.2220105932, 8489.81217805925, 9085.64578910483, -10066.1824674413, -16574.0615989596, 2946.03899649132, -1774.90207348420, -280.887137146606, -3317.48783021137, 3483.44598181295, 364.44177581487, -12695.6834595021, 7631.8309267164, 19887.9083786603, [...]
+9203.04266026558, 65.6303514089061, -6118.17816546983, -13297.8885728750, -14749.6126905944, -4451.01124100189, -3509.15676760310, -4166.89150762227, 3731.57827983157, -6335.53116901022, 11595.1712570423, -4380.61712256202, 921.318940632885, -6989.65082192515, 7145.36534801545, -1641.44066018401, 2752.23784416121, -15929.0562595308, -10674.3943612122, -1006.56421081397, -6587.4290359456, -1296.86833870153, -18476.6886871723, 3294.51852129768, 19151.3033019001, 1933.69291640875, 853.99572 [...]
+10687.9470536658, -7358.95518495829, 3235.51585568248, 11704.6356558342, -4098.06464361707, -16610.7378749632, 5159.26274024842, -2694.19179113877, -10570.7334104282, -866.184092549528, 9847.21320764893, -767.128763961318, 1587.54833974282, 2614.7116053204, 3633.47210703744, 8464.14955433588, 11468.5641954121, -13528.3369611413, -4997.9276186407, -15935.7266857547, 15365.3224740075, -10398.2564963784, 1061.68137424057, 7933.68037130682, -958.845407604931, 4824.67436366499, 1362.862650874 [...]
+-10466.8762544479, -8402.50845078266, 5280.1837092378, -7677.86354617871, 6024.12866206853, 4982.54200477638, -3412.39058197129, -1726.95336747328, 889.531832966405, 3229.07261657941, -4470.63933684372, 5881.05864303091, -2064.66012347255, 71.0162843222442, -8791.44308262484, -4166.87848229263, 2991.51298799478, 7690.59780868722, -4903.47808598144, -2746.19298731080, 5027.84225021892, 1247.66526930314, -13297.5901715494, -15129.8387687100, -2391.64236823216, -13044.8638667634, 1767.54838 [...]
+-4123.17968550195, 13715.6345102783, -7944.3647253972, -6724.9526264091, -12336.1763363487, 4196.22913017796, 18104.7776646891, -5302.76790767384, 8889.39194687267, 6043.34459121207, 5621.3232506983, 8633.89988607794, -8800.29922758009, -7794.27068695854, -5516.36580527442, -2252.90082749180, -5013.84617089765, 3554.51473969565, 15709.0203955725, 8821.69901731416, -6478.3063414716, 3751.51766344929, 13117.589855896, -23985.5658777528, -5883.13056616386, -16648.3069524174, 10848.293580686 [...]
+1754.3384079722, 419.868320645975, -14176.4746803063, -5732.51113779232, -3288.25375336249, -21526.2218206490, 3413.89502587481, 11211.4308809098, 3053.82998963186, -6903.71727869402, 3683.79984285415, -1512.47658822019, -3071.83358975257, -2263.87080978059, 321.195379414908, -2350.40166999968, 2341.69882741127, -1875.00786392084, -13442.8300858436, -14564.3766403417, 16033.8901910909, 7927.51047639908, -20411.3436250176, 2504.71633236305, -7163.26523399989, -5129.27042102674, -6174.7330 [...]
+-793.90761741722, 9314.60389906267, 16037.8020913363, 5886.98834774458, 17354.3164287816, 2427.55241532978, -3821.35120425926, -9695.66437897915, 6907.28802397564, -1456.11356049826, -8786.73817742875, 3545.64770163789, 5788.6193565221, 13810.5954645004, -10479.3960490552, 11110.9990731121, -10543.0092356198, -20331.5426439577, -2934.67049121381, 14564.6512193680, 5546.98514997953, -9871.2106650576, -15507.0937537504, 2571.69717774653, 17018.1811551198, -24222.680521187, 3345.11356953878 [...]
+12302.7487284086, -15395.5518402024, -409.311464816898, -4066.95299548223, -3976.12015366806, -1077.39697731388, -5656.23459903651, -2772.88789450256, -19928.1936809026, -13566.1007808085, 28093.1958531364, -2947.89952332589, 7870.52854913566, -2564.07496764424, -488.948501809467, 15515.2803427182, 9073.90270627355, 6741.0783635531, -9882.40411682582, 7447.95042715167, -6516.9132405264, -1711.69573002692, 5378.95655608542, -1153.38116619306, 11963.9195433542, 3731.54112171453, 1591.23270 [...]
+-7201.25792566784, 9878.84253704273, 15549.9641782772, 3449.29306474041, 9380.00602138418, -7005.88039820572, 13370.8935253607, -8226.85314516048, 2019.16993579179, -2021.63335416128, 7442.28044989083, -2513.73084275957, 8037.23273191134, 6252.6173045781, 4591.58230582885, -2252.57158920666, 10386.0998046914, 8241.85381684289, -18762.1636668943, -11386.4256994186, 8278.23507762473, -8251.6545237766, -7834.7609437028, 17535.9717682712, 12299.9994756010, -10103.6719151041, 3749.62308193958 [...]
+-2515.18124140172, 8291.34198988701, -7221.86888578987, 9551.00801060794, -7046.86700782674, 2874.63214669859, 11098.7624603938, -2122.36280272032, -1816.92002712315, 20436.2927625153, -4447.04407737159, 12368.4066978730, 8207.00679113253, -22664.4957772101, -9183.1760850368, 9948.3669914373, -17531.9350157075, 542.79744195306, -3547.62520920564, 2075.53072461324, -3005.17714123067, 1382.64849470602, -6850.01545028353, -3508.72682703009, -10683.1827278256, -12638.1308715765, 12762.249435 [...]
+-3704.60320237594, -1885.60811704644, -14743.3137010545, 12196.2849347294, 1482.23522056489, -11214.3376699072, -14124.0126798777, 8411.15543166176, 18233.9638444171, 8387.65219591744, 1399.64373082398, -2841.07097792855, 2798.89695258128, -2639.8809759817, -9282.01035200035, 3598.79608797332, -1661.51042900852, -1333.65055811407, -3957.02327512099, 4283.50036606326, 9577.39677846123, 11105.0763085895, -3173.05082494565, -11230.4098405732, 3955.14530428999, -3418.51745711609, -13796.4303 [...]
+-2299.39648080403, 19364.7530513413, 5253.12728027974, 18644.7369065062, -6475.21903471093, -2373.43148776985, 9048.64040516322, 10385.6253333809, -15292.553934453, -10464.7495829963, 18984.4986534208, -580.518468158853, 14266.2024722058, -10836.5468423392, 6469.8350990513, 4082.0274306922, 9070.35996198615, 5849.86253869345, -8008.75922002264, 8767.1258387689, 6013.57115312811, 4843.37321842746, -19751.4699554048, -1155.56537639905, 9073.96570232945, -5882.78464574125, 10167.5623307619, [...]
+-10733.7502818580, 6988.03779524289, -15072.8232417380, 2916.48519992144, -12003.6008185528, -9507.74778506585, -174.940323148278, 5788.21487191171, -3315.44482880137, -6521.08505105241, 12951.2355788587, 11597.3006205562, -8673.10511032459, 17840.9963524692, -2417.41241928167, 3754.03253603247, 1156.86792011363, -1415.57384585688, 11640.7730655828, -1408.83350271454, -4048.84045793022, 14326.1954996211, 699.026736430896, 6371.12114545114, -26239.0005222175, 1174.44034442987, -6731.84550 [...]
+-5062.96212507485, 7232.22761495888, -651.731101200781, -5470.87527298969, 8177.26170745229, -11341.3527160378, 10834.4140207774, 5110.74645434512, 219.984478769268, 9824.10837233, 18819.6489092431, -4489.13141224701, -12280.313623953, 2680.71434955207, -1013.61201067421, -3083.42287492899, 3097.63574648970, 1875.61716625072, 4157.81392774589, -2251.67605981347, -1625.24427347532, 4908.61413124404, 13440.8196482216, -499.098297016512, 15785.3536197566, -2997.00482454843, -5251.2090846393 [...]
+-2515.17141517784, -16436.9771362405, 11330.6095787251, 19712.8399487610, -17426.4886371731, 2231.88842015157, -7562.44806722273, -3969.6304239734, -2915.64596696502, -1375.58842397066, 8786.88987237161, -2225.97167704619, -13825.0422601468, -12320.9650281225, 7611.17053514611, 16102.4245993794, 31536.4336504305, -10011.8602649025, -3775.60987032226, 6623.19728521127, 3603.0348067459, 7876.76816311543, 11613.2989101174, 4879.76064560998, 5821.68065549634, -5159.88606057079, 5044.73722958 [...]
+-11010.6746481740, -3229.16021411665, 14330.8647575449, -8776.43117174253, -500.924303166787, -11563.7677948898, -15660.9731326087, 4331.75632541491, -587.890230056001, 8269.56395979932, -11304.6997463179, 5320.44299293232, 26337.8413088857, 5079.58814339368, 765.55017335714, 3776.18913194094, 7651.76738537008, 24158.4284011918, -12533.0486674780, 10368.5894588257, -17000.9654912938, -4084.20080271033, -5417.07778471244, 2507.64682026119, -16832.7000214149, 8889.55580890985, 13828.576211 [...]
+3479.26600842523, 19353.0849552784, 8566.16491170237, 2404.5430474018, 7356.60519481681, -1928.66804302665, 800.73377109151, 846.839277488578, 1844.91107576907, 7837.38360483164, 12285.4063439055, -22986.8287370700, 9754.02405511465, -691.441459193294, -7889.40722207463, 2214.90077029020, 796.42482073703, -3241.49368073324, 4024.99673249141, -10867.1150551072, 5602.91009666163, -804.995535644726, -1441.31677186118, 3980.68203894802, 12058.6016443909, -13799.5281168267, -13119.8226982272, [...]
+5300.47862783497, 1379.47991984467, 1458.98404999497, 1734.42715573911, 17817.9075532857, -80.629422549343, 17495.9481935379, -6853.38249719653, -7160.54868030582, -8855.65154796338, -14681.7931878427, -3375.72167636157, -15247.2597300483, 7532.28202509484, 147.190359463209, -5728.09716245591, -13266.4076727464, 24249.229455423, -16853.0204203485, -9427.78410566727, -8385.58632156347, -13695.5432844433, 23826.9512673137, 12784.6726624952, -1040.53647110449, -2548.11632020175, -12502.4039 [...]
+2349.76956063878, -15693.2989813942, 9241.69939675467, 23160.7573562917, 358.664775279955, -15395.0509295456, -285.759638454181, 291.993692044887, -3471.68457376773, -10640.7420894158, -6327.52980174771, 4229.16733870049, 4281.01188831604, 10531.3710610717, 7287.51412035134, 8627.22456230718, -4890.16665900273, 10169.5278828295, 2467.27295156757, 4629.50511156335, 17459.8001990789, -7550.27651139794, 5691.30708005257, -15350.6226879532, -729.006413665539, 4591.1754491047, -12719.30751019 [...]
+-18483.0113014162, -6212.13982872438, -5044.83770194895, -1924.27305246687, 254.451734571508, 687.856108445567, 3239.93636286139, 3130.40611252042, -1248.17675181590, 10243.5920748001, -5334.69240437205, 4987.57535210755, 16040.9838069242, 18443.0237303910, 1774.73997687535, 7837.85567033343, -25237.3593380252, 3130.05952337454, -16317.2942246679, -15933.2362573695, 15830.4220161912, -1884.00026431333, 1598.29493133411, -10221.7616522975, -33.8639745868443, -6395.9970097369, 3422.8822554 [...]
+3289.07993643646, 6471.57066932085, 5384.38724149287, -6849.85757993177, 7250.29760197418, -11960.3901209968, 1783.88446711316, 1336.93594873881, 20397.0675511469, 3234.21211286424, -16183.7367320489, 15426.6050751775, -8625.0783330439, 10869.5473984361, 5612.42229585383, 14847.6645662456, 7420.52819650577, 17814.598062878, 10288.1399667897, 8634.4937710298, 11954.1673494520, -6441.93614461718, -6120.51009905672, -974.653383629917, 7713.92216827574, -13113.7637179697, -4916.95120331886,  [...]
+5741.54569804732, 7064.87274918998, 4961.61455411569, -4955.43759691165, -13071.4145107465, 28202.1956462394, -1956.01686634313, 33.7481190345918, -19210.1649294718, -7528.32729118042, -12557.0196792626, 1649.87435571294, 5759.60444527725, -9803.14705534623, 16916.8176733643, 10644.2665180988, 6405.79136282825, 12517.1277066834, 3582.98076438146, 3448.24254124767, -4383.19813604739, 2506.92133783719, 13740.4461141490, 5552.76016384461, 7510.59083528602, -10715.1051230112, 4044.9601370018 [...]
+21287.5288456421, -13300.937017928, 1780.76240467424, 16920.3414201139, -10619.1332234001, -15016.7929016379, 4317.72612849277, -7975.62794975512, 12929.0388661551, 8075.67116441576, -27871.0965466156, 21066.9785488320, 9859.13315326149, 3418.40056158392, -14118.2087876342, -1023.04782478472, -225.164827953089, 12571.4549930745, -1320.44192962794, 5848.17645507225, 2034.51218871179, 2502.79264156044, 12624.7796805143, -8983.8950409086, 2208.23241765836, -12834.8434911506, -13617.42471020 [...]
+7731.27043897109, 4991.47605159596, -6649.21653315694, -2102.29857927459, -3172.32147219752, -5661.01312849759, 10091.0322342933, 2373.33302203709, -10285.3821942642, 6943.75624066763, -1858.73949298214, -18334.7832583259, 11506.1916107230, -11162.3717860693, 16283.5455541752, 5457.75053203444, -4524.48909840815, 7190.80494440058, 7464.90263064247, -1087.07357262087, 14556.9681776601, 5790.23935521526, -21977.4423947494, -2778.22342496370, 3122.35857913950, 16807.5887870611, 11047.570319 [...]
+-4717.30378189086, -13743.5218546681, 9637.70535865377, 5750.66359456404, 11983.3785925108, 21024.0900188309, -2609.83394089064, 7887.81635165282, 7803.72752188473, -3177.12904085438, 6973.73850249206, -8872.88447834316, 21068.0035318672, 6201.2865568694, 1781.64979682522, 6604.68760330701, 1268.06872612955, 11979.4845014688, -3658.40191784303, 2261.74551988407, -535.390660246228, 25913.2357892521, 15422.3374552625, -17775.7847469469, -226.536846811346, -10283.3952715334, 1739.3322654423 [...]
+-183.165233579735, 5932.7711899209, -10766.3541865329, -15874.2351148935, -9158.2315822855, 9009.06001567174, 9490.49705222393, 908.488024891519, 2395.67750529816, 9839.10092105583, 6114.12883402512, -5971.6803161426, -1182.94271733834, 7214.34924307894, 8109.00069106473, 17994.9132676144, 5157.04460628873, -18685.7916605756, -4003.90599679386, -6902.84343409221, 1108.26044767010, 6380.05993941675, 1320.19096360922, 18733.9779964281, 19660.5753636208, -10858.0171722763, 2673.71757534661, [...]
+-12326.5112403996, -2974.52783627788, 2967.73745585378, 4719.46492866587, 6105.17207428957, 21456.6735504834, -7385.40018009617, -3891.28924574842, 320.180664948423, 4284.87403620192, -389.874788979447, -12540.9960083065, 8111.25456753474, -8109.82068927337, -22451.2788720401, -8693.74911184892, 7832.04980902858, 8960.08321162673, -7899.08502143185, -11034.5692734054, -14600.4695312127, -481.99792779425, 5915.29903182547, 7959.49918237137, -8395.66463529639, -13409.9288686081, -5598.9130 [...]
+2063.05016777501, -10142.1553098489, -14678.4822615976, -1169.41965931256, 4961.12898400482, 25645.3324570573, -7483.27942282986, -5056.17604624685, -6042.32935094743, -4016.69869161558, 8622.7332429417, 4363.97672471824, 10081.5600359118, -2516.19405571990, 3933.90354928808, -17798.7585526391, -6470.63664341986, -15724.9576535108, -11933.7049450595, -4942.21069047453, 2534.60229074270, 1828.44805569609, 7143.11303976817, -4755.36194519798, -9263.12335179983, 5000.66459066828, 2580.66374 [...]
+1939.96235627809, -19942.8678259664, -16498.0476849282, 2720.26994979996, -14131.9575879044, -2474.76425074746, -14935.2756200860, 3373.55843021124, -2446.34330294336, -1980.18639718908, 3392.66050024634, -13138.9554498407, 4672.58609034386, 827.348330884036, -6326.46167923654, 8963.13125286784, 2711.87013242599, -11965.2726380877, 5166.5651362427, 7111.60749718207, -8141.30847879114, 658.746193044452, -14.6903966186769, 2293.40059999844, -13034.8412358391, -17900.6492413569, 3488.369835 [...]
+-6246.88643665591, 4605.14170778223, -4216.99535756903, -2987.94821203338, -484.856526533278, -1470.65060960475, 4125.37443666686, -8813.24534764737, -149.524608992647, -5220.8461681454, 16661.912565673, -9433.87363798567, -6724.9033366298, -7216.01327930178, 12683.4048261726, -8418.97831621469, 10621.4826615562, -2518.01935564421, 3905.27155666726, 5072.65838260643, 2338.85235384382, 10842.5067085930, -8323.10925673338, -13907.8694070567, -16778.1644018994, -6030.20003268727, 6258.03983 [...]
+-10793.0081277411, -4495.93016379908, -2688.34290449812, 15198.9845927599, -4041.78747727699, -9090.6838537395, 4553.5074726224, 10097.2100271229, -15515.3655404600, -8244.37264914891, 87.1184570520614, -4473.14310963362, 4661.30222844421, 7891.5142465648, 8193.17099015504, -5206.7314075763, -3194.60577985984, -1034.16606222866, -2824.60508489863, 1227.24453550130, 14635.3887057493, 16209.8172968051, 11557.4101757663, 6571.20783691536, 3998.50101858254, -51.7846279561205, -2752.565309884 [...]
+9564.79167687813, -8175.17050247433, -20432.2894775904, -5470.942180814, 14224.4587221059, 6792.22956413419, 32.0853505702163, -4445.3859478989, -15885.8668797758, 12645.5941834562, -7494.3300846061, 2834.35179011882, -13629.9513835582, 5195.3591782973, 8904.55433459241, 3738.01443633265, 13745.8633135301, 3197.93220387152, 3474.60313795191, -2448.66730380271, -646.602718818822, 3878.09911620813, -7871.23305454878, 2787.17940608686, -11766.4834472295, 19820.528243584, 21706.5128589617, - [...]
+-7379.03969722597, -21.0040767454504, 21222.7746613501, 15393.6728756995, 3284.79868456529, -13534.0662888007, -14657.3165736155, -12845.5061384478, 2265.83604779651, 2728.73853552014, 3047.37983842196, -11538.1579141804, 10568.6380472410, 16121.5509130253, -746.617248489761, 10920.5470954736, 1434.93559329721, -2382.10034739777, -4280.9548790642, -5643.00295878765, -11232.300350742, -1421.10206623541, -6316.86350255702, 4891.0410807622, -3380.75837722729, -8601.84025484003, 5493.8932501 [...]
+1111.73167638473, -1110.89942564318, -14.5901441837577, 7974.34256335091, -2828.29140274821, 743.239452848596, 2628.147374627, -4894.95989878898, -9872.69797430773, -12139.8181518818, -2910.69368088655, -1024.69402683533, 5393.95803205421, 5645.56154689599, 513.854126501338, -979.17663052995, -207.476168820152, 1180.49526926300, -2863.39021565657, 3000.33587898078, 7275.41121171005, -5403.17588176663, 11285.0351297562, -10422.5094231733, 11372.5271349061, 4857.55258762796, 3619.133586052 [...]
+3302.40728863658, 6489.0923512881, -4182.09627142732, 2111.88954830279, 20400.0864685596, 3331.24610247027, 1279.0860068201, 14463.4309911378, 13899.6137783619, -5775.1731295439, -5042.501945889, -19232.8890658970, 11565.3040227179, 1762.7468525868, 2514.70734282291, 362.026449615877, 394.474934055138, -1652.37256042351, -16851.1131634272, 5323.81995732519, -2418.91445952683, -2139.55955043371, 19585.8562028893, -13073.6909913344, 3923.04863022984, -6971.68654042708, 9328.40826723995, -2 [...]
+-9914.69579668591, -20944.6978986310, 15734.1612784216, 2838.31664334722, -6602.74734122488, -9496.48182615516, 2147.2780845761, 6338.36841342373, -9299.02523069476, 10032.9632275019, 9803.11994049328, -17089.3024418047, -15218.2737649310, 6870.0714466143, -4738.59721823658, -2379.22084443786, -6529.09223230935, -9691.1375826236, 15207.8061864847, 12061.9003531942, -29403.3506676981, -451.011869065715, 5490.61902342348, 9938.57988248067, -5124.1097623358, 3291.80047896155, -2072.06348126 [...]
+5857.09592169966, 4554.07072139481, -2538.52021738820, -7882.59037606756, 13498.0884369484, 567.175507287013, -17523.8554183966, -5493.04805260762, 1546.71138328206, -2924.59926945477, 13770.5509841791, 10677.8169065176, -6684.96276780058, 16908.2829486866, -3064.58335543481, -3199.39500617436, -2550.2901031969, 454.498334339891, -7570.69774081347, 16309.8516871294, 244.886310177886, 8989.25898502492, 3904.03088214836, 6201.09286451071, -6176.20128073204, 315.806889412979, -5564.31357412 [...]
+24169.2329439429, 28714.2351771641, -10328.7365181245, 10677.9746209922, -6016.62280108562, -10905.9706923516, -18237.3899347516, -9271.98970601885, 2088.05593207362, -15548.7689487866, 3526.06623134087, 5278.03792031417, -8326.97839075764, -311.883029340421, -12367.4462832730, -5772.58274065883, -16076.0340678489, -3263.43684461927, 4856.30535181382, -9974.02722590706, -7892.1054180402, -10956.1722531311, -12608.5909636074, -1237.94891703446, 3947.96318022711, 13170.9721453032, 6324.976 [...]
+12092.4080823384, 7593.80594589373, -4857.63162475865, 13122.9650103285, 5052.87348319084, 11933.6269174519, 9380.6387622492, 4574.17044956220, 7084.00371507565, -6532.83677961661, 11014.1979428500, 3607.12469974775, -17969.7754367714, -5955.04525105962, 5895.64728872909, -2222.33432716683, -13169.4642225778, 11229.6301719267, -343.188947572227, -4550.40844992662, 10130.2501353618, 5788.83290151854, 7505.15509414337, -14939.9609390028, 18708.0530291102, 4697.37013955793, 2528.40064238495 [...]
+-9206.75189724356, 4791.80856430986, 2333.49967925019, 16901.706725251, 6.3732255681208, 18054.8132276459, -5427.58974898014, -1282.78768145925, 11428.7184528321, 14076.3945778083, -1699.70947864497, -9439.78893743498, -2797.2988424701, 4697.3215622685, 7192.89092105134, 3791.45529019676, -16422.9298651043, 10547.2858562051, 4937.65888878977, 1114.69553597531, 2042.86900464034, -5021.63471618515, -1270.91581420058, 2935.28454548982, 9179.76578297548, 20065.5774834230, -3156.41743115607,  [...]
+10319.1000738724, 556.05831710356, 3706.3886981586, 3214.26790992755, -17289.2993421016, 9642.78411718433, 5029.17873251549, 11278.8686075865, 6185.7017639089, 2074.34064455829, 28410.4251128903, 13053.2436437658, -19241.2662595876, -29572.7084589565, 3426.92410333458, 7990.97432661924, -2498.84805920652, -12588.3954805051, -1030.04074705951, 9070.99049946193, -5558.08086244807, 7903.37950650252, 2968.09841723991, 19042.1399451504, 3040.86666437103, 4586.19496589688, -4240.39398171238, 2 [...]
+3964.53593737166, -4697.06716608721, 1491.97231240586, -4531.52090965559, 487.691155892629, 4089.34723964017, -13879.6967784648, 12661.5718809452, -15883.0516261729, 1382.02587831214, -10185.2776408488, -4569.13265491492, 8282.88598395315, -9553.68744999135, -5159.93137438155, -5750.99015659244, -6958.70173263345, -195.396350823365, -9636.70187216654, -5450.64594464354, -112.650346766378, 3162.10847622153, 4196.04238352414, -3219.95188470892, -82.1372846046084, -11121.1795300049, -9627.8 [...]
+11692.0525218933, 8200.54382170463, 511.055650413216, -1969.84241446441, -12896.1802880979, 6275.9681888359, 16137.9283179682, 4442.44848893639, 9597.15063981235, 1873.99438619100, -13855.37825636, -3294.95226619415, 2548.45744089306, 3598.25793855658, -6141.63511729557, 10549.6068600352, -5496.16540003134, 16796.4844629709, -8286.54595230315, 7865.57636986316, -3147.71980873426, 1990.73676779479, 6782.08740341251, 1161.76504851374, -3787.2010380366, 26839.0608037037, 22110.8059781388, - [...]
+-678.093896825549, -5153.53378446166, 10020.9670988992, 10697.4846840312, 17120.1634879411, 9308.65481089017, 3325.72183169243, -1285.36879678147, 1932.64609102149, 11416.2588258693, 10866.4856122842, 12215.3245132049, -13794.1711569073, 7608.34526803528, -2351.23335127732, 6336.73407606413, 2764.91663186228, -979.751665354056, 2491.58070620228, -12718.5645587520, -11950.1802998978, -563.907155420721, -4928.10533690554, -1339.09408934601, 1193.25477575466, 8148.27715003546, 11337.2748860 [...]
+22458.4085863180, -10741.4325009730, -2060.79385216805, -3108.8672335606, 11440.7379367218, -10501.8486154812, -2543.21784041926, 10099.3300647580, 5447.14366448364, 15611.379933094, 11846.8409391557, -3402.80300610996, 5375.09701215405, -8030.37359726961, -2992.44698348446, -4189.90766039102, 2441.15756725555, -3679.67933168304, 1053.12196683002, 7751.26720916454, 4201.96475715332, -15786.0207336750, -11572.4797100594, 7886.29856374258, 8169.97982085061, 2559.24614347192, -1181.32466661 [...]
+-17350.5081200132, 2495.09915207303, 2116.58507649953, 3069.2742896355, 10572.4679604986, 10097.5629464260, -6547.38442809837, 14864.4499201019, 304.589224522614, 13450.9424121436, 5397.15355845332, 9014.74817443845, -17769.4052299659, 21237.0606854605, -2488.65130447027, 12584.8151849544, -1704.09813337162, -9529.62899596538, -4651.03248422952, 1696.24080007755, -19328.331501065, -2577.79366993361, -1373.50828469759, -4407.07920392339, -5090.54311511081, -16000.9531812126, 3188.73884878 [...]
+-3615.28138154525, 15335.1223717891, -104.349981658408, -10935.0705165101, -7486.84809564171, -1164.20501151284, -19029.1864097854, -4536.85155749189, -11449.4818007375, 1576.26678758068, 6521.85571450449, 5910.53729732593, 5383.42010462862, -9439.33258987453, 1807.98190933804, 1829.60667008151, -3324.06926233242, -5499.87863145864, -8349.92064003875, 9943.37628964312, 208.288182146104, 11176.4524622808, 943.782247163615, 6141.10951896367, -9406.31315240774, -4973.78199350964, 11927.4631 [...]
+-15476.5213150292, 10079.8876947333, 19573.7602220475, 1532.90823044598, -476.785541299087, 950.44691726718, -2428.32889833383, 697.999939514988, 2892.33166140802, 9076.43453218909, 5319.29201089049, 5928.59457067774, 18709.2601662302, 1828.72242924957, 1057.33855097734, 13781.0982277119, 2708.60632160021, 11764.3117328485, 19041.1498712275, 11713.0689057074, 2673.76378385443, -2959.67378613096, 7640.2835617758, -17635.81631832, -2998.48841519963, 9498.92579440932, 19957.8227976356, -994 [...]
+-12855.8577159934, -8491.46107697349, 1182.49388533431, 19286.8190578296, 4081.56654736623, 2990.06022843458, 13288.1609155761, -17028.7521253970, 10577.5105953638, -8861.98984544948, -13837.8468612262, 16834.3691012891, 1818.03165604967, -11594.2663355343, 10686.0187633666, 19687.3914603092, -7642.84228057791, 13925.8437767675, -22231.7264550309, 10981.3446759382, -12429.8835093796, 14743.9420469759, -12195.7039347464, 417.648940726064, -323.099758345786, -5724.38239197807, 11584.667924 [...]
+6788.16943384509, 8871.32427270593, -10099.8409540369, -8219.21156471449, -13683.5547378593, 3993.73649033291, -2763.08612749523, 2277.58749233664, 11588.9584895166, 18762.3438322196, 895.899494836681, -10536.6894775870, 1935.38154717696, 3663.36760880011, 4522.98837170521, 3963.68588747313, -6350.21613962081, 20825.4429443353, -5267.7161060455, -10233.3744500884, -3347.40280205544, -16946.4977987008, -9447.45756145476, -2422.92843126803, -3217.57923315555, 12480.9853752927, 8352.6487543 [...]
+-10090.1669246122, -6043.25333949378, -6838.58856010839, 9671.87334477353, -14739.3546211891, -14254.0846126812, -696.480765131477, -6511.42861070835, 5220.9604962245, -7540.0727242159, 267.183525517404, 2140.82660834939, -9991.65231647037, 4691.8929268602, 11502.4419885096, -1179.01792448192, 13868.8712311533, -913.272075052085, -3889.72951479229, -18188.2263948453, -13482.1501559505, -3907.40491174166, 5908.83650074144, -9603.28179819387, -3679.58629673344, -4108.59229541284, 10324.884 [...]
+17125.6993154330, 5402.80465455274, 6181.31620628567, 3936.81992442341, 19859.233556296, -2131.83466727781, -4010.47735401983, -1228.02043426758, -4776.71282082922, -5896.21067839431, -11482.1364792814, 11057.4584766895, -10595.9763677591, -2311.94967123807, 20280.1084938033, -6009.38184973838, -11160.4677666671, -10084.7798422781, 8007.01790599207, -8615.11326883474, -1447.56108712205, 9329.76153119543, -2771.59431634554, 12940.2055933407, 8325.31551170548, -16183.3541809180, -2710.4758 [...]
+3856.04399422695, 8011.11143691839, -6972.1542839869, 5412.32426804907, -21089.5465811543, 11346.4124933397, 4876.77636517931, 4479.22956095393, -3231.13050791305, -7733.86746266275, -5304.85502745522, 7712.53827352282, 12837.4883156678, 13150.5092180586, 881.862688817388, 15168.7649479345, 943.76669255129, 151.220361472181, 12058.5349341644, 3393.39910704468, -4859.51446772396, 7359.67012933161, 1001.42027118070, -3471.46519896997, -8160.60647712434, -15033.5764811331, 10874.9036897757, [...]
+1056.44626453239, -65.053525102682, -10209.597396202, 4720.84947111906, 2116.88602256678, 13288.8479554388, 12589.8262295743, 8773.56683732555, -20732.2597784074, -9456.58296398897, -21038.8170413091, 25813.4870976457, 26709.3666747833, -3891.86684470224, -8883.81261788155, -503.893018890397, 5715.29481682453, 9217.47380177104, -4130.25768107026, 7814.74013717216, 7236.03223694849, 2042.75199912836, -921.258610289053, -5785.059673766, 9174.52395769854, 6754.53511466137, 15609.5121088335, [...]
+16117.0175024675, 6226.53043108061, -141.188658503619, 17719.5175427521, 1515.69938360601, 9581.61574524373, -7182.04875274513, -3450.31020657827, -2955.87952306774, -16659.7336818911, 7329.99249974233, -15948.5004245478, 81.06348608049, -24124.4711368847, 15462.3632946261, -7758.06506072985, 2641.17442514848, 3374.48316457982, -9257.16779110083, -1439.18758169331, -5053.18571081229, 10716.6291093070, 6657.17429447591, -7486.9783548055, 16593.8784934701, 10935.5043307769, 1988.9313815532 [...]
+-2642.24934217442, -2657.05764042287, 5367.93795608424, 2168.16249634085, 3603.10600014856, -6602.43952598075, -19083.6920035032, -2127.66494472455, -10064.6080438741, -2695.70122171147, 1851.31739526731, -4303.89764975497, 8584.31848198054, -4947.12994214352, -7370.20851146078, 2065.55098843949, 1513.12946512221, -2546.10874781716, -12482.8835700270, 5282.49477409673, -5275.72412490590, -6629.37129366989, 3028.93443910202, 4446.98304878071, 15787.7914704704, 11940.8154733042, -467.10741 [...]
+6932.83465285524, -580.919629187795, -5643.75803354068, 10312.9008888580, -2698.00869981535, 5907.72750708619, 21706.7421106381, 6220.17511404813, 4314.92610339284, 4370.83645406539, -19539.950287676, -7018.70749462921, -1338.51641084565, 16825.4446426752, 2116.48648909105, -8729.62758572715, -7029.69306724748, 5925.58937681257, 15783.8041233728, 16250.2075205308, 5412.53524465622, -4632.12098781715, -13991.1700001093, -4150.05819078180, 4568.90755267699, -3366.27477484942, 4566.53626673 [...]
+-11414.3658150304, -15244.980970798, -2168.13390724606, -8465.60282268291, 10441.8328630829, 15350.0616795328, 8308.51511876253, -21479.0037886414, -2128.18337933383, -481.88521596009, -1356.01855632775, 6123.41824832741, -358.047751541547, 6213.05959964022, -19516.2025504346, 9130.36981587306, -8866.02744711067, -4112.34836515527, -19633.8481968934, 5866.64630743852, 10538.1106288342, 7696.08347915542, 9775.11122646087, 8190.72607563588, 4514.98499138107, 5724.35445257902, 4713.80463439 [...]
+9552.29846677442, 14413.2190621339, 9092.16746562882, -10561.5206317855, 13498.3906003120, -2479.74030400649, -22678.0308718069, -8963.93964978982, -5306.31992551738, 19921.1536987297, 23907.7543642133, 594.14381250313, -2628.83606517605, 14205.7198062653, 23940.0776013640, -4853.87319395868, 932.547301837938, 7848.05243983818, 11633.8159638813, 1210.06943167515, 3903.62768400399, 2111.43213718626, -2363.17393263918, -8797.78546965774, 11869.6588121520, 17994.6311939324, 28186.9923038791 [...]
+-10723.5776045122, 5652.38290717159, -1810.13027978901, -17324.6589673580, -10307.3339268303, -9198.68339265849, 7257.54981809816, 5505.64935797888, 14771.5309027049, -8586.55576136141, 3084.16381789015, -11769.3184496146, 4066.33042536491, 6764.83705830032, 11113.1973943123, 9162.34108976923, 4661.99104775406, -11972.8746147732, -13118.2061526117, 8817.86642259202, -5411.730137682, 9359.39478265424, -7100.08701362065, -8164.18968421479, 15967.5528854417, 2519.25035638755, -3835.52163105 [...]
+-9955.32678320787, 11214.6113651264, -3927.18001320892, 7758.67543349501, -12558.3193932448, -1576.99670337295, 1239.19257548837, 6982.37237710499, 1117.52483802354, -7296.70845058444, 16026.1454556324, -1879.93626470890, -18948.6801853609, 2020.16451931885, -14493.1344126299, -7484.74852557308, 13488.8938821376, -8254.42263187118, 7223.47470040232, -6587.14762357267, 8985.81198312104, 814.503863937969, 1988.16990917114, -10815.6184808474, 7798.70140476687, 2233.19341317601, 5850.4147832 [...]
+1228.22830900936, 18171.5019157676, 3133.38608589704, -1139.64614350625, 12158.8091474338, 14513.5562562749, 1014.86975749435, 3041.86076053440, 13060.1846798401, -10974.1425616204, -7390.29644853653, -1799.07007340771, -4495.12712132639, -7151.31678812893, 13379.4448759442, -10825.5475752157, -3660.97569514057, -3002.41823151798, 13621.0962023720, 6226.97065048574, 1641.85087611246, 2476.6299618556, 18855.7478820673, -17173.1010834343, 1307.39045313250, -14727.7892162378, 9394.177233929 [...]
+-10389.0339713765, -8151.11348475213, 12635.6542037434, 4805.96676344287, 1614.01952896033, -12915.7107664349, -17785.8234962498, -5107.85276459368, 20155.3879037901, 7688.49268269485, -22165.0619490007, 19673.1319662637, 4171.65040242232, -9947.90771550885, 3859.81424046309, 12220.5704590978, 3721.26402083551, 8924.51648409231, 3398.75530756313, -12511.1179017574, 5327.10621945361, 345.697681685784, -3595.57198123798, 26630.7008219611, 13135.9820763397, -1812.09713480189, -8707.92890164 [...]
+-3583.75253147365, -12579.6872676223, -13377.6745838182, 5334.05451798852, 6098.89821348703, -4353.63728455318, -8038.94791143855, -6547.05121339409, -4653.37590995874, -7542.740275054, -18972.6414193812, -8990.47935770845, -4826.5950082618, 7389.45306307144, 8669.95579761223, -3925.63723474541, 5210.98477949416, -19883.8501148170, 8063.94543122956, -12357.1745561851, -10709.8307001608, 7701.88785259647, 12598.5031991576, -2578.19022489414, -517.580051198607, -14198.5747163378, 376.39864 [...]
+16398.9788762309, -11119.3731340179, 7496.16290395961, -14337.7479615986, -7572.85604367227, -9832.3093756334, 3286.50631988429, -19193.7766997749, -8042.5341559009, 13923.6331483174, -25709.3688457197, 14224.1032360749, -13628.6885530418, 11557.7690768326, 15512.5048552652, 2419.94406405813, 7233.20972860064, -1684.47727325031, -5154.00205283142, -22916.5799999093, -8260.811432748, -5556.07966061394, 3123.86206620358, 13389.4052957205, 7182.47528846698, 5798.10008713001, 12638.818040686 [...]
+359.584228244442, -10213.9225422097, -11337.0756031728, -6502.13881743063, 1254.1454964283, 9069.98817990715, 4141.53567831943, -0.452498007261656, -10936.1713911783, 3823.35355376495, 875.985960765756, -4642.71371501872, -14862.5245047884, -7607.56273676069, 10647.3158036494, -8148.74858667061, -19013.3718832111, -7056.5257242024, 1881.07449602706, 41735.3625036579, -10832.3204218793, -13014.3712048128, 8976.87558318972, 485.292802741101, -6088.81760833042, 9613.9717344034, 14862.447494 [...]
+-10376.6474739722, 18870.0047773267, 9707.51716590833, 12206.7173201421, 2768.86778549084, 9857.02302469699, 9387.8576932671, 15246.5709537366, 9460.3880970828, -17037.529388921, 2065.35277970081, 2556.09058509158, 1290.6428136618, 5581.5328275097, -12247.3610521376, -9557.76000544503, 13095.0076601358, -8289.2400309679, -4402.52428573495, 16879.5288548901, -17371.3184822004, 2856.12356859628, 12472.8750020102, 1727.20301316766, 2974.43803451067, 6323.95689399287, 2370.11194409551, 16295 [...]
+7331.5302665951, 1505.54345413867, 5127.88043643891, 12060.9367485454, 3719.16052550325, 10442.7105258057, -4476.9368328397, 3581.42189276634, -10189.4107891994, -8658.68597328215, -3465.69363796884, -4715.14864750831, 9442.3617299285, 14269.2504186926, -6356.95213912184, 18886.345557487, 5697.98915174154, -12260.1364879409, 4393.82014200066, -12594.8085960640, 10318.8668605062, 3771.50544549745, -3715.15707326257, -110.201463481477, 4300.43896410484, 2606.87517295647, -7562.17602061405, [...]
+6263.46563246983, 6405.35248087667, 12809.3378408346, 7440.5358399743, -5057.70955179335, 3893.33512263719, 14672.3880698661, 10636.4585238014, 1490.91031349075, 8095.9785004816, -12369.7006696768, 12993.0898550281, 1155.81273668720, -4664.6336643312, 3819.50282432333, 12888.2436738352, -13506.1513296173, 1531.73925163797, 7222.4605928381, -6344.21237796868, 4519.10858676669, -3214.50944785299, 4489.61429177642, -10350.0919661147, 15013.0165275054, 4193.40885216178, -2151.93188180906, 78 [...]
+-6.32978371892854, 15121.3679696359, 7328.22320189095, 2758.18507164047, -9053.11989875832, 2085.87356222078, -16662.8017248691, 9365.23590561703, 6749.652742766, 5978.01246212559, 11128.7233981762, 13277.7870255890, 12511.0547779091, -25040.3084701952, -7954.29858791583, 1667.44512310570, -5965.75481465851, 685.885283900662, -18618.8181580354, -14436.2825339667, 7160.61901760528, 4965.22143649578, 4228.38043831058, -790.952293877131, -16366.7522553528, 13048.4182218502, -13815.709044708 [...]
+3338.05841636876, 17915.2641833126, 2012.20637553005, 11522.4518721433, -822.202786270168, 4481.78158085988, 7894.1771803494, -13675.2742843240, 21921.8966430681, -14895.1633170588, 10512.4749766763, -4757.73243303387, 8078.43114230209, 1363.83999380305, -33902.9290444941, -2920.66872180881, 319.019003245146, 15374.4995933862, 6897.02428761091, -606.49046736983, 8706.04936240117, 3729.01372763115, -14432.8312173512, -9819.50173569585, 8766.34836256572, -6024.29650249712, 7099.00700367819 [...]
+-8961.10045667549, 6833.24265741632, -4054.18620204438, 10662.5254975162, -8350.48586123457, 9882.11256483738, -8517.9949937293, 5040.40971080049, 19194.1314129741, -10512.8378266667, -2695.09715584173, 4427.10423908683, 3908.38916231231, -805.4562242586, 3879.94938239472, -10592.9074477076, -8583.2071172871, -5326.14662133446, -979.833558655483, -11965.6923329992, -1324.47274777452, -4047.14238680204, -10118.6389220546, 1764.28389002189, 5262.6706356312, 9232.00700906879, 10947.63251915 [...]
+18752.5049460967, 4533.89131033143, -11213.7656748914, 1389.6143688103, -4302.89252724668, 10501.077517442, -5865.02607195591, -18032.9493248806, 3104.39573738835, -5422.65568181372, 2025.96796145095, 5944.2896950198, -19980.7641967470, 7333.4350212978, -17579.4271688147, 8319.78126158268, 870.855394939766, -7073.3045517722, -16934.4797741312, 769.298985727464, -1298.13692591609, -6534.34682773533, 4815.60580963314, -24705.2989906594, -4820.12935274937, -1941.02772044589, 10143.650859193 [...]
+-12794.8061871100, -4952.21178685274, -2670.40663015542, -4998.96466634846, -5615.39210878628, 1288.36446686517, -10581.2765730305, -19349.5126840334, -1678.93935681473, -3885.74023604897, -10092.9078670613, -16080.6901309817, -2217.32139996183, 271.044744775013, -4591.75089938326, 24077.693218231, 20294.4630925606, 19045.8711073967, 7238.40212671063, 4535.16573031499, -2986.01780120198, 7925.49600351517, -4343.6433221164, 1112.68508064722, 22995.3923348572, -10021.9574161149, 3209.90281 [...]
+-2065.66273085136, -23086.4771764823, -4946.51037031309, 499.679051269936, -12124.8849531185, -11034.8739879845, 13750.4526605869, -12405.2280749388, 5400.61083829663, -4802.97211782387, -17963.6819698622, 548.26316327211, -2981.70077211632, 497.381848216702, -3426.40899253247, 7884.18382992956, -6803.58788159882, 4672.72599246103, -3586.03076783787, -8003.77155688486, -3973.27836898768, -17020.4465662701, 6371.66793115484, 1062.30070410366, 5108.70561243646, 11906.5688499976, -7969.8781 [...]
+7865.91194464548, 3051.64608141169, 3815.44672342587, -19968.8548592467, 5751.0554697674, -4024.24647183612, -1679.85494357510, -13782.5635704250, 13744.3370824897, 22918.7206355991, 9441.01513969314, -2898.06312600364, 2220.28841515513, 219.705576737574, -388.123814540614, 5428.66554003908, 7614.13443358295, 978.46585805156, -11846.0627011341, -4383.16582070819, 5319.68287775149, 9047.43999563243, -4381.22953131287, -16245.824305842, 11694.5498296364, 11707.1522564815, -5257.21061328166 [...]
+12615.7572196213, 4957.5516950494, -9178.29168871146, -6154.08263736172, 22470.7810501295, 12793.0222502457, 10599.9067232293, 13102.8076360821, -12787.1598546423, 16672.3000635911, 10172.6346855704, -11827.5040613741, -1565.06630528077, -2340.04115919494, 24903.5073106614, 14803.0925411849, 7290.47399354149, 6069.87785709412, 14835.5708477289, 2699.76368641622, 11125.4265226956, -611.489714931538, 6650.59232645462, 4248.4756219202, -12903.3966828157, -2941.56651720182, 7150.21821813764, [...]
+9551.28337207266, 9229.75479419969, -133.811149916776, -2952.94899481308, 5229.36144298321, -1461.30302413503, -1633.68230613562, 1108.72901146168, -22697.0521123181, 10137.0362459572, 6167.87774929751, -8698.82058351177, 14860.3041001621, -3010.88393037375, -4697.78733811259, -7977.48583070382, 1062.16431763805, 1050.07812891430, -981.54353069388, -2177.93812710377, 8085.09854451896, -8253.55124623794, -9137.91735558887, 2089.69513862758, -409.517003579951, 8008.3210219532, 10652.500092 [...]
+
+double y4[100] = {
+-9429084.92351584, -14108877.5139263, -44597237.496434, -51264981.2541185, -61868564.26111, -40790458.7611962, -16798741.7808914, -80127913.9782022, 18977552.2641458, -98210874.5347748, -28908621.0225011, -122492064.148554, 54830273.5153695, 64307144.0380555, -46498556.7941315, 73666569.1929155, 30325663.4899331, -77695067.8394815, -8423777.6682193, -30325334.8791726, 51747332.659533, -149705721.594690, 1724881.74810515, 27626464.9820607, -99951153.6472705, -10464985.689452, 8367940.0702 [...]
+
+double lars4[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 23.48930515004130700, 82.96362004358508100, 101.36678392810015000, 150.15479816788212000, 186.60349488428659000, 192.21780212676961000, 199.06125132122159000, 247.83164154810200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 65.84214518381242000, 83.24436590123436000, 131.17456971005649000, 147.50982332949570000, 200.34795572935550000, 233.10711691362130000, 240.10948043233634000, 249.15854294394333000, 309.863043602288 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -65.11297316171963700, -97.25175461530777500, -118.81446286214522000, -145.43097642450300000, -258.45246315097489000, -324.90150770296600000, -363.60732860612370000, -379.00260772332371000, -409.92594380936640000, -483.26272493071156000, -500.46498705425489000, -550.41145341881975000, -565.13488682308719000, -611.90896404513478000, -653.98879861123976000, -663.22421663563762000, -674. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -5.12258425233860400, -26.26095448352293400, -70.18 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -144.63026779224444000, -227.26353246706054000, -280.99006919331100000, -297.23269085672047000, -328.13338596171315000, -412.02834916926849000, -436.05570758456241000, -492.84878663761873000, -510.15317339929419000, -560.73997426348330000, -586.24837964661288000, -591.41890811699761000, -598.0788359657 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-88.18990148529790900, -215.00309478270037000, -387.42784309864015000, -403.02176255083469000, -436.03527925289472000, -504.38588853260080000, -548.69246303103705000, -576.00282086679749000, -609.04464456779158000, -742.56599598619073000, -816.07672449303595000, -860.38397388191345000, -869.03667040511027000, -887.52143100953526000, -928.41122600267431000, -942.38476713392731000, -976.20462017917066000, -986.91433156191499000, -1012.88085346111280000, -1031.41151638431530000, -1036.01022 [...]
+0.00000000000000000, 0.00000000000000000, -158.79455391949560000, -172.23141383066169000, -206.03381648470020000, -269.84264571736423000, -306.15546857136746000, -324.14571675120817000, -350.98882530056704000, -478.93072989711357000, -545.45029911364543000, -599.43001684623346000, -617.06415564153860000, -645.94674463356682000, -712.59480816642451000, -731.66111635328912000, -761.72819400005096000, -769.56353033397227000, -782.05598073874171000, -793.23781622948252000, -795.3467796498896 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 50.21745771150207800, 61.00077849216833700, 74.63481596317207300, 162.89952568458790000, 288. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.42013443061030400, 104.91585383377556000, 124.51154092093920000, 168.77841273620180000, 183.29099966629258000, 225.56733631978673000, 257.28054849387036000, 263.42863479048793000, 270.63567055477336000, 318.788390330 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -74.60471707233510600, -97.94626154616705100, -164.39808157129741000, -217.93456719177703000, -230.67598792802008000, -245.50330489784929000, -343.869649003 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -31.28726468638891900, -153.92496946197357000, -226.43162681766498000, -267.27141311358946000, -280.87187776893597000, -303.18728933182138000, -346.00425351534284000, -359.29853724364835000, -401.88568258363006000, -413.40701130098694000, -434.20515490249807000, -450.24342892009827000, -454.18075944104396000, -458.29912640 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 116.36176 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -70.69718626735476600, -92.58934618579260700, -127.83673475857204000, -208.90026333199026000, -231.72037832382262000, -283.34162521654071000, -301.61261228998251000, -342.31847304354130000, -365.19682020779857000, -368.28656041847449000, -371.75197041825919000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 62.95142376844949400, 115.30243905497581000, 127.32078823084498000, 142.65752698886723000, 235.47169939644337000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.17612870503193500, 71.69701634003712300, 100.59594213014097000, 205.73592753333398000, 265.69070075646613000, 316.82092103483603000, 330.41458156539221000, 353.67982876711426000, 405.08500120910185000, 420.41259070006186000, 460.09552079441505000, 473.63892353147514000, 494.24767473067033000, 511.90872588872605000, 513.42907123925465000, 516.01856734711089000,  [...]
+0.00000000000000000, 149.71861771190038000, 341.62543344039500000, 359.28351630792338000, 403.01683600563786000, 484.95935343460138000, 537.70198210797435000, 566.95171610875252000, 602.72637014913687000, 721.55352756198408000, 791.35911256861039000, 830.29236106320786000, 846.87405123132464000, 875.74509454986980000, 941.30881645972670000, 960.81406992871166000, 1000.93500720192280000, 1014.31936627450740000, 1052.20505883884080000, 1090.57279505451450000, 1099.60707572161780000, 1110.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -26.25903081095378900, -74.69553504089100200, -103.72542498581643000, -119.72508532944987000, -140.76050973034083000, -210.09484686757972000, -244.40515161408899000, -271.05890198909003000, -284.72975688877978000, -309.92712000434585000, -368.60851280700149000, -386.22639409880998000, -426.36066700654590000, -438.06612299580365000, -477.34692735679374000, -507.04450605857909000, -513.39214708365921000, -5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 69.36026571985375700, 142.9317 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 15.39696067533322900, 49.17247259093291200, 119.45333213597534000, 161.91379597168952000, 186.24351377251475000, 210.47849509448565000, 298.33369770988054000, 351.72941770049681000, 403.35500748203395000, 423.23687288058153000, 462.67678264081360000, 549.21315683652517000, 571.84792928707179000, 626.35896912741305000, 644.50564790827161000, 681.80953698471012000, 708.52130249348943000, 712.61303056297254000, 717.8590715174340 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -18.04993943316478400, -39.29913208163101500, -105.79391865328355000, -147.30611292674527000, -170.47329151864824000, -175.94532889014843000, -184.13257496086163000, -201.85285643517994000, -203.28828769155999000, -213.48716376331188000, -215.52262492303180000, -224.74449735570977000, -227.87912577380970000, -229.61972478577974000, -232.012414 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -12.55979142479378100, -41.48396354988349100, -55.45942325609646400, -57.54770048944003200, -59.65178129815543400, -72.3059382468998420 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -8.63605047557682500, -19.82317806149810100, -103.38103960218361000, -23 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.86987000998593800, 80.84881413064648800, 92.84733301846020500, 117.74559109680973000, 171.23228348246482000, 189.26429215595198000, 232.58761420812948000, 245.79156825904920000, 272.27654486483340000, 295.25879720037136000, 299.43066289062210000, 304.27262233001107000, 339.26453 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -23.01345036688261600, -65.27329984836569600, -166.44621254573423000, -198.39530537571812000, -251.93337303406918000, -265.26717601312430000, -304.83160265802127000, -334.13169761489530000, -339.78324874989619000, -346.96858618672422000, -4 [...]
+
+double larslsq4[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 881.55429696805140000, 946.35763024954531000, 935.46630018279382000, 960.80302260366386000, 999.26958508808684000, 811.95150131260903000, 797.29798640506363000, 825.683982433115 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 777.32678015874842000, 718.94798855537749000, 826.98167485386386000, 887.88399091144277000, 1078.29182944255830000, 963.51072078216509000, 1013.06337466524470000, 1040.20432390803690000, 1029.115804 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1172.02810686047950000, -941.29038947090407000, -1007.51668973963320000, -1004.12905824104910000, -1140.20460745702280000, -1136.29513612606710000, -1026.38666013226930000, -1180.70122726735170000, -1257.65564469527910000, -1275.73376002063880000, -1128.86411653057050000, -1275.48882450426550000, -1232.45539525159570000, -1389.09416497009810000, -1592.20765728083640000, -1682.6731937 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -452.92573018573341000, -276.71736181920915000, -40 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1272.98251700663970000, -1236.27886000101350000, -1200.97670856036580000, -1143.05609335567780000, -1175.24240892206600000, -1318.59020415327430000, -1313.77580063684080000, -1317.31905356431590000, -1294.45204274438700000, -1401.27634245620830000, -1154.98794889194210000, -1162.16621447212900000, -11 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-1861.10977847469780000, -1990.34086544951580000, -1917.93321615208010000, -1866.90085972882430000, -1660.00803709132260000, -1666.34056723121720000, -1712.28544830934770000, -1701.59314781569420000, -1675.03514573885200000, -1784.25055822120000000, -1713.69891204046230000, -1619.07939608200720000, -1319.61991772215150000, -1394.26108337225720000, -1370.26288171157810000, -1452.83862602281560000, -1467.17048666414580000, -1472.31809906794620000, -1444.33343869860530000, -1444.57420101621 [...]
+0.00000000000000000, 0.00000000000000000, -1568.31331708503130000, -1433.61655923724420000, -1459.25444037075930000, -1354.58744097976250000, -1259.81407176722970000, -1065.60979614615460000, -1216.99728156683660000, -1477.08649648712840000, -1357.70508760068470000, -1523.75200253123080000, -1535.34986007215340000, -1437.73157854978900000, -1432.78812844906720000, -1428.15390206401820000, -1198.21468049558080000, -1124.68997961346870000, -989.62710035239411000, -1042.54984514141440000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1169.87409004353530000, 1251.31455867536190000, 1266.48732058561680000, 1208.6973733701452000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 978.01076721761399000, 866.68661702555221000, 840.34255306502439000, 811.40459589214606000, 841.05516532578292000, 928.01931715608566000, 964.36350253860996000, 942.08338219819814000, 900.65620884618932000, 889.32230881 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1157.64814462019650000, -1155.87146812667990000, -1268.54324413405200000, -1411.59278742838180000, -1637.13407166174850000, -1541.66923556261280000, -1509. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1040.67243861405950000, -1110.69931645272320000, -1111.79333808552340000, -966.59171247133293000, -989.10676304405865000, -914.94008070963491000, -808.68073599934996000, -844.93910369244725000, -1020.12712452586240000, -935.59628104088983000, -779.78138801710008000, -807.83540376934570000, -888.80186286035348000, -818.316 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1015.3308 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1281.28083393865610000, -1232.60858531997500000, -1094.10564211939160000, -1084.86587587127470000, -1065.33983444120460000, -1032.73193675376640000, -1129.72138614472010000, -1018.67585831903760000, -875.29618219497877000, -709.34664986212761000, -674.68920354 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1108.93496498802120000, 1282.52921926390900000, 1453.96282458196110000, 1483.35580072943480000, 1335.1735173134675 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1177.08099635445770000, 1247.17905985696190000, 1032.92887463020930000, 1025.99949215921080000, 997.78431195563212000, 1192.34952180190770000, 1038.29514670054800000, 991.47133342480583000, 960.56493353219173000, 980.32987506159134000, 1036.17620725904660000, 1087.47607361682410000, 836.67701578476567000, 905.68240468934118000, 681.25195791588635000, 742.385659884 [...]
+0.00000000000000000, 2245.72385253478890000, 2045.06078983050270000, 2016.93594200220580000, 2024.42519437362530000, 1877.97534135786830000, 1922.84523554639300000, 1772.47300056420910000, 1756.88304548371590000, 1648.59938304735240000, 1643.73866572241900000, 1496.96605016937220000, 1710.35421396732450000, 1667.21341635688440000, 1649.78483315702760000, 1673.34153940318790000, 1583.37428351042350000, 1620.94806870190250000, 1681.70330522891600000, 1946.02610311008330000, 2096.8535632207 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -999.80991452646560000, -898.11208249939625000, -866.11738793273435000, -779.14752957440930000, -819.40230633241742000, -751.01588954290685000, -663.36019977570095000, -727.46453928088931000, -996.63016594490739000, -1000.68548571359070000, -1002.71466505130830000, -1029.80810372974290000, -1008.99353792797490000, -968.60072234237884000, -1130.02596760518990000, -1169.18656726532140000, -1214.074686117071 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 891.17021483388419000, 711.318 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1460.78655382985220000, 1301.39612509753170000, 1314.22210496634260000, 1277.02365111619610000, 1188.98742429523370000, 992.34393082410554000, 983.74773302554411000, 1003.73197511201420000, 1287.36607058956450000, 1458.57140125350200000, 1543.87910864404220000, 1484.31787486790860000, 1398.69681704766780000, 1417.70066633724700000, 1466.98030975049410000, 1301.64069665724580000, 1304.09118548166200000, 1164.27726321758040000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -761.97418056414745000, -724.83748873527577000, -624.56183033918467000, -654.20173742281668000, -567.17659821006112000, -460.89792854284559000, -408.57704121422046000, -393.33671470272839000, -255.72463271724132000, -361.54517043300081000, -307.77726001358582000, -377.97259302655095000, -297.76931253685274000, -421.75524888480669000, -441.1752 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -581.81603548265616000, -522.08005137671375000, -367.05855357938259000, -288.06158561362076000, -243.58511631566927000, -222.2377755920 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -961.92401218282134000, -997.77311117324223000, -1093.41014673076480000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 579.55451748450992000, 714.05796182332801000, 717.66198923254501000, 800.30431679866581000, 749.20494372592964000, 847.97408693465547000, 861.51620008637292000, 844.24364724033478000, 712.34363089506201000, 807.67484584314514000, 759.94086389310428000, 727.54426856021462000, 753.86 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1221.42312190457780000, -1223.78121311943890000, -1259.71212389905460000, -1365.49658413384100000, -1029.15034504898490000, -869.60448912173786000, -962.22323275952135000, -987.41139637806623000, -963.62810435900894000, -975.09231247500998 [...]
+
+double lasso4[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 23.48930515004130700, 82.96362004358508100, 101.36678392810015000, 150.15479816788212000, 186.60349488428659000, 192.21780212676961000, 199.06125132122159000, 247.83164154810200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 65.84214518381242000, 83.24436590123436000, 131.17456971005649000, 147.50982332949570000, 200.34795572935550000, 233.10711691362130000, 240.10948043233634000, 249.15854294394333000, 309.863043602288 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -65.11297316171963700, -97.25175461530777500, -118.81446286214522000, -145.43097642450300000, -258.45246315097489000, -324.90150770296600000, -363.60732860612370000, -379.00260772332371000, -409.92594380936640000, -483.26272493071156000, -500.46498705425489000, -550.41145341881975000, -565.13488682308719000, -611.90896404513478000, -653.98879861123976000, -663.22421663563762000, -674. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -5.12258425233860400, -26.26095448352293400, -70.18 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -144.63026779224444000, -227.26353246706054000, -280.99006919331100000, -297.23269085672047000, -328.13338596171315000, -412.02834916926849000, -436.05570758456241000, -492.84878663761873000, -510.15317339929419000, -560.73997426348330000, -586.24837964661288000, -591.41890811699761000, -598.0788359657 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-88.18990148529790900, -215.00309478270037000, -387.42784309864015000, -403.02176255083469000, -436.03527925289472000, -504.38588853260080000, -548.69246303103705000, -576.00282086679749000, -609.04464456779158000, -742.56599598619073000, -816.07672449303595000, -860.38397388191345000, -869.03667040511027000, -887.52143100953526000, -928.41122600267431000, -942.38476713392731000, -976.20462017917066000, -986.91433156191499000, -1012.88085346111280000, -1031.41151638431530000, -1036.01022 [...]
+0.00000000000000000, 0.00000000000000000, -158.79455391949560000, -172.23141383066169000, -206.03381648470020000, -269.84264571736423000, -306.15546857136746000, -324.14571675120817000, -350.98882530056704000, -478.93072989711357000, -545.45029911364543000, -599.43001684623346000, -617.06415564153860000, -645.94674463356682000, -712.59480816642451000, -731.66111635328912000, -761.72819400005096000, -769.56353033397227000, -782.05598073874171000, -793.23781622948252000, -795.3467796498896 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 50.21745771150207800, 61.00077849216833700, 74.63481596317207300, 162.89952568458790000, 288. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.42013443061030400, 104.91585383377556000, 124.51154092093920000, 168.77841273620180000, 183.29099966629258000, 225.56733631978673000, 257.28054849387036000, 263.42863479048793000, 270.63567055477336000, 318.788390330 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -74.60471707233510600, -97.94626154616705100, -164.39808157129741000, -217.93456719177703000, -230.67598792802008000, -245.50330489784929000, -343.869649003 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -31.28726468638891900, -153.92496946197357000, -226.43162681766498000, -267.27141311358946000, -280.87187776893597000, -303.18728933182138000, -346.00425351534284000, -359.29853724364835000, -401.88568258363006000, -413.40701130098694000, -434.20515490249807000, -450.24342892009827000, -454.18075944104396000, -458.29912640 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 116.36176 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -70.69718626735476600, -92.58934618579260700, -127.83673475857204000, -208.90026333199026000, -231.72037832382262000, -283.34162521654071000, -301.61261228998251000, -342.31847304354130000, -365.19682020779857000, -368.28656041847449000, -371.75197041825919000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 62.95142376844949400, 115.30243905497581000, 127.32078823084498000, 142.65752698886723000, 235.47169939644337000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.17612870503193500, 71.69701634003712300, 100.59594213014097000, 205.73592753333398000, 265.69070075646613000, 316.82092103483603000, 330.41458156539221000, 353.67982876711426000, 405.08500120910185000, 420.41259070006186000, 460.09552079441505000, 473.63892353147514000, 494.24767473067033000, 511.90872588872605000, 513.42907123925465000, 516.01856734711089000,  [...]
+0.00000000000000000, 149.71861771190038000, 341.62543344039500000, 359.28351630792338000, 403.01683600563786000, 484.95935343460138000, 537.70198210797435000, 566.95171610875252000, 602.72637014913687000, 721.55352756198408000, 791.35911256861039000, 830.29236106320786000, 846.87405123132464000, 875.74509454986980000, 941.30881645972670000, 960.81406992871166000, 1000.93500720192280000, 1014.31936627450740000, 1052.20505883884080000, 1090.57279505451450000, 1099.60707572161780000, 1110.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -26.25903081095378900, -74.69553504089100200, -103.72542498581643000, -119.72508532944987000, -140.76050973034083000, -210.09484686757972000, -244.40515161408899000, -271.05890198909003000, -284.72975688877978000, -309.92712000434585000, -368.60851280700149000, -386.22639409880998000, -426.36066700654590000, -438.06612299580365000, -477.34692735679374000, -507.04450605857909000, -513.39214708365921000, -5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 69.36026571985375700, 142.9317 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 15.39696067533322900, 49.17247259093291200, 119.45333213597534000, 161.91379597168952000, 186.24351377251475000, 210.47849509448565000, 298.33369770988054000, 351.72941770049681000, 403.35500748203395000, 423.23687288058153000, 462.67678264081360000, 549.21315683652517000, 571.84792928707179000, 626.35896912741305000, 644.50564790827161000, 681.80953698471012000, 708.52130249348943000, 712.61303056297254000, 717.8590715174340 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -18.04993943316478400, -39.29913208163101500, -105.79391865328355000, -147.30611292674527000, -170.47329151864824000, -175.94532889014843000, -184.13257496086163000, -201.85285643517994000, -203.28828769155999000, -213.48716376331188000, -215.52262492303180000, -224.74449735570977000, -227.87912577380970000, -229.61972478577974000, -232.012414 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -12.55979142479378100, -41.48396354988349100, -55.45942325609646400, -57.54770048944003200, -59.65178129815543400, -72.3059382468998420 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -8.63605047557682500, -19.82317806149810100, -103.38103960218361000, -23 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.86987000998593800, 80.84881413064648800, 92.84733301846020500, 117.74559109680973000, 171.23228348246482000, 189.26429215595198000, 232.58761420812948000, 245.79156825904920000, 272.27654486483340000, 295.25879720037136000, 299.43066289062210000, 304.27262233001107000, 339.26453 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -23.01345036688261600, -65.27329984836569600, -166.44621254573423000, -198.39530537571812000, -251.93337303406918000, -265.26717601312430000, -304.83160265802127000, -334.13169761489530000, -339.78324874989619000, -346.96858618672422000, -4 [...]
+
+double lassolsq4[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 881.55429696805140000, 946.35763024954531000, 935.46630018279382000, 960.80302260366386000, 999.26958508808684000, 811.95150131260903000, 797.29798640506363000, 825.683982433115 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 777.32678015874842000, 718.94798855537749000, 826.98167485386386000, 887.88399091144277000, 1078.29182944255830000, 963.51072078216509000, 1013.06337466524470000, 1040.20432390803690000, 1029.115804 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1172.02810686047950000, -941.29038947090407000, -1007.51668973963320000, -1004.12905824104910000, -1140.20460745702280000, -1136.29513612606710000, -1026.38666013226930000, -1180.70122726735170000, -1257.65564469527910000, -1275.73376002063880000, -1128.86411653057050000, -1275.48882450426550000, -1232.45539525159570000, -1389.09416497009810000, -1592.20765728083640000, -1682.6731937 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -452.92573018573341000, -276.71736181920915000, -40 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1272.98251700663970000, -1236.27886000101350000, -1200.97670856036580000, -1143.05609335567780000, -1175.24240892206600000, -1318.59020415327430000, -1313.77580063684080000, -1317.31905356431590000, -1294.45204274438700000, -1401.27634245620830000, -1154.98794889194210000, -1162.16621447212900000, -11 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-1861.10977847469780000, -1990.34086544951580000, -1917.93321615208010000, -1866.90085972882430000, -1660.00803709132260000, -1666.34056723121720000, -1712.28544830934770000, -1701.59314781569420000, -1675.03514573885200000, -1784.25055822120000000, -1713.69891204046230000, -1619.07939608200720000, -1319.61991772215150000, -1394.26108337225720000, -1370.26288171157810000, -1452.83862602281560000, -1467.17048666414580000, -1472.31809906794620000, -1444.33343869860530000, -1444.57420101621 [...]
+0.00000000000000000, 0.00000000000000000, -1568.31331708503130000, -1433.61655923724420000, -1459.25444037075930000, -1354.58744097976250000, -1259.81407176722970000, -1065.60979614615460000, -1216.99728156683660000, -1477.08649648712840000, -1357.70508760068470000, -1523.75200253123080000, -1535.34986007215340000, -1437.73157854978900000, -1432.78812844906720000, -1428.15390206401820000, -1198.21468049558080000, -1124.68997961346870000, -989.62710035239411000, -1042.54984514141440000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1169.87409004353530000, 1251.31455867536190000, 1266.48732058561680000, 1208.6973733701452000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 978.01076721761399000, 866.68661702555221000, 840.34255306502439000, 811.40459589214606000, 841.05516532578292000, 928.01931715608566000, 964.36350253860996000, 942.08338219819814000, 900.65620884618932000, 889.32230881 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1157.64814462019650000, -1155.87146812667990000, -1268.54324413405200000, -1411.59278742838180000, -1637.13407166174850000, -1541.66923556261280000, -1509. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1040.67243861405950000, -1110.69931645272320000, -1111.79333808552340000, -966.59171247133293000, -989.10676304405865000, -914.94008070963491000, -808.68073599934996000, -844.93910369244725000, -1020.12712452586240000, -935.59628104088983000, -779.78138801710008000, -807.83540376934570000, -888.80186286035348000, -818.316 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1015.3308 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1281.28083393865610000, -1232.60858531997500000, -1094.10564211939160000, -1084.86587587127470000, -1065.33983444120460000, -1032.73193675376640000, -1129.72138614472010000, -1018.67585831903760000, -875.29618219497877000, -709.34664986212761000, -674.68920354 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1108.93496498802120000, 1282.52921926390900000, 1453.96282458196110000, 1483.35580072943480000, 1335.1735173134675 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1177.08099635445770000, 1247.17905985696190000, 1032.92887463020930000, 1025.99949215921080000, 997.78431195563212000, 1192.34952180190770000, 1038.29514670054800000, 991.47133342480583000, 960.56493353219173000, 980.32987506159134000, 1036.17620725904660000, 1087.47607361682410000, 836.67701578476567000, 905.68240468934118000, 681.25195791588635000, 742.385659884 [...]
+0.00000000000000000, 2245.72385253478890000, 2045.06078983050270000, 2016.93594200220580000, 2024.42519437362530000, 1877.97534135786830000, 1922.84523554639300000, 1772.47300056420910000, 1756.88304548371590000, 1648.59938304735240000, 1643.73866572241900000, 1496.96605016937220000, 1710.35421396732450000, 1667.21341635688440000, 1649.78483315702760000, 1673.34153940318790000, 1583.37428351042350000, 1620.94806870190250000, 1681.70330522891600000, 1946.02610311008330000, 2096.8535632207 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -999.80991452646560000, -898.11208249939625000, -866.11738793273435000, -779.14752957440930000, -819.40230633241742000, -751.01588954290685000, -663.36019977570095000, -727.46453928088931000, -996.63016594490739000, -1000.68548571359070000, -1002.71466505130830000, -1029.80810372974290000, -1008.99353792797490000, -968.60072234237884000, -1130.02596760518990000, -1169.18656726532140000, -1214.074686117071 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 891.17021483388419000, 711.318 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1460.78655382985220000, 1301.39612509753170000, 1314.22210496634260000, 1277.02365111619610000, 1188.98742429523370000, 992.34393082410554000, 983.74773302554411000, 1003.73197511201420000, 1287.36607058956450000, 1458.57140125350200000, 1543.87910864404220000, 1484.31787486790860000, 1398.69681704766780000, 1417.70066633724700000, 1466.98030975049410000, 1301.64069665724580000, 1304.09118548166200000, 1164.27726321758040000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -761.97418056414745000, -724.83748873527577000, -624.56183033918467000, -654.20173742281668000, -567.17659821006112000, -460.89792854284559000, -408.57704121422046000, -393.33671470272839000, -255.72463271724132000, -361.54517043300081000, -307.77726001358582000, -377.97259302655095000, -297.76931253685274000, -421.75524888480669000, -441.1752 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -581.81603548265616000, -522.08005137671375000, -367.05855357938259000, -288.06158561362076000, -243.58511631566927000, -222.2377755920 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -961.92401218282134000, -997.77311117324223000, -1093.41014673076480000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 579.55451748450992000, 714.05796182332801000, 717.66198923254501000, 800.30431679866581000, 749.20494372592964000, 847.97408693465547000, 861.51620008637292000, 844.24364724033478000, 712.34363089506201000, 807.67484584314514000, 759.94086389310428000, 727.54426856021462000, 753.86 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1221.42312190457780000, -1223.78121311943890000, -1259.71212389905460000, -1365.49658413384100000, -1029.15034504898490000, -869.60448912173786000, -962.22323275952135000, -987.41139637806623000, -963.62810435900894000, -975.09231247500998 [...]
+
+double nnlasso4[1200] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.31412848185012600, 36.75892794447133800, 98.65667469184640500, 266.88040720631335000, 334.52860725051073000, 378.84752984211087000, 400.05563185747934000, 420.25844625654622000, 431.95969647159376000, 482.68204520682610000, 529.52193462195498000, 530.55527456890434000, 545.96525558765086000, 583.32238390372970000, 614.40189135908327000, 697 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 63.11165434247925500, 84.41465803834530800, 85.98882935801599100, 117.64729181352286000, 199.60508793122955000, 237.16787216726780000, 266.92545268971935000, 282.99685806299323000, 300.44146792447896000, 309.40662097575751000, 340.68796719391008000, 371.05910864780913000, 371.98507208151540000, 384.13311685960076000, 398.19294802909405000, 409.09927788156324000, 4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 15.91794228245526300, 35.30526304145360700, 52.29694290926573800, 93.38799604461264900, 141.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.84966632974732200, 61.06969897712726700, 161.50919325669011000, 249.83052908816029000, 252.13691341719959000, 280.52543092455193000, 326.10051162822418000, 365.05239838034663000, 424.349494816120 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 75.41801757701604500, 77.12303052857065200, 100.54396788099096000, 138.03300972292246000, 172.38779186129253000, 228.33136636451286000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 52.78322026801351500, 82.99613577830490400, 119.13982514347938000, 138.70989929832876000, 225.29485624287142000, 302.53741712163355000, 304.52846888810114000, 329.56515490067329000, 394.41482694783042000, 456.30041774056087000, 558.20158036 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 153.70798766409030000, 202.67395595259791000, 237.41636380998182000, 257.34209507801756000, 277.81918493563080000, 288.90908990374169000, 333.15817217811787000, 372.43050192208335000, 373.58735795048113000, 389.44973181111891000, 425.29612764676574000, 466.46668002876226000, 580.16 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 156.41707316146520000, 357.984 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 112.83663013114050000, 391.76004355713366000, 509.36575171894231000, 582.89493646934568000, 619.33616886024174000, 654.31994114873874000, 673.84022952313421000, 765.31029338388703000, 838.37896993286176000, 840.38915362076193000, 866.58535973283972000, 912.28062647291245000, 963.42480011755697000, 1046 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 18.39658091997749500, 111.76531944814114000, 145.14019964941704000, 147.48601857084009000, 202.08520733697645000, 366.21123260101962000, 432.20958294149932000, 478.85156534242253000, 506.44803922519861000, 539.70054752856367000, 560.27068381691777000, 649.63862958782295000, 713.19242660789905000, 714.91178350362270000, 735.57523435275698000, 782.23949170144624000, 834.4043092284217700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 52.732236 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 26.04465843221797500, 61.30120510680563900, 79.16568552010313900, 152.59314511874197000, 204.47250071065781000, 205.97411883091121000, 224.31897833346252000, 264.12205987064846000, 306.84633386745713000, 375.81655184040 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 50.90768484044180300, 91.42144900826645000, 92.43199474094400600, 102.21097149601198000, 113.91069245520734000, 117.55711577280265000, 77.92374912121069000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 50.33713216787105400, 94.85156292166261900, 120.86770979310730000, 158.80681740973529000, 178.78386672095658000, 272.54350730280339000, 345.88311503522897000, 347.74022392320751000, 373.68870760726981000, 426.49193960473360000, 476.19723133478482000, 508.187320 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.96896861545670010, 22.96049546239169100, 106.69172110729305000, 137.41756239550051000, 139.48460977738242000, 206.89399985369576000, 380.23603415907286000, 447.02518439762548000, 486.71013017860889000, 504.09134728815599000, 516.73635857345346000, 521.88635863218542000, 544.87525845343305000, 568.94035627699861000, 569.36887148601170000, 579.78062222934705000, 582.17264334152435000, 585.1861696951010600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 18.66628794557938400, 435.44036423119417000, 443.52631216089560000, 461.30573189978685000, 557.61024448003252000, 594.04448933245635000, 596.39958259133073000, 672.71426878000545000, 883.65411480987882000, 956.37523106601634000, 1007.83061580724380000, 1039.65023617731550000, 1068.55552691822660000, 1082.55182811085360000, 1150.80776674497320000, 1209.39844640817500000, 1210.98625942596480000, 1231.73477193644930000, 1269.58691790108670000, 1305. [...]
+293.16394331504353000, 456.62239553903066000, 476.73659201323829000, 951.74300919732707000, 960.45286865078538000, 979.05871391600863000, 1082.86551873917050000, 1119.37911471432400000, 1121.77370673058820000, 1204.12339843203610000, 1424.40559121494450000, 1515.68255359470120000, 1578.51801897070500000, 1612.12548967380050000, 1661.58785350688340000, 1688.56545539621740000, 1811.58557043138030000, 1915.98683135278470000, 1918.45736231600630000, 1947.52192467165470000, 2013.3553067018543 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 17.45539653548388500, 97.18685171537137500, 159.26441587546293000, 160.99439479645071000, 181.65875554229265000, 226.35398696976208000, 270.75265511272232000, 323.89240487122544 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 3.95270564000714940, 99.73850582422650700, 404.86293722394453000, 512.06354801481427000, 582.04417623764959000, 622.63277530281880000, 670.71093886675567000, 694.77529329791514000, 791.55650726135173000, 893.16974864016527000, 895.85313695948594000, 930.65046128634503000, 1001.61247067360830000, 1065.71501244484720000, 119 [...]
+0.00000000000000000, 158.60293131054459000, 177.30091401328096000, 621.06812209995917000, 628.97069071418355000, 648.92904118511592000, 754.36205113111293000, 789.43683847828788000, 792.85879182061490000, 879.32613127297611000, 1064.72697964013220000, 1131.51027339872940000, 1180.80659443672700000, 1211.24860940044800000, 1247.67671887017560000, 1271.96074263643300000, 1386.24754920850890000, 1495.23410593175530000, 1498.11477388336080000, 1533.87185234947380000, 1602.50523214422790000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.48246681310938590, 20.98183242719804300, 52.18383221287378900, 76.07702507813070300, 99.78155741501490200, 136.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 71.51302867239886000, 216.69458039590458000, 386.07 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 72.85170036705703500, 151.15311662362322000, 297.03556261819807000, 478. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 393.17558426349080000, 399.92187234917992000, 417.60699454308570000, 513.74738674944422000, 553.80665218382705000, 556.63447937093565000, 635.51619882351224000, 830.42260434325181000, 904.65592138669706000, 949.23748698750296000, 973.07972203306633000, 1001.24882108651960000, 1020.40277519192220000, 1107.80161707573070000, 1187.75803756416210000, 1189.89261933743160000, 1215.06907276807440000, 1265.30397699594980000, 1314.988 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlassolsq4[1200] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 753.29130207316314000, 758.30036878367275000, 787.20757492368159000, 795.75091630562565000, 808.24140325859992000, 790.22525088297493000, 736.96960804901971000, 681.19507837579476000, 693.37021221306270000, 684.03286550670839000, 698.72614946845272000, 671.13956240074504000, 691.85675338382339000, 737.15949473797991000, 719.86378812711860000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 578.74147072406583000, 530.77229741013969000, 550.57901742405170000, 469.81621506466558000, 457.26826487745262000, 500.20475318814817000, 543.14168140589970000, 538.30877062226136000, 525.75352870847382000, 509.69165375132616000, 464.86448658159799000, 480.77168926801596000, 497.96095278778500000, 499.14276195999491000, 456.09150456779992000, 446.10765823223448000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 166.61848101740392000, 115.14248680090127000, 109.95470311376447000, 145.92441613200526000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 526.71048858121310000, 579.81432868169315000, 560.22051219148864000, 568.88214236397755000, 565.91690355667060000, 549.28911949250869000, 513.77925080135969000, 497.22759020002678000, 500.1630096961 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 347.85773954776545000, 309.08738286586151000, 322.27789642887149000, 292.41334206835052000, 288.96365756861832000, 299.8572803295484200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 542.72836318466034000, 562.96145702841136000, 585.96649537951009000, 575.91302579323201000, 569.00827924340808000, 581.56811145974427000, 575.40795579028543000, 566.59592202382146000, 661.46656877000316000, 666.29640294037119000, 688.485958 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 636.94314404458100000, 545.56269108579534000, 559.90282629794046000, 573.88420455925689000, 542.29831925345150000, 536.66191323108671000, 508.81228196649050000, 514.29769679582159000, 530.97581598542013000, 539.62418551849589000, 572.91202366849780000, 606.17045594703814000, 725.53 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 356.40204403538775000, 357.984 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1368.03196984224540000, 1268.65396008961220000, 1332.91063249098330000, 1265.40856008226770000, 1198.24513927352270000, 1106.16528999324010000, 1109.93112217072580000, 1128.41596278779840000, 1102.33194248938180000, 1113.87150858915060000, 1114.59369547439560000, 1100.45429321237590000, 1136.9720022071 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 969.92182514810463000, 874.59915742365399000, 844.43748906634494000, 839.81501748869414000, 809.44690549839424000, 882.19915678036409000, 894.36915335555068000, 911.79242452649714000, 944.84831370400752000, 969.18514085325342000, 1019.81559031724420000, 1004.39959074552420000, 942.77388932207748000, 948.82760706939359000, 931.20310633718429000, 974.40347360630017000, 1011.414855771225 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 52.732236 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 439.79264137715285000, 516.66966851489951000, 478.26517937486932000, 444.07568864009073000, 391.88126147594460000, 410.26692165386333000, 397.99596251869474000, 428.03163595402430000, 451.82234354886407000, 463.99750775 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 252.99422771125430000, 237.77319624955697000, 229.91516527875706000, 194.79184904383365000, 162.09028631212760000, 129.93050103462571000, 27.251034722110326 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 402.82756955854472000, 508.04403255080643000, 534.16275530400878000, 648.82285040115300000, 625.07897771033129000, 644.73803324485039000, 610.81479823230893000, 600.39699115010933000, 619.35177141001429000, 643.93629411910911000, 644.86188449217514000, 549.0878 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 975.41777868582062000, 798.36633345110613000, 790.78591820118652000, 781.21006137432255000, 749.53887762595730000, 956.75645301468762000, 925.19772631217802000, 914.72240445430236000, 855.07428707500037000, 780.21105678325432000, 680.05749753554971000, 636.93937832493907000, 636.13352925950801000, 655.87301203867901000, 627.66769721328546000, 678.35218495727861000, 592.02301550713639000, 595.4119496777860 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 1467.81702822421720000, 1373.47314933166350000, 1425.17664614608160000, 1380.90958561977230000, 1344.42971001013830000, 1357.44404353605820000, 1291.46574621727290000, 1521.63928846741960000, 1546.81776057879980000, 1465.61159342328940000, 1485.45050528846850000, 1545.13982746736090000, 1441.89208623985130000, 1395.23468216456010000, 1421.76109554404020000, 1421.05116535188560000, 1427.00574359966840000, 1428.16795141374860000, 1425.4625174602172 [...]
+2086.07682176890280000, 2038.80739554412090000, 2038.29520482843240000, 2020.83923615755790000, 2017.84731588006500000, 1941.40772523892000000, 1930.97961537914630000, 1884.44129735891260000, 1828.49726424674900000, 2120.18185507126330000, 2116.94019201861370000, 2154.85794971447560000, 2161.77025154690590000, 2146.01704565158480000, 2300.43659904887500000, 2291.25565462722170000, 2299.93442834833010000, 2293.12549678876480000, 2254.56924597670060000, 2222.68595827412400000, 2284.4579782 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 407.41579623232360000, 413.69415676889975000, 383.51314136239233000, 396.35532832965691000, 377.29524182633310000, 410.40949607351382000, 421.41037589730877000, 391.833525957998 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1170.52729235321070000, 1165.26031254601710000, 1364.12897514240190000, 1262.74576924671190000, 1231.61933898707800000, 1267.42721702989750000, 1291.68155370502810000, 1232.38240255750630000, 1175.74567253201460000, 1260.23698428475790000, 1260.92393187230250000, 1260.08848974133550000, 1293.83489234275230000, 1283.2337634 [...]
+0.00000000000000000, 1693.78924601098740000, 1628.91226568562270000, 1619.85430824589930000, 1588.35840714989170000, 1681.23359760525550000, 1615.76243946510730000, 1524.35194741153210000, 1802.79076491583420000, 1841.18932580193840000, 1647.59979786719050000, 1599.16648291125810000, 1638.38559271666080000, 1694.85342690261700000, 1718.17691808702670000, 1814.47535093460150000, 1839.92808306669690000, 1888.93667417957770000, 1890.02515502368350000, 1872.39619757029980000, 1885.1383287002 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 203.16976417404840000, 205.58891611236609000, 180.67404855568810000, 157.15364583971331000, 130.08867231722380000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 314.17773815185865000, 402.31452460036490000, 386.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 372.85589257919787000, 416.85281890827127000, 483.55162588148261000, 478 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1278.09527895064410000, 1218.93480813016960000, 1332.33350203701870000, 1299.22596906022110000, 1393.16054844818700000, 1391.22011071879910000, 1512.99691169307950000, 1443.17948693754900000, 1424.48161003222620000, 1363.05311662939490000, 1351.83979234360570000, 1365.07683492904150000, 1448.30961669700510000, 1454.74589204265320000, 1476.59226667128110000, 1480.29913976650960000, 1453.42306526967200000, 1472.1719263753828000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+
+
+// Data from file x43.txt and y43.txt
+double x5[5000] = {
+24453.1115306975, -10522.5538679446, -1805.7929467378, 2818.90288090206, 2070.85866380461, -9869.75613020128, 3030.14630713608, 9916.34459104185, 5340.11132251115, -10165.8335051025, -10262.0925928979, -4942.4870047215, 4751.4889673589, 10573.1133638229, -17.4515898631199, 7211.21928538814, 7744.98665396361, 5624.83077079502, 2764.63710543784, 14531.7279689806, 9752.39338554282, -3378.37402633849, -6544.57611113803, -4943.56689923524, 17671.5452101061, 5851.37259080152, 39.3766581595515, [...]
+5127.18122242948, 12504.0094949101, 19342.8043284775, 6246.19507786037, -1950.57962566795, -14074.8603520582, -505.949473880245, 6073.21871766825, -1671.26297665267, -8630.6452230862, 6895.82494438794, -12459.7546077922, -1955.34242276273, 8538.34233242067, -13370.9503503977, 247.273264880506, -6889.32382201447, 1026.35819666208, -3834.68403270979, -1723.95845903408, -3920.22635780772, 6939.22338621425, -4639.83630123463, 5782.85450319724, -18022.1361794180, 8885.06291971005, -6793.55934 [...]
+5640.49441525264, 4156.83556314842, 7867.92308578377, 6827.49194160593, 11064.1012578913, 24335.2601872766, -7120.2265109716, 2952.44409695825, 8845.61576421039, 513.471795358053, -2925.25345579513, -8008.5903832683, 3686.34032527818, 13349.3305955975, 14519.1638054492, -1581.05633337559, -3822.11808687179, 5975.01534472988, 1302.88141212554, -13983.9761049926, 7601.10459941801, -6438.11098385948, -19402.3442225589, -5793.94092567925, -1892.16960506472, -1407.53782403743, -19271.00543518 [...]
+4486.26307848176, -1439.26866049148, -5545.32710420329, -3717.62408412493, 3659.30318111437, 12193.4954870460, -7138.81426166202, 11925.2943092950, -15590.8405783925, 15485.6397142034, -9684.19904765115, -11208.2622809491, 5605.45392134529, 3835.20171504248, 2407.45655638783, -9896.2791765919, 10011.0609288912, -9822.15757979244, 13151.7848937224, 12466.5994538016, -208.603408774184, -6681.87828594069, 7252.26559950074, 3643.05817742052, 9060.05284462836, -12674.8221221623, 10422.7243774 [...]
+2705.28402776094, 5496.45517080339, 1794.06400450692, 1618.19559697341, -7543.73841419422, -5130.74377815388, 11305.5952394581, -14124.4861632902, 8385.3720613238, -20269.5497036930, 10765.8414048277, 10422.1706097111, 494.512607805879, -4159.48897314544, 21666.9780845307, 18791.8041907010, -5728.76066129077, 14835.8996638222, 911.904937876678, 8249.8125200265, -19229.1183318233, -6323.29061093334, 5434.53813177903, 942.357386775046, 1865.32108667070, -6.12372426133112, 3788.59106048271, [...]
+-13831.7916520566, -6462.05122538655, 11514.8870144504, 8223.69591152652, 16332.9465144674, -7097.0260802616, 12889.2931458438, 1300.85616848886, -9866.7803271685, 8243.10642535606, 6937.56693733234, 17733.8739008247, -2163.95472087746, -22664.327454174, -11532.3565170989, -2001.00297253307, 8250.78288502213, -11165.6671168884, -4176.55110339814, 15098.2944491532, -3512.56123801357, -1966.46579344298, -1874.30918134659, -4627.96504071304, -7069.52073590908, -2603.60794891433, -20958.2523 [...]
+-4520.58052067585, 11394.8236200430, 1295.29861283845, 19923.8605006944, 2175.16874640103, 8313.20281600926, 654.647550280377, 2403.73344384554, 8044.80365225665, 6655.66188964402, 5525.96224598052, 955.095542051321, 1352.87632349827, 1314.39559251322, 1111.91535850903, -14691.874123256, 2358.17154588762, 10651.3990693738, -4529.62464233472, 11549.6275689000, -15571.7184945964, -2050.72532465232, -10029.2658635193, -581.37132952967, -5683.16458517598, 2822.26152932181, 16098.8375584860,  [...]
+5372.62016966396, 8047.19547157195, -9630.93765051203, -686.477578007881, 5872.35176941177, -3179.18834274434, -3771.81602156872, 8815.74574687447, -4527.81261443564, 295.203505574608, 3587.09651673725, 2793.27099069911, -741.761747068364, -14902.9022425475, -7428.82940474421, -4458.10391689825, 5893.84140177586, -10034.9387886689, 2673.4788952885, -6774.15851792206, -21539.9522321833, -9276.79297591817, 1593.04353302351, -11180.4827780878, 8244.24650259962, -7068.35663409598, 7569.25416 [...]
+-14002.9414754296, 8417.63575970112, 4350.04116646827, -13444.1498011066, 20711.7402708721, -9525.45449683367, -18416.3283085747, 6393.61395346091, -6963.20561366264, 10231.8150241848, -12476.4350452447, -10756.6687193805, 11044.6555419249, -1997.50478294187, 14873.1227579815, 6976.00813280208, -793.384545787969, -8362.50615879488, -5.38052328285391, 17949.3950736143, -10081.6561320098, 6044.73257548663, 8882.5604716381, 7778.20435880758, -16482.3910280416, -2782.19328153912, 28043.82873 [...]
+6862.81910176359, 18900.9646522585, 18808.4112862683, 12337.7686562078, 13228.8250025190, 33108.0057379309, 15421.9481555522, 23605.2433580617, 6379.45985970159, -976.11615914738, -10259.6967362340, 13391.3128632104, -5226.24104969523, -13765.8316879276, 1655.13196724367, -18046.6837374928, -161.784614522656, -5749.48986695171, -11843.6328006118, 16154.7658223227, 3779.07016891448, 15067.6633286763, -13532.5845020061, -16437.5170011254, 13076.1632350872, -3999.50169555001, 10557.66781115 [...]
+-6861.37727306113, -584.326381500088, -2888.31628211643, 6335.81727333421, 2109.65744152866, -1732.37085521198, -15880.296974625, -1798.31497194003, 7813.88535258401, 456.483437958903, -5409.64627218474, -3960.73087407335, -6755.52061083449, -3277.55705281583, 1492.06174577717, -13982.356601391, -11399.2571261842, 11052.1008068995, -1991.13921459845, 15018.8595758357, 15024.8180774549, 9218.71927322494, -13989.7082665656, 1515.92883702831, 77.3530532245629, 20227.0902765992, 1059.8641981 [...]
+-23951.3332234783, -950.211983971611, 14440.7668224992, 8210.6845161992, -8332.28105394646, 9301.35071563848, 12072.8356841891, -4583.18956484156, 6601.13374087325, -13899.6701403742, 10771.8484877634, 9618.9809136344, -807.326226255724, 8910.7612952535, -14343.0227393672, -8556.53856255617, -258.394990982272, -8077.8274157435, 7863.71545750246, -13933.7379349659, 1458.26865840231, -3300.26661020361, 5409.52982273617, 1006.09410973648, -16493.6199001796, -4627.10584772123, -12406.9272632 [...]
+-1958.04937384374, 1369.08468634636, 11528.4573956213, -10652.2771646132, 12641.7010448431, -7088.47722200102, 3532.32438979744, 5684.02953799749, 12066.7177840059, 2887.23509931752, 2368.96488552461, -284.391689392131, -9313.64711604725, -23375.7105556991, -17598.6517631039, 12193.7140884578, -4553.72952261778, 11264.3296751632, -474.056448511812, 4716.55549983826, -23982.4123231189, -2094.26469783521, -2620.82927865993, 7902.62281608823, -7614.06681849533, 7439.97879595724, -2568.50804 [...]
+-14696.9167549732, -15296.6590329979, -6244.27258694434, 2700.67800784369, 4870.94744926849, -2729.46667747029, 16232.2199557337, 3208.80467043157, -243.920556210675, 2133.88759794193, -13336.7887022478, -2289.11374585899, 9266.81610805615, -27038.7218547687, -7539.7336164607, -22195.1338840255, 10727.4282183489, -4554.12978463814, -9972.37855290353, -16228.7982417463, 4909.30020189514, -12924.9425650359, 5692.66147969076, 6934.03176119457, 5707.91336448995, 13331.5686181136, 4537.143440 [...]
+-6800.4903536284, -4423.64622737476, 17993.7190182922, -12706.0109435851, 12403.0320716831, -2058.78357065443, 4565.11824180540, 12393.4534519339, -838.7124745439, -11441.1376487832, 10085.4025914206, -5820.34746569066, 814.728643131538, -7198.98666341699, -5162.72250096251, -13622.2406317841, 10768.7103482864, 4496.6666880307, 12416.4882161054, -1453.44723488416, 13429.1028101685, 9604.9267395015, 9495.76524345854, -12261.1027808951, 1818.81667237243, 8754.17048028915, 2569.58885897705, [...]
+-4450.51925857178, -3790.65465886885, -12274.6990286897, -12002.1434607850, -5495.11542621253, -9272.0054505167, 16333.7330602424, 3792.44800068173, -507.200609071734, -40.6671954836510, 5622.87136889146, -3380.11949561609, 4196.00865822596, -11212.9041195722, -5657.94825489994, 10612.7209111448, 16652.8210249553, 20436.0781741251, -7688.47653672636, 3936.19254905097, 1175.33007516006, 973.781201600004, 7942.3549879221, 13435.2016812116, 14180.4306462454, -2689.31573523388, -7283.3066879 [...]
+7413.270343073, -1141.65888112189, 4824.86516762777, -5033.88763371523, 14271.3696182176, -4899.1263811563, 992.002684133164, 19539.4797379977, 15283.3134314662, -29997.1648404219, -3489.37644350955, 12375.4852825514, 23951.5976868690, 19707.8976694148, 16210.254522914, 6796.70577091656, -5875.20658128077, 1787.76779705079, 6778.47419716556, 6982.7293786138, -1303.25316857239, -11569.2429122417, 3167.43396198552, 23925.4986239491, -1773.35934649891, -7720.75086906382, -14759.9417469073,  [...]
+-5057.35460862051, 5659.9535453055, 9005.94215359549, 4178.18053784039, -7519.99473193402, 6903.90004969696, 579.863181819225, -7150.78375345534, -9033.98467237955, -2140.84422817546, 11312.6426251062, -11216.2797549883, 30270.4701819939, -5332.63130409879, -10269.3870722095, -17605.0388826333, 8932.30266053487, -4192.69124987813, -3811.12713084981, -3353.90053464586, 1342.58144261928, -6660.49933205658, -15046.2285547242, -3053.23532208065, -12466.4707421914, 575.831739328822, 2255.5610 [...]
+-2644.53599123365, -8228.32471449877, 10436.1462732087, -792.53286833554, 1773.85530333968, -8097.27031670415, 8021.55970373996, -7712.90459518374, -3244.31901877218, -10262.7306316383, 4165.79679866236, -8682.79278784857, -7785.68126359652, 4374.9382621321, -12138.0765357827, -932.5475862721, 6113.79795249548, 4712.48370867525, 16154.3807931872, -5446.00149764843, 7173.10999005516, 12357.2542909948, 10287.9531468570, 546.989902791848, -2875.41882621997, -5102.56123735482, 3178.548919378 [...]
+-26082.8309207069, 20179.3892408376, -13781.0930519852, 13676.0326839421, 24890.0180398705, 18522.3309219827, -1908.97797081016, 2021.68293053247, -13611.7125942825, 950.722495188765, -21961.8671023218, -7347.34079299426, 24747.4094835934, -7611.41475711051, 16933.6607412832, -397.714390162166, -9302.94656321791, -5423.48436557462, -17394.9151305737, 1852.20122001004, 2788.55996435052, 7692.12747987401, -3797.76867449279, -12592.0707681569, -14567.86047812, -10432.6651728919, -6480.28589 [...]
+2963.55677330126, 14874.4513678136, -656.915632982707, 3865.51666753434, -1912.37717433169, -8324.0067734682, 725.869812256448, 19091.6971902555, -1220.39748164157, 4390.69444560465, 21028.7951045353, -3918.94651548978, 5366.73013164938, -3702.78044697316, 1470.40302091540, -14064.6157524442, -8461.66815919643, 13839.5798388626, 8740.0625905012, 2108.03069767090, 25353.7984419044, -659.356970806772, -11963.9243153316, 10543.1217528882, 10036.0921640978, 2125.4140722052, -3695.74811284320 [...]
+-7525.98711477664, -21566.4494146852, -16656.4388005871, 5247.14853345846, 10046.2170053705, 955.731925270122, 5370.60415613482, -6874.21225059927, -13914.2416681832, -2544.02599605357, 2813.86304002795, 13666.6854740102, -787.058795095292, -13574.5221551744, 4019.96173652710, 4354.38611347156, 3566.71966518591, -17909.9260107965, -4579.36788268962, 13725.2968676154, 15374.2809237269, -5837.59733234992, -4.85207183160189, 2512.58977169514, -18984.6280682802, 4818.443597323, 1742.32375395 [...]
+15360.5648601315, 22877.8164399772, 9174.51828535683, 20869.1855115610, 9583.48555435608, 601.493675459448, 1112.10151255277, -268.363187973093, 8639.07819423434, 13821.4902512156, -6808.61961203392, 18841.8579025128, 19394.2980203137, 8979.1166655354, -5254.7285917179, 6511.14854561322, -2708.07863850900, -851.223200453832, 27126.7243848430, 8272.6025189014, -11150.9792600467, 6129.88787212209, -10652.3055067530, 4246.13319841001, 14358.2194591338, 9200.25209051051, 5948.97903126847, -6 [...]
+-7688.07450452784, 10368.4869090094, -26014.0489092956, 13272.5245522657, -5211.6745941522, -485.183779835737, -6211.28579140776, 1216.13565459968, 3072.39526390091, 261.571976721282, -14340.7975738964, 8044.74384069611, 78.006053867172, 1037.47824681062, -11601.8363418020, 3807.25878435238, -790.896800006336, 3532.48824399306, 4205.9716408371, 6503.49709237675, -16552.1962110057, 1520.45723501882, 9520.78734956528, 2447.38749438901, 22533.2527180354, 4599.92684424277, -193.467112871622, [...]
+-9676.60149244033, -1849.01278146117, 2147.1026754321, -3418.99178670151, 19675.0943378009, 23994.9167474866, -8337.52496621794, -7217.65003306299, -4435.02956019909, -4413.76941295697, -10248.7051511378, -519.92442605403, -4620.5143212448, 7948.134506729, 9077.36323053282, -16583.8544740190, 8338.5925047162, 6824.47196391494, 3526.36836506336, -311.477537036669, -14965.1618915923, 7640.72329026422, -12527.8790004111, 2295.38332499481, 8714.81595330052, -2340.72796007221, 10442.210390539 [...]
+-1413.85822334764, 5286.40216318104, 6109.99486674068, -6023.81548677311, -8060.5619244028, 523.86697850504, -9945.4734181051, 19622.9242466575, -2546.93741507145, -8112.36284338687, -2174.53916751, -14985.5920713893, -6968.32869256911, 3095.15932061584, -14338.2050689923, 5267.18414217815, 10246.4762243363, 10432.078755275, 16721.5597738877, -12754.9664041133, -2379.6854189216, 6457.60094187528, 2112.54183755808, 11257.2663022159, -16426.9663916434, -15338.9992444238, 3331.04146332026,  [...]
+-9321.07585875235, 860.757381955848, 2115.39256759501, -1503.56827692680, -6559.63302944533, 5664.75784915767, -2259.24340580639, 8247.6332701332, 9983.60435319129, -14036.6347058375, 3804.44746658998, -9074.85457505727, -5628.66389711501, 3199.46094202825, -2142.53496060517, -19220.7031480239, 4345.58254998343, -1315.74847818302, 2539.14829083189, -10008.1063537872, 23011.6556156786, -10515.3748163479, 8849.40207270867, -5294.66977011956, -4064.94280162634, -8301.27362056573, 2606.54064 [...]
+-5919.62038323108, -7618.63442122744, 5540.80120717828, 6913.03910240678, -5299.63703594553, 22205.9832978433, -14489.1018651762, -17078.1352018608, -9762.44383696014, 6538.63595948025, 3254.77925218472, -7834.40756630957, 15946.6366168385, -17786.1987147545, -3332.69207203308, -6726.54593204647, -2386.32193343213, 14632.2260681547, 21314.789224676, 6966.54912189647, 11321.6502716297, -11843.4061885196, 6746.62325154408, 2976.16882571102, 7736.46657390202, -14247.2001611724, -1999.499568 [...]
+-7546.74309133929, 6340.61049471449, -7896.43599413786, -28096.7232937529, 13008.5976778657, -12784.8907496024, 1255.59114424853, 1830.90424142020, -2734.27318419133, 2217.20539010425, -2179.74601512518, -20586.3578291640, 833.858723730424, 2751.98260944069, 6131.22723165684, 2991.03345466036, -12589.9717035280, -5283.08143539115, -6123.70453090636, 20135.3090778745, -695.801833052548, 5961.22889735046, 7447.92047251158, -4853.03792439058, 7464.93613828608, -1219.36538207543, 11830.57910 [...]
+-64.9484988708211, 4458.526616174, 15805.3190455154, 9169.93830735276, 5514.42752418433, -3964.04461668327, 1950.95099398551, 1581.83400652966, 3275.77145334325, -8082.17656931174, 8517.60400026939, -14016.8118796443, -15752.4603948545, 6432.87980066389, -6462.12783801037, -1539.87184443078, 1659.37479626732, -2978.31796416339, 17011.6155342701, 5913.07676176194, 13662.0057249316, 8479.36591705378, -9153.75598075082, 13405.5217191068, -10041.7204299802, 11701.0094800966, -4792.4529044129 [...]
+1216.88088783917, -5746.11368130098, 7782.3954912734, 33131.5389015064, -7395.29405565419, 2505.88093372356, 7329.89591747963, 1804.18014263398, 5211.17116349732, -2408.87502030629, -8484.74461752558, 648.985466911258, 13715.6427038285, -2996.30051765932, 1287.00957830692, -2312.80506061918, 3523.75458529866, 1474.14161419761, -30670.5199147567, 16480.7488850422, 15950.0078827669, 5822.52553017432, -8669.82242261592, -16724.5450181289, 6162.44885735503, 3304.08133291972, 19239.950770407, [...]
+13263.6698293480, 14091.2208540700, -1599.39184717796, -8562.97714048104, 21146.3307022090, -10827.5184837402, 6435.3740752281, -1342.63358146908, -8692.82772920747, 1055.02964376412, -16691.4605349644, 14287.0463044237, -14942.5769032516, 9307.15764853776, -7707.1913143262, 2318.43825621215, 447.466393393248, 6962.89462348634, -3290.20101561533, -4974.336688459, -2685.2347970981, -1342.54791076422, 13908.4738015279, -7435.05919912152, -2611.83523353436, -5468.22909356319, 1848.250476524 [...]
+-16061.4221729383, 2217.18368622405, -7754.50762383139, 9101.78435862447, -2830.00783430493, 3280.32064977982, 9064.72819135396, 3464.24782950161, -5525.3763788484, -2073.74565900462, 9793.09660312117, 15258.6088219776, -6903.02851539922, 13494.3107270255, 7955.33827525852, 751.40603955554, -22992.3419601323, -4125.33487465867, 4546.15302704177, -7001.23830580262, 11518.7321111128, 379.380981930839, 15313.5986040302, -15854.2823022570, 18532.7467762996, -10710.3084019103, -20356.38061103 [...]
+6855.88811056681, -2503.48547495615, 145.319200259066, 1590.57600137236, -8054.86485949751, -24202.9722829355, -23055.8698939901, -5312.67497060158, 5847.21480765332, 12370.1139336942, -13270.1039738561, 10120.1664776246, -4376.23928199575, -20474.2125038846, 5739.45029013339, 6982.94391693732, -3191.98198316419, -4552.60602236347, -9084.87253421345, -6636.29567625181, -12574.0367206615, -4860.26351131713, -10091.4286713305, -7724.19170062149, -26774.6717427712, 10383.6793919656, 370.856 [...]
+4519.93930311893, 10646.0145310083, 5676.59274426181, -16063.9803087785, 211.034490421402, -10614.4280424177, 14139.3917957523, 5192.54919409353, 14038.8671451362, -6812.14641164714, 48.0198351032464, -3767.39242904272, 11205.7038883041, 5441.20226020182, -12994.2192432621, 2679.16697990691, -1005.54077614834, 31044.7134232093, -10661.2849842979, 4681.35761909329, 3976.05418775545, 10383.9994386204, -5270.57321696979, 965.97365056147, 3077.10725539107, 10303.3149994157, 2453.92379606508, [...]
+3330.10029247904, 9641.27386725964, 3758.93657366353, -3531.24786714642, -8587.65459151129, -3285.73158281894, -20352.4838204991, 918.229543282621, 7382.9348620046, -7642.93082466837, -7019.89474833617, 13942.5176462875, 3695.26153698201, 4039.06205831883, 11792.5493703770, -6638.16809890451, -6621.37421800241, -8841.12113937004, 9433.06465409104, 14471.0805159266, -12816.0417354452, 12140.2207418746, -2609.6518065777, 6483.2708590291, -1322.29292560783, -17657.250382144, -10948.77954122 [...]
+4822.25526832826, -4989.99637645686, 26766.7967897428, 1971.74297104064, -400.55727328711, -7815.56946575436, 24568.6470653556, 12204.4027338539, 2060.94670045801, -10856.3121524704, -3882.6750011891, 4310.66367341472, 7044.91364142358, -10657.7858390026, -1532.83908735798, -13000.8242457216, 6526.06901208399, 16873.423695202, 14066.3841365340, -6949.77786210345, 7684.14813892972, 6087.68491479368, 9630.15664672109, 646.433527093584, 7565.66840421182, -11925.9287009435, -7335.38765590688 [...]
+13772.7689669513, 12063.3045372500, 3035.14242009093, -5282.52109103355, 5981.0831374009, 17380.3013988547, 9187.51627146634, -183.963305706082, -19132.9223031442, 2499.78673662581, 4191.77972537762, 8819.58730306742, 589.509140906411, 2832.81366922849, 7100.40183556312, 433.212285821204, 460.215487432991, 13181.4795494103, 435.955970509702, 11888.1845486544, -7843.02044140581, 7556.02053125318, 22197.6073783611, -7353.38666346018, -351.848813841102, -572.989231035512, -5741.1812134794,  [...]
+10591.7198545168, 6398.81109239794, 17187.9938192405, 5699.54848602061, 8216.23770512377, 5725.43469793499, 3186.56575393084, -4942.01286505717, 236.223438631812, -55.62920783275, 17041.3438078773, -2255.28636222692, 11714.6636338316, -4872.53824800704, 7849.77819764334, -13577.5963667327, 13025.5645202701, -19988.1600703682, -13054.8806847848, -11132.2487355686, -6134.11394136375, -3785.95263636054, -3665.61689127865, -7145.09871335675, 7310.32123274188, 6733.48995606485, -10520.9665417 [...]
+2467.86580826779, -4518.52510135539, -8401.42971485425, -10689.3619957681, -4404.08283988578, 10147.6662962338, -14033.9811947339, -8701.63145535387, -1786.57179655702, 3570.64397954536, -7440.9689894568, -26314.7942083570, -7709.62694180955, -4824.29018554136, 8447.08895652698, -6556.10921225477, -5084.77854758385, 4120.70087700573, -3248.45807716092, 13415.8745604971, -213.439424652770, 9160.25580266718, -1817.61976183715, -4728.49952549889, 4822.46534713862, 17165.1174324924, -9472.90 [...]
+-16167.2279698571, -9987.94280540666, -2503.83821969274, -8102.99049992397, -8685.96134312869, -5600.71752354309, 5524.64608702642, -3555.02934738653, -3415.62709657695, 6285.03161385537, 14737.4642819830, -13872.4323876589, 10581.124623544, -13679.6861075923, -6971.39610947091, -14581.4367755546, 16952.0023910905, 1359.07224926495, 757.284722636024, 21437.3394762356, 9926.78495803615, 16599.9183188494, 3769.69342924378, 11890.1575441937, 11110.2663085206, -12256.0208759583, -4080.200188 [...]
+19970.0406474297, -5535.02626941011, 4357.06911204287, 7425.57982377707, 15493.8122390934, 11172.8740361486, 20754.7183572024, -9892.41929575535, 4603.19719343168, -15914.4306063956, -6753.48906059978, -10140.4056907068, -5.21991812684906, 3837.47333177999, 6645.65257543082, 4859.74517306361, -1217.55646501448, 3210.84266466828, -5508.71659705244, -3603.59794096391, 3710.82843140271, 5043.01803890159, 5827.81103969083, 6908.52394392522, 10563.6697200501, 6517.81410516475, 21401.487617764 [...]
+18263.6683412105, -1651.83544464381, 1818.67448010784, -19256.1100315919, 3974.24822752021, -2239.35713271372, 6923.38147285841, -10718.2287453091, 7835.27633702359, 25822.5475261680, -3133.73813013766, -6999.0353720119, -7392.1898878135, 12294.7635350100, 22124.5287673871, 2171.75421814631, 2184.38734044285, -9766.0771188807, 16317.7502424515, -2358.27516997799, 13154.4383403358, 14136.2761241350, -7061.24682873499, 6440.60007866921, -10072.3530562607, 14342.9556110499, 16355.7040503884 [...]
+-2752.05244179251, -1553.25765803440, -4623.47285895149, -3459.37299975639, 729.299702500491, -7134.88338697641, 394.889341355173, 7939.2879658384, 10875.1784009892, 25267.7793252457, -9502.61688140792, 2730.45090478627, 5201.68342769546, -14432.4188627601, 864.507786030512, 11347.1253025865, -2763.72722524293, 5295.65054045312, 6103.09149696317, -11748.6289478806, -19051.6158263080, 12104.5052815954, -2144.68156205824, -15194.3536503947, 2821.49837346408, 12744.3217373565, -1243.7672313 [...]
+7405.46694051144, 2945.66710342418, 7438.87288545994, -1627.15544497756, 7452.55099277309, 8398.99850497529, 412.518224699828, 3796.03821946426, 10622.4245734568, -13387.3054762751, 5138.16415952399, 7172.22308424077, 9847.5226042537, -3715.77246753507, 6882.22338416593, 14324.3555364929, 6108.4490229355, 1144.74078801581, -5316.25682833363, -7408.05816891153, -1578.8517531181, -5260.38342583127, 8663.03611328393, 341.732039859564, -2451.84863450055, 4929.1091489633, 22110.5797976888, -1 [...]
+2254.201367856, -4777.30839222422, 1863.17045640171, -9295.61835579326, -5514.67777262769, 6438.74293864601, 1582.71974591680, -1084.12023748785, 4615.02950097996, -11233.5167859241, 8265.56202536698, 3930.25348633399, -2636.64325559680, -2958.42209068140, -5224.68273064959, 3106.28689707061, 6224.65750748872, -2663.58918057019, 696.26205488545, 6058.90553035313, 5608.35349661546, 5790.39853560874, 841.021869699614, -12202.6742004042, 9496.23976092127, -1517.93328539940, 10602.8945564214 [...]
+-16432.1425644097, -10664.3500486054, 367.518556746287, -2840.78390453803, -12827.3978944551, -1428.19794655975, 19519.2850428104, -1730.28451595394, -1906.29303739615, 19031.8096542856, 10063.8291291784, 2501.34851109420, -6027.98297312447, -8738.53880897976, 1975.03423250278, 3875.43699958711, 11228.0727977479, 295.512699208188, 24279.9366450897, -6366.24774960794, -10365.6353604499, -6561.34918137384, 7534.26663107935, -388.053975197234, 1458.88994072448, 23769.0001144866, -614.432441 [...]
+10404.3436057563, 4215.56345107471, -1477.46258709700, -466.115758824148, -23384.7351123543, -7370.57752085242, 2458.62271236700, 9394.38485929632, 6223.07330217456, -23637.3607031059, 3860.69414355556, -8399.35499119332, 8094.69542509973, 26.9090715473153, 39.9075390143462, -3650.20614636437, -8238.75286087216, -1253.04506893315, 8043.7300173799, 15277.3758672531, 11747.8107562949, 1286.60958919727, 14906.0287840390, -4564.62281555259, -9802.01428452741, -13520.5365151382, -3098.5370671 [...]
+1526.02756737811, 7032.75457545723, 10224.2138311212, 13198.9930886035, -470.711659319022, -16012.9532816758, 2094.83658586409, 4189.3063751793, 8658.83489928862, 8890.97557378665, -7619.81190683001, -3036.57634898462, 6806.39071420244, -12765.4808329138, 6736.48503186703, -5881.53587291856, -165.938171899753, 5559.77001883075, 7123.9679080313, -21325.6819038692, 15210.6295198825, 6070.72802896248, 10187.5139302502, 1384.09451108593, -3792.42686584526, 14637.1979960398, 16004.2023017986, [...]
+15900.2011562075, 5409.00027658421, 15080.2590292104, -2644.13499015093, 7485.59207417584, -2521.04318107447, 8888.70942122026, -1090.3384912559, -3218.70599935327, -2359.86838424930, -10881.3807839323, 19147.2672173070, -3529.8012826608, 3862.20684522293, -6213.36471513791, 10924.3214729281, -20157.6313130082, -5920.19805891772, -362.118731961118, -10256.9946054607, 24797.1896227017, 6698.68662074693, 12306.5367683120, -7458.84078460886, -2283.84962591246, 3497.91612094920, -4126.505771 [...]
+-4308.6465161266, 4563.99921244499, 758.843649700106, -645.667425336366, 8577.67130733805, -23855.6411085477, -3991.18254399536, 20633.4552200590, 9319.30025736046, 8083.10026757418, 9256.76119698597, -3646.29634212139, 5669.06418744102, 1495.77313859901, 12414.7605357021, 8068.55194210792, 6580.79811248212, -6272.11948672632, 17022.2504899468, -6017.38504474244, 9772.56179646654, 1656.60473725228, 11643.4982548173, 15665.6498751756, 7306.30171494865, 6762.78180980887, 1745.87147256738,  [...]
+-8601.34702897384, 21078.2770191978, 7625.83652025025, 9372.20054211348, -7204.39747966095, 4257.12605907641, -15759.1562935409, -9766.16109379188, -3718.06708959402, -6635.49556349773, -1914.52953703505, -18888.8857181501, 10419.7111810226, 5006.00269833836, -278.424798820010, 7679.30794686886, 39.4992292157317, -15346.4153261353, 15985.9393144313, 4200.23612331213, -4377.45656280477, 9844.3683489617, 7211.29055509281, 12179.5992850867, 4549.71480050971, 14633.5709643324, 7231.095581345 [...]
+-16390.8602067224, 3523.00221937553, -14566.4975033331, 4130.77133842876, 19288.3149230643, 2388.52853597969, -2997.00139285220, -3676.7567148802, 11961.7044815168, -4406.78016063449, 25939.1252895646, -13026.6121131487, -1699.14794726127, 20305.0768676233, -14688.1441841981, 6127.3788148156, 1005.17947493387, 1026.13198612251, -5923.36158058566, -9739.55220809465, 12525.1581928329, -6302.48639372578, -2240.81155031831, 136.060296447526, -9040.62967619139, 1675.94615418171, 17190.6341480 [...]
+2136.77787909872, -6291.44880252393, 840.187289011333, 4329.7815488612, 3437.03718126259, -8095.32126144938, -2476.37311097071, -5145.33537550976, 7150.92558126549, 3541.66878580435, 18947.0945171087, -5916.74843306953, 2035.81841029715, -15908.4862701458, 3658.17300889433, 6883.14642590938, -6355.04657336008, 13325.1829626725, 7751.75706892357, -12558.4173831288, 2809.14440395293, 9057.2731573954, 4388.45615196228, -24061.4587899889, -16962.4895236626, 9009.65559679459, 10701.2347774281 [...]
+-1982.69476030081, 22518.4749496349, -6673.32065067347, 631.726860236005, -9048.85625322477, -3222.69575092727, -7481.84009385885, 4866.66137094954, 903.96715549921, 14523.7342075227, -21587.0501630086, -18427.6251922821, -5668.12332421538, 10074.6845106143, -2350.74524440483, 3892.43289695864, 8091.89476873993, -15788.4890943757, -10903.2523340739, -10930.4936150345, -2163.11970927966, 1211.78041289275, -369.981558277225, -1018.75880230181, -5927.60696554765, -13656.5328927045, 6555.206 [...]
+11935.1510032670, -3400.89550575697, 26864.3042610039, 3934.05354351638, 6377.06773761214, -8315.70427604647, 1279.56971862745, 2010.89761705851, 4839.70125674188, 5154.95891282094, 11082.8830266565, 17864.7641291026, -3844.74891826751, 7871.97502419493, -19892.7487506784, -6365.18176344044, -12589.5125774593, 4026.4594132827, 7735.72261581872, 10237.9758436289, -851.71909751644, -6950.25523089842, -10459.2643888774, 3291.2803605221, 2082.26060295890, 195.664743544030, 10046.9796551736,  [...]
+4453.46743076449, 7386.73201819242, -7292.06782208905, -2463.57056846701, 15866.9913001870, 6881.5503490561, -14350.8451487176, 24494.9482678176, 14540.2835846008, -4932.46884379554, 5414.07124267403, -9360.89562735092, -2698.27164083831, 14030.6723577367, -1181.09718539174, -12892.9543999485, 9785.822097859, -11509.3680188100, -3501.47608045189, -13612.8792754878, 892.982826111882, -7714.47390767707, -16078.8045882804, -6604.11859231687, 17320.3561101813, -1796.33965675946, -2268.523042 [...]
+-10206.6627747106, -4824.33236613054, -5151.8481635532, 8482.78955644231, 5551.57002260032, 8657.83679147084, -6774.77989655195, 18511.9085792220, -4002.1754011988, 3124.60765169851, 2612.05028109026, -19162.1220783117, 12267.7725530643, -7176.22340223423, -12911.4397621384, 11953.6524502407, 143.843870549138, 2646.21568416175, -132.112054056527, 13068.9515277615, 25550.3083581614, -8575.62016191722, -14003.7586405713, -8846.50198364081, -13521.8131537243, 15892.3198542794, 2130.45721102 [...]
+-1198.34515765534, 6250.49287332156, 4304.54261678229, 4078.82249864073, 13434.8368361857, 2938.6622440752, -2888.28330879552, 399.54180803242, 8675.77839178369, 170.600888590825, -9171.74813422106, 12757.2027824906, -8544.33112023058, -2022.64313838701, 18707.9225391101, 2752.36160714490, 20551.5888663185, -1738.78032208296, 6933.09090830424, 9917.92419874393, 4352.30242512578, -13808.9230848195, 12354.6965501730, 5190.78126483996, 16264.1549958473, -14975.0118631737, 8517.2875368233, 1 [...]
+5703.9208646924, -14759.352213707, -9790.77746798453, 8992.10139801394, -497.459835070657, 4654.21346638008, 8533.97811764716, 3750.30221881137, -10435.6271365630, 640.385677850003, 17418.099648226, 4335.6926840548, -4797.1923510299, 15500.8302739944, 2791.68829986735, 14061.7410868167, -7058.44565604721, -13799.8665160975, 20664.2491216374, 4362.82494145525, 17091.4478638459, 1045.04440719175, 5092.55213366257, 14876.5418058422, 1672.61214265704, 1165.43516665932, 19487.6285764094, -486 [...]
+12384.2820492280, -3525.56070724414, 6998.95396158772, -8843.85265687592, -267.434732084317, -21940.0461301075, -1497.70557777679, -560.748660854333, -7551.89039972448, -1728.63753474992, 2236.8007012124, 10309.4603111545, -7636.95298172678, -4286.41631956617, 16461.6557804406, -5853.59419661785, 1607.47148506809, 9279.48969422295, 5883.58455390768, 7867.13288628436, -14474.0064109383, -9212.04785099798, -20244.0211826597, 450.673749492963, 15911.8888292889, 2532.31758580029, 14881.49245 [...]
+-1799.05869092986, -11092.0088651275, 14187.9434671072, -11036.0174649121, -1081.78316316643, -11830.9413140450, -8604.15263172214, -9442.32358113484, -4768.73558061463, -131.829905455691, 3167.18877084011, 570.011534098023, 5987.63160586148, 3405.02282286465, 9809.62271870844, 1079.63090399602, -14738.1014593872, 6814.34588985536, 5824.64109742383, -1968.49844895430, 10372.7962082032, 5285.73513073556, 257.244785254587, -10035.1648395035, -3016.93737998637, 17537.8860014396, -13890.9277 [...]
+-4600.98790581634, 8052.48970968203, -10350.724131007, -1200.20237195260, 1451.16868091461, 12461.143641194, -2509.05183173086, -2997.04396795742, -115.540338427014, 96.8783283008636, 3255.03115193846, -11222.0213274597, 3668.83168199013, 12429.8921573955, -2467.05400418164, 15678.8370864484, 13638.0585154803, -12375.1956398064, 5816.07184538539, -29198.7180154571, -15301.9016166240, -505.566045009403, -15441.9357326448, 14739.2792250643, 15168.5185946081, -11751.2063658868, 11572.743582 [...]
+73.427757276124, -380.437852711313, -945.3076721897, -20107.4582131105, -4545.53965453631, -8598.08347592677, -2305.82221684492, -10147.5228715721, 21710.0345159218, 100.814969399802, -6688.18930228313, 4733.82434687059, -1768.09401776665, 7290.21274622888, -4246.85338062528, -3105.62934200648, 3910.97573588219, -4766.06279310451, 1630.21930747638, 6460.98720568716, -1166.20203003426, -18420.4292745917, 14678.6738905398, 370.662123950267, -13968.6642105907, 24184.1130436681, -6853.683757 [...]
+1183.53555206550, -2854.90255693356, -5040.72045587919, -7230.35808803038, 4238.71408394499, -3661.54168072471, 9003.46720069071, 424.70401313538, 7143.86183441048, 1121.22208032182, -10971.3781344340, 1006.02098924331, -10181.8137121774, -13584.7533141892, 14848.5698471832, 25759.5087584454, 5436.99196834286, 9681.71438929322, -7602.27151203896, -4989.55665009738, 16207.3914399642, 1141.80052457595, -2095.21992193367, 1676.73433162775, 13685.9417596040, 21808.8246062296, 34548.379798288 [...]
+-1648.68561659653, 13027.1875668612, -13916.4123188699, 1216.89157927454, 1891.5307891693, 3955.76482864667, -1949.24499754938, -21041.6706124913, -3756.1070348893, 1229.68270332165, -14717.8680072132, -3212.64699621883, 17531.7672782331, 10282.2721826621, 1800.82246820322, -2730.17668842141, 15204.3551020431, 13243.3731649671, 15530.1802561736, -604.175472805033, -3373.22801038531, -12517.3217343567, -5596.7456235172, -3494.55073337683, -1265.87652888780, -14892.549161653, -2331.7802081 [...]
+6443.29744299774, -11551.9495865639, 8011.94133956354, -15073.2560198409, 11973.5062232537, 5771.88761969447, 3390.67706209999, 17041.8754917051, -3524.46537664461, -13559.6518010882, -8450.87456453635, 1036.14938676009, -181.252704993746, -15900.2509326329, -172.324312754048, 414.801647328711, -2138.42813900335, -10036.7638410349, 4272.48980503389, 21991.1213373515, 9134.68583220629, 21833.0349958943, -5220.75491367, -5132.97783265022, -7393.47149210904, 8460.18973674093, 2002.761300766 [...]
+6684.9246754867, 17193.469306092, -7022.89710375848, 10735.9812303757, -9526.76362810981, -7321.83011464541, 9725.49189516909, -5293.73079531973, 2818.87580095570, -20001.108080071, 1591.63588426915, 10238.5451469860, -7606.52027189286, 27116.7759668394, -21251.2151583309, 11300.0170075179, -6171.20143063156, -13099.7731020065, -10233.3498845207, 5104.88154665081, 7018.84562842426, 1777.71405048551, 22953.5907445595, -5429.63522520487, -4921.86776284473, -1535.19513734784, -2502.57805084 [...]
+-3432.56789409982, -9661.23681672965, -22070.8198251312, 20545.3181820071, -7047.26376124138, 2775.78165244677, 6452.11870096608, -13615.2282826804, 4165.22387780216, 8460.46797394666, -6914.26631778761, -4978.61420152787, -4928.7274871507, -4621.03630119790, 5745.34288881499, -12214.8781833428, 7850.76301891701, 20906.4352820814, -177.502966723858, 5216.6587854631, -6029.28415582595, -5200.20826308958, 8698.64965657059, 18344.5944574714, -8923.59535402827, -4930.91414370335, 23905.89794 [...]
+17494.8790894345, 2934.34523125405, -178.364662576222, 12811.6573387898, -7156.40484333543, -7377.12857723205, 3766.47664814979, 6234.28962888577, 8948.53360457587, -2860.42348872677, -3779.60533762015, -2123.40737564640, -11924.3579296028, 4801.18455897216, 11991.3943545072, -9938.21053730294, 3249.35407791728, 3497.31388288697, -4394.70647965839, 2625.85903254688, -9355.79496420574, 10589.3503004977, -7123.32347878663, 9446.92913253604, 3488.82151178751, -9735.92711927108, -839.3501450 [...]
+2023.98509106876, 1587.50929187907, -6049.41282993193, -3007.70673397791, -6928.2460488298, -10546.5228811163, 6366.16646510301, 13241.7024556879, 18793.700532228, 22459.9451543200, -5335.88466932842, 21979.1272701051, -3446.41776435208, -1682.83509608005, -4862.63461321813, -13759.1849273859, -8111.90641034823, -4826.97933876033, 17889.0433256657, 5839.59323186976, 4515.83453770991, 23432.4397239984, -15555.4609832228, 959.5794499785, 3072.61035318872, -8706.82112420619, 10602.368606792 [...]
+14372.6471741622, 17702.9168374152, -5108.67139542787, 10997.2564354686, 7143.13196044917, 7136.58126928699, -14191.826969942, 5848.5782175203, 12423.2569047482, 12641.5324646270, 8217.42241551165, -1962.23381905028, -22259.0305068303, 7149.78397531459, 8979.38883930025, 1960.60028279701, -10096.5652630826, -21301.8353017679, 2218.71561556859, 17497.2419079099, 4577.12306563055, -1334.12476325127, 6949.31645641404, -4301.04045152313, -5069.4560714973, 8979.59830510826, 4874.60549650492,  [...]
+7073.10637592048, -6880.07984179669, 3140.68782070225, -19234.7100826952, -7569.09839073487, -27885.392679589, 7713.63716458407, 7342.732528184, 1031.43053055897, -10077.8010084105, 3683.77152756979, -2500.46741461978, 97.5168879169213, -8911.81004212003, -108.406000194088, 8370.77868351431, 7757.34281501319, 16505.6929421784, -18409.4349341159, 377.338044038527, -6892.32184748189, -4018.78934470458, 1361.50323895362, -11334.9221355356, -15616.4329537929, -11539.7936444222, -1916.1519069 [...]
+-12129.0785570746, -11031.4619667071, 712.173260121551, -4239.01730457962, 8219.65049307439, 13943.6941839315, -3627.17452159233, 8036.40911818232, -16761.0575788745, 7592.75233134752, 14349.148120901, 13296.9576402520, 8827.90269699404, 194.943943731918, 1015.56788418637, 1205.64692379734, -11515.0965846390, -6554.7635728907, -1014.56265507069, 3061.59751777838, 14974.5933032061, 3648.69642304956, -958.50434321786, 2757.18159297978, 11181.5247471798, 2319.92679223544, 7769.16095034888,  [...]
+9414.12005305469, 7694.02902499074, 2746.78727548877, -2486.30685224222, -12323.4685865525, 11756.4438402612, -4519.94095325289, -4644.34781454421, -1895.63962566182, 10884.5714184737, 6661.34352661406, 18842.1370506607, -6483.97850049148, 1476.39572459766, 3331.47885921284, 10064.7513841704, -11877.8385273274, 7325.81937621345, -5168.36849147686, 11731.9289840293, -202.838825755904, -1999.42405919156, -8254.94103548285, 7368.16557282457, 5955.14970870723, 9366.32289264183, 1216.01810755 [...]
+-12059.8605693717, -3151.94612468353, -3419.68320773810, 2801.23671357991, 1611.49319208628, -8611.04239833564, 332.367284910523, 6975.29588461009, 1160.08582021078, -1784.97644562834, -5726.00560334066, 9647.18892691028, 10452.3784574896, 18677.0690489833, 3954.44634522086, 65.7535300367739, -1190.80373993977, -10370.2776734558, -1167.98612820874, -7129.8809831994, -2532.65427347263, -1042.18486209270, -11334.0114058449, 15131.0439485521, 4561.28843526264, -2185.08645610647, -4834.39039 [...]
+-17311.8429175013, 5187.21823760145, -17070.2301217660, 800.39863583402, 11249.7996914356, -1230.86236792463, 11478.2569417895, -3677.69411169466, -4430.19884297640, -7670.62257778001, -16873.2407606795, -5852.40665685568, 2902.91327543816, 12689.4794290842, -5812.721190207, -13416.1665712852, 1218.75505893569, 13636.0569424927, 6825.38756130891, -6248.26709473377, -8639.2767015951, 2178.05893279120, -4630.96276016767, -4917.59124692349, -1910.18349357483, -2006.46265804874, -2739.919270 [...]
+-16835.5655670222, 11059.4874845122, 9483.92924205057, -10716.7512066682, -5670.27246915823, -1558.72893400212, 6870.73942068743, 13214.9772975889, 403.568873988145, -15092.8938031224, -5068.30237371156, -8774.38451607008, -10701.8993397657, 9746.40123209042, -6449.9028513018, 20736.7630599007, -7027.5203317852, 2587.02119015003, -11322.3480045406, 2281.91566497479, 4997.04042094864, -7991.67788969558, -1937.54913957515, -9555.87020120244, -10775.3719837417, -10430.1507370999, -12536.491 [...]
+18654.3284004837, -7289.04709000148, 6543.81625928838, 15798.4960218638, -4913.02094195489, -4349.60939467128, 11113.5581189909, 17613.2917036775, 13405.1510926991, -14342.7207185069, -17532.7081911197, 13193.7930389460, -4675.71641900901, -2750.13541495561, -4158.86455246774, 15629.2371851119, 633.046296178838, 5123.9794711011, 8335.7000507594, 18195.5237872320, 6015.3731916081, 1502.07219937771, 15808.3741380203, -4864.77226686033, 21636.9822938729, 5570.35566600388, -177.180557784611, [...]
+3760.87889555771, 19218.3558806882, 13096.4450422979, 4976.73874293829, -975.26920077324, 9673.75904066903, 10366.6095261026, 13068.3469307397, -28877.7124574094, 20139.3236427066, 9954.97929642085, -2734.12569769287, -11602.1577652460, -6019.56285834806, -7420.94143890533, -11978.3125962577, 11270.2416257147, -4485.83955077124, -43858.4483189613, 19079.5293318515, -1715.80583725528, 9203.66980894546, 6268.27559098654, -6948.25398217523, -2915.84520412175, 4456.12589410112, -9040.7845832 [...]
+-5842.05108372104, 9966.53407959726, 4404.01043163620, 4155.39045975742, -8056.45110490132, 3596.92981455541, -3790.11730545536, -16844.6687635819, -2935.78508559114, -8034.71504514816, -420.886806675609, 472.596136915051, 4822.50163701992, 16478.8417316016, 14868.4844281291, 706.941740203864, -8030.30224687837, 1422.49857525557, -3109.15664621460, 16104.4539951013, -3417.62751240437, -19679.7843771810, -1283.49606855375, -15036.0792115289, -3574.14698760258, 8674.90098011169, 3840.83383 [...]
+-12542.6452384339, -2606.93064677632, 3058.07981403218, 2030.65640994484, -9560.72356609, 11050.7958381710, 6811.26645934088, 6312.0215608995, -8166.71849634882, -12871.5770165249, -12096.3509646859, 7215.78747520483, 7142.13290798225, 5601.7682340959, 7484.10313031843, 364.922727248323, -8514.51244545796, -8725.47242636053, -9303.0153001791, 8604.62799836907, 8113.09737388596, -1149.55596535433, -5650.40015127353, 7491.94577642153, -8978.17305145342, 299.261980281949, -23236.6759489163, [...]
+-11939.1198720721, 23628.7842067767, -1556.96106683555, 12822.9298804952, -4841.88180957284, -2513.75078869848, 14688.1476528182, 2736.08258706980, -3864.8716397986, 5515.18725093604, -13885.7186425234, -3041.45067646204, -3345.87792428524, -3343.84476473291, 9748.82119733064, 6379.38052357209, 5455.35372280314, 3006.92361610878, 13086.9657966611, 4284.55448571226, -858.68378355529, 8184.27332667542, -7254.42937654258, -12750.8430347129, 6728.63789800816, -5036.9921936703, -7171.62833649 [...]
+863.879484728644, -1653.43570876881, 848.542773363248, -231.839924331925, 1872.53230146684, 5134.67571006008, -292.695890971303, 2533.12564342712, 14222.8996518783, 8372.22535196628, -855.835849843695, 12144.1404847856, -6419.77383762828, 1045.53514226358, -9447.8444044813, -11263.4157531722, 2592.70194212513, 7692.13500276193, 8322.02251653629, -2256.74052450357, 12536.6924419252, 4643.40921648699, 9470.12321157799, 10618.2810994269, 13052.5099438859, -4330.72372475521, 4734.7011363497, [...]
+455.067077197461, -9505.19061243486, -13380.4045718037, -7501.24053398848, -1228.49336656440, -3693.62849117227, 3246.19260637382, 8194.86474650982, 6207.95656242393, -14205.1732099764, 9570.93241009452, 27660.3794439146, 5362.48091249597, -7196.3858622251, -16974.8216703330, 496.884442932226, -11445.9774169981, -12606.4764598439, -2548.18134423811, -16642.9234538183, 19148.4951479579, 12109.6961759189, 12166.4192669416, 319.613134849621, -7266.92589595265, 14089.3668380293, -3019.747771 [...]
+-2140.46995027849, -10445.4338087644, 2364.35818908291, 2454.84499165389, -331.607560219374, -19334.1677057763, 3528.52794782720, 4848.7971134134, -4897.10024002599, -6394.01149888331, 11594.1388183877, -13602.1021637318, -8.04481695217057, 5040.64473941133, 6087.71883371416, -12953.8948971715, -10189.7076483907, -13222.9095197399, 3097.14786782431, -8768.7129018494, 7263.69962155621, -4063.03579440825, 6958.61076737267, -1860.01254235453, 1053.58238962997, 5289.60613270693, -20422.86838 [...]
+-221.079111152562, -1391.00713347677, -12374.0270059068, 13355.214413222, -7189.93248990162, 8536.92243971055, 5840.06597387674, -2265.60196155322, -5282.21026531865, -4900.25623321413, -7266.97517436782, 630.930005330354, -3722.84331931772, -13843.3328711314, 10570.9233155726, 141.789708326260, -2348.50698924468, 8288.01534756187, -15819.3335817620, -3730.06116834416, 2519.85761766865, 532.125760926524, -9091.54713443382, 4870.53511708504, -18877.2189220955, -4746.35866223597, 12793.652 [...]
+-3893.7982179198, -4763.06439369064, 4726.64675323371, -16613.3684492191, 2442.93187959305, 6764.32914669215, 19117.0865081621, 12147.6377647778, -14450.7029649007, -338.428192402363, 11677.0377137100, 9440.75865795866, 4514.40101472414, -14929.9431050952, -6313.25672328803, -13769.2724911039, -2427.17726362421, 1398.07641201327, 4570.7622445393, -88.9698990963706, 4975.51320727352, 90.3373054264805, -4850.53969060856, 4503.47182703193, -4823.85623766006, 4812.90220791454, 1832.498313753 [...]
+12182.9623679474, -7376.29522131808, -3307.04544136311, 771.746598640436, 3453.7869163376, -2602.02947362592, 11006.9353095399, -9752.07517621303, -8571.99340299975, -11621.1525485683, -701.679776993053, 9749.1762591612, 2970.16649047572, -658.750309711464, -543.987103117898, -729.958816726211, -2507.52568579121, -897.493954073406, -1252.80065064037, -7289.27665366236, 31187.5857803935, 15294.8456345415, 17586.1394093335, -27292.0109029848, 7251.76068907995, -23306.0960838788, 15027.7260 [...]
+9411.70929530056, 4268.82614624324, 25874.1610837884, 9115.87308559732, -10554.4884967388, 10011.5840658923, 13219.8560594391, 6707.80030568945, -1168.86423707806, 128.707012242354, -6607.84808797413, -24664.4401722722, 12066.5633837044, 17439.9306017398, 7604.30494607576, -10725.8698567995, -1191.83609126635, 15333.3452976517, 3411.18375760967, 1578.09027622558, -8507.44103307104, 7689.99710386004, 13355.1123660720, 13096.8901958114, -13591.5621460764, -16089.8184488919, 20842.552538669 [...]
+2238.53356511139, -6021.48798470557, -764.527905605326, -2359.91081291591, 967.769948834238, -11575.0213568785, -8338.03685988542, -2877.07054583801, 9445.5288511328, 171.807262535057, 16257.8555446861, 2649.27560243015, 3658.85174435309, -7153.35420744034, -4535.6195680772, 4373.1281705351, 19015.6647424194, -10318.6932365279, 109.311130789308, 1267.87258396213, 6629.73332525892, -4448.02129880141, -10799.2790662159, 19493.0443534705, 15414.4651587724, 18321.4803646060, -2105.1202793259 [...]
+13534.9122023975, 877.290022826227, 7757.23245643733, 3092.68620233684, -12732.3756208069, 11382.8988694641, 7546.83428899656, -9207.094508946, 19590.1486286852, -257.087407457732, -11629.2506484845, 19425.4003003380, 145.206512046456, 4500.81335588098, 12.5640213458728, -1884.74690310972, -3570.0940741438, -669.912211442115, -8810.99159094002, -21207.3278522659, -13216.8835598573, 12949.7308519212, -13423.7664337141, -20285.5494116917, -5466.16070031228, -8694.4106681933, -7671.72738758 [...]
+-14211.9976609648, 10136.6591963882, 8993.4272210666, 2081.78536538811, 14241.7969216609, 8508.41021488292, -10899.5164176107, 19888.8402997858, -2985.41133778109, -53.4525937242416, 14593.0676320357, 2664.21237569409, 17493.9000437603, 10547.6096295781, -7122.39233060191, -4588.27316061338, 9463.9086638299, -2944.94311307901, 640.877732201242, -5081.72342223872, 1737.20734420333, -89.2499706615458, -12299.3931571342, 3504.67572467055, 2721.94871848899, 7595.78843668235, -7856.5977609557 [...]
+-11365.5257993791, -7189.70106204078, -7242.9615258664, -4059.12471316661, -7850.2510638391, 1714.75888675338, -3904.20698073826, -11116.5268582199, 8577.55744397674, -7845.40340873362, 8494.02019740669, -4176.95586900074, 23211.3688777162, -6543.01288799474, -4014.82782445689, -1662.74503703846, 27731.6260719123, 438.497403868202, 7318.47605794912, -3885.30185146279, 7766.85737764297, -211.290583965093, 8464.90881229122, 5227.79440555101, -2254.91910426586, 2106.25345475770, 14613.60195 [...]
+-24618.8289883407, 1206.99458113020, 1943.32319789374, 14227.7213458785, 4859.50889607476, 7542.84061258729, 9776.31787643378, -4711.33075328489, 2749.07848584045, 15022.5482143412, -1339.96350282347, 6364.67777712252, 9039.35074380559, -3212.06875621537, 8375.76874890397, -721.133733316439, -7007.84136467562, 4601.48201160157, -751.891512419848, 9217.74576437765, -1308.08664418441, 7616.81853647278, -1535.40723580932, 801.184529880244, 12278.5853514450, -3957.39830537193, 1632.985905805 [...]
+8634.89787941326, 15163.6105462609, 143.084012720189, 4836.47079535894, 9784.1184493458, 19066.0376249535, 16878.7730345996, 7805.04501430157, 19591.8485010433, -7568.99969936443, 527.917098315321, 1341.23460001155, -5241.13570045901, 8311.33282227282, -13482.3375505177, 325.306353796303, 4913.69557579004, 3047.62940637134, -16586.2661961230, 2479.51933590463, -2664.67024033516, 3945.84996242672, 3067.93684671392, -4570.78019829665, 11049.7446070368, 9171.63555929334, -1697.44233020091,  [...]
+-13488.3423827723, 13075.7960907589, 18487.7936101195, -1770.15742852314, -10411.7035471363, -9691.3000292299, 4498.42626544549, -4099.95856089278, 627.636148274453, -18694.7631313551, 13931.9653960833, -2253.01041502797, 13529.0431075450, 5714.53610959958, 2218.87882880174, 3594.42241809683, 15666.8484363067, -13707.641755711, -32077.8838294081, 9046.1070326052, -15993.9117047612, -14220.4329894613, -19865.7401359724, -6708.99169913906, -3686.68828186382, -12435.2344506663, -14062.50910 [...]
+2340.85332360768, -5324.28731643868, -11867.3425485731, 17685.982819599, 2965.81038320315, 1604.30952124145, -4641.21839143418, 23074.0390353668, -4634.52183824358, -1138.38615198433, -7918.40342534741, 13141.5708356479, 2063.02680706357, -6026.60192174555, -1886.13779047785, 4915.63078030534, 1519.81333534466, 5993.9206555775, 4281.33288020365, 1687.20121530753, -3495.68569550552, -13466.0623421427, -3337.77048870418, 17574.9462613505, 13288.6494874881, -3423.81989723359, 12504.54299794 [...]
+-9994.53420715501, 8948.95252866395, 5500.79938264881, -12888.2475980533, -8754.98871747561, -338.826804179129, 8266.46194453223, 2958.97629478626, -8470.25958875079, -5919.26028776104, 13941.6315479057, 25944.6536804341, -2944.90650551729, -4527.46547316419, -5503.92285093687, 6978.0335291394, -284.191725106973, 650.59270859712, 21764.3844736439, 3327.28080997763, -3338.74842484296, -4849.38784044342, 15254.2698390619, -8901.38273526432, -1867.20942632303, -7771.00284021566, 4444.335084 [...]
+-162.948691202102, -1989.82726214259, -4016.57486372485, 10004.9848036772, -3496.44379591495, 4428.84673643649, 7517.30723863267, 3043.59874799576, 8219.95571050718, 12472.5157209934, 10584.6206113399, 5266.68207292078, 3738.38752749225, -3936.67897860289, 17509.9722517386, 6992.18179238876, -8145.75392130295, -1430.70247095017, 16731.0144693887, 8428.30538810792, 3234.90652484195, 23971.6696777662, 5911.772371924, 117.164659532956, 2099.44926930906, -10269.0861633048, -13548.0359924812, [...]
+
+double y5[100] = {
+48096110.7515225, -48114685.5522426, -18938059.6233489, 60539248.5567633, 91453030.4559117, 80410744.4587294, 90342730.802252, -30146208.6652129, 3379800.38902381, 18719528.6134663, 13543143.5028794, -3675603.93433599, 5681006.14507804, 88363997.7538736, 2550870.44116776, 76339187.907032, 137172248.184188, 5068168.92122888, -134406141.152233, 70765447.3172784, 96347650.592202, 56365693.7839156, 45024867.6059287, 44073049.3691214, -11289721.4157962, -36002301.7666806, 13647473.0731573, -2 [...]
+
+double lars5[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -33.84857120387898300, -51.70470155834353700, -86.73959730201677600, -122.13999202070755000, -140.96626917939264000, -342.09855698019760000, -398.51935457172618000, -422.43642169621842000, -431.4058 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 39.95768296895066400, 88.47046622677987700, 124.46847191045789000, 180.09092251614175000, 232.89244965733312000, 258.84119925601647000, 481.08728870192152000, 541.02304295608883000, 567.90852098967923000, 578.3407611282 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -35.98291202809645000, -64.87472184496026300, -82.69590014600198900, -247.40968472661712000, -305.38375728751237000, -329.25374404537229000, -338.9267038668 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 76.83582860968603300, 112.32007856826168000, 274.03160552378171000, 289.60949600276751000, 443.56834631199268000, 473.57224589312244000, 505.62935347465697000, 525.26754960344886000, 560.67680225776087000, 587.46922980312706000, 605.19118043037463000, 762.83991470405351000, 802.08764574229281000, 817.56052929308214000, 824 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 81.30496850961452500, 139.59136599396598000, 456.90294674859081000, 604.68959930014614000, 639.99265214268132000, 704.30457206177539000, 730.69939244045702000, 865.36385584720040000, 881.04062723682648000, 1022.32192004781480000, 1057.98276708080830000, 1098.53872628753520000, 1122.30731692463720000, 1157.21682930665720000, 1191.28920934251600000, 1210.29645248731910000, 1378.55087982835060000, 1423.66477820212070000, 1443.45 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -38.29913261681510800, -55.55319950794677900, -63.54147753501522500, -66 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 22.95920394394067900, 85.40249040294266100, 114.36311682318829000, 239.91594093823826000, 251.69999372812887000, 354.97484244120113000, 373.22256378620267000, 392.40576588619859000, 410.05487348794867000, 443.27508809911245000, 468.26293919695871000, 480.20253498751379000, 593.75650231627276000, 611.88077034039566000, 617.76264332180642000, 61 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.03302682544831000, 203.15334809736254000, 218.23380757229705000, 364.66670837563970000, 391.69156226317244000, 419.02737444815619000, 435.17301010532179000, 461.31447292763045000, 479.60924932032628000, 488.38643818623007000, 566.00018322927917000, 582.85597879302929000, 588.91629611246435000, 590.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 278.34542763971558000, 388.02149890932407000, 418.46477782417372000, 469.66791035459619000, 489.73081982205872000, 581.62409742637237000, 592.63399687906121000, 691.65534189066557000, 718.18300926813913000, 750.38032798065080000, 769.61462050405532000, 803.23774817018148000, 840.30999872398706000, 857.86039509900274000, 1035.12634327130470000, 1079.13253294171140000, 1097.454730485087 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -18.87235465503025400, -94.49261903568735500, -142.75781649556802000, -426.91380734333450000, -563.98498481466731000, -593.52079673992250000, -632.47889867016727000, -646.16438702317305000, -718.97075584700565000, -728.26909578420839000, -799.89883732266981000, -823.66086487517100000, -849.31418790004989000, -866.75215982705538000, -887.76702729834994000, -905.38158322379752000, -915.77714363440214000, -1007.47518946777200000, -1038.6883179905717 [...]
+-38.57759727267461600, -59.84595548838074600, -80.33167556886176900, -160.81549746940917000, -212.06057154614072000, -486.21946256736720000, -612.15316242180347000, -643.85701355867343000, -699.83360723524561000, -724.21333666580995000, -845.57517093075887000, -858.68758054532782000, -979.19832176259069000, -1016.49742624187910000, -1060.90566391195920000, -1089.29920353477160000, -1143.76786579668280000, -1196.03337943250360000, -1221.45794614741570000, -1447.69820567427180000, -1512.77 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 88.71426312728866000, 114.51964422974615000, 139.17554422030534000, 153.58527164196425000, 178.08471899975498000, 201.08519533833081000, 211.50936307922441000, 296.63129160867459000, 326.91519564591385000, 340.27169561502421000, 346.1608458 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 77.08424730166751700, 84.86566535281612300, 153.32064927838343000, 169.03425894104399000, 180.28520639925401000, 188.48202687784260000, 203.16657446656205000, 215.40464083483266000, 223.36691757464376000, 305.10503398149041000, 335.22863339062798000, 348.51459709412376000, 354.0151 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 166.93969532939690000, 206.46027967580443000, 275.51156847594029000, 301.20764516330331000, 428.60328876763316000, 445.27650435469877000, 591.07941929740389000, 628.60668579901903000, 665.97839653572873000, 687.71110580276456000, 727.76366141031622000, 766.92502727686747000, 789.26951001185319000, 988.15509902671909000, 1045.01122765488910000, 1069.127620604789200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -19.51349079111507800, -231.58582946623989000, -296.49565480182417000, -322.92611822110604000, -333.97912617257776 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -15.07306329021170100, -153.99506379239972000, -186.10006344127834000, -224.88636247856002000, -251.21746478836212000, -291.71949206254743000, -331.80396725705947000, -354.54275306376138000, -556.28604283653408000, -611.41284369111281000, -634.82984727083476000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -4.63647870925929160, -6.95734 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -7.85400313374689410, -11.68019280996653500, -13.12 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -60.78572946236219100, -330.78684075241438000, -483.65361518609399000, -522.26280063648437000, -581.10090008492477000, -611.14590194251093000, -771.56068011017669000, -789.65769083786734000, -960.91369754103710000, -1001.41839453646340000, -1041.61349681198110000, -1069.41925736520880000, -1113.17149167178700000, -1154.77891347147600000, -1178.70276372728130000, -1365.78906033294360000, -1422.947428164945 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 102.08517375284153000, 131.28699113014287000, 143.53745753115015000, 148.46144544249310000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 19.41508076424258200, 32.93247691616723200, 87.09842138990197200, 114.20161015386624000, 252.44562649113072000, 283.86655115856024000, 295.40330647750142000, 321.96961409433135000, 339.86189603973361000, 435.11561606618795000, 442.96385689564357000, 531.98881674738266000, 557.16580665415199000, 576.86065352701939000, 590.90557250285428000, 612.62958701407354000, 630.29207834048486000, 638.31898896468192000, 703.41944308737629000, 719.77203468608411000, 726.2204009006 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1.610281 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 20.62025953081379000, 57.34363716577910700, 95.98093819110003700, 118.63100457128753000, 323.65576738069564000, 378.93261746248777000, 402.21185849305488000, 412.160187210380230 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.37010799392270100, 66.74788937954387800, 281.07182688116660000, 336.37969717936136000, 360.73343475088558000, 370.42153867539008000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq5[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -911.32299086472858000, -742.24947537297373000, -849.56527160232315000, -938.40727926559714000, -921.38779351118683000, -1037.13707795467300000, -1025.22238752950720000, -1020.88477329849430000, -96 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1192.48753586459410000, 1346.09301339113340000, 1516.60854924798260000, 1391.17582769039180000, 1450.39749909034300000, 1334.51657286360140000, 1249.08727015604090000, 1206.76901921181370000, 1240.63189160583920000, 119 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -819.45003954418394000, -731.06614174896094000, -821.45221494250018000, -816.59937809101064000, -949.34004039193132000, -926.52405957586291000, -913.4120624 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1672.66389531943350000, 1792.45078733275550000, 1629.81882663433980000, 1515.96789473169090000, 1570.38176615785780000, 1338.99755089406610000, 1336.66271383962500000, 1284.72961863417230000, 1331.65346592810420000, 1205.25279761217480000, 1339.83412688614020000, 1307.61541694262310000, 1238.03809536991120000, 1204.7201089 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1593.60875202042280000, 1834.71454672731310000, 1864.11915448172680000, 2030.70321571613430000, 1908.41410320600240000, 2040.01954628594990000, 1980.45804092017740000, 1994.38886761888490000, 2115.18335564769950000, 2056.34923574189450000, 2086.57571169692070000, 2149.89231383966810000, 2041.50289399357670000, 1917.31249270300420000, 1976.93494699196340000, 1998.21971226835600000, 1959.97572019179690000, 1924.7746197197807000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -463.71287356354293000, -487.28121346912235000, -537.97214315374208000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 847.87219126338607000, 1382.30721456583430000, 1485.60917248207940000, 1292.54909402414890000, 1179.39120644027840000, 1110.83580937301490000, 899.55547487560932000, 889.70206322597289000, 1092.59351847679950000, 1166.58914607624110000, 1044.43632912102840000, 975.14465595123659000, 986.15685914574760000, 813.19897613908586000, 764.93776189872 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1645.45030486833870000, 1621.05579900700990000, 1405.43230269107810000, 1436.39826132474600000, 1171.18998562589040000, 1127.66809634154610000, 1059.56833550028700000, 1030.50066804354200000, 901.45278003477529000, 852.23464122389862000, 834.20447380760663000, 770.08442386386992000, 740.556415326274650 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1512.75419454164530000, 1446.30090591404090000, 1512.27692456785210000, 1533.12225807287560000, 1439.68214591171250000, 1352.05607483366250000, 1459.38053622466900000, 1416.38523033916020000, 1483.34070382169560000, 1585.04845567577150000, 1513.45664654179000000, 1535.32455732329980000, 1695.12717328053300000, 1585.39175863776970000, 1647.69165431094580000, 1567.93832287439700000, 155 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -1627.32267497125960000, -1501.05871246492070000, -1546.43789569211690000, -1687.09131140569640000, -1886.60351712160200000, -1654.72809764016960000, -1441.61226276570850000, -1294.15354483731330000, -1329.37835217107820000, -1460.27432406641360000, -1324.15160917382970000, -1509.04710563560680000, -1514.33885313756790000, -1541.12561819000350000, -1345.33026842820780000, -1311.54049460161760000, -1346.71306546027490000, -1324.34959510966910000,  [...]
+-2007.60137159546930000, -1832.10767612097540000, -1826.28567164723220000, -1657.84563723527840000, -1702.40337389872980000, -1702.06173980700580000, -1827.30465044554630000, -1782.96090473468050000, -1862.42950662560380000, -1878.56018450615190000, -1863.07112267088090000, -1890.95274379657890000, -1861.20750906455310000, -2092.34387689963210000, -2212.12390420356680000, -2187.35404562038550000, -2329.73097875047010000, -2401.17895396608760000, -2275.40392515758410000, -2229.50055618578 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 738.00738283290048000, 858.84388617946342000, 778.34348443021736000, 710.84833847615130000, 711.51880104826375000, 731.43341815961321000, 643.63116866336850000, 590.78107707821221000, 663.29850322237189000, 674.47552370498715000, 695.922514 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 723.35751803315384000, 697.45229214416111000, 654.33760535291378000, 622.27385862049766000, 471.94946992350509000, 505.47520686831245000, 522.89779325241216000, 497.59169877396062000, 553.43388185325693000, 587.56162091654357000, 669.83133167198480000, 680.95348002314779000, 680.69 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1777.76364018470100000, 1626.41557836154670000, 1709.66002113993610000, 1517.88173543168680000, 1496.68661514308560000, 1757.86359672120370000, 1658.20015240306750000, 1711.03418727078290000, 1634.78502630181670000, 1528.17365324558660000, 1599.84040347679120000, 1669.91331694745830000, 1715.53417346382570000, 1675.42986303144990000, 1676.54976972721760000, 1672.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -828.42266066440675000, -964.42910502394454000, -1017.49192112682090000, -984.26419880690764000, -990.426723732001 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1201.68929900322590000, -1170.75489385927650000, -1112.12899638239310000, -1230.36411317991500000, -1269.51228723100550000, -1173.58272042791650000, -1256.07744182326430000, -1297.15279386695810000, -1253.43595980591610000, -1223.74260093671800000, -1220.76570 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -280.00091553873062000, -333.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -204.37539116199267000, -238.92087080356350000, -21 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1828.59611947831330000, -1528.19015962823190000, -1958.68602221603780000, -1909.47198200087400000, -1803.12833429995640000, -2033.73565161304490000, -2116.47597719241820000, -2214.33204759555470000, -2214.32372362761360000, -2169.72618921005690000, -2083.61239921694820000, -2144.74309577858140000, -2065.80248795747140000, -2114.16870535293080000, -2170.43827931262830000, -2012.28984998324200000, -2057.84 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 454.85363750574760000, 455.65084806685866000, 450.06632187230900000, 440.90129973413394000, 4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 1637.24585512309640000, 1184.99116634999610000, 1094.60588700534820000, 902.43429442504885000, 865.53141412382058000, 587.05134926138408000, 709.91329198738390000, 873.73381174674932000, 1187.03697741911830000, 1233.72149658966850000, 1060.81105959833170000, 1183.55590276223670000, 1283.36488321602540000, 1087.42058901103750000, 1134.06051172448220000, 1085.63330705577100000, 1037.55629094499110000, 971.06527609351974000, 928.38244551200773000, 901.41106123484735000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -228.4292 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 818.06137196896066000, 856.93315248597287000, 986.88526694286998000, 1057.56328425928450000, 1032.14523699445200000, 992.92907049761982000, 984.70064563320182000, 1002.999940053 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1043.40416640021980000, 1035.84675213825040000, 1021.69579212976170000, 950.72071222943134000, 970.10807208290760000, 945.8063184628831 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso5[2700] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -33.84857120387898300, -51.70470155834353700, -86.73959730201677600, -122.13999202070755000, -140.96626917939264000, -342.09855698019760000, -398.51935457172618000, -422.43642169621842000, -431.4058 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 39.95768296895066400, 88.47046622677987700, 124.46847191045789000, 180.09092251614175000, 232.89244965733312000, 258.84119925601647000, 481.08728870192152000, 541.02304295608883000, 567.90852098967923000, 578.3407611282 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -35.98291202809645000, -64.87472184496026300, -82.69590014600198900, -247.40968472661712000, -305.38375728751237000, -329.25374404537229000, -338.9267038668 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 76.83582860968603300, 112.32007856826168000, 274.03160552378171000, 289.60949600276751000, 443.56834631199268000, 473.57224589312244000, 505.62935347465697000, 525.26754960344886000, 560.67680225776087000, 587.46922980312706000, 605.19118043037463000, 762.83991470405351000, 802.08764574229281000, 817.56052929308214000, 824 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 81.30496850961452500, 139.59136599396598000, 456.90294674859081000, 604.68959930014614000, 639.99265214268132000, 704.30457206177539000, 730.69939244045702000, 865.36385584720040000, 881.04062723682648000, 1022.32192004781480000, 1057.98276708080830000, 1098.53872628753520000, 1122.30731692463720000, 1157.21682930665720000, 1191.28920934251600000, 1210.29645248731910000, 1378.55087982835060000, 1423.66477820212070000, 1443.45 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -38.29913261681510800, -55.55319950794677900, -63.54147753501522500, -66 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 22.95920394394067900, 85.40249040294266100, 114.36311682318829000, 239.91594093823826000, 251.69999372812887000, 354.97484244120113000, 373.22256378620267000, 392.40576588619859000, 410.05487348794867000, 443.27508809911245000, 468.26293919695871000, 480.20253498751379000, 593.75650231627276000, 611.88077034039566000, 617.76264332180642000, 61 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.03302682544831000, 203.15334809736254000, 218.23380757229705000, 364.66670837563970000, 391.69156226317244000, 419.02737444815619000, 435.17301010532179000, 461.31447292763045000, 479.60924932032628000, 488.38643818623007000, 566.00018322927917000, 582.85597879302929000, 588.91629611246435000, 590.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 278.34542763971558000, 388.02149890932407000, 418.46477782417372000, 469.66791035459619000, 489.73081982205872000, 581.62409742637237000, 592.63399687906121000, 691.65534189066557000, 718.18300926813913000, 750.38032798065080000, 769.61462050405532000, 803.23774817018148000, 840.30999872398706000, 857.86039509900274000, 1035.12634327130470000, 1079.13253294171140000, 1097.454730485087 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -18.87235465503025400, -94.49261903568735500, -142.75781649556802000, -426.91380734333450000, -563.98498481466731000, -593.52079673992250000, -632.47889867016727000, -646.16438702317305000, -718.97075584700565000, -728.26909578420839000, -799.89883732266981000, -823.66086487517100000, -849.31418790004989000, -866.75215982705538000, -887.76702729834994000, -905.38158322379752000, -915.77714363440214000, -1007.47518946777200000, -1038.6883179905717 [...]
+-38.57759727267461600, -59.84595548838074600, -80.33167556886176900, -160.81549746940917000, -212.06057154614072000, -486.21946256736720000, -612.15316242180347000, -643.85701355867343000, -699.83360723524561000, -724.21333666580995000, -845.57517093075887000, -858.68758054532782000, -979.19832176259069000, -1016.49742624187910000, -1060.90566391195920000, -1089.29920353477160000, -1143.76786579668280000, -1196.03337943250360000, -1221.45794614741570000, -1447.69820567427180000, -1512.77 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 88.71426312728866000, 114.51964422974615000, 139.17554422030534000, 153.58527164196425000, 178.08471899975498000, 201.08519533833081000, 211.50936307922441000, 296.63129160867459000, 326.91519564591385000, 340.27169561502421000, 346.1608458 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 77.08424730166751700, 84.86566535281612300, 153.32064927838343000, 169.03425894104399000, 180.28520639925401000, 188.48202687784260000, 203.16657446656205000, 215.40464083483266000, 223.36691757464376000, 305.10503398149041000, 335.22863339062798000, 348.51459709412376000, 354.0151 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 166.93969532939690000, 206.46027967580443000, 275.51156847594029000, 301.20764516330331000, 428.60328876763316000, 445.27650435469877000, 591.07941929740389000, 628.60668579901903000, 665.97839653572873000, 687.71110580276456000, 727.76366141031622000, 766.92502727686747000, 789.26951001185319000, 988.15509902671909000, 1045.01122765488910000, 1069.127620604789200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -19.51349079111507800, -231.58582946623989000, -296.49565480182417000, -322.92611822110604000, -333.97912617257776 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -15.07306329021170100, -153.99506379239972000, -186.10006344127834000, -224.88636247856002000, -251.21746478836212000, -291.71949206254743000, -331.80396725705947000, -354.54275306376138000, -556.28604283653408000, -611.41284369111281000, -634.82984727083476000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -4.63647870925929160, -6.95734 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -7.85400313374689410, -11.68019280996653500, -13.12 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -60.78572946236219100, -330.78684075241438000, -483.65361518609399000, -522.26280063648437000, -581.10090008492477000, -611.14590194251093000, -771.56068011017669000, -789.65769083786734000, -960.91369754103710000, -1001.41839453646340000, -1041.61349681198110000, -1069.41925736520880000, -1113.17149167178700000, -1154.77891347147600000, -1178.70276372728130000, -1365.78906033294360000, -1422.947428164945 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 102.08517375284153000, 131.28699113014287000, 143.53745753115015000, 148.46144544249310000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 19.41508076424258200, 32.93247691616723200, 87.09842138990197200, 114.20161015386624000, 252.44562649113072000, 283.86655115856024000, 295.40330647750142000, 321.96961409433135000, 339.86189603973361000, 435.11561606618795000, 442.96385689564357000, 531.98881674738266000, 557.16580665415199000, 576.86065352701939000, 590.90557250285428000, 612.62958701407354000, 630.29207834048486000, 638.31898896468192000, 703.41944308737629000, 719.77203468608411000, 726.2204009006 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1.610281 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 20.62025953081379000, 57.34363716577910700, 95.98093819110003700, 118.63100457128753000, 323.65576738069564000, 378.93261746248777000, 402.21185849305488000, 412.160187210380230 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.37010799392270100, 66.74788937954387800, 281.07182688116660000, 336.37969717936136000, 360.73343475088558000, 370.42153867539008000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq5[2700] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -911.32299086472858000, -742.24947537297373000, -849.56527160232315000, -938.40727926559714000, -921.38779351118683000, -1037.13707795467300000, -1025.22238752950720000, -1020.88477329849430000, -96 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1192.48753586459410000, 1346.09301339113340000, 1516.60854924798260000, 1391.17582769039180000, 1450.39749909034300000, 1334.51657286360140000, 1249.08727015604090000, 1206.76901921181370000, 1240.63189160583920000, 119 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -819.45003954418394000, -731.06614174896094000, -821.45221494250018000, -816.59937809101064000, -949.34004039193132000, -926.52405957586291000, -913.4120624 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1672.66389531943350000, 1792.45078733275550000, 1629.81882663433980000, 1515.96789473169090000, 1570.38176615785780000, 1338.99755089406610000, 1336.66271383962500000, 1284.72961863417230000, 1331.65346592810420000, 1205.25279761217480000, 1339.83412688614020000, 1307.61541694262310000, 1238.03809536991120000, 1204.7201089 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1593.60875202042280000, 1834.71454672731310000, 1864.11915448172680000, 2030.70321571613430000, 1908.41410320600240000, 2040.01954628594990000, 1980.45804092017740000, 1994.38886761888490000, 2115.18335564769950000, 2056.34923574189450000, 2086.57571169692070000, 2149.89231383966810000, 2041.50289399357670000, 1917.31249270300420000, 1976.93494699196340000, 1998.21971226835600000, 1959.97572019179690000, 1924.7746197197807000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -463.71287356354293000, -487.28121346912235000, -537.97214315374208000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 847.87219126338607000, 1382.30721456583430000, 1485.60917248207940000, 1292.54909402414890000, 1179.39120644027840000, 1110.83580937301490000, 899.55547487560932000, 889.70206322597289000, 1092.59351847679950000, 1166.58914607624110000, 1044.43632912102840000, 975.14465595123659000, 986.15685914574760000, 813.19897613908586000, 764.93776189872 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1645.45030486833870000, 1621.05579900700990000, 1405.43230269107810000, 1436.39826132474600000, 1171.18998562589040000, 1127.66809634154610000, 1059.56833550028700000, 1030.50066804354200000, 901.45278003477529000, 852.23464122389862000, 834.20447380760663000, 770.08442386386992000, 740.556415326274650 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1512.75419454164530000, 1446.30090591404090000, 1512.27692456785210000, 1533.12225807287560000, 1439.68214591171250000, 1352.05607483366250000, 1459.38053622466900000, 1416.38523033916020000, 1483.34070382169560000, 1585.04845567577150000, 1513.45664654179000000, 1535.32455732329980000, 1695.12717328053300000, 1585.39175863776970000, 1647.69165431094580000, 1567.93832287439700000, 155 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -1627.32267497125960000, -1501.05871246492070000, -1546.43789569211690000, -1687.09131140569640000, -1886.60351712160200000, -1654.72809764016960000, -1441.61226276570850000, -1294.15354483731330000, -1329.37835217107820000, -1460.27432406641360000, -1324.15160917382970000, -1509.04710563560680000, -1514.33885313756790000, -1541.12561819000350000, -1345.33026842820780000, -1311.54049460161760000, -1346.71306546027490000, -1324.34959510966910000,  [...]
+-2007.60137159546930000, -1832.10767612097540000, -1826.28567164723220000, -1657.84563723527840000, -1702.40337389872980000, -1702.06173980700580000, -1827.30465044554630000, -1782.96090473468050000, -1862.42950662560380000, -1878.56018450615190000, -1863.07112267088090000, -1890.95274379657890000, -1861.20750906455310000, -2092.34387689963210000, -2212.12390420356680000, -2187.35404562038550000, -2329.73097875047010000, -2401.17895396608760000, -2275.40392515758410000, -2229.50055618578 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 738.00738283290048000, 858.84388617946342000, 778.34348443021736000, 710.84833847615130000, 711.51880104826375000, 731.43341815961321000, 643.63116866336850000, 590.78107707821221000, 663.29850322237189000, 674.47552370498715000, 695.922514 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 723.35751803315384000, 697.45229214416111000, 654.33760535291378000, 622.27385862049766000, 471.94946992350509000, 505.47520686831245000, 522.89779325241216000, 497.59169877396062000, 553.43388185325693000, 587.56162091654357000, 669.83133167198480000, 680.95348002314779000, 680.69 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1777.76364018470100000, 1626.41557836154670000, 1709.66002113993610000, 1517.88173543168680000, 1496.68661514308560000, 1757.86359672120370000, 1658.20015240306750000, 1711.03418727078290000, 1634.78502630181670000, 1528.17365324558660000, 1599.84040347679120000, 1669.91331694745830000, 1715.53417346382570000, 1675.42986303144990000, 1676.54976972721760000, 1672.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -828.42266066440675000, -964.42910502394454000, -1017.49192112682090000, -984.26419880690764000, -990.426723732001 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1201.68929900322590000, -1170.75489385927650000, -1112.12899638239310000, -1230.36411317991500000, -1269.51228723100550000, -1173.58272042791650000, -1256.07744182326430000, -1297.15279386695810000, -1253.43595980591610000, -1223.74260093671800000, -1220.76570 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -280.00091553873062000, -333.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -204.37539116199267000, -238.92087080356350000, -21 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1828.59611947831330000, -1528.19015962823190000, -1958.68602221603780000, -1909.47198200087400000, -1803.12833429995640000, -2033.73565161304490000, -2116.47597719241820000, -2214.33204759555470000, -2214.32372362761360000, -2169.72618921005690000, -2083.61239921694820000, -2144.74309577858140000, -2065.80248795747140000, -2114.16870535293080000, -2170.43827931262830000, -2012.28984998324200000, -2057.84 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 454.85363750574760000, 455.65084806685866000, 450.06632187230900000, 440.90129973413394000, 4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 1637.24585512309640000, 1184.99116634999610000, 1094.60588700534820000, 902.43429442504885000, 865.53141412382058000, 587.05134926138408000, 709.91329198738390000, 873.73381174674932000, 1187.03697741911830000, 1233.72149658966850000, 1060.81105959833170000, 1183.55590276223670000, 1283.36488321602540000, 1087.42058901103750000, 1134.06051172448220000, 1085.63330705577100000, 1037.55629094499110000, 971.06527609351974000, 928.38244551200773000, 901.41106123484735000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -228.4292 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 818.06137196896066000, 856.93315248597287000, 986.88526694286998000, 1057.56328425928450000, 1032.14523699445200000, 992.92907049761982000, 984.70064563320182000, 1002.999940053 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1043.40416640021980000, 1035.84675213825040000, 1021.69579212976170000, 950.72071222943134000, 970.10807208290760000, 945.8063184628831 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso5[1400] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 28.76236508166204700, 202.19042079079085000, 270.54059097952461000, 351. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 112.48121324908175000, 201.18207131475197000, 201.85833778496740000, 230.59178471902905000, 399.73564209753641000, 462.5112018987640600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 58.63497029918410400, 59.10273782764306100, 72.44342463210898600, 156.43363893098729000, 190.37319287892026000, 21 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 40.21115313935818100, 95.50641125097914100, 145.20316955531624000, 215.02536834236525000, 271.98411416363808000, 272.51650714799200000, 297.04118252296280000, 453.76498249364056000, 508.939009748760 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 71.55553446705404500, 145.99503107149533000, 218.80879730676494000, 287.11382675436346000, 287.57461470890343000, 303.21700453172815000, 412.77185755196609000, 454.4349224851642 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.87719060075837996, 34.30149158356223900, 236.16158257161902000, 310.33915223507768000, 386. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 77.86401985938795200, 206.8877 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.13038205242027300, 148.42340336566306000, 166.69922887599407000, 273.44476877076801000, 557.84208299887348000, 575.54534334229697000, 689.24049163263567000, 796.74026972022716000, 947.41521688459432000, 986.11719885663410000, 1047.55333543588970000, 1105.90552950571080000, 1175.39370452083990000, 1240.25420290890680000, 1240.63381355339790000, 1257.27718235618840000, 1366.548768578 [...]
+0.00000000000000000, 164.21025945409917000, 460.28322246236047000, 602.26456186703092000, 616.99555309381185000, 645.75518072371437000, 736.87657532525793000, 750.44404487654674000, 818.89254273046822000, 1020.09033084399570000, 1034.00292288874430000, 1113.07404569779420000, 1192.77949245745480000, 1317.10691118815110000, 1356.30226336515580000, 1417.21106543817380000, 1474.83057088125360000, 1535.12192064590040000, 1579.41081910926370000, 1579.81215470964780000, 1597.16362832139090000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 67.45229137062551700, 112.03216756192003000, 191.06 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 191.64470919578764000, 214.19483932274281000, 263.74338422980475000, 388.78986203373728000, 406.79249608347328000, 509.15373595356272000, 781.34751478986300000, 797.81211936902582000, 926.74724721997609000, 1062.15022230893190000, 1253.90483198089710000, 1308.54970031206470000, 1394.93000760896480000, 1485.78108540934360000, 1608.80784049364800000, 1717.27899162346310000, 1718.05399960461820000, 1751.22485567904640000, 1965.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 92.43048226056770000, 357.62151476604618000, 375.84706338297104000, 491.71301637261774000, 616.73162480485053000, 790.60837414003311000, 834.21063045535561000, 905.11781531793201000, 970.72492434982894000, 1061.54834506989980000, 1148.07584912008410000, 1148.58309080040860000, 1168.57160504687410000, 1296.69203389658990000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 277.56057986605686000, 452.94091193496257000, 474.61598703563277000, 511.26230255349594000, 614.82836337127583000, 630.63688722156087000, 713.98637854108881000, 949.02592178552413000, 964.91315738295577000, 1062.74330952664510000, 1172.99256913872360000, 1356.60500066747140000, 1413.10052289931700000, 1490.56094827976270000, 1566.62271162670940000, 1662.00926465912560000, 1740.99925266742280000, 1741.70280834180520000, 1769.59101265101000000, 193 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 11.46364010762855500, 75.73812861026331700, 256.26615544535554000, 266.77362928558637000, 324.60108496923453000, 383.48538843596975000, 475.61429784194900000, 508.31621103112309000, 546.89067090443780000, 573.31540920195539000, 606.46900318782571000, 642.56741578830486000, 642.77237728057992000, 652.89277231281721000, 716.70473725965041000, 73 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 123.11819713691771000, 129.75418289060022000, 173.10806636861014000, 227.29135328372388000, 307.46179668186358000, 330.25384885328214000, 351.60452425307136000, 369.42838256527244000, 382.73425831370099000, 386.47791116503043000, 386.41232093693355000, 383.61519953710547000, 359.69005502098003000, 348. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 77.21402842479213300, 88.25541151033233700, 135.18311848895854000, 267.69224117678573000, 275.00710863328987000, 307.89112943033257000, 345.40372184788555000, 409.61803782631830000, 429.18151355994792000, 461.58753853598523000, 488.56903122897563000, 499.57188627400927000, 505.74576779053166000, 505.71905251735711000, 506.20011781597879000, 505.20473178116009000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 19.24086316020940400, 45.34717543535025200, 121.64305071879271000, 133.27149959530405000, 193.99671299017081000, 388.25642037725618000, 397.33276705772079000, 457.03207818572474000, 529.25711843676766000, 635.25482525410746000, 662.60133669402057000, 692.21241343703082000, 712.10454922722681000, 747.47568825747635000, 779.36952592107116000, 779.51162392733011000, 788.35543240888364000, 837.752146875089470 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 89.23859698545805900, 215.14906274110123000, 252.96210208516970000, 299.49619317283157000, 345.88566338552204000, 403.78105433658101000, 451.36253763874322000, 451.63097278725610000, 464.29843155043903000, 546.17417636140317000, 584.4901906 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+34.89110251440218500, 173.16279189172727000, 405.11803550890136000, 546.58848024214683000, 561.42480509152756000, 589.63935590251276000, 662.04768544409126000, 674.76991831511123000, 761.11170635638541000, 1023.93225085579090000, 1037.71463762519760000, 1125.62982845735110000, 1223.36979252761970000, 1367.06214595457690000, 1417.03596870555570000, 1489.80568817789090000, 1560.91264355885820000, 1656.67425515502960000, 1749.30564922976050000, 1749.93490914764450000, 1769.77962712826250000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 107.49742 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 59.19306030441228500, 160.90547394469820000, 256.65085478599457000, 257.28833759225819000, 285.39114204644829000, 451.61185478499766000, 511.094775097125250 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 76.66540104094463000, 163.95112134042725000, 311.49426607428529000, 362.90594973885254000, 442.95804303660492000, 524.49460451046400000, 640.61285756751408000, 732.14708944038239000, 732.91666876259410000, 769.10894554468280000, 979.97233826494221000, 1049.7325 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 122.62358580547725000, 161.10633667622685000, 211.98245094323309000, 274.68418447680170000, 345.72926518884094000, 404.81514627074546000, 405.27837203013331000, 424.61271895201025000, 532.77562555518386000, 564.74575403 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 22.24809691504145400, 175.15561907364824000, 336.32250038537518000, 574.18276703202162000, 642.86769257215042000, 752.18213743236140000, 861.31960414969205000, 990.63190226199083000, 1101.35651157909320000, 1102.28981795344660000, 1141.48548804652090000, 1376.90005567275420000, 145 [...]
+
+double nnlassolsq5[1400] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 436.09716356746708000, 427.16587311283007000, 460.82842712218377000, 443 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 619.91537151874343000, 573.20674235245838000, 616.38959725883751000, 637.51704220248723000, 619.15351924335732000, 637.2792442347969200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 304.55880928515859000, 345.83033893328968000, 261.37524424189445000, 265.38796223959218000, 284.86138892241354000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 535.59451232435470000, 516.22593171563256000, 484.92750271734587000, 530.01280176900866000, 510.87761687576733000, 598.85759318314251000, 644.36149757461533000, 657.07123328369698000, 662.5442784505 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 615.99299937227829000, 654.85937570328554000, 547.29202675254624000, 573.59534073983582000, 570.02394431265054000, 524.74571707766120000, 554.88930510981936000, 570.425481854922 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 538.56897415932008000, 507.65898032636778000, 498.01982165591750000, 516.85055056232716000, 4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 294.63854743553435000, 353.337 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1526.95658099748900000, 1602.44498892142810000, 1650.94404613850360000, 1760.19680118410270000, 1620.34470611613550000, 1748.66801812216540000, 1750.49913988838650000, 1620.19328575329000000, 1559.46466437003210000, 1462.90824660354930000, 1514.99634598570740000, 1504.79795016449000000, 1488.87426345128890000, 1512.28883822548620000, 1473.32386326175130000, 1492.98183523022840000, 150 [...]
+0.00000000000000000, 1898.42947563323560000, 1988.36502653769910000, 1736.30878900468130000, 1656.36402142747470000, 1799.71170760357180000, 1927.35979784177720000, 1852.30652181275260000, 1772.24331879357010000, 1771.76120444638850000, 1955.93350946116110000, 1851.14347232017370000, 1803.32671121568070000, 1822.13133212525620000, 1839.17141060377840000, 1880.64179847694460000, 1868.71437199163690000, 1807.11303307297930000, 1765.16508621293250000, 1825.81895709614720000, 1842.8965152729 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 154.95318445978029000, 236.14317054150507000, 280.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1722.36400678967560000, 1805.25506398488100000, 2251.83820689903130000, 2022.49767029684950000, 1868.85046278323530000, 1934.84123134891020000, 1798.25797610950190000, 1888.85414148307000000, 2130.25963586083210000, 2099.34295145113860000, 2032.82199844576260000, 1981.74995254804480000, 2052.16324432123700000, 2106.83410528190600000, 2163.81588234868560000, 2172.22323000134340000, 2193.11087242013400000, 2220.9930383829583000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1379.80237145901830000, 1348.36985720028930000, 1583.57964642437670000, 1573.23449286209120000, 1574.37964980725500000, 1496.90474499636780000, 1371.37085877987120000, 1444.62224719275380000, 1419.21154856903150000, 1471.27815427994370000, 1510.98514821785990000, 1459.50717452069080000, 1451.65046172287500000, 1462.8932365 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 1710.09689561903110000, 1853.75213100199540000, 2003.93531535374000000, 1981.66572787351450000, 1967.89871929407540000, 1914.50335771794180000, 1874.87821291732390000, 1827.12890918995370000, 2017.69529792468170000, 1975.91415792149060000, 2017.50673426570620000, 2102.44821736384570000, 2109.10000058475230000, 2079.92636828130480000, 2086.57678335767100000, 2092.32463777894510000, 2072.29508164692330000, 2172.96153941361540000, 2164.5458798939553 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 942.46664224792062000, 970.95329645539982000, 930.71521829629194000, 963.06095588586174000, 864.37686585110634000, 834.54173617261915000, 849.84670449316252000, 911.18910431238760000, 840.38831996728368000, 753.95348104822040000, 756.03412230314200000, 793.96955964055542000, 768.40768418755022000, 796.21857529698843000, 799.48330280817856000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 583.08529551296738000, 569.49382441109833000, 577.78394276587778000, 642.33770800717957000, 633.11829439389999000, 611.04170212043255000, 514.05328066656205000, 491.27130725677233000, 442.76077888023372000, 402.17935138631981000, 346.20745930375858000, 344.00215386077087000, 328.65372593698754000, 318. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1086.00022824741310000, 984.96541844594583000, 788.79228844347540000, 762.74364777994242000, 759.73346466985799000, 614.83871677297589000, 632.75182539730713000, 670.45991867583530000, 670.19475415696513000, 708.15203165331980000, 673.01304580049282000, 549.20883743292075000, 531.63995066877999000, 489.34338357031265000, 513.01300110691091000, 503.9134907388573800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1376.81050422328490000, 1092.84159470731290000, 1118.43375908457960000, 1077.65920826583900000, 1039.77757205510030000, 1114.00676448642180000, 998.78514862264603000, 1014.28022097994720000, 1082.50409518281190000, 1065.82300605131100000, 999.49808402543215000, 917.51126243802969000, 848.08610611487416000, 907.04477221737397000, 913.13705335743850000, 866.61348110570805000, 913.60211971894137000, 901.8308 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 772.81016468078383000, 726.60390277040744000, 718.80177562898712000, 653.55549511404251000, 663.00155527601487000, 664.96332759218558000, 650.92639822583703000, 616.17374564518036000, 643.69594451498153000, 652.38555402883401000, 691.162514 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+1800.89324550394300000, 1633.44561203268130000, 1602.27762593518450000, 1676.55205033546670000, 1608.22525436252700000, 1721.72512141734730000, 1608.04836801305870000, 1707.98771699369560000, 1963.68025375524850000, 2005.82449796664330000, 1951.01705300675010000, 1946.25197449140230000, 1972.06220503703890000, 1950.74793564934680000, 2032.69103584324810000, 2043.48140154460410000, 2046.99591788528730000, 2088.68162217412870000, 2137.81557641561040000, 2135.65254825186680000, 2050.8220301 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 229.51324 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 463.83359674723494000, 619.75857047773616000, 658.22130841669104000, 648.04636303335360000, 683.38519283929838000, 667.23775153359657000, 676.69606273673810 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 792.27922537870381000, 832.56356795089982000, 910.82216971119203000, 996.27481799400061000, 1052.04242847225100000, 1081.87409806616710000, 1164.45471789016510000, 1116.05535418322890000, 1204.64593489024990000, 1281.66671775562650000, 1253.50989804110870000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 620.72694906104039000, 635.19655565012533000, 599.07847198561160000, 703.30982002325311000, 666.23346041370996000, 652.63017254923409000, 689.22200359687633000, 698.42720830005658000, 673.08740347379319000, 653.75104186 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1496.53850757551210000, 1602.43226820370270000, 1570.86788142466250000, 1540.38350258633550000, 1489.03514819124190000, 1583.91206133667310000, 1607.37738273728680000, 1573.99578367056530000, 1565.75209077942780000, 1674.37890395002340000, 1696.57754440379520000, 1682.2860476816659 [...]
+
+
+
+// Data from file x45.txt and y45.txt
+double x6[5000] = {
+-12590.9515597006, -15621.968391713, 626.151771369557, 10885.0341032725, 10074.0201793363, 953.811588855134, 15862.9388321539, 4364.66579200027, 7638.25388883435, -7775.80650373108, 15080.8095548610, -2243.2382242446, -13043.9906460957, -5427.53319938344, -7603.90738690411, -16734.0897452722, 7252.87971551491, 9605.957967065, 15872.5175068131, 740.578456509333, -12095.1600803297, -1691.99867783081, 18608.7531840084, -10584.4995727237, -12303.258677107, 5590.94465969832, 9286.115156189, 3 [...]
+2105.87373688329, 5052.572656469, -1915.86258630896, 7204.68296888948, -6421.10685623071, -12198.5709978813, 13033.6346338013, -3065.33317274384, -2004.68470724165, -2883.18856222599, -12505.3815012690, -9825.13168513325, 9322.61851660428, 12280.4333594396, 982.067852018721, 6569.23456420976, 6426.7917049068, -8159.4142209856, -3316.97041945172, -6331.75932802109, 21196.9838380968, 17647.5101306166, 20846.4784654462, 672.201390861607, -9599.23372848055, 4124.82019973576, 13025.0012428352 [...]
+8739.78448506748, -12204.1388378674, -6497.29855694829, -11633.1675625218, 4244.2692408111, -3772.32854180873, -3136.22724567149, -3900.68594983966, 19378.3273557344, 8140.8247699583, -10209.4394207484, 1767.09273503008, -7880.16162871178, -10017.0726821550, -3706.65903836589, -4275.32251161477, 13306.9244139052, -4871.99592249834, 5166.10995460431, 12141.6083619081, -621.069893386103, -23108.1465243992, -18514.1320719569, -5818.27754518352, -9572.58695125821, 10343.2358376460, 576.03472 [...]
+-1300.17188513776, -514.529964980431, 9931.0195198119, 7742.31908324298, -18260.6600929257, 7812.46233029526, 7214.92468433866, 10990.8159289235, 9923.92150436009, -8072.43837564, 4417.80850608645, -497.292627338319, 1786.21080755980, -9154.16244945972, 19066.4917373337, 18029.0634280511, -12002.2956835118, -4215.55518389023, 384.414298777938, 15878.5505844362, 25459.4963215367, 6434.44546255672, -14310.3807622864, -6568.8989506015, 1477.88405500592, -11667.4853500534, -4501.35938948763, [...]
+2935.85645870262, -16384.7515919466, -11263.6836993177, -1157.97645677919, -5136.3599862556, -346.562565559540, 10883.8668132474, 711.963235512692, 10316.7331453283, 3563.23541620209, 4447.81556552038, -17628.4655923098, -2945.20470373104, -1952.85446022429, 12705.1426720701, -3138.35773887923, 5302.99472374311, -9083.51131699486, 11362.7085420858, -3675.73564923605, -3356.98292362227, -3621.61824041120, 12518.5799888594, 10121.8346788133, -11758.3804772847, -331.022685711518, -15463.930 [...]
+12546.5577447885, -6370.01369244788, 4922.76987604537, -1080.78171780406, -7639.44978890695, 3101.98798661741, 2944.43167048372, 1789.30698450816, -3798.32091394159, -7843.5804831542, -13019.0583381054, 5232.4668434899, -8573.96875789472, -6482.66012012381, 4978.97445354294, 4827.52798525495, -9800.62792623162, 1330.49433431640, 6948.51790367801, -8053.67375631203, -8798.9711957503, -6947.80777150119, 1951.75770108488, 3139.85226489158, -15898.7791711253, -7546.7822597117, -3809.44587807 [...]
+-11463.6983762727, -20839.3877872420, -14327.4469656675, -620.676953876506, -723.257555912207, -10757.6307375755, 12692.1025383799, -5986.48499708004, -18678.9781595130, -16787.2483221977, 16573.275691817, -14658.1484871455, -11715.7610935250, 6956.81148477195, -5158.76623763213, 1949.5323532305, -5370.97281824064, -14283.1497340502, 10999.7963566343, 12099.8828822281, 23755.0326375802, -15445.3821940144, 18784.5188265439, -2913.29430578933, 14387.1743363990, 927.79087408586, -36.8944594 [...]
+-959.278948177012, -12698.6918278613, 5626.35909794419, -2361.59461790082, 513.025915729139, -10825.0765639089, 8304.26297314625, -1298.75748489305, -697.967289771252, -3118.88477539290, -1213.17273805899, 4245.20930588182, 1206.05560509691, 20300.1178136885, 3363.78610697125, -4733.2422457271, 15760.6351501566, 10928.8619886429, 11773.2734584591, -2257.16326535022, 2946.4546315268, 1826.11370690754, -13516.5950958892, 27329.2257823788, -5617.02615958979, 18669.5690618526, -15718.3244646 [...]
+-891.043202986647, -14922.0392599207, 3123.97332343549, 745.247335592406, -887.907856396993, 2483.83179606483, -1542.21735234352, -14351.4292725259, -8203.49366488565, -7406.68061956991, -15481.3040208492, 851.902458744027, 5107.79589948254, 2796.37567511416, 998.216649311072, 6059.96246709255, 959.786364621126, -2703.42895067783, -6651.39953884378, -7941.20189649876, -6431.29077047163, -15684.4909254283, -4127.5880198437, -18326.5229509114, 16320.4165302176, -1354.55759129118, -10773.31 [...]
+-9646.4872909255, -10933.4951924182, 7197.33168718149, -18.4281894470621, -6755.11492870254, 18550.5889140620, -354.667029135297, 9339.90095963752, -2688.02538242174, -6291.1530198052, 3159.88299091888, 2678.13904183375, 9124.6590031416, -5527.03768018781, 8250.90383478693, 20129.9839564819, -9552.13310512573, -23022.1065303801, -5084.08202436145, 808.235986371808, -16863.042646772, -9561.06843115868, 5230.61071023063, -966.322162962247, -3883.91437947343, 21937.1092191124, -1339.8412719 [...]
+-14545.8978417733, 10115.1430566030, -2039.36773960816, -4313.60145126086, 7812.11634550758, -8897.96470794122, -11677.0722261253, -22385.7857204468, -6558.36647951804, 11450.4051369106, -4176.26014666709, 18202.6525985552, 722.828187291806, 4459.89195139689, 39.9195338383582, 5435.48229797906, 2225.67513650356, 5222.98346179262, -2225.40440922065, -8206.47524966045, 14367.6695901520, -14065.7984558153, 3228.13317488511, 16202.5394678690, -2518.68807045287, 15089.0539605943, -4499.444442 [...]
+-1708.91000866089, -3888.17830436296, 5013.33951549976, 8070.60208551246, -2101.21704095577, 7531.86999774887, -12159.0165533065, -325.968128599549, 8935.80144320306, 11475.6753199198, -18377.2187413733, 15621.7183399524, 564.529934760389, 9012.52318062792, 10681.2581617743, 10667.9419731515, 9129.21942564296, -8227.3421079726, 6331.69332914684, 15082.1003470688, -5626.21990006838, -9091.91394598423, 1948.16907326292, -87.0410495395123, -4712.87034399912, -1354.89648445311, 6849.43578570 [...]
+-6266.60635191261, 857.833682910964, 7716.91232285504, -8098.11318088832, 2431.06153574627, -16253.7723789741, -10861.9524583867, 2570.17204215927, -5197.78730622671, -102.406679339348, -6226.55936621808, 2225.38120239039, -9975.73437758618, 8081.22967139674, -11465.7858024679, -5225.07878270934, -169.085371837266, 20828.7967304732, 9858.2726725715, 235.294435913151, 9758.0557609745, -11128.5513863075, 10192.4856794309, 9331.0508516705, 3041.12378269138, 4147.490997162, 1456.45691699505, [...]
+6804.22840674152, -11095.4035479377, -8663.90562052087, 589.688660196004, -16350.2941416191, -2957.25866813208, 3856.35552390110, 1001.85356524382, -3122.39824925953, 24887.8264110683, 5061.20535149367, 4521.52257449599, 9210.98274020625, -9501.64406272485, -7758.15870752504, -8969.70709389836, -8673.94939823906, 6494.18155521918, -5320.76167153775, 4262.29693546734, -15416.4025730678, 13860.8910771297, -6080.45413916898, 2661.64875595026, -346.3430023798, 1688.69076475938, -6155.4764555 [...]
+13197.4590077882, 1750.32867835039, 10680.6246755623, 1642.74706035484, 5572.91104768803, -375.175313380488, -9465.49323698068, -2263.34177086924, -5123.63838253831, 6906.17400149888, 5312.11175926218, 6511.35119343118, -13249.0884050296, 13724.4380179780, -9026.77307982201, 26087.3428852581, -10998.0889641649, -11828.8662942379, -3067.75778575022, 15643.9522022938, -13078.4391708217, 7171.20941505628, 4812.4272425847, -15648.0562305970, 6955.93347796, 10355.0470270457, 8014.77804548758, [...]
+5951.3023306698, -10324.2381242188, 9849.39434031862, -7342.217177268, 385.501572756001, 1250.14068687068, 17601.2965979632, 2572.30890643155, 15404.5448666952, 18096.1036130738, 8970.47503934864, -17391.8406060759, -3117.47459784083, -7722.69234057626, -1739.46421995224, 3685.83277659292, -11152.5069821527, -11144.6658829513, 7645.34889824307, -12749.8531241671, -15929.2193430215, -235.352522644929, 3272.48734344718, -9645.91882964826, 14574.478713861, 2081.92776871485, 3576.9488964515, [...]
+-1221.66645137107, 13239.6797532353, 965.348362862753, 4562.88749738183, 11668.7809179577, -11529.5329852483, -5901.80531288153, 5894.72251546058, 10590.3049563071, 6502.17999327929, -5255.97972831003, -1617.60973195231, 2828.39435865254, 20068.7209848397, 5015.15282729674, -5752.45983848749, -6506.92326058959, -5878.17964492697, -14482.7183895154, 6966.50858501838, -17562.5797424129, -13207.6207391526, -612.17654151672, -16009.3169558841, -6514.65446012382, -9004.93668430612, 17249.7761 [...]
+-3449.0862542362, -1824.28803557735, -9221.79618304894, 6661.56223067155, -8716.40448367912, -2625.02318317662, 7834.22088285589, 1861.7928032373, -6442.4464563264, 5796.98278799984, 8330.23578245855, -3343.58572261788, 4574.51397573743, 6475.38365810944, 10514.0915823965, -15135.7240886577, 10160.7256375307, -7947.95973658722, -22032.2734750160, 6324.71677935926, -6276.83225903764, -13436.6023936227, 6180.32177067974, -4349.29169787149, -6388.428326609, -11559.9539379906, -13525.5745873 [...]
+-13510.4041068304, -7206.31409074131, -7417.38828530889, 3796.04963425309, 19984.8912528473, 1396.03289533661, -10633.9610882165, 5563.84851115703, -16731.1179035738, 12893.7223430161, 7885.34531753645, 11504.3613556289, 2628.03380744346, -6228.11623563935, 11737.5620858416, -4018.30931242601, 15432.2132307438, 16809.5030333036, -10288.5265837303, -15291.4313815073, 6923.05041678379, 11461.0990346558, -13836.7824069800, 7393.18712442381, -4005.37997329513, 17309.7681190500, -2755.2378878 [...]
+-4319.89377915202, 4135.46327085675, 6712.41232207561, -6956.5704325231, 2824.15579377439, 17041.9670471178, 13445.889996278, 13811.0751695337, 2338.65107587519, 7587.32642703751, -130.613520761151, -2007.83003348925, 9539.04202037602, -2043.36068585174, -13952.7845924673, -22286.2059015981, 79.3947454301136, -5252.00444608793, 223.418809095934, 508.541324125202, 165.952114379561, -9941.4175530332, -2884.3243947212, 8223.4674889734, 23995.4602859817, -19561.7582840715, 13683.1944788893,  [...]
+3278.11142804714, 16043.4421597185, -17543.9754097060, 2114.92670926610, 951.951183179848, -4230.71113812929, -12289.7394223308, 10715.7580994625, 4414.5401878113, -19254.3304636605, 3843.67828593345, -13252.0232803961, -5421.11672871821, 10860.3847781033, -11087.7435554460, 10678.2941393745, -8266.18624679838, 12022.1394505461, 7237.7266037622, -5766.1896288671, 282.011751307293, -13723.6413431228, 7392.98282602718, -4815.01953620322, 19382.6120337156, 14408.7023022592, 16520.8769354148 [...]
+10947.5817295781, -6494.34408709946, -6592.20951206595, 2174.32921361055, -3605.89935340039, 2573.84349043795, -6180.71053383419, -777.990042974924, 1453.27451400772, -6218.3211034369, -4838.99251606779, -2775.20393553253, -713.625424604178, -11970.9510620322, 7358.82004422134, -4857.08495616361, -6785.34779454498, 6.06634788435305, -14463.0671031416, -2303.52452404693, -5426.96354479926, 2056.26141056728, -4361.58861628385, -18168.9770725176, 9297.70702208322, 8998.06842354323, -7784.19 [...]
+-18766.0638679961, 13928.3837594535, 1248.50236921829, -2070.77006993928, 13991.8055813704, 8423.87848868694, 6918.03809662725, 1963.34649212394, 614.706544731045, -4080.69724106136, 2211.86243585462, -20627.0702782697, -3952.77440858132, 13648.7804029629, 5898.08776350123, 10578.4546854358, 768.225901146753, 2999.58561575734, 27606.5625813238, 12516.5672151642, 12628.8325440374, -10196.6790531593, -1051.52738396418, -21701.6882820359, 5479.11720358416, -5668.23019502928, -9953.964773865 [...]
+-5479.42967473282, -15883.601863063, 9727.23520622118, 2675.64121456814, 130.268771037701, -2206.80866904705, 4396.52043018254, -1625.52743881940, -8751.13363644296, 15360.3527215115, 7299.65134663224, 12407.6396689182, -24458.7421691153, -20331.220108513, 12737.5896909926, -4762.9660166585, -4446.86716023757, 5824.93811122807, 4750.19999471683, 11422.0683072306, -10415.3099415966, -3513.01706356425, -5813.03898761825, 11046.2452799014, -2857.45775295009, -18503.4556697873, -3648.8098233 [...]
+-531.494791571553, 16537.9041938062, 15690.5149875825, -9926.1220824401, 9635.15695411145, 16722.2069557217, 12033.6279343425, -4697.19240178057, 5982.75603916529, -4293.19852183577, 4585.88404117632, -1154.95683705615, 2090.50330962282, -7378.1806430255, -7484.21738275244, 5502.96583126298, -894.739499046717, -8954.0774744125, 2624.88029083869, -17400.3094445815, -8571.57562112401, 14718.1552401991, -19824.3075925574, 12811.7811591110, 1100.33445246691, 4145.44632093751, 12034.441898043 [...]
+17999.0565593070, 14489.429373436, 13242.1057645332, 10864.0134772785, -17154.5363622697, -2241.21141646652, -2381.19471556684, 2359.32389509173, 6818.03467244529, 2915.50356884291, -7801.2215814142, -10765.5316542653, 12001.9496298617, -1544.38031339496, 10251.9668632977, 12476.7180609656, -15641.7126584847, -5975.95776006166, -153.058102461556, 3081.17268764322, 5935.67627440935, -16117.8176612043, 13059.9636371484, 12160.3704682406, 10428.3945202609, -26582.8134402063, -8150.184481361 [...]
+20034.5344238268, 13954.6841860076, 4950.42528344629, 9188.24623408593, 7885.92228477295, 17476.7681413473, -17653.5274317992, -741.71338627305, 17558.6435477632, -461.197065051932, -12593.5917573992, -5219.80162226389, -4124.29122601384, 2816.68159704069, 13643.3747072499, -24279.0129788532, 21032.7936104989, 5734.74046415006, 4355.40483946589, -2300.21611169652, 12909.2282235755, -7846.59575463922, 704.208580510725, -6314.09607225414, 8860.31571288057, 7154.30778513465, 11446.322980110 [...]
+16983.9692663674, -3134.52010829995, 40.6621798575417, 18738.5945997372, -3112.86320264302, 5035.85309909385, 9336.79040320516, -11474.5290937352, -8865.44774263701, -4577.44186776585, 3542.64477534316, -1992.83440627443, -2526.65719248167, -5369.64139913545, 0.857293434068888, -5229.2215979864, -5476.12997143032, -1437.18086166109, 915.653132466829, 8565.56354144535, 616.214844012755, 20780.0749136630, -7638.54138128914, -7662.89793395097, 5139.04089506983, -11942.8195657404, 11889.3946 [...]
+9587.17692855698, 13504.747984501, -12147.6509059655, 13092.1885488289, -599.385530745206, 37.5030750846757, 5918.45574190997, -2084.14314414689, -26821.1828754027, 8757.34291042872, 3789.32439352922, -8429.366019571, -22526.5372694224, -10925.9988886983, 4034.36105153382, 12564.9338537719, 9416.00055608813, -14528.3022289365, 7481.52283832529, 1812.82182925885, 14557.1719145226, 855.454329488083, -12057.7922981979, -22730.2417548185, 3764.09454793487, 3168.31005007124, -16084.2711124613 [...]
+-1952.76126441727, 12159.9156950686, 13195.8878892015, -8170.62642206778, -9353.46547958336, -11821.2732755309, 8211.62099045479, -1738.57718884245, 5509.85346134558, 4743.64175945028, 9454.2378026217, -3488.89655064102, -1816.61206746122, 10644.7982860686, -3283.66588579032, 7964.23905043564, 12844.9830403304, 8717.4388126623, 5827.6243894974, -14335.4173974201, 6593.84995469325, 5567.6295085991, -6548.98133757624, 231.200910197915, -20391.2542577495, -31110.231615875, -7359.86088246483 [...]
+-2333.40350631104, 30283.8828918175, 8557.98028212741, 14421.0469289582, 6722.09498023229, -12864.5103582044, -267.816557013601, 17384.4845228442, -10781.7575952475, 10160.7514901845, -17324.0424714471, -24961.2692136929, 17230.3009059909, -3023.57105121716, 17304.8757869626, 4151.03345575499, 5526.04529120493, 3088.35552003993, -17403.5655106349, 2471.86777421784, -3920.12870471979, 8047.59820592016, 6154.33200020476, -4877.78850971213, 9230.57853519115, 18029.7972461808, 884.1056291744 [...]
+-7846.5806683534, 2982.85507207971, -13462.0917415641, 2330.07776847878, -6152.86278806457, -590.791812747659, 8702.78596657142, 317.582630878106, 5313.51805058653, -8135.54342807533, 5340.18091404478, 3537.42919892372, -12709.7751833319, -856.81428244995, 7001.21738211235, 1077.75372258000, -849.474819541405, -3505.19708533238, -4104.64157108772, 3727.71528603314, -7445.3967160681, -1061.01633738029, 20.5712677278694, 19801.9351394053, 9926.09777759055, -5081.47019669756, -5452.20178166 [...]
+-5992.29932998208, 9415.6003090869, 5410.80579425239, -5674.33289602219, 2319.26761276844, 15514.7351379771, 22806.7215104306, 2672.06829789593, -385.648377044236, -4722.24648311303, -4645.85124417948, 18956.0212114815, 1340.65760588880, -5952.03474088967, -8893.25544816186, -17899.924229186, 1794.67871235867, -3238.43063114196, -6374.65345187037, 8290.24071931882, 18129.1310337988, 8138.67886658853, 23921.862776236, 9924.60146402037, -11864.2382646098, 22730.0490438294, 3000.99644087733 [...]
+5091.85121220634, -2509.15140603692, -11169.4521204852, -3734.33174565015, 7996.33617465644, 527.486900777118, -13529.4465913048, -15996.906549415, 7070.75384890724, 2029.22872414146, -16123.4648823246, -5320.82413700907, -7799.15111610477, -4588.92108168735, 4623.41657247164, -20609.3143501764, 23194.9664916725, 13377.177285083, -3769.16682769696, -7327.45948106056, 2021.66908364264, 7381.14082697692, 5240.73045574049, -12485.9591825708, -10441.1174819031, 4706.95564466335, 12252.532761 [...]
+2082.65119858586, 7206.88227238565, 2602.35812295304, 12922.792977238, -5376.88162185514, -7674.24237862516, -6064.77951694326, -19960.5412589148, -20345.041438289, -15184.9620067399, -12248.5913032803, 4730.8419761419, -737.418577796003, -11368.4263208625, 4830.34746828089, -468.60657018667, -11401.7758118729, 19010.7914602223, -14792.3978215630, -6845.79098017996, 14960.8529231398, -6721.5934563389, -13532.0119095128, -5081.03934667458, 10929.9540767117, -2789.44111370313, -4674.278474 [...]
+11240.5433999217, 12345.7568297587, -7981.51609322617, -33030.0585703719, -5938.5019249788, -7861.52406423593, 13021.4105052671, -13740.5662239852, 7184.20361011326, -11007.8542769822, 1463.06540954738, -6495.47163253433, -1758.33980290126, 2233.17200055018, 9957.70670112814, 19629.7613086343, 3041.67087569202, -16155.1043702040, 20092.7174105430, 2426.79720260483, 1947.75602317983, -5549.72274625947, -1344.51767491347, 3871.22898049828, -5472.4196404689, 12640.9495417934, -6614.35656589 [...]
+10053.5379744449, -3810.68486883429, 24833.7747774115, 15603.9807991214, 6818.94477695676, 2939.59865670045, -15835.9747101846, 8205.86306195261, 12439.4184748846, 19132.6373739545, 5798.08520259424, -6168.19904910964, 3812.49350975724, 22345.3209782356, -4566.1817636064, 4975.37885456175, 4255.05720473393, 20338.2112293075, 1099.58947215463, -2861.21528461822, -6736.842841108, 9142.48726193827, 5587.52367380804, -1429.09256947160, -3015.06445779448, 625.7831322487, -2584.56080610188, 46 [...]
+-4662.89939667788, -2945.16188682781, 10904.8288475442, -11818.2794559505, -12233.1902001014, 157.494436611241, -4958.7241981266, 4405.28323899074, 5680.32331981217, 10315.3922105142, 1557.29883518580, -7504.8518827169, 22328.0687142792, -2290.82546217898, 6373.01628390354, 21173.0832469034, -1372.51489866193, -3318.08766132227, -4911.18999268751, 5421.1718581875, -2661.03417820774, -8825.45452504154, 5033.01163293846, 3216.48612984425, -6872.4086048032, 12225.5981011212, 3871.2061783987 [...]
+-10240.5341843884, 254.550704702329, 539.60300324885, 9828.4093599153, -7667.62729854008, -6318.59664849481, -9969.6297903649, -145.635399648651, -7668.35470608636, -2780.54891675233, -5646.13574447834, -6366.72882642146, -9535.97601790758, 8385.87191225733, 5437.58136474467, -2150.60580894266, -11905.7683723041, -19154.3125387107, -660.855662882727, -19028.0292540989, 2729.44604916929, -8080.25282687262, -6827.1915598096, 14870.0893398506, 1138.10074677864, 8743.17250602988, 7514.834521 [...]
+4342.57460408996, 10502.7399877592, -4713.31265534144, -321.896403484624, 10429.6946242882, -14595.5617322175, 9780.26196708965, -4961.6444364218, 16005.0694876478, -3990.32309886863, -8716.98311593361, 14943.0618415675, 500.661371447465, 6657.16165946336, -13859.9750770819, -10311.8618209947, -13070.8261740779, -6231.29949589838, -10412.0721429945, 16729.7750653024, -4307.28792191246, -74.489478863978, 17698.5240107682, 27043.3568039810, 1335.55973695414, -3201.43491518472, -17204.66662 [...]
+-2581.30273911711, 6843.49970285436, 9987.41916275069, 16317.0125175189, -16811.6161241593, -10857.1369310650, -2218.37422463070, 17473.8585186131, 395.75666710943, -23804.7577769629, 11446.5972310969, 10415.8962351884, 4203.56257471835, -1816.95894332925, -7854.07082130239, 14651.3963926145, 2843.89312657529, 27951.3958506867, 6011.42783061027, -7779.17323583485, 11726.2432280732, -8805.7195900516, -10216.5304941156, 22964.6552307835, -1481.68433320381, -1628.03923208477, 2571.048238106 [...]
+31.1275560339141, -11942.6015631241, -5676.20815763897, -11837.3741720717, 6504.53150154155, -7797.49950742892, -1663.84940091876, 12182.9784963511, 6855.55247398706, 9497.43405564485, -5243.1973054447, -8025.3802040656, 8504.78665623319, -980.50700712974, -11391.9294818563, 658.222104385183, -8912.28570131452, -5382.49040254393, -4097.62161496576, 7655.79806173996, 9255.52625589183, -1859.82161691282, 9186.55066074374, 944.869250331434, -9848.5354415384, -9244.55536907666, -11706.028309 [...]
+2772.76312383191, 16250.91379056, 12606.1209488096, 6999.95705542076, 14462.0574239535, 12329.2670764344, 1795.3173549456, -9727.52122186475, -12765.7162485587, 6227.4681753719, -2322.68844845686, -7234.24061131391, 7693.74428228268, -5534.73162280946, -228.455615757844, -2012.06573185027, 14485.3301271262, 16687.3395284833, 10348.2058806398, -2492.68737435502, -2879.59703048273, 767.243906504057, 7868.09336594841, 3893.15960460659, -7240.48671826772, 10450.0768760679, -9278.66718218362, [...]
+-454.118226222514, 10569.4866353392, 2813.17822573304, -7754.75184387826, -3110.85801114529, 5968.98789663064, 13601.6031410859, -5317.47314871697, -14531.4309982165, 12680.6242709388, -4409.27961532714, -10635.8373667656, 13026.9413813318, 15058.6950247580, 10201.7129519065, -3701.64152290841, -5429.24275512941, 5886.2780463273, -347.835099587326, -377.117062657255, 2736.59945069758, -405.095953758229, 4727.72704907871, -2060.54581787865, 21240.3106050040, 22724.3400967447, -9625.016048 [...]
+-2489.37840896606, -3872.00764199807, -9758.95123810647, -13995.8700924295, -7104.03661459467, -8987.65552561943, -4630.86936472198, 5498.46487717134, 870.848542157263, -415.55695993313, 629.549740996819, 2059.45755203154, -14759.7794878365, 656.871766497969, 6948.32013076284, -7439.31550459859, -3452.4572035397, -9838.09397962584, 5961.76994954292, 11633.9776455512, -18671.3907219035, 2221.49548743999, 12041.5424610891, -6870.58082979538, 3754.12853647334, -18384.7426419882, 11861.55563 [...]
+-4342.76133440144, 6922.53399165505, -2717.09244914704, 819.684904613346, 10900.2024771347, 3392.31609665014, -2091.98784103619, 15335.805007112, -7736.36115214567, 9954.99805599576, 2719.91270299217, -15532.6994309766, 12695.3264452936, -6184.75489990856, 5410.05334900381, -8100.88979657065, -12548.2010766866, -3973.83253910919, 5646.87407487795, -11501.9643093418, -8638.1822446249, 6103.98951826496, 3844.35310500295, 14449.5791456975, -10914.0634290162, -21367.8747299254, -6353.2789024 [...]
+14377.8562293386, 17487.6201742328, 13144.6360948839, -13694.272202217, -5260.99426697349, -778.503726667422, -10201.3570779573, -132.360523974922, 7533.53280249777, -13750.4641720641, -7583.07012222781, 6368.00612914603, 20872.0481134132, 5728.63407873737, 768.74755073191, -6968.25799411629, -6004.60376083429, -12116.5546748267, 19861.9548029168, -13062.0031291474, 8834.68478533827, -27323.2736714472, -11542.4709472129, 6283.3954304652, -15818.2417883069, -4253.4042461628, -7934.3303778 [...]
+-7379.90844527331, -9063.33966015815, 9964.57355914667, 9634.76579609563, -948.007691163493, -8233.66371951267, 14737.0746686305, -1093.40851176191, 13560.1857031356, -9134.4468529068, -8052.76518737093, 4282.88639374335, -11785.9637330966, 13260.6721343537, 15389.7987566031, 8677.09062110007, 4667.61302386535, 1690.45817427904, -8946.34301411928, 9892.64263705847, 14486.8542154044, 17068.5928914578, -8083.4442463316, -51.3116616015278, -1753.66803496439, 4671.7682714372, -1431.901264270 [...]
+668.795856945805, 13385.6589647856, 5005.39223644369, 4926.80106107131, -3381.72113223048, 8632.04366497541, -13778.7567316281, -5514.58070553934, 10218.2043795539, -8713.3826110336, 3258.43982092996, 1659.94393951632, 4898.06249301321, 17340.1652617217, 5872.29668918694, -2559.13465699615, -1840.88045727887, -3277.67001132534, 14821.6242193940, 18977.5257436110, 4522.03261494507, 2981.80911378962, -1508.11877374809, 16514.5406450267, -1752.10948358373, -8747.79940659586, -2649.023628928 [...]
+-10069.9774210319, -22121.0541116377, 22820.5887317795, -10522.9368850774, -1223.77099495273, 19585.94517147, -6404.84115923257, 2745.15538209989, -11681.6469081704, -1583.2512230685, -2034.56609077223, 11574.2329640677, 4799.12580165172, -6566.31615737033, -6859.05207580832, 22161.8761489317, -23944.1377363108, 2332.18642221217, 3614.83915819262, 12738.9423552662, -745.819388041874, -8050.76738136779, -2678.38303206412, 12994.4516878886, 11789.4274653329, 1887.56132335253, 14969.8331270 [...]
+-17418.7809241470, 4573.01331243708, -4221.7841459377, 17470.0370571376, 3213.67296196429, -5445.62248011342, -33.2132553877165, -16305.2058554056, 1523.17924845457, 8757.35168828751, -903.659693743759, -8118.07386222681, -2571.89275099167, -5018.22405708706, 2944.91744014599, 1191.13680494048, -827.24353731043, -1463.24394933471, -1345.11161552733, -9367.86083505653, 11782.9488275134, -1077.68390529981, -1781.89151644780, 5365.73934725626, 4779.07606342919, 1655.77101341794, -13671.7547 [...]
+20153.0386951111, -912.594972708413, -2383.73109763415, -14069.0566739847, -14746.2444349830, 2986.13875782737, 389.226659039547, 10126.1992660533, 4801.7410405067, -12302.6010598329, 2228.24606322812, -7008.27445475937, -6111.4226654311, 1924.44315698061, -15975.1593477194, 2958.22290968245, -2519.05444212166, 1118.61034322893, -1647.66766359253, 13408.6027326580, -4940.48495327344, 919.40989222457, -5840.79541579219, 14620.5865963852, -10804.3756828734, -6994.81115706184, 1033.41403707 [...]
+-3518.8600524653, 5356.36814637491, 6616.15179770555, -11216.8002139061, 6491.73481953282, 3160.64533764110, -3904.39337214591, 5710.00361061893, 14123.1020780312, -1304.07379318147, -8695.06484265729, 2054.40652822100, 8543.62921532521, -8249.24718115983, -13722.405940991, 5967.71466973972, 2429.53561720718, 3346.96961157169, 11265.3778447033, -8810.68318648784, -2828.69241698474, -17756.8201247792, -5644.08511765786, -11626.7385443874, -23181.8217429926, 5338.7070497063, 5331.387259067 [...]
+1333.15907315177, -20571.3080261067, -11670.0877956667, -8173.38975617506, 29169.1027711941, 3229.56768421693, 1066.12861433311, -3363.58272765107, -10064.5871609802, 11788.0608001314, 13541.0701065214, -5354.70971200676, -459.746501976998, 3799.01069688138, 7658.72657126503, 5707.19271310999, 7936.49016641733, -3951.94231258848, -11925.4922678735, 10133.5752213247, -2486.31165959462, 11329.6016615832, 10218.6207396722, 5649.11175439864, -12493.935869772, -8878.10371649209, -11714.138426 [...]
+-8636.00599620183, -8750.22589289041, -14023.2406075266, -7233.64451692916, -11801.2462894365, -14457.2729921794, 12372.5246748520, 3481.12133527313, 13861.4284011346, 474.244837311571, -14998.0557514617, -7231.79987301257, 9973.42422051732, -2487.29858429771, 370.991696007206, -1883.49318090885, -439.589994688897, 12786.4381806431, 19076.6618364616, -6881.83793019508, -491.341623428032, -1045.04953559049, -4065.82540630241, 1730.23658806590, -2481.51650889685, 8896.5163949753, -7336.661 [...]
+22880.592775189, -4874.94161671756, 4966.14325299546, 8044.2078823301, 9130.9261756185, -6022.71679751297, 23589.5775882091, -11555.8958550738, -12425.4199328142, -9805.02523556221, -2593.31143763741, -10553.5764616996, -10266.6089879811, 5233.26383294464, 18128.0950188984, -8520.53601617495, 10449.6182741143, -10791.2999714778, -265.395483564134, 8103.5394837051, 5338.14786007236, 8481.00253292663, -962.455217886757, -5372.93639996494, -3128.24587725818, 2355.21420842062, -7554.02228059 [...]
+762.664626070333, -17231.0583800095, 16897.7607833127, 8507.15812553177, -14011.5751132548, 1370.23838509584, 17961.3154811429, 1249.10379398993, -18956.1582693455, -11960.1437184726, -7488.81695589435, 23833.0230937101, 913.591266964056, -20111.7051998035, -3973.48277183843, 2119.76112330425, 2819.57590616031, -8318.95888632753, -12759.4144381069, 11080.1238211048, 9313.03100338058, -4808.84128337603, -12055.7336764346, 12204.6287210781, -5088.12034461641, -2988.28986775658, -5171.46805 [...]
+-10841.8810004614, -1821.20514703314, 1382.64271036261, -1448.98951950256, 2940.37778739673, 7603.61256195789, -21710.6078438691, -8308.245194418, -8087.02253966733, 10529.2170988355, -16910.7900867186, -11109.6879898285, -6337.28866450512, -2106.28468872317, -7199.26292488521, 2487.28125017780, 5334.26994478534, -1809.14939351100, -5211.72690836733, 22568.0575534175, -2603.73592461564, -10413.4466302751, -1401.53527739658, -9067.67933660543, 5798.49219649323, -11814.6599696635, 29827.94 [...]
+-4613.34156870698, 1617.93659901058, -3525.37419933428, 5926.30660137411, 4509.15212121568, 887.900583942113, -10648.9684461141, 11849.9408668352, 4586.44963616002, 31783.0138957725, 9280.75499552119, 8092.20252183762, 13244.0469334766, 64.260162338909, 3160.98517133603, -13156.4849356752, -119.941455770185, -6917.68398937007, 8670.25567960077, -4060.77498806145, -2393.0647362652, -12296.7800078401, 7607.94339376623, 4668.96759444092, 11588.5727162690, -2178.6664930521, 3202.17615227105, [...]
+-9760.2853842273, -12570.9025418036, -8169.66818856908, 3568.23329410666, -8465.9826612913, -17469.9679801651, -17910.6521679867, 4499.26905109234, -6508.30492050502, -4522.8005275404, 11117.1271837047, 9579.72922986788, -6427.92158900471, 9350.96707776055, -12716.6900207312, -23704.2352341534, -4522.41452671259, 3865.8272282803, -948.128251919275, 2134.27479064847, -12820.8036409600, 17768.9861743975, -4523.01530893052, -1194.40364901809, 6296.94448494295, 7160.43149988675, 12150.591419 [...]
+7665.3006005347, 9864.91742374584, 22920.790267564, -3405.31980295648, 18123.3819274801, 353.048644502575, 11065.0546829265, -7563.9187945123, 16473.8245119292, -3504.13775000335, -12576.9944935236, 17634.1037339361, -3945.03554163372, -8914.87175064197, -5228.47451005366, 1469.33236876227, 9062.20561161575, -11399.2806263811, 9786.1946972967, 5567.81976295172, -16973.3414661631, 5844.85266202831, 12259.0049112605, 8388.26632378966, 3523.35491173557, 813.908706843214, 101.073465700120, 5 [...]
+-14652.7528219318, 4260.88900013032, -1826.00504600477, -8719.60875643497, -17223.754483154, -8502.26675566456, 14612.0495289625, 2321.88594284515, 2492.69537706754, -17708.2308813188, 2079.82076172642, -10567.9704521074, 905.44926891, -14617.3469181368, 7159.75455230721, 25619.4709260011, 5363.30761380837, 18141.3985776440, 3944.60174849002, -16964.6579604887, -21086.9440477272, 888.556180132759, 125.744293944237, -11163.3707359121, 6671.99924067463, -5965.42346508027, 20433.8083567066, [...]
+10383.8955191629, -17378.2777947861, 2782.98398684235, -4043.09815086743, -4501.96761116241, -17033.3968137292, 89.4843950592371, 1493.03839384190, 7008.98573171623, 15201.7555877567, -7192.30016541027, 14031.7528917567, 22252.6421933804, -2618.40013606228, -2990.06388148138, -9999.52179032553, -10772.1397413643, -15581.8687935057, 11734.6814327411, 17960.4237812943, -15136.5189609498, -6633.07785905181, 14248.0241234129, -11345.5373277772, 5124.51931997824, 17237.2725965565, -360.253499 [...]
+14178.7513413482, 3502.86032027528, -4997.0624104297, 1400.61856434752, -11397.5837366430, 18855.7646163987, 1791.9706071399, -2073.86089665496, 1921.29311958902, -19755.1372376908, -1429.30694554016, -10745.0507363832, -14456.6013672636, 4292.35734575598, -2302.23903466189, 6355.28768280702, -7970.02899252617, -2121.24438364680, -6342.56758393988, 21057.1794264861, 5069.45831612677, -537.053224950299, -15485.0565476061, -3773.69247949355, 596.92960787689, -5760.81405686648, -2501.297434 [...]
+-1824.10859014353, 5072.05391335592, 11446.0438349564, 17979.5041211492, 143.125332162578, -11395.6099866164, -5305.94148510721, -2939.60782217687, -2914.4988164352, 2021.23763580650, -16098.8408119833, -12486.9904694907, 12249.3334257538, -4993.71285660193, -4179.95266415142, -6426.65618061737, -202.265746509723, -13067.9396766495, 4588.14352552272, -11152.3252409337, 5909.81522638902, 5925.65095288686, -7413.3791774444, 3966.14430512111, -169.290509667223, -5323.59562313762, -8443.7964 [...]
+-4919.1867205699, 10623.0621214437, -4796.29993971417, -2578.9131565837, -4310.68185681796, 9003.13645639787, 10635.5731859891, -5121.94487338309, 14328.5078233986, -11884.7575961686, 1056.15211049555, -5897.38509185266, -3714.24790062604, 26628.9106381295, -4425.71118869157, 3645.39544334793, -12450.5407575348, -7814.14726940832, -750.104056576057, 3142.69142648019, 8365.62628541152, -7381.60775579181, -11670.5919674342, 319.344062741199, -11757.1260428555, -21592.599266616, 16567.87591 [...]
+10112.0933573776, -8877.77342806525, -8509.53278074094, -23265.3646042605, -13787.2402083772, -3921.17639229572, -3640.41800574946, -8878.8406615969, -3232.67624318223, -13076.7278681146, 9368.64912380242, -656.404249096351, 1504.10309537816, 24370.1042163857, 11671.4927231860, 14476.7653287195, 8028.38090743374, -666.115924313147, 15413.654744582, 1576.211741732, 2305.91836600703, 11657.0718008905, -14429.5768479685, 5570.86084840722, 7256.82369495719, 4199.69747054326, -12477.741060229 [...]
+-15903.9543757706, 11739.6786892399, 15625.2604139013, -5181.41041289217, 5018.77098119481, -18429.4408846376, 5304.50720620460, 129.318697206691, 187.974408740657, 7793.98131507107, -5620.38575044942, 9910.19630991923, 10465.5093838703, 11035.908846833, -10984.6940393739, -4487.59417757201, 13626.7608015845, 19738.8584166336, 7953.53386292278, -16164.8622322202, 1090.56051016776, 5967.35541900447, -3032.0945168232, -14271.6945196708, 15518.1613748248, 5486.06866080427, 7159.15521603989, [...]
+-6959.40856385387, -1541.73433683761, 2806.66415269525, -5709.2452247432, 7295.25960741338, 3856.75268174663, -6622.15082434232, 5592.75039714694, -5137.97156382729, 941.440480603492, 4873.79726200809, 14746.0413320963, 2967.18631904052, -10733.8758877341, -10450.2391862726, 4483.75619471862, -3704.1678818889, -2192.25089583249, 3637.76040232579, -5956.77302840201, 8706.60530221692, -15713.4987070982, -431.059559788003, 5778.19259369529, 10648.8349606986, -6447.37555174857, -12697.185848 [...]
+-12594.4872321637, -6027.38851881847, -6016.83807093041, 12469.3890434865, 16449.0750966528, -5993.28211082842, 9919.43598162968, 4997.42077181064, 5519.7722849203, -5677.71723358344, -540.507959372391, -1151.48938959927, 4009.84992102058, -6505.56979391547, 14887.687238759, 16610.3033893791, 1136.58167276014, 14944.751091711, -9661.02363777619, -3104.27166020500, -9182.05872015914, 8211.7189200081, -1419.95691274886, 3996.47681271755, -2365.73720259265, 12202.8697188499, 10290.233898209 [...]
+-7574.83974670658, 6959.45381018005, -12370.6659142029, -3433.64080107670, -2778.60163750961, -5583.1943416176, -6719.14334315293, 14947.8566430743, -115.166447974889, 2223.09181307834, -3140.7129778956, -6728.38333214734, 14244.625166463, 9.53605254035317, -1862.11479736298, -1825.13388543147, 16362.4095256163, -6923.19322690268, -4913.35706005754, 1381.40702959129, -4001.3138156489, 1381.70000513111, -9517.7579248435, 11714.4004517069, 8667.6056925446, -2795.38930900610, -5313.26519907 [...]
+33769.4834050117, 1654.24079975312, 2114.66921161952, -9131.2197525731, -10252.2864877207, -2840.17110889008, 15756.2491746195, 2458.21567243394, -10492.6626667766, -2459.86462129035, 919.449259440653, 17224.4010336720, -6077.63261631952, -1739.65394180927, -1334.96585745225, 7559.26157405233, 1064.18244197398, -7036.22747905848, 2523.84034096878, -6008.4321847523, 6143.13267634358, -5023.64874482775, 5881.70045131863, -17963.7920050802, 1638.86555106052, 12147.6674340692, -1170.79994719 [...]
+-10443.1995968136, -2198.0156041432, -6731.71135569955, 6219.13124017212, -77.9796257600178, 8514.73904645097, 14290.2815629464, -12918.6982955357, -2805.83837571522, -22879.4765891260, 10715.8952268386, 21182.7294257914, 8309.29104536176, -9771.76406311847, -3421.85224472254, 12426.7501984829, -3285.8043899252, -8911.59739896308, -16396.2669137575, -15997.9171607623, -9969.86289215338, -15623.8721298544, 1604.02977449641, -2499.08148112593, 8665.91885500455, 21670.565004125, 9044.672493 [...]
+7690.99667274677, -21199.4556027076, -1856.21872226029, 13346.1358213785, 7941.76152086048, -4832.76671769951, 7568.5848693021, 3844.62426006289, -3341.79283945475, 2837.95303728485, -1755.28158845687, -20805.6774882299, 7237.87950768116, -9249.47958305854, 16596.4194085936, 6895.87056008687, -2530.45000525728, -6011.62396924768, -959.101527599305, 14353.2699305373, 1972.29661586733, 855.725216055269, -8886.54305701552, -2819.39487463633, -6429.19234491895, 18576.9700752419, -2053.726194 [...]
+8444.02344521432, -1879.99278471286, 5250.91905724839, 4561.41282983083, -13278.192888336, -4672.33674253832, -14907.367053306, -487.318275841167, 12049.5043987925, 7548.699829941, -3045.81501992919, -2140.80600719020, 4183.22865627927, -2589.80762825015, -538.752975099711, -2844.53924278376, -9238.57727089469, 13246.8755401089, 1040.10611742906, -8570.56803132549, 7632.42285645401, -9864.86600808914, 9333.52317232655, 15145.3213104924, -472.665278308399, 7062.74608216959, -4508.23484973 [...]
+6797.5113131409, -4468.98056168381, 8093.52322721482, 5859.33497921113, 6513.99685121313, 12604.1529594201, -4393.21555207764, -12869.7604399850, 506.928221933405, 6749.64645412697, -1777.29975793442, 11216.5353329839, -2806.24256526940, 8894.40612490266, -189.274426112187, 26198.2173497416, 5975.97361310976, 5395.8448756967, -10388.1010125113, 6616.422509495, 7679.73084826337, 2333.90776215421, -13894.1606931291, 11650.7216315849, -181.483308606072, 134.362308382779, 8475.48273360223, - [...]
+4182.04597872572, -18853.4432086867, -8327.99736634826, -2996.34941853439, 20247.2619769879, 8877.19738862213, 1077.35151708261, 2053.9943486326, -14758.8485369923, 5166.78251095779, 21586.3246013312, -9136.0275402331, -4685.75908685677, -7160.51128623644, -1431.83104382365, 14994.4861378397, 10080.9093376509, 1090.47109731608, -24387.1960083151, -7363.23080962924, 5222.96553119372, -577.619107078568, 15414.6672690280, 6825.07599772479, 9963.48583935665, 1316.77103937887, -2983.233430783 [...]
+2421.03505737722, 33.3534315302361, 2240.70929023471, 7399.34039311627, 19681.7423189711, 6712.13937777491, -16897.3999044895, 11909.3948592215, 11566.4531595564, -3196.05509804988, 11367.7926400373, -4280.64466416522, -10397.7081883675, -3877.61927746529, 17954.3833913763, -808.859440374064, -17201.1280458136, 5256.47082651989, 8316.90226927765, -10086.0187687376, -2702.06417767928, 6297.92704793363, 2925.44298482876, 3114.80046084795, 7435.93392953632, -14885.8347439375, 1052.538699890 [...]
+7559.23943820245, -3400.59878401196, -10826.0968559044, 4927.89992810258, -6317.18480189758, 1293.13847796971, 3813.92217510398, -6696.83242720042, -807.197599224786, -11833.6595833991, 5979.48941303243, -4605.31815247355, 2764.25059039267, 12012.4052664819, -8300.04325271643, -33205.2076440658, 13468.1610111024, 16856.2791012444, 6575.89547756073, -2284.37959316564, 18580.2547913970, 9616.76513566197, 86.0204670252421, 8112.11723492892, -872.40983074919, 9215.97214729327, 6736.211297295 [...]
+-21741.6638581646, -4748.99543900346, 14689.7769581158, -2640.58616062443, -20198.072147683, -13367.8667502504, 12675.8905016103, -9695.1207383684, -11843.6909350921, 3531.93613858294, -9241.59216404933, -15578.0636414824, 3842.67549335011, -3519.93661983068, 10387.5399486408, 3662.97732642044, -10375.4082911438, -2523.24320356809, 13643.6847561177, -2924.46494600071, 237.579004166521, 9161.41477555555, 12421.3455213498, 4085.89341829539, 17042.6684402309, -7711.75658940568, 1918.8261104 [...]
+-16843.0983738927, -28819.2174601111, 13898.09292464, -6993.6207939507, -980.363218187046, 2826.03221823101, -5660.68055883844, -1526.12857413684, -12375.3237716841, -5194.37282576226, -13655.5672141142, -1508.79596439437, 2190.2072416276, -6989.50806628032, 8089.06131986747, -9273.50767955827, 9695.5211698834, -17724.0113740931, -10119.8356485274, -7678.51696191175, 11518.8893296713, 14825.5753250026, -10583.6251120229, -18167.1514522106, -16288.1139783785, -15659.3430681097, 5671.49522 [...]
+-5240.95603818022, 5542.41724030592, -1859.15437525914, -1225.26571120066, 22427.6785141995, -5014.65892279659, -11028.6630329626, 16870.2556299136, -7474.82598856338, -11150.9575690848, 9556.46622789845, -12229.1236976932, -4298.79171920259, -6736.76230273357, 10956.9918074052, -1213.01992359320, 6098.13324829251, 3845.83705134047, 18463.4177956431, 9430.87254172024, -8525.24313008988, -1808.99362139156, -5750.96337564232, 6973.10802772141, 5156.80785168461, -5451.59618720536, 7224.7389 [...]
+7900.67192149919, 643.417370809135, 3061.97353936574, 7279.91235836431, -8455.88218490683, -3340.63425802065, 10094.4387545282, 1764.88101959415, 1584.25355873555, -12748.7942158331, -7983.4328308132, -259.943612890262, -4994.84760190078, 14965.3392679660, -16935.8937754802, 6362.65076423374, 2955.45830277301, -7036.94577696858, -8673.32748203439, 9041.99571725504, -4908.37441753019, 9598.48946991422, -3112.87817484023, 14458.9581039829, 3173.73009855179, 1959.04408189713, -3395.89095232 [...]
+4403.39099779971, -5204.64132393111, -11582.3967163946, 1685.63225115500, 8323.9656918674, -7576.91989618436, -6.96561253120558, -5379.72292240298, -2177.82684204277, 7752.59181601906, 6150.17701857617, 1926.4935677097, 2054.07314240812, -16202.7559195266, -5744.00188971409, -7679.22830213874, -151.042870389573, -5492.48256533921, 6885.64218103189, -2872.09028926336, 13351.5973463761, -4526.99482499165, -1622.20985535927, 6123.94413707091, 2268.40326370926, -9391.43172599335, -6410.11989 [...]
+10720.7591135011, -22873.1603881215, 14380.015304042, 9981.04007951523, -6678.13757176039, -1563.65020237176, -3202.81768291118, -2956.51865990005, -2377.00523677698, -12249.7463297887, 3610.41576010768, 907.274585092408, 1259.04872595063, -8741.90727545488, 4885.06708343, 16566.051310422, -6227.74588908627, 1471.69908134541, -11432.0899011641, -1826.17666185936, 3496.14554030963, -6842.81320033572, -11949.7478108812, -14117.0284977191, -16460.4800151801, -19270.98041362, -2937.047150568 [...]
+-10336.6922786028, 243.344252196754, -6218.22785138204, -302.547915373835, -2052.95471237863, -11385.3465882945, 16373.5070037620, 21156.7862644575, -353.757321528731, 14612.4462327829, -6265.86604164707, -11333.8266813639, -9060.31328814424, 9267.65863652961, 649.614687899533, 17627.9527722317, 11776.278974853, -4100.91638335212, -5178.77964319847, -5536.33170428209, 10621.4753139222, -14445.9106885606, 6894.38833606493, 1542.46912393952, -19694.6318751058, -4373.816467334, -1267.277318 [...]
+-5955.9154975671, -12286.0506943744, -69.649278801312, 25423.5636568714, 1034.82420799677, -5642.98957074145, 3241.66773322713, 1257.00607749707, -7723.08594315984, -15599.198919301, -572.122353682746, 13755.3589654955, 1709.10995799639, 16409.4633509056, -11045.2352831925, -13664.637478196, -6961.66636094796, 310.419077067302, -16670.3423064619, -700.869946911641, 6452.50107078712, -9205.61058465862, -1594.48635517267, 5222.01110018521, -10745.3213564365, -3599.86527695298, 6301.5310532 [...]
+26820.474526347, 8834.07106521652, 529.946303218895, 15607.9307408873, 17728.9822066321, 9601.62580000451, -6064.61696963249, -5030.26894992209, -1066.81429748256, 182.501430982268, 7217.10436940164, 2062.86368912004, 2822.84334171782, -12240.5749527314, 1845.11285563623, -2297.20231470108, -6257.53255777253, 7412.55446305419, -6062.80739806824, -5191.97141257339, -6700.44655981078, 12227.3029292036, 1826.54712293198, 12217.5148093384, 6237.53815188327, 679.84434819748, -1251.81662714481 [...]
+-3676.60820230861, -3867.44285792723, 1944.87699950749, 6225.60971728496, 13138.7532773823, -6810.74317486696, -83.3020037867466, -3704.99620100398, 2502.67805038668, -14729.5038661421, -5469.541253717, 3040.01917751462, 779.693014506253, 6103.11676663553, -9983.5249030437, 8099.05075314689, -17830.3421786897, 10426.9179251349, 8724.3450557835, -4436.97848272407, 223.346272264997, -3775.62535293914, -5042.92413926107, -9282.33702950857, -18847.3517742062, -9218.43936416643, 3760.78903422 [...]
+7280.42097385805, -16915.4338848825, 4816.64844783052, 15209.3024468685, -5444.69388145802, 11337.1533095385, -2615.70690122258, -6137.13768298978, 5312.63030252277, -5275.93153892947, 931.020111457362, 2717.48434325579, 9460.994218705, -21710.3921560852, 10618.2930192112, 26579.7882518479, -9092.94223980712, -414.626819996335, 5188.22340224594, 1342.84463590804, -18827.6595388828, 1603.99080538309, -2793.1311422684, 6786.81116771201, -6393.23545774699, -9580.79580241196, 14431.787608462 [...]
+859.601529820047, 1398.20795124900, 13591.5226140174, 1716.48434175794, -6160.27515440794, -2683.43506893497, -9886.8420048909, -6504.03583370096, -4863.33278165776, 18377.8627119354, 14584.0648052289, 20868.3618622514, 9726.1333323836, 38.2790370275983, 1465.1897595268, -1936.51406968590, -9846.84255233163, -437.603752019209, 4504.0057532474, -10470.9904339355, 2282.18074492871, 15731.5816999974, -6737.95534601646, -9751.28071153433, -3472.3562999993, -11344.5409379358, 1507.20458728439 [...]
+10075.3175429838, -6997.81279774113, 17405.2371264978, 3699.6280469161, -17124.0408581961, -9458.21920353917, 6691.28633995709, -1257.49898656816, 4279.69448066372, -11287.8843968311, -16773.628483065, -11193.5589822574, 3893.24436742531, 1926.85689736812, -3904.90074178366, 7960.3395171475, 11212.9087842327, 22148.0507192301, -3987.60276065623, -3820.24186639938, -1477.24132351948, 7644.28579959566, -2880.23969750941, 6885.29556672307, -3052.40969478091, 6365.74942074159, -8037.38861075 [...]
+18760.8052068284, -3700.18126700892, 2466.5590734512, 8839.77569617378, -3553.76863543595, 5789.1059018621, -17401.8029123209, 12818.7192827520, 17212.1562396697, -10172.0614294936, 8574.87563969267, -12996.2874903256, -3365.21543991036, 8068.20765830413, 19235.9509954932, 27371.517291585, 9067.15808807781, -19672.2041618831, -5590.41114861442, -9192.5232952709, 2093.17069777798, -4982.09515610479, 15426.0088037556, -6061.52111018385, -925.626508119734, -20503.4021072765, -6551.855878532 [...]
+11798.003337111, 3767.46039173116, -109.350332654045, 7087.80630558705, 6229.83032147617, -3584.94239917429, 5588.54184964471, 3914.12615300852, -4069.290568565, -4388.47286141632, -4964.37385185697, -11896.613644733, 9589.28516932705, -22298.5099876368, -4321.27908884525, -3210.38110881468, 2210.44301689771, -6595.3080669761, 12078.6762580253, 14034.4300310086, -18906.3316125035, 18532.6561976492, 7166.47120637995, 8541.28492651074, 6632.04525194879, 1128.81538538337, -8832.43119988732, [...]
+-6684.82073559638, 16052.2801268956, 10252.0075630670, 4409.49546922097, -11209.2615129590, 2894.81851490157, -6747.54208613091, 8368.1719312432, -17145.5034027953, 9606.61246128028, 4928.94532375803, -4839.78146583472, -1590.43682525061, 4671.31396500442, 15174.7168439295, 9016.11588253048, 9453.45228780202, -6693.92322555557, 11374.8740713879, 7689.22527031204, 5230.45759961826, -2958.20646439096, 639.199213505095, 7998.8428744294, -5467.80311115627, -6202.13590639525, -5840.9659105722 [...]
+12619.8119701145, -9800.13719201562, -24784.8173120246, 1571.73243596996, 3144.50750042742, -13300.9627375048, -168.854044435205, -1617.84988515245, -5111.36626435059, -11230.8011884685, 3917.77899985633, -13969.1844006672, 990.579536989171, 2120.50614487674, -7329.17868192722, 15348.1450280867, -13941.6068651622, 2495.74242381184, -23618.6256084273, 14306.3570493972, -2695.78268761576, 5611.16304612178, -12686.4963706939, 10163.0189010759, -23432.3242720903, 2422.12470578194, -3236.5786 [...]
+-27026.5221390991, 4620.03360947586, -1148.13887011939, -1511.41906154493, 2165.67771226321, 159.138001919619, -14575.2492949794, -596.386177963954, 1171.87556368982, 2409.43157400885, 8720.97941219641, 19339.7750043418, 20926.7588310254, -1391.82578562829, 1534.56859294781, -2088.4709146315, 8038.30463585685, -4113.2975876527, 10387.045914787, 4294.50603490591, -9591.56979089766, 2084.97752379347, -32887.5440572325, -3017.43877697775, -8559.24994360924, -7746.11501539912, 4416.835927685 [...]
+14342.3398655949, -1791.55926984490, 7553.86957813359, -6762.51647293268, 2170.96192355125, 11520.9695278334, 7291.78883655344, -12196.0335556538, -7320.69452926766, 307.231064383804, 2639.16393443493, 11101.1919549646, 16003.1987870050, 7571.50940512641, 84.767255469777, 7240.36871159573, -16803.7444436314, -9005.87428752254, 3174.72010009760, -22945.3884261279, 4761.0985992183, -10007.9027396305, -1092.63024119212, -2648.74393917828, 11194.9291985684, 8635.95607859852, -16916.983720643 [...]
+818.183811892027, -6047.092371416, 4425.6827895336, -1344.7914784107, -9345.03779262651, -1122.32368793552, -4132.85718268434, -11607.2027749629, 3194.56580674095, 9024.69653221667, 16991.3576233255, 3655.18150295165, 7698.23719334828, -3611.97138446969, -4037.37627027641, -8092.7058311481, -4147.35415452242, -3500.32381935916, -7547.96902713332, -7713.0297179222, 2330.36427100645, 9579.19004062865, -4601.61664491836, 12708.8766063622, 3551.03800170605, 14400.0596304444, -8853.5984805712 [...]
+435.778030517754, -10458.5437257313, 24305.4309849473, 12423.3061597314, 5166.01201725931, 16667.1581958446, 9807.61545598217, -8690.23367497813, 16797.7560270969, 9055.512380289, -1317.37320162631, -5614.84357331708, 14123.4703992022, 169.929089334692, 4329.21324850884, 5153.64987955514, -10873.605054673, -9996.86158011388, -8726.68529987824, 5213.24119183021, -503.886782133671, -4751.02420172569, 9413.80651765282, 10276.9299627064, 4916.34086549117, -7954.07733580221, -1328.99446009108 [...]
+
+double y6[100] = {
+-52261963.471364, -66925596.1332487, 68638539.4562293, 152341926.108658, 114750447.823165, 35767175.2410332, -169291067.813487, -61526711.5524784, 56965021.5127846, 129920722.560498, -65203493.2678022, -11235262.2496311, -75443133.4006308, -22144244.7439622, -75790594.1935929, 46294490.7713293, -82174075.2893446, 67724801.8985045, -79477804.5486296, 123108360.718560, 29846286.7395871, 46877597.2295137, 4852093.388421, 106198304.285860, -43674689.310301, 92127608.2868564, 142771975.006120 [...]
+
+double lars6[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -35.61070810873418700, -196.91568238434385000, -241.86936567047280000, -288.39676923935525000, -306.52226755693300000, -403.89250550585984000, -453.70513663171999000, -580.23154891746810000, -582.37283253668420000, -608.88151476597693000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -147.59412067302387000, -199.72764733393882000, -502.13883988023770000, -590.36243946504965000, -666.07507978158492000, -695.40161274386060000, -872.83945729777838000, -971.82735524136376000, -1203.20851159521200000, -1206.82031941552580000, -1256.0776209624476 [...]
+618.92782934604622000, 800.08361289176844000, 1032.88980256400370000, 1039.03200008678100000, 1208.35223425427440000, 1264.56819518204930000, 1429.88584999002550000, 1569.69687899692670000, 1638.89807428332670000, 1722.55264615942060000, 1728.02940628333160000, 1805.16774928367820000, 1834.54462061850200000, 1964.16421763970200000, 1994.09653058466350000, 2024.62826473480210000, 2032.80858904473600000, 2074.62950539910030000, 2074.90365499079690000, 2068.75606741922320000, 2068.983025044 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -7.25053353724618700, -209.00120620158981000, -284.66262911985535000, -463.82863530981308000, -670.71468985890158000, -753.88671967234529000, -857.74558324308214000, -862.94263462207550000, -944.68832442157088000, -976.67382235410935000, -1170.35773327695160000, -1221.87761019928620000, -1264.58743232153780000, -1280.09802037904460000, -1374.10976459842250000, -1419.06759331865810000, -1523.67581444996020000, -1525.5256652528 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 190.05064803995936000, 378.03798009017981000, 462.20466363033188000, 572.53126205507215000, 581.24463430690616000, 661.41322458431694000, 694.88488820316798000, 862.15443316791368000, 906.60460946474677000, 948.40176602198460000, 965.84998980814453000, 1063.44436758644520000, 1114.78890210046010000, 1223.66666612144920000, 1224.77829902207170000, 1241.540698387493 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 117.04346752589007000, 118.88584994199867000, 144.79347887288750000, 149.29566303198132000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2.44310615488744440, -30.84906109619489800, -35.91584784398496300, -52. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -183.86340529384651000, -229.01231839928096000, -258.90511868540398000, -268.20248560852747000, -330.54442351479366000, -365.58528381933905000, -467.37522430452026000, -469.17716976124302000, -493.94408536215997000, -49 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 111.78437155035760000, 119.37282174651935000, 191.56917999257888000, 218.99488051642160000, 349.26835262727388000, 385.64480254033623000, 415.18096520852464000, 429.45862623627926000, 495.57175169001124000, 527.78244843742516000, 611.12003738392104000, 611.53354612717033000, 613.89477455619556000, 614. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -62.47222841664923000, -84.68209918033275600, -206.51007643329399000, -282.99484995998699000, -467.71222438270615000, -470.52204293415764000, -507.04343572761627000, -513.878452 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -258.40736399671891000, -347.64043517007849000, -559.96762394482164000, -788.76006782539696000, -888.15049249715753000, -1027.29176459434480000, -1037.48198570742260000, -1130.13954725997450000, -1166.77105986108750000, -1369.51551902299370000, -1445.73530244433820000, -1503.72987340486270000, -1530.03592379836140000, -1664.68711946739610000, -1736.57385611010250000, -1890.07278002333690000, -1892.5898391 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -8.68893239480482290, -67.45343642417793700, -90.50367744240286100, -202.91850588779562000, -228.47374387365602000, -245.65998218082382000, -255.04480096355087000, -302.92590892073940000, -333.29218135333809000, -413.06260864765977000, -414.55804758863832000, -433.15241485646879000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -20.90233566978178100, -24.71220013367768000, -35.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 40.003878 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1.95537639718881960, -15.5091 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -75.38066682417320400, -139.81190548867590000, -290.26941748456727000, -292.68545323656542000, -328.12923455428313000, -334.47928249095 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 76.62846996123212800, 163.05324377685315000, 168.40682812771703000, 218.41140135336383000, 234.33864202182758000, 340.44433825149594000, 363.45276092343539000, 376.02196316114822000, 377.79929223253436000, 390.86079321811019000, 400.20148110681112000, 420.08798727717499000, 420.65485427375927000, 428.68121921197388000, 430 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -86.43576630809307900, -292.21698988564594000, -294.93808936305436000, -332.26527581308574000, -339.26590166451717 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -172.32041534121956000, -239.54073941908652000, -320.75771977126908000, -324.62948681497858000, -396.26682135537061000, -420.49039244120581000, -557.98417297120614000, -600.61270074379604000, -642.27517792718027000, -660.81525637606546000, -767.69868986955430000, -827.83938353289375000, -974.59576761684059000, -976.94258438020267000, -1006.362 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 21.84699546822130500, 154.93611911372790000, 228.15737595303511000, 395.13163930151774000, 397.78517008979895000, 431.58219625959356000, 438.013707137585700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 62.77657552986836700, 111.02601468809613000, 132.52664611025898000, 251.77609479545075000, 311.61631717012438000, 439.78379709890248000, 441.93889267224932000, 467.84012197971470000, 473.24948620288 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 60.27082217682576700, 200.76240896984217000, 367.09493899985125000, 430.29171515680395000, 506.48713673503181000, 509.54653050219827000, 540.82333299698632000, 548.61719653314265000, 593.73413318286100000, 601.75712213159022000, 611.87060505817863000, 615.14586036163098000, 629.01825232854083000, 626.67899657972225000, 632.00459399223394000, 632.09658645382979000, 633.0215865237926200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 149.52403934416174000, 340.09684977520465000, 345.35424308775998000, 544.40286749345296000, 619.70813855951042000, 791.50204748703857000, 946.36347398490079000, 1010.57124706328030000, 1093.16350157514880000, 1099.10301621454000000, 1180.91215939861240000, 1213.36935147472600000, 1404.75130627573690000, 1461.75736497324420000, 1510.69337776287740000, 1533.10425003509980000, 1656.12606388889730000, 1711.64747409017150000, 1837.12337178148070000, 1838.87706164978480000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 195.85314269402087000, 201.74298191750211000, 413.23368600120239000, 492.63482413167537000, 675.99491667403345000, 874.66504528579617000, 968.11386426608419000, 1074.69742860438530000, 1081.26897519272260000, 1143.28574857451050000, 1160.42865002880830000, 1257.48718405192950000, 1292.76313722299870000, 1319.69318947125950000, 1327.21886682748780000, 1370.54558272734860000, 1392.21978978533460000, 1424.25793896756430000, 1424.61977392215040000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq6[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1139.70249007505340000, -942.66150175978464000, -925.23826165849050000, -1103.27478218300600000, -1088.62659088718530000, -1040.07524908396790000, -1033.30733406770880000, -1073.14407136799630000, -1115.88592177936950000, -1083.44811831048 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1872.77698409461460000, -1816.10096334560400000, -1900.24750693480470000, -1931.50424234296750000, -1992.10148923973700000, -1960.82382714111260000, -2032.15566254426470000, -2123.61560394292880000, -2104.60662575593460000, -2106.72294355826490000, -2137.89702 [...]
+3873.75615352106020000, 3508.94947875008570000, 3157.86485306382290000, 2997.82378223904150000, 2711.77712226951780000, 2506.21547819438410000, 2699.76604070949220000, 2414.63513840037060000, 2506.07354144363260000, 2447.16561658557570000, 2454.53896152848620000, 2706.81441955824680000, 2745.35948342955180000, 2563.42207079510440000, 2449.11623434001190000, 2559.35913187109140000, 2385.78465055462990000, 2347.87260170564790000, 2078.09356289532250000, 2044.80673666568760000, 2125.5308184 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2319.49878936278900000, -2000.38180491577490000, -1955.80368309934900000, -1840.08431940612290000, -1921.01621519081250000, -1796.13380094955100000, -1757.36742039198070000, -1552.34794004238920000, -1900.18887253007230000, -1968.36781792379090000, -2065.79798550502570000, -2005.06329911741430000, -2012.60456447532350000, -1949.37054269124340000, -1988.34929636806190000, -1942.18102317062020000, -1931.20101978371490000, -198 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1649.91622295191220000, 1514.12638642449000000, 1516.91597051160850000, 1528.17639188700240000, 1737.10102679843450000, 1598.47953522452190000, 1732.65669036652730000, 1635.47568024338470000, 1582.31938258129280000, 1680.43453100601070000, 1718.73032548175730000, 1701.09156164346520000, 1712.21578676870400000, 1647.82485043127370000, 1501.74800896273840000, 1541.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 573.01301390210847000, 577.92599089463977000, 608.59984092724699000, 579.35661917305015000, 7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -611.15701044330683000, -539.38122577838692000, -519.90918892403511000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1033.90145557579010000, -915.34902428250905000, -782.44573840673741000, -669.37826233797546000, -737.86462661409837000, -773.30836877837123000, -863.92117402549650000, -918.14221046657462000, -937.32904563048567000, -9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1080.05668111761110000, 1126.00474505164470000, 1035.45049097973540000, 1069.31469079891550000, 951.54920378191161000, 938.62583990781775000, 932.47545617235664000, 1045.53109062869520000, 927.53156224054510000, 902.57474898011071000, 935.78063939159847000, 714.56162006374325000, 656.16621400621125000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1156.60689855688910000, -1043.02463081917540000, -1002.49105014739190000, -1172.94468405840960000, -1187.32092364396700000, -1170.60444310920750000, -1160.86067133333090000, -1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2552.85294038764370000, -2318.53977672179280000, -2190.94945277239910000, -2171.45133810830790000, -2133.63386296914400000, -2232.52858814240700000, -2389.24705140563720000, -2213.18565118320430000, -2302.51236274084520000, -2306.84453507174380000, -2604.39963073892110000, -2519.44313313720340000, -2665.12613660352190000, -2544.45047314977550000, -2573.02255562447360000, -2488.06287879132740000, -2519.72 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1161.30330054004340000, -754.33388170652790000, -805.16460479203727000, -722.63520232221583000, -616.95480910590425000, -546.65867644467687000, -659.99407270432675000, -615.76415669971118000, -686.62341144643949000, -723.82651812926576000, -787.15523276084048000, -766.034511485265 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -395.10239432053572000, -388.64088368196144000, -33 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1103.6168 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -188.73828293203860000, -375.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -567.89131939240292000, -889.51106149413044000, -876.41100183643016000, -894.65461145636891000, -962.65473722663262000, -941.0532454135 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1036.87675702327240000, 911.66160633834704000, 878.57672743234571000, 802.89967519666698000, 728.15458855554584000, 830.99262872142140000, 713.21810272359357000, 596.15817876988649000, 454.48996999247066000, 476.20002733408700000, 508.88642915092572000, 497.56041174634032000, 561.89301619836681000, 572.37167936348476000, 5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1092.17184081201230000, -1093.88472197539070000, -972.91562363304831000, -1000.50807793507520000, -1007.984848038 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1213.72689687781940000, -1081.89347181976250000, -1024.25635782783820000, -838.23163284606198000, -1233.61387398002350000, -1171.52981811294560000, -1193.64598365521900000, -1248.63546177388120000, -1371.94917684793790000, -1460.80846239419130000, -1466.03729307397790000, -1527.61527199223410000, -1546.31876329594070000, -1561.665434763846200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 964.53167690961527000, 1024.49344591840780000, 1080.13408153715590000, 1045.61799898382740000, 1058.92757810709780000, 1036.62698047677400000, 1052.36923322 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1017.08234043682920000, 956.06365038367005000, 1060.26592781024190000, 1030.90987358435450000, 1007.89602774765190000, 939.08947317502327000, 978.89330946755922000, 931.53191600214507000, 989.966765 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1391.47821178139070000, 1279.94226570338040000, 1372.31405085396410000, 1222.22447961443370000, 1166.48920864152480000, 915.38479159381052000, 906.40838096896755000, 790.26194714473422000, 802.31893994812560000, 723.71956657735745000, 788.99750746434756000, 756.47115183548362000, 719.65556170975742000, 599.46024218479192000, 652.75167443760972000, 655.01703563328215000, 649.5812230113 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2385.39285002680120000, 2079.58009994024090000, 2021.97548133141370000, 2311.79149253333340000, 2282.98283265942930000, 2111.12929532534280000, 1882.25776704084460000, 1815.17303730879620000, 1808.57471621481590000, 1886.99842178414110000, 2137.15439485345770000, 2219.68798258753900000, 2289.54914550972260000, 2328.34191487072170000, 2367.75562075618750000, 2500.11987557016480000, 2459.90714428962340000, 2357.67501028062860000, 2325.94337481838240000, 2275.8189458617 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 1983.53345468535460000, 2080.05585387752580000, 2291.09777983875070000, 2246.37532417316920000, 2084.46728799147740000, 2075.31419190208320000, 2139.14166110439560000, 1997.92052833139340000, 1953.00541811666790000, 1868.18098285002750000, 1691.93553714140650000, 1706.20859706167110000, 1829.01483922484250000, 1791.34442683384120000, 1651.94730701534080000, 1653.62704141558380000, 1644.41321451630920000, 1549.06986276094950000, 1514.7730271786420 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso6[2800] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -35.61070810873418700, -196.91568238434385000, -241.86936567047280000, -288.39676923935525000, -306.52226755693300000, -403.89250550585984000, -453.70513663171999000, -580.23154891746810000, -582.37283253668420000, -608.88151476597693000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -147.59412067302387000, -199.72764733393882000, -502.13883988023770000, -590.36243946504965000, -666.07507978158492000, -695.40161274386060000, -872.83945729777838000, -971.82735524136376000, -1203.20851159521200000, -1206.82031941552580000, -1256.0776209624476 [...]
+618.92782934604622000, 800.08361289176844000, 1032.88980256400370000, 1039.03200008678100000, 1208.35223425427440000, 1264.56819518204930000, 1429.88584999002550000, 1569.69687899692670000, 1638.89807428332670000, 1722.55264615942060000, 1728.02940628333160000, 1805.16774928367820000, 1834.54462061850200000, 1964.16421763970200000, 1994.09653058466350000, 2024.62826473480210000, 2032.80858904473600000, 2074.62950539910030000, 2074.90365499079690000, 2068.75606741922320000, 2068.983025044 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -7.25053353724618700, -209.00120620158981000, -284.66262911985535000, -463.82863530981308000, -670.71468985890158000, -753.88671967234529000, -857.74558324308214000, -862.94263462207550000, -944.68832442157088000, -976.67382235410935000, -1170.35773327695160000, -1221.87761019928620000, -1264.58743232153780000, -1280.09802037904460000, -1374.10976459842250000, -1419.06759331865810000, -1523.67581444996020000, -1525.5256652528 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 190.05064803995936000, 378.03798009017981000, 462.20466363033188000, 572.53126205507215000, 581.24463430690616000, 661.41322458431694000, 694.88488820316798000, 862.15443316791368000, 906.60460946474677000, 948.40176602198460000, 965.84998980814453000, 1063.44436758644520000, 1114.78890210046010000, 1223.66666612144920000, 1224.77829902207170000, 1241.540698387493 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 117.04346752589007000, 118.88584994199867000, 144.79347887288750000, 149.29566303198132000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2.44310615488744440, -30.84906109619489800, -35.91584784398496300, -52. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -183.86340529384651000, -229.01231839928096000, -258.90511868540398000, -268.20248560852747000, -330.54442351479366000, -365.58528381933905000, -467.37522430452026000, -469.17716976124302000, -493.94408536215997000, -49 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 111.78437155035760000, 119.37282174651935000, 191.56917999257888000, 218.99488051642160000, 349.26835262727388000, 385.64480254033623000, 415.18096520852464000, 429.45862623627926000, 495.57175169001124000, 527.78244843742516000, 611.12003738392104000, 611.53354612717033000, 613.89477455619556000, 614. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -62.47222841664923000, -84.68209918033275600, -206.51007643329399000, -282.99484995998699000, -467.71222438270615000, -470.52204293415764000, -507.04343572761627000, -513.878452 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -258.40736399671891000, -347.64043517007849000, -559.96762394482164000, -788.76006782539696000, -888.15049249715753000, -1027.29176459434480000, -1037.48198570742260000, -1130.13954725997450000, -1166.77105986108750000, -1369.51551902299370000, -1445.73530244433820000, -1503.72987340486270000, -1530.03592379836140000, -1664.68711946739610000, -1736.57385611010250000, -1890.07278002333690000, -1892.5898391 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -8.68893239480482290, -67.45343642417793700, -90.50367744240286100, -202.91850588779562000, -228.47374387365602000, -245.65998218082382000, -255.04480096355087000, -302.92590892073940000, -333.29218135333809000, -413.06260864765977000, -414.55804758863832000, -433.15241485646879000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -20.90233566978178100, -24.71220013367768000, -35.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 40.003878 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1.95537639718881960, -15.5091 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -75.38066682417320400, -139.81190548867590000, -290.26941748456727000, -292.68545323656542000, -328.12923455428313000, -334.47928249095 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 76.62846996123212800, 163.05324377685315000, 168.40682812771703000, 218.41140135336383000, 234.33864202182758000, 340.44433825149594000, 363.45276092343539000, 376.02196316114822000, 377.79929223253436000, 390.86079321811019000, 400.20148110681112000, 420.08798727717499000, 420.65485427375927000, 428.68121921197388000, 430 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -86.43576630809307900, -292.21698988564594000, -294.93808936305436000, -332.26527581308574000, -339.26590166451717 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -172.32041534121956000, -239.54073941908652000, -320.75771977126908000, -324.62948681497858000, -396.26682135537061000, -420.49039244120581000, -557.98417297120614000, -600.61270074379604000, -642.27517792718027000, -660.81525637606546000, -767.69868986955430000, -827.83938353289375000, -974.59576761684059000, -976.94258438020267000, -1006.362 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 21.84699546822130500, 154.93611911372790000, 228.15737595303511000, 395.13163930151774000, 397.78517008979895000, 431.58219625959356000, 438.013707137585700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 62.77657552986836700, 111.02601468809613000, 132.52664611025898000, 251.77609479545075000, 311.61631717012438000, 439.78379709890248000, 441.93889267224932000, 467.84012197971470000, 473.24948620288 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 60.27082217682576700, 200.76240896984217000, 367.09493899985125000, 430.29171515680395000, 506.48713673503181000, 509.54653050219827000, 540.82333299698632000, 548.61719653314265000, 593.73413318286100000, 601.75712213159022000, 611.87060505817863000, 615.14586036163098000, 629.01825232854083000, 626.67899657972225000, 632.00459399223394000, 632.09658645382979000, 633.0215865237926200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 149.52403934416174000, 340.09684977520465000, 345.35424308775998000, 544.40286749345296000, 619.70813855951042000, 791.50204748703857000, 946.36347398490079000, 1010.57124706328030000, 1093.16350157514880000, 1099.10301621454000000, 1180.91215939861240000, 1213.36935147472600000, 1404.75130627573690000, 1461.75736497324420000, 1510.69337776287740000, 1533.10425003509980000, 1656.12606388889730000, 1711.64747409017150000, 1837.12337178148070000, 1838.87706164978480000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 195.85314269402087000, 201.74298191750211000, 413.23368600120239000, 492.63482413167537000, 675.99491667403345000, 874.66504528579617000, 968.11386426608419000, 1074.69742860438530000, 1081.26897519272260000, 1143.28574857451050000, 1160.42865002880830000, 1257.48718405192950000, 1292.76313722299870000, 1319.69318947125950000, 1327.21886682748780000, 1370.54558272734860000, 1392.21978978533460000, 1424.25793896756430000, 1424.61977392215040000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq6[2800] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1139.70249007505340000, -942.66150175978464000, -925.23826165849050000, -1103.27478218300600000, -1088.62659088718530000, -1040.07524908396790000, -1033.30733406770880000, -1073.14407136799630000, -1115.88592177936950000, -1083.44811831048 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1872.77698409461460000, -1816.10096334560400000, -1900.24750693480470000, -1931.50424234296750000, -1992.10148923973700000, -1960.82382714111260000, -2032.15566254426470000, -2123.61560394292880000, -2104.60662575593460000, -2106.72294355826490000, -2137.89702 [...]
+3873.75615352106020000, 3508.94947875008570000, 3157.86485306382290000, 2997.82378223904150000, 2711.77712226951780000, 2506.21547819438410000, 2699.76604070949220000, 2414.63513840037060000, 2506.07354144363260000, 2447.16561658557570000, 2454.53896152848620000, 2706.81441955824680000, 2745.35948342955180000, 2563.42207079510440000, 2449.11623434001190000, 2559.35913187109140000, 2385.78465055462990000, 2347.87260170564790000, 2078.09356289532250000, 2044.80673666568760000, 2125.5308184 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2319.49878936278900000, -2000.38180491577490000, -1955.80368309934900000, -1840.08431940612290000, -1921.01621519081250000, -1796.13380094955100000, -1757.36742039198070000, -1552.34794004238920000, -1900.18887253007230000, -1968.36781792379090000, -2065.79798550502570000, -2005.06329911741430000, -2012.60456447532350000, -1949.37054269124340000, -1988.34929636806190000, -1942.18102317062020000, -1931.20101978371490000, -198 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1649.91622295191220000, 1514.12638642449000000, 1516.91597051160850000, 1528.17639188700240000, 1737.10102679843450000, 1598.47953522452190000, 1732.65669036652730000, 1635.47568024338470000, 1582.31938258129280000, 1680.43453100601070000, 1718.73032548175730000, 1701.09156164346520000, 1712.21578676870400000, 1647.82485043127370000, 1501.74800896273840000, 1541.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 573.01301390210847000, 577.92599089463977000, 608.59984092724699000, 579.35661917305015000, 7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -611.15701044330683000, -539.38122577838692000, -519.90918892403511000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1033.90145557579010000, -915.34902428250905000, -782.44573840673741000, -669.37826233797546000, -737.86462661409837000, -773.30836877837123000, -863.92117402549650000, -918.14221046657462000, -937.32904563048567000, -9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1080.05668111761110000, 1126.00474505164470000, 1035.45049097973540000, 1069.31469079891550000, 951.54920378191161000, 938.62583990781775000, 932.47545617235664000, 1045.53109062869520000, 927.53156224054510000, 902.57474898011071000, 935.78063939159847000, 714.56162006374325000, 656.16621400621125000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1156.60689855688910000, -1043.02463081917540000, -1002.49105014739190000, -1172.94468405840960000, -1187.32092364396700000, -1170.60444310920750000, -1160.86067133333090000, -1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2552.85294038764370000, -2318.53977672179280000, -2190.94945277239910000, -2171.45133810830790000, -2133.63386296914400000, -2232.52858814240700000, -2389.24705140563720000, -2213.18565118320430000, -2302.51236274084520000, -2306.84453507174380000, -2604.39963073892110000, -2519.44313313720340000, -2665.12613660352190000, -2544.45047314977550000, -2573.02255562447360000, -2488.06287879132740000, -2519.72 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1161.30330054004340000, -754.33388170652790000, -805.16460479203727000, -722.63520232221583000, -616.95480910590425000, -546.65867644467687000, -659.99407270432675000, -615.76415669971118000, -686.62341144643949000, -723.82651812926576000, -787.15523276084048000, -766.034511485265 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -395.10239432053572000, -388.64088368196144000, -33 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1103.6168 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -188.73828293203860000, -375.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -567.89131939240292000, -889.51106149413044000, -876.41100183643016000, -894.65461145636891000, -962.65473722663262000, -941.0532454135 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1036.87675702327240000, 911.66160633834704000, 878.57672743234571000, 802.89967519666698000, 728.15458855554584000, 830.99262872142140000, 713.21810272359357000, 596.15817876988649000, 454.48996999247066000, 476.20002733408700000, 508.88642915092572000, 497.56041174634032000, 561.89301619836681000, 572.37167936348476000, 5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1092.17184081201230000, -1093.88472197539070000, -972.91562363304831000, -1000.50807793507520000, -1007.984848038 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1213.72689687781940000, -1081.89347181976250000, -1024.25635782783820000, -838.23163284606198000, -1233.61387398002350000, -1171.52981811294560000, -1193.64598365521900000, -1248.63546177388120000, -1371.94917684793790000, -1460.80846239419130000, -1466.03729307397790000, -1527.61527199223410000, -1546.31876329594070000, -1561.665434763846200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 964.53167690961527000, 1024.49344591840780000, 1080.13408153715590000, 1045.61799898382740000, 1058.92757810709780000, 1036.62698047677400000, 1052.36923322 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1017.08234043682920000, 956.06365038367005000, 1060.26592781024190000, 1030.90987358435450000, 1007.89602774765190000, 939.08947317502327000, 978.89330946755922000, 931.53191600214507000, 989.966765 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1391.47821178139070000, 1279.94226570338040000, 1372.31405085396410000, 1222.22447961443370000, 1166.48920864152480000, 915.38479159381052000, 906.40838096896755000, 790.26194714473422000, 802.31893994812560000, 723.71956657735745000, 788.99750746434756000, 756.47115183548362000, 719.65556170975742000, 599.46024218479192000, 652.75167443760972000, 655.01703563328215000, 649.5812230113 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2385.39285002680120000, 2079.58009994024090000, 2021.97548133141370000, 2311.79149253333340000, 2282.98283265942930000, 2111.12929532534280000, 1882.25776704084460000, 1815.17303730879620000, 1808.57471621481590000, 1886.99842178414110000, 2137.15439485345770000, 2219.68798258753900000, 2289.54914550972260000, 2328.34191487072170000, 2367.75562075618750000, 2500.11987557016480000, 2459.90714428962340000, 2357.67501028062860000, 2325.94337481838240000, 2275.8189458617 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 1983.53345468535460000, 2080.05585387752580000, 2291.09777983875070000, 2246.37532417316920000, 2084.46728799147740000, 2075.31419190208320000, 2139.14166110439560000, 1997.92052833139340000, 1953.00541811666790000, 1868.18098285002750000, 1691.93553714140650000, 1706.20859706167110000, 1829.01483922484250000, 1791.34442683384120000, 1651.94730701534080000, 1653.62704141558380000, 1644.41321451630920000, 1549.06986276094950000, 1514.7730271786420 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso6[1400] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.24558469539847700, 106.79482604421059000, 122.90836479518939000, 176.64548442117996000, 250.71617123873418000, 276.94395277515287000, 301.51931783341769000, 344.02732673727428000, 561.01151464835016000, 563.36973315888224000, 575.1760681 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.14080444172659680, 14.65983182675993600, 17.23733 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+618.92782934604622000, 800.08361289176844000, 1202.06602005030980000, 1258.53996770679280000, 1614.06077780514560000, 1921.75317091595660000, 2367.54953036677990000, 2420.56027770293890000, 2498.90304588112530000, 2527.85315203482790000, 2547.74745427833020000, 2551.64721799851990000, 2560.80092881679090000, 2598.80021536571480000, 2607.07766643525470000, 2640.12342521867090000, 2678.92951864959920000, 2686.54242098194940000, 2685.97214221273410000, 2690.62332320811950000, 2761.396254839 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 418.42958281358540000, 755.78545679639171000, 1273.36325093332830000, 1330.87914154845040000, 1429.57627009605360000, 1485.78712535204500000, 1519.76892638057780000, 1527.91850615709380000, 1562.57794895005210000, 1631.03610995772330000, 1645.33385003213930000, 1688.29005471604750000, 1743.95825892365680000, 1765.12574808685920000, 1776.27136518834120000, 1795.37352563306040000, 1892.68675456003030000, 18 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 56.79252392658684600, 132.61577572877565000, 166.96913979828111000, 198.70342913875231000, 205.75812164452648000, 228.40004040817450000, 263.26939607859043000, 270.08233475881900000, 288.96091634271033000, 311.70113517228776000, 323.88188127047243000, 336.52100580123266000, 363.56074807384437000, 477.33709476529003000, 479.01513168273476000, 4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 33.32235200342326200, 92.52904715898310400, 371.81932749460293000, 375.20418727355741000, 393.09204589928362000, 3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 9.48008052654411770, 33.85841566836465700, 64.60994925529112700, 73.48474100716221400, 84.96444230182433400, 103.79953039192014000, 201.57757175364910000, 202.68582557982859000, 208.0762938276192800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 372.95125624458910000, 425.01820062838112000, 518.20199635378924000, 575.69273167134759000, 604.74907970658955000, 611.39264458267007000, 635.18253958009370000, 694.06209948848721000, 707.31503966730281000, 755.16446158698250000, 814.20933624238262000, 834.27571350248968000, 850.42759447308219000, 880.14813941567127000, 1059.83798134249100000, 1061.342217005504600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.3868481 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 205.73939603079509000, 207.74399699536730000, 219.93757012114253000, 222 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 33.09248518076699200, 62.02324926165421500, 107.18474862296146000, 318.40466044179971000, 320.74507427320469000, 336.38227457291975000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 295.79125649415533000, 700.14224480471864000, 748.44047603910417000, 827.35854710679610000, 859.81831034322579000, 871.02788795427693000, 873.02483198588095000, 884.24124440807748000, 921.21436646144014000, 928.81957370639816000, 950.51330129201585000, 978.33043271920917000, 989.01918193135077000, 1003.82551174224350000, 1028.47039026577660000, 1171.11186281163960000, 1172.93368661910 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 66.65075224329133600, 161.42591572007601000, 194.01677922316006000, 218.84855287530635000, 266.04019989940480000, 476.33516330275137000, 478.69997821788257000, 492.5774252880393 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 45.02961355014487300, 63.14214750781758300, 83.01969943749712400, 114.47629550462386000, 233.53244113125092000, 234.96436315610171000, 245.24579019763470000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 96.99051033770091100, 167.18158544435903000, 209.30438669002817000, 219.75622753025982000, 256.13455199032472000, 329.10356076131490000, 343.86958226259810000, 387.18415135462698000, 445.53389233216677000, 469.97407159292936000, 496.35555402723969000, 542.17317016232732000, 754.00797355459861000, 756.26149959079100000, 767 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 75.54340066734236800, 119.25918763965760000, 130.24168609179753000, 172.46815761433226000, 249.88849814954580000, 265.43625048710658000, 310.45348137443364000, 375.12652574730288000, 401.40753029947575000, 419.83846829932526000, 454.61907944478980000, 620.78658225684580000, 622.84948395706624000, 634.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.67069850720232400, 205.37529711475992000, 207.92820285007275000, 218.90812477811232000, 22 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.48645970083221710, 30.74263048830506400, 60.15942351875273900, 67.46617455391144300, 92.41963092102049900, 135.88419947714951000, 156.73746815940143000, 174.14638020289544000, 200.93167665486942000, 309.36091941556163000, 310.61020878541819000, 319.2458189964 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 62.91427486774550500, 375.18895740760200000, 590.67934600821070000, 905.36945483973648000, 949.50490606275048000, 1025.73321060280430000, 1066.54465822663310000, 1097.65638007821120000, 1104.53076244322070000, 1136.12550911672380000, 1190.36543575255380000, 1201.83438134800920000, 1235.34928270174120000, 1287.96431775779160000, 1307.63689117364360000, 1328.59765811710120000, 1368.59166200215740000, 1525.21967629669350000, 152 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 40.25184163883048400, 49.48690353757572100, 86.32300800485768400, 175.23723107334922000, 193.37594829356158000, 254.38701719980440000, 340.12265588409622000, 369.47829440353229000, 394.00020978833817000, 444.82132217651417000, 663.76024477358317000, 666.21186345180899000, 680.71047 [...]
+0.00000000000000000, 149.52403934416174000, 478.58280356298621000, 533.39759662290680000, 794.83292981675891000, 985.84436081167428000, 1266.35191281367590000, 1299.93947019234000000, 1366.20640542523300000, 1414.57287893367520000, 1444.54619013378170000, 1451.95497987578960000, 1481.75543508335250000, 1532.65630462152990000, 1543.08603222286320000, 1570.50645879089300000, 1612.60082304368230000, 1626.38591964211220000, 1638.86343753039360000, 1654.62166132217980000, 1699.579866124406400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 95.58647741792833600, 115.77604220679115000, 171.68764629385856000, 245.18621841595191000, 269.70541960573092000, 294.68840144207735000, 332.27051986591249000, 539.57965506369919000, 541.33741048653474000, 549.660866348 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 12.39444081714648300, 14.95487 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 338.17622229267198000, 393.69036516662771000, 662.80515792643371000, 906.26123596469722000, 1224.82688441892150000, 1257.46133074149880000, 1303.42618468468980000, 1313.74626771702040000, 1320.36279008212520000, 1322.55159872753640000, 1330.32847432978660000, 1333.37650658410010000, 1332.57715781086810000, 1336.38953118870240000, 1350.50238339329170000, 1357.90610004921430000, 1369.63658126262500000, 1398.56535949611020000, 1557.84783009763150000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlassolsq6[1400] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 579.01112086384967000, 612.95210391431021000, 631.93804055490091000, 679.14924915276151000, 663.98359247837243000, 663.78572765811089000, 680.62900300534875000, 664.06591386269383000, 689.55720570224844000, 682.30650941915837000, 667.715007 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 110.11229977410345000, 112.78490735008167000, 120.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+3873.75615352106020000, 3508.94947875008570000, 3157.86485306382290000, 2846.04118963136530000, 3071.53741218416010000, 3138.87607641795470000, 3080.74459860037360000, 3037.62889556841260000, 2956.35799051684580000, 2817.84836696578260000, 2857.15023938255580000, 2801.55791051535790000, 2706.41462547872790000, 2863.91140168584710000, 2868.56387993313820000, 2949.13921007378490000, 2895.44289053294960000, 2798.82750487925200000, 2677.17478745747620000, 2725.64160405949000000, 2803.3235283 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2133.80410593938590000, 2090.24666130932200000, 2101.39587699699000000, 2000.38962594349500000, 2005.88331828151490000, 2048.85514882901450000, 2048.26516376531120000, 2050.17248660372210000, 2113.92697990827310000, 2108.65097924405930000, 2097.00210904412420000, 2089.97988704201180000, 2054.55150689213590000, 2077.33168385534420000, 1948.20823694474730000, 1939.19179888124060000, 1950.33702106806800000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 717.88269913651573000, 575.35889371995790000, 511.08916284915750000, 692.24561951398664000, 657.84784197396152000, 588.57894010786640000, 506.54386482685726000, 485.30433043353509000, 465.49732887698860000, 438.57712347346956000, 503.53952534065581000, 531.49733719427877000, 567.14028840787785000, 544.74043531208406000, 563.64694188829924000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 547.36665398043738000, 538.29038848192806000, 537.27637040637671000, 545.91962708709298000, 533.29842332907549000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 308.95758147645671000, 261.82383830199774000, 236.18398927919677000, 204.38182768006061000, 262.05503417580098000, 245.60704234504254000, 259.50320226959758000, 258.58061937235198000, 250.3271882184 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 969.60708576467221000, 1031.10053339846760000, 1062.31588338876400000, 1151.58140221501210000, 1056.64303894297250000, 1037.13584804042600000, 1013.62300187431790000, 1104.84954827977460000, 1125.97787632542710000, 1202.61149302853190000, 1143.64226220347880000, 1130.24100450478610000, 1099.59315092273140000, 1103.91117742427510000, 1166.28976996459570000, 1137.20 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 57.109472 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 327.62345170506688000, 308.84606847417245000, 315.51171075256747000, 316 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 521.18392687743585000, 508.32111041183788000, 447.20120248107219000, 443.53548121950166000, 438.78387134780667000, 458.9478232526236100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1465.83745063779450000, 1347.03207372510270000, 1310.65331571397790000, 1288.17276991952670000, 1184.97000292699570000, 1045.36295586720050000, 1000.99608913456690000, 1062.66760159874340000, 1179.16626871376410000, 1169.06948018651500000, 1153.37456104516740000, 1133.53237109891070000, 1146.67089604076730000, 1232.23404279971190000, 1214.01923872839050000, 1255.61547036883190000, 126 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 689.91180824240939000, 690.21117599571767000, 674.70964548769859000, 601.91370243489939000, 621.34143435321937000, 600.91802648776786000, 597.96944421594924000, 601.349896179667 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 296.26627775339324000, 330.28959091948354000, 389.65898785430107000, 351.30989041301541000, 304.06363817893748000, 307.18336607344048000, 325.83238641708664 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 663.33236381687436000, 870.29043774770491000, 864.41215886929058000, 889.54726357054187000, 834.82688870081506000, 838.18944728118186000, 810.33093834445617000, 792.22510233897162000, 771.08841355842128000, 830.44993992220361000, 903.32714839941139000, 887.12946219881314000, 879.50306816714135000, 869.91810976761508000, 85 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 832.26686816796416000, 799.14160204677478000, 834.03914426343965000, 844.19055932197273000, 790.03017418268075000, 756.59262857941815000, 731.41627499115009000, 735.96106664369177000, 789.03430813246882000, 704.16169548151811000, 716.47885451751097000, 719.22747182263345000, 726.89195367319758000, 728. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 321.28965496175613000, 304.72679239403749000, 336.68403141235700000, 304.96957630246237000, 2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 487.24535346361711000, 400.69281416745980000, 265.39277409745324000, 298.28779404812985000, 325.76309731464596000, 378.38890591694343000, 464.30886751516391000, 442.70341479210333000, 402.59551961711963000, 373.59653066128141000, 373.61813175920850000, 386.9323 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1831.45521053189510000, 1655.37577174360580000, 1443.08354498647900000, 1408.81778698183620000, 1463.26113953651020000, 1470.84149109824060000, 1475.35575074837220000, 1581.51619443335880000, 1545.06556935237900000, 1638.72253774943920000, 1568.78336414781960000, 1564.14049845749760000, 1548.75208921749160000, 1581.52281964674530000, 1597.79384578058490000, 1651.94706668362870000, 1669.70255444154920000, 1618.0091856601232000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 666.26182963405836000, 641.30242882255641000, 672.29753228191908000, 795.56875040521027000, 766.38138725965712000, 824.91055900975164000, 818.47310502551807000, 802.45381282138874000, 772.28535832248065000, 827.44844173041054000, 793.46395901551682000, 789.85927818686309000, 794.35 [...]
+0.00000000000000000, 2385.39285002680120000, 2079.58009994024090000, 2074.25943775855830000, 1866.60110402214720000, 1741.41841165569210000, 1715.11421974806990000, 1690.91353961452520000, 1753.14878559737710000, 1899.06318809058870000, 1910.70106455957190000, 1926.73650716454130000, 1955.80956800616830000, 1887.77849594526900000, 1872.56306028079190000, 1826.91892892106760000, 1847.46065911245570000, 1829.70663236289240000, 1831.34675841448230000, 1773.26376684483720000, 1726.2139889168 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 762.46858826501216000, 753.56813598757265000, 694.52533728807805000, 655.26160276481880000, 631.34680714725596000, 680.08615061806029000, 615.22256564976396000, 662.39365502533076000, 629.98982437964037000, 614.90073761 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 109.54299747785240000, 117.831 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 1983.53345468535460000, 1954.21115933114490000, 1766.05568861874580000, 1869.28786807691360000, 1734.47539224001820000, 1637.34076461134690000, 1571.82172654181590000, 1417.12325297491930000, 1423.26513983085690000, 1462.81822091533580000, 1454.04000808977070000, 1354.64183865402470000, 1307.32558190657390000, 1372.03959930284400000, 1429.24314154627950000, 1467.10583880449870000, 1550.59580726751910000, 1616.36726440418100000, 1652.2098914688308 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+
+
+// Data from file x46.txt and y46.txt
+double x7[5000] = {
+10019.6268931192, -6784.90709540646, -9538.4031554377, 20557.6883715592, -26245.5799300853, 5318.71582277234, -2176.14452853061, -11026.8859912718, 4019.91455432801, -10070.0478024065, -3966.62940298016, 7720.24598408855, -495.612851010477, 20188.7322602904, 5792.66699008537, 4426.29253332514, 509.438603302275, -5870.32361697487, 5679.87065905724, 6770.35169040891, -10170.4900415646, 6116.37345151433, 1799.34378769585, -2160.61249763631, -9233.72251514332, 1753.10822570323, -10242.149037 [...]
+1965.95682238325, 21059.6148538852, 15424.0077669726, -2026.91643177487, 6487.2778984078, -11437.5547406024, 2609.12244221786, -8790.26925137947, -15059.1982409352, 9118.11332766692, 9269.0765423265, 28649.3242131557, 324.478498339237, 14658.3913822362, -966.395421457508, 18367.5367609493, -7086.28993006593, 9825.36726937443, 11886.1531808241, -894.124568802982, 23980.479620752, -4446.81362759128, -1224.10956386697, -8976.10876465485, 1813.32897140045, -5006.99155644056, -4736.6525383368 [...]
+13038.6273489608, 19332.9897002974, 3759.50455475419, -6317.88744545337, -14767.9877470048, -2358.98905557885, 7337.72854705778, 10784.3102012596, 11250.3398370885, 7622.18894582367, -6753.99561265862, -2545.22461595835, 22648.6374115304, -7294.97796984465, 3227.72336280676, 22187.2569946148, -12147.2508364553, 10346.4383487409, -6788.62688171641, -487.956604762587, 7248.73566129858, -19921.4396135113, -8820.14821571415, 11622.4955835264, -14400.8556811804, 8106.5704150618, -7451.1281706 [...]
+-10281.0747391412, 5743.95653857111, -12224.2827118938, 4590.08213405177, -1092.14207137325, -2401.57615614939, -10203.5066407478, -3828.83485336981, 4033.03752163207, 2511.01567058026, -18516.6263748681, 17411.6406238552, -12106.3011900588, 298.897852135039, 5323.60884861098, 21688.4741563993, -5666.06057477496, 2719.62909610047, -547.162940336107, 10541.2472060003, 21803.5885710341, -8867.18546675691, -9115.3029441691, 5821.51739309682, 2874.67680232839, -20611.0130302366, 4788.3662100 [...]
+-5087.4260798419, 178.797808132052, -4527.14448693758, 7779.0498070513, 7043.34691587342, -13712.7680704349, 10703.703562765, 1155.90053634485, 417.35220423527, -146.219851590432, -4278.61663908039, 15275.1258107716, -6993.84648157157, -11822.6311228588, -668.583588501793, -10658.8338552425, -4037.91322371906, 20892.8263454112, 4155.62091572587, -8501.6737125348, -13991.7700377299, -6470.78967454976, 1625.70201881765, -159.944118193430, -3735.09331592008, -13455.5859442253, -5609.8791938 [...]
+-2271.40563885864, 2247.33227806071, 30846.5007194178, -11313.5821609902, 3138.91096819305, -20530.1597399524, -12239.4579333335, 15855.6806788770, 4825.14252081877, 6517.65077326274, -12465.2905455802, 11765.7564616663, -13333.4500764337, -19714.9171631894, 9930.96512313674, -5510.00003889677, -3175.14614253351, -4661.40567144669, -10060.0880787322, -1685.64880292300, 445.254972328535, -7014.9541456343, 3388.57231710568, -1243.99961458858, 8475.49143197658, -2487.36330172647, -1193.2913 [...]
+5047.02558029179, -888.762077473047, 3036.97072767868, 15082.7099097744, -9000.93836834512, 10346.9147686913, 3210.87523212164, 4694.49635636254, 713.089338873923, -8502.19254566465, -19313.2844288171, -8821.66722403574, 5638.75191099374, 15815.3787998830, 7507.86025706833, -14775.6662269722, -31316.9243837894, -2847.58315498153, 21608.4963987515, 12393.4463518192, 5444.75678397821, 10403.8845415858, 7755.8554311231, 15836.6913142192, -2917.88222662032, 2941.5781413047, -19242.5090902882 [...]
+-6497.53312055758, 10644.5641955966, 13764.4503802353, -12398.0492203622, -6519.91654776829, -5971.64433855387, 2778.65072345946, 4970.88966603933, -12507.8039639609, -12396.4086390211, -4979.11643611500, 5500.27219995424, -4609.11442012672, -1516.32859746535, 1361.49683851409, 2603.52968527299, 15532.8008044136, -2314.31839478851, 16807.2945420924, 1805.13629014713, -7284.86793634898, -10770.5736250800, -1176.29077585976, 2722.66073958926, 23188.3100280491, 3193.35454786148, 10953.24291 [...]
+6392.12226694785, 4914.11669756949, 5309.53572550889, -5435.86352922818, -4575.30190880295, -876.866031445222, 11438.6295460098, 6779.57943684713, -1495.46407438526, -23727.7933055726, 4927.76944087867, -8575.60634956994, 3012.51558533736, -3651.62872013056, -4737.79975119124, -4492.62113347827, -10564.0598771427, 2639.94612782467, 8368.44895214864, 15427.8320600392, -1952.47347653921, 4178.24148884687, 4726.26758972034, -13187.8665856747, -10556.9655037781, -2334.93725631974, 6763.94843 [...]
+5055.69653833233, 6492.5378820971, -1733.66252000351, -3918.20268714769, -13039.4258227554, -4106.05752058189, -12682.3799200071, 15158.5849524779, -17221.6519929083, 6708.24321507496, 10862.7372956120, 14803.7854515832, -6642.5862258981, 8059.293440782, 953.275442964963, -9616.87126852853, 3542.39073367695, -5356.24129325454, -10491.6008872507, 689.879891404344, 1316.60118316940, 7294.45355669363, -3019.73234349884, -8377.08701316038, 5963.73134601171, -15949.6334406779, -687.1264347232 [...]
+-23266.9888045896, -12523.8829716149, 12837.126003407, -10423.9704827552, -14867.0677550369, 7575.96692404119, -942.709516282505, -16021.0734888543, -4442.53956717927, 5541.39071093405, -15347.7243039085, -9541.76669372521, -6741.02591977947, -6376.90151433033, -2488.79506672087, -24347.8633944277, -3647.46628730856, -12311.5502646599, -7370.77249662625, -17924.0991706198, -10768.0792838250, -5805.37012780701, -1939.26225272532, 19658.3066100081, 13410.3890948621, 2337.49178267995, 3725. [...]
+8768.81318083212, 1616.78114010670, 5249.72426065565, -4672.34910885585, -5969.64884260566, 1042.50772931779, 16600.7253985493, 6784.72004229935, 17900.2485922156, -6182.32827457775, -12751.6632856666, -24421.8115112093, 9224.47914533377, 1222.59294611570, 182.276015083875, 1764.79689377898, -7555.66120269505, 9323.43643740122, 14414.7811771149, 6552.27419528439, -159.169911570154, -2417.17979524540, -4187.78924456391, 6331.48784509446, 9621.65424814086, 14268.7760260085, -21287.59799943 [...]
+4998.39263524724, 19935.4034553679, 6075.97088005211, 6105.30938997185, -3498.08445980302, -2993.58395326108, 7466.3133709453, -8964.60639650975, 21364.4602356982, -10733.9442697152, 11287.7943045634, 14363.3241297690, -16699.8194931330, -1307.85842371271, 7309.30003853146, -2786.6897397012, -1376.81907382645, 3155.67296464859, -206.659331049447, -7094.6665703475, -1499.21196296027, 9716.15417854003, -11668.2259392078, -4265.26026674169, 21467.8206904821, -5642.63260751381, 6825.42166770 [...]
+3518.34927609815, 1128.81247066802, -1484.12501698955, -2209.23269456805, 18459.8572896101, 11739.0490270768, -13392.1001363447, -3758.97606756628, -1070.13167758279, -8909.21209420025, -11033.0778071767, -6005.63917702724, -14589.8963403814, 9750.19982205583, 14753.7407056209, 8435.12725370798, 2788.10217176236, -6045.72100952027, 9940.93608180074, 3081.47629978326, -2166.35715200503, -16116.5187111613, -8386.7425192575, -14054.5564245860, 6685.24661759409, -5966.2910083463, -14793.6662 [...]
+-11714.1742107670, 6264.46967454464, 3939.13278124128, 6553.46474557238, 8290.93461746073, 8665.48857912068, 7419.91211881127, -1967.51620171263, -11247.7297159798, -6704.26386428625, -14257.6743465125, -1293.80352146190, -3086.80750300746, -13326.8531978328, 15710.0308775548, 7704.64814064368, -1645.56191915292, -5187.76732361366, -1434.82510488681, -8551.3294736105, 6758.73250673247, 7451.02563189174, -1748.45446769484, 5007.43954094662, -1718.22940755450, 9700.19106306212, 9707.456993 [...]
+-5237.47115975167, -7947.02216796275, -4514.62599629688, 6773.88867386517, -2333.23559654082, -8336.34753594844, -12977.9898144008, -18026.9666579238, 3074.15634506645, -466.748576464092, -16623.3526625163, 24407.2046437572, 471.781116803295, 13574.9695924826, -7443.33028737385, -29027.3793890049, -12240.5197019919, 2346.18218946535, -18567.2675353436, -8447.0761472801, 3322.07130722111, 18152.4938460995, 7635.59231901392, -15060.2377822131, 3224.57064503747, 10483.0986217914, -1306.0387 [...]
+3929.18860204196, 10659.3309408002, 3891.47436793837, -92.3251608970134, 1030.68972730484, -911.029787660636, -5940.95867125484, 13294.6110338057, -9504.69109685137, 5143.53056642281, 8512.41360631533, -3393.22762848507, -3634.58751238301, 17629.0122141613, 9501.9855578033, 16581.124268021, 5630.15623575535, -10408.3913602019, -4579.02907071925, 8254.89309348683, -4499.0012922603, -15656.4840070305, 5562.59272520157, -1832.38788753863, 21684.199108358, 9385.09465312658, -3979.59996833349 [...]
+-7724.6037248192, 3860.27023753292, 7508.74904116571, 10484.2471275314, 16548.0193945667, -330.839782231595, -7974.51439445064, -1104.59528381124, -3910.68244513727, 233.638774392678, 8121.60586183395, -8785.80675539916, 19568.3171969355, -9330.38637650628, -12580.2012446462, -479.551331812529, 5962.4890457017, 14744.1469978961, -152.330703302417, 23391.7589214023, 9863.34276509214, 147.742071329626, 23914.7771076152, 11709.8632560587, -5331.83564507963, 4708.02585524672, 839.79398772414 [...]
+8540.09848365193, 1290.89902899454, 11431.6006991378, 6319.91533311798, -13949.853484607, -7757.46830200895, 13043.6597507958, -7582.00835931871, -1624.73643893995, -11375.2291152698, 13719.1102237065, -1405.36655667757, -21748.3588881229, -4134.98875296733, -4985.03202490563, 16011.7355318659, 3079.87682582300, -3317.76432399138, 3945.41050361505, -12026.5955360365, 7237.55547878233, 1003.79392372249, 12329.7567630115, 16425.2401304567, -8423.91607284521, 2496.28211983888, -12688.876217 [...]
+-16257.3166227139, 11454.8906720866, -8504.53843868098, 4957.09518883415, 13432.4684451617, 7841.49275240227, 4563.63124314874, 12014.4058508324, 137.372046687764, -274.742012256431, -12637.3270888291, 1425.00236088553, -1605.59258749286, -7859.77078487374, -3390.94706997671, -1662.92278653761, -18753.8463801105, -5066.98545151624, 15435.3621258135, -1236.20107271053, -4797.99958454779, 8424.8955744964, 5496.74068066866, 7499.09397199576, -1713.85037032795, -1535.19129740993, -5521.76061 [...]
+6859.83861612792, 10037.8525588957, 21566.2838746084, -3796.53177193558, -10463.5183608548, 11062.6575192984, 5381.13461654205, 7996.09543818853, -9731.25566624533, 10378.4248318492, -5017.70645012724, 10291.8390535712, -10956.1814619205, 869.677540144073, -12585.2755960440, 6639.59581637446, -9432.69867238035, 17531.175200421, 19823.7815372232, -18816.5485897501, -6353.68777787788, -4564.72736200635, 939.40170341632, -10321.5532876746, -7747.60629196385, 1058.77743821711, -2904.95194732 [...]
+481.170733547355, 13950.2863503136, -9167.03742978903, -22341.1436757507, 15923.3314026171, 17670.0517880978, 17195.2143093352, -16359.8872557695, 13167.3176153493, -10686.5868257293, 2617.00373008103, -4161.78699140047, 27271.1098231368, -5244.80795130323, -15048.1172697478, -1978.39938928508, 1827.99924751175, -10085.4754347486, -14864.7370470425, 4598.77438594002, 2614.51383134888, 1956.36528384616, -8105.62622018695, -4519.35126711103, -571.477931507185, 21986.7090614211, 11271.50350 [...]
+-4391.06941898946, 19923.1582351957, 8087.75530249175, 17119.5865751092, 7545.87698791663, -2267.50431908571, 3681.30980681347, 1046.60613808281, 19219.2570174414, -12117.7090699298, 4827.08797273065, -1251.47342636653, -8666.41868170104, 1876.70620531455, 11665.5003987049, 6537.62700473575, 14085.467922836, 851.779458313458, -9543.3215640905, -7458.3674572769, -8699.93704629496, -10253.5168478396, 3915.63859748093, 8691.63270003372, -9447.13820557567, -5498.61332143928, 1114.21727911329 [...]
+19710.1470125274, 12657.5235490788, 5684.27381392755, 5273.23693974932, 418.54621227088, 484.135707397693, -9566.23329076743, -5753.42027030512, 10687.7243874373, 1840.00437062419, -7980.56087269945, -20217.9727996318, 16067.3297540010, -10636.7298613677, 6320.5598751768, 6123.73999667999, -11007.9052864332, 12306.4499975281, -8058.97482847544, -6748.77612109996, 10707.1317128332, 4159.30318339692, 4741.88849313788, 9966.69442806602, -4063.1425728405, 10277.9118893257, 19273.6046375417,  [...]
+4548.13467612126, -5434.44206059244, -1766.50411982158, -157.383104746186, 2620.27930603498, 11933.8695554736, 7697.29391648593, -8063.312326329, 5711.51216711624, -17260.1533574309, -3325.45609735009, 21783.4960909884, -6671.49659383818, 8850.2963984464, -1899.57987678667, -14403.3290025636, 1336.18135553462, -2935.05624734893, -1312.53697208299, -6050.9573986403, -2578.03691433815, -9651.61281229468, 11207.6093555945, -23955.8133625062, 1658.01384892481, 7073.97018827099, 3340.68497713 [...]
+52.7307680384896, -868.215412205955, -3221.98363107956, 3198.29343580617, 26633.7550567975, -2600.15664853609, -6079.96420776001, 22605.1669311513, -8563.17635594564, 7408.13808078572, 5961.67804533961, -523.760133463392, -5956.24023451268, -17472.0723350231, 2910.41371495364, -14187.9924299746, 7117.57915442234, -8149.21520299894, -8561.75805655145, 5308.99584773827, 20126.4954148813, -1661.00886905714, 5871.52869604366, -6559.55614915547, 3389.4326483362, -11209.6337057831, -11389.7251 [...]
+421.860483481563, 7574.43299910411, -11844.6708174953, 5865.27905524718, 1976.47717616255, 2547.17331283149, 6781.83551770299, 11008.0882158141, -13503.7215992522, -11103.6700351380, 1174.28119814777, 1316.25784129614, -1840.25038165167, 6984.27174183752, 8331.81930097124, 9808.47138514922, 2780.12010292238, -21011.6186694657, -6016.11570304014, -1072.02005628351, 21933.0766215145, 12354.3844743302, 11910.2854746687, -6819.71211617469, 11206.7826341021, -6300.17164751432, 18111.950136199 [...]
+17379.0870544017, 4969.14116676648, -3988.87376844657, -3763.12360549329, 7274.99403154397, 6416.25980589775, 9123.90435557, -13659.2282440493, 13773.4478551017, 5956.67577476702, -8047.49781219833, 7515.67262034003, -12689.9293471509, 4800.62774387789, -8684.71213674219, -5258.34614171658, -5626.29315297522, -12819.4880469719, 2884.08485520363, 5493.4507109996, 1131.89496213083, 2219.09491685402, 12240.9720740424, 16220.9041509515, -7701.99044493345, -4188.56041569856, 6060.22889417132, [...]
+74.6278045520261, 8979.51386173372, -7152.93008395364, 667.417570452756, -315.188033595239, 15184.8395024423, -1626.53034016087, 11212.7355463250, -703.782771804538, -17836.6413602636, 1105.18201796894, 22801.0325667645, 10437.8197184231, 6493.45426406366, 14014.9022188320, 9913.16582903948, 4229.36743909927, -17372.0775107603, -9655.65473416487, -5436.84523859363, 10311.50321111, -6494.21252283947, -1639.38444155114, 7194.02351377324, 13365.0324776119, 8451.80588036034, -18215.846684374 [...]
+5493.43229574884, 8909.33793402030, -4813.33143476013, -23352.1371140125, 16373.8096243044, -1368.67011739508, -6146.10002065156, 6714.96033718591, 2178.30700863905, 7256.44686247131, -868.89114642785, 8274.07389404205, -10551.4171977770, -3891.26433169463, 3296.59450246432, 4845.88847588255, 6857.55929840964, -624.237615568937, 1865.35716579971, 7492.42081134742, 18113.5415041882, -2404.15416476527, -13562.4467585524, -8597.59108556437, -9269.65740299949, -6443.45167471055, -950.6122786 [...]
+3358.33922514502, -6059.12651762352, -7052.92448743344, 4999.58330696725, -22.3200925103054, 19383.0640632642, 712.535647501468, -3800.88982320557, 18088.3575512822, -5375.48793826093, -7395.03047409286, -3027.26747365232, -13052.1868785126, -3466.01961349461, -1645.67070768259, 1573.94314463414, 3840.94995024026, 2509.34187402126, -12095.4009158913, 8249.49169018573, -9785.6946729627, -14342.7085297786, 5697.48086424322, -11057.1142641046, -4175.23966730137, 8020.80570653378, -9638.2322 [...]
+2847.54010083617, 6591.90707748064, -1110.56288396363, 6218.19872271902, 7923.11911250643, 6517.59462968502, 5663.54106576623, -8137.14127879098, -5121.33275340815, 10195.7525613981, -2698.13849713338, -12814.1440467387, -2294.13023477271, -2909.72133832803, -3057.89038416585, 1409.78002768239, 18142.6790454156, 15445.5415560776, -5380.2549189459, -9146.95135880265, 7735.60411606094, -6013.34531304577, 17566.4908707300, 4657.38188459449, -4026.91660039386, 5570.76140030236, 37.5769655825 [...]
+-19099.2300693221, 17482.0280498313, 4832.7147175649, -2612.62463882958, 7604.77948207823, 8083.2077817303, 3236.04012153829, 6617.69115867768, 20597.3987932017, 29.4311097231173, -1339.20657671260, -4488.13649900594, 5959.3678988152, 3995.67018225227, -3969.12148926675, -14995.5409423776, 1079.50689805275, 12881.9019676581, 4961.92842428874, 1245.94100804156, 6260.86154828627, -11715.8221227952, 13935.9621953029, 2221.91431859312, -10940.0941953505, 10371.7293949335, 1787.60595668309, 1 [...]
+-345.513741508697, 961.8327781975, -1213.97412293342, -9431.08707455797, -10588.8537702576, 18155.7592545859, -559.425560874681, 9684.56705194448, 887.930411428556, -7145.24113466638, -2765.20757354903, -6357.88245431328, -4162.70457284057, -14050.7651430768, 8665.99672574884, 8838.6127021536, 15141.4510621420, -4544.86103177388, -10002.7134313931, -8684.1117481277, 6710.28394755541, 2019.10101432935, -13348.0162138254, -8764.92393704826, -13094.7077564095, -11175.3036598236, -2464.88498 [...]
+1504.25300381424, -2540.75607298831, -1428.77488290800, -206.477509367641, 15083.5549237553, 20402.5764285183, -1657.70041165655, 16372.1980671966, 6391.73593983542, -6157.48320883413, 2894.51909171297, -7904.90890939468, -13020.0378535994, 282.949242966999, -8856.3874445392, 12876.1846799188, -255.818913913995, 9754.83961074957, 18518.2186015009, 6021.76014640625, -8684.40438628873, -1657.64510298366, 6849.22535003401, 2062.67854723008, 5021.14488812138, -7590.74752778905, 13346.9775551 [...]
+-12455.6122517056, -8498.94236306324, -15071.1334465938, 8373.02521566947, -5794.57362423485, 11304.4281433416, 10881.3367950879, 17963.3156974771, -3329.45744194807, -14562.5181435983, 11089.1093570496, -3429.38799641491, -9856.21906267139, 3784.27957692823, 9987.09466551855, 2430.26224904855, -11992.3865776430, -4588.50481132032, 14074.3859342562, -6938.35896947198, -4311.61477273777, 489.142005575051, 835.296835563506, 8422.17143846442, -5710.53470610866, -7931.3659913091, -1004.46651 [...]
+-6576.22654541311, -22727.0922591148, -12612.9359655307, 9621.89725766464, -7715.16593181522, -2079.2016032615, -1419.75393020969, 5280.31317910693, 5180.04609362112, -5526.50283321286, 16834.0596285429, -3886.17538627302, 14735.9146834218, -6605.49147819164, -12402.9015956233, 4546.28637031083, 11952.4273869698, 12968.8480667074, -5940.02587964276, -17903.1217136488, -11113.2844185841, 2369.67785909401, -3745.3791920228, -13287.3257876959, 7900.95713006188, 2944.25984140101, -4351.38133 [...]
+9961.55353981266, 19831.6935496287, 444.29927453931, -4699.94332519392, -5811.25025249178, 3730.85459422936, -2206.26231789737, -9515.7504479494, -5464.27930308421, -17147.7135918225, -9731.25794506641, 8124.32659759636, 2276.75908345996, 3315.62531130249, 5106.47326898726, -13662.9876980030, -5153.03002710246, -9058.89402999397, -18040.1634403175, 3590.9947556992, 8508.74436015798, 2879.08402316473, 11392.6691284847, -7762.83731873031, 11606.9034280894, -5966.49886809123, 6895.097155087 [...]
+6911.7840861914, -7922.26563657823, -8386.54451991261, -22674.3421481390, 9817.8873281951, -8306.34969374575, 19485.8673883702, -5411.86638823511, 7104.14922526069, -8000.88958789636, -6190.17306269875, 21366.2253244255, -3134.2384555049, 4115.92805988232, 20919.5126521901, 3972.15947527721, 2679.98707850377, 919.965428014725, 2351.21396406321, 12655.9567455166, 15134.7228528788, 4789.08601672778, 5452.825922373, 1458.82435518855, 10454.4724188564, 14012.0736009061, 8268.49917432748, 844 [...]
+2702.33956949284, -1199.97042350666, 7017.8581556379, -19694.5661184476, 4702.03817581587, -1917.72067796632, 2470.30027050122, -13291.6004295002, -9060.765109091, 5122.5317736186, 11479.1071020230, 1689.06076811714, -5593.8650697199, 19082.8258516732, 5262.26628669184, 9726.01269758003, 11011.1923190774, -2054.36858820925, 6611.08611149084, -554.004285722936, 7582.34068199302, 7152.48228640108, 5491.72157038781, -4587.43322844169, 11416.4544103038, -3173.33606524046, -8922.28723997871,  [...]
+10466.3785696909, -1909.53828421588, 22104.5264102925, -6213.33815316183, -2364.78746457297, 11639.9088420724, 6465.82722954914, 5658.92169275626, 24752.5377448731, 8580.20543932925, 1169.2093317669, 2980.45593302741, -5336.62240538644, 14245.0393946710, 1787.66614801154, -2919.31315205962, -10284.3098390557, -3355.46519579834, 10078.0662949818, 8840.94810080059, -22169.0901597684, 5861.69641249102, 12645.3592048545, 1145.19474211140, 20455.7470134985, 631.659646251777, 957.124897747676, [...]
+-4446.32187498052, 15875.0703294151, -11683.0184624961, 4941.23726471698, -14393.8427388145, -13371.3431749610, -10135.6988254985, 3700.69006477138, -10092.3810836081, -4944.28242131659, -5591.25954048993, -14466.1650415911, 2744.87581926915, -3075.82280928078, 11811.1834318280, 3520.8525754885, 4062.07156580584, 20659.0258853230, 13164.8825766687, 4493.8146876976, -3745.37513328553, -4684.03578728723, -7086.52117912113, -56.2788839371214, -16509.6424832232, 14996.5721992562, -9743.24008 [...]
+-2938.11367566909, 8020.5657279616, 6012.72250412816, 12078.7791370033, -1780.06458471308, -2431.67341042445, 1816.49588212419, 3405.5280442074, 7325.15517536151, -8787.2962141821, 4689.04355954862, 16518.6095083923, 3550.21126001952, -1066.43132269611, 1695.52242233612, 13747.4740799229, -10056.0389576606, -13471.6654807821, 7648.37593089568, 6205.62552015056, -36.2159968967977, 4789.63238178418, 1479.78831859501, 5522.16275001300, 9230.29792388943, -3504.08151763625, -15341.0282748966, [...]
+-3154.81518035068, 8155.78187992077, -1753.23620221275, -1764.53826106685, 8161.44245894964, 15636.6806452789, -8289.4142955965, -1851.68481396725, 7102.60686938262, -1046.63716984776, 901.733619236938, 21837.8436289393, -17774.3815841089, 2210.41459071678, 579.059324361013, -4298.52915341944, 2725.28235349176, 18765.0743200033, -2484.56685620480, 4633.62518426547, 4035.19075243351, -2900.39330952375, 21246.0972815640, 10869.5980638350, -30234.3717714882, -4414.55263793588, 19755.6607842 [...]
+-904.832461341074, 18010.2423543126, -9258.45810321624, 12251.0668161388, -4705.06903771785, 1100.92802659175, 9821.53272093567, -14174.8879907144, 2012.45161406504, 8573.45525106667, 4325.22001251773, -6373.30152272167, -1914.06094834530, 8578.66023123234, 6608.25573176875, 8106.35054789835, 2889.62920507767, -5405.53770055445, 3001.58163356175, -4098.29297137216, 5340.50745843043, 1153.3446760266, -8712.86991375255, 11762.4484610559, 2480.96343151381, -76.437345029518, -6684.0893831646 [...]
+1788.78588603605, 5317.41740146853, 6378.35492311221, -17743.0570981060, -13446.8621941009, 16755.9037207787, -8260.75181108792, 3989.37658714443, 12318.2761106550, -3449.97457785371, 9859.54846781152, 7967.82999096144, 3970.17232181156, 13187.1358934621, 11998.5457171559, -3159.54901702945, 18692.8197912793, 15618.7536395984, -3130.76324438475, 8197.56418340124, -11253.1111925684, 2560.57469144418, 14102.7883740672, -4981.95158524074, 10417.4593716969, 16898.5249603299, -5967.4581546933 [...]
+3562.00135296178, -1206.48872086239, 8892.50458104738, -708.870144795159, -7674.08998315815, 9930.79256060628, 12136.8645360374, 5646.9805698002, -4544.33972839994, 2015.36193455966, -6278.39499373378, -4743.47005516796, -2688.72018341854, 2306.16868858035, 14330.8997218379, 10593.2193114091, -2461.28767455681, -16213.7998732227, 1281.74855075995, -11170.0699781083, 1262.61213395098, -990.744129411308, -5612.22907254429, 7017.29558934434, -4543.00005547674, -16402.7811304775, -9692.48730 [...]
+6353.52468385178, -6825.37981962595, 8061.13738927389, -907.457600993587, 6215.74156758286, 19540.4966572510, 1168.77755639345, 11959.1028003270, 3391.84193734834, -15260.0657126734, -9551.9368795838, 21511.6756800546, -16160.4198758633, -5249.53144091764, 2580.16539208699, -1212.92974592120, -2637.31237257037, -6805.79865773223, -14842.8050794885, 15046.1464656751, -26994.6961555065, 4495.94969279247, -6540.212299014, -8492.27866437729, -10606.4575320555, -1141.81525171373, -7761.404673 [...]
+11459.6898736022, -2251.81067702117, 7244.16128326345, -4614.86637537742, -12247.2681877770, -19663.8404555415, 6043.35075719477, 24381.3769988778, -11237.2893540766, -24509.9908935585, -20121.1252969316, 11287.1475884456, 2279.32011956085, 172.647715648886, -762.127831961408, -11240.018526555, -12134.4469085479, 538.357824889492, 658.766381053792, -19951.2618078740, -4224.85829516757, -3641.59024216306, -2075.72045263155, -21739.9438658022, 21096.0996939983, 13567.210854556, 1381.672089 [...]
+-8142.11925190504, -5084.97065382987, -3265.96652836693, -3329.60274102741, -15259.3514902910, -5159.94794248052, 7190.8768172075, 1363.35792117811, 2892.27584390893, -5450.83429471937, -3466.08741421433, 4462.68096749664, 14172.3820723197, 8632.47696532992, 16887.3166768452, -9590.1208203712, -4931.2771325484, -4599.24915043155, 18506.5403257132, 5740.43757298484, -13634.1159861529, -4328.62537812449, -2344.20162533364, 7175.79181515759, -4942.70424106653, -3027.48506151328, -10987.6943 [...]
+5861.73914071475, -8340.70230109954, 9934.86066426057, -11520.1018156040, -1830.67278283559, -11017.6008380774, -10717.0944630390, 19674.7417559745, -2336.92830686031, 15659.0297443929, 10159.3574775719, -13531.8658968025, 13919.2337665409, 8.20621919189852, -1032.03784694696, 513.277740746496, -6733.1582960314, -10468.4085189338, -11677.8642619496, 965.696537443933, 2757.97580605666, 3802.68938888054, 22344.651422286, -21116.2293177005, 14193.8028213895, 9783.06350508307, -10505.3156998 [...]
+8269.0656792509, 8733.91798786839, 8380.38793257715, 3418.69273949645, -9790.92081014874, 1098.3288122426, -16018.547947299, -2611.98122335386, -1850.71132549046, -1760.71915221150, 9210.3931742877, -13295.5546026010, 14270.2474056901, -17497.2349744962, -17720.4272423061, 19840.9059708217, -5856.22348939097, 3051.39450251591, 15473.7354373868, -87.2265225535003, 395.451115528574, 1937.67745561428, 8862.665313294, -4727.69838705898, 1842.99299338967, 9795.5657987651, 36.0480684296445, 62 [...]
+8961.6221524302, -7205.17428153502, -278.843237555949, 7846.05897044064, 14723.0601876981, -15578.9055109276, 6130.29012724039, 16625.1271047111, -10329.3876793959, -2433.23514806428, -9177.71735675152, -2933.74381201035, -6453.74351834463, 6863.83592991732, -1741.32555023588, -16598.0267218431, 3593.17957192548, -5820.06744978971, -1026.76832161054, 9294.01238684908, -126.298016642675, -4085.67749083585, 9881.63330771671, -5766.54032675416, 7866.96604239926, -1185.83701023264, 11037.908 [...]
+6861.82820021002, 9084.78172782265, 15121.0693699711, -2227.35358500169, 19580.1994183781, 1142.40139517222, -666.495633727339, -10949.8725955729, 7372.26334267333, -10588.5790150377, 20935.1330524490, 7978.92437503158, -10143.4700092943, 2313.50561674898, 20417.7386769654, 13268.2638043513, 4734.7058222138, -6867.50269008316, 6987.69973570343, -17483.7867159003, 8539.045942631, 3334.54350174363, 16221.7597889441, -2832.92059910308, 15164.3723017493, 4112.59663749734, -5226.42896641982,  [...]
+33424.8564280134, 24454.9178842311, -2266.95276293268, -14184.7260115915, 841.574460448782, -3764.1394445746, -987.663868559955, 16539.8984633395, 798.668112174439, 2676.99703852028, -8357.99710825851, -6356.68343364065, -15542.3495776430, 5984.29827361783, -423.07538853095, 1800.33186434377, 2423.58254149878, -7933.01945986734, -14344.5418648502, 3465.31155600323, 11070.6427883549, -6738.4932985553, 16846.9628125143, -980.365941542, 6824.62549587812, 5114.74377548488, 10044.4398086764,  [...]
+9961.71544986905, -2317.96995314393, 11407.7537893978, -8239.7559914607, 10657.4978855986, -7135.8268935722, -6844.26760374145, 16903.6701723358, 5972.25005250507, -1057.60407345901, 2975.56426797138, -3042.86981914829, -356.969225465495, 4083.51230839586, -10337.4880909509, -4380.13110715309, -9304.56489424548, -548.403718658652, -5168.66269498042, -8959.71664154285, -5655.87047772953, -71.4906653720585, -1121.40124407110, -311.737336041241, 11386.9923365892, 2009.75294117646, 943.63916 [...]
+8421.29457742834, 358.062679615039, 10619.0506070763, 22657.6006983852, 7461.13473014013, 4270.26957745007, 13705.2350371836, 3482.85958661724, -1003.51424985972, 14046.6487294510, 7349.47978503217, -4315.55233869832, 956.650440501337, 4101.80653095523, 510.149066305534, -1355.24672905043, 3135.99516037381, 20637.2408473326, -5307.48971579696, -14448.1040521231, 14133.6481878717, 26052.8541474057, -12229.5568619645, 254.619099113595, 260.886430312171, -986.81359015585, -14303.113465127,  [...]
+-5373.20645110677, 7832.92921833114, 10974.4489309728, 14477.0894337462, 16966.4558103988, 5762.94043807008, 21138.9784369202, 19149.0485315151, 2938.04661753646, -8980.66416734543, 4221.65841589059, -11433.2754134699, -1791.99539192733, 1323.74245113516, 6429.68638583463, -6967.29059422642, -10460.9072178165, 406.746529573166, 4230.22611471957, 1752.60504614317, 2756.38132844108, 18972.6993579207, -17864.5622212806, -27001.0638269005, -18447.7633616672, 5222.92714548566, -15368.79944986 [...]
+4566.78845055701, -11086.3865230836, -10179.6395929098, -712.123838612541, -4786.01090901708, -1144.60989628778, -3011.03538868568, -118.835155429413, -10756.7153480950, -2577.32423594232, -4821.15741768605, 6029.87189785389, -3438.16817257678, -7148.20725117661, -6867.16083246968, 1249.01238959114, 8397.29888820716, -11459.9567715600, -2395.56149447884, 3014.94114558617, 777.460243357082, 4054.75460248759, -637.433321952595, -6578.29889080297, -3400.05133823235, -3583.68958315724, 579.3 [...]
+2300.45838932230, -10000.3998862343, 7923.52140563741, 12498.8009531865, 2161.94423044538, 7745.6859124607, 2.87364999025225, -9549.29446678402, -15100.9384656348, -1528.39145271458, 114.486645548983, -5470.09191993462, -10891.4556502654, -1964.17851958687, 18999.0354700294, 3675.75435064874, 11473.6998661690, 15662.8715959055, -25740.3793844725, 5349.53340632746, -6194.56694654467, -14195.8906159440, 12430.8146611085, 4417.49527807587, -4697.51613483863, -807.08556951568, -5112.03337631 [...]
+-3031.80315500797, 16347.6457142382, 11885.7597306739, -16462.4451860328, 5509.24765358647, -10060.0952526341, 427.104665917111, -5756.486296559, -685.303018442153, -11496.0772720698, 1207.56828873223, -8936.79965546973, 1470.31495667512, 2180.27581139748, -649.404801474771, 12695.5746925494, -10774.1078922038, -5954.95404371948, 6707.03175521264, -7172.53335386077, -8275.46243299154, -4524.88247639947, -2339.03767225767, -11483.3626339922, 16826.9094212621, 10028.8094390832, -7444.45885 [...]
+-16729.634894395, -4602.15362750053, -3280.35945988327, -12016.0238859688, 6615.21450003106, 4964.55478731376, -2011.37942125004, -16018.0800118305, 2161.17065044014, 3771.33717943916, -9562.15777367269, -2569.00121559162, 12041.3847028976, -4599.63991052498, -5234.77464505341, 18070.8375319626, -674.77356842271, 11451.0070598824, 9438.36311805618, -10792.2425737443, 20000.9315054888, -2153.03214909441, 6268.70420983673, -5423.46163512397, -7783.50853476802, -587.170129114629, -1801.7139 [...]
+-3970.85716221463, 6484.74961964652, 5254.30603335803, -86.3621471921975, 9276.13956955716, -10013.2759969980, -755.997749291945, -7202.8042573816, 15864.1984554455, -12207.2819609424, 4791.6358609101, 429.665900026409, 12362.8802865606, 3929.27322259354, -1576.16678029912, 13789.558045196, -1775.907573007, 3626.12053715631, -8854.07157335937, -18048.0171653035, 11631.7333795001, -272.954541737148, -10281.1059633690, -2689.95627626038, -7881.31454779161, 2385.65339551166, -1596.541368832 [...]
+-7683.23003162168, 14791.3602288680, 9826.94699324807, -15718.6827113066, -1839.24017990097, -12979.2587595607, -2251.35794049884, -8030.50481020197, -5133.37759103248, 1683.81936401820, 5351.67910966219, 5466.77558524543, 4047.43750375781, 12963.1646904279, 2902.83208384652, -14267.6746042069, 4949.7225142591, -4204.65757434492, -4418.4024206474, -13890.3545232548, 13540.3833555859, 3927.05581840686, 140.939956966637, 7256.65077704376, -198.363495736807, 16439.4723880335, 6336.596543223 [...]
+-26595.2453607902, -1398.01845401012, 15765.3182784753, -10060.8767326689, 4178.66416155251, 4039.57871821176, -13884.7863417651, -4346.92296111861, -868.749527354115, -29144.5281769853, 2424.19949916937, 11.0835348751408, 7449.28561246307, -8191.51077743619, -20.4457053286476, 14462.2953782123, -9876.59446173178, -8240.222973629, -19601.3448995956, -13619.8624493912, 7273.99470694992, 3160.99936861339, -9578.3297550141, -2695.11428541692, 4625.15378805474, -5947.35120430922, 7992.260525 [...]
+7063.7864780238, -9154.76941725079, -11560.4803089626, 29723.2497569783, -14962.3275424791, -4046.77976937966, 8493.03678748403, -2991.85310281351, 345.40414677878, -439.415436723486, -3943.42702786965, 5981.83961769225, 10456.9887616734, 21046.3946317083, 19751.8793549274, -58.9294443642275, 7663.04624966234, -4716.29484767278, 890.48631629721, 16001.3097510467, 10764.2144047846, 1782.04383310787, 2187.26655832235, 7826.0941894431, 14076.7564105922, -9507.72414234173, 10438.7260264246,  [...]
+7078.0188264347, -7564.46071927532, -5134.2860035361, 16574.6793464634, 3712.3237662611, -12239.3633484270, 1421.3194731684, 15051.8230780432, 8509.51091309926, 6402.68019785954, -671.085525291243, 8482.90767204774, -4868.04151918431, 1770.12023008291, 9681.00099171071, -10322.6031356234, -2186.05722326150, 1481.51422814021, -1389.77789276645, 6708.71129598399, 3526.19083850585, 1623.71758584947, 6672.5638582344, -1296.37153369983, -14745.2544616178, -10896.8507458406, -2361.58545974625, [...]
+4372.37965840789, -14882.0238332776, 4959.68250137112, 6886.50108763008, -593.58663141907, -23344.3082012313, -918.02066674693, 17529.3130523417, -7093.49025160529, -7222.12071491322, -11091.6170983304, -8366.05718095803, 1000.78528662117, -651.062163717539, -3387.29716810418, -7410.16319093491, -5060.82038219822, -2800.02514081892, -4939.29440442881, 22533.3999272209, -24071.7953547963, 1444.96540603716, -4982.91127989171, 15725.0003067387, -8721.89465348438, -16441.9285107335, -14818.4 [...]
+-12040.1019124073, 3267.74035040621, -5561.70133124097, -13462.4873478176, -6991.72519490976, 15888.1676388241, 17938.4672532824, -23925.1385753022, -5230.60305334505, 14476.5214254417, -6030.96068145567, -5790.25040455774, 3027.04140001988, 2863.12652167431, -762.898640482919, -4420.48092909304, -2223.66323151982, -9896.43594515518, 3375.80809455713, -4953.48051693435, 792.527718418755, -6383.39859721081, 18170.9053461694, -25459.7864236499, -1235.03266749297, 13999.1101869339, 12361.53 [...]
+-7596.20252773636, 4372.8860907798, 6500.48226012126, 7546.70019621364, -8418.69000537947, 15085.0487102011, 3321.0363195695, -13028.3622861004, 6688.61187018902, 2090.77855792737, 11980.7803377062, 8531.39920153846, 11710.1341236364, -765.30479613586, -2078.71685163425, -2507.79799749546, -3049.82859948726, 3694.67109055028, -7461.88256813032, -1863.31132334739, -10095.8350656103, 526.272044664698, -9837.53130527138, -3361.60742680976, 5018.40792498857, -185.684958672139, 8915.681602040 [...]
+-12318.5931151980, -4687.10406344879, 3951.44355682478, -17631.5404325807, -1337.87629620158, 1358.12805614496, -2010.41922330363, 24306.8498845641, 8077.10064282005, -5867.01334185702, -13101.2135514057, -17660.0797212937, 5283.87358379691, -6333.79147701101, 4916.32553607454, -2803.47559350047, 3087.05998748986, 2357.40112140022, 5767.63650709134, -4729.47571783405, -2773.80068885427, -2175.19259914102, -5607.73692173966, -6180.2992135733, 1474.44766716376, 799.526241644636, 6503.87808 [...]
+9461.50134167993, -5581.72000208198, -9196.1240961257, -11189.2769802302, 1020.88237807896, -18614.6531812075, -23991.0471172508, -938.150778141754, 2542.92672482058, -20941.2734591713, 4782.38045340187, 7617.70211887293, 6276.22337216461, -20919.5475468019, -6739.63630677055, 23109.1561778046, -13210.0110587647, 10967.5625667529, 305.901355284727, -2180.90865142198, -6434.42604110765, 13076.2220817778, -2989.16919464675, 4129.85927028834, 3494.63718470678, -18338.5116559541, 13357.05962 [...]
+5300.03307069335, 21235.9095346987, 18408.2643729613, 25757.1056433239, -11683.4236054770, 10941.0779761890, -20035.1381661592, -11085.6243843784, -3986.59848970321, 9329.7737277624, 4303.9535224935, 7367.82128424404, 10791.8008013693, -1741.60552226082, -2512.126283873, -19492.0225600341, -4001.61619991087, 8229.73819681482, 6871.4888186973, 10373.4255097118, -7332.65153923744, 12196.3964994291, -20129.6039854971, 5233.02684296525, 2449.53126643556, 5104.32650974078, 18465.0767761343, 1 [...]
+4887.84168352685, 18533.4377741813, -5832.85777378767, -3547.14373779118, -24105.225548251, -13729.7443059414, 10777.7161182840, -4567.1283145939, -3660.23498615323, 8229.48275283344, -3397.1215945176, -10258.9253077624, 14482.2145150063, -12625.4330302288, 5129.28798506258, -13120.0378697165, 1604.69451205073, 7610.94801935985, -3732.82665543091, 4831.95929818322, -3185.81306647905, -7209.86935141327, 5828.65394737147, 3988.23481573812, -7558.42286729104, -3148.22852963604, 15374.490872 [...]
+31515.3736946266, 2537.13677491461, -15263.8300660748, -8585.74347842994, 11557.3998766865, 2423.53319328431, 6663.82320885047, 8053.87921447283, 10551.4930427369, 7516.80399371372, 6908.44895293758, -2685.85683457859, -3397.32496864893, -13989.4308510972, 4380.33810029949, 1361.41585401041, -11866.7294114635, 1627.55673370059, 9798.04334979529, 1544.13053585441, 12593.1837712394, 3164.70172543388, 6845.13210500404, -6156.14102893479, -1013.23538059977, 7889.13131767632, 2877.49294014938 [...]
+-6891.68617661743, 2930.76433265516, 20406.6733092851, 2729.98999149256, 3067.04633591020, -19134.0191058983, 21347.1593092233, -22995.6154976731, 10616.8877596895, 7636.30315185192, -7205.12197691765, -8089.07639678777, -1390.95789479843, 17392.8080927830, 168.049090086453, -12404.6632178757, 617.378466820317, -2636.12921122459, 12728.5422912687, -8090.71538881803, 1859.18875927818, -15110.1698313800, 4082.96353180117, -379.498365668410, 5527.33586331804, 18983.6069125838, 3244.18462382 [...]
+-17216.7537650515, 1839.26349671857, 11079.9441200385, 6045.0496208385, -17994.4678935272, 1857.53380080218, -8019.11352726168, -14029.5348226941, 873.06345071682, -9326.35591913983, 3457.60559072876, 6474.63319351232, 4500.34231151363, 1703.20384342179, -5001.37336517168, -3477.89123381410, 1755.56343444275, -14771.7128321925, -20552.4965130202, -11032.2608187715, 12347.9396130101, 12918.1438910382, 3075.96623650827, 12971.9758873755, 10008.0555544429, 14225.9953368412, -11709.750298563 [...]
+-6536.42585591582, -9646.33856850165, -5886.40794581862, 11096.5638283745, 16390.6254490467, 11346.0910175482, -7428.05577334401, 239.657681114793, -17341.3403964538, -8563.65909537128, 2261.18080332796, 8016.77164258217, 6833.86702260029, 1569.37244123298, 333.511673329860, -9069.07333451177, -4804.73047036118, 9962.69516090623, -3596.34137800587, 4016.89584812226, -11412.3857718095, -9527.02960593809, -19074.5995663733, -3849.51155691317, -4143.9148586778, 3506.3197981675, -4970.649182 [...]
+12725.1702170213, -6139.4588929461, 14118.7632646375, -531.421404402867, -2926.49414278799, 12616.4238629939, 5972.74323932153, -10418.8175859753, -6593.10828760994, 12527.4339546277, 115.687573221790, -18418.83450484, 5625.72893601, 3338.76689128614, 3311.77387477255, -1871.15120952613, -4047.11547256605, 17272.1805827891, 10544.7072767468, 13791.2039951284, -5523.53803554371, 8742.68360518056, -13440.8433994511, -18559.1048778731, -36.6371217473207, -14699.9357502003, 5106.11058809445, [...]
+13103.3878315188, 4983.15508674502, -6877.00892527321, -1761.06126810018, -7224.92230650819, -6229.42909580787, -12163.5506445841, 1129.62450926840, -14272.8412925616, 22788.6860838013, -4954.76735698054, -9092.41022037444, -6468.05688203606, -2402.27957535532, -4466.89473988024, -6821.11057737149, 3600.51487680271, 4334.08662009039, 5208.80631831272, -6471.34580102549, 9195.76744514784, -10614.707453758, 2461.56128980124, 10940.2569552606, 2523.46931383654, 8841.4624783104, -2619.465997 [...]
+-19823.9483853313, -8915.85913393839, 15572.7909194871, -5657.31651848186, 11730.7781760855, -7574.92793450297, 17051.6252209515, -9064.11337252072, 14760.0233749733, 16584.1025646157, 2991.04036216445, -2962.00490886303, -7854.43753835379, 2672.1583324275, 20533.4787608465, -1642.54905995713, 2526.00543030638, 1328.50221378627, 1976.68721308948, 14823.9165566184, 6711.36172822421, -14919.0831284728, 7590.21521793576, -13326.9296700632, 6927.08758144116, -7119.25417001885, 7289.734575524 [...]
+-1554.42531802856, 2214.8462118324, 7215.8305479171, -726.155524242052, 8982.92108950951, -6514.34718846287, -8990.5189596469, 1371.40836228429, -6603.63876620064, 10229.5197096599, -2565.23434782809, -3535.87082719114, -1570.35084192387, -25109.7617850559, -513.768217220499, 13201.8105027840, -6204.01819530173, 2416.06586808327, 9258.53303139269, 5385.19786254883, 15084.9704357028, 5346.21334070028, -3158.3455867502, -2319.17160872631, 801.327851693931, -14684.1478857320, -13423.1569922 [...]
+406.571903663431, 19093.7568791548, -7035.48692804426, -10781.5371509859, -5555.30899381602, -7616.91165124705, 8798.04582204345, -2573.75361312595, -873.240664757365, -2208.90835222434, 19968.3422815859, -6149.26156813368, 5014.00227297375, -11182.9317573897, -10781.8252715476, -16959.1647714326, 5424.52954508911, -8942.04653851303, -9160.68906937134, 5119.02502237328, 15569.0712191793, 3675.05069207501, 4623.59337756742, -8954.52493956247, -5823.93513894125, 6237.77958384312, 4388.9397 [...]
+-2394.79394175385, 819.975706554202, 20124.2321883503, 3990.86417027511, -2418.71079063594, 11811.8981982344, 1216.87207930618, -1473.69885994489, 4193.31368025336, 7304.31033973997, 7227.00071179687, -16801.3521456665, 193.349993939630, -10969.5404872544, 9120.85633251697, 9992.80140545028, 18525.8647994225, -4039.51379745665, -13160.2606939433, 11788.6216185055, -2198.83750524271, -21769.6495412947, -5981.43047140935, -26681.9067371798, -7471.16683443045, 1740.92805218092, 6175.9626718 [...]
+11708.8360839172, 9709.2533009676, -1801.75231701773, 9093.92097835778, -7190.45371204097, -2757.71692380086, 9267.59802612983, -831.827804216206, 5861.12835744316, 20766.8245034893, 7540.0378350793, 7799.80498994746, 5169.99272245715, 20209.6594077634, -4857.32571576564, -574.085745541486, -4278.10562194904, -4708.23050885724, -2504.34162335967, 10702.8085399601, -16603.3459385011, -13945.7121311251, -550.148098965711, 935.723025724014, -8667.43999827833, 3586.59373766096, 4196.84932702 [...]
+-4279.46600516462, -602.663459010106, 7202.7673757418, 8555.45938189315, -3465.45855276561, 5169.02986554152, -16827.4389706929, 5345.06632787453, -18440.7104509880, -12209.3911262183, -7549.58575147216, 18713.4086936302, -4846.35657911185, -11723.9335109971, -2187.38338155447, -8322.75474089198, -20320.7553082921, -11815.2533451063, -17875.7096478003, -26822.4606594384, 8647.53264539631, 6775.18156513813, 1613.96612053482, -5875.92656286452, 3904.27941522442, 376.90850068704, 20129.9634 [...]
+-9696.26629047598, -5894.07368999885, -1899.87558661610, 4075.11283296801, -5272.61943311691, 7051.94784471348, 555.779050229382, -3423.57778579729, -19484.8734187441, -24212.8504538368, 13197.5513886019, -4620.56032025125, -3126.05949400224, 18128.0288199060, -180.231399147233, -5736.40647533782, 16150.9238991453, -8328.14495803282, -530.81800886962, -25204.5078711306, 13384.6092309015, -8776.95801713356, 14229.2770818716, -7594.52243590997, 1838.8704821848, -10644.7044608361, 2233.8098 [...]
+-6872.14204965609, -7347.62635003652, -1480.0210680063, 10176.9042170251, 600.103803890243, 7894.35326804362, 12092.4945643390, -5755.39776366975, 1758.53090691877, -2585.8981294421, -9662.93480379086, 16637.3427416717, -7464.32522211439, 503.605101015193, -12064.1021344088, 6852.45890606063, -2378.06712499088, -3726.16946049523, -16764.5862116559, -1179.09443895467, -4964.81220352226, 9758.73256034087, 5481.53370176937, 9254.94365041357, 128.244277991844, 656.781761610392, -1323.9906146 [...]
+6685.95272883518, 4999.28286661461, -8731.27755435808, -15384.3802498243, 12881.7808019154, 6029.97870046708, 16382.8251990947, -10095.3300830210, 3181.34425307871, -5426.13395380237, -6089.65629424529, 2254.48313304264, -9420.824794865, -476.913878624517, 16646.5451675076, -11873.3203798679, -6961.52220025849, -135.584525389085, 26983.5263905190, -9558.44025327997, 337.894800784682, -9179.25575034376, -7803.06730843517, 20977.4961445277, -860.784911954086, -12401.2888899178, 9816.527663 [...]
+3572.63328597748, 3496.77763857694, -16339.2603994493, 886.745073628164, 8189.62770384874, 4661.66972581589, 692.151642399519, 5916.05282343414, -3671.34753864319, 1346.87197573153, 13729.8776592517, 1228.86583799564, -1702.98397175462, 19005.1222303937, 5498.1339306449, -7345.59138965192, 13582.8933918345, -10037.3882289721, 5600.60699084464, -918.08047570835, -20190.4455290687, 10502.6836011158, 17444.2000453218, -12815.7263859366, 7655.01842488696, -3700.01889157278, 766.165735954096, [...]
+16493.7476970454, 5333.72788013011, 1838.10534813561, -2404.91008527734, -13671.1936917327, -253.681529349175, 861.367526420835, 8333.7674711995, -3503.01803772458, 11873.6939752434, 5577.41799994468, -14702.8346696228, -8763.537751286, 4472.43787642846, 7058.64217610009, 17202.0459679331, 13741.6005086304, -1.12256526359043, 4120.55885257197, -12860.8069127976, -6542.2038957095, -14964.2289314254, 14639.400370702, 5758.06936483081, 9796.93046308962, -2516.56291867720, -14019.9199791410, [...]
+-14131.8357750872, 572.039778723729, 4354.88435307976, -4820.54601880874, -9639.78351169206, -3411.79994478274, 2024.98047332425, 23801.3920374158, -2290.97030627362, -6614.60265119748, -10791.7300621943, 3759.23501016609, 21797.4789441521, -1922.98014427026, -10884.0466262609, 5641.08152789934, 4925.21055629333, 9532.70620075132, -15824.1748629054, 7265.54048850292, 12786.981759491, 729.188397320544, 4077.06802984984, -521.064647268785, 5168.79144509418, -4011.00933911921, 4118.52420348 [...]
+5038.25566164094, 2186.49110539487, 8022.60213631518, -11113.7823490918, -576.094486574439, 5126.88994281545, -4010.85890770493, -1236.83791493479, -15595.9759375133, 7268.20522390372, 4448.69534635084, -5261.74217781047, 9547.45626553224, -11001.8698175876, 6006.67900075948, 3978.90074736923, 3227.26638840862, 14195.3014505390, -4703.30265947976, 2622.90854754535, -2791.62755685396, 2958.75014854238, 22287.6739154426, -90.9796442443557, -7260.32463538727, -2418.34689481213, 8494.8913629 [...]
+-17810.9996372239, 3878.01197785692, -3966.84162267161, -8169.09120725056, -6905.94719407713, -17182.3027673452, -4059.01842446685, -5317.50886330925, 11074.6736784480, 8393.88119211331, -2763.45995141387, -2439.39559366002, 5384.05507926525, 11397.7320180638, 8614.34603915517, -5555.09642550459, -9121.17302122606, 6003.92352362748, 9534.45942539063, 12008.5246904142, -8849.9069898818, 4554.19299021827, 7556.91368658131, 16834.0580150597, -1114.04682327589, 10470.3523077119, 1994.8361997 [...]
+-7198.69246256503, -11194.6200540472, -14800.0510663712, 7223.05029149914, 3922.68549650169, 10399.3414220841, 8161.12657372447, -5026.54126433161, 529.334066082062, 3669.24750325536, -3095.61464172136, -8656.23287408416, 8434.71292587245, -3477.56318131188, 7064.38255398065, -20995.4806875324, -8308.6089300557, -29903.2524015299, -5889.3019114346, -18561.9752685333, 6289.60726823614, 19151.2879868189, -11374.4850343335, -15291.6330372854, 14844.5586099304, -6857.81941779312, -9857.16380 [...]
+-6022.0645841396, -9714.2202509204, 14258.9410408158, 6094.36964804411, 11532.9568563476, -4022.08913739195, -12328.5621807176, 11609.6218662355, -10743.0681930266, -13086.7571463503, -2151.92012916932, 3365.12346250994, -18260.2960767721, -9280.79261509504, -715.319603866242, -4541.20836080587, -6259.05272535096, 7293.92728289747, -16536.32358926, 11312.0216799126, -3294.48903447055, 7192.9527087548, 2050.35553827583, 4928.9145880618, 1100.48776474982, 5223.41602306218, 22727.8610620643 [...]
+-3285.74705989555, 4181.07364004654, 4726.00747644935, 23249.3427719498, 7974.52638085266, -20448.0129056506, 14220.3785072606, -9448.97937416142, -1477.23681142792, 7577.64490034304, 8146.0855076864, -5714.6487464792, -7448.52575419804, -1078.44034382684, -9606.85849987452, 6466.00268530874, 9454.56274913535, 2161.86517614433, 8743.73874835368, 1387.69071331194, -9390.77154485624, 7338.23925754119, 2903.60532945768, -1449.29151359101, -5638.28351919697, 21217.3912006943, 5935.4500752607 [...]
+13606.3263169538, -9387.54979557024, -14413.1922675599, -8834.2810076747, -7689.8836170846, 2097.47466861196, 6822.09213957446, -1936.17633288421, -13572.6131177729, -6594.04351620592, 753.153702481576, -3966.22449268440, 650.362313716385, 6976.65495683728, 2869.15808544526, 6956.03342825923, -5451.23041804164, 7020.61186804061, 5145.81489521122, 13959.5561530886, -18644.5419121744, 2122.01711469261, 6453.15423636416, 7358.38879350876, -4345.28401267167, -4680.84557282939, 13761.73931089 [...]
+16034.1947347045, 5753.48377495264, -5174.71584296421, -22148.6546591604, -3168.48380680874, -2076.5408948834, 1029.22850675697, 1761.83606440449, -4028.61992874428, 1444.96535080196, 2381.75661453062, -2571.29573817737, 1364.92786858492, 1780.09977552944, -11843.8674348238, 11107.9618765213, 9631.17021865405, -26711.3418411468, -24015.5462491186, -7111.4943883676, -14155.4648073824, -6580.92190052075, -3051.09192276248, -2509.92297646890, 6242.20937597649, 9771.25737612309, -17038.64082 [...]
+12261.6247983113, -20113.3552761759, -6303.6076140178, -10051.3586443491, -3861.59130025505, 9596.5966327739, -18144.5642154635, -9471.22186410175, 1628.62600712937, -11167.5124199461, 9835.02230327199, 1749.79680366542, -9112.9193914639, 5870.74291528516, -63.025325895931, -7339.21591063953, -4730.07721183579, 941.40978183108, -4805.64831418116, -9606.88116583711, 7753.59965172741, -27065.9779210514, -11185.0052169763, -13807.2501090319, 11381.5539502529, 11813.5524428925, 5594.20018799 [...]
+
+double y7[100] = {
+-7243675.80018765, -39764508.6976817, -12716411.6496654, -145467932.560514, -33853734.6146579, 98604256.9530346, 3974431.08782626, -41188221.6190945, 58560576.6014985, -3181763.34685733, 5909573.1233727, 23159398.5205479, 28233949.8727208, 47407008.0412599, 46966110.1285307, 87872090.306284, 127686262.122376, -20130229.3356024, -61128187.7204486, -35020979.4007107, -29590436.5624832, -25421945.6291611, -6930984.27853126, -29105432.5183949, 99748350.8576323, 77412499.5519389, 1139378.7296 [...]
+
+double lars7[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -155.20599027823536000, -255.59168394952900000, -27 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 74.22990653961450400, 75.57941282905220200, 161.33518711906197000, 183.99486351774809000, 184.72134341931394000, 201.01139719796657000, 226.86953273768509000, 313.50727124421917000, 391.09749043389974000, 562.72857997857136000, 585.58252989071116000, 666.47220935111409000, 680.43671172469033000, 788.06883244238657000, 849. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 64.56896099881299700, 229.86671804670144000, 252.37033624108966000, 324.92941218118267000, 343.01452382181310000, 458.65484939580989000, 535.817805032123370 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.11278450534091130, 50.14763813423794400, 61.47583854016671300, 61.84177251572788900, 69.67205014627933200, 80.28714649169222600, 106.58458525598631000, 139.71930873968634000, 252.91773011111968000, 270.14712378730235000, 330.24798190970625000, 342.96092812865652000, 412.52808919395500000, 459.6836939 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 59.86273404709392300, 69.95635321172453300, 133.53139622283098000, 171.75136490812832000, 178 [...]
+-110.37402894151982000, -503.08405718637817000, -754.72024472320788000, -761.69128275469495000, -793.98201277538544000, -852.38124111718071000, -1038.38929405719090000, -1051.58627335954590000, -1125.35964170069970000, -1126.71249754877390000, -1208.98125978481990000, -1229.91009759450870000, -1230.59178808550360000, -1245.36758429642600000, -1263.35243491980050000, -1314.18255814216260000, -1353.66867246097740000, -1408.57432606912950000, -1414.74307224662270000, -1439.28423193874710000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -5.31826645649457670, -29.54255669151544300, -70.10270204068186200, -223.67459866871314000, -229.84495581473089000, -273.90866081503810000, -274.78144386788887000, -334.54961071855081000, -349.46416435140458000, -349.87040955141589000, -357.59555986439779000, -374.12730802695751000, -420.87745702885371000, -453.34231739498870000, -493.23463713414327000, -497.11352710384631000, -511.34958396555970000, -507.73346291303704000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -0.36878594924343655, -8.15756097853141780, -17.93630556797272400, -65.05790550869073700, -123.18626646833573000, -289.49578770978803000, -312.72035054002657000, -396.12798904500875000, -415.06416466675529000, -521.01801145462230000, -581.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -25.21668267220763200, -72.48025057022812200, -230.61614037342594000, -239.84257601122093000, -285.68386230355924000, -286.41197063789610000, -312.52973863878816000, -320.76238530646566000, -320.99653332629413000, -327.75277272616023000, -344.71489157413299000, -397.92405063427645000, -443.37383230813265000, -549.61168004483773000, -567.91381953477207000, -634.77250572955711000, -647.23620590753478000, -7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.96567051736606000, 82.31638090360972600, 121.35382258929921000, 127.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 202.60440143102207000, 213.59472733021710000, 264.01728732892610000, 265.24013508491441000, 348.59909302243841000, 372.71425550745420000, 373.48341732179102000, 390.60533382999125000, 409.44094389009655000, 475.10157492364721000, 523.32474787114734000, 628.36326426272103000, 644.38222174963676000, 710.60277801933239000, 721.62251481669432000, 818.16084510210635000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -16.87960877267513000, -104.83548358986783000, -106.18278207631035000, -194.05874501442136000, -215.92231609874506000, -216.69665928912229000, -229.68367013137413000, -254.40731862875597000, -347.16595614980025000, -422.17864360325137000, -601.18440564357320000, -628.13374070130521000, -720.39472002101434000, -740.18537977255778000, -849.12235 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -127.04671986169807000, -157.98562908513858000, -159.00796811704311000, -178.39018914008895000, -203.84515204534904000, -311.92323388155006000, -392.26919294446793000, -563.43377901016231000, -586.78539090551305000, -670.43895834235843000, -687.28585232304022000, -802.4777748794912 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -54.58471021199384400, -243.72809152956444000, -256.47221552327210000, -321.16419529310559000, -322.00109249984314000, -389.19496592066656000, -406.57611536150250000, -407.11012826557743000, -416.46731103608346000, -430.61272004129273000, -483.54882157629572000, -520.97209928556322000, -576.39941787365842000, -585.62283914999853000, -618.47686141114536000, -623.80622913052991000, -678 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -21.29699416410341700, -21.99437284025071900, -38.50003116955418400, -66.03427905953326200, -145.56579000474730000, -212.06360625662816000, -344.23820846609340000, -366.55543171673327000, -443.18190748024227000, -459.16396146033316000, -531.24961353425192000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 76.17379702963829400, 138.55145113557174000, 312.57737604472686000, 341.59887245576550000, 434.16662990946651000, 453.04802368171079000, 606.19781775557726000, 699.5310978132863 [...]
+0.00000000000000000, -430.37719939162645000, -664.40496585642097000, -671.19039534346302000, -700.42412038231782000, -749.95043934286628000, -903.06457652389076000, -911.27073177867521000, -951.16464414212601000, -951.87771453748462000, -996.85271541261682000, -1005.98050311161490000, -1006.29784742169200000, -1012.20545484188090000, -1015.49420188711550000, -1034.61628606277260000, -1059.77252622515930000, -1136.67602420059460000, -1149.46681910414420000, -1191.82287569154210000, -1200. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 45.44092395105262500, 54.78034 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.89790376438789600, 33.48697282417360600, 89.27973667784408500, 136.90124186417884000, 334.38937009227612000, 364.97411043994589000, 466.21925384924003000, 487.06954635112641000, 602.01998785066917000, 665.87448762801 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 5.9806907 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 32.35818087016024700, 132.99253146208645000, 224.09989197552977000, 456.76566430317865000, 492.34147122331535000, 622.12319715494743000, 649.89106831458378000, 831.06257669581998000, 943.85246597019 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -240.75693880506370000, -246.81900739866703000, -275.37226735035125000, -334.16102287827363000, -531.86860285090938000, -543.14768602452432000, -601.21312182928398000, -602.28139288423654000, -671.69877155175425000, -687.47603065792578000, -687.97173928428526000, -696.06412230502303000, -708.11985348022893000, -742.48328330794811000, -771.39622236440948000, -805.14394801596541000, -807.90739664498824000, -817.47879515922068000, -821.4811417034184 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 23.26442256867926500, 98.90184260242992300, 114.41965343474348000, 207.89884259958751000, 263.81797185593638000, 2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 254.75982445621437000, 294.55410998403232000, 420.61227477700578000, 447.66606475477897000, 616.78258092132955000, 720.9481915972051000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq7[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1046.54205607183190000, -1109.65187579353730000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1180.28562501718240000, 1177.57123053427130000, 1256.50367763733220000, 1293.80250298354170000, 1260.54457323776570000, 1356.62985770436030000, 1480.12397177264300000, 1470.87423411609350000, 1506.14073743140940000, 1462.48489873139850000, 1361.82126909619910000, 1367.87675495826830000, 1256.89942002894490000, 1406.1918240 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 992.48467871787818000, 1096.42126695782300000, 1016.70999227117150000, 954.09825088759874000, 1089.57835813857950000, 1122.76834565608310000, 1192.303866779 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 909.80022772265454000, 676.36117391242885000, 616.29944372758348000, 603.74289137667540000, 625.15292846072498000, 594.76417037604040000, 457.88400002135126000, 615.89594604635636000, 846.34748209834765000, 855.34674467956961000, 851.39005297676260000, 867.75867686688264000, 812.04694501396773000, 860. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 578.94000142157734000, 486.62677114546489000, 498.63797889140415000, 496.91875274848786000, 4 [...]
+-2289.52950550001470000, -2209.05842329233880000, -2352.02881349227210000, -2248.17736254014060000, -2170.25246244364010000, -2082.37677198646950000, -1960.94800855510020000, -2175.12426344257210000, -2224.61275582847880000, -2231.43952756023240000, -2259.61787173076480000, -2254.94609888885680000, -2240.08766564235070000, -2293.56442281138920000, -2135.01597170123660000, -1993.20657643220190000, -1921.12067325674120000, -1696.41092315797370000, -1624.26570503896850000, -1652.08370249362 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1139.37161983961570000, -1062.01146629139730000, -924.37422115900790000, -985.35716722855773000, -755.16446318820829000, -930.47573956905467000, -987.48637188571786000, -1097.83597379799880000, -1079.93733041670430000, -951.46726341118438000, -905.61869307022732000, -1175.36399185174560000, -1045.39835169707700000, -919.89240185190272000, -702.36555187829447000, -628.86075990930522000, -634.79221670853769000, -358.4579012261 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -546.49331075933355000, -560.69423954810304000, -491.87825107607506000, -694.54089928442534000, -958.54460188732196000, -1161.35439446184090000, -1101.54702773366330000, -1119.36607301332040000, -1196.76041074942530000, -1129.50280500088230 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1099.98257301235960000, -1067.93822044715080000, -1014.93510348774080000, -1025.34437264346660000, -968.73762337692540000, -880.97713355869689000, -646.07411852523342000, -723.97441729033324000, -667.73961376735804000, -807.04124409495444000, -1166.81015474606810000, -1108.72887864534320000, -1096.52925140875000000, -1106.55142240382180000, -1189.54945525842530000, -1214.51255072875280000, -1161.74493438 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 632.75717695546064000, 469.10633093362918000, 453.47609734639730000, 415 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1207.47732591727780000, 1149.26707993709310000, 1015.33388500088100000, 1263.80400392008640000, 1413.15835904785560000, 1553.80753689170480000, 1512.51306641360320000, 1605.23624082273360000, 1322.33784952737910000, 1352.24179614283250000, 1216.33636590063360000, 1179.01564948307010000, 1188.46914811612830000, 1284.80951848411200000, 1176.52360252229710000, 1372.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1453.94193033398760000, -1415.41369728242010000, -1206.37173242562970000, -1316.30370729892590000, -1286.73894156444480000, -1363.39925940780060000, -1150.98384998530650000, -1452.67709259951740000, -1586.30013068469480000, -1500.18037446097170000, -1539.60159984907750000, -1543.47301238353410000, -1520.40123146589600000, -1557.15522333033190 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1749.53296720985400000, -1673.28696034792370000, -1672.96049027536630000, -1553.36738222947320000, -1437.55920724032280000, -1755.70516406602840000, -1546.91497191347870000, -1460.74450673374460000, -1379.92731366935000000, -1395.80952289232250000, -1382.73534782349040000, -1464.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1204.23944916849310000, -1181.83733984475950000, -1341.45591741509750000, -1285.10093588260840000, -1005.40203794437970000, -1247.31342541350730000, -1257.85625249774130000, -1197.91450700791510000, -1080.26703170364500000, -1116.19179439154690000, -1190.70595790001200000, -1058.77922917934050000, -866.97078383928920000, -898.89809048430607000, -903.35820485530462000, -843.8056008860 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1064.36426507847750000, -1054.72243339938860000, -1209.41350557134770000, -1400.52408945600430000, -1208.00283951673990000, -1167.69875880692140000, -1037.14841390794780000, -1124.56414816368920000, -1107.61967967702090000, -1118.91236316930330000, -945.231969 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1093.75617669854140000, 1034.97606110262540000, 1224.88834475801990000, 1327.31949714282700000, 1236.83325299170610000, 1232.48284343602470000, 1485.72530688266510000, 1493.5908 [...]
+0.00000000000000000, -2299.98178575782960000, -2149.94073224689690000, -2118.09779023858980000, -1946.40127478306610000, -1793.06612274452960000, -1662.47675968748510000, -1609.90994080012090000, -1545.60012114881670000, -1534.16306384131100000, -1571.21874763926230000, -1453.03404180898660000, -1476.24392562130990000, -1431.29186701451160000, -1174.88840209821460000, -1290.06234072279020000, -1421.29097540422230000, -1539.83379952651400000, -1583.90859164400380000, -1559.097549328216700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 432.04266776410492000, 461.408 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1071.75706745453610000, 934.43488845867546000, 834.59814831528956000, 821.26633741918317000, 1369.69825103747420000, 1403.79061164315450000, 1344.12857777837870000, 1347.78164070520640000, 1262.17153292803300000, 1209.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 266.37371 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1600.64734666613500000, 1477.33594015317340000, 1533.39696773110110000, 1676.48931323347210000, 1700.68049428365020000, 1747.47680360296450000, 1796.16479753937370000, 1871.51661603367940000, 1903.4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -1769.00740670587970000, -1539.47880044439990000, -1492.34716658673390000, -1572.36071520127710000, -1512.45437826823900000, -1503.40367707551790000, -1466.41166931057660000, -1474.61964789129230000, -1558.21313679954100000, -1460.20210042985420000, -1422.05241282997210000, -1270.13878991035990000, -1292.41946734571070000, -1201.53379754278970000, -1186.90191087064200000, -982.06253239995033000, -901.76845295684780000, -900.47359091665101000, -98 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 813.44494333120565000, 754.76338864354807000, 755.00383037435688000, 744.74263680107765000, 739.56606417682633000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1590.30900978710820000, 1646.17455828510380000, 1513.67841605117770000, 1564.46211113532650000, 1588.00572707943710000, 1607.1671156671 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso7[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -155.20599027823536000, -255.59168394952900000, -27 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 74.22990653961450400, 75.57941282905220200, 161.33518711906197000, 183.99486351774809000, 184.72134341931394000, 201.01139719796657000, 226.86953273768509000, 313.50727124421917000, 391.09749043389974000, 562.72857997857136000, 585.58252989071116000, 666.47220935111409000, 680.43671172469033000, 788.06883244238657000, 849. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 64.56896099881299700, 229.86671804670144000, 252.37033624108966000, 324.92941218118267000, 343.01452382181310000, 458.65484939580989000, 535.817805032123370 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.11278450534091130, 50.14763813423794400, 61.47583854016671300, 61.84177251572788900, 69.67205014627933200, 80.28714649169222600, 106.58458525598631000, 139.71930873968634000, 252.91773011111968000, 270.14712378730235000, 330.24798190970625000, 342.96092812865652000, 412.52808919395500000, 459.6836939 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 59.86273404709392300, 69.95635321172453300, 133.53139622283098000, 171.75136490812832000, 178 [...]
+-110.37402894151982000, -503.08405718637817000, -754.72024472320788000, -761.69128275469495000, -793.98201277538544000, -852.38124111718071000, -1038.38929405719090000, -1051.58627335954590000, -1125.35964170069970000, -1126.71249754877390000, -1208.98125978481990000, -1229.91009759450870000, -1230.59178808550360000, -1245.36758429642600000, -1263.35243491980050000, -1314.18255814216260000, -1353.66867246097740000, -1408.57432606912950000, -1414.74307224662270000, -1439.28423193874710000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -5.31826645649457670, -29.54255669151544300, -70.10270204068186200, -223.67459866871314000, -229.84495581473089000, -273.90866081503810000, -274.78144386788887000, -334.54961071855081000, -349.46416435140458000, -349.87040955141589000, -357.59555986439779000, -374.12730802695751000, -420.87745702885371000, -453.34231739498870000, -493.23463713414327000, -497.11352710384631000, -511.34958396555970000, -507.73346291303704000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -0.36878594924343655, -8.15756097853141780, -17.93630556797272400, -65.05790550869073700, -123.18626646833573000, -289.49578770978803000, -312.72035054002657000, -396.12798904500875000, -415.06416466675529000, -521.01801145462230000, -581.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -25.21668267220763200, -72.48025057022812200, -230.61614037342594000, -239.84257601122093000, -285.68386230355924000, -286.41197063789610000, -312.52973863878816000, -320.76238530646566000, -320.99653332629413000, -327.75277272616023000, -344.71489157413299000, -397.92405063427645000, -443.37383230813265000, -549.61168004483773000, -567.91381953477207000, -634.77250572955711000, -647.23620590753478000, -7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.96567051736606000, 82.31638090360972600, 121.35382258929921000, 127.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 202.60440143102207000, 213.59472733021710000, 264.01728732892610000, 265.24013508491441000, 348.59909302243841000, 372.71425550745420000, 373.48341732179102000, 390.60533382999125000, 409.44094389009655000, 475.10157492364721000, 523.32474787114734000, 628.36326426272103000, 644.38222174963676000, 710.60277801933239000, 721.62251481669432000, 818.16084510210635000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -16.87960877267513000, -104.83548358986783000, -106.18278207631035000, -194.05874501442136000, -215.92231609874506000, -216.69665928912229000, -229.68367013137413000, -254.40731862875597000, -347.16595614980025000, -422.17864360325137000, -601.18440564357320000, -628.13374070130521000, -720.39472002101434000, -740.18537977255778000, -849.12235 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -127.04671986169807000, -157.98562908513858000, -159.00796811704311000, -178.39018914008895000, -203.84515204534904000, -311.92323388155006000, -392.26919294446793000, -563.43377901016231000, -586.78539090551305000, -670.43895834235843000, -687.28585232304022000, -802.4777748794912 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -54.58471021199384400, -243.72809152956444000, -256.47221552327210000, -321.16419529310559000, -322.00109249984314000, -389.19496592066656000, -406.57611536150250000, -407.11012826557743000, -416.46731103608346000, -430.61272004129273000, -483.54882157629572000, -520.97209928556322000, -576.39941787365842000, -585.62283914999853000, -618.47686141114536000, -623.80622913052991000, -678 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -21.29699416410341700, -21.99437284025071900, -38.50003116955418400, -66.03427905953326200, -145.56579000474730000, -212.06360625662816000, -344.23820846609340000, -366.55543171673327000, -443.18190748024227000, -459.16396146033316000, -531.24961353425192000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 76.17379702963829400, 138.55145113557174000, 312.57737604472686000, 341.59887245576550000, 434.16662990946651000, 453.04802368171079000, 606.19781775557726000, 699.5310978132863 [...]
+0.00000000000000000, -430.37719939162645000, -664.40496585642097000, -671.19039534346302000, -700.42412038231782000, -749.95043934286628000, -903.06457652389076000, -911.27073177867521000, -951.16464414212601000, -951.87771453748462000, -996.85271541261682000, -1005.98050311161490000, -1006.29784742169200000, -1012.20545484188090000, -1015.49420188711550000, -1034.61628606277260000, -1059.77252622515930000, -1136.67602420059460000, -1149.46681910414420000, -1191.82287569154210000, -1200. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 45.44092395105262500, 54.78034 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.89790376438789600, 33.48697282417360600, 89.27973667784408500, 136.90124186417884000, 334.38937009227612000, 364.97411043994589000, 466.21925384924003000, 487.06954635112641000, 602.01998785066917000, 665.87448762801 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 5.9806907 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 32.35818087016024700, 132.99253146208645000, 224.09989197552977000, 456.76566430317865000, 492.34147122331535000, 622.12319715494743000, 649.89106831458378000, 831.06257669581998000, 943.85246597019 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -240.75693880506370000, -246.81900739866703000, -275.37226735035125000, -334.16102287827363000, -531.86860285090938000, -543.14768602452432000, -601.21312182928398000, -602.28139288423654000, -671.69877155175425000, -687.47603065792578000, -687.97173928428526000, -696.06412230502303000, -708.11985348022893000, -742.48328330794811000, -771.39622236440948000, -805.14394801596541000, -807.90739664498824000, -817.47879515922068000, -821.4811417034184 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 23.26442256867926500, 98.90184260242992300, 114.41965343474348000, 207.89884259958751000, 263.81797185593638000, 2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 254.75982445621437000, 294.55410998403232000, 420.61227477700578000, 447.66606475477897000, 616.78258092132955000, 720.9481915972051000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq7[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1046.54205607183190000, -1109.65187579353730000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1180.28562501718240000, 1177.57123053427130000, 1256.50367763733220000, 1293.80250298354170000, 1260.54457323776570000, 1356.62985770436030000, 1480.12397177264300000, 1470.87423411609350000, 1506.14073743140940000, 1462.48489873139850000, 1361.82126909619910000, 1367.87675495826830000, 1256.89942002894490000, 1406.1918240 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 992.48467871787818000, 1096.42126695782300000, 1016.70999227117150000, 954.09825088759874000, 1089.57835813857950000, 1122.76834565608310000, 1192.303866779 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 909.80022772265454000, 676.36117391242885000, 616.29944372758348000, 603.74289137667540000, 625.15292846072498000, 594.76417037604040000, 457.88400002135126000, 615.89594604635636000, 846.34748209834765000, 855.34674467956961000, 851.39005297676260000, 867.75867686688264000, 812.04694501396773000, 860. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 578.94000142157734000, 486.62677114546489000, 498.63797889140415000, 496.91875274848786000, 4 [...]
+-2289.52950550001470000, -2209.05842329233880000, -2352.02881349227210000, -2248.17736254014060000, -2170.25246244364010000, -2082.37677198646950000, -1960.94800855510020000, -2175.12426344257210000, -2224.61275582847880000, -2231.43952756023240000, -2259.61787173076480000, -2254.94609888885680000, -2240.08766564235070000, -2293.56442281138920000, -2135.01597170123660000, -1993.20657643220190000, -1921.12067325674120000, -1696.41092315797370000, -1624.26570503896850000, -1652.08370249362 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1139.37161983961570000, -1062.01146629139730000, -924.37422115900790000, -985.35716722855773000, -755.16446318820829000, -930.47573956905467000, -987.48637188571786000, -1097.83597379799880000, -1079.93733041670430000, -951.46726341118438000, -905.61869307022732000, -1175.36399185174560000, -1045.39835169707700000, -919.89240185190272000, -702.36555187829447000, -628.86075990930522000, -634.79221670853769000, -358.4579012261 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -546.49331075933355000, -560.69423954810304000, -491.87825107607506000, -694.54089928442534000, -958.54460188732196000, -1161.35439446184090000, -1101.54702773366330000, -1119.36607301332040000, -1196.76041074942530000, -1129.50280500088230 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1099.98257301235960000, -1067.93822044715080000, -1014.93510348774080000, -1025.34437264346660000, -968.73762337692540000, -880.97713355869689000, -646.07411852523342000, -723.97441729033324000, -667.73961376735804000, -807.04124409495444000, -1166.81015474606810000, -1108.72887864534320000, -1096.52925140875000000, -1106.55142240382180000, -1189.54945525842530000, -1214.51255072875280000, -1161.74493438 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 632.75717695546064000, 469.10633093362918000, 453.47609734639730000, 415 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1207.47732591727780000, 1149.26707993709310000, 1015.33388500088100000, 1263.80400392008640000, 1413.15835904785560000, 1553.80753689170480000, 1512.51306641360320000, 1605.23624082273360000, 1322.33784952737910000, 1352.24179614283250000, 1216.33636590063360000, 1179.01564948307010000, 1188.46914811612830000, 1284.80951848411200000, 1176.52360252229710000, 1372.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1453.94193033398760000, -1415.41369728242010000, -1206.37173242562970000, -1316.30370729892590000, -1286.73894156444480000, -1363.39925940780060000, -1150.98384998530650000, -1452.67709259951740000, -1586.30013068469480000, -1500.18037446097170000, -1539.60159984907750000, -1543.47301238353410000, -1520.40123146589600000, -1557.15522333033190 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1749.53296720985400000, -1673.28696034792370000, -1672.96049027536630000, -1553.36738222947320000, -1437.55920724032280000, -1755.70516406602840000, -1546.91497191347870000, -1460.74450673374460000, -1379.92731366935000000, -1395.80952289232250000, -1382.73534782349040000, -1464.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1204.23944916849310000, -1181.83733984475950000, -1341.45591741509750000, -1285.10093588260840000, -1005.40203794437970000, -1247.31342541350730000, -1257.85625249774130000, -1197.91450700791510000, -1080.26703170364500000, -1116.19179439154690000, -1190.70595790001200000, -1058.77922917934050000, -866.97078383928920000, -898.89809048430607000, -903.35820485530462000, -843.8056008860 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1064.36426507847750000, -1054.72243339938860000, -1209.41350557134770000, -1400.52408945600430000, -1208.00283951673990000, -1167.69875880692140000, -1037.14841390794780000, -1124.56414816368920000, -1107.61967967702090000, -1118.91236316930330000, -945.231969 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1093.75617669854140000, 1034.97606110262540000, 1224.88834475801990000, 1327.31949714282700000, 1236.83325299170610000, 1232.48284343602470000, 1485.72530688266510000, 1493.5908 [...]
+0.00000000000000000, -2299.98178575782960000, -2149.94073224689690000, -2118.09779023858980000, -1946.40127478306610000, -1793.06612274452960000, -1662.47675968748510000, -1609.90994080012090000, -1545.60012114881670000, -1534.16306384131100000, -1571.21874763926230000, -1453.03404180898660000, -1476.24392562130990000, -1431.29186701451160000, -1174.88840209821460000, -1290.06234072279020000, -1421.29097540422230000, -1539.83379952651400000, -1583.90859164400380000, -1559.097549328216700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 432.04266776410492000, 461.408 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1071.75706745453610000, 934.43488845867546000, 834.59814831528956000, 821.26633741918317000, 1369.69825103747420000, 1403.79061164315450000, 1344.12857777837870000, 1347.78164070520640000, 1262.17153292803300000, 1209.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 266.37371 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1600.64734666613500000, 1477.33594015317340000, 1533.39696773110110000, 1676.48931323347210000, 1700.68049428365020000, 1747.47680360296450000, 1796.16479753937370000, 1871.51661603367940000, 1903.4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -1769.00740670587970000, -1539.47880044439990000, -1492.34716658673390000, -1572.36071520127710000, -1512.45437826823900000, -1503.40367707551790000, -1466.41166931057660000, -1474.61964789129230000, -1558.21313679954100000, -1460.20210042985420000, -1422.05241282997210000, -1270.13878991035990000, -1292.41946734571070000, -1201.53379754278970000, -1186.90191087064200000, -982.06253239995033000, -901.76845295684780000, -900.47359091665101000, -98 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 813.44494333120565000, 754.76338864354807000, 755.00383037435688000, 744.74263680107765000, 739.56606417682633000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1590.30900978710820000, 1646.17455828510380000, 1513.67841605117770000, 1564.46211113532650000, 1588.00572707943710000, 1607.1671156671 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso7[1350] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.36223641700389830, 50.05426217490528300, 71.27632995231705600, 99.34877983255361800, 170.25677958141702000, 200.47541177686344000, 316.14457862428407000, 320.40738398547722000, 343.25945196918741000, 365.24231525446839000, 555.99425790074633000, 654.69633182408359000, 666.60113464363644000, 719.40443674383312000, 965.87120614482706000, 1027.69611598409640000, 1028.39768345372020000, 1077.39059105489420000, 1116.610799021878 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 433.61367995587580000, 568.47169155086317000, 569.98966740860658000, 628.76588505343557000, 673.46147616647102000, 711.7163201442265300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 33.99955131357969400, 239.59252814313530000, 304.64942032470600000, 305.38689904745411000, 340.11917725520374000, 363.10674117968261000, 381.738162707061920 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 3.07444223995862490, 24.21257004814511800, 52.22734344692490500, 311.31645870124225000, 415.29743289009571000, 426.16265502319561000, 472.95937167196610000, 730.15199898268122000, 808.14599310141978000, 809.01526660919478000, 846.24630638912754000, 881.95972432075519000, 910.570627 [...]
+0.00000000000000000, 69.35213596624406300, 92.32563194065342300, 101.16907812151132000, 148.18190628685480000, 171.87872299519856000, 208.83451561219425000, 294.15548617919120000, 328.71116593753135000, 461.00490899072236000, 465.98356165766580000, 496.28348656977920000, 528.69104048910788000, 854.67309636807374000, 986.63088286650770000, 1001.64276793118440000, 1066.88144322757060000, 1426.49000633354190000, 1534.35900558256960000, 1535.57408236188010000, 1589.34831680520690000, 1635.07 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.05324911220201800, 40.71525 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 44.07198514774428600, 86.54679079467719300, 95.9915 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 26.64474428739727700, 65.33185956338779500, 127.90195251460457000, 158.81223729786629000, 265.18884998038243000, 268.31612247361164000, 283.89312980750481000, 294.77902690927016000, 342.20434382192940000, 342.26797453492026000, 342.61799288648780000, 348.27861708542355000, 259.04231467360148000, 205.73338401818339000, 205.09688879379226000, 182.66103282155333000, 149.35322557657273000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.19944406959600372, 8.71816214017516340, 15.52377025662324100, 20.90705101729477300, 20.6248 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 12.79430689081451800, 68.32825132855590800, 391.22186395146025000, 451.62192861716949000, 452.27460665486939000, 473.79513473046865000, 494.89638939674472000, 504.03260387780495 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 23.28027987703205800, 262.97963381142478000, 369.58488279034685000, 381.15273908290408000, 433.79097964640334000, 844.30759586298814000, 977.25177449679529000, 978.74681089175954000, 1042.36319198084240000, 1088.67412685176550000, 1131.0103 [...]
+484.85693925394628000, 568.03720419149420000, 594.98645301551414000, 604.59467618488964000, 659.63380144324833000, 680.27567236066704000, 707.85418405319558000, 781.57301974979089000, 811.52205336631789000, 905.66660574737341000, 908.79107001123032000, 926.83123208125483000, 944.09100734006108000, 1124.89373043481150000, 1217.60345159441230000, 1227.41385826880510000, 1273.40603091380880000, 1591.91709587651580000, 1718.23272161040150000, 1719.69815258419770000, 1799.22116295800130000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 23.92195424005154800, 90.01245089640197200, 92.19608492655893900, 105.82624380316265000, 124.54324313322172000, 297.52416231178307000, 362.83055430316853000, 372.05871589916387000, 411.87121562647138000, 696.20952228793567000, 769.05202465481261000, 769.87205274335952000, 805.45204094071778000, 825.67468581385276000, 844.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 42.27359758062647900, 62.81041394271404200, 94.11771873873816200, 162.82235930486240000, 193.32498985820965000, 298.86104846511694000, 302.33545079566920000, 321.59138422158543000, 340.92296533127245000, 558.25295875035636000, 613.08511802509361000, 622.10843081263329000, 659.52142420247958000, 832.33130908153498000, 883.27044563281152000, 883.80037960755533000, 911.51139434630250000, 925.9620284222421600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 21.64491765671680000, 46.59869377843379800, 301.70123382887789000, 428.58664198329137000, 440.74182393370040000, 495.13304745638351000, 789.56424855873433000, 874.76876495495731000, 875.74372037905391000, 922.02941776505861000, 948.49931341413253000, 975.710531 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 168.14139034303210000, 185.84029444259892000, 263.00843397802475000, 686.65567315055614000, 806.01852791813951000, 807.39702039881661000, 890.19615548217075000, 951.64802433797342000, 998.6720467580 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 94.00649861651565700, 133.08520296317576000, 276.22258551120740000, 281.26453053447750000, 308.76852235638518000, 340.12249498776453000, 679.89714816479443000, 763.01727991148289000, 772.61099084363650000, 819.12728838512862000, 1105.32396285280040000, 1199.44971311598760000, 1200.49305824176640000, 1251.34629944678890000, 1299.811936611758000 [...]
+0.00000000000000000, 0.00000000000000000, 17.70982918566868100, 24.81960357529282400, 60.30859791741085000, 75.24131540107525500, 91.28979751715481000, 137.47053154115167000, 155.04980170271187000, 217.40103996170367000, 218.99518361175319000, 230.29460119356170000, 241.38129700219145000, 394.95343827323654000, 460.75728798952434000, 467.94937322217720000, 497.64674246667141000, 627.38934677640816000, 660.98395470584182000, 661.36242892816347000, 683.72517880938653000, 706.53471666972359 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 91.48741834210018500, 95.11335980243367800, 117.85781948292046000, 146.76727727809850000, 445.89030961888352000, 520.80700438312090000, 529.44968500581979000, 571.66386826589758000, 812.46006608329651000, 882.99271522152742000, 883.80238073324074000, 911.10921574850954000, 935.81078258136006000, 949.46 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 104.52393094628943000, 105.68246533712295000, 166.52445155006299000, 221.42851521670264000, 277.00370466151435000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 10.946257 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 263.47680213372490000, 371.48011588004221000, 382.56051341876548000, 430.56792519109104000, 799.08819584728337000, 908.21104161149617000, 909.43704627122622000, 971.54749900544027000, 1016.35631133080890000, 1053.486879 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 33.14058123402490000, 143.10715078745764000, 188.16593035498789000, 367.24733692848770000, 373.65553728993729000, 411.01430942200022000, 452.19647895884418000, 877.97904719947576000, 1010.13702529595340000, 1025.89920178909440000, 1093.46690073582360000, 1519.57567485853110000, 1646.82174218313500000, 1648.21166034097700000, 1709.23080200954180000, 1760.4026839702 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 71.02503261012334700, 122.78624079342315000, 160.10589474703224000, 168. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlassolsq7[1350] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1118.54319818534960000, 1161.43211729077100000, 1334.46664380232640000, 1293.30258560338780000, 1363.47636875784250000, 1347.73778370500760000, 1404.84537466052510000, 1451.92128945925400000, 1354.61165469198890000, 1219.26692688553910000, 1098.31680349668550000, 1352.78766011214840000, 1401.90600433711570000, 1391.94452698938080000, 1307.04394495649940000, 1265.99771451413610000, 1268.25053164404110000, 1400.3818282343468000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1033.84537502899430000, 1088.27640814837200000, 1084.36331308709460000, 1016.25469074695970000, 1002.72814699749520000, 1012.7904499892 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 467.04181191602510000, 524.18553496452989000, 555.40856324249319000, 556.77867367780414000, 569.09561604311534000, 548.41027537301341000, 553.09035617612324 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 819.15067639280903000, 959.71180519328084000, 1140.58902142019250000, 1047.92687834701360000, 1150.72490166409120000, 1097.25741113691270000, 1068.99535401334790000, 1086.17205505362560000, 1108.77066886006470000, 1102.53990189685240000, 1091.69611104023470000, 1136.248470987070000 [...]
+0.00000000000000000, 1523.88933647446520000, 1466.28237311379170000, 1435.90875177509290000, 1372.04081674532590000, 1582.37225496475820000, 1780.60717630196750000, 1729.91243615179090000, 1640.63127094865600000, 1706.17946413047710000, 1787.51111120398560000, 1837.25165732988170000, 1787.71031794597820000, 1781.46532668734840000, 1919.93028370983640000, 1928.85780531138240000, 1897.80721540892930000, 1924.27978413268900000, 1950.13567262028730000, 1949.41718062739760000, 1943.8609873455 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 305.94055482380799000, 286.468 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 362.08780553714007000, 411.01314685817027000, 424.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1612.60626565595430000, 1710.73967808736960000, 1180.81362496914130000, 1332.33347439618140000, 1266.42631077978850000, 1098.41555523401300000, 973.27672039510844000, 717.69136202877314000, 477.03819262556215000, 342.71801623299234000, 364.23701525004992000, 420.37631852035236000, 135.51655998764264000, 0.25628062831090315, 0.00000000000000000, 34.75013648030753900, 0.0000000000000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 65.96226887135273400, 64.87876626674871300, 49.96887399662428900, 38.80095771752465300, 0.000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 803.03974847991719000, 775.64772792073529000, 838.18880570627505000, 684.43151942087388000, 675.32698070829599000, 615.67162927284176000, 664.75445119906112000, 597.345840410573 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 927.70895791722296000, 944.46346039796515000, 1123.57309098117370000, 1095.64597284409570000, 1104.22872976602710000, 1412.56707612762280000, 1489.67969984374800000, 1484.07016115994380000, 1461.76131793224140000, 1421.14580885957000000, 14 [...]
+1939.64473102894640000, 2312.59471513365590000, 2206.71773381664930000, 2054.76199729577500000, 2092.43685754481880000, 1908.93122450147480000, 1880.80022664178090000, 2022.09255430154640000, 1948.54900818097080000, 1791.77352527703810000, 1738.14508975948590000, 1725.22539316992610000, 1614.62571753457520000, 1638.92987433531450000, 1873.31259545485750000, 1833.35751904968220000, 1859.19477349216820000, 2032.81747623712680000, 2205.11115960510870000, 2215.82980725456350000, 2323.4855261 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 932.12844701220433000, 712.06911717387493000, 671.81726399365391000, 709.04916494716235000, 851.69047033067170000, 789.32231192435370000, 824.72384710649214000, 942.03977839177389000, 918.95128627615418000, 1089.80610761475960000, 1049.82048513591990000, 1050.04715760009890000, 1040.01710289306670000, 997.33580875652910000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1142.75874376726640000, 1285.21285738026150000, 1425.65365055480080000, 1318.96444878946680000, 1351.36947222741060000, 1292.18705009032460000, 1224.57660823148380000, 1173.79131202094960000, 1091.94642552216370000, 1176.13896101218460000, 1000.89718092799470000, 1179.43692537182210000, 1136.03969010595960000, 1071.54417279215640000, 1079.61327410546780000, 1065.83922983970300000, 1094.19936638557620000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 979.57289010449153000, 1016.04196804686310000, 1026.97751143247210000, 1326.01057238303930000, 1191.51145998902030000, 1187.89802467501110000, 1197.13196860405670000, 1203.18610534389700000, 1206.00678720348010000, 1227.17306802804480000, 1147.14740943296170000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1357.35699503172210000, 1279.02012865829560000, 1245.87627487093460000, 1273.09127755180910000, 1266.09779322030980000, 1274.87499746009920000, 1436.05873819853900000, 1419.03187139634770000, 1390.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1675.92103655849160000, 1616.72373268404700000, 1623.45959404042700000, 1619.59232668502000000, 1525.99852239772420000, 1558.21060080489930000, 1645.90280076064550000, 1350.90202105272330000, 1365.17035312538270000, 1411.59165523629280000, 1501.49300220944790000, 1562.25358632616260000, 1552.61516944861730000, 1586.60199451808330000, 1646.9104 [...]
+0.00000000000000000, 0.00000000000000000, 1076.86683436149310000, 1097.89651889575380000, 984.17392667526235000, 964.07384023641202000, 773.85032861024308000, 914.58674797852973000, 822.45377458525218000, 804.26307568426398000, 642.14274830582747000, 730.36710530972493000, 672.09457394717185000, 831.57092919532647000, 926.16895594081086000, 912.17137126605166000, 875.89337851697928000, 806.98613282789677000, 790.47300357605945000, 789.74495404916661000, 831.15411504785982000, 877.8107651 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 952.58487318701009000, 1057.57888078339240000, 1124.44765695397220000, 1269.88705224039810000, 1296.32025594056630000, 1050.67119953203700000, 1063.26828287779340000, 1109.33347395650500000, 1145.78329056691290000, 1154.85794045025590000, 1158.04805941795760000, 1091.13258763806700000, 1114.65387806069 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 507.40716836466657000, 497.79501917727515000, 567.63206817377693000, 626.63397519499392000, 716.51384051541515000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 428.81015 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1012.56175537903490000, 1135.35643332439640000, 1066.94566383731720000, 1042.02417435802910000, 1309.21404507620900000, 1328.82060900696210000, 1323.93833020430860000, 1381.01762341012180000, 1344.19728587671510000, 134 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1442.64788318412070000, 1993.59320892493930000, 1898.84039068419660000, 2052.79652177771500000, 2074.64049992794030000, 2064.38224591309380000, 2052.10573047009580000, 2088.51186314477950000, 1944.85232362791130000, 1999.45628694625880000, 1954.05676045878070000, 2109.41867013309820000, 2137.28652941771040000, 2120.43193779931110000, 2111.50633583978650000, 2150.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 539.26552448297241000, 531.51476786930766000, 495.68914304872095000, 533 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+
+
+// Data from file x47.txt and y47.txt
+double x8[5000] = {
+16720.9803824810, -12880.8191727079, 6060.9471711186, 13620.8953964914, -4012.06174663884, -5927.18069139129, 3035.89223592199, -4287.66919336782, -6501.03564167126, 3297.37051347604, 4775.45653804269, 7436.45026207525, 1898.35673487781, 1011.47865992537, 2984.67653323693, 7529.49576304357, 16155.5708255975, -15038.7773534218, 3592.91103463450, 7104.98867062374, -2474.73094869709, 3285.5635639294, 13475.8054750492, 13486.1027029426, -1063.85414812176, 22888.0880754895, 15295.5484814506,  [...]
+-3106.63199672244, -2034.30006128701, -6801.49097631723, -7527.5689309757, -2903.95153025983, -4198.06258466784, 5220.56796287836, -6677.40292520008, 244.153376690899, -12870.6743591219, 10225.8027277640, 8489.66731782378, 6181.09571985416, -4488.25934157845, 5671.59234498351, -6393.26016911087, 2850.74715065093, -8877.48029658272, -2554.19295360452, 2432.02092882776, -163.088993677252, 8324.25549720456, 17533.7719470102, 13358.9337640214, -7156.5828043742, -9313.88895148008, -7640.35577 [...]
+-2047.42264058667, -4049.20670827686, 2518.6308354864, -4020.12930628253, -6681.05108440104, -3124.23033440135, 3420.20706483366, -11643.7956240902, -719.87041042297, 20766.8475593889, -12617.2521040850, 10227.2588640637, -6526.36456131055, 6523.89684906788, 8111.47954151073, 13890.1764237405, -3607.8971130309, 1540.36474911170, -15605.1968890622, 937.501274737724, 7076.86420383703, -11961.1851762145, -2681.8204616571, -8214.25206341694, -2957.59599069537, 17153.1733079104, 13843.0603300 [...]
+4819.36729590938, -14020.9994779561, -297.586255117281, 13985.6458962009, 2003.22376019698, 14624.0277683722, 5967.2030138923, -1784.44669069161, -3850.23491572428, -7922.38278068549, 1255.52188272313, 9037.79700486267, -25922.3874629084, 7033.81643348762, -721.613372712841, -3455.81827360831, 4025.36847462676, -9580.85221199942, -452.881349837533, -12492.8559844170, 2307.35981938399, 7104.87540307074, 630.734679033919, 2977.89916248720, -11629.4783652929, 5030.11433731758, -567.30009217 [...]
+-7330.66808718614, 12462.4414231352, 12566.6459233130, -1974.48441263043, 7978.93025211751, 3334.56495449234, 1412.61721132678, 7186.5630982913, -9115.53350331045, 8519.24485470472, -1687.18174334751, -12128.3904144313, -5009.99704243756, 6033.51055611772, 4711.62137280923, 10313.6998733071, -6961.20654636296, 1716.06697166972, 11458.5023149305, 29123.1429144961, -24064.3028966303, 6450.51981998242, 22897.5946345287, -672.69908591403, -8817.7240189855, 13329.4195216264, -9397.56213167284 [...]
+-10176.4486699406, 10866.0500031711, 3221.69243037023, -12042.5793660958, -9849.72859216266, 3556.80050854463, -4424.28496168875, 3125.78426659284, 23376.4316808258, 11875.7348223664, 15688.0604539569, -1006.20162105932, -6038.82735491837, 6457.38289899167, -9445.85105864213, -3454.07365798157, 2360.94956682022, -256.924766855598, 8299.82400361025, 6163.56354417885, 4866.26490822566, 3807.22556584562, -18369.2061576993, -4050.31348284797, 10219.0606203904, -11138.7465325051, 2799.1269529 [...]
+15166.7403325267, -9724.17003000897, -12196.1412290049, 3640.02428922075, 3877.78363078419, 16413.3240629967, 6433.13401190972, 10451.7320021841, 11724.0510722226, 12946.7655320228, -9519.58742679408, -3282.60188065714, -1632.26433796507, 8392.41439476093, -14361.6353292196, 10915.2392048325, 7961.44417573107, -15176.8406827481, -5490.83644184926, -1211.01844755626, -2737.62799716044, 6173.16882592207, -16265.5667273565, 13116.9342480179, -4557.70428732934, -12837.7348041165, 17013.28302 [...]
+-7037.04278351242, -22686.2610254244, 2134.51746392862, -3795.90009772749, -1261.31484215785, -12779.9794540461, -9581.94793537338, 11091.7925462397, -6017.28141864435, -4983.96229225571, 19630.4998170424, 6431.77767388774, -1672.28571307470, 10738.7475504985, -4697.60674949509, -726.112038190834, -12132.9414139132, -2552.54109096795, 9067.37091867117, -4065.54954225966, 14939.6646845244, -9271.50092017896, -1713.20706603957, -9814.18869931148, 4638.60602710563, -7345.68328452276, 17730. [...]
+2264.51265197467, 8087.15002565016, -1290.35177221546, -3764.60374833291, -4821.54256962365, -966.14063559596, -13387.312721456, -5932.40462689226, -19640.0906041062, -8770.71926036259, -3361.01858827085, -28632.7500119271, 10337.6303548829, -8478.93454245202, 6854.7264731737, -1695.58963117809, -7695.36419556435, -2201.30556025548, -4947.52187618589, 3960.07220385296, -1505.68236103376, -1496.67654634180, -18040.0991200757, 20482.1236973586, 301.978138182150, -9874.04290422761, 2626.111 [...]
+-687.903460525501, 3509.36491906036, -2622.71908358275, -9538.18883623546, -61.3583346658657, -14975.7057520123, -15039.2419486385, 10156.4978659343, -16423.5407956431, 2864.52766062703, -12205.5957209966, 2032.85399765364, 7268.15273442995, 280.392774085638, -3580.06574861447, 9950.48180470364, 7387.34780945227, -7656.73566926238, 3685.81889169219, -1197.48916763738, 7719.6174360934, -12802.0078374072, 18063.9134138349, -9651.90522830903, -7544.58111982705, 2884.26814404029, 7441.607039 [...]
+-96.8433658899117, 5875.28587946631, -5243.19049270085, -11035.7919737506, -5894.3912812468, -12799.4444111414, -2521.47771333820, 4017.58938600744, -2106.63837142365, -21963.9719830155, 7251.38357966078, 18448.4483507424, 1992.27036193417, -14458.6349524338, -8020.9555315537, 12053.4009104372, 6025.2432940751, 5766.11656528528, -8433.90433833374, 7113.79218814432, 2862.63542752298, -4433.94276302909, -9934.06887106216, 15102.3215137910, 2281.64669749250, -1519.19195463605, -8194.9277626 [...]
+1809.13623954179, 6233.71668795256, -153.881606312614, -11245.6773576448, 14776.6715177220, -10132.9302217180, -7423.7953970858, 4530.53625850567, 8187.68275051076, 10596.2799335668, 8668.8798831257, -10253.8942569693, -10485.1484835713, 1008.70667814989, 3978.21033237902, 10274.7976732610, 9090.93372439628, -945.029208122023, 7409.21889519205, -16151.7188733631, 8856.75202487854, 10419.2349550098, -3847.28583932373, 4534.879492081, 4642.73537310715, 5129.77374276745, 4561.63503901815, 1 [...]
+8462.60568072013, 36203.5126587256, -392.38738641845, 3713.54879726171, -6138.84189240879, 5809.49336633491, -533.610665652453, 3687.18604678923, 2722.99930813768, 4172.73410848377, 9172.64535966084, 15662.4968882940, -8636.52010250155, 4379.73857941562, -6599.41733592084, -984.330248497481, 14686.6335028831, 4362.4369201412, 2442.43946335845, -9240.69454395706, -8193.77052696086, 1422.34166139148, 4261.7621479372, 10460.5013495225, 9220.55445772525, 23668.8111003715, 3593.38904061203, 3 [...]
+-5279.37223103403, 4227.92847271979, 1279.39256371488, 6135.84492444046, -754.162562753475, -513.326087241911, 9465.72112394024, -1877.33980563147, -10173.1328999005, 2813.43110578676, -6769.95940425657, 10537.6936906960, 15021.1623181492, 10485.6895621242, -7441.88950455069, -23.8610846936097, 20219.6197396893, 2104.94607842916, -13266.6401954878, -12105.8831768662, -4403.28651035919, 5973.62988763542, -3615.13546672204, 7133.09291766686, 1162.49741380196, 14649.4611430551, -2520.463063 [...]
+11459.5874793304, -4540.20965942333, -15051.5587061952, 3363.03008645255, 448.675315377231, 5547.78782566606, -6437.8108513615, 11210.4631516163, 9694.8035126748, 11196.0959458492, 12747.3392813944, -659.363968410978, 7663.98824126661, 4915.2752176956, 14385.150603008, -10647.0188426099, -23059.7975696387, 8434.87554963229, 10684.1927278660, 9428.95778223276, 4992.95570736263, 188.79865509164, 9446.04337365515, -18086.8928820826, -5369.78090585022, 7509.08328135462, 9260.79093273627, -14 [...]
+-13808.1006934115, -14281.7529704952, -1334.70944347228, -16529.7281882114, -2974.37763405937, 3764.04678678849, -19206.5394918702, 14323.1125701252, 12577.7665953817, 7818.87879435736, 660.72489685795, 858.821031107635, 5619.62113793677, -18569.9496742290, 9170.93138477158, -3251.30000039346, 1619.65015464629, 1553.59062784031, -9913.95913830272, -2080.99659267987, -4258.69180773496, -7437.97395866457, 5865.51592449554, -2116.60094053818, -21231.0634137738, 11801.938740574, 6492.1515332 [...]
+4049.20277332333, -3837.63362510883, 264.212494943, 13743.8545950728, -10595.3480990884, 5571.2380142638, -2165.99218709972, -113.991020406336, -1061.10893807408, -1316.23806870196, 7103.9261663028, -4135.40373594114, 9146.66782547905, 6512.96364782659, 9267.14108344634, -17865.6065839003, 1877.65973385933, -18326.8851766401, 7391.70692145389, 809.99278940053, -7230.96396779912, -7702.20238304003, 21989.0889095233, 11560.9388091953, -2970.21655208418, 1912.16763609810, -1548.72722665050, [...]
+11742.1400998757, -15569.9126352204, 19255.8356750579, 11363.4025310443, 6130.12182667062, 60.6044245053797, -1006.06711764261, 19028.2935456632, 13663.7632937819, -15401.4362087326, -17891.5527501197, -20795.7090318116, 4023.58956083888, 11602.5506875414, 1980.62504698583, -19095.7252328158, 11776.8014793802, -13573.9434341276, 11305.225907696, -506.81351203376, 1207.70814242443, -15391.9888047402, 5481.06824788237, -12745.3013603126, 6826.62483059861, -15231.2785941327, 12358.207587689 [...]
+-7080.32812190266, 28582.9493904032, -12108.2657481989, 2628.84027698083, 13994.4760654196, -9413.74422177613, 8047.30501127842, -13560.3781518073, -9598.92423391906, -9053.41962154461, 826.580839272855, -23381.8627060768, 10545.6102119417, 19120.9881250497, -4184.25366591656, -2454.96524313036, -18196.1103095551, -6709.58484829068, -9188.83839783832, 11784.9607141867, -6133.07204300718, -4070.02775180828, 21810.0246057034, 21314.6327204332, 3421.43512772355, 22105.3285455794, -9894.0421 [...]
+5582.90059606561, 16915.3903560423, 13124.2437737088, -9706.56749710696, 2527.1470533981, -781.452684974525, 4048.41602377226, -8071.3178166712, -3243.07016250556, -10033.9979265111, 1303.70572889896, 15654.0740650546, 5545.50859499015, -16778.0209556778, 9548.27697628563, -7504.99325948425, -7761.76316002488, -4707.86869960521, 13296.3235611102, -8919.98341047022, -3170.48695046736, -1461.65458406151, 3464.68175469821, 1005.49049157547, -6132.894690509, 23710.5753115790, 2746.0068432383 [...]
+12776.1588416966, -4926.31262092586, -2430.96129088978, -11456.6712641382, -2079.99716107772, -8470.06122121027, -10317.6131338616, 6297.93912039218, 6652.30757847105, 824.169167195597, -22.7451619969779, -8945.72979490834, 5586.55149420662, -4921.52987790182, 83.695771122003, 5624.8560475534, 1936.98418065174, -55.0554670327251, 15423.4483217875, 4855.14933855132, 160.296661416562, -26816.4914480709, -7953.12410057577, -12616.6174085695, -5621.42710916077, -7519.07407250541, -10442.2443 [...]
+21721.4745567401, 3281.32802118228, -283.600416732675, 15924.0050486528, 4618.14158256226, -6359.07923903981, -8946.884268445, 16556.7121125726, -6970.36875700392, 11661.8123645308, -13180.1029747166, -4808.39159148968, 3026.45727702917, 12116.2563658122, -11016.5318568246, -9635.50065453203, -15265.6351569947, -7689.16373029428, 15552.2337292274, -9414.08696662522, 17621.6468670625, 7742.03197158231, -24441.1314577748, -2847.03836366876, 1795.79606306137, -11554.1927911510, -14761.72842 [...]
+-8957.18568310646, 4240.5471256694, 25116.4734359846, 15790.2016471827, 13123.7768408877, 1882.76657309949, 3619.59885759589, -1537.20018442805, 565.069440436702, 12305.1583600163, 1725.86245907137, -26912.6028779945, -671.693578025159, 7433.48674711861, -5044.47754663469, 21845.0065491030, -5952.91388748977, 5300.265779556, -19176.4021136084, -3149.95182578238, -11136.2135109786, 2995.96014332486, 8488.23094164745, -16833.4360629984, -6037.64670117615, 2574.69249134807, 13264.5032163331 [...]
+-5633.14131319498, -11356.8043036488, 188.702160599170, 12808.5548968831, 20017.7448350495, -12023.6724720724, 8785.33694925949, -7846.47237714078, -1857.39278362401, 12304.4708615623, 6913.94781786741, -3737.09393137654, 19790.9106280216, -8052.71314856493, 1655.46896449504, 17899.2990223563, -11015.5109689647, -2165.35337036327, 10060.6752405464, 12713.8033895598, -17407.9445148233, 2716.87935012343, -13025.4296039803, 6152.0866285524, 13647.1999719541, -7310.53158468142, 7377.53155315 [...]
+-8129.71134211069, -5208.31935422967, -3574.19131765256, 12385.3759727846, 379.498468627093, -3328.64138800577, 2393.69266702456, 2875.68131611862, 11210.3258894219, 5589.06590419478, -12465.7914628052, 18342.4446384406, -2055.85509173118, -14162.0076322554, 653.896200168489, -3332.95178681201, -2030.37744672731, 783.377923916594, 5573.33572321467, -5921.25531244262, 4850.7063437262, 4107.80735032423, -2276.03228124652, 5343.21647333349, -1546.07298770287, -21746.5097528193, 15894.635953 [...]
+7512.88322094924, 1944.29476329218, 7845.202694745, 7227.21546460779, -24763.8392273841, -4321.16423519052, -1169.91687045950, 10820.5659283684, 7788.32416206374, -2437.86048609813, -3330.3282710926, 1554.81128626106, 9100.46728175448, -11974.0796170364, -3570.99021594879, -1397.21287922572, 106.373517293164, -2422.53748340707, -7587.53492344878, -13088.1025285556, 9176.04881011022, 11587.1557205975, -2236.06123923787, -10479.6995197932, -12544.8136927193, 3492.20512379038, 11401.2534430 [...]
+-9952.24937477454, 16034.6060527927, 15031.9515421128, 9130.13717843695, 5412.96350029184, 9117.97093614255, 95.1535848173927, 6401.79196081713, 333.016653673566, -6460.02139260234, 6323.05807326712, -16000.7262250320, 3461.67042515395, -1469.35772441687, -6974.71571202294, -19408.7295333355, -339.658776643761, -7203.2730019198, -15952.5359703748, -5934.45833521445, 4674.04944646073, -9322.95664999336, 1165.58846235205, 1825.13199705976, -8050.05952471505, -9690.88122380736, -7914.584202 [...]
+-5921.41114237763, 3702.24195439848, 13123.4956704318, -12924.7823585983, 3030.60938987704, 876.316650520574, 2653.20114844283, -3443.61695802702, 12610.0212129981, 4202.41180622526, -634.49204728102, 3043.53489341839, 696.687837874664, -9773.77267628328, 7951.54186375342, 2257.86568389945, -3151.24886544333, 5879.30297482779, -5911.96672141608, -11933.4627167949, 5960.43386056587, 19061.8170589828, 7697.47158923192, -2921.77436137608, 11704.3263844553, 19371.2719167246, -1353.7082671460 [...]
+1282.75672103810, 8954.51722801203, 7390.6251883666, 5794.29555270989, 18165.7456444892, -8763.62424392902, -1149.62726494627, 137.873940713650, 9592.03434370353, 15284.8990986214, -4601.89601202941, -284.391552653834, 2684.90966531892, 15638.0976825466, 7440.24846848273, -3546.47485990801, 520.423760255033, 10162.4706369277, 2398.40633221675, 5926.13050848889, -1130.52165238207, 6229.52041805695, 4262.77525732776, 7723.77678484153, -22421.0041459056, 15588.216889031, -1234.40460172654,  [...]
+-12863.4120479425, -19505.1559628380, 8466.93762694666, 21371.9289927333, 7054.44277640556, -25060.2921940846, 5994.24975191334, -18477.2320616354, -8682.45871976413, 9364.02595191, -9007.67175645984, 4784.92280142239, -6763.8058349134, -9007.75279212904, -10441.7996545638, -12168.8741028046, -13280.1463575938, -8141.90036617336, -1698.03605542121, -10805.6989788191, 6281.11380798255, -5189.27709649561, 11773.8749575454, -15974.9664506041, 661.56708515218, 1402.48862862471, 5716.52503829 [...]
+-6870.01780319426, 5604.89172978714, -29208.0045127056, -9162.70081676669, 5815.02506902941, 2317.12014921038, 3004.88821538050, -19554.0882779935, 16184.128975327, 1885.82131969724, -2117.18528219386, 574.535539920121, -1148.17295083889, -4278.99237572469, -1538.57864078319, 9967.20890444063, 24049.1094438764, -5010.06625697149, 11988.7314383701, 10166.6941020494, 5638.4107898708, 7026.59040651756, -6456.54317426433, -4505.37459501102, 8535.21639390193, 7983.854444919, 1047.29049017769, [...]
+11078.2453186600, 793.872692767152, 9757.7971744175, 4056.65264554746, 16137.7107232785, -15588.8372159965, 23905.91168104, -10953.1526874260, 11137.9650695331, -1855.9173311996, -2693.39375258417, -7593.70744391022, 20187.7271464112, 6025.56358289716, 19534.9761266688, 3188.69273077755, 14718.7737817746, -966.688876161935, -9220.51308174489, 10692.0887965954, 14667.9889572302, 1988.60939324599, -17383.7649007399, 3370.66678369255, 2733.14356705763, 2580.92760818135, -11659.9042457877, 2 [...]
+3459.69094901957, 1359.17250151212, -2943.72382323145, -584.253343895327, -1031.49939797199, -4460.25558821327, -14885.9236148984, 4842.36057931905, 2907.6997672057, 495.867908720707, -19282.6207467054, -4059.21374999672, 10196.7745294048, 8901.41465138269, 4592.22257039592, -22927.2401305938, -117.203375216151, -6215.19053251363, 18812.274873119, -2897.73036321661, -11741.7871961205, 5137.18543828249, -7204.51287510057, -183.706205185169, 8807.06959869256, 6119.60798680298, 1397.7973353 [...]
+3420.43989222706, -4831.79707056486, -18168.8455205132, -14068.6192483941, 17068.8816055204, 23112.8442389398, -5235.7616203543, -21782.4408657687, -10514.6405303495, -3439.51030520664, -1909.80463130984, 8421.96676879171, -4091.34851425744, -12633.7280759235, 8052.72524455003, 7528.81368707436, 3202.51211941989, 7091.54762092602, 14158.5106331731, 8187.5930058633, 15693.2761360624, 9886.0472549588, 3932.72797018705, 15480.4549062565, 9127.44918699302, 11141.4528847779, -7462.73218790429 [...]
+21170.3691659501, -4654.29520079538, -19249.4708707642, -7615.33411422326, 3610.0900551395, 15168.1731383737, -8484.06947250693, -10251.1098651571, 4765.03568565885, -16686.8496975445, 6330.2187456926, 14116.5608627513, -17920.4920719615, -1765.46640908822, 1178.61791759145, -8558.2219645673, -13476.8482798507, 7429.43379538382, 17476.5715787880, -13509.8708195228, 5951.83206181243, 9739.86860661682, -13605.7724682930, -4840.98918387503, 20546.9384786824, -6020.02611197084, 8309.54080590 [...]
+-19093.2607290860, 1885.17974335214, 16213.5360625461, 6082.55846741603, 4008.65278528481, -4895.80444078161, -7389.788722848, 2882.07046702726, 6509.42756673815, 7511.22434585523, -20667.1469146973, -21535.4037896145, 1223.0680976682, 3300.75154160920, -12245.6026767750, 7024.48820825311, -10501.6367694643, 1737.79468972853, 5605.37914739091, -2908.59605500148, 6852.12592594415, -4337.223607433, 2385.65316593009, -3563.78808341449, 17817.992881946, -10359.2378734993, 3090.26964773545, - [...]
+5024.13899230092, -2380.61602804894, 3211.71641305676, -7939.96917025633, 12816.2877347206, -2308.84878039806, 530.868683323307, 1046.63920671627, 4780.4860387656, 13541.3679152977, 25828.5138886283, -864.470511313752, -5685.6705208313, 3219.23426654070, 3108.23530792236, -11562.6230594269, -17481.8754183705, -16474.4098068749, 5254.66244695766, 5064.73705561634, 2080.34443387002, 1915.4253815249, 8929.0176163052, -9471.85597715401, -19888.5071343952, -228.609619812576, -1359.23847711585 [...]
+8938.61434648433, -1737.83312925205, -10106.0995045672, 1518.71289123093, 18536.2406890074, -2365.41755305613, -12625.1136230967, -6218.83069053464, 7139.53910853006, -4087.51312617143, 6663.2799292678, -7826.1472908838, -10958.7223227934, -1553.63093549437, 5735.0333026394, 9830.37305969786, -15528.4516603770, 3282.02267030821, -3285.98844504004, 3468.64976143494, 13.4941576278472, 11118.5344973415, -9888.9662729397, 12518.1907080337, -12003.3796896188, 9004.07789319815, 674.89953241570 [...]
+18964.7216920992, 3192.77488600856, 6025.14169292313, -6239.12103784124, 13450.5028266937, 13317.6080155089, 3717.05336425277, -3552.0443547739, -2788.27387738414, -2310.53981010657, -1775.40721658743, 5081.05799797595, -3493.25525737052, 7605.43275496401, 1165.35976228248, 12210.4053496888, 7048.93975636041, 6298.13344673432, -8468.79146629817, -1881.23705934099, 3723.58213658008, -13425.5732177125, 3364.64152587532, 1352.79217959492, -721.359921055716, -2397.76034468053, 5075.875496483 [...]
+5918.79140224225, 12298.6105580276, -18356.4670174931, -2202.7321749201, -390.291076548801, 2180.26756722681, 9280.84289315353, 12852.0730304342, -16465.2875516552, -8831.7588823606, -5526.62413351097, 15430.8305442800, 29563.9900257755, -11496.3236070545, -10726.0294808009, -4366.87512410958, -9755.2356004342, -8728.77360734257, 5658.81751921765, -4782.43784686186, -8072.16165798294, 11536.1038599878, 16951.0715394080, 7190.20812048278, 3363.4840904267, 2222.29055522551, 10517.952363293 [...]
+-10109.7809409084, -4453.17284678705, 9855.89228086831, -13764.1937887554, -4641.63799011093, -13701.8514999768, 1828.97857436737, 10089.1465144402, -8985.30261713381, 3150.17387219211, 7540.66267501429, 10554.9820575648, 9544.7170065135, 4865.49157231672, 499.619407795953, 4026.41129137159, 5002.15125206595, -14920.8954326648, -9268.72042177989, 11175.4670021061, -17916.5878670337, -2802.08677827646, 11095.7931104777, -7112.55775471704, -4152.62243626782, 3723.05761624789, -8448.3805123 [...]
+716.393022523141, 3599.82280441776, 7697.20369915507, 3028.96989777451, -5843.65396009561, -16780.8838816790, -4278.45654205207, -5696.64934669431, -7406.5411288951, 18211.9150242867, -2350.84399055588, -2398.26907196088, 11077.0465034738, 3327.39850404347, -896.365898691599, 9208.27275318405, 8191.29098702479, -6763.34955047036, 8637.13775312202, 10420.2648739617, -6019.72985382997, -8018.90522350683, -11135.5793751563, -9848.86536149058, -32745.8830619243, -5713.39973308006, -9472.6321 [...]
+16399.9171816096, 12822.085197815, 11300.8377277228, -16768.5762694759, -11252.0610743365, -4918.27020251837, -36.9329471323078, -10388.2806836891, 4905.46912933632, -2803.54749807316, -6340.97325844016, -488.519914876175, 14813.1767183733, 4634.72548063467, -14096.9366917640, 6948.43104118918, -3198.82502734364, 5413.91666283553, -14190.4312652304, -3209.29714106559, -8250.35393721802, 6244.2927865651, -11656.7227731755, 5018.76706490302, 14883.3712758096, -6308.30684728302, -11984.9493 [...]
+-261.594394627767, 355.788398060802, 19477.9074188432, 1027.48899642044, -433.632293781397, 9870.02335075052, -4149.89110365815, -5178.96665539421, 9635.54933261722, 6861.35024896489, 4365.09160877692, 8036.09053095613, 13192.0468418321, -11074.6287488976, 19847.206423745, 5945.68996125978, 14475.1874031890, 2868.84694457584, -2702.27650296901, -7813.80646102234, -16381.9637897863, -14649.7533343892, -877.47488434523, 6305.07621430231, -1889.42694749979, 16409.0920947781, -7853.166988813 [...]
+1685.17075478169, -1334.37698809506, 4762.18514420726, 15958.0417108582, 17338.8779187756, -9113.62081362797, -5567.55086394255, 11060.2490819676, -12194.1768223720, 3337.65353632667, 11412.1805212150, -6179.72792974974, 16426.2530932923, 12315.6826060136, 11566.9048966690, 10279.1106794263, 5261.99603411265, -28102.2135644367, 5090.16781931923, -5501.34740362164, 25447.6651277508, 22792.6082008817, -13333.7164253425, 98.4711960255187, -685.423983105305, -5362.44436763248, 13293.43460590 [...]
+-17765.8221767906, 3103.21755666295, -23469.2484828278, 4157.68929508267, 9480.99508884632, 4733.42939427159, 7680.69049174214, -4532.87333131664, -2373.17924824375, 9062.1606016996, 1476.39762736602, -11395.3289811665, -5183.25798477183, 7457.04803921667, -12020.4105647358, -12933.6511129152, 493.861327500751, -8691.30700104342, -18889.6219428548, 28888.6931362986, 2996.87919644812, -1245.65786127603, -6684.31356516064, 13588.1819219222, 16960.7379479265, 9499.72454519155, 6292.27947738 [...]
+-7051.84171123754, -197.560449587027, -3337.60362443802, -1515.65795419346, 4992.94824408007, 2716.11086376371, 17271.6204933409, 6032.00924184753, -4978.45992194577, 10925.0273886320, 18748.2103936075, 7847.41512528158, 7120.94936079207, -9053.86694942607, -11609.1181847505, -8188.49926162712, -3297.97361452178, -10547.5435787476, 4145.80216957757, 9717.96310220522, -1603.80720495266, 4524.75966717630, 7056.87139677406, -1654.16302953923, 8627.95542215432, 2328.30037777903, 10087.131753 [...]
+-10318.6317740459, -1276.60384985643, 3477.42591426795, 14423.9859654041, -5528.24937034827, -10951.7509751190, 4328.77040475704, 7070.19494497253, 1442.57782248329, 22527.8712463987, -18826.4539336384, 6757.14849666689, 11684.3219677971, -12782.3182270329, -12539.9360453242, -7634.15504905496, -6589.54415295143, -1418.84999981021, -5334.74475342464, 16571.4348631136, 10079.5326862544, -897.930264165448, -13129.4126513860, 5392.46773801648, 7218.68309720669, -29383.8955947451, -9332.8449 [...]
+-1389.43957421304, 4256.71214656063, 4492.20418622738, -3462.27863097691, 15662.8377700047, 3788.96746124672, -13920.3653594509, -8060.86887798273, 5702.53944607579, -7720.73873138395, -14483.3572575388, 11498.6787715012, -3952.35772250052, 12601.5620190063, 5413.2783493216, -2416.09550719835, -14571.1461053082, 2651.2950653394, -1598.3228916142, 12506.2252975273, -2196.19125234516, 17171.4380000681, 13384.2049106298, -7592.45313563325, -8202.79632080224, 2301.18656620322, 6316.654684463 [...]
+13337.7203761262, 7970.14610504638, 20310.3400449757, -823.968088807699, -17726.0371079455, 7430.89062415405, 6312.36930665289, -14987.5731022850, -8457.41878119534, 21667.9292701066, 2595.10727973726, 4461.93886267832, -6520.45440159179, -6806.01618403201, 6288.78692424401, -10409.1750523052, -8416.33271454324, 7460.02645428675, 3881.19452547227, 3810.02233741127, 12771.9577429148, -4971.60023019572, -8916.23353489019, 2768.12440276314, -494.516359832209, -11946.2452010205, 14211.247589 [...]
+15722.1298518067, -8640.27615623418, -7151.13272860285, -19851.6818681493, -5548.87530066363, 4231.16135293601, 7907.11797970493, -8598.38965424002, 9162.16504256788, -3229.4579475286, -1592.13940558112, -14372.8313666275, -2665.17198542376, -2927.38496044741, -17523.3809912184, 3921.22765752025, -5163.94242356407, -3460.5777214927, 8211.84331874274, 4772.08041247415, 4441.27496631393, -16721.6043884482, 4453.03542842709, 9219.39585728013, -5535.81732101444, 1302.67554944895, 8135.212689 [...]
+-5056.96587504903, 66.8231357385888, 1990.63780231683, -2869.29452358324, -3866.02335391091, 1253.94010012358, 7469.92619683867, -8654.52803343034, 5661.05062036631, 19404.1435475922, 9345.186562002, -5125.62798740996, 7291.97280665335, 4079.30054013187, 1514.45603861141, -1569.03639424497, 3473.81145979959, 3526.420529889, -6298.3366071692, -16611.0871352968, 5528.91872541138, 9168.99510521914, -14848.4790222901, 10754.4564479040, -11035.5194537210, -11438.7252412496, -10987.0384757954, [...]
+-12940.1167620923, 460.088811143568, -13858.9536401858, 9928.15413035534, 12133.3202992158, 17444.4068506049, -6963.12337393092, 4872.42512134897, 7007.84118281135, 9920.41640938294, -770.694970147697, 11762.8602243820, 174.960222446096, -362.037663635236, 13675.5269729190, -16874.0672051393, -2748.70590914913, -6003.60614741937, 16723.1570311319, 2724.65268630943, -10607.9355448576, 8608.63906551018, -7174.42233747364, -12758.1068757772, 18594.3798591718, -5985.34559312085, 7601.8387412 [...]
+-938.989796234801, -10479.1400591234, 11280.0311119286, -24903.6667400689, -2265.66926207697, -12231.4777049754, 5220.86310031665, -73.7547656225618, -3556.81786991085, -6678.71093464777, 2396.74298693922, -15075.2364543902, 4777.6586147976, -1332.24041343422, 3845.24762953383, -14345.3402526829, -19488.3973077806, 6510.10498484982, -6005.23832571896, -7292.5692854352, -870.250234959167, -4112.83073529828, 4729.15606529154, 7356.40220727248, 6696.77239275833, -13667.1401029904, -18612.40 [...]
+1052.35055527775, 17516.5817605817, 8597.07811592594, -6265.01748972591, -146.462104964996, 17172.1680225669, -10512.7924573786, -5841.07626862249, 977.104679079888, -545.625131413634, -14262.0451989453, -7125.39644738051, -7609.92082735119, 8030.48174202613, -12575.3332368345, 187.848331950970, -730.194023406001, 4128.07048747266, 7416.02477032416, 6868.63602196614, 5751.76372810522, -1349.18095745985, 4431.00810008469, -2563.94466498159, -3181.59079211224, -10790.3270244489, 11093.6864 [...]
+19877.9410219970, -3400.67376390586, -11785.6121608208, -4055.38516920972, 1522.53047974514, 6265.1106878983, 10057.2611362305, -6406.64823640416, 10947.8606113980, -7683.75175889728, -7518.70355674458, -9311.37916699982, -276.619910066672, -5493.78873158076, 6225.25035603829, 10292.9599653788, -18279.2610339848, 16734.9642983392, 309.803098717940, 16006.9343920531, -8228.94040667366, 10231.0965761532, 8361.51258816309, -9530.54153992472, 609.504464843573, 23198.6846069311, 16925.8207129 [...]
+6346.63315623606, -9161.837746366, 4056.62595242276, 9732.40359066252, -5290.95620040655, -554.920793181211, -7202.62837022806, 5798.98281765651, 5498.77344522729, -22002.7841346542, -6842.12507793955, 8929.4225732372, 4987.26179479538, -3975.15656026353, -4608.4806448484, 2852.08001011659, 3409.14454961175, -13793.7761894085, 7493.21976133125, -13522.8142720636, 5724.56694462524, 5341.80360048167, 6725.01662934154, -6103.4788783378, -4879.5187788209, -7156.77198556072, 775.5810831804, - [...]
+-10556.6030802725, 4764.3884243152, -4348.19357929538, -13524.8551297246, 8667.40153491529, 10128.9679167014, 15126.3174238924, -7719.3772305895, 3009.25000992228, 14155.0985426319, -5415.99133577468, -9515.25189497066, -11906.7117572976, -5943.89189300153, 2293.69884117860, 5732.69770167001, -11069.4349257030, -8898.67107012971, 3711.92853175764, -1963.37952034919, 8758.16640788064, -5663.93721331151, 5588.40712192974, 11562.3236211055, -8171.54787142762, -0.9396360491341, -3640.5717937 [...]
+13699.5171082980, -6464.18443622009, -6476.67316732318, -7145.71944240192, -8931.23679760779, -13560.3214223195, -9106.1331864037, -7652.89553762085, -8632.8179019238, -11243.3359243664, 14583.4141159486, -7112.48875261674, 2968.78721684614, -15791.1582204732, 7646.06993323006, -1746.84258633264, 6805.51194097722, -462.158639744802, -3709.85827048559, -1258.11793352771, 22967.0883024910, -15109.9055631662, 7870.54780929158, -4801.18296376804, 6759.6896707178, -11235.7530012106, -648.4843 [...]
+13365.6640762170, -7946.56798281164, 24881.2164852094, -1910.26988877555, 16793.2528164101, 4903.73471996252, -1912.33557078461, -4428.17177138395, 5588.01671757532, -12646.7766248337, 5078.27888491747, 15.6346210695138, -4390.05537888307, 933.930767649723, -10423.9853045907, 5604.28083119791, -28118.6493123217, 9949.61020732453, -3352.61317043294, -6314.90749224599, -2607.70410899145, 5528.65895936509, -4100.78736116246, -1993.79896069188, -7448.50248530124, -15007.4405024048, 7915.1758 [...]
+6353.61905199928, 7564.19815486875, 3409.78057104814, 9748.26608235094, -7453.0637214284, 2010.17797869335, -8392.20525879276, -8588.6890801648, 8148.83555161502, -9971.26448067848, -8419.319928011, 3455.09637820079, 4322.04325462186, -16719.6282135880, 10045.4279798633, 6206.40296266195, -8623.76191250108, 5563.75082888007, -11837.5924378280, 3229.20528962814, -2866.15715154204, -9520.70886998096, -5748.67510720675, -838.673866735837, 4263.32473447982, 7752.73200556355, 6346.62212933637 [...]
+7411.4378368483, -2762.52435485419, -7045.32204046016, 36775.8405712612, -7568.33246851151, 12610.6660208555, 12322.2034271473, 12097.8832603135, 9248.94411681168, 5289.54230149718, 10693.5933836351, 5157.40808953828, -6489.02944585792, -5581.66659873843, 20663.4031793047, 7149.33230532946, -4715.01345263156, -9772.0464644351, -2950.45824539357, -7180.50300550914, -8186.44916389221, 5339.12758837358, 5269.01747063792, 10143.296526901, -7367.55229172908, 6141.05869027834, 2506.12076861200 [...]
+2148.30841791438, 2615.06567155347, 1110.85707175566, 9049.2338637304, 17768.9510813167, -4578.51422408908, 10025.5456780761, -10088.0114629851, 2185.73971123248, 6057.52304263524, 6828.13294278781, 4944.26858482381, -9620.2363383815, 5619.18657112072, -11808.0321233830, 3851.94151258621, -7332.24744774965, 5237.6309015314, -7363.2253186043, -12966.7856752744, 2562.02725282204, 946.381988075713, -5277.57103178924, 11288.4581149558, -4687.63289791732, 3573.6172939433, 12890.3189675354, -1 [...]
+5945.06632909641, 17132.1719653942, -11015.4378741162, -16295.1876425404, 3190.69780036563, 3763.29002308474, -6191.91519055332, 2738.28970258063, 6157.04536129538, -4074.76946709436, 17884.3494865866, 16312.2894801906, -8234.81911111059, -6002.54988475348, -2460.37627856953, -5456.5053910844, -7683.58720644839, -2104.14569657244, 12860.2455926154, -17112.2720629494, -12654.1279203191, 14066.8489821829, -16684.7280241257, 14612.5311172923, 5098.08560960722, 9734.8957671761, 8541.41959339 [...]
+222.129095387306, -4787.92451843636, -5758.71153389412, -4245.20169207323, -10095.8925289212, 5468.45141515166, -15320.1162194931, -8132.96133594389, -21637.2258112945, 2217.30874824638, 1266.36813312552, -14423.5631056512, 5900.3760543958, -4689.14279675096, 10587.7784430172, -12463.0470935005, 2226.09832053049, 8394.6299218197, -25953.6911143053, 605.8217374583, 8552.34313412094, -7583.09812593464, 196.909141777795, -6008.47919337562, -12882.7398170233, -737.705132395159, 1300.70535988 [...]
+8810.45145464662, 10813.0007636419, 885.600474511445, 1007.07864939599, 6469.93538184808, 18818.5441670130, -9450.90132892427, -10219.3801135594, 15852.7731793364, 1900.18029356104, -14500.4597958441, 5681.01777653411, -19227.0452788367, -548.154655683242, 11782.1911652485, -5907.40912973331, 14355.8560963784, 3908.77599171986, 460.705422794928, -959.212538157697, -811.779616060786, -642.733997637665, -7333.9818314881, 3275.30567910714, -4753.65586945427, -7766.61688611405, 16315.0548109 [...]
+23415.5424275607, 5000.32524629769, 14538.0369815416, -16733.1843438295, -7052.03019164684, -2707.85844314651, -22.0130090760149, 9043.92487190023, -20962.2603319183, -252.466270923659, -3127.06257228984, -2117.30990313028, -1121.81302959966, -16564.4731615542, -16769.8710934762, 1597.43951321891, -22995.9182037999, -14548.9770848620, -5061.1342012061, -4852.63078728652, -17924.1356610063, 2169.48289183814, 23658.2659213137, 4770.82743113278, -7301.89120931724, 2847.07976805189, 16793.16 [...]
+-2230.76710320247, 20257.7254381870, -12382.6194604103, 765.132152454957, -29314.3798407867, 3685.17247502876, -7247.69407519223, 2049.09841924101, -3946.17892878103, -6348.5947982166, 16423.5527035613, 2777.36906036518, -1162.66857974306, 8620.72365811579, 2448.19190970410, 15517.8204836917, 433.298057163238, -7797.45071392401, -9510.94616009453, 7557.77802128739, 15962.1095246134, 10334.2608482270, -16430.9456976809, -7334.12224724791, -30515.69916274, -14323.969164532, 6003.9238544999 [...]
+9936.13388076833, 9755.11481034717, -5480.7855238916, 8238.14298605944, 1856.16580538636, -9300.9328919608, -13711.4502317185, -10513.9664029167, 3624.19783246769, -5544.6731782037, 6607.6623512749, 13970.3386019889, -12942.2025502030, 5162.68925040393, -2980.89184891617, 4484.07207633849, 12125.4427396527, -27494.3072945103, 6792.0327160484, -8076.27739886473, -17779.6246488548, -4964.55169423446, 3272.08583728856, -11294.3514396466, 3470.39560151085, 3513.15632637304, -2396.86739505226 [...]
+3142.13336130251, -4648.00097084593, -5148.95971412332, 7948.1240497673, -13848.3679962846, -3697.462247497, 6287.28461882557, -3663.9315267436, 4755.52045557393, 1711.08301600426, -6426.62393832286, -10513.0909233439, -3795.70682481880, 195.849077621760, -5097.36949045282, 13920.4493351514, 3250.97672661082, 13317.2120097489, -4468.28597403864, -464.201060528081, 31464.3294535440, 11841.7793829803, -2332.00978849547, -7511.6167834587, 7988.66828130331, 16404.7575137704, 8905.86654602545 [...]
+11991.3532628922, 8397.82320611634, -7764.688493407, 18146.8306216232, 20336.1546799880, -19539.0191052647, 980.050178075226, 3821.06378665545, 7360.56758734574, 9962.21696005933, -2680.43833921492, 1802.71103473943, 20201.3651467763, -13383.4324904964, -21336.670755985, -1746.71784242886, 5219.29529280654, 6805.69173370904, 15966.3639905598, -15274.5688761589, -9052.7212017696, -5291.42955267722, -6287.80320191385, 1861.54144927574, -12989.6202766584, -9355.0705354199, -10734.1738988305 [...]
+-6555.92512963742, 8757.10194046822, 18574.9512087333, 27443.6108510419, -6366.67820335208, -10272.4000892201, -2441.14471632329, -2857.98865546391, -10724.2574389843, -2943.45083322213, 8215.7609432415, 8675.48855964714, 26890.4521545015, -3541.02941344278, 13780.3804653559, 3246.14180034473, 12116.7087071562, -6717.53762192762, 13096.2751470863, -4829.04481750496, 5601.49606806705, 7118.78890536162, 22302.5452216962, 8666.6657551927, 10106.1512517366, 11273.0958282662, 2229.28035607071 [...]
+16853.8128971663, 9471.92564150814, 1605.24438266041, -5278.86269049185, 11619.9073953624, 1662.09679093158, -6127.35754801929, -21003.3277214078, 20702.2300370788, 22309.1387492763, -3421.55512473269, 2815.31391379188, -6611.68601625597, 2919.39714940907, -6028.65942127336, 8733.68705957007, -3609.49788572097, -2103.02442719867, -2148.99597778255, -4720.58117183765, -6652.82404995726, 5876.68824614925, 11793.6168744459, -4052.15760214747, -10776.7076391213, 323.979715816514, -3143.33875 [...]
+1180.82905714396, -22725.8873288921, -13623.3632918679, -18366.0650103260, 3190.85261851132, -11488.5015901438, -6878.48855758596, 3556.68204635941, 9979.77780552196, -3604.03218736916, 7464.60237875832, -13513.8465460085, -118.469318746768, -7501.18594261937, -8598.0013725686, 4826.93390384826, 6329.33494137928, 6739.35877902108, 28115.6677558286, 3176.05726430449, 15145.9026238134, -19726.2882030537, 8180.21271555257, -12384.3974317385, 16878.3673896573, 4572.08036580503, 4562.71198963 [...]
+-17090.9194737821, -745.048764477889, -1880.87996688635, 4634.34199153157, 18372.9127381251, 5386.78506109133, 4780.39275668725, 3840.42493551610, -7339.49012805953, 10900.7731567584, -2413.05196892538, -6651.9954600436, 5690.46618734473, 2344.03703900077, 12962.6618905041, 2276.67086795376, -1297.05135643494, -5183.20173325614, -1796.63643890475, -6213.83635262603, -2136.69545909329, 2197.0132949806, -3670.54134931168, 11693.3279006251, 9228.53961321618, -6672.89668989401, 11029.6952489 [...]
+26414.2539663843, 325.869759329811, 13902.9325260432, 2114.41008484436, -3444.9056829863, -6207.32982018945, 12334.5520857831, 5795.26774993403, 7773.48605014727, 5625.12255888508, -28010.7711535775, 3894.23313111365, -1305.53095488164, 9239.65039313185, -6652.35225623483, -9839.69690480084, 11791.5256471568, -9657.63006728627, -5449.15351588571, -2074.94031996166, -4006.24511691331, 12307.3235723365, 7264.92266191364, -5149.83980112961, 4639.75705694477, -15601.4638358321, 4645.54903000 [...]
+-6929.54708904132, -6739.29224132713, 6421.60895078647, 1535.21384377052, -3361.16849040951, -88.0775687997371, -19539.5276777733, 9768.98664940694, -7013.98902222996, -1415.59346224371, -8912.34687956855, -11252.9509480370, -5051.78254719247, -5618.60951648365, -7349.36593549512, -2169.75815129369, 5360.48865092982, -474.387749904847, 13248.2326420708, -4484.87882718643, 3878.31047294614, 6795.12561369904, 9768.87678763728, -13244.9907218729, -5550.6332348057, -13370.0286269795, -7798.2 [...]
+5721.4567572348, 2151.65601393784, -12381.6770913634, 10374.1775390565, 214.210029594631, -7395.83342787669, -6910.22487166948, 14765.0353827124, 3441.99550329166, -3453.33905247983, -78.9677244828262, 2215.73908585342, 11376.6347871211, -4980.24680413119, -10371.009515978, 11420.2016099991, 7518.21618626373, 6285.97679823326, 8501.065691309, -2402.26224079810, 3916.75487336212, 6544.2951739964, -1042.29612365445, 21013.9514874014, -5498.77344426639, -8513.71511160129, -3454.41548152515, [...]
+21982.9566752329, 19530.1279450463, -4144.83477979514, 20659.087723494, 544.379081934917, -22864.0880510767, -3819.82401261572, -15243.4814751503, 11944.3483663516, 19254.1549643578, -4242.68794310363, -16254.5666322160, -2022.74094161655, 4790.25819710055, -14404.5081251306, -11896.4886832552, 4671.78845510398, -9508.35484964149, -2740.27913526272, 4544.24931090061, 14561.0123641206, 7628.31442161402, -3497.70312243928, -4280.81039774084, 12634.1593632456, -4092.4686243564, 18157.566859 [...]
+8011.77490954482, -8550.81440951235, -13324.2957453373, -8054.85252788292, -6959.92821287442, 3090.52744713016, -4743.40336292185, -564.860555167957, 11740.9967982143, 453.185433306712, -5056.01510527462, -2958.17769243183, -7299.99736455486, 6841.86036905963, -17369.1825774787, -9157.18493048668, 10651.9946422644, 9625.01028185765, 5658.20996260221, 11776.5419243498, -8142.84202778157, -17241.4350850859, 3644.06014024735, 15858.1353059812, -12585.9352832059, 9562.0274833401, 2150.152169 [...]
+-2344.40446669888, 1735.63289756198, -20152.0321659589, -5752.82118522637, -16462.6008242165, 5982.46919298925, 13287.5799909979, 2828.54828823657, -9636.50743610895, 4978.03131171586, -7801.35263274654, -15193.8523847016, -15991.8170587283, 7260.43838308848, -1318.84781224137, -6528.30339061108, 1303.11814192026, 24356.8755678137, -290.151792098521, -1420.83044947403, -1208.15623880215, -10701.5585305619, 14674.8935495646, -7703.54399868611, -23090.8822327039, -2077.32631420952, -25988. [...]
+-7060.47109724037, -8317.85361082613, 3922.29356094893, -13472.2436252653, 9725.7317372876, 12092.7303875407, 2622.93256319782, 3745.07107359457, 6500.31058457853, 2240.20105078119, 9391.41873853783, -606.825174305483, -7602.64873457781, 7009.18163509564, 4804.173293283, 6807.68015224327, 17012.4653237711, 6274.54610270195, -1519.61727841710, 4663.14037925895, 17474.3633803762, -5008.28322416226, 6383.85442403124, 9752.55506923079, -7156.35651392389, -22129.4371558236, -6268.3811622921,  [...]
+9565.31633518552, -11016.3808305782, 6916.24489394788, -4855.64802600853, 4936.80061506377, 6824.67756453505, 7925.21564010243, 18851.8385715078, -7711.09946814646, 4699.47414730972, 16997.7407887226, 2230.77945666095, 4910.41440477032, -18795.7365817683, 11725.3247764349, -10467.1642173583, 816.85940704531, -11231.0605805842, -8717.61607994254, 13510.4383295511, -15169.9675619909, -10263.6185939315, 9216.25409445767, -7521.0836702561, 13394.5812340191, 19004.1701774115, 7747.36048193991 [...]
+-1320.43155915603, 2881.09169854838, -22575.1582067968, -14565.9022551892, 15620.8101733232, -3978.48578853971, -189.964897375012, -1418.39170449905, -16464.4657340700, 25799.7669270599, -5735.80700250329, 5767.15865654185, -3099.71392175437, -12150.5941231474, -364.73210931521, 13861.6326483281, 7688.41325662826, 2190.75115230741, 4234.12122940097, 7159.79339143438, 2067.40207429787, -2922.43267401123, -17709.3749692251, -11209.833777018, -12599.0318088846, 18298.1841208270, 4013.927106 [...]
+-15289.8184564530, 6296.56113520643, 310.422435007171, 13407.0469692718, 1994.94307085087, 13889.3705455619, -14126.1761254475, -1347.33865854092, -337.922191587573, 19178.5338867966, 6736.29309329927, -9213.75522241921, -8965.56907846585, 2809.51313927422, -5578.18834657891, -1672.62970895291, 948.934543440044, 6549.87387021051, 3681.36338927115, 14183.4790786341, -3706.49244808656, 12966.3019768341, -4089.52618373745, 10487.8227219731, 1379.54145516112, 14657.5913079762, 430.3335340517 [...]
+-10415.0637133091, 17194.1193558641, -7505.30249363412, -14861.5565030745, 2037.29949613579, 16555.2547347008, -10468.4069999018, 1853.81149538400, 893.159810229509, 11848.9051521030, 581.255743996008, 7172.63250523572, -10219.5415372850, -12023.2888094844, 6168.16735305138, 5537.57728723234, -8762.87084846818, -3965.67973204662, -13726.5345959574, 6873.76400590913, -6596.39298658682, -10625.7836279299, -10233.4332988953, 769.586199759834, 6998.61112440614, 12640.0755711121, -10355.60330 [...]
+-7365.4851579581, -7446.5901365753, -26739.0861869492, -1323.07223366828, -3421.52798018241, -13676.5839640179, 2417.5919334941, -27661.9752375644, 9071.3646637786, -2368.81289440331, 3110.30141209443, 2473.80427053465, -7570.05940184893, 10434.8791201612, -3098.39173451236, -18235.9418000601, 9493.95618745795, 4665.34758525899, -1481.67263221035, 8346.11114326718, 8590.40102920566, -6080.65308201099, -1533.29749133981, 3847.84035358724, 11231.0085763511, 7164.49094205771, 4517.934489048 [...]
+-4620.51736330856, -7639.69624224963, 3289.15193019413, -2441.27542258232, 7143.49009258779, -6005.95201289947, 7495.87949313295, -200.419807413705, -2412.80985285675, 7665.23772953479, 1238.63689560002, 6101.34293592453, -10865.2606446405, -4959.49966623084, 8967.41765283541, 2106.54757652435, 4731.82194889078, 6038.24603670174, 2700.8447472398, -12718.7112945215, -725.434282705042, 6131.82924378965, -1794.98566904074, 2967.16899983434, -3550.11936147819, -3592.24758258604, 5737.6940745 [...]
+1170.61564053304, 15699.7297727391, 18223.8276858449, 16299.1498365588, -20146.1576647663, -10052.0110812407, 3327.95567768449, 9385.26664953373, -22646.2925043801, 33715.4875546405, 9277.34301436998, 4937.71909678878, -11875.4187488717, -4081.90581007418, 8752.28291765822, -824.29101749517, 11107.8715348101, -7539.40297197, 10936.0968803095, 1450.02403321816, 2338.89531332874, -8288.78895840727, 4876.37262339386, 20450.4964251599, 4497.42192749238, 16508.5390314712, 12199.4379537855, -1 [...]
+16040.2247924329, 1503.64804432072, 9047.89039837012, 6531.30893222386, 21819.0647630771, 361.167251628662, 6964.65850011257, 10821.0653210619, 7069.03274299023, 6407.73934184843, 23183.0493192992, 729.604772163183, -15522.5846542853, -14971.2852688609, 2322.25416310474, 3160.8011432638, 15123.9313680444, -20426.1294958753, -2047.5252594483, -5676.29263948878, -15896.3619537898, 15553.2010534641, -2007.0195999606, 4130.1941166856, -5033.93549242374, -5448.7778871964, 9195.95249966392, 32 [...]
+5937.76135022059, -1290.58485879160, 14056.6888346485, 1911.17138729392, -4101.77590300918, 3396.91116000681, -4779.34260205912, -12204.0489454187, 1869.28955987665, 9097.73169186942, 2145.33980168079, -9333.81908164607, 3488.85003950803, 2362.60352703809, 1765.59909866466, -15222.6911901764, 6606.9991889846, -1254.88705513619, 1347.98207131889, 10536.9557840237, -1461.08208579880, 19478.8032264016, 20289.1023771908, 4713.45098193195, -913.364439708951, 21480.0220240498, -987.88345418856 [...]
+-12718.4323200109, -5437.38845851249, -9387.69063309266, 2099.25416699139, -11390.0058174729, 765.553931956425, 6358.56729777334, 1655.88252116681, 5201.4437970531, 9326.89893464412, 885.074502920111, 1368.61991846051, -13584.0007361254, -10929.2502032326, 8808.48577269704, -8850.0913350618, -3125.83981751055, 1875.96860022938, -7610.4582057144, 9907.55483005133, -1425.14472385291, 2942.66994352560, 7118.96189338726, 5092.13958338691, 4601.69611608722, 9600.28115931731, 8833.19782478484, [...]
+-28007.0232439889, 1601.97464472558, -5315.95217874268, 336.608774253309, -13073.7008709934, -2921.0958069663, -6918.94480196034, 5405.94019647396, -6501.04781910376, -8034.63781504728, 10757.1670492661, 17108.1422695513, -823.732200795805, 6984.05269648934, 872.667238017043, 10934.5611256786, -2152.10865003335, -990.2729414027, -3465.07126851585, -5241.01545792699, -3771.51952034421, 14816.6417678502, -17322.4205775971, -3220.71113129625, -11813.8156912876, -20954.2927942536, 5438.94021 [...]
+13940.4612897770, -1342.14922084425, -9134.4443548027, 11684.0266560565, 29707.853855638, 3589.28231560964, 892.449186350325, -18647.5527647428, -15977.3432063525, -1192.76784117481, -5772.03529102667, -10143.2472342203, -16932.3902525028, 12720.8198444712, 22742.782710804, 5916.44644643242, -13120.6708071535, 6914.61416196153, 2627.59183994173, -12388.5453608498, 7754.38300380256, 26157.7301518665, -1369.2283485982, 9802.06148510911, 18392.6017630549, -8469.1697340248, -7992.55180606106 [...]
+-23982.4902890863, -1082.88981663230, 16281.9172160328, -2488.97432403586, 3343.76696074297, -3059.5794660206, -8309.37886461983, 20100.0333982969, -4132.44230325822, 12256.1110702754, -769.178359500308, 249.669818390885, 14224.7905339721, 9934.80496886203, -8870.65870651206, 2783.15587867557, 14305.0114378950, 14276.7191013823, 11770.2093201362, -4992.19757405644, -15263.8300472789, -5006.58641267965, 1593.47550271968, 21879.8055131518, -7146.45166100021, -16247.3430412361, 11362.709129 [...]
+10178.7485742702, -5558.84570886119, 3631.35000538844, -5271.19652453275, 18887.0929103166, -5845.59438054185, 21194.3010577333, -10510.5923239111, -6462.60054715458, -5894.30260671796, -18365.1943379720, -7060.40336676621, -7341.66833776388, 107.927739329013, -4618.93737570045, -3175.37219941871, 10219.1198819948, -8918.50532901768, -13202.2448837173, 1759.52765925510, 2491.58917879333, -5577.97318247942, -2838.12043390014, -17334.9775920782, 16500.1023260416, -8010.07252731586, 6082.36 [...]
+10647.9810110270, 18454.6222128454, -9359.38132096247, 1620.17389483016, -4202.01550503778, -190.588232946766, -8808.38007325434, -18214.4522677282, 6797.0132657337, -1058.71839350005, 2037.66339590507, -3936.01852955575, 67.1347563554273, 5854.73954086817, -1155.11857987468, 7220.99821282406, 8807.049463934, 15912.0967255983, -1628.11981328683, 17446.5106962246, -9347.9911266351, -10023.0004122325, 3719.30641665473, -9014.9888682102, -8316.1829662879, 7974.8588401129, 838.355691641522,  [...]
+7415.17691143153, 17612.3722698116, -16627.3763694004, -3862.35217019568, -2118.87287876393, -9585.22620167855, -2726.36949989192, 1571.27435278939, -2218.15906350861, -169.320348228711, -10043.8309699236, -13277.5639007808, -11534.8503573591, 551.115245333744, 6865.35941826977, -8640.82042067067, 8427.33441719877, -124.383956178881, -3832.85915499766, -23604.5160320507, 2366.63679484143, -12859.0022488694, 1913.89294412724, 3292.11494615303, 4206.79535145234, 5388.3750138727, -3062.2566 [...]
+3862.67032154555, 12619.2459571269, 3815.10474356451, 9093.746839335, -9128.89059361876, -9828.00022985892, 1525.86728192293, -7607.48133097873, -8739.91863658098, -11076.1457006069, 7647.49254323722, -10792.7097858511, -8110.18254935957, -14369.7074139562, -14577.9159110419, 5113.58284835258, -13932.9791920090, -12988.4665482705, -6547.32073783291, 9332.36305813726, -1718.37568530143, -3719.87784851023, 13069.7269522963, 6042.28519364077, -5678.76549390954, -3551.31707706713, -456.07865 [...]
+-6081.50393921486, 11245.2478184076, 8208.00526945381, 8825.88800796728, -12489.3366866016, 1724.5823868432, -9539.6759974542, 2665.60524424693, -2353.03511868273, 1696.45793189641, 14695.1171054371, 12595.9989878359, -13868.6652933904, -8538.16935181854, 21565.3812005727, -1215.79229474033, -20505.5241154257, 13842.2966033778, 13939.0803276074, 14049.1970789630, 11038.9868221483, 10520.2051278110, -4238.87172282183, 4358.45467739217, -7887.61388268187, 12410.5275133083, -7390.8809431055 [...]
+
+double y8[100] = {
+-91692641.4947016, -22045836.0791763, -13230386.4672756, -123035191.217161, 50429920.8189935, 13792438.4237423, 41315803.9298188, -62965720.7937154, 94482070.740244, 40700563.713854, 10317897.0348672, 6448005.60811446, -12452805.8975128, -39828228.3860454, 38197303.710843, -12923417.3041794, -59133907.0787515, -82074218.8375644, 127858144.577532, -71834949.9785227, 46377624.3841635, -54308589.6147598, 72646019.093946, 50870472.8603386, -129799571.932105, 58381209.6168467, 30433723.799027 [...]
+
+double lars8[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 170.69269704813894000, 216.87429831800964000, 274.90306052058156000, 305.19494697136628000, 323.80225459617350000, 330.44265638987798000, 335.21942049271291000, 382.54469713223529000, 435.48997712791254000, 441.36885291719079000, 443.16411676041599000, 496.31969460164856000, 525.80954313007544000, 547. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 80.58605646497353800, 163.32058288994480000, 181.53418786163263000, 326.22336829039392000, 467.98122136497176000, 513.68284729893003000, 597.30979741746876000, 644.00399872501623000, 672.59144920956112000, 684.71550554973294000, 693.78515914064496000, 792.13287266715292000, 897.31143673774113000, 907.59295911021661000, 910.23125814702189000, 980.22803492798062000, 1016.205576680077900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -66.18678689789101100, -83.42912610601773300, -257.37464716748724000, -449.11281663817675000, -509.58166344063102000, -604.26506131629878000, -658.34635926835642000, -690.56568046451900000, -704.94302547440770000, -715.55301455177550000, -816.97340187307850000, -928.05226150065744000, -938.01183813666671000, -940.30527123186107000, -993.83554627799492000, -1021.48 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -22.52526631642935900, -90.87901279856242800, -150.73020038382757000, -164.11057290044664000, -272.66383891720415000, -384.57582103280794000, -413.96202750244805000, -450.65710347549367000, -473.49414618114025000, -488.30344421786418000, -493.60011649256535000, -497.06675640852927000, -539.98732448799444000, -593.95281071982060000, -601.54374340109337000, -603.39861101980750000, -646.48848856454572000, -6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -20.32225366120043100, -184.63609129521495000, -356.48238012945762000, -404.47457876674031000, -472.79474458322255000, -514.86553468623299000, -545.02831735557857000, -556.38694456201233000, -563.81229806918361000, -631.12983121201557000, -699.83912699532050000, -706.20849974198381000, -707.50010594740388000, -747.88338404800743000, -767.29521 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -360.86172937119795000, -445.51869995961027000, -475.19673909480633000, -555.70927833092833000, -636.19885402472551000, -650.99848405311150000, -783.59556720903424000, -907.16176490989164000, -936.94665542163420000, -977.52758200765322000, -996.66235726799800000, -1007.04701641049470000, -1011.59588342217610000, -1015.07013495055380000, -1053.89380866436390000, -1084.57978357280540000, -1088.63916997047520000, -1089.73118593447290000, -1122.25247 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -5.88544189463283640, -63.77946413620000500, -118.77239032333013000, -120.37938306918835000, -120.80404488194350000, -127.86964218409713000, -130.72101158904491000, -136.8018872 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 17.16417470548459400, 25.32949082603812100, 46.4403 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -151.85262108145093000, -331.63798550849924000, -378.14191118802438000, -447.35796899946388000, -486.44962379360754000, -513.31848045204424000, -526.22296482613592000, -535.30582075154450000, -624.60264900589129000, -722.54789203438918000, -733.00221975826753000, -735.64033561098847000, -802.22683259586302000, -837.7997763 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.04096958747768650, 56.00811202297454400, 84.59128779574112400, 108.18098936369655000, 125.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -75.71341122554790100, -104.26568899853154000, -171.46940361768756000, -252.45153358371132000, -274.02958059769423000, -462.50982946296830000, -664.73983943620271000, -720.97660068011794000, -811.28424261861858000, -860.96140975366723000, -888.99698275376522000, -898.72691155356370000, -905.58619278773108000, -979.72147348788258000, -1051.49137872542880000, -1058.04862386778720000, -1059.39583432256900000, -1090.7166174225326 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -101.59183369612394000, -160.81892501198479000, -198.48470139440917000, -212.59569485245498000, -222.55552457779461000, -327.97209528315057000, -435.49662696432461000, -446.21421290459023000, -448.87077592172426000, -507.77530471167870000, -539.9847755009157000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-345.62196817662834000, -556.82323233995305000, -974.36766335983850000, -1079.74854164926480000, -1119.05570520668950000, -1232.29849801453040000, -1330.07857565136670000, -1346.52597577484860000, -1454.29683542718410000, -1537.03000375305690000, -1549.60697634811570000, -1559.19362842466530000, -1566.17584557340110000, -1569.92524519696240000, -1568.71731337250960000, -1569.48257775190360000, -1578.76314272205490000, -1585.51007606150390000, -1586.44633636030130000, -1586.75872390003130 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -12.26756437635706100, -20.17218820837448600, -110.49895739595463000, -205.70513362981779000, -216.36123396176995000, -219.05620976225794000, -292.60057684613253000, -330.25736335947192000, -362.386 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -47.90767236274726300, -114.97269661196380000, -156.98899932731405000, -184.16009609040648000, -197.04785054865144000, -207.08706851475856000, -310.96800704305303000, -438.35973894382840000, -451.17473420201100000, -454.76997093229318000, -567.67289075885424000, -625.74586564968786 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 69.48902149383953000, 74.07564864734368400, 75.32909950680155500, 108.52292262311013000, 130.80819888710690000, 148.15881911436946000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 38.28473977269037200, 63.76875249732128000, 76.69429772832927500, 86.18426636517898500, 177.51763557399295000, 268.39494223619312000, 277.18451820243433000, 279.62004331397372000, 363.45493174864981000, 406.16473887267136000, 440.6430538965 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -79.85953886628931300, -118.42609449825389000, -145.19939483626982000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 47.928587 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -178.63275144277003000, -490.46679442804390000, -549.51838065265974000, -565.71030900734945000, -616.83689751825079000, -674.12253482540007000, -683.57567652891237000, -771.71439745773728000, -859.32486929752406000, -875.29379938989973000, -891.97681889330863000, -896.27527869676715000, -897.34966597146058000, -895.50440693361691000, -895.42570139441966000, -897.44158861301048000, -911.51411180070693000, -912.12156739692114000, -912.43504069012033000, -908.7126663446 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -33.73692758059429800, -67.189 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -15.67495119080020900, -19.71629196089527600, -141.39075960986742000, -204.37045595536972000, -249.900918214452020 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -69.61951965930042300, -147.40499644209655000, -156.06630110806105000, -158.24780827334965000, -215.98154141505972000, -245.46421143654896000, -265.37845739 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.90847731556274900, -35.86553156782805000, -43.39046921758037500, -130.77552460477503000, -227.69899549989546000, -238.24657474728141000, -241.23005870741238000, -334.61603861392467000, -382.05425133709826000, -420.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq8[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1199.35934628215590000, 1179.24219849658680000, 1072.56275518777650000, 1000.88168496507660000, 973.74211221908672000, 909.60571373381538000, 889.66452665241536000, 851.81863692200477000, 859.64706514750037000, 931.27085332182196000, 1013.48295550283610000, 1065.29599781764570000, 1087.7125107559086000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1547.41163151953860000, 1512.68541993980310000, 1518.48720760193190000, 1386.17759476741230000, 1322.27421835071440000, 1466.04865046358550000, 1746.84056398180790000, 1716.38807238273030000, 1671.13051097883250000, 1742.15235282623230000, 1746.51142733976690000, 1767.34151956933560000, 1739.92164603127500000, 1764.37894303370920000, 1748.36524530674960000, 1729.47221413379880000, 170 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1145.66505040518650000, -1349.08727052745940000, -1531.65299803996160000, -1604.60841621883080000, -1769.67822837857900000, -1905.77705938215150000, -1900.38329281688860000, -1815.96337115582810000, -1958.90737147379100000, -1947.06798864546540000, -1822.65045466236120000, -1817.93112594366740000, -1767.96924701112880000, -1668.88235728006700000, -1566.8226013121 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1271.53778685557090000, -1335.05235852330040000, -1126.87754143944990000, -1146.28458343550730000, -1067.89602401481440000, -1059.00493043711370000, -1026.33450997962180000, -955.06529667923928000, -997.97213704931085000, -1005.58156158780670000, -955.56567274446456000, -899.44407604282799000, -965.58450026541266000, -1026.28301079660510000, -1234.11589474246510000, -1192.65235793727360000, -1107.7217255 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1512.05870245892880000, -1388.35530618553370000, -1392.10106315119150000, -1404.57310626511730000, -1411.91942235158650000, -1481.06784695005790000, -1598.59259806265300000, -1547.06453674402540000, -1425.68255687336860000, -1298.64550651360240000, -1250.28545236563830000, -1236.98488654776270000, -1117.81714874170120000, -1180.14523160150500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -2261.62778077767010000, -2219.40244183895580000, -2120.82622663048640000, -2021.19669445059890000, -1948.94950219296040000, -1737.35179457273970000, -1754.96632411814610000, -1651.82412449333560000, -1557.62722410375890000, -1535.35043194052720000, -1436.11367386855820000, -1369.77568305212090000, -1408.33930464620360000, -1418.33094415267330000, -1438.86648319442970000, -1330.41234430851910000, -1426.91838999766490000, -1436.64246520166630000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -689.01619439083174000, -637.85230293896586000, -559.33365348245718000, -254.29426561654077000, -255.71047260437868000, -203.49966251799088000, -185.05133237360974000, -274.9619 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 344.21233483974549000, 210.84887442594297000, 592.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1264.28429731273100000, -1415.10090808644420000, -1347.22665653363650000, -1398.79752146147780000, -1384.23279258696290000, -1451.82829730448160000, -1651.72724238832980000, -1589.56450076626110000, -1510.06338756293300000, -1507.21026555910020000, -1604.18852278481970000, -1573.71612890985060000, -1514.96744114906300000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 650.41552992381503000, 633.67138735777223000, 629.21840839306458000, 644.14883550461559000, 5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1662.19575617267740000, -1687.47238353412190000, -1394.70989541284350000, -1573.23553184169260000, -1857.94639224957380000, -1843.26570768532570000, -1883.46372353454130000, -1892.88169584751680000, -2052.64737635759780000, -2001.85259898678530000, -1868.25936135644180000, -1747.35256501517760000, -1701.75172036740420000, -1714.84142886764630000, -1626.45696612972320000, -1604.48090574106850000, -1487.37721712177310000, -142 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1498.06675356162150000, -1521.03470508003260000, -1514.12315016235610000, -1443.32937140050100000, -1378.60567286147100000, -1373.27500668159020000, -1296.90093443574280000, -1339.33850738629350000, -1292.80685846212670000, -1138.28827051356460000, -1153.70773 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-3262.79084166276930000, -3086.05322593435630000, -3173.69836218282940000, -3287.87653634703840000, -3298.61437236857590000, -3293.54124853110900000, -2924.82993555435410000, -2553.83234352287990000, -2243.79732081971450000, -2035.61519523484620000, -1811.69565179659750000, -1690.97114147184650000, -1726.53019920732660000, -1700.88907438953060000, -1463.36382570006370000, -1658.30779100067800000, -1670.78853794987320000, -1639.56134557139400000, -1664.46734066809840000, -1685.99789677631 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1082.22090622239810000, -937.67196532618482000, -1006.17251400307740000, -968.42419897675939000, -1104.36177288398380000, -1075.19525293042580000, -1079.81809578135610000, -1047.77410722138480000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1046.24477602354090000, -1036.84427778980720000, -1121.93994835746570000, -1133.22694217828280000, -1321.09297706668760000, -1372.35191123018400000, -1341.04370345262670000, -1458.92485910593840000, -1519.08159891403810000, -1596.90361594292610000, -1776.18361633277320000, -1732.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 626.18191288215496000, 456.29121130813729000, 473.52496430093311000, 463.82897954782305000, 555.43441746637563000, 542.3721382454335800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 917.53621097682424000, 953.90696786305477000, 1204.03546267487950000, 1187.69703840842450000, 1083.17256347567600000, 996.43441551972319000, 1009.64273009786000000, 1053.33687528990870000, 1260.82199724383170000, 1219.96231896471320000, 122 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -934.67453751783933000, -853.27768384494516000, -753.49993119163730000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1286.8097 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -2317.84017795685710000, -2132.98944046218140000, -1786.87246984292850000, -1463.54303438247670000, -1547.44190392747810000, -1608.42684513481410000, -1377.47490000441350000, -1417.39508683577810000, -1387.30276210584000000, -1208.06670674952970000, -1121.30054971426780000, -994.99417109468857000, -934.87723989167603000, -734.56446697963258000, -886.29024900528077000, -917.43097704164416000, -1024.25240418236560000, -962.74242118074289000, -1012.01913537837150000, -8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -800.25397565321668000, -931.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1321.90937761347530000, -1303.56812447055060000, -1443.79196772890210000, -1404.39283798282120000, -1284.37198689 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -759.96152284808545000, -770.56274204472243000, -877.83533213753503000, -851.26830100523375000, -833.96233266794263000, -807.23039896507237000, -717.8384209 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -894.94365524196246000, -991.51870397702180000, -916.81958655371761000, -997.27926493473376000, -1004.17571219649350000, -1117.20376961517350000, -1189.02228098693940000, -1334.21780718306740000, -1285.94741587207090000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso8[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 170.69269704813894000, 216.87429831800964000, 274.90306052058156000, 305.19494697136628000, 323.80225459617350000, 330.44265638987798000, 335.21942049271291000, 382.54469713223529000, 435.48997712791254000, 441.36885291719079000, 443.16411676041599000, 496.31969460164856000, 525.80954313007544000, 547. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 80.58605646497353800, 163.32058288994480000, 181.53418786163263000, 326.22336829039392000, 467.98122136497176000, 513.68284729893003000, 597.30979741746876000, 644.00399872501623000, 672.59144920956112000, 684.71550554973294000, 693.78515914064496000, 792.13287266715292000, 897.31143673774113000, 907.59295911021661000, 910.23125814702189000, 980.22803492798062000, 1016.205576680077900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -66.18678689789101100, -83.42912610601773300, -257.37464716748724000, -449.11281663817675000, -509.58166344063102000, -604.26506131629878000, -658.34635926835642000, -690.56568046451900000, -704.94302547440770000, -715.55301455177550000, -816.97340187307850000, -928.05226150065744000, -938.01183813666671000, -940.30527123186107000, -993.83554627799492000, -1021.48 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -22.52526631642935900, -90.87901279856242800, -150.73020038382757000, -164.11057290044664000, -272.66383891720415000, -384.57582103280794000, -413.96202750244805000, -450.65710347549367000, -473.49414618114025000, -488.30344421786418000, -493.60011649256535000, -497.06675640852927000, -539.98732448799444000, -593.95281071982060000, -601.54374340109337000, -603.39861101980750000, -646.48848856454572000, -6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -20.32225366120043100, -184.63609129521495000, -356.48238012945762000, -404.47457876674031000, -472.79474458322255000, -514.86553468623299000, -545.02831735557857000, -556.38694456201233000, -563.81229806918361000, -631.12983121201557000, -699.83912699532050000, -706.20849974198381000, -707.50010594740388000, -747.88338404800743000, -767.29521 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -360.86172937119795000, -445.51869995961027000, -475.19673909480633000, -555.70927833092833000, -636.19885402472551000, -650.99848405311150000, -783.59556720903424000, -907.16176490989164000, -936.94665542163420000, -977.52758200765322000, -996.66235726799800000, -1007.04701641049470000, -1011.59588342217610000, -1015.07013495055380000, -1053.89380866436390000, -1084.57978357280540000, -1088.63916997047520000, -1089.73118593447290000, -1122.25247 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -5.88544189463283640, -63.77946413620000500, -118.77239032333013000, -120.37938306918835000, -120.80404488194350000, -127.86964218409713000, -130.72101158904491000, -136.8018872 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 17.16417470548459400, 25.32949082603812100, 46.4403 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -151.85262108145093000, -331.63798550849924000, -378.14191118802438000, -447.35796899946388000, -486.44962379360754000, -513.31848045204424000, -526.22296482613592000, -535.30582075154450000, -624.60264900589129000, -722.54789203438918000, -733.00221975826753000, -735.64033561098847000, -802.22683259586302000, -837.7997763 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.04096958747768650, 56.00811202297454400, 84.59128779574112400, 108.18098936369655000, 125.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -75.71341122554790100, -104.26568899853154000, -171.46940361768756000, -252.45153358371132000, -274.02958059769423000, -462.50982946296830000, -664.73983943620271000, -720.97660068011794000, -811.28424261861858000, -860.96140975366723000, -888.99698275376522000, -898.72691155356370000, -905.58619278773108000, -979.72147348788258000, -1051.49137872542880000, -1058.04862386778720000, -1059.39583432256900000, -1090.7166174225326 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -101.59183369612394000, -160.81892501198479000, -198.48470139440917000, -212.59569485245498000, -222.55552457779461000, -327.97209528315057000, -435.49662696432461000, -446.21421290459023000, -448.87077592172426000, -507.77530471167870000, -539.9847755009157000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-345.62196817662834000, -556.82323233995305000, -974.36766335983850000, -1079.74854164926480000, -1119.05570520668950000, -1232.29849801453040000, -1330.07857565136670000, -1346.52597577484860000, -1454.29683542718410000, -1537.03000375305690000, -1549.60697634811570000, -1559.19362842466530000, -1566.17584557340110000, -1569.92524519696240000, -1568.71731337250960000, -1569.48257775190360000, -1578.76314272205490000, -1585.51007606150390000, -1586.44633636030130000, -1586.75872390003130 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -12.26756437635706100, -20.17218820837448600, -110.49895739595463000, -205.70513362981779000, -216.36123396176995000, -219.05620976225794000, -292.60057684613253000, -330.25736335947192000, -362.386 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -47.90767236274726300, -114.97269661196380000, -156.98899932731405000, -184.16009609040648000, -197.04785054865144000, -207.08706851475856000, -310.96800704305303000, -438.35973894382840000, -451.17473420201100000, -454.76997093229318000, -567.67289075885424000, -625.74586564968786 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 69.48902149383953000, 74.07564864734368400, 75.32909950680155500, 108.52292262311013000, 130.80819888710690000, 148.15881911436946000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 38.28473977269037200, 63.76875249732128000, 76.69429772832927500, 86.18426636517898500, 177.51763557399295000, 268.39494223619312000, 277.18451820243433000, 279.62004331397372000, 363.45493174864981000, 406.16473887267136000, 440.6430538965 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -79.85953886628931300, -118.42609449825389000, -145.19939483626982000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 47.928587 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -178.63275144277003000, -490.46679442804390000, -549.51838065265974000, -565.71030900734945000, -616.83689751825079000, -674.12253482540007000, -683.57567652891237000, -771.71439745773728000, -859.32486929752406000, -875.29379938989973000, -891.97681889330863000, -896.27527869676715000, -897.34966597146058000, -895.50440693361691000, -895.42570139441966000, -897.44158861301048000, -911.51411180070693000, -912.12156739692114000, -912.43504069012033000, -908.7126663446 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -33.73692758059429800, -67.189 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -15.67495119080020900, -19.71629196089527600, -141.39075960986742000, -204.37045595536972000, -249.900918214452020 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -69.61951965930042300, -147.40499644209655000, -156.06630110806105000, -158.24780827334965000, -215.98154141505972000, -245.46421143654896000, -265.37845739 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.90847731556274900, -35.86553156782805000, -43.39046921758037500, -130.77552460477503000, -227.69899549989546000, -238.24657474728141000, -241.23005870741238000, -334.61603861392467000, -382.05425133709826000, -420.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq8[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1199.35934628215590000, 1179.24219849658680000, 1072.56275518777650000, 1000.88168496507660000, 973.74211221908672000, 909.60571373381538000, 889.66452665241536000, 851.81863692200477000, 859.64706514750037000, 931.27085332182196000, 1013.48295550283610000, 1065.29599781764570000, 1087.7125107559086000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1547.41163151953860000, 1512.68541993980310000, 1518.48720760193190000, 1386.17759476741230000, 1322.27421835071440000, 1466.04865046358550000, 1746.84056398180790000, 1716.38807238273030000, 1671.13051097883250000, 1742.15235282623230000, 1746.51142733976690000, 1767.34151956933560000, 1739.92164603127500000, 1764.37894303370920000, 1748.36524530674960000, 1729.47221413379880000, 170 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1145.66505040518650000, -1349.08727052745940000, -1531.65299803996160000, -1604.60841621883080000, -1769.67822837857900000, -1905.77705938215150000, -1900.38329281688860000, -1815.96337115582810000, -1958.90737147379100000, -1947.06798864546540000, -1822.65045466236120000, -1817.93112594366740000, -1767.96924701112880000, -1668.88235728006700000, -1566.8226013121 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1271.53778685557090000, -1335.05235852330040000, -1126.87754143944990000, -1146.28458343550730000, -1067.89602401481440000, -1059.00493043711370000, -1026.33450997962180000, -955.06529667923928000, -997.97213704931085000, -1005.58156158780670000, -955.56567274446456000, -899.44407604282799000, -965.58450026541266000, -1026.28301079660510000, -1234.11589474246510000, -1192.65235793727360000, -1107.7217255 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1512.05870245892880000, -1388.35530618553370000, -1392.10106315119150000, -1404.57310626511730000, -1411.91942235158650000, -1481.06784695005790000, -1598.59259806265300000, -1547.06453674402540000, -1425.68255687336860000, -1298.64550651360240000, -1250.28545236563830000, -1236.98488654776270000, -1117.81714874170120000, -1180.14523160150500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -2261.62778077767010000, -2219.40244183895580000, -2120.82622663048640000, -2021.19669445059890000, -1948.94950219296040000, -1737.35179457273970000, -1754.96632411814610000, -1651.82412449333560000, -1557.62722410375890000, -1535.35043194052720000, -1436.11367386855820000, -1369.77568305212090000, -1408.33930464620360000, -1418.33094415267330000, -1438.86648319442970000, -1330.41234430851910000, -1426.91838999766490000, -1436.64246520166630000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -689.01619439083174000, -637.85230293896586000, -559.33365348245718000, -254.29426561654077000, -255.71047260437868000, -203.49966251799088000, -185.05133237360974000, -274.9619 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 344.21233483974549000, 210.84887442594297000, 592.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1264.28429731273100000, -1415.10090808644420000, -1347.22665653363650000, -1398.79752146147780000, -1384.23279258696290000, -1451.82829730448160000, -1651.72724238832980000, -1589.56450076626110000, -1510.06338756293300000, -1507.21026555910020000, -1604.18852278481970000, -1573.71612890985060000, -1514.96744114906300000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 650.41552992381503000, 633.67138735777223000, 629.21840839306458000, 644.14883550461559000, 5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1662.19575617267740000, -1687.47238353412190000, -1394.70989541284350000, -1573.23553184169260000, -1857.94639224957380000, -1843.26570768532570000, -1883.46372353454130000, -1892.88169584751680000, -2052.64737635759780000, -2001.85259898678530000, -1868.25936135644180000, -1747.35256501517760000, -1701.75172036740420000, -1714.84142886764630000, -1626.45696612972320000, -1604.48090574106850000, -1487.37721712177310000, -142 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1498.06675356162150000, -1521.03470508003260000, -1514.12315016235610000, -1443.32937140050100000, -1378.60567286147100000, -1373.27500668159020000, -1296.90093443574280000, -1339.33850738629350000, -1292.80685846212670000, -1138.28827051356460000, -1153.70773 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-3262.79084166276930000, -3086.05322593435630000, -3173.69836218282940000, -3287.87653634703840000, -3298.61437236857590000, -3293.54124853110900000, -2924.82993555435410000, -2553.83234352287990000, -2243.79732081971450000, -2035.61519523484620000, -1811.69565179659750000, -1690.97114147184650000, -1726.53019920732660000, -1700.88907438953060000, -1463.36382570006370000, -1658.30779100067800000, -1670.78853794987320000, -1639.56134557139400000, -1664.46734066809840000, -1685.99789677631 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1082.22090622239810000, -937.67196532618482000, -1006.17251400307740000, -968.42419897675939000, -1104.36177288398380000, -1075.19525293042580000, -1079.81809578135610000, -1047.77410722138480000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1046.24477602354090000, -1036.84427778980720000, -1121.93994835746570000, -1133.22694217828280000, -1321.09297706668760000, -1372.35191123018400000, -1341.04370345262670000, -1458.92485910593840000, -1519.08159891403810000, -1596.90361594292610000, -1776.18361633277320000, -1732.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 626.18191288215496000, 456.29121130813729000, 473.52496430093311000, 463.82897954782305000, 555.43441746637563000, 542.3721382454335800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 917.53621097682424000, 953.90696786305477000, 1204.03546267487950000, 1187.69703840842450000, 1083.17256347567600000, 996.43441551972319000, 1009.64273009786000000, 1053.33687528990870000, 1260.82199724383170000, 1219.96231896471320000, 122 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -934.67453751783933000, -853.27768384494516000, -753.49993119163730000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1286.8097 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -2317.84017795685710000, -2132.98944046218140000, -1786.87246984292850000, -1463.54303438247670000, -1547.44190392747810000, -1608.42684513481410000, -1377.47490000441350000, -1417.39508683577810000, -1387.30276210584000000, -1208.06670674952970000, -1121.30054971426780000, -994.99417109468857000, -934.87723989167603000, -734.56446697963258000, -886.29024900528077000, -917.43097704164416000, -1024.25240418236560000, -962.74242118074289000, -1012.01913537837150000, -8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -800.25397565321668000, -931.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1321.90937761347530000, -1303.56812447055060000, -1443.79196772890210000, -1404.39283798282120000, -1284.37198689 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -759.96152284808545000, -770.56274204472243000, -877.83533213753503000, -851.26830100523375000, -833.96233266794263000, -807.23039896507237000, -717.8384209 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -894.94365524196246000, -991.51870397702180000, -916.81958655371761000, -997.27926493473376000, -1004.17571219649350000, -1117.20376961517350000, -1189.02228098693940000, -1334.21780718306740000, -1285.94741587207090000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso8[1050] = {
+0.00000000000000000, 246.96489139372576000, 304.00778893841618000, 360.58679904721055000, 560.90117507875584000, 585.01445993697075000, 613.13691387862252000, 679.69900266322270000, 718.98893061795127000, 780.99843388992770000, 1030.73943437425710000, 1034.56455328474820000, 1089.22746728688710000, 1171.81441658905370000, 1255.84325709944600000, 1305.63592475560270000, 1596.25661706245000000, 1628.95291843923810000, 1657.47122805342950000, 1664.02403643477330000, 1666.17426238992310000, 
+232.13839819114961000, 496.67538145565214000, 557.44265878199951000, 618.40793421314390000, 785.13569690728866000, 807.56462629900159000, 834.78357578140640000, 895.72229329895777000, 934.47597249365720000, 985.53130053902407000, 1171.40232603581190000, 1174.03236372974150000, 1215.89385370281640000, 1281.72002462468280000, 1344.97974403399140000, 1393.59610951833410000, 1602.38827710210190000, 1629.73886488093670000, 1654.86877900390230000, 1661.23832590486290000, 1662.71278817803770000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 28.66802486969510600, 53.51757436354629500, 61.84199254191690900, 63.84132244654001200, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 529.85565601026656000, 590.91937199511233000, 643.51345567875239000, 659.26222197506672000, 664.44228793194429000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.29464942799269260, 85.46433128740119400, 199.55985388698144000, 318.76165830776114000, 398.51698707686432000, 778.58304605384365000, 824.72833361079483000, 866.87620875740561000, 877.18562966985610000, 880.62895972545630000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.74977815848247700, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 356.99190263631345000, 361.73345531321706000, 432.06171985245589000, 544.46528122052177000, 666.24799634897579000, 747.47089530311450000, 1103.11232963892390000, 1137.63720028540000000, 1168.22871694164270000, 1176.56915357149520000, 1179.06644182379390000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 89.83913368164586200, 418.80533555461199000, 424.45081602007036000, 502.59997504347081000, 653.73023844748843000, 810.38550636735340000, 928.03819212691633000, 1568.10769926922260000, 1640.96768114425530000, 1706.44593930303650000, 1725.79284020780870000, 1731.65405417518470000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 268.51604391566900000, 296.83296077434392000, 329.47658933075246000, 402.23751228847783000, 439.93698543783847000, 487.00971256087928000, 658.78908045902733000, 660.33729199645961000, 689.51641127957157000, 727.86896055256682000, 759.21718333523438000, 773.53493398913247000, 841.49824132180595000, 849.83057745138410000, 858.90828528444581000, 861.53470182788101000, 862.10655428688347000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 28.40360679592866000, 63.73713800069472800, 159.64579807407623000, 216.29253535413250000, 298.03440844593047000, 660.65868260015077000, 666.08972613892672000, 747.50622618195393000, 888.01753404327519000, 1038.52783222399530000, 1151.17909948276130000, 1682.43401760100050000, 1745.21391847196880000, 1801.19323558281440000, 1814.68357870872910000, 1819.15713589160050000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 50.26203712356647200, 141.40206256346079000, 242.15022069052972000, 304.27412560582729000, 764.73552533248949000, 810.03927666672587000, 849.54522837993636000, 859.48829254215048000, 862.04176427734478000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 25.88632178981952900, 90.53175777713980200, 128.65290134551182000, 198.37870411461128000, 511.64804900921263000, 516.91265603327747000, 590.89931511518398000, 722.71914028219214000, 860.59125460249834000, 961.93702322821241000, 1450.00901195995200000, 1504.01072735853200000, 1551.32404199024380000, 1566.98165830942660000, 1572.59053971781420000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 50.64182131143719100, 120.42507861014090000, 436.95264060413643000, 442.85381897551542000, 528.75276581282276000, 661.06715180605033000, 796.06013421638488000, 880.48958993183749000, 1315.55844754538320000, 1367.48518512326430000, 1411.66689843202400000, 1423.12855113005210000, 1426.37758000217830000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 72.35049660128950700, 121.78288850833006000, 214.23208482147362000, 632.96181418055517000, 639.57487097505691000, 721.53131527998596000, 863.05857605951041000, 1003.32328836656030000, 1104.33045056594100000, 1528.72503641021970000, 1571.06806671630580000, 1609.38679090936260000, 1621.89918514299710000, 1625.80364189091260000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 71.59748163507025300, 295.49965267590392000, 321.14694005979004000, 352.18530409139936000, 416.20982244480012000, 457.40728919132607000, 511.77814243780188000, 725.69605371767591000, 728.02009059581974000, 770.71593317054578000, 840.58172388750484000, 894.75305429492107000, 917.44620219546914000, 1146.15924754523800000, 1173.70381511965070000, 1197.73467966301130000, 1204.75456522762120000, 1207.23887728694830000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 60.57988334738920600, 135.49873413852868000, 335.63566024706495000, 353.54391414740525000, 371.44655758539477000, 410.67383025185558000, 428.63486415781642000, 440.12207419254599000, 554.71567728665968000, 555.37390774103642000, 572.75549275382991000, 594.90651473051196000, 619.37618949924706000, 632.05536286774259000, 784.16767933207313000, 798.89852149458125000, 810.85421572801295000, 816.39484209873012000, 817.03116117618697000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 101.70135187537214000, 223.85495922733870000, 318.78554132713407000, 845.93818185505256000, 905.75752256989745000, 960.08625992240491000, 976.10564412507949000, 980.26709462875158000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 13.46257897361127800, 17.33127470291795900, 18.30386247236972300, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 87.40545243644805900, 157.77715065216938000, 481.81967477295711000, 520.53146461688914000, 555.59503377805640000, 564.69191983032408000, 566.38942799572999000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 12.28101571906305400, 17.04140304169356700, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 75.27848508549810400, 306.55714416346137000, 329.03676251494466000, 353.19013866649692000, 360.25642981588749000, 361.48938141061745000};
+
+double nnlassolsq8[1050] = {
+0.00000000000000000, 1388.15139467635730000, 1300.45269186148610000, 1203.83743688478490000, 1398.39586165374340000, 1491.83318728970680000, 1475.10708244239590000, 1478.18191705412140000, 1484.56543455233370000, 1586.38949036598270000, 1577.94051823858440000, 1683.66348919968750000, 1676.34355876134620000, 1649.04806679608760000, 1646.22111151660920000, 1595.31381844447310000, 1668.38462389768780000, 1668.79581639311940000, 1667.51627709065270000, 1665.84454304366800000, 1666.1742623899 [...]
+1771.74700903935880000, 1719.05979900134050000, 1618.94630538256840000, 1527.03124335911210000, 1482.20805949644340000, 1651.04046654515080000, 1669.06078793920510000, 1626.74689981514850000, 1689.60350203909820000, 1648.64747505243190000, 1578.65955017429810000, 1620.33343527646120000, 1665.51412779444830000, 1662.10050960005110000, 1638.86923940294860000, 1676.43065153491060000, 1654.20758415517820000, 1663.06760947785350000, 1663.72032816938190000, 1663.00791865869270000, 1662.7127881 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 63.60216547048743500, 62.27037025487148000, 64.15468924033885400, 63.84132244654001200, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 661.35844775933674000, 665.33009437719238000, 662.03875247288886000, 663.63755716814251000, 664.44228793194429000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1074.45758534652330000, 935.79942638960222000, 858.86768863040936000, 872.54467339867381000, 862.50810737267500000, 872.91014672288168000, 880.95983092900076000, 881.72202109306306000, 880.04980145892057000, 880.62895972545630000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.74977815848247700, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1139.18768015998280000, 1166.34551292050970000, 1187.43410623573480000, 1193.99601629690550000, 1232.02130403924390000, 1219.99987187482110000, 1191.37757876159500000, 1179.70834717711070000, 1179.00401495517080000, 1178.88630052927010000, 1179.06644182379390000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1256.68664851174070000, 1139.59472083984250000, 1382.45380850408060000, 1341.97397541307100000, 1527.04554880194910000, 1538.16833666999920000, 1612.50407439331210000, 1726.96403334416500000, 1729.75303913674790000, 1729.50944913145920000, 1731.16781211436460000, 1731.65405417518470000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1391.15518991532890000, 1361.73600734490380000, 1330.02348568911910000, 1275.08202299887240000, 1174.52298129691390000, 1098.39911948051600000, 1035.17043601179220000, 923.05917987355053000, 1002.91958011717400000, 949.49147160246275000, 904.85351337807901000, 856.83105060663183000, 858.36578732111388000, 859.98415458851866000, 862.10574058815382000, 862.26437503008333000, 862.10655428688347000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1096.56676740889180000, 1146.73117229501420000, 1310.17198811812390000, 1320.07188399851020000, 1359.71318434231510000, 1455.19540451560260000, 1587.70410321318100000, 1621.97364452927830000, 1699.97057157075890000, 1737.76260583973500000, 1806.54832063487290000, 1814.28408671042330000, 1821.71594098306950000, 1820.91091846991230000, 1818.43147692087650000, 1819.15713589160050000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 590.10978077619666000, 668.06017729178336000, 710.20201775492296000, 665.69123319809171000, 879.01562948894559000, 865.24529891789791000, 863.46047187052136000, 862.25068279783227000, 862.04176427734478000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 819.31769171799863000, 866.02238722938398000, 871.45527687245567000, 1103.99050541450260000, 1198.04445462683930000, 1410.28378966218910000, 1385.56529468082610000, 1484.44792268260840000, 1501.11205490632600000, 1551.53445135770220000, 1571.14167963029740000, 1569.81587183544300000, 1567.98928519780750000, 1571.33167014095850000, 1572.59053971781420000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1037.41350888368920000, 1026.78311011436630000, 1130.48804192049170000, 1444.24715893174520000, 1451.36464718670640000, 1425.65378366501110000, 1423.20517768753620000, 1371.67329324012960000, 1423.53647652418750000, 1430.76181334342910000, 1427.22909278151560000, 1426.31283690056580000, 1426.37758000217830000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 940.27150747545954000, 1084.98846681613440000, 1414.97958254661940000, 1550.42975619708090000, 1761.76956057885010000, 1601.79809450019520000, 1680.88235858592410000, 1654.95952549986960000, 1691.95797427000120000, 1634.05385985233780000, 1622.66622811388740000, 1622.88385538374290000, 1625.37538879031850000, 1625.80364189091260000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1138.68264166604470000, 1231.61258812379310000, 1285.65429118421430000, 1303.52987493786100000, 1184.25188573901480000, 1260.15278160097570000, 1217.95697998822810000, 1194.40608804656110000, 1122.39472310536730000, 1229.29770972386130000, 1244.30539463920190000, 1146.42007251058930000, 1049.46771448710840000, 1202.92263891751670000, 1207.26893866081740000, 1206.19910886693560000, 1206.70483560336420000, 1207.23887728694830000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 1118.81006763785990000, 1252.08540814021260000, 1172.38844616271170000, 1027.01250652310430000, 920.17337260652516000, 881.24660785328263000, 778.61121332843243000, 589.32011219737922000, 805.79877415665931000, 667.07153009493595000, 759.44528861694675000, 722.90752654983135000, 733.05643400200506000, 705.81875832317121000, 821.91983701422123000, 816.84915861074762000, 815.06538870683153000, 817.93414346973054000, 817.03116117618697000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 689.38872617096740000, 791.35134329894663000, 871.06145591004895000, 976.77012282044655000, 978.65188026205021000, 979.22255650587329000, 980.55616260726492000, 980.26709462875158000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 18.20452433386912700, 18.40607892930989600, 18.30386247236972300, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 493.47023661352091000, 567.17729476994316000, 562.24251462365294000, 567.70468689024574000, 567.94552987719101000, 567.21922418820259000, 566.38942799572999000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 15.69293759734434500, 17.04140304169356700, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 513.22475360521264000, 363.95728511834875000, 356.42986516894058000, 361.69772032681027000, 362.21959262932546000, 361.48938141061745000};
+
+
+
+// Data from file x52.txt and y52.txt
+double x9[5000] = {
+2741.9959067895, 4706.80249046006, 18033.9990988959, 8390.84010248002, 11519.9250284480, 5961.19179074024, -28804.77586272, -2115.91424490938, -4108.20242324598, -882.173358865835, -9772.32006281111, 10929.7047807790, -1441.1807091154, -8912.98983984287, 7406.717777001, 9635.45952661707, -22258.9985057678, 188.496679022070, -359.504349661602, 4175.83080967843, -9452.54297976147, 8743.85344311446, 22252.6457256344, 17963.3272587470, -5364.55400313188, 4395.38015015015, 7431.9210444848, 36 [...]
+7571.93342186905, 8012.80081908227, 14530.0214154205, 9629.55512169033, 9327.24142065123, -6952.37502369753, 9928.25702821715, 26901.4198888358, 3649.38287315062, -6796.44370473733, 2572.38827871740, 9960.86313483467, -15828.1870483157, 1408.67242248349, 2882.66187745775, -23299.695888915, 8358.4364742494, -6101.4096539126, 5789.6907897112, -3215.82899964152, 9034.25680549344, 4345.45500326531, 18433.1383349364, 5146.00408289094, 14520.8636860886, 16366.6975876212, 6640.85304834348, 1272 [...]
+1755.36009025563, -10157.2442565939, 2494.44904298557, -11319.3134477336, 12600.6574545961, -7921.64101711448, 1360.56722370885, -7974.64953415392, 13768.2663243985, 9367.80244090174, -8975.19699787967, 9168.60503171077, -14932.4432968273, 5111.42481879825, 4824.8153390953, 11191.4803150124, -1062.65712853398, 3590.07837528920, 5132.08958456227, -4508.93514069978, 6005.06343177493, -17339.8533310937, -10851.7551567942, -2800.11248463897, 692.252772776494, -12079.3024963392, 1242.63022714 [...]
+-759.240037560824, -10526.9023422025, 11941.6049209504, -17349.4547878612, -14354.4008555892, 10988.8041011619, 5474.39731128494, 7196.86601443713, -6941.6375104383, 5192.96245581839, -7491.65660058538, 13950.6259151653, -13430.9572190066, 10206.7373925788, 3041.19424790471, -16267.4828356025, -7761.68910477599, 3878.40962401857, 9616.25558328926, 5583.64451464229, -4160.37813403232, -10465.2905474821, -21423.5572553497, 14344.1425639342, -3747.28660485728, 2682.10342542712, 5610.6523852 [...]
+5079.14048598601, -5626.55020850191, 1462.34722658831, -2990.45125939837, 7098.65358097105, 5373.03284073209, -8261.51466651096, 15443.4917024063, 28576.4926240179, 1488.95983281769, 3980.85712305022, 8784.87672486823, -17475.0947007896, 9456.75075770844, -5097.23625656636, 13497.6491812909, 3048.82098896731, 15460.4363173746, 8001.96307960948, -3390.53713855822, -5029.01780780177, -4429.22632377536, 19580.1410084348, 5259.16952684244, 426.959305480269, 4663.17799329367, -9104.1158224233 [...]
+-7742.75876981364, -7910.62311404664, 12334.2496626975, -4765.2417440187, -7009.37454212648, -4284.77430242935, -1399.55047880213, -8240.27607493914, -917.117451929018, -8163.5763900123, -7635.23453985592, -14249.3188633566, 24344.6330168153, -2207.27634296331, 8581.86449901769, 3742.10165120721, -6761.02792327756, -352.183052966495, -4235.41682646824, -10387.055178249, -8431.27566827206, -75.518536072203, -6592.36216038928, 1490.27467959205, 16168.5283409359, -1026.66284470755, 25654.08 [...]
+3548.09211074533, -7283.15695660248, -13761.7517064404, -350.450849649473, -988.767866401273, 4370.79604969716, 498.702990958169, 17090.9945250342, -7889.85131735254, -6788.88802073463, 9523.0931296196, 4478.85550823824, -5082.94042543335, 18082.1106429699, 3604.90339492984, -1411.16463863192, -701.73980125283, 394.391706641041, 4708.73444686506, 202.615471320836, -242.574985352096, 10553.5024525397, -9801.49019418251, 4715.55789882509, 16098.5869870167, -3576.93422121005, 14920.94608644 [...]
+-1358.30852578559, 9846.84782903674, 3318.86284562513, -16587.2674026244, 12633.0816514559, 1589.69668642916, 27173.8804449204, 3978.24534761512, -4167.82845437229, 1263.21875221979, 1587.43392063643, -4432.40907656386, 5289.64200563204, -833.647663181138, 15080.3878584718, -16528.6822932009, 7505.09128469861, -290.503061550739, 1867.78327405062, -7718.41455501088, -1957.26784748123, -628.768658837427, -3708.50802336873, -9766.43211602869, -11877.4030736676, 17749.5449218859, -14426.8496 [...]
+7372.21317107426, 2618.48799888838, -189.050434630670, -1085.68375206514, 20472.9519072220, 21173.7641321396, 10235.9328708629, -10510.4699761680, 8473.61418882997, 6570.16585547868, -10433.0791121383, 8004.14603724772, 11558.9086835485, -23369.0606226549, -2194.55992904097, 11866.9320533888, 19921.8215740590, 14659.1662647544, 7807.3751141121, 16472.8338732992, 20686.1967990782, -20975.2329344156, 12052.142576854, 8666.98298308912, -12795.6716155575, 6667.7786004625, 7040.55868496919, 7 [...]
+9118.22314314935, -1792.59513403438, 1088.70631192818, 229.683739703029, -9255.37022078928, 12200.0057826411, 17113.3564889980, -2997.77725231450, 23124.218593967, -7681.60871598037, -38.7375698358139, 5541.13322521488, -5766.83469915838, -3589.05568884468, -585.548722958865, 17100.9035002839, -1922.22075536937, 4093.88781494382, 8695.38294557426, -16519.663710574, -10924.8920956180, 11093.7397468739, 3638.40241468889, 16081.9513241123, 8763.91935592819, 13668.2240509562, 22448.600059232 [...]
+1469.55915770688, 5467.18356084376, 7860.1297613336, -1864.86481471576, 4957.39364684407, -19818.4138802564, 1047.10677287207, 8424.02083351032, 20241.2298259813, 8281.75750626974, 4451.47173407262, 1512.71183301457, 21114.9478176638, -295.777636971418, -12215.9915219611, 12774.2836612615, 7511.68496877998, 11188.8496503286, 3717.57781177444, 12778.4500862914, -4667.16572351175, -6571.0711088489, 563.811629712059, -2394.17288092265, 18215.9279108132, -10371.9328161672, -571.852887051582, [...]
+-7740.71232137215, 4630.32335504094, -96.6075520639782, 1815.24567195998, -848.638729164762, -14487.3202048552, 544.674564810433, -8322.91510820158, -6899.70002603568, 811.059994998175, -618.954918769715, 4352.04250085938, -190.784866862988, -1147.92757630145, 9106.3642041652, 204.155238577803, -6896.98735281432, 6886.53424682834, 9030.64568904853, 10052.7038644299, 8579.75424650339, -12132.9809387060, -3745.06478695571, -4655.08759271880, -603.816784141232, 4976.13339807382, 5323.563096 [...]
+7064.88492436856, 4645.31125490194, 7766.93697401914, -14534.5475387390, -7448.70936096408, -19351.5315557772, 14391.7832970032, 9277.31795659837, 3552.10247874089, 4343.69050543647, -4668.25505653603, 16811.2287634428, -2611.51909353668, 10253.7494656739, 6866.15993952142, 12480.5678548869, -113.339171884237, -10993.6523655203, 16319.5658046022, 1301.38972567219, -14816.6566505447, 639.520083747241, -17529.4998247697, -5577.58195133273, 7623.81184035811, 10528.8995753367, -4465.85722658 [...]
+-10596.0948435293, -1044.53372076607, 4327.56410051204, -7469.30172058816, -1023.99068254988, -3185.83812517746, -19143.9270413507, 18484.5709303701, 4215.52795709856, -3502.21467003492, -548.057660607047, 2373.88981517715, -13885.0641163408, 7444.05379824666, -9692.67221085034, 5352.18116540091, 16971.6311998771, -4099.82986740008, 4008.60257247568, 6773.39845534964, -1842.26579064756, -7239.55634823097, 2510.50595934515, 12415.5588607536, 3654.63965350317, -13218.0918645872, -7139.1158 [...]
+5418.95898919238, -153.618505909013, 11950.4912983127, -7919.77907589241, -881.713152590946, 7817.73499716987, -15934.5471284463, -15403.7471200833, 15245.6129885271, -6476.61760391645, 11775.9938285962, -9221.96184068276, 6466.39439829417, 2578.21196224283, 2340.32404278775, -10010.9964269239, 27346.1877843266, 19386.0926973375, -3260.18113581209, 4598.23161891407, 5871.88454076048, 3660.97559976345, 1936.00866460782, -1636.87432777658, 11873.0822454644, 8810.9515131359, 7039.0720096703 [...]
+-4121.5716198409, 13219.2264017217, -8899.00309756102, 11779.3863812074, 11163.7739356027, 3860.88867848258, 2599.20636468079, 8016.56948950581, -1120.54432876688, -2393.60099821884, 13088.2063432810, 13263.9306054884, -3123.41696456296, -9653.96979422389, 9278.7961090122, -8027.20160066623, 5484.85695932706, 20431.2208288679, 9451.83151194883, 3889.8423385633, 3719.34161083800, -2625.28038261759, 1407.64623759088, 2461.27648985421, 8124.77872435664, 4705.93868111448, -7947.40367824564,  [...]
+3597.75047079016, -12805.5677679265, -1860.03865652497, 6336.64722673794, -3579.84988786850, -1445.92490716893, -17966.4579677891, 9099.02279557508, 5115.3802244622, -13219.9371742473, -8031.2624569005, -3426.87727244596, 10639.1447396049, -2635.99340713256, 1472.28885651496, -2312.14539493246, 23029.4395347189, 10971.8299702611, 16108.3531226192, -3252.2632786917, -7708.256967838, -7466.43614783628, -9519.3136910244, 2201.71535115110, -1334.66646307595, -7169.10905966788, 3905.492751826 [...]
+-10012.5250616886, 8324.34226939249, -6723.79359368942, -13300.1542405082, -3017.73894475996, 1729.68474680875, -3803.73664418832, -9722.72917872408, -6940.30278790775, -3709.37201784176, -3574.64417831140, 1665.62296036144, 10764.4011526058, 629.620171262935, 22684.1293007658, -4557.43356929337, -15310.9837445563, 10127.8166738615, -3513.2659418516, 601.345043759583, 14469.9433207876, -5510.05246950351, -4472.78440699806, -1766.23121078609, 8069.6587074259, -13995.5360729087, 8674.08358 [...]
+2719.4156987057, -177.870287478523, -7447.39193602574, -896.309105935367, 8842.50748775685, 15096.1699165675, -6643.17556664683, 9381.85650914575, 5091.13917729138, -3824.2109684488, 542.475264455035, 25139.224068247, -6279.81336520065, 4945.89935002987, -7535.29925201537, 2183.96094535391, -6543.68457681972, 62.0145413673866, -2437.26178578518, -5200.28691419999, -9194.34033558151, 10924.5201238791, -5487.3593861558, 11737.9061034787, -5413.78483413416, -972.205836414765, 20025.52527844 [...]
+-6443.61684890321, 2682.71741639885, -3738.42447237865, 6139.28623569552, 12386.9867906769, 8335.01493078532, 2066.31319389186, -9814.95455210758, -11465.6679355169, 7037.76012803313, 6997.39372427726, 21108.4774309431, 18348.6288496789, 7275.51603325108, -8772.93179147242, 483.307680884243, -4092.79397713641, -8219.32998283239, 5011.12846056744, -8642.87763002791, 18587.2611760362, 1651.68899935735, 8397.01178989435, -9642.6306911955, -9946.07368022491, -7822.8146516415, -14225.18272475 [...]
+7374.89976136877, 6963.62001860997, 10472.9446757428, 6323.36781031162, -2877.24545936932, -11033.0039437772, 3866.33535954951, 9539.30181775359, -1730.79672945907, -18452.7958978455, -16733.6586458486, 3294.63024723931, -2772.01840383419, -21246.4195852499, -970.886509370094, -3318.24603815834, 18062.1541289456, -6010.33666256399, 4696.92562062231, 15509.6076272101, -10094.1654448451, 3886.35395847220, -11625.1323595993, -4654.00700081592, -1861.70609676891, 6834.50583071524, 8810.86397 [...]
+4155.86620888796, -21057.9457204298, -5778.34777322441, 15019.1896296241, -216.537431841425, -3825.65663026717, -6743.4881137886, 6942.5504755329, 6398.60651182115, 18826.6841811088, -1905.24780608393, 1266.85868580212, 5316.1304804528, 2162.12845555955, 10486.2705717174, 5372.76999775244, -2567.68615201043, -22527.7189183584, 8129.94526984169, -9111.34321841466, 21443.1963186653, 15046.3159508169, -3768.46739904629, -2253.55386020860, 19473.4072122866, 711.693152489282, -20483.502924793 [...]
+-8908.81033999861, -6702.09610703528, -22365.5446374654, 595.914723653185, 2312.26098629149, -11669.0142782790, 4313.13385425509, 6456.47593361386, -19881.1478095665, 793.529622319178, 2459.05996378972, -9677.0692157290, 3920.71053412255, 3823.29289139652, -2927.78764859709, -3300.46898135628, -517.919572959674, 25380.0401573752, -1048.53533082123, 1343.64118451627, -11173.7414677283, -15271.5695004403, 721.996787329835, 9567.2937965311, 1380.81898028518, 5945.68127593565, 7927.766447372 [...]
+-7463.84150396201, -4497.22576666569, 3616.63437082819, 3791.69245092691, 13207.5593767355, -5594.80945235484, -2938.45948434277, 3537.42753203268, -17163.0718976619, 1110.46715439454, -21632.3661443260, 16782.6512569639, 12633.6494307760, -1218.59747386514, 10132.3436940249, -4108.01705031539, 1485.15257527709, -4401.88228771468, -10676.3147557149, -238.653365658624, -1048.51346397485, 10416.0132818712, -3079.96413532877, -6039.84535072147, 9520.65146367706, -2792.06719342163, -4840.592 [...]
+22939.2224815016, -7381.9936456934, -5577.6141657466, -4576.45530029148, 1501.30476936193, 3845.78609286054, 4065.48411259295, 6683.23559774312, 14847.3897195502, -11165.2976579539, 20904.5955415874, 12837.6520679500, 1082.2921977794, -8838.1545269345, 5383.56593583594, 3511.42102303991, -10234.2676117722, 18455.0119830989, 18038.4017853321, -29061.3924377287, 12369.5869605314, -196.480608799524, 164.111216473514, 3272.88413957569, 4885.18973653029, 11621.9349310814, -5038.31814938086, - [...]
+717.411497622894, -5033.36928378613, -11161.8748057715, 14284.4150328306, 11004.5461165201, -2966.90160244938, -7345.48206560279, 29827.7910629523, -7468.58882184626, 12823.3349207805, 12496.5931617107, 1789.50641038331, -4398.30627313684, -20907.7716040842, 3264.94860307748, -19164.9538795000, 3825.0958874146, -3252.10969127885, 6702.99886429372, -865.279005715371, -10591.0242420655, 11953.4748246179, -22385.7234621047, 5173.10608876642, -1788.56889546077, -1208.69218577671, 447.5575440 [...]
+-206.989438293809, -15886.9578982579, 2506.09735128770, 6813.82554216184, -10434.7055689172, -432.796403443435, -7367.77541350442, 8874.87447363729, 9246.29856503503, -7942.7415690613, 10229.1987596446, 351.283701408919, -1556.88156780782, 6349.55237147873, -4383.05081674626, 11011.1392375218, 2946.40963130635, 4585.87588784128, 12795.4452216146, 4941.16083131166, -3998.20466929266, -2774.00703247955, -1811.17908133503, 4786.81183409755, -7200.4978394087, 10989.5317022394, -3528.63018214 [...]
+-11009.5326020799, 17574.4869824376, -16644.2741902299, -21072.3368652015, 2886.69688794714, 7957.75146877019, -9111.67023541795, -281.112273402012, 7810.21520943333, 2479.59629661371, -14207.1751193017, -2928.09934533069, 9429.08457968596, 6324.06642589609, 1575.81823595330, -17007.9137657715, -19147.5799339447, 7831.50301572295, -20007.6655713549, -2324.12293700880, -244.302755890662, -9561.52066573686, 6442.23572440645, -19097.5361166959, -936.494676654985, -5238.67197326604, 10099.32 [...]
+-1639.12559848368, 1016.07914773577, -200.952593305208, 7120.63027743139, -3459.0349159072, 16398.1517129490, -21746.0176459737, 15149.1495688891, -5300.77941657342, -13085.2876246087, 10244.5159502217, 2918.57806613718, -10257.6714558272, 5014.02354865719, 6781.71653235534, 3820.06231904059, -12680.0596621651, -9953.79284070765, 8146.48376315984, 8862.9977927424, 5539.33970995022, -14606.7167843590, 3465.36073063159, -587.717520432573, -5772.87896312817, 23115.7614795074, 5290.840701471 [...]
+-19839.912368587, -4849.32196524619, -1872.54194776294, -4008.1222810858, -9231.06351892871, -7825.2900028419, -1322.40365269154, 9901.1536505533, -18574.2296462432, 4737.64918933575, 5205.84178809274, -12680.7964903550, 11106.2954885911, -13392.8823540288, 593.021910051689, -2406.4606558148, 1427.82251301516, -14074.6068182317, 5352.58895276703, -621.004386704307, -8572.62369141856, 13235.9024637671, -9453.40577175173, -2286.2756851793, -16249.3708263205, -6495.58316316828, 3234.1241697 [...]
+-5220.70971625756, 919.8065673207, -2164.69596318397, 6076.6420145171, -11215.4397959504, -4551.11453234598, 10694.8644175406, -4570.21539070224, 11949.8265287202, -5252.83669411536, -1928.48165493224, -2990.26292501614, 5763.39349201762, 10227.8105623117, -6200.00140110802, 844.269206561896, -9515.14888768754, 4238.26794799586, 13595.1648836709, -10745.0773840222, 87.5629544767656, 10439.2765949585, 2441.59499095145, 840.88352877301, 3438.09163886869, -10780.2607286386, 2344.77509748349 [...]
+15285.5421179939, -6585.55317331184, -6249.98291003505, -4450.32806767844, 11465.6666576105, 5713.58651822904, 12666.1664777098, -7294.30589422487, -5364.28236805889, -22332.2308788028, -3030.44010786646, -14810.5813702299, 12769.4629685594, -2732.50998657264, 1525.77343064101, 7296.17004516712, 7842.28609724155, -12189.9168567250, -2292.65238016401, -2358.14662352785, 5723.66274937398, -14837.1088223483, 5472.48758694308, 10856.3850336429, -9134.26227055372, 3356.73578524219, -6368.3584 [...]
+-3735.32972738246, -6178.64324900861, -10178.0407159681, 1633.09903284034, -6866.67362245845, 3153.51091045089, 4746.50900133614, -9434.54025227739, 9917.60378169353, -6215.23365160305, -13246.5843392255, 4169.22142518239, 9119.13413803151, -13489.7816178540, 18822.0163229924, -9788.20690825875, 10133.3551626697, -6918.19735400196, 14329.1859096212, -8596.04007605627, 8651.33403355032, 11782.5325720690, 11041.2659494601, 9058.740990825, -7763.27484095587, -7464.26982331916, -9216.2322919 [...]
+-3779.93137702780, 8976.48449248981, 12015.1338401365, 13288.0385695651, 1288.95290591184, 7965.37397323926, -12032.5323940234, 9654.93716101367, 20274.4207911937, -3261.44064622703, -13815.1311275009, 826.868888850005, 6610.50140698614, 10975.6157774154, -454.33435395048, 7386.72616783198, -10618.4131397794, 2930.68700646720, 10597.7411364947, -4134.89864009944, 10406.0386147985, 3307.58771176638, -181.770681413098, -4702.2602628578, -14917.6665122256, -15423.4465678273, 7419.1467672922 [...]
+-7939.07451488825, 13370.8017505048, 15945.2169840816, 7982.12927726173, 24197.041617480, 7212.90049917624, -5181.63895332445, -14986.7368257184, 5572.77745873666, 14.4759384667037, 24274.1962218819, 8659.68767910615, 7010.1301870365, 5060.84030472407, -2625.84766859489, 1612.96712619428, 3524.66462760169, -11716.1759714689, 2810.62449229924, -13395.3300656054, -6996.35928055414, -7931.7724589996, 5481.3637618301, -3064.40728274834, 7102.93047571238, -6097.45434980243, 2688.19425168358,  [...]
+3755.01213398384, -3124.76235072131, -5653.82814359894, -18503.7734098484, -14413.3823099288, 3364.17986916874, -293.917420944552, -1359.04425926737, 20787.6126331998, -16184.6888650495, 9342.79698548395, 7867.85856947699, 12961.9364168067, -6167.02147255063, -187.74340552017, -12740.6420907797, 12126.0416618575, 6891.6108443939, 4537.58675625490, -16725.1127198630, -2235.00223962435, -24778.002399519, -6339.99087150922, 13176.0100799637, -7877.84701261478, 920.703881887708, 5685.0809272 [...]
+-4950.90716116821, 8482.51803306089, -2595.43304496322, -5019.51908782417, 14467.8812974585, 211.542472156755, 10658.5396533697, 16119.6619908383, 5975.08570485786, -8001.18467515582, 3115.64618567138, -11081.3417673542, 17401.1141369444, -82.7419416252505, 4193.60696218251, 2218.25265437100, -3057.93608634209, 1087.09764518058, -1423.79357831568, 27490.6048705217, -4442.13813247129, -6602.41466531129, -14456.9603397800, -4357.55895223881, 7736.27932058265, -18864.805481954, -1118.286675 [...]
+5946.04793477778, 14306.8645611753, 5607.7034589673, -7739.85771975788, 1182.87320746549, 3474.00444677071, -15783.2020819342, -6190.60036620516, -1641.61021744402, -6649.79552301327, -16163.4788794776, 1583.24017698134, 15241.1558559536, -4149.83145922658, -3655.58899741742, 829.00082752163, 1219.94963098130, 6258.27170178629, -12079.7296554028, -170.356807750535, 21634.7452926230, 9585.03500590387, 1396.34453171599, -9617.7585403288, 4324.73040419412, -3985.76304689654, 9704.8185934420 [...]
+4719.10333004476, 1477.23201398895, 916.875435478891, -7297.48975405024, -275.314770567107, -8266.67635548525, -5222.02306814302, 1780.24091809973, -5301.51515173165, -12499.7499018062, 11747.6634646797, -8016.60352921887, 8124.95070613057, -1351.63248242431, -10282.0446653475, -18571.8058148229, 10025.8925898125, -1157.30585375465, 3385.32822376979, 5613.03139892463, 5611.65889982365, 9475.873713588, -2665.97181670574, 5810.02119305619, -3695.17508746958, 3600.15377990638, 7911.21966768 [...]
+-581.296861311781, -1513.08370988429, 22105.6041726177, -14453.3336291684, 5209.8318418057, 6569.57205579455, -9210.4269455256, -13728.6190136137, 78.4601736718287, 10016.6781578812, -23197.2012792395, 12260.0838716649, -13708.3494407952, -12327.0305373419, 17233.0028856517, 5510.21355846226, -8295.93435469917, 679.034058171404, -20654.3615241698, -95.0128869568531, -2050.74205672989, 8659.23970972483, 10026.3765324383, 3035.78336236245, 1738.96585082258, -500.915121198391, -1405.6694452 [...]
+-7326.52329642312, 7178.95337955648, 23604.3158190893, -5483.57754426584, -14246.6170385861, -14738.1647408723, 6656.25156178781, 6318.72599117007, 5881.13819468354, 3557.69595550739, -744.075287477156, 8296.42508984403, -7142.41790725466, -20841.7159587219, -3409.88763669148, -5202.5138658853, -5359.82966137161, 11941.7675201080, -2322.89045595539, 5782.54090608711, 1450.21888915737, 2020.38201616355, 14818.5108141428, -21307.480821715, -9679.58835376131, -5689.72397316665, -2280.478116 [...]
+-6768.61498459494, 10750.6085361704, -4846.15876302584, 15416.8154797105, 14751.0427078399, 24411.6448792102, 3389.41004900232, -733.371622283701, -1732.08965629067, -3065.46702656919, -24242.5355348733, 6304.79429477211, 22123.9713102183, -2465.4634188938, 16058.8013233803, -7486.27245377146, -594.94078835369, 123.102004488770, 2381.57603234005, -13787.3562700876, 11195.1451400805, 17846.3228036003, -9718.66108616956, -5657.00720077289, -5660.52668209304, -11010.9846186108, -8693.130521 [...]
+-9827.82104595253, -21003.9684147275, -1724.92500335245, -6640.96038298543, 10897.0626631724, 7936.10602217007, -929.461908857053, -288.871787631328, -2182.66939558564, -7646.42319277353, 16383.2605850187, 1656.68722194467, 15242.8462310606, -21913.0039682230, 6617.62395991232, -1667.56628753566, 13888.8734044477, 5361.31727728214, -7538.4758460631, 13705.6164291460, -6600.47071829702, 3260.16866162768, -5055.38708878136, -1969.59530849168, -3732.62500763155, -5350.36829266703, 9821.2457 [...]
+5916.7132403003, 16070.9594561255, 2006.65721448568, -5566.73435677605, -7334.20295007226, 3631.91452995787, 383.139178321458, -14589.3535364920, 6948.09462875203, -8462.00567562134, -484.34261389014, -3960.30321746636, 13672.1290922075, -9472.07316814761, -11876.6068840203, 6127.4341231184, 10983.5031577643, 2674.94748814557, -6098.58837332748, 6280.40448876688, 3974.52087537353, -24731.0619245463, 11601.4601471410, 18758.7842446294, -7791.29635727468, 5360.49429454935, 1569.31225291866 [...]
+1602.39335302986, -5537.06960600712, 5283.48051137318, -6292.14653484987, -6981.37536663441, 18683.8613568398, 10762.6178115594, -17051.5662868360, 1321.1804772217, 12975.9150024429, 24474.4080047092, 18910.2501558237, -1869.56581313953, 10636.6681257160, -12698.6784487957, -13981.9640509391, -2357.46012477649, -1212.55396554109, 15875.503472093, 8700.72875913474, -250.979799011063, 11965.1521104823, 10289.0258468531, -4871.83785080303, 7343.02448088044, -6466.30540193977, 14557.18620411 [...]
+1563.86293440172, -10529.1489985950, 3881.71374048211, -801.273363932337, -857.486245699435, -892.108253118359, 11530.5275325512, 5316.81594142217, 10257.5225931192, 1035.02378746415, 3241.04514693276, 6680.83898059933, -604.173987498744, 209.320653917354, -5858.87389773207, 5739.57032843254, 5264.11816377997, -2897.00690454434, -1319.48342692522, 10151.2940896897, -3394.02485226136, 11146.2178819183, 12421.0363413655, 17936.9793512319, -7591.64510104621, 9686.0921334802, 7916.9049288615 [...]
+-19297.6470305364, -5454.89790403606, -752.434279775435, 6927.98164184498, 8750.25148373682, -13819.2533274118, 11675.2411451242, -4889.28600306629, 5209.625962293, 6150.52117670763, -14750.3434521916, 16670.8406763647, 7430.9609156373, 29165.4177557796, -21717.5941977742, -5087.24934466207, 8264.54512962816, -24788.4829294676, -14972.6992726847, 5282.64773383888, 2911.33553483371, 1255.52933507541, -5885.36159440938, 16002.5572411848, 11087.0535963426, -9631.2099858483, 534.24209315745, [...]
+-8570.50276138687, 6143.21286712785, 7533.85167988908, -3243.8070972609, -15272.3707701947, -3835.92104501288, -5430.42409203037, -14584.7028562892, 15511.2847319255, -4234.50820227619, 21287.3489166026, -12534.8499266811, 10233.7599221050, -3067.99300670744, 12445.9214931349, 2562.43860389968, 11958.6915486278, 19257.46416799, -4862.89531981874, 4047.01021011434, 7766.84072186732, 13901.8284590643, -939.897622632822, 2935.88975878889, -7096.56003004464, 10928.7693593907, 5129.3222093988 [...]
+-14028.4638656242, -1348.85358147399, 9743.8375979624, 2669.60227439741, 6686.3275693087, 6890.50906896957, 4311.90691540842, 5667.27191475093, -11583.8734951209, 14969.8105476853, 13646.7986324147, 12335.3051822689, -10525.0246357494, 18884.7939706556, -9075.48762677425, -13448.6381649334, 4335.43630665247, 2562.60236496907, 798.405489019331, 876.975284235163, 8553.42665959593, 3423.76236238890, -2181.5008628016, 12705.8388955426, -18171.4865543301, 13654.0543516627, 5197.03757549473, - [...]
+-1339.61999338159, 2949.29865829433, 8715.62153524741, -11031.5696910829, 9260.95042760038, -8452.24630355372, -12839.5707342177, -1898.80300498168, -12407.5734678538, -5935.8158003514, -2895.53791377626, -10485.4692583180, 20499.2782133881, -1738.18979147867, 13491.6863978074, -8482.13635821363, 9271.9001535727, 9289.60077753882, 8326.91808170502, 10512.9423489577, -8020.83854933137, 12328.3217979729, -3622.79183173394, 16813.4744294237, 560.437064789145, 4796.625888515, 6622.2009352223 [...]
+-3248.03738878253, 6223.97609020128, 14544.1397230860, 9722.29447879899, 7815.25674149575, 5569.32188419983, 3261.89175697559, 10471.8930673667, -9206.69194784359, -8644.73523864233, -2041.76120691065, 3305.84690351474, 12884.3270286016, 11214.3483014056, -6642.3101725081, -2927.98810667506, 1728.73032457819, 14282.3979915132, 1061.40494916495, -3018.16736654522, -5137.01913980793, -6369.19746354544, 11130.6391796381, -841.354140568783, -12849.0165271471, 9424.76535851324, -192.373585621 [...]
+5587.75463325858, 2067.54887653347, 9919.88537880416, 5281.29555160166, -20320.440168683, 2524.27905899175, -6255.82038231123, 4784.23785179199, 2416.24363581295, 8112.69331892059, 6974.46256848165, -9418.80501980747, 2173.54632365133, 21376.9530131218, -2028.50260950687, -14445.1998322044, -3812.70212909424, -1121.52655451050, 2958.93054256716, -1880.55611050395, 4380.63758553354, 1431.69119828774, 13206.6269003900, -10669.845537487, -13662.3905467014, 11204.0601833602, 3669.53620786017 [...]
+13763.2212182444, -2569.04367617236, 9347.62221537358, 9008.68382204714, 9612.43258886142, -10425.3803921257, 852.967546450359, 2208.76981008233, -13896.8978699242, 7715.34242512749, 504.695786568489, 9134.38326665377, -14473.9008645083, -5777.66155504651, -4007.71154513984, -1899.45032263474, -4490.13479696381, -8730.03154331734, 11112.2445648035, 18327.3935051731, -10503.8151792185, -3157.38274527204, 4073.98684045348, 11427.0104205293, 6952.52202878972, 10124.7812829999, 5210.58872426 [...]
+-10992.2542670531, 1763.09314623801, 6689.97086568642, -4637.18999510906, -2515.73359357726, -3287.94366746161, -18648.823817626, -790.380610805664, -2044.90857816277, -5051.69577989814, -10636.6333561060, 7224.5600782667, 23314.7756483997, -8430.13481253977, 2517.81479123535, -131.237632179939, -5676.62989185197, 2421.14539057526, -21726.5697510713, -5478.1100438956, 10593.3977794927, -4173.95952808982, 3896.15550509798, -1674.03187801878, 14047.3278579356, -18429.5052969357, 22085.8100 [...]
+635.205429541899, 760.477585051727, 687.353228690443, -8114.06308385685, 1534.00551958709, -21385.5783641965, 4391.22588954046, 6530.35704510936, -13684.0496535391, 10292.2146166088, -10418.7376764129, 4894.94581851344, 13851.5769240633, -6575.7325494581, 6830.78474415934, -641.9580436617, 3466.32943025768, 3582.99439822646, -21155.6585655853, -8483.2786126904, -6339.8256960848, -7543.09811979015, -6443.968773518, 1499.31584818912, 3220.8859120386, 828.293098799122, 4969.73551531383, 102 [...]
+10956.2499307240, 14784.4287673067, 664.04644608647, -14554.7872321953, 18877.8946846306, 7895.47055519536, 5044.31933239988, -7818.3570661679, -1187.56214162420, -5920.96495179779, 9870.07547168895, 11165.5839870674, -14952.4648209502, 19363.0749922851, 4372.66506434328, 19544.1083538675, 2545.60599238292, -11815.0454797093, -14316.4633257338, 12973.0519040052, 7578.53326552161, -5018.62657567597, -9175.69819256316, -1858.86741236087, -14473.8157407680, 6556.6639316215, 8154.58691779376 [...]
+6220.86953273968, -14361.79461604, 744.818853095303, -6068.00297050815, -9831.76128090014, 27770.4731976389, -16242.3223065876, 6750.34232059723, -8322.88022459792, -8877.8705844899, -13890.5439621725, -825.965372610424, 10880.0112357562, 7366.11226212936, 5812.06141990555, 14329.0458169988, -18578.8528290891, 4634.34315887604, -8964.41060514295, -6107.14903669536, -20887.1584591695, 2842.93213037767, -3390.85023166812, -15384.6381119941, 5036.82762154841, -13982.9596484061, 316.97972773 [...]
+3627.06528986836, 6577.31868454851, 7991.2760606399, 1225.23001049852, 20007.4230933804, 2285.41888644148, -7751.48853266889, -11353.7490520386, -4284.50510580186, 551.970412107581, -11708.0193439646, 3773.76984152366, 2492.31873344319, 4896.50643083242, -9322.90981763947, 12160.8454053448, 1648.78827726413, -590.384594267531, 13945.2693368632, 1855.01802492252, -4134.13397118071, 8293.50956216602, 5562.36379494552, -40.0877009574283, -9729.3706435111, -2206.48198391974, 6439.68042575648 [...]
+8156.59662561019, 17474.1971230627, 9330.55423387876, -11185.1850630473, -19496.9128183786, -4555.0829605839, -11690.4893181669, 2917.07992998798, -5452.87814541658, 1748.55621941327, 3067.26847603668, 4088.13281831774, 12418.7398181981, -10944.5911964907, -1079.04476037323, -15722.4980215364, 3884.15848675356, 10680.7859988603, 11018.2730371758, -5242.49312082722, 1248.37756173628, 13711.4492565637, 1278.08644402829, -269.589138147214, -12643.4622714532, 12.9609251715203, -12515.5652998 [...]
+2553.5862997957, 1624.77677866568, 5413.20810892204, 2388.94043754720, 295.542248024945, -998.732470104908, 7983.23061985123, 14264.2774113513, 753.58300081006, -8051.60265824814, -3820.12512810366, 6610.63072115913, -14011.1573564845, -1038.55689895666, -2522.56494810095, -5757.53581432009, -6906.62081862454, 2027.91393491592, 17416.4101757344, -22317.653771507, 6149.43080306163, -7475.58720086161, 4217.8097710114, 388.865770676962, 25593.8611028981, 13298.5717420967, -12126.1132253042, [...]
+11373.2276758606, -3883.62367137397, 23496.6082768923, 4205.07230442737, -6111.73638653002, -881.530204736892, 1077.42297121367, -13189.6354035118, 20609.2310537349, -5960.08058837335, -14196.2923561134, 4235.21000130437, -7240.70087828927, -4874.70276070378, 3613.3529641628, 8907.30997993069, -13704.2104666286, 908.54688560574, -13182.7574080749, -5233.53292208354, -8421.13774478311, 3753.85514289337, -13209.7017784958, 12524.6546856893, 3267.02097510767, -14447.5840461344, 3262.2776402 [...]
+-7353.73307965912, 14206.5764799422, 6950.18608304227, 8529.92489223246, -4579.3381293213, 8842.79852895432, 14461.5675158829, 5554.58896297708, 3008.10319925908, 5558.66785131077, -5767.92532157191, 4558.4370858945, -1569.46783932173, 7650.99797635945, 14345.9273555383, -10083.5938646169, -16335.6022136539, -12079.2013214712, 4790.35184802241, 18873.3450360841, -1594.82953103699, -2982.5338099918, -3980.10014625022, -1825.68757606991, 13028.3269288251, -1910.87147100715, 304.98461507545 [...]
+3647.71637890861, 7989.43217655485, -8651.17533624456, 4269.33255658886, -7862.05119802668, 7287.52750227928, -14541.9472088141, -2040.55029581851, -9669.64759620158, 8330.14507768595, -14718.2720639074, -6852.430560571, -2.07033063208425, -4662.91325957695, 2816.77168758363, 1342.13148056654, 4501.76480619775, -17358.6861207212, -1955.75018894374, 6238.04331908794, -1224.34359375008, -17.9864212193903, -17659.6791902934, -7079.25485045205, 15759.2982859991, -5852.50201244674, -6130.1649 [...]
+8923.57243764318, 7786.59452821693, 5945.32886830034, 3769.33267845198, 6548.35980537142, -654.928299257367, -1769.87417987698, 486.418632206836, 480.371125019301, 209.874984417896, -2101.27100344704, 6308.76687011258, 7390.60222650326, -11381.3684251356, -17613.3848665621, 1927.67972481168, 10513.1597336234, -951.045683649375, -11353.9592946754, -7300.55995495068, -11002.7201908167, 4143.98372486682, 5337.62947760271, -7034.57910193843, -8277.53363654789, 16668.4087408739, -845.52564548 [...]
+1940.4848599137, -8234.10003596326, -22913.9842728427, 6261.5709806097, 9924.14494572628, -16573.7740358288, -2162.54103784880, 10160.0171244174, -5937.0619221488, 5153.78064542652, 22561.7455615827, -8668.55264773058, 7115.74810187597, 6905.19896398596, 1200.79078014376, 3807.23368462618, 18032.2771070705, -2704.48020766477, 2400.29048847607, 11077.7658590327, 20817.2955704705, -17888.4154960053, 3433.34064161947, -21155.0261699772, -8175.98368422348, 22930.3622642836, -19608.8465352171 [...]
+-25306.9712886115, -7932.62484891777, 3662.27773613432, -16716.0876387887, 6019.1885520401, -7289.15971340994, -38.1630276443531, 1048.36029200613, -17778.0273165091, 4998.56048908588, -1035.70849982215, -7568.36548727498, -11402.5896400594, -6496.50350098556, -16961.6191863437, 16632.4677111214, 5980.87188858129, -1206.72219068477, -16758.4499954568, 1287.22731095229, 9211.56698051424, 1927.80371101543, 6454.10615701744, 8426.14290965588, 847.818440305578, -815.788173762913, -8609.24293 [...]
+-2782.12457196173, -13621.4040747582, -4615.02501659065, -11216.7255267303, 1965.91931648861, 1138.68788357875, 6757.08621866035, 3096.98261514341, 1739.53842128691, -7037.44397362266, -22852.9681227174, 16200.2081845944, -4673.67645673535, -20248.9728099387, -5306.02193878098, 27356.2211709733, -887.54487466073, -4744.57735357268, -8806.93400434333, 6985.2961710731, 991.00670912232, 9005.79987845177, -6567.24441417085, 14773.528799615, -3918.09869023519, -15161.3725136185, 3050.17378876 [...]
+3152.64435926967, 10578.6620323501, -2746.94390593528, -15545.6400473607, -12969.8469477584, 525.096681083919, -5573.42885814561, 9232.97879209643, -18282.9253536653, 1950.93781721015, 9920.04375813868, -18442.6486145417, -17591.2418741578, 5193.53296034535, 8639.37513429367, -5400.36948352477, 3925.62286312143, 11225.3050783559, -2720.78559224142, 2557.29054831812, -8467.04588088474, -1610.88130206933, -3466.21656985541, 4410.69396677032, -5828.30089743014, 13062.7442542222, 11198.26096 [...]
+-10376.1738871908, 2907.14406597884, 5377.46936152352, -3516.81650759827, 672.226863703947, 12137.8201033098, -5646.63577170042, 9583.32140707958, 6573.37951597593, 12924.8665866214, -9579.7340473221, -4450.78632945122, -2023.96465159288, -5028.03954224293, -15751.5495932596, -2019.52335293726, 5839.43670049869, 4081.21393860792, 3007.74944288359, -4230.59386595525, -5721.87427726505, 5194.5383601389, 12352.0824357219, -17010.8251034653, -2474.54820100035, -1523.93445398792, 5009.2349063 [...]
+-5643.38280588185, -7927.56010050765, 8845.39767977994, 4030.93325497052, -3424.58716641645, -8301.28322202977, 4504.16065816164, -1804.64493325037, 1118.47746404733, 9974.1120026828, 2562.19479768591, 8817.37614701122, -9523.3837162639, 10297.3178680172, 10820.5455787459, 23636.2470646359, 8622.59484557001, -9880.5367391696, -693.494412649186, 5422.10725528728, -4927.350727376, -14800.4471629810, -3189.46560935610, 2639.60430831748, -3567.05862191487, -14542.7872134103, 10242.4381178283 [...]
+4341.55658569682, -9383.60624582705, 1487.62577352929, -8522.93959150445, 23683.1292352185, 7642.85218610759, 13578.2057218629, 3436.16473283979, 1965.02788795385, 1984.19495252378, -17650.9750286447, -1405.22744326377, 9964.2346717993, 23630.1008721627, -4767.37674982786, -16656.8429205526, -21156.7931384803, -8701.48239898049, -435.857373406926, -12567.3175971955, -4920.38505394397, 14155.2413094714, -10463.2911206029, 3005.62331241333, -21692.5673781605, -402.974098618897, 14008.12379 [...]
+-4550.11397410343, -13665.1742156005, -9816.20647520807, 14031.0706485731, 5057.57330055974, 9535.15268189002, 1363.48717631794, -14957.2402560721, -5592.94279810044, 8910.44790664259, 6757.18238820858, 17082.5794755554, -2731.16979095224, -3775.90086295983, 13711.2386921847, -6112.3319920862, -7774.51780419767, -11513.0696431002, -2754.63474555715, -18885.9139115212, 5515.65106245401, 9709.78418021315, -10574.9733325831, -3491.84107072241, -14861.7867555935, 13949.0663045058, 5895.89644 [...]
+-2985.18707775198, 2316.26547850048, 2634.82150069276, 6124.69888870666, 7349.31896224672, -1978.19745119086, 9721.34385021194, 10316.6072845219, 3476.80058799955, -6815.08095451028, 12112.7484435571, -2895.73999924039, -591.568332881575, 18773.7170193485, 5620.9031297887, -5555.54702192748, -7074.91263819148, 4505.86854230403, -6249.43461765836, 876.916093643425, 7263.52255907831, -16142.3912183755, 9390.63936814084, 3191.34912204025, -3602.12681640915, 17048.1175149693, 1967.5332084558 [...]
+-3366.86847596468, 1283.26169745623, -19581.3972255720, -14954.4412157414, -3367.31512044992, -6532.76760252419, -585.673173988489, -11599.5226403844, 1939.41531569192, 1904.37127783988, 4059.73924827643, -1051.20356094337, -5858.47172832164, 9719.27474977831, 2040.07366695947, 6186.91001277684, -2986.40771931789, -1356.97625541234, -176.379284423996, 12632.3584961054, 7743.8221048823, -7416.25129888468, 13307.0615671796, -8802.84671084812, 8827.2363280244, -11230.6116060254, 2132.123480 [...]
+11195.2572530735, -6440.22122942099, -7230.66625020755, 9792.08988464882, -5334.11774492473, 8640.64454924461, -10556.2325903187, -5414.01756331467, 934.235917768484, -9220.3095232404, -4211.78439937722, 6938.16836716415, 6964.86349801187, -2390.79652787435, 5428.82118575341, 10091.2983078777, 11366.3732250275, -18198.6866627290, 2257.86195839917, 5946.23849877681, 4136.4810285721, -11532.7494677073, 18028.6004020529, -16163.4153991725, -1428.35221440744, 7326.74290376541, -2580.13252153 [...]
+17280.8767374545, 1682.48894940087, -1407.75561647360, -11340.4734077549, -1642.26143995774, 4458.00936329684, -16759.4474238471, -28405.7687122846, 13125.4609839973, -2223.56929233566, 6867.13958071195, -9938.92462007215, -2291.1362553749, -10916.7055606626, 4565.67065779016, 1212.98211612124, 22165.8617590106, 5467.07879190512, -14646.0027491554, 1293.10604110011, 7404.30354072355, 1602.06311709739, 1334.50197326339, 16074.6621508675, 3572.21898355789, -4869.8150029104, 4685.7706620635 [...]
+18143.1605539563, -8237.22794432766, 12730.1849774703, 13311.7720407435, 8355.04129038295, 14797.7261111710, 3384.32133202439, -10382.1080643366, -5548.26434135802, -18974.7982803364, -3967.08254454542, -4882.2095741107, 13121.7749885101, 10097.8554765069, -7681.58438942028, 32992.4973087543, -10613.5922509691, 10001.2395015171, 9579.03806032747, 2128.46046833847, -2224.64952968694, 4654.54957054132, 9679.16235816857, 503.734622756125, 12027.5872695935, 1644.36179717848, 6130.90187773822 [...]
+-2304.35118033477, 12399.3775189247, 1869.89891210157, 420.004692914372, 3919.09843246509, 10013.9540244548, -762.161104617708, -44.4274316095194, 945.289149235944, 13512.3067377592, -995.43307648253, -11640.3539994995, 6624.882607992, -14790.7571297165, 5273.19933509179, 18162.3838265195, -2564.84369814444, 3260.3212449393, -8931.84127255799, -11331.0431459988, 24879.2713540647, 4250.04998500928, 13123.4882822164, -5239.48659439584, 7947.89515019552, 43.3257433583026, 1469.11053273530,  [...]
+589.253857451304, -19563.7292919600, 11056.1042108567, 7116.06568827648, 7231.06428382397, -6106.9287292542, 3006.937414599, 9253.48871150377, -1991.39205053069, -4990.682026609, 12774.2172576354, 7231.72456603363, 10320.4390419885, -18358.4322057776, 2831.44241497214, -1440.63682691547, 2706.66884751189, -3193.16190806639, 15012.5028894515, 2789.4858026459, -9961.68110867056, 15281.9580034527, 3961.41375974050, -9195.5714804605, -12972.2133997108, -458.337194737446, -14971.4862691045, - [...]
+4135.41950284622, -8534.49442877583, 95.2527781626712, 15926.8392928146, 1070.32249567315, 2453.77494083355, -10479.0162506087, 16646.881461232, 3165.53594672792, -12556.9004493319, -465.642771403833, 16713.0789439836, 1002.77477351105, -1319.37667123093, 1357.69435538984, -21945.3007543433, 6738.11072143143, -7234.07144876166, -4390.680827579, -3545.20721622581, 2263.34413230686, -24605.1435496284, 4081.89819024584, 9732.60232159586, -10836.2711652369, -10487.8283320014, 8480.6209837082 [...]
+-625.273543444767, -20360.6432795989, 4344.24798937559, 11317.5644323632, 5019.44860501801, 2779.00002798154, 20450.7569703917, 12407.2026678579, 10771.3430314662, 2846.68593948814, -8794.47673981934, -4110.2310181877, 14970.2326765770, 3582.20643917379, 3428.81594330435, 9377.2064272546, 3290.12407167588, 2138.66188005101, 629.605167917406, 10489.7741909815, 3644.40387945969, -13077.1247593879, 13051.2048190393, -15977.3223552792, -9773.65172521242, -26543.0843300504, 11081.6564017597,  [...]
+11966.5679192522, 2443.08953632276, 726.837215497406, 5957.1226677255, 11934.3387022531, 1537.46389059212, -7432.17442906143, 9387.88356960542, -7838.42302845119, -346.214734813906, 30545.641727527, -3635.31486642972, -5303.54927546983, -202.905909501932, -4572.91746056786, 8457.91000350983, -3759.08559362594, 4756.90355947466, 11542.5516590435, 2779.44643574267, -19210.2436866346, 1689.76463254890, 17940.5552448913, 11786.5097970278, -5102.93450323739, 3048.40159011510, -162.39788504655 [...]
+-2.37625282010101, -684.684384215683, -6554.82569880124, -5881.54686982026, 10572.5038327681, 15351.3634470998, 1775.55892699123, 168.795558664903, -18357.42296086, -11651.0576325998, 5688.40815472859, 33587.8971713483, 11342.8947231689, 567.854367369404, 480.273357804434, 9652.1374393805, 12819.3031041895, 4423.66509406192, 5493.4595212471, 7090.95008876337, -8444.70180339212, -7353.36240962175, 2405.18758242046, 4745.88042614283, -8654.2394306749, 3318.50267509741, -8134.39571509557, - [...]
+-12458.1582344620, 13639.0585137932, 9683.4753150664, 949.961733229413, 8755.73052701548, -3798.16585741821, -5029.3789660586, 4793.64752980838, 7957.60448458469, 20026.6502471334, -10417.2045536372, 3473.69200496928, -2395.72137868695, -2180.29562795511, 5761.30435902692, 9103.4233002449, -9652.65757501458, 7987.47405125872, -16360.3541979386, -6171.97768153097, 8881.82768677487, -439.554513596736, -11497.2995121210, 18446.3550093570, 3414.34582972719, 12985.0532835667, 1329.23311601603 [...]
+8925.54773071725, -1312.73068444871, -16469.7388280153, 4319.41035664411, -302.588546970955, -1264.20464325403, 20468.7407948974, -3549.13577631174, 10642.9202464923, 5896.32084405701, 3138.78968252471, 12158.1633527938, -227.662939620189, -3850.08856476626, -20165.6269685206, 14103.6850221926, -6815.97310624067, 29353.5957139447, 17294.1614697225, 12884.9958737344, 11592.3937680464, -7172.85473240384, 5365.86017425771, 2710.43021166808, 5355.57240111966, -11842.4662227016, -14925.315040 [...]
+231.384375068332, -3531.75602749403, 7960.6964651407, -2689.73105864126, 11422.5469045609, 4360.47725288651, 15057.5905294845, 14252.9283631210, 15591.7155307330, -17763.4490113135, 18878.5572657393, 5029.23975296769, 7821.59563371998, -7939.49020464186, 8336.3233264545, -2621.18985990756, -1408.73455916019, -6072.93449845379, 12739.2018773644, -6130.50721379117, 20125.3865614965, 17710.7133569768, -2601.18702046240, -4972.36567137923, 4340.60208912477, 10459.2128733933, 17073.0562490439 [...]
+23519.9570013946, 27836.2094077191, -2696.92302471716, -6383.31358623262, 4543.29720250211, 15110.2727021932, -3551.35269338006, -1525.44947620367, -13000.9212391205, 14598.5800171301, 5557.20601099204, 8839.37542709755, -1113.35299571372, 378.077497710516, -7239.49379718522, 15264.7215624786, 5486.12740482973, -1743.04477577776, -3404.57200075939, -2585.28478212917, -8448.44750894223, 17523.0882647084, -5583.11883392609, -9793.69736859573, 381.795075584479, 11956.2917679861, -18590.6736 [...]
+-9066.53777731286, 23898.4634905161, -22549.6488566085, -6216.5790156357, -14060.2003817997, 7832.63589828695, 6393.69120326782, -13716.6146231895, 6996.39794569274, 19640.9971987244, 1554.39534819165, -194.938491585987, 9161.04531410267, -4098.6422082141, -1016.30880357672, 5083.21930131209, -4696.81346259663, -1855.61990375205, 5277.93207303901, 2616.16250533799, -14161.9293291720, 19504.3849312141, 9618.51812159406, -3092.40609571323, -3393.71039635743, 1115.99753518937, 6237.39020463 [...]
+-8245.7894255273, 12942.8893916050, 14261.294932423, -17837.4549000482, -10297.2748571722, 7647.12946050495, 5987.70151659588, -9522.65148206026, 9646.77346810806, 9280.43786779934, -3450.31524983703, -1833.63377075470, 2810.91602636539, 2548.61023854766, -4020.34007416279, 1739.43002535395, 6916.95586139019, 20346.5130398378, -8337.00810757442, 437.503318352400, -5633.19951192994, 7083.4186353677, -9359.68159775782, 16265.2617218352, -6776.79611527638, 13426.3488046756, -8212.4696204092 [...]
+9169.82052197789, 7156.5007398527, 16826.8728033501, -4247.75197328439, -9598.42665390254, -11386.957787656, 5482.53923407671, 17671.3649018725, -24834.1658750873, 7723.23756016558, -8716.4306204861, -1249.08418548600, 4305.96357964704, 21930.1069619051, 4155.83349734039, 7087.55265872609, 6747.401674609, -655.63767155226, 7557.19809339281, 873.35598693478, -14270.8937675424, -4916.68715455152, -2409.51132810689, 9488.84459361144, -5981.59344267346, -3127.98575999570, -21153.0968674622,  [...]
+-24837.8188167327, -8497.57485338406, 18055.7654557124, 6896.76290305948, -3774.07494085974, -8949.78009766435, -10293.3911608738, 3602.37906530467, 13167.6420159655, 7181.78942565881, -2036.49685221537, 4439.80894296732, 10661.2420405405, -11767.7217584602, 14503.4427948771, 3996.77543105645, -7035.5696358571, -16460.529688584, -5541.17272240564, 23159.7576974070, 19485.7238747580, -18975.6864594102, -5944.65750805217, 11532.6294806661, -19559.2856635004, 9627.29184483282, 5424.16217301 [...]
+-23043.2165129218, 22851.0699765696, -11617.5311308223, -3637.23596505019, 3615.16911562392, 3487.96253743213, -1152.82674706401, 2522.4006956723, -7272.28643116105, 851.364565765857, -6298.08843541301, -4320.09065051056, 8814.95544432196, 1393.60531684547, -11064.7251437205, 13617.1797783174, 7535.07721955065, -28849.6246703783, 14024.6525639244, 2426.22979470599, -430.035330498072, -14101.8063078379, -11385.6570412655, -12138.4049441487, 1568.56201410503, 4488.53814909216, -3821.333614 [...]
+2028.19652074073, 8845.27435343922, -14543.2391544642, -2171.62089428312, -2198.37279441041, 15176.0045028169, -8377.4848550149, -387.43969430862, -4199.52164459052, 2956.85555933444, -634.087676076111, -2166.57145175157, 10829.6627028287, 13379.5797995020, -5581.33130232208, 6264.49593435078, 23983.6350784671, 2084.92650587689, 3356.4905961999, 17829.0074614856, -6022.4392752891, -1601.25423579452, 5860.30681287144, 11252.4409326541, 12178.2108818829, -8788.42875137497, -10374.247093063 [...]
+4786.96189354306, 10026.7090496578, 4164.45928125799, 18885.4486276935, 905.355491846174, -1290.34880535237, -4163.13135461685, -9934.18732091687, -1562.67995455875, -11642.5854005551, 10973.3777853505, 6551.86049764404, 10302.2047438262, -4212.45484890704, -481.114048338035, 10590.6351344873, 3357.10038622068, -6473.16624157643, -8492.51380087933, -1601.58486533613, -14956.2366080527, 4575.08752234514, -1215.65842896035, -855.975563245238, -13643.3323113798, 4315.8829722477, -16584.2940 [...]
+-14958.9666670090, 8921.04476468481, 6102.99733009156, 18339.4272561643, -5141.63359782587, 15.6840382537479, -12856.4632572497, 4533.39649702276, -2642.49392566631, 5584.78242350172, 7465.68057818878, 12771.9761340828, 9181.99637566538, 20402.5513775694, -12889.9490027104, -12489.6643686846, 14600.8859535214, -6425.42585234401, -3349.04011576867, 6107.66263244957, 6327.61010716448, -4198.16601564126, -14648.0579455994, 3886.17459315093, -3916.36664186345, 5240.7739981936, 11106.32367872 [...]
+-2974.0714940686, 13509.4934077085, -13534.3036540552, 3180.12642380939, 18179.9533940666, -9666.84979827229, -6116.18920650889, 10666.9742512544, -1717.69418758150, 1492.38382729701, 9772.78781501164, 4206.01429332548, 8307.57057818824, 14862.0441572796, -5113.26265421661, 4420.04092055437, -20140.0670464031, -4529.16119462165, 13837.3515583707, 5974.3263644768, -10059.5092918134, -2686.59354804001, -7151.60516461846, 1298.08163602364, -15589.9871535469, -3186.14236612199, 669.400941725 [...]
+17603.0084560805, -4975.40513565923, 18726.8045645519, 19532.5186786025, 14375.9871828403, -8821.49789056274, -12899.0481278096, -14244.7933897377, 6232.42474601235, 6101.57101072846, 9101.43198326526, -10984.2534674381, -802.648775124546, -4686.46015669455, 238.778439748165, -111.882126504791, 766.840025939035, -15592.4445343825, -2965.08297341633, 9409.2860007516, -29347.0953120395, -298.616507913762, 4659.20453165727, -16610.3297753790, -2832.83784296851, 6111.76828333452, -1691.07990 [...]
+1986.53312183444, 195.908411975114, -15204.3056965287, -7903.25057815158, 14411.0070397403, -5799.54128244813, -4856.2692437706, -3648.95999662032, -1158.00158421278, 7189.72908240063, -9895.57160961015, -11705.0130372221, -17491.1721718700, 12508.7754106413, 13778.2494398955, 2106.77979081429, -2554.26540205796, -3433.50594848413, 1037.31349445951, -6040.5302190208, 15118.4536893142, -5277.19486745381, 1998.03249356859, 6970.14408397067, 11447.9349841734, 4384.25050264301, -6492.2966775 [...]
+8907.25528606282, 2466.98456248593, -10849.6401648187, 10402.8671575983, 15585.1476359536, -3848.35409118835, 11751.9506439120, 390.995841620255, 15924.9624983828, 5759.45712570867, 9534.42578116015, -7598.42665688358, -5685.68105660719, -1813.85706308156, 21267.2401064204, 12686.1828573081, 3777.88969368858, -7252.76713789614, -8026.42843082881, 4223.80689984993, 96.7784177257403, -9155.32665319498, -7500.24378366636, -6885.58788039874, 10040.6533872418, 1400.43559448491, 727.0574662114 [...]
+-8640.579448537, -23598.4498745221, 14212.0409876277, -8060.94035975525, 12520.5689130936, 2770.70584841205, -12076.3701838664, -10183.6967727372, 2164.82697916366, 10887.6871263453, 6967.59767285978, 4126.19801395722, -10413.6475620817, 10936.9626012714, 13958.4876215981, 16535.4036228052, 9490.56390586523, 8623.52261459813, -2609.67737856794, -357.913452310571, 3468.7589829571, 847.135206427577, 3638.39755979401, 8403.33654347143, -3276.0126840641, -7778.65829158829, 3204.63410959039,  [...]
+
+double y9[100] = {
+49972270.0155347, 25075068.4342817, -97950492.0912938, -42103330.9024006, 25548516.6753177, 16360759.8257629, -145395302.122295, 110054089.958565, 32338024.6697476, -65013501.5903851, -159051757.771586, 22118424.6534242, -126210439.396589, -72540010.5657742, 186210227.241125, 7693665.65370867, -35243419.3127202, 25772630.1222372, -120817042.338222, 47738757.1714048, 17019294.1762211, -46775007.0993947, 26004938.5038012, 44852160.342641, 89041053.2283838, -15931124.7019522, -9189402.30810 [...]
+
+double lars9[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -139.84768956212210000, -227.08689161198330000, -293.72268083912201000, -434.97836025586366000, -448.03190616182690000, -575.31195170951526000, -580.40610349910014000, -717.39275283263862000, -841.25311906528657000, -902.82031912270190000, -952.19655312044256000, -1033.41518904449070000, -1039.80081814575400000, -1051.35437710356130000, -1056. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -34.19722762056716200, -108.52 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -4.68020454135956140, -137.57332293314556000, -248.29750314728241000, -310.89472363051811000, -361.37732863262767000, -437.65458163870994000, -444.11149129690335000, -457.41528232382183000, -463.78237924298674000, -502. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -80.20145228966397600, -285.34412242441203000, -564.37853511975868000, -678.22358449066485000, -772.06388284131765000, -840.28490643973942000, -961.88070780279145000, -973.03564934467124000, -1098.19776229050600000, -1102.78466659530480000, -1227.06767742093140000, -1336.72796084617900000, -1401.35544072792070000, -1452.34041020879360000, -1526.16117093196140000, -1530.33625445851950000, -1538.46486780824 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-372.39072044964240000, -385.89490989298446000, -538.93797083544291000, -552.90076757207908000, -611.78636701733137000, -785.36791296885565000, -963.82281672573311000, -1053.89198217060520000, -1113.44417962567580000, -1153.17374219715570000, -1232.17687477038110000, -1238.96433556434520000, -1316.35994167400690000, -1318.97232175645510000, -1386.05401884192610000, -1440.81031393234090000, -1469.11662405714450000, -1487.43115990107090000, -1509.41360393306900000, -1510.91175598551040000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.00672032038712400, 110.20619394767951000, 113.58637863695951000, 121.32934526701823000, 124.50691514415007000, 145.22447778170576000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -98.00505501661507400, -163.40268207307119000, -292.13082134207866000, -303.31002022784043000, -419.24438729852073000, -423.38357873198237000, -522.25447817572558000, -611.92564909318605000, -663.11111938560680000, -703.14229484257885000, -762.66544902606881000, -768.22196606151010000, -777.14352500007180000, -781.20121937 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 30.12287085781785800, 56.40067493888793800, 100.89043547303697000, 103.00105508897256000, 106.82693686734613000, 108.76996407552109000, 118.0265012048417800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -35.41223 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.55369013616231520, 22.67261676820543000, 67.23168 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 175.17028587216652000, 189.93409548496666000, 246.61460533256144000, 401.08718043974898000, 567.95402822583424000, 669.95034051173707000, 748.14448792822895000, 797.05636554679415000, 893.83000605845632000, 902.47527656271723000, 986.09223398815698000, 988.96221128925527000, 1063.15714165107280000, 1124.87018582139490000, 1152.27775383863350000, 1182.37862285557940000, 1227.68871734020810000, 1230.50857324436920000, 1237.18217519218660000, 1239.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -67.44977092078686100, -178.84256716072497000, -189.08499385774448000, -295.91598582194399000, -300.35460757554699000, -433.00822029527109000, -528.55654448364237000, -587.02352276891133000, -633.17842559810606000, -703.10863359047460000, -708.24337290347819000, -718.89435588262813000, -723.69612542344 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.27312091080472800, 88.71256956820884900, 300.66635363623521000, 540.25691424463469000, 663.24738561092272000, 727.94735475805260000, 781.09057849162855000, 860.34537690566299000, 867.65427309287168000, 931.32365977480447000, 934.18345661883734000, 1000.60293485154500000, 1050.12695218319280000, 1078.73370354836400000, 1100.69005609402460000, 1135.19004201416810000, 1136.63837221953900000, 1138.95650089194760000, 1139.93006 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 84.01411286490147700, 151.23680238419578000, 189.34668666385875000, 221.29931510091808000, 276.07582293536535000, 279.97023672659481000, 289.62831716864150000, 294.21934782683411000, 323.81748527198 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 110.76041422942352000, 115.20818299586600000, 225.43007723327190000, 318.43131537786951000, 370.35616520140968000, 417.03820699914053000, 493.28077036192906000, 499.32055649809911000, 510.37292222372042000, 515.37330655979213000, 556.698878 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -82.79834738002601600, -89.98119430747179600, -168.83358039922479000, -171.43413533479733000, -237.60323843458539000, -299.45656460819782000, -334.74225846595795000, -362.81623276569684000, -413.28236742170355000, -416.55578729082168000, -422.15634547822600000, -425.276990738586960 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 226.77941881222230000, 325.69595018518822000, 385.94120059135054000, 433.58635277960929000, 518.50071434418737000, 526.58166207528166000, 612.24580685138881000, 615.91460760329278000, 725.53950775086287000, 825.63331902190998000, 882.91015459588414000, 929.99168994901652000, 993.40754705333472000, 997.45166167117736000, 1004.98528621257890000, 1008.621043838913900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -14.51840075715461300, -176.91056069033132000, -189.65741971819745000, -260.18914772784797000, -456.99014242399960000, -688.39815545896249000, -817.39702795679375000, -897.72643522600390000, -945.97284255090449000, -1037.64903439984410000, -1044.97772677664510000, -1133.92401154470240000, -1136.91176617020010000, -1208.63799607987380000, -1277.38218569815470000, -1318.66749832696500000, -1351.29999749337180000, -1402.28001607588610000, -1405.24213147981050000, -1411. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -77.51024417392019900, -126.50143356846208000, -167.47059926811937000, -233.41841108269961000, -237.36596893562782000, -243.96323029878323000, -247.46187574757215000, -266.44438 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -56.66866739874191700, -60.39004394071268700, -69.26011237201125000, -73.15739922600434400, -94.63227718733819000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.41520220254128050, 19.30724112518421600, 25.04458484135399800, 66.64971658689209700, 155.59 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.50509996929332330, 86.44826286913327400, 90.12338325008262500, 203.73972685034485000, 290.55675473895701000, 333.02472307303498000, 364.40211134328217000, 422.64047871444211000, 426.44203009190869000, 432.80127012598797000, 435.52863174751405000, 449.36824601 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -155.18498230686632000, -325.33954483510564000, -410.10316524008755000, -465.22471985908766000, -499.33131027911361000, -564.70778966565376000, -568.63862163093279000, -603.88607565851896000, -604.49266615031650000, -618.20556333893603000, -639.66081890458054000, -655.58793669888939000, -666.64894031834353000, -691.51095343950783000, -694.34935046905525000, -701.33291614624261000, -70 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -11.10430523628095900, -16.36950979857168400, -46.09014569169968200, -10 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq9[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1832.98911888187380000, -1778.46196426810980000, -1921.06346974333040000, -2104.32877898170230000, -2144.79242749351530000, -2016.49584967755460000, -2107.12480998179400000, -2083.51120749675190000, -2133.56288255482380000, -1956.99025649034890000, -1924.88713730175160000, -1934.93451586504170000, -2069.44432408484360000, -1968.97941748394810 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -859.86292092608630000, -846.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1407.33880573727560000, -1462.86846969481800000, -1403.54953006553890000, -1382.70094406385490000, -1355.86294599953660000, -1284.32501631666310000, -1485.24854961415080000, -1514.05002343437080000, -1519.9984957482800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2424.31581062017360000, -2121.28471352961010000, -2406.83650422046550000, -2056.55003533423860000, -2440.82627693806990000, -2506.33937431859390000, -2398.89196822689380000, -2423.00675776034720000, -2515.40044348855830000, -2477.48116097534920000, -2466.49732634029940000, -2480.87971211173590000, -2507.92430134900310000, -2456.72239185375790000, -2345.56476907618940000, -2203.54285191395910000, -2184.06 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-2777.54060334313410000, -2628.77957479408220000, -2500.67631955889150000, -2530.89293945788630000, -2332.88461670955670000, -2338.84972087292000000, -2142.15654401026720000, -2144.36287944792680000, -2172.46114084098240000, -2123.42619133539940000, -2165.83074968945130000, -2121.23001251146620000, -2192.70548993930650000, -2101.90335817963570000, -2055.03559335666930000, -2012.11570330075690000, -1953.78477761205540000, -1848.21964307808710000, -1753.41669411215050000, -1752.47958074381 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 766.02320239390235000, 922.71356294371662000, 658.62041663070715000, 736.30349241240981000, 651.62320662799050000, 645.4340534974302300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1840.82933325989420000, -1760.50578898987580000, -1813.43158657733870000, -1756.43421085947510000, -1731.96188613677460000, -1663.90040119864690000, -1508.25830421622600000, -1547.51895633813140000, -1539.52232473480760000, -1491.73924297127200000, -1423.36694049062860000, -1664.17623939227380000, -1485.72569532098210000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 545.89465934107523000, 574.06211918324971000, 594.72265157502954000, 443.32551593588056000, 410.69217304188766000, 431.09215865456201000, 341.51845298786458 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -387.1466 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 426.17668702451357000, 508.42858770598195000, 509.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 2420.54008726081070000, 2281.39903565042000000, 1903.26287264035800000, 1783.55173871788540000, 1669.77208182146770000, 1904.82366955865250000, 2138.67131851765450000, 1991.55401363895410000, 2037.49458632042410000, 2026.22768786436340000, 1932.88174934445100000, 1849.09520570176660000, 1803.07642650785060000, 1768.75952622725500000, 1621.55740653013800000, 1775.35280289931350000, 1730.62656421758110000, 1685.19303320291620000, 1767.2235485224573 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1714.66915099737300000, -1495.27537760773200000, -1520.44318475338150000, -1505.55654464050260000, -1630.61078016965370000, -1755.91486335828090000, -1525.46972978592090000, -1588.11064025321910000, -1542.41017052654980000, -1479.32745721928450000, -1536.18857681118580000, -1564.83357876846340000, -15 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2036.22631284367690000, 2264.41606922311350000, 2197.56354890639800000, 2122.26801262559550000, 2152.29781707567740000, 1878.50716018943920000, 2078.92371948921250000, 1796.97342233927930000, 1817.69854415198460000, 1652.24809443115960000, 1791.26536522071090000, 1662.98043955227630000, 1566.84083792046840000, 1568.54609174843950000, 1533.22076277178550000, 1518.13668631796550000, 1370.17272987908430000, 1323.0705842141667000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 921.85656390203008000, 852.61158946206069000, 841.87423845629917000, 850.75235969710263000, 884.08998011317578000, 907.92056174402683000, 1056.70766371416790000, 1055.80985510451390000, 1038.4416923 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1364.89357259561640000, 1448.20571787898960000, 1324.63328103694810000, 1288.76921866754580000, 1259.42722309034300000, 1336.65436300424930000, 1339.56615321631940000, 1473.19900664769740000, 1388.19140069511630000, 1344.87010730462980000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1061.30382368636170000, -1023.64099717306140000, -1061.67415617679490000, -950.82117195428941000, -897.48384222318691000, -944.80955160261931000, -938.91327240390456000, -915.86145819041280000, -973.45178204797696000, -944.37465321629486000, -866.97273942554250000, -942.9502505829 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1724.19883522950730000, 1523.28225165768440000, 1457.28272515765910000, 1597.14876344172540000, 1522.01310845798640000, 1576.98077844118760000, 1582.21549497718550000, 1715.45521213365170000, 1818.78910478031640000, 1869.97230739120160000, 1863.61933275122760000, 1857.47769726352040000, 1697.31767994323700000, 1649.54032631210950000, 1603.33273475722350000, 1611.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -2425.85145808220430000, -2258.48763913573160000, -1995.39790629964020000, -2321.67845527984450000, -2218.27624782183560000, -2216.38007572315790000, -2379.19140615131070000, -2326.22460016185370000, -2124.21875917495940000, -2121.07229838564260000, -1997.59519849822710000, -2141.05716301561140000, -2032.34265742345160000, -1923.93782157240340000, -1994.63169923514670000, -2025.56557697159880000, -1994.14620319874210000, -1968.15349463057150000, -1882.865062772425500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -886.22128195876030000, -965.34157909154135000, -974.54555195981084000, -965.43300645175600000, -873.88544777324296000, -767.94136092272470000, -827.84030501662653000, -724.7625 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -685.68562026786640000, -660.43917439150437000, -773.75272215324947000, -719.66509937447086000, -613.1266474716758 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1040.82718924170100000, 1043.23915510754020000, 976.79307805318297000, 1071.17354316419530000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 983.05284985134790000, 980.31669869782854000, 1191.55798236090660000, 1336.79455006789540000, 1196.37106960107510000, 1060.17254654262300000, 982.52317193423278000, 1069.08095570884140000, 1039.41886075811610000, 937.87489413837534000, 887.96140240677505000, 78 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1544.02528530172500000, -1448.86630513934600000, -1436.33962188927630000, -1445.45154212065060000, -1332.26277855912170000, -1337.32276479002300000, -1079.58641640806330000, -1002.99076618829640000, -786.28800505152242000, -754.95934195477878000, -863.51641604988595000, -928.29627412557113000, -884.54595678036583000, -967.47699346702007000, -1152.02345311496700000, -1255.992719236413 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -893.04800570554244000, -889.79643984097436000, -763.67198339078288000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso9[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -139.84768956212210000, -227.08689161198330000, -293.72268083912201000, -434.97836025586366000, -448.03190616182690000, -575.31195170951526000, -580.40610349910014000, -717.39275283263862000, -841.25311906528657000, -902.82031912270190000, -952.19655312044256000, -1033.41518904449070000, -1039.80081814575400000, -1051.35437710356130000, -1056. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -34.19722762056716200, -108.52 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -4.68020454135956140, -137.57332293314556000, -248.29750314728241000, -310.89472363051811000, -361.37732863262767000, -437.65458163870994000, -444.11149129690335000, -457.41528232382183000, -463.78237924298674000, -502. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -80.20145228966397600, -285.34412242441203000, -564.37853511975868000, -678.22358449066485000, -772.06388284131765000, -840.28490643973942000, -961.88070780279145000, -973.03564934467124000, -1098.19776229050600000, -1102.78466659530480000, -1227.06767742093140000, -1336.72796084617900000, -1401.35544072792070000, -1452.34041020879360000, -1526.16117093196140000, -1530.33625445851950000, -1538.46486780824 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-372.39072044964240000, -385.89490989298446000, -538.93797083544291000, -552.90076757207908000, -611.78636701733137000, -785.36791296885565000, -963.82281672573311000, -1053.89198217060520000, -1113.44417962567580000, -1153.17374219715570000, -1232.17687477038110000, -1238.96433556434520000, -1316.35994167400690000, -1318.97232175645510000, -1386.05401884192610000, -1440.81031393234090000, -1469.11662405714450000, -1487.43115990107090000, -1509.41360393306900000, -1510.91175598551040000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.00672032038712400, 110.20619394767951000, 113.58637863695951000, 121.32934526701823000, 124.50691514415007000, 145.22447778170576000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -98.00505501661507400, -163.40268207307119000, -292.13082134207866000, -303.31002022784043000, -419.24438729852073000, -423.38357873198237000, -522.25447817572558000, -611.92564909318605000, -663.11111938560680000, -703.14229484257885000, -762.66544902606881000, -768.22196606151010000, -777.14352500007180000, -781.20121937 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 30.12287085781785800, 56.40067493888793800, 100.89043547303697000, 103.00105508897256000, 106.82693686734613000, 108.76996407552109000, 118.0265012048417800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -35.41223 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.55369013616231520, 22.67261676820543000, 67.23168 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 175.17028587216652000, 189.93409548496666000, 246.61460533256144000, 401.08718043974898000, 567.95402822583424000, 669.95034051173707000, 748.14448792822895000, 797.05636554679415000, 893.83000605845632000, 902.47527656271723000, 986.09223398815698000, 988.96221128925527000, 1063.15714165107280000, 1124.87018582139490000, 1152.27775383863350000, 1182.37862285557940000, 1227.68871734020810000, 1230.50857324436920000, 1237.18217519218660000, 1239.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -67.44977092078686100, -178.84256716072497000, -189.08499385774448000, -295.91598582194399000, -300.35460757554699000, -433.00822029527109000, -528.55654448364237000, -587.02352276891133000, -633.17842559810606000, -703.10863359047460000, -708.24337290347819000, -718.89435588262813000, -723.69612542344 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.27312091080472800, 88.71256956820884900, 300.66635363623521000, 540.25691424463469000, 663.24738561092272000, 727.94735475805260000, 781.09057849162855000, 860.34537690566299000, 867.65427309287168000, 931.32365977480447000, 934.18345661883734000, 1000.60293485154500000, 1050.12695218319280000, 1078.73370354836400000, 1100.69005609402460000, 1135.19004201416810000, 1136.63837221953900000, 1138.95650089194760000, 1139.93006 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 84.01411286490147700, 151.23680238419578000, 189.34668666385875000, 221.29931510091808000, 276.07582293536535000, 279.97023672659481000, 289.62831716864150000, 294.21934782683411000, 323.81748527198 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 110.76041422942352000, 115.20818299586600000, 225.43007723327190000, 318.43131537786951000, 370.35616520140968000, 417.03820699914053000, 493.28077036192906000, 499.32055649809911000, 510.37292222372042000, 515.37330655979213000, 556.698878 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -82.79834738002601600, -89.98119430747179600, -168.83358039922479000, -171.43413533479733000, -237.60323843458539000, -299.45656460819782000, -334.74225846595795000, -362.81623276569684000, -413.28236742170355000, -416.55578729082168000, -422.15634547822600000, -425.276990738586960 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 226.77941881222230000, 325.69595018518822000, 385.94120059135054000, 433.58635277960929000, 518.50071434418737000, 526.58166207528166000, 612.24580685138881000, 615.91460760329278000, 725.53950775086287000, 825.63331902190998000, 882.91015459588414000, 929.99168994901652000, 993.40754705333472000, 997.45166167117736000, 1004.98528621257890000, 1008.621043838913900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -14.51840075715461300, -176.91056069033132000, -189.65741971819745000, -260.18914772784797000, -456.99014242399960000, -688.39815545896249000, -817.39702795679375000, -897.72643522600390000, -945.97284255090449000, -1037.64903439984410000, -1044.97772677664510000, -1133.92401154470240000, -1136.91176617020010000, -1208.63799607987380000, -1277.38218569815470000, -1318.66749832696500000, -1351.29999749337180000, -1402.28001607588610000, -1405.24213147981050000, -1411. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -77.51024417392019900, -126.50143356846208000, -167.47059926811937000, -233.41841108269961000, -237.36596893562782000, -243.96323029878323000, -247.46187574757215000, -266.44438 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -56.66866739874191700, -60.39004394071268700, -69.26011237201125000, -73.15739922600434400, -94.63227718733819000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.41520220254128050, 19.30724112518421600, 25.04458484135399800, 66.64971658689209700, 155.59 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.50509996929332330, 86.44826286913327400, 90.12338325008262500, 203.73972685034485000, 290.55675473895701000, 333.02472307303498000, 364.40211134328217000, 422.64047871444211000, 426.44203009190869000, 432.80127012598797000, 435.52863174751405000, 449.36824601 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -155.18498230686632000, -325.33954483510564000, -410.10316524008755000, -465.22471985908766000, -499.33131027911361000, -564.70778966565376000, -568.63862163093279000, -603.88607565851896000, -604.49266615031650000, -618.20556333893603000, -639.66081890458054000, -655.58793669888939000, -666.64894031834353000, -691.51095343950783000, -694.34935046905525000, -701.33291614624261000, -70 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -11.10430523628095900, -16.36950979857168400, -46.09014569169968200, -10 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq9[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1832.98911888187380000, -1778.46196426810980000, -1921.06346974333040000, -2104.32877898170230000, -2144.79242749351530000, -2016.49584967755460000, -2107.12480998179400000, -2083.51120749675190000, -2133.56288255482380000, -1956.99025649034890000, -1924.88713730175160000, -1934.93451586504170000, -2069.44432408484360000, -1968.97941748394810 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -859.86292092608630000, -846.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1407.33880573727560000, -1462.86846969481800000, -1403.54953006553890000, -1382.70094406385490000, -1355.86294599953660000, -1284.32501631666310000, -1485.24854961415080000, -1514.05002343437080000, -1519.9984957482800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2424.31581062017360000, -2121.28471352961010000, -2406.83650422046550000, -2056.55003533423860000, -2440.82627693806990000, -2506.33937431859390000, -2398.89196822689380000, -2423.00675776034720000, -2515.40044348855830000, -2477.48116097534920000, -2466.49732634029940000, -2480.87971211173590000, -2507.92430134900310000, -2456.72239185375790000, -2345.56476907618940000, -2203.54285191395910000, -2184.06 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-2777.54060334313410000, -2628.77957479408220000, -2500.67631955889150000, -2530.89293945788630000, -2332.88461670955670000, -2338.84972087292000000, -2142.15654401026720000, -2144.36287944792680000, -2172.46114084098240000, -2123.42619133539940000, -2165.83074968945130000, -2121.23001251146620000, -2192.70548993930650000, -2101.90335817963570000, -2055.03559335666930000, -2012.11570330075690000, -1953.78477761205540000, -1848.21964307808710000, -1753.41669411215050000, -1752.47958074381 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 766.02320239390235000, 922.71356294371662000, 658.62041663070715000, 736.30349241240981000, 651.62320662799050000, 645.4340534974302300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1840.82933325989420000, -1760.50578898987580000, -1813.43158657733870000, -1756.43421085947510000, -1731.96188613677460000, -1663.90040119864690000, -1508.25830421622600000, -1547.51895633813140000, -1539.52232473480760000, -1491.73924297127200000, -1423.36694049062860000, -1664.17623939227380000, -1485.72569532098210000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 545.89465934107523000, 574.06211918324971000, 594.72265157502954000, 443.32551593588056000, 410.69217304188766000, 431.09215865456201000, 341.51845298786458 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -387.1466 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 426.17668702451357000, 508.42858770598195000, 509.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 2420.54008726081070000, 2281.39903565042000000, 1903.26287264035800000, 1783.55173871788540000, 1669.77208182146770000, 1904.82366955865250000, 2138.67131851765450000, 1991.55401363895410000, 2037.49458632042410000, 2026.22768786436340000, 1932.88174934445100000, 1849.09520570176660000, 1803.07642650785060000, 1768.75952622725500000, 1621.55740653013800000, 1775.35280289931350000, 1730.62656421758110000, 1685.19303320291620000, 1767.2235485224573 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1714.66915099737300000, -1495.27537760773200000, -1520.44318475338150000, -1505.55654464050260000, -1630.61078016965370000, -1755.91486335828090000, -1525.46972978592090000, -1588.11064025321910000, -1542.41017052654980000, -1479.32745721928450000, -1536.18857681118580000, -1564.83357876846340000, -15 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2036.22631284367690000, 2264.41606922311350000, 2197.56354890639800000, 2122.26801262559550000, 2152.29781707567740000, 1878.50716018943920000, 2078.92371948921250000, 1796.97342233927930000, 1817.69854415198460000, 1652.24809443115960000, 1791.26536522071090000, 1662.98043955227630000, 1566.84083792046840000, 1568.54609174843950000, 1533.22076277178550000, 1518.13668631796550000, 1370.17272987908430000, 1323.0705842141667000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 921.85656390203008000, 852.61158946206069000, 841.87423845629917000, 850.75235969710263000, 884.08998011317578000, 907.92056174402683000, 1056.70766371416790000, 1055.80985510451390000, 1038.4416923 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1364.89357259561640000, 1448.20571787898960000, 1324.63328103694810000, 1288.76921866754580000, 1259.42722309034300000, 1336.65436300424930000, 1339.56615321631940000, 1473.19900664769740000, 1388.19140069511630000, 1344.87010730462980000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1061.30382368636170000, -1023.64099717306140000, -1061.67415617679490000, -950.82117195428941000, -897.48384222318691000, -944.80955160261931000, -938.91327240390456000, -915.86145819041280000, -973.45178204797696000, -944.37465321629486000, -866.97273942554250000, -942.9502505829 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1724.19883522950730000, 1523.28225165768440000, 1457.28272515765910000, 1597.14876344172540000, 1522.01310845798640000, 1576.98077844118760000, 1582.21549497718550000, 1715.45521213365170000, 1818.78910478031640000, 1869.97230739120160000, 1863.61933275122760000, 1857.47769726352040000, 1697.31767994323700000, 1649.54032631210950000, 1603.33273475722350000, 1611.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -2425.85145808220430000, -2258.48763913573160000, -1995.39790629964020000, -2321.67845527984450000, -2218.27624782183560000, -2216.38007572315790000, -2379.19140615131070000, -2326.22460016185370000, -2124.21875917495940000, -2121.07229838564260000, -1997.59519849822710000, -2141.05716301561140000, -2032.34265742345160000, -1923.93782157240340000, -1994.63169923514670000, -2025.56557697159880000, -1994.14620319874210000, -1968.15349463057150000, -1882.865062772425500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -886.22128195876030000, -965.34157909154135000, -974.54555195981084000, -965.43300645175600000, -873.88544777324296000, -767.94136092272470000, -827.84030501662653000, -724.7625 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -685.68562026786640000, -660.43917439150437000, -773.75272215324947000, -719.66509937447086000, -613.1266474716758 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1040.82718924170100000, 1043.23915510754020000, 976.79307805318297000, 1071.17354316419530000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 983.05284985134790000, 980.31669869782854000, 1191.55798236090660000, 1336.79455006789540000, 1196.37106960107510000, 1060.17254654262300000, 982.52317193423278000, 1069.08095570884140000, 1039.41886075811610000, 937.87489413837534000, 887.96140240677505000, 78 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1544.02528530172500000, -1448.86630513934600000, -1436.33962188927630000, -1445.45154212065060000, -1332.26277855912170000, -1337.32276479002300000, -1079.58641640806330000, -1002.99076618829640000, -786.28800505152242000, -754.95934195477878000, -863.51641604988595000, -928.29627412557113000, -884.54595678036583000, -967.47699346702007000, -1152.02345311496700000, -1255.992719236413 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -893.04800570554244000, -889.79643984097436000, -763.67198339078288000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso9[1250] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 219.09624318611387000, 242.36170350526899000, 266.55647844436669000, 298.84580550696535000, 442.48937797570704000, 485.4718000863285900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 67.24040079325669700, 161.10178297660715000, 188.72597619195773000, 209.00498329107720000, 277.52257454170780000, 476.78117185969774000, 507.05076431537969000, 534.78460344270206000, 550.90075981249470000, 626.38419907220668000, 645.6234485 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 31.40012542877057600, 65.64290369750581500, 204.27343921011339000, 248.91493445823173000, 325 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 66.75145028427337500, 169.99641093410503000, 312.21061538942263000, 354.71868434752048000, 385.78403383113948000, 485.18165727391766000, 775.52448153098749000, 833.68467835541901000, 892.21796176740088000, 973.97551581585969000, 1307.52537159527950000, 1393.832 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 107.61793184747164000, 143.89533477224563000, 218.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 45.14066240622514000, 92.77442093348082600, 138.37868174419768000, 336.16220323519610000, 393.57312268253150000, 5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 179.08953934256050000, 310.06954449990292000, 522.71316864517109000, 688.30985236586196000, 738.31802078974727000, 962.15572523011997000, 1011.83717741061700000, 1075.54319954411200000, 1164.03081865653080000, 1306.90227614192440000, 1345.12272528019620000, 1371.31164275402830000, 1469.64463637141010000, 1818.76344928597860000, 1867.95278680585330000, 1914.59610429121700000, 1972.33601891345140000, 2213.4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 109.87640202827383000, 474.14557179280791000, 519.44263006147912000, 561.52183934809102000, 622.85932719414484000, 854.25949372483660000, 919.87943097788036 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 107.19662745023626000, 176.06716666452027000, 195.04710577665455000, 285.52918675647027000, 309.09282098031917000, 341.15731504098403000, 382.60125556358423000, 461.65960249448403000, 481.86117589483814000, 495.71057056733520000, 530.05089612119900000, 622.80963128767257000, 633.11224218958250000, 637.91278975396733000, 632.63014112278086000, 597.57275517748576000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.57994021143932900, 74.52345769911332200, 119.90015326392383000, 201.23921532980097000, 213.64710464526740000, 221.87153642232624000, 237.42218081988884000, 289.73355709641663000, 289.68384553055404000, 284.72456845189237000, 271.57778150587393000, 223.91247992621129000, 212.2616 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 148.14451649934330000, 191.13881654275576000, 233.89731508976649000, 280.65674506359966000, 345.38338055590503000, 355.65454367717450000, 364.41184204828028000, 392.82477895280050000, 491.00163776983203000, 498.53562236913262000, 506.19063273066928000, 508.90980459390357000, 514.47936663552832000, 511. [...]
+210.45436236573252000, 489.06610669296236000, 845.99390209317119000, 963.51946136069739000, 1137.12349488066370000, 1260.30927750879750000, 1435.28661838475840000, 1558.69990638935660000, 1602.73101054731770000, 1803.36633243339950000, 1849.85005296841270000, 1906.28359024868790000, 1974.08217413927220000, 2096.92353573676840000, 2129.01425580398470000, 2151.81702163684210000, 2223.78249416079230000, 2468.24457520257510000, 2503.77459765451660000, 2534.71517555002400000, 2569.10709327917 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 127.35831 [...]
+0.00000000000000000, 262.69835621481104000, 596.11048660852725000, 707.32937116004814000, 832.54348410830971000, 899.50088762214045000, 1007.96836176667320000, 1074.13769481666870000, 1090.83056178831700000, 1170.03021660992770000, 1189.64956840855710000, 1213.99059555265510000, 1249.51596008213800000, 1288.43342111156020000, 1300.68354886621390000, 1308.24015218231280000, 1314.61890490248290000, 1289.54725849103280000, 1299.65040189047480000, 1312.91668152816990000, 1328.645036088692700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 104.89891902622074000, 267.74059483447371000, 370.99329975493441000, 404.59276379051528000, 536.00624775543793000, 570.54379578005842000, 606.37940930844115000, 653.23885200620350000, 741.64481503060324000, 763.11721090209153000, 779.44068166404975000, 819.31577742422462000, 931.24727289407372000, 948.43486778626868000, 968.61019660695399000, 983.66742509875291000, 1059.55041199411020 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 112.96564056729656000, 151.72450144003363000, 318.39140381237189000, 358.41183068658421000, 414.95160326424076000, 499.89249043324537000, 609.46468956176079000, 641.19735809692645000, 666.22397349651692000, 754.64722262491898000, 1048.06945666466440000, 1096.21064021606730000, 1141.13004905807070000, 1187.88993015861230000, 1376.21785886128210 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 28.72904746685506100, 48.34615016216649500, 111.81809520723131000, 302.45349627247350000, 334.95052492095903000, 362.53290741651784000, 401.45207223094530000, 575.84896576049289000, 621.025336058725 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 47.28185749732521300, 136.2829 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 148.77599744653071000, 183.04766563519522000, 208.65061688632227000, 289.05092501424582000, 570.47959263787186000, 600.34510335687560000, 627.10437205543485000, 656.38365897659560000, 772.59904893309408000, 809.90317277 [...]
+0.00000000000000000, 0.00000000000000000, 300.47535390050285000, 408.96311997337165000, 534.85632576534806000, 633.58649632146478000, 782.72208371702504000, 886.72109204121136000, 917.60431636508031000, 1054.65945761998200000, 1089.73247519705480000, 1133.82887483838140000, 1195.58268189564250000, 1317.73292470008440000, 1346.80601182407190000, 1368.29459029523970000, 1414.07544992160140000, 1615.79991136133910000, 1645.84217377442810000, 1678.38276699348900000, 1703.09097895823990000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 67.43834453752856500, 325.10569120412066000, 404.17407388566744000, 583. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 11.24150026837065600, 28.45025497011558700, 100.32915985986980000, 111.75718056688737000, 122.65961566571733000, 120.45641996625790000, 102.51548423236353000, 93.512704331165750 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 128.98126799152513000, 259.58867263763159000, 365.87663026827852000, 514.63490108537906000, 618.39744556112555000, 650.81652538573928000, 780.79172168768844000, 811.59478969163160000, 849.57394628185034000, 895.97898022646348000, 963.09980257932261000, 979.70789820481059000, 991.82838578758128000, 1022.70160356272990000, 1138.54333740504190000, 1159.57386986832560000, 1181.20015703687570000, 1213.07451360101780000, 1349.76712 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 36.56160940266736500, 174.14378197453883000, 215.11356112231232000, 253.66008739023769000, 304.35501640983279000, 411.51513263547332000, 434.70389128875775000, 451.00342583006392000, 517.37314786492425000, 730.59343580390214000, 758.31133078780999000, 786.36672518181399000, 822.32441271592143000, 993.25301903510035000, 105 [...]
+
+double nnlassolsq9[1250] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 531.35963179513169000, 456.18914885295686000, 475.06997665920409000, 543.75619194550654000, 562.91144990401006000, 573.7330932663877500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 713.81134511277776000, 630.71301151904754000, 706.99254073795987000, 702.43962310964696000, 821.39594306100059000, 760.77127549256011000, 785.25156231055894000, 773.79818509088830000, 673.13972988387036000, 689.66494317864283000, 685.129855 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 302.01020607710871000, 325.36996590188892000, 320.49288455000999000, 340.58301425954943000, 3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1032.83886994265340000, 1162.78037587275640000, 1023.74272494207900000, 1152.22653164116540000, 1141.67506233978590000, 1274.17203621019510000, 1189.33091126429010000, 1368.22154705634810000, 1396.66488127604820000, 1594.09603172067480000, 1587.1533704957183000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 197.83828843552286000, 218.38835629425469000, 222.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 460.01801240125263000, 503.28791604307088000, 484.28112550661069000, 501.97192964258568000, 511.46229095780774000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1915.93479084683780000, 1936.95489420007880000, 1971.94337728621920000, 2123.02111970931080000, 2031.80823871623720000, 2061.00493816693140000, 1906.16374184129130000, 1997.55442593012370000, 2014.91098556714290000, 2021.72278179250160000, 2062.18912848251240000, 2008.54792349381360000, 2250.18428318480300000, 2316.33940934137350000, 2320.04056998030140000, 2316.57385864933390000, 2410.28583358889410000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 982.04437818063684000, 993.31433371376193000, 935.75737812518992000, 924.16555695040768000, 1088.09627135291110000, 1048.25137946858690000, 1054.62522323319 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 837.77386149508538000, 772.75386581009161000, 685.97421532982253000, 729.71781761352588000, 733.26689633451269000, 805.22370158086278000, 781.11832928553292000, 857.20766033397354000, 860.86953146945336000, 832.69802949600671000, 802.63474202306622000, 755.01252324490576000, 727.80114751731764000, 679.28448957412354000, 592.56193173660529000, 568.18276591889025000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 714.06457070700776000, 609.20348833179503000, 556.23385376710803000, 608.19824338491992000, 446.43559257187246000, 421.99077854250106000, 360.85882237097616000, 364.28950283681928000, 289.22695806790239000, 241.98491846997155000, 171.86109601619449000, 183.95277775047018000, 188.33 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 875.40575143383785000, 965.08850924157525000, 852.73701600755237000, 730.28655745840956000, 669.22641488906095000, 548.35520947594512000, 577.49694756697875000, 618.35868085635423000, 630.92662311589947000, 567.77872601109675000, 572.16243835286070000, 529.53437290796114000, 519.14855015177409000, 505. [...]
+2804.68105436937500000, 2626.62155803942010000, 2530.55820204470550000, 2456.14993946024880000, 2820.76924196359100000, 2790.38361830849090000, 2627.80978593521790000, 2627.93892049151960000, 2741.62100207962480000, 2788.31194779810080000, 2686.61355853183340000, 2723.04083194326770000, 2626.02050128347310000, 2711.52862031711270000, 2731.07879804740560000, 2706.66048564904030000, 2795.02417449822410000, 2816.66021529949190000, 2830.32278667915310000, 2801.36481994723590000, 2829.9653590 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 135.86519 [...]
+0.00000000000000000, 2278.16365809096850000, 2169.68973504525870000, 2119.86208197187940000, 2046.89435180203740000, 1731.16995573492430000, 1747.20679798642500000, 1647.42144390160460000, 1522.60122681155420000, 1558.83190926120960000, 1542.82176286612640000, 1566.27597669914210000, 1591.12112929800150000, 1483.14690455546130000, 1530.51222031954150000, 1492.10959989767930000, 1365.25164994718580000, 1253.81429861642600000, 1392.50604770399760000, 1427.24708478734510000, 1447.9425793912 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1407.83454159041640000, 1377.55555757152460000, 1265.56326217601240000, 1273.66234636772220000, 1181.13260743273140000, 1192.26166659631600000, 1125.02485083926990000, 1103.83036779052240000, 1183.96126020362360000, 1165.96788437276700000, 1176.62807238031090000, 1135.83307254901520000, 1090.77583239474760000, 1106.40206280639500000, 1142.48362178346410000, 1097.87456362073860000, 112 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1091.68739817167420000, 1154.24486915087410000, 1136.58150700495870000, 1078.82818935964520000, 1233.24637835902100000, 1316.66795548533510000, 1157.68094048296850000, 1236.54437791354280000, 1275.17878549572080000, 1456.52610483740550000, 1466.26476554838290000, 1538.66508356681240000, 1528.25095011894610000, 1542.55760495877580000, 1534.1005 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 567.72414561336393000, 525.67514144030508000, 615.64054325356631000, 574.15352845834980000, 633.62317192528997000, 600.24121748452478000, 696.64892399833514000, 722.05275960764106000, 713.7917430667 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 144.37173009522019000, 142.227 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 893.13834661813200000, 826.02969211224524000, 831.62899877370955000, 927.24595804702767000, 971.58126433209577000, 874.83207990686185000, 857.71898781657956000, 878.46327867893615000, 870.02699372723168000, 886.50449140 [...]
+0.00000000000000000, 0.00000000000000000, 1718.60546514202750000, 1786.80932764542670000, 1755.79316819141720000, 1859.90090864871060000, 1799.12593455349130000, 1787.75694422604720000, 1716.41678680688870000, 1727.48146709073650000, 1721.08944922354290000, 1772.03189161614180000, 1789.39558118375980000, 1928.88017456794960000, 1892.25575100858670000, 1891.16086901922400000, 1777.47103759806010000, 1903.30444808218590000, 1921.95363411663990000, 1958.82153706561100000, 1890.4995839366279 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 578.94950082275238000, 541.11839000142709000, 566.53527556872882000, 595 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 284.77292164573646000, 165.04850976609245000, 202.77341031337326000, 216.78946618000040000, 216.61812064208294000, 103.74546438925702000, 87.47489023795954200, 75.02614733235007 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1767.10469329542410000, 1526.24473420123490000, 1686.06531793194770000, 1528.46722603705780000, 1517.38460123795490000, 1489.35478721272530000, 1418.85733496219650000, 1366.08747806568930000, 1399.24268358702850000, 1342.20098760267520000, 1298.92153365432320000, 1291.29783664653020000, 1286.74757959217410000, 1267.76452305415770000, 1303.64490111016040000, 1352.86061207059110000, 1367.57811683455540000, 1454.8374022629539000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 982.24879620656020000, 849.55305863199476000, 952.61941537138352000, 811.54031231993599000, 791.82784140372974000, 947.66314858063299000, 869.75581080131849000, 847.60839353328868000, 1044.19733464566390000, 1034.48221392164370000, 1013.06006962728110000, 1028.15150902939850000, 1095.05884079309290000, 1136.549210928768200 [...]
+
+
+
+// Data from file x56.txt and y56.txt
+double x10[5000] = {
+12326.3015360409, 2270.15344960091, -13177.6442365811, 229.355634753738, -4401.87339102021, -15897.1724517243, -7302.92238863108, -8840.67070169662, -17544.6261726266, -7137.25499575763, 2022.42189104218, -4680.35048217572, -22194.9512983225, -15248.2164917731, 6617.6360699504, 2921.18561430935, 10009.4141197723, 23704.8079677813, -19416.8140611839, 3640.22003261022, 7632.51141283387, 5970.01481487843, 8755.57396491401, 6159.9017679393, 3802.42030546788, 5675.62359426087, -8235.662872602 [...]
+-1348.59770055456, 20977.3622967859, 4581.33879668372, 5950.776728442, -6514.1080892133, 1826.01190846583, -10254.6752248054, -6142.24517914031, -2768.20410097938, 9746.44029458268, 11793.8686582458, -10217.7145612866, 18231.4053047527, -1059.24713701691, 398.978287946877, 3241.0664493658, -7083.01603636863, -1915.21710000673, -7722.44471858495, -5419.5789464754, -63.8961463117188, 8699.21827882042, -12930.8263479973, -298.639860242591, -7671.52610379567, 4342.02263793432, -5724.47726332 [...]
+-18928.8549828126, 10725.1973285757, 2205.32050816751, 12063.7815536196, 4347.57943249732, 15241.5854322774, 6414.15981258894, -20905.8025825929, -12041.4311562972, 6557.15840674711, 26726.8534392722, -1421.25370652268, -4403.34535086398, -12043.1876870322, -5547.76238217329, -1008.74153610077, 8872.1596477786, -14059.9929001778, -3572.50773725420, 5200.49514859371, 24320.6538961128, 8872.48607483724, -9145.0770719662, -10729.5818516463, 2677.22325285255, -1775.61122870295, -13420.042170 [...]
+-2203.28045775777, -12887.7713673992, 12135.2332249573, 11280.3951745827, -3759.56706250499, 2570.86513279134, 14116.5360286548, 12835.5252871640, -10341.8380113730, -5040.20495668658, 410.808449892953, -5518.84366990025, 16949.8705392138, 2056.95190333705, -20349.1344228185, -674.93153941431, 8296.34092533277, -8169.07457827653, 509.215000682448, 2905.11404276496, -9301.07606930545, 2508.71323969883, 2405.09028697023, 1038.62765513180, 18564.8214665673, 3614.63975032153, 14197.244332959 [...]
+13371.0797409124, 1641.65419330878, 9729.75248953258, -12684.573442097, 11948.6024630281, 13366.0485357608, 1357.13349567062, -21384.4875775481, 3400.42848095989, -1616.72134015755, 2150.81019905818, -9385.30127863123, 5966.19924580684, -984.426293768137, 1461.16267694141, -1321.08868750361, 8937.61564782417, 4021.69176916299, -2843.53463674722, -10663.6020443189, -2080.47027189187, 1782.70694970982, 3916.25626107205, -3403.99626266697, -15737.4672801213, -7648.3851890838, -13178.6568261 [...]
+-9555.67629576742, 18930.9381063422, -7560.09902476916, 7412.8105549794, 2563.22796259672, -4067.71810426127, -18309.0819647242, -3833.67342292440, -4696.56882554526, 16163.7311142478, 12358.8717838181, 555.347688292147, -585.508079624274, -10077.5315030384, 2941.1552043864, -3560.52061895487, -12781.0671543943, 4846.11275158887, 9651.50429382917, 5085.27870021408, 13742.1342179412, 10644.0830816569, -17389.9399847617, 14947.9140319093, -13134.2650084250, 73.2734226087812, -18228.6760176 [...]
+-3800.89443822991, -4242.01137605868, -1432.83274022712, 14285.1907584069, 1190.96518699911, -7441.47581153307, -11487.5302011647, 41.7133448530267, -4176.75200392733, 16435.2348297271, 7721.66399357186, -9858.63041465089, 5140.0848574682, -72.0614147371004, 11060.7864027011, 2924.02495733578, -2050.34973975437, -9101.05334436012, 1172.80117698668, -6052.07764028454, -19920.0006187697, -3311.87261419518, -2789.53658360983, 1354.22508965145, 1629.95518938792, -14786.1839590600, -9207.6774 [...]
+-4035.87170480805, 2502.61888571417, -377.976372162817, -749.164123481755, -4218.38600447756, -10519.9140398292, -4841.37594172205, 1487.32181494795, 1923.58065659913, 3332.90710056671, 24206.9526500962, 2079.57139960942, -1899.84620962348, 5854.07876880634, -557.316254286605, 8434.38068977526, -1319.48903304986, -4576.93987742636, 3182.03048497557, -8282.06030653506, -14434.7293710725, 3672.21402666076, -2457.64529800634, 601.027915786713, 3185.97522210904, 1814.53751176195, -2322.82286 [...]
+9181.10966304587, -1400.07976339638, -8700.63786442287, 5101.6288546502, -3896.69345662424, 10926.2737226331, -1801.38122895892, -6576.73512596022, -2031.71917975914, -1259.52552881979, -11136.4949379337, -12157.2036298509, 6426.12223672385, 8887.67217283146, -3592.98674023647, -14538.0771018943, 4115.58152607666, -3614.66443514516, 11439.4668755740, 5990.43933395739, -1071.62676273552, -16864.1831155928, -13551.2623176108, 6419.67798059208, -11197.5792938138, 16159.8585435473, 12654.993 [...]
+-1841.02365632845, -13034.9539833368, 10310.3900256881, -174.815043865603, -4669.69352027922, -25970.7469652341, 2488.85860550616, -1194.88864426703, 3622.82916043977, 169.259564936217, 19759.7519208138, 471.816496587932, -7778.44921954716, 13366.9462618845, -23621.5929555524, 3207.26578796257, 14213.3162722960, 12225.0113840132, -13072.5426887005, 23623.6656127402, -3715.06371627781, 16994.9221886899, 7588.29789136933, 12087.9881734188, 9916.81498284647, 889.21470199561, 1174.2848571262 [...]
+10895.6674843218, 6625.17668966055, 200.533229210909, 1833.33085824932, 1103.45531995005, -5345.42754441473, -2774.12680445352, -366.510259348927, -13791.1595506639, 11894.9211988058, -8684.36508454287, 8281.55987413744, 4164.15712774798, 8632.75990842577, 6854.61508565516, -2115.60205493605, 3556.24851398936, -2156.47541240651, -5367.16406581793, -10105.8576958015, 5870.17678928303, -4639.82216352249, 15739.8034131005, 2848.39534827361, -11954.6542521168, 17753.1885534941, 8579.06281956 [...]
+-480.519800899421, -17790.4500322997, 13364.3667729029, -12401.5207453961, 854.954044898235, 18104.3961294042, 20977.5651088726, -9915.19615563157, -9473.725026409, 4031.2829398224, -18185.7521527213, -19374.6497569384, 18335.3675973250, 4692.24951790502, 6638.3025924292, 2839.47812471785, 12977.2058796898, 5528.37092634727, -8249.08376117231, -10334.6265696575, 2679.67326543382, -6106.66370799673, 26143.9186951297, 234.73480923728, 3931.35626416007, 5770.98706311169, -11205.1144155087,  [...]
+-3111.45306100819, 9911.19427784413, -5497.65531384107, 9008.1113036788, 3374.37259782391, 4882.63974469508, 7000.25036696294, 2216.94423600645, 2814.51744293865, -1522.97848750334, 7345.85807606069, -2069.82020702378, 11487.9402970590, -8519.52377217845, -2299.65316783886, 4355.84973430021, -2821.00448364263, 6494.18283644006, -1100.29100194521, 20053.9242712602, 7722.76730070764, 114.915789555483, 1176.78916604425, -7537.00658204508, 35361.4697306432, 15898.1093144425, 13428.5871359058 [...]
+4486.29372605263, 751.270463954922, 2745.03336304483, 2255.22149050439, 2320.19085187219, 4960.48353759397, -4743.71196086544, 15515.0337667247, -12687.8402190877, 2334.19706922019, 2905.03521263305, -14337.9174537787, -6463.91924900794, 7421.5766052841, -4114.77749514465, 6931.07911192046, 690.291511905927, -2038.73569840095, 989.985731293814, -571.143339730795, 9605.8989747653, -4450.10428761921, 6033.71273027008, -9930.47043406713, -6589.29691760732, 22874.4312479454, 5082.52785631106 [...]
+8227.28146763725, -6127.91260803212, -1862.28602959618, 2430.72180322016, 8148.08395118468, -6689.87251689468, 10072.8865584817, -5321.09093977129, 2305.22111221321, -5050.50692048841, 7206.48067398239, -2131.88327082718, -5687.40578785499, -4682.05166356274, 396.208405120484, 6429.0552041432, 1633.49136828853, -6528.61395600824, -17120.8531448768, -11853.4921670461, 7714.80566889756, -18501.3024600477, -12935.9500226653, -12625.7268839694, -4168.12056432369, 14725.055774347, -1094.64967 [...]
+-3086.27731351002, -12690.5499484177, 10079.5779921307, 19529.6013142007, 10242.4913520103, 3667.74507112865, -9314.30950412516, -3798.3127419386, 12610.0572430044, 7595.36674925136, -5195.81165484617, -1834.20241801486, -5943.44363701875, -16657.9174508736, 8467.73856232504, -5012.81977381578, -564.702436648139, -4790.23424448632, -5338.41489126335, -9849.01925494452, 4212.10851855587, -3564.91957598481, 14098.9662469390, -1554.57686900834, -9694.26884960696, -2688.67340390372, 17862.77 [...]
+16009.0309815849, -415.21799947378, -5823.88293830585, 11532.5709245227, -6066.52135048416, -4137.50721277926, -1907.05540628481, -5801.535910972, -2614.81442903023, 16392.0356686500, 86.892404329495, -8145.0782123234, -793.274496093333, -3735.01974721036, -10034.9803877317, -5481.98275682261, 26147.3182056807, 7541.15150974793, 16557.8491790551, 8158.05976908318, -17.0424540302019, -6435.80606973615, 1737.10573207228, 5604.5648886799, 11792.9502378499, -4955.18492073091, -1001.771763787 [...]
+-18153.8698009635, -8501.79825647942, -5968.38919151554, 5977.74255658871, 6560.24275542395, -5402.62186726689, 13461.2348119399, -1481.63178590673, -14637.0022502397, 6758.99433358947, 7421.3598818625, 23139.3601110860, 2401.78138975113, 6161.29457328421, 27474.292650535, -11040.0552528351, -852.702805440715, 10432.3478321977, -6707.13052813574, 17139.6678651141, -7571.94010582336, 6179.31272337625, -13620.4247382222, -6592.07127920878, 7047.00691258356, 20482.9313705166, 2080.503841588 [...]
+5343.13398876839, 2267.63661495717, 3091.98043399877, 7831.01327909889, -4339.44001849157, 4572.90342711422, -16172.2267288158, -8481.16181879105, 2661.64905345434, -6699.95744226977, -5616.48165816199, 2443.96310660902, 8897.85340262987, 361.864595926021, 1871.01144639784, 2156.54278668280, -4752.22529995091, -26052.3384133274, 1896.39136013762, -10126.5611787495, -2613.11667228901, -6430.95730988823, -16150.2131595121, 10850.9195358212, -20779.7265942864, 3423.14794533701, 4184.1441735 [...]
+-675.414035660968, -5919.67618186412, 9775.51817097231, 4623.83795214836, 302.898526355120, -11917.6521654656, 7597.08206194454, -3640.27068675349, 1846.54373796479, 12024.9514338091, -2481.55461597856, 5289.86395238022, 934.884517427574, -6920.43145552602, -11993.7434508894, -15115.0334156316, 5035.1972286797, 75.4537285526844, -3991.62940401045, -10375.9003598334, 5177.88516124582, -6477.3212700747, -18396.655311949, -3517.51920325027, -9135.45528192094, 15943.8158016444, 20444.1768730 [...]
+9008.8286950188, -14425.5767610690, -5910.81686125876, -5429.56478511693, -13689.3676665452, 8529.02116678038, 3831.15614178499, 3923.20412359018, 17593.5024758156, -15895.9679932649, -16545.5692542600, -1659.70830557631, -1346.76755901048, 12254.2067863403, 2746.53629256133, 3499.11046509632, 3749.44883282442, -2646.89729041617, -26292.8135037043, 9784.88713879097, -72.2234604708675, -7289.0031687059, -3344.13286978965, -8845.72420456913, -3176.15659257035, 16579.5774217361, -4159.13093 [...]
+-3463.97137962445, 3108.68435153737, 6998.46101846328, -446.254269632557, -6620.35826630299, 17713.2375209728, -16318.6143648135, 5589.02694008815, -19589.1421343338, -1789.09367495602, -10760.1063259039, 12586.2270879556, 1258.24636101693, -3861.75496267816, 29811.9438340988, -3114.83699629453, 11398.860786327, 15779.5619024051, 23095.2102533904, 14338.5854283833, -16002.4051360845, 163.974993451578, 772.560592230323, 7641.41869696924, -8540.59334587728, -3096.75650781113, -3706.9767177 [...]
+6286.49107151897, 12467.4613094109, 24177.4730945672, 6894.88637147633, 12687.0273551942, -11551.2369621685, -4287.67840045661, 13489.1157303034, 22152.1530557012, 2393.62105710671, -13038.9141719036, -1463.59890145015, -1113.34627612274, -2229.04468963192, 12558.0373765472, 9120.97436702813, -11538.9779494723, -11771.7073671643, -12737.4658895296, 14870.4454483762, 5252.06606226499, 9495.334435341, -1834.30027170897, -11564.8816025264, 9094.74855800802, 7754.53208393096, 1121.1128326684 [...]
+-32131.3156695834, 12775.1769605796, 2629.40772132368, 4440.71243377839, -17492.7264972061, -14494.5778480926, -8120.1090787719, -12959.3222155109, 3492.73984735006, 7544.60718097089, -9159.98539419964, 11207.3576309391, 14110.0021511132, -10513.7697703033, -16140.0594378739, -480.552545919038, 9187.19540141442, -1285.33606771258, -12645.110800985, -6271.2411419827, -27958.4143131538, 17885.8093635248, 3149.22841611628, 1123.85754484307, 5900.33556989065, 4685.13846441131, 7943.362372677 [...]
+-5759.88056013008, -4525.95309719241, -12562.9002335688, -22410.0847176800, 8286.32717754795, 10030.3558961583, 3695.57016114928, 5270.80313196755, -10212.7743928833, -737.755061524992, -5838.31187245996, 6661.2487114298, -13841.1920942383, 16674.4782518173, 9984.21577439363, 2461.57694657798, -5821.06121194531, -3418.557914568, 6107.1987132863, 7633.35355133062, 17532.1952837331, -1865.80574970808, 7831.3538600956, 30598.3697027017, 4165.66825735115, 15090.3841577031, -12459.8437276561, [...]
+-6325.27492004166, 148.097195073715, -11772.3575247363, -1439.58961901836, 7090.84926349139, -1541.26236866983, 1541.78738949393, 12530.9440107430, -363.617597885444, -4028.67984731581, 1644.73500066832, 13335.3026957092, -3594.57128301043, -408.637434969686, -6006.04537636619, -778.196475335967, 1184.49739226041, -11640.294328558, 14170.8471199735, 12731.9551932464, -17803.3537672010, 7265.37551476776, 3237.83155228471, 1720.19375393614, 7970.24958816127, -3506.1502138307, 5132.47830206 [...]
+3613.97049900666, -15759.3648470773, 5887.21476946433, -8986.63069624517, -908.079438719669, -17042.3659158993, 5609.92707165984, -4157.75557334794, 5667.87002828626, 2310.54105449238, 1187.11435666136, 5015.44792262724, 3911.17259598835, 415.170105094896, -3924.96435931963, -5467.9064803219, 395.122992996161, 1062.60111257547, 12421.9754096313, 5910.35384892475, 13048.5925523300, -2774.65781530603, 1301.00803068215, -16905.5030963345, -17380.2279252280, -1080.33257910607, -9174.45332785 [...]
+-9629.01646518576, -7158.2378065147, -7342.79383783579, 699.224384506446, 20120.7117560806, 19533.6277185663, 7050.92492861974, -12026.5366486317, -25494.5460540769, 10820.6247544839, -14230.6357469308, -160.717494873212, -7042.66180256926, 1722.64485340620, 24536.4303301399, -3962.06248114399, -6366.35488057661, 1544.65960957961, 5805.74935240271, 4662.67358368951, -7399.28728579991, -2682.09071679125, -12687.9089137708, -6516.01405219538, 11129.5453427496, -4385.49963145999, 225.393527 [...]
+-16014.7079828614, 9194.67100666082, -15778.5953593861, -5163.90595614537, -10659.5159603956, 14291.3538380900, -14918.2181158063, 7684.53209638469, 1331.26608254413, 16368.4446849504, 5735.94866961266, 1773.36564016178, -19486.2176406070, 1001.22616350237, 6069.3636933325, -3791.99792635966, 11387.0351440935, -7737.07445999505, 1333.14675437125, 3962.02787918899, 5292.11767113516, 564.839129103607, -3104.66067429776, 15282.5120444004, 5186.85060687983, 3022.99221142934, 1317.30855064073 [...]
+-15602.8914882078, -4311.60971459384, -13375.5400494920, -1129.22922706066, 17478.5519812902, -17518.0949490422, -5068.52667485263, 5931.48080596617, -722.848236885392, 10555.5618508344, 17845.8979182991, 1921.97297309518, -12588.7864738727, 9040.63408655632, 15338.7464353252, -1171.81047915672, -4126.10729356341, 15201.8388690097, -6571.18169376097, -11619.1010276786, 16173.1031585210, -9854.65533167977, 1488.86423754746, 4763.72713428639, -10183.6175155104, -1390.69533560554, -4447.928 [...]
+908.88354509216, -11021.4382937767, 9612.66256996856, 7626.51073045568, -11244.7713844545, -7987.02029520644, -4222.17125725406, -11982.8785196514, 13797.7439091036, 1288.96731716841, -4973.54532996263, -5106.7221116413, -4713.11127732602, 5330.37527706169, 12615.7612315017, 17016.6194044574, 6121.86797427235, 1834.49905288735, -8683.81589979422, 18831.6045875296, -1921.38130608149, -15568.1174683285, -7930.81195128506, -12021.1227106243, 10667.4818543785, -487.567880427681, -10511.74199 [...]
+19964.9390429578, -21738.8643473472, 766.573558831293, 5792.07905285773, 14458.8937757599, 4682.88473009832, 3044.66468702511, -10567.0660865089, 7126.17821355294, -11232.5965669471, 9616.94965709718, -12360.1566920273, 20658.3858985628, -3175.79996834952, 14449.9165781402, 3695.0667271404, 7424.68365227799, -13516.2581899401, 3696.71074316756, -10483.6871519313, 4627.04829174173, -5185.78996979109, 3290.00397771650, 267.348718328137, 8707.28701125623, 7047.2182073101, 28198.2917607657,  [...]
+6340.86397998471, 4635.19539980303, 15489.2667374449, 15961.3683314036, 2284.70659187847, -1702.27435521258, 96.7674837492531, -7596.19283323921, 4770.75801271896, -5903.13174051415, 16132.0019561053, 17396.9849181682, -4975.20125888548, 7828.61477797479, 3491.09545941484, 1313.12822675609, 10866.1192187451, 13585.6636745195, 684.785026342327, -18318.6765807054, -5924.77831552668, 3158.50899572224, 4610.98937791414, 6879.60376303146, -6872.75851297539, 667.272294006391, 694.748445212052, [...]
+7484.48736972091, 13870.6102112740, 4537.28449262369, 8114.80647775196, 7761.31380068641, 4901.91041605161, -11052.4423293986, -15037.0921596156, 20533.7950674048, -1439.00365436581, -5417.24070644499, 8937.98759710692, -14056.8641952800, -13044.4728852639, 5232.3427863082, 6111.74849828407, 2234.82455033469, 9535.91045902926, -4099.25009790398, -3466.00857771429, 8888.0529635301, -15.1261239913364, 6890.3816464617, -14461.5194419023, -7180.3704765398, 280.302968017036, 8849.44558702787, [...]
+12887.8126507585, -6982.09169496374, 9942.97960284355, 21614.0952005088, 15602.4386308277, 4906.97145220418, 7967.15112663165, 2001.76682969001, -8691.68166909756, 1426.90145070404, 8090.01688985031, 3021.51872615395, -3911.16463012466, 11054.8596942874, 1652.5501250736, -681.361386958504, 1817.51468811677, -16980.7521070979, 3045.78338694604, -5757.4450347298, -15900.4754617016, 15581.4518642979, 4990.78018718176, -4090.02607577368, 1503.33104201162, 9620.24576230886, -15831.4563489582, [...]
+7350.02335991134, -15005.3961691020, 6472.35628672645, -3926.88319872108, -336.646460574247, -17552.1676000938, -3823.47271808589, -4587.00162208229, 908.272606728919, 7343.24597047592, 19457.8921406037, 13216.5391877886, -129.894739681395, 2813.80954765443, -1962.79093527935, -7381.07603037094, -12692.0083320917, 10758.6444876530, -6493.85718690945, -3834.38812597376, 7176.46005807118, -3410.53507094401, 11050.6162392082, -20554.2449733983, 13403.7011118027, -12131.6496724954, -6666.570 [...]
+-1511.67236557272, -16579.1360770066, 1381.11847381017, 442.342734996786, 9673.17016265238, -368.066169722172, -12810.6282166786, 920.485734248822, -18847.6277293275, 7835.2213999845, -4482.10199699828, 1246.89737747, 11647.8182540841, -2012.65540182337, 3346.30357467543, 2984.55216269656, -3850.34138999611, -4099.40238709305, 7221.4279552838, -5743.50243149532, 8331.23028401041, -558.367851934635, 12541.3559530814, 22274.0303414577, 14844.4943002132, 9558.4599811408, -16.6820461898873,  [...]
+-5685.24730151740, 6099.2632242371, 389.717589497841, -14859.8344131086, 1689.54455236287, -4641.35882567238, 8971.12845984645, -1526.03520545297, 9279.16615976614, 2712.15665605785, 2667.82296085466, 11761.2386639825, 5738.64948182596, 15322.1829652016, 5715.09216330487, -8653.37125407452, 2435.12453235173, -5316.97917203754, -2859.24042523909, -11004.4773417385, 14344.6461044026, -13835.011970996, -13387.9605625939, -2587.27703452734, -20726.0175324527, 3699.77832490887, 3404.465824138 [...]
+-4230.94077369069, 8501.58944854747, 15639.1559448303, 8150.9979342361, -1638.02422534845, 654.83694667479, 13083.4409104879, 4376.12348894104, 3787.58496334178, 2895.78059067113, -1454.05980586623, 31692.1563173309, 4107.902537939, -1985.58371645838, 17270.1495277679, 22804.2485175492, 7400.30773541815, -617.141708592242, -4223.59750564025, 25135.2317683298, -18955.3325481004, -3001.92750258469, -3693.16654301804, -1434.58924418522, -17916.5203580234, 17431.7385848927, -7477.13683784863 [...]
+2979.65339769768, 5179.76474722313, -8692.61614750783, 6259.95251009005, 7685.57284809697, 2170.21323827275, 20571.4235113251, 13531.0660302696, -869.15897341069, 11440.3288977046, -4236.39678203412, -6389.29168682555, 5459.29903958389, -750.888381577522, -10503.6936936951, 3167.08025799688, 14462.2835301412, 2819.25186317899, 5870.62355543005, 18077.4240866144, 6172.65902945608, -7321.21183216886, -7816.19610264103, -1514.05593347168, 11552.1076523229, -148.957410352092, -943.4309975078 [...]
+-8191.5027372658, 5198.6653314972, -2459.92914062967, 904.510901624998, 18878.9456690158, 4048.13312838507, 14823.6053325359, 6737.90409765703, 19593.9027018683, 3862.57617900329, -7491.58281831932, -887.3545357678, -2102.08985980818, -8925.30824231628, 9842.3180802055, -13554.2189200479, -12309.7200497179, 20926.3617804238, -120.674172592520, 4810.86392740228, 5101.31555436218, -11897.6643646426, -1150.87179119008, 2050.28784819363, -13830.0475732509, 8384.5110834936, 2872.48020580766,  [...]
+-7305.05204512576, -7087.9614865747, 14792.8557376663, -8914.84821101079, 18667.0681174792, 14088.1899817851, -3782.89623183343, 1926.25285003719, 1480.23482971106, -5189.76472519536, 6272.1270902241, 4674.94215250421, 5077.76694827336, -6881.29661781954, -15947.2883513616, 6487.31794683766, 16925.2161161274, -6501.20223615476, -8509.14716628955, -1628.15128339190, -13744.1170887295, -932.19440005293, 549.974174254388, 24918.7491447565, -1275.76163587949, -10938.0982930420, 7067.66821446 [...]
+-254.302708330789, -1079.66674650714, 7715.45083495414, 5784.4342435845, -8794.5786132284, -11882.6496042173, 344.838032915661, -3547.9246191644, 17293.5440107897, -148.174220088648, 311.513024134516, -2560.19712377882, 2546.89015545934, 16673.0097662238, 8860.02937802558, -3041.42252205885, 7212.85903794305, -7547.06841733142, -17307.2057033103, 10325.2697019296, 940.639317663558, -11739.0010545601, -4297.54505469683, 3961.54899529001, -14016.7262162508, 10881.3858814788, -17713.9234917 [...]
+-1373.89450781574, -1206.84047227975, -3430.7684284979, -15573.5871045157, -14015.1726401515, -13365.1672086668, 1085.94924197486, -6619.00047975397, -5450.3663667534, 10612.7498003818, -4036.07012030792, -5682.54513088344, -1222.44221797697, -10422.6918644846, 2136.135323581, -11908.4618249715, -17029.3166572889, 14465.0459946128, 17469.9786868555, 16110.8345480572, 79.0891862150341, 22454.1588134429, 2617.84811001339, 3385.02116316523, -4665.89346060053, 13922.8078107614, -23881.232435 [...]
+8297.6714353607, 11011.8019085570, 8919.16487503196, -2930.55257525362, 4582.9766565273, 56.9739302291187, -5776.75633569321, 4599.92805693072, 16591.3595077468, -238.247989285939, -16707.0938739117, 13411.0750005399, -2832.02835329822, -400.467420486586, -8710.2434946704, -138.481254536895, 19567.6480826130, -2263.31507229711, 10771.8530518572, 2731.3319423249, 21789.5040341809, 3546.95118498035, -1440.17774150868, -10846.4765821394, -17022.5984462663, -4902.64274174786, -2215.770076126 [...]
+23773.6797681560, -939.007234865813, 2155.3290885524, 1100.30072188789, 10894.3560289757, 8416.00652020847, -9928.06084652636, -12680.2901583323, 1579.68346836266, 20647.354478378, 3926.81329390956, -262.539861770977, 2642.44252677287, 7399.5274430622, 4637.81734007376, -6925.57343843506, 5220.00468384863, 6709.97213243296, -7567.79229162312, -23683.4798916459, 5495.72725257983, -9177.07448980385, -1691.94309758263, 4418.83710885153, -312.365817761988, -7732.2467052123, 14239.3270587978, [...]
+4141.552982002, 6305.74675555626, 14624.8850544963, -4140.58779182398, 15535.6845523007, 21604.9078062283, 10325.3895253754, 14736.0571987161, -15326.1476273528, 11483.7584329191, 7989.86457640729, -3764.78582442841, 3911.76688376552, 19325.1172960884, -4832.75237028595, -2039.13578358487, 8419.26561445341, 8998.53477902726, -8346.13420955581, 2777.49738207582, -3846.74556739927, 2038.57578210443, -9699.66721734084, -4363.66123167045, 4962.65764666301, 14381.6123015762, -14872.4984446698 [...]
+2167.10485557364, 2656.92711099787, 2176.33193739742, -8607.20484768395, -2129.64771622803, 7191.56498700212, 8880.48204939018, 14562.3484307418, -6511.69836617309, 3322.1792976777, -17000.9075053422, 13947.1168182434, 12833.8326678189, -10110.5567395934, -359.414497226285, -2823.15163783746, -2543.00826112943, -10556.2634148068, -9848.67620340723, 3111.97347203378, 493.353357243824, -1125.29414032593, 18589.2792618253, 8436.37593367733, 2918.15258607675, -11606.6695240024, -11348.809040 [...]
+-1104.10898828912, -96.4700692865703, 8621.92666241074, 6095.02689534727, -7774.62235667309, 4687.74942309751, -21328.4580056783, -3474.84599816399, 1102.42147483204, -9045.23307055473, 1800.93236985137, -15764.3377634485, -7609.6858117681, 3975.12544784867, 2526.10312746072, 6510.29688121318, 1577.17545761626, 11241.8885050427, 24429.5289598357, 2005.26954132631, -6043.23014600612, 8486.57980188048, 16029.3722674678, -1826.85250762678, -2497.14713404149, 8227.07615894037, 9730.282640766 [...]
+-5048.5621465107, 13254.8678345979, 863.585343653958, -3541.75209361091, -15971.1575564163, 1752.12165682758, 2306.30334190686, 8427.67611856163, -7124.56737987675, -4522.10347867059, -3072.12108547114, -4621.92129275344, 845.628585028105, -7325.57508187153, 10295.7587543991, 9158.30595130348, 2987.70014797351, -16262.4901305987, 4823.88549385856, 10526.731106749, 8428.05520920413, -4485.84903710868, -5925.44995194536, 6130.2915822437, 2221.93469999588, 16386.9258357569, 1245.06186528010 [...]
+10996.1282542062, 830.421164186917, -8116.32460896404, 10832.3132073944, 5156.47146546783, -1331.07211872796, 20747.8194056761, -7442.39461534022, -5737.5937105048, -12355.5758019479, -2914.48395621723, -16546.7766068482, -13432.7712460138, -2741.45073901982, 6601.89998613317, -5948.97231184968, 899.646547817253, -506.175368492997, -2677.44770733979, 8748.53189740452, 1088.90175926146, -2456.52807589621, -7361.68031501564, -3669.07145803484, -7239.53679551986, -6637.56079874519, -8629.61 [...]
+8427.37001287598, 8283.85199765805, 2569.32266619989, -5.45815865960447, -9483.94651561016, -1746.28401426375, -2758.08952373102, -5300.64173388115, 6941.54874128915, 12285.2084085158, -224.630359569574, -13691.6350501751, 2170.61849642735, -22567.2060076955, 4548.54631603534, 28427.3268742818, -824.90973064543, -9846.16177496067, 8114.83261539031, -4274.91048720271, 3598.69344224994, -5956.88311750754, -8045.83044011866, 1352.9964015495, -5920.44586680456, 3200.34403355644, -9674.697758 [...]
+649.515683764808, 13861.6548001227, -5926.21586648401, -14899.0585128529, 5085.17084277741, 15984.1894735889, -8482.32478366591, 2745.86977029870, 5695.55571970128, 7192.79327236407, 7224.45816019807, 18202.1161465323, 16805.7016657161, 2161.64933933183, 388.617921032239, 15420.6352252459, -6294.57009798205, -15164.7262794514, -8253.32091542014, 2530.26985229306, 576.253929532151, 6702.31230624439, 2797.06938595104, -12111.6745895880, 13387.6361236781, -1416.09085454746, 1282.78680856077 [...]
+-9699.38631995986, 354.970825914787, 188.685264501001, 3625.92826349837, -19619.4131163364, -15395.373810129, -11829.1938326159, 15699.0509778999, -9108.05879402691, 4400.55451463244, -5264.6699921567, -14271.1417796648, 6431.4250078224, 2276.63886145568, -3736.07496987764, -9000.74078321507, 4563.08503193762, 47.0839585950943, -8926.72430179504, -4486.92942528008, -8792.66049607051, -1889.18959285946, -11241.3610361600, -2899.89223533886, 13456.1539877431, -1790.43600629339, -8478.47718 [...]
+-846.894974755725, 12056.2496783004, 10943.4990001023, -2177.30975217195, 6646.24714780408, 624.266941339951, 8732.24650203363, 14662.5117806041, 17497.0552639378, 5148.40388863346, 6095.02792434327, -11285.3961345956, -4071.25800773116, -15166.9427223153, 5337.68819032532, -11206.9698321363, 2552.49131994668, -293.082820971005, -11524.7211453833, 840.74074131115, 2721.88201275177, 24914.8791868522, 19149.7859302777, 18688.0449940566, 14734.5794086340, 12691.4937596781, 6594.98983786736, [...]
+3889.51687245268, -10997.1795931079, -7588.39568604653, 4138.40497313933, -19771.1232081076, 7129.35717929618, 11976.9439451908, 9136.4392109655, 17416.9617144966, -22082.9015761816, -12070.6617183007, 20735.9783832058, -2216.0378271401, 7982.89419001068, 725.048540947756, 3628.41169197494, -1534.68404974373, -13149.9684909676, 1679.39099568024, -7719.10125729699, 11493.2421321297, -343.636788083732, -3673.42643037062, 13896.9410514517, 6360.42768220052, 13199.1346931979, 6619.3458729528 [...]
+130.511245546471, -8893.37983250403, -8313.9030758354, 1188.33056889569, 16015.9857597182, -2913.9065471549, -9301.19198074631, 12324.8804151525, -12508.3060770971, 5860.58913148507, 16356.8409677167, -1997.01636776905, 6819.15147808247, -6843.515648058, -1839.41613795461, 16617.0757876435, 18951.410595487, -1830.18677137311, -9654.99360979, -7180.2310717045, -17443.2273928702, 7007.27937330276, 21093.6856287047, -5072.1911584704, -18600.8072736752, 5377.56318638538, 179.729880832283, -4 [...]
+21527.0103721505, 8121.72888032007, 13574.8772002152, -21062.2614501733, -2439.24212118975, 792.06652597888, 7457.50599650436, 10715.1954363029, -392.02058848871, 2561.341662059, 15521.3095335748, -2377.79413266377, 2872.67103121581, 9573.1143276983, -3776.88438507867, 7845.38254981664, -3495.11323037206, -14413.0948766106, -5390.57972675136, -2144.61812615804, -21735.5652003833, -6212.69162033984, -6341.25006011134, -9360.88771147121, -2522.11195940752, 8252.21911015969, 15316.646847443 [...]
+-2564.13817207490, -8291.6660469314, -12453.784935795, -5868.97148070265, 7112.36745104127, -6176.74366376152, -279.738227100369, -8639.83299609251, 15387.2092996123, -7001.87972321972, -6388.00781211947, 20748.1449397674, 4703.52177517294, -13234.6327959217, 6467.34292355232, -18219.4011199289, -14123.5202595371, -4341.2183461265, 6892.01027761158, -2664.91462274332, 1847.53792427914, -13029.2046476301, -4853.47165464459, 3723.90059994583, 216.222338330376, 5370.02592772052, -21956.7339 [...]
+-16748.3877805404, -3779.28852125174, -15205.8086843309, -7571.66560803657, 13565.8815923536, -12091.4218016661, 3757.4288511566, -488.689638257342, -27312.2678225496, -13357.9854864758, -4168.14767318788, -6460.90146807994, -17800.2662283374, -4770.74463835386, 21803.7800120235, -4221.2596562926, -8488.15437547332, 3080.22106934387, 12203.9156158578, -663.972735741878, -6325.7139839531, 6191.47188750845, -2212.86325448572, -6667.90982335969, 1071.61618813913, -11196.0172154632, -2422.26 [...]
+-5255.89907303625, -12489.3320708269, 2727.86154005103, -18785.99587395, -1921.01290265723, -5538.53676782902, 6620.33041252858, -6260.35221833341, 1567.97635782092, 1363.21488140526, 14534.236572193, -10810.4618271785, 6194.62169825646, 9771.5056506435, 1802.02409271368, 9249.29266433997, -7526.38366701257, 2064.12477917219, -16144.6859270419, 3999.78374721351, 4123.1119246335, -26045.6715813025, -2061.14573112693, -2783.00036338876, -5999.06336387147, -5540.35806946624, 5779.2002897104 [...]
+-23467.9722539290, -16246.8298716297, -14828.8985668118, -8271.30599800049, -2750.97007815463, -751.603488589177, -5047.54578322659, 6815.29762391047, -516.361529502324, -5012.17965041979, -1002.81181558216, -8170.32954521594, -3528.54542388343, 7288.54709090232, -31832.0387433157, 4909.01880258786, 13105.1761527974, -7663.1893094902, 5316.72471562265, -25667.7950735011, -1515.46580872394, -7297.70660334146, 4943.95645461982, 16931.9198976054, -1945.44147506529, -378.286248517788, 6968.8 [...]
+-5051.54049155308, 8201.0524582491, 3313.75255952559, -11933.3901685156, 3393.32313301853, -1769.14433012899, -11927.6185403784, 520.193402494002, -5866.69549751075, -2226.76150961124, -12634.9312825422, -5757.5112850263, -10037.6822132046, 8786.46005746205, -16296.2148855409, -5969.7100288716, 10195.5025718459, -332.771756444516, -19275.894408972, -14494.0881898946, 8551.90001973192, -16452.8629254577, 329.904865682943, 9161.43785944938, 15073.2694475685, 2206.49645394369, 3773.91389324 [...]
+8737.1434165938, 5592.29237458557, -18347.3230339077, -9769.355821697, 538.379656738686, -2098.06361106934, 15139.9169307866, 2680.04265696142, -12703.1999472395, 672.615202379792, -2358.82414021550, -103.824432764485, 11857.5818763292, -684.497766332682, 6657.92969427406, 7293.04100650326, 13211.4381460077, 1185.24148651746, 7109.63784235703, 1642.70529186014, 17337.1507410003, 10762.8320559510, -8022.99532790534, -8669.08415020907, -11268.8515589365, -6570.65560526588, 1752.66076893710 [...]
+21420.0745536029, 3034.85140821106, -17501.9316028198, 1165.71736058232, -2617.25030909950, 17521.8737130061, -5628.15211320236, 3723.19193216996, -5117.6359906351, 477.661164330417, -7793.56465197043, -5525.64013827242, -8583.0339613995, 22421.0781715028, 13284.6568977083, 2657.29175027402, -465.800277795787, -4815.52642236839, -13494.0284818491, -8003.58581855594, 1451.3073906188, 8286.93179794242, -10916.6260371568, -767.67669569067, -6433.77351388068, -8803.38668942827, -949.65278973 [...]
+598.897061551564, -7210.08173075846, 3891.39134878388, 6238.56115425247, 3702.09927499939, -1446.68014083651, 7299.45275079253, 242.612901836854, 1494.14057821145, 4827.29790352436, 5286.07291218291, -8452.92366367768, -7133.98730606151, -2329.77178327626, -960.919001486537, 9294.56455308259, 5255.83458802629, -10021.2711732386, -1069.98175393168, 16350.6008499385, -13203.2919140285, -6323.02310739086, -8239.76903484064, -2891.75210313091, -7085.06998608758, -1335.00912058432, -14397.905 [...]
+6515.88075126486, -2799.85498209121, 5013.15229055972, -685.992643666682, -14488.8778616375, -4697.21329265018, -8527.67952703903, 24584.2506948168, 15.1047864606435, -7436.05906928142, 494.938814641104, -11769.1217651781, 13604.9016391029, 4219.02868729901, 12545.7961502100, 6401.11579565554, -17281.4984886363, 281.931145503963, 19008.538123318, 8633.39621131031, 14451.6057341003, -538.843911327429, -1041.72460251063, 3309.46607829137, -3186.36744215933, -5718.61775269712, -4546.0497750 [...]
+851.171034860932, 3089.35876645520, -1789.01210463792, 2633.90005100720, -15149.1038117488, 10157.0416116708, -14708.2111231079, -11048.1091321772, -2840.87888236972, 988.579833711896, -995.201964714712, 10279.9726442826, -18074.6737258419, 11060.7740143126, -202.933293646454, -6356.70211294987, 13145.0304403950, -1397.62777036589, -2202.45100183996, -15638.4661261315, 688.257687365149, -4704.28908783405, 15833.3992822601, 22391.3663975586, -4257.72311688106, 11064.0855876307, -3184.1651 [...]
+5999.95681047324, 3924.87134682671, 3833.23860621233, -1090.75259537055, 16768.9821826549, 1199.73736644434, -10610.231898738, 16677.1205891296, -5050.02251100456, 2556.95217352361, -15980.8667245395, -6646.85325111292, -140.5644114712, -8323.28631304544, 28757.4155061509, 16969.5850026349, -5906.86613831794, 12695.7646396793, 3274.45166494474, 4004.11797461366, 11466.9721495476, -9733.72088759996, 10412.2235382675, 3918.10049715643, 1753.25190381505, -15031.3760941992, 7082.57278339382, [...]
+10023.1594071484, 2357.19832714824, -2376.25843661376, 446.149788021308, 15621.7112757054, 3826.27860434948, 3743.58364741852, 17653.9518417201, 14940.8670878219, 3591.65623390058, 2903.55709098626, 10052.7275135726, 16660.4245498612, 12446.9684931523, -4671.30550272553, 12508.8900947976, 5374.12421718552, -4672.39559636848, -13560.7569003222, 1803.61017450648, -11497.6375723418, -8662.12868634116, -3114.33216110460, -3098.18257931801, 5370.57481418246, 13881.7383747730, -20742.91873275, [...]
+10929.6468130994, -2235.62140605324, 8444.85774979675, -4843.16587335246, 13046.9200209044, 3823.80466751001, 7779.32729839746, -10933.5675391745, -6723.03353545843, -9629.28821227713, -2333.48133193696, 3993.26628271163, -15286.2822892563, -9667.0000504997, -8475.48054216429, -23429.3759014999, 3182.36405530026, -16941.3346948730, 5690.76713291597, 4452.2110098535, 4629.58543176001, 5732.71580243474, -5528.48585609197, -6308.53164893588, -8367.82662728217, 3468.5416746948, -17646.144442 [...]
+16246.2594848222, 5565.3465327455, 4007.66568700682, -15446.5051234212, -11759.7109071906, -442.485221533381, 2504.19569512437, 17614.0351397669, -7552.2097718356, 14714.7233234118, -426.799380764211, 2528.03034136809, 9436.63806970352, -1158.21466739190, 14084.6550469042, -17367.8993216298, -1346.88698056103, 14007.9926861161, 1259.78131824362, 1915.40628403126, -19064.9192260352, 18941.576234204, 5112.59381831148, 19026.855430881, -6793.56748699381, -2550.64520509544, 573.470806731842, [...]
+-9201.48872724331, -18769.9350855829, 1381.49040969430, -6359.70048135973, -7793.86761212498, 5462.26184575893, 2169.67593022194, -15056.9235284911, 8372.44733257548, 6791.85460270483, 4346.32750985365, -14171.2597096769, 246.397395061255, 17282.6448615028, -8327.62976350386, -9342.60402645549, 4157.20811726629, -11475.7101160667, -1711.18665457982, -1743.60648642578, -3160.81260687484, -6236.41859397652, -542.295940180777, 11597.2272089005, -2299.47324931984, 5807.09962942404, 7422.9889 [...]
+1385.20847080344, 3421.19937757460, -17246.4894221240, -1189.71743535653, -7791.3154961735, -8266.19876533166, -8771.19916860176, 1282.90132804965, 801.087535989033, 5120.7278781168, -956.368194518037, 3988.31331751978, -3291.96967992551, 3337.6552959064, 6985.82933862528, 1998.76096594793, 256.720524661234, 3926.37084620316, 7376.2015678176, -333.916114854061, 18511.5787850225, -16134.5218285434, 2051.85435176618, 16228.7221142349, 4047.31146617925, 4204.28732666463, -1312.61081883989,  [...]
+-9255.61058255204, -10079.2703224584, -7978.79848699948, -4845.86339564075, -17268.4757774654, -5519.00789112344, 22.7855522715661, 723.595091519293, 726.743678465378, 7286.94475563066, -253.756422549905, 4215.82254086763, -2231.98417542245, -12450.5551790349, -2474.25680984807, 12494.6235252647, -8949.10071501931, -25014.0000535797, -23601.2902765873, 1859.5066957893, 5193.36430912449, 8341.91398858806, 1723.99596030321, -4829.20317421693, -9918.27040610428, 17994.9714095283, 10655.5081 [...]
+-3653.30386998819, 884.06464426874, -6731.89283253759, -10541.1090780406, 637.111058551985, 8990.70754012771, -2737.68745229999, -9755.11440961537, -244.948252342625, -16266.5960193799, -17222.8033275109, 8874.77553936804, 16964.4657894228, -6021.94449950108, -394.892534860118, 19340.6892873145, 5760.02750386376, -15392.9259517057, 4764.73073309058, 12718.9124605838, -695.877974017193, 29555.0356240586, -5074.70833893023, 6687.85149100076, 6506.7964093019, 12857.7948277034, -7515.3905661 [...]
+12560.7494470084, 7315.39992227173, 6817.65079324713, 7091.08580748242, -4673.94340960008, -2076.59749978777, 11297.2984723962, 7196.36540159447, -5304.36041765499, -7683.7335019011, 571.969876768631, -13525.9054344551, 1095.61771781864, 4393.08353853448, -1294.04058345343, -6772.74873918322, -3754.92071430511, -9219.36175205929, 2005.17008892803, 4512.5834342377, 4600.66300217594, -1134.97924926496, -2113.05548476779, 3970.94568279789, -16711.9477505638, -5296.56529419965, -6542.7248114 [...]
+4274.66993743511, -10186.3638559424, 5345.13544823794, 19344.3678746319, 16699.9136567926, 12425.0495042174, 6433.85099222378, 20439.062936658, -7160.20896291882, -5762.41062171412, -344.677960169089, 5379.02027067768, -15238.8902243168, -14790.0418030218, -12680.295190768, -5440.61660658858, 748.65014083278, 4964.3613741832, 1938.16025428627, 5078.37684326086, 13039.5937602345, 1662.81946561333, 2534.08521695357, -1246.87645157519, -1401.67486801255, 492.445806042888, -7895.08969908101, [...]
+-5922.31503682913, 1059.48587202456, -176.231989241194, -6729.63902601122, -4070.47410181336, -4655.84827538725, -1911.85964479492, -10028.8516976634, -3382.85458817316, -358.441899963596, -14767.7356887932, 23316.8173772755, -6179.94183358311, 17510.0337256813, 671.733739266613, 6827.55452325841, -1215.37558459060, 3721.95731363013, -20270.377291393, -414.156215115682, -3554.92208092141, -3207.63889247976, 5312.46780585491, 12772.4665721927, -4147.81168915323, -803.292936363985, -5907.1 [...]
+815.426275680505, -4969.06463893272, -14014.3090952269, -7942.62153281443, -9555.62209704697, -3020.20452470014, -10746.9281310784, 12801.0844593635, -6806.38764903528, -731.386306316951, 1718.28430208786, 5736.21329614769, -15813.9701833867, 5202.21534515286, 14293.6870651278, 21183.6432592913, -6052.61405726496, -9839.29444301133, 5239.48943239112, -19831.9768942221, -4768.17210593596, -5449.73666594314, -10503.1013155603, -5549.14549480586, 12850.0442669800, -1032.47018165074, 12894.6 [...]
+-8713.6706907462, -5198.22051668395, -15905.2251588251, -13930.4912368747, -5864.362285584, 13064.6633074313, -2331.94024837146, 1014.90299428239, 5019.59987161607, 11237.3367045433, 17357.6416065636, 7332.82537533803, 4569.48956438354, 5564.99001180800, -18139.8360907496, -2146.42871935918, -9782.59667357726, -2121.15578859528, 2444.57048821955, -4985.7487168264, 97.3206458073875, -2703.45527246529, -12327.8571032346, 3102.71053269929, 10551.1953925899, 6524.32810789453, 12001.279676404 [...]
+9438.63877405911, -15635.0185655617, -10296.5384132283, -2975.45206287297, 6878.46507408415, -8677.04424698984, 2802.45446508826, -16614.7131274521, -6072.32909776122, -12426.0233490178, 2177.16431741198, 13041.5244991861, -10126.6958575779, -4514.64970217438, -10.7558047064345, -21101.3861982862, -11248.0072593854, -19948.2360277856, -3182.99068307007, -20226.0020136727, 2427.69678304389, 1360.52267616413, 12202.1945868734, 1371.59308392737, -6295.17064193479, 2897.28221611297, -5.78589 [...]
+12146.9709157522, 3419.47259367743, -20337.0773072263, 5111.52359976791, -8977.0200357896, -6422.30245017935, 4318.29969884791, 4162.9668928617, -12129.0915892092, -18109.5616489765, 6141.98049720759, -34.1717451695586, 779.465812695236, -18737.3761264471, 10017.1877057761, -9095.19644006553, 6683.0398931459, -887.114365985199, -683.908343083783, -5193.10589108439, 20343.7494927878, 8980.0397442374, 6795.58158352787, -14859.4456643654, -4838.30504101514, 5271.55729148941, 15503.765381904 [...]
+-7353.21838004456, -1512.03573281868, -2185.89630647107, -960.179404207387, 4457.62805598161, -2023.11153016572, -12627.1090467989, 18773.1785103617, -11523.0065955516, -23870.2792203502, 1312.05672574424, 1320.96220209472, 2433.44336210765, -13995.0810740828, 4866.84613045339, -586.757285383056, 1818.79235541812, 19799.3030953066, 4333.8461454049, -4422.75259910267, -3403.62831793632, -18212.6943794077, -5840.35766790584, -531.663724535112, 7416.48144328253, 5149.9226271697, 20482.71386 [...]
+-4998.67409429508, 1264.61770685664, -18357.0177528294, -11604.7698024561, 1134.80426884875, -27398.7678834671, 6742.87492301013, -11067.6879282551, 16726.5956240665, -3363.64638186875, -12521.0956562594, 2744.71104073036, -7629.61380714496, -10565.0831154413, -10201.8888622773, -12202.7842894319, 15924.3686914894, 10729.5550044811, 11958.8921213356, 5381.53596893535, 2661.31533275816, 18593.5101186880, 2425.57696662132, 1863.01356493846, -6785.81552968608, -11593.0177284289, 7461.952738 [...]
+-11025.6736715817, 6014.03687852895, -18889.5222387997, 1847.15229660679, -14866.5393305748, 4946.77841875075, 3626.74726861005, 5542.24052443965, -14168.6227203171, 1222.09926481039, 4804.57130841093, -5548.40688494516, -4879.65939785356, -1029.29688918066, 3782.34750143878, 6164.24138133457, -7465.26533516109, -10547.8251546169, 15202.4019853628, 15898.7101542034, -13407.9888965233, 7675.71351270146, 5123.3024851557, -19412.8027794916, 9503.7590375055, -21211.0384525695, -11392.8221538 [...]
+14658.6824708201, 5122.39833634247, -8518.04167143373, 14503.3405765460, -2942.50846872025, 2891.09573330558, -190.732527063043, 20674.2213073784, 17146.1885371219, -10704.4990426524, -1066.44644131443, 2825.81509389792, 2390.86758198328, -2229.11548980871, -2095.42000856783, 9513.2636408992, 4702.75538028875, 6748.66118406601, -2755.09366905192, -11105.2024255624, 268.706246650625, -4402.11415286564, 10177.3641366261, -3193.09261825134, -12684.9783021077, 20516.8677109852, 364.015802212 [...]
+8533.83052455945, 4117.18069835906, -10352.1103850476, -9411.51360968548, -6524.38705869287, 13137.5124213441, -483.665082972279, 10125.9335299969, -5371.71806752928, 4796.59535290021, 3454.09828004779, 4572.10282294253, -2924.70291257511, 1629.63944041792, -7787.78929015319, -23200.1485221491, 3479.93668115928, -3701.15658559918, 7807.28932320236, 213.096255054800, -490.909659950393, 3489.4057394281, 9780.88650205508, 9449.83532313473, -15664.5160840755, 702.608956636501, 2860.646938161 [...]
+8813.26544239377, 17482.2805154042, 5774.0748681677, 207.794667437618, -11466.9272040961, -5621.70335449657, -4206.53301944682, 17710.7511360614, -17527.8878991826, -5143.98037424335, -4104.46653129466, 19325.4632001611, -14701.7156407297, -4538.23014160962, 15347.7289830978, -7779.6786051323, -217.832518680309, -13361.3402191248, 20825.1908393175, 6482.43457820488, -17467.4153138004, 12329.2739944275, 11513.0610798460, -2777.27397059056, 4796.35937663484, -4860.729847705, 12082.47736131 [...]
+3430.19422109767, -5427.70488895583, -785.44082151192, -8191.23952123178, -6295.46492851804, 4277.7848867789, -9223.39947988749, -5184.94089660748, -11013.9017920701, 6771.3584705626, -4223.68011109127, -11870.7684866168, 3036.11911209150, -3526.75531535045, -2149.30041683721, -11819.8028365587, -2375.21520818194, -14518.1578906937, -5664.70974518275, 14494.3195099226, 11128.7302912142, 782.81146153158, -559.982167033163, 8051.93989878873, -4012.40954343323, 8223.53533811112, -15355.8052 [...]
+-1610.53007409165, -738.063265870923, 2590.75410102451, -282.173254491666, -6313.97851887284, -6935.24606763609, 7107.08900248227, 4316.45204873681, 10564.9081634414, 2652.36111747171, -9564.42913891164, 236.872192742043, -619.199869198186, 11423.3531740253, 65.565243415918, -12514.4804742725, -1386.47626820719, -11877.7510826223, 8397.242763608, 2039.43761636752, 15928.5787755479, -2400.254444914, 6388.73651664466, -424.005055568021, 19911.8999728674, 1250.33799524791, -10598.7977407027 [...]
+14850.4281054850, -22655.3786484361, 7104.05323326932, 18322.0835049855, -6172.65499471591, 13499.0448833569, -12778.4661741812, -5311.38119271861, -478.41683854305, -22988.3470156955, -21124.2696602939, -3658.17991077063, -11800.3768256880, -2245.83840518477, -5776.42253851612, 1601.77903550422, -5205.16543419375, 7976.38280938413, 3926.71172375434, -1955.71052218514, -9843.30909546573, 3527.48885930376, 11201.9988135750, 1316.98318476680, 20666.0837132362, 18187.0447330138, 1305.579409 [...]
+-11190.5683316264, -2636.14611645304, 6150.07112064363, 16184.7781576732, -5975.66351353959, -5183.97425292021, -5667.1798849215, -7885.48432610086, -5639.96381297931, -9940.32769130544, 11554.4059268827, 7017.44476349614, 3013.12022739268, -7338.8630096386, 7077.88836454011, 5412.77635936769, 11287.1371290887, 1441.01093992915, -4136.31375339502, -7441.8449626291, -10598.9568421524, -12922.6254455513, -9805.07901833328, 1150.23583745367, 6316.49179626317, -12773.4679522146, -11961.36961 [...]
+-5870.41537907038, -9927.13500716554, -3442.21768451800, 9765.02601584222, -9140.6196092155, 26.3800110138993, 13070.1953327834, 5116.08401791083, -16719.8491568124, 11902.9475036287, -11028.9216794389, 15004.2174818462, -177.526334743902, 7889.4501113725, -6140.25007761433, -1285.94087318803, 1245.5007288103, -7760.29851709451, 927.837287079741, -6905.72785076884, -3566.00492090209, 15443.8513610178, 10649.3067558611, 1924.12785442884, -6102.4116937142, 1853.38677878632, -21412.35788752 [...]
+482.06340398987, 12120.4033802553, 7555.66571257137, -5613.99204978149, -3001.43567894871, 5440.06786800723, -1090.83190651817, -12944.2556034859, -11048.9573353627, -1506.20219265348, 26498.2726109875, -9658.2141308633, -7360.5932548069, -10000.006907525, -12777.4373756801, 2212.17401639223, 8129.51265631062, 12061.4285075162, 397.856701429813, 11503.2740966737, -2984.04832173955, 3203.47422064507, -6581.57057067034, -14253.6409989036, -7643.9681745712, -7430.13496656641, 4146.606892372 [...]
+-2537.05938349784, -1465.99942364860, -2470.45154103644, -20525.509628751, 6943.82958454143, 5853.46056539891, -4500.25580098360, -2513.37729309002, -1912.20822849589, -4490.70350004655, -159.277035653726, -3572.12201603628, -6922.14755948786, -6628.46417013084, -10976.3706164424, 15839.9976221972, -7804.7700593732, -12911.5212432841, -10871.8765301729, -15716.936175009, -10280.1788217698, 5113.2831053663, 3448.57637219718, 6606.61527558723, 9862.46135718832, 4989.22044538076, 20211.7895 [...]
+13308.8440625384, -8160.02355981327, 3988.06566820463, -830.740203566894, 9681.6609213983, 9167.5091472659, -8511.41309482461, -1456.89043804962, 663.063601474843, 7719.08705530381, 9233.61779520286, 8823.53366628371, -3058.87975935143, -11503.5044666106, 11274.8928406209, -4874.1799029802, 14267.6648056421, -12655.0563868734, 26022.8681144270, -5828.73400599467, 7986.73601002787, 9851.11246258868, -9955.72769252753, 15155.6242561409, -863.325904780433, 9666.19287491073, -12189.766211280 [...]
+-9230.1639996571, 971.86452207063, -13340.0326630089, -3209.07185621985, 15963.6320251541, -6133.6876792706, -14984.8772905202, 1415.06263089043, -1283.87703549715, 13989.6072678798, -7263.98938936245, -1657.26132639592, -1838.8348060906, -2879.62273743954, -3214.07302350211, 18587.9888149788, -5694.22379291954, -6983.0368089603, -3820.12489285503, -2355.26154169147, 7848.1406790068, 11473.0097835837, -6195.9751455185, 1362.13840843185, -9661.5735307698, 11098.6685380514, -1184.601680623 [...]
+6297.47584773961, 8818.57852424291, 8135.05436365619, -3012.94639239714, -17510.7208855168, -13397.2209906607, -14281.1677498170, -3172.34531493497, -4231.0320770058, -6639.82233573385, -15819.1997498778, 9493.49724906679, -9740.95033680025, -2082.48952905011, -11723.9169410163, 13383.936174176, 1015.42524817391, -1502.06029481905, 8502.21258563911, -13501.2986810517, -10435.3173348235, 5598.04503539467, 322.642810727311, -6783.57829637709, 10559.0974303808, 8904.36366109595, -5499.43717 [...]
+3698.3925226274, -16597.8253925252, -7423.66707636866, -8587.72474924745, -1978.63956262880, 3563.6350376767, -3324.77845211623, 14148.2386141402, -500.26670086347, -6062.02233791842, 104.776493347424, 9207.45182177447, -21878.3505271206, 5811.65308511265, -3400.34841586050, -619.56563391704, 10640.1659807160, -14592.3234624580, 7531.64751686015, 20387.4529361875, 4697.1334219257, -3973.77275249724, -13660.1836134115, -10425.6915759907, 11086.2101910941, 6519.68682942295, 17305.221066891 [...]
+
+double y10[100] = {
+75588565.5513863, 25568173.6099986, -59314064.0088064, -22667004.7679739, 41188200.7149437, 34517029.9539581, 27467622.1830036, -107875739.531507, -120495887.061831, -11818914.4124746, 3242296.71409796, 86647431.4840694, 7493522.32082964, -5749817.43378039, 84663658.948486, 74224649.5253085, -106806248.945283, 149367479.289515, -35064436.6695613, 9741898.51202256, -63739989.4093866, 129450240.562464, -72633168.9540307, 5842005.31826342, 8537287.0044783, -98807863.8604586, -33692693.04107 [...]
+
+double lars10[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -88.37221952668400600, -100.91383790788444000, -135.92884972884937000, -179.21255350818063000, -293.65424884250899 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 55.150095 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -58.17498948691092400, -103.89919838546591000, -174.87234820635462000, -235.11498646210089000, -244.86930801475137000, -247.22786404500968000, -334.27422355035424000, -507.91746269195738000, -520.79916964103063000, -548.18648004881777000, -581.44376470230907000, -593.25846836247399000, -658.86129601597736000, -670.09914789996049000, -697.84397364710708000, -734.34 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -166.83879588268562000, -765.81852467728447000, -897.78345665946949000, -999.92514791965311000, -1088.56763073986210000, -1142.01904771443610000, -1181.76898012808420000, -1236.94437298094820000, -1285.90912434820050000, -1293.10374921000700000, -1294.51308816735920000, -1359.60860194143110000, -1497.96144119890120000, -1510.50177253298990000, -1535.34817584249480000, -1569.59043747951230000, -1581.75059242008800000, -1664.03035265961280000, -1677.04484401855580000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -83.98354897227456200, -153.74512378370710000, -204.59573118887323000, -242.47438870251935000, -299.61383773456834000, -350.27251093635539000, -356.87569204441724000, -358.68146006347797000, -434.58981888264657000, -599.88219939110274000, -613.09253746990203000, -632.91809041863792000, -658.50869205522361000, -669.16967417105593000, -727.06863338330481000, -736.60415768765540000, -764.05102266519134000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -72.48643604458246200, -82.29018005195690900, -84.49291146495505700, -177.55095477324681000, -361.64182033757720000, -377.80789748716467000, -410.60322044888215000, -456.78514337274419000, -474.41597892970640000, -609.86450225133706000, -626.07438438881809000, -665.76136408232890000, -713.8258755805027 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -15.69173905893314300, -61.53690252747143300, -119.20376655740527000, -289.46869239563745000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -571.53975635850509000, -690.81670646406383000, -776.99413751717339000, -851.15251302437514000, -890.83245241621898000, -924.56794517963817000, -966.07634822872058000, -992.65543835122583000, -995.08688791591817000, -995.60984903163990000, -1015.80489340015950000, -1054.84705660900430000, -1059.39234837673730000, -1070.09890855513030000, -1085.50910206773480000, -1089.89440583782650000, -1115.63682384746360000, -1119.45609676935990000, -1129.4906 [...]
+477.44910718827163000, 633.74140736011748000, 1210.37837993878040000, 1321.79022086435320000, 1391.85398953159010000, 1462.60708722163010000, 1510.03082398999460000, 1545.48693372865800000, 1597.51253263279140000, 1641.70553471978700000, 1648.89834604231420000, 1650.63426356643190000, 1702.36079187700600000, 1815.92026974619850000, 1825.45269729749570000, 1844.87930256270620000, 1875.87566196957940000, 1882.99727614342740000, 1947.27887506361300000, 1953.23854384317340000, 1970.687691281 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -74.90391996933625800, -250.65043409611783000, -263.47156027621861000, -283.26531613931655000, -311.56756860935957000, -327.70428079319760000, -429.55442413827245000, -445.06449824135797000, -494.32030246268585000, -554.49947075167142000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 108.48873106745464000, 184.81230767967440000, 252.21401183265917000, 283.38559741516156000, 313.29264808116460000, 356.15772284312561000, 394.36064859828565000, 400.11760668354140000, 401.40985608950308000, 465.49546238248092000, 594.66381316942181000, 602.69810483343167000, 617.64342605006811000, 636.18499954396816000, 645.17425729597062000, 703.32733114640541000, 712.81567147302007000, 742.33967458667473000, 778.38501732754 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -172.95210079905851000, -199.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.76862765758440620, 63.97605469059314500, 181.64246484678509000, 190.19603362348946000, 208.58843605601564000, 239.20517354541536000, 247.25184683354482000, 288.42057538416566000, 290.97902830739662000, 298.59566841420053000, 309.97382679129549000, 313.7551172 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 51.88154573663079100, 90.24416287296972400, 97.24855355344249100, 98.71605399470226400, 164.67573502510811000, 305.77659437513040000, 316.62244377071659000, 332.89388299290465000, 356.04801028624331000, 368.07180394260058000, 448.96566375338233000, 461.24120501181471000, 500.94471252636214000, 551.51781526429079000, 699.39 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 147.75898375397017000, 158.16218881941600000, 176.12239137705737000, 202.72738455872906000, 212.64817024477836000, 294.22654774584987000, 305.31703417345392000, 335.36066165855152000, 372.72789972154658000, 440.01241538 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.59552361345757190, 9.54916080064306170, 81.45717172355209400, 220.83578959308582000, 231.93791898458142000, 252.23624435689663000, 283.12605971584060000, 292.62859340088289000, 357.80041094545686000, 366.11076666446138000, 395.47388411492750000, 432.50411243673290000, 564.5335382 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -29.37484686679432900, -68.30228662871455500, -83.18425230084088200, -187.48734774815688000, -203.27914310841419000, -241.26334022203929000, -288.06003786314267000, -389.6387477 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -27.11729524090719300, -63.88085964982631300, -93.87493988018265200, -98.01650380458005400, -98.64207186404979700, -122.36063478685584000, -160.20447729417998000, -163.10366991551808000, -169.91262791320347000, -175.69549415146506000, -176.27862036337569000, -176.50854597754119000, -178.33155773823657000, -181.49507910095704000, -184.813596628 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 12.89014676545617100, 42.75179847485251400, 86.81617556560947000, 103.49661958131935000, 222.36792391523156000, 240.10517186496142000, 285.42933346333029000, 341.14619751605119000, 487.1847521872010 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -30.12046700076127700, -41.63175957297011100, -128.67971194514217000, -138.11315445547123000, -169.45603813481443000, -208.72149789655589000, -298.503503491 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -18.26420111077785800, -135.57566256832058000, -154.26446618171639000, -207.08561095041253000, -273.12112611518683000, -476.68249160789 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.43835440265021840, -6.39137663893324340, -3.00935 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -80.23368904880649700, -132.62451072957901000, -174.79150694045578000, -238.43830268280291000, -297.08804785040581000, -306.28757715068855000, -308.33988704602308000, -391.90324622715463000, -570.81981287664757000, -583.28574461093240000, -607.28467788912417000, -641.33545780226893000, -654.21438679901371000, -742.13743815353200000, -755.64004096315898000, -796.91773180332223000, -849 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -43.02490027649300700, -97.35657327344350200, -243.12115522035504000, -2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq10[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -858.41902351662566000, -852.20612530981668000, -837.27335785646710000, -824.02051833552673000, -800.2604243946045 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1431.6982 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1578.21337013361740000, -1503.16084398998670000, -1565.75499297290710000, -1606.46682333240780000, -1696.79307212760680000, -1754.31980931347270000, -1602.82155285004340000, -1536.03185059368160000, -1481.55897296148280000, -1570.05963810395970000, -1415.25039097876490000, -1381.94420572222410000, -1230.50301824328270000, -1343.29069230682830000, -1253.5679375918 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -2767.21517372562450000, -2579.02611207108700000, -2577.21536273556060000, -2661.26980509386980000, -2578.55068839012120000, -2538.63649479766350000, -2398.20458790843900000, -2318.23351585957470000, -2400.53331202600660000, -2364.01849754489790000, -2195.06552937681140000, -2308.26102826627400000, -2317.12690569281810000, -2445.80066682890720000, -2462.41520937552880000, -2428.09181391824900000, -2393.49678949591450000, -2380.98944619435860000, -2456.664083357655300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1449.98423541290050000, -1326.36079560397050000, -1533.25733674775420000, -1401.64485709545740000, -1419.39319360034320000, -1503.45680963457380000, -1339.75446201186380000, -1512.54780948903070000, -1540.82041139428930000, -1578.55246292314610000, -1598.36272445369630000, -1372.64755272296840000, -1300.10085561588290000, -1380.83919909986660000, -1231.58134942156060000, -1307.81958208063770000, -1313.80 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1722.55373216666860000, -1541.57044108847300000, -1492.01460165595770000, -1533.70798396342500000, -1451.61496587206330000, -1583.52676410198300000, -1634.25971483760550000, -1614.63052219149560000, -1651.35523542537930000, -1790.11891984559840000, -1597.11010397656950000, -1460.68456429528780000, -14 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -955.68864955109711000, -979.80743709918158000, -978.28120185934870000, -1043.191036839917600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -2301.68215168123520000, -2208.77691496675520000, -2178.67853183944270000, -2097.67358929781180000, -1927.61873032191970000, -1956.94843368959050000, -1779.52928865256290000, -1597.69673662740980000, -1357.00641098714500000, -1329.77637934990000000, -1310.11208492838270000, -1286.00958230392850000, -1398.39506300653370000, -1469.58123443884010000, -1471.86419981210820000, -1382.63357534594640000, -1339.94788926444770000, -1348.24557213761930000,  [...]
+2919.08982390770460000, 3069.73840227599610000, 2955.95086526401560000, 2739.65629751523600000, 2531.44807986538220000, 2651.88917274551890000, 2749.15266444721100000, 2630.52209682415740000, 2617.07419478192290000, 2647.70653905054090000, 2719.54315035671240000, 2759.86689772253980000, 2456.18380889008130000, 2488.28812960116560000, 2536.41229726026040000, 2569.72326047859220000, 2652.99773110952950000, 2358.39773369621250000, 2507.40783944823580000, 2310.24615270692170000, 2320.1910354 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1166.49658589059230000, -1291.21798334558840000, -1219.71305186103400000, -1021.80836810126880000, -1021.14460996873910000, -1404.90393923090070000, -1317.04347656736290000, -1374.17896309762590000, -1480.90536948110570000, -1451.003319573 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1489.15428870960300000, 1426.22279008634840000, 1385.16284234315390000, 1097.85942695797330000, 1228.51436406391280000, 1196.19777606737970000, 1264.00470677765200000, 1257.03668689503320000, 1227.14333285133380000, 1399.43026645107420000, 1359.44936175789830000, 1201.92183422346510000, 1175.28206826775730000, 1101.04817168459340000, 1245.24850226911120000, 1210.05431956607300000, 1281.20458994911130000, 1333.7002472341612000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -938.56992989136461000, -850.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1131.90268541519590000, 970.53970506914038000, 878.32682671631812000, 828.14914714200779000, 894.84429974253021000, 1006.80959043061410000, 784.40424930461722000, 647.15149800360507000, 444.24042492153484000, 451.15562574350372000, 479.47704638687031000, 330.49 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1068.62015365879940000, 963.52340495617341000, 1139.84708049513460000, 1036.43305809670440000, 1125.92187659916520000, 1141.21265488742640000, 1125.54133731038680000, 940.01253526304197000, 936.55435540686210000, 1170.71525895357670000, 1153.84847130687720000, 1196.59442585042280000, 1296.19896207823600000, 1304.9177465109 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1022.61675472258960000, 934.06722159918513000, 846.25204754324523000, 869.75176246713318000, 874.90618356854452000, 1005.07402001530930000, 969.68080791771661000, 937.12921877464930000, 929.39682180497527000, 737.864968 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1138.18376347548660000, 1257.90231883935530000, 1129.38974156190760000, 1046.07472838452100000, 1059.97101217483490000, 1009.60575390687030000, 1057.57692060534600000, 926.96636451590041000, 925.68645114230060000, 863.93377223553694000, 983.61194531816056000, 984.15251764269351000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1125.40680795423280000, -1044.26762942946060000, -1076.62381770078920000, -1096.35062769793080000, -1149.26981973234610000, -1002.08010582791080000, -985.20193497153218000, -83 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -856.96634188749852000, -784.34773797165190000, -776.65441651127298000, -714.48532226291161000, -498.37333605658341000, -468.01690141917641000, -384.27193403828142000, -379.33493054555987000, -423.96792975040967000, -320.68003629227076000, -215.20497346059199000, -178.51204306397685000, -287.53713504287549000, -244.85985377054496000, -234.2503 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 974.27941917413887000, 1156.94738331575060000, 1191.57171961633320000, 1216.99287529989190000, 1258.17384209526900000, 1302.63611319410620000, 1193.26429251000880000, 1171.17400427579900000, 1133.66 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -785.28268885520072000, -810.06341316466035000, -887.18728227746521000, -703.21347773459343000, -797.24846755871306000, -793.66869479213858000, -695.9470956 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1237.48351753834730000, -1157.78961680190470000, -1273.79733576419290000, -1265.08382000308070000, -1256.86841254903170000, -1377.8002 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 118.24934665252654000, -67.61230779888158800, 81.40 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1428.87413245757440000, -1501.52995361426610000, -1465.19459820302810000, -1485.74413335875370000, -1632.17957266249980000, -1675.63091257760330000, -1619.74384471015760000, -1609.69198224002050000, -1630.15674597956010000, -1513.03567360612080000, -1502.73097669645840000, -1495.03611969562730000, -1513.94205364255960000, -1508.27033665051860000, -1564.49907672608330000, -1623.702595 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -904.80606076690901000, -906.74884869968957000, -888.38630246712091000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso10[2700] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -88.37221952668400600, -100.91383790788444000, -135.92884972884937000, -179.21255350818063000, -240.76529707038586 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -58.17498948691092400, -103.89919838546591000, -174.87234820635462000, -235.11498646210089000, -244.86930801475137000, -247.22786404500968000, -334.27422355035424000, -507.91746269195738000, -520.79916964103063000, -548.18648004881777000, -581.44376470230907000, -593.25846836247399000, -658.86129601597736000, -670.09914789996049000, -697.84397364710708000, -734.34 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -166.83879588268562000, -765.81852467728447000, -897.78345665946949000, -999.92514791965311000, -1088.56763073986210000, -1142.01904771443610000, -1181.76898012808420000, -1236.94437298094820000, -1285.90912434820050000, -1293.10374921000700000, -1294.51308816735920000, -1359.60860194143110000, -1497.96144119890120000, -1510.50177253298990000, -1535.34817584249480000, -1569.59043747951230000, -1581.75059242008800000, -1664.03035265961280000, -1677.04484401855580000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -83.98354897227456200, -153.74512378370710000, -204.59573118887323000, -242.47438870251935000, -299.61383773456834000, -350.27251093635539000, -356.87569204441724000, -358.68146006347797000, -434.58981888264657000, -599.88219939110274000, -613.09253746990203000, -632.91809041863792000, -658.50869205522361000, -669.16967417105593000, -727.06863338330481000, -736.60415768765540000, -764.05102266519134000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -72.48643604458246200, -82.29018005195690900, -84.49291146495505700, -177.55095477324681000, -361.64182033757720000, -377.80789748716467000, -410.60322044888215000, -456.78514337274419000, -474.41597892970640000, -609.86450225133706000, -626.07438438881809000, -665.76136408232890000, -713.8258755805027 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -15.69173905893314300, -61.53690252747143300, -119.20376655740527000, -210.78117011772196000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -571.53975635850509000, -690.81670646406383000, -776.99413751717339000, -851.15251302437514000, -890.83245241621898000, -924.56794517963817000, -966.07634822872058000, -992.65543835122583000, -995.08688791591817000, -995.60984903163990000, -1015.80489340015950000, -1054.84705660900430000, -1059.39234837673730000, -1070.09890855513030000, -1085.50910206773480000, -1089.89440583782650000, -1115.63682384746360000, -1119.45609676935990000, -1129.4906 [...]
+477.44910718827163000, 633.74140736011748000, 1210.37837993878040000, 1321.79022086435320000, 1391.85398953159010000, 1462.60708722163010000, 1510.03082398999460000, 1545.48693372865800000, 1597.51253263279140000, 1641.70553471978700000, 1648.89834604231420000, 1650.63426356643190000, 1702.36079187700600000, 1815.92026974619850000, 1825.45269729749570000, 1844.87930256270620000, 1875.87566196957940000, 1882.99727614342740000, 1947.27887506361300000, 1953.23854384317340000, 1970.687691281 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -74.90391996933625800, -250.65043409611783000, -263.47156027621861000, -283.26531613931655000, -311.56756860935957000, -327.70428079319760000, -429.55442413827245000, -445.06449824135797000, -494.32030246268585000, -554.49947075167142000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 108.48873106745464000, 184.81230767967440000, 252.21401183265917000, 283.38559741516156000, 313.29264808116460000, 356.15772284312561000, 394.36064859828565000, 400.11760668354140000, 401.40985608950308000, 465.49546238248092000, 594.66381316942181000, 602.69810483343167000, 617.64342605006811000, 636.18499954396816000, 645.17425729597062000, 703.32733114640541000, 712.81567147302007000, 742.33967458667473000, 778.38501732754 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -93.02270713422228700, -170.87 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.76862765758440620, 63.97605469059314500, 181.64246484678509000, 190.19603362348946000, 208.58843605601564000, 239.20517354541536000, 247.25184683354482000, 288.42057538416566000, 290.97902830739662000, 298.59566841420053000, 309.97382679129549000, 312.0076030 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 51.88154573663079100, 90.24416287296972400, 97.24855355344249100, 98.71605399470226400, 164.67573502510811000, 305.77659437513040000, 316.62244377071659000, 332.89388299290465000, 356.04801028624331000, 368.07180394260058000, 448.96566375338233000, 461.24120501181471000, 500.94471252636214000, 551.51781526429079000, 631.05 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 147.75898375397017000, 158.16218881941600000, 176.12239137705737000, 202.72738455872906000, 212.64817024477836000, 294.22654774584987000, 305.31703417345392000, 335.36066165855152000, 372.72789972154658000, 408.91703975 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.59552361345757190, 9.54916080064306170, 81.45717172355209400, 220.83578959308582000, 231.93791898458142000, 252.23624435689663000, 283.12605971584060000, 292.62859340088289000, 357.80041094545686000, 366.11076666446138000, 395.47388411492750000, 432.50411243673290000, 503.5164595 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -29.37484686679432900, -68.30228662871455500, -83.18425230084088200, -187.48734774815688000, -203.27914310841419000, -241.26334022203929000, -288.06003786314267000, -342.6943934 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -27.11729524090719300, -63.88085964982631300, -93.87493988018265200, -98.01650380458005400, -98.64207186404979700, -122.36063478685584000, -160.20447729417998000, -163.10366991551808000, -169.91262791320347000, -175.69549415146506000, -176.27862036337569000, -176.50854597754119000, -178.33155773823657000, -181.49507910095704000, -184.813596628 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 12.89014676545617100, 42.75179847485251400, 86.81617556560947000, 103.49661958131935000, 222.36792391523156000, 240.10517186496142000, 285.42933346333029000, 341.14619751605119000, 419.6933885516945 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -30.12046700076127700, -41.63175957297011100, -128.67971194514217000, -138.11315445547123000, -169.45603813481443000, -208.72149789655589000, -257.010967488 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -18.26420111077785800, -135.57566256832058000, -154.26446618171639000, -207.08561095041253000, -273.12112611518683000, -382.60710054732 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.43835440265021840, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -80.23368904880649700, -132.62451072957901000, -174.79150694045578000, -238.43830268280291000, -297.08804785040581000, -306.28757715068855000, -308.33988704602308000, -391.90324622715463000, -570.81981287664757000, -583.28574461093240000, -607.28467788912417000, -641.33545780226893000, -654.21438679901371000, -742.13743815353200000, -755.64004096315898000, -796.91773180332223000, -849 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -43.02490027649300700, -97.35657327344350200, -175.75640741447936000, -2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq10[2700] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -858.41902351662566000, -852.20612530981668000, -837.27335785646710000, -824.02051833552673000, -800.2604243946045 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1578.21337013361740000, -1503.16084398998670000, -1565.75499297290710000, -1606.46682333240780000, -1696.79307212760680000, -1754.31980931347270000, -1602.82155285004340000, -1536.03185059368160000, -1481.55897296148280000, -1570.05963810395970000, -1415.25039097876490000, -1381.94420572222410000, -1230.50301824328270000, -1343.29069230682830000, -1253.5679375918 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -2767.21517372562450000, -2579.02611207108700000, -2577.21536273556060000, -2661.26980509386980000, -2578.55068839012120000, -2538.63649479766350000, -2398.20458790843900000, -2318.23351585957470000, -2400.53331202600660000, -2364.01849754489790000, -2195.06552937681140000, -2308.26102826627400000, -2317.12690569281810000, -2445.80066682890720000, -2462.41520937552880000, -2428.09181391824900000, -2393.49678949591450000, -2380.98944619435860000, -2456.664083357655300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1449.98423541290050000, -1326.36079560397050000, -1533.25733674775420000, -1401.64485709545740000, -1419.39319360034320000, -1503.45680963457380000, -1339.75446201186380000, -1512.54780948903070000, -1540.82041139428930000, -1578.55246292314610000, -1598.36272445369630000, -1372.64755272296840000, -1300.10085561588290000, -1380.83919909986660000, -1231.58134942156060000, -1307.81958208063770000, -1313.80 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1722.55373216666860000, -1541.57044108847300000, -1492.01460165595770000, -1533.70798396342500000, -1451.61496587206330000, -1583.52676410198300000, -1634.25971483760550000, -1614.63052219149560000, -1651.35523542537930000, -1790.11891984559840000, -1597.11010397656950000, -1460.68456429528780000, -14 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -955.68864955109711000, -979.80743709918158000, -978.28120185934870000, -1043.191036839917600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -2301.68215168123520000, -2208.77691496675520000, -2178.67853183944270000, -2097.67358929781180000, -1927.61873032191970000, -1956.94843368959050000, -1779.52928865256290000, -1597.69673662740980000, -1357.00641098714500000, -1329.77637934990000000, -1310.11208492838270000, -1286.00958230392850000, -1398.39506300653370000, -1469.58123443884010000, -1471.86419981210820000, -1382.63357534594640000, -1339.94788926444770000, -1348.24557213761930000,  [...]
+2919.08982390770460000, 3069.73840227599610000, 2955.95086526401560000, 2739.65629751523600000, 2531.44807986538220000, 2651.88917274551890000, 2749.15266444721100000, 2630.52209682415740000, 2617.07419478192290000, 2647.70653905054090000, 2719.54315035671240000, 2759.86689772253980000, 2456.18380889008130000, 2488.28812960116560000, 2536.41229726026040000, 2569.72326047859220000, 2652.99773110952950000, 2358.39773369621250000, 2507.40783944823580000, 2310.24615270692170000, 2320.1910354 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1166.49658589059230000, -1291.21798334558840000, -1219.71305186103400000, -1021.80836810126880000, -1021.14460996873910000, -1404.90393923090070000, -1317.04347656736290000, -1374.17896309762590000, -1480.90536948110570000, -1451.003319573 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1489.15428870960300000, 1426.22279008634840000, 1385.16284234315390000, 1097.85942695797330000, 1228.51436406391280000, 1196.19777606737970000, 1264.00470677765200000, 1257.03668689503320000, 1227.14333285133380000, 1399.43026645107420000, 1359.44936175789830000, 1201.92183422346510000, 1175.28206826775730000, 1101.04817168459340000, 1245.24850226911120000, 1210.05431956607300000, 1281.20458994911130000, 1333.7002472341612000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -938.56992989136461000, -921.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1131.90268541519590000, 970.53970506914038000, 878.32682671631812000, 828.14914714200779000, 894.84429974253021000, 1006.80959043061410000, 784.40424930461722000, 647.15149800360507000, 444.24042492153484000, 451.15562574350372000, 479.47704638687031000, 330.49 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1068.62015365879940000, 963.52340495617341000, 1139.84708049513460000, 1036.43305809670440000, 1125.92187659916520000, 1141.21265488742640000, 1125.54133731038680000, 940.01253526304197000, 936.55435540686210000, 1170.71525895357670000, 1153.84847130687720000, 1196.59442585042280000, 1296.19896207823600000, 1304.9177465109 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1022.61675472258960000, 934.06722159918513000, 846.25204754324523000, 869.75176246713318000, 874.90618356854452000, 1005.07402001530930000, 969.68080791771661000, 937.12921877464930000, 929.39682180497527000, 737.864968 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1138.18376347548660000, 1257.90231883935530000, 1129.38974156190760000, 1046.07472838452100000, 1059.97101217483490000, 1009.60575390687030000, 1057.57692060534600000, 926.96636451590041000, 925.68645114230060000, 863.93377223553694000, 983.61194531816056000, 984.15251764269351000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1125.40680795423280000, -1044.26762942946060000, -1076.62381770078920000, -1096.35062769793080000, -1149.26981973234610000, -1002.08010582791080000, -985.20193497153218000, -83 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -856.96634188749852000, -784.34773797165190000, -776.65441651127298000, -714.48532226291161000, -498.37333605658341000, -468.01690141917641000, -384.27193403828142000, -379.33493054555987000, -423.96792975040967000, -320.68003629227076000, -215.20497346059199000, -178.51204306397685000, -287.53713504287549000, -244.85985377054496000, -234.2503 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 974.27941917413887000, 1156.94738331575060000, 1191.57171961633320000, 1216.99287529989190000, 1258.17384209526900000, 1302.63611319410620000, 1193.26429251000880000, 1171.17400427579900000, 1133.66 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -785.28268885520072000, -810.06341316466035000, -887.18728227746521000, -703.21347773459343000, -797.24846755871306000, -793.66869479213858000, -695.9470956 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1237.48351753834730000, -1157.78961680190470000, -1273.79733576419290000, -1265.08382000308070000, -1256.86841254903170000, -1377.8002 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 118.24934665252654000, -67.61230779888158800, 0.000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1428.87413245757440000, -1501.52995361426610000, -1465.19459820302810000, -1485.74413335875370000, -1632.17957266249980000, -1675.63091257760330000, -1619.74384471015760000, -1609.69198224002050000, -1630.15674597956010000, -1513.03567360612080000, -1502.73097669645840000, -1495.03611969562730000, -1513.94205364255960000, -1508.27033665051860000, -1564.49907672608330000, -1623.702595 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -904.80606076690901000, -906.74884869968957000, -888.38630246712091000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso10[1000] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 176.27790809051444000, 231.60168595790489000, 296.56086628335430000, 352.35709040526609000, 417.54176130077360000, 467.46669561421430000, 535.41775498393224000, 542.01881204895290000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.66925827886283070, 4.61436223837497120, 150.44529086557932000, 191.50301868775614000, 239.18859323320237000, 282.71813909333991000, 336.07120334076609000, 382.51781761657941000, 433.77003429785231000, 438.44878477482087000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 44.70915131597193700, 96.59576870657237200, 145.96194669159735000, 198.52313165619367000, 235.29873182137536000, 287.14495885391284000, 292.24024051114736000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+1155.67123723413260000, 1335.11645664149840000, 1422.39469701753430000, 1428.88032689236710000, 1583.83815890813160000, 1661.62811341907400000, 2070.03406385665360000, 2165.12348972253860000, 2231.10628169494070000, 2334.83274322021230000, 2335.85238260134930000, 2336.61657608107230000, 2414.30342331196200000, 2442.41496623200740000, 2486.49046551615630000, 2523.76567035808060000, 2574.46542034581760000, 2616.08051302443440000, 2672.73031537322910000, 2676.69103079118580000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 191.41184947898915000, 285.59039791370509000, 292.37296815591355000, 449.83149547785035000, 533.16498780914867000, 919.92593219134460000, 990.46694124781561000, 1035.06251464781370000, 1112.90553986966210000, 1113.62246221885970000, 1114.37910795788280000, 1169.14606440673740000, 1189.48232813040480000, 1212.81747414737380000, 1249.58420253136520000, 1292.11850790797350000, 1319.99954317471790000, 1362.18069611164200000, 1365.52087316877580000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.00979962933483410, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 75.46934732102467100, 174.39191547995947000, 181.53448081952740000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 68.34462539354098000, 124.49261958954592000, 189.01351928698020000, 238.35296786614722000, 300.75727705084722000, 306.29177351211638000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.27367614551798860, 107.69996925388492000, 138.14027458899977000, 185.33724059123369000, 243.02246301063917000, 303.79266236294598000, 348.44509760884335000, 417.58211679529256000, 423.52914734748379000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.60804683078806670, 204.57031074794637000, 323.85551014308879000, 858.91750304542097000, 972.31403059160630000, 1044.87790949146870000, 1217.25187445258460000, 1219.75497953709650000, 1221.33675254208220000, 1366.89537740729340000, 1421.24121435824100000, 1479.06989949244390000, 1534.07797552969170000, 1604.38463710497920000, 1662.42388234194940000, 1739.93105897185520000, 1747.11303399601570000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 193.12534699504118000, 196.32328283132196000, 198.52406693680771000, 393.27800682090259000, 454.29253313788621000, 504.07547835603270000, 556.02993732509117000, 620.10685167315069000, 659.92589102506497000, 701.84331810249694000, 705.42874303778353000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 50.14536238796237900, 86.90993500493840400, 144.08198841970412000, 148.58524116067224000, 
+0.00000000000000000, 0.00000000000000000, 103.11814915523289000, 109.36477427892510000, 275.05530068652166000, 371.47295570465059000, 838.18587712968326000, 943.61637588642122000, 1024.31272872636650000, 1204.07012404749090000, 1206.04661461422070000, 1207.21722308377570000, 1326.67012070100710000, 1359.61744951236690000, 1394.17952084866330000, 1429.51137431327200000, 1476.77268467171170000, 1507.30322574419780000, 1548.77651319501680000, 1552.84144207324950000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 84.19660049743735900, 274.63566545442046000, 277.49341052444669000, 279.50803557847127000, 429.99817420465649000, 482.10551144901763000, 548.63959984991095000, 593.20279519982432000, 640.58290140430279000, 696.67951615661309000, 763.70698518990071000, 769.88412097866831000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 431.53161908241361000, 520.55352669735271000, 582.86884489047361000, 711.98495290066012000, 713.96140700453736000, 715.11846906045696000, 816.04752409267212000, 847.35481291751989000, 882.18600539192801000, 908.61535064924215000, 941.88637119302427000, 983.85605748589023000, 1032.24201055987690000, 1035.54567997892310000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 240.10492996916074000, 368.25054511055555000, 959.26360340539793000, 1096.36389539393280000, 1187.21293308000300000, 1373.15999262560310000, 1375.39586997810870000, 1376.92604862561190000, 1514.13759247374700000, 1564.56028818834530000, 1619.23538573430010000, 1672.27499695704550000, 1727.66870523099330000, 1746.17936628463390000, 1773.99261491003360000, 1776.52626107461700000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 56.09950964129414800, 59.73588940188989200, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 92.33418187197038700, 152.91062606341802000, 253.54116018688177000, 254.61378243516100000, 255.36947136930212000, 357.73694205122928000, 388.66360458965181000, 439.18422431789293000, 480.58203144651117000, 528.33837062729117000, 566.17535561524892000, 608.49568610097583000, 613.00252329630280000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 73.51971347411863200, 406.82114244494716000, 472.79166895283896000, 528.08475227183760000, 656.68138421936487000, 658.17126621419163000, 659.26690068636299000, 772.35317213786357000, 808.76800631900960000, 845.28613376962767000, 871.76100942681637000, 904.45117676803136000, 945.45954136706939000, 1003.48563697082930000, 1008.18384639116790000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 64.93931614621347100, 142.50098097112914000, 184.35881088624245000, 243.27288173071889000, 248.53019121065628000};
+
+double nnlassolsq10[1000] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 548.95184066326885000, 535.22981841636397000, 546.45506487983346000, 534.84918200049276000, 532.51730947275382000, 539.40586228493760000, 541.09181388221214000, 542.01881204895290000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 520.03505861450458000, 537.02791524631812000, 458.75043386926671000, 416.83617022192266000, 422.63223239159908000, 425.08974210450532000, 430.17765082649669000, 449.44491069397549000, 438.04970408982240000, 438.44878477482087000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 290.08205680355474000, 296.20057599855153000, 307.42335768000731000, 291.23282813622609000, 288.29040954876371000, 291.47422978161984000, 292.24024051114736000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+2919.08982390770460000, 2678.67497942834600000, 2636.37157962303440000, 2692.18463021740310000, 2744.22119491400280000, 2597.04717625765940000, 2668.52312075101550000, 2703.36887481314220000, 2699.89702302096290000, 2592.62374126040280000, 2533.48276878509520000, 2545.79149639073600000, 2578.54330555431620000, 2596.69682488957010000, 2656.04635455555440000, 2645.68126954594570000, 2663.89183712357180000, 2676.04564125933800000, 2677.46069512130730000, 2676.69103079118580000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 1624.56801033535630000, 1595.54554990230370000, 1613.51684160388090000, 1628.94068668190900000, 1535.24472663512480000, 1486.69581543831100000, 1389.75815831574570000, 1351.90257686870700000, 1306.36852768708510000, 1252.57908095757330000, 1321.48806185800090000, 1284.93038052396420000, 1301.09187494046390000, 1302.58642726265360000, 1369.83673340599880000, 1367.14235952224910000, 1360.17462744051000000, 1365.70291266545970000, 1365.52087316877580000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.00979962933483410, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 184.21665024929831000, 182.65216165285494000, 181.53448081952740000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 331.26243478597900000, 308.13524166586029000, 302.81827904642734000, 309.44848083155347000, 305.96817043653965000, 306.29177351211638000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 349.90411242655716000, 332.69869774724845000, 305.20285448945930000, 366.90123102682179000, 431.69288039322066000, 410.98177426706917000, 412.78687443003975000, 423.35520587667111000, 423.52914734748379000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1489.54249062773620000, 1679.49846900670560000, 1758.25215081759140000, 1643.01172882501900000, 1614.18516485545500000, 1560.42557830163490000, 1645.65226341836980000, 1704.91633526936200000, 1654.29941323594400000, 1674.62483560205850000, 1719.50220838978320000, 1701.53349670994500000, 1713.99227992299550000, 1728.39457446768640000, 1746.05533812578390000, 1746.40307411505750000, 1747.11303399601570000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 673.09907034990545000, 816.15937979541638000, 800.92234969952619000, 805.01262204776083000, 789.15264921435676000, 695.58758082921190000, 725.95681023042903000, 733.12849082734806000, 717.30300224209986000, 705.34351298257411000, 705.42874303778353000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 138.59392628545885000, 139.88572262372185000, 148.85597724960530000, 148.58524116067224000, 
+0.00000000000000000, 0.00000000000000000, 1537.41664912694250000, 1326.11450442326490000, 1515.80882420444210000, 1530.88888627272400000, 1522.11953648211190000, 1540.39650035212030000, 1597.63953014402480000, 1650.82052566653760000, 1589.13753991336810000, 1527.63599114457880000, 1579.20874902059180000, 1540.43908357478860000, 1527.13780442223860000, 1545.07087569824810000, 1560.13423258070340000, 1551.29610651539290000, 1552.23962146564550000, 1552.84144207324950000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 682.39175993890842000, 747.93318181807558000, 831.39243821210061000, 830.95089175416399000, 748.15348012331879000, 768.08116431949918000, 804.59237845624307000, 738.95514413661647000, 724.15398657613844000, 777.51174505838173000, 769.30392231825692000, 769.88412097866831000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1063.90965237995810000, 1024.45425497899810000, 1025.60312967094430000, 1032.87674712138100000, 1097.04526493484470000, 1031.82931488964820000, 1029.42439166018330000, 1019.17557434511400000, 1016.17958237279230000, 995.05751714712790000, 1000.57123947125330000, 1044.33213620008110000, 1036.28234120575280000, 1035.54567997892310000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2038.10173963830490000, 1909.19309966078620000, 1825.35002426227200000, 1872.40811677226110000, 1832.67194523307760000, 1835.29354425765290000, 1808.76212947110250000, 1795.76630982086840000, 1804.22025906635710000, 1841.29028609343620000, 1829.56731443134160000, 1845.75106530689780000, 1825.37452910920910000, 1772.85224125253560000, 1776.31508070110180000, 1776.52626107461700000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 60.78393877046207200, 59.73588940188989200, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 614.98374912037923000, 583.29065895564031000, 503.63786110138074000, 462.51350961151445000, 462.21652878610723000, 574.15480336922838000, 558.39541162969670000, 633.53411784079822000, 615.98138022413718000, 612.57307183179796000, 620.69643224355707000, 612.02952427801097000, 613.00252329630280000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 957.58941001119126000, 895.25001492481169000, 846.21206897661614000, 920.92786703661488000, 976.28212646856673000, 946.94586579604629000, 959.16379785431729000, 1011.43194246330150000, 1008.62001430566770000, 985.76925174919813000, 958.35209169875372000, 962.11151098855714000, 1004.55040681042710000, 1008.33094015148420000, 1008.18384639116790000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 277.33561745134392000, 279.30760755778994000, 244.67371052803227000, 248.19233274457557000, 248.53019121065628000};
+
+
+
+// Data from file x57.txt and y57.txt
+double x11[5000] = {
+1388.82532650844, 438.859961664316, -8669.81818704611, 3434.16937000454, 7414.23186104484, -19140.5684646496, 2069.96407204394, -162.121503736962, 19271.4657719447, -10790.4244827602, -5750.93976073734, -9533.33351678119, -7395.18838330348, 2452.7699918508, -15643.8579547883, 1498.20071844108, 4466.73694772578, -3468.85906634184, 954.865058422958, 8058.85414095095, -8840.64978576016, -10337.5535209899, 14281.7599851068, -1429.70416502826, -7416.22885489333, 2721.86638125007, -3316.012850 [...]
+-3012.04697738061, -5254.2123690782, -6633.12787147216, 738.34638485865, 7748.54020984567, -21335.1292882335, 6548.03474380809, 8346.28036633934, 10118.3350182887, 3383.06827793618, -5624.72138757354, -5822.0853672962, -27939.2558477613, 4114.3745972831, -8028.10189466721, -13864.8550875358, 13981.3852490292, -4546.30643263383, 14418.3588943921, 5600.54262400599, 3987.93783266056, -14014.9830115173, 4910.39809087112, 7494.62522162299, -10958.0127417206, 2963.71883857249, 7130.552036087,  [...]
+-4584.40241650675, 481.219667317723, 17098.4148463489, -16173.2665574928, -5477.59611398234, 14215.2826950894, -8761.64627021149, 22170.0099569045, -1055.45283524993, 2991.57045966811, -1255.31849042502, -4103.87013396772, -2266.27818413639, -6204.33050246315, -7648.47276590993, 12509.9774879137, 10236.5337097306, -9877.90339982069, 7066.71760219645, 18604.7296361984, 18233.9493450080, 15235.7665490633, -5318.5007478009, -977.91308391429, -8678.56690670403, 13727.0567449660, -14863.71786 [...]
+7648.94651530344, -5451.09452641615, -7733.43416431417, 12920.2931731429, -39.1628519386882, 7633.21830269176, -10121.5507698959, -4157.83545870968, 4001.79305570725, 13865.4757383741, -18508.3526476503, 460.320280097467, -521.37134335736, 13224.9011602809, 7913.83801545694, -19901.9905969238, -11725.9237615916, -8552.83094034068, -4026.57215124318, -9961.8003816137, -8253.48644756014, 22542.5660942046, 8339.19881846949, -17010.0362623646, 15772.4193691524, 1662.74169350030, 5018.2831382 [...]
+14624.5355129324, -9836.39429478025, 1924.07599616908, 3704.82460489952, -905.873882563516, 2025.8733436167, 15606.9907272253, 4886.7708378542, 1827.06295809562, 14620.9813136687, -1381.52236498655, -1149.90565706863, -2628.78535223593, 928.795599147693, 12517.9304340298, -33365.8508904694, -4162.07222774869, -13288.7410643796, -14433.4747460811, 8347.20431539885, -11107.576740569, -8880.72289085714, -8832.30693506106, 14490.8895881088, -16884.5979664229, 4601.43665555699, -6239.72008010 [...]
+13890.7042074192, -13207.2557709268, 1878.46861655858, 11875.4033633474, 5575.4947834855, -23305.6206985655, 2222.47989022207, 10145.9276683990, -13358.8730001793, -10766.6927649930, -669.40192621652, 757.08894210193, -4944.2254948612, 1171.62680125949, 68.9238727386435, -11358.2058298802, -14597.4106475152, -7326.27872313295, -610.914268998532, 6685.78923158902, 12856.6582620085, 4927.88780250809, 1119.19588677232, 7165.16726743263, 6697.5880088522, -4590.48579400720, 13184.9155777395,  [...]
+3018.23941019769, 4731.07966723382, -10777.4902822411, 6059.66328673936, -11230.9231722324, 397.724535797466, 2215.60980445318, -13244.9761434358, 8541.0300812437, 3545.86299106728, -19277.6670972917, 11727.0593219994, 6102.94671757615, 13622.1004888489, 3605.39658521735, 8286.36159403215, -3364.44005043903, -4833.39956598255, 19157.5085065168, 5249.51455448288, 8593.14810104357, 17841.3425818090, -17440.0233675136, -12883.196720768, 7818.49096641417, 12823.2236028521, -484.911568305241, [...]
+-19851.0759355368, -11339.7441566449, -14259.5466911292, 8350.78449721605, 3443.98851969221, 13368.3218454593, -1237.54274281770, -2446.86426972825, -12616.1209801405, 1715.94768490835, -4952.32109907408, 4217.01421180667, 14642.7303082876, -17553.3714390724, 5877.48396876691, 5428.13791666306, 4984.39300517766, -1753.52392544424, -5430.49059155546, 2671.54648949371, 1561.15180463782, 2303.23895956418, 15822.5746334129, -2747.71944299056, 303.923860870553, -5352.39519396909, -1270.041720 [...]
+-4147.34350051022, 12945.4215957758, 11601.0886076509, 2126.40926002197, -2521.4884012779, -10743.3260234401, -6899.01574684175, -1516.68889275595, -4920.26388746068, -6322.54456467984, -2948.82630521814, 26037.9857908008, 10784.2557680482, -5953.61465714808, 15454.0042507475, 1330.00678727304, 11766.1858226428, 20913.3920712253, -12485.9665813331, 21984.1698411309, 17286.5012293857, -17185.7048391494, 3370.76395610158, -6171.52977911488, -8459.15502357545, -28.3973422625083, 4031.640341 [...]
+-8617.03083043675, 3255.73465312348, -2082.58057279237, -8010.60615569663, 9841.20349486132, -7714.67874059017, -15095.6461023984, 1067.91048501776, -8803.9728367287, 13866.7733711214, 555.91997967399, -8217.19202803127, 125.749536560916, 16922.2175249544, 20705.0426952041, -22875.3604354579, -3833.8529599114, -6687.35170625261, -9148.31227349376, -1895.96996417669, -753.296398148215, -8522.38477272355, -874.951450600708, -6177.70306637806, -16656.4591842841, 12228.4910148187, 2090.40248 [...]
+-3716.20135068632, -6742.93872870365, 21415.0659090648, 426.614273259113, 2107.89396584592, -6237.92515728371, 556.678513760683, -13037.0241691270, -8264.9048254413, 28285.2815225249, -2348.15712365230, 10753.9897069570, -147.029242435769, 3763.75846821281, -18598.6699538286, 4819.54622496996, -2288.89871666056, -26123.8181369159, 13169.5438651989, -1422.48646431831, 8217.77623213248, 10621.5280731312, 8628.70827761908, 1875.10657049057, 803.40371014719, 677.149624203394, -1036.671419230 [...]
+15007.7240056362, 25642.7121878914, 8298.22902893436, -6950.55839801811, 11548.8408452488, -2359.30014592770, -9102.43672516253, -3206.57663835766, -1468.49548018255, -32010.4147561748, -9579.74007840135, -6623.72161803463, 1439.77891628594, -9787.47771423833, 1663.44008393009, -1921.47588668987, 23739.0747807720, 9780.73081677713, -21803.1418388180, 2193.79035929122, 2675.4718784488, -5921.68625135456, 14939.6805651210, 5262.99171358434, 13186.1577198461, 14146.5758329973, -14305.061283 [...]
+-13126.9176932704, 21038.8822330085, 11558.7839382175, 1839.72439864514, 761.39082056146, 10540.8414456803, -12060.1570706601, 2623.12432343691, 1250.55248880522, 5652.33906346644, -8217.49896086789, -1058.15875487097, -10860.1974711440, -17005.4624034415, -9808.2442552351, -4863.04923831697, -5824.64539978225, 1365.76210161268, 9994.65264171225, 7134.11834356565, -5430.06558843458, 1798.59657976073, -6190.06452162176, 4502.83473241151, 612.521886292055, -4090.03070646284, 2183.893371126 [...]
+10204.8275345281, 1439.12817585228, -12288.8586349461, 13912.7800487326, -22349.8861033959, 7742.4962791088, -4492.10950356028, 9536.96340947257, -5242.90682812203, 8593.1218651775, 4495.83791740847, -4743.20914394543, 700.26741144616, 5794.28984221394, 5922.37422567809, 8089.1205745306, -20284.9055615336, -1344.58005657470, -16785.3348175002, 1245.70298075237, -8523.44106146972, -1153.90147388590, 1273.58505918035, 9951.51649243178, 8284.555208504, -8533.3865930555, 9565.25045412208, -1 [...]
+13352.4707341007, 2566.31965147899, -27142.8578250481, 4682.28839563852, 6250.63783491014, 15554.3075528726, -8804.45684956484, -5692.89065526221, 4901.74021745313, 2342.19255804483, 4494.66518441202, 8353.30075074817, 916.933420628661, 17970.3421165634, -12549.1309484924, 5236.24010373969, -5803.1446257607, 19446.3031383621, 7197.80528248917, 1411.36834367009, 3822.16834401389, 7964.54740057374, -14621.8579438517, 5465.53026726793, 6243.98078887143, -1475.79441107169, -7624.62729571517, [...]
+7074.92714184859, -2715.04549278593, 2006.69489596383, 24220.9745280325, -3262.2373301771, 13348.4189774186, 11670.1121719951, -12991.5199242050, -11018.1460210583, -15706.5792631072, 27715.3668753549, 3050.13456307962, -8629.99176150871, -3407.25844454754, 4570.56027650162, 15720.1877990630, -5322.94781147737, -4394.33394378732, 10074.2750736261, 15027.1478553402, -20440.2310589615, 15969.1265857226, 12501.7453278542, 8264.7837373751, -964.511312992683, -16451.4092113418, -15777.1363014 [...]
+21796.1353812087, 10573.2080144424, 7323.82972803857, -20081.9666333971, -8966.05767709998, 4416.56403710356, 3275.70612724925, -8933.9297023889, 3793.24378327717, 14089.7359278488, 9094.65648013153, -2072.27877268281, -4440.89383231271, -12855.3947187315, 5550.56376892527, 4753.06663455134, 9885.36092239513, 13806.7642170324, 8825.31249185318, -16958.2357784378, -7020.27611281867, 4595.04831476255, 8240.20835580672, 4102.28711012701, 10895.6170898126, -5443.28483128769, 6718.26604479593 [...]
+12310.6231860884, -16147.0436480094, 16182.3267365031, 19569.8871986978, 19544.7028110345, 9488.9193090329, -4900.89269158397, 6607.62624891063, -2214.43060437719, 1521.07685975314, -1972.30139044604, -13467.9280312378, -17579.0847207561, 12098.2521639793, 97.2614211123128, 13745.4392000469, -3739.39975457840, 6585.59754371328, -9251.82623426307, -11055.0792180213, 2998.68836759315, -16739.5274156104, 28886.9450576501, -27241.2158826834, 3574.73184396792, 4692.87737312635, 11098.12986557 [...]
+7900.79992983346, -4798.76017157498, 33428.345821937, -3402.23290768166, -29975.0721985023, 7838.2146583654, -4356.68310839515, -2045.23622041547, 4672.75300727679, 20193.9231677873, 5196.89599576349, -735.581892347404, 493.850827885058, 6259.15585602777, 1900.95218927865, 3487.85457120272, -11668.8037606104, -20712.4988144165, -324.295587886600, 11567.8803832144, 17597.7573244575, -748.902770719335, -10160.8578595100, 4008.24011983778, -3191.56600029431, -1814.50617604422, -7885.4243994 [...]
+11603.5776947361, 26419.5835345323, -13259.5920837536, -11706.4121825665, -5032.20292315257, 3764.55327191514, -15656.6407077046, 14559.1272219135, 10575.8080703942, -14565.9708100567, -5405.95170993664, 1375.14888750978, 2453.24439549016, 1721.01643002815, -22508.1008721063, -5901.50958053897, -8036.85430210906, -13287.5789642868, -16213.4901743197, 6024.08013017082, -14022.0625867526, 9358.46275169136, 6436.69255277802, 17374.9247984246, -8413.9051944679, -3161.7172493955, 18059.655992 [...]
+14112.4654920174, 10522.2459066799, 771.891165978914, -1949.37291524927, 20137.9394954074, -2498.14889438505, 4641.64441058093, 5793.27128506076, 7453.11498819008, 21571.0561158480, -9592.64848465894, -3359.59115412832, 4220.11415070353, -9590.56832452219, 3829.20620679626, 10639.8683387334, -16772.2683684127, 1495.94181008302, 12820.2035487895, -7654.308216987, 9233.69546927332, 16239.2647041526, 6748.64125334307, -20589.2703105969, 2508.9500552563, -4547.35232574594, 8992.14153247337,  [...]
+5047.4122983244, 14102.3333862115, 104.269758486009, 13004.7942804464, -10170.2736284678, 3170.68246960601, 7483.80019506967, -9531.85845190477, -10925.0098096913, 6857.41841525399, -1491.80894524154, -2607.68197753122, 9387.80242822892, -22120.4214077379, -16351.5114371752, 316.064917570743, 10830.7199370038, -16986.0882422570, -6320.47965303297, -15961.287982829, -322.905513999659, -5661.05168458063, -17359.625721151, 1043.93891538738, -4385.39679309528, -6449.50528454368, 21504.319846 [...]
+-11064.3559606456, 2490.9551485102, 8558.43709038103, 13755.9013930048, -53.9627970295194, 29957.4650748979, 1807.4375934961, -6456.40913602522, 4354.77364447886, 5319.7322714094, 1709.81710916050, 9173.11024153138, -8835.13627439602, 2234.25654591892, 20302.7835027364, 4921.56177172576, 17897.0022779173, 11675.8824789686, -14586.6361306821, 479.337883733233, 10907.5339490556, -3409.47113130454, 18323.3572857280, -13723.5045444687, 14942.7051818834, 3507.18579542066, -3805.53213408852, - [...]
+-9526.5070902477, 3990.58006504146, 12059.6292827491, -2774.8619428068, -9605.73233836688, -11286.4723258641, -9189.94570588017, 4060.20652767913, -4855.89499383879, -10066.1077577139, 1953.6267475224, 8228.86240527585, 4913.6412495193, -6389.64568304404, -14327.1243412265, 2584.70368995424, -4706.31974504258, -4272.08087062927, -3001.79358955687, -6983.85073426728, -14966.7788777738, -5291.0946366223, 9964.63160710952, 613.567858944732, -8409.81345198143, -2072.84674923988, -5825.260100 [...]
+14591.8828694468, -5267.90643019333, 1556.28144957183, 7032.14849515608, 5756.02263954504, 5514.82220224852, -10141.2098522869, 1183.47594405692, 2762.35438102245, -2304.26047752154, 8937.21725217935, 2877.19381369266, -2062.18818123968, 837.48713781111, 14849.1310004388, 6825.3268421527, -5446.42678796297, -3217.01180286016, -2109.29220923764, -3312.81298257237, -11438.4780860563, 19706.4811674565, 5547.58838320465, -3433.82876109402, 176.413008484615, 10724.1089148269, 2175.43308384071 [...]
+24027.2847904925, -21927.1732628842, -2777.09280088519, 1411.35739456461, 51.1873528903178, 754.914716222059, -18544.8552416780, -3278.80297785537, 13476.1623616422, 9479.34556288802, -15070.7467251447, 1610.48045016121, 377.606692227411, 7433.62979835266, -4791.06066031193, -8458.067293264, -8853.56937783519, 4707.53334130254, 3488.62503657303, -5744.91753731956, 14677.6849858447, 10246.8809530099, 3264.34820117637, 200.898319166333, 4499.88017836023, -12299.0928256679, 18668.7981964017 [...]
+14119.7318032206, 6687.87493160957, -17678.0638846833, -14565.7118504284, -5230.77729465943, 1831.17733457329, 10124.4033931939, 1313.77082697717, -8588.3299931345, 667.734560372743, 5131.86473366607, -3019.19846568414, -5903.31518660478, 4514.93595681711, 17840.8574203136, -8037.5024419089, 11255.7938307125, 4370.04099306194, -2745.68630507376, -12966.3821769889, 6432.91419245266, 4434.65805619517, 25260.0087145580, 4233.87107958879, 1398.66038086131, -9651.11454655859, -4219.3740667803 [...]
+-15690.8790640686, -10854.3138587393, -5726.18179134976, -4265.1423443419, 6812.07376816145, -5833.72008732634, 4380.15184601484, -5318.92299247284, -3934.50728558223, 3239.81932336616, -11669.9144620127, 1674.09518150675, -738.767928483665, 18801.9400012453, -749.589842635354, 3416.21933555048, 9071.95630626682, -7905.84545170176, 3961.24095297893, -3138.6295726181, -10616.7829374524, 3857.95881421939, 11740.9964079381, -11961.3779434415, 5684.65770605497, -1720.30222369092, -12474.1590 [...]
+27122.9369588229, -347.886506367932, 11208.5143009306, -8172.35774880852, -2880.11634394633, -1912.46146739915, -531.148083428089, -22890.0932505915, -3474.94229908368, 4120.73058884275, 9802.35054400023, 2604.54173414789, -1222.52200853750, 8207.84088666409, -2647.87531622043, -12222.5931540358, 11302.1212805687, -13215.4605032869, 2658.4481372, 462.602743838874, -14305.2240071922, -3583.44143429107, -2805.79536928588, -10454.5963755391, -7464.63244821868, 17764.7256944162, 20087.616829 [...]
+-1245.81982803660, 7411.79770763277, -1557.57778545260, -22094.5318851976, -22073.2138796445, 898.315926754142, 2884.02547052343, -10175.3638427364, 16594.3119805135, 1450.40724323827, 7029.04352198666, -5937.41985538107, -3912.34977431658, 15141.4381374973, -10263.6312250278, -4874.94995121573, -881.640696942715, -12990.4453317506, -15173.4344392368, 7431.55658201199, 17396.8779007953, 11422.7780186394, 3656.73303940895, 2502.217214782, 21951.9254824531, -5787.64850614234, -1340.6264560 [...]
+14018.6336197699, 7876.9247082921, -2928.23095236933, -14298.9872067696, -3089.01831540037, 12062.6966423384, 8106.16991287442, 6543.10516048664, 14374.1779986584, 3853.21107305015, -10577.1423939779, 17743.5815215394, -11783.8634715886, 1606.54998945440, 7886.9279832725, 23332.5989540012, -4009.77869306850, -8177.46769426002, -11386.7819828101, -2772.65450959902, -1370.36628953393, 6205.21788407219, 15556.5669360019, -1868.79557402001, 10419.9447602837, 10165.1694682001, -1569.766130543 [...]
+-4142.38210521815, 3554.56818258132, -12010.5850184117, 12172.0552390519, 4535.70324802199, -6536.34590908138, -11237.2445194013, 1924.38842621655, 16557.7836832217, -4410.81752278527, -3327.55370622748, 10636.0721069356, -3104.72627524818, -12132.5868684202, 15258.9405288948, 9624.17763710004, 6332.27056934709, -686.715915198795, 401.816737350728, -5243.92088643959, 14670.2456356550, -9267.01568251125, -17434.7171954574, -14459.1171065775, 10212.7632904310, -3038.82148501148, 6999.05979 [...]
+-14388.7850072899, -6664.02694185573, -17036.5261170201, -3123.40236577887, -9628.48191219122, 2856.74888586761, 15156.8616325539, -8681.09383309112, 1719.72145378757, 20222.4942214986, -6184.87420371828, -9596.66751571631, -7334.111623068, -14528.4092507821, -31343.8725946785, 1389.86717283768, -504.727709177228, -5680.91999091341, 11967.3876117639, 4685.36603552084, 14897.1530076356, -2893.46307954794, -3510.10733438135, -2097.68722339127, 7249.97969745109, -20139.5077975279, -12028.80 [...]
+13642.6876384918, 8130.48249650767, -12705.5050989708, -1497.28045101417, 8954.34114435129, -9435.55345297833, -4054.02110628965, 2220.71442099994, -3970.88748985534, -20726.8258987365, 2956.75157564905, -6036.88190760414, -7392.22988244654, -9688.49494297548, -8722.8621436422, 862.632018940847, -11487.4086561214, 10510.2131104437, -5569.66634928711, 8923.1331164715, 21593.1556258214, 3929.62495484877, -11366.6642716927, 3186.86208876679, 3694.53751888549, -5382.37786164141, 1082.0927831 [...]
+-15033.9967070899, 8418.24122320392, -1615.46775701381, -3035.28250601218, -3639.40820029161, -4544.92392932451, 8375.5347010724, 2830.71981585121, -3289.02286482071, 3937.15734679985, -3270.02022537532, -4964.81271788098, -1345.44325695257, 8029.7260561204, -19661.2609777494, -13125.3097164076, 3396.22032931335, -12012.0201515369, 4930.43021010996, 884.122096027113, -2554.38990975410, 8157.58928561068, -1595.05079261179, -5857.65790059246, -563.725739996024, 11370.3136832109, -9610.1038 [...]
+1378.40931791884, -2715.01276928985, -225.823891850805, 8636.32001408228, 5718.82541790861, 4848.77017075589, -1566.58313298715, -1468.16815244458, 8669.41606361106, 22323.4827649808, 27378.9386270931, -7593.0176027171, 4950.83725324747, -12619.8909318031, 2055.07609069359, -5941.28230185786, 4331.96804330038, -8625.875642102, 8240.25658735072, -25680.7056544312, 14423.6912894485, 917.3951034987, 928.431369766203, 11507.7683431252, 7817.13392330181, 25335.5381713820, 16199.3516521367, 25 [...]
+-8489.901802819, -11518.082923844, 3080.05373489236, -3628.09042024956, 5555.10970939376, -13237.1239341580, 237.179356823296, 11532.5313178648, -12378.4601873352, -7454.26875764373, 5277.03923321028, 5660.08558836819, -297.091831052782, -10240.9592783703, 6898.98316632226, -3141.20806339411, 15164.5588224792, 727.511913955177, -2814.45565194799, 8946.97285107137, -7351.71372490181, 1919.18682664872, 7663.16142644765, 10626.5772531620, -11032.6173388593, -15085.5658659457, 8185.736246073 [...]
+-1618.64005015937, -164.336124963069, 9554.926695774, -1577.66074613981, -7493.55267744187, -6821.52121396816, -4952.74776683026, -3614.10138050344, -4197.29020005424, -13819.1642184191, 2751.44719807401, 13793.4552006241, -15551.8900044585, 5697.63543718154, 8820.45663061468, 1799.24751043706, -815.850495679574, 6673.89118268068, 23138.0158031319, -6251.9712099053, 7950.4919992942, 6323.47237447512, 13323.1778088634, -8308.20578323918, -13590.2739044823, -9922.6393459411, 2622.054329488 [...]
+420.300836232212, -12904.6851575728, 24514.7821721249, -872.543949291803, -12298.1176052937, 14502.7965018794, -8294.64143825893, -1520.88569013181, 196.275765961022, -12961.2838236964, -1618.28673997378, -4773.02706635343, 27810.9661387791, -2655.96527396992, -394.568462515397, 7201.41394174803, 15279.2733897999, -7309.02159160819, 9258.12255160693, 8508.37419119515, 1444.23923538138, -10036.7083379761, 7369.6166842716, 3373.9156824671, -15699.8943373993, -2853.95115670523, 15309.743639 [...]
+537.302851076785, -13639.292418015, -22981.0436911285, -5067.99741172223, -3691.86743851325, 9877.77870549073, -3174.73844062395, -8484.71197988807, 8416.71626840066, -1600.51770895278, 13776.2181596588, 13954.2972766486, 10004.3997305305, 7838.75537459108, 10690.6702186426, -18161.2443392644, -8247.19485487299, 6867.96056644236, 13865.3517698683, 7417.9368391563, -1204.83222493612, -4701.79297102551, 5739.05120264894, -9253.78383042496, 2935.82812613451, -7618.54942924314, 1436.01633333 [...]
+-17136.6349681069, 3872.84878649580, 14841.4518732616, 2870.40710410998, -4075.06996249861, -4806.5105420323, -14416.4671469749, -1911.48672827903, -339.416005590437, 4808.62578909258, -5550.9181858789, -10518.7090798115, -15543.6667731413, -26793.9803156457, -2116.76225617016, 5560.72859600384, 5748.83177112314, -3407.52384292096, 21175.0067724949, -6879.26114359947, 13054.4405911724, -1524.10368278619, -1672.0534000638, 11721.3393397359, -1950.79336922866, 6533.66503738157, -10452.1725 [...]
+2726.60930876392, -4884.776685737, -2812.80611341055, -23342.492670378, 9151.20637852072, -749.243511165047, -478.192982946169, 11509.0618689964, -3593.84567987706, 2683.38192813499, 12955.4623827766, -8884.72179374685, 2315.36176629064, -8785.17125267249, -9553.68107404014, -15943.8645656959, 3270.25647980013, -7449.63438379604, -15590.6418822254, -4713.85641655119, 15600.6039586017, 11411.0680829936, 16117.9246367773, -4550.52161587973, -19908.8547590704, 690.863377794093, -874.1613080 [...]
+-9585.24547703611, -379.453156468895, 8541.09201562945, -5066.72279873099, -21900.7608847717, 17337.6419491985, -7802.76779509854, 19638.8040741531, -3328.75870885436, 21833.0711699946, 20839.8118022039, -924.699210131378, 12189.022170406, 6789.06785731033, -1663.16573742179, 4014.63121502717, -3290.72378629040, -23410.7171449968, 10919.763302012, 7510.16082451209, -15195.3007071185, 14201.2713743930, 11351.4198756421, 18628.1268238883, -7592.71928743593, -2959.99164375702, -2967.9133165 [...]
+3145.87508057110, -12230.4217530822, 10088.7801698624, -14698.1873833615, 676.111438247272, 28114.9020047734, 9205.41794320156, -39.8362518108905, 11926.8062991687, 6543.38731073992, -21858.8394755457, 7393.05590809896, 8015.35671145293, -1765.84560878953, -880.904594494194, -8106.81878470027, 11674.621425113, 11459.3776207081, 7874.1567746238, 6549.10680143755, 2060.68423865762, 9597.26723311628, 8088.48578362207, 14201.8527965426, 2840.39937418158, -5112.10046864359, 25178.0117295295,  [...]
+-12713.0393399977, 26.3073068548405, 186.745949026923, 1925.80168995817, -41200.4084236497, -8641.73654524068, 20848.4289551482, -1369.83724651966, 782.423498763463, 4218.14416162009, -4017.86680547861, -989.86579877128, 22021.1271679448, -10659.1278537776, -5137.0380815331, -2715.42052012764, -13439.9487596403, -5194.74789001777, -4884.45111181404, -1683.55491003040, -7969.56061996109, -5271.39714084871, -10724.6344633344, 3946.97354565143, 3245.56941620871, 11436.6283226115, -1059.1662 [...]
+-17482.6295756583, -10380.5484920160, -5450.50715414119, -656.240917714548, -4153.1290589909, 6551.8153374368, 9951.89391153105, 3722.86184631359, -7960.25440538576, -767.817253576411, 4879.13076362637, 9210.4537630501, -12198.4323528251, 9808.15570766551, 2351.70945831620, -4697.33343371134, 3811.71186927416, -7408.80525937412, -11727.0373855653, 530.837207700915, -2880.80414836529, -1784.09682273474, -15600.2167950030, -8572.95710397883, -7732.63256938237, 12204.7832580618, 952.3492343 [...]
+-9681.98031524389, 17105.8305838185, -20776.3547611097, 12335.7289918302, -2572.24445613765, -7972.83820650238, 13975.9387592647, -3189.07638261927, -14951.1331352983, 3408.34158490454, 3322.85652992474, 1673.43029733551, -2798.64189909138, 458.035489965634, -19480.4375282700, 10494.6831367019, 2015.10205906346, 1768.17742441724, 15195.7040183294, 1804.40398888948, -9859.74578141852, 13015.9412812919, -2317.15867955966, 1172.34868787474, -8339.9059626841, -9059.04033426667, -20629.497783 [...]
+-3913.41852902908, 12005.7059615075, -9026.9994766942, 3516.65299538616, 10346.2116422586, -15759.4686996686, 10268.3207379602, 2604.30750684203, -15794.7258316805, -5746.87922809709, 9731.0860408155, 5569.89502040024, -7974.52884602644, 6001.68458616041, -6406.47556077553, 324.227444006045, -19195.6601534748, 213.566696393299, -9580.76374227836, -7968.62675741442, -8094.5838547419, -5238.30391802464, -18882.8330098645, -7175.6620621382, -10028.8644250153, 4160.55022481572, -4699.2660434 [...]
+-261.938352998837, -14779.5244931779, 8794.10040072033, 5869.87826433271, 26140.8659240953, -7965.98121085104, 7115.16310038153, 1186.60151429629, 4947.02357477746, -1221.80917511930, 5869.86948543844, 620.409150100079, -12159.1039230627, 12828.733840066, -3458.31367433688, 388.486228434742, -12498.5861557795, -7665.27586215849, -5873.70319469177, -14692.6804677376, 7643.4025010324, -4111.47344834783, 17537.1398243450, -20637.6258277266, 18758.4366072646, 953.803249360567, 15434.84119314 [...]
+2020.97543297743, -171.331416088421, 6186.57208339399, 7632.23758290881, -11777.3634049224, 18522.5078963128, 4521.18307923836, 9547.19090149776, 16305.1337372887, -17150.6426991201, -7359.9523129398, 8207.6768180129, 8680.36813371725, -7133.06384391026, -2813.84013215208, -1529.68290863124, 463.255003991897, 14271.8595311639, 3110.97537085472, -5751.3411216435, 16336.3028231175, 14157.8382427387, 17964.5644033781, -3113.75031396272, 8352.43527795049, -21086.9075703332, -8545.85944905033 [...]
+21562.3537541503, -9522.25249921872, -754.500612112732, 3541.78506277889, -3081.50858980831, 6699.22436461644, -2638.15765845997, 12080.3456062039, 9465.04007715188, 4410.66169235646, -465.74671659158, -1270.11214022807, 5849.57796370350, -2811.83609335193, -25870.4140944527, -18455.3814860613, -3159.35568300393, -2297.36985408607, 11358.6804209452, -2838.79115942198, -1203.93154321187, 1840.54137480396, -7749.25877773788, -9566.8021966237, 4534.44574464040, -15510.9244235636, -5929.0502 [...]
+3888.37195879145, 3572.22854759381, 5533.51279750487, -7674.35649756255, 2560.21178627725, -4438.56802501428, 22342.1609862862, -2430.43862600701, 10073.1370663808, -9248.21892020116, 3211.89702721962, -3880.14513074735, -7654.54813909951, 3866.28810168502, 15200.4536674742, -5505.27535541205, 4927.12542804359, -3993.57877575283, 7662.58650066661, 22472.9894782751, -6275.47234961319, 11811.9692723880, 15903.1635551128, 7277.03681491949, 4702.29235915703, -1133.10707274259, 12052.75604444 [...]
+14242.7816850308, -15363.4026824975, 6921.61211519545, -1236.8928282433, 3654.70371736112, 6264.67905955707, 8464.28080753532, 17203.3821916834, -7555.90060393163, -25753.8245282195, 16240.0761821170, -0.93016664461021, -5183.64460499759, -952.418440033055, 4600.41425950994, 22993.7016252858, 5504.93927889892, -769.324799664379, 6204.82810826712, 5506.4173837298, -10934.3879915149, -13179.4854290040, 2479.72690583931, -7565.48403004733, -9041.79685048034, 4262.63767315193, -4091.56457086 [...]
+-7211.21986981179, 2078.62350648310, -33.0694555729863, -2734.93615371610, -12199.1777374916, 2699.51659479913, -11452.3512696698, 5210.82536878873, 2359.87695909597, -8681.31863916605, -6919.56496428171, 1698.09622636367, 11193.6859871509, -5548.88784294407, -2153.05995500168, 7506.51585014253, 2453.81570406600, -8996.37534778118, -7788.48481108624, 6219.48043359033, 20300.7048921923, 3589.65248489979, 9084.54869514167, 2241.12361935408, -1419.12868281680, 21741.5970745594, -12462.08337 [...]
+8412.27271842369, 303.893450362022, 25133.4363356376, -8279.27079730788, -7493.63457024483, 23704.5699905274, 1708.21173162585, -1798.84368680053, -14926.4670168063, 7128.01914752872, -8424.28611845603, 6265.63903668224, -8027.70034470422, 11008.0067831677, 3278.63664917805, -2776.72716088575, 19023.5710305067, -6587.74667915937, -12616.4450970932, -7308.00561234956, -8549.69017223103, 10297.2660602890, -4263.21052966918, 14650.6891443187, -6487.98759741476, -2910.23048619523, 17725.8770 [...]
+10010.2527001484, -240.007507863415, -8825.31335238898, -5539.50077775646, 12227.8427912182, -5689.95411921824, -5644.59952647407, -7206.07892389756, 753.365774294332, -493.732381091277, -1454.60660902141, 10948.1504825777, -2231.14385743778, -2668.68691628216, -5741.91853091377, 22956.3993568831, 1221.47087596707, -3944.49727661067, -4384.3162307373, -2476.82047907871, 18470.4389939183, -6591.61707025052, 13.2447411540159, 10717.2826951671, 5712.65565973718, 5722.035825825, -2198.138272 [...]
+-7359.74224011099, 2263.48323405816, 13233.7114623828, -7065.74238565005, 25490.1849211425, -2533.69286143107, -13611.2260047779, 4110.15613750373, -12235.6198977278, 8200.57870819988, 5105.35476198932, -23468.1734170733, -7531.37236836084, -3461.17323412325, 9263.72636829503, 6184.64461622952, 112.369125755734, 6840.17368501595, 1727.47484008261, -3628.10488562154, -335.908128233215, -4013.42186191587, 16497.0087447912, -199.725636427152, -2094.78260814711, -6331.58318028917, -1375.5740 [...]
+7846.61564271192, -4238.66589547151, 1930.40892117117, -20534.6686844951, 23628.1353224677, 7103.16421128039, -10537.2138242947, 2005.11349071402, -5913.82148384183, 13464.7952510129, 8540.8465850896, -13330.3204138332, -23621.8012504261, -7695.51522727042, 7665.97537096692, 5976.57104400436, 5843.48043661177, -9572.04029698859, 1663.29581351849, -2278.81700278472, 8385.82641481897, 2465.30201489695, -15241.0470043307, -9634.95553109493, 9418.95599215502, 14916.0469091713, -6678.57631826 [...]
+18681.1051971225, -2505.21686579337, -7587.21154396755, 9069.09724781394, -13287.5022674776, 9632.30243436885, 8961.5988420796, -6206.33279025106, -21560.8964476235, 1017.67822832717, -1293.89655226055, 18670.5102456120, -299.305085931122, -10196.3375048374, -3731.55013987022, 7735.64827943779, 2517.31707268062, 3755.70750648512, 5874.5030105418, 5175.92133621223, -12072.5924037539, -11168.8153399418, -15683.1564146525, 4753.97292078101, 6518.0289629421, -16755.2861485648, -7768.50188810 [...]
+-9937.60035492654, 8969.15505713551, -1737.46410457492, 994.842236422347, 9119.30385008821, -2151.92319908064, 4238.49156960371, -4037.6866803907, -9464.6386396873, 7141.92157599868, -10449.1503927754, 8686.51563935973, 6903.59569009411, -168.075878122358, 5858.15501334041, 12843.1845741192, 5210.94051925712, -2431.19186040888, -4829.24174267439, 11571.3497028685, 21418.2467743027, -3928.75932714807, 13623.0239174197, -14219.0647567759, 624.50234463434, 13454.2783163372, -17968.397834121 [...]
+1888.64023721913, 9995.0905246978, 13601.0413570587, -1494.34166081157, 5220.25872960452, -20333.5595868886, 280.054637874758, -5563.22852708752, -15423.6284451649, 4380.28427798567, -4192.1286160259, 16301.3615963628, 24577.3944439989, 12874.2802437507, 1029.47867840155, -12505.0074896787, -1434.99999349526, -18786.5207787525, -14179.5862864371, -2489.62255298565, -4913.80406389831, 289.161370788919, 1537.67722639067, -12423.6106976098, 1685.74418697224, 10216.3193176408, -8268.50089969 [...]
+2416.82981869463, -6781.14446215893, 8996.2801518171, 3869.69107026177, 20360.9163559603, 10160.6502066579, -8750.62453660651, 15113.3496727751, -6710.74878474151, 24412.5091108895, 7119.1629834843, -6887.02571630489, 15452.5614090439, -12274.1532223246, 3855.12389144367, 4564.74846661514, 3716.82928306714, -8152.6868096562, -5724.81217409692, 8634.85917916742, 4690.24414739437, 8724.02710490632, 3138.54322246464, 11531.2268379344, -2396.83664909823, -5142.22311745376, -930.943758578845, [...]
+-2616.98850080009, -4632.46800086161, -7540.04161030061, -1794.51382263955, 4166.06888638672, -9001.53739405336, -6188.32711648501, 12515.4823630883, 11407.470078334, 11729.2845679540, -2982.02502547481, -7225.89939632393, 1908.21369392132, 11110.0879235609, 12249.7078693218, -5358.95175701378, -4451.6707590196, 14373.8181109317, 13160.1881239764, -17452.8884765039, -9983.54082672565, -7616.37114240974, -126.762631486049, 3238.81937339909, 2932.93382165972, -1068.75105408483, 1138.849592 [...]
+-12122.3188071186, -506.774942150756, 1590.19795927824, 10364.3634191195, 14051.0563020917, 6793.75661062835, -5951.28136926765, -2490.21805584681, -20398.4662201271, 14915.1305763845, 2348.35022433064, 10578.0913831683, 1363.99512687054, -17420.6753226533, 1502.69172042844, -12152.0047272061, 5237.61784126403, 1361.72256660634, -8645.93588195056, 8518.64688750588, 6970.11082936179, -725.279778825735, -14881.9398502743, -8778.0328491669, -4797.86284358907, -4138.09626340439, 13609.544016 [...]
+-28184.9101997572, -6503.41025546165, -12945.0592567878, -13300.2948377982, 3650.19425934803, -3144.5539918928, -3641.28409339232, -6170.76931457593, 8021.25172974801, -6325.96168859273, -4675.54308098371, -3249.23957883361, -2303.72755872202, 18675.4012823914, 5171.08239370801, 5369.1046835274, 6169.11799404397, 16034.5048198945, -15336.0746700266, -1514.27964101713, 14107.6590044357, 9374.64387885146, -1430.30072612522, -13846.0566641079, 3767.99379186902, -8202.32279929843, 12858.7928 [...]
+8779.5572846819, 25747.8434289173, -123.363968017162, -18447.7240818648, 7198.25058190164, 162.775051235135, -12652.2349691405, 24142.2750986179, -1572.64823267866, -16599.7206938068, 14854.3865170628, -7595.974107641, -514.450870599598, -10921.7688395640, -2907.44881369413, -14210.0432421005, 10870.2936543248, 15295.2271005939, -7041.64800297512, -1064.72791097088, -5043.67361325088, -4717.33439007678, -10796.0958235780, -26355.0792893511, -15700.2454591305, -12822.7146388758, 9097.9362 [...]
+-11998.0878757058, 7712.26001497666, 18650.0214607688, 19361.1204073891, -6810.36124622458, 12896.4502592835, 252.409463137387, 933.00539895717, -9598.95797967135, -661.799157723188, 9811.31449125159, 10270.5963536748, 8653.89342605228, 7958.15127570956, 10278.3113561529, 8765.6310498296, 31612.5438967579, 308.738993503759, -5574.92039344428, 2712.50861877488, -9029.9370648586, 1118.71487771719, -345.579596256208, -1380.72537814987, 9452.25454898535, 1882.74135869954, 3585.23451834804, - [...]
+10760.9693084411, 1395.46109798653, 2047.63783315646, -4697.12373071723, 17786.7505155174, 1998.86212585324, 6089.01784373324, 428.077339738549, -8301.85783894065, -8196.67885280917, 16846.9066025712, -6115.86011683661, 4832.23448132055, -9873.14295261456, 4926.09913012548, 1900.01572026071, 2196.14419891866, -9981.63611921825, 7464.38266446724, 1851.27180058655, 6649.12421720103, 5167.31626573643, 6350.75268689748, -14671.3828623726, -3949.86308355149, 1766.70936946631, -14262.948702595 [...]
+10525.9555614741, -3694.85676046959, -4582.80039098538, 12291.5044393240, 3885.49289197079, 14767.0282789801, -1558.8350575552, 7613.27940441754, 3173.80431380265, 2492.29368625522, 1425.32999731071, -4373.27458761010, -362.592235982237, 13878.093992526, 10124.1523447407, -3030.39142367878, -10877.8279002285, 260.000466856965, 9661.11983153179, 2120.02773722021, 13027.8446887828, 3018.8939282632, -7670.74598874264, -18695.3824628219, -5634.0319073697, -8735.18684135567, -2450.34183711258 [...]
+603.75158929403, 9378.86624893062, 5325.19538148523, -6399.81922479104, 9965.36515521852, -7267.39555205532, -19437.5657037574, -1723.55804914238, 3948.53236040036, -8316.63907770332, -654.520439730996, -14291.0914957943, -15563.1174504244, 4536.74761190499, 1220.2268115056, -9091.89895265087, 8119.0840026217, 5180.51087528691, -6681.8427984846, 24966.9554344308, -5199.13130377185, -9443.08752003883, -1080.43609411755, 3139.15710996353, 1908.47591631075, 289.841034989412, 1902.1622232133 [...]
+1368.19204940206, -17022.9936485952, 10894.3712053905, -6778.22154375654, -4154.93793454391, 4192.76666606496, -11568.7089777792, -4449.31350309037, 913.36486632865, -4302.37263227806, 23454.1725753835, 8352.19925009303, 22097.1171435891, 5063.59313538367, 4820.46478645878, -26758.7274310011, 11803.0758594108, 19082.7093004369, -1406.17563694851, 4934.8288016937, -12273.8896302270, -14781.5811987024, 385.521974879238, -21350.5751902863, -5575.25269890915, 22929.2038092091, 9584.552864300 [...]
+-4298.12876323569, 749.773499488161, -11853.6597804799, -18490.5913493520, 18517.2241440944, -17298.3133385946, 12114.4061525637, 8487.44240950772, 16.1059398742905, -14677.6376778930, -12888.8498369696, 2892.26442852067, -13009.8275113762, -1707.80544148398, -3589.36389167064, 5275.88392415319, -11135.8773603119, -4246.17919145683, -9069.11505803527, 14988.4444679998, -8321.812002005, 4597.9579385022, -1830.04755191664, 6035.0241815614, 7476.60720747981, -8873.07148780087, 5962.32826054 [...]
+-11229.2496023097, 6251.16681947622, -12033.2100212236, -2773.84939078736, -4059.52934674293, -5106.05101794522, 6020.68555981755, -12555.8357252565, -9602.3342347016, -21770.2823015391, 8732.91841930344, -3786.38982754688, -2367.56211062911, 15236.2265242242, 3553.31843047683, -2025.27518273132, 3891.86637152434, -3395.87806685669, 7159.37457394604, 6468.51441097893, -1486.95667590875, -2021.93509724079, 3651.66987701881, 7337.06693379039, -7166.62253608784, 177.798487208945, 4415.89767 [...]
+-3239.77910529877, 1850.38272442962, -2222.55407911736, 4212.60364802658, 4865.57024633524, -9101.82234141363, -11108.1058867074, -980.108777996994, -9258.22638834881, -17167.0296186973, 9806.59161123887, 1272.01266315995, -2175.95254777602, 8915.32734163931, 3227.0135729526, -6930.53849173168, 6666.22183018294, 11205.5133643536, 9996.11286944943, 2928.70231320173, -8537.77790664404, 9317.4071094361, -5651.97185155567, -10390.9313193346, 12464.1612336404, 7287.11440421245, -12434.0688418 [...]
+3148.51796599744, 250.896365812026, -2149.97408498802, -18299.1490076888, -16497.1720304049, 219.611159630129, 6693.92916455735, 15572.6501145856, -13110.7716247325, 6815.40038131904, 10418.1293379176, 382.980463227888, -8329.57794323377, 7347.45717228332, -10405.8305993298, 16382.8200558941, 6937.22015571713, 918.99769621096, 7538.66647863732, -13883.9511574362, 21568.2550382572, -27743.1171021763, 8472.5853734677, 5290.61030321064, -4717.76440967475, 3045.513916458, -14728.9904684166,  [...]
+8208.95555828644, 4235.25705118312, 3318.5498513348, 13637.2447555102, 1938.46531622879, -5235.99140212961, -3692.8024880648, -10327.6156400773, 4239.54671985137, -2902.04342754531, 5079.9195007309, 16890.6005902907, 8484.5506271435, 4365.60519814313, 4211.77349988289, 539.536572643954, -8383.51762564214, -690.098449417876, 2953.57515359194, 16805.5243279123, 5198.56901835743, -17124.8441010060, -4285.86316609087, -17351.5093403577, -16239.5124712858, 3623.38109532002, 6901.20887763165,  [...]
+-9274.23318163175, 1829.86701729411, 112.535200873430, 11739.562910835, -1797.71919768781, -4170.64960233756, 3105.08724507455, -10105.5922307486, 10228.0043416717, 17708.3926787486, 261.648657460444, -6409.3446043032, -2555.67298438994, -330.950156010737, -13499.3709477393, 2582.42749289858, -1801.20765803878, -9198.34863302877, -6280.1442738252, 2634.53627772523, 10890.4377412934, 32277.7901998494, -4385.15411175063, 1195.70370321347, 6198.81428668045, 3057.92578053451, -8149.464390141 [...]
+10331.3890298920, -4228.54812574828, 11334.1248219511, 1701.66594541162, 10517.1909159559, 15983.0739109406, 9816.71410076074, 9757.1507247382, 10714.7076100693, -3843.83893871033, 2740.71123295484, -9739.6999153828, -13220.2159279357, 9448.67826094472, 11200.4181320779, 16350.8164905019, 3829.03730121581, 7902.11215783484, -17903.7887586781, 16481.3273293783, -1325.63205104363, -4915.85130069572, 1274.34606002840, 13826.4255000790, 18127.6172830444, 10272.4555141467, 7839.95724044923, - [...]
+3781.46680101371, 1685.31915820901, 1565.20016850822, -8391.52329564927, 2282.74818946446, 16403.8049190507, 8289.70219579295, -6751.30623829239, -3692.9519484871, 2577.54793541508, 2050.99318443647, 4288.88336188691, -3586.57246427452, 8208.58712683431, 365.686400939531, 16011.6081724028, 4824.05311078317, 613.638847894927, -15694.6880871173, 1785.14726138352, -3955.88788584394, -3040.94256730521, 2901.52107265192, 5460.08847315086, 610.135562803805, 2518.17466913700, 3657.3472595447, 1 [...]
+-11329.3638134873, 11968.7786358583, 15423.3972410047, 3457.9054778131, -13871.958051392, 7758.61649751216, 17944.2443021645, 2777.46879463772, 3153.51882386459, 4691.76438673627, -501.979453165374, 46.1691622946795, 20767.2548627224, -6794.46575226999, 7268.24023585396, 195.442515013943, -3926.11067753648, 13595.0804703785, 3088.56017089212, -14871.3847142702, 93.5002128369333, -332.943142441945, 414.088427529153, -2163.19656887149, 14556.9973924369, -353.941695645637, -2297.09370629968 [...]
+-281.553795343215, -6677.22119260282, -3156.77103236743, 1890.15874254581, 11285.5918968232, -6101.19381117474, -10827.1055254742, 2526.62044601717, -13775.4857370196, -25887.3862549037, -6937.12670112561, 12122.9518213702, -8486.36338864384, -3705.94336488157, 7632.02298981184, 9591.28853003675, 4389.60082174041, 9643.74016621456, -4692.98319733469, 25238.7295360614, 4563.96905355770, -3579.76800950694, -7183.05120492675, 15526.4254317400, 10162.8914332922, -20325.7773696333, -6740.3590 [...]
+-12652.4340054477, -2945.95263637388, -889.920742883133, -3419.79370109959, 9205.04262832686, 6155.30568054098, 6042.962786872, -2726.35018509622, 6180.49521128453, 9414.98731005128, 21329.1664700786, 12389.5282630218, -3225.85975142626, 253.370460350921, 24143.9609906954, 6670.39482384376, -7458.25016182665, 573.323399283041, -6203.12221073642, 9056.85933266438, 765.594364428805, -6013.54065550128, -82.0247078776614, 3770.15446321011, 997.92304944229, -5400.64173232065, -9413.0223708948 [...]
+3860.7437959313, -13857.5691923918, -5364.55222186907, -2465.75098010098, 2885.88882948049, 10318.4223450694, 10916.0709602301, 2792.06390908974, 130.522957334765, -1636.24467451915, -2588.5870038305, 8988.15703075671, -2937.89500085286, -11076.1412378386, -18.3690228070462, 17191.2798428127, 5918.31798399146, 9393.16816811784, -4462.76855407414, 8082.23811307447, 4175.57293117322, -3564.34322030704, 14832.8843155317, -6566.61214036386, -1428.44905862518, 6966.67213861086, 8404.300078242 [...]
+963.499989730333, -2346.00320224907, -3290.96040990596, -5681.83925220913, 7974.91342679491, -7025.08562789579, -4631.17217485709, -14237.5498718903, 11169.2664023105, -2753.86738198086, -15766.3635623187, -12292.5920041448, 25377.3876351931, 8640.40510873741, 4351.85384858092, 7095.57127017897, -18952.9545179917, 5485.76001919773, 24378.9125459615, -3988.18476132541, -3160.57380568311, -10580.391207303, -4742.26457405263, -13570.5966886952, -11692.1410297097, 12097.1476616568, -5418.924 [...]
+-13636.8995522122, 15215.7561096552, -5310.20502463635, -4410.15434175714, -2290.29876397295, -9282.90620574795, 6817.76120253273, -4789.52672946318, 13943.3438579055, -1819.08671454525, 2400.62183829629, -8253.4180377464, -816.318804889702, -10666.6311385792, 8131.98979325503, 15313.1564457410, 10663.5392004790, 22184.2417698676, -10969.1090705771, 21045.8020610014, -1358.22935491527, -26884.1678465463, 13814.9961853496, 20268.7312549925, 12562.6165707017, 12939.7038162724, 13879.971834 [...]
+15525.0526321114, 5452.38488849147, 4872.17765668778, 2536.33371384296, -7614.5391632365, 3056.08362950361, 11920.715146137, 5569.70356742659, -1729.83808145278, 7307.11669347253, 911.796305899462, -4929.79702826152, 1147.62213181549, 714.452555662847, -7621.08340454411, -11285.2007726449, -11079.0962092930, -1255.55521483084, -10796.7825124590, -7731.81003361617, 12995.9634517072, -6561.30064289336, -1633.51708515258, 12670.7373918814, -10143.5314076827, -5025.80700597738, -1477.6104716 [...]
+3709.73783758178, -6999.69751434866, 8951.27330898192, 2866.41578332223, 5597.21712144646, 19331.412527673, -2198.09241443634, -12267.1065407706, 4276.60680734753, 12026.3527366843, -4673.91068993608, 4378.59959338952, 5765.18302721289, 6358.89180162461, 11509.9960042998, 4719.09703456914, 6172.12643927364, -4168.95995251383, -18574.0374509989, 12235.9072211818, 2341.24385450480, 8094.99010096452, -9314.03527669514, 15278.6017183072, 628.536419071496, 4432.22563982795, 20402.9376320934,  [...]
+8524.09055029992, 21315.7858387721, 3393.7583888212, 4585.64219940783, 331.559822524163, -112.550986320496, 6895.01194806017, -21437.7175792478, -9998.77109652044, 6135.5557844868, -2080.65292794706, 1800.75591664326, -9905.21533566284, 2423.53763202513, 21669.2798291846, -13599.0159624404, -491.284068282368, 4046.93429960593, 3092.24303482567, 16581.2723430855, 7116.06670784999, -11589.1429680058, 14846.5738345177, 3053.89932266898, 5882.62552851528, -6171.64984872502, 5747.87070865405, [...]
+-8670.54815537264, 12830.4363593956, 11631.5718303116, 5854.04283028479, 9245.82950601145, 6475.7780096698, 15488.6033756618, -1609.50265754295, 3755.20406708535, -6944.05032684646, -1251.92873427672, 16763.2847671919, -4768.04985208984, -15.5942956129655, 10311.8792934853, -1245.32270885220, -8267.64422435744, -1838.47139045091, -4196.45548045313, 8212.30547028183, -1251.34275778736, 10335.1934487453, 3756.96679004765, -9483.3001731901, 2672.86432187358, -4414.42775438778, -579.60337360 [...]
+-11423.2057433313, -3999.76606003706, 5033.49620888353, -9000.2211976705, 6094.38350547683, -11368.0318449390, -10111.0534400000, -3292.47189592226, 5490.61065563354, 9746.10347197012, 4249.32069675747, -6641.80917521447, -5996.90581552434, 15647.9309901042, 17670.1765512451, -6574.90226287259, 12036.3981158797, 11879.5786073352, -1805.13706763971, 6362.17156825563, -9254.04883074017, 18847.408475695, -1005.20967445323, -1915.72489184815, -23843.20338833, 12692.4192318102, 15021.20221597 [...]
+2183.54883520745, -6446.32038412325, 1472.9903544033, -7362.53258847296, -1463.08803373558, 14605.7157271441, -2524.89768086586, 8829.30616378389, 2448.68955436758, 5070.91660284833, -1524.49023826074, -18461.0330086990, 10311.8096029440, -8350.51870082697, 10200.0496404716, 13750.0051042520, -388.182950253779, 2537.89531383414, 3182.34432630194, -3093.45923165547, 4841.21047420183, -25401.6942950006, -907.555943157156, -7387.64387546666, 1201.67241042633, -2454.83813234484, 3099.5697091 [...]
+9706.07232108605, -8944.25565015862, -225.039253012490, 2721.88653901985, -4524.95591502489, 9840.48331151935, -19968.1819736721, -4246.36457132553, -11329.6304135135, -4852.24682580483, 35311.9596915104, -5089.27130448442, 13976.0017292482, -14490.5784522764, -14383.6953790420, 3565.75680423442, -7951.55098754098, 1064.08152882362, -11031.8089291417, 11831.2088114626, 4083.81243279121, 6020.28467672318, 13764.0198829194, 12016.7644254382, 852.8221546684, -15843.1905658344, -5514.9058176 [...]
+8794.67082491526, 26341.2845027820, -26460.6921832110, -9148.41384927613, -1078.38557120536, -17216.0729830040, -16310.2018716438, -58.140863610012, 9945.03146534168, -1933.19494207255, 5000.5432957753, -3484.96731428736, -3711.99722161712, 8897.4054117893, 260.592047042488, -543.018652017273, 14761.0549010054, -12270.8525522976, -1345.29788336577, -10912.1784612693, -5164.47446871513, 19530.5888347654, -5866.84066265094, 13787.5889876360, -10853.0188654403, -3061.33701799430, -13474.445 [...]
+-11609.5019574612, -4489.15149534627, 19340.4523418149, 90.129400293831, -17803.0104488748, 17313.2359274621, 7419.058333722, 5477.77885199157, 241.795961179500, -2939.77941948242, 2875.37964010952, -7965.4930510157, -12359.8292831393, 10596.2233071222, 11365.0562088659, 13548.2874610703, 16214.7059492008, -18556.4479887764, 13875.5359840206, -5790.25156336167, 869.7679770779, 10259.6341478955, -7906.7424294445, 2676.79485776002, -14162.2820474565, 1687.21240720220, 16558.5434837866, 120 [...]
+1432.61586956054, 6264.77205157763, -4986.80055686798, -78.0860197599154, -15072.5241215382, 18476.1764491389, -7727.76976836992, -46.3656853214976, 803.204940028808, 37.0256692999277, 965.58318028061, 9590.6787548455, 19595.1136233668, 5991.96647109821, -13873.813963645, 12070.4911269004, 23382.3203879353, 10259.1827982356, -16594.0869622503, -9125.76578930646, -6720.56301089136, 1439.54301689877, -4646.55838982475, 20020.9318434486, 1709.02803323314, 14363.8444608007, 949.589952123643, [...]
+6060.91292167548, 6608.43931741522, -632.979052521775, 6745.28223915968, 2863.64993545548, -8822.73603776753, -2688.59596642398, -3173.82926699076, -17194.1266087406, 6396.66650498833, -3418.60469348179, 256.745724113315, 3237.19419651191, 12134.4630882025, -11501.0627583859, 2849.44251583990, -6182.13997880032, 6114.91167150261, 7885.0858292566, 4157.33953043139, -7354.09587370146, 15590.2871618830, 8105.58044715296, -6650.55214520119, 27797.377532535, -232.7748488406, 23618.3293969760, [...]
+15999.1767074744, 7671.00802743565, 10582.8706779387, -7920.11190333762, -4107.23546173991, -9424.0826966722, 8737.0265223652, 16022.4490553653, -13319.9727096585, 11046.4457681389, 13650.0768412787, 4809.05225692362, -297.635442660232, 1548.20843077958, 3588.14933251615, 3075.75698178806, 3103.94402690906, 8769.6996213255, 11680.0064533632, 3111.86011998138, -5888.99027864759, -1362.45278996407, 7748.17904579875, 445.440677360532, 7098.7537940126, 11322.5546386268, 5106.33722670497, -66 [...]
+3142.43106016365, -14143.7265884209, 6454.06032697153, 3404.25973470813, -1877.53003572703, 5565.37704205821, 1855.94578317945, -2072.73266666641, -1794.00256628176, 7481.00949097716, 1940.38489232351, 13135.7194509197, 15903.2406459078, -7445.16161673632, -7601.26572628161, -6972.00134065267, 21592.2022171718, 9938.11788188233, 323.506997674761, 1166.77437757192, -3316.78382829286, 4165.10370112308, -17602.0777407366, -7260.56778066736, 4946.82464479103, -21444.7479354799, -11468.783536 [...]
+-15186.8747968797, 7357.88572169953, 6480.08705911055, 1427.05892603958, 14304.3889942092, 8561.34655942681, 2134.42616048755, 3265.02237394978, 5412.36451621084, 6079.68807203162, 15805.360120106, -27387.6852065744, -15959.6459200978, 1580.58196186478, 2881.04617835317, 7287.1618160113, -2873.29232397725, -5481.80738813162, -9239.0587660965, 12459.5576715374, -17825.0480785379, -6283.61334721305, -5828.39475038205, -10989.6309207184, -7195.27861705791, 18593.3864741165, -6056.5446017472 [...]
+6388.21778542423, -20541.5012106321, -1914.39135329503, 4627.30739708472, -11437.9458293481, -7576.30207469605, 7011.34378527677, 11666.8884708779, -4883.79441646688, 2502.44672846736, 9786.79422104031, -6254.78374883815, 17321.0344432284, -2435.16143054194, 5183.11451032557, -1439.78854039292, -22033.2020136423, 8869.16553032506, 14245.9820408103, 14494.9837450938, 13306.6528223658, -5202.28443950704, 996.737233479235, -13515.2091063249, -23359.8697993341, 9695.41431091427, 328.63896746 [...]
+
+double y11[100] = {
+651081.855489435, -9761721.68965871, 77264425.7033847, 17740371.6494594, 61806302.7409431, 19088477.1962024, 102705629.439342, -110314141.391884, -112049356.927417, -75213158.6788419, -26921125.2256083, 2880907.78675606, -1187120.68620655, 103322787.649318, -41538557.4432389, 21488475.940429, 152783501.877487, 102069255.904980, -42760753.6750201, -25173754.8350064, -97961907.2948693, -78293391.6760678, 29882959.5205505, -44933576.0283187, 116154421.202354, 138249098.512276, -10133835.907 [...]
+
+double lars11[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 145.11972017561584000, 194.62858516533223000, 233.18313420342128000, 270.75869076607944000, 301.61868896164276000, 373.71348960783348000, 393.19148367304877000, 449.59202347793985000, 543.18797588931886000, 654.31971223065943000, 666.49916662854150000, 696.20129100631334000, 791.75609532238457000, 804.29872801959789000, 824.75810416423565000, 834.05740810483417000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -33.90409746780542800, -46.36302230920609400, -166.50923247434213000, -1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -28.48622689446384400, -74.96821101838976600, -92.99944594012112000, -266.45316977615198000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -222.09463407139043000, -508.67239263026369000, -536.25254403490544000, -589.98840079227944000, -762.56333836002671000, -789.16441898565836000, -830.05493722905055000, -843.57045246777000000, -978.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 72.55453856167102300, 136.94688211371459000, 202.50041948229125000, 259.71602742131859000, 376.94284759358192000, 410.22247910628516000, 506.42038775167913000, 612.37626133610490000, 769.60864426547676000, 787.24754904799158000, 813.45820181575868000, 890.91630309001027000, 904.53288501958309000, 919.15985187263072000, 924.83916931840463000, 9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -28.17577 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.45745618036983900, -72.80465004756189300, -224.30945147163851000, -253.07634746354600000, -301.03710860388662000, -320.78803641465987000, -520.578848126 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 78.02917636340301000, 166.60501674454554000, 267.42926655808634000, 278.43514279618574000, 296.33457215967729000, 355.62633535303075000, 360.28089794861938000, 364.90449811798010000, 366.17641040421728000, 390.326734930 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.69882932473732100, -100.48569062188962000, -288.15828638108246000, -564.96626545450886000, -593.95510881523978000, -645.48703370990904000, -800.59386072616155000, -820.97047955906055000, -852.98372327112224000, -863.88880707889552000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.55097007088464500, 150.97897859062147000, 168.30167956028515000, 197.07740287318236000, 209.24796830441463000, 346.02321703386565000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 208.49091003899497000, 230.96283092763295000, 377.87779569372634000, 425.03983857550145000, 465.70969490612373000, 501.18284572537533000, 532.99786121573345000, 595.24760810317832000, 610.37010872196367000, 659.19693472128711000, 655.85676454788711000, 667.46283529114828000, 670.38576793935010000, 672.87407136703177000, 680.67522493173556000, 677.95184880762713000, 679.29703967458090000, 678.1070080604723 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 30.80150540504471500, 221.64090860257227000, 279.53767143777219000, 325.94236571629926000, 379.10819160980122000, 427.04546478758010000, 526.23399042853669000, 549.88224760879496000, 614.78728028684407000, 720.55348644465312000, 823.40599697131984000, 828.12908074221696000, 829.23890417268365000, 828.39099074997364000, 831.88971813599960000, 838.69215163423758000, 842.0939850007231400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.78748831340094900, 133.56911823006084000, 156.62534365888698000, 214.23289503134100000, 315.86589982675315000, 435.03138533411220000, 444.77956932724356000, 473.53501333888175000, 557.08961258064710000, 568.99653849185131000, 585.06234281854188000, 591.78711915776637000, 667.952 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 58.95238886391443600, 69.09010681990062600, 79.60253355672362800, 83.68032179658276000, 145.89568202077353000, 156 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -124.52422842698820000, -148.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-360.21670609442862000, -877.12810957117313000, -928.18794429582306000, -1085.74063589003000000, -1360.34761154350510000, -1386.61870587858270000, -1573.01178424655090000, -1654.74528668268750000, -1717.94219552044480000, -1781.93100930819450000, -1841.81315481020760000, -1966.94287763102400000, -1992.81842997025390000, -2059.59894730541420000, -2174.17553978864590000, -2281.35255124823240000, -2294.77698351294610000, -2323.68775350926400000, -2415.91893674969920000, -2431.59115052473000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -57.94873732190073700, -110.94406746691801000, -217.45497386815765000, -244.33823943886526000, -319.71356846738888000, -439.70780463973171000, -624.83179531807400000, -642.04645552356988000, -678.20667709887550000, -772.52497488457857000, -787.96225823842144000, -807.11175235851090000, -813.34480119919 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 63.03981592105623800, 79.67908087093026400, 136.61883729236902000, 217.32999625588721000, 316.13173086666472000, 324.00059168451656000, 336.09926613526073000, 377.31019645236819000, 384.41096599367933000, 394.23208674158286000, 397.75751591831977000, 417.920336 [...]
+0.00000000000000000, -528.71753013684531000, -581.72720462776340000, -731.43607272060194000, -977.27986794631818000, -1005.51767021306130000, -1140.30049962079870000, -1182.91555313190820000, -1226.14655520669610000, -1267.47162317257560000, -1296.32106976578320000, -1360.90567642693850000, -1374.68579739843810000, -1438.54655072273980000, -1517.78559150603360000, -1615.23425379993730000, -1626.76366457299900000, -1635.13921148742220000, -1656.71929688783600000, -1664.67622384413700000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -290.73541200756546000, -322.16142140864281000, -385.39553859979537000, -571.98604094727841000, -599.75354943937043000, -642.04943964394465000, -658.67148261600880000, -814.8847 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 75.80516957215078800, 154.65067876247400000, 228.70258095583426000, 389.34083961882379000, 429.09002482914462000, 548.85723580240210000, 707.69597049043762000, 914.92788099223617000, 931.50879606043168000, 964.84173885380415000, 1060.20505793571560000, 1072.84211699224240000, 1089.57173805757570000, 1097.63212655874780000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 202.77202862981534000, 501.22945869524767000, 533.76842673536362000, 751.04284811490891000, 829.89780693261798000, 900.37686324049116000, 974.13227278207000000, 1039.65202295716200000, 1180.19161037462050000, 1214.95112160435660000, 1316.44138109861590000, 1467.17121883381720000, 1691.33902655755040000, 1713.04279079476560000, 1754.49546779965640000, 1875.90501646515100000, 1895.10334398800000000, 1922.65213962081110000, 1934 [...]
+0.00000000000000000, 0.00000000000000000, 54.86934722916127800, 210.84131045142786000, 465.35542614069760000, 493.04721180899548000, 666.17882282535652000, 733.56244034204383000, 785.06285119800339000, 842.29773823925950000, 887.64436276477568000, 981.25800366882277000, 1008.28892998649460000, 1094.82908364208240000, 1243.50755479086680000, 1421.41276911823460000, 1438.18759009879680000, 1463.86152626113880000, 1542.00737117445670000, 1552.43087430735860000, 1560.75632229989900000, 1561. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -12.32783000241722800, -121.07129772316851000, -138 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq11[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1350.95089418784100000, 1273.00480794419400000, 1205.19444694441790000, 1133.18244153740400000, 1051.31019736849430000, 1109.22150531159630000, 1137.58287849062440000, 1089.47423183346680000, 1185.70777047004340000, 1135.56986658240000000, 1181.46374274564230000, 1329.93240689484380000, 1358.36298466447120000, 1284.40851951349920000, 1331.74146410593650000, 1436.3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -874.04766433427960000, -853.23245355293716000, -810.91004232994430000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1118.88859973821760000, -1226.79182095192100000, -1260.74485343901280000, -1196.767325826349 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1746.73533684265700000, -1749.68234244897940000, -1702.38039454079310000, -1736.50856322085720000, -1785.87293805558260000, -1807.40672751806320000, -1843.32201742912800000, -1718.86717609785070000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1652.89957890646040000, 1760.36326093471350000, 1707.06702462259520000, 1649.67253838414670000, 1572.88576052705370000, 1682.07168687440280000, 1597.81650623102500000, 1339.74474657638800000, 1450.49523026677960000, 1533.04541714273520000, 1372.69450476231350000, 1350.21601210491890000, 1425.75155329162040000, 1281.61610413022910000, 1292.6451 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -853.1842 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1058.55333136314790000, -1104.35110544063450000, -1122.68044254538270000, -1354.22223684847950000, -1489.50481438307610000, -1599.90482153710470000, -1592. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 963.29520148125755000, 774.66262287226107000, 704.04339122298791000, 743.77917271723527000, 678.24076849836285000, 707.20595238065255000, 538.44932009813022000, 479.47731462606532000, 448.54845743493928000, 519.85631943 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -968.61512531726487000, -960.31193233722854000, -1576.49773449772810000, -1763.66869772564950000, -1819.64444970883550000, -1744.98361691802570000, -1720.32361581728040000, -1600.95140185677040000, -1646.27193230711900000, -1570.12781900426 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 838.74679913177249000, 823.56777756978943000, 831.38402849204215000, 910.13985339902149000, 997.44256233400415000, 1079.613406256792600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1665.04625935040120000, 1620.40143047419470000, 1598.62604568676920000, 1452.29880870029110000, 1491.05070983698620000, 1315.35276308113090000, 1305.88990099501390000, 1230.31681421610600000, 1188.30741022523740000, 1213.15293151705960000, 632.92708224448154000, 717.72231580044320000, 793.97149871410659000, 725.96506539283621000, 726.93336324528218000, 573.70582848083791000, 712.63087061203100000, 601.037 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1935.25821589255770000, 1807.36682736115650000, 1540.61470138614370000, 1495.86625092254050000, 1599.35547932384270000, 1591.60051141512800000, 1538.15100831152380000, 1453.64877964888840000, 1351.15568716893770000, 1446.61993807291990000, 1268.80339825361630000, 1027.82774971285330000, 852.91834312739968000, 823.36315787111619000, 965.81481315788517000, 1007.25646006357860000, 1062.4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1107.53052403854140000, 1049.51739570326070000, 1037.76617103199760000, 867.80903663705828000, 1013.55864915370930000, 951.07126900578817000, 856.94659043840682000, 1087.06754689070340000, 1052.53944271167710000, 1024.77259879470330000, 983.17298901467268000, 1027.29953528863530000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 408.51963367747163000, 457.14401635947536000, 340.10047789762774000, 347.76752993946576000, 479.58601198475878000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -792.40641576110204000, -839.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-3885.77098867263020000, -3309.21439197052310000, -3093.68669188259260000, -3265.09585657283470000, -3278.80179869001450000, -3010.96015414086240000, -3121.79222734697440000, -3435.02172101167890000, -3311.22007979488440000, -3250.58451287548540000, -3296.54868990484970000, -3243.51085913030150000, -2981.70560351513630000, -2817.24532897783140000, -2960.72374801154090000, -2745.47697696097110000, -2862.38098653078350000, -2940.53435673318520000, -2962.81790441796690000, -3031.49576938913 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1387.97208136150430000, -1398.37606092208780000, -1304.07460130066990000, -1271.73723588727990000, -1174.87084464142940000, -1263.44718641828940000, -1426.50152550675880000, -1369.90666223895370000, -1449.72918768550880000, -1331.79980882832340000, -1378.87415617612760000, -1281.63623451048810000, -12 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 706.16927189905016000, 715.58263455850681000, 782.61863105704560000, 771.39794408422881000, 743.98745954539197000, 656.70716812148532000, 594.23926861199050000, 621.67673773722584000, 656.21586263890890000, 637.59946803244600000, 626.07264510758296000, 526.0630 [...]
+0.00000000000000000, -3016.35205253471900000, -2829.92061024894380000, -2802.29122574445320000, -2694.78925463401990000, -2751.46064634794450000, -2260.24021025931550000, -2111.13437714200520000, -2316.05745096920740000, -2215.95311955662920000, -1997.16962445799460000, -2019.79502024349720000, -1901.32131419677490000, -2163.06727349883610000, -2061.74770626801730000, -2037.23057379144260000, -2114.24347587407600000, -1813.84173877959140000, -1784.68172795534910000, -1969.253311776444700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1549.74986197895150000, -1650.89759312844030000, -1734.57269307178100000, -1678.40308478505470000, -1662.64465326683060000, -1690.14163835256980000, -1735.15428748943190000, -1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1986.95402818248840000, 1964.29093396414400000, 2027.66841056881980000, 2028.16535700884470000, 1948.18646373884800000, 1907.65464645244040000, 1798.09602042690310000, 1812.33479821411290000, 1632.57336108820890000, 1676.04080204610500000, 1625.67650616985470000, 1556.56638247864950000, 1504.13176365625650000, 1619.6419442 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 3007.62591421763770000, 2586.30725044277690000, 2545.65243115120480000, 2556.42305624837810000, 2547.47530855554260000, 2677.24734290511510000, 2666.94597283878060000, 2631.34363706316890000, 2613.97035922677240000, 2543.35696056539750000, 2467.88091689771360000, 2501.90511366229750000, 2662.08595825654400000, 2630.70867183016160000, 2638.93898169645080000, 2595.82158369747590000, 2629.98135935669640000, 2605.3113210900560000 [...]
+0.00000000000000000, 0.00000000000000000, 2381.93333688775240000, 2368.33102953593200000, 2243.43724569403780000, 2205.22998819804430000, 2104.76686253386470000, 2201.27718092263060000, 2083.45650931983350000, 2155.93698865948590000, 1989.26397810813930000, 1936.30029031086630000, 2041.33108399131150000, 2076.65487509952300000, 2264.15917785698500000, 2191.82196700976650000, 2147.45077164144320000, 2011.64632463025010000, 2005.38516173414200000, 1951.42413485986550000, 1767.0609313182031 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -810.70724950628608000, -704.31382005861531000, -64 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso11[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 145.11972017561584000, 194.62858516533223000, 233.18313420342128000, 270.75869076607944000, 301.61868896164276000, 373.71348960783348000, 393.19148367304877000, 449.59202347793985000, 543.18797588931886000, 654.31971223065943000, 666.49916662854150000, 696.20129100631334000, 791.75609532238457000, 804.29872801959789000, 824.75810416423565000, 834.05740810483417000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -33.90409746780542800, -46.36302230920609400, -166.50923247434213000, -1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -28.48622689446384400, -74.96821101838976600, -92.99944594012112000, -266.45316977615198000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -222.09463407139043000, -508.67239263026369000, -536.25254403490544000, -589.98840079227944000, -762.56333836002671000, -789.16441898565836000, -830.05493722905055000, -843.57045246777000000, -978.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 72.55453856167102300, 136.94688211371459000, 202.50041948229125000, 259.71602742131859000, 376.94284759358192000, 410.22247910628516000, 506.42038775167913000, 612.37626133610490000, 769.60864426547676000, 787.24754904799158000, 813.45820181575868000, 890.91630309001027000, 904.53288501958309000, 919.15985187263072000, 924.83916931840463000, 9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -28.17577 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.45745618036983900, -72.80465004756189300, -224.30945147163851000, -253.07634746354600000, -301.03710860388662000, -320.78803641465987000, -520.578848126 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 78.02917636340301000, 166.60501674454554000, 267.42926655808634000, 278.43514279618574000, 296.33457215967729000, 355.62633535303075000, 360.28089794861938000, 364.90449811798010000, 366.17641040421728000, 390.326734930 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.69882932473732100, -100.48569062188962000, -288.15828638108246000, -564.96626545450886000, -593.95510881523978000, -645.48703370990904000, -800.59386072616155000, -820.97047955906055000, -852.98372327112224000, -863.88880707889552000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.55097007088464500, 150.97897859062147000, 168.30167956028515000, 197.07740287318236000, 209.24796830441463000, 346.02321703386565000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 208.49091003899497000, 230.96283092763295000, 377.87779569372634000, 425.03983857550145000, 465.70969490612373000, 501.18284572537533000, 532.99786121573345000, 595.24760810317832000, 610.37010872196367000, 659.19693472128711000, 655.85676454788711000, 667.46283529114828000, 670.38576793935010000, 672.87407136703177000, 680.67522493173556000, 677.95184880762713000, 679.29703967458090000, 678.1070080604723 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 30.80150540504471500, 221.64090860257227000, 279.53767143777219000, 325.94236571629926000, 379.10819160980122000, 427.04546478758010000, 526.23399042853669000, 549.88224760879496000, 614.78728028684407000, 720.55348644465312000, 823.40599697131984000, 828.12908074221696000, 829.23890417268365000, 828.39099074997364000, 831.88971813599960000, 838.69215163423758000, 842.0939850007231400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.78748831340094900, 133.56911823006084000, 156.62534365888698000, 214.23289503134100000, 315.86589982675315000, 435.03138533411220000, 444.77956932724356000, 473.53501333888175000, 557.08961258064710000, 568.99653849185131000, 585.06234281854188000, 591.78711915776637000, 667.952 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 58.95238886391443600, 69.09010681990062600, 79.60253355672362800, 83.68032179658276000, 145.89568202077353000, 156 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -124.52422842698820000, -148.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-360.21670609442862000, -877.12810957117313000, -928.18794429582306000, -1085.74063589003000000, -1360.34761154350510000, -1386.61870587858270000, -1573.01178424655090000, -1654.74528668268750000, -1717.94219552044480000, -1781.93100930819450000, -1841.81315481020760000, -1966.94287763102400000, -1992.81842997025390000, -2059.59894730541420000, -2174.17553978864590000, -2281.35255124823240000, -2294.77698351294610000, -2323.68775350926400000, -2415.91893674969920000, -2431.59115052473000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -57.94873732190073700, -110.94406746691801000, -217.45497386815765000, -244.33823943886526000, -319.71356846738888000, -439.70780463973171000, -624.83179531807400000, -642.04645552356988000, -678.20667709887550000, -772.52497488457857000, -787.96225823842144000, -807.11175235851090000, -813.34480119919 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 63.03981592105623800, 79.67908087093026400, 136.61883729236902000, 217.32999625588721000, 316.13173086666472000, 324.00059168451656000, 336.09926613526073000, 377.31019645236819000, 384.41096599367933000, 394.23208674158286000, 397.75751591831977000, 417.920336 [...]
+0.00000000000000000, -528.71753013684531000, -581.72720462776340000, -731.43607272060194000, -977.27986794631818000, -1005.51767021306130000, -1140.30049962079870000, -1182.91555313190820000, -1226.14655520669610000, -1267.47162317257560000, -1296.32106976578320000, -1360.90567642693850000, -1374.68579739843810000, -1438.54655072273980000, -1517.78559150603360000, -1615.23425379993730000, -1626.76366457299900000, -1635.13921148742220000, -1656.71929688783600000, -1664.67622384413700000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -290.73541200756546000, -322.16142140864281000, -385.39553859979537000, -571.98604094727841000, -599.75354943937043000, -642.04943964394465000, -658.67148261600880000, -814.8847 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 75.80516957215078800, 154.65067876247400000, 228.70258095583426000, 389.34083961882379000, 429.09002482914462000, 548.85723580240210000, 707.69597049043762000, 914.92788099223617000, 931.50879606043168000, 964.84173885380415000, 1060.20505793571560000, 1072.84211699224240000, 1089.57173805757570000, 1097.63212655874780000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 202.77202862981534000, 501.22945869524767000, 533.76842673536362000, 751.04284811490891000, 829.89780693261798000, 900.37686324049116000, 974.13227278207000000, 1039.65202295716200000, 1180.19161037462050000, 1214.95112160435660000, 1316.44138109861590000, 1467.17121883381720000, 1691.33902655755040000, 1713.04279079476560000, 1754.49546779965640000, 1875.90501646515100000, 1895.10334398800000000, 1922.65213962081110000, 1934 [...]
+0.00000000000000000, 0.00000000000000000, 54.86934722916127800, 210.84131045142786000, 465.35542614069760000, 493.04721180899548000, 666.17882282535652000, 733.56244034204383000, 785.06285119800339000, 842.29773823925950000, 887.64436276477568000, 981.25800366882277000, 1008.28892998649460000, 1094.82908364208240000, 1243.50755479086680000, 1421.41276911823460000, 1438.18759009879680000, 1463.86152626113880000, 1542.00737117445670000, 1552.43087430735860000, 1560.75632229989900000, 1561. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -12.32783000241722800, -121.07129772316851000, -138 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq11[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1350.95089418784100000, 1273.00480794419400000, 1205.19444694441790000, 1133.18244153740400000, 1051.31019736849430000, 1109.22150531159630000, 1137.58287849062440000, 1089.47423183346680000, 1185.70777047004340000, 1135.56986658240000000, 1181.46374274564230000, 1329.93240689484380000, 1358.36298466447120000, 1284.40851951349920000, 1331.74146410593650000, 1436.3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -874.04766433427960000, -853.23245355293716000, -810.91004232994430000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1118.88859973821760000, -1226.79182095192100000, -1260.74485343901280000, -1196.767325826349 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1746.73533684265700000, -1749.68234244897940000, -1702.38039454079310000, -1736.50856322085720000, -1785.87293805558260000, -1807.40672751806320000, -1843.32201742912800000, -1718.86717609785070000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1652.89957890646040000, 1760.36326093471350000, 1707.06702462259520000, 1649.67253838414670000, 1572.88576052705370000, 1682.07168687440280000, 1597.81650623102500000, 1339.74474657638800000, 1450.49523026677960000, 1533.04541714273520000, 1372.69450476231350000, 1350.21601210491890000, 1425.75155329162040000, 1281.61610413022910000, 1292.6451 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -853.1842 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1058.55333136314790000, -1104.35110544063450000, -1122.68044254538270000, -1354.22223684847950000, -1489.50481438307610000, -1599.90482153710470000, -1592. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 963.29520148125755000, 774.66262287226107000, 704.04339122298791000, 743.77917271723527000, 678.24076849836285000, 707.20595238065255000, 538.44932009813022000, 479.47731462606532000, 448.54845743493928000, 519.85631943 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -968.61512531726487000, -960.31193233722854000, -1576.49773449772810000, -1763.66869772564950000, -1819.64444970883550000, -1744.98361691802570000, -1720.32361581728040000, -1600.95140185677040000, -1646.27193230711900000, -1570.12781900426 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 838.74679913177249000, 823.56777756978943000, 831.38402849204215000, 910.13985339902149000, 997.44256233400415000, 1079.613406256792600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1665.04625935040120000, 1620.40143047419470000, 1598.62604568676920000, 1452.29880870029110000, 1491.05070983698620000, 1315.35276308113090000, 1305.88990099501390000, 1230.31681421610600000, 1188.30741022523740000, 1213.15293151705960000, 632.92708224448154000, 717.72231580044320000, 793.97149871410659000, 725.96506539283621000, 726.93336324528218000, 573.70582848083791000, 712.63087061203100000, 601.037 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1935.25821589255770000, 1807.36682736115650000, 1540.61470138614370000, 1495.86625092254050000, 1599.35547932384270000, 1591.60051141512800000, 1538.15100831152380000, 1453.64877964888840000, 1351.15568716893770000, 1446.61993807291990000, 1268.80339825361630000, 1027.82774971285330000, 852.91834312739968000, 823.36315787111619000, 965.81481315788517000, 1007.25646006357860000, 1062.4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1107.53052403854140000, 1049.51739570326070000, 1037.76617103199760000, 867.80903663705828000, 1013.55864915370930000, 951.07126900578817000, 856.94659043840682000, 1087.06754689070340000, 1052.53944271167710000, 1024.77259879470330000, 983.17298901467268000, 1027.29953528863530000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 408.51963367747163000, 457.14401635947536000, 340.10047789762774000, 347.76752993946576000, 479.58601198475878000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -792.40641576110204000, -839.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-3885.77098867263020000, -3309.21439197052310000, -3093.68669188259260000, -3265.09585657283470000, -3278.80179869001450000, -3010.96015414086240000, -3121.79222734697440000, -3435.02172101167890000, -3311.22007979488440000, -3250.58451287548540000, -3296.54868990484970000, -3243.51085913030150000, -2981.70560351513630000, -2817.24532897783140000, -2960.72374801154090000, -2745.47697696097110000, -2862.38098653078350000, -2940.53435673318520000, -2962.81790441796690000, -3031.49576938913 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1387.97208136150430000, -1398.37606092208780000, -1304.07460130066990000, -1271.73723588727990000, -1174.87084464142940000, -1263.44718641828940000, -1426.50152550675880000, -1369.90666223895370000, -1449.72918768550880000, -1331.79980882832340000, -1378.87415617612760000, -1281.63623451048810000, -12 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 706.16927189905016000, 715.58263455850681000, 782.61863105704560000, 771.39794408422881000, 743.98745954539197000, 656.70716812148532000, 594.23926861199050000, 621.67673773722584000, 656.21586263890890000, 637.59946803244600000, 626.07264510758296000, 526.0630 [...]
+0.00000000000000000, -3016.35205253471900000, -2829.92061024894380000, -2802.29122574445320000, -2694.78925463401990000, -2751.46064634794450000, -2260.24021025931550000, -2111.13437714200520000, -2316.05745096920740000, -2215.95311955662920000, -1997.16962445799460000, -2019.79502024349720000, -1901.32131419677490000, -2163.06727349883610000, -2061.74770626801730000, -2037.23057379144260000, -2114.24347587407600000, -1813.84173877959140000, -1784.68172795534910000, -1969.253311776444700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1549.74986197895150000, -1650.89759312844030000, -1734.57269307178100000, -1678.40308478505470000, -1662.64465326683060000, -1690.14163835256980000, -1735.15428748943190000, -1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1986.95402818248840000, 1964.29093396414400000, 2027.66841056881980000, 2028.16535700884470000, 1948.18646373884800000, 1907.65464645244040000, 1798.09602042690310000, 1812.33479821411290000, 1632.57336108820890000, 1676.04080204610500000, 1625.67650616985470000, 1556.56638247864950000, 1504.13176365625650000, 1619.6419442 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 3007.62591421763770000, 2586.30725044277690000, 2545.65243115120480000, 2556.42305624837810000, 2547.47530855554260000, 2677.24734290511510000, 2666.94597283878060000, 2631.34363706316890000, 2613.97035922677240000, 2543.35696056539750000, 2467.88091689771360000, 2501.90511366229750000, 2662.08595825654400000, 2630.70867183016160000, 2638.93898169645080000, 2595.82158369747590000, 2629.98135935669640000, 2605.3113210900560000 [...]
+0.00000000000000000, 0.00000000000000000, 2381.93333688775240000, 2368.33102953593200000, 2243.43724569403780000, 2205.22998819804430000, 2104.76686253386470000, 2201.27718092263060000, 2083.45650931983350000, 2155.93698865948590000, 1989.26397810813930000, 1936.30029031086630000, 2041.33108399131150000, 2076.65487509952300000, 2264.15917785698500000, 2191.82196700976650000, 2147.45077164144320000, 2011.64632463025010000, 2005.38516173414200000, 1951.42413485986550000, 1767.0609313182031 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -810.70724950628608000, -704.31382005861531000, -64 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso11[1500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 89.92278614625608700, 401.46006914563276000, 444.01836250000957000, 489.68483869735326000, 613.00882769510736000, 733.30887656157256000, 762.32106320803996000, 788.31710909414358000, 1137.69717088405470000, 1387.35538591350220000, 1410.08138135786070000, 1510.88165462773420000, 1551.05925399828240000, 1576.07318420308750000, 1607.03592181809560000, 1633.69317313139000000, 1742.52262224716610000, 1808.97114968454120000, 1829.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 104.46221648918164000, 137.61228937377831000, 199.18413300958201000, 206 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 125.38548342563047000, 146.12133390792815000, 163.00673926574294000, 381.17617047761331000, 450.15591358517867000, 457.89402255323694000, 504.67729594612780000, 533.22878832018114000, 562.87553543907427000, 600.58088410552148000, 630.98515279561866000, 733.46487432837421000, 772.48181581596111000, 784.74333602791012000, 81 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 16.849388 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 25.30499735286607800, 378.95750767725883000, 625.15321514434970000, 646.89638684732188000, 726.65280489062809000, 752.50465394947503000, 770.12829540361315000, 793.55405179271531000, 825.55886551205197000, 903.82340194374069000, 969.17625926246251000, 989.66677767515716000, 1012.56 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 55.54202954634055800, 204.89012600756604000, 308.03171779855666000, 340.17416013322668000, 401.82975594708392000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 168.93158799870528000, 246.42278073545268000, 300.05542177379954000, 363.85121058957247000, 417.73422490360491000, 580.22242658945754000, 696.70669278806099000, 732.61220634193103000, 823.2162406024 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 31.23552435415463100, 59.58978500145944000, 421.38017541863883000, 677.90896428260112000, 698.50347979742685000, 801.12594867100006000, 839.22424363440803000, 865.02911861358791000, 890.15577502267934000, 913.84232796571018000, 978.17296214048417000, 1017.36805546176230000, 1028.87427383910610000, 1047 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 81.87286374699063200, 144.65532039328042000, 226.08232152478956000, 300.61209393489742000, 445.05304060879990000, 541.05013975513532000, 571.26212137084440000, 626.2013204990931 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 84.78493233365701100, 94.09628 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 29.30800141650662400, 163.63893375918616000, 227.81662602950527000, 274.53077276384670000, 337.42303298438998000, 396.99050231540400000, 547.26998529411094000, 632.82470331510763000, 659.34180162836697000, 707.713075571 [...]
+0.00000000000000000, 0.00000000000000000, 66.38871555163223100, 139.74319772747810000, 406.72116566338286000, 446.98446030004988000, 480.19905801119114000, 576.48090876281583000, 669.66603213743451000, 687.14598545038234000, 703.27402820297982000, 921.29935179191375000, 1032.61006665220630000, 1041.77061163036230000, 1103.73567338322390000, 1140.21632355960200000, 1172.02520490067720000, 1215.18682132090980000, 1257.23148459394500000, 1363.98817916144160000, 1436.14071568880170000, 1459. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 370.23321805797246000, 427.26185364875005000, 479.06348148776652000, 616.85358259211637000, 746.91172519523457000, 768.86694279419294000, 785.01737572398702000, 981.32289629676563000, 1086.44055289354630000, 1092.93166581092330000, 1116.76736132553240000, 1138.74431327778920000, 1153.59694239295620000, 1165.90991934656290000, 1171.23175632560240000, 1184.11373201100100000, 1204.33848060743410000, 1210.815 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 42.97621749281881200, 81.25217174606881100, 201.37965618027809000, 320.51865190138716000, 352.78103276455789000, 378.26691547607061000, 685.69545478577538000, 909.61849066027889000, 928.87149560238902000, 997.02697937882874000, 1036.80116207383160000, 1059.89022543086910000, 1095.91814211989190000, 1128.82538754106710000, 1230.44182699915250000, 1266.12147966851650000, 1276.5841042414 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 293.55732073637711000, 498.84230840163934000, 517.65670749319713000, 624.22087717112197000, 665.65312831365748000, 698.79865528845880000, 743.09933434432344000, 787.26025451828332000, 932.20937553439762000, 1044.84102855122270000, 1080.05915674081370000, 1156.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 428.34966368610458000, 467.73223434624640000, 641.02624330414233000, 719.80301151592118000, 775.10473849269567000, 848.80888233018868000, 919.57580610526361000, 1125.91882340302800000, 1239.70973697579280000, 1274.83320028366300000, 1352.41 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 49.13711124895776500, 184.76189449406138000, 305.70186253673097000, 330.57653080679819000, 353.43295590772379000, 660.06285872082185000, 886.14070534563837000, 910.30122529108007000, 1019.80287664208150000, 1067.56405115403600000, 1112.21038623790040000, 1168.46099548388340000, 1213.71247865635360000, 1296.00131550400600000, 1334.66507144246730000, 1346.9688344560 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 181.83669942886763000, 381.70544425263091000, 427.12718942518524000, 465.92435141930514000, 948.31557019620220000, 1267.21646506282150000, 1301.41688008498500000, 1465.03873049527940000, 1537.23410270680710000, 1585.23335074021160000, 1643.38071019852760000, 1697.93391725931770000, 1835.36848547487260000, 1931.97908127968000000, 1962.155058442 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 48.76484109511630300, 86.23266595088701100, 238.34562174645868000, 315.17103889270658000, 339.00598272471188000, 410.49315450410933000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.31872074635255920, 1.69127589933838810, 2.7535043 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 46.19309231646149500, 105.37930095630935000, 158.06994185748738000, 311.67158853425394000, 411.75537197005588000, 443.50230527780997000, 511.805868057951440 [...]
+0.00000000000000000, 78.43719797022856700, 161.91274141543565000, 258.96912748941810000, 616.57441109048466000, 670.19851178121951000, 722.05188558366478000, 876.66778792156492000, 1038.96274970630860000, 1073.72219894135200000, 1102.74317050289710000, 1460.50594180765640000, 1605.31943712384740000, 1625.86650103600230000, 1725.86774809714280000, 1786.38524220054750000, 1838.59344364223920000, 1903.07870101833300000, 1958.31914496423590000, 2130.82726878241780000, 2268.43643955434120000, [...]
+244.93094267122277000, 319.45219011178392000, 409.45151492885714000, 504.49584945099411000, 850.81675554008859000, 897.80099859657071000, 940.96920290584569000, 1046.02000333877530000, 1167.86708962559310000, 1189.21772317015760000, 1209.16458874432690000, 1471.64281221481020000, 1551.00096036454970000, 1564.10568117748490000, 1650.15040625300320000, 1686.03977251851530000, 1712.72757026837080000, 1751.28474093166390000, 1782.31453031999850000, 1899.77518666979630000, 1970.80502844134300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 174.30272653532504000, 266.83303240676827000, 295.09006285732704000, 376.94045042972687000, 3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlassolsq11[1500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2050.87568955851200000, 1907.29131847197120000, 1733.98976249153250000, 1845.35326686120380000, 1819.87931644986000000, 1731.00465742292930000, 1848.16235430891470000, 1855.78910819587800000, 1868.09966067235020000, 2074.95238471074480000, 2039.66045577216570000, 2020.15050605248530000, 1976.29932618085150000, 1905.97957851013100000, 1894.53335164955640000, 1883.86734343264700000, 1991.97262975029930000, 1986.5434348274346000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 383.61956140638620000, 387.39020205707737000, 364.49637036880091000, 368 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1165.25678001896970000, 922.20356907838095000, 856.36977962662502000, 837.27402258878340000, 640.13670125111719000, 672.26313539385808000, 741.03840027468493000, 835.41803975073003000, 953.88372027233413000, 950.68528919043172000, 916.32450019368127000, 968.36055296099823000, 876.74789553860103000, 877.13097377237398000, 8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 404.65157 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1064.40056711287660000, 1118.29183814097950000, 1303.21393728468980000, 1249.24825957845770000, 1129.60269870610730000, 1026.12085631260920000, 1002.56486011338170000, 1011.06856350889710000, 1125.91907984098630000, 1083.21500374579230000, 1143.82055406101900000, 1144.0579591587950 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 576.79536490706300000, 547.21367983901462000, 583.65991986613312000, 582.35981634117002000, 566.62652963628716000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1022.41732765663900000, 1066.59025985674450000, 1007.41132615406830000, 956.21243996985390000, 923.41795954360907000, 952.66466036927363000, 1007.99090223232960000, 1003.15170894057440000, 1064.7602 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1200.28984301778540000, 1223.89682726629640000, 1177.72729090197000000, 1384.42857673415530000, 1269.03408857010550000, 1319.60099996073400000, 1242.45693931777120000, 1205.36720983804710000, 1123.46360547661400000, 1136.13695467631330000, 1125.62640703026840000, 1122.11021538408390000, 1115.5708919484 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 948.41598814991596000, 972.68729011296853000, 982.15414680308879000, 1000.06245197468350000, 776.12882500640285000, 797.58591142545890000, 798.90221532383373000, 773.42686048277 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 310.82948925220160000, 308.404 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 841.22862552795164000, 842.31328062148145000, 907.07389677491665000, 890.63930053514980000, 921.39475391300766000, 956.02196590070128000, 891.72838751137556000, 861.45500363383519000, 859.14182892125780000, 836.84346331 [...]
+0.00000000000000000, 0.00000000000000000, 1814.75977805711250000, 1739.38986088879870000, 1697.17270690101650000, 1667.39285680805920000, 1466.21736335564170000, 1518.71222336083430000, 1442.48703517044830000, 1341.36951244624270000, 1365.53759375225650000, 1377.09593723648910000, 1339.17684020253860000, 1295.54552074703340000, 1416.79906898390910000, 1526.32785230468830000, 1591.54957649098330000, 1615.95415470338780000, 1651.81413028035920000, 1608.68718735490670000, 1628.9559861565253 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2159.77424481033950000, 2155.83936685102940000, 2016.86182365398370000, 1965.29201713222910000, 1825.53522838125200000, 1590.58652272652530000, 1448.20034599031440000, 1391.71277444546010000, 1375.95069454067810000, 1272.75520192166100000, 1237.19141260896410000, 1371.34856990196640000, 1349.48688360752020000, 1280.23925520025230000, 1221.17637120964900000, 1213.64074843427920000, 1258.38565009653710000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1345.61518809078440000, 1217.52339431071100000, 1376.96858279725070000, 1308.58536082642790000, 1560.26758720250110000, 1424.79015543826200000, 1328.39546861430180000, 1526.33686065549450000, 1462.23818842009340000, 1341.36597584362740000, 1457.77146854325970000, 1364.40973026996770000, 1430.44713561739630000, 1437.65478346744660000, 1463.35876070792070000, 1361.46922779694250000, 135 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 907.25862029812163000, 1064.22863626637240000, 1038.87268655671480000, 1162.61041258053390000, 1104.17244610677700000, 1135.95192157377510000, 1154.44317372679320000, 1201.70364308890910000, 1264.44995580763480000, 1345.82979048381140000, 1345.41937415066240000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1608.09030691562250000, 1558.74901488613270000, 1516.55205328381270000, 1553.57703299820830000, 1504.47406176502980000, 1533.17187970728330000, 1583.71241314443020000, 1598.88149693809780000, 1543.79642378246100000, 1539.48014033080650000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1507.83583114847030000, 1512.01014337495370000, 1308.70474566618600000, 1261.56261052597320000, 1291.98314549046720000, 1301.09326930247450000, 1508.79375449698110000, 1579.62098388477830000, 1573.03332338239720000, 1573.06875066765860000, 1701.04673886001930000, 1690.76318289883100000, 1638.39063187345640000, 1484.61709125082440000, 1437.98732340162790000, 1439.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1961.32297859281080000, 2039.29582194291790000, 2127.13026134898790000, 2059.04679222388360000, 1956.78681907509390000, 2145.51841958964720000, 2248.87221540601470000, 2291.69831308737680000, 2301.35056987885990000, 2218.29095978030770000, 2183.29473859014930000, 2209.90730691256610000, 2150.38481929908080000, 2190.15431747651340000, 2189.5238 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 501.55963770863940000, 437.86239274160761000, 587.00656115967240000, 520.47378081685770000, 518.59661409398007000, 601.2643721193670700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 36.85925413345210400, 0.00000000000000000, 27.20154 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 655.42948192982340000, 654.93932620346095000, 652.56343689835614000, 663.74478404635545000, 679.21210601418193000, 682.70789506072947000, 695.00020822969498 [...]
+0.00000000000000000, 2820.10885791263040000, 2360.27165488187980000, 2375.48497650819080000, 2345.07767653037440000, 2295.58220997878110000, 2261.38637362201690000, 2389.76650569979940000, 2384.93891641118260000, 2374.66671909287700000, 2294.42726986191880000, 2208.43304896950710000, 2004.15800429459520000, 2195.08255634227230000, 2231.09971404153200000, 2426.90294271065800000, 2527.16254693235620000, 2501.84183327640680000, 2476.74214622645790000, 2526.23635272455890000, 2636.1733308438 [...]
+2923.56247239418830000, 2924.24682146628860000, 2779.61659264941090000, 2577.13474023151460000, 2524.77641026627410000, 2321.92600493635250000, 2222.47319786516800000, 2074.06581902250580000, 2178.39306234193370000, 1988.30949023881700000, 2028.23994211006290000, 2020.37117111392650000, 1769.56546660934330000, 1927.14623621349100000, 2084.87044111886330000, 2065.89314704641810000, 2064.71044763160440000, 2109.29854465606700000, 2073.52429248245790000, 2169.00894504901090000, 2160.6200898 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 573.82525279380263000, 514.10439404903241000, 508.00006486967641000, 594.82363245797217000, 5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+
+
+// Data from file x59.txt and y59.txt
+double x12[5000] = {
+28814.8089647716, 17180.8080867462, -12.1528073167832, -4108.78275117086, 16453.9300197383, -14117.9854898883, -6967.60201673342, -12121.5437790677, 5580.41135422182, -9035.17532003378, 7128.14958190403, 225.993539285981, 14519.4588535114, 1852.67338353282, 3082.05236660027, -5319.92119592139, -13575.6863651175, 6477.0129081437, -331.288846008922, -3650.38417437955, -13968.8580328479, 3029.82563846585, 1914.94572020473, -2782.32626294707, 6315.89493614398, 18991.4118115359, 424.913489615 [...]
+1474.45275120288, -23071.6907208011, -1062.89742902017, 2988.829088579, -2464.44886256714, -8668.19639836712, 22358.2864483802, -10270.9231080546, 5787.71360614413, -3949.32043227824, -15490.7140874073, 12812.3218485054, -3242.17279652288, 20725.0775211478, 16011.4969304473, -2590.02593217467, -16402.1709394926, 3752.09845421931, 7500.85861220698, -936.359305676602, -2298.30098769305, -6858.75976138775, 10216.4432925018, 11187.7946675104, 4164.66468087646, 7167.57865813061, 6349.95494377 [...]
+-14339.2806389363, -12341.0927698885, -4188.17402378172, 9035.88480389416, -1646.90001971228, 6006.37178982272, 6598.98599480581, 2864.15651300446, -12480.1390098939, 18773.7986375579, -25308.1907976507, 3570.21282224865, 15233.4243955019, -1106.56757038126, 11274.8071270236, 10183.9941889276, 10394.9183479256, -3512.3752418246, 8742.92599457266, 10604.7301207053, -564.926965901194, -5410.68123069082, 5538.24162834197, -5057.42139500969, -18753.0679594549, 25327.8156354707, -4371.2575606 [...]
+22566.2014387686, -13640.5181532665, -3522.09637760997, 1034.16661390916, 7776.28588713118, -6795.13632486812, 12618.2372734627, 6093.44960855108, -16233.1278516486, 1442.05990660998, 8514.32447568728, -1082.45488413108, 8874.70697863507, 23777.9205154602, 478.905820288068, -8064.2761925338, -27829.7135167053, 2331.21619147016, 11782.8606451605, -24100.4865306800, 6717.28888049597, -9858.54176268438, 31.6902118512549, 2777.42799486525, 1425.58211443786, -432.120932297446, 8862.2648753545 [...]
+2518.49580807843, 852.581250587478, -25520.8000174004, 2619.20932385516, 14743.6731535028, 6953.18260426277, -7052.71783687355, -1998.51874536662, 891.097252933193, -7691.48742684088, 2017.72091013019, -1012.02407370704, 6061.88426048973, 2368.40637319106, -6811.2430984285, 8640.10959072623, -6278.93131038641, 5958.62680547451, -4981.70696341764, -2075.51937261551, -18272.1787587903, 3600.62602975795, 6910.45420572998, -3512.17651091273, 541.663462693303, 165.247611349273, 2037.906541758 [...]
+14464.8390152822, 7933.24753771247, 9275.90910394043, -406.932627134074, 10640.085357939, 11014.8928136347, 11923.6371100843, 2438.66434414192, 7653.39006751295, 65.1330362435402, 18428.1283446253, 5949.65303379234, 6852.42401146998, -3269.66835841058, -1790.33671439660, -7899.65625104094, -3823.75205491517, -4298.45708438315, 32797.8154319788, 2148.06095885751, -3745.09832560115, -3052.18047402774, -8685.07469711874, 14523.4656030401, -1038.62675342209, -14555.5589419758, 592.5437413458 [...]
+-15779.4980022471, -3760.43658335460, 14745.3982001037, 719.103917023887, 1590.82923403743, -4958.86985750371, -12392.0579134679, 8083.80318573898, -21729.5761150464, -17569.0704059226, -14780.3445797257, 9365.76787938948, -363.698287243710, 11183.7839929981, -15514.3146469521, 2147.78258342667, 7306.96166008468, 7104.09611002098, 5013.79115315094, 9858.03214259938, -6557.68732343635, -11132.3974339295, -306.595974255789, 3840.10556842117, -4662.49889172269, 10185.1369053389, 5002.344967 [...]
+1577.47848846952, 12840.7576235561, 15472.8834700208, 6866.99474885122, 8177.47509795804, -1297.62644896140, -5543.58001674117, 6035.9205922407, -2140.43072511407, 16995.6320077282, -1564.09209347403, 5462.96304137179, 6069.30107492692, 11023.4599371208, 10839.6474671142, 5687.35842442288, -2253.07055888806, 11118.8139760644, -5646.95778717701, 8191.28528571518, 6754.37691339938, -3784.14156510222, 12181.3671972104, -13707.8567420242, -2812.8644130632, -5175.8226833883, -9686.95361744324 [...]
+6410.38250848237, 2814.81700593395, 5613.42618007243, 5133.97555848563, 5175.24675284922, 7809.56280138668, -2937.41390880489, 19976.2313008672, 2859.41758491389, 16086.3578865620, 1817.41566694389, -7894.51506555765, -5914.99421467547, -11268.2768727971, -3267.53134164828, 5830.41936226491, 7872.76602310975, -12272.0795958630, 1701.96432237406, -2450.50386575996, 13756.659000415, -9715.38373157913, -7843.82925169156, 1125.78231055296, 2015.1263860584, -3482.45534996511, -2478.0759016389 [...]
+-14439.16722124, -14568.2851545081, 751.180736441073, 4910.67905071252, -16232.8533527164, -1212.37175934182, 4773.4041460261, -4124.05351875083, 3218.48912170418, -2149.09547534232, -30619.5528287136, 1431.28107682718, 13741.3677841996, 14434.1323533341, 6007.59489547958, -1537.3063395198, 2214.43662555109, -2399.83818625602, -5144.64758838086, -485.934986718921, 5119.97586744514, 8550.66598358462, 1798.37816277555, -3663.97154155223, -3085.38770986561, -5554.94981816478, -272.305564005 [...]
+-12517.4061359102, -5622.1422313732, 2942.38520915893, -9584.0706969694, 1987.65234646071, -1940.4812788207, 8944.92869400284, 5916.74483706187, 24269.7602655332, -750.349244184129, 10106.4743538437, 7462.79625466278, -695.336965997054, -3696.51884416671, -3955.66288084005, 199.991327178799, 3571.44241834752, -3927.1021284244, 10092.9482521669, 10017.9194924722, -2832.53499553785, 5320.19188425285, 7142.33190304123, 29852.0799668132, 16078.3518915989, -9639.10522043427, -4723.34004598363 [...]
+2314.81686811619, 3699.2967696999, 5524.27833536417, 8415.93768640385, -468.376504211566, -9676.24771296498, -13255.8254604158, -5902.76708086728, -4672.69604789305, 2039.56876036991, -8609.20930832753, -3559.78542072259, -5399.09457615816, 2952.09043083961, -6810.59369592025, -1000.10710666283, -1808.31544598373, 11797.5406955820, -3142.71305152297, -12242.3597768344, -11084.3458317219, -1150.00957928942, 4289.8467429673, 12787.0934696547, -3589.5770338472, 8059.40784846137, -4689.14628 [...]
+5342.37813556055, -5239.84597308918, -1426.69890111797, 8977.97891610913, -2324.41301339856, -12352.0502612174, 5155.18665623137, -16130.7247428654, 71.6097370059833, -6385.13733508412, 19012.7694852788, 2733.25318336875, 2457.08763062923, 8695.11430104638, 21037.3331147899, -15970.0593028088, -197.913223906548, -4588.68316915446, -918.276412875335, 533.576562812333, 4170.54382127517, 6860.57976720229, 3879.08447530276, 467.588214368822, 17216.7751401712, 1608.97850278883, 2491.727044438 [...]
+17210.3160319544, -392.714111231531, -15896.8497588239, 5552.72247176668, 9803.36023242563, -2036.02961055938, -6126.04643278896, -637.964868473477, -13013.3253295255, -12860.7691560356, 17378.3762328048, -11592.5967174069, -2109.97803277121, -11754.1381777832, -4621.58579628607, 885.348308922414, -12289.4021991934, -10547.4154351498, 1631.02572500727, 5502.25238425211, -697.86371099763, -11100.9523623178, 5513.50951176476, 6152.29650058749, -9155.82709842559, 859.601319415287, -1683.463 [...]
+-2002.79829765231, -4973.09589424496, 3897.27291894649, -8422.90902207093, 14304.7714223913, 8194.33924980222, 14045.1014399632, -6199.90591668766, -1114.01556744412, -6382.43252352096, 6701.88732390066, 5675.85074204699, 17091.3329343426, -6726.83312213528, -691.886768754912, -7473.88889776466, 20372.5538935462, -3468.54205394224, 8065.08148821949, -19823.7323499687, -5294.25076203013, 11978.5521697736, 15454.1334337501, -12520.6684083956, -6400.07047918733, 12947.0253203928, 1868.55753 [...]
+3601.03821100648, 12794.9202248587, 11926.6450723191, 15277.2282601019, 22825.0273386627, 8899.75295373225, -3350.95484557796, 1799.34168112241, 14842.1349242748, -12023.0015654974, 14725.1777390072, 4487.99369569511, 4585.39512027333, 3448.60628473545, -11666.5332461899, 11010.6559360838, 1750.99832596857, -4212.5581138613, 11120.5830629349, -6663.17524796111, 5440.40073056438, 2146.46479618944, -13526.5828172515, 24054.4758641502, -3150.61537365322, 9016.60857139546, -16487.1689816659, [...]
+-1176.77751386871, -14366.3395840618, -11182.7220505210, -12968.3171603524, 2357.94258694894, -4116.03428117495, 9846.07849018451, -5585.61224130795, 20312.2984777372, -711.223577037183, -1149.89224370454, -6153.17966414897, -9782.68955476432, -768.253107622484, 6025.90059873705, -14293.3892239797, 9888.73208513834, -1600.63260898094, -11388.4113728777, -1027.68481155989, -1320.98477215631, 7737.62735992958, 4250.80752571318, 5173.60091855842, -5637.36200828113, -14729.2104763408, -906.5 [...]
+-21569.3777058397, 2904.0421566733, -10203.0668593095, -5595.19935492371, -3733.38988536537, 2991.70000432467, 586.079720728875, 20873.6314290022, -8766.99720911312, 3060.49553663056, 25109.7303213375, 2885.75539881872, -654.957121659081, 3608.93523210097, -18469.5574355108, 8169.04645325675, -4576.696411208, 294.180473715912, 7372.23521764766, 5633.10078456739, -2352.77158193086, 15555.2906791944, 14459.0253196875, -2812.62721885988, -11284.1508488649, -17288.1035508445, 2170.0586469537 [...]
+12150.2056032437, -20170.0201127544, -3836.5802284119, 5764.32228270673, 1159.00832660724, -9161.01497692688, 5768.36314171995, -8176.98846656422, 21256.4424805702, 3149.68560364672, -10384.5828786540, -7165.14100158256, 2838.80326762196, 1840.40187615815, 4260.35495269587, 30112.3577827832, -233.996498143325, -17231.5479300914, -5750.54187707029, -6293.24589976664, 4735.74439152798, 4697.23971370437, -6714.97293676948, -2012.58283144339, -16715.5933599285, -2747.97289003522, -9497.94998 [...]
+-7998.91656393165, 10627.6785118939, -4893.80510566949, 4787.27318016533, 3647.78986636174, -5681.59552486696, 2441.08685316637, -20175.4742906585, -14984.3951234631, 10722.0077307606, 8151.46503954399, 6111.55573882706, 7408.74473572868, 30003.4570330095, 3697.57026822023, 7493.2897293566, -29554.7793422586, -8023.21713582426, 4176.55457703955, 10018.2031824362, 8973.71917228894, -13493.6798980295, -36.8380749929904, 9646.35236438963, -2023.08578495517, 2285.79376147255, -6096.024655441 [...]
+5404.46388720824, 2707.51967772532, -22966.003996486, -6198.29349103641, -15459.7096414654, -5358.14983339999, 13412.8948917184, -24613.4259702199, -5929.22294995803, 496.973678131607, 3426.70135769734, -11543.7704822758, -2267.12594242137, 5752.15930228427, -4627.80712230004, -167.258479037799, -4818.73977384718, 7832.59853683854, -18898.2076296605, -7861.14562863453, -4146.15775643899, 14850.1806354046, 376.923992734786, 6356.54659315498, 5897.15219691907, 1600.07947256435, 10093.89685 [...]
+-15690.5660038026, -6649.58483504275, -15197.2326980913, 16964.1458181301, -10590.5404612068, 14643.2819659146, 4707.87815587543, -12115.8417819336, -701.154227664171, 3391.90243839141, 12706.4977765166, -13950.9262793202, 1697.92257712522, 6299.74197262252, 4085.59516405806, -7308.34086197494, -16310.8578729756, -1772.54077280523, -4035.28467084524, 18514.4789271540, 14771.0835329767, -8861.57608681513, 9154.21539989798, 621.724296565906, 3919.71836586259, 8135.60847286064, 1148.2917096 [...]
+11676.2148417972, 10055.2197480552, -3216.40109163444, -5987.37876218321, 2320.94282186547, -13464.6473591703, -1370.16790426543, -784.901169968204, -6049.35284277912, -5800.02337180319, 4520.65456672839, 21926.3526795051, -7363.01160337339, -4279.65589005324, -12811.9416643305, 3020.67428746841, -4779.64031411747, 236.359110796953, -11185.7584873042, -12249.2702257451, 4621.69921106903, 4797.0812738981, 5711.37343210275, -11506.5489739648, -17200.8401394180, -18294.0687959257, -4118.361 [...]
+-11412.6948964426, -5257.48212148326, 24444.969752262, -17228.5184757602, -12829.8285129693, 6770.06891981533, 20315.2458170337, -3427.35827030973, 27601.9550947547, 8979.78228812063, -4532.84085658398, -5467.15648703209, -12878.4432803288, 7909.85684398758, 19188.1927044217, -5033.26601802554, 4271.58270855743, 4256.71995352923, 17209.0091457261, -5539.88119235933, 2223.73049591775, 26494.7762734393, 10105.2922339269, 337.602476750554, 11406.6112972224, -5491.26125804798, -193.795853170 [...]
+-8410.28869845906, -11195.4782448008, 14246.0880940291, 10387.2618031415, -12482.4121019156, -142.256511135858, 9713.80838451927, -1615.29392561144, -20442.7672151746, -3835.96182550167, -6109.34674005837, -25093.6262930724, 13567.4452500835, 13368.2973159783, 18396.4968375827, -10671.2322772628, 1739.51772958225, 3255.36983724508, 1977.69277624833, -10627.0925894030, 16133.7418691405, 14370.9827051254, 10019.5830688370, 3301.43849920161, 379.197524600533, 12483.6350576735, -252.95493145 [...]
+15337.8305030463, 1128.24963319894, -9.21802701547633, -12202.7930246111, 3571.2329283793, 17307.205779471, -7692.29667889024, 1492.98233655145, -4073.2691524947, -1811.84401313448, 4831.64921521401, 9112.31045599076, 15777.1809622355, 3499.34871022236, -5220.19811344206, 18083.1829350335, 11205.0713149365, -1887.33662332241, -5189.35371060573, 1503.13382070917, 4798.34959435703, -7594.66420823755, -5524.33483179782, 2864.70665074937, 4559.87707841313, 18056.8513350970, -19111.5341406007 [...]
+-9823.59362247601, 19873.3798802614, 6697.04139184526, -2230.51581125461, 4827.34581920321, -18112.8223185393, 11531.7825101694, -8704.99946162398, -16907.8040531469, 1593.28905957613, 2193.79421946571, -11004.6649005970, -7523.5853359782, -10119.7286748651, 5757.71900281392, 16062.5287011248, -1474.95526354852, 17644.3297833174, 373.644346741755, -9095.02644516302, -10587.1361072990, 10495.9890580861, -9779.51583987147, 9752.51199140126, 3148.29912816579, -2501.70784993738, -380.3116902 [...]
+3053.94891009436, 9040.62694638441, 15128.454631098, 11520.6228096852, -15710.1617816716, -3689.12045799574, -7548.74936473681, 6053.72495377978, -6107.41343638507, -13710.1954509842, 21316.7079324448, 11361.7562875788, -5775.04326210251, -11760.2931414085, 6855.77024733237, -18080.3760455273, -7137.99578242987, -10989.8688693263, 581.36219138526, 14770.7340946421, -4375.55863399588, -4287.38820076331, 13866.0283038923, 10311.4830549647, -6585.52505250545, -6649.59607777223, 2300.6012685 [...]
+4114.97706201561, 10806.9093328249, -2712.82093147404, 19847.4983246028, 10423.0563495686, 1082.78334033636, -3126.60022951328, -10858.4408075503, -5186.77328360423, -11630.8449265726, -12496.3791830023, -2157.63135042285, 7352.1505430387, -13229.2218378588, -135.887275072924, 8419.16688270188, -9311.75156227083, -13749.0734060368, -7906.36522675556, -12405.6326053097, 3069.12080458824, -2290.76808928279, 6997.88357117575, -12201.8526859972, 9561.43001687173, -15614.6831361404, -3888.221 [...]
+13359.126333348, -18081.7621007752, 6649.86597689477, -3754.97112207052, 2480.20199578757, -5087.70293071658, -9548.1053129714, -5420.22011509233, 18864.0663333108, 9519.2182999577, -4878.74404779601, 3076.42412585945, 1598.39293229402, -13838.8274831252, 15788.5919162031, 7236.33383417229, 1140.78240004422, 2235.35302126878, 27093.4004368309, 674.509419803072, -10661.5872743685, -6998.92430380521, -2017.82331357617, 4704.49883343098, -2021.18071269711, 9551.35248386407, 14517.9612338091 [...]
+224.787304441307, 16609.6792945935, 7423.97469311089, -22886.6245826658, 738.178202045139, 4522.85759867849, 5686.6908535498, -4050.00070033004, -10062.8749955775, 14821.3717997710, 7338.5388699208, -4310.11345065279, -1200.17676688032, 15342.5358353924, 17021.0727126139, 20379.8670265944, 2774.16979627798, 8534.38138647901, -1450.48255135720, -10061.4068621453, 967.065096015097, -242.856697570357, -20875.7262029091, -6417.1475963016, 4599.03271601932, -11158.0361373228, 18713.3486779031 [...]
+1801.03483518920, -17111.6666436559, 11099.4471304399, -11400.9638580831, -9839.509946725, 9444.29552706255, -8086.27175896795, 9517.5456935014, 2961.27474439689, 1503.67001072584, -393.055744781774, 4454.51110534733, 8038.20108300055, -4416.06157071243, 1894.87217766618, -7701.26549332733, 13760.3159421249, 12675.9622008655, 239.737883539204, 12017.3890346407, 21630.5052319197, 23584.4238842195, -5809.56757926201, 10140.6024327989, -15134.0424163534, -8021.63699446158, 13274.2374492028, [...]
+-2563.82701567145, -11904.9701739649, -18205.1370206275, 2868.14680064700, 1706.60458333682, -11163.5550001527, -1823.35332817343, 4263.36805431441, -3107.61040368701, 2976.29980462535, -1198.14043656424, -10766.3329502268, 10664.3720789216, 444.986578986138, 5196.00537053664, -12756.3987488654, -2241.35476936118, 777.495762058153, 4293.50549115316, -1695.31259864246, 27194.3585078410, 939.204399029614, -9246.73877748307, 14753.6656871408, -4600.54294956058, 2314.76210111561, -4054.19377 [...]
+14814.2699257614, 3197.44295595151, -3507.865313872, 11676.0679987401, 18659.5400436474, -5350.53642551871, 3362.22068715518, -19863.8893911374, 14235.5016230002, 706.45178610177, -2278.3099192105, -12263.4030431495, 26485.6574241304, 20033.7160805522, 6182.58718112405, 19025.1690370920, 17953.6395293662, 13484.9285312756, -3281.62605636295, 8744.78625825952, 5736.22511595151, -9196.68870115184, 933.968663986672, 189.130288204915, -2976.68109508547, 4980.04111067149, -12682.3722283453, 8 [...]
+-5906.71564761406, -5914.29328721222, 19218.4306696812, 667.23310074312, 1231.39111893705, -3865.26510239395, 9177.74144276752, -493.873830012353, -7904.0578116499, -11836.4456796103, -2068.94104589950, -8310.43954697885, 179.997220755483, 12419.0465335885, -12563.7830484977, 4493.04091167238, 4631.65391531038, 8418.15183621311, 15002.6313044465, -5091.54824514314, 982.960932465716, -188.004433483727, 32031.1201739889, -2608.78536298505, -996.76003577516, 1064.40313990259, -12811.0851129 [...]
+15631.5484547569, -3505.41769133788, -1733.44171642315, -9019.88883530109, 6285.72498500157, 9460.46418098456, -7950.59492846191, 11335.3266866172, -1028.55640460029, -2836.7071949928, -15296.5136547732, -9546.1070778848, 2239.02320403072, -5143.24562520675, -6421.3239324022, -2441.56683245525, 11875.6223299939, -21348.8392025623, 4686.71633742369, -5481.14157006832, -1407.83649957311, -17738.3973415958, 3928.25723020087, 12226.2717343991, 11382.7573138667, 13696.2639118126, -5333.643989 [...]
+13934.2019092267, -10090.4605364818, -3041.00699999497, -2954.27780696098, -942.127883406, 1239.63761223255, 2062.12669771592, 25527.0151941243, -15217.3609437602, -11976.1172325003, -10211.5981263289, 10975.1969083889, 5566.72415135922, 11891.2580013297, -18098.0741047584, 8024.370615831, 6836.4116435209, -1401.21747962808, -633.688161687552, -13805.6024966331, 7221.47700542449, 9417.34510034076, -5323.61564623148, -7238.40840195659, -1560.43577584977, -11893.4690856366, 11717.919744480 [...]
+-1977.42583076004, -3791.43094540745, 2936.72830130430, -8201.90697424574, 7426.62518283394, -10739.2450397781, 6133.6958091544, 10159.1078067703, -4779.58603711178, -11054.8410773174, -8912.01109273081, 11353.2596705089, -5603.39613466261, -24619.8179186002, -14374.397870306, -8255.89488779161, 6363.83998886148, -11448.0569305607, 28507.9870921, 5708.56711028311, 369.382356241588, -10897.4554224013, 19510.5022833731, -5539.2457250772, 8471.59575679502, 530.238499919269, -15966.932266706 [...]
+1343.22081242078, 1294.34922289515, 249.553270395662, -13330.9320435326, 2416.40656056375, 394.903882786273, 1980.23906728786, -559.106910528943, -6070.05345714247, 7940.1440285444, 1452.32750171478, 653.833917980138, 5045.93072850769, 3680.44607473525, -17677.7382001934, 4292.58730478539, 1289.61926731329, 22032.1397201211, 13179.823733746, 11411.0773787418, 14473.4999335576, 8144.84049984568, -6530.01907765507, -8191.04293892526, -8464.72593254886, -2462.43544596282, -1214.09427518021, [...]
+-9353.61385751314, 4214.49101189176, -10770.9572705751, 1440.97841362541, 11462.5874278579, 13475.5785414914, -4944.33298432988, -14250.2584041979, -7141.3184057885, -9308.012262702, 11866.7658268341, 3122.02637863411, -15936.3652964325, 999.837685400842, 5099.94313190579, -4005.89300714433, -809.74006140463, -3744.03085923902, 15234.4798278027, 20293.1832946477, -1992.50628536721, -20143.6059385517, -3199.1663273069, 2295.54570367871, -17406.1983918531, 5754.21729995873, -8195.424519093 [...]
+6824.19847865718, 3923.11012828554, 592.793300074788, 13569.0399551444, 125.098140271795, -10248.4357422394, -2553.96326287336, -14141.3878441999, -162.778177563748, -3338.4477772885, -7160.57324230292, -2494.90672154848, -624.014843133014, -8376.83891746931, 16722.7250660195, 11092.4372474745, 17946.4055430368, 15448.6933246275, 1375.41481303414, 7602.10748239787, -7961.71076799208, -10758.0128659164, -25259.4932961447, 34919.8888027721, -10229.0241554326, -11114.1794471332, -9783.11736 [...]
+-428.084683271699, 3438.32776744993, 1974.99727243295, -9837.7601370675, 11973.1066951113, -6401.63889827191, 4807.45856275188, -1404.91951695771, 1881.17700386366, -2263.17701894129, -14643.0968809108, 3958.73115197066, 9580.9202540905, 7342.50327442737, 11141.3329106102, 18471.3898078142, -3289.53881503142, -4930.64984289859, -4384.63129603728, -3590.58886150594, -1853.0671731145, -17158.4008757425, -3863.32726861767, 8005.07731503812, 5820.83752096014, 329.584443461821, 6365.921483317 [...]
+5301.72632075494, -14367.1286081883, 3389.4726973617, -4690.26361962189, -3331.42134271065, -9270.7422540572, 6645.91194851746, -9357.60128179022, -479.76533898792, 3587.75651358157, 896.872336966515, -1865.70920684902, 5079.33508668706, 10483.8906628240, -1699.21814146335, 17098.0177167923, 6407.79816051591, -927.126617664136, 3870.03150655411, -11082.1973211031, 10160.3303720260, -3150.34940235423, 18921.2616804062, 5181.00081718648, -1696.23758465687, -3915.17625048936, -2091.51348964 [...]
+-1976.04485407448, -4965.91083566774, 3230.17763414714, -3566.35420727897, 1704.95280751958, 10667.0706195479, 13564.4974713461, -1406.94271909745, 15344.5566280029, -17784.2329817447, 5239.98412957196, 7715.18654294157, 10911.2378286404, -13173.1672315769, -5832.71473368946, -4329.18236713984, -12563.1682964866, 2614.20302627319, 14158.4844480746, 7157.78528609641, 4321.6892506667, 11882.0470387828, -9198.2706552618, -2038.44370483152, -6780.63247387745, 932.53896880371, 1734.7879039961 [...]
+-7940.68132828241, -9228.49786116503, 2511.55291747392, -10034.6903856118, -1139.22441045326, 11093.9246938332, 3314.4764860614, 2473.40453226906, 3121.59790961578, 10103.0039993224, -11289.0109612757, 8874.66290777598, 17545.0169380143, 6660.6517522942, 1076.77892929961, 8800.18914089507, 2652.74687234777, 6283.45708739656, 258.096977938619, -7524.01494825983, -4508.21289754052, -5343.26327813994, 9207.08936441693, 9072.7656483988, 1297.37141989229, -175.938610321587, -16844.7919671002, [...]
+-1450.52793543602, 16803.6917669616, 10883.5760699583, 11113.5193030064, 21131.1323881285, -4683.94665539269, 419.975456389991, -11070.9733845319, -8012.78799137513, 3368.75479695114, -6787.61893063168, -5682.26038541548, -14468.9358561943, 22026.3909140614, 13849.8773542983, 8926.69347911011, 12309.7550220788, -6156.30796500844, -10199.2125457587, -3456.12440123892, -1607.44165907843, 5891.19292276488, 6726.04635980741, 10837.8933460825, 603.913282498087, 1073.05675366797, -13636.760676 [...]
+-6069.06892206358, -6101.65785524405, 16623.8937924853, -4706.34416492213, 17116.1987397646, -1436.49718777336, 16272.6555046140, 11808.3738621246, -2885.62037547837, 2991.51253928065, 10081.8572729487, 8270.89393451464, 8503.71970288616, 12241.0784244219, -17993.3652427292, -13763.5438356283, 1086.47624818005, -13471.7014423983, -17232.6769429938, 11295.8101781247, -18235.8222479331, -2383.11010573687, 11616.2607504123, 16170.4453248058, -9584.70177350232, -18504.3459154914, 12444.18064 [...]
+673.873958664406, 9522.94328931873, 9376.15592578493, -11204.9927579329, -3506.89576165719, -14271.5735585683, -8855.93283673048, 6168.20768880774, 6833.67787913477, 3417.02121846226, 1061.32490128915, -8.5655854985959, 7514.65111070479, -4160.34671917804, 6658.68705273037, 4153.83888219732, -18556.5196812891, -4473.15093264299, 6563.61719465231, 14818.5137117224, 372.481713794157, 7147.68469364162, -10728.2204829581, -1292.57602186826, -5093.92019779068, 3373.25980521045, -15490.3541728 [...]
+-33.8923944320929, 2107.04619084822, 4319.86080795164, 6248.67890312998, -16655.5326037615, -856.454635879002, 1968.54497127926, -6561.71841115802, -99.5274261025258, -13592.3148180317, -14050.2323915512, -13497.3270617475, 9360.80981308311, -581.675335527867, 5809.42645029632, 1287.01843553828, 7993.03130927003, -1823.36722750797, -12438.4192791175, -13439.7192049948, -7303.13483421288, -7219.87202370721, -1737.22602479016, -6517.83791405765, -1512.56101698593, 8244.26947066112, -13996. [...]
+-7084.70313293864, -17327.0435655054, 25013.2466588872, 17667.2032979793, -1942.94957376075, 4633.58470538269, -16528.7036394936, 5052.30689812414, -30447.880981113, -9114.49682482406, 6963.52883536267, -4192.24334638363, 487.915681969839, 967.003037612873, -11704.5700804028, -7093.14855782658, -9732.97980287122, 11925.0368488406, 429.307992543843, 65.6736933596217, 2535.47816967818, 1490.47537134326, 8507.12780058244, -4409.39194007421, 11991.578943221, 8613.72749259332, 16993.978095461 [...]
+16801.2593874817, 6232.70618844694, -595.411090630965, 3527.62537071345, 15645.3916665440, -13330.7485729897, 8229.53018493071, -5859.42030018765, -19719.9170038732, 14142.5498384338, -4252.51469796012, -3821.36486703669, -8532.92455431833, 5545.82669854753, -7070.12520326053, 5110.28946215316, -8814.40319502837, -7308.93220551013, -1778.51646252760, -13237.6649222136, -2274.74573252986, 1022.38521466866, -862.867565547612, -19920.8140258998, 896.065354287988, 23047.9457899611, 5084.0655 [...]
+20013.2744951133, 4938.32178323674, 4206.25735289055, -4239.82707447085, -6413.65421603929, -5797.68329117878, -1154.56173002615, 9398.38236076596, -14611.6903777582, -2778.07871602699, 4180.48768568794, 16491.9946199862, -3345.41789426499, 10696.2276760261, -1164.66964914126, 9989.13027020999, -11138.3418019956, 2803.14702120386, 15732.9569529039, 16107.4756496691, -1069.75053823003, -7977.42086597412, -17033.3118926475, 3236.40557777686, 13286.906245764, 4211.71802895431, -1457.8820644 [...]
+12509.7776813152, -22416.7120274858, -22385.8273144098, 6309.37552439391, -3220.83142473720, 6355.80539416147, 3045.68651907567, -4352.28014012479, -2199.78539570833, 10129.6461563541, -8338.20219023127, -4290.62653625446, -9652.76490361395, 1117.35379380991, 14006.5048671857, 5547.16846190005, 4012.80111535893, 771.651132275911, 1178.83019514666, 6822.42552323837, -1498.08852004330, -8336.94863524128, 10387.8175107810, 1365.57637811459, 25222.1442868131, 1480.02890175180, 8158.839430068 [...]
+2028.58659490037, -27368.4966508138, 20084.4931501735, 11031.9993308679, -14538.6838181534, 8415.43724140884, -4364.53136528773, -5208.06950711223, 8731.72924362946, -13950.2979334361, -14152.6257115759, 5488.45684283755, 7373.93863109334, 14127.8779717091, -6099.1632917593, 4763.52792349354, -3397.43631947183, -9617.16712333725, 7142.56925602323, -300.323858641775, -9093.69886581792, -980.503102451787, 7723.89411627338, -10618.8742388556, 4806.60392330936, -9612.55623015, -2657.57588316 [...]
+-9374.98354802467, 21147.9597360856, 5567.7042292461, 1746.85121458232, 8670.322792727, -10431.2377414861, 10341.5177284205, 3554.18327552779, -917.58957652929, 16355.0560132166, -5006.57719416308, -8096.5110452087, -3101.06556764896, 5797.80241380294, -21652.0174709721, 3484.44115344444, 2435.94674500138, 5146.99722517067, 13577.0245691910, -21306.0413196212, 14659.5855684337, 4724.13460360666, 1541.28023368686, -8005.09914250841, 9500.7697712878, -9338.67100006246, -6056.1481311897, 12 [...]
+10814.4356537446, 2142.13138323678, -4706.57437712977, -6104.11016206705, -1936.10347876308, -5567.10494932805, 6956.55857312025, 18984.6370172678, 3718.89195298623, 1947.42680719251, -7452.5841529256, -3942.35984328125, 5287.54972801507, 12139.5553572885, -6268.55969834641, -6836.28994671568, 17690.1519173732, 6726.93935009975, 14239.2284577864, 6065.12266163836, 10001.3776870266, 2674.90899385254, -16440.6230111886, 4634.55891268845, -16602.3058617198, 7913.88013115024, -17474.05355799 [...]
+16720.8870188681, 397.332279614293, 4015.30070280175, 8396.89410269266, 8055.1744818449, 11917.6923503669, 1186.62475611729, 10743.6952992673, -4190.82762640075, -1361.07349436516, -5823.90974091802, 6373.36272539931, 348.932689314368, -3647.39008649066, 2556.66401548065, -2322.68786251588, 4621.77316435417, -11822.3070617571, -15237.727756406, -3095.14380152734, 3952.83861222021, -17397.9618015267, -4966.27795348420, 3388.97608910005, 14310.2113636368, -5236.52798804545, 1086.7357074679 [...]
+-382.515632890953, -1076.68575815746, 12535.7082479679, -6214.49099783389, -15606.9008253863, -1572.55607316811, -35013.4092710809, 3861.25782053154, 7370.88872468715, -27114.9952483243, 10605.0969598149, 3167.98205106873, 4972.17383210102, -13373.501438629, -3032.80793847395, -6027.41946759576, -3252.94316567719, 9374.72288407563, 8669.08507707339, -1161.77214994760, -16282.0376566846, 2067.81700840355, 2705.58501546823, 11.2435831419114, 1656.00792568322, -2629.18230021421, 14148.02658 [...]
+9904.76052042437, 11618.7413744018, 7852.29529615847, 12861.6761840527, 13209.4409006025, 4571.32813306066, 6824.5528696141, 14576.6208303587, 4863.88519388544, 23202.637811913, 360.647820740236, -6784.83496891855, 4101.24565329665, 608.135440039124, -409.48577522398, -6941.85617786005, -993.760247540643, 8624.01903000201, -10113.808306582, -5878.2857066735, -8920.03891049498, -17317.1329397173, 3604.23331225088, -10177.6128695841, 6817.7493481912, 5168.72480389283, -15146.4793812408, 11 [...]
+5674.91710496721, -8736.8299808246, -1651.82368687681, 5577.30529050072, -12957.9549651917, -2308.95957821611, -9859.26126876866, -19.8462895833775, -1918.86815549245, 16986.3928774834, -3780.17616334478, -5385.41080276621, 16356.2405508188, 6354.87236070346, -397.223921219974, 179.889598408928, 10447.1080586433, -4919.65494315097, 5811.5614468526, 7349.3641220879, 11175.3462899212, -6303.35418302358, -1942.05702865716, -4016.39617553757, 6634.65719843824, -7909.88416576203, 211.62681900 [...]
+9693.84275095774, -2758.57134558581, 11120.2215061705, 2564.62838485431, -20773.0141235677, 14004.1276616353, 7704.50307315169, 7854.95885031658, -6191.22789905521, -6623.70184107938, 8266.02216876348, 514.472498053039, -3998.51029667675, -479.256795677447, -532.271288595486, 2856.52361725569, -942.880586989646, -5723.48731970661, -5035.43551051547, -4597.64452957675, 9128.23301783529, -9392.30287461155, 16070.5439694890, 668.572989298469, -2219.18125786800, 22350.0323947339, -6038.05890 [...]
+-6630.02273280381, 2480.30290821587, 4932.42140393972, 11355.5342927304, 6049.90574800364, 11453.4251270808, -8001.03760837029, -455.002617956728, 4991.33490147807, 20133.1683401251, -6544.84375482984, -1817.21463779688, -320.028609846990, -5851.20070223219, -906.436706025724, -9656.9553587723, -15763.5228953564, 6721.94441467982, 21562.407572786, -16500.5234387111, -1702.41785745382, 7930.79063335233, -1089.74239469246, -22198.2312281254, 5934.53241559273, -4219.88473678237, -1866.79266 [...]
+-3995.57869902276, 2966.66960208300, 16808.6235374776, -1949.14404494431, -12790.1878346170, 18181.2879266393, -3327.72507836342, -6100.54131673626, -8725.67385630974, 21224.3630175866, 51.1141813330296, 11649.0937968376, 10588.7419303363, -1599.18331607519, 6032.27960552148, 10028.7573894412, -3977.05774778934, -4961.73945615595, -20519.1515567172, -2167.27748461874, 6923.67347337771, -4985.3436501732, 8836.1846091151, -7156.93248732305, -2251.19498934144, -1542.87934462644, -6301.59529 [...]
+13574.3436612981, -14864.1902182708, 6108.93342798403, -8822.71716365532, 11126.5703297574, -2890.26498625308, 6709.56334623844, 2745.22247915662, -17158.4736403105, 4676.21229856817, -12387.2518585489, -11441.5205990523, 2905.01209175169, -8609.3391435, 5526.76357874961, 5729.23459643968, 11115.6605753645, 7507.76129677618, 21194.0920154526, 9285.3916435685, 1453.96461894113, -15219.9638128082, 15305.7045370687, 6953.54068842928, -3898.95758459877, 3123.84152971611, 6514.4491275599, -15 [...]
+8190.75782748717, 9234.42211541432, 7637.1821610661, -389.82405168188, -9233.55850468898, -1081.67822122879, 26257.6656858973, 17375.8105501935, 9704.76093058399, 6222.1948116056, 6783.74138638350, 1023.01593677331, -3412.35647661448, 6028.97863725744, -15290.8274990365, 7537.95555400467, 8684.35221235647, 16859.3492577465, 6581.56933549611, -3024.27941602217, -10136.9832954868, -10343.5988275423, -2507.28173804483, -1135.18177948912, 520.979663686722, 4970.89096579038, -199.554983036646 [...]
+2590.47021739965, 6910.01637263038, -1208.17124010976, -7898.71984234346, 17206.8113167355, 19689.2376554017, 11643.7032036339, -7484.82653512722, -9993.72838843851, -23559.1379935054, -10032.8192200196, 29387.2433573045, -446.484812376337, -3813.88024203505, 7745.5894550464, -8815.72617729663, -15228.5946480913, 7120.4559386191, 11647.4414795809, 14056.7606061974, -8939.99351573566, -3272.61433278266, -1328.40117479396, -11450.3028094767, 12943.4574226894, -11171.6353120537, 6006.969615 [...]
+11915.8166649039, -4091.04708778262, -678.346004508076, -956.91091676204, 2087.62782423598, 4753.29229554389, -3813.60989305418, -7806.60059938985, 1100.02297309724, 28175.3342094752, 6524.5206974981, -14938.9005502104, -6841.738713701, -22365.4853052405, -7759.95078725775, -1480.38291143679, 13862.0806975231, -7504.56831059383, 2612.85667549881, 19863.1548922346, -7887.12657323757, 4832.94702658943, 8460.81539208642, -13784.7210363732, -25.7499662603507, 3767.52582332049, 17529.88593618 [...]
+15020.1645626212, 16577.6970271512, 12323.3648469961, -27160.3409348193, -4291.03902129853, -9036.9384215154, -19914.4317545577, -4036.46229341594, 5420.03537202052, -13739.4182621269, -7845.60811911072, -11669.9456115591, -5940.91585011255, -8589.96149525828, -7221.54860758088, -1314.93684759782, 9787.8806425459, -9616.71074833827, -3413.28054537240, 9637.76234600863, 305.381541734337, 7630.08667866921, 20486.7306997171, 12380.8021936916, -5971.47734418875, -5021.00429578215, 3131.03113 [...]
+-9411.2790059514, 27.5301707239182, 3964.84805574425, 11917.3250052103, 24795.9218067855, 17355.9674638517, -5383.70759867819, 9496.71282351612, -16440.3287413171, 22178.633011306, 15762.0062568099, 3646.8107821193, -8775.02744816616, 1114.01499451336, -4918.13930699729, -16635.1519029762, 1868.83801624782, 4995.81127711598, 616.105563884432, 15710.1653834313, -13394.9705712540, 9435.36918806477, -5198.16772240384, 535.21113146801, 7852.83080653958, -2702.102505664, 4082.12560539953, 205 [...]
+10039.9306623305, 2745.33745190227, 2398.20358718317, 1904.85433396746, -7142.58431270335, -1455.66514861649, -5002.04668966246, -1492.26080693839, -11697.8910071503, 5580.50172045166, 17988.6012993353, -1726.59253445862, -4256.10932260538, 11908.6156716545, -10506.6108897567, 10676.6913566704, 6878.83264095328, 3942.655704846, -6108.67744777165, -23207.8633312131, -8953.96825705569, 6849.1980510117, 730.974247580362, -24253.770662325, 7817.34608169508, -4652.28930356, 20914.7091190014,  [...]
+20640.8067460375, -190.255513358256, 4091.07352389432, -3171.95241235889, 7147.80993205972, 19021.3726375385, 12845.9534370323, -22006.8057359219, -9087.59313944884, 5827.14806246321, 1926.90010054223, -5761.89055116036, 28.9909927985520, 2382.19140061115, -6778.46368043688, 2039.85457192575, 6656.47760334455, 10684.6996156194, 3456.15055600757, 8564.69142426086, 10663.8340410455, 1101.99203577617, 10454.1045035825, 4598.35016031493, -6873.64968024715, -5858.61182342029, 2828.73393867573 [...]
+18398.1592147649, -8715.64154081529, -2341.34119475431, -28579.9729646086, 5320.69121572836, 12805.8626745437, 1072.63327127066, -9324.40072687533, -8195.81515074628, 17512.0554846232, -5064.00615628778, 788.47728236856, -8199.31957147544, 650.974048566585, -7976.67035638158, 19575.4071698982, -7070.10314938034, -2681.2605221601, -6775.08345033642, 9714.60825667608, 4370.32335826697, -3841.98937675214, -5895.71932070729, 6630.24263291198, -2199.45289306086, 6002.01514006002, -5461.325920 [...]
+-18224.0365557275, 16078.6850762584, 3362.29438296079, -4881.35351088834, 5023.48247480688, -2009.26934584708, 15546.2485978251, -10977.2431456105, -614.574651580102, -2881.51097291105, -6552.61374063613, -4837.87592326868, -17105.2111318284, -5132.00057343344, -7686.69672614396, 9248.26309090911, 1266.32385413326, -1821.16781604967, -7254.62446092544, -10319.2242255211, 6567.42031084604, -12234.0747707571, 5897.37066307735, -17196.2363268731, -6288.68374227896, 6527.64591569813, 8372.99 [...]
+3229.25801170853, -5479.52212402654, 9765.61959673269, -3692.74648945813, 11873.5220586889, -4864.81179052259, -14317.5472597249, 3265.27895859084, 14442.4388453927, -14376.6082890662, -16826.0213537561, 1952.86356301487, 4018.50227792030, 6306.46474421855, -3754.39983804642, -101.669939766600, -17259.3988376939, -236.683535579765, -1222.33787610325, 10019.8760686433, 1404.31362138872, 5702.50835864189, -704.807487286518, -19696.2474254362, -3312.94846157527, 13258.2600279393, -6485.9060 [...]
+17788.5402183049, -3878.73341639425, -6618.74552467675, 2245.96317195641, 4866.71450589426, -87.957263521073, 4029.17576561578, 1043.57574179236, -11532.7060800734, 3019.83436640884, -6919.99236086564, 1275.69069147958, 6668.85080835584, 9267.38036871948, 2851.82884632335, 6055.18738285024, -9764.04456592164, -9117.96028460012, -5683.0592388548, 3726.03164574908, 8264.63663697199, 17308.3023481718, 30.0796176784649, 4343.17135355110, 944.938251152123, 6843.78825982327, -398.202985523258, [...]
+15581.5234184124, -4290.59104962072, 1471.32862632368, -14994.2630867867, 7257.86270246577, -2271.00486846237, -2161.79076476131, 4684.14802618018, -3775.86329600878, -4998.46885523253, 16490.0108173718, -8396.30561531894, -16165.9331031896, 9369.19604607144, -8468.68011479266, 14167.6549914153, 4361.64409869251, 5617.15821597875, 18516.7385819851, -15832.2190446074, -14527.9594563720, 13275.2016671335, 9538.10222454956, -912.158906804406, -614.982832624445, -10995.3861271232, 14965.1136 [...]
+-11017.8867112834, 7112.46821097289, -6060.75188570061, -1463.85316408378, 4684.16703209064, 4048.8233837903, -2010.18516371311, -15114.0607747141, -3551.73443730876, -2015.77031965772, 363.231175253889, 6217.39312345367, -1137.01025004844, -2211.20551883881, 3865.97886393355, 7013.46453740807, 930.548352030087, -10650.1942292208, 6014.61251821583, 7945.77387163972, -5114.34428023031, -4861.99368871176, 3017.74426821807, -5761.84433309215, -17579.5193578885, 18070.5919815190, 5164.180229 [...]
+-2466.49303273609, -6333.88442199456, 2724.46950547535, 10499.5976477130, 1027.08338941844, -9208.6883127049, 2292.01322463838, -477.376669758676, 4866.5115619466, -10830.8114756240, 29923.2667130000, 672.031855140901, -11364.3384159318, -11048.8984090136, -5523.73238733032, 2603.68833136223, 1720.99190302294, 12440.9206737898, 6600.37646973825, 9737.40232782737, -4605.53588771197, 24540.1765143438, -2582.48779254877, -7780.54146372073, -2715.76791538552, 1259.869379068, -17780.381698763 [...]
+2495.53924808789, 476.970722412538, 764.718087964946, 5702.30450543542, 10292.5842762911, 19440.049112113, -2626.74519140294, 10529.9726691538, 7757.17616476857, -16843.1685884365, -3571.16977863513, -4755.11553876731, 3306.22956738233, -8434.6002023486, 2487.08203880374, 13175.3178259573, -6287.95220628797, 8665.16701904095, 7436.75345387357, -6401.95965417627, -199.349384587211, -429.16852380465, -4511.70702104256, -15321.4030909496, -4355.38886752889, -4887.51833022353, -3663.32823107 [...]
+5899.8782116683, -2966.3731486487, 17925.1726386312, -10127.0220283148, 3399.22730157595, 6414.7763462998, 2305.92325416248, 8543.21219858144, -23092.7671599885, -1989.56505079725, -5492.42840723103, 2761.72478950881, -13323.6379195611, 6302.00107668404, 9345.61704162247, -1953.73886693085, -726.568675863405, -1533.92892092031, -16348.1006637153, -14824.0073450942, -7069.7088709869, -8855.6267280086, -12472.9072363083, 7849.67592595633, -8686.0920047568, 4196.81778034985, 20725.808820762 [...]
+20950.1498201626, -9678.47282051269, -19897.7243053029, 17908.1064530415, 1185.18362678158, -12307.9593971173, -5473.35323386643, -25982.6685150267, 10246.1912830897, 3962.03125408588, -5652.22417595269, 2668.51706241296, -13033.7212450755, -9896.5918454093, 13428.204472206, -56.4881524287146, -6626.47689955184, 4481.56261855062, 4119.03573848198, -4313.73814023363, 14967.1811485727, 2952.20783750879, -6791.69356087781, -22431.4377948622, -13112.7186205939, -10622.9306404963, 16678.17351 [...]
+-8019.82375674467, -2671.29458983932, -6182.60271842311, -3409.71660791461, 13565.6478444196, -4071.04448138834, 13499.5989749915, -12833.6654589392, 991.685021083673, 5819.14878756116, -10243.2890629254, 15737.7489909148, -10596.7353378294, 1620.93372736559, 1663.63495775105, 6027.8218302838, 4889.167816138, -8240.62013462915, 9231.3110343221, 4870.69794111714, 10669.5506920997, 1307.44131096791, 10637.8662097508, 1977.13170516234, 1268.87568196343, -11767.811473775, -8109.56235647685,  [...]
+17191.6208208452, -8468.78333004071, -16811.6110776016, 5817.85446554108, -1412.46469523287, -1361.54696540523, -2109.26459721558, 6643.21253500785, 1871.34480023781, -3076.51529168659, -3389.12003421978, 10597.6351796068, -11001.6381410566, 8599.0115202393, 7458.00166299493, 3283.61776039553, -1133.26582645832, -9094.32367130771, 7097.26169624078, 583.939292121218, -5033.76976622675, -3845.40282766141, -86.3738408685999, 1673.77442846504, 2574.92408707388, -3255.38261901089, -13457.4104 [...]
+-3201.06143279315, 9540.82835092373, -19335.3723343607, -10703.2859348061, 5265.93314853017, -5226.992147657, -16182.0576999298, -5632.09364498638, 12035.8878577767, 840.057210837588, 10045.7469101624, 3824.00946845211, 1008.88945050137, -15703.719063561, -2400.98157480320, -16577.7868162691, -322.942262206253, -2543.93910108914, 12233.7621251128, 4651.80395613609, 5639.47391396359, -5720.23594197756, 35914.081872323, 14386.3021826570, -13636.8713621024, 2785.8812736821, -13447.495748242 [...]
+18692.0983944421, -13918.5268620518, 4570.05704752221, -5105.60292260912, -15150.1805762266, -6937.05835019956, -7388.73584382677, 15226.4914342152, 173.443547130110, -14311.6418798359, 8318.70553241375, -1014.71684157809, 1015.57931692938, -10180.9493136784, -4227.62167444654, -2744.51926895576, 13701.8222759642, 9286.2208565311, 1710.66505633965, -2186.60463608558, -9585.33459290578, -10525.5615836839, 11948.7568208063, -3317.71502323532, -4612.52646853969, -3218.19463946636, -4094.078 [...]
+20772.437096322, 5356.99273633059, -848.438086760065, -16523.0765613735, 21623.6129163882, -3908.92397779395, 6304.11998987496, -15125.5975522667, -19734.6688943540, 997.668106044125, -1599.99925605723, 412.247601052714, 12426.0917518867, -19608.2519316851, 5460.01742221223, -11324.9430755008, 14874.6866029557, -1501.85630239655, 6592.82249987949, 4235.63874080038, -11072.4432214631, 3793.79848660117, -3549.30913509291, 3854.50793515679, -17131.6982106944, 9003.73777155951, -6756.2922493 [...]
+662.569297788656, -1131.40995685238, -3373.37275902078, 1157.06436527024, 3530.13701871509, -1546.51850382821, 15670.0549196066, -733.720567183145, -5424.3081080206, 8213.3465951442, -9651.29902338857, 13099.0392976811, 3119.55945135921, 2303.92130848453, -26486.6078929574, -307.603770273461, 1999.75287184642, 1622.98912687702, 8799.70856963106, 11593.3901103597, 595.4610743445, -4407.59931109528, -6808.73548473042, 14392.6679563940, 2495.93424257224, 5045.24220998393, 7647.74200566589,  [...]
+-12752.580137688, 2042.95390657464, -6140.84394528938, 4260.69019360152, 7558.8114677584, -16093.8931136819, -9164.59580238592, 7282.68434990073, -2960.91369933987, 4498.97736907168, -9495.438743128, -5058.91513355849, 1612.02012181624, 7888.37502775259, 9507.63483001527, -2460.56842400629, 3285.40532266388, 7548.44339794218, -13687.9406996104, -7730.22893106283, 11010.2872715798, 1823.56110929884, 3534.35189724421, 16611.7607352036, 858.585526079919, -3160.97558264924, -7593.41854444927 [...]
+-11130.6694950555, -17327.6784835122, -11412.7717131849, 15073.1870610467, -1632.89742910107, 3329.1307938549, -4979.85378616214, 13814.2970396902, -9781.55642308043, -7438.3938468942, 8114.26893263183, -10443.6472632574, -8632.82920997706, 18028.0283345085, 1246.46201331506, -20082.1631381830, -10726.4892035275, -4222.9307192141, 5341.88542425148, 9939.57246136826, 21129.4495694548, 188.501157140163, 15534.7804130158, -2246.40157818928, 1615.07348731028, -1297.94610730460, -157.96629463 [...]
+-3290.68706563999, 15506.9581083729, 8180.1215619655, -4447.99247768738, 13151.9124279945, 9635.00211293812, 611.515512130352, 22929.6060767484, 2097.73434938844, -2079.04247934641, 2862.24277872805, -122.901941979090, 16544.1918146005, 8486.28298068178, -4896.83530471592, 12213.9318509743, -5670.76945377144, -6073.05575967959, -25139.6388432686, -8705.77789341776, 15239.5266366255, -4346.06635882632, 16811.8674043828, -10006.2553120858, 11134.8434800454, -349.569797297836, -9495.0122384 [...]
+3674.55915141929, -926.105590643674, -7193.1030820102, -5513.61814616175, 655.718738442628, 13531.0256419588, -11916.0628117919, 6612.70806604648, -11411.4411632679, 6647.77698209046, 12017.9006921011, 3996.04423307341, 22086.9151600041, 11296.8029524379, -20348.6754680467, -6428.58909744766, 12795.0315492209, -7241.29269948753, 4077.57096125953, -4613.41696219695, 14166.1827044804, -1676.73660048214, 992.06792848801, -14026.8648903958, 17078.3994091411, 7577.48466948057, 4077.8392371157 [...]
+-2507.89112646943, -2569.03137412984, -1185.7865623513, 15038.0616400529, -1462.52345379445, 19045.6382821475, 8609.77362759259, -16592.5901849338, -2866.75467889643, 206.001050469838, -7893.90753955896, -17452.0904904099, 2646.81664324473, 7645.29982058928, -8217.68176662252, 2124.01828705888, 7262.1561833058, -28652.2797942830, 8675.2273367492, 16365.9675491254, 6994.8210095169, -11470.2427045456, -8560.9375372406, 10007.9003658826, 481.250393404908, -4926.68093482749, 9420.50620437542 [...]
+18766.2459037267, -1414.38490890046, 2257.57360379096, 22073.4354258441, 8982.25801858106, 6099.69033349133, -12678.3192123518, -7150.78211679009, -3378.91473689796, 7618.12257187043, 10892.8805628289, 16439.4205052568, -17070.7313188965, -5891.35475802493, 368.744775670786, 2928.40570896639, 14367.1531447530, -8948.3181848652, -4935.72383257665, 9346.69618100434, 2293.91176509315, -13407.5149742766, -21149.4800846019, -17043.8483979380, 13439.5983172494, 5165.90245719518, 5125.826774144 [...]
+-8417.43049666794, -8878.66959612209, -18968.7580611316, -19922.7139185881, 8517.94457477776, -10995.3547591064, 5661.76526776185, -4680.50612464122, -9271.66247830581, 1569.84666831944, 9155.13994147374, -4882.23049133777, 315.577124789228, -7782.9148176455, -13392.0700455372, -3760.1864971742, -14687.7773688946, -2797.6919375081, 1899.77273340729, -3489.98150804788, -9171.17361825897, 8633.12903135473, -7300.14462668276, -15506.1377442791, -179.116422882307, -16757.6893887010, -18646.6 [...]
+-5026.49898774401, 290.25557443199, 1607.95161840257, 1577.89583570186, 11019.1731790222, -11675.7231696095, -62.6584698603104, 6918.82393807501, -2511.59896326492, -6273.87762318601, -21357.8527389736, 6456.18440525625, -12671.9669498606, 16994.1660370979, -4140.60775687853, 6406.84483030881, 1548.82213271420, -1498.06550809380, -6590.88050040917, -3652.54330967602, 5384.62788799199, 10584.2633508212, 14410.6088471137, 10588.6695115292, -9363.84324435415, -1545.07022052252, 7912.0666809 [...]
+4600.49750352474, 1106.58003000693, -11098.1493530725, 11482.5550030132, -12407.6284472107, -4712.56590263833, 2484.29632379147, -9280.69195055836, -4284.08452419281, 8723.71807375651, -19886.6551371003, -7136.28305446771, 11847.6738791368, -1036.76252623336, 9426.9940086291, 27899.5339357648, -1475.67406998759, -1625.23889441385, 27278.8931935495, 20506.0676422087, -4251.80576268839, -7798.66895631933, -10910.1180989560, -10898.1135604543, 13816.546218503, 9749.37971036663, -8296.255447 [...]
+2245.31506934473, -6073.34148878834, -6895.63493385899, 860.060627437292, 4758.55240568735, 1849.19744328786, -2638.41080170042, 280.379791858297, -16543.3011735721, 6295.11817212072, 3883.48534085329, 9568.94365205854, -12638.0336076176, -7659.26721958986, -1652.25575567511, 21877.7231961107, -19329.3920313740, 3478.06200747405, -17511.4512057979, 7405.85410328525, -6579.8288964715, 7352.84722659495, 6680.19202708918, -16724.3075152338, 578.832403031663, 3534.70574773081, -2397.50235574 [...]
+-901.346988005436, -2197.59406200528, -493.693131926288, -5991.01228536244, 160.623264548346, -5841.75201520861, 997.842215827434, -3364.87262349606, -5302.69408668337, -242.886963414297, 13649.3513434579, 5370.34092919164, -26812.7597154947, -20811.5119981608, 5369.85719659447, -1143.85388050521, -3861.32407919066, -18643.9235235981, -7999.97372485958, -20921.1994618096, 99.2694387124876, 1605.15187772940, -11523.9780900936, 4414.97386357415, -6470.1794410337, 11297.4336193792, 6104.322 [...]
+9925.00651613243, 651.33586145286, -3880.86113646557, 9182.14755025657, -17937.1838442905, -6272.56778999173, -7592.04494403445, -14890.1106996243, 20936.7264986904, -2365.51620476189, -5778.24645137257, 4759.79936470236, 12211.2822766717, 1320.85015139132, 9769.46321047147, 2972.26247620525, -1602.88156935048, -11032.9983958126, -11402.2543148587, -8370.24810527483, 6549.23633986127, 4682.04412510099, 13925.2095643761, -28534.5619324619, -3515.71544791166, 3928.92577660867, -13502.35253 [...]
+1349.13228671417, 5954.01790153831, 901.034574938287, -124.043083204875, -16690.0847682408, -7798.40694561545, 5350.11169330493, -7144.77993148485, 20382.9329202750, -569.470338475711, -9942.11373982592, -7930.52937004127, 16783.2994389558, -7238.85340364504, 14103.2852806051, -2685.36561307201, -3091.19708005861, -3315.57101396316, 1982.11291268397, -1586.44659506021, 4219.01262871601, 3249.38719574869, -13099.9670494091, 12947.3839695589, 18055.0459546919, 8996.34346988414, 10297.21915 [...]
+
+double y12[100] = {
+-86096136.142081, 36022558.3518468, -40051196.3085082, 19328198.7650186, -20909843.7120855, -26653948.9729136, 53786780.994652, -70302192.2869492, 7635055.50288764, -27235073.0511710, 78011176.1534077, -35948871.9705446, 36461566.2574377, 35707349.1216528, 57830864.8933213, -11296936.3461881, -12647070.3341149, 7529374.92183698, -12091150.42507, 42224959.6376129, 18429133.7984147, 100154564.808791, 52605253.7963502, -13071494.857757, 103431242.61695, 1423426.65629714, -144132886.762186,  [...]
+
+double lars12[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -57.79290630379929200, -155.77394062775727000, -217.68418410625895000, -280.75135310470273000, -309.70060688947791000, -325.88082009385147000, -339.93244028022667000, -354.04673612648673000, -385.76449373477999000, -391.67979036871429000, -420.25321873851328000, -420.95692416835521 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.88282800480795510, 5.87142050623942510, 42.029958 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -153.93021326701748000, -399.90218602885830000, -738.46869076068037000, -858.42184522845048000, -864.17478143961739000, -932.43650602958405000, -956.40972252605604000, -981.01638697694887000, -1028.49560553287780000, -1106.81044035777590000, -1174.04001957720520000, -1251.51976615498210000, -1285.09608226783640000, -1301.63493420467470000, -1312.62861014867170000, -1321.81866650790740000, -1366.36827605058170000, -1370.79639159670020000, -1392.56 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 103.23940834026160000, 108.75594638723248000, 169.68788151215438000, 191.11458304837919000, 216.10329830613722000, 272.80117863307771000, 384.00155488795383000, 469.66626544084306000, 557.45456174686581000, 588.04135272956171000, 604.46244314581054000, 615.91620982178404000, 628.66895218012110000, 670.27441752675975000, 673.31478843704053000, 687.42227732086758000, 687.950419036597170 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -38.34738151574008200, -58.13291230485447900, -77.39497083423124500, -99.36192381662077400, -158.76045328204648000, -167.27914191542934000, -211.56100275720317000, -212.54236811030052000, -214.79590 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -9.48262480599280620, -61.46959546950879600, -62.76478480508117700, -65.67732009131404400, -9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -412.92103390604865000, -529.40922010074951000, -534.50806267839812000, -582.71835497743496000, -598.24917628546075000, -616.66862134373378000, -650.02670712415397000, -719.46311933322602000, -761.88105581102570000, -821.01280743429800000, -844.57003047504963000, -855.27999635101321000, -867.83349960741839000, -882.57683659617339000, -924.29295439762529000, -930.21846747257132000, -967.26868108971746000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -7.84329329705041010, -91.54032463769210900, -126.85718065100453000, -165.42714018725246000, -248.01366746292544000, -385.17603274085684000, -475.87054149856789000, -582.90613809644572000, -622.75996719042973000, -644.74482679186644000, -659.51623541373772000, -675.24245999009793000, -709.69316602845402000, -714.55345202221281000, -740.48045796769281000, -741.1359 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 16.911059 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 78.47803691801981100, 111.98055112903664000, 146.34156039972299000, 216.02773110056745000, 360.96895514733200000, 463.88560996527889000, 573.62344647988721000, 621.78747590768012000, 647.21010687780642000, 663.73109077117670000, 678.52181387461667000, 722.88899125798184000, 728.73085904165930000, 756.53191813326896000, 757.34178746333828000, 7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 67.74276165403935600, 132.06432176388671000, 165.49699529467230000, 181.54939599046889000, 190.99717368959327000, 200.56979782707884000, 249.95408633064886000, 255.41108847150389000, 285.83828310199033000, 286.63175214282523000, 288.3622267 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+1249.03688641043550000, 1537.74327730240380000, 1676.83371101646370000, 1901.86704409869800000, 2188.22784394218340000, 2294.33336360008160000, 2299.03772098056970000, 2358.11497136608070000, 2381.14131827411890000, 2401.08985040081320000, 2440.37254999014840000, 2495.35780474578540000, 2535.21151114365330000, 2571.92944177249860000, 2588.16789271288420000, 2596.79097389360600000, 2600.25659923020070000, 2605.50801959059980000, 2618.04003070991940000, 2618.66470107968730000, 2618.4561137 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -22.74372218679684100, -45.90202731723924500, -131.05395767048824000, -142.18129835616853000, -197.84563489412614000, -199.31330471721193000, -202.322477375 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -8.97366459334474520, -11.78297483236391600, -11.65556696149655000, -2.34323624487490840, -2.33708286976042380, -0.03156306538138252, -0.04722102000634242, -0.11276808417169025, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -16.56155534470724800, -60.76267091745950900, -67.33134485670265700, -102.24551716844879000, -103.28182049248740000, -105.2136699579786 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 30.52542113097104000, 31.17689180491278100, 32.20498784673878100, 43.072 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.56451585077600400, 103.70240293623253000, 220.23414061123685000, 301.87374051804454000, 387.94312006912418000, 413.13871432972144000, 425.77543178302744000, 434.24548326282610000, 447.78500759645607000, 495.43952699694700000, 500.00257824552585000, 528.65678130154413000, 529.41978219744408000, 530.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -57.66449869277573000, -80.39574347089008200, -91.92407205873512100, -100.40606914397488000, -112.18985141598117000, -154.27242654820839000, -160.01983838020033000, -189.82604627865280000, -190.96879910259011000, -193.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 127.94763882827587000, 211.48481560774735000, 312.09947153709817000, 359.88661473636574000, 384.89414247776790000, 403.74523330916679000, 422.07210215175434000, 480.49236242582549000, 488.08175850297158000, 524.22450064936208000, 525.03474019674184000, 526.8280 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 64.45170351550785900, 71.64327153328734700, 106.57164408111272000, 107.91845161512082000, 110.59803269101863000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -267.98159699777347000, -770.27645867142576000, -933.93396488208907000, -940.89712342963685000, -1021.08632658748890000, -1048.42332446318210000, -1075.48197449528740000, -1112.34169184591770000, -1181.36288541536780000, -1226.88484247886300000, -1282.79155198209490000, -1302.97987071021290000, -1313.46149151681380000, -1324.74021639572860000, -1337.70235453452870000, -1387.42383498297000000, -1393.76098313194960000, -1429.99 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.77439638124092620, 18.576812 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.66811013842933400, 69.17754752309001300, 140.91597086933569000, 279.13844946514627000, 374.92542898245017000, 477.93490309250859000, 519.93722367774922000, 542.34108444376159000, 560.29514902325104000, 579.10642149807643000, 638.05029239580278000, 647.58404936265697000, 696.88771140073550000, 697.78435476314905000, 699. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 321.53156628664362000, 509.42069893530066000, 807.22123713502219000, 1288.95799581073580000, 1456.92573850193250000, 1465.00744881247460000, 1551.35533220733530000, 1584.20012158574380000, 1617.92403825891440000, 1689.31599047369810000, 1791.61121543144620000, 1860.28580111802150000, 1929.33924590363990000, 1953.46404725363660000, 1966.60451205097520000, 1975.94795091270630000, 1982.99113484509010000, 1998.31081940762870000, 2001.18202938535770000, 2018.2955671846016 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq12[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -985.64667047096611000, -943.93294839008138000, -851.68973818418192000, -792.69244676918834000, -847.11709925921889000, -873.79727163462439000, -978.94972474636768000, -937.65493159807477000, -772.42371281975409000, -946.37497428020754000, -901.37523385324550000, -875.4068929437054 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1217.80513257850160000, 1234.86685111511590000, 117 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -2243.34344042053910000, -2113.31098455833530000, -1869.46063910147650000, -1868.85858438648890000, -1871.08547061804420000, -1924.89113069251360000, -1850.40445503896720000, -1840.12416088403710000, -1790.76513780483260000, -1736.77462612642190000, -1862.51940890864850000, -1880.45343845685870000, -1908.40976648989770000, -1861.69609973623960000, -1812.58155897983220000, -1701.81581737654870000, -1909.45576190131240000, -1786.03412509339890000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 972.88632657922994000, 1074.29092241780860000, 1055.57497515992760000, 990.14621534229286000, 1088.54984955382360000, 1183.07451572934520000, 1278.49689081246950000, 1346.93469837584230000, 1270.06679939076800000, 1155.85722960759700000, 1160.53580742442680000, 1136.79243484857650000, 1155.97864131599750000, 1177.47095201291560000, 958.41952715166860000, 924.96547277338095000, 1029.02 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -750.23154333104856000, -728.13754604428755000, -953.36430187302119000, -1007.66751197379300000, -882.86552090801626000, -966.10223576867827000, -957.18304871871908000, -846.30393248039547000, -909. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -898.69691721341860000, -936.83098933633858000, -899.19254015338265000, -963.1098246609478800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1792.29660154590150000, -1510.65847137103290000, -1426.93566928158360000, -1283.64596610848030000, -1177.41519862617130000, -1259.75815800958870000, -1185.58422510174390000, -1278.00931275605130000, -1196.27132482665640000, -1301.00856556102960000, -1281.88839006573830000, -1217.95547069486340000, -1438.72179967855100000, -1492.19508386542450000, -1432.83841122237690000, -1485.87167783253040000, -1591.12 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1380.61983196818850000, -1308.40828869125810000, -1443.87207723214650000, -1512.04411637274300000, -1573.92414857659150000, -1488.50949381000780000, -1404.64773645055990000, -1451.75630615615890000, -1362.60995428944560000, -1389.22613295816700000, -1331.26691612459510000, -1325.50185986108070000, -1129.66872855793600000, -1170.31711021383740000, -1177.0417688800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 547.08212 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1219.46723901627410000, 1361.33610735971110000, 1346.00883926445110000, 1334.82552014554680000, 1526.87552182889890000, 1517.82639739501470000, 1464.40876210185930000, 1515.90875260498960000, 1508.10591671898350000, 1415.04617929647410000, 1290.09941676337890000, 1263.75251546787060000, 1276.54039847608760000, 1224.64870829823870000, 1280.3519 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 761.47750931582198000, 654.18780299472678000, 786.14408599470119000, 725.13768601214133000, 620.64821531026917000, 596.38564012331813000, 851.97931975587335000, 767.13061725424700000, 798.17418502619967000, 799.05067850049215000, 821.569207 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+3844.45956766345220000, 3840.06259385024260000, 3564.81519174469580000, 3469.41999956831160000, 3144.82500998479330000, 3188.12324153615870000, 3122.42034826123840000, 3217.03687393529980000, 3239.82596110587060000, 3097.56535451800480000, 3071.04857948438760000, 2937.65895137865750000, 2943.34221435454950000, 2869.98337160232220000, 2889.61992359354600000, 2888.79751189225590000, 2757.86080872306770000, 2822.64757749546970000, 2770.81305119902340000, 2677.24192333678140000, 2614.9439009 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1057.04662802191520000, -1003.46851271432400000, -1169.10902135369360000, -1185.62555315157170000, -1135.12685360408000000, -1147.12822412709830000, -1129. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -312.85213635374686000, -139.54032781729794000, -6.38741342300584950, 111.17987491631453000, -1.76006234956798350, 38.78899146570130800, -10.15906141322032100, -20.3096275828866 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -701.36082087013153000, -599.60179823257374000, -683.29568684435958000, -690.13356200821636000, -772.52209245823724000, -700.4698072697 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 544.51526990535262000, 451.89387774236047000, 348.98975269242192000, 383 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1241.33694646596540000, 1213.69760618124040000, 1157.61492427472470000, 1137.92213679981930000, 1086.60223222129140000, 880.87194128504018000, 853.69719639038294000, 819.43304342456952000, 1007.62713149435240000, 1076.37779775432500000, 927.89363902645539000, 1011.13888801260300000, 1022.16251035182640 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -525.74998588377866000, -502.38056997708730000, -482.31206091049552000, -486.13687259361200000, -599.43427242745895000, -667.28522646497061000, -698.97195869702932000, -691.70571648964381000, -928.95370462328992000, -98 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1157.15788099621680000, 1066.96576794103290000, 1128.82833083342580000, 1247.01134235291240000, 1231.73316053055870000, 1261.02522753967970000, 1179.86483728852570000, 1192.67171934250040000, 1199.76229006573230000, 1132.79931737044920000, 1048.2839882379117000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 850.15810993203388000, 746.01826759853930000, 694.69879380214024000, 977.68101961737727000, 936.25091576757427000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2134.70657783346950000, -2448.20808009936040000, -2312.51844353096660000, -2159.62761419373560000, -2186.95410974254360000, -2067.85816363810180000, -2020.19744539566930000, -1704.11721720432370000, -1736.56906193322020000, -1693.06252147272240000, -1736.60837079274170000, -1677.75759445981700000, -1668.40443362812470000, -1837.65616834788400000, -1873.67029307275240000, -1993.55964821953850000, -1988.01445434540510000, -204 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 548.51489289758888000, 545.341 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1327.49036678031580000, 1274.02698940858070000, 1292.66227321537300000, 1390.99945738558630000, 1355.85319812306440000, 1314.10344642775860000, 1299.67199570771960000, 1301.01117961957330000, 1376.78160685105190000, 1356.92863120230410000, 1356.61278891986880000, 1541.59315851859360000, 1527.06730781795450000, 1276.8328184 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2885.61867795236230000, 3059.78446873996430000, 2881.66108745188560000, 2898.21463421798850000, 2871.81790171078910000, 2879.51305079233360000, 2806.76393373101610000, 2809.02820000043900000, 2795.34810718689000000, 2835.49976682714260000, 2614.47355361568860000, 2563.56309907289510000, 2489.87330199424830000, 2401.31898047649570000, 2411.58485640194980000, 2400.85403646063060000, 2274.21783931028040000, 2185.06731533439460000, 2270.42403789398580000, 2306.4548907754 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso12[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -57.79290630379929200, -155.77394062775727000, -217.68418410625895000, -280.75135310470273000, -309.70060688947791000, -325.88082009385147000, -339.93244028022667000, -354.04673612648673000, -385.76449373477999000, -391.67979036871429000, -420.25321873851328000, -420.95692416835521 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.88282800480795510, 5.87142050623942510, 42.029958 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -153.93021326701748000, -399.90218602885830000, -738.46869076068037000, -858.42184522845048000, -864.17478143961739000, -932.43650602958405000, -956.40972252605604000, -981.01638697694887000, -1028.49560553287780000, -1106.81044035777590000, -1174.04001957720520000, -1251.51976615498210000, -1285.09608226783640000, -1301.63493420467470000, -1312.62861014867170000, -1321.81866650790740000, -1366.36827605058170000, -1370.79639159670020000, -1392.56 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 103.23940834026160000, 108.75594638723248000, 169.68788151215438000, 191.11458304837919000, 216.10329830613722000, 272.80117863307771000, 384.00155488795383000, 469.66626544084306000, 557.45456174686581000, 588.04135272956171000, 604.46244314581054000, 615.91620982178404000, 628.66895218012110000, 670.27441752675975000, 673.31478843704053000, 687.42227732086758000, 687.950419036597170 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -38.34738151574008200, -58.13291230485447900, -77.39497083423124500, -99.36192381662077400, -158.76045328204648000, -167.27914191542934000, -211.56100275720317000, -212.54236811030052000, -214.79590 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -9.48262480599280620, -61.46959546950879600, -62.76478480508117700, -65.67732009131404400, -9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -412.92103390604865000, -529.40922010074951000, -534.50806267839812000, -582.71835497743496000, -598.24917628546075000, -616.66862134373378000, -650.02670712415397000, -719.46311933322602000, -761.88105581102570000, -821.01280743429800000, -844.57003047504963000, -855.27999635101321000, -867.83349960741839000, -882.57683659617339000, -924.29295439762529000, -930.21846747257132000, -967.26868108971746000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -7.84329329705041010, -91.54032463769210900, -126.85718065100453000, -165.42714018725246000, -248.01366746292544000, -385.17603274085684000, -475.87054149856789000, -582.90613809644572000, -622.75996719042973000, -644.74482679186644000, -659.51623541373772000, -675.24245999009793000, -709.69316602845402000, -714.55345202221281000, -740.48045796769281000, -741.1359 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 16.911059 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 78.47803691801981100, 111.98055112903664000, 146.34156039972299000, 216.02773110056745000, 360.96895514733200000, 463.88560996527889000, 573.62344647988721000, 621.78747590768012000, 647.21010687780642000, 663.73109077117670000, 678.52181387461667000, 722.88899125798184000, 728.73085904165930000, 756.53191813326896000, 757.34178746333828000, 7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 67.74276165403935600, 132.06432176388671000, 165.49699529467230000, 181.54939599046889000, 190.99717368959327000, 200.56979782707884000, 249.95408633064886000, 255.41108847150389000, 285.83828310199033000, 286.63175214282523000, 288.3622267 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+1249.03688641043550000, 1537.74327730240380000, 1676.83371101646370000, 1901.86704409869800000, 2188.22784394218340000, 2294.33336360008160000, 2299.03772098056970000, 2358.11497136608070000, 2381.14131827411890000, 2401.08985040081320000, 2440.37254999014840000, 2495.35780474578540000, 2535.21151114365330000, 2571.92944177249860000, 2588.16789271288420000, 2596.79097389360600000, 2600.25659923020070000, 2605.50801959059980000, 2618.04003070991940000, 2618.66470107968730000, 2618.4561137 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -22.74372218679684100, -45.90202731723924500, -131.05395767048824000, -142.18129835616853000, -197.84563489412614000, -199.31330471721193000, -202.322477375 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -8.97366459334474520, -11.78297483236391600, -11.65556696149655000, -2.34323624487490840, -2.33708286976042380, -0.03156306538138252, -0.04722102000634242, -0.11276808417169025, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -16.56155534470724800, -60.76267091745950900, -67.33134485670265700, -102.24551716844879000, -103.28182049248740000, -105.2136699579786 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 30.52542113097104000, 31.17689180491278100, 32.20498784673878100, 43.072 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.56451585077600400, 103.70240293623253000, 220.23414061123685000, 301.87374051804454000, 387.94312006912418000, 413.13871432972144000, 425.77543178302744000, 434.24548326282610000, 447.78500759645607000, 495.43952699694700000, 500.00257824552585000, 528.65678130154413000, 529.41978219744408000, 530.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -57.66449869277573000, -80.39574347089008200, -91.92407205873512100, -100.40606914397488000, -112.18985141598117000, -154.27242654820839000, -160.01983838020033000, -189.82604627865280000, -190.96879910259011000, -193.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 127.94763882827587000, 211.48481560774735000, 312.09947153709817000, 359.88661473636574000, 384.89414247776790000, 403.74523330916679000, 422.07210215175434000, 480.49236242582549000, 488.08175850297158000, 524.22450064936208000, 525.03474019674184000, 526.8280 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 64.45170351550785900, 71.64327153328734700, 106.57164408111272000, 107.91845161512082000, 110.59803269101863000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -267.98159699777347000, -770.27645867142576000, -933.93396488208907000, -940.89712342963685000, -1021.08632658748890000, -1048.42332446318210000, -1075.48197449528740000, -1112.34169184591770000, -1181.36288541536780000, -1226.88484247886300000, -1282.79155198209490000, -1302.97987071021290000, -1313.46149151681380000, -1324.74021639572860000, -1337.70235453452870000, -1387.42383498297000000, -1393.76098313194960000, -1429.99 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.77439638124092620, 18.576812 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.66811013842933400, 69.17754752309001300, 140.91597086933569000, 279.13844946514627000, 374.92542898245017000, 477.93490309250859000, 519.93722367774922000, 542.34108444376159000, 560.29514902325104000, 579.10642149807643000, 638.05029239580278000, 647.58404936265697000, 696.88771140073550000, 697.78435476314905000, 699. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 321.53156628664362000, 509.42069893530066000, 807.22123713502219000, 1288.95799581073580000, 1456.92573850193250000, 1465.00744881247460000, 1551.35533220733530000, 1584.20012158574380000, 1617.92403825891440000, 1689.31599047369810000, 1791.61121543144620000, 1860.28580111802150000, 1929.33924590363990000, 1953.46404725363660000, 1966.60451205097520000, 1975.94795091270630000, 1982.99113484509010000, 1998.31081940762870000, 2001.18202938535770000, 2018.2955671846016 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq12[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -985.64667047096611000, -943.93294839008138000, -851.68973818418192000, -792.69244676918834000, -847.11709925921889000, -873.79727163462439000, -978.94972474636768000, -937.65493159807477000, -772.42371281975409000, -946.37497428020754000, -901.37523385324550000, -875.4068929437054 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1217.80513257850160000, 1234.86685111511590000, 117 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -2243.34344042053910000, -2113.31098455833530000, -1869.46063910147650000, -1868.85858438648890000, -1871.08547061804420000, -1924.89113069251360000, -1850.40445503896720000, -1840.12416088403710000, -1790.76513780483260000, -1736.77462612642190000, -1862.51940890864850000, -1880.45343845685870000, -1908.40976648989770000, -1861.69609973623960000, -1812.58155897983220000, -1701.81581737654870000, -1909.45576190131240000, -1786.03412509339890000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 972.88632657922994000, 1074.29092241780860000, 1055.57497515992760000, 990.14621534229286000, 1088.54984955382360000, 1183.07451572934520000, 1278.49689081246950000, 1346.93469837584230000, 1270.06679939076800000, 1155.85722960759700000, 1160.53580742442680000, 1136.79243484857650000, 1155.97864131599750000, 1177.47095201291560000, 958.41952715166860000, 924.96547277338095000, 1029.02 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -750.23154333104856000, -728.13754604428755000, -953.36430187302119000, -1007.66751197379300000, -882.86552090801626000, -966.10223576867827000, -957.18304871871908000, -846.30393248039547000, -909. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -898.69691721341860000, -936.83098933633858000, -899.19254015338265000, -963.1098246609478800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1792.29660154590150000, -1510.65847137103290000, -1426.93566928158360000, -1283.64596610848030000, -1177.41519862617130000, -1259.75815800958870000, -1185.58422510174390000, -1278.00931275605130000, -1196.27132482665640000, -1301.00856556102960000, -1281.88839006573830000, -1217.95547069486340000, -1438.72179967855100000, -1492.19508386542450000, -1432.83841122237690000, -1485.87167783253040000, -1591.12 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1380.61983196818850000, -1308.40828869125810000, -1443.87207723214650000, -1512.04411637274300000, -1573.92414857659150000, -1488.50949381000780000, -1404.64773645055990000, -1451.75630615615890000, -1362.60995428944560000, -1389.22613295816700000, -1331.26691612459510000, -1325.50185986108070000, -1129.66872855793600000, -1170.31711021383740000, -1177.0417688800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 547.08212 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1219.46723901627410000, 1361.33610735971110000, 1346.00883926445110000, 1334.82552014554680000, 1526.87552182889890000, 1517.82639739501470000, 1464.40876210185930000, 1515.90875260498960000, 1508.10591671898350000, 1415.04617929647410000, 1290.09941676337890000, 1263.75251546787060000, 1276.54039847608760000, 1224.64870829823870000, 1280.3519 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 761.47750931582198000, 654.18780299472678000, 786.14408599470119000, 725.13768601214133000, 620.64821531026917000, 596.38564012331813000, 851.97931975587335000, 767.13061725424700000, 798.17418502619967000, 799.05067850049215000, 821.569207 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+3844.45956766345220000, 3840.06259385024260000, 3564.81519174469580000, 3469.41999956831160000, 3144.82500998479330000, 3188.12324153615870000, 3122.42034826123840000, 3217.03687393529980000, 3239.82596110587060000, 3097.56535451800480000, 3071.04857948438760000, 2937.65895137865750000, 2943.34221435454950000, 2869.98337160232220000, 2889.61992359354600000, 2888.79751189225590000, 2757.86080872306770000, 2822.64757749546970000, 2770.81305119902340000, 2677.24192333678140000, 2614.9439009 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1057.04662802191520000, -1003.46851271432400000, -1169.10902135369360000, -1185.62555315157170000, -1135.12685360408000000, -1147.12822412709830000, -1129. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -312.85213635374686000, -139.54032781729794000, -6.38741342300584950, 111.17987491631453000, -1.76006234956798350, 38.78899146570130800, -10.15906141322032100, -20.3096275828866 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -701.36082087013153000, -599.60179823257374000, -683.29568684435958000, -690.13356200821636000, -772.52209245823724000, -700.4698072697 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 544.51526990535262000, 451.89387774236047000, 348.98975269242192000, 383 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1241.33694646596540000, 1213.69760618124040000, 1157.61492427472470000, 1137.92213679981930000, 1086.60223222129140000, 880.87194128504018000, 853.69719639038294000, 819.43304342456952000, 1007.62713149435240000, 1076.37779775432500000, 927.89363902645539000, 1011.13888801260300000, 1022.16251035182640 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -525.74998588377866000, -502.38056997708730000, -482.31206091049552000, -486.13687259361200000, -599.43427242745895000, -667.28522646497061000, -698.97195869702932000, -691.70571648964381000, -928.95370462328992000, -98 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1157.15788099621680000, 1066.96576794103290000, 1128.82833083342580000, 1247.01134235291240000, 1231.73316053055870000, 1261.02522753967970000, 1179.86483728852570000, 1192.67171934250040000, 1199.76229006573230000, 1132.79931737044920000, 1048.2839882379117000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 850.15810993203388000, 746.01826759853930000, 694.69879380214024000, 977.68101961737727000, 936.25091576757427000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2134.70657783346950000, -2448.20808009936040000, -2312.51844353096660000, -2159.62761419373560000, -2186.95410974254360000, -2067.85816363810180000, -2020.19744539566930000, -1704.11721720432370000, -1736.56906193322020000, -1693.06252147272240000, -1736.60837079274170000, -1677.75759445981700000, -1668.40443362812470000, -1837.65616834788400000, -1873.67029307275240000, -1993.55964821953850000, -1988.01445434540510000, -204 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 548.51489289758888000, 545.341 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1327.49036678031580000, 1274.02698940858070000, 1292.66227321537300000, 1390.99945738558630000, 1355.85319812306440000, 1314.10344642775860000, 1299.67199570771960000, 1301.01117961957330000, 1376.78160685105190000, 1356.92863120230410000, 1356.61278891986880000, 1541.59315851859360000, 1527.06730781795450000, 1276.8328184 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2885.61867795236230000, 3059.78446873996430000, 2881.66108745188560000, 2898.21463421798850000, 2871.81790171078910000, 2879.51305079233360000, 2806.76393373101610000, 2809.02820000043900000, 2795.34810718689000000, 2835.49976682714260000, 2614.47355361568860000, 2563.56309907289510000, 2489.87330199424830000, 2401.31898047649570000, 2411.58485640194980000, 2400.85403646063060000, 2274.21783931028040000, 2185.06731533439460000, 2270.42403789398580000, 2306.4548907754 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso12[1600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 98.38653306901831300, 125.40980837589721000, 199.17376265352823000, 291.38053415880938000, 304.31497113369051000, 432.04672256829878000, 483.71939401197761000, 512.9654399230958 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 13.63221977711728200, 68.23172 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 240.71244584422760000, 293.99517041626024000, 396.70500383219456000, 453.41356688650592000, 600.14973281061270000, 729.97817556928658000, 772.15967458025182000, 804.67653805916655000, 844.82295953436721000, 910.16612817280463000, 1056.14117533488320000, 1067.10303152068740000, 1091.36323521841790000, 1156.41050887415690000, 1173.97493806367830000, 1221.18276023427070000, 1288.95434033654870000, 1298.57054804148200000, 1386.05267363768850000, 1424 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.73776837634717100, 51.28046880584670900, 105.01988438361271000, 112.22640530579307000, 190.99407616733211000, 218.91000850971378000, 235.7056092066034100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 45.88978628449815000, 190.26839061586165000, 202.40234782192161000, 227.14585349647757000, 300.45115806132361000, 319.34527109055244000, 369.89953151835937000, 436.44169387495305000, 445.59799845331247000, 544.22848693530841000, 590.89544176294521000, 614.34538 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 145.37584349164905000, 217.50022867857874000, 410.85376351026787000, 565.51421576989503000, 615.40422093179257000, 644.96831041593282000, 673.92323160524336000, 710.01205256434446000, 757.84204346711817000, 760.26292545473052000, 765.73150378943694000, 770.38241188287066000, 770.16926958293868000, 769.78074989531183000, 766.92566122780715000, 766.45845932373891000, 764.08737667534513000, 765.1003566231362 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 115.22362696657061000, 147.78989112908963000, 171.22964426188932000, 198.42545438119279000, 245.87519591462629000, 401.45173804685589000, 413.78062578710313000, 440.45179420595309000, 495.22335823707323000, 511.78792312764131000, 554.33962075885836000, 615.74839391262856000, 624.20722277130062000, 721.49150228918359000, 767.09167084173066000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+1249.03688641043550000, 2226.74558928097580000, 2483.84778529952430000, 2545.35944693509650000, 2679.55235144808880000, 2739.75837245868660000, 2857.74514543499660000, 2952.87114082322840000, 2990.32771358009900000, 3016.33761169005900000, 3049.27754760304650000, 3106.84166380460370000, 3221.70939577013040000, 3229.80032610193440000, 3247.00159141788980000, 3295.09711625675030000, 3308.66938205898210000, 3347.50106927344950000, 3399.58135890525360000, 3406.85193097309460000, 3477.7109280 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 35.60823965904081900, 93.61894429544194900, 229.21740954939179000, 239.07550679828626000, 261.16580021982554000, 334.80256129486725000, 355.49972536007499000, 405.49423427060071000, 473.43315518336692000, 482.63795573310523000, 579.63788248592471000, 623.36372867008834000, 647.7535 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 53.08507587463932300, 60.15262758039845900, 128.82985359138360000, 156.04436676741784000, 174.35608308612140000, 2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 40.89925383850670200, 65.42211280647123300, 97.65308235258805800, 158.16919653331186000, 263.84953615768535000, 273.36322565930232000, 295.90549469598506000, 356.05467263669891000, 369.46005730579282000, 407.71914188001864000, 454.78536989562201000, 461.40118911863561000, 518.28587567545503000, 535.99448602689756000, 545.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 83.68042398016855500, 120.10070228280428000, 139.56886031532352000, 225. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 64.306958 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 9.60915110766267410, 30.45241382615571600, 102.41877591382949000, 119.88467023395883000, 161.17952604469403000, 209.43635707379792000, 216.25067725687634000, 267.97549226782110000, 286.23955670230941000, 295.11654633331 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 64.38804946940327100, 202.15346322569343000, 312.47597990603964000, 355.20620726486538000, 383.06386651830388000, 418.61526651528101000, 480.27550929056605000, 626.09580404028020000, 638.71558516534958000, 666.23818349909970000, 757.78890834023844000, 780.88550983271989000, 838.66931615563658000, 912.77669538416171000, 923.03123767724901000, 1017.54306244185920000, 1058.49813336904480 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.51661535804046090, 7.58712255550875090, 13.03245295198400900, 17.30539316366545000, 46.1470 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 170.58136267266664000, 296.83953611162150000, 345.48615398454899000, 380.18190276289562000, 430.01849866902563000, 509.77986459439705000, 680.66095809919511000, 692.35336182292417000, 718.12088548549741000, 795.20281064976064000, 816.48803121201070000, 870.90961278275643000, 937.60092611495361000, 946.76739835072669000, 1038.52344009637300000, 1082.036695654595900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 205.54656214187375000, 220.72977283185040000, 254.31579700470985000, 339.02640669120785000, 360.05073453680018000, 411.84542150945288000, 485.74231871287816000, 495.78138834208164000, 599.92621878244290000, 649.24350866658813000, 676.720246 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 27.60068034691813200, 60.82281013183217100, 115.04991811327685000, 260.32554175270087000, 271.37881155695680000, 297.49923020219245000, 363.56524901281222000, 382.03591429255027000, 427.42680666126097000, 480.34257564219320000, 487.67325555844388000, 553.15993376784741000, 579.63673907294071000, 591.69 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 28.34911745147433800, 68.62077749655509300, 74.16705722674792900, 120.79179348806808000, 140.63763960707598000, 151.55377262494125000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 64.47875692975675600, 214.98880835311152000, 286.89692131625526000, 466.41290056683869000, 609.07200057766090000, 658.62019557967619000, 689.95049995053137000, 725.60669669589356000, 781.99332916693265000, 897.45092729560747000, 905.98362246724980000, 925.27063521189007000, 980.09628727537893000, 993.16742506220123000, 1021.72972006166840000, 1055.08626808418030000, 1059.88527709118330000, 1100.66384522471070000, 1117.1302485 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 34.49062105546297400, 52.64937156305129700, 143.472 [...]
+0.00000000000000000, 1088.87167213309110000, 1373.06470043729430000, 1442.23185717814450000, 1575.63513667246820000, 1640.90076636875050000, 1757.32744605346280000, 1843.65992351430960000, 1876.68160575925120000, 1894.55879413817210000, 1909.65454646837090000, 1935.69166690569300000, 1956.41250354429780000, 1958.78819384750300000, 1960.90914201905570000, 1945.67289026576210000, 1942.82040438848940000, 1933.63781784557300000, 1914.31051641428620000, 1911.87453618134490000, 1892.6475750651 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 11.77692939319288400, 31.42309763807323000, 35.59552719861420700, 47.66305585327872100, 68.12104909105724500, 70.97119349721599200, 76.53459532425752300, 80.96665799051712000, 84.65721418311542800,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlassolsq12[1600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1027.51654996175220000, 1060.84111455841340000, 1113.13994373798230000, 1069.55645545788750000, 1072.86143517897380000, 1111.12212008969070000, 1073.43212032667520000, 1063.9097 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 270.43938735609902000, 252.714 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 1486.16992173356220000, 1382.50208191121830000, 1319.62634991373470000, 1421.58203002957910000, 1554.71651886283980000, 1632.87881153436210000, 1553.26852105838770000, 1693.74907926106110000, 1718.38227061794850000, 1693.74749219379670000, 1756.01648448998960000, 1741.35104134590980000, 1734.95092183306450000, 1770.69553940964900000, 1781.98106435740420000, 1806.10738051936550000, 1860.91029241067460000, 1869.95239044435470000, 1851.1442311246576 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 524.89687255394051000, 504.05977931240329000, 558.55185979722876000, 540.42797167980859000, 609.75594861779609000, 537.49970223565015000, 552.10533817780799 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 596.19033155506759000, 882.48957708755734000, 948.74460581335904000, 883.55483399129446000, 992.72231290405989000, 973.37941866823735000, 996.28791854607789000, 998.02201657510625000, 989.65302930512973000, 1068.58940285001200000, 1123.48058573419100000, 1056.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1451.68181927601680000, 1448.85844691966010000, 1668.68179216125120000, 1641.11073173083150000, 1539.25769452854320000, 1453.30642651463810000, 1303.96297306110320000, 1142.78150868783110000, 987.16226168767969000, 909.16789506044768000, 910.80488088700702000, 814.30405624437265000, 762.79118614323625000, 764.96682880534661000, 742.83023723718622000, 738.69796444760209000, 751.48170992506618000, 776.66095 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 916.55408934992670000, 750.84567697195075000, 812.11682258511655000, 790.18811414537527000, 814.88239235076901000, 1147.36127970420900000, 1172.11278060825630000, 1147.99884516509380000, 1012.46797115352630000, 1085.18298334762860000, 1081.57291462875540000, 1134.00565251368790000, 1126.81920518086170000, 1238.69540847698390000, 1287.502150234 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+3844.45956766345220000, 3840.06259385024260000, 3814.10659670341560000, 3801.97440733079200000, 3885.37161868592830000, 3767.63789707236040000, 3625.28772069160230000, 3614.43127285452190000, 3683.94128884772360000, 3727.49741417283850000, 3766.02854721732680000, 3797.13828748785910000, 3772.44112002199380000, 3727.46181530464950000, 3703.32597720926510000, 3749.29541364616490000, 3778.48372480841950000, 3828.64188142260950000, 3839.11119716046910000, 3838.85932837103160000, 3854.4269839 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 810.41974620055328000, 789.27096139200853000, 879.34234278674637000, 845.43289172169375000, 847.18894400477109000, 1030.20388226208050000, 1071.94786112187060000, 1024.94706637022680000, 1046.80137435292110000, 1029.57455053672490000, 1095.33005048174850000, 1122.38356339618140000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 501.09477355300248000, 480.09683415598681000, 493.94670222358809000, 466.62913647221086000, 519.31677754394730000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 798.26373202615548000, 735.92345295945279000, 798.97744745581576000, 883.86555137900814000, 770.53243713392249000, 858.53658533788371000, 893.91888984817820000, 924.08370031811035000, 833.49768222306307000, 881.76516832380707000, 851.99920517253452000, 854.50407256723565000, 820.70865390086681000, 738.09344080953008000, 73 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 528.56054611787431000, 535.74597493717044000, 506.31489317370017000, 513 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 281.58986 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 600.65421689149332000, 583.39365874039947000, 782.04539895300331000, 724.47993679535261000, 672.84002517843112000, 616.69824610866158000, 621.14821487277163000, 542.96623592218873000, 494.67761361579647000, 462.34349843 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1163.66610452907930000, 1098.36257030099570000, 1079.72134121033060000, 1146.47629923870550000, 1144.74495302442710000, 1192.18997998259030000, 1219.69201060945260000, 1325.22915493230110000, 1414.94017375530620000, 1396.37242358791920000, 1622.36380354990730000, 1580.39200403585710000, 1554.63479429019640000, 1538.20340933124590000, 1532.34204378812820000, 1520.00743994909860000, 152 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 91.63181503796185700, 39.86047700322931300, 75.17711364152822300, 97.80011016039283300, 143.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1280.26895810210180000, 1174.91049399657890000, 1246.31482206738060000, 1328.82928861146070000, 1514.42953175207250000, 1466.26118024359400000, 1499.94795591495380000, 1411.53630011095790000, 1401.69556401694990000, 1523.13912668760170000, 1553.29219158187240000, 1545.21572291321760000, 1500.44000341586090000, 1491.42657742855340000, 1526.33692283338150000, 1578.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1191.03666145375310000, 1154.62722751032270000, 1145.30384761272400000, 1139.00550701987230000, 1087.82389433603290000, 1053.60321115679630000, 1109.39267674677900000, 1092.28910497577640000, 1153.60368219131400000, 1212.07551753090480000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 782.25547756768196000, 783.71415987681632000, 765.32984980944138000, 956.84747467217744000, 951.24954159191543000, 990.43569597745466000, 987.47097328999473000, 1021.41209473234910000, 989.83890835124089000, 926.92341353247389000, 923.25217867844674000, 901.31449626261269000, 881.80244106472446000, 818 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 379.60651502426049000, 408.49208679653492000, 403.71937431049258000, 368.66838607667853000, 367.12772989819456000, 357.1946181414581400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1381.70818028178630000, 1567.42931612725900000, 1514.56278808084240000, 1634.22310113372940000, 1601.20430524840300000, 1576.14409469566360000, 1546.58027119791310000, 1501.46171739755000000, 1458.16981868930720000, 1451.01075656486610000, 1430.81743166971360000, 1436.92684670493210000, 1497.85168975683500000, 1445.63483896248450000, 1375.62847643008790000, 1336.59772396774720000, 1345.03579507788730000, 1317.4597636601125000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 428.11374149105961000, 394.72845779190254000, 450.3 [...]
+0.00000000000000000, 2885.61867795236230000, 2843.49274771055930000, 2855.24008387060350000, 2774.35905811047410000, 2755.16148813307150000, 2514.72110383002790000, 2444.06494376655470000, 2488.17073563603890000, 2383.35493254489980000, 2238.12803230577360000, 2247.92327079908550000, 2055.75826318152030000, 2104.91348793515590000, 2017.17479189433220000, 1801.78674642747160000, 1844.07942796194520000, 1819.86173795268500000, 1751.19841139220190000, 1767.13193948794200000, 1790.4290106404 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 324.20162450397987000, 216.95504051523571000, 180.02736195766190000, 197.18477262728848000, 240.77558927118699000, 240.32285601068133000, 106.11196559310234000, 131.54743280039528000, 154.1808352886 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+
+
+// Data from file x60.txt and y60.txt
+double x13[5000] = {
+14779.1410779229, -9306.8598765508, 8373.16937476193, 5482.09935815005, -2226.62148496176, -35037.2486211718, -9809.70576519336, -8155.63595866259, 14704.7928721634, -9794.64902942575, -2917.45545836814, -2695.50203115495, -10546.3656299362, 16043.3619254737, -9890.97541229189, -4238.91842085031, 2246.37312919521, 18930.0174182360, 13766.3680015434, 2022.91459060353, 11805.5176637722, 25844.5316596711, 3373.80619191527, -1740.91157085131, -8069.48239512503, 2427.29953780215, 5927.2728556 [...]
+12004.0524054609, 4533.81214809437, -6539.37028251119, -1495.41569284033, 1377.19222256550, 27225.0452634541, 5594.1075559721, 4890.35027522156, -7376.94338379977, -10933.1329980813, -4509.12173006, -11686.3541038840, 10603.1145638863, 2059.87003628029, -15975.8771644488, 20003.7030838184, -21410.1548075922, -2491.85479309508, -10589.9713473945, 3246.76745321222, -2369.42494857321, -720.65935721785, 15948.1061230303, 13610.3361402266, -10858.6591750656, -3757.98741091370, 1069.3511242735 [...]
+-1844.48557527934, 11278.2308978656, 8518.86066121693, 1884.61891027436, -16811.8531989833, -8552.45431219592, 6668.56352998519, -3205.08860597093, 11411.0672060897, 22058.7912701634, -16520.3562656719, -5240.84245680736, -8598.38991384652, -11798.5152163161, 11741.9837132987, 2103.84017250914, -29.7244448034940, -6341.04504798803, -3334.73928864297, -8934.50050282843, -12047.8400863766, -7061.61207893917, 3445.84273471268, -2393.7035792755, -4225.82531822491, 15954.0340171451, 10686.454 [...]
+14707.3828172069, 2090.23948563227, 11661.4492506649, 1809.3217883302, 17356.8706676891, 18134.409061981, -1919.542443424, -2708.08398762086, 24420.3758225659, -2520.55298114705, 8895.703472739, -1845.63951045667, 1075.55738789634, -5926.98695727109, 3249.9417286243, 395.201224067626, 14674.7886175446, 19806.6396950544, 2803.13136516197, -22011.2119936676, 18631.6245193238, 18583.4776388396, -454.20019278208, -3525.00353406219, -1954.68719879796, -6985.95317210532, 11863.2817589466, 830. [...]
+2575.72259522051, -1952.07942575163, -7654.29829006856, -27101.4610478873, -9038.68371429817, 7883.5291759774, -738.148604896079, 15110.9662003407, 4671.94069512351, -2663.83448631716, -1635.76840356593, -5177.14411198733, -1940.00041263813, -6307.40304743763, 23080.5435605222, 2035.8629803611, 1782.63775353860, 5325.29386921895, 2561.39830961136, 15337.4308403356, -10976.4866750680, 15321.6193581875, 6889.40132980767, 291.700068365652, -3104.85579957756, 7626.1729095119, -5148.487906177 [...]
+-912.589892210504, 6168.30460769576, -1299.72661238240, 1431.58805854594, -172.460836167130, 10774.6111626898, -5655.27999124133, -14023.7624318084, -7106.8807769814, -126.189471918026, 11104.7989197416, 11915.0352606468, -1647.57898612628, 3439.33350167549, 6548.64631709966, -228.400643034078, -12469.2703902143, 7681.8014429207, 6681.43260559493, -2072.69124857005, -2249.24121307292, 15127.4074517126, 9030.17033176452, 12788.0928947351, 8049.61662948738, 9415.53309255943, 15462.83892650 [...]
+-9171.20701510895, -20749.5554108582, -3314.94531970385, -2604.75407878854, 858.763530708314, 9781.49658794901, 9951.42431813779, 898.360445241875, 8426.92169277712, 14063.9579561720, -3178.68642761335, 11768.9358456585, 4447.75050631975, 5631.51885899309, -6900.99481036581, 9394.77647830094, -16196.0205052754, 5358.01956055281, 14732.5981348336, -15232.075270262, -13196.6066960621, -14720.4623058199, -370.189053026876, -18258.3826132128, 3120.06316467744, 4039.92346063544, 1865.80867643 [...]
+-1093.58811656316, 7002.0668307583, 14367.301688638, 2314.09634389667, 6419.01177339451, 12705.4725624667, 2817.1374599008, -8312.87120325894, -7372.13087843788, -4234.62541851287, 11081.8060951181, -71.2723002482375, 6717.7495712254, -5490.13149296855, 11098.4524882558, 15515.1364359757, -10453.2573182224, -6404.9268366848, -5297.34772066849, 20079.8366008147, 3845.98376369809, 7657.98622463196, 17376.4510293867, 16928.2923677353, 4092.52502808303, -3406.05788117363, -5037.06222399611,  [...]
+-9565.19734670072, -5644.12123873466, -2920.17019972667, 2951.54253245956, 10715.5386280415, -91.9728270649878, -12838.3142473806, -8996.42222366796, -19848.0133948708, 5009.33897877735, -1520.80088586654, 9856.73743066262, 11301.6310178159, 27386.219482739, 3768.46574202066, -9667.33550327067, 10570.2245442490, 4158.30684810129, -8786.98186701604, 6721.16508133446, 417.281100716841, 20865.4268378697, 2280.98153048211, 2513.19313916496, -2852.62533543976, 1385.16462188101, -13480.4338080 [...]
+-6717.62139099317, 639.239610856767, 8388.0310879795, -4918.15567397669, -11406.8010751918, 1652.76633183447, -9116.54474086531, -12732.9145753326, -10988.3620136744, 15975.3188782126, -4488.31531385865, -429.990424719891, 5742.77250223309, 2983.85888405592, 28133.4696877898, 9253.38518144234, 4147.84015654075, -6135.08273969683, 4711.21707962638, 10353.5416600153, -19213.0664251509, 7396.53491807542, -1668.54655056020, 14014.649274785, 3189.37647791885, -21799.4107040754, 2892.923496002 [...]
+-7275.57535665329, 1202.09865339179, -13043.9781560217, -4600.12270228787, -738.696362427576, -7929.39841900749, -4471.01407416457, 18206.9795502254, 15840.0939776403, -7385.09066455697, 6080.20112082028, -13570.0725050616, -12872.3732352008, 12132.5641712395, -6631.47631889991, -8322.87127242636, 14739.2166846275, 7779.92363643213, 18288.3230851571, -399.682855471582, -5427.38202182215, 476.705184278992, -10798.8415161183, 3378.68262303577, -724.452663586996, 16949.1363006665, 15414.546 [...]
+-10383.2627622558, -33.9882143581903, 5177.07933088557, 2883.35616630626, -12158.3842878416, -3558.64970160933, -8030.45093197332, 2580.83627617293, 11431.3520140314, 8998.1612472088, 17359.6704569978, -3600.44767726167, 9750.44913414214, 803.709250802672, -8432.79765536952, 2756.77477116872, 8507.61755238583, -15928.6528281866, 6824.75602697615, 11470.4871394604, 9368.15076271556, -302.001067392699, 7864.98947977912, 18250.7417515884, 11882.5669505557, 18268.8870140303, 1492.54733094737 [...]
+-3319.86065028639, 12908.8303162001, 4256.72014026692, 12358.5802162009, 3791.34572374613, -3564.00845318311, 9317.51543928148, 851.022682279399, 3276.33377050221, 6024.16646712745, 10926.6409404284, -10936.5203890487, -11546.6108913747, -272.279908916877, 13907.4209896463, -7187.05342729759, 6016.68371727606, 5966.45664632445, -94.4968084800037, -3111.62438026059, 7018.00094356595, 15006.2341343979, -4201.27705520635, -1574.53163757849, 3822.60246509683, 6192.9148822239, -2381.874939943 [...]
+1090.66348964053, -6148.9483291731, -7439.81622527193, -10402.1874792135, 5219.03236869531, 3373.98596320059, -3862.48681772772, 6489.26601156971, 10474.6456659452, -19271.2399554308, 9855.80853395767, -4150.13264410361, -12379.723228034, 8832.42756846136, -6796.69633511915, 8316.17045471844, -1513.81440881498, 9090.95040955717, -19514.2958813474, -8380.89379599275, -4527.67420754659, -13850.7069779359, 9876.04465780817, -8225.3618855827, -14587.3407317627, 10292.2723778468, -13329.57253 [...]
+2442.06562939412, 5819.97204645035, 15136.6001534814, -13967.5737389928, 13748.2170856744, -2455.66555598699, -5019.92629321487, -4412.48400090514, -10819.0369856985, -12675.5700251969, 6418.234094587, -4962.10027788688, -9180.7473461519, -12162.0446191973, -24415.2783786668, -11133.4656711895, -5713.05525008839, -457.706666745452, -16815.7116727163, 5679.77010959526, -9297.8373931864, -4119.45298884892, 2924.20991630182, -17510.6412886182, -18998.5545622221, -6203.02947520482, -5529.646 [...]
+-10409.7945961692, 4001.75517020373, -17814.0063932407, 4031.45379714517, 4638.95660785014, -24625.2648976985, 16631.6964794287, 5846.18698362469, -5686.90354002305, 877.907962797367, -4277.23199695793, 7275.20616745894, 925.671424709735, -1892.50940653272, -18158.4940858135, 3056.98601426987, 15123.9252635144, 1428.71601204832, 10085.5133574269, 14541.5073154597, 2040.62511339650, -1765.6627738594, -12095.9809199331, -4608.47398747765, -14422.3562260714, 6111.99654587064, 4743.497098673 [...]
+19342.6982572534, -4049.7386800095, 2783.28088681881, -5403.61645942091, 3957.8103975971, 6374.67158911438, -6430.13275298686, -7588.79316260879, -33.8119093373999, 13280.0505765301, -11271.1756338940, -16499.1650587275, -217.078810371069, -2487.01729483222, 1003.42089247026, 8328.46733530569, 321.307301784994, 1056.35659692628, -1962.33937736932, -2911.98831685225, -6885.52059899486, 797.906848986874, 11821.4836171812, 3747.12563519062, 6508.54473794599, 24501.4144970539, 1046.998062003 [...]
+-19402.8903165159, 11200.9260799676, -12697.4515160398, 14440.8113983198, 3679.78794881546, 12948.0919180853, -11414.3918787277, 5359.2741354492, 16204.9001037191, -12048.4074601633, -11395.3709362874, 5830.02521590479, -14230.9639902575, -4996.91577274941, 2148.50735943430, -14381.9496762466, -19127.6147201263, 7821.3974760531, -10307.0750271664, -11667.8675057853, 11721.7954367957, -10562.7725184073, 546.873621022584, 15439.4514164316, 4789.28357065153, -2679.88744752612, 6340.16448660 [...]
+-15693.3746279202, 1900.61785989501, -10411.1558213835, 8670.419778, 6343.40230225646, -9289.59724679857, 13986.2756726817, -23540.2296439006, -9971.98073801866, 20916.8459938942, -5099.38309525442, 18065.3333801263, -5311.02465999703, -4088.14325917166, 17285.0362622277, -1109.35372086094, 2626.56932817903, -14267.3319632193, 12147.6670606926, 17543.9389610541, -6117.15087397219, 17937.1583751883, 4707.72887027744, 3257.72736173216, 6207.65476944047, -2957.93675655527, 3980.19289490887, [...]
+-9630.61729413113, -7714.39346792282, 10418.8059435192, 12648.3878640483, 24167.8423111108, -12771.1835298719, 32200.881139786, 5733.22078727292, 9853.82831683539, 6197.84823374142, 2671.24371105895, 8299.83629410758, 16736.4171943866, 4506.74849775267, 3254.55336975308, -20117.945154499, 7870.38576699662, 2938.28773086938, 8116.17402028407, 6213.47045035266, 2093.47181807554, -2963.70813516847, -13420.9151604499, 10154.5642658221, -12877.1894826349, -6759.34901345509, 8450.67542226405,  [...]
+-7836.60062205225, 13823.7491203453, -1937.81486712748, -5851.73304887639, -87.6628528486825, 2153.33102200619, 11836.7199410232, -13841.0882095750, -6115.20661842275, 13152.0854340248, -4785.94124693004, -2354.48086195499, -5107.8930618932, 2562.05629273072, 3538.05987297397, -10343.6292273505, 6536.98343611028, -6467.48508983518, 316.446482369241, -3897.50566248123, -11968.6578837274, -1311.95859354116, -887.855197123386, -3259.13650607842, 6334.28385170214, -7976.07600440647, -7997.20 [...]
+-564.096667065962, -5402.19608124216, -10439.2457929579, -9879.81296474508, -28441.984620607, 5538.58948778562, 5038.05530581556, -21044.6311677876, -11960.9742078854, 7214.79981381246, -2731.87974663004, 2448.75170156207, -3828.15730554652, -22833.7480725196, 3489.53026275517, 10635.1784678103, 3193.77604879887, 19449.9164202188, 8695.24557979536, 8261.32795881295, -6972.06912353328, 18077.8503734202, -5558.06951621578, -786.393287469874, 678.612252978049, 6683.28089403607, 11917.076006 [...]
+-3834.62344794865, -3602.98797720672, 18364.4172677685, -12252.1519143671, 316.378414854083, -5728.91991576759, 9838.88500434388, -2323.51189590747, 1081.06483834631, 3213.54510980636, -14551.0338348289, 8269.97660349983, -3474.07819545509, -7829.0793649046, 4224.23101220971, -6989.77366304148, 3089.85010434364, -7498.26162300413, -25968.4363189773, -4219.9379097616, -11359.2608256129, 8422.3759805075, 16473.1922394362, 13150.3816794974, 8296.7664264605, 9705.46597341093, 5415.4503370344 [...]
+4709.18837644048, -6913.54764990666, 1800.73249224498, 4299.85432089522, -9823.05519477953, 819.015989624223, -21210.7750799286, -7852.44316080512, 17555.2204201123, -8577.0774664912, 14027.9295414056, 1169.92028385431, -12227.5357778999, 5756.46048940372, -395.82468645944, -1826.48911339343, 7710.4702619723, -15793.2016566845, -12333.1749188597, -30523.7083833389, 11473.9522406857, -16697.6785468152, 6566.05358158558, -12886.4353325113, 989.485304423373, -14663.7501629515, 9709.44322092 [...]
+-24267.5194287548, -1721.35611273829, 8922.19223587268, -5640.36819773542, 11335.7929332080, 9519.44412593403, 6515.54323335448, 10627.9521469024, 1851.21483855683, 14220.0226228633, 11491.8685098933, -6791.2813849126, -4127.81837429797, 7361.92539124967, 3599.98283550580, 5972.25290467938, -7045.37742874855, 3244.81637085949, -13117.3546482777, 7871.85541878828, -13820.6210926608, -1755.11363907194, -1496.51158481652, 9842.76951053546, 13979.2638071457, 4680.25512179141, -1340.705674408 [...]
+-4314.80203613406, 2221.59184743538, -8238.02587648072, -14270.4909561086, 48.3411025603193, 11761.2674108485, 7233.42011224622, -21225.5534234167, 7770.95190802863, 4495.06039713961, 7114.24857262846, 7839.348039324, 59.7262293937461, -7303.8904195447, -6417.93610406987, -13346.5887902036, 13058.8201761501, -2657.21672534325, -13261.4589317499, 20609.4584540637, -6442.97360975005, 3574.35133802605, -10409.1570165110, -6610.02662231103, -5077.25294276835, 4199.60942376086, -2603.78849396 [...]
+-1211.71718245075, -5100.34075109757, -2406.56655490864, -11033.5215881342, 8757.93096833254, -1238.38801551855, 1370.80384381219, -10407.5072791174, -2651.79478342187, -9079.41365471652, 10150.7394010929, -16287.8066051936, 11900.0105193005, 3730.76615890016, -11623.8751825551, -7951.68268212462, 1646.60235068075, -4113.38929998393, 8609.47368241718, 4956.81520182553, -4920.61306120778, 9054.46770123047, -5468.37906369333, 1585.76534651810, -7589.60830487926, -11807.9225636230, -18491.5 [...]
+15427.1110966577, -1570.2523880903, 5400.40615407111, -1411.62898989246, -6023.34185668151, -4855.25956603181, 8317.78833968549, -14026.5263992137, -8860.86128332773, -12092.8444421035, -8157.8322662557, -7897.72080374742, 3120.45077417496, 13624.5462125659, 13942.2185828607, 10707.3005387653, 8085.43906965895, 9230.5861752621, -12762.1570004856, -1218.91189908748, 11413.9896491632, -9106.98471466667, -29814.9908604633, 4145.72648620214, -1534.62178123928, 5965.15024039611, -263.37498834 [...]
+11726.3086958010, -5761.24336304172, 6178.17166499645, -4828.91279511004, -21405.2679169423, -13138.7128718051, 15863.4672877616, 14151.6544533868, 2583.91095415769, 4393.06081884899, -9874.79808535874, -373.495688068886, -10188.1099801772, 4711.03012508171, -1476.88902987168, -8868.86280797748, -1801.16949436799, -6896.52633758885, 8500.86617878248, 5920.05495309535, 6625.65930228874, 9400.23122156927, -12980.2333008539, -6365.9618491233, 9392.07823418811, 6680.59153872668, -13108.26701 [...]
+-839.451997280767, -2204.69193767561, -8354.19062616737, -6870.66396207614, 7480.60582576498, 8682.7468105334, -5252.19282201383, -2306.05838417166, -9781.3000284054, 2277.56265293698, -16255.5888735001, 559.074846880571, 116.654260307959, 3461.59409081645, -3353.67827628120, 15113.4157802772, -12147.2793483425, -6828.62418128216, 11231.8812141984, -2774.74896358505, -8703.20282259396, 3263.71464613086, -21501.9757489348, -1749.7377252127, 6302.62297104529, -4818.15478616613, -8212.84124 [...]
+4116.99593337724, -11593.4572717637, 4548.9242649997, 15189.3500107826, -2443.63745807276, 7590.6466166929, -4388.42240755797, -5482.95706182611, 16951.4868696727, -15499.7195900282, 7837.81174593344, -7592.626837037, 2885.4736224175, 2944.76891430127, -7974.63804744045, 678.152657850369, 9817.83729057959, 6450.9991425388, 8703.75968919406, -3508.62587030272, -10957.9711484616, -4391.98396474788, -7804.78596100788, -7103.1863609183, -4615.4780283524, 7280.37156178024, -2328.02599566167,  [...]
+-20337.1057208382, 1196.45070953304, -21303.3852925928, 2148.25018542355, -4681.37249476137, 165.914591466287, 5722.00730667394, 12659.1819951238, 9722.12663529846, -3636.65981193805, -16813.6375773768, 701.755046376099, 13342.6614227742, -229.512855354597, 1221.36414213643, 16538.3376560465, -701.764055005603, -7034.6933671903, 1067.67021616228, 846.192615682617, 5941.42570947229, 10595.6553386429, 20422.9269472472, 5274.03013706407, -8358.99407013164, 1769.45275951349, 5186.52091840747 [...]
+8076.73227132264, -17257.5357946735, -9894.17906076195, -7757.58711786865, -7145.55317981512, 11013.3536721221, -17668.7976648831, 1878.92965952691, -746.42682104515, 2952.82985593397, 9447.32038164882, 1526.21161923876, 9482.11936597158, -879.427281817726, 9737.63586406067, -7124.87935844995, 12304.1959525284, 18712.092797577, -23905.90580385, 6248.84675908872, 9174.85135733604, 1487.72888486553, -11485.5388222672, 8094.94048903182, 20596.0625177886, -1655.21660550485, -15718.7394254777 [...]
+2473.15391992082, -1969.19215254694, 4512.06018667255, 6499.34753526742, 2644.80938790336, 9719.28548633654, 13352.0202283787, -2464.94073630107, 16215.7108944162, -3479.43978526141, 3758.15322736757, 479.488157594934, -9409.85253748636, -5738.19897788685, -7399.04503683945, 7358.73205275903, -3720.47418489853, 4758.61438531632, 22338.7263523373, -1117.02135182628, -4311.28063446691, 8306.30824281614, -3743.81583510776, 2335.14673360903, -1427.24578431374, -10109.5735378685, -8375.349174 [...]
+-10872.5821882064, -15352.7848866771, 15266.7496089610, 21350.3865193757, 21921.543047744, -2648.05824189528, -11617.0577133153, -8051.40833367471, -7609.07024497228, -4461.45927416934, -7770.63536932143, 3731.10373223235, -2136.97809548192, 8146.9089272504, -4664.80368434613, 5096.55102524963, -195.516131239404, 3594.62145798068, -9516.52622797857, -2338.48216007163, -12947.2086386349, 13368.8208704912, 13456.8949845813, -2293.86738907678, -5351.39947595175, 4918.80971008326, -25530.529 [...]
+10547.8244870676, 11301.3571909568, -21949.7659730527, -5313.29346695562, -118.542708766792, -15741.8221223818, 529.644248345301, 4150.33911821972, -1402.25084000703, 681.205746832411, 5083.28916278913, 9642.819997054, 1986.93553549777, -151.052041144487, 5238.23882925619, 11430.3183241874, -1599.80740425804, 58.5974097767285, 7855.11692167157, 4897.17117452014, -8056.41950698676, 168.910964189121, 8363.36730467102, 20607.6600329995, 8716.8852867288, 8051.1795158548, -139.763282400212, - [...]
+-4858.25756364256, -563.608700562108, 299.318311936256, -5257.98269977725, 3824.49675662208, -2054.64079700492, 22228.4912213334, -3637.25712537772, 14130.0931068385, 2096.32321800443, -7249.69320728584, 3285.77127360995, 1014.52017598006, 7145.21462327235, -14534.1396043340, 10921.0915840576, -3848.64987950504, 1632.87317043595, -16144.8071013701, -3409.37880533838, -1798.37361081852, -1029.35392471467, 5529.02776616071, -522.429058994222, 691.50184781513, -6624.92568412194, 9641.679868 [...]
+-903.211001998403, 11912.0518217611, -9586.12635023064, 843.79139946222, 13581.8622345536, -16474.7981105873, -1652.16956410509, 4855.72501830274, 13773.8207950382, 6616.30118860051, -60.7452886306957, -3893.89243988952, 15015.7134778990, -8079.74931214431, -5399.71172719258, -3235.17056624766, -1439.32581544137, 6852.88618795017, 2271.55654006866, 375.313840235362, 6543.2028816773, -1902.11175856113, -2054.17817985776, -15435.5252191128, 3640.34559113657, -2771.56154542301, -12985.30913 [...]
+-7725.19110048704, 3739.05569999325, 11333.7027833957, 10787.7274838706, 4975.4968497603, -4607.55154405149, 6824.43040723884, -3463.44400281291, 3207.20986178641, -8445.37474357098, -1030.35047588656, 4635.47096341457, -10768.7343546903, -6020.30500821964, -1758.41686052845, 18633.6977286498, 5459.65211190512, 12903.5237422430, -5651.18039321643, -13930.4268090030, -2849.47217694658, 14777.4570985437, -11511.9029627388, -17116.1045832014, -5642.26086012171, 5930.0903033204, -2134.036412 [...]
+-16288.2500480853, 10300.7243508397, -9120.08174615707, 4882.18848730027, -273.544630125655, -6.8895271526093, -5689.69669105719, 4886.92048156159, 6812.07181578159, 10095.0509623317, 9871.54671936681, 10630.3253713671, -4075.27541571193, 1304.56645073844, -18221.8068293561, -14780.5168187744, 19686.5795148345, -6309.03432257451, 5922.25237352788, -5325.8535880205, -5913.226698536, -5515.62541842354, 7181.10855122063, 5681.09590103562, 1426.22890372025, 78.2935958811895, -12351.718349022 [...]
+4210.39072616834, -727.05521955554, -6746.76293280132, 1256.07924162243, -2188.89026502787, 9954.86274988675, 14635.0243517296, -6684.98868253465, 707.763024145943, -9296.78971760971, -13232.8813613621, -5617.87901063445, 5639.12699866527, 2910.88669295293, 1864.48400717386, -127.824183676458, 2675.46428945388, -11179.4075686930, 8307.88860289315, -7000.55997748883, -13797.3149925660, 12091.8715982539, 7152.04168113805, -6360.82445404873, 3317.77849829166, 4853.28188963312, 4675.03119934 [...]
+8911.01581899635, 2667.33370173237, 410.878691806298, -11065.3952665550, 1577.91164772116, 3838.52509995062, -12802.9833844831, -5045.29846776386, 17498.636714206, -17330.6020881983, -4245.99323448834, -17946.0937361169, -3675.38758366115, 19397.6453215916, -6175.66982972296, 7249.6240826124, 5147.83689128665, -8923.61312716938, -20009.3054070973, -6441.80127326107, 3541.78472266118, -691.100178512376, 6481.01731813218, -1605.11294891242, -1827.83838100867, 3144.77905973400, -128.9166385 [...]
+-1900.4661540648, -9926.47653288393, -9558.84877462995, -6232.65821586954, 3398.79458609835, 3818.21432550055, 1942.85598049095, -2341.78506756088, -4647.58792837851, -16579.2270560055, 3871.23552475233, -1544.14269673562, -4973.43891547513, 13157.8648221489, -3520.50272783437, 5942.21611353121, -3346.96965659778, -4248.322596964, 29682.0996406789, 1375.32751058642, 15289.2612643711, 12350.2031277882, -10748.1582870937, -867.142375042202, 5125.65073654751, -12547.9732956278, -14690.10897 [...]
+1001.73307623378, 10533.0139655860, -2400.68311963508, 3410.02829241471, 151.338340492075, 16845.5200594888, -3558.17127131621, -11489.9849085538, -294.054198950487, -4705.66277610862, -9675.01962228781, -7913.74920663578, 1923.11038635539, -7174.11827572241, 11059.7289255874, -403.881754535471, -11371.8382119265, -4890.38297517686, -5013.6773785453, -3703.30203197616, -9018.76751143035, -13726.2474380229, 8666.78088174359, 573.211052844324, 40208.6740105955, 4794.69166564448, 5869.28220 [...]
+838.585572393502, 2833.37494728189, 9302.9427731619, -5145.85165990458, -3625.31306438216, -3756.42985286864, 32.0096879995805, -2112.29874185755, 635.602004782673, -11491.2682860469, 7204.84636865773, 25249.4394998562, -18582.3946047331, -4322.35726158565, 483.616447587654, 1485.86542828205, 2836.54169447275, -9153.60587738364, -5394.02117625023, -2708.62004942241, -8230.81020517714, 4230.80099127129, -2095.14339396894, 2655.8468701546, 12119.7129993142, 1413.61761128424, -962.085383315 [...]
+18027.0791433502, 16734.2451428960, 2747.45979384569, 10569.6225602906, 5450.14902603186, 15447.1948205204, 8378.8516632961, -18138.0183685605, 10931.1344345712, -8848.45515524127, 8653.43091977448, 6302.73460395391, 26027.7854692087, 7412.3928141127, -4884.36183795454, -5661.50531126112, -8419.30402831023, -13459.1119180241, 6844.67834882002, 9110.43330123092, -4843.94816787268, 164.291327969795, -10535.6579160075, -4891.34607733353, -11302.1374971102, 9510.94402836182, 3884.56068251495 [...]
+-7533.59451961897, 5267.79596776955, 5108.32315124289, -12152.6973527739, 8253.05589771855, -15892.5822376813, 1843.90445846575, 5949.92262371642, -4830.14674407292, -13769.4144205216, -208.427393259905, 4243.76932346060, -17550.0677625888, -17005.7297683765, 14620.7502516308, -23657.2902703592, -1649.62550867519, 11204.3826337223, -6551.30920857909, 3505.20408591813, -6822.01803042853, -4968.53700536247, -16923.7737285409, -13121.1299326394, -12213.4026964282, -7230.56003768395, -8043.6 [...]
+5534.48381825357, 7120.73306061211, -12887.9011907779, -2323.62426322143, 10710.1328317742, -3297.64913543416, 10256.3927061885, -3903.05066039543, 20457.5404855637, 10011.4837988401, -14841.1761358217, 5485.46509182197, -6671.93488996204, -3332.48492543365, 4896.77043265698, -6080.4212585267, 3026.35219294919, -850.185269625868, 2385.20805423211, -17086.0040517020, 1351.21705480055, 9379.99131151264, -10709.8613484103, -7290.36219908767, -4360.6893119014, 16618.2900230703, 2350.80896113 [...]
+-7450.24885659616, 6166.810923311, 1766.05489518809, 16111.2551213474, -2457.33128991304, -12150.099385815, -25400.4189835879, -21600.2460938912, -16169.2788638647, -22758.4998784252, -3178.42308759161, 7586.78796709424, 784.505863907093, -8096.38455276158, -11804.1772133568, -8052.6385035363, 8214.53511253559, -528.08867624986, 11643.8241009372, 5802.78171955026, 14784.0137860387, 1581.58680125328, 11732.1960113063, -7702.43746806807, -29620.9265924431, 13026.2600271486, -1735.307284106 [...]
+-2625.85301008615, -1953.35874055823, -1926.72810051705, -11594.6071041107, -2593.11216910643, -3810.53034242507, -7384.921784361, 13886.1882809643, -928.063717628487, -2326.54558700851, 4788.05270303566, -272.046846726242, -14792.4683676037, -820.047763171293, -3177.76361135033, 2173.36606232269, 327.426967412314, -8118.0587989261, 5020.04494083328, -3462.44620342635, -4954.29336171817, 2778.41167283287, 8806.44315116326, 12349.7653385398, 6966.49086409066, 14781.1592253123, 10902.51856 [...]
+-9967.73122101663, -7828.64862491117, 10084.9343960828, 3346.40386674735, 11866.6308380028, 2702.36181150010, 21940.7045898743, -11664.6592071122, 18728.7731320182, 5791.35286621912, 1411.03091503163, -7100.94392012241, -4233.40574393741, 10935.0840609881, -3506.05022187788, -2591.90986941545, -1686.64717507704, 6202.42215178862, -11162.5151205486, -10824.2374757597, 5793.73079843353, 10043.4998315626, -6119.1960461287, 3630.73115616721, 314.077695099753, -22497.4183239582, -1594.2503146 [...]
+-17237.9607360548, 5664.9874223554, -14178.5776932074, 3569.98398723548, -19978.5032748532, 1368.53394308709, 953.546233958815, 3657.74098670837, 7954.31502156939, 5438.58149199766, -4277.83261830832, 2337.65715542497, 9336.77601196553, -785.866937843072, 16639.6951863728, -2237.57564708140, -7615.42767003986, -14788.0124113975, -3298.86298642779, 324.498623948260, -9079.53832473057, -4736.30898123203, -13743.5450794813, -7509.43437107358, -14829.59700675, -5677.32226528491, 5344.5370760 [...]
+-2656.53869612078, -8008.14093281848, -11021.4635082737, 12619.8163591253, -8739.2031878727, 1492.47597686343, -1113.87045196345, 12819.5983930352, 3949.5912755567, 9729.7897944441, 15866.5627563919, -10824.9252545200, 8015.8650344924, 4600.57419184283, 1847.62884370269, 4332.46339447586, 8833.6884419728, -12856.547682164, -22113.7580377850, -3079.67163663174, -2827.47336087933, -10458.4078610960, 12064.9967402513, 11135.547961078, -3524.57782513385, -27354.8941635594, -18795.3802129895, [...]
+-14523.5758677790, 855.507940719336, -10583.4641584371, 15765.8763194497, 8331.17581089729, 1703.7097069429, 9524.38310014915, 2250.73864351580, -5489.16614678025, -237.950612829157, 7044.72737258789, -2497.24077849413, -1045.26228137862, 1584.37672549825, 14292.8512961734, 9839.60724733054, 7544.06737854716, 4743.06593507913, 393.310129278516, -3050.03076075949, 4630.24991510393, 439.410905565510, 7436.80081413485, 16221.8932207545, 13218.4359429448, 1405.87345235398, -5729.59638017894, [...]
+688.53272468766, 13336.8389914028, 21088.017687755, -15491.9986688994, -3757.07432091213, 8225.4583361434, -4350.7558041764, -1815.00301087382, 4913.10778998604, 7398.54171275473, 1600.24699201764, -4336.77744170351, -5076.92690987644, -2780.84482881594, -3483.53879267111, -6090.06604979202, -15558.8527341067, 14328.426358022, 1422.99098567878, 11451.2813682632, -328.48696137114, -306.105159257017, 25695.8571700392, 1913.12012569696, 9169.35162435798, 8185.86207235801, -5099.64150488558, [...]
+-7037.19707663288, 7305.50395548658, -14146.6217197284, 10224.2763327314, -15549.4068866527, -5859.0616643928, -6574.87884558085, 34670.1174324344, -3852.474950713, 1269.199308689, 22212.4575984439, -151.916370697755, -13728.2737741348, -16497.2910677408, 2823.02507640540, -7197.20230759597, -5517.42662012971, 8826.4162277867, 1305.66426425523, -8212.71151225955, -9914.58337474458, -8569.21670919802, 5036.68909021875, 15678.9132890246, -3901.29210149753, 3987.65935030011, 25342.711962192 [...]
+2403.59867065341, 18639.6804130758, -1932.40079720982, 3116.26237615228, -8768.58358659764, 3812.69484109806, 4002.6360873422, 10157.1489307625, -1403.59521932825, 4131.43685358865, 2077.20633350272, -464.322558499226, 6479.06846142803, 7778.35209893708, -18656.4911354630, 1769.32957756513, 3092.55373934561, 170.468999665248, -10369.6899610292, -19371.5272508873, -22247.6315138823, 4648.08212282637, 13595.7370515114, 8224.18411993973, -3401.06439592028, 12412.3135223116, -599.67702122332 [...]
+-18958.2141227732, 3634.07695744666, -2008.45939712357, -677.316622783087, 14604.6540199727, -7252.02260568763, -11574.7800368021, 4185.96577913752, -6579.58344065099, -10249.2940464040, 6760.87188990219, 4681.18508552352, 14750.1050895861, -27809.1928320112, 10106.6640793052, 893.037998114317, -1052.69676723670, -6701.13064667163, -3755.74743281278, 10263.2489956999, 6986.01112861555, -4498.49764478884, -3461.50238308742, -1460.16029806228, -1543.06318693614, 3562.92542911078, -22422.03 [...]
+-3076.76954269588, -7755.0997542515, 7217.80710293264, -7693.78385117739, 368.820317017754, -18275.7846981407, -12288.6886305348, 412.013709545269, 4342.43079774348, 5035.67953594207, 17014.9113210887, -9680.39758052122, 8066.65281322951, 13082.0866157215, 744.462206156818, -27240.4208232301, 786.485186323202, -5647.31479943059, 8717.80273837661, 4358.56403382393, 7318.55134211118, -7426.81286136258, 6714.06352088856, 770.270134820035, -798.830141888831, 3113.65658728247, -5522.196100068 [...]
+4247.61064475321, 4200.23254163584, -13588.3624502212, 4882.26807020605, 18949.4643246688, -9391.96833777138, -2511.38428168552, 1605.84589871893, -6836.95255033289, 2116.9769195589, 21569.4894043989, -8183.32623470331, 7455.25714647101, 9843.25785685682, 4254.22815921663, 5815.91236104325, -18926.6454000773, -938.390212205728, 8561.60756398697, -9884.77971252642, -4485.52820298832, -1672.13152545155, 9551.64150820122, -1624.98739757199, -11191.6142586399, -19309.8508182225, -21543.92328 [...]
+-19563.4475967394, -4332.47663018654, 15506.1248151767, 151.200930430286, -289.917428413609, 10892.1476696576, 30.9105446448543, -3885.59483073606, -11370.7118917450, -2768.25458640212, -9558.87531209449, 4576.31214548358, 9041.81895680946, 29048.7998207784, 18615.3040097954, 1797.41469087201, -2767.41606026456, -2373.22594958624, 1036.91888475460, 1865.68947626025, 11663.9634097565, -335.520579565181, 11576.5992076790, -2317.66639990548, -9440.8800334066, 13217.6548615280, -5975.1617234 [...]
+-11729.2133277489, -7943.29163238877, -17734.4633529327, -4057.99881064004, 573.788226071968, -1675.55828209092, -51.2122779198588, 907.288441152698, 10429.8187317439, -6900.02766636838, -6290.59664413168, 20897.6387840636, 11114.2356955008, 6546.9695326235, 2334.85705752993, 635.624126162925, 5938.0575362191, -11020.5311255377, -10994.4327375787, 2880.79427940479, 14500.7848311157, 17402.3786007807, -12278.8308326722, -6501.76022667396, 10763.5139493293, -4032.2451446983, -13787.3755354 [...]
+5112.3432758761, -4721.78371750135, -8230.19290298696, -6038.29962868712, -13559.064441024, 6792.28804193334, -2103.33443715548, -7956.08356888965, 8588.05063193528, 10613.4348062935, 4086.30345581116, 7958.83351035243, -5206.191633779, 2586.3234007027, -9657.65043346083, 1141.81723540698, -8235.8546858736, -9433.56585504165, -4054.72798673895, 9201.80965353012, -2533.81703673315, 9732.84499987416, 5996.2725867889, -5059.06195872964, -6067.84470880139, 105.842299599, -4057.87403124288, 8 [...]
+3400.19577317023, 22573.8045320263, -2521.37277766380, -6942.44162775447, -9395.14660378654, 3124.39111322087, -4166.26844377059, -10833.9917215930, -3405.38652711401, 4300.93072581391, 2695.35384231826, 5704.10400616307, -4060.75444980281, -1082.72654115016, 1126.00169023630, -6282.61915112909, 4782.47418002198, 19702.4590271908, 6889.63795695705, -9371.2557331492, -5806.99869871879, -19474.1999048695, 19999.1669283621, -7190.84076993256, 7956.62379526878, -5449.63219172274, 4940.320230 [...]
+13936.0169533533, 13672.3758914504, -9515.20465906686, -5268.36198559546, -1256.29224332997, -7953.35077663703, 14895.8947490339, 4316.65630985209, 5156.95494283347, -6800.90372443571, -2087.69868467642, 7105.79568518737, -7352.9413164235, -2831.49876191673, 1184.48619108833, 4235.54815361776, -5183.29146912715, 6848.43321449221, -26507.3224713277, -18252.0075434010, -2966.08191800469, 20160.5821111229, -14626.4938607076, -4682.83975616787, -7263.94225751509, 5425.70736864502, -3983.3218 [...]
+14196.7133834680, 7030.19457390183, 2910.9950695763, 5633.63220375796, -13421.9421524490, -17031.9381431849, -5284.5055692775, 9685.73521111479, -1289.16285440254, -8698.5023004437, 1212.52237350507, 10708.5024614031, -537.717152258307, 9972.45238324588, 9328.79808622146, 6364.05330501612, 4390.44114728935, -13119.7776685395, -1286.74340676069, 3845.24076959353, 2427.05226131283, -12880.3722278599, 11821.8018179987, -5596.02466734689, 3690.34989344698, -2345.69090089064, -5112.6518366426 [...]
+2847.68392957474, 7367.77441757077, 11886.1659495321, 17574.7537644007, -1300.30016414555, -1048.73876004588, 17698.4731844252, 20014.7479737284, -274.309336315574, -6505.15669723367, -3407.84434316516, -1685.4842844283, 4860.13745590829, 353.981883110447, -998.64000690548, -17883.8013578826, -8854.56074573696, -2035.48628406098, 17160.5665098204, 25483.6862712903, -8555.18540317337, -2897.99693035132, 17497.6216165349, 682.95254478888, -5493.78401732966, -1032.61799124623, 15730.6822224 [...]
+-22068.4286770296, -2020.77963827667, -6021.7459815054, 2955.61899787747, -5654.21301911536, 25273.3082531966, 5243.37336177865, -8297.94239995295, -15707.3280683180, 4909.67735818778, 1070.50380245972, -2861.3971442608, 14843.9793858622, -10555.0259327493, -7960.4975406869, -1392.33378155735, -17010.5255081686, 18033.9863702339, -5849.66306196434, 3272.14111255596, -5055.5892817464, 8588.54924155644, -7784.66395702762, 4118.3872754006, -12321.4322374998, 5226.661655397, 11007.4947680089 [...]
+1483.55238948192, -16679.4821846560, -41633.5552868859, -7191.58283926239, -2139.30130798446, -2379.11042465954, 4280.81526511976, 3301.3057961852, 3383.72511539654, -279.423780607123, 17746.4870612022, 1114.54363224763, 12158.5742104792, -5066.00955519278, 10794.2169068741, -4621.77860829284, -3099.54542503299, 4021.94100049364, -10678.7639634282, 4203.90591255902, -8728.63607849827, 2365.4338604151, 767.255402022892, -9589.83626109072, 11056.8286578936, 9701.95711653044, 7243.830884658 [...]
+-3642.64839950847, -3406.03392112861, 342.766818071154, 8693.19666831113, -9891.07735603942, 15108.5131211381, 7113.57505786009, 14815.7822090205, -5670.20241147183, 4160.83858919103, 8910.44960923614, 8204.57644949869, -5592.15941084115, 2046.32217967152, 597.627820371924, -8894.81699052652, -12544.4750164472, -2322.23662910537, 6691.8930911466, -2924.32659361934, 2996.98251669658, 4097.25834387206, -1791.05448900215, 25663.3561392973, 9351.80535663961, 521.451818742402, 26508.032911466 [...]
+143.176940115590, -5744.32784765104, 5241.46699542152, 17059.7486266068, 4209.99998193199, -5529.92833933652, 3276.97727413213, -1420.4928370215, 16217.5942805966, -4768.89550501905, -15607.5945716369, 8046.2433453901, -782.802724797658, -4618.36792609579, 10348.9799224594, 18409.9033903840, 3889.04592751748, 15582.0052606277, 10664.9746347347, -3389.03144500553, 2799.36924453914, -10495.1599399703, -26571.433719233, -2147.51338224816, -3748.1803673494, 3471.30305902924, 6985.23983155968 [...]
+-22282.3460989572, 6608.77017129977, 5895.51212525638, 1369.53380606037, -19337.867138006, 9503.89905810364, 13215.2732529860, -10104.7214634293, -14670.2225346295, -9526.91090759354, -13146.2929323395, -14920.8375286280, 5845.4540873115, -12505.5821811711, -7142.33814207181, -5881.74691517246, -17876.0646658345, 3141.13275922096, -1860.58686087859, 20023.2003105046, 5119.56658437389, -1163.19568851621, -361.740005163089, -4728.29303789919, -1475.70230582954, -7925.02957876466, 5360.1292 [...]
+8591.0842913526, 2933.44205284652, -10158.4420646456, -7700.01690790063, 12538.6599780388, 162.328757948363, -329.180436199752, 4450.09159102004, 9626.75877267924, 88.8298506607806, 7127.85621819552, 2604.04107346271, 7515.19245206623, 17048.6316765622, -3194.98138336802, 17747.6478868028, -10331.1607040193, 8276.89811565731, 16962.9082304938, 5679.89951209192, -3877.00856569154, -12191.8907598198, -3287.51053629360, 3357.3063747749, 25273.9386218903, 4146.0491050213, -3379.19844051468,  [...]
+11515.5663541675, -13024.598209832, -13163.0734546127, -22133.5484175161, -2608.01789805160, 236.599476959547, 9249.91146685138, 23574.5361134630, 9833.75104200806, 2993.8529075257, 6468.61449917896, -906.162417848453, -11443.2135333660, 11479.9258596231, -5441.82740942895, 8810.27907135201, 27633.2978853128, 30734.1966216811, 7055.32888530586, -21679.9053196503, -6945.80970941801, 5100.6055224392, 7912.22672500646, -4482.13805587412, -6067.14568244413, -6364.03106381051, -7375.804398156 [...]
+-8576.56357391152, -8359.50932422715, -7939.18352501835, 13506.9462809017, 11054.7536230212, 3126.08752006406, -4227.47714715824, 2410.00330438771, 23719.4982618933, 5265.39591178729, -4849.34385481828, -3285.66620315804, 19707.8943366584, 4514.75666968381, -18557.6493796755, 15146.840838977, 10614.6652700596, -15641.2990491720, -768.239946359257, -3847.97270121663, 17778.1649517802, -14685.2124272371, 14404.5622369007, 9504.79489333947, -13052.3535287682, 5690.80505290959, -8500.6902575 [...]
+-1699.16329560849, -8135.19382264239, 6711.86627722624, -2091.26374842557, -10793.9347676643, 3588.66739201806, 1770.32982368048, 2728.74149744371, 14100.9425536421, -837.312688120185, -7214.20468101024, -4941.39475481258, -9459.82622139892, -1152.45201024464, 366.550060592915, -12098.7967869264, -9690.32202972035, -12453.0007488961, 3254.63549259686, 2141.92508686405, -1101.19924937473, 904.655963560694, -3968.10276265667, -583.546778390207, -6032.67587836894, 14825.2823665762, 12741.51 [...]
+849.822133792649, 9172.93475915331, -12880.6900540838, 9489.8990096387, 16077.9401027759, -4159.94530380337, 4651.09336244663, -17878.8822636716, -8447.40567283859, -9375.25403403035, -2331.03777960601, -19931.3273289822, -5416.47859881095, -4231.41313545571, 7720.84368648734, -9516.04796232067, -4471.77248172079, 18393.1505923371, -18427.2737147726, -6603.828660953, -9090.57725036578, 9100.83363634441, -9425.38742330882, 3070.20572330464, 9843.1054964474, -12827.2818721017, 4608.6037028 [...]
+-4757.49627407495, 14336.3219574082, -15504.5620973921, -12011.6419063766, 3215.03046603311, 13860.5405946258, -1419.75106056359, -781.955196771497, 6697.30027454308, 3509.95515657784, -539.80628309876, -2563.31523545461, -7874.65364843936, -2546.22625409907, -6933.71794955887, 9193.08086248688, -18362.5948285325, 2010.89846169852, -13068.2199722233, -18419.8566602490, 3519.76158923534, 4493.35756158354, 4353.63359786069, 12128.1269700414, -3720.17580360729, 16522.5734285539, -13959.7963 [...]
+-5445.41861006391, 13186.8920394167, -4719.63997990591, 13509.3237117153, 9256.89440059502, 3469.64677494053, 7718.84098395003, -3303.89146838470, 8389.90392578316, -18476.8286760456, 10008.3220255902, -7636.84688116955, 1603.54984458004, 963.509846792152, 876.38735332572, 3309.07255465023, -20759.1174907397, 440.182402614221, 9486.09177108667, 1526.51660500513, -504.779828581275, -1154.96430426376, 3967.96420947371, 142.632073254402, -4877.79249486236, -17645.6933271796, -1901.058436733 [...]
+-11379.7676495256, 1892.85931735193, 23841.8660584269, -10338.0930602984, 1644.24351674274, 955.298980833022, -14877.3883775273, 7049.0449536423, 1854.71618582475, -5882.72303205371, 13535.5476515985, -7876.6893415433, 4559.57548703663, 10388.3731540975, 9692.80970293472, 11862.7728096969, 12498.1757569595, 18322.4316285829, 1326.97814315192, -5681.25052682654, 13021.9226891963, -9760.99170752085, -3481.93205009558, 6162.58891885877, -15345.0946577809, -14858.9319891843, -3454.6154575470 [...]
+8945.03813531201, 14503.1443930909, -9000.01548457773, 19079.9663821595, -7560.89268796555, -5709.92280706403, 8469.52527212662, 8016.94428637228, -10047.4506661193, 9625.31051792438, 14137.9609841497, -13611.5288130291, 4260.45514315418, 2019.98282152992, -5795.67970081453, -12240.3161509553, 5907.96716852203, -11720.6289861204, 607.612305279934, 14708.478169931, 4833.65178761256, 17019.8532055693, -4949.75051837928, 3727.47654911244, 6301.76619061919, 4931.72452673474, -3866.5866281023 [...]
+-1641.84685510707, -4295.19596519477, 11762.0189954548, -441.43873156654, -3694.4402228097, -14667.9497793796, 1419.02830215868, 8183.19519022365, 6240.68520503919, 357.914190824477, 10612.7251051452, 13711.2403234053, -8518.91188846256, -6166.80975797373, -370.877804459219, 27735.3190910596, -8162.83526767812, 24086.7837897601, 3097.43373661796, -5401.03928485011, 5690.23154941655, 12909.5456871256, -7277.7964149803, 18134.0318015418, 13462.4029950666, -2022.47402098456, -4741.438940517 [...]
+-10549.1015411526, -10022.0008515093, -6011.75839516074, -10997.1384764401, 6918.88347057633, 3264.49548524093, 1228.80653447091, 5492.42157356194, 1186.09843917270, -20091.5942148667, -7555.4702076392, 1238.04546594540, -11775.0696233261, 21857.1010253295, 5869.24081118782, 10751.7050937736, 6585.33340057813, -2845.22947360713, -2237.55476311167, 5309.687468007, 6570.11033177091, -12656.0163188501, 15806.9058296611, 9332.61961404297, 16774.2275639218, 4310.75294205999, -9374.30794189475 [...]
+-15007.3012729457, -11628.9261649728, 14196.7233953549, 2174.60684256924, 5802.43400905300, 27743.8002118450, -3822.00281729061, 522.639905733962, -5442.4771115128, -27368.9067509532, -19272.5543196102, 18817.7872284669, 4542.11641890594, 78.0578587925735, -8722.96757406969, 13178.1754953106, 8107.31160389544, 7862.7423606399, -312.62346836237, -6368.72567150062, 4010.85460882599, 6580.0289337635, 19939.4006759007, -13544.4688418521, 8591.27449421824, 3137.28638003408, -794.32425972676,  [...]
+8225.35221892574, 22489.3661154416, 14196.4131730574, -4733.66952201166, 11782.0786044463, -13736.2397140875, -364.278747002955, -10984.8888105369, -5683.30205723089, 16044.4100815781, 21506.6044043371, -1831.68685063969, 7898.94282707833, 6593.58912420991, -4660.30867220944, -5879.58118980259, -10216.5308413922, 9909.19642384298, -2827.30619539148, -4254.98986622196, 6354.68296277217, 8296.87371786385, -14219.9400795383, 15831.2429438671, 4187.41296334824, 11166.3709255855, 8069.4725228 [...]
+-34048.8055470088, -7959.23398873176, 12922.3318525696, 13058.3919703329, 11018.2357077483, -13183.1025949168, 8631.80134435621, -1308.24159673994, 7122.76184880749, -998.12580017802, -711.049500527118, -7443.55746621714, 10303.9786175922, 1991.19924346084, -446.772365908808, -10188.2141354635, -676.848341631157, 16896.8096456642, -9327.90855433817, -2609.85619821048, 6689.14676670055, -1745.67105818733, -18384.895065499, 16207.1343263446, 8574.9909805619, 18322.3304967689, 2577.41327267 [...]
+-5852.80725422671, -4333.95103824316, -5673.36993260779, 13502.7217539654, 1552.23269889197, -6839.08625205278, -8578.44546563817, -2518.64406723050, -10074.9816112299, -626.411982367119, -28241.1598926888, 9606.27575753827, 2733.54163548454, -8850.14770083213, -2609.58606957905, -21355.3174405732, 11958.7787870488, 4341.5822366168, 15834.7728303672, 7399.49986984018, -14794.1751190655, 12164.4876235687, -22189.3698028165, -9890.80773395266, 2598.69156661182, 26881.3842508439, -11044.047 [...]
+10044.6603875101, 6899.11899941066, 8585.98822088331, -7795.7625283278, 4242.08665755008, -3023.51174118470, -4587.94346981123, -7167.46875107881, -13719.7091386284, 7833.1119420057, -4073.59108258677, -937.380649314729, 14879.3455304605, -291.876791949091, 8225.44171437025, -8087.69629343038, -3100.09928147545, 1119.87761907548, -230.764098247315, 1785.9504286356, -520.630919815061, 4667.80920333018, -1594.13318225301, 3894.30203501859, 1575.14851416759, 9214.897526954, 8005.12742997528 [...]
+-10539.5928467544, 12742.6182584370, 3954.99066390378, -14214.1250005573, -5140.76265289443, -1640.78578703647, -6079.00645396166, -2041.33654649541, 1491.45493222780, 10234.3380383226, 16915.7206142111, 440.625446764668, 12242.9365542589, -10243.9091061652, -14310.2539688014, 14045.3452799602, 4052.7751981875, 2587.22373914132, 6824.02310970607, -5717.81891606342, 9932.38424378999, 26480.2401562361, -3086.07317520151, -2927.89026918297, -15745.3665005534, 2098.83774870510, 13856.8961157 [...]
+-15988.4283516059, -15547.5877884106, -5357.76638876327, 85.847656084336, 3214.3429613449, -6004.10009284030, 9628.37199828726, 3062.80064305288, -2979.19706927756, 11280.1165035834, -2436.86056982857, 9073.81700926432, -2313.72570885706, -2811.51034497436, 10235.6758145601, 2308.65545842457, -2528.29595471672, 8192.3616439272, -15559.9613943460, 9331.37327377211, -9834.62179987117, 4869.86878151339, -14551.9263343262, -10699.5056674453, 10681.9187003993, -24408.0428433816, 4988.14283565 [...]
+989.565112736864, 1502.7540037069, 3087.50327146527, 1960.72736791784, -3295.54597461055, -12405.2647904264, 2665.19065406948, 6782.25182910017, 1369.55520640429, -499.585337299273, -15567.0819400711, -10610.9143045989, 11946.8763850940, -34486.3492937755, 13562.5112561295, 8507.50436832293, -4821.05306550788, 1388.87851766327, -12848.1860278251, 777.641038141542, -8357.74200805005, 3818.47324458621, -2421.48674747012, -3146.54963135061, 14865.1540765303, 2677.91926614375, -1748.74656830 [...]
+-11707.7897771282, -912.696530023347, 4735.67054685827, -15035.5436481806, 4344.09408480462, -7603.04219472642, -22326.7265620656, 24009.4102961627, -3540.95714070252, -13387.4359945236, -4780.92544930301, 2341.65839901633, -2543.77621951526, -11206.9317126740, 1878.74714257191, 21251.8143058810, -5447.46084175098, 1274.09612041675, -17873.5229464245, -6687.52789115823, 8578.44027700584, -4911.35032816788, 8092.43310356403, -4520.13508432697, -10088.5647333148, 7314.27439921442, 10224.42 [...]
+-14489.2450116322, -5392.3962979411, 8345.13194313535, 4428.95456066441, -7029.70943102492, -6034.29069387284, -1265.53392653974, 1255.62494370936, -590.629988117685, -5319.24285845023, 4607.48762063004, 15560.1048009429, 9231.35274102497, -1773.93705041241, 3195.50251816784, 5576.59833609095, 3793.82227606241, -4566.20014943632, 3119.92547578399, 12300.2269251238, -10764.5545875760, 2936.15263745825, -906.942739942136, 13036.1854684201, 2277.55974539153, -5715.05274090135, 3322.94810970 [...]
+1387.30254420031, -11451.2407620717, -17828.5509426763, 12505.0202965471, -5991.71623000357, 10900.5132147074, 15607.5478208589, 28666.0586018888, 10018.7690941530, 3305.79063204926, 5548.95825118414, -17590.4387974006, -5963.98154882863, -5201.18572422694, 2880.82316826301, -6642.96861867672, -4686.16387419420, -17490.6374761332, 5465.92801882371, 17487.212350151, -1362.40099518246, 8990.33745536987, -17580.3401821212, -9960.73854897817, -9121.22157315097, 11723.4923902048, 15798.806142 [...]
+6436.76403393559, -10693.9363628782, 6374.9394833743, 12028.4149861727, -1125.98944969993, -3061.01526293236, -11993.9051801185, -1423.07930756937, 4368.63834410994, 5302.39944765165, 2023.55816133873, -10743.4811646954, -2022.17831668438, 1115.36826300182, -4068.9774371255, 9697.817950181, 21226.8179566837, -6218.37316227323, 10101.9302344692, 3732.35756819637, 11700.7518061185, 933.488896175193, 1756.68637474638, -8696.45527758014, 2542.33447346017, -8265.83993935097, -6363.43167138293 [...]
+-14655.3965207355, 13303.4058716669, -7944.59074362909, -1207.34644406925, 12335.4693880154, 1824.89930086134, 4568.15244182422, 2805.67396482404, 19166.6116867738, 1310.45164404996, -2233.8765632262, -677.458750130739, -49.1638153479191, 2693.45699405444, 29830.8223495108, -2787.14048257191, 29851.7080308802, -19302.3839501938, 8587.48017130483, -3865.6106557772, 5931.96575427317, -589.015164387591, -5397.15020963715, 15689.1218478654, 9654.83960246356, 5962.19626351533, 676.92239860713 [...]
+658.521142365614, 13613.3274168228, 10655.2871201173, -562.577493486818, 14331.5267541812, -3916.8184372664, 1468.59388573636, -8000.41045914378, 6837.09628259136, 12314.7480175625, 14546.0113895157, 5881.4140303702, -2219.47846934183, 3628.32503525909, 11689.8856866988, 37450.1633111501, -2250.62006352686, 4830.63598949251, -1327.21435937229, -2767.66155616669, -4170.60264918324, 7492.87522392767, -7262.57315215525, -7923.55583422553, -19638.1264950081, 1674.57325366435, -3504.807370538 [...]
+22181.0628328322, -15485.3695469655, 12880.2953218334, -3486.80089525932, -11418.5918058756, -1484.79317145024, -34.8351985496718, -4542.70673019121, 13396.4218199344, 4486.15053511713, -5182.10433236008, -12659.2745482242, -2617.73892629455, -4223.08586508142, -8401.46095393525, 6009.16831387675, -13521.240824417, 7335.89194706219, -8153.50767847918, 9634.24896913746, 4711.92998416972, 12329.0199995545, 6196.5938227065, 8781.19208442631, -3339.45517207623, -12567.4226928571, 8519.780740 [...]
+13395.7509080946, -7583.07077635667, 6446.79905830047, -7279.27001431916, -3477.88737968309, 11369.1883223800, 2606.79013490137, -12895.0458221103, 7764.07735100924, -8740.343056274, 3188.89043826321, 4011.25522709269, 20744.1726984319, 3982.70388188247, 4654.63569653352, 3335.84462449734, -6814.07305465309, 5228.38231269108, 13748.5829032366, -4848.68609859190, -827.721978860784, 16167.6406262684, -10763.5819889283, 10169.4786082630, -9039.50906695482, 6123.4423596899, -843.301711007172 [...]
+24280.8366423929, -3082.868142184, 3570.0352203661, 22004.8798722800, 14459.3540509696, 4097.318870485, 5743.78098886105, 2608.27555435204, 16754.6512994669, -11048.6785500288, 5476.3710707684, 12919.8182233585, 11978.3750947600, 7838.0295916081, -8425.39751231841, 9430.55797859734, 184.680133085501, -4572.05740589285, 5219.87460377308, 45.9072217216194, 4334.97400411587, -7710.0102989912, -6016.08019884292, 2574.64356897308, -1068.91731318401, -6763.91392796221, 12010.0258345660, -12064 [...]
+
+double y13[100] = {
+-12619452.6185382, -86957427.2587282, -15676851.1741423, 10273701.860164, -84129097.0967893, 19807350.2453342, -19080279.1586701, -90874926.6949825, -4361214.14390243, -8250676.263067, -38179908.7336576, 30933653.5570601, -77758406.6939575, -60901292.9008502, -6041839.21451671, 19833991.3776107, -30372373.7123384, 33276826.5067406, 44137658.7958144, -112752968.214791, 20854904.3110437, 345759.685486873, 57536093.374925, 67044737.3087466, 5148369.55447352, -40058879.4428317, -25905926.163 [...]
+
+double lars13[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 251.88100449569302000, 490.46999343233887000, 564.54640976601081000, 654.91040827454924000, 798.23749964278500000, 846.60049293487361000, 858.12640420656953000, 985.25319229330398000, 1001.09104883904260000, 1019.63188407858690000, 1094.68110148057600000, 1129.00309703052220000, 1160.54350067786660000, 1163.17697269469390000, 1166.18718300569890000, 1238.39377367422820000, 1295.74536471973850000, 1302.73651383752710000, 1430. [...]
+0.00000000000000000, -48.47961803221642900, -93.28149253326132900, -286.61679394072490000, -487.50254370756215000, -556.76319787834996000, -626.52823812610450000, -735.83265380523551000, -775.67885325084433000, -783.18073282418072000, -886.76206607235645000, -899.19104655821002000, -914.69307920322410000, -991.82087786159184000, -1016.76137469379990000, -1026.41138400301000000, -1027.26600404547570000, -1028.31135787999390000, -1055.51058686551320000, -1076.45044085966610000, -1079.43378 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -37.90854177843621600, -42.68819315492331200, -169.47543435926329000, -186.73703357386762000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -52.01832764213635600, -95.46100171337856500, -101.86203251869499000, -251.71054795915242000, -270.925019542942780 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -20.33688047501774300, -114.86818348495957000, -152.40236667307204000, -187.27883096736480000, -189.89544270032917000, -192.84558362991010000, -260.70637935393682000, -309.27439379468564000, -315.54078205813806000, -481.39559732174189000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 51.44026278471194800, 63.12268278348698700, 213.01657404936756000, 231.24706764634163000, 254.87849977057061000, 356.39354140549648000, 391.92917996897631000, 429.52265732587051000, 432.27679988507589000, 435.58946107347009000, 513.34047431218062000, 569.84566958741118000, 577.03821924698889000, 758.00504844559634000, 780. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 169.03092672087269000, 235.27024767262296000, 248.82979238998482000, 418.87373907303481000, 440.21165047472687000, 464.18521167735736000, 576.67491995236321000, 629.56465156548938000, 669.29767478211943000, 671.82157360793440000, 674.63176952817639000, 738.25720144874026000, 789.27110706019471000, 795.53981136103414000, 945.10763404674140000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -3.68128920837235810, -95.60879699768383900, -170.69746870263742000, -180.35784110125604000, -386.75159836038142000, -414.4838963479327 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 60.471758 [...]
+0.00000000000000000, 0.00000000000000000, -66.54810518119919000, -320.69727478583303000, -616.73924626728581000, -715.40396823894071000, -826.87713099002383000, -984.64729299634962000, -1049.53909081097870000, -1062.80895408634610000, -1217.85659568958270000, -1236.84205599466800000, -1255.43293280087230000, -1332.54588861883990000, -1371.73510516632970000, -1407.73708168054690000, -1410.34372688032450000, -1412.73794710952730000, -1476.68413791097420000, -1524.44084185127140000, -1530.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 118.25505128880232000, 132.79851176727854000, 144.88112600112939000, 204.03721924083638000, 230.60661452089855000, 258.57122427674079000, 260.40643332849226000, 261.66685972324188000, 304.75624793449731000, 334.99025691243213000, 339.34441923192571000, 461.66223716402436000, 475.09 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 111.61924403253219000, 268.04848043468780000, 320.14931013844893000, 330.45648699870236000, 445.94574495942061000, 460.21666316965326000, 476.61304056887860000, 548.94504700835785000, 584.05297006536671000, 611.38814399524233000, 613.09950845901426000, 615.82993095296501000, 688.57547621800745000, 744.54834830931361000, 752.07888922834263000, 918.23629343998743000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -12.98400990683261800, -165.04860876272070000, -183.85819596704275000, -201.36775050253644000, -282.51901215264093000, -317.62723270958401000, -344.26565178996924000, -346.22782795934177000, -348.13383408414023000, -392.79279242305830000, -423.64134362686030000, -427.37219027133284000, -477.41597660849 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.86180533729137740, 142.77097474644799000, 162.02349086247091000, 211.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 231.02899380569801000, 302.85408857409254000, 367.37186148780131000, 455.79560008519780000, 495.77524900021228000, 502.22127813441972000, 568.50292467158602000, 577.51015923029502000, 586.66247300538384000, 625.97850039299976000, 641.21640434213157000, 659.94528722082680000, 661.62575048093959000, 663.72979731258113000, 709.78377689365334000, 748.64481966470385000, 752.85424851043933000, 814.2171005086212 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 79.73373830823545900, 116.03862248096677000, 145.32793825172160000, 147.42371698982723000, 149.30825165303202000, 190.92964469857876000, 219.54319941874473000, 223.15047042752695000, 283.39763909135371000, 293.098878905 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 197.04641527315695000, 219.70098809495641000, 281.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 53.52760423087145400, 57.15552928139830900, 60.57319111282542000, 147.50313847822579000, 211.16651765772315000, 219.34798866335032000, 435.60901686429258000, 464.603874676262820 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -5.80351066817598320, -11.67133615840044300, -51.37536264910615800, -73.65115473102629600, -93.78366966211899600, -95.63508661085238300, -97.22839378560945500, -135.72006272925705000, -173.45413445387760000, -177.89968371506743000, -278.04286422243371000, -291. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -49.30615423745950900, -88.58240252402303800, -91.51443143893104100, -94.29851563083619200, -156.99226861539415000, -206.03032129816233000, -212.51235232868385000, -363.50079386175145000, -382.96066 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 3.33165611467602000, 6.95589958696181300, 96.96315129318983800, 170.40559797648064000, 179.33275627431917000, 383.93668040716295000, 407.89372090264891000,  [...]
+335.81510157093146000, 389.29957108584199000, 441.89602390449068000, 630.42699202893357000, 838.52189203523585000, 908.89493098566686000, 978.96222023584687000, 1055.81085517770000000, 1086.40907850782920000, 1092.71023352803760000, 1158.36815001041440000, 1166.51180150106980000, 1174.24183322017440000, 1194.97795099115300000, 1210.00877545348430000, 1226.23070464774290000, 1227.73442004455930000, 1228.83572834973530000, 1262.59133228584120000, 1286.65020759410620000, 1289.85341930355210 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -107.69849281627390000, -242.22034331283481000, -444.67225830557766000, -516.68387437293984000, -528.91747909529533000, -667.68927089612839000, -685.46784429023842000, -706.54997276610811000, -803.52440156417561000, -841.92938807488781000, -868.17698672010931000, -870.30378559571739000, -872.46861001403943000, -917.35138251878800000, -952.29873434011915000, -957.53089592272545000, -10 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -23.36018993021867000, -92.410 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq13[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2112.72322599730250000, 1815.61170840388190000, 1721.92305197962220000, 1848.71694864123970000, 1953.26236370287120000, 1801.60167477666480000, 1976.11036558958220000, 1885.20342800239150000, 1865.16818372828830000, 1913.50303442284990000, 1799.15732872836180000, 1830.31156505399280000, 1913.25476701575870000, 2019.44085879803880000, 2114.58329570783420000, 2077.94665555493200000, 2084.98177837017740000, 2030.8463127155187000 [...]
+0.00000000000000000, -1704.59814273677720000, -1640.06027924977230000, -1714.93606115207810000, -1603.23754952569540000, -1638.89793561493960000, -1548.20017287172210000, -1616.68020785624160000, -1562.50293034296990000, -1510.84389502573590000, -1620.03037776884710000, -1577.28772061226230000, -1662.06069096641450000, -1715.80844889432480000, -1526.37572971248910000, -1256.70871337531280000, -1305.14261485723390000, -1357.66027726644510000, -1371.75860340118670000, -1364.611500865742100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -559.58197776366296000, -540.47631693931226000, -620.58324068988975000, -662.5692773094813200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -656.84035951248177000, -693.29167490542227000, -768.51256074329126000, -784.87015014104657000, -800.5900298493896 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1000.79706523769480000, -1002.21995085323440000, -919.34613227846978000, -1019.60513528070850000, -1040.67726858474860000, -1122.31625194474780000, -1049.73029101267530000, -977.63676764621539000, -968.16864356152462000, -1071.505463048314 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1067.20683159401820000, 1196.28759104058210000, 1274.13866174063970000, 1225.86099342586540000, 1394.17212620410010000, 1309.30066043401420000, 1118.03626791272630000, 1326.69043817433020000, 1327.77627569459490000, 1479.27567206230380000, 1417.35888356459510000, 1347.43451862653570000, 1326.12335501241090000, 1401.8833169 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1531.19436207678220000, 1543.26682702552810000, 1564.07100502130560000, 1622.64119203429620000, 1604.35916597015350000, 1619.97320359797570000, 1632.59965885150090000, 1710.27152939829940000, 1617.52568591413660000, 1492.45813359986230000, 1560.01139796985380000, 1478.03613624194830000, 1491.29229212439280000, 1448.40888206876000000, 1477.2685 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1163.50735258633700000, -1164.45865369455580000, -1204.02039631184860000, -1186.46022652276590000, -1121.09863669875310000, -1178.9508 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 562.16424 [...]
+0.00000000000000000, 0.00000000000000000, -2364.11262757762920000, -2198.29620808674830000, -2260.97927402757110000, -2256.95052613562030000, -2299.55865199453410000, -2256.06400971400810000, -2330.92676734561290000, -2349.95180655977670000, -2315.46288077695950000, -2272.64523413279400000, -2151.71663426148510000, -2056.39413204005810000, -2172.49651136036030000, -2266.92371846809460000, -2257.88497060435250000, -2167.06037768102030000, -2220.19256665121610000, -2181.63847244005270000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 955.40088721237271000, 926.25636544368979000, 727.39535175419212000, 759.32697211069649000, 773.50459004958645000, 925.94622230525124000, 857.11800817106314000, 658.77648650165429000, 805.76065371380059000, 751.05161425272649000, 792.81897646341679000, 896.86787771872389000, 845.44 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1586.23065738462970000, 1528.65912832832960000, 1348.95978184614590000, 1330.22632256902280000, 1263.51210125487640000, 1238.80523566524130000, 1267.09785627260380000, 1227.91520512217540000, 1301.42045817563510000, 1263.74166535087370000, 1169.54346416660630000, 1476.07616352698050000, 1534.39483433746070000, 1514.81170152653090000, 1536.36492598949510000, 1509.4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1272.39981557277750000, -1241.53747191244250000, -1210.06614102719640000, -1045.51988563806620000, -1044.27425254970080000, -1035.00079969783680000, -979.99112897245197000, -984.22230113796797000, -948.63965021823799000, -912.04673902394927000, -848.15964337343121000, -815.93005882539467000, -655.4712 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 511.20604813307943000, 633.45049655083778000, 692.73723453997070000, 622 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1514.18191056132290000, 1425.05587861846400000, 1219.72169710293000000, 1168.37279451626360000, 1285.23448972310960000, 1127.46964390560920000, 1037.72097322018840000, 1068.92422200375360000, 1027.90415045698070000, 995.03240399392075000, 952.57566254444873000, 1106.90979998804460000, 1208.02229176324270000, 1326.63026934170220000, 1245.25776786018670000, 1283.42597339071290000, 1191.25519499592410000, 10 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 828.18289064088970000, 857.86386582663306000, 844.31702572433596000, 828.85858139563936000, 743.04927443198778000, 674.86553137807527000, 613.30488758558670000, 598.83826144028342000, 497.75649598743553000, 560.52269349 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 898.13569913829679000, 844.19562979352941000, 791.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1330.96308714819180000, 1236.76221672915220000, 1137.34087860832260000, 1158.24588587356130000, 1087.26177758910510000, 1071.42668246147810000, 1205.06371198856300000, 1263.8744 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -322.42974452593359000, -294.56473622376132000, -424.07135811696969000, -528.81704379615792000, -574.24584059014296000, -697.61660044142377000, -599.21535640934133000, -583.26635027502653000, -692.72662362921369000, -640.89195064170303000, -634.3513543239092800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1056.78905079811280000, -1025.90948670893820000, -1044.85301138378830000, -971.45138943014513000, -885.93848400626996000, -880.86106489579981000, -887.59884103552565000, -900.71624231123371000, -91 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1086.60757235151030000, 1148.80914752643710000, 1143.48600828580470000, 1181.07421541794500000, 1109.07282093011870000, 1111.91550939240690000, 1068.2921110 [...]
+2779.38150298742770000, 2216.38947696706050000, 2257.78159526655960000, 2023.25288713344620000, 1994.29707638125930000, 2008.40966933289020000, 1904.62719249497080000, 1675.10817907908150000, 1690.61773999514300000, 1703.90618018434250000, 1623.17071683187940000, 1610.81075238879660000, 1546.91395158389610000, 1389.62491095635480000, 1517.13673546581660000, 1613.36680483147850000, 1716.66203387315570000, 1575.81364935973990000, 1655.07094255129070000, 1617.73327117800110000, 1623.4594966 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1790.38950510416430000, -2019.40005642447070000, -2076.16420697300190000, -1938.66323853934640000, -1715.54589806286320000, -1650.07629270718370000, -1655.42604011276920000, -1722.93926639613800000, -1713.80943989104820000, -1626.66645894522890000, -1494.57554000041430000, -1561.82473533509280000, -1554.51765340258950000, -1439.20763766504930000, -1433.22214230905390000, -1502.446767 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -667.30583195286738000, -665.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso13[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 251.88100449569302000, 490.46999343233887000, 564.54640976601081000, 654.91040827454924000, 798.23749964278500000, 846.60049293487361000, 858.12640420656953000, 985.25319229330398000, 1001.09104883904260000, 1019.63188407858690000, 1094.68110148057600000, 1129.00309703052220000, 1160.54350067786660000, 1163.17697269469390000, 1166.18718300569890000, 1238.39377367422820000, 1295.74536471973850000, 1302.73651383752710000, 1430. [...]
+0.00000000000000000, -48.47961803221642900, -93.28149253326132900, -286.61679394072490000, -487.50254370756215000, -556.76319787834996000, -626.52823812610450000, -735.83265380523551000, -775.67885325084433000, -783.18073282418072000, -886.76206607235645000, -899.19104655821002000, -914.69307920322410000, -991.82087786159184000, -1016.76137469379990000, -1026.41138400301000000, -1027.26600404547570000, -1028.31135787999390000, -1055.51058686551320000, -1076.45044085966610000, -1079.43378 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -37.90854177843621600, -42.68819315492331200, -169.47543435926329000, -186.73703357386762000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -52.01832764213635600, -95.46100171337856500, -101.86203251869499000, -251.71054795915242000, -270.925019542942780 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -20.33688047501774300, -114.86818348495957000, -152.40236667307204000, -187.27883096736480000, -189.89544270032917000, -192.84558362991010000, -260.70637935393682000, -309.27439379468564000, -315.54078205813806000, -481.39559732174189000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 51.44026278471194800, 63.12268278348698700, 213.01657404936756000, 231.24706764634163000, 254.87849977057061000, 356.39354140549648000, 391.92917996897631000, 429.52265732587051000, 432.27679988507589000, 435.58946107347009000, 513.34047431218062000, 569.84566958741118000, 577.03821924698889000, 758.00504844559634000, 780. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 169.03092672087269000, 235.27024767262296000, 248.82979238998482000, 418.87373907303481000, 440.21165047472687000, 464.18521167735736000, 576.67491995236321000, 629.56465156548938000, 669.29767478211943000, 671.82157360793440000, 674.63176952817639000, 738.25720144874026000, 789.27110706019471000, 795.53981136103414000, 945.10763404674140000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -3.68128920837235810, -95.60879699768383900, -170.69746870263742000, -180.35784110125604000, -386.75159836038142000, -414.4838963479327 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 60.471758 [...]
+0.00000000000000000, 0.00000000000000000, -66.54810518119919000, -320.69727478583303000, -616.73924626728581000, -715.40396823894071000, -826.87713099002383000, -984.64729299634962000, -1049.53909081097870000, -1062.80895408634610000, -1217.85659568958270000, -1236.84205599466800000, -1255.43293280087230000, -1332.54588861883990000, -1371.73510516632970000, -1407.73708168054690000, -1410.34372688032450000, -1412.73794710952730000, -1476.68413791097420000, -1524.44084185127140000, -1530.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 118.25505128880232000, 132.79851176727854000, 144.88112600112939000, 204.03721924083638000, 230.60661452089855000, 258.57122427674079000, 260.40643332849226000, 261.66685972324188000, 304.75624793449731000, 334.99025691243213000, 339.34441923192571000, 461.66223716402436000, 475.09 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 111.61924403253219000, 268.04848043468780000, 320.14931013844893000, 330.45648699870236000, 445.94574495942061000, 460.21666316965326000, 476.61304056887860000, 548.94504700835785000, 584.05297006536671000, 611.38814399524233000, 613.09950845901426000, 615.82993095296501000, 688.57547621800745000, 744.54834830931361000, 752.07888922834263000, 918.23629343998743000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -12.98400990683261800, -165.04860876272070000, -183.85819596704275000, -201.36775050253644000, -282.51901215264093000, -317.62723270958401000, -344.26565178996924000, -346.22782795934177000, -348.13383408414023000, -392.79279242305830000, -423.64134362686030000, -427.37219027133284000, -477.41597660849 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.86180533729137740, 142.77097474644799000, 162.02349086247091000, 211.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 231.02899380569801000, 302.85408857409254000, 367.37186148780131000, 455.79560008519780000, 495.77524900021228000, 502.22127813441972000, 568.50292467158602000, 577.51015923029502000, 586.66247300538384000, 625.97850039299976000, 641.21640434213157000, 659.94528722082680000, 661.62575048093959000, 663.72979731258113000, 709.78377689365334000, 748.64481966470385000, 752.85424851043933000, 814.2171005086212 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 79.73373830823545900, 116.03862248096677000, 145.32793825172160000, 147.42371698982723000, 149.30825165303202000, 190.92964469857876000, 219.54319941874473000, 223.15047042752695000, 283.39763909135371000, 293.098878905 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 197.04641527315695000, 219.70098809495641000, 281.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 53.52760423087145400, 57.15552928139830900, 60.57319111282542000, 147.50313847822579000, 211.16651765772315000, 219.34798866335032000, 435.60901686429258000, 464.603874676262820 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -5.80351066817598320, -11.67133615840044300, -51.37536264910615800, -73.65115473102629600, -93.78366966211899600, -95.63508661085238300, -97.22839378560945500, -135.72006272925705000, -173.45413445387760000, -177.89968371506743000, -278.04286422243371000, -291. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -49.30615423745950900, -88.58240252402303800, -91.51443143893104100, -94.29851563083619200, -156.99226861539415000, -206.03032129816233000, -212.51235232868385000, -363.50079386175145000, -382.96066 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 3.33165611467602000, 6.95589958696181300, 96.96315129318983800, 170.40559797648064000, 179.33275627431917000, 383.93668040716295000, 407.89372090264891000,  [...]
+335.81510157093146000, 389.29957108584199000, 441.89602390449068000, 630.42699202893357000, 838.52189203523585000, 908.89493098566686000, 978.96222023584687000, 1055.81085517770000000, 1086.40907850782920000, 1092.71023352803760000, 1158.36815001041440000, 1166.51180150106980000, 1174.24183322017440000, 1194.97795099115300000, 1210.00877545348430000, 1226.23070464774290000, 1227.73442004455930000, 1228.83572834973530000, 1262.59133228584120000, 1286.65020759410620000, 1289.85341930355210 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -107.69849281627390000, -242.22034331283481000, -444.67225830557766000, -516.68387437293984000, -528.91747909529533000, -667.68927089612839000, -685.46784429023842000, -706.54997276610811000, -803.52440156417561000, -841.92938807488781000, -868.17698672010931000, -870.30378559571739000, -872.46861001403943000, -917.35138251878800000, -952.29873434011915000, -957.53089592272545000, -10 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -23.36018993021867000, -92.410 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq13[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2112.72322599730250000, 1815.61170840388190000, 1721.92305197962220000, 1848.71694864123970000, 1953.26236370287120000, 1801.60167477666480000, 1976.11036558958220000, 1885.20342800239150000, 1865.16818372828830000, 1913.50303442284990000, 1799.15732872836180000, 1830.31156505399280000, 1913.25476701575870000, 2019.44085879803880000, 2114.58329570783420000, 2077.94665555493200000, 2084.98177837017740000, 2030.8463127155187000 [...]
+0.00000000000000000, -1704.59814273677720000, -1640.06027924977230000, -1714.93606115207810000, -1603.23754952569540000, -1638.89793561493960000, -1548.20017287172210000, -1616.68020785624160000, -1562.50293034296990000, -1510.84389502573590000, -1620.03037776884710000, -1577.28772061226230000, -1662.06069096641450000, -1715.80844889432480000, -1526.37572971248910000, -1256.70871337531280000, -1305.14261485723390000, -1357.66027726644510000, -1371.75860340118670000, -1364.611500865742100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -559.58197776366296000, -540.47631693931226000, -620.58324068988975000, -662.5692773094813200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -656.84035951248177000, -693.29167490542227000, -768.51256074329126000, -784.87015014104657000, -800.5900298493896 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1000.79706523769480000, -1002.21995085323440000, -919.34613227846978000, -1019.60513528070850000, -1040.67726858474860000, -1122.31625194474780000, -1049.73029101267530000, -977.63676764621539000, -968.16864356152462000, -1071.505463048314 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1067.20683159401820000, 1196.28759104058210000, 1274.13866174063970000, 1225.86099342586540000, 1394.17212620410010000, 1309.30066043401420000, 1118.03626791272630000, 1326.69043817433020000, 1327.77627569459490000, 1479.27567206230380000, 1417.35888356459510000, 1347.43451862653570000, 1326.12335501241090000, 1401.8833169 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1531.19436207678220000, 1543.26682702552810000, 1564.07100502130560000, 1622.64119203429620000, 1604.35916597015350000, 1619.97320359797570000, 1632.59965885150090000, 1710.27152939829940000, 1617.52568591413660000, 1492.45813359986230000, 1560.01139796985380000, 1478.03613624194830000, 1491.29229212439280000, 1448.40888206876000000, 1477.2685 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1163.50735258633700000, -1164.45865369455580000, -1204.02039631184860000, -1186.46022652276590000, -1121.09863669875310000, -1178.9508 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 562.16424 [...]
+0.00000000000000000, 0.00000000000000000, -2364.11262757762920000, -2198.29620808674830000, -2260.97927402757110000, -2256.95052613562030000, -2299.55865199453410000, -2256.06400971400810000, -2330.92676734561290000, -2349.95180655977670000, -2315.46288077695950000, -2272.64523413279400000, -2151.71663426148510000, -2056.39413204005810000, -2172.49651136036030000, -2266.92371846809460000, -2257.88497060435250000, -2167.06037768102030000, -2220.19256665121610000, -2181.63847244005270000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 955.40088721237271000, 926.25636544368979000, 727.39535175419212000, 759.32697211069649000, 773.50459004958645000, 925.94622230525124000, 857.11800817106314000, 658.77648650165429000, 805.76065371380059000, 751.05161425272649000, 792.81897646341679000, 896.86787771872389000, 845.44 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1586.23065738462970000, 1528.65912832832960000, 1348.95978184614590000, 1330.22632256902280000, 1263.51210125487640000, 1238.80523566524130000, 1267.09785627260380000, 1227.91520512217540000, 1301.42045817563510000, 1263.74166535087370000, 1169.54346416660630000, 1476.07616352698050000, 1534.39483433746070000, 1514.81170152653090000, 1536.36492598949510000, 1509.4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1272.39981557277750000, -1241.53747191244250000, -1210.06614102719640000, -1045.51988563806620000, -1044.27425254970080000, -1035.00079969783680000, -979.99112897245197000, -984.22230113796797000, -948.63965021823799000, -912.04673902394927000, -848.15964337343121000, -815.93005882539467000, -655.4712 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 511.20604813307943000, 633.45049655083778000, 692.73723453997070000, 622 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1514.18191056132290000, 1425.05587861846400000, 1219.72169710293000000, 1168.37279451626360000, 1285.23448972310960000, 1127.46964390560920000, 1037.72097322018840000, 1068.92422200375360000, 1027.90415045698070000, 995.03240399392075000, 952.57566254444873000, 1106.90979998804460000, 1208.02229176324270000, 1326.63026934170220000, 1245.25776786018670000, 1283.42597339071290000, 1191.25519499592410000, 10 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 828.18289064088970000, 857.86386582663306000, 844.31702572433596000, 828.85858139563936000, 743.04927443198778000, 674.86553137807527000, 613.30488758558670000, 598.83826144028342000, 497.75649598743553000, 560.52269349 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 898.13569913829679000, 844.19562979352941000, 791.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1330.96308714819180000, 1236.76221672915220000, 1137.34087860832260000, 1158.24588587356130000, 1087.26177758910510000, 1071.42668246147810000, 1205.06371198856300000, 1263.8744 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -322.42974452593359000, -294.56473622376132000, -424.07135811696969000, -528.81704379615792000, -574.24584059014296000, -697.61660044142377000, -599.21535640934133000, -583.26635027502653000, -692.72662362921369000, -640.89195064170303000, -634.3513543239092800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1056.78905079811280000, -1025.90948670893820000, -1044.85301138378830000, -971.45138943014513000, -885.93848400626996000, -880.86106489579981000, -887.59884103552565000, -900.71624231123371000, -91 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1086.60757235151030000, 1148.80914752643710000, 1143.48600828580470000, 1181.07421541794500000, 1109.07282093011870000, 1111.91550939240690000, 1068.2921110 [...]
+2779.38150298742770000, 2216.38947696706050000, 2257.78159526655960000, 2023.25288713344620000, 1994.29707638125930000, 2008.40966933289020000, 1904.62719249497080000, 1675.10817907908150000, 1690.61773999514300000, 1703.90618018434250000, 1623.17071683187940000, 1610.81075238879660000, 1546.91395158389610000, 1389.62491095635480000, 1517.13673546581660000, 1613.36680483147850000, 1716.66203387315570000, 1575.81364935973990000, 1655.07094255129070000, 1617.73327117800110000, 1623.4594966 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1790.38950510416430000, -2019.40005642447070000, -2076.16420697300190000, -1938.66323853934640000, -1715.54589806286320000, -1650.07629270718370000, -1655.42604011276920000, -1722.93926639613800000, -1713.80943989104820000, -1626.66645894522890000, -1494.57554000041430000, -1561.82473533509280000, -1554.51765340258950000, -1439.20763766504930000, -1433.22214230905390000, -1502.446767 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -667.30583195286738000, -665.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso13[1250] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 20.95561917369812500, 107.84263573304527000, 130.11310022790533000, 200.76869196983390000, 219.07776555980541000, 304.06606606001901000, 473.63142778840188000, 486.66785471076560000, 671.57745670977931000, 679.51278857495026000, 755.48242601339689000, 839.32716490656333000, 981.621 [...]
+0.00000000000000000, 255.72351189367211000, 600.67294459018092000, 728.13371171890071000, 850.98589893596829000, 961.99067454817339000, 1039.15958179100270000, 1085.82253215119930000, 1186.15209464301550000, 1287.60116729653670000, 1302.99592696981630000, 1358.46996190499340000, 1377.80793400127500000, 1441.35031346082840000, 1456.32246348567360000, 1533.84395173880190000, 1688.30756053873820000, 1700.99594937499680000, 1880.08338366120480000, 1887.30291205170150000, 1967.358777378598500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 146.51729005802372000, 250.090 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 102.77802012722802000, 315.93500442939427000, 333.03363751458244000, 579.03867145825632000, 587.93889905048070000, 675.08350881342290000, 759.44034733760873000, 884.775957100698 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 115.22746409148407000, 210.62860699492674000, 273.71205729237840000, 411.68928655729678000, 517.01559957818449000, 535.59933784922475000, 619.03663502239999000, 643.73452893714875000, 723.42559705314852000, 744.32624420524473000, 835.67066210820985000, 1022.22641422469940000, 1029.16816052021020000, 1117.12584105222000000, 1120.86105006417160000, 1166.02395651668460000, 1205.209945455 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 68.53539922557162400, 159.98652181328100000, 214.62 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 122.70364282969967000, 251.91977219927068000, 355.76385062509837000, 429.10766529647549000, 553.65973113327561000, 646.74642207381373000, 665.05038947892626000, 746.40757678186969000, 769.77937233098544000, 836.18320587985829000, 852.77507163725488000, 929.68694049710825000, 1081.67395333555310000, 1094.07578860066790000, 1287.07958885592260000, 1296.11196098741200000, 1392.86065288507830000, 1514.6250275 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 23.03978207801902300, 95.87033570510156700, 114.66256949429531000, 203.22162807505322000, 376.13613182442032000, 390.28531056635433000, 590.83868992671012000, 598.13701550672681000, 674.93451819426787000, 747.85908624294211000, 814.61640007 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 94.12420886340913700, 109.80426281628490000, 169.13615049108296000, 182.68718722646130000, 211.23947064711055000, 217.14227581543386000, 231.21953471347695000, 260.50812470291498000, 265.72235763446633000, 344.13206367351273000, 346.89846453417033000, 379.06663983539266000, 417.12680836112440000, 476.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 97.55981956998289200, 207.86398336774008000, 348.79353493873589000, 430. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 79.28470674935610400, 136.78548902184878000, 271.09548791730793000, 386.18848950327771000, 405.19971714945711000, 493.24457640059694000, 515.59910418922675000, 580.95571028614813000, 598.45151414988823000, 656.28729577798458000, 765.45169495574555000, 770.75213242563234000, 831.87473379585617000, 834.32981649680141000, 868.77024126582353000, 905.23176407783251000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 121.94797660173181000, 227.16556877461971000, 317.49195243372526000, 382.66625989099532000, 426.85460205417428000, 502.07434576712217000, 570.41582554885713000, 580.74171306929725000, 622.44135561949565000, 633.97125017952135000, 663.08878894813006000, 670.56913650147067000, 697.80614116580659000, 756.16168305797316000, 760.12644623598214000, 807.83992166276244000, 810.22157946821733000, 833.73600771380620000, 869.14815293024 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 5.22288763648966550, 74.61674856066049700, 177.34730474917458000, 338.79404295799173000, 454. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 10.82964594209051000, 63.15213100561913300, 169.40271717212491000, 178.08882844179192000, 272.19559165587663000, 276.29132107726099000, 310.95757179561957000, 348.35640541846772000, 394.562066928769 [...]
+0.00000000000000000, 0.00000000000000000, 317.99117481730525000, 409.44707261898071000, 488.49308973080815000, 581.19283350631417000, 645.01690995427430000, 687.45208778823019000, 780.76086856710617000, 838.14690309040009000, 845.04175443718395000, 863.72453878626743000, 869.97567174282312000, 897.43825349579186000, 903.12284519962111000, 935.62469998789948000, 1000.61565258556900000, 1004.33713159943260000, 1041.54615638935890000, 1043.55647972318120000, 1067.07339312585010000, 1090.530 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 50.21616447747320700, 145.36572501423632000, 216.84936331831929000, 225.84120520618524000, 259.67392618243446000, 272.82183871841147000, 311.39371319306565000, 321.27378979095067000, 361.07207085947778000, 432.29877396856142000, 440.73268945944392000, 555.77118602201767000, 560.68653863778889000, 595.74039329854202000, 632.27275543425742000, 6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 84.757262 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 63.54484366362781600, 81.77639414451648700, 141.41550623544018000, 158.59765332524185000, 220.44690300095246000, 352.51629089361171000, 361.86696055290520000, 501.21247990901804000, 507.03759903453090000, 565.36553395442297000, 634.69496544702542000, 722.200165 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 195.35726035153274000, 345.18575531368577000, 370.43132991564045000, 484.18575383943829000, 515.99606403414089000, 611.45158698584373000, 636.42067105116826000, 732.77038933307745000, 923.53800971758017000, 937.53309571951161000, 1135.34077327428780000, 1143.22145189696900000, 1221.37597552609780000, 1308.42889939075670000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 64.49540475252092600, 80.11220311522420400, 166.22414357663732000, 339.85164492824538000, 354.30918748094024000, 535.47818355166623000, 542.80005912064837000, 609.68039943913766000, 686.58370518292020000, 775.9584385136 [...]
+470.19160995898073000, 709.38957512699221000, 1074.23754392140650000, 1186.40475285542900000, 1270.91632390979770000, 1357.79309172608300000, 1420.97309542212790000, 1457.44016602266860000, 1524.84355868322970000, 1586.07226981606050000, 1599.76997842314340000, 1652.72410170130230000, 1670.41914541087270000, 1732.53797267203820000, 1748.39685997574130000, 1827.89767042777730000, 1991.59658589659560000, 2004.04299826917960000, 2186.70383891609120000, 2194.11305272483700000, 2272.067261848 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 175.55474084215817000, 182.92083215362695000, 267.16821791319194000, 373.23419065400952000, 526.47424466309849000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 18.43272426895842400, 263.56727050559664000, 273.26496059647343000, 371.01938180901442000, 489.56343563029685000, 670.61632455845518000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 51.68861536207066400, 52.67283854202755600, 65.74700187859762900, 65.46630693564817700, 66.90972042017791900, 68.19771766021861500, 56.26480743272814100, 35 [...]
+
+double nnlassolsq13[1250] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1025.82804879969400000, 1010.87267497446690000, 914.85240355061819000, 936.91540174088550000, 935.40807059778206000, 1018.33397214771130000, 1002.44666503926440000, 1041.65252571029960000, 1065.14417065095020000, 1083.95297653537300000, 1072.79123655148580000, 1060.8511323958137000 [...]
+0.00000000000000000, 2233.23025341627320000, 1939.24823761553060000, 2070.64106428004150000, 2163.87662810258420000, 1999.35034194924650000, 1899.75982110212840000, 1783.83929055858360000, 1909.98574281829040000, 2076.63464574734960000, 2041.21174527468630000, 1935.02008329368570000, 2059.21566817820210000, 2103.38586389576490000, 2042.09785739998050000, 2185.35846333001380000, 2170.02569625684280000, 2241.16399892889100000, 2261.25803472423790000, 2255.26073270112060000, 2301.7348815696 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 278.73735499907053000, 290.665 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 966.55622013876200000, 980.69731246486026000, 1060.95389617425390000, 1102.64259345855540000, 1041.55694319162310000, 1039.06777148796300000, 982.31731972031776000, 997.88125993 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1192.04891763864500000, 1274.55771195042870000, 1217.35803650891940000, 1407.13428545369380000, 1336.20482390063810000, 1426.73436340802370000, 1486.21321357399620000, 1514.00861184508950000, 1553.71115755070830000, 1562.05013811939440000, 1603.35734044325910000, 1604.02875469339690000, 1324.69106774928260000, 1304.33740236992300000, 1311.23350839772570000, 1354.65968797586310000, 130 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 249.61096521013826000, 242.51380144485231000, 236.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1434.00691512262940000, 1459.46782809511180000, 1513.84994951325830000, 1526.23528733848120000, 1452.24808299389270000, 1370.74037913182680000, 1542.76972793951860000, 1591.96525561605040000, 1593.32602807528110000, 1528.03168351675280000, 1501.92076438573960000, 1576.07802256940520000, 1555.66844981742970000, 1622.04472559465670000, 1697.87421835830950000, 1756.46501800596390000, 1796.95909776759070000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 834.88735448876150000, 854.67754546151298000, 849.89619540158355000, 947.49928706196567000, 915.39617522178003000, 992.64187312529612000, 1017.70205251765490000, 970.11089379325483000, 995.70114354276495000, 940.53115911045973000, 874.85950 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 826.18759774790988000, 861.70062921280999000, 785.78152487385250000, 660.18199338443731000, 508.72009430861431000, 448.08559504054080000, 349.52916294912228000, 351.84902420111365000, 487.70184367505220000, 511.02145185707121000, 487.89366209722976000, 513.42617854297021000, 517.68457318251114000, 530. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 505.04617001023621000, 499.29569772012167000, 475.97111550585100000, 462 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 963.48068723019253000, 996.92204999615285000, 1240.08303328657170000, 1281.33941608565830000, 1316.83388823455430000, 1408.30825165357150000, 1303.30052671709270000, 1261.89333112983040000, 1282.96318302330220000, 1142.35705358354880000, 1105.89739130619730000, 996.40150421265332000, 961.96977001221990000, 959.45805636119189000, 1012.62047652250030000, 1001.565789 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1406.39070282858420000, 1351.59977249734380000, 1161.60831403509930000, 1109.50076615355920000, 1087.85445564355700000, 1044.75169982209810000, 1101.95065484023800000, 1075.89289875857120000, 1055.83211225502100000, 1040.24752818473210000, 966.45869687323068000, 963.23275043819490000, 926.71433411934231000, 938.15227014521361000, 928.91370681301362000, 909.39460314723658000, 931.60757149248911000, 931.95070912180609000, 962.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 271.41788657148567000, 364.45995712322667000, 448.76899070914806000, 484.48673357516299000, 4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 434.53232773152195000, 502.88644299527016000, 500.76124676195150000, 547.87256089932305000, 472.49503071910465000, 485.03842896951937000, 455.75103339624980000, 447.16687478089204000, 436.2589585592 [...]
+0.00000000000000000, 0.00000000000000000, 1551.95502477396460000, 1372.72556214695080000, 1333.23818865442100000, 1447.48867384987620000, 1356.79341978725460000, 1322.22689404147970000, 1453.94266584116210000, 1284.47431890676740000, 1175.66648889738050000, 1057.89757121359390000, 1090.24542509428310000, 1183.56548986665940000, 1125.52870802005420000, 1208.78031819597960000, 1203.29977195275840000, 1162.76733785461580000, 1120.74287444624450000, 1146.01666170509790000, 1165.2984744996315 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 801.38436275147217000, 831.82793829476509000, 772.82274294716433000, 657.02168857808749000, 611.30256485203643000, 736.11184894751443000, 713.26648481927384000, 707.82520367778318000, 695.54910731504106000, 654.43002482840097000, 799.77998376948619000, 800.62230559290060000, 811.20739518061805000, 742.15279307063224000, 728.79394339298540000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 117.96153 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 723.97611336847638000, 724.19740095231998000, 762.78368187478372000, 830.83770990497771000, 740.24708489603177000, 764.39466027370963000, 759.94216592884186000, 797.79933944757090000, 803.92654004462133000, 808.98875336980961000, 817.86842308739733000, 801.1665 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1604.77393621225930000, 1510.49654090157740000, 1581.01745849976510000, 1666.45286309883290000, 1636.88874529957430000, 1605.98390096081580000, 1613.31944843276070000, 1542.52315676470080000, 1518.47569867205290000, 1533.32964692541100000, 1556.36010815979190000, 1544.87612716041370000, 1547.81058502417550000, 1538.4291275 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 736.46033821929439000, 691.10903372489543000, 889.93546667065527000, 881.33527923087695000, 969.79336461421667000, 921.08328832041104000, 915.97421007698756000, 889.02517388323122000, 889.76789570331107000, 856.61194391 [...]
+2779.38150298742770000, 2559.10446905863550000, 2490.02904971108820000, 2367.82948536244340000, 2174.07043665295030000, 2169.67217052918520000, 2125.56680088173740000, 2002.93988716579110000, 2011.12937910494380000, 2062.28660734081720000, 2256.60810924699260000, 2203.08439620178840000, 2293.93538487314030000, 2379.74181281774460000, 2368.86525910035520000, 2496.04701662758410000, 2502.11642284311760000, 2533.90966471542560000, 2575.48422696495120000, 2571.73857316471050000, 2597.6652008 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 549.21030941782692000, 558.34852757488852000, 619.05140003276836000, 653.46829248705330000, 664.76106313092134000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 803.14769831478964000, 785.31842238103229000, 767.52728884902922000, 779.31854139001018000, 802.76554552308608000, 834.0019886146561700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 212.88738330175360000, 94.57302952008208800, 93.57441292851953600, 51.16012322274183100, 72.93854761132870100, 71.60070110909754200, 45.49631611958930200, 2 [...]
+
+
+
+// Data from file x67.txt and y67.txt
+double x14[5000] = {
+-5669.61167472863, 3995.96638633374, -21959.6421860465, -24745.3774648629, -14032.6833879266, 17799.0871746831, 14581.8471208121, 2583.23258042496, -7183.65504715803, -13613.3167376150, -1543.75168422692, -800.126007039888, -8463.69564766032, 18805.0410137793, -7931.0540534458, -15384.089555884, -209.826338904239, -21232.9377613343, 12294.3235318240, -6555.30351274597, -4022.69872389235, 7034.48332606044, 2981.05741948438, 7087.38718613425, 8978.47294900071, 779.432308304863, -768.594688 [...]
+362.853404306775, -2898.44740326101, -12784.1616412391, 5485.60432662089, 7163.35527316159, 10828.0721222803, 7273.69569030173, 8612.66851685142, 11464.6736388691, 1419.01145160327, -4719.28887759551, 3390.3001073317, -3191.61885841047, 5746.81296987372, 13280.2315818461, -2173.51021032581, -2109.78454548470, 17235.7611948459, -1642.65000248053, -9571.7125794569, 21575.8268565259, -8748.28998055793, -14523.7039374816, -1937.57363607369, -9719.60702793733, 4420.26317183455, -6534.20535825 [...]
+4021.06557911069, 8141.05187462345, 16784.2510595316, 5596.79020895121, -10924.1118983401, 328.788889107691, 6171.60592182659, 5115.70436900303, 15185.6830014015, -9712.73791763056, -6874.3101066479, 3557.38986071664, 4719.04434053017, -2270.85660430957, 8265.40537408997, -18546.1660089382, 2060.92308586895, 2595.27227557566, 7876.17148161002, -563.1223907715, -6067.12707151236, 713.572836386662, 5867.01901364399, 16705.5393128311, -7494.33093951841, -3023.92737210017, 28561.6717000736,  [...]
+3251.99028865209, 12710.5137659353, -1546.03220957852, 25538.0323291196, 445.651966341096, -3269.17867737211, 6414.25962262174, -10950.3892333799, 521.95168685713, -1101.04841157043, 9148.0062200502, -610.135732535438, -7005.73384346445, -5790.08973629106, 4787.77295963491, 1169.75910888796, 14940.0845553691, 5511.30476878468, -7208.97699456095, -6802.73739619592, 843.394006887307, 12807.0250500724, -1462.73927882961, -4415.75535127923, -2464.62333461846, 140.589886426743, 74.91850401936 [...]
+257.666008154907, 8417.35020554205, 12826.9359092386, 6743.38945896814, -13481.8192926829, 6865.02653598434, 6736.26568734053, -2038.33354790688, -315.558322662295, -2939.4886882908, -13934.2033618346, 3477.41702990873, -9995.00658040142, -21334.9466305730, -17783.9053358773, -11007.8882075062, -2149.67924390191, -2373.74729855364, -22203.0286399151, -5945.8353147603, 16608.3285155648, -4780.93022373753, 4302.45263791077, -16061.4277172414, 2387.16351979683, -17975.7913796987, -737.09000 [...]
+-9968.8780363303, -9842.97002286435, 5178.03508165137, 6196.20523585175, -7478.22279830657, -10889.2997778176, -11657.6052489419, 2721.97242230886, -10145.0333436451, 17063.7113769157, 12696.1288489399, 6865.82433093595, -6485.34468575107, -16745.3956656193, 2146.80086990420, 2372.30437270444, 9625.84226439933, 6365.85912164538, 3514.41997592622, 7051.44865822544, -3399.1168808282, -13721.9331314883, -5718.53180631898, -10398.6896231641, -1759.45624844263, -9.7870915534974, 3806.40840031 [...]
+-12057.964114854, -10160.0369294996, 19369.5945106433, 7796.67319999287, 5259.77463051084, 9749.77001057894, -10489.8431692558, -8755.2441147155, -24076.2944786803, 3776.50467682249, -5584.30080628222, -8848.99714043256, -12447.5521054836, -8326.16491769504, 1625.74787890763, 8138.20428253024, -22944.191600602, 1102.65949155855, -624.603546173386, 5730.62718246464, 3306.62216555791, 1403.41105756443, 14895.2400644265, 12335.1776258229, 4001.67468108765, 9013.86034093788, 20916.6197280209 [...]
+3394.07194958286, 1110.10900828441, -2282.10213099836, 5773.09296201754, 4058.44840662294, 21435.9872457515, 5880.52056444993, -13315.9748639762, 16004.9112816383, 9594.47260318018, -7177.76296527932, 7676.11235160164, 3567.93840807023, 19949.8905115633, 2082.98505502702, 13181.4616626868, 15332.6239647325, -3983.68646003973, 4504.75418878121, 10012.7713244131, -3959.62635398832, -6540.75573682473, -1372.03524920166, -8580.19231381271, 16074.2473144057, -20155.9161615515, -4861.006108714 [...]
+-12908.0184912944, -16280.1460513541, 4169.89486977847, 13335.3725305472, -3047.95848577162, 6187.59514443277, 5330.42869265816, 2689.83140747208, -8607.51799777089, -1672.33287481736, -2745.20991447347, 6117.22952880311, -3072.64380698863, -5167.29904469896, 9632.7067876414, -12019.6588792543, 1574.99442584644, 19926.7042410071, 6146.80339023304, 8564.05998713159, 14649.6820657518, -7274.20388662668, -8067.64546532438, 14246.1047136707, 7592.16011050706, 4523.82479835194, 6005.297129971 [...]
+791.166841374753, -348.576084833322, -6463.86051574942, 7713.54799370034, -7317.4498487877, -4890.70222792781, -8572.36509393936, -16664.4534332525, 22869.7073205879, 14896.1714194399, 1436.80711679418, -11742.6291789670, 2394.92155623447, -4254.23499573943, 14741.1066177638, -1578.86550150279, -16710.2953751476, 4208.12103213135, -174.570252763467, 24544.5086441735, 3922.7567792059, -8839.4464862918, 2105.53556348799, 4512.31948326277, -15237.1046836924, 11638.5130841075, 1522.934582461 [...]
+-4751.7262939663, 5955.48837952671, -16424.4703868000, -1428.02734463437, 7142.73726629357, 5109.88269463658, 12494.7738360056, -6579.32249896475, -415.951534751199, -4123.04570317356, 9628.95498749822, -635.178379683511, 19865.6790872698, -300.695227223338, 18261.7360176775, -15488.2829379725, 11282.2089946756, 3490.42436387508, -13637.2214931359, -3355.29058884130, -5020.87737711553, -6294.71730158644, 12705.9375664124, -21824.7269494937, 10707.9208765542, 14241.5953669586, -5979.68100 [...]
+1401.28788378708, -5672.08714609817, -4698.54974006342, 1025.75916838551, 5399.39362366229, -127.964550756023, -1457.64822643706, -1397.68138255733, -5552.81293166373, 11942.8409813694, 2469.37273441546, 13371.1942201707, -10767.3434461685, -24166.9098480463, 175.278862271412, -22667.1756948651, -2742.63324628971, -515.098522176899, -6698.98384128885, 5901.34460936908, 5120.5282102524, -7647.90130247152, 17032.6821790311, 15700.4621856744, -1546.95536113780, 16799.5655972844, -7322.95688 [...]
+136.929098503895, 9159.13596629383, -3117.14998351015, -2085.60834693734, -5479.04911765035, 1891.01484863396, 15483.7672209756, 11740.4520387076, -8522.72066373916, 11503.6098342139, -17422.0124425507, -963.256961692898, -21681.0530610862, -14258.6569390186, -4505.34313017303, -8672.97649327481, 3337.35957212332, 5484.47610548642, 2056.83902093154, 4218.81158699493, 2691.80976372104, 27233.6863391126, -7474.80534375167, 2496.01992398795, 6921.72203385945, 9322.60643320838, 4075.30692961 [...]
+-1335.54184716636, 5037.95984608238, 3973.98276608302, 8305.79097453353, 400.568909084402, 21271.5433425223, -6607.26590194388, -17809.7471880722, 1389.29770386542, -14698.3105895662, -6149.76738548315, 584.558486252549, 7415.22216872647, -3157.82686948449, 5745.57049068424, 612.300710893278, 16396.0600928146, 10792.4781743878, 18238.3142978926, -8788.67833139421, 13768.1799803458, -9986.32253904917, 18711.8007375966, -2920.60559778312, 6309.34601108477, 5628.62884412272, 9094.4770285746 [...]
+-7013.78299827649, 12914.1797164003, 1161.11440682938, 5638.05250195847, -7394.18906582794, 7090.55897381056, -4137.69052496378, -7215.929892465, -640.527388989833, -8879.64967394373, -328.544077035558, 17900.9617845817, -8633.36123504588, 14581.1488127613, -453.176721517637, -11614.8766484463, -3727.98825223521, -15116.0148639061, 22.2655405229790, 11091.0163849139, -28335.16769708, -10452.5798186649, -251.440637251237, 7894.50083277788, -1911.28641356401, -26944.1669397661, -1837.08519 [...]
+14637.4514859943, 3300.85644901428, -166.964294284979, -15149.5972696061, 7860.54898997337, 1424.03804455769, 19279.2654449204, -2491.51901612873, 2780.54957707495, 1218.81164898807, 13497.5279480901, 11997.2244267554, -15019.3153727053, 19648.8276159669, -10299.5007193144, -22198.8919316527, -7295.97330195965, -19738.2351185621, -4092.07211217891, 13555.69149427, -12749.6805819759, 20825.1493092394, 12078.8347315870, -8072.87626533275, -15409.0469572420, 12225.1871940463, -3524.47652965 [...]
+14936.7425634376, 12551.6297837627, -113.504635425538, 10371.3109009885, 8146.1418716115, -5836.62316739633, 8602.22639865767, 4991.17606699692, 1388.09321094233, 23668.0126845718, 9762.7146630259, -11902.2131610034, 1906.96551489626, 19216.6706010671, -6435.69837840095, 11483.9449346773, 4711.12660329327, -1509.81639106574, 8916.54138871873, -8462.98743057779, 8703.99510562745, 5709.24054536693, 10075.2951492284, -1135.99005687867, -8701.20443282028, -382.639022759035, -4661.18151778223 [...]
+-8380.34369615284, -806.775521522669, 3822.05783437425, -5303.40195092732, -149.18347649465, -17816.4035530822, -17098.3596825913, 10685.0351041069, -3064.86222485662, -7296.11019143953, -4530.26957455212, -2885.72135705907, -2622.71536194816, 6684.68019408587, 10880.9409684472, -8238.02332032843, 8303.04267205843, -15618.5002535873, -4700.03940489829, -11228.3403404214, -11490.9637929596, -1700.05005724419, 4232.92673548836, -3603.89335701295, 4485.72934692116, 1127.79253778079, 4900.78 [...]
+-6046.39432327688, -3363.20373151362, -24855.5008252761, 2805.60366677794, -3690.61447508296, 13251.668573785, 4370.56831455397, -7388.94406120005, 4441.19347555715, 8253.5010358121, 14295.4766128070, -503.200366523457, -14898.8254314385, -4192.86095942282, 662.669487814164, 11602.6670957388, 15904.2975718256, 8126.3518764342, 2056.85565355757, -2620.22083952624, -8586.68926602711, 8876.68821547692, 4657.03842223746, 9451.6323893449, 8445.84007127917, 12438.4679009416, -2584.42706797978, [...]
+10761.9292104409, -7054.6904971539, -4498.79227709535, 13288.9496640274, 11743.0505118466, -12053.6910037780, 19976.9685696166, -11824.4399269152, 21311.0462754278, 64.0833634206805, 2768.74237417497, 14886.8059829537, 5413.81769626405, -7834.62821945587, -4694.63068782860, 379.831867381575, 559.419768115377, -1930.24967369548, 5226.04972884901, -20109.5351319233, -3028.53145542112, -1561.95599804913, -3450.53588041644, -5584.42975187664, -7352.9358490085, 3797.47888487346, 9813.98407084 [...]
+-503.667899335044, 10123.5461050785, 17352.7133872356, -13526.8797896363, 7686.53250131686, 11218.2294403056, 8510.42710085606, 4808.05817854526, -7318.60228955459, 7053.85549489234, 1873.94406396873, -10319.6751201102, 2341.29037295053, -21108.7848832543, 21927.1275569819, 8525.18490569923, -3563.29431520078, 3171.38445018883, 4604.55562574757, -8591.9420426824, -3965.55036517469, 14140.9699825859, -691.889511503123, -2147.96271387469, -6021.27459468641, -8130.4018619341, -16964.7279705 [...]
+-13178.8044844210, -12221.0442775417, 5571.19260578019, 7479.59212825024, 14283.4218319785, 2670.86095711494, 9348.4447274382, -10282.7237233936, 7510.17008044622, 5837.86389931599, 4499.33030678541, -1922.43121383246, -620.300778410474, -7129.43113036582, 1645.70977637398, 16098.7168203941, 3725.13829559455, -21310.2536323929, -901.625078321452, 5069.64541364112, 6849.56806483604, -15551.4953891885, 7005.19501883641, -7471.0946146775, 10092.0848068864, 11373.7964804415, -6765.9159746604 [...]
+-14690.3964117145, 6498.03811729722, -12252.3565214253, -16122.0880088110, -11741.2278128803, 8013.94402756343, 8311.47370205368, 6631.73370932012, 1887.47541913998, -9288.1523674226, 3819.70842580667, -14558.1521304821, 8809.69132159206, 10661.2481389493, 17431.1010289780, 7892.91872997357, 23677.5787104234, 3126.66402137625, -7891.2052340541, -10899.6133818559, 18495.8990358318, -7870.38031582475, 7221.00865154163, 9515.84714408856, 3460.76340480067, -4423.21505429532, -11056.174458825 [...]
+15119.5249184964, 6124.46800961798, 2661.36485713169, 8488.249882846, 15657.0551211222, -6002.42588725692, -13625.4922011586, 5954.93044900134, -8749.77699167988, 4425.19156558654, 9354.18329926116, 1077.11334989846, 13348.3719975847, -2934.1464196994, 2899.61543204444, -17623.6468190515, 6632.15267533965, 14152.4848182211, -3375.69053322023, 4142.67856127501, 14079.3892364165, -15942.9442503289, 8164.39568839679, 8518.02527648479, -13129.9866906262, 17086.327560991, 31297.4481096588, 99 [...]
+5974.88257266732, -7147.97304804533, 22610.1536306888, -7383.6594740567, -9828.34994207378, 3341.10926961912, 2274.99067451514, -21918.3215346706, 1288.92252188509, -5928.23363072256, -2138.88891321810, 11542.6976232123, -613.35040109358, 15352.7594650935, 248.640682292834, -9349.85150035367, -19512.5067245853, -7732.06732564722, 10034.1587850502, -13229.4644794154, 16465.2755079497, 14442.1922430046, -5981.88021851496, 12106.1075783017, -14125.2991320816, 5947.0938296776, 4889.918706970 [...]
+9312.55120827937, -5854.19319058714, 200.579805969118, 14050.0996679497, 7580.8404931692, -498.860810079092, 2139.46541952321, -4579.88363792253, -7765.02571416036, 9258.3978457828, -2668.69564234233, 392.479896930698, -11593.2619074933, 8581.1318347468, -6339.39726727283, 10193.3009081019, 9283.4074769158, -17826.834186749, -6788.88528137513, 11124.8783460977, -10557.1641365865, -10495.3818461388, -5535.08789956655, -3627.37958677118, 4844.74526922471, -7391.1756177185, -3468.1220123123 [...]
+-9418.69697249492, 7445.18221005003, -13168.9169170206, 1785.71871238239, -8266.20280948732, -11555.7228423501, 5924.07671343016, 8465.15121526496, -10064.1762192957, -264.188797784208, -13102.2289867968, 18114.5354059679, -6376.85131590452, -17000.2025280385, -14067.3646831064, 4191.76598212863, -305.879077496547, 3381.77603371619, 8675.24589588314, 8976.14931964837, 10756.3008108074, -17675.8114668128, 1195.81332128201, 1472.68833413255, 11045.5260046937, -4378.18600768826, -10129.8795 [...]
+4064.92395143359, 11595.1440913450, -8914.42366516734, 930.487161377282, 8208.96961547573, -8018.40609472391, -7886.65260168995, 7479.22301053522, -6653.13657625754, 1250.54581887537, -1800.67699193219, -12118.5071667308, 29159.2531968874, -15414.6269053095, -9789.37650154189, 1356.61153699172, 1568.97347364656, 3743.51938959088, -8974.45340481841, 5938.29333202464, 1748.64579851201, -13527.0956420837, -6750.34834954187, 12158.2031304825, -13595.2851865622, -7024.59613369929, 12739.61825 [...]
+1793.78936229318, 2862.75006244168, 9377.95425506847, -9462.2515408483, 13643.7526690884, 7048.4125976602, 10851.5240290221, 4760.564564622, 14337.5214050760, 3218.32757159541, 11687.7997177868, -1604.69275669314, 5589.27768177566, -2004.78590289687, -190.289049167757, -1801.66996283205, -2897.03643259824, -5258.31918253254, -4521.48820437776, 2856.56722789208, 16952.2447953801, -3778.18306854832, 20038.6291765619, 3345.48499684246, 29.640856944738, 202.498588856381, -1802.27824254026, 9 [...]
+-29807.9012389984, -6938.09711681806, -2940.87419695315, 2917.24634680426, -7673.23498386019, 3145.75506559053, 8275.8827009054, 5868.01808488759, 5936.8864276441, 28803.8822608381, -18441.6408995470, -8368.02149391918, 11346.9832224727, 6867.88652050515, 12468.2521172124, -10452.1022366901, 2853.30529779322, 1530.11563756572, -18439.8178471608, -4848.77686395746, -2488.88172978243, -1673.42723157710, 3890.08929920394, 2646.47319823322, 9317.55460918503, 15172.1410541785, 19769.894028200 [...]
+-14787.6920303922, -7682.08421126225, -9719.2345609088, -5845.53232209869, 1713.33244431763, 4193.37610478547, -5450.63507896245, -13429.7833922614, -3771.55751770622, -14381.4036372758, 7246.35463238549, 18986.6873878079, 521.003997021642, -22484.575501849, -4104.94180701085, 6803.27099868707, 14955.7122526929, 17490.8416268777, -13983.8823651583, -1777.46323303276, -1819.28426527855, -10179.2576651602, 1323.58694194393, 16306.6733244332, -5274.07070790597, -6226.83923075064, 9170.82438 [...]
+13887.9683288469, -2227.58654420863, -14.8696779190772, -8868.01190344825, 9697.90563747342, -1769.34501816802, 7217.44245824403, -2010.30519284810, -10292.4186913622, 5233.24752321185, -4629.41887563699, -935.766255129038, 12667.8416437741, 12598.8549580419, 655.99596138837, 8289.60106973084, -481.436952051217, 12330.5350409951, 1488.09062969984, -5432.5942669467, 1829.76787357134, 4713.06036511368, -41.2397741244407, -7794.4634869495, -767.590368215172, 8259.73278572951, 8771.401090922 [...]
+4814.94661005679, 7379.64248828705, -3913.09951231925, -4466.88312456378, -17470.3973989227, 4253.72518609051, 9711.2081254871, -7232.70557918176, 1005.08163084961, -14892.7808706781, -8797.54041577927, -252.828938438291, 2965.16410468007, 6427.17768336628, 20923.4495877172, 1338.26706129859, 18577.9169763461, -6908.51841869654, -13554.1930454971, -14652.3819578286, 17295.6377546415, 9347.9016538603, -9748.03813468228, 8800.60363322992, -11033.6256912430, 8810.54681487755, 6870.305042077 [...]
+6654.36069254008, 2611.98552721593, 4549.7619442568, 5854.78561529156, -6485.3454585474, -3098.45114690016, -3406.85760023576, 11507.9047370197, -9459.14257359034, -5435.86730486395, 5142.72828387672, 1874.79646799701, -5709.62819489204, 10400.1087700166, 4882.28142711818, -2380.58024417204, 5314.54148208977, 7034.42957205408, 1250.45902870222, -5427.0312148802, -11531.3356942602, -6565.68003050032, 8807.79217181404, -984.473694815952, 3193.50322524469, 35093.4195186016, 3669.70324106559 [...]
+7900.42135177712, -2063.88067695047, 12342.8301045039, -12281.6871960195, -572.851387670631, 5329.18956162846, 17618.1656539394, 14510.6791343513, 16795.3996351960, 12425.9904210932, -6787.94792133124, -8247.79764044038, 6020.44320043939, -7188.56686966097, 5695.62844780392, -899.792815293411, -7724.99608201023, -16209.1898467670, -2127.82728585078, -4776.651524765, -6391.32850694175, 26622.1648572614, 13255.4115434953, -12131.5393714358, 4085.18339098705, 5036.27224745344, -4834.3237861 [...]
+-15473.1677750772, 5777.52880695915, 13574.0066884364, 5033.21021789705, 2738.01748148205, 17040.5392212622, 1274.58071939915, 13297.4376385538, -1424.61478040447, 5241.82395684019, 9002.76417071069, -13911.6070827544, -921.179643009918, -793.177013399248, 4502.41957658321, 302.225726725902, 16890.8024209329, -20249.1626235138, -10585.2338102104, 7529.53834614344, 7775.65943161613, -10506.6056107734, 11131.5351443837, -4295.92353797452, 3333.17649496775, 3967.12724142851, -10380.04401902 [...]
+11656.9835824538, -2969.64905995546, 8557.9757252392, 20486.7562273235, 11091.4805879030, -9703.05865589102, -19175.7064049368, 9139.33582350486, 363.012037611872, -11484.3494278793, -3224.15579330577, 3618.65414358911, 4259.81664425066, 11662.4769732793, -8545.34278397312, 20502.6357551368, -4893.62483661548, 5774.70927242039, 2427.35622950396, 9860.29368936088, -9277.7242274087, 12111.9526008731, 16191.1807569945, 18939.4571119312, -748.917291949868, 7474.09614514586, 636.669570553413, [...]
+4684.48850221895, -10520.1173165017, 1077.02093163032, -8312.69837452626, 8878.33732737688, 6845.96195470168, 6192.80420046423, -3899.53921637643, -2376.9853137282, -238.699964246610, -547.430348377632, 1730.59099296882, -13311.2867567107, -7257.62552482858, -2650.53199856977, -2035.30783152320, 7234.5929136272, 9916.72357289137, 13651.2805266306, 20213.4914778708, 6089.64326336333, 7282.86996117934, 6892.4248203319, -13634.5694988598, -5761.09131236564, 13126.630348022, 8418.49200400958 [...]
+-1842.68508366068, 5039.14182257048, 3567.19790961547, -3409.14239616538, -2666.4384310542, 7191.27188751347, 2562.57474071464, -8225.95456551596, 25974.0663665523, 9059.80219151338, -12312.9566027839, 6944.07231558743, 3399.18102434322, -1569.50395649708, 16176.1143942817, 15869.5633876635, 1293.43819438734, 495.098040649788, 9919.06937473973, 2595.60371545298, -7271.72598181507, -3941.78627651672, 14117.0638091670, -11177.6355263123, 7277.52401801103, 9350.29288295876, -4555.3153079729 [...]
+22729.7753666996, 14599.0234057387, -21754.2122889126, 5098.25149271764, -8611.1928727605, -6195.65052975775, 1719.13527440828, 3630.00067847212, -4705.26465903265, 6120.3534298786, -2284.13901944904, -8683.48785863874, 16752.6424525589, 6948.57065900275, -7236.92984421633, -13300.0063945424, 14648.2979994314, 20812.8936480374, -1848.09098037485, 16225.7448088859, 13990.4449902854, 3860.85576597073, 16705.9202718462, 5446.01207201359, 4353.7322007207, 11569.7607125796, 2735.93984696280,  [...]
+14070.0975351374, -14991.6254916296, -7894.62582301987, -10605.3922581598, -1127.90005080223, -14507.2560607897, 10389.0599897619, -5641.89561817471, -19479.6067143455, -13741.6290747892, -5869.13985672418, 20051.2275027905, 4731.64114258503, -19233.9333378671, -224.640075309504, 6187.42301046323, 8707.4878027081, -3391.49216721566, -6649.9341379389, -16805.0874060324, -2463.15454829163, 3327.49038828119, -14494.4003282906, -8949.99704740435, -6052.79007245939, -1499.65050085651, -9137.5 [...]
+-14837.1816622783, -2424.98735993730, 3524.69652413481, -11485.4722921013, 7106.00272741036, -848.790568917942, 29155.9199266165, 10344.2332651091, -4069.81157595764, -6374.46468715359, 8203.33181333401, 11107.7512896609, -1669.25919683465, -9913.5326229615, -4889.28407250051, -3464.69958079539, -4693.15913620903, -152.313945468691, -26255.1792043026, -12893.7638517352, -8991.12010727897, -7552.9237165515, -20151.7652345191, -3981.17335057547, -14085.7600807256, 7737.47712910042, 8410.41 [...]
+1517.86246797540, 11558.9630685103, -2451.94099512707, 4625.55899900884, 4974.10862100849, -2532.09631465139, 6758.00456400808, -1995.95934214449, -5127.35602252919, -9471.00304355279, 1062.12925971768, -4401.37749582911, 8357.92036956179, 3728.71341163244, 2753.3756641993, 686.671801723137, -12226.8305317545, -8728.59558376294, 8671.18476624945, 10077.3997908798, -1011.30736298169, 1955.69004546472, 12954.4122316586, -4022.72258106147, 1609.34976616800, 16711.8823726799, -4790.909837620 [...]
+-7019.48513117672, -1415.93141567321, 4851.70801545507, 23676.8680002311, 9958.84685161098, 16464.2465247551, 1223.35622671784, 7490.87897130735, 18860.1867344606, -9248.27982138473, 9608.67056753945, 20904.7390113918, 13883.0215973521, 3778.87772713472, -11312.6111463021, 6561.90333483683, -3690.81798281356, -6763.95741158518, 780.131677839188, 7561.79454662196, 5135.79793833673, -1312.27581494527, -15995.8608321109, 5220.33021790176, 1382.28207678434, -5692.46730259921, 7455.4353516349 [...]
+5364.57101485658, 18954.4194577941, -6505.04593651223, -3971.41827338396, 774.507714336983, 15440.7581694375, 8090.21292670357, -17541.7619111108, 5001.99488916964, 17189.1553641694, -21461.4016034656, 918.887056935033, 8009.44936758049, 7658.17972506247, 9683.9501482891, 441.004480615938, -8436.39591524025, 6242.8120569339, 2398.88187400745, -121.275710076929, -7909.14365823511, 6779.61287471579, 10319.6563738504, -6477.76595857129, -2624.83021031135, 6092.29248665981, 16762.4182207417, [...]
+294.885053893876, 4718.60195196019, -9313.9609110369, 10842.2890680593, -3305.71688962241, 17144.1215604755, 8296.75371870562, -6164.80387258122, -18967.7149566722, 6430.42025017375, 10604.3242608835, 3323.86803480397, -6555.44719759932, -6554.60461856378, 11100.1335936229, 22086.3774176457, -4609.17665459489, 834.814725115411, -1816.89332415428, -7435.1658115947, -5585.24608779676, -11828.5992966715, 4958.58251577062, -2484.99128606849, 17514.8582900870, -3967.17350613217, -8885.9832374 [...]
+-5830.99550145771, -2035.51053042791, 6928.05894241978, 1450.91846367356, -5638.773962523, 9504.77153051251, -9662.09792650365, -1023.22614019689, 11938.9268920706, 3534.47506543589, -9024.47970099079, 6154.96776715997, -20271.0700780846, -1075.80903387692, -5464.21814100258, -2344.82170647573, -18944.5866277295, -1665.67621708947, 8768.33864487054, 8037.45614972038, -547.341812203799, 179.184678300367, 25.9140903263662, -4021.28582986246, 4384.53317760608, -686.04045401118, -3949.787881 [...]
+-6543.64580681436, 18731.1667392803, 7147.73792870793, 20355.5687847466, 9447.14875631553, -1747.28273935884, -789.72310897836, 7652.48685132997, -938.374170043067, 24027.5174610876, 6984.95134654152, 5255.05663521956, 5291.39095156824, -9473.7504099856, 7630.08943240913, 9632.48219304466, -4449.21199244496, -16334.5447610534, 8836.64496352447, 2294.81954752672, 9973.95483148994, 17828.4163433966, 1560.66538459508, -11604.5315235017, 4970.02180197374, -4340.58251815773, 3385.91353073121, [...]
+1348.70640358887, -3817.83515672279, 9515.11633618418, -6253.95914395882, -3704.36189206400, 3156.09687378687, -2455.40391267385, 4271.18180015398, 8143.6969181379, 9524.30341747611, -2753.09158240163, -15669.5029517147, -2349.55610016902, -9473.35861391153, 7193.00710605756, -7178.35034345992, -5934.73222352807, -17568.6357737449, -6117.33670306299, 9405.81897919271, -6749.22343410464, 8375.20427935559, 3221.61497544639, -3659.01031901223, 12572.0558887802, 4034.12094238753, -3427.29665 [...]
+4602.31156642346, -23410.9011708617, 3627.25987421054, 9561.28202373555, 7467.06295479175, 12958.1527986991, 12205.1291961742, -3659.1417249674, -4627.33413252273, 2953.26650540341, 2924.30244760327, -11079.3628989913, -1887.75022162696, 18504.6842172047, 2764.42684980974, 3183.76598993224, -1090.66216901041, 13532.7043329837, 9009.75312248237, 583.68849746698, 5391.52559800351, 3200.68220497421, -6053.20304439657, -3026.31673133116, 5023.79125726756, -13647.2860095244, 9422.28898211917, [...]
+4444.63771248556, 3717.22144531374, -14925.6249515147, 4822.60889893898, -2078.32800077769, 2056.44654816994, 7149.80649929536, 20486.3296417182, -2022.28770071425, 2741.8655254407, 12973.169149359, 12936.5132817256, -11154.1961150715, 6858.46600172446, -11404.8271452869, 15078.7288278880, 4317.01242335512, 3200.3131386673, 8659.31073845357, -9319.06521771443, -16947.5486377300, 216.371359544625, -2445.31510172197, 1668.49813482829, 6152.25632874661, -3587.03021757042, 15638.0907238788,  [...]
+-13906.8623179949, -4802.17134316853, 383.222764825925, 7562.9611753132, -8346.15475754932, 4943.21514666986, 2758.42355345776, -12498.6186173979, -13121.2402078335, 9489.62206758837, 10546.0656640834, 20547.7089862895, 17000.9022158940, -4685.44593196153, -11091.4731538453, -5821.91540476206, -15146.6977513519, 17514.0638399351, 1298.75655457120, 12875.7706379724, 3202.88361368508, 469.429142895347, -2874.62055052234, 4315.5946389378, 10163.0371532168, -8115.84225572506, 11348.283644580 [...]
+9061.90723166336, 3203.93566149044, 3950.72626661272, -23503.6690614575, 16574.6176376746, -5727.95942143972, -14778.8698535971, 4365.34247814985, 83.6182993638612, -13887.3052823953, -14425.6408477807, 17126.2576920638, 9974.99739359164, 8681.63694019804, -4366.37241364827, 14518.3303675710, 8855.28546469897, 1018.34744551459, -6270.60030454045, 2042.35326311434, -10289.7328278039, -25194.4241008827, 3816.76366482328, 2400.14652575158, 13824.0650796242, 15717.3524567811, -709.5324748409 [...]
+-18124.8749124842, -4297.64060679018, 1873.11603723654, -13749.7868541274, 935.86231505463, 606.683078625326, -2423.05413363025, -9817.44390989013, -8516.35139791263, 15385.4445462201, -9489.67966295768, 3992.35977629756, -7672.51310940569, 11194.9795126702, 1952.74790451853, 26399.2198703694, -15164.4529567825, 4365.4194404055, 445.282624857896, 2717.03794159270, -10631.9613136341, 6777.76138271392, 174.482440197784, 8874.67426798123, -5069.86069055426, -9499.28060392281, 13907.17643846 [...]
+-2478.37976859769, 9929.72819499963, 9839.53801376287, 4946.74552428996, -1752.86205413462, -21055.0599499585, 11407.0502845036, 4796.9222693804, -10001.8327003239, 11409.7972698153, -9797.76802748603, 3356.64853899556, -12326.7420800103, -14950.6020400264, 6173.76938871152, -8525.6637693518, -940.395665050736, -13593.0448987737, -6572.08337349569, 13057.3133219216, -8935.18660139377, -10399.5109044498, 2241.55375304511, 4449.17519943028, -8877.28579948945, 6402.81419675317, -16178.88472 [...]
+1552.27635492877, -17215.1118801939, -1032.64525117384, -1086.72912172589, -3109.65564465827, -7598.34948575596, -3810.11237566640, -3953.40693629464, 8839.78708545507, -6735.41584222237, 1066.47386992224, 2550.23555055128, 3860.75221297533, -3154.27180391422, -12329.6055907689, 8919.34660415028, -25766.9742536583, 3613.62203946936, 577.970648642395, 21433.3918342911, -1785.40974290155, -2038.25424423059, -4499.77854066006, 2228.10500601971, -10566.9735775642, 1690.63033847613, -11310.66 [...]
+-20373.9155310113, 3262.89418740620, 1868.01957276894, 11000.9930425507, 10853.4974057332, 8556.71786806685, 21742.9121580391, 5474.12491197198, 2540.62793807468, 11414.2003326518, 7392.78251589574, 9903.82861149186, -10167.1495996718, -7529.43009174772, 12098.9698400762, -14459.8733729413, 1221.72292147703, 14389.7167040015, 5745.1764574677, -3149.45948879745, 6434.54195381745, 16453.7930736172, -13291.9068329367, -840.47092521293, 2130.65882710831, -14443.3553087704, 3214.32247711883,  [...]
+-5927.51993664515, 9008.24709279324, 5573.7038301561, 3903.97966041365, 9861.45971783367, 3357.44893445764, 7515.56695455953, -3524.87250560683, -6660.82081553255, -2293.17013071125, 4952.10747635111, 7959.42019191814, 2381.79719260328, -2920.89738584073, 1417.03395730444, 11797.4729446107, 1055.29166431881, -6413.91087632185, 18887.3665421697, 1721.76068711227, 3015.86681305821, -4984.87324476092, -8079.17068154926, -2896.33687959303, 2389.89787435472, 1369.76088716988, 20283.4296088018 [...]
+15543.1438770934, -4561.83352003992, -10648.1733140239, 19900.5525119148, -12170.3251956144, -5354.49725447884, 4440.96698010414, -2449.65624201824, -3731.36467282796, 5745.18190216369, -488.739962474207, 1409.39078780426, -13378.5348374587, -11264.7077381182, 3503.36331100513, -8320.31121890968, -17322.6600839855, -11253.5997654372, 13203.5270051129, -2030.35237428555, -5499.78484147695, 7108.88811485613, 5475.56322614992, 7674.12494086272, 4492.78037940848, -6692.94052873698, -8217.765 [...]
+-9360.71817379918, -2304.70265639954, 586.88452391822, 17126.4749305259, -2488.48845198253, -20904.9586643175, 8944.3887502737, -522.770505533066, -10142.3693875367, 2877.81237611419, -5919.78150164275, 6212.12641374729, -15751.4987896478, 2251.16217493335, 2085.65775736537, -2561.35086589434, -11155.5559283317, 5049.17392547071, -822.846253074964, 20196.0466224918, 16226.3915287926, -10267.2395748258, -23347.4546282596, 5453.14860316453, 6294.31259919329, 13632.8519686767, -15547.154365 [...]
+26279.0924724629, 22797.5748962557, 2412.61059680365, -10192.7071724727, -1576.73338278712, 8896.31615360988, 15832.1015293535, -9242.06161724474, -19999.5156009856, 6676.3724140067, -8704.29204213689, -10127.7917611895, 11997.1101435309, 10070.1155956734, -13052.0641554872, 18584.1342028053, 4736.52128671994, 6395.09467965547, -8600.30446176698, -4625.41610249451, 4581.61784448697, 4458.39264605662, 3055.54528920331, 2519.60921335982, -5744.24264265082, -8050.90317605541, 17534.85288439 [...]
+17993.8837101035, 2116.70058417315, -1773.42459388963, 22466.2441726982, 14165.0708057637, 10051.2002308355, 56.5089134172863, -3042.78823348106, 12361.0267382161, -1177.90371843903, -1417.72912266300, 114.109040846134, 7649.65911503402, 1566.16825490410, 6044.26774634683, 11425.1162254631, 156.296263963785, 11155.5145334391, 1298.46794116066, -5107.21870710192, -12701.2973913429, -3089.63756888516, 16556.0500692106, 2866.00519795735, -12707.1240983781, 18535.4044747278, -5347.7056705373 [...]
+-2672.31352213899, 2181.53987621392, 8546.47571744447, -190.205327394504, -19862.8093371097, 6375.80787268194, 2282.75806523852, 11178.2427718741, -17004.3335664666, -539.321492697776, -8848.23161142864, 1398.36246477162, -2822.87658578866, 9314.79408617041, 10480.6608145836, 2475.01929666809, -15116.4349730774, -9745.1145053967, -5245.81799653423, -19363.0535789157, 861.32258014306, 1687.84951614902, 6049.63076680928, 424.976181976769, 7778.51147830098, 4531.98643789657, -738.9552661900 [...]
+-6761.5175674228, -10793.3811773307, -4060.54150198555, 8768.93898909862, 14016.4432532839, -4333.94538583637, -13884.6268559506, 5414.41157784606, -6001.69381267776, -12733.7187599554, 2026.40767703927, 2481.15317274863, 12498.2242824015, 3703.9104947692, -5488.99391957708, -5613.30437459995, -5232.74061551378, 6400.49387474953, 1690.71473699853, 3470.42019536974, -2145.76992496446, 11780.9222817941, 10703.4372522144, 7946.28658131664, 4067.66238619124, -10177.6521280503, 10037.95318421 [...]
+10263.0346584095, -64.9678973643368, 10387.3864149330, 975.808634881887, -15073.9284847638, 9807.55145921353, -14178.708323436, 960.371196688524, 23985.9736820865, 21815.4723021902, 9249.4879459203, -8342.63969349126, 5629.1404600841, 20290.9405211040, 8680.71474863083, 3543.62730262203, 9270.0995465596, -1673.41223988326, 16662.413162079, 3193.09234327784, -8203.6499333148, 1419.28354222294, -5259.79176049289, -7898.5510632914, -517.253346903317, 5682.19537750191, 916.541811298484, 9753 [...]
+-2746.0280923569, -22344.9762678399, 1691.37706054700, 14541.6080024942, -8867.87133497325, 2277.53859005415, 2989.03120221139, -2566.17339801059, -2828.09675033685, 4453.36708891345, 14886.1777083625, -1480.89166046862, 3784.14269849873, -2834.07832722351, 5529.02923175009, 17217.2918755802, -9105.47917142576, -7776.56076484786, -8574.66780362258, -1845.00603911586, -7412.73884875828, -6772.72848507536, 3316.81740315297, -15085.326047338, 14377.6639051356, -3640.77390017689, 47.28634637 [...]
+2798.20219846629, 26012.6120234679, -18159.9594231082, 7983.05747662436, -2795.15914656582, 7849.83766825452, 853.865515260039, -1406.42720320059, 3263.32277651335, 7440.64844065683, 25271.4869785863, -3098.45889692868, -17002.3572754285, -14723.9764135282, 3165.67221512128, 2106.99545691954, 11885.6130814804, 12268.601676111, -17951.7198812895, 20761.9333083488, 11949.5349207617, 9719.23380177012, -6951.20762421503, -15648.1414147148, -3381.33393767946, 18493.3547373576, 12382.967371362 [...]
+10361.2661207123, -4127.15801380426, -12751.7452077814, 2552.03763122720, -15597.3557882965, -22289.9123273255, -4118.17755905897, -2986.55406827794, 413.682191471751, -19430.8443197185, -17390.1981015808, -9000.77097795888, -8656.67865409814, 11871.3740537826, 898.954155825102, -1421.92576550753, -2030.02538393913, -15082.5777299874, -23491.2854413292, -7783.64656611567, 767.58700648409, -4829.00045910776, 10377.9411213693, 5551.93184888738, 10746.2431691674, 4308.21168322695, -15742.12 [...]
+-6153.69806861203, 12254.4996266401, 1343.84213794425, 2392.10183417099, -8902.86629837198, -9850.38522688448, -828.744536569503, -25056.0270022042, 5650.4960866984, -10666.7017423246, -7679.15612510906, -9396.40193541162, -11941.3062000259, 34817.7250610224, 10766.7972163330, 1956.39806984318, 12788.8423890055, 2692.76076185926, -4151.38204317388, -7421.13860911123, -1243.13964649673, 19338.0081461591, -4110.57399638014, -3789.59436741776, -1851.312951027, -11887.5623981453, 26656.96260 [...]
+-4252.02591279979, -6446.23020120946, 4399.38916599835, -10514.4981406502, 3133.65757889344, 8357.54650449004, -6177.70310619744, 14859.4348973810, 4095.02112887656, -10604.8398333928, 37.8016491647306, 545.503948472125, -14566.4323896381, 10386.2000292576, 6671.2037115432, -9065.68466315203, 13206.6171711054, 2829.36574096995, 8367.8274438819, 15002.6973280476, -18045.4259547454, -12458.4316662505, 3696.73324436959, -4534.06540129848, 10388.9795657783, -17473.1272647808, 1637.2008311776 [...]
+6098.2604381213, 14117.2911551858, -6017.119081254, 17063.2837388087, 11213.5869497415, -4617.51723688949, 12325.8343282257, 7040.20577847744, -8829.45276367456, 18684.9642791280, 14672.9102591404, 6143.2859271248, -1526.10825479148, -4055.87242843572, 2196.85862355874, -11870.0975464130, 2713.20866801896, -3956.138259772, -20618.7514941766, 5243.05433291802, -30864.4046803218, 4350.80605354703, 25415.3510669579, 15683.2749034123, 3956.41870021079, -4276.42138500556, 2993.15637124998, -8 [...]
+16924.5449232182, -654.800233473095, 10749.9713538626, -868.384009520883, 19580.1665045023, 308.951245237488, 8973.31010028792, -8101.827384323, -8839.4659730024, -18966.9582670896, -1930.25961819547, -12079.9485362819, 8959.91903531918, -918.25843306475, -563.795062875121, 15063.4718816829, 11368.9406613588, 3304.8674372124, -14599.9629616828, 373.501933179346, 1607.36529035518, 1575.46084869532, 19994.4721421063, -1049.19336243400, 3032.60112232748, 6139.11921952672, -4043.19217376399, [...]
+-226.695673797111, 33424.9695983697, -3667.98611321561, 28777.5651331546, 18048.8779221651, 24365.1397174925, -4217.36824744546, -8475.89984791138, -11467.5797829634, 5628.51133297406, -12329.5019574681, 21387.3772917063, -7374.48327193466, -2868.01242687208, 8046.14163296139, 17666.775691191, -14822.5609026334, 4646.28916801168, 2534.57456350223, 11660.9601751813, 19585.5716533347, -2850.80263218305, 10426.7908854945, 571.612166688252, 14737.7625389581, 12138.9713926128, 10044.261142295 [...]
+-2102.45083132332, -2087.84869501800, -8144.2756437237, 1845.30571135512, 17936.4548765739, -29917.4351250237, -10632.7532308409, 7077.5971450486, -8721.07105631644, 3053.36802548203, 3843.81005865112, -11737.6497117581, -5153.20952082341, 12877.4597712168, -5650.87255091678, -3154.95453671222, -5029.23342711789, 1052.68306715236, 16138.2666920070, 8165.86232001456, 3260.33658819966, -13430.7183005390, 867.757252744493, -11811.1297957333, -3227.63157962494, -7762.13036235595, 8258.862559 [...]
+4433.55977472212, -1642.84706992999, 19310.4005163978, -6227.72551970481, -4583.90954112496, -9486.60826131794, -1786.68219225486, -1162.40339374155, -4643.38107838091, -3419.08754893148, 13017.2525328310, -6533.74491833099, -2005.80021719728, 8433.89871097435, 3196.1675337639, 3598.4734869164, -6849.82391974314, 11637.7876456179, -3201.81448113392, -9221.39085278758, 589.484513853625, 13667.0282236522, -2020.67321676512, 5025.70999755809, 198.010242275444, 10416.3595670878, 3852.3782262 [...]
+-5983.77917603535, -18042.9041179938, -25401.6461491523, 5533.08830900427, 5972.09473903985, 705.456290720095, -19929.6410964335, -890.497036947503, 6736.57476389489, 453.958959352251, -27394.3705795859, -2628.91827826501, 19017.5098041736, 6268.94688802851, 8286.92957777227, 4683.18465879809, 10448.0519529641, -8881.74330891696, -6071.67195379952, -21618.8610863646, 19789.2212302247, -7037.85541178342, -2415.75747643233, -2338.28947797193, 1729.97496904683, 5943.88265519963, -4903.11115 [...]
+7579.34663773826, 2492.52078816046, 6165.83720476705, 6219.46226902296, -2906.88698837323, 6931.94677835841, -1086.54977078384, 4586.77384261374, 7573.10390198366, -2967.30415209447, 16694.1390209835, 653.347457926031, 2933.87345213896, 16162.2652346136, -3944.59607544979, -1054.34394086267, -109.182420633033, -3507.06179072146, 17830.9959431161, 1361.73993486207, 9201.29078458559, 9969.97535393648, 14348.5654306316, -16627.3720901943, 5721.80926054435, -14051.7739696333, 4259.6977197764 [...]
+-5319.45821462433, 2531.16380661845, -3318.22536409861, 2717.48813647383, 6179.84961160207, -923.167995463484, -14963.2486282024, -3999.23486630759, 10803.2937268201, 4275.80889602721, 11436.8517115727, 10157.6980839555, 8847.59977264054, -1106.39713945961, 17766.1565300611, -6089.64392830787, 11975.9148334958, 6712.29619356236, 7117.01105409679, -1384.04985595791, -6477.01107030188, 3968.87115183378, 186.262498634548, 7926.78525686804, -1983.57884150226, -7362.07067453044, 5146.93035345 [...]
+-11803.6870935923, 3101.17184452413, 2534.49387701651, 6358.63080548747, 11192.3488389547, 14577.0331712386, 5358.1751769577, 9907.5395181032, 3606.97553008640, -377.83915867194, -1700.48412859253, -11563.6864550836, 3617.02074877043, -3116.21470295917, -1169.85171626657, -3097.40514678372, -1769.57455519497, 5932.21334540091, -19019.1136081262, 14974.4361456265, 5828.01660923958, 658.618365640462, -11339.2183342635, 5403.63322708791, -4086.58434545061, -6473.42925764317, 928.14656665353 [...]
+3613.93558398503, -976.447397350354, -5140.71510849224, -2179.86623631647, 27740.4962884020, 23795.9092828594, -4502.39507481677, -1945.17287089530, 2888.34180831359, -1822.87419599899, -5402.09545439384, -1505.53240212686, 1238.52330317929, 15998.0817915843, 3645.66779433621, -7039.4601404207, 8726.4519038711, 7393.56104476681, 2230.38306152787, -2956.08606430337, -5934.88467383696, 2859.97377782523, 15475.1344295175, -16932.6902236921, 6229.78369124465, 3715.26881032868, -5326.03912485 [...]
+-3314.33372351218, -13016.4860121903, 1487.67691503176, -5668.77874425322, 1092.73859782887, -7902.8225247506, 582.907341076465, 5450.11877042065, -969.01597660604, -10774.9723806702, 4553.0762400744, 901.209299556973, -24742.8036182386, 5818.03576610716, -10246.0153683376, -2122.2915839984, -20293.0567345501, 2457.93284867759, -4548.04626565004, 4546.16268346436, -2556.38826076375, 2974.31557499963, 6324.05345845306, 31043.458261574, -19272.8949332088, 8927.60328060773, -7077.9381151725 [...]
+-8776.30196237696, 9379.76351788794, -7272.65213470466, -11885.4960183234, -16895.5608976873, 9553.89049978232, -15513.3717402507, 2910.40348304179, -159.598785034709, 4822.13364200326, 7080.1013627162, 4634.09120870215, -2265.19987009051, 7558.49757415835, -3306.10224763426, 7861.91179596876, -12912.4560658198, -10999.1554229694, -14985.8471152407, -4818.34985264637, 3683.45190744993, 22123.7749479139, -13249.4189735688, 8918.47429485303, -1375.37688573551, -7402.74203501383, -17758.356 [...]
+6712.64401122403, 25020.8506740518, 7661.00925571924, -10205.1776568594, -899.193562341513, -10400.1659141384, -5656.82722600528, 11845.2632915436, -5207.3683055304, -8377.39992455155, -14338.2095564535, 5163.17018745778, -5731.03488306881, 1384.19246726324, 6240.25784292105, -1863.01977296115, -1283.86152816806, 14522.0994059402, 10533.0443857033, -13168.0085691239, -6011.13785889261, 4711.18727419009, -5421.03377628317, -3561.92525793332, 10518.0436575698, 7097.77725635749, -488.812306 [...]
+-22805.1647980852, 9710.36042635861, 13568.6372753519, 6121.07227736146, -3457.28637850928, -6323.35358090873, -7071.28809871575, -6294.385165574, -4315.43100691840, 8788.7817273658, -5893.51338104905, 1766.79816529096, 1441.76453374639, -3419.64946383597, -570.188189185927, 9284.37817041235, -887.779673975505, 8975.80728034719, -4662.47685533281, 17055.9949691356, -3971.01718162271, 14240.6577778200, -10821.3011396338, 10427.8886619524, -6540.5772519012, -13391.0397615410, 1027.23764560 [...]
+-18823.1542392641, 3453.80523015393, 4074.28226986419, -12921.5267290526, 14886.7573291500, -450.484835431171, 22585.1849729723, 10449.9354173676, 6932.66748471767, 360.549184915493, 17917.9897338472, -7719.30536121432, 7858.38114560318, 12199.4703862364, -10852.7214457819, 1268.86213416453, 1288.39085832653, 9879.04802353884, 11137.2826520786, -1870.90470984281, 11638.7978784445, -355.960859764019, -8129.2637023241, -3479.2815288949, 4352.68362467833, -2856.64266219766, 11581.3223344810 [...]
+3595.55534980056, -4444.93705206655, -12575.6109367555, -16332.4116220801, 9991.53356647694, -3976.50008946391, -9265.07939004247, 6794.2086528659, -1094.47011924418, -4818.95374816862, 7121.76146011254, 6037.12909661272, -12972.6983682817, 15214.9141659823, 15190.0729360040, -4723.14846465433, 3054.34049704497, -14396.2758173521, -8234.2307705232, 8343.6682368869, -502.169227766616, -403.475915038279, -13850.2986348932, -11395.7540751745, -2439.32141849426, -11438.9544818923, 3866.63549 [...]
+3781.27056481163, 20945.5210882209, 7206.48513692166, 8489.9908303484, -188.696070302744, -7985.7735615283, -6399.20273462713, 899.783985578006, 4005.75255202196, 952.648008304643, -11142.2796948067, 11979.9670435188, 7683.13890584118, -6620.13952879939, 5028.79815086437, -12511.4218752322, -5181.95525899966, -14108.0710488776, 6309.9595048343, 6790.20944868674, 20633.178793648, 14665.4508170148, 4127.4466335226, 16076.9393392378, -7387.89021805996, -6457.53640356482, -22637.2146777623,  [...]
+19200.2228884727, -19334.9093579566, -3816.79229933735, -4795.02889690043, 952.989767080353, -7993.79105116075, -6784.75698203603, 14003.1889669105, -972.986310939111, -2619.74756722644, -8613.90567752214, 3772.90958407475, -2275.12477439732, 3461.42354765859, 6720.60027624979, 100.36547497354, -865.050635462215, -8115.73618398382, -10758.2601949768, -11304.9183314853, 11144.4197095369, 9952.48764486368, -16766.1425146671, -16509.9598818354, 3023.74840392733, -2293.5812990179, 13682.8328 [...]
+5642.24174875248, 3586.74531699165, -11783.7353194515, -4548.10686523157, -10961.0939784243, 9525.75356572593, -6853.84114192217, 2089.55248238663, 2774.90653481389, 722.046096200057, 1896.6050331294, -10158.443821076, -3361.7196601017, 15641.9815218637, 3635.18794078093, -1875.95157316347, 2464.65265196694, -17338.7502022888, 9787.80400754099, 19157.7247610764, 9916.05375644308, -4576.74640414225, -1703.91494869798, -1793.93034087303, -10088.4458867730, 8292.85365838586, -6376.823557947 [...]
+11776.0007198774, -4869.85234368626, 5022.8955788152, -437.835059283983, -11729.0264395555, -6930.62153696763, 11480.4790741167, 4595.39470523174, -3943.83526157741, -7943.68118026656, 6651.9663686942, -5709.67989561257, -11380.1049470523, -13247.0386427055, -12384.8957480444, -3447.81182234721, 1246.90596562872, -3238.75738131232, -3776.60613967691, 10537.2547930443, 7285.38751593047, -12317.7715725395, 10137.6233448659, 24059.6552334757, -13445.8573909068, 10390.1109634097, -20915.4679 [...]
+-4128.45950212247, -1596.19843863443, -3841.88652279524, 6694.75454368382, 11806.9777368880, -2006.52473409763, -10526.2570862556, 655.175970582448, 11917.9593472473, 7694.1311424858, -10545.4068517323, 1225.98041924835, 18170.9695357826, 2048.59205156705, -913.871177353074, 13102.4095331129, -18178.5129421976, 6239.14566108517, -20124.2390750460, -1610.45439114392, 764.578420413623, 2124.54724968868, -7573.02141846023, 2395.58093420536, 3892.61258192751, -491.067677504736, -7523.6669375 [...]
+5953.75591698405, -2911.60644895603, 11362.1664104595, -3156.92100543227, -5212.81287401608, -5464.60689818784, 13864.5549107496, -7280.47527943932, 17450.1790980984, -5573.99987954685, 8961.86972427582, -7024.26189930419, 3325.52010053567, -13721.2553261564, -7193.07875602464, 8531.3318313478, 1838.33343708452, 17357.9853379492, 6413.75063230995, -646.390420407664, -10296.0649526615, -13101.1779281420, 4137.55205584377, 3139.52601602382, 8676.10648709335, -16794.3397598626, 6171.6343935 [...]
+15454.6859736626, 94.381670050693, -13501.3073490819, -381.276878194466, -18991.2500312583, -14745.7073176039, -7482.93419094856, -2662.83277796204, 10651.8353562996, 2025.84997112353, -10840.0373441505, 3065.21417286846, 6397.96351124089, 8511.00707256506, -822.723217535312, 15610.9815010153, 15351.2979963366, -16078.8395287806, 12568.1775202590, -15591.7990997683, -15445.5828826865, 18079.5680846976, 19653.5655311907, 1021.18901008157, 5173.32637035324, 12584.0223686845, -9242.59266308 [...]
+-11284.5277704694, -15831.7594863857, 5575.738448144, -2031.76240654790, 10001.4512120439, 1772.58471957848, 332.013725417915, -3998.65939676955, 10216.4363790776, -1500.66164493535, -8892.00892249751, -585.232341243999, 27057.0408579905, -6911.06438272659, -7181.46667284454, 1561.63231116976, 4746.97171348933, 5246.00231925797, -3203.24149172243, -15977.7544240415, -11519.0198325927, 11890.7847700556, -4137.91901686211, -4818.7866619028, -19152.2315409255, -10867.1513796659, -3330.05145 [...]
+-9288.27849235196, 2387.81457405984, 13322.0941482571, -2569.83499568617, -7633.73657359111, 8953.37084176673, 4865.32790490258, 10437.8380300100, 21932.2391818489, -12951.6421648300, -6554.94675248826, 2780.09813736614, 7502.91527960469, 13816.232450124, -3931.23173677544, -13925.6352004303, 8803.5248967489, 1149.17399577710, -8191.21422319654, -6212.48852189943, -5878.93224407318, -3712.17133377759, 418.243868544172, 7738.76190163672, 15209.6760763149, -4485.19212481594, 5196.345565162 [...]
+18063.6396098229, -1910.35470060189, 15772.5777074272, -6917.7525750178, 14283.3598244979, 4664.55723313289, 5368.07026249862, 11585.8713590724, -18032.3167992759, -15438.7689607017, 724.480370549544, -6175.76693269841, -9201.91734280735, 9520.03888555415, -11057.7685020039, -4431.81288416926, -16918.7343459173, -6788.12025983731, 1788.67014271987, -19670.4302166005, 14440.6855071512, 5850.75185748503, -4552.17446685576, -1936.75426558365, -2922.47470661341, -11386.3649353394, -9914.7843 [...]
+-23068.0540670081, 8738.48258883953, 2814.96325026528, -3095.85152987677, -1696.70131482685, -5605.28630345291, -10408.9164795219, 4507.43842858286, -18563.947054391, -1715.37431860631, -5464.93353917439, -24329.9121470451, -7221.89890058607, 8970.68636442395, -15632.7414312290, -4753.83130483015, 1510.88130016157, 324.449855277087, 1960.58533554403, 8441.10854612473, 7985.85108862074, 6339.22992845185, 23191.4261982894, -2464.96628933831, -4357.61127716689, -19072.4645286934, 329.212729 [...]
+-3539.05779570128, 3894.34426787361, 9500.27430768266, 2130.41705836896, -3712.04516056877, -6679.15070847467, -3168.8223042339, 8057.25825544422, -5408.42562916412, 21516.2807114565, -7399.20295647262, -10373.6408048507, 1678.14220171583, 25086.2079427928, 8780.9109714547, 5907.27646260892, -14853.8635090961, -2815.49517480199, 3291.81773496664, -6455.95749592619, 6716.60086572954, -2305.06214493315, -4248.26194077629, -6244.81743981833, -1349.45074622643, 3651.21670752932, 2654.0338679 [...]
+-4312.90517384262, 9848.02730557203, 1029.77136044994, -7843.6557811012, -19123.8396716218, 1828.73259823285, 10529.6765012793, -11683.874904711, 19012.2097668134, -4466.17792372929, 5758.15724089877, -5929.20159902052, -3716.48502906371, -14162.1548308306, -6274.33759161965, -1784.87919207614, 24228.4113297891, 5204.1452036285, 1946.17565787906, -6880.89235285007, 9463.83817176242, -23106.2779696114, 12819.7922475712, -3463.24209122124, 10700.1109026786, 17459.1522149884, 4320.290014637 [...]
+12461.6438739657, 8023.28991775333, 7433.43677264878, 7313.77473610409, -7089.53367281897, -1285.96544888706, 17236.094693922, 4747.56872416806, 2495.17355840926, 5527.87375192286, -7526.14876474202, 863.888206253613, 7012.72277480779, -1437.09498732224, -3063.56575933387, -3569.02974459509, -9847.3133433529, 5511.45211033616, 3620.15421601124, 12860.7023484449, -6091.06863914501, 11400.7430456260, 6480.11217465224, 12606.0630771713, 2542.67877943252, 11483.905360889, -8879.77973096246,  [...]
+
+double y14[100] = {
+28490354.3539116, 127484594.814215, -75126933.7321952, -53764399.1131398, 53707363.5967705, 17345456.6261104, -106699038.507660, -48228301.2444519, 34582370.3615657, -132460.654114532, 27658230.7530203, 140009281.630421, 97168783.9514408, -14663445.9072229, 1538618.53030926, 13013344.1234354, -100086935.501659, 43289979.8689582, 26892151.3183533, 78474516.8033014, -67363251.7533571, 45518195.9943786, -10696417.9735193, 192235545.423109, 46904190.7548759, -62764898.7654417, 132105871.9107 [...]
+
+double lars14[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -89.07013828843508900, -117.40136155609837000, -164.01920235152147000, -220.90313284211331000, -295.59998775293349000, -306.76717617229838000, -358.39669191743042000, -405.31508929871654000, -419.24244905586625000, -483.83852105465661000, -584.92129661730144000, -613.98464518751325000, -675.72147560197129000, -723.72343929173917000, -788.20079133860224000, -793.60574643389123000, -845.00883006353843000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -152.53642508275146000, -196.13086916021115000, -271.43765968242883000, -317.64383988858401000, -378.22116200235081000, -383.26596671756988000, -415.92096296521834000, -420.77348160685352000, -451.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.00680076256691910, 36.90957103941837400, 41.85458857157132700, 75.89004498663624100, 120.08 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 59.83109805400017200, 143.05852836839478000, 182.56034882921983000, 236.28358736538652000, 240.20653076867166000, 264.85830467071793000, 270.08951821823848000, 303.1420992849737 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -10.31561952336396000, -72.90111235028912500, -138. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 356.08475119536160000, 443.47248373477709000, 469.76655010997428000, 503.82181051700815000, 544.45392968490796000, 608.33841559741859000, 620.46971653877290000, 694.39322486247238000, 757.67358094872509000, 785.32602168412620000, 918.77167550579713000, 1086.74934324354720000, 1132.24823920046990000, 1189.51682305325490000, 1223.12588663456040000, 1275.64541148952690000, 1278.99758221595880000, 1323.78621265668630000, 1329.213 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -138.11438349596878000, -252.85368684446902000, -412.77346440429756000, -425.38285745394666000, -549.97779028232083000, -566.81906033913594000, -677.8316064 [...]
+-139.01376153796539000, -258.61021684223232000, -423.94390330033730000, -785.49865414445037000, -871.26726431276836000, -906.32344124048325000, -950.68111579048616000, -1005.50326517568940000, -1095.25923114747870000, -1113.21077722802940000, -1208.12294472654800000, -1288.35153162107800000, -1310.47821060937280000, -1422.32858125593430000, -1577.37337916714980000, -1610.21695358066880000, -1662.82948647552730000, -1708.06315922294080000, -1770.37454334785140000, -1776.06768836788140000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 92.34636353954469700, 216.37019855965053000, 247.41901511011446000, 293.56826063149333000, 329.34527718868941000, 383.09083759886346000, 386.36422846247751000, 430.90852279239647000, 437.65446978730290000, 481.728741904 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -28.06988998057886400, -30.13927384735893600, -60.75187385980016300, -64.07290507716950900, -84.78873146148541200, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -79.88650577157243000, -190.91913831004791000, -200.27108774813240000, -272.45169086566199000, -280.27894929389487000, -332.31437909767 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 30.19119520802811300, 169.01794604708613000, 358.66791641211461000, 412.09181106004837000, 493.50490000046074000, 540.42899854308587000, 608.45398518712670000, 613.33497101034868000, 658.13212222987841000, 662.89904845125045000, 696.3162940 [...]
+0.00000000000000000, 0.00000000000000000, -164.81680702090574000, -513.25923894386005000, -589.89270458986653000, -621.95640974592663000, -657.86251939288161000, -700.83764499813401000, -768.49936376644052000, -782.59788094577607000, -866.91706642173767000, -939.48271151161225000, -960.50504167002998000, -1057.62180421573160000, -1177.45698249684760000, -1213.88158938477020000, -1261.98003744644070000, -1301.60844045343700000, -1356.23356904751540000, -1360.27352129849440000, -1390.93666 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -28.38812871569230000, -76.91387452220199300, -136.03282164850108000, -235.96060299165001000, -252.86164021606382000, -357.45863785570248000, -441.30211396058672000, -459.87743003844076000, -544.30773335198091000, -650.80741227252452000, -672.17286173009813000, -720.28918874373608000, -750.61740127232315000, -789.57392999106219000, -793.39344128024845000, -814.77086938656134000, -817. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -88.64174787139856400, -100.95330569944700000, -176.11064460354680000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 55.00489378084641600, 120.83357959111093000, 223.10470547629672000, 241.27262141593951000, 358.03067908758413000, 451.22940543363995000, 476.00518150529496000, 591.29656214658360000, 727.48755833936923000, 759.17171476820863000, 840.38649239903975000, 905.23418299451851000, 995.78896241187351000, 1003.60782660968800000, 1074.62952189740740000, 1083.445504855371200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 119.50540813004400000, 272.33647090656905000, 606.00665904606262000, 707.34432705116615000, 746.58482366629130000, 787.29778019189575000, 838.79371710240605000, 919.49483630083921000, 931.56957572899341000, 994.08020680963489000, 1046.24833748248060000, 1065.34108853960200000, 1162.14980183676150000, 1301.80582863605170000, 1342.15448425198290000, 1395.97225434761300000, 1413.92491220242820000, 1434.48302311950120000, 1435.36210891626270000, 1450.97266815087480000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 75.83358500071032900, 88.57673088369846000, 169.28815867846131000, 239.19972034671491000, 264.34988445372812000, 376.21126884490729000, 523.78523095282242000, 564.71236506641583000, 622.24932363093887000, 649.81873692614204000, 686.00032369855739000, 688.68101420355742000, 715.35014760658999000, 717.87986324173073000, 732. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 17.22838131004192900, 120.40776027887054000, 210.48120443442198000, 237.48393203546243000, 372.71584330950105000, 556.07880531941987000, 607.08939856265840000, 685.84151706632747000, 738.03756649279069000, 812.45991432479889000, 818.16777825679765000, 865.26941129404156000, 873.42674319301739000, 928.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.34432740090350200, -57.30129501177600600, -65.75330078265280100, -122.62843570875981000, -163.01180019432624000, -173.17644122783250000, -216.94147161401679000, -286.88830853084511000, -303.11481446289889000, -340.27682181305801000, -366.09577172034204000, -394.96858893989253000, -396.74626071453145000, -406.76541826591045000, -408.2597152 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -97.98478181659173500, -172.73176651524216000, -200.38723816448069000, -344.27235691082865000, -527.20684542051913000, -580.81697346191959000, -688.53457233727465000, -770.06482803333120000, -886.88124688195035000, -895.83626550750500000, -983.27355217207230000, -994.25995582363373 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -26.81411103068527200, -50.422 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 52.78133926926357600, 73.15525028561567900, 172.46494449506548000, 330.86648404875331000, 375.99703552109355000, 454.91899135161805000, 499.61530868824366000, 561.31498972015083000, 565.57549728394167000, 600.07019003722371000, 604.52732199157879000, 632.629189 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -102.7330 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq14[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1690.96605533860750000, -1404.91640113603900000, -1729.11771079147180000, -1670.48136143091050000, -1441.42672104913480000, -1231.63653230121920000, -1020.48693853453010000, -1063.12952935906470000, -1022.70244380294230000, -991.17642382044642000, -1060.14585049806080000, -1100.46683857760440000, -1251.31276895987550000, -1367.48025629597210000, -1339.81822935231660000, -1383.58183918432680000, -1451.231 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -869.66210902870012000, -925.84447126595956000, -973.54582857159369000, -937.31731174238212000, -896.47301579809471000, -933.92996338389923000, -801.03776758021945000, -848.55851778256852000, -831.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 661.67715904517775000, 401.36149296023234000, 477.79407899025870000, 493.66995611169642000, 5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1061.32491229673470000, 919.01323702312413000, 712.32130548679004000, 695.89730074463694000, 668.41412553084035000, 555.58908048365868000, 731.25928219773732000, 708.85736903532 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -919.71298548385664000, -841.12826088876454000, -80 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2073.40612847786630000, 2015.11090986864540000, 1664.70280788956600000, 1647.15741676018090000, 1579.88581386096170000, 1588.30674075424940000, 1625.18711444533530000, 1642.37875504738600000, 1644.88913665952190000, 1983.48145328791360000, 1966.85457045897460000, 1876.46956776519070000, 1893.83985857215160000, 1723.44929135957250000, 1673.85877609353840000, 1724.96109872708710000, 1644.90267347866800000, 1852.0010716511124000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1425.79689155613070000, -1791.62841669283280000, -1780.92111912126260000, -1801.75700159263940000, -2019.38853644155570000, -2051.50028519518040000, -2040. [...]
+-2599.17111868961500000, -2461.43078241815240000, -2591.93482333366090000, -2529.20068181705030000, -2413.78632939808270000, -2499.45461662904520000, -2439.89917247256340000, -2402.54094361770510000, -2472.08808700875350000, -2599.96234275610690000, -2425.26433137576620000, -2413.18796914842320000, -2269.20734656007150000, -2300.80200404339670000, -2306.29177806120200000, -2159.97515094942220000, -2153.35217208289940000, -2314.69428326367100000, -2303.46166586320440000, -2397.50105740855 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 817.63520783764875000, 799.44848603192042000, 767.13532863627267000, 723.83174741589403000, 809.15269610221389000, 842.89551935011957000, 743.67012975354658000, 956.24180306811650000, 1032.35907421578620000, 1022.733547 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -268.21375918227744000, -256.02218806210044000, -421.78167182210950000, -356.84611511151684000, -339.0722644976667 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1151.24856523790230000, -1140.82688657298060000, -1221.08004763935150000, -1123.71386884886510000, -970.30907120806580000, -971.041151 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1338.34857889962200000, 1259.36400640498870000, 1250.27701656355730000, 1306.33747531932320000, 1252.54395083744410000, 1169.73051032753820000, 1190.42219049168330000, 1146.11737049126830000, 1186.44747105686430000, 1083.13848628871410000,  [...]
+0.00000000000000000, 0.00000000000000000, -2326.02997987756000000, -2193.72332813844420000, -1968.11932561759320000, -2079.09443104003410000, -1863.33659741684640000, -1795.97656931254780000, -1806.40927681506290000, -1950.24062291057040000, -1948.21541874254240000, -1956.88168199420670000, -1871.38373427057450000, -1820.37738839834310000, -1740.84296810001660000, -1823.58155597328440000, -1710.41653382091910000, -1833.06700218271130000, -1823.56314338137870000, -1801.25317828184760000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1318.48924159995890000, -1706.06638538154200000, -1642.56617671525460000, -1768.82197176892530000, -1652.60979782292180000, -1698.79703631174610000, -1616.82072424982310000, -1264.72919937775050000, -1207.42379734071800000, -1151.49867368425540000, -1029.80235819970560000, -1168.89237603865470000, -1157.35062762557870000, -1122.85530528885560000, -1210.31093770392340000, -1066.885637 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1134.03849012886640000, -1186.30724244937850000, -1098.6552400053226000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1901.68152539679860000, 1798.35179860647990000, 1791.91225732641100000, 1745.94399314314390000, 1855.32094188927340000, 1757.91231464403470000, 1549.51731580486080000, 1496.79569625212250000, 1367.76781427854800000, 1289.52278143830020000, 1597.57662643218010000, 1774.90991454629310000, 1770.50432891440800000, 1857.07337217794040000, 1912.22411661479010000, 1860.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2320.64899601205480000, 2276.38273332695550000, 2215.22734353262600000, 2529.86756256116040000, 2529.87279098202270000, 2154.15189537991590000, 2151.06922905220430000, 2157.42513329776830000, 1931.60253487347680000, 1795.70847217400270000, 1777.66610925063150000, 1892.61285099429640000, 1922.48596553654970000, 1958.37637354873480000, 2017.53786056733590000, 1897.73173385156290000, 1654.68893494272150000, 1610.36202736637760000, 1531.31842944478670000, 1635.0758493331 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1239.09740754375250000, 1143.96728088271900000, 1204.32109211230360000, 1219.38739425242830000, 1354.08391621197100000, 1254.77119364283340000, 1217.58068637823680000, 1249.77870987013240000, 1158.68393120156160000, 1019.55356411566810000, 995.54148140870302000, 981.29090311671200000, 1029.87265926563460000, 940.8928126836 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1444.08725849448570000, 1443.56679985812460000, 1473.34642444562860000, 1407.48787681870700000, 1434.82801406293150000, 1418.13053801462390000, 1460.93957440010650000, 1420.07152919837650000, 1438.04148416872640000, 1449.15890302117490000, 1441.20778528421740000, 1420.76267394471640000, 1592.5552575195 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -644.71297432174026000, -562.85102106114687000, -765.75054644149895000, -851.98782570376432000, -729.20250106045307000, -613.60121172582217000, -560.67225962576413000, -615.73221080942483000, -574.72516169500102000, -686.74954694092105000, -712.35504390607309000, -641.98167116620516000, -590.78743761687326000, -524.92638548388084000, -539.9929 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1354.52897792958150000, -1220.71397882656810000, -1398.67399654378960000, -1474.34686647769150000, -1387.24417826508220000, -1478.17993955299580000, -1692.81858947647520000, -1863.47130272766620000, -1886.27051516917530000, -1873.31837332687750000, -2014.46547726343900000, -1962.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -355.95313554333239000, -289.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 792.79653746302040000, 955.93852359005984000, 952.44382595828563000, 1075.56606861620750000, 1131.42305314355080000, 1190.73244866491310000, 1099.03993153071700000, 1089.16886238457440000, 1030.62979677475370000, 1006.88346138392730000, 997.45612765840792000, 9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1144.109 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso14[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -89.07013828843508900, -117.40136155609837000, -164.01920235152147000, -220.90313284211331000, -295.59998775293349000, -306.76717617229838000, -358.39669191743042000, -405.31508929871654000, -419.24244905586625000, -483.83852105465661000, -584.92129661730144000, -613.98464518751325000, -675.72147560197129000, -723.72343929173917000, -788.20079133860224000, -793.60574643389123000, -845.00883006353843000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -152.53642508275146000, -196.13086916021115000, -271.43765968242883000, -317.64383988858401000, -378.22116200235081000, -383.26596671756988000, -415.92096296521834000, -420.77348160685352000, -451.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.00680076256691910, 36.90957103941837400, 41.85458857157132700, 75.89004498663624100, 120.08 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 59.83109805400017200, 143.05852836839478000, 182.56034882921983000, 236.28358736538652000, 240.20653076867166000, 264.85830467071793000, 270.08951821823848000, 303.1420992849737 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -10.31561952336396000, -72.90111235028912500, -138. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 356.08475119536160000, 443.47248373477709000, 469.76655010997428000, 503.82181051700815000, 544.45392968490796000, 608.33841559741859000, 620.46971653877290000, 694.39322486247238000, 757.67358094872509000, 785.32602168412620000, 918.77167550579713000, 1086.74934324354720000, 1132.24823920046990000, 1189.51682305325490000, 1223.12588663456040000, 1275.64541148952690000, 1278.99758221595880000, 1323.78621265668630000, 1329.213 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -138.11438349596878000, -252.85368684446902000, -412.77346440429756000, -425.38285745394666000, -549.97779028232083000, -566.81906033913594000, -677.8316064 [...]
+-139.01376153796539000, -258.61021684223232000, -423.94390330033730000, -785.49865414445037000, -871.26726431276836000, -906.32344124048325000, -950.68111579048616000, -1005.50326517568940000, -1095.25923114747870000, -1113.21077722802940000, -1208.12294472654800000, -1288.35153162107800000, -1310.47821060937280000, -1422.32858125593430000, -1577.37337916714980000, -1610.21695358066880000, -1662.82948647552730000, -1708.06315922294080000, -1770.37454334785140000, -1776.06768836788140000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 92.34636353954469700, 216.37019855965053000, 247.41901511011446000, 293.56826063149333000, 329.34527718868941000, 383.09083759886346000, 386.36422846247751000, 430.90852279239647000, 437.65446978730290000, 481.728741904 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -28.06988998057886400, -30.13927384735893600, -60.75187385980016300, -64.07290507716950900, -84.78873146148541200, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -79.88650577157243000, -190.91913831004791000, -200.27108774813240000, -272.45169086566199000, -280.27894929389487000, -332.31437909767 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 30.19119520802811300, 169.01794604708613000, 358.66791641211461000, 412.09181106004837000, 493.50490000046074000, 540.42899854308587000, 608.45398518712670000, 613.33497101034868000, 658.13212222987841000, 662.89904845125045000, 696.3162940 [...]
+0.00000000000000000, 0.00000000000000000, -164.81680702090574000, -513.25923894386005000, -589.89270458986653000, -621.95640974592663000, -657.86251939288161000, -700.83764499813401000, -768.49936376644052000, -782.59788094577607000, -866.91706642173767000, -939.48271151161225000, -960.50504167002998000, -1057.62180421573160000, -1177.45698249684760000, -1213.88158938477020000, -1261.98003744644070000, -1301.60844045343700000, -1356.23356904751540000, -1360.27352129849440000, -1390.93666 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -28.38812871569230000, -76.91387452220199300, -136.03282164850108000, -235.96060299165001000, -252.86164021606382000, -357.45863785570248000, -441.30211396058672000, -459.87743003844076000, -544.30773335198091000, -650.80741227252452000, -672.17286173009813000, -720.28918874373608000, -750.61740127232315000, -789.57392999106219000, -793.39344128024845000, -814.77086938656134000, -817. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -88.64174787139856400, -100.95330569944700000, -176.11064460354680000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 55.00489378084641600, 120.83357959111093000, 223.10470547629672000, 241.27262141593951000, 358.03067908758413000, 451.22940543363995000, 476.00518150529496000, 591.29656214658360000, 727.48755833936923000, 759.17171476820863000, 840.38649239903975000, 905.23418299451851000, 995.78896241187351000, 1003.60782660968800000, 1074.62952189740740000, 1083.445504855371200 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 119.50540813004400000, 272.33647090656905000, 606.00665904606262000, 707.34432705116615000, 746.58482366629130000, 787.29778019189575000, 838.79371710240605000, 919.49483630083921000, 931.56957572899341000, 994.08020680963489000, 1046.24833748248060000, 1065.34108853960200000, 1162.14980183676150000, 1301.80582863605170000, 1342.15448425198290000, 1395.97225434761300000, 1413.92491220242820000, 1434.48302311950120000, 1435.36210891626270000, 1450.97266815087480000, 1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 75.83358500071032900, 88.57673088369846000, 169.28815867846131000, 239.19972034671491000, 264.34988445372812000, 376.21126884490729000, 523.78523095282242000, 564.71236506641583000, 622.24932363093887000, 649.81873692614204000, 686.00032369855739000, 688.68101420355742000, 715.35014760658999000, 717.87986324173073000, 732. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 17.22838131004192900, 120.40776027887054000, 210.48120443442198000, 237.48393203546243000, 372.71584330950105000, 556.07880531941987000, 607.08939856265840000, 685.84151706632747000, 738.03756649279069000, 812.45991432479889000, 818.16777825679765000, 865.26941129404156000, 873.42674319301739000, 928.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -24.34432740090350200, -57.30129501177600600, -65.75330078265280100, -122.62843570875981000, -163.01180019432624000, -173.17644122783250000, -216.94147161401679000, -286.88830853084511000, -303.11481446289889000, -340.27682181305801000, -366.09577172034204000, -394.96858893989253000, -396.74626071453145000, -406.76541826591045000, -408.2597152 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -97.98478181659173500, -172.73176651524216000, -200.38723816448069000, -344.27235691082865000, -527.20684542051913000, -580.81697346191959000, -688.53457233727465000, -770.06482803333120000, -886.88124688195035000, -895.83626550750500000, -983.27355217207230000, -994.25995582363373 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -26.81411103068527200, -50.422 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 52.78133926926357600, 73.15525028561567900, 172.46494449506548000, 330.86648404875331000, 375.99703552109355000, 454.91899135161805000, 499.61530868824366000, 561.31498972015083000, 565.57549728394167000, 600.07019003722371000, 604.52732199157879000, 632.629189 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -102.7330 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq14[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1690.96605533860750000, -1404.91640113603900000, -1729.11771079147180000, -1670.48136143091050000, -1441.42672104913480000, -1231.63653230121920000, -1020.48693853453010000, -1063.12952935906470000, -1022.70244380294230000, -991.17642382044642000, -1060.14585049806080000, -1100.46683857760440000, -1251.31276895987550000, -1367.48025629597210000, -1339.81822935231660000, -1383.58183918432680000, -1451.231 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -869.66210902870012000, -925.84447126595956000, -973.54582857159369000, -937.31731174238212000, -896.47301579809471000, -933.92996338389923000, -801.03776758021945000, -848.55851778256852000, -831.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 661.67715904517775000, 401.36149296023234000, 477.79407899025870000, 493.66995611169642000, 5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1061.32491229673470000, 919.01323702312413000, 712.32130548679004000, 695.89730074463694000, 668.41412553084035000, 555.58908048365868000, 731.25928219773732000, 708.85736903532 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -919.71298548385664000, -841.12826088876454000, -80 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2073.40612847786630000, 2015.11090986864540000, 1664.70280788956600000, 1647.15741676018090000, 1579.88581386096170000, 1588.30674075424940000, 1625.18711444533530000, 1642.37875504738600000, 1644.88913665952190000, 1983.48145328791360000, 1966.85457045897460000, 1876.46956776519070000, 1893.83985857215160000, 1723.44929135957250000, 1673.85877609353840000, 1724.96109872708710000, 1644.90267347866800000, 1852.0010716511124000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1425.79689155613070000, -1791.62841669283280000, -1780.92111912126260000, -1801.75700159263940000, -2019.38853644155570000, -2051.50028519518040000, -2040. [...]
+-2599.17111868961500000, -2461.43078241815240000, -2591.93482333366090000, -2529.20068181705030000, -2413.78632939808270000, -2499.45461662904520000, -2439.89917247256340000, -2402.54094361770510000, -2472.08808700875350000, -2599.96234275610690000, -2425.26433137576620000, -2413.18796914842320000, -2269.20734656007150000, -2300.80200404339670000, -2306.29177806120200000, -2159.97515094942220000, -2153.35217208289940000, -2314.69428326367100000, -2303.46166586320440000, -2397.50105740855 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 817.63520783764875000, 799.44848603192042000, 767.13532863627267000, 723.83174741589403000, 809.15269610221389000, 842.89551935011957000, 743.67012975354658000, 956.24180306811650000, 1032.35907421578620000, 1022.733547 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -268.21375918227744000, -256.02218806210044000, -421.78167182210950000, -356.84611511151684000, -339.0722644976667 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1151.24856523790230000, -1140.82688657298060000, -1221.08004763935150000, -1123.71386884886510000, -970.30907120806580000, -971.041151 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1338.34857889962200000, 1259.36400640498870000, 1250.27701656355730000, 1306.33747531932320000, 1252.54395083744410000, 1169.73051032753820000, 1190.42219049168330000, 1146.11737049126830000, 1186.44747105686430000, 1083.13848628871410000,  [...]
+0.00000000000000000, 0.00000000000000000, -2326.02997987756000000, -2193.72332813844420000, -1968.11932561759320000, -2079.09443104003410000, -1863.33659741684640000, -1795.97656931254780000, -1806.40927681506290000, -1950.24062291057040000, -1948.21541874254240000, -1956.88168199420670000, -1871.38373427057450000, -1820.37738839834310000, -1740.84296810001660000, -1823.58155597328440000, -1710.41653382091910000, -1833.06700218271130000, -1823.56314338137870000, -1801.25317828184760000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1318.48924159995890000, -1706.06638538154200000, -1642.56617671525460000, -1768.82197176892530000, -1652.60979782292180000, -1698.79703631174610000, -1616.82072424982310000, -1264.72919937775050000, -1207.42379734071800000, -1151.49867368425540000, -1029.80235819970560000, -1168.89237603865470000, -1157.35062762557870000, -1122.85530528885560000, -1210.31093770392340000, -1066.885637 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1134.03849012886640000, -1186.30724244937850000, -1098.6552400053226000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1901.68152539679860000, 1798.35179860647990000, 1791.91225732641100000, 1745.94399314314390000, 1855.32094188927340000, 1757.91231464403470000, 1549.51731580486080000, 1496.79569625212250000, 1367.76781427854800000, 1289.52278143830020000, 1597.57662643218010000, 1774.90991454629310000, 1770.50432891440800000, 1857.07337217794040000, 1912.22411661479010000, 1860.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2320.64899601205480000, 2276.38273332695550000, 2215.22734353262600000, 2529.86756256116040000, 2529.87279098202270000, 2154.15189537991590000, 2151.06922905220430000, 2157.42513329776830000, 1931.60253487347680000, 1795.70847217400270000, 1777.66610925063150000, 1892.61285099429640000, 1922.48596553654970000, 1958.37637354873480000, 2017.53786056733590000, 1897.73173385156290000, 1654.68893494272150000, 1610.36202736637760000, 1531.31842944478670000, 1635.0758493331 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1239.09740754375250000, 1143.96728088271900000, 1204.32109211230360000, 1219.38739425242830000, 1354.08391621197100000, 1254.77119364283340000, 1217.58068637823680000, 1249.77870987013240000, 1158.68393120156160000, 1019.55356411566810000, 995.54148140870302000, 981.29090311671200000, 1029.87265926563460000, 940.8928126836 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1444.08725849448570000, 1443.56679985812460000, 1473.34642444562860000, 1407.48787681870700000, 1434.82801406293150000, 1418.13053801462390000, 1460.93957440010650000, 1420.07152919837650000, 1438.04148416872640000, 1449.15890302117490000, 1441.20778528421740000, 1420.76267394471640000, 1592.5552575195 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -644.71297432174026000, -562.85102106114687000, -765.75054644149895000, -851.98782570376432000, -729.20250106045307000, -613.60121172582217000, -560.67225962576413000, -615.73221080942483000, -574.72516169500102000, -686.74954694092105000, -712.35504390607309000, -641.98167116620516000, -590.78743761687326000, -524.92638548388084000, -539.9929 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1354.52897792958150000, -1220.71397882656810000, -1398.67399654378960000, -1474.34686647769150000, -1387.24417826508220000, -1478.17993955299580000, -1692.81858947647520000, -1863.47130272766620000, -1886.27051516917530000, -1873.31837332687750000, -2014.46547726343900000, -1962.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -355.95313554333239000, -289.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 792.79653746302040000, 955.93852359005984000, 952.44382595828563000, 1075.56606861620750000, 1131.42305314355080000, 1190.73244866491310000, 1099.03993153071700000, 1089.16886238457440000, 1030.62979677475370000, 1006.88346138392730000, 997.45612765840792000, 9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1144.109 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso14[1000] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 79.60767348818812600, 423.66699088381438000, 428.75735770679620000, 458.01072659099475000, 572.52431128980902000, 605.21917664031776000, 647.60348996680830000, 650.47015481832500000, 664.75769432008076000, 664.63595274225690000, 665.42266136766978000, 642.32375409393978000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 398.06492526868584000, 404.66396849814834000, 440.36520030741156000, 649.88817894482213000, 731.39705788979768000, 863.95968712795434000, 873.73279624980319000, 924.02761310535152000, 929.29392589926306000, 965.51504220783102000, 1094.85943806224350000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 491.41709423796834000, 664.49965494277876000, 771.38358941662136000, 779.84259058141686000, 989.49305369127751000, 1009.39570835785820000, 1443.48438432479320000, 1535.22292618951810000, 1980.56740292848330000, 1987.24981859576340000, 2026.47201387022780000, 2310.58546878765720000, 2431.32818782577620000, 2612.49047910778560000, 2625.88270522561970000, 2693.51833086785110000, 2701.98476441086720000, 2754.57969409377030000, 2929.27931948320930000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 5.87456856942713480, 28.18917823610610200, 30.95834029468427700, 46.27571436222940100, 88.30210369465018500, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 231.32154513628478000, 278.39948792856205000, 518.60601698640266000, 522.24660952468139000, 548.34971810898969000, 700.81328015835300000, 776.54515905690880000, 886.32289198642343000, 893.21359173772373000, 939.90389678978772000, 946.60046438691779000, 976.27436563319839000, 1094.49415619062640000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 8.05985652824735510, 227.23240624151990000, 247.13539479589332000, 663.92065548620565000, 754.01998487723188000, 1150.97314382730930000, 1156.85574461532630000, 1191.46668128898360000, 1367.93985379219610000, 1453.54828168331530000, 1599.84183529700230000, 1610.46784097237790000, 1677.82751488139820000, 1684.92243664531610000, 1735.30868595015730000, 1899.27959269552930000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 85.77683650958303500, 97.13854085385921200, 175.86386616781593000, 481.42140420086452000, 
+0.00000000000000000, 0.00000000000000000, 128.16291578664786000, 206.42529739105785000, 210.75693604149782000, 300.17612126191148000, 309.17683089916312000, 498.05905037104463000, 534.51534635352061000, 703.75594336024960000, 705.14694768920037000, 707.03317061701330000, 727.28058736675939000, 722.57147269785935000, 731.28669961003573000, 731.57922698106267000, 728.16284366145499000, 725.99813116318342000, 711.78756332445562000, 654.99996221702384000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 40.56703811155759400, 179.81302739014095000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 216.86548327463382000, 317.24067639204594000, 462.96942228791943000, 472.47314858801656000, 524.18494610535970000, 534.46212676340144000, 597.52406834170256000, 834.27103189838613000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+274.44493029303493000, 719.76009200489227000, 840.77790656161028000, 917.20123103907827000, 923.03631320420720000, 1065.31313024117780000, 1076.68860505147340000, 1344.00510963770220000, 1404.80784786194270000, 1675.09443554651690000, 1680.06817601227950000, 1707.83665142794100000, 1821.72806503675410000, 1866.60974751688150000, 1932.94478997574610000, 1937.97112934557550000, 1986.84711425569690000, 1992.72408177806940000, 2035.82160889620010000, 2238.42826429735400000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 11.35493890765310900, 82.27522370356142300, 359.33076637187162000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 83.53610240734229800, 89.83201493987378700, 255.09165910977774000, 269.50125697920026000, 562.50322490895564000, 628.24598963226231000, 929.31830861848334000, 934.72094342255400000, 962.53051306537236000, 1135.97775502594780000, 1199.20080995899370000, 1296.36525010448240000, 1303.49770893517330000, 1333.77666914057840000, 1338.20884366480000000, 1363.04112659376730000, 1465.88650145576370000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 75.48378838894376500, 207.44661288813933000, 216.63921810767764000, 280.84211088415680000, 290.79291133554227000, 359.61332394636179000, 662.50953704995550000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 13.63726456822152000, 329.31643771180029000, 400.82570886701177000, 672.43051219220524000, 676.22949365183445000, 699.06972031277348000, 828.43086742999344000, 889.94487388525260000, 1001.22597240115230000, 1008.14724200161900000, 1045.83693446853360000, 1052.16912206226740000, 1089.91975144290680000, 1247.04291437303440000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.93935879137145670, 35.43258312478705800, 228.46338466791613000, 319.64757971565683000, 461.68978138302163000, 472.12047805284374000, 541.94617693018063000, 552.90865120332626000, 626.87615674377378000, 911.59072745975993000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 36.85245101239993900, 257.44722308939845000, 366.39721028509530000, 527.50392946074624000, 538.19126004714110000, 607.61947967141043000, 616.73250001822635000, 674.69323961340911000, 838.89704529917742000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 142.92480434720056000, 152.50274909987814000, 218.58341693385836000, 227.55953445539734000, 289.08379573299646000, 515.17113680183195000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 239.71554954441768000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 161.43879460550798000, 177.14528764474645000, 528.74053977570247000, 606.63612376440346000, 845.48800292629892000, 849.04656322485198000, 874.68544879433921000, 1044.30164542045050000, 1130.52231949580100000, 1286.14541275360670000, 1296.61013930557460000, 1355.67625571952680000, 1363.62995862002140000, 1421.85427597411940000, 1693.65832860450000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000};
+
+double nnlassolsq14[1000] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1047.23876457722080000, 1042.79555216964350000, 1032.37865574060560000, 1037.32580094733230000, 860.41195577942392000, 761.42889542277112000, 733.82967712344328000, 730.88075980938743000, 720.09051108295250000, 660.94351473395352000, 668.30342055806443000, 642.32375409393978000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1114.37560781462980000, 1187.18577458205850000, 1147.36964284079270000, 1176.62984845957090000, 1120.83065615569380000, 1133.64366172996530000, 1147.87074324970310000, 1118.80949873711050000, 1089.02188303132540000, 1098.14904458386990000, 1094.85943806224350000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 2335.78437790753110000, 2396.41393583561510000, 2422.41535776225830000, 2733.55243517554660000, 2696.73474924073120000, 2722.66558544728200000, 2668.16871767291010000, 2650.30469494202410000, 2781.95678905847810000, 2779.65802007823280000, 2803.20337297596830000, 3024.84791650607260000, 3008.21345662165320000, 2981.04507885977000000, 3001.53771203340740000, 2955.45774176808620000, 2958.77280320411180000, 2947.17110870126770000, 2929.27931948320930000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 170.65756106999717000, 114.60925131234217000, 114.94738839977987000, 102.36467117853006000, 88.30210369465018500, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 883.94366586598153000, 850.63177602673727000, 950.85335117510374000, 953.95207790990969000, 1065.27904513150220000, 1084.10733094132460000, 1138.37737273281210000, 1109.65352075693360000, 1086.49929638529650000, 1120.72622058675300000, 1149.70823711986490000, 1084.93386289652700000, 1094.49415619062640000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1869.58236237525010000, 2012.01508613623080000, 1960.43401377462710000, 1839.78726384877040000, 1849.17712972162740000, 1865.28322285367310000, 1854.42101779881340000, 1876.87961379648500000, 1811.59416852857910000, 1862.56872886712790000, 1897.45985346644940000, 1908.52973144533210000, 1938.69821925681300000, 1900.11234345689700000, 1919.81238409921710000, 1899.27959269552930000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 417.97357174872360000, 441.74052244292091000, 464.13921626451946000, 481.42140420086452000, 
+0.00000000000000000, 0.00000000000000000, 1410.59820694416070000, 1415.34110809123670000, 1211.20189517084580000, 1028.34127351513080000, 1083.98024040739530000, 1030.94808397682800000, 977.64154151637729000, 1008.30135759021770000, 870.09377132891166000, 744.38672739893946000, 778.18268016574859000, 700.07223710667415000, 749.01686267893137000, 739.78468666996923000, 714.93186626381748000, 660.34211742869229000, 659.75149484909321000, 654.99996221702384000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 189.11487919519857000, 179.81302739014095000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 762.06624102964588000, 796.81386078998480000, 759.43840176447748000, 739.05484580175721000, 724.45451779432881000, 846.17036283399511000, 828.44344801735247000, 834.27103189838613000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+2466.52296926014560000, 2391.09941823851480000, 2051.71724337138720000, 2097.70920144660110000, 2270.71995196199620000, 2223.91259504795380000, 2055.91769064647680000, 2098.17897626275860000, 2143.86499337508670000, 2161.47029490330120000, 2269.85979230057640000, 2257.74584184857890000, 2108.05156872996350000, 2081.04571241664010000, 2067.89608061105900000, 2078.96109871871250000, 2176.13414417461720000, 2170.97327684397850000, 2193.63556099782180000, 2238.42826429735400000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 355.75172391740085000, 341.97018014820503000, 359.33076637187162000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1373.91486285660080000, 1543.95006692710040000, 1600.84664067965260000, 1509.91518086178690000, 1389.14289470552900000, 1427.34914606179630000, 1471.09253844579920000, 1575.37132219532050000, 1513.25350737148600000, 1572.02486736271980000, 1501.26829137484810000, 1494.03553289087860000, 1503.56481107522560000, 1451.04109781355370000, 1472.63727777246910000, 1453.97165024038400000, 1465.88650145576370000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 436.13067377786274000, 475.91035123715966000, 474.49389782581602000, 529.48722582579023000, 592.60199296969643000, 611.61899632770405000, 662.50953704995550000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1187.56682231031500000, 1219.93478165283610000, 1270.02073792618400000, 1161.17847691506200000, 1126.71689458230570000, 1151.38301314328490000, 1153.64534770323760000, 1183.84685349406210000, 1227.61503180891080000, 1202.29043791283080000, 1191.80166456530650000, 1244.22520154417930000, 1228.15450446139150000, 1247.04291437303440000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 590.65395830540581000, 639.30096464371491000, 713.74365002990976000, 755.30795981232029000, 750.65889528053947000, 764.70390623242724000, 812.36730863339028000, 885.40193242026248000, 897.72938561791511000, 911.59072745975993000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 766.65490497843507000, 812.02342893432933000, 886.93909595237460000, 855.25769092486780000, 837.97332830560094000, 876.50125278356791000, 893.13160129885944000, 886.93310565436900000, 838.89704529917742000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 433.68947556023357000, 421.16629089002078000, 474.50078355786360000, 499.80635510576298000, 514.37251811693113000, 515.17113680183195000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 239.71554954441768000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1476.07954159656110000, 1529.19916435831460000, 1520.68808598895980000, 1553.45677086179630000, 1275.29766896094090000, 1271.02455837568030000, 1382.42159907835180000, 1470.71749330792070000, 1542.46796007738590000, 1602.74334514844900000, 1590.14811346554260000, 1584.42765101932630000, 1604.86680983785140000, 1635.05930755013420000, 1693.65832860450000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000};
+
+
+
+// Data from file x73.txt and y73.txt
+double x15[5000] = {
+7291.45140983226, 6622.62068030309, 12987.1667775661, 4798.76901673982, -6539.47392526016, -10864.4737494892, 374.16697771781, 5024.4775666281, -11584.1520888260, -4412.29153459236, -7348.94992891172, -7715.9460926703, 2945.79906268659, -14649.883504714, -18310.4761933343, -8444.42018548545, 825.603200283476, 8500.25526319582, -6091.49683444171, -19784.674685309, 6082.64465631327, -2406.21687863464, -8003.88292598539, -12201.1584507117, 7264.95159046758, -20902.1189188003, 18464.90739699 [...]
+-26004.6359246041, -2707.1621895317, 11600.1333164601, 4719.69038677071, -4847.49008464375, -8008.75914586346, 11058.726369781, -6791.21285059282, -13174.7840689101, -17826.6235182912, -6066.69690305033, -505.106287860377, 8494.69597142494, -3894.50976297165, 1324.21046756263, -4058.83708677966, -1834.6671956438, -2093.32730129065, -8487.54609064786, -4566.01511091045, -2391.26758591523, -13535.3533793224, 12174.8241178100, 1373.35308566381, -8780.41560543405, -7043.93774824621, 315.2073 [...]
+12366.8605903672, 16858.5261145397, 14713.3647793668, 20622.5431134695, 210.892640391990, -9798.99995231465, -11405.0365016676, 472.703818096153, -791.831073870795, 12090.9672126360, 5212.06747855458, -7990.64320008065, 8430.5074543645, 2951.04372712241, 2070.79034155941, -1599.67284051167, -7288.89783451665, -768.008226511959, -11557.8722810839, -4800.33500737444, 2963.50528761841, -10552.8118766354, -1566.14405013543, -26039.620486728, 5297.0499277006, 28.3132116136701, 19600.399848210 [...]
+-12180.6577279158, 9584.64506061258, -3341.84495958645, -11031.9013080136, -24372.1720130485, -5461.50438760016, -9953.62277802568, -1921.20171009100, 8279.15916804866, -10233.7688651309, -5402.11439242197, -10713.3170146366, -11510.2315533126, 4816.17570119801, 7077.90747846902, 17298.6373749023, -21335.3744336262, 7718.27213023193, -4589.28613977854, 24089.6263694951, -17071.3481020974, -9424.83110718188, -8851.91310631179, 226.45920823304, 21465.3176464067, 3571.43759600196, 8542.0549 [...]
+-10558.4096016568, -6631.358415983, -8804.70148938109, 3463.28260442808, -5050.48748199817, 18093.5051808182, 5558.46156530454, 13962.6045784852, -1166.39140521753, 18947.7947670183, 24133.25263685, 9165.57658132472, -1379.73086815171, 8956.51366287442, -9985.87761742088, 15025.6206439012, 8455.04861207574, -15711.64790181, -1097.68408106888, -13321.7295615866, 23732.379870025, -12766.6658280000, -12827.9789328744, -2302.07117948156, -14196.3492199785, -2738.80428575258, -9395.3134585789 [...]
+-264.398904638569, -5942.93590992186, -7946.38692255142, -331.800312942852, 6137.42414560969, 3254.84477934751, 7503.55805573385, -922.879470464359, 7819.84409899994, 16592.9106870201, 16894.8202238995, -1037.26799859534, -3930.52589236553, -506.751293447655, 6228.26046023357, -11072.0023191554, 3856.24302874022, 578.364862239634, 6282.64150293593, -8567.5032663004, 7803.04380418827, -9305.2303634892, -1221.40872510512, 6228.75312136133, -9003.27303735156, -7193.17668454766, 686.71170335 [...]
+10160.9343131864, 10997.8612039428, 13208.2992133192, 24618.6359574518, -3540.38324602564, -7250.42011443666, -3123.98603077347, -2467.93086480065, -2488.19957472552, -8473.6324981986, 18547.2136769479, -16816.3747022731, 18040.2233575862, -20455.2795589503, -8249.75552244471, -10718.4671037933, -9083.98289360694, 5424.68346107421, -14515.0375837958, 17912.6389296060, -3990.75007130891, -10320.7250470854, 1331.38722220091, -4590.72913538366, -12953.1073030211, 15354.2930871036, 8855.5758 [...]
+202.206070658311, 1818.45610273202, -865.645415293958, 7127.37780249391, -803.523281767385, 6983.23885890474, 160.906783020521, 7916.74094178212, -5872.2315840333, 8778.57883383119, 1468.03025664918, 4797.53473730753, 2424.50860056887, -8852.71268233097, 3075.82892226838, -8641.5684232314, -1493.20693851255, 4665.04664139172, -13986.3506793208, 8893.16420552472, -6940.045601836, -2719.79283427602, -10592.2825301373, 9982.19798114756, -1044.75593282774, -3800.59317286891, -1824.4876059586 [...]
+5840.47315792677, 5655.68890356299, 7280.85895972351, 3554.68749165884, 7147.92549379303, 1464.11040019603, 16072.4351920816, -9273.30588730655, 414.480939778826, -10487.7153851870, 7650.73377672629, 4695.88596002788, -8640.83086130745, 10588.0643469302, 1263.07008941012, 3927.33084905864, -3169.12824772801, -19360.6257790664, 352.332860012752, 6971.11326480683, -6474.9971947103, 8070.45383720252, -10224.8978050903, -4093.49581380244, -8422.5946890127, 11079.8540462570, 6345.21518657336, [...]
+7563.22397020016, 679.980563389467, 3707.15668317594, 600.429695050672, -152.302489859028, -11716.5626773088, -4682.67789627168, 107.951190103100, 2460.9466003068, -26887.740730963, -12434.5621612242, 16474.7952370463, 2767.25712713547, -3104.64504796705, 13698.2849332937, -13825.2871180089, -6512.69172918254, 12556.1238236112, -20781.7953267559, 13886.5036161572, -2977.99631641165, 7417.35195363154, -2943.12806863559, 26953.8074324744, -1887.2915443073, 1444.49840132658, -2730.761833909 [...]
+-4438.00052636281, -2586.05822612807, -1183.70738675562, -3337.51788833554, -5236.90494535353, -7893.19564018678, -10429.3203628089, 9532.63252348166, -5483.56819273238, 4564.31205963738, 1126.29696433201, -13086.4130504577, 3830.65140987828, 3.41747354650561, 8163.57701860737, -10108.1875234653, 14970.0754844412, -5978.65848264896, 6341.47616137759, 7994.40917119671, -9353.87875489874, 13677.8898804065, -9292.14358614433, 3591.08196663331, -3774.29630215961, -7326.80886861406, -9384.337 [...]
+4859.77339106664, -961.402317075096, -16846.3609867842, 1136.39329017044, 16125.6913752239, -621.962152482889, -1183.78013185512, -9670.55485726522, 3222.90569070919, 10279.3305189846, -6542.93953140624, 652.001096748445, -9741.01265539052, -6042.82300098132, 6750.00289785795, 598.654932718063, -17218.1167441001, 7361.88685355378, -12817.4072173205, 14785.9007481219, -3271.6184997309, -7974.25870507757, -1163.61188365879, -5105.74051137943, 9874.65332090048, -23938.7148004738, -1734.4540 [...]
+-2234.65241725244, 6852.45575607044, 3914.07444791992, 2726.04467633837, -1791.66098861018, -10208.6319943744, 10997.0785422371, 19419.6235939134, -19118.1473956784, 6394.8146817315, 10290.7573480323, -3266.30955577048, -9114.61231005712, 6521.18793121499, 18654.3513847686, -14213.7297130234, -6346.69521990779, 15356.2299972572, -2710.09651445034, 15738.8287749543, 8269.83245752706, 2154.84369995413, -6170.9189547802, 15157.3204434888, -11236.4507713926, -24119.0133273742, -4101.41251768 [...]
+7243.08048300291, -20392.3243050407, 22261.2703467019, 11743.9196294514, -4999.66745014285, 14401.8147186514, 13825.2461747126, -11744.1422192592, 5785.17111081504, 4872.56958603504, 12626.1819217559, 140.157611672719, -15336.5801170211, 11887.0885029720, -15611.7206497561, 0.259710009127833, 12811.7536146616, 241.606410006681, -11791.6907967219, 915.797257376767, -4576.92837339609, 3462.78370512673, -2236.25442911949, -9349.65822692376, -4048.97277216684, -3801.6282405936, -10600.989614 [...]
+-12258.1315994626, 3761.85992519452, 17833.2804275888, -6203.34496611567, 17974.7777614184, -4291.45400151189, 158.92745350111, 11959.9850443279, -16108.4524652636, 10981.4032532411, 18271.6604120209, 8671.51388696226, 2055.23787339797, 6613.26871936975, -6399.69506359853, 3290.00028518378, 10859.3506535327, 8550.19469529587, 21045.4030030737, -7927.28107609499, 27806.8554700648, -5166.9142594201, 6736.35444804376, -7769.17134313098, 11734.5815598500, -15969.1138729752, 9216.51384158682, [...]
+3317.52485313840, -11833.6201113485, 17303.1861959066, 8434.7679400501, 13946.4432402459, 944.940390002554, 9357.70973842466, -16293.1225297143, -769.769754219064, 7787.59268197312, -5670.30122299929, 2515.82584759299, 21478.4021821799, -4784.01549049938, 2334.7175732188, -13028.7359045996, 9033.78040541845, -4589.30414681474, -11963.1625033179, 22896.5114456150, -3411.97498358400, -3447.45876109356, 4582.13092804575, 2334.24841173876, 11914.0816792468, -17618.3263932333, 4409.1385636141 [...]
+-6096.66586510937, -5587.55418120549, -4699.17257551875, 3496.87207353829, 12600.9885205008, 2028.96635243692, 1875.62413651027, 1502.91480783889, 4063.61237807199, 3580.28177786806, -6648.62643153084, 7578.4000229026, 6680.8290041029, 16192.1148802065, -4051.64863125333, 8185.62283011796, -5698.01075806092, -1445.00420486735, -3624.57410673399, -1458.51625709093, -7373.11452052935, 19274.7899242261, -8584.39455953977, -4110.53359305329, 3001.0679844804, -4262.00753257885, 294.1470845271 [...]
+-1757.23908375964, -1376.96655585677, 2780.96591081344, 4510.53410426834, -1467.58799706051, -3882.32741093034, -5420.17001832085, 18592.9308550572, -120.497389249583, -2043.55241320362, -2542.77690132627, -13584.6359408762, 7032.62471342074, 2778.28592170457, 1763.49949461390, -3479.88240691706, -2488.62531198073, -1965.82230228904, -1845.25868714619, -1173.42989562436, -9398.62161609047, 7218.93905627877, 4110.88515604375, 8939.45353221824, -1974.81218896572, 2584.8349131834, -13921.37 [...]
+-5177.1160750199, 9388.7100876094, 96.4573851854674, -9302.96556840152, -6213.06998158497, -12909.8736814221, 557.676502688686, 2141.70989347262, -9901.17866116246, 4486.26996687731, 4516.59024337044, -2669.51728471778, -32755.9767021453, 12837.1753802492, -1369.60608948666, 7084.20272756718, 2166.46664686065, -7595.01832632177, 7995.79208459396, -6390.9458152662, -297.907470373326, 11832.8434256706, 918.405879452048, 3207.37327415713, 12467.9715735270, 4756.63380468281, 4187.32873769172 [...]
+6432.65101017326, -6413.15985869636, 8638.03427179795, 348.984841541863, 10094.9727397827, -7788.69304638197, 4927.38705876511, -13439.8908528696, 14806.4866628519, 1952.00620410127, 3403.96581131000, 10980.4818551478, 2136.54867510283, 9026.0825423183, 15131.1736954947, 5295.17147332475, -3231.63868866966, 9360.98946965997, -10379.5596494407, 2920.8011871609, 10085.4401302594, 5965.10929855064, 6367.61736471166, -218.139531031515, 323.011053675171, 2703.71381098943, 3451.47633895586, -1 [...]
+1344.81370356160, -6377.157667392, -7047.57609939867, -1595.34319130916, 5287.60145333727, -24152.3802459909, 20164.9020954001, 4644.63130693578, -15884.6639878885, 12484.4115429357, -15136.7326389481, 7279.00680768979, -11701.3218202733, -6663.69509234246, 2186.7783577066, -16133.2040908301, 17335.0131028321, -6216.68454493831, -14430.3781710640, 19616.1460963230, -6919.72000972892, -15532.9491102552, -13379.2336723730, -13270.5975496356, -7451.63577772112, 8469.9220903351, -7413.164430 [...]
+2661.71799257509, -14247.1446411443, 4682.39612972827, 9623.34463731508, 5128.18328711723, -7818.65461332643, -9400.47120555465, 9272.16602055922, 6255.10240134176, -21411.9285685372, -6439.11418641726, 4287.53133456935, 6269.28440837851, 7234.1207750307, -11070.7617137206, -12908.2323384461, 934.866725992767, -6668.7579657424, -5035.70888634752, 7098.30814897642, 7105.56783450392, -14552.6088602471, -7550.91884718103, 5120.18888594803, 4693.45826904972, -9675.28050447973, -3404.66937741 [...]
+-7051.7363617607, -19834.7281344072, -3016.47946203773, -2751.45407692576, 20315.3184285244, -3931.20796538296, 10227.8729671932, 15065.4055406312, 8135.0401559471, 2452.38464853953, -16964.875854264, 6466.77882373749, 11252.3754609028, 7258.20285765948, 18535.0294212659, -4592.02911082169, 1848.00658309345, 3852.77306015085, 6290.13273771691, -58.4578945361454, -3150.44932773696, -7235.09737983844, 6892.13009939746, 3026.28500781771, 24496.6696983201, -21616.8119734594, 3911.80569512574 [...]
+-3268.71924330888, -14002.3671670108, 757.679543605269, 5828.96261781844, -20716.1401105689, 375.713641402841, -3735.04926026127, -5058.06195618176, 166.999858246714, -5858.00301853023, 389.162118913713, -3097.97475694744, 5460.84302893852, 2154.07567231657, 1944.30384634413, -6468.0659128014, 3647.88342880697, -3534.81166233809, 8939.27545390523, 21185.3383978858, 24381.1905592410, 2037.13168359459, -6103.14086297192, 4916.93242522787, -13345.6820627281, -26478.0055099053, -1854.9656932 [...]
+4238.7384732427, 13884.4064521700, 16243.0430041771, 6330.22676402984, -9801.77563167077, 4555.14428587001, -8815.58490605877, -24992.2560263135, 16960.9819989795, -2586.25871482901, 16092.9543308582, -16341.282245513, 7381.59558126093, -13761.4223807628, -11832.0528561281, 4612.66486716646, -7257.28024462978, 10486.2088735524, -125.145481761115, 3502.37396918971, 4951.23425725617, 1326.89473602601, 9235.50757472949, 15168.4352849701, -21748.5957315145, -5710.14329779738, -10927.77142643 [...]
+13160.5501333155, 9306.20619829495, -17456.1902559935, 13559.23241312, 9469.3311905830, -11293.0626368582, 727.688786988877, -3688.63221550666, 19792.2021299816, -2465.89450689766, -6877.03947127949, 4251.90274368326, -4352.02473738313, 11719.1687505787, 5773.83146310607, -7414.8389677214, -3404.02551838910, 985.770332071252, 1504.47855541521, -3638.24213265253, 7960.92319336133, -1769.21137441704, -8123.58617847458, -32067.3926562057, -2375.87775569498, 568.14012195827, 2271.77437228082 [...]
+8664.4260259479, -1196.97543237091, 1044.13983069842, 193.544945732252, 5318.36125340932, 11010.2577292574, -3474.60357805457, 11536.3075547902, 9072.99002119939, -5672.09994636627, -1140.49581029270, 18148.0974999493, -7688.2653304344, -2540.3188658519, -3797.91741604458, 15810.8351452743, 4563.75486419013, -2650.5991900317, 428.686019621562, 11043.4507598891, -1086.29326702762, -9217.23918721979, -15015.0583300111, 10969.2684862834, 4112.90348818796, 8450.93456740662, -3227.13574896690 [...]
+-5509.49985025418, 27644.9748092514, 14731.4301017978, 13339.8245711828, 15307.2729519533, -7612.54836858974, -16135.8742848068, 6192.10272482286, 4370.56997478312, -7601.83930018111, 9016.9657940134, -4066.49667973916, 2398.63010064089, -3266.07849757983, 9623.3932812406, 9375.3929425418, -3331.4082617979, -11571.3414829070, 8976.28804800785, 6310.84277636032, -14946.6740880594, 10066.1786325466, -8242.65648861207, 16335.7785483273, 21321.9569006113, -9636.33306045021, 3983.90482970807, [...]
+628.307140387794, -575.536908490581, 5950.07131371647, 5343.01250110547, -9977.96849890927, -4583.88246796735, 7100.34878972023, -12455.9051292681, -4309.14893076837, 6358.32660338852, -2628.80386427373, -16458.6684035298, -25710.668608006, -8210.702500206, -881.752532701001, 6140.68107585242, -1995.14932296170, 6716.6780689934, -1462.52411708608, -9642.86430156636, -7999.8045040025, -2927.82640701009, -9214.85762497139, 8185.63875933501, 8196.00514790319, -5635.36429716922, -1076.479196 [...]
+13699.684419196, 7562.70246736993, 5787.88239556281, 6036.02509037322, 3571.50118501942, -6140.74856645915, -4379.44611617697, 3058.12186791228, 26614.2454855662, -8681.26595727595, -3189.49486001327, -4750.62653877515, 2731.17741780247, -9352.23625004628, -12082.2166476917, 2880.32896622362, -13321.7050273630, -1849.07381972795, -7441.35173441012, -4079.06129479751, 8136.00978412619, 1080.22515098768, 371.731030254517, -6616.69813856598, -1703.17938666513, -4704.43324956357, -3661.58759 [...]
+15802.0186407304, 7811.45551568984, 18849.9836193224, 5046.09734726585, -1909.84833779465, 20590.4324175206, 19720.500020293, -7961.5954451291, -2621.67723865666, 5647.15733168212, 3080.18879001117, -8394.45046222972, -4988.08726414877, 11227.8121526461, -2141.5791160566, -13338.2819728889, 16494.5452768863, 18613.9077125971, 13082.7430694805, -6442.09274162345, -3886.60088738289, -5952.68448886213, 3392.31463527854, -4470.2839593595, 3599.60190732969, 4000.100275695, 1673.98898996356, - [...]
+14186.510397939, 1802.0847715883, 2816.70989460172, 8632.72166555251, 3314.87096649812, -5256.76202124263, -11746.2351627036, -3896.60478512186, 13726.0222506299, -4216.81202878443, 7730.82967069769, -2221.77879662341, 2224.42363373846, -7016.77212898383, 1353.78448180851, -5453.54415273402, -40.3102310431356, 5543.04213701515, -7749.32755909223, 601.888292849277, 2528.82395484628, -13911.3287665344, -6460.04672371992, -5328.5886589158, 6149.16620097072, -9813.5008800729, 15314.308963211 [...]
+-2925.631798976, 328.283623227727, 1951.74577192414, 619.400293729038, -6123.40828847052, 8615.26702429828, -17253.9483721034, -6113.36969215071, -14339.7730724913, -1930.72993966083, -5695.34519938462, 12641.3917197104, -7746.83970430335, 4571.66088877931, 170.587867917791, 8161.08443921098, 5171.43758350705, 1821.87479974154, -6844.669147506, 637.82685810739, 6926.29907487787, 9959.74632370676, -17617.5441615254, -4635.61171008777, -3741.92078243487, 14899.4744488432, 285.163584317484, [...]
+-5624.49839720222, 3592.3715435305, 8268.817889251, 19590.4343666218, -2369.69157476633, -5698.45638880328, -887.745582866976, 3983.70167295026, -11448.6215295593, -2170.56315539516, -1338.52937041696, -9387.91816049272, 6273.69780199295, -20487.7531272322, -20817.5343666171, 14778.9952303341, 16204.1521961331, 409.09189428954, -13132.3028077153, -5108.78249700011, 1163.92936581323, -5407.80255506982, -13386.7134260179, 6945.1741184465, -14781.4377029151, 4660.34649104855, -5268.87592616 [...]
+5954.35625821977, 19107.2519283331, -6746.74628829619, -15330.2908461281, -10773.4929630350, 1470.43587486840, 13788.0648730199, 382.611780864212, 5888.18929107815, -3256.74746976554, -635.820010630282, -1225.73147217325, 11152.90447872, 2553.79116067341, 7149.81517145616, 7757.00963156031, 4991.31838881318, -9330.30470359834, -16948.4869069024, 12426.6697264584, 12877.9165297576, -5993.25049720641, -6370.48811192767, 8891.8610775017, 18230.5100205882, -19524.9049133332, 19410.8793723594 [...]
+10442.6631493735, -8260.11345940676, 3158.34237940675, 7404.06912744917, 2691.05484300086, 5587.78794656130, 3150.20973010148, -8492.58829867591, 3441.75836806898, -690.932265187988, -441.3735811315, 3520.15009927272, -3379.80770881453, 3936.95491084373, 4835.51037527078, 2845.36173151446, 1637.79129413171, -6776.17319100992, 886.781189587336, 7289.33884746712, 976.37530442843, -2850.70377478107, 10816.6935714928, -10839.3119166186, 10381.7740030543, 9827.35938861073, 1951.34744265096, - [...]
+3330.71316935769, -1109.3924337905, 982.50177070297, 3754.22903329996, -1522.62969419461, 10844.3070552332, 7046.88195787622, -16347.0823480254, -8567.67345648223, 549.490279100184, 7541.11284529248, -6269.45892078076, 5521.37183265365, 11206.7897915744, -9637.5043402041, -95.7609827839923, -7348.20821977248, -403.738613270134, 15339.2023034289, 6045.68125334575, 1577.61681410221, 4804.05507953466, 2983.68291450562, -6633.80407774385, -839.042208583016, -1111.61421494106, -194.5807478473 [...]
+1209.48827173325, 303.808669590862, 15035.3632399638, -15636.0413405191, 7856.65860315653, -2970.86668642623, -7056.32369466989, 8833.63268967482, -1889.39438298605, -6919.6442543547, -65.2907518902337, -9216.85410877533, 4239.36843948845, -2070.51563065847, 4081.59861698479, -3307.66385934276, -8256.79127991405, 25446.1286524516, -7937.6859137617, 7005.18615194405, 10984.6139965160, -6627.07751597656, -2546.18413375086, 3652.98015692649, 8939.49209357824, 12265.3246917721, 10647.7604002 [...]
+7864.23821323877, 8804.21939192574, 6803.50808709537, -8945.94859240918, -6820.1161299064, -3691.35503970363, 11331.7397356003, 8723.4355528434, 2152.97791135293, -9764.61010146868, -12773.2355904760, 9573.9314072544, -3155.24990686913, 4867.05086613853, 13004.2535509861, 627.975846756549, -4349.18759255865, 5585.97391086752, -1762.90810175944, -12476.8563395042, -26015.7287090758, -6932.23843823323, -3143.70959506197, 15114.7710518952, -1724.89334884645, 12140.6375960392, 7527.401092235 [...]
+3952.99675508656, 242.415351280130, 1818.94690133287, 421.585690407237, -600.271412677092, 27358.1524333624, 6991.65130339953, 4720.67738881656, -9648.15688496111, 16069.5102647897, -4808.1100398651, 10453.4721646490, -2852.47674624748, -4819.62448547128, -7360.36617368962, -17138.8472444456, -3813.06887414841, -940.047221343973, 17170.5825515548, -2819.48019674102, 3525.50797931427, -19875.2934847853, 1791.2636363143, 8597.68904129808, -11016.9018507137, -297.925027214006, -5685.7190034 [...]
+-13260.1432169921, -8268.05118802023, -5386.76617687441, -2560.77689215084, -12717.2016777157, -2231.25662992486, -4555.38878372856, 8078.91506405164, -3272.21035135203, -6420.44094241267, -4444.73771628224, 12366.5750615865, 17536.7077776585, -8694.95425235546, -2905.15745979445, 8592.36168814046, -11822.8991888144, 22754.8417916077, 27378.4185082629, -8949.24269002077, 18055.6004717703, 11543.6292673548, -2618.23721465923, 2320.55241804255, 3982.44155831544, 13734.9607275688, 11336.069 [...]
+-15522.1592386937, 6951.84757980653, -2691.43100658694, -3131.65850583870, 7584.18475232331, -19319.3708976345, -14781.8747017879, -16005.1938097681, 10946.4624237287, -11834.9030393280, -12556.6173091342, -6983.3128217815, 567.728574497759, 3164.66024238394, 14553.9783855755, 20200.8656394035, 6000.32315839578, -12181.3441606183, -11879.1145142067, 1995.56331840037, -17017.4931314107, 14710.3109319784, 10164.3125855325, -16094.8002270674, 1218.93513367586, 14206.4988366860, -8347.015457 [...]
+-3720.57241638858, 7787.24582924731, 4883.73823531322, -4349.8219748501, -5847.43926575588, 765.849952782489, -6950.22769609174, 16505.4183619854, 3149.98784477821, 15079.6802479598, 643.778389200478, -11645.7400592695, 7744.05135504045, 10831.6548374732, 18308.7701535116, -11059.0059180306, -8933.01581629336, 386.427574363463, 4429.71527541285, 775.618217380446, 2319.33452142721, -6437.01695506613, 5916.25639233664, -7717.22329671842, -4316.27571096498, 7149.46180555142, 15383.025854252 [...]
+-15496.9930130937, -5226.25177518521, -2710.01158427606, -9928.98987734558, -144.33413065101, -5903.43375908592, 1944.97232523026, -1583.43619563753, 11909.0491234878, 9646.42022101402, -6627.68571587485, 41.3589798973035, -1525.29453127288, -21755.300961344, -11124.8464158859, -6543.35151713794, -11387.0838702268, -7781.98371995486, 13435.7675685684, 29866.5001493411, -14301.8451445268, 9426.10801073578, 6113.2038533481, 2886.25386487443, -7533.91601285681, -16819.9052344007, 3867.72356 [...]
+-5951.7701320118, -2231.45563048440, 4623.61213902386, 21939.0895129243, 11276.2659477329, 7707.64725670599, -20957.0555177611, -1522.28334386336, -5927.97999784433, 6356.41931738543, -2439.53259334427, 8432.12967796679, -257.849190440445, -8775.30929267676, -2136.54668857616, 4019.61440239498, 403.61876530394, 14503.3822764980, 8225.12112472255, -3461.43593549783, 1481.90030281427, -2807.83346588993, -4221.38783637475, -6119.23753835609, 7062.57719207731, 4349.42359705413, 5683.88447409 [...]
+9408.47995716797, 27511.3481664366, -861.607160781613, -1730.68449899149, -9458.62123804296, 883.27712363041, -7240.80862473004, 10501.4752025905, -8478.56714667933, -12620.8930084562, -171.876761989484, -616.091759844737, 2866.64957373867, 3901.01142969559, -13966.9438350689, 16400.0823873793, -6350.93830940548, 4156.65028146358, -8638.11660244567, 14797.2693181026, 18299.2219126706, 8990.94759431577, 9416.94626177066, 2445.19910710596, -2520.86701928531, -4380.77498132151, 12128.558755 [...]
+-27075.590457322, -18579.6272197589, -5827.09454064009, -12525.6065643138, 1561.66997244387, 7377.10755386525, -10017.2207209638, -6968.95245156525, 6089.19223077296, -7079.07049006007, -79.7643596368071, 13315.7994844737, 5245.04502190668, 1095.51248412430, -10725.3873943794, 5880.88180586605, 2647.34222650039, 6948.04186628547, 894.103546606713, 21347.0476150897, -2297.17988114142, 8702.47365883635, 9130.5558398182, 20921.4747768939, 6129.95126880481, 2958.94460068988, 2632.87587084248 [...]
+-10163.3261874707, 12142.4964942033, -21321.6998499412, 21015.1512152096, 5711.41900324397, 8460.95066986489, -3095.4546670992, 8771.87551934123, -8751.61257971452, 16180.7822014671, 2079.89437962353, 15019.8952884644, 2938.87111965153, 8480.87924910612, 6255.20063238014, -465.686711140569, 9246.04451726266, -587.241117928652, -9704.06094269702, -11454.1691006974, -5060.71297544501, -3191.63771892018, -8079.32008383048, 16625.9175688010, -7654.69552873661, 5034.65099633173, 10398.8577433 [...]
+2801.69911922049, 5633.83782413385, 3859.70934764279, -11539.4226536436, 20108.9011729506, 910.584072708744, 3093.46678270717, 10345.1829725711, 16141.6128114555, -2319.58079868220, -3105.68520943898, 6830.6150461212, 4452.31615983305, -17194.6941480456, -14058.3151436113, -4134.68125300027, -4891.80550864661, 2306.73188173197, 5506.15650039087, 118.200254175457, -10190.0760427195, -7106.15551798465, 4250.75882129769, -10792.0405925158, 20777.8300078241, -12081.5780466037, 18948.16629024 [...]
+5972.94274052168, -7393.1849573229, -11984.7181994379, 283.823032422509, -27382.1139976415, -3684.91537760446, -3817.60325697052, -4212.92967891957, -720.945811675132, 205.413248582573, -481.402925583158, 17495.1990788935, 2799.78840618159, 1807.15044026006, 2546.45625460526, 7996.00941942402, -2591.10858284593, 15297.0213679848, 15207.4635308586, 4377.52320338193, 10331.3480500449, 13698.1620982748, 18009.9246762797, 10889.5276659527, 14328.303970463, 1025.40298857229, -4626.4269386264, [...]
+-2235.6515482968, -11775.7293403186, 5842.72571343533, -10631.4281855837, -5387.85473303962, -640.121172862574, -6616.38007510869, 8830.34873148349, 19897.5582682723, -1725.44656937829, 13829.9780488725, -3383.16146012266, -1376.71848537591, -2363.99587365854, -3020.5549555367, 1899.78604382225, 9365.604258677, 5806.42957892645, -2653.58890485132, 7385.64188212568, 9613.0551566675, -8455.68312327446, 7494.00565184942, -4145.30114068604, 3042.49136481683, 528.905989866827, -1447.814046709 [...]
+-2601.13443747221, -2609.54317010988, 1395.50442049019, 5095.07971941504, -13005.5041837482, 13596.2958151428, 10947.5151323791, 15934.2688543357, 8751.84030809122, -12890.6201923300, 6475.21735684915, 4214.41591901888, -12336.2091847913, 14523.4789848914, -6743.3452798291, -10539.3618851251, 259.059374482770, 11788.6344245072, 973.124658144963, 4441.98329855885, -7367.56292191813, -6303.24937744559, -3561.91603256976, 2043.70606438364, 10501.2198443087, -4163.35876138999, 4797.974233244 [...]
+4683.29031225944, -15108.9355900213, 14642.9211660480, -460.591687396864, -17127.8975200238, -4874.66103546189, 2259.06163853332, 3860.24081641164, 10757.6899040548, 1845.48109731894, -6567.65487433924, -896.31201743468, -9087.01448458024, 12818.5536796186, -1827.24972514214, 4526.39830705585, -745.062731025217, -10086.8790168791, -4084.57705926110, -11423.0753803308, -2819.84493731957, -4881.33398109641, 7944.98588126942, 249.514199557632, -1425.01588675228, -4042.11206088417, -6482.737 [...]
+7615.96042067201, -9960.37668317323, -7339.84903275868, -3800.42489200976, -7800.23622020215, -10024.6337985184, -8553.43776873474, 18303.7180808537, 3127.17594190609, 18646.4148633108, -11277.9075273000, 14127.9048556432, -5702.49111001059, 14058.4680289029, -14605.5806348814, -2078.90612401355, 20097.7825814621, 1380.61534977282, 4593.61315710599, -12360.7699348052, -8221.32932748784, 6292.52968357952, 4820.29370583712, -14822.7092263993, 9847.83201219935, -6918.97773320277, -949.70453 [...]
+40989.2126315841, 490.934345229194, -6192.03412006823, -7711.89277440843, 15755.3139190378, 397.435852527728, 9852.80278293106, -4558.38962204953, 6196.68174463608, 10588.9616073818, 5199.09963002732, 15178.7070236724, -9874.10798389735, -11014.581907998, -9375.88667481487, -12113.0738841626, 13029.9383702791, 13111.8546832458, 1312.61110598125, 17203.0446525849, 1476.98552670608, -15899.0666337192, 552.408741568448, 17931.0650657681, 17350.550649417, -9081.09767020783, 23324.4102752660, [...]
+-2834.28670943606, -2425.24374969445, -1414.20637635385, 12839.9568830667, 20260.4352117707, 4433.46553042090, -5589.53788223894, -11282.6080481326, 35391.4073402558, -20230.1917330211, -9134.14637528029, 10839.3646579693, -353.375427086880, 17286.9047976914, -136.197064474010, 16705.8085745069, -12725.8282072791, 1554.10031879768, 3342.25806686548, 3739.24480225506, 6600.79384493611, -4859.12777612208, -2124.52815021470, -10501.3107867570, 15082.9177550803, -1996.37085114480, -20410.678 [...]
+4769.04929342708, 16530.6280661863, 15823.4323314752, -4317.88297842441, -15729.126971731, -1397.00043929497, 6630.35949126772, 5197.13117424717, 20144.6689605511, 1517.94087009901, -3917.04862495167, 2320.9083557675, -1700.06557589699, 4790.86025936495, -14726.9705204871, 2747.28049211896, 6967.90447310667, 8399.24009916501, 11907.0388580215, -3904.52823008518, -2071.03356810125, -2057.56487219028, 8431.5460163143, 2769.16818795175, 4063.04635420324, 247.919684690161, -17596.4730210461, [...]
+3737.1718040047, -3328.80066488508, -16887.8369411658, 10996.9159914541, -15487.0857963954, -10115.0584252193, -8112.4583192722, -528.479267755926, 3831.44459757914, -528.860279879959, -12061.9700552689, -9593.6359597052, -177.000217906124, -4510.67062875396, 2929.53793755204, 7027.55161790678, 965.360953692314, 4978.23769141054, 7773.1567777348, -11672.7558685121, 14028.5242889796, -9156.3305159378, 13452.9600767287, -12769.0528185293, -10303.5504910797, -7237.00395707139, 2637.00980961 [...]
+-4034.51881709366, -2182.87928041353, 5213.64600796789, 14892.0408847515, -7261.80967435924, 5235.50066692336, 3705.00986712801, 7227.53729692722, 1813.50657673878, 13732.6811835782, -9288.63686733431, 1642.66478137226, -4555.30853672298, -13792.7802473298, -5759.33712321622, -1638.26829191210, -13927.5045396698, 10315.3535782626, 7730.71502977247, 11150.4919831204, 11363.4577697616, -622.616874199327, 2643.1562883994, 591.907559122597, -2613.22122135938, 6538.39427498552, -2324.09699586 [...]
+10790.5996486660, 11860.5707346391, 8899.34665930239, -3510.17762501975, 6835.42176221702, 6085.92712102235, -13549.0143782509, 17009.9141088081, -5873.77688020216, -7785.59032803392, 3521.11134684209, 7214.07962551134, 7565.95976460413, -4325.11499607045, -6410.62702496598, -2323.34277296784, 8573.84427562343, 11534.9369427929, 10586.3941888299, -11367.7421378603, 4669.52974620546, 8606.56096591138, -15388.9440957431, 11074.0848051613, 7038.46633042456, 13131.1186230415, 13301.985789942 [...]
+-7630.79020101204, -4001.07047032926, 4335.43420065565, -11595.2966581125, 10928.1436071461, -7888.08471375243, -1999.28811848743, -22720.2233939178, 3263.78236647320, 453.717097356149, 212.764729701731, 6300.73547689437, -1096.70174875294, 2136.86198491998, -4373.52275308902, -1046.76027907721, 3249.07740504059, -16100.3537080727, -11132.6451423661, 2039.43015036737, -3026.91334571000, 3503.74169544874, 12708.0420608257, 6405.24240023226, -2681.38466797886, -21143.9294264323, 9532.67724 [...]
+11035.7788299664, -15203.8000986216, -7165.45471609038, -13687.6384371371, 1306.66890945845, 17510.7371131567, 17053.1469055154, -449.475890615353, 4244.8603992678, 13709.2222522996, 3350.84977296185, 8265.14730047838, -5317.38294346213, -9566.63178740913, -10802.8493827174, -4700.31189460305, -10028.6346789090, 15548.4514855028, 2299.30718356567, 2362.23127641149, 13553.9730603506, 4328.71133207621, 5877.51828609016, -1724.14166019177, -7755.17377677922, -13427.1705719881, -11819.665104 [...]
+16837.2934910728, 8888.76947532821, -24538.2143894588, -3909.30478761165, -8997.55897527158, -15972.1017637723, -1512.80137120573, 545.66985562249, -4076.81602026243, 17036.4134802880, -8790.94351376244, -10993.626657192, -6931.04728060255, -9905.5542886257, 5465.91560221104, -4632.33000970096, -505.728675779937, 6440.96941944545, -20738.4258286300, -1986.61803297071, 7344.4116252321, -8422.62618995994, 849.929978053927, -1775.66731176867, 3636.7002814232, -15810.5176608697, 1319.0560618 [...]
+4242.72282693409, 17320.2898914573, 5487.0755604192, 22313.8508459163, -15185.4066838760, -14093.9336250529, -5080.44946776099, 6083.76690809715, -10302.8813903833, 9632.27930581965, -18508.1712121887, 17444.5711376966, 9599.1481279799, 1196.51376566627, 2833.21485026176, -6003.61566736433, -1034.32362570635, 16381.6996595524, -18928.7538912889, -2876.97280911583, 3922.51637909615, 9003.52620969858, -12736.2845090274, 80.7053177381711, 10019.0800187382, -8919.53507125672, 5739.9407302035 [...]
+3129.60400573919, 7668.88243515636, -4554.04641999607, 9589.2939166563, -4280.70519094455, 8650.42063185373, 23718.5785047969, 154.526125095704, -16477.0786636706, -4263.87990585325, -9230.93954258983, 755.404072433918, -2502.59416507561, -1492.42950734355, 16459.7670551341, -2158.01448461369, 5110.67409755271, -11670.4756534972, -7851.90687692648, -14901.6627775600, 14392.6697387134, -14160.5809427403, 1058.10435123820, 7833.8230387279, 7141.84307186478, 18965.1754477518, -378.497596084 [...]
+7180.2645936085, 1566.65791208936, 3059.18414758344, 19170.7465334109, 6270.70261169989, -13551.7677056149, -6383.39152682255, -12535.9745013691, -16500.9903440921, 12414.5414396915, -1238.63722118875, 18403.2634597821, -7086.6699630948, 24320.5686751192, 1576.10316790867, 1120.22663863156, 22212.5393459809, -10897.8073768476, 11842.4969829131, 2434.7341766699, -4307.07857967253, 7019.5283579909, -9976.09994141078, 12421.4837639372, 4231.34762988067, -1424.51873421712, 13568.9464127325,  [...]
+-9898.12746817855, -3786.68111356246, 1153.18212643458, 11722.7404958035, -10513.6516594961, 527.4364424191, -14704.2359361356, -16697.3808903626, 16109.7738243016, 13581.1968531623, 4259.15559613143, 19658.160329573, -11906.9833024583, -14007.7623136421, -11454.0721405157, 2037.56105744610, 19644.9930673771, 133.133587274899, -3323.62878467768, -19854.9947428876, 18491.8977947953, -10507.4832007659, 3694.38242140273, -4258.87806162301, -15977.9483814547, -3201.08627601784, -12739.106796 [...]
+-11541.8556582741, 5523.72812187405, 11073.3835254073, -7966.61317011677, 165.814020705637, -1280.79992299456, 4875.54920072505, -13906.1582472709, 4306.12402588395, 6967.90453178198, 15933.1648944270, -4907.29061774364, -4714.00476255542, -6954.27177389419, 9768.42478780838, -3407.17122644591, -8262.35959147006, 7309.35898894924, -7710.44627639194, -11326.6759208516, 1838.22947239737, -4361.29046993967, -7576.00042724604, 15157.9058514242, 81.9523349873097, 22916.1408025927, 6796.595205 [...]
+-8160.62557800542, -1643.40300834952, -2438.95276559853, -8621.19427472122, 4243.74702356268, 6419.19802628004, 14515.3988073003, -7626.6542258063, -7662.65104708632, 5738.30180710746, -1029.38365046927, 8238.56431350666, -12262.6855482406, 3711.00925215089, -8058.42077325748, -2748.88900595687, 8152.62209130595, 11827.0072908593, 8840.40643778717, -5454.97492076747, -14743.6631747854, 1780.84431254749, -7950.25038941995, 2283.8011323355, -11432.1026992487, 6979.0571798207, 8683.43928006 [...]
+-2425.79215728191, -1395.15220700177, -13812.7684743793, 62.8761967890352, 8344.24902163378, 911.071274868247, -1461.99382974127, 5637.06760308315, 15909.2232297929, -988.550891028893, -2549.89492567821, 10240.4921448553, 6465.69649808297, 4345.44793851151, 5630.46334680163, -9068.23152795569, -1540.94933373855, -6407.52105299142, -23964.4162122099, 4761.45859376901, 21344.1959344427, -4655.12599780767, 2455.14544973695, 10308.6879009356, 14992.8583330467, -10637.0763703005, 1182.7821582 [...]
+-1429.76007628924, -4166.2496137078, -1511.36516386208, 4221.39416973286, -369.313320822001, 9773.95684346146, -3732.54673613892, -10569.6204293301, 67.6611216944534, -15108.2580142142, -7282.4932464131, -10109.9563939057, 3116.29767157959, 8576.93576398234, 16532.2872961198, 3173.57937215106, -11035.5844389647, 690.089652824348, -2696.20767379418, 942.299513197415, 6160.96268831138, -4565.73650251314, -1222.24735072014, 319.547865622204, 1698.17783551262, 12112.4481302422, -10231.852101 [...]
+7409.59734103724, -1968.10260847197, 7793.89233547781, 6272.0931409426, 3505.31640618047, 145.722270204986, 9771.808715872, 21012.0646088711, -18087.0900444738, 18809.3175506569, 19543.3625572257, 19303.3725771813, -303.362922816971, -8322.84695577863, -330.133100397241, -1399.86502775964, 13943.2657249286, 7730.90114594445, -561.495768491822, -1612.01441461176, -7303.12587907329, 8313.24423124958, 10591.0425628298, -153.541182412384, 8239.87119261914, -7915.09107526045, -11375.161618654 [...]
+5973.12440620038, 2617.93873229061, 12474.9638095782, 12029.7181798718, -3760.40134600718, 12019.1318761754, -2189.51641305848, 683.48563673143, -4264.49549561064, -5295.06814741698, 4955.9213735576, 7507.33989379817, 7888.59775665765, 2896.07459684176, -12122.9807549855, -8669.53572930804, -11884.9520631396, 2871.18709333825, 11519.6564139028, 6622.63026552654, -13829.385662334, 11122.0295827013, 14723.4561760492, 3512.12886636288, -25285.5028710338, -247.780856449723, -193.120926877609 [...]
+-21427.5186984273, -2723.75809602481, -14289.4331978967, 2203.66177051666, 14053.0963639991, 6537.27869992626, 4048.17222307826, 8808.94942158902, -1260.42265486014, 324.964170668997, 6440.49659116561, -5684.70490577613, -838.927113186368, -10182.5285030327, -4786.57837430589, 1563.78197770103, 11013.7737820289, 835.334893712015, -21090.8768688475, -973.231384628021, -13832.2871380274, -4397.57543145487, -10472.0617696977, -3931.68979461313, 3150.89944969658, 15755.6939346669, 12563.2106 [...]
+-2738.60186945700, -6637.37316189547, 10778.5384337294, 1659.57168404407, -11430.9952279721, -1137.27955101911, 13890.853778473, 10788.8436614016, -22880.0444058531, -5263.4559702509, 48.601886425151, -1011.77093414622, 5483.27370349244, -9389.41314020646, 196.920448804946, -5939.16788952207, -7002.81131547195, 2333.51554895467, -2151.76722791135, 3152.87069501631, 5303.89999642072, -9320.69448987512, -6606.76426639834, 3114.23367096753, -20005.9407619168, -3023.73600349778, -10624.86628 [...]
+-9184.62732875316, -17147.9103432633, -1114.25153487936, 14214.8509752558, -10859.1721450937, 3097.72765115691, -5761.75284711953, -15962.0849393444, 1375.46317304797, -817.79558124167, -3343.25290695126, 2552.77189851540, 10366.9528246347, 11964.0932355984, 4270.75581332537, -3840.16854639900, 3069.06185403914, 3256.82502709036, 4727.86595961868, 1416.25136341154, -14784.7190616159, -14907.5614053903, -6238.75207593341, -12141.8563624199, 2046.92063542195, 6665.85028519909, -7999.541722 [...]
+-2096.30087611648, -10034.1557743297, -11818.0165467932, 6604.05978574538, 2078.27811665612, -959.039647743988, -9465.31954350055, -4806.50243993537, -7887.93492801726, -6646.92861684274, 10056.9684484796, -1856.09177061650, -4389.03994331832, 190.875451382553, 22013.5521364461, -1893.48313172410, -10672.5044482757, -972.197060375989, 3261.88958075952, 417.399525559907, -1681.73855551824, -13691.0323845320, -6057.63860074637, -3250.06430819236, 2257.13532580785, 544.461197017327, -11172. [...]
+1928.01515627293, 14059.8410848203, 11435.6596778692, -5439.41400602053, -3763.09931134986, -17851.3829875324, -20476.9654542344, -4929.23261869366, -9648.6665049171, 4977.11605569717, -6087.1229144194, -3466.21924877874, -9192.14686796355, 11931.6522065555, 1057.38532404793, -7763.16891541649, -5502.5022369852, 15989.11911499, -12331.6114438688, -10925.2512102053, -9713.02480052476, -6545.67983517223, 2441.13046160987, -16625.4019888216, -1813.03726267631, -968.835317307279, 2174.132500 [...]
+7856.4719592266, -860.534791135851, -11934.5503495747, -24264.8733434454, -9295.52652818845, 3516.25728183600, -1721.33657874184, 1498.37751720094, -8773.51220291214, 269.785979081861, 19123.9806483363, 3326.96491288993, 15304.9385192211, -10638.5785555558, 4931.75597064953, 12658.8084012127, 4991.00138736604, -23637.0501580482, 4141.45866048146, -6677.54204972889, 9987.11273913556, 9525.2853315267, 2470.01772461317, -1041.82595857219, -5682.98664754622, 11193.5170994394, 1123.3268200698 [...]
+3141.89116422364, 5907.02793048778, -5595.15478378485, 11113.7199838532, 12723.4766088778, -7646.53543424696, -471.027121278796, -1045.84063287730, 11926.6376800568, -13902.8760402419, -17191.7445745922, 15347.8260440233, -200.898850409682, 8301.47094782393, 13221.8351924281, -10285.6090396796, 8943.8495716329, 11566.6211505784, 4407.47118638886, 17216.8930075838, -1151.88625641588, -3655.55752723063, -1142.69333465345, 1511.79769219345, 9708.36996586137, 7540.05987636239, 12144.93380819 [...]
+-18403.2294554860, -2820.51587323994, -1653.05558532918, 7621.3163821565, -14719.7852868228, 10873.9203782789, 5581.2400085028, -5958.92908815271, 4004.63128091327, -7595.01793693898, -12276.3214206399, -2207.02987852784, 16766.7348131162, -5823.1086916455, -2999.85282843779, 547.697522968801, -10760.2767603395, -4405.75030082703, 25468.4435583539, 1403.63766324755, -12683.4837678868, -4515.25137848916, 2967.01469643554, 7085.13917685112, 12944.2221400942, 18955.3711657597, -4588.4946075 [...]
+12601.1078125173, 7396.57369676714, 4450.91804164987, -17548.2466263970, 5104.9943972699, -160.699814118066, 1907.18087204599, 13080.4910122731, -3775.16772677879, 19649.9534104719, 17149.2050170685, -2243.83587469986, 323.176289601643, 11925.6542245552, 17765.4471559032, -6936.0291879466, -5120.66179209436, 2868.80581416981, 25.2377373515553, -2626.90459952488, 20377.8346526103, -8743.01202453333, -5970.39548835255, 9159.61946871375, 1663.82854839289, -4776.72770976206, 7769.35189068565 [...]
+22776.1630888856, 4753.11293158561, 12448.9132553504, 23085.3860189101, -13553.9892589759, 10771.5650935447, 575.869820889884, 15922.3860110677, 13983.2600248213, -396.27088577108, 2457.90658858030, 6946.79234913527, -7174.3039590131, 4516.24772738624, -4919.06022680375, -11036.2515387666, 21928.1122393066, 5270.31584634417, -11779.1783857017, -1322.48351649219, -11593.1858340998, 1925.8958477952, 8207.12050057694, -917.375366448543, -12379.4223360636, 12050.8367979511, 9795.57369562818, [...]
+9370.48543421022, 2241.50645925727, -3457.62631554001, -11068.8038190909, 3768.07048701014, 6119.47467110193, 251.016218753282, 1366.21676452444, -4458.27387795908, 148.592429655755, 1132.83338039274, -860.135990120289, 1352.86393767376, 161.486271145742, 5194.56869775855, 9767.12295350204, 3815.46177169231, -10499.3083419157, 10078.4961677597, -3982.08105964146, 4654.90545022217, -3616.67427320508, -7121.59146504717, -76.7561919898097, -4292.99336931967, -16147.0678356738, -13880.732236 [...]
+-9979.7301571899, 1116.36558891821, -25398.4407749277, -2198.13242735642, -709.944770954758, 10872.0390455999, -12813.2407425341, 4498.47290256996, -4492.5994976303, -5347.72866440748, -12705.6528958097, -19969.3726804010, 5277.19269628389, 12001.4506223327, -16921.2035187272, 12086.5051048085, -22631.2766197384, -5847.25766876378, -3076.64018207684, -18867.2063279871, -8712.08169364568, -11348.5457109636, -557.497258260752, -8912.06442497652, 8733.28037188928, 6693.01053476904, -27477.7 [...]
+8703.80515452831, -17239.0519329264, 11713.4257258250, 18025.1098475955, -1104.81817585602, 2273.98558034215, 16651.6495390412, -10760.5709897475, -9930.9343890677, -11960.6830649277, 13881.5365887319, 18627.7507644771, -7469.44704877043, -4550.07608838485, 5667.22242048202, 3792.96472069784, 15875.7441820742, -10771.0718371101, 3467.02329270198, -416.245451031511, 24547.9353490058, 20474.1523867218, -5670.91776716296, -15721.9308037124, 10748.9972074174, 15642.3693232390, 8230.534263314 [...]
+-7844.95287651531, 15697.9415541885, -14045.098919034, -4021.87651853734, 12140.1323913242, 11086.1989728378, 16156.7049423889, 24800.2687900701, 3412.23959590308, -7514.58916551337, 5304.91397669439, 10903.5449515401, -9135.14829464335, -5130.94499409801, 9207.05055514595, -7094.37231176512, -5796.10456763966, -5719.27568742002, -14993.2259703721, -1512.82421278768, -4695.71491210024, -4030.87026738597, 18004.9482545505, -3662.42781515613, 3336.01013432573, -14567.0934338606, -24935.656 [...]
+281.799605302655, -9379.28788079412, 94.5874090877592, -11822.6807830443, 1924.68335092179, -1604.34735693318, -4514.61147651551, 26189.2095494034, -2215.33440984022, -1670.85103871984, 10447.4934179853, 21506.9743687035, 16538.4163459668, -2941.85823459952, 3240.45518312571, -5122.55718657399, -6110.20458336634, -8083.32660806713, 9758.03355441265, -6104.90146314662, -8720.9530556833, 15291.1203863277, 5414.55298040541, 7214.13440018034, -7326.11920852705, 5304.79722360326, 9050.7584163 [...]
+6389.6726531286, -1965.57231814702, -17273.7805099531, -3858.82710310018, 16685.5692171469, -6194.25678033121, 1095.39898464117, 8418.50248087229, -3957.03680461556, 5387.36026855946, 983.579885882429, -15225.7844704599, 5650.39909998546, 8568.55951427421, 3668.71385784695, -15918.6893390036, 1957.31433494731, 2765.89963230089, 3315.37926566144, 2486.61238454813, -849.183711570575, 8801.53885529363, 192.238366369758, 6603.42171848217, -4795.62787068726, -7547.88275245347, 20840.44026765, [...]
+-14769.8758476509, -325.920514183036, -9181.20930066569, -8209.36749077156, -840.265575537675, -1457.31524380606, 1463.47744282549, 12678.3508212260, 3322.88233338371, -18579.5825619449, 3701.49411935519, -9505.3112076233, -6142.3786057655, 3326.48891124091, 12082.4636101946, -8110.46804999763, 4171.99458237923, 625.056466843897, 8881.03771804784, 2467.32565095449, 7874.27153703245, -5737.14443198959, -5337.02309261193, -9568.93725624175, -2968.36017612471, 1725.15258187536, -1421.459423 [...]
+-14272.8213573940, -5108.89927398348, -12260.6440332837, 8323.61750314881, 2852.74960274022, 10700.5556946248, -10510.9965435881, -12600.2127581828, -4821.33404934167, 7684.52991152522, 676.27965089629, 8257.68967298628, 7401.57792915345, -6066.05910988755, -10823.4201728701, 2438.31390157541, -2617.33537749783, 5440.47552421289, -5835.37986199753, 11984.7296731655, -7887.32988924128, -10149.5777660191, 4876.66507383057, -3402.52613942279, 4634.9871737848, 9489.09539638736, -14315.774145 [...]
+1768.24668384528, 2567.09978777714, 14196.2325253137, 18603.4970872147, 1742.07365434714, -1054.28437130354, 25658.3780032077, -10544.1067412817, -18317.1230622181, 6045.33670443822, -12562.6951024603, -7450.0658707934, -2768.2902829089, -12014.3796323934, 4536.27612317192, -7918.45048658318, 6605.70564685975, -2643.94231853276, 15603.8681276124, 5493.36223810797, -7703.35475802991, -17533.714258773, 6674.55747845454, -21685.7406724255, 454.210381090713, -19967.4372646884, -2318.76645178 [...]
+-5486.86097165745, 332.299542067262, 7537.82784836124, 5305.31497657621, -6009.91122215025, 12621.1219350582, -4382.58269014398, -4655.63305413568, 26383.9966975315, -4278.09004238232, 96.8670086155927, 16234.339607524, 14591.4038109204, -16384.8350387321, -6551.62143933202, 18061.5536890573, -11093.0713861279, -8181.02810753759, 891.829839999927, 28867.7424449883, -9660.73762143124, -383.303486939513, -1437.2766926021, -9825.4163257592, -8906.02989646169, 3875.46553271496, 19943.3111783 [...]
+-10186.5468222002, -7528.61657557391, 7395.34958963313, -8161.62978332163, -14431.5539053165, -7373.48058908633, -1218.82837288106, -166.22554009106, -7604.07639493791, -2891.30763197744, 17695.8522628577, 13889.9953022703, 10242.0272055899, 3386.1746314468, 10310.9809500845, 9005.7010696117, -15891.6383554308, -4738.67407047763, 17011.5130924814, -217.187941486218, -2713.77426690321, -11838.5656702247, -14004.435239598, 1791.61178940926, 2329.79795071642, 3429.10691744446, 24946.8707268 [...]
+-1487.85803694976, 13889.8518691285, -19330.7024689300, 11710.2394126012, 4895.71909542913, -9138.99443187178, -1967.73241609711, 6314.80588690083, -7550.9875371873, 14013.8253493366, 11779.5124990756, 6947.84766573529, -12287.8051704981, -645.140670523559, -7074.51432177558, 732.341689132986, 9199.97896807264, -6141.6517185143, -6758.5216020984, -3983.11432658274, -9914.50933488797, -3618.64100066872, -12654.8530163631, 15058.4299024471, -14459.6523835947, 6821.00421081036, 18283.051474 [...]
+9205.0623041934, 16136.4335575263, -23245.0760002555, -5403.04611600451, -5863.93944385007, 712.472192004604, 7208.17537900603, 1860.15987510037, 3898.83618136679, 6394.20714167509, 20718.5525312879, 15624.4675414846, -3665.41771470293, -6374.51254878436, 1980.96007495658, -2202.87539010035, 22061.4916397519, 18291.5073186889, -7596.87205560991, 3839.06318991168, 1628.47554860806, -16787.9792474197, 7027.38929213266, 2169.36131752331, 356.994432529018, -4849.62395724688, -6053.0938553216 [...]
+766.787163372926, 7393.06463209397, 15427.7254589748, -5095.65636027018, 1155.00498864017, 14072.9697784155, -873.782839095485, -3087.69125217603, -3668.74547808692, -2231.6784519839, 11649.0950152136, 3035.20052557547, -10160.3129049189, 4641.70972475356, -5854.8490800617, -12313.4905515821, -6760.05830398099, 18492.7133105994, -1882.63206966301, -3423.10104619518, -10962.2890181815, -9655.28470041459, -15228.2418461481, -11401.0192351188, 8046.0259331728, -198.234034127971, -2076.03448 [...]
+-5287.14295620565, 2541.21351536993, -3199.57628951393, -5645.05074086736, 6033.99152301292, 4926.2886098322, -7697.30614684727, -317.778494174353, -18533.0229332552, 3865.634311575, 3478.07134755581, 4500.67839517817, -16079.0323723165, -2025.56135781231, 7630.38898900493, -651.522339220316, -2056.07479633585, -29353.5117751338, 23341.6458105052, -9930.27886795824, -2531.78989646477, 4498.89172635766, 4826.35596270453, 8601.36162464529, 25794.7345226276, -20375.2677261333, -4577.9237088 [...]
+2471.42214532422, 17932.7964690221, 801.29156455869, 16349.0801366505, 26292.3816815212, 5373.7838976128, -11865.9251924447, 11235.2266598132, -6025.93626145913, 7934.7333985629, -6083.28427708799, -316.244696621462, -6191.97261972087, 15059.4367979289, -274.082168881752, -14224.0686251657, 2285.52704646742, 4702.87162234141, 8596.76994077376, -10628.6774698952, -3998.29277976872, -2894.17425573316, 7392.85361155651, -4246.07899683393, 7461.87323749988, -5319.571876253, -4196.05472150947 [...]
+4264.12711126494, 683.711323954072, -10711.9601202833, -18326.9991052093, -9838.74019261256, 4528.10280714379, -6835.85835484939, 10692.4169657376, 6974.69685817524, -5877.2355101298, 12605.6518303972, -5211.31803215129, -12071.0800540191, 8949.64339577207, -6056.76011806853, -930.235285640219, -11833.6185464317, -7589.34005761703, 5244.83387894592, -1261.79944664723, 12450.1761498065, -3540.75931368699, -17020.2524344802, -8510.90832448961, 4400.30718684469, -8207.7205218807, -7334.7755 [...]
+
+double y15[100] = {
+27119482.6954411, 81095521.63856, -30146989.6539448, 70623973.0963865, -89146494.2502561, 48642181.6522127, -101083605.684235, 26274637.9605653, 24745886.6255615, -54032021.2666394, -50501803.8164556, -45727188.7080584, -41937031.9566971, -93442273.7042745, -10150494.2765874, -92789183.5423421, 89926925.4429143, 66258563.8924366, 56678483.3156428, -63877137.8747003, 68833854.0921852, -47352119.7182295, 48968536.4002306, -150902478.263883, -73701709.1928169, 41252886.6970746, 33118166.389 [...]
+
+double lars15[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -56.18608564755272300, -95.28495598101552800, -133.42873578192629000, -152.06577620996470000, -188.21022782900184000, -230.14892053740977000, -264.94570852513465000, -346.72468433167535000, -398.73375888416240000, -508.04453172260617000, -561.46495610020236000, -580.04990413393693000, -598.10501530709246000, -640.23184773580238000, -673.175201 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -3.10727873342824080, -54.5167 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -196.25902497190870000, -278.37665287365746000, -308.56069222927442000, -331.86203304726712000, -389.56479099475280000, -434.16039891533302000, -436.8891530 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -62.23793850097065700, -172.62570158597327000, -225.13140230436321000, -318.41621251195318000, -420.66549239498471000, -512.48721338745997000, -597.70217967004635000, -636.03078822482007000, -720.19459563439125000, -803.94394676102502000, -863.94015316430227000, -993.85474240680605000, -1072.94843519111740000, -1242.19130372199220000, -1286.00743695548500000, -1301.72392433114210000, -1317.32109787283210000, -1377.04105490719 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 29.88300727836624700, 127.13833656853922000, 200.86856552748407000, 205.74051800420921000, 28 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -16.49141382438739700, -32.13178350070740000, -70.22405177637421000, -95.42377114133232400, -97.91008444703200600, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 45.11804816678974800, 68.35155753516893600, 108.97484706864590000, 163.41205042454001000, 205.00814226100695000, 314.35437364478247000, 372.46563568620149000, 481.32680946341588000, 520.78950573288046000, 534.68060992483220000, 547.52713155992376000, 584.98692699724234000, 611.69757534654764000, 612.94 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 48.84203349158362800, 111.00646657568559000, 136.97548836833499000, 176.68961170662413000, 221.41979841055030000, 245.35787018967224000, 302.66130740491934000, 329.46276852986972000, 348.70923118664854000, 354.44503951747345000, 354.09197852344528000, 360.37756303858311000, 384.13318503263491000, 391.47725617420156000, 391 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-215.35708655089732000, -223.26280002006553000, -444.18288866094605000, -491.60299712489780000, -577.34411390307469000, -618.96664846578403000, -666.68943711577788000, -709.22926185743677000, -737.30888691431801000, -763.70639136985005000, -773.74427831392779000, -801.50094618218031000, -827.13989976584412000, -844.21825350836843000, -863.73214532606551000, -875.59102786637607000, -912.56824009898583000, -926.01614995726140000, -930.62657523453925000, -937.49070845648134000, -964.6057297 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -88.51121929152309100, -120.74019284235533000, -151.87268870182731000, -248.36338929989228000, -314.18355035933433000, -318.63170424496 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -37.97496818722677900, -108.40595009617563000, -175.64166618186070000, -230.05447647558901000, -347.66261287308600000, -419.91107384294753000, -593.20875996267637000, -667.52194494081664000, -698.46790313616179000, -721.95619180376718000, -778.82350832449663000, -802.81313231632089 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -71.46600991901321700, -105.08063515808273000, -149.55120751233324000, -190.10382240682728000, -231.53606935245165000, -280.70272003038230000, -307.99036707387381000, -354.90347607183764000, -408.08663879959602000, -436.49754187659090000, -513.99554622319533000, -547.59125492085366000, -632.54054317371435000, -661.23666728839305000, -672.32708076152494000, -682.00907427738377000, -716.91704113529795000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -66.13308480577202900, -115.07823525213685000, -244.54627077612375000, -313.25160885487924000, -490.91184406809174000, -563.27946136362311000, -590.12886356099023000, -618.47597969976346000, -706.25711673142780000, -772.42597296111603000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 35.31551441081791900, 72.77256512567474500, 91.10995345838797700, 128.65891913504504000, 154.92144901800540000, 241.51415979764263000, 269.65160332630694000, 276.58584602132311000, 283.84356911902461000, 319.51691339420950000, 343.11328505841209000, 344.6765322 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -229.21917443486652000, -279.62740628944869000, -362.58003892499221000, -404.07182129056167000, -463.68346490182341000, -520.59126053091688000, -572.72509443833565000, -624.31837742264156000, -639.66820916711947000, -671.22745909660625000, -708.54635047594729000, -739.45435894344143000, -811.46754305962008000, -849.41417389980916000, -888.02441451435197000, -912.89435809678673000, -921.39661158039291000, -933.74859173773575000, -991.4283460748961 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 50.28304057356489700, 132.07749579461131000, 222.23229563862526000, 290.64622997152344000, 356.40645893025749000, 390.10116884285571000, 457.58572634424479000, 521.85975172579447000, 577.25971081984096000, 691.60467706086808000, 771.20907625416953000, 970.21996065484655000, 1052.19026393724220000, 1081.11356948337700000, 1112.13475920344150000, 1202.63325629070800000, 1265.29483899921 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -69.38707356567844900, -118.85192036606709000, -122.11906689543265000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 65.63432019008307300, 201.92118525381983000, 283.45270642364687000, 488.76816103851661000, 567.95341713059099000, 597.43604617307972000, 630.00360304923663000, 728.64236552708985000, 816.80361364848488000, 823.297245159 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -98.46506886139559400, -151.34995562703591000, -242.83153421009865000, -286.84585544649570000, -302.87930406942837000, -313.54806343249214000, -334.06998867417434000, -345.41882396824610000, -346.51 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.616687 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 59.35449275375078300, 183.20637056466109000, 235.77866773086018000, 254.27610083246566000, 271.79339501440529000, 310.86917518952572000, 339.78295269570123000, 342.2352584363720 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 7.51956077347015390, 193.17253272062558000, 229.77137760247385000, 288.06320406314762000, 316.55271119019238000, 340.04102789421967000, 363.15670045658652000, 389.74896500826986000, 412.57944532151572000, 426.86219545160276000, 454.63462507455012000, 487.27358997678073000, 515.04839107419070000, 567.42372680869926000, 607.38735413072527000, 700.30269879961065000, 734.95511972535576000, 746.42065269498278000, 755.00446961774924000, 783.69918451301544000, 807.667078389 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -69.33568274261826000, -74.29557309840373600, -163. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -71.60794356952075600, -148.80190511732005000, -212.14573189963320000, -275.88811433185106000, -301.51072566327497000, -349.99756529743996000, -402.49178098898489000, -439.42267175542128000, -532.22270557349395000, -580.62566305064342000, -657.95908857267011000, -698.33079338252719000, -715.03787533275477000, -730.91149562371095000, -782.50614918756321000, -822.98 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq15[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1218.79083908951110000, -963.18012261583010000, -891.84037420591062000, -948.81846440955542000, -921.46627298526710000, -963.86069765009859000, -1069.29326604348580000, -1076.05912631305930000, -1125.78816548220470000, -1101.19918285849800000, -1248.87561745844250000, -1208.71327401250300000, -1217.04365646804670000, -1064.85663892821730000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -584.71950996199598000, -574.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1261.22225290127450000, -1335.06112445537020000, -1329.58049079991720000, -1130.64416652753700000, -971.18985350429887000, -1044.07447172956860000, -947.65 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2259.83045024809050000, -2191.55798291678590000, -2085.44389270880990000, -2484.74908726336800000, -2536.41172134068210000, -2550.69515038904910000, -2292.02881782554780000, -2274.61831068479800000, -2427.61074948554870000, -2269.12755833406480000, -2250.78660858618420000, -2152.47996992945220000, -2178.62890283549680000, -2160.55636540750770000, -1849.83068387127790000, -1833.35736760471290000, -1852.00035325168870000, -197 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1054.28810461027550000, 1107.44047445358140000, 1209.24374709157630000, 1117.6597224012280000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -574.33789098874081000, -568.29182493592100000, -454.18174643506597000, -440.06899941199549000, -563.2916460380114 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 942.19885691899935000, 1061.60803068834180000, 933.09227838323147000, 1115.78358696722350000, 1166.52547779134330000, 1289.54355720355720000, 1184.82481538183170000, 1072.04179461406510000, 1028.59299957687180000, 1004.56776574551490000, 987.91260292108643000, 962.56950082592812000, 977.007099801207570 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1133.01056405093980000, 1347.02003924962810000, 1247.17793725495520000, 982.36295053089646000, 1003.96838678227150000, 798.70002274777755000, 813.71405651081955000, 704.13046992294232000, 453.14659400407339000, 428.25306040189707000, 342.14916792879012000, 575.85068316458853000, 623.58214065825769000, 491.91881420761621000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-2631.52490125468470000, -2138.60109236339170000, -2152.93358199496020000, -2165.98485771610880000, -2145.50260958269880000, -2093.68120078827360000, -1774.94538679539230000, -1589.46503349451380000, -1360.60492232247660000, -1288.56718673199360000, -1202.87429160216400000, -1364.59551799389190000, -1275.68993750720600000, -1238.99411971992160000, -1037.76408029934350000, -1041.37080538500750000, -1113.21822959478600000, -1099.06300829409090000, -1086.58103290242090000, -1172.79678042646 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1227.46802279320350000, -1210.93291672924990000, -1219.11090719920180000, -1220.95831826350540000, -1214.37629078674060000, -1151.2254 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1661.44400042409690000, -1537.22672168667960000, -1351.92145815501610000, -1487.83755326156370000, -1396.53444925867420000, -1429.89947240699420000, -1533.57653784791020000, -1623.77933579158160000, -1745.26073397399270000, -1527.14699521121340000, -1352.02759254211420000, -1130.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1378.54054799348340000, -1296.06954373203010000, -1182.28164492909810000, -1029.22016762767450000, -1151.22624352487630000, -1258.28177200411280000, -1474.56540459080860000, -1306.62135333833660000, -1338.51890355242400000, -1093.23173541574780000, -1205.15073858598540000, -1017.23829751082100000, -1093.50211292072480000, -1030.49658773863670000, -1047.47672846085040000, -1013.91286888511870000, -1068.77 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1223.12249113171740000, -1246.47324296922400000, -1399.18897095727240000, -1273.70936044505330000, -1454.95218613355540000, -1494.50140962849240000, -1498.34962554447610000, -1590.22992657383590000, -1591.06247316977460000, -1677.387660407 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 751.75505822994376000, 728.07861952464611000, 514.98912075068472000, 463.53415642766589000, 522.05522796170374000, 711.39345732414358000, 631.72245713032555000, 511.14686670816582000, 532.64210760117487000, 679.09263961620070000, 665.83024792574906000, 637.2810 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -2002.16080980477820000, -2059.51850683280510000, -1879.73867289705890000, -1874.15373482985160000, -1848.03170965533150000, -1698.12966605906970000, -1729.96319570558810000, -1650.14608731481850000, -1295.88933789444950000, -1311.46433515437820000, -1361.43532591895630000, -1453.91056471034840000, -1453.70712768003700000, -1379.88439290103130000, -1097.53572988891190000, -1232.91922808103660000, -1208.99791758692850000, -1357.18092294373790000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1831.84517867780890000, 2031.57235378295100000, 2087.71905514959600000, 1809.26102450631240000, 1663.91513394989870000, 1830.58474801561190000, 1826.63291134915810000, 1646.32516395902960000, 1857.86129392091400000, 1711.37438344681750000, 1884.02890079595950000, 2050.11564379481250000, 2106.97897158215160000, 2059.48718127155550000, 2175.55734510697360000, 2114.82871969134250000, 212 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -768.78624330242951000, -795.36038341663027000, -733.65493017425672000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1582.80898449801590000, 1417.37666999593470000, 1423.21249359966530000, 1602.87442607134040000, 1586.90431267800500000, 1594.72960293134910000, 1746.43646272780760000, 1722.88906070685650000, 2022.54535399803130000, 203 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -976.61211514588570000, -890.64767042474352000, -739.23936685798424000, -853.21937311991019000, -845.23443058211262000, -679.27870666805950000, -540.92433110218167000, -500.63174018708526000, -552.3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 418.35634 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 889.09326198440772000, 855.26563304952981000, 912.27568147032866000, 879.97914862419771000, 872.29538881583630000, 704.74035042256310000, 735.22368377939790000, 801.251373772934 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 1829.30360938578450000, 1629.14264519829590000, 1522.05948013481950000, 1354.18907608181010000, 1325.95521851346050000, 885.50510221965646000, 841.46713070429507000, 980.02939197313378000, 866.51720583579754000, 1037.46448528242670000, 1018.04895279331090000, 1058.28788238779040000, 1157.07872534357310000, 1034.52588704950040000, 1166.05392526530980000, 1204.49059740406460000, 1180.86029295757430000, 1134.25927247782850000, 1049.26219703903870000, 1072.93259272968540 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1017.60863213749220000, -1002.67475757366970000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1734.54365521205090000, -1746.10247514548450000, -1618.21707441285750000, -1543.27600692639250000, -1396.90377027416800000, -1333.64143537204090000, -1320.87101018843330000, -1293.10122954182360000, -1359.84692332683400000, -1257.26880329003010000, -1077.59459059639060000, -1217.83135195806490000, -1280.17964600667640000, -1275.06748995493440000, -1302.5635029720 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso15[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -56.18608564755272300, -95.28495598101552800, -133.42873578192629000, -152.06577620996470000, -188.21022782900184000, -230.14892053740977000, -264.94570852513465000, -346.72468433167535000, -398.73375888416240000, -508.04453172260617000, -561.46495610020236000, -580.04990413393693000, -598.10501530709246000, -640.23184773580238000, -673.175201 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -3.10727873342824080, -54.5167 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -196.25902497190870000, -278.37665287365746000, -308.56069222927442000, -331.86203304726712000, -389.56479099475280000, -434.16039891533302000, -436.8891530 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -62.23793850097065700, -172.62570158597327000, -225.13140230436321000, -318.41621251195318000, -420.66549239498471000, -512.48721338745997000, -597.70217967004635000, -636.03078822482007000, -720.19459563439125000, -803.94394676102502000, -863.94015316430227000, -993.85474240680605000, -1072.94843519111740000, -1242.19130372199220000, -1286.00743695548500000, -1301.72392433114210000, -1317.32109787283210000, -1377.04105490719 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 29.88300727836624700, 127.13833656853922000, 200.86856552748407000, 205.74051800420921000, 28 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -16.49141382438739700, -32.13178350070740000, -70.22405177637421000, -95.42377114133232400, -97.91008444703200600, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 45.11804816678974800, 68.35155753516893600, 108.97484706864590000, 163.41205042454001000, 205.00814226100695000, 314.35437364478247000, 372.46563568620149000, 481.32680946341588000, 520.78950573288046000, 534.68060992483220000, 547.52713155992376000, 584.98692699724234000, 611.69757534654764000, 612.94 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 48.84203349158362800, 111.00646657568559000, 136.97548836833499000, 176.68961170662413000, 221.41979841055030000, 245.35787018967224000, 302.66130740491934000, 329.46276852986972000, 348.70923118664854000, 354.44503951747345000, 354.09197852344528000, 360.37756303858311000, 384.13318503263491000, 391.47725617420156000, 391 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-215.35708655089732000, -223.26280002006553000, -444.18288866094605000, -491.60299712489780000, -577.34411390307469000, -618.96664846578403000, -666.68943711577788000, -709.22926185743677000, -737.30888691431801000, -763.70639136985005000, -773.74427831392779000, -801.50094618218031000, -827.13989976584412000, -844.21825350836843000, -863.73214532606551000, -875.59102786637607000, -912.56824009898583000, -926.01614995726140000, -930.62657523453925000, -937.49070845648134000, -964.6057297 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -88.51121929152309100, -120.74019284235533000, -151.87268870182731000, -248.36338929989228000, -314.18355035933433000, -318.63170424496 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -37.97496818722677900, -108.40595009617563000, -175.64166618186070000, -230.05447647558901000, -347.66261287308600000, -419.91107384294753000, -593.20875996267637000, -667.52194494081664000, -698.46790313616179000, -721.95619180376718000, -778.82350832449663000, -802.81313231632089 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -71.46600991901321700, -105.08063515808273000, -149.55120751233324000, -190.10382240682728000, -231.53606935245165000, -280.70272003038230000, -307.99036707387381000, -354.90347607183764000, -408.08663879959602000, -436.49754187659090000, -513.99554622319533000, -547.59125492085366000, -632.54054317371435000, -661.23666728839305000, -672.32708076152494000, -682.00907427738377000, -716.91704113529795000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -66.13308480577202900, -115.07823525213685000, -244.54627077612375000, -313.25160885487924000, -490.91184406809174000, -563.27946136362311000, -590.12886356099023000, -618.47597969976346000, -706.25711673142780000, -772.42597296111603000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 35.31551441081791900, 72.77256512567474500, 91.10995345838797700, 128.65891913504504000, 154.92144901800540000, 241.51415979764263000, 269.65160332630694000, 276.58584602132311000, 283.84356911902461000, 319.51691339420950000, 343.11328505841209000, 344.6765322 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -229.21917443486652000, -279.62740628944869000, -362.58003892499221000, -404.07182129056167000, -463.68346490182341000, -520.59126053091688000, -572.72509443833565000, -624.31837742264156000, -639.66820916711947000, -671.22745909660625000, -708.54635047594729000, -739.45435894344143000, -811.46754305962008000, -849.41417389980916000, -888.02441451435197000, -912.89435809678673000, -921.39661158039291000, -933.74859173773575000, -991.4283460748961 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 50.28304057356489700, 132.07749579461131000, 222.23229563862526000, 290.64622997152344000, 356.40645893025749000, 390.10116884285571000, 457.58572634424479000, 521.85975172579447000, 577.25971081984096000, 691.60467706086808000, 771.20907625416953000, 970.21996065484655000, 1052.19026393724220000, 1081.11356948337700000, 1112.13475920344150000, 1202.63325629070800000, 1265.29483899921 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -69.38707356567844900, -118.85192036606709000, -122.11906689543265000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 65.63432019008307300, 201.92118525381983000, 283.45270642364687000, 488.76816103851661000, 567.95341713059099000, 597.43604617307972000, 630.00360304923663000, 728.64236552708985000, 816.80361364848488000, 823.297245159 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -98.46506886139559400, -151.34995562703591000, -242.83153421009865000, -286.84585544649570000, -302.87930406942837000, -313.54806343249214000, -334.06998867417434000, -345.41882396824610000, -346.51 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.616687 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 59.35449275375078300, 183.20637056466109000, 235.77866773086018000, 254.27610083246566000, 271.79339501440529000, 310.86917518952572000, 339.78295269570123000, 342.2352584363720 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 7.51956077347015390, 193.17253272062558000, 229.77137760247385000, 288.06320406314762000, 316.55271119019238000, 340.04102789421967000, 363.15670045658652000, 389.74896500826986000, 412.57944532151572000, 426.86219545160276000, 454.63462507455012000, 487.27358997678073000, 515.04839107419070000, 567.42372680869926000, 607.38735413072527000, 700.30269879961065000, 734.95511972535576000, 746.42065269498278000, 755.00446961774924000, 783.69918451301544000, 807.667078389 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -69.33568274261826000, -74.29557309840373600, -163. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -71.60794356952075600, -148.80190511732005000, -212.14573189963320000, -275.88811433185106000, -301.51072566327497000, -349.99756529743996000, -402.49178098898489000, -439.42267175542128000, -532.22270557349395000, -580.62566305064342000, -657.95908857267011000, -698.33079338252719000, -715.03787533275477000, -730.91149562371095000, -782.50614918756321000, -822.98 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq15[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1218.79083908951110000, -963.18012261583010000, -891.84037420591062000, -948.81846440955542000, -921.46627298526710000, -963.86069765009859000, -1069.29326604348580000, -1076.05912631305930000, -1125.78816548220470000, -1101.19918285849800000, -1248.87561745844250000, -1208.71327401250300000, -1217.04365646804670000, -1064.85663892821730000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -584.71950996199598000, -574.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1261.22225290127450000, -1335.06112445537020000, -1329.58049079991720000, -1130.64416652753700000, -971.18985350429887000, -1044.07447172956860000, -947.65 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2259.83045024809050000, -2191.55798291678590000, -2085.44389270880990000, -2484.74908726336800000, -2536.41172134068210000, -2550.69515038904910000, -2292.02881782554780000, -2274.61831068479800000, -2427.61074948554870000, -2269.12755833406480000, -2250.78660858618420000, -2152.47996992945220000, -2178.62890283549680000, -2160.55636540750770000, -1849.83068387127790000, -1833.35736760471290000, -1852.00035325168870000, -197 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1054.28810461027550000, 1107.44047445358140000, 1209.24374709157630000, 1117.6597224012280000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -574.33789098874081000, -568.29182493592100000, -454.18174643506597000, -440.06899941199549000, -563.2916460380114 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 942.19885691899935000, 1061.60803068834180000, 933.09227838323147000, 1115.78358696722350000, 1166.52547779134330000, 1289.54355720355720000, 1184.82481538183170000, 1072.04179461406510000, 1028.59299957687180000, 1004.56776574551490000, 987.91260292108643000, 962.56950082592812000, 977.007099801207570 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1133.01056405093980000, 1347.02003924962810000, 1247.17793725495520000, 982.36295053089646000, 1003.96838678227150000, 798.70002274777755000, 813.71405651081955000, 704.13046992294232000, 453.14659400407339000, 428.25306040189707000, 342.14916792879012000, 575.85068316458853000, 623.58214065825769000, 491.91881420761621000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-2631.52490125468470000, -2138.60109236339170000, -2152.93358199496020000, -2165.98485771610880000, -2145.50260958269880000, -2093.68120078827360000, -1774.94538679539230000, -1589.46503349451380000, -1360.60492232247660000, -1288.56718673199360000, -1202.87429160216400000, -1364.59551799389190000, -1275.68993750720600000, -1238.99411971992160000, -1037.76408029934350000, -1041.37080538500750000, -1113.21822959478600000, -1099.06300829409090000, -1086.58103290242090000, -1172.79678042646 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1227.46802279320350000, -1210.93291672924990000, -1219.11090719920180000, -1220.95831826350540000, -1214.37629078674060000, -1151.2254 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1661.44400042409690000, -1537.22672168667960000, -1351.92145815501610000, -1487.83755326156370000, -1396.53444925867420000, -1429.89947240699420000, -1533.57653784791020000, -1623.77933579158160000, -1745.26073397399270000, -1527.14699521121340000, -1352.02759254211420000, -1130.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1378.54054799348340000, -1296.06954373203010000, -1182.28164492909810000, -1029.22016762767450000, -1151.22624352487630000, -1258.28177200411280000, -1474.56540459080860000, -1306.62135333833660000, -1338.51890355242400000, -1093.23173541574780000, -1205.15073858598540000, -1017.23829751082100000, -1093.50211292072480000, -1030.49658773863670000, -1047.47672846085040000, -1013.91286888511870000, -1068.77 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1223.12249113171740000, -1246.47324296922400000, -1399.18897095727240000, -1273.70936044505330000, -1454.95218613355540000, -1494.50140962849240000, -1498.34962554447610000, -1590.22992657383590000, -1591.06247316977460000, -1677.387660407 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 751.75505822994376000, 728.07861952464611000, 514.98912075068472000, 463.53415642766589000, 522.05522796170374000, 711.39345732414358000, 631.72245713032555000, 511.14686670816582000, 532.64210760117487000, 679.09263961620070000, 665.83024792574906000, 637.2810 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -2002.16080980477820000, -2059.51850683280510000, -1879.73867289705890000, -1874.15373482985160000, -1848.03170965533150000, -1698.12966605906970000, -1729.96319570558810000, -1650.14608731481850000, -1295.88933789444950000, -1311.46433515437820000, -1361.43532591895630000, -1453.91056471034840000, -1453.70712768003700000, -1379.88439290103130000, -1097.53572988891190000, -1232.91922808103660000, -1208.99791758692850000, -1357.18092294373790000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1831.84517867780890000, 2031.57235378295100000, 2087.71905514959600000, 1809.26102450631240000, 1663.91513394989870000, 1830.58474801561190000, 1826.63291134915810000, 1646.32516395902960000, 1857.86129392091400000, 1711.37438344681750000, 1884.02890079595950000, 2050.11564379481250000, 2106.97897158215160000, 2059.48718127155550000, 2175.55734510697360000, 2114.82871969134250000, 212 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -768.78624330242951000, -795.36038341663027000, -733.65493017425672000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1582.80898449801590000, 1417.37666999593470000, 1423.21249359966530000, 1602.87442607134040000, 1586.90431267800500000, 1594.72960293134910000, 1746.43646272780760000, 1722.88906070685650000, 2022.54535399803130000, 203 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -976.61211514588570000, -890.64767042474352000, -739.23936685798424000, -853.21937311991019000, -845.23443058211262000, -679.27870666805950000, -540.92433110218167000, -500.63174018708526000, -552.3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 418.35634 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 889.09326198440772000, 855.26563304952981000, 912.27568147032866000, 879.97914862419771000, 872.29538881583630000, 704.74035042256310000, 735.22368377939790000, 801.251373772934 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 1829.30360938578450000, 1629.14264519829590000, 1522.05948013481950000, 1354.18907608181010000, 1325.95521851346050000, 885.50510221965646000, 841.46713070429507000, 980.02939197313378000, 866.51720583579754000, 1037.46448528242670000, 1018.04895279331090000, 1058.28788238779040000, 1157.07872534357310000, 1034.52588704950040000, 1166.05392526530980000, 1204.49059740406460000, 1180.86029295757430000, 1134.25927247782850000, 1049.26219703903870000, 1072.93259272968540 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1017.60863213749220000, -1002.67475757366970000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1734.54365521205090000, -1746.10247514548450000, -1618.21707441285750000, -1543.27600692639250000, -1396.90377027416800000, -1333.64143537204090000, -1320.87101018843330000, -1293.10122954182360000, -1359.84692332683400000, -1257.26880329003010000, -1077.59459059639060000, -1217.83135195806490000, -1280.17964600667640000, -1275.06748995493440000, -1302.5635029720 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso15[850] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 19.23914438821083200, 155.17892474874469000, 359.34138197087537000, 385.51097670140172000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 419.29103578319831000, 463.58700353254250000, 832.69521931369525000, 839.34747583065189000, 856.56114882337295000, 994.98729712221086000, 1211.77136920991890000, 1239.20264914952080000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 377.48937643031871000, 418.73145689798577000, 466.46621585591743000, 790.70474726435452000, 888.75821263634236000, 910.70465253104851000, 1133.19590410276440000, 1154.31841421647100000, 1312.39393277948760000, 1315.75935653296010000, 1322.26695473469390000, 1377.09710652225390000, 1474.58229169361930000, 1485.93518951226910000, 
+0.00000000000000000, 0.00000000000000000, 37.72710685742423200, 494.05697868465194000, 543.83987815387059000, 593.27748527528718000, 877.62933365266940000, 956.66899289028174000, 971.10454431917788000, 1193.33649005535240000, 1217.33323228884300000, 1444.62846555673810000, 1449.81096236519010000, 1466.35138642725910000, 1600.44398948610930000, 1896.07479559532770000, 1932.83174002414240000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 8.08451724495319010, 26.21132533245146900, 171.27750031638962000, 484.44574031999878000, 524.02955756214692000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 139.78759934651444000, 451.88789367011708000, 491.61118370958729000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 5.65139915621814910, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 39.08183150995010600, 234.54491785639161000, 311.04447226126064000, 326.83356786396087000, 487.62176712138097000, 505.54974313720641000, 715.58541263296104000, 719.29817635215989000, 729.64595043626389000, 828.44016334568607000, 965.19756053909884000, 983.78268335624591000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 25.14320767853398300, 58.37445733360031100, 351.33412452944418000, 394.73486641366668000, 448.58196540482982000, 828.65319753546987000, 974.82861044316326000, 1004.75531130395150000, 1368.79697372351070000, 1400.46398936633180000, 1619.26277977624160000, 1624.55609281469450000, 1640.57888731921210000, 1754.60717842280090000, 2005.42639977580850000, 2036.36402478868130000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 375.48366186659263000, 506.98946671947255000, 535.91469762205361000, 894.98957182233585000, 924.82586515782350000, 1153.97552123364990000, 1156.92163360294720000, 1162.12726448777740000, 1188.51644805702900000, 1271.36296460042130000, 1281.73023029477960000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 98.66102344433628000, 120.00678319489138000, 329.40555939200726000, 346.92074220433943000, 472.98918095172530000, 475.69057634421483000, 483.01029290073677000, 532.46687702196755000, 669.90140062335593000, 686.70301079349792000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 54.74571068709558800, 122.66415615837641000, 539.90231293357215000, 685.51917328949128000, 717.98698472284877000, 1049.50778451722110000, 1079.56155555817900000, 1356.19922794443210000, 1361.91783005714610000, 1377.17539579108210000, 1494.33729461389180000, 1753.52814931765080000, 1785.41122965256250000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 252.70941853602952000, 257.59848544551966000, 271.72213836811773000, 381.01339914038419000, 621.85533060310865000, 652.44956725295208000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 15.75012052607121800, 202.95619162505520000, 218.39013028812087000, 375.41312136542433000, 379.00600550916261000, 392.35178642615602000, 486.59049962083020000, 636.04401662102384000, 654.58621162485474000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 259.11375108209126000, 291.44538975285440000, 
+447.61160712828297000, 469.17711225810234000, 506.24274248086095000, 826.19003833965814000, 868.39903667651322000, 919.44578999167322000, 1256.27958414353380000, 1357.50361933688650000, 1377.91190156515790000, 1553.26849106306920000, 1569.85040160832360000, 1714.83148960000270000, 1718.58556510442780000, 1726.56167047688970000, 1796.98428886575830000, 1951.08153974333160000, 1970.55361194441930000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 21.83980134636447100, 217.22709700012814000, 220.84893346465631000, 227.59997053029770000, 288.19410216273928000, 370.48105003282780000, 381.58925049505154000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000};
+
+double nnlassolsq15[850] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 482.68119346765741000, 449.36878766027814000, 385.34533360572027000, 385.51097670140172000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1227.26486275052500000, 1305.65753656270610000, 1263.46426071565520000, 1255.83551679830820000, 1271.21263866917730000, 1294.55795615521290000, 1239.38292229599960000, 1239.20264914952080000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1801.99729932409790000, 1678.36488181709640000, 1602.43291438820350000, 1675.98396185292630000, 1553.60763407771450000, 1562.50999029326040000, 1561.93654641905140000, 1555.85932762494030000, 1496.87652267903600000, 1526.46361042590390000, 1479.02520678280940000, 1495.75608033418920000, 1486.99887442289170000, 1485.93518951226910000, 
+0.00000000000000000, 0.00000000000000000, 1915.83476671256400000, 2216.08032148190660000, 2064.33068389723170000, 1769.76766917974210000, 1654.00461485340090000, 1492.59570915361430000, 1399.83783865021000000, 1621.57745002592510000, 1673.51356991882770000, 1709.89416695228440000, 1774.27949985642450000, 1864.78532222460490000, 1890.63634088398250000, 1933.72897202145760000, 1932.83174002414240000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 514.24430542165669000, 462.85886608731983000, 485.21796732640775000, 524.33364075687018000, 524.02955756214692000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 442.30460047315904000, 491.63977101934847000, 491.61118370958729000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 5.65139915621814910, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 969.13071165782526000, 768.22426438618913000, 829.74806212061469000, 795.76688195288295000, 797.46062747893086000, 846.36226145094429000, 960.70827942536437000, 951.74887695929272000, 978.90826315568813000, 1042.24259759409140000, 982.61620249076566000, 983.78268335624591000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 2140.28105400259660000, 1712.67211550286580000, 1456.85759900486070000, 1720.29906016264410000, 1730.00691866457490000, 1866.37428641025280000, 1965.96786627611140000, 1893.57297176559630000, 2070.30525808561010000, 2002.45694937384040000, 1874.61267765190410000, 1955.96267222039750000, 2026.54390568576600000, 2001.37797089305450000, 2037.37297305816650000, 2036.36402478868130000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1400.67915551805550000, 1398.66175939090390000, 1394.98887952864650000, 1586.92685527388720000, 1492.01662109362410000, 1421.40543328930240000, 1341.37341564586700000, 1287.52308227140200000, 1245.62578188113530000, 1281.91503591961490000, 1281.73023029477960000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 767.62997938008357000, 753.97202816192453000, 732.91700162980521000, 679.88602270935064000, 620.11779578172377000, 644.82098675896009000, 659.33125453944365000, 639.49681089496391000, 687.40628743415721000, 686.70301079349792000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1726.81283898048630000, 1738.95161535452550000, 1679.10148868186550000, 1672.87117551051460000, 1682.27517448178510000, 1688.34836652200670000, 1650.88658322733090000, 1679.05019645321980000, 1719.95113573721730000, 1744.70720411996490000, 1747.88958711961120000, 1786.54100849664000000, 1785.41122965256250000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 547.63483423188552000, 563.69580657302367000, 611.93969268652381000, 617.53269421904702000, 652.53110724986641000, 652.44956725295208000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 483.52588181333977000, 563.70229108513024000, 511.79076283113540000, 558.66735536097235000, 603.95122141222225000, 713.83157419295424000, 690.53429033589430000, 655.07974963780498000, 654.58621162485474000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 292.11678965607820000, 291.44538975285440000, 
+2350.65027011250280000, 2283.34564072790500000, 2351.42117881839700000, 2033.55503008910700000, 2157.56448455299140000, 2134.22958905345330000, 2175.94806228014750000, 2043.85102153168600000, 1984.03423187322280000, 1891.18063944924550000, 1885.07408811887920000, 1884.03217824741550000, 1953.62273610005700000, 1918.69405136138180000, 1949.38721606444820000, 1970.70874012779400000, 1970.55361194441930000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 437.01648887405264000, 445.25452758107275000, 447.60681178332004000, 390.22229863285679000, 419.32701433100630000, 380.96184969456328000, 381.58925049505154000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000};
+
+
+
+// Data from file x85.txt and y85.txt
+double x16[5000] = {
+-4446.30291875903, 5028.84905877326, -22985.3161077938, -12965.9117937636, -17911.3213087672, -3262.74174337692, 4795.06530180912, 14424.0602996500, 8207.30227065454, 4128.30874330166, 2430.42846552774, 2803.38448427243, 6746.30669759998, 13366.9423699031, -13691.6165507419, -9270.50543665595, -7736.82932497997, 18663.0592821589, 1573.79083161248, 21633.8106760617, -3127.35336615344, 5832.69599414053, 4425.20446388705, 10005.2981709546, 5372.31654475748, -8649.2476416321, -10104.98760566 [...]
+-199.231527090823, 13758.8028903417, 2913.85455672069, -7768.49703581848, 7884.83313653815, -13297.6561031043, 5560.3962154459, 2636.68821028302, 3958.82068892338, -2124.95242996032, 8555.97805412476, -5242.62403782432, 4314.62861666068, -3582.24313047211, 2276.83893991901, 6967.30884141661, 3669.06747944971, -4999.64406536714, 3612.90333391798, -12294.2038729651, -7829.01875889069, -5733.35875368551, -6736.10698355809, 3475.95923158994, -8567.58846514573, -15388.7551785774, -1694.925246 [...]
+9995.58384312848, -19265.7578750555, -18930.9453972371, 9558.26605113936, -4193.03181386969, -3361.88336671084, -9537.38821898754, -11446.9173277818, -2790.83935233270, -7006.53843147593, 9598.8980159931, -24462.4158231299, -6875.99575846574, 7732.67493648013, -4369.73426734955, -8055.18742440938, 1567.53458194141, -4604.76376086286, -16183.7110520883, 8654.31862844714, 670.75052104237, -18538.8803640908, 5059.43179196514, 10004.5301443759, 15419.3228612348, 10327.8158226743, 479.5635851 [...]
+8831.27896271905, -8768.01776073482, 1689.11541602669, 10414.7684940859, -6373.12863565259, 5573.86389564855, 17972.8827640320, 13591.2080172158, 3966.29086805018, 285.840072211324, -7184.54232987653, -7748.90534464467, 18229.8734169223, -19389.5763333492, -4258.08133156679, 517.907038140423, -6493.33839625545, -4944.4892491573, 11825.3253675425, 11068.2635203964, -3034.69954062374, 19240.2511531926, -3207.75614898917, 6913.84458190161, 11773.2887150958, -8800.05549253495, -5071.78331240 [...]
+-7333.01990189634, 7158.86739985306, 13506.8860486348, -9100.56817494256, -11098.8163948240, 95.4255004750167, -17919.6251965735, -1901.58147466155, 6582.84901479934, 12306.2194463770, 26072.8738427604, 8916.15994608877, 5709.12085145632, 128.742935605794, -10183.2644627267, 3965.04919028379, 19037.5796783549, 30212.5933849084, -20710.2286884468, 8328.57074803504, -9814.8195482934, -10031.2623333651, 17047.2230150056, 7512.64815566836, 757.127639955764, 26600.0272055251, -6298.1774697529 [...]
+9347.04265006039, -10350.6910981019, 8736.52305337533, -15436.30818459, -14296.2242127671, -8162.29186666908, 3853.53368318823, -2521.15627627263, -16811.8585678279, -2361.90830903619, 12636.7403209299, -20117.4597917651, -5593.07659399695, 5335.98208581093, 8785.63400040428, 9127.01812001796, -18173.4151407379, -4545.4709948718, -11560.6684528686, 16635.4529494391, -8393.36079658302, -11852.1859005688, -18944.4431931713, 7685.26591427552, 12612.4574326998, -9252.40429004358, -15211.4922 [...]
+-5995.53121988317, -18019.4602707322, -13646.4744109201, 3194.74731570762, -7996.36094507915, 10122.4940734559, -10622.3233161716, -4841.83229277264, 16420.6454415158, -17221.8166057637, 10309.3391281255, 6217.57237321022, 8246.18125592628, 12362.6453590257, -460.821113258592, 20777.4704044369, -5127.96983452636, 6152.04331738408, 944.802596178325, 16071.6790372372, 4400.57944344376, -4219.90491817623, -3396.80467938947, -9187.94511680247, 6806.31303383331, 10435.7296790090, 7219.8055264 [...]
+-21510.2040171977, -11154.7163509500, -8653.12156660627, 6490.95238364052, -79.2744243087833, -2556.50734055281, 889.700390020312, 244.598507242384, -15060.4524846668, 8640.98180637262, 2930.65590243056, 7784.87206188429, -11087.0719953688, -3719.23557664824, 17137.1594932366, -14227.1221438924, 15144.6015990365, 14702.8096042906, 7299.47080293532, -7148.05373159518, 19249.6683950565, 2482.72840766931, -2896.44631169641, -9775.82673874873, 3435.55647402034, -3525.46959319367, -5777.03698 [...]
+-20932.2038332492, 95.0987209526541, -952.15718342678, 1818.75724762374, -2262.87740216952, 18711.7440140669, -1838.37837802321, -6741.65604738343, 20447.4191190901, 12942.9363915444, 2663.79934138801, 3227.07086512153, -5694.89386050004, -5846.93023062011, -997.64161900711, 9663.53757807184, 8850.64121655574, 3378.30270361873, 11360.5542888559, 7805.70664276096, 10880.6042231959, 6092.35632771559, 4386.90209030627, -5625.80076428202, 7911.29064656001, -13577.4932236733, 13602.2963918758 [...]
+1699.26795508696, -10207.7070197124, 14107.1278338485, 5047.75450698249, -12455.2223403825, -4652.31054955655, -14119.1090595729, -316.392259481918, 14754.1016116060, 22953.7539667670, 3643.69686296583, -5792.30420238198, -22132.3216247026, 1356.888571868, -10253.8534674367, -12587.2145406869, -7150.9639738458, -9438.4758714654, 850.615790935434, 2273.08234985376, 4581.43720938537, 12424.5252314717, 475.276311285321, 381.346699314885, -5446.54514995824, 2880.3088185766, -6746.02009229608 [...]
+-2743.60083932278, -3320.1112450428, 14560.2458343873, -3400.97491281597, -2775.93295497869, -4770.13730633775, -10922.6928469154, -7425.20220418657, 6403.05536374896, 4619.97913675305, -17302.3900193630, 4839.39661891793, -3279.60888785553, -12478.7008088247, -16904.2493629726, 14476.6368284110, -2926.06643750157, -8726.47574486635, -18371.2015995128, -5649.85692393989, -6371.88089610017, 27954.4509301265, -20047.7862795078, 1800.32119049700, -2087.83430203899, -2877.12529134018, 923.77 [...]
+10625.1792056304, -2286.71222196217, -3541.87370007865, -18455.6842496751, 6727.93529821636, 12967.0292978416, -14155.1831824680, -1341.67353994834, 11520.9760888390, -6416.22615767976, 1970.67467369299, -22234.0073977499, 6738.81074668798, 16383.5392896690, 21239.1466277443, 9727.42878574764, 5270.21430139042, -10968.7619476790, -6259.52098670616, -9151.10255821553, -8298.31624663028, -699.319840203909, 10440.3520781115, 11785.8715732585, -1842.44899918951, -179.953211600346, 25486.9350 [...]
+2226.69630459833, -5704.71100335137, 3833.60113901226, -9372.5466932503, -10637.1180344551, -6996.39448330121, -8486.87245298977, -13041.6391232737, -153.134105722006, -17622.8036159376, 6891.29520785719, -5732.10426268626, -2340.69023967648, -515.930308464044, 677.650405610995, 5640.47958158929, 9244.685786997, 8281.41822082807, 6043.04094836724, 13205.0496977132, 7446.20122394565, -2927.7994413243, -13773.273576724, -2740.11306785737, 3929.82093247399, 20356.7146077927, -12537.56211522 [...]
+-8783.42031994604, -1737.56461195402, -7604.32121636616, 1797.94629257931, -8287.31040304545, -15303.8672559423, 4814.61334073047, 14676.272020614, 15327.9137829835, -13424.1423571349, -1473.4198335295, 1147.74929297038, 13907.3565405096, 16033.0058806875, 12153.5750668286, 8959.23645513175, 12765.2202754253, -2775.87820884996, -6765.10677625274, -8527.29907600367, 8527.17379634158, 816.003015606435, 9451.83374974648, -10972.8307414248, 14710.6984847670, 9429.1021287771, 1766.02485791968 [...]
+5825.01718956564, -6595.30263798016, 5761.26486842958, -3022.39163750834, 3138.55278923852, 1055.39916415361, -2609.33614651978, 3179.70346383972, -14932.1858904932, 4639.43639810718, 2525.04927241399, 1138.41156805728, 7773.94884554831, 5944.42129207142, -12925.5759239456, 5975.74876428272, -15659.3929350009, -16025.2112438227, -9362.07559244824, -7742.61284541615, 12625.0470793489, 7457.16526764295, 18901.4588417705, -4664.07585145584, 5220.36212406478, 1919.94825046372, 18456.04481413 [...]
+-12957.1015411216, -11321.7902286672, 12367.8481012729, -6471.35737901138, -2278.75326582248, -3988.5401724573, -8261.89094621475, 20140.6492350361, 3091.90927596958, 3739.23430505377, -7617.96615686056, -4257.52937013318, -6474.38147762565, 14035.2060453271, -748.484919450262, 765.153799989756, -445.171074779358, -11003.8081847418, -2060.10820770349, 6200.17617508087, -16974.6742004631, -9082.39808580765, -12375.6940110444, 3300.80475256649, 10520.8548881238, -455.64505988334, -4955.125 [...]
+-723.525853399915, 15997.9604826724, 6778.53780026332, 18601.7053416417, -14955.527485876, -3640.93747696641, 1410.77378450703, -13849.5930978916, 8735.7088142435, -18385.4590872154, 20166.1945198068, 1983.73435378926, 3800.02526757044, -3895.91184282197, 416.611046937941, -7474.79985043133, -9659.12032779931, 2066.00275927219, -102.502527408933, -8201.58908191595, -5981.08778127653, 7276.22567054946, 6005.91236278562, 4599.73893867962, 16377.1258342125, -11633.4218471281, 2388.274931985 [...]
+1178.62794273604, 3062.00640272702, 9514.71309917248, -2969.54480738628, 10194.735191481, -9691.02886826683, 4883.05439202973, 5825.31423453806, -17242.6087044478, -2411.34478723849, -8617.85422852302, -7976.67147673879, 1306.09815586658, -1275.00292204358, -1409.31243753712, 8152.38976857047, 5713.80032732648, 12906.8603959606, -693.739105021399, -18467.8354097211, 9970.2118022107, -2012.14953144419, 1104.09866033490, -6881.35097695303, -5850.60367992278, -3641.67957483115, -17102.82132 [...]
+-18382.9649961955, -2492.99172601201, 7887.65735619021, 11781.5470679635, -7447.30259977951, 11920.666157928, -14405.7493764334, -6356.02300703356, -5313.32341955696, -11371.2577823665, -25335.0645128757, 8903.84229414055, -36892.4397329839, 15291.1480116576, 7263.14923225531, -6104.49540132052, -22856.3008004592, -1522.68289369851, 11140.0477591214, 6688.54714798654, 13416.3557138011, -16305.2168112986, 3154.81958883398, -5838.19306866001, 10754.9034159776, -12878.4514646518, 7345.31706 [...]
+-4452.47930881303, -2921.67754072573, 18680.8444050505, 9197.28269892197, 12919.3144272879, -3098.79026519218, -15991.9674720099, 693.552762081785, 27881.4579093845, -28768.6222640566, 1549.96874362546, 15636.4524872254, -5035.27220954853, -11742.6692000826, -821.352103412804, -4455.7770127804, 8138.57137502227, 12857.7542108174, 5591.65276902936, 576.00577268667, 24189.3892218142, -3277.31325024674, 1932.86904034138, -7339.5557020882, 1930.31322083227, 6339.08527350326, 12438.9331961826 [...]
+21116.0396664068, 18104.623402056, -1713.15089461482, -2491.43350065911, -9884.15345505594, 169.014042817342, -3209.38585720311, 14235.8234769601, -12710.5376748480, -7848.03575824076, -1145.66021319434, -1611.79867301743, 6368.6690597571, 13145.6220048315, 53.8387365548119, -2157.64796430996, -7581.96876575307, 17264.759077795, 8973.89207158785, 7586.47758071423, 7704.26835943376, -2294.81643044094, -3531.3681046505, 7022.16022478678, 6118.9903860563, 18681.9636672595, 1364.93425565124, [...]
+-24101.4936442278, -9127.98014699693, 11079.9854099627, 1764.28843802721, 1704.56384444494, -3309.12214441591, -17829.3778922623, 11809.2977685739, 3149.24359147056, 6564.55876149598, 4017.42707039502, 5743.07120134286, 13867.7320548654, -7035.12291010453, -17196.0866051675, 14024.6073043157, -3851.90511435891, -5084.06461008972, -8876.63816110326, -8675.99395329, 8358.27967059735, -1577.17917613017, -29285.2314519399, 23023.9419611770, 3991.92152527656, 3467.19964912498, -5704.041190752 [...]
+-24924.5544791785, -3650.59532437543, 8308.84033331957, 22607.5928922706, 8999.38418049785, 3452.6035906727, -2841.03380669866, 2157.92704808696, 4397.88867562679, 9844.67961151678, 10611.0481913779, 1366.23980049388, -16166.6374747694, 15747.260947659, 9769.92646448557, -91.8296208532031, -5836.82995922319, 16313.9180313285, -3565.78988839984, 20426.9232867790, 19478.7202391305, 1057.18283242496, -383.795317750285, 1370.42489651269, -4298.1764439963, 2773.92745328193, 10290.0613413545,  [...]
+-10671.0806047329, -6100.37854742739, 8260.27681194127, -2255.35786991765, -8988.26560994389, 171.479876866724, -14348.5082529737, 7103.03621065062, -9077.48028206535, -8170.31965021142, -13325.5280335430, 16505.2126617822, -3103.66798814628, -1351.00521065654, 13576.1909793895, 18046.9919653567, 9997.33849728724, 2073.46551599803, -12688.7223290445, 10487.9286879128, -3695.32880597225, 15562.0284015614, -550.835190829372, -3545.8262221149, 19551.9294573452, 1917.76530467563, 16835.04990 [...]
+17210.6384994744, 3512.75744417740, 542.629678195068, 28072.2810945352, 732.2171166759, -4582.66339082351, -289.245728635292, 10378.6559100775, 1889.00058410356, -5132.82633227588, 8322.62149614588, -25745.5130305890, 9895.097319028, 12412.1740231514, 16896.7903127098, 18080.6711394001, 7434.53458138413, -4246.1537458776, 22414.7666960305, 20961.4049819993, -7950.9165028258, -29724.9459328923, 3156.26498811137, -9700.12900018834, 1300.14494851301, 7197.12675340962, -24980.0319988177, 522 [...]
+7894.27253095777, 18323.5719636784, 10704.1500786813, 812.254020723239, -2785.64865611444, 6139.08534858038, -4311.34430077669, -13673.0615739481, -5920.18506830759, 14719.1125091465, 3020.73717782545, 30861.7224649671, -6692.36844396242, -5225.58571509395, -3369.51733090554, 12271.3406165119, -7149.4415161426, -8071.74498250962, -8424.91895204059, 1635.84989387617, -3444.31892636898, -7952.07755438683, 9526.68974015685, -4839.84905846533, 769.289237848559, 5546.94502992338, -17350.06849 [...]
+3762.85503842549, 4031.87730694254, -6770.46502705046, 8642.26762468833, -13907.7996288541, 4569.84527266407, 2264.26176507862, -4540.50890426337, 14184.6474467354, 5205.64966739947, 6518.13375084083, -11161.1762391910, -10624.2193710658, 1083.00650860404, 23580.8469662847, 12602.1976413301, 3208.30331231677, 10265.8743787526, -6082.5325920492, -16856.2569689670, -1835.11145919955, -846.699226630157, -8883.10792275469, 12136.4104489654, -18305.0924340147, 15547.5681092946, 5054.751163690 [...]
+13688.0983480987, -249.28813796191, 10715.7392473055, 18979.6770782045, -429.754977377398, 9246.91879305229, -5147.87444053038, -15334.3551774226, -5967.39885594922, 11624.8310949554, -2342.13584894973, -12533.4458400006, -12592.0738223763, 5863.59153779877, 1848.55525853966, 1546.48855152795, -1438.66720635344, 3627.1878146534, -6940.40248454828, 11047.6790814096, -16562.7701888623, 3141.02752085241, 4556.87295817738, -6452.67880811641, -7739.24774478221, 2757.85329282633, -11308.407277 [...]
+924.079012857369, -5652.2025865905, 1569.31243829277, 2928.12074349394, -4651.74744739539, 4771.40829942057, -616.887711796007, 3476.84831250737, 17587.9422728714, -13410.9394289594, -11651.6320978775, -3420.67286790382, -16804.3598651135, 2240.33610725291, -10626.1890261175, 5285.18343956972, 2038.70742575832, 8524.67036991264, 8189.49659780821, -7340.55825778034, 14921.5497122802, 5332.58600305423, 1121.30374174720, -18439.6711669820, -6763.43628516817, 3863.60151061774, 12400.68647576 [...]
+-9913.03130192718, -1211.65943793169, 3443.2165624384, 7380.3450652007, 3864.24968300836, 16425.7346964795, -2629.68154684625, 16200.5108859314, -8105.48157250572, 12060.6220192672, 1468.59436006664, 12697.3146355331, -4103.65420678754, 12588.7695739207, -1171.27829958349, -17441.6580588764, -3103.18770444867, -8560.95351324086, 16946.8222351359, 15011.7295048792, 2506.83352185125, 8201.9278323731, -5060.83295145870, -13586.6328718504, 162.649626602573, 2202.76779054276, -8637.5620579332 [...]
+9493.01358040144, 1825.62638009912, 13948.4185994105, -5073.44281419787, 32043.5132141735, -8394.71084718735, -2093.15024945820, -1526.26092613914, 4374.7987458542, -129.700762655272, -4093.61286234528, -4047.24197092639, -19190.3689445169, -10982.3385425403, -11713.5449579770, 23872.4206701219, -16068.5855342876, -14714.2904588217, 7399.8236785411, 3367.30593722763, -12854.4488232018, -6707.68824871762, -16178.4848759233, 12306.7162828418, 7655.11408996063, -24349.0187243050, -3445.4813 [...]
+-12728.4559269866, 5629.8459620861, 13631.6823767934, -13548.0134139384, 8266.55066547496, -3455.33668654474, 7108.33677531158, 13112.4936216847, 6635.15503566989, -5867.64069499951, -12385.3138233276, 10544.0030828163, 2931.81522433845, 1552.3827064471, 13337.5302910474, 5338.73338995823, 3272.11862033646, 2898.84382987889, 1096.18340004721, 2738.96319281159, -18058.8549496972, 2584.80853016069, -6038.50851061777, -14115.1983446274, 16322.1916286268, -2603.98997638047, -3786.85490228281 [...]
+-6272.5653331825, -7236.32734331851, 5908.90510847878, 5390.17023482256, 9545.2627336014, 4199.73868015885, 1198.49237081822, 9741.1084790573, -12316.5890613429, 9544.09273233606, 5120.05357745256, 6332.31167247397, 3448.86716280746, 11307.5852808462, 20394.0392838913, -186.504629776348, 12027.4438188319, -4533.15413911599, -5301.26710588468, 10268.8057465625, -6794.45551392433, 2268.65165361733, -83.652433775803, 6900.51946243316, -4778.77982267791, -5372.54741875938, -16030.5383497145, [...]
+-2250.43582081833, 3243.25256597962, -10254.0150686028, 6654.45487686613, -1826.48747839947, -3463.14840796074, -7815.0941221575, 8430.23520890745, 7188.20469494191, 6945.60921535771, 16410.2924689118, 6736.76189482497, 7745.9204059212, -16221.1649445202, -247.330917917594, -275.475774699721, 692.413760233559, -8708.63868695413, -5001.01893679556, -1862.67322525082, -3612.94386864917, -15831.1533389822, 10173.1901461352, 8753.40502647227, -2064.70898757714, 12037.5706393154, -14218.79440 [...]
+-25810.0050457399, 4684.86715465203, 18416.942701299, -1998.02422998982, 1304.09308274270, -9396.68317792588, 6937.62793506838, 3538.47019510254, 14759.2029323348, 7664.53403932166, 4072.39913804577, -12256.7339387193, 2636.46034970946, 9441.88434538268, -8979.05264688545, -4947.07603607942, -1779.75766408320, 3590.84109334956, 786.226858375473, -9254.56033023353, 9487.49631614999, -8361.68509167109, -7210.7509663921, 712.279727194506, 1309.39880676661, 4737.64543849364, -4208.7647447249 [...]
+-9149.64036474434, -6784.34085981568, 8959.39999440583, -5078.3552319073, -3821.87989909478, -9061.12006210987, -22101.4882438867, 3448.58434925652, -5466.81870478932, 6651.42578849311, 3001.34074154310, -25153.9167883510, 7362.35855481963, -8661.43636977808, -3710.18186060317, -2843.75234241658, -3099.71994611342, -9997.95192954663, 16199.2934043423, 2591.91580315671, 7482.75416214014, 6801.00290957082, -401.765799054447, 4598.56095978297, 10888.1714886931, 2532.83219634274, -3987.01625 [...]
+13228.2474232614, -3946.92709995964, 12973.0380145007, 4308.9390086085, 6370.37502523715, 5933.07619032577, -74.9012262678767, -3466.71880496576, -3177.39021860513, -2692.19049731203, 2376.28015345849, 26173.4576626823, 2417.70523359344, 18545.4688271475, 2778.64121019894, 9291.25261727364, 3845.64867223092, 3179.6969229086, 2665.98947565158, -6755.02354391207, 14157.1100647469, -14893.8207983607, -3447.67743811351, 17232.9637632304, 8911.83703423081, -5432.09668820714, 22422.5428685227, [...]
+-5217.89931302192, -7254.57602995788, 5480.06855260269, -24562.0669729962, -16308.5807271502, -8888.06873680487, 8457.59940310902, -13366.7315997877, 14821.6393603005, -6878.32063680132, -3652.92090868499, -9829.87927186588, 2679.88556705412, -4457.97855117384, 18210.6933702694, 3943.79778581661, 2738.14146511627, -4329.54347738814, -14001.8490765203, -13196.4090381774, -6985.0163505281, -1221.79811037231, -1410.15378770256, 16973.711757079, 12907.6742642601, -371.975569505992, -578.9094 [...]
+-4335.60490013088, -1426.75663898918, -3055.12710794578, 5956.36188918983, 7623.07226960966, 9001.43157855679, 18134.8915237240, -15645.9460242204, 10253.6942739433, 10307.1997862548, 22809.8101648468, 13520.5896022982, 2048.83694141921, -6357.45598514855, 9954.98716196133, -14580.3060726269, 28710.6917257033, -6972.89002578606, -19359.2973484443, -6368.00184617494, 8955.87461520616, 10009.0332655244, -16550.3218332803, 1443.47640242129, -9076.82604101418, 394.414055108398, 9458.61586290 [...]
+-14211.4471217049, -1383.58006853904, -5327.27296308935, -10086.6285226453, 10166.1096342072, -1083.16584052667, -2425.29887465457, 5444.85228153638, -9254.43417180365, 8459.01433953761, -56.2641571301898, -14798.5508560547, -12066.8734032031, -6564.02505628796, -7271.87803358019, 188.343146878933, -17140.2297190949, -21815.6176318821, -522.789807271225, 1593.69354088497, 1382.11459571009, -19496.1467272277, 1864.04409886415, -11191.1180396376, -180.926018367581, -740.322384917336, -2307 [...]
+2746.50483343562, 25888.2231921226, 2915.58460771166, 5473.66865210613, -1293.71068982715, -20594.4720768565, 16855.8163346880, 2813.03263215495, -15056.5110113005, -4068.94283316424, -4501.09644047223, 12856.9383674636, -10082.2482596385, 3313.79538401413, 7556.98286446899, 10928.7839458, 7870.3498525939, -6536.43579439022, 2305.87759301768, 12650.6392703309, -11693.4158129415, -14614.8471623476, 14681.8140369495, -10028.1214781452, 15781.1509265922, 10862.6208326679, 3556.09435613261,  [...]
+6158.57819155727, -5854.60604084257, 20002.3933724656, -17066.7083900339, 15425.1721493533, -2556.09480991714, -2810.5660713532, -8619.09446837385, 5829.6291867008, 10494.6186532747, -1854.8580238858, -10996.0143179398, -3652.60796646942, -7195.37546169463, 1083.44915374572, 4675.27628129671, 1135.23639876771, 2957.91687891706, 1380.10641723775, 694.231285286138, 11994.6767457580, 11702.6375464702, -3287.09288402414, -9969.39059542804, 2.12545226641903, 12246.0107232798, 22073.6476403348 [...]
+-13310.4606388547, -6390.44101749594, 7257.45416488951, -15526.8968775148, -6673.17920364402, -5219.03102210964, -14998.7422491707, -1086.11399134033, 10210.3255453728, 23055.0811112463, 4788.69949222523, 315.268760676885, 4794.66326495201, 14945.2153586934, 2762.23449170187, -8262.29464833157, -13154.3963382173, 12372.0754027541, 10234.4384845820, 689.62710671878, -17145.6876448099, -10460.8563656125, 7915.11733822246, 9786.47457900046, 9754.9614572808, -6282.03564176129, -1743.65227880 [...]
+-16875.1292082962, 3763.29111251095, 8989.02646096301, 60.4478508282769, 10768.1737974952, -20987.7127834383, -1374.88637432268, 15143.7775918143, 7730.6278753994, 1982.02102599232, 6339.27458114286, -18825.0043495454, 23602.6252931003, 4928.63627208618, -853.081851308652, -7209.92816795316, -2336.17980053462, 7585.30194599004, -9995.63375989602, -13055.7049437817, -9974.00521700848, -521.704165442404, 13682.0656678450, 7398.70561631001, 12134.2399581543, -2144.43034287092, 2013.81940743 [...]
+-1680.29774065343, -3091.17801686738, 15492.0686557805, 10640.8469793301, -10245.8341292277, 2422.46527003685, -14212.7799460215, 929.670125248562, 3516.61262246051, -2411.49563545795, 3467.05043699318, 10946.0771704834, -2441.48754895668, 13727.4213244873, -5966.95296513754, 13213.3484837941, 642.640427392326, -2227.35989250129, 7231.22402298473, -5396.23388898444, -1885.56721215542, -6081.67036929938, 734.730110770872, 14956.1574193748, 9512.42648018472, 10207.7044019899, 13862.4111104 [...]
+4159.81196002201, 4244.22247664001, -4851.30277900159, -4380.96448571814, -6614.52035678363, 2688.56796875238, 24445.5296012281, 2515.79896231403, 2309.84828652974, -2677.12109380237, 10948.0179987176, 19264.2058873159, -16484.7433606266, -15987.1867451069, 1062.39339411614, 4811.19013599586, 3531.81614565999, -13867.6473935627, -535.750332753801, 9549.90764476147, -31666.185182313, 12203.1928528749, -2180.32935066165, -3920.58393360259, -12196.2268742005, 9710.0691545226, 5676.025430410 [...]
+-92.0907837838574, 174.817706281885, -5600.86038909192, 15551.0106646033, 12244.3871802829, -3493.1580849376, -10948.6475223627, -2650.91898644484, 7902.0559962266, -14835.6489763704, -9510.15281404809, -3193.71651646943, -4540.40948112004, 606.83963430805, 1301.00358247700, -7074.72114991924, 5951.24888952836, 8848.80632391271, -2619.81103651760, -2874.22239532047, -1677.19003299221, 12538.5161255956, 8182.73264543256, 13181.1410714183, 2114.56973899189, 7736.84849038894, -4087.03759448 [...]
+-4004.30977936184, 2938.42238161867, 5426.16744290725, 12957.2246514034, 5709.22477818655, 13919.7455359333, -4141.68566418488, -6562.58343846725, 12343.9018390385, -4123.86377315808, 6013.12698856399, -16206.1018612041, -13800.9426888605, 2147.55998763194, 11257.5448812903, -6356.01188726838, 2375.59327444373, 4489.28847962865, -2744.19104996733, -10017.4597658724, -1554.26414923558, 12005.2965441188, -14182.4260231453, -5543.88020279347, -21745.1529908875, 2273.35930779867, -16461.4187 [...]
+8106.25738794082, 4564.20052143007, 450.613855778297, -5445.55702770103, -24276.3966948224, 4534.85607635482, -3552.37641269621, 591.47513278948, 9981.95116563652, 1898.90494350442, 399.235894611005, -15727.6511493885, 5525.29779732299, 11455.2361137686, -3831.54069376969, 297.663058815603, -8692.60806703573, -1206.51047876177, -1829.61136854286, -19768.3815332741, -3533.95532607610, -2400.26080137667, 11984.578070646, -941.511910683423, -1895.52045344493, 10332.0410276166, 10978.5514933 [...]
+-7625.9898465931, 7608.41885071536, -2814.84621963003, 5021.94989865191, -7426.25335444688, -1062.74308582796, 56.3948610792715, 13279.8201751826, 20804.6691035164, 548.449375511547, -9388.4486532282, -14673.6621903359, 8443.85805365376, -10448.5578947872, 24341.0400058651, 1059.1023174639, -504.713070211254, -393.382113810857, -9889.44787160805, -126.962882932581, -4449.64506656739, 5550.39801687591, 2851.19069258494, 6228.85945420299, -4036.03013960537, -16290.1100242746, -10137.173489 [...]
+16340.1625070585, 7213.2939630341, -4376.7343978181, 9346.34110508917, -468.558960971633, 27964.6417281241, 7774.7575712002, -12040.6969879169, -667.12943976931, 13866.4095893241, 10971.2853779882, 153.66510678412, 5195.98883883502, 11395.7104261767, 5684.15709418923, 15412.9432201833, -4157.8624824162, 7126.13255459933, 16668.6612805469, -14057.6060316331, -6153.89872414228, 3479.18965770989, -17271.2858222956, -6195.43673603315, -7434.58315142202, -8653.04779299767, 1367.35015042040, - [...]
+4455.59461052404, 13482.5151856008, 22949.1539530398, 11872.2768915280, 1744.01282104163, -3512.24152694203, -4361.94346317038, 2981.58086130778, 3875.90340551429, 14631.8449932627, -12106.3163774425, 11496.2557426830, -13559.6147166088, -5311.35654707698, -6564.18259662366, -3764.08633327109, -3634.89018668298, 12054.5164692592, -13833.1080802707, -6043.78143870292, -12776.7763867705, -13871.8460704667, -682.377645162415, 10133.2824113496, 19788.7727971756, 271.582625164747, 1249.804153 [...]
+-13708.2279870740, -322.874494930355, 13761.9538520949, -2656.78588158623, -4014.65004025729, -6894.55720635385, -10296.4377293719, 9608.88089489273, -6663.95460088658, 17569.9657262544, -3043.23366142935, 18063.0031295938, -17699.2498828896, -1952.66222619756, 15341.5056325401, 22065.3933989134, 12294.4401415813, 12136.4416354826, -6590.43417223555, 12058.6044812859, 3882.03144987462, 16691.5329070922, -1387.28790843418, -11447.6584863416, -1216.14776647876, -7165.05087505471, -13016.26 [...]
+10343.9575379613, -9319.51057705605, -1589.51514280108, -6282.1018313303, -15065.4262672160, -714.714974293636, -6054.65818869089, 8815.99956738562, -14771.8474593427, 1553.76644526293, 17304.2947921375, 3257.06860201226, -18952.387712303, -8522.46606162269, 18325.9093645709, 5420.03267211994, -7052.46249818743, 9536.30917895167, 6280.099932781, 11209.9330685733, 2986.6079562768, -4720.6251544884, 13665.0462725348, -3655.29046105725, -12110.8134547871, 2991.04769469329, 22663.0537427292, [...]
+9641.31227745087, -727.064854074337, 1990.22422274821, -2839.08000907911, 8213.71917328135, -16883.9589475088, 7992.57012975678, -5007.90478466786, -9621.66824057044, 8703.50284581805, -4382.17711595681, 4314.84354580186, 15258.7660403431, 4393.60343673156, 7607.50506231398, -3811.77196494275, 8886.54063649646, -13449.1180503240, -12401.6945783683, 5360.47951344609, -5055.76076646272, 6076.44163052209, 18281.5037278442, 6738.58621480024, 6536.97838430489, 7011.40916514098, 23231.77520387 [...]
+-2188.46522978359, -6235.30537786123, 8859.96140560362, -2514.40538369765, -9028.17156889225, 7756.43026072278, -8319.38535230348, -10528.2347154334, -2275.74119407236, 14386.3980674161, 11330.1440380799, 21067.9049765757, -10330.1018821800, 22281.2427187712, 3962.23142082979, 7940.23377943411, -4858.51140650942, 11525.9719993072, -22496.9723552656, 21904.3978643080, -3602.99373839435, -17709.3690441504, 15568.1529131389, -11827.9433304722, 7142.62735263877, -1230.5757814082, -20058.7574 [...]
+24757.7234452621, 4917.8598965136, 532.093906427774, 3403.77214496844, 8813.36769314827, 2893.50773479891, -16125.1610587960, -4934.28119181801, 21348.4160321854, -5639.83528711089, -21784.8141610520, -24069.2155005096, 348.615650352769, 19010.9590872391, 9615.14761137392, -4026.10952639011, -1211.57742029397, -2227.97394995579, -290.981668305237, -3514.00390315202, -4671.93330320129, -7388.78820020317, 3189.52432480698, -7668.44893580565, -17767.3040160582, 21978.7486301512, -5188.76592 [...]
+-7076.14306389216, -9413.96276468069, 23909.1436851207, -7191.26687543096, -4996.47793961184, -4423.45760098882, 13309.2990385681, 4226.24525648871, -17039.062190621, 5120.18720005827, -371.750668959019, -13039.6195659475, -12225.538282241, 20472.6507438323, 1156.76021275742, 427.915376018177, 1893.97894291198, 11708.8284463396, 2586.32759983521, 8247.69450202247, 2054.21200006137, 9139.45661223463, 15276.3607282629, -13327.3890401252, -17.1473486721982, 445.005840127444, -17262.46129355 [...]
+5388.26150877939, -4203.51352335426, -2347.62925730826, -4736.21041635124, -2133.21824377826, 3366.04446969544, 28028.3037100439, -587.847533026096, 533.333748927953, -11819.1789306933, 16167.3086815719, 8372.48117338486, 4700.88344577425, 14312.2291096501, 11421.6308375917, 10135.8210480948, 13564.2074936450, 2169.40472046488, 6561.26268757996, -7201.91406812663, -4926.86581742236, -2702.91477909309, 7989.76391247635, -14727.6138647691, -6925.76565057703, -2740.72786470796, -4716.775177 [...]
+-11412.0135139239, -12642.3598984828, -5404.32442187385, 7498.97386169343, -321.686757476826, 7784.01780893427, 11805.1882353848, 8607.44196677782, 5734.75209385348, -4984.02544446854, -10885.8027567434, -8495.04583657226, -8119.25092609601, 1995.08143302175, 4551.19593133341, 19879.5560457329, -448.371353269134, 294.430749587682, -12736.4057642938, -8711.01907680092, -1035.33993629375, 895.497729970661, 3773.25662609, -816.826186329542, 2973.66410979194, -3258.56517186557, 7613.84944709 [...]
+6114.7704898786, -23503.5338793908, -641.088522244579, -2272.80888019285, -6629.8031694476, 4811.61906566509, -12571.1217952672, -2044.14486787511, 1596.80727300191, 5583.14743608453, 15094.8517850624, 6051.55296374775, 17701.006489103, -740.591705395112, 6204.13426438419, 12971.0133365343, -6604.53776450685, -6068.94291504998, -12386.072292001, -15383.7026646984, -3614.50099870953, -11289.1663851952, -6120.63559929207, 8218.85443409501, 3137.41913093054, -4553.9362715322, 2585.434787593 [...]
+-13585.9727029862, 3563.13871193783, -4625.17185400322, -4124.51832406428, -4687.20926387210, -21635.6563651705, -4948.6751816615, 8580.92789279104, 13147.6690342742, -9104.21008135626, -9413.6151664851, 863.34323563311, -379.589800327678, 2674.01278277929, 2212.83271861323, 13081.0197368649, 648.136159120674, -17484.9014663824, -2942.96921506690, 866.390014227933, 7713.65295854772, -3346.49906138067, -12720.1716720347, 2362.32187023975, -5378.52973729706, 2579.53274898316, -45.311247837 [...]
+-2144.01106019346, 4786.54417018199, -21715.0561462075, -7507.56701212251, 15055.0346482749, 5359.36419052129, 5714.66056704702, -15084.4621596942, -4330.98527256464, 774.897409311048, 1481.68726131347, -5227.65737163554, 6301.11408790924, -166.224307513422, -10442.6144828642, -12114.6294871203, -14627.6738256571, 3286.66227788555, 13138.6273533974, 9297.99122663506, -5760.56154089831, 5500.98531643949, 3183.17345473292, -1662.03739603806, 1195.54985710825, -4853.94225936637, 10527.19552 [...]
+-1918.19739432983, -15680.5510223584, -7992.99218778565, -2269.97456633802, 6830.19807557797, -3899.78148456379, 1457.09656029858, 22818.7719879995, -25826.7072168164, -19457.3998656491, -9656.55736562892, 10861.3684001292, -1592.19350424738, -834.160000543117, -7124.35221743294, -1033.98657825909, 2952.15362641462, 24758.7730636661, -12437.3270492344, 1963.90972529356, 4218.47746139132, 4750.60733357899, -6070.44853116516, -20290.7295830875, 10282.6737630517, 17700.8883343572, -9151.580 [...]
+6522.19394100721, 7751.60374776424, 2547.99133907687, 7810.89029643328, -8785.93048911774, 6939.939357642, -8746.3112185101, -1978.41085824789, 20597.2400333752, 13563.5574301931, -13673.9258080676, -16984.7220145648, -189.361157854771, 17951.5548867279, 7766.12929219578, -797.41272207052, -304.118502288388, -8243.34289351227, -4764.28478908875, 1964.60145087549, 4047.09075654729, 8168.5644859889, -8547.46369094195, 555.658975192156, -1059.51239730780, 13047.7045759526, -11349.4000327072 [...]
+155.931668875536, 6697.2261765975, 7148.42447762031, 2580.9416586281, 1593.36738261416, 1829.99563986935, -5330.27972507716, 1627.01384471728, -12632.6794956984, -2401.71102422785, 1225.53217909064, -4219.59671842356, 11227.9505564534, -11094.1740670416, -9309.42237465071, 8808.36258764963, -7125.90327878248, -15752.2649730639, 23301.6852515607, 5525.86777312284, 12623.1768716935, -1198.40185847777, 16894.6421199505, -6258.95111580638, 4713.32131335316, 21987.4118361853, -6033.2635854992 [...]
+-10993.1663232787, -7654.64400082862, -1587.73219345621, -14314.4677337411, 8052.30784373237, -3265.65449846809, 13998.1840059465, -17791.881508866, -13903.2938411951, 18787.2556349634, -10866.5191576882, 1562.69994782068, -6743.60781553432, -7808.64007597334, -9966.83897101458, -4604.65292461617, 2697.98034574874, -2123.67881790129, 11548.9043611746, 11218.5207471279, -4666.90996681339, -150.893764828488, -8128.33529583239, 10058.2149467795, 13491.2915157692, 2914.49053479483, -5061.857 [...]
+15932.7556188022, -12239.9977728745, 10968.7185882961, 14461.2027867276, -20474.2960159420, 15407.6101914931, -4162.15674258244, 1458.33950153237, -9402.42166507805, 10567.0981767782, -3134.01746225997, 18794.9195962181, 2608.81558088572, 3741.40933496035, -5128.12190220546, 3625.40427410175, -8749.15258023015, -7713.61925008994, -18181.5168967804, -647.112518285898, 402.600817005027, 3698.77917768583, 1185.04127595888, 12400.7342190495, 3657.57659369482, 16556.2086244872, -6924.95632377 [...]
+-73.9135199535448, 1450.94218274461, -3895.49278683617, 8008.14442430479, -12496.3174050484, -1652.79989575913, 21129.1667194672, 11263.2587418833, 1408.13543489426, 6558.77726391037, 8975.6777308303, 15992.3901976654, 13726.1763362735, 12675.3405482378, 17036.3972503311, -2655.91601547697, 7016.99306411048, -3406.75127483135, -543.951537599142, 1687.58171237003, -3798.98101301133, 6502.93303779707, 217.806525694145, -6205.4052216151, 1247.01513823974, 11508.9879044982, 3913.88713383429, [...]
+5949.42523097424, 7757.85364101358, 939.349397460506, 4951.90534708443, -13935.2673902716, -871.46325671549, 12259.3017229061, -5211.55064391783, -15024.3660739876, 9457.77242896715, -10269.7169753028, 2228.30264066227, -4664.20934535778, -10281.3073072390, -1135.09260276975, 3110.77677070758, -6979.44983242943, 4799.47667616011, 225.482960199793, 7893.25631009365, -5887.06007746104, 18956.8704639159, -2440.44229168291, -4061.25096603497, 10468.0047580221, -5239.04172360848, -9778.197782 [...]
+-5263.10966897204, 13975.5463198470, 2207.69873736784, 7152.56915290644, -16744.2991858248, 22811.6598429292, 5353.13597946928, 1166.74504903300, 10121.7764295439, -4097.58411001747, 2629.82460874244, 11235.0826880209, 16279.2208599871, -3037.36384934991, 14459.6248607973, 13562.5253713375, -9499.91851813146, 3114.2901029513, -10227.9175773884, 11729.8077408589, -6966.64795434526, -17901.8203103441, 4376.4996241368, -15524.9018196342, -7082.74365286324, -1313.85473587334, 7331.2894987813 [...]
+-10310.6615363225, -14609.3792670958, -787.486181276315, 6429.24872236995, 8907.67948220247, -8413.89447818729, -1044.05377970346, 13897.7156601821, 11141.3266672031, -13907.0536409012, 7698.5474176656, -4548.13110766806, 14663.9182910145, 8700.61683630895, -7186.87216702396, -5391.03381524538, 14431.471074838, 159.371511176878, -4475.62752135789, 15459.4689486599, -7194.85570955595, 1590.97680722466, 8007.66446225916, 4088.87944694494, 19519.2422435594, -14140.6153301643, 1376.091664963 [...]
+11811.5765718556, -10081.1511995636, -7522.12073912574, 949.02005230341, 10263.4563190963, -3506.49468894173, 10761.4242646795, -296.331597197357, 18755.8418956995, 1981.05693240571, 18389.6033709568, 1451.44666395068, 16770.8755657874, -11116.9479484212, 2913.16989681227, 2263.35781998995, 10763.9868656159, -1498.04196354282, -1473.61170350969, 1059.93807462781, -2096.62359142696, 15070.7999888905, -8458.4016511386, 14718.9456959349, -8859.50107013077, 10023.7748630516, -11231.875063503 [...]
+9310.98441880604, -2041.68534719710, -12489.2341323784, -6415.16529462247, -4966.387173322, -160.333138663358, 8523.07468695075, -15257.0891017098, 5558.38054591277, 19445.4669899427, -4824.18012821709, -12499.6358064531, -19494.6134741439, 5626.45279582521, -7130.76609084749, 7324.19827005031, 111.519291879406, -8417.30949307341, 245.955895403059, 9994.67864061416, -4321.23383765917, -9145.26830842447, 3401.64193504901, 2672.04865675039, 13867.2760334472, 16564.2079252122, -4515.1363359 [...]
+7550.27372452045, 1757.39354095168, 7445.76997396904, -2083.42690321786, -4234.97156461879, -6203.77749810713, -4282.84299532882, 4233.39463083756, -2388.83811896788, -701.486355839752, 10263.2827909920, 1873.93806808602, 1940.95055271247, 4820.68850904069, 3024.86820665835, -12081.6128677887, -10038.2412029157, 9152.7521556099, -3421.30512254111, 5908.08253481192, -4144.75347345602, -8849.71463338695, -13790.6180247831, 7713.15231303741, 7987.46117316955, 2592.23254874888, 1396.86769859 [...]
+-7816.35037398823, -17895.0735026012, 8397.24685410849, 12112.7931868869, 9270.72245869695, -2789.69970076344, 15102.2028406718, -7555.78092596484, 4677.03571856601, -13688.5482087762, -11458.3241048487, -19973.3931445235, -7794.76440573028, 3773.30085070766, 2752.48703824147, 9204.82656687749, -6807.5246240701, 16834.6151477808, -5163.99281931653, -16581.5099935873, -7780.08298959236, 599.656764815198, -5086.71771279079, 1950.33056178315, -10009.2261358119, -4797.78327470048, 14483.7493 [...]
+-5070.67310520878, -3372.31607872856, -4783.56239548888, -9426.92009419808, -3208.02599759254, -6356.46157839123, -17669.2700150039, -712.155881919488, -3255.58410071899, -8536.32043611195, 4991.33982799356, -12317.4274649777, 3637.87021288147, -21998.8947460524, 91.4883924009333, 6220.66842877936, 4065.52940496616, -324.142542560904, 6833.06378878503, -666.025354842145, -6335.97585172054, -6047.45636222368, -5026.74683494487, -4270.07676391747, 8947.87421069715, -4972.72031128561, 76.02 [...]
+6218.47826111877, -22811.5647879734, 3916.60539555883, 5346.17944469224, -2594.26527854619, 9266.5539812867, 10684.3688411953, -11535.1527926528, 8164.55989447002, 4785.07056613689, 7083.72163996352, 1286.77633163619, -9544.0738425443, -6024.40769151498, 1783.49017002396, 18385.9076930775, 659.596088090242, -11040.9064909419, 10247.8307791165, -8506.34554805764, 788.250886314139, 3853.13263011954, 3037.77556635182, 2774.39484465379, -12555.2413628930, -13393.4463828859, 9401.47166456468, [...]
+-3186.53945947193, 5031.52215827635, -4926.92282173255, -402.977880482388, -7140.99867743827, -4846.55176420582, -9129.218892718, -2975.35889166414, 4916.59533277756, 18098.7341127356, -4782.51405470859, 3149.02948061864, 4430.94859746861, -8337.79690303764, 3976.65904966239, -14603.6993945363, 4227.560109733, 7574.32563863824, -6926.39120436964, -5657.60191502037, 2120.30697214556, 2346.79079825723, -13232.3182227306, -190.225026840724, 11770.4670450992, 25086.4826597359, 3672.237412862 [...]
+183.155618280135, 3231.31573066704, 21455.3842689350, 5121.25923311255, 17025.7051121999, 19754.6049158575, -2028.14580302316, -9140.00630054474, -13501.2341714907, 1168.27919812746, -2494.62966436956, -3692.31061847233, 7980.76338292334, -6731.01925203623, 1066.82916545191, 17155.6910374466, 15454.0499240768, -6442.90787581734, -9390.58643726282, 7311.35422547911, 5911.63671013834, -2072.46169580350, -7015.88173856312, -9097.65220280166, 10156.9035917037, 9293.01910832525, 6573.25554936 [...]
+3998.55690410063, 6038.10746105, -3332.5476934733, 3562.06084196154, 16102.1659568066, -9489.32203231492, 29193.3326296748, -18606.7193521217, 15166.1349089166, -5748.19487412901, 3750.56260571543, -922.51198266607, 4742.76134377899, 10069.5423608186, -12888.9833428745, -7501.19178870063, -3842.05974934851, 11601.0677624874, -466.969702614429, 7917.7670551071, -7071.03178487812, 14596.0089103811, 13296.5565625269, -5914.24394971471, 2535.26931669274, 13102.9897190672, -8717.67493187751,  [...]
+-9007.63234518614, 13077.3946813801, 10133.2849522432, 8525.66703301123, -11895.5473674982, 7471.85160164196, -2530.69907984129, 5493.37681269653, 4409.97170321046, -627.722738758146, 8954.11839760488, 1310.45945228388, 9389.1121748309, 9335.63137170492, -4658.07980551101, -8914.26525101482, 5651.12017463456, 5386.47699764787, 5158.42222650967, -4390.58683937144, -13178.6613839112, 6896.33202632995, -12515.1063444482, 14632.1989663299, -4099.14851116807, -40.0104246973726, 462.5599228224 [...]
+1934.01549516544, 8118.53133750003, -5509.10766569412, 4076.17310255183, 17853.5439970549, 18871.0834302581, 7226.05927501717, -11265.4017419796, -2304.35879028905, -801.425234966716, -17112.3208512517, -7099.04454191808, 2070.67747472117, -4832.56225602072, -20492.1407854425, -1838.29505513301, -657.580805595867, -2535.69708637292, 7874.7655886271, 10730.5783265365, -8463.45397720906, 11656.3033933907, 4133.48154406525, 11035.1988843253, -13839.5422966571, 14615.2010832673, -28082.69276 [...]
+5273.52874327244, -7638.39996852622, -4018.73129127721, 9972.11187949554, -1127.918889231, 3198.12309494983, 7558.1503591557, 15192.8829447127, 8421.98028380398, 427.309039935766, 9116.24502724798, 13717.1172507803, -7215.44406317293, 7422.80490994616, 16349.9043813209, 4563.89840771743, 9697.00932683428, -10936.0710275258, 3678.91050868429, -16165.4196004815, 6276.46871677994, -8419.06372052301, -12638.8876304982, -13321.999557682, -16106.0204924881, 8336.83482180346, -670.269963655706, [...]
+5577.99981832848, -1943.78763681442, -245.626328095708, 940.121023532588, 15385.7571249629, -12026.5630228607, 5879.06108609287, 50.552731903682, -3594.84833895338, 6338.32603369617, -8752.65179926682, -11605.5015645660, -854.459749840127, -2982.48124615586, 14729.1094567361, 13312.8901688853, 2200.5680942524, 6613.95962491325, -4450.82289595971, 10599.0202464458, -7217.63052230578, -6648.5805793997, 7728.56441333855, -14802.4968985966, 37.8446990717845, -1668.90775383039, 4559.475287606 [...]
+2907.41123383389, -10246.8885148548, -12011.7989678471, -7914.58051203641, 11528.2234264318, -16257.2707113737, -5468.94970934237, 5348.99542500667, -14564.2075660051, 6723.4163931329, 7328.90206954418, -19724.5273735237, -15165.3538723364, -3511.88776957208, -1580.38781489423, -757.936124473936, -12728.0139475509, 3812.01699168824, 1437.98749137255, -3615.3125261716, 16409.6508986547, -14973.5291095189, -3020.49020955542, 5485.15138976645, 8517.27881408702, -1465.74408869132, 5753.88444 [...]
+919.071274787065, 4793.72034366191, -3422.21982317222, 4849.14406813718, 11819.314657723, 12777.9473141238, 22134.4543285438, 7246.76528692353, -2253.66398390234, 14510.3410604789, -2513.54228680425, -6855.72226377805, -1743.10007569770, -4121.81706842882, -3555.70750011998, 5736.87462256072, -1919.03121204395, 19095.7876982514, -5669.4708520211, -12236.782087025, 4777.69716073452, -3166.5305147282, -760.155421103646, -3849.60781810927, -2041.82135196943, -9434.31104841591, -5182.4203909 [...]
+9137.09829241257, 1067.02481435519, -6244.98219915596, 2518.67110493752, 15859.5868931084, -2722.76367582497, -12065.1007647869, -7274.80397243159, -12016.9105364263, 720.888662314678, 8732.34507153148, -20358.6645642300, -1175.89815072749, -9724.50723790473, 4185.56826911442, 18800.6916547775, -2291.91201224061, 9423.60949142857, 3358.82769164652, -4248.43835887664, -3542.38456145566, 8319.1994642736, -2405.48397316920, 7480.55847594406, -1071.68498845750, -5667.82367079103, -2061.17095 [...]
+-5510.18988311397, 619.355589902687, -6027.6320895577, -10860.2514314017, -3113.64069340408, 18843.2520669537, -2557.38335416753, 12983.2567743349, -8533.34953851433, 8456.97500271533, -16039.1454595961, -7057.31287287773, 8588.29497396596, -10504.5890497726, 16837.8414336691, -1342.91963754622, -15353.2301859815, 3293.43087493185, -11678.4471807781, 8972.52583973525, -7629.30908439395, -19575.323116399, -6111.11270039674, -3780.83423501468, 3055.53140212547, -10611.4185599944, 20912.426 [...]
+-12836.3085696339, 4340.71410492209, -2280.89325896350, -8429.21946912653, 14444.2829105543, -12772.0370970226, 1282.96062342898, 355.206285622619, -6465.17648850943, -16799.594577836, -4474.42403447119, -10290.6423561093, -12995.5832993685, 4525.53888663243, 14544.4888375831, 2280.83309830126, 4725.9383596008, -9351.16790940909, -9826.95459472133, -11432.5522402996, -9544.21326028434, -12101.7351232654, 9536.4843217989, 2025.73927638913, -4625.40354759533, -13665.8201750850, -14871.9521 [...]
+6882.73936918633, -3654.90210629701, -10355.668108952, 11759.4971816874, 9174.91390736937, 1718.81799700682, -1228.86044203804, 14487.3289237989, 4697.32482930793, 5800.13733313012, 5830.6712821672, 730.602953322254, 4986.1331080451, 15632.9942284287, 7012.81246304325, 2944.71297199652, 13675.4669921582, -10372.5991465544, 2415.35417139028, -5376.86963476829, 13676.0556478404, 19807.8597630286, 8100.05173692675, 3387.982960003, 7745.77779525929, -250.286801443434, 5265.39549971986, -3584 [...]
+22401.6221089088, -8284.44136571263, -20932.9541520013, 10251.6260411825, -18245.7188849666, 105.422527929382, -2165.00759480545, 8906.71042209327, 8926.03925737035, 5214.24112590683, 1095.23884014504, -5404.21457849279, 8916.93559981408, -9435.75840912754, 1212.39915160809, -7778.31894799173, 1318.70441423650, 7023.39888605177, 4318.05120603506, 7017.03477806745, -7048.66947082083, -2058.41356983616, 8884.16656804325, -1513.01583211590, 3082.33148118724, -15946.3519735212, -4263.7523169 [...]
+2198.02973500319, 9478.2378175408, 3115.90003207139, 16191.2274155801, 4924.66780267098, 6741.81170956383, 3186.01922849269, 11154.0901369094, 2967.43796846392, 10517.8184996700, 2147.60639129734, -6818.06478326478, 5376.31344268589, -4168.15570891874, -825.387534258854, -20572.7122658807, -12544.5060198599, 6753.08316898385, 20881.9217049508, -3190.07512085436, -4087.19079729251, 4549.69469830594, 2050.65736394035, -1940.10434469181, -1278.89197874975, -3684.56755748337, -11315.63968584 [...]
+-1103.12711537562, -1659.07591065664, 19573.0827901313, 19825.6681711834, -19238.2418925321, 14665.8327489424, 10298.8075648357, 6374.258457875, 7880.18680865851, -9556.04913718343, -7020.53648748037, 15475.9174718265, 4444.82485741155, -8166.04484663592, 19225.6131757626, -2573.89819719957, -3314.36826675348, 18989.0004489535, -7226.90950483008, -10553.7727933449, 9559.09379796556, 4487.68391705557, 1311.28864964541, 662.209082932184, -2170.07341752065, -1855.20277876112, 3955.069446580 [...]
+14352.4644666269, -7807.07453676696, -305.0172248321, 15964.2692558358, -7709.58785921924, 18485.1112810482, -1087.07508375838, -6266.19296707983, -6230.10061168303, 8922.1677042164, 1440.43749701289, 14860.7187251280, -9797.11388336059, -10219.4715727616, -12375.8838748618, 8783.04072053375, -4999.73244102549, -12581.8629992407, 2380.38777197949, -6324.83318795613, -6679.59625872678, -4865.54493993554, 15641.7375001039, 733.021855679172, -21591.3689882858, 9679.21674609023, -890.3818712 [...]
+3219.35711050929, 10080.4893315401, 5698.7596249279, 11600.0650245297, -5050.81343915712, -1114.78812699055, 17290.1391182628, 9432.25985563366, 14113.6431106947, 2306.86980169527, -12437.5483259312, 25831.3434488170, 7045.29299147667, -27011.4872736866, 7931.92211210702, 3106.48040654032, -5840.76737330141, 9412.96114286597, -2998.89870777712, 12151.7279620956, 5182.86454030224, -6307.34458098253, -3487.24348835666, 7583.9953294988, 6129.87266941813, -14587.7682390004, -7954.53470406163 [...]
+-22069.0292293548, 1075.61843956873, -7371.4700866978, 23360.8895347788, 1683.16341147967, -1508.3908988384, -6782.04798754348, -10003.2191099024, 3393.00366495722, 11025.0647419982, -3890.05296073076, -20883.249236256, 9763.94561297952, 5786.88547930806, -1521.08748529477, 16438.1583566975, 12656.8017654840, 1551.65229986523, -5705.7210216454, -14501.6567829470, -2614.02855499023, -6085.53832918329, -2197.85851409058, 16336.8884081738, 2975.5547103976, 3127.70679661785, -1943.3623237136 [...]
+-11331.0860103449, -8604.56214602625, -9190.93243560137, -8594.93666091206, -14531.4996079529, 10041.4146816604, 2980.56540697839, -4868.73209023428, 1632.97464069524, 9236.13153084593, -6963.05791348803, -392.897370464948, -8288.80423395563, 5820.36006477937, 2714.13609213595, 1144.40809216701, -7001.60175973991, 8571.92061238144, -8012.88249039899, 10090.2020306179, 5485.56558720046, 972.274033589876, -2271.5584732893, 1323.68979778897, 4070.23098682774, 22445.8436966727, 13752.0638520 [...]
+-7835.09907460374, -3637.63803456224, -4334.73876684031, 5130.54416806458, 2488.14471962772, -10760.8941654135, 3654.00213214221, -7406.491597882, 8135.78148707283, -2363.85627946861, -6308.81442264451, -13191.8246484253, 11840.5495964393, 14577.7037859984, -7771.59226746076, 7221.89458945567, 7307.56160072343, 21089.2673386334, 2471.62578334831, 22282.5765491896, -8182.62696539563, -6723.21586321514, 18416.9967799544, -11291.7154177304, 7908.95827540066, -3054.99079500155, -9443.9584470 [...]
+-7945.42414270773, 5758.94315564407, -3523.55815068731, -6241.95324742099, 5915.37941503488, -651.455822603005, -2671.06983711938, 11068.7567814221, 10901.2691510663, 12340.5133043667, 5032.09416894301, -6837.2304803885, 444.32920533892, 1394.84394445152, -1041.78671086489, 21540.1675398344, -14338.5087713495, 4693.03305435043, 2364.99554287448, 9933.6083485579, 9848.81170731411, -10404.7209627202, 2831.54608403670, -1401.88426496406, -3613.99453696053, 3659.4722107254, 12929.8809183328, [...]
+
+double y16[100] = {
+-91173700.7612659, 91135662.8969753, -131101481.899429, 104972400.505247, 93124016.8993616, 41932951.531562, -108634586.559969, 6616331.57940979, 58034901.4069293, 39500528.7760922, 190473034.086582, 80278437.4193072, -13495350.5484727, -97127404.220832, 83653988.950673, -104962831.040602, 8193656.20565947, -40754204.0522703, -116722922.720474, -110044522.877424, -25981316.4740955, -16182284.5779948, -71567861.3544179, -3725950.86454631, -200668806.826405, 166108374.162190, 104707088.149 [...]
+
+double lars16[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 32.50685140611577100, 112.00726869625575000, 123.93052869069734000, 166. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -37.91371269553349100, -41.45547949016953700, -184.00398512135371000, -192.72312303366181000, -222.95990573136083000, -226.80345887932071000, -236.84052087072601000, -392.09489167600964000, -418.73812632471146000, -696.96053773222570000, -724.46348112100361000, -866.53344410936427000, -889.52700567352076000, -1100.54150942960250000, -1147.52568274375880000, -1249. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 155.70377519756866000, 167.84403007362690000, 231.50553291760301000, 241.11406962750107000, 349.72889643300897000, 369.33699407967219000, 395.93084297822980000, 399.028559958894 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.65463066991741050, 9.88240688997111330, 107.71109806989907000, 120.87333061586945000, 246.57642624533582000, 258.30583359976498000, 307.57196497521443000, 315.03165277048544000, 373.76401334664848000, 388.23670174602887000, 424.48728587175088000, 429.77062130 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -319.35798975253431000, -517.88737880881979000, -860.64246285145680000, -940.79947457493381000, -976.39284430195676000, -999.66698399471056000, -1001.85577751110570000, -1102.48037727614750000, -1109.13089515438360000, -1131.12043194799050000, -1133.23513678956240000, -1137.94879657014690000, -1216.11168068792490000, -1229.35296658147130000, -1363.40260707180100000, -1374.74829765070760000, -1448.65765807152180000, -1458.82175767470020000, -1541.86627321906050000, -1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 39.681865 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -6.91689018504237120, -106.71038379307063000, -123.82976170520422000, -293.22923921603416000, -301.04528823628488000, -345.66739200146731000, -355.51464614092316000, -469.81124546220730000, -494.36970130543523000, -536.99605272328972000, -5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 421.87596581942603000, 517.78996915142807000, 547.45587614049589000, 568.48255818147345000, 570.45276647364699000, 667.16450682282436000, 673.56396303740087000, 684.34558641229489000, 685.26581107239417000, 687.46901593377879000, 712.72874167237921000, 721.03169948230584000, 776.12483595018864000, 778.97344469468544000, 800.43944354932637000, 802.55452065943348000, 818.46662359036975000, 822.95153878851181000, 834.79451455022 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -26.58624906851414900, -159.89168397259138000, -177.45361190399089000, -315.17471059105941000, -339.72596063427761000, -397.69633229752264000, -407.17783909 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -79.61980248095696300, -91.56894195118128700, -134. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 118.65187198781152000, 126.66692681418404000, 152.99796252170731000, 155.50837376323122000, 160.12846178274762000, 230.94463486722222000, 240.98944614785387000, 362.28564548852779000, 374.91153216472878000, 457.39797949789238000, 468.97071667536181000, 554.77568828688538000, 571.28326364499947000, 608.03663462794668000, 61 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 110.30970863646503000, 126.66426673617180000, 231.92058307958658000, 249.37801063474839000, 292.54455156800771000, 299.5135490540638400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -36.80396444257380800, -40.99666922455915600, -49.91016747253016900, -191.05759485462792000, -215.09906590465920000, -484.69174611942583000, -509.59338497924477000, -641.91477634061903000, -660.38329477026969000, -835.84850958150355000, -875.50801096588521000, -972.0345158441260800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 10.99518467820173100, 52.99632 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 130.00805893024773000, 180.98843249144062000, 214.92757210988378000, 217.99395681157557000, 343.96012311210438000, 353.03229494590289000, 377.32368202246897000, 380.16425170621920000, 386.42060769191795000, 446.30518513091727000, 454.77921844842984000, 546.88980098702882000, 552.32220020044213000, 583.91780231642599000, 587.23699160814851000, 614.68772073467687000, 618.29331941493774000, 626.0193368603875 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.19149097793964900, 185.81066760880151000, 216.15187460395248000, 281.63847962760406000, 288.77157281537427000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -202.32023479879581000, -246.10960126353930000, -334.81526989767605000, -347.1893325360296700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -132.48564322554211000, -158.62975599198236000, -426.12482565893617000, -450.18146931142178000, -582.40465272129939000, -601.40510002804922000, -778.10036926208466000, -816.50623438912237000, -891.70853928015993000, -90 [...]
+1697.13594268198630000, 2032.28935131752090000, 2249.91495528762650000, 2743.55639966550320000, 2866.82315367000180000, 2913.84929538430330000, 2937.00768102107350000, 2939.52301202802210000, 3060.33447498463060000, 3069.44944948641070000, 3096.72234498815310000, 3099.15902319670020000, 3104.57677335284050000, 3181.29318231076190000, 3192.54973347082430000, 3323.61747428553960000, 3333.18489131747630000, 3380.21339647090780000, 3384.70564753445210000, 3433.23443664792650000, 3440.9352600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2.52955877923736240, -130.16226712272692000, -139.06069214470762000, -166.65239752931942000, -169.24897321148836000, -175.72219052817422000, -270.87994983644296000, -285.03323164141420000, -406.61748505608125000, -412.07820739914456000, -457.84151005067207000, -464.52110203558846000, -547.13288959364559000, -564.47664535458591000, -602.097976 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -9.96964306673922880, -31.78360682853758600, -33.82043635118547100, -38.97386374384353000, -82.96432071201292000, -84.54879421359916600, -127.71997583848328000, -135.92013378561512000, -205.64501564627486000, -214.14333178289382000, -247.98407207836357000, -258.15285622180585000, -269.20015524915397000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -26.58367850442744600, -265.65809753794150000, -286.52806576871791000, -402.68874585416705000, -419.77373292263792000, -575.59702638170995000, -608.85421007016930000, -674.88636516904853000, -685.84 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 56.98499852127297100, 95.29178849419777500, 98.74321761550085300, 230.59388666968351000, 239.78640863434811000, 268.07477006961227000, 270.73640163110315000, 277.54569663460200000, 387.92300679980951000, 404.57432311106794000, 574.37471435424834000, 588.13271280265701000, 683.01396042643671000, 699.46137575268324000, 837.74913661940093000, 864.71792265484635000, 910.61027104403786000, [...]
+0.00000000000000000, 0.00000000000000000, 239.20939644551075000, 614.39276612141862000, 711.44533963594836000, 761.80036429777579000, 795.82790122929634000, 798.89332641327940000, 928.80779548347789000, 939.14549613731197000, 969.18957488494266000, 972.51730167714561000, 979.50630625811880000, 1060.46970740326400000, 1069.66062539268680000, 1169.47439740169370000, 1176.11619204067420000, 1229.75869734488650000, 1240.22800476857290000, 1276.72651856172680000, 1280.43457306607230000, 1289. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq16[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 880.62110740901824000, 1044.32667859250520000, 977.17043741418524000, 92 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1721.04987632175810000, -1631.15365673295200000, -1436.89843240067490000, -1242.45132001892030000, -1418.45038714627980000, -1650.47004371723920000, -1763.11390070350670000, -1940.38658950010400000, -2052.80168845413980000, -2039.73658038660760000, -2276.57039408480520000, -2093.58254269449750000, -2192.31514130031840000, -2265.59478502849110000, -2373.3579448849 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 907.17199096220247000, 852.96973650841903000, 781.34582312500970000, 785.52245070680272000, 949.41307688458994000, 880.91859696918800000, 707.80293569299715000, 620.704154977856 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 985.93984473111595000, 1108.96523107723280000, 1083.31873846829060000, 928.12983994110903000, 853.25330912056404000, 920.24568427067072000, 733.08036114460481000, 737.68878346521615000, 698.03712185301902000, 765.83381814632855000, 849.60610099876476000, 807.85 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -2630.82107976382890000, -2407.12503131842190000, -2108.93007890588430000, -2001.96701246774020000, -2041.25088825162610000, -2032.89595074735170000, -1984.28100907733390000, -1986.89513663890990000, -1909.81052788321340000, -2000.53442318856540000, -1916.52978729778310000, -1854.72562338013520000, -1995.59984536782010000, -2041.45791853920170000, -2010.36215596738680000, -2015.03339481070180000, -2087.00803258942010000, -2034.70767840963230000, -2000.371651443287400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 754.65508 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1058.72521514076930000, -1101.91223768454070000, -1173.78304333138660000, -1110.79659077831300000, -742.13784858184727000, -731.06562150987554000, -913.44847581710542000, -1100.86562825952160000, -1135.10774898177170000, -1036.884935757530 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1958.31573917631410000, 1787.55819749286230000, 1434.98015188750610000, 1501.93819805629660000, 1454.76749199431290000, 1517.18816672499130000, 1444.01738416412790000, 1110.62533474898650000, 1026.12049648829220000, 1022.49662990379950000, 964.63420138686706000, 1230.26269166441330000, 1042.01910158289430000, 939.73243191154393000, 985.83988985601434000, 922.39230034810589000, 906.32052610117989000, 939.96442536394727000, 973 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1526.96024125204490000, -1311.24211931372020000, -1172.49177873699520000, -1075.56043900486970000, -980.27600666019748000, -1077.52801800171870000, -1085.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1013.33926956491430000, -946.66081075647242000, -9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1161.51283299605600000, 1091.62804295264850000, 1194.06449624838710000, 1085.37416751611520000, 862.67641483020418000, 937.16689637043726000, 857.05053327064445000, 947.69366389983043000, 1087.44348612371250000, 1169.82809995861680000, 1124.66838445367220000, 1028.52209651591620000, 1001.97123826147800000, 1039.05174517088 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1063.04754076113660000, 1053.29427993650850000, 813.06175560827273000, 704.84793596516886000, 798.76835946681194000, 798.22168606262994 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1491.94519455692350000, -1593.99033639188040000, -1405.33022054321100000, -1598.66621064693710000, -1689.59314820482880000, -1785.81838949807460000, -1914.89772903078350000, -1784.76609113125370000, -1706.78781220964220000, -1804.62705148587130000, -1910.23721589075350000, -2104.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 797.82113459460243000, 809.757 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1851.13424408750830000, 1706.18431269437470000, 1721.61708344573640000, 1594.32008262739940000, 1451.10824510876680000, 1445.26350835410590000, 1337.74735939374070000, 1432.32197789905810000, 1337.78561907733710000, 1043.51087792775680000, 974.50248970268603000, 991.44019821081349000, 858.89536416798603000, 856.80697804492752000, 775.29835031024209000, 766.24868605774361000, 712.36455393564449000, 716.624 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 818.26466691147039000, 1133.35446355797970000, 1007.76376821482450000, 1049.61473727338490000, 799.222555456568330 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1319.37071273533750000, -1388.58832047586000000, -1375.08674839327000000, -1232.689110366040 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1453.71364101412970000, -1762.08153649583390000, -1717.12783745746490000, -1807.79917545719630000, -1724.40775177496240000, -1677.94808158262550000, -1753.67028763082270000, -1818.52766431565530000, -1773.6230110365937 [...]
+5040.65335024453630000, 4458.07720823886940000, 4320.87526562183760000, 4541.36051833897360000, 4498.70382185464590000, 4320.74517696116800000, 3965.09787808166220000, 4068.51239748526180000, 4122.17662082690370000, 4166.83382917531890000, 4175.02777513030650000, 4001.71382339567890000, 3928.42022963351340000, 3946.35621055489490000, 3882.92837286776650000, 3956.18557489427390000, 3873.11452374131840000, 3786.39555941728390000, 3639.23130557628430000, 3701.17158651727910000, 3641.8522314 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1137.90498402525080000, -1251.95804370221070000, -1210.37390547816200000, -1257.56281227454500000, -1131.03040081288010000, -1160.06395117390320000, -1219.85142134056080000, -1153.07205601815920000, -993.41572975285897000, -720.24976484425747000, -853.09620066698449000, -842.97892226045713000, -1003.24909006510210000, -1016.98083684692520000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1210.25062798631300000, -894.25585792370441000, -788.26977496494374000, -822.62340691198199000, -521.66410709501145000, -181.72657492378977000, -336.07568710455917000, -598.68957839464701000, -807.85431898146840000, -695.64792187004741000, -434.82556699049729000, -523.45972001259270000, -398.754334474 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1656.99458634683610000, -1419.49542022404260000, -1464.30825847130360000, -1405.96104065700140000, -1387.78899180441660000, -1435.92859235287800000, -1476.54487774840090000, -1449.26041217923940000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1761.82313341041530000, 1795.87817088401490000, 1647.89393847259320000, 1389.46237425283610000, 1346.50700472598060000, 1386.52930833160510000, 1256.61477234022440000, 1312.99269379053980000, 1488.67316327224780000, 1425.82078978378350000, 1393.87698320894720000, 1364.55450149867900000, 1502.49717081433550000, 1631.35257011913130000, 1601.26352025267190000, 1568.34226381296980000, 144 [...]
+0.00000000000000000, 0.00000000000000000, 2515.56455346878600000, 1980.78170072799370000, 1996.28665629907660000, 2268.28748467068040000, 2306.44171076307660000, 2174.78877916647530000, 2070.65853743671460000, 2183.73825031362090000, 2157.06100038571690000, 2205.11985851803270000, 2042.28061736658830000, 1867.88634353679660000, 1633.35134789914010000, 1651.20245483107850000, 1550.94063275322310000, 1693.06555260728010000, 1833.40664139482210000, 1478.24211247729270000, 1377.1789131401667 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso16[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 32.50685140611577100, 112.00726869625575000, 123.93052869069734000, 166. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -37.91371269553349100, -41.45547949016953700, -184.00398512135371000, -192.72312303366181000, -222.95990573136083000, -226.80345887932071000, -236.84052087072601000, -392.09489167600964000, -418.73812632471146000, -696.96053773222570000, -724.46348112100361000, -866.53344410936427000, -889.52700567352076000, -1100.54150942960250000, -1147.52568274375880000, -1249. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 155.70377519756866000, 167.84403007362690000, 231.50553291760301000, 241.11406962750107000, 349.72889643300897000, 369.33699407967219000, 395.93084297822980000, 399.028559958894 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.65463066991741050, 9.88240688997111330, 107.71109806989907000, 120.87333061586945000, 246.57642624533582000, 258.30583359976498000, 307.57196497521443000, 315.03165277048544000, 373.76401334664848000, 388.23670174602887000, 424.48728587175088000, 429.77062130 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -319.35798975253431000, -517.88737880881979000, -860.64246285145680000, -940.79947457493381000, -976.39284430195676000, -999.66698399471056000, -1001.85577751110570000, -1102.48037727614750000, -1109.13089515438360000, -1131.12043194799050000, -1133.23513678956240000, -1137.94879657014690000, -1216.11168068792490000, -1229.35296658147130000, -1363.40260707180100000, -1374.74829765070760000, -1448.65765807152180000, -1458.82175767470020000, -1541.86627321906050000, -1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 39.681865 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -6.91689018504237120, -106.71038379307063000, -123.82976170520422000, -293.22923921603416000, -301.04528823628488000, -345.66739200146731000, -355.51464614092316000, -469.81124546220730000, -494.36970130543523000, -536.99605272328972000, -5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 421.87596581942603000, 517.78996915142807000, 547.45587614049589000, 568.48255818147345000, 570.45276647364699000, 667.16450682282436000, 673.56396303740087000, 684.34558641229489000, 685.26581107239417000, 687.46901593377879000, 712.72874167237921000, 721.03169948230584000, 776.12483595018864000, 778.97344469468544000, 800.43944354932637000, 802.55452065943348000, 818.46662359036975000, 822.95153878851181000, 834.79451455022 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -26.58624906851414900, -159.89168397259138000, -177.45361190399089000, -315.17471059105941000, -339.72596063427761000, -397.69633229752264000, -407.17783909 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -79.61980248095696300, -91.56894195118128700, -134. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 118.65187198781152000, 126.66692681418404000, 152.99796252170731000, 155.50837376323122000, 160.12846178274762000, 230.94463486722222000, 240.98944614785387000, 362.28564548852779000, 374.91153216472878000, 457.39797949789238000, 468.97071667536181000, 554.77568828688538000, 571.28326364499947000, 608.03663462794668000, 61 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 110.30970863646503000, 126.66426673617180000, 231.92058307958658000, 249.37801063474839000, 292.54455156800771000, 299.5135490540638400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -36.80396444257380800, -40.99666922455915600, -49.91016747253016900, -191.05759485462792000, -215.09906590465920000, -484.69174611942583000, -509.59338497924477000, -641.91477634061903000, -660.38329477026969000, -835.84850958150355000, -875.50801096588521000, -972.0345158441260800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 10.99518467820173100, 52.99632 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 130.00805893024773000, 180.98843249144062000, 214.92757210988378000, 217.99395681157557000, 343.96012311210438000, 353.03229494590289000, 377.32368202246897000, 380.16425170621920000, 386.42060769191795000, 446.30518513091727000, 454.77921844842984000, 546.88980098702882000, 552.32220020044213000, 583.91780231642599000, 587.23699160814851000, 614.68772073467687000, 618.29331941493774000, 626.0193368603875 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.19149097793964900, 185.81066760880151000, 216.15187460395248000, 281.63847962760406000, 288.77157281537427000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -202.32023479879581000, -246.10960126353930000, -334.81526989767605000, -347.1893325360296700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -132.48564322554211000, -158.62975599198236000, -426.12482565893617000, -450.18146931142178000, -582.40465272129939000, -601.40510002804922000, -778.10036926208466000, -816.50623438912237000, -891.70853928015993000, -90 [...]
+1697.13594268198630000, 2032.28935131752090000, 2249.91495528762650000, 2743.55639966550320000, 2866.82315367000180000, 2913.84929538430330000, 2937.00768102107350000, 2939.52301202802210000, 3060.33447498463060000, 3069.44944948641070000, 3096.72234498815310000, 3099.15902319670020000, 3104.57677335284050000, 3181.29318231076190000, 3192.54973347082430000, 3323.61747428553960000, 3333.18489131747630000, 3380.21339647090780000, 3384.70564753445210000, 3433.23443664792650000, 3440.9352600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2.52955877923736240, -130.16226712272692000, -139.06069214470762000, -166.65239752931942000, -169.24897321148836000, -175.72219052817422000, -270.87994983644296000, -285.03323164141420000, -406.61748505608125000, -412.07820739914456000, -457.84151005067207000, -464.52110203558846000, -547.13288959364559000, -564.47664535458591000, -602.097976 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -9.96964306673922880, -31.78360682853758600, -33.82043635118547100, -38.97386374384353000, -82.96432071201292000, -84.54879421359916600, -127.71997583848328000, -135.92013378561512000, -205.64501564627486000, -214.14333178289382000, -247.98407207836357000, -258.15285622180585000, -269.20015524915397000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -26.58367850442744600, -265.65809753794150000, -286.52806576871791000, -402.68874585416705000, -419.77373292263792000, -575.59702638170995000, -608.85421007016930000, -674.88636516904853000, -685.84 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 56.98499852127297100, 95.29178849419777500, 98.74321761550085300, 230.59388666968351000, 239.78640863434811000, 268.07477006961227000, 270.73640163110315000, 277.54569663460200000, 387.92300679980951000, 404.57432311106794000, 574.37471435424834000, 588.13271280265701000, 683.01396042643671000, 699.46137575268324000, 837.74913661940093000, 864.71792265484635000, 910.61027104403786000, [...]
+0.00000000000000000, 0.00000000000000000, 239.20939644551075000, 614.39276612141862000, 711.44533963594836000, 761.80036429777579000, 795.82790122929634000, 798.89332641327940000, 928.80779548347789000, 939.14549613731197000, 969.18957488494266000, 972.51730167714561000, 979.50630625811880000, 1060.46970740326400000, 1069.66062539268680000, 1169.47439740169370000, 1176.11619204067420000, 1229.75869734488650000, 1240.22800476857290000, 1276.72651856172680000, 1280.43457306607230000, 1289. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq16[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 880.62110740901824000, 1044.32667859250520000, 977.17043741418524000, 92 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1721.04987632175810000, -1631.15365673295200000, -1436.89843240067490000, -1242.45132001892030000, -1418.45038714627980000, -1650.47004371723920000, -1763.11390070350670000, -1940.38658950010400000, -2052.80168845413980000, -2039.73658038660760000, -2276.57039408480520000, -2093.58254269449750000, -2192.31514130031840000, -2265.59478502849110000, -2373.3579448849 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 907.17199096220247000, 852.96973650841903000, 781.34582312500970000, 785.52245070680272000, 949.41307688458994000, 880.91859696918800000, 707.80293569299715000, 620.704154977856 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 985.93984473111595000, 1108.96523107723280000, 1083.31873846829060000, 928.12983994110903000, 853.25330912056404000, 920.24568427067072000, 733.08036114460481000, 737.68878346521615000, 698.03712185301902000, 765.83381814632855000, 849.60610099876476000, 807.85 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -2630.82107976382890000, -2407.12503131842190000, -2108.93007890588430000, -2001.96701246774020000, -2041.25088825162610000, -2032.89595074735170000, -1984.28100907733390000, -1986.89513663890990000, -1909.81052788321340000, -2000.53442318856540000, -1916.52978729778310000, -1854.72562338013520000, -1995.59984536782010000, -2041.45791853920170000, -2010.36215596738680000, -2015.03339481070180000, -2087.00803258942010000, -2034.70767840963230000, -2000.371651443287400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 754.65508 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1058.72521514076930000, -1101.91223768454070000, -1173.78304333138660000, -1110.79659077831300000, -742.13784858184727000, -731.06562150987554000, -913.44847581710542000, -1100.86562825952160000, -1135.10774898177170000, -1036.884935757530 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1958.31573917631410000, 1787.55819749286230000, 1434.98015188750610000, 1501.93819805629660000, 1454.76749199431290000, 1517.18816672499130000, 1444.01738416412790000, 1110.62533474898650000, 1026.12049648829220000, 1022.49662990379950000, 964.63420138686706000, 1230.26269166441330000, 1042.01910158289430000, 939.73243191154393000, 985.83988985601434000, 922.39230034810589000, 906.32052610117989000, 939.96442536394727000, 973 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1526.96024125204490000, -1311.24211931372020000, -1172.49177873699520000, -1075.56043900486970000, -980.27600666019748000, -1077.52801800171870000, -1085.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1013.33926956491430000, -946.66081075647242000, -9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1161.51283299605600000, 1091.62804295264850000, 1194.06449624838710000, 1085.37416751611520000, 862.67641483020418000, 937.16689637043726000, 857.05053327064445000, 947.69366389983043000, 1087.44348612371250000, 1169.82809995861680000, 1124.66838445367220000, 1028.52209651591620000, 1001.97123826147800000, 1039.05174517088 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1063.04754076113660000, 1053.29427993650850000, 813.06175560827273000, 704.84793596516886000, 798.76835946681194000, 798.22168606262994 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1491.94519455692350000, -1593.99033639188040000, -1405.33022054321100000, -1598.66621064693710000, -1689.59314820482880000, -1785.81838949807460000, -1914.89772903078350000, -1784.76609113125370000, -1706.78781220964220000, -1804.62705148587130000, -1910.23721589075350000, -2104.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 797.82113459460243000, 809.757 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1851.13424408750830000, 1706.18431269437470000, 1721.61708344573640000, 1594.32008262739940000, 1451.10824510876680000, 1445.26350835410590000, 1337.74735939374070000, 1432.32197789905810000, 1337.78561907733710000, 1043.51087792775680000, 974.50248970268603000, 991.44019821081349000, 858.89536416798603000, 856.80697804492752000, 775.29835031024209000, 766.24868605774361000, 712.36455393564449000, 716.624 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 818.26466691147039000, 1133.35446355797970000, 1007.76376821482450000, 1049.61473727338490000, 799.222555456568330 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1319.37071273533750000, -1388.58832047586000000, -1375.08674839327000000, -1232.689110366040 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1453.71364101412970000, -1762.08153649583390000, -1717.12783745746490000, -1807.79917545719630000, -1724.40775177496240000, -1677.94808158262550000, -1753.67028763082270000, -1818.52766431565530000, -1773.6230110365937 [...]
+5040.65335024453630000, 4458.07720823886940000, 4320.87526562183760000, 4541.36051833897360000, 4498.70382185464590000, 4320.74517696116800000, 3965.09787808166220000, 4068.51239748526180000, 4122.17662082690370000, 4166.83382917531890000, 4175.02777513030650000, 4001.71382339567890000, 3928.42022963351340000, 3946.35621055489490000, 3882.92837286776650000, 3956.18557489427390000, 3873.11452374131840000, 3786.39555941728390000, 3639.23130557628430000, 3701.17158651727910000, 3641.8522314 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1137.90498402525080000, -1251.95804370221070000, -1210.37390547816200000, -1257.56281227454500000, -1131.03040081288010000, -1160.06395117390320000, -1219.85142134056080000, -1153.07205601815920000, -993.41572975285897000, -720.24976484425747000, -853.09620066698449000, -842.97892226045713000, -1003.24909006510210000, -1016.98083684692520000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1210.25062798631300000, -894.25585792370441000, -788.26977496494374000, -822.62340691198199000, -521.66410709501145000, -181.72657492378977000, -336.07568710455917000, -598.68957839464701000, -807.85431898146840000, -695.64792187004741000, -434.82556699049729000, -523.45972001259270000, -398.754334474 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1656.99458634683610000, -1419.49542022404260000, -1464.30825847130360000, -1405.96104065700140000, -1387.78899180441660000, -1435.92859235287800000, -1476.54487774840090000, -1449.26041217923940000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1761.82313341041530000, 1795.87817088401490000, 1647.89393847259320000, 1389.46237425283610000, 1346.50700472598060000, 1386.52930833160510000, 1256.61477234022440000, 1312.99269379053980000, 1488.67316327224780000, 1425.82078978378350000, 1393.87698320894720000, 1364.55450149867900000, 1502.49717081433550000, 1631.35257011913130000, 1601.26352025267190000, 1568.34226381296980000, 144 [...]
+0.00000000000000000, 0.00000000000000000, 2515.56455346878600000, 1980.78170072799370000, 1996.28665629907660000, 2268.28748467068040000, 2306.44171076307660000, 2174.78877916647530000, 2070.65853743671460000, 2183.73825031362090000, 2157.06100038571690000, 2205.11985851803270000, 2042.28061736658830000, 1867.88634353679660000, 1633.35134789914010000, 1651.20245483107850000, 1550.94063275322310000, 1693.06555260728010000, 1833.40664139482210000, 1478.24211247729270000, 1377.1789131401667 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso16[1350] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 41.98609203507908200, 47.44751 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 215.84401837416070000, 218.16116251837869000, 239.15079726885574000, 258.11583620238997000, 388.58862069763353000, 397.18582183772031000, 426.77276127719523000, 430.29465257295567000, 495.46432757081567000, 569.94896310247179000, 639.34973865832842000, 677.00797004740423000, 746.27 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 264.59274108289708000, 314.05729273104731000, 361.64074118311919000, 555.04157824532638000, 556.76894172436596000, 573.99482309342511000, 590.84722245738180000, 673.81399407957031000, 683.54838536315901000, 719.20279939820261000, 724.19818671333257000, 813.24694982963535000, 890.28781564935377000, 977.06281755944269000, 1027.08301879277270000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 9.83711182731987850, 181.25606176291529000, 344.31679459265916000, 488.43733275914519000, 564.37898718194015000, 694.44120921684566000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 29.13257700656491900, 33.17732096199679100, 85.02512777951312700, 131.08979045682213000, 172.14749854214011000, 199.00277043416511000, 248.32696392725188000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 106.98129711233413000, 199.95831042401940000, 247.43099504918416000, 322.87110377258364000, 3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 122.91343921462101000, 293.66894679367897000, 322.59956103186641000, 344.38710302637975000, 372.76892555388247000, 373.01870976431832000, 375.57287754602578000, 379.84261941755068000, 405.76651090509256000, 409.15858372661853000, 421.30935147733214000, 421.66857922096989000, 430.64590916379359000, 429.33582233523305000, 419.43203968276629000, 416.99268791645721000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 3.08267870481932920, 32.65270073855703700, 75.49996687737862500, 272.37105168420919000, 287.05667695688493000, 341.22172843645200000, 345.19658983051903000, 380.33820519688072000, 398.66160402235238000, 421.04981726118240000, 431.21580577411953000, 445.63682088 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 20.80317610207019600, 50.72387791121836600, 221.02503857005107000, 234.81284376636043000, 287.27666401363985000, 293.91733047978619000, 394.89766927579961000, 489.72442248182716000, 579.69286182945359000, 625.73564462599290000, 697.49395563 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 92.59368294650821000, 138.70107527465510000, 220.03343133586066000, 230. [...]
+0.00000000000000000, 0.00000000000000000, 505.68885757537890000, 682.82878557983213000, 726.31116802516465000, 809.38752622215100000, 928.52818425497412000, 1085.79723325584840000, 1107.55892056784590000, 1134.37792739063050000, 1213.62369330870590000, 1214.91223223459860000, 1231.03197586890060000, 1259.03698238200150000, 1430.52984362963640000, 1443.53053589149680000, 1490.56663945104220000, 1495.72589714739430000, 1568.39042209510240000, 1645.78158042982610000, 1707.99656594414840000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 93.70259671730339300, 230.59818957270664000, 479.20497806532904000, 525.92956597388888000, 583.13843955773905000, 781.41535068946609000, 783.11384607501793000, 798.18799207423058000, 823.22484096254971000, 959.08099846814116000, 970.72645675783974000, 1015.86289996677810000, 1021.67065085275070000, 1118.57156783016560000, 1208.02036584441340000, 1270.84345200855770000, 1304.2543708489 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 76.65903784378988900, 331.66746984093680000, 334.03683972394572000, 357.33855434912152000, 384.79281732122979000, 542.96372749106411000, 557.31849775486251000, 608.05413590144622000, 615.95985196165736000, 762.10428868338147000, 887.03644781648086000, 1009.21877631479150000, 1073.02923415899200000, 117 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 44.06682458611452100, 278.94832817352591000, 296.53824307756327000, 362.19622807949094000, 368.61260738966678000, 461.85710859276708000, 553.55314271631391000, 628.47789956671227000, 665.56729635637487000, 720.868865652 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 222.03638027075979000, 287.98325069967905000, 394.40279156739820000, 571.15665274292428000, 856.91646869287297000, 901.78197050754932000, 948.96743822715905000, 1067.39047719745260000, 1068.43428687784100000, 1078.93732407074460000, 1101.68198784252440000, 1189.07472903199640000, 1194.79561396513190000, 1220.54597334493310000, 1223.96866734694550000, 1290.68477252595080000, 1365.36556235733810000, 1430.20024195832890000, 1463 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 28.09180066315493500, 79.88569141649667000, 86.4676 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 59.93775998736422400, 125.98981890233179000, 350.29606284068200000, 353.31069308599092000, 385.06195361241134000, 416.10970263337504000, 566.17343156962795000, 578.75455056449800000, 615.51576603251556000, 619.89465007942329000, 675.40771348815463000, 703.18649500350989000, 739.79984554631517000, 761.04135557977156000, 790 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 192.97802339972159000, 206.85201119102595000, 256.13424205383393000, 261.71710451191501000, 344.00876989813236000, 427.57555439024725000, 500.89196150743408000, 537.98746240519802000, 598.2410614870 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+2071.09347938555040000, 2269.07598688849790000, 2875.98855214333430000, 3107.57690754120490000, 3175.54898570142310000, 3296.43300953053400000, 3469.17978852608170000, 3771.54769980705400000, 3817.88690442040160000, 3859.62590960441780000, 3975.35491991237950000, 3977.15239748401840000, 3993.89525131168970000, 4025.34506479950100000, 4177.24777631981120000, 4188.88984631414860000, 4228.62422537351450000, 4233.04931636806850000, 4310.99076063427130000, 4376.43675299385180000, 4447.8669857 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 128.82427733679671000, 256.60149263056996000, 378.68600296566075000, 443.68961804719561000, 549.49775621808169000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 69.00179988234099000, 171.81191220469253000, 313.56610229299963000, 529.14959549340495000, 577.04802208856836000, 641.09829287423884000, 828.45758400975126000, 830.37817206303703000, 848.60295999091284000, 876.41681156906793000, 1037.18930844711100000, 1051.53159762453560000, 1100.44044402003560000, 1105.61385409914060000, 1174.71173605532730000, 1220.47138039714100000, 1272.19214507519500000, 1296.581011 [...]
+0.00000000000000000, 195.90328396803346000, 611.26775260029422000, 776.52349254626245000, 840.47852237575660000, 946.74166973311742000, 1117.91539778673520000, 1382.02452129605240000, 1441.27324515371420000, 1513.56330711735020000, 1727.91806324414370000, 1730.15250333493420000, 1751.25505016616760000, 1778.19328964582840000, 1898.44254856911150000, 1907.65924061251960000, 1942.04638926716370000, 1947.02928136354990000, 2008.23378431966150000, 2064.60917050815350000, 2115.746660867931500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 11.23260099760350400, 49.48563502875556000, 54.91520652775212600, 128.88928254377419000, 177.19188652083221000, 220.88408394660638000, 245.85629063629392000, 282.301062994436390 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1.3564494 [...]
+
+double nnlassolsq16[1350] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 153.69235706395673000, 159.472 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 957.46592452508685000, 971.29218126735464000, 901.32957845919623000, 681.12621290938864000, 822.19113468458136000, 735.04518152118635000, 714.14458785221484000, 731.46331589611623000, 801.71263899305143000, 893.90463210810412000, 900.79851578498995000, 903.67148770799326000, 930.57 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1107.56585278074840000, 1123.65153517721320000, 1028.42945550503990000, 1219.55059968425120000, 1118.20618332412960000, 1117.43510995376300000, 966.73571012924128000, 949.53893466343152000, 1066.09790960848950000, 1065.50675245399520000, 1151.37040588152400000, 1231.70896209994200000, 1225.36128481861510000, 1303.96432482425370000, 1328.152780 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 851.04133171925321000, 986.79581572474922000, 1053.51605985533000000, 1031.37274177539600000, 1021.46902815048470000, 1040.478774054678 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 312.09127519635518000, 379.05685790517748000, 328.67070817149835000, 331.43860747968517000, 326.82138344549043000, 360.64366992005415000, 379.55664412875694 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 572.27454087650824000, 550.22422945059736000, 533.16734784702362000, 523.58358665435776000, 5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 966.15386050427105000, 837.68349902346722000, 796.11155977134138000, 649.69677660729621000, 470.28648235917069000, 454.20495678412050000, 456.15149307473627000, 475.07812744077779000, 491.91983831976688000, 542.46284552139173000, 539.32724683803553000, 452.38734090172392000, 472.83258780167716000, 423.63786795883829000, 382.12219922814978000, 402.31031883622529000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1005.03197876439230000, 965.52463409256222000, 1031.19735583445210000, 926.63621229853879000, 864.18356631653876000, 867.31567647913630000, 685.10023602966305000, 545.47728816685628000, 478.35547488032165000, 505.39139596057265000, 492.40451888792535000, 484.00 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 677.09957953728315000, 718.09753255980752000, 786.98989999490186000, 776.65651581268344000, 796.84690477497236000, 861.78285364108331000, 869.42908659742784000, 902.15396657800136000, 918.62478671117947000, 902.86547060538101000, 888.410816 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 441.41550780542968000, 416.21978366217462000, 436.42255643007854000, 436 [...]
+0.00000000000000000, 0.00000000000000000, 2292.66568710316230000, 2091.14317441401820000, 1756.07163680027500000, 1837.41646324303770000, 1745.88566212118140000, 1586.84491531789470000, 1463.73594364141470000, 1510.19371335173880000, 1485.90548465617830000, 1633.72028799443680000, 1739.57594625029950000, 1883.68153999700210000, 2000.45510471349100000, 1954.44164422338580000, 1947.41859003989750000, 1936.91121880126960000, 1909.85887450437460000, 1982.37857515890620000, 1942.3748095789181 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1253.22599170021790000, 1169.76235363553360000, 1271.24801457167610000, 1290.67838287445400000, 1384.80861071406640000, 1462.67815281320780000, 1335.16822009960810000, 1273.74555864965940000, 1381.66539660397390000, 1410.57417126218570000, 1428.37854804511970000, 1454.26384226723140000, 1518.31078660816050000, 1573.93277993647140000, 1597.05959515150810000, 1507.51255147299910000, 150 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1150.88511745426170000, 1207.85500955977200000, 1104.14255724541290000, 1092.45858733556250000, 997.15318013121430000, 1068.61591276916780000, 1121.44319493290230000, 1100.83890116785190000, 1292.00398237884560000, 1448.87289649447530000, 1430.40328989601880000, 1469.50787418893700000, 1457.10204652943 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1026.96615496886010000, 1059.53418627827610000, 987.80011883550810000, 999.91866361012160000, 917.29858828470822000, 900.03592479517658000, 952.36626528347801000, 910.73679218215671000, 888.80701936399930000, 868.001676 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1987.29073428691910000, 1849.75324553640010000, 1711.29209498489990000, 1783.76612258268320000, 1767.32633203097250000, 1636.10282743132370000, 1610.17923306224450000, 1474.28208603088180000, 1407.69908830708870000, 1410.28603260583330000, 1608.99593662447230000, 1479.50857261527110000, 1419.61930819272360000, 1470.65389089667810000, 1516.65463945264220000, 1604.20013924228940000, 1690.17436432044750000, 1674.4474792739272000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 197.17532160561439000, 217.68613453789064000, 221.4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1040.94868142578530000, 1051.57989013453330000, 1120.99346480782490000, 1333.14250608147150000, 1386.74736865586330000, 1108.62185909614570000, 1064.88287796292710000, 1073.17694902258560000, 972.56985260922204000, 994.34761994872338000, 936.27723495435430000, 824.00461656286916000, 877.73080740165983000, 888.8932277206024 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 834.30530413543511000, 752.08255250868638000, 734.80236282071405000, 739.12628123503862000, 730.71752008723877000, 791.03217042332062000, 777.09182859222381000, 761.26392581627147000, 758.5490154245 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+5040.65335024453630000, 4837.45481369277060000, 5020.66442429857120000, 4948.77226573886760000, 4785.28044781449080000, 4792.31315181096940000, 4654.29890672343480000, 4734.86973958381350000, 4576.32809117891880000, 4444.51621304172930000, 4372.99007268632070000, 4561.37850965104920000, 4522.09703629050730000, 4726.82516707970990000, 4682.06874608337420000, 4646.40878178916500000, 4614.55603530176540000, 4611.45359634040600000, 4677.25675317019800000, 4661.08069448933930000, 4716.9611975 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 734.20120158690634000, 812.34232385982978000, 838.60659718909392000, 834.94400019828606000, 831.00602126104059000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1703.11938491804770000, 1444.03631851694630000, 1286.06238694189850000, 1215.98282965572030000, 1361.00924485494720000, 1538.63722917402080000, 1472.20836141669680000, 1454.61833458272100000, 1423.55664551224090000, 1496.79770690927670000, 1571.48739287880720000, 1615.16580356227660000, 1575.48195864184640000, 1548.00939317275420000, 1499.41965691928820000, 1419.49358263255040000, 1467.03623102131950000,  [...]
+0.00000000000000000, 2737.30885050492630000, 2079.06098184764600000, 2090.35510027671530000, 2355.07725855460560000, 2261.69568063539510000, 2292.24269250686260000, 2223.45686279286250000, 2411.00660185421200000, 2526.56675775074150000, 2464.42298948072950000, 2456.40259274348050000, 2416.99596975985420000, 2379.04387951546820000, 2298.06903907375590000, 2269.86382573800480000, 2276.04165565173980000, 2373.13299272984570000, 2295.84877829288420000, 2309.80236797479070000, 2308.3934175187 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 452.65991190868459000, 421.02944692103603000, 519.21596241386942000, 476.51163710777593000, 387.27417093305263000, 385.48269967463057000, 396.16308952844457000, 379.264347802043 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 29.180044 [...]
+
+
+
+// Data from file x92.txt and y92.txt
+double x17[5000] = {
+-10617.4730643269, -24844.4241577176, -525.914328594027, 5504.46212611359, 11734.4013763058, -11438.2982961345, 5446.61608283393, -8487.30997940587, -10130.3710689169, 3748.20069266442, -2349.34066174797, -4524.83167179017, -9798.53330759855, -6629.20219152352, -11631.8291565634, 1771.54610602051, -10287.3667870742, -15508.3363650047, -4238.10560487246, 628.80080422043, -1091.77716941603, -7322.31380955355, -4790.16843078179, -14040.0207287708, 2153.93684486407, 7336.25405911579, -18098. [...]
+8070.32367871442, 6577.71721979043, 28189.6177219913, -19203.9751654465, 2442.2950998976, 7352.72499462837, -5585.92252531632, -4746.82933819327, -8654.85763262696, 22571.5483987463, -12631.9681810696, 5359.8493869031, -6552.47254993876, 150.546623588052, -12572.8948473460, 6489.03178186634, -1429.45116776207, -2715.79904047289, 3141.74632777797, -4965.41116129059, 4768.72037713371, -5077.95750593766, 5250.92200418391, 15150.3973966589, 9144.7888475236, -2460.56757222815, -4317.042222601 [...]
+4677.80479576715, -13461.6261536552, 6940.62121267434, -3642.62636548762, -3047.82129316605, -13785.8672925993, 1471.44436901187, -13401.1697764250, 3731.77566771629, -5199.45580785460, 3803.78012828660, 2647.18021646696, -7060.86032234177, -5711.59313105582, -7301.62633763232, -6448.06525643026, -4819.76646949597, -5160.35971963401, 190.067155252147, -1485.97728258667, 4393.80589793708, -14772.2930187202, 1984.84499477436, 6944.97876028087, 12346.6585835637, 10516.0987931676, 3210.45640 [...]
+16597.8882189984, 7945.17205692035, 8053.72852963506, 20080.5376377495, 11508.367555382, -6832.1710747178, 12433.3927199642, -2612.46882759604, -2306.78571350768, -6579.15468388175, -222.193103415551, 6810.47629111918, -2756.4508549898, -3245.78653390691, -4521.13450809991, 9332.45502140932, 7650.66986169036, -3936.79479800487, -5604.75951048605, 1759.15443961580, -4126.11985599723, 5643.16047386815, 8415.52298852597, 12987.8613020351, -14337.8585773542, -10296.6241017633, 11907.36535116 [...]
+2960.43059453951, -24035.5019236173, -17414.6946669309, 12685.7282123352, 4411.53409928578, -7885.81622145797, 6806.83950587478, 11437.9265192516, -5071.19017584673, 12503.4824190468, -13212.5324990780, -6322.12060720125, -16227.7562814295, -13671.7884193887, -8432.70102627633, 6673.02748854464, 3898.54645693088, 5000.44048029645, 539.148994833325, 3564.30703195722, -17487.3915946668, 19241.7830120577, 8222.52536467907, -9917.09249822001, -11785.5992592599, 11048.3662648933, -1465.010722 [...]
+-20994.4864635979, 15131.581238171, 990.81963853195, 16774.7244469285, 5827.30024542465, 8038.22396872412, 6961.35754785602, -7445.22647997108, -1654.85543646514, -25450.7274035887, -452.780963291404, -2149.87449949523, -7247.56576408766, -17462.6145497495, -11984.4337826811, 18039.3577776431, -6562.33239359953, -21327.0011836387, 13134.8498674420, 7642.78170802819, 8942.43101773998, 5493.92417686734, -2426.59414697805, -2295.13252447040, 7933.26805326757, -5102.18484687958, 8191.6976198 [...]
+8861.9713562447, -766.167930937147, -7567.72349750996, 5142.13637803187, 20811.3846185053, 12199.5246181989, 3394.68540624424, -941.757281498397, -5521.64422796867, -10525.0899700059, 7564.94933252986, 6715.29270458136, 11373.4171521405, -9052.23639544424, -3222.96485912995, 6526.1551515304, 659.523755212892, -3789.06038078956, 8748.67251050626, -5274.56564806451, -5369.12754073149, -2198.26046927747, 5879.13334509837, -519.816171978084, -3197.95392357344, 1948.12577505923, -7042.5313667 [...]
+15148.8468372907, 4469.86534903533, -4442.98339090118, 14969.1582805957, -4178.12448089983, 14633.9416415737, -196.777574249247, 6026.5498524108, -819.981727122114, 5673.21168903681, -282.421540806842, 12535.9180573034, -1485.37750382171, 12461.0149721761, 7006.48095478559, 1038.42327774188, -2330.85064827003, 767.81918448849, -7767.45390088692, -5063.67725417558, 10463.5042158932, -4811.5599301964, 11346.3750133844, 14185.9889286983, -14849.3525579264, 3772.25659254146, -8391.5315604712 [...]
+-5253.21160163961, -2317.36350571449, -8104.67327258219, 9153.84259680763, 3920.23334435601, 5763.90688556303, 12002.9313872525, 3184.07603349333, 18508.3959110621, 2614.91829436051, -3943.46530711791, 12548.4389352532, -14288.4693563331, -10314.444297206, -11618.3189795744, -1415.89926735965, 18572.0196268306, 4380.97615891521, -3418.87596512233, 16974.7753321116, -14649.8467916464, 34162.1929175123, 9439.80749677736, 17756.3737339887, 3677.55202191609, -17164.5164981272, -2332.86129999 [...]
+18617.3002123062, 10007.8268018211, -3432.70734086008, -2785.41615301337, 7760.5848838107, 7817.04423303189, -12321.4850032545, 8678.40055414338, -10063.4761399211, 4246.59574042489, 5694.38970840358, -6331.22323053805, -6453.49942590773, 5910.49799396826, -27533.3818141714, -12403.4779169811, -4421.22301348777, -16971.6277110311, 6542.8328457761, 11780.9444006606, 987.819924690301, -14383.8593833449, -14323.9043065899, -465.857828245688, 6796.52443533144, 2454.43561670014, -5567.5919010 [...]
+5915.2828860613, -20177.7439863229, 1045.52883390942, -3259.80946463421, 6582.37127773455, 2815.44533065229, 8237.15690575378, 2806.03239263961, 16347.6395486845, 4495.90746264722, -11709.9948400184, -6489.26504181448, 20217.8537579025, -10790.8756125697, 3021.23382916315, -4594.19241319774, -1587.14293633082, -9234.60230474457, 5027.40091305882, 4435.58829777584, -9823.8433806788, 189.476773063538, -2927.75833597641, 2527.16842441479, 1797.39250413894, -8388.98863833212, -13867.46218244 [...]
+10865.7889577132, -15237.5184144606, 5008.73127699012, 5879.28289407713, -825.903183339052, 8217.38534899215, -6660.77743462817, -5671.76703828192, -14584.2899293988, -10535.0844022757, 4865.41157785248, -105.340746657477, 16186.0798312488, 2345.29758455899, -1046.21807338783, -5424.95139855615, -1918.10666321963, 9590.31734450368, 16509.1537316703, -1734.32247878414, 25385.6550461013, 7261.00962011492, 3912.68303793684, -9113.225489294, 10096.0376964105, 2321.13881731202, 4774.807300173 [...]
+3964.41252724476, -10129.0714078947, 79.5040973418507, -2177.72371239667, -5032.40739284546, 6396.23204672426, -7051.25833673849, -6437.735587558, 15886.1351068794, 12517.2203216107, 5784.42492803331, -3752.52000675921, -1220.29344211826, -6631.3868851061, -13438.6106617005, -5179.23989076595, -13806.8207078137, -5639.65075493796, -6966.91661249777, 19360.4067739607, -11141.6588242582, 2365.33048600032, -636.625948853542, -3315.79826259238, 12799.0506981978, 3526.82680534292, -4177.84667 [...]
+1035.29956614121, -5923.45261271046, 22334.4008152666, 2533.67806914393, -12647.8008165192, -2684.79890640485, 6097.49104309339, -4530.08901518412, -13010.1128813951, -1359.36429061541, -13180.8955159209, 1653.30119934511, -2018.86809324389, 8451.31760014562, 6158.04104881993, -4752.88041110475, 4383.0830244377, -2580.18438247811, 10645.0581716286, 33620.8906456953, 4204.15812675138, 5058.65405154732, -223.523966022353, 16775.2346819528, 20195.4884326747, -13016.0467529099, 4992.36650896 [...]
+2224.56612805039, -7149.68635460973, -13217.0291226742, -5118.96050293535, 18338.1981912554, -1565.48458671516, -7523.48139716303, 17505.6687012685, -7503.21337042281, 2313.73631323605, -841.15837862305, -2620.94091355044, -25834.3179517944, 23841.2038868205, -15503.0375372559, -1929.49484717457, 3155.12958001476, 9370.32348207795, 2439.77596696251, -4831.34201607124, -14039.5267111785, 17266.9919917996, 5693.72647934133, 10018.6628294414, -18806.434161847, 11538.3758159658, -13184.87135 [...]
+4070.47807750911, 5146.35006815021, -6535.45597085086, -2380.65326196318, -21116.6929532751, 314.997977433092, -3157.47670960440, 3272.26362418883, 7333.00996780027, -13364.9277138826, -21264.4178916101, 15535.8224976574, -11473.4944798462, 5895.30273190305, -4571.34698280231, -1420.88705200594, 12156.846130474, 2584.80037355637, 5709.80884331275, 14304.391297473, 1867.75193938970, -5131.97570604455, -4656.09558791629, -13281.3652868073, -3555.97205432805, 8906.5240234518, 5632.119873021 [...]
+-2696.82606578014, 13074.8760797566, -5017.58768253524, -1903.69939797765, -3586.55322502736, -14497.0226468858, 1138.33399751053, -5263.96146412118, 4133.16452016601, -11943.9707994151, 12892.9893268173, -8133.4834025326, -1443.12230227535, 2644.83696246769, -8766.6774601561, 14715.329716071, 6411.00869725818, -5271.84750814356, 5907.73897547604, 16586.4617568843, 15605.6609548072, 2866.63492848012, 1242.56588917169, -12783.8176445793, 8096.23519603541, -9287.66505849887, -2643.07072919 [...]
+-17708.1433395929, 5128.92431254416, 10433.6636647204, -5437.70728343657, -7771.30569607885, -5508.19076772746, 8124.798472344, -132.838185675898, 12972.2672987924, -2384.48485663405, 9876.2830803819, -1039.08390087718, 4230.15088844011, 7586.53226746918, -7619.03875049324, 16517.5443951099, 6288.62894473852, -10959.0693000294, -4227.16811214989, -23796.6040094875, 5401.90633014963, 7049.72646559892, -402.233681847858, 4914.74353901418, -15880.2421342728, -2243.17133928071, 2147.84841648 [...]
+-2011.15766707015, -3532.30850215157, -13997.2200054606, 415.400358160252, -6152.97100651067, 14753.7857245306, 13303.7076181449, -23251.7134069519, 3731.04342926728, -12900.8882672799, 1330.32963212245, -7564.88452269121, -6920.87243450063, -844.602614562193, 11406.3803075999, -323.252969946169, -3926.50126456657, -11953.1462330413, -6273.26193643627, -1478.75822758982, 20002.0583682117, -6899.1448542134, 7889.01087397525, 401.653950261366, 7804.61657708299, 2527.93027291682, 9112.75262 [...]
+-624.620667123528, -18049.1161327376, -20780.3187377353, -10453.0638025301, 11990.8076846687, 16166.7576756098, -13443.3519464632, -3698.00748357516, 15974.3878266241, -4436.11446581779, 17686.6898854563, 5428.59016861947, 10354.6302376412, -3711.30146989602, 2459.74517307773, 4878.34351313837, 1152.95200107923, 908.134943572544, -1653.28044337733, 6105.87436989287, -7945.05589213547, 17203.1970927527, -11691.949659519, 563.697300635464, -13502.6031424439, 1760.89874260043, -7202.2706602 [...]
+-9412.27199697776, -14290.8247609482, -12262.6785719430, -10473.0109686401, -5183.90659775111, 25977.4105251765, -11703.2220067664, -12049.4861932663, -5920.80306233248, -14417.2970690162, -10580.2776607625, -11344.8520553439, -4888.42632583632, 5252.48922646544, -1691.90173045289, 5351.27612432771, -1377.73466399154, 13083.1111316036, 3940.80959913175, 12976.2242337257, -3050.00298929994, 13459.9558536862, 9039.81322725511, -10723.5188963159, 2974.71947438358, 1724.94422414804, 9589.912 [...]
+11788.9473501171, -13870.3696392434, -691.980781427238, 6454.05314352752, -1203.32370931474, -3410.22603302568, -7851.26688944603, 13696.9132477464, -5080.50117842757, -19944.8149610087, 10095.2419481219, 8240.17258079547, -22376.0916135654, 8626.70640210413, 6739.18388838306, 1698.69865180594, 10010.3958943065, 14560.9622059806, 15207.0886679676, -17369.1303775143, 4143.31850660395, 10899.3065151852, 19306.0885455036, 8241.90184118675, 15025.1317153613, 8418.8702711055, 23626.8149792227 [...]
+-1703.16323810807, 6596.17129483304, -14145.9221442679, -18175.5456428385, 2676.69598927457, -11183.5536791374, 23782.2997947768, -12127.3387971708, 13534.1721868460, -6781.96287131004, -10062.5217895322, -9177.78986005708, 3520.24273113437, -1240.38203125330, 9331.93477736211, 17007.8204822065, 3451.55580590433, 5599.67207932315, -10884.1732224423, -4904.25748051179, -748.262032457287, 4420.13783489486, -25156.8715107946, 9182.59271361564, 9553.12670410945, -4212.90249465714, 12916.9571 [...]
+9209.1872562322, 2868.68795622978, 6993.93770366619, 27337.8829294906, 5800.75636466812, -7826.55929616332, 1980.04114529561, -738.579543776727, 5817.93911821833, -1553.91298818545, 10716.5944026201, -3192.32444737298, -14570.9332869046, 4943.67408576663, -21808.5365587388, -19073.3499473583, -1565.68924662681, 14299.1822457798, -20446.5065677104, 3.40645698587112, 10041.9668241687, 5641.21805335852, -2944.98797946727, -4218.19737104366, -1016.20051228086, 13966.110427489, 11221.96961576 [...]
+9270.97096552905, 5293.49916946953, -11394.8647052157, 3690.02847817601, -2058.17090126356, 3749.50005130781, 6118.72183166359, 677.226188607578, 28023.1751165532, 269.832121795238, -8595.47106421247, 3823.41079081946, 14828.3366948419, -5491.81860400397, 17592.3203641408, 1402.36871851778, 3303.96793070229, 4712.37518831799, 2548.14424843110, 340.148513962729, 22035.7570441685, -8802.74015251607, -11804.2478466604, 11347.9242157946, 13211.6603755424, -15061.1180105364, -9792.5950193651, [...]
+-6488.29790389671, 12030.6425079503, -1142.42852326932, 12075.5980349025, 2971.83238088388, 7364.95288770885, 8159.80515198195, 7463.76088129905, 5181.95636716949, 17747.7625553959, 14431.5199060640, 13197.6995626223, -10.3320761583855, -8041.20076258395, -16095.9935535347, -17725.5729434141, 9789.01573228863, 8932.09609515807, -5835.09271549591, 667.38251968065, -3694.69621817691, 7351.44928453445, -2673.74798443884, 5919.31474296059, 1927.80764093879, 2840.34198628542, 19824.5900890396 [...]
+-3652.60551539376, -3553.67522673724, 14865.3558549977, -7519.57455787363, -845.86118487381, 6807.49318274721, -14426.5748189676, 12742.5724082779, 2438.42608384491, -443.935080923698, 3280.7148366727, 1954.1925058748, -974.10929277898, -10235.5967059115, 11227.0797788107, 5261.47853997347, -311.584322793055, 23742.4348593624, -622.602526500851, -6137.07454828358, -26344.4562603387, -7263.63730636557, -2215.00339737055, -4670.53913353801, -3164.01368326759, 11833.5251874229, -2048.069538 [...]
+4279.69541946765, 8814.5804509079, 14547.9787371177, -6077.62101529908, 1536.96885700654, 11912.3043770914, -9152.41185646501, -3915.95965653508, 13783.2408683610, -7366.07123591317, 1847.91290909030, 8461.77253522505, 7021.19011560474, -15162.6354810670, 1369.253084971, 4250.81199348493, -194.737676658157, 10369.1276810027, 20159.3071497231, 8001.31684073932, -6733.4822805714, -3142.74818710864, 202.402226170231, 6472.00773097609, 1813.98460114845, 4391.79108812282, -6696.92455854494, - [...]
+-8025.02106585633, 2456.21482056928, -318.592557350749, 14920.7073932089, -12537.4689802472, -3008.44020422669, 840.081429674838, -8227.2188859361, -12931.8226763875, 1467.63960001941, -1477.29337272596, 581.706558927898, 5156.39755113822, -6080.48696418331, 6609.67105121699, 8405.14422873969, 7647.22921511055, 1831.13267108898, 3937.18621745585, 12151.1896276416, 558.591617237442, 1456.33437533469, 16175.3502210085, -7105.30432134274, -8029.53388557379, 8495.90139785862, 6309.4571941751 [...]
+-7983.2828722598, 4884.0352279971, 5519.53073539508, 4594.235707509, 7461.3415741108, -10734.4667124144, -15162.4335301710, -714.39129747849, 9650.37886753045, -12198.9031765891, -10160.0532401579, 4933.45560064407, -8930.01709350047, -13791.0494462996, 3889.41842527377, -9773.97191926515, 8431.47032827198, -6868.68542894033, 9641.51740227772, -8749.3555258981, 3042.43405301817, 14646.9945331134, -19834.3155703147, -13015.9947493797, -6369.53623474851, -1616.93809546251, -9438.8127667675 [...]
+181.939985544581, -1379.52384234393, -4556.62065322508, 11413.3700275734, -9791.46651820681, 3411.79239297480, 19344.7418542456, -8192.91622164442, 4807.28729942226, 9094.59963151597, -13527.0334830061, -19032.7799107426, -15485.2025332093, -1526.15979870889, -18293.1323280206, -1658.03216241837, -1648.93378852018, 14352.2086995744, -12031.7717997792, 22327.2802095484, 1701.35502697093, -7360.48304708365, -10894.6720556964, -4386.80899328055, 6814.28673346054, -2715.78178159839, -3261.32 [...]
+3773.9615335001, 3210.10575523735, 1361.17912862735, 8639.2545813316, 12374.4132720431, 4999.38784916824, 15726.9009376228, -10774.4384501479, 11536.8413389799, 3053.12207576189, 6363.53937964597, 3750.57763662853, -12665.5244327596, 18424.0423891741, 9285.49270909445, 4286.44544708942, 17179.0034773346, -12851.366796194, -3146.95006437798, 8708.55826752222, -16514.8447308428, 12660.9193002960, 8230.76632852622, 817.818423151542, -15555.585677911, -5147.52604107559, -11023.2939367751, -4 [...]
+-5715.52338526993, -4067.22417360442, 9053.68219166847, 9829.72526804293, 24.6696084515546, 14207.0684713435, -18450.8122467503, 5385.25978862746, 1470.74825499527, -3235.47683689482, 7757.6267469545, -9570.9716760496, -6371.1063921443, -7006.92025542369, -3029.06518157376, 20819.7016752064, -22926.3476289087, -17754.3611060791, -2333.00011024978, -13037.3739774487, 14048.2693594599, 14365.5190309653, 12004.6406015645, 5454.33168889254, -19497.4908218534, -9081.83483536683, 4830.83975182 [...]
+4036.79402286087, -11234.2183286268, 20595.9866594827, 8421.20543107328, -6088.82054075921, -1395.15450190997, -1317.65519202117, 12318.8638142723, 12120.6220825809, -1692.61292090124, 25195.5273088168, 7644.74407177754, -13685.0224309584, 12913.6018943600, -12605.3888889651, 4710.39596432607, -5608.69709305144, 9910.54994722003, 6203.61670044304, 5605.64744799968, 3577.27638836959, 4710.25536650471, 20536.2665048482, -13713.2781482682, -13546.1660583799, 564.248073835119, 1851.168397520 [...]
+-10261.4901082433, 19841.6955951729, 4693.03043590232, 8952.02939546012, -395.265551805405, 2165.80213406227, -12904.4900016321, -12905.3336130366, 252.138733380648, 2098.23909170119, -5735.96167260206, 3763.54999636970, 3779.48787189258, -11687.2382664998, 7541.73416904954, 6265.2288438644, 13543.2491248449, 3567.52677099015, 18944.5315116932, -10685.3783811299, -7740.70664948044, -12452.7591614853, -13780.1148497061, -5611.99783652976, -7870.64376159037, 2938.02376169843, 14890.8399679 [...]
+-3089.57859520566, -10524.7843534995, -4540.28335149124, -4424.94957721756, 14140.9303666633, 8352.45878031159, 17244.6788597255, -10888.3366453673, -10965.8407091001, -1358.22050525553, -4718.0288176398, 3487.92833708547, 4184.54986464979, -2696.66961721804, -2680.29992363990, 5422.36175585301, -13927.5330678372, -496.522044929592, 5949.00691789707, 1678.07253690515, 15597.0397780258, 6940.33010855492, -2203.76823266565, 10311.9630096598, -10735.8626603558, 3172.67532257683, 7721.424526 [...]
+4518.4253633288, 5273.27378505387, 3723.51550469579, 3315.73261537007, -18457.8716551692, -14590.454877729, 10787.9499373510, 5537.27718896822, -732.675403049239, -3718.92594567608, -1543.74302582470, 25447.4363866376, -5599.62119185197, -4210.16689115344, 385.659499634479, -2013.89920364675, -4444.26770994327, 4572.82991828217, 1506.80150359835, -2173.20679879551, -1513.01552861727, 4969.07012465183, 13578.2406506155, 2162.66789317645, 5182.19273915249, 7159.89039607779, 5807.8308939853 [...]
+8496.71357412855, -13925.4733645301, -8129.13657308767, 4745.76509028953, 410.690577381269, -16203.6223216282, -12127.7379373421, 11977.6994837037, -8448.65128202622, 27303.5714997229, -14383.9524749544, -16970.0313889051, 7509.00228746734, -1424.26027646411, 9352.2358730338, -6344.36666884691, -25738.3228954469, -11729.6852836530, -21989.1245574613, -9031.32156586602, 8409.01755520638, -9688.72783108507, -9008.04293359723, -3433.95491061948, 3507.4740240199, -1047.31535798227, -2261.156 [...]
+-4556.14692566326, 15937.5677175058, -9006.2682941533, -2288.14146871355, -1953.73996930345, 15888.4088272378, -5979.78797616963, 5620.72759818496, -15985.1763165392, -2253.44089075899, -233.781843538787, 2207.03114560135, 7147.66773044039, 19473.1255932120, -2377.36307476004, -10885.7301827671, -8690.6307325735, -10646.7815401825, -4258.09117627285, 6302.97140365647, -6414.74694991209, -257.122519269104, -10038.2315888990, 17087.0703252362, -22300.6216968504, -4289.8601616978, 7365.2908 [...]
+1853.37166757084, 14485.1034005739, -651.426300055189, -13687.1452475167, -3860.47449411142, -6476.95044161981, -3044.35494533569, 13517.0603972570, -9467.35125312984, -8985.85829701627, 262.408191914231, 14802.1346548926, -861.948062530836, 9056.09007590124, -16281.8960571258, -17398.0259340531, 8572.73140808272, 7646.27948067326, -10571.1580793963, -418.429519168194, 5447.51926433339, -6371.48601834437, 7293.72919662391, -25052.7260375188, 8078.86966464546, -7403.98217650374, 643.70258 [...]
+6663.68390159989, 9086.66740804061, -188.34043865501, -19333.1659282875, -2749.24903837136, -1282.20057018866, 9324.91510191113, -6564.29850302358, 24912.6193033652, 4434.09769907518, 485.825647017606, 4692.60547750313, 12576.4971433536, 13066.2461851468, -2277.69568456004, 6553.79335425593, 3664.95451199117, -8924.7957264557, 6054.37080242503, -4271.3016516014, 5489.69029856607, 13462.8023276273, -4109.19562429155, -10800.3106696452, 7862.62963996795, -2026.80365637589, 10332.4966711425 [...]
+1991.14550363116, -18879.1985603701, -1225.87213311663, -6511.29226290571, 3165.76935171010, 16272.0658947779, 25982.432667856, -5275.05503748057, -701.751518313144, 2089.3325385681, 2632.97431686133, -3138.34070472875, -21799.8927026311, 10479.1870915295, -3224.90102717334, 15230.1808346891, 9678.45971858047, 4331.82118732795, -11319.1175515007, 4009.72079344214, -3447.05073933589, 6167.53955134893, -10620.9802752277, 10985.4946972936, -8923.66912468219, 12646.2077170736, -15603.0080442 [...]
+-11623.4170321757, -2031.80009269396, -2265.07735090592, -9555.23377002645, 8781.8511003627, -4939.10133185234, -2533.09681785285, 615.987860807394, 6607.05708108792, -11213.6158315519, -3607.16525911638, 10207.3831609425, -1211.54223988428, -10389.1462694753, 2790.29284496126, 28406.4744077041, -12217.0239106980, -15663.311569008, -17946.153930174, -5595.67161839074, -7889.34404447185, -1858.65121999036, 8505.66568712031, -2699.13933290319, -8233.07143449372, 9834.41551345586, 1511.1689 [...]
+-20006.2468197565, 11285.6004395139, 20718.2179783326, -3179.03714268518, 9279.8015309547, -2456.04149985777, 11005.5944995508, 5483.17073555792, 2297.99506080991, -7015.12614810996, 190.515862471312, 474.29257996473, 2778.13014439861, -454.070567494857, -11558.5868717760, -12328.0907113162, 11110.5848265413, -1367.16188176677, -3925.26065862598, 4708.56498724322, 16106.3036839854, 4026.93997446447, -7126.47780300461, -7039.10572405785, 21006.9184715734, -9230.8841660634, 5660.8603509815 [...]
+-8517.84630180337, 1216.15055610403, 21241.5380549712, 19110.3500296778, -11598.1789583096, 18993.4640278598, 12391.2082897779, 4364.23195396351, 11007.5431693551, 843.588758518711, -13498.1675738481, 9589.78906486532, -2367.98425061806, 14282.6855974999, 2953.06448178093, -5044.18612597577, 14849.8148816986, 9630.36865437245, 3486.27031249733, -14919.4529255305, 14810.5403431556, -18003.9839157139, 3347.31606067332, 10149.4235177586, 2829.77003129537, 6058.87744511163, -4132.11743246712 [...]
+-20979.6223730219, -2903.31106391045, 20802.8486484076, -11490.7413040060, 1313.92931106088, 13227.3037844915, 20035.6006384045, -13316.9619594526, -23099.9407644144, 3734.85452765701, 10943.4089428937, -14586.6545458747, 73.757118848787, -2221.41106551993, -961.67209417369, 15240.5215487451, 15960.2260838249, -18452.539937438, -2330.94438948052, 484.758473008733, 12049.6487780939, 12327.1157342996, 10588.1272091621, -3325.33403914525, -18236.9033775028, -7834.34595484599, 10776.24707581 [...]
+7938.33822914802, -3605.39153100591, 8647.50159097827, 3708.21962723432, 19002.8259726580, 17715.2816157764, -12742.2725160361, -4305.53731809374, -8057.9591367654, -3247.63816685096, -1191.34020440855, -9581.13125286568, 13943.3419661558, -2832.21915728348, -5786.47335907168, 2775.80404896467, -6761.42141236123, 10777.8387813945, 1787.02891675033, 4150.518676668, -19470.0235389633, -9299.56556829897, 5894.80236390307, 7295.25913325009, -4378.72396610624, 17014.0739140074, 1306.496132063 [...]
+-3159.23380091415, -12988.4639635260, 13959.7567047547, -4849.27827569362, -11329.7761878568, 3534.37185237365, -4581.01401022417, -7535.57981890256, 9655.81959439163, 2430.54343967731, 2606.24943861227, 17097.1660507622, -10545.2546779509, 3654.56049990901, -8396.04077894438, -5344.93835993316, -2348.44768422424, -8741.50805475533, 6939.72739116092, 6245.37550099666, -9071.59985275653, 2542.00206158719, 12721.1031772427, 5033.41779054882, 12339.2969747427, 15591.5623680759, 12937.785716 [...]
+-1370.59376266596, 3373.28830263518, -12663.1792156837, -4749.51617113855, -1761.75675658421, 2137.73202887629, 8845.63713256856, -17798.8721916323, -10262.5805852052, 19953.5493564699, -5224.3355846882, -1155.06510293172, -2153.33044191031, -10589.3126143896, 361.972695963254, 2528.45276470278, 21278.9265285551, -5933.00966844983, 6411.91715644812, -2656.16158668772, 9341.92204293997, -3511.63855438079, -16411.8026704401, 17046.3897362835, 3505.66094480816, 7066.46297892947, 26719.37119 [...]
+-3107.77053529797, -5979.52983987219, -1009.41719674728, 3678.57618613781, 2728.56661791478, -6191.50813574772, -8224.0507172859, 8705.77044626499, 1094.93362525679, -13457.1444064540, -1251.22651273613, 20667.3944847294, -7240.00819518279, 2810.36234391217, 3318.8127810194, 8288.08054045009, 8578.87287493082, -3439.59143708182, 5749.35755018882, -5480.79587899646, 8836.32595154458, 20172.4130997059, -12871.1378954841, 11440.5126480146, 3568.94890713487, -8747.27814687543, 13302.66266260 [...]
+-2100.10854658325, 571.576753884845, -12111.0800752440, 353.275579306433, -8126.94029156165, 10681.6952856251, -7199.06247997228, 9232.08141644385, 16474.9407428334, 3110.57090581673, 1387.02222561517, 30541.3309807717, -5384.98925378327, -1769.41308040977, -23404.4606278365, 13702.7167630002, 16487.9635183671, -6154.58922918713, -15974.8203958184, 17922.2004492187, -7189.88154556206, -4179.58948526187, 4545.91432389486, -13941.85063313, -585.686238528049, -24964.7647392142, 15328.421296 [...]
+3817.30559189878, 13436.7779664716, -23892.4491707555, -6290.79583029854, 15607.2787864244, 11073.2271914973, 2602.9048052082, -6722.38173500118, 936.675626728417, -14027.5434172112, 13149.1088890353, -1255.29038371096, -1861.42993173772, -14126.1327158084, 7348.62893392988, 2326.52442388376, 3744.58588471391, 9147.45880613025, -4328.49497164908, 15385.0532634508, -10189.0901562882, 9467.35894232783, -10095.5986063266, -7456.27886161117, -23917.2149356381, -364.583382143400, 5181.4600985 [...]
+7002.57140952348, -12010.3382141265, 5553.41286758374, -9273.04671736726, -5848.82868834691, -1943.88305774897, -84.8288462550821, 3700.31303306431, 31308.2881480348, -17286.2994290026, 5396.18436091494, 7807.57705617492, -14157.0656793300, -13368.3601170099, -3321.96131965343, -1496.54980080997, -4406.37423192655, -18911.0651531747, 2048.07419882713, -6269.34141121328, -8626.94624326803, -10223.3677838812, -12936.7700896265, -166.184910983803, -5227.52860526664, 12111.5606593578, -423.9 [...]
+5122.51890053478, -9193.62999094886, -179.322305328535, 5647.93652220425, -4809.22839974638, 9020.52926015423, -1769.79843251651, 8116.62334744834, -25142.9938971403, 12796.4871627684, 3837.9271363906, 8333.41173621788, 20167.3414075659, 12397.2293501257, 215.008539731569, -13514.5556824917, -9069.21830677828, -5168.0983159778, 13360.7732341716, -11524.9823415518, -3484.82812272916, -3661.05727071937, 12982.6049328594, 154.583397648238, -5341.64011668859, 1183.49163114930, 17007.30360742 [...]
+11456.4041252593, -11784.0680102008, -8137.06239712217, 7860.62227080988, 1119.09175769630, -1769.67878137221, 15320.5586383863, 8675.64018442667, -3388.77795780402, -764.646489918026, -10041.8929743538, 17897.7858703299, 11342.1694637936, 1109.72439068049, -12608.248122924, -4833.28855520675, -3916.08607249803, 5648.64465693676, 4603.56270867169, 23642.8799971218, 3284.64922769667, -9008.20016556872, -1677.93723122863, 9398.50927359898, 3685.66426886346, -4141.09248232477, 18525.8827076 [...]
+-5946.84273001744, -11925.8059289677, -2642.34252112122, 973.772094634502, 11186.8877060279, -8901.68921109866, 5616.30380249638, 6947.31095328544, 4603.23296358971, 13662.1404500911, 8615.43204718496, -9371.7376562663, -2890.05567369325, 5161.87440609893, -5190.16064940437, -6598.95040330323, -722.51102818344, 4055.34265976112, 17745.7227103202, 33.9887579960714, 5358.67833338943, -8358.38712419554, 8111.55110412623, -11488.8144625072, -3996.33920319136, -21264.8405898792, -11587.628517 [...]
+-9714.49636084384, -15881.9984388199, 3652.59404561035, 12228.1800298118, -5572.83095402207, 6740.90172531989, 2906.79728109389, -11891.8460342917, 3897.02856246373, -4150.92727040436, -7423.47940345927, -14891.5704002896, -1407.85087950163, 2695.62339957348, -14986.5945743825, 8155.0202009626, 9482.66118765071, -10215.2949442303, 14486.8715856747, 2929.62646665339, -2693.12582917086, 4805.72684938236, -4611.68980493418, 14041.2759917874, -4158.56723977446, -13098.8251788813, 3961.826170 [...]
+-17885.0857413178, -28836.9876000727, -8563.86952028803, 12715.5408653262, -296.426752605811, -17580.0542932704, -10424.3293779279, -2457.79994902817, 8574.83103283018, 11863.1377865765, 9950.90344767572, -4406.25695187854, -6633.74799913428, 4220.90305089971, -9558.10607929899, -9680.97150202974, 3216.79341242408, -428.878290849428, 3090.04349026098, 4389.37476468391, 16026.1141258164, -11733.4453281877, 8127.85237818902, 11494.3375383397, 8888.75117848469, -1733.10861742094, 14430.1593 [...]
+10035.0568414953, 19438.0879694626, 8365.78504964185, 9466.28129443222, -3845.62999273952, 3873.32755860612, 2713.52989351521, 12710.3812288839, 491.454245560501, -1443.04095910234, 12433.7587286067, 4358.00196298706, -18578.2245159682, -1424.92959538466, 19225.3549839587, -3113.01217547119, -609.582310918627, 7359.32558831878, 3694.20971661167, 6908.80545216435, -5247.2802490686, -4148.18093079512, 16141.4768005941, -3128.95717264881, -15090.6770421888, -6199.21134255524, -335.411270946 [...]
+1144.34594020398, -7495.85368592091, -11004.3244493360, 2562.42507571702, 7888.76280715055, -1679.29282204796, 1910.38594755156, -6177.36398672894, 11154.1256027918, -12653.9918311009, 4426.00049643877, 4920.21532848559, -7536.52215181694, 1688.93691068589, -3481.57242642903, 20253.7571919882, -6660.81904008173, 2083.93621949286, 17560.0736368756, 12247.5359312902, -7073.04849459323, -7979.8631140108, 8725.3256317619, -12397.7735926083, 16467.1392123316, 6316.16053556865, 5080.8495018445 [...]
+16272.3069756029, -12125.1803841634, 5366.73836157591, -7558.44991012478, 5679.4798886325, 2291.57421407282, 19606.1502989588, 4428.48703987241, 12546.3687046313, -4323.3821720363, 723.487852991892, -8443.5099958035, 13445.7807140418, 4954.80445499385, 14503.454374108, 15027.9327598182, 7223.1228471977, 17110.2065891039, 1163.87139484824, -20173.6203812545, -1566.93174744984, 12297.3403171917, 9938.05919627182, 11440.3142998182, 8426.32089059456, -610.01146437769, 533.657029440253, 16628 [...]
+-1731.79591007523, -1926.69999785746, -4744.09110801667, -2523.79818289198, 8412.9720222579, -5190.21340171669, 6102.48036799495, -19691.0724881458, 12341.5327096440, 1879.50970209574, -6741.4085835167, -257.285877744864, 2293.92340295387, 19179.7460443899, 1203.68095878518, 2918.82884816641, 6059.01858887933, -4821.12453386351, -17845.7788156907, 2368.66861970269, 2508.35224525100, 12320.4214203126, 6090.19885183536, -8439.3002360643, -4059.84081018473, 5038.52244953534, 10958.004911997 [...]
+15984.6899446575, 2957.91171620974, -6334.80397866228, 10252.1790487982, -5723.52841956513, 8294.90233293929, 1206.73753291831, 6357.23511082757, 4852.3858365434, -8870.43547486784, 11386.8293013157, 7069.92498405894, -2980.86777853409, 24722.7462829014, 4213.41323993942, 7327.81242201182, -3467.50518900639, -7429.83369776661, 15154.1953743135, 175.258757517559, -12856.9301919426, -7305.03953118875, -15606.6676954697, -11467.4437594824, -14196.1654481744, -4770.3241288314, 29400.74868922 [...]
+3463.11761811169, 6680.63822690832, -25330.6435312764, 8154.47122745972, -1067.24698271113, 1296.54646890166, 2556.77840369341, 4501.12586754001, 1523.90867383356, 23223.3859641659, -1382.17163503001, 211.442650608233, 6823.81608369593, 15380.8042534307, 12447.4104101537, -1460.82193350109, -19762.7196341655, -17732.6364137772, -2417.60880909552, -10366.4340016391, -6262.31816547748, 366.814540248631, 24598.6617438536, -10697.3663165809, 3150.90524844784, 7338.20234014668, 10362.45732702 [...]
+-9519.72617099517, 6250.11336782545, 8801.44151431626, 3181.02403685776, -4899.92321899452, 4808.63688727736, -6166.69601690809, 16315.5860498793, 5308.66675390561, -9255.34798919068, -10515.8985522829, -2492.71749588541, 10148.4337654750, 647.183556743757, 9851.67200206883, -4699.92501828134, 154.015922351807, 5640.25768880965, -6979.98899465143, -968.76523796621, 5140.82232299083, 13505.0397683297, -5179.91822828066, -5523.36625856363, -3259.66889983463, -10818.7206432700, 1592.8304078 [...]
+-3386.18887383304, -3957.24637865234, 5143.80969203592, -1526.53972597554, 14169.3412904073, -5713.80983190858, -9368.56221785343, 7743.46324268227, -20963.8770759661, -2019.57867559820, 18680.2428983361, -16040.7659956664, 3030.52221050556, 2937.45179051222, -23719.9028073182, -9072.59289934356, 10284.8670258407, -11163.9480237115, 8175.83221058449, -19293.6611474764, 3362.12970729934, 4452.64753236358, -4007.84422364211, 8962.7543522006, -5662.44915208984, -6577.84065491325, -16989.390 [...]
+-3019.50430847295, -8681.29377458353, -7135.1129963585, 2654.54537655650, 2061.25339650185, -7173.39280807269, -16348.0479123723, 59.2658639711308, 17312.1498878263, 3767.1879165566, 8598.67205976055, -450.3228284473, -8822.77296287391, 8761.00098710968, 10225.9826592713, 7239.33244793218, 7629.89187358368, -3850.67608253943, -4050.69171076418, -2350.58116608433, 1703.25923417691, -10854.7441306372, 7639.98493767967, -3006.56885718883, 27320.15795165, -7541.20743859356, 4588.50653282337, [...]
+7019.06286819493, 1755.7539426603, 9680.21587406325, -1182.09127164987, 16110.5967590145, 8689.60529442504, -16781.4997244917, -339.077750802862, 11491.6462730887, -18063.0137136822, -732.436155374312, -6173.98341783763, -9703.7102380558, -14346.9604345823, 12060.2720111880, 375.192373967455, -6675.1888887059, -4698.70336167407, -3787.78341552907, -7908.62315095344, 12667.6377574439, 6450.71574773924, 5020.74380750899, -152.655816424072, 6064.8414623913, 961.588488697637, -5352.236996909 [...]
+2476.00683606930, 17766.2113411605, -4623.55784029816, -154.653183412222, -2291.77435176008, -7378.1477491155, 579.751824131856, -3784.69733422245, 24994.5445579960, -8004.80909188474, -9721.3995386825, 8191.46879009, 3288.76956001998, -8215.8601422531, -9542.85138557492, -3930.4134810617, 12427.4542110771, -12595.0045634475, -6245.05877868720, 7120.85214550725, -7536.00722468384, -8843.49227567116, -3848.48526210043, -3080.2011054778, 17339.0769218340, 17813.5310206644, 18497.2879645956 [...]
+21220.4057187524, 5718.53302279187, -12704.5876848443, 6050.01680221803, -12428.6797790269, -153.924874077692, 3466.03981550419, 9314.15245538505, -607.591981626835, -2011.08324406954, -7338.57387095243, -6555.8448641614, -742.944911071584, -2493.06962446980, -14497.2510003965, 17000.7661447648, 19679.5503779835, -145.956111902465, 9703.35654239812, 1189.60318286839, -20211.5848063125, 9517.75712436768, 3835.11761263324, -3494.81855987046, -4145.20493656882, -4559.24717184467, 7234.50248 [...]
+-20640.0028357493, -9573.41306383604, 276.795766332735, -631.84611522251, -14142.4469716760, 14346.6902665095, 7766.11389511147, -2448.28666450896, 446.354639771584, -107.611673116146, -2608.42000275995, 4030.50106232424, -406.346547618129, 8549.04799186901, -3401.92088815276, 1689.05293875556, -18794.8235200362, 25958.960565704, 13507.4661805021, -15453.9608602887, 3793.38506943533, -8154.08438383402, 2713.78293985434, 1070.50581002558, -749.178507295295, -13856.6640657899, 9624.5708183 [...]
+8853.1547594058, -28237.7033637039, 4486.62907748454, 10337.8146995427, 14340.1271975341, 7418.68243442056, -520.215531084430, 5868.80187207582, -3135.8195641486, 10817.5797322643, 3243.10915780878, 4854.48129314088, 10964.7652564852, 2690.73123666489, -9568.59908423644, 1744.41132627701, -2001.66229536565, 14086.4801376731, -9718.43320085483, 9104.17920402849, -6356.61479290845, -10982.3786594388, 1.43189466777523, 7831.1837962331, 18351.7981219818, 26515.2670707035, -5525.58821934824,  [...]
+5888.66413355399, 4510.63074568174, 4883.81620577089, -13312.6649266673, 6644.71007968613, -604.43606790693, 4139.86958064227, 7243.4360426874, -7496.55207266605, -2363.54205781196, -11306.6510364819, 9865.08893097067, -1730.48237154550, -10233.7731334304, -3085.55484592751, 213.613714871767, -3763.33153342393, 3250.93756910955, -13369.1454888184, 11009.5378273477, -13921.1948798823, 11668.4744759962, -6931.5585877153, 1647.05413363589, 12719.3597324464, 20518.6865033065, 18601.223620983 [...]
+8607.11757068049, -16568.665165543, 13892.3920739379, -5752.78457132023, 6041.51924590248, 8682.23810711014, 4516.63182394688, 2142.25068152625, 3469.33307794512, -1190.30475845957, -7990.19628162197, -11596.2190779014, -4356.12844994481, -2404.3318556498, -3755.02449939666, 180.903572345488, -5237.20698529684, 5833.04021919739, 9449.63344302484, 12613.5458827033, -7867.1846974164, -3003.46232669281, -13435.0512104181, -3877.67427470243, -1942.87069559371, 4686.63373098103, -6297.7504074 [...]
+-4529.5526738196, -3984.67824513577, 4969.06058853948, -5273.16620047381, -13440.6080192865, 3017.83078687866, -1082.53417873291, 8462.03117270799, 10729.9933968885, -20226.7368739975, -13589.6426464424, -5397.9269128322, 7788.67505577105, -6250.11078189076, -2293.48272009184, -1227.08663646570, 7501.61793685294, -3701.52190462394, -10750.2890337734, -11934.3671447778, -11647.2142637932, -7207.37456482289, -1605.00130513872, -8979.35077364442, 5421.88347014124, 8106.91176650363, -24882.9 [...]
+-5617.28485978612, -13230.0453569431, -12689.7909486844, 12828.5856787055, -1682.53850294536, -5542.8612714728, 9234.85624652006, 9633.59953822756, -6391.0317646485, 8314.05195842969, -9833.66459029467, -13570.6788995919, 22096.2429252765, 12417.6009790973, -4108.45511831812, -1779.65940926788, 7097.47850095666, -2652.92790097096, 903.135746296778, 12048.3617023670, 3890.78521442595, -6455.19508181853, -11235.4025012554, -21969.1168404216, 3428.98975487357, 9130.0588962054, 862.809042683 [...]
+6116.93205334621, -2833.91554569213, -7344.15378119259, -14276.0530575762, 9661.00448482701, 13756.9516646117, -3272.95585041742, 3991.01303847518, 4057.09988205506, -272.007748526378, 5160.07558511711, -13201.0972014750, 3320.56314641318, 6284.61914336384, 10572.9265491601, 7123.394055884, 4118.40102127520, -5412.09585235261, -22383.6097773291, 3686.35008133571, -12013.7111940129, 4929.78116359909, 6115.89149991848, -11783.1438110120, -7543.43021987224, 853.522949673045, -19463.09002229 [...]
+-7093.07298078579, -850.021868927354, 509.151349422967, 15159.8716483092, 11498.4990901696, 518.574843356305, 16074.0449315848, 13208.5325748948, -11669.1097541928, 9642.19321133495, -17193.0995206350, -8713.43812160348, 4328.07355081057, -17402.3901077958, 1999.00771436065, -4463.26823546834, 11195.8461422463, 6353.08306627931, 5018.54576065515, 7007.8940845353, -1087.52497319819, 8514.99625068803, 26280.9635240323, -11612.5382963800, -9114.29867934377, -22343.3099111908, -1259.65318228 [...]
+6265.38681030823, -2689.76865441636, -12238.0521024001, -20263.6632631108, -10397.5680105855, -7408.47794006749, -11617.0401345923, 3962.82073560946, -998.108487973943, -8419.42172677191, -8679.60354489238, 8.91051090606707, 5349.20680380182, 9373.09476142013, 7175.08935625125, 17604.08911614, 2718.07199630289, -3455.11337969286, -3467.12647781756, 4617.95193687615, -2098.90022867939, 5791.90282576121, 4962.6063010096, -6288.00498994033, -17661.3850775599, 16418.7279343895, 3791.00041198 [...]
+-10118.7751416755, -19772.9007442706, 3636.70278060998, 650.938025476041, 9888.89435803907, 11517.9916654075, -10709.4067099394, 7206.7891704884, -10368.4211681523, 20154.1105899032, 4366.82513444952, 4664.79722435537, 18153.4550519974, 4519.52640724239, -18576.5211517626, -223.914444345838, 3186.03813592252, 12834.0608673365, -2864.62840821822, -5390.60946910553, 1440.28544032221, 8400.34517454852, -1382.65297427933, 14712.4503137639, -12992.0019241351, 7024.28447445066, -12503.61376895 [...]
+3288.79342324517, 4899.78670098735, -10339.8422980248, -5524.49543446274, -5372.96090111172, 2982.88440131841, 5277.41528423301, 2328.03187028639, -6295.7542851857, -1875.97336242568, -10229.7146665156, -3257.36470855607, -14606.8552986921, 6385.84684284914, 26958.7102662751, 25896.6781079666, -5684.37886711765, -8126.03709787324, -6742.38898618911, 1021.95008745244, -2272.78320068180, 6272.00395431345, 2601.68401142725, -661.068736489924, -3112.17787264377, 3384.48699635053, 9148.003043 [...]
+2157.71927914919, -11037.996163606, -6830.15775721394, 1754.19837521867, -9154.51967569002, 7076.22894082629, -26709.2276300287, 19196.8307291964, 4126.89213415218, -2243.9356660166, 6898.96438285904, -12295.169483787, 6381.56103395169, -10663.4619147458, -5063.06157129363, 6033.97807132605, -6720.69928147703, -3502.46282749916, -5619.54544239657, -3721.99328939820, 9200.4236660761, 3298.32514270348, 2354.4309689451, -18768.4280388645, 11187.4329963975, 2207.98296401557, -12038.814195809 [...]
+2189.95703165511, 16368.1055937553, 11528.5123184700, 11005.2745693661, 1823.17911278011, -13786.7864156194, 1821.28712648907, -2689.50756750162, 8989.90343345191, -4240.48791317887, -14738.7387248161, 2870.07040551222, -4084.80424844174, 5946.57745342886, 11431.3248057454, -8133.18151585003, -1776.75723940056, 13130.5663969781, 5209.86031106143, 1273.96483449633, 23106.9281591033, -7076.90867125008, 6001.81326209301, 10277.9342919802, -10339.0752628088, -1865.09267509907, -18259.0414392 [...]
+3633.40095142025, 11881.1963789106, 727.303407864418, -10211.7364286372, -6852.62235359893, 11919.6177391934, -5650.61603308934, -4991.52549376677, 10642.7430651712, -2581.34584195769, -6756.61308975933, -3222.8039042273, 4604.46795390238, 23.7882077824182, 4638.92813579717, 1282.50292807336, -10871.3676189463, -8962.25477659127, 13584.7862173439, -7596.39515634847, -6830.70050339553, 13650.2765541488, -628.150345908767, -3852.43455740153, -13731.8759844592, 26728.9815858089, 5289.641766 [...]
+15992.8222996441, 10134.1301733230, -2114.20987243556, -4135.96177472193, -2476.5188084809, 12917.4291501446, -6913.16297799534, 8850.22952610301, 374.01601331471, -1314.93751612127, -2297.37858918584, -14209.5740245087, 9609.47340728478, -6912.90177659662, -7326.05302711444, -4430.02994802217, -17744.480066936, 6896.73092031633, -6999.34301871209, 11373.6532603261, 8383.37584403937, -4720.71897941704, -3853.94290181775, 7024.87122890115, -10260.5111039813, 3802.56993359419, 11401.716018 [...]
+17484.8110461614, 12972.8893323854, -4986.8957826284, -6855.01308274153, 5224.98498939919, -4256.67996914182, -365.955608800326, 8343.41101071596, -25369.1605457458, 7469.56034614643, -5102.21399068463, -13045.0587199549, -3281.64041161228, 449.28554917595, -12145.8659953116, -7685.31709631887, -1207.62687446437, 15791.0529672953, -17710.1220944840, 12355.7203205707, -1861.26864379961, 16559.8354720260, -3058.54010260545, 6071.12905360347, -6585.58125192757, -13.0870793057731, 3070.42639 [...]
+-3894.64457460895, 540.190759931036, 8709.6571765505, 739.601430097627, -10049.5757200941, -6695.88549801261, 3800.69745027599, -9636.0053715693, 3031.53905503940, -1809.40895602753, 6861.86660469068, -9400.38671369717, 4082.91427401087, 6734.70114223016, 11588.5809995025, 6675.67094745679, 1319.08619418695, 8353.4802347982, 11905.864862945, 5795.807756415, 1224.00752826615, 8777.06299973, -1748.32860847729, 22709.4887373236, 192.731859400475, 6517.05460940756, -8232.21729972652, -11561. [...]
+8391.35504156333, -362.726501375786, 19150.3065733658, 6928.34210158422, -11823.3293040763, -2170.49882586728, 12704.390734827, -13865.1544612543, 1466.40521847063, 5296.43223704963, 5257.80385420419, 3778.92492097554, 12396.1461761854, 4219.82817669678, 15013.7357125368, -2246.60818060784, -15244.6391611983, -1521.06158675572, -9382.13176566285, -13856.4447932237, -993.780750225538, 11619.0761489696, -2593.84165531405, -13790.5949094103, -11461.0538677979, 1438.59460935953, 15734.037763 [...]
+3298.3994712169, 11079.8504795517, 7766.00757660293, 3391.87950037008, -14415.9256034443, -6134.76591570302, 14765.1954529189, 4436.53624428876, 8701.77216204499, -4382.95860937867, -7940.20791206806, -301.466166501404, 10564.2811109812, -2436.12942234798, 6140.32339821205, -16991.7103508790, 2767.13835804551, 10904.6349281046, 3747.91232487189, 831.5765488776, 14175.4450348480, -4980.50133459352, -7600.69229095465, 26638.9634797736, 11976.5513657181, -7606.70235451438, 2120.43847782240, [...]
+-7988.02006890708, 115.855268073713, 11841.4234982677, 9563.78861037322, 8162.06778843307, 8578.77345094352, 10574.333847794, -9603.62741027888, -2365.50255712825, -26374.8128071789, -19011.6941525656, -2713.77865064444, 10940.5298995029, 3837.42446007184, 1684.99903310271, 5848.73173263904, -11362.5873919572, 2508.30890692878, 5058.92426873552, -344.126939161827, 921.491874110211, -8599.07898756994, -3958.85198484878, 3811.29704560072, 5275.19670334924, -3175.11854425861, -5302.05447561 [...]
+-4955.51757273155, 8137.1147285772, 4545.70130894283, 9786.77802747465, -10297.4999619098, -5314.91927624492, 5114.81223112472, -1718.98010774263, -765.766108409026, -10348.9525203610, -7623.25077970997, 669.138265334925, 4069.0152061784, 3081.11146097843, 9565.07668243282, 8920.7095150143, 12021.7093685442, -10783.5117348202, 6262.82797627555, -12601.0020818546, 13375.8525020839, -1187.68614990012, 9627.37028909833, 4204.53909032694, 13695.8278231863, 21164.7320114430, -8687.19330642396 [...]
+-11582.1163887877, 19012.0919533839, 3382.85356810762, -8824.51093543593, -4053.29034378557, 8897.58524186613, -5385.49463086179, -2132.10032681229, -20738.0430076769, 4881.62511140341, 1687.44057473889, 10910.4230073187, -17176.6655475904, -3533.87261218303, 1879.09761676356, -10082.1110608616, 6578.56651864948, 11624.7401145806, 3207.82051592141, -2675.50299699239, -23599.9393987913, -9672.26335396198, 7776.84623961518, -3269.05780504848, 4819.19390239955, 9867.5497451691, 691.48421581 [...]
+2705.86268179488, -6463.78948824978, -497.220290800507, -1818.14005752201, 4135.29888404768, 8652.27422897477, -19357.3987574629, -7900.10149382487, -7128.69751785877, 251.171784191181, 4857.09491790852, 15689.1916104660, 140.199729224676, -1257.41266629119, -22378.0712038843, 9800.80806423128, -7447.04927853086, -11562.9330551563, -543.07801459699, 19010.9882687411, 9622.0207889079, 27841.2516095196, 8599.53398234392, -2017.08253346860, -9773.39070049002, 866.283876940549, 559.093714260 [...]
+-699.080255546832, -11324.7005812016, -13623.4422431782, 2303.82981281607, 9276.31773287848, 4122.20464757926, -1502.59213859127, -11662.9159321586, -19435.7935376655, -3206.76678726703, 4704.00151518324, 3294.44088266867, 11932.5956410364, 12390.9464993036, 4332.13363349722, -6526.19335546925, 3370.21563552119, -2215.33427998885, 11097.0923871465, -2301.08182373043, 5787.98716217295, -15569.2503859229, -8228.48677897969, 26438.4228189883, 6466.30291495248, -6331.76151619796, -21574.4255 [...]
+-3725.96518959768, -342.416389509198, 783.691824411287, 5597.28605342781, -4291.74047702702, 3176.27919041721, -13863.9053746458, -18809.2134922164, 12404.5021752558, -9449.57066477927, 11849.9010698003, -2655.85815248736, -476.040006918748, 2509.91509783625, 12610.3245092151, -5513.59737834611, 6263.6309287903, 9104.4000851111, -4264.39767169922, 7132.53427281218, 1928.24223757946, -80.8739396229165, -3251.58780766694, 1769.94669629031, 23264.2516915673, 2007.89198850351, 3418.537707823 [...]
+-552.92110068732, -1100.76297393181, -16497.3760387362, 702.601254272967, -2907.57673174567, 13270.8164275498, 1503.24532901673, 8265.20674516304, -2146.91299377964, 19267.6311394600, -3826.89192023295, 824.191965288821, 4805.02279707511, -16023.9052766271, 19094.2154976702, -4389.15441934128, -5595.69087629872, 4779.58412239686, 9827.0463281333, -2215.00677200721, -2519.32306502516, -7688.12606917606, -87.0693529881091, 5317.86722830819, 4659.96481128724, -4433.88743372295, 6735.7996910 [...]
+-3256.88593009363, 13723.7135004239, 13599.5493603833, -475.898632381043, -20558.5169340871, 5615.79345540083, 9742.28644985904, 5765.37181609911, -22906.3705286961, 3716.6048879823, 23140.1518313873, -1745.22468285286, 11926.7711855165, 7512.24167625885, 9461.32673111032, 5957.14611959495, 6656.17752366524, 11262.3832034507, -8762.33686535588, 8711.87813800544, -6358.97110821686, 11276.6084821680, -931.391960850414, -5570.6530916016, -30612.8485313523, 14027.0638527489, -1178.5115747550 [...]
+-18828.4779658543, 4955.81516735434, 13139.8435126369, 6639.20552421979, -14093.7135770979, -2115.26623016345, 15544.1177478578, 2749.44542137572, 3977.82232717098, 11505.2921752662, -16182.6696364071, -1897.24921089728, -16830.7066255035, -10322.2401081117, -5576.30146753958, 6513.36825386524, -5025.61155061975, -8592.42783014677, 7217.61070455614, 781.448586050907, 18715.634526054, 1895.97583126821, -40.3441417145221, -14053.2769100671, 2418.15987624150, -1394.60135007245, 15337.539235 [...]
+7082.14613649437, -9330.01595958786, -29060.4030599161, -5347.71961557152, 7357.66147215198, 917.02452853136, -8725.03497182368, -22976.0643190468, 7454.48561045298, -13171.0994798293, 7571.28051764238, -6151.712264106, 2618.43086975578, 13075.2976099900, 3066.84251601830, -21599.2857572014, 7675.97334452384, -6777.00430796098, -2475.80479550403, -10637.4082091168, -2385.97599984688, 6879.23773473808, 1287.96506666806, 1996.47523829745, 5744.07677267132, 8244.52241646726, -625.7411579004 [...]
+-2744.57709277579, -2859.18378740727, 9931.18371354506, -13538.4086829419, -6759.97415839074, 6970.1469638422, 1959.87942916647, -2796.33556123642, -18560.4168816591, -3716.87953103098, -7408.2570693614, -16096.2801080347, -468.982811919066, -10973.7237398098, -564.685883488808, 2895.98107821064, -4027.67457521233, -3341.83548048191, -4228.01119685556, 4991.9311950079, 17474.0373233934, -781.903923058924, -4084.97866804849, -1138.17680545003, -8517.36672710485, -2829.60236644279, 19517.4 [...]
+
+double y17[100] = {
+-15913563.0649852, -31869567.2883421, -18297754.9974150, -62947882.9595622, 47819902.7467542, 103965746.698649, -65086562.5955591, 42870568.9474431, 74025648.1937307, -52734792.3883845, -99423084.825663, -24161468.9921629, 13420624.3236777, 52461973.7593251, 143942009.059124, -18560572.1692613, -52660038.265179, -37693390.8146419, 167314725.47457, 119767004.407246, 87248791.2583869, 143050663.781787, 158373052.705138, -75642271.7445662, 71404708.0234587, -61999940.5137217, -51324009.1035 [...]
+
+double lars17[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 81.11424265790721200, 93.01774047776658000, 102.73512822587330000, 132.82222615474325000, 134.78905561318757000, 143.97137113226771000, 144.64301289022887000, 149.54849793634042000, 161.55519960519700000, 185.59696482596075000, 187.83774364 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -0.972940 [...]
+-282.88154111437080000, -558.36435926412094000, -600.92549292866829000, -981.48622330340629000, -987.55980414774751000, -1009.25700368733460000, -1011.22192256409030000, -1155.44983453477150000, -1161.62733920286910000, -1224.00059987648180000, -1235.90046129911300000, -1324.05464311561850000, -1400.37389774068450000, -1409.10726035027230000, -1416.48878015363470000, -1440.75133169142530000, -1442.25673138346910000, -1448.80202459706110000, -1449.39934533528340000, -1454.0906331042818000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -18.36322461116755600, -144.53449930456819000, -267.44646749502817000, -284.60126440754743000, -301.72656647024013000, -357.17231132700573000, -361.15099072600276000, -377.77419743333633000, -379.27154890258043000, -390.32984208216715000, -438.94101127990643000, -537.87289908647210 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 27.42804272085678700, 29.86938035716115200, 223.94980164643752000, 230.93251010148967000, 314.70130585880020000, 328.81981281491102000, 381.67686743545016000, 436.55840900566267000, 445.47975610866052000, 455.28910285719394000, 489.77749405277444000, 491.93770111857492000, 501.03718353367594000, 501.46007198610147000, 504.71812952690851000, 508.21371692723091000, 525.16910788168093000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -544.14198713212841000, -552.35354213685389000, -578.30761814832863000, -581.60709513266886000, -828.83126023656905000, -839.29211441924372000, -962.09371979148739000, -985.20706468462936000, -1097.88275673559560000, -1227.27188708784840000, -1239.52582528129300000, -1249.36912859974930000, -1273.84435148762710000, -1276.51863238444090000, -1289.80823248221580000, -1291.08271731472700000, -1299.56464021245140000, -1331.519598 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 66.37292889092816500, 77.07955054429830000, 78.7211 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -4.15448408641062890, -18.63101731013022500, -33.05320860184179600, -35.23079807700100500, -3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -8.56928705784355320, -42.09526012674933100, -45.43883846582315300, -248.69301069018493000, -257.38427482683511000, -354.48721017787392000, -375.10803945115316000, -498.56985594308850000, -625.92773816527756000, -641.15348603694042000, -657.77447781137278000, -710.55970227058572000, -714.11799438541357000, -729.27907212684511000, -730.40111856287774000, -738.54158118323880000, -770.72903510178344000, -826 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 113.56679249401927000, 136.37737084565737000, 257.74020534123525000, 367.98929690922643000, 379.75699649587017000, 391.34583152171939000, 430.39019811557534000, 433.80932473652439000, 450.14201381834829000, 451.55911401045017000, 462.32973423598878000, 507.33622030216679000, 599.22441167361762000, 612. [...]
+0.00000000000000000, 283.55556326106296000, 328.16164611693875000, 678.19054373341714000, 684.84349018820376000, 708.43125961421981000, 710.99640967905509000, 897.58576296421643000, 906.02590924900881000, 1000.50633885608560000, 1018.58092378707680000, 1121.50658612510260000, 1218.40267398166860000, 1230.64316716264720000, 1245.10976246081990000, 1288.58687977635190000, 1292.63158916674370000, 1311.55841261887120000, 1313.11477050698750000, 1324.36452169090900000, 1365.63450453647100000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 17.46298695880310300, 20.17719 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2.20784225209294330, -161.88746219336144000, -168.34299507169524000, -249.61009408022471000, -263.25340674517423000, -356.35601770379805000, -436.93311396932603000, -446.88696009108486000, -456.08203729527503000, -480.59662394089139000, -482.88526107478560000, -492.69513462705947000, -493.61090162209274000, -500.80829081207753000, -530.26352383104688000, -579.836 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 11.28994126919640500, 12.12504850546652700, 18.00209777964264300, 38.67562747292583900, 86.56287898798261400, 93.52990105155240000, 94. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 183.89565486728765000, 353.33832302776676000, 373.45882355836966000, 391.25905222464104000, 446.33508320180647000, 451.14281197040293000, 473.27416574732820000, 474.93286676734363000, 487.47166803936756000, 535.63168241257392000, 636.18796254219467000, 648.3490 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 228.65706981337593000, 239.83952465553540000, 383.56982924124549000, 410.54513470181303000, 610.16982717027270000, 799.90650693584769000, 819.71529893080958000, 838.83821794955713000, 894.51624819586311000, 899.24047166172750000, 920.26880449510077000, 922.06551512591443000, 934.24150909620062000, 983.79522447695194000, 1061.03761925365190000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.88650491581474500, 27.92659287075257500, 75.25505009865078400, 79.58546647108529700, 97.29921928779607800, 98.68806246164588500, 109.87895554740075000, 148.61689848994752000, 235.33800680405918000, 250.31654708114749 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -7.61224027999423130, -85.66902342985986300, -102.38966154971891000, -252.36013506159546000, -395.48482966649669000, -410.21081175071203000, -423.85768906532473000, -470.53087858284096000, -475.45954502683895000, -499.25514865215160000, -501.27163263248991000, -515.61156299846721000, -571.95190185157503000, -681.5039530029 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.78728474026809800, 28.22697851664911500, 30.24182113870342900, 45.28659032407676900, 101.79726471687967000, 209.42751650937370000, 228.24647827734819000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 11.10253524955584800, 50.97156111881054800, 53.96212887725460000, 67.56213747009262200, 68.71415789664271800, 77.61817189963089400, 115.67122300448146000, 173.81344222861259000, 181.0862736667098700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 24.23182627949661900, 72.99828069185611000, 80.74608068157164100, 82.140 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1.04645815169540880, -8.97243816396913020, -44.35551460284651200, -97.85372302678392500, -107.19060363277008000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 38.71639246064067000, 40.97775629286761000, 53.21101384700773500, 54.30002485596334300, 62.47033322575980200, 94.60479890003443900, 168.66514001480394000, 178.72761917653347000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -43.32164040576334700, -520.06575457689985000, -526.82555632682113000, -545.26627244952249000, -547.46991330809306000, -658.95064836986978000, -663.76046012006054000, -717.43501538041744000, -732.05722111981049000, -826.90370492813486000, -924.87276169927054000, -933.76492229529788000, -942.28760082997337000, -966.38862698491675000, -968.54994525317886000, -979.21456989415935000, -980.14465379861713000, -986.70967240491962000, -1015.9394072233742 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq17[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 692.50564787593987000, 841.56855515436246000, 721.65583826507452000, 702.56214861144360000, 592.78905849507169000, 591.97049751962140000, 532.96030232713031000, 522.97336524631294000, 381.78890371556776000, 391.39034111154751000, 318.422359 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -351.3283 [...]
+-2433.26284687127550000, -2325.33727644275590000, -2212.08634207663140000, -2143.05780607881980000, -2190.77412425960710000, -2220.65284529636260000, -2012.42387319387850000, -2070.68669735631970000, -2053.18230767246680000, -1947.95412530022030000, -1909.22891647300680000, -2067.29164327455560000, -1975.62350621204310000, -1958.30429429825790000, -1886.63318483231770000, -1900.19558465403090000, -1792.80723810598260000, -1768.14256953316000000, -1794.74709544416620000, -1811.20995895762 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1057.40739666631320000, -1208.29753104079170000, -1193.88451940420050000, -1363.37973766050750000, -1392.47280270463010000, -1407.11253653350060000, -1287.63455969191700000, -1188.80950406891860000, -1244.98225997605910000, -1232.13072913924730000, -1330.59453518841020000, -1384.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1558.78773892951380000, 1273.82506347913730000, 1455.53912086219700000, 1238.69676945147470000, 1286.98837814043210000, 1127.68562649916270000, 827.32014724240969000, 850.22315790377945000, 1006.49818472720190000, 1080.06687359150690000, 1142.86186170698560000, 994.96801628613218000, 944.99493733461941000, 745.95782042652593000, 752.73431822745988000, 572.33175553990077000, 670.304338 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2205.00665024446700000, -2179.11390398783030000, -2027.37295470206000000, -2262.81787276738710000, -2397.65844626257470000, -2349.03221533148920000, -2387.42653351339410000, -2293.02673233247060000, -2047.86313911959310000, -2202.53097394922770000, -2010.11406384057640000, -1876.30966415439710000, -1737.31582431683480000, -1899.25725020873530000, -1938.19906826530840000, -2027.94055815470960000, -1945.24206106746330000, -191 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 634.51378730969941000, 701.02336458156594000, 669.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -320.41019664617517000, -284.16776690776004000, -156.50468614953019000, -162.1329644677010400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1706.19860416044710000, -1913.91398435744460000, -1749.12095723682840000, -1538.49682466920920000, -1511.73212879590820000, -1481.54088056771890000, -1541.89398979643280000, -1539.48916609722300000, -1585.87647251774500000, -1598.62381500015410000, -1716.40013907426650000, -1710.11937270972930000, -1542.70930505998400000, -1468.97806952445420000, -1379.12497394846600000, -1358.22569911970280000, -1361.12 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1431.71304473722740000, 1427.06563498980110000, 1280.96278177027470000, 1198.98204009543000000, 1119.76814664330460000, 1129.46292519468010000, 1169.74812649221760000, 1229.99426874627330000, 1247.00315685021040000, 1270.87164027140310000, 1282.23182154456840000, 1332.87061007185090000, 1385.7715295522 [...]
+0.00000000000000000, 2102.30783304971100000, 2016.73448578031660000, 1746.57093132922360000, 2002.83375828430350000, 2025.38120715810560000, 2018.03930033091000000, 2081.63850284807220000, 2124.13172366909020000, 2097.12112793234880000, 2041.29303086663550000, 1989.28346226602210000, 1948.74833676005260000, 2000.38591684234530000, 2166.51741499988160000, 2111.88494283823910000, 2234.49103941162590000, 2234.98566299180310000, 2212.94071096311520000, 2180.73994708458580000, 2122.6318416340 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1035.14373073748610000, 997.56 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1127.18862167650580000, -1175.17727839268470000, -1100.02378222192620000, -1192.86049004797310000, -1035.23135790636770000, -1141.31373439938810000, -1044.27582592605860000, -1072.83403349476090000, -1041.73569850597140000, -944.81350280209949000, -1015.82206930634710000, -971.31240412264742000, -1023.07196185543360000, -1048.70194006064000000, -1070.548045934900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 562.11873984997146000, 494.95175565059179000, 465.38626565576573000, 417.88118674798091000, 496.46951769891291000, 499.5431571057815700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1734.33889022421840000, 1630.49739640326520000, 1638.73540795493840000, 1524.99277270268930000, 1489.27427568681580000, 1570.68054332720890000, 1553.04834005333350000, 1433.92964807808610000, 1441.97466972380950000, 1419.00986969037920000, 1496.9324297047654000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1679.66177742159310000, 1853.72307632664980000, 2051.81772250992120000, 1936.88566158098640000, 2293.22620102148310000, 2230.02989170951420000, 2065.39010897274560000, 2056.81684799973620000, 1948.85511165378970000, 1999.33298435574260000, 1946.22731345270560000, 1960.85411602819290000, 1861.12618818114860000, 1892.73746288048570000, 1722.2192 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 951.02355900332668000, 858.47701498560889000, 971.48344722644072000, 1087.97523943265040000, 961.54155232874700000, 901.66347357877498000, 961.77387039188568000, 859.17012943948725000, 977.65578219668339000, 1123.212578 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1106.23231544755000000, -991.65794775890299000, -1048.49155592599350000, -1516.77666696697660000, -1474.27451306326450000, -1336.25339628092910000, -1293.05579212790960000, -1354.35089470346270000, -1623.15907528525370000, -1660.22697692883570000, -1667.12468473409170000, -1607.22361436818440000, -1605.37822147420710000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1119.56437709348190000, 1171.83419967841380000, 1195.14590335822870000, 1190.55375227588070000, 1138.34797502425680000, 1130.72396473005640000, 1324.9486091 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 718.24618105387174000, 805.94552905931027000, 750.35196385014274000, 731.09759928161372000, 734.76781538787077000, 755.42683227412647000, 813.66178099929618000, 671.50084117787264000, 604.9210119483 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 468.70567147671687000, 490.43074502393216000, 532.26029613527112000, 584 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -606.06809082838504000, -612.32929412481326000, -693.37188911367014000, -555.78918806841261000, -651.3107831924754 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 771.86368670873924000, 567.56364671172116000, 650.06359266966308000, 683.92407391491201000, 684.42642731093872000, 684.03331975767242000, 802.60892521189203000, 765.133100765936 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -1683.27163545894970000, -1975.21435787953100000, -1865.98452614613230000, -1574.84646258304520000, -1670.30992069361400000, -1366.38152515966750000, -1357.92611335406700000, -1340.42446769753340000, -1559.42376364241250000, -1626.56419350320200000, -1663.30583244619700000, -1492.94795900627150000, -1485.11478719441420000, -1422.77417819716950000, -1471.83901733961760000, -1499.53458203930290000, -1517.88319737025240000, -1486.46477896451320000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso17[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 81.11424265790721200, 93.01774047776658000, 102.73512822587330000, 132.82222615474325000, 134.78905561318757000, 143.97137113226771000, 144.64301289022887000, 149.54849793634042000, 161.55519960519700000, 185.59696482596075000, 187.83774364 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -0.972940 [...]
+-282.88154111437080000, -558.36435926412094000, -600.92549292866829000, -981.48622330340629000, -987.55980414774751000, -1009.25700368733460000, -1011.22192256409030000, -1155.44983453477150000, -1161.62733920286910000, -1224.00059987648180000, -1235.90046129911300000, -1324.05464311561850000, -1400.37389774068450000, -1409.10726035027230000, -1416.48878015363470000, -1440.75133169142530000, -1442.25673138346910000, -1448.80202459706110000, -1449.39934533528340000, -1454.0906331042818000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -18.36322461116755600, -144.53449930456819000, -267.44646749502817000, -284.60126440754743000, -301.72656647024013000, -357.17231132700573000, -361.15099072600276000, -377.77419743333633000, -379.27154890258043000, -390.32984208216715000, -438.94101127990643000, -537.87289908647210 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 27.42804272085678700, 29.86938035716115200, 223.94980164643752000, 230.93251010148967000, 314.70130585880020000, 328.81981281491102000, 381.67686743545016000, 436.55840900566267000, 445.47975610866052000, 455.28910285719394000, 489.77749405277444000, 491.93770111857492000, 501.03718353367594000, 501.46007198610147000, 504.71812952690851000, 508.21371692723091000, 525.16910788168093000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -544.14198713212841000, -552.35354213685389000, -578.30761814832863000, -581.60709513266886000, -828.83126023656905000, -839.29211441924372000, -962.09371979148739000, -985.20706468462936000, -1097.88275673559560000, -1227.27188708784840000, -1239.52582528129300000, -1249.36912859974930000, -1273.84435148762710000, -1276.51863238444090000, -1289.80823248221580000, -1291.08271731472700000, -1299.56464021245140000, -1331.519598 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 66.37292889092816500, 77.07955054429830000, 78.7211 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -4.15448408641062890, -18.63101731013022500, -33.05320860184179600, -35.23079807700100500, -3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -8.56928705784355320, -42.09526012674933100, -45.43883846582315300, -248.69301069018493000, -257.38427482683511000, -354.48721017787392000, -375.10803945115316000, -498.56985594308850000, -625.92773816527756000, -641.15348603694042000, -657.77447781137278000, -710.55970227058572000, -714.11799438541357000, -729.27907212684511000, -730.40111856287774000, -738.54158118323880000, -770.72903510178344000, -826 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 113.56679249401927000, 136.37737084565737000, 257.74020534123525000, 367.98929690922643000, 379.75699649587017000, 391.34583152171939000, 430.39019811557534000, 433.80932473652439000, 450.14201381834829000, 451.55911401045017000, 462.32973423598878000, 507.33622030216679000, 599.22441167361762000, 612. [...]
+0.00000000000000000, 283.55556326106296000, 328.16164611693875000, 678.19054373341714000, 684.84349018820376000, 708.43125961421981000, 710.99640967905509000, 897.58576296421643000, 906.02590924900881000, 1000.50633885608560000, 1018.58092378707680000, 1121.50658612510260000, 1218.40267398166860000, 1230.64316716264720000, 1245.10976246081990000, 1288.58687977635190000, 1292.63158916674370000, 1311.55841261887120000, 1313.11477050698750000, 1324.36452169090900000, 1365.63450453647100000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 17.46298695880310300, 20.17719 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2.20784225209294330, -161.88746219336144000, -168.34299507169524000, -249.61009408022471000, -263.25340674517423000, -356.35601770379805000, -436.93311396932603000, -446.88696009108486000, -456.08203729527503000, -480.59662394089139000, -482.88526107478560000, -492.69513462705947000, -493.61090162209274000, -500.80829081207753000, -530.26352383104688000, -579.836 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 11.28994126919640500, 12.12504850546652700, 18.00209777964264300, 38.67562747292583900, 86.56287898798261400, 93.52990105155240000, 94. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 183.89565486728765000, 353.33832302776676000, 373.45882355836966000, 391.25905222464104000, 446.33508320180647000, 451.14281197040293000, 473.27416574732820000, 474.93286676734363000, 487.47166803936756000, 535.63168241257392000, 636.18796254219467000, 648.3490 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 228.65706981337593000, 239.83952465553540000, 383.56982924124549000, 410.54513470181303000, 610.16982717027270000, 799.90650693584769000, 819.71529893080958000, 838.83821794955713000, 894.51624819586311000, 899.24047166172750000, 920.26880449510077000, 922.06551512591443000, 934.24150909620062000, 983.79522447695194000, 1061.03761925365190000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 14.88650491581474500, 27.92659287075257500, 75.25505009865078400, 79.58546647108529700, 97.29921928779607800, 98.68806246164588500, 109.87895554740075000, 148.61689848994752000, 235.33800680405918000, 250.31654708114749 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -7.61224027999423130, -85.66902342985986300, -102.38966154971891000, -252.36013506159546000, -395.48482966649669000, -410.21081175071203000, -423.85768906532473000, -470.53087858284096000, -475.45954502683895000, -499.25514865215160000, -501.27163263248991000, -515.61156299846721000, -571.95190185157503000, -681.5039530029 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.78728474026809800, 28.22697851664911500, 30.24182113870342900, 45.28659032407676900, 101.79726471687967000, 209.42751650937370000, 228.24647827734819000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 11.10253524955584800, 50.97156111881054800, 53.96212887725460000, 67.56213747009262200, 68.71415789664271800, 77.61817189963089400, 115.67122300448146000, 173.81344222861259000, 181.0862736667098700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 24.23182627949661900, 72.99828069185611000, 80.74608068157164100, 82.140 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1.04645815169540880, -8.97243816396913020, -44.35551460284651200, -97.85372302678392500, -107.19060363277008000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 38.71639246064067000, 40.97775629286761000, 53.21101384700773500, 54.30002485596334300, 62.47033322575980200, 94.60479890003443900, 168.66514001480394000, 178.72761917653347000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -43.32164040576334700, -520.06575457689985000, -526.82555632682113000, -545.26627244952249000, -547.46991330809306000, -658.95064836986978000, -663.76046012006054000, -717.43501538041744000, -732.05722111981049000, -826.90370492813486000, -924.87276169927054000, -933.76492229529788000, -942.28760082997337000, -966.38862698491675000, -968.54994525317886000, -979.21456989415935000, -980.14465379861713000, -986.70967240491962000, -1015.9394072233742 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq17[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 692.50564787593987000, 841.56855515436246000, 721.65583826507452000, 702.56214861144360000, 592.78905849507169000, 591.97049751962140000, 532.96030232713031000, 522.97336524631294000, 381.78890371556776000, 391.39034111154751000, 318.422359 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -351.3283 [...]
+-2433.26284687127550000, -2325.33727644275590000, -2212.08634207663140000, -2143.05780607881980000, -2190.77412425960710000, -2220.65284529636260000, -2012.42387319387850000, -2070.68669735631970000, -2053.18230767246680000, -1947.95412530022030000, -1909.22891647300680000, -2067.29164327455560000, -1975.62350621204310000, -1958.30429429825790000, -1886.63318483231770000, -1900.19558465403090000, -1792.80723810598260000, -1768.14256953316000000, -1794.74709544416620000, -1811.20995895762 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1057.40739666631320000, -1208.29753104079170000, -1193.88451940420050000, -1363.37973766050750000, -1392.47280270463010000, -1407.11253653350060000, -1287.63455969191700000, -1188.80950406891860000, -1244.98225997605910000, -1232.13072913924730000, -1330.59453518841020000, -1384.7 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1558.78773892951380000, 1273.82506347913730000, 1455.53912086219700000, 1238.69676945147470000, 1286.98837814043210000, 1127.68562649916270000, 827.32014724240969000, 850.22315790377945000, 1006.49818472720190000, 1080.06687359150690000, 1142.86186170698560000, 994.96801628613218000, 944.99493733461941000, 745.95782042652593000, 752.73431822745988000, 572.33175553990077000, 670.304338 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2205.00665024446700000, -2179.11390398783030000, -2027.37295470206000000, -2262.81787276738710000, -2397.65844626257470000, -2349.03221533148920000, -2387.42653351339410000, -2293.02673233247060000, -2047.86313911959310000, -2202.53097394922770000, -2010.11406384057640000, -1876.30966415439710000, -1737.31582431683480000, -1899.25725020873530000, -1938.19906826530840000, -2027.94055815470960000, -1945.24206106746330000, -191 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 634.51378730969941000, 701.02336458156594000, 669.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -320.41019664617517000, -284.16776690776004000, -156.50468614953019000, -162.1329644677010400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1706.19860416044710000, -1913.91398435744460000, -1749.12095723682840000, -1538.49682466920920000, -1511.73212879590820000, -1481.54088056771890000, -1541.89398979643280000, -1539.48916609722300000, -1585.87647251774500000, -1598.62381500015410000, -1716.40013907426650000, -1710.11937270972930000, -1542.70930505998400000, -1468.97806952445420000, -1379.12497394846600000, -1358.22569911970280000, -1361.12 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1431.71304473722740000, 1427.06563498980110000, 1280.96278177027470000, 1198.98204009543000000, 1119.76814664330460000, 1129.46292519468010000, 1169.74812649221760000, 1229.99426874627330000, 1247.00315685021040000, 1270.87164027140310000, 1282.23182154456840000, 1332.87061007185090000, 1385.7715295522 [...]
+0.00000000000000000, 2102.30783304971100000, 2016.73448578031660000, 1746.57093132922360000, 2002.83375828430350000, 2025.38120715810560000, 2018.03930033091000000, 2081.63850284807220000, 2124.13172366909020000, 2097.12112793234880000, 2041.29303086663550000, 1989.28346226602210000, 1948.74833676005260000, 2000.38591684234530000, 2166.51741499988160000, 2111.88494283823910000, 2234.49103941162590000, 2234.98566299180310000, 2212.94071096311520000, 2180.73994708458580000, 2122.6318416340 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1035.14373073748610000, 997.56 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1127.18862167650580000, -1175.17727839268470000, -1100.02378222192620000, -1192.86049004797310000, -1035.23135790636770000, -1141.31373439938810000, -1044.27582592605860000, -1072.83403349476090000, -1041.73569850597140000, -944.81350280209949000, -1015.82206930634710000, -971.31240412264742000, -1023.07196185543360000, -1048.70194006064000000, -1070.548045934900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 562.11873984997146000, 494.95175565059179000, 465.38626565576573000, 417.88118674798091000, 496.46951769891291000, 499.5431571057815700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1734.33889022421840000, 1630.49739640326520000, 1638.73540795493840000, 1524.99277270268930000, 1489.27427568681580000, 1570.68054332720890000, 1553.04834005333350000, 1433.92964807808610000, 1441.97466972380950000, 1419.00986969037920000, 1496.9324297047654000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1679.66177742159310000, 1853.72307632664980000, 2051.81772250992120000, 1936.88566158098640000, 2293.22620102148310000, 2230.02989170951420000, 2065.39010897274560000, 2056.81684799973620000, 1948.85511165378970000, 1999.33298435574260000, 1946.22731345270560000, 1960.85411602819290000, 1861.12618818114860000, 1892.73746288048570000, 1722.2192 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 951.02355900332668000, 858.47701498560889000, 971.48344722644072000, 1087.97523943265040000, 961.54155232874700000, 901.66347357877498000, 961.77387039188568000, 859.17012943948725000, 977.65578219668339000, 1123.212578 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1106.23231544755000000, -991.65794775890299000, -1048.49155592599350000, -1516.77666696697660000, -1474.27451306326450000, -1336.25339628092910000, -1293.05579212790960000, -1354.35089470346270000, -1623.15907528525370000, -1660.22697692883570000, -1667.12468473409170000, -1607.22361436818440000, -1605.37822147420710000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1119.56437709348190000, 1171.83419967841380000, 1195.14590335822870000, 1190.55375227588070000, 1138.34797502425680000, 1130.72396473005640000, 1324.9486091 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 718.24618105387174000, 805.94552905931027000, 750.35196385014274000, 731.09759928161372000, 734.76781538787077000, 755.42683227412647000, 813.66178099929618000, 671.50084117787264000, 604.9210119483 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 468.70567147671687000, 490.43074502393216000, 532.26029613527112000, 584 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -606.06809082838504000, -612.32929412481326000, -693.37188911367014000, -555.78918806841261000, -651.3107831924754 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 771.86368670873924000, 567.56364671172116000, 650.06359266966308000, 683.92407391491201000, 684.42642731093872000, 684.03331975767242000, 802.60892521189203000, 765.133100765936 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, -1683.27163545894970000, -1975.21435787953100000, -1865.98452614613230000, -1574.84646258304520000, -1670.30992069361400000, -1366.38152515966750000, -1357.92611335406700000, -1340.42446769753340000, -1559.42376364241250000, -1626.56419350320200000, -1663.30583244619700000, -1492.94795900627150000, -1485.11478719441420000, -1422.77417819716950000, -1471.83901733961760000, -1499.53458203930290000, -1517.88319737025240000, -1486.46477896451320000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso17[1500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 35.12206015288220600, 88.16611845291385000, 94.24995235123898900, 112.92444708956641000, 135.70504824853643000, 155.69287804204529000, 170.07430616208578000, 177.86974403424944000, 204.71842359621104000, 210.06725873308488000, 217.06355507197446000, 213.20119591083451000, 215.14270404201616000, 214.78161748678318000, 212.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 18.30374149377629700, 27.64869155660520800, 89.68905639815037000, 170.61359937774216000, 178.79889492153976000, 215.00985334862486000, 262.18046745391757000, 303.14939204909211000, 351.12480992654991000, 370.41585791350388000, 459.45175849763046000, 494.54434039336081000, 543.45086248949860000, 599.53748450087744000, 654.44248742810373000, 661.00199587968586000, 7 [...]
+0.00000000000000000, 153.29846734533947000, 338.31620721845439000, 373.43485335900999000, 571.46032808344694000, 591.83929941572512000, 609.00422807891323000, 618.42984008869246000, 685.83248651905774000, 788.31301077169610000, 799.67571977757257000, 846.84438020991206000, 913.17512912489724000, 974.57169316972136000, 1043.54416146192120000, 1069.08365353997330000, 1175.48701145351400000, 1210.57712348338010000, 1251.30024738531600000, 1289.51601535655250000, 1322.30750508555000000, 1325 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 139.32815 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 51.71824434737088400, 104.06583007240690000, 165.09538453644376000, 187.94702470469048000, 290.27194815832655000, 321.04533520518879000, 356.09573166668645000, 392.97159702716164000, 427.01663204207756000, 431.04176087764455000, 452.3573931 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 35.11875225123300500, 205.59218809105161000, 222.19617166661047000, 239.17003759784757000, 247.78126377951224000, 303.45835897730086000, 389.04899822743852000, 398.90599406034545000, 439.35584701197035000, 494.31383610623203000, 545.06097000668581000, 607.28876453220073000, 633.31758417137246000, 752.56341803604585000, 792.29719539441589000, 832.65326438536101000, 880.29963091478032000, 926.20106224201174000, 931.849964430905 [...]
+693.29562769438303000, 821.37073870384756000, 971.76679790806577000, 998.83590348478344000, 1145.78945686580160000, 1163.35732529695410000, 1181.86926250942000000, 1191.27128391367430000, 1255.44267798023000000, 1342.09865217130870000, 1351.93317009184420000, 1393.16366866087130000, 1434.16842751385410000, 1470.05885534960480000, 1520.64480292997930000, 1538.16969775297370000, 1613.91507133077200000, 1642.66297759549500000, 1672.37629628322750000, 1718.62187932448570000, 1762.38599651730 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 19.20025517066351400, 101.79218033848325000, 131.81076097525150000, 159.68369941097077000, 189.22121695315235000, 214.19516261448041000, 216.96331233695605000, 240.0040119346095 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 62.94140364587393300, 70.12203168598998100, 117.75589910122125000, 442.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 54.26194198316827100, 107.62292811294384000, 113.67351465522621000, 153.66714167943337000, 39 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 6.65272418259821750, 36.00581319716434300, 75.34888114632312300, 113.41188123045421000, 159.98665938337012000, 174.35135770627022000, 237.11541602836002000, 262.16527215553555000, 281.81620248700739000, 302.36213648591985000, 329.04703574757337000, 332.14213665840504000, 362.134939 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 35.61051575138814900, 79.22371516320507100, 98.00834781765505000, 180.36685072818619000, 212.85120863602279000, 247.23118774695894000, 285.90619533779227000, 315.18874209331722000, 318.55591565116811000, 338.98777486849 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 22.02413694566892800, 168.5204 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 46.01107875912961000, 108.79913082076361000, 171.12732940680675000, 249.82235332632942000, 280.96961329611355000, 420.23074190606212000, 467.74843170166253000, 514.79410579669548000, 570.34678107698869000, 630.62795158820677000, 637.74544650120902000, 684.57683 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 50.26370286208575800, 101.94113070115465000, 146.27261352397238000, 151.00437672715458000, 180.95406064737045000,  [...]
+0.00000000000000000, 0.00000000000000000, 196.14300627726669000, 237.25919058243977000, 426.82041736890335000, 446.94925668244628000, 465.88089826969076000, 475.58631598258336000, 541.38252555554993000, 628.59873259063079000, 637.71535597887419000, 673.39750250994348000, 702.33530337112165000, 735.61356400462535000, 770.19217619586152000, 783.52970901257129000, 845.96619832945078000, 866.21700210770030000, 887.90574846661480000, 904.72581603732522000, 930.47700787193946000, 933.725455996 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 148.32012561868558000, 160.85192576617578000, 171.91344503229021000, 178.88048262773151000, 235.73138728794987000, 327.54692392211922000, 337.02362898259889000, 383.94161830453311000, 453.79749662300748000, 524.20907513795828000, 620.26099794312222000, 659.83082959426940000, 829.74300939433556000, 887.81012186796204000, 951.50824384064344000, 1013.02121168462240000, 1071.31952081554890000, 1077.7008708475 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 36.66052972715479500, 65.57212250491127700, 100.30908469800177000, 136.45907345515565000, 140.80914090996660000, 174.51124627066025000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 68.68140011717125000, 97.19771074601267500, 221.60695920793509000, 267.58334895170913000, 313.08928198489542000, 362.46081346038949000, 409.55607841724458000, 414.92938629833895000, 449.413306613731 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 16.60283005407254800, 31.67409099241383400, 39.44028674014624200, 89.60781683991706400, 169.49521880729398000, 178.54746055842767000, 219.39885086913233000, 258.83058567106065000, 290.64625673965025000, 326.85738664357342000, 342.72179076495701000, 416.18999081875018000, 442.73580223378764000, 465.10195599565486000, 492.40601218802919000, 516.96423248648432000, 520.11766331327181000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 4.27624601032375210, 31.37132105506383400, 66.06875615522872600, 70.01396803300093600, 77.21224155990330500, 86.09298721499224900, 96.70626211026866800, 111.42991448598390000, 117.67838756845538000, 143.84571436014801000, 149.69583145812862000, 161.96219739631169000, 175.30647293139253000, 176.69876392045452000, 176.71166250044260000, 175.8301 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 27.27241817510921300, 37.10851997606354000, 31.96568381551625700, 19.47487622466730900, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 68.41592326408171200, 77.40880370520595500, 118.76418538386582000, 179.34069664719499000, 236.30690094550482000, 290.35309827069153000, 312.16983797171463000, 409.00575168949854000, 447.21590792812077000, 488.18169792906053000, 534.63155572914161000, 582.28906111720892000, 587.84516240916957000, 627.93 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlassolsq17[1500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 774.22341078762281000, 794.54537469823163000, 795.64937589573242000, 617.91632096409512000, 613.25578341121900000, 570.13315427604959000, 413.87770074634415000, 500.05382864513842000, 426.73864581014709000, 329.43684264437888000, 348.37788555245544000, 76.93814423842059100, 148.36471893974925000, 148.36471893974925000, 159 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1584.83723792770230000, 1485.61184450054450000, 1395.25362888223910000, 1248.27281916413990000, 1122.47383278292200000, 1194.21919781114500000, 1251.02010723611060000, 1152.62492799488470000, 1164.43553522394880000, 1167.71149913146610000, 1195.71777810151750000, 1277.70306412897640000, 1621.59985113427890000, 1740.73824456850870000, 1867.53323065824770000, 1867.5 [...]
+0.00000000000000000, 1783.29378727712200000, 1963.70669502522670000, 2015.74927172697080000, 2152.35663909263170000, 2199.90882429876960000, 2078.07194431201240000, 2088.97755963894310000, 2104.23980078791100000, 2153.02979190014550000, 2109.67163350882130000, 2122.36966502475750000, 2303.66951016407760000, 2247.60679630128150000, 2212.81064613466560000, 2124.62639681250720000, 2055.37002818639800000, 1993.68072739327500000, 2123.78148586496350000, 2000.70246332810210000, 1931.7226386782 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 535.20950 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1135.89005513758590000, 1189.47370637484980000, 1199.70838848164450000, 1132.40131838255500000, 1136.42910053414490000, 1007.81288614378170000, 1126.13929165009130000, 1137.82132681802200000, 1171.40877160205200000, 1171.40877160205200000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1677.43813285762510000, 1566.53237126321600000, 1532.38791511462700000, 1691.88556869857080000, 1591.27163987817380000, 1475.11560462231770000, 1528.84587713701260000, 1535.30966822782920000, 1533.19251173662680000, 1646.40055725463800000, 1597.28406821508470000, 1662.21511928490140000, 1709.08415001033450000, 1738.64492985198760000, 1679.03315736027230000, 1728.43278010348560000, 1866.28792407638530000, 1970.8877190762209000 [...]
+2228.78184886693230000, 2183.17059985240940000, 2293.00401657588420000, 2264.71563595059210000, 2318.96341720108880000, 2549.60756240021960000, 2766.22127802876960000, 2658.13848795771900000, 2605.85218756628180000, 2496.08242641565720000, 2485.74538712172810000, 2508.11039278407130000, 2293.75297485579040000, 2214.23363470637700000, 2378.21093860259820000, 2262.47053742876780000, 2240.27751997969060000, 2284.22801396834980000, 2318.70357605122040000, 2627.48562204293010000, 2672.9580715 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 812.74344516196140000, 784.77092931262371000, 801.73334944989392000, 765.05080489523561000, 765.94065527652799000, 726.12632773102632000, 726.12632773102632000, 828.562204536567 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1390.89966002138790000, 1390.89966002138790000, 1334.52897466377840000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1125.18503179775010000, 1226.59557366005920000, 1226.59557366005920000, 1175.2757407239435000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 773.63896750516619000, 829.76605320241720000, 900.09932963385597000, 902.63414458418606000, 949.55282213923476000, 768.04182843676256000, 756.13126347664024000, 821.20117930565686000, 712.50986549378399000, 714.50845368067633000, 901.44332001295891000, 901.44332001295891000, 1128.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 773.98142131280827000, 818.58325418311824000, 874.37393186482814000, 861.41535723683432000, 937.80237797610243000, 998.55511548348932000, 1054.63086432732690000, 937.90111513599322000, 937.90111513599322000, 860.9050057 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 584.61496364439631000, 584.769 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1290.23327631468530000, 1425.02780328753400000, 1463.47953102283400000, 1583.91197282199280000, 1568.28042329388650000, 1571.82505582342540000, 1528.19742932058560000, 1550.36338093208840000, 1695.29397571976480000, 1946.91060564411510000, 1946.9106056441151000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1135.38502996160560000, 1092.05855287874530000, 1021.34704681519830000, 1021.34704681519830000, 945.99731649005969 [...]
+0.00000000000000000, 0.00000000000000000, 1919.26953928719490000, 2160.04693252447490000, 1940.14411753481200000, 2035.28129482156460000, 2086.15349111547630000, 1989.78824474530820000, 1925.98431572232990000, 1790.04303818105200000, 1688.76219520084460000, 1638.30682364984340000, 1308.95968429996170000, 1425.62602018510670000, 1356.39147169477610000, 1334.76760892115820000, 1362.27327407969070000, 1318.15278981113650000, 1372.33645629322560000, 1269.73532237744580000, 1531.2327472487571 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1332.40383891511100000, 1149.71468927500180000, 1118.61827353467610000, 1265.85088172408090000, 1432.09003584877790000, 1550.23976753077980000, 1429.58394170768720000, 1652.68830613223260000, 1918.18931901732940000, 1984.16717720691120000, 2248.59614246270620000, 2295.24505491390300000, 2234.80055902188040000, 2183.68985596614400000, 2331.74823268101360000, 2203.70811331496270000, 2251.46231814985640000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 854.81103680293393000, 704.82062769957963000, 811.49400476019332000, 940.94413522605691000, 940.94413522605691000, 1035.407424092913100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1233.01350633075730000, 1275.77184437361170000, 1250.38637926246610000, 1293.63525988523090000, 1306.25709920376310000, 1340.37446041818270000, 1403.27536381719620000, 1403.27536381719620000, 1330.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1326.70355110855580000, 1321.55436500282080000, 1251.09226589648030000, 1145.32291707462920000, 1233.34299730679050000, 1222.17180207414120000, 1324.09380687468430000, 1085.43976125842570000, 950.33245791585921000, 940.73219230391408000, 998.39483999760409000, 1023.72177143974570000, 1035.15684010722110000, 966.04545516600467000, 1069.27840566818870000, 1100.14783132303110000, 1100.14 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 671.43969515220317000, 601.55446162102692000, 528.12896016605271000, 524.85369296239116000, 271.86648457678393000, 272.26044551802272000, 316.76860128299063000, 361.03491893444681000, 375.92668783142642000, 360.23161503837889000, 280.25249023494655000, 424.38792722485022000, 424.63525060320723000, 179.08417863557744000, 179.08417863557744000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 252.79666898883318000, 256.62012376336435000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 979.49985121817542000, 1114.18943625099970000, 1237.08797305991770000, 1449.20874295213710000, 1417.48012931977290000, 1206.57965534603270000, 1213.85187624023890000, 1209.77254665590070000, 1299.94932271338850000, 1386.60818106963140000, 1466.84958060006740000, 1609.81347022147430000, 1609.81347022147 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+
+
+// Data from file x96.txt and y96.txt
+double x18[5000] = {
+12415.8782440174, 3873.35623361025, 816.142441100852, -18579.4282591118, 4144.51296617457, -359.171440135352, -16113.0619862521, -2570.66166514944, 10529.0031214999, 8199.8387529444, -23196.6826841587, 7636.6821667783, -19312.8914833516, 9462.19249234831, -3520.67703443934, 15623.4358168118, 12868.8284428299, 6666.19478878707, -7249.14594964446, 6812.8508448929, 8359.64869645361, -1275.53402980811, -3216.19385598199, -26349.7832582027, -6389.12490591718, 7347.09822185748, -636.2927226715 [...]
+-6735.32722552963, 23031.5746836725, -8110.34634471375, 13242.3758215022, 4209.92212247194, 8241.88401516978, 22812.1858541528, -2533.97470246596, -104.551884060091, 10620.2354915941, 3431.10251962928, 12311.4009543797, -20281.2760793969, -2798.22586660904, -763.579190186903, 539.431038727241, 6143.02202652748, 1587.36704302332, -7617.26668546328, -883.63183789354, 4378.92335459218, 11212.3610227131, 13643.3566747908, 13201.5367771712, 2035.99338974785, 10232.6640413507, 8073.31561812751 [...]
+3817.94587131898, 4319.72035784592, 14982.2034640978, -614.179374472217, -1236.02484875965, 20059.7294040068, 6612.07669619882, -7433.87145741248, -19746.2998098276, 24060.3361205468, -3963.09712898692, 5649.54422118686, 1699.15809360583, 805.958063320537, -7395.41074074976, -14596.1320080388, -16983.7413136805, -1772.65013772206, 1728.12252108465, -4087.35582765373, -5757.3375568891, -8118.79608920078, 11698.3160410484, 14368.9460823063, 570.951183786683, 3287.81608781689, 2244.40172987 [...]
+10801.506191435, 3418.64368502650, -1652.24463713205, 35867.0683014901, 8382.45309016848, 10180.8514231209, -17082.1616613093, -7070.16548476092, -9187.3879170738, 1226.85829005655, 10609.9003369070, -9762.2358124653, -3455.24337703724, 4083.3171463123, 3505.27930560954, -3471.65881614933, 1079.72199496515, -2672.28183737206, 7215.86414554712, 5704.82117416114, 4313.72431194336, 9264.64487295467, -5359.75039842319, 12932.5835186964, 3929.07682694112, 17255.3591516796, 8859.65745415264, - [...]
+1849.52096914445, 17452.3427472123, -828.376045079629, -9228.61622682664, -9370.04784652278, -8475.31906722503, 12837.7536348651, 2002.60536839301, 14747.6756773478, -14264.3853653217, -8483.71877325848, 15602.7090402179, 8170.09164343173, 2552.45601120689, 4372.80251379824, 2839.02177814786, 2519.91976588592, -30462.6050264693, 4518.29740418859, 1734.59460845634, -8279.59815970197, 7653.37978241942, 3575.2825960552, 9553.68658925885, -10636.2658197254, 6945.99953254778, 16684.4053144474 [...]
+-4869.23419088084, 7596.7075613986, 1287.32409570381, -13925.0307956378, -5262.93056068832, -4429.73809187095, 4349.00744900955, 9280.21167171263, 664.658915921871, -766.289962942368, 4398.14321390291, -7367.67159115868, 4984.76849612577, -7465.58246719727, 8594.11680975306, 4482.65160763574, 16479.9874244946, -6927.33808840412, -6619.99311671458, -15911.8304694932, -12238.2800212072, -24111.5562351885, -3863.09615829251, 4049.3740016571, 4406.11568046858, 8204.37735989016, -11056.705313 [...]
+-465.004579381435, 19857.3195109557, 12949.6170174442, 9429.67990635734, 2409.20402816353, -9972.9875337052, 4006.87041347692, -20189.7000534218, 10735.5625501282, -5293.428826109, -11235.7809009799, 3713.44976835408, -6766.59659364796, 2027.83108330505, -3222.77449662801, -1647.00605777427, 5738.08695053969, -6289.94584700366, 698.376864271748, 5896.12481380655, 7043.72864042415, -21918.8524156240, 18416.0488684686, 5071.17980023553, -6052.44694045103, 12326.9950700125, 16241.2399716212 [...]
+8655.94032260379, -7716.16554371596, 466.806830444922, 2098.01692323132, 15697.1544722192, -1171.44839529998, -5106.82348922319, 21812.2868647497, 18190.969286307, -2624.94469734102, 8504.69763534014, 7320.35842053311, 2838.96143832428, 17063.5078638073, 6995.01493279114, 10402.8893145684, -5795.91153112133, -9383.10015540839, 13290.9602914757, -24418.5675953218, -12061.4752915948, 3096.37519257487, -9695.45326050444, -20358.1446001284, 6763.84485940329, 12025.1476198752, 6080.4162254897 [...]
+12204.2689372542, 1334.30024292184, 13589.9820956216, -9278.71480251671, -11175.7297386137, -3975.43688914725, -24308.8409180267, 16847.0031022575, 17680.6838671714, 9816.75928258833, -5707.91763154291, -6358.68373851975, 499.889988880865, 3855.18927857309, 11491.4767740943, -4872.04888916074, 7410.77598671746, 16439.7662303061, 7608.67502676867, -5163.10719830749, 4665.22642190465, -298.859890354814, -8868.16473959497, 6632.04243897066, -7492.5688307243, 7484.66103697812, 4277.025337024 [...]
+10470.5238778649, 4898.02962397784, -14915.8991770511, 20228.7003216919, -3846.81430236173, -593.7519478331, -5699.62842839856, 4116.05382298940, 7675.93440642467, -1933.64831915315, 4990.85856111278, 535.853889456422, 4828.38157466183, 1021.33126022566, 10400.7217081636, 6582.22907274398, -4312.31710302587, 1262.79568058362, -8279.86814175788, -23113.1400097851, 114.902214165538, -12453.0901584676, 5855.95322739741, -14803.9379257163, 13364.2334877127, 246.768444310122, 10555.3631780542 [...]
+-1322.51749581447, -5547.49784647615, -15225.8234697922, -6005.42955052119, -10992.4938153552, -6758.4388014511, -336.568512499124, -22600.8840370512, -22313.2531788101, 8278.77665033993, -1053.33782389085, -82.9664717792929, 9096.21282753642, -14393.4449658029, -854.901247472006, 5791.00770859448, 455.405237742697, 16074.7369368865, 4889.25265183857, 5545.4245554453, 7270.3787167422, 141.631628043424, -12246.8492817849, 13328.2209875262, 13653.6111488949, -5783.57327377046, 13336.142870 [...]
+-17594.2400486336, 10086.7131143053, -1851.42189815951, 1664.39333920265, 10076.2823332633, 22445.5758725395, 16909.2176685247, 4413.90067390731, 569.110520194164, 8774.61777998371, -4831.01081480634, 1995.13902530019, 8792.97140049428, 2277.39103090701, -5816.34716231599, -8613.26478219315, 4993.63678012194, 2497.73667871878, -632.470289390047, -9342.8156485954, 8161.91745632153, -2532.84382905181, 8293.3702271923, -7017.7370145876, -3598.9283595761, -21272.0871986174, 3934.58957019214, [...]
+-17304.9036175262, 19611.9068082217, -3049.46885790412, -3921.46436826797, -2821.46103879659, -5014.82607375863, 11150.1580427879, 2060.85400241403, 8295.97832946733, 8184.52569693049, -18848.9093865381, 689.127423197682, 2900.58579929373, 1667.78634827564, -9201.70401984798, 1403.31185755320, 11645.3127514392, 12474.4042834589, 2628.48471479125, 17646.8541640369, -14235.5216425708, 2950.02502235217, -5986.95863390309, -12053.1694331616, -2150.84822531497, -4064.80820769132, -3087.117834 [...]
+-5119.44675434845, 7802.94097935616, 5141.30587241196, 11675.1009802303, 8718.19207590023, 6205.36585823454, 14414.5556209323, -5501.0201345189, -3501.43871428131, -8749.58284242878, 1638.33533151777, 4948.23555628164, -7147.73828455853, -8571.08336061183, -9459.0804842545, 4348.08484936688, 11937.1933318352, 1516.34795146950, 8360.66181850878, -25173.1104721914, 789.473659431556, -12001.6879701314, 4207.73475185286, 1023.39922153712, -4207.50930065091, 825.998115269438, 9627.39454822827 [...]
+-22299.1968430341, 965.385997462268, 3829.99300162313, 7523.18948790185, 1679.67464520319, 2197.25478629167, 7800.10411983554, 6269.29386375616, -4314.35204303831, -8866.9282616896, -8415.2563873269, 1296.76836738307, -494.509324242059, -5095.52119508032, 10052.1748328779, -2537.45056170068, 18145.8842568854, 26914.0818912374, -12471.2554918114, -3619.02307971364, 7380.10779908298, 9096.50866376968, 4520.04192827558, 11943.6090886951, -64.8756270613685, -5169.90523812493, 255.56274151070 [...]
+7192.59510657426, -10330.0073327378, 2664.09359998104, -2360.89532615281, -5699.8724199882, 1011.45143876917, -226.92504858043, 9533.09199136813, -6930.63426705413, 3778.59897946747, 3497.73235026066, 5802.37167339809, 7290.25963570991, -12553.8067312819, -2158.00347765141, 11852.3687501486, 10153.0081273598, -854.071620112334, -10781.0139063643, -6260.20120217728, -9918.2125061766, 18022.0352101900, 2107.03688306322, 2089.19535008446, -11665.2608043389, -8578.82085408934, -4487.66106294 [...]
+4938.34956080331, -16283.7043076379, -6508.59148918495, 11009.9194961492, -10535.0379339773, -2480.21294059967, -4579.78939532425, 5704.98910539023, 10922.2032762103, -18392.6909049460, -1026.95288767364, -9172.39651016291, -753.272175377805, 10203.0978259185, 10326.2421611028, -7949.24141462262, 493.373144864839, 4449.02735840561, -24320.8074833583, 10967.4266613922, -2388.53669201931, -7742.55136929122, 17903.1626799337, 23902.0576501840, -15889.4648016145, -17698.4583400809, 9408.6460 [...]
+-33228.1683654055, -22456.7623559734, 5555.32774643446, -8486.62313077727, -5355.44018261271, -6143.67097775204, -4334.0493516365, 2307.91223195705, -9500.14426840961, 8222.79300017751, 887.363023862031, -3280.12101318538, -9989.51790617473, 12447.8986620554, 9588.50893991186, 12.87378675203, 7046.14714814526, -14642.1398933902, 26716.2381269701, 16375.9656128367, -11932.1371063695, -382.016358538956, 4767.79922767384, -15264.6074251167, 3303.91562742647, -3762.66787715378, -16720.046302 [...]
+2177.72891100514, 1874.41047442569, 9334.20504750417, -1759.24086676385, 1844.77889299489, 4999.16725683293, -7776.7005032344, -3390.99602144034, 116.218721969797, 5827.44238280772, -15824.0216031410, 7726.77822521096, 2701.58719288505, 11542.9665568669, 2577.47857093905, -12364.8471347093, -11055.4115123857, 2448.29878605098, -751.41632705818, 11682.0678076662, 1109.30638922436, 13366.3331860672, 8333.45149758595, -530.232286137808, -9988.55663706946, -10834.3147585583, 169.434744846267 [...]
+-6428.81506677854, -7284.57145998901, -4772.64285838644, -23700.6900577964, -744.316741465494, 5854.83857654324, -998.084503598093, -19942.2166432, -2864.15993215262, 8611.81516786625, -9074.28537403182, -11950.9607440231, -3558.19138774729, 4250.46013889791, -976.405573208324, 1982.15646874150, 7184.53955030647, 7279.50650032321, 18227.7161622653, 6634.63639958113, 13010.3996389059, -2497.62550358545, 18588.1695369081, 10683.3876519133, 5483.25845922987, -28871.4809145101, 12456.7015801 [...]
+4413.96726707821, 19221.0364952385, 11140.4301800009, 714.229340847092, 7767.36008566599, -3754.74988132045, -5115.98468708407, 2427.59171815693, -3691.81017219635, 3735.53446212107, 2940.57783669365, 8715.93100742538, -5062.39301088836, -20228.5390031748, 3939.41345139296, 31248.8746183167, -16029.3427214148, -5044.98388995313, 2620.32602501934, -3090.39017904422, 5205.06581701634, 5350.02052162602, -5431.14628835509, -5319.91871721067, -1124.10825788397, 4959.33927497917, 6857.74428861 [...]
+5751.14753732872, 13326.8755224141, 10007.9712916698, -11092.4152005611, -9438.64287955685, 9012.66508457793, -960.891641463942, 5294.81596481049, -6895.75147407735, 2303.81742004735, -12841.6782315327, 5061.22698950104, -9667.64799855756, 6138.04025053918, 20646.0049598056, -9606.67175443022, 10009.9948280060, -10224.341624057, -1222.59480046359, 410.684314559038, -10311.1624544887, -7004.61675608458, 20113.6886407358, -14380.9227879116, 89.6342686684776, -11464.0613829470, -14661.71364 [...]
+-478.02260540219, 3793.43328386292, -4977.51226199705, 11658.6328743923, -8107.1503382027, -585.725281588607, 7352.62325512722, -2437.23188163934, 14034.0178842673, -13659.2285221181, 9448.89811253357, 11921.1048353536, -4382.98374777479, 2934.16225601349, -7854.90362102645, 24133.2508806944, 4279.08785176352, 15497.7881781256, -2503.17700138644, 7988.63772254848, -4317.37815236093, -12101.0009326986, 6805.81275616052, 3672.66760697247, 14439.3119530163, -23482.2295760807, -4374.97719455 [...]
+-10958.6002314171, -771.202357743367, 2977.08137735400, 9978.16892764113, -5673.80061043045, -16455.1964437133, -8522.15434220755, 13806.3243163556, -4386.15311382555, 9616.85943469958, -10253.1119254834, -7660.4234064023, -4716.65601434823, -438.727520242842, 16060.5522514383, -11355.9974879917, 17787.2401665389, -676.437720634631, 12155.0323335028, -2751.07493457163, -155.624897020851, 12827.8571733325, 4713.69918136822, -13914.0820440998, -22492.8650662074, 4525.82222076828, 12584.841 [...]
+17314.8641894181, -3367.71249487472, -5570.25361071743, -12747.8724599579, 11041.5264266871, -197.566228521599, -6601.25655522273, -6316.3790725808, 1110.56347901311, 1715.41500489417, 5274.27274695973, -11731.3323407707, 5458.9611450692, 387.644696570441, -14092.0176921123, 3054.40493887978, -552.582083531029, -6395.44570819946, -430.341216446099, 9817.94806757775, 17250.8630815638, -2241.02779195974, -11206.7029278565, 17008.2016731368, 517.595634943368, -11791.7312613586, 2522.6371805 [...]
+11510.8984278893, 8698.0593757613, 6283.87977510937, 9028.37102975143, -24499.1957989574, -2666.46122965851, -1569.08981839462, 1505.85667702813, -2039.99902011311, 2982.88604329669, 7147.84776955302, 24933.8564114922, -6555.29194738166, -6921.83377066187, -1702.58178482649, 4578.66956514153, 6716.92062444715, 4331.12399569048, -20459.8356745394, -13077.0396001938, 17662.2994422817, -11031.6087770294, -11856.2624107483, 9691.88113625908, -9353.15435546526, -20328.3640536399, -865.2527174 [...]
+2425.48998550550, 1162.88354761136, -104.492243908430, 21495.6968252981, -14101.3449783331, -3802.00594531971, 12944.3485158743, 21472.7460783662, -5369.83507968369, -12910.2091407990, -8241.22805509338, -23265.3240657929, -20316.9060742267, 12021.5104018737, 11937.8975105571, -18173.3955560627, 9388.44439549129, -6617.11788242604, 110.746362169996, 6799.02823745768, 2281.11039672622, 9149.12112790632, 9320.62184447816, 11320.1501432851, 7590.24054479259, 6156.58114687928, 7515.992573453 [...]
+10674.0714064898, 5760.10143684904, -15663.8867099985, -1921.16607560429, -9438.8638434056, -2477.58218616578, 3873.35634211926, -7752.03225738223, -10522.5719046912, 8914.63508952633, 19061.7190629976, 316.451536772227, 8257.05773241432, -9229.36593509169, -22088.6135741997, 5130.13267628094, 3974.52530184618, -1688.81662595552, 1311.49126738086, -16685.7866421569, -15039.5335764955, -3294.61194270131, 3947.01886097163, -9720.59958660922, 4746.11916332359, 21762.7090863745, -988.4765197 [...]
+-2565.19001550127, -13261.2592251846, 8700.76772991753, -4571.66965926894, 1369.43492334715, -3878.66226773061, -7574.56867523474, -1506.94597894960, 17837.7729704086, 18575.8342596488, 567.161471979238, -25298.4776679347, -5709.21530663758, -14806.6810637124, -1277.98633704929, 9615.43204310722, 7584.25351595893, 1230.37550730790, -774.650363660277, -6900.53252477959, 10684.5318342696, 13135.0375410874, 8081.50669214785, -5449.60332043159, -9259.83589855919, 15966.3279169507, 14076.3256 [...]
+10196.0314009937, -8898.04682114432, 19025.0204890660, 7940.44130624832, 5607.33045947626, -7099.72567511075, -2900.24641252787, 6053.39952171336, 7169.71647378271, 1953.52408942354, -6336.59379278445, 5694.47983227527, -14585.0612951784, 6409.87150978037, -12124.7558621601, -3293.41767060395, -154.810663640441, 71.5229925427625, 1918.82559999776, -6701.48865949344, -7929.20902051895, 9254.23242231957, 6056.68236846967, -12353.6061290456, 7768.14464974386, 5425.43388086238, 9766.32079588 [...]
+10949.8429229117, -2396.16432324946, 27210.3809904124, -28057.5940035465, -2825.01323976845, 7322.68118049329, -10549.3093472129, -6983.77434509116, -16059.1404577776, 9224.9230388568, 1640.84384410889, 4857.88158997838, 4240.78256257165, -7464.33550848643, 13636.0165856291, -16266.5923895523, 8478.13070244601, 11333.7402405830, 4352.16650952925, 12734.5755864167, -2171.80475645111, 10295.3119044068, 16293.9876417271, 7116.030264964, -3108.9269829497, 8782.91923965064, 9639.8553159711, 6 [...]
+109.158070629466, -2107.52119921306, -7113.90934033375, 1966.16182754371, 9992.823816251, -4735.52004905122, -7749.11443893945, -4506.19117934257, -15420.1480782583, -5222.03477873836, 12816.0331204472, 4735.54567336608, 14903.4552749668, 2953.53420446301, -13208.4824467837, -6519.11310856831, 5134.00232384162, 3026.71487307786, 238.625382987668, -5644.79431050344, 24.3145829408181, 2323.17563220096, 2930.97145005626, 7616.6447965904, -1365.78119183399, -95.1645855559157, 9780.5667205462 [...]
+-7063.4447934917, 196.961752061669, -5177.91618688491, 2329.55269169794, 4547.20717031361, -1736.39157417151, -9947.78337489817, 12785.7466397902, 11169.2647119952, 2258.34741659556, -4031.97522216427, 8649.63133378039, -19686.0599720538, 1054.61708341076, -1097.40687462768, 6994.84455105894, -3386.27288637488, -9378.1486457617, 5799.47503030583, -3301.16227288821, 1946.56696003349, 20889.659493011, -10620.7184221152, -4234.34051486492, -10092.4527425444, 7391.50906768879, 8775.400031767 [...]
+-9002.10953428497, 10661.9802079986, 7945.14317498454, -4021.99829032496, 10803.0824872864, -8362.8120401127, 3077.67521372275, -8326.9252054609, -7336.53011938848, 516.709026606999, 8639.10737246303, -3742.9774665493, 29813.742889011, 9744.54814186262, -3432.15671847108, -3695.74376463804, 2690.02155734250, -2459.20830827909, 11877.1734355224, 14621.4409445602, 7598.49211948359, -5103.21690233801, -4632.87587533726, -228.110411152177, -3453.32038666917, -6567.94952023595, -2331.11231853 [...]
+8669.56995322013, 7644.04191479475, -1641.88290930545, -12891.8663123173, -11444.4132488099, 626.461569578959, 10671.2142595858, -26569.9977619368, 16458.9670126081, 7022.37097472234, 8547.1952186935, -3457.44560753437, -13031.4142642604, 549.030095610317, 2202.9854002612, -8224.0140187516, -3638.27005271545, 7578.48259513759, -1925.66996788294, -7172.68868335637, 10089.0506152414, -4703.92703101927, -1124.45974225583, 13878.3348449848, 2390.16817257152, -11595.6206315690, -301.374277995 [...]
+-2913.38932371686, 12549.7652839450, 22506.1949199864, -9764.55357837412, -53.2545922110452, -8910.77973019169, -1323.34038731347, -4157.30802801101, 448.926863786575, -239.162181123207, 14569.6963092937, -11129.8667479219, 10793.4327250277, 6136.79694178238, -5891.94207859998, 22930.6457447313, 3031.54177856101, -1677.49980501762, -5573.81601700699, 15407.4930705269, 5974.99545758167, -2912.19160929506, -4262.32639754174, -1713.05125422383, -21607.9245220906, -2160.19915148171, 3527.918 [...]
+-12831.7151562479, -13519.1333517336, 1428.28227524670, -8372.1102242076, 1585.73163325530, 6165.56743303437, -10430.5557834136, -4270.7574696616, 20649.5490658095, -7219.48799082929, 9627.14373330428, -12142.5491998218, -3318.72318142871, 30328.0848324111, 118.441762678348, 16834.2262243453, 4316.13776904786, 8173.72008097018, 4257.80219724575, -15401.0509223584, -6362.5945304216, -7815.77300820634, 16128.5287304259, -6056.21826716185, -3165.09144932686, -1975.61996520236, 10833.8455103 [...]
+-2085.74766183974, -17247.7549024286, -2489.77876501035, 4507.49148588159, -10835.2374776678, -2278.41080914685, -7959.61958619684, 7170.40364684678, 2588.7763572832, -18599.5158506405, -11058.9194292286, -5968.67317437607, -34194.8937845962, 12806.5436164776, -8346.36743638187, 587.510189351684, -79.085209259877, 13771.6645169077, 348.118680384586, -1027.49911146532, -2089.23401956089, 10153.7590477239, -5537.58236439405, 19893.5421584748, 13613.2690619705, 1804.10431899249, -9123.54229 [...]
+12387.5452081746, 7050.72125840015, -25035.9350196048, 15097.8439843944, -6771.63370122104, 6876.25115358761, 4251.62617086147, -2236.04183587291, 1522.46104055300, 7297.81000743417, 507.197816088339, 6157.07207834690, 1328.28751743508, 12446.9284944980, 4610.11353186031, 3874.83562024945, -4164.16605059662, -1208.01586935280, -2905.13279398796, 3680.71880820346, -20760.0642741799, -2146.14054575671, -8087.01156107439, 15513.9078995402, -1282.47334891023, 19911.3990488175, 1667.047689992 [...]
+-2442.32565548906, -203.867466176362, -2055.43198231052, 7547.0769143357, -6460.33775156172, -14459.4692658407, -10795.8262602574, 10723.6518376815, 7718.3431995057, -7228.2269463578, -396.146986625970, 11503.3123921793, 14675.9977422332, 9712.90239419195, -7860.80928659958, -8851.54192492327, -8425.0566410536, 633.774864362614, -9604.78743795083, -1286.67731568458, 20672.9824417495, -492.107561748886, 10286.3916135111, -4571.21188519596, 9867.06483438387, 3653.24389979396, -20654.135955 [...]
+-13447.35219745, 8024.85966240944, -382.114334679641, -2017.23330502661, -13688.0930573275, -16562.9025531048, 291.570009817476, 5477.10141416198, 6232.94853021141, 25928.2430553255, 14026.4839528790, -4193.18262082788, -3013.5458459154, -5966.35517167338, -12933.3915509055, 13329.3787600392, -2424.08303803965, 7849.82370920969, -2377.39653061327, -14174.8600940850, 5176.48985861938, 112.501694916654, 238.468310950035, 18219.7815613621, -112.188887953980, -10181.7494006764, -9866.2178095 [...]
+-3130.12898534532, -197.322206277600, 10540.5403658325, -5098.49841458618, 15534.5325013360, 5065.38763021425, 21712.0982563011, 7527.68613652738, 165.837634951389, 10273.4499236608, -1697.14195715129, 8086.01138184629, -3415.40803136351, 2315.23324362282, 20700.7145407958, -2560.99382580492, 8629.74634384568, 15991.1759188252, 1978.07457633750, 1413.46401284217, -12217.1279169464, -9768.7105936148, 3674.9767769203, 4041.85255529368, -14555.6164968519, -8268.42852924198, 2227.61979249865 [...]
+-9315.41653865422, 2978.25511083068, 776.214327448307, -8454.36645035867, -1349.57173261948, -2936.56752760481, -7517.04722256242, -10629.5512623172, 3555.59324503839, -2367.69465515093, 5981.79754603513, -14388.5550691709, 847.713812916792, 3968.46176095817, -13268.5240410631, 12817.8215907049, -1816.36174674680, 15081.5157417367, 13895.4246015707, 7266.41573878092, -95.6457200427825, 18335.6541660867, 9971.19201912296, 7087.0078075233, 4234.85517134019, 8538.37708767564, 13312.10676683 [...]
+1545.59362796503, -2501.08536633673, -629.050726651619, 12195.1654618427, -2957.28916141192, 2329.40228751513, 18148.5112909085, -5229.25747316034, 4874.75726339169, -20603.2420706122, 2089.93780395074, 2664.3601978619, -384.490468251234, -8403.66258982807, -1519.53356284903, -4631.58623643246, 3687.96990417825, 23188.8484718351, 2845.10551724746, 9572.83645950545, 2977.84364619106, 16205.0376775505, -3377.71049190028, 742.54645713726, -17607.5733657727, 10551.3013989663, -1469.654032923 [...]
+4477.4418126136, -5767.77137740026, -5863.83490751273, -6268.95985436986, -3326.34647213755, 9259.93954713854, 4088.32550598763, 7734.17108839672, -5598.04206415453, 7770.17479180414, 1148.60013616857, -8389.80307505774, 13316.9339225657, 7586.94489162534, -8758.7032005476, 11226.2030902167, -7227.96443155262, -5196.7454215116, 7199.72049430292, -1205.18149492851, -7682.26068961988, 12102.3131061525, 4212.2446746775, 4242.42119876933, 56.4511445763649, 866.135247345641, -5347.02305711973 [...]
+-5671.68766246735, 10038.5744224608, 21580.1581266926, -12499.0134314298, 5157.4050239008, 48.1650295559623, -14505.6347907595, 10550.2759822158, 11678.1529402056, 6862.54781790167, 25428.9165892279, 8770.1234459577, -1104.87170463159, 21863.7009929919, 16064.8182693574, 3307.55232307698, -13521.959675115, 8812.93834650029, 2375.56055965717, -3637.39440436660, 2420.10386529815, -6267.33377116594, 7104.16929364403, 6247.53380775472, -11131.7008578018, -12278.8015276050, 8323.45622090671,  [...]
+-9885.94912087402, 7782.96701456743, -1073.32206895808, 8965.6673783664, 7936.52809967925, 16169.3545857372, 13210.9108174464, 7066.50834386084, -1675.40308340551, 16948.6408173146, -4901.49554646747, 20331.6229537526, 8836.07493471278, -8448.75140886596, -20780.8361245190, -624.983123753693, -5237.62999959857, 4481.19562572349, -12055.3150230960, -766.398833808653, -4653.55058273162, 10077.8026013172, 3990.62499843441, 15222.5830100297, 5531.86398475785, 18897.2898765011, -4628.35016987 [...]
+-7800.90099208301, -9839.97155651597, -2.75729549482154, 11774.2714501113, 4231.35323021704, -17896.0377343725, -10733.9497639818, 6544.69959893612, -18031.5023027346, -10324.1303855103, -6277.90918549614, 4078.21468220085, 22671.7913174547, 16189.3542868864, -2245.93667992464, 6210.14229337004, -4332.59784152505, 2140.53729412870, 861.938158059713, 7750.51420021702, -7432.46258569634, -6960.88229176467, -19129.9065810868, 8138.5827922932, 11001.8769483818, -4684.78268468618, 19593.33881 [...]
+-5611.69592845346, -19128.1626760864, 4463.64430459439, 13189.7828426978, 11789.4746909593, 17073.5148625117, -1211.18784352156, -475.784388151389, -3384.26582087348, 8132.38059538122, -11853.9327868659, 15898.6498492209, -10050.2177720813, 1242.76753931694, 10345.2644975921, 956.763167294987, -5260.78494557756, -6814.96869728437, 4538.17146645736, 1533.31148281122, 19303.5497367415, 235.957339074916, 2158.56142680181, -7668.95903911795, 758.584707638495, -8465.0097128862, -141.034570148 [...]
+-9779.3317063347, 2008.40836739916, 5573.96923562128, 512.655921590165, -7940.52637124692, -16819.5174154575, -411.389192605711, -786.241025703558, 3804.47451339120, -3371.82508440681, -7870.82971847064, 618.363906813676, -9018.09270367397, -11759.8725850016, -2020.22485243550, 6019.35498445376, 5659.84200027111, 4713.0376464652, 3393.59856358202, -7360.0170011479, 6982.96913136018, 10838.2126127717, 10655.1871518298, -8962.21046667263, 18010.8637967752, -496.013437520625, 15718.53289160 [...]
+6794.03663636476, -7035.38050926003, -11295.241240914, 12214.8863157983, -12274.4299096250, -6938.69258513069, -8774.71854059755, 301.282634278592, -3976.19833048644, -2672.32119501775, -1641.40676699050, -804.937333941411, 5414.03356788722, -15240.4809925726, -12179.5779799734, 21223.9350579182, -7066.14229188379, 10343.4378747144, -5640.47927599453, 13778.1661046324, -15392.7054525916, 7377.2401688114, -22130.4918771662, 1597.10550289045, -8754.67193631084, 13431.7141625732, -16591.702 [...]
+1265.52627855814, 8063.26014398539, -4114.10202009830, -33164.3990590776, -2628.40189335035, 246.376547769553, 6416.95741740703, -5661.43913557843, -8902.3540327523, -20709.6006607205, -1694.42043651582, 26026.7978012614, -2330.16585591949, -15147.559137735, -4969.77947372743, -5499.13252276214, -9115.59793522747, 12114.5859741663, 3692.38396818776, 14963.5364781765, -2698.49952531035, 3007.59143853423, -3059.49048228616, -6707.66064317197, -12025.1665701589, 11806.8876527712, 409.916081 [...]
+-11408.7685815904, 27999.356104154, 16731.2054753551, 7745.13846861184, -396.95143302896, 4754.48470366589, -4215.53533472867, 8891.74444365771, 22691.0092374772, -5030.4782173222, 8278.59750988968, -852.897452739374, 5446.31602138944, 4249.39523687109, -13439.9277920388, 808.04089989191, 17329.2657859129, -1087.26585525071, 20837.6465731828, 204.668762152761, 26495.7652952399, -1743.72332609555, 9647.83568066238, -6642.73901814003, -5549.63473849589, 2116.49645125837, -8346.30148849478, [...]
+-4302.0010119451, -10681.6118356499, -889.225034365354, 4532.04012067032, 11149.6982232967, 17969.1819846862, -2538.51794950217, 23170.3277375511, 11181.4999209836, 1195.03570465064, -61.771484842306, -673.149836696675, 3496.44139321198, -7975.89350563625, 6119.9760400138, -3035.24621215398, 4363.22653754487, 14167.0262359834, -9343.38316829022, 4613.45479051501, 688.912626983758, 5150.97326053036, 5213.27111512637, 376.565960505087, 1443.41309795410, -15008.2223128809, -11769.0577708278 [...]
+-18766.9188519239, -4604.58449307958, -6091.21928915816, 5316.88319148622, 8564.10720724335, -3392.12795038102, 5975.2231951855, -5559.94949216556, -1999.66860832695, -10465.7893060539, -6411.65102214525, 14262.7881028313, 9216.4215597795, -2774.25239451078, 5790.97644124266, 11758.2659936023, -254.026834075590, 7736.73593091587, -10982.1867076533, 30097.4851581664, 369.363303184757, -4756.78096398567, 8249.65129341691, 10334.7244612797, 5061.68876215244, 590.541660094472, 13363.93901956 [...]
+6034.72841290003, 2316.79761073883, -7047.916117107, -37989.2989052099, -4804.31509610550, -10452.8816122773, -6156.38706984764, -11590.3587964680, 540.463030840135, 3718.64463801894, -4550.07376786488, 7402.84107615405, 7174.9773106987, -8553.66618825308, 9524.73994107178, 3761.99726671603, -10284.2739517927, 2151.57234784344, -4131.8475574608, 2048.80375763726, -6126.67160844265, 9147.83024598308, -3602.28132548577, -28836.6897706493, -11105.8889252908, -24078.8465178218, 19406.2601725 [...]
+8827.4822838157, -16425.6854148661, -5227.7628449633, -4749.4614542615, 6748.94731863546, -9365.61655138856, -1738.08767967217, 9942.29583036944, -14941.2606503999, -513.967529332704, 2093.13450168344, 5086.40537899379, 6186.03147882943, -4931.80810092079, -6530.28372847162, -1544.18670857629, 2955.70625331497, -5703.74111457791, 3041.92697499096, 3142.56083887397, 3096.40439715485, -5391.1196703151, 21150.4164040128, 14269.0895455319, -13495.4698427794, 410.725765374865, 6582.6154326200 [...]
+-9212.84719167587, 7156.60795314315, -12820.6850940063, 9981.1822617701, 6359.90624125945, 22149.3630471576, 20241.7814103306, -796.088003129114, -9221.60391209339, 19201.2438304663, 617.439057293676, -4642.25370149597, -10328.0378154080, 18279.9790906375, -5458.61452020104, -1525.85990847765, -8763.45068951976, 8087.98664219347, -10535.3642005954, -13877.4577925593, 13538.4249727198, 946.262669041178, -8900.76759825792, -5603.44562639721, 22576.8738953135, 1385.87945866099, 1913.4613441 [...]
+5301.05355173145, -14291.3036027507, 8771.26502507915, 9846.76419824307, -8714.08738909775, -13132.3639462343, -6279.30001663217, -7891.53517025628, -25511.0718020988, 8323.42553768701, 15257.7471022972, 5968.80158180607, -662.759619601669, 32.0182521604868, 12925.9613460773, -12917.0315673811, 9046.82660125737, 13591.9348602065, 7679.04564175348, -3328.37021541969, 7228.80686460625, 537.699353050719, -1083.59737729713, 4619.88189636535, -7086.30714202663, 22137.0465670713, 1700.13323082 [...]
+16349.0792509933, -18100.5120960789, -9070.63292810226, -5018.4612952625, 7831.05165663574, -16227.7849788739, 115.126675288793, 7813.57891955265, -315.262708817918, 1316.10517832221, 8951.63518116519, 8643.81596277412, -8570.98651944058, -3498.43497142417, 17914.0602068864, -7455.59136920364, -9983.02846215275, -10874.8062071325, -13423.2231207862, -12790.0444927056, 2435.14539745552, -5342.02616455564, -6582.08773428207, 7136.23792556649, -18298.0069889866, -3935.26534917865, 18111.723 [...]
+-5255.6644081602, -4413.12648709787, -2702.18756384631, 9586.5158236629, -823.527570974105, -13527.9162626994, 35232.0152333148, 8887.29423851571, -7005.79075459078, 8599.97777754215, 9820.46393782017, 10533.3504154164, 745.011857770013, -2023.75595606565, -9619.35585944275, -2920.07585833, -5919.6633512019, 16415.5900432499, 1989.87685377918, 11762.6021753714, 10552.6135670794, -752.287818004357, -585.955224131233, 22239.6163979278, 2839.68423491802, 15544.4422479349, -838.040231251854, [...]
+-4612.70135700898, -16405.9789783919, 3294.92053596994, -14410.0002849538, -51.1257156514856, 4894.7046194098, 7299.22143839295, -7736.49499416443, 22894.3729246022, 2389.63142131993, 6477.80258230937, -2755.74171472701, 12116.3603645271, 1792.1989798633, 1923.36202320568, 11308.9113761202, 31149.9880232457, -243.55480481479, 4742.80410904793, -12117.1298579574, 10340.1871068026, -10501.3546353673, -5329.30609640272, -10944.8814692874, -12606.7116335019, 6163.31352677798, -13425.90062371 [...]
+-9552.6333983836, -5189.61823474578, -2539.47685167086, -2621.16566222867, 3070.58945141714, -671.227326544142, 10210.9697211164, 8928.83944920807, 7396.43550687057, 7664.04098640413, -3114.05136354663, 12572.6810903272, -2722.39615365845, 6873.86824283881, -865.494023769954, 10254.6066594896, -7178.58717782391, -24076.4533381928, -15248.1988677862, 5006.23552811204, 376.08684033905, 14953.8608888777, -7524.98472038604, 17694.7754366313, 5692.64776629816, 11709.1304186302, 6802.134726352 [...]
+-1607.97346820958, 6769.13911035515, 7870.79559199822, 26947.5920561258, -858.444367291994, -385.383052436727, 25418.0366148541, 9911.87598161062, -5996.08927075194, -26974.5801113629, 14135.4925180713, 7105.48583045775, -4612.76915166426, 13291.4274881590, 4703.0664111982, 7198.09426127101, 2061.51410802578, 5512.95812916199, 2862.48851445426, 11170.6707058098, -6235.32743710264, -1802.31935880995, -5150.69382126216, 19017.0518067618, -16709.8724090506, 15925.2445078239, -1020.940257468 [...]
+-1636.08854375190, -22691.517198717, -4736.64971210486, -2579.34728052321, -1299.79107901117, 12727.4408089883, -34825.6050099879, -23811.7614515077, -5122.26760396786, -20611.8823580445, 9035.51701660802, 775.608162482182, 4578.89795807052, 1894.49873176562, 23316.7592652255, 9897.45462904152, 8791.95649078421, 13095.3867845763, -5222.50664428409, -1404.06853111644, 4859.9865130864, 11468.0101439005, 6557.36272491475, -807.222215075099, -10508.1024789262, 8551.61601291513, 15958.3887861 [...]
+-8035.40838881383, 2683.69259209128, -9219.23847254757, 5169.4523051451, 25616.9309571363, -5000.88076570882, 10365.3565960801, 664.255369643015, -5548.48573128732, 6926.0560308671, -15101.2910573014, 9047.06217395669, 13285.8679133936, -1034.9223014923, -5803.30061784339, 751.306129468862, 11710.3396148851, -5732.12362831895, 13875.2144079112, 4762.30243503036, -19595.2259352194, 1241.78404778539, 12585.1042714290, -2382.95230175285, -5332.57351475824, 8507.53713766445, -129.61266591901 [...]
+-855.749489374325, -19374.8155187284, 2744.21702553333, -1367.56740853584, 1489.07687178706, -1073.58404774239, -9933.14403117988, -11345.4797973177, -4560.02077935569, -4344.01032455009, -1399.93727373995, -7911.84254082801, -6044.28745887796, -21857.0922347260, 5537.80969115866, 3074.01304709532, -6722.00940940413, -1707.43389533728, -17087.816508661, 21893.9580675318, -4221.97514496524, 9148.01905719875, 15254.5330861796, -2877.95211172189, 20115.4481234994, -1311.10377162862, 7899.57 [...]
+2988.38957965375, 22885.9985947395, -8923.71731514487, -3477.39918253933, -7901.31975031193, 8002.2509736429, -1612.94784239171, -1614.76694623827, 1055.29204736980, 2818.34666003519, 11457.5677254743, -6312.99519943816, 5242.93289357429, 4719.49608474845, -11549.2374604345, 7027.65785961833, 4038.93581232342, -2842.60278962813, -1833.67122782710, -17598.7793948648, -2470.24689438729, -1.62187925221922, -4874.29397419347, -11846.5914859404, -14175.8056368229, -16128.055536915, 104.332593 [...]
+-8734.52141966386, -4830.40656580988, -8428.24553197386, 12602.7195418764, -571.785452964738, 856.791840933147, -583.822672479818, 5117.41594948652, -216.33693962473, -6670.26786827084, 9249.6120096095, 20441.8467160843, 3043.5528251734, 19948.4213159302, -1705.07590499233, 5135.09650529435, 3863.99269631781, -7898.52319354128, 8272.15359418012, 3909.1797776364, -52.5723194035627, 21210.2454382937, 8385.6047430455, 6229.36449802626, -4400.52473054307, 3700.92230679526, 10859.3134109061,  [...]
+-2836.05866176990, 4650.75291327766, 12792.9871196117, 4947.68489183709, 3495.81886210792, 9511.8115605371, 6900.19083873114, -5236.46606946697, -9523.74961496096, 10209.2688034658, -4895.60449671665, -1135.56659544823, 1085.22463400524, 10418.4394680570, 13384.4484527840, 12996.3018307969, -11945.7081723644, 14272.0911053690, 15697.7920243509, 11893.8624112518, 17109.5504989813, 9902.86896583283, 4173.33648354786, -5607.68742065417, -10353.4083504936, -10754.6714780306, 5570.22527557725 [...]
+-3060.14175312358, -14583.3212334870, -7614.56744758742, -16550.9967912172, 1699.60045199702, -3837.45722293232, -10719.4918139016, 6773.49349913278, -16963.219056541, 4469.44986654427, -8759.88266610519, 5579.69417983466, 15623.2562876431, -12690.4087028763, -999.868678107922, 433.138222557713, -17675.5968492228, -8762.54503605433, -3280.39765415735, 27511.5941838581, -2730.48336372343, 329.589253398082, -22735.2224419083, 2106.30826594522, -4136.00605071016, 1802.47628040596, -1619.630 [...]
+10729.6623485978, -12987.5212361279, 3279.28213448351, 4549.57011848173, 17140.2773648833, -16684.7376233243, 18.7867692973107, -18781.5956183010, -6583.66009659724, 2001.70179091124, 4349.93671597229, -12018.6349573239, -7598.4260651511, 2730.30387686014, -13304.7385248128, -9031.47248570482, -2433.87580217038, 4830.35977769471, 11404.7506582927, -162.104758852440, -2561.01861321413, 741.58175521005, 3687.89157608699, -13170.9820816390, 83.9720666295322, -9999.27067153434, 8743.56498178 [...]
+-15692.6462251928, -1934.85131995539, -1098.08626639216, 6114.06229448589, 17447.2813070041, 16059.3694454289, -8742.31805149761, -1119.81028250766, -5358.0829417448, 7269.11324837024, -19192.8555355785, 6829.06105159568, 10031.18825336, -4595.62751931233, -9546.49119971435, 14764.1846191734, 2601.15997484365, 8984.71174339525, 11603.5734018253, -2444.25876181465, 9607.46389324381, -9193.08176255206, -11569.1222450902, -8737.2904530646, 5290.28503370211, -9859.87560592685, -10526.3193235 [...]
+-2164.53703560963, -4520.06858481383, 7766.96589902138, -7024.29345478144, -10298.9942393160, -3414.66461995467, -1152.55702623315, 2204.72684026491, 4626.49761554563, 1354.23363496441, -9127.48582063619, -6912.57888063208, 2997.81141514392, 2453.23880915525, -4139.00129177299, -14278.3095794621, 7108.74807549259, 3090.12149756611, -3189.96746425357, -3564.93840923305, 8449.7941455959, -20304.5922384314, 8501.95007366118, 7931.50660541806, 9829.93493659768, 1286.58181691515, 17477.630048 [...]
+11670.5224051984, 17522.9039688372, 2970.31782915696, 4311.23421301565, 4625.72225745965, 28919.390924203, -9390.804492311, -2394.75220668082, 4702.0610841438, 14176.3549413696, 5082.32322740305, 9462.72662224375, -300.853455871366, -1610.23143104681, -4250.90515080929, 15103.2570428081, -13514.3727263336, 1782.02586642601, 12929.2241813680, 1895.97679880113, -4451.5632288028, 8199.68337398487, -174.417626561373, -2240.88042580837, 5041.99006812869, 4991.95245470287, 20781.0552662553, 12 [...]
+-16037.0165715002, 22647.4977911977, -17458.1678650596, 2869.26064148480, -14290.134445445, -6037.88058171664, -199.213659987941, 6324.5783166492, -4506.22705037199, 9278.47593103552, 13095.2806815627, -13414.8727728988, -9087.4955942347, 14644.0291572882, 4754.35221300946, 13384.8291251883, -9485.22319214574, -17836.0890982380, -4868.12449493836, -3214.84363411287, 1801.61262980165, 20480.9934563993, 7338.72501623246, -9361.24355669626, 4720.364538223, 13148.5033915497, -10001.153197200 [...]
+-5073.11956203037, -3571.2751952161, -1381.17168378862, -2544.81575115968, 11912.1517941550, -381.465732023515, -5504.49783316028, 291.513358274848, -20758.1605236821, -14066.9365610576, -561.938246086188, -1917.81266932953, 10578.9806204122, -3815.49424884424, -3058.90996678897, 3189.21741041249, 3983.43103839494, 2130.62143341761, 22878.4765608088, 1253.35553969038, 11355.8270711474, 2471.99104859939, -9791.59014648321, -9852.3263277164, -12222.6582305134, -9285.8036418335, 6314.250955 [...]
+-2072.23647355611, 7486.8116968775, -4985.24721127904, 12031.2975400687, 1365.35134557367, 4404.83788039983, 13521.6291201288, -367.431825093390, -791.006341356576, 8737.58940518427, -3561.58838860303, 13912.3284819601, -21105.6425056166, 157.634374338767, -2656.71074549258, -19356.8985938627, 12583.3105557730, 7268.16472613399, 9439.2750740313, -10805.9939406757, -10388.1542107404, -5213.1407434969, -18026.0664686237, -12164.6614921996, -11023.5170919143, 11694.6864484882, -5386.9882692 [...]
+-2394.08071186279, 22712.0182093148, -9813.79452677036, 8038.62714217936, 10970.348268569, 2614.46358873825, 27891.3197532084, 2899.71318298064, 19364.5864018224, 319.326845547206, -8453.49824569913, -16259.8866779573, 4924.97876075047, 19354.5060579898, -11947.2407026763, -6309.93847448599, -8645.72823686097, -7165.04444718733, 291.121280543626, 4510.97791667499, 6829.10131199231, -7361.76468399654, 10084.7066896303, -2296.41180903364, 13524.8641793294, 2832.03629771028, 5617.5014912158 [...]
+12659.5193463535, -11195.7242271515, 5730.73318452286, -8289.97601825164, 3182.27301275295, -11959.4568503320, 13191.3012824872, -15030.1896366367, 2256.95137572665, 16971.9678820203, -33.0916132957881, 2609.06631569995, -6965.53050511227, -2257.38501606112, 3144.48848536432, -7352.94061475717, -10265.0442175475, 3218.92563141618, 887.406877362388, -7204.06600724905, 6091.53776036982, 235.917903187270, 6441.60047106612, -11216.9273671414, -6955.00233607589, -5603.35259100235, 2113.846028 [...]
+-273.666678295051, 2539.10237804002, 986.286365817154, -2420.87579712271, 1152.05483430005, 10219.4614686736, -1211.05295943437, 2221.13535840777, 14080.9160138080, 11239.7273147739, -10328.6900013935, 10778.8523149925, 724.612151191538, -2193.769031644, 10065.8906517957, 2834.26947804794, 1380.09464100612, 6962.2995562719, 9297.86700445735, 844.5670966131, -4272.23548407012, -26631.7282507545, 6540.10433247445, -3196.48421938351, -4583.21967442548, 8889.15751753863, -3751.4493782939, 10 [...]
+16591.8726661247, 12106.6218600834, 17002.8396550204, -4890.04995012323, -9878.81094110647, 6443.59138010591, 17979.7442223165, -8611.59276680547, 1034.98680400807, 10289.0205770746, -3391.79852456332, 373.608108116632, 6478.4765294961, -378.926779475960, -8090.87174169482, 5334.60475485995, 2689.10392142362, -13333.2412958002, 2725.22520858357, 7395.79282356337, 1105.73920837734, 7794.88250559451, -4268.63839183477, -1377.44331144097, -3989.84566227711, -731.334371548662, 2673.234407525 [...]
+-15026.9111685909, -25896.9022915274, 5462.1199724746, 10102.7602510160, 2448.91038289818, -5963.99012460175, -14759.3329071954, 2607.67647776510, -13031.0236054243, 6856.25240027918, -488.041379533825, -3071.86589524432, 1821.83501705039, 3767.85911742461, -5022.66627933055, -8565.50921180016, 11405.007117341, -17914.0950709982, -3114.70124010307, 10363.9992245296, -1522.26006821799, 7800.47648206893, -10785.3954840138, -2652.90965363909, 3900.03466871117, 18803.3581335573, 18560.431527 [...]
+-13940.3948209049, 11866.6578034402, 808.375520326549, -13262.3446300431, 6959.38428397087, 1123.18155641589, 9091.04571112424, 2526.2039162713, 55.224590546852, -740.478591598972, -7217.87947548247, 264.093179793896, 10463.3468356352, 13396.0226421759, -3500.21976350510, -5353.04664398156, -5268.85827935105, -5841.48465100062, 12798.9611830604, 9447.21881984663, 22236.9036717047, -9828.27006980897, -18331.6802086690, 7287.71780950757, 10669.2803661447, -732.756586007097, 2505.0007827312 [...]
+-9148.73216319544, 4758.43593595417, -6314.84157668722, 2713.06174663834, 7361.38761947534, 4773.69620753602, -353.611781439103, 2589.02639430817, -3269.043830128, -5998.40656629768, 3304.60883524052, -9466.01512890421, -12079.4267498895, 2616.72620547515, 10151.1894349826, 7273.60801504356, 20379.9639320816, 2389.71798775441, -3647.42572370422, 1603.62857302359, -8875.28899402213, 4623.67246751448, -2316.18145262698, 5940.75727606947, 19040.8478244364, 10851.1868858197, 3602.58077728738 [...]
+-8603.26156524478, -10399.1678008978, 5747.89868799563, 15520.1436795448, -2133.28181699551, 18362.4983131202, 7671.97199430268, 11799.4791734726, -9664.74014420226, 24525.2505069173, 6339.51012078354, -8495.42014204229, 2123.66862204365, 16902.5697031911, 20422.3443443357, -5329.04194344099, 13870.8807747853, 8196.09440937493, 5518.36510340062, 1611.88050278580, 7606.21546805777, 5368.38818765449, 8144.93764392613, 6730.00862079449, 15466.3642978762, -2411.68725475209, 6866.08019250759, [...]
+1290.51121731138, 6619.28589679752, 7520.4075638618, -7183.456622467, 3729.76266379620, 5624.78449834426, -383.237971708841, 7022.58502567824, -5303.9806371206, -11209.4509560025, 8587.90229722038, -916.401070624848, 4531.98502007854, -7815.39911190329, -12440.5630011079, -2238.38671856331, 20779.9653863308, 6832.06502395768, 6543.94580653477, -4603.96648322455, 1907.34194601614, -13297.7388517664, 1725.12134530600, -4166.27779022667, -12891.4341197804, -7274.91291442802, 23908.829832572 [...]
+-52.1684110417705, 12828.2125754984, -2374.02979253494, 19366.3534996762, 4200.57851871169, 476.905874708422, 22302.0852766119, 3981.81037340909, 14083.0161812617, -1542.00012377270, -1508.29159165300, 1092.59942979785, -15891.8270729586, -17584.4911416317, 9276.02004571241, 14522.7408877679, 3859.69400068781, -2552.21059829005, 1446.42567577133, 11327.5656834108, 6176.99578746933, 3223.47916856605, 8623.80262084374, 16482.2180193923, 552.270103807043, 8257.18284590379, 17923.7416762605, [...]
+777.319523654302, -8631.4300861957, 15876.9290688566, -2492.60341951242, -7800.19752754268, -2024.19954987122, -10060.1337582941, -5561.36695804041, -6794.93690631428, -2743.1555795256, 1782.56797048955, 7500.50770413534, -9445.22953685416, 4194.76076999073, 11040.5864058876, 10618.6475708131, 24625.6124539066, 503.321581438504, -360.176564048244, -946.714818931495, 19706.2854338389, -19837.8986440515, 9613.90438495015, -10892.0399238987, -6234.05979237751, 5534.1394101075, 2425.72698073 [...]
+-973.803957241633, 2045.13398136791, -11649.7283131395, -1157.35681939181, -409.571367118644, -11030.5763734245, -14092.6417006302, -998.931754658926, 8987.39006358989, -8712.17760770672, -5272.79000146072, -1981.16797494682, -16789.7413695804, -12205.1336493362, 6311.91377200872, 7090.86368526065, 12395.1455038949, 18671.0929611219, 7868.23971680303, -9561.24112423333, -4925.7294698212, 22598.3829250140, -8713.7052362614, -3615.46522505750, 9136.03222909299, -4535.67427989814, -6412.605 [...]
+4803.85285050481, -6012.2225488932, -1158.03001837690, 13754.6249208724, 3401.12308423877, 3317.82623308234, 2200.37513815232, 5191.06650387624, 296.719287584538, -6622.06820128821, -1294.42094037173, -11446.6453291647, 14121.1576033597, 4138.55557051021, -14266.4361859651, -10091.1754385123, -7787.31095493098, -9002.39137716517, -9053.46918231492, -10706.0640997052, -5730.98688538881, 27821.9485761261, -11250.1859108644, 9880.23272435608, 7007.26525635458, 10841.7430171858, -2885.544769 [...]
+-9710.57472918359, 13054.0026845822, 10877.4989525590, -2569.41457572719, 8496.23285561757, -4603.70671256616, 3698.7345433762, -12873.1612082607, -2127.95066190137, -20602.5140773213, 910.567741884156, -21731.0960738948, -1374.04173169453, 45.9106088899978, 3690.00952873706, 742.422219299969, -959.1975729436, -11361.8807302684, 10871.2402747162, -7400.01945162022, -765.196432181431, -16182.897818213, -3417.26320364317, 3720.55973697797, -1828.00199758205, 13837.0732080401, 13447.4500622 [...]
+5882.47584516102, 10224.5224436072, 6468.2837687111, 4705.4214294513, 12921.0638408154, 3944.54888607733, 4665.75176485909, 11162.4649534624, -12107.4460958196, 5022.29285918764, 2433.71396107191, -3943.44195325962, 18699.8400423226, 5177.35815567491, -6471.46496358827, 15975.8382850453, -22481.1647097693, -4570.47961778909, -4662.60734723846, 5323.75677639707, 15625.3480428196, -12196.5995174314, 12533.5938412337, 10227.4417044284, 15782.6681675491, 12162.9429691789, 912.987157584264, 1 [...]
+-12696.7747422626, 2754.78879873711, -2396.15547072708, 3516.38861503855, 7876.27858697457, 20723.2005984878, 4756.319197426, 685.707638769685, 5474.33660806608, 14249.4353122886, -1724.39161035054, -13498.6100190331, -22497.5362912237, 981.499226913224, -3211.80741226415, -18323.5443013189, -8043.15101424013, 4340.56795551699, -5895.15984325448, -2941.32476115194, -27122.5605492420, -28738.4995700057, -6120.50468444733, 10171.5394573878, 12990.8914049681, -8969.44640321068, -10577.28742 [...]
+-1038.87254144986, 17097.5421399326, -12058.5195739633, 5159.93957030051, -4096.9995533392, 2943.38008464613, 312.804074320308, 20193.1824377174, 3895.25712723222, -6832.68571772326, -21312.9841185802, 17543.5127336258, -6703.32850011296, 5222.36987045485, -4475.10280390537, -5596.94927756477, -17402.2611658310, -8521.09512727713, -10941.3055715402, -8747.46585605308, -7572.06331706321, -599.134915193339, 3517.32913463769, -6912.65343683, -22857.3247717502, -52.7565933458586, 12757.60141 [...]
+2255.76225180746, 12722.8498578645, 3037.57905969959, 3789.44659724683, -5301.15006135348, 4093.97222918831, 2442.14878692831, 2244.49132458642, 14024.6133534886, 1676.23835335235, 1814.80712657461, 4056.95233704527, -6417.13421510377, -23745.5414241696, 5936.8923973984, -5249.57607844147, -3631.20801006454, -14063.6829650665, 8207.94987412606, -8625.79873004029, -906.628803273345, -4591.4939160686, 22557.967743722, 17366.6017358923, -3204.29804245705, 15482.0858325215, -9537.15396262799 [...]
+-11271.672218515, 2578.63299788930, 10178.3946297550, -926.133055844793, -5908.73066129432, 4801.13423568333, 10528.6443051433, 2343.05359459478, -2277.06305905124, -10709.4426622539, -10655.2302279569, -8743.7435272931, 98.0274553797786, -20635.9609052933, -15895.0857359200, -17187.0605797706, -16434.1244506940, 9040.39430414753, 13391.3380400144, 14633.2370902020, -14312.4348659063, -2371.26602588233, 13886.3099160094, 2393.2934454826, 5665.2316088075, 2722.51226751274, -151.4625998800 [...]
+14959.4393015863, 630.889971688252, 5880.21670189532, -10185.4119505574, 3656.7536967166, -13340.1927932908, -5637.83940351393, -6901.08208414992, 42.3993931657299, -14286.5171768804, -8093.1478849664, 153.529109158377, 1036.87344692701, -11396.8561264727, 19397.8469285699, 19622.1808851546, -7611.09226468991, 12300.8104593963, -16869.3564056950, -22204.2069930354, 11824.0066544611, 8371.15910226424, 17025.5204558855, 1803.21047657159, -14291.9785417756, 14745.9789478419, -15709.69808309 [...]
+5584.8219794869, -3265.41962520230, 16683.9986747092, -7924.97441188703, -1537.02678042716, -661.75999401973, -941.310103933346, -282.223349914775, 6509.46358410985, -5234.45723750046, -14984.9298177948, -3506.3632357713, 3792.97085471936, -3476.18072082632, 6820.22386213081, -3463.97377473148, -7401.70612864509, 12696.2999197451, 6892.42034596008, 5276.09475197048, -13167.7348405268, 4152.42818760287, -8505.6502598193, 3784.94624381986, 1450.49055322329, -1516.10944759094, -2354.7594107 [...]
+7639.25300369941, 11082.9895997427, 9722.27950489097, -1989.95868011071, -3537.81058810721, -26330.5326780899, 14205.6552734366, 15232.2137351744, 5987.32771836515, 2202.18706644821, -2259.43408853203, -12292.7767779437, -1932.57366194357, 5035.53284071857, -807.608770449909, -5454.19309494988, -5659.9963704937, -7636.33248116977, 18004.5786251105, 6708.33757517219, 12502.4825568072, -8263.16761376066, 5449.08131641522, 4943.76014343299, -5673.17057521206, -2421.86039479294, 18739.821631 [...]
+
+double y18[100] = {
+-7305146.02927567, -53758820.2907183, -54841321.7660888, -164868135.030098, 79362570.1928163, -40957172.5416158, -142825754.353980, -154476189.361748, 214333212.800876, 16709052.2666138, -84856238.6621234, -89035387.0716148, 52658705.553907, -178981242.070492, -91538934.3537773, 85546899.720765, -36099073.0225770, 130459142.608129, 38378328.4577875, 76077644.68289, -51415589.3726605, 39663853.1926259, -11264969.5513084, -1607754.89587789, -2809612.23852104, 69298512.586714, -92578557.054 [...]
+
+double lars18[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -47.43619003820982300, -62.99153879360179800, -84.34409666043389100, -85.48795770462832900, -135.86762738428317000, -219.95843704763860000, -244.22842526753416000, -277.96292864879558000, -280.17195758182726000, -375.29952985955697000, -420.63089425423942000, -431.78352080669828000, -450.12182912353143 [...]
+0.00000000000000000, -536.86729585198441000, -593.87973150640255000, -1031.80497958327760000, -1051.86299679329520000, -1440.47597582744670000, -1619.62716919730840000, -1717.76092324874820000, -1780.22183163131470000, -1845.51617685307590000, -1871.28654402795430000, -1902.47653017590760000, -1903.92830168858700000, -1967.53824996873120000, -2080.11702150659950000, -2112.23004997428050000, -2150.35238261982790000, -2152.69194179843500000, -2254.24830455100250000, -2322.66081335114770000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -34.13360118072711200, -59.618 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 20.77196068325443800, 48.92589370511262100, 50.62983916988690700, 127.85017097667235000, 183.06008796680936000, 195.36938106843638000, 212.89699435733689000, 234.562423397835370 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 160.69193221028078000, 265.52481851524396000, 329.17459479641315000, 400.25313213479848000, 426.55778716929933000, 458.02522889541115000, 459.21555658720092000, 506.66815304265873000, 588.72740113624843000, 611.20219303202168000, 648.66719400731199000, 650.92449549926050000, 733.73723183286290000, 788.55743928692334000, 801.60202603463688000, 820.65902000275469000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 29.79990734921014100, 64.46933366061385600, 66.07481177207238000, 126.17482692242437000, 234.58250448834769000, 263.48716553916955000, 307.96473986430857000, 310.77042903366885000, 429.50947221452662000, 505.80496937788860000, 522.18247014948986000, 536.23239677430445000, 552.56063 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 11.18181429192054000, 28.05146581111338500, 48.64858592879256300, 57.340 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -120.20251612152529000, -212.24401449799811000, -317.13326845225890000, -355.74258396878315000, -402.71462130790042000, -404.49617423747253000, -472.59517879112315000, -587.11949366476233000, -616.20957520372906000, -653.13627796041692000, -655.41270008030642000, -728.41692595264476000, -781.68888386711683000, -794.24804357236451000, -813.0766 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -280.13198346379215000, -388.88028955650037000, -442.13535687951224000, -468.22981368336599000, -487.44899920097680000, -496.45715632808532000, -505.93633763592459000, -506.37427797606193000, -512.66545050890352000, -526.70805733150894000, -526.27410220336367000, -528.74685333591594000, -528.85503301963934000, -536.50557506130144000, -541.92776935314350000, -543.02087278096815000, -54 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -76.97381667975561500, -96.49508345112911900, -116.09880097222150000, -143.85277687694793000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -58.72582310623012300, -62.42065872216424800, -214.24992264384286000, -319.03990705298224000, -343.88034254350589000, -373.26639190264729000, -413.475362248 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-156.84343779135173000, -579.81819636064347000, -629.63026136553208000, -1038.49019625093750000, -1056.54873597149000000, -1399.19787226393030000, -1575.54620031742230000, -1668.11371743455020000, -1733.40710154982140000, -1799.13734100258170000, -1821.31394414958800000, -1845.00886539943990000, -1846.04714761836320000, -1869.68768934506560000, -1911.82201552560880000, -1924.81905624994170000, -1949.03217064940920000, -1950.63344281029300000, -2014.97808657780500000, -2062.44808847827610 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -69.75916652345638600, -183.15193262488629000, -210.86447199982015000, -256.01649436793423000, -258.89995868979480000, -368.13067026267248000, -436.88691141074565000, -454.61432277200043000, -479.58260466082686000, -516 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -366.86974122437795000, -386.52677741321617000, -736.33653424164913000, -917.09533749283764000, -999.00802630596945000, -1047.19108389042840000, -1107.24850115074360000, -1129.53437317395830000, -1162.95685085979450000, -1164.35033242481810000, -1217.64773618668230000, -1309.32239776832190000, -1334.48984378111530000, -1371.16757735887270000, -1373.47329952457150000, -1460.69349920079710000, -1523.98004090722430000, -1535.939 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 32.70538664649377100, 70.97358829040305700, 91.7914 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -70.46659775033703000, -115.35402246429925000, -124.82706999738565000, -133.28233821710751000, -137.43853242966384 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -16.84460540512385800, -337.84498038338887000, -474.85274514744361000, -532.08835476397462000, -576.13481109304814000, -622.91220998106223000, -647.62333066955046000, -677.70689389081042000, -679.17885571349404000, -739.07625240217749000, -846.89767970995024000, -873.31175695449633000, -906.68122510326157000, -908.73478971031238000, -980.87952168977995000, -1026.31830434022640000, -1036.63140537506930000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -86.55456543294197000, -188.60440575627649000, -225.66316783023680000, -268.85620301143331000, -270.53099283938531000, -329.16761657092985000, -437.09487658334911000, -463.02432015574482000, -492.31870707748175000, -494.21384037280041000, -564.91995873219537000, -616.16896545880149000, -628.75564372379188000, -647.68295060 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1.48352480916727570, -54.64876701826907600, -152.25608806185321000, -182.68765513864938000, -226.41003462381161000, -229.07007687127671000, -336.86453485713656000, -409.74188200294992000, -424.91981395395106000, -440.13744409607625000, -45 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -36.44433069874922600, -37.98740322939748600, -102.49367317807565000, -205.76767615152303000, -235.83989377944459000, -290.03082540262949000, -293.43060800279670000, -433.82883295812343000, -541.88270857262000000, -566.69131023912860000, -601.87578949941053000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -54.76891637575361200, -68.45169997407626300, -86.28530261342376700, -87.54825721893483600, -135.85385878090281000, -165.38811785639118000, -172.44880018410328000, -181.83612920244573000, -191.36094 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -21.95257 [...]
+0.00000000000000000, 0.00000000000000000, 41.20548251734172100, 408.09143047233488000, 424.51590724257636000, 715.46928901271281000, 850.15818245597427000, 924.26877135745303000, 971.96642342390965000, 1019.54500053642850000, 1038.84936551913530000, 1065.11137502330940000, 1066.20418477468620000, 1119.10431166486160000, 1214.65827552617450000, 1240.28000147785840000, 1284.02481674672300000, 1286.90297118953300000, 1400.29498848554790000, 1471.93192261741390000, 1488.69785161119780000, 15 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -0.85982896631255523, -34.86188878059979900, -58.99092375355009900, -64.85314200528847600, -75.00041323496908800, -88.37701921639124700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double larslsq18[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -823.84528646831734000, -713.33807098111322000, -785.13395494744373000, -948.25464511213795000, -1074.93836651475160000, -1014.17188130256450000, -1056.65377280581290000, -1020.02669052607750000, -1035.50435996941610000, -1081.43250740232360000, -875.91465821901420000, -900.11391027060949000, -1077.043 [...]
+0.00000000000000000, -3995.32531827254430000, -3657.60583132290640000, -3263.75922267281660000, -3077.62976296313670000, -3037.08949102702540000, -2943.65911386465720000, -3018.43246071499020000, -3000.55010883517710000, -2914.21759521715970000, -2948.70815565022670000, -2926.13028205499500000, -2998.93901581716320000, -3153.21972678890730000, -3143.39104932277130000, -3187.19712770756500000, -2988.93599106287000000, -2952.65650019818850000, -3008.10226194535740000, -3009.759137540504100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -959.07043643164036000, -1029. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 716.10263922517561000, 668.23287486097172000, 633.25924804732301000, 701.05751265432116000, 737.55870390524615000, 712.27147630082777000, 812.10372209783543000, 821.642387945690 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1348.29915655894180000, 1654.98711642984790000, 1572.73034582500190000, 1563.62698037212730000, 1526.31719797302960000, 1490.78505867445210000, 1357.03009864823000000, 1391.17861352076760000, 1363.75333229671220000, 1363.53426881795100000, 1472.79136291097550000, 1422.76271514929070000, 1348.45705160272750000, 1339.14202292549000000, 1349.38118489165820000, 1472.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1275.69073942394170000, 1202.31813393950730000, 1277.02000389881550000, 1246.43158937962680000, 1258.46175274380880000, 1231.05579750248260000, 1286.34570933850480000, 1270.11863355777060000, 1310.91064859572380000, 1272.07577516404580000, 1209.92013254960080000, 1016.5493925389586 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 480.73787963813140000, 604.76482194952655000, 606.78000007579749000, 388 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1713.37494656928360000, -2010.50225398868430000, -2033.90206506636900000, -1969.94197294752870000, -1944.33448697581660000, -1748.24725946703440000, -1741.95210286145110000, -1668.76861716422540000, -1589.98506244677790000, -1465.41940694737010000, -1433.78882859235430000, -1270.32806858050710000, -1316.72368453856960000, -1321.64274547792460 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1431.05214045281060000, -1192.59378142225410000, -1147.98168837297040000, -978.04954478585717000, -802.01790639675414000, -873.07511849267439000, -817.04258386772915000, -836.69441472706194000, -629.93211934533463000, -659.33642867848130000, -511.74767793792432000, -583.14039181104511000, -565.84487012612544000, -593.29562974621081000, -596.38536309871745000, -588.92338298064817000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -850.05729767916284000, -916.24838791827949000, -786.28014476085332000, -895.9174214197051900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1350.52800916584470000, -1325.79436129319630000, -1341.28015840064090000, -1371.49396760624310000, -1387.00061318192020000, -1377.87085159040520000, -1503. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-3111.51000091400650000, -3304.58921213634590000, -3306.42387471482110000, -3122.30854311318350000, -2880.37754359572140000, -2806.96928364516360000, -2878.86333340206470000, -2895.00996706804240000, -3009.07479536834440000, -2874.97323297756570000, -2748.48550289429840000, -2622.67497024579140000, -2629.18012968898480000, -2310.34442913517570000, -2309.76857414689450000, -2359.88829615913850000, -2481.65227639000610000, -2498.15580889213610000, -2492.60905943422810000, -2539.21117357960 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1370.06130198510440000, -1254.11390432599590000, -1138.52744525138770000, -1249.23341522118110000, -1244.84179080550920000, -1178.95140031223490000, -1127.43749783069760000, -1199.03855574992330000, -1333.1593148099655 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2236.67852521842040000, -2371.79631905357340000, -2173.52730149050240000, -2253.00845803962920000, -2084.68444749661280000, -1988.56624437190110000, -2090.23480404411790000, -2061.27430488384790000, -2259.88086095417290000, -2215.39536968782110000, -2211.10467353140300000, -2175.16313609798640000, -2176.95712841016800000, -2177.97408783982160000, -2161.86798128430200000, -2108.12996609007540000, -2159.59591748992350000, -203 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1150.78617659314520000, 1107.94795064531190000, 884 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -593.54089992511217000, -566.17909581804679000, -522.62717741713448000, -422.33787125514641000, -250.0611971551363 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1718.07167394619570000, -1656.67261796826480000, -1487.42014033396620000, -1290.69306806912780000, -1436.69123847917220000, -1388.53858036914040000, -1680.75938560080090000, -1665.04790184298100000, -1789.41827875591280000, -1855.55623208628230000, -1865.23996336029970000, -1757.50937958505410000, -1640.71524322583700000, -1610.90933568739250000, -1516.41063203866290000, -1482.68091930487230000, -1469.70 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1777.61200366245040000, -1858.89926401650430000, -1775.03617006575250000, -1686.44941092565300000, -1533.75512246566430000, -1422.14694608673240000, -1456.43671960539040000, -1330.99908037869820000, -1136.71245182452340000, -1142.21602965745050000, -1089.77222492736200000, -1130.88633594858810000, -1157.30592792569720000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1120.44442638747610000, -1045.64222955606600000, -1074.12908394410010000, -1201.36867939367130000, -1188.17885132463200000, -1138.61728613883790000, -1137.02393930336690000, -1141.68263338711930000, -1062.28418264626630000, -960.3740679382 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1232.54540229043710000, -1201.86266802128650000, -1304.88247374850740000, -1181.16084850764540000, -1242.49188043277760000, -1482.07821158921370000, -1455.91694785147680000, -1476.00634527789950000, -1627.11753125358880000, -1608.47478840727220000, -1804.70793 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -572.04553539078825000, -526.47582917598777000, -478.57417412323196000, -519.38983340777156000, -494.42685130257252000, -462.01427983832519000, -468.94685728880449000, -502.75550428167855000, -449.4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -857.4300 [...]
+0.00000000000000000, 0.00000000000000000, 2255.49979909648980000, 2277.98281459350440000, 2083.31193102235970000, 1910.84907993420710000, 1845.58776434328590000, 1906.53562276606570000, 1903.85798696662550000, 1798.28460916868560000, 1845.93681948789030000, 1927.02918522394660000, 1890.46501081411980000, 2105.15605783012100000, 2117.13790504001600000, 2097.95407293716970000, 2246.28715729956870000, 2271.02919843032530000, 2242.00513503536290000, 2191.41463499477370000, 2192.7467156567627 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -294.86081241019474000, -287.25953926569355000, -301.32993141446110000, -311.02429675930279000, -421.89950832640523000, -450.8502179083 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lasso18[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -47.43619003820982300, -62.99153879360179800, -84.34409666043389100, -85.48795770462832900, -135.86762738428317000, -219.95843704763860000, -244.22842526753416000, -277.96292864879558000, -280.17195758182726000, -375.29952985955697000, -420.63089425423942000, -431.78352080669828000, -450.12182912353143 [...]
+0.00000000000000000, -536.86729585198441000, -593.87973150640255000, -1031.80497958327760000, -1051.86299679329520000, -1440.47597582744670000, -1619.62716919730840000, -1717.76092324874820000, -1780.22183163131470000, -1845.51617685307590000, -1871.28654402795430000, -1902.47653017590760000, -1903.92830168858700000, -1967.53824996873120000, -2080.11702150659950000, -2112.23004997428050000, -2150.35238261982790000, -2152.69194179843500000, -2254.24830455100250000, -2322.66081335114770000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -34.13360118072711200, -59.618 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 20.77196068325443800, 48.92589370511262100, 50.62983916988690700, 127.85017097667235000, 183.06008796680936000, 195.36938106843638000, 212.89699435733689000, 234.562423397835370 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 160.69193221028078000, 265.52481851524396000, 329.17459479641315000, 400.25313213479848000, 426.55778716929933000, 458.02522889541115000, 459.21555658720092000, 506.66815304265873000, 588.72740113624843000, 611.20219303202168000, 648.66719400731199000, 650.92449549926050000, 733.73723183286290000, 788.55743928692334000, 801.60202603463688000, 820.65902000275469000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 29.79990734921014100, 64.46933366061385600, 66.07481177207238000, 126.17482692242437000, 234.58250448834769000, 263.48716553916955000, 307.96473986430857000, 310.77042903366885000, 429.50947221452662000, 505.80496937788860000, 522.18247014948986000, 536.23239677430445000, 552.56063 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 11.18181429192054000, 28.05146581111338500, 48.64858592879256300, 57.340 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -120.20251612152529000, -212.24401449799811000, -317.13326845225890000, -355.74258396878315000, -402.71462130790042000, -404.49617423747253000, -472.59517879112315000, -587.11949366476233000, -616.20957520372906000, -653.13627796041692000, -655.41270008030642000, -728.41692595264476000, -781.68888386711683000, -794.24804357236451000, -813.0766 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -280.13198346379215000, -388.88028955650037000, -442.13535687951224000, -468.22981368336599000, -487.44899920097680000, -496.45715632808532000, -505.93633763592459000, -506.37427797606193000, -512.66545050890352000, -526.70805733150894000, -526.27410220336367000, -528.74685333591594000, -528.85503301963934000, -536.50557506130144000, -541.92776935314350000, -543.02087278096815000, -54 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -76.97381667975561500, -96.49508345112911900, -116.09880097222150000, -143.85277687694793000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -58.72582310623012300, -62.42065872216424800, -214.24992264384286000, -319.03990705298224000, -343.88034254350589000, -373.26639190264729000, -413.475362248 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-156.84343779135173000, -579.81819636064347000, -629.63026136553208000, -1038.49019625093750000, -1056.54873597149000000, -1399.19787226393030000, -1575.54620031742230000, -1668.11371743455020000, -1733.40710154982140000, -1799.13734100258170000, -1821.31394414958800000, -1845.00886539943990000, -1846.04714761836320000, -1869.68768934506560000, -1911.82201552560880000, -1924.81905624994170000, -1949.03217064940920000, -1950.63344281029300000, -2014.97808657780500000, -2062.44808847827610 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -69.75916652345638600, -183.15193262488629000, -210.86447199982015000, -256.01649436793423000, -258.89995868979480000, -368.13067026267248000, -436.88691141074565000, -454.61432277200043000, -479.58260466082686000, -516 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -366.86974122437795000, -386.52677741321617000, -736.33653424164913000, -917.09533749283764000, -999.00802630596945000, -1047.19108389042840000, -1107.24850115074360000, -1129.53437317395830000, -1162.95685085979450000, -1164.35033242481810000, -1217.64773618668230000, -1309.32239776832190000, -1334.48984378111530000, -1371.16757735887270000, -1373.47329952457150000, -1460.69349920079710000, -1523.98004090722430000, -1535.939 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 32.70538664649377100, 70.97358829040305700, 91.7914 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -70.46659775033703000, -115.35402246429925000, -124.82706999738565000, -133.28233821710751000, -137.43853242966384 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -16.84460540512385800, -337.84498038338887000, -474.85274514744361000, -532.08835476397462000, -576.13481109304814000, -622.91220998106223000, -647.62333066955046000, -677.70689389081042000, -679.17885571349404000, -739.07625240217749000, -846.89767970995024000, -873.31175695449633000, -906.68122510326157000, -908.73478971031238000, -980.87952168977995000, -1026.31830434022640000, -1036.63140537506930000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -86.55456543294197000, -188.60440575627649000, -225.66316783023680000, -268.85620301143331000, -270.53099283938531000, -329.16761657092985000, -437.09487658334911000, -463.02432015574482000, -492.31870707748175000, -494.21384037280041000, -564.91995873219537000, -616.16896545880149000, -628.75564372379188000, -647.68295060 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1.48352480916727570, -54.64876701826907600, -152.25608806185321000, -182.68765513864938000, -226.41003462381161000, -229.07007687127671000, -336.86453485713656000, -409.74188200294992000, -424.91981395395106000, -440.13744409607625000, -45 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -36.44433069874922600, -37.98740322939748600, -102.49367317807565000, -205.76767615152303000, -235.83989377944459000, -290.03082540262949000, -293.43060800279670000, -433.82883295812343000, -541.88270857262000000, -566.69131023912860000, -601.87578949941053000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -54.76891637575361200, -68.45169997407626300, -86.28530261342376700, -87.54825721893483600, -135.85385878090281000, -165.38811785639118000, -172.44880018410328000, -181.83612920244573000, -191.36094 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -21.95257 [...]
+0.00000000000000000, 0.00000000000000000, 41.20548251734172100, 408.09143047233488000, 424.51590724257636000, 715.46928901271281000, 850.15818245597427000, 924.26877135745303000, 971.96642342390965000, 1019.54500053642850000, 1038.84936551913530000, 1065.11137502330940000, 1066.20418477468620000, 1119.10431166486160000, 1214.65827552617450000, 1240.28000147785840000, 1284.02481674672300000, 1286.90297118953300000, 1400.29498848554790000, 1471.93192261741390000, 1488.69785161119780000, 15 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -0.85982896631255523, -34.86188878059979900, -58.99092375355009900, -64.85314200528847600, -75.00041323496908800, -88.37701921639124700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double lassolsq18[2600] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -823.84528646831734000, -713.33807098111322000, -785.13395494744373000, -948.25464511213795000, -1074.93836651475160000, -1014.17188130256450000, -1056.65377280581290000, -1020.02669052607750000, -1035.50435996941610000, -1081.43250740232360000, -875.91465821901420000, -900.11391027060949000, -1077.043 [...]
+0.00000000000000000, -3995.32531827254430000, -3657.60583132290640000, -3263.75922267281660000, -3077.62976296313670000, -3037.08949102702540000, -2943.65911386465720000, -3018.43246071499020000, -3000.55010883517710000, -2914.21759521715970000, -2948.70815565022670000, -2926.13028205499500000, -2998.93901581716320000, -3153.21972678890730000, -3143.39104932277130000, -3187.19712770756500000, -2988.93599106287000000, -2952.65650019818850000, -3008.10226194535740000, -3009.759137540504100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -959.07043643164036000, -1029. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 716.10263922517561000, 668.23287486097172000, 633.25924804732301000, 701.05751265432116000, 737.55870390524615000, 712.27147630082777000, 812.10372209783543000, 821.642387945690 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1348.29915655894180000, 1654.98711642984790000, 1572.73034582500190000, 1563.62698037212730000, 1526.31719797302960000, 1490.78505867445210000, 1357.03009864823000000, 1391.17861352076760000, 1363.75333229671220000, 1363.53426881795100000, 1472.79136291097550000, 1422.76271514929070000, 1348.45705160272750000, 1339.14202292549000000, 1349.38118489165820000, 1472.1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1275.69073942394170000, 1202.31813393950730000, 1277.02000389881550000, 1246.43158937962680000, 1258.46175274380880000, 1231.05579750248260000, 1286.34570933850480000, 1270.11863355777060000, 1310.91064859572380000, 1272.07577516404580000, 1209.92013254960080000, 1016.5493925389586 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 480.73787963813140000, 604.76482194952655000, 606.78000007579749000, 388 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1713.37494656928360000, -2010.50225398868430000, -2033.90206506636900000, -1969.94197294752870000, -1944.33448697581660000, -1748.24725946703440000, -1741.95210286145110000, -1668.76861716422540000, -1589.98506244677790000, -1465.41940694737010000, -1433.78882859235430000, -1270.32806858050710000, -1316.72368453856960000, -1321.64274547792460 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1431.05214045281060000, -1192.59378142225410000, -1147.98168837297040000, -978.04954478585717000, -802.01790639675414000, -873.07511849267439000, -817.04258386772915000, -836.69441472706194000, -629.93211934533463000, -659.33642867848130000, -511.74767793792432000, -583.14039181104511000, -565.84487012612544000, -593.29562974621081000, -596.38536309871745000, -588.92338298064817000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -850.05729767916284000, -916.24838791827949000, -786.28014476085332000, -895.9174214197051900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1350.52800916584470000, -1325.79436129319630000, -1341.28015840064090000, -1371.49396760624310000, -1387.00061318192020000, -1377.87085159040520000, -1503. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+-3111.51000091400650000, -3304.58921213634590000, -3306.42387471482110000, -3122.30854311318350000, -2880.37754359572140000, -2806.96928364516360000, -2878.86333340206470000, -2895.00996706804240000, -3009.07479536834440000, -2874.97323297756570000, -2748.48550289429840000, -2622.67497024579140000, -2629.18012968898480000, -2310.34442913517570000, -2309.76857414689450000, -2359.88829615913850000, -2481.65227639000610000, -2498.15580889213610000, -2492.60905943422810000, -2539.21117357960 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1370.06130198510440000, -1254.11390432599590000, -1138.52744525138770000, -1249.23341522118110000, -1244.84179080550920000, -1178.95140031223490000, -1127.43749783069760000, -1199.03855574992330000, -1333.1593148099655 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2236.67852521842040000, -2371.79631905357340000, -2173.52730149050240000, -2253.00845803962920000, -2084.68444749661280000, -1988.56624437190110000, -2090.23480404411790000, -2061.27430488384790000, -2259.88086095417290000, -2215.39536968782110000, -2211.10467353140300000, -2175.16313609798640000, -2176.95712841016800000, -2177.97408783982160000, -2161.86798128430200000, -2108.12996609007540000, -2159.59591748992350000, -203 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1150.78617659314520000, 1107.94795064531190000, 884 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -593.54089992511217000, -566.17909581804679000, -522.62717741713448000, -422.33787125514641000, -250.0611971551363 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1718.07167394619570000, -1656.67261796826480000, -1487.42014033396620000, -1290.69306806912780000, -1436.69123847917220000, -1388.53858036914040000, -1680.75938560080090000, -1665.04790184298100000, -1789.41827875591280000, -1855.55623208628230000, -1865.23996336029970000, -1757.50937958505410000, -1640.71524322583700000, -1610.90933568739250000, -1516.41063203866290000, -1482.68091930487230000, -1469.70 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1777.61200366245040000, -1858.89926401650430000, -1775.03617006575250000, -1686.44941092565300000, -1533.75512246566430000, -1422.14694608673240000, -1456.43671960539040000, -1330.99908037869820000, -1136.71245182452340000, -1142.21602965745050000, -1089.77222492736200000, -1130.88633594858810000, -1157.30592792569720000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1120.44442638747610000, -1045.64222955606600000, -1074.12908394410010000, -1201.36867939367130000, -1188.17885132463200000, -1138.61728613883790000, -1137.02393930336690000, -1141.68263338711930000, -1062.28418264626630000, -960.3740679382 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1232.54540229043710000, -1201.86266802128650000, -1304.88247374850740000, -1181.16084850764540000, -1242.49188043277760000, -1482.07821158921370000, -1455.91694785147680000, -1476.00634527789950000, -1627.11753125358880000, -1608.47478840727220000, -1804.70793 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -572.04553539078825000, -526.47582917598777000, -478.57417412323196000, -519.38983340777156000, -494.42685130257252000, -462.01427983832519000, -468.94685728880449000, -502.75550428167855000, -449.4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -857.4300 [...]
+0.00000000000000000, 0.00000000000000000, 2255.49979909648980000, 2277.98281459350440000, 2083.31193102235970000, 1910.84907993420710000, 1845.58776434328590000, 1906.53562276606570000, 1903.85798696662550000, 1798.28460916868560000, 1845.93681948789030000, 1927.02918522394660000, 1890.46501081411980000, 2105.15605783012100000, 2117.13790504001600000, 2097.95407293716970000, 2246.28715729956870000, 2271.02919843032530000, 2242.00513503536290000, 2191.41463499477370000, 2192.7467156567627 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -294.86081241019474000, -287.25953926569355000, -301.32993141446110000, -311.02429675930279000, -421.89950832640523000, -450.8502179083 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+
+double nnlasso18[850] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 81.10338217511720400, 234.23929622881218000, 273.51458296377064000, 343.42329068759767000, 823.45234791470557000, 868.46353826636664000, 881.28575804623279000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 167.23362511592498000, 217.18902687226313000, 299.66227727408216000, 909.63930117388816000, 967.54838914407264000, 985.54738535588797000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 100.71081533416293000, 736.13865519972398000, 798.65117512738129000, 819.65273504983043000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 129.60870040210986000, 161.62341196740704000, 276.95310395062302000, 471.28189429370769000, 526.81794863089385000, 643.95128368275482000, 1417.12742759938210000, 1486.12535387956090000, 1508.19636915189700000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 36.10521660244358300, 153.24177613451329000, 355.37575553270250000, 407.95554623552130000, 529.38383003899514000, 1308.46313528047740000, 1378.33642097460190000, 1402.67821002400710000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 83.25555569050727900, 134.72101617541520000, 417.33133010396978000, 430.26213453954352000, 585.07509301167204000, 676.32855258126608000, 700.90709783926025000, 781.23958653236207000, 890.78445735187063000, 924.00673252324043000, 998.77531378564470000, 1461.32750312763510000, 1500.45494198250030000, 1514.28815439640790000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 150.08804014260338000, 471.84773353598086000, 550.61376004236570000, 601.07207275119640000, 900.63038617117172000, 913.38970900889183000, 1050.71024962506660000, 1134.31703642998060000, 1155.78768721462730000, 1227.52861053389940000, 1325.07864211813650000, 1360.40507185819230000, 1431.85836490318050000, 1864.09266870857910000, 1908.49469537792580000, 1920.64623986279570000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 319.00005380418702000, 338.51923545631132000, 343.37438990161780000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 49.81027025367340900, 351.97433031618641000, 361.60619829392056000, 473.88059198209174000, 551.78672362220004000, 577.95534018298974000, 679.92462800080182000, 868.11846434262975000, 910.27616190765764000, 1017.94984433070850000, 1713.73411695076770000, 1771.77343944577570000, 1789.13660056867000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 318.57902380184777000, 399.16728921125525000, 444.92010070446673000, 723.00810537166399000, 734.69548161409296000, 868.70750645227429000, 946.98353859144129000, 965.77677817157689000, 1029.26962150003810000, 1113.84311276646640000, 1136.16006615225820000, 1187.19537972884360000, 1504.17042456447330000, 1537.82448162796980000, 1548.69718892899280000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 315.65155846494406000, 329.34994850544041000, 475.16051788913768000, 547.13873139879479000, 568.57668302875118000, 632.27126873138275000, 716.45417005385934000, 735.13320679186302000, 790.56063505921998000, 1083.58260053024220000, 1115.74900779930730000, 1127.69761235435090000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.37122698827236200, 50.11039737510508700, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 15.04466973494635000, 182.77949544205927000, 295.68405006219967000, 324.34290427567799000, 435.11526852763234000, 596.62491655885310000, 644.76721684282620000, 733.45885430104272000, 1278.80277782026630000, 1333.61515545469480000, 1352.89910143859740000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 112.52192615463409000, 178.62561804049560000, 187.90432728357658000, 220.69819986603005000, 270.67719207169313000, 287.67439277294915000, 318.98611402868386000, 459.31430791177178000, 477.44797290731879000, 481.21178559903444000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 57.44348966521399500, 172.65784147133041000, 897.61641363771832000, 961.52650319529982000, 981.62080761937284000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+815.17880564327902000, 952.12557111702040000, 1239.97668729837410000, 1310.39089913955130000, 1357.87992780520400000, 1634.34771032850020000, 1642.92831688495950000, 1751.36546216619690000, 1845.01194500520660000, 1869.15553994288510000, 1950.05936479712300000, 2117.95711088103010000, 2167.47873503536950000, 2267.58397901535000000, 2911.13653281982850000, 2970.52655832893470000, 2987.00316636030670000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 16.43027064004005700, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000};
+
+double nnlassolsq18[850] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 776.89243455583710000, 915.81631760410642000, 907.47197680302384000, 845.30268397746374000, 881.80273108400945000, 882.30106018565084000, 881.28575804623279000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 911.55671081833111000, 1023.53823367391000000, 891.74338164558537000, 983.78563155360553000, 985.35103483845853000, 985.54738535588797000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 823.72064548741378000, 813.37868343213336000, 817.86902646547037000, 819.65273504983043000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1190.11481488778900000, 1221.57143690819820000, 1266.37099188898360000, 1336.20008744245480000, 1423.24659877184740000, 1484.85950590426590000, 1511.11158038277400000, 1507.33697503038640000, 1508.19636915189700000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1231.48231533921720000, 1158.16085065569590000, 1255.03326858771170000, 1256.66601670301880000, 1401.12578304817790000, 1403.16485238634030000, 1399.81714865167330000, 1402.67821002400710000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1315.09509503908820000, 1286.75291678324220000, 1215.04740479440470000, 1382.25098325803220000, 1400.23673302993140000, 1422.99796243788000000, 1514.65737789389390000, 1470.41511391630820000, 1378.34655029058130000, 1460.26015639208820000, 1535.54407153983680000, 1517.55346919688530000, 1512.48365725462760000, 1514.28815439640790000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 1734.38750199988340000, 1753.51219888061700000, 1716.02674663787840000, 1730.55940937892800000, 1746.18509576567320000, 1852.75377713228570000, 1773.76624055510020000, 1818.41855387462690000, 1866.64131608343360000, 1842.99676629410150000, 1759.25412847032660000, 1930.62245773707130000, 1944.82644183645200000, 1916.63331570951690000, 1922.14494573783550000, 1920.64623986279570000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 357.77640513180359000, 344.51990110962021000, 343.37438990161780000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1164.79145898618780000, 1204.88420665753320000, 1070.72147049660410000, 1065.05706580022000000, 1189.24338126889620000, 1444.34994700207310000, 1554.72309188607030000, 1705.73121643732770000, 1590.75964911794970000, 1790.94657345417270000, 1798.31082808795990000, 1789.61612236374570000, 1789.13660056867000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 1587.57393707029500000, 1591.54191112666130000, 1469.07684361620590000, 1507.95918666055560000, 1595.14093255297170000, 1574.34263562608040000, 1587.46685833555970000, 1587.98626253863740000, 1573.97718002182480000, 1490.26263930855410000, 1496.38652872053150000, 1553.58138582354450000, 1542.70062402386930000, 1548.17054776509420000, 1548.69718892899280000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1206.63221196023710000, 1337.84981631511440000, 1242.92042664515720000, 1136.09097997411140000, 1278.34770322371150000, 1178.70958288363160000, 1091.13525965107420000, 1036.63866822271140000, 1188.47793286327400000, 1119.20116091703020000, 1125.63773462863200000, 1127.69761235435090000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 48.86004051576623700, 50.11039737510508700, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1122.66004600027420000, 1065.98072718005460000, 1219.51069253651920000, 1273.18468467672230000, 1385.43566560332740000, 1315.47173644914390000, 1421.85046075174250000, 1370.18218458001500000, 1345.09257094281750000, 1350.46579795134470000, 1352.89910143859740000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 705.00177259292991000, 719.51036742489964000, 495.10526883022243000, 502.03810106487157000, 493.12359107206493000, 562.03269680895448000, 543.77510210110233000, 476.37203339579514000, 483.02269743454025000, 481.21178559903444000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 984.66078146863902000, 999.78955174654106000, 985.73943417346641000, 981.17400103321961000, 981.62080761937284000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+2558.56208219709790000, 2397.70835464193400000, 2386.57321413054660000, 2352.23140526110320000, 2420.90113535380620000, 2414.72543677130530000, 2274.64785124876150000, 2322.33705303767830000, 2611.26195247176880000, 2668.50541748176010000, 2644.13640720407370000, 2865.23606486545990000, 2966.82617199827110000, 2986.24637100637070000, 2989.36416829046490000, 2988.78447982242280000, 2987.00316636030670000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 16.43027064004005700, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000};
+
+
+
+// Data from file x101.txt and y101.txt
+double x19[5000] = {
+-76643.305104564, -15174.6213630427, -57333.638570787, 25355.0611806138, -10999.2722644396, -1964.73288827741, -18680.6196228147, 23646.1051842669, -2862.18599317833, 65438.7337021508, -48730.2223224347, -19073.8714311947, -29233.3639551661, 4309.48978833944, -37064.6109118602, -21338.1503781802, -3563.22972681262, -6745.88362259657, 2323.92711376389, -79067.8284071984, 14200.7309285290, -22542.6759862688, -77713.687521487, 33507.4955474878, 53537.058534367, -39559.0962108041, 120255.177 [...]
+17523.3571786145, -61255.7125524827, 111884.799463675, 89706.6792346285, 63847.8511531506, 19413.6099778137, 73392.492597285, -47717.6000133143, 47114.6719917977, -26486.1297652427, -7680.54786548435, -26776.6349775268, 28043.1076182342, 17142.7530437769, -1865.9741186859, 26331.6069025552, 44012.9423475786, -7291.1301522522, 26821.8278574942, 15956.0467679619, 22785.7425565443, -70877.3784723895, -77014.7029243305, -150785.272576587, 47089.6382082345, 67092.173697432, -34362.7183658698, [...]
+-24402.4061840167, 93324.383299687, -66317.1687460293, -44728.8455094145, -49498.0611871608, -45225.123656188, 58060.7719986647, -94184.7301164983, 19539.4333229745, 38961.7153057576, -10050.242992216, 6655.33709793253, 15321.5161549445, 84084.8538513019, 63461.6765679175, 49037.9994205413, 8743.82571658867, -10619.6900430238, 66480.4967449218, -22206.8142756283, 22406.6440301894, 9638.8301219727, -55309.0688688099, 48195.139260332, 31635.1819298965, 5455.99085680964, 12341.6546116117, - [...]
+-23118.4951267585, 47193.2866329864, -43953.4112527996, -125833.324710546, -24777.2116989928, -74931.2852573137, -200518.029388822, -116676.084418479, -9571.9614750184, -97752.7600177215, -68451.7787063421, 16180.2863519791, -1956.61780582715, -61411.8062420659, 43930.0929314928, -889.841379028507, -71779.0256623661, 26580.2825174976, -60756.8862550109, -7280.05458100565, 11603.8705003285, 1729.37103239667, 71019.2816408148, -30169.2300879297, -53381.1792987228, -27792.8289709973, 29457. [...]
+-2272.83807519227, 65970.055459762, 42514.4378831343, -22251.6669436927, -61749.3919755274, -22321.9856863077, -51457.7411589299, 49406.6735881295, -4799.99897414902, -10425.8070285718, 3452.65118382076, -52420.9374673678, -40476.7312017872, -81844.52305678, -29040.0712157487, -4830.08131955781, -48068.494812657, 18030.4768665268, -6312.19288108244, 4943.56162733707, -35622.4248268918, -31055.4038728397, 46106.1548370438, -127037.807248882, 36197.3435965532, -17009.1564324916, 21397.2085 [...]
+-962.075286382234, 7223.22762752227, 144054.52371999, 51517.8508302157, 115828.192576124, 28522.6419228334, -2225.20729485208, -106251.698113673, 87211.269744082, 67219.5746803592, 117466.994435693, 36810.4533367317, 23012.5668260473, 62542.8069083697, 66778.306448916, -45628.8291888427, -19565.9773244324, -9968.45789761885, 42498.7351823716, 29379.1975675742, -1014.98580677551, -8078.06797955351, -12408.9539591808, -47715.0971731964, -74379.155346078, 111728.901318507, 19310.7606139255, [...]
+-97305.9810046294, 10384.7133169233, 34629.7217025513, 61703.2586280115, 104619.008675893, 41780.5619931193, -7613.4206038341, -877.825906555488, -26585.6463383875, -79135.7212362802, -85768.6161214676, -27247.1555359027, -109055.231720218, 32140.7119089784, 18584.0497657408, 25647.3591504774, -22348.29934428, 26839.6478220062, -62760.4408369194, 46972.0121569004, 14943.0203736358, -1420.25530732127, 24517.7175421521, 43338.850748635, -35814.1635106927, 25519.1872054245, 15011.7185145302 [...]
+60960.2891398072, -72580.3511931437, 8117.02595576692, -51407.1477322179, 17354.0755641660, -29203.3353377221, 42826.2085742702, 24533.0011640165, 68396.0670240874, 11837.4860857621, -4709.65224877209, 60432.6110283564, -40986.6779723885, -31356.2662194914, -31645.331034611, 58911.7915949904, -21970.522054098, 52337.1030292797, -63636.532901487, -62002.0521958908, -44745.8353436032, 26027.5922715191, 38389.7457182052, -18579.1118797356, -28550.8864976640, 112882.095610200, 55969.57159466 [...]
+26668.6691589370, 45408.4461901880, 120160.466106128, -442.942284344791, -154121.932830164, -6735.78650114224, -72906.7012158433, 45029.9951975187, 40559.4784829686, 28852.5728498973, 3853.24921461828, -69491.3972047272, -2315.57189619934, -21776.1834098363, 20379.0502347824, -33627.8144156032, -24140.6232838637, 57993.8991221398, -32059.9027784837, -14389.9599372222, -25783.6821597250, 29766.6241075671, 35762.0784968231, 56481.1881673982, -19672.5503026716, -235.363134631482, -15989.836 [...]
+-83104.5134810056, 39043.2572333355, -27572.4028225208, 26971.1141078765, 63421.2945751734, -9528.69867842737, -26372.9244647916, 44476.5544700844, -96657.8678652492, -57138.2940349092, -75362.0158246552, -6630.50141894149, 94540.8690797416, -109765.012227479, 9338.87111234259, -11667.5585189088, -38613.3891129385, -12221.9585309422, -18067.5043997854, 49436.2548916691, 109501.316047075, -18449.9913899972, -132667.430275715, 69860.2517322331, -5010.74950746629, 6985.26233121582, -47307.2 [...]
+-25533.1809035202, 19235.5907905328, 7892.19792940793, 9123.7330474576, -10908.1838484985, 38148.5817335548, 9224.09442048506, 18024.7571946075, 14293.2120282391, -48963.3365164195, 89444.8126216974, -4786.96517829038, -27359.4721448377, -7637.13421978446, 96973.2898268742, 17221.5837902519, 55045.9966349116, -54988.4450548281, -34278.4407436072, 63464.9879093252, 79007.1013333298, 61368.0084941423, -32060.4073922546, -61305.5260672265, 25632.034031436, -27078.3414494667, -86437.64166055 [...]
+79009.5893345162, 11870.519476941, 12773.7529395950, 85926.6968808753, 42892.5251510865, 5551.89047045009, 128444.926062675, -29009.2724479847, -13533.7018774708, -11282.4513084899, -37203.9235746549, -12706.3732411760, -22934.2000881740, 12457.0069949228, 78768.5458623527, -35574.3043231001, 88617.2666326054, 94604.0061534538, -38107.7808312943, -19169.9164024215, 85407.633556814, 72005.1792483212, -72897.0851036748, 64884.7981351836, 5425.52721653024, 53098.3848525553, -56768.795391466 [...]
+-28891.8873504292, -13710.6084818664, 237.252050102082, 38306.9965719136, 27678.8923239679, -35223.4243974320, -26809.0926033500, -47296.1327576725, -71946.311009937, -20976.8176583318, 88095.0136567486, 62209.2797753702, 22123.6167680967, 54321.1713237454, -54668.7502695278, 42443.1820248306, -12862.6011572866, 25774.2525309532, 35309.4157650167, 20886.4501047482, 16200.5581373391, -36710.0136634868, -12230.7183352677, 68313.735153734, 21632.6872838836, -67363.6679941427, 8825.833434976 [...]
+-42879.7243196264, 12991.3000838757, -45421.7417014246, -26524.0940294033, 58152.8137006374, 34047.036920872, -87709.0266535887, -29476.3268794072, -5555.82337205313, 15150.9243723535, 7462.97644253823, 104286.124709677, 8910.69709076655, 56775.4017001851, -11552.1212252233, -29563.2523960292, 15956.7852624314, 26365.3218218737, 10848.2001122894, 21832.8575677345, 37902.1504557418, 67420.5627471623, 30395.6906828886, -32510.1012079737, -44870.4414274023, 31999.1921383033, 19965.317814481 [...]
+10446.3813709536, 42091.8444290993, -36473.4931580690, -26981.9043132065, 24748.9783858736, -37298.9228045138, -1928.37829523551, -29452.8171474507, -16189.9958426987, 50063.7373980938, 89956.336355398, -28331.6484135485, -13365.4363695671, -22405.3311042147, 14534.4452526543, -49812.9187890072, -9725.42452577086, -36096.6707158020, -1415.59234481741, 14285.7206691989, -23079.7157440173, -23781.0878671639, -86884.5080143018, -34835.0293935115, -1440.62908753591, 40152.6693474183, 82846.6 [...]
+8704.05786167759, 31043.5431436433, -17029.5377318228, -29487.1362628401, -59499.9347984612, -10482.0540130072, 17127.6020607064, -12974.1572246742, -74397.240688985, -43857.9349584465, -21436.0965751156, -125769.519821828, -23964.1366293622, -26963.7966582892, 6065.33806099516, -3388.04252992996, 10707.6121359358, -7926.46208689348, 7012.00948637743, 3975.26892895511, -25443.9058554404, -17323.9708721016, -85363.6985809038, -24255.7907178392, 6052.61919305713, -16085.0868815063, -17578. [...]
+110.488816468513, 64320.5222615921, 11876.3378915978, 5995.81984878359, 28727.028408435, -35568.0348392545, 135736.355432989, 3660.01943981572, -71481.815058815, 70160.7633012011, 48578.5557792446, 43689.5551622448, -80279.8594197427, 68226.5781139311, -7845.46378091382, -32995.2888230104, 107672.308592692, -29645.3411515623, 13904.3783725812, 50561.3221929252, 8257.39737275133, -42170.1930721818, 2423.12501961774, -5670.9614304434, -25696.7987452141, 15645.102187743, -15725.9192788381,  [...]
+-15948.5009648651, -94255.3354882041, 40481.2434279769, -139961.581035471, 47090.8882562255, -40574.4994343631, -18484.8215077982, -90675.2917916647, 36221.6558271727, 44183.878631775, 50246.7278219858, 42721.6036797001, 26888.8519816922, 77358.1710398419, 62568.149836653, 49191.9240960043, 29154.6916608323, 38474.7785725306, -27245.4194580313, 104067.890017312, -108660.116225193, 35814.744579915, -46365.8162240996, 31860.1806835709, 41920.854824685, -71912.79810263, 26673.2928669123, -5 [...]
+-4043.01333142123, -87530.1851220216, 19123.2396932535, 51624.0045563059, -29934.3693904225, -16707.8619538739, 22608.9098279914, -7746.33302711535, -17504.6200829127, -40867.2838070262, 24299.9870754033, -57559.85155439, 6358.41710079834, -107258.868330070, 83667.9756293623, 78556.9584835148, 69806.0945053188, 59866.5040077889, 45330.5207956585, 33950.8837344643, 63348.6229808521, 38721.6655541036, 9546.78536230308, 35908.0224227295, 54674.3473720734, -7833.15249695106, 83483.3727965367 [...]
+43835.3008913655, 70172.8490724867, 52578.7182600496, -76340.5670862897, 53231.6056488339, -5568.33930129064, 6790.70586339589, -7343.04936890637, 61132.3382735227, 59818.7847029697, 13068.3888322651, 62130.6602169898, 76255.7892475039, -23945.3385513262, -33371.0773755559, -76951.100966758, -19652.8253822116, -63611.6216269654, -13400.9059262361, 81888.8760291887, 25945.8955407602, 11786.4207541666, -88894.7283583778, 79316.8751515103, 664.875393712928, 37951.4685853721, 1068.1712622307 [...]
+96736.9976531685, -29162.3012730216, 22723.3116656243, 52050.9356175069, 43360.0440108332, 73859.2322932858, 83052.6826905212, -59405.87148102, -19394.5660752360, -76512.3997373927, -59302.2231212498, -19812.5768738506, 33313.3329434951, 35888.7532582874, 16105.2343480771, -7576.93734844545, -12611.8901510262, 80853.372098935, 74218.9393620237, 48107.63031762, -10255.9038513464, 8439.36907923464, -3014.79523210757, 61546.8708979272, 35439.9900452755, 932.7327006729, -21480.9403812134, -2 [...]
+-843.36795631711, 6635.25025845162, 13900.9830672067, -65242.8740721986, -77955.5780584475, -7804.5645039686, 24098.4836664896, -55440.8570644158, 55590.3544088326, -177.937673738188, 913.278575687153, -15741.5876117134, 47609.7206202498, 28156.7524500231, 63217.8011218578, -5996.92861300334, -58307.4586840956, 51954.1871276904, -10210.0100554657, 12951.0588845326, 18749.7171056536, 7377.79841367011, -7905.54789535469, -26990.6953153326, 3249.52128230569, -565.655448349217, 26737.0372016 [...]
+-62597.7456520349, -42732.3597584782, -47450.5720846748, -32872.6872238685, 31868.6557231523, -7240.64987177605, -36326.3946277875, 9873.75745550463, -32609.4604934693, -29539.8441736835, 80171.5758332594, 25684.6310807769, -20655.8822988888, 56553.739361726, -3440.74018779503, 36613.0985511097, 64272.9059919739, 15162.0149229185, 55036.4272806031, -56490.8789879885, 91439.450198213, 62013.4235222837, 41973.0246357284, 58024.4701453864, -4398.84562901166, 19109.3867416156, 2566.051252722 [...]
+51946.7264631875, 91541.543158607, 54898.7855116995, 8506.53858961248, -2350.58809822250, -69254.6673582722, -43010.2088797824, 66643.081215902, 102072.742378029, -24484.640240843, -46833.9168284029, -46521.5541597748, 17354.5439015842, 2218.69405384890, -60543.9398873644, 67458.5359547305, 73493.8704890652, -18082.2676627993, 14008.9934603621, 50074.0184048159, -68467.4829090083, -5263.44352542108, 63720.2901191301, -30085.6429657899, 7495.43000478512, -64378.7360010852, -60561.10030726 [...]
+2797.94003643453, 15674.6039085387, 16868.2781238442, -809.843308786029, -9095.61855308044, 90167.8910259898, -26641.4390620523, 17694.0793686316, -10820.3971238191, -7330.15343063196, 15396.9564063300, -120103.272511152, 47530.0357190759, -7654.79657673751, -74303.0966241686, -68643.7131482822, -34747.5252572131, -79821.3741298841, 15810.3946463501, -15238.2272970155, -26847.1227036692, 4516.4498810994, 9569.13225772995, -86889.9867343147, 13775.6233455627, 79726.4434605925, -18030.2059 [...]
+14.5402696818291, -1994.79509143645, -40815.6561108670, 12335.6552605602, 22435.9126588302, -21852.150402486, 80789.9822540215, 108010.138702594, -5029.2370408615, -24031.7225425254, -70909.8859169116, -22521.4440295077, -33765.6841784889, -10711.6759593525, 11595.8839952959, -39845.587116537, -149733.771296422, 26653.1008581714, -100183.681700953, 45401.2279874562, 33945.3510983308, -3011.40274807596, -65673.0617188894, 79934.8973372985, 52169.7767665032, -55337.2029605841, -2607.490359 [...]
+1864.6699359224, -43404.7607024139, -89072.963587776, 11510.9843956269, -26819.1365135171, -86773.9798229002, -35698.0906574944, -29293.194643394, -95292.7044009363, -48207.4537549414, -23200.4075079366, -71565.5562306578, 20454.4633705989, -56948.4742899753, -63469.0609585259, -14320.6591938993, 28970.5843026976, 41372.6881303168, -10334.0718932301, 59446.3117267726, -15314.0717571866, -27372.0435564102, -20145.0938764241, -85219.2595341688, 73413.7675682352, 24532.3922701826, 22962.700 [...]
+-73352.3112224493, -53945.9579044912, 15027.4811989694, 14056.2274754209, -27039.0945816896, 35118.1915013277, 18127.5633313505, -124729.662322569, -41799.8072887282, 27444.9426183063, 38650.2569429333, 59885.1573581785, 61495.0329679463, -15360.6556261362, 5471.73716237893, -15112.3334330985, 60937.7486717385, 7433.4958035125, -87524.6912807691, 81009.7176504316, 40977.9476013969, 12154.7062862730, -27928.5735411071, -18118.0397370351, -40138.2237222829, 2212.77181174079, -56630.1886964 [...]
+-81694.6597851906, -37320.1018257041, 82854.2262606852, -82560.0234181504, -69045.7030815484, 106631.963011890, -2375.39657526024, -105708.643293295, 9821.4655893551, 33463.6325832698, -65190.6734043328, 26594.5817268025, 63949.2773188429, 35287.0730185155, 22271.7714801405, -7425.07050282023, 4581.47569074603, -61710.7380866143, 13102.0546219179, -90345.8817148413, -15473.8285674803, -45805.5488291242, -14412.7890194733, 4235.20392926966, -2230.54197151953, -47482.9499329307, -9509.2536 [...]
+-30890.4691666930, -32040.7642213759, -29352.5641466214, 59879.0513670873, 12891.1580065101, -31996.9226262114, 24192.9998681405, -58890.8816665629, -29717.4953914751, 90975.1206067624, -75963.2865420203, 43722.2800687339, 19469.1370230977, -64797.9668558049, 76746.3286041309, 6220.62122551776, -3523.0055931921, -109759.685203368, -107792.260161890, 25754.2683005060, -15410.7388555909, 22601.8431823745, 62606.0132406071, 68490.8311190752, 9021.7964448152, -4634.69691843835, -10006.143701 [...]
+-68231.7879121725, -45733.7651307675, -3229.53914833987, 68716.791733956, 42420.8051342579, 42593.6215298143, 29324.3903297478, 62334.3971019674, -47745.1628884531, -77675.4898303688, 37213.0367290868, -6779.77192549535, 31917.0705284467, -85807.0690692768, 31439.5664781598, -44718.3219460661, 31236.6823874419, -4113.15815264512, 23012.9726242436, 20040.722227538, -27751.5300027039, 48229.9088856307, 45941.9066338319, -4385.74685891251, 129835.494583796, -3745.44924597874, -17902.3530084 [...]
+-8976.68390160788, 39424.5938844651, 12164.9496720519, 24726.8857799298, -25584.6751931191, -27426.7218658095, -29536.4643124329, 52854.9339027654, -17680.8489577783, 8527.48791125043, 91693.1109315323, -8422.4718468843, -2764.26227281344, 41131.3179581981, 41482.5252923976, -25315.4196091484, 101270.620704295, -7732.58971243028, 50293.9321250581, -9282.25322161315, 15578.0289811508, 4338.03732429263, -88037.9984270785, -31304.8060227252, -14914.885722318, -23280.0209503864, 9063.6110590 [...]
+-8762.74205265897, 35156.5105575215, -2799.09765629799, 12638.9607469389, -48335.1059888703, 41229.4426729345, -60588.7892148467, 122504.923455432, 3410.95281573900, -25281.7451407959, 52169.7189412031, 94751.4022911852, 44979.9916537198, -44754.9833038335, 70317.5111029972, 65468.861813411, -76879.5175228649, 97785.8953748383, 64237.8837861516, -95709.749769118, -54276.5272360908, 27234.8252665103, -128555.784052777, 64503.0657642352, 41850.5940746245, 96856.5729758828, -60902.467044027 [...]
+18272.5433629604, 40532.1683835456, -44495.0904898955, 27455.5782416622, 82985.3344539954, 44763.7504071791, -12437.2632758653, -12900.3871192541, -16692.7695412155, -78211.9613802506, 14708.4187360879, 26164.188141971, -62684.2896113684, 156585.675473055, -11584.8218870782, 23104.5053639381, 445.831524347529, -52378.7259306545, 109432.032863481, 33975.2637691077, -10370.6860826210, 24918.7713516636, -21860.5645693224, -43376.5150748956, -47402.0262824727, -25636.7123202102, 58347.767610 [...]
+25864.2690829416, -70600.219349324, 52281.5003252925, -36900.5007189728, 67672.5610004132, -85415.3470755156, 34789.3610733997, -4680.81237720965, 22832.2498458914, -38354.2217507837, -52419.8224031343, 28600.2377387939, -5006.88647676882, 38643.5117990084, 1473.48477269138, -95272.5688323544, -23712.5169736438, 7247.78900849001, 6864.16995865162, -26048.0732544029, 40114.2175960229, 6911.45310399612, -61768.8404797801, -33330.540225981, -35405.5532566128, 56710.6840906227, 85074.1670595 [...]
+19311.8000747990, -25063.4327184177, 14634.8709708239, 13101.8067202544, 20431.7154121596, 64411.4928558523, 69979.0886391038, -22460.8968164633, 96443.3540368237, 5527.74285851383, 49143.5428271204, 111590.879166207, -22770.0410295677, 11776.5317893272, -60189.6199671071, -76031.917287255, -42186.8018778635, -93225.8158170972, -18587.0657022250, 21626.002978312, 10597.0827294981, -17148.7808624823, 16119.5924626482, -87318.8524332543, 74173.6611057026, -12561.2905707576, 26029.912096871 [...]
+14284.8803811757, 57841.9043127377, -65505.6401706253, -20442.1109589015, 273.510768781676, 36675.6451888950, -53336.4518895615, -2646.46687947811, 68131.6377169665, -38687.8062431709, -30378.0880994504, 15483.7777199083, 28592.2018088407, -125211.189022834, 118641.776356448, -73868.175187252, 85541.4293954646, -23915.7395952196, 9342.59171587624, -12191.9685672093, -31569.5413075041, -13962.3315314929, 13605.2229231787, 7253.55576166143, -23772.500453312, -31819.4532632076, -51118.34174 [...]
+54274.6301493697, -34056.2880685467, -20763.5566097897, 66204.2556155753, -38470.423550479, -32187.3908597053, -110144.717222395, 30175.0405993948, -3360.76227514367, -39367.3597853584, -180022.074888302, -3617.34416341195, 94114.2076993267, 69236.0748912026, -5742.90964011201, 21462.7293935095, -19463.7833996147, -25909.9615249236, -39521.4272268055, 16446.2615379853, -40804.3041025899, 26896.2147876595, -15623.4065095675, 59324.4513001744, 96249.0652714486, -101114.862589630, -30581.51 [...]
+31220.4566085781, 107642.152376193, 22026.4339945611, 122623.550258296, 32642.9121162381, -92040.8128901164, 40175.9641521465, 60281.3530364365, 114889.780636491, 96820.2534570651, -52723.0004345267, 94353.3923302764, 18855.7826874482, -36262.2116271326, -28008.1382376521, -24918.7994269121, 8521.67852553597, -31957.2219351856, 6336.11834122412, -41359.924767508, 4357.98087397624, 118678.919335156, 9893.05166446081, 99730.206497021, 35812.5801468931, 36316.3100280717, 36909.4763281825, - [...]
+-78272.0985765593, -10044.4277800678, 101450.021327789, -28742.1249950022, 15789.3111423353, -19275.0558772605, 57968.1411247834, 17512.6654041372, 52792.382837762, 66785.5333666793, 16915.3056655533, 20445.0701750676, 51344.2655194807, 28848.0311868511, 31964.8096259001, -12588.7762651038, -91482.709914699, 22974.5398179675, 80833.6786395278, -11992.9670765993, 43667.3301361787, 75015.7276984418, 29812.5414331797, -50173.2047735181, 40879.082349389, -38686.2576945508, 7227.49649809886,  [...]
+-66114.0869237768, -12390.5379397863, -57639.9310060177, 32421.6136854757, 12598.9213676228, 51934.2679125093, -85264.287498386, 47224.6297915804, 49133.6749828757, 110421.776513264, 3216.68335173271, 852.491965847155, 44109.2612739029, 59672.5290527608, -41059.8375545629, 5475.67676357013, -123038.940055864, -107198.602963887, 2154.12590366109, -151410.399137237, 33188.1657866489, -10682.2698147448, 30120.8550546516, -13151.5878294918, 32014.3623853809, -66395.1649547581, 30241.76355877 [...]
+7364.14374865393, 19814.9546388106, -34293.3217490159, 52075.9113148463, 13211.2938468980, 48445.6222849336, 22325.7396072017, 17285.4753962361, -35145.0597812043, -10723.6813431499, 64289.292426377, -33798.0569322803, 14842.7865981503, -97382.4506583999, 85131.369895747, -82597.280500819, 42601.7980160969, 12486.4506900897, 127192.358264741, 68196.9706257626, 59499.6817641309, 77344.620674785, -119502.665775819, 9716.86660210163, -23745.5079515714, 41141.038386717, 2206.3686795444, -221 [...]
+40959.0579321356, 20801.2125830934, -61581.3139971917, -17701.9763125642, -64346.1488227565, 39382.6485238552, -36740.9566236395, 76692.4566421025, 1103.15207510645, 8428.62350697089, -12702.9274383628, -20743.2903613288, 28941.3591527412, -8769.03677482915, 29626.6639227284, 53278.6931828149, 80845.1361005103, 26329.2238973173, -32513.0857444001, 31112.6007452964, 4701.51913639215, 66297.1141958323, -35553.7987557375, 87889.0164641836, 96960.1630417596, 120899.530822320, 12782.605190511 [...]
+-51764.1688028609, 93781.3699702882, -44295.8695793313, -4057.44526540287, -55150.2411786438, 1058.907844405, -30358.429533192, -16056.0905640967, -52348.1259198358, -7915.123423135, 14568.2255033372, 47840.3769267852, 43705.4148953739, 53707.3572526518, 111446.352350838, -1752.53607220422, -36975.76970203, -31674.1427212153, -86423.1351692575, 78793.6085825863, -72676.8366662104, 8214.64944818263, -85204.2643393243, -27830.4577508008, -11181.2156661853, -60607.1450545327, 75110.08187036 [...]
+-46028.1445623199, -75032.9590204014, -5446.76724642109, 56689.5342402751, 3357.14315753466, -24645.4847675379, -56971.0747935091, 24949.9601293306, 51454.0293830154, -48907.2442901284, 33722.7482073596, -10158.2417632072, 61203.324026852, 76771.5866719212, 65304.7438885023, 17160.9894118971, 3584.26602167275, 43085.0444164436, 78143.1181463051, 62949.3510482309, -4871.07743110231, -23790.6801738717, 1035.21076896516, -36142.03585793, -78390.0061677847, -36060.2832788122, -75078.98082700 [...]
+-8959.98695753082, -76658.0230242745, 34878.0391701572, 29152.5926775282, 50228.5479891442, -34186.6851288133, 6117.82057451804, 51844.9152245895, -20840.7238106590, 19993.5289391453, -57292.1654906026, 28145.1573072909, 22572.8957891273, 10130.3576545441, -13952.6601624216, 2141.73929536992, -39834.7373913196, -10390.8931524604, -20331.6449898122, -79337.4493196119, -38902.1637532514, 75887.8582244207, 55906.3778177033, -14799.1968802022, 24787.1254066088, 3435.20796933028, 5262.0158570 [...]
+-74458.5036874243, -26149.3172470139, -77508.1263157264, -15486.1407188924, -29653.5240840815, 16221.2904758867, -24752.2837054913, 95597.1500188286, 33301.7450151982, 8594.27079561046, -8002.75776800137, -16856.6754347205, 28347.6127686393, 34475.5420107003, 25256.3220631938, 70904.2196755456, 83041.0330945601, 50660.6921613702, 56842.0844236872, -59777.6949531461, -35211.1120888458, 8975.1990272908, -75024.0212305046, 1563.54885699465, 26648.6147157136, -7456.81470147855, -38636.769518 [...]
+4268.13252980859, 35865.9828430904, 50172.791424318, 32637.9537614227, -102648.316945464, -16404.0936955928, 40974.5024941524, 15516.4808563953, 68895.893646346, 58591.2528122679, -9807.48607297495, 29286.5784574217, 44312.7925104242, 13583.6161902048, -12052.4421915211, 3347.87518674291, 10674.9144654816, -9655.28809622736, -71765.6130161005, -7197.48493794108, -13501.0392761147, -22969.9094733894, -12410.7957554355, 58296.6601243873, -445.918746882336, 14079.8022542167, 9118.9856561221 [...]
+53761.880287972, 21230.8730958007, 145894.049947107, -59883.2705715996, 2740.06134802614, -73150.812309614, 21270.9513230376, 18778.6333284430, -36522.3133134376, -10877.2154897828, 32422.373494108, -45741.4825411424, -44789.3240990426, -28582.3588183459, -62110.4697539965, 35348.6608933493, 12116.9165560414, -42599.7261260834, 29041.7221970812, 3964.17088296807, 43655.7067781362, 75059.0559061654, 81963.5289957311, -5948.19616212956, 2484.30791269051, 29866.3718823415, 22821.7770123365, [...]
+-49529.1704462213, 16962.992929777, -72311.7756213808, -20831.6321669442, 25442.0564960531, 31128.1783884850, 41865.4699145270, 18043.9692363414, 8872.97089660677, 26590.7812119567, -99262.7026040387, -41991.5630009212, -42259.8536519197, 48064.4639815031, 53877.2562572878, -73217.1327639865, 26417.9287680809, -45304.5983538367, 21268.5066964708, 32835.5324945137, 30926.7596237813, 89043.886346168, 27774.7415360302, 91728.4127182177, 38264.536875906, -54478.9527719261, 97279.5306302417,  [...]
+81253.8870886358, 7604.77389993118, 9915.14315210162, 4104.3818619787, -16854.3187300693, 77835.6054895373, -17181.7731276479, 67076.6542096432, -42041.0845903644, 22075.2072159491, -16.4222958715039, 27847.2034206565, 68085.6338691613, 72632.3900463018, 54607.6285268721, 132045.806870152, 20010.9165812451, 81222.3968783015, 131207.877131982, 14362.0459683547, 4281.27066908509, -42047.153798381, -18976.0413594828, 2172.3452510256, -47924.0601064591, -6942.26835950765, 33571.6726661899, - [...]
+33960.173500588, -14535.4749177969, -12469.1704712516, 88406.3454964723, -6458.66589519509, 17751.1516887749, -58346.2899936207, 8644.29735826184, 32762.7943963733, 7479.58008239992, 7946.73218531419, 62538.9531951151, 47367.8059189167, 57618.6812630106, 29452.4614777456, 7983.35334942494, 67535.8912683926, 92754.279771944, 40220.3817469011, -16686.9448176587, -27085.5544329138, 46628.7611972689, 86079.558313317, 72331.480136436, -12490.7329381168, 57615.1570039448, -1102.80230862897, 31 [...]
+-27924.9199130778, -38460.2801212697, 11117.6612776460, 36753.4154705895, -43312.3038294688, -24967.9031959225, -73336.6452336605, -38107.49890944, -2208.64422373111, 24151.7575603502, 11385.6556982496, 62313.9333115422, -24016.7288530769, 10637.5817492556, -18251.3335110399, -53965.4773151714, -59173.4008102522, 32874.2463917002, -72157.303069804, -34531.6898629985, -29425.8811214873, -19774.7219082583, 93630.0424597085, 387.999571149518, 53409.0189107534, 16038.3117393297, 71799.728691 [...]
+-66156.3288212105, -97428.3137483337, -1031.44059542902, -17128.3302057355, 52291.9908890941, 53618.7130570024, -4222.05461976128, -10819.9762894444, -12202.4593138159, 46912.6669014137, -4499.15736001721, -6417.48013388923, 54016.9508005769, -9399.84110067107, 61344.5828079515, -43904.0240351448, 7533.69896783427, -72052.1358794266, -15738.2815809788, -21065.0138102524, -22520.4651708330, 4524.45398562214, 3770.62639757847, 20274.8533505102, -94582.8697529175, 11654.6753890903, -144937. [...]
+-68559.1730291, -14473.5675335304, 63698.3739328566, -30411.0406130914, -22612.6357963526, -52166.1811435472, -45716.9215773201, 103.760663780502, -29219.5866550368, -6238.34618564736, 84354.9798650435, -19879.4929277875, -34086.6781129772, -20093.5923825398, -15322.1860299921, -5900.73652136489, 120418.043918564, 5064.72345678179, 21213.7462396576, 20285.9941307341, 6582.29967782636, 34952.1639037482, 23820.4374797892, 38765.0535211452, 1474.83266582902, -137724.444313923, -85920.021780 [...]
+119632.641203648, 78434.6777474026, -56526.0918195893, 64740.5170994904, -8504.65059645516, 49835.9309576056, 18863.857298503, 53155.8811762822, -30916.9206016895, 3184.76362824477, -55250.4505692327, -88691.2094747071, 8687.00696236749, -21996.438136945, 12417.0931786658, -66948.3001341821, -67491.233925811, -69874.8491671896, -31170.3460213486, -12607.0035822309, -43598.7796670692, -11105.0027229576, -6713.61817438449, -90698.6072516962, -59020.9784622533, -64575.3946593718, 4193.72917 [...]
+5329.57764935246, 39743.4163921634, 101979.332077131, -17505.8077207899, -29219.0764633829, 26948.3715579139, 58824.979615691, 21948.1730736461, -110025.915072612, 35656.4543666241, 8766.49435479556, -21030.0718879859, 46536.0380233462, 20703.6283018096, -33569.3887319182, 54661.5739173949, 17545.7354879845, 67210.294394356, 7501.39502791619, 315.768290431025, 59336.6068039753, 55410.1863713089, 50525.521025318, -33672.563378099, 30563.1010737323, 33840.9327947579, 34584.9034493858, -759 [...]
+-79618.7188860514, 13612.6321254124, 8305.35231975836, -58700.8698117364, -71926.6109486006, -29104.2044220409, -3482.46269046265, 49104.7962051747, 2527.41204329699, 108197.414533184, -64871.6779381558, 57706.4261325637, 41344.0393279169, 17403.6503889756, -55525.8771699195, 14716.4722434725, -67901.2876860509, -8270.90103257771, 18881.2696675029, 58046.7585473221, -15522.4682870945, 69956.6756834581, 111722.990549415, -42154.7226342399, 18165.6378576771, 32137.2857961063, 122330.940035 [...]
+13331.9572807669, -7609.08134414988, 45.1139460884107, -97834.598908885, 32520.5445892927, 32661.7784214137, -71429.434256578, -27100.3598763107, 61903.8390396804, -72486.4715123623, -35481.2747274985, 33247.3391202021, 12316.2387666981, 78903.290775512, 56313.2518976783, -19668.4390997273, -32950.9078650097, 56299.0377080275, -76493.1077970465, 41747.4893047727, 121283.661504061, 42121.4372855199, -29392.1571043678, -83102.3976458124, -46629.6454974459, 92599.1079101729, -16995.49948145 [...]
+35240.6703386682, 18402.7760745915, 41911.0747866730, 30651.6369685749, -11408.1778838529, -75824.4065121075, 1402.69878374147, 46910.7974605214, 85600.8893670104, -23725.3197700700, -11748.1839717832, 15148.8526662038, 12180.452785047, 1955.31607779567, -83680.0652065166, 24638.2437220349, -45880.1462163943, 120560.76734439, -13083.907863756, -27014.1535551394, -52090.0232936622, -6558.5854514128, -90290.2110189632, 45742.1259470469, -80204.98416484, 33429.1597237031, 5736.54717732926,  [...]
+-86956.5257793582, -29170.9397324432, 84090.6165205755, 21100.1304913464, 41905.4866354987, -42718.7491957867, 36001.9108992025, 80204.9119789664, -40479.4762248691, 45588.2431328164, 22318.7897751352, -6492.45434577464, 52174.1023041984, -7360.04167394002, -3615.06987124795, -30559.3856550993, 106253.436931032, 6031.42014998873, -21478.298634946, 52410.3255388748, -140735.385783344, -4823.64922139536, -7403.49469289016, 14170.6221779770, -64014.918996846, -36997.0432458573, -7931.738091 [...]
+3160.67294722754, 45850.9685611007, 118359.199251280, 92781.9642045374, 41765.7536068416, -23062.5857851049, 23924.6501307798, -39676.0575402633, 29759.62252929, 76249.9567207002, -112549.464766009, -38235.4713464967, 34168.2779720199, 13366.5505276856, 25288.1763141038, -726.273510480878, -5302.57509914564, -50702.1051484343, 5103.46446731785, -16724.7381584381, 38849.4317693441, -53449.7659668702, 22279.0744999571, -1950.65104655529, 14577.8052245082, 8706.61246886926, -32759.306534731 [...]
+40656.5773790616, -60695.0979588315, 86614.96786225, 2889.50308786122, 1009.34596970528, -52437.5918859469, -14410.4698305826, 70240.9408689613, 9347.51576870461, 1771.64636857556, 26343.3011374093, -3609.95862313153, -56037.1550912085, -37720.6847115218, 38180.2568453605, 16895.1836190930, -22003.8260849024, 31379.0384180637, -3385.96999565181, -52923.3784194407, 79498.420416985, 2103.19189075850, 65754.3558451858, -35432.0548096992, 11085.9892179186, -30364.5886517401, -50637.124712610 [...]
+-65429.4380423461, 16146.8132880929, 66925.9903764669, -67446.4178630993, 95235.9292249399, -52190.6715820072, -11381.7121073209, 146460.751622384, 64397.1440818014, -106726.222536481, -53097.0062137909, -22278.0752689568, 49692.5988086305, -32780.0256567482, -31074.7505711829, -19205.9606278914, -18389.2860702161, -92417.9886141533, -61046.9300641363, -59211.38308112, -2361.16857217783, 15053.1380944054, -66357.1074791438, -39174.7343678875, 4386.34124636027, 21748.9748233829, 33198.551 [...]
+44705.7033794767, 48969.6165887002, -50415.4460926330, -17612.5459766273, -97432.1731474379, 11579.1051430081, -66654.5491961044, -60045.873913919, 19613.5193590321, -54138.2792853645, 30382.3361247991, -165672.901866482, -38021.9620521791, -93729.4052447031, 2060.15218887786, -48752.9268871975, -21372.5773200275, -19734.2968535912, 20426.0209205382, -76521.003178376, -38497.0419806146, 57797.3005029625, 75355.914607415, 47064.0174693925, 41548.8276535313, 29835.4888574586, 9757.43478435 [...]
+68883.0117583817, 16247.8509386420, 60023.5817579198, -69510.5146238961, -13138.0182138612, -77962.4729713467, 30589.6327283581, -15177.4798230538, -67523.7265287768, -26051.477907631, 44531.0489611879, 19821.8470018960, 58814.430260088, 68201.844543329, 2352.52756072312, -117401.380383303, 8982.41248605496, -32594.4737491465, -56044.6149705489, 25250.0768555282, 828.82433748866, 2293.61782165267, 7472.51488168773, -23198.9167225865, -10272.2846348039, 52437.9387870912, -32200.0496899806 [...]
+-34887.3730520105, -33269.1164411761, 65758.0907263613, -52577.6613729097, -99528.334380458, -26998.3713515012, 51364.3591891018, -21971.3967683634, 3156.8694195964, -45799.2225590449, -9165.67928498815, -49870.9564529671, 48801.0475109542, -27880.6794802288, -36002.5196343335, -52118.1518538895, 36107.3982889269, -25662.5676466835, -48877.0996695259, -31946.7773788111, 46607.4624960569, -74064.8221674506, 3787.50553398164, 57961.2985501666, 59500.0456481033, 25425.2689451237, -10244.439 [...]
+-5872.09496595676, -11880.6896530149, -56508.7736164342, -41616.5855717249, 64135.8405493353, -20845.0379801931, -40632.5922747623, -44938.701900335, 42664.3084131475, -89169.0416432768, 99928.6780979897, -43998.5571422732, -16966.9856934331, 86844.148593549, 3767.54393443098, 68803.4889020112, 1932.53916661557, 57894.7301281409, -24528.3310239024, -107922.277383204, 3639.17275671147, 35895.9394567355, -24478.3656092942, 34993.9912898144, 78232.7852004299, 15719.7773930205, 23644.5205330 [...]
+29000.5809522833, 53987.6878180158, -107271.750150820, 25217.4250572555, 57795.264253753, 20906.3917791226, 26363.6194468619, 43854.0829888217, -13603.6388644772, 77978.813962362, 40363.7802273969, 68794.1779967045, 12215.1852768986, -36760.7809184252, 89577.272664776, -27643.041416502, 9173.1911951113, -37858.6024092811, -18657.291243349, 48230.0624710856, 65690.9447783681, 138471.563440725, 10960.9517806092, -99128.6335858311, 55828.0460255348, 87432.2845415499, -10786.8536631956, 3767 [...]
+-56002.3068574058, 50810.979472774, -62373.3555748882, 46090.2883868241, 77037.3792242028, -16053.5688916884, -27377.6224832001, -5777.52935125007, 69636.5938838853, -10451.8113180205, -69.6521524801204, 8769.93485054904, 18636.0754401569, 52859.345203642, -43263.06560862, -32310.5292850191, -10246.0735033308, -28524.1373590609, 6244.27934734568, 18050.8389949114, -101764.815969941, -3378.18744094486, -81597.2765321677, 30185.3366460687, -22343.3135009790, -106545.365723593, 6350.1047018 [...]
+80970.1782855874, 25322.1023889700, 72059.9798565653, -2169.36811484693, -5224.07799116054, 36554.8732888117, 9213.6395236741, -109083.092822978, -47761.0673821992, 17436.5354351714, 81822.6352272202, 65872.2483926588, 32480.7449941130, -51707.911041083, -35299.1900788592, -29814.9604274467, 37092.7120108907, 54144.8045505855, -28163.5347359998, -57799.450104939, 28811.3966619528, -60460.4772560376, -82332.4347987687, -6700.28217693541, -50239.4566422381, 48111.1285630829, 77731.80227683 [...]
+52677.1536836709, 70990.2422792253, 9483.5093158717, -46155.7434818097, 47328.7795304135, 14640.1207693582, 13235.7684989285, -4887.08581114676, 77322.104302219, 59025.613063856, 95591.9087037323, -17805.4936086937, -4395.84378381467, 10230.8862119878, -1797.72653242021, 53378.5163456346, 995.051361592046, 88632.3324628508, 9621.44845566706, -10636.5098358202, -62242.0725956492, -27985.1574776879, -30525.6020001256, 28042.8093308133, -84335.2007459391, 24635.8903977891, 15692.2663978502, [...]
+-35522.1428906632, -15093.5034257588, 13761.2198219107, 37321.1990581213, -42651.250780101, -154351.664079287, -51835.4316351572, -4738.97330869239, 1031.41308631340, 38718.2037356131, -16489.4805789534, 947.336069483356, 34587.3937616822, -69181.3441986198, -3643.92195624521, 54860.6359815546, -31815.4035073151, -39409.547706875, 14333.4109470585, -49872.3065371615, -10807.2487376296, 64793.5467885983, 34337.0316110866, 49326.349920601, 99805.546830082, 82654.908964787, 137505.935519536 [...]
+-78838.4103681983, 65293.199563232, 4021.13765670117, 54135.559031692, -24436.1723609466, 993.359329214026, -90554.9930693648, 54623.9897948233, 39113.5889254376, -17953.7231368823, -15564.0604762621, 16489.7059379040, 23012.2431009553, -32608.3286048674, 24462.3647416093, 22093.2255288655, 50237.2134099469, 81440.8445250113, -30754.8911397773, -50761.3841850352, 53307.085522796, 69206.4202203437, 35944.6955446588, -14549.2481580179, -41473.1917888469, -24492.624725498, -102038.151568828 [...]
+-1632.53125135473, 35061.9693864890, -13147.3109050195, 33667.1817544617, -43301.4873575557, 7507.07401338553, -1325.74763312851, -5949.82836497795, 47747.3093039436, 81449.8981854882, 14444.0812403730, -86735.5183090451, 91583.4401428404, -20067.2861076683, -7519.98434649069, -37073.9962354474, -73859.9230168447, 18633.8779655372, -12124.5795819271, -9335.88934913182, 33028.2775763732, -41935.4262109785, 55264.6566284442, 5090.14643308881, 70511.0084065157, -2614.54217354473, -34823.630 [...]
+54890.447029956, 85390.1912161675, -76269.5330637937, -64330.1815244765, -29940.4848232112, -6865.26216494309, -8336.02440890616, 40016.3910967095, -48109.7579293234, 32924.3698872379, 18409.8987253696, -46335.1957770037, 42714.6323163821, 112614.120861763, 21047.1340584295, -18313.9937487644, -1172.16882731319, 11296.3418287178, -49312.502690395, -21899.2335091806, 12957.3483609705, 46367.2890552638, -54021.0301998581, 9211.0158034146, 58007.3434691989, 36671.5055032575, -33792.29483682 [...]
+-90441.8818171224, -46246.2819597683, 87544.7953839006, 56022.8747041788, -11569.1627354586, 68346.5043045766, 74051.6301735389, -71825.076792812, 18464.6557378233, -19999.7867789851, -80796.7412207804, 48692.6256706591, -43568.5407339259, -76809.1045240916, 59011.5380922763, -73434.3864098912, -9728.31580764926, -11238.5660039904, 73350.835585177, -9928.0720006869, 52526.8016546537, 81169.4527377195, -121351.189453513, 52832.1872365298, -16711.7109659961, -44538.7609517205, 68296.962494 [...]
+-7415.72370865925, 50852.2635082365, 38827.7712592261, 44338.6739789369, 8317.18655782156, -1221.23353182510, -46074.2974455090, -138466.764130098, -21374.9835814191, 741.278156459514, 29461.8244517174, 3407.96150267246, -58865.6608768706, 35970.3149583094, -21884.479477607, -110178.51070554, -70637.5109291822, -12303.1354545126, 2762.25331087398, -12843.1575125426, -27468.3055775736, -58545.1762969674, -37755.5097731661, -40682.495830488, -77805.602821965, 4820.21392922504, 53536.592606 [...]
+25112.6656353216, -50744.4387047801, -36191.423831082, 50509.2894380755, 49410.6962183105, -44504.363809335, -2855.07935753275, -15764.6913111974, 30518.6715221892, -1702.86392943431, 14880.7603593231, -1625.87956718095, -46771.4474955222, -11969.0122768754, -1174.47777928955, 35541.7896307911, 14651.1671509215, -12489.3506919444, 20729.7872871982, 26264.8951681122, -2616.71245557081, 47210.0414194701, -1341.00566553822, 41627.2581356476, 60773.2169298715, 18738.4934905618, -11129.290116 [...]
+21966.8767737935, 37947.0826017158, -24663.4669315068, 31358.0121580259, -67070.5237304378, 73338.377168209, 85379.9133288295, -35577.3492787271, -982.041329207302, -61210.4004453023, 69010.7609207424, -44395.6524679638, -40620.4423033946, -52689.0898635122, 22591.1441854147, 85069.0791820365, 5837.97561553521, -898.286871034188, 66528.3446066676, 53211.8787297086, -33658.1968407277, -73107.5066445434, -13865.2065470716, 34168.1393166832, -90056.5638685517, -6871.7340767097, 31894.883720 [...]
+57153.4495307733, 83467.1972141685, -4326.90965511635, 19691.5357054965, -21866.3089615506, 7680.20656512524, -9287.06451610225, 86753.5428485317, -52804.3999173011, 34709.9794751731, 67630.0925076825, 12031.7879649467, 14696.5574024973, 21278.5642833940, -27520.8344746519, -116787.410484711, -32763.6614015366, 1395.47334898361, 55235.427353603, -32418.3986991341, 18825.0678097278, 38437.9026084821, 12457.5879589490, -99053.5089770918, -3860.82385186801, -43771.6109205407, -92394.1230512 [...]
+-13099.7703358251, 9342.2172558561, -91077.2568989782, -58692.7255016433, 44978.272804688, -30948.7723468038, -91519.4139081863, 90628.8586258164, -62239.2041193009, 71908.1832339157, -92539.147585177, 50461.0289395644, -15590.9651337702, 55403.4968460253, -29123.230802174, 52336.2680651632, -38226.2163107520, 92466.2152197079, -21886.5159377194, 14243.0724367348, 54840.7736100297, 18344.7180755096, -13719.8486455580, 51980.0928597894, -53198.0253452596, 24818.8624073407, 32771.019793161 [...]
+-61849.7480951751, 15774.7003067180, -54368.589216172, -14953.1869819344, -27341.2371172711, -28100.7444898502, -2422.11988593672, -103401.805781579, -75676.4195443724, -21578.4453464638, -33601.4864276410, -44106.1941960647, -37654.8289993305, 9489.54762272998, -9202.30300524814, 76679.749534611, 59564.2432966018, 13235.4208940938, -63931.3749223162, 31854.0345442954, 4815.57777194068, -44030.5356254034, 22093.8640633120, 9398.23037297262, 29589.0432524009, -42724.2348273752, 26169.2438 [...]
+-41807.1941159319, -28513.4004628055, 1646.31704489907, -7920.25328106988, 22116.5654508912, -59134.3449182373, 53410.1826352897, 30930.5599448635, -41945.7914010983, 69716.8678915257, -34055.7021586771, -153997.119234815, 15416.9124287371, 28045.0941939222, -54848.3683634333, 5182.07002603102, -72436.7504173777, 24531.5751951972, -27100.520030686, 21928.5245120693, -49247.6280685988, -84459.0841913378, 784.126077377547, -41238.1356229635, -15938.8917677703, -54433.3908695306, 1092.20001 [...]
+46203.5996824905, 7251.62416811745, -94391.3635782386, 87414.0657015537, -70409.745051835, -46947.0560169039, -26618.3305333651, -33145.2876484362, -80435.7545455452, 64813.458414837, 66653.9477320274, 7172.69304829526, -32242.9989222393, -24047.5913432051, 48338.043397234, 13742.7292606461, -54423.4514959946, 9248.83494511512, -27317.7521226985, -83973.5820483376, -38265.4840926872, 10156.9636136374, 19367.1392600495, -12211.0980020451, 19677.3538258524, -20247.3539657220, -45290.104206 [...]
+65445.2495871715, -15130.6994746936, 14815.2521199437, 10426.4080305983, 17507.258557814, -80099.2801183454, -81313.8099357269, 18031.0957099681, 47893.6154966316, -69378.2868695003, 19381.6606261361, -87497.8008766907, 11528.4861306955, 31492.2225093757, 36693.9698891377, 30168.3233074526, 15397.4812523686, -98530.7995420042, 43970.4393645828, 23654.456178811, 8409.5229431255, -57008.0953726733, -85675.8581699455, 65390.5217667759, -18450.3663645439, -8241.53282671471, 23429.5017619588, [...]
+55126.8119305756, 43305.8932800555, -70184.8221734217, 16025.7486098235, -46568.5038375097, 56522.9422166805, 31413.2682471875, -41012.9668994501, 15834.6526991816, -27376.2600099749, 32516.5514560271, 7019.0717242868, -39572.9876455314, -5958.71971338873, 25929.9135602108, 63938.0618585916, 14082.6561503876, 1712.06880995206, 3573.67732551081, -52757.0163627225, -41870.9023061208, 40816.1841058796, 10403.6257606939, -7628.1683261465, -28753.2241239754, 34074.4989432908, -66146.700765199 [...]
+6980.71368988229, -53468.7253802304, 18383.5108207038, -128110.439878454, 21418.6006755673, 21184.5228257081, 41963.1957516402, 42483.1109676209, 24185.4881209387, 10684.8398149807, 25179.5625631279, 8329.53475163905, 14013.0682409335, -53795.2681085646, 12294.7015378437, -111846.251568545, 72172.2310122985, 3798.55404796493, -1467.01077212417, 55091.7479659715, -53039.6884131039, 8350.43922163821, -36519.2181990575, -79130.4056061308, -32306.488683824, 10584.9567170566, -9216.0494688500 [...]
+-31421.1407846124, -7155.48364033254, 24938.7454338727, -12929.2048964103, 74461.3249100945, 72680.9528279681, -116390.388631113, -52074.5991195226, 53458.8904902124, 49487.3486146609, -21733.1604068075, -54261.9437333024, -38288.5348843322, -4868.6134266845, -48147.8484164577, 596.244101159179, 10508.0547317186, -21211.9000933782, -5209.89163801941, -48924.0261968386, 43341.6650838133, 29425.8266495848, -49974.5843533446, 100435.950083267, 37933.3967495375, 4197.23627817918, 19374.45015 [...]
+24252.9338731881, 19675.4792839856, 21930.4979687481, -76278.431581691, 56457.6926078539, -4250.81133861975, -22397.2255908572, 6908.20211127171, 100437.801789427, 25551.8782674136, -106349.875640352, 8348.53584830187, 64571.8228959633, -23782.137308498, -88088.6441217228, -77122.6273693341, 19058.3057098338, -6562.28740511107, 24909.8759905122, -15295.6667184553, -20243.4719317527, 74060.9939373773, 13993.2716959378, 6767.48628060969, 110734.646914802, -28943.6941313442, -7091.679569941 [...]
+-31795.8726281682, 29211.7056659275, 4634.37966930431, 91748.0815520256, -5263.39007638947, -77514.9455667047, -60772.78450477, 35446.3499276239, -10867.0130897699, 14358.9349067989, -88711.423343134, 30265.2443452834, 2329.71612161451, -63360.6142212242, 23901.8839174028, 10841.4723006452, 9820.63808734028, 9267.59622902025, 39639.1063976259, -91663.2868306461, 27774.3359176815, -18249.1621488771, -11991.3985868838, -79966.3325941925, 24307.2180318459, -44249.8162733478, 29190.646835798 [...]
+32823.2746900788, 14611.8134859936, -35669.7785013505, -19097.8053520151, -102132.642912728, 18405.1488337965, 24566.6962126459, -21436.5462394402, -43291.2052860269, 4029.11864896828, -116361.006615425, 22448.2440702284, 38870.0919667387, 25573.2054185177, 21327.1815228011, -40407.1885717375, 29604.1718042966, -60439.4605841884, 45704.5413087633, -12747.6538610035, 43548.5731958364, 3109.19242522842, -131399.189625091, 27447.3680612509, -12183.6802386499, 101545.158152840, -27136.192860 [...]
+38302.1039332916, -42380.1548736852, -27575.2633417847, -12157.4969300901, 71672.192694014, -95259.7135548462, 34295.9418012159, -9270.76397110053, 92996.2659414943, 11268.7349930656, 5771.58310696545, -54387.0778420368, 11614.1277832199, -15119.2717511027, -24697.3304429174, -69196.4183149898, -65808.5715192295, -33363.2354519705, -101894.566876850, 3048.34196113246, -32615.8889093726, -40054.1881259044, 1921.32198747883, 11550.3834582961, 17679.2094702317, -38013.4789288294, -72529.842 [...]
+40824.297185854, 59411.7991180413, 95467.4763499747, 16958.2315969, -31525.2931975373, 92664.7925538121, 74502.2702387554, 8704.97623578949, -2046.79199869378, 36170.6826482258, 76507.3005334195, -33112.9976967333, 26675.5210565077, 8965.87662808664, -67089.141715706, -44006.3005834853, 18110.0617625832, 94043.1469404855, 1185.52061861014, -21619.711341754, -65265.9060851392, 29314.4115339212, -42642.9959273549, 77223.4314422489, -741.852609695735, -31327.352098579, -422.675409255058, 37 [...]
+-104960.760778699, 73550.6718033666, -15360.1661670186, 7340.772309247, -27974.3747932960, -25875.1348112248, -65124.2462029549, -36836.1671829814, 17920.4195910438, 31182.0981330855, 12436.1194990957, 44346.287585188, -26444.4428465019, 68132.9831370899, -33721.4383938477, 92553.6996798783, -15878.0485468701, -23457.7172601220, 64335.340323226, 37630.8424494192, -17055.3127195606, 24794.8645829913, -45184.5775615209, 97857.4316481984, -25289.750036866, 79031.6393578836, 17445.8407702518 [...]
+743.545489709588, 63843.3740719568, -6403.15279834958, -20799.1400357835, -62213.0166325828, -21811.6834100417, 54865.3007268042, -39533.385563393, -17655.0243819411, -22786.4727922062, -15073.2784877071, 18789.3748421173, 31871.6119657451, -54161.8302555691, -69110.5892296514, 51234.2415848413, 3645.12284756206, -24311.9850344753, 55273.0634102857, -85524.7204282798, 17925.1114994961, -13635.067459284, 83365.8856633459, -42319.7396734719, 32892.8570142104, -37947.0938650012, 38611.94790 [...]
+-3036.06450170921, -15953.3572684508, 64350.9353269823, 65862.9108636105, -40256.0420111806, -49266.1473130722, 2171.09831296544, -88588.5713405856, 61663.0494417706, 1699.45957614554, -47054.3650961402, -42798.2046962793, 69165.4365359624, 4472.11814926317, -68979.4645020188, -130692.193719141, -41848.156729475, -90659.5626710766, -12809.6685311531, 7316.10574726535, -59219.0555094327, -37754.9634012336, 84649.4310533113, -21367.2104070262, -26831.6970170800, 41702.8054268878, -114668.9 [...]
+13980.1227694832, -69403.4137600685, 70309.0704971196, -87620.023466002, -59186.5992379001, -90881.5495330359, -8390.45398729775, -17747.8271503338, 23406.8624527607, -64044.1431964754, -20853.9008306984, -73735.9997661789, 9912.86137362564, 36890.7519853708, -90064.2355898929, -61629.81678561, -7810.97485535246, -36140.6242520842, -26181.5848934465, -65886.6428926253, -53411.3991617583, -73038.9381605595, 45574.747356529, -89818.2322804814, 941.654064552552, 15812.664937112, 11679.00725 [...]
+20725.7411276999, 6919.68702867309, -44351.7160853337, -100641.383980046, -77821.3406774784, -41437.423265642, -19488.3357255681, 19074.68836818, 12853.6041231714, 53034.9654312758, -11186.9599555721, -29811.6847010364, -33293.3590293165, 6454.5904121781, -21925.6037420641, -57622.3507439507, 69692.6060927448, 26633.8114536156, -10320.1715795430, 2555.69437208395, -48133.5567192327, 104704.320116686, -14002.0861630217, 86775.108478016, -37555.2097233975, 13194.7106004386, -38776.19295492 [...]
+165241.381254402, -46629.6329068042, 14495.6786937150, -48148.8949528795, -64401.1568287286, 21412.9428770597, 35117.6350216261, 23446.2588813049, 122261.395888100, -24032.598856899, -5575.522363908, 60927.8323138332, -34440.704287171, -54020.4005154803, 2425.29249803321, -6002.74135201128, -48781.1841664667, 97984.381131947, 22115.17014937, 16800.8601571862, 42874.9823840886, 70107.6819790306, -22121.3613996705, 52492.2874507873, 12439.0310995931, -47775.223934818, -28993.1459259428, -3 [...]
+
+double y19[100] = {
+384096301.769827, -20938627.6988365, -250438582.352073, -784806091.315518, -300474137.573147, -724304620.29884, -139743307.242323, 149592521.133324, -10841274.8248467, -112881515.310515, 413935458.169942, 291326824.9718, -221617579.696090, -465192212.05469, -88718848.8727818, 91651383.285481, 322855057.915029, 618210893.700009, 179059085.235713, 55425607.3823115, 211593746.956804, -21231262.8421962, -546584051.48565, 183442219.985713, -408414097.495267, 596743192.304029, -397836241.4788, [...]
+
+double lars19[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -155.97023326945782000, -169.13025527795799000, -202.66265820180249000, -235.5306834881885700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 25.41543750181758600, 48.89562496543172900, 50.5520 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 114.28402007528709000, 165.58220364241566000, 297.35028831804090000, 353.45441548552463000, 365.11900375050226000, 476.19457197965409000, 516.29358853642577000, 570.82402154882288000, 604.76556986762932000, 641.82259742676479000, 662.84830788490524000, 668.07385429171427000, 686.97308255890061000, 694.37601494487399000, 720.59579198813196000, 739.04176955470973000, 743.04403643306136000, 747.7024560187154 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 8.92908675312713560, 49.53670124049588000, 69.68989380130858500, 197.71773098678941000, 352.22443891635464000, 363.82738768773538000, 391.20720813977164000, 419.1922995104712300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.5797850 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -116.72507411910340000, -157.18678556722799000, -202.30306007188145000, -265.98350966405178000, -327.89655956397104000, -358.39242957406327000, -364.68315321606428000, -393.13899349104918000, -407.88353178135759000, -499.21027035212097000, -607.29420442804019000, -618.24420483383437000, -640.3495928906 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 102.47822958442549000, 191.86689832255317000, 272.41685906789832000, 313.10938839897534000, 322.61107468968441000, 358.09936433654804000, 377.43778482738895000, 505.46690759072970000, 644.60808248018282000, 654.14568184722407000, 675.11470763020225000, 697.3190 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 13.02134609272963100, 42.06674680641546600, 65.27976695782796000, 66.901 [...]
+0.00000000000000000, 0.00000000000000000, 57.18937874084247900, 201.51264267498510000, 327.08963400058730000, 381.62705391739541000, 531.93456351222528000, 597.74372474978679000, 614.04023049523198000, 760.82551451116876000, 819.40011503223718000, 884.91375375161010000, 955.35257751370796000, 1012.95513212402000000, 1048.39119877436470000, 1056.92371277775030000, 1088.27750064962130000, 1106.60237495481100000, 1246.23348640021190000, 1399.65348622559990000, 1410.27001393807110000, 1439.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -35.71210237177900400, -45.20839259556165500, -82.89367550579112300, -104.01028023263805000, -241.45830517376854000, -389.87823400784418000, -404.83495921079214000, -444.59532731956125000, -484.9646 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 26.54341902315678300, 41.31078847558654100, 124.42339177584716000, 213.01648617628899000, 221.31066924231962000, 241.73158654582701000, 259.2813595229193900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -142.99211176915878000, -294.41022167211611000, -354.07895030238649000, -520.11931199851642000, -579.63805773722538000, -595.61967572365108000, -753.63705147400947000, -808.58197581664740000, -909.98206933424706000, -999.19638977156126000, -1087.16998176773290000, -1128.66530227925450000, -1137.34470499038070000, -1173.56292080542020000, -1191.32090134551910000, -1296.93599928481330000, -1416.00657455887630000, -1425.97270792 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+263.30762462890840000, 529.48073255670340000, 572.75006064781621000, 682.59623698821940000, 797.97059226455724000, 847.04974497236242000, 993.32395820178363000, 1067.44231872970020000, 1082.12579392007640000, 1224.28027316312800000, 1277.06227089061870000, 1340.78655778282650000, 1393.04032514101390000, 1454.77779468678110000, 1485.41792007644720000, 1492.78230958125640000, 1526.78170866679600000, 1546.83531625225030000, 1685.27564781130670000, 1850.09510491659990000, 1861.92239117836080 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 18.96186819389695800, 172.82866139902993000, 230.90824410314619000, 329.77272928595141000, 420.00573054035493000, 516.77227385285130000, 560.97900346914912000, 569.10477018759775000, 606.89621316150522000, 629.91600818179427000, 795.47932056582590000, 957.67724392587286000, 969.82426484707537000, 998.45335119663650000, 102 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -72.20804027313555200, -103.87149389598086000, -110.11238799279354000, -140.31030252658164000, -154.10800540547331000, -234.68256538132334000, -314.43700507541013000, -323.44090335651640000, -340.02715950512794000, -356 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -53.69337825133725100, -131.48729335858380000, -179.73744321124033000, -224.44447936954890000, -246.91351543242428000, -251.76284858182910000, -269.37360492692483000, -280.79886759897710000, -364.03029769084702000, -480.05105902560018000, -489.37893700382767000, -515.53292568908398 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 287.67517060139130000, 347.19639550355777000, 483.80793544261007000, 601.99410160964942000, 660.90895828976807000, 826.47387400642958000, 896.57552777929652000, 914.54624853006317000, 1063.46993827568120000, 1119.81285515739360000, 1201.09556293164500000, 1258.76912788629030000, 1312.54927795946450000, 1332.91739050686870000, 1337.24898255196580000, 1356.26937721162810000, 1369.04888445709500000, 1467.11584643967880000, 1537.36766548775540000, 1540.85179079603540000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 53.87971689373704000, 215.94326538449960000, 279.01357240950284000, 291.89985032377058000, 412.16227955348597000, 446.35871591423034000, 477.19340011816377000, 516.56084588782198000, 563.29464501408779000, 590.75691536331806000, 597.99683297894933000, 628.97436520371900000, 645.33386601334882000, 742.34196342475695000, 821.87775422218363000, 829.27095896645130000, 844.6718455054926800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 81.99952972741464000, 194.81401137797434000, 205.14584052207329000, 232.28721038438212000, 253.57094516603809000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -17.45205174592693400, -136.90428380235298000, -278.43149110282462000, -289.98697811926553000, -316.64109188691793000, -338.05937839799 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -81.21588661799648900, -156.04191826925853000, -194.95061085237865000, -203.80057722558996000, -238.40957453965413000, -257.32916086048840000, -384.78376625930059000, -533.10395555268997000, -543.82828398408139000, -569.10756552686018000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 127.50312000788777000, 164.39248103047493000, 173.03503166315312000, 241.73957047418941000, 264.73689649729448000, 299.48427343090134000, 340.55922258991137000, 390.85814206038248000, 411.02294466445676000, 416.24274041060846000, 442.01032274694262000, 453.03248646350738000, 513.69702726598746000, 582.90463615124327000, 588.46363290964473000, 602.49653254757038000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 31.31933070833635200, 33.55476 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 90.25908217939878900, 107.07199479242530000, 272.24512176244036000, 335.20362864355212000, 401.15257078953300000, 447.45519076819892000, 511.61709601741870000, 543.71637303205216000, 552.79197932340071000, 597.26081411029247000, 619.93912025461407000, 761.19714703789134000, 915.82000249046223000, 927.69733779965463000, 953.12446082365000000, 9 [...]
+
+double larslsq19[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -772.25316484168320000, -778.64791220964571000, -819.22955505044649000, -861.7614330586808400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 492.73409247966725000, 496.26096764347676000, 554.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1601.09851165902270000, 1581.25307978410770000, 1391.11267776249470000, 1422.17058262171620000, 1335.83744734699920000, 1350.02848424150780000, 1326.73259342811070000, 1333.67950153068610000, 1109.23252575654990000, 1136.07790497375500000, 1200.42181988670540000, 1242.26872663403450000, 1143.26065275062090000, 1014.39287406746600000, 865.14297774492184000, 811.92709447954019000, 928.41244452026422000, 833 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 990.07735895381666000, 1029.93386263644080000, 940.87999096118347000, 903.52325836247746000, 962.72456393637731000, 901.22786802602195000, 894.64535931326918000, 952.38906424372 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 786.66541 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1035.00377215039130000, -974.95619683960729000, -833.45882651181535000, -1212.45425559641280000, -1153.67389614672920000, -1138.09364231137170000, -1055.92211223723830000, -1080.15361828289560000, -1045.26620487150440000, -1002.68606356617120000, -1034.36469314808440000, -1125.40282405421180000, -1046 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1536.10115716223850000, 1520.43415122835900000, 1346.76761635830260000, 1353.51303841090180000, 1366.67788072192210000, 1214.89971746747730000, 1213.40659599696820000, 1211.27952223727520000, 1194.39459857220940000, 1095.88774088004770000, 1060.6763146022015000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 616.11610956734614000, 576.13025029092705000, 507.55480120623741000, 559 [...]
+0.00000000000000000, 0.00000000000000000, 2214.07125819365270000, 2218.51862057936840000, 1960.82364501447550000, 1886.69081382815780000, 1779.58646078760220000, 1851.32912231419870000, 1970.22343507319510000, 1915.58853791067490000, 2003.24812514524550000, 1801.41919025279480000, 2002.27178891494210000, 1781.24039998527020000, 1954.40057423308350000, 1994.49567320451480000, 1845.25781127964910000, 1898.75721484965860000, 2016.00678272635810000, 2005.85971719823260000, 1901.9835606081494 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -948.77900354430187000, -1088.68226657461810000, -992.73644410980614000, -1016.84713564184270000, -999.19644918205506000, -976.32775663939537000, -1097.56845883439040000, -1175.67704663623270000, -1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 667.38610314932419000, 679.68041597937133000, 582.61542323944968000, 563.07310140128334000, 605.46284051559803000, 617.21501495450582000, 593.65518911798938 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2141.39442314686220000, -2264.33252527699410000, -2000.75092705448560000, -1898.36430356873170000, -1713.39860317339430000, -1925.59815293368090000, -1996.76318495840000000, -1919.07080152268530000, -2328.52237311266440000, -2325.17233612441990000, -2260.53486373766100000, -2189.59426462889590000, -2091.05712925068340000, -2047.98601667418760000, -1958.96983564757280000, -1879.18218525984430000, -1886.48842007305170000, -188 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+2541.28786697336360000, 2448.62323087718410000, 2204.64101226553570000, 2217.76380657446820000, 2298.97014818657950000, 2201.48224691912860000, 2207.49682388292560000, 2479.30797241590290000, 2304.07378381914800000, 2342.61265464808590000, 2343.83630645581120000, 2232.25979168517690000, 2169.67840615356320000, 2278.21329416989510000, 2268.80737303645580000, 2301.99810490613980000, 2347.63550107559560000, 2413.72051511392460000, 2448.48428566827810000, 2501.34384690898060000, 2409.7132539 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1596.95457249934070000, 1383.30207168350240000, 1404.75147650779190000, 1712.84104785482670000, 1761.12214149407900000, 1807.41485301963170000, 1691.23174528536860000, 1461.98241787307420000, 1519.30202385497750000, 1625.02471861617600000, 1708.21442240139190000, 1598.56755746771360000, 1532.42391139853040000, 1524.8620004 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1035.29681191331570000, -913.42482623291028000, -795.87596375049998000, -869.38414896521647000, -750.56050668401042000, -678.88260067855526000, -629.56957152901771000, -740.46414085614560000, -645.00191801294125000, -6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1138.88727515597290000, -1219.78810394109220000, -896.87049762370361000, -820.73326347878231000, -821.38916283859703000, -784.61855627195462000, -694.55335874225966000, -774.69459490407723000, -822.87741017559233000, -938.48221873987325000, -921.40757082841878000, -996.43146673626 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2361.85031891310750000, 2592.02321931085630000, 2393.03784887866320000, 2139.57481014718220000, 2286.77640572021440000, 2200.77234899916310000, 2231.92774716945000000, 2410.05639267015110000, 2235.05584608227540000, 2258.55643071769600000, 2338.20296567783770000, 2115.96065829773990000, 2029.85248237654420000, 1853.67780983989410000, 1813.21412528474890000, 1815.48229006973110000, 1921.48642631248910000, 2007.74986277451440000, 1814.95266413575220000, 1702.2220296138 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1540.79291181044660000, 1561.17807300475010000, 1480.42709021804330000, 1364.28640667119130000, 1358.26942721276620000, 1137.50099906240080000, 908.55633855536996000, 1101.67191218345470000, 1186.61577413410260000, 1292.89676212711020000, 1393.53537525642810000, 1376.87066602342000000, 1352.52877107973470000, 1277.13855812139720000, 1136.14637644621510000, 1171.69354990373040000, 1127 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 534.05529038178406000, 640.57624445288320000, 683.67332988813519000, 731.34092360114039000, 659.08752457236540000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -771.87617637504877000, -795.43329980568012000, -837.64590262248953000, -825.18922674896407000, -806.73553132496056000, -746.1395566100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1288.31259025597360000, -1154.04865875317300000, -1189.74612850910170000, -1176.25492291435920000, -1073.98100994181750000, -1075.19244457277070000, -1087.42912025088300000, -1119.15937877668530000, -1040.53471300414820000, -1033.922694069 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1185.86347748561620000, 867.09045550340591000, 892.26172944950724000, 782.23967231060453000, 729.53458027459078000, 785.58396940747946000, 951.04859599474275000, 1061.72975669506100000, 926.58524997996210000, 989.80571713761265000, 1064.12183797609580000, 929.50289432423426000, 848.13498353690841000, 856.36366225415247000, 845.93331471436591000, 860.52222200365554 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 628.04297852819343000, 712.979 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1809.58607693039720000, 1506.23019851941630000, 1571.66570580093620000, 1607.65452763144460000, 1323.74770044183060000, 1135.64246881811460000, 1367.38897791343860000, 1364.41259216001320000, 1550.04015017489950000, 1670.88013270422580000, 1600.28581587990490000, 1539.93947590640350000, 1526.77905954175890000, 1477.80626494087480000, 1420.6579 [...]
+
+double lasso19[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -155.97023326945782000, -169.13025527795799000, -202.66265820180249000, -235.5306834881885700 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 25.41543750181758600, 48.89562496543172900, 50.5520 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 114.28402007528709000, 165.58220364241566000, 297.35028831804090000, 353.45441548552463000, 365.11900375050226000, 476.19457197965409000, 516.29358853642577000, 570.82402154882288000, 604.76556986762932000, 641.82259742676479000, 662.84830788490524000, 668.07385429171427000, 686.97308255890061000, 694.37601494487399000, 720.59579198813196000, 739.04176955470973000, 743.04403643306136000, 747.7024560187154 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 8.92908675312713560, 49.53670124049588000, 69.68989380130858500, 197.71773098678941000, 352.22443891635464000, 363.82738768773538000, 391.20720813977164000, 419.1922995104712300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 2.5797850 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -116.72507411910340000, -157.18678556722799000, -202.30306007188145000, -265.98350966405178000, -327.89655956397104000, -358.39242957406327000, -364.68315321606428000, -393.13899349104918000, -407.88353178135759000, -499.21027035212097000, -607.29420442804019000, -618.24420483383437000, -640.3495928906 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 102.47822958442549000, 191.86689832255317000, 272.41685906789832000, 313.10938839897534000, 322.61107468968441000, 358.09936433654804000, 377.43778482738895000, 505.46690759072970000, 644.60808248018282000, 654.14568184722407000, 675.11470763020225000, 697.3190 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 13.02134609272963100, 42.06674680641546600, 65.27976695782796000, 66.901 [...]
+0.00000000000000000, 0.00000000000000000, 57.18937874084247900, 201.51264267498510000, 327.08963400058730000, 381.62705391739541000, 531.93456351222528000, 597.74372474978679000, 614.04023049523198000, 760.82551451116876000, 819.40011503223718000, 884.91375375161010000, 955.35257751370796000, 1012.95513212402000000, 1048.39119877436470000, 1056.92371277775030000, 1088.27750064962130000, 1106.60237495481100000, 1246.23348640021190000, 1399.65348622559990000, 1410.27001393807110000, 1439.6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -35.71210237177900400, -45.20839259556165500, -82.89367550579112300, -104.01028023263805000, -241.45830517376854000, -389.87823400784418000, -404.83495921079214000, -444.59532731956125000, -484.9646 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 26.54341902315678300, 41.31078847558654100, 124.42339177584716000, 213.01648617628899000, 221.31066924231962000, 241.73158654582701000, 259.2813595229193900 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -142.99211176915878000, -294.41022167211611000, -354.07895030238649000, -520.11931199851642000, -579.63805773722538000, -595.61967572365108000, -753.63705147400947000, -808.58197581664740000, -909.98206933424706000, -999.19638977156126000, -1087.16998176773290000, -1128.66530227925450000, -1137.34470499038070000, -1173.56292080542020000, -1191.32090134551910000, -1296.93599928481330000, -1416.00657455887630000, -1425.97270792 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+263.30762462890840000, 529.48073255670340000, 572.75006064781621000, 682.59623698821940000, 797.97059226455724000, 847.04974497236242000, 993.32395820178363000, 1067.44231872970020000, 1082.12579392007640000, 1224.28027316312800000, 1277.06227089061870000, 1340.78655778282650000, 1393.04032514101390000, 1454.77779468678110000, 1485.41792007644720000, 1492.78230958125640000, 1526.78170866679600000, 1546.83531625225030000, 1685.27564781130670000, 1850.09510491659990000, 1861.92239117836080 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 18.96186819389695800, 172.82866139902993000, 230.90824410314619000, 329.77272928595141000, 420.00573054035493000, 516.77227385285130000, 560.97900346914912000, 569.10477018759775000, 606.89621316150522000, 629.91600818179427000, 795.47932056582590000, 957.67724392587286000, 969.82426484707537000, 998.45335119663650000, 102 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -72.20804027313555200, -103.87149389598086000, -110.11238799279354000, -140.31030252658164000, -154.10800540547331000, -234.68256538132334000, -314.43700507541013000, -323.44090335651640000, -340.02715950512794000, -356 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -53.69337825133725100, -131.48729335858380000, -179.73744321124033000, -224.44447936954890000, -246.91351543242428000, -251.76284858182910000, -269.37360492692483000, -280.79886759897710000, -364.03029769084702000, -480.05105902560018000, -489.37893700382767000, -515.53292568908398 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 287.67517060139130000, 347.19639550355777000, 483.80793544261007000, 601.99410160964942000, 660.90895828976807000, 826.47387400642958000, 896.57552777929652000, 914.54624853006317000, 1063.46993827568120000, 1119.81285515739360000, 1201.09556293164500000, 1258.76912788629030000, 1312.54927795946450000, 1332.91739050686870000, 1337.24898255196580000, 1356.26937721162810000, 1369.04888445709500000, 1467.11584643967880000, 1537.36766548775540000, 1540.85179079603540000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 53.87971689373704000, 215.94326538449960000, 279.01357240950284000, 291.89985032377058000, 412.16227955348597000, 446.35871591423034000, 477.19340011816377000, 516.56084588782198000, 563.29464501408779000, 590.75691536331806000, 597.99683297894933000, 628.97436520371900000, 645.33386601334882000, 742.34196342475695000, 821.87775422218363000, 829.27095896645130000, 844.6718455054926800 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 81.99952972741464000, 194.81401137797434000, 205.14584052207329000, 232.28721038438212000, 253.57094516603809000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -17.45205174592693400, -136.90428380235298000, -278.43149110282462000, -289.98697811926553000, -316.64109188691793000, -338.05937839799 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -81.21588661799648900, -156.04191826925853000, -194.95061085237865000, -203.80057722558996000, -238.40957453965413000, -257.32916086048840000, -384.78376625930059000, -533.10395555268997000, -543.82828398408139000, -569.10756552686018000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 127.50312000788777000, 164.39248103047493000, 173.03503166315312000, 241.73957047418941000, 264.73689649729448000, 299.48427343090134000, 340.55922258991137000, 390.85814206038248000, 411.02294466445676000, 416.24274041060846000, 442.01032274694262000, 453.03248646350738000, 513.69702726598746000, 582.90463615124327000, 588.46363290964473000, 602.49653254757038000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 31.31933070833635200, 33.55476 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 90.25908217939878900, 107.07199479242530000, 272.24512176244036000, 335.20362864355212000, 401.15257078953300000, 447.45519076819892000, 511.61709601741870000, 543.71637303205216000, 552.79197932340071000, 597.26081411029247000, 619.93912025461407000, 761.19714703789134000, 915.82000249046223000, 927.69733779965463000, 953.12446082365000000, 9 [...]
+
+double lassolsq19[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -772.25316484168320000, -778.64791220964571000, -819.22955505044649000, -861.7614330586808400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 492.73409247966725000, 496.26096764347676000, 554.0 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1601.09851165902270000, 1581.25307978410770000, 1391.11267776249470000, 1422.17058262171620000, 1335.83744734699920000, 1350.02848424150780000, 1326.73259342811070000, 1333.67950153068610000, 1109.23252575654990000, 1136.07790497375500000, 1200.42181988670540000, 1242.26872663403450000, 1143.26065275062090000, 1014.39287406746600000, 865.14297774492184000, 811.92709447954019000, 928.41244452026422000, 833 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 990.07735895381666000, 1029.93386263644080000, 940.87999096118347000, 903.52325836247746000, 962.72456393637731000, 901.22786802602195000, 894.64535931326918000, 952.38906424372 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 786.66541 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1035.00377215039130000, -974.95619683960729000, -833.45882651181535000, -1212.45425559641280000, -1153.67389614672920000, -1138.09364231137170000, -1055.92211223723830000, -1080.15361828289560000, -1045.26620487150440000, -1002.68606356617120000, -1034.36469314808440000, -1125.40282405421180000, -1046 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1536.10115716223850000, 1520.43415122835900000, 1346.76761635830260000, 1353.51303841090180000, 1366.67788072192210000, 1214.89971746747730000, 1213.40659599696820000, 1211.27952223727520000, 1194.39459857220940000, 1095.88774088004770000, 1060.6763146022015000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 616.11610956734614000, 576.13025029092705000, 507.55480120623741000, 559 [...]
+0.00000000000000000, 0.00000000000000000, 2214.07125819365270000, 2218.51862057936840000, 1960.82364501447550000, 1886.69081382815780000, 1779.58646078760220000, 1851.32912231419870000, 1970.22343507319510000, 1915.58853791067490000, 2003.24812514524550000, 1801.41919025279480000, 2002.27178891494210000, 1781.24039998527020000, 1954.40057423308350000, 1994.49567320451480000, 1845.25781127964910000, 1898.75721484965860000, 2016.00678272635810000, 2005.85971719823260000, 1901.9835606081494 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -948.77900354430187000, -1088.68226657461810000, -992.73644410980614000, -1016.84713564184270000, -999.19644918205506000, -976.32775663939537000, -1097.56845883439040000, -1175.67704663623270000, -1 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 667.38610314932419000, 679.68041597937133000, 582.61542323944968000, 563.07310140128334000, 605.46284051559803000, 617.21501495450582000, 593.65518911798938 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2141.39442314686220000, -2264.33252527699410000, -2000.75092705448560000, -1898.36430356873170000, -1713.39860317339430000, -1925.59815293368090000, -1996.76318495840000000, -1919.07080152268530000, -2328.52237311266440000, -2325.17233612441990000, -2260.53486373766100000, -2189.59426462889590000, -2091.05712925068340000, -2047.98601667418760000, -1958.96983564757280000, -1879.18218525984430000, -1886.48842007305170000, -188 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+2541.28786697336360000, 2448.62323087718410000, 2204.64101226553570000, 2217.76380657446820000, 2298.97014818657950000, 2201.48224691912860000, 2207.49682388292560000, 2479.30797241590290000, 2304.07378381914800000, 2342.61265464808590000, 2343.83630645581120000, 2232.25979168517690000, 2169.67840615356320000, 2278.21329416989510000, 2268.80737303645580000, 2301.99810490613980000, 2347.63550107559560000, 2413.72051511392460000, 2448.48428566827810000, 2501.34384690898060000, 2409.7132539 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1596.95457249934070000, 1383.30207168350240000, 1404.75147650779190000, 1712.84104785482670000, 1761.12214149407900000, 1807.41485301963170000, 1691.23174528536860000, 1461.98241787307420000, 1519.30202385497750000, 1625.02471861617600000, 1708.21442240139190000, 1598.56755746771360000, 1532.42391139853040000, 1524.8620004 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1035.29681191331570000, -913.42482623291028000, -795.87596375049998000, -869.38414896521647000, -750.56050668401042000, -678.88260067855526000, -629.56957152901771000, -740.46414085614560000, -645.00191801294125000, -6 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1138.88727515597290000, -1219.78810394109220000, -896.87049762370361000, -820.73326347878231000, -821.38916283859703000, -784.61855627195462000, -694.55335874225966000, -774.69459490407723000, -822.87741017559233000, -938.48221873987325000, -921.40757082841878000, -996.43146673626 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 2361.85031891310750000, 2592.02321931085630000, 2393.03784887866320000, 2139.57481014718220000, 2286.77640572021440000, 2200.77234899916310000, 2231.92774716945000000, 2410.05639267015110000, 2235.05584608227540000, 2258.55643071769600000, 2338.20296567783770000, 2115.96065829773990000, 2029.85248237654420000, 1853.67780983989410000, 1813.21412528474890000, 1815.48229006973110000, 1921.48642631248910000, 2007.74986277451440000, 1814.95266413575220000, 1702.2220296138 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1540.79291181044660000, 1561.17807300475010000, 1480.42709021804330000, 1364.28640667119130000, 1358.26942721276620000, 1137.50099906240080000, 908.55633855536996000, 1101.67191218345470000, 1186.61577413410260000, 1292.89676212711020000, 1393.53537525642810000, 1376.87066602342000000, 1352.52877107973470000, 1277.13855812139720000, 1136.14637644621510000, 1171.69354990373040000, 1127 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 534.05529038178406000, 640.57624445288320000, 683.67332988813519000, 731.34092360114039000, 659.08752457236540000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -771.87617637504877000, -795.43329980568012000, -837.64590262248953000, -825.18922674896407000, -806.73553132496056000, -746.1395566100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1288.31259025597360000, -1154.04865875317300000, -1189.74612850910170000, -1176.25492291435920000, -1073.98100994181750000, -1075.19244457277070000, -1087.42912025088300000, -1119.15937877668530000, -1040.53471300414820000, -1033.922694069 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1185.86347748561620000, 867.09045550340591000, 892.26172944950724000, 782.23967231060453000, 729.53458027459078000, 785.58396940747946000, 951.04859599474275000, 1061.72975669506100000, 926.58524997996210000, 989.80571713761265000, 1064.12183797609580000, 929.50289432423426000, 848.13498353690841000, 856.36366225415247000, 845.93331471436591000, 860.52222200365554 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 628.04297852819343000, 712.979 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1809.58607693039720000, 1506.23019851941630000, 1571.66570580093620000, 1607.65452763144460000, 1323.74770044183060000, 1135.64246881811460000, 1367.38897791343860000, 1364.41259216001320000, 1550.04015017489950000, 1670.88013270422580000, 1600.28581587990490000, 1539.93947590640350000, 1526.77905954175890000, 1477.80626494087480000, 1420.6579 [...]
+
+double nnlasso19[1250] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 128.32571829798189000, 145.16578397139202000, 302.19939283420655000, 370.47389756140637000, 448.68223958929298000, 452.93052556202582000, 529.24093487081279000, 535.23441412759314000, 551.69258140119814000, 567.40857425 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 8.15399071672074350, 38.70525734187511100, 73.93712535199244900, 81.0081 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 65.47959619229661100, 115.03732209973354000, 230.59632599763259000, 366.44408448917267000, 528.95481064321621000, 545.16127209927947000, 547.56622845205379000, 562.45173393135315000, 632.09223507134982000, 643.21364563041061000, 657.47547367946504000, 659.74006444566544000, 712.24339597909920000, 732.34386853474075000, 750.98967678608540000, 752.46240454261999000, 793.19279908232431000, 796.29295470352463000, 804.744767063321 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 75.52865586248285000, 407.31229701440719000, 451.97789937903298000, 599.00971680558757000, 619.48604173474439000, 819.34405978550865000, 910.58644104938310000, 994.95181235038228000, 999.45072392521661000, 1080.17863511373180000, 1087.41914326464260000, 1108.46573271983310000, 1135 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 48.71817817679129100, 228.29360047853393000, 252.88313987485594000, 462.34868305319071000, 562.90700501423726000, 674.92295986254169000, 679.61324854889438000, 795.55039076227081000, 805.78442309080151000, 838.25202556462841000, 866.8610543 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 7.6417837 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 212.97821391967929000, 245.72374776732062000, 342.00800762345114000, 355.93077622510361000, 492.07038802777089000, 561.98325546692411000, 628.04000520389343000, 631.54455137328728000, 702.74191619671910000, 707.08922014739949000, 721.82192513731945000, 742.9302 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 212.62506006365487000, 291.31711363073640000, 347.91282750390513000, 491.73653423547847000, 663.30534989038733000, 908.01828562935077000, 970.89389648116060000, 983.79866675638914000, 1039.76014883076120000, 1261.34796410141890000, 1296.92941297823340000, 1429.17480422997940000, 1445.12707865704970000, 1556.45740716550810000, 1618.89288233090540000, 1679.11441814077440000, 1681.85738402480870000, 1738.79388483757090000, 1743.70311982298810000, 17 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 94.60042089996963500, 99.18378037264065500, 186.29441357183475000, 193.10474852875626000, 211.04998981824193000, 228.51384164045032000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 13.26236716130987000, 83.23079729440638600, 354.82031703414134000, 396.80385736438774000, 556.40142225254169000, 578.02266623430751000, 766.24136305231764000, 863.37053195682233000, 973.02582692900819000, 977.66533427800618000, 1061.80107158608870000, 1069.46108682768500000, 1090.02947239532980000, 111 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 43.73970762583082500, 53.44531 [...]
+263.30762462890840000, 529.48073255670340000, 690.35227351150047000, 761.16230253229753000, 810.97405984118927000, 949.30064548088239000, 1142.93309839499940000, 1369.54323236792990000, 1424.01688410858200000, 1437.65846160041610000, 1503.03087747734750000, 1775.43824662388420000, 1806.88674432805900000, 1904.28967002829700000, 1914.21083147331320000, 2048.09452055676550000, 2110.28090410309960000, 2157.88440171468030000, 2160.85217588689780000, 2232.08096062028290000, 2238.7525376320150 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 256.30663659168277000, 322.82545337785632000, 340.71909310074284000, 406.41120937644627000, 721.03665574906790000, 766.75631490681462000, 925.95834443148078000, 947.64821325140451000, 1088.76094946921760000, 1163.07451160837490000, 1255.90483230906370000, 1260.15386249055090000, 1333.40338600094900000, 1340.10589230970780000, 1363.097883408781 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 187.57772143560945000, 262.83330421093444000, 335.58752699917483000, 339.63544450435552000, 445.00148956262473000, 455.29259163794717000, 480.36627016073385000, 502.914934172009 [...]
+0.00000000000000000, 287.67517060139130000, 508.96982877971516000, 591.95132949706897000, 660.02736823564567000, 836.63040757479143000, 1036.38248727867130000, 1331.39586959029130000, 1402.18514976148050000, 1419.18257786964160000, 1492.14925914724060000, 1826.48690059662200000, 1872.69630344575580000, 2049.87651270680410000, 2072.54826496014450000, 2278.30808637370770000, 2383.20733061235710000, 2492.91363981590530000, 2497.92267721785810000, 2618.63709028546150000, 2629.926516852532600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 5.87760596625935340, 136.98932076645116000, 147.86872951988778000, 177.97432749519675000, 216.78277119609874000, 2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 64.48579548565102500, 243.10519646922472000, 428.60302733187439000, 658.53604165534875000, 698.72123462261538000, 708.08380830770852000, 757.37606806043425000, 955.19534580971992000, 988.52918747854324000, 1099.60518543786720000, 1117.29675340014300000, 1318.81336920577880000, 1398.07035143046620000, 1477.80326729604830000, 1480.89025825471840000, 1548.43715334290940000, 1553.85343307211270000, 1571.59956 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 66.89439728494620900, 81.11911094986274400, 136.52771497761256000, 379.40799017037250000, 409.36165144522005000, 519.01327506276743000, 531.89360813626695000, 632.01749568732396000, 693.26067147241122000, 754.21956902692614000, 757.90460696936577000, 838.57811659334482000, 844.80320824972591000, 860.75694782318249000, 887. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 37.85858933056236700, 71.27239553510915500, 78.7812 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 72.33921568676204600, 150.81505631859395000, 154.13747647453874000, 195.79923247753194000, 199.00641017301652000, 208.25675083207022000, 206.134653977299310 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 136.34413035256401000, 242.58048177788189000, 388.54095201364970000, 411.63263627328604000, 418.91130881277604000, 460.61440780513425000, 650.36587034786612000, 679.46604562966115000, 789.78597250967675000, 805.32400377260240000, 938.82700420149718000, 1015.27315380539960000, 1111.53859265213100000, 1116.26154641127870000, 1182.82054887135540000, 1186.21644959937750000, 1205.212394018 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 17.23159159509075200, 164.42045064935994000, 225.20054206468131000, 289.53412809045273000, 293.19164644474068000, 353.88035350939174000, 358.75051964609230000, 368.37476583273286000, 375.69066179191 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 116.85566933494225000, 129.00308746138450000, 175.22178260935840000, 221.63267790402543000, 2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 252.99542443088396000, 540.90422143047340000, 598.39441760550380000, 613.87406510250128000, 701.30683960343072000, 1052.03231907086520000, 1092.74400291405370000, 1221.45926955659410000, 1237.18270549568930000, 1402.48937076405510000, 1476.95453587747810000, 1555.07166073525450000, 1560.01893243866080000, 1664.96267015251780000, 1674.69251883105700000, 1700.499164 [...]
+
+double nnlassolsq19[1250] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 623.96438831096009000, 614.08151646902172000, 616.69262413146043000, 585.63189678872777000, 605.99297617573347000, 620.94979467064115000, 601.63467870528552000, 594.98845366187686000, 589.24938528313589000, 586.52143482 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 89.44798753800122900, 108.42188556122019000, 116.78403851997405000, 116. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1468.53304814895230000, 1463.32227264517040000, 1254.58622512737020000, 1303.57139646920970000, 1218.55648097729360000, 847.49374211840291000, 727.19976890339797000, 790.32877913842208000, 804.82740476700360000, 831.03799152989814000, 712.55962656745521000, 722.79814619749936000, 817.39249436252589000, 795.68782798015513000, 788.49444615228265000, 810.70863439557968000, 831.83268812620133000, 827.20101555016345000, 824.031426 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1231.77067601685140000, 1230.26306012579430000, 1206.31454613716890000, 1166.89786429031980000, 1189.65429934288890000, 1219.60228700589530000, 1198.12464108338050000, 1164.64699265501670000, 1177.38220957369530000, 1156.76315059215270000, 1159.60586349202640000, 1156.4931114316742 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 871.49689863464550000, 921.87649763387628000, 937.58485668655374000, 881.84802460585286000, 879.80315014549672000, 900.23539981091767000, 865.11367908662953000, 905.53700792656343000, 907.81610555009263000, 912.34164674510021000, 901.653662 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 46.018893 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 741.24592194402874000, 798.74788471476234000, 713.89139258500632000, 743.61366083209771000, 764.71894226674283000, 782.30433635292684000, 760.90864412636995000, 770.14898848469943000, 770.28504481316497000, 750.43115243866919000, 755.44130102276506000, 768.6008 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 2214.07125819365270000, 1977.47835803744620000, 1887.67575817377270000, 1766.18523992570000000, 1846.84952330636680000, 1946.43866089727680000, 2143.84203104614610000, 1947.69540050646670000, 1896.45508594595030000, 1810.97078769829300000, 1897.84800383080530000, 1939.95261794272780000, 1889.32204755101950000, 1779.42009017050240000, 1815.64995835905510000, 1800.24592292627680000, 1790.34139992753940000, 1792.80809458963040000, 1792.6474155874016 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 284.88270418702893000, 280.45517161206914000, 268.93405503363238000, 261.00271010044776000, 252.00023029879327000, 249.7523448725181100 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1003.86910528509790000, 1154.35324850575850000, 1028.46655753858730000, 1105.84440210435420000, 1172.82286798949240000, 1180.07147387215740000, 1143.18937170800540000, 1169.46015840826430000, 1193.58996082315460000, 1161.15736819615630000, 1141.61850500279680000, 1145.83022634906570000, 1136.9656111579 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 96.93335191680904500, 102.1869 [...]
+2541.28786697336360000, 2448.62323087718410000, 2204.64101226553570000, 2278.43274138800370000, 2166.17027819151740000, 2175.03833530468360000, 2478.68027690150480000, 2331.14577147807630000, 2440.22598850571880000, 2456.58957832226500000, 2503.79453906741670000, 2451.11306753422560000, 2338.00583928816510000, 2280.49373254783770000, 2190.46798963645510000, 2316.22510930630730000, 2306.25300110289710000, 2253.63558476237180000, 2278.22733624471400000, 2299.65389650592170000, 2305.2671044 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1343.92398280791620000, 1563.73780406186640000, 1677.24973378164690000, 1412.06905358765810000, 1501.42851077741510000, 1538.89443807457160000, 1540.85209467525620000, 1551.60789623121670000, 1371.36924403568080000, 1397.26379513673170000, 1442.62667998323880000, 1428.20256497812720000, 1402.89334535303900000, 1406.92881932647650000, 1415.5645 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 563.24204043624263000, 499.99124018310636000, 481.92767537504960000, 499.73016152617356000, 544.95957580396703000, 557.89325043967654000, 537.58328656506342000, 530.337285114846 [...]
+0.00000000000000000, 2361.85031891310750000, 2592.02321931085630000, 2370.02400862767400000, 2512.12806178658230000, 2401.54289677101220000, 2414.34508006577650000, 2583.26229113441240000, 2722.76324036152440000, 2688.77243388266700000, 2609.17089816568800000, 2655.77256462862620000, 2653.10548072168470000, 2734.20826191118890000, 2703.84873142245850000, 2690.38593121282430000, 2713.78331356568830000, 2713.58038535100830000, 2696.02958636088990000, 2733.15578276662650000, 2742.4803128208 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 238.33631164139888000, 261.37166887489724000, 256.33471278445728000, 246.67395972705938000, 263.97930408954471000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1818.90906623154750000, 1825.88504248959270000, 1708.23462040867910000, 1634.23896597873570000, 1448.37831929382990000, 1407.40305243860830000, 1511.97419169493380000, 1445.86307438339530000, 1551.48898241777100000, 1528.61942069104680000, 1609.92277463715410000, 1722.39329151506690000, 1647.83816429700850000, 1638.18057999405940000, 1602.98043013809270000, 1612.51717419617740000, 1607.85288467635750000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1314.81322376213260000, 1143.60645072549660000, 984.75883366222467000, 981.84428606677193000, 915.23514711069777000, 942.52607994234540000, 890.54962142664772000, 832.53689503121325000, 886.26037496197648000, 876.83422658326253000, 903.64747496370740000, 915.11102269156584000, 906.86638674811172000, 897.16267018479323000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 124.25020214489182000, 111.90828951174572000, 116.4 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 300.30660959209939000, 308.66384807065208000, 285.53884866476142000, 235.32268044608722000, 230.98146416067416000, 229.36561576202888000, 203.55388534918379 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1344.51491391183730000, 975.43752374353676000, 1007.91289415808820000, 842.40933345943222000, 962.57760718294196000, 1099.03269918073310000, 1121.02232091571910000, 1170.92541212257040000, 1215.87999761983910000, 1237.98427081242490000, 1206.19518287871820000, 1256.18300241035630000, 1305.16994578063170000, 1303.05387718634390000, 1245.96338112213200000, 1220.07304235010250000, 1248.5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 497.04945879440180000, 459.19747468994171000, 416.74089690176834000, 418.93674093899847000, 437.84611758512858000, 411.45418586960949000, 407.30530517266584000, 390.33686650495287000, 384.5878215683 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 227.71366981044960000, 250.11092347262107000, 280.69078413879237000, 278.07486258091632000, 2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1998.24999964662170000, 1762.62288587477610000, 1670.87733181859080000, 1770.09624835204340000, 2039.78488693846570000, 1921.96611076787120000, 1780.30475320788760000, 1718.60251110802510000, 1675.00561092544720000, 1733.55115869404430000, 1711.62157596738330000, 1712.19892021621880000, 1755.68301461750980000, 1764.52012416048910000, 1771.69757010278770000, 1759.3 [...]
+
+
+
+// Data from file x142.txt and y142.txt
+double x20[5000] = {
+-13625.3042597735, 1059.17106330624, -15696.4849413886, -13209.4814461863, 8079.48856541928, -9147.10384033248, -1486.71763434266, 5873.46593444046, 4109.18933332952, 9348.4161929166, 19746.5990210354, 14852.0834245262, 17629.7223662551, 27866.1082224437, 7255.16925114227, 9341.54429632914, 16510.1013741216, 35544.1303289345, 19086.8852427654, 15996.6696439834, 5234.84597365202, -452.990532660593, 4786.35104458287, -5335.01297731666, 3793.28388037083, -14583.1402763370, 10687.8155292536, [...]
+-5984.9504985654, -16900.8323705221, -6155.58157382105, -14891.5738467929, -15322.9010153911, -2493.36266003440, -23707.8037751072, -9597.7017997906, -8143.38063282325, -8983.16909821216, -6350.67832994385, -5297.68593493226, -7008.48426112165, 570.963840635972, -15254.9028335656, 1747.12541544922, -825.45185744656, -6782.90940063186, -1584.71107978329, -10954.3615117451, -30069.0592055903, -25809.7931462407, -27698.5934661428, -26936.0968347511, -13424.6368353395, -9238.8637580706, -604 [...]
+-3559.07354543914, 24079.8079537923, 11742.1973596323, 11683.1458523141, 3785.27419720512, 6643.16017645084, 15151.2559366540, 3759.08385791701, 8524.98206536343, 12102.9217656404, -2999.44520463864, -15113.1322866134, 5273.09572355796, -16094.6819369475, 7832.71092767596, -10981.7612564294, -18790.1920828051, -10306.2420116603, -16801.5563330551, 13601.1853700603, -13115.3521584927, -3851.15026958161, -6826.62367330704, -7773.82786783089, -10824.6509592359, -7675.0087873765, -15924.8205 [...]
+14562.8484895461, 16159.5138448158, 18142.7559290292, 8759.32169990423, 9382.27534472766, 16797.4612602488, 10053.7399794099, 5288.81299120433, 15341.1809949292, 9731.29888027545, 7839.88704211296, 335.619293194173, -10094.4066360016, 4206.4538609789, -4724.89412699705, -4477.106157909, -16515.1786172873, -15978.6754834271, -24459.2556373847, 6633.84812184537, 498.663949923483, 7170.97872724482, -13518.7188301839, -7995.34976677338, -10784.200044173, 3058.11655594086, -6041.37723484779,  [...]
+-6225.39324058619, -15303.2807303044, -21026.4851903215, -1920.12041403599, -22775.7961545898, -19375.4164499612, -25386.8215660487, -17239.2205021947, -35309.2074194299, -32543.6624397489, 9997.94908917922, 21472.6401787306, 23677.7599247681, 22309.4034792208, 12313.0405775156, 23991.9598391249, 18193.3628829935, 18330.4463238763, 21462.6240823777, 16788.8354297437, 2689.87514390096, 4137.04903169473, 1961.01539505549, -22.2195750466292, 7827.61242404168, -12056.0400862280, -8176.267874 [...]
+-19765.0139485435, -12842.8351656078, -11406.0382080278, -21226.2110172919, -10981.0241994693, -22435.7309121556, -11523.3152503734, -5673.47186176024, -19605.6872658625, -3643.68699226801, 2423.37654236889, 4904.31101972591, 4133.30525937254, 425.048964379842, -7697.9117458597, 6610.9041986393, 6796.46985181005, -561.763126466358, 11095.695546446, 882.993357964584, -6169.93980714844, -7930.76739672531, -6315.9613148866, -3574.08883724813, 5014.73084166729, -5309.58800350789, 10327.56474 [...]
+-2436.40258440827, -13836.3517235640, -2709.95457617163, -11501.6578306331, -22620.5063945528, -11910.0414341771, -3379.76994221867, -16381.6713344031, -502.901976978057, -13431.9746568207, 30747.4483625225, 26275.3063322744, 14695.9919321722, 35689.6264366346, 22379.9206898078, 22237.9562588105, 27293.2558789812, 23300.4443467251, 23917.8139557988, 13047.9101435897, -14149.2368048238, -2616.71547725878, 5263.20853332303, 2892.99617458134, -8992.75159844355, 8506.92950159435, -4072.28552 [...]
+-841.17372757704, -2249.35462565482, -3457.66857574806, 8113.88511963156, 1372.02298370301, 2832.29517094278, 12952.5216363093, -1459.12454561765, -5627.54062657907, -4246.677165043, 19536.2438473486, 3362.17093552944, 10397.8411815529, 17695.8974902699, 10135.4319950457, 13438.5363808289, 12899.4767125141, 16495.119238923, 12654.0228313197, 19983.1725199296, -26701.2751016588, -7399.91799611302, -15189.8799806987, 2635.12896592241, -8000.35400742094, -16784.7127794651, -13733.8492976787 [...]
+20215.2579607824, 21925.1394356027, 12644.5188419575, 23083.881394355, 3930.16564465990, 14953.6208850466, 6105.47282016012, 17681.0165487142, -2714.67358774681, 12820.5008175394, 10562.7514632050, 6385.607976976, -6565.54142392308, -1507.44701016779, 17888.5687290152, 7063.81231795775, 7626.45820921679, 13633.9264434729, 4987.31296859164, 12959.8229792661, -648.264864234228, 11055.4728107767, 14380.674783514, -2172.03451812291, 9286.02121387826, -9922.70256698614, 10438.6191180979, 1113 [...]
+-11152.7404892145, -2686.92820407489, -8493.6159666591, -17555.7345941895, -16026.0499728055, -7399.34302391251, -2114.71939329953, -10336.1706728298, -10873.0353634360, 5284.45992859673, -3806.8586864963, -15526.4658156617, 3862.96374102526, -13124.0219774004, -16697.2206914109, -23556.5756532211, -6841.14087764109, -19358.1477511338, 10502.6635032386, -11048.3222772567, -9624.42009062599, -2503.19665899149, -20300.3512418338, 1221.39441519625, -7278.84104180017, -1753.42619126255, -148 [...]
+3336.59724758128, -323.127214367009, 19973.8086398773, 9972.07795875965, 7663.27817859313, -499.587602063447, 14275.7729423054, 1297.80822077575, -4031.68304060751, 7960.86642544017, 3598.36762249088, -6307.90006138897, 12370.5055116342, -5439.9318409528, -6235.81080292068, -9230.15273724766, 9449.03967333516, -18573.19336783, -11402.7206098859, 8736.9562246813, 5395.99899428467, 19201.9539937992, 7684.24497168982, 14048.1895493367, -9791.75943245945, -2010.61493891184, 1824.20288368801, [...]
+-24133.8249139704, -10721.4427775908, -7560.87273424753, -19985.753900943, -7249.96814449587, 5902.59241496666, -471.340493631357, -2186.24979204290, -10004.2296654128, 7058.99816266772, -612.474462172933, -8366.19747324974, -9565.00272474514, -417.066609464692, 1759.89265829707, -1161.0488540074, -12676.7447340728, 563.729148751834, -14266.9265790084, -7632.18012522858, 912.989228052857, 10392.7426594200, -5875.12303014354, 1422.24772220474, -782.535549044644, -1971.54606785189, 3819.77 [...]
+-10733.9759837521, -5669.6695430194, -32183.4755735696, -8012.82721088239, -21505.6163047702, -12903.2023320866, -9609.98204968018, -24074.0103114531, -3156.87798734795, -30744.107503153, -19174.2319852781, -17001.3200726862, -17724.4644934237, 2360.74498560219, -3461.36885915694, -4849.88462620179, -2372.18776824298, -23077.6926117231, -19685.6875769879, 10387.4633511138, 15928.3250564132, 7292.33952031301, -1460.15090418299, 16180.4590095543, 9629.48125411524, 12116.5221655574, 6802.48 [...]
+-9052.12020875526, -10870.7873076678, -19360.9557698354, -3167.10905160746, -7987.0340896568, -4092.43046676519, -2378.68901731604, -7332.65013149611, -3688.82520395399, -13819.8879493916, -8536.66812250061, 6517.68374157628, 5974.33379130547, -7756.1835777665, 2074.72694354502, -7106.6299726512, 569.186206044885, 2406.14247831766, 5150.81751455181, 180.753262476073, 33799.3311438394, 24037.6825282818, 24312.3195577523, 34201.3504469475, 14595.4309559334, 16683.2988918212, 16752.98572425 [...]
+-5125.34900008034, -16821.0727862144, -8956.34209504464, -22421.3575742676, -19241.3642434621, -14864.3576649282, -3077.57029378556, -8109.44709789051, -10116.3684502940, -11088.0142877194, -21074.0446633145, -21147.4357528632, -27571.4372375584, -13015.9189357898, -24738.7638749661, -11870.2769441381, -26074.6767738273, -23358.2004563675, -22363.1807356900, -10149.2037756192, 7964.02564996426, 14720.2026651528, 20441.6880320254, 17082.0532835064, 16954.4493273523, 16133.9000902423, 1415 [...]
+-686.273921394157, -8413.80998578514, 9817.82486582454, 11054.9017175506, -6718.00421101162, 3916.17892232898, -2696.13674692806, -7410.89735594593, 6207.09406423027, -1197.20256606864, -14734.7510752016, -20298.1615674772, -3199.04108396351, -6584.90416576761, -6384.90580722958, 7954.47034230987, -4844.45747674168, -7342.2652985025, -4587.22016478098, -2753.17829454895, -5584.96928900834, 2834.27284815597, 14192.5148929475, 18606.1099563120, 14907.7991912362, -2171.69414812664, 15873.22 [...]
+9762.73007625617, -4174.49302647485, 2062.88459346954, 4903.88660185339, 7900.50635423522, 200.308915694093, -2980.93704092901, -6672.74092520592, 10922.5857287678, 11517.8908672803, -954.574160828168, -4350.20967539793, -10228.1946418282, -2134.88803281845, 1614.19347760289, -11449.5416291012, 1405.74891038468, -1720.44144640478, -524.78767726637, -7233.16685743003, 10608.2437599820, 5432.47608841899, 1205.83062535079, 12030.1001989104, 21197.9597296383, -10684.1182451162, 3899.22531599 [...]
+-43.9718901882018, 7788.70504702782, 10574.5972676843, 11598.4682689484, 17973.7958559114, 18726.6277532796, 1216.08576767892, -3275.8237813652, -7215.14734267467, 4025.26869745171, -10667.7951496327, 4820.14254524964, -3537.16371115917, 3846.02195559097, -2473.07881733488, -3207.75760798494, 14205.3189016183, -197.267843965457, 23433.8598766605, -8947.17996013684, -15725.8361576067, 6536.99804638546, -1976.67148933730, 4617.29746476375, -6506.17156448513, 11080.1972290354, 15735.8377804 [...]
+-11097.4120717642, -9184.5372460274, 436.126809284864, 5602.37722246015, -5869.75742951025, -8999.99856845321, 6227.21681607783, 768.534269497717, -6591.73819658369, -1012.93867636093, 6764.33339682831, 21829.0618957905, 41526.1422798726, 22834.4291116838, 15144.1466091632, 22576.6867772244, 16782.2323377218, 15278.8393148835, 10400.5309363845, 20056.7749239606, 2153.78571853635, 13389.3149207472, 6116.06189183076, 5406.05025341183, 15375.6517467129, 11651.2041457048, 18105.1741361618, 2 [...]
+-22324.3248178942, -3657.9964389896, -17621.6565743189, -13832.8669914943, -13335.5066988976, 1738.66155570773, -14266.5668948134, -18644.7269008465, -6981.69361866053, -5407.10450081836, -7224.79568989777, -7197.97764720504, -27.9754236560602, 6448.35841162425, 6569.76290925726, -8874.199930018, 7046.3480189067, 8580.2188236237, 1304.27337969209, 9819.05477933267, -6690.99833356402, -26758.5822872171, -4763.04168784316, -1996.59759500489, -9334.35590948837, 7899.81412171163, 12998.02000 [...]
+-6403.88350287895, 3100.13749014635, -19940.0518600314, -4258.97822183487, 1927.95238563111, -6980.50139493916, -6031.09944970826, -808.811408144915, -351.169615889668, 3327.88814108369, 14351.9964639377, 14403.3370186383, 6383.96379213739, 9161.18361551468, 20359.5105441196, 11787.0003327981, 6051.52375203501, 1166.08723043738, 6300.45843905982, 15913.3544815263, 12809.5351911556, 4621.66792112772, 12021.6447371864, -9373.30441109492, 1163.18754629212, -16758.7173090154, 1539.5974501879 [...]
+6155.96109945456, -7414.67826172156, -5853.1308719305, -749.142258157563, -8751.33895592236, 5902.86612423198, 1295.21409243125, 2451.63027839517, 2872.27328257464, 6096.17946490197, 18852.9655370944, 8113.42298918118, 15009.9050572476, 24422.2497545394, 17113.1057627496, 1383.26531331029, 16106.0774727380, 14473.6389586946, 13914.0090914449, 3849.14841636694, 16098.3981131718, 13805.4096473386, -6882.33050508257, 9744.02134228231, 10622.7290759971, 25322.3691388528, 5825.97042395805, 59 [...]
+-4165.41738190455, 12030.8759145269, -2727.96637181338, 7014.54516202138, 10524.6494857579, 6516.80324007177, 13152.2161680246, 13784.5302979064, 11010.6514330162, 19275.1441485110, 7240.32248937595, 14905.1065492512, 21220.2361499044, 19031.3128859047, 11811.9170500523, 21861.6956703366, 22688.0125057051, 581.621047298404, 32504.3164526421, 369.197411643135, -7570.68259065755, 1436.73801452552, -15434.2641916703, 15356.7107308772, -2319.67273379384, -2240.11585397824, -1308.22659898246, [...]
+-102.022993147557, 20486.1163744802, 18630.3698285724, -319.251214759413, 8336.27955167705, -604.51407573481, -726.279693890795, 7098.22242585386, 3259.91142098363, 8118.33981297235, 11727.5530902853, 11451.3568948620, 7678.5775440226, 19240.0033799680, 15479.2158610791, 23334.5814601043, 3763.2347234378, 6019.9776384302, 10588.8045604211, 13338.8026329752, -13731.0153142154, -10039.2011804183, -8338.2120148116, -5420.64305972749, -22072.7053395071, -1310.18861068762, -5824.55018128675,  [...]
+6653.60380063259, 11135.5835325928, -481.82548880408, 1352.83907840166, -10835.8474700545, 2130.93235380329, -2961.65808685677, 8338.16571533969, 4025.75776389205, 1106.10447327701, -8614.33403228748, -9873.17157089248, -1356.54966555928, -17781.8930176989, -11597.5242729954, -7719.3848541628, -665.557608938582, -10471.9738876809, -11382.5374432487, -11477.7042491628, 11576.7575712712, -12041.0638913476, 19908.4478237928, -2220.6062336094, 1195.25238937166, -5007.15764313809, -24793.8564 [...]
+-14131.2409862095, -19491.4970374899, -4465.86032016031, -22575.4803425032, -8200.00735089826, -18414.8388209502, 982.87317695962, -7194.0013056394, -27909.8115550518, -5188.99894123277, 1647.24278768787, -10455.2227610700, 8230.51322237574, -23340.8501056087, 3933.50236112562, 2798.39815246858, 21420.5259193213, 4366.80880301699, 10933.2025900419, 1735.10990616838, 16552.6748707757, 13976.6713380091, 15297.4891156314, 11407.6146754707, 20926.1623209862, 9206.44371354905, 5484.4421171168 [...]
+-15390.2105845580, -13064.9866693860, -4600.56999279499, -4126.00431984879, 1965.76305163527, -5325.68325264119, -10161.1244106090, -21492.9861734156, -36406.0904137494, -25787.524573847, -1675.13888189322, -5135.15539330227, -9014.9966074386, 14743.7150677957, -23292.7796272303, -9405.65312565062, -1050.36933644838, -11435.5370998139, -6020.78645357324, -12706.6242417282, -11284.0202501978, 4582.33559515645, -14374.3514469825, -3069.57243682643, -11160.0642492232, -14510.1137037591, -31 [...]
+-10947.0097602177, -20117.8681181056, -9410.56280857963, -33803.9795766324, -12736.7060227315, -19339.0698251611, -12955.8375045296, -19407.2154095074, -12363.3239362698, -13270.8473932175, 7560.14653231424, 12758.5008591411, 9825.59426012164, 701.93919071816, 15116.4504959908, 18687.1706718248, 12930.7437317755, 13997.1132209497, 4276.31381660026, 1257.7919396617, 13221.0234624134, 651.515925437842, 9288.45275872541, 2105.0143499667, 4408.6079771054, 6501.2001813786, 2427.66801716200, 1 [...]
+15759.2939302985, 649.743548786512, -12306.5115455336, -14275.0318140265, 1297.43479580426, 6763.98588801752, 8808.1881834706, -15342.8807656045, 4235.30974327997, -6171.82693718943, -6260.01041663273, -8395.68196993301, -13535.5900043994, -21196.3165876675, 4184.89172467269, -6705.76394838056, -22703.5625283156, -8142.08296977301, -14623.8298677075, -23802.996976873, 21417.0020208138, 23100.2686452452, 20197.9376381502, 29139.3960883027, 30400.1971041085, 21713.0045222515, 24511.0602938 [...]
+-16250.1731784181, -2763.74632617971, -24500.5115736579, -11900.5452351934, -16988.1251539677, -8395.89008335067, -14170.0228041315, -8794.29485092864, -8842.95996864649, -23125.1548218975, -6304.39602078716, 4894.25933179105, -4003.56522821354, 3584.84751205338, 9407.5497975082, -3249.40205718596, -3221.92921969827, -1299.12401036386, -2368.01074593825, -1963.33031221005, -9072.83784973384, -18959.3491163282, -10187.6970373407, -2345.62032781543, -13032.7190507964, -3022.80089655389, -1 [...]
+17000.0220775668, 8115.7142057141, 8072.16180460076, 2207.5639905493, 17897.0754611496, -3672.73582177529, 24517.6950056628, 3967.12637969395, 17510.4384949342, 16716.19394445, -615.185741921613, -5886.84146796187, -8878.04492429261, -7488.33409939831, -16127.0809932422, -13001.9579800476, -17213.6479069439, -3700.56843068565, -15688.5568829112, -18607.2773130811, 11013.3612378742, 20877.5326251693, 7469.61946364444, 19912.3055370369, 3588.3879849262, 13231.7259453349, 15573.0069170236,  [...]
+-248.944228500921, -2403.1003007666, -22262.4305927900, -8416.0696022537, -4612.72178489137, -4407.67781491983, -9678.07759174643, 5486.53875806601, -2486.97685937274, -10743.6135260626, 355.894319585410, 16167.2593162843, 916.793810213983, -2398.72606279617, 9747.01392439078, 20073.7392030148, 5744.51131786891, 15846.4464808617, 9027.0211676785, 2827.07504794904, 13723.4733838701, 17295.6695064920, 20840.1820923178, 6110.75573288437, 16352.8324641372, 3600.03872070764, 15340.0342000941, [...]
+-25282.6577627477, -26713.3746767647, -15949.8468741314, -26331.3198115771, -24886.7704670292, -16542.8750469731, -33437.4907189131, -27498.2232628729, -14156.2767983073, -16537.0849019841, 3281.78242459576, 9443.87444010834, -582.402960810062, 1044.77693605119, 1980.50366265918, -11850.2071755000, 3867.78203202158, 13161.9424512152, -3022.52245880680, 7597.627251538, 29335.3543554896, 29145.3579144190, 17419.6962724753, 19748.955939292, 5099.53195729619, 32368.4294475907, 23030.66960414 [...]
+-838.667932784269, -80.9945510615175, -1869.36796457505, 12355.5999580682, 3084.92193785488, 17378.6558699803, 12583.9720395133, 2560.45461422089, 8073.52136284747, 12047.8947309393, -18398.3136023386, -11423.8236037309, -21046.8586826677, -11132.4473145031, -6568.34649625012, -23986.5917644828, -12422.9027187207, -5730.98159959721, -8640.80523993863, -23891.093827713, 9703.08187041565, -2898.27849503374, 12410.5182204544, 30853.0075064486, 14088.9280460700, 20477.5176954809, 16575.38695 [...]
+-14983.1324552541, -27270.6558629224, -9889.9106970661, -17063.3290687234, -17517.3206337386, -16135.9585791096, -23161.6303612951, -29293.8459976625, -16313.4656009715, -35272.6346309088, 17428.3841483855, 23400.3074516195, 9017.00418976748, 26682.8214384927, 25800.5803257946, 40593.4446318044, 41901.1202479218, 17883.9060634271, 32468.8817058065, 15605.8504773038, 6452.89660518914, 21863.1823686981, 14389.5986738101, 16606.3307925937, 8688.62983945483, 4683.37026779255, 17174.914882147 [...]
+-19164.9689847082, 78.9146864480779, -21173.5217840069, -29232.6322416392, -7995.98139788634, -15032.390576034, -4135.24783658604, -18678.8942177554, -3876.39146885708, -13929.9405068269, 12782.3947918816, 4443.99226249155, 22267.4956623398, 13818.7450950365, 8169.14081709853, 10572.8460898872, 15545.0121874973, 10549.3941996716, 16653.6303808792, 11928.7131470910, -12094.7963650637, -12757.3488851939, -3336.26920463144, -4905.22623564273, -20002.1278263395, 5928.51302145901, -13427.5148 [...]
+-6639.69180754231, 1804.98943089264, 15859.9574131930, -3064.10653141166, 6855.14272354141, 3381.99350237081, -589.245511818604, -130.977481723803, 1993.68343876273, 23415.8575080620, 1854.30162400940, -2513.75785953950, -4269.25394426935, 10305.2113283353, -3696.71438414301, -9717.53187514181, 1968.51677155467, 12186.5953871667, 3281.09266511328, -6513.35988215158, 4793.76274445052, 17733.4482761715, -9527.9925178948, 15267.1476084976, 4727.08786699565, 6100.72918857224, 19663.265976147 [...]
+4866.99090702169, -13303.2526805502, -2875.56822538671, 15067.0012345066, -12892.7215343327, 7258.16274531694, -4829.21631250902, 4574.96794373255, -8961.56938785543, 1838.61514474202, 12235.9858971904, 8967.12349173132, 4486.14160074406, 2900.36468820257, 5570.78405129197, 3204.38906425617, -148.935993093972, 9362.7050949419, 9817.31780995595, 4197.87388363109, 6762.01871597997, -3875.39897312423, -10440.4432711768, 2893.9484135029, 2716.8786417323, -2105.89501978035, 3764.81330029348,  [...]
+6109.8801014349, 15958.8991289522, 628.494860114079, 1269.16966854127, 1201.86574671956, 16583.0280791786, 5432.51036981722, 16318.5162864763, 16095.8327270021, 4414.30668963682, 16430.5778947406, 13312.3866204278, 29643.6899677006, 11773.9601682889, 9101.82146573518, 23649.0828595657, 15201.7772634349, 13400.6232567963, 14017.9162009140, 20460.807868878, 5894.30647315911, 2375.68711220126, 15905.2144818911, 4425.83993640486, 18739.4925579924, 8209.79280159985, 5722.5873036507, 13696.619 [...]
+-40881.6583426782, -23100.6666088673, -19447.2323257507, -26034.4039523435, -30254.7281443538, -28849.1870794358, -35539.3978566514, -30570.3122599951, -41870.0891338262, -36161.2140576672, 5361.27319259039, 21510.3619937054, -2398.53227085578, 8542.59622921635, 53.0199250283372, 6885.37234241394, 1791.92514610101, 5785.43191062497, 14613.5102828866, -498.0081063997, 12870.1789352464, 18353.4650276263, 629.709629192644, 14628.9047478576, 11131.0748654805, 22579.8641603875, 19484.34628675 [...]
+-15812.3426658141, 7178.52836356247, -3880.18425798604, 8735.01140720337, 6272.31392958393, 12633.5043880129, 14224.7200873519, -5589.08124401068, 10893.0320215565, 8428.70020540257, -8623.77266540204, 4640.44390208925, -1265.74113449799, 6655.5688097226, 12794.4219480333, 6754.32493598811, 11166.2662146215, 2195.16869064978, 9563.41351085974, -15229.0226714046, 2655.95701944303, 1495.6434535741, -13195.0608543623, 104.273085155309, -5267.48916716193, 3389.33772398700, -8201.21495360765, [...]
+13182.7812610725, 5172.62428663597, -4103.34818033188, 17198.9484122193, 3520.3662949974, 10074.8552895614, -1488.12203315231, 10598.5473253965, 8844.20510337732, 6042.97565456056, -12363.4987009775, -10359.2012540676, -5890.83077196406, 2019.7511135636, -235.411114559561, 12183.0990689800, 15319.6570019565, -6509.26816935468, -7674.60965446291, 8881.2209761608, 11202.583835606, 27866.5730105741, 20552.0910778086, 32897.1989961585, 6468.16022323957, 15747.1721650066, 20997.2745284912, 51 [...]
+936.575742871889, -17871.4934706269, -3529.55206047276, -8087.28524717513, 1112.03781271236, -18428.9846563762, -11376.0373048206, -11005.3015291126, -3933.43722804024, -5787.80176404896, -7970.71142529293, 5945.83255354277, -22085.7056453784, 4286.18683744346, 888.77467153001, -2190.76568375897, 4396.83381037438, -144.670269820675, -2349.57428853971, -2053.09775027701, -7671.27066875461, -13683.0252703694, -13079.3375401609, -3055.97137805549, -534.962444502241, -5205.77808917842, -769. [...]
+16506.3277743743, 5200.37083656598, 291.929632145862, 12259.1064470203, -2250.93004353137, 14091.7065142990, 242.648379131628, 746.713758072695, 4588.13265553617, 7825.71324004353, -570.702283035182, 319.438609219905, -10051.4162504808, 14069.9706758694, 2153.65877550328, 1795.73034243598, 713.84665297487, -16293.4570251682, 6688.83645634421, 679.070669472715, 2578.45050430246, 2611.91610995818, 427.389703311009, 7883.1433597611, 2189.07205692423, -2961.13644536137, 8900.16786962095, -72 [...]
+19973.7744958431, 27017.9587819015, 25725.7487091157, 19353.6242548863, 13280.3994146907, 26121.3832560410, 24170.148074301, 23849.4609991555, 21365.3054122839, 29719.0002307040, -12711.5262373212, -348.239620057213, 4234.0088144203, 156.728000879254, 5344.63059783312, 9429.15042276706, 13534.8863948768, 10632.3415962984, 22135.5992190272, -3367.32802504745, 22970.2680063786, 7274.84886796027, 12777.1779555762, 18845.7361236535, 5974.86221447526, 12002.3815146566, 1768.12058057055, 25369 [...]
+-555.359107360751, 3325.78430643408, -77.1031939224673, -9692.54055793703, 12373.7430308718, 11759.0503953706, -1150.31261664243, 1850.38271994582, -606.24522832272, 10386.3778142888, -1020.04022772233, -6470.96700941071, -15152.6282794798, -5758.42218946247, -30407.1688480497, -19582.7020410363, -8352.24628747376, -5615.78780633323, -12753.6964232451, -25627.4667111445, -15734.0792387209, -12392.8145152411, 7004.45773123807, -17460.8924264467, -16806.4355958987, -6027.91709005217, -1007 [...]
+2512.90725514021, 16332.9602319543, -4081.49473128781, -9306.44918166243, -3145.22896447066, 1562.57884588428, -643.93028202234, 4424.43966713526, -8375.21946175647, 13096.1492091814, -20070.8161434934, -13178.0759440278, 972.976314065182, -6850.35030291516, -6976.1207753056, -5326.28908110859, -7026.81883107152, -17057.1261515473, -9958.0132405569, -3125.95031636673, 16475.8989294070, 9550.78108688268, 11532.5610913570, 5527.51974471964, 18901.8228881662, 23217.8464601135, 23915.1009651 [...]
+-31784.4600890663, -36824.0406460814, -19077.9130584396, -18826.8079204597, -23972.6420943296, -23745.2797895979, -23667.7674978121, -33710.743154679, -16758.2081617140, -30251.2319614610, 18870.3301711594, 12941.034430923, -5358.24747265449, 10304.3856365517, 6872.81663624113, -5741.14511468949, 14365.0748376440, 9179.00928618579, 15238.7264818125, 8116.827997636, 3521.70881294331, 7772.58005978128, 2786.08040628150, 13272.014812687, -5223.99888024749, -4566.48869874016, -2746.445616085 [...]
+9492.14656380725, 8858.95613461664, 6497.51293040084, 18001.2472346415, 15362.0992102881, 14838.7026409207, 2586.90016434074, 18343.8668718872, 17403.4523691711, 16185.0510778948, 4723.54231224999, 10009.8718859625, -4514.04942366456, 4327.80131468071, 5359.69448966678, 8474.00035608456, -8605.93764390327, -6821.96702029278, 7497.90291342313, -9394.86964501789, -997.228243511386, -14902.8282033971, -17153.9264333719, -6745.09616206192, -10805.7462649151, -9404.76947606098, -17336.4489234 [...]
+5589.62719629906, 2630.15709219286, 5901.49932411517, 2253.61082212266, -7234.24664641459, 753.414317632608, -2429.08203431297, -11872.9302384236, 4010.51149627254, 12567.0667694771, 2421.02798449518, 8674.44419055356, 3747.07669726506, 10378.5185960396, -5538.4893086281, 8797.94020938276, 1452.55787518176, 13661.8739775303, 9979.08407587785, 22587.1643185806, 9153.69259531144, -515.456555927341, -14629.2331474459, 5304.0134189536, 16770.8558684038, 6589.95516154038, 10870.1837417635, 35 [...]
+-13730.3718687222, -11879.4523111917, 8037.61544784277, 5639.58567165599, 1801.66712848607, -7463.79085527345, 1981.68294241341, -5535.33514552835, 6045.49626052454, -8448.49044594783, 10162.2876812683, 3339.79396106967, 11638.5756847013, 9997.03744187704, 3721.82328585168, 8774.64686826993, 12591.0407731037, 15778.5181978700, 4002.5954189493, 16084.1183997352, -267.559737498421, -11662.9669507240, 14132.4140927497, 6922.96951598283, 16822.3057037003, -5341.68450094317, -3215.17354714451 [...]
+15165.3597366004, 15542.4724666938, 16444.3335155524, 32012.0315132424, 14267.9425160760, 26798.5781978923, 19871.2502628812, 25280.6290252444, 22083.4456996687, 11399.4123027706, -11487.8097033201, 12183.8170811984, -1217.51230983196, 9479.31313748549, -2989.13923323964, 12113.8133567525, 4054.44685148043, -5463.99514114365, 19695.093237828, -125.518141953886, -15490.9882029485, -15979.2564703804, -11096.0708671210, -11940.7313102546, -10935.6010318804, -2196.31523145893, 125.2811100831 [...]
+-21428.4985897319, -15271.6149379323, -5556.98545818553, -8493.7328471843, -16917.7344811542, -12430.3811541905, -38580.6259237578, -29357.4044683314, -18216.7529456323, -25735.5839685382, -46.1032607601862, -11751.4968459738, -15538.4751712047, -5404.96266866855, -13524.1744977035, 4355.15840199897, -18477.3735085696, 10356.8521816488, -10335.7337652301, -9158.54974629708, 5470.42355962134, 3340.67008735439, 9483.1174753942, 17213.2398387705, 12534.728010671, -4484.84475986985, 9124.606 [...]
+-3555.01195577401, -7472.42576589987, -9917.78837035726, -1582.21036143811, -4923.29252599091, -992.033943332398, -4382.66545897601, -16989.5016681174, -4775.53271205004, 9289.28002464153, 4539.9000437119, 5663.71897826857, -636.572694259603, -2151.08996225761, -4924.0820506385, 6177.51021028008, -11001.5101228317, 3626.41787995743, 4274.02959706846, 4497.37414842656, 17679.4540862111, 24756.1879290032, 12283.8174807663, 15203.0715668442, 27758.2510007318, 22719.8079231589, 11040.1895642 [...]
+22150.4206505058, 9294.26887838571, 5597.97876165531, 21486.3742640650, 15632.8211210670, 21231.4638504690, 20411.9542258411, 9197.4725143847, 12356.9839042724, 17396.0289351847, 27448.1582148672, 22424.9254645309, 13014.9871271169, 7425.91255956012, 18276.5786882972, 26691.4737928548, 12472.3951507860, 7701.45526573081, 7251.91490870593, 10904.8210355017, -20406.0583011491, -30667.8200601108, -24768.2176450630, -21578.0481321922, -12740.1710678204, 896.57270010426, -14147.9339764910, -1 [...]
+1800.52195527926, 4138.44647992805, 15286.4322552483, -9445.56293113847, 2750.53456355141, -6953.46756461577, -15564.3537427021, 10115.2053056144, -12632.4641533359, 1498.19310261970, 21611.9723904398, 3370.31578061024, 14530.3976706252, 16352.5805790645, 14803.1171568297, -9801.20715352233, 17853.5134263060, 7935.81868533842, -2424.56804089923, 21642.6785791863, -382.961898522267, -15086.5081590498, -10022.0556274519, -16722.7500029183, -14029.9025199648, -10149.6453546836, -10649.03716 [...]
+16763.6017053016, 6751.41041644754, 4573.00376901934, 9547.8687188597, 7392.58808861851, 4364.33948376022, 7521.42173193292, 6356.01326422869, 12356.7343382956, -4223.05019897145, 17152.7550697606, 3670.36759887671, 10046.7022837013, -4976.91674930573, 18520.8857657866, 15880.9124213631, 16678.9453045690, 21272.7718479273, 19414.8901032582, 9041.71514751142, 5121.32620965922, -1536.16781619939, 10158.9520736782, -247.931261859318, 8225.14964086535, -512.448772241577, -1678.95986680527, 3 [...]
+12515.9548770100, 22655.7810761733, 14966.6927943645, 27910.6800116110, 13843.4648857774, 9043.42874707168, 19613.7218768981, 15697.673593659, 20270.2953993548, 20123.4101239190, -12768.5492031774, -15530.8898691601, -22731.9072483847, -6937.152614202, 698.494715757973, -4898.54471113201, -16618.1566348294, -19778.0018728697, 3146.95426798103, -21736.5601464707, 18177.7255018503, -6107.0252985142, 2944.46114866759, 6158.99197307743, 10060.6440228115, 16389.5921174252, 8038.9758200349, 63 [...]
+3691.04761842761, -12026.2895417017, 17099.3695006667, -1159.33928427414, 1205.57815850532, -3785.98725243722, 9614.33571590187, 9416.69222325621, -4490.2718393694, -9135.09624268052, -3458.35422333617, -402.335594056633, 15541.2522170261, 3913.54875267512, -10267.5895832073, 182.481616402763, -2895.75435344023, -5035.35233249233, -3029.53022056245, 10905.8381343315, -24212.8422048579, -29092.4645294863, -38795.5354296478, -40823.3314201204, -34678.4385646845, -36562.8252956236, -26617.1 [...]
+8523.761171524, 19761.3588869061, 28183.2821713839, 11953.6873859774, 3386.57453598312, 5848.74245892916, 6281.17083912612, -6172.03648105539, 10993.5639346203, 20857.6105811687, 2024.07275910912, 16607.8733764763, -14220.3321099321, 2698.67582025262, -12006.5586466663, 6297.67982027802, 7483.7249760367, -1141.29293548831, 20697.7185118066, 15543.7311912213, -1008.74756696078, 4777.78900519949, -3204.37201202672, 404.521866085941, 5813.8783516328, 5978.08569423419, 1465.77747511494, 8099 [...]
+-2974.32788940884, -7014.13331113119, -2714.72156861945, -12135.0442438690, 14500.5716633202, -4368.65880184237, 26818.8128379198, 20308.9486784599, 6225.00633850603, -2543.84883952708, -2983.94115538704, 2848.91439506674, -8663.72154599528, -9168.2637016153, 8062.542566959, -12579.7669272256, 5418.17648044851, 1326.19686778308, -6082.20984086029, 6544.86266175883, 14714.1068053474, 7151.59277520052, 9542.49992211362, 14392.2367983899, 14436.7784227954, 8577.42575440859, 697.46563734827, [...]
+967.176142909617, 317.464030847573, -1883.04537395607, 3374.24641793728, 4898.01134162413, -18541.2002087178, -5609.34395122131, 17867.9857735223, -10540.2257303885, -4139.16835323205, -3068.73342772104, -21821.0605892755, -12644.8268485232, -9248.7387700525, -24209.1731469917, -16670.8070942196, -26496.4959308759, -4907.08636399007, -12351.4379625343, -11560.5972368371, 3603.21013032069, 33000.8914103734, 15427.2181506676, 18150.0889052294, 20370.3747517815, 19227.1299245834, 14050.8427 [...]
+15308.4317579789, 16596.9217075252, 11736.0612492262, 12696.9262192087, 15330.7104727202, 7263.70055524903, 20461.5397549471, 4141.85175597832, 20467.5411397832, 17352.4241016938, 19840.3096715474, -13881.6436734587, 4866.47253527816, -2434.34067529399, 8235.67919378225, 12238.1833198359, 19321.2105502665, 12724.8751806531, 20278.2984126996, 10404.5384074612, -7261.3810928369, 2011.78262414669, 660.292263927072, -8034.58417869503, -3351.97045108946, -2660.65191009780, 4699.24044911626, - [...]
+16284.0950888864, 13767.2130486351, 17451.7995910098, 12807.3135492921, 7044.63381255031, 672.705812293227, 17927.6413927196, 8102.18112091346, 16786.2066804890, 17641.8367904485, -9456.88353877526, 2254.67304218389, -12715.6228591851, -5762.8526279204, -305.407364436554, -9334.32611379381, -4227.76710760373, 8081.75051453073, -14870.6947775755, -5943.90230735114, -903.249447001816, -11112.1253253978, -9583.02890880312, -2433.43459323351, 7361.62193032856, 957.78587248973, 11283.89476129 [...]
+4706.96811888694, -21311.5207831158, 2184.73651241685, -17110.2269928613, 521.635570682679, 5409.73155070235, 7513.62541541516, -3288.08637397997, 36.1895206502436, 2852.38367527966, -4121.79509475201, -18082.1111586779, -5200.59569983616, -17367.7606139544, -14887.7340219312, -25925.9831361269, -25166.3607489867, -11087.1098971616, -8664.39213586262, -11373.3790005525, -13669.3765139644, 8793.360259921, 5179.87702211787, 3764.01918415550, -7270.159118605, 1022.67605347509, -4892.4717320 [...]
+16536.918233816, 2863.92684478125, -7063.19743118445, -1864.82378240049, -988.048778705858, -1430.33761061619, -7818.11202466406, 1999.44304114875, -9998.7159279031, 7021.44290593596, -977.54632616992, -2063.08926113378, -471.722295267175, -1472.66743761743, -13507.0482591778, -7041.55218115256, 16146.4762958486, 1159.20524349976, -10708.2756539232, -1480.17999666138, -29068.004469627, -18911.8693918015, -16774.6245584623, -28359.642891317, -26079.4266600097, -15762.0725871037, -27652.42 [...]
+22925.4185382126, 11409.5751576866, 1473.84042634176, -289.333585062919, 15696.8521114651, 20718.8727783905, 3354.44848572092, -1725.51747249096, -5399.44869897104, 1738.34398331382, -29567.7952538679, -17850.8893411041, -20779.1726006947, -9676.0168345009, -19347.8046904254, -12662.1650068178, -8210.86770870646, -35375.4259323413, -22329.7720248643, -16174.3130343078, 12451.8966947555, -87.254772531047, -1567.60364543998, -4326.28417012498, -661.141368027707, -6386.26520724419, -13501.5 [...]
+31327.4400804275, 35012.4667905897, 23044.8787010987, 19402.4835721628, 31364.8050343116, 24965.7644145448, 28368.8928587656, 23776.0227874576, 13827.7250210722, 6784.14357883076, 14334.9884151126, 8552.99220603292, 23248.7454693856, 12350.2615396054, 15445.7129351442, 1470.53657326861, 2955.28030102643, -7176.00336271319, 9647.10067141893, 24769.5258667533, 5453.53918829868, 13639.6972338416, 10415.4351477660, 17471.7743253583, 11003.0278218941, -307.590233794882, -20959.9611062886, -27 [...]
+7836.15382021314, 10087.2840972871, 18853.6483651217, 9488.91105817737, 14319.3055391731, 9139.83365094003, 9186.71152043761, 3100.61241047205, -2036.71660066364, 15270.8593462659, 5337.6185690221, 15590.5973286951, 587.459525414461, 14379.3819998797, 13159.4379290144, 8735.2627798229, 24315.7128819225, 13437.0598497678, 15125.3839505386, 5240.34997560115, -12083.8101694021, -20044.2212506940, -10302.5063653250, -10861.0611392636, -24903.4733587805, -15077.9530302868, -10150.2969348493,  [...]
+-8483.56500894135, 2093.26411319915, -4667.79510378065, -10306.8127917267, -5352.94963588973, 10989.9742616124, 9557.78658786914, 1956.48657549935, -9115.80093316482, 5416.34823395799, -8311.25461647789, 6806.81791277206, 26731.4074957994, 9524.61052372268, 10440.5102529958, -8295.31609185803, 1756.23912974529, -14366.9521240412, 16239.1016682221, 1182.14054087231, 1940.51230753458, 4668.36594987022, -8194.74703523413, 2446.94466081860, 9814.82598745489, 2723.79258057738, -2451.034569373 [...]
+7429.05008744107, 7708.2384085044, 1351.54858079023, -92.0371914994861, -5799.07533645048, -795.054742321257, 11887.9955017587, -3150.40835423025, 3629.49535235535, -802.676894786416, 20304.5638785741, 6548.14170919209, 23550.1453592031, 13101.4148276718, -3048.91952764621, 16583.8614526022, 10753.1450006117, 10978.9853267598, 14654.0949341901, -6676.84257356325, 14687.1228966863, -170.567871720559, 84.6402675967605, 67.914567141655, -2601.21651762912, -6790.3188617584, -11425.9693410215 [...]
+-12410.8567022458, -8569.49677601952, -17817.0038723064, -2239.67330289061, 2740.82502797925, 7082.03786667672, 1133.56116074112, -12777.5194604306, -842.120031929784, -1749.87511895618, -5510.86566750603, -15230.9283831494, 11090.7824295788, -2989.23774836295, -5553.6453775164, -5430.01349111245, 1078.62416238015, 11992.7649132294, 9168.0361756188, -14002.6230480376, -1585.87296927161, -1000.50633708124, -5096.11742550818, -3296.42479712346, 5703.83636309778, -1545.19717269908, 6686.440 [...]
+20828.261077242, 65.4142508988458, 7184.56538443576, 15363.6811997191, 23025.0404268868, 27125.5694530561, 6526.47372415717, 7953.21734556215, 22629.8211541341, 17188.4702205293, 22176.6629046080, -3187.13882517292, 4745.87176050064, -9788.1496184393, 3934.02421269956, 15271.1390794438, -3485.01540462061, 4822.31640380749, 711.914958790844, 6257.71230513357, -3829.7515634211, -526.672217260612, 4299.59856093972, -7612.94680948234, -7351.966550602, -9774.4925364353, -17658.3999121250, 511 [...]
+4511.6380581371, -7220.1220440328, 19512.2299290816, -1628.36049454206, 8813.90872264858, 4623.62322027022, -12343.1604266602, 14214.2451605105, -945.12595773729, 8166.55261680481, 967.017009450826, 17630.2555744113, 12988.7601774969, 1609.84968168584, -14669.5034802537, -2804.76367834538, -1824.53047108108, 6868.51995166788, 8489.40075549024, 3234.53060187039, 3265.47272034183, -14125.0202655203, -1796.46885587022, -2780.71836871944, -5638.15348390291, -4026.04917819137, -8308.441434926 [...]
+20763.5749221521, 7441.45387339113, 8923.57757116223, -536.84359689983, 9808.103930703, 11831.5640317899, 21048.2964481251, 8488.0497336738, 19891.5453882583, 7929.8147346554, 17951.5014553911, 28411.3700061888, 18700.6210309611, 9670.93261350816, 13953.4096113579, 11005.4421713333, 18136.4536327668, 18154.7304544074, 32486.2129834996, 15985.4427083669, 2458.42793428064, 17605.1442292783, 16695.5444518183, 27554.7945102999, 12343.9240506933, 9918.50355190077, 27271.2803431316, 30157.6439 [...]
+-473.537579527047, 27300.6822580502, 11880.9321082215, 28950.4105340119, 7029.58967520103, 6644.7013840671, 12295.2153879764, 11551.4726234226, 28165.4451886146, 20673.9913053711, 2216.95316700048, 5058.21450112534, -4963.75571841592, 586.793550524651, -8407.68872961308, 14272.5959714964, 1246.17162962856, -987.54063183096, -1727.78675867920, 9219.9038536213, 2566.201720263, -12487.1249992599, -14919.4356612735, 6579.06932586927, -3289.05832090164, -714.633549475988, -9671.69196186684, - [...]
+13098.865659421, -1320.42167609963, 9597.7010291581, -3252.33666960166, 290.681307466557, -4288.28338310789, 8607.5974633821, 12616.6759863984, -5413.41073166871, 7112.41529907053, 10103.3194292182, 14960.5463070989, 7168.90957410897, 3192.54881508931, 7296.76079208701, -8819.2113460278, 4933.82904727587, 3329.79844108541, 91.720988024313, 7312.35944790553, 11132.0460527702, -3654.69924208916, 7389.24760070728, 1238.60702520973, 6839.63129483859, 6991.5519352602, 9726.46226293587, 3079.6 [...]
+4356.91652195379, 20493.177456557, 21122.6811250576, -6409.1559483248, 11666.6313615021, 8151.30031214161, 361.382217652824, 15840.3531314811, 28973.2435611162, 17181.0874660218, -570.325042028704, -12300.8681683908, -650.062404145908, 3017.27602020916, -7910.85072420029, 12211.0769634475, 5011.72306557138, -2289.50930957602, 3602.13263318425, 5639.10500555894, -14037.1275994273, -10681.1246270986, -22469.9323243905, -28118.1942313947, -11066.3839549119, -7820.05685135151, 1706.113828122 [...]
+-13129.9408970886, -23037.0440925190, -17648.2665126796, -33685.4999959141, -11387.6587287334, -4701.42486587347, -17681.9398658118, -27381.6286736912, -25574.7576077386, -11477.8991690867, -4394.10387359793, -3675.93666987085, 2454.94908174094, -8193.96828883215, 4152.53989710516, 5497.172570131, -6331.69866687105, -158.729364622437, -2248.14903119320, 1245.52606815796, 10897.2602999651, 558.821325729237, -2790.16374656115, 7706.64831865696, 9191.91474582821, 4278.9723184179, 7887.27583 [...]
+-1815.38681215447, 6578.6792229656, -10663.9259325226, -6811.1818054898, -11614.2163592679, 4623.59188918957, -10066.1971934396, -4015.64289454964, 7268.45888558195, -11796.2878951542, -2163.50667397387, 6440.17817826848, -4965.1830687819, 3520.18016834601, 1729.13342072459, 6826.35027530532, -3712.86149913919, -3100.13070709895, -6844.02292049473, -8599.61245806704, 3623.12447929776, 23334.6893757227, 5265.47924707419, 14509.0614296957, 11627.4724036372, 4416.59008150815, -10552.6070604 [...]
+6471.84616768458, 26642.8840610038, 10530.0934014904, 1621.72430847171, 12153.9240156754, 8299.92519413113, 11882.6802235450, 16818.1742873446, 16178.2946943227, 8186.84184343817, -7245.43972720843, 12715.2161775491, 889.180209825137, -5682.67015296868, 8097.4118698447, 4177.56650994013, -3949.45592469329, 3725.70912634372, 686.22157707431, 19002.6706229407, 3549.35985249585, 3192.65012868318, 3844.64493581527, 13824.7649481300, 6114.43628607113, 8198.74275452524, 11370.8144608183, 19624 [...]
+434.421552611843, 20725.4059038545, 3325.27734663698, 9230.69829334288, 15866.2164973073, 7700.47597488493, 4620.67658450415, 8066.97589893684, 7197.7799121576, 5722.98499791521, 1426.77185026125, 8316.76685761328, 6793.7953226192, 3703.52376344913, 5589.64436087386, 13143.7142477538, 14241.7882660025, 8495.27438234777, 8230.5210892107, 17836.6822835272, -8259.21925058806, -1144.96672625953, 4915.64384185803, -2707.92905917774, -7663.63884920773, 16270.3422788412, -1420.04314660869, 3513 [...]
+-2091.2832659658, 12506.0151476254, -4821.73873501341, 4784.80447397293, 12206.5695880808, 7753.68830423962, 1405.16219829012, -16250.9450180204, -2759.46177160971, 25221.37650131, 15066.0859762617, 14692.6868975397, 14192.7641524587, 12986.6246284937, 2057.54420669001, 15643.5898002976, -13054.9723388901, 8524.38936775538, -5931.34917949069, 14199.957356027, 1175.49056097756, -9441.72020525624, -32377.0784278025, -6302.20838659534, -7096.71145608594, -811.74705403735, -14527.6879490394, [...]
+-7797.08753422416, -21197.0501096036, -2391.11777349593, -393.646257008412, -10395.9023496597, -5978.43629184479, 6194.08560565781, -7037.66141688311, -8169.18657743173, -30139.0802778738, -2256.79044841064, 4317.28297332428, -3189.53121081645, -1619.07560662716, 10258.1899125567, 11743.4006964012, -2271.19775934578, 9715.06671839471, 7316.60953931426, 3587.08074906328, -22254.4629897054, -16360.3125892641, -27073.8853728814, -25139.4971218947, -28943.3068857739, -13254.6173115364, -1331 [...]
+12456.3455270370, 21997.6090829129, 13375.8557757904, 23034.9308888277, 31413.7989016632, 24277.460824427, 13238.2357757419, 24405.6071663654, 18125.7854114592, 26766.8520188256, 4167.66153950891, -16584.9434516220, -7672.38599348528, -14476.5481077366, -1121.57456553667, -20359.0266848009, -4735.31143915737, -6292.536450173, -1404.27624228322, -17517.8140423798, -9164.92566052779, 5936.83144222593, 5636.70871835583, -9897.54949779196, 1224.93116672532, 3797.47977786013, -4644.9173402789 [...]
+-17996.1473535692, -14992.5152288488, -16940.4696180642, -6951.33527516873, -14757.0207899748, -30909.4997194321, -29363.4852661242, -16741.2819608815, -18979.7218150686, -6806.46844792049, 6045.95469128322, 3675.94593791496, -1164.04341373329, 1058.71126611152, 15137.4157822537, 4380.21384830884, -10212.7256577047, 8964.29660919424, 17300.0681243709, 8675.6112861564, 7830.62810626255, 13155.2797782834, -2117.55853270690, -1141.42683244875, 7671.4112929527, 12006.3332355573, -3104.807799 [...]
+-1050.2488557224, -3731.98713339095, -846.416014125237, 4480.59335544797, -7413.44075608205, 5808.65112719862, -10966.2729981366, -16325.1154047783, -9828.6735908601, 13571.8952694605, -9460.81342539286, -13837.3562170876, -20014.0539677616, -5641.285668165, -14545.5888075261, -19707.5886922239, -19769.7043998469, -13682.7361445785, -10891.3454322155, -12489.3133732930, -13228.5121240038, -19358.5680765402, -6052.4080891004, -19117.6991748425, -3466.45534028131, 1608.41608383806, -14380. [...]
+-8296.23741110619, -3108.02697482715, -4326.24974673472, -406.156169329362, 4617.94693417362, 2754.49154880634, -13441.9498833478, -7657.14233968152, -15457.2913293570, 988.15173222809, 8515.58922261227, 22488.5441010424, 31475.0780616354, 23737.1613524894, 38006.1029232656, 24901.0271124834, 7954.3050144608, 29268.9859983787, 32061.729743893, 17360.5630527913, 11153.4667919815, -11799.7772637305, 16780.8055608943, -11686.6740556748, 4182.51222866334, 8314.56285783229, -7115.05662623375, [...]
+1756.83469797919, 13196.3221058064, 6439.22674556502, 3066.31491531685, 14879.5128925981, 8523.2213932102, 11330.9725686294, 11796.6954809931, 7018.5533032018, 5401.02200174837, -8426.75632123201, -8467.70084045542, -11331.7222709165, -22628.5169728596, -14791.598993565, -3802.42551072944, -5043.16352150959, -16910.2699842359, -9471.03796466057, -2264.61354678457, 5615.35490455812, 6109.2656045121, 5122.10878110868, 5313.79908447189, -4784.27200460896, -2131.42118649028, 1885.08075700039 [...]
+-16233.3498442526, -10507.8613098881, -18465.2399235176, -8375.7325671037, -10602.5608662256, -2533.35769286802, -25366.8647132963, -3388.60743941129, -8891.4397949604, -11207.6922183694, -4625.47879795806, -13671.4020913097, 7180.16198800299, -4127.53654489762, 18596.9371452786, 5543.87334195921, 12323.2314349146, 577.847371400736, -2309.83060465616, -225.875779868171, -1586.90834393339, 4296.25738332913, -694.119667440401, -9796.42025295079, 4021.28855572783, 4186.92860580503, -10996.8 [...]
+-9555.78329396863, -14090.5052292313, 15721.9867287270, -5728.64007722144, 1162.75039948736, 12961.0419589864, 16889.7188132956, 8523.79781009674, -4721.81948492786, 2096.21538004078, 24306.4080761894, 4284.27066959728, 2247.10454867118, 18791.0332221725, 6975.07733626019, 8628.8838416515, 10677.6062112245, 15038.6672224448, 14217.5314979428, 4982.14845710551, 14556.5572054067, 17165.3699656926, -3114.56845109158, 13297.3515691133, 18622.9707520679, 32108.4110588599, 7863.0171392756, 261 [...]
+1133.89621430254, 9063.26225692185, 4480.37291209606, 5184.18903744694, -18352.0253293750, 6969.61535755444, 4236.88949306382, -3908.61563435498, 4666.54619248151, 17342.5457091736, -393.868156939792, -13657.7936596209, -1279.34902377059, -8317.15193857493, -58.8877504787649, -2141.72468209227, -4357.05077902383, -14117.7545032755, -3951.98005546328, 8538.59269392775, -25597.5098296736, 4300.34658048712, 9604.36690325535, -6718.39686685366, 5667.65987358963, -6798.55611295575, -5185.3949 [...]
+-8288.7715736467, -3686.54667480057, -5624.28741738852, -2841.3547828954, 2801.30840003491, -12241.9259515230, 3647.78599413674, -2082.56842350043, 10191.2955645597, -3469.67577892846, -995.077403718378, -3997.30253097062, -6970.97692392992, -6874.66627197904, -3351.45249769788, 400.824905886698, -3573.08077347297, 4331.67261460641, -3708.070724281, -1982.90416635505, -13973.9404716063, 4158.53277383497, -9401.70909492328, -2860.23465604998, 8916.04168387037, -6594.65894516702, 17210.279 [...]
+-15234.2721918057, 11043.4957627384, -9025.36361831656, 8808.90025187652, 8447.20790346727, -6408.29096044713, -5418.8071775197, -2825.3978198472, -7712.48184237697, 2318.96386161366, 11971.0017443378, 21345.3062422569, 17733.4920903876, 55126.4088882742, 32603.947207044, 23510.0728991161, 19779.6740275101, 14315.4643512055, 19697.6610624550, 28110.6645347372, 7044.90482841486, 9671.39656021734, 15702.2021691222, 12186.466162481, 17334.6824576729, 21972.028678446, 4159.84710381708, -825. [...]
+-6631.0729789972, 762.270882838465, 2571.85353115647, 2402.55627682269, -2546.22800055432, -3470.49411055630, 4649.35152720687, 8876.36105616268, -7093.5513301556, -12585.6058964723, 8295.71564165509, 6293.53012994768, 3110.35185066887, -375.737614426636, 11611.5521672016, -2788.34206068836, 5593.48264714852, -6165.24579226854, 10031.0181375007, 8503.83508897963, 3886.55072657893, -1649.57386242026, 8707.19498226522, -3734.03267986138, 1216.69546658279, -8017.93210987962, 25.073260536589 [...]
+-9663.51019171004, -4373.75674795653, -19923.4303430522, -22543.1892758511, -16556.9993925369, -24541.9399641617, -6824.21794422178, -12910.4515243755, -23616.6310677125, -15189.1554088555, 21678.4115754071, -3686.61667788022, 19333.8377470084, -7550.02124628555, 9217.24575306355, 1036.31475894461, 6084.68600165555, 6301.8968366051, 2891.49735480080, 2791.51741238959, 9508.80303853283, 10636.1787717756, -2924.53478225754, 6775.27783789377, 30036.0895750023, -3609.07190829313, 19819.66181 [...]
+16155.1568040035, 23864.1151753102, 22686.1045984651, 22390.5997698463, 12669.8338175437, 19242.0425017085, 27068.7150526775, 36478.332260579, 20674.8469965699, 16635.5007261650, -10182.6346737166, -17619.3390955923, -29858.0143706519, -7360.74299970326, -1902.51428216528, -17142.9627456959, -203.046723459570, -3347.31795905215, -15559.9936179621, 1617.64544387121, -13140.3980063881, -2318.35665067926, -10799.911267929, -2548.3401036417, -9360.10312979609, -21217.2398817488, -6209.697397 [...]
+10496.0524135734, -14008.6294277343, -2085.12653731842, 7586.73451530087, -4032.35463412236, 4911.43219084504, -963.45447494407, -8657.86027423107, -3388.18080871235, 6259.19516937297, -13720.1358438782, -24075.1033251136, 2698.78083931095, -9236.3552304343, 9281.2068018418, -10976.0975555526, -13582.1549175507, -8977.09695783353, 656.984181983908, 234.368810417839, -11200.5945421345, 2750.44037054746, 4168.8189713143, 8878.92480945832, -4248.59483239462, -5455.77383452543, -3763.2325501 [...]
+-5698.28598976872, 1392.16573433746, 12699.0649322642, -13171.4482125847, 9957.45775026494, -3905.87855143975, 851.584536994152, -11261.1379368796, -7899.72716529601, -759.237182716893, -8660.26489174855, 676.037567617688, -1942.97850145426, -18997.3846105551, 10886.1330577964, 4465.43761230119, 3519.33335581216, -7944.53424826385, -13242.6813275257, 2138.28398887331, 12165.2690297710, 5616.82277323151, -10583.6819737146, -7112.08296495578, 13435.4078954849, -918.355085873962, 16766.0738 [...]
+37811.0768431929, 30352.1099463612, 40093.3799579439, 32613.2635429629, 33262.7393285135, 38089.1435786293, 29449.7485988607, 27560.8470870125, 27383.9921328348, 30320.4001568388, 5920.61250974934, 4845.97043347801, 5665.1139592662, 400.238753189125, -7347.27119050806, -5831.29056124538, -6020.15399036825, -1285.59066963546, 11339.4171266598, 10690.9734964725, -4989.06321240507, 9709.54098507013, 14101.6686119332, 5502.62161615187, 13741.1670990102, 15723.8245140797, -16010.3878623226, 2 [...]
+
+double y20[100] = {
+13859695.9606591, -98287661.4237975, -47799299.7409104, -109793164.888451, -12698136.6609376, -60456581.2979678, -150768744.543825, -23964285.5880853, -130379300.584754, 70029823.3728867, -47318714.3541473, 49055880.7066229, -9827745.2778151, -29606522.251912, 46145889.2551197, 114840537.761665, 42707154.0620333, -123043360.082454, -120293855.495978, 95925531.6398537, -48916.4326201145, -114107160.110654, -13831767.3361138, -149964472.825251, -4090922.89296979, 137983758.26534, -40551982 [...]
+
+double lars20[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -16.98176 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 3.92024115025892160, 240.14835479195955000, 376.25311598184982000, 487.76574346582714000, 498.23916093288221000, 641.02512849612799000, 675.17203500583275000, 706.29802051439117000, 731.13884779339776000, 786.7788312396 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -151.63169682211438000, -184.41386520863196000, -279.07687926482765000, -499.95271909726904000, -561.13215959750312000, -572.10977222590031000, -573.12446705376021000, -689.50107331143556000, -691.61225993533913000, -822.32741302373120000, -890.02655329118238000, -924.17353906386654000, -928.03787029832745000, -1003.52036785767020000, -1020.89490156222520000, -1054.15471947635070000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -22.19607031307614900, -23.94665582773177800, -235.15053736166251000, -237.62738555542458000, -361.75683154661635000, -436.44209950738542000, -506.12165732294238000, -511.89479885972668000, -566.76684770094812000, -574.04960053199284000, -657.71872466270213000, -740.534045569231350 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 127.77039486626988000, 244.53805127360809000, 477.75707147245453000, 498 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -85.10612012131888100, -298.35802874983563000, -361.13409111723496000, -373.00867913057493000, -373.87936937324037000, -466.36358611089662000, -468.46308102480577000, -599.88556208092348000, -681.56601991502362000, -735.02323822271921000, -740.57074395721986000, -777.95737469231346000, -783.76201833226435000, -796.66450900568475000, -806.16468 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 138.40499685995763000, 149.60600757924109000, 256.25735893664250000, 254.80390925543685000, 294.48155235667491000, 330.54924464176509000, 409.95358475481345 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 10.86361639095124000, 151.33721247319318000, 189.98708484516766000, 212.11732675978539000, 225.79309263978180000, 255.02110779799955000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 91.83493484872840900, 122.84734800895492000, 125.38484338014678000, 412.65501003031295000, 417.00420423780753000, 552.52531074635897000, 657.96374150560189000, 683.31846382717913000, 682.45154063340112000, 601.22991404117954000, 606.10793045413936000, 590.92099526954587000, 576.55496185607137000, 522.3 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 161.74185633004478000, 233.99209977447811000, 230.62657117841684000, 227.05316686021823000, 254.79596489239879000, 260.89716439862724000, 254.32390511684397000, 250.90147854824517000, 215.6066584395 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 62.26890100951257500, 65.32178 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -788.79122505751184000, -808.14659996278624000, -866.03641636801808000, -961.94543392472838000, -1036.10725835329800000, -1050.95761826389620000, -1121.98504932474450000, -1285.97065600578890000, -1336.58455898754820000, -1356.79528419598610000, -1358.21795946531420000, -1514.48260798928960000, -1516.56177106128830000, -1621.13057112012830000, -1679.35404159182210000, -1691.38278832565080000, -1692.78036460006960000, -1660.09627396350110000, -1660.21414346357760000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -66.35783064513201200, -66.46313576909945200, -65.10487293002890400, -72.23694719841982700, -57.12289887490674500, -56.82724830935395500, -64.74372579524910500, -57.44189027909439500, -64.79938831051919100, -77.82444880485796500, -98.229628 [...]
+0.00000000000000000, 0.00000000000000000, -17.40286910866907600, -62.45857732533570300, -141.39733169308667000, -165.78587514100252000, -166.76639926368895000, -175.44521372377216000, -192.13247175725860000, -167.42463340278786000, -157.87956750160620000, -157.09246189523901000, -52.02317555135373100, -50.92483562814154400, 1.17981308586051690, 53.69373275992758500, 72.08064393446885300, 75.57476943310238900, 116.26628723700262000, 120.44019332817025000, 114.50668230520884000, 112.985253 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -50.11876745892117000, -121.60075448747821000, -110.39853815322222000, -108.40911394247631000, -106.65477953466866000, -98.75341651888237500, -69.62533117654291500, -58.68081222065988100, -57.65335304233938300, 69.43978049278621300, 70.98799559696225000, 140.33178122783437000, 206.08451824080825000, 231.28938387468307000, 234.13062348727854000, 198.46393540615972000, 197.34179118164340000, 170.91757105210331000, 137.384652146 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -92.46820587718299600, -199.31657195195058000, -220.45901532863928000, -307.67810072530960000, -503.80802789075193000, -552.13378130303295000, -569.11449119212136000, -570.54170420074627000, -731.83939665666662000, -734.67554665352475000, -890.16810366552613000, -1001.30236376355820000, -1068.82364394185240000, -1075.78146307797060000, -1211.46614295277600000, -1244.08018326607040000, -1242.07192258223470 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -0.85660297384114614, -88.49236731895226200, -90.26220063401950700, -197.27866743365246000, -288.93669036641762000, -376.38579633748446000, -385.14838276485165000, -524.52870055424171000, -558.49559936414732000, -577.99705564473754000, -591.78119517273149000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -11.23670622076961000, -57.31629606852146000, -161.17298855098724000, -209.25086445781886000, -225.59342631789013000, -226.84455813744853000, -364.71952932618672000, -366.19940156370512000, -466.84432668970516000, -537.06981443991492000, -604.07161075461704000, -611.90834326816150000, -637.35529195361892000, -643.55727320957772000, -654.66219153320060000, -661.967 [...]
+-15.70330189122266300, -731.60909771214710000, -745.77870722781836000, -774.91125237305994000, -816.11715419707718000, -813.86405241400269000, -812.25233335665257000, -787.28233843866087000, -717.20999563815724000, -728.14528679476950000, -730.64552920335223000, -730.72867545272345000, -737.37007699872015000, -736.67877320207958000, -668.20864895089881000, -617.94703720353277000, -571.53272204863185000, -567.69794052205862000, -555.25526018522578000, -557.02341660849470000, -545.68817162 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -47.72944124026381000, -76.47265259692694900, -83.72338236153869700, -84.07972030791924600, -111.80479343351804000, -113.21157415597845000, -178.63871580410478000, -255.56868764197222000, -313.76657570297755000, -318.36296160835229000, -370.08188678110992000, -377.98909778475928000, -392.34373110996677000, -394.22044190083 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 81.95341736610791400, 147.93697147122478000, 187.20439383549720000, 263.38877307065053000, 27 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -384.06989408840212000, -495.75445174281731000, -568.96137051739686000, -652.26194803464080000, -812.6544132725626 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 65.34728488294709300, 196.16776903405631000, 206.13 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 157.08538117414508000, 285.55292271592685000, 298.79162264199130000, 730.19932251820023000, 791.30760219279216000, 823.99707505795834000, 836.35567209552971000, 857.418306719100 [...]
+
+double larslsq20[2500] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1103.146 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1175.48134047734060000, 1247.51895417843210000, 1133.47263772609060000, 1218.16434116437840000, 1208.81946039937980000, 1098.56086497600380000, 1112.28641025835240000, 1141.57709438746790000, 1084.97862242438920000, 113 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2673.13940428993740000, -2653.53584920701590000, -1846.69910813293360000, -1795.43409390915580000, -1644.11184463139650000, -1167.71287435633050000, -1251.57794134555250000, -1254.54720010304620000, -1322.53878388697600000, -1379.74879731870920000, -1266.67105982901380000, -1147.83350553344390000, -1190.21758904423130000, -1245.39245586139490000, -1243.30621848231070000, -1519.274216 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1226.46960237188520000, -1194.43732144784370000, -1260.61380753011140000, -977.83159277837069000, -891.09414234324277000, -851.95396251776447000, -962.51706710781718000, -903.57981045930160000, -742.59591345005640000, -667.27608220335333000, -1827.78348786105560000, -1920.17891634 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1914.56616171822820000, 1907.80959868616950000, 1918.72418131170210000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1494.46591121880740000, -1549.12350849133330000, -1472.37668657794440000, -1017.27822084956530000, -956.04733155181736000, -915.40442118441422000, -1095.89554629764710000, -1160.32327405945260000, -1135.99565688191960000, -1085.16364984934330000, -1116.94725129241620000, -897.75709955186824000, -858.06723182267206000, -977.09844866161234000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1044.94641644502370000, 909.55065566304211000, 598.00525911645877000, 236.19830733420241000, 849.35065803767202000, 844.30766203560779000, 900.5612649681864 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 747.91738252349444000, 601.46330915000101000, 684.74390302615643000, 521.59608053397085000, 420.59457257977022000, 435.6093312326295300 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1717.46877530863590000, 1805.46178413871300000, 1822.02555082857110000, 1807.44473820862070000, 1716.75759991417680000, 1130.44119124187180000, 1244.57098003994040000, 849.38982315710825000, 623.63420191975081000, 340.96766716103679000, 668.55139356013035000, 378.54040798492150000, 371.9211157980929600 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 851.47343927028840000, 635.95669167122742000, 208.58263389041119000, -15.38830160293370300, 343.69350676074640000, 338.99858801362046000, 162.40064017426022000, 202.15146583238311000, -2.46592792588 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 447.00355191423057000, 260.585 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -2674.91735823312410000, -2263.48618124232460000, -2115.96382078923310000, -1915.14541550683500000, -2269.35608307555410000, -2169.47271138466480000, -2298.20134563117840000, -2247.77933256217560000, -2232.53634052291730000, -2453.35161551634840000, -2309.45862095615170000, -2273.19810281496210000, -2137.91808077457060000, -2067.05351047091150000, -2003.28061167966480000, -1770.17009649594620000, -1787.60043366803100000, -1555.36511770367090000, -1661.722990330059500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -388.54659687625400000, -97.93349232916037300, -59.31270014743535800, -111.91627817362837000, 41.87288259054448500, -36.76851694790678900, -90.11086388766018700, 36.02886874657323100, -167.68978284151359000, -263.35709705795415000, -224.305 [...]
+0.00000000000000000, 0.00000000000000000, -1325.93263748693180000, -1035.27846038386970000, -925.93689977867643000, -571.34685986029274000, -240.61855079377179000, -319.16663019770624000, -290.00660772188621000, 269.94594044040792000, 359.99905084906158000, 369.18846377051489000, 458.12224974072916000, 277.31321875488834000, 223.37475168431266000, 345.85518833923618000, 192.51340963019618000, 312.63748091219395000, 246.65601589605208000, 173.87034381295572000, 31.52993022196315600, 91.31 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1132.25764460101750000, -832.03060201234064000, 75.88490666429260000, 41.43244004916159200, -77.60295140552366900, -52.41032788436361000, 445.99109865279576000, 535.12675433408867000, 629.33472463888063000, 686.51811913092990000, 533.67090716312134000, 436.04125381267335000, 571.90020050686849000, 396.37919414579119000, 426.89758815042484000, 84.17550302386396800, 182.97722871378784000, -198.61000784630679000, -340.267735795 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1011.47138602074380000, -1976.11511892024550000, -1812.88789682669450000, -1752.02865740840460000, -1654.14963102304610000, -1407.58144119553370000, -1490.42259603044730000, -1524.81642569335420000, -1514.99195036529700000, -1582.25682566643490000, -1553.25018963136900000, -1619.59837740134370000, -1511.08251156761300000, -1547.84220360784070000, -1646.24689203484010000, -1661.57234619317210000, -1213.98 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -573.60542137174230000, -513.99239523681831000, -619.17554671451057000, -653.63943094414026000, -798.87656081913769000, -949.17029449162260000, -979.65550589306122000, -971.15155459849927000, -993.30569697394662000, -850.71374847548032000, -788.1263800285293000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -857.57481388677513000, -820.39562607568871000, -770.31344892305344000, -1060.31067280111140000, -1112.27806988397110000, -1063.38644883249090000, -1034.14718284622860000, -808.45809917883457000, -896.03430321876397000, -927.76966787325443000, -1042.92790152378670000, -1143.59990944795480000, -718.89613666449191000, -722.94880348643517000, -809.95811178650911000,  [...]
+-4026.37605163762190000, -2443.45449798428900000, -1811.19819304786440000, -1403.92631579421160000, -1225.64553703660320000, -776.39686296220373000, -690.85917505144539000, -373.77850615068638000, -306.22156405437227000, -921.71845575005614000, -866.29908021113533000, -786.32259414767702000, -769.61623316969633000, -530.08315703503320000, -376.22481585135591000, -338.31630807469611000, -267.52275055774089000, -307.52305356538960000, -515.38459916123713000, -579.65757792223542000, -387.17 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -327.67224622901659000, -585.27616121650260000, -477.12013324896026000, -322.33728416460644000, -246.41900576023775000, -533.62692784130309000, -457.64606121340188000, -683.56897193470752000, -694.95798682709687000, -630.20971873213955000, -535.80725127383437000, -479.20926532373471000, -593.08505375390155000, -420.9528415 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1131.03869311763400000, 1070.67917071282820000, 746.54067211864572000, 734.10160201477618000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1614.76297163923870000, -1925.42790197436310000, -1592.71818607393470000, -1838.81895132103570000, -1803.65534825 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 996.17250644351532000, 1004.45525259465890000, 843. [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1031.03068746467350000, 1127.00482201208620000, 1196.98549179701100000, 2112.57913934803450000, 1573.55437717148540000, 1281.14062382161890000, 1012.39502623673250000, 987.55590 [...]
+
+double lasso20[2900] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 192.82906232821946000, 254.78146974271402000, 360.87140395458715000, 499.05914890679247000, 506.89169771810947000, 526.52306489840544000, 663.17546967185967000, 686.619738125236 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -151.63169682211438000, -184.41386520863196000, -279.07687926482765000, -499.95271909726904000, -561.13215959750312000, -572.10977222590031000, -573.12446705376021000, -625.91647382719248000, -676.64681911454340000, -677.11514791274521000, -773.82380659797855000, -803.58694196343276000, -844.42494637761865000, -879.20955045861206000, -881.15544066221582000, -891.28574354191437000, -96 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -22.19607031307614900, -23.94665582773177800, -119.75523027461799000, -227.87071747801579000, -228.72498875114755000, -324.50386787129509000, -352.88724405905663000, -399.19295066415128000, -479.06815358910501000, -483.92136260779057000, -493.12246690130246000, -543.705326626301940 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 52.740949 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -85.10612012131888100, -298.35802874983563000, -361.13409111723496000, -373.00867913057493000, -373.87936937324037000, -415.83305365270365000, -470.50820626781916000, -470.99450733805804000, -582.09195924062374000, -618.71861883255644000, -687.97252474843845000, -757.02064876023007000, -760.86774493000405000, -764.72889282147241000, -800.79961 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 175.52715545136689000, 185.48394020475635000, 202.95387716966749000, 306.88594562618584000, 305.79759225343338000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 129.13316206553847000, 155.82333018863497000, 166.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 91.83493484872840900, 122.84734800895492000, 125.38484338014678000, 255.69942352885576000, 401.42925720983271000, 402.24513389721335000, 502.72913381899554000, 531.54717187700135000, 593.01524723224543000, 610.91865890416204000, 611.85216998328679000, 606.98246206882902000, 529.50905031695436000, 531.8 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.58869563677854009, 135.26854786788516000, 178.79858337233202000, 239.65874883118744000, 236.29336642018018000, 236.15256077540539000, 245.80875226132980000, 271.85322814484516000, 276.348100553022 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -788.79122505751184000, -808.14659996278624000, -866.03641636801808000, -961.94543392472838000, -1036.10725835329800000, -1050.95761826389620000, -1121.98504932474450000, -1285.97065600578890000, -1336.58455898754820000, -1356.79528419598610000, -1358.21795946531420000, -1429.10440862898890000, -1509.80372627106340000, -1510.43326189037980000, -1592.23028923322110000, -1616.63074340795240000, -1653.66455739364510000, -1662.84722937549100000, -1663.20314684376010000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -30.10195225259918000, -57.24901084455439800, -57.46757182809056300, -49.04952845590296600, -42.37525998038458400, -29.61987620991830600, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000000000000 [...]
+0.00000000000000000, 0.00000000000000000, -17.40286910866907600, -62.45857732533570300, -141.39733169308667000, -165.78587514100252000, -166.76639926368895000, -175.44521372377216000, -192.13247175725860000, -167.42463340278786000, -157.87956750160620000, -157.09246189523901000, -109.42980309537168000, -47.15849344955660200, -46.67641038097725200, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -50.11876745892117000, -121.60075448747821000, -110.39853815322222000, -108.40911394247631000, -106.65477953466866000, -98.75341651888237500, -69.62533117654291500, -58.68081222065988100, -57.65335304233938300, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -92.46820587718299600, -199.31657195195058000, -220.45901532863928000, -307.67810072530960000, -503.80802789075193000, -552.13378130303295000, -569.11449119212136000, -570.54170420074627000, -643.71129684050698000, -711.15038782350450000, -711.70447487097306000, -822.10350794744477000, -856.25573447928821000, -923.15284246971294000, -994.65720900896179000, -998.62993622811246000, -1017.86528614221940000,  [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -0.85660297384114614, -40.61088017503671900, -80.47892027005293900, -80.83568614873263400, -161.99054023712881000, -187.93689963884313000, -251.47917785781013000, -355.58796168042414000, -361.24833331088166000, -380.04790478719400000, -516.15844528571336000, -5 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -11.23670622076961000, -57.31629606852146000, -161.17298855098724000, -209.25086445781886000, -225.59342631789013000, -226.84455813744853000, -289.38888424338865000, -365.12434469180693000, -365.82165570062682000, -449.02399536564764000, -470.37006364230018000, -509.73009817529783000, -584.71282697852337000, -588.74874866040193000, -588.36483355564519000, -600.020 [...]
+-15.70330189122266300, -731.60909771214710000, -745.77870722781836000, -774.91125237305994000, -816.11715419707718000, -813.86405241400269000, -812.25233335665257000, -787.28233843866087000, -717.20999563815724000, -728.14528679476950000, -730.64552920335223000, -730.72867545272345000, -733.74141939393292000, -721.73292005530629000, -721.55093154857298000, -652.47759214588564000, -627.32600829601813000, -568.92491574432415000, -500.24748346516947000, -496.07639261975589000, -494.36001699 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -47.72944124026381000, -76.47265259692694900, -83.72338236153869700, -84.07972030791924600, -96.65666592703917100, -109.81148738065912000, -109.85754077415963000, -161.42616273035202000, -176.85291171641785000, -229.16553499268838000, -296.84388488987020000, -300.31717145763361000, -308.92292686626990000, -357.370677755608 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 56.56026814691159600, 86.13192 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -53.75675537592118800, -415.07693382334236000, -492.88940988376578000, - [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 111.32339081288487000, 264.21937430840870000, 273.01166154139355000, 331.20856330468280000, 737.69570800213683000, 780.3529141391537700 [...]
+
+double lassolsq20[2900] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1266.57154051241330000, 1283.99039898338970000, 1189.66252745693030000, 1259.59364297452180000, 1247.11367591684440000, 1116.22901663986480000, 1123.37049909749610000, 1126.8554 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -2673.13940428993740000, -2653.53584920701590000, -1846.69910813293360000, -1795.43409390915580000, -1644.11184463139650000, -1167.71287435633050000, -1251.57794134555250000, -1254.54720010304620000, -1141.81604688808490000, -1193.33098968270840000, -1312.33285489590890000, -1298.03882783409470000, -1163.45781044210410000, -1070.65121031950980000, -1065.05352167870520000, -1195.589557 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1226.46960237188520000, -1194.43732144784370000, -1260.61380753011140000, -1219.22998002386860000, -1170.34627288492490000, -857.83556477661773000, -824.41733358398335000, -760.94035758742928000, -918.67187580121322000, -942.57818900799168000, -769.51411678719865000, -714.04979043 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1865.0326 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1494.46591121880740000, -1549.12350849133330000, -1472.37668657794440000, -1017.27822084956530000, -956.04733155181736000, -915.40442118441422000, -971.84913695364469000, -1007.02030223017600000, -1200.72305086914250000, -1227.19352196370210000, -1228.99484620941010000, -1137.03611308231210000, -1124.44098343907240000, -880.71377921482951000, [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1141.56402371724970000, 1126.45872174764030000, 727.73270230908440000, 656.89091905425607000, 285.3605296082871000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 564.00614812893525000, 657.01040012137810000, 523.9 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1717.46877530863590000, 1805.46178413871300000, 1822.02555082857110000, 1807.44473820862070000, 1737.69128761728330000, 1301.54595113039640000, 1062.26065770425660000, 1010.29825404330850000, 1073.21344522017350000, 709.45244815368528000, 700.07446317368601000, 460.70147643882444000, 268.60709941484822 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 649.47899418936402000, 885.21503700219625000, 901.95855569745083000, 715.10785983212725000, 217.77154011651541000, 222.84559832582099000, 535.87075039461422000, 359.56144202852761000, 360.7526618726 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, -2674.91735823312410000, -2263.48618124232460000, -2115.96382078923310000, -1915.14541550683500000, -2269.35608307555410000, -2169.47271138466480000, -2298.20134563117840000, -2247.77933256217560000, -2232.53634052291730000, -2453.35161551634840000, -2309.45862095615170000, -2273.19810281496210000, -2249.77186677523060000, -2204.33946816549500000, -2047.70594101908610000, -2021.99296195970240000, -1942.97849211134300000, -1713.38527666990650000, -1696.839443122826400 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -388.54659687625400000, -306.17253403396830000, -298.37661378194105000, -2.17479576374503040, 68.50367108672246300, 70.02717253568437200, 163.01689831793931000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000 [...]
+0.00000000000000000, 0.00000000000000000, -1325.93263748693180000, -1035.27846038386970000, -925.93689977867643000, -571.34685986029274000, -240.61855079377179000, -319.16663019770624000, -290.00660772188621000, 269.94594044040792000, 359.99905084906158000, 369.18846377051489000, 458.12224974072916000, 523.83499883430875000, 484.70008836361779000, 259.91126000449560000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.000000000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1132.25764460101750000, -832.03060201234064000, 75.88490666429260000, 41.43244004916159200, -77.60295140552366900, -52.41032788436361000, 445.99109865279576000, 535.12675433408867000, 629.33472463888063000, 686.51811913092990000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1011.47138602074380000, -1976.11511892024550000, -1812.88789682669450000, -1752.02865740840460000, -1654.14963102304610000, -1407.58144119553370000, -1490.42259603044730000, -1524.81642569335420000, -1514.99195036529700000, -1329.52957875190600000, -1322.44742452739820000, -1436.84554907659320000, -1423.62313740929590000, -1445.76349071193360000, -1388.19092828609220000, -1374.07604857850740000, -1595.67 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -573.60542137174230000, -513.99239523681831000, -446.04681299376659000, -474.08119888374449000, -613.89033736018303000, -618.98108164886037000, -747.88137233765440000, -928.56439500975841000, -896.18677883749945000, -944.76757448486296000, -974.5286751671211500 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -857.57481388677513000, -820.39562607568871000, -770.31344892305344000, -1060.31067280111140000, -1112.27806988397110000, -1063.38644883249090000, -1034.14718284622860000, -1059.57665823930460000, -1134.43334640916870000, -912.32493820059278000, -824.99008554917907000, -817.21683086141616000, -997.39017209261181000, -970.16710980726862000, -576.83242115872645000,  [...]
+-4026.37605163762190000, -2443.45449798428900000, -1811.19819304786440000, -1403.92631579421160000, -1225.64553703660320000, -776.39686296220373000, -690.85917505144539000, -373.77850615068638000, -306.22156405437227000, -921.71845575005614000, -866.29908021113533000, -786.32259414767702000, -769.61623316969633000, -611.62161818208949000, -520.95393525760312000, -267.85207081001039000, -209.48535023027702000, -112.68646608124710000, -122.27217002212254000, -101.88374968625371000, -442.80 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -327.67224622901659000, -585.27616121650260000, -477.12013324896026000, -322.33728416460644000, -246.41900576023775000, -230.43392947952967000, -160.61993544967399000, -448.57903931042199000, -433.13589519090363000, -637.83991244972344000, -669.32061657251188000, -628.56320170594461000, -567.43091243325307000, -520.5248804 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 1118.64706117203290000, 1102.2 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, -1668.55404892908970000, -1631.87037721972300000, -1954.0494408386717000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.0000000 [...]
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 980.99909406707241000, 1105.70260057405560000, 1103.93457121901570000, 2079.38325880784760000, 2106.59487831169870000, 1581.36848124710 [...]
+
+double nnlasso20[350] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 426.53137849561267000, 650.41564512339653000, 828.46143313834330000, 1066.09409378602600000, 1591.60547745790360000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 147.88186073186884000, 312.43167326777581000, 538.36487457183034000, 888.70253064234942000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 9.89653042358718690, 213.91262404287889000, 264.46661490814870000, 301.53919085576314000, 293.93492633093371000, 445.89413660784140000, 
+444.68473588556895000, 455.13257354473643000, 794.24131952937682000, 898.78898579600502000, 946.91290048653593000, 949.62933148539184000, 910.98525273023881000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 171.44614678213455000, 598.70088587371515000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 559.68030160727574000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 169.10759181261574000, 427.86753206719931000, 629.39781262100280000};
+
+double nnlassolsq20[350] = {
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 1628.68139292454320000, 1694.80566270392160000, 1606.26053056478960000, 1574.76769278233590000, 1591.60547745790360000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 837.73086823881511000, 1031.27314151624200000, 1021.99475241291690000, 888.70253064234942000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 1001.98853920099980000, 788.91826783208091000, 500.29418869797513000, 463.49200329133299000, 277.65732966967414000, 445.89413660784140000, 
+2226.90700612196860000, 1502.49117368196650000, 1749.99652168176680000, 1386.48979950140320000, 1157.14386314081710000, 955.44409082380560000, 910.98525273023881000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 538.44169478475897000, 598.70088587371515000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 559.68030160727574000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 
+0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0.00000000000000000, 907.85987428037379000, 981.76593023611554000, 629.39781262100280000};
+
+
+} // namespace larsdata
+
+typedef vigra::ArrayVector<vigra::Matrix<double> > A;
+
+void loadData(A & x, A & y, A & lars, A & larslsq, 
+              A & lasso, A & lassolsq, A & nnlasso, A & nnlassolsq)
+{
+    using namespace vigra;
+    using namespace larsdata;
+
+    x.push_back(Matrix<double>(100, 50, x0));
+    y.push_back(Matrix<double>(100, 1, yy0));
+    lars.push_back(Matrix<double>(50, sizeof(lars0) / sizeof(double) / 50, lars0));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq0) / sizeof(double) / 50, larslsq0));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso0) / sizeof(double) / 50, lasso0));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq0) / sizeof(double) / 50, lassolsq0));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso0) / sizeof(double) / 50, nnlasso0));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq0) / sizeof(double) / 50, nnlassolsq0));
+
+    x.push_back(Matrix<double>(100, 50, x1));
+    y.push_back(Matrix<double>(100, 1, yy1));
+    lars.push_back(Matrix<double>(50, sizeof(lars1) / sizeof(double) / 50, lars1));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq1) / sizeof(double) / 50, larslsq1));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso1) / sizeof(double) / 50, lasso1));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq1) / sizeof(double) / 50, lassolsq1));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso1) / sizeof(double) / 50, nnlasso1));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq1) / sizeof(double) / 50, nnlassolsq1));
+
+    x.push_back(Matrix<double>(100, 50, x2));
+    y.push_back(Matrix<double>(100, 1, y2));
+    lars.push_back(Matrix<double>(50, sizeof(lars2) / sizeof(double) / 50, lars2));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq2) / sizeof(double) / 50, larslsq2));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso2) / sizeof(double) / 50, lasso2));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq2) / sizeof(double) / 50, lassolsq2));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso2) / sizeof(double) / 50, nnlasso2));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq2) / sizeof(double) / 50, nnlassolsq2));
+
+    x.push_back(Matrix<double>(100, 50, x3));
+    y.push_back(Matrix<double>(100, 1, y3));
+    lars.push_back(Matrix<double>(50, sizeof(lars3) / sizeof(double) / 50, lars3));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq3) / sizeof(double) / 50, larslsq3));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso3) / sizeof(double) / 50, lasso3));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq3) / sizeof(double) / 50, lassolsq3));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso3) / sizeof(double) / 50, nnlasso3));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq3) / sizeof(double) / 50, nnlassolsq3));
+
+    x.push_back(Matrix<double>(100, 50, x4));
+    y.push_back(Matrix<double>(100, 1, y4));
+    lars.push_back(Matrix<double>(50, sizeof(lars4) / sizeof(double) / 50, lars4));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq4) / sizeof(double) / 50, larslsq4));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso4) / sizeof(double) / 50, lasso4));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq4) / sizeof(double) / 50, lassolsq4));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso4) / sizeof(double) / 50, nnlasso4));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq4) / sizeof(double) / 50, nnlassolsq4));
+
+    x.push_back(Matrix<double>(100, 50, x5));
+    y.push_back(Matrix<double>(100, 1, y5));
+    lars.push_back(Matrix<double>(50, sizeof(lars5) / sizeof(double) / 50, lars5));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq5) / sizeof(double) / 50, larslsq5));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso5) / sizeof(double) / 50, lasso5));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq5) / sizeof(double) / 50, lassolsq5));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso5) / sizeof(double) / 50, nnlasso5));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq5) / sizeof(double) / 50, nnlassolsq5));
+
+    x.push_back(Matrix<double>(100, 50, x6));
+    y.push_back(Matrix<double>(100, 1, y6));
+    lars.push_back(Matrix<double>(50, sizeof(lars6) / sizeof(double) / 50, lars6));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq6) / sizeof(double) / 50, larslsq6));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso6) / sizeof(double) / 50, lasso6));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq6) / sizeof(double) / 50, lassolsq6));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso6) / sizeof(double) / 50, nnlasso6));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq6) / sizeof(double) / 50, nnlassolsq6));
+
+    x.push_back(Matrix<double>(100, 50, x7));
+    y.push_back(Matrix<double>(100, 1, y7));
+    lars.push_back(Matrix<double>(50, sizeof(lars7) / sizeof(double) / 50, lars7));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq7) / sizeof(double) / 50, larslsq7));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso7) / sizeof(double) / 50, lasso7));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq7) / sizeof(double) / 50, lassolsq7));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso7) / sizeof(double) / 50, nnlasso7));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq7) / sizeof(double) / 50, nnlassolsq7));
+
+    x.push_back(Matrix<double>(100, 50, x8));
+    y.push_back(Matrix<double>(100, 1, y8));
+    lars.push_back(Matrix<double>(50, sizeof(lars8) / sizeof(double) / 50, lars8));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq8) / sizeof(double) / 50, larslsq8));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso8) / sizeof(double) / 50, lasso8));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq8) / sizeof(double) / 50, lassolsq8));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso8) / sizeof(double) / 50, nnlasso8));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq8) / sizeof(double) / 50, nnlassolsq8));
+
+    x.push_back(Matrix<double>(100, 50, x9));
+    y.push_back(Matrix<double>(100, 1, y9));
+    lars.push_back(Matrix<double>(50, sizeof(lars9) / sizeof(double) / 50, lars9));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq9) / sizeof(double) / 50, larslsq9));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso9) / sizeof(double) / 50, lasso9));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq9) / sizeof(double) / 50, lassolsq9));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso9) / sizeof(double) / 50, nnlasso9));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq9) / sizeof(double) / 50, nnlassolsq9));
+
+    x.push_back(Matrix<double>(100, 50, x10));
+    y.push_back(Matrix<double>(100, 1, y10));
+    lars.push_back(Matrix<double>(50, sizeof(lars10) / sizeof(double) / 50, lars10));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq10) / sizeof(double) / 50, larslsq10));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso10) / sizeof(double) / 50, lasso10));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq10) / sizeof(double) / 50, lassolsq10));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso10) / sizeof(double) / 50, nnlasso10));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq10) / sizeof(double) / 50, nnlassolsq10));
+
+    x.push_back(Matrix<double>(100, 50, x11));
+    y.push_back(Matrix<double>(100, 1, y11));
+    lars.push_back(Matrix<double>(50, sizeof(lars11) / sizeof(double) / 50, lars11));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq11) / sizeof(double) / 50, larslsq11));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso11) / sizeof(double) / 50, lasso11));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq11) / sizeof(double) / 50, lassolsq11));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso11) / sizeof(double) / 50, nnlasso11));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq11) / sizeof(double) / 50, nnlassolsq11));
+
+    x.push_back(Matrix<double>(100, 50, x12));
+    y.push_back(Matrix<double>(100, 1, y12));
+    lars.push_back(Matrix<double>(50, sizeof(lars12) / sizeof(double) / 50, lars12));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq12) / sizeof(double) / 50, larslsq12));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso12) / sizeof(double) / 50, lasso12));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq12) / sizeof(double) / 50, lassolsq12));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso12) / sizeof(double) / 50, nnlasso12));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq12) / sizeof(double) / 50, nnlassolsq12));
+
+    x.push_back(Matrix<double>(100, 50, x13));
+    y.push_back(Matrix<double>(100, 1, y13));
+    lars.push_back(Matrix<double>(50, sizeof(lars13) / sizeof(double) / 50, lars13));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq13) / sizeof(double) / 50, larslsq13));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso13) / sizeof(double) / 50, lasso13));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq13) / sizeof(double) / 50, lassolsq13));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso13) / sizeof(double) / 50, nnlasso13));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq13) / sizeof(double) / 50, nnlassolsq13));
+
+    x.push_back(Matrix<double>(100, 50, x14));
+    y.push_back(Matrix<double>(100, 1, y14));
+    lars.push_back(Matrix<double>(50, sizeof(lars14) / sizeof(double) / 50, lars14));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq14) / sizeof(double) / 50, larslsq14));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso14) / sizeof(double) / 50, lasso14));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq14) / sizeof(double) / 50, lassolsq14));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso14) / sizeof(double) / 50, nnlasso14));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq14) / sizeof(double) / 50, nnlassolsq14));
+
+    x.push_back(Matrix<double>(100, 50, x15));
+    y.push_back(Matrix<double>(100, 1, y15));
+    lars.push_back(Matrix<double>(50, sizeof(lars15) / sizeof(double) / 50, lars15));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq15) / sizeof(double) / 50, larslsq15));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso15) / sizeof(double) / 50, lasso15));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq15) / sizeof(double) / 50, lassolsq15));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso15) / sizeof(double) / 50, nnlasso15));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq15) / sizeof(double) / 50, nnlassolsq15));
+
+    x.push_back(Matrix<double>(100, 50, x16));
+    y.push_back(Matrix<double>(100, 1, y16));
+    lars.push_back(Matrix<double>(50, sizeof(lars16) / sizeof(double) / 50, lars16));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq16) / sizeof(double) / 50, larslsq16));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso16) / sizeof(double) / 50, lasso16));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq16) / sizeof(double) / 50, lassolsq16));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso16) / sizeof(double) / 50, nnlasso16));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq16) / sizeof(double) / 50, nnlassolsq16));
+
+    x.push_back(Matrix<double>(100, 50, x17));
+    y.push_back(Matrix<double>(100, 1, y17));
+    lars.push_back(Matrix<double>(50, sizeof(lars17) / sizeof(double) / 50, lars17));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq17) / sizeof(double) / 50, larslsq17));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso17) / sizeof(double) / 50, lasso17));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq17) / sizeof(double) / 50, lassolsq17));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso17) / sizeof(double) / 50, nnlasso17));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq17) / sizeof(double) / 50, nnlassolsq17));
+
+    x.push_back(Matrix<double>(100, 50, x18));
+    y.push_back(Matrix<double>(100, 1, y18));
+    lars.push_back(Matrix<double>(50, sizeof(lars18) / sizeof(double) / 50, lars18));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq18) / sizeof(double) / 50, larslsq18));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso18) / sizeof(double) / 50, lasso18));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq18) / sizeof(double) / 50, lassolsq18));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso18) / sizeof(double) / 50, nnlasso18));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq18) / sizeof(double) / 50, nnlassolsq18));
+
+    x.push_back(Matrix<double>(100, 50, x19));
+    y.push_back(Matrix<double>(100, 1, y19));
+    lars.push_back(Matrix<double>(50, sizeof(lars19) / sizeof(double) / 50, lars19));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq19) / sizeof(double) / 50, larslsq19));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso19) / sizeof(double) / 50, lasso19));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq19) / sizeof(double) / 50, lassolsq19));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso19) / sizeof(double) / 50, nnlasso19));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq19) / sizeof(double) / 50, nnlassolsq19));
+
+    x.push_back(Matrix<double>(100, 50, x20));
+    y.push_back(Matrix<double>(100, 1, y20));
+    lars.push_back(Matrix<double>(50, sizeof(lars20) / sizeof(double) / 50, lars20));
+    larslsq.push_back(Matrix<double>(50, sizeof(larslsq20) / sizeof(double) / 50, larslsq20));
+    lasso.push_back(Matrix<double>(50, sizeof(lasso20) / sizeof(double) / 50, lasso20));
+    lassolsq.push_back(Matrix<double>(50, sizeof(lassolsq20) / sizeof(double) / 50, lassolsq20));
+    nnlasso.push_back(Matrix<double>(50, sizeof(nnlasso20) / sizeof(double) / 50, nnlasso20));
+    nnlassolsq.push_back(Matrix<double>(50, sizeof(nnlassolsq20) / sizeof(double) / 50, nnlassolsq20));
+
+}
+
+#endif // VIGRA_LARS_DATA_HXX
diff --git a/test/optimization/test.cxx b/test/optimization/test.cxx
new file mode 100644
index 0000000..6df89fc
--- /dev/null
+++ b/test/optimization/test.cxx
@@ -0,0 +1,689 @@
+/************************************************************************/
+/*                                                                      */
+/*                  Copyright 2008 by Ullrich Koethe                    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include "vigra/unittest.hxx"
+
+#include <iostream>
+#include <iomanip>
+#include <iterator>
+#include <algorithm>
+
+#include "vigra/matrix.hxx"
+#include "vigra/regression.hxx"
+#include "vigra/quadprog.hxx"
+
+#include "larsdata.hxx"
+
+using namespace vigra;
+using namespace vigra::linalg;
+
+struct GaussianFitModel
+{
+    // pass in scalar data
+    template <class T>
+    T operator()(double data, TinyVector<T, 3> const & p) const
+    {
+        return p[1] * exp(-0.5 * sq(data / p[0])) + p[2];
+    }
+    
+    // pass in vector data
+    template <class T>
+    T operator()(MultiArrayView<1, double> const & data, TinyVector<T, 3> const & p) const
+    {
+        return p[1] * exp(-0.5 * sq(data(0) / p[0])) + p[2];
+    }
+};
+
+
+struct OptimizationTest 
+{
+    typedef vigra::linalg::Matrix<double>::difference_type Shape;
+
+    ArrayVector<Matrix<double> > x, y, lars, larslsq, lasso, lassolsq, nnlasso, nnlassolsq;
+    int size;
+
+    static double w[100];
+    static double gaussianFitData[400];
+
+    OptimizationTest()
+    {
+        loadData(x, y, lars, larslsq, lasso, lassolsq, nnlasso, nnlassolsq);
+        size = x.size();
+    }
+
+    void testLarsImpl(LeastAngleRegressionOptions const & options,
+                       Matrix<double> X, Matrix<double> y,
+                       Matrix<double> const & ref, const char * message)
+    {
+        double epsilon = 1e-10;
+
+        ArrayVector<Matrix<double> > results;
+        ArrayVector<ArrayVector<MultiArrayIndex> > activeSets;
+
+        Matrix<double> offset(1,50);
+        Matrix<double> scaling(1,50, 1.0); // trivial init
+
+        prepareColumns(y, y, DataPreparationGoals(ZeroMean));
+        prepareColumns(X, X, offset, scaling, DataPreparationGoals(ZeroMean|UnitVariance));
+
+        int numSolutions = leastAngleRegression(X, y, activeSets, results, options);
+        shouldMsg(numSolutions == ref.columnCount(), (std::string("wrong number of solutions in ") + message).c_str());
+
+        for (MultiArrayIndex j = 0; j < numSolutions; ++j)
+        {
+            Matrix<double> B(50, 1);
+            for (unsigned int i = 0; i < activeSets[j].size(); ++i)
+            {
+                // activeSets[j][i] is the true index of the i-th result
+                B(activeSets[j][i],0) = results[j](i,0)*scaling(0, activeSets[j][i]);
+            }
+            std::ostringstream s;
+            s << "solution " << j << " differs in " << message;
+            shouldMsg((B - columnVector(ref, j)).norm(0) < epsilon, s.str().c_str());
+        }
+    }
+
+#define VIGRA_TEST_LARS(options, k, name, msg) \
+    testLarsImpl(options, x[k], y[k], name[k], msg);
+
+    void testLSQ()
+    {
+        double epsilon = 1e-10;
+        const char * methods[3] = { "QR", "SVD", "NE" };
+
+        for(int m=0; m<3; ++m)
+        {
+            for(int k=0; k<size; ++k)
+            {
+                Matrix<double> result(50, 1);
+                leastSquares(x[k], y[k], result, methods[m]);
+
+                // check the KKT conditions
+                Matrix<double> r = transpose(x[k])*(y[k] - x[k]*result);
+                r /= x[k].norm(2)*y[k].norm(2);
+                std::ostringstream s;
+                s << "failure in problem " << k << " of LSQ test with " << methods[m] << " solver";
+                shouldMsg(r.norm(0) < epsilon, s.str().c_str());
+            }
+        }
+    }
+
+    void testWeightedLSQ()
+    {
+        double epsilon = 1e-10;
+        Matrix<double> weights(100, 1, w);
+
+        const char * methods[3] = { "QR", "SVD", "NE" };
+
+        for(int m=0; m<3; ++m)
+        {
+            for(int k=0; k<size; ++k)
+            {
+                Matrix<double> result(50, 1);
+                weightedLeastSquares(x[k], y[k], weights, result, methods[m]);
+
+                // check the KKT conditions
+                Matrix<double> r = transpose(x[k])*(weights*pointWise(y[k] - x[k]*result));
+                r /= x[k].norm(2)*y[k].norm(2);
+                std::ostringstream s;
+                s << "failure in problem " << k << " of weighted LSQ test with " << methods[m] << " solver";
+                shouldMsg(r.norm(0) < epsilon, s.str().c_str());
+            }
+        }
+    }
+
+    void testRidgeRegression()
+    {
+        double epsilon = 1e-10;
+        double la[4] = {0.01, 1.0, 100.0, 10000.0};
+        ArrayVector<double> lambdas(la, la+4);
+        Matrix<double> weights(100, 1, w);
+
+        for(int k=0; k<size; ++k)
+        {
+            Matrix<double> results(50, 4);
+            ridgeRegressionSeries(x[k], y[k], results, lambdas);
+            for(int m=0; m<4; ++m)
+            {
+                Matrix<double> result(50, 1);
+                ridgeRegression(x[k], y[k], result, lambdas[m]);
+
+                // check the KKT conditions
+                Matrix<double> r = transpose(x[k])*(y[k] - x[k]*result) - lambdas[m]*result;
+                r /= x[k].norm(2)*y[k].norm(2);
+                std::ostringstream s;
+                s << "failure in problem " << k << " of ridge regression test";
+                shouldMsg(r.norm(0) < epsilon, s.str().c_str());
+                shouldMsg((result - columnVector(results, m)).norm(0) < epsilon, s.str().c_str());
+            }
+            for(int m=0; m<4; ++m)
+            {
+                Matrix<double> result(50, 1);
+                weightedRidgeRegression(x[k], y[k], weights, result, lambdas[m]);
+
+                // check the KKT conditions
+                Matrix<double> r = transpose(x[k])*(weights*pointWise(y[k] - x[k]*result)) - lambdas[m]*result;
+                r /= x[k].norm(2)*y[k].norm(2);
+                std::ostringstream s;
+                s << "failure in problem " << k << " of weighted ridge regression test";
+                shouldMsg(r.norm(0) < epsilon, s.str().c_str());
+            }
+        }
+    }
+
+    void testLars()
+    {
+        LeastAngleRegressionOptions larsOptions;
+        larsOptions = larsOptions.lars().leastSquaresSolutions(false);
+
+        for(int k=0; k<size; ++k)
+        {
+            std::ostringstream s;
+            s << "lars " << k;
+            VIGRA_TEST_LARS(larsOptions, k, lars, s.str().c_str());
+        }
+    }
+
+    void testLarsLSQ()
+    {
+        LeastAngleRegressionOptions larsOptions;
+        larsOptions = larsOptions.lars().leastSquaresSolutions(true);
+
+        for(int k=0; k<size; ++k)
+        {
+            std::ostringstream s;
+            s << "larslsq " << k;
+            VIGRA_TEST_LARS(larsOptions, k, larslsq, s.str().c_str());
+        }
+    }
+
+    void testLasso()
+    {
+        LeastAngleRegressionOptions larsOptions;
+        larsOptions = larsOptions.lasso().leastSquaresSolutions(false);
+
+        for(int k=0; k<size; ++k)
+        {
+            std::ostringstream s;
+            s << "lasso " << k;
+            VIGRA_TEST_LARS(larsOptions, k, lasso, s.str().c_str());
+        }
+    }
+
+    void testLassoLSQ()
+    {
+        LeastAngleRegressionOptions larsOptions;
+        larsOptions = larsOptions.lasso().leastSquaresSolutions(true);
+
+        for(int k=0; k<size; ++k)
+        {
+            std::ostringstream s;
+            s << "lassolsq " << k;
+            VIGRA_TEST_LARS(larsOptions, k, lassolsq, s.str().c_str());
+        }
+    }
+
+    void testNNLasso()
+    {
+        LeastAngleRegressionOptions larsOptions;
+        larsOptions = larsOptions.nnlasso().leastSquaresSolutions(false);
+
+        for(int k=0; k<size; ++k)
+        {
+            std::ostringstream s;
+            s << "nnlasso " << k;
+            VIGRA_TEST_LARS(larsOptions, k, nnlasso, s.str().c_str());
+        }
+    }
+
+    void testNNLassoLSQ()
+    {
+        LeastAngleRegressionOptions larsOptions;
+        larsOptions = larsOptions.nnlasso().leastSquaresSolutions(true);
+
+        for(int k=0; k<size; ++k)
+        {
+            std::ostringstream s;
+            s << "nnlassolsq " << k;
+            VIGRA_TEST_LARS(larsOptions, k, nnlassolsq, s.str().c_str());
+        }
+    }
+
+    void testNNLSQ()
+    {
+        double epsilon = 1e-10;
+        for(int k=0; k<size; ++k)
+        {
+            Matrix<double> result(50, 1);
+            nonnegativeLeastSquares(x[k], y[k], result);
+
+            // check the KKT conditions
+            Matrix<double> r = transpose(x[k])*(y[k] - x[k]*result);
+            r /= x[k].norm(2)*y[k].norm(2);
+
+            std::ostringstream s;
+            s << "failure in problem " << k << " of NNLSQ test";
+            for(int l=0; l<50; ++l)
+                shouldMsg((r(l,0) <= 0.0 && result(l,0) == 0.0) || (abs(r(l,0)) < epsilon && result(l,0) > 0.0), s.str().c_str());
+        }
+    }
+
+    void testNonlinearLSQ()
+    {
+        int size = 200;
+
+        // data are generated from a * exp(-0.5*sq(x/b)) + c + random.normal(0, 0.05)
+        // with (a, b, c) = (1, 1, 0.5)
+        Matrix<double> points(Shape2(size, 2), gaussianFitData);
+        MultiArrayView<1, double> features(points.bindOuter(0)),
+                                  response(points.bindOuter(1));
+        {
+            TinyVector<double, 3> p(2.0, 0.5, 0.0);
+            // test 1D feature vector
+            nonlinearLeastSquares(features, response, p, GaussianFitModel());
+            shouldEqualTolerance(p[0], 0.99661454591763432, 1e-14);
+            shouldEqualTolerance(p[1], 1.0070468569580588, 1e-14);
+            shouldEqualTolerance(p[2], 0.49323974179926072, 1e-14);
+        }
+        {
+            TinyVector<double, 3> p(2.0, 0.5, 0.0);
+            // test 2D feature matrix (which happens to have just one column)
+            nonlinearLeastSquares(points.subarray(Shape2(), Shape2(size,1)), response, p, GaussianFitModel());
+            shouldEqualTolerance(p[0], 0.99661454591763432, 1e-14);
+            shouldEqualTolerance(p[1], 1.0070468569580588, 1e-14);
+            shouldEqualTolerance(p[2], 0.49323974179926072, 1e-14);
+        }
+    }
+
+    void testQuadProg()
+    {
+        {
+            double Gdata[] = { 2.1, 0.0, 1.0,
+                               0.0, 2.2, 0.0,
+                               1.0, 0.0, 3.1};
+
+            double gdata[] = {6.0, 1.0, 1.0};
+
+            double CEdata[] = {1.0, 2.0, -1.0};
+
+            double cedata[] = {4.0};
+
+            double CIdata[] = { 1.0,  0.0, 0.0,
+                                0.0,  1.0, 0.0,
+                                0.0,  0.0, 1.0,
+                               -1.0, -1.0, 0.0};
+
+            double cidata[] = {0.0, 0.0, 0.0, -10.0};
+
+            double xrefdata[] = {0.0, 2.0, 0.0};
+
+            Matrix<double> G(3,3, Gdata),
+                           g(3,1, gdata),
+                           CE(1,3, CEdata),
+                           ce(1,1, cedata),
+                           CI(4,3, CIdata),
+                           ci(4,1, cidata),
+                           x(3,1),
+                           xref(3,1, xrefdata);
+
+            // Solution: x = [0 2 0]'
+            shouldEqualTolerance(quadraticProgramming(G, g, CE, ce, CI, ci, x), 6.4, 1e-14);
+            shouldEqualSequenceTolerance(x.data(), x.data()+3, xrefdata, 1e-14);
+        }
+        {
+            double Gdata[] = {13.0, 12.0, -2.0,
+                              12.0, 17.0,  6.0,
+                              -2.0,  6.0, 12.0};
+
+            double gdata[] = {-22.0, -14.5, 13.0};
+
+            double CIdata[] = { 1.0,  0.0,  0.0,
+                                0.0,  1.0,  0.0,
+                                0.0,  0.0,  1.0,
+                                0.0,  0.0,  1.0,  // add a redundant constraint
+                               -1.0,  0.0,  0.0,
+                                0.0, -1.0,  0.0,
+                                0.0,  0.0, -1.0};
+
+            double cidata[] = {-1.0, -1.0, -1.0, -2.0, -1.0, -1.0, -1.0};
+
+            double xrefdata[] = {1.0, 0.5, -1.0};
+
+            Matrix<double> G(3,3, Gdata),
+                           g(3,1, gdata),
+                           CE,
+                           ce,
+                           CI(7,3, CIdata),
+                           ci(7,1, cidata),
+                           x(3,1),
+                           xref(3,1, xrefdata);
+
+            // Solution: x = [1 0.5 -1]'
+            shouldEqualTolerance(quadraticProgramming(G, g, CE, ce, CI, ci, x), -22.625, 1e-14);
+            shouldEqualSequenceTolerance(x.data(), x.data()+3, xrefdata, 1e-14);
+        }
+        {
+            double Gdata[] = {11.9557487988864, 2.37931476086954, -0.376766571133756, 0.223144794097961, -2.05504905104678, -3.64568978396075, -5.59430271562319, -1.69330364188253,
+                               2.37931476086954, 17.1587043263327, 1.74450492549782, 6.72064470789053, 2.58420114935295, 3.98719003404737, -4.68188629728773, -0.895269022607405,
+                              -0.376766571133756, 1.74450492549782, 15.2278954316710, -4.29485935734649, -8.44276270167430, -1.41513468539932, 0.888903479635589, -2.05250235130216,
+                               0.223144794097961, 6.72064470789053, -4.29485935734649, 14.3556037317358, 3.81380696097931, -1.80980093568364, -2.37884660765149, 0.837452262645372,
+                              -2.05504905104678, 2.58420114935295, -8.44276270167430, 3.81380696097931, 11.6645675398446, 4.09567324453584, -1.30279988467841, -0.235847705894946,
+                              -3.64568978396075, 3.98719003404737, -1.41513468539932, -1.80980093568364, 4.09567324453584, 19.1274437292212, -1.29389377140431, -5.21988129175308,
+                              -5.59430271562319, -4.68188629728773, 0.888903479635589, -2.37884660765149, -1.30279988467841, -1.29389377140431, 15.2120567578534, 1.62881095102307,
+                              -1.69330364188253, -0.895269022607405, -2.05250235130216, 0.837452262645372, -0.235847705894946, -5.21988129175308, 1.62881095102307, 9.35509425897139};
+
+            double gdata[] = {1.69056816359673, -5.99644841532114, -2.18039280131329, 7.36068310570474, -1.56285526687905, 0.556686337262202, -1.39556850584431, -4.21389206565463};
+
+            double CEdata[] = {-0.941710232692403, 1.62075129330797, -0.635514086344284, -2.04726855027881, -0.0879725045073330, -0.0439787231114959, -0.214829528926237, -0.746695232460116,
+                                0.384997223212006, -3.05182514896839, -1.02873559051701, -1.12930451304791, 1.07377722353829, -0.799868398167378, 0.00731478600822687, 0.349275518947309,
+                               -0.278886986977952, -0.0484535232017660, 1.64138030542441, -2.35558595029120, -0.311909083814529, -0.865157920346768, -1.03947227889259, 0.484013190408825,
+                               -0.982943684246934, 0.318202298763980, 0.0194950686266762, -0.561248752100947, -1.47877377059869, -0.119006984268877, 0.832835771260238, -1.00785901222435};
+
+            double cedata[] = {1.00346920730319, -2.67608891438430, 0.0168223926638857, -1.44324544697726};
+
+            double xrefdata[] = {0.11925229791508, 1.15958300340908, 0.14739510825795, 0.00000000000000, 0.72868950990454, 0.09811723636230, 0.18105311441297, 0.75350474556599};
+
+            Matrix<double> G(8,8, Gdata),
+                           g(8,1, gdata),
+                           CE(4,8, CEdata),
+                           ce(4,1, cedata),
+                           CI(identityMatrix<double>(8)),
+                           ci(8,1), x(8,1),
+                           xref(8,1, xrefdata);
+
+            shouldEqualTolerance(quadraticProgramming(G, g, CE, ce, CI, ci, x), 5.96700441471631, 1e-10);
+            shouldEqualSequenceTolerance(x.data(), x.data()+8, xrefdata, 1e-10);
+        }
+        double epsilon = 1e-10;
+        for(int k=0; k<size; ++k)
+        {
+            Matrix<double> result(50, 1), ref(50,1);
+            Matrix<double> G = transpose(x[k])*x[k],
+                           g = -transpose(x[k])*y[k];
+            double m = quadraticProgramming(G, g, Matrix<double>(), Matrix<double>(),
+                                 identityMatrix<double>(50), Matrix<double>(50, 1), result);
+            nonnegativeLeastSquares(x[k], y[k], ref);
+            shouldEqualTolerance(2.0*m, squaredNorm(x[k]*ref-y[k]) - squaredNorm(y[k]), epsilon);
+            shouldEqualSequenceTolerance(ref.data(), ref.data()+50, result.data(), epsilon);
+        }
+    }
+};
+
+double OptimizationTest::w[100] =
+               {3.099060, 2.241629, 0.551814, 9.882278, 9.069642, 6.263997, 14.999678, 7.299786,
+                6.164468, 0.876546, 14.982520, 1.723430, 0.083692, 0.054570, 3.551352, 0.602337,
+                3.629894, 4.573182, 1.967879, 1.218648, 0.517033, 15.419422, 1.523039, 11.806089,
+                1.568337, 0.590645, 0.180897, 0.228799, 13.380690, 1.392058, 8.199124, 0.036260,
+                12.429014, 0.588538, 4.029622, 1.356536, 11.249162, 9.584928, 1.193385, 0.564644,
+                14.343903, 0.772126, 2.372715, 0.865896, 3.259700, 6.267629, 2.852698, 9.231133,
+                0.293141, 14.956796, 7.291935, 11.719283, 0.020900, 0.698194, 0.641376, 7.234362,
+                2.282460, 0.124404, 9.981096, 0.000032, 3.045198, 2.892267, 1.918650, 4.422195,
+                0.012394, 15.208476, 8.253837, 15.333965, 11.425123, 12.661551, 14.815347,
+                0.009620, 0.024826, 0.036806, 10.438017, 0.148247, 4.152140, 0.835896, 1.313798,
+                0.062187, 10.299775, 7.222942, 5.173045, 14.041757, 0.666464, 7.385935, 3.626625,
+                15.613323, 3.012300, 14.823977, 10.285900, 1.518461, 6.132636, 0.381827,
+                10.990995, 0.087974, 10.590009, 0.481253, 5.965124, 5.592337};
+
+double OptimizationTest::gaussianFitData[400] = {
+-4.000000, 0.444541,
+-3.959799, 0.538727,
+-3.919598, 0.518276,
+-3.879397, 0.412113,
+-3.839196, 0.518404,
+-3.798995, 0.541461,
+-3.758794, 0.503801,
+-3.718593, 0.491741,
+-3.678392, 0.460771,
+-3.638191, 0.429009,
+-3.597990, 0.541560,
+-3.557789, 0.486328,
+-3.517588, 0.490383,
+-3.477387, 0.589003,
+-3.437186, 0.536945,
+-3.396985, 0.521662,
+-3.356784, 0.510677,
+-3.316583, 0.580087,
+-3.276382, 0.590646,
+-3.236181, 0.551794,
+-3.195980, 0.535165,
+-3.155779, 0.402148,
+-3.115578, 0.513988,
+-3.075377, 0.502330,
+-3.035176, 0.514688,
+-2.994975, 0.558430,
+-2.954774, 0.375726,
+-2.914573, 0.485836,
+-2.874372, 0.529562,
+-2.834171, 0.494678,
+-2.793970, 0.449333,
+-2.753769, 0.566007,
+-2.713568, 0.539023,
+-2.673367, 0.479504,
+-2.633166, 0.546958,
+-2.592965, 0.575754,
+-2.552764, 0.538718,
+-2.512563, 0.582603,
+-2.472362, 0.550975,
+-2.432161, 0.532177,
+-2.391960, 0.499256,
+-2.351759, 0.558655,
+-2.311558, 0.578853,
+-2.271357, 0.619601,
+-2.231156, 0.577235,
+-2.190955, 0.613576,
+-2.150754, 0.550746,
+-2.110553, 0.568697,
+-2.070352, 0.611762,
+-2.030151, 0.574626,
+-1.989950, 0.679089,
+-1.949749, 0.672611,
+-1.909548, 0.675465,
+-1.869347, 0.691201,
+-1.829146, 0.788757,
+-1.788945, 0.678421,
+-1.748744, 0.606669,
+-1.708543, 0.742304,
+-1.668342, 0.746127,
+-1.628141, 0.739815,
+-1.587940, 0.734492,
+-1.547739, 0.779914,
+-1.507538, 0.830060,
+-1.467337, 0.815632,
+-1.427136, 0.981810,
+-1.386935, 0.834181,
+-1.346734, 0.864140,
+-1.306533, 0.811485,
+-1.266332, 0.961096,
+-1.226131, 0.870745,
+-1.185930, 0.968019,
+-1.145729, 1.004959,
+-1.105528, 1.007269,
+-1.065327, 1.153907,
+-1.025126, 1.141014,
+-0.984925, 1.181630,
+-0.944724, 1.095902,
+-0.904523, 1.220690,
+-0.864322, 1.213103,
+-0.824121, 1.250634,
+-0.783920, 1.286928,
+-0.743719, 1.212951,
+-0.703518, 1.259559,
+-0.663317, 1.345653,
+-0.623116, 1.190765,
+-0.582915, 1.419420,
+-0.542714, 1.390718,
+-0.502513, 1.379101,
+-0.462312, 1.409671,
+-0.422111, 1.363268,
+-0.381910, 1.412171,
+-0.341709, 1.498303,
+-0.301508, 1.520465,
+-0.261307, 1.601247,
+-0.221106, 1.472156,
+-0.180905, 1.450842,
+-0.140704, 1.464438,
+-0.100503, 1.444060,
+-0.060302, 1.494291,
+-0.020101, 1.518935,
+0.020101, 1.498086,
+0.060302, 1.553001,
+0.100503, 1.483252,
+0.140704, 1.472778,
+0.180905, 1.454707,
+0.221106, 1.394221,
+0.261307, 1.388047,
+0.301508, 1.396606,
+0.341709, 1.508361,
+0.381910, 1.474431,
+0.422111, 1.483513,
+0.462312, 1.332036,
+0.502513, 1.282955,
+0.542714, 1.330059,
+0.582915, 1.352545,
+0.623116, 1.348480,
+0.663317, 1.354922,
+0.703518, 1.294989,
+0.743719, 1.345523,
+0.783920, 1.224325,
+0.824121, 1.166410,
+0.864322, 1.104242,
+0.904523, 1.119812,
+0.944724, 1.152129,
+0.984925, 1.071238,
+1.025126, 1.138132,
+1.065327, 1.137580,
+1.105528, 0.924277,
+1.145729, 1.061945,
+1.185930, 0.883011,
+1.226131, 0.991640,
+1.266332, 1.009765,
+1.306533, 0.929159,
+1.346734, 0.839811,
+1.386935, 0.852935,
+1.427136, 0.848105,
+1.467337, 0.831661,
+1.507538, 0.810848,
+1.547739, 0.796379,
+1.587940, 0.794108,
+1.628141, 0.705262,
+1.668342, 0.736556,
+1.708543, 0.808252,
+1.748744, 0.697509,
+1.788945, 0.679672,
+1.829146, 0.741614,
+1.869347, 0.546297,
+1.909548, 0.720579,
+1.949749, 0.617860,
+1.989950, 0.646273,
+2.030151, 0.632174,
+2.070352, 0.664405,
+2.110553, 0.594448,
+2.150754, 0.565075,
+2.190955, 0.655597,
+2.231156, 0.464782,
+2.271357, 0.576826,
+2.311558, 0.501742,
+2.351759, 0.524873,
+2.391960, 0.657789,
+2.432161, 0.549708,
+2.472362, 0.556816,
+2.512563, 0.453497,
+2.552764, 0.502001,
+2.592965, 0.544503,
+2.633166, 0.548955,
+2.673367, 0.558903,
+2.713568, 0.525611,
+2.753769, 0.548909,
+2.793970, 0.542868,
+2.834171, 0.426533,
+2.874372, 0.517917,
+2.914573, 0.552697,
+2.954774, 0.542204,
+2.994975, 0.493085,
+3.035176, 0.469709,
+3.075377, 0.452920,
+3.115578, 0.501249,
+3.155779, 0.563532,
+3.195980, 0.408463,
+3.236181, 0.472325,
+3.276382, 0.447676,
+3.316583, 0.543335,
+3.356784, 0.475859,
+3.396985, 0.479589,
+3.437186, 0.491873,
+3.477387, 0.524637,
+3.517588, 0.482437,
+3.557789, 0.349477,
+3.597990, 0.528711,
+3.638191, 0.523288,
+3.678392, 0.490176,
+3.718593, 0.446792,
+3.758794, 0.518444,
+3.798995, 0.519696,
+3.839196, 0.477128,
+3.879397, 0.489703,
+3.919598, 0.453953,
+3.959799, 0.491464,
+4.000000, 0.422814
+};
+
+struct OptimizationTestSuite : public vigra::test_suite 
+{
+    OptimizationTestSuite() : vigra::test_suite("Optimization Tests") 
+    {
+        add( testCase(&OptimizationTest::testLSQ));
+        add( testCase(&OptimizationTest::testWeightedLSQ));
+        add( testCase(&OptimizationTest::testRidgeRegression));
+        add( testCase(&OptimizationTest::testLars));
+        add( testCase(&OptimizationTest::testLarsLSQ));
+        add( testCase(&OptimizationTest::testLasso));
+        add( testCase(&OptimizationTest::testLassoLSQ));
+        add( testCase(&OptimizationTest::testNNLasso));
+        add( testCase(&OptimizationTest::testNNLassoLSQ));
+        add( testCase(&OptimizationTest::testNNLSQ));
+        add( testCase(&OptimizationTest::testNonlinearLSQ));
+        add( testCase(&OptimizationTest::testQuadProg));
+    }
+};
+
+int main() 
+{
+    OptimizationTestSuite test;
+    int failed = test.run();
+    std::cout << test.report() << std::endl;
+    return failed;
+}
+
+
diff --git a/test/pixeltypes/CMakeLists.txt b/test/pixeltypes/CMakeLists.txt
new file mode 100644
index 0000000..32c2214
--- /dev/null
+++ b/test/pixeltypes/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_pixeltypes test.cxx)
diff --git a/test/pixeltypes/test.cxx b/test/pixeltypes/test.cxx
new file mode 100755
index 0000000..b7cfce4
--- /dev/null
+++ b/test/pixeltypes/test.cxx
@@ -0,0 +1,1038 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                     */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <sstream>
+#include <iterator>
+#include "vigra/unittest.hxx"
+
+#include "vigra/accessor.hxx"
+#include "vigra/tinyvector.hxx"
+#include "vigra/rgbvalue.hxx"
+#include "vigra/diff2d.hxx"
+#include "vigra/box.hxx"
+
+using namespace vigra;
+
+static float di[] = {1, 2, 4, 5, 8, 10 };
+static float df[] = {1.2f, 2.4f, 3.6f, 4.8f, 8.1f, 9.7f };
+
+template <class BVector, class IVector, class FVector, int SIZE>
+struct TinyVectorTest
+{
+    typedef BVector BV;
+    typedef IVector IV;
+    typedef FVector FV;
+
+    BV bv0, bv1, bv3;
+    IV iv0, iv1, iv3;
+    FV fv0, fv1, fv3;
+
+    template <class VECTOR>
+    void printVector(VECTOR const & v)
+    {
+        std::cerr << "(";
+        for(unsigned int i=0; i<v.size(); ++i)
+            std::cerr << (float)v[i] << ", ";
+        std::cerr << ")\n";
+    }
+
+    template <class VECTOR, class VALUE>
+    bool equalValue(VECTOR const & v, VALUE const & vv)
+    {
+        for(unsigned int i=0; i<v.size(); ++i)
+            if(v[i] != vv)
+                return false;
+        return true;
+    }
+
+    template <class VECTOR1, class VECTOR2>
+    bool equalVector(VECTOR1 const & v1, VECTOR2 const & v2)
+    {
+        for(unsigned int i=0; i<v1.size(); ++i)
+            if(v1[i] != v2[i])
+                return false;
+        return true;
+    }
+
+    template <class ITER1, class ITER2>
+    bool equalIter(ITER1 i1, ITER1 i1end, ITER2 i2)
+    {
+        if(i1end - i1 != SIZE)
+            return false;
+        for(; i1<i1end; ++i1, ++i2)
+            if(*i1 != *i2)
+                return false;
+        return true;
+    }
+
+    TinyVectorTest()
+    : bv0((unsigned char)0), bv1((unsigned char)1), bv3(),
+      iv0(0), iv1(1), iv3(),
+      fv0(0.0), fv1(1.0), fv3()
+    {
+        bv3.init(df, df+SIZE); // check that float inputs are correctly rounded
+        iv3.init(di, di+SIZE);
+        fv3.init(df, df+SIZE);
+    }
+
+    void testConstruction()
+    {
+        should(bv0.size() == SIZE);
+        should(iv0.size() == SIZE);
+        should(fv0.size() == SIZE);
+
+        should(equalValue(bv0, 0));
+        should(equalValue(iv0, 0));
+        should(equalValue(fv0, 0.0f));
+
+        should(equalValue(bv1, 1));
+        should(equalValue(iv1, 1));
+        should(equalValue(fv1, 1.0f));
+
+        should(equalIter(bv3.begin(), bv3.end(), di));
+        should(equalIter(iv3.begin(), iv3.end(), di));
+        should(equalIter(fv3.begin(), fv3.end(), df));
+
+        should(!equalVector(bv3, fv3));
+        should(!equalVector(iv3, fv3));
+
+        BV bv(fv3);
+        should(equalIter(bv3.begin(), bv3.end(), bv.begin()));
+        should(equalVector(bv3, bv));
+
+        BV bv4(bv3.begin());
+        should(equalIter(bv3.begin(), bv3.end(), bv4.begin()));
+        should(equalVector(bv3, bv4));
+
+        BV bv5(bv3.begin(), BV::ReverseCopy);
+        should(equalIter(bv3.begin(), bv3.end(),
+                         std::reverse_iterator<typename BV::iterator>(bv5.end())));
+
+        FV fv(iv3);
+        should(equalIter(iv3.begin(), iv3.end(), fv.begin()));
+        should(equalVector(iv3, fv));
+
+        fv = fv3;
+        should(equalIter(fv3.begin(), fv3.end(), fv.begin()));
+        should(equalVector(fv3, fv));
+
+        fv = bv3;
+        should(equalIter(bv3.begin(), bv3.end(), fv.begin()));
+        should(equalVector(bv3, fv));
+
+        TinyVector<double, 5> fv5;
+        fv5.copy(fv3);
+        shouldEqual(fv5[0], fv3[0]);
+        shouldEqual(fv5[1], fv3[1]);
+        shouldEqual(fv5[2], fv3[2]);
+        shouldEqual(fv5[3], SIZE <= 3 ? 0.0 : fv3[3]);
+        shouldEqual(fv5[4], SIZE <= 4 ? 0.0 : fv3[4]);
+        
+        shouldEqual(iv3, (iv3.template subarray<0,SIZE>()));
+        shouldEqual(2, (iv3.template subarray<0,2>().size()));
+        shouldEqual(iv3[0], (iv3.template subarray<0,2>()[0]));
+        shouldEqual(iv3[1], (iv3.template subarray<0,2>()[1]));
+        shouldEqual(2, (iv3.template subarray<1,3>().size()));
+        shouldEqual(iv3[1], (iv3.template subarray<1,3>()[0]));
+        shouldEqual(iv3[2], (iv3.template subarray<1,3>()[1]));
+        shouldEqual(1, (iv3.template subarray<1,2>().size()));
+        shouldEqual(iv3[1], (iv3.template subarray<1,2>()[0]));
+        
+        for(int k=0; k<SIZE; ++k)
+        {
+            IV iv = IV::unitVector(k);
+            shouldEqual(iv[k], 1);
+            iv[k] = 0;
+            should(!iv.any());
+        }
+
+        IV r = reverse(iv3);
+        for(int k=0; k<SIZE; ++k)
+            shouldEqual(iv3[k], r[SIZE-1-k]);
+    }
+
+    void testComparison()
+    {
+        should(bv0 == bv0);
+        should(iv0 == iv0);
+        should(fv0 == fv0);
+        should(iv0 == bv0);
+        should(iv0 == fv0);
+        should(fv0 == bv0);
+
+        should(bv3 == bv3);
+        should(iv3 == iv3);
+        should(fv3 == fv3);
+        should(iv3 == bv3);
+        should(iv3 != fv3);
+        should(fv3 != bv3);
+
+        should(closeAtTolerance(fv3, fv3));
+        
+        should(!bv0.any() && !bv0.all() && bv1.any() && bv1.all());
+        should(!iv0.any() && !iv0.all() && iv1.any() && iv1.all());
+        should(!fv0.any() && !fv0.all() && fv1.any() && fv1.all());
+        IV iv;
+        iv = IV(); iv[0] = 1;
+        should(iv.any() && !iv.all());
+        iv = IV(); iv[1] = 1;
+        should(iv.any() && !iv.all());
+        iv = IV(); iv[SIZE-1] = 1;
+        should(iv.any() && !iv.all());
+        iv = IV(1); iv[0] = 0;
+        should(iv.any() && !iv.all());
+        iv = IV(1); iv[1] = 0;
+        should(iv.any() && !iv.all());
+        iv = IV(1); iv[SIZE-1] = 0;
+        should(iv.any() && !iv.all());
+    }
+
+    void testArithmetic()
+    {
+        IV ivm3 = -iv3;
+        FV fvm3 = -fv3;
+
+        int mi[] = { -1, -2, -4, -5, -8, -10};
+        float mf[] = { -1.2f, -2.4f, -3.6f, -4.8f, -8.1f, -9.7f };
+
+        should(equalIter(ivm3.begin(), ivm3.end(), mi));
+        should(equalIter(fvm3.begin(), fvm3.end(), mf));
+
+        IV iva3 = abs(ivm3);
+        FV fva3 = abs(fvm3);
+        should(equalVector(iv3, iva3));
+        should(equalVector(fv3, fva3));
+
+        int fmi[] = { -2, -3, -4, -5, -9, -10 };
+        int fpi[] = { 1, 2, 3, 4, 8, 9 };
+        int ri[] = { 1, 2, 4, 5, 8, 10};
+        IV ivi3 = floor(fvm3);
+        should(equalIter(ivi3.begin(), ivi3.end(), fmi));
+        ivi3 = -ceil(fv3);
+        should(equalIter(ivi3.begin(), ivi3.end(), fmi));
+        ivi3 = round(fv3);
+        should(equalIter(ivi3.begin(), ivi3.end(), ri));
+        ivi3 = floor(fv3);
+        should(equalIter(ivi3.begin(), ivi3.end(), fpi));
+        ivi3 = -ceil(fvm3);
+        should(equalIter(ivi3.begin(), ivi3.end(), fpi));
+        ivi3 = -round(fvm3);
+        should(equalIter(ivi3.begin(), ivi3.end(), ri));
+
+        should(bv1.squaredMagnitude() == SIZE);
+        should(iv1.squaredMagnitude() == SIZE);
+        should(fv1.squaredMagnitude() == (float)SIZE);
+
+        float expectedSM = 1.2f*1.2f + 2.4f*2.4f + 3.6f*3.6f;
+        if(SIZE == 6)
+            expectedSM += 4.8f*4.8f + 8.1f*8.1f + 9.7f*9.7f;
+        shouldEqualTolerance(fv3.squaredMagnitude(), expectedSM, 1e-7f);
+
+        shouldEqual(dot(bv3, bv3), bv3.squaredMagnitude());
+        shouldEqual(dot(iv3, bv3), iv3.squaredMagnitude());
+        shouldEqual(dot(fv3, fv3), fv3.squaredMagnitude());
+
+        shouldEqual(squaredNorm(bv3), bv3.squaredMagnitude());
+        shouldEqual(squaredNorm(iv3), iv3.squaredMagnitude());
+        shouldEqual(squaredNorm(fv3), fv3.squaredMagnitude());
+
+        shouldEqual(norm(bv3), bv3.magnitude());
+        shouldEqual(norm(iv3), iv3.magnitude());
+        shouldEqual(norm(fv3), fv3.magnitude());
+
+        TinyVector<IV, 3> ivv(iv3, iv3, iv3);
+        shouldEqual(squaredNorm(ivv), 3*squaredNorm(iv3));
+        shouldEqual(norm(ivv), std::sqrt(3.0*squaredNorm(iv3)));
+
+        shouldEqualTolerance(VIGRA_CSTD::sqrt(
+                (typename NumericTraits<typename BV::value_type>::RealPromote)
+                dot(bv3, bv3)), bv3.magnitude(), 0.0);
+        shouldEqualTolerance(VIGRA_CSTD::sqrt(
+                (typename NumericTraits<typename IV::value_type>::RealPromote)
+                dot(iv3, bv3)), iv3.magnitude(), 0.0);
+        shouldEqualTolerance(VIGRA_CSTD::sqrt(
+                (typename NumericTraits<typename FV::value_type>::RealPromote)
+                dot(fv3, fv3)), fv3.magnitude(), 0.0f);
+
+        BV bv = bv3;
+        bv[2] = 200;
+        int expectedSM2 = 40005;
+        if(SIZE == 6)
+            expectedSM2 += 189;
+        should(dot(bv, bv) == expectedSM2);
+        should(bv.squaredMagnitude() == expectedSM2);
+
+        should(equalVector(bv3 - iv3, bv0));
+        should(equalVector(fv3 - fv3, fv0));
+        BV bvp = (bv3 + bv3)*0.5;
+        FV fvp = (fv3 + fv3)*0.5;
+        should(equalVector(bvp, bv3));
+        should(equalVector(fvp, fv3));
+        bvp = 2.0*bv3 - bv3;
+        fvp = 2.0*fv3 - fv3;
+        should(equalVector(bvp, bv3));
+        should(equalVector(fvp, fv3));
+
+        IV ivp = bv + bv;
+        int ip1[] = {2, 4, 400, 10, 16, 20};
+        should(equalIter(ivp.begin(), ivp.end(), ip1));
+        should(equalVector(bv0 - iv1, -iv1));
+
+        bvp = bv3 / 2.0;
+        fvp = bv3 / 2.0;
+        int ip[] = {1, 1, 2, 3, 4, 5}; // half-integers are rounded upwards
+        float fp[] = {0.5, 1.0, 2.0, 2.5, 4.0, 5.0};
+        should(equalIter(bvp.begin(), bvp.end(), ip));
+        should(equalIter(fvp.begin(), fvp.end(), fp));
+        fvp = fv3 / 2.0;
+        float fp1[] = {0.6f, 1.2f, 1.8f, 2.4f, 4.05f, 4.85f};
+        
+
+        int ivsq[] = { 1, 4, 16, 25, 64, 100 };
+        ivp = iv3*iv3;
+        should(equalIter(ivp.begin(), ivp.end(), ivsq));
+        shouldEqual(iv3 * iv1, iv3);
+        shouldEqual(iv0 * iv3, iv0);
+        shouldEqual(iv3 / iv3, iv1);
+        shouldEqual(iv3 % iv3, iv0);
+        shouldEqual(iv3 % (iv3+iv1), iv3);
+
+        float minRef[] = { 1.0f, 2.0f, 3.6f, 4.8f, 8.0f, 9.7f };
+        shouldEqualSequence(minRef, minRef+SIZE, min(iv3, fv3).begin());
+        IV ivmin = floor(fv3);
+        ivmin[1] = 3;
+        int minRef2[] = { 1, 2, 3, 4, 8, 9 };
+        shouldEqualSequence(minRef2, minRef2+SIZE, min(iv3, ivmin).begin());
+        shouldEqual(min(iv3), di[0]);
+        shouldEqual(min(fv3), df[0]);
+        shouldEqual(max(iv3), di[SIZE-1]);
+        shouldEqual(max(fv3), df[SIZE-1]);
+
+        float maxRef[] = { 1.2f, 2.4f, 4.0f, 5.0f, 8.1f, 10.0f };
+        shouldEqualSequence(maxRef, maxRef+SIZE, max(iv3, fv3).begin());
+        IV ivmax = floor(fv3);
+        ivmax[1] = 3;
+        int maxRef2[] = { 1, 3, 4, 5, 8, 10 };
+        shouldEqualSequence(maxRef2, maxRef2+SIZE, max(iv3, ivmax).begin());
+        
+        shouldEqual(sum(iv3), SIZE == 3 ? 7 : 30);
+        shouldEqual(sum(fv3), SIZE == 3 ? 7.2f : 29.8f);
+        shouldEqual(prod(iv3), SIZE == 3 ? 8 : 3200);
+        shouldEqual(prod(fv3), SIZE == 3 ? 10.368f : 3910.15f);
+
+        float cumsumRef[] = {1.2f, 3.6f, 7.2f, 12.0f, 20.1f, 29.8f };
+        shouldEqualSequenceTolerance(cumsumRef, cumsumRef+3, cumsum(fv3).begin(), 1e-6);
+        float cumprodRef[] = {1.2f, 2.88f, 10.368f, 49.7664f, 403.108f, 3910.15f };
+        shouldEqualSequenceTolerance(cumprodRef, cumprodRef+3, cumprod(fv3).begin(), 1e-6);
+    }
+
+    void testCross()
+    {
+        shouldEqual(cross(bv3, bv3), IV(0));
+        shouldEqual(cross(iv3, bv3), IV(0));
+        shouldEqualTolerance(cross(fv3, fv3), FV(0.0), FV(1e-6f));
+
+        FV cr = cross(fv1, fv3);
+        shouldEqualTolerance(cr[0], 1.2, 1e-6f);
+        shouldEqualTolerance(cr[1], -2.4, 1e-6f);
+        shouldEqualTolerance(cr[2], 1.2, 1e-6f);
+    }
+
+    void testOStreamShifting()
+    {
+        std::ostringstream out;
+        out << iv3;
+        std::string expected("(1, 2, 4)");
+        shouldEqual(expected, out.str());
+        out << "Testing.." << fv3 << 42;
+        out << bv3 << std::endl;
+    }
+
+    void testAccessor()
+    {
+        vigra::VectorAccessor<FV> v;
+        FV  pfa[] = {fv3, fv1};
+        FV * pf = pfa;
+
+        should(v.size(pf) == 3);
+        should(v.size(pf, 1) == 3);
+        should(equalVector(v(pf), fv3));
+        should(equalIter(v.begin(pf), v.end(pf), fv3.begin()));
+        should(v.getComponent(pf, 2) == fv3[2]);
+        v.setComponent(5.5, pf, 1);
+        should(pf[0][1] == 5.5);
+        should(equalVector(v(pf, 1), fv1));
+        should(equalIter(v.begin(pf, 1), v.end(pf, 1), fv1.begin()));
+        should(v.getComponent(pf, 1, 2) == fv1[2]);
+        v.setComponent(5.5, pf, 1, 1);
+        should(pf[1][1] == 5.5);
+    }
+};
+
+struct RGBValueTest
+: public TinyVectorTest<vigra::RGBValue<unsigned char>,
+                        vigra::RGBValue<int>,
+                        vigra::RGBValue<float>, 3>
+{
+    typedef TinyVectorTest<vigra::RGBValue<unsigned char>,
+                           vigra::RGBValue<int>,
+                           vigra::RGBValue<float>, 3> Base;
+
+    RGBValueTest()
+    : Base()
+    {}
+
+
+    void testRGBAccessors()
+    {
+        vigra::RGBAccessor<FV> rgb;
+        vigra::RedAccessor<FV> red;
+        vigra::GreenAccessor<FV> green;
+        vigra::BlueAccessor<FV> blue;
+        vigra::RGBToGrayAccessor<FV> gray;
+        vigra::GrayToRGBAccessor<FV::value_type> gray2rgb;
+
+        FV pfa[] = { FV(0.0), FV(1.0), FV(2.0)};
+        FV::value_type fa[] = { 0.0, 1.0, 2.0 };
+        FV * pf = pfa;
+
+        shouldEqual(gray2rgb(fa + 1), rgb(pfa + 1));
+        shouldEqual(gray2rgb(fa, 2), rgb(pfa, 2));
+
+        should(rgb(pf) == vigra::NumericTraits<FV>::zero());
+        should(red(pf) == 0.0);
+        should(green(pf) == 0.0);
+        should(blue(pf) == 0.0);
+        should(gray(pf) == 0.0);
+
+        should(rgb(pf, 1) == vigra::NumericTraits<FV>::one());
+        should(red(pf, 1) == 1.0);
+        should(green(pf, 1) == 1.0);
+        should(blue(pf, 1) == 1.0);
+        shouldEqualTolerance(gray(pf, 1), 1.0, 1e-6);
+
+        rgb.setRed(1.0, pf);
+        rgb.setGreen(2.0, pf);
+        rgb.setBlue(3.0, pf);
+        should(red(pf) == 1.0);
+        should(green(pf) == 2.0);
+        should(blue(pf) == 3.0);
+
+        red.set(4.0, pf);
+        green.set(5.0, pf);
+        blue.set(6.0, pf);
+        should(rgb.red(pf) == 4.0);
+        should(rgb.green(pf) == 5.0);
+        should(rgb.blue(pf) == 6.0);
+        should(vigra::abs(gray(pf) - 4.81) < 0.00001);
+
+        rgb.setRed(7.0, pf, 1);
+        rgb.setGreen(8.0, pf, 1);
+        rgb.setBlue(9.0, pf, 1);
+        should(red(pf, 1) == 7.0);
+        should(green(pf, 1) == 8.0);
+        should(blue(pf, 1) == 9.0);
+
+        red.set(10.0, pf, 1);
+        green.set(11.0, pf, 1);
+        blue.set(12.0, pf, 1);
+        should(rgb.red(pf, 1) == 10.0);
+        should(rgb.green(pf, 1) == 11.0);
+        should(rgb.blue(pf, 1) == 12.0);
+        should(vigra::abs(gray(pf, 1) - 10.81) <0.00001);
+    }
+
+};
+
+struct PixelTypesTestSuite
+: public vigra::test_suite
+{
+    typedef TinyVectorTest<vigra::TinyVector<unsigned char, 3>,
+                           vigra::TinyVector<int, 3>,
+                           vigra::TinyVector<float, 3>, 3> TinyVectorTests;
+
+    static const int N = detail::LoopType<1>::MaxUnrollSize + 1;
+    typedef TinyVectorTest<vigra::TinyVector<unsigned char, N>,
+                           vigra::TinyVector<int, N>,
+                           vigra::TinyVector<float, N>, N> TinyVectorTestsNoUnroll;
+
+    PixelTypesTestSuite()
+    : vigra::test_suite("PixelTypesTest")
+    {
+        add( testCase(&TinyVectorTests::testConstruction));
+        add( testCase(&TinyVectorTests::testComparison));
+        add( testCase(&TinyVectorTests::testArithmetic));
+        add( testCase(&TinyVectorTests::testCross));
+        add( testCase(&TinyVectorTests::testAccessor));
+        add( testCase(&TinyVectorTests::testOStreamShifting));
+
+        add( testCase(&TinyVectorTestsNoUnroll::testConstruction));
+        add( testCase(&TinyVectorTestsNoUnroll::testComparison));
+        add( testCase(&TinyVectorTestsNoUnroll::testArithmetic));
+
+        add( testCase(&RGBValueTest::testConstruction));
+        add( testCase(&RGBValueTest::testComparison));
+        add( testCase(&RGBValueTest::testArithmetic));
+        add( testCase(&RGBValueTest::testCross));
+        add( testCase(&RGBValueTest::testAccessor));
+        add( testCase(&RGBValueTest::testRGBAccessors));
+        add( testCase(&RGBValueTest::testOStreamShifting));
+    }
+};
+
+/********************************************************************/
+
+struct Point2DTest
+{
+    Point2D p11;
+    Point2D p55;
+
+    Point2DTest()
+    : p11(1, 1),
+      p55(5, 5)
+    {}
+
+    void testOStreamShifting()
+    {
+        std::ostringstream out;
+        out << p11;
+        out << "Testing.." << p55 << 42 << std::endl;
+        out << '@' << Diff2D(23, 11) << 3.141592;
+    }
+
+    void testOperations()
+    {
+        should(-p11 == Point2D(-1, -1));
+        should(p55-p11 == Size2D(4, 4));
+        should(p55-(p55-p11) == p11);
+        should(p55-Diff2D(4, 4) == p11);
+    }
+};
+
+struct Point2DTestSuite
+: public test_suite
+{
+    Point2DTestSuite()
+    : test_suite("Point2DTestSuite")
+    {
+        add(testCase(&Point2DTest::testOStreamShifting));
+        add(testCase(&Point2DTest::testOperations));
+    }
+};
+
+/********************************************************************/
+
+struct Rect2DTest
+{
+    Rect2D rect1_1;
+    Rect2D emptyRect;
+    Rect2D bigRect;
+
+    Rect2DTest()
+        : rect1_1(Point2D(1, 1), Point2D(2, 2)),
+          bigRect(0, 0, 10, 10)
+    {
+    }
+
+    void testProperties()
+    {
+        shouldEqual(rect1_1.width(), 1);
+        shouldEqual(rect1_1.height(), 1);
+        should(!rect1_1.isEmpty());
+
+        shouldEqual(emptyRect.width(), 0);
+        shouldEqual(emptyRect.height(), 0);
+        should(emptyRect.isEmpty());
+
+        shouldEqual(bigRect.width(), 10);
+        shouldEqual(bigRect.height(), 10);
+        should(!bigRect.isEmpty());
+
+        should(rect1_1 != emptyRect);
+        should(bigRect != emptyRect);
+        should(bigRect != rect1_1);
+
+        bigRect = rect1_1;
+        should(bigRect == rect1_1);
+    }
+
+    void testOStreamShifting()
+    {
+        std::ostringstream out;
+        out << rect1_1;
+        out << "Testing.." << bigRect << 42 << std::endl;
+    }
+
+    void testContains()
+    {
+        should(!emptyRect.contains(Point2D(0, 0)));
+        should(!emptyRect.contains(Point2D(0, 1)));
+        should(!emptyRect.contains(Point2D(0, 2)));
+        should(!emptyRect.contains(Point2D(1, 0)));
+        should(!emptyRect.contains(Point2D(1, 1)));
+        should(!emptyRect.contains(Point2D(1, 2)));
+        should(!emptyRect.contains(Point2D(2, 0)));
+        should(!emptyRect.contains(Point2D(2, 1)));
+        should(!emptyRect.contains(Point2D(2, 2)));
+
+        should( emptyRect.contains(emptyRect));
+        should(!emptyRect.contains(rect1_1));
+        should(!emptyRect.contains(bigRect));
+
+        should(!rect1_1.contains(Point2D(0, 0)));
+        should(!rect1_1.contains(Point2D(0, 1)));
+        should(!rect1_1.contains(Point2D(0, 2)));
+        should(!rect1_1.contains(Point2D(1, 0)));
+        should( rect1_1.contains(Point2D(1, 1)));
+        should(!rect1_1.contains(Point2D(1, 2)));
+        should(!rect1_1.contains(Point2D(2, 0)));
+        should(!rect1_1.contains(Point2D(2, 1)));
+        should(!rect1_1.contains(Point2D(2, 2)));
+
+        should( rect1_1.contains(emptyRect));
+        should( rect1_1.contains(rect1_1));
+        should(!rect1_1.contains(bigRect));
+
+        should(bigRect.contains(Point2D(0, 0)));
+        should(bigRect.contains(Point2D(0, 1)));
+        should(bigRect.contains(Point2D(0, 2)));
+        should(bigRect.contains(Point2D(1, 0)));
+        should(bigRect.contains(Point2D(1, 1)));
+        should(bigRect.contains(Point2D(1, 2)));
+        should(bigRect.contains(Point2D(2, 0)));
+        should(bigRect.contains(Point2D(2, 1)));
+        should(bigRect.contains(Point2D(2, 2)));
+
+        should( bigRect.contains(emptyRect));
+        should( bigRect.contains(rect1_1));
+        should( bigRect.contains(bigRect));
+    }
+
+    void testIntersection()
+    {
+        should(!emptyRect.intersects(emptyRect));
+        should(!emptyRect.intersects(rect1_1));
+        should(!emptyRect.intersects(bigRect));
+        should(!rect1_1.intersects(emptyRect));
+        should( rect1_1.intersects(rect1_1));
+        should( rect1_1.intersects(bigRect));
+        should(!bigRect.intersects(emptyRect));
+        should( bigRect.intersects(rect1_1));
+        should( bigRect.intersects(bigRect));
+
+        should(!bigRect.intersects(Rect2D(Point2D(3, -3), Point2D(3, 3))));
+        should( bigRect.intersects(Rect2D(Point2D(3, -3), Point2D(4, 3))));
+        should( bigRect.intersects(Rect2D(Point2D(3, -3), Point2D(14, 3))));
+
+        should((rect1_1 & emptyRect).isEmpty());
+        should(!(rect1_1 & bigRect).isEmpty());
+        should((rect1_1 & bigRect) == rect1_1);
+    }
+
+    void testUnion()
+    {
+        should(!(rect1_1 | emptyRect).isEmpty());
+        should((rect1_1 | emptyRect) == rect1_1);
+        should((rect1_1 | bigRect) == bigRect);
+        rect1_1 |= Point2D(3, 3);
+        shouldEqual(rect1_1.upperLeft(), Diff2D(1, 1));
+        shouldEqual(rect1_1.lowerRight(), Diff2D(4, 4));
+    }
+
+    void testSizes()
+    {
+        shouldEqual(rect1_1.size(), Size2D(1, 1));
+        shouldEqual(bigRect.size(), Size2D(10, 10));
+        emptyRect.setSize(10, 10);
+        should(bigRect == emptyRect);
+        emptyRect.addSize(Size2D(-4, -7));
+        shouldEqual(emptyRect.size(), Size2D(6, 3));
+        emptyRect.setSize(bigRect.size());
+        should(bigRect == emptyRect);
+    }
+
+    void testScaling()
+    {
+        shouldEqual((rect1_1 * 4).size(), Size2D(4, 4));
+        shouldEqual((rect1_1 * 4).lowerRight(), Size2D(8, 8));
+        Rect2D r2(rect1_1);
+        r2 *= 5;
+        shouldEqual(rect1_1 * 5, r2);
+    }
+};
+
+struct Rect2DTestSuite
+: public test_suite
+{
+    Rect2DTestSuite()
+    : test_suite("Rect2DTestSuite")
+    {
+        add(testCase(&Rect2DTest::testProperties));
+        add(testCase(&Rect2DTest::testOStreamShifting));
+        add(testCase(&Rect2DTest::testContains));
+        add(testCase(&Rect2DTest::testIntersection));
+        add(testCase(&Rect2DTest::testUnion));
+        add(testCase(&Rect2DTest::testSizes));
+        add(testCase(&Rect2DTest::testScaling));
+    }
+};
+
+
+/********************************************************************/
+
+struct IBoxTest
+{
+    typedef Box<int, 2> IBox;
+
+    IBox rect1_1;
+    IBox emptyRect;
+    IBox bigRect;
+
+    typedef IBox::Vector IPoint;
+
+    IBoxTest()
+        : rect1_1(IPoint(1, 1), IPoint(2, 2)),
+          bigRect(IPoint(10, 10))
+    {
+    }
+
+    void testProperties()
+    {
+        shouldEqual(rect1_1.size()[0], 1);
+        shouldEqual(rect1_1.size()[1], 1);
+        should(!rect1_1.isEmpty());
+
+        should(emptyRect.size()[0] <= 0);
+        should(emptyRect.size()[1] <= 0);
+        should(emptyRect.isEmpty());
+
+        shouldEqual(bigRect.size()[0], 10);
+        shouldEqual(bigRect.size()[1], 10);
+        should(!bigRect.isEmpty());
+
+        should(rect1_1 != emptyRect);
+        should(bigRect != emptyRect);
+        should(bigRect != rect1_1);
+
+        bigRect = rect1_1;
+        should(bigRect == rect1_1);
+    }
+
+    void testContains()
+    {
+        should(!emptyRect.contains(IPoint(0, 0)));
+        should(!emptyRect.contains(IPoint(0, 1)));
+        should(!emptyRect.contains(IPoint(0, 2)));
+        should(!emptyRect.contains(IPoint(1, 0)));
+        should(!emptyRect.contains(IPoint(1, 1)));
+        should(!emptyRect.contains(IPoint(1, 2)));
+        should(!emptyRect.contains(IPoint(2, 0)));
+        should(!emptyRect.contains(IPoint(2, 1)));
+        should(!emptyRect.contains(IPoint(2, 2)));
+
+        should( emptyRect.contains(emptyRect));
+        should(!emptyRect.contains(rect1_1));
+        should(!emptyRect.contains(bigRect));
+
+        should(!rect1_1.contains(IPoint(0, 0)));
+        should(!rect1_1.contains(IPoint(0, 1)));
+        should(!rect1_1.contains(IPoint(0, 2)));
+        should(!rect1_1.contains(IPoint(1, 0)));
+        should( rect1_1.contains(IPoint(1, 1)));
+        should(!rect1_1.contains(IPoint(1, 2)));
+        should(!rect1_1.contains(IPoint(2, 0)));
+        should(!rect1_1.contains(IPoint(2, 1)));
+        should(!rect1_1.contains(IPoint(2, 2)));
+
+        should( rect1_1.contains(emptyRect));
+        should( rect1_1.contains(rect1_1));
+        should(!rect1_1.contains(bigRect));
+
+        should(bigRect.contains(IPoint(0, 0)));
+        should(bigRect.contains(IPoint(0, 1)));
+        should(bigRect.contains(IPoint(0, 2)));
+        should(bigRect.contains(IPoint(1, 0)));
+        should(bigRect.contains(IPoint(1, 1)));
+        should(bigRect.contains(IPoint(1, 2)));
+        should(bigRect.contains(IPoint(2, 0)));
+        should(bigRect.contains(IPoint(2, 1)));
+        should(bigRect.contains(IPoint(2, 2)));
+
+        should( bigRect.contains(emptyRect));
+        should( bigRect.contains(rect1_1));
+        should( bigRect.contains(bigRect));
+    }
+
+    void testIntersection()
+    {
+        should(!emptyRect.intersects(emptyRect));
+        should(!emptyRect.intersects(rect1_1));
+        should(!emptyRect.intersects(bigRect));
+        should(!rect1_1.intersects(emptyRect));
+        should( rect1_1.intersects(rect1_1));
+        should( rect1_1.intersects(bigRect));
+        should(!bigRect.intersects(emptyRect));
+        should( bigRect.intersects(rect1_1));
+        should( bigRect.intersects(bigRect));
+
+        should(!bigRect.intersects(IBox(IPoint(3, -3), IPoint(3, 3))));
+        should( bigRect.intersects(IBox(IPoint(3, -3), IPoint(4, 3))));
+        should( bigRect.intersects(IBox(IPoint(3, -3), IPoint(14, 3))));
+
+        should((rect1_1 & emptyRect).isEmpty());
+        should(!(rect1_1 & bigRect).isEmpty());
+        should((rect1_1 & bigRect) == rect1_1);
+    }
+
+    void testUnion()
+    {
+        should(!(rect1_1 | emptyRect).isEmpty());
+        should((rect1_1 | emptyRect) == rect1_1);
+        should((rect1_1 | bigRect) == bigRect);
+        rect1_1 |= IPoint(3, 3);
+        shouldEqual(rect1_1.begin(), IPoint(1, 1));
+        shouldEqual(rect1_1.end(), IPoint(4, 4));
+    }
+
+    void testSizes()
+    {
+        shouldEqual(rect1_1.size(), IPoint(1, 1));
+        shouldEqual(bigRect.size(), IPoint(10, 10));
+        emptyRect.setBegin(IPoint(0, 0));
+        emptyRect.setSize(IPoint(10, 10));
+        should(bigRect == emptyRect);
+        emptyRect.addSize(IPoint(-4, -7));
+        shouldEqual(emptyRect.size(), IPoint(6, 3));
+        emptyRect.setSize(bigRect.size());
+        should(bigRect == emptyRect);
+    }
+
+    void testScaling()
+    {
+        shouldEqual((rect1_1 * 4).size(), IPoint(4, 4));
+        shouldEqual((rect1_1 * 4).end(), IPoint(8, 8));
+        IBox r2(rect1_1);
+        r2 *= 5;
+        should(rect1_1 * 5 == r2);
+        r2 /= 5;
+        should(rect1_1 == r2);
+    }
+};
+
+struct FBoxTest
+{
+    typedef Box<float, 2> FBox;
+
+    FBox rect1_1;
+    FBox emptyRect;
+    FBox bigRect;
+
+    typedef FBox::Vector FPoint;
+
+    FBoxTest()
+        : rect1_1(FPoint(1, 1), FPoint(2, 2)),
+          bigRect(FPoint(10, 10))
+    {
+    }
+
+    void testProperties()
+    {
+        shouldEqual(rect1_1.size()[0], 1);
+        shouldEqual(rect1_1.size()[1], 1);
+        should(!rect1_1.isEmpty());
+
+        should(emptyRect.size()[0] <= 0);
+        should(emptyRect.size()[1] <= 0);
+        should(emptyRect.isEmpty());
+
+        shouldEqual(bigRect.size()[0], 10);
+        shouldEqual(bigRect.size()[1], 10);
+        should(!bigRect.isEmpty());
+
+        should(rect1_1 != emptyRect);
+        should(bigRect != emptyRect);
+        should(bigRect != rect1_1);
+
+        bigRect = rect1_1;
+        should(bigRect == rect1_1);
+    }
+
+    void testContains()
+    {
+        should(!emptyRect.contains(FPoint(0, 0)));
+        should(!emptyRect.contains(FPoint(0, 1)));
+        should(!emptyRect.contains(FPoint(0, 2)));
+        should(!emptyRect.contains(FPoint(1, 0)));
+        should(!emptyRect.contains(FPoint(1, 1)));
+        should(!emptyRect.contains(FPoint(1, 2)));
+        should(!emptyRect.contains(FPoint(2, 0)));
+        should(!emptyRect.contains(FPoint(2, 1)));
+        should(!emptyRect.contains(FPoint(2, 2)));
+
+        should( emptyRect.contains(emptyRect));
+        should(!emptyRect.contains(rect1_1));
+        should(!emptyRect.contains(bigRect));
+
+        should(!rect1_1.contains(FPoint(0, 0)));
+        should(!rect1_1.contains(FPoint(0, 1)));
+        should(!rect1_1.contains(FPoint(0, 2)));
+        should(!rect1_1.contains(FPoint(1, 0)));
+        should( rect1_1.contains(FPoint(1, 1)));
+        should( rect1_1.contains(FPoint(1, 2)));
+        should(!rect1_1.contains(FPoint(1, 2.1f)));
+        should(!rect1_1.contains(FPoint(2, 0)));
+        should( rect1_1.contains(FPoint(2, 1)));
+        should(!rect1_1.contains(FPoint(2.1f, 1)));
+        should( rect1_1.contains(FPoint(2, 2)));
+
+        should( rect1_1.contains(emptyRect));
+        should( rect1_1.contains(rect1_1));
+        should(!rect1_1.contains(bigRect));
+
+        should(bigRect.contains(FPoint(0, 0)));
+        should(bigRect.contains(FPoint(0, 1)));
+        should(bigRect.contains(FPoint(0, 2)));
+        should(bigRect.contains(FPoint(1, 0)));
+        should(bigRect.contains(FPoint(1, 1)));
+        should(bigRect.contains(FPoint(1, 2)));
+        should(bigRect.contains(FPoint(2, 0)));
+        should(bigRect.contains(FPoint(2, 1)));
+        should(bigRect.contains(FPoint(2, 2)));
+
+        should( bigRect.contains(emptyRect));
+        should( bigRect.contains(rect1_1));
+        should( bigRect.contains(bigRect));
+    }
+
+    void testIntersection()
+    {
+        should(!emptyRect.intersects(emptyRect));
+        should(!emptyRect.intersects(rect1_1));
+        should(!emptyRect.intersects(bigRect));
+        should(!rect1_1.intersects(emptyRect));
+        should( rect1_1.intersects(rect1_1));
+        should( rect1_1.intersects(bigRect));
+        should(!bigRect.intersects(emptyRect));
+        should( bigRect.intersects(rect1_1));
+        should( bigRect.intersects(bigRect));
+
+        should( bigRect.intersects(FBox(FPoint(3, -3), FPoint(4, 3))));
+        should( bigRect.intersects(FBox(FPoint(3, -3), FPoint(14, 3))));
+
+        should((rect1_1 & emptyRect).isEmpty());
+        should(!(rect1_1 & bigRect).isEmpty());
+        should((rect1_1 & bigRect) == rect1_1);
+    }
+
+    void testUnion()
+    {
+        should(!(rect1_1 | emptyRect).isEmpty());
+        should((rect1_1 | emptyRect) == rect1_1);
+        should((rect1_1 | bigRect) == bigRect);
+        rect1_1 |= FPoint(3, 3);
+        shouldEqual(rect1_1.begin(), FPoint(1, 1));
+        shouldEqual(rect1_1.end(), FPoint(3, 3));
+    }
+
+    void testSizes()
+    {
+        shouldEqual(rect1_1.size(), FPoint(1, 1));
+        shouldEqual(bigRect.size(), FPoint(10, 10));
+        emptyRect.setBegin(FPoint(0, 0));
+        emptyRect.setSize(FPoint(10, 10));
+        should(bigRect == emptyRect);
+        emptyRect.addSize(FPoint(-4, -7));
+        shouldEqual(emptyRect.size(), FPoint(6, 3));
+        emptyRect.setSize(bigRect.size());
+        should(bigRect == emptyRect);
+    }
+
+    void testScaling()
+    {
+        shouldEqual((rect1_1 * 4).size(), FPoint(4, 4));
+        shouldEqual((rect1_1 * 4).end(), FPoint(8, 8));
+        FBox r2(rect1_1);
+        r2 *= 5;
+        should(rect1_1 * 5 == r2);
+        r2 /= 5;
+        should(rect1_1 == r2);
+    }
+};
+
+struct BoxTestSuite
+: public test_suite
+{
+    BoxTestSuite()
+    : test_suite("BoxTestSuite")
+    {
+        add(testCase(&IBoxTest::testProperties));
+        add(testCase(&IBoxTest::testContains));
+        add(testCase(&IBoxTest::testIntersection));
+        add(testCase(&IBoxTest::testUnion));
+        add(testCase(&IBoxTest::testSizes));
+        add(testCase(&IBoxTest::testScaling));
+
+        add(testCase(&FBoxTest::testProperties));
+        add(testCase(&FBoxTest::testContains));
+        add(testCase(&FBoxTest::testIntersection));
+        add(testCase(&FBoxTest::testUnion));
+        add(testCase(&FBoxTest::testSizes));
+        add(testCase(&FBoxTest::testScaling));
+    }
+};
+
+/********************************************************************/
+
+int main(int argc, char ** argv)
+{
+    PixelTypesTestSuite test;
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test.report() << std::endl;
+
+    Point2DTestSuite test2;
+    failed += test2.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test2.report() << std::endl;
+
+    Rect2DTestSuite test3;
+    failed += test3.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test3.report() << std::endl;
+
+    BoxTestSuite test4;
+    failed += test4.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test4.report() << std::endl;
+
+    return (failed != 0);
+}
diff --git a/test/sampler/CMakeLists.txt b/test/sampler/CMakeLists.txt
new file mode 100644
index 0000000..86ad3a2
--- /dev/null
+++ b/test/sampler/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_sampler test.cxx)
diff --git a/test/sampler/test.cxx b/test/sampler/test.cxx
new file mode 100644
index 0000000..380a3b8
--- /dev/null
+++ b/test/sampler/test.cxx
@@ -0,0 +1,433 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2013 by Ullrich Koethe                     */
+/*       Cognitive Systems Group, University of Hamburg, Germany        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define VIGRA_CHECK_BOUNDS
+#include "vigra/unittest.hxx"
+#include <cstdlib>
+#include <algorithm>
+#include <functional>
+#include <vigra/mathutil.hxx>
+#include <vigra/sampling.hxx>
+#include <map>
+
+using namespace vigra;
+
+struct wierdOrderingFunctor
+{
+    bool operator()(vigra::ArrayVectorView<unsigned int> a, vigra::ArrayVectorView<unsigned int> b)
+    {
+        size_t ii = 0;
+        while(ii < a.size() && a[ii] == b[ii])
+        {
+            ++ii;
+        }
+        if(ii == a.size())return false;
+        else return a[ii] < b[ii];
+    }
+};
+
+
+struct SamplerTests
+{
+    SamplerTests()
+    {}
+
+    void testSamplingWithoutReplacement();
+    void testStratifiedSamplingWithoutReplacement();
+    void testSamplingWithReplacement();
+    void testStratifiedSamplingWithReplacement();
+    void testSamplingWithoutReplacementChi2();
+    void testSamplingWithReplacementChi2();
+    
+    void testSamplingImpl(bool withReplacement);
+    void testStratifiedSamplingImpl(bool withReplacement);
+};
+
+void SamplerTests::testSamplingWithoutReplacement()
+{
+    testSamplingImpl(false);
+}
+
+void SamplerTests::testSamplingWithReplacement()
+{
+    testSamplingImpl(true);
+}
+
+void SamplerTests::testSamplingImpl(bool withReplacement)
+{
+    int totalDataCount = 20;
+    int numOfSamples = int(totalDataCount/2);
+
+    for(int ii = 0; ii <300; ++ii)
+    {
+        // check basic attributes
+        Sampler<> sampler( totalDataCount, 
+            SamplerOptions().withReplacement(withReplacement).sampleSize(numOfSamples));
+        shouldEqual(sampler.totalCount(), totalDataCount);
+        shouldEqual(sampler.sampleSize(), numOfSamples);
+        shouldEqual(sampler.strataCount(), 1);
+        shouldEqual(sampler.stratifiedSampling(), false);
+        shouldEqual(sampler.withReplacement(), withReplacement);
+
+        Sampler<> samplerProportional( totalDataCount, 
+            SamplerOptions().withReplacement(withReplacement).sampleProportion(0.5));
+        shouldEqual(samplerProportional.totalCount(), totalDataCount);
+        shouldEqual(samplerProportional.sampleSize(), numOfSamples);
+        shouldEqual(samplerProportional.strataCount(), 1);
+        shouldEqual(samplerProportional.withReplacement(), withReplacement);
+        
+        sampler.sample();
+        samplerProportional.sample();
+        // check that indices are either sampled or out-of-bag
+        {
+            ArrayVector<bool> wasPicked(totalDataCount, false);
+            Sampler<>::IndexArrayType usedIndices(sampler.sampledIndices());
+            Sampler<>::IndexArrayType unusedIndices(sampler.oobIndices());
+            
+            shouldEqual((int)usedIndices.size(), numOfSamples);
+            if(withReplacement)
+                should(usedIndices.size()+unusedIndices.size() >= (unsigned int)totalDataCount);
+            else
+                shouldEqual(usedIndices.size()+unusedIndices.size(), (unsigned int)totalDataCount);
+                
+            for(unsigned int ii = 0; ii < usedIndices.size(); ++ii)
+            {
+                should(usedIndices[ii] >= 0 && usedIndices[ii] < int(totalDataCount));
+                wasPicked[usedIndices[ii]] = true;
+            }
+            for(unsigned int ii = 0; ii < unusedIndices.size(); ++ii)
+            {
+                should(unusedIndices[ii] >= 0 && unusedIndices[ii] < int(totalDataCount));
+                wasPicked[unusedIndices[ii]] = true;
+            }
+            for(int ii = 0; ii < totalDataCount; ++ii)
+            {
+                should(wasPicked[ii]);
+            }
+        }
+
+        // check that consecutive samples differ
+        {
+            Sampler<>::IndexArrayType lastSampledIndices(sampler.sampledIndices());
+            sampler.sample();
+            shouldMsg(lastSampledIndices != sampler.sampledIndices(),
+                       "Consecutive samples are equal - probability of this is less than 10^-5.");
+        }
+    }
+
+    if(!withReplacement)
+    {
+        // check exception when more samples than data
+        try
+        {
+            Sampler<> sampler( 2, 
+                 SamplerOptions().withoutReplacement().sampleSize(9));
+            failTest("No exception thrown when there are too few data for sampling.");
+        }
+        catch(PreconditionViolation &)
+        {}
+    }
+}
+
+
+
+void SamplerTests::testStratifiedSamplingWithoutReplacement()
+{
+    testStratifiedSamplingImpl(false);
+}
+
+void SamplerTests::testStratifiedSamplingWithReplacement()
+{
+    testStratifiedSamplingImpl(true);
+}
+
+void SamplerTests::testStratifiedSamplingImpl(bool withReplacement)
+{
+    vigra::ArrayVector<int> strata;
+    for(int ii = 0; ii < 10; ++ii)
+    {
+        strata.push_back(1);
+        strata.push_back(2);
+    }
+    
+    {
+        int  totalDataCount = strata.size();
+        Sampler<> sampler( strata.begin(), strata.end(), 
+             SamplerOptions().withReplacement(withReplacement).sampleSize(10).stratified());
+        shouldEqual(sampler.totalCount(), totalDataCount);
+        shouldEqual(sampler.sampleSize(), 10);
+        shouldEqual(sampler.strataCount(), 2);
+        shouldEqual(sampler.stratifiedSampling(), true);
+        shouldEqual(sampler.withReplacement(), withReplacement);
+        sampler.sample();
+        if(withReplacement)
+            should(int(sampler.sampledIndices().size()+sampler.oobIndices().size()) >= totalDataCount);
+        else
+            shouldEqual(int(sampler.sampledIndices().size()+sampler.oobIndices().size()), totalDataCount);
+            
+        ArrayVector<bool> wasPicked(totalDataCount, false);
+
+        for(int ii = 0; ii < 5; ++ii)
+        {
+            int index = sampler.sampledIndices()[ii];
+            should(index >= 0 && index < int(totalDataCount));
+            shouldEqual(strata[index], 1);
+            wasPicked[index] = true;
+        }
+        for(int ii = 5; ii < 10; ++ii)
+        {
+            int index = sampler.sampledIndices()[ii];
+            should(index >= 0 && index < totalDataCount);
+            shouldEqual(strata[index], 2);
+            wasPicked[index] = true;
+        }
+        for(int ii = 0; ii < (int)sampler.oobIndices().size(); ++ii)
+        {
+            int index = sampler.oobIndices()[ii];
+            should(index >= 0 && index < totalDataCount);
+            wasPicked[index] = true;
+        }
+        for(int ii = 0; ii < totalDataCount; ++ii)
+        {
+            should(wasPicked[ii]);
+        }
+        Sampler<>::IndexArrayType lastSampledIndices(sampler.sampledIndices());
+        sampler.sample();
+        should(lastSampledIndices != sampler.sampledIndices());
+    }
+
+    {
+        int totalDataCount = strata.size();
+        Sampler<> sampler( strata.begin(), strata.end(), 
+             SamplerOptions().withReplacement(withReplacement).sampleSize(9).stratified());
+        sampler.sample();
+        shouldEqual(sampler.sampleSize(), 9);
+
+        ArrayVector<bool> wasPicked(totalDataCount, false);
+        for(int ii = 0; ii < 4; ++ii)
+        {
+            int index = sampler.sampledIndices()[ii];
+            should(index >= 0 && index < totalDataCount);
+            shouldEqual(strata[index], 1);
+            wasPicked[index] = true;
+        }
+        for(int ii = 4; ii < 9; ++ii)
+        {
+            int index = sampler.sampledIndices()[ii];
+            should(index >= 0 && index < totalDataCount);
+            shouldEqual(strata[index], 2);
+            wasPicked[index] = true;
+        }
+        for(int ii = 0; ii < (int)sampler.oobIndices().size(); ++ii)
+        {
+            int index = sampler.oobIndices()[ii];
+            should(index >= 0 && index < int(totalDataCount));
+            wasPicked[index] = true;
+        }
+        for(int ii = 0; ii < totalDataCount; ++ii)
+        {
+            should(wasPicked[ii]);
+        }
+    }
+
+    for(int ii = 0; ii < 10; ++ii)
+    {
+        strata.push_back(1);
+    }
+
+    {
+        Sampler<> sampler( strata.begin(), strata.end(), 
+             SamplerOptions().withReplacement(withReplacement).sampleSize(10).stratified());
+        sampler.sample();
+
+        for(int ii = 0; ii < 5; ++ii)
+        {
+            shouldEqual(strata[sampler.sampledIndices()[ii]], 1);
+        }
+        for(int ii = 5; ii < 10; ++ii)
+        {
+            shouldEqual(strata[sampler.sampledIndices()[ii]], 2);
+        }
+    }
+
+    for(int ii = 0; ii < 10; ++ii)
+    {
+        strata.push_back(3);
+    }
+
+    // need at most one sample per stratum
+    try
+    {
+        Sampler<> sampler( strata.begin(), strata.end(), 
+             SamplerOptions().withReplacement(withReplacement).sampleSize(2).stratified());
+        failTest("No exception thrown when there are too few data for stratified sampling.");
+    }
+    catch(PreconditionViolation &)
+    {}
+}
+
+void SamplerTests::testSamplingWithoutReplacementChi2()
+{
+    // Check that all permutations of the indices occur with about equal frequency.
+    // (Residuals are Poisson distributed, which is approximated by a Gaussian
+    //  distribution with data-dependent variance, so that conformance can be checked
+    //  by a chi-square test.)
+    // Use fixed random numbers so that the sampling is reproducible.
+    int nsamples = 120000;
+    int nclasses = 120;
+    MersenneTwister randomGenerator;
+    Sampler<> sampler( 5, 
+                SamplerOptions().withoutReplacement().sampleSize(5),
+                &randomGenerator);
+    std::map<unsigned int, int> wierdmap;
+    std::map<unsigned int , int>::iterator iter;
+    for(int ii = 0; ii < 1000; ++ii)
+    {
+        sampler.sample();
+        int dec = 1;
+        unsigned int hash = 0;
+        for(size_t ii = 0; ii < sampler.sampledIndices().size(); ++ii)
+        {
+            hash += dec* sampler.sampledIndices()[ii];
+            dec = dec *10;
+        }
+        wierdmap[hash] = 0;
+    }
+    
+    // check that all 120 permutations occured after 1000 trials
+    shouldEqual((int)wierdmap.size(), nclasses);
+    
+    for(int ii = 0; ii < nsamples; ++ii)
+    {
+        sampler.sample();
+        int dec = 1;
+        unsigned int hash = 0;
+        for(size_t ii = 0; ii < sampler.sampledIndices().size(); ++ii)
+        {
+            hash += dec* sampler.sampledIndices()[ii];
+            dec = dec *10;
+        }
+        wierdmap[hash] += 1;
+    }
+    double chi_squared = 0;
+    double ratio = nsamples/nclasses;
+    for(iter = wierdmap.begin(); iter != wierdmap.end(); ++iter)
+    {
+        chi_squared += sq(iter->second - ratio)/ratio;
+    }
+    
+    // check that we are in the 80% quantile of the expected distribution
+    shouldEqualTolerance (0, chi2CDF(119, chi_squared)-0.5, 0.4);
+}
+
+void SamplerTests::testSamplingWithReplacementChi2()
+{
+    // Check that samples are selected with uniform probability
+    // (Residuals are Poisson distributed, which is approximated by a Gaussian
+    //  distribution with data-dependent variance, so that conformance can be checked
+    //  by a chi-square test.)
+    // Use fixed random numbers so that the sampling is reproducible.
+    vigra::ArrayVector<int> observed(10);
+    observed.init(0);
+    int totalDataCount = 10;
+    int numOfSamples = 100000;
+    double chi_squared = 0,
+           ratio = double(numOfSamples) / totalDataCount;
+
+    {
+        MersenneTwister randomGenerator;
+        Sampler<> sampler(totalDataCount, 
+             SamplerOptions().withReplacement().sampleSize(numOfSamples),
+             &randomGenerator);
+
+        sampler.sample();
+        for(int ii = 0; ii < numOfSamples; ++ii)
+        {
+            observed[sampler.sampledIndices()[ii]]++;
+        }
+        for(int ii = 0; ii < totalDataCount; ++ii)
+        {
+            chi_squared += sq(observed[ii] - ratio)/ratio;
+        }
+        // check that we are in the 80% quantile of the expected distribution
+        shouldEqualTolerance (0, chi2CDF(9, chi_squared)-0.5, 0.4);
+    }
+
+    /* when sampling k times without replacement
+    the probability p of a sample not being picked is ((k-1)/k)^k
+    The distribution of the number of samples not being chosen is a
+    binomial distribution with n = k and p = ((k-1)/k)^k.
+    The expectation value of a binomial distribution is n*p ==>
+    The percentage of samples not used is (n*p)/k = p
+    For large n p converges to 0.366 => numpositives should be
+    around 0.63 +/- 0.01 */
+    totalDataCount = 10000;
+    {
+        Sampler<> sampler( totalDataCount, 
+             SamplerOptions().withReplacement().sampleSize(totalDataCount));
+        sampler.sample();
+        double numPositives = double(totalDataCount - sampler.oobIndices().size()) / totalDataCount;
+
+        shouldEqualTolerance (0, numPositives-0.63, 0.01);
+    }
+}
+
+struct SamplerTestSuite
+: public vigra::test_suite
+{
+    SamplerTestSuite()
+    : vigra::test_suite("Sampler Test")
+    {
+        add(testCase(&SamplerTests::testSamplingWithoutReplacement));
+        add(testCase(&SamplerTests::testStratifiedSamplingWithoutReplacement));
+        add(testCase(&SamplerTests::testSamplingWithReplacement));
+        add(testCase(&SamplerTests::testStratifiedSamplingWithReplacement));
+        add(testCase(&SamplerTests::testSamplingWithoutReplacementChi2));
+        add(testCase(&SamplerTests::testSamplingWithReplacementChi2));
+    }
+};
+
+int main(int argc, char **argv)
+{
+
+    SamplerTestSuite samplerTest;
+
+    int failed = samplerTest.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << samplerTest.report() << std::endl;
+
+
+    return (failed != 0);
+}
diff --git a/test/seededRegionGrowing3d/CMakeLists.txt b/test/seededRegionGrowing3d/CMakeLists.txt
new file mode 100644
index 0000000..22667be
--- /dev/null
+++ b/test/seededRegionGrowing3d/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_seededRegionGrowing3d test.cxx LIBRARIES vigraimpex)
diff --git a/test/seededRegionGrowing3d/test.cxx b/test/seededRegionGrowing3d/test.cxx
new file mode 100644
index 0000000..d45cacd
--- /dev/null
+++ b/test/seededRegionGrowing3d/test.cxx
@@ -0,0 +1,320 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2007 by F. Heinrich, B. Seppke, Ullrich Koethe       */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <functional>
+#include <cmath>
+#include "vigra/unittest.hxx"
+
+#include "vigra/seededregiongrowing3d.hxx"
+
+using namespace vigra;
+
+struct SeededRegionGrowing3DTest
+{
+    typedef vigra::MultiArray<3,int> IntVolume;
+    typedef vigra::MultiArray<3,double> DoubleVolume;
+
+    SeededRegionGrowing3DTest() :
+            vol1(IntVolume::difference_type(5,5,5)),
+            vol2(DoubleVolume::difference_type(4,4,4)),
+            vol3(IntVolume::difference_type(5,5,5)),
+            distvol1(DoubleVolume::difference_type(5,5,5)),
+            distvol2(DoubleVolume::difference_type(4,4,4))
+    {
+        static const int in1[] = { 0, 0, 0, 0, 0, 
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 1, 0, 0,  
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,
+
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,
+
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,
+
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,
+
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 0, 0, 0,  
+                                   0, 0, 2, 0, 0,  
+                                   0, 0, 0, 0, 0,   
+                                   0, 0, 0, 0, 0};
+
+        IntVolume::iterator i = vol1.begin();
+        IntVolume::iterator end = vol1.end();
+        const int * p = in1;
+
+        for(; i != end; ++i, ++p)
+        {
+            *i=*p;
+        }
+
+        for(int z=0; z<5; ++z)
+            for(int y=0; y<5; ++y)
+                for(int x=0; x<5; ++x){
+                    distvol1(x,y,z)=std::min( ((x-2.0)*(x-2.0)+(y-2.0)*(y-2.0)+(z-0.0)*(z-0.0)), 
+                                              ((x-2.0)*(x-2.0)+(y-2.0)*(y-2.0)+(z-4.0)*(z-4.0)) );
+                }
+
+        static const double in2[] = { 0.0, 0.0, 0.0, 0.0, 
+                                      0.0, 1.0, 0.0, 0.0, 
+                                      0.0, 0.0, 0.0, 0.0,  
+                                      0.0, 0.0, 0.0, 0.0,
+
+                                      0.0, 0.0, 0.0, 0.0,  
+                                      0.0, 0.0, 0.0, 0.0,  
+                                      0.0, 0.0, 0.0, 0.0,  
+                                      0.0, 0.0, 0.0, 0.0,
+
+                                      0.0, 0.0, 0.0, 0.0,  
+                                      0.0, 0.0, 0.0, 0.0,  
+                                      0.0, 0.0, 0.0, 0.0,  
+                                      0.0, 0.0, 0.0, 0.0,
+
+                                      0.0, 0.0, 0.0, 0.0, 
+                                      0.0, 0.0, 0.0, 0.0, 
+                                      0.0, 0.0, 2.0, 0.0,  
+                                      0.0, 0.0, 0.0, 0.0};
+
+        DoubleVolume::iterator id = vol2.begin();
+        DoubleVolume::iterator endd = vol2.end();
+        const double * pd = in2;
+
+        for(; id != endd; ++id, ++pd)
+        {
+            *id=*pd;
+        }
+
+        for(int z=0; z<4; ++z)
+            for(int y=0; y<4; ++y)
+                for(int x=0; x<4; ++x){
+                    distvol2(x,y,z)=std::min( ((x-1.0)*(x-1.0)+(y-1.0)*(y-1.0)+(z-0.0)*(z-0.0)), 
+                                              ((x-2.0)*(x-2.0)+(y-2.0)*(y-2.0)+(z-3.0)*(z-3.0)) );
+                }
+
+        static const int in3[] = { 1, 1, 1, 1, 1, 
+                                   1, 1, 1, 1, 1,  
+                                   1, 1, 1, 1, 1,  
+                                   1, 1, 1, 1, 1,  
+                                   1, 1, 1, 1, 1,
+
+                                   1, 1, 1, 1, 1,  
+                                   1, 2, 2, 2, 1,  
+                                   1, 2, 2, 2, 1,  
+                                   1, 2, 2, 2, 1,  
+                                   1, 1, 1, 1, 1,
+
+                                   1, 1, 1, 1, 1,  
+                                   1, 2, 2, 2, 1,  
+                                   1, 2, 3, 2, 1,  
+                                   1, 2, 2, 2, 1,  
+                                   1, 1, 1, 1, 1,
+
+                                   1, 1, 1, 1, 1,  
+                                   1, 2, 2, 2, 1,  
+                                   1, 2, 2, 2, 1,  
+                                   1, 2, 2, 2, 1,  
+                                   1, 1, 1, 1, 1,
+
+                                   4, 4, 4, 4, 4,  
+                                   4, 4, 4, 4, 4,  
+                                   4, 4, 4, 4, 4,  
+                                   4, 4, 4, 4, 4,   
+                                   4, 4, 4, 4, 4};
+
+        i = vol3.begin();
+        end = vol3.end();
+        p = in3;
+
+        for(; i != end; ++i, ++p)
+        {
+            *i=*p;
+        }
+
+    }
+
+    struct DirectCostFunctor
+    {
+        typedef double argument_type;
+        typedef double result_type;
+        typedef double cost_type;
+
+        void operator()(double const &) {}
+
+        double const & cost(double const & v) const
+        {
+            return v;
+        }
+    };
+
+    void voronoiTest()
+    {
+        DoubleVolume res(vol2);
+
+        vigra::ArrayOfRegionStatistics<DirectCostFunctor> cost(2);
+        seededRegionGrowing3D(distvol2, vol2, res, cost, CompleteGrow);
+
+        DoubleVolume::iterator i = res.begin();
+
+        int x,y,z;
+
+        for(z=0; z<4; ++z)
+        {
+            for(y=0; y<4; ++y)
+            {
+                for(x=0; x<4; ++x)
+                {
+                    double dist = *i++;
+                    double dist1 = VIGRA_CSTD::sqrt((1.0 - x)*(1.0 - x) +
+                                                    (1.0 - y)*(1.0 - y) +
+                                                    (0.0 - z)*(0.0 - z)  );
+                                                    
+                    double dist2 = VIGRA_CSTD::sqrt((2.0 - x)*(2.0 - x) +
+                                                    (2.0 - y)*(2.0 - y) +
+                                                    (3.0 - z)*(3.0 - z)  );
+                                                    
+                    double desired = (dist1 <= dist2) ? 1 : 2;
+
+                    if(VIGRA_CSTD::fabs(dist1 - dist2) > 1e-10)
+                        shouldEqual(dist, desired);
+                }
+            }
+        }
+    }
+
+    void voronoiTestWithBorder()
+    {
+
+        static const int desired[] = {  1, 1, 1, 1, 1, 
+                                        1, 1, 1, 1, 1,  
+                                        1, 1, 1, 1, 1,  
+                                        1, 1, 1, 1, 1,  
+                                        1, 1, 1, 1, 1,
+
+                                        1, 1, 1, 1, 1,  
+                                        1, 1, 1, 1, 1,  
+                                        1, 1, 1, 1, 1,  
+                                        1, 1, 1, 1, 1,  
+                                        1, 1, 1, 1, 1,
+
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,  
+                                        0, 0, 0, 0, 0,
+
+                                        2, 2, 2, 2, 2,  
+                                        2, 2, 2, 2, 2,  
+                                        2, 2, 2, 2, 2,  
+                                        2, 2, 2, 2, 2,  
+                                        2, 2, 2, 2, 2,
+
+                                        2, 2, 2, 2, 2,  
+                                        2, 2, 2, 2, 2,  
+                                        2, 2, 2, 2, 2,  
+                                        2, 2, 2, 2, 2,   
+                                        2, 2, 2, 2, 2};
+
+        IntVolume res(vol1);
+
+        vigra::ArrayOfRegionStatistics<DirectCostFunctor> cost(2);
+        seededRegionGrowing3D(srcMultiArrayRange(distvol1), srcMultiArray(vol1),
+                              destMultiArray(res), cost, KeepContours);
+
+        //int c=1;
+        //for(IntVolume::iterator iter=res.begin(); iter!=res.end(); ++iter, ++c){
+        //    std::cerr << *iter << ", ";
+        //    if(c%5==0) std::cerr << std::endl;
+        //    if(c%25==0) std::cerr << std::endl;
+        //}
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+    }
+
+    void simpleTest()
+    {
+        IntVolume res(vol3);
+
+        vigra::ArrayOfRegionStatistics<DirectCostFunctor> cost(4);
+        seededRegionGrowing3D(srcMultiArrayRange(vol3), srcMultiArray(vol3),
+                              destMultiArray(res), cost, CompleteGrow);
+
+        shouldEqualSequence(res.begin(), res.end(), vol3.begin());
+    }
+    
+    IntVolume    vol1;
+    DoubleVolume vol2;
+    IntVolume    vol3;
+    DoubleVolume distvol1;
+    DoubleVolume distvol2;
+};
+
+
+
+struct SeededRegionGrowing3DTestSuite
+: public vigra::test_suite
+{
+    SeededRegionGrowing3DTestSuite()
+    : vigra::test_suite("SeededRegionGrowing3DTestSuite")
+    {
+        add( testCase( &SeededRegionGrowing3DTest::voronoiTest));
+        add( testCase( &SeededRegionGrowing3DTest::voronoiTestWithBorder));
+        add( testCase( &SeededRegionGrowing3DTest::simpleTest));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    SeededRegionGrowing3DTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+    return (failed != 0);
+}
+
diff --git a/test/sifImport/CMakeLists.txt b/test/sifImport/CMakeLists.txt
new file mode 100644
index 0000000..499eb6d
--- /dev/null
+++ b/test/sifImport/CMakeLists.txt
@@ -0,0 +1,8 @@
+if(HDF5_FOUND)
+    INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIR})
+  
+    ADD_DEFINITIONS(-DHasHDF5 ${HDF5_CPPFLAGS})
+endif()
+
+VIGRA_ADD_TEST(test_sifImport test.cxx LIBRARIES vigraimpex)
+VIGRA_COPY_TEST_DATA(testSif_4_16_30001.sif testSif_4_13_30000.sif testSif_4_6_30000.sif testSif_forBlocks_4_16_30001.sif)
diff --git a/test/sifImport/test.cxx b/test/sifImport/test.cxx
new file mode 100644
index 0000000..20f006c
--- /dev/null
+++ b/test/sifImport/test.cxx
@@ -0,0 +1,209 @@
+/************************************************************************/
+/*                                                                    */
+/*       Copyright 2010 by Joachim Schleicher and Ullrich Koethe        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include "vigra/unittest.hxx"
+#include "vigra/sifImport.hxx"
+#include "vigra/multi_array.hxx"
+#include "vigra/multi_impex.hxx"
+
+#ifdef HasHDF5
+# include "vigra/hdf5impex.hxx"
+#endif
+
+#include "testSif_ref_4_16_30001.hxx"
+
+using namespace vigra;
+
+
+class SifImportTest
+{
+
+public:
+
+    SifImportTest()
+    {}
+
+    // Test Sif from Andor software version 4.16.30001
+    void testSifImport_4_16() {
+        MultiArray<3,float> reference_data(MultiArrayShape<3>::type(128, 128, 1), ref_4_16);
+        
+        // read SIF data to MultiArrayView
+        char sifFile[] = "testSif_4_16_30001.sif";
+        {
+            SIFImportInfo infoSIF(sifFile);
+            MultiArray<3,float> in_data(MultiArrayShape<3>::type(infoSIF.width(), infoSIF.height(), infoSIF.stacksize()));
+            readSIF(infoSIF, in_data);
+
+            // compare content
+            should (infoSIF.shape()[0] == 128);
+            should (infoSIF.shape()[1] == 128);
+            should (infoSIF.shape()[2] == 1);
+            should (in_data == reference_data);
+        }
+        {
+            // read via importVolume()
+            VolumeImportInfo info(sifFile);
+
+            // compare content
+            should (info.getFileType() == std::string("SIF"));
+            should (info.shape() == Shape3(128, 128, 1));
+            should (info.getPixelType() == std::string("FLOAT"));
+            should (info.numBands() == 1);
+
+            MultiArray<3,float> in_data(info.shape());
+            importVolume(info, in_data);
+            should (in_data == reference_data);
+        }
+    }
+
+    // SIF from Andor software version 4.13.30000
+    void testSifImport_4_13() {
+        char sifFile[] = "testSif_4_13_30000.sif";
+
+        const float reference_array[] = 
+            {0.f, 27.f, 61.f, 96.f, 132.f, 166.f, 200.f, 235.f, 
+             0.f, 27.f, 62.f, 97.f, 131.f, 166.f, 200.f, 235.f};
+        MultiArray<3, float> reference_data(MultiArrayShape<3>::type(8, 2, 1), reference_array);
+        
+
+        // read SIF
+        SIFImportInfo infoSIF(sifFile);
+        // import to MultiArrayView
+        MultiArray<3,float> in_data(MultiArrayShape<3>::type(infoSIF.width(), infoSIF.height(), infoSIF.stacksize()));
+        readSIF(infoSIF, in_data);
+        
+        
+        // compare
+        should (infoSIF.shape()[0] == 8);
+        should (infoSIF.shape()[1] == 2);
+        should (infoSIF.shape()[2] == 1);
+        should (in_data == reference_data);
+    }
+    
+    // SIF from Andor software version 4.6.3
+    void testSifImport_4_6() {
+        char sifFile[] = "testSif_4_6_30000.sif";
+
+        const float reference_array[] = 
+            {124.f, 176.114f, 228.f,
+             68.f, 120.f, 172.f,
+             12.299f, 64.f, 116.f,
+             0.f, 8.299f, 60.f};
+        MultiArray<3, float> reference_data(MultiArrayShape<3>::type(3, 4, 1), reference_array);
+        
+
+        // read SIF
+        SIFImportInfo infoSIF(sifFile);
+        // import to MultiArrayView
+        MultiArray<3,float> in_data(MultiArrayShape<3>::type(infoSIF.width(), infoSIF.height(), infoSIF.stacksize()));
+        readSIF(infoSIF, in_data);
+        
+        // compare
+        should (infoSIF.shape()[0] == 3);
+        should (infoSIF.shape()[1] == 4);
+        should (infoSIF.shape()[2] == 1);
+        should (in_data == reference_data);
+    }
+
+    // check for consistency of shape() vs shapeOfDimension(i)
+    void testShapeOfDimension() {
+        char sifFile[] = "testSif_4_6_30000.sif";
+
+        SIFImportInfo infoSIF(sifFile);
+
+        // compare
+        should (infoSIF.shape()[0] == infoSIF.width());
+        should (infoSIF.shape()[1] == infoSIF.height());
+        should (infoSIF.shape()[2] == infoSIF.stacksize());
+        for (int i = 0; i < 3; ++i) {
+            should (infoSIF.shape()[i] == infoSIF.shapeOfDimension(i));
+        }
+    }
+
+    void testReadBlock() {
+        char sifFile[] = "testSif_forBlocks_4_16_30001.sif";
+
+        SIFImportInfo infoSIF(sifFile);
+        should (infoSIF.stacksize() == 3);
+        should (infoSIF.width() == 4);
+        should (infoSIF.height() == 5);
+        MultiArray<3,float> in_data_block(MultiArrayShape<3>::type(infoSIF.width(), infoSIF.height(), 1));
+
+        // import whole volume to MultiArray
+        MultiArray<3,float> in_data_volume(MultiArrayShape<3>::type(infoSIF.width(), infoSIF.height(), infoSIF.stacksize()));
+        readSIF(infoSIF, in_data_volume);
+
+        // compare with readBlock() function
+        for (int i=0; i<infoSIF.stacksize(); ++i) {
+            readSIFBlock(infoSIF, Shape3(0,0,i), Shape3(4,5,1), in_data_block); // read one frame at a time
+            should (in_data_block == in_data_volume.subarray(Shape3(0,0,i), Shape3(4,5,i+1)));
+
+            // additional check: compare values explicitly
+            for (int xx=0; xx<infoSIF.width(); ++xx) {
+                for(int yy=0; yy<infoSIF.height(); ++yy) {
+                    should ( in_data_block(xx,infoSIF.height()-1-yy) == (float)(xx | (yy<<4) | ((i+1)<<8)) );
+                }
+            }
+        }
+    }
+
+};
+
+
+
+struct SifImportTestSuite : public vigra::test_suite
+{
+    SifImportTestSuite()
+        : vigra::test_suite("SifImportTestSuite")
+    {
+        // tests for import
+        add(testCase(&SifImportTest::testSifImport_4_16));
+        add(testCase(&SifImportTest::testSifImport_4_13));
+        add(testCase(&SifImportTest::testSifImport_4_6));
+        add(testCase(&SifImportTest::testShapeOfDimension));
+        add(testCase(&SifImportTest::testReadBlock));
+ 
+    }
+};
+
+
+int main (int argc, char ** argv)
+{
+    SifImportTestSuite test;
+    const int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test.report() << std::endl;
+
+    return failed != 0;
+}
diff --git a/test/sifImport/testSif_4_13_30000.sif b/test/sifImport/testSif_4_13_30000.sif
new file mode 100644
index 0000000..37ff71d
Binary files /dev/null and b/test/sifImport/testSif_4_13_30000.sif differ
diff --git a/test/sifImport/testSif_4_16_30001.sif b/test/sifImport/testSif_4_16_30001.sif
new file mode 100644
index 0000000..fa6b42c
Binary files /dev/null and b/test/sifImport/testSif_4_16_30001.sif differ
diff --git a/test/sifImport/testSif_4_6_30000.sif b/test/sifImport/testSif_4_6_30000.sif
new file mode 100644
index 0000000..2005e98
Binary files /dev/null and b/test/sifImport/testSif_4_6_30000.sif differ
diff --git a/test/sifImport/testSif_forBlocks_4_16_30001.sif b/test/sifImport/testSif_forBlocks_4_16_30001.sif
new file mode 100644
index 0000000..e78c3d3
Binary files /dev/null and b/test/sifImport/testSif_forBlocks_4_16_30001.sif differ
diff --git a/test/sifImport/testSif_ref_4_16_30001.hxx b/test/sifImport/testSif_ref_4_16_30001.hxx
new file mode 100644
index 0000000..2f2bad1
--- /dev/null
+++ b/test/sifImport/testSif_ref_4_16_30001.hxx
@@ -0,0 +1,130 @@
+// reference data for testSif_4_16_30001.sif
+float ref_4_16[] = {
+0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0. [...]
+0.f, 679.888916f, 663.444458f, 649.444458f, 632.333313f, 623.888916f, 613.777771f, 630.888916f, 667.666687f, 703.888916f, 711.666687f, 686.222229f, 649.f, 610.555542f, 578.f, 573.666687f, 575.333313f, 586.666687f, 606.555542f, 664.f, 835.222229f, 1038.222168f, 1196.f, 1104.666626f, 911.f, 703.111084f, 638.f, 609.666687f, 591.888916f, 552.222229f, 535.888916f, 534.444458f, 552.333313f, 540.777771f, 540.555542f, 534.444458f, 548.555542f, 545.333313f, 551.f, 551.555542f, 552.888916f, 534.44 [...]
+0.f, 679.777771f, 650.666687f, 650.888916f, 643.f, 637.888916f, 626.f, 640.333313f, 697.666687f, 740.111084f, 760.777771f, 723.888916f, 678.888916f, 627.666687f, 598.777771f, 591.f, 598.222229f, 617.888916f, 646.555542f, 727.444458f, 948.777771f, 1252.111084f, 1465.222168f, 1352.444458f, 1052.777832f, 770.777771f, 643.333313f, 608.f, 573.111084f, 551.222229f, 534.777771f, 542.111084f, 556.777771f, 547.444458f, 543.333313f, 528.111084f, 541.444458f, 541.333313f, 556.444458f, 557.444458f,  [...]
+0.f, 684.444458f, 659.444458f, 663.666687f, 647.888916f, 640.444458f, 628.777771f, 650.111084f, 698.444458f, 732.888916f, 747.666687f, 704.f, 661.333313f, 608.777771f, 597.222229f, 589.333313f, 607.777771f, 625.444458f, 657.555542f, 737.777771f, 940.666687f, 1240.f, 1424.666626f, 1329.666626f, 1034.555542f, 774.555542f, 652.111084f, 614.111084f, 578.444458f, 551.222229f, 538.f, 544.222229f, 557.f, 541.444458f, 538.666687f, 518.333313f, 529.555542f, 533.222229f, 558.333313f, 568.444458f,  [...]
+0.f, 684.f, 676.111084f, 679.111084f, 650.666687f, 632.666687f, 617.777771f, 630.222229f, 654.666687f, 668.333313f, 680.666687f, 655.555542f, 635.f, 596.555542f, 594.888916f, 597.222229f, 624.f, 640.666687f, 667.444458f, 715.777771f, 822.222229f, 996.333313f, 1092.444458f, 1058.666626f, 885.777771f, 732.111084f, 638.444458f, 602.555542f, 584.222229f, 566.555542f, 553.444458f, 548.666687f, 553.444458f, 547.444458f, 544.555542f, 540.666687f, 547.111084f, 555.f, 564.444458f, 564.666687f, 55 [...]
+0.f, 689.888916f, 679.888916f, 684.444458f, 655.444458f, 634.111084f, 614.222229f, 624.111084f, 630.f, 628.333313f, 622.888916f, 611.555542f, 598.888916f, 577.555542f, 577.222229f, 585.666687f, 605.555542f, 622.666687f, 647.777771f, 669.555542f, 700.666687f, 758.222229f, 778.222229f, 767.888916f, 703.666687f, 638.222229f, 607.666687f, 582.f, 583.555542f, 565.111084f, 555.888916f, 546.f, 548.f, 550.222229f, 549.777771f, 553.666687f, 555.444458f, 561.222229f, 566.f, 567.444458f, 563.666687 [...]
+0.f, 693.555542f, 678.555542f, 683.666687f, 658.111084f, 639.333313f, 617.888916f, 620.444458f, 609.666687f, 609.222229f, 602.333313f, 604.222229f, 591.666687f, 585.f, 577.111084f, 597.333313f, 608.777771f, 624.666687f, 628.666687f, 624.555542f, 627.555542f, 633.333313f, 639.666687f, 636.666687f, 618.111084f, 594.777771f, 582.333313f, 566.f, 568.222229f, 568.111084f, 568.111084f, 559.888916f, 546.222229f, 548.666687f, 548.333313f, 563.888916f, 568.555542f, 572.111084f, 574.777771f, 578.1 [...]
+0.f, 711.444458f, 690.111084f, 685.333313f, 666.666687f, 645.222229f, 630.555542f, 632.444458f, 616.f, 618.f, 612.f, 612.f, 590.888916f, 579.555542f, 576.777771f, 582.444458f, 587.f, 596.333313f, 604.444458f, 598.f, 603.444458f, 608.111084f, 614.f, 606.555542f, 589.333313f, 575.555542f, 570.777771f, 560.222229f, 568.777771f, 565.444458f, 567.111084f, 551.888916f, 542.777771f, 539.555542f, 543.777771f, 546.777771f, 556.222229f, 549.666687f, 563.333313f, 568.333313f, 565.666687f, 545.22222 [...]
+0.f, 845.888916f, 793.333313f, 725.333313f, 696.333313f, 679.333313f, 666.555542f, 657.444458f, 628.888916f, 626.777771f, 618.444458f, 609.555542f, 588.222229f, 578.777771f, 569.111084f, 578.333313f, 586.333313f, 597.f, 601.777771f, 588.777771f, 594.777771f, 592.f, 609.444458f, 610.555542f, 596.888916f, 576.111084f, 561.222229f, 555.666687f, 569.666687f, 573.666687f, 578.111084f, 570.444458f, 564.333313f, 557.444458f, 546.222229f, 541.222229f, 548.888916f, 546.f, 558.555542f, 555.555542f [...]
+0.f, 1197.111084f, 1034.666626f, 814.111084f, 691.333313f, 656.111084f, 646.333313f, 643.777771f, 622.888916f, 629.777771f, 630.666687f, 634.666687f, 608.777771f, 598.f, 602.f, 604.555542f, 606.222229f, 600.444458f, 607.777771f, 606.444458f, 612.666687f, 606.888916f, 613.f, 609.555542f, 605.333313f, 584.444458f, 575.f, 562.111084f, 584.555542f, 573.777771f, 572.222229f, 560.666687f, 566.444458f, 566.f, 556.555542f, 546.888916f, 547.666687f, 536.111084f, 542.333313f, 542.888916f, 542.1110 [...]
+0.f, 1554.444458f, 1265.222168f, 913.111084f, 717.111084f, 656.222229f, 629.666687f, 626.111084f, 619.111084f, 637.555542f, 636.666687f, 645.777771f, 642.222229f, 662.666687f, 670.888916f, 669.333313f, 648.444458f, 626.f, 616.666687f, 606.222229f, 610.444458f, 608.666687f, 620.888916f, 624.888916f, 626.444458f, 626.888916f, 624.222229f, 606.f, 592.222229f, 573.777771f, 564.333313f, 567.222229f, 561.111084f, 562.555542f, 541.f, 541.f, 542.f, 545.111084f, 538.f, 539.444458f, 534.f, 531.555 [...]
+0.f, 1590.777832f, 1281.f, 925.111084f, 712.111084f, 636.666687f, 608.111084f, 596.f, 601.111084f, 632.222229f, 649.111084f, 672.222229f, 705.222229f, 796.222229f, 869.222229f, 848.777771f, 761.333313f, 677.777771f, 641.222229f, 620.111084f, 608.111084f, 608.444458f, 612.777771f, 633.111084f, 669.333313f, 713.444458f, 722.555542f, 686.555542f, 637.111084f, 592.444458f, 565.666687f, 567.666687f, 562.f, 559.222229f, 551.333313f, 562.666687f, 569.333313f, 562.888916f, 547.f, 547.222229f, 54 [...]
+0.f, 1274.888916f, 1059.888916f, 838.555542f, 722.222229f, 662.333313f, 633.333313f, 612.f, 615.f, 631.888916f, 636.888916f, 665.222229f, 777.111084f, 967.111084f, 1129.888916f, 1082.555542f, 918.333313f, 738.555542f, 654.777771f, 619.333313f, 595.888916f, 594.666687f, 600.888916f, 644.777771f, 723.444458f, 817.555542f, 837.f, 776.444458f, 664.f, 606.222229f, 571.555542f, 589.111084f, 574.f, 569.555542f, 549.111084f, 556.777771f, 562.777771f, 573.f, 561.555542f, 556.f, 548.111084f, 545.2 [...]
+0.f, 894.888916f, 794.888916f, 703.666687f, 663.666687f, 646.666687f, 635.111084f, 616.555542f, 612.777771f, 613.444458f, 619.888916f, 656.111084f, 798.111084f, 1037.444458f, 1235.222168f, 1186.f, 978.222229f, 755.666687f, 652.111084f, 626.555542f, 614.222229f, 606.111084f, 600.222229f, 628.333313f, 718.777771f, 807.888916f, 828.555542f, 764.666687f, 668.111084f, 613.888916f, 591.777771f, 620.f, 617.666687f, 618.888916f, 586.222229f, 581.666687f, 580.222229f, 584.f, 582.555542f, 567.7777 [...]
+0.f, 697.111084f, 650.666687f, 623.111084f, 617.333313f, 621.777771f, 618.555542f, 612.111084f, 606.111084f, 596.555542f, 595.555542f, 632.f, 756.888916f, 950.444458f, 1103.444458f, 1082.333374f, 924.666687f, 743.555542f, 645.333313f, 621.666687f, 617.f, 615.444458f, 607.666687f, 616.333313f, 673.666687f, 750.333313f, 775.222229f, 731.333313f, 660.222229f, 630.777771f, 623.333313f, 647.f, 641.777771f, 653.777771f, 614.222229f, 593.111084f, 573.111084f, 586.666687f, 597.f, 582.333313f, 56 [...]
+0.f, 646.444458f, 618.444458f, 598.888916f, 592.222229f, 603.888916f, 609.888916f, 599.222229f, 594.777771f, 584.222229f, 586.888916f, 611.f, 667.111084f, 775.666687f, 832.555542f, 833.f, 757.888916f, 682.888916f, 643.111084f, 621.444458f, 617.777771f, 618.444458f, 613.f, 613.111084f, 622.666687f, 657.666687f, 669.888916f, 665.444458f, 649.f, 647.666687f, 658.333313f, 672.666687f, 679.f, 687.f, 658.555542f, 624.222229f, 595.888916f, 592.777771f, 593.666687f, 576.444458f, 574.555542f, 569 [...]
+0.f, 629.888916f, 613.777771f, 599.777771f, 597.111084f, 595.333313f, 604.333313f, 598.888916f, 592.222229f, 590.888916f, 585.f, 599.333313f, 613.333313f, 653.222229f, 674.666687f, 684.444458f, 666.777771f, 640.777771f, 631.f, 624.666687f, 618.333313f, 620.f, 613.333313f, 622.f, 611.222229f, 634.888916f, 640.f, 655.555542f, 649.777771f, 660.333313f, 665.222229f, 663.444458f, 661.444458f, 662.888916f, 662.222229f, 635.444458f, 602.444458f, 579.555542f, 581.444458f, 582.888916f, 589.888916 [...]
+0.f, 633.777771f, 626.111084f, 613.555542f, 607.f, 592.555542f, 591.777771f, 586.666687f, 579.111084f, 585.888916f, 578.444458f, 595.f, 589.f, 613.333313f, 617.222229f, 621.444458f, 607.555542f, 597.666687f, 605.f, 616.555542f, 620.666687f, 633.666687f, 647.777771f, 662.444458f, 655.111084f, 632.666687f, 615.666687f, 610.333313f, 615.111084f, 629.555542f, 641.111084f, 639.333313f, 640.f, 633.444458f, 649.555542f, 633.222229f, 614.666687f, 588.555542f, 593.444458f, 602.666687f, 618.111084 [...]
+0.f, 615.f, 616.444458f, 606.333313f, 602.444458f, 582.444458f, 570.111084f, 571.f, 568.111084f, 588.f, 579.888916f, 594.f, 580.f, 590.333313f, 586.888916f, 596.111084f, 582.222229f, 586.666687f, 587.222229f, 619.222229f, 626.666687f, 657.222229f, 700.111084f, 722.888916f, 714.222229f, 651.777771f, 614.666687f, 588.222229f, 591.777771f, 602.111084f, 609.666687f, 609.444458f, 609.f, 605.555542f, 630.777771f, 633.222229f, 639.222229f, 626.666687f, 650.555542f, 675.777771f, 695.f, 711.33331 [...]
+0.f, 612.f, 626.333313f, 628.888916f, 620.666687f, 594.444458f, 558.f, 548.222229f, 553.f, 575.f, 575.666687f, 580.555542f, 561.333313f, 571.666687f, 564.222229f, 579.333313f, 566.333313f, 581.888916f, 578.555542f, 606.111084f, 614.555542f, 673.222229f, 736.777771f, 766.444458f, 747.888916f, 663.111084f, 617.666687f, 576.f, 576.888916f, 578.555542f, 589.222229f, 594.888916f, 601.f, 611.888916f, 652.555542f, 681.666687f, 733.111084f, 788.888916f, 861.111084f, 882.333313f, 840.444458f, 795 [...]
+0.f, 612.555542f, 620.444458f, 624.888916f, 615.888916f, 603.555542f, 572.777771f, 556.333313f, 551.222229f, 569.111084f, 580.444458f, 581.444458f, 565.666687f, 563.888916f, 559.333313f, 566.888916f, 568.888916f, 584.222229f, 581.777771f, 604.666687f, 607.555542f, 664.444458f, 716.444458f, 746.f, 726.888916f, 662.444458f, 627.222229f, 592.888916f, 586.888916f, 580.111084f, 580.111084f, 580.888916f, 600.f, 637.555542f, 714.f, 773.444458f, 875.888916f, 1019.777771f, 1180.f, 1219.666626f, 1 [...]
+0.f, 620.333313f, 635.777771f, 639.111084f, 630.555542f, 611.555542f, 586.888916f, 563.666687f, 562.444458f, 574.333313f, 587.111084f, 585.555542f, 575.111084f, 572.333313f, 569.888916f, 580.222229f, 586.888916f, 597.111084f, 591.888916f, 606.222229f, 602.555542f, 641.333313f, 664.777771f, 674.777771f, 658.444458f, 624.444458f, 604.222229f, 583.222229f, 571.888916f, 573.f, 573.f, 577.222229f, 600.333313f, 671.f, 787.666687f, 878.444458f, 1005.f, 1223.111084f, 1450.666626f, 1499.555542f,  [...]
+0.f, 620.555542f, 623.111084f, 632.444458f, 616.222229f, 611.222229f, 604.111084f, 590.666687f, 587.777771f, 595.111084f, 610.111084f, 603.666687f, 584.444458f, 571.f, 573.f, 598.222229f, 613.888916f, 634.777771f, 618.777771f, 621.111084f, 599.555542f, 616.222229f, 621.555542f, 618.444458f, 614.111084f, 600.777771f, 590.666687f, 574.222229f, 558.111084f, 556.222229f, 558.666687f, 568.333313f, 593.444458f, 666.f, 786.111084f, 881.444458f, 996.222229f, 1208.888916f, 1424.444458f, 1471.4444 [...]
+0.f, 600.333313f, 598.444458f, 615.222229f, 614.333313f, 619.333313f, 625.f, 621.777771f, 631.111084f, 630.f, 634.444458f, 617.222229f, 593.444458f, 582.444458f, 595.222229f, 635.f, 655.666687f, 671.777771f, 646.222229f, 636.444458f, 616.222229f, 619.666687f, 613.666687f, 603.f, 597.222229f, 584.222229f, 573.555542f, 560.222229f, 545.555542f, 540.333313f, 542.333313f, 555.111084f, 575.666687f, 638.f, 722.888916f, 809.666687f, 895.222229f, 1061.222168f, 1190.333374f, 1210.666626f, 1007.88 [...]
+0.f, 588.555542f, 581.777771f, 598.333313f, 593.111084f, 609.333313f, 616.888916f, 624.777771f, 638.111084f, 650.111084f, 652.666687f, 622.666687f, 589.888916f, 587.444458f, 608.777771f, 645.111084f, 659.111084f, 662.444458f, 650.888916f, 655.444458f, 658.222229f, 651.f, 622.222229f, 594.333313f, 586.777771f, 574.f, 570.f, 556.f, 557.111084f, 548.777771f, 550.333313f, 550.222229f, 562.f, 595.777771f, 640.f, 702.888916f, 767.666687f, 874.444458f, 939.333313f, 928.888916f, 801.888916f, 693 [...]
+0.f, 583.777771f, 579.333313f, 569.555542f, 575.222229f, 589.111084f, 614.666687f, 620.888916f, 641.555542f, 654.555542f, 653.111084f, 636.222229f, 611.666687f, 614.111084f, 618.111084f, 631.777771f, 644.888916f, 638.444458f, 646.777771f, 665.f, 691.111084f, 682.555542f, 640.777771f, 603.444458f, 587.222229f, 574.444458f, 570.666687f, 555.111084f, 551.f, 544.888916f, 542.666687f, 549.111084f, 554.888916f, 585.777771f, 604.666687f, 651.111084f, 693.666687f, 759.888916f, 788.111084f, 766.8 [...]
+0.f, 594.333313f, 591.333313f, 573.444458f, 568.111084f, 572.777771f, 587.888916f, 598.666687f, 624.888916f, 642.333313f, 644.777771f, 634.f, 621.444458f, 621.555542f, 611.333313f, 610.111084f, 617.111084f, 615.222229f, 632.555542f, 659.333313f, 687.222229f, 672.444458f, 633.f, 598.222229f, 587.333313f, 579.f, 573.111084f, 562.666687f, 555.111084f, 556.333313f, 557.111084f, 567.888916f, 569.333313f, 584.888916f, 594.777771f, 620.666687f, 649.111084f, 671.222229f, 685.333313f, 666.222229f [...]
+0.f, 595.444458f, 587.f, 574.f, 568.333313f, 565.444458f, 579.666687f, 595.333313f, 626.555542f, 637.222229f, 643.444458f, 650.333313f, 655.333313f, 644.777771f, 620.111084f, 604.444458f, 612.333313f, 609.777771f, 610.222229f, 619.888916f, 637.444458f, 634.555542f, 615.666687f, 596.222229f, 596.222229f, 591.222229f, 587.222229f, 581.222229f, 568.333313f, 572.444458f, 572.222229f, 598.444458f, 601.777771f, 614.777771f, 604.666687f, 618.333313f, 629.888916f, 630.222229f, 631.555542f, 618.1 [...]
+0.f, 583.111084f, 579.f, 581.888916f, 575.777771f, 572.f, 574.777771f, 586.888916f, 625.f, 639.444458f, 681.f, 713.444458f, 743.444458f, 719.333313f, 667.222229f, 631.777771f, 610.777771f, 600.777771f, 585.777771f, 593.f, 602.444458f, 598.222229f, 591.444458f, 580.888916f, 591.888916f, 594.555542f, 591.444458f, 596.f, 620.222229f, 692.111084f, 748.333313f, 761.444458f, 717.111084f, 663.666687f, 628.666687f, 609.666687f, 608.888916f, 597.666687f, 600.555542f, 606.777771f, 624.666687f, 633 [...]
+0.f, 579.777771f, 584.555542f, 587.222229f, 578.222229f, 571.555542f, 584.777771f, 598.666687f, 645.777771f, 692.111084f, 817.888916f, 931.333313f, 968.888916f, 875.222229f, 738.555542f, 651.f, 603.222229f, 585.222229f, 572.555542f, 576.333313f, 589.f, 591.555542f, 589.333313f, 573.777771f, 583.222229f, 591.666687f, 596.777771f, 619.777771f, 721.777771f, 914.888916f, 1081.f, 1071.444458f, 928.666687f, 754.f, 671.777771f, 629.333313f, 614.666687f, 598.111084f, 599.888916f, 620.666687f, 64 [...]
+0.f, 578.666687f, 585.555542f, 579.f, 580.222229f, 580.666687f, 600.111084f, 611.222229f, 692.f, 833.666687f, 1072.111084f, 1258.777832f, 1243.888916f, 1050.111084f, 809.333313f, 671.777771f, 613.333313f, 589.111084f, 588.777771f, 586.222229f, 592.777771f, 585.666687f, 588.222229f, 583.222229f, 594.222229f, 597.888916f, 598.666687f, 624.888916f, 801.666687f, 1124.777832f, 1400.888916f, 1379.555542f, 1118.555542f, 835.444458f, 693.333313f, 629.555542f, 603.666687f, 601.111084f, 610.555542 [...]
+0.f, 596.444458f, 591.444458f, 587.333313f, 584.444458f, 582.555542f, 596.222229f, 610.222229f, 697.222229f, 915.f, 1224.555542f, 1458.666626f, 1393.555542f, 1115.888916f, 824.555542f, 658.444458f, 622.222229f, 593.333313f, 600.f, 583.444458f, 590.777771f, 586.111084f, 589.777771f, 587.888916f, 597.444458f, 606.888916f, 609.222229f, 637.111084f, 823.f, 1166.555542f, 1430.f, 1390.222168f, 1110.333374f, 837.444458f, 697.f, 632.888916f, 613.444458f, 617.111084f, 630.777771f, 641.333313f, 65 [...]
+0.f, 600.666687f, 591.888916f, 599.111084f, 599.777771f, 594.888916f, 589.444458f, 598.555542f, 677.555542f, 895.111084f, 1170.111084f, 1361.333374f, 1269.222168f, 1020.f, 777.666687f, 644.333313f, 618.777771f, 584.555542f, 594.222229f, 583.111084f, 586.f, 572.444458f, 578.555542f, 583.222229f, 600.555542f, 606.333313f, 612.111084f, 628.888916f, 752.444458f, 989.666687f, 1152.444458f, 1124.111084f, 924.111084f, 766.333313f, 670.555542f, 630.777771f, 615.666687f, 629.333313f, 647.555542f, [...]
+0.f, 632.666687f, 614.666687f, 625.777771f, 610.777771f, 604.333313f, 587.888916f, 593.777771f, 620.444458f, 738.666687f, 905.666687f, 1031.f, 988.888916f, 845.333313f, 703.111084f, 623.888916f, 602.333313f, 584.333313f, 581.111084f, 576.666687f, 576.777771f, 571.222229f, 578.666687f, 579.888916f, 592.555542f, 594.777771f, 597.444458f, 611.444458f, 670.555542f, 780.777771f, 841.888916f, 817.f, 732.555542f, 670.333313f, 653.888916f, 634.666687f, 640.666687f, 641.555542f, 664.111084f, 657. [...]
+0.f, 732.444458f, 704.f, 673.222229f, 629.f, 616.777771f, 600.555542f, 608.f, 605.222229f, 650.f, 711.333313f, 770.111084f, 759.444458f, 715.777771f, 663.f, 636.777771f, 616.444458f, 610.555542f, 596.444458f, 588.333313f, 575.f, 567.888916f, 579.444458f, 579.666687f, 587.666687f, 574.f, 568.111084f, 576.888916f, 602.f, 629.666687f, 655.444458f, 653.222229f, 649.222229f, 639.111084f, 645.444458f, 644.f, 658.f, 688.333313f, 730.222229f, 721.222229f, 748.444458f, 819.888916f, 957.444458f, 9 [...]
+0.f, 957.888916f, 885.444458f, 771.777771f, 664.222229f, 614.777771f, 602.555542f, 616.333313f, 612.888916f, 617.111084f, 621.222229f, 649.666687f, 652.888916f, 658.f, 656.222229f, 689.555542f, 713.444458f, 715.777771f, 664.111084f, 619.777771f, 581.777771f, 581.f, 581.f, 577.111084f, 570.111084f, 558.555542f, 551.888916f, 559.888916f, 572.555542f, 583.111084f, 596.555542f, 606.555542f, 624.888916f, 624.f, 628.444458f, 629.111084f, 663.888916f, 714.444458f, 765.111084f, 760.222229f, 784. [...]
+0.f, 1185.222168f, 1052.666626f, 851.111084f, 698.888916f, 617.333313f, 593.888916f, 599.777771f, 603.f, 611.333313f, 606.888916f, 621.888916f, 619.222229f, 642.f, 704.888916f, 816.111084f, 911.333313f, 904.222229f, 796.444458f, 684.111084f, 605.333313f, 592.222229f, 574.444458f, 570.555542f, 569.555542f, 564.777771f, 560.888916f, 553.555542f, 557.777771f, 561.111084f, 565.777771f, 574.222229f, 594.888916f, 609.666687f, 615.f, 619.111084f, 650.888916f, 714.111084f, 755.777771f, 763.55554 [...]
+0.f, 1211.555542f, 1061.444458f, 856.f, 708.333313f, 622.f, 591.888916f, 588.444458f, 599.666687f, 595.888916f, 593.444458f, 592.222229f, 594.444458f, 621.444458f, 737.f, 938.888916f, 1116.888916f, 1105.444458f, 926.555542f, 742.666687f, 624.333313f, 603.333313f, 571.777771f, 573.444458f, 565.666687f, 568.f, 571.222229f, 568.f, 576.888916f, 580.111084f, 572.333313f, 567.777771f, 581.333313f, 598.777771f, 611.555542f, 608.222229f, 628.555542f, 660.f, 686.333313f, 699.f, 714.333313f, 732.2 [...]
+0.f, 1034.777832f, 922.333313f, 773.222229f, 679.777771f, 630.333313f, 606.666687f, 580.f, 582.111084f, 578.888916f, 588.777771f, 574.777771f, 579.666687f, 605.333313f, 746.666687f, 971.444458f, 1162.444458f, 1135.666626f, 942.777771f, 754.f, 641.888916f, 610.555542f, 584.111084f, 587.333313f, 583.888916f, 575.888916f, 578.888916f, 572.777771f, 589.777771f, 588.222229f, 583.111084f, 568.444458f, 574.222229f, 582.888916f, 602.444458f, 603.111084f, 606.888916f, 620.555542f, 633.888916f, 65 [...]
+0.f, 797.444458f, 743.333313f, 672.111084f, 628.777771f, 610.444458f, 606.888916f, 595.333313f, 595.888916f, 589.222229f, 592.666687f, 580.777771f, 584.333313f, 598.111084f, 694.777771f, 870.222229f, 1012.555542f, 992.f, 841.222229f, 699.111084f, 627.888916f, 615.777771f, 603.333313f, 598.222229f, 576.444458f, 574.333313f, 594.777771f, 612.777771f, 636.333313f, 629.222229f, 617.333313f, 592.777771f, 588.222229f, 592.888916f, 603.444458f, 600.777771f, 603.f, 606.888916f, 611.888916f, 621. [...]
+0.f, 661.444458f, 649.666687f, 612.666687f, 596.333313f, 590.888916f, 602.111084f, 598.f, 587.666687f, 584.666687f, 582.777771f, 584.444458f, 584.777771f, 596.555542f, 653.777771f, 745.555542f, 808.666687f, 777.111084f, 702.666687f, 654.555542f, 648.444458f, 654.888916f, 648.222229f, 629.f, 604.666687f, 597.f, 620.666687f, 637.333313f, 661.444458f, 649.111084f, 641.222229f, 606.333313f, 585.666687f, 575.333313f, 579.666687f, 589.888916f, 590.777771f, 597.888916f, 603.777771f, 623.777771f [...]
+0.f, 604.f, 600.333313f, 589.333313f, 594.888916f, 595.111084f, 597.888916f, 603.888916f, 576.444458f, 579.222229f, 565.333313f, 577.444458f, 576.f, 590.888916f, 615.111084f, 664.333313f, 711.666687f, 730.777771f, 727.222229f, 734.666687f, 763.555542f, 771.888916f, 730.f, 681.333313f, 638.f, 639.888916f, 658.f, 699.f, 740.888916f, 731.111084f, 696.444458f, 636.111084f, 604.666687f, 589.888916f, 584.444458f, 588.444458f, 591.f, 594.222229f, 601.111084f, 615.888916f, 639.888916f, 651.f, 64 [...]
+0.f, 569.111084f, 570.f, 579.888916f, 605.222229f, 621.666687f, 623.777771f, 610.888916f, 583.777771f, 578.222229f, 571.333313f, 582.444458f, 584.f, 590.555542f, 611.222229f, 650.888916f, 720.222229f, 811.111084f, 901.555542f, 978.888916f, 1009.555542f, 971.777771f, 871.888916f, 766.333313f, 701.666687f, 695.555542f, 741.333313f, 857.888916f, 977.222229f, 959.888916f, 834.111084f, 677.222229f, 609.111084f, 579.666687f, 566.333313f, 577.555542f, 580.555542f, 593.111084f, 604.111084f, 627. [...]
+0.f, 556.555542f, 557.444458f, 576.444458f, 601.444458f, 629.777771f, 628.111084f, 620.666687f, 594.111084f, 590.111084f, 583.444458f, 589.666687f, 591.777771f, 592.888916f, 610.666687f, 647.555542f, 751.555542f, 953.444458f, 1164.444458f, 1311.f, 1283.111084f, 1159.666626f, 955.111084f, 800.555542f, 708.555542f, 732.333313f, 847.555542f, 1103.f, 1311.888916f, 1294.111084f, 1035.f, 766.444458f, 639.111084f, 598.444458f, 580.666687f, 580.666687f, 588.777771f, 603.555542f, 616.333313f, 631 [...]
+0.f, 550.222229f, 557.555542f, 563.f, 589.555542f, 615.555542f, 624.444458f, 604.333313f, 602.f, 601.333313f, 613.333313f, 599.222229f, 593.222229f, 580.666687f, 606.111084f, 630.f, 722.666687f, 937.555542f, 1180.444458f, 1346.111084f, 1284.111084f, 1137.111084f, 930.222229f, 775.777771f, 689.333313f, 715.222229f, 893.333313f, 1210.888916f, 1491.222168f, 1476.333374f, 1174.888916f, 835.111084f, 658.f, 599.555542f, 586.555542f, 591.444458f, 611.666687f, 629.555542f, 651.555542f, 658.11108 [...]
+0.f, 554.555542f, 563.444458f, 557.333313f, 574.666687f, 584.111084f, 592.777771f, 580.666687f, 580.f, 591.555542f, 601.222229f, 594.777771f, 578.444458f, 560.888916f, 588.111084f, 609.777771f, 682.666687f, 840.444458f, 1026.111084f, 1142.444458f, 1075.777832f, 955.222229f, 800.333313f, 697.333313f, 643.111084f, 679.555542f, 840.333313f, 1110.666626f, 1327.555542f, 1316.333374f, 1070.777832f, 811.666687f, 661.555542f, 606.444458f, 594.777771f, 595.666687f, 624.777771f, 642.666687f, 664.6 [...]
+0.f, 553.111084f, 562.222229f, 554.666687f, 579.111084f, 585.111084f, 596.111084f, 570.888916f, 571.222229f, 578.777771f, 591.222229f, 579.444458f, 560.555542f, 543.444458f, 573.222229f, 588.555542f, 628.222229f, 677.444458f, 757.444458f, 799.222229f, 781.444458f, 728.111084f, 674.888916f, 625.888916f, 617.777771f, 635.888916f, 740.333313f, 869.111084f, 995.111084f, 983.555542f, 875.f, 729.333313f, 639.888916f, 603.222229f, 595.333313f, 603.666687f, 626.333313f, 646.555542f, 653.333313f, [...]
+0.f, 560.333313f, 566.222229f, 560.888916f, 569.111084f, 575.f, 577.666687f, 564.666687f, 555.555542f, 564.444458f, 565.888916f, 567.333313f, 558.555542f, 557.333313f, 579.222229f, 579.555542f, 593.888916f, 597.333313f, 628.666687f, 640.f, 645.111084f, 629.555542f, 618.777771f, 590.555542f, 592.111084f, 602.666687f, 659.666687f, 700.f, 735.666687f, 723.888916f, 688.f, 631.444458f, 602.666687f, 594.333313f, 596.555542f, 594.888916f, 600.f, 611.333313f, 608.111084f, 593.888916f, 579.666687 [...]
+0.f, 560.555542f, 559.444458f, 559.333313f, 568.777771f, 587.222229f, 590.777771f, 574.111084f, 558.555542f, 564.777771f, 564.111084f, 556.555542f, 548.888916f, 551.333313f, 567.f, 553.555542f, 552.777771f, 544.444458f, 560.777771f, 579.111084f, 600.f, 596.f, 591.222229f, 569.444458f, 582.888916f, 591.666687f, 620.f, 606.333313f, 610.f, 607.555542f, 618.555542f, 594.444458f, 589.f, 584.333313f, 587.f, 578.333313f, 577.888916f, 587.888916f, 585.222229f, 585.444458f, 579.f, 582.666687f, 57 [...]
+0.f, 571.111084f, 564.333313f, 560.888916f, 561.222229f, 574.888916f, 578.555542f, 579.f, 569.777771f, 571.555542f, 558.222229f, 548.111084f, 541.555542f, 555.f, 562.222229f, 550.666687f, 542.777771f, 542.111084f, 554.777771f, 565.f, 583.444458f, 588.777771f, 596.222229f, 580.666687f, 586.777771f, 581.777771f, 593.444458f, 575.f, 562.777771f, 562.777771f, 567.222229f, 563.777771f, 564.222229f, 557.222229f, 561.222229f, 556.444458f, 564.666687f, 573.333313f, 566.777771f, 577.777771f, 578. [...]
+0.f, 577.222229f, 575.111084f, 571.777771f, 574.333313f, 579.333313f, 590.555542f, 589.f, 578.444458f, 564.666687f, 545.111084f, 542.444458f, 540.111084f, 554.222229f, 549.666687f, 553.666687f, 548.777771f, 556.f, 560.444458f, 565.444458f, 580.222229f, 583.333313f, 587.888916f, 573.222229f, 577.666687f, 579.555542f, 580.555542f, 558.666687f, 532.f, 529.333313f, 536.777771f, 552.111084f, 552.f, 546.333313f, 540.333313f, 545.888916f, 559.444458f, 575.888916f, 572.444458f, 581.111084f, 573. [...]
+0.f, 583.333313f, 587.444458f, 574.666687f, 573.444458f, 563.888916f, 577.f, 588.555542f, 581.f, 559.555542f, 542.111084f, 548.666687f, 561.444458f, 587.333313f, 593.777771f, 599.888916f, 585.555542f, 580.888916f, 570.888916f, 563.777771f, 572.888916f, 583.888916f, 590.f, 574.f, 564.888916f, 554.f, 554.333313f, 544.666687f, 531.222229f, 522.666687f, 526.666687f, 542.333313f, 541.333313f, 544.111084f, 542.666687f, 559.666687f, 566.888916f, 571.f, 567.444458f, 563.777771f, 567.f, 576.33331 [...]
+0.f, 599.666687f, 585.111084f, 581.f, 575.111084f, 563.777771f, 579.111084f, 592.111084f, 588.f, 564.555542f, 557.111084f, 577.888916f, 619.222229f, 681.666687f, 703.222229f, 682.888916f, 624.222229f, 587.666687f, 565.777771f, 550.888916f, 559.f, 572.f, 570.777771f, 552.888916f, 535.888916f, 535.333313f, 539.777771f, 533.f, 530.555542f, 524.666687f, 533.777771f, 545.777771f, 549.555542f, 559.222229f, 556.444458f, 566.333313f, 567.777771f, 572.333313f, 573.111084f, 566.333313f, 562.222229 [...]
+0.f, 616.777771f, 586.555542f, 569.555542f, 560.333313f, 548.777771f, 575.111084f, 595.333313f, 603.111084f, 592.333313f, 587.555542f, 631.777771f, 729.888916f, 875.666687f, 931.555542f, 855.666687f, 726.333313f, 638.f, 595.333313f, 559.555542f, 547.888916f, 560.555542f, 566.777771f, 555.555542f, 539.777771f, 527.555542f, 537.555542f, 538.111084f, 544.444458f, 536.333313f, 539.444458f, 552.888916f, 564.555542f, 574.777771f, 570.888916f, 578.333313f, 577.111084f, 578.444458f, 572.f, 563.1 [...]
+0.f, 636.888916f, 590.222229f, 569.666687f, 558.222229f, 558.666687f, 599.666687f, 628.777771f, 651.777771f, 636.777771f, 613.444458f, 662.777771f, 811.444458f, 1035.333374f, 1122.555542f, 1005.f, 791.888916f, 647.222229f, 599.f, 574.555542f, 551.666687f, 554.777771f, 552.222229f, 554.777771f, 542.333313f, 536.444458f, 541.888916f, 538.111084f, 537.777771f, 534.666687f, 534.888916f, 549.777771f, 577.333313f, 597.666687f, 600.f, 591.444458f, 584.333313f, 591.222229f, 576.666687f, 569.1110 [...]
+0.f, 632.333313f, 598.444458f, 576.111084f, 572.555542f, 572.666687f, 621.333313f, 665.333313f, 711.111084f, 689.888916f, 652.222229f, 691.444458f, 838.111084f, 1048.555542f, 1111.888916f, 997.f, 794.444458f, 664.777771f, 611.111084f, 598.888916f, 567.777771f, 563.111084f, 551.f, 556.888916f, 553.666687f, 543.111084f, 538.111084f, 536.333313f, 533.555542f, 533.888916f, 536.666687f, 567.111084f, 616.333313f, 647.444458f, 661.f, 646.444458f, 634.555542f, 612.777771f, 585.888916f, 569.66668 [...]
+0.f, 616.555542f, 588.f, 579.222229f, 573.444458f, 598.333313f, 650.333313f, 712.888916f, 755.888916f, 718.111084f, 672.f, 666.111084f, 755.444458f, 876.f, 909.111084f, 839.444458f, 704.f, 620.333313f, 589.777771f, 600.333313f, 584.333313f, 578.333313f, 551.555542f, 559.555542f, 553.f, 548.111084f, 528.333313f, 517.f, 515.f, 524.111084f, 532.f, 560.888916f, 627.333313f, 696.888916f, 743.555542f, 726.888916f, 688.888916f, 640.f, 602.f, 591.888916f, 598.888916f, 595.888916f, 577.444458f, 5 [...]
+0.f, 608.777771f, 595.333313f, 603.444458f, 597.f, 609.555542f, 638.f, 692.111084f, 729.666687f, 696.888916f, 653.888916f, 628.555542f, 661.666687f, 705.f, 700.444458f, 671.111084f, 631.222229f, 612.111084f, 602.666687f, 604.777771f, 592.555542f, 586.888916f, 557.444458f, 557.777771f, 551.666687f, 547.f, 530.333313f, 512.888916f, 523.f, 526.f, 545.666687f, 570.f, 639.555542f, 727.333313f, 791.f, 802.444458f, 758.666687f, 681.111084f, 621.888916f, 593.888916f, 594.111084f, 584.666687f, 56 [...]
+0.f, 617.333313f, 615.222229f, 626.f, 613.f, 617.222229f, 618.333313f, 635.666687f, 650.444458f, 637.555542f, 611.111084f, 575.222229f, 569.777771f, 578.888916f, 582.777771f, 578.f, 573.555542f, 578.555542f, 581.f, 584.333313f, 575.888916f, 573.555542f, 556.888916f, 557.666687f, 551.777771f, 543.888916f, 531.666687f, 524.f, 533.111084f, 529.333313f, 537.222229f, 554.111084f, 614.222229f, 719.111084f, 800.222229f, 840.777771f, 798.f, 720.444458f, 644.888916f, 591.222229f, 580.888916f, 568 [...]
+0.f, 625.f, 636.222229f, 642.111084f, 631.333313f, 613.f, 585.888916f, 580.888916f, 588.333313f, 588.333313f, 567.555542f, 550.555542f, 541.777771f, 546.444458f, 547.111084f, 550.555542f, 554.444458f, 563.f, 560.888916f, 565.777771f, 558.f, 552.111084f, 537.111084f, 541.666687f, 548.555542f, 554.222229f, 541.222229f, 538.888916f, 544.666687f, 535.666687f, 550.111084f, 558.222229f, 607.333313f, 683.888916f, 775.555542f, 832.222229f, 804.777771f, 728.f, 655.111084f, 593.555542f, 563.555542 [...]
+0.f, 640.111084f, 656.666687f, 641.222229f, 623.444458f, 600.888916f, 580.222229f, 569.777771f, 568.111084f, 567.f, 557.111084f, 542.222229f, 525.222229f, 518.444458f, 523.555542f, 539.555542f, 542.777771f, 554.333313f, 547.222229f, 561.f, 549.333313f, 539.555542f, 525.777771f, 529.111084f, 537.888916f, 548.444458f, 540.111084f, 549.444458f, 538.888916f, 530.333313f, 542.111084f, 565.111084f, 604.f, 656.888916f, 734.555542f, 790.666687f, 762.111084f, 704.333313f, 640.666687f, 596.666687f [...]
+0.f, 621.222229f, 628.111084f, 605.333313f, 596.333313f, 578.777771f, 573.f, 570.444458f, 564.222229f, 552.111084f, 537.888916f, 537.555542f, 533.222229f, 532.888916f, 531.555542f, 543.444458f, 541.222229f, 547.666687f, 541.111084f, 552.444458f, 542.666687f, 532.888916f, 523.222229f, 520.555542f, 526.888916f, 534.222229f, 531.888916f, 533.333313f, 523.777771f, 517.333313f, 535.f, 556.444458f, 598.f, 631.111084f, 691.666687f, 723.777771f, 700.555542f, 656.222229f, 613.444458f, 593.666687f [...]
+0.f, 603.f, 601.f, 591.666687f, 580.f, 567.888916f, 566.222229f, 564.777771f, 555.777771f, 543.111084f, 538.f, 531.888916f, 527.444458f, 522.333313f, 527.111084f, 539.333313f, 539.222229f, 543.777771f, 542.222229f, 553.333313f, 552.666687f, 549.111084f, 540.444458f, 535.888916f, 533.888916f, 534.666687f, 533.222229f, 538.555542f, 528.111084f, 524.777771f, 524.777771f, 552.777771f, 580.111084f, 615.555542f, 647.222229f, 663.555542f, 643.888916f, 618.444458f, 590.222229f, 581.222229f, 565. [...]
+0.f, 573.222229f, 571.f, 577.888916f, 576.f, 576.333313f, 574.666687f, 570.222229f, 562.555542f, 551.888916f, 545.222229f, 530.111084f, 536.333313f, 533.f, 534.222229f, 530.222229f, 524.666687f, 533.f, 536.222229f, 543.f, 543.111084f, 545.666687f, 543.555542f, 544.888916f, 540.222229f, 541.333313f, 542.f, 548.666687f, 546.111084f, 538.777771f, 523.888916f, 531.666687f, 560.f, 592.f, 613.555542f, 607.777771f, 605.333313f, 590.f, 585.222229f, 578.222229f, 575.444458f, 564.111084f, 549.6666 [...]
+0.f, 564.f, 559.666687f, 573.777771f, 576.555542f, 586.666687f, 587.333313f, 588.555542f, 576.f, 560.888916f, 550.666687f, 539.666687f, 536.888916f, 531.111084f, 531.444458f, 534.555542f, 527.111084f, 536.222229f, 541.444458f, 558.f, 561.f, 568.666687f, 555.777771f, 560.222229f, 552.333313f, 561.333313f, 558.222229f, 561.555542f, 561.f, 559.333313f, 545.555542f, 549.222229f, 561.333313f, 582.666687f, 591.555542f, 586.111084f, 585.777771f, 574.f, 569.888916f, 562.222229f, 562.f, 551.66668 [...]
+0.f, 560.f, 556.777771f, 557.444458f, 575.666687f, 589.222229f, 599.111084f, 599.777771f, 585.f, 567.333313f, 550.222229f, 545.555542f, 538.f, 531.777771f, 533.222229f, 538.111084f, 534.222229f, 547.777771f, 556.f, 575.777771f, 567.555542f, 569.777771f, 564.f, 570.888916f, 571.444458f, 567.222229f, 564.777771f, 557.f, 557.222229f, 555.111084f, 550.111084f, 557.555542f, 569.444458f, 578.111084f, 574.777771f, 569.555542f, 573.222229f, 566.111084f, 563.f, 552.f, 556.f, 544.888916f, 534.7777 [...]
+0.f, 569.222229f, 560.666687f, 549.777771f, 571.111084f, 578.888916f, 583.777771f, 583.444458f, 570.444458f, 560.666687f, 547.888916f, 549.666687f, 539.222229f, 533.555542f, 532.444458f, 540.666687f, 540.222229f, 553.333313f, 569.888916f, 604.333313f, 614.444458f, 631.f, 612.222229f, 611.222229f, 592.777771f, 582.555542f, 563.222229f, 550.111084f, 543.111084f, 556.888916f, 554.666687f, 567.777771f, 561.777771f, 569.111084f, 568.888916f, 567.888916f, 562.333313f, 556.f, 548.777771f, 546.8 [...]
+0.f, 578.777771f, 579.333313f, 559.333313f, 580.111084f, 570.111084f, 562.777771f, 551.111084f, 543.777771f, 553.777771f, 551.333313f, 548.f, 543.444458f, 538.777771f, 542.333313f, 539.777771f, 546.555542f, 565.444458f, 616.888916f, 713.888916f, 806.111084f, 849.777771f, 779.888916f, 700.111084f, 630.222229f, 603.555542f, 568.888916f, 551.555542f, 541.555542f, 553.666687f, 549.444458f, 557.111084f, 555.333313f, 562.444458f, 567.111084f, 572.333313f, 568.555542f, 566.222229f, 561.111084f, [...]
+0.f, 581.222229f, 580.333313f, 564.222229f, 578.888916f, 561.777771f, 547.555542f, 528.555542f, 528.333313f, 549.444458f, 552.222229f, 553.777771f, 553.555542f, 558.888916f, 554.222229f, 552.f, 553.f, 573.888916f, 674.333313f, 893.777771f, 1166.666626f, 1257.888916f, 1107.222168f, 860.444458f, 684.111084f, 617.888916f, 577.f, 567.444458f, 561.777771f, 562.555542f, 556.555542f, 559.333313f, 563.111084f, 571.333313f, 578.111084f, 579.444458f, 582.888916f, 581.555542f, 593.222229f, 609.1110 [...]
+0.f, 569.888916f, 567.111084f, 562.666687f, 568.777771f, 558.111084f, 547.222229f, 534.888916f, 532.555542f, 548.f, 544.333313f, 552.555542f, 551.111084f, 565.666687f, 559.111084f, 563.111084f, 567.f, 593.222229f, 735.666687f, 1079.333374f, 1513.111084f, 1646.777832f, 1415.222168f, 1016.111084f, 757.555542f, 646.222229f, 599.222229f, 584.111084f, 591.333313f, 586.666687f, 586.222229f, 585.111084f, 592.444458f, 590.888916f, 590.777771f, 597.555542f, 616.f, 617.888916f, 657.666687f, 732.88 [...]
+0.f, 556.555542f, 561.f, 550.777771f, 552.555542f, 548.222229f, 553.888916f, 549.777771f, 548.777771f, 557.111084f, 540.555542f, 546.666687f, 550.444458f, 580.333313f, 579.111084f, 585.333313f, 584.f, 611.111084f, 750.111084f, 1087.222168f, 1523.111084f, 1651.111084f, 1450.222168f, 1064.f, 813.f, 677.f, 626.777771f, 640.777771f, 689.222229f, 692.666687f, 658.888916f, 612.777771f, 589.888916f, 578.f, 580.444458f, 588.f, 621.f, 635.666687f, 730.777771f, 903.444458f, 1086.777832f, 1088.2221 [...]
+0.f, 553.f, 568.f, 553.888916f, 549.222229f, 538.222229f, 547.444458f, 556.222229f, 556.222229f, 558.222229f, 535.444458f, 549.777771f, 572.555542f, 621.111084f, 620.555542f, 609.777771f, 605.333313f, 623.333313f, 730.444458f, 957.111084f, 1237.333374f, 1321.333374f, 1188.555542f, 967.555542f, 809.222229f, 711.333313f, 658.333313f, 710.333313f, 838.111084f, 867.222229f, 791.555542f, 654.888916f, 597.777771f, 571.333313f, 573.888916f, 582.666687f, 612.f, 635.666687f, 762.111084f, 1018.111 [...]
+0.f, 570.111084f, 583.111084f, 557.333313f, 548.333313f, 535.444458f, 547.333313f, 547.333313f, 544.555542f, 553.888916f, 550.222229f, 573.777771f, 613.111084f, 668.333313f, 670.777771f, 643.111084f, 611.444458f, 614.222229f, 677.555542f, 786.111084f, 902.666687f, 930.333313f, 879.333313f, 815.777771f, 749.111084f, 689.222229f, 653.333313f, 750.888916f, 928.111084f, 969.f, 861.888916f, 665.777771f, 593.444458f, 562.222229f, 574.555542f, 574.222229f, 591.f, 616.111084f, 743.444458f, 974.7 [...]
+0.f, 577.333313f, 580.111084f, 573.555542f, 562.111084f, 556.f, 550.666687f, 551.111084f, 545.222229f, 554.444458f, 565.666687f, 597.777771f, 637.777771f, 681.222229f, 671.222229f, 638.777771f, 598.444458f, 592.444458f, 624.f, 675.666687f, 711.111084f, 716.444458f, 687.888916f, 693.111084f, 679.777771f, 663.555542f, 643.777771f, 720.222229f, 876.777771f, 910.333313f, 833.333313f, 657.333313f, 597.888916f, 568.777771f, 581.666687f, 583.444458f, 581.222229f, 592.111084f, 679.f, 830.444458f [...]
+0.f, 582.333313f, 571.111084f, 564.222229f, 561.888916f, 570.111084f, 567.444458f, 569.666687f, 561.f, 571.f, 585.f, 601.888916f, 624.444458f, 644.222229f, 648.444458f, 626.333313f, 586.444458f, 570.666687f, 577.777771f, 613.555542f, 627.111084f, 630.444458f, 611.111084f, 618.666687f, 613.333313f, 604.222229f, 602.666687f, 649.333313f, 729.222229f, 739.666687f, 696.888916f, 608.777771f, 581.f, 569.888916f, 574.f, 569.333313f, 559.555542f, 567.f, 613.f, 678.444458f, 719.444458f, 699.55554 [...]
+0.f, 565.888916f, 562.111084f, 572.222229f, 578.777771f, 583.666687f, 580.888916f, 591.666687f, 587.555542f, 582.444458f, 581.f, 591.111084f, 600.111084f, 601.333313f, 596.222229f, 589.222229f, 569.111084f, 557.777771f, 551.222229f, 568.444458f, 576.777771f, 578.333313f, 574.777771f, 578.111084f, 586.444458f, 582.444458f, 582.444458f, 586.333313f, 606.888916f, 612.666687f, 597.888916f, 568.777771f, 554.555542f, 555.444458f, 557.f, 554.777771f, 543.f, 545.888916f, 565.222229f, 605.777771f [...]
+0.f, 576.666687f, 575.444458f, 582.444458f, 584.f, 599.111084f, 609.666687f, 623.222229f, 609.777771f, 587.444458f, 567.666687f, 570.555542f, 570.222229f, 572.777771f, 575.444458f, 575.888916f, 570.888916f, 550.444458f, 548.111084f, 560.444458f, 572.888916f, 578.777771f, 570.222229f, 566.333313f, 555.333313f, 547.f, 552.111084f, 555.555542f, 558.666687f, 554.222229f, 544.888916f, 538.444458f, 530.333313f, 543.777771f, 545.333313f, 545.f, 533.444458f, 540.f, 553.f, 574.888916f, 585.222229 [...]
+0.f, 585.555542f, 597.333313f, 611.333313f, 620.666687f, 634.555542f, 655.222229f, 657.888916f, 642.777771f, 608.888916f, 576.111084f, 570.111084f, 559.888916f, 559.444458f, 550.111084f, 553.666687f, 554.222229f, 542.444458f, 546.777771f, 559.444458f, 573.666687f, 583.111084f, 567.888916f, 571.888916f, 558.555542f, 558.222229f, 549.111084f, 545.888916f, 545.f, 541.777771f, 537.777771f, 534.444458f, 524.888916f, 531.333313f, 534.222229f, 539.111084f, 532.333313f, 532.666687f, 543.444458f, [...]
+0.f, 612.666687f, 623.333313f, 636.222229f, 639.888916f, 651.777771f, 671.444458f, 678.333313f, 669.f, 635.222229f, 597.f, 576.888916f, 551.f, 548.222229f, 537.777771f, 546.222229f, 545.888916f, 545.777771f, 556.666687f, 573.444458f, 589.222229f, 592.888916f, 577.777771f, 577.555542f, 562.888916f, 555.333313f, 543.f, 547.222229f, 551.888916f, 542.777771f, 536.555542f, 531.222229f, 521.888916f, 530.555542f, 536.888916f, 545.111084f, 537.888916f, 532.333313f, 545.333313f, 545.f, 553.111084 [...]
+0.f, 623.888916f, 620.444458f, 630.555542f, 640.777771f, 646.666687f, 657.666687f, 656.333313f, 656.666687f, 643.777771f, 616.888916f, 591.111084f, 562.111084f, 552.111084f, 537.222229f, 539.444458f, 532.555542f, 540.f, 552.666687f, 566.333313f, 577.111084f, 574.222229f, 574.f, 583.222229f, 573.f, 561.111084f, 541.333313f, 545.777771f, 545.444458f, 537.888916f, 535.666687f, 539.666687f, 540.111084f, 536.111084f, 531.f, 530.666687f, 530.222229f, 527.888916f, 544.444458f, 545.111084f, 548. [...]
+0.f, 648.888916f, 643.222229f, 656.222229f, 653.777771f, 647.333313f, 635.777771f, 628.888916f, 619.444458f, 607.444458f, 589.555542f, 577.111084f, 558.777771f, 556.777771f, 543.f, 538.777771f, 521.777771f, 523.888916f, 532.333313f, 546.666687f, 561.555542f, 564.f, 576.444458f, 578.555542f, 573.222229f, 548.444458f, 532.222229f, 534.f, 532.f, 529.222229f, 523.111084f, 528.555542f, 539.111084f, 539.888916f, 540.777771f, 541.222229f, 545.f, 547.444458f, 551.888916f, 554.555542f, 559.f, 549 [...]
+0.f, 654.f, 655.222229f, 661.f, 674.444458f, 681.444458f, 662.222229f, 634.333313f, 595.333313f, 585.555542f, 573.222229f, 576.222229f, 563.666687f, 559.555542f, 548.888916f, 540.777771f, 525.111084f, 518.888916f, 518.222229f, 528.f, 539.222229f, 558.666687f, 570.777771f, 579.555542f, 567.444458f, 551.555542f, 535.f, 531.333313f, 528.777771f, 520.f, 526.777771f, 538.444458f, 555.111084f, 556.555542f, 550.111084f, 544.666687f, 545.555542f, 551.888916f, 559.222229f, 563.555542f, 564.555542 [...]
+0.f, 653.444458f, 689.555542f, 730.333313f, 767.888916f, 771.f, 738.555542f, 697.222229f, 638.888916f, 595.666687f, 560.f, 557.222229f, 547.777771f, 553.111084f, 543.555542f, 547.444458f, 529.111084f, 527.555542f, 519.555542f, 530.111084f, 541.888916f, 558.777771f, 569.111084f, 577.666687f, 579.666687f, 558.f, 539.333313f, 526.f, 532.444458f, 528.333313f, 535.555542f, 545.f, 558.444458f, 564.555542f, 561.f, 557.222229f, 555.555542f, 566.f, 571.111084f, 572.888916f, 571.555542f, 562.22222 [...]
+0.f, 670.333313f, 725.888916f, 803.333313f, 893.666687f, 914.222229f, 862.666687f, 777.f, 691.444458f, 631.444458f, 587.777771f, 573.777771f, 561.777771f, 553.666687f, 537.666687f, 544.444458f, 532.333313f, 540.f, 530.666687f, 548.777771f, 569.111084f, 582.222229f, 580.f, 576.555542f, 575.666687f, 559.555542f, 541.333313f, 531.666687f, 543.666687f, 553.777771f, 567.666687f, 572.888916f, 574.333313f, 570.666687f, 561.f, 546.f, 542.222229f, 562.555542f, 583.888916f, 595.444458f, 581.444458 [...]
+0.f, 689.555542f, 766.f, 919.f, 1070.444458f, 1112.222168f, 1019.888916f, 867.f, 746.f, 652.444458f, 595.777771f, 569.666687f, 561.f, 557.222229f, 541.333313f, 551.222229f, 540.888916f, 554.777771f, 547.888916f, 567.777771f, 581.444458f, 582.f, 581.444458f, 575.888916f, 584.f, 564.333313f, 558.444458f, 549.777771f, 557.444458f, 571.777771f, 585.444458f, 595.666687f, 599.f, 581.888916f, 563.333313f, 541.666687f, 543.444458f, 563.777771f, 574.333313f, 588.777771f, 576.777771f, 563.666687f, [...]
+0.f, 728.777771f, 828.666687f, 996.111084f, 1179.333374f, 1217.f, 1096.555542f, 888.555542f, 746.f, 656.777771f, 613.555542f, 596.888916f, 591.888916f, 571.222229f, 556.444458f, 561.f, 563.222229f, 567.111084f, 551.333313f, 571.888916f, 579.222229f, 585.222229f, 581.222229f, 585.777771f, 593.444458f, 584.444458f, 574.111084f, 573.777771f, 575.222229f, 595.444458f, 607.222229f, 616.888916f, 626.444458f, 602.777771f, 582.444458f, 540.555542f, 542.777771f, 549.444458f, 554.666687f, 567.6666 [...]
+0.f, 705.222229f, 819.666687f, 990.777771f, 1154.444458f, 1177.777832f, 1052.555542f, 860.555542f, 732.333313f, 644.222229f, 609.f, 600.777771f, 605.f, 603.555542f, 603.111084f, 613.555542f, 614.777771f, 607.555542f, 586.666687f, 585.333313f, 579.111084f, 583.f, 603.777771f, 624.222229f, 628.222229f, 598.444458f, 579.111084f, 579.f, 586.666687f, 596.333313f, 613.888916f, 625.555542f, 636.111084f, 616.333313f, 584.555542f, 552.888916f, 547.333313f, 552.777771f, 552.555542f, 555.f, 556.f,  [...]
+0.f, 704.888916f, 822.777771f, 942.444458f, 1049.222168f, 1025.777832f, 934.222229f, 796.111084f, 708.444458f, 645.333313f, 617.555542f, 620.333313f, 622.666687f, 637.444458f, 643.777771f, 651.555542f, 642.f, 616.777771f, 599.888916f, 589.111084f, 603.111084f, 633.333313f, 693.111084f, 731.555542f, 704.666687f, 641.888916f, 582.444458f, 582.444458f, 586.444458f, 601.333313f, 621.777771f, 631.777771f, 636.888916f, 609.666687f, 574.666687f, 551.111084f, 545.666687f, 555.555542f, 552.666687 [...]
+0.f, 671.444458f, 746.888916f, 843.888916f, 886.777771f, 872.666687f, 808.555542f, 750.111084f, 705.f, 649.444458f, 617.888916f, 608.333313f, 614.777771f, 653.666687f, 679.222229f, 692.f, 668.333313f, 638.f, 621.888916f, 605.f, 632.666687f, 691.222229f, 798.222229f, 834.777771f, 782.333313f, 673.666687f, 603.888916f, 588.777771f, 596.555542f, 606.555542f, 638.666687f, 646.555542f, 632.444458f, 599.111084f, 560.111084f, 555.444458f, 545.555542f, 572.666687f, 572.333313f, 579.666687f, 567. [...]
+0.f, 652.888916f, 698.222229f, 748.444458f, 768.666687f, 751.f, 730.555542f, 701.f, 683.777771f, 645.222229f, 613.888916f, 595.777771f, 603.222229f, 644.444458f, 679.666687f, 689.f, 665.333313f, 633.f, 609.f, 597.f, 640.444458f, 725.666687f, 855.444458f, 901.333313f, 838.555542f, 710.555542f, 623.f, 599.333313f, 593.f, 593.f, 610.888916f, 618.555542f, 602.111084f, 574.888916f, 554.555542f, 557.222229f, 556.222229f, 576.888916f, 569.888916f, 579.888916f, 568.777771f, 602.444458f, 632.1110 [...]
+0.f, 602.333313f, 628.333313f, 658.888916f, 669.444458f, 662.888916f, 654.777771f, 647.888916f, 640.555542f, 617.666687f, 595.333313f, 585.888916f, 596.444458f, 629.333313f, 655.555542f, 660.222229f, 647.222229f, 626.111084f, 609.777771f, 612.111084f, 647.444458f, 731.555542f, 829.444458f, 862.222229f, 813.444458f, 708.666687f, 646.888916f, 610.666687f, 595.222229f, 585.666687f, 588.888916f, 593.888916f, 573.555542f, 557.888916f, 553.f, 561.666687f, 565.888916f, 580.f, 570.777771f, 584.3 [...]
+0.f, 577.555542f, 598.555542f, 608.111084f, 627.444458f, 614.111084f, 615.666687f, 601.f, 593.333313f, 585.f, 584.333313f, 592.444458f, 621.888916f, 633.444458f, 642.555542f, 635.444458f, 630.111084f, 624.222229f, 615.444458f, 636.444458f, 676.555542f, 764.f, 852.f, 884.333313f, 816.444458f, 709.333313f, 635.333313f, 604.f, 579.333313f, 563.777771f, 557.333313f, 559.666687f, 549.222229f, 546.777771f, 550.888916f, 560.555542f, 559.888916f, 563.444458f, 562.222229f, 586.111084f, 609.111084 [...]
+0.f, 567.111084f, 585.777771f, 596.333313f, 606.222229f, 594.555542f, 580.777771f, 572.f, 566.222229f, 569.666687f, 575.666687f, 605.888916f, 638.888916f, 656.111084f, 640.222229f, 619.111084f, 606.333313f, 618.444458f, 629.777771f, 690.f, 760.222229f, 892.777771f, 984.777771f, 985.222229f, 866.111084f, 728.888916f, 649.222229f, 612.666687f, 580.666687f, 567.888916f, 568.111084f, 571.222229f, 558.888916f, 551.333313f, 550.111084f, 555.888916f, 552.111084f, 559.666687f, 569.444458f, 596.7 [...]
+0.f, 565.888916f, 570.555542f, 581.444458f, 591.111084f, 585.777771f, 568.444458f, 557.666687f, 563.888916f, 570.f, 583.666687f, 599.444458f, 643.333313f, 658.777771f, 653.777771f, 627.444458f, 617.333313f, 642.888916f, 673.666687f, 763.f, 909.555542f, 1085.222168f, 1191.111084f, 1118.444458f, 925.333313f, 734.222229f, 633.777771f, 605.222229f, 592.333313f, 581.333313f, 577.666687f, 561.666687f, 552.666687f, 553.222229f, 557.888916f, 558.666687f, 545.666687f, 548.666687f, 566.555542f, 59 [...]
+0.f, 559.444458f, 571.111084f, 571.555542f, 578.111084f, 572.333313f, 563.f, 554.222229f, 560.888916f, 569.888916f, 581.666687f, 586.111084f, 608.111084f, 628.666687f, 633.333313f, 630.111084f, 634.666687f, 668.666687f, 708.444458f, 829.777771f, 1032.888916f, 1222.777832f, 1271.444458f, 1115.333374f, 898.555542f, 721.111084f, 643.222229f, 616.777771f, 603.111084f, 593.777771f, 584.111084f, 566.444458f, 555.444458f, 547.111084f, 549.111084f, 543.111084f, 538.f, 544.f, 554.555542f, 577.555 [...]
+0.f, 559.555542f, 562.555542f, 561.444458f, 571.111084f, 575.555542f, 569.444458f, 564.222229f, 567.222229f, 579.333313f, 588.444458f, 582.111084f, 585.666687f, 594.333313f, 618.444458f, 649.888916f, 698.444458f, 732.333313f, 760.555542f, 839.777771f, 1023.555542f, 1177.777832f, 1177.888916f, 998.333313f, 806.333313f, 680.111084f, 640.111084f, 622.555542f, 617.777771f, 603.888916f, 596.222229f, 571.333313f, 559.111084f, 543.111084f, 548.444458f, 551.777771f, 543.111084f, 551.666687f, 546 [...]
+0.f, 571.222229f, 572.777771f, 574.222229f, 573.333313f, 578.111084f, 576.666687f, 580.555542f, 580.444458f, 597.555542f, 606.111084f, 604.666687f, 589.777771f, 586.222229f, 604.222229f, 658.555542f, 731.777771f, 778.f, 779.888916f, 811.f, 897.888916f, 985.111084f, 959.444458f, 845.111084f, 724.444458f, 657.555542f, 639.444458f, 639.777771f, 627.777771f, 622.777771f, 604.777771f, 583.555542f, 556.222229f, 538.333313f, 546.666687f, 556.555542f, 554.f, 562.444458f, 556.333313f, 570.222229f [...]
+0.f, 566.666687f, 571.333313f, 570.333313f, 567.888916f, 572.111084f, 572.555542f, 584.111084f, 607.888916f, 672.111084f, 739.555542f, 749.888916f, 698.222229f, 633.222229f, 617.f, 657.111084f, 721.888916f, 773.f, 771.333313f, 763.333313f, 766.111084f, 795.222229f, 783.777771f, 741.666687f, 680.444458f, 645.222229f, 634.555542f, 651.777771f, 649.555542f, 657.888916f, 627.777771f, 604.555542f, 566.555542f, 553.111084f, 549.111084f, 570.222229f, 574.666687f, 587.f, 574.777771f, 579.555542f [...]
+0.f, 556.555542f, 558.222229f, 563.777771f, 558.777771f, 570.333313f, 574.333313f, 596.666687f, 654.111084f, 810.888916f, 973.111084f, 999.777771f, 875.333313f, 712.f, 635.777771f, 633.777771f, 661.444458f, 708.555542f, 716.333313f, 715.888916f, 686.777771f, 684.555542f, 671.333313f, 669.444458f, 641.666687f, 635.333313f, 631.666687f, 678.888916f, 703.555542f, 736.777771f, 692.333313f, 644.111084f, 585.444458f, 566.111084f, 555.444458f, 562.777771f, 576.f, 585.333313f, 585.666687f, 577.6 [...]
+0.f, 542.333313f, 546.666687f, 552.888916f, 552.222229f, 555.f, 567.333313f, 594.888916f, 697.444458f, 923.666687f, 1158.777832f, 1204.666626f, 1026.111084f, 795.444458f, 666.222229f, 627.555542f, 626.111084f, 641.111084f, 650.666687f, 652.444458f, 644.222229f, 650.222229f, 641.333313f, 640.444458f, 623.777771f, 632.444458f, 647.111084f, 701.888916f, 748.444458f, 791.888916f, 755.666687f, 703.666687f, 631.111084f, 593.222229f, 558.444458f, 557.333313f, 573.f, 590.666687f, 599.777771f, 58 [...]
+0.f, 540.444458f, 539.888916f, 552.f, 555.f, 556.222229f, 571.222229f, 603.222229f, 707.666687f, 931.f, 1154.222168f, 1200.444458f, 1017.444458f, 798.666687f, 676.222229f, 628.222229f, 615.777771f, 612.f, 627.777771f, 629.666687f, 634.666687f, 635.777771f, 622.888916f, 621.111084f, 610.444458f, 619.f, 652.333313f, 730.222229f, 818.333313f, 857.111084f, 806.555542f, 721.111084f, 633.888916f, 590.222229f, 564.333313f, 558.777771f, 564.333313f, 580.666687f, 591.777771f, 590.333313f, 581.888 [...]
+0.f, 545.888916f, 549.333313f, 560.777771f, 561.111084f, 553.777771f, 565.888916f, 592.555542f, 671.777771f, 811.888916f, 939.555542f, 968.444458f, 860.555542f, 741.444458f, 670.333313f, 640.444458f, 630.222229f, 618.111084f, 632.444458f, 636.555542f, 650.555542f, 639.555542f, 622.666687f, 616.111084f, 616.222229f, 629.222229f, 692.666687f, 813.111084f, 981.f, 1020.555542f, 923.111084f, 763.222229f, 648.f, 599.444458f, 568.111084f, 564.333313f, 568.333313f, 574.888916f, 575.777771f, 589. [...]
+0.f, 546.555542f, 545.222229f, 550.222229f, 549.777771f, 551.f, 564.444458f, 584.f, 623.f, 690.444458f, 746.777771f, 772.333313f, 727.777771f, 693.111084f, 671.333313f, 674.666687f, 664.888916f, 647.555542f, 642.888916f, 645.555542f, 656.f, 641.222229f, 623.888916f, 618.666687f, 617.333313f, 637.555542f, 740.f, 941.666687f, 1185.f, 1240.222168f, 1079.222168f, 827.222229f, 660.777771f, 606.222229f, 590.333313f, 584.888916f, 581.111084f, 575.333313f, 563.888916f, 580.666687f, 581.555542f,  [...]
+0.f, 544.111084f, 548.777771f, 553.444458f, 555.333313f, 553.666687f, 563.555542f, 571.f, 590.777771f, 618.888916f, 630.444458f, 664.666687f, 677.f, 694.f, 699.666687f, 715.888916f, 719.333313f, 688.f, 648.666687f, 638.333313f, 639.777771f, 638.111084f, 625.666687f, 623.111084f, 623.333313f, 656.333313f, 765.777771f, 1008.888916f, 1276.444458f, 1352.222168f, 1157.333374f, 865.444458f, 675.444458f, 613.111084f, 602.222229f, 600.f, 596.888916f, 579.444458f, 559.222229f, 569.666687f, 573.55 [...]
+0.f, 547.444458f, 546.333313f, 536.444458f, 535.888916f, 541.222229f, 563.f, 571.f, 585.888916f, 601.222229f, 639.555542f, 686.888916f, 713.555542f, 734.f, 756.333313f, 782.666687f, 785.333313f, 734.111084f, 680.f, 655.333313f, 650.666687f, 651.f, 648.444458f, 652.222229f, 656.777771f, 680.555542f, 761.555542f, 952.777771f, 1138.222168f, 1198.111084f, 1040.333374f, 815.f, 660.111084f, 611.666687f, 606.666687f, 602.777771f, 590.333313f, 581.888916f, 563.333313f, 569.777771f, 567.111084f,  [...]
+0.f, 538.444458f, 542.f, 533.444458f, 531.888916f, 540.777771f, 561.888916f, 567.f, 577.888916f, 591.333313f, 639.666687f, 693.333313f, 738.777771f, 766.777771f, 805.444458f, 828.333313f, 825.777771f, 776.555542f, 712.777771f, 683.333313f, 674.111084f, 686.333313f, 716.555542f, 743.111084f, 755.111084f, 743.333313f, 745.888916f, 829.222229f, 913.555542f, 928.444458f, 835.111084f, 708.888916f, 628.444458f, 599.444458f, 583.f, 590.333313f, 578.555542f, 585.888916f, 565.555542f, 561.222229f [...]
+0.f, 542.222229f, 536.555542f, 524.f, 522.888916f, 532.777771f, 556.111084f, 558.555542f, 573.888916f, 583.222229f, 632.444458f, 680.111084f, 737.333313f, 798.777771f, 902.f, 1014.111084f, 1055.333374f, 975.444458f, 833.111084f, 733.111084f, 719.555542f, 766.f, 867.666687f, 941.111084f, 940.888916f, 859.888916f, 779.222229f, 745.444458f, 740.888916f, 727.444458f, 695.444458f, 647.444458f, 612.888916f, 597.777771f, 582.555542f, 579.111084f, 566.666687f, 569.777771f, 557.888916f, 553.44445 [...]
+0.f, 528.777771f, 533.333313f, 535.333313f, 540.333313f, 542.333313f, 562.111084f, 562.444458f, 568.888916f, 575.444458f, 604.555542f, 643.444458f, 710.111084f, 826.777771f, 1062.333374f, 1348.111084f, 1478.222168f, 1343.111084f, 1048.333374f, 849.f, 816.444458f, 907.f, 1057.333374f, 1156.222168f, 1121.222168f, 968.333313f, 801.777771f, 710.222229f, 671.888916f, 658.444458f, 643.111084f, 628.666687f, 608.666687f, 594.222229f, 579.f, 578.666687f, 574.555542f, 565.111084f, 550.666687f, 534 [...]
+0.f, 530.111084f, 544.333313f, 537.666687f, 547.f, 545.111084f, 566.777771f, 578.222229f, 577.333313f, 579.777771f, 589.222229f, 616.444458f, 681.111084f, 842.f, 1204.555542f, 1663.666626f, 1896.444458f, 1708.777832f, 1284.111084f, 988.666687f, 937.222229f, 1048.333374f, 1209.f, 1291.f, 1205.444458f, 993.555542f, 793.111084f, 695.111084f, 655.222229f, 655.333313f, 638.444458f, 630.555542f, 607.444458f, 583.222229f, 564.888916f, 552.666687f, 560.111084f, 550.888916f, 548.666687f, 546.4444 [...]
+0.f, 525.888916f, 541.111084f, 539.f, 553.222229f, 567.666687f, 594.666687f, 611.555542f, 599.333313f, 590.f, 587.555542f, 605.333313f, 651.555542f, 803.111084f, 1157.222168f, 1639.444458f, 1879.888916f, 1726.f, 1308.444458f, 1043.555542f, 1028.777832f, 1149.333374f, 1249.f, 1232.888916f, 1105.111084f, 918.888916f, 767.777771f, 713.444458f, 700.333313f, 706.111084f, 672.666687f, 650.222229f, 616.888916f, 582.111084f, 555.444458f, 539.333313f, 556.444458f, 551.666687f, 550.666687f, 543.f, [...]
+0.f, 547.444458f, 544.555542f, 540.666687f, 552.222229f, 584.f, 626.333313f, 670.555542f, 657.555542f, 628.222229f, 589.222229f, 596.777771f, 626.888916f, 725.666687f, 951.f, 1282.111084f, 1450.333374f, 1370.777832f, 1106.666626f, 963.444458f, 995.222229f, 1113.555542f, 1171.111084f, 1105.888916f, 962.222229f, 821.555542f, 734.666687f, 727.888916f, 737.f, 761.444458f, 727.666687f, 682.333313f, 618.666687f, 568.888916f, 549.888916f, 531.666687f, 541.333313f, 533.333313f, 545.111084f, 549. [...]
+0.f, 564.f, 545.111084f, 546.222229f, 568.666687f, 621.888916f, 689.222229f, 748.666687f, 746.f, 686.666687f, 613.444458f, 591.666687f, 602.555542f, 644.888916f, 741.222229f, 895.333313f, 975.777771f, 956.222229f, 850.555542f, 808.777771f, 860.f, 952.222229f, 976.777771f, 911.666687f, 806.888916f, 738.333313f, 714.f, 731.777771f, 766.f, 800.333313f, 771.333313f, 699.f, 620.777771f, 568.666687f, 569.333313f, 555.888916f, 558.888916f, 542.444458f, 543.222229f, 541.777771f, 558.222229f, 566 [...]
+0.f, 575.555542f, 548.f, 544.444458f, 557.666687f, 618.f, 693.555542f, 783.888916f, 786.555542f, 716.888916f, 623.555542f, 597.111084f, 607.111084f, 620.555542f, 641.222229f, 684.444458f, 719.222229f, 725.111084f, 714.555542f, 713.111084f, 735.555542f, 793.f, 817.333313f, 806.888916f, 750.555542f, 722.888916f, 709.777771f, 724.222229f, 741.777771f, 767.222229f, 746.444458f, 676.777771f, 606.111084f, 557.777771f, 563.f, 555.888916f, 554.333313f, 541.666687f, 548.444458f, 547.111084f, 562. [...]
+0.f, 567.333313f, 545.444458f, 545.111084f, 559.444458f, 612.777771f, 690.777771f, 765.222229f, 780.111084f, 714.f, 635.333313f, 607.555542f, 617.f, 624.888916f, 622.f, 643.333313f, 669.888916f, 683.444458f, 669.333313f, 648.222229f, 640.444458f, 671.111084f, 692.222229f, 712.777771f, 721.333313f, 749.555542f, 746.444458f, 724.888916f, 704.444458f, 702.333313f, 678.555542f, 618.555542f, 582.666687f, 554.333313f, 570.888916f, 563.f, 571.777771f, 554.333313f, 549.333313f, 541.888916f, 546. [...]
+0.f, 551.111084f, 543.555542f, 543.f, 557.111084f, 593.f, 642.333313f, 690.666687f, 697.333313f, 661.444458f, 618.444458f, 615.888916f, 640.555542f, 648.666687f, 640.555542f, 647.444458f, 671.444458f, 680.777771f, 667.222229f, 649.888916f, 635.555542f, 657.555542f, 663.888916f, 690.f, 714.111084f, 778.111084f, 777.888916f, 739.f, 678.222229f, 648.111084f, 624.444458f, 578.777771f, 565.444458f, 546.555542f, 557.222229f, 551.888916f, 557.666687f, 540.666687f, 542.f, 531.555542f, 545.555542 [...]
+0.f, 547.666687f, 551.111084f, 552.666687f, 563.f, 582.888916f, 621.444458f, 641.111084f, 640.f, 630.555542f, 623.111084f, 638.444458f, 667.f, 670.555542f, 664.777771f, 661.888916f, 716.666687f, 745.888916f, 733.f, 680.444458f, 641.444458f, 638.444458f, 631.333313f, 646.111084f, 688.666687f, 762.111084f, 774.222229f, 728.888916f, 661.222229f, 625.666687f, 611.333313f, 580.111084f, 573.111084f, 557.222229f, 565.777771f, 560.777771f, 567.666687f, 546.777771f, 537.555542f, 521.222229f, 530. [...]
+0.f, 547.333313f, 559.555542f, 560.222229f, 572.333313f, 577.444458f, 593.888916f, 593.777771f, 586.222229f, 596.888916f, 614.222229f, 637.555542f, 670.f, 668.f, 679.222229f, 698.888916f, 836.666687f, 911.333313f, 906.666687f, 781.222229f, 695.444458f, 653.666687f, 641.888916f, 644.f, 660.888916f, 696.f, 700.777771f, 685.777771f, 644.777771f, 617.111084f, 609.444458f, 590.555542f, 577.888916f, 564.666687f, 558.666687f, 556.666687f, 544.f, 540.222229f, 531.555542f, 522.777771f, 528.111084 [...]
+0.f, 554.f, 563.444458f, 563.444458f, 572.222229f, 576.111084f, 586.f, 586.111084f, 583.f, 604.222229f, 632.333313f, 669.444458f, 688.222229f, 674.777771f, 674.888916f, 770.888916f, 994.666687f, 1143.444458f, 1103.777832f, 900.444458f, 734.222229f, 652.222229f, 626.111084f, 617.f, 622.555542f, 635.333313f, 639.444458f, 626.666687f, 607.555542f, 599.777771f, 602.666687f, 604.111084f, 587.777771f, 575.111084f, 562.222229f, 551.555542f, 542.333313f, 535.222229f, 528.222229f, 520.222229f, 51 [...]
+0.f, 548.333313f, 568.f, 574.111084f, 588.555542f, 586.666687f, 586.777771f, 577.555542f, 579.666687f, 610.666687f, 662.222229f, 733.444458f, 766.333313f, 767.222229f, 746.333313f, 849.777771f, 1063.333374f, 1238.333374f, 1193.111084f, 970.888916f, 760.555542f, 656.888916f, 623.888916f, 610.111084f, 595.777771f, 590.555542f, 583.444458f, 583.777771f, 588.111084f, 592.777771f, 596.444458f, 595.555542f, 577.555542f, 565.888916f, 547.111084f, 537.333313f, 523.555542f, 521.222229f, 520.66668 [...]
+0.f, 554.777771f, 563.333313f, 566.111084f, 576.f, 585.777771f, 581.777771f, 583.444458f, 590.222229f, 641.777771f, 725.555542f, 862.111084f, 943.222229f, 935.111084f, 854.666687f, 873.333313f, 999.222229f, 1131.888916f, 1088.555542f, 912.888916f, 728.555542f, 639.777771f, 611.888916f, 588.333313f, 574.555542f, 570.222229f, 575.222229f, 574.f, 582.777771f, 593.f, 600.888916f, 607.777771f, 593.777771f, 577.222229f, 551.888916f, 532.444458f, 526.111084f, 520.777771f, 525.222229f, 522.66668 [...]
+0.f, 555.555542f, 564.222229f, 574.555542f, 571.111084f, 574.555542f, 570.777771f, 584.777771f, 594.666687f, 638.666687f, 739.777771f, 902.111084f, 1027.888916f, 1034.666626f, 933.222229f, 847.777771f, 847.888916f, 908.333313f, 897.888916f, 795.888916f, 679.888916f, 623.111084f, 622.111084f, 603.f, 586.888916f, 566.f, 558.222229f, 564.888916f, 581.f, 591.555542f, 593.111084f, 588.555542f, 581.444458f, 566.888916f, 552.333313f, 539.111084f, 532.f, 533.444458f, 526.555542f, 524.777771f, 52 [...]
+0.f, 561.222229f, 563.111084f, 566.444458f, 560.333313f, 562.888916f, 565.555542f, 587.888916f, 604.f, 642.f, 723.888916f, 856.888916f, 965.888916f, 966.444458f, 873.555542f, 769.f, 723.444458f, 733.f, 720.f, 677.444458f, 623.777771f, 601.666687f, 609.222229f, 605.333313f, 591.222229f, 565.444458f, 547.333313f, 549.888916f, 569.f, 579.666687f, 580.f, 567.777771f, 564.888916f, 558.333313f, 555.777771f, 550.333313f, 540.111084f, 540.777771f, 531.666687f, 532.444458f, 529.f, 531.444458f, 53 [...]
+0.f, 543.222229f, 553.222229f, 562.555542f, 559.222229f, 561.222229f, 569.444458f, 593.111084f, 603.666687f, 619.666687f, 672.555542f, 743.555542f, 800.111084f, 811.111084f, 764.f, 714.222229f, 656.222229f, 660.f, 645.333313f, 632.222229f, 590.111084f, 583.222229f, 591.222229f, 602.666687f, 590.777771f, 568.555542f, 551.333313f, 553.222229f, 562.555542f, 561.f, 556.777771f, 534.666687f, 536.666687f, 532.444458f, 545.666687f, 547.222229f, 542.666687f, 550.f, 553.888916f, 556.111084f, 546. [...]
+0.f, 547.888916f, 549.f, 550.222229f, 557.444458f, 556.555542f, 566.222229f, 575.666687f, 593.777771f, 608.444458f, 634.222229f, 648.111084f, 663.777771f, 682.111084f, 675.111084f, 659.111084f, 623.444458f, 622.777771f, 603.111084f, 600.111084f, 574.888916f, 577.333313f, 573.777771f, 586.222229f, 589.555542f, 574.555542f, 562.888916f, 551.666687f, 556.444458f, 549.555542f, 544.222229f, 526.888916f, 525.888916f, 528.555542f, 538.777771f, 540.222229f, 542.f, 543.555542f, 562.333313f, 555.3 [...]
+0.f, 550.555542f, 548.777771f, 558.111084f, 566.666687f, 574.f, 580.f, 586.888916f, 591.333313f, 588.222229f, 602.222229f, 600.444458f, 603.f, 618.f, 626.f, 627.666687f, 612.333313f, 608.444458f, 606.f, 588.444458f, 570.555542f, 564.777771f, 567.111084f, 576.222229f, 584.333313f, 577.f, 573.555542f, 560.f, 558.333313f, 548.666687f, 533.333313f, 526.888916f, 527.777771f, 531.666687f, 532.f, 526.888916f, 535.222229f, 542.666687f, 561.111084f, 554.333313f, 548.111084f, 545.222229f, 545.8889 [...]
+0.f, 580.222229f, 597.222229f, 630.222229f, 645.777771f, 629.222229f, 601.222229f, 583.666687f, 584.f, 580.222229f, 584.444458f, 580.888916f, 576.222229f, 585.111084f, 596.333313f, 598.333313f, 588.888916f, 575.111084f, 580.555542f, 579.888916f, 585.111084f, 578.888916f, 569.555542f, 560.444458f, 567.555542f, 567.222229f, 565.444458f, 548.444458f, 542.777771f, 541.333313f, 527.f, 528.111084f, 527.444458f, 528.444458f, 521.777771f, 518.777771f, 537.666687f, 549.111084f, 546.222229f, 533.2 [...]
+0.f, 634.444458f, 726.222229f, 817.666687f, 825.333313f, 753.444458f, 665.444458f, 616.333313f, 598.888916f, 582.111084f, 589.666687f, 593.777771f, 596.777771f, 586.666687f, 575.555542f, 572.222229f, 571.777771f, 567.f, 574.222229f, 575.f, 583.666687f, 572.111084f, 557.555542f, 545.666687f, 541.444458f, 543.f, 549.555542f, 544.111084f, 542.222229f, 532.555542f, 522.111084f, 517.111084f, 519.888916f, 514.888916f, 512.f, 509.444458f, 518.888916f, 534.888916f, 527.f, 524.333313f, 517.222229 [...]
+0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0. [...]
diff --git a/test/simpleanalysis/CMakeLists.txt b/test/simpleanalysis/CMakeLists.txt
new file mode 100644
index 0000000..7b19045
--- /dev/null
+++ b/test/simpleanalysis/CMakeLists.txt
@@ -0,0 +1,10 @@
+if(FFTW3_FOUND)
+    INCLUDE_DIRECTORIES(${FFTW3_INCLUDE_DIR})
+    ADD_DEFINITIONS(-DHasFFTW3)
+    
+    VIGRA_ADD_TEST(test_simpleanalysis test.cxx LIBRARIES vigraimpex ${FFTW3_LIBRARIES})
+else()
+    VIGRA_ADD_TEST(test_simpleanalysis test.cxx LIBRARIES vigraimpex)
+endif()
+
+VIGRA_COPY_TEST_DATA(noiseNormalizationTest.xv slantedEdgeMTF.xv lenna128.xv)
diff --git a/test/simpleanalysis/lenna128.xv b/test/simpleanalysis/lenna128.xv
new file mode 100644
index 0000000..11782b2
Binary files /dev/null and b/test/simpleanalysis/lenna128.xv differ
diff --git a/test/simpleanalysis/noiseNormalizationTest.xv b/test/simpleanalysis/noiseNormalizationTest.xv
new file mode 100644
index 0000000..56236e5
Binary files /dev/null and b/test/simpleanalysis/noiseNormalizationTest.xv differ
diff --git a/test/simpleanalysis/slantedEdgeMTF.xv b/test/simpleanalysis/slantedEdgeMTF.xv
new file mode 100644
index 0000000..7465b02
Binary files /dev/null and b/test/simpleanalysis/slantedEdgeMTF.xv differ
diff --git a/test/simpleanalysis/test.cxx b/test/simpleanalysis/test.cxx
new file mode 100755
index 0000000..454df4d
--- /dev/null
+++ b/test/simpleanalysis/test.cxx
@@ -0,0 +1,2487 @@
+/************************************************************************/
+/*                                                                      */
+/*              Copyright 2004-2010 by Ullrich Koethe                   */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <fstream>
+#include <functional>
+#include <cmath>
+#include "vigra/unittest.hxx"
+#include "vigra/stdimage.hxx"
+#include "vigra/labelimage.hxx"
+#include "vigra/edgedetection.hxx"
+#include "vigra/distancetransform.hxx"
+#include "vigra/localminmax.hxx"
+#include "vigra/multi_localminmax.hxx"
+#include "vigra/seededregiongrowing.hxx"
+#include "vigra/cornerdetection.hxx"
+#include "vigra/symmetry.hxx"
+#include "vigra/watersheds.hxx"
+#include "vigra/multi_watersheds.hxx"
+#include "vigra/noise_normalization.hxx"
+#include "vigra/affinegeometry.hxx"
+#include "vigra/affine_registration.hxx"
+#include "vigra/impex.hxx"
+
+#ifdef HasFFTW3
+# include "vigra/slanted_edge_mtf.hxx"
+#endif
+
+using namespace vigra;
+
+struct LabelingTest
+{
+    typedef vigra::DImage Image;
+    typedef vigra::MultiArrayView<2, double> View;
+
+    LabelingTest()
+    : img1(5,5), img2(5,5), img3(9,5), img4(11,11)
+    {
+        static const double in1[] = { 0.0, 0.0, 0.0, 0.0, 0.0,
+                                      0.0, 1.0, 1.0, 1.0, 0.0,
+                                      0.0, 1.0, 1.0, 1.0, 0.0,
+                                      0.0, 1.0, 1.0, 1.0, 0.0,
+                                      0.0, 0.0, 0.0, 0.0, 0.0};
+
+        Image::ScanOrderIterator i = img1.begin();
+        Image::ScanOrderIterator end = img1.end();
+        Image::Accessor acc = img1.accessor();
+        const double * p = in1;
+
+        for(; i != end; ++i, ++p)
+        {
+            acc.set(*p, i);
+        }
+
+        static const double in2[] = { 0.0, 1.0, 0.0, 1.0, 0.0,
+                                      1.0, 0.0, 1.0, 0.0, 1.0,
+                                      0.0, 1.0, 0.0, 1.0, 0.0,
+                                      1.0, 0.0, 1.0, 0.0, 1.0,
+                                      0.0, 1.0, 0.0, 1.0, 0.0};
+
+        i = img2.begin();
+        end = img2.end();
+        p = in2;
+
+        for(; i != end; ++i, ++p)
+        {
+            acc.set(*p, i);
+        }
+
+        static const int in3[] = {
+            0, 1, 0, 1, 0, 1, 0, 1, 0,
+            0, 1, 0, 1, 0, 1, 0, 0, 0,
+            0, 1, 0, 1, 0, 0, 0, 1, 0,
+            0, 1, 0, 0, 0, 1, 1, 1, 0,
+            0, 0, 0, 1, 1, 1, 0, 0, 0
+        };
+
+        i = img3.begin();
+        end = img3.end();
+        const int * p1 = in3;
+
+        for(; i != end; ++i, ++p1)
+        {
+            acc.set(*p1, i);
+        }
+
+        static const int spiral[] = {
+            1,1,1,1,1,1,1,1,1,1,1,
+            1,2,2,2,2,2,2,2,2,2,1,
+            1,2,1,1,1,1,1,1,1,2,1,
+            1,2,1,2,2,2,2,2,1,2,1,
+            1,2,1,2,1,1,1,2,1,2,1,
+            1,2,1,2,1,2,1,2,1,2,1,
+            1,2,1,2,1,2,2,2,1,2,1,
+            1,2,1,2,1,1,1,1,1,2,1,
+            1,2,1,2,2,2,2,2,2,2,1,
+            1,2,1,1,1,1,1,1,1,1,1,
+            1,2,2,2,2,2,2,2,2,2,2
+        };
+
+        i = img4.begin();
+        end = img4.end();
+        p1 = spiral;
+
+        for(; i != end; ++i, ++p1)
+        {
+            acc.set(*p1, i);
+        }
+    }
+
+    void labelingFourTest1()
+    {
+        Image res(img1);
+        int count = labelImage(srcImageRange(img1), destImage(res), false);
+        
+        should(2 == count);
+
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::ScanOrderIterator i1end = img1.end();
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = img1.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(acc(i1) == acc(i2) - 1.0);
+        }
+    }
+
+    void labelingFourTest2()
+    {
+        Image res(img3);
+        int count = labelImage(srcImageRange(img3), destImage(res), false);
+
+        should(6 == count);
+
+        static const int target[] = {
+            1, 2, 1, 3, 1, 4, 1, 5, 1,
+            1, 2, 1, 3, 1, 4, 1, 1, 1,
+            1, 2, 1, 3, 1, 1, 1, 6, 1,
+            1, 2, 1, 1, 1, 6, 6, 6, 1,
+            1, 1, 1, 6, 6, 6, 1, 1, 1
+        };
+
+        Image::ScanOrderIterator i = res.begin();
+        Image::ScanOrderIterator iend = res.end();
+        const int * p = target;
+        Image::Accessor acc = res.accessor();
+
+        for(; i != iend; ++i, ++p)
+        {
+            should(acc(i) == *p);
+        }
+    }
+
+    void labelingFourTest3()
+    {
+        Image res(img4.size());
+
+        should(2 == labelImage(srcImageRange(img4), destImage(res), false));
+
+        Image::ScanOrderIterator i = res.begin();
+        Image::ScanOrderIterator iend = res.end();
+        Image::ScanOrderIterator id = img4.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(; i != iend; ++i, ++id)
+        {
+            should(acc(i) == acc(id));
+        }
+    }
+
+    void labelingFourTest4()
+    {
+        static const int data[] = {
+            1,1,1,1,1,1,1,1,1,2,
+            2,1,1,1,1,1,1,2,1,2,
+            2,1,1,1,1,2,1,2,1,2,
+            2,1,1,2,1,2,1,2,1,2,
+            2,1,2,2,2,2,2,2,2,2,
+            2,2,2,3,3,3,3,3,3,3
+
+        };
+
+        int w=10;
+        int h=6;
+        Image img(w,h), res(w,h);
+
+        std::copy(data, data+w*h, img.begin());
+
+        should(3 == labelImage(srcImageRange(img), destImage(res), false));
+
+        Image::ScanOrderIterator i = res.begin();
+        Image::ScanOrderIterator iend = res.end();
+        Image::ScanOrderIterator id = img.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(int c=0; i != iend; ++i, ++id, ++c)
+        {
+            should(acc(i) == acc(id));
+        }
+    }
+
+    void labelingToEdgeTest()
+    {
+        Image tmp(img1);
+        Image res(9, 9), res2(img1.size());
+
+        should(2 == labelImage(View(img1), View(tmp), false));
+
+        regionImageToCrackEdgeImage(View(tmp), View(res), 0.0);
+
+        static const double desired[] = {
+               1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+               1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+               1.0, 0.0, 2.0, 2.0, 2.0, 2.0, 2.0, 0.0, 1.0,
+               1.0, 0.0, 2.0, 2.0, 2.0, 2.0, 2.0, 0.0, 1.0,
+               1.0, 0.0, 2.0, 2.0, 2.0, 2.0, 2.0, 0.0, 1.0,
+               1.0, 0.0, 2.0, 2.0, 2.0, 2.0, 2.0, 0.0, 1.0,
+               1.0, 0.0, 2.0, 2.0, 2.0, 2.0, 2.0, 0.0, 1.0,
+               1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+               1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
+
+        const double * i1 = desired;
+        const double * i1end = i1 + 81;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = img1.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+
+        regionImageToEdgeImage(View(tmp), View(res2), 1.0);
+
+        static const double edges[] = {
+            0, 1, 1, 1, 0, 
+            1, 0, 0, 1, 0, 
+            1, 0, 0, 1, 0, 
+            1, 1, 1, 1, 0, 
+            0, 0, 0, 0, 0};
+
+        shouldEqualSequence(res2.begin(), res2.end(), edges);
+    }
+
+    void labelingEightTest1()
+    {
+        Image res(img2);
+
+        should(2 == labelImage(srcImageRange(img2), destImage(res), true));
+
+        Image::ScanOrderIterator i1 = img2.begin();
+        Image::ScanOrderIterator i1end = img2.end();
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = img2.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(acc(i1) == acc(i2) - 1.0);
+        }
+    }
+
+    void labelingEightTest2()
+    {
+        static const int data[] = {
+            1,1,1,1,1,1,1,1,1,1,
+            1,1,1,2,3,3,2,1,1,1,
+            1,1,2,3,3,2,4,2,1,1,
+            1,2,3,3,2,4,4,4,2,1,
+            1,2,3,2,4,4,2,3,2,1,
+            1,2,3,3,2,2,3,3,2,1,
+            1,1,2,3,3,3,3,2,1,1,
+            1,1,1,2,2,2,2,1,1,1,
+            1,1,1,1,1,1,1,1,1,1
+        };
+
+        Image img(10,9), res(10,9);
+
+        std::copy(data, data+90, img.begin());
+
+        should(4 == labelImage(srcImageRange(img), destImage(res), true));
+
+        Image::ScanOrderIterator i = res.begin();
+        Image::ScanOrderIterator iend = res.end();
+        Image::Accessor acc = res.accessor();
+        const int * p = data;
+
+        for(; i != iend; ++i, ++p)
+        {
+            should(acc(i) == *p);
+        }
+    }
+
+    void labelingFourWithBackgroundTest1()
+    {
+        Image res(img1);
+        res = 0.0;
+
+        should(1 == labelImageWithBackground(srcImageRange(img1),
+                                             destImage(res),
+                                             false, 0.0));
+
+        Image::ScanOrderIterator i1 = img1.begin();
+        Image::ScanOrderIterator i1end = img1.end();
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = img1.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(acc(i1) == acc(i2));
+        }
+    }
+
+    void labelingFourWithBackgroundTest2()
+    {
+        Image res(img4);
+
+        should(1 == labelImageWithBackground(srcImageRange(img4),
+                                            destImage(res),
+                                            false, 2.0));
+
+        Image::ScanOrderIterator i = res.begin();
+        Image::ScanOrderIterator iend = res.end();
+        Image::ScanOrderIterator id = img4.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(; i != iend; ++i, ++id)
+        {
+            should(acc(i) == acc(id));
+        }
+    }
+
+    void labelingEightWithBackgroundTest()
+    {
+        Image res(img2), res2(img2);
+
+        should(1 == labelImageWithBackground(srcImageRange(img2),
+                                             destImage(res),
+                                             true, 0.0));
+
+        Image::ScanOrderIterator i1 = img2.begin();
+        Image::ScanOrderIterator i1end = img2.end();
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = img2.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(acc(i1) == acc(i2));
+        }
+
+        should(1 == labelImageWithBackground(View(img2), View(res2),
+                                             true, 0.0));
+        should(View(res) == View(res2));
+    }
+
+    Image img1, img2, img3, img4;
+};
+
+struct EdgeDetectionTest
+{
+    typedef vigra::DImage Image;
+    typedef vigra::MultiArrayView<2, double> View;
+
+    EdgeDetectionTest()
+    : img1(5,5), img2(9,11), imgCanny(40, 40)
+    {
+        static const double in1[] = { 0.0, 0.0, 0.0, 0.0, 0.0,
+                                      0.0, 1.0, 1.0, 1.0, 0.0,
+                                      0.0, 1.0, 1.0, 1.0, 0.0,
+                                      0.0, 1.0, 1.0, 1.0, 0.0,
+                                      0.0, 0.0, 0.0, 0.0, 0.0};
+
+        Image::ScanOrderIterator i = img1.begin();
+        Image::ScanOrderIterator end = img1.end();
+        Image::Accessor acc = img1.accessor();
+        const double * p = in1;
+
+        for(; i != end; ++i, ++p)
+        {
+            acc.set(*p, i);
+        }
+
+        static const double in2[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        i = img2.begin();
+        end = img2.end();
+        p = in2;
+
+        for(; i != end; ++i, ++p)
+        {
+            acc.set(*p, i);
+        }
+
+        for(int y=0; y<40; ++y)
+        {
+            for(int x=0; x<40; ++x)
+            {
+                if(x==y)
+                    imgCanny(x,y) = 0.0;
+                else if(x > y)
+                    imgCanny(x,y) = 2.0;
+                else
+                    imgCanny(x,y) = -2.0;
+            }
+        }
+    }
+
+    void edgeDetectionTest()
+    {
+        Image res(img1);
+        res = 0.0;
+
+        differenceOfExponentialEdgeImage(View(img1), View(res),
+                                         0.7, 0.1, 1.0);
+
+        static const double desired[] = {0.0, 1.0, 1.0, 1.0, 0.0,
+                                         1.0, 0.0, 0.0, 0.0, 1.0,
+                                         1.0, 0.0, 0.0, 0.0, 1.0,
+                                         1.0, 0.0, 0.0, 0.0, 1.0,
+                                         0.0, 1.0, 1.0, 1.0, 0.0};
+
+        const double * i1 = desired;
+        const double * i1end = i1 + 25;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+    }
+
+    void edgeToCrackEdgeTest()
+    {
+        img1.upperLeft()[vigra::Diff2D(2,2)] = 0.0;
+
+        Image res(9,9);
+        res = 0.0;
+
+        differenceOfExponentialCrackEdgeImage(View(img1), View(res),
+                                              0.7, 0.1, 1.0);
+
+        static const double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        const double * i1 = desired;
+        const double * i1end = i1 + 81;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+    }
+
+    void removeShortEdgesTest()
+    {
+        img1.upperLeft()[vigra::Diff2D(2,2)] = 0.0;
+
+        Image res(9,9);
+        res = 0.0;
+
+        differenceOfExponentialCrackEdgeImage(View(img1), View(res),
+                                              0.7, 0.1, 1.0);
+        removeShortEdges(View(res), 9, 0.0);
+
+        static const double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        const double * i1 = desired;
+        const double * i1end = i1 + 81;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+    }
+
+    void beautifyCrackEdgeTest()
+    {
+        img1.upperLeft()[vigra::Diff2D(2,2)] = 0.0;
+
+        Image res(9,9);
+        res = 0.0;
+
+        differenceOfExponentialCrackEdgeImage(View(img1), View(res),
+                                              0.7, 0.1, 1.0);
+        beautifyCrackEdgeImage(View(res), 1.0, 0.0);
+
+        static const double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        const double * i1 = desired;
+        const double * i1end = i1 + 81;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+    }
+
+    void closeGapsInCrackEdgeTest()
+    {
+        closeGapsInCrackEdgeImage(View(img2), 1.0);
+
+        static const double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        const double * i1 = desired;
+        const double * i1end = i1 + 99;
+        Image::ScanOrderIterator i2 = img2.begin();
+        Image::Accessor acc = img2.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+    }
+
+    void cannyEdgelListTest()
+    {
+        {
+            std::vector<vigra::Edgel> edgels;
+            cannyEdgelList(View(imgCanny), edgels, 1.0);
+            int count = 0;
+            for(unsigned int i=0; i<edgels.size(); ++i)
+            {
+                if (edgels[i].strength < 1.0e-10)
+                    continue;  // ignore edgels that result from round off error during convolution
+                ++count;
+                should(edgels[i].x == edgels[i].y);
+                should(VIGRA_CSTD::fabs(edgels[i].orientation-M_PI*0.25) < 0.1);
+            }
+            should(count == 75);
+
+            std::vector<vigra::Edgel> edgelsThresh;
+            double threshold = 1.25;
+            cannyEdgelListThreshold(View(imgCanny), edgelsThresh, 1.0, threshold);
+            count = 0;
+            for(unsigned int i=0; i<edgels.size(); ++i)
+            {
+                if (edgels[i].strength <= threshold)
+                    continue;  // ignore edgels below threshold
+                should(edgels[i].x == edgelsThresh[count].x);
+                should(edgels[i].y == edgelsThresh[count].y);
+                ++count;
+            }
+            should(count == 38);
+        }
+        {
+            std::vector<vigra::Edgel> edgels;
+            MultiArray<2, TinyVector<double, 2> > grad(imgCanny.width(), imgCanny.height());
+            gaussianGradient(View(imgCanny), grad, 1.0);
+
+            cannyEdgelList(grad, edgels);
+            int count = 0;
+            for(unsigned int i=0; i<edgels.size(); ++i)
+            {
+                if (edgels[i].strength < 1.0e-10)
+                    continue;  // ignore edgels that result from round off error during convolution
+                ++count;
+                should(edgels[i].x == edgels[i].y);
+                should(VIGRA_CSTD::fabs(edgels[i].orientation-M_PI*0.25) < 0.1);
+            }
+            should(count == 75);
+        }
+    }
+
+    void cannyEdgelList3x3Test()
+    {
+        std::vector<vigra::Edgel> edgels;
+        cannyEdgelList3x3(View(imgCanny), edgels, 1.0);
+        int count = 0;
+        for(unsigned int i=0; i<edgels.size(); ++i)
+        {
+            if (edgels[i].strength < 1.0e-10)
+                continue;  // ignore edgels that result from round off error during convolution
+            ++count;
+            should(edgels[i].x == edgels[i].y);
+            should(VIGRA_CSTD::fabs(edgels[i].orientation-M_PI*0.25) < 0.1);
+        }
+        should(count == 38);
+
+        std::vector<vigra::Edgel> edgelsThresh;
+        double threshold = 1.3;
+        cannyEdgelList3x3Threshold(View(imgCanny), edgelsThresh, 1.0, threshold);
+        count = 0;
+        for(unsigned int i=0; i<edgels.size(); ++i)
+        {
+            if (edgels[i].strength <= threshold)
+                continue;  // ignore edgels below threshold
+            should(edgels[i].x == edgelsThresh[count].x);
+            should(edgels[i].y == edgelsThresh[count].y);
+            ++count;
+        }
+        should(count == 36);
+    }
+
+    void cannyEdgeImageTest()
+    {
+        vigra::BImage result(40, 40);
+        result = 0;
+
+        cannyEdgeImage(View(imgCanny), MultiArrayView<2, unsigned char>(result), 1.0, 0.1, 1);
+
+        for(int y=1; y<39; ++y)
+        {
+            for(int x=1; x<39; ++x)
+            {
+                if(x == y)
+                    should(result(x,y) == 1);
+                else
+                    should(result(x,y) == 0);
+            }
+        }
+    }
+
+    void cannyEdgeImageWithThinningTest()
+    {
+        vigra::BImage result(40, 40);
+        result = 0;
+
+        cannyEdgeImageWithThinning(View(imgCanny), MultiArrayView<2, unsigned char>(result), 1.0, 0.1, 1, false);
+
+        for(int y=1; y<39; ++y)
+        {
+            for(int x=1; x<39; ++x)
+            {
+                if(x == y)
+                    should(result(x,y) == 1);
+                else
+                    should(result(x,y) == 0);
+            }
+        }
+    }
+
+    Image img1, img2, imgCanny;
+};
+
+struct DistanceTransformTest
+{
+    typedef vigra::DImage Image;
+    typedef vigra::MultiArrayView<2, double> View;
+
+    DistanceTransformTest()
+    : img(7,7)
+    {
+        static const double in[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator end = img.end();
+        Image::Accessor acc = img.accessor();
+        const double * p = in;
+
+        for(; i != end; ++i, ++p)
+        {
+            acc.set(*p, i);
+        }
+    }
+
+    void distanceTransformL1Test()
+    {
+        Image res(img);
+        Image res1(img);
+
+        distanceTransform(srcImageRange(img), destImage(res), 0.0, 1);
+
+        Image::Iterator i = res.upperLeft();
+        Image::Accessor acc = res.accessor();
+        int x,y;
+
+        for(y=0; y<7; ++y)
+        {
+            for(x=0; x<7; ++x)
+            {
+                double dist = acc(i, vigra::Diff2D(x,y));
+                double dist1 = std::abs(2.0 - x) + std::abs(2.0 - y);
+                double dist2 = std::abs(5.0 - x) + std::abs(5.0 - y);
+                double desired = (dist1 < dist2) ? dist1 : dist2;
+
+                shouldEqualTolerance(dist, desired, 1e-14);
+            }
+        }
+
+        distanceTransform(View(img), View(res1), 0.0, 1);
+        should(View(res) == View(res1));
+    }
+
+    void distanceTransformL2Test()
+    {
+
+        Image res(img);
+
+        distanceTransform(View(img), View(res), 0.0, 2);
+
+        Image::Iterator i = res.upperLeft();
+        Image::Accessor acc = res.accessor();
+        int x,y;
+
+        for(y=0; y<7; ++y)
+        {
+            for(x=0; x<7; ++x)
+            {
+                double dist = acc(i, vigra::Diff2D(x,y));
+                double dist1 = VIGRA_CSTD::sqrt((2.0 - x)*(2.0 - x) +
+                                         (2.0 - y)*(2.0 - y));
+                double dist2 = VIGRA_CSTD::sqrt((5.0 - x)*(5.0 - x) +
+                                         (5.0 - y)*(5.0 - y));
+                double desired = (dist1 < dist2) ? dist1 : dist2;
+
+                shouldEqualTolerance(dist, desired, 1e-7);
+            }
+        }
+    }
+
+    void distanceTransformLInfTest()
+    {
+
+        Image res(img);
+
+        distanceTransform(View(img), View(res), 0.0, 0);
+
+        Image::Iterator i = res.upperLeft();
+        Image::Accessor acc = res.accessor();
+        int x,y;
+
+        for(y=0; y<7; ++y)
+        {
+            for(x=0; x<7; ++x)
+            {
+                double dist = acc(i, vigra::Diff2D(x,y));
+                double dist1 = std::abs(2.0 - x) < std::abs(2.0 - y) ?
+                                      std::abs(2.0 - y) : std::abs(2.0 - x);
+                double dist2 = std::abs(5.0 - x) < std::abs(5.0 - y) ?
+                                      std::abs(5.0 - y) : std::abs(5.0 - x);
+                double desired = (dist1 < dist2) ? dist1 : dist2;
+
+                shouldEqualTolerance(dist, desired, 1e-14);
+            }
+        }
+    }
+
+
+    Image img;
+};
+
+template <class T>
+struct EqualWithToleranceFunctor
+{
+    EqualWithToleranceFunctor(T tolerance = 2.0 * NumericTraits<T>::epsilon())
+    : t(tolerance)
+    {}
+    
+    bool operator()(T l, T r) const
+    {
+        return abs(l-r) <= t;
+    }
+    
+    T t;
+};
+
+struct LocalMinMaxTest
+{
+    typedef vigra::MultiArray<2, double> Image;
+    typedef vigra::MultiArray<3, double> Volume;
+    typedef MultiArrayShape<3>::type Shp3D;
+
+    LocalMinMaxTest()
+    : img(Shape2(9,9)), vol()
+    {
+        static const double in[] = {
+            0.2,  0.1,  0.1,  0.3,  0.5,  0.3,  0.0,  0.0, -0.1,
+            0.0, -0.1,  0.1,  0.0,  1.0,  0.0,  0.3,  0.0,  0.0,
+            0.0,  0.5,  2.0,  0.0,  2.0,  2.0,  2.0,  0.0, -1.1,
+            0.1,  0.0,  1.0,  1.5,  1.0,  1.0,  0.0,  0.0,  0.0,
+            0.0,  0.1,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,
+            0.0,  0.0,  0.0,  0.0, -1.0, -1.5, -1.0,  0.0, -0.3,
+            0.0,  0.0, -2.0, -2.0, -2.0,  0.0, -2.0, -0.5,  0.0,
+            1.0,  0.0,  0.0,  0.0, -1.0,  0.0, -0.1,  0.1,  0.0,
+            0.0,  0.0,  0.0,  0.0, -0.5, -0.3, -0.1, -0.1,  0.0};
+
+        Image::iterator i = img.begin();
+        Image::iterator end = img.end();
+        const double * p = in;
+
+        for(; i != end; ++i, ++p)
+        {
+            *i = *p;
+        }
+
+        //prepare the multiarray
+        vol.reshape(Shp3D(10,20,50),0);
+
+        vol(1,1,1)=10;
+        vol(5,5,5)=350;
+
+        vol(8,3,5)=9; //plateaux
+        vol(8,4,5)=9;
+        vol(8,5,5)=9;
+
+        vol(6,7,7)=-0.5;
+        vol(7,7,7)=-1;
+        vol(7,1,15)=-100;
+        vol(7,1,19)=-20;
+
+        vol(3,15,26)=-1; //plateaux
+        vol(3,15,27)=-1;
+        vol(3,15,28)=-1;
+        vol(3,16,26)=-1;
+
+        vol(9,18,35)=-100; //on the border is skipped
+        vol(0,1,49)=100; //on the border is skipped
+
+    }
+
+
+    void localMinimum3DTest()
+    {
+        Volume res(vol.shape()), res2(vol.shape());
+
+        localMinima3D(srcMultiArrayRange(vol), destMultiArray(res), 1, NeighborCode3DSix());
+
+        Volume desired(vol);
+        desired.init(0);
+
+        desired(7,7,7)=1;
+        desired(7,1,15)=1;
+        desired(7,1,19)=1;
+
+
+        for(int z=0; z<vol.shape(2); ++z)
+            for(int y=0; y<vol.shape(1); ++y)
+                for(int x=0; x<vol.shape(0); ++x)
+                    shouldEqual(res(x,y,z), desired(x,y,z));
+
+        should(3 == localMinima(vol, res2, LocalMinmaxOptions().neighborhood(0).markWith(1)));
+        should(res == res2);
+
+        res2 = 0;
+        localMinima3D(vol, res2, 1, NeighborCode3DSix());
+        should(res == res2);
+    }
+
+    void extendedLocalMinimum3DTest()
+    {
+        Volume res(vol.shape()), res2(vol.shape());
+
+        extendedLocalMinima3D(srcMultiArrayRange(vol), destMultiArray(res),1,NeighborCode3DSix());
+
+        Volume desired(vol);
+        desired.init(0);
+
+        desired(7,7,7)=1;
+        desired(7,1,15)=1;
+        desired(7,1,19)=1;
+
+        desired(3,15,26)=1; //plateau
+        desired(3,15,27)=1;
+        desired(3,15,28)=1;
+        desired(3,16,26)=1;
+
+        for(int z=0; z<vol.shape(2); ++z)
+            for(int y=0; y<vol.shape(1); ++y)
+                for(int x=0; x<vol.shape(0); ++x)
+                    shouldEqual(res(x,y,z), desired(x,y,z));
+
+        should(4 == localMinima(vol, res2, LocalMinmaxOptions().neighborhood(0).markWith(1).allowPlateaus()));
+        should(res == res2);
+    }
+    
+    void extendedLocalMinimum3DTest2()
+    {
+        Volume res(vol.shape()), res2(vol.shape());
+
+        extendedLocalMinima3D(srcMultiArrayRange(vol), destMultiArray(res),1,NeighborCode3DTwentySix());
+
+        Volume desired(vol);
+        desired.init(0);
+
+        desired(7,7,7)=1;
+        desired(7,1,15)=1;
+        desired(7,1,19)=1;
+
+        desired(3,15,26)=1; //plateaux
+        desired(3,15,27)=1;
+        desired(3,15,28)=1;
+        desired(3,16,26)=1;
+
+        for(int z=0; z<vol.shape(2); ++z)
+            for(int y=0; y<vol.shape(1); ++y)
+                for(int x=0; x<vol.shape(0); ++x)
+                    shouldEqual(res(x,y,z), desired(x,y,z));
+
+        should(4 == localMinima(vol, res2, LocalMinmaxOptions().neighborhood(1).markWith(1).allowPlateaus()));
+        should(res == res2);
+    }
+
+    void localMaximum3DTest()
+    {
+        Volume res(vol.shape()), res2(vol.shape());
+
+        localMaxima3D(srcMultiArrayRange(vol), destMultiArray(res), 1, NeighborCode3DSix());
+
+        Volume desired(vol);
+        desired.init(0);
+
+        desired(1,1,1)=1;
+        desired(5,5,5)=1;
+
+        for(int z=0; z<vol.shape(2); ++z)
+            for(int y=0; y<vol.shape(1); ++y)
+                for(int x=0; x<vol.shape(0); ++x)
+                    shouldEqual(res(x,y,z), desired(x,y,z));
+
+        should(2 == localMaxima(vol, res2, LocalMinmaxOptions().neighborhood(0).markWith(1)));
+        should(res == res2);
+
+        res2 = 0;
+        localMaxima3D(vol, res2, 1, NeighborCode3DSix());
+        should(res == res2);
+    }
+
+    void extendedLocalMaximum3DTest()
+    {
+        Volume res(vol.shape()), res2(vol.shape());
+
+        extendedLocalMaxima3D(srcMultiArrayRange(vol), destMultiArray(res),1,NeighborCode3DSix());
+
+        Volume desired(vol);
+        desired.init(0);
+
+        desired(1,1,1)=1;
+        desired(5,5,5)=1;
+
+        desired(8,3,5)=1;
+        desired(8,4,5)=1;
+        desired(8,5,5)=1;
+
+        for(int z=0; z<vol.shape(2); ++z)
+            for(int y=0; y<vol.shape(1); ++y)
+                for(int x=0; x<vol.shape(0); ++x)
+                    shouldEqual(res(x,y,z), desired(x,y,z));
+
+        should(3 == localMaxima(vol, res2, LocalMinmaxOptions().neighborhood(0).markWith(1).allowPlateaus()));
+        should(res == res2);
+    }
+    
+    void extendedLocalMaximum3DTest2()
+    {
+        Volume res(vol.shape()), res2(vol.shape());
+
+        extendedLocalMaxima3D(srcMultiArrayRange(vol), destMultiArray(res),1,NeighborCode3DTwentySix());
+
+        Volume desired(vol);
+        desired.init(0);
+
+        desired(1,1,1)=1;
+        desired(5,5,5)=1;
+
+        desired(8,3,5)=1;
+        desired(8,4,5)=1;
+        desired(8,5,5)=1;
+
+        for(int z=0; z<vol.shape(2); ++z)
+            for(int y=0; y<vol.shape(1); ++y)
+                for(int x=0; x<vol.shape(0); ++x)
+                    shouldEqual(res(x,y,z), desired(x,y,z));
+
+        should(3 == localMaxima(vol, res2, LocalMinmaxOptions().neighborhood(1).markWith(1).allowPlateaus()));
+        should(res == res2);
+    }
+
+    void localMinimumTest()
+    {
+        Image res(img.shape()), res2(img.shape());
+
+        localMinima(srcImageRange(img), destImage(res));
+
+        double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        should(2 == localMinima(img, res2));
+        should(res == res2);
+
+        res.init(0);
+        localMinima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().allowAtBorder());
+        desired[8] = 1.0;
+        desired[26] = 1.0;
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res2.init(0);
+        should(4 == localMinima(img, res2, LocalMinmaxOptions().allowAtBorder()));
+        should(res == res2);
+    }
+
+    void localMinimum4Test()
+    {
+        Image res(img.shape()), res2(img.shape());
+
+        localMinima(srcImageRange(img), destImage(res), LocalMinmaxOptions().neighborhood(4));
+
+        double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        should(5 == localMinima(img, res2, LocalMinmaxOptions().neighborhood(4)));
+        should(res == res2);
+
+        res.init(0);
+        localMinima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().neighborhood(0).allowAtBorder());
+        desired[8] = 1.0;
+        desired[26] = 1.0;
+        desired[53] = 1.0;
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res2.init(0);
+        should(8 == localMinima(img, res2, LocalMinmaxOptions().allowAtBorder().neighborhood(4)));
+        should(res == res2);
+    }
+
+    void localMinimumTestThr()
+    {
+        Image res(img.shape()), res2(img.shape());
+
+        localMinima(srcImageRange(img), destImage(res),
+                    LocalMinmaxOptions().neighborhood(8).markWith(1.0).threshold(-1.0));
+
+        double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        should(1 == localMinima(img, res2,
+                                LocalMinmaxOptions().neighborhood(8).markWith(1.0).threshold(-1.0)));
+        should(res == res2);
+
+        res.init(0);
+        localMinima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().neighborhood(8).threshold(-1.0).allowAtBorder());
+        desired[26] = 1.0;
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res2.init(0);
+        should(2 == localMinima(img, res2, 
+                                LocalMinmaxOptions().neighborhood(8).threshold(-1.0).allowAtBorder()));
+        should(res == res2);
+    }
+
+    void localMaximumTest()
+    {
+        Image res(img.shape()), res2(img.shape());
+
+        localMaxima(srcImageRange(img), destImage(res));
+
+        double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        should(2 == localMaxima(img, res2));
+        should(res == res2);
+
+        res.init(0);
+        localMaxima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().allowAtBorder());
+        desired[0] = 1.0;
+        desired[63] = 1.0;
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res2.init(0);
+        should(4 == localMaxima(img, res2, 
+                                LocalMinmaxOptions().allowAtBorder()));
+        should(res == res2);
+    }
+
+    void localMaximum4Test()
+    {
+        Image res(img.shape()), res2(img.shape());
+
+        localMaxima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().neighborhood(4));
+
+        double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        should(4 == localMaxima(img, res2,
+                                LocalMinmaxOptions().neighborhood(4)));
+        should(res == res2);
+
+        res.init(0);
+        localMaxima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().neighborhood(DirectNeighborhood).allowAtBorder());
+        desired[0] = 1.0;
+        desired[27] = 1.0;
+        desired[63] = 1.0;
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res2.init(0);
+        should(7 == localMaxima(img, res2, 
+                                LocalMinmaxOptions().neighborhood(DirectNeighborhood).allowAtBorder()));
+        should(res == res2);
+    }
+
+    void localMaximumTestThr()
+    {
+        Image res(img.shape()), res2(img.shape());
+
+        localMaxima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().markWith(1.0).neighborhood(8).threshold(0.2));
+
+        double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        should(1 == localMaxima(img, res2,
+                                LocalMinmaxOptions().neighborhood(8).markWith(1.0).threshold(0.2)));
+        should(res == res2);
+
+        res.init(0);
+        localMaxima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().allowAtBorder().threshold(0.2));
+        desired[63] = 1.0;
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res2.init(0);
+        should(2 == localMaxima(img, res2, 
+                                LocalMinmaxOptions().neighborhood(IndirectNeighborhood).threshold(0.2).allowAtBorder()));
+        should(res == res2);
+    }
+
+    void extendedLocalMinimumTest()
+    {
+        Image res(img.shape()), res2(img.shape());
+
+        extendedLocalMinima(srcImageRange(img), destImage(res), 1.0);
+
+        double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res.init(0);
+        localMinima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().allowPlateaus());
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        should(4 == localMinima(img, res2, 
+                                LocalMinmaxOptions().allowPlateaus()));
+        should(res == res2);
+
+        res.init(0);
+        localMinima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().allowAtBorder().allowPlateaus());
+        desired[8] = 1.0;
+        desired[26] = 1.0;
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res2.init(0);
+        should(6 == localMinima(img, res2, 
+                                LocalMinmaxOptions().allowAtBorder().allowPlateaus()));
+        should(res == res2);
+    }
+
+    void extendedLocalMinimum4Test()
+    {
+        Image res(img.shape()), res2(img.shape());
+
+        extendedLocalMinima(srcImageRange(img), destImage(res), 1.0, FourNeighborCode());
+
+        double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+ 
+        res.init(0);
+        localMinima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().allowPlateaus().neighborhood(4));
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        should(7 == localMinima(img, res2, 
+                                LocalMinmaxOptions().allowPlateaus().neighborhood(0)));
+        should(res == res2);
+
+        res.init(0);
+        localMinima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().neighborhood(4).allowAtBorder().allowPlateaus());
+        desired[8] = 1.0;
+        desired[26] = 1.0;
+        desired[53] = 1.0;
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res2.init(0);
+        should(10 == localMinima(img, res2, 
+                                LocalMinmaxOptions().allowAtBorder().allowPlateaus().neighborhood(4)));
+        should(res == res2);
+   }
+
+    void extendedLocalMaximumTest()
+    {
+        Image res(img.shape()), res2(img.shape());
+
+        extendedLocalMaxima(srcImageRange(img), destImage(res), 1.0);
+
+        double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+        res.init(0);
+        localMaxima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().allowPlateaus());
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        should(4 == localMaxima(img, res2, 
+                                LocalMinmaxOptions().allowPlateaus()));
+        should(res == res2);
+
+        res.init(0);
+        localMaxima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().allowAtBorder().allowPlateaus());
+        desired[0] = 1.0;
+        desired[63] = 1.0;
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res2.init(0);
+        should(6 == localMaxima(img, res2, 
+                                LocalMinmaxOptions().allowAtBorder().allowPlateaus()));
+        should(res == res2);
+   }
+
+    void extendedLocalMaximum4Test()
+    {
+        Image res(img.shape()), res2(img.shape());
+
+        extendedLocalMaxima(srcImageRange(img), destImage(res), 1.0, FourNeighborCode());
+
+        double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res.init(0);
+        localMaxima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().allowPlateaus().neighborhood(4));
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        should(6 == localMaxima(img, res2, 
+                                LocalMinmaxOptions().allowPlateaus().neighborhood(DirectNeighborhood)));
+        should(res == res2);
+
+        res.init(0);
+        localMaxima(srcImageRange(img), destImage(res), 
+                    LocalMinmaxOptions().neighborhood(4).allowAtBorder().allowPlateaus());
+        desired[0] = 1.0;
+        desired[27] = 1.0;
+        desired[63] = 1.0;
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        res2.init(0);
+        should(9 == localMaxima(img, res2, 
+                                LocalMinmaxOptions().allowAtBorder().allowPlateaus().neighborhood(4)));
+        should(res == res2);
+   }
+
+    void plateauWithHolesTest()
+    {
+        static const double in[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 2.0, 3.0, 2.0, 2.0, 1.0, 0.0, 0.0,
+            0.0, 1.0, 3.0, 4.0, 4.1, 3.0, 1.0, 0.0, 0.0,
+            0.0, 1.0, 2.0, 2.0, 3.0, 2.0, 1.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        std::copy(in, in+81, img.begin());
+        Image res(img.shape()), res2(img.shape());
+
+        extendedLocalMaxima(srcImageRange(img), destImage(res), 1.0,
+                            EightNeighborCode(),
+                            EqualWithToleranceFunctor<Image::value_type>(0.2));
+        
+        static const double desired[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        shouldEqualSequence(res.begin(), res.end(), desired);
+    }
+
+    Image img;
+    Volume vol;
+};
+
+struct WatershedsTest
+{
+    typedef vigra::MultiArray<2, double> Image;
+    typedef vigra::MultiArray<2, int> IntImage;
+
+    WatershedsTest()
+    : img(Shape2(9,9))
+    {
+        static const double in[] = {
+            0.0,  0.1,  0.1,  0.3,  0.5,  0.3,  0.0,  0.0, 0.0,
+            0.0, -0.1,  0.1,  0.0,  1.0,  0.0,  0.3,  0.0, 0.0,
+            0.0,  0.5,  2.0,  0.0,  2.0,  2.0,  2.0,  0.0, 0.0,
+            0.0,  0.0,  1.0,  1.5,  1.0,  1.0,  3.0,  4.0, 0.0,
+            0.3,  0.1,  1.5,  0.0,  0.0,  0.0,  0.0,  3.0, 3.0,
+            0.0,  0.0,  0.0,  0.0, -1.0, -1.5, -1.0,  0.0, 0.0,
+            0.0,  0.0, -2.0, -2.0, -2.0,  0.0, -2.1, -0.5, 0.0,
+            0.0,  0.0,  0.0,  0.0, -1.0,  0.0, -0.1,  0.1, 0.0,
+            0.0,  0.0,  0.0,  0.0, -0.5, -0.3, -0.1, -0.1, 0.0};
+
+        Image::iterator i = img.begin();
+        Image::iterator end = img.end();
+        const double * p = in;
+
+        for(; i != end; ++i, ++p)
+        {
+            // transform data to a range suitable for BucketQueue (in the turbo algorithm)
+            *i = *p*10.0 + 30.0;
+        }
+    }
+
+    void watershedsTest()
+    {
+        IntImage res(img.shape()), res2(img.shape());
+
+        /*******************************************************************/
+        
+        static const double desired[] = {
+            1.0,  1.0,  1.0,  2.0,  3.0,  3.0,  3.0,  3.0,  4.0,
+            1.0,  1.0,  1.0,  2.0,  2.0,  3.0,  3.0,  3.0,  4.0,
+            1.0,  1.0,  1.0,  2.0,  2.0,  3.0,  3.0,  3.0,  4.0,
+            1.0,  1.0,  1.0,  5.0,  6.0,  6.0,  6.0,  3.0,  4.0,
+            7.0,  5.0,  5.0,  5.0,  6.0,  6.0,  6.0,  6.0,  6.0,
+            7.0,  5.0,  5.0,  5.0,  5.0,  6.0,  6.0,  6.0,  6.0,
+            7.0,  5.0,  5.0,  5.0,  5.0,  6.0,  6.0,  6.0,  6.0,
+            7.0,  5.0,  5.0,  5.0,  5.0,  6.0,  6.0,  6.0,  6.0,
+            7.0,  7.0,  7.0,  5.0,  5.0,  5.0,  5.0,  5.0,  5.0};
+
+        int count = watershedsUnionFind(srcImageRange(img), destImage(res));
+        
+        shouldEqual(7, count);
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        /*******************************************************************/
+        
+        // break ties explicitly to make the test independent of tie breaking rules
+        img(3,1) -= 0.01;
+        img(3,2) -= 0.01;
+        img(5,4) += 0.01;
+        img(6,4) += 0.01;
+        img(7,5) += 0.01;
+        img(8,5) += 0.01;
+
+        static const double desiredSeeds[] = {
+            0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  1.0,  1.0,  1.0,  
+            0.0,  2.0,  0.0,  3.0,  0.0,  1.0,  0.0,  1.0,  1.0,  
+            0.0,  0.0,  0.0,  3.0,  0.0,  0.0,  0.0,  1.0,  1.0,  
+            0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  1.0,  
+            0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  
+            0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  
+            0.0,  0.0,  4.0,  4.0,  4.0,  0.0,  5.0,  0.0,  0.0,  
+            0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  
+            0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0};
+
+
+        res.init(0);
+        count = generateWatershedSeeds(srcImageRange(img), destImage(res),
+                                       SeedOptions().extendedMinima());
+        shouldEqual(5, count);
+        shouldEqualSequence(res.begin(), res.end(), desiredSeeds);
+
+        res2.init(0);
+        should(5 == generateWatershedSeeds(img, res2, IndirectNeighborhood, SeedOptions().extendedMinima()));
+        shouldEqualSequence(res2.begin(), res2.end(), desiredSeeds);
+
+        /*******************************************************************/
+        
+        static const double desiredRG[] = {
+            2.0,  2.0,  2.0,  3.0,  3.0,  1.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  3.0,  3.0,  1.0,  1.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  3.0,  3.0,  3.0,  1.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  3.0,  3.0,  3.0,  3.0,  1.0,  1.0,  1.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  4.0,  5.0,  1.0,  1.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  4.0,  5.0,  5.0,  5.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  5.0,  5.0,  5.0,  5.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  5.0,  5.0,  5.0,  5.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  4.0,  5.0,  5.0,  5.0};
+
+        count = watershedsRegionGrowing(srcImageRange(img), destImage(res));
+
+        shouldEqual(5, count);
+        shouldEqualSequence(res.begin(), res.end(), desiredRG);
+
+        /*******************************************************************/
+        
+        static const double desiredRGC[] = {
+            2.0,  2.0,  0.0,  3.0,  0.0,  1.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  0.0,  3.0,  0.0,  1.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  0.0,  3.0,  0.0,  1.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  1.0,  
+            0.0,  0.0,  0.0,  4.0,  4.0,  0.0,  5.0,  0.0,  0.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  0.0,  5.0,  5.0,  5.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  0.0,  5.0,  5.0,  5.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  0.0,  0.0,  0.0,  0.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  4.0,  4.0,  4.0,  4.0};
+
+        res.init(0);
+        count = watershedsRegionGrowing(srcImageRange(img), destImage(res),
+                                        WatershedOptions().keepContours()
+                                          .seedOptions(SeedOptions().extendedMinima()));
+        shouldEqual(5, count);
+        shouldEqualSequence(res.begin(), res.end(), desiredRGC);
+
+        res2.init(0);
+        generateWatershedSeeds(img, res2, IndirectNeighborhood, SeedOptions().extendedMinima());
+        should(5 == watershedsMultiArray(img, res2, IndirectNeighborhood, WatershedOptions().regionGrowing().keepContours()));
+        should(res == res2);
+
+        /*******************************************************************/
+        
+        static const double desiredTRG[] = {
+            2.0,  2.0,  2.0,  3.0,  3.0,  1.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  2.0,  3.0,  3.0,  1.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  2.0,  3.0,  3.0,  1.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  3.0,  3.0,  3.0,  5.0,  1.0,  1.0,  1.0,  
+            4.0,  4.0,  4.0,  4.0,  5.0,  5.0,  5.0,  5.0,  1.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  5.0,  5.0,  5.0,  5.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  5.0,  5.0,  5.0,  5.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  5.0,  5.0,  5.0,  5.0,  
+            4.0,  4.0,  4.0,  4.0,  4.0,  4.0,  4.0,  5.0,  5.0};
+
+        res.init(0);
+        count = watershedsRegionGrowing(srcImageRange(img), destImage(res),
+                                        WatershedOptions().turboAlgorithm()
+                                          .seedOptions(SeedOptions().extendedMinima()));
+        shouldEqual(5, count);
+        shouldEqualSequence(res.begin(), res.end(), desiredTRG);
+
+        res2.init(0);
+        generateWatershedSeeds(img, res2, IndirectNeighborhood, SeedOptions().extendedMinima());
+        should(5 == watershedsMultiArray(img, res2, IndirectNeighborhood, WatershedOptions().regionGrowing()));
+        should(res == res2);
+
+        res2.init(1);  // check that this is overridden by explicit seed computation
+        should(5 == watershedsMultiArray(img, res2, IndirectNeighborhood, WatershedOptions().regionGrowing().seedOptions(SeedOptions().extendedMinima())));
+        should(res == res2);
+
+#if 0
+        std::cerr << count << "\n";
+        for(int y=0;y<9;++y)
+        {
+            std::cerr << "            ";
+            for(int x=0;x<9;++x)
+                std::cerr << res(x,y) << ".0,  ";
+            std::cerr << "\n\n";
+        }
+#endif /* #if 0 */
+    }
+
+    void watersheds4Test()
+    {
+        IntImage res(img.shape()), res2(img.shape());
+
+        /*******************************************************************/
+        
+        static const double desired[] = {
+            1.0,  1.0,  1.0,  2.0,  2.0,  3.0,  4.0,  4.0,  5.0,
+            1.0,  1.0,  1.0,  2.0,  2.0,  3.0,  3.0,  4.0,  5.0,
+            6.0,  1.0,  2.0,  2.0,  2.0,  3.0,  4.0,  4.0,  5.0,
+            6.0,  6.0,  6.0,  7.0,  7.0,  8.0,  9.0,  4.0,  5.0,
+           10.0,  7.0,  7.0,  7.0,  7.0,  8.0,  9.0,  9.0,  9.0,
+           10.0,  7.0,  7.0,  7.0,  7.0,  8.0,  9.0,  9.0,  9.0,
+           10.0,  7.0,  7.0,  7.0,  7.0,  9.0,  9.0,  9.0,  9.0,
+           10.0, 10.0,  7.0,  7.0,  7.0,  7.0,  9.0,  9.0,  7.0,
+           10.0, 10.0, 10.0,  7.0,  7.0,  7.0,  7.0,  7.0,  7.0};
+
+        int count = watershedsUnionFind(srcImageRange(img), destImage(res), FourNeighborCode());
+
+        should(10 == count);
+        shouldEqualSequence(res.begin(), res.end(), desired);
+
+        /*******************************************************************/
+        
+        // break ties explicitly to make the test independent of tie breaking rules
+        img(3,0) += 0.01;
+        img(3,4) += 0.01;
+        img(5,1) += 0.01;
+        img(0,3) += 0.01;
+        img(1,3) += 0.01;
+        img(8,5) += 0.01;
+        img(6,8) += 0.01;
+        img(7,8) += 0.01;
+        img(8,8) += 0.01;
+
+        static const double desiredSeeds[] = {
+            0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  1.0,  1.0,  1.0,  
+            0.0,  2.0,  0.0,  3.0,  0.0,  4.0,  0.0,  1.0,  1.0,  
+            0.0,  0.0,  0.0,  3.0,  0.0,  0.0,  0.0,  1.0,  1.0,  
+            0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  1.0,  
+            0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  
+            0.0,  0.0,  0.0,  0.0,  0.0,  5.0,  0.0,  0.0,  0.0,  
+            0.0,  0.0,  6.0,  6.0,  6.0,  0.0,  7.0,  0.0,  0.0,  
+            0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  
+            0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0};
+
+        res.init(0);
+        count = generateWatershedSeeds(srcImageRange(img), destImage(res), FourNeighborCode(),
+                                       SeedOptions().extendedMinima());
+        shouldEqual(7, count);
+        shouldEqualSequence(res.begin(), res.end(), desiredSeeds);
+
+        res2.init(0);
+        should(7 == generateWatershedSeeds(img, res2, DirectNeighborhood, SeedOptions().extendedMinima()));
+        shouldEqualSequence(res2.begin(), res2.end(), desiredSeeds);
+
+        /*******************************************************************/
+        
+        static const double desiredRG[] = {
+            2.0,  2.0,  2.0,  3.0,  3.0,  1.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  3.0,  3.0,  4.0,  4.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  3.0,  3.0,  3.0,  4.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  2.0,  3.0,  5.0,  5.0,  1.0,  1.0,  1.0,  
+            6.0,  6.0,  6.0,  6.0,  5.0,  5.0,  5.0,  1.0,  1.0,  
+            6.0,  6.0,  6.0,  6.0,  5.0,  5.0,  5.0,  7.0,  7.0,  
+            6.0,  6.0,  6.0,  6.0,  6.0,  7.0,  7.0,  7.0,  7.0,  
+            6.0,  6.0,  6.0,  6.0,  6.0,  6.0,  7.0,  7.0,  7.0,  
+            6.0,  6.0,  6.0,  6.0,  6.0,  6.0,  7.0,  7.0,  7.0};
+
+        count = watershedsRegionGrowing(srcImageRange(img), destImage(res), FourNeighborCode());
+
+        shouldEqual(7, count);
+        shouldEqualSequence(res.begin(), res.end(), desiredRG);
+
+        /*******************************************************************/
+        
+        static const double desiredRGC[] = {
+            2.0,  2.0,  2.0,  0.0,  0.0,  0.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  0.0,  3.0,  0.0,  4.0,  0.0,  1.0,  1.0,  
+            2.0,  2.0,  0.0,  3.0,  0.0,  0.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  2.0,  0.0,  5.0,  5.0,  0.0,  1.0,  1.0,  
+            0.0,  0.0,  0.0,  0.0,  5.0,  5.0,  5.0,  0.0,  0.0,  
+            6.0,  6.0,  6.0,  6.0,  0.0,  5.0,  0.0,  7.0,  7.0,  
+            6.0,  6.0,  6.0,  6.0,  6.0,  0.0,  7.0,  7.0,  7.0,  
+            6.0,  6.0,  6.0,  6.0,  6.0,  0.0,  7.0,  7.0,  7.0,  
+            6.0,  6.0,  6.0,  6.0,  6.0,  6.0,  0.0,  7.0,  7.0};
+
+        res.init(0);
+        count = watershedsRegionGrowing(srcImageRange(img), destImage(res), FourNeighborCode(),
+                                        WatershedOptions().keepContours()
+                                          .seedOptions(SeedOptions().extendedMinima()));
+        shouldEqual(7, count);
+        shouldEqualSequence(res.begin(), res.end(), desiredRGC);
+
+        res2.init(0);
+        generateWatershedSeeds(img, res2, DirectNeighborhood, SeedOptions().extendedMinima());
+        should(7 == watershedsMultiArray(img, res2, DirectNeighborhood, WatershedOptions().regionGrowing().keepContours()));
+        should(res == res2);
+
+        /*******************************************************************/
+        
+        static const double desiredTRG[] = {
+            2.0,  2.0,  2.0,  3.0,  1.0,  1.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  2.0,  3.0,  3.0,  4.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  3.0,  3.0,  3.0,  4.0,  1.0,  1.0,  1.0,  
+            2.0,  2.0,  2.0,  3.0,  6.0,  5.0,  7.0,  1.0,  1.0,  
+            6.0,  6.0,  6.0,  6.0,  6.0,  5.0,  7.0,  7.0,  1.0,  
+            6.0,  6.0,  6.0,  6.0,  6.0,  5.0,  7.0,  7.0,  7.0,  
+            6.0,  6.0,  6.0,  6.0,  6.0,  7.0,  7.0,  7.0,  7.0,  
+            6.0,  6.0,  6.0,  6.0,  6.0,  6.0,  7.0,  7.0,  7.0,  
+            6.0,  6.0,  6.0,  6.0,  6.0,  6.0,  6.0,  6.0,  6.0};
+
+        res.init(0);
+        count = watershedsRegionGrowing(srcImageRange(img), destImage(res), FourNeighborCode(),
+                                        WatershedOptions().turboAlgorithm()
+                                          .seedOptions(SeedOptions().extendedMinima()));
+        shouldEqual(7, count);
+        shouldEqualSequence(res.begin(), res.end(), desiredTRG);
+
+        res2.init(0);
+        generateWatershedSeeds(img, res2, DirectNeighborhood, SeedOptions().extendedMinima());
+        should(7 == watershedsMultiArray(img, res2, DirectNeighborhood, WatershedOptions().regionGrowing()));
+        should(res == res2);
+
+        res2.init(1);  // check that this is overridden by explicit seed computation
+        should(7 == watershedsMultiArray(img, res2, DirectNeighborhood, WatershedOptions().regionGrowing().seedOptions(SeedOptions().extendedMinima())));
+        should(res == res2);
+
+#if 0
+        std::cerr << count << "\n";
+        for(int k=0; k<res.size(); ++k)
+        {
+            std::cerr << res[k] << (res[k] == res2[k] ? " " : "*");
+            if(k%res.shape(0) == res.shape(0)-1)
+                std::cerr << "\n";
+        }
+#endif /* #if 0 */
+    }
+
+    Image img;
+};
+
+struct RegionGrowingTest
+{
+    typedef vigra::DImage Image;
+    typedef MultiArrayView<2, double> View;
+
+    RegionGrowingTest()
+    : img(7,7), seeds(7,7)
+    {
+        static const double in[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        Image tmp(7,7);
+
+        Image::ScanOrderIterator i = tmp.begin();
+        Image::ScanOrderIterator end = tmp.end();
+        Image::Accessor acc = tmp.accessor();
+        const double * p = in;
+
+        for(; i != end; ++i, ++p)
+        {
+            acc.set(*p, i);
+        }
+
+        distanceTransform(srcImageRange(tmp), destImage(img), 0.0, 2);
+
+        seeds = 0;
+        labelImageWithBackground(srcImageRange(tmp), destImage(seeds),
+                                 false, 0.0);
+    }
+
+    struct DirectCostFunctor
+    {
+        typedef double argument_type;
+        typedef double result_type;
+        typedef double cost_type;
+
+        void operator()(double const &) {}
+
+        double const & cost(double const & v) const
+        {
+            return v;
+        }
+    };
+
+    void voronoiTest()
+    {
+        Image res(img);
+
+        vigra::ArrayOfRegionStatistics<DirectCostFunctor> cost(2);
+        seededRegionGrowing(View(img), View(seeds), View(res), cost);
+
+        Image::Iterator i = res.upperLeft();
+        Image::Accessor acc = res.accessor();
+        int x,y;
+
+        for(y=0; y<7; ++y)
+        {
+            for(x=0; x<7; ++x)
+            {
+                double dist = acc(i, vigra::Diff2D(x,y));
+                double dist1 = VIGRA_CSTD::sqrt((2.0 - x)*(2.0 - x) +
+                                         (2.0 - y)*(2.0 - y));
+                double dist2 = VIGRA_CSTD::sqrt((5.0 - x)*(5.0 - x) +
+                                         (5.0 - y)*(5.0 - y));
+                double desired = (dist1 <= dist2) ? 1 : 2;
+
+                if(VIGRA_CSTD::fabs(dist1 - dist2) > 1e-10)
+                    shouldEqual(dist, desired);
+            }
+        }
+
+        vigra::IImage wres(img.size());
+
+        watershedsRegionGrowing(srcImageRange(img), destImage(wres),
+                                WatershedOptions().completeGrow()
+                                 .seedOptions(SeedOptions().minima().threshold(1.0)));
+
+        shouldEqualSequence(res.begin(), res.end(), wres.begin());
+    }
+
+    void voronoiWithBorderTest()
+    {
+        Image res(img);
+        Image::value_type reference[] = {
+            1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 0,
+            1, 1, 1, 1, 1, 0, 2,
+            1, 1, 1, 1, 0, 2, 2,
+            1, 1, 1, 0, 2, 2, 2,
+            1, 1, 0, 2, 2, 2, 2,
+            1, 0, 2, 2, 2, 2, 2
+        };
+
+        vigra::ArrayOfRegionStatistics<DirectCostFunctor> cost(2);
+        seededRegionGrowing(srcImageRange(img), srcImage(seeds),
+                            destImage(res), cost, KeepContours);
+
+        shouldEqualSequence(res.begin(), res.end(), reference);
+    }
+
+    Image img, seeds;
+};
+
+struct InterestOperatorTest
+{
+    typedef vigra::DImage Image;
+    typedef vigra::MultiArrayView<2, double> View;
+
+    InterestOperatorTest()
+    : img(9,9)
+    {
+        static const double in[] = {
+            1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+            1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0,
+            1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
+            1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0,
+            1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+            1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0,
+            1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
+            1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0,
+            1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0};
+
+        Image::ScanOrderIterator i = img.begin();
+        Image::ScanOrderIterator end = img.end();
+        Image::Accessor acc = img.accessor();
+        const double * p = in;
+
+        for(; i != end; ++i, ++p)
+        {
+            acc.set(*p, i);
+        }
+    }
+
+    void cornerResponseFunctionTest()
+    {
+        Image tmp(img);
+        Image tmp1(img);
+        Image res(img);
+        res = 0.0;
+
+        cornerResponseFunction(srcImageRange(img), destImage(tmp), 1.0);
+        localMaxima(srcImageRange(tmp), destImage(res), 1.0);
+
+        static const double desired[] = {
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        const double * i1 = desired;
+        const double * i1end = i1 + 81;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+
+        cornerResponseFunction(View(img), View(tmp1), 1.0);
+        should(View(tmp) == View(tmp1));
+    }
+
+    void foerstnerCornerTest()
+    {
+        Image tmp(img);
+        Image tmp1(img);
+        Image res(img);
+        res = 0.0;
+
+        foerstnerCornerDetector(srcImageRange(img), destImage(tmp), 1.0);
+        localMaxima(srcImageRange(tmp), destImage(res), 1.0);
+
+        static const double desired[] = {
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        const double * i1 = desired;
+        const double * i1end = i1 + 81;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+
+        foerstnerCornerDetector(View(img), View(tmp1), 1.0);
+        should(View(tmp) == View(tmp1));
+    }
+
+    void rohrCornerTest()
+    {
+        Image tmp(img);
+        Image tmp1(img);
+        Image res(img);
+        res = 0.0;
+
+        rohrCornerDetector(srcImageRange(img), destImage(tmp), 1.0);
+        localMaxima(srcImageRange(tmp), destImage(res), 1.0);
+
+        static const double desired[] = {
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        const double * i1 = desired;
+        const double * i1end = i1 + 81;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+
+        rohrCornerDetector(View(img), View(tmp1), 1.0);
+        should(View(tmp) == View(tmp1));
+    }
+
+
+    void beaudetCornerTest()
+    {
+        Image tmp(img);
+        Image tmp1(img);
+        Image res(img);
+        res = 0.0;
+
+        beaudetCornerDetector(srcImageRange(img), destImage(tmp), 1.0);
+        localMaxima(srcImageRange(tmp), destImage(res), 1.0);
+
+        static const double desired[] = {
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+        const double * i1 = desired;
+        const double * i1end = i1 + 81;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+
+        beaudetCornerDetector(View(img), View(tmp1), 1.0);
+        should(View(tmp) == View(tmp1));
+    }
+
+    void radialSymmetryTest()
+    {
+        Image tmp(img);
+        Image res(img);
+        res = 0.0;
+
+        radialSymmetryTransform(View(img), View(tmp), 1.0);
+        localMaxima(srcImageRange(tmp), destImage(res), 1.0);
+        localMinima(srcImageRange(tmp), destImage(res), -1.0);
+
+        static const double desired[] = {
+                   0.0, 0.0, 0.0,  0.0, 0.0,  0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0,  0.0, 0.0,  0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0,  0.0, 0.0,  0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0,  0.0, 1.0,  0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0,  0.0, 1.0,  0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0,  0.0, 0.0,  0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0,  0.0, 0.0,  0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0,  0.0, 0.0,  0.0, 0.0, 0.0, 0.0};
+
+        const double * i1 = desired;
+        const double * i1end = i1 + 81;
+        Image::ScanOrderIterator i2 = res.begin();
+        Image::Accessor acc = res.accessor();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should(*i1 == acc(i2));
+        }
+    }
+
+    Image img;
+};
+
+struct NoiseNormalizationTest
+{
+    typedef vigra::BImage U8Image;
+    typedef vigra::DImage GrayImage;
+    typedef vigra::DRGBImage RGBImage;
+    typedef MultiArrayView<2, double> View;
+    U8Image u8image;
+    GrayImage image;
+    RGBImage rgb;
+
+    NoiseNormalizationTest()
+    {
+        vigra::ImageImportInfo info("noiseNormalizationTest.xv");
+        vigra_precondition(info.width() == 400 && info.height() == 20,
+           "NoiseNormalizationTest: input image has wrong size.");
+           
+        u8image.resize(info.size());
+        importImage(info, destImage(u8image));
+        image.resize(info.size());
+        importImage(info, destImage(image));
+        rgb.resize(info.size());
+        for(unsigned int band = 0; band < 3; ++band)
+        {
+            vigra::VectorElementAccessor<RGBImage::Accessor> dband(band, rgb.accessor());
+            importImage(info, destImage(rgb, dband));
+        }
+    }
+    
+    template <class Iterator, class Accessor>
+    void checkVariance(Iterator ul, Accessor const & a, double tolerance)
+    {
+        for(unsigned int k = 0; k < 20; ++k)
+        {
+            double sum = 0.0, sum2 = 0.0;
+            for(unsigned int y = 0; y < 20; ++y)
+            {
+                for(unsigned int x = 20*k; x < 20*(k+1); ++x)
+                {
+                    sum += a(ul, Diff2D(x, y));
+                    sum2 += sq(a(ul, Diff2D(x, y)));
+                }
+            }
+            
+            sum /= 400.0;
+            sum2 /= 400.0;
+            
+            shouldEqualTolerance(VIGRA_CSTD::sqrt(sum2 - sq(sum))-1.0, 0.0, tolerance);
+       }
+    }
+    
+    void testParametricNoiseNormalizationU8()
+    {
+        GrayImage res(image.size());
+        linearNoiseNormalization(srcImageRange(u8image), destImage(res), 1.0, 0.02);
+        checkVariance(res.upperLeft(), res.accessor(), 0.1);
+        linearNoiseNormalization(srcImageRange(u8image), destImage(res));
+        checkVariance(res.upperLeft(), res.accessor(), 0.1);
+        quadraticNoiseNormalization(srcImageRange(u8image), destImage(res), 1.0, 0.02, 0.0);
+        checkVariance(res.upperLeft(), res.accessor(), 0.1);
+        quadraticNoiseNormalization(srcImageRange(u8image), destImage(res));
+        checkVariance(res.upperLeft(), res.accessor(), 0.1);
+    }
+  
+    void testParametricNoiseNormalization()
+    {
+        GrayImage res(image.size());
+        linearNoiseNormalization(View(image), View(res), 1.0, 0.02);
+        checkVariance(res.upperLeft(), res.accessor(), 0.1);
+        linearNoiseNormalization(View(image), View(res));
+        checkVariance(res.upperLeft(), res.accessor(), 0.1);
+        quadraticNoiseNormalization(View(image), View(res), 1.0, 0.02, 0.0);
+        checkVariance(res.upperLeft(), res.accessor(), 0.1);
+        quadraticNoiseNormalization(View(image), View(res));
+        checkVariance(res.upperLeft(), res.accessor(), 0.1);
+   }
+  
+    void testParametricNoiseNormalizationRGB()
+    {
+        RGBImage res(rgb.size());
+        linearNoiseNormalization(srcImageRange(rgb), destImage(res), 1.0, 0.02);
+        for(unsigned int band = 0; band < 3; ++band)
+        {
+            vigra::VectorElementAccessor<RGBImage::Accessor> dband(band, res.accessor());
+            checkVariance(res.upperLeft(), dband, 0.1);
+        }
+        linearNoiseNormalization(srcImageRange(rgb), destImage(res));
+        for(unsigned int band = 0; band < 3; ++band)
+        {
+            vigra::VectorElementAccessor<RGBImage::Accessor> dband(band, res.accessor());
+            checkVariance(res.upperLeft(), dband, 0.1);
+        }
+        quadraticNoiseNormalization(srcImageRange(rgb), destImage(res), 1.0, 0.02, 0.0);
+        for(unsigned int band = 0; band < 3; ++band)
+        {
+            vigra::VectorElementAccessor<RGBImage::Accessor> dband(band, res.accessor());
+            checkVariance(res.upperLeft(), dband, 0.1);
+        }
+        quadraticNoiseNormalization(srcImageRange(rgb), destImage(res));
+        for(unsigned int band = 0; band < 3; ++band)
+        {
+            vigra::VectorElementAccessor<RGBImage::Accessor> dband(band, res.accessor());
+            checkVariance(res.upperLeft(), dband, 0.1);
+        }
+    }
+  
+    void testNonparametricNoiseNormalizationU8()
+    {
+        GrayImage res(image.size());        
+        nonparametricNoiseNormalization(srcImageRange(u8image), destImage(res));
+        checkVariance(res.upperLeft(), res.accessor(), 0.1);
+    }
+  
+    void testNonparametricNoiseNormalization()
+    {
+        GrayImage res(image.size());        
+        nonparametricNoiseNormalization(srcImageRange(image), destImage(res));
+        checkVariance(res.upperLeft(), res.accessor(), 0.1);
+   }
+  
+    void testNonparametricNoiseNormalizationRGB()
+    {
+        RGBImage res(rgb.size());        
+        nonparametricNoiseNormalization(srcImageRange(rgb), destImage(res));
+        for(unsigned int band = 0; band < 3; ++band)
+        {
+            vigra::VectorElementAccessor<RGBImage::Accessor> dband(band, res.accessor());
+            checkVariance(res.upperLeft(), dband, 0.1);
+        }
+    }
+};
+
+#ifdef HasFFTW3
+struct SlantedEdgeMTFTest
+{
+    typedef vigra::MultiArray<2, double> Image;
+    typedef vigra::ArrayVector<vigra::TinyVector<double, 2> > Result;
+    typedef Result::value_type Pair;
+    
+    Image image;
+    Result reference;
+
+    SlantedEdgeMTFTest()
+    {
+        vigra::ImageImportInfo info("slantedEdgeMTF.xv");
+           
+        image.reshape(info.shape());
+        importImage(info, destImage(image));
+        
+        reference.push_back(Pair(0, 1));
+        reference.push_back(Pair(0.0564351, 0.981739));
+        reference.push_back(Pair(0.11287, 0.929577));
+        reference.push_back(Pair(0.169305, 0.850509));
+        reference.push_back(Pair(0.22574, 0.754266));
+        reference.push_back(Pair(0.282175, 0.651081));
+        reference.push_back(Pair(0.33861, 0.549492));
+        reference.push_back(Pair(0.395045, 0.454718));
+        reference.push_back(Pair(0.45148, 0.368628));
+        reference.push_back(Pair(0.507915, 0.291512));
+        reference.push_back(Pair(0.564351, 0.223585));
+        reference.push_back(Pair(0.620786, 0.165506));
+        reference.push_back(Pair(0.677221, 0.117569));
+        reference.push_back(Pair(0.733656, 0.0788625));
+        reference.push_back(Pair(0.790091, 0.0475224));
+        reference.push_back(Pair(0.846526, 0.021419));
+        reference.push_back(Pair(0.902961, 0));
+    }
+    
+    void testSlantedEdgeMTF()
+    {
+        Result res;
+        slantedEdgeMTF(image, res);
+        
+        shouldEqual(res.size(), reference.size());
+        
+        for(unsigned int k = 0; k < res.size(); ++k)
+        {
+            shouldEqualTolerance(res[k][0], reference[k][0], 1e-5);
+            shouldEqualTolerance(res[k][1], reference[k][1], 1e-5);
+        }
+        
+        shouldEqualTolerance(mtfFitGaussian(res), 0.5, 1e-2);
+    }
+};
+#endif // HasFFTW3
+
+struct AffineRegistrationTest
+{
+    typedef vigra::DImage Image;
+    typedef vigra::MultiArrayView<2, double> View;
+    typedef vigra::TinyVector<double, 2> Vector2;
+    typedef vigra::ArrayVector<Vector2> PointList;
+    
+    Image image;
+
+    AffineRegistrationTest()
+    {
+        ImageImportInfo info("lenna128.xv");
+        image.resize(info.size());
+        importImage(info, destImage(image));
+    }
+    
+    void testCorrespondingPoints()
+    {
+        Matrix<double> point(3,1), res(3,1);
+        point(2,0) = 1.0;
+        
+        PointList src(3), dest(3);
+        src[0] = Vector2(1.6, 2.9);     
+        src[1] = Vector2(-1.3, -4.0);     
+        src[2] = Vector2(7.1, -0.4);     
+        dest[0] = Vector2(-2.9, 1.6);     
+        dest[1] = Vector2(12.6, -3.4);     
+        dest[2] = Vector2(-3.3, 4.2);
+        
+        for(int k=1; k<=3; ++k)
+        {     
+            Matrix<double> a = affineMatrix2DFromCorrespondingPoints(src.begin(), src.begin()+k, dest.begin());
+            for(int i=0; i<k; ++i)
+            {
+                point(0,0) = src[i][0];
+                point(1,0) = src[i][1];
+                res = a * point;
+                shouldEqualTolerance(res(0,0), dest[i][0], 1e-14);
+                shouldEqualTolerance(res(1,0), dest[i][1], 1e-14);
+                shouldEqual(res(2,0), 1.0);
+            }
+        }
+    }
+
+    void testTranslationRegistration()
+    {
+        Matrix<double> m = translationMatrix2D(Vector2(5.0, 10.0));
+        Image timg(image.size());
+        affineWarpImage(SplineImageView<2, double>(srcImageRange(image)), destImageRange(timg), m);
+        
+        Matrix<double> estimated = identityMatrix<double>(3);
+        estimateTranslation(srcImageRange(image), srcImageRange(timg), estimated,
+                            AffineMotionEstimationOptions<1>().highestPyramidLevel(3));
+        
+        for(int i=0; i<9; ++i)
+            shouldEqualTolerance(m.data()[i] - estimated.data()[i], 0.0, 1e-6);
+        
+        estimated = identityMatrix<double>(3);
+        estimateTranslation(View(image), View(timg), estimated,
+                            AffineMotionEstimationOptions<1>().highestPyramidLevel(3));
+        
+        for(int i=0; i<9; ++i)
+            shouldEqualTolerance(m.data()[i] - estimated.data()[i], 0.0, 1e-6);
+    }
+
+    void testSimilarityRegistration()
+    {
+        Matrix<double> m = translationMatrix2D(Vector2(5.0, 10.0)) * 
+                             rotationMatrix2DDegrees(5.0)* scalingMatrix2D(0.9);
+        Image timg(image.size());
+        affineWarpImage(SplineImageView<2, double>(srcImageRange(image)), destImageRange(timg), m);
+
+        Matrix<double> estimated = identityMatrix<double>(3);
+        estimateSimilarityTransform(srcImageRange(image), srcImageRange(timg), estimated,
+                            AffineMotionEstimationOptions<>().useLaplacianPyramid(false));
+        
+        for(int i=0; i<9; ++i)
+            shouldEqualTolerance(m.data()[i] - estimated.data()[i], 0.0, 1e-6);
+
+        estimated = identityMatrix<double>(3);
+        estimateSimilarityTransform(srcImageRange(image), 
+                            srcIterRange(timg.upperLeft(), timg.lowerRight()-Diff2D(20,20)), estimated,
+                            AffineMotionEstimationOptions<>().useLaplacianPyramid(true));
+        
+        for(int i=0; i<9; ++i)
+            shouldEqualTolerance(m.data()[i] , estimated.data()[i], 1e-2);
+
+        estimated = identityMatrix<double>(3);
+        estimateSimilarityTransform(View(image),View(timg).subarray(Shape2(), Shape2(-20)), estimated,
+                            AffineMotionEstimationOptions<>().useLaplacianPyramid(true));
+        
+        for(int i=0; i<9; ++i)
+            shouldEqualTolerance(m.data()[i] , estimated.data()[i], 1e-2);
+    }
+
+    void testAffineRegistration()
+    {
+        Matrix<double> m = translationMatrix2D(Vector2(5.0, 10.0)) * 
+                             rotationMatrix2DDegrees(5.0)* scalingMatrix2D(1.0, 0.9);
+        Image timg(image.size());
+        affineWarpImage(SplineImageView<2, double>(srcImageRange(image)), destImageRange(timg), m);
+
+        Matrix<double> estimated = identityMatrix<double>(3);
+        estimateAffineTransform(srcImageRange(image), srcImageRange(timg), estimated);
+        
+        for(int i=0; i<9; ++i)
+            shouldEqualTolerance(m.data()[i] - estimated.data()[i], 0.0, 1e-6);
+
+        estimated = identityMatrix<double>(3);
+        estimateAffineTransform(View(image), View(timg), estimated);
+        
+        for(int i=0; i<9; ++i)
+            shouldEqualTolerance(m.data()[i] - estimated.data()[i], 0.0, 1e-6);
+    }
+};
+
+struct SimpleAnalysisTestSuite
+: public vigra::test_suite
+{
+    SimpleAnalysisTestSuite()
+    : vigra::test_suite("SimpleAnalysisTestSuite")
+    {
+        add( testCase( &LabelingTest::labelingFourTest1));
+        add( testCase( &LabelingTest::labelingFourTest2));
+        add( testCase( &LabelingTest::labelingFourTest3));
+        add( testCase( &LabelingTest::labelingFourTest4));
+        add( testCase( &LabelingTest::labelingToEdgeTest));
+        add( testCase( &LabelingTest::labelingEightTest1));
+        add( testCase( &LabelingTest::labelingEightTest2));
+        add( testCase( &LabelingTest::labelingFourWithBackgroundTest1));
+        add( testCase( &LabelingTest::labelingFourWithBackgroundTest2));
+        add( testCase( &LabelingTest::labelingEightWithBackgroundTest));
+        add( testCase( &EdgeDetectionTest::edgeDetectionTest));
+        add( testCase( &EdgeDetectionTest::edgeToCrackEdgeTest));
+        add( testCase( &EdgeDetectionTest::removeShortEdgesTest));
+        add( testCase( &EdgeDetectionTest::beautifyCrackEdgeTest));
+        add( testCase( &EdgeDetectionTest::closeGapsInCrackEdgeTest));
+        add( testCase( &EdgeDetectionTest::cannyEdgelListTest));
+        add( testCase( &EdgeDetectionTest::cannyEdgelList3x3Test));
+        add( testCase( &EdgeDetectionTest::cannyEdgeImageTest));
+        add( testCase( &EdgeDetectionTest::cannyEdgeImageWithThinningTest));
+        add( testCase( &DistanceTransformTest::distanceTransformL1Test));
+        add( testCase( &DistanceTransformTest::distanceTransformL2Test));
+        add( testCase( &DistanceTransformTest::distanceTransformLInfTest));
+
+        add( testCase( &LocalMinMaxTest::localMinimumTest));
+        add( testCase( &LocalMinMaxTest::localMinimum4Test));
+        add( testCase( &LocalMinMaxTest::localMinimumTestThr));
+        add( testCase( &LocalMinMaxTest::localMaximumTest));
+        add( testCase( &LocalMinMaxTest::localMaximum4Test));
+        add( testCase( &LocalMinMaxTest::localMaximumTestThr));
+        add( testCase( &LocalMinMaxTest::extendedLocalMinimumTest));
+        add( testCase( &LocalMinMaxTest::extendedLocalMinimum4Test));
+        add( testCase( &LocalMinMaxTest::extendedLocalMaximumTest));
+        add( testCase( &LocalMinMaxTest::extendedLocalMaximum4Test));
+
+        add( testCase( &LocalMinMaxTest::extendedLocalMaximum3DTest));
+        add( testCase( &LocalMinMaxTest::extendedLocalMinimum3DTest));
+        add( testCase( &LocalMinMaxTest::extendedLocalMaximum3DTest2));
+        add( testCase( &LocalMinMaxTest::extendedLocalMinimum3DTest2));
+        add( testCase( &LocalMinMaxTest::localMaximum3DTest));
+        add( testCase( &LocalMinMaxTest::localMinimum3DTest));
+
+        add( testCase( &LocalMinMaxTest::plateauWithHolesTest));
+        add( testCase( &WatershedsTest::watershedsTest));
+        add( testCase( &WatershedsTest::watersheds4Test));
+        add( testCase( &RegionGrowingTest::voronoiTest));
+        add( testCase( &RegionGrowingTest::voronoiWithBorderTest));
+        add( testCase( &InterestOperatorTest::cornerResponseFunctionTest));
+        add( testCase( &InterestOperatorTest::foerstnerCornerTest));
+        add( testCase( &InterestOperatorTest::rohrCornerTest));
+        add( testCase( &InterestOperatorTest::beaudetCornerTest));
+        add( testCase( &InterestOperatorTest::radialSymmetryTest));
+        add( testCase( &NoiseNormalizationTest::testParametricNoiseNormalization));
+        add( testCase( &NoiseNormalizationTest::testNonparametricNoiseNormalization));
+        add( testCase( &NoiseNormalizationTest::testParametricNoiseNormalizationU8));
+        add( testCase( &NoiseNormalizationTest::testNonparametricNoiseNormalizationU8));
+        add( testCase( &NoiseNormalizationTest::testParametricNoiseNormalizationRGB));
+        add( testCase( &NoiseNormalizationTest::testNonparametricNoiseNormalizationRGB));
+        add( testCase( &AffineRegistrationTest::testCorrespondingPoints));
+        add( testCase( &AffineRegistrationTest::testTranslationRegistration));
+        add( testCase( &AffineRegistrationTest::testSimilarityRegistration));
+        add( testCase( &AffineRegistrationTest::testAffineRegistration));
+#ifdef HasFFTW3
+        add( testCase( &SlantedEdgeMTFTest::testSlantedEdgeMTF));
+#endif // HasFFTW3
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    SimpleAnalysisTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+
+    return (failed != 0);
+}
+
diff --git a/test/simpleanalysis/test_freaky.cxx b/test/simpleanalysis/test_freaky.cxx
new file mode 100755
index 0000000..ca3ea59
--- /dev/null
+++ b/test/simpleanalysis/test_freaky.cxx
@@ -0,0 +1,24 @@
+#include <iostream>
+#include <cmath>
+
+int main()
+{
+    int x,y;
+    
+    for(y=0; y<7; ++y)
+    {
+        for(x=0; x<7; ++x)
+        {
+            double dist1 = std::sqrt((2.0 - x)*(2.0 - x) +
+                                     (2.0 - y)*(2.0 - y));
+            double dist2 = std::sqrt((5.0 - x)*(5.0 - x) +
+                                     (5.0 - y)*(5.0 - y));
+            
+            if(dist1 != dist2)
+            {
+                std::cerr << 1
+                          << ((dist1 == dist2) ? "compiler broken\n" : "");
+            }
+        }
+    }
+}
diff --git a/test/slic2d/CMakeLists.txt b/test/slic2d/CMakeLists.txt
new file mode 100644
index 0000000..9725f93
--- /dev/null
+++ b/test/slic2d/CMakeLists.txt
@@ -0,0 +1,3 @@
+
+VIGRA_COPY_TEST_DATA(lenna.xv slic.xv)
+VIGRA_ADD_TEST(test_slic2d test.cxx LIBRARIES vigraimpex)
\ No newline at end of file
diff --git a/test/slic2d/lenna.xv b/test/slic2d/lenna.xv
new file mode 100644
index 0000000..03ec3f4
Binary files /dev/null and b/test/slic2d/lenna.xv differ
diff --git a/test/slic2d/slic.xv b/test/slic2d/slic.xv
new file mode 100644
index 0000000..979b4b6
Binary files /dev/null and b/test/slic2d/slic.xv differ
diff --git a/test/slic2d/test.cxx b/test/slic2d/test.cxx
new file mode 100644
index 0000000..e79cec1
--- /dev/null
+++ b/test/slic2d/test.cxx
@@ -0,0 +1,144 @@
+/************************************************************************/
+/*                                                                      */
+/*    Copyright 2012-2013 by Ullrich Koethe and Thorsten Beier          */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <functional>
+#include <cmath>
+#include <stdlib.h>
+#include <time.h>
+
+#include "vigra/unittest.hxx"
+
+#include <vigra/slic.hxx>
+#include <vigra/impex.hxx>
+#include <vigra/multi_convolution.hxx>
+#include <vigra/multi_math.hxx>
+#include <vigra/colorconversions.hxx>
+
+
+using namespace vigra;
+
+template <unsigned int N>
+struct SlicTest
+{
+    typedef MultiArray<N, float>                  FArray;
+    typedef MultiArray<N, RGBValue<float> >       FRGBArray;
+    typedef MultiArray<N, int>                    IArray;
+    typedef typename MultiArrayShape<N>::type     Shape;
+
+    ImageImportInfo info;
+    FRGBArray lennaImage;
+
+    SlicTest()
+    :   info("lenna.xv"),
+        lennaImage(info.shape())
+    {
+        importImage(info, destImage(lennaImage));
+        transformMultiArray(srcMultiArrayRange(lennaImage), destMultiArray(lennaImage), RGBPrime2LabFunctor<float>());    
+    }
+
+    void test_seeding()
+    {
+        Shape seeds_ref[] = {
+               Shape(24, 22),
+               Shape(65, 22),
+               Shape(102, 20),
+               Shape(24, 59),
+               Shape(63, 60),
+               Shape(104, 61),
+               Shape(24, 100),
+               Shape(65, 100),
+               Shape(104, 100)
+        };
+
+        // get grad mag image
+        FArray gradMag(lennaImage.shape());
+        gaussianGradientMagnitude(lennaImage, gradMag, 3.0);
+
+        IArray labels(lennaImage.shape());
+        int maxSeedlabel = generateSlicSeeds(gradMag, labels, 39, 1);
+        shouldEqual(maxSeedlabel, 9);
+
+        typename IArray::iterator iter = labels.begin(),
+                                  end  = iter.getEndIterator();
+        int count = 0;
+        for(; iter != end; ++iter)
+        {
+            if(*iter == 0)
+                continue;
+            should(*iter <= 9 && *iter > 0);
+            shouldEqual(iter.point(), seeds_ref[*iter-1]);
+            ++count;
+        }
+        shouldEqual(count, 9);
+    }
+
+    void test_slic()
+    {
+        IArray labels(lennaImage.shape()), labels_ref(lennaImage.shape());
+
+        int seedDistance = 8;
+        // compute seeds automatically
+        slicSuperpixels(lennaImage, labels, 20.0, seedDistance, SlicOptions().minSize(0).iterations(40));
+
+        // exportImage(srcImageRange(labels), ImageExportInfo("slic.xv"));
+        importImage(ImageImportInfo("slic.xv"), destImage(labels_ref));
+
+        should(labels == labels_ref);
+    }
+};
+
+
+struct Slic2dTestSuite
+: public test_suite
+{
+    Slic2dTestSuite()
+    : test_suite("Slic2dTestSuite")
+    {
+        add( testCase( &SlicTest<2>::test_seeding));
+        add( testCase( &SlicTest<2>::test_slic));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    Slic2dTestSuite test;
+
+    int failed = test.run(testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+    return (failed != 0);
+}
+
diff --git a/test/tensorimaging/CMakeLists.txt b/test/tensorimaging/CMakeLists.txt
new file mode 100644
index 0000000..0179c31
--- /dev/null
+++ b/test/tensorimaging/CMakeLists.txt
@@ -0,0 +1,3 @@
+VIGRA_ADD_TEST(test_tensorimaging test.cxx LIBRARIES vigraimpex)
+
+VIGRA_COPY_TEST_DATA(l2.xv riesz00.xv riesz10.xv riesz01.xv riesz20.xv riesz11.xv riesz02.xv boundaryTensor.xv l2_boundary1.xv l2_boundary.xv l2_hourglass.xv l2_get.xv)
diff --git a/test/tensorimaging/boundaryTensor.xv b/test/tensorimaging/boundaryTensor.xv
new file mode 100755
index 0000000..7449d23
Binary files /dev/null and b/test/tensorimaging/boundaryTensor.xv differ
diff --git a/test/tensorimaging/l2.xv b/test/tensorimaging/l2.xv
new file mode 100755
index 0000000..4a2c339
Binary files /dev/null and b/test/tensorimaging/l2.xv differ
diff --git a/test/tensorimaging/l2_boundary.xv b/test/tensorimaging/l2_boundary.xv
new file mode 100755
index 0000000..049adde
Binary files /dev/null and b/test/tensorimaging/l2_boundary.xv differ
diff --git a/test/tensorimaging/l2_boundary1.xv b/test/tensorimaging/l2_boundary1.xv
new file mode 100755
index 0000000..dc5e982
Binary files /dev/null and b/test/tensorimaging/l2_boundary1.xv differ
diff --git a/test/tensorimaging/l2_get.xv b/test/tensorimaging/l2_get.xv
new file mode 100755
index 0000000..d59d7a4
Binary files /dev/null and b/test/tensorimaging/l2_get.xv differ
diff --git a/test/tensorimaging/l2_hourglass.xv b/test/tensorimaging/l2_hourglass.xv
new file mode 100644
index 0000000..e38a0e2
Binary files /dev/null and b/test/tensorimaging/l2_hourglass.xv differ
diff --git a/test/tensorimaging/riesz00.xv b/test/tensorimaging/riesz00.xv
new file mode 100755
index 0000000..a669dd6
Binary files /dev/null and b/test/tensorimaging/riesz00.xv differ
diff --git a/test/tensorimaging/riesz01.xv b/test/tensorimaging/riesz01.xv
new file mode 100755
index 0000000..0df463b
Binary files /dev/null and b/test/tensorimaging/riesz01.xv differ
diff --git a/test/tensorimaging/riesz02.xv b/test/tensorimaging/riesz02.xv
new file mode 100755
index 0000000..91d7617
Binary files /dev/null and b/test/tensorimaging/riesz02.xv differ
diff --git a/test/tensorimaging/riesz10.xv b/test/tensorimaging/riesz10.xv
new file mode 100755
index 0000000..7478562
Binary files /dev/null and b/test/tensorimaging/riesz10.xv differ
diff --git a/test/tensorimaging/riesz11.xv b/test/tensorimaging/riesz11.xv
new file mode 100755
index 0000000..021d081
Binary files /dev/null and b/test/tensorimaging/riesz11.xv differ
diff --git a/test/tensorimaging/riesz20.xv b/test/tensorimaging/riesz20.xv
new file mode 100755
index 0000000..d4a82c1
Binary files /dev/null and b/test/tensorimaging/riesz20.xv differ
diff --git a/test/tensorimaging/test.cxx b/test/tensorimaging/test.cxx
new file mode 100755
index 0000000..22a1692
--- /dev/null
+++ b/test/tensorimaging/test.cxx
@@ -0,0 +1,335 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+/* tensorimaging tests */
+
+#include <iostream>
+#include <functional>
+#include <cmath>
+#include "vigra/unittest.hxx"
+#include "vigra/stdimage.hxx"
+#include "vigra/impex.hxx"
+#include "vigra/tensorutilities.hxx"
+#include "vigra/orientedtensorfilters.hxx"
+#include "vigra/boundarytensor.hxx"
+#include "vigra/gradient_energy_tensor.hxx"
+#include "vigra/multi_array.hxx"
+#include "vigra/multi_math.hxx"
+
+using namespace vigra;
+
+struct TensorUtilityTest
+{
+    typedef vigra::MultiArray<2, double> Image;
+    typedef vigra::MultiArray<2, TinyVector<double, 2> > V2Image;
+    typedef vigra::MultiArray<2, TinyVector<double, 3> > V3Image;
+
+    TensorUtilityTest()
+    : w(5), h(5),
+      img2(Shape2(w, h)), img3(Shape2(w, h))
+    {
+        for(int y = 0; y < h; ++y)
+        {
+            for(int x = 0; x < w; ++x)
+            {
+                img2(x,y)[0] = x;
+                img2(x,y)[1] = y;
+            }
+        }
+        vectorToTensor(img2, img3);
+    }
+
+    void vector2TensorTest()
+    {
+        for(int y = 0; y < h; ++y)
+        {
+            for(int x = 0; x < w; ++x)
+            {
+                shouldEqual(img3(x,y)[0], x*x);
+                shouldEqual(img3(x,y)[1], x*y);
+                shouldEqual(img3(x,y)[2], y*y);
+            }
+        }
+    }
+    
+    void tensorEigenRepresentationTest()
+    {
+        V3Image res(img3.shape());
+        tensorEigenRepresentation(img3, res);
+        
+        for(int y = 0; y < h; ++y)
+        {
+            for(int x = 0; x < w; ++x)
+            {
+                shouldEqual(res(x,y)[0]+res(x,y)[1], img3(x,y)[0] + img3(x,y)[2]);
+                shouldEqual(res(x,y)[0]*res(x,y)[1], 
+                            img3(x,y)[0]*img3(x,y)[2]-sq(img3(x,y)[1]));
+                if(x == 0 && y == 0)
+                {
+                    shouldEqual(res(x,y)[2], 0.0);
+                }
+                else
+                {
+                    shouldEqualTolerance(res(x,y)[2], 
+                                    VIGRA_CSTD::atan2((double)y, (double)x), 1e-12);
+                }
+            }
+        }
+    }
+    
+    void tensorTraceTest()
+    {
+        Image res(img3.shape());
+        tensorTrace(img3, res);
+        
+        for(int y = 0; y < h; ++y)
+        {
+            for(int x = 0; x < w; ++x)
+            {
+                shouldEqual(res(x,y), img3(x,y)[0] + img3(x,y)[2]);
+            }
+        }
+    }
+    
+    
+    void tensorToEdgeCornerTest()
+    {
+        V2Image edge(img3.shape());
+        Image corner(img3.shape());
+        tensorToEdgeCorner(img3, edge, corner);
+        V3Image eigen(img3.shape());
+        tensorEigenRepresentation(img3, eigen);
+        
+        for(int y = 0; y < h; ++y)
+        {
+            for(int x = 0; x < w; ++x)
+            {
+                shouldEqual(edge(x,y)[0], eigen(x,y)[0]-eigen(x,y)[1]);
+                shouldEqual(edge(x,y)[1], eigen(x,y)[2]);
+                shouldEqual(corner(x,y), 2.0*eigen(x,y)[1]);
+            }
+        }
+    }
+    
+    int w, h;
+    V2Image img2;
+    V3Image img3;    
+};
+
+#define defImpulseResponseTest(xorder, yorder) \
+    void rieszTransform##xorder##yorder##Test() \
+    { \
+        Image res(img1.size()), ref(img1.size()); \
+        ImageImportInfo iref("riesz" #xorder #yorder ".xv"); \
+        importImage(iref, destImage(ref)); \
+        \
+        rieszTransformOfLOG(srcImageRange(img1), destImage(res), 2.0, xorder, yorder); \
+        \
+        shouldEqualSequenceTolerance(res.begin(), res.end(), ref.begin(), 1e-12); \
+        \
+        res.init(0.0); \
+        rieszTransformOfLOG(View(img1), View(res), 2.0, xorder, yorder); \
+        \
+        shouldEqualSequenceTolerance(res.begin(), res.end(), ref.begin(), 1e-12); \
+    } \
+    
+
+
+struct EdgeJunctionTensorTest
+{
+    typedef vigra::DImage Image;
+    typedef vigra::MultiArrayView<2, double> View;
+    typedef vigra::DVector2Image V2Image;
+    typedef vigra::DVector3Image V3Image;
+    typedef vigra::MultiArrayView<2, TinyVector<double, 3> > View3;
+
+    EdgeJunctionTensorTest()
+    : img1(17, 17)
+    {
+        img1.init(0.0);
+        img1(8,8) = 1.0;
+
+        ImageImportInfo i2("l2.xv");
+        img2.resize(i2.size());
+        importImage(i2, destImage(img2));
+    }
+
+    defImpulseResponseTest(0, 0)
+    defImpulseResponseTest(1, 0)
+    defImpulseResponseTest(0, 1)
+    defImpulseResponseTest(2, 0)
+    defImpulseResponseTest(1, 1)
+    defImpulseResponseTest(0, 2)
+
+    void boundaryTensorTest0()
+    {
+        V3Image res(img1.size()), res1(img1.size()), ref(img1.size());
+        ImageImportInfo iref("boundaryTensor.xv");
+        importImage(iref, destImage(ref));
+        
+        boundaryTensor(srcImageRange(img1), destImage(res), 2.0);
+        boundaryTensor(View(img1), View3(res1), 2.0);
+        
+        for(V3Image::iterator i = res.begin(), j = res1.begin(), k = ref.begin(); i < res.end(); ++i, ++j, ++k)
+        {
+            shouldEqualTolerance(i->magnitude(), k->magnitude(), 1e-12);
+            shouldEqualTolerance(j->magnitude(), k->magnitude(), 1e-12);
+        }
+    }
+
+    void boundaryTensorTest1()
+    {
+        V3Image bt(img2.size()), bt1(img2.size());
+        Image res(img2.size()), res1(img2.size()), ref(img2.size());
+        ImageImportInfo iref("l2_boundary1.xv");
+        importImage(iref, destImage(ref));
+
+        boundaryTensor1(srcImageRange(img2), destImage(bt), 2.0);
+        tensorTrace(srcImageRange(bt), destImage(res));
+        
+        shouldEqualSequenceTolerance(res.begin(), res.end(), ref.begin(), 1e-12);
+
+        boundaryTensor1(View(img2), View3(bt1), 2.0);
+        tensorTrace(View3(bt1), View(res1));
+        
+        shouldEqualSequenceTolerance(res1.begin(), res1.end(), ref.begin(), 1e-12);
+    }
+
+    void boundaryTensorTest2()
+    {
+        V3Image bt(img2.size());
+        Image res(img2.size()), ref(img2.size());
+        ImageImportInfo iref("l2_boundary.xv");
+        importImage(iref, destImage(ref));
+
+        boundaryTensor(View(img2), View3(bt), 2.0);
+        tensorTrace(View3(bt), View(res));
+        
+        shouldEqualSequenceTolerance(res.begin(), res.end(), ref.begin(), 1e-12);
+    }
+
+    void boundaryTensorTest3()
+    {
+        // does not produce the correct result
+        Image res(img2.size());
+        {
+            V3Image bt(img2.size()), bt2(img2.size());
+
+            boundaryTensor3(srcImageRange(img2), destImage(bt), destImage(bt2), 1.0);
+            combineTwoImages(srcImageRange(bt), srcImage(bt2), destImage(bt2), 
+                         std::plus<V3Image::value_type>());
+            tensorTrace(srcImageRange(bt2), destImage(res));
+        }
+        Image ref(img2.size());
+        ImageImportInfo iref("l2_boundary3.xv");
+        importImage(iref, destImage(ref));
+
+        shouldEqualSequenceTolerance(res.begin(), res.end(), ref.begin(), 1e-12);
+    }
+    
+    void hourglassTest()
+    {
+        V2Image gradient(img2.size());
+        V3Image tensor(img2.size()), smoothedTensor(img2.size());
+        Image res(img2.size()), ref(img2.size());
+        ImageImportInfo iref("l2_hourglass.xv");
+        importImage(iref, destImage(ref));
+
+        gaussianGradient(srcImageRange(img2), destImage(gradient), 0.7);
+        vectorToTensor(srcImageRange(gradient), destImage(tensor));
+        hourGlassFilter(View3(tensor), View3(smoothedTensor), 2.8, 0.4);
+        tensorTrace(srcImageRange(smoothedTensor), destImage(res));
+  
+        shouldEqualSequenceTolerance(res.begin(), res.end(), ref.begin(), 1e-12);
+    }
+
+    void energyTensorTest()
+    {
+        using namespace functor;
+        
+        V3Image get(img2.size());
+        Image res(img2.size()), ref(img2.size());
+        ImageImportInfo iref("l2_get.xv");
+        importImage(iref, destImage(ref));
+
+        Kernel1D<double> smooth, grad;
+        smooth.initGaussian(1.0);
+        grad.initGaussianDerivative(1.0, 1);
+        gradientEnergyTensor(View(img2), View3(get), grad, smooth);
+        tensorTrace(View3(get), View(res));
+
+        using namespace multi_math;
+        should(all(View(res) - View(ref) < 1e-12));
+    }
+
+    Image img1, img2;
+};
+
+struct TensorTestSuite
+: public vigra::test_suite
+{
+    TensorTestSuite()
+    : vigra::test_suite("TensorTestSuite")
+    {
+        add( testCase( &TensorUtilityTest::vector2TensorTest));
+        add( testCase( &TensorUtilityTest::tensorEigenRepresentationTest));
+        add( testCase( &TensorUtilityTest::tensorTraceTest));
+        add( testCase( &TensorUtilityTest::tensorToEdgeCornerTest));
+
+        add( testCase( &EdgeJunctionTensorTest::rieszTransform00Test));
+        add( testCase( &EdgeJunctionTensorTest::rieszTransform10Test));
+        add( testCase( &EdgeJunctionTensorTest::rieszTransform01Test));
+        add( testCase( &EdgeJunctionTensorTest::rieszTransform20Test));
+        add( testCase( &EdgeJunctionTensorTest::rieszTransform11Test));
+        add( testCase( &EdgeJunctionTensorTest::rieszTransform02Test));
+        add( testCase( &EdgeJunctionTensorTest::boundaryTensorTest0));
+        add( testCase( &EdgeJunctionTensorTest::boundaryTensorTest1));
+        add( testCase( &EdgeJunctionTensorTest::boundaryTensorTest2));
+        add( testCase( &EdgeJunctionTensorTest::hourglassTest));
+        add( testCase( &EdgeJunctionTensorTest::energyTensorTest));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    TensorTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+
+    return (failed != 0);
+}
+
diff --git a/test/unsupervised/CMakeLists.txt b/test/unsupervised/CMakeLists.txt
new file mode 100644
index 0000000..9020141
--- /dev/null
+++ b/test/unsupervised/CMakeLists.txt
@@ -0,0 +1,15 @@
+VIGRA_ADD_TEST(test_unsupervised test.cxx)
+
+# the data from 'example_data.h5' are now in 'test_data.hxx', so HDF5 is
+# no longer needed for this test
+# if(HDF5_FOUND)
+    # INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIR})
+  
+    # ADD_DEFINITIONS(${HDF5_CPPFLAGS})
+
+    # VIGRA_ADD_TEST(test_unsupervised test.cxx LIBRARIES vigraimpex ${HDF5_LIBRARIES})
+    
+    # VIGRA_COPY_TEST_DATA(example_data.h5)
+# else()
+    # MESSAGE(STATUS "** WARNING: test_unsupervised will not be executed")
+# endif()
\ No newline at end of file
diff --git a/test/unsupervised/example_data.h5 b/test/unsupervised/example_data.h5
new file mode 100644
index 0000000..dfe8e9d
Binary files /dev/null and b/test/unsupervised/example_data.h5 differ
diff --git a/test/unsupervised/test.cxx b/test/unsupervised/test.cxx
new file mode 100644
index 0000000..a2f5f2a
--- /dev/null
+++ b/test/unsupervised/test.cxx
@@ -0,0 +1,184 @@
+/************************************************************************/
+/*                                                                      */
+/*    Copyright 2008-2011 by Michael Hanselmann and Ullrich Koethe      */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+#define UNSUPERVISED_TEST 1
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4244)
+#endif
+
+#include <iostream>
+#include <fstream>
+#include <functional>
+#include <cmath>
+#include <vigra/unsupervised_decomposition.hxx>
+#include <vigra/unittest.hxx>
+#include <vector>
+#include <limits>
+#include "test_data.hxx"
+
+
+#include <stdlib.h>
+
+using namespace vigra;
+
+
+class UnsupervisedDecompositionTest
+{
+
+public:
+
+    UnsupervisedDecompositionTest()
+    {}
+
+    void testPCADecomposition()
+    {
+        unsigned int numComponents = 3;
+        unsigned int numFeatures = 159;
+        unsigned int numSamples = 1024;
+
+        Matrix<double> features(numFeatures, numSamples, plsaData, ColumnMajor);
+        Matrix<double> fz(Shape2(numFeatures, numComponents));
+        Matrix<double> zv(Shape2(numComponents, numSamples));
+
+        prepareRows(features, features, ZeroMean);
+
+        principleComponents(features, fz, zv);
+
+        Matrix<double> model = fz*zv;
+        shouldEqualTolerance(squaredNorm(model-features), 1530214.34284834, 1e-10);
+
+#if 0
+        char hdf5File_2[] = "example_data_results.h5";
+        char hdf5group_2[] = "FZ";
+        char hdf5group_3[] = "ZV";
+        writeHDF5(hdf5File_2, hdf5group_2, fz);
+        writeHDF5(hdf5File_2, hdf5group_3, zv);
+#endif    
+    }
+
+    void testPLSADecomposition()
+    {
+#if 0 // load data fro, HDF5 file
+        char hdf5File[] = "example_data.h5";
+        char hdf5group[] = "volume/data";
+
+        HDF5ImportInfo infoHDF5(hdf5File, hdf5group);
+        unsigned int numComponents = 3;
+        unsigned int numFeatures = infoHDF5.shapeOfDimension(0);
+        unsigned int numSamples = infoHDF5.shapeOfDimension(1);
+
+        Matrix<double> features(Shape2(numFeatures, numSamples));
+        readHDF5(infoHDF5, features);
+#else // get data from header file
+        unsigned int numComponents = 3;
+        unsigned int numFeatures = 159;
+        unsigned int numSamples = 1024;
+
+        Matrix<double> features(numFeatures, numSamples, plsaData, ColumnMajor);
+#endif
+        Matrix<double> fz(Shape2(numFeatures, numComponents));
+        Matrix<double> zv(Shape2(numComponents, numSamples));
+
+        pLSA(features, fz, zv, PLSAOptions().normalizedComponentWeights(false));
+
+        // TESTS
+        // -----
+        double eps = 1e-10;
+
+        // test if result matrices (approximately) satisfy normalization properties
+        Matrix<double> colSumFZ = fz.sum(0);
+        for(int i=0; i<columnCount(fz); ++i)
+        {
+            shouldEqualTolerance( colSumFZ(0,i), 1, eps );
+        }
+        Matrix<double> colSumZV = zv.sum(0);
+        Matrix<double> colSumFeat = features.sum(0);
+        for(int i=0; i<columnCount(zv); ++i)
+        {
+            shouldEqualTolerance( colSumZV(0,i) / colSumFeat(0, i), 1, eps );
+        }
+        // all entries in FZ, ZV are >= 0
+        for(int j=0; j<columnCount(zv); ++j)
+        {
+            for(int i=0; i<rowCount(zv); ++i)
+            {
+                should ( zv(i, j) >= 0 );
+            }
+        }
+        for(int j=0; j<columnCount(fz); ++j)
+        {
+            for(int i=0; i<rowCount(fz); ++i)
+            {
+                should ( fz(i, j) >= 0 );
+            }
+        }
+
+        // test if reconstruction is close to original
+        // tricky - how to properly test that? it will never be identical!
+        Matrix<double> model = fz*zv; 
+        double meanError = (features - model).squaredNorm() / columnCount(features);
+        should ( meanError < 5000 );
+
+#if 0
+        char hdf5File_2[] = "example_data_results.h5";
+        char hdf5group_2[] = "FZ";
+        char hdf5group_3[] = "ZV";
+        writeHDF5(hdf5File_2, hdf5group_2, fz);
+        writeHDF5(hdf5File_2, hdf5group_3, zv);
+#endif    
+    }
+};
+
+
+
+struct UnsupervisedDecompositionTestSuite : public vigra::test_suite
+{
+    UnsupervisedDecompositionTestSuite()
+        : vigra::test_suite("UnsupervisedDecompositionTestSuite")
+    {
+        add(testCase(&UnsupervisedDecompositionTest::testPCADecomposition));
+        add(testCase(&UnsupervisedDecompositionTest::testPLSADecomposition));
+    }
+};
+
+
+int main (int argc, char ** argv)
+{
+    UnsupervisedDecompositionTestSuite test;
+    const int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+    std::cout << test.report() << std::endl;
+
+    return failed != 0;
+}
diff --git a/test/unsupervised/test_data.hxx b/test/unsupervised/test_data.hxx
new file mode 100644
index 0000000..f72054e
--- /dev/null
+++ b/test/unsupervised/test_data.hxx
@@ -0,0 +1,2090 @@
+/************************************************************************/
+/*                                                                      */
+/*                Copyright 2011 by Ullrich Koethe                      */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_UNSUPERVISED_TEST_DATA_HXX
+#define VIGRA_UNSUPERVISED_TEST_DATA_HXX
+
+
+double plsaData[1024*159] = {
+12., 2., 4., 14., 24., 7., 40., 0., 14., 153., 6., 35., 231., 5., 11., 6., 1., 5., 70., 1., 18., 272., 48., 345., 33., 9., 2., 0., 7., 2., 50., 35., 223., 43., 9., 155., 12., 32., 3., 0., 1., 14., 7., 72., 27., 86., 13., 30., 43., 16., 3., 0., 14., 5., 43., 2., 44., 8., 30., 7., 12., 6., 0., 0., 0., 0., 34., 3., 18., 5., 29., 9., 11., 4., 0., 6., 3., 0., 1., 2., 11., 2., 15., 1., 11., 0., 0., 5., 122., 7., 1902., 86., 107., 248., 118., 105., 74., 13., 10., 19., 12., 2., 1., 7., 10., 4.,  [...]
+
+13., 1., 3., 5., 36., 8., 24., 2., 13., 169., 3., 30., 202., 6., 24., 3., 1., 2., 70., 0., 14., 308., 50., 316., 39., 18., 1., 0., 8., 5., 36., 32., 232., 36., 6., 161., 15., 39., 6., 0., 3., 17., 9., 66., 19., 88., 9., 33., 50., 8., 2., 2., 31., 5., 38., 12., 46., 10., 27., 4., 18., 8., 3., 0., 2., 0., 24., 3., 17., 0., 27., 8., 20., 4., 0., 1., 1., 1., 0., 4., 14., 2., 7., 1., 3., 1., 1., 3., 130., 5., 1930., 80., 105., 200., 118., 127., 64., 12., 12., 19., 12., 3., 2., 9., 7., 6., 9., [...]
+
+9., 3., 4., 8., 27., 4., 32., 1., 13., 163., 0., 35., 176., 6., 12., 3., 5., 5., 78., 0., 21., 260., 48., 303., 38., 15., 1., 2., 7., 7., 43., 33., 238., 36., 9., 163., 13., 31., 1., 0., 4., 26., 9., 79., 18., 81., 15., 34., 38., 12., 3., 1., 28., 5., 27., 15., 56., 9., 35., 4., 8., 8., 3., 0., 1., 0., 25., 4., 12., 3., 35., 3., 8., 3., 0., 2., 2., 2., 2., 1., 10., 5., 16., 5., 10., 1., 0., 6., 139., 7., 1813., 76., 103., 223., 102., 116., 59., 17., 11., 21., 8., 0., 1., 5., 5., 3., 15., [...]
+
+13., 3., 5., 7., 31., 4., 38., 1., 14., 159., 4., 30., 181., 2., 18., 6., 1., 4., 78., 4., 15., 297., 38., 284., 31., 18., 0., 0., 6., 5., 46., 28., 235., 41., 12., 157., 19., 47., 3., 0., 2., 16., 4., 92., 13., 88., 16., 28., 48., 5., 5., 5., 26., 5., 40., 12., 58., 8., 28., 2., 10., 4., 3., 0., 1., 0., 14., 7., 13., 0., 32., 4., 14., 6., 3., 4., 2., 1., 2., 2., 11., 3., 9., 3., 9., 0., 2., 5., 160., 13., 1942., 112., 86., 230., 93., 118., 61., 17., 10., 18., 12., 1., 4., 4., 5., 3., 13 [...]
+
+10., 0., 4., 5., 28., 7., 32., 2., 11., 159., 5., 29., 200., 2., 17., 9., 0., 8., 62., 8., 24., 322., 42., 328., 55., 13., 2., 1., 8., 4., 37., 30., 253., 43., 9., 172., 12., 26., 6., 0., 2., 24., 11., 91., 18., 105., 13., 34., 40., 24., 3., 1., 26., 8., 34., 10., 47., 10., 32., 5., 8., 7., 5., 0., 0., 0., 19., 3., 16., 6., 30., 5., 11., 3., 2., 7., 0., 2., 2., 5., 10., 3., 4., 4., 7., 3., 1., 9., 144., 11., 1896., 107., 117., 222., 89., 99., 68., 11., 10., 9., 16., 0., 1., 9., 5., 3., 9 [...]
+
+13., 1., 3., 8., 24., 7., 24., 1., 20., 163., 4., 24., 210., 3., 8., 7., 0., 6., 73., 1., 13., 304., 53., 296., 38., 25., 0., 3., 7., 4., 45., 38., 230., 29., 6., 152., 14., 59., 6., 0., 2., 11., 9., 78., 11., 104., 10., 29., 57., 20., 7., 1., 27., 8., 28., 6., 35., 8., 24., 10., 8., 11., 1., 0., 0., 0., 23., 8., 16., 4., 35., 3., 10., 4., 2., 7., 0., 2., 5., 5., 14., 3., 6., 3., 6., 0., 0., 7., 135., 8., 1842., 96., 96., 222., 101., 106., 79., 16., 12., 23., 11., 1., 1., 6., 9., 10., 10 [...]
+
+10., 2., 2., 6., 26., 4., 35., 1., 12., 177., 5., 26., 194., 3., 12., 10., 0., 9., 79., 3., 18., 302., 51., 304., 40., 22., 0., 2., 9., 4., 35., 32., 233., 41., 6., 155., 14., 36., 6., 0., 2., 18., 5., 89., 18., 102., 10., 28., 43., 7., 4., 2., 23., 6., 36., 12., 45., 5., 34., 12., 7., 12., 4., 0., 0., 0., 23., 5., 15., 5., 30., 3., 11., 5., 2., 5., 1., 2., 3., 1., 7., 4., 10., 3., 14., 3., 0., 6., 137., 10., 1802., 102., 94., 256., 93., 123., 52., 12., 12., 23., 16., 2., 5., 5., 3., 4., [...]
+
+20., 3., 2., 8., 25., 8., 33., 1., 22., 157., 5., 29., 208., 5., 13., 7., 0., 5., 85., 2., 15., 318., 49., 335., 49., 23., 1., 4., 5., 3., 40., 37., 248., 33., 10., 146., 17., 40., 7., 0., 1., 10., 4., 93., 17., 110., 23., 24., 44., 12., 1., 0., 24., 9., 40., 9., 54., 10., 29., 11., 15., 9., 3., 0., 1., 0., 20., 8., 15., 2., 27., 8., 9., 8., 2., 1., 1., 0., 2., 3., 5., 0., 15., 1., 7., 0., 1., 3., 129., 8., 1856., 89., 117., 226., 108., 109., 68., 11., 12., 23., 10., 0., 1., 7., 5., 0.,  [...]
+
+15., 4., 0., 9., 20., 3., 30., 1., 11., 146., 4., 35., 199., 6., 19., 6., 1., 7., 78., 1., 15., 308., 40., 345., 44., 15., 2., 2., 6., 2., 41., 24., 233., 42., 7., 161., 6., 35., 10., 0., 1., 23., 7., 70., 28., 84., 5., 38., 45., 20., 2., 1., 26., 9., 25., 7., 44., 5., 20., 5., 9., 7., 2., 0., 1., 0., 21., 2., 15., 5., 21., 2., 11., 7., 1., 6., 0., 1., 1., 3., 13., 2., 11., 0., 7., 1., 0., 4., 138., 6., 1833., 98., 98., 233., 107., 115., 67., 20., 8., 21., 9., 0., 2., 4., 7., 2., 7., 9., [...]
+
+19., 1., 3., 3., 24., 3., 30., 0., 17., 163., 8., 27., 227., 3., 15., 6., 2., 6., 78., 0., 13., 268., 40., 324., 39., 17., 3., 2., 8., 7., 47., 38., 225., 40., 4., 166., 10., 48., 5., 0., 4., 10., 10., 72., 22., 79., 22., 40., 45., 12., 2., 2., 17., 4., 45., 8., 40., 9., 32., 6., 17., 5., 1., 0., 0., 0., 34., 2., 14., 0., 26., 2., 15., 6., 2., 2., 1., 2., 5., 3., 13., 3., 6., 1., 10., 1., 0., 6., 139., 9., 1919., 100., 88., 241., 99., 110., 72., 15., 14., 15., 8., 0., 2., 9., 10., 3., 7. [...]
+
+7., 1., 6., 9., 18., 11., 35., 2., 10., 126., 2., 27., 197., 4., 14., 5., 2., 5., 92., 1., 16., 270., 44., 310., 42., 19., 0., 1., 4., 4., 34., 32., 270., 37., 7., 160., 16., 46., 3., 0., 3., 18., 6., 73., 20., 73., 15., 36., 33., 6., 5., 0., 24., 5., 31., 14., 51., 10., 40., 7., 12., 7., 1., 0., 3., 0., 17., 4., 13., 2., 25., 5., 9., 2., 4., 2., 0., 0., 2., 2., 5., 1., 10., 1., 10., 1., 2., 4., 145., 8., 1808., 102., 113., 210., 95., 107., 63., 10., 15., 10., 8., 2., 2., 7., 4., 5., 6., [...]
+
+16., 1., 3., 7., 8., 6., 28., 1., 8., 171., 3., 29., 206., 3., 18., 4., 2., 4., 84., 3., 16., 305., 47., 305., 45., 22., 1., 1., 8., 5., 53., 28., 223., 53., 11., 146., 7., 37., 6., 0., 2., 14., 5., 78., 22., 88., 11., 30., 40., 12., 2., 0., 20., 7., 39., 12., 31., 6., 31., 6., 9., 5., 2., 0., 0., 0., 17., 10., 17., 5., 24., 3., 8., 5., 1., 5., 2., 0., 3., 3., 9., 4., 8., 0., 12., 1., 1., 2., 169., 4., 1900., 98., 111., 215., 99., 91., 64., 19., 10., 19., 8., 1., 0., 5., 7., 2., 6., 7.,  [...]
+
+14., 3., 4., 4., 26., 5., 32., 0., 26., 153., 3., 17., 190., 5., 13., 7., 4., 6., 68., 4., 18., 292., 54., 344., 35., 16., 1., 2., 10., 3., 38., 43., 249., 39., 10., 152., 18., 37., 4., 0., 2., 13., 5., 81., 21., 84., 15., 47., 42., 7., 2., 2., 24., 6., 32., 10., 44., 15., 24., 9., 8., 8., 1., 0., 1., 0., 30., 8., 10., 4., 33., 2., 13., 6., 3., 2., 0., 2., 5., 1., 6., 6., 8., 0., 6., 1., 0., 1., 134., 5., 1787., 98., 98., 235., 98., 130., 67., 13., 12., 16., 10., 1., 2., 4., 7., 4., 11., [...]
+
+11., 3., 3., 7., 24., 5., 27., 1., 17., 141., 1., 21., 198., 6., 14., 7., 0., 8., 81., 1., 8., 301., 47., 300., 42., 21., 2., 1., 11., 5., 51., 30., 215., 45., 4., 151., 15., 43., 3., 0., 1., 18., 8., 81., 22., 76., 8., 33., 62., 19., 0., 2., 28., 7., 34., 12., 53., 6., 31., 12., 14., 8., 2., 0., 2., 0., 17., 4., 20., 5., 27., 5., 11., 4., 5., 4., 0., 3., 0., 1., 10., 3., 4., 3., 10., 0., 0., 5., 131., 10., 1839., 90., 97., 202., 106., 128., 60., 25., 12., 25., 12., 0., 3., 2., 6., 4., 9 [...]
+
+10., 2., 4., 15., 21., 10., 26., 1., 14., 154., 2., 17., 179., 4., 16., 11., 3., 5., 75., 3., 17., 282., 33., 275., 44., 22., 1., 1., 4., 3., 49., 33., 261., 43., 5., 163., 14., 50., 6., 0., 3., 23., 5., 81., 14., 69., 13., 45., 35., 7., 5., 2., 26., 7., 32., 8., 39., 10., 40., 8., 8., 3., 2., 0., 2., 0., 15., 7., 19., 6., 30., 3., 13., 3., 1., 2., 1., 1., 1., 1., 13., 1., 10., 1., 5., 1., 0., 6., 153., 7., 1929., 98., 114., 218., 112., 115., 73., 18., 19., 23., 6., 1., 2., 4., 2., 1., 1 [...]
+
+12., 2., 4., 9., 30., 4., 34., 0., 16., 159., 4., 40., 196., 6., 18., 6., 1., 6., 69., 3., 14., 295., 41., 353., 52., 16., 1., 5., 9., 5., 41., 27., 234., 47., 2., 147., 10., 40., 10., 0., 3., 22., 9., 72., 29., 101., 18., 40., 27., 10., 7., 1., 19., 5., 34., 11., 59., 12., 26., 7., 8., 5., 3., 0., 1., 0., 27., 5., 15., 3., 31., 7., 14., 2., 2., 2., 0., 1., 2., 3., 8., 2., 7., 1., 7., 2., 0., 3., 118., 11., 1952., 87., 92., 213., 110., 104., 73., 13., 19., 15., 11., 1., 2., 3., 2., 3., 1 [...]
+
+13., 3., 4., 6., 24., 6., 37., 3., 19., 189., 6., 30., 182., 3., 18., 7., 1., 3., 93., 3., 15., 322., 41., 332., 37., 16., 1., 1., 6., 4., 37., 34., 231., 37., 5., 170., 15., 42., 6., 0., 2., 25., 7., 81., 20., 81., 18., 18., 43., 9., 3., 0., 26., 2., 34., 7., 47., 7., 35., 5., 13., 2., 0., 0., 0., 0., 18., 6., 13., 5., 24., 8., 9., 9., 0., 3., 2., 1., 7., 2., 12., 5., 11., 3., 10., 2., 2., 3., 144., 5., 1829., 86., 86., 251., 90., 112., 60., 20., 11., 18., 12., 0., 2., 6., 9., 2., 7., 6 [...]
+
+9., 1., 3., 9., 29., 5., 27., 2., 22., 164., 4., 34., 227., 4., 14., 5., 0., 4., 66., 0., 16., 294., 56., 351., 33., 21., 1., 3., 7., 2., 34., 31., 224., 37., 8., 175., 7., 30., 8., 0., 1., 18., 9., 85., 15., 82., 9., 35., 52., 10., 2., 0., 28., 8., 43., 8., 48., 10., 47., 5., 11., 1., 6., 0., 3., 0., 22., 2., 10., 2., 29., 2., 6., 6., 1., 3., 2., 2., 3., 3., 12., 2., 9., 1., 9., 2., 1., 5., 142., 6., 1903., 90., 119., 217., 94., 122., 80., 18., 5., 17., 23., 0., 3., 9., 10., 3., 8., 11. [...]
+
+13., 2., 1., 9., 28., 9., 19., 3., 14., 154., 1., 33., 187., 3., 15., 7., 1., 7., 98., 2., 24., 298., 51., 344., 39., 21., 2., 0., 8., 4., 39., 30., 235., 44., 7., 149., 14., 40., 6., 0., 2., 17., 6., 90., 15., 75., 12., 27., 45., 18., 4., 1., 16., 9., 46., 8., 27., 8., 24., 8., 7., 6., 2., 0., 2., 0., 20., 2., 15., 1., 31., 4., 8., 2., 0., 3., 0., 1., 4., 1., 9., 3., 12., 1., 7., 2., 4., 3., 129., 10., 1955., 91., 95., 212., 102., 118., 78., 19., 10., 22., 11., 0., 0., 9., 6., 4., 7., 7 [...]
+
+9., 3., 4., 7., 35., 2., 31., 2., 18., 155., 5., 25., 206., 6., 22., 11., 2., 7., 79., 1., 20., 314., 42., 335., 46., 17., 2., 5., 11., 6., 47., 42., 212., 38., 5., 153., 17., 32., 10., 0., 1., 19., 8., 83., 12., 76., 13., 33., 44., 10., 3., 1., 21., 6., 27., 13., 40., 10., 23., 3., 12., 5., 3., 0., 1., 0., 27., 9., 14., 4., 28., 1., 10., 2., 1., 4., 1., 0., 3., 3., 7., 3., 10., 0., 12., 1., 0., 2., 139., 9., 1988., 99., 111., 223., 98., 115., 84., 13., 17., 14., 8., 2., 2., 6., 9., 8.,  [...]
+
+7., 1., 4., 5., 31., 5., 39., 1., 14., 172., 0., 24., 215., 3., 12., 7., 1., 3., 92., 2., 14., 287., 41., 332., 44., 25., 1., 0., 5., 9., 44., 40., 202., 50., 3., 150., 10., 39., 6., 0., 3., 20., 12., 69., 13., 82., 18., 23., 54., 9., 4., 0., 22., 6., 27., 13., 57., 5., 25., 5., 9., 7., 4., 0., 0., 0., 33., 6., 12., 1., 39., 5., 11., 5., 2., 2., 0., 0., 5., 4., 15., 4., 10., 2., 14., 0., 0., 4., 146., 5., 1815., 116., 105., 204., 106., 128., 78., 16., 12., 17., 10., 0., 3., 4., 10., 5.,  [...]
+
+17., 1., 2., 5., 31., 6., 23., 1., 16., 147., 1., 23., 231., 6., 19., 5., 2., 3., 78., 0., 11., 296., 47., 345., 45., 15., 2., 1., 8., 4., 52., 32., 239., 36., 7., 167., 10., 32., 5., 0., 1., 18., 8., 90., 22., 77., 21., 43., 38., 19., 3., 3., 28., 5., 39., 13., 48., 12., 31., 3., 10., 11., 2., 0., 2., 0., 17., 3., 16., 5., 24., 5., 8., 7., 0., 6., 1., 2., 1., 1., 9., 3., 9., 5., 11., 3., 1., 5., 129., 8., 1937., 89., 88., 230., 92., 121., 58., 17., 11., 21., 14., 1., 1., 8., 7., 6., 6., [...]
+
+15., 0., 4., 12., 29., 4., 41., 0., 16., 128., 4., 28., 210., 15., 19., 6., 0., 8., 84., 1., 25., 266., 44., 369., 53., 19., 2., 2., 8., 6., 44., 27., 255., 44., 7., 166., 12., 37., 9., 0., 1., 7., 6., 70., 17., 84., 22., 32., 42., 15., 4., 1., 24., 4., 51., 7., 51., 7., 30., 1., 9., 8., 3., 0., 3., 0., 22., 6., 17., 5., 28., 4., 9., 5., 1., 4., 3., 1., 3., 2., 10., 5., 10., 3., 11., 1., 2., 7., 147., 11., 1938., 82., 109., 219., 108., 122., 68., 23., 9., 24., 15., 0., 2., 6., 6., 2., 7. [...]
+
+12., 0., 2., 6., 31., 3., 19., 1., 12., 160., 7., 30., 189., 8., 17., 6., 0., 5., 99., 2., 16., 292., 52., 364., 31., 17., 0., 4., 4., 6., 50., 39., 259., 40., 10., 131., 19., 40., 2., 0., 2., 25., 5., 93., 20., 97., 10., 32., 43., 17., 3., 2., 24., 6., 43., 5., 48., 8., 34., 4., 6., 4., 1., 0., 1., 0., 21., 5., 15., 4., 34., 6., 16., 7., 1., 4., 0., 1., 6., 1., 15., 1., 6., 2., 10., 1., 2., 4., 137., 16., 1901., 106., 99., 229., 88., 110., 75., 15., 11., 14., 14., 1., 3., 7., 4., 6., 13 [...]
+
+14., 1., 2., 10., 28., 5., 42., 0., 14., 166., 1., 27., 215., 2., 11., 7., 0., 5., 76., 0., 19., 317., 38., 337., 38., 19., 1., 2., 11., 4., 59., 36., 231., 30., 14., 165., 19., 45., 3., 0., 1., 18., 10., 78., 23., 86., 18., 42., 51., 15., 3., 0., 17., 7., 35., 14., 42., 11., 33., 8., 8., 9., 3., 0., 1., 0., 20., 5., 15., 5., 25., 8., 12., 2., 1., 0., 1., 2., 1., 3., 9., 3., 7., 0., 8., 1., 0., 5., 143., 7., 1949., 88., 98., 192., 84., 126., 72., 19., 9., 19., 5., 0., 3., 5., 1., 4., 12. [...]
+
+16., 2., 4., 8., 30., 7., 25., 0., 16., 170., 3., 26., 206., 10., 13., 7., 1., 5., 63., 1., 15., 263., 37., 314., 40., 21., 1., 1., 11., 7., 35., 31., 233., 37., 8., 140., 12., 41., 7., 0., 2., 17., 6., 85., 17., 86., 15., 33., 50., 14., 2., 1., 19., 6., 59., 10., 60., 7., 31., 8., 13., 8., 4., 0., 1., 0., 22., 3., 16., 2., 23., 4., 11., 4., 3., 1., 0., 0., 2., 2., 6., 1., 5., 2., 12., 1., 0., 5., 135., 6., 1840., 92., 93., 227., 91., 107., 65., 20., 10., 19., 12., 0., 6., 5., 5., 7., 8. [...]
+
+11., 1., 3., 2., 13., 6., 6., 0., 5., 29., 2., 12., 29., 0., 16., 2., 2., 2., 18., 1., 5., 13., 13., 25., 38., 6., 0., 1., 3., 1., 10., 10., 17., 7., 3., 17., 3., 15., 7., 2., 1., 2., 2., 9., 14., 13., 41., 7., 22., 9., 3., 0., 3., 3., 14., 1., 8., 4., 8., 18., 7., 19., 10., 4., 1., 1., 11., 1., 3., 3., 8., 5., 4., 4., 3., 4., 5., 2., 0., 5., 5., 0., 0., 1., 1., 4., 5., 2., 3., 3., 3., 1., 3., 0., 1., 4., 2., 0., 1., 3., 4., 3., 0., 3., 2., 2., 2., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., [...]
+
+10., 3., 2., 3., 2., 0., 6., 1., 8., 10., 0., 16., 10., 0., 12., 1., 1., 2., 10., 3., 1., 18., 17., 21., 31., 6., 1., 2., 2., 1., 8., 11., 28., 13., 1., 11., 6., 18., 11., 5., 1., 1., 1., 21., 10., 14., 38., 13., 14., 8., 5., 0., 5., 1., 5., 2., 9., 13., 5., 19., 4., 29., 6., 0., 0., 1., 6., 1., 0., 1., 7., 4., 6., 4., 3., 9., 4., 3., 1., 2., 4., 0., 5., 0., 1., 2., 0., 5., 6., 5., 4., 0., 0., 3., 1., 4., 4., 0., 2., 5., 2., 2., 3., 5., 1., 1., 0., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., [...]
+
+8., 1., 2., 5., 10., 6., 4., 1., 8., 16., 1., 8., 17., 1., 27., 3., 2., 3., 22., 0., 7., 31., 10., 28., 29., 8., 0., 0., 1., 2., 9., 5., 37., 26., 3., 15., 4., 15., 12., 0., 2., 4., 2., 21., 15., 19., 51., 7., 25., 11., 3., 0., 3., 1., 16., 6., 12., 7., 4., 14., 11., 22., 11., 3., 1., 0., 0., 1., 1., 3., 3., 1., 2., 5., 1., 2., 2., 4., 1., 1., 2., 0., 4., 2., 3., 3., 1., 4., 2., 1., 3., 0., 2., 1., 3., 4., 0., 0., 0., 1., 0., 4., 1., 1., 0., 0., 3., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0. [...]
+
+13., 1., 2., 4., 10., 4., 15., 0., 5., 18., 2., 13., 25., 1., 20., 2., 1., 1., 13., 0., 4., 35., 14., 24., 32., 2., 1., 0., 1., 3., 8., 7., 29., 11., 0., 13., 5., 15., 8., 4., 1., 4., 3., 8., 12., 20., 55., 7., 19., 11., 5., 1., 4., 2., 14., 3., 7., 3., 11., 14., 5., 24., 7., 2., 2., 2., 10., 1., 2., 0., 5., 3., 4., 4., 0., 1., 1., 3., 1., 3., 1., 0., 1., 0., 3., 3., 2., 4., 3., 2., 8., 2., 5., 2., 1., 9., 3., 0., 2., 2., 1., 0., 1., 2., 2., 0., 2., 0., 0., 0., 0., 0., 0., 0., 3., 0., 0. [...]
+
+8., 0., 1., 5., 13., 5., 1., 2., 5., 25., 1., 17., 20., 2., 19., 2., 1., 4., 15., 1., 3., 10., 11., 33., 33., 4., 1., 1., 4., 2., 9., 3., 25., 10., 5., 18., 3., 17., 7., 2., 0., 4., 4., 15., 9., 12., 36., 10., 19., 12., 4., 2., 5., 3., 9., 2., 13., 8., 10., 18., 9., 21., 12., 6., 0., 0., 10., 1., 7., 2., 7., 1., 3., 1., 3., 2., 11., 2., 3., 1., 2., 0., 2., 2., 1., 7., 1., 4., 5., 1., 2., 0., 2., 1., 5., 4., 0., 0., 2., 1., 1., 0., 5., 0., 0., 1., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0 [...]
+
+3., 0., 3., 4., 18., 5., 4., 0., 8., 23., 2., 17., 16., 2., 14., 6., 1., 2., 28., 3., 7., 18., 15., 28., 26., 3., 1., 1., 1., 2., 5., 13., 25., 21., 2., 13., 6., 13., 20., 2., 2., 8., 2., 9., 15., 26., 53., 11., 23., 8., 5., 3., 6., 0., 6., 6., 17., 5., 9., 12., 4., 26., 11., 5., 0., 0., 10., 0., 6., 3., 8., 2., 2., 3., 3., 3., 2., 1., 0., 2., 2., 0., 2., 0., 2., 7., 3., 3., 1., 0., 9., 0., 4., 1., 3., 7., 2., 0., 3., 5., 4., 1., 1., 2., 4., 0., 1., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0. [...]
+
+8., 1., 2., 7., 29., 3., 37., 2., 10., 156., 3., 21., 209., 2., 21., 4., 3., 4., 81., 6., 10., 296., 43., 361., 38., 15., 1., 2., 4., 4., 44., 40., 235., 39., 9., 168., 16., 36., 4., 0., 2., 19., 5., 79., 18., 91., 13., 28., 48., 13., 4., 1., 32., 8., 39., 5., 48., 10., 25., 5., 8., 7., 3., 0., 0., 0., 29., 1., 14., 2., 27., 5., 13., 4., 1., 3., 3., 0., 1., 2., 10., 2., 8., 5., 8., 1., 2., 2., 138., 9., 1929., 87., 97., 232., 84., 108., 67., 17., 9., 22., 16., 0., 0., 10., 6., 3., 9., 6. [...]
+
+21., 1., 5., 10., 27., 3., 27., 2., 11., 136., 6., 36., 193., 9., 17., 6., 0., 4., 70., 3., 15., 294., 48., 307., 48., 17., 0., 0., 7., 2., 42., 30., 239., 40., 5., 146., 10., 44., 5., 0., 2., 10., 10., 77., 31., 81., 17., 34., 41., 8., 1., 0., 20., 13., 36., 12., 47., 10., 34., 7., 17., 8., 0., 0., 1., 0., 23., 4., 15., 2., 27., 4., 14., 5., 1., 2., 0., 1., 5., 5., 8., 2., 9., 3., 6., 2., 1., 4., 134., 3., 1858., 98., 101., 249., 118., 113., 71., 18., 8., 13., 17., 1., 3., 7., 4., 3., 8 [...]
+
+6., 6., 4., 12., 23., 4., 35., 0., 21., 160., 3., 27., 198., 3., 17., 8., 1., 6., 69., 5., 27., 280., 48., 319., 47., 16., 0., 3., 8., 6., 51., 35., 242., 36., 9., 143., 13., 35., 6., 0., 2., 23., 14., 81., 25., 116., 14., 45., 43., 13., 1., 0., 18., 5., 33., 12., 58., 7., 37., 4., 11., 14., 0., 0., 0., 0., 18., 5., 17., 4., 30., 6., 7., 6., 3., 4., 0., 0., 4., 0., 13., 1., 3., 2., 7., 1., 0., 4., 145., 8., 1919., 94., 95., 248., 99., 119., 58., 13., 11., 21., 13., 0., 2., 5., 1., 2., 15 [...]
+
+14., 3., 6., 14., 24., 15., 33., 2., 25., 166., 1., 20., 209., 7., 16., 9., 1., 7., 86., 2., 14., 305., 46., 313., 46., 13., 1., 1., 4., 5., 41., 36., 258., 35., 12., 176., 15., 38., 5., 0., 2., 24., 8., 79., 17., 90., 15., 31., 45., 17., 6., 1., 28., 6., 46., 7., 54., 11., 34., 4., 12., 9., 1., 0., 0., 0., 22., 6., 6., 4., 34., 4., 18., 2., 3., 3., 1., 3., 3., 2., 14., 1., 10., 1., 10., 1., 3., 4., 151., 8., 1900., 82., 106., 224., 98., 121., 69., 23., 12., 19., 14., 1., 1., 5., 3., 6., [...]
+
+23., 1., 2., 9., 21., 9., 23., 1., 10., 144., 3., 17., 197., 6., 8., 7., 1., 1., 76., 5., 17., 276., 41., 306., 38., 15., 2., 1., 9., 4., 43., 27., 220., 39., 13., 155., 14., 34., 5., 0., 0., 18., 10., 74., 21., 91., 12., 25., 45., 15., 4., 0., 16., 7., 47., 11., 54., 7., 28., 4., 6., 2., 3., 0., 1., 0., 22., 3., 14., 2., 29., 4., 6., 6., 1., 3., 0., 0., 1., 1., 7., 2., 6., 1., 6., 2., 1., 4., 125., 6., 1964., 110., 77., 206., 98., 101., 71., 19., 16., 15., 13., 0., 1., 6., 5., 4., 3., 1 [...]
+
+17., 1., 4., 8., 20., 8., 40., 1., 13., 152., 4., 34., 200., 4., 22., 5., 2., 3., 92., 2., 17., 280., 45., 343., 56., 16., 2., 0., 4., 3., 50., 22., 221., 49., 10., 160., 14., 41., 5., 0., 2., 15., 8., 66., 21., 85., 15., 33., 48., 12., 6., 1., 25., 3., 46., 13., 49., 9., 33., 8., 10., 5., 1., 0., 1., 0., 26., 7., 14., 2., 26., 2., 14., 4., 2., 6., 0., 0., 5., 0., 16., 1., 10., 1., 5., 1., 2., 6., 149., 5., 1923., 96., 113., 214., 96., 109., 79., 15., 14., 12., 15., 0., 2., 5., 7., 5., 8 [...]
+
+10., 4., 3., 6., 31., 2., 39., 2., 17., 159., 4., 36., 213., 8., 14., 12., 0., 1., 83., 2., 19., 264., 35., 351., 40., 21., 1., 4., 8., 2., 47., 40., 245., 45., 6., 147., 19., 29., 7., 0., 0., 18., 7., 83., 16., 85., 14., 28., 62., 13., 4., 2., 38., 12., 38., 10., 53., 3., 24., 7., 13., 8., 1., 0., 2., 0., 25., 3., 16., 4., 23., 3., 17., 8., 2., 2., 0., 0., 5., 1., 11., 2., 10., 0., 5., 0., 0., 2., 142., 10., 1934., 97., 86., 211., 96., 123., 64., 10., 11., 22., 17., 0., 3., 3., 5., 6.,  [...]
+
+18., 1., 4., 4., 21., 8., 27., 2., 11., 159., 5., 22., 201., 6., 17., 6., 0., 8., 96., 3., 16., 279., 58., 301., 44., 17., 1., 0., 6., 1., 36., 35., 229., 36., 4., 165., 10., 33., 7., 0., 4., 23., 11., 61., 20., 71., 14., 37., 43., 17., 4., 1., 25., 11., 40., 4., 51., 10., 29., 6., 11., 5., 2., 0., 1., 0., 26., 2., 12., 0., 21., 2., 8., 4., 0., 2., 1., 3., 6., 2., 13., 4., 6., 0., 6., 1., 2., 0., 165., 7., 1869., 86., 95., 244., 86., 122., 68., 16., 8., 19., 9., 2., 1., 7., 7., 6., 12.,  [...]
+
+17., 1., 3., 10., 25., 6., 33., 3., 15., 161., 1., 28., 206., 9., 21., 7., 3., 5., 108., 2., 9., 293., 48., 322., 40., 17., 2., 5., 9., 7., 45., 38., 223., 36., 7., 172., 24., 43., 7., 0., 3., 13., 10., 64., 18., 83., 13., 28., 39., 9., 3., 0., 26., 7., 38., 13., 36., 9., 35., 2., 6., 7., 3., 0., 2., 0., 32., 7., 13., 8., 30., 10., 5., 4., 1., 3., 0., 1., 4., 1., 10., 3., 12., 5., 2., 1., 1., 4., 145., 13., 1899., 89., 110., 215., 96., 97., 65., 17., 11., 17., 12., 2., 4., 5., 3., 2., 13 [...]
+
+8., 0., 9., 6., 27., 5., 29., 1., 16., 150., 6., 29., 195., 6., 13., 11., 0., 4., 82., 2., 12., 306., 47., 309., 43., 15., 0., 0., 7., 8., 39., 33., 236., 40., 13., 164., 20., 40., 7., 0., 2., 22., 13., 84., 21., 76., 13., 37., 51., 20., 3., 0., 26., 6., 42., 7., 51., 11., 38., 8., 14., 9., 7., 0., 1., 0., 20., 4., 12., 3., 32., 8., 11., 6., 1., 0., 2., 2., 1., 4., 10., 1., 10., 1., 4., 2., 1., 5., 137., 8., 1911., 72., 95., 217., 95., 107., 57., 14., 12., 13., 12., 0., 1., 6., 6., 4., 9 [...]
+
+9., 2., 4., 8., 25., 4., 34., 0., 19., 182., 5., 25., 199., 7., 15., 4., 1., 5., 76., 2., 18., 304., 34., 330., 42., 18., 1., 1., 13., 1., 51., 36., 223., 43., 7., 152., 17., 35., 5., 0., 2., 12., 9., 78., 16., 87., 14., 31., 49., 9., 1., 0., 20., 9., 39., 6., 53., 14., 40., 3., 6., 4., 0., 0., 2., 0., 24., 3., 23., 3., 29., 10., 9., 4., 6., 3., 2., 1., 3., 1., 11., 3., 10., 1., 9., 0., 1., 5., 146., 10., 1786., 84., 110., 230., 98., 102., 71., 14., 9., 22., 11., 1., 1., 9., 9., 5., 5.,  [...]
+
+14., 3., 3., 3., 27., 6., 31., 1., 7., 167., 1., 23., 218., 4., 14., 7., 1., 5., 83., 3., 20., 281., 57., 323., 40., 19., 1., 3., 8., 9., 45., 39., 230., 44., 15., 158., 22., 31., 6., 0., 1., 12., 12., 64., 18., 87., 8., 36., 41., 10., 4., 2., 31., 6., 43., 7., 40., 7., 37., 8., 5., 0., 2., 0., 1., 0., 22., 4., 14., 5., 25., 6., 7., 10., 1., 2., 0., 1., 3., 2., 11., 2., 4., 3., 9., 1., 1., 3., 167., 12., 1863., 94., 97., 241., 95., 107., 66., 15., 12., 14., 5., 1., 1., 6., 3., 5., 8., 8. [...]
+
+10., 1., 3., 11., 29., 8., 22., 1., 12., 166., 2., 22., 191., 4., 16., 5., 0., 2., 88., 0., 17., 292., 51., 338., 51., 25., 0., 4., 5., 8., 37., 20., 227., 44., 12., 157., 12., 37., 7., 0., 5., 15., 8., 82., 19., 91., 11., 41., 48., 15., 3., 1., 25., 2., 43., 7., 52., 9., 27., 7., 7., 10., 2., 0., 0., 0., 17., 7., 17., 2., 33., 4., 10., 2., 3., 3., 0., 1., 3., 1., 15., 4., 10., 0., 12., 1., 1., 4., 131., 10., 1866., 81., 90., 201., 117., 120., 64., 13., 8., 17., 9., 1., 0., 4., 3., 4., 1 [...]
+
+8., 1., 4., 9., 27., 8., 34., 0., 17., 163., 4., 24., 213., 3., 19., 17., 1., 5., 78., 4., 17., 309., 29., 339., 50., 14., 3., 3., 10., 8., 36., 42., 201., 32., 10., 161., 14., 35., 11., 0., 0., 24., 5., 82., 18., 88., 12., 32., 55., 11., 4., 2., 31., 11., 31., 9., 53., 5., 30., 8., 9., 9., 5., 0., 0., 0., 24., 13., 14., 1., 33., 8., 10., 5., 0., 2., 1., 1., 5., 1., 9., 2., 11., 5., 7., 0., 2., 5., 147., 4., 1911., 99., 112., 205., 109., 122., 63., 12., 16., 14., 14., 0., 1., 2., 1., 2., [...]
+
+14., 2., 2., 6., 31., 6., 39., 4., 17., 161., 2., 21., 200., 4., 22., 8., 0., 2., 95., 1., 14., 269., 44., 324., 40., 26., 3., 1., 6., 6., 31., 26., 228., 39., 11., 168., 11., 37., 5., 0., 1., 18., 8., 78., 18., 97., 13., 35., 46., 21., 1., 0., 31., 11., 37., 11., 54., 9., 37., 4., 9., 7., 1., 0., 4., 0., 16., 5., 14., 3., 35., 7., 10., 3., 2., 1., 4., 3., 2., 4., 8., 3., 9., 0., 7., 2., 0., 4., 139., 10., 1904., 106., 107., 235., 108., 110., 71., 18., 13., 15., 13., 1., 4., 6., 8., 4.,  [...]
+
+8., 1., 2., 8., 24., 5., 35., 0., 19., 171., 4., 29., 195., 7., 18., 10., 0., 1., 101., 4., 18., 302., 36., 335., 48., 15., 0., 2., 4., 6., 54., 31., 232., 45., 6., 154., 18., 47., 4., 0., 1., 21., 4., 83., 17., 85., 15., 35., 66., 14., 2., 1., 33., 9., 51., 12., 63., 6., 38., 5., 7., 7., 2., 0., 0., 0., 18., 5., 13., 2., 23., 2., 14., 4., 1., 2., 0., 2., 3., 1., 5., 1., 8., 1., 11., 0., 2., 4., 148., 6., 1930., 79., 100., 211., 98., 90., 73., 17., 18., 11., 16., 1., 2., 4., 6., 6., 12., [...]
+
+14., 2., 4., 5., 26., 6., 35., 1., 13., 178., 0., 29., 224., 4., 14., 12., 1., 6., 89., 6., 18., 268., 43., 309., 46., 16., 1., 1., 5., 1., 46., 24., 239., 34., 9., 168., 17., 34., 6., 0., 2., 20., 8., 97., 21., 91., 11., 36., 43., 13., 2., 1., 16., 13., 43., 6., 41., 9., 24., 5., 10., 10., 2., 0., 0., 0., 27., 4., 10., 2., 41., 1., 11., 5., 2., 2., 0., 0., 2., 1., 6., 4., 6., 2., 7., 0., 1., 3., 156., 7., 1818., 93., 103., 228., 96., 116., 66., 20., 12., 19., 9., 0., 1., 6., 3., 5., 7., [...]
+
+9., 2., 5., 7., 26., 6., 26., 1., 21., 136., 3., 40., 206., 7., 17., 4., 1., 6., 84., 0., 19., 270., 28., 337., 37., 16., 2., 2., 9., 3., 48., 31., 231., 35., 4., 167., 16., 42., 5., 0., 3., 17., 5., 81., 30., 83., 16., 40., 46., 18., 2., 0., 27., 8., 45., 13., 43., 6., 25., 6., 9., 7., 1., 0., 1., 0., 23., 4., 8., 1., 29., 7., 10., 3., 4., 2., 0., 2., 2., 3., 17., 2., 5., 2., 3., 2., 1., 6., 142., 5., 1969., 103., 91., 220., 87., 107., 55., 17., 11., 29., 12., 1., 2., 9., 5., 3., 9., 13 [...]
+
+20., 1., 6., 6., 20., 4., 35., 0., 16., 148., 6., 28., 186., 3., 11., 7., 1., 4., 85., 3., 17., 258., 38., 364., 41., 24., 0., 3., 2., 3., 43., 33., 207., 39., 4., 161., 18., 35., 5., 0., 4., 16., 12., 78., 14., 97., 12., 31., 39., 12., 4., 0., 30., 4., 43., 10., 64., 10., 27., 8., 8., 8., 3., 0., 1., 0., 31., 5., 13., 1., 21., 3., 10., 6., 3., 2., 1., 1., 1., 0., 8., 2., 4., 2., 5., 1., 1., 4., 158., 9., 1929., 100., 99., 226., 97., 110., 68., 16., 10., 17., 17., 0., 1., 5., 6., 3., 5., [...]
+
+16., 1., 1., 7., 23., 8., 23., 1., 20., 156., 3., 23., 207., 7., 10., 6., 2., 3., 88., 1., 14., 291., 36., 328., 47., 15., 2., 3., 5., 4., 36., 27., 222., 28., 6., 153., 13., 42., 7., 0., 2., 15., 12., 88., 17., 87., 11., 26., 50., 13., 7., 0., 26., 7., 42., 17., 44., 7., 29., 7., 14., 3., 2., 0., 0., 0., 23., 4., 21., 5., 21., 8., 10., 5., 2., 2., 1., 0., 3., 1., 8., 4., 10., 1., 7., 0., 0., 5., 161., 4., 1918., 103., 88., 234., 101., 113., 57., 17., 12., 12., 11., 1., 2., 6., 6., 4., 1 [...]
+
+13., 2., 2., 8., 30., 10., 21., 2., 25., 157., 2., 25., 211., 4., 17., 9., 1., 8., 87., 0., 22., 302., 48., 337., 36., 21., 1., 1., 5., 7., 42., 32., 264., 52., 12., 161., 17., 41., 8., 0., 2., 20., 8., 80., 13., 85., 17., 34., 57., 11., 1., 0., 28., 5., 40., 9., 48., 8., 22., 4., 7., 5., 3., 0., 1., 0., 17., 3., 11., 3., 23., 3., 10., 6., 1., 2., 2., 2., 2., 0., 16., 4., 7., 3., 17., 1., 2., 5., 146., 8., 1868., 84., 85., 231., 94., 101., 74., 11., 14., 16., 8., 0., 0., 7., 5., 7., 17., [...]
+
+23., 1., 2., 4., 30., 8., 20., 0., 14., 137., 4., 26., 199., 5., 15., 2., 1., 4., 77., 1., 17., 279., 43., 358., 29., 23., 1., 1., 10., 1., 51., 27., 250., 31., 13., 161., 18., 40., 3., 0., 0., 19., 11., 70., 19., 89., 15., 27., 45., 16., 1., 3., 23., 5., 35., 10., 51., 8., 22., 8., 5., 7., 1., 0., 0., 0., 36., 13., 9., 2., 34., 7., 14., 3., 4., 2., 1., 2., 2., 2., 11., 5., 8., 1., 7., 1., 0., 4., 121., 8., 1892., 91., 102., 242., 102., 138., 88., 13., 13., 10., 14., 1., 7., 3., 3., 6.,  [...]
+
+10., 1., 4., 11., 24., 7., 32., 1., 14., 174., 2., 25., 218., 5., 12., 2., 1., 4., 98., 1., 21., 297., 53., 301., 51., 11., 0., 3., 9., 2., 42., 36., 238., 44., 7., 155., 15., 45., 8., 0., 1., 15., 8., 77., 14., 99., 23., 37., 51., 14., 4., 1., 15., 13., 47., 6., 45., 5., 35., 5., 13., 9., 2., 0., 0., 0., 16., 2., 13., 6., 32., 8., 12., 9., 3., 5., 2., 1., 4., 3., 6., 2., 8., 2., 10., 0., 0., 6., 140., 10., 1853., 89., 94., 197., 88., 115., 69., 17., 11., 23., 11., 0., 3., 5., 7., 3., 12 [...]
+
+3., 1., 0., 6., 7., 2., 7., 0., 3., 26., 0., 10., 24., 2., 15., 2., 0., 6., 7., 1., 8., 17., 12., 24., 27., 4., 1., 2., 5., 0., 12., 2., 20., 15., 2., 12., 3., 16., 11., 1., 3., 0., 3., 10., 11., 26., 39., 13., 29., 9., 4., 1., 5., 2., 9., 4., 9., 9., 12., 24., 5., 21., 7., 2., 0., 0., 8., 1., 3., 1., 4., 4., 3., 5., 1., 5., 8., 3., 0., 2., 0., 0., 0., 3., 2., 7., 0., 3., 4., 2., 5., 0., 1., 2., 2., 6., 2., 0., 3., 0., 3., 0., 3., 3., 1., 0., 2., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., 0 [...]
+
+7., 2., 1., 4., 11., 2., 6., 2., 3., 21., 1., 6., 24., 1., 11., 3., 1., 2., 21., 0., 4., 24., 12., 26., 34., 5., 2., 0., 2., 3., 9., 6., 20., 18., 1., 10., 7., 16., 9., 3., 0., 3., 3., 17., 15., 11., 42., 15., 32., 14., 5., 3., 6., 0., 4., 2., 9., 5., 8., 14., 10., 26., 7., 1., 3., 2., 6., 1., 1., 4., 2., 2., 4., 6., 1., 4., 3., 4., 1., 2., 1., 0., 7., 4., 2., 8., 1., 3., 1., 1., 6., 2., 2., 2., 0., 7., 2., 0., 2., 3., 1., 1., 1., 3., 3., 1., 0., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0 [...]
+
+2., 1., 2., 6., 5., 6., 7., 1., 5., 13., 0., 11., 27., 1., 22., 4., 0., 3., 10., 3., 4., 25., 12., 20., 30., 2., 0., 3., 5., 3., 6., 8., 34., 11., 3., 19., 3., 8., 10., 2., 1., 6., 1., 13., 12., 16., 33., 14., 12., 6., 3., 0., 5., 3., 12., 2., 9., 7., 6., 19., 5., 22., 12., 5., 2., 1., 12., 2., 0., 0., 4., 1., 2., 2., 3., 3., 3., 0., 3., 3., 2., 0., 4., 1., 2., 6., 3., 3., 0., 4., 3., 0., 3., 0., 0., 10., 5., 0., 1., 1., 0., 1., 1., 2., 1., 0., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., [...]
+
+10., 2., 3., 8., 4., 2., 5., 1., 8., 15., 2., 17., 24., 0., 14., 2., 2., 1., 22., 4., 3., 19., 12., 21., 28., 3., 1., 2., 4., 0., 7., 7., 25., 14., 0., 10., 3., 13., 9., 3., 2., 5., 2., 10., 9., 19., 48., 14., 25., 9., 3., 0., 4., 1., 9., 6., 7., 8., 3., 13., 5., 18., 8., 3., 1., 1., 9., 2., 1., 1., 6., 2., 5., 1., 5., 2., 2., 1., 1., 1., 4., 0., 3., 1., 0., 3., 2., 3., 5., 4., 4., 0., 2., 1., 1., 6., 1., 0., 1., 2., 5., 1., 3., 3., 2., 1., 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., [...]
+
+6., 2., 0., 3., 7., 5., 9., 0., 4., 34., 1., 15., 28., 0., 13., 2., 1., 3., 4., 0., 5., 28., 23., 29., 25., 6., 0., 1., 5., 2., 4., 6., 19., 22., 1., 18., 5., 13., 10., 0., 0., 3., 2., 11., 13., 23., 51., 10., 15., 6., 5., 1., 7., 1., 3., 2., 11., 5., 4., 18., 1., 22., 5., 3., 0., 3., 11., 0., 5., 6., 5., 5., 3., 3., 2., 2., 1., 0., 1., 0., 2., 0., 1., 2., 2., 2., 5., 7., 2., 0., 4., 0., 3., 1., 1., 6., 3., 0., 1., 2., 3., 1., 2., 1., 2., 1., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0 [...]
+
+14., 3., 3., 2., 6., 2., 5., 2., 13., 29., 0., 14., 18., 1., 18., 3., 0., 3., 12., 2., 5., 30., 10., 23., 30., 7., 1., 2., 4., 3., 11., 6., 25., 13., 0., 16., 2., 15., 4., 1., 3., 3., 0., 14., 9., 25., 43., 8., 17., 8., 3., 1., 6., 1., 5., 0., 7., 9., 11., 15., 5., 21., 11., 1., 1., 0., 4., 0., 3., 1., 4., 4., 6., 5., 0., 4., 2., 3., 0., 4., 0., 0., 2., 1., 1., 5., 4., 3., 2., 1., 1., 2., 1., 1., 0., 6., 1., 0., 2., 0., 0., 1., 1., 1., 3., 2., 4., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0.,  [...]
+
+9., 1., 2., 3., 7., 4., 2., 0., 7., 35., 0., 11., 13., 1., 11., 3., 0., 2., 23., 0., 4., 24., 4., 21., 28., 6., 0., 1., 2., 2., 11., 7., 27., 10., 4., 13., 5., 10., 13., 3., 1., 5., 2., 14., 13., 9., 45., 11., 27., 6., 3., 0., 3., 3., 10., 2., 6., 7., 8., 14., 6., 19., 9., 3., 1., 0., 5., 1., 4., 2., 6., 0., 4., 5., 3., 8., 2., 4., 2., 7., 0., 0., 1., 4., 2., 8., 2., 3., 1., 4., 3., 0., 1., 1., 3., 7., 2., 0., 3., 2., 0., 3., 0., 0., 2., 1., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0. [...]
+
+5., 0., 4., 4., 9., 4., 4., 2., 3., 26., 0., 10., 32., 0., 16., 2., 3., 2., 21., 4., 2., 18., 10., 30., 16., 11., 0., 0., 0., 3., 7., 7., 19., 17., 6., 15., 0., 12., 10., 2., 0., 4., 1., 16., 11., 21., 41., 9., 21., 7., 1., 1., 5., 4., 7., 5., 13., 9., 7., 15., 5., 24., 11., 5., 3., 3., 7., 2., 4., 2., 7., 2., 3., 6., 2., 6., 6., 3., 2., 0., 0., 0., 1., 1., 0., 3., 2., 7., 2., 4., 7., 1., 1., 1., 4., 7., 1., 0., 5., 3., 2., 3., 1., 1., 1., 3., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0.,  [...]
+
+8., 1., 3., 5., 3., 1., 4., 1., 4., 20., 1., 14., 29., 0., 17., 3., 2., 3., 22., 1., 4., 22., 7., 16., 29., 7., 1., 0., 3., 3., 8., 6., 28., 24., 1., 14., 2., 14., 6., 2., 1., 3., 4., 8., 13., 14., 51., 7., 15., 10., 5., 3., 7., 2., 15., 3., 10., 4., 8., 10., 5., 9., 4., 3., 4., 1., 7., 0., 1., 2., 3., 3., 3., 6., 2., 5., 1., 3., 0., 5., 0., 0., 1., 1., 1., 5., 2., 5., 3., 8., 4., 0., 1., 1., 3., 5., 4., 0., 2., 1., 2., 2., 2., 2., 4., 4., 2., 0., 0., 0., 0., 3., 0., 0., 6., 0., 0., 0.,  [...]
+
+15., 2., 1., 8., 21., 3., 32., 4., 10., 166., 2., 20., 207., 5., 15., 12., 3., 4., 93., 0., 16., 312., 37., 337., 37., 26., 0., 2., 8., 9., 48., 36., 233., 48., 11., 172., 23., 42., 10., 0., 3., 11., 13., 79., 16., 82., 18., 34., 35., 8., 2., 3., 27., 7., 36., 8., 49., 9., 31., 10., 8., 8., 1., 0., 2., 0., 23., 6., 13., 3., 33., 7., 7., 5., 3., 3., 0., 0., 6., 5., 16., 4., 9., 2., 10., 1., 0., 3., 132., 8., 1828., 99., 100., 234., 95., 98., 67., 18., 10., 25., 15., 2., 2., 5., 4., 5., 9. [...]
+
+14., 2., 3., 7., 21., 4., 37., 0., 18., 165., 3., 31., 193., 5., 16., 12., 0., 5., 90., 6., 16., 258., 34., 311., 41., 16., 2., 1., 9., 1., 32., 41., 249., 48., 5., 178., 7., 32., 8., 0., 0., 12., 15., 68., 15., 78., 15., 40., 57., 9., 3., 0., 27., 3., 40., 7., 56., 8., 29., 6., 7., 6., 3., 0., 0., 0., 19., 3., 13., 2., 28., 3., 14., 5., 2., 5., 1., 0., 5., 1., 8., 0., 5., 2., 4., 1., 1., 5., 136., 5., 1874., 94., 99., 215., 87., 118., 71., 20., 13., 19., 13., 1., 2., 5., 6., 4., 10., 14 [...]
+
+15., 4., 2., 2., 25., 3., 31., 3., 17., 154., 6., 33., 204., 5., 18., 6., 1., 12., 101., 2., 21., 294., 44., 331., 41., 18., 1., 0., 10., 7., 50., 30., 234., 42., 9., 155., 15., 31., 3., 0., 2., 20., 10., 76., 21., 86., 13., 37., 45., 9., 3., 1., 19., 10., 36., 9., 47., 12., 35., 7., 7., 9., 2., 0., 1., 0., 25., 8., 11., 7., 24., 6., 11., 7., 4., 1., 1., 1., 3., 3., 11., 3., 4., 5., 4., 0., 0., 4., 140., 9., 1756., 74., 86., 201., 102., 103., 78., 18., 10., 32., 6., 3., 3., 6., 4., 2., 5 [...]
+
+17., 2., 1., 12., 37., 3., 27., 1., 16., 160., 2., 19., 212., 11., 20., 9., 0., 9., 87., 1., 10., 315., 43., 316., 40., 18., 1., 2., 11., 10., 45., 41., 258., 43., 10., 180., 10., 47., 10., 0., 0., 22., 8., 61., 13., 93., 17., 31., 35., 10., 4., 0., 18., 5., 38., 10., 54., 10., 30., 8., 12., 5., 3., 0., 2., 0., 22., 6., 12., 3., 37., 7., 5., 4., 3., 1., 0., 0., 5., 1., 9., 4., 7., 1., 13., 1., 0., 2., 151., 11., 1908., 74., 104., 235., 93., 107., 70., 25., 11., 15., 9., 0., 0., 3., 6., 3 [...]
+
+13., 2., 3., 10., 35., 8., 34., 1., 17., 172., 2., 39., 184., 6., 22., 7., 0., 2., 88., 0., 16., 313., 51., 321., 45., 23., 2., 2., 5., 7., 48., 40., 248., 31., 6., 161., 23., 52., 8., 0., 3., 9., 5., 79., 18., 93., 15., 46., 41., 15., 1., 0., 27., 8., 33., 11., 53., 6., 23., 7., 11., 9., 2., 0., 2., 0., 22., 6., 17., 3., 24., 4., 10., 4., 1., 5., 0., 0., 7., 1., 12., 4., 11., 3., 6., 0., 0., 7., 137., 3., 1941., 81., 97., 218., 79., 116., 75., 11., 14., 12., 15., 1., 4., 5., 5., 3., 10. [...]
+
+10., 5., 2., 13., 24., 4., 28., 3., 22., 173., 6., 29., 210., 6., 14., 7., 2., 7., 102., 2., 19., 327., 50., 347., 46., 18., 2., 3., 6., 7., 46., 33., 234., 40., 13., 156., 12., 28., 6., 0., 3., 20., 8., 77., 23., 90., 18., 23., 37., 17., 3., 1., 25., 7., 33., 9., 40., 8., 38., 6., 13., 6., 1., 0., 1., 0., 31., 8., 13., 2., 31., 5., 11., 6., 2., 4., 1., 1., 2., 2., 14., 1., 9., 1., 4., 0., 1., 3., 137., 8., 1829., 81., 104., 217., 90., 110., 74., 19., 6., 12., 20., 1., 4., 6., 6., 2., 12 [...]
+
+10., 2., 3., 8., 24., 8., 42., 2., 10., 160., 6., 30., 217., 1., 13., 6., 1., 1., 93., 1., 16., 299., 40., 311., 46., 17., 1., 4., 11., 11., 41., 32., 247., 36., 5., 141., 15., 48., 9., 0., 0., 17., 12., 78., 15., 82., 7., 27., 48., 11., 3., 0., 25., 6., 41., 9., 55., 9., 27., 9., 2., 4., 2., 0., 1., 0., 28., 10., 21., 5., 29., 6., 6., 8., 2., 1., 3., 1., 1., 1., 7., 2., 4., 0., 9., 2., 1., 2., 134., 7., 1916., 85., 113., 227., 114., 119., 93., 13., 13., 15., 13., 1., 2., 5., 6., 0., 14. [...]
+
+5., 1., 2., 5., 29., 4., 38., 0., 16., 163., 6., 28., 209., 4., 11., 4., 1., 8., 84., 3., 15., 277., 45., 312., 42., 15., 0., 3., 4., 7., 46., 33., 233., 39., 3., 167., 15., 38., 4., 0., 1., 15., 7., 72., 16., 90., 15., 37., 45., 14., 1., 1., 23., 6., 39., 12., 50., 7., 38., 7., 3., 12., 2., 0., 1., 0., 25., 6., 12., 4., 30., 2., 10., 4., 4., 3., 3., 2., 4., 1., 11., 1., 13., 3., 9., 3., 1., 4., 138., 9., 1855., 105., 126., 228., 94., 136., 62., 14., 21., 23., 6., 0., 4., 6., 4., 11., 5. [...]
+
+14., 1., 5., 6., 25., 2., 20., 1., 14., 168., 2., 20., 186., 2., 22., 4., 2., 5., 107., 2., 11., 257., 43., 324., 52., 18., 0., 1., 6., 6., 51., 42., 206., 48., 7., 172., 13., 49., 5., 0., 1., 13., 9., 77., 18., 85., 17., 29., 48., 9., 6., 0., 16., 5., 35., 8., 53., 7., 29., 6., 9., 3., 3., 0., 1., 0., 22., 2., 15., 5., 21., 3., 15., 4., 1., 1., 0., 1., 1., 0., 9., 7., 6., 0., 11., 1., 2., 3., 142., 5., 1757., 75., 103., 190., 81., 110., 68., 13., 10., 19., 15., 0., 1., 10., 6., 7., 8.,  [...]
+
+5., 1., 4., 6., 22., 9., 32., 2., 21., 170., 7., 26., 212., 5., 18., 6., 2., 5., 83., 2., 19., 293., 42., 339., 36., 18., 0., 1., 8., 5., 47., 38., 213., 44., 6., 140., 17., 28., 3., 0., 2., 16., 8., 85., 24., 90., 14., 38., 52., 10., 3., 1., 30., 7., 31., 11., 42., 10., 25., 8., 12., 10., 1., 0., 2., 0., 28., 3., 8., 2., 29., 4., 14., 4., 4., 6., 0., 0., 4., 1., 4., 3., 10., 5., 3., 1., 0., 3., 139., 6., 1879., 80., 94., 218., 108., 133., 71., 12., 12., 18., 12., 1., 2., 4., 3., 3., 7., [...]
+
+8., 3., 3., 10., 24., 8., 33., 2., 14., 171., 2., 36., 201., 4., 16., 6., 0., 4., 71., 1., 13., 272., 47., 328., 47., 17., 0., 3., 8., 3., 39., 35., 205., 33., 8., 149., 17., 36., 9., 0., 3., 18., 6., 88., 21., 71., 17., 25., 47., 24., 3., 0., 34., 15., 47., 10., 52., 10., 29., 6., 11., 6., 4., 0., 0., 0., 19., 7., 8., 4., 26., 3., 13., 4., 3., 2., 1., 0., 0., 3., 10., 3., 6., 2., 5., 1., 2., 1., 137., 7., 1922., 108., 97., 228., 104., 123., 59., 19., 11., 16., 10., 0., 2., 9., 4., 5., 3 [...]
+
+21., 0., 2., 13., 27., 5., 43., 0., 22., 154., 4., 25., 187., 7., 11., 5., 0., 4., 98., 1., 11., 251., 45., 331., 52., 14., 2., 5., 10., 5., 55., 36., 232., 34., 5., 183., 11., 35., 5., 0., 2., 15., 7., 66., 18., 90., 23., 29., 47., 10., 8., 1., 36., 9., 37., 18., 44., 10., 27., 8., 6., 5., 2., 0., 1., 0., 25., 4., 12., 4., 41., 8., 11., 3., 2., 6., 1., 3., 5., 1., 10., 4., 12., 4., 10., 1., 1., 5., 156., 8., 1855., 112., 88., 221., 100., 97., 75., 17., 11., 21., 7., 0., 0., 4., 2., 1.,  [...]
+
+8., 3., 2., 12., 29., 6., 31., 1., 13., 149., 3., 25., 220., 7., 16., 12., 0., 6., 89., 3., 15., 296., 41., 380., 41., 20., 1., 3., 6., 3., 33., 39., 254., 36., 12., 128., 10., 38., 11., 0., 3., 21., 8., 69., 26., 61., 7., 38., 55., 13., 3., 1., 26., 9., 43., 7., 57., 17., 30., 7., 7., 9., 0., 0., 0., 0., 23., 5., 6., 3., 34., 7., 15., 3., 4., 1., 3., 0., 2., 2., 8., 4., 7., 1., 9., 0., 1., 2., 137., 12., 1921., 98., 93., 238., 101., 96., 53., 11., 12., 11., 15., 3., 3., 6., 4., 4., 7.,  [...]
+
+8., 2., 5., 6., 20., 4., 32., 1., 16., 150., 4., 34., 224., 6., 17., 5., 2., 7., 89., 2., 14., 284., 50., 342., 45., 15., 0., 1., 5., 6., 45., 40., 213., 51., 14., 150., 12., 36., 2., 0., 2., 16., 6., 65., 18., 100., 6., 36., 47., 14., 4., 1., 25., 2., 40., 11., 53., 3., 31., 3., 10., 5., 3., 0., 0., 0., 37., 3., 13., 1., 35., 3., 19., 9., 0., 6., 1., 2., 2., 3., 10., 1., 10., 2., 6., 1., 1., 4., 146., 6., 1894., 91., 92., 227., 89., 112., 63., 13., 12., 23., 14., 1., 5., 5., 4., 3., 13. [...]
+
+21., 4., 1., 7., 19., 11., 24., 1., 15., 159., 3., 23., 212., 1., 20., 8., 1., 7., 83., 3., 20., 290., 58., 295., 42., 18., 0., 2., 3., 3., 48., 28., 221., 42., 7., 160., 4., 44., 6., 0., 2., 18., 5., 70., 21., 95., 21., 31., 49., 14., 5., 0., 18., 7., 32., 8., 65., 15., 41., 8., 13., 10., 1., 0., 0., 0., 17., 3., 17., 8., 38., 6., 9., 6., 0., 4., 1., 0., 1., 2., 10., 4., 6., 5., 12., 0., 0., 2., 142., 11., 1875., 109., 105., 217., 100., 108., 75., 13., 5., 19., 12., 1., 3., 5., 5., 1.,  [...]
+
+11., 2., 1., 6., 23., 7., 36., 1., 12., 148., 5., 23., 214., 8., 15., 6., 2., 4., 95., 2., 16., 285., 38., 319., 45., 23., 2., 2., 3., 3., 52., 37., 246., 37., 9., 168., 13., 38., 6., 0., 1., 20., 8., 72., 14., 76., 14., 30., 45., 17., 4., 3., 29., 5., 41., 14., 51., 9., 29., 9., 10., 10., 3., 0., 1., 0., 28., 7., 22., 4., 38., 5., 21., 7., 4., 4., 1., 1., 8., 3., 11., 1., 9., 6., 4., 0., 1., 2., 147., 9., 1937., 82., 92., 195., 81., 119., 58., 13., 10., 22., 14., 1., 1., 7., 4., 2., 14. [...]
+
+14., 5., 1., 1., 26., 3., 28., 0., 17., 173., 2., 17., 186., 7., 21., 5., 0., 5., 100., 1., 10., 270., 54., 346., 41., 17., 0., 2., 11., 5., 41., 31., 227., 37., 8., 174., 15., 40., 8., 0., 0., 18., 6., 71., 22., 93., 20., 43., 35., 14., 2., 2., 19., 7., 32., 13., 67., 12., 42., 7., 9., 9., 1., 0., 3., 0., 17., 1., 10., 2., 21., 7., 13., 11., 1., 2., 2., 2., 3., 3., 20., 3., 7., 3., 8., 0., 0., 2., 144., 6., 1892., 93., 92., 229., 103., 129., 57., 13., 10., 27., 19., 0., 1., 5., 4., 6.,  [...]
+
+17., 1., 3., 10., 23., 7., 30., 1., 14., 149., 3., 27., 215., 5., 18., 7., 1., 6., 88., 0., 20., 270., 42., 311., 40., 17., 0., 2., 11., 1., 37., 30., 255., 41., 10., 170., 12., 43., 5., 0., 5., 15., 12., 88., 21., 80., 16., 28., 34., 13., 3., 0., 27., 6., 48., 13., 45., 6., 17., 10., 11., 5., 3., 0., 0., 0., 21., 5., 4., 2., 31., 4., 20., 8., 3., 3., 0., 0., 4., 1., 12., 4., 7., 2., 5., 2., 1., 8., 143., 9., 1877., 84., 102., 231., 112., 108., 79., 16., 4., 16., 11., 1., 5., 6., 6., 6., [...]
+
+12., 3., 3., 6., 34., 3., 26., 0., 18., 158., 1., 20., 199., 2., 23., 7., 1., 6., 71., 3., 9., 265., 49., 294., 41., 18., 0., 1., 10., 3., 51., 33., 236., 40., 8., 164., 13., 31., 11., 0., 2., 21., 3., 88., 13., 94., 17., 26., 50., 9., 2., 0., 29., 9., 37., 14., 48., 10., 31., 8., 10., 6., 3., 0., 1., 0., 23., 8., 21., 4., 17., 5., 9., 3., 0., 3., 0., 0., 2., 3., 10., 5., 4., 2., 8., 1., 0., 6., 124., 9., 1952., 86., 99., 220., 80., 103., 66., 19., 10., 16., 14., 1., 4., 4., 9., 2., 7.,  [...]
+
+14., 3., 6., 8., 29., 4., 34., 1., 21., 150., 3., 33., 201., 3., 11., 4., 1., 5., 84., 3., 15., 270., 47., 321., 52., 19., 3., 3., 7., 1., 48., 34., 197., 42., 7., 155., 15., 36., 6., 0., 4., 11., 10., 80., 17., 78., 13., 34., 48., 14., 2., 0., 31., 4., 31., 9., 52., 10., 33., 3., 10., 10., 3., 0., 1., 0., 33., 5., 16., 1., 31., 7., 7., 8., 2., 6., 2., 0., 4., 1., 14., 0., 7., 3., 9., 1., 1., 7., 136., 12., 1918., 94., 101., 220., 92., 111., 82., 21., 12., 18., 9., 0., 3., 6., 5., 5., 10 [...]
+
+10., 0., 0., 3., 13., 5., 5., 1., 6., 8., 2., 9., 17., 3., 15., 5., 2., 1., 26., 1., 3., 34., 10., 12., 25., 4., 3., 0., 3., 2., 6., 3., 29., 16., 4., 25., 5., 15., 11., 4., 0., 3., 3., 9., 7., 15., 52., 18., 22., 12., 5., 1., 4., 2., 11., 5., 10., 8., 9., 10., 5., 31., 10., 2., 0., 2., 4., 1., 5., 2., 3., 4., 3., 3., 4., 4., 3., 1., 3., 1., 1., 0., 0., 5., 1., 5., 1., 8., 1., 1., 8., 2., 0., 3., 1., 7., 1., 0., 0., 3., 5., 4., 1., 1., 0., 0., 4., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0.,  [...]
+
+6., 2., 5., 3., 12., 1., 2., 1., 1., 21., 1., 15., 21., 1., 20., 5., 3., 2., 19., 0., 3., 20., 12., 26., 31., 4., 0., 2., 4., 1., 9., 7., 28., 15., 1., 12., 1., 11., 6., 1., 0., 3., 2., 10., 12., 19., 43., 13., 19., 7., 5., 1., 6., 1., 5., 2., 6., 7., 5., 17., 7., 17., 7., 2., 0., 3., 9., 1., 2., 2., 2., 2., 1., 4., 3., 5., 9., 2., 0., 3., 6., 0., 1., 1., 2., 10., 2., 3., 3., 1., 3., 0., 2., 0., 4., 8., 2., 0., 3., 0., 1., 2., 3., 2., 2., 0., 3., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0 [...]
+
+7., 0., 4., 3., 7., 3., 7., 2., 4., 19., 0., 4., 17., 2., 14., 1., 0., 2., 16., 2., 3., 24., 14., 22., 22., 7., 3., 1., 7., 1., 5., 8., 22., 17., 6., 20., 5., 11., 9., 1., 1., 7., 0., 12., 13., 24., 47., 12., 17., 11., 3., 2., 8., 3., 0., 5., 12., 6., 8., 15., 3., 13., 5., 3., 1., 1., 6., 2., 4., 2., 6., 2., 6., 2., 1., 3., 7., 3., 0., 2., 3., 0., 3., 2., 0., 6., 2., 2., 2., 1., 5., 2., 3., 0., 2., 8., 0., 0., 3., 2., 2., 1., 2., 3., 2., 2., 4., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0. [...]
+
+7., 1., 2., 4., 8., 5., 3., 2., 5., 14., 2., 11., 10., 2., 17., 3., 3., 1., 18., 0., 6., 30., 9., 27., 27., 8., 0., 0., 6., 2., 7., 5., 21., 6., 3., 20., 3., 15., 11., 2., 0., 9., 3., 16., 9., 30., 48., 10., 23., 10., 8., 3., 6., 3., 16., 5., 7., 1., 11., 18., 4., 26., 6., 6., 4., 0., 10., 1., 3., 3., 10., 1., 4., 6., 2., 6., 2., 1., 0., 3., 5., 0., 4., 4., 1., 10., 4., 3., 4., 1., 6., 0., 1., 0., 1., 6., 1., 0., 1., 0., 2., 0., 5., 4., 1., 1., 6., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., [...]
+
+17., 2., 3., 5., 10., 4., 7., 1., 5., 16., 2., 17., 18., 0., 17., 3., 0., 5., 20., 2., 4., 22., 11., 24., 25., 3., 0., 0., 2., 2., 3., 9., 14., 19., 3., 25., 5., 15., 8., 4., 1., 7., 3., 12., 14., 11., 62., 8., 25., 6., 4., 2., 2., 5., 9., 6., 4., 4., 3., 12., 4., 23., 14., 5., 0., 2., 4., 2., 1., 4., 3., 5., 5., 7., 4., 4., 3., 3., 1., 2., 3., 0., 1., 3., 1., 3., 1., 3., 2., 1., 4., 2., 2., 0., 4., 9., 0., 0., 2., 4., 2., 3., 1., 1., 2., 0., 2., 0., 0., 0., 0., 0., 0., 0., 3., 0., 0., 0 [...]
+
+12., 0., 1., 4., 3., 4., 9., 2., 6., 13., 0., 11., 21., 2., 17., 2., 0., 3., 15., 1., 5., 22., 14., 23., 24., 5., 0., 1., 7., 2., 10., 15., 17., 20., 3., 12., 0., 21., 8., 7., 0., 2., 2., 20., 13., 24., 47., 9., 24., 7., 5., 1., 3., 0., 10., 6., 6., 4., 10., 12., 9., 26., 10., 1., 1., 1., 4., 2., 0., 1., 6., 2., 6., 4., 4., 4., 3., 2., 1., 2., 0., 0., 1., 1., 2., 2., 1., 2., 2., 0., 10., 3., 1., 1., 2., 3., 4., 0., 3., 1., 3., 1., 0., 3., 2., 0., 1., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0 [...]
+
+10., 1., 4., 0., 5., 4., 3., 0., 6., 22., 0., 12., 22., 0., 19., 1., 0., 0., 25., 1., 6., 17., 18., 20., 21., 7., 3., 0., 5., 2., 10., 5., 21., 24., 1., 12., 4., 11., 5., 2., 0., 1., 1., 15., 15., 21., 50., 16., 26., 13., 1., 1., 3., 3., 3., 3., 11., 6., 7., 25., 8., 12., 9., 3., 0., 4., 9., 1., 2., 2., 5., 3., 7., 8., 0., 3., 3., 1., 0., 3., 4., 0., 3., 1., 2., 5., 1., 2., 2., 2., 4., 2., 4., 2., 3., 6., 0., 0., 2., 4., 4., 2., 3., 4., 2., 1., 2., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., [...]
+
+11., 2., 2., 3., 8., 3., 8., 1., 8., 26., 1., 14., 16., 1., 11., 3., 1., 0., 22., 1., 1., 17., 9., 26., 24., 5., 0., 0., 7., 2., 10., 6., 24., 15., 0., 15., 5., 15., 15., 0., 0., 3., 1., 18., 9., 24., 41., 14., 17., 7., 4., 1., 6., 2., 3., 3., 10., 7., 5., 18., 3., 24., 10., 5., 0., 2., 4., 0., 4., 2., 5., 2., 7., 3., 3., 6., 2., 3., 3., 2., 2., 0., 5., 2., 5., 3., 2., 4., 2., 2., 4., 0., 1., 2., 4., 4., 5., 0., 2., 1., 2., 1., 1., 1., 1., 1., 1., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0.,  [...]
+
+11., 1., 3., 8., 11., 2., 7., 0., 12., 21., 2., 13., 18., 1., 14., 3., 2., 3., 19., 3., 3., 25., 19., 28., 27., 6., 2., 0., 1., 3., 11., 10., 26., 15., 2., 14., 4., 15., 10., 2., 2., 5., 1., 11., 12., 11., 45., 15., 21., 13., 5., 1., 4., 8., 4., 4., 8., 5., 8., 11., 3., 16., 12., 1., 4., 4., 5., 0., 1., 1., 4., 2., 3., 5., 0., 5., 3., 4., 1., 3., 1., 0., 1., 1., 0., 4., 2., 2., 4., 2., 2., 1., 3., 1., 1., 6., 5., 0., 1., 2., 5., 3., 2., 2., 2., 2., 3., 0., 0., 0., 0., 0., 0., 0., 1., 0., [...]
+
+11., 0., 3., 6., 11., 4., 4., 1., 1., 20., 0., 14., 22., 1., 18., 4., 0., 1., 10., 2., 5., 13., 17., 37., 26., 7., 2., 2., 3., 1., 11., 6., 30., 22., 5., 16., 5., 16., 10., 6., 2., 3., 2., 9., 13., 25., 51., 14., 33., 12., 4., 1., 5., 1., 5., 5., 11., 9., 4., 12., 4., 26., 2., 4., 1., 1., 7., 1., 1., 3., 11., 5., 2., 3., 5., 3., 0., 4., 0., 1., 3., 0., 2., 2., 1., 3., 2., 3., 0., 3., 3., 2., 2., 0., 4., 8., 2., 0., 4., 2., 1., 1., 1., 1., 0., 3., 1., 0., 0., 0., 0., 4., 0., 0., 4., 0., 0 [...]
+
+6., 1., 4., 4., 11., 3., 3., 1., 6., 18., 3., 15., 27., 1., 15., 1., 1., 0., 25., 2., 4., 29., 9., 19., 19., 5., 2., 0., 2., 1., 5., 9., 32., 20., 4., 16., 5., 10., 5., 0., 1., 5., 1., 13., 12., 12., 42., 11., 31., 9., 6., 2., 1., 2., 7., 5., 8., 2., 6., 18., 9., 23., 13., 0., 0., 1., 8., 2., 4., 1., 4., 1., 2., 3., 0., 5., 2., 1., 0., 1., 7., 0., 0., 0., 2., 2., 1., 2., 3., 0., 4., 0., 7., 0., 3., 5., 1., 0., 3., 1., 3., 1., 3., 0., 1., 0., 0., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0. [...]
+
+9., 0., 4., 2., 5., 2., 9., 1., 6., 30., 0., 17., 32., 1., 12., 4., 1., 2., 12., 2., 6., 32., 15., 21., 29., 11., 0., 0., 3., 0., 7., 10., 33., 19., 7., 13., 3., 15., 7., 3., 1., 4., 0., 12., 6., 21., 44., 10., 33., 8., 6., 0., 4., 0., 9., 4., 11., 3., 7., 11., 5., 15., 9., 1., 0., 2., 5., 2., 1., 3., 4., 2., 6., 4., 2., 4., 1., 1., 1., 0., 3., 0., 3., 2., 2., 8., 4., 7., 5., 2., 3., 1., 2., 1., 5., 9., 6., 0., 4., 1., 2., 2., 3., 5., 0., 2., 2., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0 [...]
+
+18., 3., 4., 8., 33., 9., 40., 1., 18., 172., 4., 25., 202., 7., 15., 5., 1., 4., 79., 2., 15., 306., 50., 350., 52., 19., 1., 3., 6., 4., 36., 25., 214., 48., 7., 150., 15., 29., 5., 0., 1., 13., 15., 82., 17., 95., 12., 34., 35., 7., 2., 0., 29., 3., 29., 11., 50., 13., 16., 4., 14., 11., 3., 0., 2., 0., 19., 6., 8., 6., 19., 8., 22., 3., 2., 4., 0., 3., 2., 3., 8., 5., 13., 4., 10., 0., 0., 4., 136., 5., 1896., 86., 83., 236., 91., 111., 90., 14., 16., 14., 21., 3., 2., 4., 4., 4., 8. [...]
+
+18., 3., 2., 10., 24., 9., 29., 2., 13., 155., 3., 30., 205., 6., 18., 7., 1., 6., 87., 2., 18., 257., 54., 319., 39., 17., 0., 1., 3., 3., 41., 28., 194., 42., 9., 174., 15., 45., 3., 0., 0., 14., 8., 85., 17., 91., 16., 41., 49., 10., 5., 2., 32., 5., 40., 4., 41., 8., 32., 4., 11., 9., 4., 0., 1., 0., 27., 4., 11., 1., 29., 7., 8., 3., 3., 3., 0., 1., 1., 3., 17., 4., 12., 3., 3., 1., 1., 4., 130., 6., 1880., 85., 86., 222., 103., 116., 65., 15., 19., 17., 13., 2., 3., 8., 0., 5., 8., [...]
+
+8., 3., 4., 9., 24., 4., 37., 0., 21., 179., 3., 34., 240., 7., 17., 5., 0., 4., 88., 4., 8., 289., 48., 370., 37., 17., 2., 3., 6., 6., 51., 24., 206., 37., 9., 163., 13., 40., 5., 0., 4., 15., 6., 88., 17., 109., 13., 28., 45., 13., 2., 1., 21., 6., 33., 5., 53., 7., 38., 6., 12., 12., 2., 0., 0., 0., 21., 3., 18., 1., 30., 5., 15., 6., 4., 1., 2., 0., 2., 2., 9., 3., 15., 2., 12., 3., 2., 2., 144., 5., 1875., 98., 94., 224., 103., 90., 80., 16., 11., 18., 14., 2., 2., 7., 4., 4., 7.,  [...]
+
+10., 5., 4., 9., 25., 6., 26., 1., 14., 161., 2., 20., 203., 7., 15., 7., 2., 5., 85., 5., 20., 330., 44., 351., 42., 23., 0., 2., 9., 6., 36., 33., 232., 35., 7., 142., 18., 48., 9., 0., 2., 15., 8., 88., 13., 84., 14., 33., 42., 15., 2., 1., 24., 7., 49., 14., 49., 9., 39., 8., 11., 7., 2., 0., 1., 0., 25., 5., 17., 1., 31., 10., 16., 5., 5., 3., 1., 1., 1., 1., 11., 2., 7., 2., 11., 2., 3., 2., 141., 8., 1924., 87., 89., 217., 93., 129., 65., 15., 13., 13., 8., 1., 5., 9., 4., 5., 6., [...]
+
+22., 1., 2., 7., 17., 4., 36., 0., 14., 167., 4., 24., 207., 6., 17., 11., 3., 6., 97., 3., 12., 264., 54., 352., 37., 17., 0., 1., 11., 7., 50., 45., 209., 31., 7., 136., 15., 35., 3., 0., 1., 19., 8., 73., 21., 89., 13., 43., 38., 21., 2., 0., 25., 4., 34., 8., 48., 8., 33., 9., 3., 9., 1., 0., 0., 0., 29., 2., 11., 3., 29., 3., 9., 6., 2., 2., 0., 0., 7., 2., 8., 1., 6., 2., 11., 0., 1., 5., 162., 13., 1917., 107., 116., 201., 89., 107., 58., 23., 12., 17., 16., 0., 3., 4., 5., 0., 8. [...]
+
+21., 0., 4., 9., 25., 4., 29., 2., 18., 150., 3., 29., 181., 4., 8., 4., 0., 5., 73., 1., 20., 313., 54., 303., 59., 20., 1., 4., 9., 9., 40., 27., 230., 47., 5., 152., 16., 47., 8., 0., 4., 22., 7., 99., 18., 70., 9., 35., 61., 12., 2., 3., 24., 4., 42., 6., 55., 12., 39., 4., 12., 5., 1., 0., 0., 0., 19., 2., 15., 1., 27., 3., 9., 4., 2., 0., 1., 0., 4., 4., 7., 2., 7., 3., 11., 0., 2., 5., 141., 10., 1832., 92., 101., 213., 99., 120., 74., 13., 15., 13., 12., 1., 3., 5., 4., 4., 8., 9 [...]
+
+18., 4., 1., 5., 35., 7., 20., 1., 18., 129., 0., 24., 213., 4., 16., 6., 0., 6., 104., 4., 16., 315., 38., 343., 41., 24., 2., 1., 5., 6., 45., 27., 207., 41., 6., 155., 18., 42., 5., 0., 1., 18., 5., 78., 9., 90., 8., 35., 60., 18., 0., 2., 23., 4., 35., 5., 50., 3., 23., 7., 4., 8., 0., 0., 1., 0., 34., 9., 14., 3., 26., 3., 13., 3., 3., 2., 0., 0., 2., 1., 15., 8., 5., 0., 6., 3., 1., 2., 152., 11., 1958., 77., 71., 237., 87., 111., 72., 18., 11., 23., 12., 1., 2., 8., 7., 5., 6., 5. [...]
+
+7., 0., 2., 4., 28., 8., 29., 0., 18., 152., 2., 22., 199., 3., 22., 6., 1., 5., 96., 1., 13., 294., 58., 330., 36., 14., 0., 4., 6., 6., 39., 41., 242., 44., 11., 144., 8., 43., 10., 0., 2., 17., 9., 88., 19., 71., 15., 38., 45., 15., 5., 0., 25., 6., 36., 19., 35., 7., 28., 0., 8., 7., 2., 0., 2., 0., 19., 6., 13., 3., 33., 7., 14., 8., 3., 1., 0., 0., 3., 0., 13., 5., 14., 1., 13., 2., 1., 5., 142., 9., 1922., 106., 107., 245., 91., 105., 62., 7., 16., 23., 11., 1., 2., 2., 5., 6., 5. [...]
+
+15., 1., 4., 8., 17., 6., 35., 0., 22., 159., 2., 27., 178., 4., 16., 7., 1., 1., 65., 2., 14., 273., 44., 350., 32., 15., 2., 2., 7., 11., 53., 37., 239., 34., 7., 159., 14., 33., 7., 0., 0., 18., 5., 80., 21., 87., 14., 23., 45., 9., 8., 3., 22., 11., 37., 8., 48., 12., 33., 10., 8., 11., 4., 0., 1., 0., 29., 4., 5., 4., 28., 7., 12., 4., 4., 4., 1., 0., 2., 3., 11., 4., 8., 3., 13., 1., 0., 3., 119., 4., 1931., 87., 118., 219., 114., 119., 74., 17., 15., 23., 13., 1., 2., 7., 3., 5.,  [...]
+
+20., 2., 4., 4., 30., 7., 36., 1., 24., 164., 2., 30., 176., 6., 14., 5., 2., 4., 78., 1., 17., 269., 29., 316., 40., 22., 0., 3., 7., 6., 34., 25., 238., 44., 3., 162., 14., 31., 6., 0., 2., 26., 9., 95., 25., 94., 18., 28., 46., 13., 1., 1., 22., 8., 41., 9., 56., 12., 29., 1., 12., 1., 1., 0., 1., 0., 18., 6., 16., 5., 34., 3., 10., 4., 5., 2., 2., 2., 3., 2., 15., 3., 9., 1., 16., 2., 1., 3., 141., 13., 1903., 81., 99., 232., 88., 110., 65., 27., 13., 11., 19., 2., 0., 6., 3., 3., 7. [...]
+
+17., 4., 3., 9., 27., 9., 31., 2., 16., 179., 6., 32., 223., 6., 22., 7., 0., 3., 87., 1., 10., 257., 46., 348., 52., 25., 0., 0., 6., 5., 43., 34., 248., 45., 6., 144., 9., 35., 4., 0., 1., 19., 6., 75., 13., 99., 16., 31., 44., 7., 4., 0., 21., 9., 40., 12., 52., 7., 43., 11., 9., 5., 0., 0., 2., 0., 26., 6., 15., 2., 38., 1., 17., 3., 1., 0., 2., 2., 3., 1., 14., 4., 13., 0., 9., 0., 0., 4., 155., 9., 1801., 97., 95., 218., 118., 109., 72., 13., 12., 15., 11., 1., 2., 3., 6., 9., 5.,  [...]
+
+6., 1., 5., 7., 28., 4., 31., 4., 17., 186., 2., 27., 222., 5., 16., 8., 0., 3., 76., 2., 17., 256., 40., 319., 30., 27., 1., 1., 7., 8., 51., 36., 248., 38., 8., 143., 12., 49., 2., 0., 1., 15., 7., 77., 17., 96., 19., 33., 55., 16., 3., 1., 25., 8., 50., 7., 46., 9., 20., 13., 9., 11., 0., 0., 1., 0., 23., 5., 13., 4., 32., 4., 7., 6., 2., 1., 0., 1., 3., 3., 6., 0., 8., 2., 7., 0., 2., 4., 142., 7., 1840., 95., 112., 219., 95., 98., 67., 11., 20., 20., 10., 2., 3., 5., 6., 7., 7., 4., [...]
+
+18., 3., 1., 6., 27., 6., 37., 1., 22., 173., 8., 24., 167., 5., 15., 7., 1., 8., 98., 0., 16., 292., 54., 357., 37., 21., 0., 3., 5., 8., 30., 23., 240., 40., 12., 153., 12., 32., 4., 0., 3., 19., 6., 76., 22., 83., 12., 40., 40., 12., 3., 2., 25., 7., 40., 7., 45., 7., 38., 3., 12., 9., 6., 0., 0., 0., 19., 4., 17., 2., 23., 4., 7., 5., 3., 4., 2., 1., 1., 1., 9., 3., 8., 2., 7., 1., 3., 5., 132., 10., 1853., 89., 87., 219., 92., 104., 57., 23., 7., 14., 16., 1., 0., 6., 1., 3., 9., 3. [...]
+
+9., 4., 3., 4., 23., 2., 28., 0., 13., 174., 3., 26., 183., 6., 14., 6., 0., 2., 105., 3., 14., 318., 46., 301., 42., 24., 1., 1., 7., 8., 45., 29., 238., 41., 5., 141., 7., 29., 5., 0., 3., 14., 7., 80., 14., 93., 16., 38., 52., 10., 2., 0., 26., 10., 45., 11., 54., 10., 30., 5., 12., 8., 2., 0., 0., 0., 18., 5., 15., 3., 27., 6., 9., 9., 3., 0., 0., 1., 4., 1., 13., 2., 6., 4., 6., 1., 1., 3., 156., 11., 1924., 73., 99., 189., 105., 129., 79., 21., 18., 17., 15., 1., 1., 7., 2., 3., 11 [...]
+
+14., 3., 2., 10., 26., 5., 32., 1., 15., 138., 3., 27., 197., 8., 13., 5., 1., 3., 83., 1., 25., 303., 29., 334., 46., 18., 0., 2., 5., 2., 57., 35., 242., 45., 10., 155., 15., 38., 8., 0., 1., 16., 9., 92., 19., 85., 14., 39., 44., 10., 3., 1., 25., 7., 36., 15., 47., 10., 20., 7., 6., 4., 3., 0., 1., 0., 16., 5., 10., 1., 28., 4., 16., 3., 2., 3., 0., 3., 6., 1., 8., 3., 10., 3., 6., 1., 0., 9., 150., 7., 1913., 84., 91., 220., 101., 100., 56., 16., 7., 11., 15., 0., 4., 7., 4., 2., 8. [...]
+
+19., 2., 2., 4., 21., 4., 29., 2., 3., 163., 0., 24., 182., 5., 18., 5., 0., 4., 79., 5., 12., 290., 42., 327., 53., 14., 2., 2., 6., 3., 45., 32., 220., 49., 8., 183., 13., 37., 1., 0., 2., 22., 15., 66., 20., 86., 18., 38., 45., 14., 2., 1., 20., 5., 40., 12., 51., 8., 36., 9., 9., 6., 4., 0., 0., 0., 19., 4., 15., 2., 32., 6., 7., 3., 3., 2., 1., 0., 4., 7., 10., 6., 9., 3., 6., 1., 1., 3., 146., 7., 1904., 78., 98., 228., 89., 127., 65., 22., 11., 11., 16., 0., 4., 8., 6., 10., 10.,  [...]
+
+9., 1., 0., 6., 20., 6., 39., 1., 21., 151., 2., 23., 206., 6., 20., 6., 0., 7., 81., 1., 19., 294., 53., 353., 43., 17., 0., 3., 7., 6., 44., 32., 236., 40., 7., 158., 13., 48., 6., 0., 2., 10., 11., 85., 18., 93., 11., 33., 44., 8., 2., 2., 44., 6., 45., 5., 49., 12., 26., 8., 11., 8., 3., 0., 3., 0., 22., 4., 9., 5., 27., 7., 11., 5., 2., 5., 2., 0., 3., 1., 11., 1., 7., 4., 16., 3., 1., 5., 123., 12., 1902., 81., 81., 214., 98., 119., 68., 10., 9., 15., 11., 2., 4., 8., 6., 6., 5., 8 [...]
+
+10., 2., 4., 3., 33., 7., 27., 1., 9., 168., 3., 21., 214., 1., 14., 11., 1., 0., 80., 3., 19., 269., 36., 353., 40., 20., 0., 3., 7., 5., 37., 34., 233., 31., 11., 165., 13., 37., 4., 0., 2., 14., 9., 72., 9., 89., 13., 33., 42., 10., 1., 1., 23., 8., 37., 13., 45., 5., 31., 5., 11., 7., 2., 0., 3., 0., 17., 4., 10., 3., 26., 5., 15., 4., 1., 7., 1., 2., 4., 5., 13., 1., 13., 0., 6., 2., 0., 8., 136., 7., 1836., 88., 110., 226., 106., 115., 72., 14., 15., 17., 12., 0., 1., 4., 4., 2., 1 [...]
+
+9., 0., 1., 3., 5., 1., 7., 1., 4., 23., 1., 14., 24., 2., 13., 6., 2., 1., 17., 1., 11., 28., 12., 35., 27., 5., 2., 2., 1., 1., 9., 4., 27., 15., 4., 18., 6., 13., 11., 0., 1., 5., 2., 10., 14., 16., 53., 16., 23., 8., 3., 1., 3., 3., 4., 0., 10., 3., 15., 15., 2., 18., 7., 4., 3., 0., 3., 0., 7., 0., 8., 3., 4., 3., 1., 6., 3., 1., 0., 3., 3., 0., 2., 2., 4., 10., 1., 2., 3., 3., 5., 0., 2., 0., 0., 5., 3., 0., 3., 3., 2., 1., 2., 3., 1., 0., 2., 0., 0., 0., 0., 3., 0., 0., 5., 0., 0. [...]
+
+11., 2., 0., 2., 12., 1., 3., 0., 7., 22., 1., 10., 16., 0., 12., 4., 0., 3., 22., 1., 3., 18., 10., 25., 23., 4., 1., 1., 2., 2., 9., 6., 24., 16., 2., 16., 8., 16., 5., 2., 0., 2., 1., 12., 9., 13., 53., 15., 27., 8., 7., 1., 7., 1., 3., 2., 11., 5., 12., 14., 5., 26., 8., 3., 0., 0., 9., 3., 4., 7., 1., 1., 2., 4., 1., 2., 4., 3., 1., 1., 3., 0., 2., 1., 2., 4., 2., 3., 3., 6., 1., 1., 4., 2., 4., 8., 1., 0., 1., 2., 2., 3., 3., 1., 0., 1., 4., 0., 0., 0., 0., 6., 0., 0., 2., 0., 0.,  [...]
+
+6., 0., 6., 7., 6., 3., 2., 2., 4., 24., 2., 14., 22., 0., 9., 2., 0., 2., 13., 1., 3., 14., 23., 28., 27., 8., 1., 1., 4., 1., 7., 7., 15., 19., 2., 6., 5., 15., 11., 0., 0., 3., 1., 9., 14., 20., 50., 16., 14., 12., 4., 0., 4., 2., 13., 5., 15., 9., 6., 12., 3., 12., 5., 3., 2., 0., 11., 1., 6., 0., 2., 4., 2., 7., 1., 8., 4., 3., 1., 1., 3., 0., 2., 1., 3., 3., 1., 3., 0., 0., 5., 1., 2., 0., 3., 6., 0., 0., 0., 3., 5., 1., 3., 1., 0., 0., 4., 0., 0., 0., 0., 2., 0., 0., 4., 0., 0., 0 [...]
+
+2., 2., 2., 7., 5., 1., 10., 2., 4., 16., 0., 13., 17., 0., 20., 4., 0., 1., 25., 2., 2., 20., 9., 18., 28., 6., 1., 0., 1., 1., 10., 8., 21., 17., 2., 14., 4., 16., 8., 1., 1., 5., 2., 14., 12., 22., 54., 21., 25., 8., 6., 1., 9., 3., 6., 3., 10., 5., 15., 9., 6., 24., 8., 3., 1., 1., 7., 3., 6., 4., 3., 4., 4., 8., 2., 5., 0., 2., 1., 2., 2., 0., 0., 2., 3., 3., 3., 11., 0., 4., 7., 0., 0., 0., 1., 9., 3., 0., 1., 2., 1., 2., 4., 2., 1., 2., 2., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0.,  [...]
+
+12., 2., 1., 2., 10., 3., 9., 0., 5., 35., 1., 11., 20., 1., 10., 1., 0., 1., 11., 1., 4., 27., 13., 25., 25., 13., 1., 1., 3., 1., 13., 10., 35., 12., 2., 15., 3., 13., 6., 4., 1., 2., 1., 12., 8., 22., 48., 7., 17., 12., 6., 1., 7., 2., 9., 4., 15., 4., 10., 19., 5., 23., 4., 4., 0., 1., 5., 1., 5., 2., 7., 1., 8., 2., 5., 0., 1., 7., 1., 1., 2., 0., 2., 3., 2., 3., 1., 3., 4., 3., 6., 0., 1., 2., 1., 4., 1., 0., 4., 1., 1., 1., 1., 3., 1., 1., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0 [...]
+
+8., 0., 1., 4., 8., 2., 5., 0., 9., 19., 0., 16., 26., 1., 12., 0., 0., 2., 13., 1., 3., 15., 7., 14., 17., 4., 1., 2., 2., 5., 6., 4., 24., 13., 6., 18., 3., 22., 10., 1., 2., 1., 2., 12., 12., 18., 37., 9., 17., 7., 3., 2., 6., 4., 6., 5., 7., 4., 9., 13., 11., 15., 9., 1., 1., 1., 7., 2., 1., 3., 6., 4., 3., 4., 3., 4., 4., 3., 1., 1., 1., 0., 2., 1., 1., 5., 3., 2., 1., 3., 1., 3., 0., 0., 5., 10., 2., 0., 1., 3., 2., 3., 0., 1., 0., 1., 0., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+12., 0., 0., 3., 6., 3., 7., 1., 3., 27., 0., 13., 20., 1., 8., 5., 0., 6., 14., 0., 6., 29., 13., 23., 15., 6., 1., 1., 4., 2., 10., 3., 24., 24., 1., 13., 2., 19., 7., 3., 2., 3., 3., 11., 11., 16., 60., 16., 27., 9., 6., 1., 5., 2., 9., 4., 14., 5., 7., 19., 4., 26., 8., 0., 1., 1., 4., 0., 2., 3., 6., 6., 5., 9., 0., 2., 3., 3., 0., 2., 3., 0., 2., 0., 2., 6., 3., 3., 0., 2., 3., 2., 2., 0., 5., 5., 2., 0., 1., 0., 1., 4., 2., 5., 3., 0., 1., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., 0 [...]
+
+4., 1., 3., 3., 4., 3., 5., 1., 6., 28., 2., 12., 19., 1., 17., 2., 3., 2., 22., 0., 4., 15., 11., 21., 24., 9., 3., 3., 2., 3., 9., 6., 30., 19., 2., 17., 3., 11., 9., 1., 0., 4., 3., 9., 16., 17., 45., 12., 22., 11., 3., 1., 4., 1., 4., 1., 13., 4., 5., 20., 2., 18., 9., 1., 0., 2., 5., 0., 3., 1., 7., 3., 4., 2., 0., 4., 1., 1., 0., 4., 1., 0., 1., 2., 1., 9., 1., 7., 5., 0., 4., 0., 1., 2., 3., 5., 4., 0., 1., 3., 4., 3., 2., 0., 1., 0., 2., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., 0. [...]
+
+7., 2., 2., 5., 6., 3., 1., 2., 9., 29., 1., 4., 20., 0., 16., 3., 3., 2., 17., 1., 2., 30., 20., 17., 28., 9., 2., 2., 5., 0., 9., 7., 18., 15., 2., 26., 0., 21., 8., 1., 0., 6., 1., 20., 4., 16., 49., 10., 21., 5., 4., 1., 10., 4., 6., 3., 10., 7., 6., 15., 10., 31., 12., 1., 3., 2., 1., 1., 3., 1., 4., 1., 1., 2., 1., 6., 3., 1., 0., 3., 1., 0., 2., 3., 3., 2., 3., 3., 2., 2., 5., 1., 2., 2., 0., 3., 2., 0., 1., 1., 4., 3., 2., 3., 1., 1., 3., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0 [...]
+
+5., 1., 3., 3., 10., 1., 5., 3., 7., 17., 0., 10., 28., 2., 13., 2., 2., 4., 21., 1., 2., 34., 7., 28., 23., 3., 1., 1., 0., 2., 5., 8., 37., 7., 3., 19., 4., 17., 9., 1., 0., 3., 3., 5., 11., 20., 41., 12., 21., 14., 4., 1., 3., 3., 6., 1., 11., 3., 11., 17., 4., 17., 6., 7., 1., 0., 6., 0., 4., 2., 4., 4., 5., 6., 2., 2., 2., 1., 1., 3., 4., 0., 3., 1., 2., 5., 1., 5., 2., 5., 2., 2., 1., 1., 1., 8., 1., 0., 1., 3., 0., 1., 2., 2., 2., 0., 5., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0. [...]
+
+6., 1., 1., 2., 4., 2., 5., 0., 6., 27., 1., 12., 23., 2., 17., 3., 3., 2., 14., 3., 2., 20., 16., 30., 35., 9., 2., 0., 4., 0., 9., 4., 23., 12., 7., 12., 5., 17., 9., 3., 0., 4., 3., 14., 7., 28., 44., 13., 16., 9., 7., 1., 7., 3., 10., 3., 5., 7., 6., 14., 3., 20., 11., 5., 0., 1., 4., 0., 4., 3., 7., 2., 8., 2., 0., 5., 2., 3., 1., 1., 1., 0., 3., 0., 1., 5., 2., 3., 0., 4., 5., 0., 2., 0., 2., 11., 1., 0., 1., 1., 1., 2., 4., 2., 1., 2., 1., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0 [...]
+
+8., 2., 5., 2., 6., 4., 5., 2., 5., 25., 2., 14., 24., 0., 17., 1., 3., 1., 21., 3., 7., 20., 20., 23., 23., 3., 0., 1., 1., 2., 9., 5., 23., 20., 4., 15., 4., 14., 7., 3., 1., 1., 0., 17., 17., 16., 48., 17., 21., 8., 3., 0., 7., 4., 5., 3., 12., 7., 12., 19., 7., 22., 9., 0., 1., 0., 12., 4., 2., 0., 4., 0., 3., 1., 0., 1., 2., 3., 0., 4., 1., 0., 1., 1., 8., 7., 1., 5., 4., 2., 4., 3., 3., 0., 0., 11., 1., 0., 0., 2., 2., 2., 1., 0., 2., 1., 1., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., [...]
+
+10., 1., 1., 4., 10., 6., 6., 0., 2., 28., 0., 7., 28., 2., 12., 2., 1., 5., 19., 2., 7., 22., 17., 29., 42., 5., 0., 0., 2., 5., 5., 3., 22., 10., 3., 8., 2., 17., 11., 1., 0., 6., 2., 8., 14., 10., 42., 13., 19., 11., 4., 4., 4., 2., 9., 4., 13., 4., 11., 15., 8., 26., 8., 4., 1., 2., 3., 2., 3., 3., 4., 3., 5., 3., 5., 1., 5., 2., 2., 1., 3., 0., 3., 0., 4., 3., 1., 3., 2., 1., 5., 1., 2., 2., 0., 6., 2., 0., 0., 1., 7., 1., 2., 3., 0., 0., 1., 0., 0., 0., 0., 4., 0., 0., 0., 0., 0.,  [...]
+
+12., 3., 3., 7., 12., 3., 8., 1., 2., 29., 0., 10., 25., 0., 18., 4., 3., 0., 11., 1., 7., 23., 8., 37., 35., 2., 3., 2., 4., 2., 10., 8., 33., 16., 7., 17., 3., 14., 10., 2., 0., 6., 2., 7., 13., 20., 33., 15., 23., 9., 3., 1., 7., 5., 4., 4., 9., 6., 6., 20., 11., 32., 8., 4., 1., 2., 6., 0., 6., 1., 7., 2., 3., 8., 2., 5., 3., 2., 2., 6., 0., 0., 3., 1., 3., 4., 1., 7., 1., 1., 2., 1., 2., 0., 3., 9., 4., 0., 1., 1., 1., 3., 2., 4., 0., 3., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0.,  [...]
+
+10., 3., 5., 7., 26., 5., 35., 2., 16., 148., 2., 29., 219., 4., 21., 6., 1., 8., 73., 1., 17., 256., 41., 324., 46., 22., 3., 2., 12., 7., 43., 25., 236., 40., 8., 156., 16., 33., 7., 0., 3., 18., 14., 101., 22., 73., 22., 45., 37., 6., 6., 1., 30., 8., 43., 7., 46., 13., 31., 6., 14., 8., 2., 0., 2., 0., 19., 6., 11., 3., 28., 4., 18., 7., 2., 6., 0., 1., 2., 1., 12., 2., 9., 2., 7., 1., 0., 5., 136., 7., 1863., 90., 97., 220., 113., 118., 58., 13., 15., 18., 15., 1., 0., 4., 6., 8., 1 [...]
+
+9., 1., 3., 5., 25., 3., 31., 2., 11., 162., 2., 25., 223., 3., 21., 9., 1., 7., 76., 5., 14., 300., 34., 354., 57., 21., 0., 3., 4., 4., 43., 23., 249., 39., 12., 169., 16., 46., 5., 0., 2., 14., 9., 86., 15., 78., 15., 47., 51., 12., 2., 1., 24., 7., 51., 15., 54., 12., 30., 3., 8., 9., 0., 0., 0., 0., 20., 8., 16., 5., 31., 4., 11., 4., 3., 2., 0., 0., 4., 3., 14., 0., 10., 1., 12., 1., 1., 5., 135., 7., 1795., 81., 99., 214., 97., 136., 73., 11., 13., 22., 11., 2., 0., 4., 7., 4., 7. [...]
+
+10., 2., 2., 11., 26., 8., 36., 1., 18., 176., 6., 17., 205., 3., 17., 4., 1., 6., 69., 0., 16., 258., 47., 326., 47., 14., 1., 2., 12., 1., 42., 35., 231., 50., 9., 163., 17., 35., 6., 0., 0., 25., 6., 84., 12., 90., 17., 36., 43., 16., 2., 0., 20., 6., 31., 7., 54., 4., 35., 5., 8., 4., 0., 0., 1., 0., 28., 6., 17., 6., 23., 7., 14., 9., 2., 5., 1., 1., 1., 1., 10., 3., 8., 3., 7., 1., 1., 3., 145., 9., 1901., 100., 91., 231., 99., 112., 66., 10., 8., 23., 9., 2., 1., 4., 4., 5., 8., 9 [...]
+
+12., 5., 2., 7., 27., 11., 30., 1., 21., 140., 6., 18., 211., 3., 17., 11., 1., 4., 86., 1., 18., 306., 48., 326., 41., 16., 1., 4., 6., 6., 45., 26., 230., 38., 5., 164., 10., 39., 6., 0., 1., 20., 11., 79., 17., 87., 12., 50., 53., 9., 5., 5., 20., 7., 34., 9., 53., 5., 26., 5., 8., 6., 1., 0., 1., 0., 22., 8., 10., 3., 22., 3., 17., 4., 1., 2., 1., 0., 5., 0., 7., 6., 7., 2., 10., 0., 1., 7., 133., 9., 1784., 86., 89., 198., 88., 134., 70., 15., 9., 16., 10., 0., 2., 4., 9., 5., 5., 8 [...]
+
+13., 3., 1., 4., 18., 10., 26., 1., 19., 170., 4., 30., 215., 3., 17., 13., 0., 4., 104., 0., 15., 281., 48., 312., 44., 12., 0., 3., 6., 6., 45., 40., 211., 32., 5., 150., 14., 49., 5., 0., 1., 16., 8., 78., 21., 75., 13., 21., 40., 17., 1., 1., 24., 8., 41., 6., 57., 7., 31., 8., 8., 6., 0., 0., 1., 0., 24., 10., 16., 7., 33., 3., 9., 7., 1., 2., 4., 2., 5., 4., 12., 1., 6., 1., 3., 1., 1., 5., 171., 6., 1787., 77., 91., 262., 92., 113., 68., 16., 11., 15., 10., 1., 3., 8., 5., 3., 10. [...]
+
+9., 2., 2., 10., 31., 7., 37., 0., 11., 165., 4., 36., 192., 5., 11., 5., 1., 5., 81., 2., 11., 288., 39., 329., 48., 18., 1., 3., 4., 3., 34., 30., 238., 46., 8., 144., 14., 38., 6., 0., 1., 26., 10., 73., 21., 75., 14., 25., 49., 9., 1., 0., 29., 7., 41., 8., 50., 10., 39., 9., 12., 6., 1., 0., 1., 0., 28., 2., 13., 3., 18., 4., 11., 7., 3., 0., 3., 1., 2., 1., 7., 4., 7., 1., 9., 0., 1., 5., 137., 9., 1915., 108., 121., 224., 106., 123., 74., 18., 8., 17., 15., 1., 1., 6., 5., 7., 11. [...]
+
+11., 0., 5., 10., 20., 5., 22., 2., 9., 170., 5., 31., 207., 4., 17., 9., 1., 6., 90., 0., 13., 300., 42., 311., 48., 23., 0., 1., 7., 6., 44., 28., 228., 38., 6., 152., 22., 28., 4., 0., 5., 22., 12., 73., 25., 81., 14., 48., 47., 10., 3., 0., 21., 10., 47., 10., 40., 9., 32., 4., 8., 1., 1., 0., 2., 0., 25., 2., 14., 9., 19., 2., 9., 4., 1., 3., 1., 0., 5., 2., 16., 3., 11., 0., 12., 0., 2., 7., 145., 11., 1911., 94., 116., 217., 95., 117., 80., 14., 9., 32., 11., 2., 1., 3., 8., 5., 9 [...]
+
+14., 3., 0., 7., 18., 7., 30., 1., 21., 140., 5., 27., 173., 8., 18., 7., 3., 4., 80., 0., 13., 269., 42., 344., 47., 14., 1., 0., 6., 1., 49., 29., 213., 46., 5., 143., 11., 41., 4., 0., 2., 21., 8., 76., 19., 71., 13., 27., 45., 17., 1., 2., 22., 8., 28., 10., 40., 3., 28., 6., 12., 6., 3., 0., 1., 0., 22., 5., 17., 5., 26., 7., 8., 6., 1., 2., 0., 1., 5., 2., 12., 1., 7., 4., 7., 1., 0., 3., 140., 9., 1832., 90., 107., 197., 96., 126., 62., 22., 9., 16., 9., 2., 4., 3., 5., 4., 10., 3 [...]
+
+13., 1., 1., 8., 27., 6., 33., 0., 21., 158., 3., 35., 217., 6., 12., 8., 2., 7., 71., 1., 11., 265., 35., 303., 36., 10., 2., 4., 7., 3., 45., 36., 230., 40., 10., 164., 16., 30., 4., 0., 1., 23., 8., 96., 17., 87., 24., 44., 46., 19., 3., 2., 26., 12., 46., 12., 43., 10., 31., 5., 9., 15., 0., 0., 4., 0., 29., 3., 15., 1., 25., 4., 14., 2., 1., 4., 2., 1., 1., 1., 10., 4., 11., 2., 5., 1., 0., 1., 142., 7., 1875., 89., 121., 205., 111., 112., 73., 17., 10., 16., 17., 1., 2., 9., 1., 5. [...]
+
+18., 0., 3., 11., 29., 7., 26., 1., 14., 169., 1., 27., 206., 1., 9., 9., 0., 6., 93., 1., 12., 293., 43., 331., 41., 19., 1., 3., 6., 4., 38., 31., 244., 41., 12., 167., 12., 39., 5., 0., 3., 16., 6., 57., 15., 98., 8., 26., 51., 14., 4., 1., 22., 8., 36., 10., 56., 9., 18., 6., 15., 7., 2., 0., 2., 0., 31., 6., 15., 5., 36., 3., 11., 2., 4., 0., 0., 2., 1., 3., 14., 3., 5., 5., 5., 1., 0., 4., 143., 9., 1944., 90., 98., 210., 91., 120., 81., 15., 18., 10., 11., 0., 2., 5., 5., 4., 11., [...]
+
+21., 1., 2., 9., 23., 3., 38., 1., 16., 154., 4., 26., 220., 5., 22., 5., 0., 6., 76., 2., 13., 272., 37., 316., 40., 25., 1., 1., 9., 9., 45., 34., 240., 36., 7., 155., 8., 39., 7., 0., 3., 16., 11., 78., 14., 108., 16., 47., 49., 10., 1., 2., 20., 8., 28., 11., 40., 11., 29., 4., 9., 16., 1., 0., 0., 0., 20., 5., 9., 5., 23., 10., 11., 4., 3., 4., 0., 0., 5., 1., 6., 2., 8., 3., 8., 0., 1., 5., 161., 12., 1840., 100., 101., 195., 97., 116., 65., 17., 14., 23., 11., 1., 6., 5., 3., 5.,  [...]
+
+11., 3., 0., 9., 28., 5., 37., 0., 12., 147., 2., 33., 194., 5., 5., 5., 1., 3., 82., 2., 18., 312., 39., 311., 36., 16., 0., 1., 7., 2., 46., 37., 231., 45., 11., 146., 14., 38., 6., 0., 2., 13., 8., 73., 19., 73., 16., 28., 31., 19., 1., 0., 32., 5., 35., 10., 36., 5., 30., 6., 13., 8., 1., 0., 0., 0., 24., 2., 16., 4., 30., 4., 8., 6., 0., 4., 0., 2., 0., 7., 10., 2., 9., 3., 13., 1., 0., 4., 138., 8., 1872., 102., 91., 205., 112., 89., 49., 15., 14., 15., 9., 1., 2., 9., 11., 4., 12. [...]
+
+20., 3., 2., 2., 28., 7., 35., 1., 14., 136., 6., 31., 189., 3., 17., 8., 1., 1., 73., 1., 15., 270., 41., 320., 32., 20., 0., 2., 7., 4., 52., 44., 255., 31., 9., 151., 24., 31., 5., 0., 1., 8., 9., 80., 27., 80., 9., 38., 37., 17., 6., 1., 22., 9., 37., 14., 64., 8., 30., 6., 10., 4., 0., 0., 1., 0., 28., 8., 7., 3., 31., 6., 14., 4., 4., 1., 0., 0., 1., 1., 19., 5., 12., 1., 13., 0., 1., 3., 126., 7., 1937., 95., 103., 234., 90., 129., 56., 12., 8., 18., 17., 0., 0., 4., 2., 7., 13.,  [...]
+
+15., 3., 1., 6., 24., 6., 34., 0., 20., 142., 2., 31., 198., 5., 10., 7., 2., 3., 86., 4., 20., 262., 45., 361., 48., 18., 2., 3., 14., 3., 37., 29., 254., 39., 8., 185., 10., 39., 7., 0., 2., 17., 6., 82., 11., 81., 15., 26., 35., 20., 2., 0., 23., 7., 35., 8., 61., 18., 38., 7., 10., 6., 1., 0., 0., 0., 22., 6., 17., 2., 26., 6., 16., 7., 3., 1., 0., 0., 3., 1., 10., 3., 9., 2., 9., 0., 1., 2., 130., 11., 1826., 86., 121., 175., 96., 116., 62., 18., 17., 14., 16., 1., 2., 2., 4., 3., 7 [...]
+
+18., 2., 1., 8., 27., 8., 21., 1., 8., 159., 3., 29., 228., 4., 10., 5., 2., 10., 79., 2., 15., 254., 60., 377., 52., 22., 2., 1., 5., 8., 43., 33., 225., 40., 6., 134., 9., 47., 3., 0., 0., 15., 11., 97., 12., 78., 17., 36., 52., 12., 2., 0., 22., 5., 34., 10., 38., 9., 27., 3., 13., 9., 6., 0., 1., 0., 16., 10., 15., 7., 33., 1., 10., 1., 3., 2., 1., 0., 5., 2., 15., 3., 5., 1., 8., 2., 0., 6., 130., 6., 1966., 93., 117., 203., 108., 118., 72., 20., 10., 16., 19., 0., 0., 7., 8., 5., 6 [...]
+
+13., 1., 3., 4., 29., 5., 30., 2., 17., 169., 3., 19., 176., 5., 26., 6., 0., 9., 77., 1., 11., 298., 50., 339., 48., 11., 3., 1., 4., 3., 43., 31., 267., 45., 8., 159., 15., 45., 4., 0., 7., 16., 12., 61., 21., 89., 24., 45., 57., 13., 2., 2., 32., 6., 34., 9., 50., 13., 31., 11., 12., 3., 1., 0., 1., 0., 30., 3., 12., 2., 27., 4., 15., 5., 5., 1., 2., 1., 2., 2., 14., 1., 4., 5., 7., 0., 0., 6., 152., 7., 1859., 105., 115., 203., 102., 107., 72., 20., 17., 21., 19., 1., 5., 6., 4., 8., [...]
+
+15., 1., 1., 7., 30., 12., 30., 0., 11., 158., 2., 29., 187., 2., 16., 9., 1., 8., 76., 2., 16., 300., 37., 347., 42., 10., 1., 2., 6., 5., 38., 33., 235., 48., 6., 165., 9., 38., 6., 0., 3., 15., 9., 76., 15., 105., 19., 39., 38., 20., 2., 1., 30., 6., 43., 12., 55., 6., 34., 5., 7., 4., 2., 0., 1., 0., 21., 6., 20., 2., 35., 4., 16., 4., 1., 3., 0., 1., 7., 1., 14., 3., 9., 2., 6., 2., 0., 3., 143., 9., 1865., 68., 107., 211., 102., 129., 64., 12., 14., 18., 15., 1., 0., 5., 7., 3., 7. [...]
+
+1., 1., 2., 5., 1., 3., 5., 0., 5., 21., 0., 10., 25., 3., 16., 2., 0., 1., 27., 1., 7., 26., 8., 28., 27., 9., 0., 3., 7., 3., 4., 9., 33., 17., 3., 14., 5., 22., 7., 2., 2., 2., 5., 13., 15., 19., 43., 6., 25., 11., 5., 1., 10., 2., 10., 4., 10., 4., 7., 19., 8., 20., 6., 4., 1., 0., 7., 1., 2., 3., 6., 3., 3., 2., 0., 3., 2., 1., 1., 3., 3., 0., 3., 1., 0., 2., 3., 1., 1., 4., 5., 0., 3., 2., 1., 5., 5., 0., 9., 3., 3., 3., 0., 1., 2., 0., 1., 0., 0., 0., 0., 3., 0., 0., 4., 0., 0., 0 [...]
+
+12., 2., 3., 4., 11., 2., 4., 1., 4., 25., 1., 8., 21., 2., 17., 1., 0., 2., 18., 2., 4., 29., 17., 35., 27., 10., 1., 0., 1., 1., 11., 7., 35., 18., 0., 24., 7., 16., 5., 4., 1., 0., 2., 13., 18., 12., 45., 14., 17., 11., 1., 3., 8., 1., 9., 4., 11., 3., 11., 18., 3., 21., 4., 1., 0., 0., 10., 1., 4., 1., 5., 4., 7., 5., 1., 8., 4., 0., 0., 1., 0., 0., 1., 4., 2., 4., 3., 3., 0., 6., 2., 1., 3., 2., 0., 9., 2., 0., 3., 2., 0., 2., 2., 5., 3., 1., 2., 0., 0., 0., 0., 5., 0., 0., 5., 0.,  [...]
+
+11., 0., 1., 1., 10., 2., 4., 1., 4., 25., 1., 9., 27., 1., 8., 1., 0., 1., 25., 0., 4., 19., 13., 37., 25., 8., 0., 0., 4., 2., 10., 6., 36., 13., 3., 11., 7., 16., 10., 1., 0., 4., 1., 11., 10., 15., 58., 11., 19., 8., 7., 0., 6., 2., 2., 2., 10., 7., 5., 16., 5., 16., 8., 7., 0., 1., 6., 0., 5., 2., 5., 8., 3., 4., 3., 4., 4., 0., 1., 0., 1., 0., 3., 3., 2., 5., 2., 1., 2., 1., 2., 0., 3., 2., 2., 4., 1., 0., 1., 3., 4., 2., 2., 2., 2., 3., 1., 0., 0., 0., 0., 2., 0., 0., 4., 0., 0.,  [...]
+
+4., 1., 0., 1., 8., 5., 8., 0., 2., 7., 3., 11., 28., 1., 7., 1., 0., 2., 18., 0., 6., 18., 11., 29., 34., 6., 1., 1., 3., 2., 13., 7., 34., 24., 4., 19., 4., 13., 2., 2., 1., 8., 2., 11., 13., 15., 36., 17., 21., 9., 5., 1., 6., 0., 5., 2., 7., 5., 4., 16., 8., 32., 10., 4., 1., 1., 8., 0., 7., 3., 5., 0., 4., 3., 3., 4., 1., 1., 0., 1., 0., 0., 0., 2., 2., 2., 1., 3., 1., 3., 3., 0., 0., 2., 2., 10., 3., 0., 1., 3., 1., 3., 1., 2., 1., 1., 1., 0., 0., 0., 0., 5., 0., 0., 1., 0., 0., 0. [...]
+
+12., 0., 5., 5., 9., 0., 2., 0., 7., 16., 0., 9., 16., 0., 12., 3., 0., 2., 20., 3., 6., 22., 11., 35., 18., 4., 2., 0., 2., 2., 8., 11., 23., 16., 1., 17., 0., 18., 10., 1., 1., 7., 0., 15., 10., 23., 39., 14., 32., 6., 1., 2., 5., 0., 3., 4., 13., 7., 7., 19., 19., 20., 10., 2., 0., 1., 7., 1., 6., 0., 5., 2., 6., 4., 2., 7., 1., 2., 1., 3., 3., 0., 0., 0., 2., 4., 1., 0., 3., 3., 1., 1., 3., 1., 1., 7., 2., 0., 4., 2., 1., 1., 0., 0., 2., 0., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0. [...]
+
+4., 0., 1., 2., 8., 4., 3., 0., 4., 18., 1., 8., 19., 1., 19., 2., 0., 3., 16., 0., 1., 29., 10., 20., 31., 9., 1., 1., 4., 3., 2., 7., 33., 15., 6., 29., 6., 9., 7., 2., 1., 6., 3., 16., 10., 20., 46., 11., 19., 7., 4., 3., 3., 1., 8., 2., 10., 6., 7., 10., 5., 20., 4., 2., 0., 2., 12., 0., 5., 4., 4., 5., 3., 1., 0., 5., 1., 1., 1., 3., 1., 0., 3., 1., 4., 3., 2., 5., 0., 3., 4., 1., 0., 0., 2., 7., 1., 0., 4., 1., 2., 2., 1., 1., 3., 1., 2., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., [...]
+
+9., 0., 4., 2., 5., 3., 6., 2., 7., 9., 2., 19., 22., 0., 24., 2., 0., 3., 15., 1., 4., 18., 8., 20., 31., 7., 2., 0., 4., 4., 7., 6., 26., 15., 4., 22., 4., 18., 8., 1., 0., 6., 1., 11., 11., 21., 46., 14., 18., 15., 3., 0., 7., 1., 10., 6., 8., 5., 12., 18., 7., 28., 7., 3., 2., 2., 10., 1., 2., 1., 10., 2., 4., 1., 3., 3., 4., 1., 1., 3., 1., 0., 0., 2., 0., 5., 0., 8., 3., 2., 5., 0., 3., 3., 4., 2., 4., 0., 2., 3., 2., 2., 1., 2., 2., 1., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0.,  [...]
+
+4., 0., 2., 3., 13., 2., 6., 0., 3., 18., 1., 16., 26., 1., 14., 4., 0., 1., 23., 4., 1., 18., 10., 15., 25., 7., 0., 3., 1., 1., 10., 10., 14., 21., 5., 21., 2., 15., 10., 0., 0., 4., 3., 14., 12., 24., 53., 9., 14., 8., 2., 1., 5., 1., 10., 2., 7., 7., 5., 17., 5., 24., 16., 2., 1., 1., 7., 0., 1., 3., 3., 5., 0., 4., 0., 3., 2., 2., 2., 1., 2., 0., 0., 5., 3., 5., 0., 8., 2., 3., 5., 1., 3., 1., 3., 10., 1., 0., 2., 1., 1., 2., 2., 3., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 4., 0., 0 [...]
+
+1., 3., 2., 1., 10., 1., 6., 1., 5., 21., 4., 12., 19., 1., 16., 3., 1., 0., 27., 2., 3., 35., 8., 28., 24., 8., 2., 2., 0., 4., 9., 6., 23., 19., 3., 15., 3., 19., 13., 3., 1., 6., 1., 12., 7., 16., 46., 12., 16., 7., 7., 1., 7., 4., 5., 2., 10., 8., 11., 16., 9., 16., 11., 1., 1., 1., 8., 2., 3., 4., 2., 1., 6., 6., 4., 4., 2., 1., 3., 1., 2., 0., 1., 3., 0., 5., 1., 7., 2., 1., 6., 2., 2., 1., 1., 10., 2., 0., 0., 1., 3., 3., 2., 1., 2., 2., 1., 0., 0., 0., 0., 4., 0., 0., 5., 0., 0., [...]
+
+9., 0., 4., 3., 6., 2., 6., 1., 7., 22., 0., 7., 8., 1., 16., 1., 1., 1., 18., 1., 6., 37., 20., 20., 34., 1., 1., 0., 0., 4., 13., 6., 25., 14., 4., 12., 4., 12., 16., 4., 1., 4., 1., 6., 8., 15., 50., 12., 15., 9., 4., 0., 7., 3., 8., 4., 8., 11., 10., 13., 3., 21., 10., 1., 2., 2., 4., 3., 4., 0., 6., 5., 2., 5., 2., 9., 6., 2., 1., 3., 2., 0., 1., 0., 1., 4., 1., 7., 0., 1., 3., 0., 2., 1., 1., 9., 2., 0., 1., 1., 1., 3., 2., 5., 1., 0., 4., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. [...]
+
+10., 2., 1., 4., 6., 1., 10., 0., 6., 24., 1., 9., 43., 1., 18., 3., 1., 5., 16., 1., 2., 24., 10., 34., 20., 7., 2., 1., 2., 1., 7., 1., 43., 18., 3., 14., 5., 15., 7., 3., 2., 7., 3., 10., 14., 28., 47., 11., 22., 13., 4., 3., 7., 3., 10., 3., 8., 6., 11., 13., 6., 24., 10., 1., 1., 1., 8., 0., 2., 2., 8., 3., 3., 5., 1., 5., 3., 4., 1., 4., 1., 0., 2., 2., 3., 5., 0., 6., 1., 4., 1., 1., 1., 1., 4., 8., 3., 0., 3., 0., 2., 1., 2., 3., 4., 1., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0. [...]
+
+10., 1., 2., 5., 8., 0., 7., 0., 6., 18., 2., 19., 22., 1., 18., 3., 0., 3., 13., 1., 3., 27., 12., 35., 22., 5., 1., 0., 3., 2., 5., 3., 23., 16., 1., 17., 6., 15., 7., 1., 2., 6., 1., 8., 18., 16., 42., 16., 24., 8., 6., 1., 9., 3., 4., 1., 5., 5., 7., 15., 9., 23., 9., 2., 1., 0., 9., 2., 6., 2., 3., 1., 3., 3., 1., 7., 2., 0., 0., 4., 3., 0., 1., 2., 1., 6., 5., 8., 1., 4., 4., 0., 3., 1., 2., 3., 2., 0., 4., 2., 0., 1., 3., 0., 0., 1., 1., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., [...]
+
+5., 0., 3., 5., 11., 2., 2., 2., 7., 29., 0., 15., 17., 1., 17., 1., 2., 4., 28., 4., 4., 22., 13., 16., 24., 7., 2., 0., 2., 2., 11., 11., 21., 12., 2., 9., 0., 10., 8., 1., 1., 1., 1., 11., 12., 11., 40., 20., 16., 13., 5., 0., 7., 2., 5., 1., 9., 3., 4., 17., 5., 32., 3., 3., 3., 1., 8., 0., 7., 1., 3., 5., 6., 5., 4., 6., 7., 4., 2., 5., 1., 0., 0., 5., 2., 6., 3., 4., 1., 3., 7., 1., 4., 2., 2., 3., 2., 0., 2., 3., 0., 3., 1., 3., 1., 0., 2., 0., 0., 0., 0., 4., 0., 0., 0., 0., 0.,  [...]
+
+8., 1., 3., 5., 8., 0., 3., 0., 8., 21., 1., 16., 23., 1., 15., 3., 2., 2., 20., 1., 5., 33., 15., 12., 29., 1., 0., 0., 3., 1., 7., 5., 30., 22., 3., 9., 5., 15., 8., 2., 2., 1., 3., 11., 14., 21., 33., 7., 23., 12., 2., 2., 4., 1., 10., 5., 17., 7., 6., 14., 9., 29., 10., 1., 0., 1., 7., 1., 3., 1., 10., 3., 4., 4., 2., 3., 1., 0., 0., 1., 4., 0., 6., 1., 4., 5., 1., 9., 2., 4., 3., 0., 3., 0., 3., 10., 0., 0., 2., 3., 3., 3., 5., 2., 0., 0., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., [...]
+
+8., 1., 1., 2., 14., 6., 10., 1., 6., 18., 1., 11., 24., 3., 12., 1., 2., 2., 8., 1., 6., 37., 13., 24., 28., 3., 0., 2., 7., 3., 11., 8., 40., 20., 2., 18., 4., 7., 7., 6., 1., 5., 3., 16., 9., 17., 48., 10., 20., 9., 6., 2., 3., 2., 7., 1., 10., 3., 11., 19., 11., 24., 7., 5., 2., 2., 4., 2., 4., 0., 7., 3., 10., 4., 2., 4., 2., 1., 1., 0., 2., 0., 1., 0., 2., 5., 2., 9., 0., 2., 4., 2., 2., 0., 0., 10., 3., 0., 0., 3., 2., 2., 2., 2., 2., 1., 1., 0., 0., 0., 0., 4., 0., 0., 4., 0., 0. [...]
+
+13., 1., 5., 6., 22., 10., 36., 0., 19., 170., 3., 30., 224., 5., 12., 3., 1., 4., 67., 0., 20., 242., 47., 349., 52., 22., 1., 2., 7., 1., 35., 40., 244., 34., 5., 175., 15., 51., 8., 0., 5., 16., 8., 83., 17., 93., 11., 42., 43., 11., 1., 0., 20., 11., 22., 6., 47., 12., 25., 5., 5., 8., 2., 0., 3., 0., 20., 6., 12., 3., 28., 3., 11., 1., 2., 0., 0., 1., 2., 3., 9., 2., 6., 2., 8., 2., 0., 3., 132., 10., 1868., 89., 100., 218., 108., 104., 57., 11., 10., 15., 18., 2., 0., 7., 3., 4., 7 [...]
+
+11., 2., 4., 8., 39., 8., 36., 0., 14., 165., 3., 22., 198., 4., 14., 6., 0., 4., 89., 2., 22., 251., 50., 310., 49., 17., 2., 1., 6., 5., 45., 27., 219., 37., 6., 141., 12., 43., 5., 0., 1., 20., 5., 77., 19., 98., 23., 31., 40., 11., 2., 1., 23., 6., 57., 14., 45., 6., 26., 7., 4., 6., 4., 0., 1., 0., 31., 6., 15., 1., 28., 6., 9., 1., 3., 2., 1., 0., 3., 1., 9., 4., 13., 0., 8., 1., 0., 4., 122., 12., 1899., 90., 89., 224., 78., 125., 66., 24., 14., 23., 14., 1., 1., 7., 2., 4., 8., 9 [...]
+
+8., 4., 1., 12., 20., 10., 36., 2., 18., 159., 2., 33., 226., 2., 17., 3., 2., 2., 93., 2., 19., 265., 40., 312., 43., 20., 5., 2., 6., 3., 44., 22., 245., 53., 6., 167., 12., 38., 6., 0., 4., 16., 6., 76., 21., 81., 17., 39., 56., 9., 7., 3., 23., 6., 40., 7., 48., 11., 37., 5., 12., 6., 2., 0., 0., 0., 20., 2., 15., 1., 23., 3., 19., 3., 2., 2., 1., 3., 0., 2., 17., 2., 10., 2., 8., 1., 1., 1., 131., 12., 1856., 96., 110., 207., 95., 144., 69., 12., 15., 16., 12., 0., 3., 4., 5., 4., 9 [...]
+
+15., 6., 0., 7., 36., 4., 31., 1., 12., 167., 3., 22., 226., 1., 16., 7., 2., 3., 74., 6., 17., 307., 41., 303., 50., 21., 0., 3., 7., 9., 30., 15., 225., 34., 7., 167., 16., 31., 3., 0., 0., 19., 6., 75., 16., 86., 17., 29., 36., 16., 3., 0., 31., 6., 43., 11., 43., 12., 30., 9., 10., 7., 0., 0., 2., 0., 20., 9., 15., 6., 31., 2., 9., 3., 1., 1., 1., 4., 1., 0., 13., 4., 8., 4., 7., 0., 2., 5., 132., 7., 1966., 68., 110., 221., 95., 109., 67., 21., 18., 24., 11., 0., 0., 8., 3., 4., 7., [...]
+
+5., 1., 6., 8., 23., 6., 27., 1., 16., 158., 2., 27., 210., 5., 11., 9., 2., 9., 86., 3., 22., 282., 54., 349., 39., 19., 1., 1., 5., 4., 48., 27., 224., 42., 5., 158., 17., 50., 8., 0., 3., 11., 8., 88., 22., 94., 11., 38., 55., 9., 1., 2., 28., 8., 39., 7., 50., 13., 42., 4., 8., 6., 1., 0., 0., 0., 28., 8., 13., 3., 27., 3., 3., 6., 1., 0., 1., 0., 1., 4., 8., 3., 6., 3., 7., 1., 1., 3., 156., 5., 1878., 105., 114., 229., 86., 122., 82., 16., 13., 19., 14., 1., 4., 6., 5., 5., 8., 11. [...]
+
+15., 1., 4., 9., 15., 5., 31., 2., 20., 147., 4., 19., 196., 2., 19., 6., 0., 8., 95., 1., 12., 269., 34., 335., 41., 28., 1., 2., 6., 2., 37., 30., 196., 46., 11., 144., 18., 32., 6., 0., 2., 21., 9., 91., 24., 82., 15., 34., 36., 9., 3., 2., 35., 4., 34., 8., 39., 11., 27., 2., 9., 9., 1., 0., 0., 0., 27., 6., 21., 5., 34., 3., 10., 9., 1., 3., 1., 1., 6., 4., 5., 3., 10., 2., 7., 2., 0., 5., 165., 2., 1904., 83., 78., 222., 112., 110., 71., 16., 15., 11., 12., 0., 1., 3., 7., 1., 5.,  [...]
+
+11., 0., 1., 11., 18., 8., 28., 3., 24., 143., 2., 28., 201., 6., 17., 10., 0., 5., 84., 3., 18., 274., 42., 311., 33., 16., 1., 4., 10., 8., 43., 23., 219., 41., 5., 171., 16., 39., 11., 0., 5., 13., 10., 78., 24., 98., 22., 38., 45., 17., 3., 2., 25., 9., 30., 7., 54., 5., 32., 7., 5., 6., 2., 0., 1., 0., 19., 8., 16., 1., 35., 6., 11., 5., 1., 4., 2., 1., 5., 1., 12., 3., 11., 2., 5., 1., 0., 2., 145., 10., 1849., 81., 112., 215., 90., 116., 74., 9., 12., 18., 16., 1., 2., 3., 8., 3., [...]
+
+16., 2., 1., 10., 22., 7., 36., 1., 12., 160., 3., 24., 202., 2., 14., 14., 1., 6., 77., 2., 11., 276., 55., 340., 51., 17., 0., 2., 6., 1., 40., 28., 227., 50., 13., 132., 14., 36., 7., 0., 2., 13., 1., 77., 16., 80., 16., 41., 34., 11., 5., 1., 28., 9., 36., 10., 56., 6., 20., 9., 10., 7., 1., 0., 2., 0., 22., 4., 16., 7., 31., 5., 5., 5., 2., 0., 2., 0., 4., 2., 8., 1., 11., 4., 4., 0., 0., 2., 157., 11., 1887., 79., 101., 215., 89., 102., 63., 19., 9., 12., 12., 0., 5., 2., 6., 3., 8 [...]
+
+13., 3., 1., 2., 23., 3., 35., 0., 18., 153., 3., 31., 207., 4., 14., 11., 0., 4., 80., 4., 11., 274., 59., 366., 38., 18., 0., 1., 7., 7., 48., 28., 221., 37., 6., 180., 13., 26., 2., 0., 2., 17., 8., 86., 26., 75., 13., 40., 49., 16., 1., 2., 23., 11., 37., 11., 39., 7., 32., 8., 13., 5., 1., 0., 0., 0., 21., 2., 25., 1., 25., 4., 14., 4., 1., 7., 1., 1., 3., 1., 11., 4., 12., 3., 8., 0., 3., 5., 146., 6., 1846., 84., 100., 236., 99., 105., 82., 14., 7., 19., 11., 0., 2., 6., 5., 2., 1 [...]
+
+12., 3., 3., 10., 32., 5., 33., 0., 13., 142., 1., 34., 217., 4., 18., 8., 1., 5., 78., 1., 14., 305., 42., 315., 39., 18., 0., 2., 5., 1., 54., 26., 225., 36., 13., 167., 17., 37., 5., 0., 2., 11., 3., 76., 23., 97., 11., 42., 29., 16., 2., 0., 35., 13., 36., 10., 56., 6., 39., 6., 9., 7., 1., 0., 1., 0., 18., 3., 23., 5., 20., 6., 7., 4., 4., 2., 1., 0., 6., 5., 9., 4., 12., 2., 7., 1., 3., 4., 163., 8., 1906., 111., 112., 234., 101., 120., 68., 17., 14., 15., 20., 0., 0., 11., 7., 2., [...]
+
+9., 3., 3., 4., 36., 3., 30., 1., 15., 136., 1., 23., 211., 3., 16., 9., 0., 6., 86., 2., 15., 294., 33., 345., 44., 13., 1., 4., 5., 5., 45., 25., 220., 42., 6., 150., 13., 30., 4., 0., 2., 17., 9., 89., 10., 95., 21., 42., 46., 15., 1., 2., 25., 4., 46., 7., 43., 9., 33., 7., 14., 14., 2., 0., 0., 0., 25., 7., 24., 2., 27., 4., 18., 5., 1., 2., 0., 3., 3., 2., 9., 1., 8., 0., 9., 2., 0., 4., 148., 8., 1932., 107., 102., 229., 108., 117., 62., 10., 4., 13., 13., 0., 1., 3., 5., 3., 9.,  [...]
+
+13., 1., 2., 7., 25., 2., 29., 0., 20., 152., 3., 23., 218., 6., 14., 9., 1., 5., 91., 2., 16., 310., 49., 301., 51., 16., 1., 1., 6., 5., 52., 31., 243., 44., 10., 149., 10., 39., 12., 0., 1., 13., 8., 64., 22., 82., 19., 41., 46., 16., 2., 1., 39., 4., 37., 8., 40., 11., 42., 6., 5., 4., 2., 0., 3., 0., 24., 5., 17., 3., 35., 6., 11., 8., 1., 4., 0., 1., 2., 2., 16., 0., 10., 2., 7., 2., 2., 3., 147., 11., 1897., 86., 100., 226., 88., 108., 66., 16., 12., 27., 17., 1., 2., 4., 7., 4.,  [...]
+
+15., 1., 1., 9., 24., 5., 40., 1., 14., 154., 1., 23., 194., 9., 20., 11., 0., 8., 66., 3., 14., 257., 50., 296., 36., 22., 0., 1., 4., 12., 47., 37., 249., 51., 10., 158., 8., 46., 3., 0., 1., 12., 8., 75., 12., 82., 10., 38., 43., 14., 3., 0., 25., 5., 35., 9., 45., 7., 30., 4., 8., 4., 3., 0., 0., 0., 28., 6., 11., 2., 29., 4., 13., 1., 4., 0., 1., 3., 5., 2., 15., 2., 5., 3., 7., 3., 2., 3., 119., 12., 1859., 79., 95., 225., 82., 114., 61., 18., 12., 14., 10., 0., 2., 4., 4., 3., 9., [...]
+
+5., 2., 4., 9., 22., 6., 36., 0., 8., 159., 2., 38., 222., 8., 15., 5., 3., 2., 77., 2., 24., 278., 43., 339., 40., 12., 0., 0., 10., 3., 40., 34., 211., 48., 11., 143., 12., 38., 5., 0., 0., 17., 13., 81., 17., 74., 21., 41., 49., 16., 4., 1., 26., 10., 34., 7., 51., 6., 32., 6., 7., 8., 6., 0., 1., 0., 17., 6., 10., 2., 38., 5., 18., 6., 3., 3., 1., 3., 1., 2., 8., 2., 7., 2., 10., 0., 2., 5., 140., 8., 1829., 94., 98., 231., 87., 110., 65., 13., 11., 21., 12., 1., 4., 6., 4., 3., 9.,  [...]
+
+15., 4., 2., 8., 21., 5., 30., 0., 22., 175., 3., 26., 218., 6., 18., 9., 1., 10., 84., 2., 20., 319., 40., 319., 34., 13., 0., 3., 6., 5., 47., 26., 222., 29., 7., 155., 17., 39., 3., 0., 3., 30., 6., 83., 20., 66., 17., 31., 47., 12., 2., 1., 16., 2., 32., 13., 53., 12., 31., 3., 9., 7., 1., 0., 1., 0., 23., 4., 15., 5., 25., 5., 10., 4., 0., 1., 0., 0., 4., 2., 19., 6., 9., 5., 7., 2., 2., 3., 153., 12., 1836., 101., 115., 216., 105., 129., 67., 21., 11., 21., 8., 1., 1., 8., 3., 4.,  [...]
+
+5., 1., 1., 0., 4., 4., 6., 2., 6., 19., 1., 20., 20., 0., 15., 3., 0., 1., 15., 4., 1., 26., 11., 21., 31., 2., 4., 2., 3., 3., 8., 4., 22., 14., 7., 17., 3., 9., 8., 2., 0., 2., 0., 11., 10., 27., 39., 15., 24., 9., 3., 3., 7., 6., 6., 1., 8., 11., 10., 14., 10., 22., 10., 2., 0., 0., 4., 1., 4., 2., 5., 5., 3., 4., 2., 8., 1., 2., 1., 4., 3., 0., 1., 5., 1., 5., 5., 1., 4., 2., 3., 0., 3., 1., 3., 4., 2., 0., 3., 1., 2., 3., 6., 3., 2., 0., 4., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0.,  [...]
+
+11., 1., 1., 7., 8., 4., 9., 2., 10., 21., 1., 9., 18., 1., 16., 0., 2., 1., 13., 3., 3., 23., 7., 14., 33., 4., 2., 0., 2., 2., 9., 5., 26., 19., 1., 13., 6., 15., 12., 3., 0., 4., 1., 18., 9., 12., 50., 12., 18., 10., 4., 0., 3., 1., 8., 5., 9., 10., 5., 22., 6., 18., 9., 4., 2., 1., 13., 3., 3., 1., 8., 5., 7., 6., 0., 3., 3., 3., 2., 5., 0., 0., 2., 4., 1., 5., 4., 5., 1., 2., 2., 1., 1., 0., 2., 5., 1., 0., 1., 3., 5., 2., 2., 4., 2., 0., 2., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0.,  [...]
+
+10., 1., 1., 4., 3., 1., 11., 0., 10., 24., 0., 17., 26., 1., 21., 3., 0., 4., 28., 3., 7., 36., 9., 29., 35., 4., 2., 1., 2., 1., 7., 6., 27., 13., 4., 20., 3., 13., 4., 2., 2., 3., 0., 12., 13., 14., 47., 16., 18., 7., 2., 1., 2., 1., 6., 4., 10., 6., 12., 15., 5., 33., 8., 2., 0., 1., 6., 0., 1., 3., 6., 3., 4., 4., 2., 4., 1., 3., 0., 2., 2., 0., 2., 2., 3., 10., 4., 3., 3., 2., 2., 1., 4., 0., 2., 9., 2., 0., 4., 1., 3., 2., 1., 2., 0., 1., 1., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0. [...]
+
+5., 0., 5., 6., 3., 5., 9., 0., 3., 14., 1., 10., 23., 0., 16., 3., 2., 2., 24., 0., 5., 9., 17., 12., 28., 8., 1., 4., 4., 4., 10., 5., 27., 12., 5., 14., 6., 15., 7., 1., 1., 2., 1., 13., 10., 25., 60., 15., 16., 6., 2., 1., 6., 1., 13., 5., 9., 5., 5., 13., 10., 21., 6., 3., 1., 1., 6., 0., 2., 1., 5., 2., 2., 4., 1., 1., 3., 2., 0., 3., 0., 0., 3., 2., 1., 5., 0., 6., 1., 2., 4., 0., 0., 1., 2., 5., 2., 0., 5., 2., 2., 4., 2., 1., 3., 0., 4., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0 [...]
+
+8., 2., 0., 3., 10., 1., 2., 1., 6., 15., 0., 11., 24., 1., 13., 2., 0., 4., 8., 1., 7., 23., 12., 24., 24., 6., 0., 2., 1., 2., 5., 7., 25., 13., 4., 16., 5., 13., 12., 0., 3., 6., 2., 13., 7., 15., 46., 13., 22., 9., 5., 1., 6., 2., 3., 2., 15., 7., 10., 5., 3., 21., 9., 4., 0., 1., 3., 2., 4., 2., 2., 2., 1., 1., 0., 4., 2., 2., 2., 0., 0., 0., 2., 4., 0., 5., 4., 3., 1., 3., 5., 0., 3., 1., 3., 5., 1., 0., 2., 3., 1., 1., 5., 6., 5., 0., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0. [...]
+
+10., 1., 0., 2., 8., 4., 5., 0., 9., 10., 1., 11., 28., 4., 11., 2., 1., 3., 14., 2., 3., 26., 9., 40., 28., 4., 0., 2., 0., 2., 5., 4., 25., 15., 5., 26., 8., 11., 4., 2., 3., 6., 3., 10., 10., 19., 40., 10., 22., 17., 5., 0., 7., 3., 5., 0., 10., 8., 8., 16., 7., 29., 6., 4., 2., 1., 12., 1., 4., 4., 8., 3., 4., 2., 1., 6., 2., 2., 1., 3., 1., 0., 3., 1., 0., 5., 3., 6., 2., 4., 2., 0., 3., 0., 1., 6., 0., 0., 1., 1., 3., 4., 0., 2., 2., 1., 1., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0.,  [...]
+
+7., 0., 2., 9., 9., 1., 3., 1., 5., 37., 2., 14., 20., 0., 12., 3., 0., 0., 12., 1., 2., 19., 10., 16., 25., 6., 1., 2., 4., 3., 7., 3., 28., 12., 4., 15., 5., 12., 11., 1., 2., 5., 2., 13., 16., 15., 40., 14., 19., 15., 6., 2., 6., 2., 3., 3., 7., 5., 9., 18., 12., 28., 8., 2., 1., 1., 8., 0., 5., 3., 8., 6., 4., 7., 2., 5., 4., 3., 3., 1., 1., 0., 2., 0., 1., 8., 4., 2., 2., 2., 3., 2., 1., 1., 2., 7., 0., 0., 2., 1., 2., 0., 1., 1., 2., 0., 3., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0.,  [...]
+
+1., 2., 4., 4., 7., 3., 10., 0., 6., 13., 1., 15., 15., 0., 15., 3., 2., 2., 12., 0., 3., 10., 15., 51., 21., 3., 0., 1., 2., 4., 8., 7., 21., 19., 5., 15., 3., 12., 8., 4., 3., 7., 2., 9., 10., 18., 45., 9., 22., 6., 7., 0., 6., 3., 5., 1., 11., 5., 14., 20., 3., 19., 4., 0., 3., 2., 7., 1., 4., 0., 5., 4., 7., 4., 1., 5., 4., 1., 0., 1., 1., 0., 2., 2., 1., 5., 0., 6., 1., 1., 4., 1., 1., 0., 3., 6., 1., 0., 3., 2., 3., 0., 2., 1., 2., 2., 0., 0., 0., 0., 0., 6., 0., 0., 4., 0., 0., 0. [...]
+
+8., 0., 2., 1., 8., 1., 6., 3., 4., 28., 4., 14., 22., 0., 16., 1., 1., 3., 13., 3., 4., 25., 8., 28., 24., 6., 0., 1., 4., 1., 7., 13., 32., 18., 4., 23., 6., 16., 12., 4., 3., 6., 1., 9., 11., 10., 44., 14., 31., 9., 1., 2., 5., 1., 7., 4., 8., 8., 4., 13., 9., 24., 3., 3., 1., 0., 4., 3., 4., 0., 6., 2., 1., 5., 3., 8., 4., 0., 0., 1., 2., 0., 4., 3., 2., 6., 2., 7., 3., 0., 3., 2., 3., 2., 2., 10., 2., 0., 4., 0., 1., 3., 2., 2., 3., 1., 4., 0., 0., 0., 0., 4., 0., 0., 4., 0., 0., 0. [...]
+
+4., 1., 2., 2., 8., 5., 5., 0., 9., 17., 3., 17., 32., 1., 16., 4., 0., 2., 16., 1., 4., 29., 13., 30., 29., 2., 0., 0., 5., 1., 5., 4., 18., 20., 3., 21., 1., 15., 10., 0., 1., 6., 5., 9., 15., 17., 51., 12., 20., 10., 4., 1., 4., 1., 5., 4., 15., 7., 11., 14., 5., 18., 5., 2., 1., 1., 10., 1., 2., 3., 7., 3., 2., 4., 3., 4., 4., 5., 1., 1., 3., 0., 3., 0., 1., 6., 2., 4., 1., 1., 4., 1., 2., 1., 2., 4., 5., 0., 2., 2., 2., 0., 2., 2., 3., 1., 3., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., [...]
+
+7., 0., 2., 3., 8., 1., 8., 0., 5., 22., 1., 13., 21., 0., 14., 6., 1., 3., 22., 1., 4., 23., 15., 30., 29., 5., 1., 3., 2., 4., 11., 7., 10., 28., 6., 19., 5., 8., 11., 1., 0., 4., 5., 14., 14., 9., 37., 11., 25., 7., 1., 2., 10., 3., 6., 2., 13., 4., 9., 14., 7., 22., 12., 3., 1., 1., 4., 0., 2., 4., 8., 6., 5., 2., 2., 1., 2., 2., 1., 2., 1., 0., 4., 3., 4., 4., 1., 2., 1., 1., 5., 3., 2., 1., 2., 5., 4., 0., 3., 4., 0., 1., 2., 5., 3., 0., 2., 0., 0., 0., 0., 5., 0., 0., 0., 0., 0.,  [...]
+
+7., 2., 4., 2., 11., 2., 6., 0., 6., 13., 0., 18., 13., 1., 15., 5., 2., 4., 20., 0., 3., 18., 9., 16., 30., 9., 0., 0., 1., 3., 10., 10., 27., 11., 3., 22., 2., 15., 11., 1., 0., 5., 3., 12., 12., 11., 34., 12., 18., 14., 4., 1., 11., 2., 9., 1., 11., 3., 6., 10., 11., 14., 14., 3., 0., 0., 6., 1., 4., 5., 6., 3., 7., 1., 3., 5., 2., 1., 0., 5., 1., 0., 5., 2., 2., 2., 1., 5., 1., 4., 5., 0., 0., 1., 1., 6., 4., 0., 0., 0., 1., 0., 5., 1., 3., 0., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., [...]
+
+5., 1., 0., 1., 9., 2., 7., 0., 5., 26., 2., 10., 23., 2., 16., 0., 0., 3., 18., 0., 4., 27., 10., 39., 25., 7., 0., 2., 2., 3., 6., 4., 19., 16., 2., 13., 4., 10., 10., 2., 1., 1., 0., 19., 5., 25., 49., 6., 15., 19., 7., 0., 1., 0., 9., 5., 7., 11., 5., 19., 6., 23., 5., 3., 0., 3., 3., 0., 2., 1., 8., 6., 3., 1., 2., 3., 4., 1., 0., 2., 1., 0., 3., 0., 2., 6., 0., 4., 2., 6., 5., 2., 3., 0., 3., 7., 0., 0., 4., 0., 4., 1., 4., 4., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0. [...]
+
+11., 1., 0., 5., 11., 3., 7., 2., 7., 18., 2., 16., 24., 2., 16., 4., 1., 4., 31., 4., 2., 35., 17., 33., 30., 5., 0., 0., 1., 0., 3., 1., 20., 7., 2., 20., 3., 13., 7., 1., 0., 3., 0., 15., 15., 21., 40., 20., 27., 7., 4., 4., 9., 3., 5., 4., 16., 4., 6., 13., 6., 21., 7., 2., 2., 0., 8., 2., 3., 0., 8., 2., 6., 0., 4., 4., 6., 1., 2., 2., 3., 0., 1., 3., 4., 5., 1., 1., 2., 3., 5., 0., 1., 0., 2., 9., 2., 0., 1., 1., 2., 1., 2., 2., 4., 1., 3., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0., 0 [...]
+
+7., 1., 5., 1., 5., 3., 7., 1., 8., 36., 1., 12., 22., 1., 4., 4., 3., 3., 19., 1., 3., 21., 11., 22., 25., 6., 1., 0., 3., 0., 5., 8., 24., 10., 5., 15., 2., 16., 11., 2., 0., 2., 1., 12., 13., 20., 51., 9., 27., 7., 1., 1., 9., 6., 3., 2., 9., 6., 9., 20., 4., 23., 6., 4., 1., 0., 9., 3., 3., 4., 8., 4., 4., 4., 2., 6., 1., 2., 1., 1., 2., 0., 2., 1., 1., 8., 2., 5., 4., 1., 3., 0., 1., 1., 2., 4., 1., 0., 1., 4., 3., 6., 1., 0., 8., 2., 0., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0.,  [...]
+
+5., 3., 2., 6., 5., 5., 2., 0., 6., 13., 0., 18., 23., 0., 22., 1., 0., 4., 26., 1., 3., 24., 10., 18., 28., 4., 0., 1., 7., 3., 8., 12., 26., 17., 2., 17., 7., 21., 9., 1., 4., 3., 3., 12., 13., 15., 54., 12., 25., 8., 7., 1., 3., 2., 12., 3., 7., 5., 9., 13., 5., 25., 6., 1., 0., 1., 10., 2., 6., 2., 9., 2., 2., 4., 0., 4., 5., 1., 0., 2., 3., 0., 3., 4., 2., 8., 3., 4., 4., 4., 5., 2., 2., 3., 2., 8., 3., 0., 1., 2., 0., 4., 0., 2., 3., 0., 1., 0., 0., 0., 0., 2., 0., 0., 5., 0., 0.,  [...]
+
+8., 0., 2., 3., 9., 5., 5., 0., 7., 19., 1., 17., 14., 0., 16., 3., 2., 3., 26., 2., 3., 31., 12., 35., 19., 4., 0., 0., 2., 1., 11., 6., 20., 18., 1., 8., 7., 19., 8., 2., 1., 3., 2., 19., 21., 15., 44., 13., 24., 13., 2., 2., 3., 4., 7., 0., 13., 3., 7., 15., 4., 14., 4., 2., 2., 1., 5., 1., 4., 2., 8., 0., 5., 5., 1., 7., 4., 4., 4., 2., 4., 0., 2., 5., 2., 9., 4., 3., 3., 4., 5., 0., 0., 1., 4., 5., 1., 0., 3., 1., 1., 5., 4., 1., 2., 0., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0 [...]
+
+15., 5., 1., 11., 17., 4., 35., 0., 9., 151., 1., 23., 208., 5., 19., 9., 2., 7., 56., 1., 19., 297., 44., 367., 43., 17., 1., 2., 9., 3., 48., 36., 251., 33., 7., 144., 12., 48., 6., 0., 5., 15., 8., 56., 21., 91., 11., 23., 48., 17., 2., 2., 18., 7., 41., 14., 51., 8., 22., 4., 14., 7., 3., 0., 1., 0., 28., 5., 9., 4., 27., 3., 14., 2., 4., 7., 0., 1., 4., 0., 13., 4., 10., 0., 16., 1., 3., 6., 155., 8., 1789., 87., 104., 226., 96., 105., 72., 13., 16., 17., 12., 1., 1., 7., 4., 4., 13 [...]
+
+17., 3., 3., 11., 17., 6., 28., 2., 13., 169., 3., 24., 197., 4., 15., 8., 0., 4., 88., 3., 16., 298., 41., 317., 32., 16., 0., 2., 5., 8., 50., 32., 252., 37., 10., 164., 14., 34., 4., 0., 1., 14., 5., 78., 29., 70., 6., 27., 48., 12., 2., 1., 29., 7., 39., 8., 49., 11., 26., 9., 6., 10., 2., 0., 2., 0., 24., 11., 14., 4., 28., 8., 9., 3., 1., 2., 0., 0., 1., 2., 9., 2., 8., 3., 6., 1., 0., 4., 141., 14., 1815., 97., 123., 209., 115., 119., 69., 19., 21., 29., 13., 2., 2., 5., 8., 2., 1 [...]
+
+14., 1., 2., 5., 18., 9., 28., 1., 16., 177., 4., 24., 235., 5., 16., 6., 0., 3., 75., 1., 18., 292., 33., 305., 39., 11., 0., 1., 4., 6., 49., 21., 244., 30., 8., 161., 10., 33., 4., 0., 1., 14., 9., 54., 29., 81., 18., 29., 39., 13., 4., 1., 36., 5., 47., 10., 48., 7., 30., 10., 11., 10., 4., 0., 0., 0., 31., 4., 8., 4., 40., 8., 7., 4., 3., 0., 2., 1., 2., 0., 10., 3., 7., 3., 7., 1., 0., 3., 162., 9., 1823., 86., 97., 210., 91., 104., 80., 16., 8., 23., 16., 0., 0., 5., 3., 7., 11.,  [...]
+
+15., 4., 3., 9., 29., 4., 29., 2., 12., 148., 3., 21., 208., 6., 25., 9., 1., 6., 74., 0., 13., 306., 47., 320., 37., 11., 0., 2., 5., 8., 36., 32., 225., 42., 9., 174., 15., 36., 3., 0., 2., 16., 7., 77., 22., 83., 18., 31., 52., 13., 0., 0., 29., 9., 44., 13., 40., 6., 31., 4., 10., 6., 3., 0., 0., 0., 22., 5., 17., 5., 29., 2., 11., 7., 1., 1., 2., 1., 2., 1., 8., 2., 7., 3., 12., 2., 2., 5., 137., 10., 1895., 85., 125., 220., 112., 111., 75., 13., 17., 18., 16., 0., 2., 8., 6., 4., 7 [...]
+
+13., 4., 0., 12., 28., 4., 24., 0., 10., 167., 2., 24., 211., 5., 19., 9., 1., 4., 82., 2., 10., 265., 31., 316., 48., 11., 0., 5., 4., 5., 48., 33., 228., 45., 7., 163., 13., 51., 6., 0., 3., 22., 9., 84., 15., 78., 16., 34., 43., 13., 3., 1., 20., 4., 46., 8., 59., 7., 26., 1., 14., 8., 1., 0., 1., 0., 23., 4., 18., 2., 42., 1., 10., 2., 1., 4., 0., 1., 0., 2., 11., 3., 6., 4., 11., 2., 0., 5., 141., 7., 1863., 87., 111., 208., 114., 117., 70., 17., 14., 25., 20., 1., 0., 5., 9., 5., 1 [...]
+
+7., 1., 1., 6., 28., 5., 37., 0., 15., 155., 5., 37., 199., 3., 17., 3., 1., 5., 87., 0., 19., 302., 37., 327., 44., 22., 1., 1., 9., 2., 49., 39., 230., 40., 12., 177., 13., 34., 4., 0., 0., 21., 11., 83., 21., 87., 13., 30., 57., 14., 2., 0., 25., 15., 42., 7., 55., 11., 31., 4., 6., 7., 2., 0., 3., 0., 18., 1., 10., 7., 33., 1., 8., 4., 1., 1., 1., 0., 5., 2., 8., 2., 6., 4., 8., 2., 0., 8., 155., 3., 1834., 90., 104., 235., 123., 126., 66., 16., 10., 10., 10., 2., 0., 9., 4., 4., 7., [...]
+
+16., 1., 3., 9., 18., 8., 28., 1., 14., 135., 2., 26., 223., 4., 9., 4., 1., 8., 86., 1., 11., 297., 48., 332., 35., 20., 1., 0., 10., 7., 45., 45., 226., 39., 12., 141., 15., 34., 5., 0., 0., 13., 8., 90., 21., 90., 9., 29., 47., 9., 3., 0., 32., 9., 49., 12., 47., 7., 39., 9., 11., 7., 2., 0., 1., 0., 23., 2., 20., 3., 24., 9., 9., 7., 3., 3., 3., 0., 2., 2., 11., 5., 4., 3., 9., 0., 0., 1., 153., 11., 1870., 111., 93., 237., 95., 99., 63., 26., 17., 20., 10., 0., 0., 3., 5., 4., 2., 9 [...]
+
+17., 0., 2., 15., 23., 9., 30., 0., 20., 150., 1., 33., 202., 9., 14., 9., 2., 7., 90., 3., 18., 297., 48., 335., 57., 22., 2., 0., 6., 4., 44., 36., 226., 37., 4., 144., 15., 46., 4., 0., 1., 16., 6., 97., 17., 94., 21., 34., 40., 11., 2., 0., 19., 4., 41., 8., 55., 8., 26., 6., 12., 10., 0., 0., 0., 0., 15., 10., 21., 4., 25., 10., 8., 2., 2., 5., 0., 0., 3., 0., 16., 0., 6., 2., 9., 0., 1., 5., 125., 9., 1903., 86., 98., 234., 100., 110., 63., 18., 14., 14., 16., 0., 1., 1., 6., 4., 4 [...]
+
+10., 1., 4., 6., 29., 5., 29., 0., 16., 177., 4., 27., 193., 5., 15., 14., 0., 6., 61., 2., 15., 253., 48., 321., 36., 18., 0., 4., 13., 4., 47., 29., 228., 31., 7., 180., 21., 48., 8., 0., 4., 21., 4., 67., 21., 66., 13., 32., 62., 13., 3., 1., 15., 9., 39., 12., 46., 5., 39., 2., 8., 4., 2., 0., 3., 0., 18., 3., 9., 4., 31., 5., 3., 6., 3., 4., 3., 0., 2., 2., 9., 3., 3., 2., 9., 0., 0., 2., 126., 11., 1885., 82., 91., 223., 114., 115., 78., 13., 15., 21., 12., 0., 4., 5., 4., 3., 3.,  [...]
+
+18., 0., 4., 10., 31., 10., 28., 0., 17., 145., 0., 28., 198., 4., 11., 7., 0., 1., 79., 1., 15., 262., 32., 336., 38., 11., 2., 0., 7., 4., 43., 38., 231., 47., 14., 178., 13., 32., 5., 0., 5., 26., 7., 66., 29., 84., 15., 34., 38., 13., 4., 1., 20., 6., 29., 10., 63., 11., 17., 6., 13., 8., 1., 0., 0., 0., 22., 5., 10., 3., 33., 4., 16., 4., 2., 3., 6., 1., 4., 1., 11., 1., 5., 5., 2., 2., 1., 7., 162., 9., 1943., 97., 102., 200., 91., 110., 66., 20., 22., 20., 9., 0., 1., 6., 8., 5.,  [...]
+
+16., 4., 4., 10., 28., 2., 32., 1., 14., 153., 1., 31., 215., 14., 20., 4., 1., 8., 86., 5., 15., 269., 45., 330., 47., 14., 0., 1., 5., 7., 49., 40., 223., 44., 9., 173., 13., 47., 5., 0., 0., 16., 7., 82., 17., 94., 21., 34., 41., 13., 3., 1., 16., 7., 41., 9., 45., 7., 47., 8., 14., 7., 3., 0., 2., 0., 20., 5., 10., 2., 23., 5., 13., 4., 3., 2., 1., 1., 3., 2., 11., 0., 4., 4., 8., 0., 0., 2., 138., 1., 1868., 94., 87., 246., 82., 103., 74., 10., 17., 24., 14., 0., 1., 9., 2., 4., 9., [...]
+
+15., 3., 1., 3., 29., 6., 27., 1., 15., 148., 1., 31., 219., 4., 16., 7., 0., 4., 73., 2., 12., 251., 50., 351., 37., 20., 1., 1., 7., 8., 49., 39., 233., 31., 10., 166., 13., 45., 7., 0., 1., 16., 4., 79., 16., 84., 15., 22., 43., 11., 4., 1., 24., 5., 37., 19., 49., 11., 35., 7., 12., 5., 6., 0., 2., 0., 26., 9., 17., 3., 37., 4., 16., 5., 1., 5., 1., 0., 4., 3., 18., 4., 10., 0., 11., 0., 0., 2., 148., 3., 1827., 107., 97., 222., 75., 118., 54., 19., 10., 18., 11., 0., 2., 7., 1., 3., [...]
+
+15., 3., 1., 18., 22., 10., 22., 1., 16., 161., 5., 19., 211., 7., 15., 5., 0., 6., 67., 2., 16., 318., 38., 340., 46., 18., 0., 3., 8., 5., 50., 34., 261., 44., 5., 154., 17., 37., 5., 0., 0., 13., 5., 91., 18., 78., 12., 34., 46., 18., 2., 1., 28., 13., 39., 10., 48., 6., 38., 6., 12., 5., 1., 0., 0., 0., 23., 5., 19., 1., 26., 5., 9., 8., 1., 2., 1., 1., 1., 5., 9., 3., 7., 3., 7., 2., 1., 4., 150., 7., 1921., 84., 110., 198., 104., 111., 59., 17., 14., 14., 14., 1., 0., 6., 1., 2., 1 [...]
+
+16., 0., 2., 6., 27., 3., 36., 0., 23., 180., 6., 27., 235., 5., 12., 14., 0., 7., 93., 3., 19., 303., 50., 316., 41., 19., 1., 3., 7., 2., 42., 33., 238., 47., 11., 168., 15., 42., 8., 0., 1., 23., 2., 74., 23., 82., 14., 32., 51., 9., 3., 2., 20., 6., 46., 10., 47., 7., 24., 3., 12., 5., 2., 0., 2., 0., 25., 1., 13., 1., 26., 8., 6., 8., 2., 6., 0., 1., 3., 0., 13., 3., 11., 2., 9., 4., 0., 4., 133., 11., 1865., 106., 99., 218., 85., 111., 70., 16., 7., 17., 17., 1., 4., 7., 3., 8., 9. [...]
+
+17., 2., 1., 5., 11., 3., 5., 0., 8., 24., 2., 14., 29., 0., 27., 3., 0., 3., 11., 2., 4., 25., 11., 13., 26., 6., 1., 0., 3., 1., 6., 10., 33., 13., 4., 9., 6., 7., 8., 2., 0., 3., 2., 16., 5., 19., 58., 15., 22., 8., 5., 1., 0., 2., 6., 2., 8., 6., 6., 15., 10., 22., 12., 1., 1., 0., 5., 2., 6., 1., 1., 2., 2., 3., 3., 2., 4., 3., 2., 2., 0., 0., 0., 2., 2., 5., 1., 7., 4., 2., 3., 2., 5., 2., 3., 10., 0., 0., 3., 2., 3., 4., 1., 1., 2., 1., 4., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0.,  [...]
+
+6., 1., 2., 9., 7., 1., 8., 0., 5., 19., 1., 10., 29., 0., 19., 2., 0., 1., 17., 1., 7., 30., 13., 25., 18., 9., 1., 1., 5., 1., 18., 9., 24., 9., 4., 19., 8., 11., 5., 2., 2., 2., 2., 14., 13., 15., 42., 12., 19., 8., 4., 0., 3., 3., 8., 3., 13., 7., 4., 26., 7., 22., 8., 6., 1., 1., 7., 1., 1., 2., 4., 4., 4., 3., 2., 1., 2., 1., 3., 0., 2., 0., 2., 1., 1., 6., 2., 5., 0., 0., 3., 2., 1., 3., 2., 12., 1., 0., 1., 2., 3., 3., 1., 0., 6., 0., 1., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0 [...]
+
+11., 0., 0., 4., 8., 4., 8., 1., 8., 28., 1., 10., 24., 0., 16., 5., 2., 2., 10., 3., 4., 23., 11., 32., 23., 5., 0., 1., 5., 1., 13., 7., 24., 11., 4., 11., 9., 14., 9., 0., 2., 3., 1., 13., 12., 16., 50., 6., 19., 8., 2., 0., 3., 1., 6., 3., 9., 5., 10., 15., 6., 17., 6., 2., 0., 0., 10., 0., 7., 0., 6., 1., 7., 3., 2., 3., 2., 0., 2., 1., 3., 0., 3., 6., 2., 8., 4., 9., 2., 1., 4., 1., 3., 4., 4., 8., 2., 0., 2., 1., 2., 3., 4., 0., 2., 0., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0.,  [...]
+
+8., 1., 1., 5., 6., 2., 1., 1., 8., 31., 0., 16., 21., 0., 16., 5., 0., 0., 21., 0., 1., 24., 12., 34., 23., 7., 1., 0., 3., 4., 13., 6., 33., 22., 2., 11., 3., 15., 11., 3., 1., 3., 2., 14., 9., 21., 39., 15., 28., 10., 5., 1., 7., 4., 7., 1., 10., 10., 12., 23., 7., 27., 9., 6., 0., 0., 5., 3., 4., 4., 2., 5., 4., 5., 2., 9., 3., 2., 1., 2., 3., 0., 1., 2., 4., 4., 5., 4., 0., 5., 5., 1., 3., 0., 4., 8., 1., 0., 0., 2., 0., 5., 0., 2., 2., 2., 1., 0., 0., 0., 0., 3., 0., 0., 0., 0., 0. [...]
+
+8., 1., 3., 3., 13., 2., 9., 2., 2., 33., 2., 8., 23., 1., 14., 7., 1., 2., 19., 1., 5., 36., 11., 23., 24., 1., 1., 2., 4., 4., 4., 14., 20., 19., 6., 24., 3., 18., 6., 0., 0., 6., 4., 16., 10., 13., 42., 8., 23., 11., 6., 2., 6., 3., 5., 6., 7., 7., 9., 16., 9., 22., 16., 3., 2., 0., 4., 0., 4., 6., 4., 8., 3., 6., 1., 1., 3., 5., 0., 3., 4., 0., 0., 2., 2., 6., 2., 5., 2., 3., 1., 1., 4., 0., 3., 2., 6., 0., 3., 1., 3., 1., 0., 3., 1., 1., 1., 0., 0., 0., 0., 4., 0., 0., 4., 0., 0., 0 [...]
+
+7., 0., 3., 2., 8., 3., 6., 0., 3., 22., 1., 10., 26., 1., 21., 2., 2., 4., 19., 6., 3., 18., 11., 34., 29., 8., 1., 2., 0., 2., 7., 5., 31., 17., 5., 19., 1., 17., 9., 1., 0., 5., 3., 16., 8., 17., 36., 8., 25., 7., 3., 2., 5., 2., 5., 3., 9., 5., 8., 14., 4., 29., 6., 4., 0., 3., 8., 0., 0., 0., 3., 1., 4., 4., 2., 4., 4., 1., 1., 2., 0., 0., 6., 4., 1., 4., 3., 4., 2., 3., 7., 0., 0., 1., 0., 4., 0., 0., 3., 1., 2., 4., 0., 1., 3., 1., 2., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 1 [...]
+
+2., 1., 2., 6., 10., 4., 10., 0., 5., 33., 1., 12., 22., 2., 13., 1., 1., 1., 18., 2., 7., 24., 13., 29., 28., 14., 0., 1., 5., 2., 7., 7., 30., 19., 1., 19., 4., 20., 6., 3., 2., 4., 2., 9., 16., 15., 48., 13., 15., 9., 6., 1., 11., 1., 4., 2., 13., 9., 9., 11., 5., 18., 11., 3., 2., 2., 9., 1., 0., 3., 6., 1., 0., 3., 4., 7., 3., 2., 2., 0., 1., 0., 4., 2., 2., 10., 4., 1., 2., 4., 1., 0., 3., 0., 3., 9., 2., 0., 4., 2., 2., 4., 3., 2., 2., 1., 5., 0., 0., 0., 0., 3., 0., 0., 4., 0., 0 [...]
+
+9., 1., 4., 7., 6., 5., 4., 3., 5., 21., 0., 9., 25., 3., 15., 4., 0., 0., 14., 1., 7., 31., 10., 24., 31., 6., 1., 1., 5., 4., 8., 6., 24., 14., 3., 9., 9., 18., 9., 5., 0., 5., 3., 17., 9., 12., 47., 15., 12., 8., 6., 0., 7., 4., 5., 4., 10., 6., 12., 10., 4., 18., 13., 5., 1., 1., 6., 3., 7., 3., 6., 5., 6., 4., 2., 7., 3., 1., 1., 1., 0., 0., 4., 2., 3., 4., 2., 2., 1., 1., 0., 1., 0., 1., 2., 4., 2., 0., 2., 2., 1., 3., 2., 3., 3., 0., 1., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., 0., [...]
+
+7., 1., 3., 1., 8., 1., 2., 2., 6., 36., 1., 18., 19., 1., 16., 0., 2., 1., 28., 2., 1., 24., 9., 18., 31., 3., 1., 1., 1., 1., 9., 11., 24., 17., 4., 21., 3., 12., 11., 4., 1., 4., 5., 15., 21., 19., 44., 15., 17., 4., 4., 2., 2., 6., 7., 2., 8., 11., 9., 11., 4., 23., 7., 4., 0., 2., 9., 1., 3., 1., 4., 2., 5., 4., 1., 2., 6., 2., 0., 2., 1., 0., 5., 2., 1., 1., 2., 7., 1., 3., 6., 1., 2., 0., 2., 4., 2., 0., 0., 1., 3., 1., 5., 2., 3., 0., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0 [...]
+
+13., 2., 3., 4., 10., 5., 10., 5., 10., 25., 1., 16., 15., 0., 17., 5., 0., 0., 15., 3., 6., 29., 15., 28., 29., 9., 1., 1., 0., 2., 3., 7., 22., 23., 2., 14., 4., 20., 11., 4., 1., 4., 3., 12., 8., 22., 44., 12., 24., 11., 1., 2., 3., 0., 9., 4., 9., 6., 12., 9., 6., 21., 6., 3., 0., 0., 8., 2., 2., 1., 6., 3., 8., 1., 2., 3., 3., 2., 0., 2., 1., 0., 1., 2., 3., 6., 3., 3., 2., 1., 9., 6., 1., 1., 2., 2., 0., 0., 3., 1., 3., 4., 1., 2., 0., 2., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0. [...]
+
+4., 0., 4., 1., 10., 2., 8., 2., 4., 17., 0., 6., 18., 1., 14., 4., 0., 1., 20., 1., 5., 20., 11., 21., 32., 9., 3., 0., 5., 2., 8., 5., 23., 16., 1., 6., 5., 9., 12., 2., 1., 7., 1., 7., 15., 20., 43., 22., 16., 6., 3., 1., 11., 2., 6., 0., 13., 6., 10., 16., 3., 20., 9., 4., 1., 0., 7., 0., 3., 2., 11., 2., 3., 3., 1., 5., 1., 0., 2., 1., 1., 0., 1., 2., 3., 5., 1., 5., 2., 0., 6., 1., 1., 1., 2., 12., 2., 0., 5., 3., 6., 1., 2., 2., 2., 0., 5., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.,  [...]
+
+5., 1., 5., 3., 5., 4., 6., 3., 4., 2., 0., 5., 27., 0., 16., 5., 1., 1., 7., 2., 5., 19., 12., 23., 35., 4., 1., 1., 1., 0., 8., 5., 28., 19., 5., 16., 0., 14., 5., 3., 0., 4., 4., 8., 12., 14., 36., 13., 19., 16., 10., 0., 2., 3., 12., 2., 12., 7., 5., 13., 5., 14., 10., 2., 2., 1., 10., 1., 4., 3., 3., 5., 4., 4., 1., 5., 5., 2., 1., 1., 2., 0., 0., 5., 2., 5., 2., 7., 2., 0., 2., 0., 2., 1., 1., 3., 1., 0., 1., 3., 1., 2., 2., 1., 1., 2., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0 [...]
+
+7., 0., 0., 1., 11., 3., 10., 1., 9., 20., 0., 17., 19., 1., 23., 7., 2., 2., 16., 2., 6., 25., 16., 23., 30., 4., 1., 0., 3., 5., 0., 11., 25., 20., 2., 9., 8., 17., 9., 4., 1., 3., 1., 9., 9., 20., 36., 5., 12., 11., 8., 2., 6., 0., 7., 3., 15., 5., 12., 22., 10., 23., 5., 3., 0., 1., 12., 0., 1., 3., 6., 2., 8., 6., 2., 3., 1., 3., 1., 0., 2., 0., 1., 3., 2., 9., 1., 3., 4., 0., 4., 0., 1., 1., 3., 4., 1., 0., 2., 1., 0., 1., 6., 2., 0., 2., 3., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., [...]
+
+12., 2., 3., 7., 5., 6., 4., 0., 4., 20., 0., 17., 20., 1., 12., 5., 1., 2., 31., 0., 4., 26., 12., 18., 14., 6., 0., 1., 4., 2., 6., 10., 24., 20., 2., 10., 2., 12., 6., 2., 0., 3., 3., 12., 8., 15., 60., 10., 21., 8., 5., 1., 8., 4., 13., 2., 8., 8., 15., 15., 6., 14., 10., 1., 0., 2., 10., 1., 3., 0., 9., 2., 4., 4., 3., 5., 4., 0., 0., 0., 4., 0., 2., 4., 1., 8., 2., 7., 2., 2., 8., 3., 2., 1., 1., 8., 3., 0., 2., 3., 0., 2., 2., 1., 2., 1., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0. [...]
+
+4., 1., 0., 3., 9., 1., 7., 1., 9., 13., 1., 7., 23., 1., 12., 2., 1., 0., 19., 2., 4., 15., 16., 24., 28., 4., 1., 1., 2., 2., 5., 15., 18., 16., 0., 12., 3., 11., 4., 2., 2., 8., 4., 14., 9., 23., 50., 15., 21., 7., 4., 1., 3., 0., 10., 2., 6., 4., 9., 16., 7., 22., 5., 4., 1., 2., 13., 0., 2., 1., 7., 2., 4., 5., 4., 7., 6., 0., 0., 2., 0., 0., 1., 1., 1., 4., 5., 4., 0., 0., 3., 0., 2., 0., 1., 8., 0., 0., 0., 2., 1., 1., 3., 2., 2., 3., 2., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., 0. [...]
+
+4., 0., 1., 4., 3., 2., 7., 1., 11., 28., 5., 14., 31., 0., 10., 5., 0., 1., 13., 0., 5., 27., 6., 20., 23., 7., 1., 0., 3., 2., 6., 5., 24., 17., 4., 10., 4., 10., 8., 0., 0., 6., 4., 5., 12., 21., 35., 16., 14., 8., 4., 4., 5., 3., 6., 2., 9., 9., 9., 15., 6., 21., 6., 2., 1., 1., 9., 1., 3., 1., 2., 4., 5., 8., 1., 6., 3., 2., 3., 1., 1., 0., 1., 3., 4., 8., 1., 7., 2., 3., 3., 0., 2., 0., 1., 6., 1., 0., 1., 4., 3., 1., 2., 1., 3., 0., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0.,  [...]
+
+11., 1., 2., 2., 2., 4., 4., 2., 6., 16., 0., 8., 24., 1., 16., 3., 0., 2., 16., 0., 4., 17., 8., 35., 26., 5., 0., 1., 2., 2., 7., 13., 26., 18., 2., 15., 1., 8., 4., 2., 2., 3., 2., 19., 6., 12., 41., 7., 24., 6., 4., 0., 6., 5., 9., 4., 11., 6., 7., 12., 1., 27., 11., 5., 0., 0., 8., 1., 2., 1., 7., 1., 3., 4., 3., 5., 4., 3., 1., 2., 1., 0., 2., 1., 4., 6., 0., 4., 4., 3., 6., 0., 0., 1., 3., 7., 1., 0., 2., 1., 2., 1., 3., 3., 0., 3., 6., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0.,  [...]
+
+6., 0., 1., 0., 21., 0., 16., 5., 7., 45., 2., 10., 70., 1., 6., 2., 0., 4., 66., 9., 8., 75., 14., 80., 11., 3., 0., 1., 2., 1., 11., 8., 54., 9., 0., 35., 44., 13., 1., 0., 1., 4., 5., 32., 5., 24., 8., 19., 8., 0., 1., 0., 9., 1., 18., 6., 15., 5., 12., 3., 3., 36., 9., 6., 3., 0., 12., 5., 5., 0., 16., 6., 2., 0., 1., 1., 0., 5., 3., 19., 4., 3., 7., 2., 3., 0., 0., 0., 0., 0., 8., 4., 0., 1., 4., 2., 1., 0., 0., 0., 2., 0., 3., 4., 1., 0., 0., 0., 4., 0., 1., 0., 0., 0., 0., 0., 1., [...]
+
+11., 1., 1., 6., 27., 9., 33., 1., 12., 161., 4., 27., 227., 6., 13., 9., 1., 7., 70., 3., 11., 268., 44., 297., 51., 18., 0., 4., 5., 5., 48., 36., 232., 46., 11., 159., 18., 38., 3., 0., 0., 22., 10., 85., 25., 93., 17., 38., 44., 16., 2., 2., 31., 8., 46., 8., 52., 7., 36., 8., 13., 5., 1., 0., 1., 0., 17., 8., 9., 1., 34., 3., 12., 4., 3., 3., 0., 3., 3., 1., 9., 4., 8., 5., 11., 3., 0., 5., 129., 4., 1868., 103., 97., 201., 82., 108., 66., 16., 7., 19., 10., 3., 1., 6., 2., 5., 11., [...]
+
+19., 1., 7., 10., 26., 7., 36., 0., 15., 139., 4., 31., 210., 7., 21., 5., 3., 4., 100., 2., 12., 276., 45., 332., 47., 18., 2., 1., 8., 6., 36., 39., 205., 36., 8., 169., 16., 34., 5., 0., 1., 16., 8., 65., 24., 96., 9., 36., 54., 14., 3., 0., 22., 8., 29., 8., 39., 11., 27., 3., 12., 7., 3., 0., 1., 0., 17., 6., 12., 4., 30., 7., 12., 6., 1., 3., 0., 3., 4., 5., 14., 2., 12., 3., 7., 2., 0., 5., 132., 4., 1922., 93., 115., 225., 89., 117., 74., 19., 9., 14., 12., 3., 1., 3., 6., 1., 5. [...]
+
+15., 3., 3., 4., 29., 8., 28., 3., 19., 200., 4., 27., 215., 7., 16., 6., 0., 8., 87., 3., 21., 283., 31., 305., 41., 19., 2., 2., 10., 5., 38., 19., 246., 35., 10., 155., 15., 40., 6., 0., 4., 19., 8., 74., 25., 82., 18., 35., 46., 19., 2., 1., 26., 7., 30., 13., 46., 6., 37., 5., 6., 8., 1., 0., 0., 0., 30., 7., 16., 5., 27., 5., 12., 7., 2., 0., 2., 1., 1., 3., 13., 4., 9., 3., 6., 0., 1., 3., 155., 10., 1946., 86., 76., 206., 104., 129., 71., 16., 18., 12., 11., 0., 5., 9., 9., 5., 7 [...]
+
+9., 4., 3., 7., 28., 8., 33., 0., 22., 145., 6., 21., 186., 8., 17., 6., 0., 2., 63., 2., 14., 277., 49., 349., 44., 17., 2., 3., 6., 5., 38., 24., 250., 40., 11., 177., 12., 25., 7., 0., 0., 14., 5., 93., 11., 87., 21., 40., 43., 19., 4., 0., 16., 7., 44., 9., 56., 5., 36., 6., 8., 7., 3., 0., 2., 0., 27., 6., 16., 3., 26., 9., 19., 6., 2., 4., 0., 2., 3., 1., 14., 6., 10., 3., 12., 0., 1., 1., 128., 5., 1873., 87., 106., 219., 92., 110., 80., 15., 6., 21., 17., 0., 3., 10., 7., 2., 7., [...]
+
+11., 2., 1., 13., 20., 3., 32., 0., 17., 154., 5., 27., 185., 3., 17., 9., 2., 6., 91., 2., 10., 301., 62., 310., 36., 15., 0., 0., 6., 6., 39., 35., 211., 50., 8., 175., 21., 36., 7., 0., 5., 18., 6., 100., 25., 87., 17., 35., 46., 22., 3., 1., 22., 5., 46., 5., 48., 11., 29., 4., 10., 6., 3., 0., 1., 0., 28., 3., 17., 3., 32., 7., 12., 2., 6., 3., 1., 2., 3., 1., 7., 1., 11., 3., 7., 0., 1., 3., 151., 8., 1896., 97., 110., 216., 103., 113., 68., 21., 14., 13., 13., 2., 2., 2., 7., 3.,  [...]
+
+10., 1., 3., 14., 39., 2., 29., 0., 9., 153., 3., 24., 188., 7., 14., 3., 0., 4., 75., 1., 17., 287., 48., 345., 37., 14., 1., 2., 4., 4., 49., 29., 237., 41., 8., 165., 16., 35., 4., 0., 1., 21., 8., 74., 23., 91., 23., 41., 46., 19., 3., 0., 32., 4., 31., 13., 56., 7., 25., 4., 8., 6., 4., 0., 0., 0., 23., 3., 19., 3., 28., 3., 10., 8., 0., 1., 0., 2., 2., 7., 12., 1., 9., 1., 5., 0., 2., 2., 132., 7., 1944., 83., 98., 213., 89., 92., 66., 24., 12., 23., 22., 1., 1., 4., 6., 2., 13., 1 [...]
+
+11., 0., 1., 11., 19., 3., 35., 0., 14., 156., 3., 21., 200., 5., 11., 7., 1., 12., 85., 3., 16., 293., 46., 321., 34., 16., 1., 3., 8., 8., 37., 28., 238., 41., 8., 152., 14., 53., 4., 0., 1., 16., 9., 88., 16., 83., 12., 41., 35., 10., 1., 0., 26., 6., 44., 15., 51., 10., 21., 7., 14., 8., 3., 0., 1., 0., 23., 7., 16., 3., 36., 8., 7., 4., 1., 1., 1., 2., 6., 1., 17., 2., 9., 0., 12., 2., 1., 5., 164., 6., 1867., 89., 93., 216., 90., 116., 56., 9., 18., 25., 13., 1., 3., 7., 3., 5., 10 [...]
+
+9., 5., 4., 5., 20., 6., 37., 1., 20., 163., 2., 33., 206., 5., 18., 7., 2., 4., 64., 3., 21., 262., 49., 359., 46., 15., 2., 0., 4., 5., 40., 40., 221., 34., 6., 166., 17., 28., 6., 0., 4., 28., 10., 80., 24., 70., 12., 41., 56., 16., 2., 0., 26., 5., 45., 13., 53., 15., 31., 6., 16., 4., 0., 0., 4., 0., 24., 5., 16., 5., 35., 6., 7., 7., 0., 2., 0., 2., 3., 2., 7., 2., 7., 1., 5., 1., 0., 6., 144., 16., 1861., 90., 111., 211., 80., 107., 67., 11., 10., 20., 19., 1., 2., 6., 11., 5., 12 [...]
+
+19., 0., 4., 7., 15., 7., 23., 0., 13., 152., 4., 20., 197., 2., 15., 8., 1., 4., 79., 1., 12., 275., 37., 338., 37., 15., 1., 1., 13., 2., 51., 32., 250., 48., 9., 182., 12., 34., 6., 0., 2., 18., 4., 77., 14., 95., 13., 33., 47., 14., 8., 1., 24., 2., 31., 15., 54., 10., 24., 10., 9., 4., 0., 0., 0., 0., 27., 4., 12., 2., 38., 2., 8., 2., 0., 3., 0., 1., 3., 2., 5., 2., 9., 4., 5., 2., 2., 3., 154., 8., 1823., 118., 96., 218., 83., 104., 62., 16., 5., 21., 9., 1., 4., 11., 5., 1., 9.,  [...]
+
+16., 5., 4., 11., 29., 11., 29., 1., 20., 160., 4., 34., 194., 9., 24., 8., 1., 7., 80., 0., 20., 272., 44., 341., 46., 15., 0., 4., 11., 7., 35., 31., 249., 34., 9., 165., 13., 34., 2., 0., 2., 20., 8., 71., 23., 86., 11., 32., 37., 13., 3., 1., 19., 9., 37., 16., 58., 5., 34., 9., 8., 8., 2., 0., 1., 0., 32., 4., 16., 4., 31., 3., 9., 8., 2., 2., 0., 1., 4., 1., 18., 5., 8., 2., 11., 0., 1., 7., 107., 14., 1910., 91., 83., 221., 99., 123., 77., 20., 9., 23., 16., 1., 2., 8., 6., 4., 11 [...]
+
+7., 2., 2., 8., 23., 7., 28., 1., 26., 158., 4., 24., 205., 3., 21., 5., 0., 6., 86., 0., 17., 290., 46., 298., 51., 24., 1., 0., 8., 3., 45., 36., 228., 29., 13., 167., 10., 29., 5., 0., 3., 13., 7., 84., 25., 99., 15., 33., 50., 11., 3., 0., 25., 3., 33., 11., 56., 8., 35., 4., 8., 7., 0., 0., 0., 0., 16., 8., 9., 2., 26., 5., 15., 2., 1., 3., 0., 1., 5., 0., 11., 3., 10., 0., 10., 0., 1., 1., 147., 9., 1947., 78., 86., 232., 87., 112., 62., 20., 18., 14., 17., 0., 1., 7., 4., 5., 8.,  [...]
+
+7., 2., 4., 7., 23., 5., 33., 0., 17., 170., 4., 23., 218., 7., 15., 7., 1., 9., 86., 1., 13., 309., 51., 372., 38., 22., 1., 3., 4., 7., 60., 36., 214., 57., 4., 155., 10., 40., 10., 0., 2., 11., 6., 79., 16., 87., 20., 38., 43., 7., 1., 0., 28., 7., 26., 11., 48., 9., 33., 3., 9., 6., 5., 0., 0., 0., 17., 4., 10., 3., 39., 7., 8., 2., 3., 2., 0., 4., 1., 3., 12., 3., 7., 0., 7., 1., 0., 4., 173., 8., 1941., 89., 100., 212., 92., 109., 62., 14., 12., 17., 10., 1., 4., 8., 1., 5., 5., 6. [...]
+
+3., 1., 1., 4., 6., 1., 6., 0., 2., 20., 1., 24., 34., 1., 12., 2., 0., 3., 15., 3., 3., 19., 14., 26., 33., 4., 0., 0., 2., 4., 5., 9., 24., 16., 2., 18., 1., 12., 12., 0., 2., 3., 1., 14., 10., 29., 40., 17., 16., 7., 4., 0., 9., 1., 5., 3., 9., 9., 6., 12., 5., 19., 15., 2., 0., 1., 9., 1., 4., 2., 6., 3., 1., 5., 1., 4., 3., 3., 0., 2., 1., 0., 1., 2., 0., 7., 1., 6., 2., 5., 4., 0., 2., 0., 2., 6., 1., 0., 1., 1., 1., 1., 3., 6., 5., 3., 2., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0., 0 [...]
+
+10., 1., 1., 3., 12., 3., 4., 2., 3., 23., 3., 19., 16., 0., 8., 2., 0., 2., 13., 3., 3., 32., 14., 18., 21., 4., 1., 0., 2., 3., 9., 5., 33., 16., 2., 20., 1., 15., 5., 0., 2., 1., 1., 17., 18., 12., 55., 19., 13., 7., 9., 0., 3., 2., 5., 3., 11., 5., 9., 15., 3., 14., 15., 2., 1., 1., 4., 1., 2., 2., 3., 2., 1., 4., 3., 5., 2., 2., 0., 0., 3., 0., 3., 2., 2., 4., 3., 2., 3., 3., 4., 1., 2., 1., 2., 5., 2., 0., 1., 2., 0., 0., 3., 4., 4., 1., 4., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.,  [...]
+
+9., 0., 1., 1., 13., 5., 2., 1., 5., 29., 1., 14., 35., 1., 27., 6., 1., 1., 14., 2., 7., 19., 7., 32., 19., 3., 2., 0., 7., 3., 10., 4., 22., 17., 1., 19., 1., 17., 6., 3., 0., 3., 0., 13., 9., 20., 45., 10., 20., 7., 2., 2., 5., 1., 8., 3., 7., 10., 11., 17., 9., 26., 2., 6., 1., 0., 7., 1., 1., 3., 4., 2., 6., 3., 0., 3., 3., 2., 0., 5., 1., 0., 1., 1., 1., 3., 2., 6., 0., 2., 2., 1., 3., 0., 5., 9., 0., 0., 2., 4., 5., 0., 2., 1., 2., 1., 2., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., 0 [...]
+
+7., 2., 2., 6., 7., 4., 3., 0., 6., 24., 1., 17., 22., 0., 15., 5., 2., 3., 24., 1., 4., 20., 12., 30., 22., 3., 1., 1., 1., 2., 5., 9., 24., 16., 2., 20., 5., 17., 13., 0., 2., 1., 1., 5., 13., 18., 42., 14., 18., 6., 1., 1., 5., 0., 9., 2., 10., 7., 9., 18., 8., 22., 4., 6., 1., 1., 8., 1., 0., 1., 6., 2., 1., 4., 3., 3., 3., 2., 2., 2., 1., 0., 1., 2., 1., 6., 3., 4., 3., 1., 7., 2., 0., 2., 1., 13., 2., 0., 2., 1., 0., 2., 0., 3., 1., 2., 1., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0 [...]
+
+9., 1., 3., 2., 6., 6., 8., 1., 7., 20., 1., 13., 25., 0., 13., 1., 2., 0., 22., 1., 4., 23., 10., 25., 32., 8., 0., 2., 4., 3., 9., 2., 28., 8., 4., 20., 1., 5., 12., 1., 0., 6., 4., 8., 9., 21., 49., 9., 11., 6., 4., 2., 4., 0., 4., 3., 15., 6., 12., 20., 8., 13., 8., 1., 1., 2., 8., 2., 4., 5., 5., 2., 3., 2., 3., 7., 0., 2., 2., 3., 4., 0., 2., 1., 2., 9., 0., 2., 1., 1., 5., 2., 1., 1., 2., 8., 3., 0., 2., 7., 2., 1., 0., 3., 2., 1., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0., 4 [...]
+
+5., 0., 2., 3., 7., 2., 6., 0., 12., 20., 0., 21., 17., 0., 10., 2., 1., 1., 22., 0., 3., 30., 10., 30., 31., 6., 0., 0., 1., 3., 6., 3., 27., 16., 3., 15., 4., 14., 9., 5., 0., 3., 2., 12., 5., 15., 48., 9., 19., 7., 6., 4., 7., 0., 7., 3., 8., 9., 10., 17., 5., 18., 9., 2., 0., 0., 4., 1., 1., 1., 5., 5., 4., 2., 1., 5., 4., 1., 3., 1., 3., 0., 1., 1., 2., 8., 1., 4., 2., 3., 3., 1., 2., 1., 1., 6., 2., 0., 0., 1., 2., 0., 2., 4., 2., 1., 3., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0., [...]
+
+9., 0., 2., 6., 11., 6., 7., 0., 8., 18., 1., 10., 27., 0., 28., 3., 0., 1., 15., 3., 5., 34., 11., 29., 29., 2., 0., 1., 6., 3., 9., 6., 23., 13., 2., 4., 3., 15., 7., 2., 1., 4., 4., 7., 9., 19., 52., 12., 19., 13., 3., 1., 6., 1., 7., 4., 8., 3., 7., 15., 5., 18., 10., 2., 1., 1., 3., 1., 2., 2., 5., 5., 5., 8., 4., 6., 4., 2., 3., 4., 2., 0., 0., 2., 1., 3., 3., 3., 2., 1., 5., 1., 2., 0., 5., 6., 0., 0., 3., 1., 4., 3., 3., 3., 0., 0., 1., 0., 0., 0., 0., 3., 0., 0., 4., 0., 0., 0., [...]
+
+11., 0., 4., 2., 5., 2., 9., 1., 7., 11., 2., 11., 28., 0., 13., 2., 1., 3., 14., 1., 2., 28., 15., 40., 28., 5., 0., 0., 3., 1., 8., 8., 29., 9., 3., 13., 3., 18., 13., 0., 0., 7., 4., 15., 10., 13., 56., 7., 23., 9., 8., 3., 7., 3., 6., 2., 12., 6., 12., 20., 3., 13., 13., 2., 2., 1., 5., 2., 1., 2., 4., 4., 1., 3., 0., 5., 2., 2., 0., 0., 3., 0., 1., 2., 0., 4., 1., 4., 1., 0., 3., 0., 3., 3., 1., 9., 0., 0., 2., 1., 2., 1., 3., 4., 1., 1., 3., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0.,  [...]
+
+4., 2., 2., 3., 6., 3., 11., 2., 3., 22., 1., 7., 16., 1., 9., 2., 1., 3., 19., 1., 8., 10., 7., 15., 27., 7., 2., 2., 3., 1., 9., 9., 32., 12., 2., 10., 4., 13., 8., 3., 0., 4., 2., 17., 9., 14., 45., 13., 18., 10., 6., 0., 2., 1., 9., 5., 6., 4., 10., 18., 6., 27., 10., 3., 1., 1., 8., 2., 3., 4., 6., 1., 4., 1., 4., 3., 1., 0., 0., 2., 2., 0., 3., 3., 4., 13., 1., 3., 4., 1., 1., 1., 2., 0., 2., 7., 3., 0., 1., 3., 0., 3., 5., 2., 1., 1., 4., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+5., 1., 3., 1., 6., 4., 7., 1., 3., 16., 0., 16., 23., 2., 22., 1., 0., 1., 15., 1., 1., 17., 11., 25., 30., 3., 0., 0., 1., 0., 7., 8., 25., 20., 0., 7., 3., 22., 9., 0., 1., 4., 0., 9., 8., 18., 52., 10., 20., 7., 5., 4., 3., 1., 9., 4., 11., 5., 8., 11., 5., 20., 4., 5., 4., 0., 9., 2., 2., 3., 4., 3., 3., 4., 4., 4., 5., 4., 0., 3., 1., 0., 2., 4., 5., 7., 1., 3., 0., 3., 5., 1., 2., 1., 1., 4., 2., 0., 2., 1., 1., 2., 1., 1., 6., 0., 0., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0., 1 [...]
+
+11., 1., 4., 1., 5., 1., 7., 0., 4., 15., 2., 10., 27., 1., 17., 3., 0., 0., 29., 3., 3., 22., 9., 27., 23., 3., 0., 0., 4., 2., 8., 7., 17., 14., 2., 7., 7., 12., 13., 1., 0., 4., 2., 5., 9., 15., 46., 15., 19., 6., 5., 2., 3., 2., 10., 5., 11., 2., 6., 15., 4., 26., 7., 4., 1., 0., 6., 2., 4., 1., 6., 1., 4., 5., 0., 6., 3., 1., 0., 1., 3., 0., 2., 3., 2., 10., 2., 1., 2., 1., 3., 1., 3., 0., 1., 10., 5., 0., 2., 3., 1., 3., 0., 2., 1., 0., 1., 0., 0., 0., 0., 2., 0., 0., 6., 0., 0., 0 [...]
+
+13., 1., 0., 6., 5., 3., 7., 2., 6., 15., 1., 13., 17., 1., 12., 7., 0., 3., 18., 4., 1., 18., 9., 14., 32., 6., 2., 0., 1., 1., 4., 10., 19., 14., 4., 13., 0., 13., 8., 2., 0., 4., 0., 15., 12., 13., 48., 13., 20., 11., 1., 3., 7., 3., 5., 5., 9., 10., 4., 16., 6., 21., 8., 4., 2., 1., 4., 0., 3., 0., 5., 1., 1., 4., 1., 3., 5., 1., 1., 3., 3., 0., 3., 1., 2., 6., 2., 5., 0., 2., 7., 1., 1., 0., 0., 5., 2., 0., 1., 4., 0., 1., 2., 1., 0., 0., 2., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0.,  [...]
+
+13., 4., 1., 2., 9., 3., 10., 1., 7., 18., 1., 13., 20., 1., 17., 2., 3., 1., 11., 6., 3., 19., 14., 28., 32., 6., 0., 0., 5., 1., 6., 8., 29., 20., 2., 12., 4., 18., 10., 5., 0., 6., 1., 16., 10., 20., 53., 10., 21., 9., 2., 2., 5., 1., 4., 2., 14., 7., 10., 16., 6., 16., 8., 6., 0., 0., 6., 1., 3., 2., 3., 1., 4., 6., 1., 4., 3., 2., 0., 0., 0., 0., 2., 2., 4., 6., 1., 2., 1., 2., 3., 2., 2., 0., 1., 5., 5., 0., 2., 0., 1., 3., 2., 2., 1., 2., 1., 0., 0., 0., 0., 6., 0., 0., 1., 0., 0. [...]
+
+8., 2., 1., 4., 6., 5., 4., 1., 5., 29., 0., 14., 22., 1., 9., 1., 2., 3., 22., 4., 7., 33., 17., 20., 25., 11., 0., 0., 0., 2., 8., 5., 21., 13., 2., 21., 5., 11., 11., 2., 3., 6., 0., 13., 6., 13., 67., 11., 23., 14., 5., 0., 4., 1., 8., 3., 9., 9., 13., 21., 3., 23., 4., 3., 1., 1., 7., 3., 1., 2., 7., 3., 4., 4., 1., 5., 5., 1., 0., 2., 2., 0., 1., 3., 1., 11., 1., 6., 2., 4., 2., 0., 2., 0., 3., 8., 0., 0., 2., 3., 4., 1., 3., 2., 1., 2., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0.,  [...]
+
+7., 0., 4., 4., 9., 3., 13., 3., 6., 23., 3., 8., 16., 0., 21., 5., 1., 2., 19., 1., 7., 9., 6., 27., 31., 1., 0., 2., 3., 0., 4., 6., 27., 19., 1., 15., 4., 12., 4., 3., 0., 6., 2., 6., 9., 23., 46., 10., 21., 12., 3., 1., 7., 3., 4., 4., 7., 12., 11., 20., 5., 23., 9., 3., 0., 1., 7., 3., 1., 1., 7., 0., 3., 3., 1., 4., 4., 0., 0., 0., 1., 0., 1., 0., 2., 4., 3., 2., 0., 2., 5., 0., 1., 4., 5., 9., 3., 0., 3., 1., 1., 0., 2., 6., 0., 1., 2., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., 0.,  [...]
+
+10., 0., 4., 5., 6., 3., 4., 1., 2., 19., 0., 17., 21., 3., 16., 3., 2., 2., 25., 2., 1., 37., 13., 28., 34., 7., 0., 0., 0., 3., 7., 8., 26., 15., 2., 12., 2., 13., 6., 2., 2., 2., 1., 15., 9., 24., 45., 9., 23., 10., 7., 1., 2., 1., 9., 1., 10., 11., 13., 21., 6., 32., 5., 3., 2., 1., 9., 1., 4., 0., 4., 2., 5., 3., 4., 4., 2., 2., 0., 2., 3., 0., 2., 2., 2., 12., 4., 3., 1., 4., 8., 1., 3., 1., 3., 6., 3., 0., 5., 1., 4., 1., 4., 1., 1., 1., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., [...]
+
+3., 0., 2., 3., 9., 4., 5., 2., 7., 11., 2., 15., 10., 2., 19., 1., 2., 1., 20., 2., 5., 20., 13., 28., 25., 8., 3., 2., 3., 5., 8., 8., 26., 20., 5., 13., 4., 8., 10., 1., 0., 7., 3., 20., 15., 23., 51., 7., 21., 10., 4., 2., 10., 2., 8., 3., 6., 4., 8., 16., 4., 24., 10., 2., 1., 1., 10., 0., 3., 1., 9., 2., 5., 4., 1., 2., 2., 4., 2., 0., 0., 0., 3., 3., 3., 6., 1., 4., 2., 3., 1., 1., 0., 1., 2., 7., 3., 0., 1., 2., 4., 2., 1., 1., 1., 1., 2., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0.,  [...]
+
+6., 1., 4., 2., 9., 2., 11., 1., 4., 11., 1., 14., 15., 1., 15., 1., 0., 0., 14., 3., 2., 24., 11., 5., 38., 6., 0., 1., 5., 1., 7., 1., 15., 11., 3., 9., 6., 6., 9., 2., 0., 6., 1., 20., 13., 13., 44., 12., 20., 8., 3., 2., 8., 0., 2., 3., 9., 6., 9., 9., 5., 22., 8., 5., 0., 1., 10., 1., 3., 3., 7., 1., 7., 2., 1., 5., 2., 4., 1., 0., 1., 0., 2., 3., 2., 4., 2., 4., 3., 4., 5., 1., 2., 0., 4., 6., 3., 0., 3., 0., 1., 0., 1., 3., 1., 1., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0., 1 [...]
+
+11., 0., 4., 5., 8., 3., 3., 0., 9., 18., 0., 11., 28., 1., 19., 3., 0., 1., 15., 0., 6., 23., 12., 24., 31., 7., 3., 0., 2., 4., 9., 7., 34., 17., 4., 20., 5., 18., 15., 3., 1., 1., 1., 6., 9., 26., 41., 13., 21., 10., 11., 0., 2., 3., 3., 7., 11., 5., 7., 26., 8., 17., 5., 2., 0., 0., 4., 0., 2., 5., 6., 3., 2., 3., 1., 1., 4., 1., 1., 2., 2., 0., 1., 0., 6., 3., 2., 2., 0., 2., 0., 1., 1., 0., 0., 4., 2., 0., 1., 1., 1., 1., 3., 0., 2., 1., 6., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0.,  [...]
+
+12., 1., 3., 2., 7., 0., 17., 2., 7., 39., 1., 4., 50., 0., 3., 5., 0., 4., 72., 19., 5., 84., 21., 84., 9., 2., 0., 0., 4., 3., 12., 7., 64., 7., 2., 43., 33., 10., 5., 0., 2., 8., 4., 23., 4., 26., 9., 12., 6., 2., 3., 0., 6., 5., 18., 7., 30., 3., 13., 3., 1., 30., 3., 7., 1., 0., 19., 2., 9., 3., 11., 2., 2., 0., 3., 0., 0., 6., 3., 11., 5., 3., 3., 2., 5., 0., 0., 0., 0., 0., 2., 3., 2., 0., 1., 0., 3., 0., 2., 0., 1., 0., 1., 1., 3., 0., 2., 0., 1., 0., 0., 0., 0., 0., 1., 0., 1.,  [...]
+
+8., 3., 7., 12., 12., 7., 32., 1., 11., 166., 4., 20., 186., 3., 12., 11., 1., 5., 96., 1., 18., 307., 46., 313., 45., 23., 0., 2., 9., 9., 44., 30., 241., 43., 10., 144., 18., 40., 7., 0., 1., 19., 12., 60., 20., 82., 10., 28., 40., 10., 3., 1., 26., 9., 39., 13., 59., 9., 25., 8., 4., 7., 2., 0., 1., 0., 21., 9., 19., 4., 38., 4., 16., 6., 3., 2., 0., 2., 3., 4., 7., 4., 8., 1., 8., 2., 0., 3., 136., 10., 1888., 91., 107., 218., 122., 115., 70., 15., 9., 21., 16., 0., 2., 7., 3., 5., 1 [...]
+
+14., 1., 2., 10., 21., 2., 26., 0., 14., 173., 4., 21., 178., 7., 15., 8., 5., 7., 75., 4., 14., 281., 36., 339., 42., 24., 0., 5., 3., 8., 42., 33., 234., 41., 6., 142., 15., 36., 5., 0., 1., 22., 8., 77., 16., 85., 14., 36., 54., 10., 1., 0., 22., 7., 47., 11., 56., 7., 38., 5., 17., 6., 5., 0., 0., 0., 33., 5., 11., 3., 27., 2., 13., 6., 2., 3., 1., 1., 4., 0., 9., 2., 7., 2., 7., 0., 1., 3., 138., 7., 1940., 89., 92., 222., 107., 133., 57., 14., 8., 12., 14., 1., 1., 3., 0., 7., 7.,  [...]
+
+16., 3., 4., 12., 30., 4., 34., 1., 20., 176., 3., 21., 192., 6., 14., 7., 2., 7., 59., 2., 17., 317., 41., 316., 45., 20., 2., 4., 6., 6., 50., 30., 236., 35., 16., 178., 12., 37., 6., 0., 3., 10., 10., 79., 17., 78., 18., 24., 54., 10., 3., 4., 33., 7., 50., 8., 50., 6., 27., 6., 16., 11., 3., 0., 1., 0., 24., 3., 15., 5., 32., 5., 10., 7., 1., 1., 0., 2., 4., 3., 9., 2., 12., 3., 12., 0., 2., 3., 144., 9., 1908., 99., 106., 235., 94., 119., 63., 14., 10., 9., 8., 0., 4., 5., 6., 4., 1 [...]
+
+16., 1., 3., 8., 13., 7., 25., 0., 13., 137., 3., 29., 187., 7., 15., 9., 1., 7., 84., 4., 18., 272., 35., 363., 52., 20., 3., 1., 3., 5., 53., 32., 224., 42., 9., 170., 16., 41., 13., 0., 1., 19., 2., 78., 12., 79., 23., 36., 39., 13., 5., 3., 23., 6., 32., 11., 51., 18., 32., 3., 13., 10., 3., 0., 1., 0., 18., 6., 10., 7., 17., 2., 9., 4., 1., 1., 1., 1., 1., 1., 12., 2., 5., 0., 11., 1., 0., 2., 138., 7., 1841., 78., 103., 224., 108., 104., 73., 13., 10., 21., 14., 0., 1., 6., 2., 6., [...]
+
+13., 5., 4., 8., 21., 6., 31., 2., 12., 185., 0., 24., 215., 6., 12., 4., 2., 3., 70., 1., 16., 281., 44., 346., 31., 14., 2., 1., 5., 6., 48., 34., 228., 35., 5., 132., 13., 34., 8., 0., 3., 12., 4., 68., 23., 86., 10., 38., 49., 16., 1., 0., 29., 4., 49., 8., 50., 12., 27., 6., 10., 7., 1., 0., 2., 0., 26., 6., 17., 4., 21., 9., 13., 2., 0., 7., 0., 1., 1., 3., 10., 5., 6., 1., 7., 2., 0., 2., 141., 6., 1889., 90., 104., 237., 75., 113., 55., 12., 11., 23., 7., 2., 1., 11., 5., 4., 11. [...]
+
+10., 1., 0., 6., 26., 4., 35., 0., 10., 152., 2., 25., 208., 6., 18., 7., 2., 7., 95., 0., 10., 276., 40., 322., 50., 25., 2., 2., 6., 6., 36., 32., 218., 42., 12., 174., 12., 35., 6., 0., 5., 19., 5., 73., 24., 79., 17., 29., 52., 20., 4., 1., 31., 12., 53., 7., 37., 9., 25., 6., 9., 3., 2., 0., 3., 0., 20., 5., 17., 1., 27., 6., 11., 1., 4., 3., 0., 2., 2., 1., 13., 4., 7., 2., 4., 1., 0., 6., 147., 12., 1917., 84., 116., 188., 109., 125., 74., 10., 22., 17., 14., 3., 1., 8., 4., 8., 1 [...]
+
+21., 3., 1., 4., 32., 6., 40., 2., 19., 157., 3., 27., 210., 4., 12., 11., 2., 6., 84., 3., 16., 278., 53., 356., 48., 20., 1., 4., 6., 3., 47., 25., 233., 32., 5., 166., 13., 40., 8., 0., 2., 16., 6., 96., 22., 83., 10., 32., 51., 21., 4., 3., 13., 10., 39., 9., 56., 11., 33., 5., 10., 4., 1., 0., 1., 0., 19., 3., 18., 5., 26., 8., 13., 3., 2., 3., 1., 2., 0., 0., 11., 1., 5., 1., 6., 0., 2., 2., 152., 14., 1938., 84., 104., 207., 89., 109., 65., 15., 7., 15., 15., 1., 0., 2., 7., 2., 1 [...]
+
+18., 3., 2., 9., 15., 8., 31., 1., 14., 159., 1., 18., 219., 3., 20., 5., 1., 3., 79., 0., 17., 256., 54., 328., 53., 20., 1., 3., 6., 10., 45., 37., 219., 46., 7., 151., 9., 38., 8., 0., 4., 12., 11., 88., 23., 100., 11., 39., 39., 10., 5., 2., 25., 4., 40., 6., 48., 13., 31., 9., 7., 9., 4., 0., 0., 0., 31., 11., 13., 2., 31., 7., 12., 7., 3., 5., 1., 1., 0., 1., 11., 6., 5., 1., 10., 0., 0., 3., 133., 9., 1857., 93., 92., 212., 94., 130., 62., 15., 13., 25., 19., 2., 2., 12., 5., 2.,  [...]
+
+7., 3., 7., 8., 21., 10., 23., 1., 12., 155., 4., 20., 204., 5., 14., 7., 2., 7., 79., 3., 14., 290., 46., 293., 46., 25., 1., 1., 8., 9., 52., 39., 218., 51., 8., 161., 12., 36., 2., 0., 2., 14., 11., 84., 23., 82., 17., 29., 50., 15., 1., 2., 26., 5., 49., 13., 45., 9., 29., 3., 12., 7., 3., 0., 3., 0., 20., 4., 16., 2., 43., 4., 5., 2., 2., 2., 2., 0., 5., 2., 12., 5., 7., 0., 7., 3., 1., 1., 149., 7., 1917., 90., 102., 226., 91., 111., 73., 10., 7., 21., 12., 1., 1., 6., 5., 3., 10., [...]
+
+19., 1., 1., 8., 18., 8., 27., 1., 13., 167., 4., 37., 181., 4., 8., 12., 1., 5., 100., 2., 16., 305., 57., 281., 42., 19., 1., 3., 7., 4., 41., 27., 224., 33., 7., 148., 8., 42., 6., 0., 3., 14., 9., 92., 19., 89., 19., 47., 51., 17., 0., 3., 26., 11., 36., 8., 36., 10., 31., 3., 12., 5., 3., 0., 0., 0., 23., 5., 21., 2., 24., 8., 13., 5., 6., 3., 0., 1., 3., 3., 7., 2., 11., 0., 8., 0., 3., 3., 142., 12., 1972., 80., 97., 234., 102., 100., 63., 8., 12., 11., 7., 1., 1., 10., 4., 4., 8. [...]
+
+18., 0., 1., 7., 26., 9., 32., 1., 19., 136., 1., 31., 201., 5., 8., 8., 0., 4., 89., 2., 14., 299., 48., 344., 45., 17., 2., 3., 7., 2., 44., 33., 230., 30., 9., 169., 13., 33., 4., 0., 4., 13., 11., 88., 16., 104., 20., 39., 43., 12., 2., 3., 19., 7., 32., 4., 44., 9., 25., 6., 9., 4., 2., 0., 1., 0., 21., 10., 8., 5., 28., 2., 11., 7., 3., 6., 0., 0., 3., 1., 11., 1., 8., 2., 13., 1., 0., 3., 139., 12., 1877., 77., 110., 238., 111., 112., 71., 27., 13., 14., 12., 0., 1., 6., 10., 6.,  [...]
+
+8., 2., 3., 1., 6., 2., 6., 1., 7., 21., 1., 15., 13., 3., 19., 4., 0., 3., 15., 3., 5., 36., 10., 21., 23., 6., 2., 2., 2., 0., 6., 8., 29., 10., 2., 17., 2., 21., 13., 2., 1., 2., 2., 12., 15., 8., 49., 15., 22., 10., 3., 1., 4., 4., 4., 3., 6., 7., 10., 16., 11., 21., 13., 4., 0., 3., 4., 0., 3., 2., 4., 2., 5., 2., 2., 4., 4., 1., 0., 1., 3., 0., 2., 4., 3., 8., 1., 3., 2., 3., 2., 0., 3., 0., 3., 7., 3., 0., 0., 1., 2., 0., 2., 1., 1., 0., 4., 0., 0., 0., 0., 4., 0., 0., 4., 0., 0., [...]
+
+7., 2., 2., 3., 11., 6., 7., 2., 7., 38., 2., 14., 10., 2., 21., 0., 1., 3., 11., 2., 4., 11., 17., 33., 32., 7., 0., 0., 2., 3., 7., 8., 20., 15., 2., 13., 5., 17., 7., 1., 0., 2., 4., 9., 9., 27., 56., 11., 14., 6., 6., 1., 8., 1., 6., 1., 10., 5., 8., 15., 6., 17., 7., 9., 0., 0., 5., 1., 2., 2., 5., 3., 6., 5., 2., 2., 2., 2., 1., 5., 1., 0., 3., 2., 3., 4., 5., 1., 2., 3., 2., 2., 1., 0., 2., 7., 1., 0., 1., 4., 1., 3., 2., 2., 1., 0., 3., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., 0., [...]
+
+2., 2., 2., 2., 8., 2., 9., 1., 5., 21., 0., 13., 14., 1., 15., 3., 0., 0., 12., 0., 1., 27., 11., 32., 28., 7., 0., 0., 3., 3., 4., 7., 31., 13., 4., 22., 3., 10., 12., 3., 0., 1., 0., 12., 8., 13., 44., 11., 21., 8., 5., 2., 6., 3., 11., 2., 17., 7., 8., 17., 7., 24., 6., 4., 0., 0., 6., 1., 2., 1., 6., 3., 3., 2., 5., 6., 3., 2., 1., 4., 3., 0., 1., 1., 2., 1., 6., 1., 3., 3., 2., 0., 3., 3., 2., 5., 1., 0., 1., 1., 1., 0., 1., 1., 3., 0., 2., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0 [...]
+
+13., 1., 2., 1., 10., 2., 8., 3., 9., 18., 0., 8., 21., 2., 19., 2., 1., 1., 11., 2., 5., 16., 10., 24., 23., 4., 2., 0., 3., 1., 5., 5., 17., 19., 3., 13., 8., 15., 12., 1., 1., 6., 1., 16., 8., 11., 30., 7., 21., 6., 3., 0., 2., 1., 11., 0., 13., 6., 6., 18., 3., 14., 8., 1., 1., 0., 7., 0., 3., 3., 5., 1., 6., 4., 3., 5., 7., 2., 1., 1., 2., 0., 0., 0., 2., 8., 1., 2., 1., 1., 4., 0., 3., 2., 2., 8., 0., 0., 1., 4., 1., 2., 4., 2., 2., 0., 2., 0., 0., 0., 0., 4., 0., 0., 0., 0., 0., 0 [...]
+
+5., 1., 5., 2., 9., 3., 9., 1., 4., 32., 1., 14., 25., 1., 11., 3., 1., 2., 12., 1., 3., 33., 6., 26., 28., 3., 0., 1., 4., 1., 4., 8., 13., 17., 0., 18., 5., 11., 10., 1., 1., 4., 0., 6., 12., 20., 60., 13., 19., 5., 4., 1., 4., 1., 5., 4., 13., 6., 6., 18., 3., 23., 9., 1., 0., 0., 8., 1., 2., 1., 2., 7., 5., 3., 5., 3., 3., 2., 0., 2., 2., 0., 1., 0., 4., 5., 5., 4., 3., 2., 4., 3., 2., 0., 5., 10., 1., 0., 2., 4., 2., 3., 2., 2., 1., 0., 6., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+3., 1., 3., 6., 1., 1., 7., 2., 5., 30., 1., 17., 15., 0., 12., 3., 1., 1., 10., 0., 1., 28., 12., 21., 23., 6., 2., 0., 3., 5., 10., 16., 38., 10., 2., 19., 3., 10., 12., 1., 3., 6., 0., 13., 16., 26., 44., 13., 15., 13., 2., 0., 4., 1., 8., 4., 4., 7., 9., 6., 12., 21., 8., 3., 2., 1., 3., 0., 2., 4., 3., 3., 4., 5., 3., 6., 5., 5., 0., 3., 1., 0., 1., 4., 0., 5., 1., 1., 3., 3., 1., 2., 1., 0., 8., 11., 2., 0., 2., 3., 2., 3., 2., 3., 2., 2., 2., 0., 0., 0., 0., 7., 0., 0., 2., 0., 0. [...]
+
+11., 2., 1., 2., 4., 2., 3., 2., 3., 27., 1., 20., 22., 1., 21., 2., 1., 3., 19., 1., 8., 10., 15., 29., 29., 8., 0., 0., 0., 3., 5., 13., 25., 10., 3., 12., 5., 16., 9., 1., 2., 4., 4., 10., 14., 15., 38., 17., 17., 11., 4., 2., 5., 0., 10., 5., 9., 6., 7., 10., 4., 21., 13., 4., 1., 1., 4., 0., 4., 0., 5., 4., 3., 3., 0., 3., 2., 0., 0., 0., 1., 0., 0., 1., 3., 9., 5., 4., 0., 0., 7., 0., 3., 0., 2., 5., 3., 0., 2., 2., 0., 4., 1., 2., 3., 1., 3., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0. [...]
+
+13., 1., 3., 4., 11., 4., 3., 0., 6., 31., 0., 8., 26., 1., 15., 3., 1., 2., 18., 2., 4., 19., 10., 10., 20., 7., 0., 1., 2., 3., 10., 0., 23., 20., 3., 19., 2., 7., 6., 1., 1., 6., 0., 17., 8., 21., 40., 9., 34., 10., 4., 0., 11., 3., 5., 1., 10., 7., 5., 16., 6., 28., 9., 4., 1., 1., 10., 1., 6., 0., 5., 1., 6., 6., 4., 5., 3., 2., 2., 1., 4., 0., 0., 0., 0., 4., 4., 4., 0., 3., 6., 2., 1., 1., 2., 7., 2., 0., 2., 1., 1., 0., 1., 5., 1., 0., 2., 0., 0., 0., 0., 0., 0., 0., 5., 0., 0.,  [...]
+
+7., 3., 0., 4., 7., 4., 6., 1., 2., 15., 0., 10., 21., 0., 22., 0., 0., 4., 15., 1., 1., 19., 16., 18., 32., 4., 0., 1., 4., 2., 7., 5., 24., 8., 4., 15., 4., 15., 11., 2., 1., 2., 5., 11., 10., 12., 37., 7., 19., 7., 4., 1., 3., 2., 11., 1., 3., 12., 10., 15., 8., 20., 7., 4., 0., 2., 11., 1., 7., 2., 5., 7., 7., 5., 1., 5., 3., 0., 0., 2., 0., 0., 5., 1., 1., 4., 1., 4., 2., 1., 3., 1., 2., 0., 3., 9., 2., 0., 2., 4., 1., 3., 0., 0., 2., 1., 1., 0., 0., 0., 0., 5., 0., 0., 4., 0., 0.,  [...]
+
+10., 0., 3., 6., 7., 5., 4., 1., 4., 26., 1., 14., 27., 2., 18., 1., 0., 2., 13., 2., 4., 23., 11., 29., 26., 7., 0., 3., 4., 3., 9., 10., 26., 18., 3., 17., 3., 5., 11., 0., 2., 2., 0., 16., 13., 12., 51., 12., 19., 11., 2., 1., 4., 1., 8., 3., 9., 7., 9., 9., 9., 17., 8., 1., 0., 0., 7., 1., 3., 3., 2., 4., 2., 1., 4., 2., 2., 2., 1., 0., 1., 0., 4., 0., 1., 5., 3., 6., 4., 2., 3., 1., 3., 1., 1., 6., 0., 0., 3., 1., 0., 3., 2., 0., 4., 1., 2., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., 0 [...]
+
+6., 1., 4., 4., 9., 7., 5., 0., 7., 27., 1., 11., 28., 0., 17., 1., 0., 2., 16., 4., 4., 24., 13., 22., 30., 5., 2., 0., 3., 0., 12., 6., 3., 14., 1., 7., 5., 17., 13., 0., 1., 4., 3., 10., 18., 13., 45., 8., 12., 14., 4., 2., 5., 0., 12., 2., 11., 9., 12., 16., 8., 22., 8., 1., 0., 2., 12., 1., 0., 1., 4., 2., 5., 6., 2., 1., 7., 2., 1., 1., 1., 0., 2., 3., 2., 2., 2., 1., 2., 0., 5., 1., 3., 2., 1., 7., 4., 0., 5., 4., 4., 2., 0., 1., 5., 0., 3., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., [...]
+
+10., 0., 0., 5., 6., 1., 9., 3., 6., 25., 1., 18., 24., 0., 23., 1., 1., 3., 17., 4., 5., 38., 9., 34., 30., 6., 0., 0., 6., 4., 14., 6., 34., 19., 2., 14., 7., 12., 7., 1., 0., 2., 3., 17., 19., 26., 35., 5., 33., 11., 2., 2., 9., 0., 7., 4., 6., 7., 8., 12., 5., 26., 9., 6., 3., 2., 10., 0., 2., 0., 2., 2., 5., 7., 1., 4., 3., 0., 2., 2., 4., 0., 1., 2., 0., 6., 1., 0., 2., 1., 2., 0., 3., 1., 2., 8., 3., 0., 1., 0., 2., 3., 4., 2., 2., 0., 2., 0., 0., 0., 0., 4., 0., 0., 0., 0., 0., 0 [...]
+
+10., 2., 4., 6., 13., 5., 7., 1., 5., 37., 1., 12., 17., 0., 20., 2., 0., 3., 16., 2., 1., 33., 12., 16., 22., 2., 0., 1., 5., 3., 11., 16., 28., 19., 0., 14., 4., 7., 11., 2., 0., 7., 1., 15., 7., 19., 40., 8., 27., 3., 2., 3., 3., 4., 4., 2., 6., 3., 4., 20., 4., 24., 10., 3., 1., 0., 5., 0., 1., 2., 10., 7., 3., 9., 0., 6., 6., 2., 2., 2., 4., 0., 3., 2., 1., 7., 6., 3., 4., 3., 8., 1., 1., 0., 1., 5., 2., 0., 2., 2., 3., 1., 1., 2., 2., 0., 4., 0., 0., 0., 0., 4., 0., 0., 4., 0., 0., [...]
+
+7., 2., 3., 5., 8., 3., 10., 1., 7., 18., 1., 10., 21., 0., 11., 3., 3., 1., 18., 1., 3., 29., 8., 28., 21., 2., 2., 0., 2., 1., 10., 7., 20., 23., 5., 17., 6., 12., 11., 4., 1., 4., 4., 22., 12., 21., 41., 14., 26., 10., 4., 3., 4., 3., 8., 0., 9., 2., 7., 12., 10., 25., 13., 3., 2., 1., 12., 2., 2., 1., 3., 2., 6., 4., 2., 5., 6., 4., 0., 3., 2., 0., 3., 3., 5., 7., 6., 5., 1., 3., 4., 0., 3., 1., 4., 4., 0., 0., 4., 1., 2., 8., 3., 3., 3., 1., 0., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0 [...]
+
+7., 1., 0., 3., 11., 4., 3., 1., 6., 18., 2., 13., 17., 1., 16., 2., 3., 4., 24., 2., 6., 31., 7., 32., 23., 2., 0., 2., 2., 2., 10., 2., 18., 22., 1., 5., 2., 12., 7., 4., 0., 2., 0., 11., 15., 18., 58., 13., 17., 9., 5., 0., 3., 1., 10., 2., 11., 7., 13., 14., 5., 18., 13., 2., 2., 2., 6., 0., 7., 4., 6., 5., 7., 2., 2., 2., 4., 2., 0., 1., 4., 0., 2., 3., 4., 7., 4., 10., 0., 2., 2., 0., 6., 1., 2., 9., 2., 0., 2., 2., 4., 2., 2., 1., 5., 0., 4., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0. [...]
+
+13., 0., 2., 4., 9., 3., 4., 2., 8., 19., 1., 22., 31., 1., 8., 4., 0., 3., 28., 3., 4., 22., 12., 18., 29., 6., 2., 2., 5., 3., 8., 10., 30., 18., 3., 12., 5., 13., 10., 1., 2., 2., 2., 11., 9., 16., 45., 19., 25., 8., 1., 1., 6., 1., 6., 3., 14., 8., 7., 12., 7., 19., 4., 3., 0., 3., 10., 2., 2., 3., 3., 3., 4., 4., 4., 4., 3., 1., 1., 0., 3., 0., 2., 2., 2., 4., 1., 3., 4., 2., 6., 1., 0., 1., 1., 4., 1., 0., 4., 3., 3., 2., 1., 3., 1., 2., 4., 0., 0., 0., 0., 2., 0., 0., 4., 0., 0.,  [...]
+
+3., 2., 1., 7., 10., 2., 8., 1., 7., 24., 2., 14., 21., 1., 24., 3., 1., 2., 23., 2., 3., 33., 14., 24., 28., 12., 0., 2., 4., 3., 6., 1., 34., 16., 4., 22., 3., 12., 5., 1., 2., 2., 3., 12., 14., 17., 53., 8., 19., 14., 7., 2., 2., 1., 8., 4., 13., 7., 12., 19., 4., 29., 9., 4., 2., 0., 1., 0., 6., 2., 0., 2., 4., 3., 3., 3., 3., 2., 0., 2., 1., 0., 4., 1., 1., 7., 4., 4., 3., 0., 1., 0., 1., 1., 1., 6., 3., 0., 1., 2., 3., 1., 1., 4., 1., 0., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., [...]
+
+7., 2., 2., 2., 11., 1., 5., 0., 3., 16., 3., 22., 27., 1., 13., 3., 1., 2., 18., 5., 8., 14., 11., 20., 19., 6., 2., 3., 6., 3., 7., 6., 26., 21., 1., 9., 5., 19., 5., 2., 1., 1., 2., 9., 10., 23., 25., 10., 21., 11., 3., 0., 3., 7., 3., 2., 9., 3., 5., 10., 3., 24., 8., 4., 0., 1., 4., 1., 5., 2., 5., 3., 1., 1., 1., 3., 3., 6., 1., 1., 1., 0., 2., 0., 2., 5., 2., 4., 2., 2., 2., 0., 3., 0., 2., 8., 1., 0., 4., 4., 0., 1., 4., 0., 2., 4., 1., 0., 0., 0., 0., 1., 0., 0., 4., 0., 0., 0., [...]
+
+9., 0., 2., 6., 6., 3., 6., 3., 6., 20., 2., 17., 17., 0., 12., 1., 0., 1., 15., 2., 5., 19., 14., 36., 32., 4., 1., 2., 3., 2., 9., 13., 22., 11., 2., 13., 1., 14., 9., 1., 1., 4., 1., 12., 5., 20., 48., 6., 26., 4., 4., 0., 3., 2., 5., 4., 8., 7., 8., 14., 4., 23., 1., 2., 0., 0., 12., 0., 0., 2., 5., 5., 1., 4., 1., 5., 3., 2., 2., 1., 4., 0., 1., 2., 2., 5., 3., 3., 1., 1., 5., 1., 1., 1., 6., 6., 0., 0., 2., 3., 3., 2., 3., 1., 2., 1., 2., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0., [...]
+
+7., 0., 2., 2., 10., 0., 11., 1., 9., 29., 2., 17., 26., 0., 14., 4., 0., 5., 12., 3., 5., 21., 17., 22., 28., 2., 0., 1., 0., 0., 5., 6., 21., 15., 4., 19., 3., 9., 7., 0., 0., 2., 3., 14., 19., 24., 56., 9., 20., 9., 2., 1., 7., 3., 3., 4., 6., 6., 11., 20., 5., 21., 7., 5., 1., 1., 11., 0., 6., 0., 7., 2., 4., 5., 1., 4., 2., 1., 1., 3., 2., 0., 3., 0., 0., 7., 3., 4., 3., 2., 5., 1., 1., 2., 0., 5., 3., 0., 2., 4., 3., 3., 2., 2., 1., 1., 0., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., 0 [...]
+
+12., 1., 1., 4., 10., 0., 11., 3., 3., 51., 1., 6., 53., 1., 11., 1., 0., 1., 64., 11., 4., 69., 18., 74., 14., 6., 0., 0., 2., 1., 16., 13., 56., 16., 1., 39., 36., 14., 2., 0., 2., 2., 3., 28., 7., 25., 7., 9., 13., 5., 1., 0., 8., 2., 17., 6., 13., 1., 7., 4., 2., 36., 9., 11., 1., 0., 15., 2., 5., 0., 9., 4., 2., 2., 0., 1., 0., 11., 1., 21., 9., 5., 2., 4., 3., 0., 0., 0., 0., 0., 7., 1., 1., 3., 4., 2., 0., 0., 0., 0., 0., 0., 1., 8., 2., 0., 5., 0., 0., 0., 1., 0., 0., 0., 2., 0., [...]
+
+19., 3., 3., 5., 19., 6., 30., 0., 15., 163., 5., 20., 201., 2., 13., 9., 0., 5., 79., 5., 11., 297., 38., 348., 49., 14., 0., 1., 7., 2., 42., 33., 223., 44., 5., 159., 10., 39., 6., 0., 0., 17., 13., 74., 20., 93., 12., 28., 41., 21., 6., 0., 33., 2., 40., 7., 49., 11., 24., 4., 14., 7., 0., 0., 1., 0., 26., 5., 10., 3., 26., 1., 14., 2., 2., 4., 0., 0., 1., 2., 15., 0., 6., 2., 8., 3., 0., 7., 134., 7., 1863., 88., 104., 202., 92., 107., 70., 14., 12., 12., 20., 0., 2., 3., 5., 8., 8. [...]
+
+11., 2., 2., 7., 20., 6., 29., 1., 21., 161., 5., 32., 226., 3., 15., 6., 1., 7., 80., 4., 12., 279., 38., 344., 33., 14., 3., 1., 5., 6., 39., 42., 226., 47., 13., 146., 8., 41., 10., 0., 4., 13., 13., 65., 14., 99., 16., 25., 38., 14., 3., 2., 16., 8., 35., 7., 53., 13., 24., 7., 4., 9., 0., 0., 0., 0., 17., 5., 18., 0., 31., 8., 10., 5., 5., 3., 1., 1., 2., 1., 9., 0., 10., 2., 7., 2., 1., 3., 130., 7., 1891., 108., 108., 205., 95., 115., 61., 16., 12., 17., 18., 2., 2., 7., 3., 3., 8 [...]
+
+12., 3., 0., 3., 25., 4., 29., 0., 17., 132., 6., 31., 196., 5., 28., 12., 1., 4., 99., 1., 19., 259., 57., 321., 42., 14., 0., 1., 8., 3., 49., 27., 241., 44., 11., 163., 9., 38., 5., 0., 1., 18., 6., 79., 21., 80., 5., 38., 51., 10., 2., 1., 17., 6., 54., 9., 50., 6., 28., 6., 7., 6., 3., 0., 0., 0., 23., 8., 13., 2., 30., 4., 11., 3., 1., 0., 3., 3., 4., 1., 14., 2., 10., 5., 7., 2., 0., 5., 135., 6., 1877., 98., 93., 209., 110., 116., 75., 16., 14., 22., 10., 1., 3., 7., 7., 4., 9.,  [...]
+
+20., 2., 3., 12., 25., 4., 33., 0., 18., 125., 4., 15., 192., 6., 19., 7., 2., 2., 70., 2., 13., 271., 49., 317., 47., 16., 0., 3., 4., 4., 38., 26., 234., 45., 7., 154., 19., 43., 6., 0., 7., 12., 9., 70., 26., 90., 12., 33., 50., 7., 2., 1., 23., 6., 44., 10., 60., 9., 35., 7., 9., 5., 5., 0., 2., 0., 23., 5., 9., 7., 30., 6., 10., 3., 0., 4., 1., 5., 5., 6., 14., 3., 12., 1., 6., 1., 0., 4., 129., 7., 1920., 94., 111., 217., 95., 98., 72., 12., 17., 24., 15., 1., 2., 7., 7., 4., 13.,  [...]
+
+7., 3., 2., 8., 26., 5., 22., 0., 8., 149., 7., 23., 178., 5., 14., 7., 0., 2., 90., 1., 16., 266., 39., 327., 45., 16., 0., 1., 7., 1., 38., 36., 227., 34., 8., 160., 24., 31., 8., 0., 1., 11., 8., 88., 15., 95., 15., 40., 42., 9., 4., 3., 30., 5., 39., 6., 49., 10., 32., 9., 8., 10., 1., 0., 0., 0., 33., 2., 21., 5., 36., 7., 9., 10., 2., 2., 1., 2., 4., 0., 9., 2., 4., 2., 6., 1., 1., 4., 140., 8., 1893., 75., 99., 226., 97., 125., 53., 14., 13., 22., 18., 2., 1., 8., 2., 4., 11., 7., [...]
+
+12., 0., 3., 6., 21., 2., 34., 2., 21., 167., 1., 34., 171., 5., 18., 5., 3., 3., 85., 2., 22., 264., 27., 345., 43., 10., 1., 2., 15., 6., 42., 27., 224., 39., 9., 164., 12., 35., 8., 0., 3., 13., 7., 78., 20., 77., 15., 42., 51., 14., 2., 0., 29., 16., 46., 7., 56., 9., 27., 4., 14., 7., 1., 0., 0., 0., 19., 7., 13., 6., 22., 7., 11., 5., 4., 3., 1., 0., 5., 0., 16., 3., 10., 0., 14., 4., 1., 2., 118., 7., 1829., 108., 88., 213., 106., 114., 73., 16., 12., 13., 10., 0., 1., 4., 3., 7., [...]
+
+15., 0., 2., 13., 23., 12., 22., 2., 7., 143., 3., 33., 210., 3., 16., 9., 0., 7., 80., 2., 14., 292., 48., 309., 47., 16., 2., 2., 5., 8., 33., 39., 238., 34., 7., 166., 18., 28., 7., 0., 5., 18., 8., 82., 16., 85., 15., 39., 38., 15., 0., 0., 29., 2., 36., 9., 57., 9., 32., 4., 20., 13., 0., 0., 0., 0., 31., 5., 15., 2., 23., 5., 14., 2., 3., 3., 1., 2., 0., 1., 14., 3., 10., 3., 7., 1., 0., 6., 137., 10., 1871., 94., 99., 215., 98., 110., 67., 17., 12., 21., 11., 3., 0., 4., 11., 3.,  [...]
+
+11., 4., 2., 7., 16., 5., 36., 0., 17., 157., 3., 21., 221., 0., 18., 9., 1., 6., 71., 1., 20., 287., 41., 345., 38., 19., 1., 2., 9., 6., 46., 35., 229., 40., 7., 156., 12., 34., 8., 0., 2., 21., 6., 97., 22., 96., 14., 38., 56., 9., 5., 1., 14., 10., 33., 11., 41., 8., 41., 10., 16., 2., 3., 0., 1., 0., 34., 3., 20., 5., 23., 6., 16., 3., 2., 2., 1., 0., 1., 3., 9., 2., 4., 1., 6., 1., 2., 1., 133., 7., 1900., 87., 92., 224., 108., 102., 71., 14., 17., 15., 17., 0., 0., 8., 7., 5., 12. [...]
+
+12., 1., 4., 8., 26., 4., 29., 0., 12., 177., 3., 30., 208., 4., 20., 8., 0., 8., 75., 3., 16., 291., 46., 338., 54., 20., 1., 3., 9., 4., 39., 37., 228., 38., 13., 159., 15., 37., 4., 0., 1., 9., 9., 76., 22., 99., 16., 39., 45., 9., 1., 2., 30., 6., 40., 8., 66., 11., 34., 4., 6., 10., 1., 0., 0., 0., 17., 3., 14., 1., 26., 4., 14., 4., 2., 1., 2., 2., 1., 0., 8., 3., 7., 0., 6., 3., 0., 0., 157., 7., 1873., 90., 109., 212., 97., 111., 64., 17., 12., 12., 16., 0., 3., 9., 5., 8., 12.,  [...]
+
+14., 1., 3., 8., 18., 7., 39., 2., 23., 128., 5., 22., 200., 4., 13., 7., 0., 7., 94., 3., 19., 288., 35., 335., 41., 19., 0., 2., 8., 5., 42., 28., 219., 45., 8., 180., 10., 36., 7., 0., 4., 15., 10., 77., 21., 82., 15., 32., 43., 13., 0., 2., 24., 4., 38., 14., 57., 16., 33., 4., 9., 9., 2., 0., 0., 0., 23., 4., 12., 2., 23., 6., 15., 4., 0., 6., 2., 2., 6., 1., 13., 4., 4., 4., 9., 1., 0., 2., 154., 9., 1876., 81., 94., 214., 99., 104., 53., 16., 13., 11., 9., 1., 0., 2., 8., 3., 7.,  [...]
+
+10., 0., 2., 1., 11., 4., 8., 3., 3., 27., 0., 14., 32., 1., 8., 4., 0., 3., 17., 0., 6., 13., 10., 24., 24., 4., 2., 1., 2., 1., 9., 5., 30., 13., 2., 17., 3., 19., 4., 0., 1., 8., 3., 13., 14., 14., 38., 11., 20., 13., 6., 4., 7., 5., 11., 1., 10., 6., 10., 19., 6., 25., 14., 5., 0., 1., 4., 1., 2., 2., 4., 3., 7., 3., 1., 4., 1., 3., 1., 4., 2., 0., 1., 1., 1., 7., 3., 6., 1., 2., 4., 1., 2., 0., 2., 8., 1., 0., 6., 2., 2., 2., 2., 2., 4., 1., 3., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0 [...]
+
+8., 2., 1., 3., 11., 5., 7., 2., 5., 13., 1., 19., 24., 2., 13., 3., 1., 1., 13., 0., 3., 22., 9., 30., 20., 5., 0., 1., 2., 3., 5., 8., 27., 17., 8., 15., 9., 13., 9., 3., 0., 5., 3., 9., 16., 25., 45., 17., 19., 5., 5., 2., 1., 2., 2., 2., 7., 9., 7., 16., 7., 19., 7., 3., 1., 1., 7., 4., 0., 1., 6., 6., 2., 1., 2., 6., 4., 4., 0., 0., 2., 0., 2., 1., 2., 9., 3., 3., 4., 0., 4., 0., 2., 0., 2., 6., 0., 0., 1., 3., 1., 1., 0., 3., 2., 3., 2., 0., 0., 0., 0., 4., 0., 0., 1., 0., 0., 0.,  [...]
+
+2., 3., 1., 4., 5., 4., 6., 1., 6., 23., 2., 20., 20., 1., 23., 5., 3., 2., 18., 1., 4., 31., 13., 16., 27., 8., 0., 0., 1., 2., 9., 14., 26., 16., 1., 14., 6., 18., 7., 1., 0., 5., 3., 6., 7., 12., 45., 12., 21., 10., 3., 0., 7., 2., 12., 4., 7., 4., 5., 15., 7., 31., 8., 3., 1., 0., 17., 1., 4., 1., 6., 0., 4., 3., 5., 4., 5., 2., 0., 1., 1., 0., 3., 2., 1., 11., 1., 2., 1., 0., 2., 0., 2., 0., 1., 5., 2., 0., 3., 2., 1., 4., 2., 0., 4., 0., 3., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0.,  [...]
+
+6., 0., 0., 3., 8., 3., 1., 1., 5., 22., 1., 18., 14., 0., 17., 0., 0., 0., 17., 2., 5., 30., 6., 19., 23., 11., 0., 1., 2., 3., 9., 7., 17., 14., 6., 24., 6., 16., 10., 2., 0., 4., 2., 10., 12., 26., 53., 12., 21., 6., 5., 1., 6., 3., 6., 2., 5., 3., 7., 20., 3., 20., 12., 1., 0., 1., 9., 1., 1., 5., 6., 3., 1., 7., 2., 2., 4., 1., 1., 0., 0., 0., 3., 2., 5., 8., 0., 4., 5., 4., 1., 0., 2., 2., 2., 11., 3., 0., 1., 1., 3., 3., 2., 5., 2., 1., 0., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0.,  [...]
+
+3., 0., 1., 8., 5., 3., 4., 2., 2., 22., 1., 18., 11., 1., 14., 4., 3., 2., 27., 5., 6., 15., 11., 18., 21., 5., 2., 0., 4., 0., 6., 2., 17., 18., 2., 15., 3., 12., 7., 1., 1., 3., 1., 15., 13., 19., 41., 10., 17., 5., 2., 0., 5., 3., 3., 2., 9., 7., 11., 14., 8., 29., 9., 3., 1., 0., 2., 0., 5., 1., 2., 3., 1., 6., 4., 1., 4., 2., 0., 2., 3., 0., 3., 1., 1., 9., 5., 11., 2., 1., 1., 0., 4., 1., 5., 9., 1., 0., 2., 1., 1., 0., 4., 2., 1., 0., 2., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., 0 [...]
+
+7., 0., 2., 2., 11., 2., 3., 0., 4., 23., 0., 17., 20., 2., 14., 2., 3., 0., 19., 1., 3., 28., 15., 23., 41., 4., 1., 0., 1., 2., 9., 8., 25., 16., 3., 7., 6., 11., 3., 4., 1., 7., 1., 10., 15., 25., 32., 15., 22., 12., 3., 2., 3., 1., 2., 1., 6., 8., 8., 15., 8., 15., 7., 6., 0., 1., 6., 1., 2., 0., 3., 3., 6., 3., 1., 5., 2., 2., 0., 2., 1., 0., 3., 1., 1., 9., 2., 6., 1., 1., 2., 1., 4., 0., 3., 7., 3., 0., 2., 2., 1., 0., 2., 3., 1., 1., 3., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0. [...]
+
+6., 0., 0., 4., 9., 2., 12., 1., 5., 28., 2., 11., 24., 2., 12., 3., 2., 5., 19., 5., 3., 25., 13., 42., 21., 6., 3., 1., 3., 2., 7., 5., 21., 13., 5., 13., 4., 14., 7., 4., 0., 6., 2., 9., 10., 18., 27., 13., 29., 13., 5., 0., 8., 0., 6., 5., 12., 11., 10., 20., 2., 19., 4., 2., 0., 1., 4., 2., 6., 1., 3., 5., 3., 3., 3., 5., 2., 0., 3., 3., 1., 0., 1., 1., 1., 4., 2., 2., 4., 3., 3., 2., 1., 1., 4., 7., 1., 0., 5., 3., 3., 1., 1., 0., 2., 0., 1., 0., 0., 0., 0., 4., 0., 0., 4., 0., 0., [...]
+
+14., 0., 1., 8., 7., 3., 3., 2., 2., 22., 4., 9., 15., 1., 21., 4., 0., 3., 16., 2., 2., 34., 18., 33., 21., 4., 1., 0., 1., 2., 4., 3., 32., 18., 4., 19., 4., 14., 8., 4., 0., 6., 1., 6., 10., 18., 37., 7., 13., 11., 7., 1., 4., 2., 7., 1., 3., 9., 8., 15., 8., 23., 8., 3., 0., 1., 8., 3., 3., 0., 7., 6., 6., 2., 3., 3., 2., 3., 2., 2., 3., 0., 1., 2., 4., 6., 4., 2., 4., 3., 9., 2., 4., 1., 4., 8., 4., 0., 2., 1., 2., 3., 2., 3., 0., 2., 2., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0.,  [...]
+
+6., 1., 3., 6., 5., 2., 5., 0., 5., 29., 0., 13., 16., 0., 16., 7., 1., 2., 16., 2., 7., 29., 12., 34., 24., 6., 1., 0., 4., 6., 6., 8., 24., 13., 4., 20., 5., 8., 10., 2., 1., 3., 1., 17., 10., 24., 57., 7., 22., 9., 6., 3., 5., 1., 7., 4., 8., 6., 8., 15., 0., 25., 10., 5., 2., 1., 5., 0., 3., 4., 5., 1., 5., 3., 3., 5., 4., 2., 1., 2., 1., 0., 4., 3., 3., 7., 1., 4., 2., 3., 5., 2., 3., 2., 4., 11., 1., 0., 4., 1., 2., 5., 2., 2., 2., 2., 2., 0., 0., 0., 0., 2., 0., 0., 4., 0., 0., 0. [...]
+
+11., 0., 2., 5., 9., 0., 6., 0., 3., 24., 0., 19., 27., 1., 8., 5., 0., 2., 13., 2., 7., 23., 17., 16., 21., 5., 0., 0., 1., 0., 7., 4., 28., 12., 6., 26., 6., 10., 8., 2., 1., 0., 3., 8., 8., 26., 33., 13., 17., 7., 6., 0., 3., 2., 5., 2., 4., 7., 8., 14., 6., 19., 8., 2., 0., 1., 4., 2., 2., 2., 6., 3., 0., 9., 5., 2., 2., 3., 1., 0., 0., 0., 2., 3., 3., 3., 0., 1., 2., 2., 4., 1., 1., 2., 2., 7., 4., 0., 0., 4., 3., 2., 2., 4., 2., 1., 3., 0., 0., 0., 0., 3., 0., 0., 4., 0., 0., 0., 3 [...]
+
+11., 0., 0., 6., 6., 2., 5., 0., 5., 28., 0., 11., 32., 1., 20., 4., 0., 1., 20., 3., 6., 35., 12., 25., 27., 8., 0., 1., 3., 1., 9., 4., 15., 13., 3., 26., 0., 12., 6., 1., 2., 6., 4., 7., 14., 19., 44., 18., 27., 2., 5., 1., 8., 0., 6., 2., 8., 8., 6., 18., 6., 27., 5., 3., 0., 3., 8., 0., 4., 1., 4., 1., 2., 2., 1., 4., 0., 3., 0., 0., 3., 0., 1., 2., 1., 9., 3., 4., 0., 2., 5., 1., 4., 0., 3., 7., 0., 0., 3., 4., 0., 1., 1., 0., 3., 1., 3., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0., [...]
+
+6., 0., 1., 5., 7., 9., 4., 0., 8., 7., 0., 15., 19., 1., 12., 2., 1., 2., 41., 2., 4., 19., 16., 40., 18., 7., 0., 2., 4., 0., 11., 8., 21., 13., 3., 11., 5., 15., 9., 1., 1., 6., 2., 10., 12., 11., 41., 10., 18., 9., 4., 2., 6., 4., 10., 3., 16., 4., 12., 24., 4., 18., 11., 3., 1., 1., 5., 2., 5., 3., 6., 6., 2., 5., 0., 4., 4., 4., 0., 3., 2., 0., 0., 2., 2., 2., 1., 5., 2., 2., 5., 0., 2., 0., 2., 6., 0., 0., 4., 2., 2., 3., 3., 4., 3., 0., 0., 0., 0., 0., 0., 4., 0., 0., 5., 0., 0., [...]
+
+4., 2., 0., 2., 3., 1., 2., 1., 4., 18., 0., 11., 19., 1., 21., 6., 2., 0., 15., 3., 5., 28., 9., 25., 32., 6., 0., 3., 4., 2., 5., 7., 24., 16., 3., 15., 6., 15., 7., 0., 4., 7., 1., 16., 11., 10., 44., 12., 16., 2., 4., 1., 5., 0., 4., 7., 10., 9., 7., 12., 4., 15., 7., 2., 2., 2., 5., 2., 1., 4., 7., 3., 2., 9., 1., 6., 5., 2., 1., 2., 2., 0., 0., 2., 3., 7., 4., 6., 1., 2., 0., 1., 2., 2., 1., 6., 2., 0., 4., 2., 2., 4., 4., 1., 2., 1., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., [...]
+
+7., 1., 1., 4., 7., 2., 8., 2., 6., 31., 0., 15., 23., 1., 10., 6., 0., 1., 24., 0., 4., 26., 16., 27., 23., 6., 0., 0., 4., 1., 13., 14., 24., 17., 2., 17., 1., 15., 8., 4., 1., 6., 0., 18., 5., 12., 36., 14., 29., 5., 4., 0., 10., 2., 6., 4., 13., 2., 11., 22., 4., 21., 9., 4., 2., 1., 4., 1., 4., 2., 5., 3., 3., 3., 1., 1., 5., 2., 1., 0., 2., 0., 2., 1., 3., 8., 2., 6., 5., 4., 1., 0., 4., 0., 2., 10., 3., 0., 1., 3., 0., 1., 1., 5., 2., 0., 3., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0. [...]
+
+5., 1., 1., 4., 9., 2., 6., 1., 4., 14., 1., 19., 17., 2., 6., 3., 0., 0., 12., 1., 3., 17., 12., 25., 18., 5., 0., 2., 1., 1., 5., 5., 28., 22., 2., 17., 8., 11., 9., 0., 0., 5., 1., 14., 16., 14., 46., 8., 16., 5., 3., 2., 4., 2., 6., 6., 14., 5., 8., 19., 9., 26., 7., 3., 1., 2., 8., 1., 0., 1., 7., 2., 3., 7., 2., 3., 2., 3., 1., 2., 0., 0., 1., 4., 4., 11., 2., 1., 2., 4., 5., 4., 2., 1., 1., 13., 5., 0., 3., 3., 4., 4., 2., 0., 0., 2., 2., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0. [...]
+
+1., 0., 3., 3., 5., 5., 6., 1., 3., 23., 0., 13., 22., 0., 17., 4., 0., 0., 19., 0., 4., 14., 9., 23., 34., 3., 1., 0., 6., 3., 11., 5., 30., 17., 1., 7., 2., 16., 14., 3., 0., 6., 3., 11., 6., 20., 48., 14., 11., 10., 7., 0., 5., 5., 6., 1., 10., 4., 7., 12., 5., 20., 13., 4., 1., 1., 9., 1., 2., 1., 5., 4., 4., 3., 1., 6., 0., 2., 1., 1., 3., 0., 1., 4., 4., 5., 3., 6., 2., 3., 2., 1., 1., 0., 2., 10., 1., 0., 5., 2., 2., 2., 2., 6., 4., 1., 5., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0.,  [...]
+
+2., 1., 5., 4., 10., 3., 6., 0., 4., 26., 3., 16., 20., 0., 15., 2., 1., 2., 9., 1., 8., 24., 10., 22., 17., 3., 1., 2., 2., 1., 10., 11., 16., 12., 3., 21., 4., 11., 14., 0., 2., 4., 2., 15., 14., 21., 54., 12., 21., 6., 4., 1., 2., 2., 4., 5., 11., 10., 10., 21., 8., 21., 10., 4., 1., 0., 8., 0., 3., 1., 4., 4., 5., 4., 1., 3., 4., 1., 2., 1., 1., 0., 5., 3., 0., 9., 3., 4., 2., 5., 1., 0., 5., 2., 1., 7., 1., 0., 0., 2., 0., 2., 1., 0., 2., 1., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0.,  [...]
+
+8., 2., 0., 6., 16., 2., 9., 0., 10., 20., 0., 10., 17., 1., 13., 5., 2., 4., 17., 2., 5., 24., 12., 24., 25., 9., 0., 2., 1., 3., 9., 8., 30., 15., 4., 16., 3., 11., 7., 3., 2., 4., 2., 14., 11., 18., 40., 13., 24., 10., 3., 1., 5., 1., 10., 3., 12., 7., 9., 16., 11., 17., 9., 3., 3., 0., 4., 2., 6., 2., 6., 3., 1., 8., 3., 5., 1., 1., 1., 2., 2., 0., 2., 6., 0., 7., 3., 6., 4., 2., 5., 0., 3., 1., 1., 9., 1., 0., 2., 2., 0., 2., 1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 3., 0., 0 [...]
+
+4., 2., 1., 1., 6., 1., 2., 0., 3., 10., 2., 21., 25., 0., 13., 3., 1., 2., 19., 2., 3., 32., 18., 22., 29., 5., 0., 2., 8., 3., 7., 8., 32., 14., 2., 19., 3., 16., 12., 2., 1., 7., 0., 9., 14., 11., 47., 13., 12., 9., 5., 1., 7., 1., 3., 5., 9., 5., 6., 20., 3., 13., 7., 2., 0., 2., 10., 0., 2., 2., 2., 4., 3., 2., 2., 6., 2., 3., 0., 2., 2., 0., 2., 3., 2., 4., 2., 3., 3., 0., 5., 1., 3., 1., 8., 6., 3., 0., 2., 2., 1., 3., 2., 1., 3., 2., 4., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0. [...]
+
+4., 0., 0., 7., 8., 4., 9., 2., 5., 23., 1., 18., 29., 0., 10., 1., 0., 0., 8., 2., 7., 15., 16., 31., 34., 3., 0., 1., 4., 3., 5., 6., 13., 20., 0., 15., 7., 20., 13., 3., 0., 2., 3., 20., 9., 18., 37., 14., 22., 10., 3., 1., 7., 5., 6., 2., 12., 9., 8., 12., 4., 23., 11., 3., 0., 1., 6., 1., 4., 2., 5., 0., 4., 3., 1., 4., 1., 3., 2., 2., 2., 0., 1., 1., 1., 8., 1., 2., 3., 3., 4., 1., 2., 2., 2., 3., 1., 0., 4., 2., 2., 1., 2., 1., 3., 0., 4., 0., 0., 0., 0., 3., 0., 0., 4., 0., 0., 0 [...]
+
+9., 0., 2., 5., 6., 0., 14., 2., 6., 60., 1., 13., 50., 1., 4., 2., 0., 1., 76., 10., 5., 84., 11., 83., 9., 3., 0., 1., 1., 3., 13., 6., 46., 11., 1., 51., 22., 14., 3., 0., 1., 13., 1., 27., 5., 16., 11., 13., 7., 3., 1., 0., 7., 3., 10., 7., 18., 4., 7., 2., 0., 36., 5., 9., 2., 0., 21., 4., 5., 1., 6., 1., 4., 0., 0., 1., 0., 3., 4., 13., 12., 1., 6., 0., 1., 0., 0., 0., 0., 0., 8., 3., 3., 1., 2., 3., 1., 0., 4., 0., 0., 0., 0., 4., 0., 0., 1., 0., 2., 0., 1., 0., 0., 0., 0., 0., 3. [...]
+
+6., 0., 4., 2., 11., 0., 6., 3., 8., 48., 0., 5., 63., 1., 3., 3., 0., 1., 63., 3., 2., 82., 15., 74., 15., 1., 0., 1., 3., 2., 8., 11., 44., 14., 2., 40., 38., 20., 6., 0., 0., 7., 4., 20., 0., 30., 9., 15., 10., 4., 5., 0., 8., 4., 19., 7., 9., 4., 8., 1., 2., 39., 8., 10., 1., 0., 18., 2., 5., 0., 5., 3., 2., 0., 1., 1., 0., 5., 0., 13., 5., 3., 2., 0., 1., 0., 0., 0., 0., 0., 4., 2., 4., 0., 3., 1., 0., 0., 1., 0., 1., 0., 1., 3., 1., 0., 1., 0., 0., 0., 1., 0., 0., 0., 1., 0., 5., 0 [...]
+
+10., 1., 2., 16., 16., 3., 38., 3., 16., 162., 3., 19., 229., 4., 13., 9., 0., 6., 94., 1., 15., 262., 53., 305., 45., 13., 0., 6., 6., 4., 55., 37., 227., 35., 2., 139., 12., 35., 11., 0., 0., 11., 14., 69., 22., 95., 15., 30., 33., 14., 2., 2., 26., 12., 48., 14., 59., 5., 29., 9., 8., 8., 2., 0., 0., 0., 20., 2., 9., 4., 32., 4., 15., 7., 3., 3., 3., 1., 2., 0., 8., 6., 8., 4., 8., 1., 2., 5., 179., 7., 1907., 98., 96., 241., 107., 105., 88., 16., 14., 21., 14., 0., 3., 6., 2., 3., 10 [...]
+
+20., 2., 2., 6., 26., 5., 37., 0., 19., 160., 1., 28., 222., 6., 19., 8., 1., 8., 85., 0., 9., 255., 53., 349., 39., 15., 0., 2., 4., 10., 44., 29., 252., 36., 7., 163., 13., 40., 6., 0., 0., 15., 8., 83., 19., 83., 20., 41., 43., 12., 6., 1., 18., 9., 34., 10., 64., 9., 22., 8., 10., 9., 2., 0., 2., 0., 26., 1., 19., 2., 29., 4., 11., 6., 1., 2., 0., 1., 0., 3., 4., 5., 9., 2., 5., 0., 0., 7., 148., 11., 1946., 97., 106., 236., 95., 111., 60., 22., 10., 18., 13., 0., 0., 11., 7., 0., 16 [...]
+
+10., 0., 1., 9., 34., 3., 35., 0., 19., 146., 3., 24., 222., 11., 24., 3., 0., 4., 67., 1., 23., 267., 53., 323., 38., 21., 2., 2., 8., 5., 50., 26., 241., 37., 8., 135., 15., 42., 3., 0., 3., 14., 7., 77., 21., 85., 14., 32., 65., 9., 5., 2., 30., 5., 39., 14., 43., 12., 36., 6., 6., 10., 5., 0., 0., 0., 22., 4., 14., 2., 22., 5., 10., 4., 1., 3., 1., 1., 0., 3., 10., 2., 8., 1., 10., 2., 0., 5., 123., 7., 1876., 87., 104., 226., 73., 111., 68., 12., 16., 23., 21., 1., 1., 8., 3., 3., 8 [...]
+
+10., 2., 3., 9., 26., 4., 37., 0., 17., 144., 1., 24., 214., 7., 16., 8., 1., 7., 82., 2., 23., 302., 38., 340., 41., 16., 1., 3., 7., 4., 51., 24., 223., 45., 11., 141., 16., 33., 5., 0., 1., 17., 6., 77., 16., 95., 9., 40., 49., 11., 3., 1., 24., 4., 37., 3., 43., 7., 25., 4., 18., 2., 1., 0., 0., 0., 17., 7., 11., 4., 31., 2., 6., 6., 1., 2., 0., 1., 2., 1., 14., 8., 9., 0., 6., 1., 1., 4., 143., 13., 1888., 96., 86., 229., 95., 106., 58., 17., 11., 15., 7., 0., 1., 2., 2., 8., 3., 3. [...]
+
+10., 0., 2., 5., 32., 7., 28., 1., 20., 149., 5., 32., 166., 3., 13., 8., 1., 2., 89., 1., 17., 288., 45., 333., 44., 22., 0., 2., 5., 2., 44., 36., 254., 47., 2., 151., 17., 43., 9., 0., 1., 24., 9., 90., 16., 82., 14., 38., 51., 15., 3., 0., 33., 7., 37., 10., 51., 10., 42., 6., 20., 4., 2., 0., 0., 0., 24., 2., 10., 6., 26., 4., 11., 5., 1., 2., 1., 0., 3., 2., 18., 4., 6., 3., 13., 1., 0., 4., 140., 4., 1958., 76., 103., 215., 100., 105., 80., 11., 11., 18., 21., 2., 3., 9., 3., 3.,  [...]
+
+13., 1., 3., 10., 21., 6., 37., 0., 16., 152., 4., 34., 190., 4., 20., 7., 0., 4., 88., 1., 14., 276., 37., 338., 34., 10., 2., 5., 8., 6., 48., 35., 248., 40., 6., 159., 16., 48., 11., 0., 0., 23., 6., 70., 17., 76., 16., 39., 37., 15., 3., 0., 29., 10., 34., 9., 46., 7., 29., 7., 5., 8., 4., 0., 1., 0., 34., 9., 19., 2., 29., 0., 13., 8., 4., 2., 2., 2., 4., 0., 13., 3., 10., 3., 10., 1., 0., 6., 138., 6., 1895., 81., 81., 240., 97., 109., 54., 11., 19., 22., 10., 0., 1., 5., 5., 1., 1 [...]
+
+17., 3., 2., 9., 22., 5., 25., 1., 9., 179., 2., 30., 209., 5., 11., 5., 3., 3., 76., 0., 16., 285., 34., 352., 51., 11., 2., 3., 2., 6., 42., 34., 221., 42., 12., 148., 11., 36., 7., 0., 6., 13., 8., 80., 15., 85., 12., 42., 33., 14., 3., 3., 22., 4., 32., 8., 33., 9., 34., 10., 13., 6., 1., 0., 2., 0., 28., 4., 12., 2., 30., 2., 8., 5., 3., 3., 1., 2., 1., 0., 11., 5., 8., 1., 7., 2., 2., 2., 159., 8., 1923., 80., 85., 240., 91., 112., 77., 20., 15., 23., 8., 2., 1., 5., 3., 7., 4., 10 [...]
+
+16., 4., 8., 10., 26., 3., 29., 1., 16., 190., 5., 33., 210., 6., 10., 4., 0., 2., 84., 3., 19., 288., 47., 334., 38., 15., 2., 3., 3., 8., 40., 37., 233., 46., 5., 129., 9., 36., 9., 0., 2., 20., 3., 69., 13., 110., 20., 27., 48., 8., 0., 0., 20., 7., 31., 6., 53., 9., 34., 8., 13., 13., 0., 0., 0., 0., 29., 5., 16., 3., 26., 2., 16., 3., 2., 5., 1., 2., 1., 1., 11., 5., 5., 1., 7., 0., 0., 4., 137., 10., 1930., 91., 77., 232., 97., 118., 85., 10., 14., 15., 10., 3., 0., 8., 1., 5., 7., [...]
+
+21., 0., 3., 11., 25., 4., 43., 0., 18., 152., 3., 26., 238., 6., 6., 7., 0., 6., 77., 5., 16., 309., 40., 298., 36., 10., 1., 1., 3., 6., 42., 13., 215., 26., 6., 151., 20., 45., 8., 0., 1., 14., 4., 74., 17., 103., 18., 36., 46., 9., 2., 1., 22., 9., 36., 9., 35., 4., 33., 4., 11., 7., 3., 0., 1., 0., 19., 5., 11., 4., 27., 4., 10., 6., 2., 2., 2., 0., 2., 0., 8., 2., 13., 1., 7., 1., 2., 1., 131., 7., 1965., 71., 104., 237., 95., 93., 57., 15., 17., 16., 19., 1., 2., 5., 6., 4., 9., 8 [...]
+
+7., 1., 0., 3., 13., 4., 6., 0., 8., 21., 0., 21., 13., 1., 26., 3., 0., 2., 15., 5., 3., 28., 15., 38., 30., 5., 0., 1., 4., 2., 6., 13., 17., 16., 6., 25., 5., 14., 14., 1., 3., 5., 1., 11., 11., 28., 47., 15., 13., 10., 3., 1., 10., 1., 9., 4., 14., 3., 7., 19., 6., 19., 7., 5., 1., 0., 7., 0., 2., 1., 4., 3., 5., 3., 1., 13., 1., 2., 2., 1., 1., 0., 2., 3., 0., 6., 2., 3., 1., 3., 1., 1., 1., 1., 0., 5., 2., 0., 2., 2., 6., 1., 1., 0., 2., 0., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0.,  [...]
+
+7., 0., 0., 7., 11., 1., 8., 2., 11., 28., 1., 7., 18., 2., 15., 1., 0., 2., 24., 2., 5., 25., 14., 19., 24., 8., 1., 0., 0., 1., 10., 9., 25., 11., 1., 7., 5., 23., 6., 2., 2., 4., 1., 12., 15., 6., 43., 6., 20., 10., 5., 1., 6., 1., 10., 2., 10., 2., 8., 15., 8., 24., 9., 2., 0., 2., 8., 3., 2., 1., 2., 3., 4., 3., 2., 1., 1., 3., 2., 0., 3., 0., 5., 2., 5., 4., 1., 6., 4., 2., 3., 3., 3., 1., 2., 5., 4., 0., 3., 0., 4., 1., 0., 0., 6., 1., 4., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0 [...]
+
+1., 1., 3., 3., 4., 1., 3., 0., 3., 13., 1., 11., 20., 0., 14., 5., 0., 1., 23., 3., 1., 21., 13., 24., 27., 4., 1., 0., 4., 1., 12., 8., 20., 27., 4., 19., 6., 15., 9., 2., 2., 5., 5., 14., 10., 10., 43., 14., 21., 9., 4., 1., 3., 2., 5., 3., 16., 9., 14., 15., 7., 17., 7., 2., 0., 1., 7., 3., 5., 1., 5., 2., 5., 2., 1., 3., 3., 4., 1., 4., 3., 0., 2., 2., 2., 6., 2., 5., 1., 1., 3., 0., 1., 2., 2., 6., 1., 0., 1., 3., 1., 1., 5., 1., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0.,  [...]
+
+17., 2., 3., 4., 5., 3., 5., 2., 1., 22., 1., 16., 16., 3., 19., 1., 0., 1., 4., 3., 3., 31., 13., 19., 30., 9., 3., 0., 4., 3., 6., 0., 24., 16., 1., 14., 6., 14., 6., 2., 1., 4., 3., 14., 12., 15., 41., 15., 27., 8., 3., 1., 6., 2., 4., 2., 12., 5., 4., 12., 11., 25., 13., 3., 3., 0., 7., 2., 4., 2., 0., 2., 4., 6., 1., 2., 4., 2., 2., 2., 4., 0., 3., 0., 0., 4., 4., 1., 0., 4., 4., 1., 4., 1., 1., 7., 3., 0., 2., 1., 3., 5., 0., 3., 2., 1., 3., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0.,  [...]
+
+11., 1., 0., 3., 6., 4., 13., 1., 9., 18., 0., 13., 15., 3., 11., 5., 0., 2., 29., 0., 1., 24., 11., 31., 24., 7., 1., 0., 3., 2., 6., 12., 19., 9., 2., 20., 3., 11., 10., 1., 1., 2., 3., 12., 11., 17., 37., 11., 15., 10., 1., 2., 2., 1., 13., 1., 5., 4., 4., 15., 3., 24., 4., 3., 1., 2., 5., 1., 1., 1., 3., 2., 4., 2., 1., 5., 0., 3., 1., 3., 6., 0., 1., 0., 3., 7., 3., 4., 2., 0., 2., 0., 0., 0., 1., 3., 6., 0., 1., 4., 2., 3., 1., 0., 4., 1., 3., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0. [...]
+
+10., 2., 2., 1., 13., 1., 8., 0., 6., 24., 1., 15., 32., 1., 19., 6., 0., 1., 14., 4., 4., 21., 9., 32., 32., 5., 2., 0., 5., 0., 3., 8., 31., 12., 3., 21., 2., 9., 13., 3., 2., 3., 2., 16., 16., 18., 52., 13., 19., 11., 1., 0., 4., 2., 5., 2., 11., 8., 8., 10., 3., 22., 6., 4., 0., 0., 5., 1., 2., 3., 2., 4., 2., 4., 0., 3., 3., 1., 0., 0., 3., 0., 2., 2., 1., 7., 0., 1., 1., 3., 6., 1., 2., 2., 1., 8., 3., 0., 2., 0., 3., 3., 1., 1., 2., 0., 1., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0.,  [...]
+
+7., 0., 6., 6., 8., 2., 4., 1., 6., 37., 2., 13., 8., 1., 13., 2., 0., 0., 13., 0., 4., 28., 11., 21., 28., 2., 1., 0., 4., 2., 4., 9., 23., 23., 1., 12., 7., 13., 6., 7., 2., 5., 1., 14., 12., 12., 39., 15., 16., 11., 3., 1., 3., 2., 3., 1., 11., 4., 3., 25., 6., 17., 3., 2., 0., 1., 6., 0., 3., 1., 5., 4., 1., 8., 1., 2., 4., 0., 1., 1., 2., 0., 2., 5., 3., 7., 1., 5., 1., 1., 1., 2., 1., 1., 2., 7., 3., 0., 4., 1., 1., 2., 1., 5., 1., 1., 2., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0. [...]
+
+5., 0., 3., 3., 7., 5., 6., 1., 10., 25., 1., 9., 24., 0., 18., 0., 3., 0., 17., 2., 4., 24., 15., 25., 25., 3., 0., 0., 3., 4., 5., 6., 21., 22., 8., 17., 4., 12., 12., 0., 1., 6., 1., 8., 5., 16., 47., 10., 20., 8., 5., 0., 5., 1., 8., 1., 9., 4., 11., 26., 8., 25., 11., 7., 4., 0., 5., 3., 6., 1., 5., 6., 4., 6., 1., 5., 1., 3., 2., 2., 2., 0., 3., 2., 0., 6., 5., 4., 2., 5., 5., 0., 1., 4., 1., 8., 1., 0., 1., 4., 4., 2., 2., 2., 1., 3., 0., 0., 0., 0., 0., 2., 0., 0., 4., 0., 0., 0. [...]
+
+15., 2., 4., 2., 4., 1., 12., 1., 6., 18., 1., 9., 22., 2., 15., 2., 2., 2., 4., 6., 3., 28., 7., 21., 33., 2., 1., 0., 2., 2., 6., 6., 24., 20., 2., 13., 3., 14., 6., 1., 0., 6., 5., 8., 9., 15., 47., 11., 21., 8., 5., 2., 10., 2., 6., 2., 8., 4., 11., 9., 5., 27., 11., 3., 0., 1., 6., 2., 6., 1., 8., 1., 3., 6., 5., 2., 3., 3., 2., 0., 4., 0., 1., 4., 2., 2., 0., 5., 1., 1., 8., 0., 5., 2., 0., 12., 1., 0., 1., 5., 0., 2., 1., 2., 6., 0., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0., [...]
+
+5., 1., 1., 5., 9., 4., 4., 1., 6., 28., 3., 12., 20., 1., 13., 3., 1., 1., 10., 6., 3., 22., 10., 27., 32., 9., 0., 2., 2., 2., 8., 3., 14., 18., 3., 18., 3., 11., 9., 5., 0., 2., 4., 11., 11., 15., 41., 13., 21., 5., 4., 0., 8., 2., 6., 4., 9., 3., 7., 16., 5., 10., 4., 2., 4., 1., 11., 0., 4., 4., 7., 2., 5., 4., 1., 8., 2., 1., 1., 2., 6., 0., 3., 4., 1., 8., 3., 2., 5., 0., 5., 2., 2., 4., 2., 7., 3., 0., 3., 1., 0., 5., 2., 0., 3., 0., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+5., 1., 3., 3., 7., 4., 6., 1., 7., 8., 0., 9., 22., 2., 17., 2., 3., 3., 16., 1., 4., 28., 12., 36., 35., 6., 1., 2., 2., 1., 10., 3., 32., 15., 1., 13., 2., 13., 7., 4., 0., 7., 2., 8., 13., 23., 39., 13., 28., 11., 2., 0., 4., 2., 9., 2., 12., 9., 15., 7., 5., 30., 5., 6., 1., 0., 5., 1., 3., 1., 5., 4., 0., 7., 1., 5., 5., 2., 0., 1., 1., 0., 1., 4., 0., 4., 4., 0., 2., 2., 1., 1., 2., 1., 0., 5., 2., 0., 4., 3., 1., 2., 2., 1., 2., 2., 6., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0., [...]
+
+5., 2., 4., 1., 3., 2., 14., 0., 5., 21., 2., 15., 22., 1., 11., 2., 1., 1., 9., 0., 2., 35., 11., 29., 27., 4., 2., 1., 4., 1., 9., 6., 27., 12., 3., 12., 3., 10., 10., 3., 0., 3., 3., 18., 10., 11., 47., 4., 26., 13., 3., 2., 7., 0., 3., 6., 8., 7., 7., 10., 4., 24., 8., 6., 1., 1., 9., 0., 1., 0., 5., 3., 2., 5., 1., 3., 2., 3., 1., 1., 1., 0., 1., 1., 3., 5., 3., 6., 1., 1., 3., 2., 1., 1., 1., 10., 2., 0., 4., 4., 0., 1., 3., 1., 2., 3., 2., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0 [...]
+
+5., 2., 1., 6., 9., 4., 2., 1., 8., 28., 0., 10., 25., 2., 10., 1., 3., 2., 14., 3., 4., 27., 11., 29., 30., 5., 1., 1., 2., 3., 7., 7., 24., 12., 0., 9., 4., 11., 10., 0., 1., 6., 1., 12., 16., 17., 53., 10., 25., 8., 5., 1., 6., 3., 5., 2., 12., 9., 7., 26., 12., 18., 10., 4., 0., 0., 9., 0., 5., 0., 4., 3., 5., 4., 1., 3., 6., 1., 3., 3., 3., 0., 1., 2., 1., 5., 2., 1., 1., 2., 3., 0., 1., 1., 3., 3., 1., 0., 1., 2., 2., 0., 4., 1., 3., 3., 2., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0.,  [...]
+
+13., 0., 4., 3., 8., 2., 6., 1., 7., 21., 0., 10., 25., 0., 18., 4., 0., 3., 16., 4., 4., 22., 8., 23., 29., 10., 2., 2., 1., 2., 6., 3., 17., 14., 3., 18., 5., 17., 8., 0., 0., 5., 0., 17., 4., 12., 52., 12., 22., 7., 3., 0., 8., 2., 6., 4., 9., 5., 10., 19., 6., 25., 6., 2., 4., 0., 9., 1., 1., 1., 4., 4., 4., 0., 2., 7., 3., 5., 3., 4., 1., 0., 3., 0., 4., 5., 2., 3., 3., 2., 3., 0., 1., 1., 3., 6., 2., 0., 2., 0., 2., 2., 2., 4., 1., 0., 1., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., 0. [...]
+
+6., 0., 5., 5., 9., 3., 8., 1., 7., 10., 1., 15., 36., 0., 14., 0., 1., 1., 9., 1., 4., 40., 10., 31., 20., 4., 1., 1., 6., 2., 8., 6., 15., 18., 3., 17., 3., 15., 8., 2., 0., 4., 2., 10., 9., 14., 44., 11., 15., 8., 6., 2., 2., 1., 9., 2., 8., 7., 12., 14., 8., 20., 10., 1., 0., 2., 4., 2., 5., 0., 8., 7., 1., 4., 1., 6., 2., 2., 0., 1., 2., 0., 2., 2., 2., 8., 2., 4., 1., 1., 4., 0., 0., 2., 3., 7., 1., 0., 2., 2., 3., 1., 0., 2., 1., 0., 2., 0., 0., 0., 0., 6., 0., 0., 2., 0., 0., 0., [...]
+
+3., 0., 1., 5., 7., 2., 5., 1., 4., 30., 2., 14., 12., 1., 11., 6., 3., 2., 15., 3., 4., 28., 14., 27., 26., 13., 3., 2., 1., 2., 11., 7., 23., 17., 0., 10., 3., 13., 11., 2., 0., 3., 3., 11., 11., 15., 50., 12., 24., 7., 4., 2., 3., 2., 7., 4., 11., 2., 5., 18., 7., 25., 16., 2., 2., 1., 6., 0., 5., 1., 6., 1., 3., 4., 3., 9., 3., 3., 0., 1., 2., 0., 5., 1., 0., 4., 4., 5., 2., 0., 3., 1., 2., 1., 1., 7., 6., 0., 1., 2., 4., 0., 4., 5., 5., 0., 4., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0. [...]
+
+14., 1., 1., 5., 9., 5., 6., 1., 4., 30., 1., 12., 19., 0., 13., 0., 0., 1., 23., 4., 1., 30., 13., 24., 25., 8., 1., 1., 2., 4., 7., 5., 34., 20., 3., 11., 2., 8., 10., 1., 1., 7., 1., 7., 7., 18., 57., 14., 29., 8., 3., 1., 3., 3., 4., 3., 9., 4., 13., 15., 8., 17., 8., 5., 2., 1., 5., 0., 3., 0., 3., 2., 4., 9., 2., 6., 3., 1., 0., 1., 1., 0., 2., 3., 1., 5., 3., 6., 0., 0., 5., 1., 1., 0., 1., 8., 0., 0., 6., 3., 2., 3., 1., 1., 3., 0., 0., 0., 0., 0., 0., 3., 0., 0., 4., 0., 0., 0., [...]
+
+8., 2., 1., 6., 6., 0., 9., 3., 6., 14., 0., 11., 21., 1., 11., 2., 0., 2., 16., 1., 1., 16., 12., 21., 30., 9., 0., 1., 3., 1., 4., 4., 36., 19., 2., 14., 7., 16., 7., 3., 3., 2., 7., 11., 8., 21., 45., 12., 26., 5., 3., 1., 3., 2., 8., 0., 13., 5., 7., 19., 5., 12., 8., 5., 2., 1., 12., 1., 1., 3., 5., 1., 2., 3., 3., 4., 5., 0., 2., 3., 0., 0., 4., 6., 2., 4., 1., 4., 0., 4., 2., 2., 1., 1., 2., 6., 0., 0., 1., 1., 1., 1., 1., 3., 3., 1., 3., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0., 0. [...]
+
+12., 1., 4., 5., 3., 3., 5., 1., 6., 27., 0., 17., 25., 3., 15., 2., 1., 1., 12., 2., 5., 14., 11., 16., 21., 7., 2., 3., 4., 2., 4., 8., 22., 15., 2., 15., 2., 15., 8., 1., 1., 4., 1., 9., 15., 19., 45., 10., 26., 12., 3., 0., 5., 2., 2., 4., 4., 11., 4., 12., 3., 15., 6., 1., 1., 0., 9., 1., 2., 2., 10., 3., 2., 5., 1., 2., 4., 4., 1., 2., 1., 0., 2., 2., 2., 9., 1., 3., 2., 3., 5., 1., 4., 1., 4., 11., 1., 0., 3., 1., 2., 2., 3., 2., 1., 1., 3., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., [...]
+
+6., 2., 0., 6., 7., 1., 6., 1., 6., 4., 3., 15., 16., 2., 13., 0., 2., 3., 22., 2., 1., 29., 16., 17., 30., 5., 1., 1., 4., 1., 7., 7., 16., 11., 4., 17., 4., 23., 10., 2., 0., 3., 1., 10., 5., 18., 40., 13., 20., 6., 3., 1., 8., 2., 8., 3., 14., 7., 10., 17., 1., 21., 6., 3., 0., 1., 8., 2., 3., 2., 2., 4., 5., 2., 2., 7., 3., 0., 2., 0., 1., 0., 2., 5., 2., 5., 2., 5., 5., 4., 5., 1., 3., 2., 5., 10., 3., 0., 4., 3., 2., 1., 3., 5., 0., 1., 1., 0., 0., 0., 0., 5., 0., 0., 3., 0., 0., 0 [...]
+
+7., 0., 3., 0., 13., 3., 12., 2., 8., 16., 1., 13., 17., 0., 14., 4., 2., 4., 17., 3., 5., 24., 10., 28., 30., 4., 0., 3., 3., 2., 3., 6., 21., 14., 2., 14., 2., 11., 13., 2., 0., 5., 3., 12., 8., 17., 43., 13., 21., 7., 5., 1., 4., 2., 9., 7., 8., 10., 9., 15., 6., 27., 5., 2., 1., 0., 2., 1., 5., 0., 4., 3., 5., 6., 3., 5., 2., 1., 3., 0., 3., 0., 3., 2., 1., 5., 3., 7., 2., 3., 3., 0., 1., 2., 0., 5., 2., 0., 1., 4., 1., 3., 1., 2., 3., 0., 0., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0.,  [...]
+
+6., 1., 0., 3., 10., 0., 12., 3., 8., 51., 2., 3., 69., 0., 6., 2., 0., 0., 64., 9., 10., 60., 17., 67., 17., 3., 0., 2., 5., 0., 12., 10., 39., 13., 3., 47., 31., 15., 4., 0., 0., 8., 2., 26., 4., 22., 3., 13., 4., 4., 1., 0., 14., 6., 16., 2., 15., 3., 8., 3., 1., 41., 11., 5., 2., 0., 11., 2., 9., 2., 10., 0., 3., 3., 0., 1., 0., 5., 0., 10., 18., 4., 4., 1., 2., 0., 0., 0., 0., 0., 9., 1., 1., 3., 2., 2., 1., 0., 3., 0., 2., 0., 0., 3., 0., 0., 1., 0., 1., 0., 2., 0., 0., 0., 2., 0., [...]
+
+3., 2., 3., 5., 7., 0., 11., 2., 4., 69., 1., 5., 58., 0., 5., 0., 0., 1., 68., 7., 7., 70., 17., 93., 15., 3., 0., 2., 2., 1., 16., 9., 57., 14., 0., 41., 33., 17., 3., 0., 0., 4., 8., 12., 3., 29., 11., 18., 4., 2., 1., 0., 8., 2., 12., 5., 15., 3., 5., 4., 2., 38., 6., 6., 1., 0., 15., 2., 7., 3., 12., 3., 5., 2., 1., 2., 0., 5., 1., 11., 13., 1., 4., 0., 4., 0., 0., 0., 0., 0., 12., 4., 3., 4., 4., 2., 0., 0., 1., 0., 0., 0., 1., 3., 0., 0., 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1. [...]
+
+9., 2., 1., 11., 30., 6., 31., 0., 16., 170., 1., 25., 212., 3., 21., 10., 0., 4., 85., 3., 22., 260., 40., 314., 53., 18., 1., 3., 9., 2., 47., 37., 227., 36., 10., 169., 12., 39., 5., 0., 1., 16., 4., 78., 24., 84., 10., 38., 42., 20., 4., 0., 30., 8., 35., 9., 48., 9., 33., 8., 16., 5., 1., 0., 0., 0., 18., 4., 14., 4., 23., 5., 15., 4., 2., 0., 2., 0., 5., 1., 7., 2., 13., 3., 15., 0., 1., 8., 139., 7., 1838., 106., 99., 222., 105., 113., 72., 15., 7., 17., 11., 1., 1., 6., 2., 4., 9 [...]
+
+12., 2., 4., 8., 32., 5., 24., 0., 14., 136., 3., 24., 220., 5., 16., 8., 2., 5., 75., 3., 15., 290., 40., 345., 28., 15., 1., 1., 11., 8., 47., 34., 223., 33., 9., 181., 14., 49., 1., 0., 2., 15., 11., 63., 19., 77., 6., 41., 35., 5., 7., 1., 23., 10., 41., 11., 46., 13., 39., 2., 16., 3., 1., 0., 0., 0., 22., 3., 15., 2., 21., 5., 17., 6., 2., 4., 0., 0., 5., 1., 9., 3., 7., 2., 10., 0., 0., 5., 151., 10., 1794., 90., 102., 257., 84., 115., 57., 16., 12., 16., 9., 3., 3., 5., 6., 5., 1 [...]
+
+17., 7., 2., 13., 24., 3., 32., 2., 12., 168., 7., 24., 201., 6., 23., 6., 0., 0., 88., 3., 21., 287., 43., 323., 44., 16., 1., 2., 6., 7., 42., 31., 222., 37., 12., 175., 7., 42., 6., 0., 1., 13., 5., 97., 20., 81., 14., 33., 38., 17., 2., 0., 29., 4., 47., 10., 50., 5., 23., 7., 6., 6., 3., 0., 1., 0., 26., 4., 18., 5., 22., 7., 11., 4., 3., 2., 3., 1., 3., 1., 4., 6., 10., 3., 8., 0., 1., 5., 160., 9., 1830., 115., 90., 213., 78., 122., 60., 18., 12., 17., 14., 0., 1., 7., 4., 2., 6., [...]
+
+8., 1., 3., 5., 26., 5., 35., 0., 16., 162., 4., 37., 195., 2., 22., 4., 0., 5., 75., 3., 12., 248., 51., 318., 48., 21., 0., 3., 8., 2., 40., 39., 238., 45., 8., 154., 9., 54., 5., 0., 4., 15., 7., 63., 26., 99., 15., 39., 42., 14., 6., 1., 25., 6., 42., 11., 38., 10., 39., 6., 9., 11., 6., 0., 3., 0., 26., 6., 12., 2., 28., 7., 15., 4., 1., 5., 1., 0., 4., 3., 6., 2., 8., 1., 9., 2., 1., 2., 151., 11., 1926., 73., 105., 253., 81., 112., 72., 15., 12., 20., 7., 3., 3., 12., 3., 4., 15., [...]
+
+20., 0., 4., 7., 19., 10., 26., 0., 15., 165., 5., 27., 199., 1., 16., 12., 1., 5., 88., 4., 20., 294., 48., 332., 34., 18., 0., 1., 5., 6., 49., 30., 235., 28., 11., 168., 11., 45., 6., 0., 3., 14., 12., 61., 17., 91., 21., 44., 45., 10., 6., 1., 26., 4., 50., 12., 47., 11., 23., 7., 13., 7., 2., 0., 0., 0., 34., 2., 14., 3., 30., 3., 13., 3., 2., 2., 1., 0., 5., 4., 14., 3., 7., 3., 10., 1., 1., 3., 125., 10., 1845., 101., 110., 235., 84., 100., 65., 14., 8., 17., 12., 1., 4., 7., 8.,  [...]
+
+13., 3., 2., 10., 24., 6., 35., 1., 9., 156., 0., 36., 220., 9., 12., 7., 4., 1., 86., 3., 13., 268., 37., 325., 43., 18., 1., 2., 2., 6., 48., 34., 241., 48., 7., 156., 9., 34., 6., 0., 0., 19., 11., 80., 19., 82., 15., 27., 49., 11., 4., 1., 31., 7., 39., 8., 38., 7., 32., 7., 9., 6., 1., 0., 1., 0., 22., 6., 14., 3., 28., 5., 10., 10., 2., 0., 2., 0., 5., 0., 17., 4., 10., 4., 7., 1., 1., 5., 144., 4., 1894., 94., 105., 218., 99., 112., 69., 15., 11., 25., 12., 1., 4., 4., 9., 3., 11. [...]
+
+18., 1., 1., 7., 27., 3., 35., 0., 9., 162., 2., 24., 209., 4., 17., 7., 2., 11., 69., 1., 11., 304., 43., 329., 45., 13., 0., 2., 8., 4., 49., 21., 230., 40., 5., 156., 9., 60., 6., 0., 1., 18., 6., 72., 16., 71., 9., 26., 50., 18., 1., 2., 28., 5., 36., 8., 59., 8., 33., 3., 7., 8., 5., 0., 1., 0., 26., 2., 20., 5., 22., 4., 25., 2., 2., 2., 0., 0., 3., 2., 11., 4., 10., 3., 10., 3., 0., 4., 130., 3., 1892., 76., 93., 194., 100., 104., 78., 16., 13., 11., 13., 2., 2., 10., 3., 7., 5.,  [...]
+
+16., 1., 2., 5., 21., 3., 35., 0., 13., 162., 2., 18., 198., 6., 16., 8., 0., 6., 84., 2., 19., 302., 48., 339., 44., 23., 0., 2., 7., 6., 49., 30., 217., 32., 6., 155., 18., 46., 3., 0., 3., 16., 10., 78., 24., 85., 12., 34., 42., 13., 2., 0., 24., 4., 30., 9., 57., 7., 32., 10., 6., 10., 1., 0., 1., 0., 27., 9., 17., 4., 22., 8., 12., 3., 0., 5., 3., 2., 0., 2., 12., 1., 9., 2., 8., 1., 3., 6., 130., 6., 1868., 98., 106., 229., 97., 124., 86., 17., 9., 11., 13., 1., 3., 3., 6., 2., 9., [...]
+
+10., 1., 2., 5., 5., 2., 3., 5., 7., 8., 1., 12., 15., 1., 16., 4., 0., 1., 16., 2., 6., 12., 7., 34., 32., 5., 1., 0., 5., 4., 5., 12., 25., 16., 1., 18., 2., 13., 7., 1., 1., 3., 2., 7., 11., 17., 48., 16., 23., 7., 6., 0., 5., 1., 6., 3., 17., 2., 11., 16., 2., 33., 6., 3., 1., 1., 7., 1., 3., 1., 3., 1., 4., 4., 1., 4., 1., 3., 0., 1., 2., 0., 0., 3., 1., 3., 0., 2., 5., 1., 4., 1., 1., 2., 4., 12., 2., 0., 1., 0., 1., 0., 2., 3., 2., 1., 5., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0 [...]
+
+12., 1., 2., 4., 5., 4., 5., 1., 3., 12., 2., 9., 12., 2., 13., 4., 0., 4., 25., 1., 3., 33., 9., 33., 22., 3., 0., 2., 3., 0., 7., 11., 26., 17., 2., 15., 4., 17., 10., 1., 2., 3., 3., 8., 9., 11., 51., 8., 24., 4., 4., 1., 4., 2., 9., 5., 7., 5., 8., 21., 7., 31., 9., 4., 1., 2., 10., 2., 3., 2., 6., 0., 4., 6., 1., 5., 3., 5., 0., 5., 0., 0., 0., 3., 1., 4., 2., 2., 5., 2., 6., 0., 2., 1., 2., 10., 1., 0., 2., 2., 3., 4., 0., 4., 1., 1., 1., 0., 0., 0., 0., 4., 0., 0., 0., 0., 0., 0., [...]
+
+1., 1., 3., 4., 6., 5., 2., 0., 7., 6., 0., 17., 24., 2., 17., 6., 2., 0., 17., 1., 0., 20., 13., 26., 23., 5., 0., 0., 4., 2., 6., 15., 13., 11., 5., 21., 1., 11., 12., 1., 0., 6., 2., 14., 12., 16., 35., 9., 28., 10., 2., 1., 2., 3., 5., 4., 10., 8., 8., 23., 9., 20., 9., 3., 0., 0., 8., 0., 3., 0., 4., 3., 5., 8., 5., 4., 3., 0., 2., 2., 0., 0., 1., 3., 5., 5., 3., 2., 2., 1., 2., 1., 7., 0., 3., 10., 1., 0., 0., 1., 1., 5., 3., 3., 2., 1., 3., 0., 0., 0., 0., 2., 0., 0., 4., 0., 0.,  [...]
+
+4., 1., 2., 3., 11., 2., 0., 1., 8., 18., 2., 2., 21., 0., 17., 2., 0., 3., 20., 3., 5., 17., 6., 22., 14., 4., 0., 1., 0., 3., 10., 12., 28., 20., 2., 19., 4., 16., 4., 1., 1., 2., 0., 9., 9., 17., 52., 23., 16., 9., 8., 2., 4., 0., 6., 1., 13., 7., 6., 18., 5., 19., 10., 1., 2., 3., 9., 1., 5., 1., 6., 4., 5., 3., 1., 3., 8., 5., 1., 3., 2., 0., 1., 5., 2., 5., 2., 4., 2., 0., 4., 1., 1., 1., 4., 2., 1., 0., 3., 1., 2., 3., 1., 3., 1., 1., 3., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0. [...]
+
+10., 1., 3., 1., 8., 2., 4., 1., 8., 11., 2., 18., 22., 0., 17., 5., 2., 3., 17., 5., 6., 26., 12., 21., 27., 7., 0., 2., 3., 1., 9., 7., 34., 15., 11., 24., 7., 11., 3., 2., 2., 1., 3., 11., 8., 25., 43., 12., 25., 5., 7., 1., 8., 4., 6., 6., 10., 9., 6., 24., 7., 20., 6., 2., 1., 1., 10., 2., 2., 0., 5., 5., 5., 7., 4., 3., 4., 4., 0., 4., 1., 0., 2., 0., 2., 7., 4., 4., 3., 4., 3., 2., 3., 0., 5., 5., 2., 0., 3., 3., 0., 2., 1., 3., 6., 0., 6., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0.,  [...]
+
+10., 1., 0., 9., 9., 4., 2., 1., 5., 41., 1., 10., 32., 0., 9., 4., 3., 3., 18., 0., 1., 24., 15., 18., 26., 3., 3., 0., 2., 2., 8., 3., 23., 13., 1., 16., 2., 6., 11., 2., 2., 6., 2., 6., 15., 15., 48., 10., 17., 8., 7., 0., 5., 0., 7., 5., 10., 7., 11., 26., 4., 26., 9., 1., 1., 0., 8., 3., 5., 2., 9., 3., 4., 4., 1., 6., 4., 4., 1., 1., 1., 0., 1., 4., 0., 5., 1., 7., 6., 2., 2., 0., 2., 2., 2., 8., 2., 0., 3., 1., 5., 1., 0., 1., 4., 1., 1., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0. [...]
+
+13., 2., 2., 4., 9., 3., 4., 2., 5., 32., 4., 16., 19., 0., 10., 3., 1., 1., 13., 4., 5., 18., 10., 24., 29., 3., 1., 0., 7., 2., 8., 7., 33., 12., 2., 12., 4., 8., 8., 1., 0., 6., 3., 6., 14., 19., 43., 9., 19., 14., 5., 2., 5., 2., 6., 5., 12., 11., 12., 11., 4., 17., 8., 1., 1., 1., 10., 0., 5., 0., 2., 1., 5., 4., 1., 10., 3., 2., 0., 2., 3., 0., 2., 0., 2., 5., 3., 3., 1., 3., 3., 0., 4., 3., 3., 5., 1., 0., 2., 1., 2., 3., 0., 3., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 4., 0., 0., [...]
+
+8., 3., 1., 4., 2., 3., 7., 0., 4., 17., 2., 13., 25., 1., 20., 0., 1., 0., 25., 2., 3., 37., 10., 16., 33., 3., 0., 0., 5., 0., 12., 6., 24., 14., 1., 11., 6., 10., 6., 1., 1., 3., 2., 8., 13., 17., 45., 11., 34., 4., 4., 1., 9., 2., 5., 2., 6., 8., 11., 20., 6., 18., 12., 3., 0., 1., 10., 2., 2., 2., 5., 2., 5., 2., 4., 1., 3., 2., 0., 2., 2., 0., 1., 2., 5., 9., 4., 6., 4., 1., 1., 2., 3., 0., 3., 3., 3., 0., 0., 0., 2., 6., 1., 2., 3., 0., 0., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0.,  [...]
+
+9., 1., 3., 2., 8., 2., 5., 0., 5., 27., 2., 15., 22., 1., 22., 3., 0., 2., 23., 1., 5., 24., 14., 24., 29., 5., 0., 1., 3., 2., 4., 2., 25., 17., 4., 17., 3., 15., 8., 0., 1., 3., 1., 13., 4., 12., 43., 13., 25., 9., 2., 0., 7., 2., 5., 4., 11., 6., 5., 19., 9., 25., 2., 2., 0., 0., 5., 0., 8., 3., 4., 2., 8., 7., 2., 6., 4., 1., 2., 0., 3., 0., 3., 2., 2., 5., 2., 4., 0., 1., 0., 1., 3., 1., 2., 7., 2., 0., 1., 0., 0., 4., 2., 0., 1., 1., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0., [...]
+
+15., 1., 0., 8., 5., 1., 8., 2., 6., 32., 1., 10., 24., 0., 11., 2., 1., 3., 8., 2., 5., 23., 12., 21., 26., 5., 3., 1., 1., 1., 6., 6., 21., 10., 4., 14., 2., 17., 9., 2., 1., 2., 3., 13., 5., 11., 39., 15., 25., 8., 7., 1., 1., 4., 8., 4., 10., 8., 8., 18., 10., 24., 8., 4., 2., 2., 10., 0., 1., 2., 6., 2., 2., 4., 1., 9., 4., 0., 0., 4., 3., 0., 1., 3., 3., 6., 1., 9., 2., 3., 2., 1., 2., 1., 2., 7., 5., 0., 2., 2., 0., 4., 1., 6., 4., 3., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0 [...]
+
+7., 2., 4., 6., 10., 3., 12., 2., 8., 19., 1., 13., 19., 1., 17., 1., 0., 0., 14., 4., 2., 15., 13., 31., 24., 4., 1., 1., 1., 3., 8., 7., 18., 20., 2., 14., 0., 17., 9., 2., 0., 3., 4., 12., 14., 17., 40., 8., 19., 5., 3., 0., 13., 3., 11., 2., 7., 4., 4., 21., 4., 28., 5., 2., 1., 1., 6., 0., 5., 5., 3., 3., 8., 5., 1., 4., 2., 2., 1., 1., 2., 0., 2., 0., 3., 5., 5., 3., 1., 3., 4., 1., 3., 0., 2., 3., 1., 0., 0., 2., 3., 4., 4., 3., 1., 1., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0.,  [...]
+
+6., 0., 2., 3., 6., 4., 6., 1., 0., 23., 1., 16., 17., 1., 17., 5., 4., 1., 17., 2., 2., 30., 13., 22., 32., 4., 0., 0., 4., 4., 10., 11., 19., 11., 3., 23., 8., 13., 9., 4., 3., 8., 3., 18., 17., 15., 40., 10., 17., 6., 3., 0., 5., 1., 9., 3., 7., 4., 6., 20., 7., 16., 10., 2., 1., 1., 6., 0., 1., 2., 6., 2., 3., 4., 6., 1., 6., 1., 3., 3., 1., 0., 2., 5., 2., 9., 2., 6., 1., 4., 1., 0., 1., 0., 3., 2., 0., 0., 1., 2., 3., 1., 5., 1., 4., 1., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0.,  [...]
+
+4., 1., 3., 4., 6., 5., 9., 0., 6., 27., 2., 14., 29., 1., 21., 1., 1., 2., 30., 1., 3., 20., 9., 36., 26., 5., 1., 0., 0., 0., 9., 3., 23., 18., 2., 11., 3., 11., 4., 2., 0., 4., 3., 17., 11., 22., 42., 11., 17., 7., 3., 2., 5., 6., 8., 3., 10., 7., 15., 11., 4., 21., 7., 1., 1., 0., 10., 3., 4., 1., 6., 4., 6., 3., 2., 5., 9., 2., 2., 1., 3., 0., 3., 2., 3., 1., 0., 1., 5., 1., 3., 1., 1., 1., 0., 7., 0., 0., 1., 0., 3., 0., 4., 2., 1., 0., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0 [...]
+
+8., 0., 1., 1., 12., 1., 3., 2., 5., 25., 0., 12., 18., 2., 14., 3., 1., 1., 14., 0., 3., 13., 10., 30., 33., 9., 0., 1., 5., 1., 8., 6., 19., 12., 2., 16., 2., 14., 7., 4., 0., 4., 2., 14., 5., 14., 48., 10., 25., 5., 3., 1., 7., 1., 6., 4., 15., 7., 10., 12., 5., 21., 8., 3., 0., 1., 3., 0., 2., 2., 7., 3., 5., 1., 2., 8., 6., 2., 0., 1., 0., 0., 2., 3., 2., 9., 2., 5., 2., 3., 6., 0., 3., 1., 2., 10., 1., 0., 0., 1., 2., 5., 4., 3., 2., 1., 2., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0.,  [...]
+
+9., 0., 2., 3., 6., 2., 5., 1., 2., 34., 1., 24., 19., 0., 13., 3., 2., 1., 17., 1., 4., 20., 13., 19., 27., 5., 3., 0., 3., 4., 2., 9., 35., 13., 4., 26., 8., 16., 10., 4., 0., 4., 6., 15., 11., 17., 55., 10., 19., 8., 8., 0., 8., 2., 8., 2., 10., 4., 6., 26., 3., 16., 8., 4., 1., 1., 10., 3., 3., 3., 3., 2., 5., 4., 4., 6., 3., 1., 0., 2., 4., 0., 3., 2., 3., 7., 2., 7., 4., 1., 3., 2., 3., 1., 0., 8., 0., 0., 4., 0., 1., 2., 2., 1., 1., 1., 2., 0., 0., 0., 0., 1., 0., 0., 6., 0., 0.,  [...]
+
+6., 0., 1., 0., 10., 6., 7., 2., 11., 20., 0., 14., 27., 1., 19., 2., 0., 4., 15., 1., 5., 14., 12., 28., 27., 5., 2., 1., 6., 1., 10., 9., 27., 18., 2., 16., 2., 24., 13., 4., 2., 5., 3., 22., 19., 15., 47., 12., 18., 11., 7., 4., 3., 1., 10., 3., 10., 6., 7., 18., 4., 25., 8., 1., 3., 0., 3., 1., 6., 1., 6., 5., 6., 4., 2., 2., 0., 3., 0., 1., 6., 0., 1., 1., 3., 6., 2., 4., 2., 1., 6., 0., 3., 1., 0., 4., 2., 0., 0., 4., 2., 2., 0., 1., 3., 3., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0.,  [...]
+
+11., 0., 1., 6., 4., 2., 10., 2., 6., 26., 1., 21., 17., 1., 11., 3., 1., 1., 21., 5., 5., 20., 11., 18., 26., 6., 0., 1., 5., 0., 10., 10., 14., 21., 0., 14., 5., 18., 6., 2., 0., 7., 2., 8., 12., 19., 53., 12., 25., 8., 1., 1., 6., 1., 6., 4., 14., 8., 5., 22., 7., 23., 8., 4., 1., 0., 6., 0., 4., 1., 8., 6., 6., 3., 2., 3., 8., 1., 0., 2., 1., 0., 2., 2., 4., 8., 2., 4., 1., 5., 3., 1., 0., 0., 1., 7., 2., 0., 1., 1., 0., 2., 3., 0., 1., 1., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., [...]
+
+5., 0., 0., 6., 7., 3., 5., 2., 3., 27., 1., 10., 20., 2., 20., 3., 2., 1., 12., 1., 7., 32., 16., 17., 28., 10., 1., 1., 2., 0., 3., 4., 26., 16., 3., 16., 6., 17., 8., 1., 1., 6., 1., 7., 8., 17., 40., 12., 22., 12., 2., 1., 3., 1., 4., 0., 12., 10., 15., 13., 5., 25., 7., 5., 2., 1., 7., 0., 4., 3., 5., 2., 5., 3., 2., 5., 1., 1., 2., 1., 3., 0., 2., 3., 2., 10., 2., 6., 1., 0., 8., 1., 3., 1., 4., 7., 2., 0., 0., 1., 0., 2., 2., 0., 4., 1., 2., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., [...]
+
+7., 1., 2., 6., 11., 4., 7., 0., 4., 22., 2., 12., 30., 1., 13., 3., 0., 1., 16., 1., 5., 26., 9., 28., 23., 3., 2., 1., 3., 0., 4., 8., 36., 17., 4., 17., 3., 14., 9., 4., 1., 3., 1., 24., 11., 23., 49., 16., 16., 14., 4., 0., 4., 1., 7., 7., 7., 4., 15., 14., 6., 25., 6., 5., 2., 0., 3., 3., 1., 1., 3., 6., 2., 1., 1., 3., 2., 3., 1., 3., 1., 0., 3., 3., 2., 3., 1., 3., 2., 2., 4., 1., 5., 0., 2., 7., 1., 0., 3., 2., 0., 0., 0., 3., 2., 0., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0 [...]
+
+12., 2., 0., 4., 11., 1., 5., 3., 3., 22., 1., 13., 25., 2., 22., 1., 1., 3., 22., 0., 4., 22., 10., 25., 19., 6., 2., 0., 4., 2., 3., 8., 14., 14., 2., 9., 4., 20., 5., 2., 0., 5., 2., 15., 9., 13., 39., 9., 15., 6., 7., 0., 5., 3., 9., 3., 10., 2., 7., 18., 1., 24., 7., 2., 2., 2., 5., 1., 5., 2., 5., 4., 1., 6., 0., 5., 3., 2., 0., 1., 2., 0., 0., 2., 5., 4., 3., 3., 0., 3., 4., 0., 0., 2., 1., 6., 2., 0., 0., 0., 1., 2., 2., 5., 2., 0., 3., 0., 0., 0., 0., 4., 0., 0., 5., 0., 0., 0., [...]
+
+11., 2., 3., 5., 11., 4., 6., 1., 4., 25., 0., 9., 20., 0., 7., 1., 2., 2., 20., 3., 6., 33., 9., 17., 25., 8., 0., 2., 3., 1., 7., 5., 19., 17., 5., 18., 7., 9., 4., 0., 0., 3., 4., 8., 4., 13., 48., 20., 26., 10., 8., 1., 6., 1., 3., 3., 8., 3., 8., 11., 7., 26., 11., 0., 2., 0., 4., 0., 3., 1., 4., 4., 5., 3., 2., 2., 5., 2., 0., 1., 2., 0., 1., 1., 2., 4., 3., 6., 4., 1., 7., 1., 0., 6., 4., 7., 2., 0., 1., 3., 3., 0., 3., 1., 3., 2., 2., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 5 [...]
+
+8., 0., 1., 4., 8., 1., 3., 1., 6., 37., 0., 10., 13., 0., 11., 4., 0., 1., 16., 3., 6., 27., 14., 30., 20., 9., 1., 1., 8., 2., 9., 5., 16., 13., 1., 20., 5., 15., 8., 2., 1., 2., 0., 6., 5., 19., 50., 8., 22., 10., 0., 0., 8., 2., 4., 4., 15., 6., 12., 8., 8., 18., 4., 3., 2., 1., 3., 1., 6., 2., 3., 2., 2., 4., 2., 3., 1., 2., 0., 0., 1., 0., 1., 2., 4., 5., 3., 2., 4., 3., 5., 0., 1., 1., 2., 8., 2., 0., 0., 1., 5., 2., 4., 1., 5., 1., 2., 0., 0., 0., 0., 0., 0., 0., 3., 0., 0., 0.,  [...]
+
+7., 1., 1., 3., 10., 0., 13., 3., 5., 47., 2., 9., 61., 0., 7., 3., 0., 2., 62., 10., 14., 79., 10., 84., 12., 7., 0., 0., 1., 2., 19., 10., 68., 18., 4., 32., 34., 11., 8., 0., 0., 5., 1., 33., 11., 22., 4., 17., 2., 3., 1., 0., 13., 10., 14., 8., 20., 4., 6., 1., 2., 44., 12., 4., 3., 0., 8., 2., 5., 2., 15., 3., 5., 0., 0., 0., 0., 4., 2., 15., 10., 4., 6., 1., 6., 0., 0., 0., 0., 0., 9., 1., 5., 2., 3., 1., 2., 0., 0., 0., 0., 0., 0., 3., 4., 0., 1., 0., 2., 0., 1., 0., 0., 0., 0., 0 [...]
+
+10., 0., 4., 2., 15., 0., 10., 1., 10., 41., 0., 12., 62., 0., 3., 3., 0., 1., 66., 11., 2., 69., 15., 65., 15., 4., 0., 1., 2., 2., 7., 5., 51., 5., 3., 43., 27., 23., 7., 0., 0., 8., 3., 17., 9., 28., 3., 12., 8., 5., 3., 0., 7., 1., 20., 7., 18., 2., 9., 2., 2., 33., 8., 2., 1., 0., 18., 2., 10., 3., 15., 4., 3., 1., 2., 0., 0., 7., 3., 13., 6., 5., 5., 0., 5., 0., 0., 0., 0., 0., 11., 4., 5., 2., 5., 1., 1., 0., 1., 0., 0., 0., 1., 0., 3., 0., 4., 0., 0., 0., 1., 0., 0., 0., 1., 0.,  [...]
+
+6., 1., 1., 9., 27., 8., 21., 2., 15., 161., 3., 23., 214., 6., 12., 5., 0., 1., 81., 0., 11., 297., 45., 360., 55., 20., 0., 1., 4., 8., 40., 19., 225., 38., 10., 166., 16., 32., 7., 0., 3., 13., 9., 100., 24., 77., 12., 33., 50., 13., 0., 1., 22., 6., 31., 11., 40., 11., 30., 7., 7., 7., 5., 0., 1., 0., 24., 2., 13., 4., 26., 5., 9., 8., 3., 4., 1., 1., 4., 3., 15., 1., 9., 3., 9., 0., 0., 1., 147., 11., 1906., 97., 97., 230., 94., 112., 58., 5., 17., 18., 14., 1., 5., 5., 5., 8., 12., [...]
+
+18., 1., 3., 7., 26., 6., 33., 0., 11., 151., 5., 27., 197., 2., 19., 8., 0., 5., 80., 1., 24., 289., 46., 293., 35., 24., 0., 3., 9., 12., 52., 37., 210., 44., 14., 152., 7., 41., 5., 0., 2., 18., 5., 78., 15., 85., 10., 25., 52., 8., 3., 0., 28., 7., 26., 7., 46., 13., 35., 8., 11., 7., 5., 0., 1., 0., 28., 6., 10., 2., 28., 5., 7., 4., 2., 4., 1., 2., 1., 2., 9., 6., 7., 5., 11., 1., 1., 5., 129., 8., 1907., 98., 79., 229., 95., 119., 65., 15., 14., 28., 17., 0., 4., 5., 4., 3., 13.,  [...]
+
+11., 2., 5., 7., 27., 6., 39., 0., 17., 133., 2., 26., 184., 6., 18., 14., 1., 6., 89., 0., 16., 298., 36., 327., 51., 24., 0., 1., 10., 7., 35., 27., 246., 52., 4., 168., 13., 29., 6., 0., 2., 21., 8., 72., 17., 95., 20., 28., 42., 8., 2., 0., 26., 10., 41., 8., 47., 7., 20., 4., 7., 10., 2., 0., 0., 0., 27., 4., 16., 2., 19., 2., 10., 5., 0., 1., 1., 0., 3., 2., 15., 4., 6., 2., 2., 2., 1., 5., 147., 12., 1820., 88., 110., 228., 85., 95., 70., 10., 16., 16., 18., 1., 1., 3., 2., 3., 12 [...]
+
+13., 1., 5., 8., 21., 6., 19., 1., 22., 168., 6., 24., 194., 5., 16., 4., 0., 4., 77., 6., 13., 280., 52., 324., 50., 22., 1., 1., 5., 2., 45., 33., 234., 43., 4., 142., 11., 39., 9., 0., 5., 18., 8., 78., 26., 114., 15., 40., 53., 10., 1., 1., 30., 10., 50., 10., 57., 9., 28., 5., 6., 8., 2., 0., 0., 0., 22., 6., 17., 3., 31., 4., 10., 1., 0., 5., 0., 0., 3., 1., 10., 2., 13., 8., 7., 0., 0., 3., 159., 7., 1850., 94., 107., 205., 93., 123., 69., 18., 16., 18., 14., 0., 0., 10., 1., 1.,  [...]
+
+18., 0., 2., 9., 15., 4., 32., 0., 20., 153., 2., 23., 222., 6., 17., 10., 2., 6., 88., 2., 18., 273., 42., 315., 55., 16., 2., 4., 6., 3., 55., 28., 233., 57., 5., 137., 25., 25., 9., 0., 3., 11., 3., 77., 24., 101., 15., 29., 32., 8., 0., 1., 25., 6., 35., 7., 32., 8., 27., 5., 14., 3., 2., 0., 5., 0., 22., 5., 13., 4., 26., 6., 14., 1., 0., 5., 0., 1., 3., 2., 13., 3., 9., 2., 8., 0., 2., 1., 119., 12., 1859., 98., 121., 235., 92., 111., 77., 17., 11., 26., 7., 0., 1., 2., 6., 7., 4., [...]
+
+12., 4., 0., 5., 30., 2., 40., 2., 17., 172., 2., 24., 190., 2., 11., 6., 0., 4., 75., 3., 22., 320., 35., 384., 45., 25., 0., 3., 11., 3., 39., 30., 238., 53., 5., 174., 15., 35., 4., 0., 2., 9., 10., 88., 18., 89., 13., 33., 45., 11., 4., 3., 30., 5., 38., 9., 39., 8., 28., 4., 9., 10., 2., 0., 0., 0., 25., 4., 16., 3., 38., 6., 12., 6., 1., 2., 0., 1., 2., 2., 13., 5., 8., 1., 8., 1., 1., 5., 163., 5., 1961., 80., 116., 237., 111., 99., 71., 12., 19., 20., 16., 1., 3., 8., 5., 7., 7., [...]
+
+11., 2., 4., 14., 35., 4., 29., 2., 14., 167., 2., 26., 201., 7., 14., 6., 2., 8., 81., 1., 15., 300., 43., 326., 51., 19., 1., 0., 6., 5., 48., 34., 232., 41., 5., 165., 8., 30., 4., 0., 2., 16., 12., 65., 12., 82., 16., 38., 45., 12., 2., 2., 29., 7., 45., 3., 42., 9., 31., 8., 13., 6., 2., 0., 3., 0., 20., 11., 20., 1., 30., 4., 17., 2., 1., 3., 1., 1., 4., 2., 10., 2., 7., 2., 4., 0., 1., 1., 143., 12., 1932., 79., 96., 232., 105., 113., 74., 17., 13., 12., 11., 1., 3., 3., 4., 4., 6 [...]
+
+8., 3., 6., 2., 4., 0., 4., 2., 7., 24., 1., 13., 17., 1., 18., 1., 2., 5., 20., 0., 6., 12., 19., 26., 27., 4., 1., 0., 2., 4., 12., 13., 33., 19., 1., 15., 2., 14., 9., 2., 0., 6., 5., 13., 10., 14., 50., 16., 21., 9., 5., 3., 3., 5., 8., 2., 11., 6., 6., 20., 6., 22., 9., 0., 1., 1., 10., 3., 3., 1., 7., 1., 4., 3., 1., 5., 6., 3., 2., 3., 2., 0., 3., 1., 3., 5., 1., 7., 3., 1., 2., 3., 1., 1., 3., 8., 0., 0., 1., 5., 0., 2., 1., 3., 1., 0., 2., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., [...]
+
+9., 2., 0., 2., 5., 7., 4., 0., 5., 15., 1., 15., 17., 0., 19., 2., 0., 4., 14., 3., 4., 27., 14., 28., 32., 5., 1., 1., 3., 3., 11., 4., 17., 18., 6., 18., 5., 16., 4., 2., 2., 2., 1., 13., 15., 17., 45., 13., 23., 5., 3., 3., 3., 3., 11., 5., 11., 3., 8., 15., 5., 24., 5., 4., 0., 0., 6., 1., 1., 1., 2., 4., 6., 1., 0., 3., 5., 4., 1., 3., 2., 0., 2., 2., 1., 5., 4., 3., 3., 3., 4., 1., 2., 1., 2., 8., 1., 0., 0., 0., 1., 2., 1., 2., 4., 3., 1., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0.,  [...]
+
+7., 1., 3., 7., 6., 5., 2., 0., 6., 17., 0., 22., 25., 0., 16., 2., 0., 1., 15., 1., 5., 35., 9., 15., 20., 8., 1., 0., 0., 1., 6., 8., 24., 19., 3., 21., 3., 19., 8., 2., 0., 10., 3., 13., 12., 16., 50., 13., 22., 7., 4., 3., 2., 3., 6., 2., 7., 2., 5., 13., 6., 15., 6., 1., 2., 0., 7., 0., 3., 1., 7., 2., 2., 9., 3., 2., 3., 1., 1., 3., 1., 0., 5., 1., 3., 8., 1., 1., 4., 1., 7., 1., 5., 2., 0., 8., 3., 0., 0., 2., 5., 1., 4., 1., 0., 0., 1., 0., 0., 0., 0., 4., 0., 0., 1., 0., 0., 0., [...]
+
+3., 2., 2., 2., 4., 5., 2., 2., 3., 16., 0., 15., 23., 2., 19., 3., 1., 2., 23., 1., 2., 17., 18., 17., 21., 6., 0., 1., 1., 2., 2., 3., 36., 16., 4., 15., 7., 7., 12., 3., 0., 4., 3., 12., 13., 23., 45., 20., 22., 6., 3., 3., 6., 3., 3., 1., 11., 5., 5., 17., 8., 21., 11., 0., 1., 1., 3., 0., 3., 2., 4., 1., 3., 0., 3., 7., 2., 1., 0., 3., 0., 0., 6., 0., 1., 3., 0., 2., 1., 0., 4., 1., 0., 1., 2., 7., 1., 0., 2., 2., 3., 6., 2., 3., 1., 1., 3., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0 [...]
+
+10., 0., 2., 2., 8., 5., 10., 1., 7., 24., 0., 5., 23., 3., 11., 5., 0., 1., 22., 1., 4., 31., 10., 22., 27., 4., 0., 3., 1., 2., 9., 1., 28., 16., 2., 8., 4., 19., 9., 1., 1., 2., 3., 14., 12., 15., 57., 9., 16., 5., 6., 0., 4., 1., 8., 2., 14., 3., 9., 25., 5., 24., 5., 6., 4., 0., 5., 0., 5., 0., 7., 1., 6., 5., 1., 6., 3., 3., 3., 1., 2., 0., 1., 0., 4., 6., 2., 3., 1., 1., 1., 0., 0., 0., 4., 6., 3., 0., 4., 4., 2., 3., 4., 1., 3., 3., 5., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0., [...]
+
+16., 1., 3., 7., 4., 7., 2., 2., 7., 21., 1., 16., 30., 2., 14., 1., 1., 1., 14., 3., 4., 27., 5., 20., 30., 9., 0., 1., 3., 0., 12., 7., 25., 20., 5., 15., 5., 11., 12., 2., 0., 8., 2., 9., 11., 12., 44., 7., 25., 4., 5., 1., 11., 1., 4., 6., 9., 7., 11., 17., 9., 20., 7., 2., 1., 0., 10., 2., 1., 2., 7., 4., 4., 5., 3., 5., 2., 0., 0., 3., 2., 0., 2., 1., 2., 5., 0., 4., 2., 2., 3., 0., 2., 1., 0., 8., 1., 0., 2., 1., 2., 3., 1., 0., 0., 1., 2., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.,  [...]
+
+4., 1., 2., 3., 11., 0., 5., 0., 6., 31., 0., 14., 19., 0., 15., 2., 0., 3., 27., 3., 5., 40., 9., 31., 27., 3., 1., 0., 1., 1., 4., 7., 19., 10., 3., 17., 3., 20., 11., 4., 0., 5., 2., 7., 13., 15., 45., 8., 10., 5., 5., 0., 5., 3., 5., 4., 7., 3., 9., 15., 5., 21., 6., 1., 1., 1., 6., 0., 2., 3., 8., 2., 5., 7., 2., 7., 3., 4., 1., 2., 6., 0., 4., 3., 2., 8., 1., 4., 1., 0., 4., 0., 2., 0., 3., 10., 4., 0., 2., 4., 1., 1., 2., 0., 4., 0., 1., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0., 0., [...]
+
+6., 2., 3., 5., 13., 1., 6., 3., 6., 19., 2., 12., 14., 2., 18., 2., 0., 5., 13., 3., 3., 30., 19., 34., 29., 7., 1., 0., 3., 2., 5., 0., 21., 18., 5., 15., 6., 10., 9., 3., 0., 2., 5., 15., 8., 17., 49., 9., 20., 2., 2., 0., 6., 1., 5., 0., 10., 6., 5., 16., 3., 18., 13., 1., 1., 2., 10., 2., 3., 0., 3., 3., 1., 3., 0., 3., 7., 3., 0., 0., 1., 0., 0., 2., 0., 2., 2., 6., 4., 2., 4., 0., 2., 0., 2., 12., 5., 0., 1., 4., 3., 1., 5., 4., 0., 1., 2., 0., 0., 0., 0., 2., 0., 0., 4., 0., 0.,  [...]
+
+4., 0., 2., 4., 13., 1., 3., 1., 3., 16., 0., 14., 15., 0., 17., 2., 1., 4., 32., 2., 2., 33., 24., 14., 20., 3., 0., 3., 8., 3., 11., 5., 20., 21., 1., 11., 5., 6., 10., 2., 0., 8., 2., 10., 19., 14., 37., 12., 23., 10., 4., 1., 8., 1., 2., 4., 17., 11., 10., 14., 7., 29., 12., 4., 0., 1., 13., 0., 7., 2., 4., 3., 7., 3., 3., 5., 2., 1., 0., 2., 1., 0., 1., 3., 1., 9., 4., 1., 2., 4., 5., 1., 7., 1., 2., 8., 1., 0., 2., 1., 1., 1., 2., 1., 1., 1., 0., 0., 0., 0., 0., 3., 0., 0., 5., 0., [...]
+
+12., 1., 1., 4., 10., 3., 0., 2., 8., 22., 0., 13., 20., 0., 11., 4., 1., 3., 17., 1., 4., 26., 15., 23., 26., 9., 1., 0., 2., 3., 9., 6., 23., 30., 4., 14., 8., 13., 5., 1., 3., 4., 1., 12., 18., 18., 46., 12., 24., 5., 2., 1., 5., 3., 10., 1., 8., 7., 13., 17., 7., 24., 6., 3., 2., 1., 8., 1., 1., 2., 4., 3., 4., 3., 1., 1., 3., 1., 1., 5., 1., 0., 6., 2., 2., 4., 4., 6., 2., 1., 2., 0., 2., 0., 0., 9., 1., 0., 0., 0., 2., 2., 4., 2., 4., 0., 0., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., [...]
+
+13., 1., 3., 3., 9., 4., 10., 1., 5., 21., 1., 13., 29., 1., 13., 2., 2., 4., 30., 2., 5., 18., 10., 25., 27., 3., 3., 1., 3., 4., 6., 5., 30., 13., 4., 14., 3., 13., 6., 1., 1., 2., 2., 13., 11., 11., 44., 11., 24., 10., 6., 1., 3., 2., 10., 2., 7., 6., 8., 14., 2., 29., 8., 2., 0., 1., 4., 1., 1., 3., 4., 3., 2., 4., 1., 3., 4., 0., 1., 4., 0., 0., 3., 6., 5., 4., 1., 4., 1., 0., 2., 0., 2., 0., 4., 9., 5., 0., 0., 1., 3., 0., 2., 1., 3., 1., 4., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0., [...]
+
+8., 0., 3., 5., 8., 3., 3., 1., 9., 22., 0., 17., 18., 1., 21., 1., 1., 0., 16., 4., 5., 18., 14., 19., 26., 6., 2., 1., 2., 1., 4., 8., 39., 11., 4., 10., 1., 18., 6., 2., 2., 4., 3., 11., 12., 21., 50., 7., 22., 15., 1., 0., 4., 1., 1., 4., 9., 4., 8., 18., 4., 27., 6., 4., 0., 0., 5., 2., 3., 1., 4., 4., 1., 5., 0., 3., 7., 3., 2., 4., 4., 0., 2., 1., 2., 7., 4., 2., 2., 3., 4., 1., 5., 2., 2., 4., 4., 0., 2., 0., 2., 1., 0., 2., 5., 2., 0., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0., 0., [...]
+
+10., 0., 1., 5., 5., 5., 8., 0., 7., 28., 1., 15., 29., 1., 20., 3., 0., 1., 17., 2., 4., 26., 7., 19., 22., 13., 1., 3., 0., 2., 5., 7., 25., 23., 2., 20., 7., 13., 11., 2., 0., 6., 1., 9., 14., 21., 38., 6., 21., 7., 6., 0., 0., 1., 7., 2., 18., 1., 5., 13., 9., 25., 12., 1., 0., 1., 6., 2., 5., 1., 2., 3., 3., 4., 3., 4., 1., 1., 2., 1., 2., 0., 1., 2., 4., 3., 2., 2., 2., 2., 5., 0., 3., 1., 1., 8., 0., 0., 2., 2., 1., 4., 4., 1., 2., 0., 2., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0 [...]
+
+7., 0., 3., 5., 11., 5., 7., 0., 4., 27., 1., 15., 25., 0., 10., 5., 3., 1., 30., 1., 2., 17., 19., 34., 41., 9., 3., 5., 1., 3., 9., 7., 18., 17., 0., 11., 6., 18., 5., 0., 0., 1., 2., 11., 11., 14., 40., 15., 17., 8., 7., 0., 2., 1., 12., 6., 7., 3., 8., 17., 6., 23., 9., 4., 1., 1., 7., 1., 4., 4., 7., 3., 4., 3., 3., 4., 4., 1., 1., 1., 2., 0., 2., 3., 1., 8., 6., 3., 2., 1., 5., 1., 2., 2., 2., 6., 3., 0., 1., 1., 2., 3., 5., 3., 0., 0., 3., 0., 0., 0., 0., 4., 0., 0., 0., 0., 0., 0 [...]
+
+8., 2., 1., 1., 7., 5., 4., 0., 5., 21., 4., 16., 29., 0., 22., 4., 1., 5., 10., 3., 4., 23., 6., 29., 23., 6., 0., 2., 4., 4., 12., 8., 28., 17., 3., 16., 3., 17., 2., 3., 3., 1., 4., 11., 12., 23., 42., 8., 22., 14., 5., 0., 4., 2., 11., 3., 7., 4., 13., 21., 6., 22., 10., 2., 0., 0., 8., 1., 1., 3., 6., 4., 3., 3., 1., 2., 4., 3., 0., 1., 2., 0., 2., 1., 2., 6., 3., 8., 0., 3., 7., 0., 2., 1., 1., 6., 1., 0., 1., 2., 0., 2., 2., 1., 1., 2., 3., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.,  [...]
+
+4., 0., 2., 4., 7., 4., 2., 0., 10., 11., 0., 14., 30., 1., 24., 3., 1., 5., 21., 1., 6., 17., 15., 18., 41., 5., 1., 1., 3., 2., 8., 4., 33., 20., 7., 13., 1., 13., 7., 5., 2., 3., 4., 14., 18., 16., 41., 16., 20., 11., 1., 0., 0., 2., 5., 5., 11., 3., 8., 16., 7., 34., 6., 4., 1., 0., 8., 3., 1., 2., 6., 3., 4., 2., 2., 2., 2., 0., 1., 3., 1., 0., 0., 4., 1., 3., 5., 0., 4., 1., 3., 1., 2., 1., 3., 6., 3., 0., 0., 1., 3., 5., 2., 1., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.,  [...]
+
+6., 2., 0., 6., 5., 4., 3., 2., 9., 30., 0., 17., 28., 0., 9., 6., 1., 2., 15., 2., 7., 30., 14., 32., 21., 3., 0., 0., 3., 1., 4., 8., 24., 15., 3., 14., 3., 7., 6., 2., 0., 3., 3., 15., 6., 16., 46., 11., 21., 11., 0., 1., 3., 1., 4., 2., 4., 3., 8., 14., 7., 21., 8., 3., 1., 5., 7., 1., 2., 1., 5., 6., 3., 1., 0., 6., 1., 2., 2., 4., 2., 0., 1., 2., 1., 6., 1., 5., 1., 1., 7., 3., 3., 1., 1., 10., 2., 0., 3., 4., 3., 1., 6., 0., 1., 2., 1., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., 0.,  [...]
+
+7., 1., 6., 3., 6., 3., 4., 1., 9., 17., 1., 14., 15., 0., 14., 4., 0., 1., 9., 0., 3., 28., 10., 28., 24., 6., 1., 1., 5., 2., 9., 7., 21., 12., 3., 17., 3., 12., 7., 1., 0., 6., 0., 8., 2., 15., 52., 8., 25., 10., 4., 0., 4., 3., 8., 2., 15., 4., 9., 17., 7., 20., 14., 3., 2., 1., 9., 1., 5., 2., 6., 2., 1., 9., 3., 2., 5., 1., 3., 2., 1., 0., 1., 1., 6., 7., 3., 4., 2., 2., 2., 1., 2., 1., 4., 2., 2., 0., 3., 3., 2., 1., 0., 4., 2., 1., 2., 0., 0., 0., 0., 0., 0., 0., 3., 0., 0., 0.,  [...]
+
+5., 1., 1., 2., 9., 3., 5., 0., 3., 18., 1., 15., 27., 3., 18., 6., 0., 2., 27., 2., 5., 30., 13., 25., 35., 4., 0., 2., 2., 2., 9., 6., 23., 23., 2., 7., 4., 10., 11., 2., 0., 3., 2., 16., 12., 10., 48., 9., 24., 7., 3., 1., 4., 1., 8., 1., 9., 6., 6., 18., 3., 15., 6., 3., 0., 0., 12., 0., 5., 4., 9., 1., 4., 4., 3., 5., 3., 0., 1., 7., 1., 0., 0., 0., 3., 7., 2., 5., 2., 0., 2., 1., 3., 0., 4., 5., 1., 0., 1., 6., 3., 1., 1., 2., 2., 1., 3., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., [...]
+
+6., 0., 0., 2., 9., 2., 4., 1., 5., 20., 0., 13., 13., 3., 15., 2., 0., 2., 21., 2., 4., 27., 17., 29., 15., 3., 1., 2., 0., 5., 7., 11., 23., 19., 0., 9., 5., 20., 10., 2., 2., 6., 2., 10., 15., 18., 36., 10., 15., 10., 3., 2., 4., 2., 12., 3., 11., 5., 8., 7., 11., 17., 5., 0., 0., 1., 5., 0., 4., 6., 3., 6., 6., 4., 0., 1., 2., 2., 0., 2., 4., 0., 0., 4., 2., 11., 0., 3., 3., 3., 6., 0., 4., 2., 2., 4., 0., 0., 1., 1., 0., 0., 0., 4., 1., 2., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0. [...]
+
+8., 1., 1., 4., 12., 2., 6., 0., 9., 14., 1., 9., 13., 1., 16., 6., 2., 1., 10., 0., 4., 23., 10., 29., 28., 4., 1., 1., 4., 2., 6., 3., 25., 20., 3., 11., 1., 8., 6., 1., 0., 0., 0., 10., 11., 20., 45., 15., 21., 7., 7., 1., 4., 4., 4., 5., 3., 6., 6., 13., 3., 16., 5., 4., 1., 1., 10., 1., 3., 2., 6., 4., 3., 7., 3., 2., 2., 4., 0., 4., 4., 0., 1., 2., 2., 10., 1., 4., 1., 2., 5., 1., 3., 1., 4., 6., 0., 0., 2., 2., 5., 1., 3., 3., 4., 3., 0., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0. [...]
+
+7., 0., 3., 2., 6., 5., 8., 1., 7., 28., 2., 12., 21., 0., 13., 0., 0., 3., 35., 4., 4., 41., 8., 23., 22., 6., 0., 0., 0., 1., 6., 2., 28., 12., 1., 11., 7., 13., 5., 2., 1., 5., 2., 11., 10., 14., 35., 12., 14., 13., 6., 1., 8., 0., 15., 2., 8., 9., 8., 18., 4., 16., 6., 4., 0., 1., 5., 1., 3., 0., 2., 3., 6., 4., 2., 6., 3., 2., 2., 2., 2., 0., 3., 3., 1., 4., 0., 3., 3., 2., 4., 1., 2., 1., 1., 7., 1., 0., 0., 1., 1., 1., 3., 6., 2., 0., 3., 0., 0., 0., 0., 6., 0., 0., 0., 0., 0., 0. [...]
+
+4., 1., 2., 3., 6., 0., 14., 2., 6., 45., 0., 7., 61., 0., 4., 1., 0., 4., 77., 10., 4., 67., 12., 70., 13., 6., 0., 1., 4., 2., 14., 9., 41., 11., 4., 43., 32., 15., 7., 0., 1., 9., 3., 24., 0., 26., 6., 12., 5., 5., 0., 0., 8., 8., 16., 6., 9., 0., 12., 5., 1., 33., 7., 6., 3., 0., 12., 3., 8., 3., 10., 0., 3., 0., 3., 3., 0., 2., 5., 18., 10., 1., 2., 1., 6., 0., 0., 0., 0., 0., 16., 1., 0., 0., 4., 0., 1., 0., 3., 0., 0., 0., 0., 2., 0., 0., 5., 0., 1., 0., 1., 0., 0., 0., 3., 0., 0. [...]
+
+8., 0., 1., 2., 13., 0., 13., 2., 8., 59., 3., 9., 59., 1., 3., 4., 0., 4., 71., 10., 9., 88., 18., 90., 11., 7., 0., 0., 4., 2., 11., 10., 55., 11., 1., 36., 27., 13., 6., 0., 1., 7., 4., 16., 3., 27., 12., 12., 12., 1., 3., 0., 8., 6., 14., 9., 18., 2., 5., 3., 5., 38., 4., 7., 1., 0., 16., 7., 6., 1., 13., 2., 2., 1., 1., 0., 0., 7., 1., 14., 7., 4., 4., 0., 2., 0., 0., 0., 0., 0., 9., 0., 1., 1., 4., 1., 0., 0., 1., 0., 1., 0., 0., 5., 1., 0., 0., 0., 0., 0., 2., 0., 0., 0., 1., 0.,  [...]
+
+8., 1., 5., 5., 14., 0., 9., 1., 10., 54., 2., 9., 55., 1., 5., 1., 0., 3., 87., 6., 7., 77., 12., 89., 10., 3., 0., 0., 3., 2., 14., 7., 44., 11., 2., 34., 41., 10., 2., 0., 2., 0., 3., 18., 6., 21., 8., 13., 11., 0., 1., 0., 7., 6., 20., 4., 16., 7., 5., 4., 4., 41., 9., 4., 1., 0., 15., 4., 7., 1., 10., 2., 2., 1., 0., 2., 0., 1., 1., 28., 9., 2., 4., 1., 3., 0., 0., 0., 0., 0., 6., 3., 1., 4., 2., 0., 0., 0., 0., 0., 0., 0., 1., 6., 2., 0., 2., 0., 0., 0., 2., 0., 0., 0., 2., 0., 2., [...]
+
+10., 3., 3., 8., 24., 5., 25., 1., 12., 151., 4., 29., 203., 1., 20., 4., 0., 4., 74., 3., 9., 277., 32., 340., 36., 18., 0., 4., 7., 2., 38., 34., 224., 29., 8., 159., 10., 31., 7., 0., 0., 22., 15., 95., 15., 84., 20., 35., 53., 11., 3., 1., 27., 9., 33., 8., 41., 12., 33., 4., 5., 7., 3., 0., 1., 0., 21., 6., 16., 2., 33., 5., 16., 5., 1., 3., 0., 0., 3., 0., 15., 5., 8., 2., 7., 0., 2., 5., 124., 8., 1829., 98., 91., 219., 95., 96., 73., 16., 10., 21., 6., 0., 1., 7., 6., 4., 6., 9., [...]
+
+14., 1., 3., 6., 30., 9., 31., 5., 9., 153., 2., 31., 201., 9., 15., 9., 1., 3., 93., 5., 13., 266., 46., 355., 54., 16., 1., 1., 8., 2., 44., 24., 211., 51., 4., 148., 16., 40., 3., 0., 2., 23., 5., 83., 25., 87., 14., 40., 39., 14., 2., 1., 30., 6., 46., 8., 43., 4., 33., 8., 10., 2., 2., 0., 1., 0., 26., 0., 13., 0., 25., 3., 7., 2., 2., 3., 0., 0., 2., 3., 12., 0., 10., 3., 6., 1., 3., 3., 130., 6., 1837., 79., 105., 224., 76., 96., 68., 14., 6., 17., 13., 1., 1., 5., 7., 3., 10., 8. [...]
+
+13., 2., 2., 4., 27., 4., 38., 3., 23., 158., 4., 30., 238., 3., 15., 9., 1., 6., 88., 2., 20., 294., 54., 315., 54., 20., 1., 5., 12., 10., 38., 35., 254., 35., 7., 151., 13., 33., 4., 0., 1., 19., 8., 84., 15., 91., 14., 56., 44., 12., 1., 2., 23., 10., 40., 8., 47., 12., 38., 5., 8., 7., 3., 0., 0., 0., 24., 6., 10., 3., 29., 7., 10., 2., 3., 4., 3., 3., 3., 0., 13., 4., 10., 1., 4., 1., 1., 6., 165., 8., 1904., 94., 81., 234., 89., 119., 71., 19., 13., 22., 8., 2., 3., 5., 5., 3., 12 [...]
+
+14., 1., 2., 5., 20., 6., 26., 2., 12., 163., 1., 28., 217., 3., 17., 5., 1., 2., 84., 1., 23., 295., 34., 322., 39., 20., 2., 1., 8., 7., 39., 35., 217., 46., 8., 158., 12., 42., 2., 0., 0., 15., 5., 86., 18., 100., 15., 32., 46., 5., 4., 0., 26., 8., 41., 9., 38., 16., 26., 3., 17., 6., 2., 0., 1., 0., 24., 4., 16., 1., 31., 4., 6., 6., 2., 3., 3., 0., 1., 3., 16., 2., 6., 3., 10., 2., 2., 5., 161., 9., 1827., 92., 99., 195., 92., 121., 72., 16., 13., 15., 11., 1., 2., 4., 8., 4., 8.,  [...]
+
+13., 0., 1., 4., 16., 6., 23., 1., 13., 149., 2., 24., 202., 5., 20., 13., 1., 8., 67., 0., 13., 305., 42., 329., 46., 24., 0., 2., 11., 4., 32., 36., 247., 40., 3., 154., 17., 38., 9., 0., 1., 17., 4., 86., 31., 78., 12., 26., 35., 15., 4., 5., 21., 3., 43., 12., 35., 12., 29., 7., 12., 5., 1., 0., 1., 0., 23., 5., 14., 2., 30., 5., 10., 2., 0., 2., 2., 3., 0., 3., 20., 4., 6., 2., 13., 0., 0., 5., 144., 5., 1852., 94., 86., 226., 92., 106., 74., 16., 14., 10., 15., 1., 0., 5., 10., 6., [...]
+
+10., 2., 5., 9., 27., 3., 27., 1., 19., 168., 3., 27., 199., 5., 13., 9., 0., 4., 80., 1., 15., 312., 39., 301., 44., 18., 0., 1., 7., 4., 45., 27., 211., 40., 8., 164., 9., 50., 5., 0., 3., 9., 9., 90., 17., 84., 13., 37., 46., 14., 4., 0., 22., 10., 38., 8., 55., 9., 27., 7., 6., 7., 1., 0., 0., 0., 27., 4., 21., 1., 38., 5., 7., 4., 2., 3., 0., 1., 4., 3., 10., 2., 8., 4., 10., 2., 2., 3., 143., 7., 1825., 99., 103., 229., 82., 118., 70., 19., 14., 18., 14., 1., 2., 13., 6., 6., 10.,  [...]
+
+17., 2., 2., 11., 25., 7., 40., 0., 21., 175., 5., 26., 188., 2., 19., 6., 0., 5., 76., 5., 17., 286., 48., 325., 33., 18., 0., 0., 4., 7., 51., 33., 215., 35., 5., 134., 3., 29., 5., 0., 4., 22., 7., 67., 20., 75., 9., 35., 32., 15., 2., 3., 24., 7., 36., 16., 57., 6., 25., 3., 8., 9., 1., 0., 1., 0., 18., 6., 14., 0., 39., 0., 9., 1., 3., 2., 1., 1., 3., 2., 9., 4., 9., 2., 6., 1., 1., 5., 146., 6., 1906., 102., 88., 238., 103., 131., 69., 16., 8., 15., 10., 1., 4., 11., 7., 2., 8., 6. [...]
+
+6., 1., 1., 3., 5., 2., 13., 2., 1., 18., 1., 16., 24., 3., 12., 5., 3., 3., 7., 5., 1., 22., 13., 27., 28., 4., 0., 0., 2., 0., 7., 6., 21., 15., 3., 13., 5., 9., 10., 2., 1., 4., 1., 18., 10., 14., 38., 14., 27., 7., 2., 0., 2., 3., 9., 4., 7., 3., 14., 15., 8., 22., 12., 3., 0., 3., 4., 1., 3., 3., 4., 2., 4., 3., 1., 4., 2., 0., 0., 1., 5., 0., 1., 0., 2., 6., 3., 7., 3., 2., 6., 0., 1., 0., 2., 9., 2., 0., 1., 0., 3., 3., 1., 2., 2., 0., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0 [...]
+
+6., 2., 1., 4., 9., 4., 6., 0., 8., 19., 1., 15., 31., 0., 17., 2., 1., 1., 24., 0., 6., 25., 13., 29., 31., 5., 1., 2., 1., 5., 8., 13., 35., 20., 2., 8., 1., 16., 9., 2., 0., 1., 1., 14., 8., 11., 34., 16., 19., 6., 4., 6., 5., 3., 8., 3., 8., 6., 7., 18., 7., 29., 10., 2., 1., 2., 5., 0., 1., 0., 3., 3., 6., 1., 1., 4., 2., 2., 0., 1., 1., 0., 3., 3., 3., 12., 0., 6., 1., 1., 6., 1., 2., 2., 2., 6., 1., 0., 1., 3., 0., 5., 4., 4., 1., 1., 4., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., 0. [...]
+
+7., 0., 2., 1., 7., 5., 6., 1., 8., 14., 0., 15., 12., 3., 18., 2., 1., 1., 26., 3., 3., 28., 11., 12., 25., 4., 0., 2., 3., 1., 11., 8., 26., 13., 3., 16., 6., 18., 7., 1., 0., 1., 3., 14., 18., 22., 44., 14., 17., 10., 5., 0., 6., 0., 6., 2., 14., 3., 9., 17., 9., 31., 7., 4., 0., 1., 10., 1., 2., 4., 4., 3., 2., 2., 5., 3., 2., 0., 2., 2., 2., 0., 0., 4., 0., 6., 3., 2., 2., 1., 5., 0., 2., 1., 1., 11., 2., 0., 0., 1., 3., 1., 1., 3., 1., 1., 2., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0. [...]
+
+3., 3., 2., 3., 6., 3., 4., 1., 7., 27., 1., 11., 25., 0., 17., 5., 1., 2., 19., 2., 3., 13., 16., 19., 31., 10., 1., 2., 3., 2., 9., 11., 34., 25., 7., 20., 3., 10., 4., 5., 0., 2., 3., 10., 10., 21., 31., 14., 26., 7., 5., 1., 3., 1., 6., 6., 17., 6., 7., 14., 5., 20., 10., 3., 0., 3., 7., 1., 2., 2., 4., 6., 0., 3., 3., 7., 2., 4., 2., 3., 2., 0., 3., 1., 2., 5., 1., 3., 2., 4., 2., 0., 2., 0., 3., 5., 1., 0., 5., 6., 0., 1., 3., 3., 3., 0., 6., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., [...]
+
+5., 2., 2., 3., 9., 1., 4., 0., 6., 19., 0., 11., 23., 2., 17., 4., 1., 4., 6., 2., 4., 31., 13., 22., 21., 8., 2., 2., 3., 5., 7., 6., 28., 10., 4., 18., 5., 19., 12., 2., 0., 4., 1., 15., 8., 14., 40., 14., 17., 8., 4., 3., 4., 1., 6., 1., 8., 3., 6., 15., 6., 19., 10., 4., 2., 0., 6., 1., 2., 2., 3., 5., 3., 7., 2., 6., 0., 4., 1., 5., 3., 0., 0., 4., 0., 8., 2., 5., 2., 1., 0., 0., 0., 1., 1., 5., 3., 0., 1., 0., 1., 1., 1., 3., 3., 1., 0., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0., [...]
+
+7., 1., 1., 4., 5., 4., 7., 2., 5., 26., 1., 12., 22., 0., 12., 0., 0., 0., 12., 0., 7., 11., 5., 22., 28., 4., 0., 0., 5., 2., 8., 8., 37., 12., 2., 11., 7., 9., 7., 5., 2., 5., 0., 13., 8., 17., 48., 14., 28., 7., 3., 1., 5., 3., 9., 4., 3., 11., 7., 12., 7., 28., 13., 1., 1., 1., 6., 0., 4., 2., 6., 4., 5., 5., 0., 2., 2., 1., 2., 2., 3., 0., 1., 2., 1., 12., 1., 5., 2., 3., 2., 2., 1., 2., 1., 6., 0., 0., 3., 1., 3., 1., 5., 4., 2., 1., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0., [...]
+
+6., 1., 2., 0., 7., 2., 6., 1., 4., 27., 1., 13., 27., 1., 10., 0., 0., 3., 13., 3., 6., 22., 12., 24., 23., 5., 1., 2., 0., 1., 6., 5., 18., 11., 3., 19., 4., 11., 8., 3., 1., 5., 3., 13., 17., 15., 30., 16., 18., 4., 0., 1., 5., 3., 11., 4., 10., 9., 9., 14., 6., 25., 9., 3., 0., 1., 7., 0., 2., 0., 6., 3., 2., 6., 0., 4., 6., 1., 1., 2., 0., 0., 3., 3., 0., 3., 1., 3., 1., 3., 4., 0., 1., 1., 1., 10., 1., 0., 2., 4., 1., 2., 2., 2., 2., 1., 1., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0.,  [...]
+
+11., 0., 0., 4., 11., 2., 4., 2., 10., 29., 2., 18., 21., 0., 10., 1., 3., 0., 7., 1., 7., 22., 18., 33., 20., 6., 0., 1., 4., 1., 6., 10., 28., 15., 3., 19., 2., 14., 8., 2., 0., 4., 1., 8., 18., 23., 46., 9., 19., 4., 7., 1., 4., 2., 4., 1., 9., 4., 8., 17., 9., 21., 10., 1., 0., 0., 1., 0., 4., 4., 3., 3., 4., 7., 0., 5., 6., 1., 2., 1., 3., 0., 2., 0., 2., 8., 3., 6., 4., 3., 4., 0., 4., 1., 1., 7., 1., 0., 0., 6., 2., 0., 2., 2., 1., 1., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0 [...]
+
+4., 1., 3., 5., 11., 3., 13., 2., 9., 22., 3., 18., 25., 0., 16., 4., 2., 1., 36., 2., 2., 11., 11., 15., 25., 7., 1., 1., 3., 2., 8., 11., 23., 16., 2., 13., 3., 9., 5., 3., 0., 6., 3., 11., 11., 17., 57., 12., 23., 11., 2., 0., 5., 1., 6., 3., 10., 4., 7., 15., 4., 23., 8., 5., 3., 0., 3., 1., 5., 3., 7., 1., 5., 2., 3., 2., 0., 2., 1., 1., 2., 0., 1., 0., 4., 11., 2., 3., 0., 2., 1., 2., 4., 0., 1., 6., 3., 0., 2., 1., 0., 2., 0., 3., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0. [...]
+
+9., 1., 5., 5., 8., 3., 5., 1., 6., 27., 2., 14., 14., 1., 17., 2., 1., 1., 24., 3., 4., 13., 19., 27., 32., 2., 1., 0., 4., 3., 5., 9., 21., 17., 1., 24., 4., 15., 9., 2., 0., 5., 4., 14., 14., 22., 41., 15., 23., 10., 3., 1., 3., 2., 9., 4., 11., 8., 9., 21., 5., 22., 7., 2., 1., 2., 7., 2., 1., 2., 5., 7., 2., 4., 1., 3., 4., 2., 1., 0., 0., 0., 5., 2., 0., 9., 1., 4., 4., 3., 1., 1., 3., 1., 2., 11., 4., 0., 2., 2., 1., 0., 1., 3., 1., 0., 4., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0.,  [...]
+
+7., 4., 5., 9., 9., 5., 3., 1., 4., 24., 0., 11., 14., 0., 17., 0., 0., 0., 18., 4., 10., 27., 11., 23., 24., 5., 0., 0., 3., 1., 7., 4., 29., 14., 6., 13., 4., 8., 6., 1., 1., 3., 2., 13., 5., 19., 33., 10., 25., 9., 3., 1., 6., 1., 7., 2., 14., 10., 4., 13., 4., 18., 3., 1., 1., 1., 2., 1., 2., 3., 8., 2., 2., 5., 3., 3., 2., 4., 2., 4., 5., 0., 4., 1., 1., 6., 3., 4., 1., 1., 6., 1., 0., 0., 1., 1., 1., 0., 2., 2., 0., 2., 3., 2., 1., 0., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0. [...]
+
+6., 1., 3., 3., 7., 2., 7., 0., 5., 35., 1., 13., 20., 0., 12., 2., 0., 4., 6., 1., 3., 16., 6., 25., 26., 3., 0., 2., 5., 4., 7., 1., 34., 13., 3., 11., 3., 14., 6., 3., 0., 8., 4., 17., 13., 18., 38., 16., 28., 5., 6., 3., 11., 3., 9., 4., 10., 9., 14., 19., 4., 17., 11., 3., 0., 0., 5., 0., 4., 0., 2., 2., 5., 2., 3., 6., 3., 2., 1., 0., 1., 0., 3., 4., 0., 8., 6., 4., 2., 0., 3., 0., 6., 0., 4., 5., 1., 0., 2., 4., 3., 4., 1., 1., 2., 0., 5., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0 [...]
+
+9., 0., 0., 2., 13., 2., 3., 0., 7., 19., 2., 17., 17., 0., 16., 3., 1., 2., 13., 0., 5., 27., 13., 18., 27., 5., 1., 6., 2., 4., 2., 9., 21., 22., 2., 15., 4., 10., 9., 4., 1., 5., 3., 14., 11., 13., 44., 10., 26., 9., 2., 0., 5., 2., 5., 5., 12., 3., 9., 12., 4., 19., 9., 3., 0., 1., 9., 1., 5., 3., 5., 3., 3., 1., 3., 6., 3., 0., 0., 1., 2., 0., 2., 1., 3., 5., 0., 2., 2., 1., 5., 0., 2., 1., 4., 7., 3., 0., 3., 1., 2., 2., 1., 0., 2., 1., 0., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0 [...]
+
+8., 1., 1., 6., 8., 1., 7., 1., 3., 13., 0., 23., 17., 1., 16., 4., 3., 4., 5., 2., 4., 23., 13., 17., 23., 7., 2., 2., 1., 2., 12., 7., 25., 18., 5., 20., 4., 11., 11., 1., 2., 2., 1., 15., 9., 16., 63., 9., 26., 10., 8., 0., 7., 3., 5., 3., 6., 6., 5., 15., 5., 22., 8., 2., 1., 2., 10., 1., 4., 4., 9., 1., 5., 8., 3., 4., 4., 5., 0., 2., 2., 0., 3., 0., 0., 7., 1., 3., 0., 1., 5., 0., 4., 1., 2., 1., 2., 0., 1., 3., 1., 3., 3., 3., 2., 0., 2., 0., 0., 0., 0., 4., 0., 0., 0., 0., 0., 0. [...]
+
+7., 1., 1., 3., 5., 3., 8., 1., 1., 16., 0., 15., 26., 1., 17., 2., 0., 1., 18., 0., 2., 18., 5., 37., 28., 2., 2., 0., 6., 1., 9., 8., 36., 11., 2., 18., 6., 19., 14., 2., 1., 3., 0., 11., 13., 11., 53., 12., 26., 15., 4., 0., 8., 3., 7., 0., 10., 5., 4., 18., 6., 18., 5., 2., 0., 1., 7., 2., 0., 1., 6., 0., 6., 3., 4., 13., 4., 0., 0., 2., 4., 0., 2., 3., 0., 11., 2., 6., 1., 2., 6., 1., 0., 0., 2., 5., 3., 0., 5., 1., 2., 3., 3., 2., 2., 1., 3., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., [...]
+
+13., 0., 1., 2., 6., 5., 6., 0., 6., 14., 0., 12., 12., 0., 16., 2., 1., 3., 33., 2., 4., 29., 6., 31., 25., 10., 0., 1., 1., 0., 5., 6., 27., 18., 2., 14., 1., 13., 11., 0., 1., 4., 2., 12., 14., 14., 51., 16., 18., 9., 1., 0., 4., 2., 6., 1., 10., 7., 9., 15., 5., 21., 5., 5., 0., 2., 9., 0., 1., 2., 7., 3., 8., 8., 4., 1., 8., 1., 2., 0., 1., 0., 1., 2., 3., 5., 2., 2., 4., 1., 3., 1., 2., 2., 5., 2., 2., 0., 2., 6., 1., 2., 3., 1., 2., 2., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.,  [...]
+
+4., 1., 0., 6., 5., 3., 5., 0., 4., 11., 2., 14., 15., 2., 26., 3., 2., 1., 4., 2., 1., 20., 15., 36., 27., 2., 0., 0., 3., 2., 8., 9., 19., 19., 2., 23., 5., 16., 5., 3., 1., 4., 1., 17., 19., 9., 47., 5., 17., 12., 2., 0., 4., 2., 5., 2., 12., 3., 10., 10., 7., 12., 6., 2., 0., 3., 11., 0., 3., 3., 7., 1., 1., 4., 2., 5., 2., 1., 2., 3., 4., 0., 1., 1., 3., 12., 4., 10., 0., 2., 1., 3., 3., 0., 4., 12., 1., 0., 3., 1., 4., 2., 1., 1., 2., 3., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., [...]
+
+6., 1., 3., 4., 12., 4., 8., 2., 7., 25., 2., 13., 27., 1., 10., 2., 2., 3., 13., 2., 3., 32., 9., 24., 27., 5., 0., 1., 6., 2., 7., 8., 20., 14., 5., 18., 6., 17., 8., 2., 1., 9., 2., 13., 11., 23., 42., 9., 21., 5., 2., 3., 2., 1., 4., 2., 9., 7., 14., 17., 5., 27., 4., 2., 0., 1., 9., 1., 2., 2., 6., 4., 2., 3., 2., 1., 3., 3., 0., 0., 2., 0., 2., 2., 3., 8., 1., 5., 0., 2., 4., 2., 1., 1., 3., 3., 2., 0., 1., 2., 2., 4., 2., 4., 2., 0., 1., 0., 0., 0., 0., 1., 0., 0., 4., 0., 0., 0., [...]
+
+11., 2., 1., 5., 8., 3., 11., 0., 7., 27., 1., 7., 26., 0., 16., 6., 1., 3., 31., 2., 3., 14., 11., 24., 32., 4., 2., 1., 4., 6., 3., 6., 28., 11., 3., 9., 3., 13., 10., 2., 2., 5., 3., 11., 9., 17., 44., 12., 20., 5., 3., 3., 6., 2., 4., 2., 13., 6., 11., 9., 4., 17., 8., 5., 1., 1., 12., 1., 1., 3., 5., 6., 1., 4., 1., 3., 2., 5., 1., 1., 3., 0., 2., 2., 3., 4., 1., 4., 3., 2., 7., 1., 3., 1., 4., 5., 4., 0., 4., 2., 2., 1., 1., 1., 3., 0., 2., 0., 0., 0., 0., 2., 0., 0., 5., 0., 0., 0 [...]
+
+9., 2., 1., 4., 9., 2., 6., 2., 4., 24., 3., 13., 21., 1., 18., 2., 0., 3., 16., 0., 6., 23., 6., 21., 22., 7., 0., 1., 4., 3., 8., 11., 27., 17., 3., 11., 6., 17., 8., 3., 1., 4., 3., 10., 11., 19., 50., 13., 16., 13., 9., 0., 8., 1., 7., 2., 15., 7., 8., 18., 3., 33., 12., 3., 0., 1., 8., 2., 0., 2., 5., 2., 4., 4., 5., 5., 4., 1., 1., 2., 3., 0., 4., 2., 3., 5., 2., 4., 2., 2., 4., 0., 1., 0., 5., 5., 3., 0., 3., 3., 1., 4., 2., 2., 3., 4., 2., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0.,  [...]
+
+12., 0., 2., 2., 7., 2., 4., 0., 5., 27., 0., 9., 19., 0., 15., 1., 1., 3., 19., 4., 6., 27., 12., 32., 28., 7., 1., 0., 3., 1., 9., 9., 25., 17., 3., 17., 5., 9., 4., 2., 0., 6., 2., 11., 16., 19., 39., 13., 22., 11., 0., 1., 7., 2., 4., 5., 9., 2., 12., 21., 6., 29., 4., 7., 0., 2., 6., 2., 6., 2., 6., 3., 3., 3., 2., 2., 0., 1., 0., 4., 3., 0., 1., 3., 3., 6., 3., 8., 2., 4., 8., 0., 2., 0., 5., 2., 2., 0., 3., 2., 1., 3., 4., 1., 3., 0., 3., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0. [...]
+
+10., 0., 3., 1., 14., 5., 6., 0., 7., 10., 1., 11., 23., 4., 9., 2., 1., 3., 19., 2., 4., 35., 15., 31., 26., 7., 0., 1., 2., 1., 6., 2., 24., 21., 2., 20., 3., 17., 10., 4., 1., 11., 4., 7., 12., 23., 46., 11., 22., 7., 0., 0., 9., 4., 5., 2., 14., 8., 7., 18., 6., 14., 12., 5., 0., 3., 4., 2., 4., 2., 4., 5., 2., 5., 2., 5., 4., 7., 1., 1., 3., 0., 2., 0., 2., 6., 2., 6., 2., 1., 6., 0., 4., 1., 2., 5., 4., 0., 2., 1., 3., 5., 3., 0., 2., 0., 2., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., [...]
+
+13., 0., 2., 1., 6., 0., 22., 2., 7., 50., 0., 11., 79., 1., 8., 2., 0., 2., 79., 10., 5., 84., 14., 86., 17., 5., 0., 3., 2., 1., 15., 14., 54., 11., 4., 38., 27., 15., 4., 0., 1., 8., 2., 23., 6., 29., 4., 11., 7., 4., 4., 0., 10., 2., 13., 9., 14., 5., 9., 5., 6., 51., 3., 5., 3., 0., 12., 5., 9., 2., 13., 2., 3., 4., 2., 1., 0., 6., 2., 8., 17., 1., 2., 0., 3., 0., 0., 0., 0., 0., 6., 1., 4., 2., 3., 1., 3., 0., 1., 0., 3., 0., 1., 3., 2., 0., 2., 0., 4., 0., 0., 0., 0., 0., 1., 0.,  [...]
+
+5., 0., 3., 4., 12., 0., 14., 1., 12., 52., 1., 9., 63., 2., 7., 2., 0., 1., 66., 7., 13., 64., 6., 73., 15., 2., 0., 4., 2., 1., 12., 13., 68., 12., 2., 35., 36., 13., 6., 0., 1., 2., 4., 23., 3., 20., 5., 9., 7., 2., 2., 0., 9., 3., 14., 9., 15., 3., 5., 5., 5., 47., 9., 5., 4., 0., 7., 8., 5., 2., 15., 1., 2., 1., 0., 2., 0., 7., 3., 18., 14., 0., 2., 2., 5., 0., 0., 0., 0., 0., 6., 1., 4., 2., 2., 1., 3., 0., 1., 0., 2., 0., 1., 2., 2., 0., 0., 0., 0., 0., 1., 0., 0., 0., 2., 0., 3., [...]
+
+4., 1., 1., 3., 12., 0., 11., 3., 8., 68., 0., 11., 59., 0., 2., 2., 0., 0., 69., 6., 13., 92., 23., 74., 14., 7., 0., 3., 4., 2., 13., 9., 57., 13., 3., 37., 45., 12., 1., 0., 1., 3., 5., 22., 5., 22., 4., 11., 5., 4., 1., 0., 11., 2., 10., 9., 16., 2., 12., 3., 3., 49., 6., 6., 0., 0., 15., 7., 8., 3., 10., 5., 4., 2., 2., 1., 0., 12., 1., 15., 7., 2., 2., 3., 0., 0., 0., 0., 0., 0., 10., 2., 1., 2., 2., 4., 1., 0., 1., 0., 1., 0., 0., 5., 0., 0., 0., 0., 1., 0., 2., 0., 0., 0., 1., 0. [...]
+
+15., 4., 3., 10., 26., 7., 47., 1., 19., 163., 6., 28., 181., 6., 29., 4., 2., 2., 75., 1., 20., 283., 39., 299., 48., 17., 0., 3., 9., 4., 56., 36., 250., 42., 8., 175., 18., 35., 7., 0., 2., 16., 9., 86., 21., 96., 9., 44., 41., 14., 3., 1., 31., 7., 29., 13., 46., 8., 30., 5., 11., 4., 1., 0., 0., 0., 28., 6., 14., 2., 20., 2., 9., 6., 1., 2., 0., 1., 1., 5., 8., 2., 5., 1., 2., 0., 0., 4., 140., 10., 1854., 82., 101., 213., 104., 116., 62., 14., 13., 18., 13., 0., 5., 5., 7., 4., 9., [...]
+
+11., 1., 0., 6., 14., 5., 31., 0., 19., 156., 2., 27., 204., 3., 15., 1., 1., 5., 88., 0., 9., 290., 50., 298., 26., 12., 4., 0., 7., 4., 41., 30., 222., 39., 11., 152., 13., 39., 7., 0., 3., 16., 13., 81., 24., 111., 20., 37., 22., 12., 5., 0., 32., 11., 46., 9., 40., 6., 34., 3., 10., 8., 2., 0., 0., 0., 27., 5., 5., 2., 24., 6., 12., 3., 0., 2., 0., 0., 5., 0., 7., 5., 12., 0., 8., 2., 2., 2., 157., 9., 1902., 77., 96., 206., 91., 119., 72., 16., 12., 17., 22., 0., 2., 9., 4., 4., 6., [...]
+
+14., 3., 4., 8., 19., 2., 31., 0., 13., 162., 1., 27., 202., 5., 15., 7., 1., 3., 99., 0., 31., 290., 46., 363., 54., 19., 1., 3., 6., 4., 50., 27., 208., 56., 4., 176., 11., 31., 7., 0., 1., 10., 11., 78., 21., 95., 7., 41., 56., 8., 4., 1., 16., 9., 42., 10., 49., 7., 32., 10., 8., 5., 2., 0., 1., 0., 20., 6., 9., 4., 31., 10., 7., 3., 2., 1., 3., 0., 5., 2., 10., 3., 4., 7., 6., 1., 1., 6., 125., 12., 1767., 87., 94., 229., 92., 126., 74., 15., 12., 15., 19., 1., 2., 9., 2., 4., 8., 1 [...]
+
+15., 1., 1., 8., 25., 5., 36., 3., 9., 188., 8., 27., 203., 4., 16., 6., 1., 5., 67., 2., 30., 293., 55., 306., 32., 20., 2., 1., 6., 8., 43., 33., 233., 43., 11., 172., 9., 38., 11., 0., 2., 22., 8., 74., 14., 95., 12., 36., 37., 17., 3., 2., 27., 7., 35., 5., 38., 9., 28., 6., 9., 4., 4., 0., 1., 0., 22., 5., 11., 0., 48., 1., 5., 3., 0., 2., 2., 2., 2., 1., 15., 4., 13., 2., 15., 0., 1., 4., 136., 9., 1915., 79., 76., 225., 106., 104., 56., 30., 6., 18., 12., 0., 1., 8., 10., 3., 12., [...]
+
+12., 1., 3., 12., 24., 2., 23., 0., 19., 140., 2., 23., 211., 7., 19., 2., 1., 4., 73., 1., 5., 309., 53., 316., 39., 18., 0., 1., 8., 8., 38., 29., 240., 30., 11., 151., 15., 43., 4., 0., 2., 13., 4., 66., 13., 103., 14., 38., 35., 4., 0., 0., 35., 8., 45., 12., 51., 14., 35., 8., 10., 7., 2., 0., 0., 0., 23., 6., 15., 1., 38., 5., 11., 5., 2., 3., 3., 0., 3., 1., 11., 3., 12., 0., 7., 0., 0., 6., 135., 12., 1918., 86., 98., 193., 95., 106., 83., 10., 11., 19., 10., 2., 5., 8., 5., 7.,  [...]
+
+15., 2., 0., 10., 27., 9., 40., 2., 21., 176., 4., 30., 208., 8., 15., 3., 0., 8., 70., 2., 12., 275., 39., 311., 43., 10., 0., 0., 7., 5., 43., 34., 268., 30., 11., 165., 18., 37., 5., 0., 0., 20., 9., 77., 21., 102., 14., 37., 46., 13., 2., 1., 24., 1., 42., 10., 46., 7., 32., 3., 8., 7., 4., 0., 0., 0., 25., 4., 23., 6., 19., 10., 10., 3., 2., 2., 0., 1., 1., 0., 11., 0., 12., 4., 9., 1., 1., 5., 150., 14., 1864., 90., 94., 231., 108., 103., 62., 16., 9., 18., 8., 0., 0., 3., 5., 4.,  [...]
+
+8., 3., 1., 9., 11., 4., 7., 2., 8., 29., 1., 2., 22., 3., 9., 5., 2., 2., 17., 8., 8., 23., 16., 33., 29., 6., 4., 0., 2., 3., 10., 4., 15., 17., 7., 16., 4., 17., 11., 5., 2., 7., 2., 6., 13., 23., 58., 9., 23., 6., 6., 4., 6., 0., 7., 4., 8., 5., 8., 20., 6., 21., 13., 4., 3., 2., 5., 2., 7., 1., 4., 6., 4., 4., 1., 2., 6., 3., 2., 6., 5., 0., 1., 1., 2., 6., 1., 2., 0., 2., 0., 1., 4., 3., 1., 14., 0., 0., 1., 3., 2., 1., 2., 0., 1., 2., 2., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0. [...]
+
+11., 1., 1., 1., 6., 5., 7., 0., 10., 14., 1., 15., 30., 1., 18., 2., 2., 1., 19., 3., 6., 18., 15., 15., 29., 5., 0., 2., 2., 1., 6., 9., 21., 21., 0., 23., 5., 11., 11., 2., 2., 4., 2., 6., 6., 21., 42., 11., 18., 4., 8., 1., 2., 6., 5., 1., 17., 11., 8., 22., 4., 20., 9., 2., 3., 2., 16., 2., 2., 1., 4., 4., 2., 6., 2., 2., 3., 3., 0., 2., 0., 0., 1., 1., 4., 9., 1., 0., 1., 2., 4., 2., 3., 2., 3., 3., 4., 0., 1., 1., 0., 2., 1., 4., 1., 1., 2., 0., 0., 0., 0., 1., 0., 0., 5., 0., 0., [...]
+
+12., 2., 2., 7., 2., 4., 6., 1., 7., 17., 2., 14., 14., 0., 20., 4., 2., 2., 24., 1., 4., 23., 14., 17., 24., 4., 1., 0., 3., 2., 8., 9., 23., 17., 4., 13., 3., 18., 7., 3., 2., 5., 0., 14., 8., 13., 39., 9., 26., 7., 3., 0., 4., 1., 8., 0., 9., 8., 4., 16., 7., 18., 10., 4., 1., 2., 0., 3., 2., 4., 6., 7., 6., 3., 1., 3., 1., 4., 0., 3., 1., 0., 3., 0., 3., 3., 2., 6., 3., 1., 5., 2., 2., 0., 2., 3., 3., 0., 1., 1., 1., 2., 3., 2., 1., 1., 2., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0., [...]
+
+3., 3., 2., 9., 9., 1., 7., 1., 5., 10., 0., 12., 11., 2., 12., 4., 1., 2., 3., 2., 4., 24., 14., 24., 25., 8., 1., 2., 2., 0., 12., 6., 24., 19., 4., 20., 7., 21., 8., 2., 1., 6., 1., 6., 18., 24., 64., 10., 16., 13., 1., 0., 7., 0., 10., 2., 7., 9., 6., 20., 6., 24., 6., 2., 1., 0., 4., 0., 3., 1., 6., 4., 6., 2., 1., 6., 1., 1., 2., 1., 3., 0., 4., 2., 2., 6., 0., 4., 1., 3., 2., 0., 2., 1., 2., 8., 1., 0., 0., 1., 1., 0., 1., 3., 3., 1., 6., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0. [...]
+
+13., 0., 3., 2., 9., 3., 6., 1., 6., 20., 3., 20., 36., 3., 24., 3., 1., 4., 16., 1., 6., 23., 9., 20., 23., 2., 2., 1., 3., 1., 6., 9., 33., 18., 11., 21., 1., 21., 6., 4., 0., 3., 3., 12., 9., 22., 44., 13., 25., 10., 7., 2., 2., 1., 5., 3., 3., 5., 7., 17., 4., 23., 15., 6., 3., 0., 7., 0., 3., 3., 3., 7., 2., 3., 2., 8., 1., 2., 1., 2., 1., 0., 2., 4., 2., 5., 2., 7., 0., 3., 2., 2., 1., 1., 2., 5., 2., 0., 0., 2., 2., 1., 2., 1., 1., 0., 3., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0 [...]
+
+7., 2., 1., 7., 9., 6., 8., 0., 6., 28., 1., 12., 24., 1., 12., 6., 1., 2., 11., 0., 5., 18., 16., 13., 31., 7., 2., 2., 3., 4., 5., 4., 13., 18., 3., 15., 4., 12., 6., 3., 0., 1., 1., 10., 7., 18., 46., 13., 14., 4., 3., 0., 9., 2., 4., 5., 13., 5., 9., 16., 8., 13., 9., 4., 1., 0., 12., 0., 4., 4., 9., 0., 3., 3., 0., 2., 1., 1., 0., 0., 3., 0., 1., 0., 4., 9., 3., 6., 2., 2., 7., 1., 4., 0., 5., 3., 1., 0., 2., 7., 4., 2., 2., 0., 2., 0., 3., 0., 0., 0., 0., 5., 0., 0., 1., 0., 0., 0. [...]
+
+10., 0., 2., 4., 2., 4., 3., 2., 7., 12., 1., 15., 23., 0., 19., 7., 1., 5., 17., 3., 3., 21., 20., 10., 39., 6., 0., 0., 1., 2., 7., 3., 37., 23., 2., 6., 7., 20., 8., 1., 2., 4., 2., 5., 9., 12., 41., 13., 20., 11., 5., 3., 5., 2., 7., 1., 13., 4., 11., 20., 6., 24., 9., 3., 2., 2., 10., 1., 1., 3., 4., 0., 6., 1., 1., 3., 6., 3., 1., 1., 4., 0., 1., 1., 1., 5., 1., 8., 1., 0., 5., 2., 2., 1., 4., 7., 2., 0., 1., 1., 2., 0., 5., 4., 3., 0., 2., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0 [...]
+
+12., 0., 0., 8., 3., 3., 3., 0., 4., 18., 1., 17., 23., 1., 10., 3., 3., 0., 14., 2., 7., 18., 14., 38., 24., 13., 3., 0., 5., 2., 7., 7., 46., 20., 3., 10., 4., 21., 16., 2., 1., 5., 0., 16., 8., 20., 52., 15., 28., 15., 4., 0., 5., 2., 10., 4., 12., 5., 7., 17., 8., 25., 10., 4., 1., 2., 11., 0., 3., 0., 2., 3., 7., 5., 2., 4., 4., 1., 4., 1., 3., 0., 6., 2., 2., 2., 0., 3., 1., 1., 2., 1., 1., 1., 3., 8., 1., 0., 1., 0., 3., 1., 3., 1., 4., 4., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0.,  [...]
+
+4., 3., 5., 2., 6., 1., 5., 1., 6., 14., 0., 19., 26., 0., 14., 6., 0., 3., 29., 1., 6., 29., 12., 26., 20., 4., 0., 0., 2., 1., 12., 6., 33., 18., 3., 17., 4., 13., 5., 1., 1., 2., 3., 10., 10., 24., 42., 12., 23., 11., 4., 2., 4., 2., 7., 6., 11., 6., 9., 17., 7., 22., 10., 1., 1., 2., 9., 2., 2., 2., 5., 2., 1., 8., 2., 2., 3., 3., 0., 2., 3., 0., 1., 4., 4., 11., 4., 7., 2., 3., 7., 2., 2., 2., 4., 8., 3., 0., 3., 0., 0., 1., 4., 4., 0., 1., 0., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0. [...]
+
+8., 0., 1., 4., 5., 3., 2., 1., 6., 28., 2., 19., 21., 1., 13., 1., 1., 4., 22., 0., 6., 30., 13., 19., 28., 11., 1., 3., 1., 2., 8., 5., 23., 23., 2., 20., 3., 10., 6., 2., 1., 4., 0., 10., 8., 15., 51., 13., 15., 4., 3., 2., 3., 1., 10., 3., 8., 6., 13., 17., 7., 20., 8., 3., 0., 0., 8., 0., 5., 3., 5., 4., 2., 5., 0., 1., 4., 2., 1., 2., 1., 0., 4., 3., 2., 7., 3., 3., 3., 7., 7., 3., 4., 2., 2., 7., 2., 0., 0., 0., 5., 4., 0., 1., 3., 0., 3., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0 [...]
+
+6., 0., 4., 4., 9., 3., 6., 0., 8., 28., 0., 15., 23., 1., 14., 1., 0., 2., 18., 3., 4., 15., 11., 27., 32., 8., 0., 3., 5., 3., 9., 8., 27., 18., 5., 13., 5., 11., 8., 1., 1., 4., 4., 15., 13., 10., 40., 7., 16., 7., 7., 3., 5., 1., 7., 3., 6., 8., 10., 14., 6., 21., 4., 5., 1., 1., 7., 0., 3., 0., 7., 1., 5., 0., 2., 5., 3., 4., 0., 2., 2., 0., 4., 0., 3., 6., 2., 3., 3., 0., 5., 1., 1., 1., 1., 7., 2., 0., 1., 2., 1., 0., 4., 2., 2., 2., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., [...]
+
+9., 0., 3., 2., 0., 2., 9., 1., 7., 14., 0., 6., 29., 1., 16., 3., 0., 4., 15., 1., 1., 28., 10., 11., 27., 3., 0., 1., 2., 1., 10., 5., 27., 12., 1., 8., 2., 14., 12., 2., 1., 4., 1., 16., 11., 25., 51., 14., 24., 5., 4., 0., 5., 1., 6., 1., 5., 8., 9., 13., 7., 25., 5., 1., 1., 3., 8., 1., 0., 2., 6., 3., 12., 1., 3., 6., 3., 4., 0., 2., 1., 0., 1., 3., 1., 5., 1., 7., 3., 1., 5., 1., 0., 1., 1., 6., 0., 0., 1., 0., 2., 1., 3., 2., 1., 1., 2., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0. [...]
+
+8., 2., 2., 9., 13., 1., 5., 1., 11., 27., 0., 9., 24., 2., 12., 1., 0., 1., 13., 2., 5., 18., 14., 25., 23., 10., 0., 0., 1., 3., 11., 12., 33., 13., 4., 16., 2., 6., 9., 2., 0., 3., 4., 6., 15., 21., 40., 9., 19., 11., 1., 1., 0., 3., 7., 4., 10., 6., 10., 14., 8., 27., 9., 2., 1., 2., 6., 0., 3., 4., 3., 1., 8., 4., 1., 4., 1., 2., 2., 3., 4., 0., 1., 2., 2., 4., 2., 3., 2., 8., 6., 0., 2., 1., 3., 8., 1., 0., 0., 2., 3., 0., 1., 0., 1., 3., 3., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., [...]
+
+12., 2., 3., 4., 12., 1., 5., 1., 8., 27., 1., 6., 30., 4., 16., 4., 0., 1., 20., 1., 1., 34., 9., 26., 26., 1., 1., 0., 2., 0., 8., 4., 27., 19., 5., 15., 2., 14., 10., 3., 1., 4., 1., 6., 9., 17., 45., 15., 16., 9., 4., 1., 3., 4., 1., 3., 7., 7., 7., 14., 4., 22., 3., 2., 2., 2., 4., 3., 2., 3., 6., 7., 3., 9., 2., 3., 4., 2., 2., 1., 1., 0., 3., 1., 3., 3., 1., 7., 2., 4., 7., 3., 0., 0., 1., 7., 2., 0., 1., 1., 0., 2., 0., 0., 2., 2., 1., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.,  [...]
+
+7., 0., 1., 9., 10., 5., 3., 0., 5., 14., 0., 9., 24., 0., 15., 5., 3., 2., 9., 0., 8., 28., 17., 22., 37., 6., 1., 2., 3., 1., 8., 11., 22., 17., 6., 13., 2., 14., 7., 0., 2., 5., 2., 9., 10., 18., 52., 9., 17., 9., 5., 1., 5., 1., 11., 2., 14., 9., 13., 11., 11., 24., 9., 2., 0., 2., 12., 0., 1., 1., 6., 0., 1., 4., 0., 4., 2., 4., 0., 3., 2., 0., 1., 1., 4., 9., 3., 5., 3., 3., 5., 0., 3., 1., 2., 12., 1., 0., 2., 3., 2., 0., 3., 1., 3., 4., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., [...]
+
+2., 0., 2., 8., 11., 3., 4., 1., 11., 11., 0., 11., 19., 1., 12., 3., 1., 1., 16., 3., 5., 28., 11., 32., 32., 9., 0., 2., 1., 2., 9., 6., 19., 13., 1., 14., 2., 14., 9., 1., 2., 4., 3., 16., 6., 19., 54., 14., 11., 8., 7., 2., 6., 2., 9., 2., 12., 6., 9., 14., 4., 28., 14., 1., 0., 1., 10., 0., 1., 0., 1., 5., 3., 3., 1., 5., 3., 2., 2., 1., 1., 0., 4., 1., 0., 4., 1., 9., 3., 0., 3., 0., 2., 0., 2., 6., 3., 0., 2., 0., 2., 2., 2., 4., 2., 1., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., [...]
+
+11., 1., 1., 3., 7., 1., 9., 1., 4., 14., 1., 16., 22., 2., 7., 4., 1., 0., 15., 3., 4., 22., 18., 22., 19., 6., 0., 2., 3., 3., 12., 8., 16., 19., 4., 8., 4., 14., 14., 1., 1., 4., 4., 11., 18., 20., 37., 9., 24., 7., 3., 0., 6., 1., 6., 2., 8., 12., 6., 16., 5., 21., 11., 3., 0., 0., 6., 0., 4., 2., 2., 1., 4., 2., 1., 2., 3., 4., 1., 1., 1., 0., 2., 1., 2., 2., 4., 6., 0., 1., 3., 2., 2., 2., 1., 6., 0., 0., 1., 1., 1., 2., 1., 0., 2., 1., 0., 0., 0., 0., 0., 2., 0., 0., 6., 0., 0., 0 [...]
+
+6., 0., 0., 4., 11., 1., 3., 3., 6., 31., 1., 16., 20., 1., 12., 5., 1., 0., 17., 2., 6., 23., 17., 20., 23., 7., 1., 1., 3., 3., 2., 5., 34., 24., 2., 15., 4., 15., 5., 2., 1., 3., 3., 12., 18., 20., 59., 11., 20., 6., 1., 2., 4., 5., 4., 3., 8., 7., 10., 15., 7., 17., 6., 2., 3., 0., 8., 3., 2., 2., 4., 6., 3., 4., 3., 7., 3., 1., 2., 1., 1., 0., 1., 2., 2., 4., 2., 3., 2., 2., 2., 1., 2., 2., 4., 7., 1., 0., 6., 0., 1., 2., 2., 1., 3., 0., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0 [...]
+
+1., 1., 4., 2., 13., 2., 7., 1., 3., 18., 1., 8., 27., 2., 13., 4., 1., 4., 23., 2., 5., 17., 12., 31., 17., 6., 2., 3., 1., 3., 11., 4., 25., 15., 6., 14., 1., 13., 8., 3., 0., 5., 2., 9., 17., 14., 42., 13., 15., 9., 6., 1., 7., 1., 11., 2., 6., 8., 9., 16., 6., 23., 7., 4., 1., 1., 2., 1., 3., 0., 4., 3., 1., 5., 0., 6., 3., 0., 1., 2., 3., 0., 1., 4., 3., 7., 3., 5., 2., 2., 1., 0., 2., 0., 4., 6., 6., 0., 2., 1., 2., 4., 1., 5., 2., 1., 1., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0. [...]
+
+10., 0., 2., 1., 12., 5., 9., 0., 5., 34., 3., 14., 20., 1., 19., 1., 1., 2., 10., 3., 4., 12., 15., 27., 24., 4., 1., 0., 3., 3., 5., 5., 28., 23., 4., 8., 4., 9., 14., 1., 0., 4., 2., 14., 9., 14., 58., 17., 27., 6., 4., 1., 6., 2., 3., 4., 4., 5., 6., 14., 3., 18., 7., 7., 0., 0., 7., 0., 0., 1., 3., 1., 3., 4., 0., 2., 3., 2., 6., 5., 1., 0., 1., 0., 6., 6., 2., 4., 4., 0., 5., 0., 3., 1., 3., 8., 2., 0., 0., 1., 2., 2., 2., 3., 1., 1., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., [...]
+
+9., 3., 2., 3., 10., 2., 3., 2., 7., 14., 0., 15., 32., 2., 8., 2., 1., 2., 13., 3., 5., 24., 7., 31., 22., 5., 1., 0., 1., 2., 4., 3., 31., 19., 2., 17., 4., 14., 5., 1., 1., 2., 1., 9., 12., 16., 43., 13., 28., 7., 6., 1., 7., 1., 8., 0., 7., 2., 11., 12., 5., 20., 8., 3., 0., 1., 11., 0., 3., 1., 5., 3., 5., 6., 2., 4., 1., 5., 1., 2., 2., 0., 1., 1., 1., 5., 3., 3., 1., 1., 4., 1., 1., 1., 3., 9., 1., 0., 2., 1., 3., 1., 2., 1., 3., 1., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0., [...]
+
+3., 1., 3., 2., 9., 1., 4., 3., 6., 17., 0., 9., 24., 1., 12., 2., 0., 2., 16., 2., 5., 24., 7., 34., 27., 9., 1., 1., 4., 4., 4., 3., 34., 11., 3., 12., 5., 11., 6., 1., 1., 4., 0., 14., 14., 21., 47., 15., 17., 8., 3., 0., 2., 1., 12., 5., 14., 5., 9., 16., 4., 15., 12., 2., 6., 0., 11., 0., 2., 2., 3., 5., 5., 3., 3., 8., 1., 2., 0., 2., 0., 0., 1., 4., 3., 3., 3., 2., 2., 0., 0., 0., 4., 3., 2., 5., 2., 0., 2., 2., 1., 2., 1., 2., 2., 1., 3., 0., 0., 0., 0., 5., 0., 0., 1., 0., 0., 0 [...]
+
+8., 0., 1., 3., 9., 0., 14., 0., 8., 44., 1., 11., 66., 0., 5., 0., 0., 0., 74., 8., 10., 87., 15., 75., 11., 1., 0., 1., 7., 2., 10., 7., 46., 11., 3., 35., 22., 10., 5., 0., 2., 6., 2., 20., 6., 27., 6., 18., 1., 2., 3., 0., 13., 7., 15., 4., 10., 4., 4., 4., 6., 33., 12., 4., 2., 0., 9., 2., 12., 3., 14., 2., 3., 1., 1., 1., 0., 7., 2., 11., 9., 5., 2., 0., 1., 0., 0., 0., 0., 0., 10., 1., 2., 2., 4., 0., 2., 0., 1., 0., 0., 0., 0., 4., 2., 0., 3., 0., 0., 0., 0., 0., 0., 0., 1., 0.,  [...]
+
+3., 1., 3., 5., 2., 0., 18., 0., 10., 32., 1., 7., 43., 0., 7., 2., 0., 2., 69., 11., 7., 72., 16., 70., 12., 5., 0., 2., 1., 1., 13., 9., 48., 13., 4., 47., 30., 17., 4., 0., 2., 10., 3., 26., 8., 29., 10., 7., 10., 3., 1., 0., 17., 4., 19., 7., 16., 6., 11., 2., 2., 40., 6., 7., 2., 0., 14., 4., 8., 2., 10., 2., 2., 2., 1., 0., 0., 5., 5., 16., 10., 3., 9., 0., 2., 0., 0., 0., 0., 0., 9., 2., 3., 1., 5., 2., 2., 0., 0., 0., 0., 0., 2., 2., 2., 0., 4., 0., 0., 0., 2., 0., 0., 0., 0., 0. [...]
+
+3., 3., 6., 4., 17., 0., 12., 1., 12., 41., 1., 4., 52., 0., 7., 0., 0., 0., 76., 10., 4., 84., 14., 67., 17., 5., 0., 1., 0., 2., 10., 6., 55., 5., 2., 40., 31., 13., 9., 0., 0., 7., 2., 20., 3., 15., 10., 11., 10., 1., 2., 0., 11., 5., 13., 5., 18., 4., 5., 2., 1., 38., 13., 5., 1., 0., 11., 4., 10., 3., 15., 2., 5., 3., 2., 0., 0., 2., 2., 12., 5., 5., 1., 2., 2., 0., 0., 0., 0., 0., 10., 2., 1., 2., 6., 1., 1., 0., 1., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0., 0., 0., 0., 0., 0., 0., 0 [...]
+
+13., 1., 2., 3., 10., 0., 8., 2., 6., 49., 0., 9., 63., 2., 4., 2., 0., 2., 55., 14., 7., 79., 20., 83., 10., 4., 0., 1., 2., 0., 14., 10., 47., 20., 4., 37., 28., 19., 7., 0., 0., 10., 3., 28., 5., 20., 3., 13., 3., 4., 1., 0., 7., 4., 16., 5., 13., 2., 5., 3., 3., 38., 11., 6., 3., 0., 17., 1., 8., 5., 8., 6., 7., 1., 0., 1., 0., 5., 2., 14., 6., 1., 3., 1., 5., 0., 0., 0., 0., 0., 13., 2., 1., 1., 1., 0., 1., 0., 1., 0., 0., 0., 1., 2., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0.,  [...]
+
+22., 2., 5., 9., 21., 7., 43., 0., 13., 154., 3., 26., 221., 5., 13., 12., 0., 3., 89., 1., 16., 297., 37., 341., 48., 24., 1., 1., 6., 5., 33., 29., 218., 43., 9., 143., 11., 33., 5., 0., 3., 15., 7., 76., 8., 105., 19., 34., 46., 14., 1., 1., 25., 5., 44., 9., 52., 15., 27., 8., 7., 4., 1., 0., 2., 0., 24., 6., 11., 1., 30., 7., 11., 5., 1., 3., 0., 0., 5., 0., 6., 1., 5., 3., 2., 2., 3., 5., 135., 3., 1894., 88., 115., 204., 100., 103., 70., 16., 11., 17., 20., 1., 2., 11., 5., 5., 9. [...]
+
+23., 1., 1., 4., 22., 5., 35., 4., 17., 150., 2., 31., 210., 6., 20., 7., 0., 6., 67., 2., 11., 312., 55., 347., 38., 14., 2., 2., 10., 2., 38., 30., 247., 40., 6., 154., 16., 33., 4., 0., 3., 16., 9., 94., 25., 80., 14., 28., 42., 10., 8., 0., 31., 7., 44., 7., 50., 13., 33., 7., 7., 5., 3., 0., 0., 0., 28., 5., 12., 2., 27., 2., 12., 3., 0., 5., 2., 1., 3., 3., 5., 3., 8., 1., 8., 3., 2., 4., 141., 6., 1836., 91., 90., 206., 103., 122., 60., 10., 11., 14., 14., 1., 1., 7., 4., 0., 11., [...]
+
+15., 0., 1., 7., 22., 8., 38., 1., 13., 154., 6., 27., 201., 6., 12., 8., 1., 4., 76., 1., 17., 283., 60., 295., 37., 19., 2., 3., 10., 3., 42., 34., 226., 45., 9., 168., 8., 39., 7., 0., 2., 14., 4., 79., 19., 82., 16., 27., 45., 12., 3., 1., 26., 2., 43., 10., 45., 4., 32., 7., 12., 9., 1., 0., 0., 0., 28., 6., 9., 4., 30., 4., 14., 4., 2., 3., 1., 0., 6., 1., 12., 4., 8., 1., 5., 0., 2., 1., 149., 12., 1826., 86., 119., 223., 103., 111., 87., 16., 9., 8., 13., 1., 2., 8., 4., 3., 14., [...]
+
+19., 5., 3., 10., 30., 8., 30., 0., 13., 149., 2., 30., 188., 8., 22., 6., 1., 3., 63., 0., 16., 259., 51., 325., 48., 25., 2., 2., 8., 6., 42., 43., 222., 34., 4., 160., 14., 39., 4., 0., 1., 9., 4., 84., 25., 96., 13., 34., 47., 10., 3., 1., 24., 8., 51., 14., 47., 6., 34., 5., 13., 3., 2., 0., 2., 0., 19., 10., 9., 3., 39., 3., 11., 6., 3., 4., 0., 0., 2., 3., 8., 1., 6., 2., 5., 0., 1., 6., 137., 7., 1888., 87., 91., 231., 90., 112., 84., 29., 8., 21., 13., 3., 1., 5., 6., 3., 8., 9. [...]
+
+15., 2., 1., 11., 22., 6., 32., 0., 12., 144., 1., 22., 216., 4., 24., 8., 1., 3., 91., 1., 10., 310., 42., 325., 34., 24., 0., 4., 8., 3., 41., 32., 242., 47., 11., 162., 20., 39., 3., 0., 1., 10., 16., 81., 18., 82., 17., 37., 57., 11., 2., 3., 17., 4., 64., 5., 41., 11., 21., 5., 12., 4., 1., 0., 1., 0., 31., 4., 16., 2., 26., 5., 12., 6., 5., 3., 1., 0., 1., 4., 5., 1., 5., 2., 12., 0., 2., 6., 158., 10., 1888., 81., 98., 213., 101., 127., 68., 20., 9., 16., 14., 0., 1., 13., 3., 3., [...]
+
+14., 2., 3., 8., 6., 3., 8., 1., 5., 2., 1., 16., 22., 2., 13., 2., 1., 0., 20., 0., 3., 21., 9., 30., 27., 4., 0., 0., 1., 2., 7., 8., 14., 22., 0., 13., 2., 23., 8., 2., 1., 2., 3., 11., 16., 13., 51., 14., 24., 6., 5., 1., 4., 1., 6., 6., 10., 6., 6., 16., 2., 18., 5., 3., 0., 0., 8., 0., 4., 3., 6., 7., 3., 7., 1., 3., 1., 1., 1., 2., 0., 0., 2., 1., 1., 4., 2., 3., 0., 3., 3., 2., 1., 0., 3., 8., 0., 0., 2., 1., 2., 3., 1., 4., 0., 2., 7., 0., 0., 0., 0., 5., 0., 0., 2., 0., 0., 0., [...]
+
+6., 0., 4., 4., 10., 1., 5., 2., 4., 16., 0., 12., 36., 3., 17., 2., 4., 3., 25., 2., 1., 12., 8., 17., 25., 9., 0., 3., 6., 2., 8., 5., 30., 13., 2., 17., 0., 15., 9., 1., 2., 3., 2., 14., 20., 21., 46., 13., 16., 7., 1., 2., 4., 0., 8., 7., 13., 6., 13., 14., 1., 20., 10., 3., 1., 0., 2., 2., 2., 2., 7., 3., 4., 2., 1., 6., 1., 1., 1., 0., 1., 0., 3., 5., 0., 6., 2., 2., 4., 1., 5., 3., 4., 2., 4., 9., 3., 0., 1., 0., 2., 8., 2., 1., 2., 3., 0., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0.,  [...]
+
+11., 0., 1., 6., 6., 6., 4., 1., 4., 19., 0., 14., 22., 1., 21., 2., 2., 1., 26., 1., 5., 16., 16., 28., 25., 4., 0., 2., 3., 1., 9., 12., 18., 18., 7., 22., 6., 12., 7., 1., 1., 2., 1., 8., 9., 16., 49., 11., 19., 7., 6., 2., 3., 3., 11., 4., 9., 6., 6., 11., 10., 25., 9., 3., 2., 0., 7., 1., 2., 1., 6., 1., 4., 5., 1., 4., 5., 2., 0., 1., 2., 0., 0., 1., 0., 3., 3., 3., 2., 0., 2., 1., 1., 4., 1., 9., 2., 0., 1., 4., 3., 0., 2., 3., 2., 0., 1., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0 [...]
+
+6., 1., 0., 2., 5., 3., 8., 0., 9., 16., 1., 14., 14., 3., 21., 8., 0., 0., 17., 3., 4., 19., 9., 27., 25., 6., 2., 1., 2., 0., 8., 8., 22., 11., 3., 12., 2., 17., 5., 3., 1., 3., 0., 17., 14., 17., 43., 16., 15., 11., 2., 0., 3., 2., 7., 2., 10., 4., 7., 14., 6., 22., 5., 3., 0., 3., 6., 0., 3., 2., 3., 5., 3., 5., 4., 1., 4., 2., 0., 0., 3., 0., 2., 9., 0., 9., 3., 1., 0., 0., 4., 1., 2., 0., 2., 4., 3., 0., 1., 0., 2., 2., 2., 5., 1., 0., 0., 0., 0., 0., 0., 3., 0., 0., 0., 0., 0., 0. [...]
+
+8., 0., 1., 4., 7., 1., 8., 0., 6., 22., 0., 12., 28., 2., 10., 5., 2., 0., 13., 0., 7., 15., 13., 25., 22., 10., 1., 0., 1., 3., 5., 7., 23., 16., 5., 9., 1., 14., 7., 3., 2., 8., 2., 14., 13., 25., 41., 17., 16., 12., 4., 1., 2., 3., 8., 2., 10., 9., 2., 18., 7., 33., 8., 3., 3., 1., 10., 2., 3., 2., 7., 4., 1., 5., 1., 3., 2., 3., 2., 0., 7., 0., 2., 3., 2., 7., 3., 5., 1., 4., 6., 0., 0., 1., 3., 8., 4., 0., 1., 2., 2., 0., 0., 1., 0., 0., 3., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0.,  [...]
+
+6., 0., 3., 2., 15., 4., 8., 0., 5., 22., 1., 15., 12., 0., 10., 3., 5., 4., 16., 1., 2., 13., 13., 33., 34., 4., 0., 0., 4., 1., 17., 11., 23., 16., 5., 15., 3., 13., 16., 1., 0., 2., 0., 11., 10., 9., 43., 13., 28., 9., 3., 1., 3., 2., 5., 4., 12., 5., 6., 20., 5., 23., 11., 6., 1., 2., 5., 3., 0., 0., 4., 3., 4., 5., 2., 4., 1., 3., 1., 0., 2., 0., 1., 1., 1., 6., 3., 4., 2., 2., 5., 2., 2., 1., 5., 7., 3., 0., 5., 3., 4., 2., 0., 2., 0., 0., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0. [...]
+
+12., 2., 4., 2., 6., 2., 5., 2., 3., 34., 0., 12., 28., 0., 19., 1., 1., 3., 20., 2., 7., 14., 13., 21., 40., 5., 2., 3., 6., 3., 5., 8., 33., 25., 4., 16., 1., 19., 8., 2., 0., 2., 1., 13., 13., 9., 45., 13., 15., 6., 0., 2., 8., 2., 4., 0., 8., 6., 15., 10., 6., 28., 4., 4., 2., 2., 3., 2., 5., 2., 6., 2., 3., 4., 2., 2., 3., 1., 2., 5., 4., 0., 2., 0., 2., 4., 4., 2., 3., 4., 5., 2., 1., 0., 4., 8., 0., 0., 2., 3., 2., 2., 1., 3., 3., 1., 4., 0., 0., 0., 0., 5., 0., 0., 1., 0., 0., 0. [...]
+
+2., 0., 4., 7., 6., 2., 5., 2., 5., 16., 1., 9., 25., 0., 22., 4., 0., 2., 28., 1., 1., 29., 9., 31., 21., 8., 1., 1., 3., 0., 11., 4., 25., 15., 4., 12., 6., 18., 8., 2., 1., 1., 4., 10., 10., 17., 42., 13., 18., 16., 2., 1., 2., 1., 5., 4., 9., 3., 11., 18., 10., 25., 10., 0., 1., 2., 9., 1., 6., 1., 2., 5., 7., 4., 2., 2., 4., 3., 1., 0., 2., 0., 1., 0., 4., 10., 3., 4., 5., 1., 5., 1., 2., 0., 2., 3., 2., 0., 1., 7., 3., 0., 1., 0., 2., 0., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., [...]
+
+11., 4., 3., 4., 3., 1., 9., 0., 8., 16., 0., 15., 20., 0., 20., 3., 0., 3., 14., 0., 5., 32., 10., 22., 25., 7., 1., 0., 4., 2., 14., 6., 21., 17., 6., 15., 5., 14., 11., 0., 1., 7., 3., 8., 11., 16., 53., 8., 18., 13., 4., 1., 5., 4., 7., 4., 3., 3., 7., 14., 4., 27., 5., 4., 1., 0., 5., 2., 4., 3., 2., 3., 2., 1., 1., 2., 0., 3., 0., 2., 0., 0., 2., 3., 1., 8., 1., 2., 0., 3., 1., 0., 2., 1., 1., 7., 4., 0., 2., 1., 2., 1., 3., 0., 1., 1., 1., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., 0 [...]
+
+8., 3., 0., 6., 10., 2., 6., 2., 3., 27., 1., 14., 11., 0., 17., 4., 1., 4., 12., 0., 5., 20., 13., 31., 20., 3., 0., 0., 5., 1., 10., 8., 11., 19., 0., 9., 4., 15., 9., 1., 1., 5., 6., 6., 13., 15., 35., 16., 17., 7., 4., 2., 3., 5., 6., 3., 7., 2., 7., 17., 3., 18., 6., 2., 1., 1., 4., 0., 5., 3., 2., 1., 5., 6., 3., 3., 3., 2., 4., 1., 2., 0., 2., 4., 3., 7., 1., 1., 2., 2., 6., 2., 5., 0., 3., 13., 2., 0., 2., 0., 2., 1., 4., 1., 3., 1., 4., 0., 0., 0., 0., 4., 0., 0., 4., 0., 0., 0. [...]
+
+11., 0., 0., 6., 11., 2., 4., 0., 5., 11., 2., 13., 25., 1., 12., 4., 3., 1., 13., 3., 4., 34., 14., 32., 29., 13., 1., 0., 2., 3., 9., 10., 28., 13., 2., 14., 3., 8., 5., 2., 1., 4., 2., 11., 15., 20., 37., 14., 24., 14., 3., 2., 1., 3., 10., 1., 7., 5., 9., 14., 8., 18., 8., 1., 0., 1., 8., 0., 2., 2., 5., 2., 5., 2., 4., 3., 1., 0., 0., 1., 2., 0., 3., 9., 1., 2., 0., 4., 2., 1., 5., 1., 3., 4., 1., 12., 3., 0., 4., 3., 2., 2., 1., 1., 1., 0., 3., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0 [...]
+
+13., 0., 0., 1., 3., 1., 7., 0., 5., 28., 2., 17., 18., 1., 12., 3., 2., 2., 24., 7., 2., 23., 6., 27., 24., 5., 0., 1., 0., 2., 8., 12., 17., 10., 1., 9., 6., 10., 7., 3., 1., 3., 2., 9., 13., 13., 41., 7., 23., 9., 6., 1., 8., 3., 12., 2., 7., 8., 6., 12., 2., 16., 14., 4., 1., 0., 8., 1., 3., 1., 7., 5., 3., 8., 4., 2., 3., 0., 0., 3., 3., 0., 4., 3., 1., 6., 2., 7., 4., 3., 1., 0., 4., 0., 3., 6., 3., 0., 3., 3., 2., 2., 1., 2., 3., 2., 2., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., 0., [...]
+
+15., 0., 2., 1., 5., 5., 10., 0., 5., 17., 1., 8., 14., 0., 25., 3., 0., 4., 10., 0., 5., 29., 12., 27., 21., 6., 0., 0., 4., 2., 6., 3., 21., 21., 2., 22., 2., 16., 7., 2., 1., 3., 2., 12., 14., 16., 37., 14., 20., 8., 5., 1., 3., 2., 7., 2., 13., 4., 13., 10., 7., 20., 10., 1., 0., 0., 4., 2., 3., 0., 3., 5., 1., 6., 8., 5., 3., 1., 1., 1., 2., 0., 1., 0., 3., 6., 0., 8., 1., 1., 5., 0., 5., 2., 3., 4., 0., 0., 6., 1., 1., 2., 1., 2., 3., 0., 3., 0., 0., 0., 0., 4., 0., 0., 1., 0., 0., [...]
+
+5., 1., 1., 3., 9., 2., 5., 0., 3., 15., 2., 9., 13., 0., 9., 1., 0., 2., 19., 4., 1., 27., 10., 28., 28., 8., 0., 2., 5., 1., 4., 6., 28., 10., 2., 12., 3., 11., 13., 4., 1., 1., 4., 13., 7., 15., 43., 12., 25., 10., 1., 2., 8., 4., 5., 2., 11., 9., 8., 17., 7., 29., 5., 4., 3., 0., 6., 0., 1., 3., 8., 0., 4., 4., 1., 6., 4., 2., 1., 3., 0., 0., 4., 3., 1., 6., 1., 5., 4., 0., 2., 2., 0., 2., 3., 7., 3., 0., 2., 3., 1., 2., 3., 1., 3., 0., 1., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0., [...]
+
+9., 0., 1., 1., 8., 4., 8., 1., 7., 24., 3., 9., 23., 0., 16., 2., 0., 1., 10., 3., 5., 37., 12., 24., 19., 5., 0., 2., 1., 2., 7., 9., 22., 18., 3., 14., 1., 15., 9., 1., 3., 1., 2., 10., 9., 15., 41., 10., 29., 9., 6., 2., 5., 2., 6., 3., 13., 8., 12., 15., 11., 18., 8., 4., 0., 0., 11., 0., 7., 1., 7., 4., 3., 4., 2., 4., 6., 2., 1., 1., 3., 0., 1., 2., 3., 3., 2., 3., 5., 2., 6., 1., 0., 2., 2., 1., 1., 0., 1., 2., 2., 2., 3., 3., 3., 0., 0., 0., 0., 0., 0., 4., 0., 0., 0., 0., 0., 0 [...]
+
+7., 1., 1., 3., 12., 6., 3., 1., 5., 11., 0., 16., 25., 1., 14., 2., 0., 5., 21., 0., 6., 27., 16., 26., 35., 6., 1., 1., 7., 0., 9., 9., 21., 14., 2., 10., 3., 15., 13., 1., 1., 3., 2., 10., 10., 17., 41., 11., 15., 11., 4., 1., 7., 3., 12., 3., 16., 11., 10., 15., 6., 23., 5., 4., 2., 1., 5., 0., 1., 2., 4., 4., 3., 0., 3., 3., 2., 1., 0., 2., 5., 0., 4., 4., 0., 10., 2., 3., 4., 1., 2., 1., 2., 2., 4., 9., 1., 0., 2., 1., 1., 4., 2., 4., 2., 1., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., [...]
+
+6., 2., 2., 5., 1., 0., 7., 2., 4., 31., 0., 21., 25., 0., 10., 0., 0., 0., 15., 4., 6., 23., 10., 15., 25., 7., 0., 1., 5., 1., 15., 4., 32., 16., 1., 16., 2., 16., 8., 3., 0., 3., 3., 13., 21., 15., 50., 8., 21., 10., 6., 3., 10., 3., 8., 5., 9., 5., 6., 18., 6., 27., 2., 1., 0., 4., 5., 1., 3., 2., 6., 1., 3., 6., 3., 2., 1., 1., 2., 3., 0., 0., 1., 2., 1., 10., 0., 2., 3., 2., 4., 1., 1., 1., 2., 2., 1., 0., 0., 0., 2., 3., 3., 1., 1., 2., 1., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0.,  [...]
+
+8., 0., 1., 2., 11., 2., 4., 2., 4., 14., 3., 3., 23., 0., 17., 3., 0., 4., 20., 2., 4., 21., 10., 21., 30., 8., 3., 0., 3., 2., 8., 6., 25., 14., 3., 22., 4., 8., 12., 0., 1., 4., 0., 11., 10., 19., 51., 14., 14., 20., 6., 0., 3., 2., 5., 4., 6., 2., 9., 16., 4., 21., 5., 2., 2., 2., 7., 0., 3., 1., 2., 0., 4., 8., 2., 1., 1., 2., 0., 2., 2., 0., 4., 0., 3., 13., 2., 3., 1., 5., 5., 2., 2., 1., 0., 7., 1., 0., 2., 0., 2., 0., 0., 2., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0 [...]
+
+6., 1., 1., 3., 7., 1., 7., 1., 8., 19., 1., 13., 26., 1., 21., 2., 0., 1., 26., 3., 5., 27., 8., 18., 25., 5., 1., 0., 3., 3., 8., 9., 23., 15., 2., 14., 7., 19., 7., 3., 2., 5., 2., 17., 13., 15., 47., 13., 29., 11., 5., 0., 5., 4., 7., 5., 5., 6., 2., 18., 10., 16., 6., 7., 0., 1., 9., 0., 5., 2., 4., 3., 3., 4., 6., 4., 2., 1., 0., 5., 4., 0., 0., 0., 3., 6., 2., 4., 2., 3., 1., 1., 2., 0., 0., 6., 3., 0., 1., 1., 2., 1., 2., 1., 1., 1., 1., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0. [...]
+
+6., 1., 0., 1., 8., 0., 8., 1., 5., 26., 0., 19., 13., 2., 21., 4., 4., 0., 11., 1., 5., 12., 7., 28., 24., 7., 2., 1., 4., 1., 6., 4., 25., 12., 3., 15., 4., 12., 5., 0., 0., 3., 4., 15., 13., 15., 49., 8., 18., 10., 4., 3., 6., 0., 6., 0., 6., 4., 8., 20., 6., 33., 6., 4., 2., 1., 8., 0., 1., 1., 7., 3., 4., 2., 2., 1., 4., 3., 1., 1., 3., 0., 1., 1., 1., 5., 2., 8., 2., 1., 6., 2., 3., 1., 3., 2., 2., 0., 0., 4., 2., 1., 1., 1., 4., 1., 1., 0., 0., 0., 0., 5., 0., 0., 2., 0., 0., 0.,  [...]
+
+5., 1., 2., 5., 6., 5., 5., 1., 6., 28., 1., 10., 24., 0., 20., 3., 3., 3., 17., 4., 0., 10., 18., 27., 27., 5., 0., 1., 0., 1., 8., 6., 14., 21., 4., 20., 5., 12., 13., 2., 2., 5., 2., 13., 10., 19., 35., 9., 14., 6., 5., 2., 7., 2., 7., 2., 8., 10., 7., 17., 4., 25., 9., 3., 0., 1., 7., 2., 5., 3., 3., 7., 1., 5., 3., 9., 2., 0., 1., 2., 4., 0., 2., 4., 1., 6., 4., 0., 0., 4., 12., 2., 2., 0., 1., 13., 3., 0., 1., 2., 4., 1., 4., 5., 0., 0., 1., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0.,  [...]
+
+5., 1., 1., 6., 4., 6., 7., 4., 8., 17., 3., 11., 16., 2., 8., 2., 3., 1., 14., 0., 6., 25., 14., 30., 32., 10., 2., 2., 1., 0., 12., 7., 16., 10., 4., 23., 6., 15., 9., 0., 1., 3., 1., 13., 14., 15., 49., 18., 19., 10., 1., 2., 6., 2., 11., 3., 9., 7., 14., 13., 7., 21., 8., 7., 2., 1., 6., 1., 5., 2., 5., 0., 3., 3., 7., 2., 3., 0., 2., 2., 3., 0., 2., 2., 1., 6., 1., 7., 3., 0., 2., 3., 2., 0., 0., 8., 3., 0., 1., 0., 3., 3., 1., 3., 2., 3., 5., 0., 0., 0., 0., 6., 0., 0., 0., 0., 0., [...]
+
+6., 0., 0., 5., 12., 0., 19., 0., 3., 43., 2., 10., 59., 1., 10., 3., 0., 3., 46., 6., 6., 66., 15., 90., 18., 2., 0., 0., 1., 0., 11., 11., 37., 14., 1., 37., 35., 11., 4., 0., 0., 9., 3., 22., 9., 33., 9., 11., 7., 6., 2., 0., 11., 5., 15., 6., 9., 3., 6., 6., 2., 47., 9., 5., 4., 0., 18., 3., 7., 3., 13., 2., 5., 0., 1., 3., 0., 3., 1., 10., 6., 3., 2., 1., 3., 0., 0., 0., 0., 0., 8., 1., 4., 4., 4., 0., 2., 0., 2., 0., 0., 0., 0., 3., 3., 0., 2., 0., 2., 0., 2., 0., 0., 0., 0., 0., 4 [...]
+
+6., 3., 1., 5., 7., 0., 18., 4., 6., 32., 0., 6., 82., 1., 8., 5., 0., 1., 45., 10., 8., 77., 11., 81., 18., 1., 0., 2., 5., 3., 3., 10., 44., 22., 2., 46., 32., 15., 6., 0., 2., 3., 3., 17., 8., 10., 11., 18., 5., 2., 3., 0., 11., 4., 8., 3., 15., 3., 9., 6., 2., 35., 8., 4., 0., 0., 6., 0., 8., 0., 8., 2., 8., 2., 0., 2., 0., 6., 4., 9., 9., 1., 6., 1., 2., 0., 0., 0., 0., 0., 10., 0., 3., 4., 2., 1., 2., 0., 1., 0., 1., 0., 2., 4., 4., 0., 3., 0., 0., 0., 1., 0., 0., 0., 1., 0., 1., 3 [...]
+
+6., 1., 0., 2., 12., 0., 13., 3., 6., 65., 2., 7., 48., 1., 3., 2., 0., 5., 93., 8., 7., 69., 19., 85., 12., 2., 0., 1., 4., 1., 10., 7., 59., 15., 1., 35., 29., 16., 2., 0., 1., 7., 4., 31., 6., 21., 7., 12., 1., 3., 2., 0., 7., 1., 20., 4., 20., 3., 9., 1., 2., 41., 7., 3., 3., 0., 13., 3., 3., 4., 8., 1., 2., 1., 1., 2., 0., 3., 1., 13., 12., 5., 5., 2., 4., 0., 0., 0., 0., 0., 16., 3., 2., 5., 2., 0., 1., 0., 0., 0., 1., 0., 1., 5., 2., 0., 3., 0., 1., 0., 1., 0., 0., 0., 1., 0., 2., [...]
+
+12., 4., 3., 5., 18., 0., 17., 3., 6., 62., 1., 11., 66., 2., 5., 1., 0., 2., 73., 11., 9., 70., 9., 99., 12., 4., 0., 2., 2., 3., 6., 9., 58., 14., 3., 32., 38., 16., 8., 0., 1., 7., 3., 17., 7., 26., 9., 12., 6., 1., 2., 0., 13., 4., 13., 5., 25., 1., 6., 5., 0., 32., 4., 5., 3., 0., 11., 2., 11., 2., 8., 1., 1., 1., 2., 2., 0., 6., 1., 15., 14., 4., 1., 1., 1., 0., 0., 0., 0., 0., 13., 2., 1., 5., 2., 0., 0., 0., 3., 0., 1., 0., 2., 5., 3., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1., 0.,  [...]
+
+14., 0., 2., 1., 14., 0., 19., 1., 8., 44., 1., 7., 65., 0., 5., 0., 0., 0., 52., 5., 15., 84., 19., 79., 6., 2., 0., 2., 4., 3., 17., 9., 49., 12., 1., 39., 35., 18., 10., 0., 0., 1., 3., 25., 7., 18., 5., 14., 8., 3., 3., 0., 12., 3., 11., 2., 10., 4., 6., 3., 2., 38., 8., 10., 4., 0., 17., 2., 11., 1., 11., 3., 5., 0., 3., 2., 0., 6., 0., 15., 5., 3., 2., 1., 4., 0., 0., 0., 0., 0., 14., 1., 2., 1., 1., 1., 0., 0., 1., 0., 1., 0., 0., 0., 2., 0., 5., 0., 1., 0., 1., 0., 0., 0., 2., 0. [...]
+
+15., 1., 4., 8., 23., 6., 33., 3., 19., 167., 5., 31., 198., 6., 18., 8., 0., 5., 83., 1., 20., 289., 51., 305., 42., 11., 0., 2., 7., 6., 47., 30., 245., 45., 5., 162., 13., 40., 6., 0., 1., 24., 11., 91., 30., 72., 12., 28., 41., 13., 1., 1., 23., 12., 40., 8., 52., 14., 26., 7., 6., 11., 1., 0., 3., 0., 28., 3., 14., 4., 22., 4., 10., 8., 2., 3., 3., 1., 0., 0., 9., 4., 5., 2., 7., 2., 2., 7., 137., 5., 1855., 78., 90., 230., 97., 139., 65., 9., 9., 13., 7., 2., 1., 6., 6., 4., 10., 7 [...]
+
+15., 3., 2., 12., 23., 4., 20., 1., 16., 161., 3., 29., 197., 1., 17., 9., 2., 6., 97., 3., 15., 305., 40., 292., 29., 19., 0., 2., 8., 5., 47., 38., 214., 44., 6., 130., 11., 47., 7., 0., 2., 17., 9., 80., 21., 81., 12., 48., 65., 8., 2., 3., 27., 2., 39., 18., 51., 9., 36., 6., 8., 8., 4., 0., 1., 0., 40., 3., 10., 3., 27., 9., 4., 5., 3., 4., 4., 0., 3., 2., 18., 3., 7., 1., 7., 0., 2., 4., 133., 5., 1924., 91., 99., 247., 96., 117., 70., 13., 6., 18., 15., 1., 5., 7., 3., 4., 18., 8. [...]
+
+12., 1., 1., 7., 21., 9., 32., 2., 22., 174., 4., 27., 262., 9., 11., 4., 0., 5., 65., 0., 15., 271., 41., 329., 42., 16., 0., 0., 8., 4., 41., 29., 238., 50., 9., 165., 16., 45., 6., 0., 3., 21., 8., 69., 12., 83., 18., 35., 40., 11., 1., 2., 28., 11., 32., 11., 41., 13., 22., 5., 12., 11., 2., 0., 1., 0., 31., 4., 18., 3., 25., 5., 9., 4., 4., 3., 3., 4., 6., 1., 14., 4., 4., 2., 10., 2., 0., 6., 137., 12., 1862., 87., 103., 214., 92., 125., 56., 15., 18., 22., 12., 0., 2., 3., 9., 3., [...]
+
+18., 1., 3., 1., 21., 10., 26., 1., 23., 159., 2., 22., 242., 10., 17., 5., 1., 9., 86., 0., 15., 280., 42., 351., 41., 27., 0., 3., 11., 6., 31., 29., 229., 44., 3., 160., 16., 40., 4., 0., 2., 18., 3., 77., 23., 101., 13., 36., 47., 6., 2., 0., 18., 8., 32., 13., 55., 16., 25., 3., 10., 4., 1., 0., 1., 0., 18., 4., 18., 2., 34., 3., 16., 8., 5., 4., 0., 1., 3., 2., 13., 6., 7., 1., 7., 0., 0., 6., 143., 9., 1870., 84., 99., 214., 112., 103., 75., 13., 10., 17., 10., 1., 1., 14., 5., 3. [...]
+
+22., 1., 1., 8., 17., 9., 35., 0., 14., 167., 2., 24., 229., 3., 13., 13., 2., 3., 82., 3., 16., 300., 48., 314., 55., 15., 0., 0., 7., 2., 44., 42., 245., 39., 5., 165., 5., 41., 3., 0., 1., 21., 8., 72., 21., 96., 23., 36., 48., 11., 2., 4., 16., 6., 36., 9., 45., 6., 35., 8., 11., 9., 0., 0., 1., 0., 22., 8., 14., 1., 26., 7., 9., 8., 1., 4., 1., 1., 4., 2., 14., 1., 8., 1., 3., 1., 0., 2., 138., 10., 1835., 80., 109., 219., 103., 119., 65., 19., 9., 14., 16., 0., 2., 6., 5., 2., 11., [...]
+
+9., 2., 1., 5., 10., 5., 8., 2., 6., 18., 1., 23., 23., 1., 10., 3., 2., 0., 16., 0., 7., 21., 19., 32., 16., 4., 2., 2., 2., 2., 4., 7., 30., 20., 2., 12., 3., 12., 10., 1., 0., 5., 4., 10., 12., 12., 44., 5., 20., 13., 4., 2., 8., 4., 4., 6., 7., 6., 9., 9., 13., 20., 11., 4., 0., 0., 6., 0., 3., 1., 3., 3., 3., 1., 2., 4., 3., 0., 1., 5., 2., 0., 0., 6., 2., 10., 1., 4., 3., 2., 5., 0., 2., 1., 1., 3., 2., 0., 3., 2., 2., 0., 3., 1., 1., 0., 4., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., [...]
+
+9., 1., 1., 5., 5., 2., 4., 1., 8., 21., 0., 16., 22., 1., 8., 4., 0., 3., 25., 2., 5., 31., 12., 20., 26., 3., 1., 0., 2., 3., 7., 8., 19., 19., 4., 10., 6., 19., 10., 3., 0., 5., 1., 13., 9., 17., 48., 6., 14., 7., 7., 0., 5., 2., 5., 3., 11., 5., 7., 18., 11., 25., 10., 8., 0., 0., 6., 4., 2., 2., 3., 2., 3., 2., 2., 1., 0., 3., 0., 3., 4., 0., 1., 4., 5., 6., 0., 4., 2., 2., 4., 0., 1., 1., 4., 9., 4., 0., 2., 3., 1., 4., 4., 1., 5., 0., 1., 0., 0., 0., 0., 4., 0., 0., 1., 0., 0., 0. [...]
+
+5., 2., 0., 8., 13., 2., 5., 1., 4., 21., 2., 22., 17., 2., 13., 4., 1., 5., 12., 4., 6., 16., 15., 24., 27., 5., 0., 0., 1., 2., 11., 4., 13., 21., 5., 19., 3., 13., 7., 3., 1., 6., 5., 10., 13., 19., 61., 8., 18., 10., 2., 2., 11., 4., 9., 5., 15., 3., 12., 18., 3., 19., 8., 3., 0., 0., 4., 1., 3., 2., 7., 2., 4., 4., 2., 3., 4., 0., 0., 4., 0., 0., 3., 0., 3., 8., 1., 5., 1., 3., 4., 3., 1., 0., 4., 7., 3., 0., 7., 2., 2., 1., 4., 4., 2., 1., 3., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. [...]
+
+7., 0., 2., 7., 4., 3., 5., 0., 6., 14., 1., 21., 24., 1., 12., 3., 3., 2., 22., 2., 4., 27., 10., 31., 21., 5., 1., 1., 1., 2., 4., 3., 24., 13., 4., 17., 5., 12., 2., 2., 1., 6., 2., 19., 10., 14., 54., 13., 18., 9., 3., 2., 7., 4., 7., 3., 11., 6., 10., 15., 2., 28., 9., 5., 1., 4., 5., 1., 2., 0., 6., 2., 7., 6., 2., 5., 3., 3., 3., 4., 5., 0., 1., 2., 3., 4., 2., 5., 1., 1., 4., 2., 2., 0., 3., 7., 0., 0., 2., 2., 1., 3., 4., 2., 2., 3., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0 [...]
+
+9., 1., 2., 6., 10., 1., 3., 0., 4., 10., 2., 5., 22., 0., 12., 2., 2., 1., 20., 2., 2., 24., 11., 29., 27., 5., 1., 2., 4., 1., 7., 9., 30., 22., 2., 17., 3., 6., 12., 3., 0., 1., 0., 19., 11., 16., 49., 13., 18., 11., 6., 0., 1., 2., 6., 2., 12., 3., 7., 15., 5., 20., 8., 4., 2., 2., 1., 4., 3., 3., 3., 3., 6., 3., 0., 8., 3., 1., 1., 2., 0., 0., 1., 3., 3., 5., 0., 5., 5., 3., 2., 1., 3., 1., 0., 7., 2., 0., 2., 0., 0., 0., 0., 3., 1., 0., 0., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0 [...]
+
+4., 2., 4., 3., 11., 2., 2., 0., 4., 16., 0., 16., 29., 0., 18., 4., 0., 3., 19., 2., 4., 30., 15., 27., 25., 5., 3., 1., 3., 1., 5., 6., 22., 14., 1., 12., 2., 13., 10., 2., 2., 5., 4., 7., 13., 28., 45., 9., 23., 13., 2., 1., 5., 2., 4., 1., 13., 7., 7., 16., 6., 24., 11., 3., 2., 1., 5., 2., 4., 2., 8., 2., 3., 4., 0., 2., 1., 0., 0., 0., 1., 0., 2., 2., 0., 7., 2., 4., 2., 0., 4., 0., 1., 1., 1., 7., 1., 0., 1., 3., 3., 3., 1., 1., 2., 0., 2., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0.,  [...]
+
+6., 2., 0., 1., 4., 2., 10., 1., 10., 18., 2., 8., 15., 0., 15., 1., 0., 2., 19., 2., 2., 36., 10., 16., 25., 7., 2., 1., 2., 2., 4., 7., 24., 16., 4., 11., 3., 14., 6., 2., 1., 6., 1., 21., 10., 16., 31., 9., 24., 11., 0., 2., 4., 1., 9., 4., 7., 5., 11., 18., 5., 19., 6., 3., 2., 1., 2., 0., 1., 0., 5., 2., 5., 7., 3., 3., 4., 2., 1., 0., 3., 0., 0., 2., 1., 8., 2., 5., 1., 2., 3., 0., 1., 1., 2., 5., 1., 0., 2., 3., 3., 2., 2., 0., 4., 1., 2., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0 [...]
+
+8., 1., 6., 2., 10., 2., 8., 0., 8., 29., 0., 16., 25., 1., 12., 3., 1., 1., 9., 1., 10., 14., 16., 32., 30., 6., 0., 2., 5., 1., 6., 7., 28., 12., 1., 14., 3., 8., 13., 1., 0., 5., 6., 16., 8., 17., 52., 14., 15., 14., 7., 1., 7., 2., 2., 2., 9., 5., 11., 12., 9., 22., 11., 4., 2., 1., 5., 1., 2., 2., 4., 4., 6., 3., 2., 4., 1., 1., 1., 5., 2., 0., 2., 0., 1., 6., 1., 2., 2., 3., 2., 2., 0., 0., 3., 4., 0., 0., 4., 2., 1., 0., 2., 3., 2., 1., 3., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0.,  [...]
+
+7., 2., 2., 3., 10., 5., 2., 1., 4., 32., 0., 10., 24., 1., 8., 2., 0., 1., 12., 3., 2., 25., 13., 24., 27., 4., 2., 0., 3., 1., 11., 2., 31., 18., 1., 9., 2., 12., 6., 8., 1., 9., 2., 10., 11., 22., 52., 15., 23., 7., 6., 1., 5., 4., 5., 3., 9., 5., 10., 16., 4., 15., 9., 2., 0., 0., 6., 1., 2., 2., 3., 0., 4., 4., 2., 7., 3., 0., 0., 4., 2., 0., 2., 0., 0., 2., 4., 5., 0., 1., 2., 0., 4., 2., 0., 11., 2., 0., 0., 3., 4., 3., 5., 2., 1., 0., 2., 0., 0., 0., 0., 5., 0., 0., 3., 0., 0., 0 [...]
+
+9., 2., 0., 4., 8., 5., 8., 0., 10., 19., 1., 10., 18., 1., 10., 1., 1., 0., 19., 2., 3., 18., 13., 25., 29., 7., 0., 2., 2., 0., 12., 1., 27., 21., 2., 21., 4., 16., 9., 1., 1., 1., 1., 20., 10., 22., 51., 14., 24., 8., 3., 1., 7., 2., 6., 1., 12., 8., 2., 15., 2., 22., 8., 3., 0., 1., 10., 2., 4., 4., 5., 3., 1., 4., 1., 1., 4., 0., 0., 1., 0., 0., 2., 3., 2., 8., 2., 4., 1., 0., 7., 2., 3., 1., 4., 8., 3., 0., 2., 7., 2., 3., 2., 0., 2., 1., 2., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., [...]
+
+6., 1., 4., 2., 10., 5., 6., 0., 4., 41., 0., 2., 22., 1., 18., 2., 0., 4., 18., 2., 2., 28., 15., 35., 22., 6., 1., 1., 2., 2., 10., 4., 26., 13., 5., 20., 3., 14., 6., 1., 0., 0., 0., 13., 10., 15., 34., 12., 22., 8., 3., 1., 8., 6., 2., 0., 9., 7., 10., 19., 7., 22., 8., 2., 1., 0., 2., 1., 3., 0., 2., 5., 3., 5., 2., 2., 2., 2., 0., 2., 3., 0., 2., 1., 3., 12., 3., 3., 3., 5., 4., 2., 4., 1., 1., 12., 0., 0., 1., 1., 3., 3., 0., 2., 1., 1., 0., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., [...]
+
+6., 1., 2., 3., 3., 5., 8., 0., 6., 11., 0., 9., 20., 2., 12., 6., 0., 1., 17., 2., 0., 21., 10., 30., 32., 3., 2., 1., 3., 5., 8., 8., 31., 21., 1., 13., 4., 6., 12., 5., 1., 3., 4., 9., 8., 16., 40., 11., 13., 11., 1., 0., 5., 2., 11., 7., 12., 3., 6., 19., 6., 24., 8., 1., 3., 2., 8., 0., 8., 4., 8., 0., 3., 6., 1., 2., 4., 3., 3., 4., 0., 0., 2., 2., 1., 6., 1., 5., 0., 4., 7., 3., 1., 2., 2., 6., 2., 0., 1., 3., 2., 3., 1., 3., 2., 1., 4., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0., [...]
+
+6., 0., 3., 6., 11., 4., 6., 1., 3., 34., 1., 12., 18., 1., 15., 4., 1., 2., 24., 4., 7., 29., 13., 12., 22., 4., 2., 0., 3., 3., 6., 7., 33., 16., 4., 13., 6., 10., 9., 2., 2., 2., 2., 16., 15., 17., 52., 12., 27., 8., 3., 1., 6., 0., 2., 2., 14., 7., 8., 16., 11., 24., 8., 2., 1., 0., 9., 0., 4., 2., 4., 2., 5., 6., 0., 10., 2., 1., 2., 2., 3., 0., 2., 2., 0., 3., 3., 3., 2., 0., 4., 1., 1., 1., 1., 3., 2., 0., 0., 0., 1., 2., 3., 6., 2., 0., 1., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., [...]
+
+15., 1., 4., 4., 4., 2., 6., 0., 8., 15., 0., 13., 14., 0., 15., 3., 0., 0., 19., 2., 2., 36., 13., 23., 22., 5., 2., 0., 6., 0., 10., 4., 27., 24., 3., 22., 4., 13., 8., 0., 1., 5., 2., 14., 16., 25., 62., 15., 24., 10., 3., 2., 6., 5., 7., 4., 12., 7., 12., 7., 7., 17., 13., 2., 0., 1., 7., 2., 5., 3., 4., 3., 4., 4., 3., 2., 5., 3., 1., 3., 3., 0., 4., 1., 0., 8., 0., 4., 2., 1., 2., 0., 5., 0., 1., 7., 1., 0., 1., 1., 0., 3., 2., 1., 0., 2., 1., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0. [...]
+
+6., 1., 1., 2., 4., 4., 2., 1., 7., 32., 1., 9., 29., 0., 12., 7., 0., 1., 20., 2., 5., 15., 13., 26., 38., 4., 0., 1., 5., 9., 12., 4., 18., 13., 3., 16., 3., 18., 16., 1., 2., 2., 0., 13., 15., 15., 53., 11., 17., 13., 7., 2., 4., 1., 9., 3., 7., 7., 8., 16., 6., 19., 10., 5., 0., 0., 7., 0., 3., 4., 8., 5., 5., 6., 2., 7., 5., 2., 0., 0., 2., 0., 0., 2., 4., 4., 5., 5., 3., 1., 3., 3., 2., 2., 2., 9., 1., 0., 2., 2., 2., 2., 2., 1., 0., 3., 7., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0.,  [...]
+
+5., 2., 4., 3., 13., 2., 3., 0., 3., 21., 5., 18., 12., 1., 11., 3., 2., 2., 18., 3., 3., 18., 6., 37., 37., 7., 0., 1., 5., 4., 6., 9., 36., 11., 3., 11., 1., 13., 7., 3., 0., 4., 3., 13., 5., 19., 51., 13., 25., 6., 2., 1., 1., 1., 6., 2., 12., 5., 5., 17., 6., 26., 5., 3., 2., 1., 10., 0., 5., 3., 5., 1., 4., 5., 1., 4., 2., 2., 2., 1., 2., 0., 0., 1., 1., 6., 0., 6., 1., 0., 2., 0., 3., 1., 2., 6., 1., 0., 3., 1., 2., 2., 2., 3., 4., 0., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+11., 2., 2., 4., 11., 2., 7., 1., 5., 24., 0., 16., 8., 0., 13., 5., 2., 1., 19., 1., 2., 22., 9., 26., 28., 4., 1., 0., 1., 3., 9., 6., 15., 20., 5., 7., 2., 9., 7., 1., 3., 4., 2., 6., 8., 12., 48., 8., 20., 12., 5., 2., 7., 1., 2., 4., 6., 1., 9., 18., 6., 21., 7., 4., 0., 1., 7., 2., 5., 5., 2., 3., 4., 6., 2., 5., 1., 0., 1., 2., 1., 0., 3., 4., 1., 7., 1., 4., 2., 3., 6., 1., 0., 1., 3., 8., 0., 0., 2., 2., 2., 2., 3., 2., 3., 3., 1., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., 0., 1., [...]
+
+9., 0., 2., 4., 7., 4., 7., 0., 9., 25., 0., 15., 23., 2., 16., 2., 2., 1., 26., 4., 3., 29., 11., 29., 35., 4., 1., 2., 1., 5., 17., 2., 34., 13., 1., 6., 2., 18., 7., 2., 1., 6., 3., 15., 9., 18., 56., 16., 27., 9., 6., 4., 4., 4., 5., 5., 13., 10., 7., 20., 8., 15., 7., 2., 1., 0., 8., 1., 3., 2., 2., 2., 6., 3., 4., 5., 5., 1., 0., 5., 1., 0., 1., 4., 2., 7., 2., 4., 2., 3., 1., 2., 4., 1., 2., 2., 1., 0., 1., 2., 1., 5., 3., 2., 5., 1., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+10., 1., 0., 4., 7., 0., 9., 1., 2., 13., 0., 13., 12., 3., 14., 3., 0., 1., 14., 1., 2., 25., 11., 27., 27., 6., 0., 4., 6., 1., 0., 11., 35., 19., 1., 14., 3., 13., 8., 0., 3., 4., 1., 10., 14., 16., 39., 16., 25., 7., 1., 1., 3., 4., 9., 1., 12., 3., 9., 13., 4., 20., 6., 4., 1., 2., 10., 3., 5., 3., 3., 8., 3., 2., 1., 3., 1., 4., 1., 1., 4., 0., 1., 1., 0., 5., 3., 5., 2., 5., 4., 0., 3., 1., 4., 8., 2., 0., 1., 1., 2., 2., 3., 3., 2., 2., 5., 0., 0., 0., 0., 1., 0., 0., 4., 0., 0., [...]
+
+9., 0., 2., 5., 5., 7., 7., 0., 8., 29., 0., 13., 13., 2., 20., 4., 0., 1., 6., 1., 5., 29., 13., 22., 35., 3., 2., 2., 3., 0., 9., 9., 31., 12., 3., 17., 3., 9., 12., 3., 1., 2., 2., 6., 9., 14., 48., 8., 18., 10., 5., 0., 8., 3., 4., 6., 4., 10., 3., 9., 5., 16., 12., 3., 0., 2., 4., 1., 1., 1., 5., 4., 8., 6., 1., 3., 4., 1., 1., 1., 0., 0., 2., 5., 2., 8., 4., 5., 0., 3., 5., 0., 5., 2., 0., 9., 1., 0., 4., 2., 4., 3., 2., 5., 0., 1., 3., 0., 0., 0., 0., 0., 0., 0., 4., 0., 0., 0., 0 [...]
+
+10., 1., 3., 3., 9., 5., 7., 3., 6., 20., 2., 13., 24., 1., 15., 3., 0., 5., 13., 1., 7., 19., 6., 21., 24., 10., 0., 1., 0., 2., 9., 11., 33., 11., 0., 13., 5., 15., 12., 0., 0., 4., 5., 14., 14., 16., 46., 11., 18., 12., 0., 0., 4., 3., 6., 2., 13., 4., 3., 12., 10., 18., 7., 2., 2., 3., 4., 2., 2., 1., 4., 3., 3., 5., 5., 4., 3., 1., 0., 3., 0., 0., 1., 2., 2., 6., 0., 5., 4., 1., 3., 1., 0., 0., 0., 3., 2., 0., 1., 3., 5., 2., 3., 3., 0., 2., 3., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0 [...]
+
+6., 1., 0., 4., 5., 1., 4., 0., 0., 15., 2., 14., 21., 0., 16., 3., 1., 1., 21., 1., 3., 19., 15., 21., 35., 5., 2., 2., 2., 1., 7., 5., 21., 22., 2., 17., 2., 16., 10., 2., 2., 3., 2., 18., 16., 19., 41., 13., 18., 9., 4., 1., 3., 0., 6., 4., 11., 4., 3., 20., 2., 28., 7., 3., 2., 2., 6., 1., 4., 0., 3., 5., 4., 2., 3., 3., 7., 5., 1., 1., 1., 0., 2., 1., 4., 5., 1., 5., 3., 1., 3., 2., 1., 0., 2., 8., 4., 0., 4., 0., 4., 0., 1., 0., 1., 2., 5., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0 [...]
+
+8., 1., 1., 5., 10., 0., 19., 7., 8., 54., 0., 9., 57., 1., 8., 2., 0., 1., 59., 0., 9., 83., 8., 78., 9., 3., 0., 1., 2., 1., 12., 10., 57., 7., 1., 40., 34., 13., 4., 0., 3., 5., 2., 13., 3., 26., 4., 11., 7., 4., 2., 0., 14., 2., 25., 7., 16., 1., 15., 3., 0., 38., 10., 7., 0., 0., 15., 2., 14., 0., 9., 3., 2., 0., 1., 2., 0., 9., 5., 24., 8., 5., 3., 2., 4., 0., 0., 0., 0., 0., 12., 2., 3., 1., 3., 0., 0., 0., 0., 0., 0., 0., 0., 2., 3., 0., 1., 0., 0., 0., 0., 0., 0., 0., 2., 0., 3. [...]
+
+17., 0., 3., 2., 10., 0., 14., 2., 8., 58., 2., 7., 55., 2., 8., 4., 0., 4., 81., 12., 9., 86., 24., 76., 11., 4., 0., 1., 5., 3., 15., 9., 68., 10., 3., 49., 26., 17., 3., 0., 1., 5., 5., 28., 6., 20., 2., 14., 6., 2., 1., 0., 9., 5., 14., 2., 9., 5., 7., 5., 1., 31., 8., 7., 1., 0., 10., 3., 2., 1., 9., 5., 4., 1., 1., 0., 0., 6., 6., 10., 7., 2., 3., 2., 3., 0., 0., 0., 0., 0., 10., 0., 3., 4., 2., 1., 1., 0., 3., 0., 2., 0., 0., 2., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1., [...]
+
+5., 0., 4., 8., 18., 0., 10., 3., 8., 56., 1., 9., 42., 1., 6., 0., 0., 1., 94., 10., 13., 98., 19., 77., 15., 6., 0., 1., 3., 1., 18., 11., 51., 9., 1., 36., 26., 13., 7., 0., 0., 9., 2., 26., 2., 16., 5., 17., 3., 2., 3., 0., 21., 5., 15., 5., 19., 4., 11., 2., 2., 34., 10., 15., 1., 0., 9., 3., 12., 2., 14., 3., 1., 2., 2., 0., 0., 5., 0., 16., 8., 4., 1., 2., 2., 0., 0., 0., 0., 0., 7., 5., 3., 2., 6., 1., 1., 0., 3., 0., 2., 0., 1., 2., 2., 0., 2., 0., 0., 0., 0., 0., 0., 0., 1., 0. [...]
+
+17., 0., 2., 9., 11., 0., 17., 3., 8., 57., 0., 12., 61., 1., 11., 2., 0., 3., 79., 4., 8., 74., 16., 71., 12., 4., 0., 1., 3., 1., 12., 8., 43., 7., 2., 42., 30., 14., 4., 0., 1., 6., 2., 34., 5., 24., 12., 7., 7., 1., 2., 0., 10., 7., 21., 5., 14., 4., 7., 4., 3., 31., 6., 4., 1., 0., 20., 5., 7., 2., 7., 1., 2., 1., 1., 1., 0., 5., 1., 12., 5., 2., 5., 1., 3., 0., 0., 0., 0., 0., 6., 4., 6., 1., 4., 1., 0., 0., 0., 0., 1., 0., 0., 4., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 3. [...]
+
+15., 1., 3., 4., 13., 0., 12., 0., 9., 58., 2., 13., 49., 0., 9., 1., 0., 1., 73., 1., 9., 43., 11., 78., 12., 1., 0., 0., 2., 4., 12., 10., 67., 9., 3., 34., 40., 13., 4., 0., 0., 6., 2., 23., 9., 18., 9., 16., 6., 1., 3., 0., 6., 4., 17., 4., 11., 1., 8., 5., 1., 28., 10., 11., 5., 0., 19., 4., 9., 4., 11., 2., 6., 1., 0., 0., 0., 8., 1., 17., 8., 5., 8., 3., 5., 0., 0., 0., 0., 0., 10., 0., 3., 2., 4., 0., 1., 0., 0., 0., 1., 0., 1., 2., 4., 0., 1., 0., 0., 0., 1., 0., 0., 0., 0., 0., [...]
+
+8., 2., 4., 5., 20., 6., 17., 0., 13., 191., 2., 19., 215., 3., 12., 5., 1., 5., 82., 5., 20., 281., 48., 353., 37., 13., 1., 3., 10., 6., 54., 35., 243., 52., 11., 161., 8., 48., 6., 0., 2., 17., 4., 84., 18., 92., 16., 33., 49., 15., 0., 2., 20., 7., 35., 9., 46., 11., 26., 3., 9., 4., 4., 0., 1., 0., 20., 2., 5., 1., 23., 3., 9., 7., 5., 1., 1., 0., 4., 1., 6., 3., 4., 3., 6., 1., 2., 6., 146., 10., 1962., 87., 100., 223., 102., 122., 74., 17., 14., 18., 11., 1., 4., 9., 4., 5., 6., 9 [...]
+
+14., 3., 6., 10., 27., 5., 34., 1., 15., 149., 5., 20., 193., 3., 15., 3., 1., 5., 86., 1., 10., 327., 45., 342., 54., 21., 0., 5., 5., 4., 43., 29., 236., 39., 8., 147., 8., 44., 7., 0., 2., 17., 9., 69., 13., 88., 18., 46., 43., 9., 1., 1., 24., 6., 48., 14., 37., 6., 33., 6., 10., 7., 0., 0., 0., 0., 28., 2., 15., 1., 27., 5., 7., 7., 1., 4., 1., 1., 2., 2., 11., 2., 9., 0., 11., 0., 0., 5., 137., 6., 1813., 93., 102., 226., 97., 113., 61., 9., 9., 18., 17., 0., 3., 5., 6., 3., 9., 5. [...]
+
+15., 4., 3., 9., 21., 3., 26., 1., 9., 150., 0., 17., 207., 7., 12., 7., 1., 1., 90., 3., 17., 281., 46., 347., 38., 22., 3., 5., 6., 8., 43., 24., 223., 44., 7., 146., 15., 36., 5., 0., 1., 16., 11., 85., 16., 97., 15., 41., 49., 11., 3., 0., 27., 11., 32., 11., 59., 3., 20., 6., 9., 6., 0., 0., 1., 0., 28., 7., 15., 7., 31., 4., 11., 8., 2., 3., 2., 2., 2., 1., 13., 5., 10., 7., 6., 1., 2., 5., 150., 7., 1859., 76., 97., 208., 94., 96., 65., 10., 13., 14., 13., 1., 3., 2., 7., 4., 9.,  [...]
+
+9., 5., 2., 8., 27., 3., 41., 0., 18., 159., 2., 30., 202., 7., 7., 7., 0., 7., 70., 1., 19., 304., 37., 338., 44., 26., 1., 4., 6., 11., 44., 31., 236., 37., 9., 130., 12., 31., 6., 0., 2., 18., 11., 86., 17., 92., 9., 34., 47., 18., 3., 1., 26., 7., 31., 11., 52., 9., 28., 7., 10., 11., 1., 0., 0., 0., 26., 7., 15., 3., 28., 2., 11., 6., 6., 2., 1., 4., 1., 6., 14., 4., 6., 0., 13., 1., 0., 4., 153., 10., 1913., 103., 73., 227., 98., 98., 68., 17., 17., 19., 10., 0., 2., 11., 6., 4., 8 [...]
+
+6., 1., 5., 4., 9., 3., 7., 0., 7., 28., 0., 9., 21., 1., 13., 3., 1., 3., 18., 2., 5., 18., 13., 28., 25., 8., 0., 0., 2., 1., 10., 14., 21., 10., 5., 20., 1., 17., 7., 1., 1., 6., 4., 8., 9., 28., 48., 10., 19., 3., 3., 1., 4., 1., 7., 7., 9., 6., 10., 6., 10., 19., 7., 4., 1., 1., 7., 1., 2., 1., 3., 1., 3., 2., 1., 5., 4., 1., 0., 1., 2., 0., 1., 3., 2., 8., 2., 4., 1., 5., 1., 3., 1., 2., 0., 7., 0., 0., 2., 3., 2., 4., 3., 4., 5., 2., 1., 0., 0., 0., 0., 4., 0., 0., 1., 0., 0., 0., [...]
+
+9., 3., 3., 4., 7., 2., 9., 1., 5., 21., 0., 13., 15., 3., 13., 1., 1., 1., 17., 1., 3., 23., 10., 31., 25., 4., 2., 1., 2., 2., 8., 6., 15., 11., 1., 17., 7., 10., 10., 3., 0., 6., 2., 14., 12., 25., 48., 8., 21., 8., 7., 1., 7., 3., 9., 3., 15., 9., 6., 16., 3., 27., 15., 3., 0., 0., 5., 3., 4., 2., 5., 3., 1., 6., 1., 2., 4., 6., 0., 1., 1., 0., 1., 6., 5., 6., 1., 1., 3., 1., 8., 2., 0., 0., 1., 10., 2., 0., 4., 2., 2., 0., 3., 3., 1., 1., 2., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.,  [...]
+
+12., 0., 3., 7., 8., 4., 12., 2., 3., 15., 0., 15., 30., 0., 15., 3., 4., 2., 23., 1., 1., 17., 8., 24., 24., 0., 0., 1., 0., 3., 2., 2., 15., 15., 2., 12., 4., 10., 13., 2., 1., 2., 2., 13., 11., 15., 49., 12., 24., 2., 4., 4., 3., 2., 8., 1., 7., 3., 13., 17., 7., 26., 1., 1., 1., 0., 12., 0., 0., 3., 2., 5., 7., 1., 1., 4., 2., 4., 0., 1., 3., 0., 1., 3., 3., 3., 4., 6., 2., 1., 6., 0., 2., 0., 0., 9., 0., 0., 1., 1., 2., 0., 1., 0., 2., 2., 2., 0., 0., 0., 0., 1., 0., 0., 5., 0., 0., [...]
+
+8., 2., 3., 5., 12., 3., 6., 2., 4., 24., 2., 11., 22., 1., 13., 3., 0., 2., 24., 1., 3., 28., 18., 36., 35., 8., 2., 1., 2., 2., 5., 4., 28., 11., 3., 6., 5., 13., 5., 1., 0., 4., 2., 13., 12., 25., 49., 15., 23., 6., 2., 1., 5., 3., 6., 4., 11., 4., 6., 16., 4., 28., 8., 1., 1., 1., 5., 0., 0., 1., 11., 4., 4., 4., 4., 4., 3., 0., 2., 2., 2., 0., 3., 1., 2., 1., 1., 6., 2., 4., 5., 0., 3., 1., 3., 4., 2., 0., 0., 1., 0., 2., 1., 2., 3., 0., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0 [...]
+
+9., 1., 2., 5., 5., 3., 1., 0., 5., 20., 3., 10., 26., 0., 15., 7., 0., 1., 18., 0., 3., 31., 12., 29., 22., 8., 2., 0., 1., 1., 5., 7., 27., 27., 3., 9., 4., 12., 10., 3., 1., 4., 3., 11., 16., 23., 35., 17., 29., 11., 4., 1., 4., 0., 7., 2., 11., 5., 16., 24., 6., 27., 9., 2., 2., 0., 8., 1., 3., 2., 6., 0., 4., 2., 2., 4., 4., 1., 1., 2., 1., 0., 2., 1., 3., 6., 0., 7., 1., 0., 6., 0., 2., 0., 4., 8., 7., 0., 2., 2., 3., 2., 2., 0., 1., 0., 1., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0.,  [...]
+
+4., 1., 1., 2., 8., 2., 10., 3., 4., 17., 1., 11., 18., 1., 15., 2., 1., 3., 21., 3., 7., 19., 10., 33., 15., 5., 0., 1., 3., 3., 14., 12., 22., 17., 2., 17., 3., 10., 8., 3., 1., 2., 1., 17., 6., 16., 56., 10., 16., 6., 7., 2., 4., 3., 6., 3., 8., 4., 10., 17., 6., 27., 3., 3., 1., 1., 8., 2., 2., 0., 5., 5., 3., 2., 2., 9., 5., 3., 0., 4., 0., 0., 3., 2., 2., 5., 2., 3., 1., 3., 3., 0., 2., 1., 2., 7., 1., 0., 3., 4., 2., 2., 3., 0., 2., 1., 4., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0.,  [...]
+
+3., 0., 2., 3., 10., 5., 6., 1., 4., 29., 0., 14., 22., 1., 16., 1., 2., 3., 23., 3., 6., 11., 10., 28., 27., 10., 0., 0., 0., 2., 10., 10., 32., 13., 3., 18., 5., 16., 9., 1., 1., 3., 4., 11., 10., 13., 44., 15., 23., 12., 3., 0., 3., 3., 8., 7., 11., 3., 7., 13., 5., 25., 8., 2., 0., 1., 8., 0., 10., 6., 1., 5., 3., 5., 3., 3., 1., 1., 0., 1., 2., 0., 3., 1., 2., 6., 2., 4., 0., 2., 2., 0., 1., 3., 4., 3., 1., 0., 1., 2., 1., 2., 4., 2., 1., 0., 1., 0., 0., 0., 0., 4., 0., 0., 0., 0.,  [...]
+
+4., 0., 3., 4., 10., 3., 6., 3., 6., 21., 1., 17., 24., 1., 17., 2., 1., 3., 21., 2., 5., 22., 13., 23., 31., 5., 1., 0., 3., 4., 6., 7., 29., 14., 2., 10., 5., 12., 7., 5., 3., 3., 5., 7., 4., 16., 36., 13., 28., 12., 5., 1., 5., 4., 8., 3., 8., 3., 9., 15., 10., 21., 6., 4., 1., 1., 6., 0., 1., 1., 2., 4., 2., 1., 4., 10., 2., 2., 1., 1., 3., 0., 3., 3., 2., 6., 4., 5., 2., 2., 3., 0., 1., 1., 0., 11., 0., 0., 4., 1., 2., 2., 5., 5., 1., 1., 2., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0.,  [...]
+
+13., 3., 1., 5., 11., 1., 3., 2., 4., 21., 1., 8., 16., 0., 10., 4., 2., 2., 15., 2., 3., 20., 11., 31., 24., 5., 0., 3., 2., 3., 5., 7., 25., 16., 1., 11., 3., 12., 11., 3., 2., 6., 2., 16., 13., 15., 45., 5., 22., 12., 5., 1., 6., 4., 5., 2., 5., 7., 7., 11., 6., 26., 9., 1., 0., 1., 4., 1., 6., 2., 3., 3., 7., 3., 0., 1., 4., 5., 1., 1., 0., 0., 3., 1., 4., 3., 0., 3., 3., 3., 6., 1., 2., 2., 1., 7., 1., 0., 2., 2., 0., 6., 0., 0., 3., 3., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0 [...]
+
+12., 1., 1., 6., 8., 1., 4., 1., 5., 28., 0., 13., 30., 0., 12., 4., 0., 3., 23., 0., 4., 32., 15., 24., 21., 6., 3., 0., 2., 1., 8., 12., 29., 16., 3., 12., 6., 13., 8., 4., 0., 3., 2., 17., 12., 15., 56., 15., 22., 9., 5., 0., 7., 1., 3., 3., 8., 5., 6., 19., 8., 22., 6., 3., 0., 1., 9., 0., 4., 1., 7., 6., 5., 3., 1., 5., 5., 2., 2., 2., 2., 0., 0., 1., 2., 9., 3., 2., 0., 4., 0., 1., 3., 1., 0., 10., 1., 0., 4., 1., 2., 2., 1., 0., 0., 2., 2., 0., 0., 0., 0., 4., 0., 0., 0., 0., 0.,  [...]
+
+14., 2., 3., 3., 6., 3., 5., 1., 9., 27., 0., 6., 26., 1., 14., 7., 1., 1., 18., 3., 7., 18., 12., 19., 27., 10., 3., 1., 4., 1., 11., 5., 25., 15., 3., 17., 6., 11., 7., 1., 2., 4., 0., 14., 12., 12., 52., 9., 17., 5., 7., 1., 5., 3., 5., 5., 15., 6., 7., 16., 7., 25., 10., 2., 0., 0., 11., 2., 4., 2., 10., 4., 4., 2., 2., 5., 2., 5., 0., 1., 2., 0., 2., 2., 0., 4., 0., 5., 3., 2., 6., 2., 1., 1., 1., 8., 5., 0., 4., 1., 1., 1., 3., 0., 1., 1., 4., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0. [...]
+
+6., 0., 1., 6., 7., 5., 5., 0., 6., 20., 1., 14., 17., 0., 14., 2., 1., 2., 17., 2., 4., 25., 11., 24., 20., 10., 2., 1., 5., 0., 8., 11., 33., 13., 3., 16., 5., 7., 9., 0., 1., 4., 0., 9., 12., 10., 42., 9., 21., 8., 4., 2., 4., 4., 6., 2., 8., 3., 11., 16., 5., 28., 12., 3., 0., 2., 9., 2., 3., 4., 8., 4., 1., 2., 2., 2., 0., 4., 2., 1., 2., 0., 3., 2., 1., 7., 0., 8., 4., 1., 3., 0., 2., 1., 1., 8., 1., 0., 1., 3., 2., 2., 2., 3., 3., 1., 2., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0. [...]
+
+6., 1., 5., 3., 10., 2., 9., 0., 5., 14., 0., 10., 12., 1., 16., 4., 0., 2., 21., 1., 3., 31., 11., 16., 25., 6., 3., 0., 2., 1., 5., 6., 26., 24., 7., 18., 3., 16., 13., 3., 2., 4., 1., 20., 12., 13., 47., 16., 27., 10., 3., 1., 5., 5., 6., 2., 11., 8., 7., 20., 8., 19., 9., 2., 1., 1., 9., 1., 3., 3., 5., 2., 2., 1., 2., 2., 5., 2., 0., 2., 1., 0., 0., 2., 4., 3., 3., 6., 2., 1., 3., 2., 3., 1., 1., 13., 1., 0., 2., 2., 2., 3., 3., 2., 0., 2., 1., 0., 0., 0., 0., 7., 0., 0., 4., 0., 0. [...]
+
+7., 2., 2., 3., 8., 4., 2., 1., 10., 27., 0., 11., 26., 2., 13., 2., 2., 3., 14., 1., 4., 33., 12., 27., 17., 7., 0., 1., 5., 4., 13., 11., 37., 15., 5., 10., 4., 16., 9., 2., 1., 2., 1., 13., 9., 17., 41., 15., 20., 12., 5., 1., 2., 0., 8., 6., 10., 9., 8., 11., 11., 19., 11., 5., 1., 3., 8., 3., 4., 4., 5., 1., 8., 4., 2., 5., 0., 4., 1., 3., 0., 0., 2., 0., 4., 5., 2., 1., 1., 3., 5., 0., 5., 3., 5., 2., 2., 0., 1., 3., 1., 0., 0., 1., 4., 0., 2., 0., 0., 0., 0., 2., 0., 0., 4., 0., 0 [...]
+
+9., 0., 6., 5., 7., 3., 3., 0., 5., 17., 1., 9., 11., 0., 12., 2., 0., 5., 25., 1., 3., 14., 0., 33., 33., 4., 0., 0., 1., 5., 6., 4., 22., 18., 1., 21., 3., 8., 9., 2., 1., 3., 1., 15., 15., 17., 39., 14., 27., 8., 8., 2., 4., 2., 8., 5., 9., 7., 3., 10., 7., 31., 10., 1., 3., 2., 2., 1., 2., 0., 9., 5., 7., 6., 2., 0., 5., 4., 2., 2., 0., 0., 1., 0., 1., 2., 3., 4., 2., 2., 3., 1., 2., 0., 3., 5., 0., 0., 0., 2., 3., 3., 4., 3., 3., 1., 2., 0., 0., 0., 0., 4., 0., 0., 1., 0., 0., 0., 3 [...]
+
+9., 1., 1., 3., 3., 2., 6., 0., 8., 10., 1., 11., 18., 1., 17., 0., 0., 5., 19., 2., 7., 32., 10., 19., 21., 8., 0., 1., 4., 0., 10., 7., 24., 8., 1., 12., 6., 17., 8., 1., 0., 5., 5., 8., 4., 22., 42., 8., 27., 11., 2., 1., 5., 2., 2., 2., 6., 1., 5., 14., 6., 18., 9., 4., 1., 0., 8., 0., 5., 0., 4., 4., 3., 6., 1., 6., 4., 0., 0., 2., 2., 0., 2., 2., 1., 1., 3., 3., 1., 0., 6., 1., 2., 0., 3., 9., 1., 0., 4., 0., 5., 2., 4., 0., 2., 0., 1., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0., 5 [...]
+
+11., 1., 1., 4., 7., 4., 12., 1., 6., 17., 0., 17., 17., 0., 17., 4., 2., 4., 9., 1., 3., 26., 12., 25., 20., 9., 1., 1., 3., 5., 10., 5., 11., 21., 3., 18., 3., 17., 11., 4., 0., 2., 1., 14., 10., 17., 47., 12., 29., 10., 4., 0., 5., 3., 9., 2., 11., 9., 6., 15., 2., 17., 8., 3., 0., 2., 12., 1., 7., 4., 4., 4., 5., 3., 2., 7., 6., 3., 1., 2., 1., 0., 2., 1., 1., 4., 2., 5., 3., 2., 4., 0., 1., 1., 2., 7., 3., 0., 0., 1., 1., 3., 0., 1., 0., 1., 3., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0 [...]
+
+12., 1., 2., 6., 10., 4., 5., 0., 13., 5., 1., 18., 23., 0., 21., 6., 2., 4., 24., 6., 0., 1., 9., 17., 33., 6., 1., 2., 3., 0., 12., 13., 25., 19., 2., 21., 6., 9., 4., 0., 1., 4., 2., 13., 12., 18., 43., 11., 19., 14., 2., 0., 6., 1., 8., 2., 10., 7., 12., 15., 6., 17., 6., 3., 4., 0., 9., 2., 3., 1., 8., 4., 5., 5., 3., 4., 2., 1., 3., 1., 0., 0., 2., 3., 2., 7., 3., 6., 1., 4., 5., 2., 3., 2., 4., 4., 5., 0., 2., 0., 4., 3., 2., 2., 2., 0., 3., 0., 0., 0., 0., 0., 0., 0., 4., 0., 0., [...]
+
+7., 1., 0., 3., 7., 3., 7., 2., 10., 16., 0., 18., 33., 1., 15., 4., 1., 0., 8., 0., 5., 34., 11., 15., 30., 11., 3., 0., 4., 2., 9., 5., 28., 7., 3., 15., 5., 14., 10., 3., 0., 5., 2., 8., 15., 14., 45., 11., 25., 5., 4., 1., 2., 1., 7., 2., 9., 10., 5., 23., 5., 15., 11., 3., 1., 2., 5., 1., 1., 2., 2., 4., 3., 3., 3., 5., 4., 4., 0., 3., 3., 0., 3., 3., 1., 9., 5., 3., 2., 2., 4., 0., 1., 0., 4., 10., 1., 0., 0., 1., 1., 4., 0., 4., 1., 2., 3., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0.,  [...]
+
+2., 1., 1., 2., 7., 4., 7., 1., 6., 30., 3., 15., 21., 0., 23., 2., 0., 1., 10., 1., 5., 17., 10., 22., 29., 4., 2., 2., 2., 4., 6., 1., 36., 14., 1., 16., 9., 16., 6., 2., 1., 5., 4., 20., 12., 14., 54., 12., 21., 15., 4., 0., 4., 2., 10., 2., 5., 5., 7., 22., 3., 25., 8., 3., 1., 1., 7., 0., 7., 2., 14., 2., 4., 5., 4., 2., 4., 4., 1., 3., 2., 0., 0., 0., 1., 4., 2., 3., 1., 2., 5., 2., 0., 1., 2., 10., 0., 0., 4., 4., 2., 2., 3., 2., 0., 2., 2., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0., [...]
+
+3., 0., 4., 2., 3., 1., 6., 1., 4., 20., 1., 16., 15., 0., 15., 4., 1., 2., 15., 1., 9., 25., 8., 15., 30., 6., 0., 1., 4., 2., 5., 11., 27., 14., 2., 14., 3., 22., 15., 3., 1., 2., 3., 10., 14., 14., 46., 16., 31., 7., 4., 0., 5., 3., 13., 4., 14., 5., 4., 19., 7., 21., 6., 9., 1., 2., 5., 2., 7., 1., 3., 6., 3., 3., 3., 4., 2., 3., 0., 2., 4., 0., 5., 4., 2., 3., 1., 2., 1., 1., 5., 0., 1., 0., 1., 7., 1., 0., 6., 1., 2., 0., 1., 3., 2., 3., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0.,  [...]
+
+12., 0., 5., 3., 7., 0., 11., 0., 4., 27., 0., 11., 12., 0., 11., 3., 1., 0., 17., 1., 10., 25., 8., 33., 17., 5., 1., 0., 3., 2., 15., 4., 28., 14., 2., 9., 4., 12., 11., 4., 1., 2., 0., 4., 8., 12., 48., 13., 13., 18., 4., 0., 0., 2., 8., 5., 7., 6., 6., 16., 6., 21., 7., 1., 2., 0., 6., 0., 1., 2., 3., 3., 4., 4., 1., 7., 7., 2., 1., 5., 2., 0., 7., 1., 2., 9., 5., 5., 4., 3., 3., 1., 1., 2., 0., 8., 4., 0., 2., 3., 1., 1., 2., 1., 1., 1., 3., 0., 0., 0., 0., 4., 0., 0., 4., 0., 0., 0 [...]
+
+10., 2., 3., 4., 14., 0., 16., 3., 5., 46., 0., 8., 62., 1., 6., 3., 0., 0., 72., 3., 9., 81., 14., 73., 11., 3., 0., 2., 3., 1., 5., 15., 56., 8., 2., 38., 35., 10., 11., 0., 0., 10., 0., 32., 10., 23., 6., 16., 7., 3., 0., 0., 7., 2., 17., 7., 16., 5., 12., 5., 3., 40., 4., 9., 2., 0., 13., 4., 5., 1., 6., 4., 7., 1., 1., 0., 0., 0., 0., 12., 5., 1., 6., 0., 2., 0., 0., 0., 0., 0., 14., 0., 3., 0., 2., 1., 0., 0., 1., 0., 2., 0., 4., 5., 0., 0., 3., 0., 0., 0., 3., 0., 0., 0., 0., 0.,  [...]
+
+3., 1., 0., 2., 13., 0., 20., 1., 2., 67., 2., 13., 55., 1., 11., 0., 0., 4., 68., 8., 7., 86., 13., 83., 19., 2., 0., 1., 6., 4., 15., 6., 44., 16., 3., 37., 30., 17., 8., 0., 3., 5., 2., 27., 3., 32., 6., 18., 9., 6., 4., 0., 7., 5., 20., 1., 8., 2., 10., 7., 2., 36., 5., 11., 2., 0., 19., 1., 9., 2., 10., 3., 1., 1., 0., 2., 0., 6., 1., 20., 8., 2., 5., 0., 3., 0., 0., 0., 0., 0., 11., 0., 2., 2., 1., 2., 0., 0., 0., 0., 4., 0., 2., 3., 3., 0., 3., 0., 2., 0., 2., 0., 0., 0., 0., 0.,  [...]
+
+11., 1., 0., 1., 8., 0., 18., 0., 6., 49., 0., 12., 61., 0., 3., 0., 0., 2., 71., 6., 5., 84., 9., 65., 11., 3., 0., 2., 4., 2., 8., 6., 53., 18., 0., 47., 23., 14., 5., 0., 1., 9., 4., 18., 6., 25., 9., 7., 10., 2., 3., 0., 11., 3., 13., 6., 14., 5., 9., 3., 1., 37., 6., 7., 0., 0., 12., 5., 7., 0., 20., 0., 5., 2., 1., 0., 0., 4., 0., 28., 13., 2., 1., 2., 2., 0., 0., 0., 0., 0., 5., 3., 5., 1., 2., 2., 0., 0., 2., 0., 0., 0., 0., 0., 4., 0., 1., 0., 0., 0., 1., 0., 0., 0., 0., 0., 4., [...]
+
+12., 1., 3., 7., 11., 0., 12., 1., 8., 49., 3., 10., 44., 2., 3., 1., 0., 4., 71., 7., 3., 85., 11., 67., 13., 2., 0., 1., 1., 4., 17., 10., 60., 9., 3., 32., 34., 14., 6., 0., 2., 8., 3., 31., 4., 18., 9., 11., 1., 1., 2., 0., 10., 1., 19., 9., 14., 5., 6., 8., 7., 39., 8., 11., 4., 0., 10., 7., 16., 1., 18., 0., 3., 0., 2., 1., 0., 6., 0., 12., 8., 2., 4., 1., 0., 0., 0., 0., 0., 0., 10., 2., 6., 1., 2., 2., 3., 0., 2., 0., 1., 0., 1., 2., 3., 0., 2., 0., 0., 0., 1., 0., 0., 0., 3., 0. [...]
+
+7., 1., 0., 4., 9., 0., 15., 2., 4., 50., 1., 13., 55., 0., 4., 1., 0., 4., 57., 8., 7., 74., 12., 82., 9., 5., 0., 0., 2., 2., 17., 9., 61., 14., 3., 35., 27., 16., 6., 0., 1., 4., 1., 19., 7., 29., 8., 13., 7., 3., 1., 0., 8., 6., 21., 8., 11., 0., 11., 3., 2., 31., 6., 4., 2., 0., 14., 2., 13., 2., 12., 0., 3., 2., 1., 3., 0., 7., 1., 13., 10., 6., 2., 0., 2., 0., 0., 0., 0., 0., 14., 2., 3., 5., 3., 1., 0., 0., 2., 0., 1., 0., 1., 1., 0., 0., 7., 0., 1., 0., 1., 0., 0., 0., 3., 0., 0 [...]
+
+5., 2., 2., 1., 7., 0., 17., 1., 6., 55., 1., 8., 62., 0., 4., 3., 0., 3., 61., 7., 3., 87., 11., 73., 9., 5., 0., 0., 1., 3., 15., 10., 64., 7., 2., 33., 30., 15., 8., 0., 1., 4., 0., 18., 7., 30., 2., 16., 5., 3., 2., 0., 12., 5., 20., 10., 16., 4., 14., 3., 5., 41., 12., 5., 0., 0., 11., 4., 6., 3., 9., 2., 1., 1., 2., 0., 0., 8., 3., 13., 14., 2., 2., 1., 1., 0., 0., 0., 0., 0., 12., 1., 6., 2., 4., 0., 0., 0., 0., 0., 2., 0., 4., 2., 0., 0., 3., 0., 0., 0., 0., 0., 0., 0., 3., 0., 5 [...]
+
+16., 2., 1., 3., 21., 2., 37., 4., 12., 167., 0., 16., 220., 3., 24., 3., 0., 4., 92., 4., 19., 261., 40., 370., 45., 19., 1., 2., 6., 5., 57., 32., 230., 40., 8., 148., 17., 33., 8., 0., 2., 12., 14., 84., 15., 87., 18., 47., 43., 14., 6., 2., 24., 4., 37., 7., 45., 10., 28., 6., 13., 10., 1., 0., 2., 0., 17., 4., 8., 5., 20., 2., 5., 4., 2., 5., 1., 1., 7., 0., 13., 1., 11., 0., 4., 4., 0., 8., 138., 12., 1946., 89., 102., 198., 95., 108., 74., 16., 12., 14., 8., 3., 2., 2., 2., 1., 7. [...]
+
+14., 2., 3., 6., 16., 2., 33., 0., 9., 162., 1., 27., 197., 4., 8., 7., 1., 4., 80., 4., 21., 288., 45., 355., 42., 18., 1., 3., 7., 10., 49., 29., 249., 42., 11., 161., 18., 43., 6., 0., 2., 24., 10., 79., 12., 89., 10., 34., 42., 8., 6., 2., 29., 6., 39., 8., 55., 11., 41., 8., 13., 5., 1., 0., 2., 0., 31., 4., 10., 6., 30., 4., 19., 2., 3., 3., 0., 1., 2., 3., 10., 1., 11., 2., 8., 2., 0., 6., 144., 8., 1868., 84., 113., 250., 99., 109., 56., 19., 9., 15., 16., 1., 1., 10., 5., 4., 8. [...]
+
+14., 1., 5., 11., 16., 7., 31., 0., 9., 152., 1., 22., 219., 4., 12., 8., 0., 3., 74., 3., 12., 299., 36., 295., 42., 15., 1., 1., 6., 9., 50., 29., 223., 40., 8., 183., 12., 45., 8., 0., 2., 20., 7., 73., 15., 71., 17., 26., 51., 15., 2., 0., 16., 8., 32., 11., 49., 7., 38., 7., 11., 7., 1., 0., 0., 0., 23., 4., 20., 1., 29., 7., 12., 6., 4., 4., 1., 1., 1., 3., 14., 0., 7., 0., 7., 1., 2., 2., 135., 11., 1921., 90., 92., 216., 125., 120., 66., 16., 13., 16., 16., 4., 5., 8., 4., 6., 12 [...]
+
+8., 1., 4., 2., 8., 4., 10., 2., 10., 31., 1., 15., 25., 1., 15., 4., 2., 5., 17., 1., 6., 17., 11., 19., 30., 8., 2., 1., 0., 1., 4., 10., 21., 15., 4., 19., 4., 9., 10., 4., 2., 4., 0., 22., 13., 13., 47., 16., 14., 9., 2., 1., 6., 3., 10., 5., 10., 4., 7., 21., 6., 33., 11., 3., 0., 1., 6., 2., 4., 7., 4., 1., 3., 4., 0., 5., 3., 2., 0., 2., 2., 0., 2., 1., 3., 6., 3., 4., 5., 4., 4., 3., 1., 1., 1., 9., 4., 0., 6., 1., 2., 4., 6., 2., 4., 1., 4., 0., 0., 0., 0., 1., 0., 0., 4., 0., 0 [...]
+
+11., 0., 1., 2., 9., 7., 6., 0., 5., 24., 0., 15., 25., 0., 11., 1., 0., 0., 25., 0., 6., 33., 13., 21., 26., 7., 3., 3., 3., 2., 15., 10., 26., 18., 1., 7., 5., 13., 11., 0., 2., 2., 2., 10., 12., 16., 43., 12., 20., 6., 2., 1., 8., 1., 2., 4., 7., 8., 8., 12., 5., 25., 10., 2., 1., 4., 4., 3., 1., 1., 6., 4., 6., 3., 1., 2., 6., 0., 0., 3., 0., 0., 3., 1., 0., 8., 2., 0., 3., 2., 5., 1., 2., 0., 6., 9., 2., 0., 2., 3., 2., 1., 0., 2., 1., 1., 2., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., [...]
+
+9., 0., 1., 4., 11., 4., 6., 1., 8., 14., 3., 11., 23., 2., 16., 2., 1., 4., 16., 0., 0., 9., 15., 22., 26., 1., 0., 0., 4., 1., 8., 5., 20., 11., 5., 18., 3., 10., 7., 2., 0., 3., 1., 12., 11., 15., 51., 11., 19., 12., 6., 1., 5., 1., 11., 1., 17., 5., 7., 12., 8., 26., 8., 6., 3., 1., 6., 1., 1., 4., 4., 2., 6., 7., 3., 5., 0., 3., 1., 1., 3., 0., 2., 5., 3., 9., 2., 6., 1., 1., 5., 0., 1., 0., 4., 6., 4., 0., 2., 1., 3., 0., 1., 2., 4., 0., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0.,  [...]
+
+8., 0., 0., 3., 7., 4., 5., 2., 8., 17., 0., 14., 18., 3., 18., 1., 1., 3., 19., 1., 4., 26., 10., 24., 24., 5., 0., 2., 1., 1., 9., 8., 23., 12., 2., 10., 4., 11., 7., 1., 2., 3., 3., 12., 6., 22., 38., 9., 18., 6., 7., 3., 6., 4., 10., 3., 10., 6., 8., 15., 5., 19., 15., 8., 2., 1., 7., 2., 1., 4., 6., 4., 3., 6., 2., 3., 2., 3., 2., 1., 2., 0., 3., 1., 1., 9., 3., 2., 3., 3., 4., 0., 2., 2., 2., 6., 0., 0., 1., 1., 2., 4., 2., 4., 3., 0., 2., 0., 0., 0., 0., 1., 0., 0., 4., 0., 0., 0. [...]
+
+10., 1., 1., 3., 9., 2., 5., 2., 8., 34., 1., 9., 17., 0., 17., 1., 1., 1., 16., 0., 5., 32., 10., 22., 30., 9., 1., 0., 1., 0., 5., 7., 33., 11., 0., 23., 5., 14., 5., 2., 1., 0., 3., 11., 10., 20., 45., 14., 27., 10., 3., 2., 9., 2., 8., 7., 7., 7., 10., 11., 7., 13., 4., 4., 0., 1., 6., 0., 1., 2., 4., 2., 2., 3., 2., 7., 2., 3., 1., 5., 1., 0., 2., 3., 1., 10., 0., 2., 3., 1., 4., 0., 1., 0., 0., 7., 2., 0., 0., 1., 2., 1., 2., 0., 4., 2., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0.,  [...]
+
+11., 1., 2., 4., 7., 1., 7., 0., 5., 20., 4., 13., 23., 1., 14., 2., 0., 3., 14., 1., 3., 26., 11., 37., 26., 4., 0., 2., 6., 3., 6., 9., 29., 12., 2., 13., 5., 11., 11., 1., 0., 4., 1., 16., 10., 17., 46., 12., 16., 6., 3., 0., 3., 1., 3., 5., 8., 6., 5., 10., 6., 18., 12., 3., 3., 0., 8., 0., 3., 1., 9., 4., 5., 4., 0., 5., 2., 4., 2., 2., 2., 0., 4., 2., 3., 6., 0., 3., 4., 1., 3., 0., 1., 0., 1., 6., 1., 0., 2., 1., 4., 3., 1., 0., 4., 0., 1., 0., 0., 0., 0., 5., 0., 0., 0., 0., 0.,  [...]
+
+10., 1., 0., 3., 9., 4., 4., 2., 4., 26., 1., 13., 18., 2., 24., 4., 1., 2., 13., 0., 4., 22., 15., 20., 32., 3., 2., 1., 1., 0., 7., 3., 30., 13., 6., 17., 3., 16., 7., 2., 0., 4., 4., 5., 5., 17., 56., 16., 18., 6., 9., 0., 5., 2., 13., 2., 11., 4., 8., 18., 7., 27., 9., 2., 0., 2., 6., 1., 1., 3., 5., 5., 8., 3., 3., 4., 2., 3., 3., 2., 1., 0., 0., 2., 3., 6., 2., 4., 0., 2., 5., 0., 2., 2., 0., 5., 1., 0., 2., 0., 4., 2., 1., 0., 1., 2., 3., 0., 0., 0., 0., 2., 0., 0., 5., 0., 0., 0. [...]
+
+14., 0., 2., 2., 7., 2., 8., 2., 5., 17., 1., 15., 24., 0., 8., 2., 1., 2., 7., 2., 4., 16., 7., 22., 19., 5., 0., 1., 0., 1., 5., 4., 19., 14., 1., 15., 2., 14., 11., 3., 1., 4., 5., 10., 12., 17., 49., 14., 19., 10., 6., 1., 6., 3., 8., 5., 10., 2., 5., 18., 12., 28., 8., 3., 1., 2., 11., 1., 1., 0., 5., 3., 6., 10., 3., 3., 4., 3., 2., 2., 1., 0., 2., 4., 3., 8., 1., 3., 4., 1., 1., 1., 1., 2., 0., 6., 3., 0., 2., 0., 0., 0., 3., 3., 2., 1., 3., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., [...]
+
+5., 1., 1., 7., 6., 3., 1., 0., 6., 19., 1., 14., 12., 0., 14., 1., 4., 1., 28., 2., 1., 15., 13., 22., 21., 4., 0., 1., 5., 1., 7., 5., 20., 18., 4., 10., 5., 13., 12., 0., 0., 3., 2., 14., 14., 18., 55., 11., 19., 7., 0., 0., 3., 1., 6., 3., 8., 3., 5., 19., 5., 16., 3., 1., 1., 3., 10., 3., 2., 3., 3., 3., 6., 7., 0., 2., 4., 2., 2., 3., 2., 0., 3., 4., 3., 6., 2., 4., 5., 2., 0., 2., 2., 0., 0., 6., 1., 0., 1., 4., 0., 4., 0., 4., 1., 1., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0 [...]
+
+5., 1., 0., 5., 6., 2., 14., 1., 7., 18., 3., 10., 18., 0., 11., 4., 1., 1., 24., 1., 5., 23., 23., 15., 25., 4., 1., 1., 1., 2., 5., 7., 23., 15., 3., 16., 2., 16., 12., 0., 1., 3., 3., 16., 13., 11., 36., 13., 21., 13., 4., 0., 5., 3., 17., 6., 10., 8., 7., 15., 9., 16., 8., 3., 2., 1., 2., 2., 3., 3., 5., 5., 6., 3., 1., 6., 1., 0., 0., 3., 2., 0., 4., 1., 3., 5., 1., 6., 0., 2., 2., 0., 2., 0., 2., 8., 1., 0., 2., 1., 1., 3., 3., 4., 1., 1., 4., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0. [...]
+
+7., 2., 2., 7., 8., 4., 0., 1., 6., 25., 1., 13., 37., 3., 19., 4., 3., 1., 13., 1., 6., 26., 13., 26., 33., 5., 0., 0., 4., 2., 9., 7., 15., 17., 3., 20., 3., 7., 10., 3., 0., 2., 1., 11., 7., 20., 44., 10., 26., 14., 8., 2., 4., 6., 4., 2., 6., 6., 10., 16., 14., 16., 5., 2., 2., 0., 12., 1., 4., 3., 5., 1., 2., 2., 2., 2., 4., 2., 1., 1., 4., 0., 1., 1., 1., 6., 2., 6., 3., 1., 4., 0., 0., 0., 3., 8., 0., 0., 2., 2., 2., 1., 2., 3., 1., 1., 1., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0.,  [...]
+
+4., 1., 1., 5., 12., 4., 6., 1., 4., 25., 2., 7., 26., 0., 10., 5., 0., 1., 23., 1., 4., 18., 12., 28., 29., 5., 3., 0., 2., 0., 13., 9., 20., 9., 2., 18., 3., 15., 5., 0., 1., 4., 0., 12., 7., 15., 52., 14., 22., 12., 2., 1., 11., 1., 3., 4., 9., 6., 8., 19., 7., 27., 6., 4., 3., 1., 6., 0., 4., 2., 4., 0., 1., 7., 2., 5., 5., 3., 2., 3., 2., 0., 1., 1., 2., 4., 5., 7., 2., 0., 5., 1., 3., 2., 4., 6., 1., 0., 1., 2., 2., 3., 1., 2., 2., 0., 5., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., 0. [...]
+
+9., 1., 2., 6., 7., 2., 6., 4., 6., 13., 0., 21., 19., 1., 14., 1., 2., 2., 15., 3., 5., 27., 12., 28., 30., 6., 1., 0., 5., 2., 8., 7., 28., 11., 4., 14., 5., 8., 3., 1., 2., 4., 0., 9., 12., 21., 33., 7., 25., 10., 5., 0., 5., 2., 8., 1., 16., 3., 12., 13., 5., 25., 6., 3., 2., 1., 4., 1., 1., 1., 8., 1., 2., 1., 3., 5., 2., 6., 0., 5., 2., 0., 2., 3., 0., 8., 1., 5., 2., 1., 3., 4., 1., 0., 3., 4., 2., 0., 0., 3., 4., 2., 2., 1., 4., 2., 0., 0., 0., 0., 0., 1., 0., 0., 4., 0., 0., 0., [...]
+
+4., 0., 1., 6., 7., 1., 3., 2., 6., 26., 1., 6., 11., 0., 17., 3., 1., 2., 17., 1., 5., 16., 16., 19., 20., 5., 2., 2., 5., 1., 7., 7., 25., 22., 4., 20., 8., 12., 9., 4., 2., 2., 5., 8., 5., 14., 49., 10., 18., 8., 3., 0., 4., 1., 8., 2., 13., 6., 11., 8., 6., 20., 4., 5., 0., 0., 6., 0., 0., 3., 8., 2., 5., 4., 2., 7., 4., 2., 0., 1., 3., 0., 5., 2., 4., 2., 5., 4., 0., 2., 5., 2., 4., 2., 3., 6., 1., 0., 4., 0., 2., 3., 1., 2., 4., 1., 2., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0., 0., 1 [...]
+
+2., 2., 5., 2., 11., 3., 5., 1., 5., 29., 0., 16., 27., 2., 19., 6., 2., 3., 20., 4., 3., 18., 7., 26., 18., 9., 1., 1., 2., 1., 8., 6., 42., 15., 3., 12., 3., 19., 8., 2., 2., 4., 1., 15., 11., 17., 32., 8., 15., 5., 8., 2., 9., 1., 3., 2., 11., 7., 4., 20., 7., 28., 8., 4., 1., 0., 4., 1., 4., 2., 2., 6., 5., 4., 0., 4., 2., 4., 3., 1., 3., 0., 2., 1., 2., 10., 0., 6., 2., 1., 3., 0., 1., 1., 2., 6., 1., 0., 2., 0., 1., 1., 0., 1., 0., 0., 2., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0. [...]
+
+9., 2., 3., 2., 6., 4., 3., 0., 3., 30., 3., 17., 27., 0., 19., 4., 1., 3., 19., 12., 5., 26., 10., 20., 24., 5., 1., 0., 2., 4., 15., 8., 28., 14., 5., 18., 3., 14., 11., 2., 3., 5., 2., 11., 14., 25., 46., 15., 19., 12., 4., 1., 5., 2., 12., 2., 15., 6., 4., 8., 6., 19., 11., 1., 1., 0., 10., 1., 3., 2., 7., 3., 3., 4., 1., 3., 1., 3., 0., 0., 2., 0., 2., 0., 0., 4., 2., 0., 1., 0., 4., 1., 3., 0., 2., 12., 4., 0., 3., 2., 1., 1., 2., 0., 0., 2., 3., 0., 0., 0., 0., 2., 0., 0., 4., 0., [...]
+
+6., 0., 2., 5., 11., 2., 5., 0., 4., 25., 1., 20., 36., 1., 10., 6., 0., 2., 20., 0., 1., 31., 14., 28., 27., 9., 1., 2., 2., 0., 9., 6., 33., 12., 3., 18., 4., 15., 5., 0., 0., 7., 4., 10., 19., 19., 44., 15., 17., 8., 3., 2., 4., 0., 8., 2., 10., 5., 9., 24., 4., 20., 9., 3., 1., 0., 4., 1., 1., 3., 9., 2., 1., 7., 1., 3., 2., 1., 0., 2., 2., 0., 3., 0., 3., 5., 3., 1., 9., 2., 1., 1., 2., 1., 2., 6., 2., 0., 0., 1., 1., 1., 1., 4., 2., 1., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0 [...]
+
+9., 0., 0., 2., 10., 1., 6., 0., 7., 15., 2., 1., 12., 2., 12., 3., 1., 3., 18., 2., 3., 17., 15., 16., 27., 4., 2., 2., 1., 1., 15., 12., 30., 14., 3., 16., 4., 16., 9., 5., 0., 5., 0., 10., 7., 22., 41., 12., 15., 7., 5., 2., 10., 3., 7., 5., 5., 7., 5., 11., 8., 23., 5., 4., 1., 1., 6., 2., 2., 1., 6., 4., 2., 5., 4., 7., 3., 4., 3., 1., 2., 0., 4., 1., 4., 3., 2., 6., 3., 2., 3., 0., 1., 1., 5., 9., 0., 0., 0., 0., 2., 2., 2., 4., 3., 2., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0 [...]
+
+7., 2., 2., 3., 10., 3., 7., 1., 4., 14., 1., 15., 14., 0., 8., 3., 1., 2., 23., 2., 2., 27., 12., 26., 39., 7., 1., 1., 2., 4., 11., 6., 18., 15., 1., 13., 3., 20., 5., 2., 0., 2., 1., 8., 12., 19., 58., 12., 17., 3., 6., 1., 4., 0., 10., 3., 9., 9., 17., 16., 2., 23., 5., 4., 2., 1., 2., 1., 1., 4., 7., 1., 4., 1., 3., 5., 2., 0., 0., 1., 1., 0., 1., 2., 3., 4., 2., 9., 2., 2., 2., 2., 0., 3., 1., 5., 3., 0., 1., 2., 5., 3., 3., 1., 1., 2., 1., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0 [...]
+
+8., 1., 5., 3., 2., 1., 6., 2., 8., 31., 1., 9., 18., 2., 12., 5., 0., 4., 18., 4., 2., 10., 12., 31., 35., 1., 0., 0., 3., 0., 5., 5., 14., 17., 6., 18., 4., 16., 10., 2., 2., 4., 4., 3., 9., 17., 52., 17., 28., 12., 3., 3., 3., 2., 8., 6., 12., 5., 5., 21., 5., 23., 7., 2., 0., 2., 8., 1., 1., 7., 5., 3., 2., 4., 0., 2., 3., 5., 1., 1., 0., 0., 3., 4., 1., 2., 0., 5., 2., 0., 3., 0., 7., 0., 4., 7., 4., 0., 2., 5., 2., 4., 2., 1., 3., 0., 2., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0., [...]
+
+9., 0., 3., 5., 10., 4., 5., 3., 8., 24., 1., 26., 30., 0., 11., 7., 1., 0., 18., 2., 8., 14., 13., 19., 30., 8., 2., 0., 5., 1., 8., 7., 22., 17., 3., 23., 5., 15., 12., 3., 3., 3., 2., 13., 10., 8., 47., 10., 21., 9., 3., 1., 7., 2., 8., 4., 9., 9., 11., 18., 4., 12., 11., 4., 6., 1., 3., 1., 2., 3., 4., 1., 4., 4., 1., 4., 4., 1., 0., 2., 4., 0., 2., 3., 5., 4., 2., 4., 3., 0., 5., 3., 2., 1., 2., 9., 1., 0., 3., 2., 4., 3., 2., 1., 1., 1., 0., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0.,  [...]
+
+10., 2., 1., 1., 12., 1., 3., 0., 5., 28., 0., 15., 29., 1., 15., 8., 0., 3., 13., 3., 11., 9., 16., 32., 26., 10., 2., 3., 3., 3., 9., 10., 37., 18., 1., 16., 3., 16., 11., 0., 1., 4., 1., 15., 9., 17., 58., 9., 28., 15., 7., 2., 2., 5., 8., 4., 9., 6., 9., 19., 2., 20., 10., 1., 1., 0., 6., 1., 1., 1., 6., 3., 6., 3., 0., 5., 2., 2., 2., 4., 2., 0., 1., 1., 3., 7., 4., 0., 3., 4., 2., 1., 1., 1., 3., 11., 4., 0., 3., 1., 1., 4., 2., 2., 0., 1., 2., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0 [...]
+
+7., 1., 2., 9., 15., 0., 12., 1., 6., 52., 2., 9., 56., 2., 1., 1., 0., 1., 74., 6., 11., 89., 18., 71., 16., 0., 0., 1., 2., 3., 16., 7., 60., 13., 6., 43., 33., 21., 4., 0., 1., 2., 2., 23., 8., 29., 7., 15., 3., 2., 3., 0., 5., 7., 20., 9., 9., 0., 6., 4., 6., 37., 8., 6., 4., 0., 13., 3., 3., 0., 14., 1., 3., 1., 0., 1., 0., 4., 0., 14., 9., 5., 3., 2., 1., 0., 0., 0., 0., 0., 10., 2., 4., 4., 4., 0., 1., 0., 1., 0., 0., 0., 2., 2., 2., 0., 3., 0., 1., 0., 1., 0., 0., 0., 2., 0., 1., [...]
+
+12., 2., 2., 3., 13., 0., 12., 1., 8., 45., 1., 3., 65., 3., 3., 1., 0., 2., 63., 14., 10., 80., 12., 101., 10., 6., 0., 3., 0., 0., 18., 11., 59., 16., 2., 41., 32., 14., 4., 0., 2., 5., 6., 19., 5., 21., 7., 9., 9., 1., 2., 0., 9., 4., 16., 4., 15., 4., 8., 2., 5., 33., 11., 6., 3., 0., 14., 2., 1., 5., 11., 2., 0., 0., 1., 0., 0., 3., 1., 12., 10., 1., 4., 3., 5., 0., 0., 0., 0., 0., 7., 0., 4., 4., 3., 2., 1., 0., 1., 0., 0., 0., 1., 1., 1., 0., 2., 0., 2., 0., 3., 0., 0., 0., 0., 0. [...]
+
+8., 2., 1., 5., 11., 0., 17., 1., 6., 51., 1., 4., 48., 0., 1., 1., 0., 1., 61., 15., 9., 63., 15., 83., 7., 4., 0., 0., 3., 4., 10., 11., 46., 12., 2., 37., 27., 8., 6., 0., 0., 3., 7., 16., 7., 11., 10., 19., 8., 1., 3., 0., 6., 4., 13., 6., 9., 1., 11., 3., 3., 28., 7., 6., 1., 0., 16., 3., 8., 3., 17., 2., 3., 2., 0., 1., 0., 6., 1., 18., 8., 4., 4., 3., 3., 0., 0., 0., 0., 0., 9., 8., 2., 2., 2., 2., 0., 0., 2., 0., 1., 0., 0., 2., 1., 0., 4., 0., 0., 0., 1., 0., 0., 0., 0., 0., 5., [...]
+
+8., 2., 0., 5., 7., 0., 17., 0., 7., 38., 2., 10., 54., 2., 3., 1., 0., 3., 64., 8., 7., 62., 21., 96., 17., 3., 0., 0., 4., 1., 12., 11., 56., 8., 3., 36., 38., 12., 2., 0., 2., 7., 2., 31., 4., 24., 6., 16., 3., 3., 2., 0., 11., 2., 22., 4., 13., 1., 7., 4., 2., 43., 9., 11., 4., 0., 19., 3., 7., 4., 5., 1., 4., 2., 1., 2., 0., 6., 0., 16., 7., 5., 4., 0., 4., 0., 0., 0., 0., 0., 9., 3., 4., 2., 8., 1., 1., 0., 1., 0., 1., 0., 2., 2., 5., 0., 3., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1., [...]
+
+6., 1., 2., 3., 9., 0., 19., 2., 5., 56., 0., 9., 62., 0., 6., 1., 0., 4., 90., 10., 6., 90., 15., 81., 9., 6., 0., 0., 5., 1., 17., 8., 55., 11., 2., 50., 27., 16., 4., 0., 2., 11., 3., 27., 7., 28., 13., 14., 2., 2., 2., 0., 5., 2., 15., 4., 19., 5., 11., 3., 3., 37., 12., 6., 2., 0., 6., 2., 11., 1., 6., 1., 4., 1., 2., 0., 0., 8., 4., 18., 12., 4., 3., 1., 1., 0., 0., 0., 0., 0., 15., 1., 5., 3., 5., 1., 0., 0., 0., 0., 1., 0., 0., 3., 2., 0., 3., 0., 3., 0., 1., 0., 0., 0., 0., 0.,  [...]
+
+8., 0., 3., 3., 17., 0., 16., 0., 4., 59., 1., 8., 52., 2., 7., 2., 0., 1., 70., 9., 8., 69., 15., 89., 10., 4., 0., 2., 2., 1., 15., 18., 50., 9., 4., 39., 38., 12., 4., 0., 0., 9., 0., 22., 6., 17., 6., 13., 8., 3., 2., 0., 5., 3., 13., 4., 11., 1., 6., 3., 3., 27., 6., 7., 3., 0., 18., 5., 13., 2., 15., 3., 4., 1., 1., 1., 0., 4., 1., 13., 9., 2., 5., 1., 2., 0., 0., 0., 0., 0., 13., 2., 3., 0., 7., 0., 1., 0., 1., 0., 1., 0., 3., 4., 4., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 2. [...]
+
+8., 0., 1., 6., 6., 0., 11., 1., 11., 41., 1., 9., 58., 1., 5., 1., 0., 3., 65., 11., 6., 88., 15., 88., 11., 4., 0., 0., 5., 3., 18., 9., 53., 6., 3., 45., 33., 16., 2., 0., 2., 7., 2., 29., 6., 21., 4., 13., 4., 3., 2., 0., 13., 5., 19., 5., 15., 2., 7., 0., 6., 39., 8., 5., 1., 0., 11., 6., 5., 6., 12., 2., 5., 2., 0., 0., 0., 4., 3., 19., 11., 2., 2., 0., 1., 0., 0., 0., 0., 0., 9., 2., 3., 3., 4., 2., 1., 0., 0., 0., 0., 0., 1., 1., 2., 0., 2., 0., 1., 0., 1., 0., 0., 0., 1., 0., 2. [...]
+
+20., 3., 2., 12., 16., 7., 31., 3., 13., 173., 4., 31., 212., 5., 12., 7., 0., 8., 82., 2., 21., 291., 42., 352., 46., 16., 1., 1., 7., 6., 55., 25., 239., 42., 8., 159., 11., 41., 3., 0., 2., 15., 12., 85., 20., 77., 15., 38., 36., 9., 1., 1., 28., 5., 41., 7., 45., 12., 31., 8., 10., 7., 4., 0., 0., 0., 12., 2., 23., 3., 25., 4., 12., 5., 6., 0., 0., 1., 1., 1., 14., 4., 5., 3., 5., 1., 0., 7., 137., 8., 1875., 93., 107., 206., 87., 97., 70., 7., 9., 13., 12., 1., 1., 5., 3., 2., 8., 5 [...]
+
+10., 3., 2., 12., 28., 3., 29., 3., 19., 157., 5., 28., 194., 7., 11., 5., 1., 10., 75., 6., 15., 293., 48., 309., 55., 13., 4., 1., 6., 5., 46., 34., 209., 34., 5., 148., 17., 45., 8., 0., 0., 18., 8., 91., 15., 77., 23., 33., 44., 14., 4., 0., 24., 6., 34., 7., 43., 9., 28., 2., 9., 6., 1., 0., 3., 0., 23., 3., 11., 1., 30., 4., 7., 3., 2., 4., 1., 1., 1., 0., 6., 5., 6., 1., 6., 0., 1., 7., 142., 11., 1928., 98., 105., 202., 106., 100., 74., 21., 16., 19., 13., 1., 2., 3., 2., 3., 7., [...]
+
+16., 4., 3., 10., 38., 9., 33., 4., 15., 172., 5., 33., 199., 4., 15., 9., 1., 7., 83., 2., 19., 307., 49., 329., 38., 19., 0., 2., 11., 4., 50., 22., 264., 28., 9., 154., 16., 49., 6., 0., 4., 12., 11., 88., 20., 89., 12., 33., 44., 14., 4., 1., 21., 6., 35., 11., 55., 8., 31., 6., 11., 8., 2., 0., 0., 0., 14., 10., 12., 0., 36., 5., 10., 1., 1., 0., 0., 3., 4., 1., 18., 4., 8., 2., 10., 1., 1., 4., 162., 9., 1813., 80., 107., 225., 95., 107., 83., 17., 7., 20., 3., 0., 3., 17., 6., 3., [...]
+
+10., 0., 3., 7., 11., 4., 7., 1., 8., 12., 1., 22., 32., 0., 16., 5., 1., 3., 8., 3., 4., 21., 14., 21., 21., 8., 1., 0., 6., 3., 9., 9., 35., 8., 7., 16., 2., 17., 11., 1., 1., 5., 0., 11., 9., 30., 51., 9., 25., 4., 4., 2., 4., 2., 3., 4., 15., 2., 7., 18., 4., 25., 9., 6., 1., 1., 10., 2., 5., 2., 6., 4., 5., 5., 0., 3., 2., 0., 1., 5., 0., 0., 1., 2., 4., 5., 3., 4., 4., 1., 1., 1., 0., 2., 1., 3., 2., 0., 1., 3., 0., 2., 4., 1., 2., 0., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+11., 0., 3., 7., 8., 3., 8., 0., 7., 10., 0., 11., 22., 1., 15., 3., 2., 2., 12., 0., 1., 26., 9., 28., 24., 5., 1., 1., 0., 3., 10., 6., 29., 13., 2., 8., 6., 11., 11., 0., 0., 4., 1., 7., 10., 24., 44., 12., 19., 8., 4., 1., 2., 1., 11., 4., 7., 10., 4., 19., 10., 9., 11., 0., 0., 0., 2., 1., 3., 1., 3., 9., 2., 2., 2., 2., 4., 3., 0., 2., 1., 0., 2., 1., 2., 7., 1., 1., 3., 1., 5., 2., 2., 2., 2., 4., 3., 0., 3., 0., 1., 2., 3., 5., 3., 0., 3., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.,  [...]
+
+9., 2., 1., 5., 5., 3., 7., 2., 11., 28., 3., 14., 17., 1., 18., 1., 0., 1., 7., 2., 7., 30., 12., 32., 30., 7., 1., 1., 4., 2., 4., 12., 30., 28., 3., 15., 4., 12., 10., 3., 0., 5., 3., 8., 14., 18., 52., 16., 22., 8., 2., 2., 0., 2., 13., 3., 5., 7., 2., 12., 8., 15., 3., 3., 1., 1., 12., 1., 2., 2., 4., 3., 3., 8., 4., 4., 4., 1., 2., 1., 2., 0., 3., 3., 0., 4., 5., 2., 3., 1., 4., 1., 1., 0., 1., 9., 3., 0., 3., 1., 1., 1., 6., 2., 3., 0., 3., 0., 0., 0., 0., 6., 0., 0., 3., 0., 0.,  [...]
+
+5., 0., 3., 3., 5., 1., 7., 2., 7., 36., 0., 14., 35., 2., 13., 4., 0., 4., 12., 0., 4., 29., 13., 31., 23., 7., 1., 3., 4., 2., 4., 4., 31., 13., 3., 11., 4., 13., 10., 4., 1., 2., 0., 8., 8., 17., 50., 13., 28., 5., 4., 1., 1., 3., 8., 2., 9., 6., 8., 11., 6., 22., 8., 4., 2., 0., 2., 1., 5., 1., 5., 3., 0., 2., 1., 6., 5., 2., 2., 0., 3., 0., 2., 2., 2., 2., 0., 3., 2., 0., 5., 0., 5., 0., 2., 5., 0., 0., 1., 2., 0., 1., 1., 2., 1., 1., 2., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0.,  [...]
+
+1., 0., 1., 7., 10., 7., 5., 1., 10., 22., 2., 6., 17., 0., 12., 2., 2., 4., 18., 7., 2., 19., 15., 23., 31., 5., 1., 2., 1., 2., 8., 19., 20., 18., 5., 11., 3., 17., 12., 0., 0., 3., 5., 12., 10., 17., 54., 16., 20., 12., 2., 1., 5., 2., 5., 1., 9., 5., 8., 10., 9., 28., 8., 4., 0., 3., 6., 0., 3., 1., 4., 2., 0., 4., 2., 2., 0., 6., 3., 3., 3., 0., 0., 3., 2., 6., 2., 4., 4., 0., 6., 1., 1., 2., 3., 4., 3., 0., 5., 2., 1., 2., 3., 2., 0., 2., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., [...]
+
+3., 1., 1., 9., 12., 2., 8., 0., 8., 29., 1., 8., 14., 2., 18., 2., 0., 1., 16., 1., 5., 24., 13., 15., 29., 4., 0., 1., 0., 2., 8., 6., 21., 15., 4., 11., 2., 12., 13., 5., 1., 3., 0., 14., 15., 17., 44., 12., 26., 6., 8., 2., 3., 1., 3., 2., 7., 7., 6., 10., 11., 25., 4., 4., 2., 3., 4., 1., 3., 0., 9., 3., 4., 1., 2., 5., 2., 2., 0., 2., 4., 0., 1., 1., 5., 6., 2., 5., 2., 2., 6., 1., 2., 1., 1., 11., 7., 0., 2., 0., 3., 1., 2., 1., 3., 2., 3., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0.,  [...]
+
+6., 1., 3., 8., 15., 2., 5., 2., 7., 23., 1., 15., 19., 0., 11., 1., 0., 3., 16., 2., 3., 11., 12., 27., 19., 9., 2., 1., 4., 3., 10., 6., 22., 18., 4., 18., 7., 12., 9., 4., 1., 4., 5., 16., 7., 11., 42., 12., 23., 11., 4., 2., 5., 2., 7., 4., 11., 6., 7., 18., 3., 19., 9., 2., 3., 0., 5., 0., 4., 3., 9., 2., 7., 5., 0., 4., 3., 2., 1., 2., 0., 0., 0., 1., 1., 3., 2., 4., 3., 2., 6., 0., 2., 0., 3., 9., 2., 0., 1., 3., 4., 1., 1., 2., 3., 3., 1., 0., 0., 0., 0., 3., 0., 0., 0., 0., 0.,  [...]
+
+9., 1., 2., 4., 5., 5., 2., 1., 7., 15., 2., 11., 18., 2., 15., 4., 0., 3., 14., 3., 3., 20., 7., 15., 24., 3., 1., 1., 1., 2., 8., 4., 30., 15., 3., 11., 4., 12., 9., 2., 1., 4., 4., 13., 11., 15., 48., 20., 16., 8., 4., 1., 5., 1., 6., 1., 10., 5., 6., 17., 3., 16., 8., 5., 1., 1., 7., 2., 3., 2., 6., 7., 3., 5., 0., 3., 2., 3., 0., 1., 2., 0., 1., 3., 2., 8., 3., 5., 1., 1., 7., 1., 4., 1., 0., 5., 2., 0., 3., 3., 2., 5., 3., 0., 3., 1., 1., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0., [...]
+
+10., 0., 3., 9., 8., 0., 5., 0., 4., 29., 1., 10., 28., 2., 21., 5., 1., 4., 20., 1., 4., 35., 7., 21., 18., 6., 2., 1., 2., 1., 9., 8., 28., 15., 3., 9., 11., 20., 15., 1., 1., 5., 4., 13., 14., 16., 45., 13., 13., 13., 5., 1., 4., 2., 5., 0., 12., 5., 12., 21., 6., 19., 6., 4., 1., 0., 8., 0., 3., 1., 2., 5., 7., 7., 1., 5., 2., 2., 1., 2., 3., 0., 2., 3., 4., 0., 3., 2., 2., 1., 1., 0., 5., 1., 0., 11., 2., 0., 2., 2., 1., 1., 1., 0., 4., 1., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0. [...]
+
+14., 0., 2., 3., 7., 2., 9., 0., 4., 15., 1., 5., 23., 0., 14., 4., 3., 2., 16., 2., 7., 30., 18., 27., 31., 8., 3., 1., 4., 2., 5., 11., 22., 20., 4., 14., 6., 13., 10., 0., 0., 4., 1., 18., 7., 25., 43., 11., 30., 7., 6., 2., 8., 1., 8., 7., 7., 4., 7., 16., 6., 33., 4., 4., 2., 0., 3., 0., 1., 1., 9., 6., 5., 3., 0., 1., 1., 0., 2., 3., 5., 0., 2., 1., 2., 8., 2., 5., 3., 0., 2., 1., 3., 3., 2., 7., 1., 0., 3., 0., 0., 2., 1., 0., 6., 0., 2., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., 0. [...]
+
+3., 0., 1., 6., 9., 3., 2., 0., 7., 20., 0., 13., 18., 2., 19., 3., 0., 0., 25., 4., 3., 14., 14., 31., 31., 8., 1., 0., 1., 4., 6., 8., 29., 20., 2., 7., 3., 11., 3., 1., 0., 6., 0., 10., 15., 10., 56., 10., 29., 10., 8., 1., 4., 2., 17., 1., 6., 8., 7., 13., 4., 21., 10., 2., 1., 2., 5., 0., 3., 4., 8., 0., 7., 2., 3., 5., 2., 1., 1., 4., 2., 0., 1., 3., 4., 12., 4., 2., 1., 1., 2., 0., 2., 0., 1., 7., 4., 0., 1., 2., 2., 2., 1., 0., 3., 0., 3., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0.,  [...]
+
+7., 2., 0., 4., 12., 2., 7., 1., 2., 8., 2., 13., 27., 0., 14., 3., 0., 2., 10., 0., 5., 25., 12., 21., 20., 9., 1., 2., 5., 3., 9., 5., 27., 20., 1., 22., 2., 21., 9., 2., 2., 4., 3., 10., 8., 29., 46., 5., 23., 9., 3., 2., 7., 2., 6., 3., 8., 5., 7., 13., 10., 21., 5., 3., 0., 0., 6., 4., 3., 2., 5., 2., 4., 2., 4., 3., 4., 1., 2., 3., 3., 0., 0., 1., 2., 7., 0., 2., 1., 0., 4., 1., 0., 3., 4., 8., 0., 0., 4., 0., 3., 3., 1., 4., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0.,  [...]
+
+6., 2., 1., 3., 9., 2., 3., 3., 4., 25., 1., 13., 21., 0., 12., 1., 2., 1., 23., 2., 3., 13., 9., 30., 28., 6., 1., 1., 7., 0., 5., 5., 30., 21., 4., 17., 3., 18., 10., 2., 2., 5., 1., 16., 10., 19., 47., 10., 24., 9., 3., 0., 5., 5., 8., 5., 9., 9., 4., 19., 6., 26., 9., 2., 0., 2., 6., 1., 6., 1., 5., 4., 8., 3., 0., 4., 0., 3., 0., 4., 3., 0., 2., 2., 0., 8., 0., 1., 2., 1., 3., 0., 6., 2., 0., 12., 0., 0., 3., 3., 2., 3., 1., 2., 4., 0., 2., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0. [...]
+
+10., 0., 3., 2., 4., 2., 6., 0., 12., 20., 2., 15., 28., 3., 15., 4., 0., 3., 14., 5., 5., 22., 6., 22., 27., 7., 0., 1., 1., 1., 8., 5., 41., 20., 2., 15., 4., 15., 9., 1., 1., 3., 1., 16., 5., 18., 39., 8., 18., 7., 6., 1., 7., 1., 5., 3., 12., 8., 9., 11., 8., 27., 6., 3., 1., 2., 11., 0., 3., 1., 4., 2., 4., 5., 1., 1., 4., 0., 0., 4., 2., 0., 1., 2., 1., 7., 3., 6., 1., 2., 7., 3., 2., 1., 2., 10., 3., 0., 2., 1., 0., 1., 2., 0., 2., 3., 3., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0 [...]
+
+4., 2., 3., 5., 11., 3., 4., 0., 6., 10., 0., 16., 23., 3., 19., 6., 0., 1., 23., 4., 6., 22., 11., 33., 30., 12., 1., 1., 7., 0., 9., 7., 29., 16., 2., 19., 4., 15., 5., 1., 2., 2., 3., 13., 17., 20., 47., 7., 21., 9., 4., 0., 6., 2., 11., 1., 12., 4., 9., 14., 4., 26., 7., 4., 0., 1., 9., 2., 5., 0., 3., 1., 6., 3., 7., 4., 7., 1., 3., 4., 4., 0., 1., 1., 2., 5., 3., 5., 0., 1., 3., 1., 2., 0., 1., 8., 2., 0., 2., 2., 2., 2., 4., 3., 5., 0., 2., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0.,  [...]
+
+5., 1., 1., 2., 8., 2., 8., 5., 6., 4., 0., 17., 25., 0., 14., 5., 1., 1., 17., 5., 5., 23., 11., 18., 21., 7., 1., 1., 4., 0., 6., 13., 25., 13., 4., 12., 2., 10., 10., 1., 2., 4., 1., 14., 8., 11., 49., 13., 18., 8., 6., 0., 4., 1., 4., 5., 6., 5., 9., 14., 5., 22., 9., 3., 2., 1., 10., 1., 3., 2., 7., 3., 3., 7., 1., 0., 3., 2., 0., 3., 0., 0., 5., 1., 1., 7., 2., 5., 4., 4., 3., 3., 4., 1., 3., 7., 1., 0., 1., 1., 1., 3., 2., 1., 4., 1., 4., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0. [...]
+
+8., 0., 3., 7., 14., 5., 10., 2., 2., 25., 0., 16., 14., 1., 12., 4., 2., 2., 16., 2., 2., 15., 12., 13., 26., 4., 1., 1., 3., 1., 7., 9., 21., 13., 2., 4., 2., 18., 8., 2., 0., 1., 3., 9., 12., 18., 39., 12., 29., 4., 3., 1., 10., 3., 9., 3., 9., 10., 5., 12., 1., 27., 9., 4., 0., 1., 5., 1., 2., 2., 5., 2., 5., 4., 3., 6., 3., 3., 0., 2., 0., 0., 1., 1., 0., 9., 2., 1., 3., 4., 1., 2., 2., 0., 0., 9., 4., 0., 1., 2., 0., 2., 1., 4., 4., 0., 2., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0., 0 [...]
+
+9., 1., 2., 6., 10., 4., 4., 0., 4., 39., 1., 9., 27., 1., 16., 1., 2., 2., 26., 0., 6., 10., 8., 30., 26., 7., 2., 2., 1., 0., 6., 11., 24., 16., 6., 5., 5., 12., 6., 1., 2., 3., 2., 15., 6., 18., 39., 18., 15., 11., 8., 1., 6., 2., 4., 5., 8., 5., 11., 11., 6., 18., 4., 1., 1., 2., 12., 1., 0., 2., 6., 2., 6., 3., 1., 3., 2., 2., 0., 2., 1., 0., 0., 0., 1., 5., 3., 4., 2., 2., 7., 1., 2., 1., 4., 5., 1., 0., 1., 5., 0., 4., 5., 0., 1., 0., 2., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0. [...]
+
+13., 1., 2., 7., 7., 2., 6., 0., 5., 14., 2., 12., 26., 3., 17., 2., 3., 2., 27., 3., 2., 19., 6., 17., 31., 4., 1., 1., 3., 2., 12., 9., 32., 12., 4., 14., 4., 13., 9., 4., 2., 1., 4., 15., 13., 22., 46., 20., 15., 11., 2., 2., 9., 1., 5., 1., 9., 3., 11., 13., 7., 23., 9., 1., 0., 4., 10., 0., 2., 1., 6., 4., 2., 0., 2., 5., 3., 3., 1., 2., 3., 0., 1., 2., 3., 6., 2., 3., 2., 0., 7., 2., 1., 1., 2., 6., 1., 0., 2., 4., 2., 2., 4., 4., 3., 2., 3., 0., 0., 0., 0., 4., 0., 0., 1., 0., 0., [...]
+
+13., 0., 1., 4., 7., 5., 9., 0., 7., 18., 2., 17., 20., 2., 9., 4., 2., 2., 13., 4., 2., 14., 18., 23., 27., 2., 1., 0., 4., 4., 9., 12., 26., 20., 2., 17., 3., 17., 5., 3., 1., 3., 5., 15., 5., 33., 41., 14., 22., 6., 6., 2., 4., 2., 10., 2., 2., 5., 10., 15., 9., 30., 6., 5., 1., 2., 6., 1., 7., 1., 4., 3., 3., 5., 3., 5., 7., 4., 2., 3., 5., 0., 4., 1., 1., 7., 3., 7., 2., 3., 5., 0., 2., 2., 3., 6., 3., 0., 4., 4., 1., 6., 4., 4., 4., 1., 2., 0., 0., 0., 0., 2., 0., 0., 6., 0., 0., 0 [...]
+
+4., 1., 4., 7., 7., 2., 7., 1., 4., 35., 2., 8., 21., 2., 20., 2., 2., 3., 17., 0., 5., 28., 9., 27., 17., 2., 1., 0., 1., 1., 9., 5., 24., 19., 4., 24., 8., 17., 10., 1., 0., 1., 4., 14., 14., 14., 42., 13., 23., 9., 8., 2., 3., 1., 6., 1., 11., 9., 8., 18., 3., 26., 7., 7., 0., 0., 8., 0., 1., 1., 6., 0., 5., 2., 1., 3., 4., 6., 2., 4., 0., 0., 0., 5., 0., 8., 0., 5., 1., 4., 4., 1., 1., 2., 2., 4., 0., 0., 3., 3., 2., 3., 2., 1., 2., 0., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0., [...]
+
+8., 1., 3., 1., 7., 3., 3., 2., 6., 32., 0., 9., 16., 0., 9., 1., 1., 0., 17., 1., 3., 12., 11., 31., 23., 6., 3., 0., 4., 2., 7., 10., 19., 18., 4., 12., 1., 17., 10., 5., 1., 5., 0., 16., 7., 14., 45., 14., 24., 4., 5., 3., 0., 1., 4., 2., 14., 5., 7., 18., 3., 23., 7., 2., 1., 1., 7., 0., 1., 1., 5., 7., 2., 1., 2., 5., 1., 4., 0., 2., 2., 0., 3., 2., 3., 7., 1., 1., 3., 1., 4., 2., 1., 0., 4., 8., 2., 0., 2., 2., 3., 1., 1., 0., 2., 0., 2., 0., 0., 0., 0., 1., 0., 0., 5., 0., 0., 0., [...]
+
+9., 1., 0., 4., 10., 0., 15., 1., 7., 44., 0., 9., 62., 0., 4., 2., 0., 0., 69., 9., 12., 77., 15., 84., 9., 2., 0., 1., 6., 4., 16., 6., 43., 12., 1., 42., 38., 23., 6., 0., 2., 12., 0., 24., 2., 20., 6., 18., 3., 3., 0., 0., 8., 7., 8., 3., 19., 4., 10., 1., 3., 41., 10., 8., 1., 0., 13., 2., 12., 4., 14., 1., 3., 0., 0., 1., 0., 3., 0., 17., 8., 1., 4., 0., 2., 0., 0., 0., 0., 0., 10., 3., 1., 0., 5., 1., 0., 0., 3., 0., 1., 0., 0., 3., 2., 0., 1., 0., 2., 0., 1., 0., 0., 0., 1., 0.,  [...]
+
+7., 0., 3., 5., 12., 0., 16., 3., 8., 45., 1., 6., 69., 1., 4., 1., 0., 2., 81., 6., 5., 91., 20., 74., 13., 4., 0., 1., 3., 1., 14., 8., 55., 10., 2., 32., 41., 12., 6., 0., 0., 11., 4., 26., 3., 26., 8., 16., 4., 3., 2., 0., 7., 2., 19., 6., 17., 4., 10., 2., 5., 33., 7., 10., 0., 0., 11., 8., 11., 3., 10., 2., 6., 3., 1., 0., 0., 9., 3., 11., 6., 2., 3., 1., 2., 0., 0., 0., 0., 0., 11., 5., 1., 1., 3., 1., 1., 0., 4., 0., 1., 0., 0., 2., 0., 0., 4., 0., 0., 0., 3., 0., 0., 0., 1., 0., [...]
+
+6., 0., 2., 5., 9., 0., 10., 1., 11., 55., 2., 5., 56., 1., 4., 0., 0., 4., 66., 7., 12., 81., 15., 82., 16., 3., 0., 2., 3., 5., 17., 10., 59., 19., 2., 41., 30., 18., 1., 0., 1., 3., 9., 20., 9., 18., 7., 14., 12., 3., 2., 0., 11., 3., 16., 4., 12., 3., 13., 6., 5., 35., 11., 2., 1., 0., 7., 3., 6., 3., 12., 1., 4., 0., 0., 2., 0., 6., 0., 18., 11., 3., 4., 1., 0., 0., 0., 0., 0., 0., 9., 4., 3., 1., 2., 1., 2., 0., 0., 0., 2., 0., 1., 3., 2., 0., 4., 0., 1., 0., 0., 0., 0., 0., 1., 0. [...]
+
+6., 0., 2., 5., 9., 0., 15., 3., 9., 53., 2., 6., 47., 2., 7., 1., 0., 1., 66., 4., 5., 83., 14., 93., 8., 0., 0., 2., 2., 3., 21., 7., 73., 14., 3., 44., 30., 9., 8., 0., 1., 4., 5., 18., 6., 25., 7., 12., 5., 2., 1., 0., 12., 4., 10., 5., 17., 2., 10., 3., 4., 45., 11., 5., 4., 0., 9., 4., 13., 3., 9., 4., 3., 0., 0., 0., 0., 2., 1., 16., 8., 5., 2., 1., 3., 0., 0., 0., 0., 0., 13., 1., 3., 1., 1., 0., 1., 0., 2., 0., 3., 0., 0., 0., 1., 0., 2., 0., 1., 0., 1., 0., 0., 0., 1., 0., 1.,  [...]
+
+8., 1., 2., 7., 12., 0., 17., 1., 5., 50., 0., 6., 62., 1., 7., 0., 0., 1., 58., 8., 6., 77., 20., 84., 13., 5., 0., 1., 2., 1., 10., 8., 42., 9., 1., 43., 29., 15., 1., 0., 0., 5., 1., 21., 5., 26., 6., 10., 4., 1., 3., 0., 10., 9., 20., 4., 11., 1., 6., 4., 5., 42., 3., 9., 3., 0., 11., 3., 5., 2., 9., 3., 3., 1., 1., 0., 0., 2., 1., 9., 11., 7., 4., 0., 3., 0., 0., 0., 0., 0., 10., 3., 4., 1., 6., 0., 2., 0., 0., 0., 1., 0., 0., 2., 3., 0., 3., 0., 1., 0., 1., 0., 0., 0., 1., 0., 0.,  [...]
+
+7., 2., 1., 8., 9., 0., 9., 2., 12., 54., 3., 4., 73., 0., 6., 1., 0., 3., 81., 9., 7., 70., 13., 80., 10., 6., 0., 0., 2., 3., 17., 14., 43., 13., 2., 39., 32., 12., 5., 0., 2., 2., 2., 28., 5., 13., 8., 6., 2., 5., 2., 0., 7., 4., 19., 3., 16., 3., 6., 5., 1., 30., 9., 8., 1., 0., 16., 5., 9., 2., 8., 2., 5., 0., 1., 0., 0., 4., 1., 18., 17., 4., 4., 1., 1., 0., 0., 0., 0., 0., 10., 2., 4., 4., 4., 2., 1., 0., 1., 0., 0., 0., 1., 2., 3., 0., 1., 0., 1., 0., 2., 0., 0., 0., 0., 0., 3.,  [...]
+
+9., 1., 1., 4., 11., 0., 17., 5., 9., 56., 1., 11., 64., 4., 4., 2., 0., 0., 88., 8., 9., 74., 18., 77., 15., 3., 0., 4., 6., 2., 17., 16., 60., 8., 2., 37., 42., 14., 3., 0., 1., 4., 1., 31., 7., 24., 7., 13., 1., 2., 2., 0., 6., 2., 18., 5., 21., 4., 9., 6., 1., 40., 8., 6., 3., 0., 15., 2., 9., 2., 12., 2., 5., 0., 1., 1., 0., 7., 3., 14., 8., 6., 5., 0., 3., 0., 0., 0., 0., 0., 11., 2., 2., 1., 4., 3., 1., 0., 0., 0., 0., 0., 2., 3., 0., 0., 3., 0., 1., 0., 1., 0., 0., 0., 1., 0., 2. [...]
+
+27., 2., 2., 8., 19., 3., 32., 1., 20., 173., 1., 23., 213., 7., 25., 4., 0., 6., 93., 1., 16., 308., 40., 330., 29., 18., 0., 2., 6., 2., 29., 41., 234., 43., 4., 160., 16., 39., 8., 0., 5., 23., 6., 91., 19., 98., 10., 32., 48., 15., 1., 2., 34., 11., 25., 7., 50., 11., 21., 4., 14., 9., 3., 0., 1., 0., 24., 7., 14., 0., 35., 4., 16., 10., 0., 6., 1., 0., 4., 3., 7., 0., 8., 3., 9., 1., 0., 5., 127., 10., 1851., 92., 105., 245., 102., 97., 69., 16., 18., 25., 15., 0., 2., 5., 5., 7., 1 [...]
+
+12., 6., 6., 8., 23., 6., 28., 2., 17., 167., 3., 28., 173., 4., 12., 7., 0., 7., 84., 2., 14., 273., 42., 303., 38., 12., 0., 1., 5., 5., 34., 25., 215., 34., 8., 155., 13., 35., 3., 0., 5., 7., 9., 79., 23., 77., 14., 32., 42., 19., 1., 1., 33., 5., 32., 13., 50., 11., 29., 11., 13., 8., 1., 0., 2., 0., 32., 11., 8., 3., 23., 6., 7., 9., 1., 2., 0., 0., 3., 1., 9., 3., 6., 3., 8., 2., 1., 3., 144., 10., 1924., 92., 112., 259., 92., 97., 75., 16., 15., 14., 20., 0., 3., 6., 6., 4., 8.,  [...]
+
+12., 0., 1., 6., 8., 2., 6., 0., 8., 18., 0., 11., 22., 0., 15., 2., 0., 3., 16., 0., 10., 23., 11., 19., 38., 12., 1., 1., 2., 3., 6., 5., 15., 19., 2., 12., 2., 16., 8., 1., 1., 7., 3., 12., 12., 14., 55., 8., 16., 6., 5., 2., 5., 2., 6., 3., 16., 1., 10., 13., 5., 23., 9., 3., 2., 0., 4., 1., 1., 3., 2., 5., 1., 5., 2., 5., 3., 2., 3., 2., 2., 0., 1., 1., 2., 7., 2., 3., 0., 7., 5., 0., 4., 1., 2., 6., 4., 0., 0., 2., 4., 1., 4., 3., 3., 0., 3., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., [...]
+
+16., 2., 1., 6., 5., 0., 8., 3., 4., 26., 0., 17., 21., 1., 15., 4., 0., 2., 16., 3., 2., 6., 12., 35., 21., 5., 0., 1., 2., 3., 9., 4., 36., 18., 1., 12., 2., 16., 6., 1., 1., 2., 1., 16., 15., 16., 43., 18., 12., 13., 3., 1., 5., 1., 6., 5., 10., 8., 10., 21., 4., 19., 8., 2., 2., 4., 10., 2., 2., 1., 3., 4., 3., 4., 3., 3., 2., 5., 1., 1., 2., 0., 3., 2., 0., 4., 2., 6., 5., 1., 3., 0., 6., 1., 3., 8., 2., 0., 3., 0., 2., 0., 0., 2., 3., 0., 0., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., [...]
+
+5., 0., 3., 3., 9., 5., 9., 2., 6., 22., 3., 2., 34., 1., 16., 3., 1., 0., 22., 1., 4., 30., 17., 32., 23., 4., 2., 3., 4., 0., 6., 4., 31., 18., 1., 12., 2., 12., 7., 4., 3., 3., 2., 8., 18., 15., 54., 11., 13., 6., 4., 1., 3., 2., 5., 1., 9., 5., 6., 25., 5., 25., 3., 4., 1., 2., 6., 0., 4., 3., 7., 4., 4., 6., 1., 4., 5., 2., 2., 2., 3., 0., 4., 2., 2., 10., 0., 3., 1., 3., 5., 4., 2., 0., 5., 6., 0., 0., 1., 3., 3., 5., 0., 2., 1., 1., 2., 0., 0., 0., 0., 3., 0., 0., 5., 0., 0., 0.,  [...]
+
+5., 2., 1., 7., 4., 1., 4., 0., 9., 26., 0., 11., 18., 1., 13., 4., 0., 2., 19., 2., 5., 22., 13., 23., 24., 5., 1., 1., 4., 2., 6., 11., 31., 16., 4., 15., 0., 17., 11., 2., 1., 2., 2., 13., 11., 10., 51., 18., 20., 7., 3., 1., 5., 5., 15., 1., 5., 7., 12., 16., 8., 18., 5., 2., 3., 0., 4., 3., 3., 2., 2., 2., 3., 5., 2., 8., 1., 2., 2., 2., 1., 0., 1., 1., 2., 12., 0., 1., 3., 1., 4., 1., 4., 0., 1., 10., 0., 0., 2., 0., 0., 2., 1., 3., 4., 0., 1., 0., 0., 0., 0., 3., 0., 0., 0., 0., 0 [...]
+
+15., 3., 3., 2., 9., 2., 5., 0., 10., 16., 3., 11., 31., 3., 12., 8., 0., 2., 25., 2., 4., 6., 12., 14., 23., 5., 0., 0., 1., 4., 15., 5., 38., 15., 2., 15., 3., 15., 3., 3., 0., 3., 1., 13., 9., 11., 50., 7., 26., 10., 5., 0., 7., 2., 11., 3., 6., 5., 7., 12., 5., 19., 8., 2., 3., 2., 8., 1., 3., 2., 4., 3., 4., 3., 2., 6., 4., 0., 0., 3., 2., 0., 3., 0., 1., 10., 3., 6., 3., 1., 3., 1., 2., 0., 2., 6., 1., 0., 2., 2., 4., 1., 3., 3., 2., 1., 1., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0.,  [...]
+
+13., 2., 1., 3., 17., 5., 7., 1., 3., 23., 0., 15., 20., 1., 16., 4., 1., 2., 25., 1., 6., 32., 18., 19., 28., 7., 1., 1., 4., 1., 4., 7., 17., 16., 5., 26., 9., 17., 10., 1., 0., 4., 2., 15., 12., 23., 44., 9., 20., 5., 3., 0., 1., 2., 6., 4., 11., 1., 3., 10., 3., 21., 5., 1., 2., 0., 10., 0., 2., 1., 1., 4., 2., 5., 1., 0., 2., 2., 2., 1., 4., 0., 3., 4., 3., 7., 2., 4., 0., 0., 5., 0., 3., 0., 2., 8., 2., 0., 5., 6., 5., 1., 1., 1., 1., 0., 1., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., [...]
+
+8., 1., 2., 6., 6., 5., 6., 0., 5., 10., 1., 12., 25., 1., 13., 1., 1., 1., 17., 3., 5., 22., 12., 12., 25., 2., 1., 1., 4., 5., 9., 9., 21., 15., 2., 16., 2., 12., 7., 2., 3., 2., 2., 10., 7., 15., 60., 11., 16., 8., 4., 0., 7., 3., 6., 2., 7., 6., 8., 9., 6., 23., 11., 1., 1., 1., 11., 0., 1., 1., 5., 4., 7., 5., 3., 5., 2., 3., 1., 1., 0., 0., 1., 0., 2., 7., 4., 2., 3., 0., 2., 0., 0., 2., 2., 11., 3., 0., 2., 0., 2., 2., 1., 1., 0., 0., 1., 0., 0., 0., 0., 4., 0., 0., 0., 0., 0., 0. [...]
+
+11., 1., 1., 5., 6., 3., 5., 1., 6., 25., 0., 13., 16., 2., 15., 2., 2., 2., 8., 1., 5., 21., 10., 13., 31., 5., 0., 2., 2., 1., 11., 15., 25., 16., 1., 13., 2., 13., 10., 2., 3., 5., 1., 7., 10., 17., 41., 9., 14., 9., 3., 3., 5., 2., 7., 2., 12., 7., 2., 19., 6., 20., 6., 0., 2., 0., 8., 0., 3., 0., 3., 2., 2., 5., 1., 6., 5., 3., 0., 2., 2., 0., 2., 2., 3., 1., 1., 6., 3., 0., 5., 1., 3., 0., 1., 10., 4., 0., 2., 0., 2., 3., 1., 2., 0., 2., 3., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0.,  [...]
+
+7., 2., 2., 7., 8., 1., 6., 0., 8., 30., 0., 11., 20., 1., 25., 7., 0., 5., 15., 2., 1., 5., 13., 23., 27., 2., 1., 0., 4., 2., 10., 6., 18., 19., 3., 22., 4., 15., 11., 3., 1., 5., 2., 12., 7., 15., 44., 6., 19., 6., 2., 1., 4., 5., 3., 2., 4., 9., 11., 19., 8., 16., 10., 5., 1., 2., 5., 0., 3., 3., 9., 3., 6., 4., 1., 1., 3., 0., 2., 0., 5., 0., 4., 3., 5., 8., 2., 4., 0., 1., 4., 3., 0., 0., 4., 2., 2., 0., 4., 2., 2., 3., 2., 0., 3., 1., 3., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+11., 1., 3., 1., 8., 2., 2., 2., 9., 9., 1., 16., 15., 0., 19., 2., 2., 3., 25., 5., 2., 29., 9., 35., 15., 8., 1., 0., 3., 1., 12., 4., 22., 16., 5., 13., 3., 18., 9., 4., 0., 5., 2., 16., 14., 11., 52., 13., 24., 12., 3., 0., 2., 2., 5., 3., 7., 4., 9., 18., 3., 30., 4., 3., 0., 0., 8., 0., 3., 1., 3., 3., 6., 3., 1., 6., 6., 3., 1., 1., 3., 0., 3., 3., 2., 7., 3., 2., 2., 4., 6., 0., 2., 0., 0., 4., 2., 0., 1., 0., 2., 4., 0., 4., 4., 0., 0., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0. [...]
+
+6., 1., 3., 4., 4., 5., 9., 1., 4., 36., 0., 2., 24., 0., 20., 4., 3., 4., 15., 1., 3., 30., 15., 21., 26., 9., 1., 0., 3., 1., 5., 5., 33., 14., 3., 16., 2., 8., 6., 2., 2., 5., 0., 17., 7., 16., 47., 11., 23., 9., 3., 1., 6., 3., 5., 1., 13., 7., 12., 15., 9., 20., 11., 4., 2., 3., 4., 1., 3., 1., 6., 5., 2., 2., 2., 4., 2., 4., 0., 4., 2., 0., 3., 1., 2., 7., 1., 10., 2., 0., 3., 1., 1., 0., 1., 6., 3., 0., 4., 3., 3., 0., 1., 1., 3., 0., 2., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0. [...]
+
+1., 0., 1., 7., 5., 1., 4., 1., 5., 14., 0., 14., 25., 0., 16., 5., 1., 3., 20., 4., 5., 13., 9., 23., 21., 6., 0., 2., 2., 1., 4., 3., 23., 17., 3., 12., 1., 15., 10., 5., 3., 5., 1., 12., 11., 13., 47., 7., 11., 11., 3., 0., 6., 3., 4., 1., 13., 3., 10., 18., 5., 23., 4., 3., 1., 0., 6., 1., 3., 1., 2., 2., 4., 3., 4., 4., 5., 1., 1., 2., 2., 0., 0., 1., 0., 3., 0., 4., 2., 3., 3., 1., 2., 2., 2., 5., 2., 0., 1., 2., 4., 3., 3., 1., 2., 1., 1., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0 [...]
+
+9., 3., 1., 6., 5., 0., 8., 1., 4., 22., 1., 10., 17., 1., 15., 4., 0., 1., 12., 1., 6., 19., 11., 23., 27., 4., 2., 0., 5., 1., 7., 9., 21., 17., 3., 18., 4., 13., 13., 5., 0., 2., 3., 20., 8., 22., 48., 10., 22., 9., 9., 5., 5., 1., 5., 2., 6., 4., 10., 16., 6., 21., 9., 4., 0., 3., 5., 1., 1., 0., 3., 3., 2., 5., 0., 4., 2., 1., 2., 3., 4., 0., 5., 5., 1., 7., 2., 8., 0., 5., 7., 0., 1., 1., 4., 9., 1., 0., 2., 1., 2., 1., 2., 1., 2., 0., 3., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0. [...]
+
+13., 0., 0., 3., 5., 2., 5., 4., 8., 29., 1., 9., 32., 2., 14., 1., 3., 3., 16., 8., 7., 24., 13., 28., 33., 2., 0., 3., 4., 2., 9., 2., 19., 12., 2., 20., 0., 18., 8., 4., 0., 3., 3., 12., 17., 25., 55., 10., 33., 6., 4., 0., 7., 2., 8., 3., 9., 9., 7., 16., 7., 21., 12., 5., 2., 0., 6., 4., 0., 4., 8., 6., 2., 6., 3., 3., 4., 2., 0., 1., 1., 0., 4., 1., 2., 5., 4., 3., 2., 0., 10., 0., 1., 2., 5., 6., 5., 0., 1., 1., 3., 3., 1., 2., 3., 3., 1., 0., 0., 0., 0., 3., 0., 0., 4., 0., 0., 0 [...]
+
+9., 2., 2., 2., 6., 3., 8., 0., 4., 26., 1., 8., 16., 0., 16., 0., 0., 1., 17., 2., 3., 26., 8., 22., 25., 6., 0., 1., 2., 2., 3., 12., 21., 15., 4., 18., 3., 11., 9., 1., 1., 3., 0., 16., 10., 20., 37., 14., 23., 8., 5., 0., 1., 0., 3., 7., 11., 5., 8., 20., 8., 22., 11., 2., 2., 1., 6., 2., 6., 3., 5., 2., 7., 3., 3., 7., 2., 5., 0., 4., 5., 0., 2., 1., 3., 3., 6., 4., 2., 5., 7., 1., 2., 2., 1., 7., 3., 0., 2., 3., 5., 1., 4., 3., 0., 0., 2., 0., 0., 0., 0., 0., 0., 0., 3., 0., 0., 0. [...]
+
+14., 3., 2., 3., 5., 1., 8., 2., 6., 7., 2., 11., 9., 3., 17., 1., 1., 2., 8., 3., 2., 20., 13., 27., 30., 6., 0., 1., 6., 1., 10., 5., 35., 18., 0., 10., 4., 4., 9., 2., 0., 5., 2., 13., 9., 17., 48., 22., 33., 10., 8., 2., 6., 3., 14., 2., 8., 3., 7., 17., 8., 15., 8., 6., 2., 2., 9., 2., 1., 0., 8., 2., 6., 5., 3., 7., 4., 1., 0., 0., 5., 0., 3., 0., 2., 9., 3., 3., 5., 1., 2., 1., 2., 0., 1., 6., 4., 0., 3., 3., 3., 1., 2., 2., 5., 2., 3., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., 0.,  [...]
+
+2., 2., 1., 3., 7., 3., 4., 3., 8., 13., 2., 20., 24., 2., 13., 2., 0., 3., 21., 3., 3., 25., 2., 17., 28., 9., 0., 2., 6., 3., 7., 2., 21., 13., 6., 12., 4., 16., 11., 0., 1., 1., 2., 8., 9., 22., 55., 16., 29., 4., 3., 2., 5., 1., 5., 0., 6., 9., 12., 17., 7., 14., 5., 5., 1., 1., 9., 0., 5., 0., 5., 5., 4., 3., 6., 7., 6., 1., 1., 1., 3., 0., 1., 3., 1., 7., 1., 3., 0., 1., 1., 0., 3., 1., 0., 9., 1., 0., 2., 5., 1., 4., 3., 1., 3., 3., 1., 0., 0., 0., 0., 1., 0., 0., 8., 0., 0., 0.,  [...]
+
+1., 1., 6., 6., 9., 1., 9., 0., 0., 19., 0., 16., 31., 3., 13., 2., 2., 1., 27., 0., 2., 22., 17., 15., 23., 10., 0., 1., 1., 4., 10., 14., 27., 16., 3., 16., 4., 9., 8., 3., 2., 3., 1., 23., 13., 18., 40., 12., 22., 14., 1., 0., 4., 4., 10., 4., 9., 4., 9., 19., 11., 16., 8., 4., 1., 3., 2., 1., 5., 2., 3., 1., 4., 4., 1., 3., 3., 5., 1., 2., 2., 0., 4., 1., 3., 2., 1., 8., 0., 3., 4., 0., 2., 0., 2., 2., 3., 0., 0., 1., 0., 2., 2., 0., 2., 2., 1., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0. [...]
+
+8., 3., 1., 2., 10., 3., 7., 1., 9., 26., 1., 13., 22., 0., 15., 3., 1., 5., 21., 2., 8., 4., 12., 24., 29., 5., 1., 0., 2., 0., 4., 5., 17., 11., 3., 14., 5., 10., 12., 4., 0., 4., 3., 14., 14., 17., 44., 14., 24., 9., 1., 0., 3., 4., 10., 2., 12., 7., 7., 23., 8., 20., 5., 1., 1., 4., 4., 1., 1., 1., 3., 4., 4., 4., 1., 7., 2., 4., 0., 1., 3., 0., 0., 1., 3., 7., 1., 3., 2., 2., 4., 1., 1., 3., 4., 10., 3., 0., 5., 3., 3., 3., 1., 3., 2., 2., 0., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., [...]
+
+4., 2., 1., 4., 9., 3., 3., 0., 4., 28., 0., 14., 19., 0., 9., 3., 2., 1., 23., 2., 4., 21., 15., 23., 27., 2., 0., 1., 3., 2., 6., 7., 14., 8., 5., 18., 5., 8., 9., 2., 0., 4., 3., 12., 7., 17., 48., 10., 28., 5., 4., 1., 1., 1., 2., 0., 19., 11., 5., 11., 4., 12., 6., 4., 0., 3., 8., 1., 6., 1., 8., 3., 7., 7., 3., 5., 2., 3., 1., 4., 3., 0., 4., 2., 2., 3., 0., 5., 3., 4., 3., 1., 2., 0., 2., 7., 3., 0., 2., 3., 1., 1., 4., 1., 1., 0., 3., 0., 0., 0., 0., 4., 0., 0., 0., 0., 0., 0., 5 [...]
+
+3., 1., 2., 6., 2., 3., 4., 2., 7., 23., 1., 14., 25., 1., 14., 2., 1., 2., 21., 2., 4., 31., 14., 26., 32., 6., 2., 1., 4., 3., 11., 6., 10., 16., 3., 17., 6., 19., 12., 3., 0., 8., 2., 10., 13., 10., 37., 11., 21., 10., 3., 1., 6., 3., 7., 4., 9., 7., 12., 13., 7., 24., 7., 3., 1., 2., 8., 1., 3., 1., 2., 1., 6., 4., 2., 4., 3., 0., 5., 1., 3., 0., 1., 2., 0., 7., 0., 8., 3., 4., 4., 2., 3., 0., 5., 4., 1., 0., 2., 4., 5., 1., 3., 4., 2., 3., 3., 0., 0., 0., 0., 3., 0., 0., 5., 0., 0., [...]
+
+10., 2., 0., 1., 8., 5., 4., 0., 10., 21., 2., 10., 12., 1., 14., 4., 1., 1., 17., 4., 4., 24., 13., 33., 17., 6., 0., 1., 2., 1., 5., 4., 33., 14., 4., 20., 3., 10., 7., 1., 3., 6., 2., 6., 11., 15., 51., 18., 19., 12., 4., 1., 5., 4., 2., 2., 9., 5., 5., 13., 5., 21., 8., 3., 0., 1., 7., 0., 2., 0., 7., 2., 6., 6., 0., 2., 3., 2., 1., 0., 0., 0., 4., 2., 0., 5., 4., 4., 0., 1., 5., 1., 4., 2., 3., 5., 0., 0., 4., 1., 1., 2., 2., 1., 2., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0 [...]
+
+13., 2., 3., 1., 17., 0., 17., 0., 6., 45., 1., 8., 57., 1., 4., 3., 0., 1., 64., 5., 6., 69., 12., 71., 9., 5., 0., 1., 2., 2., 20., 17., 49., 9., 1., 38., 35., 19., 4., 0., 0., 8., 5., 22., 5., 23., 10., 10., 6., 3., 3., 0., 6., 5., 15., 6., 15., 3., 9., 1., 3., 43., 11., 3., 0., 0., 16., 3., 5., 0., 8., 3., 2., 0., 0., 2., 0., 3., 2., 18., 8., 4., 4., 2., 2., 0., 0., 0., 0., 0., 7., 1., 5., 1., 1., 1., 1., 0., 0., 0., 0., 0., 1., 2., 1., 0., 1., 0., 0., 0., 1., 0., 0., 0., 1., 0., 2., [...]
+
+13., 1., 2., 2., 10., 0., 11., 1., 9., 44., 1., 10., 48., 0., 4., 1., 0., 1., 78., 8., 5., 76., 14., 79., 13., 0., 0., 1., 2., 4., 11., 10., 41., 17., 2., 39., 32., 20., 5., 0., 3., 3., 2., 20., 5., 22., 7., 21., 3., 5., 5., 0., 9., 5., 20., 2., 22., 3., 9., 3., 6., 30., 19., 9., 1., 0., 8., 3., 8., 2., 16., 1., 2., 0., 2., 0., 0., 4., 2., 18., 8., 2., 4., 2., 2., 0., 0., 0., 0., 0., 8., 3., 1., 1., 3., 1., 0., 0., 1., 0., 2., 0., 1., 5., 2., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0., 0., 1 [...]
+
+14., 0., 1., 7., 10., 0., 13., 1., 5., 52., 1., 8., 63., 1., 4., 2., 0., 1., 69., 8., 11., 101., 19., 71., 7., 6., 0., 0., 0., 2., 18., 7., 51., 10., 0., 38., 28., 12., 1., 0., 1., 5., 3., 29., 13., 17., 11., 14., 8., 5., 3., 0., 11., 4., 10., 7., 15., 6., 10., 1., 2., 33., 10., 5., 2., 0., 15., 3., 10., 1., 12., 0., 4., 0., 0., 1., 0., 8., 3., 14., 7., 2., 4., 2., 3., 0., 0., 0., 0., 0., 9., 2., 4., 5., 3., 1., 0., 0., 0., 0., 0., 0., 0., 4., 2., 0., 1., 0., 1., 0., 0., 0., 0., 0., 1.,  [...]
+
+12., 2., 1., 4., 12., 0., 8., 2., 4., 60., 1., 7., 62., 1., 6., 0., 0., 0., 80., 2., 10., 81., 13., 79., 13., 4., 0., 0., 3., 0., 20., 14., 63., 11., 2., 35., 40., 7., 3., 0., 0., 4., 2., 21., 6., 21., 8., 11., 3., 1., 5., 0., 7., 6., 23., 5., 16., 3., 7., 2., 2., 29., 8., 10., 3., 0., 12., 2., 5., 1., 14., 2., 2., 0., 1., 2., 0., 2., 1., 21., 8., 3., 5., 1., 2., 0., 0., 0., 0., 0., 10., 6., 3., 1., 2., 2., 2., 0., 1., 0., 1., 0., 1., 0., 2., 0., 1., 0., 0., 0., 2., 0., 0., 0., 3., 0., 1 [...]
+
+8., 0., 7., 6., 12., 0., 15., 0., 10., 59., 1., 10., 61., 0., 6., 0., 0., 4., 79., 10., 8., 77., 11., 61., 12., 2., 0., 1., 0., 1., 17., 6., 44., 11., 2., 35., 36., 16., 3., 0., 1., 5., 5., 27., 7., 34., 10., 15., 4., 4., 6., 0., 4., 5., 20., 4., 14., 5., 6., 3., 2., 42., 9., 3., 1., 0., 13., 0., 6., 5., 11., 3., 4., 4., 1., 0., 0., 3., 0., 17., 11., 3., 4., 0., 1., 0., 0., 0., 0., 0., 10., 3., 4., 3., 4., 1., 0., 0., 0., 0., 0., 0., 0., 2., 5., 0., 1., 0., 0., 0., 2., 0., 0., 0., 1., 0. [...]
+
+8., 0., 2., 2., 9., 0., 19., 2., 10., 36., 1., 6., 43., 2., 6., 2., 0., 1., 76., 7., 7., 45., 21., 66., 16., 2., 0., 4., 3., 1., 13., 3., 48., 11., 4., 46., 24., 10., 15., 0., 2., 6., 2., 16., 5., 25., 6., 8., 12., 4., 1., 0., 14., 1., 18., 5., 20., 3., 10., 6., 3., 41., 9., 3., 2., 0., 12., 4., 5., 3., 12., 1., 10., 2., 2., 1., 0., 6., 4., 10., 16., 5., 1., 0., 1., 0., 0., 0., 0., 0., 7., 2., 3., 2., 2., 2., 2., 0., 1., 0., 0., 0., 3., 4., 2., 0., 2., 0., 0., 0., 1., 0., 0., 0., 2., 0., [...]
+
+10., 2., 1., 2., 9., 0., 14., 2., 6., 45., 2., 7., 63., 1., 5., 2., 0., 2., 74., 18., 7., 78., 14., 56., 8., 5., 0., 0., 2., 3., 16., 7., 47., 11., 2., 36., 35., 17., 4., 0., 2., 8., 2., 21., 10., 28., 6., 10., 6., 2., 2., 0., 8., 7., 25., 5., 21., 2., 7., 4., 6., 40., 7., 5., 0., 0., 14., 5., 12., 4., 13., 1., 5., 0., 1., 0., 0., 4., 2., 14., 10., 2., 5., 0., 4., 0., 0., 0., 0., 0., 8., 4., 5., 0., 2., 0., 0., 0., 2., 0., 2., 0., 1., 5., 2., 0., 3., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0 [...]
+
+9., 1., 4., 4., 11., 0., 14., 1., 8., 44., 1., 6., 71., 1., 9., 1., 0., 2., 76., 10., 5., 92., 18., 59., 9., 5., 0., 0., 5., 1., 13., 6., 50., 12., 1., 42., 33., 16., 5., 0., 0., 5., 0., 28., 10., 30., 8., 14., 8., 7., 2., 0., 7., 3., 19., 4., 19., 2., 12., 6., 4., 35., 5., 5., 1., 0., 19., 6., 7., 2., 15., 2., 6., 0., 1., 2., 0., 7., 1., 21., 9., 5., 1., 1., 1., 0., 0., 0., 0., 0., 7., 4., 0., 3., 6., 0., 0., 0., 3., 0., 2., 0., 0., 0., 1., 0., 2., 0., 0., 0., 0., 0., 0., 0., 1., 0., 2. [...]
+
+15., 0., 3., 4., 21., 5., 29., 1., 15., 153., 2., 29., 230., 5., 19., 3., 4., 4., 86., 1., 8., 289., 52., 351., 42., 18., 1., 0., 3., 6., 39., 36., 229., 41., 7., 145., 12., 29., 10., 0., 4., 16., 7., 69., 21., 86., 15., 27., 38., 12., 2., 3., 32., 5., 36., 12., 49., 6., 26., 3., 8., 3., 3., 0., 0., 0., 20., 5., 13., 5., 36., 7., 13., 10., 2., 5., 0., 1., 4., 4., 13., 2., 5., 2., 8., 0., 1., 5., 153., 9., 1858., 98., 101., 220., 106., 111., 66., 21., 10., 21., 8., 1., 2., 2., 3., 2., 13. [...]
+
+18., 1., 6., 7., 32., 9., 35., 1., 7., 163., 2., 30., 199., 3., 16., 3., 0., 4., 78., 3., 16., 277., 52., 327., 45., 19., 3., 2., 10., 2., 37., 34., 203., 41., 5., 144., 9., 53., 9., 0., 5., 12., 9., 76., 25., 93., 19., 26., 46., 15., 2., 2., 19., 3., 50., 9., 59., 12., 39., 8., 4., 5., 1., 0., 1., 0., 18., 5., 15., 3., 33., 3., 15., 5., 0., 3., 0., 1., 2., 0., 12., 2., 12., 0., 6., 0., 0., 4., 136., 6., 1880., 78., 118., 214., 106., 137., 70., 17., 14., 15., 15., 0., 2., 5., 4., 2., 9., [...]
+
+9., 6., 4., 5., 6., 3., 6., 0., 5., 23., 0., 11., 19., 0., 10., 3., 0., 2., 10., 2., 4., 23., 17., 17., 28., 4., 1., 0., 2., 1., 5., 9., 18., 11., 4., 22., 1., 15., 10., 3., 0., 5., 0., 18., 10., 14., 57., 8., 19., 5., 4., 2., 5., 1., 6., 3., 4., 5., 12., 12., 6., 23., 11., 2., 1., 2., 9., 1., 2., 0., 5., 5., 4., 6., 2., 5., 2., 1., 2., 2., 2., 0., 0., 1., 1., 6., 2., 4., 1., 2., 4., 2., 0., 3., 1., 8., 0., 0., 1., 1., 0., 4., 1., 2., 3., 1., 2., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., 0 [...]
+
+9., 1., 2., 7., 10., 5., 6., 1., 7., 24., 1., 12., 15., 1., 14., 5., 1., 1., 7., 2., 5., 35., 13., 27., 24., 5., 2., 0., 2., 4., 6., 11., 31., 13., 1., 11., 4., 13., 6., 2., 1., 3., 1., 15., 6., 15., 44., 5., 17., 9., 2., 3., 8., 2., 8., 2., 6., 5., 9., 12., 8., 22., 7., 2., 0., 0., 6., 1., 2., 1., 9., 2., 5., 2., 1., 1., 3., 4., 0., 1., 0., 0., 4., 2., 4., 7., 2., 3., 3., 2., 2., 0., 3., 1., 1., 9., 2., 0., 2., 4., 3., 3., 2., 2., 4., 2., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0.,  [...]
+
+17., 1., 1., 1., 5., 2., 2., 3., 3., 31., 0., 17., 15., 0., 15., 1., 2., 1., 25., 2., 2., 12., 7., 20., 29., 5., 1., 4., 3., 0., 10., 11., 24., 18., 5., 19., 4., 21., 7., 1., 1., 4., 2., 12., 9., 23., 65., 9., 22., 11., 5., 0., 2., 2., 7., 2., 10., 9., 7., 13., 8., 32., 7., 3., 0., 1., 7., 0., 1., 2., 7., 4., 6., 3., 0., 2., 2., 2., 1., 1., 1., 0., 1., 1., 0., 6., 3., 3., 1., 1., 7., 2., 2., 0., 1., 10., 1., 0., 2., 0., 3., 2., 1., 1., 4., 1., 3., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0.,  [...]
+
+18., 0., 1., 5., 12., 5., 4., 0., 10., 13., 1., 12., 16., 0., 14., 2., 2., 1., 8., 0., 2., 27., 18., 25., 25., 6., 1., 1., 3., 4., 8., 11., 16., 12., 2., 20., 3., 23., 12., 1., 0., 5., 0., 20., 9., 17., 35., 12., 21., 8., 7., 1., 3., 2., 9., 5., 8., 5., 10., 16., 11., 24., 13., 5., 1., 0., 5., 1., 6., 3., 11., 2., 5., 9., 1., 8., 3., 1., 0., 2., 5., 0., 2., 1., 3., 8., 3., 3., 1., 4., 1., 1., 3., 0., 3., 4., 3., 0., 3., 0., 1., 1., 1., 3., 2., 0., 2., 0., 0., 0., 0., 5., 0., 0., 4., 0.,  [...]
+
+7., 2., 0., 3., 7., 4., 7., 1., 6., 16., 0., 9., 29., 2., 10., 2., 1., 1., 16., 1., 1., 9., 16., 28., 24., 4., 1., 0., 1., 1., 7., 7., 22., 17., 1., 14., 7., 18., 10., 2., 1., 6., 2., 19., 8., 12., 53., 13., 28., 9., 5., 1., 4., 2., 4., 4., 4., 6., 13., 16., 4., 26., 12., 3., 3., 1., 10., 1., 5., 1., 6., 4., 5., 4., 5., 0., 1., 3., 3., 1., 1., 0., 2., 1., 1., 12., 5., 6., 0., 1., 3., 1., 1., 2., 2., 9., 0., 0., 3., 3., 3., 4., 1., 2., 0., 2., 0., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., 0 [...]
+
+5., 1., 4., 0., 3., 5., 6., 0., 5., 5., 1., 19., 26., 3., 13., 2., 0., 3., 20., 1., 0., 25., 11., 34., 30., 5., 1., 0., 1., 2., 7., 6., 21., 16., 3., 11., 4., 13., 10., 4., 1., 2., 2., 14., 10., 9., 50., 14., 25., 6., 1., 0., 5., 3., 4., 3., 9., 10., 12., 14., 5., 26., 9., 1., 0., 0., 6., 5., 4., 0., 3., 2., 7., 5., 1., 0., 4., 2., 0., 2., 4., 0., 1., 2., 1., 8., 4., 3., 3., 0., 5., 1., 4., 1., 2., 6., 6., 0., 3., 3., 3., 1., 1., 1., 7., 2., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. [...]
+
+9., 1., 1., 2., 12., 2., 7., 2., 6., 3., 3., 14., 25., 2., 9., 3., 1., 1., 19., 0., 5., 28., 10., 36., 23., 3., 1., 0., 2., 2., 10., 7., 20., 20., 1., 21., 3., 15., 8., 3., 0., 6., 4., 7., 11., 22., 51., 9., 18., 13., 2., 2., 7., 2., 10., 5., 10., 10., 9., 17., 2., 24., 8., 1., 1., 2., 8., 1., 5., 1., 7., 2., 3., 3., 4., 6., 3., 2., 3., 5., 1., 0., 0., 1., 2., 9., 0., 4., 3., 2., 2., 3., 3., 1., 1., 7., 0., 0., 5., 3., 3., 4., 1., 2., 2., 1., 3., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0 [...]
+
+12., 1., 3., 6., 6., 5., 9., 0., 3., 31., 0., 16., 22., 2., 22., 4., 1., 2., 16., 4., 4., 30., 12., 32., 27., 8., 3., 0., 3., 2., 9., 9., 25., 13., 2., 16., 4., 14., 10., 3., 0., 6., 5., 15., 7., 10., 42., 10., 24., 11., 6., 2., 3., 0., 8., 3., 13., 11., 12., 11., 5., 22., 7., 2., 2., 0., 9., 1., 3., 5., 6., 5., 3., 4., 3., 5., 3., 1., 0., 3., 1., 0., 1., 1., 2., 7., 1., 4., 0., 1., 1., 0., 4., 2., 2., 7., 3., 0., 5., 4., 1., 4., 1., 1., 2., 0., 2., 0., 0., 0., 0., 3., 0., 0., 6., 0., 0. [...]
+
+3., 1., 3., 4., 11., 2., 4., 2., 7., 29., 0., 15., 22., 1., 11., 2., 2., 2., 18., 3., 7., 28., 6., 45., 32., 6., 1., 3., 5., 1., 6., 3., 26., 17., 2., 16., 4., 14., 10., 1., 2., 5., 2., 13., 10., 11., 40., 8., 13., 10., 6., 1., 8., 1., 6., 0., 8., 6., 8., 7., 3., 17., 9., 3., 3., 2., 10., 1., 2., 3., 5., 1., 8., 5., 4., 7., 2., 2., 2., 3., 2., 0., 2., 2., 3., 11., 1., 3., 2., 2., 2., 2., 2., 0., 3., 5., 2., 0., 2., 3., 2., 2., 2., 3., 2., 0., 3., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0 [...]
+
+5., 0., 3., 5., 9., 5., 4., 0., 7., 28., 3., 14., 27., 1., 11., 2., 2., 6., 25., 4., 3., 13., 9., 43., 18., 4., 0., 1., 4., 0., 11., 5., 25., 16., 0., 13., 4., 11., 13., 0., 1., 8., 3., 11., 12., 18., 49., 14., 14., 7., 7., 0., 4., 0., 11., 4., 6., 10., 3., 18., 6., 23., 9., 0., 1., 1., 13., 0., 3., 1., 5., 4., 7., 3., 4., 4., 3., 3., 0., 2., 1., 0., 2., 1., 1., 4., 0., 8., 0., 2., 2., 0., 3., 1., 3., 7., 3., 0., 3., 2., 1., 3., 2., 1., 1., 0., 1., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., [...]
+
+13., 1., 1., 3., 8., 2., 6., 0., 5., 18., 0., 11., 21., 0., 11., 1., 0., 2., 15., 4., 1., 31., 6., 16., 15., 11., 0., 0., 1., 4., 8., 6., 42., 18., 3., 10., 0., 12., 11., 1., 0., 4., 1., 10., 11., 19., 40., 8., 14., 9., 3., 1., 4., 5., 8., 3., 13., 5., 8., 19., 5., 17., 12., 3., 0., 1., 4., 0., 1., 5., 3., 1., 5., 3., 1., 6., 1., 1., 0., 0., 1., 0., 3., 3., 3., 8., 4., 4., 1., 6., 2., 2., 1., 2., 4., 6., 2., 0., 3., 4., 3., 3., 3., 2., 4., 0., 3., 0., 0., 0., 0., 3., 0., 0., 5., 0., 0.,  [...]
+
+4., 1., 1., 3., 4., 3., 2., 3., 5., 29., 2., 11., 21., 0., 18., 2., 1., 2., 24., 1., 5., 14., 13., 29., 36., 1., 0., 3., 4., 2., 7., 4., 25., 13., 1., 16., 3., 6., 6., 1., 1., 2., 5., 23., 9., 23., 43., 15., 19., 8., 2., 0., 3., 1., 6., 4., 9., 7., 6., 22., 3., 28., 8., 4., 0., 1., 11., 2., 3., 1., 5., 0., 2., 6., 2., 3., 0., 0., 2., 2., 4., 0., 5., 1., 3., 12., 1., 2., 3., 1., 5., 2., 1., 0., 3., 7., 1., 0., 4., 2., 2., 1., 1., 1., 1., 0., 2., 0., 0., 0., 0., 3., 0., 0., 0., 0., 0., 0., [...]
+
+7., 4., 2., 3., 14., 3., 5., 1., 3., 28., 1., 12., 25., 4., 18., 4., 1., 2., 3., 0., 4., 25., 15., 15., 33., 6., 0., 1., 3., 1., 11., 5., 27., 22., 4., 18., 5., 9., 8., 2., 3., 7., 3., 17., 13., 19., 48., 15., 10., 13., 7., 2., 3., 0., 2., 0., 9., 8., 5., 15., 6., 31., 8., 2., 0., 0., 9., 1., 5., 0., 3., 3., 4., 2., 1., 4., 3., 4., 0., 1., 2., 0., 0., 4., 3., 4., 1., 1., 2., 2., 3., 1., 4., 4., 0., 8., 2., 0., 0., 0., 2., 2., 2., 1., 1., 1., 3., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0. [...]
+
+5., 0., 0., 5., 12., 5., 9., 2., 7., 0., 0., 14., 22., 0., 14., 2., 0., 1., 15., 2., 6., 10., 9., 26., 32., 1., 3., 2., 3., 1., 12., 16., 34., 16., 1., 8., 7., 12., 10., 2., 1., 2., 3., 8., 9., 12., 43., 14., 24., 10., 6., 2., 4., 0., 6., 4., 11., 6., 10., 21., 7., 25., 6., 3., 2., 1., 6., 2., 0., 2., 6., 3., 2., 4., 0., 5., 5., 5., 2., 2., 4., 0., 0., 2., 2., 6., 0., 5., 1., 2., 2., 0., 2., 2., 1., 7., 4., 0., 0., 0., 1., 1., 2., 0., 1., 2., 2., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0 [...]
+
+8., 1., 0., 6., 10., 2., 16., 0., 6., 24., 1., 22., 19., 1., 15., 2., 1., 4., 9., 1., 5., 23., 15., 35., 26., 5., 1., 0., 5., 1., 6., 11., 26., 14., 3., 29., 3., 11., 12., 2., 0., 7., 0., 14., 13., 21., 50., 10., 18., 5., 3., 0., 6., 0., 7., 2., 15., 3., 9., 15., 6., 31., 8., 7., 1., 1., 8., 2., 4., 4., 4., 2., 6., 6., 1., 4., 2., 6., 1., 3., 3., 0., 2., 5., 3., 11., 2., 2., 6., 1., 3., 0., 1., 0., 1., 5., 2., 0., 3., 0., 3., 5., 3., 0., 2., 1., 1., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0. [...]
+
+5., 1., 3., 4., 8., 5., 4., 0., 5., 16., 0., 12., 10., 1., 19., 3., 1., 3., 21., 0., 5., 27., 15., 19., 28., 3., 1., 1., 2., 5., 9., 11., 20., 15., 6., 18., 3., 21., 7., 1., 3., 4., 1., 15., 11., 19., 44., 11., 26., 8., 1., 1., 3., 1., 4., 7., 7., 5., 9., 12., 5., 26., 6., 2., 1., 1., 3., 0., 3., 4., 6., 2., 3., 1., 2., 4., 1., 0., 1., 3., 2., 0., 4., 5., 3., 6., 2., 2., 3., 0., 4., 0., 2., 0., 0., 7., 1., 0., 4., 1., 0., 1., 2., 6., 2., 1., 2., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0., 0. [...]
+
+4., 1., 2., 3., 13., 5., 5., 1., 8., 32., 1., 14., 27., 1., 16., 3., 1., 1., 15., 1., 1., 33., 18., 46., 28., 4., 0., 0., 1., 0., 4., 8., 22., 24., 2., 15., 6., 14., 6., 0., 3., 6., 3., 11., 12., 12., 45., 11., 18., 7., 3., 1., 2., 3., 9., 2., 6., 7., 5., 13., 6., 22., 10., 1., 1., 1., 4., 0., 2., 0., 5., 0., 3., 4., 2., 5., 5., 0., 3., 1., 3., 0., 2., 1., 2., 8., 1., 5., 6., 2., 3., 2., 1., 2., 5., 8., 3., 0., 0., 1., 3., 4., 3., 0., 2., 1., 1., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0 [...]
+
+6., 0., 2., 6., 7., 4., 8., 0., 8., 29., 1., 15., 16., 2., 17., 1., 3., 1., 15., 1., 6., 25., 9., 12., 19., 8., 0., 0., 4., 2., 5., 9., 18., 16., 3., 15., 6., 12., 8., 4., 0., 0., 2., 4., 10., 10., 54., 13., 14., 8., 5., 3., 9., 3., 5., 1., 10., 6., 11., 25., 8., 34., 10., 2., 1., 2., 7., 1., 0., 2., 6., 2., 2., 5., 2., 6., 3., 1., 2., 2., 2., 0., 4., 2., 1., 9., 4., 2., 3., 3., 6., 2., 2., 2., 2., 8., 2., 0., 4., 2., 0., 3., 0., 2., 1., 0., 2., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0. [...]
+
+9., 1., 2., 3., 8., 4., 2., 0., 4., 21., 0., 17., 14., 2., 17., 1., 0., 3., 18., 1., 3., 18., 17., 26., 35., 6., 2., 0., 2., 2., 5., 4., 28., 14., 3., 14., 3., 15., 7., 2., 0., 2., 1., 14., 13., 18., 33., 15., 19., 12., 5., 2., 7., 3., 7., 0., 7., 5., 7., 18., 7., 14., 7., 4., 2., 2., 4., 0., 2., 3., 6., 4., 4., 1., 2., 2., 1., 1., 1., 2., 1., 0., 3., 0., 3., 9., 1., 3., 2., 3., 4., 1., 2., 0., 1., 7., 1., 0., 2., 3., 1., 1., 3., 3., 3., 1., 3., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0. [...]
+
+13., 3., 2., 1., 6., 4., 4., 1., 12., 21., 0., 13., 18., 1., 18., 1., 1., 5., 30., 4., 2., 24., 8., 18., 16., 9., 0., 0., 3., 1., 4., 7., 33., 15., 2., 9., 4., 15., 12., 0., 3., 4., 1., 18., 7., 19., 43., 17., 22., 6., 3., 0., 3., 1., 8., 4., 8., 9., 6., 11., 8., 15., 12., 1., 1., 2., 8., 0., 1., 3., 5., 3., 3., 6., 2., 2., 7., 3., 1., 1., 3., 0., 4., 2., 3., 2., 4., 6., 4., 1., 7., 3., 5., 1., 2., 8., 3., 0., 5., 1., 0., 4., 5., 3., 1., 1., 3., 0., 0., 0., 0., 5., 0., 0., 4., 0., 0., 0. [...]
+
+3., 2., 3., 4., 8., 5., 7., 1., 8., 16., 0., 9., 23., 0., 16., 2., 1., 0., 12., 5., 3., 15., 17., 18., 26., 7., 0., 3., 5., 2., 5., 8., 16., 22., 3., 15., 7., 7., 12., 2., 0., 1., 3., 13., 17., 18., 47., 11., 21., 10., 6., 0., 6., 3., 7., 2., 14., 8., 7., 11., 7., 20., 4., 3., 0., 0., 7., 2., 1., 3., 2., 4., 5., 4., 4., 4., 1., 2., 1., 1., 4., 0., 2., 0., 0., 2., 2., 3., 2., 2., 5., 0., 2., 2., 1., 8., 0., 0., 3., 1., 0., 4., 2., 4., 2., 4., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0. [...]
+
+13., 1., 4., 4., 22., 0., 16., 4., 10., 48., 1., 6., 60., 1., 8., 2., 0., 1., 59., 13., 8., 65., 18., 83., 13., 4., 0., 1., 1., 2., 15., 11., 60., 13., 1., 26., 36., 11., 2., 0., 2., 6., 1., 20., 8., 22., 4., 12., 7., 4., 1., 0., 7., 3., 13., 4., 14., 4., 9., 5., 0., 35., 3., 8., 0., 0., 16., 5., 7., 0., 14., 4., 7., 4., 1., 0., 0., 3., 2., 16., 9., 6., 2., 1., 4., 0., 0., 0., 0., 0., 8., 1., 2., 3., 4., 4., 0., 0., 1., 0., 2., 0., 2., 4., 3., 0., 3., 0., 1., 0., 1., 0., 0., 0., 1., 0.,  [...]
+
+5., 1., 3., 5., 22., 0., 11., 1., 5., 49., 1., 5., 58., 1., 5., 1., 0., 3., 69., 8., 9., 68., 9., 85., 8., 3., 0., 0., 2., 3., 11., 11., 59., 10., 4., 36., 44., 13., 4., 0., 0., 6., 2., 27., 5., 27., 4., 13., 13., 5., 1., 0., 9., 5., 16., 3., 15., 0., 11., 7., 5., 42., 6., 6., 0., 0., 15., 1., 7., 3., 12., 4., 6., 1., 2., 0., 0., 7., 2., 15., 10., 1., 2., 1., 2., 0., 0., 0., 0., 0., 9., 2., 0., 4., 3., 2., 0., 0., 0., 0., 1., 0., 0., 5., 1., 0., 0., 0., 0., 0., 1., 0., 0., 0., 1., 0., 3. [...]
+
+12., 1., 1., 3., 10., 0., 26., 2., 4., 45., 1., 9., 80., 0., 5., 5., 0., 3., 68., 19., 9., 57., 18., 57., 9., 5., 0., 0., 0., 6., 13., 7., 53., 8., 3., 31., 43., 13., 4., 0., 1., 5., 6., 29., 7., 25., 6., 15., 4., 2., 3., 0., 16., 6., 22., 2., 15., 4., 5., 2., 3., 38., 8., 11., 2., 0., 18., 3., 8., 1., 9., 4., 5., 1., 0., 0., 0., 3., 3., 8., 7., 6., 4., 0., 2., 0., 0., 0., 0., 0., 10., 1., 4., 2., 2., 2., 1., 0., 1., 0., 0., 0., 1., 4., 3., 0., 1., 0., 1., 0., 0., 0., 0., 0., 1., 0., 2., [...]
+
+14., 2., 7., 6., 14., 0., 11., 0., 5., 39., 0., 7., 66., 1., 6., 1., 0., 4., 71., 5., 9., 80., 8., 81., 19., 2., 0., 2., 1., 0., 19., 7., 35., 22., 3., 41., 36., 15., 5., 0., 1., 9., 7., 23., 5., 23., 4., 14., 5., 2., 1., 0., 9., 5., 10., 7., 16., 4., 10., 2., 1., 40., 9., 7., 0., 0., 10., 2., 8., 1., 13., 1., 3., 0., 0., 3., 0., 6., 4., 18., 9., 2., 1., 1., 5., 0., 0., 0., 0., 0., 5., 0., 3., 0., 3., 3., 1., 0., 0., 0., 0., 0., 1., 6., 1., 0., 1., 0., 1., 0., 3., 0., 0., 0., 1., 0., 2., [...]
+
+8., 1., 2., 5., 12., 0., 12., 1., 4., 53., 1., 4., 42., 3., 7., 1., 0., 2., 57., 10., 7., 79., 12., 66., 12., 5., 0., 0., 3., 4., 11., 7., 48., 11., 5., 52., 25., 20., 3., 0., 1., 4., 3., 10., 10., 32., 5., 15., 6., 2., 1., 0., 9., 4., 20., 3., 16., 2., 4., 1., 0., 55., 10., 11., 1., 0., 6., 1., 12., 2., 16., 1., 5., 3., 1., 2., 0., 8., 0., 25., 7., 1., 5., 1., 4., 0., 0., 0., 0., 0., 7., 4., 5., 2., 4., 0., 1., 0., 1., 0., 0., 0., 3., 3., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 1., 0.,  [...]
+
+12., 1., 2., 4., 18., 0., 14., 1., 11., 55., 1., 13., 42., 1., 4., 1., 0., 2., 64., 8., 5., 81., 11., 76., 12., 3., 0., 0., 1., 1., 11., 10., 52., 9., 0., 39., 31., 15., 3., 0., 0., 8., 2., 11., 4., 20., 11., 12., 4., 2., 2., 0., 11., 6., 18., 6., 10., 4., 8., 1., 4., 34., 11., 8., 1., 0., 10., 1., 5., 2., 10., 4., 2., 0., 0., 1., 0., 5., 2., 15., 8., 5., 7., 0., 4., 0., 0., 0., 0., 0., 5., 1., 1., 1., 3., 2., 0., 0., 1., 0., 1., 0., 0., 1., 3., 0., 1., 0., 2., 0., 0., 0., 0., 0., 2., 0. [...]
+
+4., 1., 2., 2., 10., 0., 22., 0., 8., 56., 2., 6., 55., 0., 7., 3., 0., 3., 72., 7., 4., 79., 5., 72., 10., 5., 0., 0., 4., 1., 10., 10., 58., 9., 4., 46., 29., 13., 4., 0., 0., 4., 5., 19., 6., 25., 3., 14., 11., 5., 0., 0., 9., 3., 18., 7., 13., 2., 16., 1., 7., 39., 12., 4., 3., 0., 10., 3., 7., 1., 12., 2., 2., 2., 2., 0., 0., 0., 3., 13., 10., 3., 1., 3., 2., 0., 0., 0., 0., 0., 6., 1., 4., 2., 4., 1., 0., 0., 2., 0., 1., 0., 1., 3., 2., 0., 1., 0., 2., 0., 1., 0., 0., 0., 2., 0., 1 [...]
+
+12., 1., 1., 2., 7., 0., 18., 2., 13., 38., 1., 8., 50., 2., 5., 4., 0., 6., 69., 5., 6., 73., 19., 83., 17., 4., 0., 1., 2., 3., 19., 11., 47., 12., 3., 34., 26., 14., 3., 0., 0., 10., 5., 25., 5., 26., 4., 10., 2., 2., 4., 0., 7., 1., 23., 7., 15., 2., 5., 2., 4., 35., 8., 9., 1., 0., 15., 4., 9., 1., 14., 1., 5., 0., 1., 3., 0., 7., 3., 14., 6., 5., 1., 2., 4., 0., 0., 0., 0., 0., 11., 1., 2., 2., 2., 0., 2., 0., 0., 0., 1., 0., 2., 5., 1., 0., 3., 0., 1., 0., 2., 0., 0., 0., 0., 0.,  [...]
+
+11., 2., 2., 4., 13., 0., 21., 1., 7., 56., 0., 7., 56., 1., 5., 4., 0., 2., 66., 15., 3., 91., 15., 79., 20., 2., 0., 1., 4., 1., 13., 5., 58., 16., 4., 56., 40., 11., 6., 0., 3., 7., 5., 15., 2., 30., 5., 9., 3., 2., 1., 0., 10., 5., 11., 4., 15., 0., 15., 2., 5., 37., 16., 5., 1., 0., 14., 5., 3., 0., 13., 3., 1., 3., 1., 0., 0., 7., 1., 16., 9., 4., 4., 0., 0., 0., 0., 0., 0., 0., 9., 0., 3., 0., 1., 2., 0., 0., 0., 0., 1., 0., 0., 4., 0., 0., 0., 0., 1., 0., 3., 0., 0., 0., 0., 0.,  [...]
+
+15., 4., 2., 5., 19., 5., 39., 0., 21., 158., 3., 19., 180., 3., 13., 9., 2., 7., 90., 4., 13., 262., 42., 307., 38., 25., 1., 0., 6., 8., 42., 30., 221., 37., 9., 151., 12., 48., 5., 0., 6., 22., 15., 74., 18., 70., 18., 33., 52., 9., 2., 2., 23., 14., 34., 12., 58., 12., 26., 4., 9., 9., 0., 0., 1., 0., 36., 6., 16., 4., 25., 7., 6., 4., 2., 6., 2., 2., 5., 3., 7., 4., 6., 1., 6., 0., 0., 2., 125., 14., 1946., 106., 111., 210., 92., 120., 78., 9., 12., 18., 8., 1., 0., 8., 4., 1., 10., [...]
+
+13., 3., 4., 6., 25., 5., 35., 2., 14., 172., 2., 31., 231., 7., 18., 6., 0., 7., 74., 0., 17., 254., 36., 310., 38., 18., 2., 2., 9., 5., 51., 33., 238., 35., 6., 161., 6., 43., 2., 0., 2., 9., 8., 83., 17., 102., 12., 35., 29., 13., 2., 1., 32., 5., 49., 11., 48., 11., 32., 6., 11., 5., 3., 0., 1., 0., 28., 4., 12., 1., 28., 4., 10., 1., 2., 2., 1., 0., 4., 5., 5., 8., 5., 3., 6., 2., 1., 5., 133., 9., 1854., 92., 101., 211., 78., 126., 71., 17., 17., 17., 20., 1., 1., 1., 10., 2., 6., [...]
+
+10., 1., 0., 1., 10., 4., 10., 2., 0., 25., 0., 16., 18., 1., 14., 2., 0., 2., 11., 2., 2., 23., 12., 30., 28., 9., 1., 0., 2., 1., 5., 6., 23., 15., 3., 19., 5., 14., 10., 0., 0., 3., 1., 13., 8., 14., 54., 15., 18., 10., 0., 1., 4., 2., 11., 3., 11., 4., 7., 16., 6., 21., 5., 3., 2., 1., 8., 1., 1., 1., 6., 5., 3., 5., 3., 2., 2., 1., 1., 4., 2., 0., 1., 1., 4., 7., 1., 3., 0., 2., 3., 1., 2., 1., 1., 2., 2., 0., 2., 3., 1., 4., 4., 0., 2., 1., 2., 0., 0., 0., 0., 0., 0., 0., 6., 0., 0 [...]
+
+12., 2., 5., 5., 8., 3., 5., 1., 5., 27., 2., 14., 16., 1., 24., 2., 1., 3., 20., 3., 6., 22., 9., 31., 16., 4., 1., 0., 7., 2., 9., 10., 43., 16., 5., 17., 5., 14., 11., 1., 1., 2., 0., 17., 11., 12., 37., 13., 19., 9., 2., 1., 1., 4., 8., 5., 10., 7., 7., 11., 5., 14., 10., 4., 2., 0., 8., 1., 2., 4., 6., 5., 3., 2., 1., 5., 1., 2., 3., 1., 5., 0., 4., 3., 0., 2., 1., 2., 3., 1., 4., 1., 1., 1., 0., 6., 3., 0., 2., 0., 4., 0., 1., 4., 2., 0., 0., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., [...]
+
+8., 2., 0., 3., 3., 1., 8., 0., 9., 20., 2., 15., 21., 1., 19., 3., 0., 0., 16., 1., 10., 31., 15., 21., 27., 8., 0., 0., 3., 2., 11., 6., 22., 19., 3., 17., 2., 13., 7., 1., 2., 1., 2., 16., 8., 21., 50., 13., 16., 11., 5., 1., 5., 3., 2., 4., 9., 7., 6., 12., 7., 19., 16., 4., 2., 1., 6., 3., 5., 6., 5., 2., 2., 3., 2., 9., 5., 3., 0., 4., 6., 0., 2., 1., 2., 4., 2., 8., 2., 2., 3., 0., 5., 2., 2., 2., 2., 0., 1., 2., 1., 2., 4., 1., 2., 2., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.,  [...]
+
+5., 2., 2., 8., 7., 4., 7., 1., 5., 29., 1., 18., 35., 1., 13., 2., 2., 3., 18., 4., 4., 24., 12., 37., 22., 7., 4., 2., 3., 3., 9., 8., 35., 15., 2., 12., 6., 20., 6., 1., 2., 3., 2., 12., 17., 16., 50., 18., 21., 9., 3., 1., 7., 1., 14., 3., 10., 2., 13., 13., 8., 28., 9., 7., 0., 1., 7., 3., 5., 3., 2., 2., 2., 3., 1., 7., 4., 4., 0., 2., 1., 0., 0., 1., 3., 4., 2., 1., 2., 0., 10., 2., 0., 0., 2., 9., 2., 0., 1., 3., 1., 2., 2., 0., 2., 0., 5., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., [...]
+
+8., 1., 4., 2., 5., 1., 7., 0., 8., 28., 3., 7., 22., 1., 15., 2., 0., 3., 21., 1., 4., 23., 16., 28., 28., 3., 2., 1., 3., 4., 7., 7., 33., 20., 4., 19., 5., 12., 9., 1., 0., 1., 0., 12., 11., 21., 56., 11., 25., 9., 0., 1., 4., 1., 11., 4., 13., 5., 9., 14., 7., 20., 7., 1., 1., 0., 4., 1., 3., 0., 1., 2., 1., 5., 2., 4., 1., 4., 1., 1., 3., 0., 3., 1., 2., 7., 2., 0., 2., 5., 1., 1., 5., 2., 2., 12., 2., 0., 2., 3., 1., 3., 2., 3., 2., 1., 2., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0 [...]
+
+9., 1., 1., 2., 11., 3., 6., 0., 5., 27., 0., 13., 17., 0., 17., 0., 2., 3., 20., 2., 11., 15., 9., 28., 22., 6., 3., 0., 0., 5., 9., 10., 19., 18., 2., 10., 4., 13., 10., 3., 1., 5., 2., 15., 10., 17., 36., 8., 14., 8., 5., 0., 5., 6., 8., 4., 10., 2., 6., 18., 2., 18., 10., 0., 2., 0., 10., 1., 1., 5., 4., 6., 7., 2., 1., 3., 2., 2., 3., 5., 2., 0., 1., 2., 3., 6., 2., 2., 3., 2., 3., 2., 1., 0., 3., 4., 6., 0., 1., 2., 1., 4., 0., 1., 3., 0., 4., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0. [...]
+
+7., 0., 3., 2., 6., 4., 8., 1., 12., 18., 1., 14., 18., 0., 26., 4., 2., 0., 17., 0., 4., 30., 9., 21., 24., 3., 1., 1., 5., 1., 13., 8., 24., 16., 2., 20., 4., 8., 8., 2., 2., 3., 4., 15., 11., 23., 46., 5., 16., 7., 4., 1., 5., 3., 3., 1., 9., 3., 7., 14., 4., 22., 8., 3., 0., 2., 7., 0., 4., 3., 8., 3., 6., 6., 3., 8., 2., 3., 1., 2., 2., 0., 3., 1., 4., 4., 1., 4., 0., 3., 4., 1., 3., 0., 2., 9., 4., 0., 4., 3., 3., 2., 1., 1., 3., 2., 2., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0.,  [...]
+
+8., 5., 2., 2., 9., 2., 5., 0., 5., 18., 0., 10., 30., 1., 13., 9., 2., 1., 18., 2., 2., 2., 20., 16., 22., 4., 1., 2., 2., 2., 7., 12., 23., 13., 1., 10., 5., 16., 13., 3., 1., 4., 5., 12., 9., 16., 51., 10., 20., 9., 6., 1., 7., 2., 2., 4., 12., 5., 5., 20., 8., 15., 12., 3., 1., 2., 7., 0., 4., 3., 7., 3., 4., 6., 2., 4., 1., 3., 0., 2., 2., 0., 1., 2., 0., 6., 0., 6., 1., 2., 2., 3., 4., 2., 0., 9., 3., 0., 3., 2., 2., 2., 3., 0., 1., 1., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0 [...]
+
+4., 0., 2., 7., 11., 1., 11., 3., 6., 8., 0., 7., 21., 0., 13., 2., 1., 1., 22., 3., 2., 34., 5., 15., 20., 6., 0., 1., 0., 5., 3., 8., 27., 12., 5., 14., 4., 10., 11., 1., 2., 5., 5., 17., 11., 15., 53., 17., 19., 5., 2., 1., 2., 2., 8., 2., 13., 5., 9., 16., 3., 17., 7., 4., 0., 0., 4., 1., 1., 1., 2., 3., 2., 2., 3., 4., 4., 3., 1., 2., 2., 0., 1., 1., 1., 6., 1., 1., 3., 2., 1., 1., 1., 2., 4., 5., 0., 0., 1., 1., 4., 2., 2., 2., 2., 0., 0., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+18., 0., 3., 6., 14., 5., 3., 0., 7., 22., 0., 12., 18., 1., 15., 1., 0., 1., 20., 2., 3., 30., 8., 35., 21., 7., 1., 1., 2., 1., 9., 6., 16., 13., 4., 10., 3., 16., 8., 0., 0., 1., 3., 17., 16., 19., 59., 6., 18., 11., 3., 0., 2., 3., 7., 4., 5., 5., 4., 15., 4., 29., 8., 2., 1., 0., 16., 1., 6., 2., 8., 3., 2., 4., 5., 1., 3., 1., 1., 2., 4., 0., 0., 1., 0., 3., 4., 4., 1., 1., 6., 2., 3., 1., 4., 2., 3., 0., 0., 3., 4., 0., 2., 2., 2., 1., 1., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0 [...]
+
+8., 0., 2., 3., 10., 5., 4., 1., 7., 31., 3., 22., 24., 2., 18., 3., 2., 2., 16., 3., 2., 21., 7., 17., 27., 9., 2., 1., 1., 5., 6., 5., 23., 15., 1., 11., 5., 11., 9., 1., 3., 3., 2., 11., 16., 17., 41., 9., 21., 4., 4., 2., 1., 1., 7., 2., 9., 7., 8., 20., 7., 24., 7., 1., 0., 1., 7., 1., 6., 3., 3., 2., 5., 4., 3., 3., 4., 2., 0., 4., 2., 0., 1., 0., 2., 5., 4., 4., 1., 4., 8., 5., 3., 0., 1., 14., 0., 0., 2., 3., 3., 1., 2., 2., 3., 1., 3., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0., [...]
+
+15., 2., 0., 6., 14., 7., 8., 0., 6., 24., 0., 14., 16., 2., 12., 5., 0., 3., 16., 0., 2., 9., 0., 25., 23., 10., 1., 0., 2., 2., 11., 6., 29., 17., 3., 16., 7., 11., 9., 1., 0., 3., 4., 18., 10., 14., 43., 11., 22., 6., 2., 4., 6., 1., 7., 4., 13., 5., 7., 20., 2., 26., 8., 1., 1., 2., 9., 0., 3., 7., 8., 3., 5., 2., 2., 4., 5., 1., 1., 5., 2., 0., 2., 2., 2., 4., 2., 9., 1., 2., 6., 2., 2., 0., 6., 10., 1., 0., 5., 2., 3., 1., 2., 3., 1., 0., 4., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., [...]
+
+6., 1., 4., 2., 10., 3., 4., 0., 4., 25., 2., 11., 13., 2., 11., 1., 0., 2., 31., 1., 4., 25., 15., 24., 38., 2., 1., 4., 5., 1., 8., 9., 32., 18., 5., 17., 4., 13., 5., 1., 0., 4., 0., 10., 12., 10., 45., 18., 27., 3., 7., 0., 9., 1., 9., 4., 9., 4., 9., 19., 3., 24., 9., 3., 0., 0., 6., 0., 1., 4., 5., 4., 3., 4., 4., 4., 4., 2., 1., 6., 4., 0., 1., 3., 4., 7., 1., 6., 3., 2., 4., 0., 4., 1., 5., 8., 0., 0., 4., 1., 2., 1., 1., 5., 2., 0., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+8., 1., 0., 5., 6., 3., 6., 0., 1., 21., 3., 9., 30., 2., 19., 0., 0., 5., 25., 2., 1., 30., 7., 28., 33., 8., 0., 1., 6., 3., 8., 5., 13., 16., 2., 20., 1., 15., 11., 3., 0., 10., 3., 12., 14., 17., 49., 14., 18., 9., 7., 0., 6., 5., 8., 5., 12., 5., 7., 13., 3., 20., 12., 1., 1., 3., 6., 0., 2., 2., 5., 4., 3., 6., 4., 6., 4., 1., 0., 1., 3., 0., 1., 4., 4., 7., 6., 2., 3., 1., 4., 1., 3., 1., 2., 5., 2., 0., 2., 2., 1., 2., 5., 4., 1., 0., 3., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0 [...]
+
+9., 1., 0., 2., 4., 1., 6., 1., 4., 7., 1., 9., 19., 0., 23., 2., 3., 0., 14., 2., 4., 25., 8., 27., 39., 7., 1., 1., 3., 1., 7., 2., 31., 20., 1., 10., 4., 13., 13., 2., 1., 5., 1., 3., 13., 19., 48., 11., 30., 10., 7., 0., 4., 6., 6., 5., 11., 8., 9., 12., 13., 20., 10., 2., 1., 0., 12., 1., 3., 3., 4., 2., 3., 5., 2., 4., 3., 1., 2., 2., 3., 0., 0., 1., 2., 7., 0., 9., 0., 4., 5., 2., 1., 1., 1., 4., 3., 0., 1., 0., 6., 0., 1., 2., 1., 3., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0 [...]
+
+5., 2., 1., 5., 8., 6., 6., 1., 6., 23., 0., 14., 23., 0., 13., 1., 1., 1., 27., 3., 5., 22., 12., 31., 24., 6., 0., 3., 2., 5., 6., 11., 26., 22., 1., 16., 3., 18., 8., 1., 0., 6., 2., 3., 11., 15., 59., 14., 17., 13., 3., 1., 8., 3., 6., 2., 6., 4., 10., 9., 4., 23., 4., 4., 0., 2., 11., 2., 4., 2., 10., 5., 6., 1., 3., 4., 2., 3., 0., 2., 4., 0., 2., 1., 1., 7., 4., 4., 3., 1., 6., 1., 2., 1., 1., 9., 2., 0., 2., 0., 3., 1., 1., 0., 1., 4., 3., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.,  [...]
+
+11., 2., 3., 7., 9., 3., 8., 1., 6., 20., 0., 12., 20., 0., 8., 3., 2., 2., 5., 2., 4., 34., 5., 22., 32., 4., 1., 1., 4., 1., 9., 8., 27., 16., 1., 15., 2., 16., 2., 2., 0., 4., 1., 10., 13., 21., 43., 14., 20., 10., 5., 0., 5., 2., 8., 6., 6., 5., 8., 8., 7., 26., 12., 4., 2., 0., 4., 2., 3., 4., 5., 7., 6., 1., 2., 2., 3., 3., 0., 2., 3., 0., 0., 4., 3., 8., 2., 6., 1., 1., 6., 1., 2., 1., 1., 10., 2., 0., 2., 2., 0., 2., 2., 4., 4., 0., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0., [...]
+
+19., 1., 2., 5., 6., 4., 9., 0., 1., 26., 1., 10., 13., 1., 12., 7., 2., 3., 19., 1., 3., 40., 13., 21., 29., 4., 3., 1., 2., 1., 4., 4., 20., 13., 5., 19., 3., 13., 7., 2., 1., 5., 2., 19., 11., 7., 40., 13., 22., 8., 2., 0., 3., 2., 7., 7., 9., 6., 7., 21., 8., 20., 13., 2., 2., 3., 8., 1., 3., 0., 4., 1., 3., 4., 2., 3., 4., 1., 2., 2., 2., 0., 3., 2., 3., 5., 2., 3., 0., 0., 8., 1., 3., 2., 2., 8., 3., 0., 2., 2., 5., 1., 1., 3., 1., 0., 2., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0. [...]
+
+7., 0., 1., 2., 10., 3., 4., 2., 9., 18., 0., 16., 18., 2., 14., 5., 0., 1., 32., 2., 0., 13., 10., 32., 20., 11., 0., 1., 3., 2., 4., 12., 31., 11., 4., 21., 2., 11., 9., 2., 1., 6., 5., 8., 11., 8., 40., 8., 14., 11., 4., 1., 3., 4., 7., 4., 6., 5., 4., 17., 6., 21., 8., 5., 1., 0., 7., 1., 2., 2., 2., 3., 5., 3., 1., 9., 5., 0., 0., 1., 7., 0., 3., 3., 1., 6., 1., 3., 2., 1., 6., 2., 2., 0., 0., 11., 2., 0., 1., 5., 0., 4., 1., 1., 2., 0., 3., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0., 0 [...]
+
+5., 1., 2., 2., 2., 2., 4., 2., 6., 26., 0., 11., 27., 0., 7., 1., 1., 2., 23., 2., 6., 25., 8., 40., 32., 8., 1., 0., 5., 3., 11., 7., 24., 10., 5., 21., 8., 14., 10., 5., 1., 2., 3., 12., 6., 20., 41., 15., 28., 11., 3., 1., 9., 1., 10., 3., 14., 8., 3., 24., 10., 21., 7., 2., 2., 0., 7., 0., 2., 0., 2., 4., 3., 2., 3., 5., 3., 2., 0., 2., 4., 0., 1., 2., 0., 6., 2., 4., 3., 4., 3., 2., 3., 0., 4., 8., 1., 0., 1., 1., 1., 2., 3., 1., 3., 3., 2., 0., 0., 0., 0., 3., 0., 0., 0., 0., 0.,  [...]
+
+10., 1., 1., 2., 13., 0., 15., 1., 5., 42., 0., 4., 61., 0., 8., 0., 0., 1., 78., 10., 14., 71., 12., 92., 8., 4., 0., 1., 0., 2., 21., 6., 53., 13., 2., 43., 32., 16., 8., 0., 0., 6., 4., 21., 5., 17., 9., 9., 6., 1., 0., 0., 8., 2., 18., 3., 15., 5., 12., 4., 2., 42., 7., 8., 3., 0., 14., 1., 11., 1., 14., 4., 6., 0., 0., 2., 0., 9., 3., 16., 10., 1., 4., 3., 1., 0., 0., 0., 0., 0., 10., 1., 3., 4., 4., 0., 0., 0., 1., 0., 0., 0., 0., 3., 2., 0., 4., 0., 2., 0., 0., 0., 0., 0., 0., 0., [...]
+
+14., 2., 3., 4., 12., 0., 8., 1., 8., 51., 0., 8., 48., 1., 1., 6., 0., 3., 68., 11., 7., 59., 14., 53., 17., 3., 0., 0., 2., 1., 15., 11., 49., 17., 1., 37., 38., 17., 10., 0., 0., 9., 1., 29., 4., 26., 9., 10., 3., 2., 4., 0., 11., 6., 14., 3., 19., 1., 11., 2., 3., 33., 10., 5., 2., 0., 10., 3., 8., 3., 11., 3., 3., 0., 1., 1., 0., 6., 2., 18., 10., 4., 3., 0., 1., 0., 0., 0., 0., 0., 9., 1., 1., 1., 3., 1., 2., 0., 1., 0., 0., 0., 1., 3., 2., 0., 2., 0., 0., 0., 1., 0., 0., 0., 1., 0 [...]
+
+11., 0., 0., 2., 13., 0., 11., 3., 7., 48., 1., 12., 58., 3., 1., 2., 0., 4., 78., 8., 3., 76., 11., 82., 11., 4., 0., 0., 3., 3., 15., 14., 46., 9., 0., 41., 32., 8., 6., 0., 1., 6., 1., 20., 4., 31., 3., 9., 6., 3., 2., 0., 9., 9., 14., 8., 19., 4., 9., 7., 3., 38., 8., 4., 2., 0., 13., 1., 7., 3., 12., 3., 3., 0., 1., 3., 0., 0., 5., 15., 11., 5., 4., 1., 1., 0., 0., 0., 0., 0., 9., 2., 2., 3., 0., 0., 1., 0., 2., 0., 1., 0., 0., 6., 0., 0., 1., 0., 1., 0., 3., 0., 0., 0., 3., 0., 0., [...]
+
+12., 0., 2., 4., 4., 0., 18., 1., 9., 47., 0., 5., 39., 1., 5., 1., 0., 1., 75., 7., 12., 76., 10., 104., 11., 5., 0., 0., 4., 1., 18., 9., 48., 15., 3., 47., 44., 17., 9., 0., 2., 5., 7., 23., 9., 28., 9., 15., 10., 2., 1., 0., 13., 5., 14., 6., 15., 1., 7., 4., 4., 38., 8., 5., 3., 0., 12., 3., 11., 3., 12., 0., 4., 1., 0., 1., 0., 3., 0., 23., 10., 2., 2., 0., 7., 0., 0., 0., 0., 0., 6., 1., 3., 4., 1., 1., 0., 0., 2., 0., 2., 0., 2., 4., 5., 0., 1., 0., 3., 0., 3., 0., 0., 0., 2., 0. [...]
+
+14., 0., 1., 3., 8., 0., 21., 3., 6., 54., 0., 7., 56., 2., 4., 3., 0., 2., 47., 12., 6., 84., 15., 69., 18., 6., 0., 0., 0., 2., 4., 7., 43., 13., 0., 43., 36., 15., 4., 0., 1., 4., 3., 25., 6., 26., 10., 8., 3., 3., 2., 0., 19., 7., 12., 6., 11., 3., 2., 2., 1., 39., 9., 4., 3., 0., 10., 1., 10., 6., 8., 3., 6., 0., 5., 2., 0., 6., 4., 7., 4., 1., 5., 0., 4., 0., 0., 0., 0., 0., 7., 2., 0., 2., 2., 0., 2., 0., 1., 0., 1., 0., 4., 2., 3., 0., 0., 0., 2., 0., 1., 0., 0., 0., 3., 0., 0.,  [...]
+
+3., 0., 1., 4., 12., 0., 15., 2., 7., 68., 0., 13., 55., 1., 3., 2., 0., 5., 79., 11., 4., 73., 15., 72., 8., 3., 0., 0., 3., 1., 8., 12., 43., 15., 1., 37., 36., 13., 11., 0., 0., 4., 2., 25., 4., 35., 7., 10., 6., 4., 1., 0., 10., 6., 17., 3., 17., 4., 5., 1., 5., 32., 9., 10., 3., 0., 10., 2., 11., 2., 6., 0., 7., 0., 0., 1., 0., 3., 1., 11., 6., 2., 1., 0., 3., 0., 0., 0., 0., 0., 12., 0., 3., 1., 2., 1., 0., 0., 3., 0., 0., 0., 2., 4., 2., 0., 4., 0., 2., 0., 0., 0., 0., 0., 1., 0., [...]
+
+12., 2., 1., 3., 15., 0., 12., 2., 7., 41., 1., 7., 68., 2., 3., 3., 0., 1., 82., 7., 11., 84., 18., 85., 12., 3., 0., 0., 2., 2., 15., 16., 56., 15., 1., 35., 24., 13., 7., 0., 0., 10., 4., 29., 4., 21., 10., 12., 5., 4., 2., 0., 8., 3., 15., 4., 12., 3., 4., 3., 1., 39., 8., 7., 2., 0., 18., 4., 9., 2., 7., 3., 4., 1., 3., 0., 0., 5., 2., 15., 11., 4., 5., 2., 4., 0., 0., 0., 0., 0., 9., 2., 3., 1., 4., 0., 1., 0., 2., 0., 0., 0., 0., 2., 1., 0., 1., 0., 0., 0., 0., 0., 0., 0., 1., 0., [...]
+
+10., 1., 4., 6., 15., 0., 11., 5., 4., 56., 4., 2., 45., 1., 4., 1., 0., 1., 74., 9., 12., 80., 11., 78., 11., 7., 0., 2., 5., 2., 12., 11., 66., 13., 2., 41., 29., 11., 6., 0., 1., 5., 6., 29., 8., 22., 8., 5., 7., 5., 1., 0., 15., 5., 22., 1., 13., 4., 8., 5., 9., 32., 11., 3., 2., 0., 12., 4., 9., 1., 5., 3., 2., 1., 0., 1., 0., 5., 3., 8., 14., 5., 4., 0., 8., 0., 0., 0., 0., 0., 7., 1., 3., 3., 1., 1., 0., 0., 0., 0., 1., 0., 1., 3., 1., 0., 2., 0., 2., 0., 1., 0., 0., 0., 2., 0., 0 [...]
+
+10., 2., 2., 4., 13., 0., 18., 1., 7., 63., 0., 14., 57., 2., 5., 3., 0., 3., 83., 7., 7., 75., 13., 62., 15., 4., 0., 2., 2., 3., 10., 6., 57., 5., 5., 40., 28., 13., 5., 0., 1., 6., 3., 18., 7., 24., 11., 16., 5., 2., 3., 0., 11., 3., 16., 2., 14., 3., 6., 1., 1., 34., 5., 12., 1., 0., 15., 2., 6., 5., 11., 4., 5., 1., 0., 0., 0., 3., 0., 14., 11., 1., 2., 3., 4., 0., 0., 0., 0., 0., 9., 4., 4., 1., 2., 1., 2., 0., 0., 0., 2., 0., 1., 4., 3., 0., 2., 0., 1., 0., 1., 0., 0., 0., 0., 0., [...]
+
+7., 0., 2., 4., 8., 0., 14., 1., 5., 30., 1., 13., 56., 1., 7., 2., 0., 0., 57., 13., 7., 78., 16., 76., 11., 5., 0., 0., 3., 1., 13., 4., 51., 10., 1., 41., 29., 12., 5., 0., 0., 4., 2., 22., 5., 21., 5., 9., 10., 5., 3., 0., 10., 3., 23., 3., 11., 3., 6., 5., 3., 40., 6., 4., 0., 0., 8., 2., 7., 2., 13., 4., 3., 0., 1., 1., 0., 5., 0., 12., 14., 2., 0., 0., 1., 0., 0., 0., 0., 0., 17., 2., 3., 2., 6., 2., 0., 0., 0., 0., 1., 0., 1., 3., 0., 0., 3., 0., 0., 0., 1., 0., 0., 0., 2., 0., 3 [...]
+
+15., 3., 4., 6., 20., 3., 35., 1., 11., 127., 1., 35., 198., 7., 18., 8., 2., 11., 63., 2., 16., 260., 54., 349., 35., 16., 1., 2., 2., 2., 41., 42., 273., 36., 9., 168., 17., 48., 2., 0., 1., 21., 8., 59., 25., 79., 16., 29., 59., 12., 4., 1., 28., 4., 34., 13., 48., 11., 27., 5., 11., 7., 0., 0., 0., 0., 22., 3., 14., 2., 33., 6., 16., 8., 3., 1., 1., 1., 5., 2., 7., 3., 13., 4., 4., 3., 0., 1., 148., 6., 1882., 86., 113., 222., 105., 113., 60., 19., 14., 10., 14., 0., 0., 5., 3., 7.,  [...]
+
+10., 2., 1., 3., 10., 2., 6., 1., 4., 33., 4., 7., 11., 2., 16., 3., 2., 4., 11., 2., 7., 37., 13., 21., 21., 9., 2., 2., 3., 1., 9., 10., 24., 16., 1., 14., 3., 19., 11., 0., 1., 4., 4., 10., 7., 21., 47., 15., 23., 8., 1., 3., 4., 1., 3., 2., 7., 7., 5., 20., 6., 21., 8., 3., 1., 1., 9., 1., 1., 3., 5., 2., 5., 2., 1., 4., 5., 1., 0., 0., 1., 0., 5., 2., 1., 6., 3., 5., 1., 3., 6., 0., 2., 1., 1., 6., 2., 0., 4., 1., 2., 1., 1., 0., 2., 1., 2., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0 [...]
+
+4., 0., 1., 4., 13., 9., 2., 2., 3., 22., 2., 18., 16., 3., 8., 7., 0., 8., 17., 2., 7., 11., 11., 26., 21., 7., 1., 3., 3., 1., 10., 9., 20., 12., 3., 18., 1., 20., 9., 2., 2., 3., 2., 9., 9., 19., 49., 7., 15., 11., 5., 0., 5., 0., 8., 4., 3., 11., 9., 18., 8., 24., 13., 3., 0., 0., 4., 1., 3., 1., 7., 2., 3., 3., 2., 3., 5., 1., 1., 0., 0., 0., 2., 3., 1., 5., 1., 2., 2., 1., 4., 1., 4., 2., 1., 10., 4., 0., 2., 4., 3., 1., 2., 2., 2., 0., 0., 0., 0., 0., 0., 2., 0., 0., 4., 0., 0., 0 [...]
+
+10., 1., 5., 2., 8., 2., 9., 1., 7., 24., 1., 12., 24., 2., 18., 1., 1., 3., 23., 0., 4., 20., 12., 25., 39., 6., 1., 1., 2., 2., 8., 11., 25., 13., 1., 16., 5., 17., 11., 1., 1., 4., 1., 11., 10., 11., 45., 12., 22., 7., 3., 0., 7., 1., 9., 5., 8., 3., 9., 14., 6., 27., 10., 2., 1., 1., 8., 2., 1., 1., 6., 2., 3., 1., 4., 1., 2., 1., 0., 1., 1., 0., 3., 0., 2., 4., 3., 3., 2., 5., 5., 0., 1., 0., 5., 12., 3., 0., 2., 0., 2., 3., 1., 3., 2., 1., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0. [...]
+
+6., 1., 1., 5., 8., 1., 7., 0., 9., 34., 0., 8., 27., 1., 12., 3., 1., 2., 18., 1., 3., 28., 6., 18., 25., 4., 4., 0., 7., 1., 3., 10., 17., 14., 3., 13., 3., 22., 7., 1., 0., 4., 2., 14., 8., 16., 46., 14., 13., 9., 3., 2., 3., 2., 5., 3., 6., 5., 6., 13., 7., 26., 8., 3., 1., 0., 2., 2., 3., 4., 6., 2., 3., 5., 1., 4., 3., 4., 2., 2., 2., 0., 2., 2., 2., 7., 2., 2., 1., 0., 4., 1., 1., 1., 2., 9., 2., 0., 1., 2., 1., 2., 2., 2., 0., 0., 4., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0., 0 [...]
+
+10., 2., 3., 2., 5., 0., 5., 1., 5., 21., 1., 19., 20., 1., 20., 1., 2., 1., 22., 3., 1., 21., 13., 33., 27., 7., 1., 1., 7., 4., 5., 9., 26., 20., 4., 13., 2., 8., 7., 2., 0., 5., 5., 16., 12., 16., 30., 15., 16., 6., 1., 1., 4., 0., 6., 3., 13., 2., 2., 23., 6., 25., 9., 5., 0., 1., 7., 1., 4., 0., 7., 1., 9., 3., 1., 4., 3., 2., 0., 2., 1., 0., 5., 2., 1., 10., 1., 5., 1., 1., 3., 0., 4., 2., 1., 8., 0., 0., 4., 6., 3., 2., 0., 3., 3., 1., 2., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0 [...]
+
+5., 1., 5., 4., 5., 4., 12., 0., 4., 13., 2., 21., 2., 3., 14., 5., 2., 2., 18., 2., 5., 27., 8., 28., 22., 7., 4., 1., 5., 3., 4., 6., 21., 15., 2., 14., 1., 15., 15., 1., 2., 3., 1., 13., 10., 18., 39., 16., 27., 11., 3., 0., 4., 1., 6., 4., 8., 5., 8., 20., 3., 20., 8., 7., 3., 2., 7., 1., 3., 2., 5., 5., 5., 2., 2., 5., 4., 3., 1., 1., 2., 0., 2., 4., 1., 6., 3., 1., 3., 3., 4., 3., 5., 0., 2., 6., 3., 0., 4., 4., 2., 0., 3., 2., 1., 1., 2., 0., 0., 0., 0., 1., 0., 0., 4., 0., 0., 0. [...]
+
+9., 1., 1., 8., 7., 3., 7., 2., 9., 22., 0., 17., 15., 3., 18., 3., 1., 5., 20., 1., 5., 29., 11., 29., 23., 4., 2., 4., 1., 3., 5., 14., 40., 16., 2., 25., 4., 15., 12., 5., 0., 4., 2., 12., 14., 26., 55., 13., 18., 9., 1., 1., 4., 0., 7., 1., 9., 8., 8., 15., 12., 28., 9., 6., 1., 1., 6., 0., 3., 1., 2., 3., 3., 3., 3., 3., 2., 2., 1., 1., 2., 0., 2., 3., 3., 7., 3., 3., 4., 2., 4., 2., 1., 2., 2., 7., 1., 0., 0., 3., 1., 2., 1., 4., 3., 0., 2., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0.,  [...]
+
+3., 3., 1., 3., 6., 3., 7., 0., 7., 12., 0., 13., 15., 2., 12., 3., 0., 1., 22., 2., 3., 14., 11., 31., 27., 5., 0., 1., 3., 2., 6., 10., 17., 11., 3., 19., 4., 16., 5., 1., 0., 2., 1., 14., 6., 28., 48., 10., 19., 11., 3., 0., 2., 2., 6., 3., 4., 12., 5., 14., 5., 24., 11., 4., 1., 0., 12., 1., 4., 1., 11., 3., 4., 6., 0., 3., 0., 2., 1., 3., 3., 0., 3., 3., 2., 13., 1., 3., 2., 5., 4., 1., 0., 0., 2., 7., 3., 0., 2., 3., 0., 1., 3., 2., 3., 1., 2., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0 [...]
+
+9., 0., 4., 6., 9., 1., 8., 0., 7., 26., 1., 9., 17., 1., 16., 2., 1., 1., 18., 3., 1., 31., 15., 15., 29., 5., 0., 1., 1., 3., 8., 14., 17., 25., 0., 13., 4., 12., 9., 0., 0., 1., 2., 14., 5., 20., 49., 10., 17., 9., 4., 1., 4., 4., 4., 6., 10., 4., 6., 16., 8., 17., 9., 1., 0., 0., 6., 0., 5., 3., 5., 4., 3., 4., 3., 3., 1., 2., 1., 2., 2., 0., 3., 0., 2., 4., 0., 2., 2., 0., 8., 0., 2., 0., 2., 8., 4., 0., 2., 0., 4., 2., 0., 6., 2., 2., 3., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0., [...]
+
+6., 2., 1., 7., 9., 4., 9., 0., 10., 13., 1., 24., 28., 0., 21., 5., 2., 4., 18., 2., 4., 15., 16., 31., 25., 6., 1., 2., 4., 2., 5., 2., 16., 5., 7., 22., 7., 21., 8., 1., 1., 4., 2., 15., 12., 14., 60., 8., 24., 8., 7., 0., 4., 0., 12., 3., 10., 5., 8., 24., 6., 37., 6., 1., 2., 0., 10., 0., 1., 1., 2., 2., 3., 3., 2., 3., 2., 3., 1., 1., 2., 0., 0., 5., 3., 8., 0., 5., 3., 3., 5., 0., 2., 1., 3., 9., 2., 0., 2., 1., 1., 5., 3., 6., 3., 0., 5., 0., 0., 0., 0., 0., 0., 0., 4., 0., 0., 0 [...]
+
+9., 1., 3., 6., 3., 3., 4., 1., 12., 14., 1., 10., 21., 1., 14., 2., 1., 1., 15., 2., 7., 11., 3., 21., 30., 7., 0., 2., 4., 1., 13., 6., 38., 17., 5., 20., 5., 7., 7., 4., 1., 5., 2., 19., 9., 14., 51., 14., 21., 14., 4., 1., 5., 1., 10., 5., 9., 7., 4., 22., 4., 19., 7., 3., 1., 0., 6., 1., 1., 1., 6., 0., 3., 3., 2., 6., 4., 2., 2., 2., 1., 0., 3., 1., 2., 5., 1., 4., 2., 1., 5., 1., 0., 0., 3., 12., 3., 0., 3., 2., 2., 3., 1., 1., 1., 0., 2., 0., 0., 0., 0., 0., 0., 0., 3., 0., 0., 0 [...]
+
+7., 3., 0., 1., 11., 4., 5., 0., 4., 22., 0., 10., 30., 1., 18., 5., 1., 0., 19., 2., 7., 31., 11., 19., 34., 3., 2., 1., 0., 4., 3., 9., 26., 14., 4., 20., 6., 16., 8., 6., 2., 6., 1., 18., 7., 19., 54., 14., 15., 9., 2., 1., 4., 0., 4., 1., 11., 11., 13., 20., 5., 24., 4., 3., 1., 2., 7., 0., 5., 3., 1., 5., 5., 2., 3., 2., 4., 2., 0., 2., 1., 0., 1., 1., 4., 7., 3., 4., 4., 0., 5., 1., 1., 1., 2., 3., 2., 0., 5., 3., 2., 2., 4., 3., 2., 0., 3., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0.,  [...]
+
+7., 0., 0., 2., 8., 6., 4., 1., 4., 19., 2., 17., 26., 2., 15., 2., 4., 2., 13., 3., 2., 9., 10., 22., 26., 7., 0., 1., 1., 2., 3., 7., 26., 19., 1., 15., 7., 13., 7., 2., 2., 3., 2., 10., 14., 25., 44., 12., 19., 5., 4., 1., 2., 3., 8., 5., 15., 5., 7., 10., 5., 20., 14., 2., 0., 3., 12., 1., 2., 0., 3., 2., 3., 3., 0., 4., 8., 2., 0., 2., 2., 0., 2., 2., 0., 6., 0., 2., 1., 2., 5., 1., 3., 1., 2., 5., 2., 0., 1., 4., 0., 3., 1., 0., 2., 0., 0., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., 0 [...]
+
+3., 0., 1., 1., 10., 3., 2., 6., 3., 19., 2., 15., 8., 0., 14., 2., 0., 1., 15., 7., 7., 38., 7., 25., 20., 6., 3., 0., 3., 1., 9., 9., 36., 19., 5., 17., 1., 13., 8., 1., 1., 7., 3., 16., 7., 15., 49., 8., 17., 5., 2., 1., 6., 4., 9., 3., 8., 3., 10., 22., 7., 21., 9., 1., 1., 2., 5., 0., 3., 1., 3., 0., 3., 4., 2., 3., 4., 1., 1., 0., 5., 0., 2., 3., 4., 3., 3., 4., 4., 1., 0., 1., 3., 0., 2., 6., 2., 0., 3., 3., 3., 3., 4., 1., 0., 1., 2., 0., 0., 0., 0., 3., 0., 0., 0., 0., 0., 0., 4 [...]
+
+6., 2., 0., 5., 9., 0., 5., 1., 5., 24., 0., 10., 13., 3., 15., 1., 0., 0., 26., 2., 3., 34., 14., 14., 29., 6., 2., 3., 1., 2., 10., 6., 28., 11., 1., 14., 3., 14., 7., 1., 2., 2., 2., 18., 18., 18., 41., 19., 13., 14., 5., 0., 4., 1., 7., 2., 13., 12., 9., 8., 5., 14., 8., 4., 2., 1., 8., 1., 4., 1., 5., 1., 10., 6., 2., 3., 2., 2., 1., 1., 2., 0., 1., 2., 1., 8., 3., 3., 0., 2., 4., 0., 3., 0., 3., 8., 2., 0., 2., 4., 0., 4., 1., 2., 2., 2., 4., 0., 0., 0., 0., 5., 0., 0., 2., 0., 0., [...]
+
+2., 2., 3., 4., 12., 3., 4., 1., 2., 12., 1., 11., 23., 1., 12., 5., 0., 2., 17., 0., 3., 36., 11., 26., 25., 7., 2., 0., 5., 0., 9., 6., 5., 23., 4., 19., 2., 20., 12., 3., 1., 3., 2., 12., 7., 22., 51., 9., 29., 14., 9., 3., 2., 3., 6., 1., 12., 6., 10., 13., 3., 28., 11., 5., 1., 2., 8., 1., 3., 0., 3., 1., 0., 5., 2., 6., 1., 1., 1., 3., 2., 0., 0., 1., 4., 6., 1., 3., 4., 6., 4., 2., 1., 1., 2., 9., 3., 0., 1., 3., 4., 1., 1., 2., 0., 2., 0., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0.,  [...]
+
+14., 1., 3., 1., 7., 1., 2., 2., 5., 13., 0., 12., 19., 1., 8., 2., 0., 5., 15., 4., 1., 27., 10., 29., 29., 5., 1., 1., 2., 2., 7., 4., 12., 17., 2., 14., 7., 20., 10., 3., 0., 6., 3., 14., 11., 27., 60., 7., 15., 7., 3., 0., 3., 5., 8., 5., 8., 10., 14., 20., 6., 18., 11., 2., 0., 0., 5., 1., 5., 3., 5., 1., 2., 6., 2., 5., 1., 4., 0., 2., 1., 0., 2., 0., 0., 3., 2., 1., 0., 2., 5., 1., 1., 1., 0., 7., 2., 0., 2., 2., 0., 1., 5., 0., 4., 1., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0.,  [...]
+
+7., 2., 3., 2., 7., 1., 5., 1., 9., 17., 1., 10., 28., 1., 14., 1., 0., 2., 17., 4., 6., 22., 17., 21., 24., 4., 0., 0., 3., 2., 8., 5., 43., 22., 1., 8., 3., 19., 10., 3., 0., 7., 1., 13., 4., 23., 46., 17., 28., 12., 5., 1., 3., 3., 5., 6., 7., 6., 10., 14., 13., 15., 8., 0., 0., 1., 4., 1., 3., 1., 6., 1., 5., 4., 3., 4., 2., 1., 0., 3., 2., 0., 3., 1., 1., 8., 5., 3., 1., 2., 4., 1., 3., 0., 3., 8., 4., 0., 3., 5., 4., 1., 2., 2., 1., 0., 3., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0 [...]
+
+11., 2., 2., 1., 5., 2., 9., 0., 10., 8., 2., 8., 20., 0., 16., 1., 3., 0., 18., 4., 2., 15., 9., 28., 28., 8., 2., 0., 2., 0., 8., 12., 22., 23., 2., 10., 3., 15., 9., 3., 1., 3., 1., 14., 9., 17., 50., 14., 22., 7., 2., 1., 9., 2., 8., 1., 9., 4., 11., 13., 7., 25., 4., 5., 1., 1., 13., 1., 1., 3., 7., 5., 2., 2., 2., 4., 3., 3., 0., 3., 0., 0., 1., 2., 0., 4., 1., 3., 3., 3., 4., 0., 3., 1., 1., 6., 3., 0., 1., 4., 4., 1., 2., 2., 1., 3., 1., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0. [...]
+
+5., 2., 2., 3., 6., 3., 3., 1., 5., 26., 2., 18., 27., 2., 12., 4., 1., 1., 18., 5., 8., 24., 12., 17., 31., 7., 1., 1., 1., 2., 4., 6., 27., 10., 1., 22., 4., 15., 7., 3., 2., 6., 3., 12., 10., 19., 43., 11., 23., 9., 5., 0., 2., 1., 10., 1., 13., 4., 11., 15., 10., 19., 9., 3., 0., 1., 8., 0., 3., 5., 6., 2., 3., 3., 1., 3., 1., 1., 3., 1., 3., 0., 3., 1., 0., 2., 1., 4., 3., 2., 3., 1., 1., 0., 3., 15., 0., 0., 2., 4., 1., 2., 2., 2., 3., 0., 3., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0. [...]
+
+8., 0., 4., 5., 11., 0., 25., 0., 6., 62., 1., 13., 71., 1., 4., 1., 0., 2., 76., 9., 9., 82., 16., 76., 10., 4., 0., 2., 1., 1., 19., 9., 52., 8., 4., 45., 33., 8., 6., 0., 0., 4., 4., 17., 7., 23., 4., 7., 4., 3., 2., 0., 17., 6., 12., 3., 22., 4., 8., 2., 2., 34., 10., 11., 2., 0., 14., 7., 10., 4., 18., 2., 5., 2., 1., 0., 0., 7., 1., 19., 12., 1., 5., 0., 4., 0., 0., 0., 0., 0., 6., 0., 2., 2., 5., 0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 3., 0., 2., 0., 2., 0., 0., 0., 3., 0., 3 [...]
+
+12., 2., 1., 2., 5., 0., 12., 2., 7., 34., 3., 8., 52., 1., 6., 1., 0., 1., 45., 14., 10., 81., 10., 77., 7., 2., 0., 0., 2., 2., 11., 6., 37., 11., 3., 45., 37., 19., 3., 0., 0., 7., 3., 23., 8., 25., 8., 12., 6., 5., 2., 0., 9., 1., 18., 8., 14., 0., 11., 4., 3., 27., 9., 10., 6., 0., 13., 7., 4., 1., 12., 1., 2., 1., 2., 1., 0., 2., 3., 14., 12., 2., 7., 3., 0., 0., 0., 0., 0., 0., 9., 1., 6., 2., 4., 0., 0., 0., 1., 0., 0., 0., 1., 3., 2., 0., 3., 0., 0., 0., 2., 0., 0., 0., 2., 0.,  [...]
+
+8., 0., 2., 7., 7., 0., 20., 5., 5., 57., 1., 6., 61., 2., 7., 1., 0., 3., 69., 9., 12., 61., 16., 79., 14., 5., 0., 2., 1., 1., 17., 4., 49., 10., 2., 36., 35., 9., 6., 0., 0., 4., 4., 22., 4., 28., 8., 5., 8., 1., 0., 0., 7., 6., 16., 3., 17., 1., 14., 2., 0., 44., 7., 9., 4., 0., 18., 3., 7., 3., 9., 5., 4., 0., 3., 0., 0., 2., 4., 14., 7., 3., 3., 0., 2., 0., 0., 0., 0., 0., 12., 1., 1., 0., 3., 1., 1., 0., 2., 0., 1., 0., 2., 1., 3., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 4., 0 [...]
+
+8., 2., 1., 6., 12., 0., 16., 3., 13., 47., 0., 5., 42., 1., 6., 0., 0., 4., 64., 10., 8., 72., 15., 71., 14., 1., 0., 2., 2., 2., 19., 7., 65., 9., 1., 33., 30., 14., 3., 0., 1., 8., 2., 22., 7., 26., 11., 7., 7., 3., 0., 0., 12., 5., 24., 5., 9., 4., 5., 3., 3., 38., 5., 7., 0., 0., 17., 1., 7., 1., 13., 0., 1., 1., 4., 1., 0., 6., 0., 21., 9., 2., 4., 1., 1., 0., 0., 0., 0., 0., 8., 1., 4., 3., 2., 0., 1., 0., 2., 0., 0., 0., 4., 3., 2., 0., 2., 0., 0., 0., 1., 0., 0., 0., 2., 0., 5., [...]
+
+14., 0., 3., 0., 11., 0., 11., 2., 8., 48., 1., 9., 46., 0., 4., 0., 0., 1., 75., 3., 12., 73., 12., 82., 6., 7., 0., 0., 3., 2., 18., 8., 61., 11., 3., 33., 32., 10., 4., 0., 1., 9., 4., 19., 7., 26., 9., 10., 5., 3., 2., 0., 6., 8., 19., 2., 23., 2., 8., 2., 6., 39., 5., 6., 3., 0., 12., 2., 8., 3., 7., 4., 3., 1., 0., 0., 0., 5., 1., 18., 12., 2., 6., 1., 3., 0., 0., 0., 0., 0., 13., 1., 4., 3., 1., 2., 1., 0., 3., 0., 2., 0., 1., 5., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 2., 0., 2. [...]
+
+11., 1., 7., 4., 11., 0., 19., 0., 4., 58., 2., 7., 57., 0., 4., 3., 0., 1., 80., 17., 8., 79., 14., 77., 9., 5., 0., 1., 2., 3., 7., 6., 57., 6., 0., 36., 37., 9., 3., 0., 0., 7., 6., 25., 3., 14., 5., 11., 6., 3., 0., 0., 9., 6., 20., 4., 19., 4., 6., 4., 3., 34., 8., 9., 1., 0., 17., 2., 10., 1., 13., 5., 3., 1., 1., 0., 0., 7., 2., 13., 9., 2., 5., 2., 3., 0., 0., 0., 0., 0., 18., 0., 3., 4., 2., 0., 1., 0., 1., 0., 1., 0., 2., 4., 4., 0., 2., 0., 3., 0., 0., 0., 0., 0., 0., 0., 4.,  [...]
+
+3., 1., 3., 6., 8., 0., 15., 1., 8., 47., 0., 3., 64., 2., 4., 1., 0., 0., 75., 4., 5., 84., 5., 98., 5., 5., 0., 1., 5., 3., 11., 6., 46., 16., 3., 38., 34., 7., 4., 0., 2., 7., 5., 32., 9., 25., 5., 4., 4., 4., 1., 0., 11., 3., 12., 6., 13., 4., 6., 6., 3., 32., 11., 10., 0., 0., 11., 3., 5., 1., 6., 0., 3., 2., 3., 0., 0., 3., 1., 14., 12., 5., 2., 1., 4., 0., 0., 0., 0., 0., 5., 1., 2., 5., 3., 1., 0., 0., 0., 0., 0., 0., 1., 0., 2., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 2., 0. [...]
+
+5., 1., 2., 2., 13., 0., 13., 1., 15., 57., 0., 6., 53., 1., 2., 1., 0., 3., 74., 9., 8., 79., 16., 76., 13., 2., 0., 1., 4., 1., 14., 9., 53., 9., 2., 34., 33., 14., 4., 0., 0., 8., 5., 19., 6., 22., 6., 13., 3., 1., 2., 0., 11., 8., 11., 8., 15., 3., 12., 3., 2., 38., 11., 7., 2., 0., 7., 3., 7., 3., 8., 4., 4., 0., 0., 0., 0., 2., 2., 21., 8., 3., 2., 3., 3., 0., 0., 0., 0., 0., 16., 4., 2., 0., 1., 0., 0., 0., 1., 0., 1., 0., 1., 6., 2., 0., 1., 0., 2., 0., 2., 0., 0., 0., 0., 0., 0. [...]
+
+12., 0., 1., 2., 9., 0., 17., 4., 10., 49., 1., 11., 40., 1., 8., 1., 0., 0., 70., 15., 12., 68., 16., 90., 12., 3., 0., 2., 1., 4., 21., 6., 35., 10., 3., 39., 22., 12., 4., 0., 2., 7., 5., 22., 5., 19., 5., 11., 1., 2., 1., 0., 14., 4., 12., 5., 11., 3., 4., 2., 4., 43., 8., 4., 0., 0., 12., 7., 10., 2., 15., 2., 3., 0., 0., 1., 0., 6., 1., 17., 7., 3., 5., 1., 4., 0., 0., 0., 0., 0., 11., 0., 2., 3., 2., 0., 5., 0., 0., 0., 0., 0., 1., 4., 1., 0., 1., 0., 4., 0., 0., 0., 0., 0., 0., 0 [...]
+
+14., 0., 2., 4., 12., 0., 9., 1., 8., 47., 2., 11., 48., 1., 2., 1., 0., 1., 79., 6., 10., 64., 14., 56., 11., 2., 0., 0., 4., 1., 13., 7., 81., 14., 0., 38., 33., 19., 3., 0., 1., 6., 4., 24., 8., 28., 6., 11., 1., 5., 1., 0., 15., 4., 18., 5., 20., 2., 10., 4., 3., 49., 11., 6., 2., 0., 15., 3., 9., 1., 10., 3., 6., 1., 0., 2., 0., 3., 1., 11., 9., 2., 7., 0., 3., 0., 0., 0., 0., 0., 7., 3., 2., 0., 4., 0., 0., 0., 1., 0., 0., 0., 0., 2., 3., 0., 1., 0., 0., 0., 0., 0., 0., 0., 1., 0., [...]
+
+14., 2., 2., 1., 13., 0., 16., 3., 7., 43., 1., 10., 57., 0., 8., 0., 0., 4., 73., 12., 1., 81., 10., 94., 10., 8., 0., 0., 6., 0., 14., 18., 43., 12., 2., 36., 28., 9., 6., 0., 0., 4., 6., 17., 8., 20., 8., 16., 5., 4., 0., 0., 12., 5., 19., 6., 20., 1., 8., 4., 5., 44., 15., 7., 1., 0., 14., 4., 7., 4., 11., 4., 6., 0., 3., 1., 0., 6., 2., 12., 11., 2., 7., 0., 2., 0., 0., 0., 0., 0., 16., 1., 5., 1., 4., 0., 1., 0., 1., 0., 0., 0., 1., 2., 5., 0., 3., 0., 0., 0., 1., 0., 0., 0., 1., 0 [...]
+
+12., 4., 1., 8., 31., 8., 24., 3., 16., 147., 2., 17., 186., 10., 11., 7., 0., 4., 79., 1., 12., 284., 37., 327., 41., 19., 1., 6., 8., 6., 52., 35., 202., 37., 8., 168., 12., 50., 11., 0., 0., 11., 9., 67., 23., 91., 18., 44., 43., 10., 5., 1., 26., 8., 39., 12., 50., 8., 37., 2., 14., 5., 1., 0., 0., 0., 25., 5., 16., 2., 30., 4., 14., 5., 2., 6., 0., 2., 5., 1., 14., 3., 7., 0., 10., 1., 1., 7., 132., 7., 1762., 81., 115., 228., 77., 111., 67., 15., 12., 15., 16., 2., 2., 10., 1., 4., [...]
+
+9., 2., 2., 8., 8., 5., 6., 0., 10., 18., 1., 13., 19., 3., 16., 2., 1., 0., 18., 2., 3., 28., 6., 27., 28., 5., 1., 0., 1., 1., 12., 7., 21., 16., 1., 20., 7., 13., 6., 1., 0., 4., 2., 9., 9., 21., 44., 10., 14., 5., 4., 0., 6., 0., 9., 4., 14., 5., 7., 14., 7., 22., 8., 3., 0., 0., 6., 1., 3., 1., 4., 5., 2., 5., 2., 4., 2., 2., 2., 1., 3., 0., 2., 3., 6., 7., 3., 9., 3., 1., 7., 0., 4., 2., 4., 9., 2., 0., 1., 0., 2., 3., 2., 1., 4., 2., 1., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0., [...]
+
+12., 0., 2., 4., 11., 1., 5., 1., 12., 20., 2., 12., 17., 3., 13., 3., 2., 0., 17., 3., 4., 27., 12., 17., 26., 5., 2., 0., 1., 1., 8., 11., 29., 13., 6., 19., 3., 17., 5., 2., 1., 6., 1., 8., 13., 19., 45., 7., 23., 7., 1., 2., 8., 2., 8., 2., 4., 5., 4., 22., 6., 11., 9., 7., 2., 0., 8., 1., 5., 1., 4., 3., 3., 3., 2., 4., 2., 0., 1., 1., 3., 0., 1., 0., 1., 3., 0., 3., 3., 0., 5., 3., 1., 1., 4., 6., 1., 0., 1., 3., 1., 3., 3., 1., 4., 0., 1., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., 0 [...]
+
+13., 2., 1., 1., 12., 3., 6., 0., 10., 31., 3., 9., 21., 0., 17., 2., 0., 3., 13., 0., 5., 19., 12., 19., 17., 8., 0., 2., 4., 6., 11., 7., 36., 8., 3., 11., 2., 17., 9., 2., 3., 10., 1., 13., 8., 23., 38., 20., 23., 13., 4., 2., 5., 3., 7., 4., 12., 3., 9., 9., 8., 20., 9., 3., 2., 0., 10., 2., 3., 2., 7., 1., 4., 2., 0., 1., 4., 6., 2., 3., 1., 0., 1., 1., 3., 7., 2., 4., 2., 0., 6., 1., 0., 1., 2., 5., 1., 0., 1., 1., 5., 2., 2., 2., 0., 0., 2., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., [...]
+
+9., 2., 3., 8., 8., 5., 8., 2., 9., 14., 1., 10., 24., 3., 14., 5., 2., 3., 12., 0., 1., 14., 15., 25., 23., 5., 0., 0., 6., 0., 5., 4., 22., 7., 2., 15., 8., 9., 7., 1., 0., 5., 2., 7., 6., 14., 51., 14., 17., 9., 8., 1., 5., 1., 6., 2., 6., 4., 5., 19., 9., 15., 9., 3., 1., 0., 7., 2., 6., 4., 7., 1., 7., 2., 1., 0., 5., 3., 2., 2., 1., 0., 5., 3., 3., 12., 2., 6., 0., 3., 4., 2., 2., 1., 0., 6., 4., 0., 1., 5., 3., 3., 2., 4., 2., 2., 0., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0., 2. [...]
+
+5., 0., 1., 7., 7., 4., 14., 1., 6., 21., 2., 8., 30., 1., 20., 5., 2., 4., 17., 3., 5., 29., 12., 9., 24., 10., 3., 3., 0., 1., 4., 11., 22., 26., 1., 19., 2., 20., 8., 1., 0., 4., 1., 14., 5., 20., 40., 16., 20., 6., 4., 3., 6., 3., 6., 5., 8., 11., 7., 12., 3., 32., 5., 1., 1., 0., 9., 1., 5., 1., 2., 1., 6., 7., 0., 5., 2., 1., 2., 1., 2., 0., 1., 4., 2., 4., 2., 5., 1., 4., 2., 0., 4., 0., 2., 3., 1., 0., 2., 2., 1., 1., 1., 0., 1., 1., 3., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0. [...]
+
+8., 1., 2., 6., 9., 3., 9., 0., 3., 24., 0., 18., 23., 1., 12., 8., 1., 1., 11., 2., 1., 28., 15., 32., 29., 5., 0., 1., 2., 1., 7., 9., 14., 18., 4., 12., 3., 8., 11., 3., 0., 5., 0., 9., 13., 9., 38., 9., 17., 5., 3., 1., 5., 3., 11., 4., 9., 9., 8., 16., 6., 30., 11., 4., 2., 2., 8., 0., 1., 3., 5., 1., 2., 1., 3., 3., 9., 1., 1., 4., 3., 0., 0., 3., 2., 7., 3., 4., 1., 2., 6., 2., 3., 2., 0., 4., 3., 0., 4., 2., 3., 1., 4., 5., 3., 0., 0., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0.,  [...]
+
+6., 0., 4., 1., 8., 2., 4., 1., 5., 16., 0., 14., 13., 1., 8., 2., 0., 0., 29., 3., 5., 21., 14., 20., 29., 4., 0., 2., 2., 2., 6., 5., 22., 18., 2., 18., 3., 13., 5., 0., 1., 5., 3., 6., 13., 9., 40., 7., 16., 5., 1., 2., 2., 2., 9., 1., 9., 8., 1., 15., 5., 19., 14., 4., 1., 0., 9., 1., 3., 1., 2., 2., 6., 10., 1., 3., 6., 1., 0., 4., 3., 0., 3., 0., 1., 8., 2., 8., 1., 0., 5., 0., 2., 0., 0., 3., 3., 0., 2., 4., 4., 3., 3., 2., 2., 0., 0., 0., 0., 0., 0., 2., 0., 0., 4., 0., 0., 0., 1 [...]
+
+12., 0., 2., 5., 8., 0., 6., 1., 5., 11., 2., 12., 35., 0., 21., 4., 4., 1., 9., 3., 6., 38., 12., 17., 30., 7., 0., 1., 2., 2., 8., 5., 15., 17., 5., 13., 2., 20., 9., 0., 1., 5., 2., 20., 5., 20., 45., 10., 23., 9., 1., 0., 4., 2., 5., 1., 11., 5., 9., 16., 5., 32., 9., 4., 1., 3., 8., 0., 7., 4., 8., 2., 2., 5., 0., 4., 4., 1., 0., 1., 2., 0., 4., 2., 1., 5., 2., 4., 0., 5., 3., 3., 0., 3., 2., 4., 2., 0., 5., 1., 2., 1., 0., 5., 4., 0., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0., [...]
+
+13., 2., 2., 3., 7., 0., 5., 2., 4., 20., 1., 19., 14., 1., 13., 3., 0., 3., 14., 1., 2., 32., 10., 16., 24., 5., 0., 0., 1., 4., 8., 4., 24., 15., 1., 9., 9., 13., 10., 3., 2., 1., 1., 6., 14., 14., 52., 15., 33., 8., 2., 1., 5., 0., 4., 0., 7., 6., 6., 17., 8., 20., 6., 1., 0., 0., 7., 2., 3., 2., 7., 2., 4., 2., 3., 2., 1., 2., 0., 3., 3., 0., 2., 1., 2., 6., 1., 6., 1., 1., 8., 1., 0., 3., 6., 9., 6., 0., 2., 2., 0., 2., 0., 2., 4., 1., 4., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0., [...]
+
+6., 1., 2., 3., 9., 2., 10., 0., 5., 35., 0., 12., 17., 4., 12., 5., 0., 4., 17., 3., 2., 33., 15., 18., 33., 3., 2., 2., 2., 3., 7., 4., 27., 19., 3., 19., 5., 16., 8., 1., 0., 4., 3., 13., 12., 18., 52., 8., 30., 5., 3., 0., 7., 5., 5., 3., 10., 6., 5., 13., 4., 25., 12., 2., 2., 1., 5., 1., 3., 4., 4., 1., 4., 6., 4., 1., 2., 2., 2., 1., 3., 0., 1., 3., 0., 5., 2., 4., 2., 1., 2., 2., 1., 0., 1., 13., 2., 0., 0., 4., 1., 3., 1., 1., 4., 2., 1., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0.,  [...]
+
+8., 0., 0., 4., 7., 2., 2., 0., 3., 21., 1., 11., 28., 3., 18., 2., 2., 1., 24., 5., 3., 19., 11., 20., 26., 8., 2., 1., 2., 2., 7., 13., 23., 16., 3., 17., 4., 12., 10., 1., 3., 6., 4., 10., 14., 10., 50., 11., 31., 7., 3., 1., 9., 2., 7., 1., 8., 6., 10., 9., 11., 20., 4., 1., 0., 2., 8., 1., 2., 4., 8., 2., 9., 2., 2., 8., 1., 3., 2., 2., 0., 0., 4., 0., 4., 3., 1., 3., 4., 0., 1., 1., 1., 1., 3., 7., 2., 0., 1., 0., 4., 2., 0., 3., 3., 0., 0., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0.,  [...]
+
+8., 1., 3., 3., 4., 4., 8., 1., 5., 15., 0., 15., 18., 0., 23., 4., 0., 5., 20., 2., 4., 17., 13., 12., 18., 11., 1., 1., 1., 1., 11., 9., 26., 23., 0., 13., 5., 12., 9., 0., 0., 1., 5., 16., 10., 30., 52., 8., 22., 13., 2., 1., 5., 2., 6., 6., 9., 5., 7., 12., 4., 10., 7., 2., 2., 0., 5., 0., 4., 1., 1., 3., 4., 4., 2., 5., 1., 3., 1., 4., 2., 0., 2., 1., 0., 4., 2., 10., 1., 1., 0., 3., 1., 1., 1., 5., 3., 0., 2., 1., 4., 1., 1., 2., 2., 2., 2., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0.,  [...]
+
+2., 2., 1., 5., 9., 5., 5., 1., 6., 31., 3., 15., 16., 1., 17., 4., 1., 0., 16., 1., 3., 6., 13., 29., 29., 7., 2., 1., 3., 4., 6., 10., 44., 21., 2., 16., 4., 17., 8., 0., 2., 4., 3., 16., 8., 15., 51., 14., 18., 12., 0., 3., 2., 5., 8., 2., 9., 4., 3., 12., 4., 22., 8., 3., 0., 0., 6., 0., 2., 2., 5., 1., 3., 3., 1., 2., 7., 1., 1., 3., 2., 0., 2., 3., 5., 3., 3., 6., 3., 1., 6., 2., 3., 1., 4., 13., 6., 0., 0., 0., 3., 3., 0., 5., 2., 0., 5., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. [...]
+
+5., 1., 4., 4., 10., 5., 4., 1., 4., 21., 0., 16., 19., 2., 14., 1., 3., 2., 15., 4., 5., 19., 15., 27., 22., 5., 0., 1., 5., 2., 5., 14., 20., 16., 1., 11., 2., 13., 5., 0., 0., 7., 4., 15., 11., 15., 33., 9., 28., 11., 4., 1., 10., 4., 5., 3., 9., 6., 9., 13., 4., 26., 7., 0., 0., 1., 8., 0., 3., 2., 5., 8., 1., 4., 1., 4., 6., 0., 0., 0., 2., 0., 2., 3., 2., 7., 2., 3., 3., 2., 3., 1., 2., 1., 1., 9., 4., 0., 1., 2., 1., 2., 3., 2., 3., 2., 5., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0.,  [...]
+
+8., 2., 6., 2., 6., 1., 3., 1., 6., 22., 0., 8., 26., 0., 15., 2., 0., 4., 22., 2., 6., 17., 8., 19., 25., 7., 0., 1., 3., 1., 10., 2., 28., 16., 2., 8., 5., 7., 8., 0., 0., 3., 2., 15., 15., 20., 44., 10., 20., 8., 5., 0., 10., 3., 10., 1., 8., 6., 9., 29., 4., 22., 10., 3., 0., 0., 7., 2., 3., 3., 6., 0., 2., 4., 0., 5., 5., 2., 0., 0., 0., 0., 5., 3., 2., 5., 5., 4., 3., 0., 2., 0., 4., 0., 1., 9., 6., 0., 3., 0., 1., 3., 2., 2., 1., 3., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0., [...]
+
+10., 1., 6., 1., 4., 1., 8., 1., 4., 16., 1., 14., 32., 2., 18., 3., 1., 1., 21., 3., 0., 20., 12., 18., 28., 6., 0., 1., 2., 2., 9., 9., 29., 16., 3., 14., 0., 8., 10., 0., 1., 9., 1., 3., 16., 20., 45., 12., 23., 8., 5., 0., 4., 2., 4., 4., 19., 4., 8., 14., 7., 20., 9., 3., 0., 1., 8., 1., 3., 1., 7., 3., 1., 1., 4., 3., 2., 2., 0., 4., 1., 0., 3., 2., 1., 7., 5., 8., 0., 2., 4., 2., 3., 0., 2., 11., 2., 0., 1., 1., 1., 4., 2., 5., 1., 0., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0 [...]
+
+16., 4., 6., 5., 4., 4., 4., 0., 6., 8., 0., 21., 33., 0., 15., 1., 1., 0., 19., 0., 2., 22., 10., 18., 29., 6., 0., 2., 4., 0., 12., 11., 35., 16., 0., 18., 2., 11., 15., 0., 2., 4., 2., 12., 8., 18., 46., 14., 22., 12., 2., 0., 3., 0., 2., 3., 8., 9., 5., 8., 3., 24., 4., 2., 1., 1., 4., 2., 1., 2., 7., 5., 4., 1., 2., 4., 5., 2., 3., 2., 5., 0., 4., 0., 1., 7., 2., 4., 2., 2., 4., 0., 3., 0., 1., 5., 1., 0., 2., 7., 2., 5., 2., 1., 1., 2., 3., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., 0 [...]
+
+8., 1., 1., 2., 7., 3., 4., 0., 10., 29., 1., 13., 23., 2., 15., 2., 0., 2., 18., 2., 2., 10., 15., 17., 28., 3., 1., 0., 5., 2., 9., 5., 38., 24., 2., 12., 5., 11., 7., 2., 1., 2., 2., 13., 10., 16., 45., 17., 12., 13., 5., 1., 5., 1., 3., 2., 12., 4., 7., 22., 3., 21., 5., 1., 0., 2., 5., 1., 0., 3., 5., 2., 3., 4., 1., 4., 1., 0., 2., 2., 1., 0., 1., 3., 2., 5., 2., 3., 3., 2., 4., 0., 3., 1., 1., 7., 3., 0., 0., 0., 1., 2., 0., 4., 2., 0., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0.,  [...]
+
+5., 2., 3., 6., 7., 3., 7., 2., 6., 18., 1., 13., 23., 0., 19., 3., 1., 2., 31., 2., 5., 43., 13., 28., 35., 4., 1., 0., 2., 1., 4., 9., 27., 14., 8., 26., 4., 17., 8., 0., 2., 1., 0., 9., 6., 19., 52., 20., 25., 8., 3., 0., 5., 1., 7., 4., 7., 8., 10., 8., 4., 19., 3., 2., 2., 2., 7., 0., 2., 4., 3., 2., 1., 3., 6., 3., 3., 1., 0., 3., 1., 0., 3., 2., 2., 11., 3., 4., 0., 0., 2., 0., 2., 0., 1., 6., 1., 0., 3., 4., 4., 2., 3., 1., 1., 1., 4., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0.,  [...]
+
+13., 1., 2., 1., 13., 0., 23., 6., 9., 46., 1., 6., 61., 1., 4., 3., 0., 0., 63., 10., 6., 69., 16., 93., 16., 3., 0., 2., 3., 0., 21., 6., 35., 10., 1., 37., 23., 11., 4., 0., 2., 2., 0., 28., 6., 32., 9., 16., 5., 2., 4., 0., 4., 6., 15., 9., 17., 3., 13., 2., 3., 45., 6., 12., 0., 0., 10., 1., 6., 3., 18., 2., 3., 1., 0., 2., 0., 4., 3., 16., 9., 1., 7., 3., 4., 0., 0., 0., 0., 0., 13., 3., 1., 4., 0., 1., 3., 0., 1., 0., 0., 0., 1., 1., 3., 0., 2., 0., 0., 0., 0., 0., 0., 0., 4., 0., [...]
+
+13., 3., 1., 6., 13., 0., 19., 3., 6., 40., 2., 4., 62., 1., 5., 1., 0., 4., 80., 3., 11., 63., 16., 71., 7., 4., 0., 1., 2., 0., 13., 7., 61., 8., 3., 36., 38., 10., 8., 0., 2., 8., 5., 25., 5., 14., 7., 6., 8., 2., 3., 0., 7., 5., 19., 5., 20., 0., 5., 5., 1., 31., 9., 9., 3., 0., 20., 4., 6., 0., 10., 3., 0., 0., 2., 3., 0., 3., 2., 10., 22., 1., 3., 2., 2., 0., 0., 0., 0., 0., 7., 4., 3., 3., 2., 1., 0., 0., 0., 0., 3., 0., 0., 4., 2., 0., 1., 0., 1., 0., 3., 0., 0., 0., 0., 0., 1.,  [...]
+
+11., 1., 2., 5., 8., 0., 9., 0., 6., 56., 1., 13., 48., 0., 4., 1., 0., 2., 67., 10., 5., 65., 10., 72., 13., 8., 0., 0., 4., 1., 16., 13., 53., 18., 1., 39., 31., 17., 4., 0., 1., 3., 1., 24., 5., 27., 6., 10., 11., 2., 2., 0., 13., 3., 27., 5., 14., 2., 7., 1., 4., 43., 12., 12., 1., 0., 15., 4., 11., 4., 10., 1., 4., 2., 4., 1., 0., 6., 2., 17., 10., 5., 5., 1., 3., 0., 0., 0., 0., 0., 7., 2., 2., 1., 2., 0., 1., 0., 1., 0., 1., 0., 0., 4., 4., 0., 5., 0., 3., 0., 0., 0., 0., 0., 0.,  [...]
+
+12., 1., 5., 1., 8., 0., 20., 1., 3., 44., 2., 7., 58., 1., 5., 3., 0., 2., 64., 7., 8., 83., 14., 81., 8., 3., 0., 2., 1., 4., 14., 8., 42., 15., 3., 36., 30., 14., 7., 0., 1., 7., 4., 25., 14., 19., 7., 11., 4., 6., 1., 0., 10., 3., 11., 5., 17., 4., 10., 4., 4., 51., 12., 7., 2., 0., 23., 4., 9., 5., 15., 2., 4., 1., 0., 1., 0., 2., 3., 14., 12., 1., 2., 2., 2., 0., 0., 0., 0., 0., 9., 1., 2., 0., 2., 0., 2., 0., 0., 0., 1., 0., 0., 2., 2., 0., 2., 0., 0., 0., 0., 0., 0., 0., 0., 0.,  [...]
+
+8., 2., 4., 1., 7., 0., 11., 1., 8., 34., 1., 8., 64., 1., 4., 1., 0., 3., 55., 5., 7., 69., 16., 90., 12., 2., 0., 2., 3., 0., 20., 8., 47., 17., 1., 43., 33., 20., 5., 0., 0., 4., 2., 17., 7., 31., 11., 22., 8., 2., 2., 0., 9., 5., 17., 9., 18., 3., 6., 3., 3., 36., 6., 6., 2., 0., 5., 3., 9., 2., 7., 1., 3., 1., 3., 1., 0., 2., 1., 16., 12., 2., 1., 1., 5., 0., 0., 0., 0., 0., 12., 1., 2., 0., 3., 0., 1., 0., 1., 0., 3., 0., 6., 0., 2., 0., 2., 0., 3., 0., 1., 0., 0., 0., 1., 0., 1.,  [...]
+
+8., 2., 4., 1., 10., 0., 9., 1., 7., 56., 0., 7., 56., 3., 2., 3., 0., 1., 56., 5., 4., 73., 12., 94., 11., 6., 0., 2., 3., 1., 16., 6., 58., 11., 1., 43., 37., 16., 4., 0., 2., 4., 2., 23., 7., 24., 3., 13., 5., 2., 2., 0., 7., 8., 12., 5., 16., 0., 6., 4., 2., 45., 1., 7., 0., 0., 13., 2., 7., 1., 15., 1., 4., 2., 1., 0., 0., 5., 2., 13., 3., 3., 3., 2., 0., 0., 0., 0., 0., 0., 12., 0., 6., 1., 2., 0., 0., 0., 1., 0., 4., 0., 1., 5., 2., 0., 4., 0., 1., 0., 3., 0., 0., 0., 1., 0., 2.,  [...]
+
+10., 2., 1., 4., 8., 0., 17., 3., 8., 42., 1., 9., 40., 2., 9., 1., 0., 1., 73., 5., 5., 90., 14., 81., 16., 3., 0., 4., 1., 3., 9., 11., 53., 15., 3., 33., 26., 18., 6., 0., 0., 6., 7., 26., 8., 26., 9., 11., 5., 6., 2., 0., 5., 7., 14., 4., 15., 5., 10., 2., 6., 38., 7., 13., 3., 0., 8., 5., 5., 2., 6., 4., 5., 2., 0., 1., 0., 4., 1., 11., 6., 6., 2., 0., 3., 0., 0., 0., 0., 0., 8., 5., 3., 1., 6., 0., 0., 0., 0., 0., 1., 0., 0., 5., 1., 0., 2., 0., 0., 0., 1., 0., 0., 0., 2., 0., 1.,  [...]
+
+8., 4., 1., 3., 8., 0., 10., 2., 4., 62., 2., 8., 46., 1., 6., 3., 0., 2., 55., 7., 9., 72., 20., 78., 11., 6., 0., 0., 2., 2., 15., 9., 52., 12., 1., 37., 36., 17., 7., 0., 0., 4., 2., 19., 5., 25., 4., 11., 5., 1., 2., 0., 7., 10., 15., 6., 17., 3., 6., 2., 6., 37., 7., 9., 2., 0., 13., 5., 11., 2., 10., 3., 3., 1., 0., 0., 0., 3., 5., 22., 5., 3., 1., 0., 1., 0., 0., 0., 0., 0., 10., 2., 1., 1., 4., 1., 0., 0., 2., 0., 0., 0., 1., 5., 1., 0., 4., 0., 0., 0., 4., 0., 0., 0., 1., 0., 0. [...]
+
+10., 2., 2., 4., 17., 0., 12., 5., 6., 50., 0., 8., 51., 0., 4., 3., 0., 2., 67., 7., 7., 78., 13., 59., 15., 0., 0., 1., 4., 0., 18., 12., 49., 19., 2., 29., 40., 14., 9., 0., 1., 8., 5., 15., 8., 26., 8., 9., 5., 1., 4., 0., 14., 3., 11., 8., 18., 1., 9., 5., 1., 31., 9., 10., 1., 0., 7., 5., 6., 0., 10., 2., 7., 3., 1., 1., 0., 2., 0., 13., 7., 5., 2., 2., 1., 0., 0., 0., 0., 0., 3., 1., 2., 3., 7., 0., 0., 0., 1., 0., 1., 0., 0., 5., 1., 0., 5., 0., 3., 0., 2., 0., 0., 0., 1., 0., 4. [...]
+
+11., 2., 3., 6., 18., 0., 10., 4., 6., 59., 3., 8., 77., 4., 6., 2., 0., 1., 82., 9., 12., 73., 19., 91., 7., 4., 0., 1., 3., 5., 11., 9., 42., 11., 2., 45., 32., 16., 2., 0., 0., 7., 1., 26., 3., 25., 4., 17., 6., 2., 1., 0., 14., 6., 11., 3., 14., 4., 12., 3., 7., 20., 8., 9., 2., 0., 13., 1., 10., 3., 13., 1., 4., 2., 0., 1., 0., 4., 4., 20., 9., 3., 4., 1., 6., 0., 0., 0., 0., 0., 5., 3., 3., 3., 3., 0., 2., 0., 2., 0., 4., 0., 2., 4., 2., 0., 1., 0., 1., 0., 2., 0., 0., 0., 1., 0.,  [...]
+
+10., 1., 4., 8., 12., 0., 21., 2., 8., 41., 0., 7., 58., 1., 7., 2., 0., 1., 70., 10., 9., 79., 11., 90., 19., 4., 0., 1., 6., 1., 16., 5., 47., 10., 3., 37., 28., 19., 3., 0., 2., 5., 4., 24., 4., 28., 2., 14., 11., 2., 1., 0., 8., 2., 15., 7., 16., 2., 6., 2., 3., 35., 14., 8., 1., 0., 13., 6., 5., 1., 12., 0., 4., 1., 0., 2., 0., 3., 3., 17., 4., 2., 6., 2., 3., 0., 0., 0., 0., 0., 11., 1., 6., 2., 1., 1., 2., 0., 1., 0., 3., 0., 0., 1., 4., 0., 2., 0., 2., 0., 0., 0., 0., 0., 1., 0., [...]
+
+8., 1., 0., 2., 13., 0., 13., 0., 6., 56., 0., 10., 53., 2., 4., 1., 0., 1., 65., 17., 13., 72., 22., 85., 7., 5., 0., 0., 4., 5., 17., 5., 58., 10., 3., 40., 33., 20., 6., 0., 0., 7., 1., 32., 6., 27., 7., 19., 7., 2., 2., 0., 12., 4., 14., 4., 15., 1., 8., 2., 4., 33., 7., 8., 3., 0., 10., 4., 6., 3., 4., 1., 9., 0., 1., 0., 0., 4., 0., 18., 9., 3., 7., 1., 2., 0., 0., 0., 0., 0., 7., 1., 2., 1., 2., 1., 1., 0., 2., 0., 2., 0., 4., 2., 3., 0., 1., 0., 2., 0., 0., 0., 0., 0., 1., 0., 2. [...]
+
+6., 3., 3., 8., 26., 9., 27., 2., 14., 169., 2., 30., 196., 7., 17., 3., 0., 5., 99., 1., 13., 263., 51., 357., 59., 18., 0., 2., 5., 4., 51., 32., 261., 44., 11., 148., 17., 49., 6., 0., 2., 16., 10., 80., 18., 90., 21., 36., 40., 13., 1., 0., 30., 6., 30., 7., 54., 11., 35., 6., 7., 9., 0., 0., 1., 0., 19., 3., 15., 3., 30., 4., 12., 4., 2., 2., 3., 2., 3., 0., 14., 3., 10., 0., 9., 2., 0., 4., 133., 8., 1846., 89., 116., 211., 99., 113., 72., 19., 16., 26., 9., 0., 1., 9., 5., 6., 7., [...]
+
+12., 1., 3., 4., 6., 2., 6., 4., 4., 23., 0., 8., 29., 2., 11., 1., 3., 4., 19., 3., 3., 21., 10., 28., 22., 5., 0., 2., 4., 2., 5., 5., 26., 14., 1., 14., 4., 14., 10., 1., 1., 3., 2., 5., 12., 15., 54., 10., 25., 10., 9., 2., 3., 2., 6., 2., 14., 12., 9., 10., 8., 22., 10., 2., 0., 1., 6., 2., 3., 3., 2., 3., 6., 1., 2., 2., 0., 2., 0., 2., 2., 0., 2., 2., 2., 10., 3., 3., 0., 2., 7., 2., 4., 0., 0., 6., 4., 0., 2., 2., 2., 1., 4., 8., 3., 1., 0., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0. [...]
+
+9., 0., 1., 3., 7., 1., 7., 1., 11., 31., 1., 8., 25., 1., 10., 1., 2., 1., 20., 2., 9., 29., 13., 29., 39., 11., 2., 2., 5., 0., 4., 7., 32., 18., 4., 18., 1., 13., 6., 4., 0., 2., 0., 5., 11., 20., 46., 9., 20., 6., 8., 1., 8., 3., 5., 3., 14., 9., 10., 24., 7., 17., 7., 3., 1., 1., 3., 1., 3., 2., 6., 1., 5., 6., 2., 0., 0., 2., 3., 3., 0., 0., 3., 1., 1., 5., 5., 3., 2., 7., 2., 0., 1., 0., 3., 11., 3., 0., 2., 3., 2., 2., 2., 2., 2., 0., 0., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., 0 [...]
+
+9., 1., 2., 6., 7., 3., 11., 0., 6., 29., 2., 8., 21., 0., 18., 5., 0., 3., 13., 3., 2., 31., 6., 22., 21., 5., 1., 0., 3., 1., 4., 5., 31., 14., 3., 10., 4., 10., 9., 2., 1., 7., 3., 14., 8., 17., 54., 5., 23., 12., 4., 0., 8., 1., 7., 3., 7., 9., 11., 19., 9., 25., 7., 3., 2., 0., 6., 0., 7., 2., 10., 3., 3., 4., 1., 5., 5., 1., 3., 3., 2., 0., 2., 1., 2., 3., 2., 4., 3., 3., 3., 0., 2., 1., 3., 7., 3., 0., 2., 5., 0., 0., 1., 3., 3., 2., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., [...]
+
+14., 0., 4., 5., 8., 4., 4., 2., 9., 20., 0., 13., 24., 0., 25., 6., 3., 2., 20., 4., 6., 16., 11., 31., 31., 5., 1., 0., 6., 1., 14., 7., 28., 16., 1., 18., 3., 18., 3., 3., 0., 0., 3., 18., 8., 16., 43., 18., 19., 8., 5., 1., 4., 4., 12., 2., 5., 7., 15., 16., 8., 18., 7., 1., 0., 2., 4., 2., 4., 3., 5., 7., 3., 6., 1., 2., 2., 0., 1., 8., 3., 0., 3., 2., 3., 4., 0., 2., 2., 2., 6., 1., 4., 2., 1., 10., 0., 0., 3., 1., 4., 0., 2., 2., 0., 0., 3., 0., 0., 0., 0., 1., 0., 0., 7., 0., 0., [...]
+
+8., 2., 1., 1., 6., 3., 4., 2., 5., 13., 0., 9., 19., 0., 7., 1., 0., 3., 26., 1., 2., 24., 12., 25., 24., 7., 4., 0., 1., 3., 7., 9., 35., 11., 2., 23., 3., 17., 8., 3., 0., 7., 0., 11., 13., 16., 40., 11., 25., 9., 5., 0., 6., 2., 5., 3., 14., 7., 10., 16., 8., 18., 6., 5., 2., 4., 7., 1., 2., 1., 6., 4., 3., 4., 1., 5., 4., 1., 3., 5., 5., 0., 1., 0., 1., 5., 2., 4., 4., 0., 2., 0., 6., 1., 2., 12., 1., 0., 1., 2., 2., 3., 2., 1., 4., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. [...]
+
+7., 2., 0., 3., 11., 3., 6., 0., 7., 13., 1., 12., 19., 0., 22., 3., 1., 0., 31., 3., 6., 20., 10., 22., 21., 4., 0., 2., 0., 5., 5., 4., 27., 16., 7., 25., 3., 14., 10., 4., 5., 5., 2., 7., 6., 24., 48., 14., 15., 15., 4., 0., 8., 3., 2., 2., 11., 4., 11., 14., 5., 20., 11., 5., 1., 0., 10., 2., 2., 2., 3., 1., 9., 1., 2., 5., 4., 1., 0., 4., 1., 0., 0., 2., 1., 9., 0., 5., 1., 4., 9., 0., 1., 0., 0., 4., 2., 0., 4., 1., 4., 2., 1., 1., 1., 2., 3., 0., 0., 0., 0., 3., 0., 0., 4., 0., 0. [...]
+
+12., 2., 2., 3., 12., 1., 6., 1., 4., 30., 1., 11., 25., 3., 9., 2., 0., 2., 22., 3., 2., 19., 14., 10., 27., 7., 1., 0., 1., 1., 4., 6., 28., 17., 2., 15., 4., 10., 7., 4., 1., 3., 0., 9., 3., 17., 42., 18., 20., 10., 5., 0., 3., 4., 9., 1., 4., 7., 8., 15., 6., 19., 10., 0., 1., 0., 2., 1., 2., 1., 2., 3., 3., 2., 2., 1., 4., 2., 1., 4., 2., 0., 3., 3., 1., 4., 3., 1., 0., 0., 4., 0., 1., 1., 2., 5., 2., 0., 2., 3., 0., 4., 3., 4., 2., 2., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0. [...]
+
+0., 3., 3., 7., 11., 1., 5., 1., 7., 8., 0., 15., 24., 0., 14., 2., 0., 1., 20., 2., 6., 31., 12., 23., 21., 5., 2., 0., 3., 4., 18., 6., 17., 16., 6., 13., 2., 12., 7., 0., 1., 4., 2., 18., 7., 16., 45., 11., 20., 15., 3., 0., 5., 2., 6., 3., 16., 5., 9., 19., 3., 23., 5., 5., 0., 1., 8., 3., 3., 4., 7., 2., 6., 4., 1., 2., 4., 1., 0., 4., 2., 0., 2., 5., 2., 6., 0., 3., 0., 2., 5., 2., 1., 1., 2., 7., 0., 0., 2., 2., 2., 1., 0., 4., 1., 1., 1., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., 0 [...]
+
+3., 0., 4., 1., 2., 3., 5., 1., 4., 11., 5., 15., 24., 1., 12., 3., 1., 1., 10., 4., 2., 14., 19., 39., 25., 8., 2., 1., 3., 3., 5., 6., 32., 11., 3., 19., 5., 6., 7., 3., 1., 4., 1., 11., 10., 15., 42., 7., 26., 6., 2., 1., 4., 3., 4., 3., 10., 5., 5., 16., 9., 19., 7., 0., 0., 1., 8., 0., 4., 0., 2., 3., 1., 1., 4., 0., 1., 3., 0., 3., 1., 0., 3., 2., 1., 7., 0., 0., 1., 1., 3., 1., 0., 0., 2., 9., 1., 0., 1., 1., 6., 3., 4., 2., 3., 0., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0.,  [...]
+
+3., 2., 0., 5., 5., 3., 6., 4., 7., 25., 1., 11., 16., 1., 18., 4., 3., 3., 18., 4., 6., 14., 11., 37., 27., 4., 1., 1., 3., 5., 7., 11., 14., 22., 6., 17., 1., 11., 8., 2., 1., 3., 2., 8., 16., 12., 43., 10., 18., 12., 8., 2., 3., 1., 8., 3., 4., 4., 11., 19., 6., 18., 9., 4., 2., 0., 6., 0., 4., 1., 6., 2., 5., 6., 3., 5., 3., 2., 2., 1., 2., 0., 0., 0., 2., 5., 2., 6., 2., 2., 2., 0., 2., 1., 2., 2., 1., 0., 1., 3., 0., 3., 3., 5., 1., 0., 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0 [...]
+
+11., 0., 0., 4., 11., 4., 10., 1., 10., 11., 1., 14., 28., 0., 10., 6., 0., 3., 19., 3., 2., 13., 13., 27., 28., 6., 1., 1., 1., 3., 7., 9., 20., 13., 1., 13., 5., 12., 11., 1., 0., 3., 3., 13., 10., 14., 50., 18., 20., 10., 4., 0., 5., 4., 8., 2., 8., 6., 8., 15., 6., 22., 7., 5., 0., 2., 6., 0., 1., 1., 0., 5., 5., 4., 0., 7., 3., 1., 2., 3., 0., 0., 3., 1., 2., 7., 0., 3., 3., 2., 6., 1., 2., 1., 4., 4., 4., 0., 0., 1., 0., 0., 2., 4., 1., 1., 4., 0., 0., 0., 0., 1., 0., 0., 5., 0., 0 [...]
+
+8., 2., 4., 3., 6., 4., 5., 0., 5., 24., 0., 15., 17., 1., 14., 3., 1., 1., 16., 2., 3., 20., 10., 29., 29., 2., 0., 1., 3., 4., 7., 5., 15., 19., 2., 12., 5., 16., 5., 2., 0., 2., 5., 8., 10., 25., 52., 11., 17., 8., 6., 2., 4., 3., 6., 1., 12., 9., 8., 8., 8., 14., 4., 2., 1., 1., 8., 1., 3., 1., 5., 2., 5., 3., 0., 2., 3., 2., 0., 2., 1., 0., 1., 3., 2., 7., 4., 2., 2., 1., 5., 1., 2., 0., 2., 10., 3., 0., 3., 2., 2., 3., 1., 3., 3., 1., 1., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0., 0., [...]
+
+8., 0., 2., 4., 8., 3., 2., 1., 9., 34., 0., 17., 26., 2., 19., 1., 0., 2., 16., 3., 5., 35., 14., 31., 30., 6., 2., 1., 2., 3., 6., 4., 35., 15., 2., 17., 1., 14., 12., 1., 1., 4., 3., 16., 13., 18., 54., 9., 25., 10., 3., 0., 10., 4., 7., 2., 6., 10., 7., 20., 11., 13., 14., 7., 1., 0., 2., 0., 2., 2., 5., 2., 5., 5., 3., 2., 4., 0., 0., 0., 1., 0., 1., 0., 1., 8., 1., 2., 6., 1., 2., 2., 2., 1., 1., 8., 2., 0., 1., 0., 1., 2., 5., 2., 0., 0., 2., 0., 0., 0., 0., 3., 0., 0., 5., 0., 0. [...]
+
+11., 0., 1., 5., 12., 2., 1., 1., 6., 32., 0., 14., 15., 1., 15., 4., 0., 1., 11., 3., 4., 18., 17., 26., 24., 9., 1., 1., 0., 3., 9., 9., 29., 15., 2., 12., 6., 17., 9., 1., 2., 5., 1., 9., 14., 21., 47., 12., 24., 10., 8., 0., 8., 4., 13., 0., 8., 7., 8., 15., 4., 21., 8., 1., 0., 1., 9., 3., 5., 2., 4., 5., 1., 4., 0., 6., 4., 4., 0., 3., 3., 0., 4., 1., 4., 4., 4., 2., 3., 4., 2., 1., 1., 1., 3., 4., 2., 0., 2., 3., 2., 2., 3., 2., 2., 0., 0., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0.,  [...]
+
+7., 0., 0., 4., 13., 5., 14., 0., 6., 16., 0., 10., 24., 0., 18., 0., 1., 1., 8., 0., 8., 27., 13., 10., 23., 4., 3., 1., 1., 3., 7., 11., 28., 19., 5., 20., 3., 14., 8., 1., 1., 4., 3., 10., 3., 15., 40., 10., 23., 13., 7., 2., 4., 0., 8., 3., 8., 6., 9., 13., 4., 19., 5., 1., 1., 1., 5., 0., 3., 1., 3., 2., 5., 1., 0., 5., 7., 5., 1., 1., 1., 0., 5., 2., 1., 3., 1., 1., 1., 2., 5., 1., 4., 1., 1., 6., 1., 0., 0., 1., 3., 0., 1., 6., 1., 1., 4., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0 [...]
+
+7., 2., 4., 6., 10., 7., 5., 1., 8., 19., 1., 11., 29., 1., 14., 2., 3., 3., 17., 4., 3., 23., 17., 30., 27., 4., 1., 1., 4., 4., 10., 6., 21., 10., 4., 17., 3., 18., 9., 1., 2., 4., 3., 20., 14., 19., 36., 11., 21., 8., 6., 1., 4., 3., 8., 2., 10., 8., 9., 17., 8., 16., 13., 4., 0., 1., 8., 3., 3., 1., 7., 0., 9., 5., 0., 4., 6., 2., 0., 1., 2., 0., 2., 0., 1., 4., 1., 2., 2., 0., 2., 1., 1., 0., 3., 8., 0., 0., 2., 0., 3., 0., 1., 1., 3., 1., 2., 0., 0., 0., 0., 0., 0., 0., 5., 0., 0., [...]
+
+5., 1., 1., 2., 8., 2., 7., 0., 5., 21., 3., 8., 19., 3., 20., 3., 2., 1., 18., 1., 2., 36., 10., 19., 29., 12., 1., 1., 4., 2., 3., 7., 15., 19., 5., 17., 3., 7., 9., 0., 1., 4., 1., 15., 17., 20., 50., 17., 18., 2., 4., 1., 10., 0., 3., 2., 12., 5., 8., 12., 2., 15., 6., 5., 2., 0., 12., 1., 7., 2., 9., 2., 1., 4., 3., 5., 2., 0., 1., 2., 0., 0., 1., 1., 1., 6., 1., 0., 1., 5., 2., 0., 2., 0., 1., 5., 0., 0., 1., 3., 2., 2., 2., 1., 1., 2., 2., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0., 0 [...]
+
+6., 0., 3., 4., 12., 0., 16., 3., 5., 42., 2., 6., 55., 1., 3., 3., 0., 1., 67., 8., 14., 79., 16., 87., 7., 5., 0., 0., 5., 4., 6., 10., 48., 15., 0., 30., 35., 13., 7., 0., 0., 7., 4., 22., 6., 21., 6., 7., 4., 5., 1., 0., 11., 9., 20., 9., 11., 7., 7., 3., 2., 32., 6., 12., 3., 0., 11., 1., 8., 1., 13., 1., 6., 3., 2., 1., 0., 7., 1., 18., 13., 4., 4., 0., 2., 0., 0., 0., 0., 0., 15., 3., 6., 1., 2., 2., 1., 0., 0., 0., 1., 0., 2., 6., 2., 0., 5., 0., 2., 0., 2., 0., 0., 0., 1., 0., 6 [...]
+
+12., 0., 2., 6., 16., 0., 15., 3., 6., 51., 0., 12., 58., 3., 1., 0., 0., 0., 52., 5., 8., 74., 11., 74., 11., 2., 0., 1., 3., 3., 10., 9., 39., 11., 0., 35., 36., 20., 4., 0., 2., 3., 2., 18., 10., 17., 6., 16., 14., 3., 1., 0., 10., 4., 19., 6., 15., 3., 9., 3., 1., 42., 8., 6., 2., 0., 22., 5., 8., 2., 17., 1., 6., 2., 1., 1., 0., 7., 4., 12., 10., 0., 6., 1., 1., 0., 0., 0., 0., 0., 9., 4., 4., 0., 5., 1., 1., 0., 2., 0., 1., 0., 0., 3., 1., 0., 0., 0., 0., 0., 2., 0., 0., 0., 1., 0. [...]
+
+4., 0., 1., 4., 7., 0., 14., 1., 3., 48., 3., 6., 59., 2., 6., 3., 0., 1., 82., 12., 7., 62., 12., 70., 16., 1., 0., 2., 3., 2., 12., 5., 66., 4., 1., 36., 28., 15., 5., 0., 2., 4., 2., 23., 5., 27., 6., 15., 6., 1., 8., 0., 13., 1., 13., 6., 29., 3., 7., 2., 2., 34., 8., 6., 4., 0., 17., 4., 7., 0., 13., 3., 1., 1., 1., 2., 0., 11., 1., 13., 6., 7., 10., 0., 2., 0., 0., 0., 0., 0., 4., 2., 6., 1., 3., 2., 1., 0., 1., 0., 1., 0., 0., 3., 4., 0., 4., 0., 1., 0., 0., 0., 0., 0., 2., 0., 2. [...]
+
+8., 1., 3., 6., 8., 0., 14., 0., 5., 38., 1., 4., 59., 2., 9., 3., 0., 1., 78., 9., 11., 76., 11., 76., 8., 3., 0., 0., 4., 2., 9., 6., 61., 11., 1., 43., 37., 17., 8., 0., 0., 8., 2., 26., 5., 26., 10., 11., 2., 5., 3., 0., 10., 1., 6., 3., 20., 2., 12., 4., 1., 34., 9., 4., 4., 0., 10., 6., 9., 2., 13., 0., 5., 0., 1., 2., 0., 4., 4., 25., 6., 8., 4., 1., 1., 0., 0., 0., 0., 0., 10., 6., 7., 4., 1., 3., 0., 0., 2., 0., 2., 0., 1., 4., 0., 0., 1., 0., 1., 0., 1., 0., 0., 0., 3., 0., 1., [...]
+
+5., 2., 4., 7., 7., 0., 10., 2., 8., 49., 0., 7., 58., 1., 8., 2., 0., 2., 72., 14., 6., 65., 13., 66., 10., 3., 0., 1., 2., 0., 4., 8., 62., 10., 4., 38., 35., 17., 4., 0., 1., 4., 4., 22., 3., 21., 4., 14., 5., 1., 3., 0., 7., 2., 23., 3., 12., 1., 10., 1., 4., 34., 2., 5., 3., 0., 11., 0., 8., 1., 10., 3., 6., 1., 1., 1., 0., 6., 1., 20., 9., 6., 5., 2., 2., 0., 0., 0., 0., 0., 7., 0., 4., 1., 4., 1., 1., 0., 2., 0., 1., 0., 0., 5., 4., 0., 4., 0., 1., 0., 1., 0., 0., 0., 0., 0., 2.,  [...]
+
+14., 2., 4., 3., 14., 0., 10., 3., 10., 57., 0., 10., 56., 0., 6., 0., 0., 3., 70., 7., 11., 76., 9., 85., 16., 4., 0., 2., 2., 2., 12., 8., 40., 12., 3., 40., 33., 15., 6., 0., 0., 5., 3., 30., 5., 24., 6., 9., 7., 3., 0., 0., 10., 10., 19., 7., 12., 4., 9., 5., 4., 31., 6., 10., 2., 0., 12., 7., 5., 0., 7., 2., 4., 0., 2., 1., 0., 7., 3., 20., 6., 3., 1., 1., 2., 0., 0., 0., 0., 0., 12., 1., 2., 1., 5., 1., 2., 0., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 3., 0., 1., 0., 0., 0., 0., 0., [...]
+
+13., 0., 1., 6., 9., 0., 19., 4., 5., 49., 2., 9., 60., 2., 5., 1., 0., 2., 54., 12., 6., 73., 14., 75., 16., 4., 0., 0., 3., 1., 12., 10., 37., 18., 1., 43., 28., 11., 5., 0., 0., 4., 1., 21., 0., 33., 5., 13., 9., 6., 2., 0., 10., 5., 18., 10., 10., 3., 12., 1., 5., 47., 11., 8., 4., 0., 11., 4., 6., 3., 7., 1., 6., 1., 1., 1., 0., 5., 1., 18., 14., 0., 3., 1., 2., 0., 0., 0., 0., 0., 13., 0., 4., 2., 3., 0., 1., 0., 0., 0., 2., 0., 2., 2., 1., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1., 0 [...]
+
+10., 0., 1., 7., 5., 0., 13., 3., 10., 66., 0., 4., 46., 0., 3., 0., 0., 1., 68., 10., 11., 71., 22., 96., 5., 0., 0., 4., 8., 1., 13., 3., 46., 14., 3., 42., 34., 16., 8., 0., 1., 6., 6., 21., 5., 24., 5., 17., 4., 4., 1., 0., 11., 6., 8., 5., 23., 3., 8., 0., 2., 37., 2., 12., 1., 0., 17., 9., 13., 1., 10., 5., 3., 0., 0., 0., 0., 9., 3., 13., 9., 6., 4., 4., 3., 0., 0., 0., 0., 0., 13., 2., 1., 1., 3., 2., 1., 0., 1., 0., 0., 0., 1., 3., 0., 0., 5., 0., 0., 0., 0., 0., 0., 0., 0., 0., [...]
+
+8., 2., 1., 8., 11., 0., 10., 2., 5., 42., 2., 6., 62., 0., 7., 2., 0., 3., 77., 13., 10., 88., 13., 82., 12., 7., 0., 1., 0., 1., 18., 5., 53., 13., 2., 38., 27., 13., 3., 0., 1., 4., 7., 28., 7., 21., 6., 16., 11., 3., 0., 0., 11., 1., 14., 7., 18., 1., 2., 3., 2., 28., 7., 11., 3., 0., 14., 1., 14., 5., 11., 2., 5., 0., 3., 1., 0., 3., 5., 12., 8., 2., 6., 3., 6., 0., 0., 0., 0., 0., 9., 1., 0., 2., 1., 1., 0., 0., 1., 0., 3., 0., 0., 2., 1., 0., 2., 0., 1., 0., 0., 0., 0., 0., 2., 0. [...]
+
+15., 1., 0., 4., 14., 0., 11., 2., 5., 66., 1., 11., 53., 1., 6., 2., 0., 2., 64., 8., 4., 78., 12., 97., 12., 5., 0., 2., 4., 1., 11., 13., 59., 15., 1., 33., 24., 11., 1., 0., 0., 3., 2., 32., 7., 33., 8., 12., 8., 2., 0., 0., 7., 5., 10., 5., 16., 8., 11., 3., 2., 34., 6., 5., 1., 0., 15., 4., 10., 1., 4., 0., 6., 1., 2., 0., 0., 2., 3., 14., 13., 4., 3., 0., 2., 0., 0., 0., 0., 0., 6., 1., 2., 2., 3., 0., 0., 0., 0., 0., 1., 0., 1., 3., 1., 0., 3., 0., 0., 0., 1., 0., 0., 0., 1., 0., [...]
+
+9., 1., 0., 7., 16., 0., 12., 1., 5., 64., 0., 8., 61., 0., 3., 1., 0., 1., 61., 13., 12., 69., 11., 86., 14., 3., 0., 2., 4., 1., 20., 10., 41., 11., 3., 41., 37., 16., 7., 0., 2., 6., 2., 21., 4., 16., 8., 8., 8., 7., 3., 0., 9., 2., 17., 3., 18., 5., 7., 5., 3., 37., 10., 7., 4., 0., 13., 0., 11., 3., 11., 0., 5., 4., 1., 1., 0., 6., 2., 10., 11., 2., 2., 0., 3., 0., 0., 0., 0., 0., 8., 2., 1., 2., 3., 2., 0., 0., 0., 0., 1., 0., 2., 5., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0., 2., 0., [...]
+
+8., 0., 4., 4., 15., 0., 15., 2., 9., 61., 1., 9., 62., 1., 3., 2., 0., 1., 89., 7., 12., 72., 13., 89., 6., 7., 0., 1., 4., 4., 20., 7., 56., 11., 2., 31., 45., 10., 3., 0., 1., 7., 4., 27., 8., 25., 13., 12., 4., 4., 0., 0., 11., 3., 23., 1., 22., 7., 10., 2., 2., 29., 14., 9., 4., 0., 13., 2., 7., 2., 5., 2., 3., 1., 0., 2., 0., 2., 2., 15., 13., 4., 6., 1., 2., 0., 0., 0., 0., 0., 13., 0., 2., 4., 2., 0., 1., 0., 2., 0., 1., 0., 0., 2., 2., 0., 1., 0., 3., 0., 1., 0., 0., 0., 0., 0., [...]
+
+4., 0., 2., 1., 11., 0., 20., 3., 4., 47., 0., 10., 66., 1., 4., 2., 0., 0., 80., 4., 9., 99., 11., 71., 19., 4., 0., 0., 1., 3., 12., 8., 53., 10., 1., 33., 24., 16., 5., 0., 2., 4., 1., 25., 3., 26., 4., 6., 0., 1., 5., 0., 7., 2., 19., 3., 11., 2., 11., 1., 2., 30., 7., 7., 1., 0., 14., 1., 10., 1., 11., 0., 4., 1., 0., 1., 0., 6., 1., 13., 6., 2., 4., 1., 4., 0., 0., 0., 0., 0., 3., 1., 4., 0., 1., 3., 2., 0., 0., 0., 2., 0., 0., 4., 0., 0., 3., 0., 0., 0., 0., 0., 0., 0., 3., 0., 0. [...]
+
+2., 1., 2., 3., 10., 0., 16., 3., 9., 49., 2., 8., 57., 1., 2., 3., 0., 1., 77., 7., 8., 77., 9., 85., 10., 4., 0., 0., 2., 5., 21., 10., 48., 8., 3., 43., 35., 17., 8., 0., 0., 10., 2., 23., 9., 24., 6., 11., 7., 5., 4., 0., 7., 4., 15., 1., 18., 4., 12., 1., 2., 34., 9., 8., 2., 0., 15., 2., 15., 0., 10., 4., 5., 0., 3., 1., 0., 2., 2., 19., 5., 5., 4., 1., 3., 0., 0., 0., 0., 0., 8., 1., 3., 1., 3., 0., 0., 0., 2., 0., 4., 0., 1., 3., 2., 0., 1., 0., 0., 0., 2., 0., 0., 0., 3., 0., 5. [...]
+
+8., 0., 2., 7., 16., 1., 6., 1., 9., 28., 0., 8., 20., 3., 10., 6., 1., 3., 10., 5., 4., 19., 12., 22., 32., 1., 1., 2., 1., 4., 10., 8., 23., 15., 2., 8., 4., 15., 8., 0., 2., 3., 4., 11., 5., 19., 45., 11., 20., 8., 6., 3., 7., 5., 10., 2., 9., 3., 3., 17., 12., 16., 7., 2., 0., 0., 5., 3., 5., 2., 2., 1., 4., 0., 1., 8., 3., 1., 0., 1., 4., 0., 2., 3., 5., 3., 1., 4., 3., 1., 5., 0., 4., 1., 4., 13., 2., 0., 0., 1., 4., 1., 1., 4., 1., 4., 3., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0., 0 [...]
+
+6., 1., 2., 5., 9., 4., 4., 1., 13., 24., 1., 6., 12., 2., 11., 2., 2., 0., 20., 2., 5., 12., 6., 30., 25., 6., 0., 0., 6., 0., 10., 9., 29., 15., 3., 13., 2., 16., 14., 1., 0., 3., 1., 11., 12., 27., 47., 25., 25., 12., 4., 0., 4., 2., 9., 1., 5., 11., 3., 16., 8., 18., 17., 3., 0., 1., 1., 0., 3., 2., 8., 4., 7., 3., 3., 4., 1., 3., 1., 1., 2., 0., 1., 2., 4., 7., 2., 5., 2., 0., 4., 2., 2., 2., 1., 9., 1., 0., 0., 0., 0., 2., 2., 0., 3., 1., 4., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., [...]
+
+8., 1., 2., 3., 9., 5., 5., 1., 1., 37., 1., 13., 28., 0., 17., 5., 2., 4., 23., 1., 6., 28., 14., 32., 22., 6., 3., 0., 3., 4., 5., 5., 24., 17., 5., 22., 7., 10., 12., 3., 1., 1., 3., 12., 8., 18., 39., 12., 25., 7., 2., 0., 5., 0., 14., 3., 8., 8., 16., 12., 1., 26., 9., 2., 1., 2., 7., 1., 3., 4., 3., 2., 1., 5., 4., 3., 3., 3., 1., 1., 3., 0., 1., 2., 0., 5., 2., 2., 3., 1., 4., 0., 2., 2., 2., 11., 0., 0., 3., 3., 3., 2., 2., 2., 1., 0., 2., 0., 0., 0., 0., 3., 0., 0., 0., 0., 0.,  [...]
+
+7., 1., 2., 1., 10., 3., 4., 0., 12., 26., 1., 18., 16., 0., 12., 0., 2., 1., 19., 2., 6., 27., 14., 14., 31., 8., 2., 0., 4., 4., 10., 5., 33., 19., 3., 20., 4., 14., 8., 2., 4., 5., 1., 17., 13., 10., 36., 17., 21., 4., 3., 1., 6., 2., 4., 2., 13., 4., 10., 7., 5., 18., 7., 2., 1., 0., 8., 0., 7., 1., 8., 2., 6., 5., 3., 2., 2., 2., 2., 0., 2., 0., 3., 2., 1., 5., 3., 4., 2., 2., 4., 4., 1., 1., 0., 9., 3., 0., 3., 2., 2., 1., 1., 2., 4., 1., 1., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., [...]
+
+8., 0., 1., 3., 7., 5., 9., 0., 7., 20., 1., 12., 21., 0., 16., 3., 1., 5., 19., 1., 8., 35., 12., 26., 34., 6., 2., 3., 2., 3., 5., 2., 28., 20., 4., 15., 6., 15., 7., 3., 0., 4., 0., 13., 7., 22., 34., 13., 18., 6., 7., 0., 6., 1., 3., 1., 8., 7., 10., 19., 6., 9., 5., 2., 1., 0., 5., 2., 2., 2., 5., 1., 3., 5., 5., 2., 4., 4., 2., 3., 2., 0., 3., 4., 0., 5., 1., 1., 2., 1., 3., 1., 1., 1., 3., 6., 3., 0., 2., 1., 2., 2., 1., 3., 2., 2., 2., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0.,  [...]
+
+12., 0., 3., 8., 3., 4., 9., 2., 8., 23., 0., 10., 16., 2., 12., 3., 1., 2., 16., 0., 6., 23., 14., 27., 18., 3., 0., 1., 7., 2., 5., 4., 39., 18., 2., 14., 4., 13., 5., 3., 2., 4., 3., 8., 7., 13., 56., 6., 26., 4., 2., 2., 2., 2., 11., 6., 13., 3., 10., 15., 2., 25., 10., 2., 1., 0., 2., 3., 5., 1., 5., 3., 2., 3., 2., 4., 2., 0., 1., 2., 5., 0., 1., 3., 2., 4., 2., 0., 3., 0., 2., 0., 2., 0., 1., 5., 1., 0., 1., 2., 1., 3., 1., 1., 0., 3., 2., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0 [...]
+
+11., 0., 2., 3., 12., 4., 7., 1., 3., 15., 1., 17., 13., 1., 11., 1., 1., 1., 21., 3., 6., 15., 11., 20., 29., 8., 2., 0., 3., 3., 10., 7., 14., 14., 3., 15., 6., 10., 12., 0., 1., 3., 0., 16., 11., 19., 50., 14., 26., 13., 2., 0., 3., 0., 2., 0., 10., 9., 7., 18., 5., 26., 9., 7., 1., 1., 9., 1., 6., 3., 5., 5., 5., 6., 1., 3., 6., 1., 0., 4., 5., 0., 0., 3., 1., 8., 3., 2., 2., 3., 4., 2., 1., 3., 1., 10., 4., 0., 1., 4., 1., 4., 1., 2., 2., 0., 4., 0., 0., 0., 0., 1., 0., 0., 1., 0.,  [...]
+
+8., 1., 2., 2., 6., 6., 4., 1., 6., 28., 0., 9., 23., 0., 16., 5., 0., 3., 19., 0., 1., 20., 13., 22., 22., 7., 1., 0., 4., 3., 5., 11., 33., 18., 7., 26., 5., 13., 4., 1., 1., 6., 1., 20., 8., 17., 50., 8., 22., 11., 9., 0., 7., 3., 4., 3., 12., 9., 6., 14., 5., 22., 6., 5., 1., 1., 12., 3., 7., 1., 3., 4., 6., 5., 0., 3., 7., 1., 3., 4., 5., 0., 3., 2., 4., 10., 4., 4., 3., 1., 3., 0., 3., 0., 4., 3., 5., 0., 1., 4., 3., 7., 3., 2., 0., 1., 1., 0., 0., 0., 0., 0., 0., 0., 3., 0., 0., 0 [...]
+
+10., 0., 5., 3., 5., 0., 6., 0., 4., 31., 0., 13., 27., 1., 11., 3., 0., 3., 25., 2., 3., 13., 16., 25., 25., 6., 0., 1., 6., 2., 10., 3., 25., 9., 1., 9., 4., 13., 4., 1., 1., 5., 2., 13., 9., 8., 41., 12., 18., 9., 7., 0., 2., 4., 7., 3., 5., 7., 15., 16., 11., 26., 10., 2., 0., 0., 2., 1., 2., 4., 6., 1., 3., 7., 3., 1., 4., 4., 1., 0., 2., 0., 3., 1., 0., 0., 0., 4., 3., 3., 1., 0., 1., 0., 3., 7., 0., 0., 1., 2., 1., 2., 4., 1., 1., 0., 4., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0. [...]
+
+9., 0., 0., 2., 7., 0., 10., 1., 11., 20., 2., 9., 10., 0., 8., 3., 2., 0., 24., 1., 2., 21., 6., 19., 16., 10., 0., 0., 2., 1., 8., 10., 20., 14., 2., 11., 7., 12., 10., 5., 0., 1., 4., 10., 12., 22., 36., 10., 11., 8., 6., 1., 5., 1., 10., 5., 5., 3., 10., 16., 3., 19., 12., 1., 2., 1., 4., 0., 2., 2., 8., 0., 5., 4., 1., 6., 4., 1., 0., 2., 2., 0., 3., 4., 3., 6., 2., 2., 1., 2., 3., 0., 2., 1., 1., 9., 2., 0., 2., 1., 1., 1., 1., 1., 0., 0., 3., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0. [...]
+
+8., 0., 1., 9., 4., 4., 4., 1., 4., 31., 0., 9., 26., 1., 16., 1., 1., 3., 27., 3., 4., 31., 19., 17., 25., 6., 3., 2., 6., 2., 8., 3., 38., 19., 4., 20., 4., 20., 7., 1., 1., 5., 0., 12., 8., 20., 46., 11., 20., 12., 4., 1., 6., 1., 4., 0., 16., 10., 11., 15., 11., 22., 5., 3., 1., 2., 7., 0., 1., 2., 8., 2., 5., 5., 2., 1., 3., 1., 0., 2., 0., 0., 1., 2., 1., 2., 2., 5., 3., 3., 4., 1., 5., 0., 3., 10., 1., 0., 0., 5., 0., 6., 2., 3., 3., 2., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., [...]
+
+8., 1., 2., 3., 10., 3., 6., 1., 6., 14., 2., 11., 19., 0., 11., 4., 0., 2., 22., 3., 4., 22., 15., 28., 26., 5., 3., 2., 3., 1., 6., 6., 29., 15., 5., 19., 3., 15., 8., 1., 1., 4., 0., 9., 14., 13., 53., 12., 14., 7., 4., 1., 2., 3., 8., 1., 10., 8., 9., 15., 4., 23., 5., 3., 0., 2., 2., 0., 2., 2., 8., 1., 7., 8., 2., 2., 2., 4., 0., 2., 0., 0., 2., 3., 5., 5., 1., 3., 0., 4., 7., 1., 2., 2., 3., 6., 2., 0., 1., 2., 1., 3., 3., 0., 2., 0., 3., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0. [...]
+
+8., 1., 2., 3., 8., 4., 3., 0., 7., 19., 0., 16., 29., 0., 14., 4., 2., 0., 30., 4., 1., 32., 20., 34., 26., 8., 1., 0., 4., 1., 7., 7., 40., 19., 3., 16., 2., 21., 20., 2., 1., 5., 1., 15., 8., 22., 52., 12., 33., 12., 3., 0., 4., 3., 6., 2., 13., 1., 9., 25., 6., 16., 8., 2., 1., 0., 5., 1., 4., 2., 6., 4., 5., 5., 2., 2., 0., 2., 2., 0., 2., 0., 2., 2., 0., 4., 4., 6., 0., 0., 4., 0., 6., 0., 1., 3., 3., 0., 3., 2., 2., 1., 2., 2., 1., 1., 3., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0., 0 [...]
+
+12., 0., 1., 3., 5., 3., 6., 0., 8., 6., 1., 16., 22., 0., 19., 3., 0., 4., 24., 4., 2., 29., 14., 29., 23., 11., 2., 3., 6., 2., 5., 13., 21., 7., 1., 11., 5., 20., 4., 3., 1., 6., 2., 7., 9., 12., 37., 10., 26., 7., 7., 0., 7., 3., 6., 2., 10., 9., 7., 12., 10., 17., 5., 2., 1., 1., 7., 3., 4., 4., 7., 5., 2., 3., 0., 3., 5., 2., 0., 3., 1., 0., 3., 2., 1., 5., 2., 2., 2., 4., 4., 0., 3., 2., 3., 6., 0., 0., 4., 0., 2., 3., 2., 5., 3., 1., 1., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0. [...]
+
+9., 3., 2., 5., 9., 3., 7., 3., 6., 25., 1., 18., 22., 1., 20., 0., 2., 2., 20., 2., 6., 18., 10., 27., 33., 6., 1., 1., 3., 1., 4., 12., 45., 16., 3., 20., 2., 11., 10., 1., 1., 4., 3., 10., 16., 15., 41., 10., 20., 13., 3., 3., 6., 0., 7., 1., 5., 6., 5., 11., 8., 21., 4., 4., 0., 1., 7., 0., 1., 2., 7., 1., 5., 6., 4., 5., 0., 1., 0., 3., 1., 0., 2., 0., 2., 5., 3., 7., 0., 1., 4., 1., 1., 0., 4., 11., 4., 0., 2., 2., 1., 6., 1., 1., 4., 3., 1., 0., 0., 0., 0., 3., 0., 0., 3., 0., 0., [...]
+
+7., 1., 2., 1., 17., 0., 6., 0., 5., 25., 1., 9., 28., 3., 13., 2., 2., 3., 22., 1., 2., 23., 10., 16., 32., 4., 1., 1., 4., 3., 9., 6., 23., 18., 4., 19., 1., 15., 6., 1., 2., 5., 2., 15., 6., 22., 35., 14., 16., 10., 3., 0., 7., 1., 8., 5., 9., 4., 11., 22., 6., 18., 7., 3., 1., 0., 6., 2., 3., 2., 6., 5., 4., 4., 5., 1., 6., 1., 0., 1., 0., 0., 0., 1., 0., 6., 0., 5., 2., 3., 3., 1., 1., 1., 3., 3., 3., 0., 2., 3., 2., 1., 1., 3., 2., 3., 8., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0. [...]
+
+6., 1., 0., 4., 10., 2., 8., 0., 4., 13., 1., 14., 22., 2., 20., 2., 1., 2., 22., 1., 10., 33., 13., 22., 26., 9., 0., 1., 4., 2., 8., 8., 32., 13., 3., 17., 4., 13., 7., 5., 0., 3., 0., 15., 10., 13., 50., 15., 15., 8., 6., 1., 6., 2., 8., 3., 6., 3., 6., 11., 4., 25., 3., 0., 2., 3., 9., 4., 2., 2., 6., 3., 5., 1., 2., 1., 5., 3., 1., 3., 1., 0., 3., 0., 1., 8., 2., 2., 4., 6., 1., 1., 4., 0., 2., 7., 2., 0., 2., 1., 1., 1., 0., 2., 4., 1., 1., 0., 0., 0., 0., 4., 0., 0., 5., 0., 0., 0 [...]
+
+12., 0., 1., 6., 9., 0., 26., 0., 1., 36., 2., 8., 54., 0., 7., 3., 0., 3., 75., 9., 8., 68., 10., 86., 16., 4., 0., 1., 5., 2., 14., 10., 59., 10., 2., 33., 34., 22., 7., 0., 1., 5., 5., 15., 2., 28., 7., 14., 10., 1., 1., 0., 10., 3., 15., 2., 19., 4., 5., 2., 4., 33., 9., 7., 0., 0., 20., 3., 14., 4., 9., 1., 3., 1., 0., 1., 0., 3., 1., 17., 9., 3., 6., 1., 3., 0., 0., 0., 0., 0., 9., 2., 1., 3., 0., 0., 2., 0., 2., 0., 3., 0., 0., 1., 1., 0., 0., 0., 0., 0., 1., 0., 0., 0., 1., 0., 2 [...]
+
+6., 1., 0., 3., 10., 0., 9., 0., 2., 40., 2., 7., 63., 0., 2., 1., 0., 4., 54., 14., 11., 92., 13., 87., 9., 7., 0., 1., 2., 1., 11., 7., 45., 12., 3., 54., 34., 22., 4., 0., 0., 10., 9., 18., 6., 21., 8., 11., 9., 5., 4., 0., 12., 3., 16., 6., 12., 4., 7., 5., 3., 42., 11., 8., 1., 0., 19., 5., 9., 4., 13., 3., 4., 0., 1., 4., 0., 10., 0., 5., 12., 4., 7., 1., 2., 0., 0., 0., 0., 0., 7., 3., 4., 4., 3., 0., 1., 0., 0., 0., 1., 0., 1., 1., 1., 0., 3., 0., 3., 0., 0., 0., 0., 0., 2., 0.,  [...]
+
+5., 1., 1., 7., 7., 0., 14., 3., 6., 42., 2., 6., 40., 3., 5., 4., 0., 1., 83., 15., 10., 84., 15., 85., 6., 7., 0., 1., 1., 2., 17., 8., 52., 11., 1., 41., 35., 16., 7., 0., 2., 5., 5., 27., 4., 17., 6., 8., 7., 1., 3., 0., 9., 1., 17., 5., 15., 4., 5., 2., 7., 32., 7., 8., 3., 0., 21., 0., 4., 1., 11., 1., 2., 2., 1., 2., 0., 4., 1., 16., 12., 2., 2., 1., 3., 0., 0., 0., 0., 0., 7., 0., 2., 0., 1., 1., 0., 0., 1., 0., 0., 0., 2., 3., 1., 0., 1., 0., 2., 0., 1., 0., 0., 0., 0., 0., 0.,  [...]
+
+13., 1., 0., 4., 9., 0., 14., 4., 9., 46., 1., 12., 59., 0., 8., 0., 0., 6., 52., 9., 10., 60., 22., 75., 15., 4., 0., 2., 2., 2., 16., 6., 55., 14., 2., 40., 29., 15., 7., 0., 0., 6., 2., 21., 6., 29., 7., 13., 3., 2., 0., 0., 13., 3., 25., 9., 10., 2., 9., 3., 2., 35., 10., 6., 1., 0., 11., 3., 8., 0., 16., 2., 2., 1., 0., 0., 0., 4., 3., 20., 8., 0., 7., 0., 3., 0., 0., 0., 0., 0., 7., 1., 6., 4., 3., 1., 2., 0., 0., 0., 1., 0., 0., 2., 4., 0., 3., 0., 2., 0., 3., 0., 0., 0., 1., 0.,  [...]
+
+13., 1., 0., 4., 12., 0., 9., 1., 2., 60., 0., 7., 70., 2., 7., 1., 0., 2., 64., 8., 8., 64., 10., 70., 9., 3., 0., 1., 3., 3., 11., 9., 36., 17., 2., 37., 30., 12., 8., 0., 3., 7., 2., 24., 7., 19., 8., 13., 10., 2., 1., 0., 5., 2., 14., 7., 28., 1., 10., 3., 3., 43., 11., 10., 0., 0., 14., 5., 8., 0., 11., 1., 2., 2., 1., 2., 0., 4., 2., 11., 12., 2., 2., 1., 6., 0., 0., 0., 0., 0., 13., 2., 2., 3., 4., 1., 4., 0., 1., 0., 0., 0., 0., 2., 3., 0., 0., 0., 1., 0., 1., 0., 0., 0., 1., 0., [...]
+
+6., 0., 3., 4., 9., 0., 12., 0., 11., 53., 1., 7., 55., 3., 9., 5., 0., 3., 86., 7., 9., 63., 8., 87., 12., 6., 0., 1., 1., 4., 13., 9., 38., 13., 3., 39., 34., 13., 6., 0., 0., 6., 2., 19., 3., 34., 6., 17., 3., 2., 0., 0., 13., 3., 15., 5., 20., 3., 10., 3., 3., 25., 11., 6., 1., 0., 6., 3., 9., 5., 10., 3., 5., 1., 3., 0., 0., 5., 1., 15., 11., 3., 3., 0., 1., 0., 0., 0., 0., 0., 10., 2., 1., 2., 4., 0., 1., 0., 1., 0., 1., 0., 1., 6., 1., 0., 0., 0., 0., 0., 3., 0., 0., 0., 0., 0., 2 [...]
+
+8., 0., 3., 3., 12., 0., 18., 3., 11., 50., 1., 8., 33., 1., 2., 0., 0., 2., 77., 11., 10., 80., 16., 98., 22., 2., 0., 2., 3., 0., 8., 8., 49., 12., 0., 46., 25., 10., 5., 0., 4., 8., 2., 31., 7., 22., 12., 12., 6., 2., 2., 0., 11., 3., 17., 4., 15., 1., 9., 3., 4., 39., 6., 8., 2., 0., 11., 3., 11., 4., 11., 0., 2., 1., 0., 0., 0., 4., 0., 20., 5., 2., 5., 2., 1., 0., 0., 0., 0., 0., 9., 3., 3., 3., 1., 1., 2., 0., 0., 0., 2., 0., 1., 2., 2., 0., 1., 0., 1., 0., 2., 0., 0., 0., 0., 0., [...]
+
+9., 3., 3., 5., 8., 0., 14., 1., 7., 52., 0., 9., 62., 2., 3., 1., 0., 2., 57., 8., 7., 74., 11., 80., 8., 4., 0., 1., 2., 0., 8., 11., 59., 12., 0., 39., 29., 19., 7., 0., 0., 6., 5., 32., 7., 26., 8., 9., 7., 8., 1., 0., 11., 5., 13., 5., 14., 3., 7., 3., 7., 33., 7., 8., 1., 0., 10., 4., 4., 1., 15., 2., 3., 1., 0., 0., 0., 4., 3., 19., 9., 4., 4., 1., 4., 0., 0., 0., 0., 0., 12., 1., 5., 3., 1., 1., 0., 0., 2., 0., 1., 0., 0., 6., 3., 0., 2., 0., 1., 0., 1., 0., 0., 0., 2., 0., 2., 2 [...]
+
+10., 2., 0., 4., 18., 0., 20., 2., 6., 40., 4., 13., 58., 0., 3., 2., 0., 2., 58., 7., 8., 86., 18., 90., 9., 1., 0., 1., 6., 2., 13., 16., 48., 10., 1., 35., 27., 16., 4., 0., 1., 4., 3., 21., 5., 26., 5., 18., 6., 4., 3., 0., 13., 1., 21., 5., 15., 0., 8., 6., 1., 38., 8., 3., 3., 0., 12., 1., 7., 1., 8., 3., 7., 0., 2., 1., 0., 6., 1., 15., 7., 2., 5., 3., 1., 0., 0., 0., 0., 0., 11., 3., 1., 0., 2., 0., 0., 0., 0., 0., 0., 0., 2., 4., 3., 0., 0., 0., 2., 0., 0., 0., 0., 0., 1., 0., 1 [...]
+
+8., 2., 3., 1., 6., 0., 19., 1., 2., 47., 2., 6., 55., 0., 9., 5., 0., 3., 64., 11., 10., 85., 15., 95., 16., 2., 0., 0., 6., 2., 19., 9., 55., 9., 4., 47., 27., 16., 4., 0., 1., 9., 1., 24., 3., 27., 5., 12., 12., 4., 1., 0., 10., 3., 14., 4., 21., 2., 8., 2., 3., 23., 11., 9., 5., 0., 18., 3., 8., 3., 5., 2., 3., 1., 1., 1., 0., 2., 2., 17., 8., 6., 7., 4., 3., 0., 0., 0., 0., 0., 14., 0., 6., 0., 7., 1., 0., 0., 0., 0., 0., 0., 0., 8., 2., 0., 0., 0., 1., 0., 2., 0., 0., 0., 0., 0., 4 [...]
+
+10., 0., 1., 4., 13., 0., 8., 0., 9., 50., 1., 7., 53., 0., 4., 1., 0., 0., 76., 7., 6., 75., 17., 94., 13., 3., 0., 2., 0., 1., 16., 8., 48., 11., 2., 42., 41., 15., 5., 0., 0., 2., 3., 29., 7., 37., 13., 15., 7., 3., 1., 0., 6., 5., 8., 6., 19., 1., 16., 3., 2., 35., 12., 7., 1., 0., 13., 2., 7., 2., 12., 2., 4., 0., 2., 0., 0., 5., 2., 9., 6., 10., 6., 0., 4., 0., 0., 0., 0., 0., 6., 2., 5., 0., 1., 1., 1., 0., 2., 0., 0., 0., 1., 0., 4., 0., 0., 0., 1., 0., 1., 0., 0., 0., 0., 0., 2. [...]
+
+12., 0., 2., 4., 16., 0., 15., 0., 5., 63., 2., 3., 63., 1., 5., 2., 0., 2., 76., 9., 8., 63., 14., 73., 15., 2., 0., 2., 4., 0., 13., 7., 49., 13., 2., 31., 43., 10., 3., 0., 0., 5., 0., 26., 8., 27., 2., 13., 7., 4., 0., 0., 11., 1., 16., 4., 9., 3., 12., 6., 2., 38., 8., 5., 2., 0., 13., 1., 9., 2., 12., 4., 3., 2., 0., 1., 0., 7., 2., 17., 11., 5., 1., 0., 2., 0., 0., 0., 0., 0., 11., 1., 3., 3., 3., 0., 3., 0., 1., 0., 0., 0., 2., 6., 5., 0., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0.,  [...]
+
+11., 2., 2., 2., 6., 0., 12., 3., 7., 55., 0., 10., 64., 1., 2., 2., 0., 3., 59., 9., 12., 68., 16., 72., 6., 2., 0., 0., 0., 1., 14., 16., 54., 8., 1., 45., 38., 16., 6., 0., 2., 6., 1., 29., 10., 26., 5., 17., 12., 5., 4., 0., 7., 4., 13., 5., 17., 5., 7., 4., 2., 34., 8., 7., 3., 0., 12., 2., 11., 2., 13., 2., 5., 3., 1., 2., 0., 1., 2., 14., 7., 2., 6., 2., 3., 0., 0., 0., 0., 0., 9., 2., 6., 2., 2., 1., 0., 0., 3., 0., 2., 0., 0., 3., 3., 0., 3., 0., 1., 0., 1., 0., 0., 0., 2., 0.,  [...]
+
+7., 3., 1., 3., 15., 0., 16., 0., 11., 70., 1., 6., 88., 0., 4., 2., 0., 1., 65., 13., 3., 68., 19., 75., 19., 6., 0., 1., 5., 2., 21., 8., 63., 15., 1., 33., 26., 24., 8., 0., 1., 4., 2., 18., 3., 16., 12., 10., 4., 1., 2., 0., 9., 4., 12., 5., 14., 4., 13., 6., 3., 30., 4., 10., 5., 0., 11., 0., 5., 0., 6., 3., 3., 2., 1., 1., 0., 5., 2., 20., 14., 4., 9., 0., 5., 0., 0., 0., 0., 0., 10., 2., 2., 4., 2., 0., 0., 0., 1., 0., 2., 0., 1., 3., 0., 0., 4., 0., 0., 0., 1., 0., 0., 0., 1., 0. [...]
+
+6., 1., 0., 5., 12., 0., 12., 0., 6., 56., 0., 11., 70., 1., 5., 1., 0., 1., 82., 4., 10., 64., 12., 94., 14., 2., 0., 0., 1., 3., 12., 6., 67., 18., 2., 47., 33., 14., 8., 0., 2., 8., 5., 15., 5., 22., 4., 13., 8., 3., 2., 0., 13., 4., 21., 3., 17., 1., 4., 5., 0., 43., 13., 6., 1., 0., 14., 1., 5., 2., 12., 0., 11., 1., 1., 4., 0., 4., 1., 18., 7., 6., 5., 1., 2., 0., 0., 0., 0., 0., 11., 1., 3., 2., 2., 1., 2., 0., 3., 0., 0., 0., 0., 3., 0., 0., 3., 0., 1., 0., 2., 0., 0., 0., 1., 0. [...]
+
+9., 3., 2., 4., 9., 3., 11., 2., 6., 11., 4., 15., 25., 2., 11., 3., 0., 0., 16., 3., 6., 19., 16., 23., 26., 6., 1., 1., 7., 0., 8., 6., 41., 21., 3., 16., 2., 9., 12., 3., 1., 3., 4., 14., 12., 13., 56., 13., 16., 10., 6., 0., 2., 2., 6., 0., 16., 4., 3., 12., 10., 24., 11., 4., 0., 3., 7., 1., 1., 3., 9., 1., 4., 3., 2., 1., 4., 3., 2., 5., 2., 0., 1., 1., 3., 6., 3., 2., 1., 2., 8., 2., 4., 0., 2., 11., 0., 0., 2., 5., 5., 1., 1., 2., 0., 0., 2., 0., 0., 0., 0., 0., 0., 0., 5., 0., 0 [...]
+
+7., 0., 2., 9., 8., 4., 10., 3., 9., 24., 0., 12., 26., 0., 20., 3., 1., 1., 13., 1., 5., 22., 13., 31., 27., 4., 0., 1., 3., 3., 10., 11., 25., 15., 6., 15., 1., 13., 9., 2., 2., 3., 1., 12., 12., 17., 41., 6., 16., 11., 4., 0., 4., 2., 4., 2., 4., 7., 9., 9., 5., 27., 11., 0., 1., 2., 6., 1., 3., 2., 10., 6., 1., 2., 1., 6., 3., 2., 0., 2., 1., 0., 3., 2., 1., 4., 4., 5., 2., 2., 4., 1., 1., 0., 3., 6., 3., 0., 2., 3., 1., 5., 2., 5., 0., 0., 2., 0., 0., 0., 0., 5., 0., 0., 5., 0., 0., [...]
+
+10., 2., 2., 4., 11., 0., 4., 0., 9., 23., 1., 10., 26., 1., 10., 5., 1., 4., 19., 2., 2., 14., 12., 31., 32., 5., 0., 0., 1., 0., 6., 2., 22., 20., 3., 23., 4., 16., 10., 1., 1., 7., 4., 7., 6., 22., 52., 9., 19., 5., 4., 0., 9., 1., 6., 1., 8., 8., 7., 14., 5., 21., 12., 1., 3., 0., 6., 3., 0., 3., 3., 1., 5., 4., 3., 10., 2., 2., 0., 3., 1., 0., 3., 2., 1., 5., 5., 4., 3., 2., 2., 1., 2., 0., 3., 6., 2., 0., 3., 2., 3., 1., 1., 3., 2., 0., 1., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0 [...]
+
+10., 0., 2., 5., 12., 3., 4., 1., 6., 17., 1., 17., 21., 1., 12., 5., 1., 3., 26., 1., 3., 17., 14., 22., 24., 7., 0., 0., 4., 1., 3., 9., 19., 10., 2., 17., 6., 15., 13., 2., 0., 3., 4., 13., 6., 18., 59., 14., 20., 14., 1., 0., 6., 4., 10., 2., 8., 7., 6., 25., 3., 25., 3., 3., 1., 3., 6., 2., 4., 0., 4., 2., 5., 4., 2., 3., 3., 3., 0., 4., 0., 0., 2., 3., 2., 4., 2., 5., 1., 0., 6., 0., 3., 2., 1., 9., 1., 0., 0., 0., 6., 0., 2., 3., 3., 0., 0., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., [...]
+
+7., 1., 3., 1., 9., 1., 7., 1., 10., 24., 3., 13., 24., 0., 9., 3., 1., 0., 18., 2., 2., 22., 10., 16., 24., 8., 0., 0., 3., 4., 5., 8., 23., 20., 1., 9., 5., 16., 7., 2., 1., 4., 2., 10., 10., 12., 46., 14., 21., 1., 2., 1., 5., 5., 6., 1., 9., 7., 6., 14., 3., 17., 11., 3., 0., 1., 6., 1., 3., 3., 5., 3., 4., 2., 2., 4., 2., 1., 0., 1., 1., 0., 3., 1., 0., 6., 0., 4., 2., 1., 4., 2., 1., 1., 2., 10., 1., 0., 3., 2., 2., 2., 1., 4., 0., 0., 2., 0., 0., 0., 0., 0., 0., 0., 5., 0., 0., 0. [...]
+
+12., 1., 3., 4., 10., 1., 6., 1., 3., 21., 0., 13., 35., 4., 11., 0., 2., 4., 19., 2., 3., 28., 13., 19., 17., 6., 1., 0., 1., 3., 8., 2., 24., 14., 2., 18., 4., 10., 8., 2., 0., 5., 1., 16., 19., 21., 50., 11., 22., 5., 6., 2., 10., 2., 3., 4., 6., 8., 5., 12., 6., 21., 9., 4., 2., 0., 6., 2., 2., 2., 6., 3., 4., 5., 2., 2., 2., 1., 1., 1., 0., 0., 2., 3., 4., 8., 1., 3., 0., 2., 4., 1., 7., 2., 1., 8., 1., 0., 4., 2., 1., 2., 4., 4., 2., 0., 2., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0.,  [...]
+
+8., 2., 2., 4., 10., 3., 4., 0., 6., 25., 0., 13., 20., 1., 11., 3., 0., 1., 12., 1., 2., 13., 8., 30., 26., 8., 1., 0., 1., 3., 6., 9., 27., 16., 5., 16., 6., 15., 6., 3., 0., 3., 2., 19., 4., 19., 56., 6., 15., 13., 6., 4., 7., 3., 11., 5., 17., 8., 6., 13., 10., 12., 5., 2., 0., 2., 7., 1., 1., 6., 2., 2., 4., 5., 2., 6., 3., 1., 2., 2., 2., 0., 4., 3., 3., 8., 3., 5., 3., 1., 7., 2., 1., 0., 2., 6., 2., 0., 3., 1., 3., 1., 2., 4., 2., 2., 1., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0 [...]
+
+3., 0., 1., 4., 11., 3., 5., 3., 6., 11., 1., 19., 19., 0., 12., 5., 1., 0., 24., 0., 8., 36., 8., 18., 24., 4., 0., 0., 4., 3., 4., 6., 20., 20., 6., 11., 5., 20., 8., 2., 1., 4., 1., 10., 10., 18., 54., 15., 16., 7., 4., 1., 5., 2., 5., 3., 10., 7., 7., 24., 4., 21., 13., 2., 1., 0., 6., 1., 0., 4., 5., 3., 7., 1., 1., 5., 2., 1., 1., 1., 4., 0., 1., 0., 2., 2., 6., 1., 2., 1., 6., 2., 1., 1., 2., 4., 1., 0., 1., 2., 3., 1., 1., 0., 3., 0., 1., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0 [...]
+
+12., 0., 0., 2., 10., 2., 6., 1., 7., 27., 2., 9., 18., 0., 21., 5., 1., 4., 18., 1., 3., 18., 9., 18., 22., 7., 1., 0., 4., 1., 8., 3., 34., 14., 4., 18., 5., 16., 7., 0., 0., 8., 3., 15., 14., 17., 44., 9., 23., 3., 2., 0., 0., 3., 10., 2., 15., 9., 8., 15., 4., 16., 12., 5., 1., 1., 10., 1., 2., 2., 9., 8., 4., 3., 3., 7., 4., 2., 2., 3., 2., 0., 2., 1., 3., 3., 3., 4., 4., 2., 2., 0., 2., 0., 2., 6., 5., 0., 2., 3., 2., 4., 3., 1., 2., 1., 1., 0., 0., 0., 0., 2., 0., 0., 7., 0., 0.,  [...]
+
+6., 3., 4., 5., 7., 2., 10., 1., 5., 23., 1., 17., 27., 1., 9., 1., 3., 3., 14., 1., 3., 16., 11., 25., 28., 1., 1., 0., 2., 2., 13., 14., 30., 14., 7., 18., 4., 12., 10., 2., 0., 5., 1., 8., 14., 15., 52., 17., 28., 9., 5., 0., 7., 2., 7., 6., 6., 2., 5., 12., 7., 15., 3., 2., 1., 0., 5., 2., 3., 4., 4., 4., 7., 4., 1., 1., 3., 2., 0., 3., 4., 0., 2., 0., 1., 2., 5., 4., 3., 4., 5., 2., 0., 1., 1., 6., 4., 0., 4., 3., 2., 3., 3., 0., 2., 1., 4., 0., 0., 0., 0., 0., 0., 0., 3., 0., 0., 0 [...]
+
+8., 2., 0., 6., 9., 1., 8., 0., 3., 19., 0., 11., 30., 1., 9., 5., 0., 2., 8., 0., 2., 32., 11., 24., 26., 4., 1., 2., 3., 3., 12., 9., 35., 17., 4., 21., 2., 20., 5., 2., 3., 4., 2., 15., 13., 13., 43., 15., 26., 11., 3., 0., 8., 2., 1., 4., 12., 8., 5., 23., 10., 28., 8., 3., 0., 0., 10., 0., 0., 2., 2., 1., 2., 1., 1., 3., 3., 3., 2., 1., 4., 0., 0., 1., 1., 5., 2., 7., 3., 2., 3., 0., 2., 1., 4., 6., 1., 0., 2., 1., 4., 4., 0., 2., 1., 1., 2., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0.,  [...]
+
+6., 2., 5., 5., 5., 2., 6., 0., 10., 20., 0., 11., 18., 2., 18., 3., 0., 0., 11., 1., 4., 42., 8., 20., 24., 8., 0., 1., 4., 4., 5., 8., 12., 18., 2., 12., 4., 13., 8., 3., 0., 3., 3., 13., 17., 18., 39., 13., 19., 11., 6., 1., 6., 2., 11., 2., 13., 1., 7., 27., 4., 26., 8., 2., 2., 2., 6., 1., 5., 2., 2., 4., 3., 4., 2., 4., 2., 5., 2., 4., 3., 0., 1., 1., 1., 9., 3., 2., 1., 3., 1., 0., 1., 3., 4., 6., 5., 0., 3., 2., 2., 4., 2., 1., 3., 0., 3., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0.,  [...]
+
+6., 0., 4., 2., 9., 2., 6., 0., 10., 27., 4., 15., 32., 1., 16., 3., 1., 2., 11., 1., 1., 27., 7., 22., 34., 5., 3., 0., 5., 0., 10., 4., 25., 17., 3., 18., 9., 13., 12., 0., 1., 4., 0., 15., 13., 11., 55., 12., 15., 12., 2., 1., 2., 2., 9., 3., 8., 5., 7., 22., 4., 28., 9., 3., 0., 0., 10., 3., 4., 4., 4., 4., 4., 3., 1., 7., 6., 4., 1., 3., 2., 0., 2., 4., 0., 10., 2., 8., 1., 1., 5., 0., 2., 2., 2., 14., 2., 0., 1., 2., 4., 2., 1., 2., 2., 1., 2., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0 [...]
+
+13., 0., 1., 11., 5., 2., 3., 0., 7., 25., 1., 12., 21., 0., 20., 2., 1., 1., 14., 1., 6., 20., 11., 27., 19., 9., 2., 1., 2., 4., 5., 3., 26., 18., 3., 12., 5., 19., 8., 3., 1., 10., 0., 14., 9., 17., 45., 9., 20., 14., 1., 1., 3., 2., 2., 3., 10., 1., 7., 9., 5., 24., 10., 3., 3., 3., 12., 2., 2., 1., 5., 6., 3., 1., 1., 4., 2., 5., 1., 1., 2., 0., 0., 3., 1., 4., 3., 3., 1., 0., 4., 0., 1., 1., 1., 10., 0., 0., 4., 4., 1., 2., 1., 4., 0., 1., 5., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0. [...]
+
+11., 1., 5., 6., 8., 5., 9., 1., 7., 22., 0., 9., 19., 1., 19., 4., 1., 2., 17., 2., 7., 31., 11., 11., 29., 3., 4., 0., 1., 2., 7., 0., 22., 22., 1., 13., 4., 14., 6., 1., 2., 2., 2., 7., 12., 23., 36., 11., 25., 9., 5., 2., 1., 1., 2., 3., 11., 4., 3., 13., 5., 19., 4., 1., 1., 1., 3., 1., 2., 1., 8., 4., 3., 4., 2., 3., 1., 1., 0., 2., 0., 0., 1., 1., 3., 6., 4., 2., 1., 1., 4., 0., 2., 0., 1., 6., 3., 0., 4., 1., 0., 1., 2., 4., 1., 0., 2., 0., 0., 0., 0., 0., 0., 0., 4., 0., 0., 0., [...]
+
+11., 0., 4., 3., 12., 0., 18., 2., 13., 39., 0., 5., 67., 0., 6., 2., 0., 3., 68., 6., 15., 79., 8., 77., 16., 4., 0., 2., 4., 2., 13., 12., 50., 13., 0., 43., 37., 10., 4., 0., 1., 6., 3., 22., 8., 23., 6., 7., 8., 1., 2., 0., 5., 4., 19., 7., 18., 2., 9., 3., 3., 39., 5., 7., 2., 0., 17., 2., 4., 3., 17., 2., 5., 0., 0., 2., 0., 5., 2., 13., 11., 4., 8., 0., 2., 0., 0., 0., 0., 0., 9., 0., 1., 2., 2., 1., 1., 0., 0., 0., 0., 0., 1., 3., 1., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 3 [...]
+
+8., 2., 1., 2., 11., 0., 16., 1., 9., 49., 0., 13., 57., 1., 6., 3., 0., 3., 73., 7., 3., 95., 10., 68., 7., 6., 0., 1., 4., 2., 14., 9., 47., 9., 1., 51., 42., 15., 4., 0., 1., 11., 4., 18., 6., 23., 4., 10., 3., 2., 3., 0., 5., 4., 19., 4., 14., 0., 7., 0., 3., 31., 7., 6., 2., 0., 10., 1., 10., 4., 11., 2., 3., 1., 3., 5., 0., 7., 2., 20., 7., 4., 7., 3., 2., 0., 0., 0., 0., 0., 9., 0., 3., 6., 3., 0., 0., 0., 0., 0., 0., 0., 0., 6., 4., 0., 1., 0., 4., 0., 2., 0., 0., 0., 3., 0., 4., [...]
+
+8., 1., 1., 5., 12., 0., 14., 2., 6., 55., 1., 12., 55., 2., 9., 0., 0., 0., 48., 9., 7., 71., 15., 94., 10., 0., 0., 2., 3., 1., 10., 9., 41., 18., 3., 45., 28., 9., 4., 0., 0., 5., 6., 16., 7., 22., 10., 12., 2., 0., 3., 0., 6., 6., 17., 4., 12., 3., 9., 3., 5., 41., 7., 9., 3., 0., 16., 1., 7., 2., 8., 0., 5., 2., 0., 0., 0., 7., 0., 13., 6., 5., 5., 1., 1., 0., 0., 0., 0., 0., 8., 1., 2., 2., 3., 2., 2., 0., 1., 0., 2., 0., 1., 1., 2., 0., 3., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.,  [...]
+
+10., 2., 1., 3., 12., 0., 17., 2., 7., 44., 2., 9., 54., 1., 6., 1., 0., 0., 65., 5., 6., 87., 16., 95., 12., 2., 0., 2., 1., 2., 19., 10., 51., 15., 1., 45., 27., 9., 5., 0., 1., 5., 2., 18., 5., 27., 9., 17., 7., 0., 4., 0., 13., 4., 12., 4., 16., 3., 8., 2., 1., 43., 11., 3., 3., 0., 20., 6., 9., 2., 11., 1., 5., 3., 2., 0., 0., 2., 2., 26., 10., 4., 7., 0., 3., 0., 0., 0., 0., 0., 8., 1., 3., 2., 1., 2., 1., 0., 3., 0., 0., 0., 0., 1., 1., 0., 1., 0., 1., 0., 2., 0., 0., 0., 2., 0.,  [...]
+
+13., 1., 2., 2., 8., 0., 15., 2., 11., 50., 2., 16., 52., 1., 7., 3., 0., 4., 55., 12., 4., 55., 18., 85., 12., 5., 0., 1., 1., 1., 19., 4., 46., 11., 0., 44., 34., 18., 4., 0., 3., 4., 2., 29., 9., 35., 12., 18., 5., 4., 4., 0., 9., 3., 22., 4., 16., 2., 8., 4., 2., 37., 12., 3., 1., 0., 9., 3., 4., 2., 15., 0., 6., 0., 2., 1., 0., 6., 2., 19., 10., 2., 0., 2., 2., 0., 0., 0., 0., 0., 6., 3., 3., 3., 3., 1., 2., 0., 0., 0., 3., 0., 0., 4., 2., 0., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., [...]
+
+5., 1., 1., 3., 15., 0., 11., 4., 5., 53., 2., 3., 64., 1., 6., 1., 0., 0., 70., 14., 6., 91., 8., 76., 11., 10., 0., 0., 4., 0., 14., 6., 35., 14., 1., 38., 38., 21., 4., 0., 0., 3., 4., 25., 8., 18., 7., 14., 5., 4., 3., 0., 9., 5., 16., 3., 19., 4., 8., 8., 4., 43., 9., 9., 2., 0., 15., 8., 8., 3., 10., 1., 4., 3., 0., 2., 0., 2., 3., 13., 12., 4., 6., 0., 1., 0., 0., 0., 0., 0., 8., 2., 1., 1., 4., 2., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 5., 0., 1., 0., 0., 0., 0., 0., 0., 0., 4. [...]
+
+10., 0., 2., 5., 9., 0., 16., 0., 7., 53., 0., 6., 65., 0., 5., 3., 0., 2., 72., 8., 8., 79., 13., 88., 15., 4., 0., 0., 1., 2., 14., 11., 59., 17., 1., 45., 30., 11., 6., 0., 0., 7., 4., 38., 7., 26., 4., 9., 11., 3., 2., 0., 15., 2., 18., 6., 19., 2., 9., 2., 0., 30., 14., 4., 1., 0., 15., 3., 7., 2., 9., 1., 7., 1., 2., 0., 0., 4., 4., 17., 5., 4., 4., 0., 1., 0., 0., 0., 0., 0., 9., 4., 2., 0., 6., 0., 0., 0., 0., 0., 2., 0., 2., 4., 2., 0., 1., 0., 0., 0., 0., 0., 0., 0., 1., 0., 1. [...]
+
+4., 0., 1., 3., 8., 0., 21., 0., 7., 54., 0., 5., 56., 2., 5., 4., 0., 1., 61., 14., 9., 71., 16., 95., 12., 4., 0., 1., 1., 1., 15., 9., 36., 10., 2., 39., 23., 20., 6., 0., 1., 8., 1., 22., 6., 20., 4., 17., 4., 1., 3., 0., 11., 2., 11., 3., 14., 3., 5., 5., 4., 35., 9., 6., 3., 0., 23., 4., 7., 1., 10., 2., 4., 2., 4., 2., 0., 2., 3., 11., 9., 1., 3., 1., 6., 0., 0., 0., 0., 0., 13., 1., 4., 5., 2., 1., 2., 0., 1., 0., 2., 0., 2., 0., 2., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1. [...]
+
+9., 0., 0., 5., 10., 0., 15., 1., 9., 52., 2., 3., 40., 1., 2., 3., 0., 2., 85., 12., 9., 75., 13., 68., 12., 3., 0., 1., 3., 3., 21., 5., 40., 13., 3., 34., 31., 17., 6., 0., 0., 5., 4., 25., 4., 24., 10., 17., 6., 2., 2., 0., 13., 7., 9., 5., 14., 4., 8., 0., 3., 29., 7., 7., 0., 0., 20., 3., 10., 2., 18., 2., 3., 2., 2., 1., 0., 6., 1., 17., 8., 5., 5., 0., 2., 0., 0., 0., 0., 0., 11., 2., 5., 3., 1., 0., 1., 0., 2., 0., 0., 0., 0., 2., 3., 0., 1., 0., 3., 0., 2., 0., 0., 0., 0., 0.,  [...]
+
+4., 0., 4., 6., 17., 0., 9., 6., 12., 28., 0., 10., 52., 2., 3., 1., 0., 2., 70., 8., 5., 70., 12., 95., 15., 5., 0., 0., 5., 3., 9., 11., 42., 12., 0., 45., 37., 13., 4., 0., 0., 9., 0., 25., 2., 26., 8., 11., 2., 6., 1., 0., 11., 4., 17., 4., 10., 1., 6., 4., 4., 36., 10., 9., 1., 0., 20., 2., 6., 1., 15., 2., 1., 0., 0., 3., 0., 8., 0., 14., 7., 3., 3., 1., 3., 0., 0., 0., 0., 0., 8., 5., 3., 1., 4., 0., 0., 0., 0., 0., 0., 0., 3., 0., 5., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 3 [...]
+
+8., 1., 1., 3., 9., 0., 12., 2., 5., 43., 1., 6., 54., 2., 7., 2., 0., 0., 68., 6., 13., 87., 17., 72., 19., 3., 0., 1., 3., 2., 12., 5., 71., 12., 1., 34., 36., 21., 4., 0., 1., 9., 3., 20., 6., 25., 8., 16., 8., 4., 3., 0., 10., 7., 14., 5., 6., 2., 7., 5., 2., 34., 3., 12., 0., 0., 10., 3., 7., 5., 14., 3., 7., 2., 2., 0., 0., 7., 0., 21., 8., 1., 5., 0., 4., 0., 0., 0., 0., 0., 8., 4., 7., 2., 2., 0., 2., 0., 1., 0., 0., 0., 1., 6., 1., 0., 3., 0., 1., 0., 1., 0., 0., 0., 4., 0., 1., [...]
+
+9., 1., 3., 1., 6., 0., 25., 0., 17., 46., 0., 2., 66., 1., 5., 3., 0., 1., 62., 7., 5., 75., 14., 62., 12., 2., 0., 2., 6., 2., 9., 10., 49., 11., 1., 42., 31., 14., 3., 0., 0., 8., 2., 21., 5., 26., 8., 8., 9., 4., 0., 0., 10., 3., 15., 8., 13., 1., 8., 5., 4., 44., 4., 5., 2., 0., 14., 3., 8., 2., 16., 5., 3., 1., 4., 2., 0., 4., 1., 22., 6., 2., 3., 2., 3., 0., 0., 0., 0., 0., 6., 4., 2., 3., 1., 1., 0., 0., 1., 0., 2., 0., 1., 5., 0., 0., 2., 0., 3., 0., 2., 0., 0., 0., 2., 0., 1.,  [...]
+
+20., 0., 5., 7., 11., 0., 18., 2., 9., 64., 3., 5., 61., 3., 6., 5., 0., 0., 45., 8., 6., 90., 20., 72., 16., 5., 0., 0., 1., 0., 18., 18., 52., 11., 1., 41., 28., 18., 3., 0., 3., 4., 3., 20., 8., 25., 6., 14., 10., 5., 3., 0., 5., 2., 15., 7., 16., 3., 10., 1., 1., 44., 10., 9., 1., 0., 16., 4., 11., 3., 10., 0., 5., 1., 2., 0., 0., 5., 2., 15., 7., 4., 7., 1., 2., 0., 0., 0., 0., 0., 10., 1., 1., 4., 5., 0., 0., 0., 3., 0., 2., 0., 3., 3., 2., 0., 0., 0., 2., 0., 0., 0., 0., 0., 0., 0 [...]
+
+9., 2., 1., 4., 10., 0., 13., 4., 5., 53., 1., 8., 64., 0., 3., 1., 0., 5., 80., 17., 7., 65., 13., 81., 10., 5., 0., 1., 2., 0., 20., 10., 51., 12., 4., 26., 23., 11., 3., 0., 0., 3., 1., 31., 7., 26., 3., 13., 3., 1., 3., 0., 13., 0., 15., 6., 15., 1., 8., 5., 5., 28., 13., 6., 2., 0., 18., 0., 5., 4., 9., 4., 6., 0., 1., 0., 0., 7., 2., 13., 9., 5., 6., 0., 3., 0., 0., 0., 0., 0., 6., 1., 1., 1., 3., 3., 1., 0., 0., 0., 3., 0., 4., 3., 2., 0., 2., 0., 1., 0., 0., 0., 0., 0., 2., 0., 1 [...]
+
+10., 0., 2., 4., 9., 0., 11., 1., 7., 42., 0., 8., 58., 1., 4., 4., 0., 1., 70., 13., 10., 71., 17., 84., 10., 4., 0., 0., 3., 4., 18., 10., 51., 4., 0., 42., 28., 21., 2., 0., 1., 4., 2., 17., 3., 31., 7., 12., 3., 3., 0., 0., 10., 5., 19., 6., 15., 5., 10., 4., 4., 39., 8., 9., 0., 0., 14., 3., 10., 3., 9., 3., 6., 1., 0., 1., 0., 5., 4., 16., 8., 3., 4., 1., 4., 0., 0., 0., 0., 0., 8., 5., 3., 0., 3., 1., 1., 0., 0., 0., 2., 0., 0., 0., 2., 0., 5., 0., 3., 0., 1., 0., 0., 0., 0., 0.,  [...]
+
+5., 1., 1., 6., 9., 0., 17., 2., 9., 48., 1., 5., 50., 0., 7., 0., 0., 0., 73., 15., 12., 71., 22., 74., 11., 4., 0., 1., 2., 1., 17., 4., 48., 15., 1., 40., 39., 15., 8., 0., 0., 7., 1., 20., 6., 30., 5., 22., 6., 1., 4., 0., 5., 3., 20., 3., 16., 4., 5., 1., 1., 33., 8., 5., 3., 0., 10., 4., 9., 5., 7., 1., 4., 0., 0., 1., 0., 6., 3., 13., 5., 1., 3., 1., 1., 0., 0., 0., 0., 0., 14., 1., 2., 2., 1., 2., 0., 0., 1., 0., 1., 0., 2., 2., 2., 0., 4., 0., 2., 0., 3., 0., 0., 0., 0., 0., 1., [...]
+
+6., 1., 1., 4., 11., 0., 15., 1., 4., 63., 1., 3., 65., 0., 6., 2., 0., 1., 62., 7., 9., 65., 12., 75., 11., 2., 0., 1., 0., 1., 10., 8., 56., 11., 2., 49., 32., 22., 6., 0., 1., 7., 2., 23., 9., 32., 6., 10., 3., 2., 4., 0., 15., 3., 20., 3., 17., 2., 4., 4., 4., 30., 4., 6., 3., 0., 15., 2., 9., 2., 14., 5., 5., 0., 2., 2., 0., 6., 1., 16., 9., 2., 3., 1., 0., 0., 0., 0., 0., 0., 3., 2., 6., 1., 2., 2., 1., 0., 1., 0., 2., 0., 0., 3., 1., 0., 2., 0., 1., 0., 4., 0., 0., 0., 0., 0., 2., [...]
+
+7., 1., 4., 3., 4., 1., 3., 0., 5., 35., 2., 8., 21., 1., 10., 3., 0., 3., 13., 3., 2., 19., 11., 23., 36., 2., 0., 0., 2., 1., 10., 5., 22., 13., 4., 19., 2., 19., 17., 2., 1., 3., 3., 15., 13., 21., 36., 10., 18., 10., 3., 1., 6., 3., 6., 2., 5., 6., 10., 11., 5., 27., 3., 3., 1., 1., 8., 0., 3., 2., 3., 2., 4., 5., 1., 7., 1., 0., 1., 2., 1., 0., 1., 4., 3., 7., 3., 3., 3., 3., 2., 0., 2., 1., 3., 8., 3., 0., 2., 4., 3., 1., 2., 3., 2., 1., 0., 0., 0., 0., 0., 4., 0., 0., 2., 0., 0.,  [...]
+
+7., 0., 1., 2., 9., 2., 5., 1., 8., 24., 1., 14., 27., 0., 9., 4., 0., 3., 24., 3., 2., 21., 5., 23., 21., 10., 3., 3., 2., 1., 8., 12., 31., 16., 3., 17., 3., 13., 16., 4., 1., 3., 3., 6., 10., 20., 38., 9., 21., 14., 4., 1., 7., 2., 5., 2., 8., 6., 13., 12., 6., 26., 8., 3., 2., 0., 5., 0., 4., 3., 5., 4., 4., 5., 3., 4., 3., 0., 1., 2., 1., 0., 4., 0., 3., 7., 1., 3., 1., 1., 6., 2., 2., 2., 2., 6., 1., 0., 0., 3., 3., 1., 0., 1., 4., 2., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0. [...]
+
+5., 0., 3., 5., 6., 3., 5., 2., 1., 30., 1., 13., 18., 0., 18., 5., 1., 3., 13., 3., 8., 21., 8., 24., 23., 8., 1., 0., 4., 1., 10., 2., 22., 14., 7., 10., 6., 27., 7., 1., 0., 4., 2., 17., 8., 12., 48., 13., 20., 6., 2., 2., 4., 1., 8., 2., 7., 11., 7., 13., 5., 17., 7., 1., 0., 0., 3., 0., 3., 4., 6., 2., 7., 2., 0., 4., 3., 2., 1., 0., 1., 0., 2., 2., 2., 5., 4., 4., 0., 3., 7., 1., 2., 0., 2., 4., 0., 0., 4., 3., 2., 0., 2., 4., 1., 0., 2., 0., 0., 0., 0., 2., 0., 0., 5., 0., 0., 0., [...]
+
+6., 0., 2., 1., 8., 4., 12., 3., 7., 22., 3., 16., 35., 5., 11., 5., 1., 2., 21., 3., 4., 15., 10., 34., 23., 3., 1., 1., 3., 1., 6., 4., 18., 19., 1., 13., 4., 20., 9., 0., 0., 4., 1., 10., 11., 18., 52., 9., 13., 9., 5., 0., 3., 1., 11., 4., 9., 7., 11., 18., 5., 17., 10., 5., 0., 2., 9., 3., 1., 0., 6., 6., 6., 3., 1., 5., 3., 4., 1., 1., 1., 0., 2., 2., 3., 7., 0., 4., 3., 5., 4., 1., 2., 2., 3., 7., 1., 0., 3., 1., 3., 1., 1., 4., 1., 1., 3., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0.,  [...]
+
+2., 3., 3., 1., 6., 2., 2., 1., 5., 15., 2., 14., 12., 1., 13., 4., 1., 3., 22., 4., 5., 14., 14., 35., 34., 5., 5., 1., 3., 3., 8., 6., 27., 15., 2., 17., 5., 21., 11., 1., 1., 5., 2., 15., 5., 22., 58., 7., 18., 5., 7., 1., 4., 2., 13., 4., 10., 4., 5., 15., 3., 28., 9., 3., 2., 0., 5., 2., 4., 1., 3., 2., 4., 3., 3., 1., 3., 2., 0., 3., 0., 0., 2., 0., 2., 4., 0., 1., 2., 1., 4., 0., 4., 0., 0., 4., 3., 0., 5., 1., 2., 4., 6., 2., 3., 0., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0. [...]
+
+7., 2., 2., 6., 9., 1., 7., 0., 4., 40., 0., 13., 27., 2., 17., 3., 0., 0., 9., 1., 6., 25., 12., 17., 28., 5., 0., 2., 6., 2., 9., 6., 16., 15., 3., 20., 5., 9., 9., 2., 1., 4., 2., 10., 19., 18., 46., 12., 16., 9., 3., 1., 4., 3., 5., 2., 4., 6., 8., 9., 7., 26., 6., 1., 1., 0., 3., 2., 2., 0., 3., 2., 3., 5., 3., 5., 1., 2., 0., 3., 4., 0., 3., 5., 2., 6., 3., 6., 1., 3., 3., 2., 6., 0., 1., 9., 3., 0., 2., 1., 1., 4., 2., 2., 2., 0., 4., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0., 0. [...]
+
+8., 3., 2., 6., 5., 4., 3., 1., 9., 27., 4., 18., 34., 1., 17., 0., 1., 6., 21., 3., 3., 16., 16., 30., 29., 3., 1., 2., 0., 2., 4., 8., 22., 13., 1., 16., 6., 15., 10., 0., 0., 2., 3., 12., 6., 11., 45., 8., 18., 10., 3., 1., 5., 1., 6., 1., 8., 4., 9., 19., 6., 19., 1., 2., 1., 1., 6., 0., 4., 3., 10., 4., 4., 4., 1., 3., 4., 1., 1., 0., 1., 0., 0., 1., 3., 5., 2., 3., 1., 1., 5., 0., 3., 1., 1., 12., 2., 0., 2., 2., 1., 3., 1., 1., 3., 0., 4., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0 [...]
+
+9., 1., 2., 4., 9., 3., 1., 1., 6., 26., 2., 17., 30., 0., 18., 3., 1., 1., 7., 0., 7., 34., 9., 14., 27., 1., 1., 0., 0., 2., 8., 5., 14., 19., 1., 12., 3., 11., 8., 3., 2., 8., 2., 18., 14., 22., 48., 17., 15., 13., 4., 2., 5., 2., 5., 5., 16., 7., 6., 21., 5., 19., 10., 1., 1., 0., 4., 0., 3., 1., 4., 2., 4., 5., 5., 5., 1., 3., 3., 0., 1., 0., 1., 7., 1., 7., 5., 4., 3., 6., 3., 1., 2., 1., 2., 8., 2., 0., 3., 0., 3., 2., 1., 1., 3., 1., 2., 0., 0., 0., 0., 0., 0., 0., 3., 0., 0., 0. [...]
+
+8., 1., 2., 6., 5., 5., 4., 2., 11., 20., 3., 17., 15., 0., 18., 1., 0., 0., 19., 1., 2., 26., 18., 13., 24., 8., 1., 0., 2., 1., 7., 6., 23., 21., 4., 13., 8., 19., 8., 3., 0., 4., 2., 18., 8., 20., 44., 10., 23., 8., 4., 0., 9., 2., 11., 4., 7., 4., 5., 21., 4., 31., 4., 2., 2., 1., 8., 1., 4., 2., 0., 2., 6., 4., 3., 3., 2., 3., 2., 0., 2., 0., 2., 1., 2., 10., 2., 7., 3., 2., 4., 2., 3., 1., 1., 11., 3., 0., 2., 2., 2., 2., 0., 5., 2., 0., 0., 0., 0., 0., 0., 5., 0., 0., 2., 0., 0.,  [...]
+
+7., 0., 2., 4., 12., 3., 7., 3., 5., 38., 0., 18., 26., 1., 13., 5., 0., 0., 25., 2., 7., 27., 14., 19., 33., 8., 2., 0., 4., 2., 9., 4., 22., 24., 6., 26., 1., 9., 11., 3., 3., 1., 0., 12., 15., 14., 50., 14., 12., 10., 1., 3., 5., 0., 7., 2., 15., 4., 5., 19., 4., 22., 9., 0., 1., 1., 9., 1., 5., 1., 0., 2., 0., 3., 0., 4., 2., 4., 1., 0., 0., 0., 1., 3., 2., 5., 1., 3., 1., 2., 2., 3., 4., 0., 1., 5., 2., 0., 4., 2., 1., 1., 0., 2., 1., 0., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0.,  [...]
+
+5., 0., 3., 9., 12., 3., 4., 0., 5., 26., 1., 10., 20., 1., 13., 1., 0., 3., 13., 0., 2., 25., 12., 25., 32., 8., 2., 0., 2., 4., 5., 11., 16., 14., 4., 15., 3., 17., 6., 1., 1., 5., 4., 9., 11., 14., 46., 14., 13., 12., 1., 0., 5., 4., 11., 6., 7., 7., 8., 20., 8., 30., 6., 4., 0., 4., 17., 1., 2., 2., 6., 3., 2., 3., 1., 5., 5., 2., 2., 1., 0., 0., 5., 1., 1., 3., 0., 6., 1., 3., 5., 2., 2., 1., 1., 10., 0., 0., 3., 0., 3., 1., 2., 2., 0., 2., 1., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0. [...]
+
+6., 1., 3., 4., 9., 4., 9., 1., 7., 26., 2., 15., 24., 1., 20., 3., 0., 1., 18., 2., 9., 35., 14., 15., 24., 4., 2., 1., 4., 1., 7., 5., 17., 14., 4., 15., 5., 15., 11., 2., 1., 5., 2., 7., 9., 21., 49., 9., 22., 8., 4., 0., 5., 1., 5., 1., 6., 5., 7., 15., 7., 23., 4., 2., 0., 2., 5., 0., 5., 1., 8., 3., 2., 5., 2., 6., 3., 0., 1., 4., 1., 0., 0., 4., 4., 9., 3., 6., 0., 2., 2., 2., 2., 2., 0., 8., 1., 0., 0., 0., 2., 5., 0., 2., 2., 2., 3., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0., 1 [...]
+
+9., 0., 1., 4., 13., 4., 7., 3., 10., 14., 0., 13., 14., 1., 12., 4., 2., 3., 19., 3., 4., 32., 11., 16., 23., 6., 1., 0., 5., 2., 10., 14., 33., 17., 3., 15., 3., 11., 6., 2., 2., 8., 1., 12., 12., 18., 44., 13., 21., 10., 4., 0., 4., 1., 3., 4., 11., 6., 8., 11., 5., 22., 9., 6., 0., 0., 2., 1., 3., 3., 4., 7., 2., 2., 0., 2., 7., 2., 0., 1., 0., 0., 2., 1., 1., 7., 2., 5., 5., 0., 4., 0., 3., 2., 1., 4., 4., 0., 3., 1., 2., 3., 1., 0., 3., 1., 2., 0., 0., 0., 0., 5., 0., 0., 3., 0., 0 [...]
+
+10., 0., 2., 4., 8., 5., 4., 3., 7., 25., 0., 11., 14., 2., 14., 1., 0., 3., 14., 2., 5., 18., 16., 18., 32., 5., 1., 0., 3., 2., 8., 10., 23., 26., 7., 16., 5., 20., 10., 2., 1., 2., 3., 11., 10., 13., 38., 16., 27., 9., 3., 0., 3., 0., 5., 4., 14., 4., 6., 15., 8., 28., 4., 2., 0., 1., 8., 3., 2., 1., 7., 5., 7., 5., 0., 3., 4., 4., 0., 3., 2., 0., 3., 3., 4., 6., 3., 3., 1., 0., 3., 0., 2., 2., 3., 7., 0., 0., 3., 0., 0., 1., 2., 1., 4., 0., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., [...]
+
+14., 2., 0., 3., 8., 0., 10., 4., 9., 54., 1., 3., 72., 0., 7., 1., 0., 1., 75., 5., 12., 93., 20., 75., 13., 3., 0., 1., 3., 2., 14., 12., 44., 12., 2., 33., 36., 18., 3., 0., 0., 8., 2., 22., 4., 26., 12., 14., 2., 4., 5., 0., 8., 1., 17., 8., 15., 4., 8., 4., 2., 44., 5., 6., 2., 0., 5., 4., 14., 2., 17., 1., 6., 0., 0., 1., 0., 3., 3., 19., 13., 2., 4., 0., 4., 0., 0., 0., 0., 0., 10., 1., 5., 2., 2., 1., 0., 0., 0., 0., 1., 0., 2., 3., 0., 0., 2., 0., 1., 0., 0., 0., 0., 0., 1., 0., [...]
+
+9., 0., 2., 4., 8., 0., 16., 1., 8., 60., 1., 12., 47., 0., 7., 1., 0., 2., 86., 11., 11., 66., 14., 80., 14., 4., 0., 0., 7., 3., 14., 8., 52., 12., 2., 40., 32., 13., 5., 0., 3., 5., 6., 20., 6., 32., 8., 10., 6., 2., 1., 0., 8., 4., 7., 3., 18., 0., 8., 3., 4., 30., 12., 8., 5., 0., 13., 6., 7., 0., 12., 1., 7., 2., 0., 1., 0., 5., 3., 11., 5., 3., 2., 1., 2., 0., 0., 0., 0., 0., 8., 1., 4., 1., 5., 3., 1., 0., 2., 0., 1., 0., 1., 3., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1., 0., 2. [...]
+
+7., 2., 0., 4., 11., 0., 15., 3., 8., 31., 1., 7., 49., 0., 5., 3., 0., 1., 71., 6., 6., 71., 5., 71., 8., 8., 0., 0., 3., 3., 16., 10., 65., 15., 3., 34., 32., 19., 0., 0., 0., 3., 2., 26., 3., 22., 7., 11., 4., 2., 2., 0., 9., 4., 14., 5., 15., 4., 10., 3., 2., 38., 15., 5., 2., 0., 16., 4., 5., 0., 9., 1., 5., 3., 1., 1., 0., 6., 1., 20., 11., 3., 3., 3., 4., 0., 0., 0., 0., 0., 10., 2., 1., 1., 2., 1., 0., 0., 0., 0., 0., 0., 1., 3., 3., 0., 4., 0., 0., 0., 1., 0., 0., 0., 1., 0., 4. [...]
+
+5., 1., 4., 6., 3., 0., 12., 5., 7., 60., 1., 6., 62., 0., 6., 3., 0., 0., 70., 10., 8., 67., 13., 68., 7., 6., 0., 0., 3., 0., 16., 8., 57., 12., 0., 31., 20., 13., 3., 0., 0., 6., 9., 21., 4., 17., 5., 14., 6., 2., 4., 0., 9., 3., 16., 6., 23., 4., 5., 6., 1., 44., 5., 12., 2., 0., 17., 2., 7., 1., 10., 1., 6., 4., 1., 2., 0., 7., 1., 21., 10., 1., 1., 2., 2., 0., 0., 0., 0., 0., 7., 2., 5., 2., 4., 0., 0., 0., 2., 0., 0., 0., 3., 4., 2., 0., 1., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1., [...]
+
+7., 2., 2., 2., 21., 0., 20., 3., 4., 60., 1., 8., 67., 0., 3., 1., 0., 2., 92., 4., 7., 87., 19., 89., 7., 4., 0., 2., 4., 2., 13., 10., 49., 14., 4., 42., 34., 19., 4., 0., 0., 13., 2., 17., 4., 26., 6., 15., 5., 2., 3., 0., 10., 5., 10., 7., 16., 4., 5., 8., 2., 25., 11., 3., 2., 0., 10., 1., 8., 3., 10., 3., 1., 2., 1., 1., 0., 4., 2., 17., 10., 0., 9., 0., 2., 0., 0., 0., 0., 0., 12., 4., 4., 1., 5., 1., 0., 0., 0., 0., 0., 0., 0., 3., 2., 0., 0., 0., 3., 0., 1., 0., 0., 0., 0., 0., [...]
+
+14., 3., 2., 9., 13., 0., 17., 1., 12., 55., 1., 11., 63., 0., 7., 3., 0., 4., 69., 10., 8., 82., 10., 84., 10., 5., 0., 2., 3., 2., 14., 10., 48., 11., 2., 40., 20., 10., 3., 0., 1., 6., 4., 25., 5., 19., 6., 13., 10., 2., 1., 0., 7., 2., 12., 5., 17., 3., 6., 5., 1., 38., 5., 7., 1., 0., 11., 1., 6., 1., 5., 0., 4., 0., 1., 1., 0., 2., 2., 23., 6., 4., 3., 1., 3., 0., 0., 0., 0., 0., 1., 2., 1., 2., 4., 1., 0., 0., 0., 0., 3., 0., 1., 2., 0., 0., 2., 0., 0., 0., 1., 0., 0., 0., 0., 0., [...]
+
+4., 0., 1., 4., 6., 0., 10., 1., 5., 51., 1., 3., 67., 2., 5., 2., 0., 1., 80., 7., 6., 70., 19., 91., 11., 6., 0., 1., 3., 1., 13., 8., 52., 12., 2., 47., 35., 9., 5., 0., 0., 7., 4., 16., 11., 25., 8., 17., 8., 2., 1., 0., 11., 3., 10., 3., 16., 0., 11., 2., 2., 38., 11., 9., 4., 0., 15., 4., 5., 0., 11., 5., 3., 1., 2., 1., 0., 7., 2., 14., 12., 4., 5., 0., 3., 0., 0., 0., 0., 0., 10., 2., 4., 1., 4., 1., 0., 0., 1., 0., 1., 0., 0., 7., 2., 0., 2., 0., 0., 0., 1., 0., 0., 0., 1., 0.,  [...]
+
+6., 1., 5., 7., 12., 0., 18., 4., 8., 38., 0., 10., 67., 2., 4., 3., 0., 2., 81., 11., 6., 66., 15., 68., 9., 4., 0., 4., 5., 2., 9., 3., 42., 12., 0., 47., 26., 13., 9., 0., 2., 8., 1., 23., 7., 35., 2., 13., 3., 1., 0., 0., 10., 4., 19., 4., 15., 3., 8., 2., 3., 42., 6., 8., 1., 0., 11., 1., 11., 1., 16., 3., 5., 3., 0., 1., 0., 5., 1., 15., 11., 9., 3., 3., 2., 0., 0., 0., 0., 0., 10., 2., 2., 5., 2., 0., 3., 0., 1., 0., 0., 0., 2., 2., 1., 0., 2., 0., 2., 0., 1., 0., 0., 0., 1., 0.,  [...]
+
+14., 1., 2., 3., 8., 0., 13., 2., 7., 64., 2., 7., 55., 0., 5., 1., 0., 1., 85., 6., 2., 83., 15., 68., 12., 3., 0., 1., 1., 0., 16., 10., 58., 12., 0., 40., 26., 11., 8., 0., 0., 3., 1., 22., 14., 24., 8., 17., 3., 6., 2., 0., 9., 1., 10., 5., 16., 5., 11., 2., 4., 37., 10., 9., 1., 0., 17., 4., 13., 1., 4., 4., 6., 1., 0., 0., 0., 3., 2., 20., 14., 3., 6., 1., 6., 0., 0., 0., 0., 0., 8., 2., 1., 1., 8., 1., 0., 0., 0., 0., 0., 0., 2., 8., 5., 0., 2., 0., 1., 0., 0., 0., 0., 0., 3., 0., [...]
+
+6., 3., 2., 5., 12., 0., 16., 1., 5., 68., 1., 7., 42., 1., 7., 5., 0., 4., 58., 12., 9., 94., 15., 72., 15., 7., 0., 0., 4., 2., 14., 7., 56., 11., 0., 44., 43., 6., 6., 0., 1., 6., 0., 25., 4., 23., 5., 13., 6., 1., 1., 0., 4., 3., 11., 6., 14., 4., 4., 1., 6., 54., 8., 5., 2., 0., 13., 1., 3., 1., 10., 1., 4., 1., 3., 1., 0., 5., 1., 15., 8., 4., 6., 0., 3., 0., 0., 0., 0., 0., 8., 2., 2., 3., 5., 0., 1., 0., 0., 0., 2., 0., 0., 4., 4., 0., 5., 0., 1., 0., 1., 0., 0., 0., 1., 0., 1.,  [...]
+
+5., 1., 4., 2., 18., 0., 10., 4., 7., 43., 2., 6., 49., 1., 1., 3., 0., 3., 60., 4., 11., 70., 22., 73., 7., 7., 0., 1., 2., 3., 13., 8., 55., 10., 2., 30., 31., 11., 8., 0., 0., 9., 8., 19., 5., 20., 5., 17., 6., 8., 3., 0., 14., 6., 16., 5., 18., 2., 5., 1., 2., 29., 6., 3., 2., 0., 17., 1., 8., 2., 16., 5., 2., 3., 2., 0., 0., 4., 0., 20., 8., 1., 3., 2., 4., 0., 0., 0., 0., 0., 11., 1., 4., 5., 1., 2., 0., 0., 0., 0., 0., 0., 1., 3., 2., 0., 2., 0., 0., 0., 3., 0., 0., 0., 2., 0., 2. [...]
+
+19., 1., 1., 5., 4., 0., 14., 0., 5., 58., 0., 12., 63., 0., 5., 3., 0., 1., 70., 9., 12., 92., 9., 75., 14., 5., 0., 0., 2., 3., 18., 4., 35., 11., 2., 39., 29., 16., 0., 0., 1., 9., 3., 27., 2., 23., 11., 15., 4., 2., 2., 0., 6., 7., 13., 6., 11., 2., 4., 0., 3., 39., 12., 9., 3., 0., 14., 2., 10., 4., 17., 2., 5., 0., 1., 1., 0., 3., 3., 9., 6., 4., 5., 1., 5., 0., 0., 0., 0., 0., 2., 0., 4., 2., 3., 3., 2., 0., 2., 0., 2., 0., 1., 2., 2., 0., 4., 0., 1., 0., 3., 0., 0., 0., 0., 0., 2 [...]
+
+10., 1., 2., 3., 12., 0., 16., 1., 11., 47., 0., 11., 64., 3., 5., 2., 0., 3., 75., 5., 10., 66., 15., 91., 13., 3., 0., 0., 4., 1., 15., 5., 44., 6., 4., 40., 28., 12., 6., 0., 0., 6., 1., 28., 8., 18., 8., 12., 8., 3., 2., 0., 14., 5., 19., 4., 15., 2., 4., 1., 2., 30., 7., 3., 1., 0., 17., 3., 9., 2., 7., 1., 2., 0., 0., 2., 0., 6., 3., 16., 5., 6., 3., 0., 2., 0., 0., 0., 0., 0., 14., 0., 2., 3., 2., 2., 0., 0., 0., 0., 1., 0., 1., 3., 2., 0., 3., 0., 0., 0., 0., 0., 0., 0., 1., 0.,  [...]
+
+7., 1., 1., 5., 13., 0., 15., 1., 7., 42., 0., 10., 60., 2., 3., 1., 0., 2., 68., 10., 4., 79., 13., 81., 13., 3., 0., 1., 5., 3., 12., 14., 51., 10., 6., 37., 35., 18., 6., 0., 2., 7., 3., 17., 2., 18., 8., 19., 12., 2., 4., 0., 5., 2., 8., 9., 8., 2., 6., 3., 2., 33., 6., 5., 0., 0., 11., 0., 4., 0., 10., 1., 4., 1., 0., 0., 0., 3., 2., 19., 13., 7., 3., 3., 4., 0., 0., 0., 0., 0., 8., 0., 4., 1., 6., 1., 2., 0., 0., 0., 1., 0., 1., 6., 2., 0., 3., 0., 1., 0., 0., 0., 0., 0., 4., 0., 0 [...]
+
+7., 0., 3., 7., 16., 0., 14., 3., 6., 55., 0., 2., 64., 2., 1., 2., 0., 1., 78., 6., 5., 91., 10., 74., 12., 3., 0., 2., 3., 3., 12., 12., 55., 10., 5., 37., 30., 10., 4., 0., 0., 5., 2., 32., 5., 32., 4., 8., 5., 4., 1., 0., 8., 4., 12., 2., 14., 4., 6., 6., 2., 33., 8., 9., 2., 0., 13., 0., 7., 3., 18., 5., 8., 0., 4., 2., 0., 5., 1., 18., 10., 0., 3., 4., 0., 0., 0., 0., 0., 0., 7., 1., 1., 1., 4., 1., 1., 0., 0., 0., 1., 0., 2., 4., 2., 0., 2., 0., 3., 0., 2., 0., 0., 0., 0., 0., 1., [...]
+
+10., 1., 2., 0., 16., 0., 12., 1., 3., 52., 1., 7., 47., 1., 6., 4., 0., 3., 55., 10., 8., 79., 18., 78., 9., 3., 0., 0., 3., 0., 16., 8., 57., 18., 0., 46., 29., 11., 8., 0., 1., 10., 3., 23., 8., 28., 5., 12., 4., 3., 0., 0., 7., 5., 19., 4., 14., 3., 12., 2., 2., 36., 9., 13., 2., 0., 20., 3., 9., 5., 7., 2., 6., 0., 1., 0., 0., 6., 2., 26., 8., 0., 2., 2., 2., 0., 0., 0., 0., 0., 6., 0., 2., 1., 3., 1., 0., 0., 0., 0., 1., 0., 0., 2., 2., 0., 0., 0., 3., 0., 4., 0., 0., 0., 1., 0., 3 [...]
+
+13., 0., 5., 2., 7., 0., 17., 2., 7., 60., 2., 11., 55., 0., 2., 1., 0., 2., 71., 11., 7., 78., 16., 79., 14., 2., 0., 2., 2., 2., 10., 9., 54., 5., 3., 32., 29., 15., 4., 0., 2., 3., 2., 21., 7., 31., 10., 12., 8., 2., 4., 0., 8., 3., 15., 4., 18., 2., 6., 2., 1., 29., 6., 9., 0., 0., 14., 4., 13., 3., 4., 1., 3., 2., 0., 0., 0., 7., 2., 20., 7., 2., 9., 1., 2., 0., 0., 0., 0., 0., 5., 2., 3., 2., 4., 1., 1., 0., 1., 0., 1., 0., 1., 7., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0., 4., 0., 2. [...]
+
+1., 0., 2., 4., 13., 0., 16., 1., 5., 61., 0., 9., 68., 1., 5., 2., 0., 1., 62., 6., 1., 72., 13., 67., 13., 4., 0., 3., 5., 1., 22., 8., 40., 8., 0., 29., 35., 11., 9., 0., 0., 7., 3., 18., 4., 23., 9., 15., 6., 0., 2., 0., 11., 1., 17., 9., 20., 3., 8., 1., 3., 30., 13., 6., 2., 0., 15., 6., 15., 2., 16., 0., 4., 0., 1., 1., 0., 5., 2., 24., 11., 1., 5., 0., 4., 0., 0., 0., 0., 0., 5., 3., 2., 2., 1., 3., 1., 0., 3., 0., 1., 0., 1., 4., 1., 0., 3., 0., 2., 0., 2., 0., 0., 0., 0., 0., 5 [...]
+
+11., 1., 0., 3., 8., 2., 8., 0., 6., 17., 1., 10., 11., 0., 13., 2., 2., 1., 15., 3., 0., 20., 20., 33., 29., 10., 0., 1., 4., 6., 4., 8., 29., 20., 5., 13., 3., 11., 9., 1., 0., 6., 4., 9., 16., 26., 50., 14., 12., 12., 6., 1., 4., 2., 8., 5., 7., 4., 8., 10., 6., 21., 4., 2., 1., 1., 7., 0., 5., 0., 7., 4., 4., 3., 3., 2., 7., 2., 0., 1., 1., 0., 0., 1., 2., 4., 2., 2., 3., 1., 7., 0., 1., 0., 0., 3., 3., 0., 1., 3., 3., 1., 0., 1., 1., 0., 2., 0., 0., 0., 0., 1., 0., 0., 4., 0., 0., 0 [...]
+
+7., 3., 1., 6., 9., 5., 11., 2., 5., 21., 1., 18., 18., 3., 16., 3., 1., 1., 22., 1., 4., 30., 13., 12., 21., 8., 0., 0., 0., 1., 9., 5., 13., 18., 3., 6., 5., 14., 6., 4., 2., 4., 0., 12., 8., 24., 51., 12., 30., 9., 5., 0., 5., 2., 5., 4., 11., 6., 7., 15., 3., 16., 9., 5., 2., 1., 5., 0., 4., 1., 6., 3., 3., 5., 2., 2., 4., 2., 0., 3., 1., 0., 3., 2., 0., 3., 1., 4., 0., 3., 7., 0., 2., 1., 4., 7., 2., 0., 4., 1., 2., 0., 2., 3., 4., 0., 1., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0., [...]
+
+8., 0., 2., 3., 7., 2., 5., 1., 5., 28., 3., 4., 22., 2., 24., 3., 2., 1., 24., 2., 3., 7., 8., 19., 29., 2., 0., 2., 5., 1., 15., 15., 18., 11., 7., 12., 5., 13., 15., 4., 1., 6., 5., 14., 8., 25., 51., 14., 19., 13., 4., 1., 5., 3., 5., 2., 9., 4., 3., 19., 5., 14., 10., 3., 1., 4., 5., 1., 3., 2., 5., 2., 3., 6., 0., 5., 1., 2., 1., 4., 1., 0., 6., 0., 1., 7., 2., 9., 2., 7., 6., 1., 1., 0., 1., 6., 2., 0., 2., 1., 3., 2., 0., 1., 1., 2., 3., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+12., 1., 1., 4., 6., 2., 3., 0., 5., 18., 0., 11., 13., 2., 18., 2., 1., 1., 14., 1., 5., 27., 10., 24., 22., 10., 0., 1., 2., 1., 4., 4., 19., 13., 3., 16., 8., 15., 3., 3., 0., 2., 0., 10., 10., 8., 46., 10., 25., 10., 3., 3., 6., 1., 5., 3., 17., 6., 9., 12., 8., 21., 13., 1., 1., 1., 6., 2., 4., 1., 4., 0., 2., 5., 4., 1., 1., 1., 1., 2., 2., 0., 4., 2., 2., 7., 2., 3., 4., 0., 7., 1., 4., 1., 4., 4., 4., 0., 1., 4., 5., 4., 1., 1., 1., 0., 4., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0., [...]
+
+10., 2., 4., 2., 8., 4., 4., 1., 9., 23., 0., 9., 24., 1., 13., 2., 3., 2., 20., 3., 5., 22., 18., 17., 26., 8., 2., 3., 3., 2., 3., 12., 44., 9., 2., 16., 6., 15., 9., 1., 0., 5., 2., 6., 17., 18., 56., 11., 14., 10., 5., 0., 3., 3., 4., 5., 9., 4., 5., 22., 4., 24., 6., 4., 1., 1., 11., 0., 2., 2., 3., 1., 4., 5., 2., 6., 4., 4., 1., 3., 2., 0., 4., 1., 5., 8., 2., 3., 7., 1., 6., 1., 3., 0., 2., 8., 3., 0., 1., 3., 0., 3., 3., 2., 0., 2., 4., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0. [...]
+
+8., 0., 2., 3., 11., 1., 7., 0., 9., 24., 2., 16., 20., 1., 16., 0., 0., 1., 22., 2., 4., 28., 17., 39., 32., 5., 1., 2., 2., 3., 5., 8., 32., 22., 1., 14., 6., 7., 11., 3., 0., 2., 4., 24., 10., 10., 39., 7., 17., 11., 6., 0., 7., 4., 6., 6., 14., 5., 11., 15., 5., 21., 12., 2., 0., 0., 3., 0., 6., 3., 3., 1., 4., 3., 1., 2., 5., 1., 1., 5., 3., 0., 1., 2., 1., 7., 3., 3., 5., 2., 4., 1., 2., 1., 1., 11., 2., 0., 4., 1., 1., 4., 2., 2., 5., 1., 3., 0., 0., 0., 0., 2., 0., 0., 7., 0., 0. [...]
+
+10., 0., 0., 5., 7., 1., 5., 2., 10., 25., 2., 12., 30., 4., 12., 4., 1., 4., 10., 1., 2., 33., 8., 33., 26., 7., 1., 3., 1., 1., 7., 12., 25., 18., 6., 15., 1., 15., 9., 1., 1., 1., 1., 7., 15., 15., 49., 12., 19., 10., 6., 0., 5., 1., 1., 1., 8., 8., 13., 18., 6., 20., 4., 2., 0., 1., 7., 1., 4., 0., 5., 2., 2., 6., 2., 5., 5., 1., 1., 1., 2., 0., 1., 2., 2., 4., 2., 3., 1., 3., 3., 1., 1., 1., 3., 9., 1., 0., 1., 1., 3., 4., 2., 4., 2., 0., 1., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0.,  [...]
+
+10., 1., 4., 2., 11., 3., 5., 1., 4., 14., 1., 12., 24., 0., 11., 2., 1., 1., 15., 2., 6., 18., 13., 17., 29., 8., 0., 0., 4., 0., 10., 8., 20., 17., 1., 15., 3., 14., 8., 1., 0., 2., 2., 12., 6., 11., 49., 6., 29., 6., 1., 1., 6., 1., 8., 3., 13., 6., 9., 22., 4., 27., 8., 6., 0., 0., 6., 1., 5., 0., 3., 3., 3., 3., 1., 7., 4., 2., 2., 1., 2., 0., 0., 2., 1., 4., 2., 3., 3., 6., 2., 2., 1., 2., 4., 5., 0., 0., 4., 0., 2., 7., 1., 3., 2., 3., 5., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0., 0 [...]
+
+6., 0., 0., 4., 5., 1., 9., 0., 4., 25., 1., 13., 24., 1., 16., 4., 2., 1., 21., 2., 2., 21., 11., 19., 21., 6., 0., 1., 6., 1., 6., 5., 26., 12., 3., 15., 2., 22., 13., 2., 0., 7., 1., 3., 10., 17., 40., 20., 29., 7., 1., 0., 4., 1., 9., 1., 8., 10., 9., 16., 4., 26., 10., 3., 4., 2., 7., 2., 2., 3., 4., 2., 6., 9., 2., 5., 6., 2., 1., 5., 4., 0., 2., 1., 4., 3., 1., 4., 3., 2., 2., 0., 1., 1., 3., 8., 3., 0., 4., 2., 1., 3., 1., 1., 2., 1., 3., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0 [...]
+
+4., 0., 4., 2., 7., 6., 7., 1., 5., 27., 2., 10., 22., 0., 19., 3., 0., 1., 12., 2., 4., 25., 8., 30., 29., 10., 0., 0., 5., 2., 12., 7., 22., 25., 3., 15., 5., 20., 6., 2., 1., 3., 1., 16., 9., 11., 40., 13., 20., 13., 6., 2., 4., 1., 15., 2., 12., 7., 6., 15., 8., 24., 8., 2., 0., 0., 6., 1., 6., 0., 5., 4., 7., 3., 1., 4., 5., 1., 0., 4., 1., 0., 0., 2., 3., 7., 1., 3., 1., 2., 0., 1., 1., 0., 2., 6., 2., 0., 0., 1., 0., 0., 2., 0., 3., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,  [...]
+
+15., 2., 0., 4., 8., 0., 9., 2., 11., 22., 1., 10., 27., 2., 16., 2., 0., 4., 18., 1., 1., 23., 14., 32., 16., 6., 0., 2., 1., 1., 4., 11., 27., 17., 1., 13., 6., 18., 5., 1., 0., 5., 1., 11., 10., 20., 50., 14., 24., 13., 2., 1., 5., 0., 7., 4., 15., 5., 7., 16., 6., 24., 8., 1., 1., 0., 3., 1., 3., 1., 7., 6., 5., 2., 1., 3., 3., 0., 4., 2., 2., 0., 3., 2., 2., 4., 3., 4., 1., 3., 7., 2., 1., 1., 2., 10., 5., 0., 1., 2., 3., 2., 6., 3., 2., 0., 1., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0 [...]
+
+11., 2., 1., 6., 12., 1., 5., 2., 6., 23., 0., 22., 26., 2., 15., 2., 0., 3., 9., 3., 3., 23., 19., 32., 20., 2., 1., 3., 1., 3., 13., 4., 29., 14., 3., 8., 7., 19., 13., 3., 1., 2., 0., 8., 14., 19., 32., 10., 14., 14., 3., 2., 4., 1., 9., 1., 9., 5., 17., 20., 5., 18., 12., 2., 0., 1., 11., 1., 3., 4., 5., 2., 1., 7., 1., 6., 0., 3., 1., 1., 2., 0., 3., 1., 3., 4., 2., 5., 2., 2., 4., 2., 4., 1., 3., 3., 1., 0., 1., 2., 3., 5., 2., 2., 0., 1., 3., 0., 0., 0., 0., 1., 0., 0., 2., 0., 0. [...]
+
+13., 0., 2., 3., 10., 0., 15., 3., 5., 47., 0., 12., 60., 3., 8., 2., 0., 2., 72., 13., 4., 92., 18., 97., 8., 2., 0., 0., 3., 3., 20., 13., 33., 14., 1., 38., 19., 7., 0., 0., 0., 6., 3., 29., 4., 21., 5., 14., 9., 4., 1., 0., 9., 4., 11., 3., 15., 2., 7., 3., 3., 29., 11., 12., 0., 0., 7., 3., 10., 2., 11., 0., 3., 1., 1., 1., 0., 3., 3., 19., 9., 5., 2., 1., 2., 0., 0., 0., 0., 0., 10., 2., 0., 1., 3., 1., 3., 0., 0., 0., 1., 0., 2., 4., 3., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., [...]
+
+8., 1., 4., 5., 11., 0., 11., 3., 9., 43., 1., 11., 61., 1., 8., 2., 0., 5., 58., 10., 9., 53., 7., 78., 10., 4., 0., 0., 4., 3., 19., 10., 48., 9., 5., 34., 26., 11., 4., 0., 0., 4., 1., 32., 6., 36., 7., 11., 6., 3., 2., 0., 5., 4., 17., 2., 22., 3., 16., 0., 2., 37., 7., 6., 0., 0., 14., 2., 7., 4., 13., 0., 2., 1., 3., 1., 0., 4., 6., 28., 8., 4., 4., 0., 7., 0., 0., 0., 0., 0., 11., 1., 1., 5., 1., 1., 1., 0., 0., 0., 0., 0., 0., 3., 4., 0., 2., 0., 1., 0., 1., 0., 0., 0., 3., 0., 2 [...]
+
+1., 0., 0., 4., 14., 0., 9., 3., 5., 49., 3., 5., 55., 2., 9., 0., 0., 4., 76., 8., 9., 85., 17., 76., 5., 2., 0., 1., 2., 1., 12., 6., 59., 9., 2., 38., 44., 14., 5., 0., 0., 4., 3., 27., 5., 28., 5., 10., 10., 5., 0., 0., 10., 7., 15., 1., 19., 2., 6., 4., 5., 36., 13., 4., 4., 0., 10., 7., 10., 3., 14., 4., 3., 1., 1., 3., 0., 5., 1., 13., 13., 3., 2., 0., 1., 0., 0., 0., 0., 0., 11., 4., 3., 6., 2., 1., 0., 0., 2., 0., 0., 0., 0., 4., 0., 0., 0., 0., 1., 0., 2., 0., 0., 0., 0., 0., 5 [...]
+
+2., 2., 1., 1., 8., 0., 11., 3., 7., 46., 2., 11., 57., 2., 6., 4., 0., 1., 72., 9., 8., 67., 16., 68., 15., 1., 0., 1., 2., 3., 16., 13., 49., 11., 4., 33., 37., 15., 2., 0., 1., 0., 2., 20., 6., 29., 9., 8., 4., 3., 4., 0., 7., 5., 19., 6., 20., 3., 11., 1., 3., 49., 8., 7., 2., 0., 14., 2., 9., 2., 10., 1., 4., 0., 0., 3., 0., 1., 2., 11., 9., 1., 4., 0., 6., 0., 0., 0., 0., 0., 5., 2., 3., 3., 0., 1., 3., 0., 1., 0., 2., 0., 2., 5., 3., 0., 0., 0., 0., 0., 3., 0., 0., 0., 0., 0., 3., [...]
+
+10., 2., 2., 3., 8., 0., 13., 2., 12., 49., 0., 3., 48., 3., 5., 2., 0., 5., 80., 11., 5., 79., 11., 71., 8., 3., 0., 2., 1., 0., 14., 9., 43., 15., 1., 44., 34., 11., 2., 0., 0., 8., 3., 22., 9., 27., 6., 10., 7., 1., 2., 0., 11., 5., 23., 6., 12., 2., 7., 2., 2., 43., 10., 6., 2., 0., 6., 4., 8., 2., 12., 1., 1., 2., 0., 1., 0., 2., 2., 22., 9., 2., 3., 1., 1., 0., 0., 0., 0., 0., 8., 2., 1., 4., 2., 1., 1., 0., 0., 0., 0., 0., 0., 2., 1., 0., 1., 0., 3., 0., 1., 0., 0., 0., 1., 0., 0. [...]
+
+10., 2., 2., 5., 6., 0., 13., 4., 6., 42., 2., 5., 55., 3., 6., 1., 0., 4., 76., 5., 10., 88., 12., 86., 4., 4., 0., 2., 2., 2., 13., 13., 39., 12., 2., 37., 29., 11., 8., 0., 2., 9., 4., 27., 3., 17., 12., 11., 8., 0., 0., 0., 11., 4., 20., 8., 14., 3., 8., 4., 2., 47., 10., 5., 2., 0., 22., 3., 9., 3., 13., 8., 4., 1., 1., 1., 0., 8., 2., 15., 13., 2., 4., 1., 4., 0., 0., 0., 0., 0., 13., 2., 2., 5., 1., 1., 2., 0., 0., 0., 2., 0., 0., 3., 3., 0., 1., 0., 1., 0., 2., 0., 0., 0., 0., 0. [...]
+
+6., 0., 1., 3., 8., 0., 15., 1., 7., 47., 0., 6., 63., 3., 5., 3., 0., 1., 79., 10., 6., 71., 15., 85., 14., 6., 0., 1., 5., 0., 18., 7., 34., 15., 1., 42., 36., 10., 6., 0., 1., 8., 5., 23., 7., 20., 8., 9., 5., 5., 1., 0., 4., 5., 23., 8., 17., 3., 7., 1., 8., 39., 5., 4., 5., 0., 13., 1., 10., 1., 6., 0., 3., 0., 0., 1., 0., 3., 0., 17., 11., 0., 4., 2., 3., 0., 0., 0., 0., 0., 10., 0., 0., 0., 4., 3., 1., 0., 3., 0., 1., 0., 0., 2., 0., 0., 0., 0., 1., 0., 3., 0., 0., 0., 1., 0., 2., [...]
+
+19., 0., 4., 6., 8., 0., 16., 7., 7., 39., 0., 3., 70., 1., 5., 3., 0., 3., 62., 11., 11., 54., 14., 74., 11., 7., 0., 2., 1., 0., 12., 5., 66., 17., 2., 44., 33., 17., 4., 0., 0., 7., 7., 24., 8., 24., 4., 15., 3., 2., 2., 0., 10., 7., 22., 4., 14., 2., 8., 2., 4., 48., 6., 5., 0., 0., 9., 4., 6., 3., 12., 0., 4., 2., 0., 0., 0., 3., 2., 22., 8., 3., 4., 0., 1., 0., 0., 0., 0., 0., 11., 5., 6., 2., 3., 1., 1., 0., 2., 0., 1., 0., 0., 5., 2., 0., 3., 0., 0., 0., 0., 0., 0., 0., 2., 0., 1 [...]
+
+7., 1., 2., 3., 12., 0., 15., 2., 8., 69., 0., 5., 59., 1., 5., 2., 0., 4., 65., 10., 7., 76., 14., 74., 17., 4., 0., 0., 0., 2., 11., 15., 55., 12., 1., 33., 34., 14., 4., 0., 2., 6., 0., 24., 8., 35., 11., 11., 2., 2., 0., 0., 6., 6., 13., 4., 15., 2., 5., 0., 4., 35., 8., 5., 4., 0., 15., 1., 7., 1., 7., 3., 5., 1., 1., 1., 0., 0., 2., 20., 7., 3., 2., 0., 5., 0., 0., 0., 0., 0., 9., 1., 4., 1., 4., 3., 1., 0., 1., 0., 0., 0., 1., 3., 1., 0., 0., 0., 3., 0., 0., 0., 0., 0., 0., 0., 3. [...]
+
+9., 1., 1., 0., 14., 0., 19., 2., 7., 45., 2., 9., 61., 1., 4., 1., 0., 5., 62., 8., 3., 81., 17., 87., 11., 2., 0., 1., 2., 1., 15., 12., 48., 10., 1., 43., 39., 14., 6., 0., 0., 6., 2., 29., 4., 24., 8., 13., 7., 2., 2., 0., 8., 2., 13., 5., 15., 3., 7., 2., 4., 42., 7., 8., 1., 0., 13., 3., 6., 4., 9., 4., 7., 0., 1., 1., 0., 2., 4., 17., 7., 1., 1., 2., 2., 0., 0., 0., 0., 0., 13., 5., 2., 1., 3., 1., 0., 0., 3., 0., 1., 0., 2., 3., 2., 0., 2., 0., 0., 0., 1., 0., 0., 0., 2., 0., 0., [...]
+
+6., 2., 0., 5., 13., 0., 17., 0., 7., 51., 3., 6., 55., 1., 1., 1., 0., 3., 70., 6., 9., 77., 23., 71., 10., 2., 0., 3., 4., 0., 16., 16., 51., 9., 1., 44., 34., 10., 6., 0., 1., 8., 4., 13., 5., 25., 5., 11., 8., 5., 3., 0., 6., 3., 14., 10., 15., 7., 9., 6., 3., 38., 4., 6., 3., 0., 10., 1., 6., 0., 21., 2., 1., 0., 1., 2., 0., 2., 1., 14., 10., 6., 2., 1., 3., 0., 0., 0., 0., 0., 11., 1., 4., 2., 0., 0., 1., 0., 0., 0., 1., 0., 0., 3., 3., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 4 [...]
+
+7., 0., 2., 6., 12., 0., 16., 0., 4., 56., 2., 6., 54., 0., 3., 3., 0., 4., 69., 8., 11., 80., 13., 77., 14., 5., 0., 2., 1., 2., 11., 3., 45., 16., 2., 41., 26., 5., 4., 0., 2., 5., 0., 23., 6., 25., 7., 15., 7., 6., 3., 0., 9., 6., 12., 9., 15., 6., 8., 4., 8., 31., 9., 5., 2., 0., 16., 3., 5., 1., 8., 1., 2., 0., 0., 0., 0., 4., 2., 19., 10., 6., 4., 0., 2., 0., 0., 0., 0., 0., 7., 2., 6., 5., 2., 2., 1., 0., 1., 0., 1., 0., 0., 3., 0., 0., 2., 0., 1., 0., 0., 0., 0., 0., 0., 0., 2.,  [...]
+
+14., 1., 1., 1., 12., 0., 15., 0., 6., 44., 1., 12., 60., 1., 5., 5., 0., 2., 69., 13., 7., 72., 20., 97., 12., 4., 0., 0., 5., 3., 11., 11., 63., 13., 7., 41., 26., 9., 6., 0., 1., 6., 6., 26., 9., 21., 4., 11., 2., 1., 3., 0., 13., 2., 13., 4., 21., 4., 7., 2., 3., 40., 1., 4., 4., 0., 14., 2., 9., 4., 11., 1., 4., 1., 2., 1., 0., 2., 2., 24., 6., 2., 10., 3., 3., 0., 0., 0., 0., 0., 7., 3., 1., 2., 6., 1., 1., 0., 1., 0., 1., 0., 0., 5., 3., 0., 5., 0., 0., 0., 2., 0., 0., 0., 0., 0., [...]
+
+8., 2., 3., 3., 11., 0., 17., 3., 14., 50., 0., 12., 44., 1., 4., 3., 0., 4., 56., 4., 12., 86., 17., 86., 11., 6., 0., 1., 3., 4., 10., 10., 59., 10., 0., 49., 31., 18., 1., 0., 1., 6., 2., 27., 9., 33., 9., 8., 5., 1., 1., 0., 9., 5., 16., 5., 21., 5., 10., 3., 4., 35., 4., 4., 3., 0., 8., 6., 10., 3., 8., 3., 2., 1., 0., 2., 0., 7., 3., 17., 12., 1., 3., 0., 2., 0., 0., 0., 0., 0., 12., 2., 7., 2., 6., 2., 1., 0., 0., 0., 1., 0., 1., 4., 4., 0., 3., 0., 7., 0., 1., 0., 0., 0., 0., 0., [...]
+
+8., 2., 3., 2., 12., 0., 17., 4., 6., 47., 1., 9., 65., 1., 2., 0., 0., 1., 83., 5., 9., 67., 16., 76., 12., 5., 0., 1., 2., 1., 14., 8., 46., 14., 4., 44., 35., 14., 5., 0., 3., 7., 1., 24., 5., 15., 7., 12., 7., 1., 1., 0., 7., 7., 13., 0., 17., 4., 5., 5., 3., 45., 11., 10., 2., 0., 17., 2., 7., 4., 13., 2., 6., 0., 1., 1., 0., 6., 3., 15., 8., 4., 6., 0., 3., 0., 0., 0., 0., 0., 11., 2., 3., 5., 1., 2., 2., 0., 3., 0., 1., 0., 1., 4., 2., 0., 1., 0., 2., 0., 2., 0., 0., 0., 0., 0., 4 [...]
+
+3., 1., 1., 4., 12., 0., 12., 3., 9., 57., 0., 7., 47., 1., 2., 1., 0., 5., 80., 13., 10., 79., 13., 82., 16., 3., 0., 3., 1., 1., 15., 8., 68., 10., 1., 45., 25., 11., 8., 0., 0., 7., 1., 16., 4., 17., 3., 15., 6., 3., 2., 0., 12., 7., 17., 6., 20., 3., 7., 4., 1., 30., 6., 5., 2., 0., 15., 4., 14., 4., 12., 0., 4., 1., 1., 1., 0., 9., 2., 14., 11., 2., 5., 0., 2., 0., 0., 0., 0., 0., 13., 3., 4., 2., 4., 3., 2., 0., 0., 0., 0., 0., 2., 6., 2., 0., 2., 0., 0., 0., 0., 0., 0., 0., 1., 0. [...]
+
+7., 2., 5., 3., 6., 0., 15., 0., 6., 59., 2., 9., 66., 0., 4., 4., 0., 1., 76., 6., 9., 77., 16., 84., 5., 5., 0., 0., 4., 1., 11., 17., 59., 10., 2., 32., 26., 15., 4., 0., 1., 2., 5., 22., 5., 16., 12., 10., 3., 3., 1., 0., 8., 6., 17., 3., 18., 2., 5., 4., 2., 51., 4., 6., 1., 0., 12., 5., 10., 1., 20., 2., 5., 1., 2., 2., 0., 8., 1., 19., 12., 3., 4., 0., 4., 0., 0., 0., 0., 0., 8., 2., 5., 3., 2., 2., 1., 0., 3., 0., 0., 0., 0., 3., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 3. [...]
+
+9., 1., 2., 3., 13., 0., 19., 4., 5., 52., 0., 7., 46., 1., 5., 3., 0., 3., 77., 11., 6., 83., 14., 88., 8., 4., 0., 1., 4., 3., 22., 16., 56., 14., 0., 39., 36., 11., 11., 0., 1., 7., 2., 18., 6., 32., 6., 9., 3., 3., 1., 0., 3., 5., 16., 6., 17., 3., 12., 3., 2., 37., 5., 6., 2., 0., 22., 4., 5., 0., 11., 3., 3., 0., 6., 2., 0., 5., 0., 18., 11., 3., 4., 0., 1., 0., 0., 0., 0., 0., 7., 1., 4., 1., 1., 1., 1., 0., 0., 0., 1., 0., 1., 0., 2., 0., 3., 0., 0., 0., 0., 0., 0., 0., 1., 0., 1 [...]
+
+2., 0., 2., 4., 13., 0., 9., 3., 5., 58., 0., 8., 59., 0., 7., 2., 0., 0., 65., 10., 11., 92., 15., 92., 11., 4., 0., 3., 6., 3., 10., 9., 40., 17., 1., 22., 35., 13., 4., 0., 0., 6., 2., 31., 6., 21., 6., 14., 6., 3., 2., 0., 15., 6., 14., 6., 19., 5., 10., 3., 3., 38., 6., 3., 3., 0., 13., 3., 7., 2., 4., 0., 1., 3., 0., 1., 0., 2., 2., 16., 11., 3., 4., 1., 5., 0., 0., 0., 0., 0., 6., 1., 3., 2., 3., 1., 1., 0., 0., 0., 1., 0., 1., 2., 5., 0., 4., 0., 1., 0., 0., 0., 0., 0., 0., 0., 5 [...]
+
+7., 1., 0., 7., 16., 0., 13., 1., 10., 51., 1., 5., 46., 1., 8., 3., 0., 4., 62., 12., 5., 65., 22., 74., 11., 2., 0., 0., 2., 3., 13., 10., 49., 17., 0., 37., 43., 14., 6., 0., 1., 7., 1., 29., 3., 21., 9., 12., 5., 3., 1., 0., 8., 3., 16., 11., 15., 2., 9., 4., 7., 27., 8., 9., 1., 0., 11., 8., 11., 1., 10., 2., 3., 2., 0., 0., 0., 4., 2., 17., 10., 3., 6., 1., 2., 0., 0., 0., 0., 0., 8., 2., 4., 0., 3., 2., 1., 0., 2., 0., 0., 0., 0., 1., 1., 0., 4., 0., 1., 0., 0., 0., 0., 0., 2., 0. [...]
+
+11., 0., 1., 4., 8., 1., 11., 1., 8., 15., 0., 22., 18., 0., 16., 4., 0., 2., 19., 2., 4., 24., 12., 17., 27., 6., 1., 1., 4., 2., 5., 8., 29., 14., 3., 14., 3., 11., 17., 5., 0., 7., 3., 9., 8., 13., 50., 6., 22., 16., 3., 0., 5., 1., 8., 2., 6., 6., 9., 19., 10., 17., 15., 1., 2., 0., 2., 0., 7., 4., 6., 4., 4., 1., 3., 8., 2., 0., 0., 5., 1., 0., 2., 1., 4., 7., 4., 4., 3., 3., 4., 2., 0., 0., 2., 7., 4., 0., 3., 1., 1., 0., 1., 2., 0., 0., 1., 0., 0., 0., 0., 3., 0., 0., 2., 0., 0.,  [...]
+
+10., 1., 4., 3., 7., 3., 3., 0., 5., 19., 3., 11., 19., 1., 13., 3., 2., 2., 15., 4., 2., 30., 13., 25., 39., 4., 1., 3., 5., 3., 8., 4., 21., 20., 3., 15., 4., 13., 7., 2., 0., 1., 0., 11., 8., 16., 59., 21., 24., 12., 5., 5., 5., 4., 5., 5., 13., 5., 8., 16., 5., 22., 9., 5., 1., 2., 4., 0., 2., 2., 3., 4., 4., 2., 1., 1., 2., 0., 3., 5., 4., 0., 4., 5., 2., 7., 3., 2., 3., 0., 6., 0., 0., 2., 1., 5., 3., 0., 0., 2., 2., 5., 2., 3., 2., 2., 5., 0., 0., 0., 0., 2., 0., 0., 1., 0., 0., 0 [...]
+
+2., 0., 4., 3., 9., 8., 2., 0., 5., 30., 2., 16., 22., 1., 12., 1., 1., 1., 16., 0., 1., 31., 13., 27., 36., 4., 0., 0., 4., 2., 10., 10., 22., 15., 3., 12., 1., 9., 9., 1., 1., 3., 3., 8., 11., 20., 47., 9., 12., 8., 6., 0., 2., 2., 8., 3., 11., 6., 5., 11., 6., 25., 9., 2., 1., 0., 7., 0., 2., 2., 11., 4., 2., 5., 3., 4., 4., 1., 1., 4., 0., 0., 2., 0., 0., 3., 0., 3., 6., 0., 3., 2., 2., 0., 1., 8., 0., 0., 1., 0., 0., 3., 4., 0., 2., 0., 2., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0. [...]
+
+8., 0., 2., 3., 6., 0., 6., 5., 5., 23., 0., 9., 19., 0., 9., 6., 2., 3., 22., 4., 1., 38., 10., 9., 23., 5., 0., 1., 0., 5., 8., 3., 31., 22., 1., 13., 4., 16., 7., 2., 3., 6., 1., 11., 4., 17., 51., 11., 20., 11., 4., 0., 6., 4., 7., 6., 9., 7., 5., 17., 6., 22., 8., 6., 1., 1., 6., 2., 2., 1., 10., 0., 5., 4., 1., 4., 4., 3., 0., 1., 1., 0., 3., 5., 4., 6., 4., 9., 2., 3., 4., 0., 2., 1., 2., 6., 3., 0., 2., 3., 2., 0., 1., 2., 0., 2., 2., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 0., 1 [...]
+
+6., 1., 2., 4., 9., 2., 3., 2., 4., 32., 1., 8., 17., 2., 21., 2., 1., 3., 31., 3., 2., 15., 13., 22., 37., 5., 3., 0., 2., 2., 5., 3., 26., 11., 2., 14., 3., 14., 7., 4., 0., 8., 3., 6., 13., 16., 58., 7., 18., 7., 4., 0., 8., 1., 8., 3., 17., 3., 3., 11., 5., 23., 7., 3., 1., 0., 4., 1., 1., 2., 8., 1., 8., 5., 0., 10., 2., 1., 1., 1., 0., 0., 2., 1., 3., 9., 4., 2., 3., 4., 4., 0., 3., 0., 1., 5., 2., 0., 3., 2., 3., 0., 3., 2., 1., 1., 2., 0., 0., 0., 0., 3., 0., 0., 1., 0., 0., 0.,  [...]
+
+6., 1., 4., 9., 9., 3., 4., 3., 4., 22., 0., 15., 19., 0., 16., 1., 0., 2., 11., 4., 3., 34., 17., 20., 30., 5., 0., 1., 3., 1., 11., 3., 20., 17., 1., 11., 7., 14., 11., 4., 0., 3., 2., 20., 8., 10., 56., 12., 19., 7., 6., 2., 7., 0., 6., 3., 15., 2., 7., 19., 4., 24., 9., 3., 1., 3., 4., 0., 4., 1., 6., 4., 5., 6., 0., 2., 1., 0., 2., 1., 4., 0., 2., 1., 2., 4., 3., 1., 5., 0., 3., 0., 4., 1., 1., 7., 1., 0., 1., 5., 2., 4., 1., 0., 3., 0., 2., 0., 0., 0., 0., 4., 0., 0., 3., 0., 0., 0 [...]
+
+9., 0., 0., 3., 11., 1., 8., 0., 4., 20., 0., 10., 22., 1., 15., 2., 2., 0., 18., 2., 5., 14., 15., 28., 29., 6., 0., 0., 2., 2., 11., 10., 21., 13., 4., 15., 1., 13., 12., 6., 0., 5., 2., 20., 9., 18., 46., 6., 31., 8., 4., 1., 11., 6., 9., 3., 11., 5., 4., 10., 11., 27., 12., 2., 0., 1., 3., 2., 1., 1., 3., 1., 0., 6., 2., 5., 2., 2., 0., 4., 3., 0., 1., 1., 0., 6., 0., 5., 5., 1., 5., 0., 1., 0., 1., 12., 3., 0., 1., 5., 2., 2., 4., 1., 0., 1., 3., 0., 0., 0., 0., 1., 0., 0., 4., 0.,  [...]
+
+13., 1., 4., 2., 9., 2., 7., 1., 11., 5., 2., 11., 37., 3., 14., 3., 1., 0., 10., 3., 3., 21., 15., 31., 18., 6., 4., 0., 8., 1., 8., 6., 33., 18., 4., 19., 6., 15., 8., 2., 2., 4., 3., 12., 15., 21., 49., 19., 24., 6., 1., 0., 5., 4., 6., 3., 7., 5., 7., 14., 2., 27., 6., 2., 0., 3., 8., 1., 5., 2., 3., 4., 5., 1., 0., 2., 3., 3., 0., 2., 3., 0., 2., 2., 3., 4., 3., 6., 2., 3., 3., 1., 1., 2., 3., 2., 4., 0., 2., 2., 3., 1., 1., 1., 2., 1., 0., 0., 0., 0., 0., 2., 0., 0., 5., 0., 0., 0. [...]
+
+7., 1., 5., 4., 9., 3., 6., 1., 12., 20., 0., 9., 14., 0., 10., 4., 1., 2., 15., 1., 1., 29., 15., 14., 32., 6., 1., 2., 3., 2., 9., 3., 36., 13., 1., 17., 8., 12., 10., 3., 1., 2., 2., 13., 9., 14., 49., 3., 14., 9., 3., 1., 8., 2., 8., 2., 13., 6., 5., 19., 11., 21., 8., 3., 2., 1., 7., 1., 6., 3., 5., 3., 5., 10., 1., 5., 4., 2., 1., 1., 5., 0., 2., 1., 1., 12., 1., 6., 7., 2., 4., 0., 5., 0., 1., 9., 0., 0., 2., 3., 0., 3., 2., 1., 3., 0., 1., 0., 0., 0., 0., 2., 0., 0., 2., 0., 0.,  [...]
+
+18., 1., 1., 5., 19., 0., 16., 1., 7., 41., 1., 7., 45., 3., 2., 5., 0., 4., 66., 8., 6., 72., 16., 79., 11., 5., 0., 0., 4., 2., 26., 9., 49., 11., 1., 44., 28., 18., 6., 0., 0., 5., 4., 12., 5., 24., 6., 12., 6., 5., 2., 0., 11., 3., 7., 10., 18., 2., 5., 1., 2., 37., 13., 6., 2., 0., 10., 5., 16., 3., 14., 4., 4., 2., 2., 3., 0., 5., 3., 13., 10., 2., 5., 1., 3., 0., 0., 0., 0., 0., 10., 1., 8., 4., 2., 1., 0., 0., 0., 0., 4., 0., 3., 1., 1., 0., 1., 0., 2., 0., 0., 0., 0., 0., 2., 0. [...]
+
+9., 0., 0., 2., 13., 0., 5., 1., 3., 56., 0., 10., 61., 2., 5., 7., 0., 0., 75., 7., 9., 72., 16., 74., 13., 3., 0., 1., 2., 1., 17., 14., 60., 15., 1., 41., 27., 11., 6., 0., 1., 5., 2., 33., 9., 26., 12., 11., 5., 3., 3., 0., 10., 4., 17., 8., 19., 1., 9., 4., 5., 51., 10., 3., 2., 0., 9., 4., 10., 1., 10., 1., 3., 2., 2., 1., 0., 5., 2., 14., 5., 2., 0., 0., 4., 0., 0., 0., 0., 0., 5., 2., 2., 4., 2., 1., 0., 0., 2., 0., 0., 0., 2., 2., 7., 0., 1., 0., 3., 0., 0., 0., 0., 0., 1., 0.,  [...]
+
+8., 2., 2., 4., 12., 0., 14., 3., 9., 46., 1., 3., 56., 1., 8., 1., 0., 2., 68., 14., 11., 80., 11., 80., 12., 1., 0., 1., 1., 1., 13., 14., 53., 10., 1., 32., 26., 9., 5., 0., 0., 5., 7., 15., 3., 23., 4., 8., 5., 4., 3., 0., 10., 2., 9., 3., 20., 0., 5., 6., 3., 36., 8., 10., 1., 0., 11., 5., 7., 0., 8., 2., 5., 4., 1., 0., 0., 7., 3., 20., 6., 7., 2., 5., 4., 0., 0., 0., 0., 0., 5., 2., 5., 3., 4., 2., 1., 0., 1., 0., 1., 0., 0., 2., 1., 0., 0., 0., 2., 0., 4., 0., 0., 0., 1., 0., 2., [...]
+
+9., 0., 1., 2., 7., 0., 14., 1., 6., 45., 1., 10., 55., 0., 2., 6., 0., 0., 71., 13., 12., 53., 17., 87., 13., 7., 0., 0., 4., 2., 11., 6., 49., 17., 0., 33., 29., 18., 3., 0., 0., 4., 5., 28., 7., 37., 6., 15., 7., 0., 1., 0., 10., 5., 14., 5., 17., 0., 10., 4., 5., 37., 6., 6., 2., 0., 14., 3., 4., 2., 8., 3., 2., 2., 2., 1., 0., 5., 2., 13., 16., 8., 4., 3., 3., 0., 0., 0., 0., 0., 8., 1., 3., 2., 3., 1., 1., 0., 0., 0., 1., 0., 2., 1., 3., 0., 0., 0., 1., 0., 2., 0., 0., 0., 1., 0.,  [...]
+
+14., 1., 3., 4., 15., 0., 13., 0., 11., 59., 2., 9., 54., 1., 3., 5., 0., 2., 61., 5., 12., 71., 12., 87., 11., 2., 0., 0., 3., 2., 15., 7., 46., 11., 1., 47., 35., 14., 5., 0., 2., 4., 2., 21., 7., 25., 15., 14., 6., 2., 2., 0., 10., 6., 18., 11., 9., 5., 11., 0., 1., 35., 5., 6., 6., 0., 9., 3., 4., 1., 13., 3., 1., 0., 1., 3., 0., 7., 5., 18., 11., 3., 1., 3., 3., 0., 0., 0., 0., 0., 14., 1., 1., 1., 2., 1., 1., 0., 1., 0., 1., 0., 2., 6., 1., 0., 2., 0., 0., 0., 0., 0., 0., 0., 1., 0 [...]
+
+9., 1., 4., 3., 13., 0., 10., 3., 4., 54., 1., 10., 57., 1., 2., 4., 0., 1., 70., 11., 12., 69., 15., 89., 7., 5., 0., 0., 4., 0., 14., 11., 39., 7., 1., 38., 20., 18., 9., 0., 2., 5., 2., 21., 12., 26., 8., 16., 7., 4., 0., 0., 12., 7., 15., 8., 14., 0., 7., 3., 3., 39., 16., 8., 5., 0., 17., 2., 5., 1., 14., 0., 7., 0., 0., 0., 0., 4., 1., 19., 8., 2., 2., 1., 4., 0., 0., 0., 0., 0., 9., 0., 5., 4., 4., 0., 1., 0., 1., 0., 1., 0., 0., 3., 1., 0., 2., 0., 1., 0., 0., 0., 0., 0., 1., 0., [...]
+
+12., 1., 1., 3., 7., 0., 12., 3., 9., 45., 0., 6., 47., 2., 2., 3., 0., 1., 74., 12., 6., 66., 11., 80., 16., 7., 0., 2., 3., 3., 12., 10., 42., 14., 0., 37., 40., 14., 5., 0., 2., 7., 2., 18., 8., 25., 7., 15., 8., 2., 5., 0., 7., 5., 12., 4., 13., 1., 6., 1., 4., 48., 13., 8., 5., 0., 13., 5., 10., 4., 10., 3., 4., 0., 1., 0., 0., 2., 2., 21., 5., 3., 5., 0., 5., 0., 0., 0., 0., 0., 7., 3., 3., 5., 1., 2., 0., 0., 0., 0., 1., 0., 0., 4., 1., 0., 3., 0., 1., 0., 0., 0., 0., 0., 0., 0.,  [...]
+
+6., 3., 2., 3., 14., 0., 15., 1., 6., 29., 0., 9., 64., 0., 3., 4., 0., 1., 75., 10., 10., 68., 16., 86., 16., 5., 0., 0., 4., 1., 14., 12., 58., 12., 2., 35., 46., 18., 4., 0., 0., 6., 2., 23., 8., 25., 8., 4., 7., 3., 3., 0., 15., 3., 17., 3., 10., 4., 10., 1., 3., 24., 16., 8., 1., 0., 13., 1., 7., 0., 12., 7., 1., 2., 1., 0., 0., 3., 3., 13., 7., 6., 7., 2., 0., 0., 0., 0., 0., 0., 10., 3., 3., 2., 3., 0., 1., 0., 0., 0., 2., 0., 1., 0., 1., 0., 1., 0., 0., 0., 2., 0., 0., 0., 0., 0. [...]
+
+10., 2., 2., 2., 4., 0., 17., 0., 3., 38., 1., 6., 51., 0., 4., 5., 0., 4., 55., 9., 9., 72., 15., 84., 17., 4., 0., 0., 5., 4., 14., 8., 53., 13., 5., 46., 38., 14., 2., 0., 0., 6., 2., 37., 9., 30., 7., 12., 8., 2., 1., 0., 10., 4., 20., 5., 17., 2., 10., 6., 3., 34., 8., 5., 3., 0., 14., 2., 6., 1., 15., 2., 6., 2., 0., 2., 0., 4., 0., 10., 11., 0., 5., 0., 0., 0., 0., 0., 0., 0., 6., 0., 3., 2., 8., 2., 1., 0., 0., 0., 1., 0., 1., 5., 1., 0., 2., 0., 1., 0., 2., 0., 0., 0., 0., 0., 0 [...]
+
+12., 1., 0., 5., 15., 0., 17., 1., 3., 48., 2., 8., 68., 0., 8., 3., 0., 3., 83., 6., 8., 66., 22., 76., 14., 2., 0., 0., 5., 1., 17., 13., 41., 12., 3., 37., 39., 8., 4., 0., 2., 3., 1., 19., 7., 27., 5., 10., 4., 5., 1., 0., 14., 0., 25., 6., 19., 5., 10., 3., 6., 31., 6., 8., 1., 0., 13., 3., 12., 2., 10., 2., 5., 0., 1., 1., 0., 7., 2., 12., 5., 1., 2., 0., 2., 0., 0., 0., 0., 0., 6., 2., 4., 2., 4., 0., 0., 0., 1., 0., 0., 0., 0., 2., 2., 0., 1., 0., 1., 0., 2., 0., 0., 0., 1., 0.,  [...]
+
+17., 0., 3., 4., 21., 0., 14., 4., 6., 54., 3., 4., 77., 2., 4., 2., 0., 1., 75., 9., 8., 65., 14., 85., 8., 5., 0., 0., 2., 2., 20., 8., 58., 9., 0., 38., 27., 10., 3., 0., 2., 5., 3., 29., 7., 17., 6., 8., 7., 3., 5., 0., 4., 3., 9., 4., 21., 5., 3., 1., 3., 31., 8., 7., 2., 0., 14., 1., 13., 4., 7., 1., 4., 2., 2., 2., 0., 5., 5., 13., 10., 3., 4., 1., 3., 0., 0., 0., 0., 0., 21., 1., 1., 2., 1., 2., 0., 0., 2., 0., 0., 0., 0., 5., 3., 0., 2., 0., 2., 0., 0., 0., 0., 0., 1., 0., 2., 5 [...]
+
+9., 1., 1., 6., 15., 0., 23., 1., 4., 56., 1., 6., 58., 0., 8., 4., 0., 2., 74., 9., 8., 73., 5., 62., 17., 1., 0., 1., 4., 3., 15., 8., 58., 19., 3., 52., 27., 23., 4., 0., 1., 7., 5., 23., 0., 26., 4., 5., 8., 3., 1., 0., 8., 5., 14., 4., 20., 1., 11., 2., 7., 51., 10., 7., 1., 0., 14., 3., 5., 0., 14., 1., 4., 0., 1., 0., 0., 6., 4., 17., 10., 4., 5., 2., 5., 0., 0., 0., 0., 0., 5., 3., 4., 0., 4., 1., 1., 0., 1., 0., 0., 0., 1., 4., 4., 0., 0., 0., 1., 0., 1., 0., 0., 0., 3., 0., 0., [...]
+
+7., 1., 3., 6., 13., 0., 14., 3., 9., 49., 0., 10., 50., 0., 10., 1., 0., 0., 67., 19., 7., 81., 13., 72., 12., 0., 0., 5., 1., 2., 14., 13., 65., 7., 1., 52., 30., 11., 10., 0., 1., 9., 1., 23., 4., 26., 10., 13., 4., 4., 1., 0., 6., 5., 17., 4., 16., 2., 10., 7., 2., 38., 13., 6., 1., 0., 14., 2., 8., 1., 9., 1., 6., 0., 0., 1., 0., 4., 3., 25., 8., 3., 8., 2., 5., 0., 0., 0., 0., 0., 10., 3., 5., 3., 3., 1., 2., 0., 3., 0., 3., 0., 0., 2., 3., 0., 2., 0., 0., 0., 2., 0., 0., 0., 1., 0 [...]
+
+9., 0., 0., 4., 14., 0., 13., 0., 4., 53., 1., 6., 56., 1., 5., 0., 0., 4., 75., 7., 13., 73., 7., 95., 18., 6., 0., 1., 4., 4., 16., 8., 48., 14., 5., 41., 45., 10., 4., 0., 1., 3., 4., 23., 6., 36., 12., 11., 6., 4., 2., 0., 12., 4., 10., 5., 31., 3., 12., 2., 4., 34., 11., 10., 2., 0., 13., 2., 4., 3., 6., 1., 1., 0., 1., 2., 0., 5., 0., 17., 7., 3., 5., 1., 3., 0., 0., 0., 0., 0., 15., 1., 2., 2., 2., 0., 0., 0., 2., 0., 0., 0., 2., 5., 0., 0., 0., 0., 1., 0., 1., 0., 0., 0., 0., 0., [...]
+
+8., 2., 4., 3., 11., 0., 13., 2., 10., 55., 1., 8., 57., 1., 7., 2., 0., 3., 65., 10., 13., 74., 20., 66., 8., 7., 0., 1., 6., 2., 22., 6., 58., 11., 0., 40., 30., 19., 8., 0., 2., 3., 3., 17., 8., 18., 10., 13., 8., 4., 4., 0., 9., 6., 11., 6., 20., 4., 9., 5., 1., 32., 8., 13., 3., 0., 14., 2., 9., 6., 10., 1., 4., 1., 0., 0., 0., 4., 2., 17., 3., 2., 5., 1., 1., 0., 0., 0., 0., 0., 13., 1., 3., 0., 4., 1., 1., 0., 0., 0., 3., 0., 0., 3., 0., 0., 3., 0., 1., 0., 1., 0., 0., 0., 2., 0., [...]
+
+7., 2., 2., 3., 10., 0., 17., 1., 8., 44., 0., 8., 47., 2., 4., 3., 0., 2., 63., 6., 9., 78., 16., 80., 17., 5., 0., 1., 3., 3., 21., 3., 61., 16., 2., 42., 33., 17., 4., 0., 0., 7., 3., 19., 5., 22., 7., 7., 7., 2., 3., 0., 6., 6., 18., 3., 16., 5., 5., 6., 4., 30., 6., 12., 3., 0., 13., 4., 9., 2., 13., 1., 1., 2., 1., 1., 0., 8., 2., 14., 7., 1., 2., 2., 7., 0., 0., 0., 0., 0., 6., 2., 3., 0., 3., 0., 1., 0., 1., 0., 1., 0., 2., 2., 1., 0., 2., 0., 0., 0., 1., 0., 0., 0., 1., 0., 1.,  [...]
+
+10., 1., 1., 4., 16., 0., 13., 1., 4., 57., 2., 5., 65., 0., 5., 2., 0., 0., 62., 7., 9., 69., 16., 87., 8., 3., 0., 0., 5., 3., 14., 9., 52., 15., 0., 29., 36., 13., 1., 0., 1., 5., 2., 26., 3., 15., 5., 10., 3., 7., 2., 0., 13., 5., 19., 5., 16., 1., 6., 3., 3., 31., 11., 9., 1., 0., 19., 7., 6., 2., 14., 3., 2., 0., 2., 0., 0., 6., 1., 22., 6., 0., 7., 1., 1., 0., 0., 0., 0., 0., 18., 3., 2., 0., 2., 0., 4., 0., 3., 0., 1., 0., 0., 3., 2., 0., 1., 0., 2., 0., 2., 0., 0., 0., 0., 0., 1 [...]
+
+6., 0., 4., 4., 12., 0., 9., 2., 9., 52., 2., 11., 44., 2., 2., 4., 0., 7., 66., 12., 8., 82., 15., 89., 11., 12., 0., 0., 6., 2., 10., 9., 43., 14., 2., 40., 34., 10., 6., 0., 2., 6., 2., 23., 4., 21., 14., 11., 8., 4., 1., 0., 15., 0., 13., 5., 17., 5., 6., 1., 4., 45., 8., 11., 2., 0., 14., 2., 11., 1., 10., 4., 7., 1., 0., 2., 0., 2., 1., 11., 4., 4., 4., 0., 2., 0., 0., 0., 0., 0., 2., 2., 2., 1., 1., 0., 0., 0., 0., 0., 0., 0., 3., 3., 1., 0., 0., 0., 0., 0., 1., 0., 0., 0., 1., 0. [...]
+
+13., 1., 1., 4., 4., 0., 11., 3., 8., 63., 0., 8., 54., 0., 1., 2., 0., 3., 82., 5., 10., 73., 17., 74., 16., 0., 0., 0., 4., 0., 13., 10., 63., 14., 0., 32., 30., 10., 9., 0., 0., 1., 3., 22., 3., 21., 7., 13., 10., 6., 2., 0., 9., 2., 27., 4., 23., 2., 12., 3., 1., 32., 13., 8., 2., 0., 15., 4., 12., 1., 8., 4., 4., 1., 0., 1., 0., 1., 2., 15., 12., 1., 3., 0., 2., 0., 0., 0., 0., 0., 10., 1., 5., 2., 2., 1., 2., 0., 4., 0., 0., 0., 3., 2., 2., 0., 2., 0., 2., 0., 1., 0., 0., 0., 1., 0 [...]
+
+9., 0., 2., 5., 11., 0., 11., 3., 5., 52., 2., 9., 68., 2., 8., 1., 0., 0., 79., 13., 7., 81., 14., 90., 11., 4., 0., 0., 5., 2., 16., 10., 51., 10., 3., 43., 32., 10., 6., 0., 3., 10., 4., 15., 9., 15., 2., 7., 6., 4., 2., 0., 7., 7., 18., 3., 12., 3., 11., 1., 2., 33., 11., 12., 2., 0., 15., 2., 19., 1., 5., 0., 1., 1., 0., 2., 0., 9., 1., 12., 9., 4., 3., 1., 4., 0., 0., 0., 0., 0., 4., 7., 5., 1., 2., 0., 3., 0., 1., 0., 1., 0., 0., 1., 3., 0., 2., 0., 2., 0., 1., 0., 0., 0., 2., 0., [...]
+
+12., 0., 3., 1., 13., 0., 19., 1., 4., 40., 3., 4., 64., 3., 4., 0., 0., 2., 82., 6., 7., 74., 13., 90., 10., 1., 0., 2., 3., 3., 16., 17., 64., 12., 1., 41., 30., 14., 4., 0., 0., 4., 2., 19., 7., 23., 5., 8., 8., 1., 0., 0., 10., 4., 14., 4., 15., 3., 10., 5., 2., 29., 13., 1., 4., 0., 10., 2., 5., 5., 10., 0., 4., 1., 4., 1., 0., 5., 0., 19., 7., 3., 4., 1., 4., 0., 0., 0., 0., 0., 5., 2., 0., 1., 4., 2., 2., 0., 0., 0., 1., 0., 0., 2., 0., 0., 0., 0., 2., 0., 1., 0., 0., 0., 2., 0.,  [...]
+
+6., 3., 1., 5., 15., 0., 12., 1., 7., 47., 0., 10., 51., 3., 5., 2., 0., 1., 74., 9., 4., 73., 23., 90., 8., 2., 0., 2., 0., 1., 13., 11., 48., 13., 2., 29., 37., 15., 1., 0., 1., 8., 6., 25., 4., 23., 11., 14., 11., 2., 6., 0., 9., 7., 15., 3., 22., 4., 3., 0., 0., 30., 10., 6., 2., 0., 9., 3., 7., 1., 11., 6., 5., 0., 1., 0., 0., 5., 4., 16., 11., 1., 5., 0., 2., 0., 0., 0., 0., 0., 9., 2., 4., 2., 3., 1., 0., 0., 0., 0., 1., 0., 1., 1., 3., 0., 0., 0., 1., 0., 1., 0., 0., 0., 1., 0.,  [...]
+
+10., 1., 2., 5., 8., 0., 11., 4., 6., 64., 1., 4., 59., 0., 4., 1., 0., 1., 59., 8., 8., 67., 19., 74., 10., 3., 0., 0., 3., 2., 13., 9., 56., 7., 1., 53., 37., 17., 2., 0., 2., 10., 1., 23., 2., 15., 7., 10., 8., 1., 1., 0., 10., 3., 22., 5., 16., 3., 6., 5., 5., 37., 5., 8., 0., 0., 18., 4., 7., 0., 5., 1., 3., 1., 1., 1., 0., 4., 3., 9., 9., 1., 4., 6., 3., 0., 0., 0., 0., 0., 11., 0., 5., 0., 4., 3., 2., 0., 0., 0., 1., 0., 1., 3., 2., 0., 2., 0., 4., 0., 2., 0., 0., 0., 2., 0., 0.,  [...]
+
+12., 2., 2., 2., 9., 4., 4., 0., 1., 13., 1., 15., 27., 1., 12., 4., 1., 0., 20., 1., 4., 16., 14., 17., 20., 4., 0., 0., 2., 0., 10., 7., 23., 18., 5., 13., 3., 16., 5., 1., 1., 5., 3., 11., 14., 28., 38., 11., 28., 16., 2., 2., 7., 2., 2., 2., 5., 9., 6., 15., 4., 17., 3., 3., 1., 1., 5., 2., 5., 3., 4., 6., 2., 7., 1., 1., 4., 2., 0., 0., 2., 0., 0., 2., 1., 3., 3., 0., 1., 2., 2., 1., 2., 0., 0., 8., 2., 0., 2., 3., 3., 2., 0., 1., 0., 1., 3., 0., 0., 0., 0., 6., 0., 0., 1., 0., 0.,  [...]
+
+7., 1., 3., 3., 8., 3., 6., 0., 3., 35., 1., 12., 24., 1., 12., 3., 0., 1., 15., 2., 5., 31., 7., 21., 32., 6., 3., 2., 3., 4., 7., 11., 20., 14., 3., 15., 2., 16., 9., 4., 0., 7., 1., 11., 14., 16., 44., 6., 28., 11., 6., 2., 2., 2., 7., 4., 16., 4., 3., 10., 5., 18., 7., 1., 0., 1., 14., 0., 1., 1., 8., 3., 4., 5., 1., 3., 3., 3., 3., 0., 2., 0., 0., 0., 2., 4., 3., 5., 4., 3., 5., 1., 4., 0., 2., 4., 3., 0., 1., 6., 4., 3., 3., 4., 2., 1., 0., 0., 0., 0., 0., 2., 0., 0., 3., 0., 0., 0 [...]
+
+10., 1., 1., 4., 4., 4., 7., 1., 7., 23., 2., 13., 25., 1., 9., 2., 2., 5., 15., 2., 5., 9., 8., 31., 27., 5., 1., 1., 2., 2., 12., 5., 28., 17., 2., 13., 3., 15., 8., 4., 2., 2., 2., 15., 12., 15., 41., 10., 27., 10., 7., 1., 3., 3., 3., 1., 16., 10., 8., 15., 6., 17., 9., 3., 3., 3., 4., 0., 4., 0., 7., 2., 1., 2., 0., 4., 1., 0., 0., 4., 2., 0., 4., 1., 1., 2., 2., 4., 2., 2., 4., 0., 3., 0., 2., 10., 1., 0., 3., 1., 2., 1., 3., 3., 3., 1., 0., 0., 0., 0., 0., 3., 0., 0., 4., 0., 0.,  [...]
+
+7., 0., 2., 4., 12., 2., 2., 0., 4., 19., 1., 6., 15., 1., 13., 2., 0., 2., 7., 1., 2., 29., 17., 22., 25., 4., 2., 1., 5., 4., 12., 5., 24., 16., 5., 20., 1., 18., 11., 0., 1., 3., 5., 7., 10., 28., 50., 11., 13., 11., 4., 0., 5., 3., 2., 0., 13., 15., 7., 16., 4., 16., 6., 2., 1., 2., 3., 1., 4., 2., 6., 1., 4., 4., 2., 2., 2., 4., 0., 2., 1., 0., 5., 0., 2., 6., 1., 4., 2., 3., 3., 1., 4., 0., 1., 3., 1., 0., 4., 1., 1., 5., 1., 3., 4., 1., 3., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0.,  [...]
+
+7., 0., 0., 4., 4., 2., 8., 3., 6., 30., 0., 18., 21., 1., 14., 4., 1., 2., 15., 4., 4., 21., 14., 28., 34., 2., 0., 0., 3., 3., 9., 7., 14., 13., 1., 17., 5., 15., 8., 3., 1., 1., 3., 13., 13., 17., 38., 14., 16., 9., 3., 0., 1., 3., 4., 4., 16., 9., 5., 10., 8., 24., 5., 3., 0., 1., 7., 2., 4., 3., 9., 3., 4., 7., 2., 1., 2., 2., 0., 3., 3., 0., 0., 4., 3., 6., 2., 7., 1., 4., 3., 3., 4., 2., 2., 6., 2., 0., 5., 3., 1., 0., 1., 7., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 5., 0., 0., 0. [...]
+
+9., 3., 0., 4., 10., 5., 8., 1., 4., 22., 0., 11., 17., 1., 17., 3., 1., 2., 27., 0., 6., 30., 13., 23., 29., 7., 0., 0., 1., 0., 6., 3., 24., 11., 5., 8., 5., 12., 11., 0., 0., 2., 5., 10., 13., 22., 39., 8., 21., 12., 2., 3., 3., 2., 12., 3., 6., 6., 5., 15., 12., 21., 6., 1., 2., 0., 7., 0., 2., 1., 7., 5., 5., 5., 2., 4., 2., 2., 2., 3., 3., 0., 4., 1., 1., 4., 2., 5., 4., 2., 4., 1., 5., 0., 1., 7., 2., 0., 2., 5., 1., 2., 5., 1., 2., 1., 1., 0., 0., 0., 0., 4., 0., 0., 4., 0., 0.,  [...]
+
+14., 1., 2., 2., 13., 0., 14., 1., 8., 46., 0., 6., 48., 0., 4., 2., 0., 2., 54., 9., 9., 83., 12., 84., 8., 5., 0., 1., 2., 4., 12., 7., 64., 15., 0., 31., 31., 17., 5., 0., 1., 5., 3., 37., 6., 22., 9., 9., 4., 4., 3., 0., 13., 4., 15., 3., 12., 6., 7., 6., 4., 33., 6., 5., 1., 0., 13., 2., 9., 3., 14., 2., 6., 0., 0., 1., 0., 3., 3., 16., 15., 4., 5., 1., 3., 0., 0., 0., 0., 0., 10., 3., 1., 1., 1., 0., 3., 0., 1., 0., 0., 0., 1., 4., 2., 0., 0., 0., 1., 0., 3., 0., 0., 0., 3., 0., 0. [...]
+
+8., 3., 3., 7., 10., 0., 13., 2., 5., 58., 1., 10., 63., 0., 10., 3., 0., 4., 72., 8., 9., 100., 8., 83., 14., 2., 0., 1., 4., 3., 13., 12., 55., 13., 3., 39., 30., 16., 5., 0., 0., 9., 1., 21., 7., 18., 5., 13., 7., 1., 0., 0., 7., 4., 21., 6., 16., 3., 3., 5., 5., 34., 1., 7., 5., 0., 11., 3., 10., 3., 7., 2., 4., 1., 3., 1., 0., 6., 0., 15., 6., 6., 4., 0., 3., 0., 0., 0., 0., 0., 11., 2., 1., 1., 2., 1., 0., 0., 1., 0., 0., 0., 1., 0., 1., 0., 2., 0., 1., 0., 3., 0., 0., 0., 0., 0.,  [...]
+
+8., 0., 1., 7., 8., 0., 13., 1., 4., 55., 1., 7., 62., 1., 5., 2., 0., 2., 72., 16., 10., 68., 21., 88., 12., 2., 0., 0., 4., 2., 13., 10., 65., 14., 1., 41., 25., 8., 9., 0., 0., 10., 5., 16., 4., 22., 4., 15., 5., 3., 1., 0., 5., 7., 6., 3., 15., 1., 7., 4., 0., 41., 8., 7., 2., 0., 15., 1., 4., 0., 19., 0., 6., 1., 2., 2., 0., 8., 2., 20., 9., 0., 1., 0., 4., 0., 0., 0., 0., 0., 11., 1., 1., 2., 6., 1., 2., 0., 0., 0., 0., 0., 0., 7., 2., 0., 1., 0., 0., 0., 0., 0., 0., 0., 2., 0., 1. [...]
+
+11., 4., 1., 7., 15., 0., 16., 1., 10., 66., 0., 12., 48., 0., 2., 2., 0., 1., 54., 9., 6., 64., 11., 71., 14., 4., 0., 3., 2., 0., 9., 9., 48., 11., 1., 32., 27., 15., 5., 0., 0., 8., 2., 32., 7., 19., 3., 12., 3., 1., 1., 0., 11., 3., 20., 5., 19., 5., 6., 5., 6., 34., 5., 8., 2., 0., 11., 5., 7., 3., 10., 2., 3., 0., 1., 0., 0., 4., 3., 20., 14., 5., 7., 2., 4., 0., 0., 0., 0., 0., 6., 4., 6., 3., 4., 1., 1., 0., 1., 0., 0., 0., 1., 6., 2., 0., 0., 0., 1., 0., 1., 0., 0., 0., 1., 0.,  [...]
+
+17., 0., 1., 6., 13., 0., 15., 0., 3., 47., 0., 8., 54., 1., 7., 1., 0., 0., 67., 11., 6., 80., 15., 82., 13., 3., 0., 0., 3., 2., 27., 12., 55., 13., 1., 51., 26., 17., 6., 0., 1., 1., 1., 24., 4., 19., 7., 10., 5., 4., 2., 0., 7., 5., 22., 7., 15., 0., 7., 2., 0., 42., 5., 5., 3., 0., 10., 3., 4., 2., 10., 2., 3., 2., 0., 1., 0., 7., 3., 11., 7., 1., 4., 1., 5., 0., 0., 0., 0., 0., 9., 3., 4., 3., 1., 3., 3., 0., 1., 0., 0., 0., 1., 4., 4., 0., 2., 0., 1., 0., 2., 0., 0., 0., 2., 0., 2 [...]
+
+9., 0., 2., 4., 14., 0., 16., 1., 5., 39., 2., 7., 71., 0., 2., 0., 0., 2., 56., 6., 3., 74., 11., 89., 15., 1., 0., 0., 5., 1., 14., 12., 50., 8., 3., 57., 44., 20., 3., 0., 1., 12., 5., 19., 12., 23., 3., 12., 9., 3., 1., 0., 7., 5., 25., 8., 18., 1., 9., 3., 4., 41., 8., 6., 2., 0., 14., 1., 8., 1., 11., 3., 6., 1., 1., 2., 0., 6., 1., 12., 9., 3., 3., 2., 5., 0., 0., 0., 0., 0., 5., 6., 4., 1., 3., 1., 4., 0., 1., 0., 0., 0., 0., 2., 2., 0., 2., 0., 0., 0., 3., 0., 0., 0., 1., 0., 2. [...]
+
+10., 2., 1., 3., 11., 0., 10., 1., 7., 48., 0., 10., 42., 1., 6., 2., 0., 0., 69., 9., 7., 95., 12., 107., 10., 3., 0., 3., 6., 3., 17., 8., 54., 13., 0., 45., 39., 19., 5., 0., 0., 7., 9., 11., 6., 27., 6., 14., 5., 6., 1., 0., 6., 6., 14., 4., 11., 3., 14., 0., 1., 40., 9., 5., 4., 0., 14., 4., 9., 0., 19., 2., 6., 2., 1., 0., 0., 2., 3., 18., 6., 4., 4., 0., 0., 0., 0., 0., 0., 0., 5., 5., 1., 1., 4., 2., 2., 0., 0., 0., 2., 0., 3., 3., 2., 0., 6., 0., 0., 0., 1., 0., 0., 0., 3., 0.,  [...]
+
+10., 0., 1., 2., 7., 0., 10., 0., 4., 41., 0., 10., 47., 2., 6., 5., 0., 0., 71., 4., 7., 70., 12., 64., 10., 2., 0., 0., 1., 2., 15., 12., 48., 10., 2., 46., 31., 8., 11., 0., 2., 3., 5., 23., 4., 29., 15., 13., 10., 2., 1., 0., 10., 5., 20., 5., 18., 3., 6., 3., 2., 32., 7., 5., 2., 0., 16., 3., 6., 3., 6., 2., 4., 0., 0., 1., 0., 6., 3., 13., 16., 3., 4., 1., 3., 0., 0., 0., 0., 0., 5., 2., 2., 2., 3., 0., 1., 0., 3., 0., 3., 0., 1., 2., 3., 0., 2., 0., 1., 0., 0., 0., 0., 0., 1., 0., [...]
+
+7., 0., 2., 3., 14., 0., 14., 6., 4., 54., 1., 8., 75., 2., 2., 2., 0., 3., 64., 11., 11., 87., 13., 87., 8., 7., 0., 2., 5., 3., 16., 11., 73., 8., 4., 47., 29., 12., 6., 0., 0., 2., 2., 25., 10., 26., 11., 14., 6., 4., 3., 0., 7., 2., 13., 1., 20., 3., 6., 2., 2., 41., 5., 5., 3., 0., 13., 3., 8., 1., 16., 2., 2., 0., 2., 2., 0., 3., 2., 9., 7., 6., 7., 1., 2., 0., 0., 0., 0., 0., 4., 2., 4., 1., 4., 2., 0., 0., 1., 0., 1., 0., 2., 0., 0., 0., 1., 0., 0., 0., 2., 0., 0., 0., 1., 0., 0. [...]
+
+14., 1., 2., 3., 10., 0., 12., 1., 3., 49., 2., 12., 53., 1., 5., 2., 0., 5., 73., 11., 6., 74., 9., 100., 7., 4., 0., 1., 2., 3., 13., 10., 39., 9., 3., 32., 39., 16., 6., 0., 1., 6., 5., 23., 8., 18., 13., 8., 13., 3., 3., 0., 7., 6., 12., 6., 13., 3., 6., 5., 4., 36., 14., 10., 2., 0., 10., 4., 7., 3., 20., 3., 3., 0., 3., 1., 0., 7., 4., 17., 14., 3., 6., 2., 0., 0., 0., 0., 0., 0., 6., 3., 3., 2., 2., 2., 0., 0., 1., 0., 0., 0., 2., 3., 2., 0., 3., 0., 0., 0., 2., 0., 0., 0., 1., 0. [...]
+
+8., 1., 1., 9., 14., 0., 21., 1., 9., 33., 0., 15., 78., 1., 7., 2., 0., 3., 63., 10., 11., 77., 12., 68., 9., 2., 0., 1., 4., 1., 13., 13., 50., 9., 3., 43., 31., 11., 4., 0., 1., 5., 4., 26., 6., 26., 10., 10., 7., 4., 4., 0., 12., 4., 11., 5., 12., 4., 3., 5., 1., 44., 5., 7., 4., 0., 17., 6., 7., 1., 7., 3., 7., 1., 1., 1., 0., 3., 2., 10., 10., 2., 4., 1., 3., 0., 0., 0., 0., 0., 9., 2., 2., 2., 5., 2., 1., 0., 0., 0., 0., 0., 2., 4., 2., 0., 2., 0., 1., 0., 2., 0., 0., 0., 0., 0.,  [...]
+
+7., 1., 4., 2., 10., 0., 13., 2., 6., 60., 1., 12., 57., 1., 4., 2., 0., 1., 82., 5., 8., 78., 16., 82., 11., 4., 0., 2., 3., 2., 18., 12., 54., 10., 4., 40., 34., 17., 3., 0., 0., 5., 7., 23., 8., 22., 11., 17., 4., 4., 2., 0., 12., 4., 15., 0., 11., 3., 9., 4., 3., 33., 7., 7., 3., 0., 12., 0., 8., 3., 8., 4., 6., 1., 2., 2., 0., 2., 2., 16., 10., 4., 2., 0., 2., 0., 0., 0., 0., 0., 5., 3., 3., 2., 2., 1., 0., 0., 2., 0., 3., 0., 0., 3., 0., 0., 4., 0., 2., 0., 1., 0., 0., 0., 3., 0.,  [...]
+
+6., 3., 5., 3., 6., 0., 17., 2., 10., 38., 2., 6., 59., 0., 12., 1., 0., 1., 68., 13., 9., 79., 13., 76., 15., 1., 0., 1., 3., 2., 14., 10., 35., 17., 2., 34., 34., 13., 3., 0., 1., 6., 2., 32., 8., 17., 12., 16., 6., 6., 0., 0., 17., 3., 24., 4., 19., 2., 8., 0., 7., 37., 7., 7., 3., 0., 13., 1., 7., 0., 6., 3., 5., 0., 2., 0., 0., 5., 1., 20., 11., 6., 3., 0., 3., 0., 0., 0., 0., 0., 11., 3., 2., 3., 1., 1., 2., 0., 0., 0., 0., 0., 2., 3., 2., 0., 1., 0., 1., 0., 2., 0., 0., 0., 2., 0. [...]
+
+6., 4., 1., 1., 12., 0., 13., 3., 6., 56., 3., 8., 47., 1., 3., 1., 0., 3., 81., 8., 4., 66., 17., 75., 11., 4., 0., 0., 5., 0., 20., 5., 48., 12., 2., 34., 21., 12., 3., 0., 1., 8., 7., 24., 8., 22., 10., 13., 7., 0., 2., 0., 13., 7., 24., 0., 8., 3., 5., 2., 2., 44., 10., 8., 1., 0., 12., 3., 5., 6., 18., 1., 4., 0., 0., 3., 0., 2., 1., 19., 2., 2., 3., 1., 6., 0., 0., 0., 0., 0., 13., 1., 3., 0., 2., 2., 1., 0., 0., 0., 1., 0., 0., 1., 2., 0., 1., 0., 1., 0., 1., 0., 0., 0., 1., 0., 1 [...]
+
+8., 2., 1., 0., 12., 0., 16., 3., 10., 58., 0., 4., 59., 3., 3., 0., 0., 3., 69., 8., 10., 68., 8., 98., 8., 3., 0., 1., 5., 4., 7., 9., 53., 7., 3., 34., 41., 12., 2., 0., 1., 8., 2., 18., 6., 17., 9., 15., 10., 2., 1., 0., 6., 5., 20., 6., 14., 3., 8., 0., 4., 40., 5., 4., 1., 0., 16., 4., 7., 3., 11., 2., 6., 2., 2., 2., 0., 1., 1., 21., 6., 2., 5., 4., 3., 0., 0., 0., 0., 0., 18., 2., 1., 3., 3., 1., 6., 0., 3., 0., 1., 0., 1., 4., 0., 0., 3., 0., 1., 0., 0., 0., 0., 0., 2., 0., 1.,  [...]
+
+11., 0., 1., 4., 14., 0., 12., 0., 4., 58., 2., 4., 54., 2., 5., 2., 0., 0., 68., 11., 7., 80., 13., 92., 13., 3., 0., 0., 1., 4., 13., 9., 50., 17., 2., 25., 32., 16., 6., 0., 0., 5., 2., 20., 6., 22., 4., 19., 7., 4., 0., 0., 11., 7., 16., 6., 9., 4., 11., 4., 4., 39., 5., 11., 2., 0., 17., 3., 8., 1., 7., 4., 3., 2., 1., 3., 0., 10., 0., 15., 4., 5., 3., 1., 0., 0., 0., 0., 0., 0., 3., 1., 2., 2., 2., 1., 5., 0., 3., 0., 0., 0., 2., 5., 0., 0., 2., 0., 1., 0., 0., 0., 0., 0., 0., 0.,  [...]
+
+7., 0., 1., 3., 10., 0., 17., 2., 5., 28., 0., 10., 62., 2., 4., 4., 0., 0., 73., 14., 6., 78., 13., 66., 18., 5., 0., 1., 3., 0., 15., 10., 57., 14., 2., 35., 35., 15., 6., 0., 0., 4., 5., 26., 6., 16., 9., 15., 8., 3., 1., 0., 9., 0., 23., 6., 11., 5., 4., 2., 6., 49., 7., 7., 0., 0., 11., 0., 3., 0., 15., 3., 5., 1., 2., 2., 0., 7., 4., 18., 7., 1., 2., 1., 6., 0., 0., 0., 0., 0., 5., 0., 5., 2., 9., 1., 1., 0., 1., 0., 0., 0., 1., 0., 2., 0., 1., 0., 0., 0., 2., 0., 0., 0., 3., 0., 2 [...]
+
+9., 2., 2., 2., 12., 0., 20., 2., 7., 55., 0., 13., 56., 2., 6., 1., 0., 4., 72., 9., 6., 71., 13., 91., 9., 0., 0., 0., 7., 3., 15., 10., 52., 7., 6., 41., 42., 17., 11., 0., 1., 3., 3., 23., 5., 28., 13., 14., 3., 4., 1., 0., 9., 4., 11., 2., 13., 3., 7., 5., 2., 29., 15., 12., 3., 0., 24., 6., 10., 1., 12., 0., 11., 1., 2., 1., 0., 6., 7., 10., 10., 4., 1., 0., 1., 0., 0., 0., 0., 0., 8., 3., 3., 3., 4., 2., 2., 0., 2., 0., 1., 0., 3., 2., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1., 0 [...]
+
+11., 2., 3., 4., 5., 0., 15., 1., 7., 51., 2., 7., 63., 0., 1., 3., 0., 1., 56., 15., 10., 79., 13., 83., 12., 6., 0., 1., 4., 0., 16., 8., 44., 9., 2., 30., 31., 11., 5., 0., 1., 6., 2., 17., 12., 27., 8., 11., 9., 1., 5., 0., 10., 8., 11., 2., 15., 9., 7., 5., 1., 41., 9., 5., 1., 0., 6., 2., 7., 1., 11., 0., 6., 0., 1., 0., 0., 5., 2., 13., 6., 0., 7., 0., 1., 0., 0., 0., 0., 0., 8., 0., 3., 0., 6., 1., 2., 0., 1., 0., 1., 0., 1., 4., 3., 0., 1., 0., 0., 0., 2., 0., 0., 0., 0., 0., 1. [...]
+
+11., 0., 3., 1., 14., 0., 12., 4., 11., 41., 1., 6., 50., 1., 4., 2., 0., 3., 75., 13., 4., 64., 15., 84., 16., 10., 0., 0., 4., 3., 13., 4., 54., 11., 4., 44., 31., 15., 7., 0., 2., 4., 3., 23., 5., 13., 3., 13., 2., 6., 1., 0., 10., 7., 9., 1., 11., 3., 10., 4., 1., 35., 6., 8., 0., 0., 20., 2., 11., 1., 6., 3., 5., 1., 1., 3., 0., 6., 0., 13., 6., 4., 6., 2., 2., 0., 0., 0., 0., 0., 9., 2., 2., 1., 2., 0., 1., 0., 1., 0., 3., 0., 1., 3., 3., 0., 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., [...]
+
+8., 3., 2., 3., 15., 0., 13., 0., 8., 47., 2., 5., 73., 1., 4., 0., 0., 0., 69., 12., 10., 72., 16., 81., 10., 3., 0., 1., 4., 2., 14., 13., 53., 12., 6., 37., 31., 15., 3., 0., 0., 6., 4., 18., 3., 27., 9., 10., 8., 4., 1., 0., 11., 6., 15., 5., 21., 1., 7., 2., 1., 37., 6., 7., 3., 0., 8., 2., 11., 4., 10., 6., 1., 0., 1., 0., 0., 7., 2., 14., 8., 2., 3., 1., 1., 0., 0., 0., 0., 0., 9., 1., 5., 3., 4., 0., 0., 0., 1., 0., 3., 0., 1., 2., 2., 0., 4., 0., 1., 0., 0., 0., 0., 0., 0., 0.,  [...]
+
+6., 0., 2., 5., 9., 0., 19., 3., 9., 67., 0., 9., 54., 1., 5., 2., 0., 5., 73., 10., 7., 78., 11., 92., 8., 3., 0., 0., 3., 3., 16., 14., 55., 12., 1., 36., 34., 12., 5., 0., 0., 5., 2., 14., 5., 19., 7., 20., 4., 3., 0., 0., 9., 6., 16., 5., 15., 3., 3., 3., 2., 32., 8., 14., 2., 0., 16., 4., 11., 1., 16., 2., 5., 0., 1., 2., 0., 5., 2., 17., 7., 4., 4., 0., 1., 0., 0., 0., 0., 0., 13., 6., 4., 1., 6., 1., 2., 0., 1., 0., 2., 0., 2., 1., 1., 0., 1., 0., 0., 0., 1., 0., 0., 0., 1., 0., 2 [...]
+
+4., 1., 2., 4., 6., 0., 16., 2., 8., 30., 1., 7., 53., 0., 3., 2., 0., 0., 72., 4., 3., 71., 13., 83., 14., 5., 0., 0., 1., 6., 17., 9., 54., 12., 1., 39., 26., 12., 10., 0., 4., 13., 1., 29., 6., 26., 7., 11., 4., 1., 4., 0., 13., 5., 20., 5., 21., 1., 8., 0., 5., 33., 9., 12., 1., 0., 14., 3., 9., 3., 10., 2., 2., 1., 1., 1., 0., 8., 2., 14., 8., 5., 3., 1., 1., 0., 0., 0., 0., 0., 9., 3., 2., 1., 2., 1., 0., 0., 0., 0., 1., 0., 0., 3., 0., 0., 3., 0., 0., 0., 0., 0., 0., 0., 2., 0., 3 [...]
+
+7., 0., 4., 5., 12., 0., 15., 2., 6., 47., 1., 7., 61., 0., 10., 1., 0., 0., 95., 12., 3., 78., 23., 81., 11., 2., 0., 0., 2., 2., 7., 10., 45., 19., 0., 37., 33., 18., 3., 0., 0., 7., 3., 32., 3., 21., 6., 9., 5., 3., 5., 0., 5., 4., 21., 5., 22., 2., 6., 3., 0., 38., 2., 5., 3., 0., 9., 4., 6., 2., 10., 3., 1., 0., 2., 1., 0., 7., 2., 9., 6., 5., 5., 3., 2., 0., 0., 0., 0., 0., 4., 3., 5., 2., 6., 1., 1., 0., 0., 0., 0., 0., 0., 8., 1., 0., 1., 0., 2., 0., 2., 0., 0., 0., 2., 0., 2., 1 [...]
+
+12., 0., 1., 8., 10., 0., 19., 2., 4., 49., 0., 8., 62., 1., 4., 3., 0., 1., 76., 9., 6., 75., 11., 75., 10., 4., 0., 1., 5., 2., 11., 10., 48., 10., 1., 34., 36., 21., 4., 0., 1., 5., 5., 29., 6., 22., 6., 13., 7., 3., 1., 0., 14., 2., 14., 8., 12., 2., 5., 5., 8., 36., 7., 7., 1., 0., 10., 3., 4., 1., 6., 2., 3., 0., 0., 0., 0., 4., 1., 21., 9., 6., 6., 0., 1., 0., 0., 0., 0., 0., 11., 2., 1., 3., 4., 1., 1., 0., 3., 0., 0., 0., 0., 3., 5., 0., 4., 0., 0., 0., 0., 0., 0., 0., 2., 0., 2 [...]
+
+9., 1., 3., 4., 14., 0., 15., 2., 5., 39., 0., 9., 64., 0., 4., 2., 0., 1., 69., 8., 9., 60., 15., 72., 12., 4., 0., 0., 2., 2., 10., 11., 42., 16., 0., 38., 37., 13., 6., 0., 2., 8., 2., 27., 5., 26., 5., 10., 7., 2., 4., 0., 3., 5., 21., 5., 13., 6., 8., 4., 1., 36., 11., 5., 3., 0., 12., 2., 10., 1., 11., 2., 0., 2., 0., 0., 0., 2., 0., 16., 11., 4., 5., 1., 3., 0., 0., 0., 0., 0., 11., 2., 3., 3., 4., 1., 0., 0., 1., 0., 2., 0., 1., 6., 2., 0., 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., [...]
+};
+
+#endif // VIGRA_UNSUPERVISED_TEST_DATA_HXX
diff --git a/test/utilities/CMakeLists.txt b/test/utilities/CMakeLists.txt
new file mode 100644
index 0000000..a9c37f1
--- /dev/null
+++ b/test/utilities/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_utilities test.cxx)
diff --git a/test/utilities/test.cxx b/test/utilities/test.cxx
new file mode 100755
index 0000000..2ea5a39
--- /dev/null
+++ b/test/utilities/test.cxx
@@ -0,0 +1,508 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2004 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <cstddef>
+#include <iostream>
+#include <iterator>
+#include <algorithm>
+#include <queue>
+#include "vigra/unittest.hxx"
+#include "vigra/accessor.hxx"
+#include "vigra/array_vector.hxx"
+#include "vigra/copyimage.hxx"
+#include "vigra/sized_int.hxx"
+#include "vigra/bucket_queue.hxx"
+
+using namespace vigra;
+
+struct ArrayVectorTest
+{
+    typedef int value_type;
+    typedef ArrayVector<value_type> Vector;
+    typedef Vector::iterator Iterator;
+    typedef Vector::const_iterator ConstIterator;
+    typedef StandardValueAccessor<value_type> Accessor;
+    
+    Vector vector_;
+
+    ArrayVectorTest()
+    {}
+    
+    void testAccessor()
+    {
+        vector_.resize(3, 0);
+        Iterator i = vector_.begin();
+        ConstIterator ci = const_cast<Vector const &>(vector_).begin();
+        
+        StandardValueAccessor<value_type> sva;
+        StandardConstValueAccessor<value_type> scva;
+        sva.set(3, i);
+        shouldEqual(vector_[0], 3);
+        shouldEqual(sva(i), 3);
+        shouldEqual(scva(i), 3);
+        shouldEqual(scva(ci), 3);
+        sva.set(4, i+1);
+        shouldEqual(vector_[1], 4);
+        shouldEqual(sva(i+1), 4);
+        shouldEqual(scva(i+1), 4);
+        shouldEqual(scva(ci+1), 4);
+        sva.set(5, i, 2);
+        shouldEqual(vector_[2], 5);
+        shouldEqual(sva(i, 2), 5);
+        shouldEqual(scva(i, 2), 5);
+        shouldEqual(scva(ci, 2), 5);
+        
+        StandardAccessor<value_type> sa;
+        StandardConstAccessor<value_type> sca;
+        sa.set(6, i);
+        shouldEqual(vector_[0], 6);
+        shouldEqual(sa(i), 6);
+        shouldEqual(sca(i), 6);
+        shouldEqual(sca(ci), 6);
+        sa.set(7, i+1);
+        shouldEqual(vector_[1], 7);
+        shouldEqual(sa(i+1), 7);
+        shouldEqual(sca(i+1), 7);
+        shouldEqual(sca(ci+1), 7);
+        sa.set(8, i, 2);
+        shouldEqual(vector_[2], 8);
+        shouldEqual(sa(i, 2), 8);
+        shouldEqual(sca(i, 2), 8);
+        shouldEqual(sca(ci, 2), 8);
+        
+        Vector varray[] = { vector_, vector_, vector_ };
+        Vector  * v = varray;
+        Vector const * cv = varray;
+        int k;
+        
+        VectorComponentAccessor<Vector> vca(0);
+        for(k = 0; k<2; ++k, vca.setIndex(k))
+        {
+            shouldEqual(vca(v), 6 + k);
+            shouldEqual(vca(v + 1), 6 + k);
+            shouldEqual(vca(v, 2), 6 + k);
+            shouldEqual(vca(cv), 6 + k);
+            shouldEqual(vca(cv + 1), 6 + k);
+            shouldEqual(vca(cv, 2), 6 + k);
+            vca.set(3 + k, v);
+            vca.set(3 + k, v + 1);
+            vca.set(3 + k, v, 2);
+            shouldEqual(v[0][k], 3 + k);
+            shouldEqual(v[1][k], 3 + k);
+            shouldEqual(v[2][k], 3 + k);
+        }
+        
+        VectorComponentValueAccessor<Vector> vcva(0);
+        for(k = 0; k<2; ++k, vcva.setIndex(k))
+        {
+            shouldEqual(vcva(v), 3 + k);
+            shouldEqual(vcva(v + 1), 3 + k);
+            shouldEqual(vcva(v, 2), 3 + k);
+            shouldEqual(vcva(cv), 3 + k);
+            shouldEqual(vcva(cv + 1), 3 + k);
+            shouldEqual(vcva(cv, 2), 3 + k);
+            vcva.set(6 + k, v);
+            vcva.set(6 + k, v + 1);
+            vcva.set(6 + k, v, 2);
+            shouldEqual(v[0][k], 6 + k);
+            shouldEqual(v[1][k], 6 + k);
+            shouldEqual(v[2][k], 6 + k);
+        }
+
+        VectorAccessor<Vector> va;
+        VectorElementAccessor<VectorAccessor<Vector> > vea(0, va);
+        for(k = 0; k<2; ++k, vea.setIndex(k))
+        {
+            shouldEqual(vea(v), 6 + k);
+            shouldEqual(vea(v + 1), 6 + k);
+            shouldEqual(vea(v, 2), 6 + k);
+            shouldEqual(vea(cv), 6 + k);
+            shouldEqual(vea(cv + 1), 6 + k);
+            shouldEqual(vea(cv, 2), 6 + k);
+            vea.set(3 + k, v);
+            vea.set(3 + k, v + 1);
+            vea.set(3 + k, v, 2);
+            shouldEqual(v[0][k], 3 + k);
+            shouldEqual(v[1][k], 3 + k);
+            shouldEqual(v[2][k], 3 + k);
+        }
+
+        for(k = 0; k<2; ++k)
+        {
+            shouldEqual(va.getComponent(v, k), 3 + k);
+            shouldEqual(va.getComponent(v + 1, k), 3 + k);
+            shouldEqual(va.getComponent(v, 2, k), 3 + k);
+            shouldEqual(va.getComponent(cv, k), 3 + k);
+            shouldEqual(va.getComponent(cv + 1, k), 3 + k);
+            shouldEqual(va.getComponent(cv, 2, k), 3 + k);
+            va.setComponent(6 + k, v, k);
+            va.setComponent(6 + k, v + 1, k);
+            va.setComponent(6 + k, v, 2, k);
+            shouldEqual(v[0][k], 6 + k);
+            shouldEqual(v[1][k], 6 + k);
+            shouldEqual(v[2][k], 6 + k);
+        }
+
+        SequenceAccessor<Vector> sqa;
+        SequenceAccessor<const Vector> sqca;
+        shouldEqual(sqa.size(v), 3u);
+        shouldEqual(sqa.size(v + 1), 3u);
+        shouldEqual(sqa.size(v, 2), 3u);
+        shouldEqual(sqca.size(cv), 3u);
+        shouldEqual(sqca.size(cv + 1), 3u);
+        shouldEqual(sqca.size(cv, 2), 3u);
+        should(sqa.end(v) == v[0].end());
+        should(sqa.end(v + 1) == v[1].end());
+        should(sqa.end(v, 2) == v[2].end());
+        should(sqca.end(cv) == cv[0].end());
+        should(sqca.end(cv + 1) == cv[1].end());
+        should(sqca.end(cv, 2) == cv[2].end());
+        for(k = 0; k<2; ++k)
+        {
+            shouldEqual(sqa.begin(v)[k], 6 + k);
+            shouldEqual(sqa.begin(v + 1)[k], 6 + k);
+            shouldEqual(sqa.begin(v, 2)[k], 6 + k);
+            shouldEqual(sqca.begin(cv)[k], 6 + k);
+            shouldEqual(sqca.begin(cv + 1)[k], 6 + k);
+            shouldEqual(sqca.begin(cv, 2)[k], 6 + k);
+            sqa.begin(v)[k] = 3 + k;
+            sqa.begin(v + 1)[k] = 3 + k;
+            sqa.begin(v, 2)[k] = 3 + k;
+            shouldEqual(v[0][k], 3 + k);
+            shouldEqual(v[1][k], 3 + k);
+            shouldEqual(v[2][k], 3 + k);
+        }
+    }
+
+    void testBackInsertion()
+    {
+        static value_type data[] = { 0, 1, 2, 3, 4 };
+        
+        shouldEqual(vector_.size(), 0u);
+        
+        Accessor a;
+        copyLine(data, data + 5, a, std::back_inserter(vector_), a);
+        
+        shouldEqual(vector_.size(), 5u);
+        shouldEqualSequence(vector_.begin(), vector_.end(), data);
+    }
+
+    void testAmbiguousConstructor()
+    {
+        ArrayVector<std::ptrdiff_t> a(2, std::ptrdiff_t(1));
+        ArrayVector<std::ptrdiff_t> b(a.begin(), a.end());
+    }
+};
+
+struct BucketQueueTest
+{
+    struct Priority
+    {
+        int operator()(double v) const
+        {
+            return (int)v;
+        }
+    };
+    
+    ArrayVector<double> data;
+    ArrayVector<int> idata;
+    
+    BucketQueueTest()
+    {
+        data.push_back(1.1);
+        data.push_back(4.4);
+        data.push_back(12.2);
+        data.push_back(2.2);
+        data.push_back(3.6);
+        data.push_back(4.5);
+        
+        idata.resize(data.size());
+        std::transform(data.begin(), data.end(), idata.begin(), Priority());
+    }
+    
+    void testDescending()
+    {
+        std::priority_queue<int> queue;
+        BucketQueue<int> bqueue;
+        
+        for(unsigned int k=0; k<idata.size(); ++k)
+        {
+            queue.push(idata[k]);
+            bqueue.push(idata[k], idata[k]);
+        }
+        
+        shouldEqual(idata.size(), bqueue.size());
+        shouldEqual(false, bqueue.empty());
+        
+        for(unsigned int k=0; k<idata.size(); ++k)
+        {
+            shouldEqual(queue.top(), bqueue.top());
+            queue.pop();
+            bqueue.pop();
+        }
+        
+        shouldEqual(0u, bqueue.size());
+        shouldEqual(true, bqueue.empty());        
+    }
+    
+    void testAscending()
+    {
+        std::priority_queue<int, std::vector<int>, std::greater<int> > queue;
+        BucketQueue<int, true> bqueue;
+        
+        for(unsigned int k=0; k<idata.size(); ++k)
+        {
+            queue.push(idata[k]);
+            bqueue.push(idata[k], idata[k]);
+        }
+        
+        shouldEqual(idata.size(), bqueue.size());
+        shouldEqual(false, bqueue.empty());
+        
+        for(unsigned int k=0; k<idata.size(); ++k)
+        {
+            shouldEqual(queue.top(), bqueue.top());
+            queue.pop();
+            bqueue.pop();
+        }
+        
+        shouldEqual(0u, bqueue.size());
+        shouldEqual(true, bqueue.empty());        
+    }
+    
+    void testDescendingMapped()
+    {
+        Priority priority;
+        std::priority_queue<int> queue;
+        MappedBucketQueue<double, Priority> bqueue;
+        
+        for(unsigned int k=0; k<data.size(); ++k)
+        {
+            queue.push(idata[k]);
+            bqueue.push(data[k]);
+        }
+        
+        shouldEqual(data.size(), bqueue.size());
+        shouldEqual(false, bqueue.empty());
+        
+        for(unsigned int k=0; k<data.size(); ++k)
+        {
+            shouldEqual(queue.top(), priority(bqueue.top()));
+            switch(k)
+            {
+              case 1:
+                  shouldEqual(4.4, bqueue.top());
+                  break;
+              case 2:
+                  shouldEqual(4.5, bqueue.top());
+                  break;
+            }
+            queue.pop();
+            bqueue.pop();
+        }
+        
+        shouldEqual(0u, bqueue.size());
+        shouldEqual(true, bqueue.empty());        
+    }
+    
+    void testAscendingMapped()
+    {
+        Priority priority;
+        std::priority_queue<int, std::vector<int>, std::greater<int> > queue;
+        MappedBucketQueue<double, Priority, true> bqueue;
+        
+        for(unsigned int k=0; k<data.size(); ++k)
+        {
+            queue.push(idata[k]);
+            bqueue.push(data[k]);
+        }
+        
+        shouldEqual(data.size(), bqueue.size());
+        shouldEqual(false, bqueue.empty());
+        
+        for(unsigned int k=0; k<data.size(); ++k)
+        {
+            shouldEqual(queue.top(), priority(bqueue.top()));
+            switch(k)
+            {
+              case 3:
+                  shouldEqual(4.4, bqueue.top());
+                  break;
+              case 4:
+                  shouldEqual(4.5, bqueue.top());
+                  break;
+            }
+            queue.pop();
+            bqueue.pop();
+        }
+        
+        shouldEqual(0u, bqueue.size());
+        shouldEqual(true, bqueue.empty());        
+    }
+};
+
+struct SizedIntTest
+{
+    void testSizedInt()
+    {
+        shouldEqual(sizeof(Int8), 1u);
+        shouldEqual(sizeof(Int16), 2u);
+        shouldEqual(sizeof(Int32), 4u);
+        shouldEqual(sizeof(UInt8), 1u);
+        shouldEqual(sizeof(UInt16), 2u);
+        shouldEqual(sizeof(UInt32), 4u);
+        should(sizeof(IntBiggest) >= 4u);
+        should(sizeof(UIntBiggest) >= 4u);
+    }
+};
+
+struct MetaprogrammingTest
+{
+    struct TrueResult {};
+    struct FalseResult {};
+    
+    struct Derived 
+    : public TrueResult 
+    {
+        typedef TrueResult result_type;
+        typedef TrueResult value_type;
+    };
+    
+    void testInt()
+    {
+        shouldEqual(MetaInt<1>::value, 1);
+        shouldEqual((MetaMax<1,2>::value), 2);
+        shouldEqual((MetaMin<1,2>::value), 1);
+    }
+ 
+    void testLogic()
+    {
+        shouldEqual(VigraTrueType::value, true);
+        shouldEqual(VigraFalseType::value, false);        
+        should(typeid(Not<VigraFalseType>::type) == typeid(VigraTrueType));
+        should(typeid(Not<VigraTrueType>::type) == typeid(VigraFalseType));
+        should(typeid(And<VigraTrueType, VigraTrueType>::type) == typeid(VigraTrueType));
+        should(typeid(And<VigraTrueType, VigraFalseType>::type) == typeid(VigraFalseType));
+        should(typeid(And<VigraFalseType, VigraTrueType>::type) == typeid(VigraFalseType));
+        should(typeid(And<VigraFalseType, VigraFalseType>::type) == typeid(VigraFalseType));
+        should(typeid(Or<VigraTrueType, VigraTrueType>::type) == typeid(VigraTrueType));
+        should(typeid(Or<VigraTrueType, VigraFalseType>::type) == typeid(VigraTrueType));
+        should(typeid(Or<VigraFalseType, VigraTrueType>::type) == typeid(VigraTrueType));
+        should(typeid(Or<VigraFalseType, VigraFalseType>::type) == typeid(VigraFalseType));
+        should(typeid(If<VigraTrueType, TrueResult, FalseResult>::type) == typeid(TrueResult));
+        should(typeid(If<VigraFalseType, TrueResult, FalseResult>::type) == typeid(FalseResult));
+        should(typeid(IfBool<true, TrueResult, FalseResult>::type) == typeid(TrueResult));
+        should(typeid(IfBool<false, TrueResult, FalseResult>::type) == typeid(FalseResult));
+    }
+ 
+    void testTypeTools()
+    {
+        should(typeid(IsSameType<TrueResult, TrueResult>::type) == typeid(VigraTrueType));
+        should(typeid(IsSameType<TrueResult, FalseResult>::type) == typeid(VigraFalseType));
+        should(typeid(IsDifferentType<TrueResult, TrueResult>::type) == typeid(VigraFalseType));
+        should(typeid(IsDifferentType<TrueResult, FalseResult>::type) == typeid(VigraTrueType));
+        should(typeid(IsConvertibleTo<int, double>::type) == typeid(VigraTrueType));
+        should(typeid(IsConvertibleTo<int, FalseResult>::type) == typeid(VigraFalseType));
+        should(typeid(IsDerivedFrom<Derived, TrueResult>::type) == typeid(VigraTrueType));
+        should(typeid(IsDerivedFrom<Derived, FalseResult>::type) == typeid(VigraFalseType));
+        should(typeid(has_result_type<Derived>::type) == typeid(VigraTrueType));
+        should(typeid(has_result_type<FalseResult>::type) == typeid(VigraFalseType));
+        should(typeid(has_value_type<Derived>::type) == typeid(VigraTrueType));
+        should(typeid(has_value_type<FalseResult>::type) == typeid(VigraFalseType));
+
+        should(typeid(IsIterator<std::reverse_iterator<int*> >::type) == typeid(VigraTrueType));
+        should(typeid(IsIterator<int*>::type) == typeid(VigraTrueType));
+        should(typeid(IsIterator<int const*>::type) == typeid(VigraTrueType));
+        should(typeid(IsIterator<FalseResult>::type) == typeid(VigraFalseType));
+
+        should(typeid(UnqualifiedType<int>::type) == typeid(int));
+        should(typeid(UnqualifiedType<const int>::type) == typeid(int));
+        should(typeid(UnqualifiedType<int*>::type) == typeid(int));
+        should(typeid(UnqualifiedType<const int*>::type) == typeid(int));
+        should(typeid(UnqualifiedType<int&>::type) == typeid(int));
+        should(typeid(UnqualifiedType<const int&>::type) == typeid(int));
+        should(typeid(UnqualifiedType<int**>::type) == typeid(int));
+        should(typeid(UnqualifiedType<const int**>::type) == typeid(int));
+        should(typeid(UnqualifiedType<int*&>::type) == typeid(int));
+        should(typeid(UnqualifiedType<const int*&>::type) == typeid(int));
+    }
+};
+
+void stringTest()
+{
+    std::string s;
+    s << "Hallo " << 1 << " " << 2.0 << " " << false;
+    shouldEqual(s, std::string("Hallo 1 2 0"));
+
+    shouldEqual(asString(1), "1");
+    shouldEqual(asString(2.0), "2");
+    shouldEqual(asString(false), "0");
+
+    shouldEqual(tolower("AluFr iNsta< Z89>"), "alufr insta< z89>");
+    shouldEqual(normalizeString("AluFr iNsta< Z89>"), "alufrinsta<z89>");
+}
+
+struct UtilitiesTestSuite
+: public vigra::test_suite
+{
+    UtilitiesTestSuite()
+    : vigra::test_suite("UtilitiesTestSuite")
+    {
+        add( testCase( &ArrayVectorTest::testAccessor));
+        add( testCase( &ArrayVectorTest::testBackInsertion));
+        add( testCase( &ArrayVectorTest::testAmbiguousConstructor));
+        add( testCase( &BucketQueueTest::testDescending));
+        add( testCase( &BucketQueueTest::testAscending));
+        add( testCase( &BucketQueueTest::testDescendingMapped));
+        add( testCase( &BucketQueueTest::testAscendingMapped));
+        add( testCase( &SizedIntTest::testSizedInt));
+        add( testCase( &MetaprogrammingTest::testInt));
+        add( testCase( &MetaprogrammingTest::testLogic));
+        add( testCase( &MetaprogrammingTest::testTypeTools));
+        add( testCase( &stringTest));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    UtilitiesTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+
+    return (failed != 0);
+}
+
diff --git a/test/volumelabeling/CMakeLists.txt b/test/volumelabeling/CMakeLists.txt
new file mode 100644
index 0000000..f4c7d71
--- /dev/null
+++ b/test/volumelabeling/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_volumelabeling test.cxx LIBRARIES vigraimpex)
diff --git a/test/volumelabeling/test.cxx b/test/volumelabeling/test.cxx
new file mode 100644
index 0000000..f7ab6dd
--- /dev/null
+++ b/test/volumelabeling/test.cxx
@@ -0,0 +1,484 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2006-2007 by F. Heinrich, B. Seppke, Ullrich Koethe    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <functional>
+#include <cmath>
+#include "vigra/unittest.hxx"
+
+#include "vigra/labelvolume.hxx"
+#include "vigra/multi_labeling.hxx"
+
+using namespace vigra;
+
+struct VolumeLabelingTest
+{
+    typedef vigra::MultiArray<3,int> IntVolume;
+    typedef vigra::MultiArray<3,double> DoubleVolume;
+
+    VolumeLabelingTest()
+    : vol1(IntVolume::difference_type(4,4,4)),vol2(IntVolume::difference_type(4,4,4)),
+      vol3(IntVolume::difference_type(5,5,5)),vol4(DoubleVolume::difference_type(5,5,5)),
+      vol5(DoubleVolume::difference_type(5,5,5)),vol6(DoubleVolume::difference_type(5,5,5))
+    {
+        static const int in1[] = { 0, 0, 0, 0,    0, 0, 0, 0,    0, 0, 0, 0,    0, 0, 0, 0,
+                                   0, 0, 0, 0,    0, 1, 1, 0,    0, 1, 1, 0,    0, 0, 0, 0,
+                                   0, 0, 0, 0,    0, 1, 1, 0,    0, 1, 1, 0,    0, 0, 0, 0,
+                                   0, 0, 0, 0,    0, 0, 0, 0,    0, 0, 0, 0,    0, 0, 0, 0};
+
+        IntVolume::iterator i = vol1.begin();
+        IntVolume::iterator end = vol1.end();
+        const int * p = in1;
+
+        for(; i != end; ++i, ++p)
+        {
+            *i=*p;
+        }
+
+        static const int in2[] = { 0, 1, 0, 1,    1, 0, 1, 0,    0, 1, 0, 1,    1, 0, 1, 0,
+                                   1, 0, 1, 0,    0, 1, 0, 1,    1, 0, 1, 0,    0, 1, 0, 1,
+                                   0, 1, 0, 1,    1, 0, 1, 0,    0, 1, 0, 1,    1, 0, 1, 0,
+                                   1, 0, 1, 0,    0, 1, 0, 1,    1, 0, 1, 0,    0, 1, 0, 1};
+
+        i = vol2.begin();
+        end = vol2.end();
+        p = in2;
+
+        for(; i != end; ++i, ++p)
+        {
+            *i=*p;
+        }
+
+                        
+        static const int in3[] = { 0, 1, 0, 0, 0,    1, 1, 0, 0, 0,    0, 0, 0, 0, 0,    0, 0, 0, 0, 0,    0, 0, 0, 0, 0,
+                                   1, 1, 1, 0, 0,    1, 1, 1, 0, 0,    1, 1, 1, 0, 0,    0, 0, 0, 0, 0,    0, 0, 0, 0, 0,
+                                   0, 0, 1, 0, 0,    0, 0, 1, 0, 0,    1, 1, 1, 0, 0,    0, 0, 0, 0, 0,    0, 0, 0, 0, 0,
+                                   1, 1, 1, 1, 0,    1, 1, 1, 1, 0,    1, 1, 1, 1, 0,    1, 1, 1, 1, 0,    0, 0, 0, 0, 0,
+                                   0, 0, 0, 1, 0,    0, 0, 0, 1, 0,    0, 0, 0, 1, 0,    1, 1, 1, 1, 0,    0, 0, 0, 0, 0};
+
+        i = vol3.begin();
+        end = vol3.end();
+        p = in3;
+
+        for(; i != end; ++i, ++p)
+        {
+            *i=*p;
+        }
+
+        static const double in4[] = { 1.0, 0.0, 0.0, 0.0, 1.0,    0.0, 0.0, 0.0, 0.0, 0.0,    0.0, 0.0, 1.0, 0.0, 0.0,    0.0, 0.0, 0.0, 0.0, 0.0,    1.0, 0.0, 0.0, 0.0, 1.0,
+                                      0.0, 0.0, 0.0, 0.0, 0.0,    0.0, 1.0, 0.0, 1.0, 0.0,    0.0, 0.0, 1.0, 0.0, 0.0,    0.0, 1.0, 0.0, 1.0, 0.0,    0.0, 0.0, 0.0, 0.0, 0.0,
+                                      0.0, 0.0, 1.0, 0.0, 0.0,    0.0, 0.0, 1.0, 0.0, 0.0,    1.0, 1.0, 1.0, 1.0, 1.0,    0.0, 0.0, 1.0, 0.0, 0.0,    0.0, 0.0, 1.0, 0.0, 0.0,
+                                      0.0, 0.0, 0.0, 0.0, 0.0,    0.0, 1.0, 0.0, 1.0, 0.0,    0.0, 0.0, 1.0, 0.0, 0.0,    0.0, 1.0, 0.0, 1.0, 0.0,    0.0, 0.0, 0.0, 0.0, 0.0,
+                                      1.0, 0.0, 0.0, 0.0, 1.0,    0.0, 0.0, 0.0, 0.0, 0.0,    0.0, 0.0, 1.0, 0.0, 0.0,    0.0, 0.0, 0.0, 0.0, 0.0,    1.0, 0.0, 0.0, 0.0, 1.0};
+
+        DoubleVolume::iterator id = vol4.begin();
+        DoubleVolume::iterator endd = vol4.end();
+        const double * pd = in4;
+
+        for(; id != endd; ++id, ++pd)
+        {
+            *id=*pd;
+        }
+
+        static const double in5[] = { 0.0, 0.0, 0.0, 0.0, 0.0,    0.0, 1.0, 1.0, 1.0, 0.0,    0.0, 1.0, 1.0, 1.0, 0.0,    0.0, 1.0, 1.0, 1.0, 0.0,    0.0, 0.0, 0.0, 0.0, 0.0,
+                                      2.0, 2.0, 0.0, 2.0, 2.0,    2.0, 1.0, 0.0, 1.0, 2.0,    2.0, 2.0, 0.0, 2.0, 2.0,    2.0, 1.0, 0.0, 1.0, 2.0,    2.0, 2.0, 0.0, 2.0, 2.0,
+                                      0.0, 0.0, 0.0, 0.0, 0.0,    0.0, 2.0, 2.0, 2.0, 0.0,    0.0, 2.0, 1.0, 2.0, 0.0,    0.0, 2.0, 2.0, 2.0, 0.0,    0.0, 0.0, 0.0, 0.0, 0.0,
+                                      2.0, 2.0, 0.0, 2.0, 2.0,    2.0, 1.0, 0.0, 1.0, 2.0,    2.0, 2.0, 0.0, 2.0, 2.0,    2.0, 1.0, 0.0, 1.0, 2.0,    2.0, 2.0, 0.0, 2.0, 2.0,
+                                      0.0, 0.0, 0.0, 0.0, 0.0,    0.0, 1.0, 1.0, 1.0, 0.0,    0.0, 1.0, 1.0, 1.0, 0.0,    0.0, 1.0, 1.0, 1.0, 0.0,    0.0, 0.0, 0.0, 0.0, 0.0};
+
+        id = vol5.begin();
+        endd = vol5.end();
+        pd = in5;
+
+        for(; id != endd; ++id, ++pd)
+        {
+            *id=*pd;
+        }
+
+        static const double in6[] = {
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            1.0, 1.0, 0.0, 1.0, 1.0, 
+            1.0, 1.0, 0.0, 1.0, 1.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            1.0, 1.0, 0.0, 1.0, 1.0, 
+            1.0, 1.0, 0.0, 1.0, 1.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0, 
+            0.0, 0.0, 0.0, 0.0, 0.0 };
+
+        id = vol6.begin();
+        endd = vol6.end();
+        pd = in6;
+
+        for(; id != endd; ++id, ++pd)
+        {
+            *id=*pd;
+        }
+
+    }
+
+    void labelingSixTest1()
+    {
+        IntVolume res(vol1.shape()), res2(vol1.shape());
+        
+        unsigned int maxLabel = labelVolumeSix(srcMultiArrayRange(vol1), destMultiArray(res));
+        should(2 == maxLabel);
+
+        IntVolume::iterator i1 = vol1.begin();
+        IntVolume::iterator i1end = vol1.end();
+        IntVolume::iterator i2 = res.begin();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should( *i1 == (*i2 - 1.0) );
+        }
+
+        maxLabel = labelMultiArray(vol1, res2, DirectNeighborhood);
+        should(2 == maxLabel);
+        should(res == res2);
+
+        res2 = 0;
+        maxLabel = labelVolumeSix(vol1, res2);
+        should(2 == maxLabel);
+        should(res == res2);
+
+        res2 = 0;
+        maxLabel = labelVolume(vol1, res2, NeighborCode3DSix());
+        should(2 == maxLabel);
+        should(res == res2);
+    }
+
+    void labelingSixTest2()
+    {
+        IntVolume res(vol2.shape()), res2(vol2.shape());
+
+        should(64 == labelVolume(srcMultiArrayRange(vol2), destMultiArray(res), NeighborCode3DSix()));
+
+        IntVolume::iterator i2 = res.begin();
+        IntVolume::iterator i2end = res.end();
+        int address = 0;
+
+        for(; i2 != i2end; ++i2, ++address)
+        {
+            should( *i2 == address+1 );
+        }
+
+        should(64 == labelMultiArray(vol2, res2, DirectNeighborhood));
+        should(res == res2);
+    }
+
+    void labelingSixTest3()
+    {
+        IntVolume res(vol3.shape()), res2(vol3.shape());
+
+        should(5 == labelVolume(srcMultiArrayRange(vol3), destMultiArray(res), NeighborCode3DSix()));
+
+        static const int out3[] = { 1, 2, 3, 3, 3,    2, 2, 3, 3, 3,    3, 3, 3, 3, 3,    3, 3, 3, 3, 3,    3, 3, 3, 3, 3,
+                                    2, 2, 2, 3, 3,    2, 2, 2, 3, 3,    2, 2, 2, 3, 3,    3, 3, 3, 3, 3,    3, 3, 3, 3, 3,
+                                    4, 4, 2, 3, 3,    4, 4, 2, 3, 3,    2, 2, 2, 3, 3,    3, 3, 3, 3, 3,    3, 3, 3, 3, 3,
+                                    2, 2, 2, 2, 3,    2, 2, 2, 2, 3,    2, 2, 2, 2, 3,    2, 2, 2, 2, 3,    3, 3, 3, 3, 3,
+                                    5, 5, 5, 2, 3,    5, 5, 5, 2, 3,    5, 5, 5, 2, 3,    2, 2, 2, 2, 3,    3, 3, 3, 3, 3};
+
+        IntVolume::iterator i2 = res.begin();
+        IntVolume::iterator i2end = res.end();
+        const int * p = out3;
+
+        for(; i2 != i2end; ++i2, ++p)
+        {
+            should( *i2 == *p );
+        }
+
+        should(5 == labelMultiArray(vol3, res2, DirectNeighborhood));
+        should(res == res2);
+    }
+
+    void labelingSixTest4()
+    {
+        IntVolume res(vol4.shape()), res2(vol4.shape());
+
+        should(18 == labelVolume(srcMultiArrayRange(vol4), destMultiArray(res), NeighborCode3DSix()));
+
+        static const int out4[] = { 1, 2, 2, 2, 3,    2, 2, 2, 2, 2,    2, 2, 4, 2, 2,    2, 2, 2, 2, 2,    5, 2, 2, 2, 6,
+                                    2, 2, 2, 2, 2,    2, 7, 2, 8, 2,    2, 2, 4, 2, 2,    2, 9, 2,10, 2,    2, 2, 2, 2, 2,
+                                    2, 2, 4, 2, 2,    2, 2, 4, 2, 2,    4, 4, 4, 4, 4,    2, 2, 4, 2, 2,    2, 2, 4, 2, 2,
+                                    2, 2, 2, 2, 2,    2,11, 2,12, 2,    2, 2, 4, 2, 2,    2,13, 2,14, 2,    2, 2, 2, 2, 2,
+                                   15, 2, 2, 2,16,    2, 2, 2, 2, 2,    2, 2, 4, 2, 2,    2, 2, 2, 2, 2,   17, 2, 2, 2,18};
+
+        IntVolume::iterator i2 = res.begin();
+        IntVolume::iterator i2end = res.end();
+        const int * p = out4;
+
+        for(; i2 != i2end; ++i2, ++p)
+        {
+            should( *i2 == *p );
+        }
+
+        should(18 == labelMultiArray(vol4, res2, DirectNeighborhood));
+        should(res == res2);
+    }
+
+    void labelingSixWithBackgroundTest1()
+    {
+        IntVolume res(vol5.shape()), res2(vol5.shape());
+
+        unsigned int maxLabel = labelVolumeWithBackground(srcMultiArrayRange(vol5), destMultiArray(res), NeighborCode3DSix(), 0);
+        should(4 == maxLabel);
+
+        static const int out5[] = { 0, 0, 0, 0, 0,    0, 1, 1, 1, 0,    0, 1, 1, 1, 0,    0, 1, 1, 1, 0,    0, 0, 0, 0, 0,
+                                    2, 2, 0, 2, 2,    2, 1, 0, 1, 2,    2, 2, 0, 2, 2,    2, 1, 0, 1, 2,    2, 2, 0, 2, 2,
+                                    0, 0, 0, 0, 0,    0, 2, 2, 2, 0,    0, 2, 3, 2, 0,    0, 2, 2, 2, 0,    0, 0, 0, 0, 0,
+                                    2, 2, 0, 2, 2,    2, 4, 0, 4, 2,    2, 2, 0, 2, 2,    2, 4, 0, 4, 2,    2, 2, 0, 2, 2,
+                                    0, 0, 0, 0, 0,    0, 4, 4, 4, 0,    0, 4, 4, 4, 0,    0, 4, 4, 4, 0,    0, 0, 0, 0, 0};
+
+        IntVolume::iterator i2 = res.begin();
+        IntVolume::iterator i2end = res.end();
+        const int * p = out5;
+
+        for(; i2 != i2end; ++i2, ++p)
+        {
+            should( *i2 == *p );
+        }
+
+        should(4 == labelMultiArrayWithBackground(vol5, res2, DirectNeighborhood));
+        should(res == res2);
+
+        res2 = 0;
+        should(4 == labelVolumeWithBackground(vol5, res2, NeighborCode3DSix(), 0));
+        should(res == res2);
+    }
+
+
+    void labelingTwentySixTest1()
+    {
+        IntVolume res(vol1.shape()), res2(vol1.shape());
+
+        should(2 == labelVolume(srcMultiArrayRange(vol1), destMultiArray(res), NeighborCode3DTwentySix()));
+
+        IntVolume::iterator i1 = vol1.begin();
+        IntVolume::iterator i1end = vol1.end();
+        IntVolume::iterator i2 = res.begin();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should( *i1 == (*i2 - 1.0) );
+        }
+
+        should(2 == labelMultiArray(vol1, res2, IndirectNeighborhood));
+        should(res == res2);
+    }
+
+    void labelingTwentySixTest2()
+    {
+        IntVolume res(vol2.shape()), res2(vol2.shape());
+
+        should(2 == labelVolume(srcMultiArrayRange(vol2), destMultiArray(res), NeighborCode3DTwentySix()));
+
+        IntVolume::iterator i1 = vol2.begin();
+        IntVolume::iterator i1end = vol2.end();
+        IntVolume::iterator i2 = res.begin();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should( *i1 == (*i2 - 1.0) );
+        }
+
+        should(2 == labelMultiArray(vol2, res2, IndirectNeighborhood));
+        should(res == res2);
+    }
+
+    void labelingTwentySixTest3()
+    {
+        IntVolume res(vol4.shape()), res2(vol4.shape());
+
+        should(2 == labelVolume(srcMultiArrayRange(vol4), destMultiArray(res), NeighborCode3DTwentySix()));
+
+        DoubleVolume::iterator i1 = vol4.begin();
+        DoubleVolume::iterator i1end = vol4.end();
+        IntVolume::iterator i2 = res.begin();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should( *i1 == 2-*i2 );
+        }
+
+        should(2 == labelMultiArray(vol4, res2, IndirectNeighborhood));
+        should(res == res2);
+    }
+
+    void labelingTwentySixWithBackgroundTest1()
+    {
+        IntVolume res(vol5.shape()), res2(vol5.shape());
+
+        should(2 == labelVolumeWithBackground(srcMultiArrayRange(vol5), destMultiArray(res), NeighborCode3DTwentySix(), 0));
+
+        DoubleVolume::iterator i1 = vol5.begin();
+        DoubleVolume::iterator i1end = vol5.end();
+        IntVolume::iterator i2 = res.begin();
+
+        for(; i1 != i1end; ++i1, ++i2)
+        {
+            should( *i1 == *i2 );
+        }
+
+        should(2 == labelMultiArrayWithBackground(vol5, res2, IndirectNeighborhood));
+        should(res == res2);
+    }
+
+    void labelingAllTest()
+    {
+        IntVolume res(vol6.shape());
+        static const int out6[] = {
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+                1, 1, 0, 2, 2, 
+                1, 1, 0, 2, 2, 
+                0, 0, 0, 0, 0, 
+
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+                1, 1, 0, 2, 2, 
+                1, 1, 0, 2, 2, 
+                0, 0, 0, 0, 0, 
+
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0, 
+                0, 0, 0, 0, 0 };
+
+        res = 0;
+        should(2 == labelVolumeWithBackground(srcMultiArrayRange(vol6), destMultiArray(res), NeighborCode3DSix(), 0));
+        shouldEqualSequence(res.begin(), res.end(), out6);
+
+        res = 0;
+        should(2 == labelVolumeWithBackground(srcMultiArrayRange(vol6), destMultiArray(res), NeighborCode3DTwentySix(), 0));
+        shouldEqualSequence(res.begin(), res.end(), out6);
+
+        res = 0;
+        should(3 == labelVolume(srcMultiArrayRange(vol6), destMultiArray(res), NeighborCode3DSix()));
+        res -= 1;
+        shouldEqualSequence(res.begin(), res.end(), out6);
+
+        res = 0;
+        should(3 == labelVolume(srcMultiArrayRange(vol6), destMultiArray(res), NeighborCode3DTwentySix()));
+        res -= 1;
+        shouldEqualSequence(res.begin(), res.end(), out6);
+
+        res = 0;
+        should(2 == labelMultiArrayWithBackground(vol6, res, DirectNeighborhood));
+        shouldEqualSequence(res.begin(), res.end(), out6);
+
+        res = 0;
+        should(2 == labelMultiArrayWithBackground(vol6, res, IndirectNeighborhood, 0.0));
+        shouldEqualSequence(res.begin(), res.end(), out6);
+
+        res = 0;
+        should(3 == labelMultiArray(vol6, res, DirectNeighborhood));
+        res -= 1;
+        shouldEqualSequence(res.begin(), res.end(), out6);
+
+        res = 0;
+        should(3 == labelMultiArray(vol6, res, IndirectNeighborhood));
+        res -= 1;
+        shouldEqualSequence(res.begin(), res.end(), out6);
+    }
+
+    IntVolume vol1, vol2, vol3;
+    DoubleVolume vol4, vol5, vol6;
+};
+
+
+
+struct VolumeLabelingTestSuite
+: public vigra::test_suite
+{
+    VolumeLabelingTestSuite()
+    : vigra::test_suite("VolumeLabelingTestSuite")
+    {
+        add( testCase( &VolumeLabelingTest::labelingSixTest1));
+        add( testCase( &VolumeLabelingTest::labelingSixTest2));
+        add( testCase( &VolumeLabelingTest::labelingSixTest3));
+        add( testCase( &VolumeLabelingTest::labelingSixTest4));
+        add( testCase( &VolumeLabelingTest::labelingSixWithBackgroundTest1));
+        add( testCase( &VolumeLabelingTest::labelingTwentySixTest1));
+        add( testCase( &VolumeLabelingTest::labelingTwentySixTest2));
+        add( testCase( &VolumeLabelingTest::labelingTwentySixTest3));
+        add( testCase( &VolumeLabelingTest::labelingTwentySixWithBackgroundTest1));
+        add( testCase( &VolumeLabelingTest::labelingAllTest));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    VolumeLabelingTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+    return (failed != 0);
+}
+
diff --git a/test/voxelneighborhood/CMakeLists.txt b/test/voxelneighborhood/CMakeLists.txt
new file mode 100644
index 0000000..29ff284
--- /dev/null
+++ b/test/voxelneighborhood/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_voxelneighborhood test.cxx LIBRARIES vigraimpex)
diff --git a/test/voxelneighborhood/test.cxx b/test/voxelneighborhood/test.cxx
new file mode 100644
index 0000000..ec43d45
--- /dev/null
+++ b/test/voxelneighborhood/test.cxx
@@ -0,0 +1,2335 @@
+/************************************************************************/
+/*                                                                      */
+/*     Copyright 2006-2007 by F. Heinrich, B. Seppke, Ullrich Koethe    */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <functional>
+#include <cmath>
+#include <set>
+#include "vigra/unittest.hxx"
+
+#include "vigra/voxelneighborhood.hxx"
+#include "vigra/multi_array.hxx"
+
+using namespace vigra;
+struct NeighborhoodCirculator3dTest
+{
+
+    typedef vigra::NeighborhoodCirculator<vigra::StridedMultiIterator<3,int>, vigra::NeighborCode3DSix> SixTraverser;
+    typedef vigra::NeighborhoodCirculator<vigra::StridedMultiIterator<3,int>, vigra::NeighborCode3DTwentySix> TwentySixTraverser;
+
+    typedef vigra::MultiArray<3,int> IntVolume;
+
+    IntVolume vol;
+        
+    SixTraverser sixTrav;
+    TwentySixTraverser twentySixTrav;
+
+    enum { w=5,h=5,d=5 };
+        
+
+    NeighborhoodCirculator3dTest()
+    : vol(IntVolume::difference_type(w,h,d)),
+      sixTrav(vol.traverser_begin() + vigra::Diff3D(1,1,1)),         // set sixTrav to voxel 31=(1,1,1)
+      twentySixTrav(vol.traverser_begin() + vigra::Diff3D(1,1,1))    // set twentySixTrav to voxel 31=(1,1,1)
+    {
+        int i=0;
+        for(vigra::MultiArray<3,int>::iterator iter = vol.begin(); iter!= vol.end(); ++iter, ++i){
+                *iter=i;
+        }
+    }
+
+    void testInit()
+    {
+        should(*sixTrav == 6);
+        should(!sixTrav.isDiagonal());
+        should(*(sixTrav.center()) == 31);
+        should(*twentySixTrav == 0);
+        should(twentySixTrav.isDiagonal());
+        should(*(twentySixTrav.center()) == 31);
+    }
+
+    void testSixTraverserForward()
+    {
+        sixTrav++;
+        shouldEqual(*sixTrav, 26);
+        sixTrav++;
+        shouldEqual(*sixTrav, 30);
+        sixTrav++;
+        shouldEqual(*sixTrav, 56);
+        sixTrav++;
+        shouldEqual(*sixTrav, 36);
+        sixTrav++;
+        shouldEqual(*sixTrav, 32);
+    }
+
+    void testSixTraverserBackward()
+    {
+        sixTrav--;
+        shouldEqual(*sixTrav, 32);
+        sixTrav--;
+        shouldEqual(*sixTrav, 36);
+        sixTrav--;
+        shouldEqual(*sixTrav, 56);
+        sixTrav--;
+        shouldEqual(*sixTrav, 30);
+        sixTrav--;
+        shouldEqual(*sixTrav, 26);
+    }
+
+    void testTwentySixTraverserForward()
+    {
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 1);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 2);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 5);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 6);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 7);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 10);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 11);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 12);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 25);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 26);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 27);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 30);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 32);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 35);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 36);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 37);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 50);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 51);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 52);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 55);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 56);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 57);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 60);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 61);
+        twentySixTrav++;
+        shouldEqual(*twentySixTrav, 62);
+    }
+
+    void testTwentySixTraverserBackward()
+    {
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 62);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 61);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 60);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 57);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 56);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 55);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 52);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 51);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 50);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 37);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 36);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 35);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 32);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 30);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 27);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 26);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 25);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 12);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 11);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 10);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 7);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 6);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 5);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 2);
+        twentySixTrav--;
+        shouldEqual(*twentySixTrav, 1);
+    }
+
+    void testIsDiagonal()
+    {
+        should(*twentySixTrav == 0);
+        should(*sixTrav == 6);
+        for(int i=0; i<27; i++, sixTrav++, twentySixTrav++)
+        {
+            switch(i){
+                case  4 : 
+                case 10 :
+                case 12 :
+                case 13 :
+                case 15 :
+                case 21 : should(!twentySixTrav.isDiagonal()); break;
+                default : should(twentySixTrav.isDiagonal());
+            }
+            should(!sixTrav.isDiagonal());
+        }
+    }
+
+    void testEquality()
+    {
+        TwentySixTraverser twentySixTrav2 = twentySixTrav;
+        should(twentySixTrav == twentySixTrav2);
+        twentySixTrav2++;
+        should(twentySixTrav != twentySixTrav2);
+        twentySixTrav2++;
+        should(twentySixTrav != twentySixTrav2);
+        twentySixTrav++;
+        should(twentySixTrav != twentySixTrav2);
+        twentySixTrav2--;
+        should(twentySixTrav == twentySixTrav2);
+
+        SixTraverser sixTrav2(vol.traverser_begin() + vigra::Diff3D(1,1,1));
+        should(sixTrav == sixTrav2);
+        sixTrav--;
+        should(sixTrav != sixTrav2);
+
+        twentySixTrav2 = twentySixTrav + 3;
+        twentySixTrav += 3;
+        should(twentySixTrav == twentySixTrav2);
+
+        sixTrav2 = sixTrav + 3;
+        sixTrav += 3;
+        should(sixTrav == sixTrav2);
+
+        twentySixTrav2 = twentySixTrav - 5;
+        twentySixTrav -= 5;
+        should(twentySixTrav == twentySixTrav2);
+
+        sixTrav2 = sixTrav - 5;
+        sixTrav -= 5;
+        should(sixTrav == sixTrav2);
+    }
+
+    void testTurning()
+    {
+        SixTraverser sixTrav2 = sixTrav;
+        sixTrav2.turnRound();
+        should(sixTrav != sixTrav2);
+        sixTrav2.turnRound();
+        should(sixTrav == sixTrav2);
+
+        TwentySixTraverser twentySixTrav2 = twentySixTrav;
+        twentySixTrav2.turnRound();
+        should(twentySixTrav != twentySixTrav2);
+        twentySixTrav2.turnRound();
+        should(twentySixTrav == twentySixTrav2);
+
+        sixTrav++; // turn to North
+        sixTrav2.turnTo(Neighborhood3DSix::North);
+        should(sixTrav == sixTrav2);
+        sixTrav-=2; // turn to East
+        sixTrav2.turnTo(Neighborhood3DSix::East);
+        should(sixTrav == sixTrav2);
+
+        twentySixTrav++; // turn to InFrontNorth
+        twentySixTrav2.turnTo(Neighborhood3DTwentySix::InFrontNorth);
+        should(twentySixTrav == twentySixTrav2);
+        twentySixTrav+=12; // turn to East
+        twentySixTrav2.turnTo(Neighborhood3DTwentySix::East);
+        should(twentySixTrav == twentySixTrav2);
+    }
+
+    void testMoving()
+    {
+        sixTrav.turnTo(Neighborhood3DSix::Behind);
+        sixTrav.swapCenterNeighbor();
+        should(*(sixTrav.center()) == 56 );
+        shouldEqual(*sixTrav, 31); // looking Behind from 6 now
+        should(sixTrav.direction() == Neighborhood3DSix::InFront);
+
+        twentySixTrav.turnTo(Neighborhood3DTwentySix::BehindSouthEast);
+        twentySixTrav.swapCenterNeighbor();
+        should(*(twentySixTrav.center()) == 62 );
+        shouldEqual(*twentySixTrav, 31); // looking Behind from 6 now
+        should(twentySixTrav.direction() == Neighborhood3DTwentySix::InFrontNorthWest);
+    }
+
+    void testMiscellaneous()
+    {
+        SixTraverser sixTrav2 = sixTrav;
+        TwentySixTraverser twentySixTrav2 = twentySixTrav;
+        // test operator[]
+        for(int i=0; i<6; i++, sixTrav++, twentySixTrav++){
+                should(sixTrav2[i] == *sixTrav);
+                should(twentySixTrav2[i] == *twentySixTrav);
+        }
+
+        twentySixTrav.turnTo(Neighborhood3DTwentySix::InFrontNorthWest);
+
+        // test base()
+        should(twentySixTrav.base() == vol.traverser_begin());
+        twentySixTrav += Neighborhood3DTwentySix::BehindEast - twentySixTrav.direction();
+        twentySixTrav.moveCenterToNeighbor();
+        should(*(twentySixTrav.base()) == 83);
+        twentySixTrav.turnRound();
+        twentySixTrav.swapCenterNeighbor();
+        should(*(twentySixTrav.base()) == 57);
+    }
+};
+
+struct RestrictedNeighborhoodCirculator3dTest
+{
+
+    typedef vigra::RestrictedNeighborhoodCirculator<vigra::StridedMultiIterator<3,int>, vigra::NeighborCode3DSix> SixTraverser;
+    typedef vigra::RestrictedNeighborhoodCirculator<vigra::StridedMultiIterator<3,int>, vigra::NeighborCode3DTwentySix> TwentySixTraverser;
+    typedef vigra::MultiArray<3,int> IntVolume;
+
+    IntVolume vol;
+        
+    SixTraverser sixTrav;
+    TwentySixTraverser twentySixTrav;
+
+    enum { w=3,h=3,d=3 };
+        
+
+    RestrictedNeighborhoodCirculator3dTest()
+    : vol(IntVolume::difference_type(w,h,d)),
+      sixTrav(vol.traverser_begin(), TopLeftFrontBorder),
+      twentySixTrav(vol.traverser_begin(), TopLeftFrontBorder)
+    {
+        int i=0;
+        for(vigra::MultiArray<3,int>::iterator iter = vol.begin(); iter!= vol.end(); ++iter, ++i){
+            *iter=i;
+        }
+    }
+
+    void testInit()
+    {
+        should(*sixTrav == 9);
+        should(!sixTrav.isDiagonal());
+        should(*(sixTrav.center()) == 0);
+        should(*twentySixTrav == 1);
+        should(!twentySixTrav.isDiagonal());
+        should(*(twentySixTrav.center()) == 0);
+    }
+
+    void testBordersSix()
+    {
+        std::set<int> directions;
+        std::set<int>::iterator dir_Iter;
+        int x,y,z,start;
+        AtVolumeBorder atBorder;
+
+////////test first plane in volume
+
+        //-------------TopLeftFrontBorder--------------//
+        x=0,y=0,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 9);
+        should(atBorder == TopLeftFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DSix::InFront); // insert "0"   |
+        //directions.insert(Neighborhood3DSix::North);   // insert "1"   |- border directions
+        //directions.insert(Neighborhood3DSix::West);    // insert "2"   |
+        directions.insert(Neighborhood3DSix::Behind); // insert "3"
+        directions.insert(Neighborhood3DSix::South);  // insert "4"
+        directions.insert(Neighborhood3DSix::East);   // insert "5"
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------TopFrontBorder--------------//
+        x=1,y=0,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 0);
+        should(atBorder == TopFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(2);
+        directions.insert(3);
+        directions.insert(4);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------TopRightFrontBorder--------------//
+        x=2,y=0,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 1);
+        should(atBorder == TopRightFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(2);
+        directions.insert(3);
+        directions.insert(4);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------FrontLeftBorder--------------//
+        x=0,y=1,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 0);
+        should(atBorder == FrontLeftBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(3);
+        directions.insert(4);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------FrontBorder--------------//
+        x=1,y=1,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 1);
+        should(atBorder == FrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(3);
+        directions.insert(4);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------FrontRightBorder--------------//
+        x=2,y=1,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 2);
+        should(atBorder == FrontRightBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(3);
+        directions.insert(4);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------BottomLeftFrontBorder--------------//
+        x=0,y=2,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 3);
+        should(atBorder == BottomLeftFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(3);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------BottomFrontBorder--------------//
+        x=1,y=2,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 4);
+        should(atBorder == BottomFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(3);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------BottomRightFrontBorder--------------//
+        x=2,y=2,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 5);
+        should(atBorder == BottomRightFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(3);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+
+////////test second plane in volume
+
+        //-------------TopLeftBorder--------------//
+        x=0,y=0,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 0);
+        should(atBorder == TopLeftBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(Neighborhood3DSix::InFront); // insert "1"
+        directions.insert(Neighborhood3DSix::Behind); // insert "3"
+        directions.insert(Neighborhood3DSix::South);  // insert "4"
+        directions.insert(Neighborhood3DSix::East);   // insert "5"
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------TopBorder--------------//
+        x=1,y=0,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 1);
+        should(atBorder == TopBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(0);
+        directions.insert(2);
+        directions.insert(3);
+        directions.insert(4);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------TopRightBorder--------------//
+        x=2,y=0,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 2);
+        should(atBorder == TopRightBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(0);
+        directions.insert(2);
+        directions.insert(3);
+        directions.insert(4);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------LeftBorder--------------//
+        x=0,y=1,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 3);
+        should(atBorder == LeftBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(0);
+        directions.insert(1);
+        directions.insert(3);
+        directions.insert(4);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------NotAtBorder--------------//
+        x=1,y=1,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 4);
+        should(atBorder == NotAtBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(0);
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(3);
+        directions.insert(4);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------RightBorder--------------//
+        x=2,y=1,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 5);
+        should(atBorder == RightBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(0);
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(3);
+        directions.insert(4);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------BottomLeftBorder--------------//
+        x=0,y=2,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 6);
+        should(atBorder == BottomLeftBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(0);
+        directions.insert(1);
+        directions.insert(3);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------BottomBorder--------------//
+        x=1,y=2,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 7);
+        should(atBorder == BottomBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(0);
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(3);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------BottomRightBorder--------------//
+        x=2,y=2,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 8);
+        should(atBorder == BottomRightBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(0);
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(3);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+
+////////test third plane in volume
+
+        //-------------TopLeftRearBorder--------------//
+        x=0,y=0,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 9);
+        should(atBorder == TopLeftRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(Neighborhood3DSix::InFront);// insert "0"
+        directions.insert(Neighborhood3DSix::South);  // insert "4"
+        directions.insert(Neighborhood3DSix::East);   // insert "5"
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------TopRearBorder--------------//
+        x=1,y=0,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 10);
+        should(atBorder == TopRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(2);
+        directions.insert(0);
+        directions.insert(4);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------TopRightRearBorder--------------//
+        x=2,y=0,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 11);
+        should(atBorder == TopRightRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(2);
+        directions.insert(0);
+        directions.insert(4);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------RearLeftBorder--------------//
+        x=0,y=1,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 12);
+        should(atBorder == RearLeftBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(0);
+        directions.insert(4);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------RearBorder--------------//
+        x=1,y=1,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 13);
+        should(atBorder == RearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(0);
+        directions.insert(4);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------RearRightBorder--------------//
+        x=2,y=1,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 14);
+        should(atBorder == RearRightBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(0);
+        directions.insert(4);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------BottomLeftRearBorder--------------//
+        x=0,y=2,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 15);
+        should(atBorder == BottomLeftRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(0);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------BottomRearBorder--------------//
+        x=1,y=2,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 16);
+        should(atBorder == BottomRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(0);
+        directions.insert(5);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+
+        //-------------BottomRightRearBorder--------------//
+        x=2,y=2,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        sixTrav = SixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*sixTrav == 17);
+        should(atBorder == BottomRightRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(1);
+        directions.insert(2);
+        directions.insert(0);
+
+        start = *sixTrav;
+        dir_Iter=directions.begin();
+        do{
+            should(*dir_Iter == sixTrav.direction());
+            sixTrav++;
+            dir_Iter++;
+        }while(*sixTrav!=start);
+    }
+
+
+    void testBordersTwentySix()
+    {
+        std::set<int> directions;
+        std::set<int>::iterator dir_Iter;
+        int x,y,z,start;
+        AtVolumeBorder atBorder;
+
+////////test first plane in volume
+
+        //-------------TopLeftFrontBorder--------------//
+        x=0,y=0,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 1);
+        should(atBorder == TopLeftFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        //directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        //directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        //directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------TopFrontBorder--------------//
+        x=1,y=0,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 0);
+        should(atBorder == TopFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        //directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        //directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------TopRightFrontBorder--------------//
+        x=2,y=0,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 1);
+        should(atBorder == TopRightFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        //directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        //directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        //directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------FrontLeftBorder--------------//
+        x=0,y=1,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 0);
+        should(atBorder == FrontLeftBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        //directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        //directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------FrontBorder--------------//
+        x=1,y=1,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 0);
+        should(atBorder == FrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        //directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------FrontRightBorder--------------//
+        x=2,y=1,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 1);
+        should(atBorder == FrontRightBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        //directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        //directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------BottomLeftFrontBorder--------------//
+        x=0,y=2,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 3);
+        should(atBorder == BottomLeftFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        //directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        //directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        //directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------BottomFrontBorder--------------//
+        x=1,y=2,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 3);
+        should(atBorder == BottomFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        //directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        //directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------BottomRightFrontBorder--------------//
+        x=2,y=2,z=0;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 4);
+        should(atBorder == BottomRightFrontBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        //directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        //directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        //directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+
+////////test middle plane in volume
+
+        //-------------TopLeftBorder--------------//
+        x=0,y=0,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 0);
+        should(atBorder == TopLeftBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        //directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        //directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------TopBorder--------------//
+        x=1,y=0,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 0);
+        should(atBorder == TopBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        //directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------TopRightBorder--------------//
+        x=2,y=0,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 1);
+        should(atBorder == TopRightBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        //directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        //directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------LeftBorder--------------//
+        x=0,y=1,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 0);
+        should(atBorder == LeftBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        //directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------NotAtBorder--------------//
+        x=1,y=1,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 0);
+        should(atBorder == NotAtBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------RightBorder--------------//
+        x=2,y=1,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 1);
+        should(atBorder == RightBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        //directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------BottomLeftBorder--------------//
+        x=0,y=2,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 3);
+        should(atBorder == BottomLeftBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        //directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        //directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------BottomBorder--------------//
+        x=1,y=2,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 3);
+        should(atBorder == BottomBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        //directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------BottomRightBorder--------------//
+        x=2,y=2,z=1;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 4);
+        should(atBorder == BottomRightBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        //directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        //directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        directions.insert(Neighborhood3DTwentySix::BehindWest);
+        directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+////////test back plane in volume
+
+        //-------------TopLeftRearBorder--------------//
+        x=0,y=0,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 9);
+        should(atBorder == TopLeftRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        //directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        //directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        //directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------TopRearBorder--------------//
+        x=1,y=0,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 9);
+        should(atBorder == TopRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        //directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        //directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------TopRightRearBorder--------------//
+        x=2,y=0,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 10);
+        should(atBorder == TopRightRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        //directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        //directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        //directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------RearLeftBorder--------------//
+        x=0,y=1,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 9);
+        should(atBorder == RearLeftBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        //directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        //directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------RearBorder--------------//
+        x=1,y=1,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 9);
+        should(atBorder == RearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        //directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------RearRightBorder--------------//
+        x=2,y=1,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 10);
+        should(atBorder == RearRightBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        //directions.insert(Neighborhood3DTwentySix::East);
+        directions.insert(Neighborhood3DTwentySix::SouthWest);
+        directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        //directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------BottomLeftRearBorder--------------//
+        x=0,y=2,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 12);
+        should(atBorder == BottomLeftRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        //directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        //directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        //directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------BottomRearBorder--------------//
+        x=1,y=2,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 12);
+        should(atBorder == BottomRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        //directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        //directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+        //-------------BottomRightRearBorder--------------//
+        x=2,y=2,z=2;
+        atBorder = isAtVolumeBorder(x,y,z,w,h,d);
+        twentySixTrav = TwentySixTraverser(vol.traverser_begin() + vigra::Diff3D(x,y,z), atBorder);
+        should(*twentySixTrav == 13);
+        should(atBorder == BottomRightRearBorder);
+
+        //clear direction list and fill to compare
+        directions.clear();
+        directions.insert(Neighborhood3DTwentySix::InFrontNorthWest);
+        directions.insert(Neighborhood3DTwentySix::InFrontNorth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontNorthEast);
+        directions.insert(Neighborhood3DTwentySix::InFrontWest);
+        directions.insert(Neighborhood3DTwentySix::InFront);
+        //directions.insert(Neighborhood3DTwentySix::InFrontEast);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouth);
+        //directions.insert(Neighborhood3DTwentySix::InFrontSouthEast);
+
+        directions.insert(Neighborhood3DTwentySix::NorthWest);
+        directions.insert(Neighborhood3DTwentySix::North);
+        //directions.insert(Neighborhood3DTwentySix::NorthEast);
+        directions.insert(Neighborhood3DTwentySix::West);
+        //directions.insert(Neighborhood3DTwentySix::East);
+        //directions.insert(Neighborhood3DTwentySix::SouthWest);
+        //directions.insert(Neighborhood3DTwentySix::South);
+        //directions.insert(Neighborhood3DTwentySix::SouthEast);
+
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorth);
+        //directions.insert(Neighborhood3DTwentySix::BehindNorthEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindWest);
+        //directions.insert(Neighborhood3DTwentySix::Behind);
+        //directions.insert(Neighborhood3DTwentySix::BehindEast);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthWest);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouth);
+        //directions.insert(Neighborhood3DTwentySix::BehindSouthEast);
+
+
+        start = *twentySixTrav;
+        dir_Iter=directions.begin();
+        do{
+            //std::cerr << *dir_Iter << " =?= " << twentySixTrav.direction() << std::endl;
+            should(*dir_Iter == twentySixTrav.direction());
+            twentySixTrav++;
+            dir_Iter++;
+        }while(*twentySixTrav!=start);
+
+    }
+};
+
+struct NeighborhoodCirculator3dTestSuite
+: public vigra::test_suite
+{
+    NeighborhoodCirculator3dTestSuite()
+    : vigra::test_suite("NeighborhoodCirculator3dTestSuite")
+    {
+        add( testCase( &NeighborhoodCirculator3dTest::testInit));
+        add( testCase( &NeighborhoodCirculator3dTest::testSixTraverserForward));
+        add( testCase( &NeighborhoodCirculator3dTest::testSixTraverserBackward));
+        add( testCase( &NeighborhoodCirculator3dTest::testTwentySixTraverserForward));
+        add( testCase( &NeighborhoodCirculator3dTest::testTwentySixTraverserBackward));
+        add( testCase( &NeighborhoodCirculator3dTest::testIsDiagonal));
+        add( testCase( &NeighborhoodCirculator3dTest::testEquality));
+        add( testCase( &NeighborhoodCirculator3dTest::testTurning));
+        add( testCase( &NeighborhoodCirculator3dTest::testMoving));
+        add( testCase( &NeighborhoodCirculator3dTest::testMiscellaneous));
+
+        add( testCase( &RestrictedNeighborhoodCirculator3dTest::testInit));
+        add( testCase( &RestrictedNeighborhoodCirculator3dTest::testBordersSix));
+        add( testCase( &RestrictedNeighborhoodCirculator3dTest::testBordersTwentySix));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    NeighborhoodCirculator3dTestSuite test;
+
+    int failed = test.run(vigra::testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+    return (failed != 0);
+}
+
diff --git a/test/watersheds3d/CMakeLists.txt b/test/watersheds3d/CMakeLists.txt
new file mode 100644
index 0000000..da3b76a
--- /dev/null
+++ b/test/watersheds3d/CMakeLists.txt
@@ -0,0 +1 @@
+VIGRA_ADD_TEST(test_watersheds3d test.cxx LIBRARIES vigraimpex)
diff --git a/test/watersheds3d/test.cxx b/test/watersheds3d/test.cxx
new file mode 100644
index 0000000..98410b9
--- /dev/null
+++ b/test/watersheds3d/test.cxx
@@ -0,0 +1,503 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2004 by F. Heinrich, B. Seppke, Ullrich Koethe       */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#include <iostream>
+#include <functional>
+#include <cmath>
+#include "vigra/unittest.hxx"
+
+#include "vigra/watersheds3d.hxx"
+#include "vigra/multi_array.hxx"
+#include "vigra/multi_watersheds.hxx"
+#include "list"
+
+#include <stdlib.h>
+#include <time.h>
+
+
+using namespace vigra;
+
+struct Watersheds3dTest
+{
+    typedef MultiArray<3,int> IntVolume;
+    typedef MultiArray<3,double> DVolume;
+    typedef TinyVector<int,3> IntVec;
+
+    enum { WIDTH    =   100, // 
+           HEIGHT   =   100, // Volume-Dimensionen
+           DEPTH    =   100 }; //
+
+    DVolume volume;
+    IntVolume shouldVol;
+    std::list<std::list<IntVec> > pointslists;
+
+    Watersheds3dTest()
+    : volume(IntVolume::difference_type(WIDTH,HEIGHT,DEPTH)),
+      shouldVol(IntVolume::difference_type(WIDTH,HEIGHT,DEPTH))
+    {
+        std::list<IntVec> temp;
+        temp.push_back(IntVec(      0,        0,       0));
+        temp.push_back(IntVec(WIDTH-1,        0,       0));
+        temp.push_back(IntVec(      0, HEIGHT-1,       0));
+        temp.push_back(IntVec(WIDTH-1, HEIGHT-1,       0));
+        temp.push_back(IntVec(      0,        0, DEPTH-1));
+        temp.push_back(IntVec(WIDTH-1,        0, DEPTH-1));
+        temp.push_back(IntVec(      0, HEIGHT-1, DEPTH-1));
+        temp.push_back(IntVec(WIDTH-1, HEIGHT-1, DEPTH-1));
+        pointslists.push_back(temp);
+
+        temp.clear();
+        temp.push_back(IntVec(      0,        3,       4));
+        temp.push_back(IntVec(      0,        3,       6));
+        temp.push_back(IntVec(      0,        5,       4));
+        temp.push_back(IntVec(      0,        5,       6));
+        pointslists.push_back(temp);
+
+        temp.clear();
+        temp.push_back(IntVec(     80,       98,      77));
+        temp.push_back(IntVec(     33,        8,      97));
+        temp.push_back(IntVec(     93,       85,      30));
+        temp.push_back(IntVec(     73,       62,      43));
+        temp.push_back(IntVec(     93,       84,      14));
+        temp.push_back(IntVec(     87,       31,      61));
+        temp.push_back(IntVec(     44,       12,      20));
+        temp.push_back(IntVec(      1,       29,      86));
+        temp.push_back(IntVec(      1,       65,      87));
+        temp.push_back(IntVec(     26,       40,      71));
+        pointslists.push_back(temp);
+
+        temp.clear();
+        temp.push_back(IntVec(      0, HEIGHT/2, DEPTH/2));
+        temp.push_back(IntVec(WIDTH/2, HEIGHT/2,       0));
+        temp.push_back(IntVec(WIDTH/2,        0, DEPTH/2));
+        temp.push_back(IntVec(WIDTH-1, HEIGHT/2, DEPTH/2));
+        temp.push_back(IntVec(WIDTH/2, HEIGHT/2, DEPTH-1));
+        temp.push_back(IntVec(WIDTH/2, HEIGHT-1, DEPTH/2));
+        pointslists.push_back(temp);
+    }
+
+    void testDistanceVolumesSix()
+    {    
+        for(std::list<std::list<IntVec> >::iterator list_iter=pointslists.begin(); list_iter!=pointslists.end(); ++list_iter){
+            IntVec temp;
+            for(int z=0; z<DEPTH; ++z)
+                for(int y=0; y<HEIGHT; ++y)
+                    for(int x=0; x<WIDTH; ++x){
+                        temp = IntVec(x,y,z);
+                        int tempVal=10000000;
+                        for(std::list<IntVec>::iterator iter=(*list_iter).begin(); iter!=(*list_iter).end(); ++iter){
+                            if((temp-*iter).squaredMagnitude()<tempVal){
+                                tempVal = (temp-*iter).squaredMagnitude();
+                            }
+                        }
+                        volume(x,y,z)=tempVal;
+                    }
+
+            //Watersheds3D
+            IntVolume labelVolume(IntVolume::difference_type(WIDTH,HEIGHT,DEPTH));
+
+            int max_region_label = watersheds3DSix( srcMultiArrayRange(volume),
+                                                        destMultiArray(labelVolume));
+            should(max_region_label == (int)(*list_iter).size());
+        }
+    }
+
+    void testDistanceVolumesTwentySix()
+    {
+        for(std::list<std::list<IntVec> >::iterator list_iter=pointslists.begin(); list_iter!=pointslists.end(); ++list_iter){
+            IntVec temp;
+            for(int z=0; z<DEPTH; ++z)
+                for(int y=0; y<HEIGHT; ++y)
+                    for(int x=0; x<WIDTH; ++x){
+                        temp = IntVec(x,y,z);
+                        int tempVal=10000000;
+                        for(std::list<IntVec>::iterator iter=(*list_iter).begin(); iter!=(*list_iter).end(); ++iter){
+                            if((temp-*iter).squaredMagnitude()<tempVal){
+                                    tempVal = (temp-*iter).squaredMagnitude();
+                            }
+                        }
+                        volume(x,y,z)=tempVal;
+                    }
+
+            //Watersheds3D
+            IntVolume labelVolume(IntVolume::difference_type(WIDTH,HEIGHT,DEPTH));
+
+            int max_region_label = watersheds3DTwentySix( srcMultiArrayRange(volume),
+                                                                destMultiArray(labelVolume));
+            should(max_region_label == (int)(*list_iter).size());
+        }
+    }
+
+    void testWatersheds3dSix1()
+    {
+        static const int data[] = {
+            6, 5, 4, 5,    
+            7, 6, 5, 6,    
+           10, 9, 8, 9,  
+            6, 5, 4, 5,
+
+            5, 3, 2, 3,  
+            6, 4, 3, 4,    
+            9, 7, 6, 7,  
+            5, 3, 2, 3,
+
+            4, 2, 1, 2,  
+            5, 3, 2, 3,    
+            8, 6, 5, 6,  
+            4, 2, 1, 2,
+
+            5, 3, 2, 3,  
+            6, 4, 3, 4,    
+            9, 7, 6, 7,  
+            5, 3, 2, 3
+        };
+
+        IntVolume vol(IntVolume::difference_type(4,4,4));
+        const int *i=data;
+        for(IntVolume::iterator iter=vol.begin(); iter!=vol.end(); ++iter, ++i){
+            *iter=*i;
+        }
+
+        static const int desired[] = {
+            1, 1, 1, 1,  
+            1, 1, 1, 1,    
+            2, 2, 2, 2, 
+            2, 2, 2, 2,
+
+            1, 1, 1, 1, 
+            1, 1, 1, 1,    
+            2, 2, 2, 2, 
+            2, 2, 2, 2,
+
+            1, 1, 1, 1, 
+            1, 1, 1, 1,    
+            2, 2, 2, 2,  
+            2, 2, 2, 2,
+
+            1, 1, 1, 1, 
+            1, 1, 1, 1,    
+            2, 2, 2, 2, 
+            2, 2, 2, 2
+        };
+
+        IntVolume labelVolume(vol.shape()), labelVolume2(vol.shape());
+
+        int max_region_label = watersheds3DSix( srcMultiArrayRange(vol),
+                                                       destMultiArray(labelVolume));
+        
+        shouldEqual(max_region_label, 2);
+        
+        //int c=1;
+        //for(IntVolume::iterator iter=labelVolume.begin(); iter!=labelVolume.end(); ++iter, ++c){
+            //std::cerr << *iter << ", ";
+            //if(c%4==0) std::cerr << std::endl;
+            //if(c%16==0) std::cerr << std::endl;
+        //}
+
+        shouldEqualSequence(labelVolume.begin(), labelVolume.end(), desired);
+
+        should(2 == watershedsMultiArray(vol, labelVolume2, DirectNeighborhood, WatershedOptions().unionFind()));
+        should(labelVolume == labelVolume2);
+    }
+
+    void testWatersheds3dSix2()
+    {
+        static const double data[] = {
+            3.0, 2.0, 3.0,    
+            7.0, 6.0, 7.0,      
+            2.0, 3.0, 4.0,
+
+            2.0, 1.0, 2.0, 
+            6.0, 5.0, 6.0,
+            3.0, 2.1, 3.1,
+
+            3.0, 2.0, 3.0, 
+            7.0, 6.0, 7.0,    
+            4.0, 3.1, 4.0
+        };
+
+        DVolume vol(Shape3(3,3,3));
+        const double *i=data;
+        for(DVolume::iterator iter=vol.begin(); iter!=vol.end(); ++iter, ++i){
+            *iter=*i;
+        }
+
+        static const int desired[] = {
+            1, 1, 1,
+            2, 1, 1,
+            2, 2, 2,
+
+            1, 1, 1,
+            1, 1, 1,
+            2, 3, 3,
+
+            1, 1, 1,
+            1, 1, 1,
+            2, 3, 3
+        };
+
+        IntVolume labelVolume(vol.shape()), labelVolume2(vol.shape());
+
+        int max_region_label = watersheds3DSix( vol, labelVolume);
+
+        shouldEqual(max_region_label, 3);
+        shouldEqualSequence(labelVolume.begin(), labelVolume.end(), desired);
+
+        should(3 == watershedsMultiArray(vol, labelVolume2, DirectNeighborhood, WatershedOptions().unionFind()));
+        should(labelVolume == labelVolume2);
+    }
+
+    void testWatersheds3dGradient1()
+    {
+        int w=4,h=4,d=8;
+
+        IntVolume vol(IntVolume::difference_type(w,h,d));
+
+        static const int data[] = {
+            0, 0, 0, 0, 
+            0, 0, 0, 0, 
+            0, 0, 0, 0, 
+            0, 0, 0, 0,
+
+            0, 0, 0, 0, 
+            0, 0, 0, 0, 
+            0, 0, 0, 0, 
+            0, 0, 0, 0,
+
+            4, 4, 4, 4, 
+            4, 4, 4, 4, 
+            4, 4, 4, 4, 
+            4, 4, 4, 4,
+
+            9, 9, 9, 9,  
+            9, 9, 9, 9,    
+            9, 9, 9, 9,  
+            9, 9, 9, 9,
+
+            9, 9, 9, 9,  
+            9, 9, 9, 9,    
+            9, 9, 9, 9,  
+            9, 9, 9, 9,
+
+            4, 4, 4, 4, 
+            4, 4, 4, 4, 
+            4, 4, 4, 4, 
+            4, 4, 4, 4,
+
+            0, 0, 0, 0, 
+            0, 0, 0, 0, 
+            0, 0, 0, 0, 
+            0, 0, 0, 0,
+
+            0, 0, 0, 0, 
+            0, 0, 0, 0, 
+            0, 0, 0, 0, 
+            0, 0, 0, 0
+        };
+
+        const int *i=data;
+        for(IntVolume::iterator iter=vol.begin(); iter!=vol.end(); ++iter, ++i){
+            *iter=*i;
+        }
+
+ 
+        IntVolume labelVolume(vol.shape()), labelVolume2(vol.shape());
+
+        int max_region_label = watersheds3DSix( srcMultiArrayRange(vol),
+                                                       destMultiArray(labelVolume));
+        shouldEqual(2, max_region_label);
+        using namespace multi_math;
+        should(all(labelVolume.subarray(Shape3(0), Shape3(w,h,d/2)) == 1));
+        should(all(labelVolume.subarray(Shape3(w,h,d/2), Shape3(w,h,d)) == 2));
+
+        max_region_label = watersheds3DTwentySix( srcMultiArrayRange(vol),
+                                                  destMultiArray(labelVolume2));
+
+        shouldEqual(2, max_region_label);        
+        should(all(labelVolume == labelVolume2));
+
+        labelVolume2.init(0);
+        should(2 == watershedsMultiArray(vol, labelVolume2, DirectNeighborhood, WatershedOptions().unionFind()));
+        should(all(labelVolume == labelVolume2));
+
+        labelVolume2.init(0);
+        should(2 == watershedsMultiArray(vol, labelVolume2, IndirectNeighborhood, WatershedOptions().unionFind()));
+        should(all(labelVolume == labelVolume2));
+    }
+
+    void testWatersheds3dGradient2()
+    {
+        int w=8,h=8,d=8;
+
+        IntVolume vol(IntVolume::difference_type(w,h,d));
+
+        static const int data[] = {
+
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,  
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            0, 0, 4, 9, 9, 4, 0, 0,
+
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            4, 4, 4, 9, 9, 4, 4, 4,   
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,   
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            0, 0, 4, 9, 9, 4, 0, 0,
+
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,   
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            4, 4, 4, 9, 9, 4, 4, 4,
+
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,  
+           10,10,10,12,12,10,10,10,  
+           10,10,10,12,12,10,10,10, 
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,
+
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,  
+           10,10,10,12,12,10,10,10,  
+           10,10,10,12,12,10,10,10, 
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,
+
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,   
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            4, 4, 4, 9, 9, 4, 4, 4,
+
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,   
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            0, 0, 4, 9, 9, 4, 0, 0,
+
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            9, 9, 9,10,10, 9, 9, 9,
+            9, 9, 9,10,10, 9, 9, 9,   
+            4, 4, 4, 9, 9, 4, 4, 4,  
+            0, 0, 4, 9, 9, 4, 0, 0,  
+            0, 0, 4, 9, 9, 4, 0, 0
+
+        };
+
+        const int *i=data;
+        for(IntVolume::iterator iter=vol.begin(); iter!=vol.end(); ++iter, ++i){
+            *iter=*i;
+        }
+
+        IntVolume labelVolume(Shape3(w,h,d)), labelVolume2(Shape3(w,h,d));
+
+        int max_region_label = watersheds3DSix( srcMultiArrayRange(vol),
+                                                       destMultiArray(labelVolume));
+        shouldEqual(8, max_region_label);
+
+        // each octand should be one region
+        for(int z=0; z<d; ++z){
+            for(int y=0; y<h; ++y){
+                for(int x=0; x<w; ++x){
+                    shouldEqual( labelVolume(x,y,z)-1, ( ((z>=d/2.0)<<2) | ((y>=h/2.0)<<1) |((x>=w/2.0)<<0) ) );
+                }
+            }
+        }
+
+        max_region_label = watersheds3DTwentySix( vol, labelVolume2);
+        shouldEqual(8, max_region_label);
+        should(labelVolume == labelVolume2);
+
+        labelVolume2.init(0);
+        max_region_label = watershedsMultiArray(vol, labelVolume2, DirectNeighborhood, WatershedOptions().unionFind());
+        shouldEqual(8, max_region_label);
+        should(labelVolume == labelVolume2);
+
+        labelVolume2.init(0);
+        max_region_label = watershedsMultiArray(vol, labelVolume2, IndirectNeighborhood, WatershedOptions().unionFind());
+        shouldEqual(8, max_region_label);
+        should(labelVolume == labelVolume2);
+    }
+};
+
+
+struct Watershed3DTestSuite
+: public test_suite
+{
+    Watershed3DTestSuite()
+    : test_suite("Watershed3DTestSuite")
+    {
+        add( testCase( &Watersheds3dTest::testDistanceVolumesSix));
+        add( testCase( &Watersheds3dTest::testDistanceVolumesTwentySix));
+        add( testCase( &Watersheds3dTest::testWatersheds3dSix1));
+        add( testCase( &Watersheds3dTest::testWatersheds3dSix2));
+        add( testCase( &Watersheds3dTest::testWatersheds3dGradient1));
+        add( testCase( &Watersheds3dTest::testWatersheds3dGradient2));
+    }
+};
+
+int main(int argc, char ** argv)
+{
+    Watershed3DTestSuite test;
+
+    int failed = test.run(testsToBeExecuted(argc, argv));
+
+    std::cout << test.report() << std::endl;
+    return (failed != 0);
+}
+
diff --git a/vigranumpy/CMakeLists.txt b/vigranumpy/CMakeLists.txt
new file mode 100644
index 0000000..78bec61
--- /dev/null
+++ b/vigranumpy/CMakeLists.txt
@@ -0,0 +1,83 @@
+IF(VIGRANUMPY_DEPENDENCIES_FOUND)
+    ADD_CUSTOM_TARGET(vigranumpy)
+    ADD_DEPENDENCIES(vigranumpy vigraimpex)
+
+    SET(vigranumpy_tmp_dir "${CMAKE_BINARY_DIR}/vigranumpy/vigra")
+    FILE(MAKE_DIRECTORY ${vigranumpy_tmp_dir})
+
+    INCLUDE_DIRECTORIES(${VIGRANUMPY_INCLUDE_DIRS})
+
+    # configure boost's autolink magic to use the right library name
+    # (default on Windows is a mangled name like 'boost_python-vc110-mt-1_51.lib')
+    if("${Boost_PYTHON_LIBRARY}" MATCHES "boost_python\\.lib")
+        ADD_DEFINITIONS(-DBOOST_AUTO_LINK_NOMANGLE)
+    endif()
+        
+    IF(HDF5_FOUND)
+        ADD_DEFINITIONS(-DHasHDF5 ${HDF5_CPPFLAGS})
+        INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIR})
+        SET(VIGRANUMPY_IMPEX_LIBRARIES vigraimpex ${HDF5_LIBRARIES})
+    ELSE()
+        SET(VIGRANUMPY_IMPEX_LIBRARIES vigraimpex)
+    ENDIF(HDF5_FOUND)
+
+    IF(MSVC OR MINGW)
+        ADD_DEFINITIONS(-DVIGRA_DLL)
+    ENDIF ()
+    
+    include(VIGRA_ADD_NUMPY_MODULE)
+
+    ADD_SUBDIRECTORY(src)
+    ADD_SUBDIRECTORY(lib)
+    ADD_SUBDIRECTORY(test)
+    ADD_SUBDIRECTORY(docsrc)
+
+    IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/private/CMakeLists.txt)
+        ADD_SUBDIRECTORY(private EXCLUDE_FROM_ALL)
+    ENDIF()
+    
+    IF(PYTHON_PLATFORM MATCHES "^windows$")
+        FILE(MAKE_DIRECTORY ${vigranumpy_tmp_dir}/dlls)    
+        GET_TARGET_PROPERTY(VIGRAIMPEX_LOCATION vigraimpex LOCATION)
+        file(RELATIVE_PATH VIGRAIMPEX_DOCDIR ${vigranumpy_tmp_dir} ${DOCDIR})
+        
+        CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in
+                        ${CMAKE_CURRENT_BINARY_DIR}/setup.py
+                        @ONLY)
+
+        add_custom_target(PACKAGE_VIGRANUMPY 
+                           COMMAND ${CMAKE_COMMAND} -E copy_directory ${DOCDIR} ${vigranumpy_tmp_dir}/doc
+                           COMMAND python setup.py bdist_wininst
+                           DEPENDS check
+                           WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+                           COMMENT "Creating vigranumpy setup in ${CMAKE_CURRENT_BINARY_DIR}/dist")        
+    ENDIF()
+    
+    set(VIGRANUMPY_CONFIG_INSTALL_PATH lib${LIB_SUFFIX}/vigranumpy)
+    
+    set(VIGRANUMPY_INCLUDE_RELATIVE "")
+    foreach(PATH ${CMAKE_INSTALL_PREFIX}/include ${VIGRANUMPY_INCLUDE_DIRS})
+        file(RELATIVE_PATH RELPATH ${CMAKE_INSTALL_PREFIX}/${VIGRANUMPY_CONFIG_INSTALL_PATH} ${PATH})
+        set(VIGRANUMPY_INCLUDE_RELATIVE ${VIGRANUMPY_INCLUDE_RELATIVE} ${RELPATH})
+    endforeach(PATH)
+    
+    set(VIGRANUMPY_LIBRARIES_RELATIVE "")
+    foreach(PATH ${VIGRANUMPY_LIBRARIES})
+        if(EXISTS ${PATH})
+            file(RELATIVE_PATH RELPATH ${CMAKE_INSTALL_PREFIX}/${VIGRANUMPY_CONFIG_INSTALL_PATH} ${PATH})
+            set(VIGRANUMPY_LIBRARIES_RELATIVE ${VIGRANUMPY_LIBRARIES_RELATIVE} ${RELPATH})
+        else()
+            # If ${PATH} is not referring to a path, it is probably a keyword like 
+            # "optimized" or "debug" (e.g. on the Mac). We then pass it on unchanged. 
+            set(VIGRANUMPY_LIBRARIES_RELATIVE ${VIGRANUMPY_LIBRARIES_RELATIVE} ${PATH})
+        endif()
+    endforeach(PATH)
+    
+    CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/config/VigranumpyConfig.cmake.in
+            ${PROJECT_BINARY_DIR}/lib/vigranumpy/CMake/VigranumpyConfig.cmake
+            @ONLY IMMEDIATE)
+    INSTALL(FILES ${PROJECT_BINARY_DIR}/lib/vigranumpy/CMake/VigranumpyConfig.cmake
+            DESTINATION ${VIGRANUMPY_CONFIG_INSTALL_PATH})
+ENDIF()
+
+
diff --git a/vigranumpy/docsrc/CMakeLists.txt b/vigranumpy/docsrc/CMakeLists.txt
new file mode 100644
index 0000000..547cf81
--- /dev/null
+++ b/vigranumpy/docsrc/CMakeLists.txt
@@ -0,0 +1,64 @@
+IF(PYTHON_SPHINX)
+    # vigranumpy documentation generation using sphinx
+    IF(DEFINED VIGRANUMPY_DOCDIR)
+        MESSAGE(SEND_ERROR "VIGRANUMPY_DOCDIR already defined! Please delete from Cache.")
+    ENDIF()
+    SET(VIGRANUMPY_DOCDIR ${DOCDIR}/vigranumpy)
+    SET(SPHINX_OPTS ${SPHINX_OPTS} CACHE STRING
+        "options passed to sphinx during vigranumpy doc generation"
+        FORCE)
+    IF(NOT DEFINED SPHINX_PAPER)
+        SET(SPHINX_PAPER a4)
+    ENDIF()
+    SET(SPHINX_PAPER ${SPHINX_PAPER} CACHE STRING
+        "Papersize for sphinx documentation generation (a4, letter)"
+        FORCE)
+    SET(SPHINX_ALLOPTS
+        -d ${VIGRANUMPY_DOCDIR}/doctrees
+        -D latex_paper_size=${SPHINX_PAPER}
+        -c ${CMAKE_CURRENT_BINARY_DIR}
+        ${SPHINX_OPTS})
+    file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/_static)
+    configure_file(_static/vigra-icon.ico ${CMAKE_CURRENT_BINARY_DIR}/_static/vigra-icon.ico COPYONLY)
+    
+    DEPENDENCY_PATH(VIGRAIMPEX_PATH vigraimpex)
+    STRING(REGEX REPLACE "/vigra$" "" VIGRANUMPY_TMP_PATH ${vigranumpy_tmp_dir})   
+    
+    CONFIGURE_FILE(
+        ${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in
+        ${CMAKE_CURRENT_BINARY_DIR}/conf.py
+        @ONLY)
+    
+    # VIGRA_CONFIGURATION is 'release' or 'debug' on Windows, nothing on Linux
+    # variable CMAKE_CFG_INTDIR contains a dot '.' for a Windows nmake build, or
+    #                           '$(OutDir)' for a VisualStudio build (OutDir will be
+    #                           set by VS at build time)
+    IF(CMAKE_CFG_INTDIR AND NOT CMAKE_CFG_INTDIR STREQUAL ".")
+        SET(VIGRA_CONFIGURATION -D build_configuration=${CMAKE_CFG_INTDIR})
+    ELSE()
+        SET(VIGRA_CONFIGURATION)
+    ENDIF()
+
+    ADD_CUSTOM_TARGET (doc_python
+        COMMAND ${CMAKE_COMMAND} -E make_directory
+            ${VIGRANUMPY_DOCDIR}
+        COMMAND ${PYTHON_SPHINX} -b html
+            ${SPHINX_ALLOPTS}
+            ${VIGRA_CONFIGURATION}
+            ${CMAKE_CURRENT_SOURCE_DIR}
+            ${VIGRANUMPY_DOCDIR}
+        COMMENT "Generating vigranumpy documentation")
+
+ELSE(PYTHON_SPHINX)
+    # no vigranumpy documentation if sphinx not available
+    ADD_CUSTOM_TARGET (doc_python 
+        ${CMAKE_COMMAND} -E echo
+        "Cannot generate Python documentation for vigranumpy. "
+        "(sphinx-build not found)"
+        VERBATIM)
+
+ENDIF(PYTHON_SPHINX)
+
+ADD_DEPENDENCIES(doc_python vigranumpy)
+ADD_DEPENDENCIES(doc_python doc_cpp)
+ADD_DEPENDENCIES(doc doc_python)
diff --git a/vigranumpy/docsrc/_static/basic.css b/vigranumpy/docsrc/_static/basic.css
new file mode 100644
index 0000000..c726798
--- /dev/null
+++ b/vigranumpy/docsrc/_static/basic.css
@@ -0,0 +1,413 @@
+/**
+ * Sphinx stylesheet -- basic theme
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+    clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+    width: 100%;
+    font-size: 90%;
+}
+
+div.related h3 {
+    display: none;
+}
+
+div.related ul {
+    margin: 0;
+    padding: 0 0 0 10px;
+    list-style: none;
+}
+
+div.related li {
+    display: inline;
+}
+
+div.related li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+    padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+    float: left;
+    width: 230px;
+    margin-left: -100%;
+    font-size: 90%;
+}
+
+div.sphinxsidebar ul {
+    list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+    margin-left: 20px;
+    list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+    margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+img {
+    border: 0;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+    margin: 10px 0 0 20px;
+    padding: 0;
+}
+
+ul.search li {
+    padding: 5px 0 5px 20px;
+    background-image: url(file.png);
+    background-repeat: no-repeat;
+    background-position: 0 7px;
+}
+
+ul.search li a {
+    font-weight: bold;
+}
+
+ul.search li div.context {
+    color: #888;
+    margin: 2px 0 0 30px;
+    text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+    font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+    width: 90%;
+}
+
+table.contentstable p.biglink {
+    line-height: 150%;
+}
+
+a.biglink {
+    font-size: 1.3em;
+}
+
+span.linkdescr {
+    font-style: italic;
+    padding-top: 5px;
+    font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable td {
+    text-align: left;
+    vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+    height: 10px;
+}
+
+table.indextable tr.cap {
+    margin-top: 10px;
+    background-color: #f2f2f2;
+}
+
+img.toggler {
+    margin-right: 3px;
+    margin-top: 3px;
+    cursor: pointer;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+a.headerlink {
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+div.body p.caption {
+    text-align: inherit;
+}
+
+div.body td {
+    text-align: left;
+}
+
+.field-list ul {
+    padding-left: 1em;
+}
+
+.first {
+    margin-top: 0 !important;
+}
+
+p.rubric {
+    margin-top: 30px;
+    font-weight: bold;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+    margin: 0 0 0.5em 1em;
+    border: 1px solid #ddb;
+    padding: 7px 7px 0 7px;
+    background-color: #ffe;
+    width: 40%;
+    float: right;
+}
+
+p.sidebar-title {
+    font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+    border: 1px solid #ccc;
+    padding: 7px 7px 0 7px;
+    margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+    font-size: 1.1em;
+    font-weight: bold;
+    margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+    margin-top: 10px;
+    margin-bottom: 10px;
+    padding: 7px;
+}
+
+div.admonition dt {
+    font-weight: bold;
+}
+
+div.admonition dl {
+    margin-bottom: 0;
+}
+
+p.admonition-title {
+    margin: 0px 10px 5px 0px;
+    font-weight: bold;
+}
+
+div.body p.centered {
+    text-align: center;
+    margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+    border: 0;
+    border-collapse: collapse;
+}
+
+table.docutils td, table.docutils th {
+    padding: 1px 8px 1px 0;
+    border-top: 0;
+    border-left: 0;
+    border-right: 0;
+    border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+    border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+    border: 0 !important;
+}
+
+th {
+    text-align: left;
+    padding-right: 5px;
+}
+
+/* -- other body styles ----------------------------------------------------- */
+
+dl {
+    margin-bottom: 15px;
+}
+
+dd p {
+    margin-top: 0px;
+}
+
+dd ul, dd table {
+    margin-bottom: 10px;
+}
+
+dd {
+    margin-top: 3px;
+    margin-bottom: 10px;
+    margin-left: 30px;
+}
+
+dt:target, .highlight {
+    background-color: #fbe54e;
+}
+
+dl.glossary dt {
+    font-weight: bold;
+    font-size: 1.1em;
+}
+
+.field-list ul {
+    margin: 0;
+    padding-left: 1em;
+}
+
+.field-list p {
+    margin: 0;
+}
+
+.refcount {
+    color: #060;
+}
+
+.optional {
+    font-size: 1.3em;
+}
+
+.versionmodified {
+    font-style: italic;
+}
+
+.system-message {
+    background-color: #fda;
+    padding: 5px;
+    border: 3px solid red;
+}
+
+.footnote:target  {
+    background-color: #ffa
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+    overflow: auto;
+}
+
+td.linenos pre {
+    padding: 5px 0px;
+    border: 0;
+    background-color: transparent;
+    color: #aaa;
+}
+
+table.highlighttable {
+    margin-left: 0.5em;
+}
+
+table.highlighttable td {
+    padding: 0 0.5em 0 0.5em;
+}
+
+em.property {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.2em;
+}
+
+tt.descname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.7em;
+}
+
+tt.descclassname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.7em;
+}
+
+tt.xref, a tt {
+    background-color: transparent;
+    font-weight: bold;
+}
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+    background-color: transparent;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+    vertical-align: middle;
+}
+
+div.body div.math p {
+    text-align: center;
+}
+
+span.eqno {
+    float: right;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+ at media print {
+    div.document,
+    div.documentwrapper,
+    div.bodywrapper {
+        margin: 0;
+        width: 100%;
+    }
+
+    div.sphinxsidebar,
+    div.related,
+    div.footer,
+    #top-link {
+        display: none;
+    }
+}
diff --git a/vigranumpy/docsrc/_static/default.css b/vigranumpy/docsrc/_static/default.css
new file mode 100644
index 0000000..c999f67
--- /dev/null
+++ b/vigranumpy/docsrc/_static/default.css
@@ -0,0 +1,210 @@
+/**
+ * Sphinx stylesheet -- default theme
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+ at import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+    font-family: sans-serif;
+    font-size: 100%;
+    background-color: #11303d;
+    color: #000;
+    margin: 0;
+    padding: 0;
+}
+
+div.document {
+    background-color: #1c4e63;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 230px;
+}
+
+div.body {
+    background-color: #ffffff;
+    color: #000000;
+    padding: 0 20px 30px 20px;
+}
+
+div.footer {
+    color: #ffffff;
+    width: 100%;
+    padding: 9px 0 9px 0;
+    text-align: center;
+    font-size: 75%;
+}
+
+div.footer a {
+    color: #ffffff;
+    text-decoration: underline;
+}
+
+div.related {
+    background-color: #133f52;
+    line-height: 30px;
+    color: #ffffff;
+}
+
+div.related a {
+    color: #ffffff;
+}
+
+div.sphinxsidebar {
+}
+
+div.sphinxsidebar h3 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: #ffffff;
+    font-size: 1.4em;
+    font-weight: normal;
+    margin: 0;
+    padding: 0;
+}
+
+div.sphinxsidebar h3 a {
+    color: #ffffff;
+}
+
+div.sphinxsidebar h4 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: #ffffff;
+    font-size: 1.3em;
+    font-weight: normal;
+    margin: 5px 0 0 0;
+    padding: 0;
+}
+
+div.sphinxsidebar p {
+    color: #ffffff;
+}
+
+div.sphinxsidebar p.topless {
+    margin: 5px 10px 10px 10px;
+}
+
+div.sphinxsidebar ul {
+    margin: 10px;
+    padding: 0;
+    color: #ffffff;
+}
+
+div.sphinxsidebar a {
+    color: #98dbcc;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+/* -- body styles ----------------------------------------------------------- */
+
+a {
+    color: #355f7c;
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+div.body p, div.body dd, div.body li {
+    text-align: justify;
+    line-height: 130%;
+}
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: 'Trebuchet MS', sans-serif;
+    background-color: #f2f2f2;
+    font-weight: normal;
+    color: #20435c;
+    border-bottom: 1px solid #ccc;
+    margin: 20px -20px 10px -20px;
+    padding: 3px 0 3px 10px;
+}
+
+div.body h1 { margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 160%; }
+div.body h3 { font-size: 140%; }
+div.body h4 { font-size: 120%; }
+div.body h5 { font-size: 110%; }
+div.body h6 { font-size: 100%; }
+
+a.headerlink {
+    color: #c60f0f;
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+}
+
+a.headerlink:hover {
+    background-color: #c60f0f;
+    color: white;
+}
+
+div.body p, div.body dd, div.body li {
+    text-align: justify;
+    line-height: 130%;
+}
+
+div.admonition p.admonition-title + p {
+    display: inline;
+}
+
+div.note {
+    background-color: #eee;
+    border: 1px solid #ccc;
+}
+
+div.seealso {
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+
+div.topic {
+    background-color: #eee;
+}
+
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #f66;
+}
+
+p.admonition-title {
+    display: inline;
+}
+
+p.admonition-title:after {
+    content: ":";
+}
+
+pre {
+    padding: 5px;
+    background-color: #eeffcc;
+    color: #333333;
+    line-height: 120%;
+    border: 1px solid #ac9;
+    border-left: none;
+    border-right: none;
+}
+
+tt {
+    background-color: #ecf0f3;
+    padding: 0 1px 0 1px;
+    font-size: 0.95em;
+}
\ No newline at end of file
diff --git a/vigranumpy/docsrc/_static/doctools.js b/vigranumpy/docsrc/_static/doctools.js
new file mode 100644
index 0000000..9447678
--- /dev/null
+++ b/vigranumpy/docsrc/_static/doctools.js
@@ -0,0 +1,232 @@
+/// XXX: make it cross browser
+
+/**
+ * make the code below compatible with browsers without
+ * an installed firebug like debugger
+ */
+if (!window.console || !console.firebug) {
+  var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
+      "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
+  window.console = {};
+  for (var i = 0; i < names.length; ++i)
+    window.console[names[i]] = function() {}
+}
+
+/**
+ * small helper function to urldecode strings
+ */
+jQuery.urldecode = function(x) {
+  return decodeURIComponent(x).replace(/\+/g, ' ');
+}
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+  if (typeof s == 'undefined')
+    s = document.location.search;
+  var parts = s.substr(s.indexOf('?') + 1).split('&');
+  var result = {};
+  for (var i = 0; i < parts.length; i++) {
+    var tmp = parts[i].split('=', 2);
+    var key = jQuery.urldecode(tmp[0]);
+    var value = jQuery.urldecode(tmp[1]);
+    if (key in result)
+      result[key].push(value);
+    else
+      result[key] = [value];
+  }
+  return result;
+}
+
+/**
+ * small function to check if an array contains
+ * a given item.
+ */
+jQuery.contains = function(arr, item) {
+  for (var i = 0; i < arr.length; i++) {
+    if (arr[i] == item)
+      return true;
+  }
+  return false;
+}
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+  function highlight(node) {
+    if (node.nodeType == 3) {
+      var val = node.nodeValue;
+      var pos = val.toLowerCase().indexOf(text);
+      if (pos >= 0 && !jQuery.className.has(node.parentNode, className)) {
+        var span = document.createElement("span");
+        span.className = className;
+        span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+        node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+          document.createTextNode(val.substr(pos + text.length)),
+          node.nextSibling));
+        node.nodeValue = val.substr(0, pos);
+      }
+    }
+    else if (!jQuery(node).is("button, select, textarea")) {
+      jQuery.each(node.childNodes, function() {
+        highlight(this)
+      });
+    }
+  }
+  return this.each(function() {
+    highlight(this);
+  });
+}
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+var Documentation = {
+
+  init : function() {
+    this.fixFirefoxAnchorBug();
+    this.highlightSearchWords();
+    this.initModIndex();
+  },
+
+  /**
+   * i18n support
+   */
+  TRANSLATIONS : {},
+  PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
+  LOCALE : 'unknown',
+
+  // gettext and ngettext don't access this so that the functions
+  // can savely bound to a different name (_ = Documentation.gettext)
+  gettext : function(string) {
+    var translated = Documentation.TRANSLATIONS[string];
+    if (typeof translated == 'undefined')
+      return string;
+    return (typeof translated == 'string') ? translated : translated[0];
+  },
+
+  ngettext : function(singular, plural, n) {
+    var translated = Documentation.TRANSLATIONS[singular];
+    if (typeof translated == 'undefined')
+      return (n == 1) ? singular : plural;
+    return translated[Documentation.PLURALEXPR(n)];
+  },
+
+  addTranslations : function(catalog) {
+    for (var key in catalog.messages)
+      this.TRANSLATIONS[key] = catalog.messages[key];
+    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
+    this.LOCALE = catalog.locale;
+  },
+
+  /**
+   * add context elements like header anchor links
+   */
+  addContextElements : function() {
+    $('div[id] > :header:first').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this headline')).
+      appendTo(this);
+    });
+    $('dt[id]').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this definition')).
+      appendTo(this);
+    });
+  },
+
+  /**
+   * workaround a firefox stupidity
+   */
+  fixFirefoxAnchorBug : function() {
+    if (document.location.hash && $.browser.mozilla)
+      window.setTimeout(function() {
+        document.location.href += '';
+      }, 10);
+  },
+
+  /**
+   * highlight the search words provided in the url in the text
+   */
+  highlightSearchWords : function() {
+    var params = $.getQueryParameters();
+    var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
+    if (terms.length) {
+      var body = $('div.body');
+      window.setTimeout(function() {
+        $.each(terms, function() {
+          body.highlightText(this.toLowerCase(), 'highlight');
+        });
+      }, 10);
+      $('<li class="highlight-link"><a href="javascript:Documentation.' +
+        'hideSearchWords()">' + _('Hide Search Matches') + '</a></li>')
+          .appendTo($('.sidebar .this-page-menu'));
+    }
+  },
+
+  /**
+   * init the modindex toggle buttons
+   */
+  initModIndex : function() {
+    var togglers = $('img.toggler').click(function() {
+      var src = $(this).attr('src');
+      var idnum = $(this).attr('id').substr(7);
+      console.log($('tr.cg-' + idnum).toggle());
+      if (src.substr(-9) == 'minus.png')
+        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
+      else
+        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
+    }).css('display', '');
+    if (DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX) {
+        togglers.click();
+    }
+  },
+
+  /**
+   * helper function to hide the search marks again
+   */
+  hideSearchWords : function() {
+    $('.sidebar .this-page-menu li.highlight-link').fadeOut(300);
+    $('span.highlight').removeClass('highlight');
+  },
+
+  /**
+   * make the url absolute
+   */
+  makeURL : function(relativeURL) {
+    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
+  },
+
+  /**
+   * get the current relative url
+   */
+  getCurrentURL : function() {
+    var path = document.location.pathname;
+    var parts = path.split(/\//);
+    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
+      if (this == '..')
+        parts.pop();
+    });
+    var url = parts.join('/');
+    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
+  }
+};
+
+// quick alias for translations
+_ = Documentation.gettext;
+
+$(document).ready(function() {
+  Documentation.init();
+});
diff --git a/vigranumpy/docsrc/_static/file.png b/vigranumpy/docsrc/_static/file.png
new file mode 100644
index 0000000..d18082e
Binary files /dev/null and b/vigranumpy/docsrc/_static/file.png differ
diff --git a/vigranumpy/docsrc/_static/jquery.js b/vigranumpy/docsrc/_static/jquery.js
new file mode 100644
index 0000000..82b98e1
--- /dev/null
+++ b/vigranumpy/docsrc/_static/jquery.js
@@ -0,0 +1,32 @@
+/*
+ * jQuery 1.2.6 - New Wave Javascript
+ *
+ * Copyright (c) 2008 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
+ * $Rev: 5685 $
+ */
+(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){ [...]
+return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);retur [...]
+return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.g [...]
+selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:fun [...]
+return(this[0].value||"").replace(/\r/g,"");}return undefined;}if(value.constructor==Number)value+='';return this.each(function(){if(this.nodeType!=1)return;if(value.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,value)>=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this. [...]
+this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);} [...]
+return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByT [...]
+jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i<length;i++)if((options=arguments[i])!=null)for( [...]
+script.appendChild(document.createTextNode(data));head.insertBefore(script,head.firstChild);head.removeChild(script);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;var id=elem[expando];if(!id)id=elem[expando]=++uuid;if(name&&!jQuery.cache[id])jQuery.cache[id]={};if(data!==undefined)jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData: [...]
+for(;i<length;)if(callback.apply(object[i++],args)===false)break;}else{if(length==undefined){for(name in object)if(callback.call(object[name],name,object[name])===false)break;}else
+for(var value=object[0];i<length&&callback.call(value,i,value)!==false;value=object[++i]){}}return object;},prop:function(elem,value,type,i,name){if(jQuery.isFunction(value))value=value.call(elem,i);return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(name)?value+"px":value;},className:{add:function(elem,classNames){jQuery.each((classNames||"").split(/\s+/),function(i,className){if(elem.nodeType==1&&!jQuery.className.has(elem.className,className))elem.className+=(elem.c [...]
+jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid [...]
+ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&&notxml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode) [...]
+while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i<length;i++)if(array[i]===elem)return i;return-1;},merge:function(first,second){var i=0,elem,pos=first.length;if(jQuery.browser.msie){while(elem=second[i++])if(elem.nodeType!=8)first[pos++]=elem;}else
+while(elem=second[i++])first[pos++]=elem;return first;},unique:function(array){var ret=[],done={};try{for(var i=0,length=array.length;i<length;i++){var id=jQuery.data(array[i]);if(!done[id]){done[id]=true;ret.push(array[i]);}}}catch(e){ret=array;}return ret;},grep:function(elems,callback,inv){var ret=[];for(var i=0,length=elems.length;i<length;i++)if(!inv!=!callback(elems[i],i))ret.push(elems[i]);return ret;},map:function(elems,callback){var ret=[];for(var i=0,length=elems.length;i<lengt [...]
+for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuer [...]
+jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.call(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DO [...]
+xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false; [...]
+jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.compl [...]
+for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else
+s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style. [...]
+e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timer [...]
\ No newline at end of file
diff --git a/vigranumpy/docsrc/_static/minus.png b/vigranumpy/docsrc/_static/minus.png
new file mode 100644
index 0000000..da1c562
Binary files /dev/null and b/vigranumpy/docsrc/_static/minus.png differ
diff --git a/vigranumpy/docsrc/_static/plus.png b/vigranumpy/docsrc/_static/plus.png
new file mode 100644
index 0000000..b3cb374
Binary files /dev/null and b/vigranumpy/docsrc/_static/plus.png differ
diff --git a/vigranumpy/docsrc/_static/pygments.css b/vigranumpy/docsrc/_static/pygments.css
new file mode 100644
index 0000000..1f2d2b6
--- /dev/null
+++ b/vigranumpy/docsrc/_static/pygments.css
@@ -0,0 +1,61 @@
+.hll { background-color: #ffffcc }
+.c { color: #408090; font-style: italic } /* Comment */
+.err { border: 1px solid #FF0000 } /* Error */
+.k { color: #007020; font-weight: bold } /* Keyword */
+.o { color: #666666 } /* Operator */
+.cm { color: #408090; font-style: italic } /* Comment.Multiline */
+.cp { color: #007020 } /* Comment.Preproc */
+.c1 { color: #408090; font-style: italic } /* Comment.Single */
+.cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
+.gd { color: #A00000 } /* Generic.Deleted */
+.ge { font-style: italic } /* Generic.Emph */
+.gr { color: #FF0000 } /* Generic.Error */
+.gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.gi { color: #00A000 } /* Generic.Inserted */
+.go { color: #303030 } /* Generic.Output */
+.gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.gs { font-weight: bold } /* Generic.Strong */
+.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.gt { color: #0040D0 } /* Generic.Traceback */
+.kc { color: #007020; font-weight: bold } /* Keyword.Constant */
+.kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
+.kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
+.kp { color: #007020 } /* Keyword.Pseudo */
+.kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
+.kt { color: #902000 } /* Keyword.Type */
+.m { color: #208050 } /* Literal.Number */
+.s { color: #4070a0 } /* Literal.String */
+.na { color: #4070a0 } /* Name.Attribute */
+.nb { color: #007020 } /* Name.Builtin */
+.nc { color: #0e84b5; font-weight: bold } /* Name.Class */
+.no { color: #60add5 } /* Name.Constant */
+.nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.ne { color: #007020 } /* Name.Exception */
+.nf { color: #06287e } /* Name.Function */
+.nl { color: #002070; font-weight: bold } /* Name.Label */
+.nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.nt { color: #062873; font-weight: bold } /* Name.Tag */
+.nv { color: #bb60d5 } /* Name.Variable */
+.ow { color: #007020; font-weight: bold } /* Operator.Word */
+.w { color: #bbbbbb } /* Text.Whitespace */
+.mf { color: #208050 } /* Literal.Number.Float */
+.mh { color: #208050 } /* Literal.Number.Hex */
+.mi { color: #208050 } /* Literal.Number.Integer */
+.mo { color: #208050 } /* Literal.Number.Oct */
+.sb { color: #4070a0 } /* Literal.String.Backtick */
+.sc { color: #4070a0 } /* Literal.String.Char */
+.sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
+.s2 { color: #4070a0 } /* Literal.String.Double */
+.se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
+.sh { color: #4070a0 } /* Literal.String.Heredoc */
+.si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
+.sx { color: #c65d09 } /* Literal.String.Other */
+.sr { color: #235388 } /* Literal.String.Regex */
+.s1 { color: #4070a0 } /* Literal.String.Single */
+.ss { color: #517918 } /* Literal.String.Symbol */
+.bp { color: #007020 } /* Name.Builtin.Pseudo */
+.vc { color: #bb60d5 } /* Name.Variable.Class */
+.vg { color: #bb60d5 } /* Name.Variable.Global */
+.vi { color: #bb60d5 } /* Name.Variable.Instance */
+.il { color: #208050 } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/vigranumpy/docsrc/_static/searchtools.js b/vigranumpy/docsrc/_static/searchtools.js
new file mode 100644
index 0000000..e022625
--- /dev/null
+++ b/vigranumpy/docsrc/_static/searchtools.js
@@ -0,0 +1,467 @@
+/**
+ * helper function to return a node containing the
+ * search summary for a given text. keywords is a list
+ * of stemmed words, hlwords is the list of normal, unstemmed
+ * words. the first one is used to find the occurance, the
+ * latter for highlighting it.
+ */
+
+jQuery.makeSearchSummary = function(text, keywords, hlwords) {
+  var textLower = text.toLowerCase();
+  var start = 0;
+  $.each(keywords, function() {
+    var i = textLower.indexOf(this.toLowerCase());
+    if (i > -1)
+      start = i;
+  });
+  start = Math.max(start - 120, 0);
+  var excerpt = ((start > 0) ? '...' : '') +
+  $.trim(text.substr(start, 240)) +
+  ((start + 240 - text.length) ? '...' : '');
+  var rv = $('<div class="context"></div>').text(excerpt);
+  $.each(hlwords, function() {
+    rv = rv.highlightText(this, 'highlight');
+  });
+  return rv;
+}
+
+/**
+ * Porter Stemmer
+ */
+var PorterStemmer = function() {
+
+  var step2list = {
+    ational: 'ate',
+    tional: 'tion',
+    enci: 'ence',
+    anci: 'ance',
+    izer: 'ize',
+    bli: 'ble',
+    alli: 'al',
+    entli: 'ent',
+    eli: 'e',
+    ousli: 'ous',
+    ization: 'ize',
+    ation: 'ate',
+    ator: 'ate',
+    alism: 'al',
+    iveness: 'ive',
+    fulness: 'ful',
+    ousness: 'ous',
+    aliti: 'al',
+    iviti: 'ive',
+    biliti: 'ble',
+    logi: 'log'
+  };
+
+  var step3list = {
+    icate: 'ic',
+    ative: '',
+    alize: 'al',
+    iciti: 'ic',
+    ical: 'ic',
+    ful: '',
+    ness: ''
+  };
+
+  var c = "[^aeiou]";          // consonant
+  var v = "[aeiouy]";          // vowel
+  var C = c + "[^aeiouy]*";    // consonant sequence
+  var V = v + "[aeiou]*";      // vowel sequence
+
+  var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
+  var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
+  var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
+  var s_v   = "^(" + C + ")?" + v;                         // vowel in stem
+
+  this.stemWord = function (w) {
+    var stem;
+    var suffix;
+    var firstch;
+    var origword = w;
+
+    if (w.length < 3)
+      return w;
+
+    var re;
+    var re2;
+    var re3;
+    var re4;
+
+    firstch = w.substr(0,1);
+    if (firstch == "y")
+      w = firstch.toUpperCase() + w.substr(1);
+
+    // Step 1a
+    re = /^(.+?)(ss|i)es$/;
+    re2 = /^(.+?)([^s])s$/;
+
+    if (re.test(w))
+      w = w.replace(re,"$1$2");
+    else if (re2.test(w))
+      w = w.replace(re2,"$1$2");
+
+    // Step 1b
+    re = /^(.+?)eed$/;
+    re2 = /^(.+?)(ed|ing)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      re = new RegExp(mgr0);
+      if (re.test(fp[1])) {
+        re = /.$/;
+        w = w.replace(re,"");
+      }
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1];
+      re2 = new RegExp(s_v);
+      if (re2.test(stem)) {
+        w = stem;
+        re2 = /(at|bl|iz)$/;
+        re3 = new RegExp("([^aeiouylsz])\\1$");
+        re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+        if (re2.test(w))
+          w = w + "e";
+        else if (re3.test(w)) {
+          re = /.$/;
+          w = w.replace(re,"");
+        }
+        else if (re4.test(w))
+          w = w + "e";
+      }
+    }
+
+    // Step 1c
+    re = /^(.+?)y$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(s_v);
+      if (re.test(stem))
+        w = stem + "i";
+    }
+
+    // Step 2
+    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step2list[suffix];
+    }
+
+    // Step 3
+    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step3list[suffix];
+    }
+
+    // Step 4
+    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+    re2 = /^(.+?)(s|t)(ion)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      if (re.test(stem))
+        w = stem;
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1] + fp[2];
+      re2 = new RegExp(mgr1);
+      if (re2.test(stem))
+        w = stem;
+    }
+
+    // Step 5
+    re = /^(.+?)e$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      re2 = new RegExp(meq1);
+      re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+        w = stem;
+    }
+    re = /ll$/;
+    re2 = new RegExp(mgr1);
+    if (re.test(w) && re2.test(w)) {
+      re = /.$/;
+      w = w.replace(re,"");
+    }
+
+    // and turn initial Y back to y
+    if (firstch == "y")
+      w = firstch.toLowerCase() + w.substr(1);
+    return w;
+  }
+}
+
+
+/**
+ * Search Module
+ */
+var Search = {
+
+  _index : null,
+  _queued_query : null,
+  _pulse_status : -1,
+
+  init : function() {
+      var params = $.getQueryParameters();
+      if (params.q) {
+          var query = params.q[0];
+          $('input[name="q"]')[0].value = query;
+          this.performSearch(query);
+      }
+  },
+
+  /**
+   * Sets the index
+   */
+  setIndex : function(index) {
+    var q;
+    this._index = index;
+    if ((q = this._queued_query) !== null) {
+      this._queued_query = null;
+      Search.query(q);
+    }
+  },
+
+  hasIndex : function() {
+      return this._index !== null;
+  },
+
+  deferQuery : function(query) {
+      this._queued_query = query;
+  },
+
+  stopPulse : function() {
+      this._pulse_status = 0;
+  },
+
+  startPulse : function() {
+    if (this._pulse_status >= 0)
+        return;
+    function pulse() {
+      Search._pulse_status = (Search._pulse_status + 1) % 4;
+      var dotString = '';
+      for (var i = 0; i < Search._pulse_status; i++)
+        dotString += '.';
+      Search.dots.text(dotString);
+      if (Search._pulse_status > -1)
+        window.setTimeout(pulse, 500);
+    };
+    pulse();
+  },
+
+  /**
+   * perform a search for something
+   */
+  performSearch : function(query) {
+    // create the required interface elements
+    this.out = $('#search-results');
+    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
+    this.dots = $('<span></span>').appendTo(this.title);
+    this.status = $('<p style="display: none"></p>').appendTo(this.out);
+    this.output = $('<ul class="search"/>').appendTo(this.out);
+
+    $('#search-progress').text(_('Preparing search...'));
+    this.startPulse();
+
+    // index already loaded, the browser was quick!
+    if (this.hasIndex())
+      this.query(query);
+    else
+      this.deferQuery(query);
+  },
+
+  query : function(query) {
+    // stem the searchterms and add them to the
+    // correct list
+    var stemmer = new PorterStemmer();
+    var searchterms = [];
+    var excluded = [];
+    var hlterms = [];
+    var tmp = query.split(/\s+/);
+    var object = (tmp.length == 1) ? tmp[0].toLowerCase() : null;
+    for (var i = 0; i < tmp.length; i++) {
+      // stem the word
+      var word = stemmer.stemWord(tmp[i]).toLowerCase();
+      // select the correct list
+      if (word[0] == '-') {
+        var toAppend = excluded;
+        word = word.substr(1);
+      }
+      else {
+        var toAppend = searchterms;
+        hlterms.push(tmp[i].toLowerCase());
+      }
+      // only add if not already in the list
+      if (!$.contains(toAppend, word))
+        toAppend.push(word);
+    };
+    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
+
+    console.debug('SEARCH: searching for:');
+    console.info('required: ', searchterms);
+    console.info('excluded: ', excluded);
+
+    // prepare search
+    var filenames = this._index.filenames;
+    var titles = this._index.titles;
+    var terms = this._index.terms;
+    var descrefs = this._index.descrefs;
+    var modules = this._index.modules;
+    var desctypes = this._index.desctypes;
+    var fileMap = {};
+    var files = null;
+    var objectResults = [];
+    var regularResults = [];
+    $('#search-progress').empty();
+
+    // lookup as object
+    if (object != null) {
+      for (var module in modules) {
+        if (module.indexOf(object) > -1) {
+          fn = modules[module];
+          descr = _('module, in ') + titles[fn];
+          objectResults.push([filenames[fn], module, '#module-'+module, descr]);
+        }
+      }
+      for (var prefix in descrefs) {
+        for (var name in descrefs[prefix]) {
+          var fullname = (prefix ? prefix + '.' : '') + name;
+          if (fullname.toLowerCase().indexOf(object) > -1) {
+            match = descrefs[prefix][name];
+            descr = desctypes[match[1]] + _(', in ') + titles[match[0]];
+            objectResults.push([filenames[match[0]], fullname, '#'+fullname, descr]);
+          }
+        }
+      }
+    }
+
+    // sort results descending
+    objectResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+
+    // perform the search on the required terms
+    for (var i = 0; i < searchterms.length; i++) {
+      var word = searchterms[i];
+      // no match but word was a required one
+      if ((files = terms[word]) == null)
+        break;
+      if (files.length == undefined) {
+        files = [files];
+      }
+      // create the mapping
+      for (var j = 0; j < files.length; j++) {
+        var file = files[j];
+        if (file in fileMap)
+          fileMap[file].push(word);
+        else
+          fileMap[file] = [word];
+      }
+    }
+
+    // now check if the files don't contain excluded terms
+    for (var file in fileMap) {
+      var valid = true;
+
+      // check if all requirements are matched
+      if (fileMap[file].length != searchterms.length)
+        continue;
+
+      // ensure that none of the excluded terms is in the
+      // search result.
+      for (var i = 0; i < excluded.length; i++) {
+        if (terms[excluded[i]] == file ||
+            $.contains(terms[excluded[i]] || [], file)) {
+          valid = false;
+          break;
+        }
+      }
+
+      // if we have still a valid result we can add it
+      // to the result list
+      if (valid)
+        regularResults.push([filenames[file], titles[file], '', null]);
+    }
+
+    // delete unused variables in order to not waste
+    // memory until list is retrieved completely
+    delete filenames, titles, terms;
+
+    // now sort the regular results descending by title
+    regularResults.sort(function(a, b) {
+      var left = a[1].toLowerCase();
+      var right = b[1].toLowerCase();
+      return (left > right) ? -1 : ((left < right) ? 1 : 0);
+    });
+
+    // combine both
+    var results = regularResults.concat(objectResults);
+
+    // print the results
+    var resultCount = results.length;
+    function displayNextItem() {
+      // results left, load the summary and display it
+      if (results.length) {
+        var item = results.pop();
+        var listItem = $('<li style="display:none"></li>');
+        listItem.append($('<a/>').attr(
+          'href',
+          item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
+          highlightstring + item[2]).html(item[1]));
+        if (item[3]) {
+          listItem.append($('<span> (' + item[3] + ')</span>'));
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
+          $.get('_sources/' + item[0] + '.txt', function(data) {
+            listItem.append($.makeSearchSummary(data, searchterms, hlterms));
+            Search.output.append(listItem);
+            listItem.slideDown(5, function() {
+              displayNextItem();
+            });
+          });
+        } else {
+          // no source available, just display title
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        }
+      }
+      // search finished, update title and status message
+      else {
+        Search.stopPulse();
+        Search.title.text(_('Search Results'));
+        if (!resultCount)
+          Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
+        else
+            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
+        Search.status.fadeIn(500);
+      }
+    }
+    displayNextItem();
+  }
+}
+
+$(document).ready(function() {
+  Search.init();
+});
diff --git a/vigranumpy/docsrc/_static/vigra-icon.ico b/vigranumpy/docsrc/_static/vigra-icon.ico
new file mode 100644
index 0000000..8d7dd85
Binary files /dev/null and b/vigranumpy/docsrc/_static/vigra-icon.ico differ
diff --git a/vigranumpy/docsrc/conf.py.in b/vigranumpy/docsrc/conf.py.in
new file mode 100644
index 0000000..ee5b7ca
--- /dev/null
+++ b/vigranumpy/docsrc/conf.py.in
@@ -0,0 +1,276 @@
+# -*- coding: utf-8 -*-
+#
+# vigranumpy documentation build configuration file, created by
+# sphinx-quickstart on Thu Dec 03 15:51:41 2009.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# silent lots of 'arg is not a Python function' warnings
+import inspect
+
+_original_getargspec = inspect.getargspec
+
+def _getargspec_workaround(*args, **kw):
+    try:
+        return _original_getargspec(*args, **kw)
+    except TypeError, e:
+        if str(e).startswith('arg is not a Python function'):
+            return inspect.ArgSpec([], None, None, None)
+        else:
+            raise
+
+inspect.getargspec = _getargspec_workaround
+_getargspec_workaround.__module__ = 'inspect'
+
+# set the PATH of the current build, so that we don't create
+# documentation for a possibly outdated installation
+vigranumpy_path=r'@VIGRANUMPY_TMP_PATH@'
+print "Working directory:", vigranumpy_path
+sys.path.insert(0,vigranumpy_path)
+
+# find the build configuration ('release' or 'debug' on Windows, nothing on Linux)
+outdir = ''
+match = 'build_configuration='
+for a in sys.argv:
+    if a.startswith(match):
+        outdir = '/' + a[len(match):]
+
+vigraimpex_path=r'@VIGRAIMPEX_PATH@%s' % outdir
+print "vigraimpex path:", vigraimpex_path
+os.environ['PATH'] = os.pathsep.join([vigraimpex_path, os.environ['PATH']])
+
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'vigranumpy'
+copyright = u'@vigra_year@, Ullrich Koethe and others'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '@vigra_version_short@'
+# The full version, including alpha/beta/rc tags.
+release = '@vigra_version@'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+autoclass_content = 'both'
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+html_favicon = 'vigra-icon.ico'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'vigranumpydoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'vigranumpy.tex', u'vigranumpy Documentation',
+   u'Ullrich Koethe and others', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
+
+rst_epilog=""""""
+replace_file=open("./c_api_replaces.txt")
+for l in replace_file:
+    replacement=l.split(":")
+    k = replacement[0].rfind('.')
+    if k >= 0:        
+        rst_epilog += """
+    .. |%s| replace:: %s
+"""% (replacement[0],replacement[0][k+1:])
+    rst_epilog += """
+    .. _%s: ../../doc/vigra/%s
+"""% (replacement[0],replacement[1])
+
+# make python accumulators documentation better (?)
+
+def processAccumulators(app, what, name, obj, options, docstringlines):
+    global_accumulators = ["MultibandFeatures3D", "SinglebandFeatures", "Vector3Features"]
+    region_accumulators = ["MultibandRegionFeatures3D", "SinglebandRegionFeatures2D", "SinglebandRegionFeatures3D", "Vector3RegionFeatures2D", "Vector3RegionFeatures3D"]
+    for acc in global_accumulators:
+        if name.find(acc) != -1 and docstringlines[0].find("Raises an exception") == -1:
+            docstringlines[:] = ["See :class:`MultibandFeatures2D`.","\n"]
+    for acc in region_accumulators:
+        if name.find(acc) != -1 and docstringlines[0].find("Raises an exception") == -1:
+            docstringlines[:] = ["See :class:`MultibandRegionFeatures2D`.","\n"]
+
+
+def skipMember(app, what, name, obj, skip, options):
+    #check if member function of accumulator class
+    skip_accumulator_members = ["MultibandFeatures3D", "MultibandRegionFeatures3D", "SinglebandFeatures", "SinglebandRegionFeatures2D", "SinglebandRegionFeatures3D", "Vector3Features", "Vector3RegionFeatures2D", "Vector3RegionFeatures3D"]
+    for acc in skip_accumulator_members:
+        if str(obj).find(acc) != -1 and str(obj).find("method") != -1:
+            #skip_member = True
+            return True
+    #make sure to document __getitem__ member of documented accumulator classes
+    doc_accumulator_members = ["MultibandFeatures2D", "MultibandRegionFeatures2D"]
+    for acc in doc_accumulator_members:
+        if name.find("__getitem__") != -1 and str(obj).find(acc) != -1:
+            return False
+    return skip
+
+
+def setup(app):
+    app.connect('autodoc-process-docstring', processAccumulators)
+    app.connect('autodoc-skip-member', skipMember)
+
diff --git a/vigranumpy/docsrc/index.rst b/vigranumpy/docsrc/index.rst
new file mode 100644
index 0000000..b4e5e52
--- /dev/null
+++ b/vigranumpy/docsrc/index.rst
@@ -0,0 +1,673 @@
+.. vigranumpy documentation master file, created by
+   sphinx-quickstart on Thu Dec 03 15:51:41 2009.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Vigranumpy Reference
+====================
+
+.. contents::
+
+.. toctree::
+   :maxdepth: 2
+
+Introduction
+------------
+
+Vigranumpy exports the functionality of the C++ image processing library `VIGRA <../vigra/index.html>`_ to Python. It can be invoked by importing the vigra module::
+
+    import vigra
+
+Vigranumpy is based on the popular `numpy <http://numpy.scipy.org/>`_ module and uses its ndarray data structure to represent image and volume data. It introduces the C++ wrapper class NumpyArray_ to allow transparent execution of VIGRA C++ functions on numpy arrays. Thus, vigranumpy is fully interoperable with existing numpy functionality, including various tools for image display such as matplotlib. Since vigranumpy uses `boost_python <http://www.boost.org/doc/libs>`_, it is able to su [...]
+
+Basic calling syntax is similar to C++, with one important difference: Arguments for output images are optional. If no output image is provided, vigranumpy will allocate it as appropriate. In either case, the output image will be returned by the function, for example::
+
+    # allocate new result image
+    >>> smoothImage = vigra.gaussianSmoothing(inputImage, scale)
+    
+    # reuse and overwrite existing result image
+    >>> smoothImage = vigra.gaussianSmoothing(inputImage, scale, out=smoothImage)
+    
+Unless otherwise noted, all functions expect and create arrays with dtype=numpy.float32.
+
+Another important concern is the interpretation and ordering of the array axes. Numpy does not provide any means to attach semantics to axes, but relies purely on the convention that the most important axis is last, as in ``array[y, x]`` or ``array[z, y, x]`` ("C-order"). However, there is no way to enforce this convention in a program, since arrays can be transposed outside of the user's control (e.g. when saving data to a file). Moreover, many imaging libraries (e.g. `Image Magick <htt [...]
+
+To solve these ambiguities in a clean way, vigranumpy introduces the concept of **axistags** which is realized in class :class:`vigra.AxisTags`. Every :class:`~vigra.VigraArray` (which is a subclass of numpy.ndarray) gets a new property ``array.axistags`` that describes axis semantics, and all vigranumpy functions account for and preserve axistag information. Unfortunately, this functionality cannot easily be retrofitted to numpy.ndarray itself. Therefore, we employ the following convers [...]
+
+* When the Python array has **no** ``array.axistags`` property, it is mapped to the C++ NumpyArray 
+  **without** any change in axis ordering. Since most VIGRA functions can work on arbitrarily 
+  transposed arrays, you will get correct results, but execution may be slower because the 
+  processor cache is poorly utilized in certain axis orders.
+  
+  Moreover, this may lead to overload resolution ambiguities. For example, when the array has shape 
+  ``(3, 60, 40)``, vigranumpy has no way to decide if this is a 2-dimensional RGB image or
+  a 3-dimensional array that happens to have only 3 slices. Thus, vigranumpy may not always 
+  execute the function you actually intended to call.
+  
+* When the Python array **has** the ``array.axistags`` property, it is transposed into a 
+  **canonical** axis ordering before vigranumpy executes a function, and the results are 
+  transposed back into the original ordering. Likewise, functions that change axis ordering
+  (such as ``array.swapaxes(0,1)``) or reduce the number of axes (such as ``array.max(axis=1)``)
+  as well as array arithmetic operations preserve axistags (see section :ref:`sec-dtype-coercion`). 
+  Thus, you can work in any desired axis order without loosing control. Overload ambiguities 
+  can no longer occur because a function cannot be called when the axistags are unsuitable.
+
+Detailed information about the use of axistags is given in section :ref:`sec-vigraarray` below. Section :ref:`sec-own-modules` describes how you can take advantage of the axistags mechanism in your own C++ code.
+
+.. _sec-vigraarray:
+    
+Axistags and the VigraArray Data Structure
+------------------------------------------
+
+While vigranumpy can directly work on numpy.ndarrays, this would not give us the advantages of axistags as described above. Therefore, vigranumpy introduces its own array class :class:`~vigra.VigraArray` which is a subclass of numpy.ndarray, but re-implements many of its methods so that axistags are respected. Arrays with a conforming ``axistags`` property are most easily constructed by one of the predefined :ref:`array factories <subsec-array-factories>`. A **view with axistags** can be [...]
+
+    >>> width, height, depth = 300, 200, 3
+    
+    # create a 2-dimensional RGB image
+    >>> rgb = vigra.RGBImage((width, height))
+    >>> rgb.shape
+    (300, 200, 3)
+    >>> rgb.axistags             # short output: only axis keys
+    x y c
+    >>> print rgb.axistags       # long output
+    AxisInfo: 'x' (type: Space)
+    AxisInfo: 'y' (type: Space)
+    AxisInfo: 'c' (type: Channels) RGB
+    
+    # create a 3-dimensional scalar volume
+    >>> volume = vigra.ScalarVolume((width, height, depth))
+    >>> volume.shape
+    (300, 200, 3)        # same shape as before
+    >>> volume.axistags
+    x y z                # but different semantic interpretation
+    >>> print volume.axistags
+    AxisInfo: 'x' (type: Space)
+    AxisInfo: 'y' (type: Space)
+    AxisInfo: 'z' (type: Space)
+
+It is also possible to attach additional information to the axistags, in particular the resolution of the axis, and a text comment. The resolution will be correctly adjusted when the image is resized::
+
+    >>> rgb.axistags['x'].resolution = 1.2  # in some unit of length
+    >>> rgb.axistags['y'].resolution = 1.4  # in some unit of length
+    >>> rgb.axistags['c'].description = 'fluorescence microscopy, DAPI and GFP staining'
+    >>> print rgb.axistags
+    AxisInfo: 'x' (type: Space, resolution=1.2)
+    AxisInfo: 'y' (type: Space, resolution=1.4)
+    AxisInfo: 'c' (type: Channels) fluorescence microscopy, DAPI and GFP staining
+    
+    # interpolate the image to twice its original size
+    >>> rgb2 = vigra.sampling.resize(rgb, shape=(2*width-1, 2*height-1))
+    >>> print rgb2.axistags
+    AxisInfo: 'x' (type: Space, resolution=0.6)
+    AxisInfo: 'y' (type: Space, resolution=0.7)
+    AxisInfo: 'c' (type: Channels) fluorescence microscopy, DAPI and GFP staining
+
+When the array is transposed, the axistags are transposed accordingly. When axes are dropped from the array, the corresponding entries are dropped from the axistags property::
+
+    # transpose the volume into reverse axis order
+    >>> transposed_volume = volume.transpose()
+    >>> transposed_volume.shape
+    (3, 200, 300)
+    >>> transposed_volume.axistags
+    z y x
+    
+    # get a view to the first slice (z == 0)
+    >>> first_slice = volume[..., 0]
+    >>> first_slice.shape
+    (300, 200)
+    >>> first_slice.axistags
+    x y
+    
+    # get the maximum of each slice
+    >>> volume.max(axis=0).max(axis=0)
+    VigraArray(shape=(3,), axistags=z, dtype=float32, data=
+    [ 0.  0.  0.])
+    
+    # likewise, but specify axes by their keys
+    >>> volume.max(axis='x').max(axis='y')
+    VigraArray(shape=(3,), axistags=z, dtype=float32, data=
+    [ 0.  0.  0.])
+
+The initial ordering of the axes is controlled by the argument ``order`` that can optionally be passed to the VigraArray constuctor or the factory functions. If ``order`` is not explicitly provided, it is determined by the static property :attr:`VigraArray.defaultOrder` (which yields 'V' order). The following orders are currently supported:
+
+.. _array-order-parameter:
+
+    'C' order:
+        Both strides and axes are arranged in descending order, as in a 
+        plain numpy.ndarray. For example, axistags will be 'y x c' or 
+        'z y x c'. array.flags['C_CONTIGUOUS'] will be true.
+
+    'F' order:
+        Both strides and axes are arranged in ascending order, i.e. 
+        opposite to 'C' order. For example, axistags will be 'c x y' 
+        or 'c x y z'. array.flags['F_CONTIGUOUS'] will be true.
+
+    'V' order:
+        VIGRA-order is an interleaved memory layout that simulates 
+        vector-valued pixels or voxels: Channels will be the last axis 
+        and have the smallest stride, whereas all other axes are arranged 
+        in ascending order. For example, axistags will be 'x y c' or 
+        'x y z c'.
+
+    'A' order:
+        Defaults to 'V' when a new array is created, and means
+        'preserve order' when an existing array is copied.
+        
+The meaning of 'ascending' or 'descending' order is determined by two rules: the primary order is according to axis type (see :class:`vigra.AxisType`), where ``Channels < Space < Angle < Time < Frequency < Unknown``. The secondary order (between axes of the same type) is lexicographic, such that 'x' < 'y' < 'z'. Usage examples::
+
+    >>> rgbv = vigra.RGBImage((width, height), order='V')
+    >>> rgbv.shape
+    (300, 200, 3)
+    >>> rgbv.axistags
+    x y c
+    
+    >>> rgbc = vigra.RGBImage((width, height), order='C')
+    >>> rgbc.shape
+    (200, 300, 3)
+    >>> rgbc.axistags
+    y x c
+    
+    >>> rgbf = vigra.RGBImage((width, height), order='F')
+    >>> rgbf.shape
+    (3, 300, 200)
+    >>> rgbf.axistags
+    c x y
+    
+Functions that reduce the array to a one-dimensional shape (``flatten()``, ``flat``, ``ravel()``, ``take()``) always transpose the array into 'C' order before flattening.
+
+Axistags are stored in a list-like class :class:`vigra.AxisTags`, whose individual entries are of type :class:`vigra.AxisInfo`. The simplest way to attach axistags to a plain numpy.ndarray (by creating a view of type VigraArray) is via the convenience function :func:`vigra.taggedView`.
+
+More On the Motivation and Use of Axistags
+------------------------------------------
+
+History of the problem
+^^^^^^^^^^^^^^^^^^^^^^
+
+A Fortran array declaration::
+
+    real f(20,10)
+
+is compiled such that the elements of the first index are consecutive in memory. In contrast, a C array declaration::
+
+    float c[20][10];
+
+places the elements of the last index consecutive in memory. The two possibilities are commonly referred to as "Fortran order" and "C order", but we will see that these terms are actually ambiguous because their meaning depends on what the array is used for.
+
+Arrays as Matrices
+^^^^^^^^^^^^^^^^^^
+
+When the array represents a matrix, users require the syntax to conform to the mathematical syntax conventions (in order to avoid bugs when typing formulas). In mathematics, m\ :sub:`ij` means that the first index i refers to rows, and the second index j refers to columns. Thus, Fortran's ``f(i, j)`` and C's ``c[i][j]`` have exactly the same meaning, but the memory layouts of the two matrices differ: Since in Fortran the first index changes quickest, this is referred to as the "column ma [...]
+
+In short: When the array is a matrix, the syntax is the same, but the memory layouts differ.
+
+Arrays as Images
+^^^^^^^^^^^^^^^^
+
+When the array represents an image, users require the memory layout to be the same as in the image files which store the data (in order to ensure fast I/O). All image formats (JPEG, TIFF, PNG, ...) follow the convention of analog television to scan an image left to right, then top to bottom. Consequently, the horizontal pixels are consecutive in memory, and therefore Fortran (where the first axis changes fastest) must use the syntax ``f(x, y)``, whereas C (where the last axis changes fas [...]
+
+In short: When the array is an image, the memory layout is the same, but the syntax differs.
+
+Thus, we have four basic conventions: FM and CM for matrices, FI and CI for images. The meaning of the terms "Fortran order" and "C order" depends on whether we are talking about matrices (where they refer to FM and CM, i.e. a difference in memory layout) or images (where they refer to FI and CI, i.e. a difference in index order).
+
+Multi-Dimensional Arrays
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+When we add more dimensions, the confusion increases, because there are no universally accepted memory and indexing conventions. For example, an RGB image can be stored in "interleaved format"::
+
+    RGB RGB RGB ...
+    RGB RGB RGB ...
+    :
+    :
+
+where the color values of each pixel are consecutive in memory, or in "banded format"::
+
+    R R R ...
+    R R R ...
+    :
+    G G G ...
+    G G G ...
+    :
+    B B B ...
+    B B B ...
+    :
+    
+where we have a separate scalar image for each color. In Fortran, interleaved and banded images must be indexed as ``f(color, x, y)`` and ``f(x, y, color)`` respectively, whereas in C we must use ``c[y][x][color]`` or ``c[color][y][x]``.
+
+VIGRA and numpy
+^^^^^^^^^^^^^^^
+
+From the beginning, VIGRA adopted Fortran conventions, i.e. its default behavior is according to FM and FI (this is possible because VIGRA uses array classes, where the mapping from indices to memory is encapsulated in the appropriate way).
+
+In contrast, numpy adopted C conventions, i.e. its default behavior is CM and CI. 
+
+In addition, both packages provide array views which keep the memory layout intact, but change the index order. Thus, VIGRA also supports the CI convention, and numpy also supports FI. Note that changing the index order is only allowed for images. Matrices always use the fixed index order dictated by mathematics where transpose(m) is a well-defined mathematical operation (which just happens to revert the index order). Therefore, the existence of array views does not imply that VIGRA supp [...]
+
+However, numpy's array constructor provides an argument 'order' which can take the values 'C' (default) and 'F' to construct arrays with C or Fortran memory order. By this mechanism, numpy also supports the FM convention (and thus all four basic possibilities).
+
+But here is the catch: When you get a numpy array view, you have no way to tell which convention it adheres to. It simply doesn't contain this information.
+
+The usual solution to this problem is to enforce a fixed axis order in the entire application, but this workaround breaks down when the application must simultaneously handle arrays with different meaning (e.g. sequences 'xyt' vs. volumes 'xyz' vs. multi-spectral images 'xyc') or when the application uses modules with conflicting requirements (e.g. numpy's 'yx' vs. PyQt's 'xy').
+
+Vigranumpy Axistags
+^^^^^^^^^^^^^^^^^^^
+
+This is precisely where axistags enter: They attach information to array views that allows the user to figure out which convention applies to a given view. Thus, the primary purpose of axistags is entirely passive - they just keep track of how users manipulate the axis order when creating new array views. The main use case of axistags is therefore to re-adjust the axis order whenever an algorithm has specific order requirements. Using axistags, one can easily ensure that arrays conform t [...]
+
+    width  = image.width    # this works for any axis order!
+    height = image.height
+    
+Now suppose we want to execute a numpy algorithm which expects the [y, x] ordering. We simply transpose the array before calling the algorithm like this::
+
+    # adjust the axis order
+    numpy_image = image.transposeToNumpyOrder()
+    
+    # execute the algorithm
+    for y in xrange(height):
+        for x in xrange(width):
+            numpy_image[y, x] = ...   # note the index order
+            
+When we want to execute a VIGRA algorithm which expects the [x, y] ordering, we do::
+
+    # adjust the axis order
+    vigra_image = image.transposeToVigraOrder()
+    
+    # execute the algorithm
+    for y in xrange(height):
+        for x in xrange(width):
+            vigra_image[x, y] = ...   # note the index order
+
+Notice that the order of the loops (the inner loop runs over x) is the same in both cases: To maximize cache locality and therefore speed, the inner loop should operate on consecutive memory cells. Since image memory order derives from file memory order (where the x-axis is consecutive), and array views can never change the memory order, this loop ordering is always preferable, regardless of the index order.
+
+Vigranumpy Conventions
+^^^^^^^^^^^^^^^^^^^^^^
+
+To handle axis meaning in a well-defined way, vigranumpy adopts the following conventions, which are designed such that The Right Thing (TM) should happen automatically, at least most of the time:
+
+1. When the array represents a matrix, no axistags are allowed because the index order has a fixed semantic meaning and must not be messed around with. In vigranumpy, this requirement is enforced by an assertion::
+
+    vigra_precondition( !matrix.axistags(), "matrix must not have axistags");
+    
+   in the C++ gluecode functions. This applies, for example, to the feature matrices passed to a random forest and to unsupervised learning algorithms. If desired, we can introduce additional axistags for features and samples in the future because this is a common use case.
+
+2. When arrays represent image data with up to five dimensions, axistags should be used. To sort indices according to the requirements of the next algorithm to be executed, the appropriate convenience function should be called (many more convenience functions are documented in :py:class:`vigra.VigraArray`)::
+
+    numpy_array   = array.transposeToNumpyOrder()    # gives 'yx', 'zyx' etc. 
+    vigra_array   = array.transposeToVigraOrder()    # gives 'xy', 'xyz' etc.
+    ilastik_array = array.view5D()                   # gives 'txyzc' (inserts singleton axes if necessary)
+    user_defined  = array.withAxes('y', 'x', 't')    # specify order explicitly (inserts singleton axes if necessary)
+    
+   Algorithms with special order requirements can then check for the correct order in an assertion. 
+
+3. The function ``vigra.taggedView()`` allows to attach axistags to an array very conveniently. For example, when you know from the context that the axes of a given array are to be interpreted as 'xyzt' in that order, you can make this knowledge explicit by calling::
+
+    tagged_array = vigra.taggedView(array, 'xyzt')
+
+4. When you call a vigranumpy function that executes a C++ VIGRA function, ``image.transposeToVigraOrder()`` will be invoked automatically on the input arrays, and the original axis order will be restored in the output arrays.
+
+5. When you call a vigranumpy function that is forwarded to a numpy function (in particular, a ufunc like ``+``, ``-``, ``sqrt`` etc.), ``image.transposeToNumpyOrder()`` will be invoked automatically on the input arrays, and the original axis order will be restored in the output arrays.
+
+6. When vigranumpy writes arrays to a file, it will always order the axes such that the memory order conforms to the established file conventions (e.g. values along the x-axis are consecutive). In particular, when you use ``vigra.impex.writeHDF5()`` to create HDF5 datasets, ``array.transposeToNumpyOrder()`` will be called before writing the data (this is a consequence of item 5, because ``writeHDF5()`` eventually forwards the actual work to h5py). In addition, the axistags (in numpy orde [...]
+
+7. When vigranumpy reads data from a file, it preserves the file's memory order and attaches the appropriate axistags. In case of images, the axis order follows from the usual file conventions. If you call ``vigra.impex.readHDF5()`` to read HDF5, the axistags will be read from the attribute ``axistags`` (if present). Upon return, the read functions automatically call ``array.transposeToVigraOrder()``, but this only changes the index order, not the memory layout. This latter convention wa [...]
+
+8. When you display an image via ``image.imshow()`` or ``image.show()``, the axes are re-ordered automatically such that the image is displayed upright (i.e. x goes to the right, y goes down). If you want to override this (i.e. want to enforce transposed display), you can remove the axistags by calling ``image.view(numpy.ndarray)``.
+
+Item 4. has two important consequences one should be aware of:
+
+* When a function needs parameters that depend on the axis order (such as the new shape in ``vigra.sampling.resize()`` or axis-dependent sigmas in ``vigra.filters.gaussianSmoothing()``), these parameters must be re-ordered on the C++ side in the same way as the axes. This is achieved by a call to ``NumpyArray::permuteLikewise()`` in the C++ gluecode functions.
+
+* When a vigranumpy function computes a gradient image, the gradient vector elements will always be stored in the order (dx, dy, dz), regardless of the array's original axis ordering. The same applies to any function producing vector-valued elements whose interpretation depends on the axis meaning (e.g. the Hessian matrix and the structure tensor). For example, the output of the Hessian is ordered as (dxx, dxy, dxz, dyy, dyz, dzz).
+
+Axistag Reference
+-----------------
+
+.. autoclass:: vigra.AxisType
+
+----------------
+
+.. autoclass:: vigra.AxisInfo
+    :members: key, typeFlags, resolution, description, isSpatial, isTemporal, isChannel, isFrequency, isAngular, isType, compatible
+    
+----------------
+
+.. autoclass:: vigra.AxisTags
+    :members: index, channelIndex, innerNonchannelIndex, axisTypeCount, setChannelDescription, toJSON, fromJSON
+
+VigraArray Reference
+--------------------
+
+.. autoclass:: vigra.VigraArray
+    :show-inheritance:
+    :members: defaultAxistags, channelIndex, innerNonchannelIndex, channels, spatialDimensions, width, height, depth, duration, dropChannelAxis, insertChannelAxis, withAxes, view5D, asRGB, __getitem__, subarray, bindAxis, channelIter, sliceIter, spaceIter, timeIter, copyValues, swapaxes, transpose, T, transposeToOrder, transposeToDefaultOrder, transposeToNormalOrder, transposeToNumpyOrder, transposeToVigraOrder, permutationToOrder, permutationToNormalOrder, permutationFromNormalOrder, pe [...]
+    
+    .. attribute:: VigraArray.axistags
+    
+      The :class:`~vigra.AxisTags` object of this array. 
+
+    .. attribute:: VigraArray.defaultOrder
+    
+      Get the default axis ordering, currently 'V' (:ref:`VIGRA order <array-order-parameter>`).
+
+-------------
+
+.. autofunction:: vigra.newaxis(axisinfo=vigra.AxisInfo())
+.. autofunction:: vigra.taggedView
+.. autofunction:: vigra.dropChannelAxis
+
+-------------
+
+.. _subsec-array-factories:
+
+.. autofunction:: vigra.Image
+.. autofunction:: vigra.ScalarImage
+.. autofunction:: vigra.Vector2Image
+.. autofunction:: vigra.Vector3Image
+.. autofunction:: vigra.Vector4Image
+.. autofunction:: vigra.RGBImage
+
+-------------
+
+.. autofunction:: vigra.Volume
+.. autofunction:: vigra.ScalarVolume
+.. autofunction:: vigra.Vector2Volume
+.. autofunction:: vigra.Vector3Volume
+.. autofunction:: vigra.Vector4Volume
+.. autofunction:: vigra.Vector6Volume
+.. autofunction:: vigra.RGBVolume
+   
+
+Import and Export Functions
+---------------------------
+
+The module vigra.impex defines read and write functions for image and volume data. Note
+that the contents of this module are automatically imported into the vigra module, so
+you may call 'vigra.readImage(...)' instead of 'vigra.impex.readImage(...)' etc.
+
+.. automodule:: vigra.impex
+   :members:
+
+   
+.. _sec-dtype-coercion:
+
+Mathematical Functions and Type Coercion
+----------------------------------------
+
+vigranumpy supports all arithmetic and algebraic functions defined in  
+`numpy.ufunc <http://docs.scipy.org/doc/numpy/reference/ufuncs.html#available-ufuncs>`_, but re-implements them in module `vigra.ufunc` to take full advantage of axistags. 
+
+.. automodule:: vigra.ufunc
+
+
+Color and Intensity Manipulation
+--------------------------------
+
+The module vigra.colors provides functions to adjust image brightness and contrast, 
+and to transform between different color spaces. 
+See `Color Conversions <../vigra/group__ColorConversions.html>`_ in the C++ documentation
+for more information.
+
+.. automodule:: vigra.colors
+   :members:
+
+
+Filters
+-------
+
+The module vigra.filters provides operators that consider a window around each pixel, compute
+one or several numbers from the values in the window, and store the results in the
+corresponding pixel of the output image. This includes convolution, non-linear diffusion, 
+morphological operators, feature detectors (such as the structure tensor) etc.
+
+.. automodule:: vigra.filters
+   :members:
+
+
+Sampling: Image Resizing and Image Pyramids
+-------------------------------------------
+
+The module vigra.sampling contains methods to change the number and/or location of
+the image sampling points, such as resizing, rotation, and interpolation.
+
+.. automodule:: vigra.sampling
+   :members:
+   
+---------------------------------------------
+
+Spline image views implement an interpolated view for an image which can be accessed 
+at real-valued coordinates (in contrast to the plain image, which can only be
+accessed at integer coordinates). Module vigra.sampling defines::
+
+    SplineImageView0
+    SplineImageView1
+    SplineImageView2
+    SplineImageView3
+    SplineImageView4
+    SplineImageView5
+    
+The number denotes the spline interpolation order of the respective classes. 
+Below, we describe SplineImageView3 in detail, but the other classes work 
+analogously. See SplineImageView_ in the C++ documentation for more detailed information.
+
+.. autoclass:: vigra.sampling.SplineImageView3
+   :members:
+
+-------------
+
+.. autoclass:: vigra.sampling.ImagePyramid
+   :show-inheritance:
+   :members:
+
+
+Fourier Transforms
+------------------
+
+The module vigra.fourier contains functions for Fourier transforms, Cosine/Sine 
+transforms, and Fourier-domain filters.
+
+.. automodule:: vigra.fourier
+   :members:
+
+   
+Image Analysis
+--------------
+
+The module vigra.analysis contains segmentation algorithms (e.g. watershed), edge and 
+corner detection, localization of maxima and minima etc.
+
+.. automodule:: vigra.analysis
+   :members:
+
+   
+Geometry
+--------
+
+The module vigra.geometry contains geometric primitives (such as polygons) and related algorithms.
+
+.. automodule:: vigra.geometry
+   :members:
+
+
+Optimization
+------------
+
+The module vigra.optimization provides functions for constrained and unconstrained linear regression.
+
+.. automodule:: vigra.optimization
+   :members:
+
+
+Machine Learning
+----------------
+
+The module vigra.learning will eventually provide a wide range of machine learning 
+tools. Right now, it only contains an implementation of the random forest classifier
+and probabilistic latent semantic analysis (pLSA) as an example for unsupervised learning.
+
+.. automodule:: vigra.learning
+   :members:
+
+.. autoclass:: vigra.learning.RandomForest
+   :members:
+   
+For more information, refer to RandomForest_ in the C++ documentation.
+
+.. autoclass:: vigra.learning.RandomForestOld
+   :members:
+
+
+Noise Estimation and Normalization
+----------------------------------
+
+The module vigra.noise provides noise estimation and normalization according to a
+method proposed by Foerstner.
+
+.. automodule:: vigra.noise
+   :members:
+
+   
+.. _sec-own-modules:
+
+Writing Your Own C++ Modules
+----------------------------
+
+When you want to write your own vigranumpy extension modules, first make sure that you compile and link with the same versions of numpy and boost_python that your current vigranumpy installation uses. Otherwise, communication between new and existing modules will not work (and even crash). Then follow these steps:
+
+1. Create the main module source file. This file contains the module's 'init' function. Let's assume that the module will be called 'my_module', and the file is 'my_module.cxx'. A stub for 'my_module.cxx' typically looks like this::
+
+        // define PY_ARRAY_UNIQUE_SYMBOL (required by the numpy C-API)
+        #define PY_ARRAY_UNIQUE_SYMBOL my_module_PyArray_API
+
+        // include the vigranumpy C++ API
+        #include <Python.h>
+        #include <boost/python.hpp>
+        #include <vigra/numpy_array.hxx>
+        #include <vigra/numpy_array_converters.hxx>
+        
+        ... // your includes
+        
+        ... // implementation of your wrapper functions and classes
+        
+        using namespace boost::python;
+        
+        // the argument of the init macro must be the module name
+        BOOST_PYTHON_MODULE_INIT(my_module)
+        {
+            // initialize numpy and vigranumpy
+            vigra::import_vigranumpy();
+            
+            // export a function
+            def("my_function", &my_function, 
+                (arg("arg1"), arg("arg2"), ...),
+                "Documentation");
+
+            // export a class and its member functions
+            class_<MyClass>("MyClass",
+                "Documentation")
+                .def("foo", &MyClass::foo,
+                     (arg("arg1"), arg("arg2"), ...),
+                     "Documentation")
+            ;
+                     
+            ... // more module functionality (refer to boost_python documentation)
+        }
+    
+2. When your module uses additional C++ source files, they should start with the following defines::
+
+        // this must define the same symbol as the main module file (numpy requirement)
+        #define PY_ARRAY_UNIQUE_SYMBOL my_module_PyArray_API
+        #define NO_IMPORT_ARRAY
+
+3. Implement your wrapper functions. Numpy ndarrays are passed to C++ via the wrapper classes NumpyArray_ and NumpyAnyArray_. You can influence the conversion from Python to C++ by using different instantiations of NumpyArray, as long as the Python array supports the axistags attribute (refer to :ref:`axis order definitions <array-order-parameter>` for the meaning of the term 'ascending order')::
+
+            // We add a 'using' declaration for brevity of our examples.
+            // In actual code, you should probably prefer explicit namespace qualification.
+        using namespace vigra;
+
+            // Accept any array type and return an arbitrary array type.
+            // Returning NumpyAnyArray is always safe, because at that point
+            // C++ no longer cares about the particular type of the array.
+        NumpyAnyArray foo(NumpyAnyArray array);
+        
+            // Accept a 3-dimensional float32 array and transpose it 
+            // into ascending axis order ('F' order).
+        void foo(NumpyArray<3, float> array);
+        
+            // Accept a 2-dimensional float32 array with an arbitrary number of channels and
+            // transpose the axes into VIGRA ('V') order (channels are last, other axes ascending).
+            // Note that the NumpyArray dimension is 3 to account for the channel dimension.
+            // If the original numpy array has no channel axis, vigranumpy will automatically
+            // insert a singleton axis.
+        void foo(NumpyArray<3, Multiband<float> > array);
+        
+            // Accept a 2-dimensional float32 array that has only a single channel
+            // (that is, 'array.channels == 1' must hold on the Python side).
+            // Non-channel axes are transposed into ascending order.
+            // Note that the NumpyArray dimension is now 2.
+        void foo(NumpyArray<2, Singleband<float> > array);
+        
+            // Accept a float32 array that has 2 non-channel dimensions and 
+            // exactly 3 channels (i.e. 'array.channels == 3' on the Python side). 
+            // Non-channel axes are transposed into ascending order.
+            // Note that the NumpyArray dimension is again 2, but the pixel type is 
+            // now a vector.
+            // The conversion will only succeed if the channel axis is unstrided on
+            // the Python side (that is, the following expression is True:
+            //      array.strides[array.channelIndex] == array.dtype.itemsize).
+        void foo(NumpyArray<2, TinyVector<float, 3> > array);
+        void foo(NumpyArray<2, RGBValue<float> > array);
+    
+   Or course, these functions can also be templated. 
+   
+   When your functions return newly allocated arrays, it is usually desirable to transfer the input's axistags to the output (otherwise, vigranumpy will use :meth:`~vigra.VigraArray.defaultAxistags` as a fallback). There is a standard vigranumpy idiom for this task which assumes that the wrapped function has an optional parameter 'output' for a possibly pre-allocated output array. The axistags are then transferred by reshaping the output array with a ``taggedShape()`` (which is a combina [...]
+   
+        NumpyAnyArray
+        foo(NumpyArray<3, Multiband<float32> > input, 
+            NumpyArray<3, Multiband<float32> > output = boost::python::object())
+        {
+            // Reshape only if the output array was not explicitly passed in.
+            // Otherwise, use the output array as is.
+            output.reshapeIfEmpty(input.taggedShape(), 
+                      "error message when shape is unsuitable.");
+                      
+            ... // your algorithm
+        }
+        
+   It is also possible to modify the tagged shape before it is applied to the output array::
+   
+        input.taggedShape()
+             .resize(Shape2(new_width, new_height))
+             .setChannelCount(new_channel_count)
+             .setChannelDescription("a description")
+             
+   The C++ code can be multi-threaded when you unlock Python's global interpreter lock. After unlocking, your wrapper code must not call any Python functions, so the unlock statement should go after ``output.reshapeIfEmpty()``::
+   
+        NumpyAnyArray
+        foo(NumpyArray<3, Multiband<float32> > input, 
+            NumpyArray<3, Multiband<float32> > output = boost::python::object())
+        {
+            output.reshapeIfEmpty(input.taggedShape(), "Message.");
+            
+                // Allow parallelization from here on. The destructor of
+                // _pythread will automatically regain the global interpreter lock
+                // just before this function returns to Python.
+            PyAllowThreads _pythread;
+            
+            ... // your algorithm
+        }
+
+4. Export your wrapped functions. ``boost::python::def`` is called in its usual way, with one simple extension: Since vigranumpy does not know which NumpyArray variants you are going to use, appropriate converter functions between Python and C++ must be registered on demand. You do this by enclosing your function pointer into a call to the 'registerConverters()' function::
+
+        // in the module's init function
+        def("my_function", vigra::registerConverters(&my_function),
+           (arg("arg1"), ...),
+           "Documentation");
+           
+If you need more information, it is always a good idea to look at the source code of the existing vigranumpy modules.
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/vigranumpy/docsrc/make.bat b/vigranumpy/docsrc/make.bat
new file mode 100644
index 0000000..72cc5fa
--- /dev/null
+++ b/vigranumpy/docsrc/make.bat
@@ -0,0 +1,116 @@
+ at ECHO OFF
+
+REM Command file for Sphinx documentation
+
+set SPHINXBUILD=sphinx-build
+set BUILDDIR=..\doc
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees -D pngmath_dvipng_args=\['-D 1000'\, '-bg Transparent'\]
+%SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+) else (
+	set ALLSPHINXOPTS=-D latex_paper_size=a4 %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html      to make standalone HTML files
+	echo.  dirhtml   to make HTML files named index.html in directories
+	echo.  pickle    to make pickle files
+	echo.  json      to make JSON files
+	echo.  htmlhelp  to make HTML files and a HTML help project
+	echo.  qthelp    to make HTML files and a qthelp project
+	echo.  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  changes   to make an overview over all changed/added/deprecated items
+	echo.  linkcheck to check all external links for integrity
+	echo.  doctest   to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\vigranumpy.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\vigranumpy.ghc
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+:end
diff --git a/vigranumpy/lib/CMakeLists.txt b/vigranumpy/lib/CMakeLists.txt
new file mode 100644
index 0000000..65729a4
--- /dev/null
+++ b/vigranumpy/lib/CMakeLists.txt
@@ -0,0 +1,32 @@
+FILE(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/__version__.py
+     "version = '${vigra_version}'
+")
+SET(PYSOURCES
+    __init__.py
+    __version__.py
+    tagged_array.py
+    arraytypes.py
+    ufunc.py
+    )
+
+INSTALL(FILES ${PYSOURCES} DESTINATION ${VIGRANUMPY_INSTALL_DIR}/vigra)
+
+ADD_CUSTOM_TARGET(vigranumpy_lib)
+ADD_DEPENDENCIES(vigranumpy vigranumpy_lib)
+
+FOREACH(lib_file ${PYSOURCES})
+    ADD_CUSTOM_COMMAND(
+        TARGET vigranumpy_lib
+        POST_BUILD
+        COMMAND ${CMAKE_COMMAND}
+        ARGS -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${lib_file} ${vigranumpy_tmp_dir}/${lib_file}
+        COMMENT "Copying Python sources to temporary module directory")
+ENDFOREACH(lib_file)
+ADD_CUSTOM_COMMAND(
+    TARGET vigranumpy_lib
+    POST_BUILD
+    COMMAND ${CMAKE_COMMAND}
+    ARGS -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/pyqt ${vigranumpy_tmp_dir}/pyqt
+    COMMENT "Copying Python sources to temporary module directory")
+
+ADD_SUBDIRECTORY(pyqt)
\ No newline at end of file
diff --git a/vigranumpy/lib/__init__.py b/vigranumpy/lib/__init__.py
new file mode 100644
index 0000000..5618ddf
--- /dev/null
+++ b/vigranumpy/lib/__init__.py
@@ -0,0 +1,440 @@
+#######################################################################
+#
+#         Copyright 2009-2010 by Ullrich Koethe
+#
+#    This file is part of the VIGRA computer vision library.
+#    The VIGRA Website is
+#        http://hci.iwr.uni-heidelberg.de/vigra/
+#    Please direct questions, bug reports, and contributions to
+#        ullrich.koethe at iwr.uni-heidelberg.de    or
+#        vigra at informatik.uni-hamburg.de
+#
+#    Permission is hereby granted, free of charge, to any person
+#    obtaining a copy of this software and associated documentation
+#    files (the "Software"), to deal in the Software without
+#    restriction, including without limitation the rights to use,
+#    copy, modify, merge, publish, distribute, sublicense, and/or
+#    sell copies of the Software, and to permit persons to whom the
+#    Software is furnished to do so, subject to the following
+#    conditions:
+#
+#    The above copyright notice and this permission notice shall be
+#    included in all copies or substantial portions of the
+#    Software.
+#
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+#    OTHER DEALINGS IN THE SOFTWARE.
+#
+#######################################################################
+
+import sys, os
+
+_vigra_path = os.path.abspath(os.path.dirname(__file__))
+_vigra_doc_path = _vigra_path + '/doc/vigranumpy/index.html'
+
+if sys.platform.startswith('win'):
+    # On Windows, add subdirectory 'dlls' to the PATH in order to find
+    # the DLLs vigranumpy depends upon. Since this directory appears
+    # at the end of PATH, already installed DLLs are always preferred.
+    _vigra_dll_path = _vigra_path + '/dlls'
+    if os.path.exists(_vigra_dll_path):
+        os.putenv('PATH', os.getenv('PATH') + os.pathsep + _vigra_dll_path)
+
+def _fallbackModule(moduleName, message):
+    '''This function installs a fallback module with the given 'moduleName'.
+       All function calls into this module raise an ImportError with the
+       given 'message' that hopefully tells the user why the real module
+       was not available.
+    '''
+    import sys
+    moduleClass = vigranumpycore.__class__
+    class FallbackModule(moduleClass):
+        def __init__(self, name):
+            moduleClass.__init__(self, name)
+            self.__name__ = name
+        def __getattr__(self, name):
+            if name.startswith('__'):
+                return moduleClass.__getattribute__(self, name)
+            try:
+                return moduleClass.__getattribute__(self, name)
+            except AttributeError:
+                raise ImportError("""%s.%s: %s""" % (self.__name__, name, self.__doc__))
+
+    module = FallbackModule(moduleName)
+    sys.modules[moduleName] = module
+    module.__doc__ = """Import of module '%s' failed.\n%s""" % (moduleName, message)
+
+if not os.path.exists(_vigra_doc_path):
+    _vigra_doc_path = "http://hci.iwr.uni-heidelberg.de/vigra/doc/vigranumpy/index.html"
+
+__doc__ = '''VIGRA Computer Vision Library
+
+HTML documentation is available in
+
+   %s
+
+Help on individual functions can be obtained via their doc strings
+as usual.
+
+The following sub-modules group related functionality:
+
+* arraytypes (VigraArray and axistags, automatically imported into 'vigra')
+* ufunc      (improved array arithmetic, automatically used by VigraArray)
+* impex      (image and array I/O)
+* colors     (color space transformations)
+* filters    (spatial filtering, e.g. smoothing)
+* sampling   (image and array re-sampling and interpolation)
+* fourier    (Fourier transform and Fourier domain filters)
+* analysis   (image analysis and segmentation)
+* learning   (machine learning and classification)
+* noise      (noise estimation and normalization)
+* geometry   (geometric algorithms, e.g. convex hull)
+''' % _vigra_doc_path
+ 
+from __version__ import version
+import vigranumpycore
+import arraytypes
+import impex
+import sampling
+import filters
+import analysis
+import learning
+import colors
+import noise
+import geometry
+import optimization
+
+sampling.ImagePyramid = arraytypes.ImagePyramid
+
+try:
+    import fourier
+except Exception, e:
+    _fallbackModule('vigra.fourier', 
+    '''
+    %s
+    
+    Make sure that the fftw3 libraries are found during compilation and import.
+    They may be downloaded at http://www.fftw.org/.''' % str(e))
+    import fourier
+
+# import most frequently used functions
+from arraytypes import *
+standardArrayType = arraytypes.VigraArray 
+defaultAxistags = arraytypes.VigraArray.defaultAxistags
+
+from impex import readImage, readVolume
+
+def readHDF5(filenameOrGroup, pathInFile, order=None):
+    '''Read an array from an HDF5 file.
+    
+       'filenameOrGroup' can contain a filename or a group object
+       referring to an already open HDF5 file. 'pathInFile' is the name 
+       of the dataset to be read, including intermediate groups. If the 
+       first argument is a group object, the path is relative to this 
+       group, otherwise it is relative to the file's root group.
+       
+       If the dataset has an attribute 'axistags', the returned array
+       will have type :class:`~vigra.VigraArray` and will be transposed 
+       into the given 'order' ('vigra.VigraArray.defaultOrder'
+       will be used if no order is given).  Otherwise, the returned 
+       array is a plain 'numpy.ndarray'. In this case, order='F' will 
+       return the array transposed into Fortran order.
+       
+       Requirements: the 'h5py' module must be installed.
+    '''
+    import h5py
+    if isinstance(filenameOrGroup, h5py.highlevel.Group):
+        file = None
+        group = filenameOrGroup
+    else:
+        file = h5py.File(filenameOrGroup, 'r')
+        group = file['/']
+    try:
+        dataset = group[pathInFile]
+        if not isinstance(dataset, h5py.highlevel.Dataset):
+            raise IOError("readHDF5(): '%s' is not a dataset" % pathInFile)
+        data = dataset.value
+        axistags = dataset.attrs.get('axistags', None)
+        if axistags is not None:
+            data = data.view(arraytypes.VigraArray)
+            data.axistags = arraytypes.AxisTags.fromJSON(axistags)
+            if order is None:
+                order = arraytypes.VigraArray.defaultOrder
+            data = data.transposeToOrder(order)
+        else:
+            if order == 'F':
+                data = data.transpose()
+            elif order not in [None, 'C', 'A']:
+                raise IOError("readHDF5(): unsupported order '%s'" % order)
+    finally:
+        if file is not None:
+            file.close()
+    return data
+        
+def writeHDF5(data, filenameOrGroup, pathInFile, compression=None):
+    '''Write an array to an HDF5 file.
+
+       'filenameOrGroup' can contain a filename or a group object
+       referring to an already open HDF5 file. 'pathInFile' is the name of the
+       dataset to be written, including intermediate groups. If the first
+       argument is a group object, the path is relative to this group,
+       otherwise it is relative to the file's root group. If the dataset already
+       exists, it will be replaced without warning.
+
+       If 'data' has an attribute 'axistags', the array is transposed to
+       numpy order before writing. Moreover, the axistags will be
+       stored along with the data in an attribute 'axistags'.
+
+       'compression' can be set to 'gzip', 'szip' or 'lzf'
+       gzip (standard compression),
+       szip (available if HDF5 is compiled with szip. Faster compression, limited types),
+       lzf (very fast compression, all types).
+       The 'lzf' compression filter is many times faster than 'gzip' 
+       at the cost of a lower compresion ratio.
+
+       Requirements: the 'h5py' module must be installed.
+    '''
+    import h5py
+    if isinstance(filenameOrGroup, h5py.highlevel.Group):
+        file = None
+        group = filenameOrGroup
+    else:
+        file = h5py.File(filenameOrGroup)
+        group = file['/']
+    try:
+        levels = pathInFile.split('/')
+        for groupname in levels[:-1]:
+            if groupname == '':
+                continue
+            g = group.get(groupname, default=None)
+            if g is None:
+                group = group.create_group(groupname)
+            elif not isinstance(g, h5py.highlevel.Group):
+                raise IOError("writeHDF5(): invalid path '%s'" % pathInFile)
+            else:
+                group = g
+        dataset = group.get(levels[-1], default=None)
+        if dataset is not None:
+            if isinstance(dataset, h5py.highlevel.Dataset):
+                del group[levels[-1]]
+            else:
+                raise IOError("writeHDF5(): cannot replace '%s' because it is not a dataset" % pathInFile)
+        try:
+            data = data.transposeToNumpyOrder()
+        except:
+            pass
+        dataset = group.create_dataset(levels[-1], data=data, compression=compression)
+        if hasattr(data, 'axistags'):
+            dataset.attrs['axistags'] = data.axistags.toJSON()
+    finally:
+        if file is not None:
+            file.close()
+        
+impex.readHDF5 = readHDF5
+readHDF5.__module__ = 'vigra.impex'
+impex.writeHDF5 = writeHDF5
+writeHDF5.__module__ = 'vigra.impex'
+
+from filters import convolve, gaussianSmoothing
+from sampling import resize
+
+# import enums
+CLOCKWISE = sampling.RotationDirection.CLOCKWISE
+COUNTER_CLOCKWISE = sampling.RotationDirection.COUNTER_CLOCKWISE
+UPSIDE_DOWN = sampling.RotationDirection.UPSIDE_DOWN
+CompleteGrow = analysis.SRGType.CompleteGrow
+KeepContours = analysis.SRGType.KeepContours
+StopAtThreshold = analysis.SRGType.StopAtThreshold
+ 
+_selfdict = globals()
+def searchfor(searchstring):
+   '''Scan all vigra modules to find classes and functions containing
+      'searchstring' in their name.
+   '''
+   for attr in _selfdict.keys():
+      contents = dir(_selfdict[attr])
+      for cont in contents:
+         if ( cont.upper().find(searchstring.upper()) ) >= 0:
+            print attr+"."+cont
+
+# FIXME: use axistags here
+def imshow(image):
+    '''Display a scalar or RGB image by means of matplotlib.
+       If the image does not have one or three channels, an exception is raised.
+       The image will be automatically scaled to the range 0...255 when its dtype 
+       is not already 'uint8'.
+    '''
+    import matplotlib.pylab
+    
+    if not hasattr(image, 'axistags'):
+        return matplotlib.pyplot.imshow(image)
+    
+    image = image.transposeToNumpyOrder()
+    if image.channels == 1:
+        image = image.dropChannelAxis().view(numpy.ndarray)
+        plot = matplotlib.pyplot.imshow(image, cmap=matplotlib.cm.gray, \
+                                         norm=matplotlib.cm.colors.Normalize())
+        matplotlib.pylab.show()
+        return plot
+    elif image.channels == 3:
+        if image.dtype != numpy.uint8:
+            out = image.__class__(image.shape, dtype=numpy.uint8, axistags=image.axistags)
+            image = colors.linearRangeMapping(image, newRange=(0.0, 255.0), out=out)
+        plot = matplotlib.pyplot.imshow(image.view(numpy.ndarray))
+        matplotlib.pylab.show()
+        return plot
+    else:
+        raise RuntimeError("vigra.imshow(): Image must have 1 or 3 channels.")
+
+        
+# auto-generate code for additional Kernel generators:
+def _genKernelFactories(name):
+    for oldName in dir(eval('filters.'+name)):
+        if not oldName.startswith('init'):
+            continue
+        #remove init from beginning and start with lower case character
+        newPrefix = oldName[4].lower() + oldName[5:]
+        if newPrefix == "explicitly":
+            newPrefix = "explict"
+        newName = newPrefix + 'Kernel'
+        if name == 'Kernel2D':
+            newName += '2D'
+        code = '''def %(newName)s(*args):
+        k = filters.%(name)s()
+        k.%(oldName)s(*args)
+        return k
+%(newName)s.__doc__ = filters.%(name)s.%(oldName)s.__doc__
+filters.%(newName)s=%(newName)s
+''' % {'oldName': oldName, 'newName': newName, 'name': name}
+        exec code
+
+_genKernelFactories('Kernel1D')
+_genKernelFactories('Kernel2D')
+del _genKernelFactories
+
+# define watershedsUnionFind()
+def _genWatershedsUnionFind():
+    def watershedsUnionFind(image, neighborhood=None, out = None):
+        '''Compute watersheds of an image using the union find algorithm.
+           If 'neighborhood' is 'None', it defaults to 8-neighborhood for 2D inputs
+           and 6-neighborhood for 3D inputs.
+           
+           Calls :func:`watersheds` with parameters::\n\n
+                watersheds(image, neighborhood=neighborhood, method='UnionFind', out=out)
+        '''
+        if neighborhood is None:
+            neighborhood = 8 if image.spatialDimensions == 2 else 6
+                
+        return analysis.watersheds(image, neighborhood=neighborhood, method='UnionFind', out=out)
+    
+    watershedsUnionFind.__module__ = 'vigra.analysis'
+    analysis.watershedsUnionFind = watershedsUnionFind
+
+_genWatershedsUnionFind()
+del _genWatershedsUnionFind
+
+# define tensor convenience functions
+def _genTensorConvenienceFunctions():
+    def hessianOfGaussianEigenvalues(image, scale, out=None, 
+                                     sigma_d=0.0, step_size=1.0, window_size=0.0, roi=None):
+        '''Compute the eigenvalues of the Hessian of Gaussian at the given scale
+           for a scalar image or volume.
+           
+           Calls :func:`hessianOfGaussian` and :func:`tensorEigenvalues`.
+        '''
+        
+        hessian = filters.hessianOfGaussian(image, scale, 
+                                            sigma_d=sigma_d, step_size=step_size, 
+                                            window_size=window_size, roi=roi)
+        return filters.tensorEigenvalues(hessian, out=out)
+    
+    hessianOfGaussianEigenvalues.__module__ = 'vigra.filters'
+    filters.hessianOfGaussianEigenvalues = hessianOfGaussianEigenvalues
+
+    def structureTensorEigenvalues(image, innerScale, outerScale, out=None, 
+                                   sigma_d=0.0, step_size=1.0, window_size=0.0, roi=None):
+        '''Compute the eigenvalues of the structure tensor at the given scales
+           for a scalar or multi-channel image or volume.
+           
+           Calls :func:`structureTensor` and :func:`tensorEigenvalues`.
+        '''
+
+        st = filters.structureTensor(image, innerScale, outerScale, 
+                                     sigma_d=sigma_d, step_size=step_size, 
+                                     window_size=window_size, roi=roi)
+        return filters.tensorEigenvalues(st, out=out)
+    
+    structureTensorEigenvalues.__module__ = 'vigra.filters'
+    filters.structureTensorEigenvalues = structureTensorEigenvalues
+
+_genTensorConvenienceFunctions()
+del _genTensorConvenienceFunctions
+
+# define feature convenience functions
+def _genFeaturConvenienceFunctions():
+    def supportedFeatures(array):
+        '''Return a list of feature names that are available for the given array. These feature
+           names are the valid inputs to a call of :func:`extractFeatures`. E.g., to compute 
+           just the first two features in the list, use::
+           
+                f = vigra.analysis.supportedFeatures(array)
+                print "Computing features:", f[:2]
+                r = vigra.analysis.extractFeatures(array, features=f[:2])
+        '''
+        
+        return analysis.extractFeatures(array, None).supportedFeatures()
+
+    supportedFeatures.__module__ = 'vigra.analysis'
+    analysis.supportedFeatures = supportedFeatures
+
+    def supportedRegionFeatures(array, labels):
+        '''Return a list of feature names that are available for the given array and label array. 
+           These feature names are the valid inputs to a call of 
+           :func:`extractRegionFeatures`. E.g., to compute just the first two features in the 
+           list, use::
+           
+                f = vigra.analysis.supportedRegionFeatures(array, labels)
+                print "Computing features:", f[:2]
+                r = vigra.analysis.extractRegionFeatures(array, labels, features=f[:2])
+        '''
+        
+        return analysis.extractRegionFeatures(array, labels, None).supportedFeatures()
+    
+    supportedRegionFeatures.__module__ = 'vigra.analysis'
+    analysis.supportedRegionFeatures = supportedRegionFeatures
+    
+    # implement the read-only part of the 'dict' API in FeatureAccumulator and RegionFeatureAccumulator
+    def __len__(self):
+        return len(self.keys())
+    def __iter__(self):
+        return self.keys().__iter__()
+    def has_key(self, key):
+        try:
+            return self.isActive(key)
+        except:
+            return False
+    def values(self):
+        return [self[k] for k in self.keys()]
+    def items(self):
+        return [(k, self[k]) for k in self.keys()]
+    def iterkeys(self):
+        return self.keys().__iter__()
+    def itervalues(self):
+        for k in self.keys():
+            yield self[k]
+    def iteritems(self):
+        for k in self.keys():
+            yield (k, self[k])
+    
+    for k in ['__len__', '__iter__', 'has_key', 'values', 'items', 'iterkeys', 'itervalues', 'iteritems']:
+        setattr(analysis.FeatureAccumulator, k, eval(k))
+        setattr(analysis.RegionFeatureAccumulator, k, eval(k))
+
+_genFeaturConvenienceFunctions()
+del _genFeaturConvenienceFunctions
diff --git a/vigranumpy/lib/arraytypes.py b/vigranumpy/lib/arraytypes.py
new file mode 100644
index 0000000..168e84b
--- /dev/null
+++ b/vigranumpy/lib/arraytypes.py
@@ -0,0 +1,1979 @@
+#######################################################################
+#
+#         Copyright 2009-2011 by Ullrich Koethe
+#
+#    This file is part of the VIGRA computer vision library.
+#    The VIGRA Website is
+#        http://hci.iwr.uni-heidelberg.de/vigra/
+#    Please direct questions, bug reports, and contributions to
+#        ullrich.koethe at iwr.uni-heidelberg.de    or
+#        vigra at informatik.uni-hamburg.de
+#
+#    Permission is hereby granted, free of charge, to any person
+#    obtaining a copy of this software and associated documentation
+#    files (the "Software"), to deal in the Software without
+#    restriction, including without limitation the rights to use,
+#    copy, modify, merge, publish, distribute, sublicense, and/or
+#    sell copies of the Software, and to permit persons to whom the
+#    Software is furnished to do so, subject to the following
+#    conditions:
+#
+#    The above copyright notice and this permission notice shall be
+#    included in all copies or substantial portions of the
+#    Software.
+#
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+#    OTHER DEALINGS IN THE SOFTWARE.
+#
+#######################################################################
+
+import sys
+import copy
+import numpy
+import ufunc
+import vigranumpycore
+
+from vigranumpycore import AxisType, AxisInfo, AxisTags
+
+def _preserve_doc(f):
+    npy_doc = eval('numpy.ndarray.%s.__doc__' % f.__name__)
+    f.__doc__ =  ("" if npy_doc is None else npy_doc) + \
+                 ("" if f.__doc__ is None else "\n" + f.__doc__)
+    return f
+
+# a decorator to finalize the return value of a 
+# dimension-reducing function (e.g. array.max())
+def _finalize_reduce_result(f):
+    def new_f(self, axis=None, out=None):
+        if type(axis) == str:
+            axis = self.axistags.index(axis)
+        res = f(self, axis, out)
+        if out is None:
+            if axis is not None:
+                res.axistags = self._copy_axistags()
+                del res.axistags[axis]
+            else:
+                # this 'else' is necessary because numpy 1.6.0 gives 
+                #     type(res) == type(self)
+                # instead of the desired
+                #     type(res) == self.dtype
+                # when res is scalar and self is a subclass of ndarray 
+                # (this is probably a bug in numpy, since it works correctly 
+                #  when self is a plain ndarray)
+                res = res.dtype.type(res)
+        return res
+    new_f.__doc__ = f.__doc__
+    return new_f
+
+def _numpyarray_overloaded_function(f, self, axis=None, dtype=None, out=None):
+    if type(axis) == str:
+        axis = self.axistags.index(axis)
+    if axis is None:
+        return f(self.transposeToOrder('C').view(numpy.ndarray), dtype=dtype, out=out)
+    else:
+        res = f(self.view(numpy.ndarray), axis, dtype, out)
+        if out is None:
+            res = res.view(VigraArray)
+            res.axistags = self._copy_axistags()
+            del res.axistags[axis]
+        return res
+
+class classproperty(object):
+    def __get__(self, instance, cls):
+            if self.__instance_method is not None and instance is not None:
+                return self.__instance_method(instance)
+            else:
+                return self.__class_method(cls)
+    def __init__(self, class_method, instance_method=None):
+            self.__class_method = class_method
+            self.__instance_method = instance_method
+
+def newaxis(axisinfo=AxisInfo()):
+    '''
+    Create a new singleton axis via the indexing operator. This works similar to 
+    `numpy.newaxis`, but allows to provide an AxisInfo object for the new axis. 
+    For example::
+    
+        >>> s = vigra.ScalarImage((width, height))
+        >>> s.axistags  # no channel axis
+        x y
+        >>> t = s[..., numpy.newaxis]
+        >>> t.axistags  # with unknown axis type
+        x y ?
+        >>> t = s[..., vigra.newaxis(vigra.AxisInfo.c)]
+        >>> t.axistags  # with channel axis 
+        x y c
+    '''
+    return axisinfo
+
+def taggedView(array, axistags):
+    '''
+    Create a view to the given array with type :class:`~vigra.VigraArray` and the 
+    given axistags. This is essentially a shorthand for::
+    
+        >>> view = array.view(vigra.VigraArray)
+        >>> view.axistags = copy.copy(axistags)
+        
+    if axistags is an instance of AxisTags. Otherwise, the function first attempts
+    to convert the input to that type by calling VigraArray.defaultAxistags()
+    '''
+    if not isinstance(axistags, AxisTags):
+        axistags = VigraArray.defaultAxistags(axistags)
+    else:
+        axistags = copy.copy(axistags)
+    if array.ndim != len(axistags):
+        raise RuntimeError('vigra.taggedView(): array.ndim must match len(axistags).')
+    res = array.view(VigraArray)
+    res.axistags = axistags
+    return res
+
+def dropChannelAxis(array):
+    '''
+    Return the view created by ``array.``:meth:`~vigra.VigraArray.dropChannelAxis` if 
+    the given array supports that function, or return ``array`` unchanged otherwise.
+    '''
+    try:
+        return array.dropChannelAxis()
+    except:
+        return array
+
+# FIXME: This is a workaround for the disabled C++ function for the same purpose.
+#        Enable the C++ version when boost 1.41 is available on all relevant platforms.
+def _AxisTags_fromJSON(json_rep):
+    '''
+        Construct a new AxisTags object from the given JSON representation.
+        This is mainly used to reconstruct arrays from HDF5 datasets with
+        a suitable axistags attribute (see :func:`~vigra.impex.readHDF5`).
+    '''
+    tag_dict = eval(json_rep)
+    tag_list = []
+    for tags in tag_dict['axes']:
+        tags['typeFlags'] = AxisType(tags['typeFlags'])
+        tag_list.append(AxisInfo(**tags))
+    return AxisTags(tag_list)
+
+def _AxisTags__reduce__(self):
+    '''
+        enable pickling of AxisTags
+    '''
+    return _AxisTags_fromJSON, (self.toJSON(),)
+
+AxisTags.__reduce__ = _AxisTags__reduce__
+AxisTags.fromJSON = staticmethod(_AxisTags_fromJSON)
+AxisTags.fromJSON.__doc__ = _AxisTags_fromJSON.__doc__
+    
+# How to construct a VigraArray
+#
+# case 1: from shape and order or axistags
+# conventions: - shape has explicit channel axis
+#              - 'A' order defaults to 'V' order
+#              - order implies axistags and vice versa, you cannot provide both
+# * look up the array type. If it is a plain ndarray, skip axistags
+# * construct array according to order, optionally init with a constant
+# * create and assign normalized axistags, if not explicitly given
+# * optionally remove a singleton channel dimension (while we know where it is)
+# * permute the array by the inverse normalization
+# * assign axistags, if explicitly given (check compatibility)
+#
+# case 2: from another array
+# * if taget order is 'A' or source and target order are equal, copy as is (including axistags)
+# * otherwise, normalize the shape according to target order and
+#   remember the normalizing permutation
+# * construct array in normalized order
+# * permute the array by the inverse normalization
+# * copy original data and axistags
+
+_constructArrayFromAxistags = vigranumpycore.constructArrayFromAxistags 
+    
+def _constructArrayFromOrder(cls, shape, dtype, order, init):
+    axistags = VigraArray.defaultAxistags(len(shape), order)
+    return _constructArrayFromAxistags(cls, shape, dtype, axistags, init)
+    
+def _constructArrayFromArray(cls, obj, dtype, order, init, axistags):
+    if order is None:
+        order = 'A'
+    if order == 'A':
+        # we cannot use ndarray.copy('A') here, because this only preserves 'C' and 'F'
+        # order, whereas any other order is silently transformed into 'C'
+        
+        # we must also make sure that a singleton channel index has the smallest stride
+        # (otherwise, strides in the copy may not exactly match those in obj)
+        strides = list(obj.strides)
+        try:
+            channelIndex = obj.channelIndex
+            if channelIndex < obj.ndim and obj.shape[channelIndex] == 1:
+                strides[channelIndex] = 0
+        except:
+            pass
+        permutation = list(numpy.array(strides).argsort())
+        norm_shape = tuple(numpy.array(obj.shape)[permutation])
+        inverse_permutation = list(numpy.array(permutation).argsort())
+        array = numpy.ndarray.__new__(cls, norm_shape, dtype, order='F')
+        array = array.transpose(inverse_permutation)
+    else:
+        array = _constructArrayFromOrder(cls, obj.shape, dtype, order, False)
+        
+    if init:
+        array[...] = obj
+    if cls is not numpy.ndarray:
+        if axistags is not None:
+            array.axistags = axistags
+        elif hasattr(array, 'axistags'):
+            del array.axistags
+    return array
+
+def _constructArrayFromPickle(_arraypickle, _permutation, _axistags):
+    reconstructionFunction = _arraypickle[0]
+    reconstructionArgs = _arraypickle[1]
+    array = reconstructionFunction(*reconstructionArgs)
+    array.__setstate__(_arraypickle[2])
+    array = array.transpose(_permutation)
+    array.axistags = AxisTags.fromJSON(_axistags)
+    return array
+    
+def _constructArrayFromZMQSocket(socket, flags=0, copy=True, track=False):
+    metadata = socket.recv_json(flags=flags)
+    axistags = AxisTags.fromJSON(socket.recv(flags=flags))
+    data = buffer(socket.recv(flags=flags, copy=copy, track=track))
+    array = numpy.frombuffer(data, dtype=metadata['dtype']).reshape(metadata['shape'])
+    array = taggedView(array.transpose(metadata['permutation']), axistags)
+    return array
+    
+##################################################################
+
+class VigraArray(numpy.ndarray):
+    '''
+    This class extends numpy.ndarray with the concept of **axistags** 
+    which encode the semantics of the array's axes. VigraArray overrides all
+    numpy.ndarray methods in order to handle axistags in a sensible way.
+    In particular, operations acting on two arrays simultaneously (e.g.
+    addition) will first transpose the arguments such that their axis 
+    ordering matches.
+
+    Constructor:
+    
+    .. method:: VigraArray(obj, dtype=numpy.float32, order=None, init=True, value=None, axistags=None)
+
+        :param obj: an array or shape object (see below)
+        :param dtype: desired element type
+        :param order: desired memory layout (see below)
+        :param init: True: initialize the image with zeros; False: do not 
+                     initialize the image
+        :type init: boolean
+        :param value: initialize the image with this value (overrides init)
+        :type value: convertible to dtype
+        :param axistags: the AxisTags object of the new array. The length of 
+                         axistags must match the array's shape. It axistags=None, 
+                         obj.axistags is used if it exists. Otherwise, a new 
+                         axistags object is created by a call to 
+                         :meth:`~vigra.VigraArray.defaultAxistags`.
+ 
+        **obj** may be one of the following
+
+        * If obj is a numpy.ndarray or a subtype, a copy of obj with the given 
+          dtype, order and resulting class VigraArray is created. If obj.axistags
+          exists, the new array will have these axistags as well, unless new
+          axistags are explicitly passed to the constructor.
+        * If obj is a sequence, it is interpreted as a shape. 
+        * Otherwise, or if shape and axistags are incompatible, an exception
+          is raised.
+          
+        **order** can be 'C' (C order), 'F' (Fortran order), 'V' (VIGRA
+        order), 'A' (any), or None. This parameter controls the order of strides 
+        and axistags (unless axistags are explicit passed into the constructor). 
+        See the :ref:`order definitions <array-order-parameter>` for details. If 
+        'order=None', the order is determined by :attr:`VigraArray.defaultOrder`.
+    '''
+    
+    ###############################################################
+    #                                                             #
+    #       a number of helper functions related to axistags      #
+    #                                                             #
+    ###############################################################    
+    
+    # a number of helper functions related to axistags
+    
+    # IMPORTANT: do not remove or rename this function, it is called from C++
+    @classproperty
+    def defaultOrder(cls):
+        '''
+        Get the default axis ordering, currently 'V' (VIGRA order)
+        '''
+        return 'V'
+
+    # IMPORTANT: do not remove or rename this function, it is called from C++
+    @staticmethod
+    def defaultAxistags(tagSpec, order=None, noChannels=False):
+        '''
+        Get default axistags for the given specification 'tagSpec'. TagSpec can be the 
+        number of dimensions of the array (``array.ndim``, must be <= 5) or a string 
+        containing a sequence of axis keys (only the default keys 'x', 'y', 'z', 't', 
+        and 'c' are currently supported). The 'order' parameter determines the axis 
+        ordering, see the :ref:`order definitions <array-order-parameter>` for details.
+        If 'noChannels' is True, there will be no channel axis. Examples::
+        
+            >>> vigra.VigraArray.defaultAxistags(3)
+            x y c
+            >>> vigra.VigraArray.defaultAxistags(4)
+            x y z c
+            >>> vigra.VigraArray.defaultAxistags(5)
+            x y z t c
+            >>> vigra.VigraArray.defaultAxistags(3, order='C')
+            y x c
+            >>> vigra.VigraArray.defaultAxistags(2, noChannels=True)
+            x y
+            >>> vigra.VigraArray.defaultAxistags(3, noChannels=True)
+            x y z
+            >>> vigra.VigraArray.defaultAxistags(4, noChannels=True)
+            x y z t
+            >>> vigra.VigraArray.defaultAxistags('xty')
+            x t y
+            >>> vigra.VigraArray.defaultAxistags('xty', order='V')
+            x y t
+        '''
+        if type(tagSpec) == str:
+            taglist = [eval('AxisInfo.' + k) for k in tagSpec]
+        else:
+            start = 1 if noChannels else 0
+            end = start + tagSpec
+            taglist = [AxisInfo.c, AxisInfo.x, AxisInfo.y, AxisInfo.z, AxisInfo.t][start:end]
+            if order is None or order == 'A':
+                order = VigraArray.defaultOrder
+        tags = AxisTags(taglist)
+        if order is not None:
+            tags.transpose(tags.permutationToOrder(order))
+        return tags
+
+    # IMPORTANT: do not remove or rename this function, it is called from C++
+    @staticmethod
+    def _copyValuesImpl(target, source):
+        try:
+            target = target.squeeze()
+            target = target.transposeToNumpyOrder()
+        except:
+            pass
+
+        try:
+            source = source.squeeze()
+            source = source.transposeToNumpyOrder()
+        except:
+            pass
+        
+        try:
+            compatible = source.axistags.compatible(target.axistags)
+        except:
+            compatible = True
+
+        if not compatible:
+            raise RuntimeError("VigraArray._copyValuesImpl(): incompatible axistags")
+
+        target[...] = source
+    
+    # IMPORTANT: do not remove or rename this function, it is called from C++
+    @staticmethod
+    def _empty_axistags(ndim):
+        '''Create an axistags object with non-informative entries. 
+           That is, all axisinfo objects are '?'.
+        '''
+        return AxisTags(ndim)
+    
+    def _copy_axistags(self):
+        '''Create a copy of 'self.axistags'. If the array doesn't have axistags, _empty_axistags() 
+           will be returned.
+        '''
+        return copy.copy(getattr(self, 'axistags', self._empty_axistags(self.ndim)))
+        
+    def _transform_axistags(self, index):
+        if hasattr(self, 'axistags'):
+            return self.axistags.transform(index, self.ndim)
+        else:
+            return self._empty_axistags(self.ndim)
+
+    def _transpose_axistags(self, *permutation):
+        '''Create a copy of self.axistags with transposed entries.
+        '''
+        if hasattr(self, 'axistags'):
+            res = copy.copy(self.axistags)
+            try:
+                len(permutation[0])
+                res.transpose(permutation[0])
+            except:
+                res.transpose(permutation)
+            return res
+        else:
+            return self._empty_axistags(self.ndim)
+
+    ###############################################################
+    #                                                             #
+    #                   standard array functions                  #
+    #                                                             #
+    ###############################################################    
+    
+    def __new__(cls, obj, dtype=numpy.float32, order=None, init=True, value=None, axistags=None):
+        if value is not None:
+            init = False
+        if isinstance(obj, numpy.ndarray):
+            if axistags is None:
+                if hasattr(obj, 'axistags'):
+                    axistags = copy.copy(obj.axistags)
+                else:
+                    raise RuntimeError("VigraArray(): axistags must be given when constructing from plain array.")
+            elif obj.ndim != len(axistags):
+                raise RuntimeError("VigraArray(): axistags have wrong length.")
+            if order is None:
+                res = _constructArrayFromAxistags(cls, obj.shape, dtype, axistags, init)
+                if init:
+                    res[...] = obj
+            else:
+                res = _constructArrayFromArray(cls, obj, dtype, order, init, axistags)
+        else:
+            if axistags is None:
+                if order is None:
+                    order = VigraArray.defaultOrder
+            elif len(axistags) != len(obj):
+                raise RuntimeError("VigraArray(): axistags have wrong length.")
+            if order is None:
+                res = _constructArrayFromAxistags(cls, obj, dtype, axistags, init)
+            else:
+                res = _constructArrayFromOrder(cls, obj, dtype, order, init)
+                if cls is not numpy.ndarray and axistags is not None:
+                    res.axistags = axistags
+        if value is not None:
+            res.fill(value)
+        return res
+
+    __array_priority__ = 15.0
+
+    def __array_finalize__(self, obj):
+        if hasattr(obj, 'axistags'):
+            self.axistags = obj.axistags
+
+    def __copy__(self, order='A'):
+        result = numpy.ndarray.__copy__(self, order)
+        result.axistags = result._copy_axistags()
+        return result
+        
+    @_preserve_doc
+    def __deepcopy__(self, memo):
+        # numpy.ndarray.__deepcopy__ always creates C-order arrays =>
+        #   transpose self accordingly, and transpose back after the copy
+        result = numpy.ndarray.__deepcopy__(self.transposeToNumpyOrder(), memo)
+        result = result.transpose(self.permutationFromNumpyOrder())
+        memo[id(self)] = result
+        result.__dict__ = copy.deepcopy(self.__dict__, memo)
+        return result
+    
+    def __repr__(self):
+        return "%s(shape=%s, axistags=%s, dtype=%s, data=\n%s)" % \
+          (self.__class__.__name__, str(self.shape), repr(self.axistags), str(self.dtype), str(self))
+          
+    def __str__(self):
+        try:
+            self = self.transposeToVigraOrder().transpose()
+        except:
+            pass
+        return str(self.view(numpy.ndarray))
+          
+    def __reduce__(self):
+        '''
+            Enable pickling of a VigraArray, including axistags. The stride ordering
+            will be preserved in the unpickled array. Note that user-defined attributes
+            will not be saved and restored.
+        '''
+        # since the stride ordering is not necessarily preserved by ndarray's pickling
+        # functions, we need to normalize stride ordering, and permute to the original 
+        # ordering upon reconstruction
+        pickled = numpy.ndarray.__reduce__(self.transposeToNumpyOrder())
+        return _constructArrayFromPickle, (pickled, self.permutationFromNumpyOrder(), self.axistags.toJSON())
+        
+    @staticmethod
+    def receiveSocket(socket, flags=0, copy=True, track=False):
+        '''
+        Reconstruct an array that has been transferred via a ZMQ socket by a call to 
+        VigraArray.sendSocket(). This only works when the 'zmq' module is available.
+        The meaning of the arguments is described in zmq.Socket.recv().
+        '''
+        return _constructArrayFromZMQSocket(socket, flags, copy, track)
+
+            
+    ###############################################################
+    #                                                             #
+    #                     array I/O and display                   #
+    #                                                             #
+    ###############################################################    
+    
+    def writeImage(self, filename, dtype = '', compression = ''):
+        '''Write an image to a file. 
+        Consult :func:`vigra.impex.writeImage` for detailed documentation'''
+        import vigra.impex
+
+        ndim = self.ndim
+        if self.channelIndex < ndim:
+            ndim -= 1
+        if ndim != 2:
+            raise RuntimeError("VigraArray.writeImage(): array must have 2 non-channel axes.")
+
+        vigra.impex.writeImage(self, filename, dtype, compression)
+            
+    def writeSlices(self, filename_base, filename_ext, dtype = '', compression = ''):
+        '''Write a volume to a sequence of files.         
+        Consult :func:`vigra.impex.writeVolume` for detailed documentation.
+        '''
+        import vigra.impex
+
+        ndim = self.ndim
+        if self.channelIndex < ndim:
+            ndim -= 1
+        if ndim != 3:
+            raise RuntimeError("VigraArray.writeSlices(): array must have 3 non-channel axes.")
+
+        vigra.impex.writeVolume(self, filename_base, filename_ext, dtype, compression)
+            
+    def writeHDF5(self, filenameOurGroup, pathInFile):
+        '''Write the array to a HDF5 file. 
+           This is just a shortcut for :func:`vigra.impex.writeHDF5`
+        '''
+        import vigra.impex
+
+        vigra.impex.writeHDF5(self, filenameOurGroup, pathInFile)
+
+    def sendSocket(self, socket, flags=0, copy=True, track=False):
+        '''
+        Send array and metadata over a ZMQ socket. Only works if the 'zmq' module is available.
+        The meaning of the arguments is described in zmq.Socket.send().
+        '''
+        import zmq
+        
+        transposed = self.transposeToNumpyOrder().view(numpy.ndarray)
+        metadata = dict(
+            dtype = str(transposed.dtype),
+            shape = transposed.shape,
+            permutation = self.permutationFromNumpyOrder()
+        )
+        socket.send_json(metadata, flags|zmq.SNDMORE)
+        socket.send(self.axistags.toJSON(), flags|zmq.SNDMORE)
+        return socket.send(transposed, flags, copy=copy, track=track)
+
+    def imshow(self):
+        '''
+        Shorthand for 'vigra.imshow(self)'.
+        '''
+        import vigra
+        return vigra.imshow(self)
+
+    def show(self, normalize=True):
+        '''
+        Display this image in a vigra.pyqt.ImageWindow.
+        
+        The channels are intepreted as follows: 1 channel = gray image, 
+        2 channels = gray + alpha, 3 channels = RGB, 4 channels = RGB + alpha.
+        
+        The parameter `normalize` can be used to normalize an image's
+        value range to 0..255:
+
+        `normalize` = (nmin, nmax):
+          scale & clip image values from nmin..nmax to 0..255
+
+        `normalize` = nmax:
+          lets nmin default to zero, i.e. scale & clip the range 0..nmax
+          to 0..255
+
+        `normalize` = True: (default)
+          scale the image's actual range min()..max() to 0..255
+
+        `normalize` = False:
+          don't scale the image's values
+           
+        '''
+        from pyqt.imagewindow import showImage
+
+        ndim = self.ndim
+        channelIndex = self.channelIndex
+        if channelIndex < ndim:
+            if self.channels > 4:
+                raise RuntimeError("VigraArray.show(): array can have at most 4 channels.")
+            ndim -= 1
+        if ndim != 2:
+            raise RuntimeError("VigraArray.show(): array must have 2 non-channel axes.")
+
+        return showImage(self, normalize)
+
+    def qimage(self, normalize=True):
+        '''
+        Convert this image to a Qt QImage (mainly for display purposes).
+        The present image must have 1, 2, 3, or 4 channels, and the resulting
+        QImage will have QImage.Format_Indexed8 iff there was only one
+        channel and QImage.Format_[A]RGB32 otherwise (with the last of
+        2/4 channels being used as alpha channel).
+        
+        The parameter `normalize` can be used to normalize an image's
+        value range to 0..255:
+
+        `normalize` = (nmin, nmax):
+          scale & clip image values from nmin..nmax to 0..255
+
+        `normalize` = nmax:
+          lets nmin default to zero, i.e. scale & clip the range 0..nmax
+          to 0..255
+
+        `normalize` = True: (default)
+          scale the image's actual range min()..max() to 0..255
+
+        `normalize` = False:
+          don't scale the image's values
+           
+        '''
+        try:
+            import qimage2ndarray
+        except Exception, e:
+            from vigra import _fallbackModule
+            _fallbackModule('qimage2ndarray',
+            '''
+            %s
+            
+            If qimage2ndarray is missing on your system, download it from
+            http://pypi.python.org/pypi/qimage2ndarray/.''' % str(e))
+            import qimage2ndarray
+        
+        ndim = self.ndim
+        if self.channelIndex < ndim:
+            ndim -= 1
+        if ndim != 2:
+            raise RuntimeError("VigraArray.qimage(): array must have 2 non-channel axes.")
+
+        yxImage = self.transposeToNumpyOrder()
+
+        if self.channels == 1:
+            q = qimage2ndarray.gray2qimage(yxImage.dropChannelAxis(), normalize)
+        else:
+            q = qimage2ndarray.array2qimage(yxImage, normalize)
+
+        return q
+        
+    def asRGB(self, normalize=True):
+        '''
+        Expand a scalar array (i.e. an array with a single channel) into an RGB array with
+        three identical color channels. This is useful when you want to paste color
+        annotations (e.g. user labels) into the array.
+        
+        The parameter `normalize` can be used to normalize the array's
+        value range to 0..255:
+
+        `normalize` = (nmin, nmax):
+          scale & clip array values from nmin..nmax to 0..255
+
+        `normalize` = True: (default)
+          scale the array's actual range min()..max() to 0..255
+
+        `normalize` = False:
+          don't scale the array's values
+           
+        '''
+        if self.channels != 1:
+            raise RuntimeError("VigraArray.asRGB(): array must have a single channel.")
+        img = self.dropChannelAxis()
+        shape = img.shape + (3,)
+        axistags = copy.copy(img.axistags)
+        axistags.append(AxisInfo.c)
+        res = VigraArray(shape, axistags=axistags)
+        if normalize:
+            try:
+                m, M = normalize
+                clip = True
+            except:
+                m, M = img.min(), img.max()
+                clip = False
+            if m == M:
+                return res
+            f = 255.0 / (M - m)
+            img = f * (img - m)
+            if clip:
+                img = numpy.minimum(255.0, numpy.maximum(0.0, img))
+        res[...,0] = img
+        res[...,1] = img
+        res[...,2] = img
+        return res
+
+    ###############################################################
+    #                                                             #
+    #           new functionality enabled by axistags             #
+    #                                                             #
+    ###############################################################    
+    
+    def copyValues(self, other):
+        '''
+        Copy the values of an array to another one. This is similar to::
+        
+            self[...] = other
+            
+        but will first transpose both arrays so that axistags are aligned. If
+        there is no valid alignment, RuntimeError will be raised.
+        '''
+        self._copyValuesImpl(self, other)
+    
+    # IMPORTANT: do not remove or rename this property, it is called from C++
+    @property
+    def channelIndex(self):
+        '''
+        The index of the channel axis according to the axistags.        
+        For example, when axistags are 'x y c', the channel index is 2. 
+        If the axistags contain no channel axis, self.ndim is returned.
+        '''
+        return self.axistags.channelIndex
+    
+    # IMPORTANT: do not remove or rename this property, it is called from C++
+    @property
+    def innerNonchannelIndex(self):
+        '''
+        The index of the innermost non-channel axis according to the axistags.
+        The innermost axis is determined by the AxisInfo sorting rules (see 
+        the :ref:`order definitions <array-order-parameter>` for details).
+        For example, when axistags are 'x y c', the innerNonchannelIndex is 0.
+        '''
+        return self.axistags.innerNonchannelIndex
+    
+    @property
+    def channels(self):
+        '''
+        The number of channels in this array (shape of the 'c' axis).
+        If the axistags contain no channel axis, the number of channels is implicitly 1.
+        '''
+        i = self.channelIndex
+        if i < self.ndim:
+            return self.shape[i]
+        else:
+            return 1
+            
+    @property
+    def width(self):
+        '''
+        The width of the array (shape of the 'x' axis).
+        If the axistags contain no 'x' axis, RuntimeError will be raised.
+        '''
+        i = self.axistags.index('x')
+        if i < self.ndim:
+            return self.shape[i]
+        else:
+            raise RuntimeError("VigraArray.width(): axistag 'x' does not exist.")
+    
+    @property
+    def height(self):
+        '''
+        The height of the array (shape of the 'y' axis).
+        If the axistags contain no 'y' axis, RuntimeError will be raised.
+        '''
+        i = self.axistags.index('y')
+        if i < self.ndim:
+            return self.shape[i]
+        else:
+            raise RuntimeError("VigraArray.height(): axistag 'y' does not exist.")
+    
+    @property
+    def depth(self):
+        '''
+        The depth of the array (shape of the 'z' axis).
+        If the axistags contain no 'z' axis, RuntimeError will be raised.
+        '''
+        i = self.axistags.index('z')
+        if i < self.ndim:
+            return self.shape[i]
+        else:
+            raise RuntimeError("VigraArray.depth(): axistag 'z' does not exist.")
+    
+    @property
+    def duration(self):
+        '''
+        The number of time steps in the array (shape of the 't' axis).
+        If the axistags contain no 't' axis, RuntimeError will be raised.
+        '''
+        i = self.axistags.index('t')
+        if i < self.ndim:
+            return self.shape[i]
+        else:
+            raise RuntimeError("VigraArray.duration(): axistag 't' does not exist.")
+            
+    @property
+    def spatialDimensions(self):
+        '''
+        The number of spatial axes in the array.
+        That is, the number of entries in the axistags where the flag 'AxisType.Space'
+        is set.
+        '''
+        return self.axistags.axisTypeCount(AxisType.Space)
+            
+    def iterImpl(self, type):
+        axes = [k for k in xrange(self.ndim) if self.axistags[k].isType(type)]
+        if axes:
+            axes.sort(key=lambda x: self.axistags[x], reverse=True)
+            slices = [slice(None)]*self.ndim
+            for point in numpy.ndindex(*(self.shape[k] for k in axes)):
+                for j in xrange(len(point)):
+                    slices[axes[j]] = point[j]
+                yield self[tuple(slices)]
+        else:
+            yield self
+            
+    def channelIter(self):
+        '''
+        Create an iterator over the channels of the array.
+        In each iteration, you get the array corresponding to a single channel.
+        If the axistags contain no channel axis, there is only one iteration
+        which yields the entire array. Example::
+        
+            >>> rgb = vigra.RGBImage((200, 100))
+            >>> rgb.axistags
+            x y c
+            >>> red, green, blue = rgb.channelIter()
+            >>> red.axistags
+            x y
+            >>> red.shape
+            (200, 100)
+        '''
+        return self.iterImpl(AxisType.Channels)
+            
+    def spaceIter(self):
+        '''
+        Create an iterator over all the spatial coordinates in the array.
+        In each iteration, you get the value corresponding to a single 
+        coordinate location. If the axistags contain no spatial axes, 
+        there is only one iteration which yields the entire array. Example::
+        
+            >>> s = vigra.ScalarImage((2,2))
+            >>> s.ravel()[...] = range(4)
+            >>> for p in s.spaceIter():
+            ....    print p
+            0.0
+            1.0
+            2.0
+            3.0
+        '''
+        return self.iterImpl(AxisType.Space)
+        
+    def timeIter(self):
+        '''
+        Create an iterator over the time points of the array.
+        In each iteration, you get the array corresponding to a single time point.
+        If the axistags contain no time axis, there is only one iteration
+        which yields the entire array. Example::
+        
+            >>> from vigra import *
+            >>> axistags = AxisTags(AxisInfo.t, AxisInfo.x, AxisInfo.y)
+            >>> timesteps, width, height = 2, 200, 100
+            >>> image_sequence = Image((timesteps, width, height), axistags=axistags)
+            >>> step1, step2 = image_sequence.timeIter()
+        '''
+        return self.iterImpl(AxisType.Time)
+        
+    def sliceIter(self, key='z'):
+        '''
+        Create an iterator over a single spatial axis of the array.
+        In each iteration, you get the array corresponding to one coordinate
+        along the axis given by 'key'. For example, to iterate along the z-axis
+        to get all x-y-slices in turn, you write::
+        
+            >>> volume = vigra.Volume((width, height, depth))
+            >>> for slice in volume.sliceIter('z'):
+            ...     processSlice(slice)
+        '''
+        i = self.axistags.index(key)
+        if i < self.ndim:
+            if not self.axistags[i].isSpatial():
+                raise RuntimeError("VigraArray.sliceIter(): %s is not a spatial axis." % key)
+            for k in xrange(self.shape[i]):
+                yield self.bindAxis(i, k)
+        else:
+            yield self
+    
+    def bindAxis(self, which, index=0):
+        '''
+        Bind the axis identified by 'which' to the given 'index'.
+        This is similar to::
+        
+            array[:, index, ...]
+            
+        but you do not need to know the position of the axis when you use the 
+        axis key (according to axistags). For example, to get the green channel
+        of an RGBImage, you write::
+        
+            >>> rgb = vigra.RGBImage((200, 100))
+            >>> green = rgb.bindAxis('c', 1)
+            
+        This gives the correct result irrespective of the axis ordering.
+        '''
+        if type(which) == str:
+            which = self.axistags.index(which)
+        return self[(slice(None),)*which + (index,) + (slice(None),)*(self.ndim-which-1)]
+    
+    def dropChannelAxis(self, ignoreMultiChannel=False):
+        '''
+        Drop the channel axis when it is a singleton.
+        This function is for easy transformation of an array shaped 
+        (width, height, 1) into (width, height). A RuntimeError
+        is raised when there is more than one channel, unless ignoreMultiChannel=True,
+        in which case 'self' is returned.
+        '''
+        ci = self.channelIndex
+        if ci == self.ndim:
+            return self
+        
+        if self.shape[ci] != 1:
+            if ignoreMultiChannel:
+                return self
+            raise RuntimeError("dropChannelAxis(): only allowed when there is a single channel.")
+        return self.bindAxis(ci, 0)
+    
+    def insertChannelAxis(self, order=None):
+        '''
+        Insert a singleton channel axis.
+        This function is for easy transformation of an array shaped 
+        (width, height) into (width, height, 1). The 'order' parameter
+        determines the position of the new axis: when order is 'F', it
+        will become the first axis, otherwise it will become the last
+        one. A RuntimeError is raised when the array already contains a
+        channel axis.
+        '''
+        ci = self.channelIndex
+        if ci != self.ndim:
+            return self
+        
+        if order == 'F':
+            res = self[numpy.newaxis,...]
+            res.axistags[0] = AxisInfo.c
+        else:
+            res = self[..., numpy.newaxis]
+            res.axistags[-1] = AxisInfo.c
+        return res
+    
+    def withAxes(self, *axiskeys):
+        '''
+        Create a view containing the desired axis keys in the given  
+        order. When the array contains an axis not listed, the axis
+        will be dropped if it is a singfleton (otherwise, an exception
+        is raised). If a requested key is not present in this array,
+        a singleton axis will be inserted at that position, if the 
+        missing key is among the known standard keys (otherwise, an 
+        exception is raised). The function fails if this array contains
+        axes of unknown type (key '?'). If 'self' is already suitable, 
+        it is simply retured without generating a new view.
+        
+        Usage::
+        
+            >>> a = vigra.ScalarVolume((200, 100))
+            >>> a.axistags
+            x y
+            >>> a.shape
+            (200, 100)
+            >>> b = a.withAxes('y', 'x', 'c')
+            >>> b.axistags
+            y x c
+            >>> b.shape
+            (100, 200, 1)
+        
+        '''
+        if repr(self.axistags) == ' '.join(axiskeys):
+            return self
+        axisinfo = []
+        slicing = [0]*self.ndim
+        for key in axiskeys:
+            index = self.axistags.index(key)
+            if index < self.ndim:
+                axisinfo.append(self.axistags[index])
+                slicing[index] = slice(None)
+            else:
+                axisinfo.append(eval('AxisInfo.%s' % key))
+                slicing.append(axisinfo[-1])
+        for k in xrange(self.ndim):
+            if self.axistags[k].isType(AxisType.UnknownAxisType):
+                raise RuntimeError("VigraArray.ensureAxes(): array must not contain axes of unknown type (key '?').")
+            if slicing[k] == 0 and self.shape[k] != 1:
+                raise RuntimeError("VigraArray.ensureAxes(): cannot drop non-singleton axis '%s'." % self.axistags[k].key)
+        permutation = AxisTags(axisinfo).permutationFromNumpyOrder()
+        return self[slicing].transposeToNumpyOrder().transpose(permutation)
+    
+    def view5D(self, order='C'):
+        '''
+            Create a 5-dimensional view containing the standard tags 
+            'x', 'y', 'z', 't', 'c' in the desired 'order' (which can be 
+            'C', 'F', and 'V' with the usual meaning). If 'self' has an 
+            axis key that is not among the five admissible keys, an 
+            exception is raised. Axes missing in 'self' are added as 
+            singleton axes with the appropriate tags. 
+        '''
+        stdTags = ['x', 'y', 'z', 't', 'c']
+        for tag in self.axistags:
+            try:
+                del stdTags[stdTags.index(tag.key)]
+            except:
+                raise RuntimeError("VigraArray.view5D(): array contains unsuitable axis key '%s'." % tag.key)
+        index = [Ellipsis] + [newaxis(eval('AxisInfo.' + k)) for k in stdTags]
+        return self[index].transposeToOrder(order)
+    
+    def permutationToOrder(self, order):
+        '''Create the permutation that would transpose this array into
+           an array view with the given order (where order can be 'A',
+           'C', 'F', 'V' with the usual meaning). 
+        '''
+        return list(self.axistags.permutationToOrder(order))
+    
+    def permutationToNormalOrder(self, types=AxisType.AllAxes):
+        '''Create the permutation that would transpose this array to 
+           normal order (that is, from the current axis order into 
+           ascending order, e.g. 'x y c' into 'c x y'). 
+           If 'types' is not 'AxisType.AllAxes', only the axes with the
+           desired types are considered.
+        '''
+        return list(self.axistags.permutationToNormalOrder(types))
+    
+    def permutationFromNormalOrder(self):
+        '''Create the permutation that would transpose an array that is 
+           in normal (ascending) order into the axis order of this array.
+           (e.g. 'c x y' into 'x y c'). 
+        '''
+        return list(self.axistags.permutationFromNormalOrder())
+    
+    def permutationToNumpyOrder(self):
+        '''Create the permutation that would transpose this array to 
+           numpy order (that is, from the current axis order into 
+           descending order, e.g. 'x y c' into 'y x c'). 
+        '''
+        return list(self.axistags.permutationToNumpyOrder())
+    
+    def permutationFromNumpyOrder(self):
+        '''Create the permutation that would transpose an array that is 
+           in numpy (descending) order into the axis order of this array.
+           (e.g.  'y x c' into 'x y c'). 
+        '''
+        return list(self.axistags.permutationFromNumpyOrder())
+    
+    def permutationToVigraOrder(self):
+        '''Create the permutation that would transpose this array to 
+           VIGRA order (that is, from the current axis order into 
+           ascending spatial order, but with the channel axis at the 
+           last position, e.g. 'c x y' into 'x y c'). 
+        '''
+        return list(self.axistags.permutationToVigraOrder())
+    
+    def permutationFromVigraOrder(self):
+        '''Create the permutation that would transpose an array that is 
+           in VIGRA order (ascending spatial order, but with the channel 
+           axis at the last position) into the axis order of this array.
+           (e.g.  'x y c' into 'c x y'). 
+        '''
+        return list(self.axistags.permutationFromVigraOrder())
+    
+    def transposeToOrder(self, order):
+        '''
+        Get a transposed view onto this array according to the given 'order'.
+        Possible orders are:
+        
+        'A':
+            return the array unchanged
+        'C':
+            transpose to descending axis order (e.g. 'z y x c')
+        'F':
+            transpose to ascending axis order (e.g. 'c x y z')
+        'V':
+            transpose to VIGRA order, i.e. ascending spatial axes, but
+            the channel axis is last (e.g. 'x y z c')
+        '''
+        if order == 'A':
+            return self
+        permutation = self.permutationToOrder(order)
+        return self.transpose(permutation)
+    
+    def transposeToDefaultOrder(self):
+        '''Equivalent to self.transposeToOrder(VigraArray.defaultOrder).
+        '''
+        return self.transposeToOrder(VigraArray.defaultOrder)
+
+    def transposeToNormalOrder(self):
+        '''Equivalent to self.transposeToOrder('F').
+        '''
+        return self.transposeToOrder('F')
+
+    def transposeToVigraOrder(self):
+        '''Equivalent to self.transposeToOrder('V').
+        '''
+        return self.transposeToOrder('V')
+
+    def transposeToNumpyOrder(self):
+        '''Equivalent to self.transposeToOrder('C').
+        '''
+        return self.transposeToOrder('C')
+
+    @property
+    def T(self):
+        '''
+        Equivalent to self.transpose()
+        '''
+        return self.transpose()
+
+    def __getitem__(self, index):
+        '''
+        ``array.__getitem__(index)`` implements the indexing operator ``array[index]``.
+        In addition to the usual numpy.ndarray indexing functionality, this function
+        also updates the axistags of the result array. There are three cases:
+
+            * getitem creates a scalar value => no axistags are required
+            * getitem creates an array view => axistags are transferred from the
+              corresponding axes of the base array
+            * getitem creates a copy of an array (fancy indexing) => all axistags are '?'
+         
+        If the index contains 'numpy.newaxis', a new singleton axis is inserted at the 
+        appropriate position, whose axisinfo is set to '?' (unknown). If the index contains
+        'vigra.newaxis(axisinfo)', the singleton axis will get the given axisinfo.
+        '''
+        try:
+            res = numpy.ndarray.__getitem__(self, index)
+        except:
+            res = numpy.ndarray.__getitem__(self, 
+                     map(lambda x: None if isinstance(x, AxisInfo) else x, index))
+        if res is not self and hasattr(res, 'axistags'):
+            if res.base is self or res.base is self.base:
+                res.axistags = res._transform_axistags(index)
+            else:
+                res.axistags = res._empty_axistags(res.ndim)
+        return res
+        
+    def subarray(self, p1, p2=None):
+        '''
+        Construct a subarray view from a pair of points. The first point denotes the start
+        of the subarray (inclusive), the second its end (exclusive). For example,
+        
+            a.subarray((1,2,3), (4,5,6))  # equivalent to a[1:4, 2:5, 3:6]
+        
+        The given points must have the same dimension, otherwise an IndexError is raised. 
+        If only one point is given, it refers to the subarray's end, and the start is set 
+        to the point (0, 0, ...) with appropriate dimension, for example
+        
+            a.subarray((4,5,6))           # equivalent to a[:4, :5, :6]
+        
+        The function transforms the given point pair into a tuple of slices and calls 
+        self.__getitem__() in it. If the points have lower dimension than the array, an 
+        Ellipsis ('...') is implicitly appended to the slicing, so that missing axes 
+        are left unaltered.
+        '''
+        if p2 is not None:
+            if len(p1) != len(p2):
+                raise IndexError('VigraArray.subarray(): points must have the same dimension.')
+            return self.__getitem__(tuple(map(lambda x,y: slice(x.__int__(), y.__int__()), p1, p2)))
+        else:
+            return self.__getitem__(tuple(map(lambda x: slice(x.__int__()), p1)))
+    
+    ###############################################################
+    #                                                             #
+    #      re-implement ndarray methods to handle axistags        #
+    #                                                             #
+    ###############################################################    
+    
+    @_finalize_reduce_result
+    @_preserve_doc
+    def all(self, axis=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        if type(axis) == str:
+            axis = self.axistags.index(axis)
+        return numpy.ndarray.all(self, axis, out)
+
+    @_finalize_reduce_result
+    @_preserve_doc
+    def any(self, axis=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        if type(axis) == str:
+            axis = self.axistags.index(axis)
+        return numpy.ndarray.any(self, axis, out)
+
+    @_finalize_reduce_result
+    @_preserve_doc
+    def argmax(self, axis=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        if type(axis) == str:
+            axis = self.axistags.index(axis)
+        return numpy.ndarray.argmax(self, axis, out)
+        
+    @_finalize_reduce_result
+    @_preserve_doc
+    def argmin(self, axis=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        if type(axis) == str:
+            axis = self.axistags.index(axis)
+        return numpy.ndarray.argmin(self, axis, out)
+    
+    @_preserve_doc
+    def copy(self, order='A'):
+        return self.__class__(self, dtype=self.dtype, order=order)
+    
+    @_preserve_doc
+    def cumprod(self, axis=None, dtype=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        if type(axis) == str:
+            axis = self.axistags.index(axis)
+        res = numpy.ndarray.cumprod(self, axis, dtype, out)
+        if axis is None and out is None:
+            res.axistags = res._empty_axistags(res.ndim)
+        return res
+
+    @_preserve_doc
+    def cumsum(self, axis=None, dtype=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        if type(axis) == str:
+            axis = self.axistags.index(axis)
+        res = numpy.ndarray.cumsum(self, axis, dtype, out)
+        if axis is None and out is None:
+            res.axistags = res._empty_axistags(res.ndim)
+        return res
+
+    @property
+    def flat(self):
+        '''
+        The array is always transposed to 'C' order before flattening.
+        '''
+        return self.transposeToNumpyOrder().view(numpy.ndarray).flat
+    
+    @_preserve_doc
+    def flatten(self, order='C'):
+        '''
+        The array is always transposed to 'C' order before flattening.
+        '''
+        res = self.transposeToNumpyOrder().view(numpy.ndarray).flatten(order)
+        return taggedView(res, self._empty_axistags(1))
+
+    @_finalize_reduce_result
+    @_preserve_doc
+    def max(self, axis=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        return numpy.ndarray.max(self, axis, out)
+
+    @_preserve_doc
+    def mean(self, axis=None, dtype=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        return _numpyarray_overloaded_function(numpy.ndarray.mean, self, axis, dtype, out)
+    
+    @_finalize_reduce_result
+    @_preserve_doc
+    def min(self, axis=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        return numpy.ndarray.min(self, axis, out)
+    
+    @_preserve_doc
+    def nonzero(self):
+        res = numpy.ndarray.nonzero(self)
+        for k in xrange(len(res)):
+            res[k].axistags = AxisTags(AxisInfo(self.axistags[k]))
+        return res
+
+    @property
+    def order(self):
+        if self.flags.c_contiguous:
+            return 'C'
+        elif self.flags.f_contiguous:
+            return 'F'
+        elif self.channelIndex == self.ndim-1 and self.itemsize == self.strides[-1] and \
+             reduce(lambda x, y: y if y >= x and x >= 0 else -1, self.strides[:-1], 0) >= 0:
+            return 'V'
+        return 'A'
+    
+    @_preserve_doc
+    def prod(self, axis=None, dtype=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        return _numpyarray_overloaded_function(numpy.ndarray.prod, self, axis, dtype, out)
+
+    @_preserve_doc
+    def ptp(self, axis=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        if type(axis) == str:
+            axis = self.axistags.index(axis)
+        if axis is None:
+            return self.transposeToOrder('C').view(numpy.ndarray).ptp(out=out)
+        else:
+            res = self.view(numpy.ndarray).ptp(axis, out)
+            if out is None:
+                res = res.view(VigraArray)
+                res.axistags = self._copy_axistags()
+                del res.axistags[axis]
+            return res
+
+    @_preserve_doc
+    def ravel(self, order='C'):
+        '''
+        The array is always transposed to 'C' order before flattening.
+        '''
+        res = self.transposeToNumpyOrder().view(numpy.ndarray).ravel(order)
+        return taggedView(res, self._empty_axistags(1))
+
+    @_preserve_doc
+    def repeat(self, repeats, axis=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        if type(axis) == str:
+            axis = self.axistags.index(axis)
+        if axis is None:
+            return numpy.ndarray.repeat(self.ravel(), repeats)
+        else:
+            return numpy.ndarray.repeat(self, repeats, axis)
+
+    @_preserve_doc
+    def reshape(self, shape, order='C', axistags=None):
+        '''
+        An additional keyword argument 'axistags' can be used to determine
+        the result's axistags. If not given, all axes of the result will 
+        have type 'unknown'.
+        '''
+        if axistags is not None and len(shape) != len(axistags):
+            raise RuntimeError("VigraArray.reshape(): size mismatch between shape and axistags.")
+        res = numpy.ndarray.reshape(self, shape, order=order)
+        if axistags is not None:
+            res.axistags = copy.copy(axistags)
+        else:
+            res.axistags = res._empty_axistags(res.ndim)
+        return res        
+
+    @_preserve_doc
+    def resize(self, new_shape, refcheck=True, order=False, axistags=None):
+        '''
+        An additional keyword argument 'axistags' can be used to determine
+        the self's axistags after the resize. If not given, all axes will have 
+        type 'unknown'.
+        '''
+        # ndarray.resize() internally checks for refcount <= 2
+        # We need to increase the threshold because we have two
+        # additional references ('self' and the argument to 'sys.getrefcount')
+        if sys.getrefcount(self) <= 4:
+            refcheck = False
+        if axistags is not None and len(new_shape) != len(axistags):
+            raise RuntimeError("VigraArray.resize(): size mismatch between shape and axistags.")
+        numpy.ndarray.resize(self, new_shape, refcheck=refcheck)
+        if axistags is not None:
+            self.axistags = copy.copy(axistags)
+        else:
+            self.axistags = self._empty_axistags(self.ndim)
+            
+    @_preserve_doc
+    def squeeze(self):
+        res = numpy.ndarray.squeeze(self)
+        if self.ndim != res.ndim:
+            res.axistags = res._copy_axistags()
+            for k in xrange(self.ndim-1, -1, -1):
+                if self.shape[k] == 1:
+                    del res.axistags[k]
+        return res        
+
+    @_preserve_doc
+    def std(self, axis=None, dtype=None, out=None, ddof=0):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        return _numpyarray_overloaded_function(numpy.ndarray.std, self, axis, dtype, out)
+
+    @_preserve_doc
+    def sum(self, axis=None, dtype=None, out=None):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        return _numpyarray_overloaded_function(numpy.ndarray.sum, self, axis, dtype, out)
+            
+    @_preserve_doc
+    def swapaxes(self, i, j, keepTags=False):
+        '''
+        Parameters 'i' and 'j' can also be ints (axis positions) or strings (axis keys).
+        
+        If 'keepsTags' is False, axistags are swapped like the axes, otherwise they remain
+        unchanged such that the swapped axes aquire a new meaning. 
+        '''
+        if type(i) == str:
+            i = self.axistags.index(i)
+        if type(j) == str:
+            j = self.axistags.index(j)
+        res = numpy.ndarray.swapaxes(self, i, j)
+        res.axistags = res._copy_axistags()
+        if not keepTags:
+            try:
+                res.axistags.swapaxes(i, j)
+            except:
+                res.axistags[i], res.axistags[j] = res.axistags[j], res.axistags[i]
+        return res        
+ 
+    @_preserve_doc
+    def take(self, indices, axis=None, out=None, mode='raise'):
+        '''
+        The array is always transposed to 'C' order before flattening.
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        if type(axis) == str:
+            axis = self.axistags.index(axis)
+        if axis is None:
+            return numpy.ndarray.take(self.ravel(), indices, axis, out, mode)
+        else:
+            return numpy.ndarray.take(self, indices, axis, out, mode)
+           
+    @_preserve_doc
+    def transpose(self, *axes, **keepTags):
+        '''
+        An additional keyword parameter 'keepTags' can be provided (it has to be passed as an explicit
+        keyword parameter). If it is True, the axistags will remain unchanged such that the transposed 
+        axes aquire a new meaning. 
+        '''
+        keepTags = keepTags.get('keepTags', False)
+        res = numpy.ndarray.transpose(self, *axes)
+        if not keepTags:
+            res.axistags = res._transpose_axistags(*axes)
+        return res
+
+    @_preserve_doc
+    def var(self, axis=None, dtype=None, out=None, ddof=0):
+        '''
+        The 'axis' parameter can be an int (axis position) or string (axis key).
+        '''
+        return _numpyarray_overloaded_function(numpy.ndarray.var, self, axis, dtype, out)
+
+    ###############################################################
+    #                                                             #
+    #        reimplement the numerical operators to make          #
+    #             sure that array order is preserved              #
+    #                                                             #
+    ###############################################################    
+    
+    def __abs__(self):
+        return ufunc.absolute(self)
+    
+    def __add__(self, other):
+        return ufunc.add(self, other)
+        
+    def __and__(self, other):
+        return ufunc.bitwise_and(self, other)
+        
+    def __div__(self, other):
+        return ufunc.divide(self, other)
+    
+    def __divmod__(self, other):
+        return ufunc.floor_divide(self, other), ufunc.remainder(self, other)
+    
+    def __eq__(self, other):
+        return ufunc.equal(self, other)
+    
+    def __floordiv__(self, other):
+        return ufunc.floor_divide(self, other)
+    
+    def __ge__(self, other):
+        return ufunc.greater_equal(self, other)
+    
+    def __gt__(self, other):
+        return ufunc.greater(self, other)
+        
+    def __invert__(self):
+        return ufunc.invert(self)
+    
+    def __le__(self, other):
+        return ufunc.less_equal(self, other)
+    
+    def __lshift__(self, other):
+        return ufunc.left_shift(self, other)
+    
+    def __lt__(self, other):
+        return ufunc.less(self, other)
+    
+    def __mod__(self, other):
+        return ufunc.remainder(self, other)
+    
+    def __mul__(self, other):
+        return ufunc.multiply(self, other)
+    
+    def __ne__(self, other):
+        return ufunc.not_equal(self, other)
+    
+    def __neg__(self):
+        return ufunc.negative(self)
+    
+    def __or__(self, other):
+        return ufunc.bitwise_or(self, other)
+    
+    def __pos__(self):
+        return self
+    
+    def __pow__(self, other):
+        return ufunc.power(self, other)
+    
+    def __radd__(self, other):
+        return ufunc.add(other, self)
+    
+    def __radd__(self, other):
+        return ufunc.add(other, self)
+    
+    def __rand__(self, other):
+        return ufunc.bitwise_and(other, self)
+    
+    def __rdiv__(self, other):
+        return ufunc.divide(other, self)
+    
+    def __rdivmod__(self, other):
+        return ufunc.floor_divide(other, self), ufunc.remainder(other, self)
+    
+    def __rfloordiv__(self, other):
+        return ufunc.floor_divide(other, self)
+    
+    def __rlshift__(self, other):
+        return ufunc.left_shoft(other, self)
+    
+    def __rmod__(self, other):
+        return ufunc.remainder(other, self)
+    
+    def __rmul__(self, other):
+        return ufunc.multiply(other, self)
+    
+    def __ror__(self, other):
+        return ufunc.bitwise_or(other, self)
+    
+    def __rpow__(self, other):
+        return ufunc.power(other, self)
+    
+    def __rrshift__(self, other):
+        return ufunc.right_shift(other, self)
+    
+    def __rshift__(self, other):
+        return ufunc.right_shift(self, other)
+
+    def __rsub__(self, other):
+        return ufunc.subtract(other, self)
+    
+    def __rtruediv__(self, other):
+        return ufunc.true_divide(other, self)
+    
+    def __rxor__(self, other):
+        return ufunc.bitwise_xor(other, self)
+    
+    def __sub__(self, other):
+        return ufunc.subtract(self, other)
+    
+    def __truediv__(self, other):
+        return ufunc.true_divide(self, other)
+    
+    def __xor__(self, other):
+        return ufunc.bitwise_xor(self, other)
+
+
+##################################################################
+
+# channelCount == None: array must not have channels
+# channelCount == 0:    array can have arbitrary number of channels (including None)
+def _adjustShape(shape, order, spatialDimensions, channelCount, axistags, name):
+    if order is None:
+        order = VigraArray.defaultOrder
+    if len(shape) == spatialDimensions:
+        if channelCount is not None and channelCount == 0:
+            channelCount = 1
+        if channelCount:
+            if order == 'F':
+                shape = (channelCount,) + shape
+            else:
+                shape = shape + (channelCount,)
+    else:        
+        if channelCount is None or len(shape) != spatialDimensions + 1:
+            raise RuntimeError("%s: input shape has wrong length." % name)
+        if channelCount > 0:
+            if order == 'F':
+                if shape[0] != channelCount:
+                    raise RuntimeError("%s: input shape has wrong number of channels." % name)
+            else:
+                if shape[-1] != channelCount:
+                    raise RuntimeError("%s: input shape has wrong number of channels." % name)
+    if axistags is None:
+        axistags = VigraArray.defaultAxistags(spatialDimensions+1, order)
+    if len(shape) == spatialDimensions:
+        axistags.dropChannelAxis()
+    if len(shape) != len(axistags):
+        raise RuntimeError("%s: size mismatch between shape and axistags." % name)
+    return shape, axistags
+
+def _adjustArray(array, order, spatialDimensions, channelCount, axistags, name):
+    if order is None:
+        order = VigraArray.defaultOrder
+    if array.ndim == spatialDimensions:
+        if channelCount is not None and channelCount > 1:
+            raise RuntimeError("%s: input array has too few dimensions." % name)
+        if hasattr(array, 'axistags'):
+            if array.channelIndex != array.ndim:
+                raise RuntimeError("%s: input array has too few non-channel axes." % name)
+        if channelCount:
+            if hasattr(array, 'axistags'):
+                array = array.insertChannelAxis(order)
+            elif order == 'F':
+                array = array[numpy.newaxis,...]
+            else:
+                array = array[...,numpy.newaxis]
+    else:
+        if channelCount is None or array.ndim != spatialDimensions+1:
+            raise RuntimeError("%s: input array has wrong number of dimensions." % name)
+        if hasattr(array, 'axistags'):
+            channelIndex = array.channelIndex
+            if channelIndex == array.ndim:
+                raise RuntimeError("%s: input array has no channel axis." % name)
+            if channelCount > 0 and array.shape[channelIndex] != channelCount:
+                raise RuntimeError("%s: input array has wrong number of channels." % name)
+    if axistags is None:
+        if hasattr(array, 'axistags'):
+            axistags = copy.copy(array.axistags)
+        else:
+            axistags = VigraArray.defaultAxistags(spatialDimensions+1, order)
+    if array.ndim == spatialDimensions:
+        axistags.dropChannelAxis()
+    if array.ndim != len(axistags):
+        raise RuntimeError("%s: axistags have wrong number of axes." % name)
+    return array, axistags
+
+def _adjustInput(obj, order, spatialDimensions, channelCount, axistags, name):
+    if isinstance(obj, numpy.ndarray):
+        return _adjustArray(obj, order, spatialDimensions, channelCount, axistags, name)
+    else:
+        return _adjustShape(obj, order, spatialDimensions, channelCount, axistags, name)
+
+#################################################################
+
+def Image(obj, dtype=numpy.float32, order=None, 
+          init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing an image (i.e. an array with 
+    two spatial axes 'x' and 'y' and optionally a channel axis 'c'). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are not image-like.
+    '''
+    obj, axistags = _adjustInput(obj, order, 2, 0, axistags, "vigra.Image()")
+    return VigraArray(obj, dtype, None, init, value, axistags)
+        
+def ScalarImage(obj, dtype=numpy.float32, order=None, 
+                init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing a single-band image (i.e. an 
+    array with two spatial axes 'x' and 'y' and no channel axis). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are unsuitable for a single-band image.
+    '''
+    obj, axistags = _adjustInput(obj, order, 2, None, axistags, "vigra.ScalarImage()")
+    return VigraArray(obj, dtype, None, init, value, axistags)
+        
+def Vector2Image(obj, dtype=numpy.float32, order=None, 
+                 init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing a 2-band image (i.e. an 
+    array with two spatial axes 'x' and 'y' and channel axis 'c' with 2 channels). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are unsuitable for a 2-band image.
+    '''
+    obj, axistags = _adjustInput(obj, order, 2, 2, axistags, "vigra.Vector2Image()")
+    return VigraArray(obj, dtype, None, init, value, axistags)
+
+def Vector3Image(obj, dtype=numpy.float32, order=None, 
+                 init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing a 3-band image (i.e. an 
+    array with two spatial axes 'x' and 'y' and channel axis 'c' with 3 channels). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are unsuitable for a 3-band image.
+    '''
+    obj, axistags = _adjustInput(obj, order, 2, 3, axistags, "vigra.Vector3Image()")
+    return VigraArray(obj, dtype, None, init, value, axistags)
+
+def Vector4Image(obj, dtype=numpy.float32, order=None, 
+                 init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing a 4-band image (i.e. an 
+    array with two spatial axes 'x' and 'y' and channel axis 'c' with 4 channels). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are unsuitable for a 4-band image.
+    '''
+    obj, axistags = _adjustInput(obj, order, 2, 4, axistags, "vigra.Vector4Image()")
+    return VigraArray(obj, dtype, None, init, value, axistags)
+
+def RGBImage(obj, dtype=numpy.float32, order=None, 
+             init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing a RGB image (i.e. an 
+    array with two spatial axes 'x' and 'y' and channel axis 'c' with 3 channels). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are unsuitable for an RGB image.
+    '''
+    obj, axistags = _adjustInput(obj, order, 2, 3, axistags, "vigra.RGBImage()")
+    res = VigraArray(obj, dtype, None, init, value, axistags)
+    res.axistags['c'].description = 'RGB'
+    return res
+
+#################################################################
+
+def Volume(obj, dtype=numpy.float32, order=None, 
+           init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing a volume (i.e. an array with 
+    three spatial axes 'x', 'y' and 'z' and optionally a channel axis 'c'). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are not volume-like.
+    '''
+    obj, axistags = _adjustInput(obj, order, 3, 0, axistags, "vigra.Volume()")
+    return VigraArray(obj, dtype, None, init, value, axistags)
+
+def ScalarVolume(obj, dtype=numpy.float32, order=None, 
+                 init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing a single-band volume (i.e. an 
+    array with three spatial axes 'x', 'y' and 'z' and no channel axis). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are unsuitable for a single-band volume.
+    '''
+    obj, axistags = _adjustInput(obj, order, 3, None, axistags, "vigra.ScalarVolume()")
+    return VigraArray(obj, dtype, None, init, value, axistags)
+
+def Vector2Volume(obj, dtype=numpy.float32, order=None, 
+                  init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing a 2-band volume (i.e. an 
+    array with three spatial axes 'x', 'y' and 'z' and channel axis 'c' with 2 channels). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are unsuitable for a 2-band volume.
+    '''
+    obj, axistags = _adjustInput(obj, order, 3, 2, axistags, "vigra.Vector2Volume()")
+    return VigraArray(obj, dtype, None, init, value, axistags)
+
+def Vector3Volume(obj, dtype=numpy.float32, order=None, 
+                  init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing a 3-band volume (i.e. an 
+    array with three spatial axes 'x', 'y' and 'z' and channel axis 'c' with 3 channels). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are unsuitable for a 3-band volume.
+    '''
+    obj, axistags = _adjustInput(obj, order, 3, 3, axistags, "vigra.Vector3Volume()")
+    return VigraArray(obj, dtype, None, init, value, axistags)
+
+def Vector4Volume(obj, dtype=numpy.float32, order=None, 
+                  init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing a 4-band volume (i.e. an 
+    array with three spatial axes 'x', 'y' and 'z' and channel axis 'c' with 4 channels). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are unsuitable for a 4-band volume.
+    '''
+    obj, axistags = _adjustInput(obj, order, 3, 4, axistags, "vigra.Vector4Volume()")
+    return VigraArray(obj, dtype, None, init, value, axistags)
+
+def Vector6Volume(obj, dtype=numpy.float32, order=None, 
+                  init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing a 6-band volume (i.e. an 
+    array with three spatial axes 'x', 'y' and 'z' and channel axis 'c' with 6 channels). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are unsuitable for a 6-band volume.
+    '''
+    obj, axistags = _adjustInput(obj, order, 3, 6, axistags, "vigra.Vector6Volume()")
+    return VigraArray(obj, dtype, None, init, value, axistags)
+
+def RGBVolume(obj, dtype=numpy.float32, order=None, 
+              init=True, value=None, axistags=None):
+    '''
+    Factory function for a :class:`~vigra.VigraArray` representing an RGB volume (i.e. an 
+    array with three spatial axes 'x', 'y' and 'z' and channel axis 'c' with 3 channels). 
+    Paramters are interpreted as in the VigraArray constructor, but an exception
+    will be raised if the shape or axistags are unsuitable for an RGB volume.
+    '''
+    obj, axistags = _adjustInput(obj, order, 3, 3, axistags, "vigra.RGBVolume()")
+    res = VigraArray(obj, dtype, None, init, value, axistags)
+    res.axistags['c'].description = 'RGB'
+    return res
+
+#################################################################
+
+class ImagePyramid(list):
+    def __init__(self, image, copyImageToLevel = 0, lowestLevel = 0, highestLevel = 0):
+        ''' Create a new pyramid.
+            The new pyramid levels range from 'lowestLevel' to 'highestLevel' (inclusive),
+            and the given 'image' is copied to 'copyImageToLevel'. The images at other
+            levels are filled with zeros and sized so that the shape is reduced by half
+            when going up (to higher levels), and doubled when going down.
+            
+            This class can handle multi-channel images, but only when image.channelIndex
+            exists and returns image.ndim-1 (i.e. the image must have axistags, and the 
+            channel axis must correspond to the last index, as in C- or V-order).
+        '''
+        if lowestLevel > copyImageToLevel or highestLevel < copyImageToLevel:
+            raise ValueError('ImagePyramid(): copyImageToLevel must be between lowestLevel and highestLevel (inclusive)')
+        
+        list.__init__(self, [image.__class__(image, dtype=image.dtype)])
+        self._lowestLevel = copyImageToLevel
+        self._highestLevel = copyImageToLevel
+        self.createLevel(lowestLevel)
+        self.createLevel(highestLevel)
+
+    @property
+    def lowestLevel(self):
+        '''The pyramids lowest level.
+        '''
+        return self._lowestLevel
+    
+    @property
+    def highestLevel(self):
+        '''The pyramids highest level (inclusive).
+        '''
+        return self._highestLevel
+    
+    def __getitem__(self, level):
+        '''Get the image at 'level'.
+           Raises IndexError when the level does not exist.
+        '''
+        if level < self.lowestLevel or level > self.highestLevel:
+            raise IndexError("ImagePyramid[level]: level out of range.")
+        return list.__getitem__(self, level - self.lowestLevel)
+    
+    def __setitem__(self, level, image):
+        '''Copy the data of the given 'image' to the image at 'level'.
+           Raises IndexError when the level does not exist.
+        '''
+        self[level][...] = image[...]
+        
+    def expandImpl(self, src, dest, centerValue):
+        import filters
+        
+        ss, ds = src.shape, dest.shape
+        s = [ss[k] if 2*ss[k] == ds[k] else -1 for k in range(len(ss))]
+    
+        smooth1 = filters.explictKernel(-1, 1, numpy.array([0.5 - centerValue, 2.0*centerValue, 0.5 - centerValue]))
+        smooth2 = filters.explictKernel(-1, 0, numpy.array([0.5, 0.5]));
+
+        filters.convolve(src, (smooth1, smooth1), out=dest[::2,::2])
+        filters.convolve(src[:,:s[1]], (smooth1, smooth2), out=dest[::2,1::2])
+        filters.convolve(src[:s[0],:], (smooth2, smooth1), out=dest[1::2,::2])
+        filters.convolve(src[:s[0],:s[1]], (smooth2, smooth2), out=dest[1::2,1::2])
+    
+    def reduce(self, srcLevel, destLevel, centerValue = 0.42):
+        '''Reduce the image at 'srcLevel' to 'destLevel', using the Burt smoothing filter
+           with the given 'centerValue'. srcLevel must be smaller than destLevel.
+           
+           For more details, see pyramidReduceBurtFilter_ in the C++ documentation.
+        '''
+        # FIXME: This should be implemented in C++
+        # FIXME: This should be implemented for arbitrary dimensions
+        import filters
+        
+        if srcLevel > destLevel:
+            raise RuntimeError("ImagePyramid::reduce(): srcLevel <= destLevel required.")
+        if srcLevel < self.lowestLevel or srcLevel > self.highestLevel:
+            raise RuntimeError("ImagePyramid::reduce(): srcLevel does not exist.")
+        self.createLevel(destLevel)
+        
+        smooth = filters.burtFilterKernel(0.25 - 0.5*centerValue)
+        for k in range(srcLevel, destLevel):
+            i = filters.convolve(self[k], smooth)
+            self[k+1] = i[::2,::2]
+
+    def expand(self, srcLevel, destLevel, centerValue = 0.42):
+        '''Expand the image at 'srcLevel' to 'destLevel', using the Burt smoothing filter
+           with the given 'centerValue'. srcLevel must be larger than destLevel.
+           
+           For more details, see pyramidExpandBurtFilter_ in the C++ documentation.
+        '''
+        # FIXME: This should be implemented in C++
+        # FIXME: This should be implemented for arbitrary dimensions
+        if srcLevel < destLevel:
+            raise RuntimeError("ImagePyramid::expand(): srcLevel >= destLevel required.")
+        if srcLevel < self.lowestLevel or srcLevel > self.highestLevel:
+            raise RuntimeError("ImagePyramid::expand(): srcLevel does not exist.")
+        self.createLevel(destLevel)
+
+        for k in range(srcLevel, destLevel, -1):
+            self.expandImpl(self[k], self[k-1], centerValue)
+
+    def reduceLaplacian(self, srcLevel, destLevel, centerValue = 0.42):
+        '''Reduce the image at 'srcLevel' to 'destLevel', using the Burt smoothing filter
+           with the given 'centerValue', and compute Laplacian images for the levels
+           srcLevel ... destLevel-1. srcLevel must be smaller than destLevel.
+           
+           For more details, see pyramidReduceBurtLaplacian_ in the C++ documentation.
+        '''
+        # FIXME: This should be implemented in C++
+        # FIXME: This should be implemented for arbitrary dimensions
+        import filters
+        
+        if srcLevel > destLevel:
+            raise RuntimeError("ImagePyramid::reduceLaplacian(): srcLevel <= destLevel required.")
+        if srcLevel < self.lowestLevel or srcLevel > self.highestLevel:
+            raise RuntimeError("ImagePyramid::reduceLaplacian(): srcLevel does not exist.")
+        self.createLevel(destLevel)
+
+        smooth = filters.burtFilterKernel(0.25 - 0.5*centerValue)
+        for k in range(srcLevel, destLevel):
+            i = filters.convolve(self[k], smooth)
+            self[k+1] = i[::2,::2]
+            self.expandImpl(self[k+1], i, centerValue)
+            self[k] = i - self[k]
+
+    def expandLaplacian(self, srcLevel, destLevel, centerValue = 0.42):
+        '''Expand the image at 'srcLevel' to 'destLevel', using the Burt smoothing filter
+           with the given 'centerValue', and reconstruct the images for the levels
+           srcLevel-1 ... destLevel from their Laplacian images. srcLevel must be larger than destLevel.
+           
+           For more details, see pyramidExpandBurtLaplacian_ in the C++ documentation.
+        '''
+        # FIXME: This should be implemented in C++
+        # FIXME: This should be implemented for arbitrary dimensions
+        import filters
+        
+        if srcLevel < destLevel:
+            raise RuntimeError("ImagePyramid::expandLaplacian(): srcLevel >= destLevel required.")
+        if srcLevel < self.lowestLevel or srcLevel > self.highestLevel:
+            raise RuntimeError("ImagePyramid::expandLaplacian(): srcLevel does not exist.")
+        self.createLevel(destLevel)
+
+        smooth1 = filters.explictKernel(-1, 1, numpy.array([0.5 - centerValue, 2.0*centerValue, 0.5 - centerValue]))
+        smooth2 = filters.explictKernel(-1, 0, numpy.array([0.5, 0.5]));
+        for k in range(srcLevel, destLevel, -1):
+            i = self[k-1].__class__(self[k-1].shape, dtype = self[k-1].dtype)
+            self.expandImpl(self[k], i, centerValue)
+            self[k-1] = i - self[k-1]
+
+    def createLevel(self, level):
+        ''' Make sure that 'level' exists. If 'level' is outside the current range of levels,
+            empty images of the appropriate shape are inserted into the pyramid.
+        '''
+        if level > self.highestLevel:
+            for i in range(self.highestLevel, level):
+                image = list.__getitem__(self, -1)
+                newShape = [int((k + 1) / 2) for k in image.shape]
+                channelIndex = getattr(image, 'channelIndex', image.ndim)
+                if channelIndex < image.ndim:
+                    newShape[channelIndex] = image.shape[channelIndex]
+                self.append(image.__class__(newShape, dtype=image.dtype))
+            self._highestLevel = level
+        elif level < self.lowestLevel:
+            image = list.__getitem__(self, 0)
+            for i in range(self.lowestLevel, level, -1):
+                newShape = [2*k-1 for k in image.shape]
+                channelIndex = getattr(image, 'channelIndex', image.ndim)
+                if channelIndex < image.ndim:
+                    newShape[channelIndex] = image.shape[channelIndex]
+                self.insert(0, image.__class__(newShape, dtype=image.dtype))
+            self._lowestLevel = level
+             
diff --git a/vigranumpy/lib/axistags.py b/vigranumpy/lib/axistags.py
new file mode 100644
index 0000000..54131e0
--- /dev/null
+++ b/vigranumpy/lib/axistags.py
@@ -0,0 +1,250 @@
+import numpy as np
+
+class TaggedArray(np.ndarray):
+
+    def __new__(subtype, shape, dtype=float, buffer=None, offset=0,
+          strides=None, order=None, axistags=None):
+        obj = np.ndarray.__new__(subtype, shape, dtype, buffer, offset, strides, order)
+        if axistags is None:
+            defaulttags = [['x'], ['y','x'], ['z','y','x'], ['z','y','x', 'c']]
+            obj.axistags = defaulttags[len(shape)-1]
+        else:
+            obj.axistags = list(axistags)
+        return obj
+
+    def __array_finalize__(self, obj):
+        if hasattr(obj, 'axistags'):
+            self.axistags = list(obj.axistags)
+
+    def all(self, axis=None, out=None):
+        res = np.ndarray.all(self, axis, out)
+        if axis is not None:
+            del res.axistags[axis]
+        return res
+
+    def any(self, axis=None, out=None):
+        res = np.ndarray.any(self, axis, out)
+        if axis is not None:
+            del res.axistags[axis]
+        return res
+
+    def argmax(self, axis=None, out=None):
+        res = np.ndarray.argmax(self, axis, out)
+        if axis is not None:
+            del res.axistags[axis]
+        return res
+        
+    def argmin(self, axis=None, out=None):
+        res = np.ndarray.argmin(self, axis, out)
+        if axis is not None:
+            del res.axistags[axis]
+        return res
+    
+    def cumsum(self, axis=None, dtype=None, out=None):
+        res = np.ndarray.cumsum(self, axis, dtype, out)
+        if res.ndim != self.ndim:
+            res.axistags = [None]*res.ndim
+        return res        
+
+    def cumprod(self, axis=None, dtype=None, out=None):
+        res = np.ndarray.cumprod(self, axis, dtype, out)
+        if res.ndim != self.ndim:
+            res.axistags = [None]*res.ndim
+        return res        
+
+    def flatten(self, order='C'):
+        res = np.ndarray.flatten(self, order)
+        res.axistags = [None]
+        return res        
+
+    def max(self, axis=None, out=None):
+        res = np.ndarray.max(self, axis, out)
+        if axis is not None:
+            del res.axistags[axis]
+        return res
+
+    def mean(self, axis=None, out=None):
+        res = np.ndarray.mean(self, axis, out)
+        if axis is not None:
+            del res.axistags[axis]
+        return res
+    
+    def min(self, axis=None, out=None):
+        res = np.ndarray.min(self, axis, out)
+        if axis is not None:
+            del res.axistags[axis]
+        return res
+    
+    def nonzero(self):
+        res = np.ndarray.nonzero(self)
+        for k in xrange(len(res)):
+            res[k].axistags = [self.axistags[k]]
+        return res
+
+    def prod(self, axis=None, dtype=None, out=None):
+        res = np.ndarray.prod(self, axis, dtype, out)
+        if axis is not None:
+            del res.axistags[axis]
+        return res
+
+    def ptp(self, axis=None, out=None):
+        res = np.ndarray.ptp(self, axis, out)
+        if axis is not None:
+            del res.axistags[axis]
+        return res
+
+    def ravel(self, order='C'):
+        res = np.ndarray.ravel(self, order)
+        res.axistags = [None]
+        return res        
+
+    def repeat(self, repeats, axis=None):
+        res = np.ndarray.repeat(self, repeats, axis)
+        if axis is None:
+            res.axistags = [None]*res.ndim
+        return res        
+
+    def reshape(self, shape, order='C'):
+        res = np.ndarray.reshape(self, shape, order)
+        res.axistags = [None]*res.ndim
+        return res        
+
+    def resize(self, new_shape, refcheck=True, order=False):
+        res = np.ndarray.reshape(self, new_shape, refcheck, order)
+        res.axistags = [None]*res.ndim
+        return res        
+            
+    def squeeze(self):
+        res = np.ndarray.squeeze(self)
+        for k in xrange(self.ndim-1, -1, -1):
+            if self.shape[k] == 1:
+                del res.axistags[k]
+        return res        
+
+    def std(self, axis=None, dtype=None, out=None, ddof=0):
+        res = np.ndarray.std(self, axis, dtype, out, ddof)
+        if axis is not None:
+            del res.axistags[axis]
+        if len(res.shape) == 0:
+            res = res.item()
+        return res
+
+    def sum(self, axis=None, dtype=None, out=None):
+        res = np.ndarray.sum(self, axis, dtype, out)
+        if axis is not None:
+            del res.axistags[axis]
+        return res
+            
+    def swapaxes(self, i, j):
+        res = np.ndarray.swapaxes(self, i, j)
+        res.axistags[i] = self.axistags[j]
+        res.axistags[j] = self.axistags[i]
+        return res        
+ 
+    def take(self, indices, axis=None, out=None, mode='raise'):
+        res = np.ndarray.take(self, indices, axis, out, mode)
+        if axis is None:
+            res.axistags = [None]*res.ndim
+        return res        
+           
+    def transpose(self, *axes):
+        res = np.ndarray.transpose(self, *axes)
+        if len(axes) == 1:
+            axes = axes[0]
+        if not axes:
+            res.axistags.reverse()
+        else:
+            res.axistags = [self.axistags[k] for k in axes]
+        return res
+
+    def var(self, axis=None, dtype=None, out=None, ddof=0):
+        res = np.ndarray.var(self, axis, dtype, out, ddof)
+        if axis is not None:
+            del res.axistags[axis]
+        if len(res.shape) == 0:
+            res = res.item()
+        return res
+    
+    @property
+    def T(self):
+        return self.transpose()
+
+    def __getitem__(self, index):
+        '''x.__getitem__(y) <==> x[y]
+         
+           In addition to the usual indexing functionality, this function
+           also updates the axistags of the result array. There are three cases:
+             * getitem creates a value => no axistags are required
+             * getitem creates an arrayview => axistags are transferred from the
+                                             corresponding axes of the base array,
+                                             axes resulting from 'newaxis' get tag 'None'
+             * getitem creates a copy of an array (fancy indexing) => all axistags are 'None'
+        '''
+        res = np.ndarray.__getitem__(self, index)
+        if hasattr(res, 'axistags'):
+            # indexing created an array => set default (uninformative) axistags
+            lnew = res.ndim
+            if res is not self:
+                res.axistags = [None]*lnew
+            if res.base is self:
+                # indexing created an array view => transfer the axistags
+                try:
+                    # make sure that 'index' is a tuple
+                    lindex = len(index)
+                except:
+                    index = (index,)
+                    lindex = 1
+                lindex -= index.count(np.newaxis)
+                if lindex < self.ndim and index.count(Ellipsis) == 0:
+                    index += (Ellipsis,)
+                    lindex += 1
+                
+                # how many missing axes are represented by an Ellipsis ?
+                lellipsis = self.ndim - lindex
+                
+                knew, kold, kindex = 0, 0, 0
+                while knew < lnew:
+                    try:
+                        # if index[kindex] is int, the dimension is bound => drop this axis
+                        int(index[kindex]) 
+                        kold += 1
+                        kindex += 1
+                    except:
+                        if index[kindex] is np.newaxis:
+                            # tag of newaxis is unknown
+                            res.axistags[knew] = None
+                        else:
+                            # tag of existing axis is copied
+                            res.axistags[knew] = self.axistags[kold]
+                            kold += 1
+                        knew += 1
+                        # the first ellipsis represents all missing axes
+                        if lellipsis > 0 and index[kindex] is Ellipsis:
+                            lellipsis -= 1
+                        else:
+                            kindex += 1
+        return res
+    
+    for k in ['all', 'any', 'argmax', 'argmin', 'cumsum', 'cumprod', 'flatten', 
+               'max', 'mean', 'min', 'nonzero', 'prod', 'ptp', 'ravel', 'repeat', 
+               'reshape', 'resize', 'squeeze', 'std', 'sum', 'swapaxes', 'take', 
+               'transpose', 'var']:
+        exec k + '.__doc__ = np.ndarray.' + k + '.__doc__'
+
+        
+def benchmark(expression):
+    '''transfer of axistags causes a slowdown by a factor of about 10,
+       when getitem returns a value, the slowdown is about 3 (due to Python calls)
+    '''
+    import timeit, axistags
+    reload(axistags)
+    repetitions = 100000
+    t1 = timeit.Timer(expression, 
+         "import numpy, axistags\na = axistags.TaggedArray((2,3,4), axistags='zyx', dtype=numpy.uint8)")
+    t2 = timeit.Timer(expression, 
+         "import numpy, axistags\na = numpy.ndarray((2,3,4), dtype=numpy.uint8)")
+    t3 = timeit.Timer(expression, 
+         "import numpy, axistags\na = axistags.TaggedArray((2,3,4), axistags='zyx', dtype=numpy.uint8).view(numpy.ndarray)")
+    print "TaggedArray:", t1.timeit(repetitions)/repetitions*1e6,"musec"
+    print "ndarray:", t2.timeit(repetitions)/repetitions*1e6,"musec"
+    print "TaggedArray as ndarray:", t3.timeit(repetitions)/repetitions*1e6,"musec"
diff --git a/vigranumpy/lib/pyqt/CMakeLists.txt b/vigranumpy/lib/pyqt/CMakeLists.txt
new file mode 100644
index 0000000..a0a0a48
--- /dev/null
+++ b/vigranumpy/lib/pyqt/CMakeLists.txt
@@ -0,0 +1,9 @@
+SET(PYSOURCES
+    __init__.py
+    imagewindow.py
+    quickdialog.py
+    overlays.py
+    viewer2svg.py
+    )
+
+INSTALL(FILES ${PYSOURCES} DESTINATION ${VIGRANUMPY_INSTALL_DIR}/vigra/pyqt)
diff --git a/vigranumpy/lib/pyqt/__init__.py b/vigranumpy/lib/pyqt/__init__.py
new file mode 100644
index 0000000..55e3de8
--- /dev/null
+++ b/vigranumpy/lib/pyqt/__init__.py
@@ -0,0 +1,41 @@
+#######################################################################
+#                                                                      
+#         Copyright 2009-2010 by Ullrich Koethe                        
+#                                                                      
+#    This file is part of the VIGRA computer vision library.           
+#    The VIGRA Website is                                              
+#        http://hci.iwr.uni-heidelberg.de/vigra/                       
+#    Please direct questions, bug reports, and contributions to        
+#        ullrich.koethe at iwr.uni-heidelberg.de    or                    
+#        vigra at informatik.uni-hamburg.de                               
+#                                                                      
+#    Permission is hereby granted, free of charge, to any person       
+#    obtaining a copy of this software and associated documentation    
+#    files (the "Software"), to deal in the Software without           
+#    restriction, including without limitation the rights to use,      
+#    copy, modify, merge, publish, distribute, sublicense, and/or      
+#    sell copies of the Software, and to permit persons to whom the    
+#    Software is furnished to do so, subject to the following          
+#    conditions:                                                       
+#                                                                      
+#    The above copyright notice and this permission notice shall be    
+#    included in all copies or substantial portions of the             
+#    Software.                                                         
+#                                                                      
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     
+#    OTHER DEALINGS IN THE SOFTWARE.                                   
+#                                                                      
+#######################################################################
+
+import quickdialog
+import imagewindow
+import overlays
+import viewer2svg
+
+from imagewindow import *
diff --git a/vigranumpy/lib/pyqt/imagewindow.py b/vigranumpy/lib/pyqt/imagewindow.py
new file mode 100644
index 0000000..27220ac
--- /dev/null
+++ b/vigranumpy/lib/pyqt/imagewindow.py
@@ -0,0 +1,617 @@
+#######################################################################
+#
+#         Copyright 2009-2010 by Ullrich Koethe
+#
+#    This file is part of the VIGRA computer vision library.
+#    The VIGRA Website is
+#        http://hci.iwr.uni-heidelberg.de/vigra/
+#    Please direct questions, bug reports, and contributions to
+#        ullrich.koethe at iwr.uni-heidelberg.de    or
+#        vigra at informatik.uni-hamburg.de
+#
+#    Permission is hereby granted, free of charge, to any person
+#    obtaining a copy of this software and associated documentation
+#    files (the "Software"), to deal in the Software without
+#    restriction, including without limitation the rights to use,
+#    copy, modify, merge, publish, distribute, sublicense, and/or
+#    sell copies of the Software, and to permit persons to whom the
+#    Software is furnished to do so, subject to the following
+#    conditions:
+#
+#    The above copyright notice and this permission notice shall be
+#    included in all copies or substantial portions of the
+#    Software.
+#
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+#    OTHER DEALINGS IN THE SOFTWARE.
+#
+#######################################################################
+
+import math, os, numpy, PyQt4
+
+import PyQt4.QtCore as qcore
+import PyQt4.QtGui  as qt
+from PyQt4.QtCore import SIGNAL
+
+import vigra
+import vigra.ufunc
+
+try:
+    from VigraQt import OverlayViewer, ImageCursor
+except Exception, e:
+    vigra._fallbackModule('VigraQt',
+    '''
+    %s
+
+    If VigraQt is missing on your system, you can download it from
+    http://kogs-www.informatik.uni-hamburg.de/~meine/software/vigraqt/.''' % str(e))
+    from VigraQt import OverlayViewer, ImageCursor
+
+import quickdialog
+import weakref
+import viewer2svg
+
+class Crosshair(ImageCursor):
+    def __init__(self, *args):
+        ImageCursor.__init__(self, *args)
+        self.visible = False
+        self.position = qcore.QPoint(-1, -1)
+    def setVisible(self, what=True):
+        self.visible = what
+        if what:
+            ImageCursor.setPosition(self, self.position)
+        else:
+            ImageCursor.setPosition(self, qcore.QPoint(-1, -1))
+    def setPosition(self, pos):
+        self.position = pos
+        if self.visible:
+            ImageCursor.setPosition(self, self.position)
+
+class ImageViewer(OverlayViewer):
+
+    activeViewers = weakref.WeakValueDictionary()
+
+    def __init__(self, image, normalize=True, title=None, parent=None):
+        OverlayViewer.__init__(self, parent)
+        self.setImage(image, normalize)
+        self._savedExpression = "x"
+        self._lastSaveType = 2
+        self.overlays = []
+
+        if title is not None:
+            self.setWindowTitle(title)
+        elif hasattr(image, "name"):
+            self.setWindowTitle(image.name)
+        else:
+            for k in xrange(1, 10000):
+                if not ImageViewer.activeViewers.has_key(k):
+                    break
+            ImageViewer.activeViewers[k] = self
+            self.setWindowTitle("Image %d" % k)
+
+        #self.imageCursor = ImageCursor(self) # doesn't work anymore - setVisible() is gone
+        self.imageCursor = Crosshair(self)
+        self.imageCursor.setVisible(False)
+        self.imageCursor.setPosition(qcore.QPoint(self.image.width // 2, self.image.height // 2))
+        OverlayViewer.addOverlay(self, self.imageCursor)
+
+        self.zoomInAction = qt.QAction("Zoom in", self)
+        self.zoomInAction.setShortcut("+")
+        self.connect(self.zoomInAction, SIGNAL("triggered()"), self.zoomInPopup)
+
+        self.zoomOutAction = qt.QAction("Zoom out", self)
+        self.zoomOutAction.setShortcut("-")
+        self.connect(self.zoomOutAction, SIGNAL("triggered()"), self.zoomOutPopup)
+
+        self.saveAction = qt.QAction("Save image...", self)
+        self.saveAction.setShortcut("S")
+        self.connect(self.saveAction, SIGNAL("triggered()"), self.writeImage)
+
+        self.svgAction = qt.QAction("Save as SVG...", self)
+        self.svgAction.setShortcut("V")
+        self.connect(self.svgAction, SIGNAL("triggered()"), self.writeSVG)
+
+        self.expressionAction = qt.QAction("Apply expression...", self)
+        self.expressionAction.setShortcut("E")
+        self.connect(self.expressionAction, SIGNAL("triggered()"), self.applyExpression)
+
+        self.cursorAction = qt.QAction("Line cursor", self)
+        self.cursorAction.setShortcut("L")
+        self.cursorAction.setCheckable(True)
+        self.cursorAction.setChecked(False)
+        self.connect(self.cursorAction, SIGNAL("triggered()"), self._toggleImageCursor)
+
+        self.popup = qt.QMenu(self)
+        self.popup.addAction(self.zoomInAction)
+        self.popup.addAction(self.zoomOutAction)
+
+        self.popup.addAction(self.saveAction)
+        self.popup.addAction(self.svgAction)
+        self.popup.addAction(self.expressionAction)
+        self.popup.addAction(self.cursorAction)
+
+        self.overlayMenu = self.popup.addMenu("Overlays")
+        self.connect(self.overlayMenu, SIGNAL("aboutToShow()"), self.overlayPopup)
+
+    def setImage(self, image, normalize=True):
+        if not hasattr(image, "qimage"):
+            image = image.view(vigra.Image)
+        self.image = image
+        self._normalized = normalize
+        OverlayViewer.setImage(self, image.qimage(normalize))
+
+    def showImageCursor(self, yesOrNo=True):
+        if yesOrNo != self.cursorAction.isChecked():
+            self.cursorAction.trigger()
+
+    def _toggleImageCursor(self):
+        self.imageCursor.activateTool(self.cursorAction.isChecked())
+        self.imageCursor.setVisible(self.cursorAction.isChecked())
+
+    def addOverlay(self, overlay):
+        if not hasattr(overlay, "draw"):
+            raise TypeError("addOverlay: " + str(overlay) +
+              "is no valid overlay with 'draw' method!")
+        if overlay.parent() is None:
+            overlay.setParent(self)
+        overlay.visible = True
+        if not hasattr(overlay, "name") or not overlay.name:
+            overlay.name = self._defaultOverlayName(overlay)
+        self.overlays.append(overlay)
+        OverlayViewer.addOverlay(self, overlay)
+        self.update()
+        return len(self.overlays) - 1
+
+    def removeOverlay(self, overlay):
+        if type(overlay) == int:
+            try:
+                OverlayViewer.removeOverlay(self, self.overlays[overlay])
+                self.overlays.pop(overlay)
+                self.update()
+            except IndexError, e:
+                print "No such overlay."
+        else:
+            try:
+                self.overlays.remove(overlay)
+                OverlayViewer.removeOverlay(self, overlay)
+                self.update()
+            except ValueError, e:
+                print "No such overlay."
+
+    def _slideAfterZoom(self, shift):
+        if self.zoomLevel() > 0:
+            shift *= 1 + self.zoomLevel()
+        elif self.zoomLevel() < 0:
+            shift /= 1 - self.zoomLevel()
+        self.slideBy(shift)
+
+    def zoomInPopup(self):
+        beforePos = self.imageCoordinate(self.mousepos)
+        self.zoomUp()
+        afterPos = self.imageCoordinate(self.mousepos)
+        self._slideAfterZoom(afterPos - beforePos)
+
+    def zoomOutPopup(self):
+        beforePos = self.imageCoordinate(self.mousepos)
+        self.zoomDown()
+        afterPos = self.imageCoordinate(self.mousepos)
+        self._slideAfterZoom(afterPos - beforePos)
+
+    def _defaultOverlayName(self, o):
+        name = str(o.__class__)
+        if name[:8] == "<class '":
+            name = name[8:-2]
+        try:
+            name = name[name.rindex(".") + 1:]
+        except ValueError:
+            pass
+        return name
+
+    def overlayPopup(self):
+        self.overlayMenu.clear()
+        index = 0
+        hideable = False
+        showable = False
+        for o in self.overlays:
+            overlayName = o.name
+            text = "[%d] %s" % (index, overlayName)
+
+            color = None
+            if hasattr(o, "color") and isinstance(o.color, qt.QColor):
+                color = o.color
+                pmHeight = 5
+            elif hasattr(o, "fillColor") and isinstance(o.fillColor, qt.QColor):
+                color = o.fillColor
+                pmHeight = 16
+
+            if color:
+                colorPM = qt.QPixmap(16, pmHeight)
+                colorPM.fill(color)
+                icon = qt.QIcon(colorPM)
+                id = qt.QAction(icon, text, self)
+            else:
+                id = qt.QAction(text, self)
+
+            self.overlayMenu.addAction(id)
+            id.setCheckable(True)
+            self.connect(id, SIGNAL('triggered()'), self.toggleOverlayVisibilityWithParam(o))
+            id.setChecked(o.isVisible())
+            if o.isVisible():
+                hideable = True
+            else:
+                showable = True
+            index += 1
+        id = qt.QAction("&Hide all", self)
+        self.overlayMenu.addAction(id)
+        self.connect(id, SIGNAL('triggered()'), self.toggleOverlayVisibilityWithParam(False))
+        id.setEnabled(hideable)
+        id = qt.QAction("&Show all", self)
+        self.overlayMenu.addAction(id)
+        self.connect(id, SIGNAL('triggered()'), self.toggleOverlayVisibilityWithParam(True))
+        id.setEnabled(showable)
+
+    def toggleOverlayVisibilityWithParam(self, o):
+        return lambda: self.toggleOverlayVisibility(o)
+
+    def toggleOverlayVisibility(self, o=None):
+        '''Toggle or set visibility of given overlay and update view.
+           The parameter can be a boolean - which sets the visibility of
+           all overlays accordingly - an overlay object or the index
+           of the overlay to be hidden/re-shown. If it is omitted, all
+           overlays will be toggled.
+        '''
+        if o is None:
+            for k in self.overlays:
+                k.setVisible(not k.isVisible())
+        elif type(o) is bool:
+            for k in self.overlays:
+                k.setVisible(o)
+        else:
+            if type(o) is int:
+                o = self.overlays[o]
+            o.setVisible(not o.isVisible())
+        self.update()
+
+    def applyExpression(self, expr=None, normalized=None):
+        if expr is not None:
+            self._savedExpression = expr
+        else:
+            d = quickdialog.QuickDialog(self, "Enter Expression")
+            d.expression = quickdialog.OptionalStringInput(d, "Execute 'lambda x: ")
+            d.expression.setText(self._savedExpression)
+            d.expression.setFocus()
+            d.addSpacing(10)
+            d.norm = quickdialog.CheckBox(d, "Normalize intensity to range 0...255")
+            d.norm.setChecked(self._normalized)
+            if d.exec_() == 0:
+                return
+            self._savedExpression = d.expression.text()
+            self._normalized = True if d.norm.selection() else False
+
+        if normalized is not None:
+            self._normalized = normalized
+
+        try:
+            image, normalized = self.getDisplayedImage()
+        except Exception, e:
+            qt.QMessageBox.critical(self, "Error Applying Expression", str(e))
+            return
+
+        OverlayViewer.setImage(self, image.qimage(normalized))
+
+    def getDisplayedImage(self):
+        """Returns the displayed image and the normalize flag
+        (BYTE or NBYTE) as tuple/pair.
+
+        Note that the returned image is the original image if no
+        expression is applied, i.e. you should not change the returned
+        object.  If active, the expression is applied via
+        eval() on every call of getDisplayedImage()."""
+
+        if not self._savedExpression or self._savedExpression == "x":
+            self._savedExpression = "x"
+            image = self.image
+        else:
+            for f in vigra.ufunc.__all__:
+                exec 'from vigra.ufunc import %s' % f
+            for f in dir(vigra.colors):
+                if not f.startswith('__'):
+                    exec 'from vigra.colors import %s' % f
+            x = self.image
+            image = eval(self._savedExpression)
+
+        return image, self._normalized
+
+    def writeImage(self):
+        d = quickdialog.QuickDialog(self, "Write Image")
+
+        imageFileExtensions = '*.' + ' *.'.join(vigra.impex.listExtensions().split(' '))
+        d.filedialog = quickdialog.OutputFile(
+            d, "Output filename:", "Image Files (" + imageFileExtensions + ")")
+        d.filedialog.setFocus()
+
+        d.choices = quickdialog.HDialogGroup(d)
+
+        d.type = quickdialog.VChoice(d.choices, "Output Pixel Type")
+        d.type.addButton("Byte", "UINT8")
+        d.type.addButton("Normalized to byte", "NBYTE")
+        d.type.addButton("Keep type", "NATIVE")
+        d.type.selectButton(1 if self._normalized else 0)
+        d.type.buttonBox.setEnabled(self._lastSaveType)
+
+        d.choices.addStretch(1)
+
+        d.which = quickdialog.VChoice(d.choices, "Save ...")
+        d.which.addButton("displayed image (zoomed, overlays)", 0)
+        d.which.addButton("displayed image (1:1)", 1)
+        d.which.addButton("original image", 2)
+        d.connect(d.which.buttonBox, SIGNAL("clicked(int)"), \
+                  d.type.buttonBox.setEnabled)
+        d.which.selectButton(self._lastSaveType)
+
+        while True:
+            if d.exec_() == 0:
+                return
+
+            filename = d.filedialog.text()
+            pixelType = d.type.selection()
+
+            self._lastSaveType = d.which.selection()
+            if d.which.selection():
+                if d.which.selection() == 2:
+                    image = self.image
+                else:
+                    image = self.getDisplay()[0]
+                try:
+                    image.writeImage(filename, pixelType)
+                except RuntimeError, e:
+                    qt.QMessageBox.critical(self, "Error", str(e))
+                else:
+                    return
+            else:
+                formats = {"png": "PNG", \
+                           "bmp": "BMP", \
+                           "xbm": "XBM", \
+                           "xpm": "XPM", \
+                           "pnm": "PPM", \
+                           "ppm": "PPM", \
+                           "png": "PNG", \
+                           "jpg": "JPEG", \
+                           "jpeg": "JPEG", \
+                           "tif": "TIF"}
+
+                _, ext = os.path.splitext(filename)
+                if not formats.has_key(ext[1:]):
+                    f = " ".join(formats.keys())
+                    qt.QMessageBox.critical(self, "Error", \
+                                   "Displayed image with overlays can only be stored as\n" + f)
+                else:
+                    pixmap = self.getContentsPixmap()
+                    pixmap.save(filename, formats[ext[1:]])
+                    return
+
+    def writeSVG(self):
+        d = quickdialog.QuickDialog(self, "Write Viewer Contents to SVG")
+
+        d.filedialog = quickdialog.OutputFile(
+            d, "Output filename:", "SVG Files (*.svg)")
+        d.filedialog.setFocus()
+
+        d.choices = quickdialog.HDialogGroup(d)
+
+        d.which = quickdialog.VChoice(d.choices, "Save ...")
+        d.which.addButton("all overlays", 0)
+        d.which.addButton("only displayed overlays", 1)
+
+        d.which.selectButton(self._lastSaveType)
+
+        while True:
+            if d.exec_() == 0:
+                return
+
+            self._lastSaveType = d.which.selection()
+            allOVs = (d.which.selection() == 0)
+
+            filename = d.filedialog.text()
+            basename, ext = os.path.splitext(filename)
+
+            try:
+                if ext == ".SVG" or ext == ".svg":
+                    viewer2svg.viewer2svg(self, basename, not allOVs)
+                else:
+                    viewer2svg.viewer2svg(self, filename, not allOVs)
+            except RuntimeError, e:
+                qt.QMessageBox.critical(self, "Error", str(e))
+            return
+
+    def contextMenuEvent(self, e):
+        "handles pop-up menu"
+        self.overlayMenu.setEnabled(len(self.overlays) > 0)
+        self.mousepos = e.pos()
+        self.popup.exec_(e.globalPos())
+
+    def keyPressEvent(self, e):
+        "handles keys [S], [E], and possibly [Q] (for toplevel-windows)"
+        if e.key() == qcore.Qt.Key_Q and not self.parent():
+            self.close()
+        elif e.key() == qcore.Qt.Key_S:
+            self.writeImage()
+        elif e.key() == qcore.Qt.Key_E:
+            self.applyExpression()
+        elif e.key() == qcore.Qt.Key_L:
+            self.cursorAction.trigger()
+        elif e.key() == qcore.Qt.Key_Right or e.key() == qcore.Qt.Key_Left or \
+          e.key() == qcore.Qt.Key_Up or e.key() == qcore.Qt.Key_Down:
+            OverlayViewer.keyPressEvent(self, e)
+        elif e.key() == qcore.Qt.Key_Plus or e.key() == qcore.Qt.Key_Greater:
+            OverlayViewer.zoomUp(self)
+        elif e.key() == qcore.Qt.Key_Minus or e.key() == qcore.Qt.Key_Less:
+            OverlayViewer.zoomDown(self)
+        else:
+            self.emit(qcore.SIGNAL("keyPressed"), (e.key()))
+            e.ignore()
+
+    def keyReleaseEvent(self, e):
+        self.emit(qcore.SIGNAL("keyReleased"), (e.key()))
+        e.ignore()
+
+    def mousePressEvent(self, e):
+        imagePos = OverlayViewer.imageCoordinateF(self, qcore.QPoint(e.x(), e.y()))
+        self.emit(qcore.SIGNAL("mousePressed"), (imagePos.x(), imagePos.y(), e.button()))
+        OverlayViewer.mousePressEvent(self, e)
+        e.ignore()
+
+class CaptionImageViewer(qt.QFrame):
+    def __init__(self, image, normalize=True, title=None, parent=None):
+        qt.QFrame.__init__(self, parent)
+        self.viewer = ImageViewer(image, normalize, title, parent=self)
+        self.setWindowTitle(self.viewer.windowTitle())
+
+        self._captionCoords = 0, 0
+        self._xplaces = int(math.log10(self.viewer.image.width) + 1.0)
+        self._yplaces = int(math.log10(self.viewer.image.height) + 1.0)
+        self._valueplaces = self.viewer.image.channels * 5
+
+        self.label = qt.QLabel(self)
+        font = qt.QFont()
+        font.setPointSize(10)
+        font.setStyleHint(qt.QFont.TypeWriter)
+        self.label.setFont(font)
+
+        self._layout = qt.QVBoxLayout(self)
+        self._layout.setSpacing(5)
+        self._layout.addWidget(self.viewer, 1)
+        self._layout.addWidget(self.label)
+
+        self.connect(self.viewer, SIGNAL('mouseOver(int, int)'), self.updateCaption)
+        self.connect(self.viewer.cursorAction, SIGNAL('triggered()'), self._toggleCaptionSignals)
+
+        self.updateCaption()
+
+    def updateCaption(self, x=None, y=None):
+        x = int(round(x)) if x is not None else self._captionCoords[0]
+        y = int(round(y)) if y is not None else self._captionCoords[1]
+        if x < 0 or x >= self.viewer.image.width or \
+           y < 0 or y >= self.viewer.image.height:
+            return
+
+        self._captionCoords = x, y
+
+        label = str(x).rjust(self._xplaces) + " x " + str(y).rjust(self._yplaces) +\
+                " = " + str(self.viewer.image[x, y]).ljust(self._valueplaces)
+        self.label.setText(label)
+        self.emit(SIGNAL('captionChanged'), self.label.text())
+
+    def updateCaptionP(self, point):
+        self.updateCaption(point.x(), point.y())
+
+    def _toggleCaptionSignals(self):
+        if self.viewer.cursorAction.isChecked():
+            self.disconnect(self.viewer,
+              SIGNAL('mouseOver(int, int)'), self.updateCaption)
+            self.connect(self.viewer.imageCursor,
+              SIGNAL('positionChanged(QPoint)'), self.updateCaptionP)
+        else:
+            self.connect(self.viewer,
+              SIGNAL('mouseOver(int, int)'), self.updateCaption)
+            self.disconnect(self.viewer.imageCursor,
+              SIGNAL('positionChanged(QPoint)'), self.updateCaptionP)
+
+    def setImage(self, image, normalize=None):
+        """imageWindow.setImage(image, normalize = None)
+
+        Replace the current image with the given one.  If normalized
+        is not given (or None), the normalized state is not changed."""
+
+        self.viewer.setImage(image, normalize)
+        self.updateCaption()
+
+class CursorAction(qt.QAction):
+    def __init__(self, name, parent):
+        qt.QAction.__init__(self, name, parent)
+        self.x, self.y = -1, -1
+        self.zoomLevel = 0
+
+    def trigger(self):
+        qt.QAction.trigger(self)
+        for v in self.viewers:
+            v.viewer.cursorAction.setChecked(self.isChecked())
+            v.viewer._toggleImageCursor()
+            v._toggleCaptionSignals()
+
+    def broadcastPosition(self, pos):
+        if self.x == pos.x() and self.y == pos.y():
+            return
+        self.x, self.y = pos.x(), pos.y()
+        for v in self.viewers:
+            v.viewer.imageCursor.setPosition(pos)
+
+    def broadcastZoom(self, level):
+        if self.zoomLevel == level:
+            return
+        self.zoomLevel = level
+        for v in self.viewers:
+            v.viewer.setZoomLevel(level)
+
+class ImageWindow(qt.QFrame):
+    '''Display one or more images in a grid-like layout.
+    '''
+    def __init__(self, parent=None):
+        qt.QFrame.__init__(self, parent)
+        self.cursorAction = CursorAction("Connected line cursors", self)
+        self.cursorAction.setCheckable(True)
+        self.cursorAction.setChecked(False)
+        self.addAction(self.cursorAction)
+        self.cursorAction.viewers = []
+        self.layout = qt.QGridLayout(self)
+
+    def setImage(self, image, x=0, y=0, normalize=True, title=None):
+        """Place the given image at the given position of this window's grid layout.
+
+           If an image already exists at this position, it is replaced.
+        """
+        if self.layout.itemAtPosition(y, x):
+            self.layout.itemAtPosition(y, x).widget().setImage(image, normalize)
+        else:
+            CIviewer = CaptionImageViewer(image, normalize, title, parent=self)
+            self.layout.addWidget(CIviewer, y, x)
+            self.cursorAction.viewers.append(CIviewer)
+            if len(self.cursorAction.viewers) == 1:
+                self.setWindowTitle(CIviewer.windowTitle())
+            if self.cursorAction.x != -1:
+                CIviewer.viewer.imageCursor.setPosition(
+                  qcore.QPoint(self.cursorAction.x, self.cursorAction.y))
+            CIviewer.viewer.setZoomLevel(self.cursorAction.zoomLevel)
+            if self.cursorAction.isChecked():
+                CIviewer.viewer.cursorAction.trigger()
+            self.disconnect(CIviewer.viewer.cursorAction, SIGNAL("triggered()"),
+                            CIviewer.viewer._toggleImageCursor)
+            self.connect(CIviewer.viewer.cursorAction, SIGNAL("triggered()"),
+                         self.cursorAction.trigger)
+            self.connect(CIviewer.viewer.imageCursor, SIGNAL("positionChanged(QPoint)"),
+                         self.cursorAction.broadcastPosition)
+            self.connect(CIviewer.viewer, SIGNAL("zoomLevelChanged(int)"),
+                         self.cursorAction.broadcastZoom)
+            self.updateGeometry()
+        # this call is necessary to update the sizeHint() before adjustSize() is called
+        qcore.QCoreApplication.processEvents()
+        self.adjustSize()
+
+    def viewer(self, x=0, y=0):
+        if self.layout.itemAtPosition(y, x):
+            return self.layout.itemAtPosition(y, x).widget().viewer
+        raise ValueError("ImageWindow.viewer(): viewer at (%d, %d) is undefined." % (x, y))
+
+def showImage(image, normalize=True, title=None):
+    if isinstance(image, str):
+        image = vigra.impex.readImage(image)
+    v = ImageWindow()
+    v.setImage(image, normalize=normalize, title=title)
+    v.show()
+    return v
diff --git a/vigranumpy/lib/pyqt/overlays.py b/vigranumpy/lib/pyqt/overlays.py
new file mode 100644
index 0000000..9bd8a9f
--- /dev/null
+++ b/vigranumpy/lib/pyqt/overlays.py
@@ -0,0 +1,205 @@
+import VigraQt
+from PyQt4 import QtCore, QtGui
+
+class Overlay(VigraQt.Overlay):
+    def __init__(self, color=QtCore.Qt.red, fillColor=None, width=0,
+                 name=None, aa=False, parent=None):
+        VigraQt.Overlay.__init__(self, parent)
+        self.color = color and QtGui.QColor(color)
+        self.fillColor = fillColor and QtGui.QColor(fillColor)
+        self.width = width
+        self.name = name
+        self.setAntialiased(aa)
+
+    def _setupPainter(self, p):
+        if self.color:
+            p.setPen(QtGui.QPen(self.color, self.width))
+        else:
+            p.setPen(QtCore.Qt.NoPen)
+
+        if self.fillColor:
+            p.setBrush(self.fillColor)
+        else:
+            p.setBrush(QtCore.Qt.NoBrush)
+
+class OverlayGroup(Overlay):
+    def __init__(self, overlays, color=QtCore.Qt.red, fillColor=QtCore.Qt.red,
+                 name=None, parent=None):
+        Overlay.__init__(self, color, fillColor, parent=parent)
+        self.overlays = overlays
+        self.name = name
+        # Coordinate and aliasing settings from individual overlays
+        # are used so following setting won't get effective
+        self.setCoordinateSystem(VigraQt.Overlay.UnscaledPixel)
+        if parent:
+            parent.addOverlay(self)
+            self.setParent(parent)
+
+    def setParent(self, parent):
+        Overlay.setParent(self, parent)
+        for o in self.overlays:
+            o.setParent(parent)
+
+    def draw(self, p, r):
+        for o in self.overlays:
+            p.save()
+            if self.parent():
+                if o.coordinateSystem() & VigraQt.Overlay.Scaled:
+                    p.scale(self.parent().zoomFactor(), self.parent().zoomFactor())
+                if o.coordinateSystem() & VigraQt.Overlay.Pixel:
+                    p.translate(0.5, 0.5)
+                p.setRenderHint(QtGui.QPainter.Antialiasing, o.isAntialiased())
+            o.draw(p, r)
+            p.restore()
+
+class PointOverlay(Overlay):
+    def __init__(self, points, color=QtCore.Qt.red, fillColor=QtCore.Qt.red,
+                 radius=0.5, colors=None, name=None, aa=False, parent=None):
+        Overlay.__init__(self, color, fillColor, aa=aa, parent=parent)
+        self.originalPoints = points
+        self.color = color and QtGui.QColor(color)
+        self.colors = colors
+        self.name = name
+        self.radius = radius
+        if parent:
+            parent.addOverlay(self)
+
+    def draw(self, p, r):
+        p.save()
+        visibleRect = QtCore.QRectF(
+          VigraQt.OverlayViewer.imageCoordinateF(self.parent(), r.topLeft()),
+          VigraQt.OverlayViewer.imageCoordinateF(self.parent(), r.bottomRight()))
+        w = (2.0 * self.radius + 1.0) / self.parent().zoomFactor()
+        if self.colors:
+            for i in range(len(self.originalPoints)):
+                point = QtCore.QPointF(*self.originalPoints[i])
+                if visibleRect.contains(point):
+                    if len(self.colors) > i:
+                        p.setBrush(QtGui.QBrush(self.colors[i]))
+                        p.setPen(self.colors[i])
+                    else:
+                        self._setupPainter(p)
+                    p.drawEllipse(point, w, w)
+        else:
+            self._setupPainter(p)
+            for i in range(len(self.originalPoints)):
+                point = QtCore.QPointF(*self.originalPoints[i])
+                if visibleRect.contains(point):
+                    p.drawEllipse(point, w, w)
+        p.restore()
+
+
+class EdgeOverlay(Overlay):
+    def __init__(self, edges, color=QtCore.Qt.red, colors=None, fillColor=None,
+                 width=0, name=None, aa=False, parent=None):
+        Overlay.__init__(self, color, fillColor, width, name, aa, parent)
+        # input should be list of Polygons, but also accept single Polygon
+        self.width = width
+        self.colors = colors
+        if not hasattr(edges[0][0], "__getitem__"):
+            self.originalEdges = [edges]
+        else:
+            self.originalEdges = edges
+        if parent:
+            parent.addOverlay(self)
+
+    def draw(self, p, r):
+        p.save()
+        visibleRect = QtCore.QRectF(
+          VigraQt.OverlayViewer.imageCoordinateF(self.parent(), r.topLeft()),
+          VigraQt.OverlayViewer.imageCoordinateF(self.parent(), r.bottomRight()))
+        self._setupPainter(p)
+        if self.colors:
+            for j, polygon in enumerate(self.originalEdges):
+                qpolf = QtGui.QPolygonF(len(polygon))
+                for i, (x, y) in enumerate(polygon):
+                    qpolf[i] = QtCore.QPointF(x, y)
+                if qpolf.boundingRect().intersects(visibleRect):
+                    if len(self.colors) > j:
+                        p.setBrush(QtGui.QBrush(self.colors[j]))
+                        p.setPen(self.colors[j])
+                    else:
+                        self._setupPainter(p)
+                    p.drawPolygon(qpolf) if qpolf.isClosed() else p.drawPolyline(qpolf)
+        else:
+            for polygon in self.originalEdges:
+                qpolf = QtGui.QPolygonF(len(polygon))
+                for i, (x, y) in enumerate(polygon):
+                    qpolf[i] = QtCore.QPointF(x, y)
+                if qpolf.boundingRect().intersects(visibleRect):
+                    p.drawPolygon(qpolf) if qpolf.isClosed() else p.drawPolyline(qpolf)
+        p.restore()
+
+
+class TextOverlay(Overlay):
+    def __init__(self, text, pos, color=QtCore.Qt.red, pointsize=None,
+                 zoomText=False, name=None, aa=False, parent=None):
+        Overlay.__init__(self, color, color, aa=aa, parent=parent)
+        self.text = text
+        self.pos = pos
+        self.pointsize = pointsize
+        self.name = name
+        if zoomText:
+            self.setCoordinateSystem(VigraQt.Overlay.ScaledPixel)
+        else:
+            self.setCoordinateSystem(VigraQt.Overlay.UnscaledPixel)
+        if parent:
+            parent.addOverlay(self)
+
+    def draw(self, p, r):
+        p.save()
+        visibleRect = QtCore.QRectF(
+          VigraQt.OverlayViewer.imageCoordinateF(self.parent(), r.topLeft()),
+          VigraQt.OverlayViewer.imageCoordinateF(self.parent(), r.bottomRight()))
+
+        if self.coordinateSystem() & VigraQt.Overlay.Scaled:
+            position = QtCore.QPointF(*self.pos)
+        else:
+            position = QtCore.QPointF(*map(
+              lambda x: (x+0.5) * self.parent().zoomFactor(), self.pos))
+
+        self._setupPainter(p)
+        if self.pointsize:
+            defaultFont = p.font()
+            defaultFont.setPointSizeF(self.pointsize)
+            p.setFont(defaultFont)
+        twidth = p.fontMetrics().width(self.text)
+        theight = p.fontMetrics().height()
+        textRect = QtCore.QRectF(position.x() - twidth / 2.0,
+          position.y() - theight / 2.0, twidth, theight)
+        if self.coordinateSystem() & VigraQt.Overlay.Unscaled:
+            twidth /= self.parent().zoomFactor()
+            theight /= self.parent().zoomFactor()
+            displayRect = QtCore.QRectF(self.pos[0] - twidth / 2.0,
+              self.pos[1] - theight / 2.0, twidth, theight)
+        else:
+            displayRect = textRect
+        if displayRect.intersects(visibleRect):
+            p.drawText(textRect, QtCore.Qt.AlignCenter, self.text)
+        p.restore()
+
+
+class MapOverlay(Overlay):
+    def __init__(self, geomap, edgeColor=QtCore.Qt.blue,
+                 nodeColor=QtCore.Qt.red, name=None, aa=False, parent=None):
+        Overlay.__init__(self, aa=aa, parent=parent)
+        self.edges, self.nodes = [], []
+        for edge in geomap.edgeIter():
+            self.edges.append(edge)
+        for node in geomap.nodeIter():
+            self.nodes.append(node.position())
+        self.eo = EdgeOverlay(self.edges, edgeColor, parent=None)
+        self.po = PointOverlay(self.nodes, nodeColor, radius=0.3, parent=None)
+        self.eo.setParent(parent)
+        self.po.setParent(parent)
+        if parent:
+            parent.addOverlay(self)
+
+    def setParent(self, parent):
+        Overlay.setParent(self, parent)
+        self.eo.setParent(parent)
+        self.po.setParent(parent)
+
+    def draw(self, p, r):
+        self.eo.draw(p, r)
+        self.po.draw(p, r)
diff --git a/vigranumpy/lib/pyqt/quickdialog.py b/vigranumpy/lib/pyqt/quickdialog.py
new file mode 100644
index 0000000..c81be41
--- /dev/null
+++ b/vigranumpy/lib/pyqt/quickdialog.py
@@ -0,0 +1,450 @@
+#######################################################################
+#                                                                      
+#         Copyright 2009-2010 by Ullrich Koethe                        
+#                                                                      
+#    This file is part of the VIGRA computer vision library.           
+#    The VIGRA Website is                                              
+#        http://hci.iwr.uni-heidelberg.de/vigra/                       
+#    Please direct questions, bug reports, and contributions to        
+#        ullrich.koethe at iwr.uni-heidelberg.de    or                    
+#        vigra at informatik.uni-hamburg.de                               
+#                                                                      
+#    Permission is hereby granted, free of charge, to any person       
+#    obtaining a copy of this software and associated documentation    
+#    files (the "Software"), to deal in the Software without           
+#    restriction, including without limitation the rights to use,      
+#    copy, modify, merge, publish, distribute, sublicense, and/or      
+#    sell copies of the Software, and to permit persons to whom the    
+#    Software is furnished to do so, subject to the following          
+#    conditions:                                                       
+#                                                                      
+#    The above copyright notice and this permission notice shall be    
+#    included in all copies or substantial portions of the             
+#    Software.                                                         
+#                                                                      
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     
+#    OTHER DEALINGS IN THE SOFTWARE.                                   
+#                                                                      
+#######################################################################
+
+import PyQt4.QtGui  as qt
+import PyQt4.QtCore as qcore
+from PyQt4.QtCore import SIGNAL
+import os
+
+def alignLabels(*args):
+    m = 0
+    for dialogElement in args:
+        fontMetrics = qt.QFontMetrics(dialogElement.font())
+        for line in dialogElement.label.text().ascii().split('\n'):
+            labelWidth = fontMetrics.width(line)
+            m = max(m, labelWidth)
+    for dialogElement in args:
+        dialogElement.label.setFixedWidth(m+10)
+
+class FileDialog(qt.QFrame):
+    def __init__(self, parent, label, filter):
+        qt.QFrame.__init__(self, parent)
+        parent.addWidget(self)
+        self.filter = filter
+        self.label = qt.QLabel(label)
+        self.filename = qt.QLineEdit()
+        self.filebrowser = qt.QPushButton("Browse...")
+        self.filebrowser.setFocusPolicy(qcore.Qt.NoFocus)
+
+        self._layout = qt.QHBoxLayout()
+        self._layout.setSpacing(5)
+        self._layout.addWidget(self.label)
+        self._layout.addWidget(self.filename, 1)
+        self._layout.addWidget(self.filebrowser)
+        
+        self.setLayout(self._layout)
+            
+    def text(self):
+        return str(qcore.QFile.encodeName(self.filename.text()))
+        
+    def setFocus(self):
+        self.filename.setFocus()
+
+class InputFile(FileDialog):
+    def __init__(self, parent, label, filter):
+        FileDialog.__init__(self, parent, label, filter)
+        self.connect(self.filebrowser, SIGNAL("clicked()"), self.browse)
+        
+    def browse(self):
+        fn = qt.QFileDialog.getOpenFileName( "", self.filter, self)
+        if not fn.isNull():
+            self.filename.setText(fn)
+        
+    def validate(self):
+        try:
+            filename = str(qcore.QFile.encodeName(self.filename.text()))
+            file = open(filename)
+            file.close()
+            return True
+        except IOError:
+            qt.QMessageBox.critical(None, "Error", "File '" + filename + "' not found")
+            return False
+
+class OutputFile(FileDialog):
+    def __init__(self, parent, label, filter):
+        FileDialog.__init__(self, parent, label, filter)
+        self.connect(self.filebrowser, SIGNAL("clicked()"), self.browse)
+        
+    def browse(self):
+        fn = qt.QFileDialog.getSaveFileName( self, "Save File", "", self.filter)
+        if not fn.isNull():
+            self.filename.setText(fn)
+        
+    def validate(self):
+        try:
+            filename = str(qcore.QFile.encodeName(self.filename.text()))
+            file = open(filename)
+            file.close()
+            return not qt.QMessageBox.warning(
+                None, "Warning", "File '" + filename + "' exists",
+                "Overwrite", "Cancel")
+        except IOError:
+            return True
+
+class _OptionalValueInput(qt.QFrame):
+    def __init__(self, parent, label):
+        qt.QFrame.__init__(self, parent)
+        parent.addWidget(self)
+        self.label = qt.QLabel(label)
+        self.variable = qt.QLineEdit()
+        self.variable.setValidator(self._QValidator(self.variable))
+
+        self._layout = qt.QHBoxLayout()
+        self._layout.setSpacing(5)
+        self._layout.addWidget(self.label)
+        self._layout.addWidget(self.variable, 1)
+        
+        self.setLayout(self._layout)
+                    
+    def setFocus(self):
+        self.variable.setFocus()
+        
+    def setValue(self, text):
+        self.variable.setText(str(self._text2Value(text)))
+    
+    def value(self):
+        text = self.text()
+        if text == "":
+            return None
+        return self._text2Value(text)
+
+    def text(self):
+        return str(self.variable.text())
+        
+    def validate(self):
+        try:
+            v = self.value()
+            if v == None:
+                return True
+        except:
+            qt.QMessageBox.critical(None, "Error",
+                qcore.QString("Field '%1' must contain "+self._mustContain).arg(
+                    self.label.text()))
+            return False
+        try:
+            if v < self.min:
+                qt.QMessageBox.critical(None, "Error",
+                    qcore.QString("Field '%1' value must be >= "+str(self.min)).arg(
+                        self.label.text()))
+                return False
+        except AttributeError:
+            pass
+        try:
+            if v > self.max:
+                qt.QMessageBox.critical(None, "Error",
+                    qcore.QString("Field '%1' value must be <= "+str(self.max)).arg(
+                        self.label.text()))
+                return False
+        except AttributeError:
+            pass
+        return True
+            
+class OptionalIntegerInput(_OptionalValueInput):
+    _QValidator = qt.QIntValidator
+    _text2Value = int
+    _mustContain = "an integer"
+
+class IntegerInput(OptionalIntegerInput):
+    def value(self):
+        return int(self.text())
+
+class OptionalFloatInput(_OptionalValueInput):
+    _QValidator = qt.QDoubleValidator
+    _text2Value = float
+    _mustContain = "a float"
+
+class FloatInput(OptionalFloatInput):
+    def value(self):
+        return float(self.text())
+
+class OptionalStringInput(qt.QFrame):
+    def __init__(self, parent, label):
+        qt.QFrame.__init__(self, parent)
+        parent.addWidget(self)
+        self.label = qt.QLabel(label)
+        self.variable = qt.QLineEdit()
+
+        self._layout = qt.QHBoxLayout()
+        self._layout.setSpacing(5)
+        self._layout.addWidget(self.label)
+        self._layout.addWidget(self.variable, 1)
+        
+        self.setLayout(self._layout)
+                    
+    def setFocus(self):
+        self.variable.setFocus()
+            
+    def setText(self, text):
+        self.variable.setText(text)
+    
+    def text(self):
+        return str(self.variable.text())
+    
+    def unicode(self):
+        return unicode(self.variable.text())
+
+class StringInput(OptionalStringInput):
+    def __init__(self, parent, label):
+        OptionalStringInput.__init__(self, parent, label)
+            
+    def validate(self):
+        if self.text() == "":
+            qt.QMessageBox.critical(
+                None, "Error",
+                qcore.QString("Field '%1' empty").arg(self.label.text()))
+            return False
+        return True
+
+OutputVariable = StringInput
+InputVariable = StringInput
+OptionalInputVariable = OptionalStringInput
+
+class CheckBox(qt.QCheckBox):
+    def __init__(self, parent, label):
+        qt.QCheckBox.__init__(self, label, parent)
+        parent.addWidget(self)
+
+    def selection(self):
+        return self.isChecked()
+
+
+class Choice(qt.QFrame):
+    def __init__(self, parent, label, vertical = 0):
+        qt.QFrame.__init__(self, parent)
+        parent.addWidget(self)
+        
+        self.buttonBox = qt.QGroupBox(label, self)
+        if vertical:
+            self.buttonBox.layout = qt.QVBoxLayout(self.buttonBox)
+        else:
+            self.buttonBox.layout = qt.QHBoxLayout(self.buttonBox)
+        
+        self.layout = qt.QHBoxLayout(self)
+        self.layout.addWidget(self.buttonBox)
+        self.layout.addStretch(5)
+        
+        self.buttons = []
+        self.results = []
+    
+    def addButton(self, label, result):
+        self.buttons.append(qt.QRadioButton(label))
+        self.buttonBox.layout.addWidget(self.buttons[-1])
+        self.results.append(result)
+        self.buttons[0].setChecked(True)
+        
+    def addSpacing(self, spacing):
+        self.buttonBox.addSpace(spacing)
+        
+    def selectButton(self, index):
+        if index >= 0 and index < len(self.buttons):
+            self.buttons[index].setChecked(True)
+        
+    def selection(self):
+        for k in range(len(self.buttons)):
+            if self.buttons[k].isChecked():
+                return self.results[k]
+        return None # should never happen
+
+class HChoice(Choice):
+    def __init__(self, parent, label):
+        Choice.__init__(self, parent, label, 0)
+        
+class VChoice(Choice):
+    def __init__(self, parent, label):
+        Choice.__init__(self, parent, label, 1)
+        
+class DialogGroup(qt.QFrame):
+    def __init__(self, parent, vertical = 0):
+        qt.QFrame.__init__(self, parent)
+        parent.addWidget(self)
+        if vertical:
+            self.layout = qt.QVBoxLayout(self)
+            self.defaultAlignment = qcore.Qt.AlignLeft
+        else:
+            self.layout = qt.QHBoxLayout(self)
+            self.defaultAlignment = qcore.Qt.AlignTop
+        self.widgets = []
+               
+    def addWidget(self, widget, stretch = 0, alignment = None):
+        if alignment is None:
+            alignment = self.defaultAlignment
+        self.layout.addWidget(widget, stretch, alignment)
+        self.widgets.append(widget)
+        
+    def addSpacing(self, spacing):
+        self.layout.addSpacing(spacing)
+
+    def addStretch(self, stretch):
+        self.layout.addStretch(stretch)
+        
+    def addLabel(self, labelString):
+        label = qt.QLabel(labelString, self)
+        self.addWidget(label, 0, qcore.Qt.AlignLeft)
+        
+    def validate(self):
+        for i in self.widgets:
+            try:
+                if i.validate() == 0:
+                    return False
+            except AttributeError:
+                continue
+        return True
+
+class HDialogGroup(DialogGroup):
+    def __init__(self, parent):
+        DialogGroup.__init__(self, parent, 0)
+        
+class VDialogGroup(DialogGroup):
+    def __init__(self, parent):
+        DialogGroup.__init__(self, parent, 1)
+       
+#class DialogStack(qt.QWidgetStack):
+#    def __init__(self, parent, widgetMapping = None):
+#        qt.QWidgetStack.__init__(self, parent)
+#        parent.addWidget(self)
+#        self.widgetMapping = widgetMapping
+#        self.size = 0
+#            
+#    def raiseWidget(self, index):
+#        if self.widgetMapping:
+#            qt.QWidgetStack.raiseWidget(self, self.widgetMapping[index])
+#        else:
+#            qt.QWidgetStack.raiseWidget(self, index)
+#
+#    def addWidget(self, widget):
+#        qt.QWidgetStack.addWidget(self, widget, self.size)
+#        self.size = self.size + 1
+#        
+#    def validate(self):
+#        try:
+#            return self.visibleWidget().validate()
+#        except AttributeError:
+#            pass
+
+class QuickDialog(qt.QDialog):
+    def __init__(self, parent, title):
+        qt.QDialog.__init__(self, parent)
+
+        self.layout = qt.QVBoxLayout(self)
+        self.layout.addStretch(5)
+        self.layout.addSpacing(20)
+        
+        self.insertButtons()
+        
+        self.widgets = []
+        self.setWindowTitle(title)
+        self.setOrientation(qcore.Qt.Vertical)
+        self.resize(500,-1)
+        
+    def insertButtons(self):
+        self.buttons = qt.QFrame(self)
+        self.buttons.OK = qt.QPushButton("OK", self.buttons)
+        self.buttons.Cancel = qt.QPushButton("Cancel", self.buttons)
+        self.buttons.OK.setDefault(1)
+        self.connect(self.buttons.Cancel, SIGNAL("clicked()"), self.reject)
+        self.connect(self.buttons.OK, SIGNAL("clicked()"), self.tryAccept)
+        
+        self.buttons.layout = qt.QHBoxLayout(self.buttons)
+        self.buttons.layout.addStretch(5)
+        self.buttons.layout.addWidget(self.buttons.OK)
+        self.buttons.layout.addWidget(self.buttons.Cancel)
+        self.layout.addWidget(self.buttons)
+        
+    def addWidget(self, widget, stretch = 0, alignment = None):
+        if alignment is None:
+            alignment = qcore.Qt.AlignTop
+        self.layout.insertWidget(len(self.widgets), widget, stretch, alignment)
+        self.widgets.append(widget)
+        
+    def addSpacing(self, spacing):
+        self.layout.insertSpacing(len(self.widgets), spacing)
+        self.widgets.append(None)
+
+    def addStretch(self, stretch):
+        self.layout.insertStretch(len(self.widgets), stretch)
+        self.widgets.append(None)
+
+    def addLabel(self, labelString):
+        label = qt.QLabel(labelString, self)
+        self.addWidget(label, 0, qcore.Qt.AlignLeft)
+        
+    def setHelp(self, *functionSeq):
+        helpString = ""
+        functionList = list(*functionSeq)
+        while len(functionList) > 0:
+            function = functionList.pop()
+            if (len(functionList) == 0) and (function.__doc__):
+                helpString = helpString + function.__doc__
+            elif function.__doc__:
+                helpString = helpString + function.__doc__ + os.linesep + \
+                    "--------------------------------------------------------"+\
+                    "--------------------------------" + os.linesep
+        
+        if not hasattr(self.buttons, "Help"):
+            self.buttons.Help = qt.QPushButton("Help", self.buttons)
+            self.buttons.Help.setToggleButton(1)
+            self.buttons.layout.insertWidget(3, self.buttons.Help)
+            self.connect(self.buttons.Help, SIGNAL("toggled(bool)"), self.showExtension)
+        
+        if int(qt.qVersion()[0]) < 3:
+            self.help = qt.QMultiLineEdit(self)
+            self.help.setText(helpString)
+            if self.help.numLines() > 20:
+                self.help.setFixedVisibleLines(20)
+            else:
+                self.help.setFixedVisibleLines(self.help.numLines()+1)
+
+            self.help.setReadOnly(1)
+            self.help.setWordWrap(qt.QMultiLineEdit.WidgetWidth)
+        else:
+            self.help = qt.QVBox(self)
+            self.help.text = qcore.QtextEdit(self.help)
+            self.help.text.setText(helpString)
+            self.help.text.setReadOnly(1)
+            self.help.text.setWordWrap(qt.QMultiLineEdit.WidgetWidth)
+            total_height = self.help.text.heightForWidth(self.help.width())
+            if  total_height > self.help.text.height():
+                self.help.text.setMinimumSize(self.help.text.width(), min(300, total_height))
+                
+        self.setExtension(self.help)
+        
+    def tryAccept(self):
+        for i in self.widgets:
+            try:
+                if i.validate() == 0:
+                    return
+            except AttributeError:
+                continue
+        self.accept()
diff --git a/vigranumpy/lib/pyqt/viewer2svg.py b/vigranumpy/lib/pyqt/viewer2svg.py
new file mode 100644
index 0000000..445455a
--- /dev/null
+++ b/vigranumpy/lib/pyqt/viewer2svg.py
@@ -0,0 +1,108 @@
+import os 
+from PyQt4 import QtCore, QtGui
+
+def viewer2svg(viewer, basepath, onlyVisible = False, moveBy = QtCore.QPointF(0.5, 0.5)):
+    outvec=[]
+    outvec.append('<?xml version="1.0" standalone="no"?>\n')
+    outvec.append('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"\n')
+    outvec.append('  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')
+
+    pngFilename = basepath + "_bg.png"
+    viewer.image.writeImage(pngFilename, "")
+    _, bgFilename = os.path.split(pngFilename)
+
+    outvec.append('\n<svg version="1.1" xmlns="http://www.w3.org/2000/svg"\n')
+    outvec.append('  width="21cm" height="29.7cm" preserveAspectRatio="xMinYMin meet"\n')
+    outvec.append('  viewBox="-1 -1 ' + str(viewer.image.width + 1) + ' ' + \
+      str(viewer.image.height + 1) + '" xmlns:xlink="http://www.w3.org/1999/xlink">\n')
+    outvec.append('\n<g style="fill:none">\n')
+
+    outvec.append('\n<image xlink:href="' + bgFilename + '"\n')
+    outvec.append('  x="0" y="0" width="' + str(viewer.image.width) + '" height="' + \
+      str(viewer.image.height) + '" />\n')
+
+    ovs = []
+    for ov in viewer.overlays:
+        if onlyVisible and not ov.isVisible():
+            continue
+        ovname = viewer._defaultOverlayName(ov)
+        if ovname == "MapOverlay":
+            ovs.append([viewer._defaultOverlayName(ov.eo), ov.eo])
+            ovs.append([viewer._defaultOverlayName(ov.po), ov.po])
+        else:
+            ovs.append([ovname, ov])            
+
+    for overlay in ovs:
+        if overlay[0] == "EdgeOverlay":
+            overlay = overlay[1]
+            color = 'rgb' + str(overlay.color.getRgb()[:3]) + '; opacity:' + str(overlay.color.getRgb()[-1] / 255.0)
+            if not overlay.colors:
+                for i, edge in enumerate(overlay.originalEdges):
+                    outvec.append(writeEdge(edge, overlay.width, color, moveBy))
+            else:
+                for i, edge in enumerate(overlay.originalEdges):
+                    if len(overlay.colors) > i:
+                        color = overlay.colors[i] if hasattr(overlay.colors[i], "getRgb") else \
+                          QtGui.QColor(overlay.colors[i])
+                        color = 'rgb' + str(color.getRgb()[:3]) + '; opacity:' + str(color.getRgb()[-1] / 255.0)
+                    outvec.append(writeEdge(edge, overlay.width, color, moveBy))
+                
+        elif overlay[0] == "PointOverlay":
+            overlay = overlay[1]
+            color = '  style="fill:rgb' + str(overlay.color.getRgb()[:3]) + '; opacity:' + str(overlay.color.getRgb()[-1] / 255.0) + '"/>\n'
+            radius = '" r="' + str(overlay.radius if overlay.radius > 0 else 0.5) + '"\n'
+            pointList = []
+            for point in overlay.originalPoints:
+                pointList.append(QtCore.QPointF(*point) + moveBy)
+            for point in pointList:
+                outvec.append('<circle cx="' + str(point.x()) + '" cy="' + str(point.y()) + radius + color)
+        elif overlay[0] == "TextOverlay":
+            overlay = overlay[1]
+            for element in overlay.textlist:
+                if len(element) == 4:
+                    outvec.extend(writeText(text = element[0], position = element[1], color = element[2], size = element[3]))
+                elif len(element) == 3:
+                    outvec.extend(writeText(text = element[0], position = element[1], color = element[2]))
+                else:
+                    outvec.extend(writeText(text = element[0], position = element[1]))
+        else:
+            print str(overlay[0]) + " not supported yet.\n"
+
+    outvec.append('\n</g>\n')
+    outvec.append('</svg>\n')
+
+    f = open(basepath + ".svg", 'w')
+    for line in outvec:
+        f.write(line)
+    f.close()
+
+def writeEdge(edge, width, color, moveBy):
+    qpolf = QtGui.QPolygonF(len(edge))
+    for i, (x, y) in enumerate(edge):
+        qpolf[i] = QtCore.QPointF(x,y) + moveBy
+    result = "\n"
+    if qpolf.size() == 2:
+        result += '<line x1="' + str(qpolf[0].x()) + '" y1="' + str(qpolf[0].y()) + '" '
+        result += 'x2="' + str(qpolf[1].x()) + '" y2="' + str(qpolf[1].y())
+    elif qpolf.size() > 2:
+        result += '<polyline points="' + str(qpolf[0].x()) + '" y1="' + str(qpolf[0].y())
+        for pos in range(1, qpolf.size()):
+            result += ' ' + str(qpolf[pos].x()) + '" y1="' + str(qpolf[pos].y())
+    result += '"\n  style="stroke:' + color + '; stroke-width:' + str(width if width > 0 else 0.5) + ';\n'
+    result += '  stroke-linejoin:bevel; stroke-linecap:butt;"/>\n'
+    return result
+
+def writeText(text, position, color = None, size = None):
+    if not size:
+        size= "6"
+    if not color:
+        color = 'fill:rgb(0, 255, 0); opacity:1; stroke:rgb(0, 0, 0); stroke-width:0.3;'
+    else:
+        color = 'fill:rgb' + str(QtGui.QColor(color).getRgb()[:3]) + '; opacity:' + \
+          str(QtGui.QColor(color).getRgb()[-1] / 255.0) + '; stroke:rgb(0, 0, 0); stroke-width:0.3;'
+    style = '  style="' + color + '\n    dominant-baseline: central; ' + \
+      'text-anchor: middle; font-size: ' + str(size) + 'pt; font-family: sans-serif"'
+
+    return '\n<text x="' + str(position[0]) + '" y="' + str(position[1]) + '"\n' + \
+            style + '>' + text.toUtf8().data() + '</text>\n'
+
diff --git a/vigranumpy/lib/tagged_array.py b/vigranumpy/lib/tagged_array.py
new file mode 100644
index 0000000..ee920f2
--- /dev/null
+++ b/vigranumpy/lib/tagged_array.py
@@ -0,0 +1,377 @@
+#######################################################################
+#
+#         Copyright 2009-2011 by Ullrich Koethe
+#
+#    This file is part of the VIGRA computer vision library.
+#    The VIGRA Website is
+#        http://hci.iwr.uni-heidelberg.de/vigra/
+#    Please direct questions, bug reports, and contributions to
+#        ullrich.koethe at iwr.uni-heidelberg.de    or
+#        vigra at informatik.uni-hamburg.de
+#
+#    Permission is hereby granted, free of charge, to any person
+#    obtaining a copy of this software and associated documentation
+#    files (the "Software"), to deal in the Software without
+#    restriction, including without limitation the rights to use,
+#    copy, modify, merge, publish, distribute, sublicense, and/or
+#    sell copies of the Software, and to permit persons to whom the
+#    Software is furnished to do so, subject to the following
+#    conditions:
+#
+#    The above copyright notice and this permission notice shall be
+#    included in all copies or substantial portions of the
+#    Software.
+#
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+#    OTHER DEALINGS IN THE SOFTWARE.
+#
+#######################################################################
+
+import copy
+import numpy
+    
+def preserve_doc(f):
+    f.__doc__ = eval('numpy.ndarray.%s.__doc__' % f.__name__)
+    return f
+
+class TaggedArray(numpy.ndarray):
+    '''
+TaggedArray extends numpy.ndarray with an attribute 'axistags'. Any 
+axistags object must support the standard sequence interface, and its 
+length must match the number of dimensions of the array. Each item in 
+the axistags sequence is supposed to provide a description of the 
+corresponding array axis. All array functions that change the number or 
+ordering of an array's axes (such as transpose() and __getitem__()) are 
+overloaded so that they apply the same transformation to the axistags 
+object. 
+
+Example:
+  >>> axistags = ['x', 'y']
+  >>> a = TaggedArray((2,3), axistags=axistags)
+  >>> a.axistags
+  ['x', 'y']
+  >>> a[:,0].axistags
+  ['x']
+  >>> a[1,...].axistags
+  ['y']
+  >>> a.transpose().axistags
+  ['y', 'x']
+  
+Except for the new 'axistags' keyword, the 'TaggedArray' constructor is identical to the constructor 
+of 'numpy.ndarray'. 
+    '''
+    def __new__(subtype, shape, dtype=float, buffer=None, offset=0, strides=None, order=None, axistags=None):
+        res = numpy.ndarray.__new__(subtype, shape, dtype, buffer, offset, strides, order)
+        if axistags is None:
+            res.axistags = res.default_axistags()
+        else:
+            if len(axistags) != res.ndim:
+                raise RuntimeError('TaggedArray(): len(axistags) must match ndim')
+            res.axistags = copy.copy(axistags)
+        return res
+        
+    def default_axistags(self):
+        '''Create an axistags object with non-informative entries.
+        '''
+        return [None]*self.ndim
+    
+    def copy_axistags(self):
+        '''Create a copy of 'self.axistags'. If the array doesn't have axistags, default_axistags() 
+           will be returned.
+        '''
+        return copy.copy(getattr(self, 'axistags', self.default_axistags()))
+        
+    def transpose_axistags(self, axes=None):
+        '''Create a copy of 'self.axistags' according to the given axes permutation 
+           (internally called in transpose()).
+        '''
+        axistags = self.default_axistags()
+        if hasattr(self, 'axistags'):
+            if axes is None:
+                axes = range(self.ndim-1, -1, -1)
+            for k in xrange(self.ndim):
+                axistags[k] = self.axistags[int(axes[k])]
+        return axistags
+        
+    def transform_axistags(self, index):
+        '''Create a copy of 'self.axistags' according to the given index or slice object 
+           (internally called in __getitem__()).
+        '''
+        # we assume that self.ndim is already set to its new value, whereas
+        # self.axistags has just been copied by __array_finalize__
+        
+        new_axistags = self.default_axistags()
+        
+        if hasattr(self, 'axistags'):
+            old_axistags = self.axistags
+            old_ndim = len(old_axistags)
+            new_ndim = len(new_axistags)
+            try:
+                # make sure that 'index' is a tuple
+                len_index = len(index)
+            except:
+                index = (index,)
+                len_index = 1
+            len_index -= index.count(numpy.newaxis)
+            if len_index < old_ndim and index.count(Ellipsis) == 0:
+                index += (Ellipsis,)
+                len_index += 1
+            
+            # how many missing axes are represented by an Ellipsis ?
+            len_ellipsis = old_ndim - len_index
+            
+            knew, kold, kindex = 0, 0, 0
+            while knew < new_ndim:
+                try:
+                    # if index[kindex] is int, the dimension is bound => drop this axis
+                    int(index[kindex]) 
+                    kold += 1
+                    kindex += 1
+                except:
+                    if index[kindex] is not numpy.newaxis:
+                        # copy the tag
+                        new_axistags[knew] = old_axistags[kold]
+                        kold += 1
+                    knew += 1
+                    # the first ellipsis represents all missing axes
+                    if len_ellipsis > 0 and index[kindex] is Ellipsis:
+                        len_ellipsis -= 1
+                    else:
+                        kindex += 1
+        return new_axistags
+    
+    __array_priority__ = 10.0
+    
+    def __array_finalize__(self, obj):
+        if hasattr(obj, 'axistags'):
+            self.axistags = obj.axistags
+
+    @preserve_doc
+    def __copy__(self, order = 'C'):
+        result = numpy.ndarray.__copy__(self, order)
+        result.axistags = result.copy_axistags()
+        return result
+    
+    @preserve_doc
+    def __deepcopy__(self, memo):
+        result = numpy.ndarray.__deepcopy__(self, memo)
+        memo[id(self)] = result
+        result.__dict__ = copy.deepcopy(self.__dict__, memo)
+        return result
+    
+    def __repr__(self):
+        return "%s(shape=%s, axistags=%s, dtype=%s, data=\n%s)" % \
+          (self.__class__.__name__, str(self.shape), repr(self.axistags), str(self.dtype), str(self))
+          
+    @preserve_doc
+    def all(self, axis=None, out=None):
+        res = numpy.ndarray.all(self, axis, out)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        return res
+
+    @preserve_doc
+    def any(self, axis=None, out=None):
+        res = numpy.ndarray.any(self, axis, out)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        return res
+
+    @preserve_doc
+    def argmax(self, axis=None, out=None):
+        res = numpy.ndarray.argmax(self, axis, out)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        return res
+        
+    @preserve_doc
+    def argmin(self, axis=None, out=None):
+        res = numpy.ndarray.argmin(self, axis, out)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        return res
+    
+    @preserve_doc
+    def cumsum(self, axis=None, dtype=None, out=None):
+        res = numpy.ndarray.cumsum(self, axis, dtype, out)
+        if res.ndim != self.ndim:
+            res.axistags = res.default_axistags()
+        return res        
+
+    @preserve_doc
+    def cumprod(self, axis=None, dtype=None, out=None):
+        res = numpy.ndarray.cumprod(self, axis, dtype, out)
+        if res.ndim != self.ndim:
+            res.axistags = res.default_axistags()
+        return res        
+
+    # FIXME: we should also provide a possibility to determine flattening order by axistags
+    #        (the same applies to flat and ravel)
+    @preserve_doc
+    def flatten(self, order='C'):
+        res = numpy.ndarray.flatten(self, order)
+        res.axistags = res.default_axistags()
+        return res        
+
+    @preserve_doc
+    def max(self, axis=None, out=None):
+        res = numpy.ndarray.max(self, axis, out)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        return res
+
+    @preserve_doc
+    def mean(self, axis=None, out=None):
+        res = numpy.ndarray.mean(self, axis, out)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        return res
+    
+    @preserve_doc
+    def min(self, axis=None, out=None):
+        res = numpy.ndarray.min(self, axis, out)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        return res
+    
+    @preserve_doc
+    def nonzero(self):
+        res = numpy.ndarray.nonzero(self)
+        for k in xrange(len(res)):
+            res[k].axistags = copy.copy(self.axistags[k])
+        return res
+
+    @preserve_doc
+    def prod(self, axis=None, dtype=None, out=None):
+        res = numpy.ndarray.prod(self, axis, dtype, out)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        return res
+
+    @preserve_doc
+    def ptp(self, axis=None, out=None):
+        res = numpy.ndarray.ptp(self, axis, out)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        return res
+
+    @preserve_doc
+    def ravel(self, order='C'):
+        res = numpy.ndarray.ravel(self, order)
+        res.axistags = res.default_axistags()
+        return res        
+
+    @preserve_doc
+    def repeat(self, repeats, axis=None):
+        res = numpy.ndarray.repeat(self, repeats, axis)
+        if axis is None:
+            res.axistags = res.default_axistags()
+        return res        
+
+    @preserve_doc
+    def reshape(self, shape, order='C'):
+        res = numpy.ndarray.reshape(self, shape, order)
+        res.axistags = res.default_axistags()
+        return res        
+
+    @preserve_doc
+    def resize(self, new_shape, refcheck=True, order=False):
+        res = numpy.ndarray.reshape(self, new_shape, refcheck, order)
+        res.axistags = res.default_axistags()
+        return res        
+            
+    @preserve_doc
+    def squeeze(self):
+        res = numpy.ndarray.squeeze(self)
+        if self.ndim != res.ndim:
+            res.axistags = res.copy_axistags()
+            for k in xrange(self.ndim-1, -1, -1):
+                if self.shape[k] == 1:
+                    del res.axistags[k]
+        return res        
+
+    @preserve_doc
+    def std(self, axis=None, dtype=None, out=None, ddof=0):
+        res = numpy.ndarray.std(self, axis, dtype, out, ddof)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        if len(res.shape) == 0:
+            res = res.item()
+        return res
+
+    @preserve_doc
+    def sum(self, axis=None, dtype=None, out=None):
+        res = numpy.ndarray.sum(self, axis, dtype, out)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        return res
+            
+    @preserve_doc
+    def swapaxes(self, i, j):
+        res = numpy.ndarray.swapaxes(self, i, j)
+        res.axistags = res.copy_axistags()
+        res.axistags[i], res.axistags[j] = res.axistags[j], res.axistags[i]
+        return res        
+ 
+    @preserve_doc
+    def take(self, indices, axis=None, out=None, mode='raise'):
+        res = numpy.ndarray.take(self, indices, axis, out, mode)
+        if axis is None:
+            res.axistags = res.default_axistags()
+        return res        
+           
+    @preserve_doc
+    def transpose(self, *axes):
+        res = numpy.ndarray.transpose(self, *axes)
+        res.axistags = res.transpose_axistags(*axes)
+        return res
+
+    @preserve_doc
+    def var(self, axis=None, dtype=None, out=None, ddof=0):
+        res = numpy.ndarray.var(self, axis, dtype, out, ddof)
+        if axis is not None:
+            res.axistags = res.copy_axistags()
+            del res.axistags[axis]
+        if len(res.shape) == 0:
+            res = res.item()
+        return res
+
+    @property
+    def T(self):
+        return self.transpose()
+
+    def __getitem__(self, index):
+        '''x.__getitem__(y) <==> x[y]
+         
+           In addition to the usual indexing functionality, this function
+           also updates the axistags of the result array. There are three cases:
+             * getitem creates a scalar value => no axistags are required
+             * getitem creates an arrayview => axistags are transferred from the
+                                             corresponding axes of the base array,
+                                             axes resulting from 'newaxis' get tag 'None'
+             * getitem creates a copy of an array (fancy indexing) => all axistags are 'None'
+        '''
+        res = numpy.ndarray.__getitem__(self, index)
+        if res is not self and hasattr(res, 'axistags'):
+            if res.base is self:
+                res.axistags = res.transform_axistags(index)
+            else:
+                res.axistags = res.default_axistags()
+        return res
diff --git a/vigranumpy/lib/ufunc.py b/vigranumpy/lib/ufunc.py
new file mode 100644
index 0000000..9b3bbb0
--- /dev/null
+++ b/vigranumpy/lib/ufunc.py
@@ -0,0 +1,368 @@
+#######################################################################
+#                                                                      
+#         Copyright 2009-2010 by Ullrich Koethe                        
+#                                                                      
+#    This file is part of the VIGRA computer vision library.           
+#    The VIGRA Website is                                              
+#        http://hci.iwr.uni-heidelberg.de/vigra/                       
+#    Please direct questions, bug reports, and contributions to        
+#        ullrich.koethe at iwr.uni-heidelberg.de    or                    
+#        vigra at informatik.uni-hamburg.de                               
+#                                                                      
+#    Permission is hereby granted, free of charge, to any person       
+#    obtaining a copy of this software and associated documentation    
+#    files (the "Software"), to deal in the Software without           
+#    restriction, including without limitation the rights to use,      
+#    copy, modify, merge, publish, distribute, sublicense, and/or      
+#    sell copies of the Software, and to permit persons to whom the    
+#    Software is furnished to do so, subject to the following          
+#    conditions:                                                       
+#                                                                      
+#    The above copyright notice and this permission notice shall be    
+#    included in all copies or substantial portions of the             
+#    Software.                                                         
+#                                                                      
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     
+#    OTHER DEALINGS IN THE SOFTWARE.                                   
+#                                                                      
+#######################################################################
+
+import numpy
+import copy
+
+vigraTypecastingRules = '''
+Default output types are thus determined according to the following rules:
+   
+   1. The output type does not depend on the order of the arguments::
+   
+         a + b results in the same type as b + a
+   
+   2.a With exception of logical functions and abs(), the output type 
+       does not depend on the function to be executed.
+        
+   2.b The output type of logical functions is bool. 
+   
+   2.c The output type of abs() follows general rules unless the 
+       input contains complex numbers, in which case the output type 
+       is the corresponding float number type::
+      
+         a + b results in the same type as a / b
+         a == b => bool
+         abs(complex128) => float64
+         
+   3. If the inputs have the same type, the type is preserved::
+   
+         uint8 + uint8 => uint8
+   
+   4. If (and only if) one of the inputs has at least 64 bits, the output 
+      will also have at least 64 bits::
+      
+         int64 + uint32 => int64
+         int64 + 1.0    => float64
+         
+   5. If an array is combined with a scalar of the same kind (integer,
+      float, or complex), the array type is preserved. If an integer 
+      array with at most 32 bits is combined with a float scalar, the 
+      result is float32 (and rule 4 kicks in if the array has 64 bits)::
+      
+         uint8   + 1   => uint8
+         uint8   + 1.0 => float32
+         float32 + 1.0 => float32
+         float64 + 1.0 => float64
+         
+   6. Integer expressions with mixed types always produce signed results.
+      If the arguments have at most 32 bits, the result will be int32, 
+      otherwise it will be int64 (cf. rule 4)::
+      
+         int8  + uint8  => int32
+         int32 + uint8  => int32
+         int32 + uint32 => int32
+         int32 + int64  => int64
+         int64 + uint64 => int64
+         
+   7. In all other cases, the output type is equal to the highest input 
+      type::
+      
+         int32   + float32    => float32
+         float32 + complex128 => complex128
+         
+   8. All defaults can be overridden by providing an explicit output array::
+   
+         ufunc.add(uint8, uint8, uint16) => uint16
+         
+In order to prevent overflow, necessary upcasting is performed before 
+the function is executed.
+'''
+
+class Function(object):
+    test_types = numpy.typecodes['AllInteger'][:-2] + numpy.typecodes['AllFloat']+'O'
+    len_test_types = len(test_types)
+    kindToNumber = {'b': 1, 'u': 2, 'i': 2, 'f': 3, 'c': 4}
+    boolFunctions = ['equal', 'greater', 'greater_equal', 'less', 'less_equal', 'not_equal',
+                     'logical_and', 'logical_not', 'logical_or', 'logical_xor']
+    
+    def __init__(self, function):
+        self.function = function
+        self.is_bool = function.__name__ in self.boolFunctions
+        self.is_abs  = function.__name__ == "absolute"
+        self.__doc__ = function.__doc__
+        self.nin = function.nin
+        self.nout = function.nout
+        
+    def __getattr__(self, name):
+        return getattr(self.function, name)
+        
+    def __repr__(self):
+        return "<vigra.ufunc '%s'>" % self.__name__
+    
+    def priorities(self, *args):
+        '''Among the inputs with largest size, find the one with highest 
+           __array_priority__. Return this input, or None if there is no 
+           inputs with 'size' and '__array_priority__' defined.'''
+        maxSize = max([getattr(x, 'size', 0) for x in args])
+        if maxSize == 0:
+            return None
+        priorities = [(getattr(x, '__array_priority__', -1.0), x) for x in args if getattr(x, 'size', 0) == maxSize]
+        priorities.sort(key = lambda (p, x): p)
+        if priorities[-1][0] == -1.0:
+            return None
+        else:
+            return priorities[-1][1]
+    
+    def common_type_numpy(self, *args):
+        '''Find a common type for the given inputs.
+           This function will become obsolete when numpy.find_common_type() will be fixed.
+           Code taken from the partial fix in numpy changeset 7133.
+        '''
+        arrayTypes = [x.dtype for x in args if hasattr(x, 'dtype')]
+        N = len(arrayTypes)
+        if N == 1:
+            highestArrayType = arrayTypes[0]
+        else:
+            k = 0
+            while k < self.len_test_types:
+                highestArrayType = numpy.dtype(self.test_types[k])
+                numcoerce = len([x for x in arrayTypes if highestArrayType >= x])
+                if numcoerce == N:
+                    break
+                k += 1
+        scalarTypes = [numpy.dtype(type(x)) for x in args if numpy.isscalar(x)]
+        N = len(scalarTypes)
+        if N == 0 or highestArrayType >= scalarTypes[0]:
+            return (highestArrayType, highestArrayType)
+        else:
+            h, s = highestArrayType.kind, scalarTypes[0].kind
+            if (h in ['i', 'u'] and s in ['i', 'u']) or \
+               (h == 'f' and s == 'f') or \
+               (h == 'c' and s == 'c'):
+                return (highestArrayType, highestArrayType)
+            return (highestArrayType, scalarTypes[0])
+        
+    def common_type(self, *args):
+        '''Find the appropriate pair (in_dtype, out_dtype) according to 
+           vigranumpy typecasting rules. in_dtype is the type into which 
+           the arguments will be casted before performing the operation
+           (to prevent possible overflow), out_type is the type the output
+           array will have (unless an explicit out-argument is provided).
+           
+           See ufunc.vigraTypecastingRules for detailed information on coercion rules.
+        '''
+        if self.is_abs and args[0].dtype.kind == "c" and args[1] is None:
+            dtype = args[0].dtype
+            if dtype == numpy.complex64:
+                return dtype, numpy.float32
+            if dtype == numpy.complex128:
+                return dtype, numpy.float64
+            if dtype == numpy.clongdouble:
+                return dtype, numpy.longdouble
+        arrayTypes = [(self.kindToNumber[x.dtype.kind], x.dtype.itemsize, x.dtype) for x in args if hasattr(x, 'dtype')]
+        arrayTypes.sort()
+        if arrayTypes[0] != arrayTypes[-1] and arrayTypes[-1][0] == 2:
+            if arrayTypes[-1][1] <= 4: 
+                highestArrayType = (2, 4, numpy.int32)
+            else: 
+                highestArrayType = (2, 8, numpy.int64)
+        else:
+            highestArrayType = arrayTypes[-1]
+            
+        if self.is_bool:
+            return (highestArrayType[-1], numpy.bool8)
+
+        scalarType = [numpy.dtype(type(x)) for x in args if numpy.isscalar(x)]
+        if not scalarType:
+            return (highestArrayType[-1], highestArrayType[-1])
+        scalarType = (self.kindToNumber[scalarType[0].kind], scalarType[0].itemsize, scalarType[0])
+        if highestArrayType[0] >= scalarType[0]:
+            return (highestArrayType[-1], highestArrayType[-1])
+        elif scalarType[0] == 3 and highestArrayType[1] <= 4:
+            return (highestArrayType[-1], numpy.float32)        
+        else:
+            return (highestArrayType[-1], scalarType[-1])        
+        
+class UnaryFunction(Function):
+    def __call__(self, arg, out=None):
+        a = arg.squeeze().transposeToNumpyOrder()
+        dtype, out_dtype = self.common_type(a, out)
+        
+        if out is None:
+            out = arg.__class__(arg, dtype=out_dtype, order='A', init=False)
+            o = out.squeeze().transposeToNumpyOrder()
+        else:
+            o = out.squeeze().transposeToNumpyOrder()
+            if not a.axistags.compatible(o.axistags):
+                raise RuntimeError("%s(): axistag mismatch" % self.function.__name__)
+        
+        a = numpy.require(a, dtype).view(numpy.ndarray) # view(ndarray) prevents infinite recursion
+        self.function(a, o)
+        return out            
+
+class UnaryFunctionOut2(Function):
+    def __call__(self, arg, out1=None, out2=None):
+        a = arg.squeeze().transposeToNumpyOrder()
+        dtype, out_dtype = self.common_type(a, out1, out2)
+
+        if out1 is None:
+            out1 = arg.__class__(arg, dtype=out_dtype, order='A', init=False)
+            o1 = out1.squeeze().transposeToNumpyOrder()
+        else:
+            o1 = out1.squeeze().transposeToNumpyOrder()
+            if not a.axistags.compatible(o1.axistags):
+                raise RuntimeError("%s(): axistag mismatch" % self.function.__name__)
+
+        if out2 is None:
+            out2 = arg.__class__(arg, dtype=out_dtype, order='A', init=False)            
+            o2 = out2.squeeze().transposeToNumpyOrder()
+        else:
+            o2 = out2.squeeze().transposeToNumpyOrder()
+            if not a.axistags.compatible(o2.axistags):
+                raise RuntimeError("%s(): axistag mismatch" % self.function.__name__)
+            
+        a = numpy.require(a, dtype).view(numpy.ndarray) # view(ndarray) prevents infinite recursion
+        self.function(a, o1, o2)
+        return out1, out2
+                
+class BinaryFunction(Function):
+    def __call__(self, arg1, arg2, out=None):
+        dtype, out_dtype = self.common_type(arg1, arg2, out)
+        
+        if isinstance(arg1, numpy.ndarray):
+            a1 = arg1.transposeToNumpyOrder()
+            if isinstance(arg2, numpy.ndarray):
+                a2 = arg2.transposeToNumpyOrder()
+                
+                if arg1.__array_priority__ == arg2.__array_priority__:
+                    priorityArg = arg2 if arg1.ndim < arg2.ndim else arg1
+                else:
+                    priorityArg = arg2 if arg1.__array_priority__ < arg2.__array_priority__ else arg1
+                
+                if a1.ndim < a2.ndim:
+                    a1 = a1.insertChannelAxis(order='C')
+                elif a1.ndim > a2.ndim:
+                    a2 = a2.insertChannelAxis(order='C')
+                    
+                axistags = a1.axistags
+                
+                if not axistags.compatible(a2.axistags):
+                    raise RuntimeError("%s(): input axistag mismatch %r vs. %r" % 
+                                         (self.function.__name__, axistags, a2.axistags))
+                shape = tuple(max(k) for k in zip(a1.shape, a2.shape))
+                a2 = numpy.require(a2, dtype).view(numpy.ndarray)
+            else:
+                priorityArg = arg1
+                axistags = a1.axistags
+                shape = a1.shape
+                a2 = arg2
+            a1 = numpy.require(a1, dtype).view(numpy.ndarray) # view(ndarray) prevents infinite recursion
+        else:
+            a1 = arg1
+            a2 = arg2.transposeToNumpyOrder()
+            axistags = a2.axistags
+            shape = a2.shape
+            priorityArg = arg2
+            a2 = numpy.require(a2, dtype).view(numpy.ndarray)
+            
+        if out is None:
+            outClass = priorityArg.__class__
+            inversePermutation = priorityArg.permutationFromNumpyOrder()
+            o = outClass(shape, dtype=out_dtype, order='C', axistags=axistags, init=False)
+            if priorityArg.ndim < o.ndim:
+                out = o.dropChannelAxis().transpose(inversePermutation)
+            else:
+                out = o.transpose(inversePermutation)
+        else:
+            o = out.transposeToNumpyOrder()
+            if o.ndim < len(shape):
+                o = o.insertChannelAxis(order='C')
+            if not axistags.compatible(o.axistags):
+                raise RuntimeError("%s(): output axistag mismatch %r vs. %r" % 
+                                         (self.function.__name__, axistags, o.axistags))
+        self.function(a1, a2, o)
+        return out
+        
+__all__ = []
+
+for _k in numpy.__dict__.itervalues():
+     if type(_k) == numpy.ufunc:
+        if _k.nin == 1 and _k.nout == 1:
+            exec _k.__name__ + " = UnaryFunction(_k)"
+        if _k.nin == 1 and _k.nout == 2:
+            exec _k.__name__ + " = UnaryFunctionOut2(_k)"
+        if _k.nin == 2:
+            exec _k.__name__ + " = BinaryFunction(_k)"
+        __all__.append(_k.__name__)
+
+__all__.sort()
+
+def _prepareDoc():
+    doc = '''
+The following mathematical functions are available in this module
+(refer to numpy for detailed documentation)::
+    
+'''
+
+    k = 0    
+    while k < len(__all__):
+        t = 8
+        while True:
+            d = '    ' + '   '.join(__all__[k:k+t]) + '\n'
+            if len(d) <= 80:
+                break
+            t -= 1
+        doc += d
+        k += t
+
+    return doc + '''
+Some of these functions are also provided as member functions of 
+VigraArray::
+
+    __abs__   __add__   __and__   __div__   __divmod__   __eq__
+    __floordiv__   __ge__   __gt__   __invert__   __le__   __lshift__
+    __lt__   __mod__   __mul__   __ne__   __neg__   __or__   __pos__
+    __pow__   __radd__   __radd__   __rand__   __rdiv__   __rdivmod__
+    __rfloordiv__   __rlshift__   __rmod__   __rmul__   __ror__   __rpow__
+    __rrshift__   __rshift__   __rsub__   __rtruediv__   __rxor__   __sub__
+    __truediv__   __xor__
+
+As usual, these functions are applied independently at each pixel.
+
+Vigranumpy overloads the numpy-versions of these functions in order to make their
+behavior more suitable for image analysis. In particular, we changed two aspects:
+
+* Axistag consistency is checked, and the order of axes and strides is 
+  preserved in the result array. (In contrast, plain numpy functions 
+  always create C-order arrays, disregarding the stride order of the 
+  inputs.)
+* Typecasting rules are changed such that (i) data are represented with 
+  at most 32 bits, when possible, (ii) the number of types that occur as 
+  results of mixed expressions is reduced, and (iii) the chance of bad 
+  surprises is minimized. 
+
+''' + vigraTypecastingRules
+
+__doc__ = _prepareDoc()
\ No newline at end of file
diff --git a/vigranumpy/setup.py.in b/vigranumpy/setup.py.in
new file mode 100644
index 0000000..55ef0c0
--- /dev/null
+++ b/vigranumpy/setup.py.in
@@ -0,0 +1,37 @@
+import distutils, ctypes.util, shutil, os, sys
+from distutils.core import setup
+
+# copy the required DLLs to the directory $vigranumpy_tmp_dir/dlls
+# if additional libraries are linked dynamically (e.g. tiff, png)
+# they must be added to the list as well
+dlls = ['@Boost_PYTHON_LIBRARY_RELEASE@',
+        '@FFTW3_LIBRARY@',
+        '@HDF5_Z_LIBRARY@',
+        '@HDF5_SZ_LIBRARY@',
+        '@HDF5_CORE_LIBRARY@',
+        '@HDF5_HL_LIBRARY@']
+
+for d in dlls:
+    if not d:
+        continue
+    dll = ctypes.util.find_library(os.path.splitext(os.path.basename(d))[0])
+    shutil.copy(dll, '@vigranumpy_tmp_dir@/dlls')
+vigraimpex_dll='@VIGRAIMPEX_LOCATION@'.replace('$(OutDir)', 'release').replace('$(Configuration)', 'release')
+shutil.copy(vigraimpex_dll, '@vigranumpy_tmp_dir@/dlls')
+msvc_runtime = ctypes.util.find_library(ctypes.util.find_msvcrt())
+shutil.copy(msvc_runtime, '@vigranumpy_tmp_dir@/dlls')
+
+docdir = '@DOCDIR@'    
+
+setup(name = 'vigranumpy',
+      description = 'VIGRA Computer Vision Library',
+      author = 'Ullrich Koethe',
+      author_email = 'ullrich.koethe at iwr.uni-heidelberg.de',
+      url = 'http://hci.iwr.uni-heidelberg.de/vigra/',
+      license = 'MIT',
+      version = '@vigra_version@',
+      packages = ['vigra', 'vigra.pyqt'],
+      package_dir = {'vigra': 'vigra', 'vigra.pyqt': 'vigra/pyqt'},
+      package_data = {'vigra': ['*.pyd', 'dlls/*.dll', 
+                  'doc/vigra/*.*', 'doc/vigra/documents/*.*', 
+                  'doc/vigranumpy/*.*', 'doc/vigranumpy/_static/*.*']})
diff --git a/vigranumpy/src/CMakeLists.txt b/vigranumpy/src/CMakeLists.txt
new file mode 100644
index 0000000..c8b5232
--- /dev/null
+++ b/vigranumpy/src/CMakeLists.txt
@@ -0,0 +1,7 @@
+ADD_SUBDIRECTORY(core)
+
+IF(FFTW3F_FOUND)
+    ADD_SUBDIRECTORY(fourier)
+ELSE()
+    MESSAGE(STATUS "vigranumpy fourier module will not be built (fftw3f missing)")
+ENDIF()
diff --git a/vigranumpy/src/core/CMakeLists.txt b/vigranumpy/src/core/CMakeLists.txt
new file mode 100644
index 0000000..1e8b04a
--- /dev/null
+++ b/vigranumpy/src/core/CMakeLists.txt
@@ -0,0 +1,65 @@
+IF(MSVC)
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
+ENDIF()
+
+# note special treatment of target vigranumpy_core: 
+# module name is automatically changed into vigranumpycore
+VIGRA_ADD_NUMPY_MODULE(core 
+  SOURCES 
+    vigranumpycore.cxx
+    converters.cxx
+    axistags.cxx
+  VIGRANUMPY)
+
+VIGRA_ADD_NUMPY_MODULE(impex 
+  SOURCES
+    impex.cxx
+  LIBRARIES   
+    ${VIGRANUMPY_IMPEX_LIBRARIES}
+  VIGRANUMPY)   
+     
+VIGRA_ADD_NUMPY_MODULE(sampling 
+  SOURCES
+    sampling.cxx
+  VIGRANUMPY)
+   
+VIGRA_ADD_NUMPY_MODULE(filters SOURCES
+    kernel.cxx
+    convolution.cxx
+    filters.cxx
+    tensors.cxx
+    morphology.cxx
+  VIGRANUMPY)
+   
+VIGRA_ADD_NUMPY_MODULE(analysis SOURCES
+    segmentation.cxx
+    edgedetection.cxx
+    interestpoints.cxx
+    accumulator.cxx
+    accumulator-region-singleband.cxx
+    accumulator-region-multiband.cxx
+  VIGRANUMPY)
+   
+VIGRA_ADD_NUMPY_MODULE(learning SOURCES
+    random_forest_old.cxx
+    random_forest.cxx
+    learning.cxx
+  LIBRARIES   
+    ${VIGRANUMPY_IMPEX_LIBRARIES}
+  VIGRANUMPY)
+   
+VIGRA_ADD_NUMPY_MODULE(colors SOURCES
+    colors.cxx
+  VIGRANUMPY)
+   
+VIGRA_ADD_NUMPY_MODULE(noise SOURCES
+    noise.cxx
+  VIGRANUMPY)
+   
+VIGRA_ADD_NUMPY_MODULE(geometry SOURCES
+    geometry.cxx
+  VIGRANUMPY)
+   
+VIGRA_ADD_NUMPY_MODULE(optimization SOURCES
+    optimization.cxx
+  VIGRANUMPY)
diff --git a/vigranumpy/src/core/accumulator-region-multiband.cxx b/vigranumpy/src/core/accumulator-region-multiband.cxx
new file mode 100644
index 0000000..a85a2a5
--- /dev/null
+++ b/vigranumpy/src/core/accumulator-region-multiband.cxx
@@ -0,0 +1,69 @@
+/************************************************************************/
+/*                                                                      */
+/*            Copyright 2011-2012 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyanalysis_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include "pythonaccumulator.hxx"
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+void defineMultibandRegionAccumulators()
+{
+    using namespace python;
+    using namespace vigra::acc;
+
+    docstring_options doc_options(true, true, false);
+    
+    typedef Select<Count, Mean, Variance, Skewness, Kurtosis, Covariance, 
+                   Principal<Variance>, Principal<Skewness>, Principal<Kurtosis>,
+                   Principal<CoordinateSystem>,
+                   Minimum, Maximum, Principal<Minimum>, Principal<Maximum>,
+                   Select<RegionCenter, RegionRadii, RegionAxes,
+                          Coord<Minimum>, Coord<Maximum>, Principal<Coord<Skewness> >, Principal<Coord<Kurtosis> > >,
+                   DataArg<1>, LabelArg<2>
+                   > VectorRegionAccumulators;
+
+    definePythonAccumulatorArrayMultiband<3, float, VectorRegionAccumulators>();
+    definePythonAccumulatorArrayMultiband<4, float, VectorRegionAccumulators>();
+    
+    definePythonAccumulatorArray<2, TinyVector<float, 3>, VectorRegionAccumulators>();
+    definePythonAccumulatorArray<3, TinyVector<float, 3>, VectorRegionAccumulators>();
+}
+
+} // namespace vigra
diff --git a/vigranumpy/src/core/accumulator-region-singleband.cxx b/vigranumpy/src/core/accumulator-region-singleband.cxx
new file mode 100644
index 0000000..c2d0a8c
--- /dev/null
+++ b/vigranumpy/src/core/accumulator-region-singleband.cxx
@@ -0,0 +1,65 @@
+/************************************************************************/
+/*                                                                      */
+/*            Copyright 2011-2012 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyanalysis_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include "pythonaccumulator.hxx"
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+void defineSinglebandRegionAccumulators()
+{
+    using namespace python;
+    using namespace vigra::acc;
+
+    docstring_options doc_options(true, true, false);
+    typedef Select<Count, Mean, Variance, Skewness, Kurtosis, 
+                   Minimum, Maximum, StandardQuantiles<GlobalRangeHistogram<0> >,
+                   RegionCenter, RegionRadii, RegionAxes,
+                   Weighted<RegionCenter>, Weighted<RegionRadii>, Weighted<RegionAxes>,
+                   Select<Coord<Minimum>, Coord<Maximum>, Coord<ArgMinWeight>, Coord<ArgMaxWeight>, 
+                          Principal<Coord<Skewness> >, Principal<Coord<Kurtosis> >, 
+                          Principal<Weighted<Coord<Skewness> > >, Principal<Weighted<Coord<Kurtosis> > > >,
+                   DataArg<1>, WeightArg<1>, LabelArg<2>
+                   > ScalarRegionAccumulators;
+    definePythonAccumulatorArraySingleband<2, float, ScalarRegionAccumulators>();
+    definePythonAccumulatorArraySingleband<3, float, ScalarRegionAccumulators>();
+}
+
+} // namespace vigra
diff --git a/vigranumpy/src/core/accumulator.cxx b/vigranumpy/src/core/accumulator.cxx
new file mode 100644
index 0000000..6378a2d
--- /dev/null
+++ b/vigranumpy/src/core/accumulator.cxx
@@ -0,0 +1,165 @@
+/************************************************************************/
+/*                                                                      */
+/*            Copyright 2011-2012 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyanalysis_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include "pythonaccumulator.hxx"
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+namespace acc 
+{
+
+AliasMap defineAliasMap()
+{
+    AliasMap res;
+    res["Coord<DivideByCount<PowerSum<1> > >"] = "RegionCenter";
+    res["Coord<RootDivideByCount<Principal<PowerSum<2> > > >"] = "RegionRadii";
+    res["Coord<Principal<CoordinateSystem> >"] = "RegionAxes";
+    res["DivideByCount<Central<PowerSum<2> > >"] = "Variance";
+    res["DivideUnbiased<Central<PowerSum<2> > >"] = "UnbiasedVariance";
+    res["DivideByCount<Principal<PowerSum<2> > >"] = "Principal<Variance>";
+    res["DivideByCount<FlatScatterMatrix>"] = "Covariance";
+    res["DivideByCount<PowerSum<1> >"] = "Mean";
+    res["PowerSum<1>"] = "Sum";
+    res["PowerSum<0>"] = "Count";
+    res["Principal<CoordinateSystem>"] = "PrincipalAxes";
+    res["AutoRangeHistogram<0>"] = "Histogram";
+    res["GlobalRangeHistogram<0>"] = "Histogram";
+    res["StandardQuantiles<AutoRangeHistogram<0> >"] = "Quantiles";
+    res["StandardQuantiles<GlobalRangeHistogram<0> >"] = "Quantiles";
+    res["Weighted<Coord<DivideByCount<PowerSum<1> > > >"] = "Weighted<RegionCenter>";
+    res["Weighted<Coord<RootDivideByCount<Principal<PowerSum<2> > > > >"] = "Weighted<RegionRadii>";
+    res["Weighted<Coord<Principal<CoordinateSystem> > >"] = "Weighted<RegionAxes>";
+    return res;
+}
+
+AliasMap * createTagToAlias(ArrayVector<std::string> const & names)
+{
+    const AliasMap aliases = defineAliasMap();
+    VIGRA_UNIQUE_PTR<AliasMap> res(new AliasMap());
+    for(unsigned int k=0; k<names.size(); ++k)
+    {
+            // lookup alias names
+        AliasMap::const_iterator a = aliases.find(names[k]);
+        std::string alias = (a == aliases.end())
+                               ? names[k]
+                               : a->second;
+                               
+            // treat FlatScatterMatrix and ScatterMatrixEigensystem as internal,
+            // i.e. use names only when they don't contain these strings
+        if(alias.find("ScatterMatrixEigensystem") == std::string::npos &&
+           alias.find("FlatScatterMatrix") == std::string::npos)
+             (*res)[names[k]] = alias;
+    }
+    return res.release();   
+}
+
+AliasMap * createAliasToTag(AliasMap const & tagToAlias)
+{
+    VIGRA_UNIQUE_PTR<AliasMap> res(new AliasMap());
+    for(AliasMap::const_iterator k = tagToAlias.begin(); k != tagToAlias.end(); ++k)
+        (*res)[normalizeString(k->second)] = normalizeString(k->first);
+    return res.release();
+}
+
+ArrayVector<std::string> * createSortedNames(AliasMap const & tagToAlias)
+{
+    VIGRA_UNIQUE_PTR<ArrayVector<std::string> > res(new ArrayVector<std::string>());
+    for(AliasMap::const_iterator k = tagToAlias.begin(); k != tagToAlias.end(); ++k)
+        res->push_back(k->second);
+    std::sort(res->begin(), res->end());
+    return res.release();
+}
+
+} // namespace acc
+
+void defineGlobalAccumulators()
+{
+    using namespace python;
+    using namespace vigra::acc;
+
+    docstring_options doc_options(true, true, false);
+    
+    PythonFeatureAccumulator::definePythonClass();
+    PythonRegionFeatureAccumulator::definePythonClass();
+    
+    typedef Select<Count, Mean, Variance, Skewness, Kurtosis, Covariance, 
+                   Principal<Variance>, Principal<Skewness>, Principal<Kurtosis>,
+                   Principal<CoordinateSystem>,
+                   Minimum, Maximum, Principal<Minimum>, Principal<Maximum>
+                   > VectorAccumulators;
+
+    definePythonAccumulatorMultiband<3, float, VectorAccumulators>();
+    definePythonAccumulatorMultiband<4, float, VectorAccumulators>();
+    
+    definePythonAccumulator<TinyVector<float, 3>, VectorAccumulators>();
+
+    typedef Select<Count, Mean, Variance, Skewness, Kurtosis, 
+                   UnbiasedVariance, UnbiasedSkewness, UnbiasedKurtosis,
+                   Minimum, Maximum, StandardQuantiles<AutoRangeHistogram<0> > 
+                   > ScalarAccumulators;
+    definePythonAccumulatorSingleband<float, ScalarAccumulators>();
+}
+
+void defineSinglebandRegionAccumulators();
+void defineMultibandRegionAccumulators();
+
+void defineAccumulators()
+{
+    NumpyArrayConverter<NumpyArray<1, npy_uint32> >();
+    NumpyArrayConverter<NumpyArray<1, float> >();
+    NumpyArrayConverter<NumpyArray<1, double> >();
+    NumpyArrayConverter<NumpyArray<2, MultiArrayIndex> >();
+    NumpyArrayConverter<NumpyArray<2, float> >();
+    NumpyArrayConverter<NumpyArray<2, double> >();
+    NumpyArrayConverter<NumpyArray<3, float> >();
+    NumpyArrayConverter<NumpyArray<3, double> >();
+    
+    defineGlobalAccumulators();
+    // changed order (?)
+    defineMultibandRegionAccumulators();
+    defineSinglebandRegionAccumulators();
+}
+
+// TODO:
+//  * is there a good implementation of merge for histogramms with different mapping?
+//  * multiband histograms
+
+} // namespace vigra
diff --git a/vigranumpy/src/core/axistags.cxx b/vigranumpy/src/core/axistags.cxx
new file mode 100644
index 0000000..1afbe33
--- /dev/null
+++ b/vigranumpy/src/core/axistags.cxx
@@ -0,0 +1,748 @@
+/************************************************************************/
+/*                                                                      */
+/*               Copyright 2010-2011 by Ullrich Koethe                  */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpycore_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/axistags.hxx>
+#include <boost/python.hpp>
+#include <boost/python/slice.hpp>
+
+// disable axistag construction from json for the moment,
+// because these libraries require boost 1.41, whereas
+// our Ubuntu longterm support has only boost 1.40
+//
+// as a workaround, we will do this in Python using the 'json' module
+#define VIGRA_DISABLE_FROMJSON
+
+#ifndef VIGRA_DISABLE_FROMJSON  
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#endif
+
+namespace python = boost::python;
+
+namespace vigra {
+
+template<class T>
+inline PyObject * managingPyObject(T *p)
+{
+    return typename python::manage_new_object::apply<T *>::type()(p);
+}
+
+template<class Copyable>
+python::object
+generic__copy__(python::object copyable)
+{
+    Copyable* newCopyable(new Copyable(python::extract<const Copyable &>(copyable)()));
+    python::object result(python::detail::new_reference(managingPyObject(newCopyable)));
+
+    python::extract<python::dict>(result.attr("__dict__"))().update(copyable.attr("__dict__"));
+
+    return result;
+}
+
+template<class Copyable>
+python::object
+generic__deepcopy__(python::object copyable, python::dict memo)
+{
+    python::object copyMod = python::import("copy");
+    python::object deepcopy = copyMod.attr("deepcopy");
+    python::object builtin = python::import("__builtin__");
+    python::object globals = builtin.attr("__dict__");
+    
+    Copyable* newCopyable(new Copyable(python::extract<const Copyable &>(copyable)()));
+    python::object result(python::detail::new_reference(managingPyObject(newCopyable)));
+
+    python::dict locals;
+    locals["copyable"] = copyable;
+    size_t copyableId = python::extract<size_t>(python::eval("id(copyable)", globals, locals))();
+    memo[copyableId] = result;
+
+    python::object dict_copy = deepcopy(python::extract<python::dict>(copyable.attr("__dict__"))(),
+                                        memo);    
+    python::extract<python::dict>(result.attr("__dict__"))().update(dict_copy);
+    return result;
+}
+
+AxisInfo AxisInfo__call__(AxisInfo const & i, double resolution, std::string const & description)
+{
+    return AxisInfo(i.key(), i.typeFlags(), resolution, description);
+}
+
+AxisInfo AxisInfo_x()
+{
+    return AxisInfo::x();
+}
+
+AxisInfo AxisInfo_y()
+{
+    return AxisInfo::y();
+}
+
+AxisInfo AxisInfo_z()
+{
+    return AxisInfo::z();
+}
+
+AxisInfo AxisInfo_t()
+{
+    return AxisInfo::t();
+}
+
+AxisInfo AxisInfo_fx()
+{
+    return AxisInfo::fx();
+}
+
+AxisInfo AxisInfo_fy()
+{
+    return AxisInfo::fy();
+}
+
+AxisInfo AxisInfo_fz()
+{
+    return AxisInfo::fz();
+}
+
+AxisInfo AxisInfo_ft()
+{
+    return AxisInfo::ft();
+}
+
+AxisInfo AxisInfo_c()
+{
+    return AxisInfo::c();
+}
+
+#ifndef VIGRA_DISABLE_FROMJSON  
+AxisTags AxisTags::fromJSON(std::string const & repr)
+{
+    using boost::property_tree::ptree;
+    
+    std::istringstream s(repr);
+    ptree pt;
+    read_json(s, pt);
+    
+    AxisTags res;
+    for(ptree::iterator v = pt.get_child("axes").begin(); 
+                         v != pt.get_child("axes").end(); ++v)
+    {
+        std::string key(v->second.get<std::string>("key"));
+        unsigned int typeFlags(v->second.get<unsigned int>("typeFlags"));
+        double resolution(v->second.get<double>("resolution"));
+        std::string description(v->second.get<std::string>("description"));
+        
+        res.push_back(AxisInfo(key, (AxisInfo::AxisType)typeFlags, resolution, description));
+    }    
+    return res;
+}
+
+AxisTags * AxisTags_readJSON(std::string const & repr)
+{
+    return new AxisTags(AxisTags::fromJSON(repr));
+}
+#endif
+
+AxisTags *
+AxisTags_create(python::object i1, python::object i2,
+                python::object i3, python::object i4, python::object i5)
+{
+    VIGRA_UNIQUE_PTR<AxisTags> res(new AxisTags());
+    
+    python::extract<AxisTags const &> tags(i1);
+    if(tags.check())
+    {
+        res = VIGRA_UNIQUE_PTR<AxisTags>(new AxisTags(tags()));
+    }
+    else if(PySequence_Check(i1.ptr()))
+    {
+        int size = len(i1);
+        for(int k=0; k<size; ++k)
+        {
+            python::extract<AxisInfo const &> info(i1[k]);
+            if(!info.check())
+            {
+                PyErr_SetString(PyExc_TypeError, "AxisTags(): Argument must be a sequence of AxisInfo objects.");
+                python::throw_error_already_set();
+            }
+            res->push_back(info());
+        }
+    }
+    else if(PyInt_Check(i1.ptr()))
+    {
+        int size = python::extract<int>(i1)();
+        for(int k=0; k<size; ++k)
+            res->push_back(AxisInfo());
+    }
+    else
+    {
+        if(i1 != python::object())
+        {
+            python::extract<AxisInfo const &> info(i1);
+            if(!info.check())
+            {
+                PyErr_SetString(PyExc_TypeError, "AxisTags(): Argument must be a sequence of AxisInfo objects.");
+                python::throw_error_already_set();
+            }
+            res->push_back(info());
+        }
+        if(i2 != python::object())
+        {
+            python::extract<AxisInfo const &> info(i2);
+            if(!info.check())
+            {
+                PyErr_SetString(PyExc_TypeError, "AxisTags(): Argument must be a sequence of AxisInfo objects.");
+                python::throw_error_already_set();
+            }
+            res->push_back(info());
+        }
+        if(i3 != python::object())
+        {
+            python::extract<AxisInfo const &> info(i3);
+            if(!info.check())
+            {
+                PyErr_SetString(PyExc_TypeError, "AxisTags(): Argument must be a sequence of AxisInfo objects.");
+                python::throw_error_already_set();
+            }
+            res->push_back(info());
+        }
+        if(i4 != python::object())
+        {
+            python::extract<AxisInfo const &> info(i4);
+            if(!info.check())
+            {
+                PyErr_SetString(PyExc_TypeError, "AxisTags(): Argument must be a sequence of AxisInfo objects.");
+                python::throw_error_already_set();
+            }
+            res->push_back(info());
+        }
+        if(i5 != python::object())
+        {
+            python::extract<AxisInfo const &> info(i5);
+            if(!info.check())
+            {
+                PyErr_SetString(PyExc_TypeError, "AxisTags(): Argument must be a sequence of AxisInfo objects.");
+                python::throw_error_already_set();
+            }
+            res->push_back(info());
+        }
+    }
+    
+    return res.release();
+}
+
+void AxisTags_insertChannelAxis(AxisTags & axistags)
+{
+    int k = axistags.channelIndex();
+    vigra_precondition(k == (int)axistags.size(),
+         "AxisTags::insertChannelAxis(): already has a channel axis.");
+    if(detail::defaultOrder() == "F")
+        axistags.insert(0, AxisInfo::c());
+    else
+        axistags.push_back(AxisInfo::c());
+}
+
+AxisInfo & AxisTags_getitem(AxisTags & axistags, int index)
+{
+    if(index < 0)
+        index += axistags.size();
+        
+    if(index >= (int)axistags.size())
+    {
+        PyErr_SetString(PyExc_IndexError, "AxisTags.__getitem__(): Invalid index or key.");
+        python::throw_error_already_set();
+    }
+    
+    return axistags.get(index);
+}
+
+std::string AxisTags_str(AxisTags const & axistags)
+{
+    std::string res;
+    for(unsigned int k=0; k<axistags.size(); ++k)
+        res += axistags.get(k).repr() + "\n";
+    return res;
+}
+
+python::object
+AxisTags_permutationToNormalOrder(AxisTags const & axistags)
+{
+    ArrayVector<npy_intp> permutation;
+    axistags.permutationToNormalOrder(permutation);
+    return python::object(permutation);
+}
+
+python::object
+AxisTags_permutationToNormalOrder2(AxisTags const & axistags, unsigned int types)
+{
+    ArrayVector<npy_intp> permutation;
+    axistags.permutationToNormalOrder(permutation, (AxisInfo::AxisType)types);
+    return python::object(permutation);
+}
+
+python::object
+AxisTags_permutationFromNormalOrder(AxisTags const & axistags)
+{
+    ArrayVector<npy_intp> permutation;
+    axistags.permutationFromNormalOrder(permutation);
+    return python::object(permutation);
+}
+
+python::object
+AxisTags_permutationFromNormalOrder2(AxisTags const & axistags, unsigned int types)
+{
+    ArrayVector<npy_intp> permutation;
+    axistags.permutationFromNormalOrder(permutation, (AxisInfo::AxisType)types);
+    return python::object(permutation);
+}
+
+python::object
+AxisTags_permutationToNumpyOrder(AxisTags const & axistags)
+{
+    ArrayVector<npy_intp> permutation;
+    axistags.permutationToNumpyOrder(permutation);
+    return python::object(permutation);
+}
+
+python::object
+AxisTags_permutationFromNumpyOrder(AxisTags const & axistags)
+{
+    ArrayVector<npy_intp> permutation;
+    axistags.permutationFromNumpyOrder(permutation);
+    return python::object(permutation);
+}
+
+python::object
+AxisTags_permutationToVigraOrder(AxisTags const & axistags)
+{
+    ArrayVector<npy_intp> permutation;
+    axistags.permutationToVigraOrder(permutation);
+    return python::object(permutation);
+}
+
+python::object
+AxisTags_permutationFromVigraOrder(AxisTags const & axistags)
+{
+    ArrayVector<npy_intp> permutation;
+    axistags.permutationFromVigraOrder(permutation);
+    return python::object(permutation);
+}
+
+python::object
+AxisTags_permutationToOrder(AxisTags const & axistags, std::string const & order)
+{
+    ArrayVector<npy_intp> permutation;
+    axistags.permutationToOrder(permutation, order);
+    return python::object(permutation);
+}
+
+
+
+AxisTags *
+AxisTags_transform(AxisTags const & oldTags, python::object index, int lnew)
+{
+    VIGRA_UNIQUE_PTR<AxisTags> newTags(new AxisTags());
+    python::object ellipsis = python::object(python::detail::borrowed_reference(Py_Ellipsis));
+    int lold = oldTags.size();
+    if(!PySequence_Check(index.ptr()))
+    {
+        index = python::make_tuple(index);
+    }
+    int lindex = len(index);
+    int lnewaxis = 0, lellipsis = 0;
+    for(int k=0; k<lindex; ++k)
+    {
+        python::object item(index[k]);
+        if(item == python::object() || python::extract<AxisInfo const &>(item).check())
+            ++lnewaxis;
+        else if(item == ellipsis)
+            ++lellipsis;
+    }
+    lindex -= lnewaxis;
+    if(lindex < lold && lellipsis == 0)
+    {
+        index += python::make_tuple(ellipsis);
+        ++lindex;
+    }
+    lellipsis = lold - lindex;
+    int knew = 0, kold = 0, kindex = 0;
+    while(knew < lnew)
+    {
+        python::object item = index[kindex];
+        if(PyInt_Check(item.ptr()))
+        {
+            ++kold;
+            ++kindex;
+        }
+        else 
+        {
+            if(item != python::object())
+            {
+                python::extract<AxisInfo const &> newaxis(item);
+                
+                if(newaxis.check())
+                {
+                    newTags->push_back(newaxis);
+                }
+                else
+                {
+                    newTags->push_back(oldTags.get(kold));
+                    // adjust the resolution if item has a valid 'step' member
+                    python::extract<python::slice> slice(item);
+                    if(slice.check())
+                    {
+                        python::extract<int> step(slice().step());
+                        if(step.check())
+                        {
+                            newTags->get(knew).resolution_ *= step();
+                        }
+                    }
+                    ++kold;
+                }
+            }
+            else
+            {
+                newTags->push_back(AxisInfo());
+            }
+            ++knew;
+            if(lellipsis > 0 && item == ellipsis)
+                --lellipsis;
+            else
+                ++kindex;
+        }
+    }
+    return newTags.release();
+}
+
+// #if 0
+// void printAxistags(NumpyAnyArray a)
+// {
+    // python::object array(python::detail::borrowed_reference(a.pyObject()));
+    // python::object tags(getattr(array, "axistags", PyAxisTags()));
+    // std::cerr << "Axistags via boost::python:\n";
+    // std::cerr << python::extract<PyAxisTags const &>(tags)().repr();
+
+    // std::cerr << "Axistags via C-API:\n";
+    // if(PyObject_HasAttrString(a.pyObject(), "axistags"))
+    // {
+        // python::object tags(python::detail::new_reference(PyObject_GetAttrString(a.pyObject(), "axistags")));
+        // std::cerr << python::extract<PyAxisTags const &>(tags)().repr();
+    // }
+    // else
+    // {
+        // std::cerr << "attribute 'axistags' missing\n";
+    // }
+// }
+// #endif
+
+void defineAxisTags()
+{
+    using namespace boost::python;
+
+    docstring_options doc_options(true, false, false);
+
+    enum_<AxisInfo::AxisType>("AxisType",
+         "\nEnum to encode the type of an axis described by an\n"
+         ":class:`~vigra.AxisInfo` object. Possible values:\n\n"
+         "   ``AxisType.Channels:``\n      a channel axis\n"
+         "   ``AxisType.Space:``\n      a spatial axis\n"
+         "   ``AxisType.Angle:``\n      an axis encoding angles (e.g. polar coordinates)\n"
+         "   ``AxisType.Time:``\n      a temporal axis\n"
+         "   ``AxisType.Frequency:``\n      an axis in the Fourier domain\n"
+         "   ``AxisType.UnknownAxisType:``\n      type not specified\n"
+         "   ``AxisType.NonChannel:``\n      any type except Channels\n"
+         "   ``AxisType.AllAxes:``\n      any type\n\n"
+         "Types can be combined by the bitwise 'or' operator. For example,\n"
+         "``Space | Frequency`` denotes a spatial axis in the Fourier domain.\n\n")
+        .value("UnknownAxisType", AxisInfo::UnknownAxisType)
+        .value("Channels", AxisInfo::Channels)
+        .value("Space", AxisInfo::Space)
+        .value("Angle", AxisInfo::Angle)
+        .value("Time", AxisInfo::Time)
+        .value("Frequency", AxisInfo::Frequency)
+        .value("NonChannel", AxisInfo::NonChannel)
+        .value("AllAxes", AxisInfo::AllAxes)
+    ;
+
+    class_<AxisInfo>("AxisInfo", 
+         "\n"
+         "An object describing a single axis.\n\nConstructor:\n\n"
+         ".. method:: AxisInfo(key='?', typeFlags=AxisType.UnknownAxisType, resolution=0.0, description='')\n\n"
+         "    :param key: the key of the axis,\n"
+         "                e.g. 'x' (x-axis), 'c' (channel axis), '?' (unknown)\n" 
+         "    :type key: string\n"
+         "    :param typeFlags: the type of the axis,\n"
+         "                      e.g. AxisType.Space or AxisType.Time\n"
+         "    :type typeFlags: :class:`~vigra.AxisType`\n"
+         "    :param resolution: the resolution (step size) of the axis\n"
+         "                       (e.g. 0.0 means 'unknown')\n"
+         "    :param description: an arbitrary string giving additional information \n"
+         "                        about the axis.\n\n"
+         "In addition, AxisInfo defines the following factories for the most common\n"
+         "cases:\n\n"
+         "   ``AxisInfo.c`` or ``AxisInfo.c(description='a description')``:\n"
+         "        Factory for an axisinfo object describing the 'c' (channel) axis.\n"
+         "   ``AxisInfo.x`` or ``AxisInfo.x(resolution=0.0, description='')``:\n"
+         "        Factory for an axisinfo object describing the 'x' (spatial) axis.\n"
+         "   ``AxisInfo.y`` or ``AxisInfo.y(resolution=0.0, description='')``:\n"
+         "        Factory for an axisinfo object describing the 'y' (spatial) axis.\n"
+         "   ``AxisInfo.z`` or ``AxisInfo.z(resolution=0.0, description='')``:\n"
+         "        Factory for an axisinfo object describing the 'z' (spatial) axis.\n"
+         "   ``AxisInfo.t`` or ``AxisInfo.t(resolution=0.0, description='')``:\n"
+         "        Factory for an axisinfo object describing the 't' (time) axis.\n"
+         "   ``AxisInfo.fx`` or ``AxisInfo.fx(resolution=0.0, description='')``:\n"
+         "        Factory for an axisinfo object describing the 'x' axis\n"
+         "        in the Fourier domain.\n"
+         "   ``AxisInfo.fy`` or ``AxisInfo.fy(resolution=0.0, description='')``:\n"
+         "        Factory for an axisinfo object describing the 'y' axis\n"
+         "        in the Fourier domain.\n"
+         "   ``AxisInfo.fz`` or ``AxisInfo.fz(resolution=0.0, description='')``:\n"
+         "        Factory for an axisinfo object describing the 'z' axis\n"
+         "        in the Fourier domain.\n"
+         "   ``AxisInfo.ft`` or ``AxisInfo.ft(resolution=0.0, description='')``:\n"
+         "        Factory for an axisinfo object describing the 't' axis\n"
+         "        in the Fourier domain.\n\n", 
+         no_init)
+        .def(init<std::string, AxisInfo::AxisType, double, std::string>(
+             (arg("key")="?", arg("typeFlags")=AxisInfo::UnknownAxisType, 
+              arg("resolution")=0.0, arg("description")="")))
+        .def(init<AxisInfo const &>())
+        .def_readonly("key", &AxisInfo::key_,
+             "\n(read-only property, type 'string') the key of the axis.\n")
+        .def_readwrite("description", &AxisInfo::description_,
+             "\n(read/write property, type 'string') the string description of the axis.\n")
+        .def_readwrite("resolution", &AxisInfo::resolution_,
+             "\n(read/write property, type 'float') the resolution of the axis. The resolution\n"
+             "will be automatically adjusted whenever the image size changes, e.g. due to a call\n"
+             "to :func:`~vigra.sampling.resize` or slicing with non-unit step size::\n\n"
+             "    >>> a = vigra.RGBImage((200,100))\n"
+             "    >>> a.axistags['x'].resolution = 1.0\n"
+             "    >>> a.axistags['y'].resolution = 1.2\n"
+             "    >>> print a.axistags\n"
+             "    AxisInfo: 'x' (type: Space, resolution=1)\n"
+             "    AxisInfo: 'y' (type: Space, resolution=1.2)\n"
+             "    AxisInfo: 'c' (type: Channels) RGB\n"
+             "    >>> b = a[::2, ::4, :]\n"
+             "    >>> print b.axistags\n"
+             "    AxisInfo: 'x' (type: Space, resolution=2)\n"
+             "    AxisInfo: 'y' (type: Space, resolution=4.8)\n"
+             "    AxisInfo: 'c' (type: Channels) RGB\n\n")
+        .def_readonly("typeFlags", &AxisInfo::flags_,
+             "\n(read-only property, type :class:`~vigra.AxisType`) the type of the axis .\n")
+        .def("toFrequencyDomain", &AxisInfo::toFrequencyDomain, (arg("size") = 0, arg("sign") = 1))
+        .def("fromFrequencyDomain", &AxisInfo::fromFrequencyDomain, (arg("size") = 0))
+        .def("isSpatial", &AxisInfo::isSpatial, 
+             "\naxisinfo.isSSpactial() yields True when :attr:`~vigra.AxisInfo.typeFlags` "
+             "contains AxisType.Space\n")
+        .def("isTemporal", &AxisInfo::isTemporal, 
+             "\naxisinfo.isTemporal() yields True when :attr:`~vigra.AxisInfo.typeFlags` "
+             "contains AxisType.Time\n")
+        .def("isChannel", &AxisInfo::isChannel, 
+             "\naxisinfo.isChannel() yields True when :attr:`~vigra.AxisInfo.typeFlags` "
+             "contains AxisType.Channels\n")
+        .def("isFrequency", &AxisInfo::isFrequency, 
+             "\naxisinfo.isFrequency() yields True when :attr:`~vigra.AxisInfo.typeFlags` "
+             "contains AxisType.Frequency\n")
+        .def("isAngular", &AxisInfo::isAngular, 
+             "\naxisinfo.isAngular() yields True when :attr:`~vigra.AxisInfo.typeFlags` "
+             "contains AxisType.Angle\n")
+        .def("isType", &AxisInfo::isType, 
+             "\naxisinfo.isType(axistype) yields True when :attr:`~vigra.AxisInfo.typeFlags` "
+             "contains the given axistype.\n")
+        .def("compatible", &AxisInfo::compatible, 
+             "\naxisinfo1.compatible(axisinfo2) yields True when the two axisinfo objects "
+             "have the same keys and types, or either of the two is 'unknown'.\n")
+        .def(self == self)
+        .def(self != self)
+        .def(self < self)
+        .def(self <= self)
+        .def(self > self)
+        .def(self >= self)
+        .def("__copy__", &generic__copy__<AxisInfo>)
+        .def("__deepcopy__", &generic__deepcopy__<AxisInfo>)
+        .def("__repr__", &AxisInfo::repr)
+        .def("__call__", &AxisInfo__call__, (arg("resolution") = 0.0, arg("description") = ""))
+        .add_static_property("x", &AxisInfo_x)
+        .add_static_property("y", &AxisInfo_y)
+        .add_static_property("z", &AxisInfo_z)
+        .add_static_property("t", &AxisInfo_t)
+        .add_static_property("fx", &AxisInfo_fx)
+        .add_static_property("fy", &AxisInfo_fy)
+        .add_static_property("fz", &AxisInfo_fz)
+        .add_static_property("ft", &AxisInfo_ft)
+        .add_static_property("c", &AxisInfo_c)
+    ;
+
+    class_<AxisTags >("AxisTags", 
+            "Object to describe axis properties and axis ordering in a "
+            ":class:`~vigra.VigraArray`. \n\nConstructor:\n\n"
+            ".. method:: AxisTags(i1=None, i2=None, i3=None, i4=None, i5=None)\n\n"
+            "    The parameters 'i1'...'i5' are the :class:`~vigra.AxisInfo` objects\n"
+            "    describing the axes. If all are None, an empty AxisTags object is\n"
+            "    created. Alternatively, 'i1' can also be a Python sequence of\n"
+            "    :class:`~vigra.AxisInfo` objects, or an integer (in which case an\n"
+            "    AxisTags object with that many '?' entries is created).\n\n"
+            "Most AxisTags methods should not be called directly, but via the\n"
+            "corresponding array methods, because this ensures that arrays and\n"
+            "their axistags are always kept in sync (rule of thumb: if an axistags\n" 
+            "function is not documented, you call it on your own risk).\n\n"
+            "The entries of an axistags object (i.e. the individual axisinfo objects)\n"
+            "can be accessed via the index operator, where the argument can either be\n"
+            "the axis index or the axis key::\n\n"
+            "    >>> print array.axistags[0]\n"
+            "    AxisInfo: 'x' (type: Space, resolution=1.2)\n"
+            "    >>> print array.axistags['x']\n"
+            "    AxisInfo: 'x' (type: Space, resolution=1.2)\n"
+            "    >>> array.axistags['x'].resolution = 2.0\n"
+            "    >>> print array.axistags['x']\n"
+            "    AxisInfo: 'x' (type: Space, resolution=2)\n\n",
+            no_init)
+        .def("__init__", make_constructor(&AxisTags_create,
+            default_call_policies(),
+            (arg("i1")=object(), arg("i2")=object(), arg("i3")=object(), 
+             arg("i4")=object(), arg("i5")=object())))
+        .def("__repr__", &AxisTags::repr)
+        .def("__str__", &AxisTags_str)
+        .def("__copy__", &generic__copy__<AxisTags>)
+        .def("__deepcopy__", &generic__deepcopy__<AxisTags>)
+        .def("__len__", &AxisTags::size)
+        .def("__getitem__", &AxisTags_getitem, return_internal_reference<>())
+        .def("__getitem__", 
+            (AxisInfo & (AxisTags::*)(std::string const &))&AxisTags::get, return_internal_reference<>())
+        .def("__setitem__", (void (AxisTags::*)(int, AxisInfo const &))&AxisTags::set)
+        .def("__setitem__", 
+            (void (AxisTags::*)(std::string const &, AxisInfo const &))&AxisTags::set)
+        .def("__delitem__", (void (AxisTags::*)(int))&AxisTags::dropAxis)
+        .def("__delitem__", (void (AxisTags::*)(std::string const &))&AxisTags::dropAxis)
+        .def("insert", &AxisTags::insert)
+        .def("append", &AxisTags::push_back)
+        .def("dropChannelAxis", &AxisTags::dropChannelAxis)
+        .def("insertChannelAxis", &AxisTags_insertChannelAxis)
+        .def("swapaxes", &AxisTags::swapaxes)
+        
+        // NOTE: in contrast to arrays, AxisTags::transpose() works
+        //       in-place, i.e. changes 'self'
+        .def("transpose", (void (AxisTags::*)())&AxisTags::transpose)
+        .def("transpose", (void (AxisTags::*)(ArrayVector<npy_intp> const &))&AxisTags::transpose)
+        .def("index", &AxisTags::index,
+             "Get the axis index of a given axis key::\n\n"
+             "    >>> axistags.index('x')\n"
+             "    0\n\n"     
+             "In this example, the 'x'-axis corresponds to index 0 (i.e. the first index).\n")
+        .add_property("channelIndex", &AxisTags::channelIndex,
+            "(read-only property, type 'int') the index of the channel axis, or ``len(axistags)``\n"
+            "when no channel axis exists (i.e. ``axistags.channelIndex`` is similar to\n"
+            "``axistags.index('c')``, but doesn't throw an exception when there\n"
+            "is no 'c' axis.)\n\n")
+        .add_property("innerNonchannelIndex", &AxisTags::innerNonchannelIndex,
+            "(read-only property, type 'int') the index of the innermost non-channel axis.\n")
+        .def("axisTypeCount", &AxisTags::axisTypeCount,
+            "How many axes of the given type(s) are in this axistags object?::\n\n"
+            "    axistags.axisTypeCount(types) -> int\n\n"
+            "The 'types' of the query must be single :class:`~vigra.AxisType` instances\n"
+            "or a combination of them. Examples::\n\n"
+            "    >>> a = vigra.defaultAxistags('txyc')\n"
+            "    >>> a.axisTypeCount(vigra.AxisType.Space)\n"
+            "    2\n"
+            "    >>> a.axisTypeCount(vigra.AxisType.Time)\n"
+            "    1\n"
+            "    >>> a.axisTypeCount(vigra.AxisType(vigra.AxisType.Space | vigra.AxisType.Time))\n"
+            "    3\n"
+            "    >>> a.axisTypeCount(vigra.AxisType.NonChannel)\n"
+            "    3\n\n")
+        
+        // IMPORTANT: do not remove are rename the following functions,
+        //            they are used by the vigranumpy C++ API
+        .def("resolution", (double (AxisTags::*)(int) const)&AxisTags::resolution)
+        .def("resolution", (double (AxisTags::*)(std::string const &) const)&AxisTags::resolution)
+        .def("setResolution", (void (AxisTags::*)(int, double))&AxisTags::setResolution)
+        .def("setResolution", 
+            (void (AxisTags::*)(std::string const &, double))&AxisTags::setResolution)
+        .def("scaleResolution", (void (AxisTags::*)(int, double))&AxisTags::scaleResolution)
+        .def("scaleResolution", 
+            (void (AxisTags::*)(std::string const &, double))&AxisTags::scaleResolution)
+        .def("description", (std::string (AxisTags::*)(int) const)&AxisTags::description)
+        .def("description", 
+             (std::string (AxisTags::*)(std::string const &) const)&AxisTags::description)
+        .def("setDescription", 
+            (void (AxisTags::*)(int, std::string const &))&AxisTags::setDescription)
+        .def("setDescription", 
+            (void (AxisTags::*)(std::string const &, std::string const &))&AxisTags::setDescription)
+        .def("setChannelDescription", &AxisTags::setChannelDescription,
+             "Set a description for the channel axis, if one exists::\n\n"
+             "    axistags.setChannelDescription('colors are in Lab color space')\n\n"
+             "It is similar to::\n\n"
+             "    axistags['c'].description = 'colors are in Lab color space'\n\n"
+             "except when the axistags contain no channel axis, in which case\n"
+             "setChannelDescription() is simply ignored, whereas axistags['c']\n"
+             "would cause an exception.\n")
+        .def("toFrequencyDomain", (void (AxisTags::*)(int, int, int))&AxisTags::toFrequencyDomain,
+                (arg("index"), arg("size")=0, arg("sign")=1))
+        .def("toFrequencyDomain", 
+               (void (AxisTags::*)(std::string const &, int, int))&AxisTags::toFrequencyDomain,
+               (arg("key"), arg("size")=0, arg("sign")=1))
+        .def("fromFrequencyDomain", (void (AxisTags::*)(int, int))&AxisTags::fromFrequencyDomain,
+                (arg("index"), arg("size")=0))
+        .def("fromFrequencyDomain", 
+               (void (AxisTags::*)(std::string const &, int))&AxisTags::fromFrequencyDomain,
+               (arg("key"), arg("size")=0))
+        .def("permutationToNormalOrder", &AxisTags_permutationToNormalOrder)
+        .def("permutationToNormalOrder", &AxisTags_permutationToNormalOrder2)
+        .def("permutationFromNormalOrder", &AxisTags_permutationFromNormalOrder)
+        .def("permutationFromNormalOrder", &AxisTags_permutationFromNormalOrder2)
+        .def("permutationToNumpyOrder", &AxisTags_permutationToNumpyOrder)
+        .def("permutationFromNumpyOrder", &AxisTags_permutationFromNumpyOrder)
+        .def("permutationToVigraOrder", &AxisTags_permutationToVigraOrder)
+        .def("permutationFromVigraOrder", &AxisTags_permutationFromVigraOrder)
+        .def("permutationToOrder", &AxisTags_permutationToOrder)
+        .def("transform", &AxisTags_transform,
+                             return_value_policy<manage_new_object>())
+        .def("compatible", &AxisTags::compatible)
+        .def(self == self)
+        .def(self != self)
+        .def("toJSON", &AxisTags::toJSON,
+             "Create a string representation of this axistags in JSON format.")
+#ifndef VIGRA_DISABLE_FROMJSON
+        .def("fromJSON", &AxisTags_readJSON,
+                             return_value_policy<manage_new_object>())
+        .staticmethod("fromJSON")
+#endif
+        ;
+}
+
+} // namespace vigra
+
diff --git a/vigranumpy/src/core/colors.cxx b/vigranumpy/src/core/colors.cxx
new file mode 100644
index 0000000..9541ab4
--- /dev/null
+++ b/vigranumpy/src/core/colors.cxx
@@ -0,0 +1,639 @@
+
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpycolors_PyArray_API
+//#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/multi_pointoperators.hxx>
+#include <vigra/colorconversions.hxx>
+#include <vigra/mathutil.hxx>
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+template<class ValueType>
+struct BrightnessFunctor
+{
+    double factor, min, max, diff;
+
+    typedef ValueType argument_type;
+    typedef ValueType result_type;
+
+    BrightnessFunctor(double f, double mi, double ma)
+    : factor(0.0), min(mi), max(ma), diff(ma-mi)
+    {
+        vigra_precondition(f > 0.0,
+            "brightness(): Factor must be positive.");
+        vigra_precondition(diff > 0.0,
+            "brightness(): Range upper bound must be greater than lower bound.");
+        factor = 0.25 * diff * std::log(f);
+    }
+
+    result_type operator()(argument_type v) const
+    {
+        double r = v + factor;
+
+        return detail::RequiresExplicitCast<result_type>::cast(
+                   r < min
+                       ? min
+                       : r > max
+                            ? max
+                            : r);
+    }
+};
+
+template<class ValueType>
+struct ContrastFunctor
+{
+    double factor, min, max, diff, offset;
+
+    typedef ValueType argument_type;
+    typedef ValueType result_type;
+
+    ContrastFunctor(double f, double mi, double ma)
+    : factor(f), min(mi), max(ma), diff(0.5*(ma-mi)), offset(diff*(1.0-f))
+    {
+        vigra_precondition(f > 0.0,
+            "contrast(): Factor must be positive.");
+        vigra_precondition(diff > 0.0,
+            "contrast(): Range upper bound must be greater than lower bound.");
+    }
+
+    result_type operator()(argument_type v) const
+    {
+        double r = v * factor + offset;
+
+        return detail::RequiresExplicitCast<result_type>::cast(
+                   r < min
+                       ? min
+                       : r > max
+                            ? max
+                            : r);
+    }
+};
+
+inline
+bool parseRange(python::object range, double * min, double * max,
+                const char * message)
+{
+    if(!range)
+    {
+        return false;
+    }
+    python::extract<std::string> isString(range);
+    if(isString.check())
+    {
+        std::string text(isString());
+        if(text == "" || text == "auto")
+            return false;
+        vigra_precondition(false, message);
+    }
+    python::extract<python::tuple> isTuple(range);
+    if(isTuple.check())
+    {
+        python::extract<double> arg1(isTuple()[0]),
+                                arg2(isTuple()[1]);
+        if(arg1.check() && arg2.check())
+        {
+            *min = arg1();
+            *max = arg2();
+            return true;
+        }
+    }
+    vigra_precondition(false, message);
+    return false;
+}
+
+template < class PixelType, unsigned int N>
+NumpyAnyArray
+pythonBrightnessTransform(NumpyArray<N, Multiband<PixelType> > image,
+                          double factor,
+                          python::object range,
+                          NumpyArray<N, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(image.taggedShape(),
+            "brightness(): Output images has wrong dimensions");
+
+    double min = 0.0, max = 0.0;
+    bool computeRange = !parseRange(range, &min, &max, "brightness(): Invalid range argument.");
+    
+    {
+        PyAllowThreads _pythread;
+        if(computeRange)
+        {
+            FindMinMax<PixelType> minmax;
+            inspectMultiArray(srcMultiArrayRange(image), minmax);
+            min = minmax.min;
+            max = minmax.max;
+        }
+
+        vigra_precondition(min < max,
+              "brightness(): Range upper bound must be greater than lower bound.");
+
+        transformMultiArray(srcMultiArrayRange(image), destMultiArray(res),
+                            BrightnessFunctor<PixelType>(factor, min, max));
+    }
+    return res;
+}
+
+template < class PixelType, unsigned int N>
+NumpyAnyArray
+pythonContrastTransform(NumpyArray<N, Multiband<PixelType> > image,
+                        double factor,
+                        python::object range,
+                        NumpyArray<N, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(image.taggedShape(),
+            "contrast(): Output images has wrong dimensions");
+
+    double min = 0.0, max = 0.0;
+    bool computeRange = !parseRange(range, &min, &max, "contrast(): Invalid range argument.");
+    {
+        PyAllowThreads _pythread;
+        if(computeRange)
+        {
+            FindMinMax<PixelType> minmax;
+            inspectMultiArray(srcMultiArrayRange(image), minmax);
+            min = minmax.min;
+            max = minmax.max;
+        }
+
+        vigra_precondition(min < max,
+              "contrast(): Range upper bound must be greater than lower bound.");
+
+        transformMultiArray(srcMultiArrayRange(image), destMultiArray(res),
+                            ContrastFunctor<PixelType>(factor, min, max));
+    }
+    return res;
+}
+
+template < class PixelType, unsigned int N>
+NumpyAnyArray
+pythonGammaTransform(NumpyArray<N, Multiband<PixelType> > image,
+                     double gamma,
+                     python::object range,
+                     NumpyArray<N, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(image.taggedShape(),
+            "gamma_correction(): Output images has wrong dimensions");
+
+    double min = 0.0, max = 0.0;
+    bool computeRange = !parseRange(range, &min, &max, "gamma_correction(): Invalid range argument.");    
+    {
+        PyAllowThreads _pythread;
+        if(computeRange)
+        {
+            FindMinMax<PixelType> minmax;
+            inspectMultiArray(srcMultiArrayRange(image), minmax);
+            min = minmax.min;
+            max = minmax.max;
+        }
+
+        vigra_precondition(min < max,
+              "gamma_correction(): Range upper bound must be greater than lower bound.");
+
+        transformMultiArray(srcMultiArrayRange(image), destMultiArray(res),
+                            GammaFunctor<PixelType>(1.0 / gamma, PixelType(min), PixelType(max)));
+    }
+    return res;
+}
+
+template < class SrcPixelType, class DestPixelType, unsigned int N>
+NumpyAnyArray
+pythonLinearRangeMapping(NumpyArray<N, Multiband<SrcPixelType> > image,
+                         python::object oldRange,
+                         python::object newRange,
+                         NumpyArray<N, Multiband<DestPixelType> > res)
+{
+    res.reshapeIfEmpty(image.taggedShape(),
+        "linearRangeMapping(): Output images has wrong dimensions");
+
+    double oldMin = 0.0, oldMax = 0.0,
+           newMin = 0.0, newMax = 0.0;
+    bool computeRange = !parseRange(oldRange, &oldMin, &oldMax, 
+                                    "linearRangeMapping(): Argument 'oldRange' is invalid.");
+    if(!parseRange(newRange, &newMin, &newMax, "linearRangeMapping(): Argument 'newRange' is invalid."))
+    {
+        newMin = 0.0;
+        newMax = 255.0;
+    }
+    
+    {
+        PyAllowThreads _pythread;
+        if(computeRange)
+        {
+            FindMinMax<SrcPixelType> minmax;
+            inspectMultiArray(srcMultiArrayRange(image), minmax);
+            oldMin = minmax.min;
+            oldMax = minmax.max;
+        }
+        
+        vigra_precondition(oldMin < oldMax && newMin < newMax,
+              "linearRangeMapping(): Range upper bound must be greater than lower bound.");
+
+        transformMultiArray(srcMultiArrayRange(image), destMultiArray(res),
+                            linearRangeMapping(oldMin, oldMax, newMin, newMax));
+    }
+    
+    return res;
+}
+
+
+template < class PixelType, unsigned int N, class Functor >
+NumpyAnyArray
+pythonColorTransform(NumpyArray<N, TinyVector<PixelType, 3> > image,
+                     NumpyArray<N, TinyVector<PixelType, 3> > res)
+{
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(Functor::targetColorSpace()),
+        "colorTransform(): Output images has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        transformMultiArray(srcMultiArrayRange(image), destMultiArray(res), Functor());
+    }
+    return res;
+}
+
+#define exportColorTransform(name) \
+def("transform_" #name, registerConverters(&pythonColorTransform<float, 2, name##Functor<float> >), \
+    (arg("image"), arg("out")=object()), \
+    "Convert the colors of the given 'image' using " #name "Functor.\n" \
+    "\n" \
+    "For details see " #name "Functor_ in the C++ documentation.\n")
+
+template<class T>
+NumpyAnyArray pythonApplyColortable(const NumpyArray<2, Singleband<T> >& valueImage, 
+                                    const NumpyArray<2, UInt8>& colortable,
+                                    NumpyArray<3, Multiband<npy_uint8> > res =  NumpyArray<3, Multiband<npy_uint8> >())
+{
+    vigra_precondition(!colortable.axistags(),
+                       "applyColortable(): colortable must not have axistags\n"
+                       "(use 'array.view(numpy.ndarray)' to remove them).");
+    
+    // Singleband: there is only a singleton channel axis (which is removed when converted from python numpy array to C++
+    // Multiband: channel axis is allowed to be singleband, but does not have to be,
+    //            will be last when converted Python -> C++ and channel axis is counted in the dimension ('3')
+    typedef NumpyArray<2, Singleband<T> > InputType;
+    
+    res.reshapeIfEmpty(valueImage.taggedShape().setChannelCount(colortable.shape(1)),
+                       "pythonApplyColortable: shape of res is wrong");
+    
+    const unsigned int N = colortable.shape(0);
+   
+    for(MultiArrayIndex c=0; c<colortable.shape(1); ++c)
+    {
+        MultiArrayView<2, UInt8>::iterator channelIter = res.bind<2>(c).begin();
+        
+        //make an unstrided copy of the current column of the colortable
+        ArrayVector<UInt8> ctable(colortable.bind<1>(c).begin(), colortable.bind<1>(c).end());
+        
+        for(typename InputType::const_iterator v = valueImage.begin(); v != valueImage.end(); ++v, ++channelIter)
+        {
+            const_cast<UInt8 &>(*channelIter) = ctable[*v % N];
+        }
+    }
+    
+    return res;
+}
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pyApplyColortable, pythonApplyColortable)
+
+template<class T>
+void pythonGray2QImage_ARGB32Premultiplied(
+    const NumpyArray<2, Singleband<T> >& image, 
+    NumpyArray<3, Multiband<npy_uint8> > qimageView,
+    NumpyArray<1, T> normalize = boost::python::object()
+) 
+{
+    vigra_precondition(image.isUnstrided() || image.transpose().isUnstrided(),
+        "gray2qimage_ARGB32Premultiplied(): Can only handle arrays with contiguous memory.");
+    typedef typename NumericTraits<T>::RealPromote TmpType;
+    
+    T* data = image.data(); 
+    const T* dataEnd = data+image.size();
+    UInt8* imgData = qimageView.data();
+    UInt8 pixel = 0;
+    TmpType pixelF;
+    
+    TmpType normalizeLow, normalizeHigh; 
+    if(normalize != boost::python::object())
+    {
+        vigra_precondition(normalize.shape(0) == 2,
+            "gray2qimage_ARGB32Premultiplied(): normalize.shape[0] == 2 required.");
+            
+        //normalize = None
+        normalizeLow = normalize[0];
+        normalizeHigh = normalize[1];
+        
+        vigra_precondition(normalizeHigh > normalizeLow,
+            "gray2qimage_ARGB32Premultiplied(): normalize[0] < normalize[1] is required.");
+            
+        const TmpType f = TmpType(255) / static_cast<TmpType>(normalizeHigh-normalizeLow);
+        
+        while(data < dataEnd) 
+        {
+            pixelF = detail::RequiresExplicitCast<TmpType>::cast(*data);
+            
+            if(pixelF < normalizeLow) 
+            {
+                pixel = 0;
+            }
+            else if(pixelF > normalizeHigh) 
+            {
+                pixel = 255;
+            }
+            else
+            {
+                pixel = detail::RequiresExplicitCast<UInt8>::cast((pixelF-normalizeLow)*f);
+            }
+            *imgData = pixel; ++imgData; //B
+            *imgData = pixel; ++imgData; //G
+            *imgData = pixel; ++imgData; //R
+            *imgData = 255;   ++imgData; //A
+            ++data;
+        }
+    }
+    else 
+    {
+        while(data < dataEnd) 
+        {
+            pixel = detail::RequiresExplicitCast<UInt8>::cast(*data);
+            *imgData = pixel; ++imgData; //B
+            *imgData = pixel; ++imgData; //G
+            *imgData = pixel; ++imgData; //R
+            *imgData = 255;   ++imgData; //A
+            ++data;
+        }
+    }
+}
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pyGray2QImage_ARGB32Premultiplied, pythonGray2QImage_ARGB32Premultiplied)
+
+template<class T>
+void pythonAlphaModulated2QImage_ARGB32Premultiplied(
+    const NumpyArray<2, Singleband<T> >& image, 
+    NumpyArray<3, Multiband<npy_uint8> > qimageView,
+    NumpyArray<1, float> tintColor,
+    NumpyArray<1, T> normalize
+) 
+{
+    vigra_precondition(image.isUnstrided() || image.transpose().isUnstrided(),
+        "alphamodulated2qimage_ARGB32Premultiplied(): Can only handle arrays with contiguous memory.");
+    typedef typename NumericTraits<T>::RealPromote TmpType;
+    
+    vigra_precondition(normalize.shape(0) == 2,
+        "alphamodulated2qimage_ARGB32Premultiplied(): normalize.shape[0] == 2 required.");
+    vigra_precondition(tintColor.shape(0) == 3,
+        "alphamodulated2qimage_ARGB32Premultiplied(): tintColor.shape[0] == 3 required.");
+            
+    const TmpType l = normalize[0];
+    const TmpType h = normalize[1];
+    
+    vigra_precondition(h > l,
+        "alphamodulated2qimage_ARGB32Premultiplied(): normalize[0] < normalize[1] is required.");
+    
+    const TmpType r = tintColor[0];
+    const TmpType g = tintColor[1];
+    const TmpType b = tintColor[2];
+    
+    T* data = image.data();
+    const T* dataEnd = image.data()+image.size();
+    unsigned char* imgData = qimageView.data();
+    TmpType pixelF;
+    const TmpType f = TmpType(255) / static_cast<TmpType>(h-l);
+    while(data < dataEnd) 
+    {
+        pixelF = detail::RequiresExplicitCast<TmpType>::cast(*data);
+        if(pixelF < l)
+        {
+            pixelF = TmpType();
+        }
+        else if(pixelF > h)
+        {
+            pixelF = TmpType(255);
+        }
+        else
+        {
+            pixelF = (pixelF-l)*f;
+        }
+        *imgData = detail::RequiresExplicitCast<UInt8>::cast(pixelF*b); ++imgData; //B
+        *imgData = detail::RequiresExplicitCast<UInt8>::cast(pixelF*g); ++imgData; //G
+        *imgData = detail::RequiresExplicitCast<UInt8>::cast(pixelF*r); ++imgData; //R
+        *imgData = detail::RequiresExplicitCast<UInt8>::cast(pixelF);   ++imgData; //A
+        ++data;
+    }
+}
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pyAlphaModulated2QImage_ARGB32Premultiplied, pythonAlphaModulated2QImage_ARGB32Premultiplied)
+
+void defineColors()
+{
+    using namespace python;
+
+    docstring_options doc_options(true, true, false);
+
+    multidef("applyColortable", pyApplyColortable<vigra::UInt8, vigra::Int16, vigra::UInt16, vigra::Int32, vigra::UInt32>(),
+        (arg("valueImage"), 
+        arg("colortable"),
+        arg("out")=python::object()), 
+        "Applies a colortable to the given 2D valueImage.\n\n"
+        "Colortable must have 4 columns, each row represents a color (for example, RGBA).\n"
+        "Values in valueImage are first taken module the length of the colortable.\n\n"
+        "Returns: uint8 image with 4 channels\n");
+    
+    multidef("gray2qimage_ARGB32Premultiplied", pyGray2QImage_ARGB32Premultiplied<vigra::UInt8, vigra::Int16, vigra::UInt16, vigra::Int32, vigra::UInt32, float, double>(),
+        (arg("image"), 
+        arg("qimage"),
+        arg("normalize")=python::object()), 
+        "Convert the image (single-band) into a QImage of format Format_ARGB32_Premultiplied.\n"
+        "\n"
+        "import qimage2ndarray\n"
+        "qimg = QImage(a.shape[0], a.shape[1], QImage.Format_ARGB32_Premultiplied)\n"
+        "normalize = numpy.asarray([10, 217], dtype=image.dtype)\n"
+        "vigra.colors.gray2qimage_ARGB32Premultiplied(a, qimage2ndarray.byte_view(qimg), normalize)\n");
+    
+    multidef("alphamodulated2qimage_ARGB32Premultiplied", pyAlphaModulated2QImage_ARGB32Premultiplied<vigra::UInt8, vigra::Int16, vigra::UInt16, vigra::Int32, vigra::UInt32, float, double>(),
+        (arg("image"), 
+        arg("qimage"),
+        arg("tintColor"),
+        arg("normalize")), 
+        "Convert the image (single-band) into a QImage of format Format_ARGB32_Premultiplied.\n"
+        "\n"
+        "import qimage2ndarray\n"
+        "qimg = QImage(a.shape[0], a.shape[1], QImage.Format_ARGB32_Premultiplied)\n"
+        "normalize = numpy.asarray([10, 217], dtype=image.dtype)\n"
+        "tintColor = numpy.asarray([1.0, 0.0, 0.0], dtype=numpy.float32) #RGB\n"
+        "vigra.colors.alphamodulated2qimage_ARGB32Premultiplied(a, qimage2ndarray.byte_view(qimg), tintColor, normalize)\n");
+    
+    def("brightness",
+         registerConverters(&pythonBrightnessTransform<float, 3>),
+         (arg("image"), arg("factor"), arg("range")=make_tuple(0.0, 255.0), arg("out")=object()),
+        "Adjust the brightness of a 2D scalar or multiband image. The function applies the formula::\n"
+        "\n"
+        "   out = image + 0.25 * log(factor) * (range[1] - range[0])\n"
+        "\n"
+        "to each element of the array. 'factor' and 'range[1] - range[0]' must be "
+        "positive. Elements outside the given range are clipped at the range borders. "
+        "If 'range' is None or \"\" or \"auto\", the range is set to the actual range "
+        "of 'image'::\n"
+        "\n"
+        "   range = image.min(), image.max()\n\n");
+
+    def("brightness",
+         registerConverters(&pythonBrightnessTransform<float, 4>),
+         (arg("volume"), arg("factor"), arg("range")=make_tuple(0.0, 255.0), arg("out")=object()),
+         "Likewise for a 3D scalar or multiband volume.\n");
+
+    def("contrast",
+         registerConverters(&pythonContrastTransform<float, 3>),
+         (arg("image"), arg("factor"), arg("range")=make_tuple(0.0, 255.0), arg("out")=object()),
+        "Adjust the contrast of an image or volume. The function applies the formula::\n"
+        "\n"
+        "    out = factor * image + (1.0 - factor) * (range[1] - range[0]) / 2.0\n"
+        "\n"
+        "to each element of the array. 'factor' and 'range[1] - range[0]' must be "
+        "positive. Elements outside the given range are clipped at the range borders. "
+        "If 'range' is None or \"\" or \"auto\", the range is set to the actual range "
+        "of 'image'::\n"
+        "\n"
+        "   range = image.min(), image.max()\n\n");
+
+    def("contrast",
+         registerConverters(&pythonContrastTransform<float, 4>),
+         (arg("volume"), arg("factor"), arg("range")=make_tuple(0.0, 255.0), arg("out")=object()),
+         "Likewise for a 3D scalar or multiband volume.\n");
+
+    def("gammaCorrection",
+         registerConverters(&pythonGammaTransform<float, 3>),
+         (arg("image"), arg("gamma"), arg("range")=make_tuple(0.0, 255.0), arg("out")=object()),
+        "Adjust gamma correction to an image or volume. The function applies the formula::\n"
+        "\n"
+        "    diff = range[1] - range[0]\n"
+        "    out = pow((image - range[0]) / diff, 1.0 / gamma) * diff + range[0]\n"
+        "\n"
+        "to each element of the array. 'gamma' and 'range[1] - range[0]' must be "
+        "positive. Elements outside the given range are clipped at the range borders. "
+        "If 'range' is None or \"\" or \"auto\", the range is set to the actual range "
+        "of 'image'::\n"
+        "\n"
+        "   range = image.min(), image.max()\n\n");
+
+    def("gammaCorrection",
+         registerConverters(&pythonGammaTransform<float, 4>),
+         (arg("volume"), arg("gamma"), arg("range")=make_tuple(0.0, 255.0), arg("out")=object()),
+         "Likewise for a 3D scalar or multiband volume.\n");
+
+    def("linearRangeMapping",
+         registerConverters(&pythonLinearRangeMapping<float, UInt8, 3>),
+         (arg("image"), arg("oldRange")="auto", arg("newRange")=make_tuple(0.0, 255.0), arg("out")=object()),
+        "Convert the intensity range of a 2D scalar or multiband image. The function applies a linear transformation "
+        "to the intensities such that the value oldRange[0] is mapped onto newRange[0], "
+        "and oldRange[1] is mapped onto newRange[1]. That is, the algorithm applies the formula::\n"
+        "\n"
+        "    oldDiff = oldRange[1] - oldRange[0]\n"
+        "    newDiff = newRange[1] - newRange[0]\n"
+        "    out = (image - oldRange[0]) / oldDiff * newDiff + newRange[0]\n"
+        "\n"
+        "to each element of the array. 'oldDiff' and 'newDiff' must be "
+        "positive. If 'oldRange' is None or \"\" or \"auto\" (the default), the range is set to "
+        "the actual range of 'image'::\n"
+        "\n"
+        "   range = image.min(), image.max()\n\n"
+        "If 'newRange' is None or \"\" or \"auto\", it is set to (0, 255.0). "
+        "If 'out' is explicitly passed, it must be a uin8 image.\n");
+
+    def("linearRangeMapping",
+         registerConverters(&pythonLinearRangeMapping<float, float, 3>),
+         (arg("image"), arg("oldRange")="auto", arg("newRange")=make_tuple(0.0, 255.0), arg("out")=object()),
+         "Likewise, but 'out' is a float32 image.\n");
+
+    def("linearRangeMapping",
+         registerConverters(&pythonLinearRangeMapping<float, UInt8, 4>),
+         (arg("volume"), arg("oldRange")="auto", arg("newRange")=make_tuple(0.0, 255.0), arg("out")=object()),
+         "Likewise for a 3D scalar or multiband volume, when 'out' is a unit8 volume.\n");
+
+    def("linearRangeMapping",
+         registerConverters(&pythonLinearRangeMapping<float, float, 4>),
+         (arg("volume"), arg("oldRange")="auto", arg("newRange")=make_tuple(0.0, 255.0), arg("out")=object()),
+         "Likewise, but 'out' is a float32 volume.\n");
+
+
+    exportColorTransform(RGB2sRGB);
+    exportColorTransform(sRGB2RGB);
+    exportColorTransform(RGB2RGBPrime);
+    exportColorTransform(RGBPrime2RGB);
+
+    exportColorTransform(RGB2XYZ);
+    exportColorTransform(RGBPrime2XYZ);
+    exportColorTransform(XYZ2RGB);
+    exportColorTransform(XYZ2RGBPrime);
+
+    exportColorTransform(RGB2Lab);
+    exportColorTransform(RGBPrime2Lab);
+    exportColorTransform(XYZ2Lab);
+    exportColorTransform(Lab2RGB);
+    exportColorTransform(Lab2RGBPrime);
+    exportColorTransform(Lab2XYZ);
+
+    exportColorTransform(RGB2Luv);
+    exportColorTransform(RGBPrime2Luv);
+    exportColorTransform(XYZ2Luv);
+    exportColorTransform(Luv2RGB);
+    exportColorTransform(Luv2RGBPrime);
+    exportColorTransform(Luv2XYZ);
+
+    exportColorTransform(RGBPrime2YPrimePbPr);
+    exportColorTransform(YPrimePbPr2RGBPrime);
+    exportColorTransform(RGBPrime2YPrimeCbCr);
+    exportColorTransform(YPrimeCbCr2RGBPrime);
+
+    exportColorTransform(RGBPrime2YPrimeUV);
+    exportColorTransform(YPrimeUV2RGBPrime);
+    exportColorTransform(RGBPrime2YPrimeIQ);
+    exportColorTransform(YPrimeIQ2RGBPrime);
+}
+
+} // namespace vigra
+
+using namespace vigra;
+using namespace boost::python;
+
+BOOST_PYTHON_MODULE_INIT(colors)
+{
+    import_vigranumpy();
+    defineColors();
+}
diff --git a/vigranumpy/src/core/converters.cxx b/vigranumpy/src/core/converters.cxx
new file mode 100644
index 0000000..3677188
--- /dev/null
+++ b/vigranumpy/src/core/converters.cxx
@@ -0,0 +1,425 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2009 by Ullrich Koethe and Hans Meine                */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpycore_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include <Python.h>
+#include <vigra/matrix.hxx>
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <boost/python.hpp>
+#include <boost/python/to_python_converter.hpp>
+
+namespace python = boost::python;
+
+namespace vigra {
+
+#define VIGRA_NUMPY_TYPECHECKER(type) \
+    if(python::object((python::detail::new_reference)PyArray_TypeObjectFromType(type)).ptr() == obj) \
+        return obj;
+        
+#define VIGRA_NUMPY_TYPECONVERTER(type) \
+    if(python::object((python::detail::new_reference)PyArray_TypeObjectFromType(type)).ptr() == obj) \
+        typeID = type;
+        
+struct NumpyTypenumConverter
+{
+    NumpyTypenumConverter()
+    {
+        python::converter::registry::insert(&convertible, &construct, 
+                                            python::type_id<NPY_TYPES>());
+        python::to_python_converter<NPY_TYPES, NumpyTypenumConverter>();
+    }
+        
+    static void* convertible(PyObject* obj)
+    {
+        // FIXME: there should be a more elegant way to program this...
+        if(obj == 0)
+            return 0;
+        if(obj->ob_type == &PyArrayDescr_Type)
+            return obj;
+        if(!PyType_Check(obj))
+            return 0;
+        VIGRA_NUMPY_TYPECHECKER(NPY_BOOL)
+        VIGRA_NUMPY_TYPECHECKER(NPY_INT8)
+        VIGRA_NUMPY_TYPECHECKER(NPY_UINT8)
+        VIGRA_NUMPY_TYPECHECKER(NPY_INT16)
+        VIGRA_NUMPY_TYPECHECKER(NPY_UINT16)
+        VIGRA_NUMPY_TYPECHECKER(NPY_INT32)
+        VIGRA_NUMPY_TYPECHECKER(NPY_UINT32)
+        VIGRA_NUMPY_TYPECHECKER(NPY_INT)
+        VIGRA_NUMPY_TYPECHECKER(NPY_UINT)
+        VIGRA_NUMPY_TYPECHECKER(NPY_INT64) 
+        VIGRA_NUMPY_TYPECHECKER(NPY_UINT64)
+        VIGRA_NUMPY_TYPECHECKER(NPY_FLOAT32)
+        VIGRA_NUMPY_TYPECHECKER(NPY_FLOAT64)
+        VIGRA_NUMPY_TYPECHECKER(NPY_LONGDOUBLE)
+        VIGRA_NUMPY_TYPECHECKER(NPY_CFLOAT)
+        VIGRA_NUMPY_TYPECHECKER(NPY_CDOUBLE)
+        VIGRA_NUMPY_TYPECHECKER(NPY_CLONGDOUBLE)
+        return 0;
+    }
+
+    // from Python
+    static void construct(PyObject* obj, 
+        python::converter::rvalue_from_python_stage1_data* data)
+    {
+        void* const storage =   
+            ((python::converter::rvalue_from_python_storage<NumpyAnyArray>* ) data)->storage.bytes;
+
+        // FIXME: there should be a more elegant way to program this...
+        int typeID = -1;
+        if(obj->ob_type == &PyArrayDescr_Type)
+            typeID = (NPY_TYPES)((PyArray_Descr*)obj)->type_num;
+        VIGRA_NUMPY_TYPECONVERTER(NPY_BOOL)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_INT8)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_UINT8)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_INT16)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_UINT16)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_INT32)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_UINT32)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_INT)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_UINT)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_INT64) 
+        VIGRA_NUMPY_TYPECONVERTER(NPY_UINT64)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_FLOAT32)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_FLOAT64)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_LONGDOUBLE)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_CFLOAT)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_CDOUBLE)
+        VIGRA_NUMPY_TYPECONVERTER(NPY_CLONGDOUBLE)
+
+        new (storage) NPY_TYPES((NPY_TYPES)typeID);
+
+        data->convertible = storage;
+    }
+
+    // to Python
+    static PyObject* convert(NPY_TYPES typeID)
+    {
+        return PyArray_TypeObjectFromType(typeID);
+    }
+};
+
+#undef VIGRA_NUMPY_TYPECHECKER
+#undef VIGRA_NUMPY_TYPECONVERTER
+
+struct NumpyAnyArrayConverter
+{
+    NumpyAnyArrayConverter()
+    {
+        python::converter::registry::insert(&convertible, &construct, 
+                                            python::type_id<NumpyAnyArray>());
+        python::to_python_converter<NumpyAnyArray, NumpyAnyArrayConverter>();
+    }
+        
+    static void* convertible(PyObject* obj)
+    {
+        return obj && (obj == Py_None || PyArray_Check(obj))
+                 ? obj
+                 : 0;
+    }
+
+    // from Python
+    static void construct(PyObject* obj, 
+        python::converter::rvalue_from_python_stage1_data* data)
+    {
+        void* const storage =   
+            ((python::converter::rvalue_from_python_storage<NumpyAnyArray>* ) data)->storage.bytes;
+
+        if(obj == Py_None)
+            obj = 0;
+            
+        new (storage) NumpyAnyArray(obj);
+
+        data->convertible = storage;
+    }
+    
+    static PyObject* convert(NumpyAnyArray const& a)
+    {
+        return returnNumpyArray(a);
+    }
+};
+
+namespace detail {
+
+template <int N, class T>
+struct MultiArrayShapeConverterTraits
+{
+    typedef TinyVector<T, N> ShapeType;
+
+    static void construct(void* const storage, PyObject * obj)
+    {
+        ShapeType * shape = new (storage) ShapeType();
+        for(int i=0; i<PySequence_Length(obj); ++i)
+            (*shape)[i] = python::extract<T>(PySequence_ITEM(obj, i));
+    }
+};
+
+template <class T>
+struct MultiArrayShapeConverterTraits<0, T>
+{
+    typedef ArrayVector<T> ShapeType;
+
+    static void construct(void* const storage, PyObject * obj)
+    {
+        int len = (obj == Py_None)
+                           ? 0
+                           : PySequence_Length(obj);
+        ShapeType * shape = new (storage) ShapeType(len);
+        for(int i=0; i<len; ++i)
+            (*shape)[i] = python::extract<T>(PySequence_ITEM(obj, i));
+    }
+};
+
+} // namespace detail
+
+
+template <int M, class T>
+struct MultiArrayShapeConverter
+{
+
+    typedef typename detail::MultiArrayShapeConverterTraits<M, T>::ShapeType ShapeType;
+    
+    MultiArrayShapeConverter()
+    {
+        python::converter::registry::insert(&convertible, &construct, 
+                                            python::type_id<ShapeType>());
+        python::to_python_converter<ShapeType, MultiArrayShapeConverter>();
+    }
+        
+    static void* convertible(PyObject* obj)
+    {
+        if(obj == 0)
+            return 0;
+        if(M == 0 && obj == Py_None)
+            return obj;
+        if(!PySequence_Check(obj) || (M != 0 && PySequence_Length(obj) != M))
+            return 0;
+        for(int i=0; i<PySequence_Length(obj); ++i)
+            if(!PyNumber_Check(PySequence_ITEM(obj, i)))
+                return 0;
+        return obj;
+    }
+
+    // from Python
+    static void construct(PyObject* obj, 
+        python::converter::rvalue_from_python_stage1_data* data)
+    {
+        void* const storage =   
+            ((python::converter::rvalue_from_python_storage<ShapeType>* ) data)->storage.bytes;
+
+        detail::MultiArrayShapeConverterTraits<M, T>::construct(storage, obj);
+        data->convertible = storage;
+    }
+
+    // to Python
+    static PyObject* convert(ShapeType const& shape)
+    {
+        return shapeToPythonTuple(shape).release();
+    }
+};
+
+python_ptr point2DToPythonTuple(Point2D const & point)
+{
+    python_ptr tuple(PyTuple_New(2), python_ptr::keep_count);
+    pythonToCppException(tuple);
+    PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), 0 ,pythonFromData(point.x).release());
+    PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), 1 ,pythonFromData(point.y).release());
+    return tuple;
+}
+
+struct Point2DConverter
+{
+    Point2DConverter()
+    {
+        python::converter::registry::insert(&convertible, &construct,
+                                            python::type_id<Point2D>());
+        python::to_python_converter<Point2D, Point2DConverter>();
+    }
+
+    static void* convertible(PyObject* obj)
+    {
+        if(obj == 0 || !PySequence_Check(obj) || (PySequence_Length(obj) !=2))
+            return 0;
+        if(!PyNumber_Check(PySequence_Fast_GET_ITEM(obj,0)))
+            return 0;
+        if(!PyNumber_Check(PySequence_Fast_GET_ITEM(obj,0)))
+            return 0;
+        return obj;
+    }
+
+    //from python
+    static void construct(PyObject* obj, python::converter::rvalue_from_python_stage1_data* data)
+    {
+        void* const storage = 
+            ((python::converter::rvalue_from_python_storage<Point2D>*) data)->storage.bytes;
+        new (storage) Point2D(python::extract<int>(PySequence_Fast_GET_ITEM(obj,0)),
+                              python::extract<int>(PySequence_Fast_GET_ITEM(obj,1)));
+        data->convertible = storage;
+    }
+
+    //to python
+    static PyObject* convert(Point2D const& p)
+    {
+        return point2DToPythonTuple(p).release();
+    }
+
+};
+
+void registerNumpyPoint2DConverter()
+{
+    Point2DConverter();
+}
+
+template <class T>
+void registerNumpyShapeConvertersOneType()
+{
+    MultiArrayShapeConverter<0, T>();
+    MultiArrayShapeConverter<1, T>();
+    MultiArrayShapeConverter<2, T>();
+    MultiArrayShapeConverter<3, T>();
+    MultiArrayShapeConverter<4, T>();
+    MultiArrayShapeConverter<5, T>();
+    MultiArrayShapeConverter<6, T>();
+    MultiArrayShapeConverter<7, T>();
+}
+
+void registerNumpyShapeConvertersAllTypes()
+{
+    registerNumpyShapeConvertersOneType<MultiArrayIndex>();
+    registerNumpyShapeConvertersOneType<float>();
+    registerNumpyShapeConvertersOneType<double>();
+    registerNumpyShapeConvertersOneType<short>();
+    if(typeid(npy_intp) != typeid(MultiArrayIndex))
+        MultiArrayShapeConverter<0, npy_intp>();
+}
+
+#if 0 // FIXME: reimplement to replace the Python versions for consistence?
+PyObject * 
+constructNumpyArrayFromShape(python::object type, ArrayVector<npy_intp> const & shape, 
+                       unsigned int spatialDimensions, unsigned int channels,
+                       NPY_TYPES typeCode, std::string order, bool init)
+{
+    PyObject * obj = type.ptr();
+    vigra_precondition(obj && PyType_Check(obj) && PyType_IsSubtype((PyTypeObject *)obj, &PyArray_Type),
+           "constructNumpyArray(type, ...): first argument was not an array type.");
+    return detail::constructNumpyArrayImpl((PyTypeObject *)obj, shape, spatialDimensions, channels, typeCode, order, init).release();
+}
+
+PyObject * 
+constructNumpyArrayFromArray(python::object type, NumpyAnyArray array, 
+                       unsigned int spatialDimensions, unsigned int channels,
+                       NPY_TYPES typeCode, std::string order, bool init)
+{
+    PyObject * obj = type.ptr();
+    vigra_precondition(obj && PyType_Check(obj) && PyType_IsSubtype((PyTypeObject *)obj, &PyArray_Type),
+           "constructNumpyArray(type, ...): first argument was not an array type.");
+    PyObject * res = detail::constructNumpyArrayImpl((PyTypeObject *)obj, array.shape(), spatialDimensions, channels, 
+                                                     typeCode, order, false, array.strideOrdering()).release();
+    if(init)
+    {
+        NumpyAnyArray lhs(res);
+        lhs = array;
+    }
+    return res;
+}
+#endif
+
+PyObject * 
+constructArrayFromAxistags(python::object type, ArrayVector<npy_intp> const & shape, 
+                           NPY_TYPES typeCode, AxisTags const & axistags, bool init)
+{
+    PyAxisTags pyaxistags(python_ptr(python::object(axistags).ptr()));
+    
+    ArrayVector<npy_intp> norm_shape(shape);
+    if(pyaxistags.size() > 0)
+    {
+        ArrayVector<npy_intp> permutation(pyaxistags.permutationToNormalOrder());
+        applyPermutation(permutation.begin(), permutation.end(), shape.begin(), norm_shape.begin());
+    }
+    
+    TaggedShape tagged_shape(norm_shape, pyaxistags);
+    // FIXME: check that type is an array class?
+    return constructArray(tagged_shape, typeCode, init, python_ptr(type.ptr()));
+}
+
+template <class T>
+struct MatrixConverter
+{
+    typedef linalg::Matrix<T> ArrayType;
+    
+    MatrixConverter();
+        
+    // to Python
+    static PyObject* convert(ArrayType const& a)
+    {
+        return returnNumpyArray(NumpyArray<2, T>(a));
+    }
+};
+
+template <class T>
+MatrixConverter<T>::MatrixConverter()
+{
+    using namespace boost::python;
+    
+    converter::registration const * reg = converter::registry::query(type_id<ArrayType>());
+    
+    // register the to_python_converter only once
+    if(!reg || !reg->rvalue_chain)
+    {
+        to_python_converter<ArrayType, MatrixConverter>();
+    }
+}
+
+void registerNumpyArrayConverters()
+{
+    NumpyTypenumConverter();
+    registerNumpyShapeConvertersAllTypes();
+    registerNumpyPoint2DConverter();
+    NumpyAnyArrayConverter();
+    MatrixConverter<float>();
+    MatrixConverter<double>();
+    
+    python::docstring_options doc_options(true, true, false);
+        
+    doc_options.disable_all();
+    python::def("constructArrayFromAxistags", &constructArrayFromAxistags);
+    // python::def("constructNumpyArray", &constructNumpyArrayFromArray);
+}
+
+} // namespace vigra
+
diff --git a/vigranumpy/src/core/convolution.cxx b/vigranumpy/src/core/convolution.cxx
new file mode 100644
index 0000000..40f5908
--- /dev/null
+++ b/vigranumpy/src/core/convolution.cxx
@@ -0,0 +1,761 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyfilters_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include <Python.h>
+#include <vigra/config.hxx>
+#include <boost/python.hpp>
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/functorexpression.hxx>
+#include <vigra/convolution.hxx>
+#include <vigra/multi_convolution.hxx>
+#include <vigra/recursiveconvolution.hxx>
+#include <vigra/nonlineardiffusion.hxx>
+#include "vigranumpykernel.hxx"
+#include "vigranumpyscaleparam.hxx"
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+template < class VoxelType, unsigned int ndim >
+NumpyAnyArray 
+pythonConvolveOneDimensionND(NumpyArray<ndim, Multiband<VoxelType> > array,
+                             unsigned int dim,
+                             Kernel const & kernel,
+                             NumpyArray<ndim, Multiband<VoxelType> > res=python::object())
+{
+    vigra_precondition(dim < ndim-1,
+           "convolveOneDimension(): dim out of range.");
+
+    res.reshapeIfEmpty(array.taggedShape(), 
+            "convolveOneDimension(): Output array has wrong shape.");
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<array.shape(ndim-1);++k)
+        {
+            MultiArrayView<ndim-1, VoxelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<ndim-1, VoxelType, StridedArrayTag> bres = res.bindOuter(k);
+            convolveMultiArrayOneDimension(srcMultiArrayRange(barray), 
+                                           destMultiArray(bres), dim, kernel);
+        }
+    }
+    return res;
+}
+
+template < class VoxelType, unsigned int ndim >
+NumpyAnyArray 
+pythonSeparableConvolveND_1Kernel(NumpyArray<ndim, Multiband<VoxelType> > array,
+                                  Kernel const & kernel,
+                                  NumpyArray<ndim, Multiband<VoxelType> > res=python::object())
+{
+    res.reshapeIfEmpty(array.taggedShape(), 
+            "convolve(): Output array has wrong shape.");
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<array.shape(ndim-1);++k)
+        {
+            MultiArrayView<ndim-1, VoxelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<ndim-1, VoxelType, StridedArrayTag> bres = res.bindOuter(k);
+            separableConvolveMultiArray(srcMultiArrayRange(barray), destMultiArray(bres), kernel);
+        }
+    }
+    return res;
+}
+
+template < class VoxelType, unsigned int ndim >
+NumpyAnyArray 
+pythonSeparableConvolveND_NKernels(NumpyArray<ndim, Multiband<VoxelType> > array,
+                                   python::tuple pykernels,
+                                   NumpyArray<ndim, Multiband<VoxelType> > res=python::object())
+{
+    if(python::len(pykernels) == 1)
+    {
+        return pythonSeparableConvolveND_1Kernel(array, 
+                    python::extract<Kernel1D<KernelValueType> const &>(pykernels[0]), res);
+    }
+    
+    vigra_precondition(python::len(pykernels) == ndim-1,
+       "convolve(): Number of kernels must be 1 or equal to the number of spatial dimensions.");
+       
+    ArrayVector<Kernel1D<KernelValueType> > kernels;
+    for(unsigned int k=0; k < ndim-1; ++k)
+        kernels.push_back(python::extract<Kernel1D<KernelValueType> const &>(pykernels[k]));
+        
+    kernels = array.permuteLikewise(kernels);
+
+    res.reshapeIfEmpty(array.taggedShape(), 
+            "convolve(): Output array has wrong shape.");
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0; k < array.shape(ndim-1); ++k)
+        {
+            MultiArrayView<ndim-1, VoxelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<ndim-1, VoxelType, StridedArrayTag> bres = res.bindOuter(k);
+            separableConvolveMultiArray(srcMultiArrayRange(barray), 
+                                        destMultiArray(bres), kernels.begin());
+        }
+    }
+    return res;
+}
+
+template <class PixelType>
+NumpyAnyArray 
+pythonConvolveImage(NumpyArray<3, Multiband<PixelType> > image,
+                    TwoDKernel const & kernel, 
+                    NumpyArray<3, Multiband<PixelType> > res = python::object())
+{
+    res.reshapeIfEmpty(image.taggedShape(), 
+            "convolve(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            convolveImage(srcImageRange(bimage), destImage(bres),
+                          kernel2d(kernel));
+        }
+    }
+    return res;
+}
+
+template <class PixelType>
+NumpyAnyArray 
+pythonNormalizedConvolveImage(NumpyArray<3, Multiband<PixelType> > image,
+                              NumpyArray<3, Multiband<PixelType> > mask,
+                              TwoDKernel const & kernel, 
+                              NumpyArray<3, Multiband<PixelType> > res = python::object())
+{
+    vigra_precondition(mask.shape(2)==1 || mask.shape(2)==image.shape(2),
+               "normalizedConvolveImage(): mask image must either have 1 channel or as many as the input image");
+    vigra_precondition(mask.shape(0)==image.shape(0) && mask.shape(1)==image.shape(1),
+               "normalizedConvolveImage(): mask dimensions must be same as image dimensions");
+
+    res.reshapeIfEmpty(image.taggedShape(), 
+           "normalizedConvolveImage(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bmask = mask.bindOuter(mask.shape(2)==1?0:k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            normalizedConvolveImage(srcImageRange(bimage), srcImage(bmask), destImage(bres),
+                                    kernel2d(kernel));
+        }
+    }
+    return res;
+}
+
+template < class VoxelType, unsigned int ndim >
+NumpyAnyArray 
+pythonGaussianSmoothing(NumpyArray<ndim, Multiband<VoxelType> > array,
+                        python::object sigma,
+                        NumpyArray<ndim, Multiband<VoxelType> > res=python::object(),
+                        python::object sigma_d = python::object(0.0), 
+                        python::object step_size = python::object(1.0),
+                        double window_size = 0.0, 
+                        python::object roi = python::object())
+{
+    static const unsigned int N = ndim - 1;
+    
+    pythonScaleParam<N> params(sigma, sigma_d, step_size, "gaussianSmoothing");
+    
+    params.permuteLikewise(array);
+    
+    ConvolutionOptions<N> opt(params().filterWindowSize(window_size));
+    
+    if(roi != python::object())
+    {
+        typedef typename MultiArrayShape<N>::type Shape;
+        Shape start = array.permuteLikewise(python::extract<Shape>(roi[0])());
+        Shape stop  = array.permuteLikewise(python::extract<Shape>(roi[1])());
+        opt.subarray(start, stop);
+        res.reshapeIfEmpty(array.taggedShape().resize(stop-start), 
+                "gaussianSmoothing(): Output array has wrong shape.");
+    }
+    else
+    {
+        res.reshapeIfEmpty(array.taggedShape(), 
+                "gaussianSmoothing(): Output array has wrong shape.");
+    }
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0; k<array.shape(ndim-1); ++k)
+        {
+            MultiArrayView<ndim-1, VoxelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<ndim-1, VoxelType, StridedArrayTag> bres = res.bindOuter(k);
+            gaussianSmoothMultiArray(srcMultiArrayRange(barray), destMultiArray(bres), opt);
+        }
+    }
+    
+    return res;
+}
+
+template < class VoxelType>
+NumpyAnyArray 
+pythonRecursiveGaussian(NumpyArray<3, Multiband<VoxelType> > image,
+                        python::tuple sigmas,
+                        NumpyArray<3, Multiband<VoxelType> > res=python::object())
+{
+    typedef typename NumericTraits<VoxelType>::RealPromote TmpType;
+
+    const unsigned int ndim = 3;
+    unsigned int sigmaCount = python::len(sigmas);
+    vigra_precondition(sigmaCount == 1 || sigmaCount == ndim-1,
+       "recursiveGaussianSmoothing(): Number of kernels must be 1 or equal to the number of spatial dimensions.");
+       
+    ArrayVector<double> scales;
+    for(unsigned int k=0; k < sigmaCount; ++k)
+    {
+        scales.push_back(python::extract<double>(sigmas[k]));        
+    }
+    for(unsigned int k=sigmaCount; k < ndim-1; ++k)
+    {
+        scales.push_back(scales.back());
+    }
+    scales = image.permuteLikewise(scales);
+    
+    res.reshapeIfEmpty(image.taggedShape(), 
+            "recursiveGaussianSmoothing(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        MultiArray<ndim-1, TmpType> tmp(image.bindOuter(0).shape());
+
+        for(int k=0;k<image.shape(ndim-1);++k)
+        {
+            MultiArrayView<ndim-1, VoxelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<ndim-1, VoxelType, StridedArrayTag> bres = res.bindOuter(k);
+            recursiveGaussianFilterX(srcImageRange(bimage), destImage(tmp), scales[0]);
+            recursiveGaussianFilterY(srcImageRange(tmp), destImage(bres), scales[1]);
+        }
+    }
+    return res;
+
+}
+
+template < class VoxelType >
+NumpyAnyArray 
+pythonRecursiveGaussianIsotropic(NumpyArray<3, Multiband<VoxelType> > image,
+                                 double sigma,
+                                 NumpyArray<3, Multiband<VoxelType> > res=python::object())
+{
+    return pythonRecursiveGaussian(image, python::make_tuple(sigma), res);
+}
+
+template <class PixelType>
+NumpyAnyArray 
+pythonSimpleSharpening2D(NumpyArray<3, Multiband<PixelType> > image, 
+                         double sharpeningFactor,
+                         NumpyArray<3, Multiband<PixelType> > res=python::object() )
+{
+    vigra_precondition(sharpeningFactor >= 0 ,
+       "simpleSharpening2D(): sharpeningFactor must be >= 0.");
+       
+    res.reshapeIfEmpty(image.taggedShape(), 
+          "simpleSharpening2D(): Output array has wrong shape.");
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            simpleSharpening(srcImageRange(bimage), destImage(bres),
+                             sharpeningFactor);
+        }
+    }
+    return res;
+}
+
+template <class PixelType>
+NumpyAnyArray 
+pythonGaussianSharpening2D(NumpyArray<3, Multiband<PixelType> > image,
+                           double sharpeningFactor, double scale, 
+                           NumpyArray<3, Multiband<PixelType> > res=python::object() )
+{
+    vigra_precondition(sharpeningFactor >= 0 ,
+       "gaussianSharpening2D(): sharpeningFactor must be >= 0.");
+    vigra_precondition(sharpeningFactor >= 0 ,
+       "gaussianSharpening2D(): scale must be >= 0.");
+       
+    res.reshapeIfEmpty(image.taggedShape(), 
+             "gaussianSharpening2D(): Output array has wrong shape.");
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            gaussianSharpening(srcImageRange(bimage), destImage(bres),
+                               sharpeningFactor, scale);
+        }
+    }
+    return res;
+}
+
+template <class PixelType, unsigned int N>
+NumpyAnyArray 
+pythonLaplacianOfGaussian(NumpyArray<N, Multiband<PixelType> > array,
+                          python::object scale,
+                          NumpyArray<N, Multiband<PixelType> > res=python::object(),
+                          python::object sigma_d = python::object(0.0), 
+                          python::object step_size = python::object(1.0),
+                          double window_size = 0.0, 
+                          python::object roi = python::object())
+{
+    pythonScaleParam<N - 1> params(scale, sigma_d, step_size, "laplacianOfGaussian");
+    params.permuteLikewise(array);
+    
+    std::string description("channel-wise Laplacian of Gaussian, scale=");
+    description += asString(scale);
+    
+    ConvolutionOptions<N-1> opt(params().filterWindowSize(window_size));
+    
+    if(roi != python::object())
+    {
+        typedef typename MultiArrayShape<N-1>::type Shape;
+        Shape start = array.permuteLikewise(python::extract<Shape>(roi[0])());
+        Shape stop  = array.permuteLikewise(python::extract<Shape>(roi[1])());
+        opt.subarray(start, stop);
+        res.reshapeIfEmpty(array.taggedShape().resize(stop-start).setChannelDescription(description), 
+                "laplacianOfGaussian(): Output array has wrong shape.");
+    }
+    else
+    {
+        res.reshapeIfEmpty(array.taggedShape().setChannelDescription(description), 
+                "laplacianOfGaussian(): Output array has wrong shape.");
+    }
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0; k<array.shape(N-1); ++k)
+        {
+            MultiArrayView<N-1, PixelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<N-1, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            laplacianOfGaussianMultiArray(srcMultiArrayRange(barray), destMultiArray(bres), opt);
+        }
+    }
+    
+    return res;
+}
+
+template <class PixelType, unsigned int N>
+NumpyAnyArray 
+pythonGaussianDivergence(NumpyArray<N, TinyVector<PixelType, N> > array,
+                         python::object scale,
+                         NumpyArray<N, Singleband<PixelType> > res=python::object(),
+                         python::object sigma_d = python::object(0.0), 
+                         python::object step_size = python::object(1.0),
+                         double window_size = 0.0, 
+                         python::object roi = python::object())
+{
+    pythonScaleParam<N> params(scale, sigma_d, step_size, "gaussianDivergence");
+    params.permuteLikewise(array);
+    
+    std::string description("divergence of a vector field using Gaussian derivatives, scale=");
+    description += asString(scale);
+    
+    ConvolutionOptions<N> opt(params().filterWindowSize(window_size));
+    
+    if(roi != python::object())
+    {
+        typedef typename MultiArrayShape<N>::type Shape;
+        Shape start = array.permuteLikewise(python::extract<Shape>(roi[0])());
+        Shape stop  = array.permuteLikewise(python::extract<Shape>(roi[1])());
+        opt.subarray(start, stop);
+        res.reshapeIfEmpty(array.taggedShape().resize(stop-start).setChannelDescription(description), 
+                "gaussianDivergence(): Output array has wrong shape.");
+    }
+    else
+    {
+        res.reshapeIfEmpty(array.taggedShape().setChannelDescription(description), 
+                "gaussianDivergence(): Output array has wrong shape.");
+    }
+    
+    {
+        PyAllowThreads _pythread;
+        gaussianDivergenceMultiArray(array, res, opt);
+    }
+    
+    return res;
+}
+
+template <class PixelType>
+NumpyAnyArray 
+pythonRecursiveFilter1(NumpyArray<3, Multiband<PixelType> > image,
+                       double b, BorderTreatmentMode borderTreatment, 
+                       NumpyArray<3, Multiband<PixelType> > res = python::object())
+{
+    res.reshapeIfEmpty(image.taggedShape(), 
+            "recursiveFilter2D(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            recursiveFilterX(srcImageRange(bimage), destImage(bres), b, borderTreatment);
+            recursiveFilterY(srcImageRange(bres), destImage(bres), b, borderTreatment);
+        }
+    }
+    return res;
+}
+
+template <class PixelType>
+NumpyAnyArray 
+pythonRecursiveFilter2(NumpyArray<3, Multiband<PixelType> > image,
+                       double b1, double b2, 
+                       NumpyArray<3, Multiband<PixelType> > res = python::object())
+{
+    res.reshapeIfEmpty(image.taggedShape(), 
+            "recursiveFilter2D(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            recursiveFilterX(srcImageRange(bimage), destImage(bres), b1, b2);
+            recursiveFilterY(srcImageRange(bres), destImage(bres), b1, b2);
+        }
+    }
+    return res;
+}
+
+
+template <class PixelType>
+NumpyAnyArray 
+pythonRecursiveSmooth(NumpyArray<3, Multiband<PixelType> > image,
+                      double scale, BorderTreatmentMode borderTreatment, 
+                      NumpyArray<3, Multiband<PixelType> > res = python::object())
+{
+    return pythonRecursiveFilter1(image, std::exp(-1.0/scale), borderTreatment, res);
+}
+
+template <class PixelType>
+NumpyAnyArray 
+pythonRecursiveGradient(NumpyArray<2, Singleband<PixelType> > image,
+                        double scale, 
+                        NumpyArray<2, TinyVector<PixelType, 2> > res = python::object())
+{
+    std::string description("recursive gradient, scale=");
+    description += asString(scale);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "recursiveGradient2D(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        VectorComponentValueAccessor<TinyVector<PixelType, 2> > band(0);
+        recursiveFirstDerivativeX(srcImageRange(image), destImage(res, band), scale);
+        recursiveSmoothY(srcImageRange(res, band), destImage(res, band), scale);
+
+        band.setIndex(1);
+        recursiveSmoothX(srcImageRange(image), destImage(res, band), scale);
+        recursiveFirstDerivativeY(srcImageRange(res, band), destImage(res, band), scale);
+    }
+    
+    return res;
+}
+
+template <class PixelType>
+NumpyAnyArray 
+pythonRecursiveLaplacian(NumpyArray<3, Multiband<PixelType> > image,
+                         double scale, 
+                         NumpyArray<3, Multiband<PixelType> > res = python::object())
+{
+    using namespace vigra::functor;
+    
+    std::string description("channel-wise recursive Laplacian, scale=");
+    description += asString(scale);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "recursiveLaplacian2D(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        MultiArrayShape<2>::type tmpShape(image.shape().begin());
+        MultiArray<2, PixelType > tmp(tmpShape);
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+
+            recursiveSecondDerivativeX(srcImageRange(bimage), destImage(bres), scale);
+            recursiveSmoothY(srcImageRange(bres), destImage(bres), scale);
+
+            recursiveSmoothX(srcImageRange(bimage), destImage(tmp), scale);
+            recursiveSecondDerivativeY(srcImageRange(tmp), destImage(tmp), scale);
+            
+            combineTwoImages(srcImageRange(bres), srcImage(tmp), destImage(bres), Arg1()+Arg2());
+        }
+    }
+    return res;
+}
+
+void defineConvolutionFunctions()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+
+    def("convolveOneDimension",
+        registerConverters(&pythonConvolveOneDimensionND<float,3>),
+        (arg("image"), arg("dim"), arg("kernel"), arg("out")=python::object()),
+        "Convolution along a single dimension of a 2D scalar or multiband image. "
+        "'kernel' must be an instance of Kernel1D.\n"
+        "\n"
+        "For details see convolveMultiArrayOneDimension_ in the vigra C++ documentation.\n");
+
+    def("convolveOneDimension",
+        registerConverters(&pythonConvolveOneDimensionND<float,4>),
+        (arg("volume"), arg("dim"), arg("kernel"), arg("out")=python::object()), 
+        "Likewise for a 3D scalar or multiband volume.\n");
+
+    def("convolve", registerConverters(&pythonSeparableConvolveND_1Kernel<float,3>),
+        (arg("image"), arg("kernel"), arg("out")=python::object()),
+        "Convolve an image with the given 'kernel' (or kernels).\n"
+        "If the input has multiple channels, the filter is applied to each channel\n"
+        "independently. The function can be used in 3 different ways:\n"
+        "\n"
+        "* When 'kernel' is a single object of type :class:`Kernel1D`, this kernel\n"
+        "  is applied along all spatial dimensions of the data (separable filtering).\n"
+        "* When 'kernel' is a tuple of :class:`Kernel1D` objects, one different kernel\n"
+        "  is used for each spatial dimension (separable filtering). The number of\n"
+        "  kernels must equal the number of dimensions).\n"
+        "* When 'kernel' is an instance of :class:`Kernel2D`, a 2-dimensional convolution\n"
+        "  is performed (non-separable filtering). This is only applicable to 2D images.\n"
+        "\n"
+        "For details see separableConvolveMultiArray_ and "
+        "convolveImage_ in the vigra C++ documentation.\n");
+
+    def("convolve", registerConverters(&pythonSeparableConvolveND_1Kernel<float,4>),
+        (arg("volume"), arg("kernel"), arg("out")=python::object()),
+        "Convolve a volume with the same 1D kernel along all dimensions.\n");
+
+    def("convolve", registerConverters(&pythonSeparableConvolveND_NKernels<float,3>),
+        (arg("image"), arg("kernels"), arg("out")=python::object()),
+        "Convolve an image with a different 1D kernel along each dimensions.\n");
+
+    def("convolve", registerConverters(&pythonSeparableConvolveND_NKernels<float,4>),
+        (arg("volume"), arg("kernels"), arg("out")=python::object()),
+        "Convolve a volume with a different 1D kernel along each dimensions.\n");
+
+    def("convolve", registerConverters(&pythonConvolveImage<float>),
+        (arg("image"), arg("kernel"), arg("out") = python::object()),
+        "Convolve an image with a 2D kernel.\n");
+
+    def("normalizedConvolveImage", registerConverters(&pythonNormalizedConvolveImage<float>),
+        (arg("image"), arg("mask"), arg("kernel"), arg("out") = python::object()),
+        "Perform normalized convolution of an image. If the image has multiple channels, "
+        "every channel is convolved independently. The 'mask' tells the algorithm "
+        "whether input pixels are valid (non-zero mask value) or not. Invalid pixels "
+        "are ignored in the convolution. The mask must have one channel (which is then "
+        "used for all channels input channels) or as many channels as the input image.\n\n"
+        "For details, see normalizedConvolveImage_ in the C++ documentation.\n");
+
+    def("gaussianSmoothing",
+        registerConverters(&pythonGaussianSmoothing<float,3>),
+        (arg("array"), arg("sigma"), arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Perform Gaussian smoothing of a 2D or 3D scalar or multiband array.\n\n"
+        "Each channel of the array is smoothed independently. "
+        "If 'sigma' is a single value, an isotropic Gaussian filter at this scale is "
+        "applied (i.e. each dimension is smoothed in the same way). "
+        "If 'sigma' is a tuple or list of values, the amount of smoothing will be different "
+        "for each spatial dimension.\n"
+        "The optional 'sigma_d' (single, tuple, or list) (single, tuple, or list) denotes the resolution standard deviation "
+        "per axis, the optional 'step_size' (single, tuple, or list) the distance between two adjacent "
+        "pixels for each dimension. "
+        "The length of the tuples or lists must be equal to the "
+        "number of spatial dimensions.\n\n"
+        "'window_size' specifies the ratio between the effective filter scale and "
+        "the size of the filter window. Use a value around 2.0 to speed-up "
+        "the computation by increasing the error resulting from cutting off the Gaussian. "
+        "For the default 0.0, the window size is automatically determined.\n"
+        "\n"
+        "If 'roi' is not None, it must specify the desired region-of-interest as "
+        "a pair '(first_point, beyond_last_point)' (e.g. 'roi=((10,20), (200,250))'). "
+        "As usual, the second point is the first point outside the ROI, and the ROI "
+        "must not be outside the input array dimensions. "
+        "The coordinates refer only to non-channel axes - if your array has an explicit "
+        "channel axis, the ROI dimension must be one less than the array dimension. "
+        "If you pass in an explicit 'out' array and specify an ROI, the 'out' array "
+        "must have the shape of the ROI.\n\n"
+        "For details see gaussianSmoothing_ and ConvolutionOptions_ in the vigra C++ documentation.\n");
+
+    def("gaussianSmoothing",
+        registerConverters(&pythonGaussianSmoothing<float,4>),
+        (arg("array"), arg("sigma"), arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Smooth volume with Gaussian.\n");
+
+    def("recursiveGaussianSmoothing2D",
+        registerConverters(&pythonRecursiveGaussian<float>),               
+        (arg("image"), arg("sigma"), arg("out")=python::object()),
+        "Compute a fast approximate Gaussian smoothing of a 2D scalar or multiband image.\n\n"
+        "This function uses the third-order recursive filter approximation to the "
+        "Gaussian filter proposed by Young and van Vliet. "
+        "Each channel of the array is smoothed independently. "
+        "If 'sigma' is a single value, an isotropic Gaussian filter at this scale is "
+        "applied (i.e. each dimension is smoothed in the same way). "
+        "If 'sigma' is a tuple of values, the amount of smoothing will be different "
+        "for each spatial dimension. The length of the tuple must be equal to the "
+        "number of spatial dimensions.\n\n"        
+        "For details see recursiveGaussianFilterLine_ in the vigra C++ documentation.\n");
+
+    def("recursiveGaussianSmoothing2D",
+        registerConverters(&pythonRecursiveGaussianIsotropic<float>),               
+        (arg("image"), arg("sigma"), arg("out")=python::object()),
+        "Compute isotropic fast approximate Gaussian smoothing.\n");
+
+    def("simpleSharpening2D", 
+        registerConverters(&pythonSimpleSharpening2D<float>),
+        (arg("image"), arg("sharpeningFactor")=1.0, arg("out") = python::object()),
+        "Perform simple sharpening function.\n"
+        "\n"
+        "For details see simpleSharpening_ in the vigra C++ documentation.\n");
+
+    def("gaussianSharpening2D", 
+        registerConverters(&pythonGaussianSharpening2D<float>),
+        (arg("image"), arg("sharpeningFactor")=1.0, arg("scale")=1.0, arg("out") = python::object()),
+          "Perform sharpening function with gaussian filter."
+          "\n\n"
+          "For details see gaussianSharpening_ in the vigra C++ documentation.\n");
+          
+    def("laplacianOfGaussian", 
+         registerConverters(&pythonLaplacianOfGaussian<float,3>),
+         (arg("array"), arg("scale") = 1.0, arg("out") = python::object(), 
+          arg("sigma_d") = 0.0, arg("step_size") = 1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+          "Filter 2D or 3D scalar array with the Laplacian of Gaussian operator at the given scale.\n\n"
+          "If 'sigma' is a single value, an isotropic filter at this scale is "
+          "applied (i.e., each dimension is filtered in the same way). "
+          "If 'sigma' is a tuple or list of values, the amount of smoothing "
+          "will be different for each spatial dimension.\n"
+          "The optional 'sigma_d' (single, tuple, or list) denotes the resolution standard deviation "
+          "per axis, the optional 'step_size' (single, tuple, or list) the distance between two adjacent "
+          "pixels for each dimension. "
+          "The length of the tuples or lists must be equal to the "
+          "number of spatial dimensions.\n\n" 
+          "'window_size' and 'roi' have the same meaning as in :func:`gaussianSmoothing`.\n\n"
+          "For details see laplacianOfGaussianMultiArray_ and ConvolutionOptions_ in the vigra C++ documentation.\n");
+
+    def("laplacianOfGaussian", 
+         registerConverters(&pythonLaplacianOfGaussian<float,4>),
+         (arg("array"), arg("scale") = 1.0, arg("out") = python::object(), 
+         arg("sigma_d") = 0.0, arg("step_size") = 1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+         "Likewise for a scalar volume.\n");
+
+    def("gaussianDivergence", 
+         registerConverters(&pythonGaussianDivergence<float,2>),
+         (arg("array"), arg("scale") = 1.0, arg("out") = python::object(), 
+          arg("sigma_d") = 0.0, arg("step_size") = 1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+          "Compute the divergence of a 2D vector field with a first derivative of Gaussian at the given scale.\n\n"
+          "If 'sigma' is a single value, an isotropic filter at this scale is "
+          "applied (i.e., each dimension is filtered in the same way). "
+          "If 'sigma' is a tuple or list of values, the amount of smoothing "
+          "will be different for each spatial dimension.\n"
+          "The optional 'sigma_d' (single, tuple, or list) denotes the resolution standard deviation "
+          "per axis, the optional 'step_size' (single, tuple, or list) the distance between two adjacent "
+          "pixels for each dimension. "
+          "The length of the tuples or lists must be equal to the "
+          "number of spatial dimensions.\n\n" 
+          "'window_size' and 'roi' have the same meaning as in :func:`gaussianSmoothing`.\n\n"
+          "For details see gaussianDivergenceMultiArray_ and ConvolutionOptions_ in the vigra C++ documentation.\n");
+
+    def("gaussianDivergence", 
+         registerConverters(&pythonGaussianDivergence<float,3>),
+         (arg("array"), arg("scale") = 1.0, arg("out") = python::object(), 
+         arg("sigma_d") = 0.0, arg("step_size") = 1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+         "Likewise for a 3D vector field.\n");
+
+    def("recursiveFilter2D", registerConverters(&pythonRecursiveFilter1<float>),
+              (arg("image"), arg("b"), arg("borderTreament") = BORDER_TREATMENT_REFLECT, arg("out") = python::object()),
+              "Perform 2D convolution with a first-order recursive filter with "
+              "parameter 'b' and given 'borderTreatment'. 'b' must be between -1 and 1.\n"
+              "\n"
+              "For details see recursiveFilterX_ and recursiveFilterY_ (which "
+              "this function calls in succession) in the vigra C++ documentation.\n");
+
+    def("recursiveFilter2D", registerConverters(&pythonRecursiveFilter2<float>),
+              (arg("image"), arg("b1"), arg("b2"), arg("out") = python::object()),
+              "Perform 2D convolution with a second-order recursive filter with "
+              "parameters 'b1' and 'b2'. Border treatment is always BORDER_TREATMENT_REFLECT.\n"
+              "\n"
+              "For details see recursiveFilterX_ and recursiveFilterY_ (which "
+              "this function calls in succession) in the vigra C++ documentation.\n");
+
+    def("recursiveSmooth2D", registerConverters(&pythonRecursiveSmooth<float>),
+              (arg("image"), arg("scale"), arg("borderTreament") = BORDER_TREATMENT_REFLECT, arg("out") = python::object()),
+              "Calls recursiveFilter2D() with b = exp(-1/scale), which "
+              "corresponds to smoothing with an exponential filter exp(-abs(x)/scale).\n"
+              "\n"
+              "For details see recursiveSmoothLine_ in the vigra C++ documentation.\n");
+
+    def("recursiveGradient2D", registerConverters(&pythonRecursiveSmooth<float>),
+              (arg("image"), arg("scale"), arg("out") = python::object()),
+              "Compute the gradient of a scalar image using a recursive (exponential) filter "
+              "at the given 'scale'. The output image (if given) must have two channels.\n"
+              "\n"
+              "For details see recursiveSmoothLine_ and recursiveFirstDerivativeLine_ (which "
+              "this function calls internally) in the vigra C++ documentation.\n");
+
+    def("recursiveLaplacian2D", registerConverters(&pythonRecursiveLaplacian<float>),
+              (arg("image"), arg("scale"), arg("out") = python::object()),
+              "Compute the gradient of a 2D scalar or multiband image using a recursive (exponential) filter "
+              "at the given 'scale'. The output image (if given) must have as many channels as the input.\n"
+              "\n"
+              "For details see recursiveSmoothLine_ and recursiveSecondDerivativeLine_ (which "
+              "this function calls internally) in the vigra C++ documentation.\n");
+
+}
+
+} // namespace vigra
diff --git a/vigranumpy/src/core/edgedetection.cxx b/vigranumpy/src/core/edgedetection.cxx
new file mode 100644
index 0000000..0dd0b15
--- /dev/null
+++ b/vigranumpy/src/core/edgedetection.cxx
@@ -0,0 +1,473 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyanalysis_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/edgedetection.hxx>
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+double Edgel__getitem__(Edgel const & e, unsigned int i)
+{
+    if(i > 1)
+    {
+        PyErr_SetString(PyExc_IndexError,
+            "Edgel.__getitem__(): index out of bounds.");
+        python::throw_error_already_set();
+    }
+    return i == 0 ? e.x : e.y;
+}
+
+void Edgel__setitem__(Edgel & e, unsigned int i, double v)
+{
+    if(i > 1)
+    {
+        PyErr_SetString(PyExc_IndexError,
+            "Edgel.__setitem__(): index out of bounds.");
+        python::throw_error_already_set();
+    }
+    if(i==0)
+        e.x = Edgel::value_type(v);
+    else
+        e.y = Edgel::value_type(v);
+}
+
+unsigned int Edgel__len__(Edgel const & e)
+{
+    return 2;
+}
+
+PyObject * Edgel__repr__(Edgel const & e)
+{
+        std::stringstream s;
+        s << std::setprecision(14)
+          << "Edgel(x=" << e.x << ", y=" << e.y << ", strength=" << e.strength << ", angle=" << e.orientation << ")";
+        return PyString_FromString(s.str().c_str());
+}
+
+template < class PixelType>
+python::list
+pythonFindEdgelsFromGrad(NumpyArray<2, TinyVector<PixelType, 2> > grad,
+                         double threshold) 
+{
+    std::vector<Edgel> edgels;
+    {
+        PyAllowThreads _pythread;
+        cannyEdgelList(srcImageRange(grad), edgels);
+    }
+    
+    python::list pyEdgels;
+    for(unsigned int i = 0; i < edgels.size(); ++i)
+    {
+        if(edgels[i].strength >= threshold)
+            pyEdgels.append(edgels[i]);
+    }
+    return pyEdgels;
+}
+
+template < class PixelType>
+python::list
+pythonFindEdgels(NumpyArray<2, Singleband<PixelType> > image,
+                 double scale, double threshold)
+{
+    std::vector<Edgel> edgels;
+    {
+        PyAllowThreads _pythread;
+        cannyEdgelList(srcImageRange(image), edgels, scale);
+    }
+    
+    python::list pyEdgels;
+    for(unsigned int i = 0; i < edgels.size(); ++i)
+    {
+        if(edgels[i].strength >= threshold)
+            pyEdgels.append(edgels[i]);
+    }
+    return pyEdgels;
+}
+
+template < class PixelType>
+python::list
+pythonFindEdgels3x3FromGrad(NumpyArray<2, TinyVector<PixelType, 2> > grad,
+                            double threshold) 
+{
+    std::vector<Edgel> edgels;
+    {
+        PyAllowThreads _pythread;
+        cannyEdgelList3x3(srcImageRange(grad), edgels);
+    }
+    
+    python::list pyEdgels;
+    for(unsigned int i = 0; i < edgels.size(); ++i)
+    {
+        if(edgels[i].strength >= threshold)
+            pyEdgels.append(edgels[i]);
+    }
+    return pyEdgels;
+}
+
+template < class PixelType>
+python::list
+pythonFindEdgels3x3(NumpyArray<2, Singleband<PixelType> > image,
+                    double scale, double threshold)
+{
+    std::vector<Edgel> edgels;
+    {
+        PyAllowThreads _pythread;
+        cannyEdgelList3x3(srcImageRange(image), edgels, scale);
+    }
+    python::list pyEdgels;
+    for(unsigned int i = 0; i < edgels.size(); ++i)
+    {
+        if(edgels[i].strength >= threshold)
+            pyEdgels.append(edgels[i]);
+    }
+    return pyEdgels;
+}
+
+template < class SrcPixelType, typename DestPixelType >
+NumpyAnyArray 
+pythonCannyEdgeImage(NumpyArray<2, Singleband<SrcPixelType> > image,
+                     double scale, double threshold, DestPixelType edgeMarker, 
+                     NumpyArray<2, Singleband<DestPixelType> > res = python::object())
+{
+    std::string description("Canny edges, scale=");
+    description += asString(scale) + ", threshold=" + asString(threshold);
+
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "cannyEdgeImage(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        cannyEdgeImage(srcImageRange(image), destImage(res), 
+                       scale, threshold, edgeMarker);
+    }
+    
+    return res;
+}
+
+template < class SrcPixelType, typename DestPixelType >
+NumpyAnyArray 
+pythonCannyEdgeImageWithThinning(NumpyArray<2, Singleband<SrcPixelType> > image,
+                                 double scale, double threshold, 
+                                 DestPixelType edgeMarker, bool addBorder = true,
+                                 NumpyArray<2, Singleband<DestPixelType> > res = python::object())
+{
+    std::string description("Canny edges with thinning, scale=");
+    description += asString(scale) + ", threshold=" + asString(threshold);
+
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "cannyEdgeImageWithThinning(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        cannyEdgeImageWithThinning(srcImageRange(image), destImage(res),
+                                   scale, threshold, edgeMarker, addBorder);
+    }
+    
+    return res;
+}
+
+template < class SrcPixelType, typename DestPixelType >
+NumpyAnyArray 
+pythonShenCastanEdgeImage(NumpyArray<2, Singleband<SrcPixelType> > image,
+                          double scale, double threshold, DestPixelType edgeMarker, 
+                          NumpyArray<2, Singleband<DestPixelType> > res = python::object())
+{
+    std::string description("Shen/Castan edges, scale=");
+    description += asString(scale) + ", threshold=" + asString(threshold);
+
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "shenCastanEdgeImage(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        differenceOfExponentialEdgeImage(srcImageRange(image), destImage(res), 
+                                         scale, threshold, edgeMarker);
+    }
+    
+    return res;
+}
+
+template < class SrcPixelType, typename DestPixelType >
+NumpyAnyArray 
+pythonShenCastanCrackEdgeImage(NumpyArray<2, Singleband<SrcPixelType> > image,
+                               double scale, double threshold, DestPixelType edgeMarker, 
+                               NumpyArray<2, Singleband<DestPixelType> > res = python::object())
+{
+    std::string description("Shen/Castan crack edges, scale=");
+    description += asString(scale) + ", threshold=" + asString(threshold);
+
+    MultiArrayShape<2>::type newShape = 2*image.shape() - MultiArrayShape<2>::type(1,1);
+    res.reshapeIfEmpty(image.taggedShape().resize(newShape).setChannelDescription(description), 
+                       "shenCastanCrackEdgeImage(): Output array has wrong shape. Needs to be (w,h)*2 - 1.");    
+    
+    {
+        PyAllowThreads _pythread;
+        differenceOfExponentialCrackEdgeImage(srcImageRange(image), destImage(res), 
+                                              scale, threshold, edgeMarker);
+    }
+    
+    return res;
+}
+
+template < class PixelType>
+NumpyAnyArray 
+pythonRemoveShortEdges(NumpyArray<2, Singleband<PixelType> > image,
+                       int minEdgeLength, PixelType nonEdgeMarker, 
+                       NumpyArray<2, Singleband<PixelType> > res = python::object())
+{
+    res.reshapeIfEmpty(image.taggedShape(), 
+            "removeShortEdges(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        copyImage(srcImageRange(image), destImage(res));
+        removeShortEdges(destImageRange(res), minEdgeLength, nonEdgeMarker);
+    }
+    
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonBeautifyCrackEdgeImage(NumpyArray<2, Singleband<PixelType> > image,
+                             PixelType edgeMarker, 
+                             PixelType backgroundMarker,
+                             NumpyArray<2, Singleband<PixelType> > res = python::object())
+{
+    res.reshapeIfEmpty(image.taggedShape(), 
+            "beautifyCrackEdgeImage(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        copyImage(srcImageRange(image), destImage(res));
+        beautifyCrackEdgeImage(destImageRange(res), edgeMarker, backgroundMarker);
+    }
+    
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonCloseGapsInCrackEdgeImage(NumpyArray<2, Singleband<PixelType> > image,
+                                PixelType edgeMarker,
+                                NumpyArray<2, Singleband<PixelType> > res = python::object())
+{
+    res.reshapeIfEmpty(image.taggedShape(), 
+            "closeGapsInCrackEdgeImage(): Output array has wrong shape.");
+    
+    {
+        PyAllowThreads _pythread;
+        copyImage(srcImageRange(image), destImage(res));
+        closeGapsInCrackEdgeImage(destImageRange(res), edgeMarker);
+    }
+    
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonRegionImageToCrackEdgeImage(NumpyArray<2, Singleband<PixelType> > image,
+                                  PixelType edgeLabel = 0,
+                                  NumpyArray<2, Singleband<PixelType> > res = python::object())
+{
+    MultiArrayShape<2>::type newShape = 2*image.shape() - MultiArrayShape<2>::type(1,1);
+    res.reshapeIfEmpty(image.taggedShape().resize(newShape), 
+            "regionImageToCrackEdgeImage(): Output array has wrong shape. Needs to be (w,h)*2 - 1.");
+
+    {
+        PyAllowThreads _pythread;
+        regionImageToCrackEdgeImage(srcImageRange(image), destImage(res), edgeLabel);
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonRegionImageToEdgeImage(NumpyArray<2, Singleband<PixelType> > image,
+                             PixelType edgeLabel = 1,
+                             NumpyArray<2, Singleband<PixelType> > res = python::object())
+{
+    res.reshapeIfEmpty(image.taggedShape(), 
+            "regionImageToEdgeImage2D(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        regionImageToEdgeImage(srcImageRange(image), destImage(res), edgeLabel);
+    }
+    return res;
+}
+
+
+void defineEdgedetection()
+{
+    using namespace python;
+
+    docstring_options doc_options(true, true, false);
+
+    class_<Edgel> edgel("Edgel", "Represent an Edgel at a particular subpixel position (x, y), having "
+                                  "given 'strength' and 'orientation'.\n\n"
+                                  "For details, see Edgel_ in the vigra C++ documentation.\n",
+                         init<>("Standard constructor::\n\n   Edgel()\n\n"));
+    edgel
+       .def(init<float, float, float, float>(args("x", "y", "strength", "orientation"), 
+            "Constructor::\n\n    Edgel(x, y, strength, orientation)\n\n"))
+       .def_readwrite("x", &Edgel::x, "The edgel's x position.")
+       .def_readwrite("y", &Edgel::y, "The edgel's y position.")
+       .def_readwrite("strength", &Edgel::strength, "The edgel's strength.")
+       .def_readwrite("orientation", &Edgel::orientation, "The edgel's orientation.")
+       .def("__getitem__", &Edgel__getitem__)
+       .def("__setitem__", &Edgel__setitem__)
+       .def("__repr__", &Edgel__repr__)
+       .def("__len__", &Edgel__len__)
+       ;
+
+    def("cannyEdgelList", 
+        registerConverters(&pythonFindEdgelsFromGrad<float>),
+        args("gradient", "threshold"),
+        "Return a list of :class:`Edgel` objects whose strength is at least 'threshold'.\n\n"
+        "The function comes in two forms::\n\n"
+        "    cannyEdgelList(gradient, threshold) -> list\n"
+        "    cannyEdgelList(image, scale, threshold) -> list\n\n"
+        "The first form expects a gradient image (i.e. with two channels) to compute "
+        "edgels, whereas the second form expects a scalar image and computes the "
+        "gradient internally at 'scale'.\n\n"
+        "For details see cannyEdgelList_ in the vigra C++ documentation.\n");
+
+    def("cannyEdgelList",  
+        registerConverters(&pythonFindEdgels<float>),
+        args("image", "scale", "threshold"),
+         "Compute edgels of a 2D scalar image, given the filter scale.\n");
+
+    def("cannyEdgelList3x3", 
+        registerConverters(&pythonFindEdgels3x3FromGrad<float>),
+        args("gradient", "threshold"),
+        "Return a list of :class:`Edgel` objects whose strength is at least 'threshold'.\n\n"
+        "The function comes in two forms::\n\n"
+        "    cannyEdgelList3x3(gradient, threshold) -> list\n"
+        "    cannyEdgelList3x3(image, scale, threshold) -> list\n\n"
+        "The first form expects a gradient image (i.e. with two channels) to compute "
+        "edgels, whereas the second form expects a scalar image and computes the "
+        "gradient internally at 'scale'. The results are slightly better than "
+        "those of :func:`cannyEdgelList`.\n\n"
+        "For details see cannyEdgelList3x3_ in the vigra C++ documentation.\n");
+
+    def("cannyEdgelList3x3",  
+        registerConverters(&pythonFindEdgels3x3<float>),
+        args("image", "scale", "threshold"),
+         "Compute edgels of a 2D scalar image, given the filter scale.\n");
+
+    def("cannyEdgeImage",
+        registerConverters(&pythonCannyEdgeImage<float, UInt8>),
+        (arg("image"), arg("scale"), arg("threshold"), arg("edgeMarker"),arg("out")=python::object()),
+        "Detect and mark edges in an edge image using Canny's algorithm.\n\n"
+        "For details see cannyEdgeImage_ in the vigra C++ documentation.\n");
+
+    def("cannyEdgeImageWithThinning",
+        registerConverters(&pythonCannyEdgeImageWithThinning<float, UInt8>),
+        (arg("image"), arg("scale"), arg("threshold"), arg("edgeMarker"),
+        arg("addBorder")=true,arg("out")=python::object()),
+        "Detect and mark edges in an edge image using Canny's algorithm.\n\n"
+        "For details see cannyEdgeImageWithThinning_ in the vigra C++ documentation.\n");
+
+    def("shenCastanEdgeImage",
+        registerConverters(&pythonShenCastanEdgeImage<float, UInt8>),
+        (arg("image"), arg("scale"), arg("threshold"), arg("edgeMarker"),arg("out")=python::object()),
+        "Detect and mark edges in an edge image using the Shen/Castan zero-crossing detector.\n\n"
+        "For details see differenceOfExponentialEdgeImage_ in the vigra C++ documentation.\n");
+
+    def("shenCastanCrackEdgeImage",
+        registerConverters(&pythonShenCastanCrackEdgeImage<float, UInt8>),
+        (arg("image"), arg("scale"), arg("threshold"), arg("edgeMarker"),arg("out")=python::object()),
+        "Detect and mark edges in a crack edge image using the Shen/Castan zero-crossing detector.\n\n"
+        "For details see differenceOfExponentialCrackEdgeImage_ in the vigra C++ documentation.\n");
+
+    def("removeShortEdges",
+        registerConverters(&pythonRemoveShortEdges<UInt8>),
+        (arg("image"), arg("minEdgeLength"), arg("nonEdgeMarker"),arg("out")=python::object()),
+        "Remove short edges from an edge image.\n\n"
+        "For details see removeShortEdges_ in the vigra C++ documentation.\n");
+
+    def("beautifyCrackEdgeImage",
+        registerConverters(&pythonBeautifyCrackEdgeImage<UInt8>),
+        (arg("image"), arg("edgeMarker"), arg("backgroundMarker"),arg("out")=python::object()),
+        "Beautify crack edge image for visualization.\n\n"
+        "For details see beautifyCrackEdgeImage_ in the vigra C++ documentation.\n");
+
+    def("closeGapsInCrackEdgeImage",
+        registerConverters(&pythonCloseGapsInCrackEdgeImage<UInt8>),
+        (arg("image"), arg("edgeMarker"),arg("out")=python::object()),
+        "Close one-pixel wide gaps in a cell grid edge image.\n\n"
+        "For details see closeGapsInCrackEdgeImage_ in the vigra C++ documentation.\n");
+
+    def("regionImageToEdgeImage",
+        registerConverters(&pythonRegionImageToEdgeImage<npy_uint32>),
+        (arg("image"), 
+         arg("edgeLabel") = 1,
+         arg("out")=python::object()),
+        "Transform a labeled uint32 image into an edge image.\n\n"
+        "For details see regionImageToEdgeImage_ in the vigra C++ documentation.\n");
+
+    def("regionImageToEdgeImage",
+        registerConverters(&pythonRegionImageToEdgeImage<npy_uint64>),
+        (arg("image"), 
+         arg("edgeLabel") = 1,
+         arg("out")=python::object()),
+         "Likewise for a uint64 image.\n");
+
+    def("regionImageToCrackEdgeImage",
+         registerConverters(&pythonRegionImageToCrackEdgeImage<npy_uint32>),
+         (arg("image"), 
+          arg("edgeLabel") = 0, 
+          arg("out")=python::object()),
+         "Transform a labeled uint32 image into a crack edge image. \n\n"
+         "For details see regionImageToCrackEdgeImage_ in the vigra C++ documentation.\n");
+
+    def("regionImageToCrackEdgeImage",
+         registerConverters(&pythonRegionImageToCrackEdgeImage<npy_uint64>),
+         (arg("image"), 
+          arg("edgeLabel") = 0, 
+          arg("out")=python::object()),
+         "Likewise for a uint64 image.\n");
+
+}
+
+} // namespace vigra
diff --git a/vigranumpy/src/core/filters.cxx b/vigranumpy/src/core/filters.cxx
new file mode 100644
index 0000000..489eeac
--- /dev/null
+++ b/vigranumpy/src/core/filters.cxx
@@ -0,0 +1,132 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyfilters_PyArray_API
+//#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/nonlineardiffusion.hxx>
+#include <vigra/symmetry.hxx>
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+template <class InValue, class OutValue>
+NumpyAnyArray 
+pythonNonlinearDiffusion2D(NumpyArray<3, Multiband<InValue> > image, 
+                           double edgeThreshold, double scale,
+                           NumpyArray<3, Multiband<OutValue> > res=NumpyArray<3, Multiband<float> >())
+{
+    res.reshapeIfEmpty(image.taggedShape(), 
+        "nonlinearDiffusion2D(): Output array has wrong shape.");
+        
+    {
+        PyAllowThreads _pythread;
+        for(int k=0; k<image.shape(2); ++k)
+        {
+            MultiArrayView<2, OutValue, StridedArrayTag> bres = res.bindOuter(k);
+            nonlinearDiffusion(srcImageRange(image.bindOuter(k)), 
+                               destImage(bres), 
+                               DiffusivityFunctor< double >(edgeThreshold), scale);
+        }
+    }
+    return res;
+}
+
+template < class SrcPixelType >
+NumpyAnyArray 
+pythonRadialSymmetryTransform2D(NumpyArray<2, Singleband<SrcPixelType> > image,
+                                double scale = 1.0,
+                                NumpyArray<2, Singleband<SrcPixelType> > res = python::object())
+{
+    std::string description("radial symmetry transform, scale=");
+    description += asString(scale);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "radialSymmetryTransform2D(): Output array has wrong shape.");    
+        
+    {
+        PyAllowThreads _pythread;
+        radialSymmetryTransform(srcImageRange(image), destImage(res), scale);
+    }
+    return res;
+}
+
+
+void defineFilters2D()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+    
+    def("nonlinearDiffusion", 
+        registerConverters(&pythonNonlinearDiffusion2D<float, float>),
+        (arg("image"), arg("edgeThreshold"), arg("scale"), arg("out")=python::object()),
+        "Perform edge-preserving smoothing at the given scale."
+        "\n\n"
+        "For details see nonlinearDiffusion_ in the vigra C++ documentation.\n");
+
+    def("radialSymmetryTransform2D",
+        registerConverters(&pythonRadialSymmetryTransform2D<float>),
+        (arg("image"), arg("scale"),arg("out")=python::object()),
+        "Find centers of radial symmetry in an 2D image.\n\n"
+        "This algorithm implements the Fast Radial Symmetry Transform according to "
+        "[G. Loy, A. Zelinsky: \"A Fast Radial Symmetry Transform for Detecting Points of Interest\", "
+        "in: A. Heyden et al. (Eds.): Proc. of 7th European Conf. on Computer Vision, Part 1, pp. 358-368, Springer LNCS 2350, 2002]\n\n"
+        "For details see radialSymmetryTransform_ in the vigra C++ documentation.\n");
+}
+
+void defineKernels();
+void defineConvolutionFunctions();
+void defineMorphology();
+void defineTensor();
+
+} // namespace vigra
+
+using namespace vigra;
+using namespace boost::python;
+
+BOOST_PYTHON_MODULE_INIT(filters)
+{
+    import_vigranumpy();
+    defineFilters2D();
+    defineKernels();
+    defineConvolutionFunctions();
+    defineMorphology();
+    defineTensor();
+}
diff --git a/vigranumpy/src/core/geometry.cxx b/vigranumpy/src/core/geometry.cxx
new file mode 100644
index 0000000..7063249
--- /dev/null
+++ b/vigranumpy/src/core/geometry.cxx
@@ -0,0 +1,94 @@
+
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2010 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpygeometry_PyArray_API
+//#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/polygon.hxx>
+#include <vigra/array_vector.hxx>
+#include <vigra/tinyvector.hxx>
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+template < class Coordinate>
+NumpyAnyArray
+pyconvexHull(NumpyArray<1, TinyVector<Coordinate, 2>, UnstridedArrayTag > points)
+{
+    ArrayVector<TinyVector<Coordinate, 2> > hull;
+    {
+        PyAllowThreads _pythread;
+    
+        convexHull(ArrayVectorView<TinyVector<Coordinate, 2> >(points.shape(0), points.data()), hull);
+    }
+
+    NumpyArray<1, TinyVector<Coordinate, 2> > result(MultiArrayShape<1>::type(hull.size()));
+    for(MultiArrayIndex i = 0; i < result.shape(0); ++i)
+        result(i) = hull[i];
+
+    return result;
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pythonConvexHull, pyconvexHull)
+
+void defineGeometry()
+{
+    using namespace python;
+
+    docstring_options doc_options(true, true, false);
+
+    multidef("convexHull",
+         pythonConvexHull<double, float, Int32>(),
+         args("points"),
+        "Compute the convex hull of a point set.\n"
+        "\n"
+        "For details see convexHull_ in the vigra C++ documentation.\n\n");
+}
+
+} // namespace vigra
+
+using namespace vigra;
+using namespace boost::python;
+
+BOOST_PYTHON_MODULE_INIT(geometry)
+{
+    import_vigranumpy();
+    defineGeometry();
+}
diff --git a/vigranumpy/src/core/impex.cxx b/vigranumpy/src/core/impex.cxx
new file mode 100644
index 0000000..91db647
--- /dev/null
+++ b/vigranumpy/src/core/impex.cxx
@@ -0,0 +1,583 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyimpex_PyArray_API
+//#define NO_IMPORT_ARRAY
+
+#include <Python.h>
+#include <iostream>
+#include <cstring>
+#include <cstdio>
+#include <vigra/numpy_array.hxx>
+#include <vigra/impex.hxx>
+#include <vigra/multi_impex.hxx>
+#include <vigra/axistags.hxx>
+#include <vigra/numpy_array_converters.hxx>
+
+namespace python = boost::python;
+
+namespace vigra {
+
+namespace detail {
+
+template <class T>
+NumpyAnyArray readImageImpl(ImageImportInfo const & info, std::string order = "")
+{
+    typedef UnstridedArrayTag Stride;
+    
+    if(order == "")
+        order = detail::defaultOrder();
+
+    switch(info.numBands())
+    {
+      case 1:
+      {
+        NumpyArray<2, Singleband<T>, Stride> res(MultiArrayShape<2>::type(info.width(), info.height()), order);
+        importImage(info, destImage(res));
+        return res;
+      }
+      case 2:
+      {
+        NumpyArray<2, TinyVector<T, 2>, Stride> res(MultiArrayShape<2>::type(info.width(), info.height()), order);
+        importImage(info, destImage(res));
+        return res;
+      }
+      case 3:
+      {
+        NumpyArray<2, RGBValue<T>, Stride> res(MultiArrayShape<2>::type(info.width(), info.height()), order);
+        importImage(info, destImage(res));
+        return res;
+      }
+      case 4:
+      {
+        NumpyArray<2, TinyVector<T, 4>, Stride> res(MultiArrayShape<2>::type(info.width(), info.height()), order);
+        importImage(info, destImage(res));
+        return res;
+      }
+      default:
+      {
+        NumpyArray<3, Multiband<T> > res(MultiArrayShape<3>::type(info.width(), info.height(), info.numBands()), order);
+        importImage(info, destImage(res));
+        return res;
+      }
+    }
+}
+
+std::string numpyTypeIdToImpexString(NPY_TYPES typeID)
+{
+    switch(typeID)
+    {
+        case NPY_BOOL: return std::string("UINT8");
+        case NPY_INT8: return std::string("INT8");
+        case NPY_UINT8: return std::string("UINT8");
+        case NPY_INT16: return std::string("INT16");
+        case NPY_UINT16: return std::string("UINT16");
+        case NPY_INT32: return std::string("INT32");
+        case NPY_UINT32: return std::string("UINT32");
+        case NPY_INT64: return std::string("DOUBLE");
+        case NPY_UINT64: return std::string("DOUBLE");
+        case NPY_FLOAT32: return std::string("FLOAT");
+        case NPY_FLOAT64: return std::string("DOUBLE");
+        default: return std::string("UNKNOWN");
+    }
+}
+
+} // namespace detail
+
+NumpyAnyArray 
+readImage(const char * filename, python::object import_type, unsigned int index, std::string order = "")
+{
+    ImageImportInfo info(filename, index);
+    std::string importType(info.getPixelType());
+
+    if(python::extract<std::string>(import_type).check())
+    {
+        std::string type = python::extract<std::string>(import_type)();
+        if(type != "" && type != "NATIVE")
+            importType = type;
+    }
+    else if(python::extract<NPY_TYPES>(import_type).check())
+    {
+        importType = detail::numpyTypeIdToImpexString(python::extract<NPY_TYPES>(import_type)());
+    }
+    else if(import_type)
+        vigra_precondition(false, "readImage(filename, import_type, order): import_type must be a string or a numpy dtype.");
+
+    // FIXME: support all types, at least via a type cast at the end?
+    if(importType == "FLOAT")
+        return detail::readImageImpl<float>(info, order);
+    if(importType == "UINT8")
+        return detail::readImageImpl<UInt8>(info, order);
+    if(importType == "INT16")
+        return detail::readImageImpl<Int16>(info, order);
+    if(importType == "UINT16")
+        return detail::readImageImpl<UInt16>(info, order);
+    if(importType == "INT32")
+        return detail::readImageImpl<Int32>(info, order);
+    if(importType == "UINT32")
+        return detail::readImageImpl<UInt32>(info, order);
+    if(importType == "DOUBLE")
+        return detail::readImageImpl<double>(info, order);
+    vigra_fail("readImage(filename, import_type, order): import_type specifies an unknown pixel type.");
+    return NumpyAnyArray();
+}
+
+// when export_type == "", writeImage() will figure out the best compromise
+// between the input pixel type and the capabilities of the given file format
+// (see negotiatePixelType())
+template <class T>
+void writeImage(NumpyArray<3, Multiband<T> > const & image,
+                    const char * filename,
+                    python::object export_type,
+                    const char * compression = "",
+                    const char * mode = "w")
+{
+    ImageExportInfo info(filename, mode);
+
+    if(python::extract<std::string>(export_type).check())
+    {
+        std::string type = python::extract<std::string>(export_type)();
+        if(type == "NBYTE")
+        {
+            info.setForcedRangeMapping(0.0, 0.0, 0.0, 255.0);
+            info.setPixelType("UINT8");
+        }
+        else if(type != "" && type != "NATIVE")
+        {
+            info.setPixelType(type.c_str());
+        }
+    }
+    else if(python::extract<NPY_TYPES>(export_type).check())
+    {
+        info.setPixelType(detail::numpyTypeIdToImpexString(python::extract<NPY_TYPES>(export_type)()).c_str());
+    }
+    else if(export_type)
+        vigra_precondition(false, "writeImage(filename, export_type): export_type must be a string or a numpy dtype.");
+
+    if(std::string(compression) == "RunLength")
+        info.setCompression("RLE");
+    else if(std::string(compression) != "")
+        info.setCompression(compression);
+    exportImage(srcImageRange(image), info);
+}
+
+unsigned int numberImages(const char * filename)
+{
+    ImageImportInfo info(filename);
+    return info.numImages();
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pywriteImage, writeImage)
+
+namespace detail {
+
+template <class T>
+NumpyAnyArray 
+readVolumeImpl(VolumeImportInfo const & info, std::string order = "")
+{
+    if(order == "")
+        order = detail::defaultOrder();
+
+    switch(info.numBands())
+    {
+      case 1:
+      {
+        NumpyArray<3, Singleband<T> > volume(info.shape(), order);
+        importVolume(info, volume);
+        return volume;
+      }
+      case 2:
+      {
+        NumpyArray<3, TinyVector<T, 2> > volume(info.shape(), order);
+        importVolume(info, volume);
+        return volume;
+      }
+      case 3:
+      {
+        NumpyArray<3, RGBValue<T> > volume(info.shape(), order);
+        importVolume(info, volume);
+        return volume;
+      }
+      case 4:
+      {
+        NumpyArray<3, TinyVector<T, 4> > volume(info.shape(), order);
+        importVolume(info, volume);
+        return volume;
+      }
+      //FIXME not yet supported
+      /*default:
+      {
+        NumpyArray<4, Multiband<T> > volume(MultiArrayShape<4>::type(info.width(), info.height(), info.depth(), info.numBands()));
+        importVolume(info, volume);
+        return volume;
+      }*/
+      default:
+      {
+        NumpyArray<3, RGBValue<T> > volume(info.shape(), order);
+        importVolume(info, volume);
+        return volume;
+      }
+    }
+}
+
+} // namespace detail
+
+NumpyAnyArray 
+readVolume(const char * filename, python::object import_type, std::string order = "")
+{
+    VolumeImportInfo info(filename);
+    std::string importType(info.getPixelType());
+
+    if(python::extract<std::string>(import_type).check())
+    {
+        std::string type = python::extract<std::string>(import_type)();
+        if(type != "" && type != "NATIVE")
+            importType = type;
+    }
+    else if(python::extract<NPY_TYPES>(import_type).check())
+    {
+        importType = detail::numpyTypeIdToImpexString(python::extract<NPY_TYPES>(import_type)());
+    }
+    else if(import_type)
+        vigra_precondition(false, "readVolume(filename, import_type, order): import_type must be a string or a numpy dtype.");
+
+    if(importType == "FLOAT")
+        return detail::readVolumeImpl<float>(info, order);
+    if(importType == "UINT8")
+        return detail::readVolumeImpl<UInt8>(info, order);
+    if(importType == "INT16")
+        return detail::readVolumeImpl<Int16>(info, order);
+    if(importType == "UINT16")
+        return detail::readVolumeImpl<UInt16>(info, order);
+    if(importType == "INT32")
+        return detail::readVolumeImpl<Int32>(info, order);
+    if(importType == "UINT32")
+        return detail::readVolumeImpl<UInt32>(info, order);
+    if(importType == "DOUBLE")
+        return detail::readVolumeImpl<double>(info, order);
+    vigra_fail("readVolume(filename, import_type, order): import_type specifies an unknown pixel type.");
+    return NumpyAnyArray();
+}
+
+template <class T>
+void writeVolume(NumpyArray<3, T > const & volume,
+                    const char * filename_base, 
+                    const char * filename_ext, 
+                    python::object export_type,  
+                    const char * compression = "")
+{
+    VolumeExportInfo info(filename_base, filename_ext);
+    
+    if(python::extract<std::string>(export_type).check())
+    {
+        std::string type = python::extract<std::string>(export_type)();        
+        if(type == "NBYTE")
+        {
+            info.setForcedRangeMapping(0.0, 0.0, 0.0, 255.0);
+            info.setPixelType("UINT8");
+        }
+        else if(type != "" && type != "NATIVE")
+        {
+            info.setPixelType(type.c_str());
+        }
+    }
+    else if(python::extract<NPY_TYPES>(export_type).check())
+    {
+        info.setPixelType(detail::numpyTypeIdToImpexString(python::extract<NPY_TYPES>(export_type)()).c_str());
+    }
+    else if(export_type)
+        vigra_precondition(false, "writeVolume(filename, export_type): export_type must be a string or a numpy dtype.");
+        
+    if(std::string(compression) == "RunLength")
+        info.setCompression("RLE");
+    else if(std::string(compression) != "")
+        info.setCompression(compression);
+    exportVolume(volume, info);
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pywriteVolume, writeVolume)
+
+NPY_TYPES
+impexTypeNameToNumpyTypeId(const std::string& typeName)
+{
+    if (typeName=="UINT8") return NPY_UINT8;
+    else if (typeName=="INT8") return NPY_INT8;
+    else if (typeName=="INT16") return NPY_INT16;
+    else if (typeName=="UINT16") return NPY_UINT16;
+    else if (typeName=="INT32") return NPY_INT32;
+    else if (typeName=="UINT32") return NPY_UINT32;
+    else if (typeName=="DOUBLE") return NPY_FLOAT64;
+    else if (typeName=="FLOAT") return NPY_FLOAT32;
+    else throw std::runtime_error("ImageInfo::getDtype(): unknown pixel type.");
+}
+
+NPY_TYPES
+pythonGetPixelType(const ImageImportInfo& info)
+{
+    return impexTypeNameToNumpyTypeId(info.getPixelType());
+}
+
+python::tuple
+pythonGetShape(const ImageImportInfo& info)
+{
+    return python::make_tuple(info.width(),info.height(),info.numBands());
+}
+
+AxisTags
+pythonGetAxisTags(const ImageImportInfo& info)
+{
+    return AxisTags(AxisInfo::x(), AxisInfo::y(), AxisInfo::c());
+}
+
+/***************************************************************************/
+
+void defineImpexFunctions()
+{
+    using namespace python;
+
+    docstring_options doc_options(true, false, false);
+
+    class_<ImageImportInfo>("ImageInfo", python::no_init)
+        .def(init<char const *>(args("filename"), "Extract header info from given file.\n\n"))
+        .def("getDtype", &pythonGetPixelType, "Get dtype of pixels in the file.")
+        .def("getShape", &pythonGetShape, "Get shape of image in the file.")
+        .def("getAxisTags", &pythonGetAxisTags, "Get axistags of image in the file.")
+    ;
+    
+    // FIXME: add an order parameter to the import functions
+    def("readVolume", &readVolume, (arg("filename"), arg("dtype") = "FLOAT", arg("order") = ""),
+        "Read a 3D volume from a directory::\n"
+        "\n"
+        "   readVolume(filename, dtype='FLOAT', order='') -> Volume\n"
+        "\n"
+        "If the filename refers to a multi-page TIFF file, the images in the file are\n"
+        "interpreted as the z-slices of the volume.\n"
+        "\n"
+        "If the volume is stored in a by-slice manner (e.g. one file per\n"
+        "z-slice), the 'filename' can refer to an arbitrary image from the set.\n"
+        "readVolume() then assumes that the slices are enumerated like::\n"
+        "\n"
+        "   name_base+[0-9]+name_ext\n"
+        "\n"
+        "where name_base, the index, and name_ext\n"
+        "are determined automatically. All slice files with the same name base\n"
+        "and extension are considered part of the same volume. Slice numbers\n"
+        "must be non-negative, but can otherwise start anywhere and need not\n"
+        "be successive. Slices will be read in ascending numerical (not\n"
+        "lexicographic) order. All slices must have the same size.\n"
+        "\n"
+        "Otherwise, readVolume() will try to read 'filename' as an info text\n"
+        "file with the following key-value pairs::\n"
+        "\n"
+        "    name = [short descriptive name of the volume] (optional)\n"
+        "    filename = [absolute or relative path to raw voxel data file] (required)\n"
+        "    gradfile =  [abs. or rel. path to gradient data file] (currently ignored)\n"
+        "    description =  [arbitrary description of the data set] (optional)\n"
+        "    width = [positive integer] (required)\n"
+        "    height = [positive integer] (required)\n"
+        "    depth = [positive integer] (required)\n"
+        "    datatype = [UNSIGNED_CHAR | UNSIGNED_BYTE] (default: UNSIGNED_CHAR)\n"
+        "\n"
+        "Lines starting with # are ignored.\n"
+        "When import_type is 'UINT8', 'INT16', 'UINT16', 'INT32', 'UINT32',\n"
+        "'FLOAT', 'DOUBLE', or one of the corresponding numpy dtypes (numpy.uint8\n"
+        "etc.), the returned volume will have the requested pixel type. \n"
+        "\n"
+        "The order parameter determines the axis ordering of the resulting array\n"
+        "(allowed values: 'C', 'F', 'V'). When order == '' (the default), " 
+        "vigra.VigraArray.defaultOrder is used.\n"
+        "\n"
+        "For details see the help for :func:`readImage`.\n");
+        
+    multidef("writeVolume", pywriteVolume<Singleband<Int8>, Singleband<UInt64>, Singleband<Int64>, Singleband<UInt16>, 
+                                          Singleband<Int16>, Singleband<UInt32>, Singleband<Int32>, Singleband<double>, 
+                                          Singleband<float>, Singleband<UInt8>, TinyVector<float, 3>, TinyVector<UInt8, 3> >(), 
+       (arg("volume"), arg("filename_base"), arg("filename_ext"), arg("dtype") = "", arg("compression") = ""),
+       "Write a volume as a sequence of images::\n\n"
+       "   writeVolume(volume, filename_base, filename_ext, dtype='', compression='')\n\n"
+       "The resulting image sequence will be enumerated in the form::\n\n"
+       "    filename_base+[0-9]+filename_ext\n\n"
+       "Write a volume as a multi-page tiff (filename_ext must be an empty string)::\n\n"
+       "   writeVolume(volume, filename, '', dtype='', compression='')\n\n"
+       "Parameters 'dtype' and 'compression' will be handled as in :func:`writeImage`.\n\n");
+    
+    def("readImage", &readImage, 
+        (arg("filename"), arg("dtype") = "FLOAT", arg("index") = 0, arg("order") = ""),
+        "Read an image from a file::\n"
+        "\n"
+        "   readImage(filename, dtype='FLOAT', index=0, order='') -> Image\n"
+        "\n"
+        "When 'dtype' is 'UINT8', 'INT16', 'UINT16', 'INT32', 'UINT32',\n"
+        "'FLOAT', 'DOUBLE', or one of the corresponding numpy dtypes (numpy.uint8\n"
+        "etc.), the returned image will have the requested pixel type. If\n"
+        "dtype is 'NATIVE' or '' (empty string), the image is imported with\n"
+        "the original type of the data in the file. By default, image data are\n"
+        "returned as 'FLOAT' (i.e. numpy.float32). Caution: If the requested \n"
+        "dtype is smaller than the original type in the file, values will be\n"
+        "clipped at the bounds of the representable range, which may not be the\n"
+        "desired behavior.\n"
+        "\n"
+        "Individual images of sequential formats such as multi-image TIFF can be \n"
+        "accessed via 'index'. The number of images in a file can be checked with the \n"
+        "function :func:`numberImages`. Alternatively, :func:`readVolume` can read \n"
+        "an entire multi-page TIFF in one go.\n"
+        "\n"
+        "The 'order' parameter determines the axis ordering of the resulting array\n"
+        "(allowed values: 'C', 'F', 'V'). When order == '' (the default), \n" 
+        "'vigra.VigraArray.defaultOrder' is used.\n"
+        "\n"
+        "Supported file formats are listed by the function :func:`listFormats`.\n"
+        "When 'filename' does not refer to a recognized image file format, an\n"
+        "exception is raised. The file can be checked beforehand with the function\n"
+        ":func:`isImage`.\n");
+        
+    multidef("writeImage", pywriteImage<Int8, UInt64, Int64, UInt16, Int16, UInt32, Int32, double, float, UInt8>(),
+       (arg("image"), arg("filename"), arg("dtype") = "", arg("compression") = "", arg("mode") = "w"),
+        "Save an image to a file::\n"
+        "\n"
+        "   writeImage(image, filename, dtype='', compression='', mode='w')\n"
+        "\n"
+        "Parameters:\n\n"
+        " image:\n"
+        "    the image to be saved\n"
+        " filename:\n"
+        "    the file name to save to. The file type will be deduced\n"
+        "    from the file name extension (see vigra.impexListExtensions()\n"
+        "    for a list of supported extensions).\n"
+        " dtype:\n"
+        "    the pixel type written to the file. Possible values:\n\n"
+        "     '' or 'NATIVE':\n"
+        "        save with original pixel type, or convert automatically\n"
+        "        when this type is unsupported by the target file format\n"
+        "     'UINT8', 'INT16', 'UINT16', 'INT32', 'UINT32', 'FLOAT', 'DOUBLE':\n"
+        "        save as specified, or raise exception when this type is not \n"
+        "        supported by the target file format (see list below)\n"
+        "     'NBYTE':\n"
+        "        normalize to range 0...255 and then save as 'UINT8'\n"
+        "     numpy.uint8, numpy.int16 etc.:\n"
+        "        behaves like the corresponding string argument\n\n"
+        " compression:\n"
+        "     how to compress the data (ignored when compression type is unsupported \n"
+        "     by the file format). Possible values:\n\n"
+        "     '' or not given:\n"
+        "        save with the native compression of the target file format\n"
+        "     'RLE', 'RunLength':\n"
+        "        use run length encoding (native in BMP, supported by TIFF)\n"
+        "     'DEFLATE':\n"
+        "        use deflate encoding (only supported by TIFF)\n"
+        "     'LZW':\n"
+        "        use LZW algorithm (only supported by TIFF with LZW enabled)\n"
+        "     'ASCII':\n"
+        "        write as ASCII rather than binary file (only supported by PNM)\n"
+        "     '1' ... '100':\n"
+        "        use this JPEG compression level (only supported by JPEG and TIFF)\n\n"
+        " mode:\n"
+        "     support for sequential file formats such as multi-image TIFF. \n"
+        "     Possible values:\n\n"
+        "     'w':\n"
+        "        create a new file (default)\n"
+        "     'a':\n"
+        "        append an image to a file or create a new one if the file does \n"
+        "        not exist (only supported by TIFF to create multi-page TIFF files)\n\n"
+        "Supported file formats are listed by the function vigra.impexListFormats().\n"
+        "The different file formats support the following pixel types:\n\n"
+        "   BMP:\n"
+        "       Microsoft Windows bitmap image file (pixel type: UINT8 as gray and RGB).\n"
+        "   GIF:\n"
+        "       CompuServe graphics interchange format; 8-bit color\n"
+        "       (pixel type: UINT8 as gray and RGB).\n"
+        "   JPEG:\n"
+        "       Joint Photographic Experts Group JFIF format; compressed 24-bit color\n"
+        "       (pixel types: UINT8 as gray and RGB). Only available if libjpeg is\n"
+        "       installed.\n"
+        "   PNG:\n"
+        "       Portable Network Graphic (pixel types: UINT8 and UINT16 with\n"
+        "       up to 4 channels). (only available if libpng is installed)\n"
+        "   PBM:\n"
+        "       Portable bitmap format (black and white).\n"
+        "   PGM:\n"
+        "       Portable graymap format (pixel types: UINT8, INT16, INT32 as gray scale).\n"
+        "   PNM:\n"
+        "       Portable anymap (pixel types: UINT8, INT16, INT32, gray and RGB)\n"
+        "   PPM:\n"
+        "       Portable pixmap format (pixel types: UINT8, INT16, INT32 as RGB)\n"
+        "   SUN:\n"
+        "       SUN Rasterfile (pixel types: UINT8 as gray and RGB).\n"
+        "   TIFF:\n"
+        "       Tagged Image File Format (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE\n"
+        "       with up to 4 channels). Only available if libtiff is installed.\n"
+        "   VIFF:\n"
+        "       Khoros Visualization image file (pixel types: UINT8, INT16\n"
+        "       INT32, FLOAT, DOUBLE with arbitrary many channels).\n\n");
+        
+    def("listFormats", &impexListFormats,
+        "Ask for the image file formats that vigra.impex understands::\n\n"
+        "    listFormats() -> string\n\n"
+        "This function returns a string containing the supported image file "
+        "formats for reading and writing with the functions :func:`readImage` and "
+        ":func:`writeImage`.\n");
+        
+    def("listExtensions", &impexListExtensions,
+        "Ask for the image file extensions that vigra.impex understands::\n\n"
+        "    listExtensions() -> string\n\n"
+        "This function returns a string containing the supported image file "
+        "extensions for reading and writing with the functions :func:`readImage` and "
+        ":func:`writeImage`.\n");
+        
+    def("isImage", &isImage, args("filename"),
+        "Check whether the given file name contains image data::\n\n"
+        "   isImage(filename) -> bool\n\n"
+        "This function tests whether a file has a supported image format. "
+        "It checks the first few bytes of the file and compares them with "
+        "the \"magic strings\" of each recognized image format. If the "
+        "image format is supported it returns True otherwise False.\n");
+    def("numberImages", &numberImages, args("filename"),
+        "Check how many images the given file contains::\n\n"
+        "   numberImages(filename) -> int\n\n"
+        "This function tests how many images an image file contains"
+        "(Values > 1 are only expected for the TIFF format to support multi-image TIFF).");
+
+}
+
+} // namespace vigra
+
+using namespace vigra;
+using namespace boost::python;
+
+BOOST_PYTHON_MODULE_INIT(impex)
+{
+    import_vigranumpy();
+    defineImpexFunctions();
+}
diff --git a/vigranumpy/src/core/interestpoints.cxx b/vigranumpy/src/core/interestpoints.cxx
new file mode 100644
index 0000000..34d2d0b
--- /dev/null
+++ b/vigranumpy/src/core/interestpoints.cxx
@@ -0,0 +1,197 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyanalysis_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/cornerdetection.hxx>
+#include <vigra/boundarytensor.hxx>
+#include <vigra/mathutil.hxx>
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+template < class PixelType >
+NumpyAnyArray 
+pythonCornerResponseFunction2D(NumpyArray<2, Singleband<PixelType> > image,
+                               double scale=1.0,
+                               NumpyArray<2, Singleband<PixelType> > res = python::object() )
+{
+    std::string description("Harris cornerness, scale=");
+    description += asString(scale);
+
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "cornernessHarris(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        cornerResponseFunction(srcImageRange(image), destImage(res), scale);
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonFoerstnerCornerDetector2D(NumpyArray<2, Singleband<PixelType> > image,
+                                double scale=1.0,
+                                NumpyArray<2, Singleband<PixelType> > res = python::object() )
+{
+    std::string description("Foerstner cornerness, scale=");
+    description += asString(scale);
+
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "cornernessFoerstner(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        foerstnerCornerDetector(srcImageRange(image), destImage(res), scale);
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonRohrCornerDetector2D(NumpyArray<2, Singleband<PixelType> > image,
+                           double scale = 1.0,
+                           NumpyArray<2, Singleband<PixelType> > res = python::object())
+{
+    std::string description("Rohr cornerness, scale=");
+    description += asString(scale);
+
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "cornernessRohr(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        rohrCornerDetector(srcImageRange(image), destImage(res), scale);
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonBeaudetCornerDetector2D(NumpyArray<2, Singleband<PixelType> > image,
+                              double scale=1.0,
+                              NumpyArray<2, Singleband<PixelType> > res = python::object())
+{
+    std::string description("Beaudet cornerness, scale=");
+    description += asString(scale);
+
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "cornernessBeaudet(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        beaudetCornerDetector(srcImageRange(image), destImage(res), scale);
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonBoundaryTensorCornerDetector2D(NumpyArray<2, Singleband<PixelType> > image,
+                                     double scale=1.0,
+                                     NumpyArray<2, Singleband<PixelType> > res = python::object())
+{
+    std::string description("boundary tensor cornerness, scale=");
+    description += asString(scale);
+
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+        "cornernessBoundaryTensor(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        MultiArray<2, TinyVector<PixelType, 3> > bt(image.shape());
+        boundaryTensor(srcImageRange(image), destImage(bt), scale);
+        
+        PixelType ev1, ev2;
+        for(int y=0; y<image.shape(1); ++y)
+        {
+            for(int x=0; x<image.shape(0); ++x)
+            {
+                symmetric2x2Eigenvalues(bt(x,y)[0], bt(x,y)[1], bt(x,y)[2], &ev1, &ev2);
+                res(x,y) = PixelType(2.0)*ev2;
+            }
+        }
+    }
+    return res;
+}
+
+
+void defineInterestpoints()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+
+    def("cornernessHarris",
+        registerConverters(&pythonCornerResponseFunction2D<float>),
+        (arg("image"), arg("scale"),arg("out")=python::object()),
+        "Find corners in a scalar 2D image using the method of Harris at the given 'scale'.\n\n"
+        "For details see cornerResponseFunction_ in the vigra C++ documentation.\n"
+        );
+
+    def("cornernessFoerstner",
+        registerConverters(&pythonFoerstnerCornerDetector2D<float>), 
+        (arg("image"), arg("scale"),arg("out")=python::object()),
+        "Find corners in a scalar 2D image using the method of Foerstner at the given 'scale'.\n\n"
+        "For details see foerstnerCornerDetector_ in the vigra C++ documentation.\n");
+
+    def("cornernessRohr",
+        registerConverters(&pythonRohrCornerDetector2D<float>), 
+        (arg("image"), arg("scale"),arg("out")=python::object()),
+        "Find corners in a scalar 2D image using the method of Rohr at the given 'scale'.\n\n"
+        "For details see rohrCornerDetector_ in the vigra C++ documentation.\n");
+
+    def("cornernessBeaudet",
+        registerConverters(&pythonBeaudetCornerDetector2D<float>),
+        (arg("image"), arg("scale"),arg("out")=python::object()),
+        "Find corners in a scalar 2D image using the method of Beaudet at the given 'scale'.\n\n"
+        "For details see beaudetCornerDetector_ in the vigra C++ documentation.\n");
+
+    def("cornernessBoundaryTensor",
+        registerConverters(&pythonBoundaryTensorCornerDetector2D<float>),
+        (arg("image"), arg("scale"),arg("out")=python::object()),
+        "Find corners in a scalar 2D image using the boundary tensor at the given 'scale'.\n\n"
+        "Specifically, the cornerness is defined as twice the small eigenvalue "
+        "of the boundary tensor.\n\n"
+        "For details see boundaryTensor_ in the vigra C++ documentation.\n");
+}
+
+} // namespace vigra
diff --git a/vigranumpy/src/core/kernel.cxx b/vigranumpy/src/core/kernel.cxx
new file mode 100644
index 0000000..18203f9
--- /dev/null
+++ b/vigranumpy/src/core/kernel.cxx
@@ -0,0 +1,491 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyfilters_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include <Python.h>
+#include <vigra/config.hxx>
+#include <iostream>
+#include <boost/python.hpp>
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include "vigranumpykernel.hxx"
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+template<class T>
+void pythonInitExplicitlyKernel1D(Kernel1D<T> &k, int left, int right, NumpyArray<1,T> contents)
+{
+    vigra_precondition(contents.size() == 1 || right-left+1 == contents.shape(0),
+              "Kernel1D::initExplicitly(): 'contents' must contain as many elements as the kernel (or just one element).");
+              
+    k.initExplicitly(left,right);
+    for(int i=left; i<=right; ++i)
+    {
+        k[i] = (contents.size() == 1)
+                     ? contents(0)
+                     : contents(i-left);
+    }
+}
+
+#if 0 // alternative implementation
+template<class KernelValueType>
+void pythonInitExplicitlyKernel1D(Kernel1D<KernelValueType> & self, int left, int right,
+    python::object const & args)
+{
+    vigra_precondition(left <= 0, "left should be <= 0");
+    vigra_precondition(right >= 0, "right should be >= 0");
+
+    if(! PySequence_Check(args.ptr()))
+    {
+        KernelValueType value = python::extract<KernelValueType>(args);
+        self.initExplicitly(left, right) = value;
+    }
+    else
+    {
+        KernelValueType value = python::extract<KernelValueType>(args[0]);
+        Kernel::InitProxy ip = self.initExplicitly(left, right) = value;
+        if(python::len(args) != self.size())
+        {
+            std::stringstream str;
+            str << "Wrong number of init values. The number must be ";
+            str << self.size();
+            PyErr_SetString(PyExc_ValueError, str.str().c_str());
+            python::throw_error_already_set();
+        }
+        else
+        {
+            int size = self.size();
+            for(int i=1; i<size; ++i)
+            {
+                ip,(python::extract<KernelValueType>(args[i]));
+            }
+        }
+    }
+}
+#endif // #if 0
+
+template<class T>
+T pythonGetItemKernel1D(Kernel1D<T> const & self, int position)
+{
+    if(self.left() <= position && self.right() >= position)
+    {
+        return self[position];
+    }
+    else
+    {
+        std::stringstream str;
+        str << "Bad position: " << position << "." << std::endl;
+        str << self.left() << " <= position <= " << self.right();
+        PyErr_SetString(PyExc_ValueError, str.str().c_str());
+        python::throw_error_already_set();
+        return 0;
+    }
+}
+
+template<class T>
+void pythonSetItemKernel1D(Kernel1D<T> & self, int position, T value)
+{
+    if(self.left() <= position && self.right() >= position)
+    {
+        self[position] = value;
+    }
+    else
+    {
+        std::stringstream str;
+        str << "Bad position: " << position << "." << std::endl;
+        str << self.left() << " <= position <= " << self.right();
+        PyErr_SetString(PyExc_ValueError, str.str().c_str());
+        python::throw_error_already_set();
+    }
+}
+    
+template<class T>
+void pythonInitExplicitlyKernel2D(Kernel2D<T> &k,
+                                  MultiArrayShape<2>::type upperleft, MultiArrayShape<2>::type lowerright,
+                                  NumpyArray<2,T> contents)
+{
+    vigra_precondition(contents.size() == 1 || 
+                       lowerright - upperleft + MultiArrayShape<2>::type(1,1) == contents.shape(),
+              "Kernel2D::initExplicitly(): 'contents' must contain as many elements as the kernel (or just one element).");
+
+    Point2D ul(upperleft[0], upperleft[1]), lr(lowerright[0], lowerright[1]);
+    
+    k.initExplicitly(ul, lr);
+
+    for(int y = ul.y; y <= lr.y; ++y)
+    {
+        for(int x = ul.x; x <= lr.x; ++x)
+        {
+            k(x,y) = (contents.size() == 1)
+                           ? contents(0)
+                           : contents(x-ul.x, y-ul.y);
+        }
+    }
+}
+
+#if 0 // alternative implementation
+void py2DKernel_initExplicitly(TwoDKernel & self, int upperleftX,
+    int upperleftY, int lowerrightX, int lowerrightY,
+    python::object const & args)
+{
+    vigra_precondition(upperleftX <= 0 ,
+       "initExplicitly(): upperleftX must be <= 0.");
+    vigra_precondition(upperleftY <= 0 ,
+       "initExplicitly(): upperleftY must be <= 0.");
+    vigra_precondition(lowerrightX >= 0 ,
+       "initExplicitly(): lowerrightX must be >= 0.");
+    vigra_precondition(lowerrightY >= 0 ,
+       "initExplicitly(): lowerrightY must be >= 0.");
+    Diff2D upperleft(upperleftX, upperleftY);
+    Diff2D lowerright(lowerrightX, lowerrightY);
+    if(! PySequence_Check(args.ptr()))
+    {
+        KernelValueType value = python::extract<KernelValueType>(args);
+        self.initExplicitly(upperleft, lowerright) = value;
+    }
+    else
+    {
+        KernelValueType value = python::extract<KernelValueType>(args[0]);
+        TwoDKernel::InitProxy ip = self.initExplicitly(upperleft, lowerright) =
+            value;
+        if(python::len(args) != (self.width() * self.height()))
+        {
+            std::stringstream str;
+            str << "Wrong number of init values. The number must be ";
+            str << self.width() * self.height();
+            PyErr_SetString(PyExc_ValueError, str.str().c_str());
+            python::throw_error_already_set();
+        }
+        else
+        {
+            int size = self.width() * self.height();
+            for(int i=1; i<size; ++i)
+            {
+                ip,(python::extract<KernelValueType>(args[i]));
+            }
+        }
+    }
+}
+#endif
+
+template<class T>
+T pythonGetItemKernel2D(Kernel2D<T> const & self, MultiArrayShape<2>::type position)
+{
+    if(self.upperLeft().x <= position[0] && self.lowerRight().x >= position[0] &&
+       self.upperLeft().y <= position[1] && self.lowerRight().y >= position[1])
+    {
+        return self(position[0], position[1]);
+    }
+    else
+    {
+        std::stringstream str;
+        str << "Bad position: " << position << "." << std::endl;
+        str << self.upperLeft() << " <= position <= " << self.lowerRight();
+        PyErr_SetString(PyExc_ValueError, str.str().c_str());
+        python::throw_error_already_set();
+        return 0;
+    }
+}
+
+template<class T>
+void pythonSetItemKernel2D(Kernel2D<T> & self, MultiArrayShape<2>::type position, T value)
+{
+    if(self.upperLeft().x <= position[0] && self.lowerRight().x >= position[0] &&
+       self.upperLeft().y <= position[1] && self.lowerRight().y >= position[1])
+    {
+        self(position[0], position[1]) = value;
+    }
+    else
+    {
+        std::stringstream str;
+        str << "Bad position: " << position << "." << std::endl;
+        str << self.upperLeft() << " <= position <= " << self.lowerRight();
+        PyErr_SetString(PyExc_ValueError, str.str().c_str());
+        python::throw_error_already_set();
+    }
+}   
+
+template<class T>
+void defineKernels()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+
+    enum_<BorderTreatmentMode>("BorderTreatmentMode")
+        .value("BORDER_TREATMENT_AVOID",BORDER_TREATMENT_AVOID)
+        .value("BORDER_TREATMENT_CLIP",BORDER_TREATMENT_CLIP)
+        .value("BORDER_TREATMENT_REPEAT",BORDER_TREATMENT_REPEAT)
+        .value("BORDER_TREATMENT_REFLECT",BORDER_TREATMENT_REFLECT)
+        .value("BORDER_TREATMENT_WRAP",BORDER_TREATMENT_WRAP);
+
+    class_<Kernel1D<T> > kernel1d("Kernel1D",
+                                "Generic 1 dimensional convolution kernel.\n\n"
+                                "This kernel may be used for convolution of 1 dimensional signals or "
+                                "for separable convolution of multidimensional signals. "
+                                "The kernel's size is given by its left() and right() "
+                                "methods. The desired border treatment mode is returned by "
+                                "getBorderTreatment(). "
+                                "The different init functions create a kernel with the specified "
+                                "properties. "
+                                "For more details, see Kernel1D_ in the C++ documentation.\n\n",
+                                init<>("Standard constructor::\n\n   Kernel1D()\n\nCreates an identity kernel.\n"));
+    kernel1d
+        .def(init< Kernel1D<T> >(args("kernel"),
+            "Copy constructor::\n\n"
+            "   Kernel1D(other_kernel)\n\n"))
+        .def("initGaussian",
+             (void (Kernel1D<T>::*)(double,T, double))&Kernel1D<T>::initGaussian,
+             (arg("scale"), arg("norm")=1.0, arg("window_size")=0.0),
+                "Init kernel as a sampled Gaussian function. The radius of the kernel is "
+                "always 3*std_dev. 'norm' denotes the desired sum of all bins of the "
+                "kernel (i.e. the kernel is corrected for the normalization error "
+                "introduced by windowing the Gaussian to a finite interval). "
+                "However, if norm is 0.0, the kernel is normalized to 1 by the "
+                "analytic expression for the Gaussian, and no correction for the "
+                "windowing error is performed.\n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'gaussianKernel()'.\n\n")
+        .def("initDiscreteGaussian",
+             (void (Kernel1D<T>::*)(double,T))&Kernel1D<T>::initDiscreteGaussian,
+             (arg("scale"),arg("norm")=1.0),
+                "Init kernel as Lindeberg's discrete analog of the Gaussian function. "
+                "The radius of the kernel is always 3*std_dev. 'norm' denotes "
+                "the desired sum of all bins of the kernel.\n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'discreteGaussianKernel()'.\n\n")
+        .def("initGaussianDerivative",
+             (void (Kernel1D<T>::*)(double,int,T,double))&Kernel1D<T>::initGaussianDerivative,
+             (arg("scale"),arg("order"),arg("norm")=1.0, arg("window_size")=0.0),
+                "Init kernel as a Gaussian derivative of order 'order'. The radius of "
+                "the kernel is always 3*std_dev + 0.5*order. 'norm' denotes "
+                "the norm of the kernel. Thus, the kernel will be corrected for "
+                "the error introduced by windowing the Gaussian to a finite "
+                "interval. However, if norm is 0.0, the kernel is normalized to 1 "
+                "by the analytic expression for the Gaussian derivative, and no "
+                "correction for the windowing error is performed.\n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'gaussianDerivativeKernel()'.\n\n")
+        .def("initBurtFilter",
+             &Kernel1D<T>::initBurtFilter,
+             (arg("a")=0.04785),
+                "Init kernel as a 5-tap smoothing filter of the form::\n\n"
+                "   [ a, 0.25, 0.5 - 2*a, 0.25, a]\n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'burtFilterKernel()'.\n\n")
+        .def("initBinomial",
+             (void (Kernel1D<T>::*)(int,T))&Kernel1D<T>::initBinomial,
+             (arg("radius"), arg("norm")=1.0),
+                "Init kernel as a binomial filter with given radius (i.e. window size 2*radius+1). "
+                "'norm' denotes the sum of all bins of the kernel.\n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'binomialKernel()'.\n\n")
+        .def("initAveraging",
+             (void (Kernel1D<T>::*)(int,T))&Kernel1D<T>::initAveraging,
+             (arg("radius"),arg("norm")=1.0),
+                "Init kernel as an averaging filter with given radius (i.e. window size 2*radius+1). "
+                "'norm' denotes the sum of all bins of the kernel.\n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'averagingKernel()'.\n\n")
+        .def("initSymmetricDifference",
+             (void (Kernel1D<T>::*)(T))&Kernel1D<T>::initSymmetricDifference,
+             (arg("norm")=1.0),
+                "Init kernel as a symmetric difference filter of the form::\n\n"
+                "   [ 0.5 * norm, 0.0 * norm, -0.5 * norm]\n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'symmetricDifferenceKernel()'.\n\n")
+        .def("initSecondDifference3",
+             &Kernel1D<T>::initSecondDifference3,
+                "Init kernel as a 3-tap second difference filter of the form::\n\n"
+                "   [ 1, -2, 1]\n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'secondDifference3Kernel()'.\n\n")
+        .def("initOptimalSmoothing3",
+             &Kernel1D<T>::initOptimalSmoothing3)
+        .def("initOptimalFirstDerivativeSmoothing3",
+             &Kernel1D<T>::initOptimalFirstDerivativeSmoothing3)
+        .def("initOptimalSecondDerivativeSmoothing3",
+             &Kernel1D<T>::initOptimalSecondDerivativeSmoothing3)
+        .def("initOptimalSmoothing5",
+             &Kernel1D<T>::initOptimalSmoothing5)
+        .def("initOptimalFirstDerivativeSmoothing5",
+             &Kernel1D<T>::initOptimalFirstDerivativeSmoothing5)
+        .def("initOptimalSecondDerivativeSmoothing5",
+             &Kernel1D<T>::initOptimalSecondDerivativeSmoothing5)
+        .def("initOptimalFirstDerivative5",
+             &Kernel1D<T>::initOptimalFirstDerivative5)
+        .def("initOptimalSecondDerivative5",
+             &Kernel1D<T>::initOptimalSecondDerivative5)
+        .def("initExplicitly",
+             registerConverters(&pythonInitExplicitlyKernel1D<T>),
+             (arg("left"), arg("right"), arg("contents")),
+                "Init the kernel with explicit values from 'contents', which must be a "
+                "1D numpy.ndarray. 'left' and 'right' are the boundaries of the kernel "
+                "(inclusive). If 'contents' contains the wrong number of values, a "
+                "run-time error results. It is, however, possible to give just one "
+                "initializer. This creates an averaging filter with the given constant. "
+                "The norm is set to the sum of the initializer values. \n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'explicitlyKernel()'.\n\n")
+        .def("__getitem__",
+             &pythonGetItemKernel1D<T>)
+        .def("__setitem__",
+             &pythonSetItemKernel1D<T>)
+        .def("left",
+             &Kernel1D<T>::left,
+                "Left border of kernel (inclusive).\n")
+        .def("right",
+             &Kernel1D<T>::right,
+                "Right border of kernel (inclusive).\n")
+        .def("size",
+             &Kernel1D<T>::size,
+                "Number of kernel elements (right() - left() + 1).\n")
+        .def("borderTreatment",
+             &Kernel1D<T>::borderTreatment,
+                "Return current border treatment mode.\n")
+        .def("setBorderTreatment",
+             &Kernel1D<T>::setBorderTreatment,
+             args("borderTreatment"),
+                "Set border treatment mode.\n")
+        .def("norm",
+             &Kernel1D<T>::norm,
+                "Return the norm of kernel.\n")
+        .def("normalize",
+             (void (Kernel1D<T>::*)(T,unsigned int,double))&Kernel1D<T>::normalize,
+             (arg("norm")=1.0,arg("derivativeOrder")=0,arg("offset")= 0.0),
+                "Set a new norm and normalize kernel, use the normalization "
+                "formula for the given derivativeOrder.\n")
+        ;
+
+    class_<Kernel2D<T> > kernel2d("Kernel2D",
+            "Generic 2 dimensional convolution kernel.\n\n"
+            "This kernel may be used for convolution of 2 dimensional signals. "
+            "The desired border treatment mode is returned by borderTreatment()."
+            "(Note that the 2D convolution functions don't currently support all "
+            "modes.) "
+            "The different init functions create a kernel with the specified "
+            "properties. "
+            "For more details, see Kernel2D_ in the C++ documentation.\n\n",
+            init<>("Standard constructor::\n\n   Kernel2D()\n\nCreates an identity kernel.\n"));
+    kernel2d
+        .def(init< Kernel2D<T> >(args("kernel"),
+            "Copy constructor::\n\n"
+            "   Kernel2D(other_kernel)\n\n"))
+        .def("initExplicitly",
+             registerConverters(&pythonInitExplicitlyKernel2D<T>),
+             (arg("upperLeft"), arg("lowerRight"), arg("contents")),
+                "Init the kernel with explicit values from 'contents', which must be a "
+                "2D numpy.ndarray. 'upperLeft' and 'lowerRight' are the boundaries of the "
+                "kernel (inclusive), and  must be 2D tuples. "
+                "If 'contents' contains the wrong number of values, a run-time error "
+                "results. It is, however, possible to give just one initializer. "
+                "This creates an averaging filter with the given constant. "
+                "The norm is set to the sum of the initializer values. \n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'explicitlyKernel2D()'.\n\n")
+        .def("initSeparable",
+             (void (Kernel2D<T>::*)(Kernel1D<T> const &,Kernel1D<T> const &))&Kernel2D<T>::initSeparable,
+             (arg("kernelX"), arg("kernelY")),
+                "Init the 2D kernel as the cartesian product of two 1D kernels of "
+                "type Kernel1D. The norm becomes the product of the two original "
+                "norms.\n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'separableKernel2D()'.\n\n")
+        .def("initGaussian",
+             (void (Kernel2D<T>::*)(double, T))&Kernel2D<T>::initGaussian,
+             (arg("scale"), arg("norm")=1.0),
+                "Init kernel as a sampled 2D Gaussian function. The radius of the kernel is "
+                "always 3*std_dev. 'norm' denotes the desired sum of all bins of the "
+                "kernel (i.e. the kernel is corrected for the normalization error "
+                "introduced by windowing the Gaussian to a finite interval). "
+                "However, if norm is 0.0, the kernel is normalized to 1 by the "
+                "analytic expression for the Gaussian, and no correction for the "
+                "windowing error is performed.\n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'gaussianKernel2D()'.\n\n")
+        .def("initDisk",
+             &Kernel2D<T>::initDisk,
+             args("radius"),
+                "Init the 2D kernel as a circular averaging filter. The norm will "
+                "be calculated as 1 / (number of non-zero kernel values).\n\n"
+                "Precondition::\n\n"
+                "   radius > 0\n\n"
+                "Kernel construction and initialization can be performed in one step "
+                "by calling the factory function 'diskKernel2D()'.\n\n")
+        .def("__setitem__",
+             &pythonSetItemKernel2D<T>)
+        .def("__getitem__",
+             &pythonGetItemKernel2D<T>)
+        .def("width",
+             &Kernel2D<T>::width,
+                "Horizontal kernel size (lowerRight()[0] - upperLeft()[0] + 1).\n")
+        .def("height",
+             &Kernel2D<T>::height,
+                "Vertical kernel size (lowerRight()[1] - upperLeft()[1] + 1).\n")
+        .def("upperLeft",
+             &Kernel2D<T>::upperLeft,
+                "Upper left border of kernel (inclusive).\n")
+        .def("lowerRight",
+             &Kernel2D<T>::lowerRight,
+                "Lower right border of kernel (inclusive).\n")
+        .def("norm",
+             &Kernel2D<T>::norm,
+                "Return the norm of the kernel.\n")
+        .def("normalize",
+            (void (Kernel2D<T>::*)(T))&Kernel2D<T>::normalize,
+             (arg("norm")=1.0),
+                "Set the kernel's norm and renormalize the values.\n")
+        .def("borderTreatment",
+             &Kernel2D<T>::borderTreatment,
+                "Return current border treatment mode.\n")
+        .def("setBorderTreatment",
+             &Kernel2D<T>::setBorderTreatment,
+             args("borderTreatment"),
+                "Set border treatment mode.\n")
+    ;
+}
+
+void defineKernels()
+{
+    defineKernels<KernelValueType>();
+}
+
+} // namespace vigra
+
diff --git a/vigranumpy/src/core/learning.cxx b/vigranumpy/src/core/learning.cxx
new file mode 100644
index 0000000..eb0d6a7
--- /dev/null
+++ b/vigranumpy/src/core/learning.cxx
@@ -0,0 +1,150 @@
+/************************************************************************/
+/*                                                                      */
+/*       Copyright 2011 by Ullrich Koethe and Michael Hanselmann        */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyrigfht notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpylearning_PyArray_API
+// #define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/unsupervised_decomposition.hxx>
+#include <set>
+#include <cmath>
+#include <memory>
+#include <boost/python.hpp>
+
+namespace python = boost::python;
+namespace vigra
+{
+
+template<class U>
+python::tuple
+pythonPCA(NumpyArray<2,U> features, int nComponents)
+{
+    vigra_precondition(!features.axistags(),
+                       "principleComponents(): feature matrix must not have axistags\n"
+                       "(use 'array.view(numpy.ndarray)' to remove them).");
+    
+    NumpyArray<2, U> fz(Shape2(features.shape(0), nComponents)); 
+    NumpyArray<2, U> zv(Shape2(nComponents, features.shape(1))); 
+
+    {
+        PyAllowThreads _pythread;
+        principleComponents(features, fz, zv);
+    }
+    return python::make_tuple(fz, zv);
+}
+
+template<class U>
+python::tuple
+pythonPLSA(NumpyArray<2,U> features, 
+           int nComponents,
+           int nIterations,
+           double minGain,
+           bool normalize)
+{
+    vigra_precondition(!features.axistags(),
+                       "pLSA(): feature matrix must not have axistags\n"
+                       "(use 'array.view(numpy.ndarray)' to remove them).");
+    
+    NumpyArray<2, U> fz(Shape2(features.shape(0), nComponents)); 
+    NumpyArray<2, U> zv(Shape2(nComponents, features.shape(1))); 
+
+    {
+        PyAllowThreads _pythread;
+        pLSA(features, fz, zv,
+             RandomNumberGenerator<>(), 
+             PLSAOptions().maximumNumberOfIterations(nIterations)
+                          .minimumRelativeGain(minGain)
+                          .normalizedComponentWeights(normalize));
+    }
+    return python::make_tuple(fz, zv);
+}
+
+
+void defineUnsupervised()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+
+    def("principleComponents", registerConverters(&pythonPCA<double>),
+        (arg("features"), arg("nComponents")),
+        "\nPerform principle component analysis. \n\n"
+        "The imput matrix 'features' must have shape (nFeatures*nSamples). PCA will\n"
+        "reduce it to a smaller matrix 'C' with shape (nComponents*nSamples) that \n"
+        "preserves as much variance as possible. Specifically, the call::\n\n"
+        "    P, C = principleComponents(features, 3)\n\n"
+        "returns a projection matrix 'P' with shape (nComponents*nFeatures)\n"
+        "such that ``C = numpy.dot(numpy.transpose(P), features)``. Conversely, the\n"
+        "matrix  ``f = numpy.dot(P, C)`` is the best possible rank-nComponents\n"
+        "approximation to the matrix 'features' under the least-squares criterion.\n\n"
+        "See principleComponents_ in the C++ documentation for more detailed\ninformation.\n\n");
+
+    PLSAOptions options;
+
+    def("pLSA", registerConverters(&pythonPLSA<double>),
+        (arg("features"), arg("nComponents"), arg("nIterations") = options.max_iterations,
+         arg("minGain") = options.min_rel_gain, arg("normalize") = options.normalized_component_weights),
+        "\nPerform probabilistic latent semantic analysis. \n\n"
+        "The imput matrix 'features' must have shape (nFeatures*nSamples). PCA will\n"
+        "reduce it to a smaller matrix 'C' with shape (nComponents*nSamples) that \n"
+        "preserves as much information as possible. Specifically, the call::\n\n"
+        "    P, C = pLSA(features, 3)\n\n"
+        "returns a projection matrix 'P' with shape (nComponents*nFeatures)\n"
+        "such that the matrix ``f = numpy.dot(P, C)`` is a rank-nComponents matrix\n"
+        "that approximates the matrix 'features' well under the pLSA criterion.\n"
+        "Note that the result of pLSA() is not unique, since the algorithm uses random\n"
+        "initialization.\n\n"
+        "See pLSA_ in the C++ documentation for more detailed\ninformation.\n\n");
+}
+
+void defineRandomForest();
+void defineRandomForestOld();
+
+} // namespace vigra
+
+
+using namespace vigra;
+using namespace boost::python;
+
+BOOST_PYTHON_MODULE_INIT(learning)
+{
+    import_vigranumpy();
+    defineUnsupervised();
+    defineRandomForest();
+    defineRandomForestOld();
+}
+
+
diff --git a/vigranumpy/src/core/morphology.cxx b/vigranumpy/src/core/morphology.cxx
new file mode 100644
index 0000000..115d4b5
--- /dev/null
+++ b/vigranumpy/src/core/morphology.cxx
@@ -0,0 +1,778 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyfilters_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/flatmorphology.hxx>
+#include <vigra/multi_morphology.hxx>
+#include <vigra/distancetransform.hxx>
+#include <vigra/multi_distance.hxx>
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+template < class PixelType >
+NumpyAnyArray 
+pythonDiscRankOrderFilter(NumpyArray<3, Multiband<PixelType> > image,
+                          int radius, float rank, 
+                          NumpyArray<3, Multiband<PixelType> > res)
+{
+    vigra_precondition((rank >= 0.0) && (rank <= 1.0),
+        "Rank must be in the range 0.0 <= rank <= 1.0");
+    vigra_precondition(radius >= 0, "Radius must be >= 0.");
+
+    res.reshapeIfEmpty(image.taggedShape(),
+            "discRankOrderFilter(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0; k<image.shape(2); ++k)
+        { 
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            discRankOrderFilter(srcImageRange(bimage,StandardValueAccessor<UInt8>()), 
+                                destImage(bres), radius, rank);
+        }
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonDiscRankOrderFilterWithMask(NumpyArray<3, Multiband<PixelType> > image,
+                                  NumpyArray<3, Multiband<PixelType> > mask,
+                                  int radius, float rank,
+                                  NumpyArray<3, Multiband<PixelType> > res)
+{
+    vigra_precondition((rank >= 0.0) && (rank <= 1.0),
+        "Rank must be in the range 0.0 <= rank <= 1.0");
+    vigra_precondition(radius >= 0, "Radius must be >= 0.");
+    vigra_precondition(mask.shape(2)==1 || mask.shape(2)==image.shape(2),
+               "discRankOrderFilterWithMask(): mask image must either have 1 channel or as many as the input image");
+    vigra_precondition(mask.shape(0)==image.shape(0) && mask.shape(1)==image.shape(1),
+               "discRankOrderFilterWithMaks(): mask dimensions must be same as image dimensions");
+
+    res.reshapeIfEmpty(image.taggedShape(),
+            "discRankOrderFilterWithMask(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0; k<image.shape(2); ++k)
+        { 
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bmask = mask.bindOuter(mask.shape(2)==1?0:k);
+            discRankOrderFilterWithMask(srcImageRange(bimage,StandardValueAccessor<UInt8>()), 
+                                        srcImage(bmask),
+                                        destImage(bres), radius, rank);
+        }
+    }
+    
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonDiscErosion(NumpyArray<3, Multiband<PixelType> > image,
+                  int radius, 
+                  NumpyArray<3, Multiband<PixelType> > res)
+{
+    return pythonDiscRankOrderFilter(image, radius, 0.0f, res);
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonDiscDilation(NumpyArray<3, Multiband<PixelType> > image,
+                   int radius, 
+                   NumpyArray<3, Multiband<PixelType> > res)
+{
+    return pythonDiscRankOrderFilter(image, radius, 1.0f, res);
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonDiscMedian(NumpyArray<3, Multiband<PixelType> > image,
+                 int radius, 
+                 NumpyArray<3, Multiband<PixelType> > res)
+{
+    return pythonDiscRankOrderFilter(image, radius, 0.5f, res);
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonDiscOpening(NumpyArray<3, Multiband<PixelType> > image, 
+                  int radius, 
+                  NumpyArray<3, Multiband<PixelType> > res)
+{
+    vigra_precondition(radius >= 0, "Radius must be >=0.");
+
+    res.reshapeIfEmpty(image.taggedShape(),
+            "discOpening(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        MultiArray<2,PixelType> tmp(MultiArrayShape<2>::type(image.shape(0), image.shape(1)));
+
+        for(int k=0; k<image.shape(2); ++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            discErosion(srcImageRange(bimage), destImage(tmp), radius);
+            discDilation(srcImageRange(tmp), destImage(bres), radius);
+        }
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonDiscClosing(NumpyArray<3, Multiband<PixelType> > image, 
+                  int radius, 
+                  NumpyArray<3, Multiband<PixelType> > res)
+{
+    vigra_precondition(radius >= 0, "Radius must be >=0.");
+
+    res.reshapeIfEmpty(image.taggedShape(),
+            "discClosing(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        MultiArray<2,PixelType> tmp(MultiArrayShape<2>::type(image.shape(0), image.shape(1)));
+
+        for(int k=0; k<image.shape(2); ++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            discDilation(srcImageRange(bimage), destImage(tmp), radius);
+            discErosion(srcImageRange(tmp), destImage(bres), radius);
+        }
+    }
+    return res;
+}
+
+template < int dim, class PixelType >
+NumpyAnyArray 
+pythonMultiBinaryErosion(NumpyArray<dim, Multiband<PixelType> > array,
+                         double radius, 
+                         NumpyArray<dim, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(array.taggedShape(),
+            "multiBinaryErosion(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0; k<array.shape(dim-1); ++k)
+        {
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            multiBinaryErosion(srcMultiArrayRange(barray), destMultiArray(bres), radius);
+        }
+    }
+    return res;
+}
+
+template < int dim, class PixelType >
+NumpyAnyArray 
+pythonMultiBinaryDilation(NumpyArray<dim, Multiband<PixelType> > array,
+                          double radius, 
+                          NumpyArray<dim, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(array.taggedShape(),
+            "multiBinaryDilation(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0; k<array.shape(dim-1); ++k)
+        {
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            multiBinaryDilation(srcMultiArrayRange(barray), destMultiArray(bres), radius);
+        }
+    }
+    return res;
+}
+
+template <int dim, class PixelType >
+NumpyAnyArray 
+pythonMultiBinaryOpening(NumpyArray<dim, Multiband<PixelType> > array, 
+                         double radius, 
+                         NumpyArray<dim, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(array.taggedShape(),
+            "multiBinaryOpening(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        MultiArray<dim-1,PixelType> tmp(typename MultiArrayShape<dim-1>::type(array.shape().begin()));
+
+        for(int k=0; k<array.shape(dim-1); ++k)
+        {
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            multiBinaryErosion(srcMultiArrayRange(barray), destMultiArray(tmp), radius);
+            multiBinaryDilation(srcMultiArrayRange(tmp), destMultiArray(bres), radius);
+        }
+    }
+    return res;
+}
+
+template <int dim, class PixelType >
+NumpyAnyArray 
+pythonMultiBinaryClosing(NumpyArray<dim, Multiband<PixelType> > array, 
+                         double radius, 
+                         NumpyArray<dim, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(array.taggedShape(),
+            "multiBinaryOpening(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        MultiArray<dim-1,PixelType> tmp(typename MultiArrayShape<dim-1>::type(array.shape().begin()));
+
+        for(int k=0; k<array.shape(dim-1); ++k)
+        {
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            multiBinaryDilation(srcMultiArrayRange(barray), destMultiArray(tmp), radius);
+            multiBinaryErosion(srcMultiArrayRange(tmp), destMultiArray(bres), radius);
+        }
+    }
+    return res;
+}
+
+template < int dim , class PixelType>
+NumpyAnyArray 
+pythonMultiGrayscaleErosion(NumpyArray<dim, Multiband<PixelType> > array, 
+                            double sigma, 
+                            NumpyArray<dim, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(array.taggedShape(),
+            "multiGrayscaleErosion(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0; k<array.shape(dim-1); ++k)
+        {
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            multiGrayscaleErosion(srcMultiArrayRange(barray), destMultiArray(bres), sigma);
+        }
+    }
+    return res;
+}
+template < int dim, class PixelType >
+NumpyAnyArray 
+pythonMultiGrayscaleDilation(NumpyArray<dim, Multiband<PixelType> > array, 
+                             double sigma, 
+                             NumpyArray<dim, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(array.taggedShape(),
+            "multiGrayscaleDilation(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0; k<array.shape(dim-1); ++k)
+        {
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            multiGrayscaleDilation(srcMultiArrayRange(barray), destMultiArray(bres), sigma);
+        }
+    }
+    return res;
+}
+
+template <int dim, class PixelType>
+NumpyAnyArray 
+pythonMultiGrayscaleOpening(NumpyArray<dim, Multiband<PixelType> > array, 
+                            double sigma, 
+                            NumpyArray<dim, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(array.taggedShape(),
+            "multiGrayscaleOpening(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        MultiArray<dim-1,PixelType> tmp(typename MultiArrayShape<dim-1>::type(array.shape().begin()));
+
+        for(int k=0; k<array.shape(dim-1); ++k)
+        {
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            multiGrayscaleErosion(srcMultiArrayRange(barray), destMultiArray(tmp), sigma);
+            multiGrayscaleDilation(srcMultiArrayRange(tmp), destMultiArray(bres), sigma);
+        }
+    }
+    return res;
+}
+
+template <int dim, class PixelType>
+NumpyAnyArray 
+pythonMultiGrayscaleClosing(NumpyArray<dim, Multiband<PixelType> > array, 
+                            double sigma, 
+                            NumpyArray<dim, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(array.taggedShape(),
+            "multiGrayscaleClosing(): Output image has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        MultiArray<dim-1,PixelType> tmp(typename MultiArrayShape<dim-1>::type(array.shape().begin()));
+
+        for(int k=0; k<array.shape(dim-1); ++k)
+        {
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> barray = array.bindOuter(k);
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            multiGrayscaleDilation(srcMultiArrayRange(barray), destMultiArray(tmp), sigma);
+            multiGrayscaleErosion(srcMultiArrayRange(tmp), destMultiArray(bres), sigma);
+        }
+    }
+    return res;
+}
+
+namespace detail {
+
+template <class PixelType>
+struct IsBackgroundAccessor
+{
+    typedef bool value_type;
+    
+    template <class Iterator>
+    value_type operator()(Iterator const & i) const
+    {
+        return *i == NumericTraits<PixelType>::zero();
+    }
+};
+
+} // namespace detail
+
+template < class PixelType, typename DestPixelType >
+NumpyAnyArray 
+pythonDistanceTransform2D(NumpyArray<2, Singleband<PixelType> > image,
+                          bool background, 
+                          int norm,
+                          ArrayVector<double> pixelPitch = ArrayVector<double>(),
+                          NumpyArray<2, Singleband<DestPixelType> > res = python::object())
+{
+    res.reshapeIfEmpty(image.taggedShape(), 
+            "distanceTransform2D(): Output array has wrong shape.");
+    
+    if(pixelPitch.size() == 0)
+    {
+        PyAllowThreads _pythread;
+        if(background)
+        {
+            distanceTransform(srcImageRange(image), destImage(res), 
+                              NumericTraits<PixelType>::zero(), norm);
+        }
+        else
+        {
+            distanceTransform(srcImageRange(image, detail::IsBackgroundAccessor<PixelType>()), 
+                              destImage(res), false, norm);
+        }
+    }
+    else
+    {
+        vigra_precondition(norm == 2,
+             "distanceTransform2D(): Anisotropic transform is only supported for norm=2.");
+        pixelPitch = image.permuteLikewise(pixelPitch);
+        
+        PyAllowThreads _pythread;
+        separableMultiDistance(srcMultiArrayRange(image), destMultiArray(res), background, pixelPitch);
+    }
+
+    return res;
+}
+
+template < class VoxelType >
+NumpyAnyArray 
+pythonDistanceTransform3D(NumpyArray<3, Singleband<VoxelType> > volume, 
+                          bool background, 
+                          ArrayVector<double> pixelPitch = ArrayVector<double>(),
+                          NumpyArray<3, Singleband<VoxelType> > res=python::object())
+{
+    res.reshapeIfEmpty(volume.taggedShape(), 
+            "distanceTransform3D(): Output array has wrong shape.");
+    
+    if (pixelPitch.size() == 0)
+    {
+        pixelPitch = ArrayVector<double>(3, 1.0);
+    }
+    else
+    {
+        pixelPitch = volume.permuteLikewise(pixelPitch);
+    }
+    
+    {
+        PyAllowThreads _pythread;
+        separableMultiDistance(srcMultiArrayRange(volume), destMultiArray(res), background, pixelPitch);
+    }
+    return res;
+}
+
+void defineMorphology()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+
+    def("discRankOrderFilter",
+        registerConverters(&pythonDiscRankOrderFilter<float>),
+        (arg("image"), arg("radius"), arg("rank"), arg("out")=object()),
+        "Apply rank order filter with disc structuring function to a float image.\n\n"
+        "The pixel values of the source image  must be in the range 0...255. Radius must be >= 0. "
+        "Rank must be in the range 0.0 <= rank <= 1.0. The filter acts as a minimum filter if rank = 0.0, as a median "
+        "if rank = 0.5, and as a maximum filter if rank = 1.0. "
+        "This function also works for multiband images, it is then executed on every band.\n"
+        "\n" 
+        "For details see discRankOrderFilter_ in the C++ documentation.\n"
+       );
+
+    def("discRankOrderFilter",
+        registerConverters(&pythonDiscRankOrderFilter<UInt8>),
+        (arg("image"), arg("radius"), arg("rank"), arg("out")=object()),
+        "Likewise for a uint8 image.\n");
+
+    def("discRankOrderFilterWithMask",
+        registerConverters(&pythonDiscRankOrderFilterWithMask<float>),
+        (arg("image"), arg("mask"), arg("radius"), arg("rank"), arg("out")=object()),
+        "Apply rank order filter with disc structuring function to a float image using a mask.\n"
+        "\n"
+        "The pixel values of the source image must be in the range 0...255. Radius must be >= 0."
+        "Rank must be in the range 0.0 <= rank <= 1.0. The filter acts as a minimum filter if rank = 0.0,"
+        "as a median if rank = 0.5, and as a maximum filter if rank = 1.0.\n"
+        "\n"
+        "The mask is only applied to the input image, i.e. the function generates an output "
+        "wherever the current disc contains at least one pixel with non-zero mask value. "
+        "Source pixels with mask value zero are ignored during the calculation of "
+        "the rank order.\n\n"
+        "This function also works for multiband images, it is then executed on every band. "
+        "If the mask has only one band, it is used for every image band. If the mask has "
+        "the same number of bands, as the image the bands are used for the corresponding image bands.\n\n"
+        "For details see discRankOrderFilterWithMask_ in the C++ documentation.\n"
+        );
+    
+    def("discRankOrderFilterWithMask",
+        registerConverters(&pythonDiscRankOrderFilterWithMask<UInt8>),
+        (arg("image"), arg("mask"), arg("radius"), arg("rank"), arg("out")=object()),
+        "Likewise for a uint8 image.\n");
+
+    def("discErosion",
+        registerConverters(&pythonDiscErosion<UInt8>),
+        (arg("image"), arg("radius"), arg("out")=object()),
+        "Apply erosion (minimum) filter with disc of given radius to image.\n\n"
+        "This is an abbreviation for the rank order filter with rank = 0.0. "
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "See discErosion_ in the C++ documentation for more information.\n"
+        );
+
+    def("discDilation",
+        registerConverters(&pythonDiscDilation<UInt8>),
+        (arg("image"), arg("radius"), arg("out")=object()),
+        "Apply dilation (maximum) filter with disc of given radius to image.\n\n"
+        "This is an abbreviation for the rank order filter with rank = 1.0. "
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "See discDilation_ in the C++ documentation for more information.\n"
+       );
+
+    def("discMedian",
+        registerConverters(&pythonDiscMedian<UInt8>),
+        (arg("image"), arg("radius"), arg("out")=object()),
+        "Apply median filter with disc of given radius to image.\n\n"
+        "This is an abbreviation for the rank order filter with rank = 0.5. "
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "See discMedian_ in the C++ documentation for more information.\n"
+        );
+
+    def("discOpening",
+        registerConverters(&pythonDiscOpening<UInt8>),
+        (arg("image"), arg("radius"), arg("out")=object()),
+        "Apply a opening filter with disc of given radius to image.\n\n"
+        "This is an abbreviation for applying an erosion and a dilation filter in sequence. "
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "See discRankOrderFilter_ in the C++ documentation for more information.\n"
+       );
+
+    def("discClosing",
+        registerConverters(&pythonDiscClosing<UInt8>),
+        (arg("image"), arg("radius"), arg("out")=object()),
+        "Apply a closing filter with disc of given radius to image.\n\n"
+        "This is an abbreviation for applying a dilation and an erosion  filter in sequence. "
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "See discRankOrderFilter_ in the C++ documentation for more information.\n"
+       );
+
+    def("multiBinaryErosion",
+        registerConverters(&pythonMultiBinaryErosion<4, UInt8>),
+        (arg("volume"), arg("radius"), arg("out")=object()),
+       "Binary erosion on a 3D scalar or multiband uint8 array.\n"
+       "\n"
+       "This function applies a flat circular erosion operator with a given radius. "
+       "The operation is isotropic. The input is a uint8 or boolean multi-dimensional array "
+       "where non-zero pixels represent foreground and zero pixels represent background. "
+       "This function also works for multiband arrays, it is then executed on every band.\n"
+       "\n"
+       "For details see multiBinaryErosion_ in the C++ documentation.\n"
+        );
+        
+    def("multiBinaryErosion",
+        registerConverters(&pythonMultiBinaryErosion<4, bool>),
+        (arg("volume"), arg("radius"), arg("out")=object()),
+        "Likewise for a bool array.\n");
+
+    def("multiBinaryDilation",
+        registerConverters(&pythonMultiBinaryDilation<4, UInt8>),
+        (arg("volume"), arg("radius"), arg("out")=object()),
+       "Binary dilation on a 3D scalar or multiband uint8 array.\n"
+       "\n"
+       "This function applies a flat circular dilation operator with a given radius. "
+       "The operation is isotropic. The input is a uint8 or boolean multi-dimensional array "
+       "where non-zero pixels represent foreground and zero pixels represent background. "
+       "This function also works for multiband arrays, it is then executed on every band.\n"
+       "\n"
+       "For details see multiBinaryDilation_ in the C++ documentation.\n"
+       );
+       
+    def("multiBinaryDilation",
+        registerConverters(&pythonMultiBinaryDilation<4, bool>),
+        (arg("volume"), arg("radius"), arg("out")=object()),
+        "Likewise for bool arrays.\n");
+    
+    def("multiBinaryOpening",
+        registerConverters(&pythonMultiBinaryOpening<4, UInt8>),
+        (arg("volume"), arg("radius"), arg("out")=object()),
+        "Binary opening on a 3D scalar or multiband uint8 array.\n"
+        "\n"
+        "This function applies a flat circular opening operator (sequential erosion "
+        "and dilation) with a given radius. The operation is isotropic. "
+        "The input is a uint8 or boolean multi-dimensional array where non-zero pixels represent "
+        "foreground and zero pixels represent background. "
+        "This function also works for multiband arrays, it is then executed on every band.\n"
+        "\n"
+        "For details see vigra C++ documentation (multiBinaryDilation_ and multiBinaryErosion_).\n"
+        );
+        
+    def("multiBinaryOpening",
+        registerConverters(&pythonMultiBinaryOpening<4, bool>),
+        (arg("volume"), arg("radius"), arg("out")=object()),
+        "Likewise for a bool array.\n");
+        
+    def("multiBinaryClosing",
+        registerConverters(&pythonMultiBinaryClosing<4, UInt8>),
+        (arg("volume"), arg("radius"), arg("out")=object()),
+        "Binary closing on a 3D scalar or multiband uint8 array.\n"
+        "\n"
+        "This function applies a flat circular opening operator (sequential dilation "
+        "and erosion) with a given radius. The operation is isotropic. "
+        "The input is a uint8 or boolean multi-dimensional array where non-zero pixels represent "
+        "foreground and zero pixels represent background. "
+        "This function also works for multiband arrays, it is then executed on every band.\n"
+        "\n"
+        "For details see vigra C++ documentation (multiBinaryDilation_ and multiBinaryErosion_).\n"
+        );
+        
+    def("multiBinaryClosing",
+        registerConverters(&pythonMultiBinaryClosing<4, bool>),
+        (arg("volume"), arg("radius"), arg("out")=object()),
+        "Likewise for a bool array.\n");
+    
+    def("multiGrayscaleErosion",
+        registerConverters(&pythonMultiGrayscaleErosion<4,UInt8>),
+        (arg("volume"), arg("sigma"), arg("out")=object()),
+        "Parabolic grayscale erosion on a 3D scalar or multiband uint8 array.\n"
+        "\n"
+        "This function applies a parabolic erosion operator with a given spread 'sigma' on a grayscale array. "
+        "The operation is isotropic. The input is a grayscale multi-dimensional array. "
+        "This function also works for multiband arrays, it is then executed on every band.\n"
+        "\n"
+        "For details see multiGrayscaleErosion_ in the C++ documentation.\n"
+        );
+                
+    def("multiGrayscaleErosion",
+        registerConverters(&pythonMultiGrayscaleErosion<4,float>),
+        (arg("volume"), arg("sigma"), arg("out")=object()),
+        "Likewise for a 3D float array.\n");
+
+    def("multiGrayscaleErosion",
+        registerConverters(&pythonMultiGrayscaleErosion<3,UInt8>),
+        (arg("image"), arg("sigma"), arg("out")=object()),
+        "Likewise for a 2D uint8 array.\n");
+    
+    def("multiGrayscaleErosion",
+        registerConverters(&pythonMultiGrayscaleErosion<3,float>),
+        (arg("image"), arg("sigma"), arg("out")=object()),
+        "Likewise for a 2D float array.\n");
+
+    def("multiGrayscaleDilation",
+        registerConverters(&pythonMultiGrayscaleDilation<4,UInt8>),
+        (arg("volume"), arg("sigma"), arg("out")=object()),
+        "Parabolic grayscale dilation on multi-dimensional arrays.\n"
+        "\n"
+        "This function applies a parabolic dilation operator with a given spread 'sigma' on a grayscale array. "
+        "The operation is isotropic. The input is a grayscale multi-dimensional array. "
+        "This function also works for multiband arrays, it is then executed on every band.\n"
+        "\n"
+        "For details see multiGrayscaleDilation_ in the C++ documentation.\n"
+        );
+        
+    def("multiGrayscaleDilation",
+        registerConverters(&pythonMultiGrayscaleDilation<4,float>),
+        (arg("volume"), arg("sigma"), arg("out")=object()),
+        "Likewise for a 3D float array.\n");
+
+    def("multiGrayscaleDilation",
+        registerConverters(&pythonMultiGrayscaleDilation<3,UInt8>),
+        (arg("image"), arg("sigma"), arg("out")=object()),
+        "Likewise for a 2D uint8 array.\n");
+
+    def("multiGrayscaleDilation",
+        registerConverters(&pythonMultiGrayscaleDilation<3,float>),
+        (arg("image"), arg("sigma"), arg("out")=object()));
+
+    def("multiGrayscaleOpening",
+        registerConverters(&pythonMultiGrayscaleOpening<4,UInt8>),
+        (arg("volume"), arg("sigma"), arg("out")=object()),
+        "Parabolic grayscale opening on multi-dimensional arrays.\n"
+        "\n"
+        "This function applies a parabolic opening (sequential erosion and dilation) "
+        "operator with a given spread 'sigma' on a grayscale array. "
+        "The operation is isotropic. The input is a grayscale multi-dimensional array. "
+        "This function also works for multiband arrays, it is then executed on every band.\n"
+        "\n"
+        "For details see multiGrayscaleDilation_ and multiGrayscaleErosion_ in the C++ documentation.\n"
+        );
+
+    def("multiGrayscaleOpening",
+        registerConverters(&pythonMultiGrayscaleOpening<4,float>),
+        (arg("volume"), arg("sigma"), arg("out")=object()),
+        "Likewise for a 3D float array.\n");
+
+    def("multiGrayscaleOpening",
+        registerConverters(&pythonMultiGrayscaleOpening<3,UInt8>),
+        (arg("image"), arg("sigma"), arg("out")=object()),
+        "Likewise for a 2D uint8 array.\n");
+
+    def("multiGrayscaleOpening",
+        registerConverters(&pythonMultiGrayscaleOpening<3,float>),
+        (arg("image"), arg("sigma"), arg("out")=object()));
+
+    def("multiGrayscaleClosing",
+        registerConverters(&pythonMultiGrayscaleClosing<4,UInt8>),
+        (arg("volume"), arg("sigma"), arg("out")=object()),
+        "Parabolic grayscale closing on multi-dimensional arrays.\n"
+        "\n"
+        "This function applies a parabolic closing (sequential dilation and erosion) "
+        "operator with a given spread 'sigma' on a grayscale array. "
+        "The operation is isotropic. The input is a grayscale multi-dimensional array. "
+        "This function also works for multiband arrays, it is then executed on every band.\n"
+        "\n"
+        "For details see multiGrayscaleDilation_ and multiGrayscaleErosion_ in the C++ documentation.\n"
+        );
+    
+    def("multiGrayscaleClosing",
+        registerConverters(&pythonMultiGrayscaleClosing<4,float>),
+        (arg("volume"), arg("sigma"), arg("out")=object()),
+        "Likewise for a 3D float array.\n");
+
+    def("multiGrayscaleClosing",
+        registerConverters(&pythonMultiGrayscaleClosing<3,UInt8>),
+        (arg("image"), arg("sigma"), arg("out")=object()),
+        "Likewise for a 2D uint8 array.\n");
+
+    def("multiGrayscaleClosing",
+        registerConverters(&pythonMultiGrayscaleClosing<3,float>),
+        (arg("image"), arg("sigma"), arg("out")=object()));
+
+    def("distanceTransform2D",
+        registerConverters(&pythonDistanceTransform2D<float, float>),
+        (arg("image"), 
+         arg("background")=true, 
+         arg("norm")=2,
+         arg("pixel_pitch") = ArrayVector<double>(), 
+         arg("out")=python::object()),
+        "Compute the distance transform of a 2D scalar float image.\n"
+        "All pixels with a value of 0.0 are considered to be background pixels,\n"
+        "while all pixels with a nonzero value are considered to be foreground pixels.\n"
+        "The parameter 'background' is a Boolean scalar that specifies whether to\n"
+        "compute the distance of all background pixels to the nearest foreground pixels\n"
+        "(if it is 'True', default) or vice versa (if it is 'False').\n"
+        "Hence in the destination image, for background==True all background pixels\n"
+        "will be assigned their distance value, while all foreground pixels will be assigned 0.\n"
+        "For background==False, it is exactly the other way around.\n\n"
+        "The 'norm' parameter gives the distance norm to use\n"
+        "(0: infinity norm, 1: L1 norm, 2: Euclidean norm).\n\n"
+        "If 'pixel_pitch' is given, it must contain the pixel distance along the two axes.\n"
+        "They are then used to compute the distance anisotropically. If no 'pixel_pitch' is\n"
+        "given, the data is treated isotropically with unit distance between pixels.\n"
+        "The anisotropic distance transform is only supported for norm =2 (Euclidean).\n"
+        "\n"
+        "For details see distanceTransform_ in the vigra C++ documentation.\n");
+
+        def("distanceTransform2D",
+        registerConverters(&pythonDistanceTransform2D<UInt8,float>),
+        (arg("image"), 
+         arg("background")=true, 
+         arg("norm")=2,
+         arg("pixel_pitch") = ArrayVector<double>(), 
+         arg("out")=python::object()),
+        "Likewise for a 2D uint8 input array.\n");
+
+    def("distanceTransform3D",
+        registerConverters(&pythonDistanceTransform3D<float>),
+        (arg("array"), 
+         arg("background") = true, 
+         arg("pixel_pitch") = ArrayVector<double>(), 
+         arg("out")=python::object()),
+        "Compute the Euclidean distance transform of a 3D scalar float volume.\n"
+        "All voxels with a value of 0.0 are considered to be background voxels,\n"
+        "while all voxels with a nonzero value are considered to be foreground voxels.\n"
+        "The parameter 'background' is a Boolean scalar that specifies whether to\n"
+        "compute the distance of all background voxels to the nearest foreground voxel\n"
+        "(if it is 'True', default) or vice versa (if it is 'False').\n"
+        "Hence in the destination volume, for background==True all background voxels\n"
+        "will be assigned their distance value, while all foreground voxels will be assigned 0.\n"
+        "For background==False, it is exactly the other way around.\n\n"
+        "If 'pixel_pitch' is given, it must contain the pixel distance along the three axes.\n"
+        "They are then used to compute the distance anisotropically. If no 'pixel_pitch' is\n"
+        "given, the data is treated isotropically with unit distance between pixels.\n"
+        "\n"
+        "For more details see separableMultiDistance_ in the vigra C++ documentation.\n");
+}
+
+} // namespace vigra
diff --git a/vigranumpy/src/core/noise.cxx b/vigranumpy/src/core/noise.cxx
new file mode 100644
index 0000000..5c9963b
--- /dev/null
+++ b/vigranumpy/src/core/noise.cxx
@@ -0,0 +1,357 @@
+
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpynoise_PyArray_API
+//#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/noise_normalization.hxx>
+#include <vigra/mathutil.hxx>
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+//TODO
+NumpyAnyArray vectorToArray(std::vector< TinyVector< double, 2 > > & result)
+{
+    NumpyArray<2,double> res(MultiArrayShape<2>::type(result.size(),2));
+
+    for(size_t ii=0;ii<result.size();++ii)
+    {
+        res(ii,0)=result[ii][0];
+        res(ii,1)=result[ii][1];
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonNoiseVarianceEstimation(NumpyArray<2, Singleband<PixelType> > image,
+                              bool useGradient=true, 
+                              unsigned int windowRadius=6,
+                              unsigned int clusterCount=10, 
+                              double averagingQuantile=0.8,
+                              double noiseEstimationQuantile=1.5, 
+                              double noiseVarianceInitialGuess=10.0,
+                              NumpyArray<3, Multiband<PixelType> > res=python::object())
+{
+    NoiseNormalizationOptions noiseNormalizationOptions;
+    noiseNormalizationOptions
+        .useGradient(useGradient)
+        .windowRadius(windowRadius)
+        .clusterCount(clusterCount)
+        .averagingQuantile(averagingQuantile)
+        .noiseEstimationQuantile(noiseEstimationQuantile)
+        .noiseVarianceInitialGuess(noiseVarianceInitialGuess);
+        
+    std::vector< TinyVector< double, 2 > > result;
+    
+    {
+        PyAllowThreads _pythread;
+        noiseVarianceEstimation(srcImageRange(image), result, noiseNormalizationOptions);
+    }
+    
+    return vectorToArray(result);
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonNoiseVarianceClustering(NumpyArray<2, Singleband<PixelType> > image,
+                              bool useGradient=true, 
+                              unsigned int windowRadius=6,
+                              unsigned int clusterCount=10, 
+                              double averagingQuantile=0.8,
+                              double noiseEstimationQuantile=1.5, 
+                              double noiseVarianceInitialGuess=10.0,
+                              NumpyArray<3, Multiband<PixelType> > res=python::object())
+{
+    NoiseNormalizationOptions noiseNormalizationOptions;
+    noiseNormalizationOptions
+        .useGradient(useGradient)
+        .windowRadius(windowRadius)
+        .clusterCount(clusterCount)
+        .averagingQuantile(averagingQuantile)
+        .noiseEstimationQuantile(noiseEstimationQuantile)
+        .noiseVarianceInitialGuess(noiseVarianceInitialGuess);
+        
+    std::vector< TinyVector< double, 2 > > result;
+    
+    {
+        PyAllowThreads _pythread;
+        noiseVarianceClustering(srcImageRange(image), result, noiseNormalizationOptions);
+    }
+    
+    return vectorToArray(result);
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonNonparametricNoiseNormalization(NumpyArray<3, Multiband<PixelType> > image,
+                                      bool useGradient=true, 
+                                      unsigned int windowRadius=6,
+                                      unsigned int clusterCount=10, 
+                                      double averagingQuantile=0.8,
+                                      double noiseEstimationQuantile=1.5, 
+                                      double noiseVarianceInitialGuess=10.0,
+                                      NumpyArray<3, Multiband<PixelType> > res=python::object())
+{
+    NoiseNormalizationOptions noiseNormalizationOptions;
+    noiseNormalizationOptions
+        .useGradient(useGradient)
+        .windowRadius(windowRadius)
+        .clusterCount(clusterCount)
+        .averagingQuantile(averagingQuantile)
+        .noiseEstimationQuantile(noiseEstimationQuantile)
+        .noiseVarianceInitialGuess(noiseVarianceInitialGuess);
+    
+    res.reshapeIfEmpty(image.taggedShape(),
+            "nonparametricNoiseNormalization(): Output images has wrong dimensions");
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            nonparametricNoiseNormalization(srcImageRange(image),
+                                            destImage(res), noiseNormalizationOptions);
+        }
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonQuadraticNoiseNormalizationEstimated(NumpyArray<3, Multiband<PixelType> > image,
+                                           bool useGradient=true, 
+                                           unsigned int windowRadius=6,
+                                           unsigned int clusterCount=10, 
+                                           double averagingQuantile=0.8,
+                                           double noiseEstimationQuantile=1.5, 
+                                           double noiseVarianceInitialGuess=10.0,
+                                           NumpyArray<3, Multiband<PixelType> > res=python::object())
+{
+    NoiseNormalizationOptions noiseNormalizationOptions;
+    noiseNormalizationOptions
+        .useGradient(useGradient)
+        .windowRadius(windowRadius)
+        .clusterCount(clusterCount)
+        .averagingQuantile(averagingQuantile)
+        .noiseEstimationQuantile(noiseEstimationQuantile)
+        .noiseVarianceInitialGuess(noiseVarianceInitialGuess);
+
+    res.reshapeIfEmpty(image.taggedShape(),
+        "quadraticNoiseNormalizationEstimated(): Output images has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            quadraticNoiseNormalization(srcImageRange(bimage),
+                                        destImage(bres), noiseNormalizationOptions);
+        }
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonLinearNoiseNormalizationEstimated(NumpyArray<3, Multiband<PixelType> > image,
+                                        bool useGradient=true, 
+                                        unsigned int windowRadius=6,
+                                        unsigned int clusterCount=10, 
+                                        double averagingQuantile=0.8,
+                                        double noiseEstimationQuantile=1.5, 
+                                        double noiseVarianceInitialGuess=10.0,
+                                        NumpyArray<3, Multiband<PixelType> > res=python::object())
+{
+    NoiseNormalizationOptions noiseNormalizationOptions;
+    noiseNormalizationOptions
+        .useGradient(useGradient)
+        .windowRadius(windowRadius)
+        .clusterCount(clusterCount)
+        .averagingQuantile(averagingQuantile)
+        .noiseEstimationQuantile(noiseEstimationQuantile)
+        .noiseVarianceInitialGuess(noiseVarianceInitialGuess);
+    
+    res.reshapeIfEmpty(image.taggedShape(),
+        "linearNoiseNormalizationEstimated(): Output images has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            linearNoiseNormalization(srcImageRange(bimage),
+                                     destImage(bres), noiseNormalizationOptions);
+        }
+    }
+    return res;
+}
+
+
+template < class PixelType >
+NumpyAnyArray 
+pythonQuadraticNoiseNormalization(NumpyArray<3, Multiband<PixelType> > image,
+                                  double a0, double a1, double a2,
+                                  NumpyArray<3, Multiband<PixelType> > res=python::object())
+{
+    res.reshapeIfEmpty(image.taggedShape(),
+        "quadraticNoiseNormalization(): Output images has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            quadraticNoiseNormalization(srcImageRange(bimage), destImage(bres), a0, a1, a2);
+        }
+    }
+    
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonLinearNoiseNormalization(NumpyArray<3, Multiband<PixelType> > image,
+                               double a0, double a1, 
+                               NumpyArray<3, Multiband<PixelType> > res)
+{
+    res.reshapeIfEmpty(image.taggedShape(),
+            "linearNoiseNormalization(): Output images has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            linearNoiseNormalization(srcImageRange(bimage), destImage(bres),a0, a1);
+        } 
+    }
+    return res;
+}
+
+
+void defineNoise()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+
+    def("noiseVarianceEstimation",
+        registerConverters(&pythonNoiseVarianceEstimation<float>),
+        (arg("image"), arg("useGradient")=true, arg("windowRadius")=6,
+        arg("clusterCount")=10, arg("averagingQuantile")=0.8,
+        arg("noiseEstimationQuantile")=1.5,
+        arg("noiseVarianceInitialGuess")=10.0, arg("out")=object()),
+        "Determine the noise variance as a function of the image intensity.\n"
+        "\n"
+        "Returns an array with the means in the first column and the variances in the second column.\n"
+        "Since the length of the resulting array is not known beforhand, it can not be written into an preallocated array\n"
+        "(the \"out\" argument in most other vigra python functions.\n\n"
+        "For details see the vigra documentation noiseVarianceEstimation_.\n"
+        );
+
+    def("noiseVarianceClustering",
+        registerConverters(&pythonNoiseVarianceClustering<float>),
+        (arg("image"), arg("useGradient")=true, arg("windowRadius")=6,
+        arg("clusterCount")=10, arg("averagingQuantile")=0.8,
+        arg("noiseEstimationQuantile")=1.5,
+        arg("noiseVarianceInitialGuess")=10.0, arg("out")=object()),
+        "Determine the noise variance as a function of the image intensity and cluster the results.\n"
+        "This operator first calls noiseVarianceEstimation() to obtain a sequence of intensity/variance pairs,\n"
+        "which are then clustered using the median cut algorithm. Then the cluster centers (i.e. average variance vs. average intensity)\n"
+        "are determined and returned in the result sequence.\n"
+        "\n"
+        "Since the length of the resulting array is not known beforhand, it cannot be written into an preallocated array\n"
+        "(the \"out\" argument in most other vigra python functions)\n.\n"
+        "For details see the vigra documentation noiseVarianceClustering_.\n"
+        );
+
+    def("nonparametricNoiseNormalization",
+        registerConverters(&pythonNonparametricNoiseNormalization<float>),    // also multiband
+        (arg("image"), arg("useGradient")=true, arg("windowRadius")=6,
+        arg("clusterCount")=10, arg("averagingQuantile")=0.8,
+        arg("noiseEstimationQuantile")=1.5,
+        arg("noiseVarianceInitialGuess")=10.0, arg("out")=object()),
+        "Noise normalization by means of an estimated non-parametric noise model.\n\n"
+        "For details see nonparametricNoiseNormalization_ in the vigra C++ documentation.\n");
+
+    def("quadraticNoiseNormalizationEstimated",
+        registerConverters(&pythonQuadraticNoiseNormalizationEstimated<float>),    // also multiband
+        (arg("image"), arg("useGradient")=true, arg("windowRadius")=6,
+        arg("clusterCount")=10, arg("averagingQuantile")=0.8,
+        arg("noiseEstimationQuantile")=1.5,
+        arg("noiseVarianceInitialGuess")=10.0, arg("out")=object()));
+
+    def("linearNoiseNormalizationEstimated",
+        registerConverters(&pythonLinearNoiseNormalizationEstimated<float>),    // also multiband
+        (arg("image"), arg("useGradient")=true, arg("windowRadius")=6,
+        arg("clusterCount")=10, arg("averagingQuantile")=0.8,
+        arg("noiseEstimationQuantile")=1.5,
+        arg("noiseVarianceInitialGuess")=10.0, arg("out")=object()));
+
+    def("quadraticNoiseNormalization",
+        registerConverters(&pythonQuadraticNoiseNormalization<float>),    // also multiband
+        (arg("image"), arg("a0"), arg("a1"), arg("a2"), arg("out")=object()),
+        "Noise normalization by means of an estimated quadratic noise model.\n\n"
+        "For details see quadraticNoiseNormalization_ in the vigra C++ documentation.\n"
+        );
+
+    def("linearNoiseNormalization",
+        registerConverters(&pythonLinearNoiseNormalization<float>),    // also multiband
+        (arg("image"), arg("a0"), arg("a1"), arg("out")=object()),
+        "Noise normalization by means of an estimated linear noise model.\n\n"
+        "For details see linearNoiseNormalization_ in the vigra C++ documentation.\n"
+       );
+}
+
+} // namespace vigra
+
+using namespace vigra;
+using namespace boost::python;
+
+BOOST_PYTHON_MODULE_INIT(noise)
+{
+    import_vigranumpy();
+    defineNoise();
+}
diff --git a/vigranumpy/src/core/optimization.cxx b/vigranumpy/src/core/optimization.cxx
new file mode 100644
index 0000000..b9354ea
--- /dev/null
+++ b/vigranumpy/src/core/optimization.cxx
@@ -0,0 +1,234 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2011 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyoptimization_PyArray_API
+//#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/regression.hxx>
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+template <class T >
+NumpyAnyArray
+pythonLeastSquares(NumpyArray<2, T> A, NumpyArray<2, T> b)
+{
+    NumpyArray<2, T, UnstridedArrayTag> res(Shape2(A.shape(1), 1));
+    
+    {
+        PyAllowThreads _pythread;
+        
+        leastSquares(A, b, res);
+    }
+    return res;
+}
+
+template <class T >
+NumpyAnyArray
+pythonNonnegativeLeastSquares(NumpyArray<2, T> A, NumpyArray<2, T> b)
+{
+    NumpyArray<2, T, UnstridedArrayTag> res(Shape2(A.shape(1), 1));
+    
+    {
+        PyAllowThreads _pythread;
+        
+        nonnegativeLeastSquares(A, b, res);
+    }
+    return res;
+}
+
+template <class T >
+NumpyAnyArray
+pythonRidgeRegression(NumpyArray<2, T> A, NumpyArray<2, T> b, double lambda)
+{
+    NumpyArray<2, T, UnstridedArrayTag> res(Shape2(A.shape(1), 1));
+    
+    {
+        PyAllowThreads _pythread;
+        
+        ridgeRegression(A, b, res, lambda);
+    }
+    return res;
+}
+
+template <class T >
+python::tuple
+pythonlassoRegression(NumpyArray<2, T> A, NumpyArray<2, T> b,
+                      bool nonNegative,
+                      bool lsqSolutions,
+                      bool lassoSolutions,
+                      unsigned int maxSolutionCount)
+{
+    vigra_precondition(lsqSolutions || lassoSolutions,
+        "lassoRegression(): At least one of 'lsqSolutions' and 'lassoSolutions' must be 'True'.");
+    
+    ArrayVector<Matrix<double> > lasso_solutions, lsq_solutions;
+    ArrayVector<ArrayVector<MultiArrayIndex> > activeSets;
+    unsigned int numSolutions = 0;
+    
+    {
+        PyAllowThreads _pythread;
+        
+        ArrayVector<Matrix<double> > * plasso = lassoSolutions
+                                                     ? &lasso_solutions
+                                                     : 0,
+                                     * plsq = lsqSolutions
+                                                     ? &lsq_solutions
+                                                     : 0;
+                                                            
+        LeastAngleRegressionOptions options;
+        if(nonNegative)
+            options.nnlasso();
+        else
+            options.lasso();
+        options.maxSolutionCount(maxSolutionCount);
+    
+        numSolutions = 
+            linalg::detail::leastAngleRegressionImpl(A, b, activeSets, plasso, plsq, options);
+    }
+    
+    python::list pyActiveSets;
+    for(unsigned int k=0; k<numSolutions; ++k)
+        pyActiveSets.append(python::object(activeSets[k]));
+    python::list pyLassoSolutions;
+    if(lassoSolutions)
+    {
+        for(unsigned int k=0; k<numSolutions; ++k)
+        {
+            NumpyArray<2, double, UnstridedArrayTag> sol(Shape2(A.shape(1), 1));
+            for(unsigned int m=0; m<activeSets[k].size(); ++m)
+            {
+                sol(activeSets[k][m], 0) = lasso_solutions[k](m,0);
+            }
+            pyLassoSolutions.append(python::object(sol));
+        }
+    }
+    python::list pyLsqSolutions;
+    if(lsqSolutions)
+    {
+        for(unsigned int k=0; k<numSolutions; ++k)
+        {
+            NumpyArray<2, double, UnstridedArrayTag> sol(Shape2(A.shape(1), 1));
+            for(unsigned int m=0; m<activeSets[k].size(); ++m)
+            {
+                sol(activeSets[k][m], 0) = lsq_solutions[k](m,0);
+            }
+            pyLsqSolutions.append(python::object(sol));
+        }
+    }
+        
+    if(lsqSolutions)
+    {
+        if(lassoSolutions)
+            return python::make_tuple(numSolutions, pyActiveSets, pyLsqSolutions, pyLassoSolutions);
+        else
+            return python::make_tuple(numSolutions, pyActiveSets, pyLsqSolutions, python::object());
+    }
+    else
+    {
+        return python::make_tuple(numSolutions, pyActiveSets, python::object(), pyLassoSolutions);
+    }
+}
+
+
+void defineOptimization()
+{
+    using namespace python;
+
+    docstring_options doc_options(true, true, false);
+    
+    NumpyArrayConverter<NumpyArray<2, double, UnstridedArrayTag> >();
+
+    def("leastSquares", registerConverters(&pythonLeastSquares<double>),
+        (arg("A"), arg("b")),
+        "Perform plain linear regression.\n"
+        "\n"
+        "For details see leastSquares_ in the vigra C++ documentation.\n\n");
+
+    def("nonnegativeLeastSquares", registerConverters(&pythonNonnegativeLeastSquares<double>),
+        (arg("A"), arg("b")),
+        "Perform linear regression where the solution is constrained to be non-negative.\n"
+        "\n"
+        "For details see nonnegativeLeastSquares_ in the vigra C++ documentation.\n\n");
+
+    def("ridgeRegression", registerConverters(&pythonRidgeRegression<double>),
+        (arg("A"), arg("b"), arg("lambda")),
+        "Perform linear regression with L2 regularization.\n"
+        "\n"
+        "'lambda' is the regularization parameter - the larger it is, the more\n"
+        "biased towards zero the solution will become.\n"
+        "\n"
+        "For details see ridgeRegression_ in the vigra C++ documentation.\n\n");
+
+    def("lassoRegression", registerConverters(&pythonlassoRegression<double>),
+        (arg("A"), arg("b"), 
+         arg("nonNegative")=false, arg("lsq")=true, arg("lasso")=false, arg("maxSolutionCount")=0),
+        "Perform linear regression with L1 regularization.\n"
+        "\n"
+        "If 'nonNegative' is 'True', the solution will be constrained to non-negative\n"
+        "values, otherwise values may have arbitrary sign (the default).\n"
+        "If 'lsq' is 'True', the algorithm will return the least squares solution\n"
+        "for each active set. If 'lasso' is 'True', the LASSO solution will be returned\n"
+        "for each active set. Both may be 'True' simultaneously.\n"
+        "If 'maxSolutionCount' is non-zero, atr most so many active sets will\n"
+        "be computed.\n"
+        "\n"
+        "The algorithm returns a tuple::\n\n"
+        "   (numActiveSets, activeSets, lsqSolutions, lassoSolutions)\n\n"
+        "where 'numActiveSets' specifies how many active sets have been computed,\n"
+        "'activeSets' is the list of all active sets (ordered by decreasing regularization),\n"
+        "and 'lsqSolutions' and 'lassoSolutions' are lists of the corresponding solutions\n"
+        "for each active set ('lsqSolutions' and 'lassoSolutions' will be 'None' when\n"
+        "the corresponding function argument was 'False'). An active set is a list of\n"
+        "indices of all variables whose values are non-zero in the corresponding\n"
+        "solution.\n"
+        "\n"
+        "For details see leastAngleRegression_ in the vigra C++ documentation.\n\n");
+}
+
+} // namespace vigra
+
+using namespace vigra;
+using namespace boost::python;
+
+BOOST_PYTHON_MODULE_INIT(optimization)
+{
+    import_vigranumpy();
+    defineOptimization();
+}
diff --git a/vigranumpy/src/core/pythonaccumulator.hxx b/vigranumpy/src/core/pythonaccumulator.hxx
new file mode 100644
index 0000000..558a84b
--- /dev/null
+++ b/vigranumpy/src/core/pythonaccumulator.hxx
@@ -0,0 +1,955 @@
+/************************************************************************/
+/*                                                                      */
+/*            Copyright 2011-2012 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#ifndef VIGRA_PYTHONACCUMULATOR_HXX
+#define VIGRA_PYTHONACCUMULATOR_HXX
+
+#ifdef _MSC_VER
+#pragma warning (disable: 4503)
+#endif
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/accumulator.hxx>
+#include <vigra/timing.hxx>
+#include <map>
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+namespace acc 
+{
+
+struct GetTag_Visitor
+{
+    mutable python::object result;
+    
+    GetTag_Visitor()
+    {}
+    
+    template <class Permutation>
+    GetTag_Visitor(Permutation const & p)
+    {}
+
+    python::object to_python(signed char t) const { return python::object(t); }
+    python::object to_python(signed short t) const { return python::object(t); }
+    python::object to_python(signed int t) const { return python::object(t); }
+    python::object to_python(signed long t) const { return python::object(t); }
+    python::object to_python(signed long long t) const { return python::object(t); }
+    python::object to_python(unsigned char t) const { return python::object(t); }
+    python::object to_python(unsigned short t) const { return python::object(t); }
+    python::object to_python(unsigned int t) const { return python::object(t); }
+    python::object to_python(unsigned long t) const { return python::object(t); }
+    python::object to_python(unsigned long long t) const { return python::object(t); }
+    python::object to_python(float t) const { return python::object(t); }
+    python::object to_python(double t) const { return python::object(t); }
+    python::object to_python(long double t) const { return python::object(t); }
+    
+    template <class T, int N>
+    python::object to_python(TinyVector<T, N> const & t) const
+    {
+        NumpyArray<1, T> a = NumpyArray<1, T>(Shape1(N));
+        for(int k=0; k<N; ++k)
+            a(k) = t[k];
+        return python::object(a);
+    }
+    
+    template <class T, class Stride>
+    python::object to_python(MultiArrayView<1, T, Stride> const & t) const
+    {
+        NumpyArray<1, T> a(t);
+        return python::object(a);
+    }
+    
+    template <class T>
+    python::object to_python(Matrix<T> const & t) const
+    {
+        return python::object(t);
+    }
+    
+    template <class T1, class T2>
+    python::object to_python(std::pair<T1, T2> const & t) const
+    {
+        return python::make_tuple(to_python(t.first), to_python(t.second));
+    }
+    
+    template <class TAG, class Accu>
+    void exec(Accu & a) const
+    {
+        result = to_python(get<TAG>(a));
+    }
+};
+
+struct GetArrayTag_Visitor
+: public GetTag_Visitor
+{
+    template <class TAG, class T, class Accu>
+    struct ToPythonArray
+    {
+        template <class Permutation>
+        static python::object exec(Accu & a, Permutation const &)
+        {
+            unsigned int n = a.regionCount();
+            Shape1 s(n);
+            NumpyArray<1, T> res(s);
+            
+            for(unsigned int k=0; k<n; ++k)
+                res(k) = get<TAG>(a, k);
+            return python::object(res);
+        }
+    };
+    
+    template <class TAG, class T, int N, class Accu>
+    struct ToPythonArray<TAG, TinyVector<T, N>, Accu>
+    {
+        template <class Permutation>
+        static python::object exec(Accu & a, Permutation const & p)
+        {
+            unsigned int n = a.regionCount();
+            Shape2 s(n, N);
+            NumpyArray<2, T> res(s);
+            
+            for(unsigned int k=0; k<n; ++k)
+                for(int j=0; j<N; ++j)
+                    res(k, p(j)) = get<TAG>(a, k)[j];
+            return python::object(res);
+        }
+    };
+    
+    template <class TAG, class T, class Alloc, class Accu>
+    struct ToPythonArray<TAG, MultiArray<1, T, Alloc>, Accu>
+    {
+        template <class Permutation>
+        static python::object exec(Accu & a, Permutation const & p)
+        {
+            unsigned int n = a.regionCount();
+            MultiArrayIndex N = get<TAG>(a, 0).shape(0);
+            Shape2 s(n, N);
+            NumpyArray<2, T> res(s);
+            
+            for(unsigned int k=0; k<n; ++k)
+                for(int j=0; j<N; ++j)
+                    res(k, p(j)) = get<TAG>(a, k)[j];
+            return python::object(res);
+        }
+    };
+    
+    template <class TAG, class T, class Accu>
+    struct ToPythonArray<TAG, Matrix<T>, Accu>
+    {
+        template <class Permutation>
+        static python::object exec(Accu & a, Permutation const & p)
+        {
+            unsigned int n = a.regionCount();
+            Shape2 m = get<TAG>(a, 0).shape();
+            Shape3 s(n, m[0], m[1]);
+            NumpyArray<3, T> res(s);
+            
+            for(unsigned int k=0; k<n; ++k)
+                for(int i=0; i<m[0]; ++i)
+                    for(int j=0; j<m[1]; ++j)
+                        res(k, p(i), p(j)) = get<TAG>(a, k)(i, j);
+            return python::object(res);
+        }
+    };
+    
+    template <class TAG, class T, class Accu>
+    struct ToPythonArray<TAG, Error__Attempt_to_access_inactive_statistic<T>, Accu>
+    {
+        template <class Permutation>
+        static python::object exec(Accu & a, Permutation const & p)
+        {
+            vigra_precondition(false, "PythonAccumulator::get(): Attempt to access inactive statistic.");
+            return python::object();
+        }
+    };
+    
+    template <class TAG, class T1, class T2, class Accu>
+    struct ToPythonArray<TAG, std::pair<T1, T2>, Accu>
+    {
+        template <class Permutation>
+        static python::object exec(Accu & a, Permutation const & p)
+        {
+            vigra_precondition(false, "PythonAccumulator::get(): Export for this statistic is not implemented, sorry.");
+            return python::object();
+        }
+    };
+    
+    struct CoordPermutation
+    {
+        ArrayVector<npy_intp> permutation_;
+        
+        CoordPermutation()
+        {}
+        
+        template <class Permute>
+        CoordPermutation(Permute const & p)
+        : permutation_(p.begin(), p.end())
+        {}
+        
+        template <class T>
+        T operator()(T const & t) const
+        {
+            return permutation_[t];
+        }
+    };
+    
+    struct IdentityPermutation
+    {
+        template <class T>
+        T operator()(T const & t) const
+        {
+            return t;
+        }
+    };
+    
+    CoordPermutation coord_permutation_;
+    
+    GetArrayTag_Visitor()
+    {}
+    
+    template <class Permute>
+    GetArrayTag_Visitor(Permute const & p)
+    : coord_permutation_(p)
+    {}
+    
+    template <class TAG, class Accu>
+    void exec(Accu & a) const
+    {
+        exec(a, (TAG *)0);
+    }
+    
+    template <class Accu, class TAG>
+    void exec(Accu & a, TAG *) const
+    {
+        if(IsCoordinateFeature<TAG>::value && !IsPrincipalFeature<TAG>::value)
+            this->result = ToPythonArray<TAG, typename LookupTag<TAG, Accu>::value_type, Accu>::exec(a, coord_permutation_);
+        else
+            this->result = ToPythonArray<TAG, typename LookupTag<TAG, Accu>::value_type, Accu>::exec(a, IdentityPermutation());
+    }
+    
+    template <class Accu, class TAG>
+    void exec(Accu & a, Global<TAG> *) const
+    {
+        vigra_precondition(IsPrincipalFeature<TAG>::value || !IsCoordinateFeature<TAG>::value,
+            "PythonAccumulator::get(): Export of global coordinate features unsupported, sorry.");
+        this->result = to_python(get<Global<TAG> >(a));
+    }
+};
+
+typedef std::map<std::string, std::string> AliasMap;
+
+AliasMap defineAliasMap();
+
+AliasMap * createTagToAlias(ArrayVector<std::string> const & names);
+
+AliasMap * createAliasToTag(AliasMap const & tagToAlias);
+
+ArrayVector<std::string> * createSortedNames(AliasMap const & tagToAlias);
+
+struct PythonFeatureAccumulator
+{
+    virtual void activate(std::string const & tag) { throw std::runtime_error("abstract function called."); }   
+    virtual bool isActive(std::string const & tag) const { throw std::runtime_error("abstract function called."); return false; }
+    virtual python::list activeNames() const { throw std::runtime_error("abstract function called."); return python::list(); }
+    virtual python::list names() const { throw std::runtime_error("abstract function called."); return python::list(); }
+    virtual python::object get(std::string const & tag) { throw std::runtime_error("abstract function called."); return python::object(); }
+    virtual void merge(PythonFeatureAccumulator const & o) { throw std::runtime_error("abstract function called."); }
+    virtual PythonFeatureAccumulator * create() const { throw std::runtime_error("abstract function called."); return 0; }
+    
+    static void definePythonClass()
+    {
+        python::class_<PythonFeatureAccumulator>(
+               "FeatureAccumulator", 
+               "An instance of this accumulator class is returned by"
+               " :func:`extractFeatures`. "
+               "The object contains the computed features "
+               "(i.e. the selected features and their dependencies).\n"
+               ,python::no_init)
+            .def("__getitem__", &PythonFeatureAccumulator::get, 
+               "accumulator[feature] returns the value of the 'feature'. The return type is a"
+               " float or a numpy array of appropriate shape.\n",
+               python::arg("feature") )
+            .def("isActive", &PythonFeatureAccumulator::isActive,
+               "Returns True if 'feature' has been computed and False otherwise.\n",
+               python::arg("feature"))
+            .def("activeFeatures", &PythonFeatureAccumulator::activeNames,
+               "Returns a list with the names of all computed features.\n")
+            .def("keys", &PythonFeatureAccumulator::activeNames,
+               "Returns a list with the names of all computed features.\n")
+            .def("supportedFeatures", &PythonFeatureAccumulator::names,
+               "Returns a list of all supported features for the given input data array.\n")
+            .def("merge", &PythonFeatureAccumulator::merge,
+               "Merge features with the features from accumulator 'other'. Raises a "
+               "TypeError when 'other' is incompatible with 'self'.\n",
+               python::arg("other"))
+            .def("createAccumulator", &PythonFeatureAccumulator::create,
+               "Create an empty accumulator with the same active features as 'self'. "
+               "This is useful for merging.\n", 
+               python::return_value_policy<python::manage_new_object>())
+            ;
+    }
+};
+
+struct PythonRegionFeatureAccumulator
+: public PythonFeatureAccumulator
+{
+    virtual MultiArrayIndex maxRegionLabel() { throw std::runtime_error("abstract function called."); }
+    virtual void mergeAll(PythonRegionFeatureAccumulator const & o) { throw std::runtime_error("abstract function called."); }
+    virtual void remappingMerge(PythonFeatureAccumulator const & o, NumpyArray<1, npy_uint32> labelMapping) { throw std::runtime_error("abstract function called."); }
+    virtual void mergeRegions(npy_uint32 i, npy_uint32 j) { throw std::runtime_error("abstract function called."); }
+    virtual PythonRegionFeatureAccumulator * create() const { throw std::runtime_error("abstract function called."); return 0; }
+    
+    static void definePythonClass()
+    {
+        python::class_<PythonRegionFeatureAccumulator>(
+                "RegionFeatureAccumulator", 
+                "An instance of this accumulator class is returned by "
+                ":func:`extractRegionFeatures()` and contains the computed"
+                " global and per-region features. \n",
+                python::no_init)
+            .def("__getitem__", &PythonRegionFeatureAccumulator::get,
+               "accumulator[feature] returns the value of the 'feature'. "
+               "The return type is a numpy array of appropriate shape. "
+               "The first index of the returned arrays is the region label.\n",
+               python::arg("feature"))
+            .def("maxRegionLabel", &PythonRegionFeatureAccumulator::maxRegionLabel,
+                "Return the highest region label in this accumulator.\n")
+            .def("isActive", &PythonRegionFeatureAccumulator::isActive, 
+               "Returns True if 'feature' has been computed"
+               " and False otherwise.\n",
+               python::arg("feature"))
+            .def("activeFeatures", &PythonRegionFeatureAccumulator::activeNames,
+               "Returns a list with the names of all selected features.\n")
+            .def("keys", &PythonRegionFeatureAccumulator::activeNames,
+               "Returns a list with the names of all selected features.\n")
+            .def("supportedFeatures", &PythonRegionFeatureAccumulator::names,
+               "Returns a list with the names of all supported features for the given input arrays.\n")
+            .def("merge", &PythonRegionFeatureAccumulator::mergeAll,
+               "Merge features with the features from accumulator 'other'. "
+               "'self' and 'other' must have the same `maxRegionLabel`(), or "
+               "'self' must be an empty accumulator (as returned by `create`).\n",
+               python::arg("other"))
+            .def("merge", &PythonRegionFeatureAccumulator::remappingMerge,
+               "Merge features with the features from accumulator 'other'. "
+               "The 'labelMap' determines the correspondence of regions between "
+               "'self' and 'other' (i.e. region k of accumulator 'other' is "
+               "merged into region labelMap[k] of 'self').\n",
+               (python::arg("other"), python::arg("labelMap")))
+            .def("merge", &PythonRegionFeatureAccumulator::mergeRegions,
+               "Merge features from region 'j' into region 'i' of this accumulator.\n",
+               (python::arg("i"), python::arg("j")))
+            .def("createAccumulator", &PythonRegionFeatureAccumulator::create,
+               "Create an empty accumulator with the same active features as 'self'. "
+               "This is useful for merging.\n", 
+               python::return_value_policy<python::manage_new_object>())
+            ;
+    }  
+};
+
+template <class BaseType, class PythonBaseType, class GetVisitor>
+struct PythonAccumulator
+: public BaseType, public PythonBaseType
+{
+    typedef typename BaseType::AccumulatorTags AccumulatorTags;
+    typedef PythonBaseType PythonBase;
+    
+    ArrayVector<npy_intp> permutation_;
+    
+    PythonAccumulator()
+    {}
+    
+    template <class Permutation>
+    PythonAccumulator(Permutation const & p)
+    : permutation_(p.begin(), p.end())
+    {}
+    
+    void activate(std::string const & tag)
+    {
+        vigra_precondition(this->activateImpl(resolveAlias(tag)), 
+                            "FeatureAccumulator::activate(): Tag '" + tag + "' not found.");
+    }
+    
+    bool isActive(std::string const & tag) const
+    {
+        acc_detail::TagIsActive_Visitor v;
+        vigra_precondition(this->isActiveImpl(resolveAlias(tag), v), 
+                           "FeatureAccumulator::isActive(): Tag '" + tag + "' not found.");
+        return v.result;
+    }
+        
+    python::list activeNames() const
+    {
+        python::list result;
+        for(unsigned int k=0; k<nameList().size(); ++k)
+            if(isActive(nameList()[k]))
+                result.append(python::object(nameList()[k]));
+        return result;
+    }
+    
+    python::list names() const
+    {
+        python::list result;
+        for(unsigned int k=0; k<nameList().size(); ++k)
+            result.append(python::object(nameList()[k]));
+        return result;
+    }
+    
+    python::object get(std::string const & tag)
+    {
+        GetVisitor v(permutation_);
+        
+        vigra_precondition(isActive(tag), "FeatureAccumulator::get(): Tag '" + tag + "' is not active.");
+        acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec((BaseType &)*this, resolveAlias(tag), v);
+        return v.result;
+    }
+    
+    void merge(PythonFeatureAccumulator const & o)
+    {
+        PythonAccumulator const * p = dynamic_cast<PythonAccumulator const *>(&o);
+        if(p == 0)
+        {
+            PyErr_SetString(PyExc_TypeError, "FeatureAccumulator::merge(): accumulators are incompatible.");
+            python::throw_error_already_set();
+        }
+        BaseType::merge(*p);
+    }
+    
+    void mergeAll(PythonRegionFeatureAccumulator const & o)
+    {
+        merge(o);
+    }
+    
+    void remappingMerge(PythonFeatureAccumulator const & o, NumpyArray<1, npy_uint32> labelMapping)
+    {
+        PythonAccumulator const * p = dynamic_cast<PythonAccumulator const *>(&o);
+        if(p == 0)
+        {
+            PyErr_SetString(PyExc_TypeError, "FeatureAccumulator::merge(): accumulators are incompatible.");
+            python::throw_error_already_set();
+        }
+        BaseType::merge(*p, labelMapping);
+    }
+    
+    void mergeRegions(npy_uint32 i, npy_uint32 j)
+    {
+        BaseType::merge(i, j);
+    }
+    
+    PythonAccumulator * create() const
+    {
+        VIGRA_UNIQUE_PTR<PythonAccumulator> a(new PythonAccumulator(permutation_));
+        pythonActivateTags(*a, activeNames());
+        return a.release();
+    }
+    
+    MultiArrayIndex maxRegionLabel() 
+    {
+        return BaseType::maxRegionLabel();
+    }
+
+    private:
+    static std::string createAlias(std::string const & n)
+    {
+        AliasMap::const_iterator k = tagToAlias().find(n);
+        if(k == tagToAlias().end())
+            return n;
+        else
+            return k->second;
+    }
+    
+    static std::string resolveAlias(std::string const & n)
+    {
+        AliasMap::const_iterator k = aliasToTag().find(normalizeString(n));
+        if(k == aliasToTag().end())
+            return n;
+        else
+            return k->second;
+    }
+    
+    static AliasMap const & tagToAlias()
+    {
+        static AliasMap * a = VIGRA_SAFE_STATIC(a, createTagToAlias(PythonAccumulator::tagNames()));
+        return *a;   
+    }
+    
+    static AliasMap const & aliasToTag()
+    {
+        static AliasMap * a = VIGRA_SAFE_STATIC(a, createAliasToTag(tagToAlias()));
+        return *a;   
+    }
+    
+    static ArrayVector<std::string> const & nameList()
+    {
+        static ArrayVector<std::string> * n = VIGRA_SAFE_STATIC(n, createSortedNames(tagToAlias()));
+        return *n;
+    }
+};
+
+template <class Accu>
+bool pythonActivateTags(Accu & a, python::object tags)
+{
+    if(tags == python::object() || python::len(tags) == 0)
+        return false;
+
+    if(PyString_Check(tags.ptr()))
+    {
+        std::string tag = python::extract<std::string>(tags)();
+        if(normalizeString(tag) == "all")
+            a.activateAll();
+        else
+            a.activate(tag);
+    }
+    else
+    {
+        for(int k=0; k<python::len(tags); ++k)
+        {
+            a.activate(python::extract<std::string>(tags[k])());
+        }
+    }
+    return true;
+}
+
+template <class Accu>
+void pythonHistogramOptions(Accu & a, python::object minmax, int binCount)
+{
+    HistogramOptions options;
+    options.setBinCount(binCount);
+    
+    if(PyString_Check(minmax.ptr()))
+    {
+        std::string spec = normalizeString(python::extract<std::string>(minmax)());
+        if(spec == "globalminmax")
+            options.globalAutoInit();
+        else if(spec == "regionminmax")
+            options.regionAutoInit();
+        else
+            vigra_precondition(false, 
+                "extractFeatures(): invalid histogramRange.");
+    }
+    else if(python::len(minmax) == 2)
+    {
+        options.setMinMax(python::extract<double>(minmax[0])(), python::extract<double>(minmax[1])());
+    }
+    else
+        vigra_precondition(false, "extractFeatures(): invalid histogramRange.");
+    a.setHistogramOptions(options);
+}
+
+template <class Accumulator, unsigned int ndim, class T>
+typename Accumulator::PythonBase *
+pythonInspect(NumpyArray<ndim, T> in, python::object tags)
+{
+    VIGRA_UNIQUE_PTR<Accumulator> res(new Accumulator);
+    if(pythonActivateTags(*res, tags))
+    {
+        PyAllowThreads _pythread;
+        
+        extractFeatures(in.begin(), in.end(), *res);
+    }
+    
+    return res.release();
+}
+
+template <class Accumulator, unsigned int ndim, class T>
+typename Accumulator::PythonBase *
+pythonInspectWithHistogram(NumpyArray<ndim, Singleband<T> > in, python::object tags,
+                           python::object histogramRange, int binCount)
+{
+    VIGRA_UNIQUE_PTR<Accumulator> res(new Accumulator);
+    if(pythonActivateTags(*res, tags))
+    {
+        pythonHistogramOptions(*res, histogramRange, binCount);
+        
+        PyAllowThreads _pythread;
+        
+        extractFeatures(in.begin(), in.end(), *res);
+    }
+    
+    return res.release();
+}
+
+template <class Accumulator, unsigned int ndim, class T>
+typename Accumulator::PythonBase *
+pythonInspectMultiband(NumpyArray<ndim, Multiband<T> > in, python::object tags)
+{
+    typedef typename CoupledIteratorType<ndim, Multiband<T> >::type Iterator;
+    
+    VIGRA_UNIQUE_PTR<Accumulator> res(new Accumulator);
+    if(pythonActivateTags(*res, tags))
+    {
+        PyAllowThreads _pythread;
+        
+        Iterator i   = createCoupledIterator(MultiArrayView<ndim, Multiband<T>, StridedArrayTag>(in)),
+                 end = i.getEndIterator();
+        extractFeatures(i, end, *res);
+    }
+    
+    return res.release();
+}
+
+template <class Accumulator, unsigned int ndim, class T>
+typename Accumulator::PythonBase *
+pythonRegionInspect(NumpyArray<ndim, T> in, 
+                    NumpyArray<ndim, Singleband<npy_uint32> > labels,
+                    python::object tags,
+                    python::object ignore_label)
+{
+    typedef typename CoupledIteratorType<ndim, T, npy_uint32>::type Iterator;
+    
+    TinyVector<npy_intp, ndim> permutation = in.template permuteLikewise<ndim>();
+    
+    VIGRA_UNIQUE_PTR<Accumulator> res(new Accumulator(permutation));
+    if(pythonActivateTags(*res, tags))
+    {
+        if(ignore_label != python::object())
+            res->ignoreLabel(python::extract<MultiArrayIndex>(ignore_label)());
+            
+        PyAllowThreads _pythread;
+        
+        Iterator i     = createCoupledIterator(in, labels),
+                 end   = i.getEndIterator();
+        extractFeatures(i, end, *res);
+    }
+    
+    return res.release();
+}
+
+template <class Accumulator, unsigned int ndim, class T>
+typename Accumulator::PythonBase *
+pythonRegionInspectWithHistogram(NumpyArray<ndim, Singleband<T> > in, 
+                    NumpyArray<ndim, Singleband<npy_uint32> > labels,
+                    python::object tags, python::object histogramRange, int binCount,
+                    python::object ignore_label)
+{
+    typedef typename CoupledIteratorType<ndim, T, npy_uint32>::type Iterator;
+    
+    TinyVector<npy_intp, ndim> permutation = in.template permuteLikewise<ndim>();
+    
+    VIGRA_UNIQUE_PTR<Accumulator> res(new Accumulator(permutation));
+    if(pythonActivateTags(*res, tags))
+    {
+        pythonHistogramOptions(*res, histogramRange, binCount);
+        if(ignore_label != python::object())
+            res->ignoreLabel(python::extract<MultiArrayIndex>(ignore_label)());
+                    
+        PyAllowThreads _pythread;
+        
+        Iterator i     = createCoupledIterator(in, labels),
+                 end   = i.getEndIterator();
+        extractFeatures(i, end, *res);
+    }
+    
+    return res.release();
+}
+
+template <class Accumulator, unsigned int ndim, class T>
+typename Accumulator::PythonBase *
+pythonRegionInspectMultiband(NumpyArray<ndim, Multiband<T> > in, 
+                             NumpyArray<ndim-1, Singleband<npy_uint32> > labels,
+                             python::object tags,
+                             python::object ignore_label)
+{
+    typedef typename CoupledIteratorType<ndim, Multiband<T>, npy_uint32>::type Iterator;
+    
+    TinyVector<npy_intp, ndim-1> permutation = in.template permuteLikewise<ndim-1>();
+    
+    VIGRA_UNIQUE_PTR<Accumulator> res(new Accumulator(permutation));
+    if(pythonActivateTags(*res, tags))
+    {
+        if(ignore_label != python::object())
+            res->ignoreLabel(python::extract<MultiArrayIndex>(ignore_label)());
+            
+        PyAllowThreads _pythread;
+        
+        Iterator i     = createCoupledIterator(MultiArrayView<ndim, Multiband<T>, StridedArrayTag>(in), labels),
+                 end   = i.getEndIterator();
+        extractFeatures(i, end, *res);
+    }
+    
+    return res.release();
+}
+
+} // namespace acc
+
+template <class T, class Accumulators>
+void definePythonAccumulatorSingleband()
+{
+    using namespace python;
+
+    docstring_options doc_options(true, true, false);
+
+    typedef acc::PythonAccumulator<acc::DynamicAccumulatorChain<T, Accumulators>, 
+                                    acc::PythonFeatureAccumulator, acc::GetTag_Visitor> Accu;
+    
+    def("extractFeatures", &acc::pythonInspectWithHistogram<Accu, 2, T>,
+          (arg("image"), arg("features") = "all", 
+           arg("histogramRange") = "globalminmax", arg("binCount") = 64),
+          "\nThis overload of extractFeatures() computes global statistics for a\n"
+          "2D scalar input array, e.g. :class:`vigra.ScalarImage`\n\n"
+          "Features 'Histogram' and 'Quantiles' are supported for this input.\nOptions are:\n\n"
+          "    - histogramRange: lower and upper bound of the histogram\n\n"
+          "        + 'globalminmax':  compute and use global minimum/maximum (default)\n"
+          "        + [lower, upper]:  provide explicit bounds (float numbers),\n"
+          "                           useful to ensure that merge will be allowed.\n\n"
+          "    - binCount: number of bins (default: 64).\n\n"
+          "Histogram options are ignored when the histogram feature is not selected.\n"
+          "Quantiles (0%, 10%, 25%, 50%, 75%, 90%, 100%) are computed from\n"
+          "the specified histogram.\n\n",
+          return_value_policy<manage_new_object>());
+    
+    def("extractFeatures", &acc::pythonInspectWithHistogram<Accu, 3, T>,
+          (arg("volume"), arg("features") = "all", 
+           arg("histogramRange") = "globalminmax", arg("binCount") = 64),
+          "Likewise for a scalar 3D input array, e.g. :class:`vigra.ScalarVolume`.\n\n",
+          return_value_policy<manage_new_object>());
+}
+
+template <class T, class Accumulators>
+void definePythonAccumulator()
+{
+    using namespace python;
+
+    docstring_options doc_options(true, true, false);
+
+    typedef acc::PythonAccumulator<acc::DynamicAccumulatorChain<T, Accumulators>, 
+                                    acc::PythonFeatureAccumulator, acc::GetTag_Visitor> Accu;
+    
+    def("extractFeatures", &acc::pythonInspect<Accu, 2, T>,
+          (arg("image"), arg("features") = "all"),
+          "Likewise for 2D arrays with 3 channels.\n"
+          "Histograms and quantiles are not supported for this input.\n\n",
+          return_value_policy<manage_new_object>());
+    
+    def("extractFeatures", &acc::pythonInspect<Accu, 3, T>,
+          (arg("volume"), arg("features") = "all"),
+          "Likewise for 3D arrays with 3 channels.\n"
+          "Histograms and quantiles are not supported for this input.\n\n",
+          return_value_policy<manage_new_object>());
+}
+
+template <unsigned int N, class T, class Accumulators>
+void definePythonAccumulatorMultiband()
+{
+    using namespace python;
+
+    docstring_options doc_options(true, true, false);
+
+    typedef typename CoupledIteratorType<N, Multiband<T> >::type::value_type ResultType;    
+    typedef acc::PythonAccumulator<acc::DynamicAccumulatorChain<ResultType, Accumulators>, 
+                                    acc::PythonFeatureAccumulator, acc::GetTag_Visitor> Accu;
+    
+    std::string argname = N == 3 
+                             ? "image"
+                             : "volume";
+    
+    std::string doc_string;
+    if (N==3) {
+      doc_string +=
+        "Extract global features (e.g. Mean, Variance, Minimum, etc.)\n"
+        "from the input array ('image' or 'volume'). An accumulator object\n"
+        "of type :class:`FeatureAccumulator` is returned that holds the computed\nfeatures.\n\n" 
+        "The overloaded function extractFeatures() supports 2D or 3D\n"
+        "arrays with arbitrary many channels. The element type of the\n"
+        "input array must be **dtype=numpy.float32**. The set of available features\n"
+        "depends on the input array. The 'Histogram' feature, for example,\n"
+        "is only supported for singleband arrays. Call :func:`supportedFeatures`\n"
+        "with the same input array to get a list of all available features\n"
+        "for this input.\n\n"
+        "The argument 'features' can take the following values:\n\n"
+        "   - 'all': compute all supported features (default)\n\n"
+        "   - name:  compute a single feature (and its dependencies)\n\n"
+        "   - [name1, name2,...]:  compute the given features plus dependencies\n\n"
+        "   - None or '':  return an empty accumulator, whose method \n"
+        "                  :meth:`~.FeatureAccumulator.supportedFeatures`\n"
+        "                  tells you the list of supported features for the\n"
+        "                  given input array.\n\n"
+        "To compute per-region features, use :func:`extractRegionFeatures`.\n\n"
+        "This overload is called for 2D input arrays two or more than\n"
+        "four channels. Histograms and quantiles are not supported for\n"
+        "this input.\n\n"
+        "For further details about the meaning of the features, see\n"
+        "`Feature Accumulators <../vigra/group__FeatureAccumulators.html>`_ in the vigra C++ documentation.\n\n";
+    } else {
+      doc_string +=
+        "Overload for 3D arrays with arbitrary many channels.\n"
+        "Histograms and quantiles are not supported for this input.\n\n";
+    }
+    def("extractFeatures", &acc::pythonInspectMultiband<Accu, N, T>,
+          (arg(argname.c_str()), arg("features") = "all"),
+          doc_string.c_str(),
+          return_value_policy<manage_new_object>());
+}
+
+template <unsigned int N, class T, class Accumulators>
+void definePythonAccumulatorArraySingleband()
+{
+    using namespace python;
+
+    docstring_options doc_options(true, true, false);
+
+    typedef typename CoupledIteratorType<N, T, npy_uint32>::type Iterator;
+    typedef typename Iterator::value_type Handle;
+    
+    typedef acc::PythonAccumulator<acc::DynamicAccumulatorChainArray<Handle, Accumulators>, 
+                                    acc::PythonRegionFeatureAccumulator, acc::GetArrayTag_Visitor> Accu;
+    
+    std::string argname = N == 2 
+                             ? "image"
+                             : "volume";
+    
+    std::string doc_string;
+    if (N==2) {
+      doc_string +=
+         "\nThis overload of extractRegionFeatures() computes region statistics\n"
+         "for a scalar 2D input array, e.g. :class:`vigra.ScalarImage`.\n\n"
+         "Features 'Histogram' and 'Quantiles' are supported for this input. Options are:\n\n"
+         "    - histogramRange: lower and upper bound of the histogram\n\n"
+         "        + 'globalminmax':  compute and use global minimum/maximum (default)\n"
+         "        + 'regionminmax':   use minimum/maximum within each region\n"
+         "        + [lower, upper]:  provide explicit bounds (float numbers),\n"
+         "                           useful to ensure that merge will be allowed.\n\n"
+         "    - binCount: number of bins (default: 64).\n\n"
+         "Histogram options are ignored when Histogram feature is not selected.\n"
+         "Quantiles (0%, 10%, 25%, 50%, 75%, 90%, 100%) are computed from\n"
+         "the specified histogram.\n\n";
+    } else {
+      doc_string += 
+         "Likewise for 3D scalar arrays, e.g. :class:`vigra.ScalarVolume`.\n\n";
+    }
+    
+    def("extractRegionFeatures", &acc::pythonRegionInspectWithHistogram<Accu, N, T>,
+          (arg(argname.c_str()), arg("labels"), arg("features") = "all", 
+           arg("histogramRange") = "globalminmax", arg("binCount") = 64, arg("ignoreLabel")=python::object()),
+          doc_string.c_str(),
+          return_value_policy<manage_new_object>());
+}
+
+template <unsigned int N, class T, class Accumulators>
+void definePythonAccumulatorArray()
+{
+    using namespace python;
+
+    docstring_options doc_options(true, true, false);
+
+    typedef typename CoupledIteratorType<N, T, npy_uint32>::type Iterator;
+    typedef typename Iterator::value_type Handle;
+    
+    typedef acc::PythonAccumulator<acc::DynamicAccumulatorChainArray<Handle, Accumulators>, 
+                                    acc::PythonRegionFeatureAccumulator, acc::GetArrayTag_Visitor> Accu;
+    
+    std::string argname = N == 2 
+                             ? "image"
+                             : "volume";
+    
+    std::string doc_string;
+    if (N==2) {
+      doc_string +=
+         "This overload of extractRegionFeatures() is called for\n"
+         "2D input arrays with 3 channels.\n\n";
+    } else {
+      doc_string +=
+         "This overload of extractRegionFeatures() is called for\n"
+         "3D input arrays with 3 channels.\n\n";
+    }
+    
+    def("extractRegionFeatures", &acc::pythonRegionInspect<Accu, N, T>,
+          (arg(argname.c_str()), arg("labels"), arg("features") = "all", arg("ignoreLabel")=python::object()),
+          doc_string.c_str(),
+          return_value_policy<manage_new_object>());
+}
+
+template <unsigned int N, class T, class Accumulators>
+void definePythonAccumulatorArrayMultiband()
+{
+    using namespace python;
+
+    docstring_options doc_options(true, true, false);
+
+    typedef typename CoupledIteratorType<N, Multiband<T>, npy_uint32>::type::value_type Handle;
+    typedef acc::PythonAccumulator<acc::DynamicAccumulatorChainArray<Handle, Accumulators>, 
+                                    acc::PythonRegionFeatureAccumulator, acc::GetArrayTag_Visitor> Accu;
+        
+    std::string argname = N == 3 
+                             ? "image"
+                             : "volume";
+    
+    std::string doc_string;
+    if (N==3) {
+      doc_string +=
+        "\nExtract region features from an input array with **dtype=numpy.float32**\n"
+        "and return a :class:`RegionFeatureAccumulator` object.\n\n"
+        "Membership of the array elements (pixels) to regions is specified\n"
+        "by a 'labels' array with element type **dtype=uint32**.\n\n"
+        "The set of available features depends on the input array.\n"
+        "Call :func:`supportedRegionFeatures` with the same input and label\n"
+        "arrays to get a list of all available features for these inputs.\n\n"
+        "The argument 'features' can take the following values:\n\n"
+        "   - 'all': compute all supported features (default)\n\n"
+        "   - name:  compute a single feature (and its dependencies)\n\n"
+        "   - [name1, name2,...]:  compute the given features plus dependencies\n\n"
+        "   - None or '':  return an empty accumulator, whose method \n"
+        "                  :meth:`~.RegionFeatureAccumulator.supportedFeatures`\n"
+        "                  tells you the list of supported features for the\n"
+        "                  given input array.\n\n"
+        "When the feature name starts with 'Global', the feature is computed\n"
+        "globally, i.e. without considering region membership.\n\n"
+        "The argument 'ignoreLabel' is useful when the label array contains\n"
+        "a background region (usually label 0) that should be ignored during\n"
+        "feature computation. If 'ignoreLabel' is None (the default), all\n"
+        "region labels are used.\n\n"
+        "This overload is called for 2D input arrays with two or more than\n"
+        "four channels. Histograms and quantiles are not supported for this\n"
+        "input.\n\n"
+        "For further details about the meaning of the features, see\n"
+        "`Feature Accumulators <../vigra/group__FeatureAccumulators.html>`_ in the vigra C++ documentation.\n\n";
+
+    } else {
+      doc_string +=
+         "Likewise for a 3D input array  with two or more than four channels.\n"
+         "Histograms and quantiles are not supported for this input.\n\n";
+    }
+    
+    def("extractRegionFeatures", &acc::pythonRegionInspectMultiband<Accu, N, T>,
+          (arg(argname.c_str()), arg("labels"), arg("features") = "all", arg("ignoreLabel")=python::object()),
+          doc_string.c_str(),
+          return_value_policy<manage_new_object>());
+}
+
+} // namespace vigra
+
+#endif // VIGRA_PYTHONACCUMULATOR_HXX
diff --git a/vigranumpy/src/core/random_forest.cxx b/vigranumpy/src/core/random_forest.cxx
new file mode 100644
index 0000000..085d75a
--- /dev/null
+++ b/vigranumpy/src/core/random_forest.cxx
@@ -0,0 +1,415 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyrigfht notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpylearning_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/random_forest.hxx>
+#ifdef HasHDF5
+# include <vigra/random_forest_hdf5_impex.hxx>
+#endif
+#include <vigra/timing.hxx>
+#include <vigra/random.hxx>
+#include <set>
+#include <cmath>
+#include <memory>
+#include <boost/python.hpp>
+
+namespace python = boost::python;
+namespace vigra
+{
+
+template<class FeatureType>
+OnlinePredictionSet<FeatureType>* 
+pythonConstructOnlinePredictioSet(NumpyArray<2,FeatureType> features, int num_sets)
+{
+    return new OnlinePredictionSet<FeatureType>(features, num_sets);
+}
+
+template<class LabelType, class FeatureType>
+RandomForest<LabelType>*
+pythonConstructRandomForest(int treeCount,
+                            int mtry,
+                            int min_split_node_size,
+                            int training_set_size,
+                            float training_set_proportions,
+                            bool sample_with_replacement,
+                            bool sample_classes_individually,
+                            bool prepare_online,
+                            ArrayVector<MultiArrayIndex> const & labels = ArrayVector<MultiArrayIndex>())
+
+
+{
+    RandomForestOptions options;
+    options .sample_with_replacement(sample_with_replacement)
+            .tree_count(treeCount)
+            .prepare_online_learning(prepare_online)
+            .min_split_node_size(min_split_node_size);
+
+
+    if(mtry  > 0)
+        options.features_per_node(mtry);
+
+    if(training_set_size != 0)
+        options.samples_per_tree(training_set_size);
+    else
+        options.samples_per_tree(training_set_proportions);
+
+    if(sample_classes_individually)
+        options.use_stratification(RF_EQUAL);
+
+    ProblemSpec<LabelType> ext_param;
+    
+    if(labels.size() > 0)
+    {
+        ext_param.classes_(labels.begin(), labels.end());
+    }
+    
+    RandomForest<LabelType>* rf = new RandomForest<LabelType>(options, ext_param);
+
+    return rf;
+}
+
+#ifdef HasHDF5
+template<class LabelType>
+RandomForest<LabelType> * 
+pythonImportRandomForestFromHDF5(std::string filename, 
+                                 std::string pathname = "")
+{ 
+    VIGRA_UNIQUE_PTR<RandomForest<LabelType> > rf(new RandomForest<LabelType>);
+    
+    vigra_precondition(rf_import_HDF5(*rf, filename, pathname),
+           "RandomForest(): Unable to load from HDF5 file.");
+           
+    return rf.release();
+}                   
+#endif // HasHDF5
+
+template<class LabelType, class FeatureType>
+python::tuple
+pythonLearnRandomForestWithFeatureSelection(RandomForest<LabelType> & rf, 
+                                            NumpyArray<2,FeatureType> trainData, 
+                                            NumpyArray<2,LabelType> trainLabels,
+                                            UInt32 randomSeed=0)
+{
+    vigra_precondition(!trainData.axistags() && !trainLabels.axistags(),
+                       "RandomForest.learnRFWithFeatureSelection(): training data and labels must not\n"
+                       "have axistags (use 'array.view(numpy.ndarray)' to remove them).");
+    
+    using namespace rf;
+    visitors::VariableImportanceVisitor var_imp;
+    visitors::OOB_Error                 oob_v;
+    
+    {
+        PyAllowThreads _pythread;
+        RandomNumberGenerator<> rnd(randomSeed, randomSeed == 0);
+        rf.learn(trainData, trainLabels,
+                visitors::create_visitor(var_imp, oob_v),
+                vigra::rf_default(), vigra::rf_default(),
+                rnd);
+    }
+    
+    double oob = oob_v.oob_breiman;
+    // std::cout << "out of bag: " << oob << std::endl;
+    NumpyArray<2,double> res(var_imp.variable_importance_);
+
+    return python::make_tuple(oob, res);
+}
+
+template<class LabelType, class FeatureType>
+double
+pythonLearnRandomForest(RandomForest<LabelType> & rf, 
+                        NumpyArray<2,FeatureType> trainData, 
+                        NumpyArray<2,LabelType> trainLabels,
+                        UInt32 randomSeed=0)
+{
+    vigra_precondition(!trainData.axistags() && !trainLabels.axistags(),
+                       "RandomForest.learnRF(): training data and labels must not\n"
+                       "have axistags (use 'array.view(numpy.ndarray)' to remove them).");
+    
+    using namespace rf;
+    visitors::OOB_Error oob_v;
+
+    {
+        PyAllowThreads _pythread;
+        RandomNumberGenerator<> rnd(randomSeed, randomSeed == 0);
+        rf.learn(trainData, trainLabels, visitors::create_visitor(oob_v),
+                vigra::rf_default(), vigra::rf_default(),
+                rnd);
+    }
+    double oob = oob_v.oob_breiman;
+
+    //std::cout << "out of bag: " << oob << std::endl;
+    return oob;
+}
+
+template<class LabelType,class FeatureType>
+void 
+pythonRFOnlineLearn(RandomForest<LabelType> & rf,
+                    NumpyArray<2,FeatureType> trainData,
+                    NumpyArray<2,LabelType> trainLabels,
+                    int startIndex,
+                    bool adjust_thresholds=false,
+                    UInt32 randomSeed=0)
+{
+    vigra_precondition(!trainData.axistags() && !trainLabels.axistags(),
+                       "RandomForest.onlineLearn(): training data and labels must not\n"
+                       "have axistags (use 'array.view(numpy.ndarray)' to remove them).");
+    
+    PyAllowThreads _pythread;
+    RandomNumberGenerator<> rnd(randomSeed, randomSeed == 0);
+    rf.onlineLearn(trainData, trainLabels, startIndex,
+            vigra::rf_default(), vigra::rf_default(), vigra::rf_default(),
+            rnd, adjust_thresholds);
+}
+
+template<class LabelType,class FeatureType>
+void 
+pythonRFReLearnTree(RandomForest<LabelType> & rf,
+                    NumpyArray<2,FeatureType> trainData,
+                    NumpyArray<2,LabelType> trainLabels,
+                    int treeId, UInt32 randomSeed=0)
+{
+    vigra_precondition(!trainData.axistags() && !trainLabels.axistags(),
+                       "RandomForest.reLearnTree(): training data and labels must not\n"
+                       "have axistags (use 'array.view(numpy.ndarray)' to remove them).");
+    
+    PyAllowThreads _pythread;
+    RandomNumberGenerator<> rnd(randomSeed, randomSeed == 0);
+    rf.reLearnTree(trainData, trainLabels, treeId,
+            vigra::rf_default(), vigra::rf_default(), vigra::rf_default(),
+            rnd);
+}
+
+template<class LabelType,class FeatureType>
+NumpyAnyArray 
+pythonRFPredictLabels(RandomForest<LabelType> const & rf,
+                      NumpyArray<2,FeatureType> testData,
+                      python::object pyNaNLabel,
+                      NumpyArray<2,LabelType> res)
+{
+    vigra_precondition(!testData.axistags() && !res.axistags(),
+                       "RandomForest.predictLabels(): test data and output array must not have axistags\n"
+                       "(use 'array.view(numpy.ndarray)' to remove them).");
+    
+    res.reshapeIfEmpty(MultiArrayShape<2>::type(testData.shape(0), 1),
+                       "RandomForest.predictLabels(): Output array has wrong dimensions.");
+    
+    python::extract<LabelType> nanLabel(pyNaNLabel);
+    
+    if(nanLabel.check())
+    {
+        LabelType nan_label(nanLabel());
+        PyAllowThreads _pythread;
+        rf.predictLabels(testData, res, nan_label);
+    }
+    else
+    {
+        PyAllowThreads _pythread;
+        rf.predictLabels(testData, res);
+    }
+    return res;
+}
+
+template<class LabelType, class FeatureType>
+NumpyAnyArray 
+pythonRFPredictProbabilities(RandomForest<LabelType> & rf,
+                             NumpyArray<2,FeatureType> testData, 
+                             NumpyArray<2,float> res)
+{
+    vigra_precondition(!testData.axistags() && !res.axistags(),
+                       "RandomForest.predictProbabilities(): test data and output array must not\n"
+                       "have axistags (use 'array.view(numpy.ndarray)' to remove them).");
+    
+    res.reshapeIfEmpty(MultiArrayShape<2>::type(testData.shape(0), rf.ext_param_.class_count_),
+                       "RandomForest.predictProbabilities(): Output array has wrong dimensions.");
+    {
+        PyAllowThreads _pythread;
+        rf.predictProbabilities(testData, res);
+    }
+    return res;
+}
+
+template<class LabelType,class FeatureType>
+NumpyAnyArray 
+pythonRFPredictProbabilitiesOnlinePredSet(RandomForest<LabelType> & rf,
+                                          OnlinePredictionSet<FeatureType> & predSet,
+                                          NumpyArray<2,float> res)
+{
+    vigra_precondition(!res.axistags(),
+                       "RandomForest.predictProbabilities(): output array must not have axistags\n"
+                       "(use 'array.view(numpy.ndarray)' to remove them).");
+    
+    res.reshapeIfEmpty(MultiArrayShape<2>::type(predSet.features.shape(0),
+                                                 rf.ext_param_.class_count_),
+                       "RandomForest.predictProbabilities(): Output array has wrong dimenstions.");
+    USETICTOC;
+    TIC;
+    {
+        PyAllowThreads _pythread;
+        rf.predictProbabilities(predSet, res);
+    }
+    std::string t = TOCS;
+    std::cerr << "Prediction Time: " << t << std::endl;
+    return res;
+}
+
+
+void defineRandomForest()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+
+    class_<OnlinePredictionSet<float> > pred_set_class("RF_OnlinePredictionSet",python::no_init);
+    pred_set_class
+        .def("__init__",
+                python::make_constructor(registerConverters(&pythonConstructOnlinePredictioSet<float>),
+                                         boost::python::default_call_policies(),
+                                         (arg("features"))),
+                                         "docu")
+
+        .def("get_worsed_tree",&OnlinePredictionSet<float>::get_worsed_tree,
+           "doku")
+    
+        .def("invalidateTree",&OnlinePredictionSet<float>::reset_tree,
+         (arg("treeId")),
+         "doku")
+    ;
+
+    enum_<RF_OptionTag>("RF_MTRY_SWITCH")
+        .value("RF_MTRY_LOG",RF_LOG)
+        .value("RF_MTRY_SQRT",RF_SQRT)
+        .value("RF_MTRY_ALL",RF_ALL);
+
+    typedef UInt32 LabelType;
+    class_<RandomForest<LabelType> > rfclass_new("RandomForest",python::no_init);
+
+    rfclass_new
+        .def("__init__",python::make_constructor(registerConverters(&pythonConstructRandomForest<LabelType,float>),
+                                                 boost::python::default_call_policies(),
+                                                 ( arg("treeCount")=255,
+                                                   arg("mtry")= -1,
+                                                   arg("min_split_node_size")=1,
+                                                   arg("training_set_size")=0,
+                                                   arg("training_set_proportions")=1.0,
+                                                   arg("sample_with_replacement")=true,
+                                                   arg("sample_classes_individually")=false,
+                                                   arg("prepare_online_learning")=false,
+                                                   arg("labels")=python::list())),
+             "Constructor::\n\n"
+             "  RandomForest(treeCount = 255, mtry=RF_SQRT, min_split_node_size=1,\n"
+             "               training_set_size=0, training_set_proportions=1.0,\n"
+             "               sample_with_replacement=True, sample_classes_individually=False,\n"
+             "               prepare_online_learning=False)\n\n"
+             "'treeCount' controls the number of trees that are created.\n"
+             "'labels' is a list specifying the permitted labels.\n"
+             "         If empty (default), the labels are automatically determined\n"
+             "         from the training data. A non-empty list is useful when some\n"
+             "         labels lack training examples.\n\n"
+             "See RandomForest_ and RandomForestOptions_ in the C++ documentation "
+             "for the meaning of the other parameters.\n")
+#ifdef HasHDF5
+        .def("__init__",python::make_constructor(&pythonImportRandomForestFromHDF5<LabelType>,
+                                                 boost::python::default_call_policies(),
+                                                 ( arg("filename"),
+                                                   arg("pathInFile")="")),
+             "Load from HDF5 file::\n\n"
+             "  RandomForest(filename, pathInFile)\n\n")
+#endif // HasHDF5
+        .def("featureCount",
+            &RandomForest<LabelType>::column_count,
+             "Returns the number of features the RandomForest works with.\n")
+        .def("labelCount",
+            &RandomForest<LabelType>::class_count,
+             "Returns the number of labels, the RandomForest knows.\n")
+        .def("treeCount",
+             &RandomForest<LabelType>::tree_count,
+             "Returns the 'treeCount', that was set when constructing the RandomForest.\n")
+        .def("predictLabels",
+             registerConverters(&pythonRFPredictLabels<LabelType,float>),
+             (arg("testData"), arg("nanLabel")=object(), arg("out")=object()),
+             "Predict labels on 'testData'.\n\n"
+             "If a 'nanLabel' is provided, it will be returned for all rows of\n"
+             "the 'testData' that contain an NaN value. Otherwise, an exception is\n"
+             "thrown whenever Nan is encountered.\n\n"
+             "The output is an array containing a label for every test samples.\n")
+        .def("predictProbabilities",
+             registerConverters(&pythonRFPredictProbabilities<LabelType,float>),
+             (arg("testData"), arg("out")=object()),
+             "Predict probabilities for different classes on 'testData'.\n\n"
+             "The output is an array containing a probability for every test sample and class.\n")
+        .def("predictProbabilities",
+             registerConverters(&pythonRFPredictProbabilitiesOnlinePredSet<LabelType,float>),
+             (arg("testData"), arg("out")=object()),
+             "The output is an array containing a probability for every test sample and class.\n")
+        .def("learnRF",
+             registerConverters(&pythonLearnRandomForest<LabelType,float>),
+             (arg("trainData"), arg("trainLabels"), arg("randomSeed")=0),
+             "Trains a random Forest using 'trainData' and 'trainLabels'.\n\n"
+             "and returns the OOB. See the vigra documentation for the meaning af the rest of the parameters.\n")
+        .def("reLearnTree",
+             registerConverters(&pythonRFReLearnTree<LabelType,float>),
+            (arg("trainData"), arg("trainLabels"), arg("treeId"),
+             arg("randomSeed")=0),
+             "Re-learn one tree of the forest using 'trainData' and 'trainLabels'.\n\n"
+             "and returns the OOB. This might be helpful in an online learning setup to improve the classifier.\n")
+        .def("learnRFWithFeatureSelection",
+             registerConverters(&pythonLearnRandomForestWithFeatureSelection<LabelType,float>),
+             (arg("trainData"), arg("trainLabels"), arg("randomSeed")=0),
+             "Train a random Forest using 'trainData' and 'trainLabels'.\n\n"
+             "and returns the OOB and the Variable importance"
+             "See the vigra documentation for the meaning af the rest of the paremeters.\n")
+        .def("onlineLearn",
+             registerConverters(&pythonRFOnlineLearn<LabelType,float>),
+             (arg("trainData"),arg("trainLabels"),arg("startIndex"),
+              arg("adjust_thresholds")=false, arg("randomSeed")=0),
+             "Learn online.\n\n"
+             "Works only if forest has been created with prepare_online_learning=true. "
+             "Needs the old training data and the new appened, starting at startIndex.\n\n")
+#ifdef HasHDF5
+        .def("writeHDF5", (void (*)(const RandomForest<LabelType, ClassificationTag> &, std::string const &, std::string const &))&rf_export_HDF5,
+             (arg("filename"), arg("pathInFile")=""),
+             "Store the random forest in the given HDF5 file 'filename' under the internal\n"
+             "path 'pathInFile'.\n")
+#endif // HasHDF5
+        ;
+}
+
+} // namespace vigra
+
+
diff --git a/vigranumpy/src/core/random_forest_old.cxx b/vigranumpy/src/core/random_forest_old.cxx
new file mode 100644
index 0000000..ed8c2bc
--- /dev/null
+++ b/vigranumpy/src/core/random_forest_old.cxx
@@ -0,0 +1,178 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpylearning_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/random_forest_deprec.hxx>
+#include <set>
+#include <cmath>
+
+#define RandomForest RandomForestDeprec
+#define RandomForestOptions RandomForestOptionsDeprec
+#define DecisionTree DecisionTreeDeprec
+
+namespace python = boost::python;
+namespace vigra
+{
+
+template<class LabelType,class FeatureType>
+RandomForest<LabelType>*
+pythonConstructRandomForest(NumpyArray<2, FeatureType> trainData,
+                            NumpyArray<1, LabelType> trainLabels,
+                            int treeCount,
+                            int mtry,
+                            int min_split_node_size,
+                            int training_set_size,
+                            float training_set_proportions,
+                            bool sample_with_replacement,
+                            bool sample_classes_individually)
+
+{
+    RandomForestOptions options;
+    options
+        .featuresPerNode(mtry)
+        .sampleWithReplacement(sample_with_replacement)
+        .setTreeCount(treeCount)
+        .trainingSetSizeProportional(training_set_proportions)
+        .trainingSetSizeAbsolute(training_set_size)
+        .sampleClassesIndividually(sample_classes_individually)
+        .minSplitNodeSize(min_split_node_size);
+        
+    std::set<LabelType> uniqueLabels(trainLabels.data(), trainLabels.data()+trainLabels.size());
+
+    RandomForest<LabelType>* rf = 
+        new RandomForest<LabelType>(uniqueLabels.begin(), uniqueLabels.end(),
+                                    treeCount, options);
+    double oob;
+
+    {
+        PyAllowThreads _pythread;
+        oob = rf->learn(trainData, trainLabels);
+    }
+    
+    std::cout << "Out-of-bag error " << oob << std::endl;
+    return rf;
+}
+
+template<class LabelType,class FeatureType>
+NumpyAnyArray 
+pythonRFPredictLabels(RandomForest<LabelType> const & rf,
+                      NumpyArray<2,FeatureType> testData,
+                      NumpyArray<2,LabelType> res)
+{
+    res.reshapeIfEmpty(MultiArrayShape<2>::type(testData.shape(0), 1),
+            "Output array has wrong dimensions.");
+    
+    {
+        PyAllowThreads _pythread;
+        rf.predictLabels(testData, res);
+    }
+    return res;
+}
+
+template<class LabelType, class FeatureType>
+NumpyAnyArray 
+pythonRFPredictProbabilities(RandomForest<LabelType> const & rf,
+                             NumpyArray<2,FeatureType> testData,
+                             NumpyArray<2,float> res)
+{
+    res.reshapeIfEmpty(MultiArrayShape<2>::type(testData.shape(0), rf.labelCount()),
+            "Output array has wrong dimensions.");
+    {
+        PyAllowThreads _pythread;
+        rf.predictProbabilities(testData, res);
+    }
+    return res;
+}
+
+void defineRandomForestOld()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+
+    class_<RandomForest<UInt32> > rfclass("RandomForestOld",python::no_init);
+    rfclass
+        .def("__init__",python::make_constructor(registerConverters(&pythonConstructRandomForest<UInt32,float>),
+                                                 boost::python::default_call_policies(),
+                                                 ( arg("trainData"), arg("trainLabels"),
+                                                   arg("treeCount")=255,
+                                                   arg("mtry")=0,
+                                                   arg("min_split_node_size")=1,
+                                                   arg("training_set_size")=0,
+                                                   arg("training_set_proportions")=1.0,
+                                                   arg("sample_with_replacement")=true,
+                                                   arg("sample_classes_individually")=false)),
+             "Constructor::\n\n"
+             "  RandomForestOld(trainData, trainLabels,\n"
+             "                  treeCount = 255, mtry=0, min_split_node_size=1,\n"
+             "                  training_set_size=0, training_set_proportions=1.0,\n"
+             "                  sample_with_replacement=True, sample_classes_individually=False,)\n\n"
+             "Construct and train a RandomForest using 'trainData' and 'trainLabels'. "
+             "'treeCount' controls the number of trees that are created.\n\n"
+             "See RandomForest_ and RandomForestOptions_ in the C++ documentation "
+             "for the meaning of the other parameters.\n")
+        .def("featureCount",
+             &RandomForest<UInt32>::featureCount,
+             "Returns the number of features the RandomForest works with.\n")
+        .def("labelCount",
+             &RandomForest<UInt32>::labelCount,
+             "Returns the number of labels, the RanfomForest knows.\n")
+        .def("treeCount",
+             &RandomForest<UInt32>::treeCount,
+             "Returns the 'treeCount', that was set when constructing the RandomForest.\n")
+        .def("predictLabels",
+             registerConverters(&pythonRFPredictLabels<UInt32,float>),
+             (arg("testData"), arg("out")=object()),
+             "Predict labels on 'testData'."
+             "The output is an array containing a labels for every test samples.\n")
+        .def("predictProbabilities",
+             registerConverters(&pythonRFPredictProbabilities<UInt32,float>),
+             (arg("testData"), arg("out")=object()),
+             "Predict probabilities for different classes on 'testData'."
+             "The output is an array containing a probability for every test sample and class.\n")
+/*            .def("writeHDF5")
+        .def("readHDF5")*/
+        ;
+}
+
+} // namespace vigra
+
+#undef RandomForest
+#undef RandomForestOptions
+#undef DecisionTree
diff --git a/vigranumpy/src/core/sampling.cxx b/vigranumpy/src/core/sampling.cxx
new file mode 100644
index 0000000..b8ec1f7
--- /dev/null
+++ b/vigranumpy/src/core/sampling.cxx
@@ -0,0 +1,933 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpysampling_PyArray_API
+//#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/affinegeometry.hxx>
+#include <vigra/basicgeometry.hxx>
+#include <vigra/resizeimage.hxx>
+#include <vigra/splines.hxx>
+#include <vigra/mathutil.hxx>
+#include <vigra/multi_resize.hxx>
+#include <vigra/splineimageview.hxx>
+#include <vigra/resampling_convolution.hxx>
+
+namespace python = boost::python;
+
+namespace vigra
+{
+    
+template < class PixelType >
+NumpyAnyArray 
+pythonResampleImage(NumpyArray<3, Multiband<PixelType> > image, 
+                    double factor, 
+                    NumpyArray<3, Multiband<PixelType> > res)
+{
+    vigra_precondition((image.shape(0) > 1) && (image.shape(1) > 1),
+        "The input image must have a size of at least 2x2.");
+    int height,width;
+    if(factor < 1.0)
+    {
+        width = (int) std::ceil(factor * image.shape(0));
+        height= (int) std::ceil(factor * image.shape(1));
+    }
+    else
+    {
+        width = (int) std::ceil(factor * image.shape(0));
+        height= (int) std::ceil(factor * image.shape(1));
+    }
+
+    res.reshapeIfEmpty(image.taggedShape().resize(width, height),
+                       "resampleImage(): Output images has wrong dimensions");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            resampleImage(srcImageRange(bimage), destImage(bres), factor);
+        }
+    }
+    
+    return res;
+}
+
+enum RotationDirection
+{
+    ROTATE_CW,
+    ROTATE_CCW,
+    UPSIDE_DOWN
+};
+
+template < class PixelType>
+NumpyAnyArray 
+pythonFixedRotateImage(NumpyArray<3, Multiband<PixelType> > image, 
+                       RotationDirection dir, 
+                       NumpyArray<3,Multiband<PixelType> > res)
+{
+    int degree=0;
+    switch(dir)
+    {
+    case ROTATE_CW:
+        degree=270;
+        break;
+    case ROTATE_CCW:
+        degree=90;
+        break;
+    case UPSIDE_DOWN:
+        degree=180;
+        break;
+    }
+    
+    TaggedShape newShape(image.taggedShape());
+    if(degree % 180 == 0)
+    {
+        res.reshapeIfEmpty(newShape,"rotateImageSimple(): Output images has wrong dimensions");
+    }
+    else
+    {
+        MultiArrayShape<2>::type permute(1, 0);
+        res.reshapeIfEmpty(image.taggedShape().transposeShape(permute),
+                     "rotateImage(): Output image has wrong dimensions");
+    }
+    
+    {
+        PyAllowThreads _pythread;    
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            rotateImage(srcImageRange(bimage),destImage(bres),degree);
+        }
+    }
+    return res;
+}
+
+template < class PixelType>
+NumpyAnyArray 
+pythonFreeRotateImageDegree(NumpyArray<3, Multiband<PixelType> > image, 
+                            double degree,RotationDirection dir, int splineOrder,
+                            NumpyArray<3,Multiband<PixelType> > res)
+{
+    return pythonFreeRotateImageRadiant(image,degree*M_PI/180.0,dir,splineOrder,res);
+}
+
+template < class PixelType>
+NumpyAnyArray 
+pythonFreeRotateImageRadiant(NumpyArray<3, Multiband<PixelType> > image, 
+                             double radiant, RotationDirection dir, int splineOrder,
+                             NumpyArray<3,Multiband<PixelType> > res)
+{
+    if(splineOrder < 0 || splineOrder > 5)
+    {
+        PyErr_SetString(PyExc_ValueError, "rotateImageRadiant(): Spline order not supported.");
+        python::throw_error_already_set();
+    }
+
+    if(!res.hasData())
+        res.reshapeIfEmpty(image.taggedShape(),
+                           "rotateImageRadiant(): Output images has wrong dimensions");
+
+    vigra_precondition(res.shape(2)==image.shape(2),
+                  "rotateImageRadiant(): number of channels of image and result must be equal.");
+
+    if(dir==ROTATE_CW)
+        radiant=-radiant;
+
+    //Define the transformation
+    linalg::Matrix< double >  transform =
+        translationMatrix2D(TinyVector<double,2>(res.shape(0)/2.0, res.shape(1)/2.0))*
+        rotationMatrix2DRadians(radiant, TinyVector<double,2>(0.0,0.0))*
+        translationMatrix2D(TinyVector<double,2>(-image.shape(0)/2.0, -image.shape(1)/2.0));
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            switch (splineOrder)
+            {
+                case 0:
+                {
+                    SplineImageView< 0, PixelType > spline(srcImageRange(bimage));
+                    affineWarpImage(spline,destImageRange(bres),transform);
+                    break;
+                }
+                case 1:
+                {
+                    SplineImageView< 1, PixelType > spline(srcImageRange(bimage));
+                    affineWarpImage(spline,destImageRange(bres),transform);
+                    break;
+                }
+                case 2:
+                {
+                    SplineImageView< 2, PixelType > spline(srcImageRange(bimage));
+                    affineWarpImage(spline,destImageRange(bres),transform);
+                    break;
+                }
+                case 3:
+                { 
+                    SplineImageView< 3, PixelType > spline(srcImageRange(bimage));
+                    affineWarpImage(spline,destImageRange(bres),transform);
+                    break;
+                }
+                case 4:
+                {
+                    SplineImageView< 4, PixelType > spline(srcImageRange(bimage));
+                    affineWarpImage(spline,destImageRange(bres),transform);
+                    break;
+                }
+                case 5:
+                {
+                    SplineImageView< 5, PixelType > spline(srcImageRange(bimage));
+                    affineWarpImage(spline,destImageRange(bres),transform);
+                    break;
+                }
+            }
+        }
+    }
+    return res;
+}
+
+template <class PixelType, unsigned int dim>
+void pythonResizeImagePrepareOutput(NumpyArray<dim, Multiband<PixelType> > const & image, 
+                                    python::object destSize,
+                                    NumpyArray<dim, Multiband<PixelType> > & res)
+{
+    for(unsigned int k=0; k<dim-1; ++k)
+        vigra_precondition(image.shape(k),
+            "resizeImage(): Each input axis must have length > 1.");
+        
+    typedef typename MultiArrayShape<dim-1>::type Shape;
+    if(destSize != python::object())
+    {
+        vigra_precondition(!res.hasData(),
+               "resizeImage(): you cannot provide both 'shape' and 'out'.");
+                       
+        Shape shape = image.permuteLikewise(python::extract<Shape>(destSize)());
+              
+        res.reshapeIfEmpty(image.taggedShape().resize(shape), 
+                           "resizeImage(): Output image has wrong dimensions");
+    }
+    else
+    {
+        vigra_precondition(res.hasData(),
+               "resizeImage(): you must proved either 'shape' or 'out'.");
+        vigra_precondition(res.shape(dim-1) == image.shape(dim-1),
+               "resizeImage(): number of channels of image and result must be equal.");
+    }
+}
+
+template < class PixelType>
+NumpyAnyArray pythonResizeImageNoInterpolation(NumpyArray<3, Multiband<PixelType> > image, 
+                                               python::object destSize,
+                                               NumpyArray<3, Multiband<PixelType> > res)
+{
+    pythonResizeImagePrepareOutput(image, destSize, res);
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            resizeImageNoInterpolation(srcImageRange(bimage),destImageRange(bres));
+        }
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray pythonResizeImageLinearInterpolation(NumpyArray<3, Multiband<PixelType> > image,
+                                                   python::object destSize,
+                                                   NumpyArray<3, Multiband<PixelType> > res)
+{
+    pythonResizeImagePrepareOutput(image, destSize, res);
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            resizeImageLinearInterpolation(srcImageRange(bimage), destImageRange(bres));
+        }
+    }
+    return res;
+}
+
+template < class PixelType, int dim >
+NumpyAnyArray 
+pythonResizeImageSplineInterpolation(NumpyArray<dim, Multiband<PixelType> > image,
+                                     python::object destSize,
+                                     int splineOrder=3, 
+                                     NumpyArray<dim, Multiband<PixelType> > res=python::object())
+{
+    if(splineOrder < 0 || splineOrder > 5)
+    {
+        PyErr_SetString(PyExc_ValueError, "resize(): Spline order not supported.");
+        python::throw_error_already_set();
+    }
+    
+    pythonResizeImagePrepareOutput(image, destSize, res);
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(dim-1);++k)
+        {
+            
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<dim-1, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            switch (splineOrder)
+            {
+                case 0:
+                {
+                    BSpline< 0, double > spline;
+                    resizeMultiArraySplineInterpolation(srcMultiArrayRange(bimage),
+                                                        destMultiArrayRange(bres), spline);
+                    break;
+                }
+                case 1:
+                {
+                    BSpline< 1, double > spline;
+                    resizeMultiArraySplineInterpolation(srcMultiArrayRange(bimage),
+                                                        destMultiArrayRange(bres), spline);
+                    break;
+                }
+                case 2:
+                {
+                    BSpline< 2, double > spline;
+                    resizeMultiArraySplineInterpolation(srcMultiArrayRange(bimage),
+                                                        destMultiArrayRange(bres), spline);
+                    break;
+                }
+                case 3:
+                {
+                    BSpline< 3, double > spline;
+                    resizeMultiArraySplineInterpolation(srcMultiArrayRange(bimage),
+                                                        destMultiArrayRange(bres), spline);
+                    break;
+                }
+                case 4:
+                {
+                    BSpline< 4, double > spline;
+                    resizeMultiArraySplineInterpolation(srcMultiArrayRange(bimage),
+                                                        destMultiArrayRange(bres), spline);
+                    break;
+                }
+                case 5:
+                {
+                    BSpline< 5, double > spline;
+                    resizeMultiArraySplineInterpolation(srcMultiArrayRange(bimage),
+                                                        destMultiArrayRange(bres), spline);
+                    break;
+                }
+            }
+        }
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray pythonResizeImageCatmullRomInterpolation(NumpyArray<3, Multiband<PixelType> > image,
+                                                       python::object destSize,
+                                                       NumpyArray<3, Multiband<PixelType> > res)
+{
+    pythonResizeImagePrepareOutput(image, destSize, res);
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+
+            resizeImageCatmullRomInterpolation(srcImageRange(bimage),destImageRange(bres));
+        }
+    }
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray pythonResizeImageCoscotInterpolation(NumpyArray<3, Multiband<PixelType> > image,
+                                                   python::object destSize,
+                                                   NumpyArray<3, Multiband<PixelType> > res)
+{
+    pythonResizeImagePrepareOutput(image, destSize, res);
+    
+    {
+        PyAllowThreads _pythread;
+        for(int k=0;k<image.shape(2);++k)
+        {
+            
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            resizeImageCoscotInterpolation(srcImageRange(bimage),destImageRange(bres));
+        }
+    }
+    return res;
+}
+
+template <class PixelType>
+NumpyAnyArray 
+resamplingGaussian2D(NumpyArray<3, Multiband<PixelType> > image, 
+    double sigmax, unsigned int derivativeOrderX, double samplingRatioX, double offsetX,
+    double sigmay, unsigned int derivativeOrderY, double samplingRatioY, double offsetY, 
+    NumpyArray<3, Multiband<PixelType> > res = python::object())
+{
+    vigra_precondition(samplingRatioX > 0 ,
+       "resamplingGaussian(): samplingRatioX must be > 0.");
+    vigra_precondition(samplingRatioY > 0 ,
+       "resamplingGaussian(): samplingRatioY must be > 0.");
+       
+    Rational<int> xratio(samplingRatioX), yratio(samplingRatioY),
+                  xoffset(offsetX), yoffset(offsetY);
+    Gaussian< double > smoothx(sigmax, derivativeOrderX);
+    Gaussian< double > smoothy(sigmay, derivativeOrderY);
+
+    int width = rational_cast< int >(image.shape(0)*xratio);
+    int height = rational_cast< int >(image.shape(1)*yratio);
+    res.reshapeIfEmpty(image.taggedShape().resize(width, height), 
+             "resamplingGaussian2D(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        for(int k=0; k<image.shape(2); ++k)
+        {
+            MultiArrayView<2, PixelType, StridedArrayTag> bimage = image.bindOuter(k);
+            MultiArrayView<2, PixelType, StridedArrayTag> bres = res.bindOuter(k);
+            resamplingConvolveImage(srcImageRange(bimage), destImageRange(bres),
+                    smoothx, xratio, xoffset, smoothy, yratio, yoffset);
+        }
+    }
+    return res;
+}
+
+
+/********************************************************************/
+/*                                                                  */
+/*                         SplineImageView                          */
+/*                                                                  */
+/********************************************************************/
+
+template <class T>
+struct BindSplineConstructor;
+
+template <class T>
+struct BindSplineConstructor
+{
+    typedef Singleband<T> type;
+    typedef Singleband<npy_int32> int_type;
+    typedef Singleband<UInt8> byte_type;
+};
+
+template <class T, int N>
+struct BindSplineConstructor<TinyVector<T, N> >
+{
+    typedef TinyVector<T, N> type;
+    typedef TinyVector<npy_int32, N> int_type;
+    typedef TinyVector<UInt8, N> byte_type;
+};
+
+template <class SplineView>
+NumpyAnyArray
+SplineView_coefficientImage(SplineView const & self)
+{
+    typedef typename BindSplineConstructor<typename SplineView::value_type>::type ResType;
+    NumpyArray<2, ResType> res(self.shape());
+    copyImage(srcImageRange(self.image()), destImage(res));
+    return res;
+}
+
+template <class SplineView>
+NumpyAnyArray
+SplineView_interpolatedImage(SplineView const & self, double xfactor, double yfactor, unsigned int xorder, unsigned int yorder)
+{
+    vigra_precondition(xfactor > 0.0 && yfactor > 0.0,
+        "SplineImageView.interpolatedImage(xfactor, yfactor): factors must be positive.");
+        
+    int wn = int((self.width() - 1.0) * xfactor + 1.5);
+    int hn = int((self.height() - 1.0) * yfactor + 1.5);
+    
+    typedef typename BindSplineConstructor<typename SplineView::value_type>::type ResType;
+    NumpyArray<2, ResType> res(Shape2(wn, hn));
+
+    {
+        PyAllowThreads _pythread;
+        for(int yn = 0; yn < hn; ++yn)
+        {
+            double yo = yn / yfactor;
+            for(int xn = 0; xn < wn; ++xn)
+            {
+                double xo = xn / xfactor;
+                res(xn, yn) = self(xo, yo, xorder, yorder);
+            }
+        }
+    }
+    return res;
+}
+
+#define VIGRA_SPLINE_IMAGE(what, dx, dy) \
+template <class SplineView> \
+NumpyAnyArray \
+SplineView_##what##Image(SplineView const & self, double xfactor, double yfactor) \
+{ \
+    return SplineView_interpolatedImage(self, xfactor, yfactor, dx, dy); \
+}
+
+VIGRA_SPLINE_IMAGE(dx,  1, 0)
+VIGRA_SPLINE_IMAGE(dxx, 2, 0)
+VIGRA_SPLINE_IMAGE(dx3, 3, 0)
+VIGRA_SPLINE_IMAGE(dy,  0, 1)
+VIGRA_SPLINE_IMAGE(dyy, 0, 2)
+VIGRA_SPLINE_IMAGE(dy3, 0, 3)
+VIGRA_SPLINE_IMAGE(dxy, 1, 1)
+VIGRA_SPLINE_IMAGE(dxxy, 2, 1)
+VIGRA_SPLINE_IMAGE(dxyy, 1, 2)
+
+#undef VIGRA_SPLINE_IMAGE
+
+#define VIGRA_SPLINE_GRADIMAGE(what) \
+template <class SplineView> \
+NumpyAnyArray \
+SplineView_##what##Image(SplineView const & self, double xfactor, double yfactor) \
+{ \
+    vigra_precondition(xfactor > 0.0 && yfactor > 0.0, \
+        "SplineImageView." #what "Image(xfactor, yfactor): factors must be positive."); \
+    int wn = int((self.width() - 1.0) * xfactor + 1.5); \
+    int hn = int((self.height() - 1.0) * yfactor + 1.5); \
+    typedef typename SplineView::SquaredNormType ResType; \
+    NumpyArray<2, Singleband<ResType> > res(Shape2(wn, hn)); \
+    for(int yn = 0; yn < hn; ++yn) \
+    { \
+        double yo = yn / yfactor; \
+        for(int xn = 0; xn < wn; ++xn) \
+        { \
+            double xo = xn / xfactor; \
+            res(xn, yn) = self.what(xo, yo); \
+        } \
+    } \
+    return res; \
+}
+
+VIGRA_SPLINE_GRADIMAGE(g2)
+VIGRA_SPLINE_GRADIMAGE(g2x)
+VIGRA_SPLINE_GRADIMAGE(g2y)
+
+#undef VIGRA_SPLINE_GRADIMAGE
+
+template <class SplineView>
+NumpyAnyArray
+SplineView_facetCoefficients(SplineView const & self, double x, double y)
+{
+    int size = SplineView::order + 1;
+    NumpyArray<2, typename SplineView::value_type> res(Shape2(size, size));
+    self.coefficientArray(x, y, res);
+    return res;
+}
+
+template <class SplineView, class T>
+SplineView *
+pySplineView(NumpyArray<2, T> const & img)
+{
+    return new SplineView(srcImageRange(img), 0);
+}
+
+template <class SplineView, class T>
+SplineView *
+pySplineView1(NumpyArray<2, T> const & img, bool skipPrefilter)
+{
+    return new SplineView(srcImageRange(img), skipPrefilter);
+}
+
+template <class SplineView>
+python::class_<SplineView> &
+defSplineView(char const * name)
+{
+    using namespace python;
+
+    docstring_options doc_options(true, true, false);
+    
+    typedef typename SplineView::value_type Value;
+    typedef typename SplineView::SquaredNormType SNormValue;
+    typedef typename SplineView::difference_type Shape;
+    
+    Value (SplineView::*callfct)(double, double) const = &SplineView::operator();
+    Value (SplineView::*callfct2)(double, double, unsigned int, unsigned int) const = &SplineView::operator();
+
+    static python::class_<SplineView> theclass(name, python::no_init);
+    theclass
+        .def("__init__", python::make_constructor(registerConverters(&pySplineView<SplineView, typename BindSplineConstructor<Value>::byte_type>)),
+             "Construct a SplineImageView for the given image::\n\n"
+             "    SplineImageView(image, skipPrefilter = False)\n\n"
+             "Currently, 'image' can have dtype numpy.uint8, numpy.int32, and numpy.float32. "
+             "If 'skipPrefilter' is True, image values are directly used as spline "
+             "coefficients, so that the view performs approximation rather than interploation.\n\n")
+        .def("__init__", python::make_constructor(registerConverters(&pySplineView<SplineView, typename BindSplineConstructor<Value>::int_type>)))
+        .def("__init__", python::make_constructor(registerConverters(&pySplineView<SplineView, typename BindSplineConstructor<Value>::type>)))
+        .def("__init__", python::make_constructor(registerConverters(&pySplineView1<SplineView, typename BindSplineConstructor<Value>::byte_type>)))
+        .def("__init__", python::make_constructor(registerConverters(&pySplineView1<SplineView, typename BindSplineConstructor<Value>::int_type>)))
+        .def("__init__", python::make_constructor(registerConverters(&pySplineView1<SplineView, typename BindSplineConstructor<Value>::type>)))
+        .def("size", &SplineView::shape)
+        .def("shape", &SplineView::shape, "The shape of the underlying image.\n\n")
+        .def("width", &SplineView::width, "The width of the underlying image.\n\n")
+        .def("height", &SplineView::height, "The height of the underlying image.\n\n")
+        .def("isInside", &SplineView::isInside, 
+             "Check if a coordinate is inside the underlying image.\n\n"
+             "SplineImageView.isInside(x, y) -> bool\n\n")
+        .def("isValid", &SplineView::isValid, 
+             "Check if a coordinate is within the valid range of the SplineImageView.\n\n"
+             "SplineImageView.isValid(x, y) -> bool\n\n"
+             "Thanks to reflective boundary conditions, the valid range is three times "
+             "as big as the size of the underlying image.\n\n")
+        .def("__getitem__", (Value (SplineView::*)(Shape const &) const)&SplineView::operator(),
+             "Return the value of the spline at a real-valued coordinate.\n\n"
+             "Usage:\n\n"
+             "    s = SplineImageView3(image)\n"
+             "    value = s[10.1, 11.3]\n\n")
+        .def("__call__", callfct,
+             "Return the value of the spline or one of its derivatives at a real-valued coordinate.\n\n"
+             "Usage:\n\n"
+             "    s = SplineImageView3(image)\n"
+             "    value = s(10.1, 11.3)\n"
+             "    xorder = 1   # derivative order along x axis\n"
+             "    yorder = 0   # derivative order along y axis\n"
+             "    derivative = s(10.1, 11.3, xorder, yorder)\n\n")
+        .def("__call__", callfct2)
+        .def("dx", (Value (SplineView::*)(double, double) const)&SplineView::dx, args("x", "y"),
+             "Return first derivative in x direction at a real-valued coordinate.\n\n"
+             "SplineImageView.dx(x, y) -> value\n\n")
+        .def("dy", (Value (SplineView::*)(double, double) const)&SplineView::dy, args("x", "y"),
+             "Return first derivative in y direction at a real-valued coordinate.\n\n"
+             "SplineImageView.dy(x, y) -> value\n\n")
+        .def("dxx", (Value (SplineView::*)(double, double) const)&SplineView::dxx, args("x", "y"),
+             "Return second derivative in x direction at a real-valued coordinate.\n\n"
+             "SplineImageView.dxx(x, y) -> value\n\n")
+        .def("dxy", (Value (SplineView::*)(double, double) const)&SplineView::dxy, args("x", "y"),
+             "Return mixed second derivative at a real-valued coordinate.\n\n"
+             "SplineImageView.dxy(x, y) -> value\n\n")
+        .def("dyy", (Value (SplineView::*)(double, double) const)&SplineView::dyy, args("x", "y"),
+             "Return second derivative in y direction at a real-valued coordinate.\n\n"
+             "SplineImageView.dyy(x, y) -> value\n\n")
+        .def("dx3", (Value (SplineView::*)(double, double) const)&SplineView::dx3, args("x", "y"),
+             "Return third derivative in x direction at a real-valued coordinate.\n\n"
+             "SplineImageView.dx3(x, y) -> value\n\n")
+        .def("dxxy", (Value (SplineView::*)(double, double) const)&SplineView::dxxy, args("x", "y"),
+             "Return mixed third derivative at a real-valued coordinate.\n\n"
+             "SplineImageView.dxxy(x, y) -> value\n\n")
+        .def("dxyy", (Value (SplineView::*)(double, double) const)&SplineView::dxyy, args("x", "y"),
+             "Return mixed third derivative at a real-valued coordinate.\n\n"
+             "SplineImageView.dxyy(x, y) -> value\n\n")
+        .def("dy3", (Value (SplineView::*)(double, double) const)&SplineView::dy3, args("x", "y"),
+             "Return third derivative in y direction at a real-valued coordinate.\n\n"
+             "SplineImageView.dy3(x, y) -> value\n\n")
+        .def("g2", (SNormValue (SplineView::*)(double, double) const)&SplineView::g2, args("x", "y"),
+             "Return gradient squared magnitude at a real-valued coordinate.\n\n"
+             "SplineImageView.g2(x, y) -> value\n\n")
+        .def("g2x", (SNormValue (SplineView::*)(double, double) const)&SplineView::g2x, args("x", "y"),
+             "Return first derivative in x direction of the gradient squared magnitude at a real-valued coordinate.\n\n"
+             "SplineImageView.g2x(x, y) -> value\n\n")
+        .def("g2y", (SNormValue (SplineView::*)(double, double) const)&SplineView::g2y, args("x", "y"),
+             "Return first derivative in y direction of the gradient squared magnitude at a real-valued coordinate.\n\n"
+             "SplineImageView.g2y(x, y) -> value\n\n")
+        .def("dxImage", &SplineView_dxImage<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`dx`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.dxImage(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("dyImage", &SplineView_dyImage<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`dy`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.dyImage(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("dxxImage", &SplineView_dxxImage<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`dxx`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.dxxImage(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("dxyImage", &SplineView_dxyImage<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`dxy`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.dxyImage(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("dyyImage", &SplineView_dyyImage<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`dyy`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.dyyImage(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("dx3Image", &SplineView_dx3Image<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`dx3`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.dx3Image(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("dxxyImage", &SplineView_dxxyImage<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`dxxy`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.dxxyImage(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("dxyyImage", &SplineView_dxyyImage<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`dxyy`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.dxyyImage(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("dy3Image", &SplineView_dy3Image<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`dy3`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.dy3Image(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("g2Image", &SplineView_g2Image<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`g2`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.g2Image(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("g2xImage", &SplineView_g2xImage<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`g2x`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.g2xImage(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("g2yImage", &SplineView_g2yImage<SplineView>, (arg("xfactor") = 2.0, arg("yfactor") = 2.0),
+             "Like :meth:`g2y`, but returns an entire image with the given sampling factors. For example,\n\n"
+             "SplineImageView.g2yImage(2.0, 2.0) -> image\n\n"
+             "creates an derivative image with two-fold oversampling in both directions.\n\n")
+        .def("coefficientImage", &SplineView_coefficientImage<SplineView>)
+        .def("interpolatedImage", &SplineView_interpolatedImage<SplineView>,
+             (arg("xfactor") = 2.0, arg("yfactor") = 2.0, arg("xorder")=0, arg("yorder")=0),
+             "Return an interpolated image or derivative image with the given sampling factors "
+             "and derivative orders. For example, we get a two-fold oversampled image "
+             "with the x-derivatives in each pixel by:\n\n"
+             "SplineImageView.interpolatedImage(2.0, 2.0, 1, 0) -> image\n\n")
+        .def("facetCoefficients", &SplineView_facetCoefficients<SplineView>,
+             "SplineImageView.facetCoefficients(x, y) -> matrix\n\n"
+             "Return the facet coefficient matrix so that spline values can be computed\n"
+             "explicitly. The matrix has size (order+1)x(order+1), where order is \n"
+             "the order of the spline. The matrix must be multiplied from left and right\n"
+             "with the powers of the local facet x- and y-coordinates respectively\n"
+             "(note that local facet coordinates are in the range [0,1] for odd order\n"
+             "splines and [-0.5, 0.5] for even order splines).\n\n"
+             "Usage for odd spline order:\n\n"
+             "    s = SplineImageView3(image)\n"
+             "    c = s.coefficients(10.1, 10.7)\n"
+             "    x = matrix([1, 0.1, 0.1**2, 0.1**3])\n"
+             "    y = matrix([1, 0.7, 0.7**2, 0.7**3])\n"
+             "    assert abs(x * c * y.T - s[10.1, 10.7]) < smallNumber\n"
+             "\n"
+             "Usage for even spline order:\n\n"
+             "    s = SplineImageView2(image)\n"
+             "    c = s.coefficients(10.1, 10.7)\n"
+             "    x = matrix([1, 0.1, 0.1**2])\n"
+             "    y = matrix([1, -0.3, (-0.3)**2])\n"
+             "    assert abs(x * c * y.T - s[10.1, 10.7]) < smallNumber\n\n")
+        ;
+
+    return theclass;
+}
+
+
+void defineSampling()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+
+    enum_<RotationDirection>("RotationDirection")
+        .value("CLOCKWISE",ROTATE_CW)
+        .value("COUNTER_CLOCKWISE",ROTATE_CCW)
+        .value("UPSIDE_DOWN",UPSIDE_DOWN);
+    def("rotateImageRadiant",
+        registerConverters(&pythonFreeRotateImageRadiant<float>),
+        (arg("image"), arg("radiant"), arg("direction")=ROTATE_CW, arg("splineOrder")=0, arg("out")=object()),
+        "Rotate an image by an arbitrary angle around its center using splines for interpolation.\n"
+        "\n"
+        "The angle may be given in radiant (parameter radiant).\n"
+        "The parameter 'splineOrder' indicates the order of the splines used for interpolation.\n"
+        "If the 'out' parameter is given, the image is cropped for it's dimensions. If the 'out'\n"
+        "parameter is not given, an output image with the same dimensions as the input image is created.\n\n"
+        "For more details, see GeometricTransformations.rotationMatrix2DRadians_ in the vigra C++ documentation.\n" 
+        );
+    def("rotateImageDegree",
+        registerConverters(&pythonFreeRotateImageDegree<float>),
+        (arg("image"), arg("degree"), arg("direction")=ROTATE_CW, arg("splineOrder")=0, arg("out")=object()),
+        "Rotate an image by an arbitrary angle using splines for interpolation around its center.\n"
+        "\n"
+        "The angle may be given in degree (parameter degree).\n"
+        "The parameter 'splineOrder' indicates the order of the splines used for interpolation.\n"
+        "If the 'out' parameter is given, the image is cropped for it's dimensions. If the 'out'\n"
+        "parameter is not given, an output image with the same dimensions as the input image is created.\n\n"
+        "For more details, see GeometricTransformations.rotationMatrix2DDegrees_ in the vigra C++ documentation.\n"  
+        );
+    def("rotateImageSimple",
+        registerConverters(&pythonFixedRotateImage<float>),
+        (arg("image"), arg("orientation")=ROTATE_CW,arg("out")=object()),
+        "Rotate an image by a multiple of 90 degrees.\n"
+        "\n"
+        "The 'orientation' parameter (which must be one of CLOCKWISE, COUNTER_CLOCKWISE and UPSIDE_DOWN\n"
+        "indicates the rotation direction. The 'out' parameter must, if given, have the according dimensions.\n"
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "For more details, see rotateImage_ in the vigra C++ documentation.\n" 
+        );
+
+//    def("rotateImageAboutCenter",
+//       &DUMMY_FUNCTION,               // also multiband
+//        (arg("image"), arg("degrees"), arg("center"), arg("splineOrder")));
+
+    def("resampleImage",
+        registerConverters(&pythonResampleImage<float>),               // also multiband
+        (arg("image"), arg("factor"),arg("out")=object()),
+        "Resample an image by the given 'factor'\n"
+        "\n"
+        "The 'out' parameter must have, if given, the according dimensions.\n"
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "For more details, see resampleImage_ in the vigra C++ documentation.\n" 
+        );
+
+    def("resamplingGaussian", registerConverters(&resamplingGaussian2D<float>),
+          (arg("image"), 
+           arg("sigmaX")=1.0, arg("derivativeOrderX")=0, arg("samplingRatioX")=2.0, arg("offsetX")=0.0, 
+           arg("sigmaY")=1.0, arg("derivativeOrderY")=0, arg("samplingRatioY")=2.0, arg("offsetY")=0.0, 
+           arg("out") = python::object()),
+          "Resample image using a gaussian filter::\n\n"
+          "   resamplingGaussian(image,\n"
+          "                      sigmaX=1.0, derivativeOrderX=0, samplingRatioX=2.0, offsetX=0.0,\n"
+          "                      sigmaY=1.0, derivativeOrderY=0, samplingRatioY=2.0, offsetY=0.0,\n"
+          "                      out=None)\n"
+          "\n"
+          "This function utilizes resamplingConvolveImage_ with a Gaussianfilter\n"
+          "(see the vigra C++ documentation for details).\n\n");
+
+    def("resizeImageNoInterpolation",
+        registerConverters(&pythonResizeImageNoInterpolation<float>),               // also multiband
+        (arg("image"), arg("shape")=object(), arg("out")=object()),
+        "Resize image by repeating the nearest pixel values.\n"
+        "\n"
+        "The desired shape of the output image is taken either from 'shape' or 'out'.\n"
+        "If both are given, they must agree.\n"
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "For more details, see resizeImageNoInterpolation_ in the vigra C++ documentation.\n"
+        );
+
+
+    def("resizeImageLinearInterpolation",
+        registerConverters(&pythonResizeImageLinearInterpolation<float>),               // also multiband>
+        (arg("image"), arg("shape")=object(), arg("out")=object()),
+        "Resize image using linear interpolation.\n"
+        "The function uses the standard separable bilinear interpolation algorithm to obtain a good compromise between quality and speed.\n"
+        "\n" 
+        "The desired shape of the output image is taken either from 'shape' or 'out'.\n"
+        "If both are given, they must agree.\n"
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "For more details, see resizeImageLinearInterpolation_ in the vigra C++ documentation.\n"
+        );
+
+    def("resizeImageSplineInterpolation",
+        registerConverters(&pythonResizeImageSplineInterpolation<float,3>),               // also multiband
+        (arg("image"), arg("shape")=object(), arg("order") = 3, arg("out") = object()),
+        "Resize image using B-spline interpolation.\n"
+        "\n"
+        "The spline order is given in the parameter 'order'.\n"
+        "The desired shape of the output image is taken either from 'shape' or 'out'.\n"
+        "If both are given, they must agree.\n"
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "For more details, see resizeImageSplineInterpolation_ in the vigra C++ documentation.\n"
+       );
+
+    def("resizeImageCatmullRomInterpolation",
+        registerConverters(&pythonResizeImageCatmullRomInterpolation<float>),               // also multiband
+        (arg("image"), arg("shape")=object(), arg("out")=object()),
+        "Resize image using the Catmull/Rom interpolation function.\n"
+        "\n" 
+        "The desired shape of the output image is taken either from 'shape' or 'out'.\n"
+        "If both are given, they must agree.\n"
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "For more details, see resizeImageCatmullRomInterpolation_ in the vigra C++ documentation.\n"
+       );
+
+    def("resizeImageCoscotInterpolation",
+        registerConverters(&pythonResizeImageCoscotInterpolation<float>),               // also multiband
+        (arg("image"), arg("shape")=object(), arg("out")=object()),
+        "Resize image using the Coscot interpolation function.\n" 
+        "\n" 
+        "The desired shape of the output image is taken either from 'shape' or 'out'.\n"
+        "If both are given, they must agree.\n"
+        "This function also works for multiband images, it is then executed on every band.\n\n"
+        "For more details, see resizeImageCoscotInterpolation_ in the vigra C++ documentation.\n"
+        );
+
+    def("resizeVolumeSplineInterpolation",
+        registerConverters(&pythonResizeImageSplineInterpolation<float,4>),               // also multiband
+        (arg("image"), arg("shape")=object(), arg("order") = 3, arg("out") = object()),
+        "Resize volume using B-spline interpolation.\n"
+        "\n"
+        "The spline order is given in the parameter 'order'.\n"
+        "The dimensions of the output volume is taken either from 'shape' or 'out'.\n"
+        "If both are given, they must agree.\n"
+        "This function also works for multiband volumes, it is then executed on every band.\n\n"
+        "For more details, see resizeMultiArraySplineInterpolation_ in the vigra C++ documentation.\n"
+       );
+
+
+    def("resize", registerConverters(&pythonResizeImageSplineInterpolation<float,3>),
+        (arg("image"), arg("shape")=object(), arg("order") = 3, arg("out") = object()),
+        "Resize image or volume using B-spline interpolation.\n"
+        "\n"
+        "The spline order is given in the parameter 'order'.\n"
+        "The desired shape of the output array is taken either from 'shape' or 'out'.\n"
+        "If both are given, they must agree. This function also works for multi-channel "
+        "data, it is then executed on every channel independently.\n\n"
+        "For more details, see resizeImageSplineInterpolation_ and "
+        "resizeMultiArraySplineInterpolation_ in the vigra C++ documentation.\n"
+       );
+
+       def("resize",
+        registerConverters(&pythonResizeImageSplineInterpolation<float,4>),
+        (arg("image"), arg("shape")=object(), arg("order") = 3, arg("out") = object()));
+
+
+    defSplineView<SplineImageView<0, float> >("SplineImageView0");
+    defSplineView<SplineImageView<1, float> >("SplineImageView1");
+    defSplineView<SplineImageView<2, float> >("SplineImageView2");
+    defSplineView<SplineImageView<3, float> >("SplineImageView3");
+    defSplineView<SplineImageView<4, float> >("SplineImageView4");
+    defSplineView<SplineImageView<5, float> >("SplineImageView5");
+
+    defSplineView<SplineImageView<3, TinyVector<float, 3> > >("SplineImageView3V3");
+}
+
+} // namespace vigra
+
+
+using namespace vigra;
+using namespace boost::python;
+
+BOOST_PYTHON_MODULE_INIT(sampling)
+{
+    import_vigranumpy();
+    defineSampling();
+}
+
diff --git a/vigranumpy/src/core/segmentation.cxx b/vigranumpy/src/core/segmentation.cxx
new file mode 100644
index 0000000..0fd1d38
--- /dev/null
+++ b/vigranumpy/src/core/segmentation.cxx
@@ -0,0 +1,1297 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyanalysis_PyArray_API
+//#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/localminmax.hxx>
+#include <vigra/labelimage.hxx>
+#include <vigra/watersheds.hxx>
+#include <vigra/seededregiongrowing.hxx>
+#include <vigra/labelvolume.hxx>
+#include <vigra/watersheds3d.hxx>
+#include <vigra/seededregiongrowing3d.hxx>
+#include <vigra/multi_watersheds.hxx>
+#include <vigra/convolution.hxx>
+#include <vigra/multi_convolution.hxx>
+#include <vigra/slic.hxx>
+
+#include <string>
+#include <cmath>
+
+#include "tws.hxx"
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+template < class PixelType >
+NumpyAnyArray 
+pythonLabelImage(NumpyArray<2, Singleband<PixelType> > image,
+                 int neighborhood = 4, 
+                 NumpyArray<2, Singleband<npy_uint32> > res = NumpyArray<2, Singleband<npy_uint32> >())
+{
+    vigra_precondition(neighborhood == 4 || neighborhood == 8,
+        "labelImage(): neighborhood must be 4 or 8.");
+
+    std::string description("connected components, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "labelImage(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        switch (neighborhood)
+        {
+            case 4:
+            {
+                labelImage(srcImageRange(image), destImage(res), false);
+                break;
+            }
+            case 8:
+            {
+                labelImage(srcImageRange(image), destImage(res), true);
+                break;
+            }
+        }
+    }
+    
+    return res;
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pyLabelImage, pythonLabelImage)
+
+template < class PixelType >
+NumpyAnyArray 
+pythonLabelImageWithBackground(NumpyArray<2, Singleband<PixelType> > image,
+                               int neighborhood = 4,
+                               PixelType background_value = 0,
+                               NumpyArray<2, Singleband<npy_uint32> > res = NumpyArray<2, Singleband<npy_uint32> >())
+{
+    vigra_precondition(neighborhood == 4 || neighborhood == 8,
+        "labelImageWithBackground(): neighborhood must be 4 or 8.");
+
+    std::string description("connected components with background, neighborhood=");
+    description += asString(neighborhood)+ ", bglabel=" + asString(background_value);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+        "labelImageWithBackground(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        switch (neighborhood)
+        {
+            case 4:
+            {
+                labelImageWithBackground(srcImageRange(image),
+                    destImage(res), false, background_value);
+                break;
+            }
+            case 8:
+            {
+                labelImageWithBackground(srcImageRange(image),
+                    destImage(res), true, background_value);
+                break;
+            }
+        }
+    }
+    return res;
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pyLabelImageWithBackground, pythonLabelImageWithBackground)
+
+template < class VoxelType >
+NumpyAnyArray 
+pythonLabelVolume(NumpyArray<3, Singleband<VoxelType> > volume, 
+                  int neighborhood=6,
+                  NumpyArray<3, Singleband<npy_uint32> > res = NumpyArray<3, Singleband<npy_uint32> >())
+{
+    vigra_precondition(neighborhood == 6 || neighborhood == 26,
+        "labelVolume(): neighborhood must be 6 or 26.");
+    
+    std::string description("connected components, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(volume.taggedShape().setChannelDescription(description), 
+            "labelVolume(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        switch (neighborhood)
+        {
+            case 6:
+            {
+                labelVolume(srcMultiArrayRange(volume),
+                    destMultiArray(res), NeighborCode3DSix());
+                break;
+            }
+            case 26:
+            {
+                labelVolume(srcMultiArrayRange(volume),
+                    destMultiArray(res), NeighborCode3DTwentySix());
+                break;
+            }
+        }
+    }
+    return res;
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pyLabelVolume, pythonLabelVolume)
+
+template < class VoxelType >
+NumpyAnyArray 
+pythonLabelVolumeWithBackground(NumpyArray<3, Singleband<VoxelType> > volume, 
+                                int neighborhood=6,
+                                VoxelType background_value = 0,
+                                NumpyArray<3, Singleband<npy_uint32> > res = NumpyArray<3, Singleband<npy_uint32> >())
+{
+    vigra_precondition(neighborhood == 6 || neighborhood == 26,
+        "labelVolumeWithBackground(): neighborhood must be 6 or 26.");
+    
+    std::string description("connected components with background, neighborhood=");
+    description += asString(neighborhood)+ ", bglabel=" + asString(background_value);
+    
+    res.reshapeIfEmpty(volume.taggedShape().setChannelDescription(description), 
+        "labelVolumeWithBackground(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        switch (neighborhood)
+        {
+            case 6:
+            {
+                labelVolumeWithBackground(srcMultiArrayRange(volume),
+                    destMultiArray(res), NeighborCode3DSix(),
+                    background_value);
+                break;
+            }
+            case 26:
+            {
+                labelVolumeWithBackground(srcMultiArrayRange(volume),
+                    destMultiArray(res), NeighborCode3DTwentySix(),
+                    background_value);
+                break;
+            }
+        }
+    }
+    return res;
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pyLabelVolumeWithBackground, pythonLabelVolumeWithBackground)
+
+/*********************************************************************************/
+
+// FIXME: support output of label images from localMinim/Maxima functions
+
+template < class PixelType >
+NumpyAnyArray 
+pythonLocalMinima2D(NumpyArray<2, Singleband<PixelType> > image,
+                    PixelType marker = NumericTraits<PixelType>::one(),
+                    int neighborhood = 8,
+                    NumpyArray<2, Singleband<PixelType> > res = NumpyArray<2, Singleband<PixelType> >())
+{
+    vigra_precondition(neighborhood == 4 || neighborhood == 8,
+        "localMinima(): neighborhood must be 4 or 8.");
+
+    std::string description("local minima, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "localMinima(): Output array has wrong shape.");
+
+    {
+            PyAllowThreads _pythread;
+        switch (neighborhood)
+        {
+            case 4:
+            {
+                localMinima(srcImageRange(image), destImage(res), marker,
+                    FourNeighborCode());
+                break;
+            }
+            case 8:
+            {
+                localMinima(srcImageRange(image), destImage(res), marker,
+                    EightNeighborCode());
+                break;
+            }
+        }
+    }
+    
+    return res;
+}
+
+template<class PixelType>
+NumpyAnyArray 
+pythonLocalMinima3D(NumpyArray<3, Singleband<PixelType> > volume,
+                    PixelType marker = NumericTraits<PixelType>::one(), 
+                    int neighborhood = 6, 
+                    NumpyArray<3, Singleband<PixelType> > res = NumpyArray<3, Singleband<PixelType> >())
+{
+    vigra_precondition(neighborhood == 6 || neighborhood == 26,
+            "localMinima(): neighborhood must be 6 or 26.");
+
+    std::string description("local minima, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(volume.taggedShape().setChannelDescription(description), 
+            "localMinima(): Output array has wrong shape.");
+            
+    switch (neighborhood)
+    {
+        case 6:
+        {
+            localMinima3D(srcMultiArrayRange(volume), destMultiArray(res), marker,
+                    NeighborCode3DSix());
+            break;
+        }
+        case 26:
+        {
+            localMinima3D(srcMultiArrayRange(volume), destMultiArray(res), marker,
+                    NeighborCode3DTwentySix());
+            break;
+        }
+    }
+
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonExtendedLocalMinima2D(NumpyArray<2, Singleband<PixelType> > image,
+                            PixelType marker = NumericTraits<PixelType>::one(),
+                            int neighborhood = 8,
+                            NumpyArray<2, Singleband<PixelType> > res = NumpyArray<2, Singleband<PixelType> >())
+{
+    vigra_precondition(neighborhood == 4 || neighborhood == 8,
+        "extendedLocalMinima(): neighborhood must be 4 or 8.");
+
+    std::string description("extended local minima, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+        "extendedLocalMinima(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        switch (neighborhood)
+        {
+            case 4:
+            {
+                extendedLocalMinima(srcImageRange(image), destImage(res),
+                    marker, FourNeighborCode());
+                break;
+            }
+            case 8:
+            {
+                extendedLocalMinima(srcImageRange(image), destImage(res),
+                    marker, EightNeighborCode());
+                break;
+            }
+        }
+    }
+    return res;
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pyExtendedLocalMinima2D, pythonExtendedLocalMinima2D)
+
+template<class PixelType>
+NumpyAnyArray 
+pythonExtendedLocalMinima3D(NumpyArray<3, Singleband<PixelType> > volume, 
+                            PixelType marker = NumericTraits<PixelType>::one(), 
+                            int neighborhood = 6,
+                            NumpyArray<3, Singleband<PixelType> > res = NumpyArray<3, Singleband<PixelType> >())
+{
+    vigra_precondition(neighborhood == 6 || neighborhood == 26,
+            "extendedLocalMinima(): neighborhood must be 6 or 26.");
+
+    std::string description("extended local minima, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(volume.taggedShape().setChannelDescription(description), 
+            "extendedLocalMinima(): Output array has wrong shape.");
+    switch (neighborhood)
+    {
+        case 6:
+        {
+            extendedLocalMinima3D(srcMultiArrayRange(volume), destMultiArray(res),
+                marker, NeighborCode3DSix());
+            break;
+        }
+        case 26:
+        {
+            extendedLocalMinima3D(srcMultiArrayRange(volume), destMultiArray(res),
+                marker, NeighborCode3DTwentySix());
+            break;
+        }
+    }
+
+    return res;
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pyExtendedLocalMinima3D, pythonExtendedLocalMinima3D)
+
+template < class PixelType >
+NumpyAnyArray 
+pythonLocalMaxima2D(NumpyArray<2, Singleband<PixelType> > image,
+                    PixelType marker = NumericTraits<PixelType>::one(),
+                    int neighborhood = 8,
+                    NumpyArray<2, Singleband<PixelType> > res = NumpyArray<2, Singleband<PixelType> >())
+{
+    vigra_precondition(neighborhood == 4 || neighborhood == 8,
+        "localMaxima(): neighborhood must be 4 or 8.");
+
+    std::string description("local maxima, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "localMaxima(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        switch (neighborhood)
+        {
+            case 4:
+            {
+                localMaxima(srcImageRange(image), destImage(res), marker,
+                    FourNeighborCode());
+                break;
+            }
+            case 8:
+            {
+                localMaxima(srcImageRange(image), destImage(res), marker,
+                    EightNeighborCode());
+                break;
+            }
+        }
+    }
+    
+    return res;
+}
+
+template<class PixelType>
+NumpyAnyArray 
+pythonLocalMaxima3D(NumpyArray<3, Singleband<PixelType> > volume,
+                    PixelType marker = NumericTraits<PixelType>::one(), 
+                    int neighborhood = 6, 
+                    NumpyArray<3, Singleband<PixelType> > res = NumpyArray<3, Singleband<PixelType> >())
+{
+    vigra_precondition(neighborhood == 6 || neighborhood == 26,
+            "localMaxima(): neighborhood must be 6 or 26.");
+
+    std::string description("local maxima, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(volume.taggedShape().setChannelDescription(description), 
+            "localMaxima(): Output array has wrong shape.");
+    switch (neighborhood)
+    {
+        case 6:
+        {
+            localMaxima3D(srcMultiArrayRange(volume), destMultiArray(res), marker,
+                NeighborCode3DSix());
+            break;
+        }
+        case 26:
+        {
+            localMaxima3D(srcMultiArrayRange(volume), destMultiArray(res), marker,
+                NeighborCode3DTwentySix());
+            break;
+        }
+    }
+
+    return res;
+}
+
+template < class PixelType >
+NumpyAnyArray 
+pythonExtendedLocalMaxima2D(NumpyArray<2, Singleband<PixelType> > image,
+                            PixelType marker = NumericTraits<PixelType>::one(),
+                            int neighborhood = 8,
+                            NumpyArray<2, Singleband<PixelType> > res = NumpyArray<2, Singleband<PixelType> >())
+{
+    vigra_precondition(neighborhood == 4 || neighborhood == 8,
+        "extendedLocalMaxima(): neighborhood must be 4 or 8.");
+
+    std::string description("extended local maxima, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "extendedLocalMaxima(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        switch (neighborhood)
+        {
+            case 4:
+            {
+                extendedLocalMaxima(srcImageRange(image), destImage(res),
+                    marker, FourNeighborCode());
+                break;
+            }
+            case 8:
+            {
+                extendedLocalMaxima(srcImageRange(image), destImage(res),
+                    marker, EightNeighborCode());
+                break;
+            }
+        }
+    }
+    return res;
+}
+
+template<class PixelType>
+NumpyAnyArray 
+pythonExtendedLocalMaxima3D(NumpyArray<3, Singleband<PixelType> > volume, 
+                            PixelType marker = NumericTraits<PixelType>::one(), 
+                            int neighborhood = 6,
+                            NumpyArray<3, Singleband<PixelType> > res = NumpyArray<3, Singleband<PixelType> >())
+{
+    vigra_precondition(neighborhood == 6 || neighborhood == 26,
+            "extendedLocalMaxima(): neighborhood must be 6 or 26.");
+
+    std::string description("extended local maxima, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(volume.taggedShape().setChannelDescription(description), 
+            "extendedLocalMaxima(): Output array has wrong shape.");
+    switch (neighborhood)
+    {
+        case 6:
+        {
+            extendedLocalMaxima3D(srcMultiArrayRange(volume), destMultiArray(res),
+                                  marker, NeighborCode3DSix());
+            break;
+        }
+        case 26:
+        {
+            extendedLocalMaxima3D(srcMultiArrayRange(volume), destMultiArray(res),
+                                  marker, NeighborCode3DTwentySix());
+            break;
+        }
+    }
+
+    return res;
+}
+
+/*************************************************************************/
+
+#if 0
+template < class PixelType >
+python::tuple 
+pythonWatersheds2DOld(NumpyArray<2, Singleband<PixelType> > image,
+                   int neighborhood = 4,
+                   NumpyArray<2, Singleband<npy_uint32> > seeds = python::object(),
+                   std::string method = "RegionGrowing", 
+                   SRGType srgType = CompleteGrow, 
+                   PixelType max_cost = 0.0, 
+                   NumpyArray<2, Singleband<npy_uint32> > res = NumpyArray<2, Singleband<npy_uint32> >())
+{
+    vigra_precondition(neighborhood == 4 || neighborhood == 8,
+           "watersheds2D(): neighborhood must be 4 or 8.");
+
+    method = tolower(method);
+    
+    bool haveSeeds = seeds.hasData();
+    unsigned int maxRegionLabel = 0;
+    
+    if(method == "")
+        method = "regiongrowing";
+    
+    if(method == "regiongrowing")
+    {
+        seeds.reshapeIfEmpty(image.shape(), 
+                "watersheds(): Seed array has wrong shape.");
+        
+        if(!haveSeeds)
+        {
+            MultiArray<2, UInt8> minima(image.shape());
+            localMinima(srcImageRange(image), destImage(minima), 1, EightNeighborCode());
+            maxRegionLabel = labelImageWithBackground(srcImageRange(minima), destImage(seeds), true, 0);
+        }
+        else
+        {
+            FindMinMax< npy_uint32 > minmax;
+            inspectImage(srcImageRange(seeds), minmax);
+            maxRegionLabel = minmax.max;
+        }
+           
+        res.reshapeIfEmpty(image.shape(), "watersheds(): Output array has wrong shape.");
+
+        ArrayOfRegionStatistics< SeedRgDirectValueFunctor< PixelType > > stats(maxRegionLabel);
+        if(neighborhood == 4)
+        {
+            seededRegionGrowing(srcImageRange(image), srcImage(seeds), destImage(res), 
+                                stats, srgType, FourNeighborCode(), max_cost);
+        }
+        else
+        {
+            seededRegionGrowing(srcImageRange(image), srcImage(seeds), destImage(res), 
+                                stats, srgType, EightNeighborCode(), max_cost);
+        }
+    }
+    else if(method == "unionfind")
+    {
+        vigra_precondition(!haveSeeds,
+           "watersheds(): UnionFind does not support seed images.");
+        vigra_precondition(srgType == CompleteGrow,
+           "watersheds(): UnionFind only supports 'CompleteGrow' mode.");
+           
+        res.reshapeIfEmpty(image.shape(), "watersheds(): Output array has wrong shape.");
+        
+        if(neighborhood == 4)
+        {
+            maxRegionLabel = watershedsUnionFind(srcImageRange(image), destImage(res),
+                                        FourNeighborCode());
+        }
+        else
+        {
+            maxRegionLabel = watershedsUnionFind(srcImageRange(image), destImage(res),
+                                        EightNeighborCode());
+        }
+    }
+    else
+    {
+        vigra_precondition(false, "watersheds(): Unknown watershed method requested.");
+    }
+
+    return python::make_tuple(res, maxRegionLabel);
+}
+#endif
+
+template < class PixelType >
+python::tuple 
+pythonWatersheds2D(NumpyArray<2, Singleband<PixelType> > image,
+                   int neighborhood = 4,
+                   NumpyArray<2, Singleband<npy_uint32> > seeds = NumpyArray<2, Singleband<npy_uint32> >(),
+                   std::string method = "", 
+                   SRGType srgType = CompleteGrow, 
+                   PixelType max_cost = 0.0, 
+                   NumpyArray<2, Singleband<npy_uint32> > res = NumpyArray<2, Singleband<npy_uint32> >())
+{
+    vigra_precondition(neighborhood == 4 || neighborhood == 8,
+           "watersheds2D(): neighborhood must be 4 or 8.");
+
+    method = tolower(method);
+    if(method == "")
+    {
+        if(IsSameType<PixelType, npy_uint8>::value)
+            method = "turbo";
+        else
+            method = "regiongrowing";
+    }
+    
+    std::string description("watershed labeling, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "watersheds(): Output array has wrong shape.");
+    
+    WatershedOptions options;
+    options.srgType(srgType);
+    
+    if(max_cost > 0.0)
+    {
+        vigra_precondition(method != "unionfind",
+           "watersheds(): UnionFind does not support a cost threshold.");
+        options.stopAtThreshold(max_cost);
+    }
+    
+    if(seeds.hasData())
+    {
+        vigra_precondition(method != "unionfind",
+           "watersheds(): UnionFind does not support seed images.");
+        res = seeds;
+    }
+    else
+    {
+        if(method == "turbo")
+            options.seedOptions(SeedOptions().extendedMinima());
+        else
+            options.seedOptions(SeedOptions().minima());
+    }
+    
+    if(method == "turbo")
+    {
+        vigra_precondition((IsSameType<PixelType, npy_uint8>::value),
+           "watersheds(): Turbo method only works for uint8 images.");
+        options.turboAlgorithm();
+        method = "regiongrowing";
+    }
+    
+    npy_uint32 maxRegionLabel = 0;
+    if(method == "regiongrowing")
+    {
+        PyAllowThreads _pythread;
+        if(neighborhood == 4)
+        {
+            maxRegionLabel = watershedsRegionGrowing(srcImageRange(image), destImage(res), 
+                                    FourNeighborCode(), options);
+        }
+        else
+        {
+            maxRegionLabel = watershedsRegionGrowing(srcImageRange(image), destImage(res), 
+                                    EightNeighborCode(), options);
+        }
+    }
+    else if(method == "unionfind")
+    {
+        vigra_precondition(srgType == CompleteGrow,
+           "watersheds(): UnionFind only supports 'CompleteGrow' mode.");
+           
+        PyAllowThreads _pythread;
+        if(neighborhood == 4)
+        {
+            maxRegionLabel = watershedsUnionFind(srcImageRange(image), destImage(res),
+                                        FourNeighborCode());
+        }
+        else
+        {
+            maxRegionLabel = watershedsUnionFind(srcImageRange(image), destImage(res),
+                                        EightNeighborCode());
+        }
+    }
+    else
+    {
+        vigra_precondition(false, "watersheds(): Unknown watershed method requested.");
+    }
+
+    return python::make_tuple(res, maxRegionLabel);
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pywatersheds2D, pythonWatersheds2D)
+
+template <unsigned int N, class PixelType >
+python::tuple 
+pythonWatershedsNew(NumpyArray<N, Singleband<PixelType> > image,
+                    int neighborhood = 0,
+                    NumpyArray<N, Singleband<npy_uint32> > seeds = NumpyArray<N, Singleband<npy_uint32> >(),
+                    std::string method = "", 
+                    SRGType srgType = CompleteGrow, 
+                    PixelType max_cost = 0.0, 
+                    NumpyArray<N, Singleband<npy_uint32> > res = NumpyArray<N, Singleband<npy_uint32> >())
+{
+    method = tolower(method);
+    if(method == "" || method == "turbo")
+    {
+        method = "regiongrowing";
+    }
+    
+    std::string description("watershed labeling, neighborhood=");
+    description += asString(neighborhood);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "watersheds(): Output array has wrong shape.");
+    
+    WatershedOptions options;
+    options.srgType(srgType);
+    
+    if(method == "regiongrowing")
+    {
+        options.regionGrowing();
+    }
+    else if(method == "unionfind")
+    {
+        options.unionFind();
+    }
+    else
+    {
+        vigra_precondition(false, "watersheds(): Unknown watershed method requested.");
+    }
+    
+    if(max_cost > 0.0)
+    {
+        vigra_precondition(method != "unionfind",
+           "watersheds(): UnionFind does not support a cost threshold.");
+        options.stopAtThreshold(max_cost);
+    }
+    
+    if(seeds.hasData())
+    {
+        vigra_precondition(method != "unionfind",
+           "watersheds(): UnionFind does not support seed images.");
+        res = seeds;
+    }
+    else
+    {
+        options.seedOptions(SeedOptions().extendedMinima());
+    }
+    
+    NeighborhoodType n = (neighborhood == 0)
+                             ? DirectNeighborhood
+                             : IndirectNeighborhood;    
+    npy_uint32 maxRegionLabel = 0;
+    {
+        PyAllowThreads _pythread;
+        maxRegionLabel = watershedsMultiArray(image, res, n, options);
+    }
+
+    return python::make_tuple(res, maxRegionLabel);
+}
+
+template <class PixelType >
+python::tuple 
+pythonWatersheds2DNew(NumpyArray<2, Singleband<PixelType> > image,
+                      int neighborhood = 4,
+                      NumpyArray<2, Singleband<npy_uint32> > seeds = NumpyArray<2, Singleband<npy_uint32> >(),
+                      std::string method = "", 
+                      SRGType srgType = CompleteGrow, 
+                      PixelType max_cost = 0.0, 
+                      NumpyArray<2, Singleband<npy_uint32> > res = NumpyArray<2, Singleband<npy_uint32> >())
+{
+    vigra_precondition(neighborhood == 4 || neighborhood == 8,
+           "watersheds2D(): neighborhood must be 4 or 8.");
+    neighborhood = (neighborhood == 4)
+                        ? 0
+                        : 1;
+    return pythonWatershedsNew(image, neighborhood, seeds, method, srgType, max_cost, res);
+}
+
+template <class PixelType >
+python::tuple 
+pythonWatersheds3DNew(NumpyArray<3, Singleband<PixelType> > image,
+                      int neighborhood = 6,
+                      NumpyArray<3, Singleband<npy_uint32> > seeds = NumpyArray<3, Singleband<npy_uint32> >(),
+                      std::string method = "", 
+                      SRGType srgType = CompleteGrow, 
+                      PixelType max_cost = 0.0, 
+                      NumpyArray<3, Singleband<npy_uint32> > res = NumpyArray<3, Singleband<npy_uint32> >())
+{
+    vigra_precondition(neighborhood == 6 || neighborhood == 26,
+           "watersheds3D(): neighborhood must be 6 or 26.");
+    neighborhood = (neighborhood == 6)
+                        ? 0
+                        : 1;
+    return pythonWatershedsNew(image, neighborhood, seeds, method, srgType, max_cost, res);
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pywatersheds2DNew, pythonWatersheds2DNew)
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pywatersheds3DNew, pythonWatersheds3DNew)
+
+template < class PixelType >
+python::tuple 
+pythonWatersheds3D(NumpyArray<3, Singleband<PixelType> > image,
+                   int neighborhood = 6,
+                   NumpyArray<3, Singleband<npy_uint32> > seeds = NumpyArray<3, Singleband<npy_uint32> >(),
+                   std::string method = "RegionGrowing", 
+                   SRGType srgType = CompleteGrow, 
+                   PixelType max_cost = 0.0, 
+                   NumpyArray<3, Singleband<npy_uint32> > res = NumpyArray<3,Singleband<npy_uint32> >())
+{
+    vigra_precondition(neighborhood == 6 || neighborhood == 26,
+           "watersheds3D(): neighborhood must be 6 or 26.");
+
+    method = tolower(method);
+    
+    bool haveSeeds = seeds.hasData();
+    unsigned int maxRegionLabel;
+    
+    if(method == "")
+    {
+        if(IsSameType<PixelType, npy_uint8>::value)
+            method = "turbo";
+        else
+            method = "regiongrowing";
+    }
+    
+    if(method == "turbo")
+    {
+        vigra_precondition((Or<typename IsSameType<PixelType, npy_uint8>::type,
+                               typename IsSameType<PixelType, float>::type>::value),
+           "watersheds3D(): Turbo algorithm requires input dtype = uint8 or dtype = float.");
+        vigra_precondition(neighborhood == 6,
+           "watersheds3D(): Turbo algorithm requires neighborhood = 6.");
+        vigra_precondition(srgType == CompleteGrow,
+           "watersheds3D(): Turbo algorithm requires termination = CompleteGrow.");
+        vigra_precondition(max_cost == 0,
+           "watersheds3D(): Turbo algorithm doesn't support 'max_cost'.");
+    }
+    
+    if(method == "regiongrowing" || method == "turbo")
+    {
+        std::string description("watershed seeds");
+        
+        seeds.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+                "watersheds(): Seed array has wrong shape.");
+        
+        if(!haveSeeds)
+        {
+            PyAllowThreads _pythread;
+            maxRegionLabel = 0;
+            
+            MultiArray<3, npy_uint32> minima(seeds.shape());
+            
+            if (neighborhood ==6)
+            {
+                extendedLocalMinima3D(srcMultiArrayRange(image), destMultiArray(minima),
+                                      (npy_uint32)1, NeighborCode3DSix());
+                maxRegionLabel = labelVolumeWithBackground(srcMultiArrayRange(minima),
+                                          destMultiArray(seeds), NeighborCode3DSix(),
+                                          (npy_uint32)0);
+            }
+            else
+            {
+                extendedLocalMinima3D(srcMultiArrayRange(image), destMultiArray(minima),
+                                      (npy_uint32)1, NeighborCode3DTwentySix());
+                maxRegionLabel = labelVolumeWithBackground(srcMultiArrayRange(minima),
+                                          destMultiArray(seeds), NeighborCode3DTwentySix(),
+                                          (npy_uint32)0);
+            }
+        }
+        else
+        {
+            PyAllowThreads _pythread;
+            FindMinMax< npy_uint32 > minmax;
+            inspectMultiArray(srcMultiArrayRange(seeds), minmax);
+            maxRegionLabel = minmax.max;
+        }
+           
+        description = "watershed labeling, neighborhood=";
+        description += asString(neighborhood);
+        
+        res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+                "watersheds(): Output array has wrong shape.");
+
+        PyAllowThreads _pythread;
+        ArrayOfRegionStatistics< SeedRgDirectValueFunctor< PixelType > > stats(maxRegionLabel);
+        if(neighborhood == 6)
+        {
+            if(method == "turbo")
+            {
+                res = seeds;
+                
+                TWS<PixelType>::exec(image, res);
+            }
+            else
+            {
+                seededRegionGrowing3D(srcMultiArrayRange(image), srcMultiArray(seeds), 
+                                      destMultiArray(res), 
+                                      stats, srgType, NeighborCode3DSix(), max_cost);
+            }
+        }
+        else
+        {
+            seededRegionGrowing3D(srcMultiArrayRange(image), srcMultiArray(seeds), 
+                                  destMultiArray(res), 
+                                  stats, srgType, NeighborCode3DTwentySix(), max_cost);
+        }
+    }
+    else if(method == "unionfind")
+    {
+        vigra_precondition(!haveSeeds,
+           "watersheds(): UnionFind does not support seed images.");
+        vigra_precondition(srgType == CompleteGrow,
+           "watersheds(): UnionFind only supports 'CompleteGrow' mode.");
+           
+        std::string description("watershed labeling, neighborhood=");
+        description += asString(neighborhood);
+        
+        res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+                "watersheds(): Output array has wrong shape.");
+        
+        PyAllowThreads _pythread;
+        if(neighborhood == 6)
+        {
+            maxRegionLabel = watersheds3DSix(srcMultiArrayRange(image), destMultiArray(res));
+        }
+        else
+        {
+            maxRegionLabel = watersheds3DTwentySix(srcMultiArrayRange(image), destMultiArray(res));
+        }
+    }
+    else
+    {
+        vigra_precondition(false, "watersheds(): Unknown watershed method requested.");
+    }
+
+    return python::make_tuple(res, maxRegionLabel);
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pywatersheds3D, pythonWatersheds3D)
+
+template <unsigned int N, class PixelType >
+python::tuple 
+pythonSlic(NumpyArray<N, PixelType > array,
+           double intensityScaling,
+           unsigned int seedDistance,
+           unsigned int minSize = 0,            // choose minSize automatically 
+           unsigned int iterations = 10, 
+           NumpyArray<N, Singleband<npy_uint32> > res = NumpyArray<N, Singleband<npy_uint32> >())
+{
+    typedef typename detail::ResolveMultiband<PixelType>::type ValueType;
+    typedef typename NormTraits<ValueType>::NormType TmpType;
+    
+    std::string description("Slic superpixels");
+    
+    res.reshapeIfEmpty(array.taggedShape().setChannelDescription(description), 
+            "slicSuperpixels(): Output array has wrong shape.");
+    
+    npy_uint32 maxRegionLabel = 0;
+    {
+        PyAllowThreads _pythread;
+        
+        MultiArray<N, TmpType> gradMag(array.shape());
+        
+        // the original code uses the symmetric difference instead of a Gaussian gradient
+        gaussianGradientMagnitude(array, gradMag, 1.0);
+        // search radius of 1 is also used in the original code
+        generateSlicSeeds(gradMag, res, seedDistance, 1);
+        
+        maxRegionLabel = slicSuperpixels(array, res, intensityScaling, seedDistance,
+                                         SlicOptions().iterations(iterations)
+                                                      .minSize(minSize));
+    }
+
+    return python::make_tuple(res, maxRegionLabel);
+}
+
+template <class PixelType >
+python::tuple 
+pythonSlic2D(NumpyArray<2, PixelType > image,
+             double intensityScaling,
+             unsigned int seedDistance,
+             unsigned int minSize = 0,            // choose minSize automatically 
+             unsigned int iterations = 10, 
+             NumpyArray<2, Singleband<npy_uint32> > res = NumpyArray<2, Singleband<npy_uint32> >())
+{
+    return pythonSlic(image, intensityScaling, seedDistance, minSize, iterations, res);
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pySlic2D, pythonSlic2D)
+
+template <class PixelType >
+python::tuple 
+pythonSlic3D(NumpyArray<3, PixelType > image,
+             double intensityScaling,
+             unsigned int seedDistance,
+             unsigned int minSize = 0,            // choose minSize automatically 
+             unsigned int iterations = 10, 
+             NumpyArray<3, Singleband<npy_uint32> > res = NumpyArray<3, Singleband<npy_uint32> >())
+{
+    return pythonSlic(image, intensityScaling, seedDistance, minSize, iterations, res);
+}
+
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pySlic3D, pythonSlic3D)
+
+void defineSegmentation()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+
+    multidef("labelImage", pyLabelImage<npy_uint8, npy_uint32, float>(),
+        (arg("image"), 
+        arg("neighborhood") = 4,
+        arg("out")=python::object()),
+        "Find the connected components of a segmented image. Parameter 'neighborhood' specifies "
+        "the pixel neighborhood to be used and can be 4 (default) or 8.\n\n"
+        "For details see labelImage_ in the vigra C++ documentation.\n");
+
+    multidef("labelImageWithBackground", pyLabelImageWithBackground<npy_uint8, npy_uint32, float>(),
+        (arg("image"), 
+        arg("neighborhood") = 4,
+        arg("background_value") = 0,
+        arg("out")=python::object()),
+        "Find the connected components of a segmented image, excluding the "
+        "background from labeling, where the background is the set of all pixels with "
+        "the given 'background_value'. Parameter 'neighborhood' specifies "
+        "the pixel neighborhood to be used and can be 4 (default) or 8.\n\n"
+        "For details see labelImageWithBackground_ in the vigra C++ documentation.\n");
+
+    multidef("labelVolume", pyLabelVolume<npy_uint8, npy_uint32, float>(),
+        (arg("volume"), 
+        arg("neighborhood")=6,
+        arg("out")=python::object()),
+        "Find the connected components of a segmented volume. Parameter 'neighborhood' specifies "
+        "the pixel neighborhood to be used and can be 6 (default) or 26.\n"
+        "\n"
+        "For details see labelVolume_ in the vigra C++ documentation.\n");
+
+    multidef("labelVolumeWithBackground", pyLabelVolumeWithBackground<npy_uint8, npy_uint32, float>(),
+        (arg("volume"), 
+         arg("neighborhood")=6, 
+         arg("background_value")=0,
+         arg("out")=python::object()),
+        "Find the connected components of a segmented volume, excluding the "
+        "background from labeling, where the background is the set of all pixels with "
+        "the given 'background_value'. Parameter 'neighborhood' specifies "
+        "the pixel neighborhood to be used and can be 6 (default) or 26.\n"
+        "\n"
+        "For details see labelVolumeWithBackground_ in the vigra C++ documentation.\n");
+    
+    /******************************************************************************/
+    
+    def("localMinima",
+        registerConverters(&pythonLocalMinima2D<float>),
+        (arg("image"), 
+         arg("marker")=1.0, 
+         arg("neighborhood") = 8,
+         arg("out")=python::object()),
+        "Find local minima in an image and mark them with the given 'marker'. Parameter "
+        "'neighborhood' specifies the pixel neighborhood to be used and can be "
+        "4 or 8 (default).\n\n"
+        "For details see localMinima_ in the vigra C++ documentation.\n");
+
+    def("localMinima3D",
+            registerConverters(&pythonLocalMinima3D<float> ),
+            (arg("volume"), arg("marker") = 1.0, arg("neighborhood") = 6, arg(
+                    "out") = python::object()),
+            "Find local minima in a volume and mark them with the given 'marker'. Parameter "
+                "'neighborhood' specifies the pixel neighborhood to be used and can be "
+                "6 or 26 (default).\n\n"
+                "For details see localMinima3D_ in the vigra C++ documentation.\n");
+
+    // def("extendedLocalMinima",
+        // registerConverters(&pythonExtendedLocalMinima2D<float>),
+        // (arg("image"), 
+         // arg("marker")=1.0, 
+         // arg("neighborhood") = 8,
+         // arg("out")=python::object()),
+        // "Find local minima and minimal plateaus in an image and mark them with "
+        // "the given 'marker'. Parameter 'neighborhood' specifies the pixel "
+        // "neighborhood to be used and can be 4 or 8 (default).\n\n"
+        // "For details see extendedLocalMinima_ in the vigra C++ documentation.\n"
+        // );
+
+    multidef("extendedLocalMinima",
+        pyExtendedLocalMinima2D<npy_uint8, float>(),
+        (arg("image"), 
+         arg("marker")=1.0, 
+         arg("neighborhood") = 8,
+         arg("out")=python::object()),
+        "Find local minima and minimal plateaus in an image and mark them with "
+        "the given 'marker'. Parameter 'neighborhood' specifies the pixel "
+        "neighborhood to be used and can be 4 or 8 (default).\n\n"
+        "For details see extendedLocalMinima_ in the vigra C++ documentation.\n"
+        );
+
+    multidef("extendedLocalMinima3D",
+        pyExtendedLocalMinima3D<float, npy_uint8>(), 
+        (arg("volume"), arg("marker") = 1, arg("neighborhood") = 6, arg("out") = python::object()),
+        "Find local minima and minimal plateaus in a volume and mark them with "
+        "the given 'marker'. Parameter 'neighborhood' specifies the pixel "
+        "neighborhood to be used and can be 6(default) or 26 .\n\n"
+        "For details see extendedLocalMinima3D_ in the vigra C++ documentation.\n");
+
+    def("localMaxima",
+        registerConverters(&pythonLocalMaxima2D<float>),
+        (arg("image"), 
+         arg("marker")=1.0, 
+         arg("neighborhood") = 8,
+         arg("out")=python::object()),
+        "Find local maxima in an image and mark them with the given 'marker'. Parameter "
+        "'neighborhood' specifies the pixel neighborhood to be used and can be "
+        "4 or 8 (default).\n\n"
+        "For details see localMaxima_ in the vigra C++ documentation.\n");
+
+    def("localMaxima3D", registerConverters(&pythonLocalMaxima3D<float> ), 
+         (arg("volume"), arg("marker") = 1.0, arg("neighborhood") = 6, arg("out") = python::object()),
+            "Find local maxima and maximal plateaus in a volume and mark them with "
+            "the given 'marker'. Parameter 'neighborhood' specifies the pixel "
+            "neighborhood to be used and can be 6(default) or 26 .\n\n"
+            "For details see localMaxima3D_ in the vigra C++ documentation.\n");
+
+    def("extendedLocalMaxima",
+        registerConverters(&pythonExtendedLocalMaxima2D<float>),
+        (arg("image"), 
+         arg("marker")=1.0, 
+         arg("neighborhood") = 8,
+         arg("out")=python::object()),
+        "Find local maxima and maximal plateaus in an image and mark them with "
+        "the given 'marker'. Parameter 'neighborhood' specifies the pixel "
+        "neighborhood to be used and can be 4 or 8 (default).\n\n"
+        "For details see extendedLocalMaxima_ in the vigra C++ documentation.\n");
+
+    def("extendedLocalMaxima3D", 
+        registerConverters(&pythonExtendedLocalMaxima3D<float> ), 
+        (arg("volume"), arg("marker") = 1.0, arg("neighborhood") = 6, arg("out") = python::object()),
+        "Find local maxima and maximal plateaus in a volume and mark them with "
+        "the given 'marker'. Parameter 'neighborhood' specifies the pixel "
+        "neighborhood to be used and can be 6 (default) or 26 .\n\n"
+        "For details see extendedLocalMaxima3D_ in the vigra C++ documentation.\n");
+
+    /*************************************************************************/
+
+    enum_<vigra::SRGType>("SRGType")
+        .value("CompleteGrow", vigra::CompleteGrow)
+        .value("KeepContours", vigra::KeepContours)
+        .value("StopAtThreshold", vigra::StopAtThreshold)
+        ;
+
+    /*  FIXME: int64 is unsupported by the C++ code (hard-coded int) */
+    multidef("watersheds", pywatersheds2D< npy_uint8, float >(),
+      (arg("image"), 
+       arg("neighborhood") = 4, 
+       arg("seeds")=python::object(), 
+       arg("method")="",
+       arg("terminate")=CompleteGrow,
+       arg("max_cost")=0,
+       arg("out")=python::object()),
+        "Compute the watersheds of a 2D image.\n"
+        "\n"
+        "   watersheds(image, neighborhood=4, seeds = None, methods = 'RegionGrowing', \n"
+        "              terminate=CompleteGrow, threshold=0, out = None) -> (labelimage, max_ragion_label)\n"
+        "\n"
+        "Parameters:\n\n"
+        " image:\n"
+        "    the image or volume containing the boundary indicator values "
+        "    (high values = high edgeness, dtype=numpy.uint8 or numpy.float32).\n"
+        " neighborhood:\n"
+        "    the pixel neighborhood to be used. Feasible values depend on the "
+        "    dimension and method:\n\n"
+        "      2-dimensional data:\n"
+        "        4 (default) or 8.\n"
+        "      3-dimensional data:\n"
+        "        6 (default) or 26\n\n"
+        " seeds:\n"
+        "    a label image specifying region seeds, only supported by methods 'RegionGrowing' and 'Turbo'"
+        "    (with dtype=numpy.uint32).\n" 
+        " method:\n"
+        "    the algorithm to be used for watershed computation. Possible values:\n\n"
+        "      'Turbo':\n"
+        "        (default if input dtype == uint8) use fastSeededRegionGrowing_ or tws() respectively\n"
+        "      'RegionGrowing':\n"
+        "        (default if input dtype != uint8) use seededRegionGrowing_ or seededRegionGrowing3D_ respectively\n"
+        "      'UnionFind:\n"
+        "        use watershedsUnionFind_ or watersheds3D_ respectively\n\n"
+        " terminate:\n"
+        "    when to stop growing. Possible values:\n\n"
+        "      CompleteGrow:\n"
+        "        (default) grow until all pixels are assigned to a region\n"
+        "      KeepCountours:\n"
+        "        keep a 1-pixel wide contour between all regions, only supported "
+        "        by method 'RegionGrowing'\n"
+        "      StopAtThreshold:\n"
+        "        stop when the boundary indicator values exceed the threshold given by "
+        "        parameter 'max_cost', only supported by method 'RegionGrowing'\n"
+        "      KeepCountours | StopAtThreshold:\n"
+        "        keep 1-pixel wide contour and stop at given 'max_cost', only "
+        "        supported by method 'RegionGrowing'\n\n"
+        " max_cost:\n"
+        "    terminate growing when boundary indicator exceeds this value (ignored when "
+        "    'terminate' is not StopAtThreshold or method is not 'RegionGrowing')\n" 
+        " out:\n"
+        "    the label image (with dtype=numpy.uint32) to be filled by the algorithm. "
+        "    It will be allocated by the watershed function if not provided)\n\n"
+         "The function returns a Python tuple (labelImage, maxRegionLabel)\n\n"
+         );
+
+    multidef("watersheds", pywatersheds3D< npy_uint8, float >(),
+      (arg("volume"), 
+       arg("neighborhood") = 6, 
+       arg("seeds")=python::object(), 
+       arg("method")="",
+       arg("terminate")=CompleteGrow,
+       arg("max_cost")=0,
+       arg("out")=python::object()),
+       "Likewise, compute watersheds of a volume.\n");
+
+    multidef("watershedsNew", pywatersheds2DNew< npy_uint8, float >(),
+      (arg("image"), 
+       arg("neighborhood") = 4, 
+       arg("seeds")=python::object(), 
+       arg("method")="",
+       arg("terminate")=CompleteGrow,
+       arg("max_cost")=0,
+       arg("out")=python::object()),
+       "graph-based watershed");
+
+    multidef("watershedsNew", pywatersheds3DNew< npy_uint8, float >(),
+      (arg("image"), 
+       arg("neighborhood") = 6, 
+       arg("seeds")=python::object(), 
+       arg("method")="",
+       arg("terminate")=CompleteGrow,
+       arg("max_cost")=0,
+       arg("out")=python::object()),
+       "graph-based watershed");
+
+    multidef("slicSuperpixels", pySlic2D< TinyVector<float, 3>, Singleband<float> >(),
+      (arg("image"), 
+       arg("intensityScaling"), 
+       arg("seedDistance"), 
+       arg("minSize")=0,
+       arg("iterations")=10,
+       arg("out")=python::object()),
+        "Compute Slic superpixels for a 2D image.\n\n"
+
+        "Parameters:\n\n"
+        " image:\n"
+        "    The 2D-image on which the superpixels will be calculated. Accepts single- and threeband images. \n\n"
+        " intensityScaling:\n"
+        "    Scale (divide) color/intensity difference by this parameter before comparing to spatial distance. \n\n"
+        " seedDistance:\n"
+        "    specify the radius of the window around each seed in which the algorithm looks for potential members of the corresponding superpixel"
+        " thus limiting the superpixel size. The grid spacing for seed placement is determined by this parameter.\n\n"
+        " minSize:\n"
+        "    Minimum size for superpixels. By default the algorithm merges all regions smaller than a quarter of the average superpixel size.\n\n"
+        " iterations:\n"
+        "    Specify number of iterations. The default is 10."
+        " out:\n"
+        "    The label image (with dtype=numpy.uint32) to be filled by the algorithm. "
+        "    It will be allocated by the slicSuperpixels function if not provided)\n\n"
+        "The function returns a Python tuple (labelImage, maxRegionLabel)\n\n");
+
+    multidef("slicSuperpixels", pySlic3D< TinyVector<float, 3>, Singleband<float> >(),
+      (arg("image"), 
+       arg("intensityScaling"), 
+       arg("seedDistance"), 
+       arg("minSize")=0,
+       arg("iterations")=10,
+       arg("out")=python::object()),
+       "Likewise compute Slic superpixels for a 3D volume, either single- or threeband.\n");
+}
+
+void defineEdgedetection();
+void defineInterestpoints();
+void defineAccumulators();
+
+} // namespace vigra
+
+using namespace vigra;
+using namespace boost::python;
+
+BOOST_PYTHON_MODULE_INIT(analysis)
+{
+    import_vigranumpy();
+    defineSegmentation();
+    defineEdgedetection();
+    defineInterestpoints();
+    defineAccumulators();
+}
diff --git a/vigranumpy/src/core/tensors.cxx b/vigranumpy/src/core/tensors.cxx
new file mode 100644
index 0000000..74fdd56
--- /dev/null
+++ b/vigranumpy/src/core/tensors.cxx
@@ -0,0 +1,772 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyfilters_PyArray_API
+#define NO_IMPORT_ARRAY
+
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/multi_convolution.hxx>
+#include <vigra/boundarytensor.hxx>
+#include <vigra/orientedtensorfilters.hxx>
+#include <vigra/tensorutilities.hxx>
+#include <vigra/multi_tensorutilities.hxx>
+#include "vigranumpyscaleparam.hxx"
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+template < class VoxelType, unsigned int ndim >
+NumpyAnyArray 
+pythonGaussianGradientND(NumpyArray<ndim, Singleband<VoxelType> > array,
+                         python::object sigma,
+                         NumpyArray<ndim, TinyVector<VoxelType, (int)ndim> > res = NumpyArray<ndim, TinyVector<VoxelType, (int)ndim> >(),
+                         python::object sigma_d = python::object(0.0), 
+                         python::object step_size = python::object(1.0),
+                         double window_size = 0.0, 
+                         python::object roi = python::object())
+{
+    pythonScaleParam<ndim> params(sigma, sigma_d, step_size, "gaussianGradient");
+    params.permuteLikewise(array);
+    std::string description("Gaussian gradient, scale=");
+    description += asString(sigma);
+    
+    ConvolutionOptions<ndim> opt(params().filterWindowSize(window_size));
+    
+    if(roi != python::object())
+    {
+        typedef typename MultiArrayShape<ndim>::type Shape;
+        Shape start = array.permuteLikewise(python::extract<Shape>(roi[0])());
+        Shape stop  = array.permuteLikewise(python::extract<Shape>(roi[1])());
+        opt.subarray(start, stop);
+        res.reshapeIfEmpty(array.taggedShape().resize(stop-start).setChannelDescription(description), 
+                       "gaussianGradient(): Output array has wrong shape.");
+    }
+    else
+    {
+        res.reshapeIfEmpty(array.taggedShape().setChannelDescription(description), 
+                       "gaussianGradient(): Output array has wrong shape.");
+    }
+
+    {
+        PyAllowThreads _pythread;
+        gaussianGradientMultiArray(srcMultiArrayRange(array), destMultiArray(res), opt);
+    }
+    return res;
+}
+
+
+template < class VoxelType, unsigned int ndim >
+NumpyAnyArray 
+pythonGaussianGradientMagnitudeND(NumpyArray<ndim, Multiband<VoxelType> > array,
+                                  const ConvolutionOptions<ndim-1> & opt,
+                                  NumpyArray<ndim-1, Singleband<VoxelType> > res = NumpyArray<ndim-1, Singleband<VoxelType> >())
+{
+    using namespace vigra::functor;
+    static const int sdim = ndim - 1;
+    
+    std::string description("Gaussian gradient magnitude");
+    typedef typename MultiArrayShape<sdim>::type Shape;
+    Shape tmpShape(array.shape().begin());
+    if(opt.to_point != Shape())
+        tmpShape = opt.to_point-opt.from_point;
+    
+    res.reshapeIfEmpty(array.taggedShape().resize(tmpShape).setChannelDescription(description), 
+          "gaussianGradientMagnitude(): Output array has wrong shape.");
+    res.init(VoxelType());
+    
+    {
+        PyAllowThreads _pythread;
+        MultiArray<sdim, TinyVector<VoxelType, sdim> > grad(tmpShape);
+        
+        for(int k=0; k<array.shape(sdim); ++k)
+        {
+            MultiArrayView<sdim, VoxelType, StridedArrayTag> barray = array.bindOuter(k);
+        
+            gaussianGradientMultiArray(srcMultiArrayRange(barray), destMultiArray(grad), opt);
+            combineTwoMultiArrays(srcMultiArrayRange(grad), srcMultiArray(res), destMultiArray(res), 
+                                  squaredNorm(Arg1())+Arg2());
+        }
+        transformMultiArray(srcMultiArrayRange(res), destMultiArray(res), sqrt(Arg1()));
+    }
+    
+    return res;
+}
+
+
+template < class PixelType>
+NumpyAnyArray 
+pythonRieszTransformOfLOG2D(NumpyArray<2, Singleband<PixelType> > image,
+                            double scale, 
+                            unsigned int xorder, unsigned int yorder,
+                            NumpyArray<2, Singleband<PixelType> > res = NumpyArray<2, Singleband<PixelType> >())
+{
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription("Riesz transform"), 
+              "rieszTransformOfLOG2D(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        rieszTransformOfLOG(srcImageRange(image), destImage(res), scale, xorder, yorder);
+    }
+    
+    return res;
+}
+
+template < class VoxelType, unsigned int ndim >
+NumpyAnyArray 
+pythonGaussianGradientMagnitudeND(NumpyArray<ndim, Multiband<VoxelType> > volume,
+                                  const ConvolutionOptions<ndim-1> & opt,
+                                  NumpyArray<ndim, Multiband<VoxelType> > res = NumpyArray<ndim, Multiband<VoxelType> >())
+{
+    using namespace vigra::functor;
+    static const int sdim = ndim - 1;
+    
+    std::string description("channel-wise Gaussian gradient magnitude");
+    
+    typedef typename MultiArrayShape<sdim>::type Shape;
+    Shape tmpShape(volume.shape().begin());
+    if(opt.to_point != Shape())
+        tmpShape = opt.to_point-opt.from_point;
+    
+    res.reshapeIfEmpty(volume.taggedShape().resize(tmpShape).setChannelDescription(description), 
+             "gaussianGradientMagnitude(): Output array has wrong shape.");
+    
+    {
+        PyAllowThreads _pythread;
+        MultiArray<sdim, TinyVector<VoxelType, sdim> > grad(tmpShape);
+        
+        for(int k=0; k<volume.shape(sdim); ++k)
+        {
+            MultiArrayView<sdim, VoxelType, StridedArrayTag> bvolume = volume.bindOuter(k);
+            MultiArrayView<sdim, VoxelType, StridedArrayTag> bres = res.bindOuter(k);
+        
+            gaussianGradientMultiArray(srcMultiArrayRange(bvolume), destMultiArray(grad), opt);
+            transformMultiArray(srcMultiArrayRange(grad), destMultiArray(bres), norm(Arg1()));
+        }
+    }
+    
+    return res;
+}
+
+template < class VoxelType, unsigned int ndim >
+NumpyAnyArray 
+pythonGaussianGradientMagnitude(NumpyArray<ndim, Multiband<VoxelType> > volume,
+                                python::object sigma, bool accumulate,
+                                NumpyAnyArray res,
+                                python::object sigma_d, 
+                                python::object step_size,
+                                double window_size = 0.0, 
+                                python::object roi = python::object())
+{
+    pythonScaleParam<ndim - 1> params(sigma, sigma_d, step_size, "gaussianGradientMagnitude");
+    params.permuteLikewise(volume);
+    ConvolutionOptions<ndim-1> opt(params().filterWindowSize(window_size));
+    
+    typedef typename MultiArrayShape<ndim - 1>::type Shape;
+    if(roi != python::object())
+    {
+        opt.subarray(volume.permuteLikewise(python::extract<Shape>(roi[0])()), 
+                     volume.permuteLikewise(python::extract<Shape>(roi[1])()));
+    }
+    else
+    {
+        opt.subarray(Shape(), Shape(volume.shape().begin()));
+    }
+    
+    return accumulate
+              ? pythonGaussianGradientMagnitudeND(volume, opt, NumpyArray<ndim-1, Singleband<VoxelType> >(res))
+              : pythonGaussianGradientMagnitudeND(volume, opt, NumpyArray<ndim, Multiband<VoxelType> >(res));
+}
+
+template < class VoxelType, unsigned int ndim >
+NumpyAnyArray 
+pythonSymmetricGradientND(NumpyArray<ndim, Singleband<VoxelType> > volume,
+                          NumpyArray<ndim, TinyVector<VoxelType, (int)ndim> > res=python::object(),
+                          python::object step_size = python::object(1.0), 
+                          python::object roi = python::object())
+{
+    pythonScaleParam<ndim> params(python::object(0.0), python::object(0.0),
+                                 step_size, "symmetricGradient");
+    params.permuteLikewise(volume);
+    ConvolutionOptions<ndim> opt(params());
+    
+    if(roi != python::object())
+    {
+        typedef typename MultiArrayShape<ndim>::type Shape;
+        Shape start = volume.permuteLikewise(python::extract<Shape>(roi[0])());
+        Shape stop  = volume.permuteLikewise(python::extract<Shape>(roi[1])());
+        opt.subarray(start, stop);
+        res.reshapeIfEmpty(volume.taggedShape().resize(stop-start).setChannelDescription("symmetric gradient"), 
+                 "symmetricGradient(): Output array has wrong shape.");
+    }
+    else
+    {
+        res.reshapeIfEmpty(volume.taggedShape().setChannelDescription("symmetric gradient"), 
+                 "symmetricGradient(): Output array has wrong shape.");
+    }
+    
+    {
+        PyAllowThreads _pythread;
+        symmetricGradientMultiArray(srcMultiArrayRange(volume), destMultiArray(res), opt);
+    }
+    return res;
+}
+
+template < class VoxelType, unsigned int N >
+NumpyAnyArray 
+pythonHessianOfGaussianND(NumpyArray<N, Singleband<VoxelType> > array,
+                          python::object sigma,
+                          NumpyArray<N, TinyVector<VoxelType, int(N*(N+1)/2)> > res= NumpyArray<N, TinyVector<VoxelType, int(N*(N+1)/2)> >(),
+                          python::object sigma_d = python::object(0.0), 
+                          python::object step_size = python::object(1.0),
+                          double window_size = 0.0, 
+                          python::object roi = python::object())
+{
+    std::string description("Hessian of Gaussian (flattened upper triangular matrix), scale=");
+    description += asString(sigma);
+    
+    pythonScaleParam<N> params(sigma, sigma_d, step_size, "hessianOfGaussian");
+    params.permuteLikewise(array);
+    ConvolutionOptions<N> opt(params().filterWindowSize(window_size));
+    
+    if(roi != python::object())
+    {
+        typedef typename MultiArrayShape<N>::type Shape;
+        Shape start = array.permuteLikewise(python::extract<Shape>(roi[0])());
+        Shape stop  = array.permuteLikewise(python::extract<Shape>(roi[1])());
+        opt.subarray(start, stop);
+        res.reshapeIfEmpty(array.taggedShape().resize(stop-start).setChannelDescription(description), 
+               "hessianOfGaussian(): Output array has wrong shape.");
+    }
+    else
+    {
+        res.reshapeIfEmpty(array.taggedShape().setChannelDescription(description), 
+               "hessianOfGaussian(): Output array has wrong shape.");
+    }
+    
+    {
+        PyAllowThreads _pythread;
+        hessianOfGaussianMultiArray(srcMultiArrayRange(array), destMultiArray(res), opt);
+    }
+    return res;
+}
+
+#if 0 // FIXME: this is probably no longer needed thanks to axistags
+template < class VoxelType>
+NumpyAnyArray 
+pythonHessianOfGaussian3D(NumpyArray<3, Singleband<VoxelType> > volume,
+                          python::object sigma,
+                          NumpyArray<3, TinyVector<VoxelType, 6> > res=NumpyArray<3, TinyVector<VoxelType, 6> >(),
+                          python::object sigma_d = python::object(0.0), python::object step_size = python::object(1.0))
+{
+    pythonScaleParam<3> params(sigma, sigma_d, step_size, "hessianOfGaussian");
+    params.permuteLikewise(volume);
+    std::string description("Hessian of Gaussian (flattened upper triangular matrix), scale=");
+    description += asString(sigma);
+    
+    res.reshapeIfEmpty(volume.taggedShape().setChannelDescription(description), 
+          "hessianOfGaussian(): Output array has wrong shape.");
+    
+    {
+        PyAllowThreads _pythread;
+        hessianOfGaussianMultiArray(srcMultiArrayRange(volume), destMultiArray(res), params());
+    }
+    
+    return res;
+}
+
+template < class PixelType>
+NumpyAnyArray 
+pythonHessianOfGaussian2D(NumpyArray<2, Singleband<PixelType> > image,
+                          python::object sigma,
+                          NumpyArray<2, TinyVector<PixelType, 3> > res=NumpyArray<2, TinyVector<PixelType, 3> >(),
+                          python::object sigma_d = python::object(0.0), python::object step_size = python::object(1.0))
+{
+    pythonScaleParam<2> params(sigma, sigma_d, step_size, "hessianOfGaussian");
+    params.permuteLikewise(image);
+    std::string description("Hessian of Gaussian (flattened upper triangular matrix), scale=");
+    description += asString(sigma);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+             "hessianOfGaussian(): Output array has wrong shape.");
+    
+    {
+        PyAllowThreads _pythread;
+        hessianOfGaussianMultiArray(srcMultiArrayRange(image), destMultiArray(res), params());
+    }
+    
+    return res;
+}
+#endif
+
+template <class PixelType, unsigned int N>
+NumpyAnyArray 
+pythonStructureTensor(NumpyArray<N, Multiband<PixelType> > array, 
+                      python::object innerScale, python::object outerScale,
+                      NumpyArray<N-1, TinyVector<PixelType, int(N*(N-1)/2)> > res=NumpyArray<N-1, TinyVector<PixelType, int(N*(N-1)/2)> >(),
+                      python::object sigma_d = python::object(0.0), 
+                      python::object step_size = python::object(1.0),
+                      double window_size = 0.0, 
+                      python::object roi = python::object())
+{
+    using namespace vigra::functor;
+    static const int sdim = N - 1;
+    
+    std::string description("structure tensor (flattened upper triangular matrix), inner scale=");
+    description += asString(innerScale) + ", outer scale=" + asString(outerScale);
+    
+    pythonScaleParam<N-1> params(innerScale, sigma_d, step_size, outerScale, "structureTensor");
+    params.permuteLikewise(array);
+    ConvolutionOptions<N-1> opt(params().filterWindowSize(window_size));
+    
+    if(roi != python::object())
+    {
+        typedef typename MultiArrayShape<N-1>::type Shape;
+        Shape start = array.permuteLikewise(python::extract<Shape>(roi[0])());
+        Shape stop  = array.permuteLikewise(python::extract<Shape>(roi[1])());
+        opt.subarray(start, stop);
+        res.reshapeIfEmpty(array.taggedShape().resize(stop-start).setChannelDescription(description), 
+                     "structureTensor(): Output array has wrong shape.");
+    }
+    else
+    {
+        res.reshapeIfEmpty(array.taggedShape().setChannelDescription(description), 
+                     "structureTensor(): Output array has wrong shape.");
+    }
+    
+    {
+        PyAllowThreads _pythread;
+
+        MultiArrayView<sdim, PixelType, StridedArrayTag> band = array.bindOuter(0); 
+        structureTensorMultiArray(srcMultiArrayRange(band), destMultiArray(res), opt);
+        
+        if(array.shape(sdim) > 1)
+        {
+            MultiArray<sdim, TinyVector<PixelType, int(N*(N-1)/2)> > st(res.shape());
+            
+            for(int b=1; b<array.shape(sdim); ++b)
+            {
+                MultiArrayView<sdim, PixelType, StridedArrayTag> band = array.bindOuter(b);
+                structureTensorMultiArray(srcMultiArrayRange(band), destMultiArray(st), opt);
+                combineTwoMultiArrays(srcMultiArrayRange(res), srcMultiArray(st), 
+                                      destMultiArray(res), Arg1() + Arg2());
+            }
+        }
+    }
+    
+    return res;
+}
+
+template < class SrcPixelType, typename DestPixelType >
+NumpyAnyArray 
+pythonBoundaryTensor2D(NumpyArray<2, Singleband<SrcPixelType> > image,
+                       double scale,
+                       NumpyArray<2, TinyVector<DestPixelType, 3> > res = NumpyArray<2, TinyVector<DestPixelType, 3> >())
+{
+    std::string description("boundary tensor (flattened upper triangular matrix), scale=");
+    description += asString(scale);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+           "boundaryTensor2D(): Output array has wrong shape.");    
+
+    {
+        PyAllowThreads _pythread;
+        boundaryTensor(srcImageRange(image), destImage(res), scale);
+    }
+    
+    return res;
+}
+
+
+template < class SrcPixelType, typename DestPixelType  >
+NumpyAnyArray 
+pythonTensorEigenRepresentation2D(NumpyArray<2, TinyVector<SrcPixelType, 3> > image,
+                                  NumpyArray<2, TinyVector<DestPixelType, 3> > res = python::object())
+{
+    std::string description("tensor eigen representation (ev1, ev2, angle)");
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+                    "tensorEigenRepresentation2D(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        tensorEigenRepresentation(srcImageRange(image), destImage(res));
+    }
+    
+    return res;
+}
+
+// FIXME: generalize to handle non-interleaved representations
+template < class PixelType, unsigned int N >
+NumpyAnyArray 
+pythonVectorToTensor(NumpyArray<N, TinyVector<PixelType, int(N)> > array,
+                     NumpyArray<N, TinyVector<PixelType, int(N*(N+1)/2)> > res = python::object())
+{
+    std::string description("outer product tensor (flattened upper triangular matrix)");
+
+    res.reshapeIfEmpty(array.taggedShape().setChannelDescription(description), 
+            "vectorToTensor(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        vectorToTensorMultiArray(srcMultiArrayRange(array), destMultiArray(res));
+    }
+    
+    return res;
+}
+
+// FIXME: generalize to handle non-interleaved representations
+template < class PixelType, unsigned int N >
+NumpyAnyArray 
+pythonTensorTrace(NumpyArray<N, TinyVector<PixelType, int(N*(N+1)/2)> > array,
+                  NumpyArray<N, Singleband<PixelType> > res = python::object())
+{
+    std::string description("tensor trace");
+
+    res.reshapeIfEmpty(array.taggedShape().setChannelDescription(description), 
+           "tensorTrace(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        tensorTraceMultiArray(srcMultiArrayRange(array), destMultiArray(res));
+    }
+    
+    return res;
+}
+
+// FIXME: generalize to handle non-interleaved representations
+template < class PixelType, unsigned int N >
+NumpyAnyArray 
+pythonTensorDeterminant(NumpyArray<N, TinyVector<PixelType, int(N*(N+1)/2)> > array,
+                        NumpyArray<N, Singleband<PixelType> > res = python::object())
+{
+    std::string description("tensor determinant");
+
+    res.reshapeIfEmpty(array.taggedShape().setChannelDescription(description), 
+                "tensorDeterminant(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        tensorDeterminantMultiArray(srcMultiArrayRange(array), destMultiArray(res));
+    }
+    
+    return res;
+}
+
+// FIXME: generalize to handle non-interleaved representations
+template < class PixelType, unsigned int N >
+NumpyAnyArray 
+pythonTensorEigenvalues(NumpyArray<N, TinyVector<PixelType, int(N*(N+1)/2)> > array,
+                        NumpyArray<N, TinyVector<PixelType, int(N)> > res = python::object())
+{
+    std::string description("tensor eigenvalues");
+
+    res.reshapeIfEmpty(array.taggedShape().setChannelDescription(description), 
+                 "tensorEigenvalues(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        tensorEigenvaluesMultiArray(srcMultiArrayRange(array), destMultiArray(res));
+    }
+    
+    return res;
+}
+
+template < class SrcPixelType, typename DestPixelType >
+NumpyAnyArray 
+pythonHourGlassFilter2D(NumpyArray<2, TinyVector<SrcPixelType, 3> > image,
+                        double sigma, 
+                        double rho,
+                        NumpyArray<2, TinyVector<DestPixelType, 3> > res = python::object())
+{
+    std::string description("hourglass tensor (flattened upper triangular matrix), scale=");
+    description += asString(sigma) + ", rho=" + asString(rho);
+    
+    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description), 
+            "hourGlassFilter2D(): Output array has wrong shape.");    
+    
+    {
+        PyAllowThreads _pythread;
+        hourGlassFilter(srcImageRange(image), destImage(res), sigma, rho);
+    }
+    
+    return res;
+}
+
+void defineTensor()
+{
+    using namespace python;
+    
+    docstring_options doc_options(true, true, false);
+    
+    def("gaussianGradient",
+        registerConverters(&pythonGaussianGradientND<float,2>),
+        (arg("image"), arg("sigma"), arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Calculate the gradient vector by means of a 1st derivative of "
+        "Gaussian filter at the given scale for a 2D scalar image.\n\n"
+        "If 'sigma' is a single value, an isotropic filter at this scale is "
+        "applied (i.e., each dimension is filtered in the same way). "
+        "If 'sigma' is a tuple or list of values, the amount of smoothing "
+        "will be different for each spatial dimension.\n"
+        "The optional 'sigma_d' (single, tuple, or list) denotes the resolution standard deviation "
+        "per axis, the optional 'step_size' (single, tuple, or list) the distance between two adjacent "
+        "pixels for each dimension. "
+        "The length of the tuples or lists must be equal to the "
+        "number of spatial dimensions.\n\n"        
+        "'window_size' and 'roi' have the same meaning as in :func:`gaussianSmoothing`.\n\n"
+        "For details see gaussianGradientMultiArray_ and ConvolutionOptions_ in the vigra C++ documentation.\n");
+
+    def("gaussianGradient",
+        registerConverters(&pythonGaussianGradientND<float,3>),
+        (arg("volume"), arg("sigma"), arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Likewise for a 3D scalar volume.\n");
+
+    def("rieszTransformOfLOG2D",
+        registerConverters(&pythonRieszTransformOfLOG2D<float>),
+        (arg("image"), arg("scale"), arg("xorder"), arg("yorder"),arg("out")=python::object()),
+        "Calculate Riesz transforms of the Laplacian of Gaussian.\n\n"
+        "For details see rieszTransformOfLOG_ in the vigra C++ documentation.\n");
+
+    def("gaussianGradientMagnitude",
+        registerConverters(&pythonGaussianGradientMagnitude<float,3>),
+        (arg("image"), arg("sigma"), arg("accumulate")=true, arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Calculate the gradient magnitude by means of a 1st derivative of "
+        "Gaussian filter at the given scale for a 2D scalar or multiband image.\n"
+        "If 'accumulate' is True (the default), the gradients are accumulated (in the "
+        "L2-norm sense) over all  channels of a multi-channel array. Otherwise, "
+        "a separate gradient magnitude is computed for each channel.\n\n"
+        "If 'sigma' is a single value, an isotropic filter at this scale is "
+        "applied (i.e., each dimension is filtered in the same way). "
+        "If 'sigma' is a tuple or list of values, the amount of smoothing "
+        "will be different for each spatial dimension.\n"
+        "The optional 'sigma_d' (single, tuple, or list) denotes the resolution standard deviation "
+        "per axis, the optional 'step_size' (single, tuple, or list) the distance between two adjacent "
+        "pixels for each dimension. "
+        "The length of the tuples or lists must be equal to the "
+        "number of spatial dimensions.\n\n"        
+        "'window_size' and 'roi' have the same meaning as in :func:`gaussianSmoothing`.\n\n"
+        "For details see gaussianGradientMultiArray_ and ConvolutionOptions_ in the vigra C++ documentation.\n");
+
+    def("gaussianGradientMagnitude",
+        registerConverters(&pythonGaussianGradientMagnitude<float,4>),
+        (arg("volume"), arg("sigma"), arg("accumulate")=true, arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Likewise for a 3D scalar or multiband volume.\n");
+
+    def("symmetricGradient",
+        registerConverters(&pythonSymmetricGradientND<float,2>),
+        (arg("image"), arg("out")=python::object(), arg("step_size")=1.0, arg("roi")=python::object()),
+        "Calculate gradient of a scalar 2D image using symmetric difference filters."
+        "\n"
+        "The optional tuple or list 'step_size' denotes the distance between two "
+        "adjacent pixels for each dimension; its length must be equal to the "
+        "number of spatial dimensions.\n\n"        
+        "'roi' has the same meaning as in :func:`gaussianSmoothing`.\n\n"
+        "For details see symmetricGradientMultiArray_ and ConvolutionOptions_ in the vigra C++ documentation.\n");
+
+    def("symmetricGradient",
+        registerConverters(&pythonSymmetricGradientND<float,3>), 
+        (arg("volume"), arg("out")=python::object(), arg("step_size")=1.0, arg("roi")=python::object()),
+        "Likewise for a 3D scalar volume.\n");
+    
+    // FIXME: is this function still needed?
+    def("hessianOfGaussian2D",
+        registerConverters(&pythonHessianOfGaussianND<float, 2>),
+        (arg("image"), arg("sigma"), arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Calculate the Hessian matrix by means of a derivative of "
+        "Gaussian filters at the given scale for a 2D scalar image.\n"
+        "\n"
+        "If 'sigma' is a single value, an isotropic filter at this scale is "
+        "applied (i.e., each dimension is filtered in the same way). "
+        "If 'sigma' is a tuple or list of values, the amount of smoothing "
+        "will be different for each spatial dimension.\n"
+        "The optional 'sigma_d' (single, tuple, or list) denotes the resolution standard deviation "
+        "per axis, the optional 'step_size' (single, tuple, or list) the distance between two adjacent "
+        "pixels for each dimension. "
+        "The length of the tuples or lists must be equal to the "
+        "number of spatial dimensions.\n\n"        
+        "'window_size' and 'roi' have the same meaning as in :func:`gaussianSmoothing`.\n\n"
+        "For details see hessianOfGaussianMultiArray_ and ConvolutionOptions_ in the vigra C++ documentation.\n");
+
+    // FIXME: is this function still needed?
+    def("hessianOfGaussian3D",
+        registerConverters(&pythonHessianOfGaussianND<float, 3>),
+        (arg("volume"), arg("sigma"), arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Calculate the Hessian matrix by means of a derivative of "
+        "Gaussian filters at the given scale for a 3D scalar image.\n"
+        "\n"
+        "For details see hessianOfGaussianMultiArray_ in the vigra C++ documentation.\n");
+
+    def("hessianOfGaussian",
+        registerConverters(&pythonHessianOfGaussianND<float,2>),
+        (arg("image"), arg("sigma"), arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Calculate the Hessian matrix by means of a derivative of "
+        "Gaussian filters at the given scale for a 2D scalar image.\n"
+        "\n"
+        "If 'sigma' is a single value, an isotropic filter at this scale is "
+        "applied (i.e., each dimension is filtered in the same way). "
+        "If 'sigma' is a tuple or list of values, the amount of smoothing "
+        "will be different for each spatial dimension.\n"
+        "The optional 'sigma_d' (single, tuple, or list) denotes the resolution standard deviation "
+        "per axis, the optional 'step_size' (single, tuple, or list) the distance between two adjacent "
+        "pixels for each dimension. "
+        "The length of the tuples or lists must be equal to the "
+        "number of spatial dimensions.\n\n"        
+        "'window_size' and 'roi' have the same meaning as in :func:`gaussianSmoothing`.\n\n"
+        "For details see hessianOfGaussianMultiArray_ in the vigra C++ documentation.\n");
+
+    def("hessianOfGaussian",
+        registerConverters(&pythonHessianOfGaussianND<float,3>),
+        (arg("volume"), arg("sigma"), arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Likewise for a 3D scalar or multiband volume.\n");
+
+    def("structureTensor",
+        registerConverters(&pythonStructureTensor<float,3>),
+        (arg("image"), arg("innerScale"), arg("outerScale"), arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Calculate the structure tensor of an image by means of Gaussian "
+        "(derivative) filters at the given scales. If the input has multiple channels, "
+        "the structure tensors of each channel are added to get the result.\n\n"
+        "If 'innerScale' and 'outerScale' are single values, "
+        "isotropic filters at these scales are "
+        "applied (i.e., each dimension is filtered in the same way). "
+        "If 'innerScale' and / or 'outerScale' are are tuples or lists of "
+        "values, the amount of smoothing "
+        "will be different for each spatial dimension.\n"
+        "The optional 'sigma_d' (single, tuple, or list) denotes the resolution standard deviation "
+        "per axis, the optional 'step_size' (single, tuple, or list) the distance between two adjacent "
+        "pixels for each dimension. "
+        "The length of the tuples or lists must be equal to the "
+        "number of spatial dimensions.\n\n"        
+        "'window_size' and 'roi' have the same meaning as in :func:`gaussianSmoothing`.\n\n"
+        "For details see structureTensorMultiArray_ and ConvolutionOptions_ in the vigra C++ documentation.\n");
+
+    def("structureTensor",
+        registerConverters(&pythonStructureTensor<float,4>),
+        (arg("volume"), arg("innerScale"), arg("outerScale"), arg("out")=python::object(), 
+         arg("sigma_d")=0.0, arg("step_size")=1.0, arg("window_size")=0.0, arg("roi")=python::object()),
+        "Likewise for a 3D scalar or multiband volume.\n");
+
+    def("boundaryTensor2D",
+        registerConverters(&pythonBoundaryTensor2D<float, float>),
+        (arg("image"), arg("scale"),arg("out")=python::object()),
+        "Calculate the boundary tensor for a scalar valued 2D image."
+        "For details see boundaryTensor_ in the vigra C++ documentation.\n");
+        
+    /** FIXME: Export of Kernel2D before
+    def("gradientEnergyTensor2D",
+        registerConverters(&gradientEnergyTensor2D<float,float>),
+        (arg("image"), arg("derivKernel"), arg("smoothKernel"),arg("out")=python::object()));
+        
+    */
+
+    def("tensorEigenRepresentation2D",
+        registerConverters(&pythonTensorEigenRepresentation2D<float,float>),
+        (arg("image"),arg("out")=python::object()),
+        "Calculate eigen representation of a symmetric 2x2 tensor.\n\n"
+        "For details see tensorEigenRepresentation_ in the vigra C++ documentation.\n"
+        );
+
+    def("vectorToTensor",
+        registerConverters(&pythonVectorToTensor<float,2>),
+        (arg("image"),arg("out")=python::object()),
+        "Turn a 2D vector valued image (e.g. the gradient image) into "
+        "a tensor image by computing the outer product in every pixel.\n\n"
+        "For details see vectorToTensorMultiArray_ in the vigra C++ documentation.\n");
+
+    def("vectorToTensor",
+        registerConverters(&pythonVectorToTensor<float,3>),
+        (arg("volume"),arg("out")=python::object()),
+        "Likewise for a 3D vector-valued volume.\n");
+
+    def("tensorTrace",
+        registerConverters(&pythonTensorTrace<float,2>),
+        (arg("image"),arg("out")=python::object()),
+        "Calculate the trace of a 2x2 tensor image.\n\n"
+        "For details see tensorTraceMultiArray_ in the vigra C++ documentation.\n");
+
+    def("tensorTrace",
+        registerConverters(&pythonTensorTrace<float,3>),
+        (arg("volume"),arg("out")=python::object()),
+        "Likewise for a 3x3 tensor volume.\n");
+
+    def("tensorDeterminant",
+        registerConverters(&pythonTensorDeterminant<float,2>),
+        (arg("image"),arg("out")=python::object()),
+        "Calculate the determinant of a 2x2 tensor image.\n\n"
+        "For details see tensorDeterminantMultiArray_ in the vigra C++ documentation.\n");
+
+    def("tensorDeterminant",
+        registerConverters(&pythonTensorDeterminant<float,3>),
+        (arg("volume"),arg("out")=python::object()),
+        "Likewise for a 3x3 tensor volume.\n");
+
+    def("tensorEigenvalues",
+        registerConverters(&pythonTensorEigenvalues<float,2>),
+        (arg("image"),arg("out")=python::object()),
+        "Calculate the eigenvalues in each pixel/voxel of a 2x2 tensor image.\n\n"
+        "For details see tensorEigenvaluesMultiArray_ in the vigra C++ documentation.\n");
+
+    def("tensorEigenvalues",
+        registerConverters(&pythonTensorEigenvalues<float,3>),
+        (arg("volume"),arg("out")=python::object()),
+        "Likewise for a 3x3 tensor volume.\n");
+
+    def("hourGlassFilter2D",
+        registerConverters(&pythonHourGlassFilter2D<float,float>),
+        (arg("image"), arg("sigma"), arg("rho"),arg("out")=python::object()),
+        "Anisotropic tensor smoothing with the hourglass filter. \n\n"
+        "For details see hourGlassFilter_ in the vigra C++ documentation.\n");
+ 
+ /* Wee, tons of errors here
+    def("ellipticGaussian2D",
+        registerConverters(&ellipticGaussian2D<float,float>),
+        (arg("image"), arg("sigmamax"), arg("sigmamin"),arg("out")=python::object()));
+    def("ellipticGaussian2D",
+        registerConverters(&ellipticGaussian2D<float,float>),
+        (arg("image"), arg("sigmamax"), arg("sigmamin"),arg("out")=python::object()));
+  */
+}
+
+} // namespace vigra
diff --git a/vigranumpy/src/core/tws.hxx b/vigranumpy/src/core/tws.hxx
new file mode 100644
index 0000000..7e7de1d
--- /dev/null
+++ b/vigranumpy/src/core/tws.hxx
@@ -0,0 +1,374 @@
+#pragma once
+#ifndef VIGRA_TWS_HXX
+#define VIGRA_TWS_HXX
+
+#include <stddef.h>
+
+#include <vector>
+#include <queue>
+#include <algorithm> // max
+#include <map>
+
+#include <vigra/windows.h>
+#include <vigra/multi_array.hxx>
+#include <vigra/bucket_queue.hxx>
+
+namespace vigra {
+
+template<class T>
+void twsc
+(
+	const MultiArrayView<3, UInt8, StridedArrayTag>&,
+	MultiArrayView<3, T, StridedArrayTag>&,
+	MultiArrayView<3, UInt8, StridedArrayTag>&
+);
+
+template<class T>
+inline bool isAtSeedBorder
+(
+	const MultiArrayView<3, T, StridedArrayTag>& labeling,
+	const MultiArrayIndex& index
+);
+
+template<class S1, class T, class S2>
+void tws
+(
+	const MultiArrayView<3, UInt8, S1>& vol,
+	MultiArrayView<3, T, S2>& labeling
+)
+{
+    size_t numVoxels = vol.size();
+
+	// define 256 queues, one for each gray level.
+	std::vector<std::queue<MultiArrayIndex> > queues(256);
+
+    std::cout << "uint8 version\n" << std::flush;
+
+	// add each unlabeled pixels which is adjacent to a seed
+	// to the queue corresponding to its gray level
+	for(MultiArrayIndex j = 0; j < labeling.size(); ++j) {
+        if(j % 1000000 == 0) {
+            std::cout << "\r  initializing queues " << (j/float(numVoxels)*100) << "%                    " << std::flush;
+        }
+		if(isAtSeedBorder<T>(labeling, j)) {
+			queues[vol[j]].push(j);
+		}
+	}
+    std::cout << "\r  initializing queues 100.0000%                    " << std::endl;
+
+	// flood
+	UInt8 grayLevel = 0;
+
+    size_t voxelsProcessed = 0;
+
+	for(;;) {
+		while(!queues[grayLevel].empty()) {
+			// label pixel and remove from queue
+			MultiArrayIndex j = queues[grayLevel].front();
+			queues[grayLevel].pop();
+
+            ++voxelsProcessed;
+
+            if(voxelsProcessed % 1000000 == 0) {
+                std::cout << "\r  watersheds " << (voxelsProcessed/float(numVoxels)*100) << "%                    " << std::flush;
+            }
+
+			// add unlabeled neighbors to queues
+			// left, upper, and front voxel
+			typename MultiArrayView<3, UInt32>::difference_type coordinate = labeling.scanOrderIndexToCoordinate(j);
+			for(unsigned short d = 0; d<3; ++d) {
+				if(coordinate[d] != 0) {
+					--coordinate[d];
+					if(labeling[coordinate] == 0) {
+						MultiArrayIndex k = labeling.coordinateToScanOrderIndex(coordinate);
+						UInt8 queueIndex = std::max(vol[coordinate], grayLevel);
+						labeling[k] = labeling[j]; // label pixel
+						queues[queueIndex].push(k);
+					}
+					++coordinate[d];
+				}
+			}
+			// right, lower, and back voxel
+			for(unsigned short d = 0; d<3; ++d) {
+				if(coordinate[d] < labeling.shape(d)-1) {
+					++coordinate[d];
+					if(labeling[coordinate] == 0) {
+						MultiArrayIndex k = labeling.coordinateToScanOrderIndex(coordinate);
+						UInt8 queueIndex = std::max(vol[coordinate], grayLevel);
+						labeling[k] = labeling[j]; // label pixel
+						queues[queueIndex].push(k);
+					}
+					--coordinate[d];
+				}
+			}
+		}
+		if(grayLevel == 255) {
+			break;
+		}
+		else {
+			queues[grayLevel] = std::queue<MultiArrayIndex>(); // free memory
+			++grayLevel;
+		}
+	}
+    std::cout << "\r  watersheds 100.0000%                    " << std::endl;
+}
+
+template<class S1, class T, class S2>
+void tws
+(
+	const MultiArrayView<3, float, S1>& vol,
+	MultiArrayView<3, T, S2>& labeling
+)
+{
+    size_t numVoxels = vol.size();
+
+	// define 256 queues, one for each gray level.
+    typedef PriorityQueue<MultiArrayIndex, float, true> PQ;
+	std::vector<PQ> queues(256);
+
+    std::cout << "float version\n" << std::flush;
+
+	// add each unlabeled pixels which is adjacent to a seed
+	// to the queue corresponding to its gray level
+	for(MultiArrayIndex j = 0; j < labeling.size(); ++j) {
+        if(j % 1000000 == 0) {
+            std::cout << "\r  initializing queues " << (j/float(numVoxels)*100) << "%                    " << std::flush;
+        }
+		if(isAtSeedBorder<T>(labeling, j)) 
+        {
+			queues[(int)vol[j]].push(j, vol[j]);
+		}
+	}
+    std::cout << "\r  initializing queues 100.0000%                    " << std::endl;
+
+	// flood
+	UInt8 grayLevel = 0;
+
+    size_t voxelsProcessed = 0;
+
+	for(;;) {
+		while(!queues[grayLevel].empty()) {
+			// label pixel and remove from queue
+			MultiArrayIndex j = queues[grayLevel].top();
+            float p = queues[grayLevel].topPriority();
+			queues[grayLevel].pop();
+
+            ++voxelsProcessed;
+
+            if(voxelsProcessed % 1000000 == 0) {
+                std::cout << "\r  watersheds " << (voxelsProcessed/float(numVoxels)*100) << "%                    " << std::flush;
+            }
+
+			// add unlabeled neighbors to queues
+			// left, upper, and front voxel
+			typename MultiArrayView<3, UInt32>::difference_type coordinate = labeling.scanOrderIndexToCoordinate(j);
+			for(unsigned short d = 0; d<3; ++d) {
+				if(coordinate[d] != 0) {
+					--coordinate[d];
+					if(labeling[coordinate] == 0) {
+						MultiArrayIndex k = labeling.coordinateToScanOrderIndex(coordinate);
+						float priority = std::max(vol[coordinate], p);
+						labeling[k] = labeling[j]; // label pixel
+						queues[(int)priority].push(k, priority);
+					}
+					++coordinate[d];
+				}
+			}
+			// right, lower, and back voxel
+			for(unsigned short d = 0; d<3; ++d) {
+				if(coordinate[d] < labeling.shape(d)-1) {
+					++coordinate[d];
+					if(labeling[coordinate] == 0) {
+						MultiArrayIndex k = labeling.coordinateToScanOrderIndex(coordinate);
+						float priority = std::max(vol[coordinate], p);
+						labeling[k] = labeling[j]; // label pixel
+						queues[(int)priority].push(k, priority);
+					}
+					--coordinate[d];
+				}
+			}
+		}
+		if(grayLevel == 255) {
+			break;
+		}
+		else {
+			queues[grayLevel] = PQ(); // free memory
+			++grayLevel;
+		}
+	}
+    std::cout << "\r  watersheds 100.0000%                    " << std::endl;
+}
+
+template <class T>
+struct TWS
+{
+    template<class S1, class U, class S2>
+    static void exec(const MultiArrayView<3, T, S1>&,
+                     MultiArrayView<3, U, S2>&)
+    {
+        vigra_precondition(false,
+           "tws(): Turbo watershed needs input type UInt8 or float32.");
+    }
+};
+
+template <>
+struct TWS<UInt8>
+{
+    template<class S1, class U, class S2>
+    static void exec(const MultiArrayView<3, UInt8, S1>& vol,
+                     MultiArrayView<3, U, S2>& labeling)
+    {
+        tws(vol, labeling);
+    }
+};
+
+template <>
+struct TWS<float>
+{
+    template<class S1, class U, class S2>
+    static void exec(const MultiArrayView<3, float, S1>& vol,
+                     MultiArrayView<3, U, S2>& labeling)
+    {
+        tws(vol, labeling);
+    }
+};
+
+template<class T>
+void twsc
+(
+	const MultiArrayView<3, UInt8>& vol,
+	MultiArrayView<3, T>& labeling, 
+	MultiArrayView<3, UInt8>& directions,
+	std::map<std::pair<T, T>, std::pair<MultiArrayIndex, MultiArrayIndex> >& adjacency
+)
+{
+	// define 256 queues, one for each gray level.
+	std::vector<std::queue<MultiArrayIndex> > queues(256);
+
+	// add each unlabeled pixels which is adjacent to a seed
+	// to the queue corresponding to its gray level
+	for(MultiArrayIndex j = 0; j < labeling.size(); ++j) {
+		if(isAtSeedBorder<T>(labeling, j)) {
+			queues[vol[j]].push(j);
+		}
+	}
+
+	// flood
+	UInt8 grayLevel = 0;
+	for(;;) {
+		while(!queues[grayLevel].empty()) {
+			// label pixel and remove from queue
+			MultiArrayIndex j = queues[grayLevel].front();
+			queues[grayLevel].pop();
+
+			// add unlabeled neighbors to queues
+			// left, upper, and front voxel
+			typename MultiArrayView<3, UInt32>::difference_type coordinate = labeling.scanOrderIndexToCoordinate(j);
+			for(unsigned short d = 0; d<3; ++d) {
+				if(coordinate[d] != 0) {
+					--coordinate[d];
+					if(labeling[coordinate] == 0) {
+						MultiArrayIndex k = labeling.coordinateToScanOrderIndex(coordinate);
+						UInt8 queueIndex = std::max(vol[coordinate], grayLevel);
+						labeling[k] = labeling[j]; // label pixel
+						directions[k] = d+1; // save direction
+						queues[queueIndex].push(k);
+					}
+					else if(labeling[coordinate] != labeling[j]) {
+						MultiArrayIndex k = labeling.coordinateToScanOrderIndex(coordinate);
+						if(labeling[j] < labeling[k]) {
+							std::pair<T, T> p(labeling[j], labeling[k]);
+							if(adjacency.count(p) == 0) {
+								adjacency[p] = std::pair<MultiArrayIndex, MultiArrayIndex>(j, k);
+							}
+						}
+						else {
+							std::pair<T, T> p(labeling[k], labeling[j]);
+							if(adjacency.count(p) == 0) {
+								adjacency[p] = std::pair<MultiArrayIndex, MultiArrayIndex>(k, j);
+							}
+						}
+					}
+					++coordinate[d];
+				}
+			}
+			// right, lower, and back voxel
+			for(unsigned short d = 0; d<3; ++d) {
+				if(coordinate[d] < labeling.shape(d)-1) {
+					++coordinate[d];
+					if(labeling[coordinate] == 0) {
+						MultiArrayIndex k = labeling.coordinateToScanOrderIndex(coordinate);
+						UInt8 queueIndex = std::max(vol[coordinate], grayLevel);
+						labeling[k] = labeling[j]; // label pixel
+						directions[k] = d+4; // save direction
+						queues[queueIndex].push(k);
+					}
+					else if(labeling[coordinate] != labeling[j]) {
+						MultiArrayIndex k = labeling.coordinateToScanOrderIndex(coordinate);
+						if(labeling[j] < labeling[k]) {
+							std::pair<T, T> p(labeling[j], labeling[k]);
+							if(adjacency.count(p) == 0) {
+								adjacency[p] = std::pair<MultiArrayIndex, MultiArrayIndex>(j, k);
+							}
+						}
+						else {
+							std::pair<T, T> p(labeling[k], labeling[j]);
+							if(adjacency.count(p) == 0) {
+								adjacency[p] = std::pair<MultiArrayIndex, MultiArrayIndex>(k, j);
+							}
+						}
+					}
+					--coordinate[d];
+				}
+			}
+		}
+		if(grayLevel == 255) {
+			break;
+		}
+		else {
+			queues[grayLevel] = std::queue<MultiArrayIndex>(); // free memory
+			++grayLevel;
+		}
+	}
+}
+
+template<class T>
+inline bool isAtSeedBorder
+(
+	const MultiArrayView<3, T, StridedArrayTag>& labeling,
+	const MultiArrayIndex& index
+)
+{
+	if(labeling[index] == 0) {	
+		return false; // not a seed voxel
+	}
+	else {
+		typename MultiArrayView<3, UInt32>::difference_type coordinate
+			= labeling.scanOrderIndexToCoordinate(index);
+		// check left, upper, and front voxel for zero label
+		for(unsigned short d = 0; d<3; ++d) {
+			if(coordinate[d] != 0) {
+				--coordinate[d];
+				if(labeling[coordinate] == 0) {
+					return true;
+				}
+				++coordinate[d];
+			}
+		}
+		// check right, lower, and back voxel for zero label
+		for(unsigned short d = 0; d<3; ++d) {
+			if(coordinate[d] < labeling.shape(d)-1) {
+				++coordinate[d];
+				if(labeling[coordinate] == 0) {
+					return true;
+				}
+				--coordinate[d];
+			}
+		}
+		return false;
+	}
+}
+
+} // namespace vigra
+
+#endif // VIGRA_TWS_HXX
diff --git a/vigranumpy/src/core/vigranumpycore.cxx b/vigranumpy/src/core/vigranumpycore.cxx
new file mode 100644
index 0000000..37a8c81
--- /dev/null
+++ b/vigranumpy/src/core/vigranumpycore.cxx
@@ -0,0 +1,74 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpycore_PyArray_API
+
+#include <Python.h>
+#include <vigra/config.hxx>
+#include <iostream>
+#include <boost/python.hpp>
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/functorexpression.hxx>
+#include <vigra/mathutil.hxx>
+#include <vigra/utilities.hxx>
+#include <vector>
+
+namespace python = boost::python;
+
+namespace vigra {
+
+UInt32 pychecksum(python::str const & s)
+{
+    unsigned int size = len(s);
+    return checksum(PyString_AsString(s.ptr()), size);
+}
+
+void registerNumpyArrayConverters();
+void defineAxisTags();
+
+} // namespace vigra
+
+using namespace boost::python;
+using namespace vigra;
+
+BOOST_PYTHON_MODULE_INIT(vigranumpycore)
+{
+    import_array();
+    registerNumpyArrayConverters();
+    defineAxisTags();
+    
+    def("checksum", &pychecksum, args("data"));
+}
diff --git a/vigranumpy/src/core/vigranumpykernel.hxx b/vigranumpy/src/core/vigranumpykernel.hxx
new file mode 100644
index 0000000..0a6e723
--- /dev/null
+++ b/vigranumpy/src/core/vigranumpykernel.hxx
@@ -0,0 +1,16 @@
+#ifndef VIGRANUMPYKERNEL_HXX
+#define VIGRANUMPYKERNEL_HXX
+
+#include <vigra/separableconvolution.hxx>
+#include <vigra/stdconvolution.hxx>
+
+namespace vigra
+{
+
+typedef double KernelValueType;
+typedef Kernel2D< KernelValueType > TwoDKernel;
+typedef Kernel1D< KernelValueType > Kernel;
+
+} // namespace vigra
+
+#endif // VIGRANUMPYKERNEL_HXX
diff --git a/vigranumpy/src/core/vigranumpyscaleparam.hxx b/vigranumpy/src/core/vigranumpyscaleparam.hxx
new file mode 100644
index 0000000..3896c43
--- /dev/null
+++ b/vigranumpy/src/core/vigranumpyscaleparam.hxx
@@ -0,0 +1,107 @@
+#ifndef VIGRANUMPYSCALEPARAM_HXX
+#define VIGRANUMPYSCALEPARAM_HXX
+
+#include <Python.h>
+#include <boost/python.hpp>
+#include <vigra/tinyvector.hxx>
+#include <vigra/tuple.hxx>
+
+namespace python = boost::python;
+
+namespace vigra
+{
+
+template <unsigned ndim>
+struct pythonScaleParam1
+{
+    typedef TinyVector<double, ndim> p_vector;
+    typedef typename p_vector::const_iterator return_type;
+    p_vector vec;
+    static unsigned len_check(python::object val,
+                              const char *const function_name)
+    {
+        unsigned count = python::len(val);
+        if (count == 1)
+            return 0;
+        if (count == ndim)
+            return 1;
+
+        std::string msg = std::string(function_name) + "(): Parameter number "
+                      "must be 1 or equal to the number of spatial dimensions.";
+        PyErr_SetString(PyExc_ValueError, msg.c_str());
+        python::throw_error_already_set();
+        return 0;
+    }
+    pythonScaleParam1()
+    {}
+    pythonScaleParam1(python::object val,
+                      const char *const function_name = "pythonScaleParam1")
+    {
+        if (PySequence_Check(val.ptr()))
+        {
+            unsigned increment = len_check(val, function_name);
+            unsigned i_v = 0;
+            for (unsigned i = 0; i != ndim; ++i, i_v += increment)
+                vec[i] = python::extract<double>(val[i_v]);
+        }
+        else
+        {
+            double x = python::extract<double>(val);
+            vec = p_vector(x);
+        }
+    }
+    return_type operator()() const
+    {
+        return vec.begin();
+    }
+};
+
+template <unsigned ndim>
+struct pythonScaleParam
+{
+    typedef ConvolutionOptions<ndim> return_type;
+    typedef TinyVector<double, ndim> p_vector;
+    pythonScaleParam1<ndim> sigma_eff;
+    pythonScaleParam1<ndim> sigma_d;
+    pythonScaleParam1<ndim> step_size;
+    pythonScaleParam1<ndim> outer_scale;
+
+    pythonScaleParam(python::object s_eff,
+                     python::object s_d,
+                     python::object s_size,
+                     const char *const function_name = "pythonScaleParam")
+        : sigma_eff(s_eff, function_name),
+          sigma_d(s_d, function_name),
+          step_size(s_size, function_name)
+    {}
+    pythonScaleParam(python::object s_eff,
+                     python::object s_d,
+                     python::object s_size,
+                     python::object s_outer,
+                     const char *const function_name = "pythonScaleParam")
+        : sigma_eff(s_eff, function_name),
+          sigma_d(s_d, function_name),
+          step_size(s_size, function_name),
+          outer_scale(s_outer, function_name)
+    {}
+    return_type operator()() const
+    {
+        return_type opt;
+        return opt.stdDev(sigma_eff()).resolutionStdDev(sigma_d())
+                  .stepSize(step_size()).outerScale(outer_scale());
+    }
+    
+    template <class Array>
+    void permuteLikewise(Array const & a)
+    {
+        sigma_eff.vec   = a.permuteLikewise(sigma_eff.vec);
+        sigma_d.vec     = a.permuteLikewise(sigma_d.vec);
+        step_size.vec   = a.permuteLikewise(step_size.vec);
+        outer_scale.vec = a.permuteLikewise(outer_scale.vec);
+    }
+};
+
+
+} // namespace vigra
+
+#endif // VIGRANUMPYSCALEPARAM_HXX
diff --git a/vigranumpy/src/fourier/CMakeLists.txt b/vigranumpy/src/fourier/CMakeLists.txt
new file mode 100644
index 0000000..7c9f154
--- /dev/null
+++ b/vigranumpy/src/fourier/CMakeLists.txt
@@ -0,0 +1,9 @@
+INCLUDE_DIRECTORIES(${VIGRANUMPY_INCLUDE_DIRS} ${FFTW3_INCLUDE_DIR})
+
+VIGRA_ADD_NUMPY_MODULE(fourier 
+  SOURCES
+    fourier.cxx
+  LIBRARIES   
+    ${FFTW3_LIBRARIES}
+    ${FFTW3F_LIBRARIES}
+  VIGRANUMPY)   
diff --git a/vigranumpy/src/fourier/fourier.cxx b/vigranumpy/src/fourier/fourier.cxx
new file mode 100644
index 0000000..6e7591e
--- /dev/null
+++ b/vigranumpy/src/fourier/fourier.cxx
@@ -0,0 +1,259 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyfourier_PyArray_API
+
+#include <Python.h>
+#include <vigra/config.hxx>
+#include <boost/python.hpp>
+#include <vigra/numpy_array.hxx>
+#include <vigra/multi_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+#include <vigra/fftw3.hxx>
+#include <vigra/multi_fft.hxx>
+#include <vigra/gaborfilter.hxx>
+#include <iostream>
+
+namespace vigra {
+
+template <>
+struct NumpyArrayValuetypeTraits<FFTWComplex<float> >
+{
+    static bool isValuetypeCompatible(PyArrayObject const * obj) /* obj must not be NULL */
+    {
+        return PyArray_EquivTypenums(NPY_CFLOAT, PyArray_DESCR((PyArrayObject *)obj)->type_num) &&
+               PyArray_ITEMSIZE((PyArrayObject *)obj) == sizeof(FFTWComplex<float>);
+    }
+
+    static NPY_TYPES const typeCode = NPY_CFLOAT;
+
+    static std::string typeName()
+    {
+        return "complex64";
+    }
+
+    static std::string typeNameImpex()
+    {
+        return "";
+    }
+
+    static PyObject * typeObject()
+    {
+        return PyArray_TypeObjectFromType(NPY_CFLOAT);
+    }
+};
+
+template <class T>
+NumpyAnyArray
+pythonCreateGaborFilter(typename MultiArrayView<2,T>::difference_type shape,
+                        double orientation, 
+                        double centerFrequency,
+                        double angularSigma, 
+                        double radialSigma, 
+                        NumpyArray<2,Singleband<T> > res)
+{
+    res.reshapeIfEmpty(TaggedShape(shape, NumpyAnyArray::defaultAxistags(3)).toFrequencyDomain(), 
+            "createGaborFilter(): Output array has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        createGaborFilter(destImageRange(res),
+                          orientation, centerFrequency, angularSigma, radialSigma);
+    }
+    return res;
+}
+
+// template <unsigned int N, int SIGN>
+// NumpyAnyArray
+// pythonFourierTransform(NumpyArray<N, Multiband<FFTWComplex<float> > > in, 
+                       // NumpyArray<N, Multiband<FFTWComplex<float> > > res)
+// {
+    // res.reshapeIfEmpty(in.shape(), in.strideOrdering(),
+        // "fourierTransform(): Output array must have the same shape and stride ordering as input array.", true);
+
+    // for(MultiArrayIndex k=0; k<in.shape(N-1); ++k)
+    // {
+        // MultiArrayView<N-1, FFTWComplex<float> , StridedArrayTag> bin = in.bindOuter(k).permuteStridesDescending();
+        // MultiArrayView<N-1, FFTWComplex<float> , StridedArrayTag> bres = res.bindOuter(k).permuteStridesDescending();
+
+        // TinyVector<int, N-1> bshape(bin.shape()), itotal(bin.shape()), ototal(bres.shape());
+        // float norm = (float)bshape[0];
+        // for(int j=1; j<(int)N-1; ++j)
+        // {
+            // itotal[j] = bin.stride(j-1) / bin.stride(j);
+            // ototal[j] = bres.stride(j-1) / bres.stride(j);
+            // norm *= (float)bshape[j];
+        // }
+
+        // fftwf_plan plan = fftwf_plan_many_dft(N-1, bshape.begin(), 1,
+                                            // (fftwf_complex*)bin.data(), itotal.begin(),
+                                            // bin.stride(N-2), 0,
+                                            // (fftwf_complex*)bres.data(), ototal.begin(),
+                                            // bres.stride(N-2), 0,
+                                            // SIGN, FFTW_ESTIMATE);
+        // vigra_postcondition(plan != 0, "fourierTransform(): Unable to create plan.");
+        // fftwf_execute(plan);
+        // fftwf_destroy_plan(plan);
+        // if(SIGN == FFTW_BACKWARD)
+        // {
+            // bres *= FFTWComplex<float>(1.0f / norm);
+        // }
+    // }
+    // return res;
+// }
+
+template <unsigned int N, int SIGN>
+NumpyAnyArray
+pythonFourierTransform(NumpyArray<N, Multiband<FFTWComplex<float> > > in, 
+                       NumpyArray<N, Multiband<FFTWComplex<float> > > res)
+{
+    res.reshapeIfEmpty(in.taggedShape().toFrequencyDomain(SIGN == FFTW_FORWARD
+                                                               ? 1
+                                                               : -1),
+            "fourierTransform(): Output has wrong shape.");
+
+    {
+        PyAllowThreads _pythread;
+        FFTWPlan<N-1, float> plan(in.bindOuter(0), res.bindOuter(0), SIGN);
+        
+        for(MultiArrayIndex k=0; k<in.shape(N-1); ++k)
+        {
+            plan.execute(in.bindOuter(k), res.bindOuter(k));
+        }
+    }
+    return res;
+}
+
+// NumpyAnyArray
+// pythonFourierTransformR2C(NumpyAnyArray in, NumpyAnyArray res)
+// {
+    // switch(in.spatialDimensions())
+    // {
+      // case 2:
+      // {
+        // NumpyArray<3, Multiband<FFTWComplex<float> > > inc(in, true), out(res, false);
+        // return pythonFourierTransform<3, FFTW_FORWARD>(inc, out);
+      // }
+      // case 3:
+      // {
+        // NumpyArray<4, Multiband<FFTWComplex<float> > > inc(in, true), out(res, false);
+        // return pythonFourierTransform<4, FFTW_FORWARD>(inc, out);
+      // }
+      // default:
+        // vigra_fail("fourierTransform(): "
+                   // "Can only handle 2 or 3 spatial dimensions.");
+    // }
+    // return res; // this will never be reached
+// }
+
+// FIXME: implement the correct R2C transform (is already provided in multi_fft.hxx)
+// FIXME: numpy arrays are not allocated with fftw_malloc() - will this cause alignment
+//        problems (sudden crashes)?
+template <unsigned int N>
+NumpyAnyArray
+pythonFourierTransformR2C(NumpyArray<N, Multiband<float> > in, 
+                          NumpyArray<N, Multiband<FFTWComplex<float> > > res)
+{
+    res.reshapeIfEmpty(in.taggedShape().toFrequencyDomain(),
+            "fourierTransformR2C(): Output has wrong shape.");
+        
+    {
+        PyAllowThreads _pythread;
+        // static_cast<typename NumpyArray<N, Multiband<FFTWComplex<float> > >::view_type &>(res) = 
+            // static_cast<typename NumpyArray<N, Multiband<float> >::view_type const &>(in);
+        res = in;
+        FFTWPlan<N-1, float> plan(res.bindOuter(0), res.bindOuter(0), FFTW_FORWARD);
+        
+        for(MultiArrayIndex k=0; k<res.shape(N-1); ++k)
+        {
+            plan.execute(res.bindOuter(k), res.bindOuter(k));
+        }
+    }
+    return res;
+}
+
+} // namespace vigra
+
+using namespace vigra;
+
+BOOST_PYTHON_MODULE_INIT(fourier)
+{
+    using boost::python::arg;
+    using boost::python::docstring_options;
+    using boost::python::object;
+    using boost::python::def;
+
+    import_vigranumpy();
+
+    docstring_options doc_options(true, true, false);
+
+    def("fourierTransform", registerConverters(&pythonFourierTransformR2C<2>),
+        (arg("image"), arg("out") = object()),
+        "Perform 2-dimensional Fourier transformation of a scalar float32 image."
+        "If the input array has multiple channels, each channel is transformed separately.\n"
+        );
+
+    def("fourierTransform", registerConverters(&pythonFourierTransformR2C<3>),
+        (arg("volume"), arg("out") = object()),
+        "Likewise for a 3D float32 volume.\n"
+        );
+
+    def("fourierTransform", registerConverters(&pythonFourierTransform<3, FFTW_FORWARD>),
+        (arg("image"), arg("out") = object()),
+        "Likewise for a 2D complex64 image.\n");
+
+    def("fourierTransform", registerConverters(&pythonFourierTransform<4, FFTW_FORWARD>),
+        (arg("volume"), arg("out") = object()),
+        "Likewise for a 3D complex64 volume.\n");
+
+    def("fourierTransformInverse", registerConverters(&pythonFourierTransform<3, FFTW_BACKWARD>),
+        (arg("image"), arg("out") = object()),
+        "Perform 2-dimensional inverse Fourier transformation of a complex64 array."
+        "If the input array has multiple channels, each channel is transformed separately.\n");
+
+    def("fourierTransformInverse", registerConverters(&pythonFourierTransform<4, FFTW_BACKWARD>),
+        (arg("volume"), arg("out") = object()),
+        "Likewise for a 3D complex128 volume.\n");
+
+    def("createGaborFilter", registerConverters(&pythonCreateGaborFilter<float>),
+        (arg("shape"),arg("orientation"),arg("centerFrequency"),arg("angularSigma"),arg("radialSigma"), arg("out") = object()),
+        "Create a 2-dimensional gabor filter in frequency space.");
+
+    def("radialGaborSigma", &radialGaborSigma,
+        "Calculate sensible radial sigma for given parameters.");
+
+    def("angularGaborSigma", &angularGaborSigma,
+        "Calculate sensible angular sigma for given parameters.");
+}
diff --git a/vigranumpy/test/CMakeLists.txt b/vigranumpy/test/CMakeLists.txt
new file mode 100644
index 0000000..f1b30c2
--- /dev/null
+++ b/vigranumpy/test/CMakeLists.txt
@@ -0,0 +1,146 @@
+INCLUDE_DIRECTORIES(${VIGRANUMPY_INCLUDE_DIRS})
+
+SET(TEST_SCRIPTS
+    test_arraytypes.py
+    test_impex.py
+    test1.py
+    test2.py
+    test3.py
+    test_color.py
+    )
+
+# setup the file 'testsuccess.cxx' which will become out-of-date when the
+# last test failed or when the tests code changed, so that tests are re-executed
+SET(TEST_SUCCESS_FILE "${CMAKE_CURRENT_BINARY_DIR}/testsuccess.cxx")
+
+# find the vigranumpy modules that we want to test, and make
+# 'testsuccess.cxx' depend on them
+# TODO: Does cmake provide a standard way to find those dependencies? 
+GET_TARGET_PROPERTY(VIGRANUMPY_DEPENDS vigranumpy VIGRA_DEPENDS)
+SEPARATE_ARGUMENTS(VIGRANUMPY_DEPENDS)
+
+add_custom_command(
+    OUTPUT ${TEST_SUCCESS_FILE}
+    DEPENDS ${TEST_SCRIPTS} ${VIGRANUMPY_DEPENDS}
+    COMMAND ${CMAKE_COMMAND}
+    ARGS -E touch ${TEST_SUCCESS_FILE})
+
+FILE(GLOB TESTSUCCESS_FOUND ${TEST_SUCCESS_FILE})
+IF(NOT TESTSUCCESS_FOUND)
+    FILE(WRITE ${TEST_SUCCESS_FILE}
+     "// auto-generated dummy file to force re-execution of failed tests
+")
+ENDIF()
+
+# setup the test target
+IF(AUTOBUILD_TESTS)
+  ADD_LIBRARY(vigranumpytest SHARED 
+               vigranumpytest.cxx ${TEST_SUCCESS_FILE} ${TEST_SCRIPTS})
+ELSE()
+  ADD_LIBRARY(vigranumpytest SHARED EXCLUDE_FROM_ALL
+               vigranumpytest.cxx ${TEST_SUCCESS_FILE} ${TEST_SCRIPTS})
+ENDIF()
+
+IF(PYTHON_PLATFORM MATCHES "^windows$")
+    SET_TARGET_PROPERTIES(vigranumpytest PROPERTIES PREFIX "" SUFFIX  ".pyd")
+ELSEIF(MACOSX)
+    SET_TARGET_PROPERTIES(vigranumpytest PROPERTIES PREFIX "" SUFFIX ".so")
+ELSE()
+    SET_TARGET_PROPERTIES(vigranumpytest PROPERTIES PREFIX "")
+ENDIF()
+
+#TARGET_LINK_LIBRARIES(vigranumpytest ${VIGRANUMPY_LIBRARIES} vigranumpy_core)
+TARGET_LINK_LIBRARIES(vigranumpytest ${VIGRANUMPY_LIBRARIES})
+ADD_DEPENDENCIES(check_python vigranumpytest)
+ADD_DEPENDENCIES(ctest vigranumpytest)
+ADD_DEPENDENCIES(vigranumpytest vigranumpy)
+
+# setup the file 'set_path.py' to ensure that tests are run against the binaries
+# which are currently being built, not against (possibly outdated) installed modules
+DEPENDENCY_PATH(VIGRAIMPEX_PATH vigraimpex)
+DEPENDENCY_PATH(VIGRANUMPYTEST_PATH vigranumpytest)
+
+STRING(REGEX REPLACE "/vigra$" "" VIGRANUMPY_TMP_PATH ${vigranumpy_tmp_dir})
+FILE(TO_NATIVE_PATH "${VIGRANUMPY_TMP_PATH}" VIGRANUMPY_TMP_PATH)
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/set_paths.py.in
+                ${CMAKE_CURRENT_BINARY_DIR}/set_paths.py 
+                @ONLY)
+
+
+IF(NOT PYTHON_NOSETESTS_NOT_FOUND)
+    # copy the individual test scripts
+    FOREACH(test_script ${TEST_SCRIPTS})
+        ADD_CUSTOM_COMMAND(
+            TARGET vigranumpytest
+            POST_BUILD
+            COMMAND ${CMAKE_COMMAND}
+            ARGS -E copy_if_different
+            ${CMAKE_CURRENT_SOURCE_DIR}/${test_script} ${CMAKE_CURRENT_BINARY_DIR}/${test_script}
+            COMMENT "Running vigranumpy tests")
+    ENDFOREACH(test_script)
+
+    VIGRA_NATIVE_PATH(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
+    
+    # Windows: Set the DLL path to the binaries currently being built
+    #          (so that binaries which are already installed are ignored)
+    #          This is not necessary on Linux, because the correct path
+    #          is hard-coded into the module by means of 'rpath'
+    set(VIGRA_PATH "")
+    if(WIN32)
+        IF(CYGWIN)
+            SET(PATHSEP ":")
+        ELSE()
+            SET(PATHSEP ";")
+        ENDIF()
+        FOREACH(lib ${LIBRARIES})
+            GET_TARGET_PROPERTY(p ${lib} LOCATION)
+            if(p)
+                GET_FILENAME_COMPONENT(p ${p} PATH)
+                VIGRA_NATIVE_PATH(p ${p})
+                SET(VIGRA_PATH  "${p}${PATHSEP}${VIGRA_PATH}")
+           endif()
+        ENDFOREACH(lib)
+    endif()
+    
+    # Setup the test execution script
+    VIGRA_NATIVE_PATH(VIGRA_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+    SET(VIGRA_TEST_EXECUTABLE "${PYTHON_EXECUTABLE} -c \"import nose; nose.main()\" .")        
+    IF(MSVC OR MINGW)
+        SET(VIGRA_TEST_EXECUTABLE "${VIGRA_TEST_EXECUTABLE} %CONFIGURATION%")
+        SET(VIGRA_RUN_TEST "${CMAKE_CURRENT_BINARY_DIR}/run_vigranumpytest.bat")
+        CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config/run_test.bat.in
+                        ${VIGRA_RUN_TEST}
+                        @ONLY)
+    ELSE()            
+        SET(VIGRA_RUN_TEST "${CMAKE_CURRENT_BINARY_DIR}/run_vigranumpytest.sh")
+        CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config/run_test.sh.in
+                        ${VIGRA_RUN_TEST}
+                       @ONLY)
+        EXECUTE_PROCESS(COMMAND chmod u+x ${VIGRA_RUN_TEST} OUTPUT_QUIET ERROR_QUIET)
+    ENDIF()
+
+    # register the test execution command
+    # VIGRA_CONFIGURATION is 'release' or 'debug' on Windows, nothing on Linux
+    # variable CMAKE_CFG_INTDIR contains a dot '.' for a Windows nmake build, or
+    #                           '$(OutDir)' for a VisualStudio build (OutDir will be
+    #                           set by VS at build time)
+    IF(NOT CMAKE_CFG_INTDIR STREQUAL ".")
+        SET(VIGRA_CONFIGURATION ${CMAKE_CFG_INTDIR})
+    ELSE()
+        SET(VIGRA_CONFIGURATION)
+    ENDIF()
+
+    IF(AUTOEXEC_TESTS)
+        add_custom_command(
+            TARGET vigranumpytest
+            POST_BUILD
+            COMMAND ${VIGRA_RUN_TEST} ARGS ${VIGRA_CONFIGURATION}
+            COMMENT "Running vigranumpy tests")
+    ENDIF()
+
+    ADD_TEST(vigranumpytest ${VIGRA_RUN_TEST} ${VIGRA_CONFIGURATION})
+
+ELSE()
+        MESSAGE(STATUS "  vigranumpy tests will NOT be executed (nosetests missing)")
+ENDIF()
diff --git a/vigranumpy/test/set_paths.py.in b/vigranumpy/test/set_paths.py.in
new file mode 100644
index 0000000..8798274
--- /dev/null
+++ b/vigranumpy/test/set_paths.py.in
@@ -0,0 +1,45 @@
+#######################################################################
+#                                                                      
+#         Copyright 2009-2010 by Ullrich Koethe                        
+#                                                                      
+#    This file is part of the VIGRA computer vision library.           
+#    The VIGRA Website is                                              
+#        http://hci.iwr.uni-heidelberg.de/vigra/                       
+#    Please direct questions, bug reports, and contributions to        
+#        ullrich.koethe at iwr.uni-heidelberg.de    or                    
+#        vigra at informatik.uni-hamburg.de                               
+#                                                                      
+#    Permission is hereby granted, free of charge, to any person       
+#    obtaining a copy of this software and associated documentation    
+#    files (the "Software"), to deal in the Software without           
+#    restriction, including without limitation the rights to use,      
+#    copy, modify, merge, publish, distribute, sublicense, and/or      
+#    sell copies of the Software, and to permit persons to whom the    
+#    Software is furnished to do so, subject to the following          
+#    conditions:                                                       
+#                                                                      
+#    The above copyright notice and this permission notice shall be    
+#    included in all copies or substantial portions of the             
+#    Software.                                                         
+#                                                                      
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     
+#    OTHER DEALINGS IN THE SOFTWARE.                                   
+#                                                                      
+#######################################################################
+
+import sys, os
+
+if len(sys.argv) == 3:
+    outdir = os.sep + sys.argv[-1]
+else:
+    outdir = ''
+
+os.environ['PATH'] = os.pathsep.join([r'@VIGRAIMPEX_PATH@%s' % outdir, os.environ['PATH']])
+sys.path.insert(0, r'@VIGRANUMPY_TMP_PATH@')
+sys.path.insert(0, r'@VIGRANUMPYTEST_PATH@%s' % outdir)
diff --git a/vigranumpy/test/test1.py b/vigranumpy/test/test1.py
new file mode 100644
index 0000000..023ed4f
--- /dev/null
+++ b/vigranumpy/test/test1.py
@@ -0,0 +1,279 @@
+#######################################################################
+#                                                                      
+#         Copyright 2009-2010 by Ullrich Koethe                        
+#                                                                      
+#    This file is part of the VIGRA computer vision library.           
+#    The VIGRA Website is                                              
+#        http://hci.iwr.uni-heidelberg.de/vigra/                       
+#    Please direct questions, bug reports, and contributions to        
+#        ullrich.koethe at iwr.uni-heidelberg.de    or                    
+#        vigra at informatik.uni-hamburg.de                               
+#                                                                      
+#    Permission is hereby granted, free of charge, to any person       
+#    obtaining a copy of this software and associated documentation    
+#    files (the "Software"), to deal in the Software without           
+#    restriction, including without limitation the rights to use,      
+#    copy, modify, merge, publish, distribute, sublicense, and/or      
+#    sell copies of the Software, and to permit persons to whom the    
+#    Software is furnished to do so, subject to the following          
+#    conditions:                                                       
+#                                                                      
+#    The above copyright notice and this permission notice shall be    
+#    included in all copies or substantial portions of the             
+#    Software.                                                         
+#                                                                      
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     
+#    OTHER DEALINGS IN THE SOFTWARE.                                   
+#                                                                      
+#######################################################################
+
+import sys
+print >> sys.stderr, "\nexecuting test file", __file__
+execfile('set_paths.py')
+
+from nose.tools import assert_equal, raises, assert_raises
+import vigra
+import numpy as np
+from vigra.analysis import *
+from vigra.filters import *
+import vigra.arraytypes as at
+
+img_rgb_f = at.RGBImage(np.random.rand(100,200,3)*255,dtype=np.float32)
+img_scalar_f = at.ScalarImage(np.random.rand(100,200)*255,dtype=np.float32)
+img_multi_f = at.Vector3Image(np.random.rand(100,200,3)*255,dtype=np.float32)
+ 
+img_rgb_i = at.RGBImage(np.random.rand(100,200,3)*255,dtype=np.int32)
+img_scalar_i = at.ScalarImage(np.random.rand(100,200)*255,dtype=np.uint32)
+img_scalar_i64 = at.ScalarImage(np.random.rand(199,199)*4095,dtype=np.uint64)
+img_scalar_ui8 = at.ScalarImage(np.random.rand(100,200)*255,dtype=np.uint8)
+img_multi_i = at.Vector3Image(np.random.rand(100,200,3)*255,dtype=np.int32)
+
+vol_rgb_f = at.RGBVolume(np.random.rand(100,200,60,3)*255,dtype=np.float32)
+vol_scalar_f = at.ScalarVolume(np.random.rand(100,200,50)*255,dtype=np.float32)
+vol_multi_f = at.Vector6Volume(np.random.rand(100,200,50,6)*255,dtype=np.float32)
+ 
+vol_rgb_i = at.RGBVolume(np.random.rand(100,200,60,3)*255,dtype=np.int32)
+vol_scalar_i = at.ScalarVolume(np.random.rand(100,200,50)*255,dtype=np.int32)
+vol_multi_i = at.Vector6Volume(np.random.rand(100,200,50,6)*255,dtype=np.int32)
+
+def checkShape(shape1, shape2):
+    if isinstance(shape1, np.ndarray):
+        shape1 = shape1.shape
+    if isinstance(shape2, np.ndarray):
+        shape2 = shape2.shape
+    assert_equal(shape1, shape2)
+
+def checkType(i,type):
+    assert_equal(i.dtype, type)
+
+def checkAboutSame(i1,i2):
+    compare_shapes(i1.shape, i2.shape)
+    difference=np.sum(np.abs(i1-i2))/float(np.size(i1))
+    assert(difference<5)
+    
+def test_watersheds():
+
+    res = watershedsUnionFind(img_scalar_f)
+    checkShape(img_scalar_f,res[0])
+    checkType(res[0], np.uint32)
+
+    res = watershedsUnionFind(img_scalar_f, 4)
+    checkShape(img_scalar_f, res[0])
+    checkType(res[0], np.uint32)
+
+    img_scalar_i = at.ScalarImage(img_scalar_f.shape, dtype=np.uint32)
+    res = watershedsUnionFind(img_scalar_f, 8, img_scalar_i)
+    assert(res[0] is img_scalar_i)
+
+    assert_raises(RuntimeError, watershedsUnionFind, img_scalar_f, 5, img_scalar_i)
+    
+    res = watersheds(img_scalar_f, seeds=img_scalar_i, method="RegionGrowing")
+    checkShape(img_scalar_f, res[0])
+    checkType(res[0], np.uint32)
+
+    # 3D
+    res = watershedsUnionFind(vol_scalar_f, 6)
+    checkShape(vol_scalar_f, res[0])
+
+    vol_scalar_i = at.ScalarVolume(vol_scalar_f.shape, dtype=np.uint32)
+    res = watershedsUnionFind(vol_scalar_f, 26, vol_scalar_i)
+    assert(res[0] is vol_scalar_i)
+    
+    assert_raises(RuntimeError, watershedsUnionFind, img_scalar_f, 17, img_scalar_i)
+
+def test_MinimaMaxima():
+    #2D Case
+    res = localMinima(img_scalar_f)
+    checkShape(img_scalar_f,res)
+    checkType(res,img_scalar_f.dtype)
+    
+    res = extendedLocalMinima(img_scalar_f)
+    checkShape(img_scalar_f,res)
+    checkType(res,img_scalar_f.dtype)
+    
+    res = localMaxima(img_scalar_f)
+    checkShape(img_scalar_f,res)
+    checkType(res,img_scalar_f.dtype)
+    
+    res = extendedLocalMaxima(img_scalar_f)
+    checkShape(img_scalar_f,res)
+    checkType(res,img_scalar_f.dtype)
+    
+    res = labelImage(img_scalar_f)
+    checkShape(img_scalar_f,res)
+    checkType(res,np.uint32)
+    
+    res = labelImageWithBackground(img_scalar_f)
+    checkShape(img_scalar_f,res)
+    checkType(res,np.uint32)
+    
+    #3D Case
+    res = localMinima3D(vol_scalar_f)
+    checkShape(vol_scalar_f,res)
+    checkType(res,vol_scalar_f.dtype)
+    
+    res = extendedLocalMinima3D(vol_scalar_f)
+    checkShape(vol_scalar_f,res)
+    checkType(res,vol_scalar_f.dtype)
+    
+    res = localMaxima3D(vol_scalar_f)
+    checkShape(vol_scalar_f,res)
+    checkType(res,vol_scalar_f.dtype)
+    
+    res = extendedLocalMaxima3D(vol_scalar_f)
+    checkShape(vol_scalar_f,res)
+    checkType(res,vol_scalar_f.dtype)
+    
+    data = vigra.taggedView(np.zeros((100,200,50),dtype=np.float32), 
+                            vigra.defaultAxistags(3, noChannels=True))
+
+    data[10,5,10]=1
+    data[98,10,10]=1
+    data[90,50,30]=1
+    data[10,10,2]=1
+    data[10,80,8]=1
+    data[10,10,8]=1
+    data[10,150,2]=1
+    data[80,10,10]=1
+    data[70,120,40]=1
+    
+    res = localMaxima3D(data,neighborhood=26)
+    np.testing.assert_array_equal(res, data, "Error in the calculation of the Maxima")
+
+    res = extendedLocalMaxima3D(data,neighborhood=26)
+    np.testing.assert_array_equal(res, data, "Error in the calculation of the Extended Maxima")
+    
+    res = localMinima3D(1-data,neighborhood=26)
+    np.testing.assert_array_equal(res, data, "Error in the calculation of the Minima")
+    
+    res = extendedLocalMinima3D(1-data,neighborhood=26)
+    np.testing.assert_array_equal(res, data, "Error in the calculation of the Extended Minima")
+
+def test_Region2Crack():
+    res = regionImageToCrackEdgeImage(img_scalar_i)
+    assert_equal(img_scalar_f.shape[0]*2-1, res.shape[0])
+    assert_equal(img_scalar_f.shape[1]*2-1, res.shape[1])
+    checkType(res,res.dtype)
+
+    regionImageToCrackEdgeImage(img_scalar_i64[0:100,0:100], 1, img_scalar_i64)
+    checkType(img_scalar_i64, np.uint64)
+    
+    res = regionImageToEdgeImage(img_scalar_i)
+    checkShape(res,img_scalar_i)
+    
+def test_transforms():
+    res = distanceTransform2D(img_scalar_f)
+    checkShape(img_scalar_i, res)
+    #print >> sys.stderr, res.dtype,
+    checkType(res, np.float32)
+    
+    res = distanceTransform2D(img_scalar_ui8)
+    checkShape(img_scalar_ui8, res)
+    checkType(res, np.float32)
+    
+    res = radialSymmetryTransform2D(img_scalar_f,1)
+    checkShape(img_scalar_f, res)
+    checkType(res, np.float32)
+
+def test_cornerss():
+    res = cornernessHarris(img_scalar_f,1)
+    checkShape(img_scalar_f, res)
+    checkType(res, np.float32)
+    
+    res = cornernessFoerstner(img_scalar_f,2)
+    checkShape(img_scalar_f, res)
+    checkType(res, np.float32)
+    
+    res = cornernessRohr(img_scalar_f,0.5)
+    checkShape(img_scalar_f, res)
+    checkType(res, np.float32)
+    
+    res = cornernessBeaudet(img_scalar_f,1)
+    checkShape(img_scalar_f, res)
+    checkType(res, np.float32)
+
+def test_edges():    
+    res = cannyEdgeImage(img_scalar_f, 1,128,255)
+    checkShape(img_scalar_f, res)
+    checkType(res, np.uint8)
+    
+    res = cannyEdgeImageWithThinning(img_scalar_f, 1,128,255)
+    checkShape(img_scalar_f, res)
+    checkType(res, np.uint8)
+    
+    res = shenCastanEdgeImage(img_scalar_f, 1,128,255)
+    checkShape(img_scalar_f, res)
+    checkType(res, np.uint8)
+    
+    res = shenCastanCrackEdgeImage(img_scalar_f, 1,128,255)
+    assert_equal(img_scalar_f.shape[0]*2-1, res.shape[0])
+    assert_equal(img_scalar_f.shape[1]*2-1, res.shape[1])
+    
+    res1 = beautifyCrackEdgeImage(res,  1, 0)
+    checkShape(res1, res)
+    checkType(res1, np.uint8)
+    
+    res1 = closeGapsInCrackEdgeImage(res, 4)
+    checkShape(res1, res)
+    checkType(res1, np.uint8)
+    
+    res = removeShortEdges(img_scalar_ui8, 10, 0)
+    checkShape(img_scalar_ui8, res)
+    checkType(res, np.uint8)
+    
+    res = boundaryTensor2D(img_scalar_f, 1)
+    assert_equal(img_scalar_f.shape[0], res.shape[0])
+    assert_equal(img_scalar_f.shape[1], res.shape[1])
+    assert_equal(res.shape[2], 3)    
+    checkType(res, np.float32)
+    
+    res = hourGlassFilter2D(img_multi_f, 1, 2)
+    assert_equal(img_multi_f.shape[0], res.shape[0])
+    assert_equal(img_multi_f.shape[1], res.shape[1])
+    checkType(res, np.float32)
+    
+    res = tensorEigenRepresentation2D(img_multi_f)
+    assert_equal(img_multi_f.shape[0], res.shape[0])
+    assert_equal(img_multi_f.shape[1], res.shape[1])
+    checkType(res, np.float32)
+    
+    res = tensorTrace(img_multi_f)
+    assert_equal(img_multi_f.shape[0], res.shape[0])
+    assert_equal(img_multi_f.shape[1], res.shape[1])
+    checkType(res, np.float32)
+    
+    res = rieszTransformOfLOG2D(img_scalar_f, 1, 1, 1)
+    assert_equal(img_multi_f.shape[0], res.shape[0])
+    assert_equal(img_multi_f.shape[1], res.shape[1])
+    checkType(res, np.float32)
+    
+    
+def ok_():
+    print >> sys.stderr, ".",
+        
diff --git a/vigranumpy/test/test2.py b/vigranumpy/test/test2.py
new file mode 100644
index 0000000..0717bc9
--- /dev/null
+++ b/vigranumpy/test/test2.py
@@ -0,0 +1,173 @@
+#######################################################################
+#
+#         Copyright 2009-2010 by Ullrich Koethe
+#
+#    This file is part of the VIGRA computer vision library.
+#    The VIGRA Website is
+#        http://hci.iwr.uni-heidelberg.de/vigra/
+#    Please direct questions, bug reports, and contributions to
+#        ullrich.koethe at iwr.uni-heidelberg.de    or
+#        vigra at informatik.uni-hamburg.de
+#
+#    Permission is hereby granted, free of charge, to any person
+#    obtaining a copy of this software and associated documentation
+#    files (the "Software"), to deal in the Software without
+#    restriction, including without limitation the rights to use,
+#    copy, modify, merge, publish, distribute, sublicense, and/or
+#    sell copies of the Software, and to permit persons to whom the
+#    Software is furnished to do so, subject to the following
+#    conditions:
+#
+#    The above copyright notice and this permission notice shall be
+#    included in all copies or substantial portions of the
+#    Software.
+#
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+#    OTHER DEALINGS IN THE SOFTWARE.
+#
+#######################################################################
+
+import sys
+print >> sys.stderr, "\nexecuting test file", __file__
+execfile('set_paths.py')
+
+from nose.tools import assert_equal, raises
+import numpy as np
+from vigra import *
+from vigra.filters import *
+from vigra.sampling import *
+from vigra.noise import *
+import vigra.arraytypes as at
+
+#in the hope, that functions are tested in C++, we basicly test return types
+
+#image=readImage("/export/home/nhuesken/sas/experiments/testdata/bmpmultilabel.bmp")
+image=at.RGBImage(np.random.rand(100,100,3)*255,dtype=np.float32)
+scalar_image=at.ScalarImage(np.random.rand(100,100)*255,dtype=np.float32)
+volume256=at.Volume(np.random.rand(100,100,100)*255,dtype=np.uint8)
+volumeBin=at.Volume(np.random.rand(100,100,100))>0.5
+
+def checkImages(i1,i2):
+    assert(i1.shape==i2.shape)
+    assert(np.sum(i1==i2)!=0)
+
+def checkAboutSame(i1,i2):
+    assert(i1.shape==i2.shape)
+    difference=np.sum(np.abs(i1-i2))/float(np.size(i1))
+    assert(difference<5)
+
+def test_simpleRotate():
+    i2=rotateImageSimple(image,orientation=RotationDirection.CLOCKWISE);
+    #simple basic test
+    assert(i2.shape[0] == image.shape[1])
+    assert(i2.shape[1] == image.shape[0])
+    #test, that they are compatible
+    i3=rotateImageSimple(i2,orientation=RotationDirection.COUNTER_CLOCKWISE);
+    checkImages(image,i3)
+    i2=rotateImageSimple(image,orientation=RotationDirection.UPSIDE_DOWN);
+    i3=rotateImageSimple(i2,orientation=RotationDirection.COUNTER_CLOCKWISE);
+    i2=rotateImageSimple(i3,orientation=RotationDirection.COUNTER_CLOCKWISE);
+    checkImages(image,i2)
+
+def test_rotate():
+    i2=rotateImageSimple(image)
+    i3=i2
+    rotateImageDegree(image,degree=90,out=i3)
+    checkImages(i2,i3)
+
+def test_resample():
+    #just testing the size
+    i2=resampleImage(image,factor=0.5)
+    assert(i2.shape[0]==image.shape[0]*0.5)
+    
+    
+def test_resize():
+    i2=resizeImageNoInterpolation(image,shape=(image.shape[0]+10,image.shape[1]+10))
+    i2=resizeImageNoInterpolation(image,shape=(image.shape[0],image.shape[1]))
+    checkAboutSame(i2,image)
+
+    i2=resizeImageCatmullRomInterpolation(image,shape=(image.shape[0]+10,image.shape[1]+10))
+    i2=resizeImageCatmullRomInterpolation(image,shape=(image.shape[0],image.shape[1]))
+    checkAboutSame(i2,image)
+
+    i2=resizeImageCoscotInterpolation( image,shape=(image.shape[0]+10,image.shape[1]+10))
+    i2=resizeImageCoscotInterpolation( image,shape=(image.shape[0],image.shape[1]))
+    checkAboutSame(i2,image)
+
+    i2=resizeImageLinearInterpolation( image,shape=(image.shape[0]+10,image.shape[1]+10))
+    i2=resizeImageLinearInterpolation( image,shape=(image.shape[0],image.shape[1]))
+    checkAboutSame(i2,image)
+
+    i2=resizeImageSplineInterpolation(
+        image,shape=(image.shape[0]+10,image.shape[1]+10),order=4)
+    i2=resizeImageSplineInterpolation(
+        image,shape=(image.shape[0],image.shape[1]), order=4)
+    checkAboutSame(i2,image)
+
+def test_2DMorphology():
+    i2=discErosion(image.astype(np.uint8),radius=2)
+    i3=(255-discDilation((256-image).astype(np.uint8),radius=2))
+    checkImages(i2,i3)
+    i2=discOpening(image.astype(np.uint8),radius=2)
+    i3=(255-discDilation((256-image).astype(np.uint8),radius=2))
+    checkImages(i2,i3)
+
+
+def test_3DMorphologyBinary():
+    i3=0
+    i2=multiBinaryClosing(volumeBin,radius=2)
+    i3=multiBinaryOpening(volumeBin==False,radius=2)
+    i3=i3==False
+    checkImages(i2,i3)
+
+def test_3DMorphologyGrayscale():
+    i2=multiGrayscaleErosion(volume256,sigma=2)
+    i3=(256-multiGrayscaleDilation(256-volume256,sigma=2))
+    checkImages(i2,i3)
+    i2=multiGrayscaleOpening(volume256,sigma=2)
+    i3=(256-multiGrayscaleClosing(256-volume256,sigma=2))
+    checkImages(i2,i3)
+
+def test_Noise():
+    # ATM, we only test that these things run
+    
+    image = RGBImage((100,100))
+    image[:50,:50] = (10, 10, 10)
+    image[50:,:50] = (20, 20, 20)
+    image[50:,50:] = (30, 30, 30)
+    image += np.random.normal(size=(100,100, 3))
+    
+    noiseVarianceEstimation(image.bindAxis('c', 0))
+    noiseVarianceClustering(image.bindAxis('c', 0))
+    nonparametricNoiseNormalization(image)
+    quadraticNoiseNormalizationEstimated(image)
+    linearNoiseNormalizationEstimated(image)
+    quadraticNoiseNormalization(image,1.0,1.0,1.0)
+    linearNoiseNormalization(image,1.0,1.0)
+    
+def test_Kernel1D():
+    # we just test functions that were not directly imported
+    contents = np.array([-1,2,3,5,3,2,-1], dtype=np.float64)
+    k1 = Kernel1D()
+    k1.initExplicitly(-3,3, contents)
+    for k in xrange(-3, 4):
+        assert(k1[k]==contents[k+3])
+    k1[-2]=5
+    assert(k1[-2]==5)
+
+def test_Kernel2D():
+    contents = np.array([[0,1,2],[3,4,5],[6,7,8]],dtype=np.float64)
+    k2=Kernel2D()
+    k2.initExplicitly((-1,-1),(1,1), contents)
+    for i in xrange(-1, 2):
+        for j in xrange(-1, 2):
+            assert(k2[i,j]==contents[i+1, j+1])
+    k2[0,-1]=-5
+    assert(k2[0,-1]==-5)
+
diff --git a/vigranumpy/test/test3.py b/vigranumpy/test/test3.py
new file mode 100644
index 0000000..2e48369
--- /dev/null
+++ b/vigranumpy/test/test3.py
@@ -0,0 +1,124 @@
+#######################################################################
+#                                                                      
+#         Copyright 2009-2010 by Ullrich Koethe                        
+#                                                                      
+#    This file is part of the VIGRA computer vision library.           
+#    The VIGRA Website is                                              
+#        http://hci.iwr.uni-heidelberg.de/vigra/                       
+#    Please direct questions, bug reports, and contributions to        
+#        ullrich.koethe at iwr.uni-heidelberg.de    or                    
+#        vigra at informatik.uni-hamburg.de                               
+#                                                                      
+#    Permission is hereby granted, free of charge, to any person       
+#    obtaining a copy of this software and associated documentation    
+#    files (the "Software"), to deal in the Software without           
+#    restriction, including without limitation the rights to use,      
+#    copy, modify, merge, publish, distribute, sublicense, and/or      
+#    sell copies of the Software, and to permit persons to whom the    
+#    Software is furnished to do so, subject to the following          
+#    conditions:                                                       
+#                                                                      
+#    The above copyright notice and this permission notice shall be    
+#    included in all copies or substantial portions of the             
+#    Software.                                                         
+#                                                                      
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     
+#    OTHER DEALINGS IN THE SOFTWARE.                                   
+#                                                                      
+#######################################################################
+
+import sys
+print >> sys.stderr, "\nexecuting test file", __file__
+execfile('set_paths.py')
+
+from nose.tools import assert_equal, raises
+from vigra import numpy as np
+from vigra import *
+from vigra import arraytypes as at
+from vigra.filters import *
+from vigra.analysis import *
+
+img_rgb_f = at.RGBImage(np.random.rand(100,200,3)*255,dtype=np.float32)
+img_scalar_f = at.ScalarImage(np.random.rand(100,200)*255,dtype=np.float32)
+img_multi_f = at.Vector4Image(np.random.rand(100,200,4)*255,dtype=np.float32)
+img_3_f = at.Vector3Image(np.random.rand(100,200,3)*255,dtype=np.float32)
+ 
+img_rgb_i = at.RGBImage(np.random.rand(100,200,3)*255,dtype=np.int32)
+img_scalar_i = at.ScalarImage(np.random.rand(100,200)*255,dtype=np.int32)
+img_multi_i = at.Vector4Image(np.random.rand(100,200,4)*255,dtype=np.int32)
+
+vol_rgb_f = at.RGBVolume(np.random.rand(100,200,60,3)*255,dtype=np.float32)
+vol_scalar_f = at.ScalarVolume(np.random.rand(100,200,50)*255,dtype=np.float32)
+vol_multi_f = at.Vector6Volume(np.random.rand(100,200,50,6)*255,dtype=np.float32)
+ 
+vol_rgb_i = at.RGBVolume(np.random.rand(100,200,60,3)*255,dtype=np.int32)
+vol_scalar_i = at.ScalarVolume(np.random.rand(100,200,50)*255,dtype=np.int32)
+vol_multi_i = at.Vector6Volume(np.random.rand(100,200,50,6)*255,dtype=np.int32)
+
+def checkShape(shape1, shape2):
+    if isinstance(shape1, np.ndarray):
+        shape1 = shape1.shape
+    if isinstance(shape2, np.ndarray):
+        shape2 = shape2.shape
+    assert_equal(shape1, shape2)
+
+def checkImages(i1,i2):
+    checkShape(i1.shape, i2.shape)
+    assert(np.sum(i1==i2)!=0)
+
+def checkAboutSame(i1,i2):
+    checkShape(i1.shape, i2.shape)
+    difference=np.sum(np.abs(i1-i2))/float(np.size(i1))
+    assert(difference<5)
+    
+def test_watersheds():
+    res = watersheds(img_scalar_f)
+    checkShape(res[0].shape, img_scalar_f.shape)
+    
+def test_structureTensor():
+    res = structureTensor(img_scalar_f,1.0,2.0, out=img_3_f)
+    res = structureTensor(img_scalar_f,1.0,2.0)
+    res = structureTensor(img_rgb_f,1.0,2.0)
+    checkShape(res.shape, img_scalar_f.shape[:2] + (3,))
+    
+def test_simpleSharpening():
+    res = simpleSharpening2D(img_scalar_f)
+    
+def test_gaussianSharpening():
+    res = gaussianSharpening2D(img_scalar_f)
+    
+def test_convolution():
+    krnl = gaussianKernel(0.5)
+    
+    k2_ = Kernel2D()
+    k2_.initDisk(10)
+    
+    #k3 = gaussianDerivativeKernel(sigma, order)
+    #guassianDerivative(img, sx,ox,sy,oy,sz,oz)
+    #guassianDerivative(img, (sx,sy, sz), (ox, oy,oz))
+    
+    k2=Kernel2D()
+    k2.initExplicitly((-1,-1),(1,1),np.array([[0,1,2],[1,2,3],[2,3,4]],dtype=np.float64))
+    res = convolve(img_scalar_f, k2)
+
+
+def test_multiconvolution():
+   vol = vol_scalar_f
+   k=Kernel1D()
+   k.initGaussian(0.5)
+   a=convolveOneDimension(vol, 0, k)
+   a=convolveOneDimension(a, 1, k)
+   a=convolveOneDimension(a, 2, k)
+         
+   b=convolve(vol, k)
+     
+   c=convolve(vol, (k, k, k))
+   checkAboutSame(a, b)
+   checkAboutSame(a, c)
+    
diff --git a/vigranumpy/test/test_arraytypes.py b/vigranumpy/test/test_arraytypes.py
new file mode 100644
index 0000000..4c14036
--- /dev/null
+++ b/vigranumpy/test/test_arraytypes.py
@@ -0,0 +1,1579 @@
+#######################################################################
+#                                                                      
+#         Copyright 2009-2010 by Ullrich Koethe                        
+#                                                                      
+#    This file is part of the VIGRA computer vision library.           
+#    The VIGRA Website is                                              
+#        http://hci.iwr.uni-heidelberg.de/vigra/                       
+#    Please direct questions, bug reports, and contributions to        
+#        ullrich.koethe at iwr.uni-heidelberg.de    or                    
+#        vigra at informatik.uni-hamburg.de                               
+#                                                                      
+#    Permission is hereby granted, free of charge, to any person       
+#    obtaining a copy of this software and associated documentation    
+#    files (the "Software"), to deal in the Software without           
+#    restriction, including without limitation the rights to use,      
+#    copy, modify, merge, publish, distribute, sublicense, and/or      
+#    sell copies of the Software, and to permit persons to whom the    
+#    Software is furnished to do so, subject to the following          
+#    conditions:                                                       
+#                                                                      
+#    The above copyright notice and this permission notice shall be    
+#    included in all copies or substantial portions of the             
+#    Software.                                                         
+#                                                                      
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     
+#    OTHER DEALINGS IN THE SOFTWARE.                                   
+#                                                                      
+#######################################################################
+
+# run with a simple 'nosetests' in this directory
+# (and nose installed, i.e. 'easy_install nose')
+
+import sys
+print >> sys.stderr, "\nexecuting test file", __file__
+execfile('set_paths.py')
+
+# import vigra  # FIXME: without this line, C++ constructors don't find VigraArray
+import vigra.arraytypes as arraytypes
+import vigra.ufunc as ufunc
+import numpy, copy
+import vigranumpytest as vt
+from nose.tools import assert_equal, raises, assert_true
+
+from vigra.arraytypes import AxisTags, AxisInfo
+
+numpyHasComplexNegateBug = numpy.version.version.startswith('1.0')
+
+try:
+    vt.testAny()
+except Exception, e:
+    ArgumentError = type(e)
+    
+allTests = set()
+for n, f in vt.__dict__.items():
+    if n.startswith('test'):
+        allTests.add(n)
+ 
+def checkShape(shape1, shape2):
+    assert_equal(shape1, shape2)
+
+def checkStride(stride1, stride2):
+    assert_equal(stride1, stride2)
+    
+def computeFStrides(shape):
+    return tuple(numpy.cumprod((1,)+shape[:-1]))
+
+def computeCStrides(shape):
+    return tuple(reversed(computeFStrides(tuple(reversed(shape)))))
+
+def computeVStrides(shape, hasChannelAxis):
+    if not hasChannelAxis:
+        return computeFStrides(shape)
+    stride = computeFStrides(shape[-1:] + shape[:-1])   
+    return stride[1:] + stride[0:1]
+
+def checkArray(cls, channels, dim, hasChannelAxis=True):
+        def testCopy(img):
+            b = cls(img, order='A')
+            assert_equal(sys.getrefcount(b), 2)
+            assert b.__class__ is img.__class__
+            assert_equal(b.shape, img.shape)
+            # print b.shape, img.shape, b.strides, img.strides
+            # assert False
+            assert_equal(b.strides, img.strides)
+            assert_equal(b.order, img.order)
+            assert_equal(b.flags.c_contiguous, img.flags.c_contiguous)
+            assert_equal(b.flags.f_contiguous, img.flags.f_contiguous)
+            assert (b == img).all()
+            assert not numpy.may_share_memory(b, img)
+            b = img.copy(order='A')
+            assert_equal(sys.getrefcount(b), 2)
+            assert_equal(b.shape, img.shape)
+            assert_equal(b.strides, img.strides)
+            assert_equal(b.order, img.order)
+            assert_equal(b.flags.c_contiguous, img.flags.c_contiguous)
+            assert_equal(b.flags.f_contiguous, img.flags.f_contiguous)
+            assert (b == img).all()
+            assert not numpy.may_share_memory(b, img)
+        
+        shape = (channels, 5, 10, 20)
+        axistags = [AxisInfo.c, AxisInfo.x, AxisInfo.y, AxisInfo.z]
+        axistags3 = AxisTags(AxisInfo.y, AxisInfo.z, AxisInfo.x)
+        axistags4 = AxisTags(AxisInfo.y, AxisInfo.z, AxisInfo.x, AxisInfo.c)
+        axistags5 = AxisTags(AxisInfo.c, AxisInfo.x, AxisInfo.y, AxisInfo.z, AxisInfo.t)
+        
+        # figure out expected strides and axistags
+        s = 0 if hasChannelAxis else 1
+        d = dim + 1
+        fshape = shape[s:d]
+        fstrides = computeFStrides(fshape)
+        faxistags = AxisTags(axistags[s:d])
+        
+        cshape = tuple(reversed(fshape))
+        cstrides = computeCStrides(cshape)
+        caxistags = AxisTags(list(reversed(faxistags)))
+        
+        vshape = fshape[1-s:d] + fshape[:1-s]
+        vstrides = computeVStrides(vshape, hasChannelAxis)
+        vaxistags = AxisTags(axistags[1:d] + axistags[:1-s])
+        
+        fcstrides = tuple([k*4 for k in cstrides])
+        fvstrides = tuple([k*4 for k in vstrides])
+        ffstrides = tuple([k*4 for k in fstrides])
+        
+        value = 1 if channels == 1 else range(1,channels+1)
+
+        # test type
+        img = cls(vshape, order="V")
+#        assert type(img) is cls
+        assert isinstance(img, numpy.ndarray)
+        assert_equal(img.dtype, numpy.float32)
+        assert_equal(sys.getrefcount(img), 2)        
+        
+        # test shape
+        checkShape(img.shape, vshape)
+        assert_equal(img.width, vshape[0])
+        assert_equal(img.height, vshape[1])
+        if dim == 3:
+            assert_equal(img.depth, vshape[2])
+        assert_equal(img.channels, channels)
+        assert_equal(img.spatialDimensions, dim)
+       
+        # test strides and order
+        checkStride(img.strides, fvstrides)
+        assert_equal(img.order, "V" if hasChannelAxis else "F")
+        assert_equal(img.flags.c_contiguous, False)
+        assert_equal(img.flags.f_contiguous, False if hasChannelAxis else True)
+        
+        # test axistags
+        assert_equal(img.axistags, vaxistags)
+        assert_equal(img.view5D('F').axistags, axistags5)
+        assert_equal(img.withAxes('y', 'z', 'x', 'c').axistags, axistags4)
+        if img.channels == 1:
+            assert_equal(img.withAxes('y', 'z', 'x').axistags, axistags3)
+        else:
+            try:
+                img.withAxes('y', 'z', 'x')
+                raise AssertionError, "img.withAxes() failed to throw on non-singleton channel."
+            except RuntimeError:
+                pass
+        # FIXME: add more tests
+
+        # test initialization and assignment
+        assert_equal(img.min(), 0.0)
+        assert_equal(img.max(), 0.0)
+        img = cls(vshape, order="V", value=99.0)
+        assert_equal(img.min(), 99.0)
+        assert_equal(img.max(), 99.0)
+        img.flat[:] = range(img.size)
+        assert_equal(img.flatten().tolist(), range(img.size))
+        img[1,2] = value
+        assert_equal((img[1,2]==value).all(), True)
+
+        # test that copy and ufuncs preserve memory layout
+        testCopy(img)
+        assert_equal(img.shape, (-img).shape)
+        assert_equal(img.strides, (-img).strides)
+        assert_equal(img.axistags, (-img).axistags)
+        assert_equal(img.shape, (img+img).shape)
+        assert_equal(img.strides, (img+img).strides)
+        assert_equal(img.axistags, (img+img).axistags)
+        assert_equal(img.shape, (img*2).shape)
+        assert_equal(img.strides, (img*2).strides)
+        assert_equal(img.axistags, (img*2).axistags)
+        
+        # test shape, strides, and copy for 'F' order
+        img = cls(fshape, order='F')
+        assert_equal(sys.getrefcount(img), 2)
+        checkShape(img.shape, fshape)
+        checkStride(img.strides, ffstrides)
+        assert_equal(img.axistags, faxistags)
+        assert_equal(img.order, "F")
+        assert_equal(img.flags.c_contiguous, False)
+        assert_equal(img.flags.f_contiguous, True)
+        
+        assert_equal(img.min(), 0.0)
+        assert_equal(img.max(), 0.0)
+        img = cls(fshape, order="F", value=99.0)
+        assert_equal(img.min(), 99.0)
+        assert_equal(img.max(), 99.0)
+
+        if dim == 2:
+            img[...,1,2] = value
+        else:
+            img[...,0,1,2] = value
+        testCopy(img)
+        assert_equal(img.strides, (-img).strides)
+        assert_equal(img.strides, (img+img).strides)
+        assert_equal(img.strides, (img*2).strides)
+        assert_equal(img.axistags, (-img).axistags)
+        assert_equal(img.axistags, (img+img).axistags)
+        assert_equal(img.axistags, (img*2).axistags)
+        assert_equal(img.view5D('F').axistags, axistags5)
+        assert_equal(img.withAxes('y', 'z', 'x', 'c').axistags, axistags4)
+
+        # test shape, strides, and copy for 'A' order (should be equal to 'V' order)
+        img = cls(vshape, order='A')
+        assert_equal(sys.getrefcount(img), 2)
+        checkShape(img.shape, vshape)
+        checkStride(img.strides, fvstrides)
+        assert_equal(img.order, "V" if hasChannelAxis else "F")
+        assert_equal(img.flags.c_contiguous, False)
+        assert_equal(img.flags.f_contiguous, False if hasChannelAxis else True)
+        assert_equal(img.axistags, vaxistags)
+        img[1,2] = value
+        testCopy(img)
+        assert_equal(img.strides, (-img).strides)
+        assert_equal(img.strides, (img+img).strides)
+        assert_equal(img.strides, (img*2).strides)
+        assert_equal(img.axistags, (-img).axistags)
+        assert_equal(img.axistags, (img+img).axistags)
+        assert_equal(img.axistags, (img*2).axistags)
+
+        # test shape, strides, and copy for 'C' order
+        img = cls(cshape, order='C')
+        assert_equal(sys.getrefcount(img), 2)
+        checkShape(img.shape, cshape)
+        checkStride(img.strides, fcstrides)
+        assert_equal(img.axistags, caxistags)
+        assert_equal(img.order, "C")
+        assert_equal(img.flags.c_contiguous, True)
+        assert_equal(img.flags.f_contiguous, False)
+        
+        assert_equal(img.min(), 0.0)
+        assert_equal(img.max(), 0.0)
+        img = cls(cshape, order="C", value=99.0)
+        assert_equal(img.min(), 99.0)
+        assert_equal(img.max(), 99.0)
+        
+        img[1,2] = value
+        testCopy(img)
+        assert_equal(img.strides, (-img).strides)
+        assert_equal(img.strides, (img+img).strides)
+        assert_equal(img.strides, (img*2).strides)
+        assert_equal(img.axistags, (-img).axistags)
+        assert_equal(img.axistags, (img+img).axistags)
+        assert_equal(img.axistags, (img*2).axistags)
+        assert_equal(img.view5D('F').axistags, axistags5)
+        assert_equal(img.withAxes('y', 'z', 'x', 'c').axistags, axistags4)
+
+        value = 10 if channels == 1 else range(10,channels+10)
+        zero = 0 if channels == 1 else (0,)*channels
+        
+        # test shape, strides, and copy for dtype uint8
+        img = cls(vshape, order="V")
+        b = cls(img, dtype=numpy.uint8, order='V')
+        assert_equal(sys.getrefcount(b), 2)
+        assert_equal(b.dtype, numpy.uint8)
+        checkShape(b.shape, img.shape)
+        checkStride(b.strides, computeVStrides(b.shape, hasChannelAxis))
+        assert_equal(img.order, "V" if hasChannelAxis else "F")
+        assert_equal(b.axistags, img.axistags)
+        assert_equal(b.flags.c_contiguous, False)
+        assert_equal(b.flags.f_contiguous, False if hasChannelAxis else True)
+        assert (b==img).all()
+        b[2,1] = value
+        assert (b[2,1]==value).all()
+        assert (img[2,1]==zero).all()
+        assert_equal(b.strides, (-b).strides)
+        assert_equal(b.strides, (b+b).strides)
+        assert_equal(b.strides, (b*2).strides)
+        assert_equal(b.axistags, (-b).axistags)
+        assert_equal(b.axistags, (b+b).axistags)
+        assert_equal(b.axistags, (b*2).axistags)
+
+        img = cls(cshape, order="C")
+        b = cls(img, dtype=numpy.uint8, order='C')
+        assert_equal(sys.getrefcount(b), 2)
+        checkShape(b.shape, img.shape)
+        checkStride(b.strides, computeCStrides(b.shape))
+        assert_equal(b.axistags, img.axistags)
+        assert_equal(b.order, "C")
+        assert b.flags.c_contiguous
+        assert not b.flags.f_contiguous
+        assert (b==img).all()
+        assert_equal(b.strides, (-b).strides)
+        assert_equal(b.strides, (b+b).strides)
+        assert_equal(b.strides, (b*2).strides)
+        assert_equal(b.axistags, (-b).axistags)
+        assert_equal(b.axistags, (b+b).axistags)
+        assert_equal(b.axistags, (b*2).axistags)
+        
+        img = cls(fshape, order="F")
+        b = cls(img, dtype=numpy.uint8, order='F')
+        assert_equal(sys.getrefcount(b), 2)
+        checkShape(b.shape, img.shape)
+        checkStride(b.strides, computeFStrides(b.shape))
+        assert_equal(b.axistags, img.axistags)
+        assert_equal(b.order, "F")
+        assert not b.flags.c_contiguous
+        assert b.flags.f_contiguous
+        assert (b==img).all()
+        assert_equal(b.strides, (-b).strides)
+        assert_equal(b.strides, (b+b).strides)
+        assert_equal(b.strides, (b*2).strides)
+        assert_equal(b.axistags, (-b).axistags)
+        assert_equal(b.axistags, (b+b).axistags)
+        assert_equal(b.axistags, (b*2).axistags)
+        
+        value = 100 if channels == 1 else range(100,channels+100)
+
+        # test ndarray view
+        img = cls(vshape, order="V")
+        v1 = img.view(numpy.ndarray)
+        v2 = img.view(numpy.ndarray)
+        assert type(v1) is numpy.ndarray
+        assert (v1==v2).all()
+        assert numpy.may_share_memory(v1, img)
+        v1[3,4] = value
+        assert (v2[3,4]==value).all()
+        assert (v1==v2).all()
+
+def checkFailure(obj, n):
+    f = getattr(vt, n)
+    try:
+        f(obj)
+    except ArgumentError:
+        return
+    raise AssertionError, "%r did not throw ArgumentError as expected when passed a %r with shape %s, stride %s, axistags '%s'" % (n, type(obj), str(obj.shape), str(obj.strides), repr(getattr(obj, "axistags", "none")))
+
+def checkCompatibility(obj, compatible):
+    for n in compatible:
+        try:
+            f = getattr(vt, n)
+            shape, acopy, default_ordering, same_ordering = f(obj)
+            
+            
+            assert_equal(obj.shape, shape)
+            
+            assert_equal(obj.__class__, acopy.__class__)
+            assert_equal(obj.shape, acopy.shape)
+            if hasattr(obj, 'axistags'):
+                assert_equal(obj.axistags, acopy.axistags)
+            else:
+                assert(not hasattr(acopy, 'axistags'))
+                
+            if n != "testAny":
+                assert_equal(obj.shape, same_ordering.shape)
+                assert(obj.view(numpy.ndarray) == same_ordering.view(numpy.ndarray)).all()
+                
+                if not hasattr(obj, 'axistags'):
+                    assert_equal(numpy.ndarray, same_ordering.__class__)
+                    assert(not hasattr(same_ordering, 'axistags'))
+                    
+                    if n.startswith("testArray"):
+                        assert_equal(numpy.ndarray, default_ordering.__class__)
+                        assert_equal(obj.shape, default_ordering.shape)
+                        assert(obj.view(numpy.ndarray) == default_ordering.view(numpy.ndarray)).all()
+                        assert(not hasattr(default_ordering, 'axistags'))
+                    else:
+                        assert_equal(arraytypes.VigraArray, default_ordering.__class__)
+                        assert_equal(arraytypes.VigraArray.defaultOrder, default_ordering.order)
+                        assert_equal(default_ordering.axistags, 
+                                     arraytypes.VigraArray.defaultAxistags(default_ordering.ndim))
+                        
+                        if obj.ndim == default_ordering.ndim:
+                            assert_equal(obj.shape, default_ordering.shape)
+                            assert(obj.view(numpy.ndarray) == default_ordering.view(numpy.ndarray)).all()
+                        else:
+                            assert_equal(obj.shape + (1,), default_ordering.shape)
+                            assert(obj.view(numpy.ndarray) == default_ordering[...,0].view(numpy.ndarray)).all()
+                     
+                else:
+                    assert_equal(arraytypes.VigraArray, same_ordering.__class__)
+                    assert_equal(obj.axistags, same_ordering.axistags)
+                    
+                    if n.startswith("testArray"):
+                        assert_equal(numpy.ndarray, default_ordering.__class__)
+                        fobj = obj.transposeToNormalOrder()
+                        fshape = fobj.shape
+                        assert_equal(fshape, default_ordering.shape)
+                        assert(fobj.view(numpy.ndarray) == default_ordering.view(numpy.ndarray)).all()
+                        assert(not hasattr(default_ordering, 'axistags'))
+                    else:
+                        assert_equal(arraytypes.VigraArray, default_ordering.__class__)
+                        assert_equal(arraytypes.VigraArray.defaultOrder, default_ordering.order)
+                        dobj = obj.transposeToOrder(arraytypes.VigraArray.defaultOrder)
+                        dshape = dobj.shape
+                        assert_equal(default_ordering.axistags, 
+                                     arraytypes.VigraArray.defaultAxistags(default_ordering.ndim))
+                        if obj.ndim == default_ordering.ndim:
+                            assert_equal(dshape, default_ordering.shape)
+                            assert(dobj.view(numpy.ndarray) == default_ordering.view(numpy.ndarray)).all()
+                        else:
+                            assert_equal(dshape + (1,), default_ordering.shape)
+                            assert(fobj.view(numpy.ndarray) == default_ordering[...,0].view(numpy.ndarray)).all()
+        except Exception:
+            print "exception in %s with shape %s strides %s tags (%s)" % (n, obj.shape, obj.strides, 
+                                            repr(getattr(obj, "axistags", "none")))
+            raise
+        
+    incompatible = allTests.difference(compatible)
+    
+    for n in incompatible:
+        try:
+            checkFailure(obj, n)
+        except Exception:
+            print "exception in %s with shape %s strides %s tags (%s)" % (n, obj.shape, obj.strides, 
+                                            repr(getattr(obj, "axistags", "none")))
+            raise
+
+def testAxisTags():
+    axistags = AxisTags(AxisInfo.c(description="RGB"), 
+                        AxisInfo.ft(3.0, "time frequency"), 
+                        AxisInfo.y(0.5), 
+                        AxisInfo.z(4, "confocal depth"))
+    
+    json = '''{
+  "axes": [
+    {
+      "key": "c",
+      "typeFlags": 1,
+      "resolution": 0,
+      "description": "RGB"
+    },
+    {
+      "key": "t",
+      "typeFlags": 24,
+      "resolution": 3,
+      "description": "time frequency"
+    },
+    {
+      "key": "y",
+      "typeFlags": 2,
+      "resolution": 0.5,
+      "description": ""
+    },
+    {
+      "key": "z",
+      "typeFlags": 2,
+      "resolution": 4,
+      "description": "confocal depth"
+    }
+  ]
+}'''
+    assert_equal(axistags.toJSON(), json)
+    
+    readBack = AxisTags.fromJSON(json)
+    assert_equal(axistags, readBack)
+    assert_equal(readBack[0].description, "RGB")
+    assert_equal(readBack[1].description, "time frequency")
+    assert_equal(readBack[2].description, "")
+    assert_equal(readBack[3].description, "confocal depth")
+    assert_equal(readBack[0].resolution, 0)
+    assert_equal(readBack[1].resolution, 3)
+    assert_equal(readBack[2].resolution, 0.5)
+    assert_equal(readBack[3].resolution, 4)
+    
+    import pickle
+    s = pickle.dumps(axistags)
+    unpickled = pickle.loads(s)
+    assert_equal(axistags, unpickled)
+    assert_equal(unpickled[0].description, "RGB")
+    assert_equal(unpickled[1].description, "time frequency")
+    assert_equal(unpickled[2].description, "")
+    assert_equal(unpickled[3].description, "confocal depth")
+    assert_equal(unpickled[0].resolution, 0)
+    assert_equal(unpickled[1].resolution, 3)
+    assert_equal(unpickled[2].resolution, 0.5)
+    assert_equal(unpickled[3].resolution, 4)
+    
+    # FIXME: add more tests here
+    defaultTags = arraytypes.VigraArray.defaultAxistags('cxyt')
+    assert_equal(defaultTags.permutationToOrder('A'), (0, 1, 2, 3))
+    assert_equal(defaultTags.permutationToOrder('F'), (0, 1, 2, 3))
+    assert_equal(defaultTags.permutationToOrder('C'), (3, 2, 1, 0))
+    assert_equal(defaultTags.permutationToOrder('V'), (1, 2, 3, 0))
+    assert_equal(defaultTags.permutationToNormalOrder(), (0, 1, 2, 3))
+    assert_equal(defaultTags.permutationToNumpyOrder(), (3, 2, 1, 0))
+    assert_equal(defaultTags.permutationToVigraOrder(), (1, 2, 3, 0))
+    assert_equal(defaultTags.permutationFromNormalOrder(), (0, 1, 2, 3))
+    assert_equal(defaultTags.permutationFromNumpyOrder(), (3, 2, 1, 0))
+    assert_equal(defaultTags.permutationFromVigraOrder(), (3, 0, 1, 2))
+    
+    defaultTags = arraytypes.AxisTags(4)
+    assert_equal(defaultTags.permutationToOrder('A'), (0, 1, 2, 3))
+    assert_equal(defaultTags.permutationToOrder('F'), (0, 1, 2, 3))
+    assert_equal(defaultTags.permutationToOrder('C'), (3, 2, 1, 0))
+    assert_equal(defaultTags.permutationToOrder('V'), (0, 1, 2, 3))
+
+    assert_equal(arraytypes.VigraArray.defaultAxistags('cxyz'),
+                 arraytypes.VigraArray.defaultAxistags(4, order='F'))
+    assert_equal(arraytypes.VigraArray.defaultAxistags('zyxc'),
+                 arraytypes.VigraArray.defaultAxistags(4, order='C'))
+    assert_equal(arraytypes.VigraArray.defaultAxistags('xyzc'),
+                 arraytypes.VigraArray.defaultAxistags(4, order='V'))
+    assert_equal(arraytypes.VigraArray.defaultAxistags('xyzc'),
+                 arraytypes.VigraArray.defaultAxistags(4, order='A'))
+
+    for order in 'VCF':
+        defaultTags = arraytypes.VigraArray.defaultAxistags(3, order=order)
+        assert_equal(defaultTags.permutationToOrder(order), (0, 1, 2))
+        assert (defaultTags.channelIndex == 0 if order == 'F' else 2)
+        
+        defaultTags.transpose(defaultTags.permutationToOrder('V'))
+        assert_equal(defaultTags.permutationToVigraOrder(), (0, 1, 2))
+        assert (defaultTags.channelIndex == 2)
+        
+        defaultTags = arraytypes.VigraArray.defaultAxistags(3, order=order, noChannels=True)
+        assert_equal(defaultTags.permutationToOrder(order), (0, 1, 2))
+        assert (defaultTags.channelIndex == 3)
+            
+def testImage1():
+    checkArray(arraytypes.Image, 1, 2)
+    
+    shape = (10, 20)
+    rshape = (20, 10)
+
+    c = ["testAny",
+         "testArray3Unstrided", "testArray3Strided",
+         "testImageSinglebandUnstrided", "testImageSinglebandStrided",
+         "testImageMultibandUnstrided", "testImageMultibandStrided"]
+
+    checkCompatibility(arraytypes.Image(rshape, order='C', value=2), c)
+    
+    checkCompatibility(arraytypes.Image(shape, order='V', value=2), c)
+
+    checkCompatibility(arraytypes.Image(shape, order='F', value=2), c)
+    
+    c = ["testAny",
+         "testArray2Strided",
+         "testImageSinglebandStrided",
+         "testImageMultibandStrided"]
+
+    a = numpy.ndarray(rshape, dtype=numpy.float32)
+    a[...] = 2
+    checkCompatibility(a, c)
+
+    img = arraytypes.Image(rshape, order='C').dropChannelAxis()
+    checkShape(vt.viewArray2Unstrided(img), shape)
+    assert_equal(img[0,0], 1)
+    
+    img = arraytypes.Image(shape, order='V').dropChannelAxis()
+    checkShape(vt.viewArray2Unstrided(img), shape)
+    assert_equal(img[0,0], 1)
+    
+    img = arraytypes.Image(shape, order='F').dropChannelAxis()
+    checkShape(vt.viewArray2Unstrided(img), shape)
+    assert_equal(img[0,0], 1)
+ 
+def testImage2():
+    checkArray(arraytypes.Image, 2, 2)
+    
+    shape = (10, 20, 2)
+    cshape = (20, 10, 2)
+    fshape = (2, 10, 20)
+    
+    c = ["testAny",
+         "testArray3Unstrided", "testArray3Strided",
+         "testImageVector2Unstrided", "testImageVector2Strided",
+         "testImageMultibandStrided"]
+         
+    checkCompatibility(arraytypes.Image(cshape, order='C', value=2), c)
+    
+    checkCompatibility(arraytypes.Image(shape, order='V', value=2), c)
+    
+    checkCompatibility(arraytypes.Image(fshape, order='F', value=2), c)
+    
+    c = ["testAny",
+         "testArray3Strided",
+         "testImageMultibandStrided",
+         "testImageVector2Strided",
+         "testVolumeSinglebandStrided",
+         "testVolumeMultibandStrided"]
+
+    a = numpy.ndarray(cshape, dtype=numpy.float32)
+    a[...] = 2
+    checkCompatibility(a, c)
+
+    img = arraytypes.Image(cshape, order='C')
+    assert_equal(vt.viewArray3Unstrided(img), fshape)
+    assert (img[0,0]==(1,0)).all()
+    
+    img = arraytypes.Image(shape, order='V')
+    assert_equal(vt.viewArray3Unstrided(img), fshape)
+    assert (img[0,0]==(1,0)).all()
+    
+    img = arraytypes.Image(fshape, order='F')
+    assert_equal(vt.viewArray3Strided(img), fshape)
+    assert (img[:,0,0]==(1,0)).all()
+    
+    img = arraytypes.Image(cshape, order='C')
+    assert_equal(vt.viewImageVector2Strided(img), shape[:-1])
+    assert (img[0,0]==(1,1)).all()
+    
+    img = arraytypes.Image(shape, order='V')
+    assert_equal(vt.viewImageVector2Unstrided(img), shape[:-1])
+    assert (img[0,0]==(1,1)).all()
+ 
+def testScalarImage():
+    checkArray(arraytypes.ScalarImage, 1, 2, False)
+    
+    shape = (10, 20)
+    cshape = (20, 10)
+
+    c = ["testAny",
+         "testArray2Unstrided", "testArray2Strided",
+         "testImageSinglebandUnstrided", "testImageSinglebandStrided",
+         "testImageMultibandUnstrided", "testImageMultibandStrided"]
+         
+    checkCompatibility(arraytypes.ScalarImage(cshape, order='C', value=2), c)
+    
+    checkCompatibility(arraytypes.ScalarImage(shape, order='V', value=2), c)
+    
+    checkCompatibility(arraytypes.ScalarImage(shape, order='F', value=2), c)
+    
+    c = ["testAny",
+         "testArray2Strided",
+         "testImageSinglebandStrided",
+         "testImageMultibandStrided"]
+         
+    checkCompatibility(arraytypes.ScalarImage(cshape, order='C', value=2).view(numpy.ndarray), c)
+
+    img = arraytypes.ScalarImage(cshape, order='C')
+    checkShape(vt.viewArray2Unstrided(img), shape)
+    assert_equal(img[0,0], 1)
+    
+    img = arraytypes.ScalarImage(shape, order='V')
+    checkShape(vt.viewArray2Unstrided(img), shape)
+    assert_equal(img[0,0], 1)
+    
+    img = arraytypes.ScalarImage(shape, order='F')
+    checkShape(vt.viewArray2Strided(img), shape)
+    assert_equal(img[0,0], 1)
+ 
+def testRGBImage():
+    checkArray(arraytypes.RGBImage, 3, 2)
+    
+    cshape = (20, 10)
+    shape = (10, 20)
+    rshape = (3, 10, 20)
+
+    c = ["testAny",
+         "testArray3Unstrided", "testArray3Strided",
+         "testImageRGBUnstrided", "testImageRGBStrided",
+         "testImageMultibandStrided"]
+         
+    checkCompatibility(arraytypes.RGBImage(cshape, order='C', value=2), c)
+    
+    checkCompatibility(arraytypes.RGBImage(shape, order='V', value=2), c)
+
+    checkCompatibility(arraytypes.RGBImage(shape, order='F', value=2), c)
+    
+    c = ["testAny",
+         "testArray3Strided",
+         "testImageMultibandStrided",
+         "testImageRGBStrided",
+         "testVolumeSinglebandStrided",
+         "testVolumeMultibandStrided"]
+
+    checkCompatibility(arraytypes.RGBImage(cshape, order='C', value=2).view(numpy.ndarray), c)
+
+    img = arraytypes.RGBImage(cshape, order='C')
+    assert_equal(vt.viewArray3Unstrided(img), rshape)
+    assert (img[0,0]==(1,0,0)).all()
+    
+    img = arraytypes.RGBImage(shape, order='V')
+    assert_equal(vt.viewArray3Unstrided(img), rshape)
+    assert (img[0,0]==(1,0,0)).all()
+    
+    img = arraytypes.RGBImage(shape, order='F')
+    assert_equal(vt.viewArray3Strided(img), rshape)
+    assert (img[:,0,0]==(1,0,0)).all()
+    
+    img = arraytypes.RGBImage(cshape, order='C')
+    assert_equal(vt.viewImageRGBUnstrided(img), shape)
+    assert (img[0,0]==(1,1,1)).all()
+    
+    img = arraytypes.RGBImage(shape, order='V')
+    assert_equal(vt.viewImageRGBStrided(img), shape)
+    assert (img[0,0]==(1,1,1)).all()
+ 
+def testVector2Image():
+    checkArray(arraytypes.Vector2Image, 2, 2)
+    
+    cshape = (20, 10)
+    shape = (10, 20)
+    rshape = (2, 10, 20)
+
+    c = ["testAny",
+         "testArray3Unstrided", "testArray3Strided",
+         "testImageVector2Unstrided", "testImageVector2Strided",
+         "testImageMultibandStrided"]
+         
+    checkCompatibility(arraytypes.Vector2Image(cshape, order='C', value=2), c)
+    
+    checkCompatibility(arraytypes.Vector2Image(shape, order='V', value=2), c)
+    
+    checkCompatibility(arraytypes.Vector2Image(shape, order='F', value=2), c)
+    
+    c = ["testAny",
+         "testArray3Strided",
+         "testImageMultibandStrided",
+         "testImageVector2Strided",
+         "testVolumeSinglebandStrided", 
+         "testVolumeMultibandStrided"]
+
+    checkCompatibility(arraytypes.Vector2Image(cshape, order='C', value=2).view(numpy.ndarray), c)
+
+    img = arraytypes.Vector2Image(cshape, order='C')
+    assert_equal(vt.viewArray3Unstrided(img), rshape)
+    assert (img[0,0]==(1,0)).all()
+    
+    img = arraytypes.Vector2Image(shape, order='V')
+    assert_equal(vt.viewArray3Unstrided(img), rshape)
+    assert (img[0,0]==(1,0)).all()
+    
+    img = arraytypes.Vector2Image(shape, order='F')
+    assert_equal(vt.viewArray3Strided(img), rshape)
+    assert (img[:,0,0]==(1,0)).all()
+    
+    img = arraytypes.Vector2Image(cshape, order='C')
+    assert_equal(vt.viewImageVector2Unstrided(img), shape)
+    assert (img[0,0]==(1,1)).all()
+    
+    img = arraytypes.Vector2Image(shape, order='V')
+    assert_equal(vt.viewImageVector2Unstrided(img), shape)
+    assert (img[0,0]==(1,1)).all()
+ 
+def testVector3Image():
+    checkArray(arraytypes.Vector3Image, 3, 2)
+ 
+def testVector4Image():
+    checkArray(arraytypes.Vector4Image, 4, 2)
+ 
+def testVolume1():
+    checkArray(arraytypes.Volume, 1, 3)
+    
+    shape = (5, 10, 20)
+    rshape = (20, 10, 5)
+
+    c = ["testAny",
+         "testArray4Unstrided", "testArray4Strided",
+         "testVolumeSinglebandUnstrided", "testVolumeSinglebandStrided",
+         "testVolumeMultibandUnstrided", "testVolumeMultibandStrided"]
+         
+    checkCompatibility(arraytypes.Volume(rshape, order='C', value=2), c)
+    
+    checkCompatibility(arraytypes.Volume(shape, order='V', value=2), c)
+    
+    checkCompatibility(arraytypes.Volume(shape, order='F', value=2), c)
+    
+    c = ["testAny",
+         "testArray3Strided",
+         "testImageMultibandStrided",
+         "testVolumeSinglebandStrided",
+         "testVolumeMultibandStrided"]
+
+    a = numpy.ndarray(rshape, dtype=numpy.float32)
+    a[...] = 2
+    checkCompatibility(a, c)
+
+    vol = arraytypes.Volume(rshape, order='C').dropChannelAxis()
+    checkShape(vt.viewArray3Unstrided(vol), shape)
+    assert_equal(vol[0,0,0], 1)
+    
+    vol = arraytypes.Volume(shape, order='V').dropChannelAxis()
+    checkShape(vt.viewArray3Unstrided(vol), shape)
+    assert_equal(vol[0,0,0], 1)
+    
+    vol = arraytypes.Volume(shape, order='F').dropChannelAxis()
+    checkShape(vt.viewArray3Unstrided(vol), shape)
+    assert_equal(vol[0,0,0], 1)
+ 
+def testVolume2():
+    checkArray(arraytypes.Volume, 2, 3)
+    
+    shape = (5, 10, 20, 2)
+    cshape = (20, 10, 5, 2)
+    fshape = (2, 5, 10, 20)
+        
+    c = ["testAny",
+         "testArray4Unstrided", "testArray4Strided",
+         "testVolumeVector2Unstrided", "testVolumeVector2Strided",
+         "testVolumeMultibandStrided"]
+         
+    checkCompatibility(arraytypes.Volume(cshape, order='C', value=2), c)
+    
+    checkCompatibility(arraytypes.Volume(shape, order='V', value=2), c)
+    
+    checkCompatibility(arraytypes.Volume(fshape, order='F', value=2), c)
+        
+    c = ["testAny",
+         "testArray4Strided",
+         "testVolumeVector2Strided",
+         "testVolumeMultibandStrided"]
+         
+    a = numpy.ndarray(cshape, dtype=numpy.float32)
+    a[...] = 2
+    checkCompatibility(a, c)
+
+    vol = arraytypes.Volume(cshape, order='C')
+    assert_equal(vt.viewArray4Unstrided(vol), fshape)
+    assert (vol[0,0,0]==(1,0)).all()
+    
+    vol = arraytypes.Volume(shape, order='V')
+    assert_equal(vt.viewArray4Unstrided(vol), fshape)
+    assert (vol[0,0,0]==(1,0)).all()
+    
+    vol = arraytypes.Volume(fshape, order='F')
+    assert_equal(vt.viewArray4Strided(vol), fshape)
+    assert (vol[:,0,0,0]==(1,0)).all()
+    
+    vol = arraytypes.Volume(cshape, order='C')
+    assert_equal(vt.viewVolumeVector2Unstrided(vol), shape[:-1])
+    assert (vol[0,0,0]==(1,1)).all()
+    
+    vol = arraytypes.Volume(shape, order='V')
+    assert_equal(vt.viewVolumeVector2Unstrided(vol), shape[:-1])
+    assert (vol[0,0,0]==(1,1)).all()
+ 
+def testScalarVolume():
+    checkArray(arraytypes.ScalarVolume, 1, 3, False)
+    
+    cshape = (20, 10, 5)
+    shape = (5, 10, 20)
+
+    c = ["testAny",
+         "testArray3Unstrided", "testArray3Strided",
+         "testVolumeSinglebandUnstrided", "testVolumeSinglebandStrided",
+         "testVolumeMultibandUnstrided", "testVolumeMultibandStrided"]
+         
+    checkCompatibility(arraytypes.ScalarVolume(cshape, order='C', value=2), c)
+    
+    checkCompatibility(arraytypes.ScalarVolume(shape, order='V', value=2), c)
+    
+    checkCompatibility(arraytypes.ScalarVolume(shape, order='F', value=2), c)
+    
+    c = ["testAny",
+         "testArray3Strided",
+         "testImageMultibandStrided",
+         "testVolumeSinglebandStrided",
+         "testVolumeMultibandStrided"]
+         
+    checkCompatibility(arraytypes.ScalarVolume(cshape, order='C', value=2).view(numpy.ndarray), c)
+
+    vol = arraytypes.ScalarVolume(cshape, order='C')
+    checkShape(vt.viewArray3Unstrided(vol), shape)
+    assert_equal(vol[0,0,0], 1)
+    
+    vol = arraytypes.ScalarVolume(shape, order='V')
+    checkShape(vt.viewArray3Unstrided(vol), shape)
+    assert_equal(vol[0,0,0], 1)
+ 
+    vol = arraytypes.ScalarVolume(shape, order='F')
+    checkShape(vt.viewArray3Strided(vol), shape)
+    assert_equal(vol[0,0,0], 1)
+
+def testRGBVolume():
+    checkArray(arraytypes.RGBVolume, 3, 3)
+    
+    cshape = (20, 10, 5)
+    shape = (5, 10, 20)
+    rshape = (3, 5, 10, 20)
+
+    c = ["testAny",
+         "testArray4Unstrided", "testArray4Strided",
+         "testVolumeRGBUnstrided", "testVolumeRGBStrided",
+         "testVolumeMultibandStrided"]
+         
+    checkCompatibility(arraytypes.RGBVolume(cshape, order='C', value=2), c)
+    
+    checkCompatibility(arraytypes.RGBVolume(shape, order='V', value=2), c)
+    
+    checkCompatibility(arraytypes.RGBVolume(shape, order='F', value=2), c)
+    
+    c = ["testAny",
+         "testArray4Strided",
+         "testVolumeRGBStrided",
+         "testVolumeMultibandStrided"]
+         
+    checkCompatibility(arraytypes.RGBVolume(cshape, order='C', value=2).view(numpy.ndarray), c)
+    
+    vol = arraytypes.RGBVolume(cshape, order='C')
+    checkShape(vt.viewArray4Unstrided(vol), rshape)
+    assert (vol[0,0,0]==(1,0,0)).all()
+    
+    vol = arraytypes.RGBVolume(shape, order='V')
+    checkShape(vt.viewArray4Unstrided(vol), rshape)
+    assert (vol[0,0,0]==(1,0,0)).all()
+    
+    vol = arraytypes.RGBVolume(shape, order='F')
+    checkShape(vt.viewArray4Strided(vol), rshape)
+    assert (vol[:,0,0,0]==(1,0,0)).all()
+    
+    vol = arraytypes.RGBVolume(cshape, order='C')
+    checkShape(vt.viewVolumeRGBUnstrided(vol), shape)
+    assert (vol[0,0,0]==(1,1,1)).all()
+    
+    vol = arraytypes.RGBVolume(shape, order='V')
+    checkShape(vt.viewVolumeRGBUnstrided(vol), shape)
+    assert (vol[0,0,0]==(1,1,1)).all()
+ 
+def testVector2Volume():
+    checkArray(arraytypes.Vector2Volume, 2, 3)
+    
+    cshape = (20, 10, 5)
+    shape = (5, 10, 20)
+    rshape = (2, 5, 10, 20)
+
+    c = ["testAny",
+         "testArray4Unstrided", "testArray4Strided",
+         "testVolumeVector2Unstrided", "testVolumeVector2Strided",
+         "testVolumeMultibandStrided"]
+         
+    checkCompatibility(arraytypes.Vector2Volume(cshape, order='C', value=2), c)
+    
+    checkCompatibility(arraytypes.Vector2Volume(shape, order='V', value=2), c)
+    
+    checkCompatibility(arraytypes.Vector2Volume(shape, order='F', value=2), c)
+    
+    c = ["testAny",
+         "testArray4Strided",
+         "testVolumeVector2Strided",
+         "testVolumeMultibandStrided"]
+         
+    checkCompatibility(arraytypes.Vector2Volume(cshape, order='C', value=2).view(numpy.ndarray), c)
+    
+    vol = arraytypes.Vector2Volume(cshape, order='C')
+    checkShape(vt.viewArray4Unstrided(vol), rshape)
+    assert (vol[0,0,0]==(1,0)).all()
+    
+    vol = arraytypes.Vector2Volume(shape, order='V')
+    checkShape(vt.viewArray4Unstrided(vol), rshape)
+    assert (vol[0,0,0]==(1,0)).all()
+    
+    vol = arraytypes.Vector2Volume(shape, order='F')
+    checkShape(vt.viewArray4Strided(vol), rshape)
+    assert (vol[:,0,0,0]==(1,0)).all()
+    
+    vol = arraytypes.Vector2Volume(cshape, order='C')
+    checkShape(vt.viewVolumeVector2Unstrided(vol), shape)
+    assert (vol[0,0,0]==(1,1)).all()
+    
+    vol = arraytypes.Vector2Volume(shape, order='V')
+    checkShape(vt.viewVolumeVector2Unstrided(vol), shape)
+    assert (vol[0,0,0]==(1,1)).all()
+ 
+def testVector3Volume():
+    checkArray(arraytypes.Vector3Volume, 3, 3)
+ 
+def testVector4Volume():
+    checkArray(arraytypes.Vector4Volume, 4, 3)
+
+def testTaggedShape():
+
+    a = arraytypes.Image((20,10))
+    a.axistags.setChannelDescription("in")
+    res = vt.checkTaggedShapeMultiband(a)
+    
+    assert_equal(res[0].shape, (20,10,1))
+    assert_equal(res[0].axistags, a.axistags)
+    assert_equal(res[0].axistags[2].description, "in")
+    
+    assert_equal(res[1].shape, (20,10,1))
+    assert_equal(res[1].axistags, a.axistags)
+    assert_equal(res[1].axistags[2].description, "res2")
+    
+    assert_equal(res[2].shape, (20,10,1))
+    assert_equal(res[2].axistags, a.axistags)
+    assert_equal(res[2].axistags[2].description, "res3")
+    
+    assert_equal(res[3].shape, (20,10,3))
+    assert_equal(res[3].axistags, a.axistags)
+    assert_equal(res[3].axistags[2].description, "res4")
+    
+    assert_equal(res[4].shape, (20,10,1))
+    assert_equal(res[4].axistags, a.axistags)
+    assert_equal(res[4].axistags[2].description, "res5")
+    
+    assert_equal(res[5].shape, (20,10,3))
+    assert_equal(res[5].axistags, a.axistags)
+    assert_equal(res[5].axistags[2].description, "res6")
+
+    res = vt.checkTaggedShapeSingleband(a)
+    
+    assert_equal(res[0].shape, (20,10,1))
+    assert_equal(res[0].axistags, a.axistags)
+    assert_equal(res[0].axistags[2].description, "in")
+    
+    assert_equal(res[1].shape, (20,10,1))
+    assert_equal(res[1].axistags, a.axistags)
+    assert_equal(res[1].axistags[2].description, "res2")
+    
+    assert_equal(res[2].shape, (20,10,1))
+    assert_equal(res[2].axistags, a.axistags)
+    assert_equal(res[2].axistags[2].description, "res3")
+    
+    assert_equal(res[3].shape, (20,10,3))
+    assert_equal(res[3].axistags, a.axistags)
+    assert_equal(res[3].axistags[2].description, "res4")
+    
+    assert_equal(res[4].shape, (20,10,1))
+    assert_equal(res[4].axistags, a.axistags)
+    assert_equal(res[4].axistags[2].description, "res5")
+    
+    assert_equal(res[5].shape, (20,10,3))
+    assert_equal(res[5].axistags, a.axistags)
+    assert_equal(res[5].axistags[2].description, "res6")
+
+    a = arraytypes.Image((20,10,2))
+    a.axistags.setChannelDescription("in")
+    res = vt.checkTaggedShapeMultiband(a)
+    
+    assert_equal(res[0].shape, (20,10,2))
+    assert_equal(res[0].axistags, a.axistags)
+    assert_equal(res[0].axistags[2].description, "in")
+    
+    assert_equal(res[1].shape, (20,10,2))
+    assert_equal(res[1].axistags, a.axistags)
+    assert_equal(res[1].axistags[2].description, "res2")
+    
+    assert_equal(res[2].shape, (20,10,1))
+    assert_equal(res[2].axistags, a.axistags)
+    assert_equal(res[2].axistags[2].description, "res3")
+    
+    assert_equal(res[3].shape, (20,10,3))
+    assert_equal(res[3].axistags, a.axistags)
+    assert_equal(res[3].axistags[2].description, "res4")
+    
+    assert_equal(res[4].shape, (20,10,1))
+    assert_equal(res[4].axistags, a.axistags)
+    assert_equal(res[4].axistags[2].description, "res5")
+    
+    assert_equal(res[5].shape, (20,10,3))
+    assert_equal(res[5].axistags, a.axistags)
+    assert_equal(res[5].axistags[2].description, "res6")
+
+    a = arraytypes.ScalarImage((20,10))
+    a.axistags.setChannelDescription("in")
+    resaxistags = copy.copy(a.axistags)
+    resaxistags.insertChannelAxis()
+    
+    res = vt.checkTaggedShapeMultiband(a)
+    
+    assert_equal(res[0].shape, (20,10))
+    assert_equal(res[0].axistags, a.axistags)
+    assert_equal(len(res[0].axistags), 2)
+    
+    assert_equal(res[1].shape, (20,10))
+    assert_equal(res[1].axistags, a.axistags)
+    assert_equal(len(res[1].axistags), 2)
+    
+    assert_equal(res[2].shape, (20,10))
+    assert_equal(res[2].axistags, a.axistags)
+    assert_equal(len(res[1].axistags), 2)
+    
+    assert_equal(res[3].shape, (20,10,3))
+    assert_equal(res[3].axistags, resaxistags)
+    assert_equal(res[3].axistags[2].description, "res4")
+    
+    assert_equal(res[4].shape, (20,10))
+    assert_equal(res[4].axistags, a.axistags)
+    assert_equal(len(res[4].axistags), 2)
+    
+    assert_equal(res[5].shape, (20,10,3))
+    assert_equal(res[5].axistags, resaxistags)
+    assert_equal(res[5].axistags[2].description, "res6")
+    
+    res = vt.checkTaggedShapeSingleband(a)
+    
+    assert_equal(res[0].shape, (20,10))
+    assert_equal(res[0].axistags, a.axistags)
+    assert_equal(len(res[0].axistags), 2)
+    
+    assert_equal(res[1].shape, (20,10))
+    assert_equal(res[1].axistags, a.axistags)
+    assert_equal(len(res[1].axistags), 2)
+    
+    assert_equal(res[2].shape, (20,10))
+    assert_equal(res[2].axistags, a.axistags)
+    assert_equal(len(res[1].axistags), 2)
+    
+    assert_equal(res[3].shape, (20,10,3))
+    assert_equal(res[3].axistags, resaxistags)
+    assert_equal(res[3].axistags[2].description, "res4")
+    
+    assert_equal(res[4].shape, (20,10))
+    assert_equal(res[4].axistags, a.axistags)
+    assert_equal(len(res[4].axistags), 2)
+    
+    assert_equal(res[5].shape, (20,10,3))
+    assert_equal(res[5].axistags, resaxistags)
+    assert_equal(res[5].axistags[2].description, "res6")
+    
+    a = numpy.zeros((3,4,5))
+    at = AxisTags(AxisInfo.x, AxisInfo.y, AxisInfo.z)
+    r = arraytypes.taggedView(a, at)
+    assert_equal(r.shape, (3,4,5))
+    assert_equal(r.axistags, at)
+    assert(r.axistags is not at)
+    r = arraytypes.taggedView(a, 'xyz')
+    assert_equal(r.shape, (3,4,5))
+    assert_equal(r.axistags, at)
+ 
+def testDeepcopy():
+    a = arraytypes.RGBImage(numpy.random.random((10, 4, 3)), order='C')
+    b = copy.deepcopy(a)
+    assert numpy.all(a == b)
+    assert_equal(b.flags.c_contiguous, a.flags.c_contiguous)
+    assert_equal(b.flags.f_contiguous, a.flags.f_contiguous)
+    assert_equal(b.axistags, a.axistags)
+    a[0,0,0] += 42
+    assert b[0,0,0] != a[0,0,0]
+
+    a = arraytypes.RGBImage(numpy.random.random((4, 10, 3)), order='V')
+    b = copy.deepcopy(a)
+    assert numpy.all(a == b)
+    assert_equal(b.flags.c_contiguous, a.flags.c_contiguous)
+    assert_equal(b.flags.f_contiguous, a.flags.f_contiguous)
+    assert_equal(b.axistags, a.axistags)
+    a[0,0,0] += 42
+    assert b[0,0,0] != a[0,0,0]
+
+    a = arraytypes.RGBImage(numpy.random.random((3, 4, 10)), order='F')
+    b = copy.deepcopy(a)
+    assert numpy.all(a == b)
+    assert_equal(b.flags.c_contiguous, a.flags.c_contiguous)
+    assert_equal(b.flags.f_contiguous, a.flags.f_contiguous)
+    assert_equal(b.axistags, a.axistags)
+    a[0,0,0] += 42
+    assert b[0,0,0] != a[0,0,0]
+
+def testDeepcopyWithAttributes():
+    a = arraytypes.Image((320, 200), order='C')
+    a.myCustomAttribute = 42
+    b = copy.deepcopy(a)
+    assert hasattr(b, "myCustomAttribute")
+    assert_equal(b.myCustomAttribute, 42)
+
+def testDeepcopyWithCyclicReference():
+    a = arraytypes.Image((320, 200), order='C')
+    b = arraytypes.Image((320, 200), order='C')
+    a.myCustomAttribute = b
+    b.backLink = a
+    c = copy.deepcopy(a)
+    assert hasattr(c, "myCustomAttribute")
+    assert c.myCustomAttribute.backLink is c
+
+def testPickle():
+    import pickle
+    a = arraytypes.RGBImage(numpy.random.random((10, 4, 3)), order='C')
+    s = pickle.dumps(a)
+    b = pickle.loads(s)
+    assert_equal(b.shape, a.shape)
+    assert_equal(b.strides, a.strides)
+    assert_equal(b.axistags, a.axistags)
+    assert numpy.all(a == b)
+
+    a = arraytypes.RGBImage(numpy.random.random((4, 10, 3)), order='V')
+    s = pickle.dumps(a)
+    b = pickle.loads(s)
+    assert_equal(b.shape, a.shape)
+    assert_equal(b.strides, a.strides)
+    assert_equal(b.axistags, a.axistags)
+    assert numpy.all(a == b)
+
+    a = arraytypes.RGBImage(numpy.random.random((3, 4, 10)), order='F')
+    s = pickle.dumps(a)
+    b = pickle.loads(s)
+    assert_equal(b.shape, a.shape)
+    assert_equal(b.strides, a.strides)
+    assert_equal(b.axistags, a.axistags)
+    assert numpy.all(a == b)
+    
+def testZMQ():
+    try:
+        import zmq
+        ctx = zmq.Context.instance()
+        sender = zmq.Socket(ctx, zmq.PUSH)
+        receiver = zmq.Socket(ctx, zmq.PULL)
+        sender.bind('inproc://a')
+        receiver.connect('inproc://a')
+    except:
+        return
+        
+    a = arraytypes.RGBImage(numpy.random.random((10, 4, 3)), order='C')
+    a.sendSocket(sender, copy=False)
+    b = arraytypes.VigraArray.receiveSocket(receiver, copy=False)
+    assert_equal(b.shape, a.shape)
+    assert_equal(b.strides, a.strides)
+    assert_equal(b.axistags, a.axistags)
+    assert numpy.all(a == b)
+
+    a = arraytypes.RGBImage(numpy.random.random((4, 10, 3)), order='V')
+    a.sendSocket(sender, copy=False)
+    b = arraytypes.VigraArray.receiveSocket(receiver, copy=False)
+    assert_equal(b.shape, a.shape)
+    assert_equal(b.strides, a.strides)
+    assert_equal(b.axistags, a.axistags)
+    assert numpy.all(a == b)
+
+    a = arraytypes.RGBImage(numpy.random.random((3, 4, 10)), order='F')
+    a.sendSocket(sender, copy=False)
+    b = arraytypes.VigraArray.receiveSocket(receiver, copy=False)
+    assert_equal(b.shape, a.shape)
+    assert_equal(b.strides, a.strides)
+    assert_equal(b.axistags, a.axistags)
+    assert numpy.all(a == b)
+    
+def testSlicing():
+    a = arraytypes.Vector2Volume((5,4,3))
+    a.flat[...] = xrange(a.size)
+    
+    tags = arraytypes.VigraArray.defaultAxistags('xyzc')
+    assert_equal(tags, a.axistags)
+    
+    b = a[...]
+    assert_true((a==b).all())
+    assert_equal(tags, b.axistags)
+    
+    b = a[...,0]
+    assert_equal(b.shape, a.shape[:-1])
+    assert_equal(b.axistags, arraytypes.VigraArray.defaultAxistags('xyz'))
+    assert_equal(b[3,2,1], a[3,2,1,0])
+    
+    b = a[1,...]
+    assert_equal(b.shape, a.shape[1:])
+    assert_equal(b.axistags, arraytypes.VigraArray.defaultAxistags('yzc'))
+    assert_equal(b[3,2,1], a[1,3,2,1])
+    
+    b = a[:,2,...]
+    assert_equal(b.shape, (5,3,2))
+    assert_equal(b.axistags, arraytypes.VigraArray.defaultAxistags('xzc'))
+    assert_equal(b[3,2,1], a[3,2,2,1])
+    
+    b = a[:,1,2,...]
+    assert_equal(b.shape, (5,2))
+    assert_equal(b.axistags, arraytypes.VigraArray.defaultAxistags('xc'))
+    assert_equal(b[2,1], a[2,1,2,1])
+    
+    b = a[2:4, :, 2, ...]
+    assert_equal(b.shape, (2, 4, 2))
+    assert_equal(b.axistags, arraytypes.VigraArray.defaultAxistags('xyc'))
+    assert_equal(b[0,2,1], a[2,2,2,1])
+    
+    b = a[1:4, :, arraytypes.newaxis(arraytypes.AxisInfo.t), 1, ...]
+    assert_equal(b.shape, (3, 4, 1, 2))
+    assert_equal(b.axistags, arraytypes.VigraArray.defaultAxistags('xytc'))
+    assert_equal(b[0,2,0,0], a[1,2,1,0])
+    
+    b = a[..., None, :,1]
+    assert_equal(b.shape, (5, 4, 1, 3))
+    rtags = arraytypes.AxisTags(arraytypes.AxisInfo.x, arraytypes.AxisInfo.y, arraytypes.AxisInfo(), arraytypes.AxisInfo.z) 
+    assert_equal(b.axistags, rtags)
+    assert_equal(b[0,3,0,1], a[0,3,1,1])
+    
+    b = a.subarray((4,3,2))
+    assert_equal(b.shape, (4,3,2,2))
+    assert_true((a[:4,:3,:2,:]==b).all())
+    assert_equal(tags, b.axistags)
+    
+    b = a.subarray((1,1,1),(4,3,2))
+    assert_equal(b.shape, (3,2,1,2))
+    assert_true((a[1:4,1:3,1:2]==b).all())
+    assert_equal(tags, b.axistags)
+    
+    b = a.subarray((1,1,1,1),(4,3,2,2))
+    assert_equal(b.shape, (3,2,1,1))
+    assert_true((a[1:4,1:3,1:2,1:]==b).all())
+    assert_equal(tags, b.axistags)
+
+def testMethods():
+    a = arraytypes.ScalarImage((20, 30))
+    ones = arraytypes.ScalarImage((20, 30), value=1)
+    
+    a.ravel()[...] = range(a.size)
+    
+    for k, i in zip(a.flat, xrange(a.size)):
+        assert_equal(k, i)
+        
+    assert (a.flatten() == range(a.size)).all()
+    
+    assert (a >= 0).all()
+    assert not (a == 0).all()
+    
+    assert (a == 0).any()
+    assert not (a == -1).any()
+    
+    assert_equal(a.argmax(), a.size-1)
+    assert (a.argmax(axis='y') == a.shape[1]-1).all()
+    
+    assert_equal(a.argmin(), 0)
+    assert (a.argmin(axis='y') == 0).all()
+    
+    assert (ones.cumsum()-1 == a.ravel()).all()
+    oc = ones.cumsum(axis='x')-1
+    for s in oc.sliceIter('y'):
+        assert (s == range(a.shape[0])).all()
+    
+    assert (ones.cumprod() == 1).all()
+    assert (ones.cumprod(axis='x') == 1).all()
+    
+    assert_equal(a.max(), a.size-1)
+    assert (a.max(axis='y') == range(a.size-a.shape[0], a.size)).all()
+    
+    assert_equal(a.mean(dtype=numpy.longdouble), (a.size - 1.0) / 2.0)
+    assert (a.mean(axis='y', dtype=numpy.longdouble) == 
+            range((a.size-a.shape[0])/2, (a.size+a.shape[0])/2)).all()
+
+    assert_equal(a.min(), 0)
+    assert (a.min(axis='y') == range(a.shape[0])).all()
+    
+    n = arraytypes.ScalarImage(numpy.array([[1, 0, 0],[0, 1, 1],[1, 0, 1]]))
+    nz = n.nonzero()
+    assert (nz[0] == [0, 1, 1, 2, 2]).all()
+    assert_equal(nz[0].axistags, n.defaultAxistags('x'))
+    assert (nz[1] == [0, 1, 2, 0, 2]).all()
+    assert_equal(nz[1].axistags, n.defaultAxistags('y'))
+    
+    assert_equal(ones.prod(), 1.0)
+    assert (ones.prod(axis='y') == [1]*ones.shape[0]).all()
+    
+    assert_equal(a.ptp(), a.size-1)
+    assert (a.ptp(axis='x') == [a.shape[0]-1]*a.shape[1]).all()
+    
+    r = arraytypes.ScalarImage((2,2))
+    r.ravel()[...] = range(4)
+    
+    assert (r.repeat(1) == r.ravel()).all()
+    assert (r.repeat(2) == reduce(lambda x,y: x+[y,y], range(4), [])).all()
+    assert (r.repeat([0,1,2,3]) == [1,2,2,3,3,3]).all()
+    assert (r.repeat(2, axis='y').ravel() == [0,1,0,1,2,3,2,3]).all()
+    assert (r.repeat([1,2], axis='y').ravel() == [0,1,2,3,2,3]).all()
+    
+    s = a[arraytypes.AxisInfo.c,:,arraytypes.AxisInfo.z,:,arraytypes.AxisInfo.t]
+    assert_equal(s.shape, (1, a.shape[0], 1, a.shape[1], 1))
+    assert_equal(s.axistags,a.defaultAxistags('cxzyt'))
+    ss = s.squeeze()
+    assert_equal(ss.shape, a.shape)
+    assert_equal(ss.axistags,a.axistags)
+    
+    assert_equal(ones.std(dtype=numpy.longdouble), 0.0)
+    assert (ones.std(axis='x', dtype=numpy.longdouble) == [0.0]*a.shape[1]).all()
+    
+    assert_equal(ones.sum(dtype=numpy.longdouble), ones.size)
+    assert (ones.sum(axis='x', dtype=numpy.longdouble) == [a.shape[0]]*a.shape[1]).all()
+    
+    b = a.swapaxes(0, 1)
+    assert_equal(b.shape, (a.shape[1], a.shape[0]))
+    assert_equal(len(b.axistags), 2)
+    assert_equal(b.axistags[0], a.axistags[1])
+    assert_equal(b.axistags[1], a.axistags[0])
+    
+    b = a.swapaxes(0, 1, keepTags=True)
+    assert_equal(b.shape, (a.shape[1], a.shape[0]))
+    assert_equal(len(b.axistags), 2)
+    assert_equal(b.axistags, a.axistags)
+    
+    rt = r.take([1,2])
+    assert (rt == [1,2]).all()
+    assert_equal(rt.axistags, arraytypes.AxisTags(1))
+    rt = r.take([0,1], axis='y')
+    assert (rt == r).all()
+    assert_equal(rt.axistags, rt.axistags)
+    
+    assert_equal(ones.var(dtype=numpy.longdouble), 0.0)
+    assert (ones.var(axis='x', dtype=numpy.longdouble) == [0.0]*a.shape[1]).all()
+    
+    a = arraytypes.Image((5,4,3))
+    b = a.transpose()
+    assert_equal(b.shape, (3,4,5))
+    assert_equal(len(b.axistags), len(a.axistags))
+    assert_equal(b.axistags[0], a.axistags[2])
+    assert_equal(b.axistags[1], a.axistags[1])
+    assert_equal(b.axistags[2], a.axistags[0])
+    b = a.transpose((1,2,0))
+    assert_equal(b.shape, (4,3,5))
+    assert_equal(len(b.axistags), len(a.axistags))
+    assert_equal(b.axistags[0], a.axistags[1])
+    assert_equal(b.axistags[1], a.axistags[2])
+    assert_equal(b.axistags[2], a.axistags[0])
+    b = a.transpose(keepTags=True)
+    assert_equal(b.shape, (3,4,5))
+    assert_equal(len(b.axistags), len(a.axistags))
+    assert_equal(b.axistags, a.axistags)
+    b = a.transpose((1,2,0), keepTags=True)
+    assert_equal(b.shape, (4,3,5))
+    assert_equal(len(b.axistags), len(a.axistags))
+    assert_equal(b.axistags, a.axistags)
+    
+def testUfuncs():
+    from numpy import bool, int8, uint8, int16, uint16, int32, uint32, int64, uint64
+    from numpy import float32, float64, longdouble, complex64, complex128, clongdouble
+    integers = [ int8, uint8, int16, uint16, int32, uint32, int64, uint64]
+    floats = [float32, float64, longdouble]
+    compl = [complex64, complex128, clongdouble]
+    types = integers + floats + compl
+    
+    arrays, ones  = {}, {}
+    for t in types:
+        arrays[t] = arraytypes.ScalarImage((2,2), t, value=2)
+        ones[t] = arraytypes.ScalarImage((1,1), t, value=1)
+    for t, a in arrays.iteritems():
+        b = -a
+        assert_equal(t, b.dtype)
+        assert_equal(a.axistags, b.axistags)
+        if not numpyHasComplexNegateBug or t is not clongdouble:
+            assert (b == -t(2)).all()
+        b = a + a
+        assert_equal(t, b.dtype)
+        assert_equal(a.axistags, b.axistags)
+        assert (b == t(4)).all()
+        b = a == a
+        assert_equal(bool, b.dtype)
+        assert_equal(a.axistags, b.axistags)
+        assert (b == True).all()
+        b = ones[t] + a
+        assert_equal(a.shape, b.shape)
+        assert_equal(a.axistags, b.axistags)
+        assert_equal(t, b.dtype)
+        assert (b == t(3)).all()
+        b = a + ones[t]
+        assert_equal(a.shape, b.shape)
+        assert_equal(a.axistags, b.axistags)
+        assert_equal(t, b.dtype)
+        assert (b == t(3)).all()
+        b = 3 + a
+        assert_equal(t, b.dtype)
+        assert_equal(a.axistags, b.axistags)
+        assert (b == t(5)).all()
+        b = a + 3
+        assert_equal(t, b.dtype)
+        assert_equal(a.axistags, b.axistags)
+        assert (b == t(5)).all()
+    for i in integers:
+        a1 = arrays[i]
+        for j in integers:
+            if i == j:
+                continue
+            a2 = arrays[j]
+            b = a1 * a2
+            if a1.dtype.itemsize < 8 and a2.dtype.itemsize < 8:
+                assert_equal(int32, b.dtype)
+            else:
+                assert_equal(int64, b.dtype)
+            assert_equal(a1.axistags, b.axistags)
+            assert (b == 4).all()
+            b = a1 <= a2
+            assert_equal(bool, b.dtype)
+            assert_equal(a1.axistags, b.axistags)
+            assert (b == True).all()
+        for j in floats + compl:
+            a2 = arrays[j]
+            b = a1 * a2
+            assert_equal(j, b.dtype)
+            assert_equal(a1.axistags, b.axistags)
+            assert (b == 4).all()
+            b = a2 * a1
+            assert_equal(j, b.dtype)
+            assert_equal(a1.axistags, b.axistags)
+            assert (b == 4).all()
+            b = a1 >= a2
+            assert_equal(bool, b.dtype)
+            assert_equal(a1.axistags, b.axistags)
+            assert (b == True).all()
+            b = a2 > a1
+            assert_equal(bool, b.dtype)
+            assert_equal(a1.axistags, b.axistags)
+            assert (b == False).all()
+        b = a1 + 1
+        assert (b == 3).all()
+        assert_equal(a1.dtype, b.dtype)
+        assert_equal(a1.axistags, b.axistags)
+        b = a1 + 1.0
+        assert_equal(a1.axistags, b.axistags)
+        assert (b == 3.0).all()
+        if a1.dtype.itemsize < 8:
+            assert_equal(float32, b.dtype)
+        else:
+            assert_equal(float64, b.dtype)
+    for i in floats:
+        a1 = arrays[i]
+        for j in compl:
+            if i == j:
+                continue
+            a2 = arrays[j]
+            b = a1 * a2
+            assert_equal(j, b.dtype)
+            assert_equal(a1.axistags, b.axistags)
+            assert (b == 4).all()
+            b = a2 * a1
+            assert_equal(j, b.dtype)
+            assert_equal(a1.axistags, b.axistags)
+            assert (b == 4).all()
+            b = a1 >= a2
+            assert_equal(bool, b.dtype)
+            assert_equal(a1.axistags, b.axistags)
+            assert (b == True).all()
+            b = a2 > a1
+            assert_equal(bool, b.dtype)
+            assert_equal(a1.axistags, b.axistags)
+            assert (b == False).all()
+        b = a1 + 0.5
+        assert (b == 2.5).all()
+        assert_equal(a1.dtype, b.dtype)
+        assert_equal(a1.axistags, b.axistags)
+        
+        fractional, integral = ufunc.modf(b)
+        assert (fractional == 0.5).all()
+        assert (integral == 2.0).all()
+        assert_equal(a1.dtype, fractional.dtype)
+        assert_equal(a1.axistags, fractional.axistags)
+        assert_equal(a1.dtype, integral.dtype)
+        assert_equal(a1.axistags, integral.axistags)
+        
+    assert_equal(float64, (arrays[float32]+arrays[float64]).dtype)
+    assert_equal(float64, (arrays[float64]+arrays[float32]).dtype)
+    assert_equal(longdouble, (arrays[float32]+arrays[longdouble]).dtype)
+    assert_equal(longdouble, (arrays[longdouble]+arrays[float32]).dtype)
+    assert_equal(longdouble, (arrays[float64]+arrays[longdouble]).dtype)
+    assert_equal(longdouble, (arrays[longdouble]+arrays[float64]).dtype)
+
+    assert_equal(complex128, (arrays[complex64]+arrays[complex128]).dtype)
+    assert_equal(complex128, (arrays[complex128]+arrays[complex64]).dtype)
+    assert_equal(clongdouble, (arrays[complex64]+arrays[clongdouble]).dtype)
+    assert_equal(clongdouble, (arrays[clongdouble]+arrays[complex64]).dtype)
+    assert_equal(clongdouble, (arrays[complex128]+arrays[clongdouble]).dtype)
+    assert_equal(clongdouble, (arrays[clongdouble]+arrays[complex128]).dtype)
+
+    b = abs(arrays[complex64])
+    assert (b == 2.0).all()
+    assert_equal(float32, b.dtype)
+    assert_equal(arrays[complex64].axistags, b.axistags)
+    b = abs(arrays[complex128])
+    assert (b == 2.0).all()
+    assert_equal(float64, b.dtype)
+    assert_equal(arrays[complex128].axistags, b.axistags)
+    b = abs(arrays[clongdouble])
+    assert (b == 2.0).all()
+    assert_equal(longdouble, b.dtype)
+    assert_equal(arrays[clongdouble].axistags, b.axistags)
+
+    a = arraytypes.ScalarImage((2,2), uint8, value=255)
+    b = a + a
+    assert (b == 254).all()
+    b = a + 255
+    assert (b == 254).all()
+    b = 255 + a
+    assert (b == 254).all()
+    
+    b = arraytypes.ScalarImage((2,2), int32, value=0)
+    bb = ufunc.add(a, a, b)
+    assert bb is b
+    assert (b == 510).all()
+    b = arraytypes.ScalarImage((2,2), int32, value=0)
+    bb = ufunc.add(a, 255, b)
+    assert bb is b
+    assert (b == 510).all()
+    b = arraytypes.ScalarImage((2,2), int32, value=0)
+    bb = ufunc.add(255, a, b)
+    assert bb is b
+    assert (b == 510).all()
diff --git a/vigranumpy/test/test_color.py b/vigranumpy/test/test_color.py
new file mode 100644
index 0000000..e2b4947
--- /dev/null
+++ b/vigranumpy/test/test_color.py
@@ -0,0 +1,106 @@
+#######################################################################
+#                                                                      
+#         Copyright 2009-2013 by Ullrich Koethe and Thorben Kroeger
+#                                                                      
+#    This file is part of the VIGRA computer vision library.           
+#    The VIGRA Website is                                              
+#        http://hci.iwr.uni-heidelberg.de/vigra/                       
+#    Please direct questions, bug reports, and contributions to        
+#        ullrich.koethe at iwr.uni-heidelberg.de    or                    
+#        vigra at informatik.uni-hamburg.de                               
+#                                                                      
+#    Permission is hereby granted, free of charge, to any person       
+#    obtaining a copy of this software and associated documentation    
+#    files (the "Software"), to deal in the Software without           
+#    restriction, including without limitation the rights to use,      
+#    copy, modify, merge, publish, distribute, sublicense, and/or      
+#    sell copies of the Software, and to permit persons to whom the    
+#    Software is furnished to do so, subject to the following          
+#    conditions:                                                       
+#                                                                      
+#    The above copyright notice and this permission notice shall be    
+#    included in all copies or substantial portions of the             
+#    Software.                                                         
+#                                                                      
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     
+#    OTHER DEALINGS IN THE SOFTWARE.                                   
+#                                                                      
+#######################################################################
+
+import sys
+print >> sys.stderr, "\nexecuting test file", __file__
+execfile('set_paths.py')
+
+from nose.tools import assert_equal, raises, assert_raises, assert_true
+import vigra
+import numpy
+
+_have_qt = False
+try:
+    from PyQt4.QtGui import QImage
+    from qimage2ndarray import byte_view
+    _have_qt = True
+except:
+    pass
+
+def test_gray2qimage():
+    if not _have_qt:
+        return
+    
+    # create test data such that rounding does not depend on the least significant bit
+    a = (numpy.random.randint(255, size=(100,200)).astype(numpy.float32)+0.25)/255.0-0.5
+    a[0,0] =-0.5 #make sure we get the correct bounds
+    a[0,1] = 0.5
+    vigra.impex.writeImage(a.swapaxes(0,1), "tmp1.png")
+
+    img = QImage(a.shape[1], a.shape[0], QImage.Format_ARGB32_Premultiplied)
+    n = numpy.asarray([-0.5, 0.5], dtype=numpy.float32)
+    vigra.colors.gray2qimage_ARGB32Premultiplied(a, byte_view(img), n)
+    img.save("tmp2.png")
+    
+    tmp1 = vigra.impex.readImage("tmp1.png")
+    tmp2 = vigra.impex.readImage("tmp2.png")
+    
+    for i in range(3):
+        assert_true( (tmp1 == tmp2[:,:,i]).all() )
+    assert_true( (tmp2[:,:,3] == 255).all() )
+
+def test_alphamodulated2qimage():
+    if not _have_qt:
+        return
+    
+    # create test data such that rounding does not depend on the least significant bit
+    a = (numpy.random.randint(255, size=(100,200)).astype(numpy.float32)+0.25)/255.0-0.5
+    a[0,0] =-0.5 #make sure we get the correct bounds
+    a[0,1] = 0.5
+    vigra.impex.writeImage(a.swapaxes(0,1), "tmp1.png")
+    
+    tintColor = numpy.asarray([0.0, 1.0, 0.0], dtype=numpy.float32)
+    
+    img = QImage(a.shape[1], a.shape[0], QImage.Format_ARGB32_Premultiplied)
+    n = numpy.asarray([-0.5, 0.5], dtype=numpy.float32)
+    
+    vigra.colors.alphamodulated2qimage_ARGB32Premultiplied(a, byte_view(img), tintColor, n)
+    
+    tmp1 = vigra.impex.readImage("tmp1.png").view(numpy.ndarray).squeeze().astype(numpy.uint8)
+    tmp2 = byte_view(img)
+    tmp2 = tmp2.swapaxes(0,1)
+    
+    assert_true( tmp1.shape[0:2] == tmp2.shape[0:2] )
+    assert_true( tmp2.ndim == 3 )
+    assert_true( tmp2.shape[2] == 4 )
+    
+    assert_true( (tmp2[:,:,0] == 0).all() )
+    assert_true( (tmp2[:,:,2] == 0).all() )
+    assert_true( (tmp2[:,:,3] == tmp1).all() )
+    assert_true( (tmp2[:,:,1] == tmp1).all() )
+
+if __name__ == '__main__':
+    import nose
+    nose.run(defaultTest=__file__)
diff --git a/vigranumpy/test/test_impex.py b/vigranumpy/test/test_impex.py
new file mode 100644
index 0000000..ef4e4b2
--- /dev/null
+++ b/vigranumpy/test/test_impex.py
@@ -0,0 +1,160 @@
+#######################################################################
+#                                                                      
+#         Copyright 2009-2010 by Ullrich Koethe                        
+#                                                                      
+#    This file is part of the VIGRA computer vision library.           
+#    The VIGRA Website is                                              
+#        http://hci.iwr.uni-heidelberg.de/vigra/                       
+#    Please direct questions, bug reports, and contributions to        
+#        ullrich.koethe at iwr.uni-heidelberg.de    or                    
+#        vigra at informatik.uni-hamburg.de                               
+#                                                                      
+#    Permission is hereby granted, free of charge, to any person       
+#    obtaining a copy of this software and associated documentation    
+#    files (the "Software"), to deal in the Software without           
+#    restriction, including without limitation the rights to use,      
+#    copy, modify, merge, publish, distribute, sublicense, and/or      
+#    sell copies of the Software, and to permit persons to whom the    
+#    Software is furnished to do so, subject to the following          
+#    conditions:                                                       
+#                                                                      
+#    The above copyright notice and this permission notice shall be    
+#    included in all copies or substantial portions of the             
+#    Software.                                                         
+#                                                                      
+#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    
+#    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   
+#    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          
+#    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       
+#    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      
+#    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      
+#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     
+#    OTHER DEALINGS IN THE SOFTWARE.                                   
+#                                                                      
+#######################################################################
+
+import sys
+print >> sys.stderr, "\nexecuting test file", __file__
+execfile('set_paths.py')
+
+from nose.tools import assert_equal, raises
+import numpy as np
+import vigra.vigranumpycore # FIXME: why is this needed? (without, impex returns ndarray)
+import vigra.impex as im
+import vigra.arraytypes as at
+
+#in the hope, that functions are tested in C++, we basicly test return types
+
+image=at.RGBImage(np.random.rand(10,10,3)*255,dtype=np.float32, 
+                  axistags=at.VigraArray.defaultAxistags(3, 'V'))
+image2=at.RGBImage(np.random.rand(20,20,3)*255,dtype=np.uint8, 
+                  axistags=at.VigraArray.defaultAxistags(3, 'V'))
+scalar_image=at.ScalarImage(np.random.rand(10,10)*255,dtype=np.float32, 
+                  axistags=at.AxisTags(at.AxisInfo.x, at.AxisInfo.y))
+volume256=at.Volume(np.random.rand(8,9,10)*255,dtype=np.uint8, 
+                  axistags=at.AxisTags(at.AxisInfo.x, at.AxisInfo.y, at.AxisInfo.z))
+volumeFloat=at.Volume(np.random.rand(3,4,5,6)*100,dtype=np.float32, 
+                  axistags=at.VigraArray.defaultAxistags(4, 'C'))
+
+def checkEqualData(i1,i2):
+    assert_equal(i1.shape, i2.shape)
+    assert(np.all(i1==i2))
+
+def checkUnequalData(i1,i2):
+    assert_equal(i1.shape, i2.shape)
+    assert(np.any(i1!=i2))
+
+def test_multiImageTiff():
+    if not 'TIFF' in im.listFormats():
+        return
+
+    filename = 'resimage.tif'
+
+    # decompose the RGB image and write the three channels as individual images
+    # to a multi-image TIFF
+    for i in range(3):
+        # the first image requires mode="w" in case the image already exists
+        im.writeImage(image2[:,:,i], filename, mode="w" if i == 0 else "a")
+
+    # test different dimensions and data types
+    im.writeImage(image, filename, mode="a")
+    im.writeImage(image2, filename, mode="a")
+    im.writeImage(scalar_image, filename, mode="a")
+
+    # check number of images contained in the file
+    assert(im.numberImages(filename) == 6)
+
+    # check for equal data
+    for i in range(3):
+        img_test = im.readImage(filename, index=i)
+        checkEqualData(img_test.dropChannelAxis(), image2[:,:,i])
+    checkEqualData(im.readImage(filename, index=3), image)
+    checkEqualData(im.readImage(filename, index=4), image2)
+    checkEqualData(im.readImage(filename, index=5).dropChannelAxis(), scalar_image)
+
+
+def test_writeAndReadImageHDF5():
+    try:
+        import h5py
+    except:
+        print "Warning: 'import h5py' failed, not executing HDF5 import/export tests"
+        return
+    
+    # positive tests
+    # write and read image
+    im.writeHDF5(image, "hdf5test.hd5", "group/subgroup/imgdata")
+    image_imp = im.readHDF5("hdf5test.hd5", "group/subgroup/imgdata")
+    checkEqualData(image,image_imp)
+    # write and read scalar image
+    im.writeHDF5(scalar_image, "hdf5test.hd5", "group/subgroup/imgdata")
+    scalar_image_imp = im.readHDF5("hdf5test.hd5", "group/subgroup/imgdata")
+    scalar_image_imp = scalar_image_imp.dropChannelAxis()
+    checkEqualData(scalar_image,scalar_image_imp)
+    # write multiple sets and check if they are all there afterwards
+    im.writeHDF5(image, "hdf5test.hd5", "group/subgroup/imgdata")
+    im.writeHDF5(image, "hdf5test.hd5", "group/subgroup/imgdata2")
+    image_imp1 = im.readHDF5("hdf5test.hd5", "group/subgroup/imgdata")
+    image_imp2 = im.readHDF5("hdf5test.hd5", "group/subgroup/imgdata2")
+    checkEqualData(image,image_imp1)
+    checkEqualData(image,image_imp2)
+
+    # negative tests
+    # write and read image
+    image_imp[1,1,1] = 100000
+    checkUnequalData(image,image_imp)
+    # write and read scalar image
+    scalar_image_imp[1,1] = 100000
+    checkUnequalData(scalar_image,scalar_image_imp)
+    
+def test_writeAndReadVolumeHDF5():
+    try:
+        import h5py
+    except:
+        return
+    
+    # positive tests
+    # write and read volume
+    im.writeHDF5(volume256, "hdf5test.hd5", "group/subgroup/voldata")
+    volume256_imp = im.readHDF5("hdf5test.hd5", "group/subgroup/voldata")
+    checkEqualData(volume256,volume256_imp)
+    # write and read binary volume
+    im.writeHDF5(volumeFloat, "hdf5test.hd5", "group/subgroup/voldata")
+    volumeFloat_imp = im.readHDF5("hdf5test.hd5", "group/subgroup/voldata")
+    checkEqualData(volumeFloat.transposeToDefaultOrder(), volumeFloat_imp)
+    # write multiple sets and check if they are all there afterwards
+    im.writeHDF5(volume256, "hdf5test.hd5", "group/subgroup/voldata")
+    im.writeHDF5(volume256, "hdf5test.hd5", "group/subgroup/voldata2")
+    volume256_imp1 = im.readHDF5("hdf5test.hd5", "group/subgroup/voldata")
+    volume256_imp1 = volume256_imp1.dropChannelAxis()
+    volume256_imp2 = im.readHDF5("hdf5test.hd5", "group/subgroup/voldata2")
+    volume256_imp2 = volume256_imp2.dropChannelAxis()
+    checkEqualData(volume256,volume256_imp1)
+    checkEqualData(volume256,volume256_imp2)
+
+    # negative tests
+    # write and read volume
+    volume256_imp[1,1,1] = 100000
+    checkUnequalData(volume256,volume256_imp)
+    # write and read binary volume
+    volumeFloat_imp[1,1,1] = 100000
+    checkUnequalData(volumeFloat.transposeToDefaultOrder(), volumeFloat_imp)
diff --git a/vigranumpy/test/vigranumpytest.cxx b/vigranumpy/test/vigranumpytest.cxx
new file mode 100644
index 0000000..863d600
--- /dev/null
+++ b/vigranumpy/test/vigranumpytest.cxx
@@ -0,0 +1,178 @@
+/************************************************************************/
+/*                                                                      */
+/*                 Copyright 2009 by Ullrich Koethe                     */
+/*                                                                      */
+/*    This file is part of the VIGRA computer vision library.           */
+/*    The VIGRA Website is                                              */
+/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
+/*    Please direct questions, bug reports, and contributions to        */
+/*        ullrich.koethe at iwr.uni-heidelberg.de    or                    */
+/*        vigra at informatik.uni-hamburg.de                               */
+/*                                                                      */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
+/*                                                                      */
+/************************************************************************/
+
+#define PY_ARRAY_UNIQUE_SYMBOL vigranumpytest_PyArray_API
+
+#include <Python.h>
+#include <iostream>
+#include <vigra/config.hxx>
+#include <boost/python.hpp>
+#include <boost/python/signature.hpp>
+#include <vigra/numpy_array.hxx>
+#include <vigra/numpy_array_converters.hxx>
+
+namespace python = boost::python;
+
+namespace vigra {
+
+python::tuple testAny(NumpyAnyArray array)
+{
+    NumpyAnyArray copy(array, true);
+    return python::make_tuple(array.shape(), copy, python::object(), python::object());
+}
+
+template <unsigned int N, class T, class Stride>
+python::tuple test(NumpyArray<N, T, Stride> const & array)
+{
+    NumpyAnyArray anyarray(array);
+    
+    NumpyArray<N, T> copy(array, true);
+    vigra_postcondition(copy.pyObject()->ob_refcnt == 1, 
+          "freshly created NumpyArray<N, T> has reference count > 1.");
+
+    NumpyArray<N, T> same_shape(array.shape());
+    same_shape = array;
+
+    NumpyArray<N, T> same_shape_and_tags(array.taggedShape());
+    same_shape_and_tags = anyarray;
+
+    return python::make_tuple(anyarray.shape(), copy, 
+                               same_shape, same_shape_and_tags);
+}
+
+template <unsigned int N, class T, class Stride>
+typename MultiArrayShape<N>::type 
+testView(MultiArrayView<N, T, Stride> array)
+{
+    array[typename MultiArrayShape<N>::type()] = NumericTraits<T>::one();
+    return array.shape();
+}
+
+// FIXME: make this to a real test (right now, it's a compile-only test)
+void testMakeReferenceUnsafe()
+{
+    MultiArray<2, vigra::UInt8> cpp_memory(MultiArrayShape<2>::type(100, 100));
+
+    NumpyArray<2, npy_uint8, vigra::UnstridedArrayTag> python_view;
+    python_view.makeUnsafeReference(cpp_memory);
+}
+
+template <unsigned int N, class T>
+python::tuple 
+checkTaggedShape(NumpyArray<N, T> in)
+{
+    NumpyArray<3, Multiband<float> > res1(in);
+    
+    NumpyArray<3, Multiband<float> > res2;
+    res2.reshapeIfEmpty(in.taggedShape().setChannelDescription("res2"), "res2 failed");
+    
+    NumpyArray<3, Multiband<float> > res3;
+    res3.reshapeIfEmpty(in.taggedShape().setChannelCount(1).setChannelDescription("res3"), 
+                        "res3 failed");
+    
+    NumpyArray<3, Multiband<float> > res4;
+    res4.reshapeIfEmpty(in.taggedShape().setChannelCount(3).setChannelDescription("res4"), 
+                        "res4 failed");
+    
+    NumpyArray<2, Singleband<float> > res5;
+    res5.reshapeIfEmpty(in.taggedShape().setChannelDescription("res5"), "res5 failed");
+    
+    NumpyArray<2, RGBValue<float> > res6;
+    res6.reshapeIfEmpty(in.taggedShape().setChannelDescription("res6"), 
+                        "res6 failed");
+    
+    return python::make_tuple(res1, res2, res3, res4, res5, res6); 
+}
+
+} // namespace vigra
+
+using namespace boost::python;
+using namespace vigra;
+
+BOOST_PYTHON_MODULE_INIT(vigranumpytest)
+{
+    import_vigranumpy();
+    
+    def("testAny", &testAny);
+
+    def("testArray2Strided", registerConverters(&test<2, float, StridedArrayTag>));
+    def("testImageSinglebandStrided", registerConverters(&test<2, Singleband<float>, StridedArrayTag>));
+    def("testImageRGBStrided", registerConverters(&test<2, RGBValue<float>, StridedArrayTag >));
+    def("testImageVector2Strided", registerConverters(&test<2, TinyVector<float, 2>, StridedArrayTag >));
+    def("testImageMultibandStrided", registerConverters(&test<3, Multiband<float>, StridedArrayTag >));
+    
+    def("testArray2Unstrided", registerConverters(&test<2, float, UnstridedArrayTag>));
+    def("testImageSinglebandUnstrided", registerConverters(&test<2, Singleband<float>, UnstridedArrayTag>));
+    def("testImageRGBUnstrided", registerConverters(&test<2, RGBValue<float>, UnstridedArrayTag >));
+    def("testImageVector2Unstrided", registerConverters(&test<2, TinyVector<float, 2>, UnstridedArrayTag >));
+    def("testImageMultibandUnstrided", registerConverters(&test<3, Multiband<float>, UnstridedArrayTag >));
+
+    def("testArray3Strided", registerConverters(&test<3, float, StridedArrayTag>));
+    def("testVolumeSinglebandStrided", registerConverters(&test<3, Singleband<float>, StridedArrayTag>));
+    def("testVolumeRGBStrided", registerConverters(&test<3, RGBValue<float>, StridedArrayTag >));
+    def("testVolumeVector2Strided", registerConverters(&test<3, TinyVector<float, 2>, StridedArrayTag >));
+    def("testVolumeMultibandStrided", registerConverters(&test<4, Multiband<float>, StridedArrayTag >));
+    
+    def("testArray3Unstrided", registerConverters(&test<3, float, UnstridedArrayTag>));
+    def("testVolumeSinglebandUnstrided", registerConverters(&test<3, Singleband<float>, UnstridedArrayTag>));
+    def("testVolumeRGBUnstrided", registerConverters(&test<3, RGBValue<float>, UnstridedArrayTag >));
+    def("testVolumeVector2Unstrided", registerConverters(&test<3, TinyVector<float, 2>, UnstridedArrayTag >));
+    def("testVolumeMultibandUnstrided", registerConverters(&test<4, Multiband<float>, UnstridedArrayTag >));
+
+    def("testArray4Strided", registerConverters(&test<4, float, StridedArrayTag>));
+    def("testArray4Unstrided", registerConverters(&test<4, float, UnstridedArrayTag>));
+
+    def("viewArray2Strided", registerConverters(&testView<2, float, StridedArrayTag>));
+    def("viewImageRGBStrided", registerConverters(&testView<2, RGBValue<float>, StridedArrayTag >));
+    def("viewImageVector2Strided", registerConverters(&testView<2, TinyVector<float, 2>, StridedArrayTag >));
+    
+    def("viewArray2Unstrided", registerConverters(&testView<2, float, UnstridedArrayTag>));
+    def("viewImageRGBUnstrided", registerConverters(&testView<2, RGBValue<float>, UnstridedArrayTag >));
+    def("viewImageVector2Unstrided", registerConverters(&testView<2, TinyVector<float, 2>, UnstridedArrayTag >));
+
+    def("viewArray3Strided", registerConverters(&testView<3, float, StridedArrayTag>));
+    def("viewVolumeRGBStrided", registerConverters(&testView<3, RGBValue<float>, StridedArrayTag >));
+    def("viewVolumeVector2Strided", registerConverters(&testView<3, TinyVector<float, 2>, StridedArrayTag >));
+    
+    def("viewArray3Unstrided", registerConverters(&testView<3, float, UnstridedArrayTag>));
+    def("viewVolumeRGBUnstrided", registerConverters(&testView<3, RGBValue<float>, UnstridedArrayTag >));
+    def("viewVolumeVector2Unstrided", registerConverters(&testView<3, TinyVector<float, 2>, UnstridedArrayTag >));    
+
+    def("viewArray4Strided", registerConverters(&testView<4, float, StridedArrayTag>));
+    def("viewArray4Unstrided", registerConverters(&testView<4, float, UnstridedArrayTag>));
+    
+    def("checkTaggedShapeMultiband", registerConverters(&checkTaggedShape<3, Multiband<float> >));
+    def("checkTaggedShapeSingleband", registerConverters(&checkTaggedShape<2, Singleband<float> >));
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/libvigraimpex.git



More information about the debian-science-commits mailing list